From 69cec87d31a3f48bc7ed1a549340e94bdd61364d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 2 Apr 2019 15:56:11 -0700 Subject: [PATCH 0001/1772] Add a simple README and Contributing.md. --- proposals/clocks/Contributing.md | 8 ++++++++ proposals/clocks/README.md | 17 +++++++++++++++++ proposals/clocks/WASI.png | Bin 0 -> 11059 bytes 3 files changed, 25 insertions(+) create mode 100644 proposals/clocks/Contributing.md create mode 100644 proposals/clocks/README.md create mode 100644 proposals/clocks/WASI.png diff --git a/proposals/clocks/Contributing.md b/proposals/clocks/Contributing.md new file mode 100644 index 000000000..1cc607fa4 --- /dev/null +++ b/proposals/clocks/Contributing.md @@ -0,0 +1,8 @@ +# Contributing to WebAssembly + +Interested in participating? Please follow +[the same contributing guidelines as the design repository][]. + + [the same contributing guidelines as the design repository]: https://github.com/WebAssembly/design/blob/master/Contributing.md + +Also, please be sure to read [the README.md](README.md) for this repository. diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md new file mode 100644 index 000000000..05d744744 --- /dev/null +++ b/proposals/clocks/README.md @@ -0,0 +1,17 @@ +# WebAssembly System Interface + +![WASI](WASI.png) + +This repository accompanies the WebAssembly WASI Subgroup, +focused on the design of the WASI, the WebAssembly System Interface. + +We'll be adding more content here, but for now, check out these: + - https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ - Blog post introducing WASI + - https://wasi.dev/ - Links to more information about WASI + - https://github.com/WebAssembly/WASI/issues - This repo's issue tracker + +The issue tracker is the place to ask questions, make suggestions, and start +discussions. + +As a W3C CG Subgroup, we'll also be having meetings. Once we have a schedule +for those, we'll post that here also. diff --git a/proposals/clocks/WASI.png b/proposals/clocks/WASI.png new file mode 100644 index 0000000000000000000000000000000000000000..bb018e99e3ec2a66d8f2d6a7bcc63105b74d9262 GIT binary patch literal 11059 zcmdsdcTiKo+b%_lbU}*rqM#rk(xpT|1f+`ej!5s)Yv`yTASgv3bdV0xLkS(Eo6sSI z-btvThTQnOGvCbp@0&Z{{pTigCbN6??ECDydv@RV$@5u9ONEk*nG6pPk5Wzbl`bA0 z{(mk~Vq8t`lpzZDL;PM{@|oudLkND#=h;BUO$>jKmAAL!(^RtaaD zcqPu5--0PggunD?lNe;Ec$F0u=+!tqi3pykveI%c^?B;jMC66}5RrX+8TPVG-k@$t zsoa#AO|+mTaI6Egbw1279$)XQ4ui0dI7!a%kf~vF2}o#e6dd)Jq{UQ@a8JC&Y&A0yClJI%bqLx)p8Nu@_2ELZQz~bAwU-` zjNtOX@;5wjVL73l)e7_%-}-}{kTi!%olwF+_vf8CcsVdreP%gTplVt;$K@^c_=!Lc z%B6;N1JC0IA0jD8rt9b(E`+a~d!%@3@JV)i2z)1>(=~YWqPFGWE4omNHFK0e#yjZM z{lZaBv1UI>tBxkTp#PLL-+m+L`Fi{Tgy}rqh1iAT!`bfTD^4?Eqx7TLNU%`f6vK;)D=kOd1xeX0QM0Q$+m}Z#+c9&oXyO zXGeVb;stIT4BmrI1irsaIdqK!WQv*LS|$Vw{_D$YySKI*VXRr(q@+DQdUl32X;ONn zFdyHD2Rz5!K?83UCHWFYmtZ6S&x+3RP+w}k1bX>9tgr)`w@DJ^=L8%wp8IbO7s*YL zbB}L7Q#1PGP-(FWoZ@4(niOz7jVLbDO&nz>q0>MYgNw!T%SSdupzB~sKF|}UWdMGw z56eG?RIyzA>llRZkMwJmI0y&H87yBif??S0HN(GnDW4)v<)PGV9;-Z#>GG|2HE(d! z7%OQ3+Py?S5@{t#-A+*UmbQjE!r67;pv>T%_%7N_5L| zh$#$m|Ds9<9m;5UKmrL`HCh3@7zRji^=V_>{63260b~bC0G6#g*nPjT;~m7@@urg) zc^jR7f;UmhCowObEGYvIFogwgI0w-!$+OEva`+D)v8~o{^G+4Rj>1OEKx8x$Qa#LB zriw}{mJcRw#*+o&j0kteN3sOr?kzN)VbM*D5y7eWB<-E@(91l8`U{ztI3G|~w0COb zD|=Mq^J%jRWZ}Pg*=Dj+ZMNV_l|T?{5TS=_a?BgBT>3-!UO<@Rq{XXO3jDa4rN8$! z>C30bs>=VP*wv5N9; zZk(wlH>FBQA@qK9sZjVoF!u|&{||8g6J;{pd;c}qfBpU6mR%ZueakUpQltqxxvWAn~wd*u;(OPQ3~dOj|&4;24}nh}3mJ zV6ospuj#|%GutPWjXLw})}mGhkqnzZ2a$_R;<(I?fCANVHKaCouSt>3QIREhY+|EPc z3L)_ZSbXLbJvPIz6YTnJT0r?D9sTnY5h1aib2sn3s`nYeSc9t28Famq#Ts4X{JoFc zCBhSzyAia%=OXKMJ*?;sE)ONe`^#|D_;EC#s;V054kZ(NYWjvynt|QPW^+eqlVdNp zS&sWxm>Q=^MafUiNZ+$DqK(s>qK>D1UF`iG1+mk^^k56)+@KHPV>66{T86cARyG29 zBod4|2MIL~>g?zM$cGqq$6L+@hGITJb@GJ9gn7w^0$9>G%ck8fHIy?9S$PYXZ0MV) zbIoQ;qWUNp(`60O^$mpTru#pm&H*I7oQ>@3p}$}%(<*n{|c{xFvB?e#k(^H26BL`NQ&VO0TM zi9R$%xGtGM!rBNOCu~^sxW!czB%-w$Aujv!vi8xG!_x%^_#AK>PK>qY$%v zspccYKxs@tP)2|~qni8yVf&VTMr7_!Dl$y~Y_x@Av2XvK`5jxztH-J+ZdLNSggAT5 zwVDi=a^;1S3mua$sv1SoL`{TSCt!q&0$zJaXd2ukJ)?fWJ_UEFt*Pf5?_28`0W2x#=%<%C zLY8Klqg#yCY1inJ2xSyaj$@#|%lG;gB$+1JI$P1P-rhvW-RyV; zx3nHDVG2C={ZAcU@wV2Ub7hL}2T83%Th=?AmNI)iaS&S2Ggl(|yFYDqD54&z?`_!5 zj|-<{meHm@HS);oYGmR!ef|{XU>)G+%nY4mg!U_XJ|5UcFn>S^Cnj?UtPoJ*0?a+Z zG{VOk#<+DELfBB=9KI5k+NQQ;dL{pwG!f9yF+7nh>BGo^^9X44YU9zsWYihE*qisW zwUQ6xCD5aG1pWi9qFFNZL9v0NQQN(i$c-VyHbgqv;yMNX?Md%xur25oE3Lc`y^*QE z(ld8U#qIZC5RHac}Qv z`inGO=7bLCkd%k#@~p|ur6~Kr#v*+$!6|+-dG}fnra+A%i28NCpNm%CES#>!M%#Zz z-G+r*RnSaUe%~-ECJAD)nx}34e!SX@>v7S$!f9A<;{&B+@@?6=-mV;JZ3Gq+(aWR3 zrq@bfm$Tm;?KCf-x)<74LU*!dhe@dgs=U-uQEv1xt*OH259W(IaHk6Fjo{D^JSgDt7G=r-sJ_wErt3*UcACN=rSllcs%F5__(XN)RIu)v+!j>Y zf4{Vq#eJb2P~lAU*9OFcCO=6ya-J>+`wC=Mow`v=xN5eE)P$(0BCI@ST3y=V7-jYA zd5;F-b&4ou6;#exVMtac=N}^P_TMkvey=ukEJfEeSJS^us^U?#zWHhEIfjC_qE>!Y zy+y{dx3qG?Yxz#8kdJM)=XGUvlJAVQBLRaS1St+E+Cu%V63pgS4m2(0=jSP}+1-}@ zT=pwAh#r%@W_-D~LAzq76(dO_$XBoN9cG&$-ufuF*;HZvQ+^Eah(ss7Rs-%KyMBaW z%Z_QJQmXBrb|33Xt=z22>?Z6{U|v)^s96BcqCWD~u6;Fpk8;$I@T54P+F3G@;VkBT z3c0Bp)<{^$oO1Tl?o7NbmpB&ZJ@)fuq2l;_0R-yJ9k!I6M|m|#92}BD7eDNP^akg4 zykUl>Yd_~HdMp2}pPB22Jk5bm^31-p5x#lIA%-!}#CpXy z&!x#@a}EVWQtk+4CA14brL;&oUc7L&%ydqpBZH-G^qFS18aW4Cs*4~FJLYE!ngF?8 z>Mx7-e|~h9W0|Tghss?Lt_62axF?EUbVnHyIn%zTHWH*q1%(?B!zV7~suov7vS+w3A1|lKYl7Cm4Ly>D7ZC>~+)lIkkGt=Ri1X5>Tj$f_qcS}jL>CuwV%X6>prp+gTVy=(cLq`IpUp*6>C=x2M}=z z7#wrr+GWmWbKGe3U{M4#{4|o^>?S<>;pO49v^w`Fb78r4;K6Uin;f&H3h6X4HLLNi zdHwZhn20d26usjfMD@y9>+WwgFxgO3_swpa4OW?exDiFVjVuijaE~`-*mSG&MZB!t zZkFGjY2%ouhe}%g^wM%%b!gYct=g2AE1xA^W6_)&9WLM}pO5u^N~;!-YPFjc?HX(D zoANwP={-8Mxz}KDY0lA*70}?@ygys#`rhVmQBvJhSx30`>^2#-2x=Qpbo{@3E)doxNfdUCIPTJz~N(R+?RGYwm z7+{2ZuYOi@Q&JiVUsuZkF1E8J=TzVOUmVS!XpVO!;I(nXINRqd_)8EZn`Bo76 zXtOlU2KB?ZftQ2%#Qf?DH`C$+iH-Y@Sss8bjUP(BMFS7? z^A7z<7_}(8(6PRv=q~wH^rxD1DuU8CKZ@@{pGE!k@*FM5Fg&9qZmLYrip0I4_I?L7 zU~hSA&#|}s)1f8%0Pkx~9|mwBwC6ZDzRjr8+16l&0iszdV4Kd|)GYITOaV_cCBZoj zBVURJutKNcS(w6Nr@153wdNPRuIUfqEurW?TCXAYNi*^RVJ935f7XM7NNH7?vuN~O z=52GW^phlhOZAs4-toVv{p2(UNBhZs6e|nhwzrL`SW-bgQ%rJ`v z+Iyaj6#6z1_yqilWC74)4p?=wu+lDP3xl7Q~ zoJ+lD#)4`oJ=V`Bv=ck5_J*qlBBLxPYwoW8PajB`R7RmJ7@UWSA?vR+dmAyG1 zlx_L^{J=hKTejhoC@}#P=tRdyw6kC!9~<+R{8p*&n))?vszQcI{Tq_qDzYj?v`<#& zqTW2BY!F~iocn9Ly+o^X`;#8vNzqDupFr#wY+ewLMHIS{xz93lHEAcn371?dckLF3#aTRW5v4-AWPR-BLV0 zczGOQv--1AT2h=8)_K<6(H_zTPIPq4`hCA!w_6FjN!tqW`f=m%IoAb7_p;|JrI-zj zEi2-AlK(Rn| zWhc4;bY4;_bC>UmH#q)d!xtPZv7-L#Z;^?w-81ArR2BdqbFS4cp6nLY6QEI>VVKw( z=KJb#344agKQZ#_G2z>*pVmdXq}JETiM^cOYW7BP&Lnihl#|8n-ZdsVRpZ?)*6!>p5(2a z(wbKbCa)6?wHpsD{MHM4{`A1jHlR5gYL!rAK3D$-w0H$xAcIy+-aUymeS)0rT3s^m zz1d{?`!T-n)E}bbWGc3T11yHIbUR63ZWHK}-#w z^lTIDwP#M2&8U=7pvc>={5XIwRw2Nu{j>Jb`F+c5LNc1~Pv?^Rq*QL5G7=58_;u=Y6a!U+jemb?;oG6&0g+n!%nRSP{k zyu8bP`A1Y16H@*BB1rPnu1hfqee+HG!V{{dU;O$>Zt(()H}fiU71sXlgVV0~O07=V zmbepiqv=_nNW6I^CcTBB2e%UiFHJP`p^hye-)VwkQZ;Wf&!&sv#O)#YZ07yf<*j_# z9{`ejIq}*ZGO+rRxTQM&>B30kw_JAPUWNfT9PJ9@ab7-O2mhJ&izW50oT^78X@@;y zGq3ic(q&S#H+*T`|97szw`Nq!xXP>z6Rb}7R7eV!DYRq!Zsq2(tetbZ?m+>1GOEHk z+D2wIODd|St_b1em7oYxwkRH4YIn6iRqz0rX{5>jY!usH1VV8&O8r z`jVC&8rn-M6Vik~K7th;Dmh)9CHLiN-kK#iqAD=_Ijl|Y88;}pLY1WrKv~Lg2_Lb` zEr}_3Yu6CMN~auX6A)q$P0Yv?gWY3#m>__VTW5^FyXcQKhykv>5GsGD54#n5csDDc z(ih-JQ#h=6P3#o=r#s6ga22iK6!uXhySUzto~dhEUP-$eA^j$8jCZF>qeEu3iG|ot zV#!sM7)7G|bNTdKSQ=hZis$ zGs0q%dKtk3Y<;3moXW_SHa3OigHLmK9M;aKNqmMOqaJoS>&dAt|5fRUagk?9Nm#P? z`nu32S*xCCgC68ye30zoG5&hM^~3B@i)S%nN_n~VnT;o~+(71uswB4>%nC=V!Qffb z6H{~(76rii=KW@0+XF|%>7pRtdFHMrXW-yO)%+i+P{Eb{^fS=U@4X2Fpdm3Ajt}-} zII=j&t0Xzbd5J`SU~!EtKIB>=8SOFp%;#I)^}6f=5cnLvi)0r+Sr`}mmif8V_qBM> zQX{d`w1BE)v6|kK68iU*oRkDkND>qNVnQ`%*Zq4HthACMb`OjSAmTIcZ+t5`ns#gg ziEUaaNH`o9*%b3DR=)8(Sh{f1xG!!oKX4h=M_8%XXg5v4pBe5T(yvU+e~y-J%(k>c zvt_57^cC||rZ;R@*aYiHo}^S8Sbub};g5-qSlf5L`?lHFf1L4Yip`%GSv%|gw?;NI zS50j#f)rFl-sciX!Ql_k%fd17C7Fc>pT0;9^oDr zl-T|vOVUHii}#k&N~LzMjUQ9K(resA9-OGNZn#QU%P;0S+>N`N&j}Ap^hnR~dOC(M zFA1VesWK@$+Huoh4kP#SL;L|)8vX0FP?eU6iL7lbG*HIJn;Dl8a#w+4f{M2KhhCl3 z&Xmjl>YNN}MVa?)L0gK*sV~_Apq_ybGT%ziKmHlmpCh7U;;UiSRPR>>VKWet(F#EC zJ+NVdI2oIH)caLnquc72(^<85Uj$y(mONjIl)}+FEKTtfov9X(?22R8n0D%DN0!psZZV0IPHlWhGr}Fy9-dGaCq+~m;a#w_97n#B zfb7WhU(_;--YW<#*iyiQNj{BsR1X@s;yCF~-?;i!G|Ch2nvA^8a2H(yj%(j6uf`BL z(sagl$PC0nTKo2{n^2@X926PZjkhZ52to@PFPVhOYChY)-@a-tZ&@dawgMlkFi&*l88A4VOjO`8XMLA+_6*F<8cU%G- z6K;&=glo!n&^`qSQPpJXyJajg^g~7}MjA%46a6iTsQmej+IyO$=ECE!z@mD`E+J~8 zB*j3A!R{<`zjsh+DIh;D+UybS9Y^s1NttfOw3XG2-k>i!tUb3qc{5AJj!FGH><{d0 zIyfu4L$I4jP#BI;04Hd*7z(D>IP6?ozGE6!=*Xp5P)lQEuO zcvGL{kKJd>d7VY<0HuA7OF_plk>*cXUCt;hXD^*+)IR=HDl5jk?vRY|mfyUXiV9!3 z%A6nT{-K`wE8*|qLr;x_5`pAtuR~MEInNdEeN0_{p=J<*3_Vq?C)t+x+e9sGT^_d8 zl=5d{%v*Rmu<3BYMNK02T-!b))Q&vb&-+Th_^w8KN#;hjpi4;YODu=R-{)`pUlTJH z?QKA+sHfm%FEo?ct?X%IyPlmp$ap0-ie7(U#03wYrppa;UQnu5c^R!+Cp8!d7mXp> zax#5JG^B}RW{kgee4A{D3}z}mF~m{%=&>uyzi}rC-4!RyZEDHhMUy5hMZuM&no@vL zGvBtGzI6K~)PurS#YSqPEI_u{^pgVOc(48IzPA>)EwP_lxly5iRudSi&d)?IHRW)O zVe#5m5Y{*Sz_A-|C|t3gY))9;D~2 zTQ6XRYB1D%^!a4a(Yw&@cw4)VAuDey3kRI)Cu@~-X_)(~jZR8gs^)NnkmAUSHfU`sCy=xi ztoUn_I%1URUr5_%ml04VQ2D&lRQlA-Hlj_W`NuPJx%~A_fFYnJ8%uTBNCZ}4m^&+< zxtk{DSAS1DL?uq7rtP~B$}I6{PYup-Xq}Ga0fR0JC5~ilLiNpjaI9my7J#VP|3&GZ z7&MT-rAT?8sP5K%J^Py5WI?k>Gx|->{bNIQ)~l^8=-KI68>tyscSxBylU((f%QHxI z@!q{Am0njaHD^^Q?RzhL3A)8y0*^`Y%x>kHjW}}Fi|FBX-r+Y-iFSBXryle)4Bw63 zx#~GROYwxKEE;ZAr+zu(d(}YT-nQCgU*eVIE>5ve+Fo+coI_Jp!rGA2#wv9B`05i@ z=O$dq8vMhmz)klfv+w?lXO`#8pjfJsZOe+6Qq5lfSojnkK^K`H8 zU(T@m8HQ_Ms+gb?a?EN*lvDN;;;YE;{&(zcf$242Bl;Q=E(Fq)aGif!L_p`W@A|Aw zxUf#ZVSg=J!z4rgYR!Hd0}+i<&UCA~k@%2G4y~?9p9l@jz+gkahd{hD9R4_sITSE@ zo%e9ui}Bdd?H>7F*+PCh^8(0gJX3h|*rwUzMX~NsV0L{AbG&=7IC}m88T9t=l56<+ zOIYt&J;E0z??buRoa)bZL_nil;{_b-^Ac$cZ$+Cqd}4Ty#&+8lFNuzSbw9B6bQe$y zN&;y^KFjR1aJqJo=nrZdII;;sLp~;S0Df|rXsMcrjjAaGQVT#^9t`a3g;ZZ;I1aD2 zna;fC>>8>sZywu4o#8002Lxk^2&>L%*HHK3Bj;2n+mndNJI~~Hm|EYrN8DeYSmUz1 zq4P2%XF}?yujZl>OLhW%zRls%V%fi4tG5zglrl_Pm5iqm`qpmx*+LpX%g_qNTa(X? zX!hL%d z-Au$D8~NtaCOwcjpDX(D%K|Es)V)Y{-%fSq-nHZmCYUY40~ty zR42n1+?KoJZx{b6F5a`oC02xuk9wnt-!(+hXO0O}zKHn3BWcbBY=2cuL&reZT@?f!EnUS%OCB^al^fJ)~eTVSa^*7xbm|{97T{j~iQ@DUk_PoaU69PCg_|n|6Xl zJ{DV2q@lN&V>yrRMsS1%Sz7J93NU=wyWjs$8Oiwh7 zGwhv^7=(^?9w)VxvXcgQ@2%X48cM>$pvS)>VLU&OUG%ec;O`EIJuGvaH@jPZ+=B4D zPx{=>Ru{7yYxZYJx^U#6ysb$t`+fo$^mPc#4ZSArMEaop3BB&el>W_E|51kgQ*IEI z;-pG?|DEzj%fB6OpoiSK`NN!){NxX>I@9b(p?p3M3g4P)&}Fk3y3z#erYTOk(6*3| zb4Xvtbq;txDzpY1`P}{QbpOAFB>#Ol|J8mlL=gIjrllH=XK`lS{GWsGK(|4F zkH?JRi92sD%!QV>!fV%fRLJ+5rvt254kg2LbZa+o;u`Mr*ms?h%=YrW!Ry-jkiwcpIqfMbNbRj3^%@fQ1H3~bG~-G2hLCoU~m_O!*S{t4k5blvqO)= z9EXs`RTLzl-PwVcgT-;asBs8qG?diy91lofKjt)2rc-7hA(tfxFmr?Hi$lA>MZ(ZX444s>;l>)hQr_Q%*@PmSd$}>38_@d1=4?UyC{i czhJ3-6EkB9r^7gK@>V=GWvy3LidGT-3mCQ^bN~PV literal 0 HcmV?d00001 From f623191b0c805ba7ab35d8b7ba9c1ecb63af0fff Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 2 Apr 2019 15:56:11 -0700 Subject: [PATCH 0002/1772] Add a simple README and Contributing.md. --- proposals/random/Contributing.md | 8 ++++++++ proposals/random/README.md | 17 +++++++++++++++++ proposals/random/WASI.png | Bin 0 -> 11059 bytes 3 files changed, 25 insertions(+) create mode 100644 proposals/random/Contributing.md create mode 100644 proposals/random/README.md create mode 100644 proposals/random/WASI.png diff --git a/proposals/random/Contributing.md b/proposals/random/Contributing.md new file mode 100644 index 000000000..1cc607fa4 --- /dev/null +++ b/proposals/random/Contributing.md @@ -0,0 +1,8 @@ +# Contributing to WebAssembly + +Interested in participating? Please follow +[the same contributing guidelines as the design repository][]. + + [the same contributing guidelines as the design repository]: https://github.com/WebAssembly/design/blob/master/Contributing.md + +Also, please be sure to read [the README.md](README.md) for this repository. diff --git a/proposals/random/README.md b/proposals/random/README.md new file mode 100644 index 000000000..05d744744 --- /dev/null +++ b/proposals/random/README.md @@ -0,0 +1,17 @@ +# WebAssembly System Interface + +![WASI](WASI.png) + +This repository accompanies the WebAssembly WASI Subgroup, +focused on the design of the WASI, the WebAssembly System Interface. + +We'll be adding more content here, but for now, check out these: + - https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ - Blog post introducing WASI + - https://wasi.dev/ - Links to more information about WASI + - https://github.com/WebAssembly/WASI/issues - This repo's issue tracker + +The issue tracker is the place to ask questions, make suggestions, and start +discussions. + +As a W3C CG Subgroup, we'll also be having meetings. Once we have a schedule +for those, we'll post that here also. diff --git a/proposals/random/WASI.png b/proposals/random/WASI.png new file mode 100644 index 0000000000000000000000000000000000000000..bb018e99e3ec2a66d8f2d6a7bcc63105b74d9262 GIT binary patch literal 11059 zcmdsdcTiKo+b%_lbU}*rqM#rk(xpT|1f+`ej!5s)Yv`yTASgv3bdV0xLkS(Eo6sSI z-btvThTQnOGvCbp@0&Z{{pTigCbN6??ECDydv@RV$@5u9ONEk*nG6pPk5Wzbl`bA0 z{(mk~Vq8t`lpzZDL;PM{@|oudLkND#=h;BUO$>jKmAAL!(^RtaaD zcqPu5--0PggunD?lNe;Ec$F0u=+!tqi3pykveI%c^?B;jMC66}5RrX+8TPVG-k@$t zsoa#AO|+mTaI6Egbw1279$)XQ4ui0dI7!a%kf~vF2}o#e6dd)Jq{UQ@a8JC&Y&A0yClJI%bqLx)p8Nu@_2ELZQz~bAwU-` zjNtOX@;5wjVL73l)e7_%-}-}{kTi!%olwF+_vf8CcsVdreP%gTplVt;$K@^c_=!Lc z%B6;N1JC0IA0jD8rt9b(E`+a~d!%@3@JV)i2z)1>(=~YWqPFGWE4omNHFK0e#yjZM z{lZaBv1UI>tBxkTp#PLL-+m+L`Fi{Tgy}rqh1iAT!`bfTD^4?Eqx7TLNU%`f6vK;)D=kOd1xeX0QM0Q$+m}Z#+c9&oXyO zXGeVb;stIT4BmrI1irsaIdqK!WQv*LS|$Vw{_D$YySKI*VXRr(q@+DQdUl32X;ONn zFdyHD2Rz5!K?83UCHWFYmtZ6S&x+3RP+w}k1bX>9tgr)`w@DJ^=L8%wp8IbO7s*YL zbB}L7Q#1PGP-(FWoZ@4(niOz7jVLbDO&nz>q0>MYgNw!T%SSdupzB~sKF|}UWdMGw z56eG?RIyzA>llRZkMwJmI0y&H87yBif??S0HN(GnDW4)v<)PGV9;-Z#>GG|2HE(d! z7%OQ3+Py?S5@{t#-A+*UmbQjE!r67;pv>T%_%7N_5L| zh$#$m|Ds9<9m;5UKmrL`HCh3@7zRji^=V_>{63260b~bC0G6#g*nPjT;~m7@@urg) zc^jR7f;UmhCowObEGYvIFogwgI0w-!$+OEva`+D)v8~o{^G+4Rj>1OEKx8x$Qa#LB zriw}{mJcRw#*+o&j0kteN3sOr?kzN)VbM*D5y7eWB<-E@(91l8`U{ztI3G|~w0COb zD|=Mq^J%jRWZ}Pg*=Dj+ZMNV_l|T?{5TS=_a?BgBT>3-!UO<@Rq{XXO3jDa4rN8$! z>C30bs>=VP*wv5N9; zZk(wlH>FBQA@qK9sZjVoF!u|&{||8g6J;{pd;c}qfBpU6mR%ZueakUpQltqxxvWAn~wd*u;(OPQ3~dOj|&4;24}nh}3mJ zV6ospuj#|%GutPWjXLw})}mGhkqnzZ2a$_R;<(I?fCANVHKaCouSt>3QIREhY+|EPc z3L)_ZSbXLbJvPIz6YTnJT0r?D9sTnY5h1aib2sn3s`nYeSc9t28Famq#Ts4X{JoFc zCBhSzyAia%=OXKMJ*?;sE)ONe`^#|D_;EC#s;V054kZ(NYWjvynt|QPW^+eqlVdNp zS&sWxm>Q=^MafUiNZ+$DqK(s>qK>D1UF`iG1+mk^^k56)+@KHPV>66{T86cARyG29 zBod4|2MIL~>g?zM$cGqq$6L+@hGITJb@GJ9gn7w^0$9>G%ck8fHIy?9S$PYXZ0MV) zbIoQ;qWUNp(`60O^$mpTru#pm&H*I7oQ>@3p}$}%(<*n{|c{xFvB?e#k(^H26BL`NQ&VO0TM zi9R$%xGtGM!rBNOCu~^sxW!czB%-w$Aujv!vi8xG!_x%^_#AK>PK>qY$%v zspccYKxs@tP)2|~qni8yVf&VTMr7_!Dl$y~Y_x@Av2XvK`5jxztH-J+ZdLNSggAT5 zwVDi=a^;1S3mua$sv1SoL`{TSCt!q&0$zJaXd2ukJ)?fWJ_UEFt*Pf5?_28`0W2x#=%<%C zLY8Klqg#yCY1inJ2xSyaj$@#|%lG;gB$+1JI$P1P-rhvW-RyV; zx3nHDVG2C={ZAcU@wV2Ub7hL}2T83%Th=?AmNI)iaS&S2Ggl(|yFYDqD54&z?`_!5 zj|-<{meHm@HS);oYGmR!ef|{XU>)G+%nY4mg!U_XJ|5UcFn>S^Cnj?UtPoJ*0?a+Z zG{VOk#<+DELfBB=9KI5k+NQQ;dL{pwG!f9yF+7nh>BGo^^9X44YU9zsWYihE*qisW zwUQ6xCD5aG1pWi9qFFNZL9v0NQQN(i$c-VyHbgqv;yMNX?Md%xur25oE3Lc`y^*QE z(ld8U#qIZC5RHac}Qv z`inGO=7bLCkd%k#@~p|ur6~Kr#v*+$!6|+-dG}fnra+A%i28NCpNm%CES#>!M%#Zz z-G+r*RnSaUe%~-ECJAD)nx}34e!SX@>v7S$!f9A<;{&B+@@?6=-mV;JZ3Gq+(aWR3 zrq@bfm$Tm;?KCf-x)<74LU*!dhe@dgs=U-uQEv1xt*OH259W(IaHk6Fjo{D^JSgDt7G=r-sJ_wErt3*UcACN=rSllcs%F5__(XN)RIu)v+!j>Y zf4{Vq#eJb2P~lAU*9OFcCO=6ya-J>+`wC=Mow`v=xN5eE)P$(0BCI@ST3y=V7-jYA zd5;F-b&4ou6;#exVMtac=N}^P_TMkvey=ukEJfEeSJS^us^U?#zWHhEIfjC_qE>!Y zy+y{dx3qG?Yxz#8kdJM)=XGUvlJAVQBLRaS1St+E+Cu%V63pgS4m2(0=jSP}+1-}@ zT=pwAh#r%@W_-D~LAzq76(dO_$XBoN9cG&$-ufuF*;HZvQ+^Eah(ss7Rs-%KyMBaW z%Z_QJQmXBrb|33Xt=z22>?Z6{U|v)^s96BcqCWD~u6;Fpk8;$I@T54P+F3G@;VkBT z3c0Bp)<{^$oO1Tl?o7NbmpB&ZJ@)fuq2l;_0R-yJ9k!I6M|m|#92}BD7eDNP^akg4 zykUl>Yd_~HdMp2}pPB22Jk5bm^31-p5x#lIA%-!}#CpXy z&!x#@a}EVWQtk+4CA14brL;&oUc7L&%ydqpBZH-G^qFS18aW4Cs*4~FJLYE!ngF?8 z>Mx7-e|~h9W0|Tghss?Lt_62axF?EUbVnHyIn%zTHWH*q1%(?B!zV7~suov7vS+w3A1|lKYl7Cm4Ly>D7ZC>~+)lIkkGt=Ri1X5>Tj$f_qcS}jL>CuwV%X6>prp+gTVy=(cLq`IpUp*6>C=x2M}=z z7#wrr+GWmWbKGe3U{M4#{4|o^>?S<>;pO49v^w`Fb78r4;K6Uin;f&H3h6X4HLLNi zdHwZhn20d26usjfMD@y9>+WwgFxgO3_swpa4OW?exDiFVjVuijaE~`-*mSG&MZB!t zZkFGjY2%ouhe}%g^wM%%b!gYct=g2AE1xA^W6_)&9WLM}pO5u^N~;!-YPFjc?HX(D zoANwP={-8Mxz}KDY0lA*70}?@ygys#`rhVmQBvJhSx30`>^2#-2x=Qpbo{@3E)doxNfdUCIPTJz~N(R+?RGYwm z7+{2ZuYOi@Q&JiVUsuZkF1E8J=TzVOUmVS!XpVO!;I(nXINRqd_)8EZn`Bo76 zXtOlU2KB?ZftQ2%#Qf?DH`C$+iH-Y@Sss8bjUP(BMFS7? z^A7z<7_}(8(6PRv=q~wH^rxD1DuU8CKZ@@{pGE!k@*FM5Fg&9qZmLYrip0I4_I?L7 zU~hSA&#|}s)1f8%0Pkx~9|mwBwC6ZDzRjr8+16l&0iszdV4Kd|)GYITOaV_cCBZoj zBVURJutKNcS(w6Nr@153wdNPRuIUfqEurW?TCXAYNi*^RVJ935f7XM7NNH7?vuN~O z=52GW^phlhOZAs4-toVv{p2(UNBhZs6e|nhwzrL`SW-bgQ%rJ`v z+Iyaj6#6z1_yqilWC74)4p?=wu+lDP3xl7Q~ zoJ+lD#)4`oJ=V`Bv=ck5_J*qlBBLxPYwoW8PajB`R7RmJ7@UWSA?vR+dmAyG1 zlx_L^{J=hKTejhoC@}#P=tRdyw6kC!9~<+R{8p*&n))?vszQcI{Tq_qDzYj?v`<#& zqTW2BY!F~iocn9Ly+o^X`;#8vNzqDupFr#wY+ewLMHIS{xz93lHEAcn371?dckLF3#aTRW5v4-AWPR-BLV0 zczGOQv--1AT2h=8)_K<6(H_zTPIPq4`hCA!w_6FjN!tqW`f=m%IoAb7_p;|JrI-zj zEi2-AlK(Rn| zWhc4;bY4;_bC>UmH#q)d!xtPZv7-L#Z;^?w-81ArR2BdqbFS4cp6nLY6QEI>VVKw( z=KJb#344agKQZ#_G2z>*pVmdXq}JETiM^cOYW7BP&Lnihl#|8n-ZdsVRpZ?)*6!>p5(2a z(wbKbCa)6?wHpsD{MHM4{`A1jHlR5gYL!rAK3D$-w0H$xAcIy+-aUymeS)0rT3s^m zz1d{?`!T-n)E}bbWGc3T11yHIbUR63ZWHK}-#w z^lTIDwP#M2&8U=7pvc>={5XIwRw2Nu{j>Jb`F+c5LNc1~Pv?^Rq*QL5G7=58_;u=Y6a!U+jemb?;oG6&0g+n!%nRSP{k zyu8bP`A1Y16H@*BB1rPnu1hfqee+HG!V{{dU;O$>Zt(()H}fiU71sXlgVV0~O07=V zmbepiqv=_nNW6I^CcTBB2e%UiFHJP`p^hye-)VwkQZ;Wf&!&sv#O)#YZ07yf<*j_# z9{`ejIq}*ZGO+rRxTQM&>B30kw_JAPUWNfT9PJ9@ab7-O2mhJ&izW50oT^78X@@;y zGq3ic(q&S#H+*T`|97szw`Nq!xXP>z6Rb}7R7eV!DYRq!Zsq2(tetbZ?m+>1GOEHk z+D2wIODd|St_b1em7oYxwkRH4YIn6iRqz0rX{5>jY!usH1VV8&O8r z`jVC&8rn-M6Vik~K7th;Dmh)9CHLiN-kK#iqAD=_Ijl|Y88;}pLY1WrKv~Lg2_Lb` zEr}_3Yu6CMN~auX6A)q$P0Yv?gWY3#m>__VTW5^FyXcQKhykv>5GsGD54#n5csDDc z(ih-JQ#h=6P3#o=r#s6ga22iK6!uXhySUzto~dhEUP-$eA^j$8jCZF>qeEu3iG|ot zV#!sM7)7G|bNTdKSQ=hZis$ zGs0q%dKtk3Y<;3moXW_SHa3OigHLmK9M;aKNqmMOqaJoS>&dAt|5fRUagk?9Nm#P? z`nu32S*xCCgC68ye30zoG5&hM^~3B@i)S%nN_n~VnT;o~+(71uswB4>%nC=V!Qffb z6H{~(76rii=KW@0+XF|%>7pRtdFHMrXW-yO)%+i+P{Eb{^fS=U@4X2Fpdm3Ajt}-} zII=j&t0Xzbd5J`SU~!EtKIB>=8SOFp%;#I)^}6f=5cnLvi)0r+Sr`}mmif8V_qBM> zQX{d`w1BE)v6|kK68iU*oRkDkND>qNVnQ`%*Zq4HthACMb`OjSAmTIcZ+t5`ns#gg ziEUaaNH`o9*%b3DR=)8(Sh{f1xG!!oKX4h=M_8%XXg5v4pBe5T(yvU+e~y-J%(k>c zvt_57^cC||rZ;R@*aYiHo}^S8Sbub};g5-qSlf5L`?lHFf1L4Yip`%GSv%|gw?;NI zS50j#f)rFl-sciX!Ql_k%fd17C7Fc>pT0;9^oDr zl-T|vOVUHii}#k&N~LzMjUQ9K(resA9-OGNZn#QU%P;0S+>N`N&j}Ap^hnR~dOC(M zFA1VesWK@$+Huoh4kP#SL;L|)8vX0FP?eU6iL7lbG*HIJn;Dl8a#w+4f{M2KhhCl3 z&Xmjl>YNN}MVa?)L0gK*sV~_Apq_ybGT%ziKmHlmpCh7U;;UiSRPR>>VKWet(F#EC zJ+NVdI2oIH)caLnquc72(^<85Uj$y(mONjIl)}+FEKTtfov9X(?22R8n0D%DN0!psZZV0IPHlWhGr}Fy9-dGaCq+~m;a#w_97n#B zfb7WhU(_;--YW<#*iyiQNj{BsR1X@s;yCF~-?;i!G|Ch2nvA^8a2H(yj%(j6uf`BL z(sagl$PC0nTKo2{n^2@X926PZjkhZ52to@PFPVhOYChY)-@a-tZ&@dawgMlkFi&*l88A4VOjO`8XMLA+_6*F<8cU%G- z6K;&=glo!n&^`qSQPpJXyJajg^g~7}MjA%46a6iTsQmej+IyO$=ECE!z@mD`E+J~8 zB*j3A!R{<`zjsh+DIh;D+UybS9Y^s1NttfOw3XG2-k>i!tUb3qc{5AJj!FGH><{d0 zIyfu4L$I4jP#BI;04Hd*7z(D>IP6?ozGE6!=*Xp5P)lQEuO zcvGL{kKJd>d7VY<0HuA7OF_plk>*cXUCt;hXD^*+)IR=HDl5jk?vRY|mfyUXiV9!3 z%A6nT{-K`wE8*|qLr;x_5`pAtuR~MEInNdEeN0_{p=J<*3_Vq?C)t+x+e9sGT^_d8 zl=5d{%v*Rmu<3BYMNK02T-!b))Q&vb&-+Th_^w8KN#;hjpi4;YODu=R-{)`pUlTJH z?QKA+sHfm%FEo?ct?X%IyPlmp$ap0-ie7(U#03wYrppa;UQnu5c^R!+Cp8!d7mXp> zax#5JG^B}RW{kgee4A{D3}z}mF~m{%=&>uyzi}rC-4!RyZEDHhMUy5hMZuM&no@vL zGvBtGzI6K~)PurS#YSqPEI_u{^pgVOc(48IzPA>)EwP_lxly5iRudSi&d)?IHRW)O zVe#5m5Y{*Sz_A-|C|t3gY))9;D~2 zTQ6XRYB1D%^!a4a(Yw&@cw4)VAuDey3kRI)Cu@~-X_)(~jZR8gs^)NnkmAUSHfU`sCy=xi ztoUn_I%1URUr5_%ml04VQ2D&lRQlA-Hlj_W`NuPJx%~A_fFYnJ8%uTBNCZ}4m^&+< zxtk{DSAS1DL?uq7rtP~B$}I6{PYup-Xq}Ga0fR0JC5~ilLiNpjaI9my7J#VP|3&GZ z7&MT-rAT?8sP5K%J^Py5WI?k>Gx|->{bNIQ)~l^8=-KI68>tyscSxBylU((f%QHxI z@!q{Am0njaHD^^Q?RzhL3A)8y0*^`Y%x>kHjW}}Fi|FBX-r+Y-iFSBXryle)4Bw63 zx#~GROYwxKEE;ZAr+zu(d(}YT-nQCgU*eVIE>5ve+Fo+coI_Jp!rGA2#wv9B`05i@ z=O$dq8vMhmz)klfv+w?lXO`#8pjfJsZOe+6Qq5lfSojnkK^K`H8 zU(T@m8HQ_Ms+gb?a?EN*lvDN;;;YE;{&(zcf$242Bl;Q=E(Fq)aGif!L_p`W@A|Aw zxUf#ZVSg=J!z4rgYR!Hd0}+i<&UCA~k@%2G4y~?9p9l@jz+gkahd{hD9R4_sITSE@ zo%e9ui}Bdd?H>7F*+PCh^8(0gJX3h|*rwUzMX~NsV0L{AbG&=7IC}m88T9t=l56<+ zOIYt&J;E0z??buRoa)bZL_nil;{_b-^Ac$cZ$+Cqd}4Ty#&+8lFNuzSbw9B6bQe$y zN&;y^KFjR1aJqJo=nrZdII;;sLp~;S0Df|rXsMcrjjAaGQVT#^9t`a3g;ZZ;I1aD2 zna;fC>>8>sZywu4o#8002Lxk^2&>L%*HHK3Bj;2n+mndNJI~~Hm|EYrN8DeYSmUz1 zq4P2%XF}?yujZl>OLhW%zRls%V%fi4tG5zglrl_Pm5iqm`qpmx*+LpX%g_qNTa(X? zX!hL%d z-Au$D8~NtaCOwcjpDX(D%K|Es)V)Y{-%fSq-nHZmCYUY40~ty zR42n1+?KoJZx{b6F5a`oC02xuk9wnt-!(+hXO0O}zKHn3BWcbBY=2cuL&reZT@?f!EnUS%OCB^al^fJ)~eTVSa^*7xbm|{97T{j~iQ@DUk_PoaU69PCg_|n|6Xl zJ{DV2q@lN&V>yrRMsS1%Sz7J93NU=wyWjs$8Oiwh7 zGwhv^7=(^?9w)VxvXcgQ@2%X48cM>$pvS)>VLU&OUG%ec;O`EIJuGvaH@jPZ+=B4D zPx{=>Ru{7yYxZYJx^U#6ysb$t`+fo$^mPc#4ZSArMEaop3BB&el>W_E|51kgQ*IEI z;-pG?|DEzj%fB6OpoiSK`NN!){NxX>I@9b(p?p3M3g4P)&}Fk3y3z#erYTOk(6*3| zb4Xvtbq;txDzpY1`P}{QbpOAFB>#Ol|J8mlL=gIjrllH=XK`lS{GWsGK(|4F zkH?JRi92sD%!QV>!fV%fRLJ+5rvt254kg2LbZa+o;u`Mr*ms?h%=YrW!Ry-jkiwcpIqfMbNbRj3^%@fQ1H3~bG~-G2hLCoU~m_O!*S{t4k5blvqO)= z9EXs`RTLzl-PwVcgT-;asBs8qG?diy91lofKjt)2rc-7hA(tfxFmr?Hi$lA>MZ(ZX444s>;l>)hQr_Q%*@PmSd$}>38_@d1=4?UyC{i czhJ3-6EkB9r^7gK@>V=GWvy3LidGT-3mCQ^bN~PV literal 0 HcmV?d00001 From 147af48a9a83aeef6af3970abf6335f877309658 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 2 Apr 2019 15:56:11 -0700 Subject: [PATCH 0003/1772] Add a simple README and Contributing.md. --- proposals/filesystem/Contributing.md | 8 ++++++++ proposals/filesystem/README.md | 17 +++++++++++++++++ proposals/filesystem/WASI.png | Bin 0 -> 11059 bytes 3 files changed, 25 insertions(+) create mode 100644 proposals/filesystem/Contributing.md create mode 100644 proposals/filesystem/README.md create mode 100644 proposals/filesystem/WASI.png diff --git a/proposals/filesystem/Contributing.md b/proposals/filesystem/Contributing.md new file mode 100644 index 000000000..1cc607fa4 --- /dev/null +++ b/proposals/filesystem/Contributing.md @@ -0,0 +1,8 @@ +# Contributing to WebAssembly + +Interested in participating? Please follow +[the same contributing guidelines as the design repository][]. + + [the same contributing guidelines as the design repository]: https://github.com/WebAssembly/design/blob/master/Contributing.md + +Also, please be sure to read [the README.md](README.md) for this repository. diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md new file mode 100644 index 000000000..05d744744 --- /dev/null +++ b/proposals/filesystem/README.md @@ -0,0 +1,17 @@ +# WebAssembly System Interface + +![WASI](WASI.png) + +This repository accompanies the WebAssembly WASI Subgroup, +focused on the design of the WASI, the WebAssembly System Interface. + +We'll be adding more content here, but for now, check out these: + - https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ - Blog post introducing WASI + - https://wasi.dev/ - Links to more information about WASI + - https://github.com/WebAssembly/WASI/issues - This repo's issue tracker + +The issue tracker is the place to ask questions, make suggestions, and start +discussions. + +As a W3C CG Subgroup, we'll also be having meetings. Once we have a schedule +for those, we'll post that here also. diff --git a/proposals/filesystem/WASI.png b/proposals/filesystem/WASI.png new file mode 100644 index 0000000000000000000000000000000000000000..bb018e99e3ec2a66d8f2d6a7bcc63105b74d9262 GIT binary patch literal 11059 zcmdsdcTiKo+b%_lbU}*rqM#rk(xpT|1f+`ej!5s)Yv`yTASgv3bdV0xLkS(Eo6sSI z-btvThTQnOGvCbp@0&Z{{pTigCbN6??ECDydv@RV$@5u9ONEk*nG6pPk5Wzbl`bA0 z{(mk~Vq8t`lpzZDL;PM{@|oudLkND#=h;BUO$>jKmAAL!(^RtaaD zcqPu5--0PggunD?lNe;Ec$F0u=+!tqi3pykveI%c^?B;jMC66}5RrX+8TPVG-k@$t zsoa#AO|+mTaI6Egbw1279$)XQ4ui0dI7!a%kf~vF2}o#e6dd)Jq{UQ@a8JC&Y&A0yClJI%bqLx)p8Nu@_2ELZQz~bAwU-` zjNtOX@;5wjVL73l)e7_%-}-}{kTi!%olwF+_vf8CcsVdreP%gTplVt;$K@^c_=!Lc z%B6;N1JC0IA0jD8rt9b(E`+a~d!%@3@JV)i2z)1>(=~YWqPFGWE4omNHFK0e#yjZM z{lZaBv1UI>tBxkTp#PLL-+m+L`Fi{Tgy}rqh1iAT!`bfTD^4?Eqx7TLNU%`f6vK;)D=kOd1xeX0QM0Q$+m}Z#+c9&oXyO zXGeVb;stIT4BmrI1irsaIdqK!WQv*LS|$Vw{_D$YySKI*VXRr(q@+DQdUl32X;ONn zFdyHD2Rz5!K?83UCHWFYmtZ6S&x+3RP+w}k1bX>9tgr)`w@DJ^=L8%wp8IbO7s*YL zbB}L7Q#1PGP-(FWoZ@4(niOz7jVLbDO&nz>q0>MYgNw!T%SSdupzB~sKF|}UWdMGw z56eG?RIyzA>llRZkMwJmI0y&H87yBif??S0HN(GnDW4)v<)PGV9;-Z#>GG|2HE(d! z7%OQ3+Py?S5@{t#-A+*UmbQjE!r67;pv>T%_%7N_5L| zh$#$m|Ds9<9m;5UKmrL`HCh3@7zRji^=V_>{63260b~bC0G6#g*nPjT;~m7@@urg) zc^jR7f;UmhCowObEGYvIFogwgI0w-!$+OEva`+D)v8~o{^G+4Rj>1OEKx8x$Qa#LB zriw}{mJcRw#*+o&j0kteN3sOr?kzN)VbM*D5y7eWB<-E@(91l8`U{ztI3G|~w0COb zD|=Mq^J%jRWZ}Pg*=Dj+ZMNV_l|T?{5TS=_a?BgBT>3-!UO<@Rq{XXO3jDa4rN8$! z>C30bs>=VP*wv5N9; zZk(wlH>FBQA@qK9sZjVoF!u|&{||8g6J;{pd;c}qfBpU6mR%ZueakUpQltqxxvWAn~wd*u;(OPQ3~dOj|&4;24}nh}3mJ zV6ospuj#|%GutPWjXLw})}mGhkqnzZ2a$_R;<(I?fCANVHKaCouSt>3QIREhY+|EPc z3L)_ZSbXLbJvPIz6YTnJT0r?D9sTnY5h1aib2sn3s`nYeSc9t28Famq#Ts4X{JoFc zCBhSzyAia%=OXKMJ*?;sE)ONe`^#|D_;EC#s;V054kZ(NYWjvynt|QPW^+eqlVdNp zS&sWxm>Q=^MafUiNZ+$DqK(s>qK>D1UF`iG1+mk^^k56)+@KHPV>66{T86cARyG29 zBod4|2MIL~>g?zM$cGqq$6L+@hGITJb@GJ9gn7w^0$9>G%ck8fHIy?9S$PYXZ0MV) zbIoQ;qWUNp(`60O^$mpTru#pm&H*I7oQ>@3p}$}%(<*n{|c{xFvB?e#k(^H26BL`NQ&VO0TM zi9R$%xGtGM!rBNOCu~^sxW!czB%-w$Aujv!vi8xG!_x%^_#AK>PK>qY$%v zspccYKxs@tP)2|~qni8yVf&VTMr7_!Dl$y~Y_x@Av2XvK`5jxztH-J+ZdLNSggAT5 zwVDi=a^;1S3mua$sv1SoL`{TSCt!q&0$zJaXd2ukJ)?fWJ_UEFt*Pf5?_28`0W2x#=%<%C zLY8Klqg#yCY1inJ2xSyaj$@#|%lG;gB$+1JI$P1P-rhvW-RyV; zx3nHDVG2C={ZAcU@wV2Ub7hL}2T83%Th=?AmNI)iaS&S2Ggl(|yFYDqD54&z?`_!5 zj|-<{meHm@HS);oYGmR!ef|{XU>)G+%nY4mg!U_XJ|5UcFn>S^Cnj?UtPoJ*0?a+Z zG{VOk#<+DELfBB=9KI5k+NQQ;dL{pwG!f9yF+7nh>BGo^^9X44YU9zsWYihE*qisW zwUQ6xCD5aG1pWi9qFFNZL9v0NQQN(i$c-VyHbgqv;yMNX?Md%xur25oE3Lc`y^*QE z(ld8U#qIZC5RHac}Qv z`inGO=7bLCkd%k#@~p|ur6~Kr#v*+$!6|+-dG}fnra+A%i28NCpNm%CES#>!M%#Zz z-G+r*RnSaUe%~-ECJAD)nx}34e!SX@>v7S$!f9A<;{&B+@@?6=-mV;JZ3Gq+(aWR3 zrq@bfm$Tm;?KCf-x)<74LU*!dhe@dgs=U-uQEv1xt*OH259W(IaHk6Fjo{D^JSgDt7G=r-sJ_wErt3*UcACN=rSllcs%F5__(XN)RIu)v+!j>Y zf4{Vq#eJb2P~lAU*9OFcCO=6ya-J>+`wC=Mow`v=xN5eE)P$(0BCI@ST3y=V7-jYA zd5;F-b&4ou6;#exVMtac=N}^P_TMkvey=ukEJfEeSJS^us^U?#zWHhEIfjC_qE>!Y zy+y{dx3qG?Yxz#8kdJM)=XGUvlJAVQBLRaS1St+E+Cu%V63pgS4m2(0=jSP}+1-}@ zT=pwAh#r%@W_-D~LAzq76(dO_$XBoN9cG&$-ufuF*;HZvQ+^Eah(ss7Rs-%KyMBaW z%Z_QJQmXBrb|33Xt=z22>?Z6{U|v)^s96BcqCWD~u6;Fpk8;$I@T54P+F3G@;VkBT z3c0Bp)<{^$oO1Tl?o7NbmpB&ZJ@)fuq2l;_0R-yJ9k!I6M|m|#92}BD7eDNP^akg4 zykUl>Yd_~HdMp2}pPB22Jk5bm^31-p5x#lIA%-!}#CpXy z&!x#@a}EVWQtk+4CA14brL;&oUc7L&%ydqpBZH-G^qFS18aW4Cs*4~FJLYE!ngF?8 z>Mx7-e|~h9W0|Tghss?Lt_62axF?EUbVnHyIn%zTHWH*q1%(?B!zV7~suov7vS+w3A1|lKYl7Cm4Ly>D7ZC>~+)lIkkGt=Ri1X5>Tj$f_qcS}jL>CuwV%X6>prp+gTVy=(cLq`IpUp*6>C=x2M}=z z7#wrr+GWmWbKGe3U{M4#{4|o^>?S<>;pO49v^w`Fb78r4;K6Uin;f&H3h6X4HLLNi zdHwZhn20d26usjfMD@y9>+WwgFxgO3_swpa4OW?exDiFVjVuijaE~`-*mSG&MZB!t zZkFGjY2%ouhe}%g^wM%%b!gYct=g2AE1xA^W6_)&9WLM}pO5u^N~;!-YPFjc?HX(D zoANwP={-8Mxz}KDY0lA*70}?@ygys#`rhVmQBvJhSx30`>^2#-2x=Qpbo{@3E)doxNfdUCIPTJz~N(R+?RGYwm z7+{2ZuYOi@Q&JiVUsuZkF1E8J=TzVOUmVS!XpVO!;I(nXINRqd_)8EZn`Bo76 zXtOlU2KB?ZftQ2%#Qf?DH`C$+iH-Y@Sss8bjUP(BMFS7? z^A7z<7_}(8(6PRv=q~wH^rxD1DuU8CKZ@@{pGE!k@*FM5Fg&9qZmLYrip0I4_I?L7 zU~hSA&#|}s)1f8%0Pkx~9|mwBwC6ZDzRjr8+16l&0iszdV4Kd|)GYITOaV_cCBZoj zBVURJutKNcS(w6Nr@153wdNPRuIUfqEurW?TCXAYNi*^RVJ935f7XM7NNH7?vuN~O z=52GW^phlhOZAs4-toVv{p2(UNBhZs6e|nhwzrL`SW-bgQ%rJ`v z+Iyaj6#6z1_yqilWC74)4p?=wu+lDP3xl7Q~ zoJ+lD#)4`oJ=V`Bv=ck5_J*qlBBLxPYwoW8PajB`R7RmJ7@UWSA?vR+dmAyG1 zlx_L^{J=hKTejhoC@}#P=tRdyw6kC!9~<+R{8p*&n))?vszQcI{Tq_qDzYj?v`<#& zqTW2BY!F~iocn9Ly+o^X`;#8vNzqDupFr#wY+ewLMHIS{xz93lHEAcn371?dckLF3#aTRW5v4-AWPR-BLV0 zczGOQv--1AT2h=8)_K<6(H_zTPIPq4`hCA!w_6FjN!tqW`f=m%IoAb7_p;|JrI-zj zEi2-AlK(Rn| zWhc4;bY4;_bC>UmH#q)d!xtPZv7-L#Z;^?w-81ArR2BdqbFS4cp6nLY6QEI>VVKw( z=KJb#344agKQZ#_G2z>*pVmdXq}JETiM^cOYW7BP&Lnihl#|8n-ZdsVRpZ?)*6!>p5(2a z(wbKbCa)6?wHpsD{MHM4{`A1jHlR5gYL!rAK3D$-w0H$xAcIy+-aUymeS)0rT3s^m zz1d{?`!T-n)E}bbWGc3T11yHIbUR63ZWHK}-#w z^lTIDwP#M2&8U=7pvc>={5XIwRw2Nu{j>Jb`F+c5LNc1~Pv?^Rq*QL5G7=58_;u=Y6a!U+jemb?;oG6&0g+n!%nRSP{k zyu8bP`A1Y16H@*BB1rPnu1hfqee+HG!V{{dU;O$>Zt(()H}fiU71sXlgVV0~O07=V zmbepiqv=_nNW6I^CcTBB2e%UiFHJP`p^hye-)VwkQZ;Wf&!&sv#O)#YZ07yf<*j_# z9{`ejIq}*ZGO+rRxTQM&>B30kw_JAPUWNfT9PJ9@ab7-O2mhJ&izW50oT^78X@@;y zGq3ic(q&S#H+*T`|97szw`Nq!xXP>z6Rb}7R7eV!DYRq!Zsq2(tetbZ?m+>1GOEHk z+D2wIODd|St_b1em7oYxwkRH4YIn6iRqz0rX{5>jY!usH1VV8&O8r z`jVC&8rn-M6Vik~K7th;Dmh)9CHLiN-kK#iqAD=_Ijl|Y88;}pLY1WrKv~Lg2_Lb` zEr}_3Yu6CMN~auX6A)q$P0Yv?gWY3#m>__VTW5^FyXcQKhykv>5GsGD54#n5csDDc z(ih-JQ#h=6P3#o=r#s6ga22iK6!uXhySUzto~dhEUP-$eA^j$8jCZF>qeEu3iG|ot zV#!sM7)7G|bNTdKSQ=hZis$ zGs0q%dKtk3Y<;3moXW_SHa3OigHLmK9M;aKNqmMOqaJoS>&dAt|5fRUagk?9Nm#P? z`nu32S*xCCgC68ye30zoG5&hM^~3B@i)S%nN_n~VnT;o~+(71uswB4>%nC=V!Qffb z6H{~(76rii=KW@0+XF|%>7pRtdFHMrXW-yO)%+i+P{Eb{^fS=U@4X2Fpdm3Ajt}-} zII=j&t0Xzbd5J`SU~!EtKIB>=8SOFp%;#I)^}6f=5cnLvi)0r+Sr`}mmif8V_qBM> zQX{d`w1BE)v6|kK68iU*oRkDkND>qNVnQ`%*Zq4HthACMb`OjSAmTIcZ+t5`ns#gg ziEUaaNH`o9*%b3DR=)8(Sh{f1xG!!oKX4h=M_8%XXg5v4pBe5T(yvU+e~y-J%(k>c zvt_57^cC||rZ;R@*aYiHo}^S8Sbub};g5-qSlf5L`?lHFf1L4Yip`%GSv%|gw?;NI zS50j#f)rFl-sciX!Ql_k%fd17C7Fc>pT0;9^oDr zl-T|vOVUHii}#k&N~LzMjUQ9K(resA9-OGNZn#QU%P;0S+>N`N&j}Ap^hnR~dOC(M zFA1VesWK@$+Huoh4kP#SL;L|)8vX0FP?eU6iL7lbG*HIJn;Dl8a#w+4f{M2KhhCl3 z&Xmjl>YNN}MVa?)L0gK*sV~_Apq_ybGT%ziKmHlmpCh7U;;UiSRPR>>VKWet(F#EC zJ+NVdI2oIH)caLnquc72(^<85Uj$y(mONjIl)}+FEKTtfov9X(?22R8n0D%DN0!psZZV0IPHlWhGr}Fy9-dGaCq+~m;a#w_97n#B zfb7WhU(_;--YW<#*iyiQNj{BsR1X@s;yCF~-?;i!G|Ch2nvA^8a2H(yj%(j6uf`BL z(sagl$PC0nTKo2{n^2@X926PZjkhZ52to@PFPVhOYChY)-@a-tZ&@dawgMlkFi&*l88A4VOjO`8XMLA+_6*F<8cU%G- z6K;&=glo!n&^`qSQPpJXyJajg^g~7}MjA%46a6iTsQmej+IyO$=ECE!z@mD`E+J~8 zB*j3A!R{<`zjsh+DIh;D+UybS9Y^s1NttfOw3XG2-k>i!tUb3qc{5AJj!FGH><{d0 zIyfu4L$I4jP#BI;04Hd*7z(D>IP6?ozGE6!=*Xp5P)lQEuO zcvGL{kKJd>d7VY<0HuA7OF_plk>*cXUCt;hXD^*+)IR=HDl5jk?vRY|mfyUXiV9!3 z%A6nT{-K`wE8*|qLr;x_5`pAtuR~MEInNdEeN0_{p=J<*3_Vq?C)t+x+e9sGT^_d8 zl=5d{%v*Rmu<3BYMNK02T-!b))Q&vb&-+Th_^w8KN#;hjpi4;YODu=R-{)`pUlTJH z?QKA+sHfm%FEo?ct?X%IyPlmp$ap0-ie7(U#03wYrppa;UQnu5c^R!+Cp8!d7mXp> zax#5JG^B}RW{kgee4A{D3}z}mF~m{%=&>uyzi}rC-4!RyZEDHhMUy5hMZuM&no@vL zGvBtGzI6K~)PurS#YSqPEI_u{^pgVOc(48IzPA>)EwP_lxly5iRudSi&d)?IHRW)O zVe#5m5Y{*Sz_A-|C|t3gY))9;D~2 zTQ6XRYB1D%^!a4a(Yw&@cw4)VAuDey3kRI)Cu@~-X_)(~jZR8gs^)NnkmAUSHfU`sCy=xi ztoUn_I%1URUr5_%ml04VQ2D&lRQlA-Hlj_W`NuPJx%~A_fFYnJ8%uTBNCZ}4m^&+< zxtk{DSAS1DL?uq7rtP~B$}I6{PYup-Xq}Ga0fR0JC5~ilLiNpjaI9my7J#VP|3&GZ z7&MT-rAT?8sP5K%J^Py5WI?k>Gx|->{bNIQ)~l^8=-KI68>tyscSxBylU((f%QHxI z@!q{Am0njaHD^^Q?RzhL3A)8y0*^`Y%x>kHjW}}Fi|FBX-r+Y-iFSBXryle)4Bw63 zx#~GROYwxKEE;ZAr+zu(d(}YT-nQCgU*eVIE>5ve+Fo+coI_Jp!rGA2#wv9B`05i@ z=O$dq8vMhmz)klfv+w?lXO`#8pjfJsZOe+6Qq5lfSojnkK^K`H8 zU(T@m8HQ_Ms+gb?a?EN*lvDN;;;YE;{&(zcf$242Bl;Q=E(Fq)aGif!L_p`W@A|Aw zxUf#ZVSg=J!z4rgYR!Hd0}+i<&UCA~k@%2G4y~?9p9l@jz+gkahd{hD9R4_sITSE@ zo%e9ui}Bdd?H>7F*+PCh^8(0gJX3h|*rwUzMX~NsV0L{AbG&=7IC}m88T9t=l56<+ zOIYt&J;E0z??buRoa)bZL_nil;{_b-^Ac$cZ$+Cqd}4Ty#&+8lFNuzSbw9B6bQe$y zN&;y^KFjR1aJqJo=nrZdII;;sLp~;S0Df|rXsMcrjjAaGQVT#^9t`a3g;ZZ;I1aD2 zna;fC>>8>sZywu4o#8002Lxk^2&>L%*HHK3Bj;2n+mndNJI~~Hm|EYrN8DeYSmUz1 zq4P2%XF}?yujZl>OLhW%zRls%V%fi4tG5zglrl_Pm5iqm`qpmx*+LpX%g_qNTa(X? zX!hL%d z-Au$D8~NtaCOwcjpDX(D%K|Es)V)Y{-%fSq-nHZmCYUY40~ty zR42n1+?KoJZx{b6F5a`oC02xuk9wnt-!(+hXO0O}zKHn3BWcbBY=2cuL&reZT@?f!EnUS%OCB^al^fJ)~eTVSa^*7xbm|{97T{j~iQ@DUk_PoaU69PCg_|n|6Xl zJ{DV2q@lN&V>yrRMsS1%Sz7J93NU=wyWjs$8Oiwh7 zGwhv^7=(^?9w)VxvXcgQ@2%X48cM>$pvS)>VLU&OUG%ec;O`EIJuGvaH@jPZ+=B4D zPx{=>Ru{7yYxZYJx^U#6ysb$t`+fo$^mPc#4ZSArMEaop3BB&el>W_E|51kgQ*IEI z;-pG?|DEzj%fB6OpoiSK`NN!){NxX>I@9b(p?p3M3g4P)&}Fk3y3z#erYTOk(6*3| zb4Xvtbq;txDzpY1`P}{QbpOAFB>#Ol|J8mlL=gIjrllH=XK`lS{GWsGK(|4F zkH?JRi92sD%!QV>!fV%fRLJ+5rvt254kg2LbZa+o;u`Mr*ms?h%=YrW!Ry-jkiwcpIqfMbNbRj3^%@fQ1H3~bG~-G2hLCoU~m_O!*S{t4k5blvqO)= z9EXs`RTLzl-PwVcgT-;asBs8qG?diy91lofKjt)2rc-7hA(tfxFmr?Hi$lA>MZ(ZX444s>;l>)hQr_Q%*@PmSd$}>38_@d1=4?UyC{i czhJ3-6EkB9r^7gK@>V=GWvy3LidGT-3mCQ^bN~PV literal 0 HcmV?d00001 From c1e38399b1f49338fa1123695456bb10fe47bdfe Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 16 Apr 2019 11:26:52 -0700 Subject: [PATCH 0004/1772] Add a HighLevelGoals.md document. --- proposals/clocks/docs/HighLevelGoals.md | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 proposals/clocks/docs/HighLevelGoals.md diff --git a/proposals/clocks/docs/HighLevelGoals.md b/proposals/clocks/docs/HighLevelGoals.md new file mode 100644 index 000000000..d6ddcb95c --- /dev/null +++ b/proposals/clocks/docs/HighLevelGoals.md @@ -0,0 +1,26 @@ +# WASI High-Level Goals + +(In the spirit of [WebAssembly's High-Level Goals](https://github.com/WebAssembly/design/blob/master/HighLevelGoals.md).) + +1. Define a portable, modular, runtime-independent, and WebAssembly-native API + to serve as a system interface which can be used by WebAssembly code to + interact with the outside world, that preserves the essential sandboxed + nature of WebAssembly through a [Capability-based] API design. +2. Specify and implement incrementally: + * Start with a Minimum Viable Product (MVP) for the standard, covering I/O + streams, filesystems, randomness, clocks, and program startup and + shutdown. + * Then add additional features, prioritized by feedback and experience. +3. Supplement API designs with documentation and tests, and, when feasible, + reference implementations which can be shared between wasm engines. +4. Make a great platform: + * Work with WebAssembly tool and library authors to help them provide + WASI support for their users. + * When being WebAssembly-native means the platform isn't directly + compatible with existing applications written for other platforms, + build tools and libraries to provide compatibility. + * Allow the overall API to evolve over time; to make changes to API + modules that have been standardized, build implementations of them + using libraries on top of new API modules to provide compatibility. + +[Capability-based]: https://en.wikipedia.org/wiki/Capability-based_security From 14cc9672de3c8fb3a8371b08168a75aef1aa32ca Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 16 Apr 2019 11:26:52 -0700 Subject: [PATCH 0005/1772] Add a HighLevelGoals.md document. --- proposals/random/docs/HighLevelGoals.md | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 proposals/random/docs/HighLevelGoals.md diff --git a/proposals/random/docs/HighLevelGoals.md b/proposals/random/docs/HighLevelGoals.md new file mode 100644 index 000000000..d6ddcb95c --- /dev/null +++ b/proposals/random/docs/HighLevelGoals.md @@ -0,0 +1,26 @@ +# WASI High-Level Goals + +(In the spirit of [WebAssembly's High-Level Goals](https://github.com/WebAssembly/design/blob/master/HighLevelGoals.md).) + +1. Define a portable, modular, runtime-independent, and WebAssembly-native API + to serve as a system interface which can be used by WebAssembly code to + interact with the outside world, that preserves the essential sandboxed + nature of WebAssembly through a [Capability-based] API design. +2. Specify and implement incrementally: + * Start with a Minimum Viable Product (MVP) for the standard, covering I/O + streams, filesystems, randomness, clocks, and program startup and + shutdown. + * Then add additional features, prioritized by feedback and experience. +3. Supplement API designs with documentation and tests, and, when feasible, + reference implementations which can be shared between wasm engines. +4. Make a great platform: + * Work with WebAssembly tool and library authors to help them provide + WASI support for their users. + * When being WebAssembly-native means the platform isn't directly + compatible with existing applications written for other platforms, + build tools and libraries to provide compatibility. + * Allow the overall API to evolve over time; to make changes to API + modules that have been standardized, build implementations of them + using libraries on top of new API modules to provide compatibility. + +[Capability-based]: https://en.wikipedia.org/wiki/Capability-based_security From 6460e1e2e58d1cfa878fc41d9bc45d5985e019aa Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 16 Apr 2019 11:26:52 -0700 Subject: [PATCH 0006/1772] Add a HighLevelGoals.md document. --- proposals/filesystem/docs/HighLevelGoals.md | 26 +++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 proposals/filesystem/docs/HighLevelGoals.md diff --git a/proposals/filesystem/docs/HighLevelGoals.md b/proposals/filesystem/docs/HighLevelGoals.md new file mode 100644 index 000000000..d6ddcb95c --- /dev/null +++ b/proposals/filesystem/docs/HighLevelGoals.md @@ -0,0 +1,26 @@ +# WASI High-Level Goals + +(In the spirit of [WebAssembly's High-Level Goals](https://github.com/WebAssembly/design/blob/master/HighLevelGoals.md).) + +1. Define a portable, modular, runtime-independent, and WebAssembly-native API + to serve as a system interface which can be used by WebAssembly code to + interact with the outside world, that preserves the essential sandboxed + nature of WebAssembly through a [Capability-based] API design. +2. Specify and implement incrementally: + * Start with a Minimum Viable Product (MVP) for the standard, covering I/O + streams, filesystems, randomness, clocks, and program startup and + shutdown. + * Then add additional features, prioritized by feedback and experience. +3. Supplement API designs with documentation and tests, and, when feasible, + reference implementations which can be shared between wasm engines. +4. Make a great platform: + * Work with WebAssembly tool and library authors to help them provide + WASI support for their users. + * When being WebAssembly-native means the platform isn't directly + compatible with existing applications written for other platforms, + build tools and libraries to provide compatibility. + * Allow the overall API to evolve over time; to make changes to API + modules that have been standardized, build implementations of them + using libraries on top of new API modules to provide compatibility. + +[Capability-based]: https://en.wikipedia.org/wiki/Capability-based_security From 4dfa989ff803797e7bc4e5b82698fbab464bd0e7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 4 Apr 2019 16:29:46 -0700 Subject: [PATCH 0007/1772] Add "liftoff" content. - Add a tentative agenda for the first meeting, though it isn't yet scheduled. - Create an intial directory structure with a few documents. --- proposals/clocks/Charter.md | 55 + proposals/clocks/README.md | 20 +- proposals/clocks/design/WASI-core.md | 2315 +++++++++++++++++ proposals/clocks/docs/WASI-overview.md | 147 ++ .../docs/wasi-software-architecture.png | Bin 0 -> 28267 bytes .../clocks/meetings/2019/WASI-liftoff.md | 64 + proposals/clocks/meetings/README.md | 15 + 7 files changed, 2610 insertions(+), 6 deletions(-) create mode 100644 proposals/clocks/Charter.md create mode 100644 proposals/clocks/design/WASI-core.md create mode 100644 proposals/clocks/docs/WASI-overview.md create mode 100644 proposals/clocks/docs/wasi-software-architecture.png create mode 100644 proposals/clocks/meetings/2019/WASI-liftoff.md create mode 100644 proposals/clocks/meetings/README.md diff --git a/proposals/clocks/Charter.md b/proposals/clocks/Charter.md new file mode 100644 index 000000000..b73293475 --- /dev/null +++ b/proposals/clocks/Charter.md @@ -0,0 +1,55 @@ +# WebAssembly System Interface Subgroup Charter + +The System Interface Subgroup is a sub-organization of the +[WebAssembly Community Group](https://www.w3.org/community/webassembly/) of the W3C. +As such, it is intended that its charter align with that of the CG. In particular, +the sections of the [CG charter](https://webassembly.github.io/cg-charter/) relating to +[Community and Business Group Process](https://webassembly.github.io/cg-charter/#process), +[Contribution Mechanics](https://webassembly.github.io/cg-charter/#contrib), +[Transparency](https://webassembly.github.io/cg-charter/#transparency), and +[Decision Process](https://webassembly.github.io/cg-charter/#decision) also apply to the Subgroup. + +## Goals + +The mission of this sugbroup is to provide a forum for pre-standardization +collaboration on a system interface API for WebAssembly programs. + +## Scope + +The Subgroup will consider topics related to system interface APIs, including: + +- APIs for host filesystems, network stacks, and other resources. +- APIs for graphics, audio, input devices +- APIs for encryption, format conversion, and other transformations + (particularly where hardware accelleration may be available on some plaforms) + + +## Deliverables + +### Specifications +The Subgroup may produce several kinds of specification-related work output: +- Creation of new specifications in standards bodies or working +groups (e.g. Wasm WG or TC39) +- Creation of new specifications outside of standards bodies +(e.g. similar to the LLVM object file format documentation in Wasm tool conventions) + +### Non-normative reports +The Subgroup may produce non-normative material such as requirements +documents, recommendations, and use cases. + +### Software +The Subgroup may produce software related to Wasm system interface APIs (either +as standalone libraries, tooling, or integration of interface-related +functionality in existing CG software such as Binaryen or WABT). Capabilities may +include: +- Libraries implementing external standard APIs in terms of WebAssembly + System Interface APIs +- Tools for producing code that uses WebAssembly System Interface APIs +- Tools for implementing WebAssembly APIs +- Tools for debugging programs using WebAssembly System Interface APIs + +## Amendments to this Charter and Chair Selection + +This charter may be amended, and Subgroup Chairs may be selected by vote of the full +WebAssembly Community Group. + diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 05d744744..4cf122cab 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -2,16 +2,24 @@ ![WASI](WASI.png) -This repository accompanies the WebAssembly WASI Subgroup, -focused on the design of the WASI, the WebAssembly System Interface. +This repository is for the WebAssembly System Interface (WASI) Subgroup of the +[WebAssembly Community Group]. Its [Charter] describes the goals, scope and +deliverables of the group. The repository may contain meeting notes, reports, +documentation, specifications and/or software produced by the group (although +larger projects may also have their own repositories). -We'll be adding more content here, but for now, check out these: +[WebAssembly Community Group](https://www.w3.org/community/webassembly/) +[Charter]: Charter.md + +We'll be adding more content here before long, but for now, check out these: - https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ - Blog post introducing WASI - - https://wasi.dev/ - Links to more information about WASI + - https://wasi.dev/ - Links to more information about WASI, including + how to get started using it. - https://github.com/WebAssembly/WASI/issues - This repo's issue tracker The issue tracker is the place to ask questions, make suggestions, and start discussions. -As a W3C CG Subgroup, we'll also be having meetings. Once we have a schedule -for those, we'll post that here also. +As a W3C CG Subgroup, we'll also be having [meetings](meetings/README.md). +A tentative agenda for the first meeting is [here](https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-liftoff.md). +Once we have a date and time, we'll post that here also. diff --git a/proposals/clocks/design/WASI-core.md b/proposals/clocks/design/WASI-core.md new file mode 100644 index 000000000..c4b256ad3 --- /dev/null +++ b/proposals/clocks/design/WASI-core.md @@ -0,0 +1,2315 @@ + + +# WASI Core API + +This is the API-level documentation for WASI Core. The function names +are prefixed with "\_\_wasi\_" to reflect how they are spelled in +flat-namespace contexts, however at the wasm module level, they are +unprefixed, because they're inside a module namespace (currently +"wasi\_unstable"). + +Functions that start with `__wasi_fd_` operate on file descriptors, +while functions that start with `__wasi_path_` operate on filesystem +paths, which are relative to directory file descriptors. + +Much inspiration and content here is derived from [CloudABI] and [POSIX], +though there are also several differences from CloudABI and POSIX. For +example, WASI Core has no concept of processes in the traditional Unix +sense. While wasm linear memories have some of the aspects of processes, +and it's possible to *emulate* the full semantics of processes on top of +them, this can sometimes be unnatural and inefficient. The goal for +WASI Core is to be a WebAssembly-native API that exposes APIs that fit +well into the underlying WebAssembly platform, rather than to directly +emulate other platforms. + +This is also a work in progress, and the API here is still evolving. + +[CloudABI]: https://github.com/NuxiNL/cloudabi +[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ + +## System calls + +- [`__wasi_args_get()`](#args_get) +- [`__wasi_args_sizes_get()`](#args_sizes_get) +- [`__wasi_clock_res_get()`](#clock_res_get) +- [`__wasi_clock_time_get()`](#clock_time_get) +- [`__wasi_environ_get()`](#environ_get) +- [`__wasi_environ_sizes_get()`](#environ_sizes_get) +- [`__wasi_fd_advise()`](#fd_advise) +- [`__wasi_fd_allocate()`](#fd_allocate) +- [`__wasi_fd_close()`](#fd_close) +- [`__wasi_fd_datasync()`](#fd_datasync) +- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) +- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) +- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) +- [`__wasi_fd_filestat_get()`](#fd_filestat_get) +- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) +- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) +- [`__wasi_fd_pread()`](#fd_pread) +- [`__wasi_fd_prestat_get()`](#fd_prestat_get) +- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) +- [`__wasi_fd_pwrite()`](#fd_pwrite) +- [`__wasi_fd_read()`](#fd_read) +- [`__wasi_fd_readdir()`](#fd_readdir) +- [`__wasi_fd_renumber()`](#fd_renumber) +- [`__wasi_fd_seek()`](#fd_seek) +- [`__wasi_fd_sync()`](#fd_sync) +- [`__wasi_fd_tell()`](#fd_tell) +- [`__wasi_fd_write()`](#fd_write) +- [`__wasi_path_create_directory()`](#path_create_directory) +- [`__wasi_path_filestat_get()`](#path_filestat_get) +- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) +- [`__wasi_path_link()`](#path_link) +- [`__wasi_path_open()`](#path_open) +- [`__wasi_path_readlink()`](#path_readlink) +- [`__wasi_path_remove_directory()`](#path_remove_directory) +- [`__wasi_path_rename()`](#path_rename) +- [`__wasi_path_symlink()`](#path_symlink) +- [`__wasi_path_unlink_file()`](#path_unlink_file) +- [`__wasi_poll_oneoff()`](#poll_oneoff) +- [`__wasi_proc_exit()`](#proc_exit) +- [`__wasi_proc_raise()`](#proc_raise) +- [`__wasi_random_get()`](#random_get) +- [`__wasi_sched_yield()`](#sched_yield) +- [`__wasi_sock_recv()`](#sock_recv) +- [`__wasi_sock_send()`](#sock_send) +- [`__wasi_sock_shutdown()`](#sock_shutdown) + +### `__wasi_args_get()` + +Read command-line argument data. + +The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + +Inputs: + +- char \*\*argv + + A pointer to a buffer to write the argument pointers. + +- char \*argv\_buf + + A pointer to a buffer to write the argument string data. + +### `__wasi_args_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*argc + + The number of arguments. + +- size\_t \*argv\_buf\_size + + The size of the argument string data. + +### `__wasi_clock_res_get()` + +Return the resolution of a clock. + +Implementations are required to provide a non-zero value for supported clocks. +For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). + +Note: This is similar to `clock_getres` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the resolution. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) resolution + + The resolution of the clock. + +### `__wasi_clock_time_get()` + +Return the time value of a clock. + +Note: This is similar to `clock_gettime` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the time. + +- [\_\_wasi\_timestamp\_t](#timestamp) precision + + The maximum lag (exclusive) that the returned + time value may have, compared to its actual + value. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) time + + The time value of the clock. + +### `__wasi_environ_get()` + +Read environment variable data. + +The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + +Inputs: + +- char \*\*environ + + A pointer to a buffer to write the environment variable pointers. + +- char \*environ\_buf + + A pointer to a buffer to write the environment variable string data. + +### `__wasi_environ_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*environ\_count + + The number of environment variables. + +- size\_t \*environ\_buf\_size + + The size of the environment variable string data. + +### `__wasi_fd_advise()` + +Provide file advisory information on a file descriptor. + +Note: This is similar to `posix_fadvise` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file for which to provide file advisory information. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file to which the advisory applies. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the region to which the advisory applies. + +- [\_\_wasi\_advice\_t](#advice) advice + + The advice. + +### `__wasi_fd_allocate()` + +Force the allocation of space in a file. + +Note: This is similar to `posix_fallocate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file in which to allocate space. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset at which to start the allocation. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the area that is allocated. + +### `__wasi_fd_close()` + +Close a file descriptor. + +Note: This is similar to `close` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to close. + +### `__wasi_fd_datasync()` + +Synchronize the data of a file to disk. + +Note: This is similar to `fdatasync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file to synchronize to disk. + +### `__wasi_fd_fdstat_get()` + +Get the attributes of a file descriptor. + +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well +as additional fields. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_fdstat\_t](#fdstat) \*buf + + The buffer where the file descriptor's attributes are stored. + +### `__wasi_fd_fdstat_set_flags()` + +Adjust the flags associated with a file descriptor. + +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_fdflags\_t](#fdflags) flags + + The desired values of the file descriptor + flags. + +### `__wasi_fd_fdstat_set_rights()` + +Adjust the rights associated with a file descriptor. + +This can only be used to remove rights, and returns +[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt +to add rights. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The desired rights of the file descriptor. + +### `__wasi_fd_filestat_get()` + +Return the attributes of an open file. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_fd_filestat_set_size()` + +Adjust the size of an open file. If this increases the file's size, the extra +bytes are filled with zeros. + +Note: This is similar to `ftruncate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + A file descriptor for the file to adjust. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + The desired file size. + +### `__wasi_fd_filestat_set_times()` + +Adjust the timestamps of an open file or directory. + +Note: This is similar to `futimens` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_fd_pread()` + +Read from a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `preadv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors in which to store data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to read. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_prestat_get()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- [\_\_wasi\_prestat\_t](#prestat) \*buf + + The buffer where the description is stored. + +### `__wasi_fd_prestat_dir_name()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- const char \*path and size\_t path\_len + + A buffer into which to write the preopened directory name. + +### `__wasi_fd_pwrite()` + +Write to a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `pwritev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to write. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_fd_read()` + +Read from a file descriptor. + +Note: This is similar to `readv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors to which to store data. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_readdir()` + +Read directory entries from a directory. + +When successful, the contents of the output buffer consist of +a sequence of directory entries. Each directory entry consists +of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes +holding the name of the directory entry. + +This function fills the output buffer as much as possible, +potentially truncating the last directory entry. This allows +the caller to grow its read buffer size in case it's too small +to fit a single large directory entry, or skip the oversized +directory entry. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The directory from which to read the directory + entries. + +- void \*buf and size\_t buf\_len + + The buffer where directory entries are stored. + +- [\_\_wasi\_dircookie\_t](#dircookie) cookie + + The location within the directory to start + reading. + +Outputs: + +- size\_t bufused + + The number of bytes stored in the read buffer. + If less than the size of the read buffer, the + end of the directory has been reached. + +### `__wasi_fd_renumber()` + +Atomically replace a file descriptor by renumbering another +file descriptor. + +Due to the strong focus on thread safety, this environment +does not provide a mechanism to duplicate or renumber a file +descriptor to an arbitrary number, like dup2(). This would be +prone to race conditions, as an actual file descriptor with the +same number could be allocated by a different thread at the same +time. + +This function provides a way to atomically renumber file +descriptors, which would disappear if dup2() were to be +removed entirely. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) from + + The file descriptor to renumber. + +- [\_\_wasi\_fd\_t](#fd) to + + The file descriptor to overwrite. + +### `__wasi_fd_seek()` + +Move the offset of a file descriptor. + +Note: This is similar to `lseek` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_filedelta\_t](#filedelta) offset + + The number of bytes to move. + +- [\_\_wasi\_whence\_t](#whence) whence + + The base from which the offset is relative. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) newoffset + + The new offset of the file descriptor, + relative to the start of the file. + +### `__wasi_fd_sync()` + +Synchronize the data and metadata of a file to disk. + +Note: This is similar to `fsync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file containing the data + and metadata to synchronize to disk. + +### `__wasi_fd_tell()` + +Return the current offset of a file descriptor. + +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The current offset of the file descriptor, relative to the start of the file. + +### `__wasi_fd_write()` + +Write to a file descriptor. + +Note: This is similar to `writev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_path_create_directory()` + +Create a directory. + +Note: This is similar to `mkdirat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path at which to create the directory. + +### `__wasi_path_filestat_get()` + +Return the attributes of a file or directory. + +Note: This is similar to `stat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_path_filestat_set_times()` + +Adjust the timestamps of a file or directory. + +Note: This is similar to `utimensat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_path_link()` + +Create a hard link. + +Note: This is similar to `linkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags + + Flags determining the method of how the path is resolved. + +- const char \*old\_path and size\_t old\_path\_len + + The source path from which to link. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the hard link. + +### `__wasi_path_open()` + +Open a file or directory. + +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since +this is error-prone in multi-threaded contexts. The returned file +descriptor is guaranteed to be less than 231. + +Note: This is similar to `openat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) dirfd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The relative path of the file or directory to open, relative to + the [`dirfd`](#path_open.dirfd) directory. + +- [\_\_wasi\_oflags\_t](#oflags) o_flags + + The method by which to open the file. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The initial rights of the newly created file descriptor. The + implementation is allowed to return a file descriptor with fewer + rights than specified, if and only if those rights do not apply + to the type of file being opened. + + The *base* rights are rights that will apply to operations using + the file descriptor itself, while the *inheriting* rights are + rights that apply to file descriptors derived from it. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + The initial flags of the file descriptor. + +Outputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file that has been + opened. + +### `__wasi_path_readlink()` + +Read the contents of a symbolic link. + +Note: This is similar to `readlinkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path of the symbolic link from which to read. + +- char \*buf and size\_t buf\_len + + The buffer to which to write the contents of the symbolic link. + +Outputs: + +- size\_t bufused + + The number of bytes placed in the buffer. + +### `__wasi_path_remove_directory()` + +Remove a directory. + +Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. + +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a directory to remove. + +### `__wasi_path_rename()` + +Rename a file or directory. + +Note: This is similar to `renameat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- const char \*old\_path and size\_t old\_path\_len + + The source path of the file or directory to rename. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path to which to rename the file or directory. + +### `__wasi_path_symlink()` + +Create a symbolic link. + +Note: This is similar to `symlinkat` in POSIX. + +Inputs: + +- const char \*old\_path and size\_t old_path\_len + + The contents of the symbolic link. + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the symbolic link. + +### `__wasi_path_unlink_file()` + +Unlink a file. + +Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. + +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a file to unlink. + +### `__wasi_poll_oneoff()` + +Concurrently poll for the occurrence of a set of events. + +Inputs: + +- const [\_\_wasi\_subscription\_t](#subscription) \*in + + The events to which to subscribe. + +- [\_\_wasi\_event\_t](#event) \*out + + The events that have occurred. + +- size\_t nsubscriptions + + Both the number of subscriptions and events. + +Outputs: + +- size\_t nevents + + The number of events stored. + +### `__wasi_proc_exit()` + +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +Note: This is similar to `_Exit` in POSIX. + +Inputs: + +- [\_\_wasi\_exitcode\_t](#exitcode) rval + + The exit code returned by the process. + +Does not return. + +### `__wasi_proc_raise()` + +Send a signal to the process of the calling thread. + +Note: This is similar to `raise` in POSIX. + +Inputs: + +- [\_\_wasi\_signal\_t](#signal) sig + + The signal condition to trigger. + +### `__wasi_random_get()` + +Write high-quality random data into a buffer. + +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. + +This function may execute slowly, so when large mounts of random +data are required, it's advisable to use this function to seed a +pseudo-random number generator, rather than to provide the +random data directly. + +Inputs: + +- void \*buf and size\_t buf\_len + + The buffer to fill with random data. + +### `__wasi_sched_yield()` + +Temporarily yield execution of the calling thread. + +Note: This is similar to `sched_yield` in POSIX. + +### `__wasi_sock_recv()` + +Receive a message from a socket. + +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to receive data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len + + List of scatter/gather vectors to which to store data. + +- [\_\_wasi\_riflags\_t](#riflags) ri\_flags + + Message flags. + +Outputs: + +- size\_t ro\_datalen + + Number of bytes stored in [`ri_data`](#sock_recv.ri_data). + +- [\_\_wasi\_roflags\_t](#roflags) ro\_flags + + Message flags. + +### `__wasi_sock_send()` + +Send a message on a socket. + +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to send data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len + + List of scatter/gather vectors to which to retrieve data + +- [\_\_wasi\_siflags\_t](#siflags) si\_flags + + Message flags. + +Outputs: + +- size\_t so\_datalen + + Number of bytes transmitted. + +### `__wasi_sock_shutdown()` + +Shut down socket send and receive channels. + +Note: This is similar to `shutdown` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to shutdown channels. + +- [\_\_wasi\_sdflags\_t](#sdflags) how + + Which channels on the socket to shut down. + +## Types + +### `__wasi_advice_t` (`uint8_t`) + +File or memory access pattern advisory information. + +Used by [`__wasi_fd_advise()`](#fd_advise). + +Possible values: + +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + +- **`__WASI_ADVICE_NORMAL`** + + The application has no advice to give on its behavior + with respect to the specified data. + +- **`__WASI_ADVICE_RANDOM`** + + The application expects to access the specified data + in a random order. + +- **`__WASI_ADVICE_SEQUENTIAL`** + + The application expects to access the specified data + sequentially from lower offsets to higher offsets. + +- **`__WASI_ADVICE_WILLNEED`** + + The application expects to access the specified data + in the near future. + +### `__wasi_ciovec_t` (`struct`) + +A region of memory for scatter/gather writes. + +Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). + +Members: + +- const void \*buf and size\_t buf\_len + + The address and length of the buffer to be written. + +### `__wasi_clockid_t` (`uint32_t`) + +Identifiers for clocks. + +Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). + +Possible values: + +- **`__WASI_CLOCK_MONOTONIC`** + + The store-wide monotonic clock, which is defined as a + clock measuring real time, whose value cannot be + adjusted and which cannot have negative clock jumps. + + The epoch of this clock is undefined. The absolute + time value of this clock therefore has no meaning. + +- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** + + The CPU-time clock associated with the current + process. + +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + +- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** + + The CPU-time clock associated with the current thread. + +### `__wasi_device_t` (`uint64_t`) + +Identifier for a device containing a file system. Can be used +in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or +directory in the filesystem. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_dircookie_t` (`uint64_t`) + +A reference to the offset of a directory entry. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). + +Special values: + +- **`__WASI_DIRCOOKIE_START`** + + Permanent reference to the first directory entry + within a directory. + +### `__wasi_dirent_t` (`struct`) + +A directory entry. + +Members: + +- [\_\_wasi\_dircookie\_t](#dircookie) d\_next + + The offset of the next directory entry stored in this + directory. + +- [\_\_wasi\_inode\_t](#inode) d\_ino + + The serial number of the file referred to by this + directory entry. + +- uint32\_t d\_namlen + + The length of the name of the directory entry. + +- [\_\_wasi\_filetype\_t](#filetype) d\_type + + The type of the file referred to by this directory + entry. + +### `__wasi_errno_t` (`uint16_t`) + +Error codes returned by functions. + +Not all of these error codes are returned by the functions +provided by this API; some are used in higher-level library layers, +and others are provided merely for alignment with POSIX. + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_ESUCCESS`** + + No error occurred. System call completed successfully. + +- **`__WASI_E2BIG`** + + Argument list too long. + +- **`__WASI_EACCES`** + + Permission denied. + +- **`__WASI_EADDRINUSE`** + + Address in use. + +- **`__WASI_EADDRNOTAVAIL`** + + Address not available. + +- **`__WASI_EAFNOSUPPORT`** + + Address family not supported. + +- **`__WASI_EAGAIN`** + + Resource unavailable, or operation would block. + +- **`__WASI_EALREADY`** + + Connection already in progress. + +- **`__WASI_EBADF`** + + Bad file descriptor. + +- **`__WASI_EBADMSG`** + + Bad message. + +- **`__WASI_EBUSY`** + + Device or resource busy. + +- **`__WASI_ECANCELED`** + + Operation canceled. + +- **`__WASI_ECHILD`** + + No child processes. + +- **`__WASI_ECONNABORTED`** + + Connection aborted. + +- **`__WASI_ECONNREFUSED`** + + Connection refused. + +- **`__WASI_ECONNRESET`** + + Connection reset. + +- **`__WASI_EDEADLK`** + + Resource deadlock would occur. + +- **`__WASI_EDESTADDRREQ`** + + Destination address required. + +- **`__WASI_EDOM`** + + Mathematics argument out of domain of function. + +- **`__WASI_EDQUOT`** + + Reserved. + +- **`__WASI_EEXIST`** + + File exists. + +- **`__WASI_EFAULT`** + + Bad address. + +- **`__WASI_EFBIG`** + + File too large. + +- **`__WASI_EHOSTUNREACH`** + + Host is unreachable. + +- **`__WASI_EIDRM`** + + Identifier removed. + +- **`__WASI_EILSEQ`** + + Illegal byte sequence. + +- **`__WASI_EINPROGRESS`** + + Operation in progress. + +- **`__WASI_EINTR`** + + Interrupted function. + +- **`__WASI_EINVAL`** + + Invalid argument. + +- **`__WASI_EIO`** + + I/O error. + +- **`__WASI_EISCONN`** + + Socket is connected. + +- **`__WASI_EISDIR`** + + Is a directory. + +- **`__WASI_ELOOP`** + + Too many levels of symbolic links. + +- **`__WASI_EMFILE`** + + File descriptor value too large. + +- **`__WASI_EMLINK`** + + Too many links. + +- **`__WASI_EMSGSIZE`** + + Message too large. + +- **`__WASI_EMULTIHOP`** + + Reserved. + +- **`__WASI_ENAMETOOLONG`** + + Filename too long. + +- **`__WASI_ENETDOWN`** + + Network is down. + +- **`__WASI_ENETRESET`** + + Connection aborted by network. + +- **`__WASI_ENETUNREACH`** + + Network unreachable. + +- **`__WASI_ENFILE`** + + Too many files open in system. + +- **`__WASI_ENOBUFS`** + + No buffer space available. + +- **`__WASI_ENODEV`** + + No such device. + +- **`__WASI_ENOENT`** + + No such file or directory. + +- **`__WASI_ENOEXEC`** + + Executable file format error. + +- **`__WASI_ENOLCK`** + + No locks available. + +- **`__WASI_ENOLINK`** + + Reserved. + +- **`__WASI_ENOMEM`** + + Not enough space. + +- **`__WASI_ENOMSG`** + + No message of the desired type. + +- **`__WASI_ENOPROTOOPT`** + + Protocol not available. + +- **`__WASI_ENOSPC`** + + No space left on device. + +- **`__WASI_ENOSYS`** + + Function not supported. + +- **`__WASI_ENOTCONN`** + + The socket is not connected. + +- **`__WASI_ENOTDIR`** + + Not a directory or a symbolic link to a directory. + +- **`__WASI_ENOTEMPTY`** + + Directory not empty. + +- **`__WASI_ENOTRECOVERABLE`** + + State not recoverable. + +- **`__WASI_ENOTSOCK`** + + Not a socket. + +- **`__WASI_ENOTSUP`** + + Not supported, or operation not supported on socket. + +- **`__WASI_ENOTTY`** + + Inappropriate I/O control operation. + +- **`__WASI_ENXIO`** + + No such device or address. + +- **`__WASI_EOVERFLOW`** + + Value too large to be stored in data type. + +- **`__WASI_EOWNERDEAD`** + + Previous owner died. + +- **`__WASI_EPERM`** + + Operation not permitted. + +- **`__WASI_EPIPE`** + + Broken pipe. + +- **`__WASI_EPROTO`** + + Protocol error. + +- **`__WASI_EPROTONOSUPPORT`** + + Protocol not supported. + +- **`__WASI_EPROTOTYPE`** + + Protocol wrong type for socket. + +- **`__WASI_ERANGE`** + + Result too large. + +- **`__WASI_EROFS`** + + Read-only file system. + +- **`__WASI_ESPIPE`** + + Invalid seek. + +- **`__WASI_ESRCH`** + + No such process. + +- **`__WASI_ESTALE`** + + Reserved. + +- **`__WASI_ETIMEDOUT`** + + Connection timed out. + +- **`__WASI_ETXTBSY`** + + Text file busy. + +- **`__WASI_EXDEV`** + + Cross-device link. + +- **`__WASI_ENOTCAPABLE`** + + Extension: Capabilities insufficient. + +### `__wasi_event_t` (`struct`) + +An event that occurred. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that got attached to + [`__wasi_subscription_t::userdata`](#subscription.userdata). + +- [\_\_wasi\_errno\_t](#errno) error + + If non-zero, an error that occurred while processing + the subscription request. + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event that occurred. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_filesize\_t](#filesize) nbytes + + The number of bytes available for reading or writing. + + - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags + + The state of the file descriptor. + +### `__wasi_eventrwflags_t` (`uint16_t` bitfield) + +The state of the file descriptor subscribed to with +[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_EVENT_FD_READWRITE_HANGUP`** + + The peer of this socket has closed or disconnected. + +### `__wasi_eventtype_t` (`uint8_t`) + +Type of a subscription to an event or its occurrence. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_EVENTTYPE_CLOCK`** + + The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) + has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +- **`__WASI_EVENTTYPE_FD_READ`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + data available for reading. This event always triggers + for regular files. + +- **`__WASI_EVENTTYPE_FD_WRITE`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + capacity available for writing. This event always + triggers for regular files. + +### `__wasi_exitcode_t` (`uint32_t`) + +Exit code generated by a process when exiting. + +Used by [`__wasi_proc_exit()`](#proc_exit). + +### `__wasi_fd_t` (`uint32_t`) + +A file descriptor number. + +Used by many functions in this API. + +As in POSIX, three file descriptor numbers are provided to instances +on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, +and `STDERR_FILENO`). + +Other than these, WASI implementations are not required to allocate +new file descriptors in ascending order. + +### `__wasi_fdflags_t` (`uint16_t` bitfield) + +File descriptor flags. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_FDFLAG_APPEND`** + + Append mode: Data written to the file is always + appended to the file's end. + +- **`__WASI_FDFLAG_DSYNC`** + + Write according to synchronized I/O data integrity + completion. Only the data stored in the file is + synchronized. + +- **`__WASI_FDFLAG_NONBLOCK`** + + Non-blocking mode. + +- **`__WASI_FDFLAG_RSYNC`** + + Synchronized read I/O operations. + +- **`__WASI_FDFLAG_SYNC`** + + Write according to synchronized I/O file integrity completion. + In addition to synchronizing the data stored in the file, the + implementation may also synchronously update the file's metadata. + +### `__wasi_fdstat_t` (`struct`) + +File descriptor attributes. + +Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). + +Members: + +- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype + + File type. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + File descriptor flags. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base + + Rights that apply to this file descriptor. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + Maximum set of rights that may be installed on new + file descriptors that are created through this file + descriptor, e.g., through [`__wasi_path_open()`](#path_open). + +### `__wasi_filedelta_t` (`int64_t`) + +Relative offset within a file. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +### `__wasi_filesize_t` (`uint64_t`) + +Non-negative file size or length of a region within a file. + +Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +### `__wasi_filestat_t` (`struct`) + +File attributes. + +Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). + +Members: + +- [\_\_wasi\_device\_t](#device) st\_dev + + Device ID of device containing the file. + +- [\_\_wasi\_inode\_t](#inode) st\_ino + + File serial number. + +- [\_\_wasi\_filetype\_t](#filetype) st\_filetype + + File type. + +- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink + + Number of hard links to the file. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + For regular files, the file size in bytes. For + symbolic links, the length in bytes of the pathname + contained in the symbolic link. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + Last data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + Last data modification timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim + + Last file status change timestamp. + +### `__wasi_filetype_t` (`uint8_t`) + +The type of a file descriptor or file. + +Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). + +Possible values: + +- **`__WASI_FILETYPE_UNKNOWN`** + + The type of the file descriptor or file is unknown or + is different from any of the other types specified. + +- **`__WASI_FILETYPE_BLOCK_DEVICE`** + + The file descriptor or file refers to a block device + inode. + +- **`__WASI_FILETYPE_CHARACTER_DEVICE`** + + The file descriptor or file refers to a character + device inode. + +- **`__WASI_FILETYPE_DIRECTORY`** + + The file descriptor or file refers to a directory + inode. + +- **`__WASI_FILETYPE_REGULAR_FILE`** + + The file descriptor or file refers to a regular file + inode. + +- **`__WASI_FILETYPE_SOCKET_DGRAM`** + + The file descriptor or file refers to a datagram + socket. + +- **`__WASI_FILETYPE_SOCKET_STREAM`** + + The file descriptor or file refers to a byte-stream + socket. + +- **`__WASI_FILETYPE_SYMBOLIC_LINK`** + + The file refers to a symbolic link inode. + +### `__wasi_fstflags_t` (`uint16_t` bitfield) + +Which file time attributes to adjust. + +Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +Possible values: + +- **`__WASI_FILESTAT_SET_ATIM`** + + Adjust the last data access timestamp to the value + stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). + +- **`__WASI_FILESTAT_SET_ATIM_NOW`** + + Adjust the last data access timestamp to the time + of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +- **`__WASI_FILESTAT_SET_MTIM`** + + Adjust the last data modification timestamp to the + value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). + +- **`__WASI_FILESTAT_SET_MTIM_NOW`** + + Adjust the last data modification timestamp to the + time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +### `__wasi_inode_t` (`uint64_t`) + +File serial number that is unique within its file system. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). + +### `__wasi_iovec_t` (`struct`) + +A region of memory for scatter/gather reads. + +Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). + +Members: + +- void \*buf and size\_t buf\_len + + The address and length of the buffer to be filled. + +### `__wasi_linkcount_t` (`uint32_t`) + +Number of hard links to an inode. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_lookupflags_t` (`uint32_t` bitfield) + +Flags determining the method of how paths are resolved. + +Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** + + As long as the resolved path corresponds to a symbolic + link, it is expanded. + +### `__wasi_oflags_t` (`uint16_t` bitfield) + +Open flags used by [`__wasi_path_open()`](#path_open). + +Used by [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_O_CREAT`** + + Create file if it does not exist. + +- **`__WASI_O_DIRECTORY`** + + Fail if not a directory. + +- **`__WASI_O_EXCL`** + + Fail if file already exists. + +- **`__WASI_O_TRUNC`** + + Truncate file to size 0. + +### `__wasi_riflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_PEEK`** + + Returns the message without removing it from the + socket's receive queue. + +- **`__WASI_SOCK_RECV_WAITALL`** + + On byte-stream sockets, block until the full amount + of data can be returned. + +### `__wasi_rights_t` (`uint64_t` bitfield) + +File descriptor rights, determining which actions may be +performed. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_RIGHT_FD_DATASYNC`** + + The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_READ`** + + The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke + [`__wasi_fd_pread()`](#fd_pread). + +- **`__WASI_RIGHT_FD_SEEK`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies + [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). + +- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** + + The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). + +- **`__WASI_RIGHT_FD_SYNC`** + + The right to invoke [`__wasi_fd_sync()`](#fd_sync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and + [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_TELL`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the + file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with + offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). + +- **`__WASI_RIGHT_FD_WRITE`** + + The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to + invoke [`__wasi_fd_pwrite()`](#fd_pwrite). + +- **`__WASI_RIGHT_FD_ADVISE`** + + The right to invoke [`__wasi_fd_advise()`](#fd_advise). + +- **`__WASI_RIGHT_FD_ALLOCATE`** + + The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). + +- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** + + The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). + +- **`__WASI_RIGHT_PATH_CREATE_FILE`** + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke + [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). + +- **`__WASI_RIGHT_PATH_LINK_SOURCE`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_LINK_TARGET`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_OPEN`** + + The right to invoke [`__wasi_path_open()`](#path_open). + +- **`__WASI_RIGHT_FD_READDIR`** + + The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). + +- **`__WASI_RIGHT_PATH_READLINK`** + + The right to invoke [`__wasi_path_readlink()`](#path_readlink). + +- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_RENAME_TARGET`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_FILESTAT_GET`** + + The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** + + The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +- **`__WASI_RIGHT_FD_FILESTAT_GET`** + + The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** + + The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). + +- **`__WASI_RIGHT_PATH_SYMLINK`** + + The right to invoke [`__wasi_path_symlink()`](#path_symlink). + +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + +- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** + + The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). + +- **`__WASI_RIGHT_POLL_FD_READWRITE`** + + If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). + + If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +- **`__WASI_RIGHT_SOCK_SHUTDOWN`** + + The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). + +### `__wasi_roflags_t` (`uint16_t` bitfield) + +Flags returned by [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** + + Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been + truncated. + +### `__wasi_sdflags_t` (`uint8_t` bitfield) + +Which channels on a socket to shut down. + +Used by [`__wasi_sock_shutdown()`](#sock_shutdown). + +Possible values: + +- **`__WASI_SHUT_RD`** + + Disables further receive operations. + +- **`__WASI_SHUT_WR`** + + Disables further send operations. + +### `__wasi_siflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +Used by [`__wasi_sock_send()`](#sock_send). + +### `__wasi_signal_t` (`uint8_t`) + +Signal condition. + +Used by [`__wasi_proc_raise()`](#proc_raise). + +Possible values: + +- **`__WASI_SIGABRT`** + + Process abort signal. + + Action: Terminates the process. + +- **`__WASI_SIGALRM`** + + Alarm clock. + + Action: Terminates the process. + +- **`__WASI_SIGBUS`** + + Access to an undefined portion of a memory object. + + Action: Terminates the process. + +- **`__WASI_SIGCHLD`** + + Child process terminated, stopped, or continued. + + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGFPE`** + + Erroneous arithmetic operation. + + Action: Terminates the process. + +- **`__WASI_SIGHUP`** + + Hangup. + + Action: Terminates the process. + +- **`__WASI_SIGILL`** + + Illegal instruction. + + Action: Terminates the process. + +- **`__WASI_SIGINT`** + + Terminate interrupt signal. + + Action: Terminates the process. + +- **`__WASI_SIGKILL`** + + Kill. + + Action: Terminates the process. + +- **`__WASI_SIGPIPE`** + + Write on a pipe with no one to read it. + + Action: Ignored. + +- **`__WASI_SIGQUIT`** + + Terminal quit signal. + + Action: Terminates the process. + +- **`__WASI_SIGSEGV`** + + Invalid memory reference. + + Action: Terminates the process. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. + +- **`__WASI_SIGSYS`** + + Bad system call. + + Action: Terminates the process. + +- **`__WASI_SIGTERM`** + + Termination signal. + + Action: Terminates the process. + +- **`__WASI_SIGTRAP`** + + Trace/breakpoint trap. + + Action: Terminates the process. + +- **`__WASI_SIGTSTP`** + + Terminal stop signal. + + Action: Stops executing. + +- **`__WASI_SIGTTIN`** + + Background process attempting read. + + Action: Stops executing. + +- **`__WASI_SIGTTOU`** + + Background process attempting write. + + Action: Stops executing. + +- **`__WASI_SIGURG`** + + High bandwidth data is available at a socket. + + Action: Ignored. + +- **`__WASI_SIGUSR1`** + + User-defined signal 1. + + Action: Terminates the process. + +- **`__WASI_SIGUSR2`** + + User-defined signal 2. + + Action: Terminates the process. + +- **`__WASI_SIGVTALRM`** + + Virtual timer expired. + + Action: Terminates the process. + +- **`__WASI_SIGXCPU`** + + CPU time limit exceeded. + + Action: Terminates the process. + +- **`__WASI_SIGXFSZ`** + + File size limit exceeded. + + Action: Terminates the process. + +### `__wasi_subclockflags_t` (`uint16_t` bitfield) + +Flags determining how to interpret the timestamp provided in +[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +Used by [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** + + If set, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp + of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + + If clear, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current + time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + +### `__wasi_subscription_t` (`struct`) + +Subscription to an event. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that is attached to the subscription in the + implementation and returned through + [`__wasi_event_t::userdata`](#event.userdata). + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event to which to subscribe. + +- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): + + - **`u.clock`** + + - [\_\_wasi\_userdata\_t](#userdata) identifier + + The user-defined unique identifier of the clock. + + - [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock against which to compare the timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) timeout + + The absolute or relative timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) precision + + The amount of time that the implementation may wait additionally + to coalesce with other events. + + - [\_\_wasi\_subclockflags\_t](#subclockflags) flags + + Flags specifying whether the timeout is absolute or relative. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor on which to wait for it to become ready + for reading or writing. + +### `__wasi_timestamp_t` (`uint64_t`) + +Timestamp in nanoseconds. + +Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +### `__wasi_userdata_t` (`uint64_t`) + +User-provided value that may be attached to objects that is +retained when extracted from the implementation. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +### `__wasi_whence_t` (`uint8_t`) + +The position relative to which to set the offset of the file descriptor. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +Possible values: + +- **`__WASI_WHENCE_CUR`** + + Seek relative to current position. + +- **`__WASI_WHENCE_END`** + + Seek relative to end-of-file. + +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + diff --git a/proposals/clocks/docs/WASI-overview.md b/proposals/clocks/docs/WASI-overview.md new file mode 100644 index 000000000..faabc2eff --- /dev/null +++ b/proposals/clocks/docs/WASI-overview.md @@ -0,0 +1,147 @@ +# WASI: WebAssembly System Interface + +WebAssembly System Interface, or WASI, is a family of APIs for WebAssembly +being designed and standardized through the WASI Subgroup of the W3C +WebAssembly Commmunity Group. Initially, the focus is on system-oriented APIs, +covering files, networking, and a few other things. Additional domains are +expected to be added in the future. + +WebAssembly is designed to run well on the Web, however it's +[not limited to the Web](https://github.com/WebAssembly/design/blob/master/NonWeb.md). +The core WebAssembly language is independent of its surrounding +environment, and WebAssembly interacts with the outside world +exclusively through APIs. On the Web, it naturally uses the +existing Web APIs provided by browsers. + +WASI is an effort to provide general-purpose APIs for supporting +non-Web use cases. The focus is on designing clean and portable APIs which +can be implemented on multiple platforms by multiple engines, and which +don't depend on browser functionality (although they still can run in +browsers; see below). + +## Capability-Oriented + +WASI's core design follows +[CloudABI](https://cloudabi.org/)'s +(and in turn +[Capsicum](https://www.cl.cam.ac.uk/research/security/capsicum/))'s concept of +[capability-based security](https://en.wikipedia.org/wiki/Capability-based_security), +which fits well into WebAssembly's sandbox model. Files, +directories, network sockets, and other resources are identified +by UNIX-like file descriptors, which are indices into external +tables whose elements represent capabilities. Similar to how core +WebAssembly provides no ability to access the outside world without +calling imported functions, WASI APIs provide no ability to access +the outside world without an associated capability. + +For example, instead of a typical +[open](http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html) +system call, WASI provides an +[openat](https://linux.die.net/man/2/openat)-like +system call, requiring the calling process to have a file +descriptor for a directory that contains the file, representing the +capability to open files within that directory. (These ideas are +common in capability-based systems.) + +However, the WASI libc implementation still does provide an +implementation of open, by taking the approach of +[libpreopen](https://github.com/musec/libpreopen). +Programs may be granted capabilities for directories on launch, and +the library maintains a mapping from their filesystem path to the +file descriptor indices representing the associated capabilities. +When a program calls open, they look up the file name in the map, +and automatically supply the appropriate directory capability. It +also means WASI doesn't require the use of CloudABI's `program_main` +construct. This eases porting of existing applications without +compromising the underlying capability model. See the diagram below +for how libpreopen fits into the overall software architecture. + +WASI also automatically provides file descriptors for standard +input and output, and WASI libc provides a normal `printf`. In +general, WASI is aiming to support a fairly full-featured libc +implementation, with the current implementation work being based on +[musl](http://www.musl-libc.org/). + +## Portable System Interface for WebAssembly + +WASI is being designed from the ground up for WebAssembly, with +sandboxing, portability, and API tidiness in mind, making natural +use of WebAssembly features such as i64, import functions with +descriptive names and typed arguments, and aiming to avoid being +tied to a particular implementation. + +We often call functions in these APIs "syscalls", because they +serve an analogous purpose to system calls in native executables. +However, they're just functions that are provided by the +surrounding environment that can do I/O on behalf of the program. + +WASI is starting with a basic POSIX-like set of syscall functions, +though adapted to suit the needs of WebAssembly, such as in +excluding functions such as fork and exec which aren't easily +implementable in some of the places people want to run WebAssembly, +and such as in adopting a capabilities-oriented design. + +And, as WebAssembly grows support for +[host bindings](https://github.com/webassembly/host-bindings) +and related features, capabilities can evolve to being represented +as opaque, unforgeable +[reference typed values](https://github.com/WebAssembly/reference-types), +which can allow for finer-grained control over capabilities, and +make the API more accessible beyond the C-like languages that +POSIX-style APIs are typically aimed at. + +## WASI Software Architecture + +To facilitate use of the WASI API, a libc +implementation called WASI libc is being developed, which presents +a relatively normal musl-based libc interface, implemented on top +of a libpreopen-like layer and a system call wrapper layer (derived +from the "bottom half" of +[cloudlibc](https://github.com/NuxiNL/cloudlibc)). +The system call wrapper layer makes calls to the actual WASI +implementation, which may map these calls to whatever the +surrounding environment provides, whether it's native OS resources, +JS runtime resources, or something else entirely. + +[This libc is part of a "sysroot"](https://github.com/CraneStation/wasi-sysroot), +which is a directory containing compiled libraries and C/C++ header +files providing standard library and related facilities laid out in +a standard way to allow compilers to use it directly. + +With the [LLVM 8.0](http://llvm.org/) +release, the WebAssembly backend is now officially stable, but LLVM +itself doesn't provide a libc - a standard C library, which you +need to build anything with clang. This is what the WASI-enabled +sysroot provides, so the combination of clang in LLVM 8.0 and the +new WASI-enabled sysroot provides usable Rust and C compilation +environments that can produce executable wasm programs. + +![WASI software architecture diagram](wasi-software-architecture.png "WASI software architecture diagram") + +## Future Evolution + +The first version of WASI is relatively simple, small, and +POSIX-like in order to make it easy for implementers to prototype +it and port existing code to it, making it a good way to start +building momentum and allow us to start getting feedback based on +experience. + +Future versions will change based on experience +and feedback with the first version, and add features to address +new use cases. They may also see significant architectural +changes. Because all of the APIs are accessed through regular +WebAssembly imports, APIs can be implemented either by wasm +runtimes directly or by other WebAssembly modules. So if WASI APIs +change significantly, the old APIs can be implemented as a library +on top of the new APIs. + +## Can WASI apps run on the Web? + +While this isn't the initial focus, it's possible to implement WASI +APIs from JavaScript, since they're just regular WebAssembly imports, +so it's possible to run WASI modules on the Web. + +And in the future, it's possible that +[builtin modules](https://github.com/tc39/ecma262/issues/395) +could take these ideas even further allowing easier and tighter +integration between .wasm modules importing WASI and the Web. diff --git a/proposals/clocks/docs/wasi-software-architecture.png b/proposals/clocks/docs/wasi-software-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..6cb8345cc43cba2410d05ee1db06e929ba335fcb GIT binary patch literal 28267 zcmbTdbySpH)HZI?DP1DnGBk*QG$P&I9Rov3i_{PUN;fj}P$JzDf+CH8zyQL~Eh+uG z!RL8??;r2_*0;XpTCQ35xzD-xIcJ}JUHdwlNHrCCTr5hgJ9qBjzEqIWxO3+o_|BcX zZ!pk+C&YL={&((xd0)y%YQ3J`%EI&~UcT(ng%Lb?fkC$#@3fPE41REr@c|COlH7~L z4+`q)Y6R-)>THX_2KiVzr4xB}>h`j)IM^Q_opD&S4!?!J{-E*jq2xo+Yaix=&hMb+ zDaMT1wAt13)8{!>-aBdD^CxNZej?PNKcg{p<$9LjpQ1{AlM?51vP}1ke7$xezOR5kAz&k6@4c>j=UEvCII`o*@X|VUZoUTFZ-*F z1Py1uBAw4ix=l*=1q21?`0OvABo2rkYiNC4Uss+abonlAY%}^t z%vKS7lbo_z5Z^+-AO>CNpQIl@Vh9~1Yihwue_BBf+|H*_4+Uj?2u!S=8Z}tuoW&p5 zI~jFi9oZ81W`+_-DP)X_4Ni#)@SSgK4y7NBVebYG-b;fUe9#UGyik*TxvR?1?Afk; zsV~cGOBYJ8=t$37eUM!u>VrJFe!YF4w2gTAetE;m`_@RYgnC4KrLPSSFsi@Q>e^aa z;$i>LuuVi5m+YxdrSoh74wcB&SS(@Iu2vA(ydMHsTSK105ug=lK2;y{NnLAZW17VK zy8hMV*CN7Mn?Y#|y8J1tWil@6=T1u}Td!ZJUyWo1>9@1+BF;DYU4YM|%PQ(jJgBj? zG*?u=8mFBso3E6g({ok?I@;62;rsj1eeKdSRHXUD%R$EVi`ld9)n|9j!7@NQ8~qrs zdt3J%c&>pR;^al+!9qLjL4dw>(DD{G_km%EXYDVYsP7yBfzB3YR;Sm=8xwxC>Jv_{ zmCtEU&`zK|--Rf}y+%{EMZKuMaYhnIK@Bzd+)M)YB3GrGKG(d3H1E{;C7CcSEB2~n z;ZZS|Qq?4|i zHXat%_uw)=%vm+{Y_*6{v*@eTKd5|eLlLf}-wa9kT&>IEHb3+FP?g0M z|DsqO9FKM62RDF~g2T6$cB?KwY2({{Uo~lyNefsPm_Fur?A@q4e=JJ8t8{kXodvM6 z_YLNPP}@uy5gM*szF(Z)z;KL&bCV6&%;BTcQYf3E zj!7_cDql6qa*ZVO{#ECm$Ij>xYe?9^=c`S**hw6ct6rWkimuf61(pZ;c(rx*YRd?x=<;nfUC>La(+=ySjdQ|LbZbZi)|))49gA)y}O<& zxujD{c2cQQmWX^w2~{pli2F?XtJb1+zeUzv24fE!JEeTJiqPf2*(w?)zIs( z$WZeTdxK9GPwRV>Q~AuNs|J28Y_YPl8bms>Tv`hAy_aa#9nW zzhemNIe$qrLQ^`)rhgiC!jnQDO5m3IBc^O!oy6t=mJw*wnyIXOD73Nl5~9%JX;}}P z-s7GIx@jAy-Ehkf4qD_wsMZ3Adu8TZ3z^x@G)+P&42aAZ#zW^+pN=8UCsbhwdBWWI zFoc-MSttfoKNb#V490Y(B#5iiq13pEi`9iT7P$@C1{Kbc3ps^2@}%==t&cVcm^Pd=o`%`-)&tXA{JO2Ze`l3W ztjY3?T^y6{5nVj964rEWBr8=Yl(bHg!7su*6_=d6#`~bBA-9|Y?rbw64pI4IO3s7P z`eqrSK`t-ii`5mWg0&MvH8|9OyK}eSQB`+CeMC%VgxdF9RJ8}!hSYgx2@ezGPA(qW zQ-0bh#<4Sd;<=&&1PW@3sneWl*Tg~^4H$+JWj}U51_EPbP-#c$PDogt1N23Q>l4KY zJF4W4*SQ0v;$0x~H0Tc>UhvvC%=fP3$+|+s8tFp zXl=Iz%L2h)TLQcjxqAc1bRPh+E5$(0zA={A^7h!uJS9I^vUJ076eW0U%Zzs>v&k$?RU-?sIXIPSk1G#!tD~+9MO(>;+ zp*daTzylZLBzG2g9y(K;1p>FIcCfTOk4fV{dbVN^O7N(YIOW8cW`mDuxIx{E0G`1D zBR^36+p=`X9w@67t$s{^;8;$>waV>F7~*@KxMzN^Fh4OiH|K^Y>W}BE3@oiAJIre?wru$=~6%CSgCn-Fpw;%58d& zvPS|C(gS-)FFVoz_;oHMk2R_XMj(X&qxxT-sPlsXPq0J&_s+6}c@tt2+^m}s?Qvm0 zmUOpPT3wHWfki3TiT$}mKey=XKX%)VPYsXW%&>j8yZP2|gT9e!+eJ3-$v%_f{05!k z<ROaP#sJ}Ku1zegCwccxVX7Q(2OE$KFR ztj$Qg!lW4osqU}#G;nDYq+)D>b&uePS_D{2KvO#j zfw2+@n2(b4$pwObd4Jm>Wr36??c4luK65Qq;(1w?nsdO_ksQD3{uS1n|T+$*f(HlrUP48U_CpoIWuCiNRG(4ZO` zoX*pH@21Ca18^LJ2Zg<#<~b*-hAl|m?s5;TryMtQLE<$ntEp})J_XO2{Ea=i5X+7= zl!Jzn;g5J{0L2wmbrH?#2er#LJZRe;;!_~lTQKE&P}y{~XRBnEW2gonP@Sp>XsFA2 z?$`Ar&7I%JJy1_|%TOHeN=P(i1;e>PjfVAVQ4|>=s#AGz$`@am$26pXl<4Q8q!>4D zu5VTB6L4o*+H`NT`mNjtg(L(O{xh4Wv{)!`t;har^NM87_RZACh(C|Nn>&RDgE9_? zN5swjhZzWGa)*1p{=`_*hj2xr%mJY$9!8^aoxZoN0s@-PV*l-$j3@EeH}V>z2g8CYO}z+_hZ z0wBx*0kB?nlCIgbiK5et1}gk3T$s!pX=boD`TCL^O5TI^9a($X75JqwI*r-&dH)QX zJO)ny`EiJd7!ObLg;-rj%zeGsA!Xy4k30>>xhHj{kQ)@BNKMO;AxusL{+%4ygHZ9$zz>2PZFLsTZkTpX$+Wny=jTo(%S^3d(d@eQJzviXEE+aExvAO>-J*`BWiu zq>ZUBY_wIr%`HAdlT(SmPLsFr=^Z45jX+LW#=rtaBoH!cgkpw+e?Fe+ zEc^VNZgj~JCHVT!nq_R{wYh`Yba!S3C;=q5Po25LsGGEyX)d*_Ksh}TiNfMzIgW-> z;H0I!?`+x^Sup8(66NK%Uu)(^u1@~aQoDp30lf`~!wnDB+;ZoE-Ea_6H^xGRY&0ZO z3N?;BKp2^W&ECl51({L^HM-w}>j>+ns%UvGQX05PSfRq*Bc|e0q6hCTB34sBwI-k z3?)d@e%Kd|^`6nYM^*+cz#2)g5I+NrbpOJem+KG-kv>8|Qb~{;NEQfKj_9GL?Sy*w zPZ3E$@Y;hn+pe6cf`nrEH=YheJJd>DFa30MhY^(hc^*XCO10md?Li(o0|Rp%8SEU^ z8%+1Ulsv#3xl~NqPY>6E8s%1pBfmddg(5U+EFEJZL?Z%?Q6#BSx~D`%9Xv5(li;{V(Wu}V9-Iqp4M7fAL*=O}B%N(3$mo^R7}Fhlw8U zDJ%rR$>f{92M+*XexI+?Gh>$JpEaQ~Ll%F=K{%4#f-4ZG|NHkhaH?MsA-D~nSw6gJ z_~#Mv-#9EpDFguVO{fOo_V)KJDE|*whUD2H{|UD6o8PzKI?|y2|1bd8>)PMts)@2f z$U>zw@mB!t55A|#XEj$`#4*093aF}B`zM0 zU-o8;Yu|HOt}SnV?NTf_LPfi)lkI;hW<7;K=jYQkGAT)GAe+0){EI#rqOCQ{9Lq88 zs}AAYw3PubG$kMQe>HYLU?2F*Wz_WVTWR*2hGH^}M|1Lak6FKyH&k=CD3un)JKH}f64^X!SZDBFrU2JAYcCu0A$LWeA50A>-UYpi0g`&G~|n$NX%FR z9JgR;e)Poguy&FVo_x z!TManxB6P3l|WYirK-zx;o-V&`S9)M4HZbf#uxqM(zaO6;h5U^qJd1(=^J3ztd|^K+ZdAG`d*74Oux{h-HXl4fFBypFNZ(zC zh?BHmN~6bPRhlf;#|4vi^9wFc{);^4Z$CPNB{8vFoK1hW>*)XvVf5(_vvbZ*+Ckmy zKmI$*uWGD+a<7aVHABW0BrU7BeD}O|2}^-ASG)N!C5TdJHj_q+gf0L*q*iy_p{vPI zOF2b6qIA04Atmx#^pDB;4-SP0eT2!6_Gpk%B?ZWK=IDA;YZiWupI85$3GIgF_H47F zn6L3sqyRZ^JUE`7FutLm)82aF3e;G%smvpf@p@j?M0W9}^5O8tJgxybSJWsuiyRAB z9)AG$Ds7eH5xAe}OOd_tN)W zHkQyZ`%R1H^Q*HmFKV1#DIyy-luiK^MUY%#r$>SgM*wP^0H7e0O#{ZPA~HfJ5%EY@4t2jsj#{de0vKCA>=zwCXvJ2 z#6&$j@+e?`l|1kH<4HHj7GL~#3+Y2Xm1_a}X{7;HEEKc+FEg|%uB%;bjlh2YN@zvL zMMuNJbF=BCHJZ{OE?Z=$r{>#$cDO@TUX=syCs=h(Z7hR!vT(%x*dB+$tfsUFd53ms zU1ocv8zXi1!wC8Uanb^H$zhUVR zzI1A0VUWrn6Pfv?OQ<7|ld0@`fwVy8p9rk^94#Y;EUxubcV^jfC=joz`kmTAz7}G2 zGu15+cLip97}%fKIA`4kZ+?Ew&gpvmgM1x=$-4gYS}vt~>s3$|IEvbrSeZP>kXjzW zLF2oGySn^CqDyIjPiAswa*|NJ(N~(d-w-wNM0UyyiMKI>mFJ}W{*4R?tVD`ba?2Bb{MAxY`wNRKg=@xIyYkA~tSaJR!un9L@Vey zgukVldC0jBFA_`TtWk9Uiqr(;>az7enJ(sPTBz&#KB9kjej&AIE=O3rt+(n4xxfem zNjPrS6M_-GY;;&gdCbi7S;h|X@*jC7r?GV|cHI5HOuDK}Ci7fB(INPF++N_E(_OWX zEeT`iL-k+5W_-JvgnQG#^k7ZuGIk~){diaeaa05uL-TW`ga4@1K%^hweqX}7qdedp zS)BSjGlJka*t#bm5}~0LjD`A{d8v^s1SV;EufMhz6sM4yXWX<9ua5|7|4gvZG;c*~ zm*K4zS2wmf5t<*#mhCf5qtZ#5y3TW;lq zl7mnS(Juag#Y0%**)PxiFZq14;8_Oc-^9%Xg*HdH3Ad*=gf(Ce{BKC`4(KF8>HO5s zOb^+!@-liRkBXOU!`(~VsAo$(9={^H&F5y+4>F>HJ!cHoihn&Fl^bc$PsQl1+Me~7 z^uSKJN%;(m{|7(#9|`&Y&JTKE@c$z}_OSjvlNE)uzYGS{rJ;8hLh3c z%3BllW*R#3af@jXoQ6ktu-(|L!pM@vwFUYd4ZZ)8s0>fo%nc2hM7BhQ36bnKZC}++ z?*{+HI!=4!V}tAXiNT04L0JK;frsI+Y=ys|Ji(EFBYYw+*EBglvMC~XX#^eq$zb&> z-)(4XRMf7U2P>eO#;Cw0TW{*yug zx#T~V_n&kE$SMEOByqx((C%ODi8K#rT5JZRkHVEKKa#SL4rW~f}?X$oiC%NvC`nIFSj z{KA{5Bh91#x*<@XU-KU-e9s08lqR$yzilYCwD-K^%W_g5kVMDwysoI}*P$sb`_%4s z9F{WG*C2MIayteAcO^CL|Mb34Sbj6jZI6t_ApB^!W>~`6BBcZs>Q!$ikIzx zfNuS5zd6NeJ8*7r%&x zXy<5S7z&?Ls)=g79O@e%MBlU&+nPy;?DRddWU)X0a%|CFT$tr|`e?f)rq{z3siqv` z*m<;A`CG3+C-oW6s6=*Nu}#=b7Qxkf+C|O~6)7TIwFTTQj11!UzAYi?(KnJvM)@K6 zGVAri&m%k`oJj18q@nVX^C;V3zh?lH8<2=p+|7Z2_aV0~_aL*SbCiZ3oc+-9&0Adc zhErYRAgvi8a~mMnjN|pZQLMKY&B$H3K=_~+#TKoA!=?KK-|hHROC@A4cV7-K9RIsn z%*Us7UE=08AH|RF=0T+NQf;1oQkgcbu5VFCg}xRGD##q}+SWj}=ua4skY@p9 z?K^PmT-23(H*M9h7phvho@HmigKX zIOLvjSF>|d3Y|!q$Fe?xKkt0k@q^BS3852KA{~m+gZYr*sq0??k(QY319&KA}9hKh(X|hUISGQu&j6km|h02fCqodv24Tv^O}_ zR&B)fY(oj&OG&zrdUl+^hsnfLWslM!srWL9W=dwnGWjnBx&Pp4d+ZG66##j0Zs*0f z_X4S&sbm=EVO9IG-MCVrxM;X1(poui_D5)a{WVc`nNS2~NI1LlRKvFsN&mRZ$QlbL z6goqcgD&~j3Q~6}6O~D*?`i9Qn>PH(+PZ)Pl8X$=MtqPG%R3VvuCNGrcnu#Bp%CG+ zWQbQIIy+p@jf#yNQ@uPQe802BEC}?B{wxwjzt1oYsr}K=5!3Mtdf6%5L6B?kh>)xC zjBtd>lpMJJ!HH{7F}mMh=JW)hJ14p_oXf|MPmqKG3i?coYq;iHP}om7nbZCqj%Svi zhtp?uITK3rtFobkx52I|)SF7I${Zh-;g{P)B=-OfqX*}@i=5mqp57t!o?0wUM~%5? zDh{~-z^zLO$^cSwe!GZVb$AY6AWfe?wYRGA_*Gn*Ug|2$p|8G=TQ3#8v0 zh^YgvVBSVwV%%q>_ko|3r9nbEI>o+-ya1`e$KEsqVyxiL^l29f2N}^$^wxnK_NzMr zzIZOSEoS>RRSM((Zh1l|dmFJWD2(hWMD392u`M009Rwd-g&a>p*OIE}TI^2397IuG zKUtK5oeqb4ux#+1yOuU|wxnbK(7k2c{r+c)waWBVuhVM5Z^TcN8vW6T%<1(?&Hcoo z$v+gUj%9&8&j6_|k$@+}D&%4ANm&aw4>_pf?$GBgqpJRlbM`^y=iD5gO1Jtc{C)cS zOWV>~_v*3Y3sxlL+H4vr+gd#F&DfBCssVDxN=XE*MwrNv-c{aRBiKbY8h z{VVGFHoV!X3)#ADMCedBB?3GkcKjtv+--h5s?dx_)1xAK-sxih4~#)^p|Dr}$~d@^ zC^_}yQufQFTkMXh1_tO2uHY>I@Jtis_3rlR`>400bE5aAzTXV1nfb=JE!6tA&t?95SpS2k> z@0O1+(2mw>&D;0@o&zM52XuM9-97CB=kcZOcAEepUG9Vd1VN5!Op%} zw-MqK4QxDHEenCB?XJb8;~9q_)877(=QvEN&7n=gV|Zf#Gmi7T1?tgU4*&L696(Dd z1xuu4ttxL&ce6F_<6fbZ&e`s-j0$xgmc~=Dr}6!%>gZa|+O_IJE+7bz_7@&1U=#v= zR|I0(du>lNwV|U+{@V7GmR5Xk_$;LcBe)Wa%d>rY?};6X=xfz7Yu~&nsA=<+N*Ae2%FB5M@gw{WsUlxi2vzT62^HB`IdiaA zB9R&e*2@8l$Htk^UuX^DJWdpg$*Ab^Bfzh9PXTS>tejmjjRPgBKMcon~1t=s4!w4nT^3;SD zXnch8z)#zr8b(za2WV)ykZSa<MQx4Gi-m!fT71_?!8gn=eQnPdE-wvbk43H<(rp zeVzUFb!;HDF7|G;|A6v9vo2S;W8r#i59EC((usQ_+RE)P zsus}ucJiwhjtHfoq9Je9t9W{iLeVYh+h2ACrz<}v7!}bpR_L8QHOUJ z%QzQyxigk4nYN8U7}IM%cZrOP#>$i+Wpyd3S6)rpZh@&0v{+zsJ{Or>@IJQcI*RiwP`NUNPyA>q; zNwV}P7h=egCSbm3;#2^+UwwE~H{4JgRRAn1>EC_srh&vVjK8*_AOvLM zQcty0}^oIT~iJ>ipNRv!;Y=)~n}SU7ljto)b`7;)5VYGS{eKYsZLTAcNq^5Xer zv*+XfC6jNgD)uY*?FBu~!EIT{QkSr+*(hMh0>G>L+!|$`V z7)#tj8{FN7As6+ppr(!LLiqb1pPZg~JLd21cu>!*l;&buR!f?Se=+OF+i(*?_6UD# z!R#=D!>H*!37yT5b^$^ir$Swq z_-aew=f$j2Z`+75K+5%o)_a`j4Me|1AH|$UyC<~8LYerN zIeffeBZk`L`joWklY#cUyuN41zM#PVLxKIWYM>&=Tw(BwB9fw)ZI^jn0oyoq`4lp1 zE;4TCr7-4jsYBjbd(cbtbg10yIx`j%j%q5|YHB%E(ReI_^NLJwuq!ROkok)N%J68! z?4+1c9*gtjBp;OyBLTnw2~R{?s6qypS4=3Ztt>evW_CK>)myc~9`Cf4`5{~UYdl(I z!6pRA^2raCC~zxU0!G%9@3={!rpx4kAg-QB`RfccgLIvVKWsO@?q%t)D&K8mAa%4Y427c zTHs#pn&4CZd!K6>t4G;r_pWqdltWAcBkBn;*aBXvY?WV3vYCb}s+lWqm*QKM4GEG3 z!^`BXGi1aJsfhrta%J;dHIZjUh zwe_89(579?%69>#m%>q@A;ij6@JH1v!yP`rP_@?)S}6s>=6X#_CD`@ z-!Up{vb*R^*DVD7c+3^c5VADkqqnQl`~LS-f4D7yWwVb%mk#6Qhw6fQ{@>Cr4k}{? z5k4d~?ywmSyc6f25AqlpC@CKF45XHH=Fgb3vppYMmjol<*8UcR8QLxW2&z|^!;G0#5TQOaDcFkr_sA>6c~*$(Rei)^mZO6wZ08?JK%D z?`E_L7wUP}TM=_m%hO9z9d#NAx<36@L&MJ#F~9@1U`?zY(DQypKq1sjxYgs#^cPoJ ztYfVhSA6tbnz{mpm?BVL-?X{62s0ySWIa?W?(xNp}KGc`d?| zPU}Bw`N4N{S--*zK|@~@Z*n$qv@!Wep0Cffa~kuHV#HE1A160jmY}{qIP5_^=?jDW zSVF5XJo+lrlyO-;aiaU98}j||NKJrhE~cMi28u_48$L8p(0IcBgV3Hn6+6h5!1VTR ziQth%4_7L-g2{g_x|!7k?2)>Mf>R!E5K6 zC=Mv-T)#g41EZLfS0x+wwc~~p|HWX(gP1%BXM6A4!?U-wFsf;$w#p66+boLFgS>D< zS9@9VwR7Av$|6la0Sx8OT}=ytTnb~$^V-fDM|XnYH;_&UQl46Q(po2hIMW$diSRzy zn#NQjJgG*!lswxq8HcSiTtq$s43STGoIm-{{QwZFp9z!Wo)kV&Ng&d?RMozFOAQq4 z?zkUhBlIZ2hT_fMX`z^Oq3?$2c;(cw4P6 z-bMB4ztBhwBSCGojd!qX0x5+vqDVWUXi4;B{$i_ulbWrslhS?e*JYJh9t+=XEm5I| z>l{-VeF5txc2*egE2ALWzokQpZ3o+5;s)$L4LAHcwpZLe1kRQuY_e0*FQH8x)AoAh zu}Z{khtJPIDFpi7HV%5 ztD0qHzhl{K9wUo0IVQqxQGcdcVRL-*EylqVQ9eqcmJvU8(9@tj>hgnoSD)?_usWtT zjCT0sgnMHJeeQU^&SzWZKhSW|!hPZ%eNt!mDNnTi3NJFQYzH_`Kp)ysGmx5QqSdJOS0Os(O1ssha+14w}oz zX-#~{D68KxU9**cG2V}dN!LBiKQ&V$0F;Ib>bwVP>2vS z@LY6K3BiakdfBNLwnkz)FTZV`8rnny<~xsyaXG;tj))>QS@j7@c1AjZ6(*ZVpvBU_ z5-FT;Pj>3n;Nj2uv`wHO5K1YedXTO`Y%NwmDlEh|d0SBx^{*(e{x^XKE-3$(C$|DJ zP?z`rOUcCl%F72j2Rp)=kx_Anr-6sg%o|_*5{YQB} zn{$|Q>_jZ?ScKnQz6|wDr>Rxtzp6c*IZ{oSd*fQEy6irkWd*3-}ms>9*CCPG(j*haB();zwRm4yhXD{eGPKZHpY3 zTjN6YZ+&`7X7Qo+P0oQgory_!gQD!u!l7v`T>UgV0yybBynvb)@O6ISqU!06(BBe{ z`a2Xt#D~z957W5XZXnD*rmeKow&eHC89##k9b!gLmMjV!JW5E*gTL{RE`j_kBtW=- zf<`aSx_Tq*U2VGUH!X8c1NiWQdU*YlOYcLJ$a!>4;5O``BAs>62j&6fNhnoe6TT0x zax#ko;@rtr`7PvNb>f5Q^K?-UyWV;d*2YhM@$KwaN)=UVRx#p^B^;^EbL-e1!;>#` zRarzrvN}N>P;+A>2Q|@kb7|9;Rvu9_gy6D!Lg}-x^=@8sDF{sXF%I=H%MQ_?x_BMP z|EGz}T+H}f13Jj7vshoO^OmpB$$@33CvzQ;YQLiEltH*|%|%~RpGM3CQOwAgi;^>1 zO5#-q*Xg)1V#r|Q-mx%-1PVXxe+R-BmPlnZzXw~rk75|?(9^~u ziVBDx0=)$l*=QGZHZ1r<=7i;|aGd)He1JmkO{|ay)l7pls~BC3^0+{^p}Z1H@}U7% zq@&DojPrr(ysLPFH>jp(jTI*wie=I0@A471pQ@jx0=)NXZoe_lf$&5!^)X=q zpWox1*t?qJi4dZ3c;_7~ccvYQ9sHeKr@oJm`*UAE26cg2djc5fBbI;S)8{tWT3p{s z8TTBKpBCrk&6QAIhqif;gqfDy4VA4|Prv@Axk|w$dthnFPoEt_b$nOT9Ep#R9vCF~ z9!deAhfLuf1=>SGcA3l;9xzmxat6L|u}9XMkkk6xz^ujWovTwSQ{!yf#q;Mhd2A@O z15P-c{*0}Hb`m`Si=x!JN(o~{BUKz@(z=ZPi>(t2{BP0VJw-|F2^ZB?s|PScq8{bP zg7& zIyIv$?)!2LvfDo(8vg-J#2Qn&i4lw+mb6!8^8tnv{Whs*0ND`PX;>pcv?6n}MoRZ% zKuY(gw(A5}idwT`RI2>9M_4IL~Uo$HxWV|7FFL{Uz zHoQC+)iVV3jXc%|5wLa>&PuAP5C#OReg01Pikz&B1+gh3z<=73Pam*W|Xw4v}AupZ_SnL=6+sI)a~sfUx5F;+Pva*I?xKpb!bO8RDJL@@O*6( zxmkYL$p};o-&C*x>BXB!ougR9eFR=f(~wiaW3jw8I7HOzj0v@N`4{-|xxVQDb=ou9 z0XxH`3NRTt?>V~(X12tCFSCEw+s_oUSCo)+iH50Wct9>y0fGCk=G|GS{JK80=4T}g z1^%!0%`r_7)_wT%m3)8kDWG8g1y#MDHJI^ki>Aax-edn1$-S$~D;6kJX5lRVu)0b9 zm3X}Hzj05rN(|-|$GlQ6q7JPAvhVk=M6NKCT8BZqE7X!NcoOvA>(hnG4AtGWfd2i@ z$B;F_G4TAMrEhirc7#4uruw>@;d2c@7*MbGcky%tou9Dt^rflCUoiYTTYGVoR{24M zJrSdI@AbluhYW!?viof!HNfXwsvUNE{+Z|Htm&hbau3(X*wRs--e;y&-9(E=?1jp) zExFVDA}qmSbh1-2gnnxj>s#q4FC+m#ikQpW>^>;W_%O8i_{&yRm#pV4f^p z9x5h)X!AKg%IgbXk{FbF4=<~XI)m?0!^Rc>nvE$rhSsSfybx-eQju{kfGr1bts82} z)I)K^UacX8VeeO{_oD{0kKWH?%8EKO1|4VSxCdCf?x#7s3Z&M&t}G?Q-G z8;k727tp{Qzp)a zJvOP_Z&Ctz%ZLvJk{)6zvo)6ps)jJc=xHiID+>n(Wu8%rz9qP~1K}S;r&coBwTo#O zM>J`UqiILePy=OJQg+i$3SoIXk0ha>eJYy3O#Gj!p;Y3!>pu7up7sRk+JGV|@|DwN z$r(dF!t#Vz@_Pi=0)dvYc-CH5- zL40k?!*1MDCEAGK;H-l7wKBl;9VsGtV6qH>Oh(*L3`j5a?8kQuX0G$=O(n)f*F$%M zFzNW6^9Lkl!f0d^G(Trr9SEkrEzU?a^l8l=67ey_p!0gTZKX3@qn`}%t$9PB`Wfov z@v+ES^T}J7m+Q$UbL{=AM^a9<(|e@TpAF6R)jn$N2@-HCUun#R+bjoB@1+n}h>rFA z?kK~}R%dj%|2y6+Q@g{|^|R^Cr0fN#USlipVNB?gT;QT#0F^#9?@2oz7vwi;iAp)@ zgw=)LjBYm#)osu!UvhrJ^-Jz*aOMHtpI0|?0(WGH`JKlnU(HDe{QK^742GC{u6;F` zyT^f?!mD3pSXUu8WB5Bv6HM6Rvz-S!Xpp(ww=Xzd1)7H3MSgJuYsc07T57zxe=iar z=n#C{!ERdW0gm)uG=j#rP*vd-M1(R=!sWNl1LD6Q$F_K?bySV8rGa&c5{!yZ{BGjS#xaZbwuYyWO9a!xoA%I9))9VZ$uEX@c-$}i z(N`D)!|OZtZ`MRARQS@lJf^;LzhUEyEHP6ni_d<4ZQq9h?Zn{OMt9% zd$swplY?p^FCF3{f1T9L3%IGzna$C;t}10}v)60oD`UN&KOb7EKepyoT|N>85pWs9 zXbiMsJs{H!a|iMhBqnhl1%)XrvQ2%8(U*lmyN9Y`1*O4B`b4P}oFUri7qa}r0t-u{ z?D_RSMFM`Srm8)#5VZ;fKj7B-c!%8E4nu-F&HdpLiE$#}$bF z49N~HwznMO!5%4MEHK*|UUYOkw{F+aNo^@DG@ZCws69n5%o^2gTx!Yf(>_qq*}0tM zU(QY9ON7PsYnoi2TlXF7R%#z#t?J00F2;6Ew=R=zpX*L=4Nv%)eM##x{$A)XW9o7I zvhN3GQbhRS&}CInPRwrff#1%WVe;8fFbPGq{vH|&=&~q=wK-7XI&*TG*EmbOZIO)2 z_()}5Gja6-2p84?)-TUE3rpV+LhlB3snF;O`uBfal$g-6Y17rtu4@j;IlM&4Ctk!H zdYxu2^tq75JY#Ql4%~2yTgP2j&lhrvI1KlQ_ILXE;iBtQ&)R;2PrG%D?4uC_aGuJc zKj3B?GgiCwlf41oM*|zoNSVxaqFA?o{KcTzjEVzDsJy!C>)e37p?kS3PhP zJs?U`w}|mb_)A9z3==qncL}8(-CT+}m1iEfhYAhP8wW&@whHh4-n~rk5MXLKUBvaC zNfTC1jZ618MQlp4Q3sy+R#Rvy~fhqu1b!_jjcV@T~EW&1EQ&*I7Cacl^LPv3o^v>{A5uEX8zF11?hvlTGkp9z<1G$`5 zNY$;E5_#|1+OB+{hNaCZ~L>q(wrB!H`}?}TvR%fl6@9^X0d0jh3j1fBm=#RtpKjlrTxtl-g_Arl*~f zc8p}~*(V_|21U);;}OF8V&*N+qw?RaWi>xl$CW%bLkSCL2eQTO&X2Hr18Xn{qaq%vT z@C0Ju7RQu5Hyr6QHvR!oCg2cwKr?;%z_KabQ*I!;?C@utZ;!ljm&dYq9b&pPqh1K@ zWT-_gK;$RyetzeDkf@h{<4!07xyem+t|=LNaBxx9eXcK#Mmt4FGn2EuF?H!e!B(|9 zsk6M*u=A;Eo*u_0(xeOHInv zdgD*u?9@7hwvbtV$nzs^AyC$8s9kRxmkh?U+tz4~ z5BE?|?=dEA_)9n^V?f`nb_@bwf4 z>SWcHX-feLYe`ryKN=Cp=Qte3Ir8vCEu&5VKMCse7`F+WXT1wHXt zI>tL>`(nRz!1u8>AVvqosta!t!S?)Z47Tc~#?S*IHeNM{g}-lfdA;^lnn*qw?9J@q zckl-lcdpf10r9VKCc<1d-a0$@btQ6M_7f!ZPRdG{n`2>YXZD$Cr^3sFF>P!6=`K5> zZyugXO=lu341s==gEUWp)xx#o&>!VE-PE2`#cV>TnLd!yl0H|qalk>SGo%@C$`q+= ztM;kH`30(JAFG6}UTPn$#|cH8gT+wjTC-n{)}rR5N&KhVa%*(=jgH!Oqy*^rgip@8 zaErEIDnidbj|j($+Q03KuQ|1A@9|jH_eO%2XS)A@clnHKGm(c4&v86uv9xwF63V!RKP2 zV@9|D?kF*7^6bp)Be{Q&Oz=?JvtQ8-sTHZu*s@B#F3CROZY%^%HhQiXSO!`*?TZ@^ zJP-J6%QM^TWY*+B`W}eb+2kVmuI=r;N7a7K-{-m04lNxt4(p)My(Yp`EuiE#{waj&_I$TwbU3-ktdE z)h0~+Qn%GDb4WEytubdE5w^Zz+Afw)`96;RSzUY5dLM)NWuIo{wr2b%QQ~I}HOsE_ zV=TJcFJHxWL>EVYL*TxA74=ls<^A_n9Es03pVZ02m-=4@w2v~-DZK&niptoaAAbAe z!YcIhsNm{!Rm5-1NKE|s?`|TSP`4)b!OcbsGwT&^CEd0WiN~4Mz2nvA=XBW>O6$hy zymz$&yysp&V`vi3B*{lSzobg3K6lf}sgu;x3&;y_G79*H-(f;Co$l~M{7c1(yUcxkc9vAv*%V)m>mb~Ytq{Y`C5njE(u<<4I(Z_TFc2v2k$xLp$Zf}oh*V-JB zQD-sP7p}>U|B=RU#_nj_mPYYqRA9o0iD@m>deU>U`yVXs7%_h=Jo+5PcanS6X4!k( zmF7#Wf>Rum{Y8n&x#&DO=eLj5Bp#JC)0lfBy|DcczfLar&@bz4rRrCuYtOVc-@MECBS5ut zCSO@$__5iqUd08?uds-+?(SM-zsGXXU2R&^z4@;dH1ilEo&0##PyATUy*KI>FY+rb zn!Rac$R_$7M&@KISXeTR&KOE%4NU_K^pl(TM0gzZS+#R)3VSofKhPf->Tvwg6`gC? zVF5l|Pa`?4U#M%cSd-qS@0VI}ky&BV4mOo?S~83!*a!_fM*5`vo_EFh{P}@6+R^tb z7caSfrD-1SHQo2(pUOZ!_@%M|r4sXA|6fN}!B$n*M3s~lk#3Nd?(UKjiA#4~x?7O$ z2I=nZZqQ42H*)Fjj_+jrkHwu91?ISq5hx~cKmneHcl;!HQ3ZegwV+eRR#N^*x67>N8sL?ge1 z@XN1a&g!bKo;`)x*+v&!RnWQm$V!@MORTz;NM{22Vn0~^8n9^omRiV3L;Uuj}UjJj= z7PWzay^yvQ@`H%1&oo+tHM+C}SoHDaBTCWd0UDDgXa_2lY zE>gAbB*}$}j?6;FJmHI|q!&=D$KJ9gCi4y~2Tl-;^V+Q);Y96bQc|kGoe?@4b*Zt9 zoDI}=q@GD36~=N(F^+j7jK#+vDo8qP9{slelzChcp&J|bGF+QY83JJr4wKIw&hoPE=Mo7 zIttE~#+C>?UB_0%hr-r`B@9iQEnPtqr|De6F1*?KXxD?JWJ7o;lLbj8<#nc=C5g9 zY+f;18pa{X$Kj{*4<_Z!!ow4ai$f04$E9}bdQH{FA+GzF7LBO_Ta!LP2g6y9k0+)Z zS{%BmO;#g{5i3JniMJ$L<+R;J@$Rb2(P?!X56aBz_;^_If2OJhdCa}9|J zIL+}kV#k#X%oWn_tx9X*fRf}j?qGPmZTmTwS&LCORr$xH6Oy#bhj7>S;n3dBQ}kt5 zn-qv8ke6N)v##dqC-v?iOAofBu78ky!Q3lgf9@-1rH1 z0`_DjM9}GBT&}uX@u3@mFS91%185A(u&`|r*#C)HoC4= zxri`=Egua3;sqBiBOlNU^E;3b5M8w{>I3;ZVP$-kJb!n=K!#8M4ix=T6F#J>-MWI! zM`G!(sOhp4I^DA%QzXWs&$JmxCX~pgmc(~u5rK~9`fob7HzAH|pRu|Os5SK>n?)C1 zuC49$2pY|QiaEk{BNOw6vC;$|^F2XBIsQ^|GNlO!@Et&{f=68I;MIJcNMdn@0}i^L z&DTygbn<0SQR#z=^EBn3nr9T8JUGm&52<;v`AEmWcuN%mZ>}n$H0?xKmKp+|YL>PB zwji57VinNWf>tr;jT10;(Yx$!KcdEd>vFQ%`^j)~barup=T+bS;P1e$oeJp*qn|v; zBNfSxO&2~n%gf|+#ZM7bq;{!^#Ox3pxJiU~Q{dNX2OnS;QBpO!l`hE=*}il9N{UiY ze68#v`L@H3Bn0F(m%i^K4~t?5_4*uE{J#t4@pT&|EyED+)ucVId2{ua=5juCX9za3 zP0d%?*uP~YVN_=HA`-y0ZTUai%}Vpp=bVVKZM}`|+t^#~xD|3vfFgkJk3+p~1LsbMp|i8Lg$tcJ^gw8{ZqPnG&onjJeYl z3-5!-7;nbdgHpG+BXKkIUOJ9h+lAA>8{n(hRHfPvsQw(foxUSV1H^8tSn70GBgpa1 z7p-u2zdBxqXS(Vu!T+z@iM`@&y-l+6vR+v?`Wyavv8yap+!`^M({}5#E&UF2>)SP0ytmN@icYB3APSHm}$wIXVD|0*yDd=my=cZ@8mc z3S*SENA3|NKYG*3JfyOXO{LXxeW=OC8-F4H=7b;OwEg57*>Co)6`J?^@OU0$ z&vEVUZvh}Ahd5I00yi*RTE=-QTyvRcaegGJ4gU;RjX?eLsO$^+(nXP%70_fEKDZRx z3qO4S_-QBX31IAW9#`P=6LUE|hJk8;NH6$jyQk~IDB)q>iM#JNlmua<@5UQ-<|JMA z!tBADYPv2Y6m3{9sU>aB2a|~1a_euKb2&bmE6Dg^Mwe=4D`kEzM0ECUIscBeeHq5f2qa%-NI(MVeU}~PJRfykKOxpFm z_0DZ3@%)yC-Xb>KD?XE?IFdxGV6oBf(AZbtY46$P3DM;%n{H8@bE{Huej(^>OvTjsLD3U-o=@s1glM595f!MX5+Q4WD95 zpO;F|E*}{uz16=_X1+9UI|TjqF(jMDp2pJK42;z$dpnmV)Y=y3p}wT6Z|ac2)VTR>JM0!;K5!cau?f)*cl2Y09#uIA9=#HZq8==gvK~ z=fXi~P#%+0iU4EV;xxrb;pZ&Fb86M&ooqMr_X8vdQV?>(@$kj+2r1i7-yH`TSSd=s z2C_@xvtZ%DtH;0aPpA^kDuUg1fCG%;P0~PPUWxkX@>HJkBXRsuY4c;pw_Px0S^(@y zkMru{R+Ca+A}Lp9y05mKtVv-NWC$_5lk@^4<1D?no^NK zU`7dTz+dQfh$WGfzzar8ExSk=oHV?Lafxx*n3et+BRr#~uyMQxlav)1L`IP>qYv?h z2O~}BE4opfkSPpeGC#-M2udnRl7zqz4sbBoM?n;hK|<M?(5j@nI!yxvbwC>vlJr_=^X`N5;(F$gyfaFPHrGS3ni-?z3oQH1My z$~EE5e1IIrvWPQEuGi=A!H<%=L8I`P=wJJNB+UGs{cpCLzvKN>{sr|aAT@CxEHD^d zRcr2XZ}p;t@EUtvNQEXNr*JT!*}<}}{1=3umr0u0u3*dYxC<~PFt+`1CO(6a4&Fob zqgSDYAHj&2>Tx)KAMcNt!YM9!3fPx=C>bd#dq;;LXkf&r{?>ohGH>qh0SC3c*H^6% z-z8f_oGxd{@ME);0sVJB&)|f%*j((nKzZ|SrK9ir$#VIWC0sEJ#q`LsFqdthsau** zUL&tsR51DhJg_td_^Bl;p@v>!+0Rlq@Vb4aat7u|w0*_zSMXFdBW z8PL6c133mTH|tqWEBi2I3#mK~8ero4JPJYEm2c3-8o8LKL)QNCsg;QopO}qJIm*%v z8mzoK=f(PWM^hEB>tdZ`&>#bbkjz8rwPSHEjyAK@XbHzxfyYT5VX|X z49x?~FEjpf-;)c5(WdD1jDUxD#(&V5)JumJ<^@c9-YK09&Ks(5` zVusEa)4D`w?mb^MflA%kMMcBKK+$PAAOEDo{r;!$?hS=9WMc4M0&YCI4`XQr(lz*u z-Zv_@(OXfO{JK#=$Q1)!FTwxgTWPQw=piN=F*;CD_SvqM_WZnJhXV?T$-z-X<-EgT zhQCKcg1Rl#m4>W@k%jy3K(6{9f!@_T1MIypr+(g0?sbt;Ai0h4NS&K47jyYz{ut5w z@HQc*(Yd(Mze zc#Uv&|D!cnc+KAXmB#Ju{M=A4t%L*J537Q=kY;AL!t_URYie|z;5@{Dyf45 z%l51)^=}?CQk|7V({ub|jD+>mMtAp5ZH8@eq`4iR(C*@j401l=_qlC7M97psS4h$j zTvWv24n2fekeHaQo*(bHZpmaDQBxIwjeX$yLtp*@=BBo6IdAW&jeQHlC14=nUQGtL zgpHNqmKz48_Jvc*mUL4lTGflr)p0l^v@qhZB@14nU3|_s@gpJS4%1P zcHAMua9IRU`Qa~9PgmPeR5p38qtxT;xJ9zS@r<>|3e&d z3T*+tDoyAMdBUgEl!{&Tq`Y^yYK0{foVReF?H1OrnXDLI&a<`eO75&mafjZ|9eEX& zFjLr8%Yni9dgr@G%ow)HXHVlI1q}6NKQa)fQ7#d-v1s?t<>N@spJR7{z1hV~$hbkA zDR3LiAPTCKA5}**{IdwD+2hkz(w1UWdde#ZJRinbm z%_I=to0Kf-`Ox*aWsTyqnHc9A8t=gw!y2}h^;w60@I45?t@6@7qH}Op_F5#lS(-6^KQ-Ju%KIC-4jBf=QNd)QgLvC#W#J3r=zuGZ z6_Nvz1FY`%O9EO`E&tryE_hwuEMTEcGR*vfE)B}gt!a%IzT7wZ}85>M^O<4qc*+O+AT%EoP5;Ih34_B9Gk2T8Ot2A2{@40>UXy1>6E| z-nPRnVTV5|7!cr-qtfyCq>gb9zA4fys-q74+JHq?$NOGj&iV{HP8AEWS?k=Zw2^Al zGLEm>#`Oca$Jd;5V%L%T|%xeZGwV8gy|t*Tp-#im}{ z!W$b$X8Z}0_%nnyLo%HcniETVA8Fj4J1Hdoz?aanqi;)Cns@`DDHy5D~96g zZ)@+Yp&(wn$OKuOuWmBPX!%{Z4v_fpIW&iH6>%zaR#;xzF<(-%Wkn4_J1vwCMHrN+6v;X)$&=s4< z)mI^yIak2Rc>k>AhgN)Hs7Jp{Kraoc%(O+GRJxTy>Kv|18L>sp~zExB%#)fiqeRcE}< z4mKvgwnAABzixW3>!gV!m#W+_|`0y_YKasGj+ND zo28Voes+91{u?oS-R5VX>P*UI;ZLCg+1hG$@K)vVVy5;0&D-j)A#$0?FM<_Dva>$6i%p3ZWi&@=`h6$L#uJot%mQUJN!8RnxKk(eZz#>`0)=f~}` zI~(&=HWg!A6je$`j;dg=xT<{CVL$ElVS?8wzL)%PeiC6+di#E=17Rz7WbNT%de~5H zX1f!|xaol%qk!+dxE|N-4PC&K`N9})`ENBe(GmcO#(<40YUo86P>;Sahnf!i(w`<> z+vZFs;X@DQ4gugK+e0H3`NWj8<7AW$o$!Y+SoLATuMNEKM<0nsR2GOdHz>;q%>?&%Quwx?i%sI49odg_>eY9R~^DZc{$E#eE^+K z7V_Cy&W2HYIrXr}Ph?(17r2KLHfYDk+D1t6D;XHTc#k04P#qwf(2m~U0@OXH6Gp3) zQ*!VlACa(}-g;HT4vbduxdG9cEc8BeBCLR~ea>Mec;gCHU7U*YOp)m+h$^Tfzf3PJ z?u}BAjxh!T@KGh03r)=LewhXX%r`SO6j`}9cV+-&J;zT77pWqZ2(VztObSE*y_GYQ z1XkK@>+?`ROA=jDvVdvaj-MJiwp=Bu%9_f4dMYCK430HcCb-ach)_P2oTC#muAr2-41DiozH0CoDQF&x_h)bikdtemqP2Kl z6G9KJ6?bnBflcY?`*xYIm?9t(NDFdS-CJOcwFxSH=#TNH?oFs_b2+&$QyY=lHtaeU zk%sS5>FXID%}zSG3tX9Rp#s3^3pZH#6t;o50}^z(6e`x6klM;rJl;7z6yY5P%VA9HR%YDgYgGd-TGAFFOe|_gKddnCG=toC2U1?}O^} z;6ud}QV%As4=25U{w$kea;p}Hw=P6Zu~)>z<*(rb^AEhJSjTzNNEE(CS)#4|FnPe} zD!1ww!5(~KcfG%ZoZRV!V-Dey(Q)O!0M8TiU_)O3L@*q!U|}%P3ZQ4ll14qfVb6|u z!N#4rAub1!1#0=hi2V(kOu)xWn)Gk0Cj|HymQEpKad@PyL;7ee%6~29BR-$38HArN zEJDyQIa`U-Rv~D?a#^SSx`f<#^v7QN7A!=E2UK8E$* zgb17JtF$~k(h>G|NHID@rQ6;*3z8<#3iSp8W|KVS%TlCCVQ z5XFmN@>{#{pC$LA|CwvDLJ5RueTiq11UdIAmX-SZl>}y(g0>g`QI*4Rp3=>El7~7y zwuGZa8{~O4k0%SbuUx}&*xoKg(!J^cH*H_&9<(%*@E>C zB36ONjrgA8ziLfZzZ*tH*;DP`x3GvxjT2-^NVRcxrQ!)t1O6{ zC^GD{Zs-s=0*96$lkE7!H6vQOVUqr_lAUosIdilLR6v$q}OTrG;++O>$teqGyyA7}Ay#9C~2cHRI`PinP^*obQdHw0?z6mEAG{%hrJglaI zV`=K0{fZ|sJwWENz^1FIy(dq6U%LiGfs{_;^-=PSf!VFTSbgJQ9KqcWu9F`;#x)!D zFLGCufKWS`&@hjlX&8Q$AcX#BwNiD)bF1sB>ukPpM*nzmsH~#rhHfT_^X9&D?=*b> za~Ge+@bG(V{OZ@6Q>O=O#?`9Ij>*P;pe-G^<@3$fy&ld_@&UqnAdxlVI36-Rlb@0D zE%+q9qHsd5`_w?*dCzyH_61Pd*3^n^h&dScJSh8*gk9#;ZS_*7Wt4dhHb&B_*Cj0a zEB*wM{(u=hRk7qWL*jW+`>^s~^zK~yq}d&Q9oHH0!^c2e-^yad2}JrWGUhqv(W34o z!-HH`EwSKv(AgBN^KErb7y$9>{+=ET>kgy`>`YMBxP`xdp=$dnEJb{ zUN<&T4G?}Q>%O|a*%5c(HLbaidLKHV{kx<80)D{Xkdk!u!_x^DhkJ+n=R;W()T)p1#%r9n@gp=?6^>35V(ew>5=&>BcCW4DDvY z!I>nwxu5JLDXfKuxY47V`jrp;cIZ3iR9#pU%t-5Pq<}2Qba29h1WS;M#5;a z?A>Y#8v)nF0_k(aLpvS}1u7kGsIny_0`)PGJv2O&hgJULXe~lX|4$u|1~sE-Uu?bQ;vK| zXM~DvCSR_j@P^h()qonnGvuG2yA}ukpjOxX{rL1>n*ob%qi!4h=^R!9L<#i<28-B) zMGlpJu;E0muN7_X$#Hs1eLBy>-74yoClyR3XUmv{(3|V_AqQnxnKaO{jSUuU8^sZ; z+pHLV1BFr#wPf&_Yi!P#OC=50fbCIP9L4Rja&E(}egwm;=x+zUkzIXN#^^owZl<7# za5=G7vF_Pw!R*5Aa*+}qDeY;GAZc3@G5T*){BgFWKx&5@DYg zZqX`diT*8yx28oW%kW=p+*#l3_|H*wEa^k#_&Lp`k6ahz zMa_}hDGo~q7jGNusfd!g!4BTinv15)x9g_Kor|WtIKSC(dVjH!E95x83mc(?FZ>`O zR?hlaVeF$^y?D^K;U^3FFV%w#7*bX5cm?0he3uEEHVO7ovN8TmO>rl*k$NY5OEYo? zeG=Mx;;_+tgW+Pjrug=Bn|F=_{cZ<)s^_*-f*r&U{+k?EzV2`{f26{6&J)Q#s5X%S z-cDd&28unL;Rgvgw z1+k!32`$&q;}DvXkTZUJezX1*p>ZU;$hl1OX-Q@g8?mVy2qqP{y9tl%nxt*&W!Uvhtk5(S;cl@q=cr zHf8oKuDojvl0p0hF+cmN%MVI*rqF-38hak0(^tvbIDXd~t7thU^rUt9himoRvpMIM zoMQHhC_(fEMkQZR&gp_D@`0ZBOh;^VvAihlknd)$Z#)d@oaBuTi#~6`aZ8%bV1>yb zUio>J8uHkjMh~Lt*0OgJ%c=4o$;}q2dQ|%QyD&tGZqd#j)a3oTjzWFJ^6Mh)BY#s? z4drm@t{Hv`m_UT}V764NvF80d3FG4_dZ?tM@|kljc@qO8*{Rr4ky#4#FUj-jb#=Wl_f0I-$>Hc#k?23 z7-{}vAm#hCG<+X4A$&9!4GMXt`MSzEpHphiN=r)C@Y4Jc=02+Aq9xnUFGsNwY=vgF zR$Hih-~<7ET6a%PT`EcXBA<`J2bvcv_cr%Bg1FTKkBC(1%#n<>aSF4Rh*btx$RIShdd)Ij93OZ|UAMqy`VQj9G_-kf6d& zu!V81Kqar8i~4oLv24f#Un58pify3|*8CE)~1-WJU!muyOZ};%W zMYwi)9n|s{g9SnU%va>N@;LKBOosT8+#OMl^%VupbXM;B=iHMkTMTE_s!sa7@%cM* zZizt8&;6>f3^+I1TW;F6&ZsQ;96u!Tl_9*#nxwZ^Ki(vWbaW{z_i-&hIkHjmk!8Yw zu~AVlz@mS8lQd+l8Ab#RMEsKR_KiWj?8D7pDCt@}UCi8Xs?d-?w|24*GyOjo&n;xK zMTw>V?F|X$hzAA>%r*dD&Qw&ySmB^mTn;)1xOnT~Qt8DW&yc zpZHJrOI@5>2({{>i`k;ZM4v7+H!gUue9poF*BkYOMxmj2-55gm(@x`i?R4 zl@Wb4q*(^)q!TqENr@);!)t%%A#gzhHjW1mrjy(4RJ_x_x5LeBPa0{hKI^Xi^z^IM zd|40`m(gwdpS#$ta*5pUw4aepEwf6?L-d+7&Mcf}70jK$z?OcFZGA{dS`eHpRV%^& z1qnAr$?ANW)p#nuB~Z>!Q2#;psb)8ph1gH*|6jNv)g1bAEQ{c##uOQNIXj|V9PHux z@H*)u+-mxeNn#MS0r4<1}Us!+GB=I2QC!z}zA zFK8>0?TPI;m%=1=d402<>{Qn1@MnN +2019 + + From 5ff4ae74305315eada91c37da93879bbb723bfc1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 4 Apr 2019 16:29:46 -0700 Subject: [PATCH 0008/1772] Add "liftoff" content. - Add a tentative agenda for the first meeting, though it isn't yet scheduled. - Create an intial directory structure with a few documents. --- proposals/random/Charter.md | 55 + proposals/random/README.md | 20 +- proposals/random/design/WASI-core.md | 2315 +++++++++++++++++ proposals/random/docs/WASI-overview.md | 147 ++ .../docs/wasi-software-architecture.png | Bin 0 -> 28267 bytes .../random/meetings/2019/WASI-liftoff.md | 64 + proposals/random/meetings/README.md | 15 + 7 files changed, 2610 insertions(+), 6 deletions(-) create mode 100644 proposals/random/Charter.md create mode 100644 proposals/random/design/WASI-core.md create mode 100644 proposals/random/docs/WASI-overview.md create mode 100644 proposals/random/docs/wasi-software-architecture.png create mode 100644 proposals/random/meetings/2019/WASI-liftoff.md create mode 100644 proposals/random/meetings/README.md diff --git a/proposals/random/Charter.md b/proposals/random/Charter.md new file mode 100644 index 000000000..b73293475 --- /dev/null +++ b/proposals/random/Charter.md @@ -0,0 +1,55 @@ +# WebAssembly System Interface Subgroup Charter + +The System Interface Subgroup is a sub-organization of the +[WebAssembly Community Group](https://www.w3.org/community/webassembly/) of the W3C. +As such, it is intended that its charter align with that of the CG. In particular, +the sections of the [CG charter](https://webassembly.github.io/cg-charter/) relating to +[Community and Business Group Process](https://webassembly.github.io/cg-charter/#process), +[Contribution Mechanics](https://webassembly.github.io/cg-charter/#contrib), +[Transparency](https://webassembly.github.io/cg-charter/#transparency), and +[Decision Process](https://webassembly.github.io/cg-charter/#decision) also apply to the Subgroup. + +## Goals + +The mission of this sugbroup is to provide a forum for pre-standardization +collaboration on a system interface API for WebAssembly programs. + +## Scope + +The Subgroup will consider topics related to system interface APIs, including: + +- APIs for host filesystems, network stacks, and other resources. +- APIs for graphics, audio, input devices +- APIs for encryption, format conversion, and other transformations + (particularly where hardware accelleration may be available on some plaforms) + + +## Deliverables + +### Specifications +The Subgroup may produce several kinds of specification-related work output: +- Creation of new specifications in standards bodies or working +groups (e.g. Wasm WG or TC39) +- Creation of new specifications outside of standards bodies +(e.g. similar to the LLVM object file format documentation in Wasm tool conventions) + +### Non-normative reports +The Subgroup may produce non-normative material such as requirements +documents, recommendations, and use cases. + +### Software +The Subgroup may produce software related to Wasm system interface APIs (either +as standalone libraries, tooling, or integration of interface-related +functionality in existing CG software such as Binaryen or WABT). Capabilities may +include: +- Libraries implementing external standard APIs in terms of WebAssembly + System Interface APIs +- Tools for producing code that uses WebAssembly System Interface APIs +- Tools for implementing WebAssembly APIs +- Tools for debugging programs using WebAssembly System Interface APIs + +## Amendments to this Charter and Chair Selection + +This charter may be amended, and Subgroup Chairs may be selected by vote of the full +WebAssembly Community Group. + diff --git a/proposals/random/README.md b/proposals/random/README.md index 05d744744..4cf122cab 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -2,16 +2,24 @@ ![WASI](WASI.png) -This repository accompanies the WebAssembly WASI Subgroup, -focused on the design of the WASI, the WebAssembly System Interface. +This repository is for the WebAssembly System Interface (WASI) Subgroup of the +[WebAssembly Community Group]. Its [Charter] describes the goals, scope and +deliverables of the group. The repository may contain meeting notes, reports, +documentation, specifications and/or software produced by the group (although +larger projects may also have their own repositories). -We'll be adding more content here, but for now, check out these: +[WebAssembly Community Group](https://www.w3.org/community/webassembly/) +[Charter]: Charter.md + +We'll be adding more content here before long, but for now, check out these: - https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ - Blog post introducing WASI - - https://wasi.dev/ - Links to more information about WASI + - https://wasi.dev/ - Links to more information about WASI, including + how to get started using it. - https://github.com/WebAssembly/WASI/issues - This repo's issue tracker The issue tracker is the place to ask questions, make suggestions, and start discussions. -As a W3C CG Subgroup, we'll also be having meetings. Once we have a schedule -for those, we'll post that here also. +As a W3C CG Subgroup, we'll also be having [meetings](meetings/README.md). +A tentative agenda for the first meeting is [here](https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-liftoff.md). +Once we have a date and time, we'll post that here also. diff --git a/proposals/random/design/WASI-core.md b/proposals/random/design/WASI-core.md new file mode 100644 index 000000000..c4b256ad3 --- /dev/null +++ b/proposals/random/design/WASI-core.md @@ -0,0 +1,2315 @@ + + +# WASI Core API + +This is the API-level documentation for WASI Core. The function names +are prefixed with "\_\_wasi\_" to reflect how they are spelled in +flat-namespace contexts, however at the wasm module level, they are +unprefixed, because they're inside a module namespace (currently +"wasi\_unstable"). + +Functions that start with `__wasi_fd_` operate on file descriptors, +while functions that start with `__wasi_path_` operate on filesystem +paths, which are relative to directory file descriptors. + +Much inspiration and content here is derived from [CloudABI] and [POSIX], +though there are also several differences from CloudABI and POSIX. For +example, WASI Core has no concept of processes in the traditional Unix +sense. While wasm linear memories have some of the aspects of processes, +and it's possible to *emulate* the full semantics of processes on top of +them, this can sometimes be unnatural and inefficient. The goal for +WASI Core is to be a WebAssembly-native API that exposes APIs that fit +well into the underlying WebAssembly platform, rather than to directly +emulate other platforms. + +This is also a work in progress, and the API here is still evolving. + +[CloudABI]: https://github.com/NuxiNL/cloudabi +[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ + +## System calls + +- [`__wasi_args_get()`](#args_get) +- [`__wasi_args_sizes_get()`](#args_sizes_get) +- [`__wasi_clock_res_get()`](#clock_res_get) +- [`__wasi_clock_time_get()`](#clock_time_get) +- [`__wasi_environ_get()`](#environ_get) +- [`__wasi_environ_sizes_get()`](#environ_sizes_get) +- [`__wasi_fd_advise()`](#fd_advise) +- [`__wasi_fd_allocate()`](#fd_allocate) +- [`__wasi_fd_close()`](#fd_close) +- [`__wasi_fd_datasync()`](#fd_datasync) +- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) +- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) +- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) +- [`__wasi_fd_filestat_get()`](#fd_filestat_get) +- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) +- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) +- [`__wasi_fd_pread()`](#fd_pread) +- [`__wasi_fd_prestat_get()`](#fd_prestat_get) +- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) +- [`__wasi_fd_pwrite()`](#fd_pwrite) +- [`__wasi_fd_read()`](#fd_read) +- [`__wasi_fd_readdir()`](#fd_readdir) +- [`__wasi_fd_renumber()`](#fd_renumber) +- [`__wasi_fd_seek()`](#fd_seek) +- [`__wasi_fd_sync()`](#fd_sync) +- [`__wasi_fd_tell()`](#fd_tell) +- [`__wasi_fd_write()`](#fd_write) +- [`__wasi_path_create_directory()`](#path_create_directory) +- [`__wasi_path_filestat_get()`](#path_filestat_get) +- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) +- [`__wasi_path_link()`](#path_link) +- [`__wasi_path_open()`](#path_open) +- [`__wasi_path_readlink()`](#path_readlink) +- [`__wasi_path_remove_directory()`](#path_remove_directory) +- [`__wasi_path_rename()`](#path_rename) +- [`__wasi_path_symlink()`](#path_symlink) +- [`__wasi_path_unlink_file()`](#path_unlink_file) +- [`__wasi_poll_oneoff()`](#poll_oneoff) +- [`__wasi_proc_exit()`](#proc_exit) +- [`__wasi_proc_raise()`](#proc_raise) +- [`__wasi_random_get()`](#random_get) +- [`__wasi_sched_yield()`](#sched_yield) +- [`__wasi_sock_recv()`](#sock_recv) +- [`__wasi_sock_send()`](#sock_send) +- [`__wasi_sock_shutdown()`](#sock_shutdown) + +### `__wasi_args_get()` + +Read command-line argument data. + +The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + +Inputs: + +- char \*\*argv + + A pointer to a buffer to write the argument pointers. + +- char \*argv\_buf + + A pointer to a buffer to write the argument string data. + +### `__wasi_args_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*argc + + The number of arguments. + +- size\_t \*argv\_buf\_size + + The size of the argument string data. + +### `__wasi_clock_res_get()` + +Return the resolution of a clock. + +Implementations are required to provide a non-zero value for supported clocks. +For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). + +Note: This is similar to `clock_getres` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the resolution. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) resolution + + The resolution of the clock. + +### `__wasi_clock_time_get()` + +Return the time value of a clock. + +Note: This is similar to `clock_gettime` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the time. + +- [\_\_wasi\_timestamp\_t](#timestamp) precision + + The maximum lag (exclusive) that the returned + time value may have, compared to its actual + value. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) time + + The time value of the clock. + +### `__wasi_environ_get()` + +Read environment variable data. + +The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + +Inputs: + +- char \*\*environ + + A pointer to a buffer to write the environment variable pointers. + +- char \*environ\_buf + + A pointer to a buffer to write the environment variable string data. + +### `__wasi_environ_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*environ\_count + + The number of environment variables. + +- size\_t \*environ\_buf\_size + + The size of the environment variable string data. + +### `__wasi_fd_advise()` + +Provide file advisory information on a file descriptor. + +Note: This is similar to `posix_fadvise` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file for which to provide file advisory information. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file to which the advisory applies. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the region to which the advisory applies. + +- [\_\_wasi\_advice\_t](#advice) advice + + The advice. + +### `__wasi_fd_allocate()` + +Force the allocation of space in a file. + +Note: This is similar to `posix_fallocate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file in which to allocate space. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset at which to start the allocation. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the area that is allocated. + +### `__wasi_fd_close()` + +Close a file descriptor. + +Note: This is similar to `close` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to close. + +### `__wasi_fd_datasync()` + +Synchronize the data of a file to disk. + +Note: This is similar to `fdatasync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file to synchronize to disk. + +### `__wasi_fd_fdstat_get()` + +Get the attributes of a file descriptor. + +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well +as additional fields. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_fdstat\_t](#fdstat) \*buf + + The buffer where the file descriptor's attributes are stored. + +### `__wasi_fd_fdstat_set_flags()` + +Adjust the flags associated with a file descriptor. + +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_fdflags\_t](#fdflags) flags + + The desired values of the file descriptor + flags. + +### `__wasi_fd_fdstat_set_rights()` + +Adjust the rights associated with a file descriptor. + +This can only be used to remove rights, and returns +[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt +to add rights. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The desired rights of the file descriptor. + +### `__wasi_fd_filestat_get()` + +Return the attributes of an open file. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_fd_filestat_set_size()` + +Adjust the size of an open file. If this increases the file's size, the extra +bytes are filled with zeros. + +Note: This is similar to `ftruncate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + A file descriptor for the file to adjust. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + The desired file size. + +### `__wasi_fd_filestat_set_times()` + +Adjust the timestamps of an open file or directory. + +Note: This is similar to `futimens` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_fd_pread()` + +Read from a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `preadv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors in which to store data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to read. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_prestat_get()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- [\_\_wasi\_prestat\_t](#prestat) \*buf + + The buffer where the description is stored. + +### `__wasi_fd_prestat_dir_name()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- const char \*path and size\_t path\_len + + A buffer into which to write the preopened directory name. + +### `__wasi_fd_pwrite()` + +Write to a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `pwritev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to write. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_fd_read()` + +Read from a file descriptor. + +Note: This is similar to `readv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors to which to store data. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_readdir()` + +Read directory entries from a directory. + +When successful, the contents of the output buffer consist of +a sequence of directory entries. Each directory entry consists +of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes +holding the name of the directory entry. + +This function fills the output buffer as much as possible, +potentially truncating the last directory entry. This allows +the caller to grow its read buffer size in case it's too small +to fit a single large directory entry, or skip the oversized +directory entry. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The directory from which to read the directory + entries. + +- void \*buf and size\_t buf\_len + + The buffer where directory entries are stored. + +- [\_\_wasi\_dircookie\_t](#dircookie) cookie + + The location within the directory to start + reading. + +Outputs: + +- size\_t bufused + + The number of bytes stored in the read buffer. + If less than the size of the read buffer, the + end of the directory has been reached. + +### `__wasi_fd_renumber()` + +Atomically replace a file descriptor by renumbering another +file descriptor. + +Due to the strong focus on thread safety, this environment +does not provide a mechanism to duplicate or renumber a file +descriptor to an arbitrary number, like dup2(). This would be +prone to race conditions, as an actual file descriptor with the +same number could be allocated by a different thread at the same +time. + +This function provides a way to atomically renumber file +descriptors, which would disappear if dup2() were to be +removed entirely. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) from + + The file descriptor to renumber. + +- [\_\_wasi\_fd\_t](#fd) to + + The file descriptor to overwrite. + +### `__wasi_fd_seek()` + +Move the offset of a file descriptor. + +Note: This is similar to `lseek` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_filedelta\_t](#filedelta) offset + + The number of bytes to move. + +- [\_\_wasi\_whence\_t](#whence) whence + + The base from which the offset is relative. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) newoffset + + The new offset of the file descriptor, + relative to the start of the file. + +### `__wasi_fd_sync()` + +Synchronize the data and metadata of a file to disk. + +Note: This is similar to `fsync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file containing the data + and metadata to synchronize to disk. + +### `__wasi_fd_tell()` + +Return the current offset of a file descriptor. + +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The current offset of the file descriptor, relative to the start of the file. + +### `__wasi_fd_write()` + +Write to a file descriptor. + +Note: This is similar to `writev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_path_create_directory()` + +Create a directory. + +Note: This is similar to `mkdirat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path at which to create the directory. + +### `__wasi_path_filestat_get()` + +Return the attributes of a file or directory. + +Note: This is similar to `stat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_path_filestat_set_times()` + +Adjust the timestamps of a file or directory. + +Note: This is similar to `utimensat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_path_link()` + +Create a hard link. + +Note: This is similar to `linkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags + + Flags determining the method of how the path is resolved. + +- const char \*old\_path and size\_t old\_path\_len + + The source path from which to link. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the hard link. + +### `__wasi_path_open()` + +Open a file or directory. + +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since +this is error-prone in multi-threaded contexts. The returned file +descriptor is guaranteed to be less than 231. + +Note: This is similar to `openat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) dirfd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The relative path of the file or directory to open, relative to + the [`dirfd`](#path_open.dirfd) directory. + +- [\_\_wasi\_oflags\_t](#oflags) o_flags + + The method by which to open the file. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The initial rights of the newly created file descriptor. The + implementation is allowed to return a file descriptor with fewer + rights than specified, if and only if those rights do not apply + to the type of file being opened. + + The *base* rights are rights that will apply to operations using + the file descriptor itself, while the *inheriting* rights are + rights that apply to file descriptors derived from it. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + The initial flags of the file descriptor. + +Outputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file that has been + opened. + +### `__wasi_path_readlink()` + +Read the contents of a symbolic link. + +Note: This is similar to `readlinkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path of the symbolic link from which to read. + +- char \*buf and size\_t buf\_len + + The buffer to which to write the contents of the symbolic link. + +Outputs: + +- size\_t bufused + + The number of bytes placed in the buffer. + +### `__wasi_path_remove_directory()` + +Remove a directory. + +Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. + +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a directory to remove. + +### `__wasi_path_rename()` + +Rename a file or directory. + +Note: This is similar to `renameat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- const char \*old\_path and size\_t old\_path\_len + + The source path of the file or directory to rename. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path to which to rename the file or directory. + +### `__wasi_path_symlink()` + +Create a symbolic link. + +Note: This is similar to `symlinkat` in POSIX. + +Inputs: + +- const char \*old\_path and size\_t old_path\_len + + The contents of the symbolic link. + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the symbolic link. + +### `__wasi_path_unlink_file()` + +Unlink a file. + +Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. + +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a file to unlink. + +### `__wasi_poll_oneoff()` + +Concurrently poll for the occurrence of a set of events. + +Inputs: + +- const [\_\_wasi\_subscription\_t](#subscription) \*in + + The events to which to subscribe. + +- [\_\_wasi\_event\_t](#event) \*out + + The events that have occurred. + +- size\_t nsubscriptions + + Both the number of subscriptions and events. + +Outputs: + +- size\_t nevents + + The number of events stored. + +### `__wasi_proc_exit()` + +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +Note: This is similar to `_Exit` in POSIX. + +Inputs: + +- [\_\_wasi\_exitcode\_t](#exitcode) rval + + The exit code returned by the process. + +Does not return. + +### `__wasi_proc_raise()` + +Send a signal to the process of the calling thread. + +Note: This is similar to `raise` in POSIX. + +Inputs: + +- [\_\_wasi\_signal\_t](#signal) sig + + The signal condition to trigger. + +### `__wasi_random_get()` + +Write high-quality random data into a buffer. + +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. + +This function may execute slowly, so when large mounts of random +data are required, it's advisable to use this function to seed a +pseudo-random number generator, rather than to provide the +random data directly. + +Inputs: + +- void \*buf and size\_t buf\_len + + The buffer to fill with random data. + +### `__wasi_sched_yield()` + +Temporarily yield execution of the calling thread. + +Note: This is similar to `sched_yield` in POSIX. + +### `__wasi_sock_recv()` + +Receive a message from a socket. + +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to receive data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len + + List of scatter/gather vectors to which to store data. + +- [\_\_wasi\_riflags\_t](#riflags) ri\_flags + + Message flags. + +Outputs: + +- size\_t ro\_datalen + + Number of bytes stored in [`ri_data`](#sock_recv.ri_data). + +- [\_\_wasi\_roflags\_t](#roflags) ro\_flags + + Message flags. + +### `__wasi_sock_send()` + +Send a message on a socket. + +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to send data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len + + List of scatter/gather vectors to which to retrieve data + +- [\_\_wasi\_siflags\_t](#siflags) si\_flags + + Message flags. + +Outputs: + +- size\_t so\_datalen + + Number of bytes transmitted. + +### `__wasi_sock_shutdown()` + +Shut down socket send and receive channels. + +Note: This is similar to `shutdown` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to shutdown channels. + +- [\_\_wasi\_sdflags\_t](#sdflags) how + + Which channels on the socket to shut down. + +## Types + +### `__wasi_advice_t` (`uint8_t`) + +File or memory access pattern advisory information. + +Used by [`__wasi_fd_advise()`](#fd_advise). + +Possible values: + +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + +- **`__WASI_ADVICE_NORMAL`** + + The application has no advice to give on its behavior + with respect to the specified data. + +- **`__WASI_ADVICE_RANDOM`** + + The application expects to access the specified data + in a random order. + +- **`__WASI_ADVICE_SEQUENTIAL`** + + The application expects to access the specified data + sequentially from lower offsets to higher offsets. + +- **`__WASI_ADVICE_WILLNEED`** + + The application expects to access the specified data + in the near future. + +### `__wasi_ciovec_t` (`struct`) + +A region of memory for scatter/gather writes. + +Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). + +Members: + +- const void \*buf and size\_t buf\_len + + The address and length of the buffer to be written. + +### `__wasi_clockid_t` (`uint32_t`) + +Identifiers for clocks. + +Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). + +Possible values: + +- **`__WASI_CLOCK_MONOTONIC`** + + The store-wide monotonic clock, which is defined as a + clock measuring real time, whose value cannot be + adjusted and which cannot have negative clock jumps. + + The epoch of this clock is undefined. The absolute + time value of this clock therefore has no meaning. + +- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** + + The CPU-time clock associated with the current + process. + +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + +- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** + + The CPU-time clock associated with the current thread. + +### `__wasi_device_t` (`uint64_t`) + +Identifier for a device containing a file system. Can be used +in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or +directory in the filesystem. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_dircookie_t` (`uint64_t`) + +A reference to the offset of a directory entry. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). + +Special values: + +- **`__WASI_DIRCOOKIE_START`** + + Permanent reference to the first directory entry + within a directory. + +### `__wasi_dirent_t` (`struct`) + +A directory entry. + +Members: + +- [\_\_wasi\_dircookie\_t](#dircookie) d\_next + + The offset of the next directory entry stored in this + directory. + +- [\_\_wasi\_inode\_t](#inode) d\_ino + + The serial number of the file referred to by this + directory entry. + +- uint32\_t d\_namlen + + The length of the name of the directory entry. + +- [\_\_wasi\_filetype\_t](#filetype) d\_type + + The type of the file referred to by this directory + entry. + +### `__wasi_errno_t` (`uint16_t`) + +Error codes returned by functions. + +Not all of these error codes are returned by the functions +provided by this API; some are used in higher-level library layers, +and others are provided merely for alignment with POSIX. + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_ESUCCESS`** + + No error occurred. System call completed successfully. + +- **`__WASI_E2BIG`** + + Argument list too long. + +- **`__WASI_EACCES`** + + Permission denied. + +- **`__WASI_EADDRINUSE`** + + Address in use. + +- **`__WASI_EADDRNOTAVAIL`** + + Address not available. + +- **`__WASI_EAFNOSUPPORT`** + + Address family not supported. + +- **`__WASI_EAGAIN`** + + Resource unavailable, or operation would block. + +- **`__WASI_EALREADY`** + + Connection already in progress. + +- **`__WASI_EBADF`** + + Bad file descriptor. + +- **`__WASI_EBADMSG`** + + Bad message. + +- **`__WASI_EBUSY`** + + Device or resource busy. + +- **`__WASI_ECANCELED`** + + Operation canceled. + +- **`__WASI_ECHILD`** + + No child processes. + +- **`__WASI_ECONNABORTED`** + + Connection aborted. + +- **`__WASI_ECONNREFUSED`** + + Connection refused. + +- **`__WASI_ECONNRESET`** + + Connection reset. + +- **`__WASI_EDEADLK`** + + Resource deadlock would occur. + +- **`__WASI_EDESTADDRREQ`** + + Destination address required. + +- **`__WASI_EDOM`** + + Mathematics argument out of domain of function. + +- **`__WASI_EDQUOT`** + + Reserved. + +- **`__WASI_EEXIST`** + + File exists. + +- **`__WASI_EFAULT`** + + Bad address. + +- **`__WASI_EFBIG`** + + File too large. + +- **`__WASI_EHOSTUNREACH`** + + Host is unreachable. + +- **`__WASI_EIDRM`** + + Identifier removed. + +- **`__WASI_EILSEQ`** + + Illegal byte sequence. + +- **`__WASI_EINPROGRESS`** + + Operation in progress. + +- **`__WASI_EINTR`** + + Interrupted function. + +- **`__WASI_EINVAL`** + + Invalid argument. + +- **`__WASI_EIO`** + + I/O error. + +- **`__WASI_EISCONN`** + + Socket is connected. + +- **`__WASI_EISDIR`** + + Is a directory. + +- **`__WASI_ELOOP`** + + Too many levels of symbolic links. + +- **`__WASI_EMFILE`** + + File descriptor value too large. + +- **`__WASI_EMLINK`** + + Too many links. + +- **`__WASI_EMSGSIZE`** + + Message too large. + +- **`__WASI_EMULTIHOP`** + + Reserved. + +- **`__WASI_ENAMETOOLONG`** + + Filename too long. + +- **`__WASI_ENETDOWN`** + + Network is down. + +- **`__WASI_ENETRESET`** + + Connection aborted by network. + +- **`__WASI_ENETUNREACH`** + + Network unreachable. + +- **`__WASI_ENFILE`** + + Too many files open in system. + +- **`__WASI_ENOBUFS`** + + No buffer space available. + +- **`__WASI_ENODEV`** + + No such device. + +- **`__WASI_ENOENT`** + + No such file or directory. + +- **`__WASI_ENOEXEC`** + + Executable file format error. + +- **`__WASI_ENOLCK`** + + No locks available. + +- **`__WASI_ENOLINK`** + + Reserved. + +- **`__WASI_ENOMEM`** + + Not enough space. + +- **`__WASI_ENOMSG`** + + No message of the desired type. + +- **`__WASI_ENOPROTOOPT`** + + Protocol not available. + +- **`__WASI_ENOSPC`** + + No space left on device. + +- **`__WASI_ENOSYS`** + + Function not supported. + +- **`__WASI_ENOTCONN`** + + The socket is not connected. + +- **`__WASI_ENOTDIR`** + + Not a directory or a symbolic link to a directory. + +- **`__WASI_ENOTEMPTY`** + + Directory not empty. + +- **`__WASI_ENOTRECOVERABLE`** + + State not recoverable. + +- **`__WASI_ENOTSOCK`** + + Not a socket. + +- **`__WASI_ENOTSUP`** + + Not supported, or operation not supported on socket. + +- **`__WASI_ENOTTY`** + + Inappropriate I/O control operation. + +- **`__WASI_ENXIO`** + + No such device or address. + +- **`__WASI_EOVERFLOW`** + + Value too large to be stored in data type. + +- **`__WASI_EOWNERDEAD`** + + Previous owner died. + +- **`__WASI_EPERM`** + + Operation not permitted. + +- **`__WASI_EPIPE`** + + Broken pipe. + +- **`__WASI_EPROTO`** + + Protocol error. + +- **`__WASI_EPROTONOSUPPORT`** + + Protocol not supported. + +- **`__WASI_EPROTOTYPE`** + + Protocol wrong type for socket. + +- **`__WASI_ERANGE`** + + Result too large. + +- **`__WASI_EROFS`** + + Read-only file system. + +- **`__WASI_ESPIPE`** + + Invalid seek. + +- **`__WASI_ESRCH`** + + No such process. + +- **`__WASI_ESTALE`** + + Reserved. + +- **`__WASI_ETIMEDOUT`** + + Connection timed out. + +- **`__WASI_ETXTBSY`** + + Text file busy. + +- **`__WASI_EXDEV`** + + Cross-device link. + +- **`__WASI_ENOTCAPABLE`** + + Extension: Capabilities insufficient. + +### `__wasi_event_t` (`struct`) + +An event that occurred. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that got attached to + [`__wasi_subscription_t::userdata`](#subscription.userdata). + +- [\_\_wasi\_errno\_t](#errno) error + + If non-zero, an error that occurred while processing + the subscription request. + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event that occurred. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_filesize\_t](#filesize) nbytes + + The number of bytes available for reading or writing. + + - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags + + The state of the file descriptor. + +### `__wasi_eventrwflags_t` (`uint16_t` bitfield) + +The state of the file descriptor subscribed to with +[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_EVENT_FD_READWRITE_HANGUP`** + + The peer of this socket has closed or disconnected. + +### `__wasi_eventtype_t` (`uint8_t`) + +Type of a subscription to an event or its occurrence. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_EVENTTYPE_CLOCK`** + + The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) + has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +- **`__WASI_EVENTTYPE_FD_READ`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + data available for reading. This event always triggers + for regular files. + +- **`__WASI_EVENTTYPE_FD_WRITE`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + capacity available for writing. This event always + triggers for regular files. + +### `__wasi_exitcode_t` (`uint32_t`) + +Exit code generated by a process when exiting. + +Used by [`__wasi_proc_exit()`](#proc_exit). + +### `__wasi_fd_t` (`uint32_t`) + +A file descriptor number. + +Used by many functions in this API. + +As in POSIX, three file descriptor numbers are provided to instances +on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, +and `STDERR_FILENO`). + +Other than these, WASI implementations are not required to allocate +new file descriptors in ascending order. + +### `__wasi_fdflags_t` (`uint16_t` bitfield) + +File descriptor flags. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_FDFLAG_APPEND`** + + Append mode: Data written to the file is always + appended to the file's end. + +- **`__WASI_FDFLAG_DSYNC`** + + Write according to synchronized I/O data integrity + completion. Only the data stored in the file is + synchronized. + +- **`__WASI_FDFLAG_NONBLOCK`** + + Non-blocking mode. + +- **`__WASI_FDFLAG_RSYNC`** + + Synchronized read I/O operations. + +- **`__WASI_FDFLAG_SYNC`** + + Write according to synchronized I/O file integrity completion. + In addition to synchronizing the data stored in the file, the + implementation may also synchronously update the file's metadata. + +### `__wasi_fdstat_t` (`struct`) + +File descriptor attributes. + +Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). + +Members: + +- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype + + File type. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + File descriptor flags. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base + + Rights that apply to this file descriptor. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + Maximum set of rights that may be installed on new + file descriptors that are created through this file + descriptor, e.g., through [`__wasi_path_open()`](#path_open). + +### `__wasi_filedelta_t` (`int64_t`) + +Relative offset within a file. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +### `__wasi_filesize_t` (`uint64_t`) + +Non-negative file size or length of a region within a file. + +Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +### `__wasi_filestat_t` (`struct`) + +File attributes. + +Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). + +Members: + +- [\_\_wasi\_device\_t](#device) st\_dev + + Device ID of device containing the file. + +- [\_\_wasi\_inode\_t](#inode) st\_ino + + File serial number. + +- [\_\_wasi\_filetype\_t](#filetype) st\_filetype + + File type. + +- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink + + Number of hard links to the file. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + For regular files, the file size in bytes. For + symbolic links, the length in bytes of the pathname + contained in the symbolic link. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + Last data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + Last data modification timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim + + Last file status change timestamp. + +### `__wasi_filetype_t` (`uint8_t`) + +The type of a file descriptor or file. + +Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). + +Possible values: + +- **`__WASI_FILETYPE_UNKNOWN`** + + The type of the file descriptor or file is unknown or + is different from any of the other types specified. + +- **`__WASI_FILETYPE_BLOCK_DEVICE`** + + The file descriptor or file refers to a block device + inode. + +- **`__WASI_FILETYPE_CHARACTER_DEVICE`** + + The file descriptor or file refers to a character + device inode. + +- **`__WASI_FILETYPE_DIRECTORY`** + + The file descriptor or file refers to a directory + inode. + +- **`__WASI_FILETYPE_REGULAR_FILE`** + + The file descriptor or file refers to a regular file + inode. + +- **`__WASI_FILETYPE_SOCKET_DGRAM`** + + The file descriptor or file refers to a datagram + socket. + +- **`__WASI_FILETYPE_SOCKET_STREAM`** + + The file descriptor or file refers to a byte-stream + socket. + +- **`__WASI_FILETYPE_SYMBOLIC_LINK`** + + The file refers to a symbolic link inode. + +### `__wasi_fstflags_t` (`uint16_t` bitfield) + +Which file time attributes to adjust. + +Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +Possible values: + +- **`__WASI_FILESTAT_SET_ATIM`** + + Adjust the last data access timestamp to the value + stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). + +- **`__WASI_FILESTAT_SET_ATIM_NOW`** + + Adjust the last data access timestamp to the time + of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +- **`__WASI_FILESTAT_SET_MTIM`** + + Adjust the last data modification timestamp to the + value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). + +- **`__WASI_FILESTAT_SET_MTIM_NOW`** + + Adjust the last data modification timestamp to the + time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +### `__wasi_inode_t` (`uint64_t`) + +File serial number that is unique within its file system. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). + +### `__wasi_iovec_t` (`struct`) + +A region of memory for scatter/gather reads. + +Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). + +Members: + +- void \*buf and size\_t buf\_len + + The address and length of the buffer to be filled. + +### `__wasi_linkcount_t` (`uint32_t`) + +Number of hard links to an inode. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_lookupflags_t` (`uint32_t` bitfield) + +Flags determining the method of how paths are resolved. + +Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** + + As long as the resolved path corresponds to a symbolic + link, it is expanded. + +### `__wasi_oflags_t` (`uint16_t` bitfield) + +Open flags used by [`__wasi_path_open()`](#path_open). + +Used by [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_O_CREAT`** + + Create file if it does not exist. + +- **`__WASI_O_DIRECTORY`** + + Fail if not a directory. + +- **`__WASI_O_EXCL`** + + Fail if file already exists. + +- **`__WASI_O_TRUNC`** + + Truncate file to size 0. + +### `__wasi_riflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_PEEK`** + + Returns the message without removing it from the + socket's receive queue. + +- **`__WASI_SOCK_RECV_WAITALL`** + + On byte-stream sockets, block until the full amount + of data can be returned. + +### `__wasi_rights_t` (`uint64_t` bitfield) + +File descriptor rights, determining which actions may be +performed. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_RIGHT_FD_DATASYNC`** + + The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_READ`** + + The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke + [`__wasi_fd_pread()`](#fd_pread). + +- **`__WASI_RIGHT_FD_SEEK`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies + [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). + +- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** + + The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). + +- **`__WASI_RIGHT_FD_SYNC`** + + The right to invoke [`__wasi_fd_sync()`](#fd_sync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and + [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_TELL`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the + file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with + offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). + +- **`__WASI_RIGHT_FD_WRITE`** + + The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to + invoke [`__wasi_fd_pwrite()`](#fd_pwrite). + +- **`__WASI_RIGHT_FD_ADVISE`** + + The right to invoke [`__wasi_fd_advise()`](#fd_advise). + +- **`__WASI_RIGHT_FD_ALLOCATE`** + + The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). + +- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** + + The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). + +- **`__WASI_RIGHT_PATH_CREATE_FILE`** + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke + [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). + +- **`__WASI_RIGHT_PATH_LINK_SOURCE`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_LINK_TARGET`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_OPEN`** + + The right to invoke [`__wasi_path_open()`](#path_open). + +- **`__WASI_RIGHT_FD_READDIR`** + + The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). + +- **`__WASI_RIGHT_PATH_READLINK`** + + The right to invoke [`__wasi_path_readlink()`](#path_readlink). + +- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_RENAME_TARGET`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_FILESTAT_GET`** + + The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** + + The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +- **`__WASI_RIGHT_FD_FILESTAT_GET`** + + The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** + + The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). + +- **`__WASI_RIGHT_PATH_SYMLINK`** + + The right to invoke [`__wasi_path_symlink()`](#path_symlink). + +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + +- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** + + The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). + +- **`__WASI_RIGHT_POLL_FD_READWRITE`** + + If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). + + If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +- **`__WASI_RIGHT_SOCK_SHUTDOWN`** + + The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). + +### `__wasi_roflags_t` (`uint16_t` bitfield) + +Flags returned by [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** + + Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been + truncated. + +### `__wasi_sdflags_t` (`uint8_t` bitfield) + +Which channels on a socket to shut down. + +Used by [`__wasi_sock_shutdown()`](#sock_shutdown). + +Possible values: + +- **`__WASI_SHUT_RD`** + + Disables further receive operations. + +- **`__WASI_SHUT_WR`** + + Disables further send operations. + +### `__wasi_siflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +Used by [`__wasi_sock_send()`](#sock_send). + +### `__wasi_signal_t` (`uint8_t`) + +Signal condition. + +Used by [`__wasi_proc_raise()`](#proc_raise). + +Possible values: + +- **`__WASI_SIGABRT`** + + Process abort signal. + + Action: Terminates the process. + +- **`__WASI_SIGALRM`** + + Alarm clock. + + Action: Terminates the process. + +- **`__WASI_SIGBUS`** + + Access to an undefined portion of a memory object. + + Action: Terminates the process. + +- **`__WASI_SIGCHLD`** + + Child process terminated, stopped, or continued. + + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGFPE`** + + Erroneous arithmetic operation. + + Action: Terminates the process. + +- **`__WASI_SIGHUP`** + + Hangup. + + Action: Terminates the process. + +- **`__WASI_SIGILL`** + + Illegal instruction. + + Action: Terminates the process. + +- **`__WASI_SIGINT`** + + Terminate interrupt signal. + + Action: Terminates the process. + +- **`__WASI_SIGKILL`** + + Kill. + + Action: Terminates the process. + +- **`__WASI_SIGPIPE`** + + Write on a pipe with no one to read it. + + Action: Ignored. + +- **`__WASI_SIGQUIT`** + + Terminal quit signal. + + Action: Terminates the process. + +- **`__WASI_SIGSEGV`** + + Invalid memory reference. + + Action: Terminates the process. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. + +- **`__WASI_SIGSYS`** + + Bad system call. + + Action: Terminates the process. + +- **`__WASI_SIGTERM`** + + Termination signal. + + Action: Terminates the process. + +- **`__WASI_SIGTRAP`** + + Trace/breakpoint trap. + + Action: Terminates the process. + +- **`__WASI_SIGTSTP`** + + Terminal stop signal. + + Action: Stops executing. + +- **`__WASI_SIGTTIN`** + + Background process attempting read. + + Action: Stops executing. + +- **`__WASI_SIGTTOU`** + + Background process attempting write. + + Action: Stops executing. + +- **`__WASI_SIGURG`** + + High bandwidth data is available at a socket. + + Action: Ignored. + +- **`__WASI_SIGUSR1`** + + User-defined signal 1. + + Action: Terminates the process. + +- **`__WASI_SIGUSR2`** + + User-defined signal 2. + + Action: Terminates the process. + +- **`__WASI_SIGVTALRM`** + + Virtual timer expired. + + Action: Terminates the process. + +- **`__WASI_SIGXCPU`** + + CPU time limit exceeded. + + Action: Terminates the process. + +- **`__WASI_SIGXFSZ`** + + File size limit exceeded. + + Action: Terminates the process. + +### `__wasi_subclockflags_t` (`uint16_t` bitfield) + +Flags determining how to interpret the timestamp provided in +[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +Used by [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** + + If set, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp + of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + + If clear, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current + time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + +### `__wasi_subscription_t` (`struct`) + +Subscription to an event. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that is attached to the subscription in the + implementation and returned through + [`__wasi_event_t::userdata`](#event.userdata). + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event to which to subscribe. + +- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): + + - **`u.clock`** + + - [\_\_wasi\_userdata\_t](#userdata) identifier + + The user-defined unique identifier of the clock. + + - [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock against which to compare the timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) timeout + + The absolute or relative timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) precision + + The amount of time that the implementation may wait additionally + to coalesce with other events. + + - [\_\_wasi\_subclockflags\_t](#subclockflags) flags + + Flags specifying whether the timeout is absolute or relative. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor on which to wait for it to become ready + for reading or writing. + +### `__wasi_timestamp_t` (`uint64_t`) + +Timestamp in nanoseconds. + +Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +### `__wasi_userdata_t` (`uint64_t`) + +User-provided value that may be attached to objects that is +retained when extracted from the implementation. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +### `__wasi_whence_t` (`uint8_t`) + +The position relative to which to set the offset of the file descriptor. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +Possible values: + +- **`__WASI_WHENCE_CUR`** + + Seek relative to current position. + +- **`__WASI_WHENCE_END`** + + Seek relative to end-of-file. + +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + diff --git a/proposals/random/docs/WASI-overview.md b/proposals/random/docs/WASI-overview.md new file mode 100644 index 000000000..faabc2eff --- /dev/null +++ b/proposals/random/docs/WASI-overview.md @@ -0,0 +1,147 @@ +# WASI: WebAssembly System Interface + +WebAssembly System Interface, or WASI, is a family of APIs for WebAssembly +being designed and standardized through the WASI Subgroup of the W3C +WebAssembly Commmunity Group. Initially, the focus is on system-oriented APIs, +covering files, networking, and a few other things. Additional domains are +expected to be added in the future. + +WebAssembly is designed to run well on the Web, however it's +[not limited to the Web](https://github.com/WebAssembly/design/blob/master/NonWeb.md). +The core WebAssembly language is independent of its surrounding +environment, and WebAssembly interacts with the outside world +exclusively through APIs. On the Web, it naturally uses the +existing Web APIs provided by browsers. + +WASI is an effort to provide general-purpose APIs for supporting +non-Web use cases. The focus is on designing clean and portable APIs which +can be implemented on multiple platforms by multiple engines, and which +don't depend on browser functionality (although they still can run in +browsers; see below). + +## Capability-Oriented + +WASI's core design follows +[CloudABI](https://cloudabi.org/)'s +(and in turn +[Capsicum](https://www.cl.cam.ac.uk/research/security/capsicum/))'s concept of +[capability-based security](https://en.wikipedia.org/wiki/Capability-based_security), +which fits well into WebAssembly's sandbox model. Files, +directories, network sockets, and other resources are identified +by UNIX-like file descriptors, which are indices into external +tables whose elements represent capabilities. Similar to how core +WebAssembly provides no ability to access the outside world without +calling imported functions, WASI APIs provide no ability to access +the outside world without an associated capability. + +For example, instead of a typical +[open](http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html) +system call, WASI provides an +[openat](https://linux.die.net/man/2/openat)-like +system call, requiring the calling process to have a file +descriptor for a directory that contains the file, representing the +capability to open files within that directory. (These ideas are +common in capability-based systems.) + +However, the WASI libc implementation still does provide an +implementation of open, by taking the approach of +[libpreopen](https://github.com/musec/libpreopen). +Programs may be granted capabilities for directories on launch, and +the library maintains a mapping from their filesystem path to the +file descriptor indices representing the associated capabilities. +When a program calls open, they look up the file name in the map, +and automatically supply the appropriate directory capability. It +also means WASI doesn't require the use of CloudABI's `program_main` +construct. This eases porting of existing applications without +compromising the underlying capability model. See the diagram below +for how libpreopen fits into the overall software architecture. + +WASI also automatically provides file descriptors for standard +input and output, and WASI libc provides a normal `printf`. In +general, WASI is aiming to support a fairly full-featured libc +implementation, with the current implementation work being based on +[musl](http://www.musl-libc.org/). + +## Portable System Interface for WebAssembly + +WASI is being designed from the ground up for WebAssembly, with +sandboxing, portability, and API tidiness in mind, making natural +use of WebAssembly features such as i64, import functions with +descriptive names and typed arguments, and aiming to avoid being +tied to a particular implementation. + +We often call functions in these APIs "syscalls", because they +serve an analogous purpose to system calls in native executables. +However, they're just functions that are provided by the +surrounding environment that can do I/O on behalf of the program. + +WASI is starting with a basic POSIX-like set of syscall functions, +though adapted to suit the needs of WebAssembly, such as in +excluding functions such as fork and exec which aren't easily +implementable in some of the places people want to run WebAssembly, +and such as in adopting a capabilities-oriented design. + +And, as WebAssembly grows support for +[host bindings](https://github.com/webassembly/host-bindings) +and related features, capabilities can evolve to being represented +as opaque, unforgeable +[reference typed values](https://github.com/WebAssembly/reference-types), +which can allow for finer-grained control over capabilities, and +make the API more accessible beyond the C-like languages that +POSIX-style APIs are typically aimed at. + +## WASI Software Architecture + +To facilitate use of the WASI API, a libc +implementation called WASI libc is being developed, which presents +a relatively normal musl-based libc interface, implemented on top +of a libpreopen-like layer and a system call wrapper layer (derived +from the "bottom half" of +[cloudlibc](https://github.com/NuxiNL/cloudlibc)). +The system call wrapper layer makes calls to the actual WASI +implementation, which may map these calls to whatever the +surrounding environment provides, whether it's native OS resources, +JS runtime resources, or something else entirely. + +[This libc is part of a "sysroot"](https://github.com/CraneStation/wasi-sysroot), +which is a directory containing compiled libraries and C/C++ header +files providing standard library and related facilities laid out in +a standard way to allow compilers to use it directly. + +With the [LLVM 8.0](http://llvm.org/) +release, the WebAssembly backend is now officially stable, but LLVM +itself doesn't provide a libc - a standard C library, which you +need to build anything with clang. This is what the WASI-enabled +sysroot provides, so the combination of clang in LLVM 8.0 and the +new WASI-enabled sysroot provides usable Rust and C compilation +environments that can produce executable wasm programs. + +![WASI software architecture diagram](wasi-software-architecture.png "WASI software architecture diagram") + +## Future Evolution + +The first version of WASI is relatively simple, small, and +POSIX-like in order to make it easy for implementers to prototype +it and port existing code to it, making it a good way to start +building momentum and allow us to start getting feedback based on +experience. + +Future versions will change based on experience +and feedback with the first version, and add features to address +new use cases. They may also see significant architectural +changes. Because all of the APIs are accessed through regular +WebAssembly imports, APIs can be implemented either by wasm +runtimes directly or by other WebAssembly modules. So if WASI APIs +change significantly, the old APIs can be implemented as a library +on top of the new APIs. + +## Can WASI apps run on the Web? + +While this isn't the initial focus, it's possible to implement WASI +APIs from JavaScript, since they're just regular WebAssembly imports, +so it's possible to run WASI modules on the Web. + +And in the future, it's possible that +[builtin modules](https://github.com/tc39/ecma262/issues/395) +could take these ideas even further allowing easier and tighter +integration between .wasm modules importing WASI and the Web. diff --git a/proposals/random/docs/wasi-software-architecture.png b/proposals/random/docs/wasi-software-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..6cb8345cc43cba2410d05ee1db06e929ba335fcb GIT binary patch literal 28267 zcmbTdbySpH)HZI?DP1DnGBk*QG$P&I9Rov3i_{PUN;fj}P$JzDf+CH8zyQL~Eh+uG z!RL8??;r2_*0;XpTCQ35xzD-xIcJ}JUHdwlNHrCCTr5hgJ9qBjzEqIWxO3+o_|BcX zZ!pk+C&YL={&((xd0)y%YQ3J`%EI&~UcT(ng%Lb?fkC$#@3fPE41REr@c|COlH7~L z4+`q)Y6R-)>THX_2KiVzr4xB}>h`j)IM^Q_opD&S4!?!J{-E*jq2xo+Yaix=&hMb+ zDaMT1wAt13)8{!>-aBdD^CxNZej?PNKcg{p<$9LjpQ1{AlM?51vP}1ke7$xezOR5kAz&k6@4c>j=UEvCII`o*@X|VUZoUTFZ-*F z1Py1uBAw4ix=l*=1q21?`0OvABo2rkYiNC4Uss+abonlAY%}^t z%vKS7lbo_z5Z^+-AO>CNpQIl@Vh9~1Yihwue_BBf+|H*_4+Uj?2u!S=8Z}tuoW&p5 zI~jFi9oZ81W`+_-DP)X_4Ni#)@SSgK4y7NBVebYG-b;fUe9#UGyik*TxvR?1?Afk; zsV~cGOBYJ8=t$37eUM!u>VrJFe!YF4w2gTAetE;m`_@RYgnC4KrLPSSFsi@Q>e^aa z;$i>LuuVi5m+YxdrSoh74wcB&SS(@Iu2vA(ydMHsTSK105ug=lK2;y{NnLAZW17VK zy8hMV*CN7Mn?Y#|y8J1tWil@6=T1u}Td!ZJUyWo1>9@1+BF;DYU4YM|%PQ(jJgBj? zG*?u=8mFBso3E6g({ok?I@;62;rsj1eeKdSRHXUD%R$EVi`ld9)n|9j!7@NQ8~qrs zdt3J%c&>pR;^al+!9qLjL4dw>(DD{G_km%EXYDVYsP7yBfzB3YR;Sm=8xwxC>Jv_{ zmCtEU&`zK|--Rf}y+%{EMZKuMaYhnIK@Bzd+)M)YB3GrGKG(d3H1E{;C7CcSEB2~n z;ZZS|Qq?4|i zHXat%_uw)=%vm+{Y_*6{v*@eTKd5|eLlLf}-wa9kT&>IEHb3+FP?g0M z|DsqO9FKM62RDF~g2T6$cB?KwY2({{Uo~lyNefsPm_Fur?A@q4e=JJ8t8{kXodvM6 z_YLNPP}@uy5gM*szF(Z)z;KL&bCV6&%;BTcQYf3E zj!7_cDql6qa*ZVO{#ECm$Ij>xYe?9^=c`S**hw6ct6rWkimuf61(pZ;c(rx*YRd?x=<;nfUC>La(+=ySjdQ|LbZbZi)|))49gA)y}O<& zxujD{c2cQQmWX^w2~{pli2F?XtJb1+zeUzv24fE!JEeTJiqPf2*(w?)zIs( z$WZeTdxK9GPwRV>Q~AuNs|J28Y_YPl8bms>Tv`hAy_aa#9nW zzhemNIe$qrLQ^`)rhgiC!jnQDO5m3IBc^O!oy6t=mJw*wnyIXOD73Nl5~9%JX;}}P z-s7GIx@jAy-Ehkf4qD_wsMZ3Adu8TZ3z^x@G)+P&42aAZ#zW^+pN=8UCsbhwdBWWI zFoc-MSttfoKNb#V490Y(B#5iiq13pEi`9iT7P$@C1{Kbc3ps^2@}%==t&cVcm^Pd=o`%`-)&tXA{JO2Ze`l3W ztjY3?T^y6{5nVj964rEWBr8=Yl(bHg!7su*6_=d6#`~bBA-9|Y?rbw64pI4IO3s7P z`eqrSK`t-ii`5mWg0&MvH8|9OyK}eSQB`+CeMC%VgxdF9RJ8}!hSYgx2@ezGPA(qW zQ-0bh#<4Sd;<=&&1PW@3sneWl*Tg~^4H$+JWj}U51_EPbP-#c$PDogt1N23Q>l4KY zJF4W4*SQ0v;$0x~H0Tc>UhvvC%=fP3$+|+s8tFp zXl=Iz%L2h)TLQcjxqAc1bRPh+E5$(0zA={A^7h!uJS9I^vUJ076eW0U%Zzs>v&k$?RU-?sIXIPSk1G#!tD~+9MO(>;+ zp*daTzylZLBzG2g9y(K;1p>FIcCfTOk4fV{dbVN^O7N(YIOW8cW`mDuxIx{E0G`1D zBR^36+p=`X9w@67t$s{^;8;$>waV>F7~*@KxMzN^Fh4OiH|K^Y>W}BE3@oiAJIre?wru$=~6%CSgCn-Fpw;%58d& zvPS|C(gS-)FFVoz_;oHMk2R_XMj(X&qxxT-sPlsXPq0J&_s+6}c@tt2+^m}s?Qvm0 zmUOpPT3wHWfki3TiT$}mKey=XKX%)VPYsXW%&>j8yZP2|gT9e!+eJ3-$v%_f{05!k z<ROaP#sJ}Ku1zegCwccxVX7Q(2OE$KFR ztj$Qg!lW4osqU}#G;nDYq+)D>b&uePS_D{2KvO#j zfw2+@n2(b4$pwObd4Jm>Wr36??c4luK65Qq;(1w?nsdO_ksQD3{uS1n|T+$*f(HlrUP48U_CpoIWuCiNRG(4ZO` zoX*pH@21Ca18^LJ2Zg<#<~b*-hAl|m?s5;TryMtQLE<$ntEp})J_XO2{Ea=i5X+7= zl!Jzn;g5J{0L2wmbrH?#2er#LJZRe;;!_~lTQKE&P}y{~XRBnEW2gonP@Sp>XsFA2 z?$`Ar&7I%JJy1_|%TOHeN=P(i1;e>PjfVAVQ4|>=s#AGz$`@am$26pXl<4Q8q!>4D zu5VTB6L4o*+H`NT`mNjtg(L(O{xh4Wv{)!`t;har^NM87_RZACh(C|Nn>&RDgE9_? zN5swjhZzWGa)*1p{=`_*hj2xr%mJY$9!8^aoxZoN0s@-PV*l-$j3@EeH}V>z2g8CYO}z+_hZ z0wBx*0kB?nlCIgbiK5et1}gk3T$s!pX=boD`TCL^O5TI^9a($X75JqwI*r-&dH)QX zJO)ny`EiJd7!ObLg;-rj%zeGsA!Xy4k30>>xhHj{kQ)@BNKMO;AxusL{+%4ygHZ9$zz>2PZFLsTZkTpX$+Wny=jTo(%S^3d(d@eQJzviXEE+aExvAO>-J*`BWiu zq>ZUBY_wIr%`HAdlT(SmPLsFr=^Z45jX+LW#=rtaBoH!cgkpw+e?Fe+ zEc^VNZgj~JCHVT!nq_R{wYh`Yba!S3C;=q5Po25LsGGEyX)d*_Ksh}TiNfMzIgW-> z;H0I!?`+x^Sup8(66NK%Uu)(^u1@~aQoDp30lf`~!wnDB+;ZoE-Ea_6H^xGRY&0ZO z3N?;BKp2^W&ECl51({L^HM-w}>j>+ns%UvGQX05PSfRq*Bc|e0q6hCTB34sBwI-k z3?)d@e%Kd|^`6nYM^*+cz#2)g5I+NrbpOJem+KG-kv>8|Qb~{;NEQfKj_9GL?Sy*w zPZ3E$@Y;hn+pe6cf`nrEH=YheJJd>DFa30MhY^(hc^*XCO10md?Li(o0|Rp%8SEU^ z8%+1Ulsv#3xl~NqPY>6E8s%1pBfmddg(5U+EFEJZL?Z%?Q6#BSx~D`%9Xv5(li;{V(Wu}V9-Iqp4M7fAL*=O}B%N(3$mo^R7}Fhlw8U zDJ%rR$>f{92M+*XexI+?Gh>$JpEaQ~Ll%F=K{%4#f-4ZG|NHkhaH?MsA-D~nSw6gJ z_~#Mv-#9EpDFguVO{fOo_V)KJDE|*whUD2H{|UD6o8PzKI?|y2|1bd8>)PMts)@2f z$U>zw@mB!t55A|#XEj$`#4*093aF}B`zM0 zU-o8;Yu|HOt}SnV?NTf_LPfi)lkI;hW<7;K=jYQkGAT)GAe+0){EI#rqOCQ{9Lq88 zs}AAYw3PubG$kMQe>HYLU?2F*Wz_WVTWR*2hGH^}M|1Lak6FKyH&k=CD3un)JKH}f64^X!SZDBFrU2JAYcCu0A$LWeA50A>-UYpi0g`&G~|n$NX%FR z9JgR;e)Poguy&FVo_x z!TManxB6P3l|WYirK-zx;o-V&`S9)M4HZbf#uxqM(zaO6;h5U^qJd1(=^J3ztd|^K+ZdAG`d*74Oux{h-HXl4fFBypFNZ(zC zh?BHmN~6bPRhlf;#|4vi^9wFc{);^4Z$CPNB{8vFoK1hW>*)XvVf5(_vvbZ*+Ckmy zKmI$*uWGD+a<7aVHABW0BrU7BeD}O|2}^-ASG)N!C5TdJHj_q+gf0L*q*iy_p{vPI zOF2b6qIA04Atmx#^pDB;4-SP0eT2!6_Gpk%B?ZWK=IDA;YZiWupI85$3GIgF_H47F zn6L3sqyRZ^JUE`7FutLm)82aF3e;G%smvpf@p@j?M0W9}^5O8tJgxybSJWsuiyRAB z9)AG$Ds7eH5xAe}OOd_tN)W zHkQyZ`%R1H^Q*HmFKV1#DIyy-luiK^MUY%#r$>SgM*wP^0H7e0O#{ZPA~HfJ5%EY@4t2jsj#{de0vKCA>=zwCXvJ2 z#6&$j@+e?`l|1kH<4HHj7GL~#3+Y2Xm1_a}X{7;HEEKc+FEg|%uB%;bjlh2YN@zvL zMMuNJbF=BCHJZ{OE?Z=$r{>#$cDO@TUX=syCs=h(Z7hR!vT(%x*dB+$tfsUFd53ms zU1ocv8zXi1!wC8Uanb^H$zhUVR zzI1A0VUWrn6Pfv?OQ<7|ld0@`fwVy8p9rk^94#Y;EUxubcV^jfC=joz`kmTAz7}G2 zGu15+cLip97}%fKIA`4kZ+?Ew&gpvmgM1x=$-4gYS}vt~>s3$|IEvbrSeZP>kXjzW zLF2oGySn^CqDyIjPiAswa*|NJ(N~(d-w-wNM0UyyiMKI>mFJ}W{*4R?tVD`ba?2Bb{MAxY`wNRKg=@xIyYkA~tSaJR!un9L@Vey zgukVldC0jBFA_`TtWk9Uiqr(;>az7enJ(sPTBz&#KB9kjej&AIE=O3rt+(n4xxfem zNjPrS6M_-GY;;&gdCbi7S;h|X@*jC7r?GV|cHI5HOuDK}Ci7fB(INPF++N_E(_OWX zEeT`iL-k+5W_-JvgnQG#^k7ZuGIk~){diaeaa05uL-TW`ga4@1K%^hweqX}7qdedp zS)BSjGlJka*t#bm5}~0LjD`A{d8v^s1SV;EufMhz6sM4yXWX<9ua5|7|4gvZG;c*~ zm*K4zS2wmf5t<*#mhCf5qtZ#5y3TW;lq zl7mnS(Juag#Y0%**)PxiFZq14;8_Oc-^9%Xg*HdH3Ad*=gf(Ce{BKC`4(KF8>HO5s zOb^+!@-liRkBXOU!`(~VsAo$(9={^H&F5y+4>F>HJ!cHoihn&Fl^bc$PsQl1+Me~7 z^uSKJN%;(m{|7(#9|`&Y&JTKE@c$z}_OSjvlNE)uzYGS{rJ;8hLh3c z%3BllW*R#3af@jXoQ6ktu-(|L!pM@vwFUYd4ZZ)8s0>fo%nc2hM7BhQ36bnKZC}++ z?*{+HI!=4!V}tAXiNT04L0JK;frsI+Y=ys|Ji(EFBYYw+*EBglvMC~XX#^eq$zb&> z-)(4XRMf7U2P>eO#;Cw0TW{*yug zx#T~V_n&kE$SMEOByqx((C%ODi8K#rT5JZRkHVEKKa#SL4rW~f}?X$oiC%NvC`nIFSj z{KA{5Bh91#x*<@XU-KU-e9s08lqR$yzilYCwD-K^%W_g5kVMDwysoI}*P$sb`_%4s z9F{WG*C2MIayteAcO^CL|Mb34Sbj6jZI6t_ApB^!W>~`6BBcZs>Q!$ikIzx zfNuS5zd6NeJ8*7r%&x zXy<5S7z&?Ls)=g79O@e%MBlU&+nPy;?DRddWU)X0a%|CFT$tr|`e?f)rq{z3siqv` z*m<;A`CG3+C-oW6s6=*Nu}#=b7Qxkf+C|O~6)7TIwFTTQj11!UzAYi?(KnJvM)@K6 zGVAri&m%k`oJj18q@nVX^C;V3zh?lH8<2=p+|7Z2_aV0~_aL*SbCiZ3oc+-9&0Adc zhErYRAgvi8a~mMnjN|pZQLMKY&B$H3K=_~+#TKoA!=?KK-|hHROC@A4cV7-K9RIsn z%*Us7UE=08AH|RF=0T+NQf;1oQkgcbu5VFCg}xRGD##q}+SWj}=ua4skY@p9 z?K^PmT-23(H*M9h7phvho@HmigKX zIOLvjSF>|d3Y|!q$Fe?xKkt0k@q^BS3852KA{~m+gZYr*sq0??k(QY319&KA}9hKh(X|hUISGQu&j6km|h02fCqodv24Tv^O}_ zR&B)fY(oj&OG&zrdUl+^hsnfLWslM!srWL9W=dwnGWjnBx&Pp4d+ZG66##j0Zs*0f z_X4S&sbm=EVO9IG-MCVrxM;X1(poui_D5)a{WVc`nNS2~NI1LlRKvFsN&mRZ$QlbL z6goqcgD&~j3Q~6}6O~D*?`i9Qn>PH(+PZ)Pl8X$=MtqPG%R3VvuCNGrcnu#Bp%CG+ zWQbQIIy+p@jf#yNQ@uPQe802BEC}?B{wxwjzt1oYsr}K=5!3Mtdf6%5L6B?kh>)xC zjBtd>lpMJJ!HH{7F}mMh=JW)hJ14p_oXf|MPmqKG3i?coYq;iHP}om7nbZCqj%Svi zhtp?uITK3rtFobkx52I|)SF7I${Zh-;g{P)B=-OfqX*}@i=5mqp57t!o?0wUM~%5? zDh{~-z^zLO$^cSwe!GZVb$AY6AWfe?wYRGA_*Gn*Ug|2$p|8G=TQ3#8v0 zh^YgvVBSVwV%%q>_ko|3r9nbEI>o+-ya1`e$KEsqVyxiL^l29f2N}^$^wxnK_NzMr zzIZOSEoS>RRSM((Zh1l|dmFJWD2(hWMD392u`M009Rwd-g&a>p*OIE}TI^2397IuG zKUtK5oeqb4ux#+1yOuU|wxnbK(7k2c{r+c)waWBVuhVM5Z^TcN8vW6T%<1(?&Hcoo z$v+gUj%9&8&j6_|k$@+}D&%4ANm&aw4>_pf?$GBgqpJRlbM`^y=iD5gO1Jtc{C)cS zOWV>~_v*3Y3sxlL+H4vr+gd#F&DfBCssVDxN=XE*MwrNv-c{aRBiKbY8h z{VVGFHoV!X3)#ADMCedBB?3GkcKjtv+--h5s?dx_)1xAK-sxih4~#)^p|Dr}$~d@^ zC^_}yQufQFTkMXh1_tO2uHY>I@Jtis_3rlR`>400bE5aAzTXV1nfb=JE!6tA&t?95SpS2k> z@0O1+(2mw>&D;0@o&zM52XuM9-97CB=kcZOcAEepUG9Vd1VN5!Op%} zw-MqK4QxDHEenCB?XJb8;~9q_)877(=QvEN&7n=gV|Zf#Gmi7T1?tgU4*&L696(Dd z1xuu4ttxL&ce6F_<6fbZ&e`s-j0$xgmc~=Dr}6!%>gZa|+O_IJE+7bz_7@&1U=#v= zR|I0(du>lNwV|U+{@V7GmR5Xk_$;LcBe)Wa%d>rY?};6X=xfz7Yu~&nsA=<+N*Ae2%FB5M@gw{WsUlxi2vzT62^HB`IdiaA zB9R&e*2@8l$Htk^UuX^DJWdpg$*Ab^Bfzh9PXTS>tejmjjRPgBKMcon~1t=s4!w4nT^3;SD zXnch8z)#zr8b(za2WV)ykZSa<MQx4Gi-m!fT71_?!8gn=eQnPdE-wvbk43H<(rp zeVzUFb!;HDF7|G;|A6v9vo2S;W8r#i59EC((usQ_+RE)P zsus}ucJiwhjtHfoq9Je9t9W{iLeVYh+h2ACrz<}v7!}bpR_L8QHOUJ z%QzQyxigk4nYN8U7}IM%cZrOP#>$i+Wpyd3S6)rpZh@&0v{+zsJ{Or>@IJQcI*RiwP`NUNPyA>q; zNwV}P7h=egCSbm3;#2^+UwwE~H{4JgRRAn1>EC_srh&vVjK8*_AOvLM zQcty0}^oIT~iJ>ipNRv!;Y=)~n}SU7ljto)b`7;)5VYGS{eKYsZLTAcNq^5Xer zv*+XfC6jNgD)uY*?FBu~!EIT{QkSr+*(hMh0>G>L+!|$`V z7)#tj8{FN7As6+ppr(!LLiqb1pPZg~JLd21cu>!*l;&buR!f?Se=+OF+i(*?_6UD# z!R#=D!>H*!37yT5b^$^ir$Swq z_-aew=f$j2Z`+75K+5%o)_a`j4Me|1AH|$UyC<~8LYerN zIeffeBZk`L`joWklY#cUyuN41zM#PVLxKIWYM>&=Tw(BwB9fw)ZI^jn0oyoq`4lp1 zE;4TCr7-4jsYBjbd(cbtbg10yIx`j%j%q5|YHB%E(ReI_^NLJwuq!ROkok)N%J68! z?4+1c9*gtjBp;OyBLTnw2~R{?s6qypS4=3Ztt>evW_CK>)myc~9`Cf4`5{~UYdl(I z!6pRA^2raCC~zxU0!G%9@3={!rpx4kAg-QB`RfccgLIvVKWsO@?q%t)D&K8mAa%4Y427c zTHs#pn&4CZd!K6>t4G;r_pWqdltWAcBkBn;*aBXvY?WV3vYCb}s+lWqm*QKM4GEG3 z!^`BXGi1aJsfhrta%J;dHIZjUh zwe_89(579?%69>#m%>q@A;ij6@JH1v!yP`rP_@?)S}6s>=6X#_CD`@ z-!Up{vb*R^*DVD7c+3^c5VADkqqnQl`~LS-f4D7yWwVb%mk#6Qhw6fQ{@>Cr4k}{? z5k4d~?ywmSyc6f25AqlpC@CKF45XHH=Fgb3vppYMmjol<*8UcR8QLxW2&z|^!;G0#5TQOaDcFkr_sA>6c~*$(Rei)^mZO6wZ08?JK%D z?`E_L7wUP}TM=_m%hO9z9d#NAx<36@L&MJ#F~9@1U`?zY(DQypKq1sjxYgs#^cPoJ ztYfVhSA6tbnz{mpm?BVL-?X{62s0ySWIa?W?(xNp}KGc`d?| zPU}Bw`N4N{S--*zK|@~@Z*n$qv@!Wep0Cffa~kuHV#HE1A160jmY}{qIP5_^=?jDW zSVF5XJo+lrlyO-;aiaU98}j||NKJrhE~cMi28u_48$L8p(0IcBgV3Hn6+6h5!1VTR ziQth%4_7L-g2{g_x|!7k?2)>Mf>R!E5K6 zC=Mv-T)#g41EZLfS0x+wwc~~p|HWX(gP1%BXM6A4!?U-wFsf;$w#p66+boLFgS>D< zS9@9VwR7Av$|6la0Sx8OT}=ytTnb~$^V-fDM|XnYH;_&UQl46Q(po2hIMW$diSRzy zn#NQjJgG*!lswxq8HcSiTtq$s43STGoIm-{{QwZFp9z!Wo)kV&Ng&d?RMozFOAQq4 z?zkUhBlIZ2hT_fMX`z^Oq3?$2c;(cw4P6 z-bMB4ztBhwBSCGojd!qX0x5+vqDVWUXi4;B{$i_ulbWrslhS?e*JYJh9t+=XEm5I| z>l{-VeF5txc2*egE2ALWzokQpZ3o+5;s)$L4LAHcwpZLe1kRQuY_e0*FQH8x)AoAh zu}Z{khtJPIDFpi7HV%5 ztD0qHzhl{K9wUo0IVQqxQGcdcVRL-*EylqVQ9eqcmJvU8(9@tj>hgnoSD)?_usWtT zjCT0sgnMHJeeQU^&SzWZKhSW|!hPZ%eNt!mDNnTi3NJFQYzH_`Kp)ysGmx5QqSdJOS0Os(O1ssha+14w}oz zX-#~{D68KxU9**cG2V}dN!LBiKQ&V$0F;Ib>bwVP>2vS z@LY6K3BiakdfBNLwnkz)FTZV`8rnny<~xsyaXG;tj))>QS@j7@c1AjZ6(*ZVpvBU_ z5-FT;Pj>3n;Nj2uv`wHO5K1YedXTO`Y%NwmDlEh|d0SBx^{*(e{x^XKE-3$(C$|DJ zP?z`rOUcCl%F72j2Rp)=kx_Anr-6sg%o|_*5{YQB} zn{$|Q>_jZ?ScKnQz6|wDr>Rxtzp6c*IZ{oSd*fQEy6irkWd*3-}ms>9*CCPG(j*haB();zwRm4yhXD{eGPKZHpY3 zTjN6YZ+&`7X7Qo+P0oQgory_!gQD!u!l7v`T>UgV0yybBynvb)@O6ISqU!06(BBe{ z`a2Xt#D~z957W5XZXnD*rmeKow&eHC89##k9b!gLmMjV!JW5E*gTL{RE`j_kBtW=- zf<`aSx_Tq*U2VGUH!X8c1NiWQdU*YlOYcLJ$a!>4;5O``BAs>62j&6fNhnoe6TT0x zax#ko;@rtr`7PvNb>f5Q^K?-UyWV;d*2YhM@$KwaN)=UVRx#p^B^;^EbL-e1!;>#` zRarzrvN}N>P;+A>2Q|@kb7|9;Rvu9_gy6D!Lg}-x^=@8sDF{sXF%I=H%MQ_?x_BMP z|EGz}T+H}f13Jj7vshoO^OmpB$$@33CvzQ;YQLiEltH*|%|%~RpGM3CQOwAgi;^>1 zO5#-q*Xg)1V#r|Q-mx%-1PVXxe+R-BmPlnZzXw~rk75|?(9^~u ziVBDx0=)$l*=QGZHZ1r<=7i;|aGd)He1JmkO{|ay)l7pls~BC3^0+{^p}Z1H@}U7% zq@&DojPrr(ysLPFH>jp(jTI*wie=I0@A471pQ@jx0=)NXZoe_lf$&5!^)X=q zpWox1*t?qJi4dZ3c;_7~ccvYQ9sHeKr@oJm`*UAE26cg2djc5fBbI;S)8{tWT3p{s z8TTBKpBCrk&6QAIhqif;gqfDy4VA4|Prv@Axk|w$dthnFPoEt_b$nOT9Ep#R9vCF~ z9!deAhfLuf1=>SGcA3l;9xzmxat6L|u}9XMkkk6xz^ujWovTwSQ{!yf#q;Mhd2A@O z15P-c{*0}Hb`m`Si=x!JN(o~{BUKz@(z=ZPi>(t2{BP0VJw-|F2^ZB?s|PScq8{bP zg7& zIyIv$?)!2LvfDo(8vg-J#2Qn&i4lw+mb6!8^8tnv{Whs*0ND`PX;>pcv?6n}MoRZ% zKuY(gw(A5}idwT`RI2>9M_4IL~Uo$HxWV|7FFL{Uz zHoQC+)iVV3jXc%|5wLa>&PuAP5C#OReg01Pikz&B1+gh3z<=73Pam*W|Xw4v}AupZ_SnL=6+sI)a~sfUx5F;+Pva*I?xKpb!bO8RDJL@@O*6( zxmkYL$p};o-&C*x>BXB!ougR9eFR=f(~wiaW3jw8I7HOzj0v@N`4{-|xxVQDb=ou9 z0XxH`3NRTt?>V~(X12tCFSCEw+s_oUSCo)+iH50Wct9>y0fGCk=G|GS{JK80=4T}g z1^%!0%`r_7)_wT%m3)8kDWG8g1y#MDHJI^ki>Aax-edn1$-S$~D;6kJX5lRVu)0b9 zm3X}Hzj05rN(|-|$GlQ6q7JPAvhVk=M6NKCT8BZqE7X!NcoOvA>(hnG4AtGWfd2i@ z$B;F_G4TAMrEhirc7#4uruw>@;d2c@7*MbGcky%tou9Dt^rflCUoiYTTYGVoR{24M zJrSdI@AbluhYW!?viof!HNfXwsvUNE{+Z|Htm&hbau3(X*wRs--e;y&-9(E=?1jp) zExFVDA}qmSbh1-2gnnxj>s#q4FC+m#ikQpW>^>;W_%O8i_{&yRm#pV4f^p z9x5h)X!AKg%IgbXk{FbF4=<~XI)m?0!^Rc>nvE$rhSsSfybx-eQju{kfGr1bts82} z)I)K^UacX8VeeO{_oD{0kKWH?%8EKO1|4VSxCdCf?x#7s3Z&M&t}G?Q-G z8;k727tp{Qzp)a zJvOP_Z&Ctz%ZLvJk{)6zvo)6ps)jJc=xHiID+>n(Wu8%rz9qP~1K}S;r&coBwTo#O zM>J`UqiILePy=OJQg+i$3SoIXk0ha>eJYy3O#Gj!p;Y3!>pu7up7sRk+JGV|@|DwN z$r(dF!t#Vz@_Pi=0)dvYc-CH5- zL40k?!*1MDCEAGK;H-l7wKBl;9VsGtV6qH>Oh(*L3`j5a?8kQuX0G$=O(n)f*F$%M zFzNW6^9Lkl!f0d^G(Trr9SEkrEzU?a^l8l=67ey_p!0gTZKX3@qn`}%t$9PB`Wfov z@v+ES^T}J7m+Q$UbL{=AM^a9<(|e@TpAF6R)jn$N2@-HCUun#R+bjoB@1+n}h>rFA z?kK~}R%dj%|2y6+Q@g{|^|R^Cr0fN#USlipVNB?gT;QT#0F^#9?@2oz7vwi;iAp)@ zgw=)LjBYm#)osu!UvhrJ^-Jz*aOMHtpI0|?0(WGH`JKlnU(HDe{QK^742GC{u6;F` zyT^f?!mD3pSXUu8WB5Bv6HM6Rvz-S!Xpp(ww=Xzd1)7H3MSgJuYsc07T57zxe=iar z=n#C{!ERdW0gm)uG=j#rP*vd-M1(R=!sWNl1LD6Q$F_K?bySV8rGa&c5{!yZ{BGjS#xaZbwuYyWO9a!xoA%I9))9VZ$uEX@c-$}i z(N`D)!|OZtZ`MRARQS@lJf^;LzhUEyEHP6ni_d<4ZQq9h?Zn{OMt9% zd$swplY?p^FCF3{f1T9L3%IGzna$C;t}10}v)60oD`UN&KOb7EKepyoT|N>85pWs9 zXbiMsJs{H!a|iMhBqnhl1%)XrvQ2%8(U*lmyN9Y`1*O4B`b4P}oFUri7qa}r0t-u{ z?D_RSMFM`Srm8)#5VZ;fKj7B-c!%8E4nu-F&HdpLiE$#}$bF z49N~HwznMO!5%4MEHK*|UUYOkw{F+aNo^@DG@ZCws69n5%o^2gTx!Yf(>_qq*}0tM zU(QY9ON7PsYnoi2TlXF7R%#z#t?J00F2;6Ew=R=zpX*L=4Nv%)eM##x{$A)XW9o7I zvhN3GQbhRS&}CInPRwrff#1%WVe;8fFbPGq{vH|&=&~q=wK-7XI&*TG*EmbOZIO)2 z_()}5Gja6-2p84?)-TUE3rpV+LhlB3snF;O`uBfal$g-6Y17rtu4@j;IlM&4Ctk!H zdYxu2^tq75JY#Ql4%~2yTgP2j&lhrvI1KlQ_ILXE;iBtQ&)R;2PrG%D?4uC_aGuJc zKj3B?GgiCwlf41oM*|zoNSVxaqFA?o{KcTzjEVzDsJy!C>)e37p?kS3PhP zJs?U`w}|mb_)A9z3==qncL}8(-CT+}m1iEfhYAhP8wW&@whHh4-n~rk5MXLKUBvaC zNfTC1jZ618MQlp4Q3sy+R#Rvy~fhqu1b!_jjcV@T~EW&1EQ&*I7Cacl^LPv3o^v>{A5uEX8zF11?hvlTGkp9z<1G$`5 zNY$;E5_#|1+OB+{hNaCZ~L>q(wrB!H`}?}TvR%fl6@9^X0d0jh3j1fBm=#RtpKjlrTxtl-g_Arl*~f zc8p}~*(V_|21U);;}OF8V&*N+qw?RaWi>xl$CW%bLkSCL2eQTO&X2Hr18Xn{qaq%vT z@C0Ju7RQu5Hyr6QHvR!oCg2cwKr?;%z_KabQ*I!;?C@utZ;!ljm&dYq9b&pPqh1K@ zWT-_gK;$RyetzeDkf@h{<4!07xyem+t|=LNaBxx9eXcK#Mmt4FGn2EuF?H!e!B(|9 zsk6M*u=A;Eo*u_0(xeOHInv zdgD*u?9@7hwvbtV$nzs^AyC$8s9kRxmkh?U+tz4~ z5BE?|?=dEA_)9n^V?f`nb_@bwf4 z>SWcHX-feLYe`ryKN=Cp=Qte3Ir8vCEu&5VKMCse7`F+WXT1wHXt zI>tL>`(nRz!1u8>AVvqosta!t!S?)Z47Tc~#?S*IHeNM{g}-lfdA;^lnn*qw?9J@q zckl-lcdpf10r9VKCc<1d-a0$@btQ6M_7f!ZPRdG{n`2>YXZD$Cr^3sFF>P!6=`K5> zZyugXO=lu341s==gEUWp)xx#o&>!VE-PE2`#cV>TnLd!yl0H|qalk>SGo%@C$`q+= ztM;kH`30(JAFG6}UTPn$#|cH8gT+wjTC-n{)}rR5N&KhVa%*(=jgH!Oqy*^rgip@8 zaErEIDnidbj|j($+Q03KuQ|1A@9|jH_eO%2XS)A@clnHKGm(c4&v86uv9xwF63V!RKP2 zV@9|D?kF*7^6bp)Be{Q&Oz=?JvtQ8-sTHZu*s@B#F3CROZY%^%HhQiXSO!`*?TZ@^ zJP-J6%QM^TWY*+B`W}eb+2kVmuI=r;N7a7K-{-m04lNxt4(p)My(Yp`EuiE#{waj&_I$TwbU3-ktdE z)h0~+Qn%GDb4WEytubdE5w^Zz+Afw)`96;RSzUY5dLM)NWuIo{wr2b%QQ~I}HOsE_ zV=TJcFJHxWL>EVYL*TxA74=ls<^A_n9Es03pVZ02m-=4@w2v~-DZK&niptoaAAbAe z!YcIhsNm{!Rm5-1NKE|s?`|TSP`4)b!OcbsGwT&^CEd0WiN~4Mz2nvA=XBW>O6$hy zymz$&yysp&V`vi3B*{lSzobg3K6lf}sgu;x3&;y_G79*H-(f;Co$l~M{7c1(yUcxkc9vAv*%V)m>mb~Ytq{Y`C5njE(u<<4I(Z_TFc2v2k$xLp$Zf}oh*V-JB zQD-sP7p}>U|B=RU#_nj_mPYYqRA9o0iD@m>deU>U`yVXs7%_h=Jo+5PcanS6X4!k( zmF7#Wf>Rum{Y8n&x#&DO=eLj5Bp#JC)0lfBy|DcczfLar&@bz4rRrCuYtOVc-@MECBS5ut zCSO@$__5iqUd08?uds-+?(SM-zsGXXU2R&^z4@;dH1ilEo&0##PyATUy*KI>FY+rb zn!Rac$R_$7M&@KISXeTR&KOE%4NU_K^pl(TM0gzZS+#R)3VSofKhPf->Tvwg6`gC? zVF5l|Pa`?4U#M%cSd-qS@0VI}ky&BV4mOo?S~83!*a!_fM*5`vo_EFh{P}@6+R^tb z7caSfrD-1SHQo2(pUOZ!_@%M|r4sXA|6fN}!B$n*M3s~lk#3Nd?(UKjiA#4~x?7O$ z2I=nZZqQ42H*)Fjj_+jrkHwu91?ISq5hx~cKmneHcl;!HQ3ZegwV+eRR#N^*x67>N8sL?ge1 z@XN1a&g!bKo;`)x*+v&!RnWQm$V!@MORTz;NM{22Vn0~^8n9^omRiV3L;Uuj}UjJj= z7PWzay^yvQ@`H%1&oo+tHM+C}SoHDaBTCWd0UDDgXa_2lY zE>gAbB*}$}j?6;FJmHI|q!&=D$KJ9gCi4y~2Tl-;^V+Q);Y96bQc|kGoe?@4b*Zt9 zoDI}=q@GD36~=N(F^+j7jK#+vDo8qP9{slelzChcp&J|bGF+QY83JJr4wKIw&hoPE=Mo7 zIttE~#+C>?UB_0%hr-r`B@9iQEnPtqr|De6F1*?KXxD?JWJ7o;lLbj8<#nc=C5g9 zY+f;18pa{X$Kj{*4<_Z!!ow4ai$f04$E9}bdQH{FA+GzF7LBO_Ta!LP2g6y9k0+)Z zS{%BmO;#g{5i3JniMJ$L<+R;J@$Rb2(P?!X56aBz_;^_If2OJhdCa}9|J zIL+}kV#k#X%oWn_tx9X*fRf}j?qGPmZTmTwS&LCORr$xH6Oy#bhj7>S;n3dBQ}kt5 zn-qv8ke6N)v##dqC-v?iOAofBu78ky!Q3lgf9@-1rH1 z0`_DjM9}GBT&}uX@u3@mFS91%185A(u&`|r*#C)HoC4= zxri`=Egua3;sqBiBOlNU^E;3b5M8w{>I3;ZVP$-kJb!n=K!#8M4ix=T6F#J>-MWI! zM`G!(sOhp4I^DA%QzXWs&$JmxCX~pgmc(~u5rK~9`fob7HzAH|pRu|Os5SK>n?)C1 zuC49$2pY|QiaEk{BNOw6vC;$|^F2XBIsQ^|GNlO!@Et&{f=68I;MIJcNMdn@0}i^L z&DTygbn<0SQR#z=^EBn3nr9T8JUGm&52<;v`AEmWcuN%mZ>}n$H0?xKmKp+|YL>PB zwji57VinNWf>tr;jT10;(Yx$!KcdEd>vFQ%`^j)~barup=T+bS;P1e$oeJp*qn|v; zBNfSxO&2~n%gf|+#ZM7bq;{!^#Ox3pxJiU~Q{dNX2OnS;QBpO!l`hE=*}il9N{UiY ze68#v`L@H3Bn0F(m%i^K4~t?5_4*uE{J#t4@pT&|EyED+)ucVId2{ua=5juCX9za3 zP0d%?*uP~YVN_=HA`-y0ZTUai%}Vpp=bVVKZM}`|+t^#~xD|3vfFgkJk3+p~1LsbMp|i8Lg$tcJ^gw8{ZqPnG&onjJeYl z3-5!-7;nbdgHpG+BXKkIUOJ9h+lAA>8{n(hRHfPvsQw(foxUSV1H^8tSn70GBgpa1 z7p-u2zdBxqXS(Vu!T+z@iM`@&y-l+6vR+v?`Wyavv8yap+!`^M({}5#E&UF2>)SP0ytmN@icYB3APSHm}$wIXVD|0*yDd=my=cZ@8mc z3S*SENA3|NKYG*3JfyOXO{LXxeW=OC8-F4H=7b;OwEg57*>Co)6`J?^@OU0$ z&vEVUZvh}Ahd5I00yi*RTE=-QTyvRcaegGJ4gU;RjX?eLsO$^+(nXP%70_fEKDZRx z3qO4S_-QBX31IAW9#`P=6LUE|hJk8;NH6$jyQk~IDB)q>iM#JNlmua<@5UQ-<|JMA z!tBADYPv2Y6m3{9sU>aB2a|~1a_euKb2&bmE6Dg^Mwe=4D`kEzM0ECUIscBeeHq5f2qa%-NI(MVeU}~PJRfykKOxpFm z_0DZ3@%)yC-Xb>KD?XE?IFdxGV6oBf(AZbtY46$P3DM;%n{H8@bE{Huej(^>OvTjsLD3U-o=@s1glM595f!MX5+Q4WD95 zpO;F|E*}{uz16=_X1+9UI|TjqF(jMDp2pJK42;z$dpnmV)Y=y3p}wT6Z|ac2)VTR>JM0!;K5!cau?f)*cl2Y09#uIA9=#HZq8==gvK~ z=fXi~P#%+0iU4EV;xxrb;pZ&Fb86M&ooqMr_X8vdQV?>(@$kj+2r1i7-yH`TSSd=s z2C_@xvtZ%DtH;0aPpA^kDuUg1fCG%;P0~PPUWxkX@>HJkBXRsuY4c;pw_Px0S^(@y zkMru{R+Ca+A}Lp9y05mKtVv-NWC$_5lk@^4<1D?no^NK zU`7dTz+dQfh$WGfzzar8ExSk=oHV?Lafxx*n3et+BRr#~uyMQxlav)1L`IP>qYv?h z2O~}BE4opfkSPpeGC#-M2udnRl7zqz4sbBoM?n;hK|<M?(5j@nI!yxvbwC>vlJr_=^X`N5;(F$gyfaFPHrGS3ni-?z3oQH1My z$~EE5e1IIrvWPQEuGi=A!H<%=L8I`P=wJJNB+UGs{cpCLzvKN>{sr|aAT@CxEHD^d zRcr2XZ}p;t@EUtvNQEXNr*JT!*}<}}{1=3umr0u0u3*dYxC<~PFt+`1CO(6a4&Fob zqgSDYAHj&2>Tx)KAMcNt!YM9!3fPx=C>bd#dq;;LXkf&r{?>ohGH>qh0SC3c*H^6% z-z8f_oGxd{@ME);0sVJB&)|f%*j((nKzZ|SrK9ir$#VIWC0sEJ#q`LsFqdthsau** zUL&tsR51DhJg_td_^Bl;p@v>!+0Rlq@Vb4aat7u|w0*_zSMXFdBW z8PL6c133mTH|tqWEBi2I3#mK~8ero4JPJYEm2c3-8o8LKL)QNCsg;QopO}qJIm*%v z8mzoK=f(PWM^hEB>tdZ`&>#bbkjz8rwPSHEjyAK@XbHzxfyYT5VX|X z49x?~FEjpf-;)c5(WdD1jDUxD#(&V5)JumJ<^@c9-YK09&Ks(5` zVusEa)4D`w?mb^MflA%kMMcBKK+$PAAOEDo{r;!$?hS=9WMc4M0&YCI4`XQr(lz*u z-Zv_@(OXfO{JK#=$Q1)!FTwxgTWPQw=piN=F*;CD_SvqM_WZnJhXV?T$-z-X<-EgT zhQCKcg1Rl#m4>W@k%jy3K(6{9f!@_T1MIypr+(g0?sbt;Ai0h4NS&K47jyYz{ut5w z@HQc*(Yd(Mze zc#Uv&|D!cnc+KAXmB#Ju{M=A4t%L*J537Q=kY;AL!t_URYie|z;5@{Dyf45 z%l51)^=}?CQk|7V({ub|jD+>mMtAp5ZH8@eq`4iR(C*@j401l=_qlC7M97psS4h$j zTvWv24n2fekeHaQo*(bHZpmaDQBxIwjeX$yLtp*@=BBo6IdAW&jeQHlC14=nUQGtL zgpHNqmKz48_Jvc*mUL4lTGflr)p0l^v@qhZB@14nU3|_s@gpJS4%1P zcHAMua9IRU`Qa~9PgmPeR5p38qtxT;xJ9zS@r<>|3e&d z3T*+tDoyAMdBUgEl!{&Tq`Y^yYK0{foVReF?H1OrnXDLI&a<`eO75&mafjZ|9eEX& zFjLr8%Yni9dgr@G%ow)HXHVlI1q}6NKQa)fQ7#d-v1s?t<>N@spJR7{z1hV~$hbkA zDR3LiAPTCKA5}**{IdwD+2hkz(w1UWdde#ZJRinbm z%_I=to0Kf-`Ox*aWsTyqnHc9A8t=gw!y2}h^;w60@I45?t@6@7qH}Op_F5#lS(-6^KQ-Ju%KIC-4jBf=QNd)QgLvC#W#J3r=zuGZ z6_Nvz1FY`%O9EO`E&tryE_hwuEMTEcGR*vfE)B}gt!a%IzT7wZ}85>M^O<4qc*+O+AT%EoP5;Ih34_B9Gk2T8Ot2A2{@40>UXy1>6E| z-nPRnVTV5|7!cr-qtfyCq>gb9zA4fys-q74+JHq?$NOGj&iV{HP8AEWS?k=Zw2^Al zGLEm>#`Oca$Jd;5V%L%T|%xeZGwV8gy|t*Tp-#im}{ z!W$b$X8Z}0_%nnyLo%HcniETVA8Fj4J1Hdoz?aanqi;)Cns@`DDHy5D~96g zZ)@+Yp&(wn$OKuOuWmBPX!%{Z4v_fpIW&iH6>%zaR#;xzF<(-%Wkn4_J1vwCMHrN+6v;X)$&=s4< z)mI^yIak2Rc>k>AhgN)Hs7Jp{Kraoc%(O+GRJxTy>Kv|18L>sp~zExB%#)fiqeRcE}< z4mKvgwnAABzixW3>!gV!m#W+_|`0y_YKasGj+ND zo28Voes+91{u?oS-R5VX>P*UI;ZLCg+1hG$@K)vVVy5;0&D-j)A#$0?FM<_Dva>$6i%p3ZWi&@=`h6$L#uJot%mQUJN!8RnxKk(eZz#>`0)=f~}` zI~(&=HWg!A6je$`j;dg=xT<{CVL$ElVS?8wzL)%PeiC6+di#E=17Rz7WbNT%de~5H zX1f!|xaol%qk!+dxE|N-4PC&K`N9})`ENBe(GmcO#(<40YUo86P>;Sahnf!i(w`<> z+vZFs;X@DQ4gugK+e0H3`NWj8<7AW$o$!Y+SoLATuMNEKM<0nsR2GOdHz>;q%>?&%Quwx?i%sI49odg_>eY9R~^DZc{$E#eE^+K z7V_Cy&W2HYIrXr}Ph?(17r2KLHfYDk+D1t6D;XHTc#k04P#qwf(2m~U0@OXH6Gp3) zQ*!VlACa(}-g;HT4vbduxdG9cEc8BeBCLR~ea>Mec;gCHU7U*YOp)m+h$^Tfzf3PJ z?u}BAjxh!T@KGh03r)=LewhXX%r`SO6j`}9cV+-&J;zT77pWqZ2(VztObSE*y_GYQ z1XkK@>+?`ROA=jDvVdvaj-MJiwp=Bu%9_f4dMYCK430HcCb-ach)_P2oTC#muAr2-41DiozH0CoDQF&x_h)bikdtemqP2Kl z6G9KJ6?bnBflcY?`*xYIm?9t(NDFdS-CJOcwFxSH=#TNH?oFs_b2+&$QyY=lHtaeU zk%sS5>FXID%}zSG3tX9Rp#s3^3pZH#6t;o50}^z(6e`x6klM;rJl;7z6yY5P%VA9HR%YDgYgGd-TGAFFOe|_gKddnCG=toC2U1?}O^} z;6ud}QV%As4=25U{w$kea;p}Hw=P6Zu~)>z<*(rb^AEhJSjTzNNEE(CS)#4|FnPe} zD!1ww!5(~KcfG%ZoZRV!V-Dey(Q)O!0M8TiU_)O3L@*q!U|}%P3ZQ4ll14qfVb6|u z!N#4rAub1!1#0=hi2V(kOu)xWn)Gk0Cj|HymQEpKad@PyL;7ee%6~29BR-$38HArN zEJDyQIa`U-Rv~D?a#^SSx`f<#^v7QN7A!=E2UK8E$* zgb17JtF$~k(h>G|NHID@rQ6;*3z8<#3iSp8W|KVS%TlCCVQ z5XFmN@>{#{pC$LA|CwvDLJ5RueTiq11UdIAmX-SZl>}y(g0>g`QI*4Rp3=>El7~7y zwuGZa8{~O4k0%SbuUx}&*xoKg(!J^cH*H_&9<(%*@E>C zB36ONjrgA8ziLfZzZ*tH*;DP`x3GvxjT2-^NVRcxrQ!)t1O6{ zC^GD{Zs-s=0*96$lkE7!H6vQOVUqr_lAUosIdilLR6v$q}OTrG;++O>$teqGyyA7}Ay#9C~2cHRI`PinP^*obQdHw0?z6mEAG{%hrJglaI zV`=K0{fZ|sJwWENz^1FIy(dq6U%LiGfs{_;^-=PSf!VFTSbgJQ9KqcWu9F`;#x)!D zFLGCufKWS`&@hjlX&8Q$AcX#BwNiD)bF1sB>ukPpM*nzmsH~#rhHfT_^X9&D?=*b> za~Ge+@bG(V{OZ@6Q>O=O#?`9Ij>*P;pe-G^<@3$fy&ld_@&UqnAdxlVI36-Rlb@0D zE%+q9qHsd5`_w?*dCzyH_61Pd*3^n^h&dScJSh8*gk9#;ZS_*7Wt4dhHb&B_*Cj0a zEB*wM{(u=hRk7qWL*jW+`>^s~^zK~yq}d&Q9oHH0!^c2e-^yad2}JrWGUhqv(W34o z!-HH`EwSKv(AgBN^KErb7y$9>{+=ET>kgy`>`YMBxP`xdp=$dnEJb{ zUN<&T4G?}Q>%O|a*%5c(HLbaidLKHV{kx<80)D{Xkdk!u!_x^DhkJ+n=R;W()T)p1#%r9n@gp=?6^>35V(ew>5=&>BcCW4DDvY z!I>nwxu5JLDXfKuxY47V`jrp;cIZ3iR9#pU%t-5Pq<}2Qba29h1WS;M#5;a z?A>Y#8v)nF0_k(aLpvS}1u7kGsIny_0`)PGJv2O&hgJULXe~lX|4$u|1~sE-Uu?bQ;vK| zXM~DvCSR_j@P^h()qonnGvuG2yA}ukpjOxX{rL1>n*ob%qi!4h=^R!9L<#i<28-B) zMGlpJu;E0muN7_X$#Hs1eLBy>-74yoClyR3XUmv{(3|V_AqQnxnKaO{jSUuU8^sZ; z+pHLV1BFr#wPf&_Yi!P#OC=50fbCIP9L4Rja&E(}egwm;=x+zUkzIXN#^^owZl<7# za5=G7vF_Pw!R*5Aa*+}qDeY;GAZc3@G5T*){BgFWKx&5@DYg zZqX`diT*8yx28oW%kW=p+*#l3_|H*wEa^k#_&Lp`k6ahz zMa_}hDGo~q7jGNusfd!g!4BTinv15)x9g_Kor|WtIKSC(dVjH!E95x83mc(?FZ>`O zR?hlaVeF$^y?D^K;U^3FFV%w#7*bX5cm?0he3uEEHVO7ovN8TmO>rl*k$NY5OEYo? zeG=Mx;;_+tgW+Pjrug=Bn|F=_{cZ<)s^_*-f*r&U{+k?EzV2`{f26{6&J)Q#s5X%S z-cDd&28unL;Rgvgw z1+k!32`$&q;}DvXkTZUJezX1*p>ZU;$hl1OX-Q@g8?mVy2qqP{y9tl%nxt*&W!Uvhtk5(S;cl@q=cr zHf8oKuDojvl0p0hF+cmN%MVI*rqF-38hak0(^tvbIDXd~t7thU^rUt9himoRvpMIM zoMQHhC_(fEMkQZR&gp_D@`0ZBOh;^VvAihlknd)$Z#)d@oaBuTi#~6`aZ8%bV1>yb zUio>J8uHkjMh~Lt*0OgJ%c=4o$;}q2dQ|%QyD&tGZqd#j)a3oTjzWFJ^6Mh)BY#s? z4drm@t{Hv`m_UT}V764NvF80d3FG4_dZ?tM@|kljc@qO8*{Rr4ky#4#FUj-jb#=Wl_f0I-$>Hc#k?23 z7-{}vAm#hCG<+X4A$&9!4GMXt`MSzEpHphiN=r)C@Y4Jc=02+Aq9xnUFGsNwY=vgF zR$Hih-~<7ET6a%PT`EcXBA<`J2bvcv_cr%Bg1FTKkBC(1%#n<>aSF4Rh*btx$RIShdd)Ij93OZ|UAMqy`VQj9G_-kf6d& zu!V81Kqar8i~4oLv24f#Un58pify3|*8CE)~1-WJU!muyOZ};%W zMYwi)9n|s{g9SnU%va>N@;LKBOosT8+#OMl^%VupbXM;B=iHMkTMTE_s!sa7@%cM* zZizt8&;6>f3^+I1TW;F6&ZsQ;96u!Tl_9*#nxwZ^Ki(vWbaW{z_i-&hIkHjmk!8Yw zu~AVlz@mS8lQd+l8Ab#RMEsKR_KiWj?8D7pDCt@}UCi8Xs?d-?w|24*GyOjo&n;xK zMTw>V?F|X$hzAA>%r*dD&Qw&ySmB^mTn;)1xOnT~Qt8DW&yc zpZHJrOI@5>2({{>i`k;ZM4v7+H!gUue9poF*BkYOMxmj2-55gm(@x`i?R4 zl@Wb4q*(^)q!TqENr@);!)t%%A#gzhHjW1mrjy(4RJ_x_x5LeBPa0{hKI^Xi^z^IM zd|40`m(gwdpS#$ta*5pUw4aepEwf6?L-d+7&Mcf}70jK$z?OcFZGA{dS`eHpRV%^& z1qnAr$?ANW)p#nuB~Z>!Q2#;psb)8ph1gH*|6jNv)g1bAEQ{c##uOQNIXj|V9PHux z@H*)u+-mxeNn#MS0r4<1}Us!+GB=I2QC!z}zA zFK8>0?TPI;m%=1=d402<>{Qn1@MnN +2019 + + From 44d3bede5ed08cc62ef795a38085cfe36301292d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 4 Apr 2019 16:29:46 -0700 Subject: [PATCH 0009/1772] Add "liftoff" content. - Add a tentative agenda for the first meeting, though it isn't yet scheduled. - Create an intial directory structure with a few documents. --- proposals/filesystem/Charter.md | 55 + proposals/filesystem/README.md | 20 +- proposals/filesystem/design/WASI-core.md | 2315 +++++++++++++++++ proposals/filesystem/docs/WASI-overview.md | 147 ++ .../docs/wasi-software-architecture.png | Bin 0 -> 28267 bytes .../filesystem/meetings/2019/WASI-liftoff.md | 64 + proposals/filesystem/meetings/README.md | 15 + 7 files changed, 2610 insertions(+), 6 deletions(-) create mode 100644 proposals/filesystem/Charter.md create mode 100644 proposals/filesystem/design/WASI-core.md create mode 100644 proposals/filesystem/docs/WASI-overview.md create mode 100644 proposals/filesystem/docs/wasi-software-architecture.png create mode 100644 proposals/filesystem/meetings/2019/WASI-liftoff.md create mode 100644 proposals/filesystem/meetings/README.md diff --git a/proposals/filesystem/Charter.md b/proposals/filesystem/Charter.md new file mode 100644 index 000000000..b73293475 --- /dev/null +++ b/proposals/filesystem/Charter.md @@ -0,0 +1,55 @@ +# WebAssembly System Interface Subgroup Charter + +The System Interface Subgroup is a sub-organization of the +[WebAssembly Community Group](https://www.w3.org/community/webassembly/) of the W3C. +As such, it is intended that its charter align with that of the CG. In particular, +the sections of the [CG charter](https://webassembly.github.io/cg-charter/) relating to +[Community and Business Group Process](https://webassembly.github.io/cg-charter/#process), +[Contribution Mechanics](https://webassembly.github.io/cg-charter/#contrib), +[Transparency](https://webassembly.github.io/cg-charter/#transparency), and +[Decision Process](https://webassembly.github.io/cg-charter/#decision) also apply to the Subgroup. + +## Goals + +The mission of this sugbroup is to provide a forum for pre-standardization +collaboration on a system interface API for WebAssembly programs. + +## Scope + +The Subgroup will consider topics related to system interface APIs, including: + +- APIs for host filesystems, network stacks, and other resources. +- APIs for graphics, audio, input devices +- APIs for encryption, format conversion, and other transformations + (particularly where hardware accelleration may be available on some plaforms) + + +## Deliverables + +### Specifications +The Subgroup may produce several kinds of specification-related work output: +- Creation of new specifications in standards bodies or working +groups (e.g. Wasm WG or TC39) +- Creation of new specifications outside of standards bodies +(e.g. similar to the LLVM object file format documentation in Wasm tool conventions) + +### Non-normative reports +The Subgroup may produce non-normative material such as requirements +documents, recommendations, and use cases. + +### Software +The Subgroup may produce software related to Wasm system interface APIs (either +as standalone libraries, tooling, or integration of interface-related +functionality in existing CG software such as Binaryen or WABT). Capabilities may +include: +- Libraries implementing external standard APIs in terms of WebAssembly + System Interface APIs +- Tools for producing code that uses WebAssembly System Interface APIs +- Tools for implementing WebAssembly APIs +- Tools for debugging programs using WebAssembly System Interface APIs + +## Amendments to this Charter and Chair Selection + +This charter may be amended, and Subgroup Chairs may be selected by vote of the full +WebAssembly Community Group. + diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index 05d744744..4cf122cab 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -2,16 +2,24 @@ ![WASI](WASI.png) -This repository accompanies the WebAssembly WASI Subgroup, -focused on the design of the WASI, the WebAssembly System Interface. +This repository is for the WebAssembly System Interface (WASI) Subgroup of the +[WebAssembly Community Group]. Its [Charter] describes the goals, scope and +deliverables of the group. The repository may contain meeting notes, reports, +documentation, specifications and/or software produced by the group (although +larger projects may also have their own repositories). -We'll be adding more content here, but for now, check out these: +[WebAssembly Community Group](https://www.w3.org/community/webassembly/) +[Charter]: Charter.md + +We'll be adding more content here before long, but for now, check out these: - https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ - Blog post introducing WASI - - https://wasi.dev/ - Links to more information about WASI + - https://wasi.dev/ - Links to more information about WASI, including + how to get started using it. - https://github.com/WebAssembly/WASI/issues - This repo's issue tracker The issue tracker is the place to ask questions, make suggestions, and start discussions. -As a W3C CG Subgroup, we'll also be having meetings. Once we have a schedule -for those, we'll post that here also. +As a W3C CG Subgroup, we'll also be having [meetings](meetings/README.md). +A tentative agenda for the first meeting is [here](https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-liftoff.md). +Once we have a date and time, we'll post that here also. diff --git a/proposals/filesystem/design/WASI-core.md b/proposals/filesystem/design/WASI-core.md new file mode 100644 index 000000000..c4b256ad3 --- /dev/null +++ b/proposals/filesystem/design/WASI-core.md @@ -0,0 +1,2315 @@ + + +# WASI Core API + +This is the API-level documentation for WASI Core. The function names +are prefixed with "\_\_wasi\_" to reflect how they are spelled in +flat-namespace contexts, however at the wasm module level, they are +unprefixed, because they're inside a module namespace (currently +"wasi\_unstable"). + +Functions that start with `__wasi_fd_` operate on file descriptors, +while functions that start with `__wasi_path_` operate on filesystem +paths, which are relative to directory file descriptors. + +Much inspiration and content here is derived from [CloudABI] and [POSIX], +though there are also several differences from CloudABI and POSIX. For +example, WASI Core has no concept of processes in the traditional Unix +sense. While wasm linear memories have some of the aspects of processes, +and it's possible to *emulate* the full semantics of processes on top of +them, this can sometimes be unnatural and inefficient. The goal for +WASI Core is to be a WebAssembly-native API that exposes APIs that fit +well into the underlying WebAssembly platform, rather than to directly +emulate other platforms. + +This is also a work in progress, and the API here is still evolving. + +[CloudABI]: https://github.com/NuxiNL/cloudabi +[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ + +## System calls + +- [`__wasi_args_get()`](#args_get) +- [`__wasi_args_sizes_get()`](#args_sizes_get) +- [`__wasi_clock_res_get()`](#clock_res_get) +- [`__wasi_clock_time_get()`](#clock_time_get) +- [`__wasi_environ_get()`](#environ_get) +- [`__wasi_environ_sizes_get()`](#environ_sizes_get) +- [`__wasi_fd_advise()`](#fd_advise) +- [`__wasi_fd_allocate()`](#fd_allocate) +- [`__wasi_fd_close()`](#fd_close) +- [`__wasi_fd_datasync()`](#fd_datasync) +- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) +- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) +- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) +- [`__wasi_fd_filestat_get()`](#fd_filestat_get) +- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) +- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) +- [`__wasi_fd_pread()`](#fd_pread) +- [`__wasi_fd_prestat_get()`](#fd_prestat_get) +- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) +- [`__wasi_fd_pwrite()`](#fd_pwrite) +- [`__wasi_fd_read()`](#fd_read) +- [`__wasi_fd_readdir()`](#fd_readdir) +- [`__wasi_fd_renumber()`](#fd_renumber) +- [`__wasi_fd_seek()`](#fd_seek) +- [`__wasi_fd_sync()`](#fd_sync) +- [`__wasi_fd_tell()`](#fd_tell) +- [`__wasi_fd_write()`](#fd_write) +- [`__wasi_path_create_directory()`](#path_create_directory) +- [`__wasi_path_filestat_get()`](#path_filestat_get) +- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) +- [`__wasi_path_link()`](#path_link) +- [`__wasi_path_open()`](#path_open) +- [`__wasi_path_readlink()`](#path_readlink) +- [`__wasi_path_remove_directory()`](#path_remove_directory) +- [`__wasi_path_rename()`](#path_rename) +- [`__wasi_path_symlink()`](#path_symlink) +- [`__wasi_path_unlink_file()`](#path_unlink_file) +- [`__wasi_poll_oneoff()`](#poll_oneoff) +- [`__wasi_proc_exit()`](#proc_exit) +- [`__wasi_proc_raise()`](#proc_raise) +- [`__wasi_random_get()`](#random_get) +- [`__wasi_sched_yield()`](#sched_yield) +- [`__wasi_sock_recv()`](#sock_recv) +- [`__wasi_sock_send()`](#sock_send) +- [`__wasi_sock_shutdown()`](#sock_shutdown) + +### `__wasi_args_get()` + +Read command-line argument data. + +The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + +Inputs: + +- char \*\*argv + + A pointer to a buffer to write the argument pointers. + +- char \*argv\_buf + + A pointer to a buffer to write the argument string data. + +### `__wasi_args_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*argc + + The number of arguments. + +- size\_t \*argv\_buf\_size + + The size of the argument string data. + +### `__wasi_clock_res_get()` + +Return the resolution of a clock. + +Implementations are required to provide a non-zero value for supported clocks. +For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). + +Note: This is similar to `clock_getres` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the resolution. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) resolution + + The resolution of the clock. + +### `__wasi_clock_time_get()` + +Return the time value of a clock. + +Note: This is similar to `clock_gettime` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the time. + +- [\_\_wasi\_timestamp\_t](#timestamp) precision + + The maximum lag (exclusive) that the returned + time value may have, compared to its actual + value. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) time + + The time value of the clock. + +### `__wasi_environ_get()` + +Read environment variable data. + +The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + +Inputs: + +- char \*\*environ + + A pointer to a buffer to write the environment variable pointers. + +- char \*environ\_buf + + A pointer to a buffer to write the environment variable string data. + +### `__wasi_environ_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*environ\_count + + The number of environment variables. + +- size\_t \*environ\_buf\_size + + The size of the environment variable string data. + +### `__wasi_fd_advise()` + +Provide file advisory information on a file descriptor. + +Note: This is similar to `posix_fadvise` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file for which to provide file advisory information. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file to which the advisory applies. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the region to which the advisory applies. + +- [\_\_wasi\_advice\_t](#advice) advice + + The advice. + +### `__wasi_fd_allocate()` + +Force the allocation of space in a file. + +Note: This is similar to `posix_fallocate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file in which to allocate space. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset at which to start the allocation. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the area that is allocated. + +### `__wasi_fd_close()` + +Close a file descriptor. + +Note: This is similar to `close` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to close. + +### `__wasi_fd_datasync()` + +Synchronize the data of a file to disk. + +Note: This is similar to `fdatasync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file to synchronize to disk. + +### `__wasi_fd_fdstat_get()` + +Get the attributes of a file descriptor. + +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well +as additional fields. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_fdstat\_t](#fdstat) \*buf + + The buffer where the file descriptor's attributes are stored. + +### `__wasi_fd_fdstat_set_flags()` + +Adjust the flags associated with a file descriptor. + +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_fdflags\_t](#fdflags) flags + + The desired values of the file descriptor + flags. + +### `__wasi_fd_fdstat_set_rights()` + +Adjust the rights associated with a file descriptor. + +This can only be used to remove rights, and returns +[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt +to add rights. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The desired rights of the file descriptor. + +### `__wasi_fd_filestat_get()` + +Return the attributes of an open file. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_fd_filestat_set_size()` + +Adjust the size of an open file. If this increases the file's size, the extra +bytes are filled with zeros. + +Note: This is similar to `ftruncate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + A file descriptor for the file to adjust. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + The desired file size. + +### `__wasi_fd_filestat_set_times()` + +Adjust the timestamps of an open file or directory. + +Note: This is similar to `futimens` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_fd_pread()` + +Read from a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `preadv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors in which to store data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to read. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_prestat_get()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- [\_\_wasi\_prestat\_t](#prestat) \*buf + + The buffer where the description is stored. + +### `__wasi_fd_prestat_dir_name()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- const char \*path and size\_t path\_len + + A buffer into which to write the preopened directory name. + +### `__wasi_fd_pwrite()` + +Write to a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `pwritev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to write. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_fd_read()` + +Read from a file descriptor. + +Note: This is similar to `readv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors to which to store data. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_readdir()` + +Read directory entries from a directory. + +When successful, the contents of the output buffer consist of +a sequence of directory entries. Each directory entry consists +of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes +holding the name of the directory entry. + +This function fills the output buffer as much as possible, +potentially truncating the last directory entry. This allows +the caller to grow its read buffer size in case it's too small +to fit a single large directory entry, or skip the oversized +directory entry. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The directory from which to read the directory + entries. + +- void \*buf and size\_t buf\_len + + The buffer where directory entries are stored. + +- [\_\_wasi\_dircookie\_t](#dircookie) cookie + + The location within the directory to start + reading. + +Outputs: + +- size\_t bufused + + The number of bytes stored in the read buffer. + If less than the size of the read buffer, the + end of the directory has been reached. + +### `__wasi_fd_renumber()` + +Atomically replace a file descriptor by renumbering another +file descriptor. + +Due to the strong focus on thread safety, this environment +does not provide a mechanism to duplicate or renumber a file +descriptor to an arbitrary number, like dup2(). This would be +prone to race conditions, as an actual file descriptor with the +same number could be allocated by a different thread at the same +time. + +This function provides a way to atomically renumber file +descriptors, which would disappear if dup2() were to be +removed entirely. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) from + + The file descriptor to renumber. + +- [\_\_wasi\_fd\_t](#fd) to + + The file descriptor to overwrite. + +### `__wasi_fd_seek()` + +Move the offset of a file descriptor. + +Note: This is similar to `lseek` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_filedelta\_t](#filedelta) offset + + The number of bytes to move. + +- [\_\_wasi\_whence\_t](#whence) whence + + The base from which the offset is relative. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) newoffset + + The new offset of the file descriptor, + relative to the start of the file. + +### `__wasi_fd_sync()` + +Synchronize the data and metadata of a file to disk. + +Note: This is similar to `fsync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file containing the data + and metadata to synchronize to disk. + +### `__wasi_fd_tell()` + +Return the current offset of a file descriptor. + +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The current offset of the file descriptor, relative to the start of the file. + +### `__wasi_fd_write()` + +Write to a file descriptor. + +Note: This is similar to `writev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_path_create_directory()` + +Create a directory. + +Note: This is similar to `mkdirat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path at which to create the directory. + +### `__wasi_path_filestat_get()` + +Return the attributes of a file or directory. + +Note: This is similar to `stat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_path_filestat_set_times()` + +Adjust the timestamps of a file or directory. + +Note: This is similar to `utimensat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_path_link()` + +Create a hard link. + +Note: This is similar to `linkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags + + Flags determining the method of how the path is resolved. + +- const char \*old\_path and size\_t old\_path\_len + + The source path from which to link. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the hard link. + +### `__wasi_path_open()` + +Open a file or directory. + +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since +this is error-prone in multi-threaded contexts. The returned file +descriptor is guaranteed to be less than 231. + +Note: This is similar to `openat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) dirfd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The relative path of the file or directory to open, relative to + the [`dirfd`](#path_open.dirfd) directory. + +- [\_\_wasi\_oflags\_t](#oflags) o_flags + + The method by which to open the file. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The initial rights of the newly created file descriptor. The + implementation is allowed to return a file descriptor with fewer + rights than specified, if and only if those rights do not apply + to the type of file being opened. + + The *base* rights are rights that will apply to operations using + the file descriptor itself, while the *inheriting* rights are + rights that apply to file descriptors derived from it. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + The initial flags of the file descriptor. + +Outputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file that has been + opened. + +### `__wasi_path_readlink()` + +Read the contents of a symbolic link. + +Note: This is similar to `readlinkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path of the symbolic link from which to read. + +- char \*buf and size\_t buf\_len + + The buffer to which to write the contents of the symbolic link. + +Outputs: + +- size\_t bufused + + The number of bytes placed in the buffer. + +### `__wasi_path_remove_directory()` + +Remove a directory. + +Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. + +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a directory to remove. + +### `__wasi_path_rename()` + +Rename a file or directory. + +Note: This is similar to `renameat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- const char \*old\_path and size\_t old\_path\_len + + The source path of the file or directory to rename. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path to which to rename the file or directory. + +### `__wasi_path_symlink()` + +Create a symbolic link. + +Note: This is similar to `symlinkat` in POSIX. + +Inputs: + +- const char \*old\_path and size\_t old_path\_len + + The contents of the symbolic link. + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the symbolic link. + +### `__wasi_path_unlink_file()` + +Unlink a file. + +Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. + +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a file to unlink. + +### `__wasi_poll_oneoff()` + +Concurrently poll for the occurrence of a set of events. + +Inputs: + +- const [\_\_wasi\_subscription\_t](#subscription) \*in + + The events to which to subscribe. + +- [\_\_wasi\_event\_t](#event) \*out + + The events that have occurred. + +- size\_t nsubscriptions + + Both the number of subscriptions and events. + +Outputs: + +- size\_t nevents + + The number of events stored. + +### `__wasi_proc_exit()` + +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +Note: This is similar to `_Exit` in POSIX. + +Inputs: + +- [\_\_wasi\_exitcode\_t](#exitcode) rval + + The exit code returned by the process. + +Does not return. + +### `__wasi_proc_raise()` + +Send a signal to the process of the calling thread. + +Note: This is similar to `raise` in POSIX. + +Inputs: + +- [\_\_wasi\_signal\_t](#signal) sig + + The signal condition to trigger. + +### `__wasi_random_get()` + +Write high-quality random data into a buffer. + +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. + +This function may execute slowly, so when large mounts of random +data are required, it's advisable to use this function to seed a +pseudo-random number generator, rather than to provide the +random data directly. + +Inputs: + +- void \*buf and size\_t buf\_len + + The buffer to fill with random data. + +### `__wasi_sched_yield()` + +Temporarily yield execution of the calling thread. + +Note: This is similar to `sched_yield` in POSIX. + +### `__wasi_sock_recv()` + +Receive a message from a socket. + +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to receive data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len + + List of scatter/gather vectors to which to store data. + +- [\_\_wasi\_riflags\_t](#riflags) ri\_flags + + Message flags. + +Outputs: + +- size\_t ro\_datalen + + Number of bytes stored in [`ri_data`](#sock_recv.ri_data). + +- [\_\_wasi\_roflags\_t](#roflags) ro\_flags + + Message flags. + +### `__wasi_sock_send()` + +Send a message on a socket. + +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to send data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len + + List of scatter/gather vectors to which to retrieve data + +- [\_\_wasi\_siflags\_t](#siflags) si\_flags + + Message flags. + +Outputs: + +- size\_t so\_datalen + + Number of bytes transmitted. + +### `__wasi_sock_shutdown()` + +Shut down socket send and receive channels. + +Note: This is similar to `shutdown` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to shutdown channels. + +- [\_\_wasi\_sdflags\_t](#sdflags) how + + Which channels on the socket to shut down. + +## Types + +### `__wasi_advice_t` (`uint8_t`) + +File or memory access pattern advisory information. + +Used by [`__wasi_fd_advise()`](#fd_advise). + +Possible values: + +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + +- **`__WASI_ADVICE_NORMAL`** + + The application has no advice to give on its behavior + with respect to the specified data. + +- **`__WASI_ADVICE_RANDOM`** + + The application expects to access the specified data + in a random order. + +- **`__WASI_ADVICE_SEQUENTIAL`** + + The application expects to access the specified data + sequentially from lower offsets to higher offsets. + +- **`__WASI_ADVICE_WILLNEED`** + + The application expects to access the specified data + in the near future. + +### `__wasi_ciovec_t` (`struct`) + +A region of memory for scatter/gather writes. + +Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). + +Members: + +- const void \*buf and size\_t buf\_len + + The address and length of the buffer to be written. + +### `__wasi_clockid_t` (`uint32_t`) + +Identifiers for clocks. + +Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). + +Possible values: + +- **`__WASI_CLOCK_MONOTONIC`** + + The store-wide monotonic clock, which is defined as a + clock measuring real time, whose value cannot be + adjusted and which cannot have negative clock jumps. + + The epoch of this clock is undefined. The absolute + time value of this clock therefore has no meaning. + +- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** + + The CPU-time clock associated with the current + process. + +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + +- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** + + The CPU-time clock associated with the current thread. + +### `__wasi_device_t` (`uint64_t`) + +Identifier for a device containing a file system. Can be used +in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or +directory in the filesystem. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_dircookie_t` (`uint64_t`) + +A reference to the offset of a directory entry. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). + +Special values: + +- **`__WASI_DIRCOOKIE_START`** + + Permanent reference to the first directory entry + within a directory. + +### `__wasi_dirent_t` (`struct`) + +A directory entry. + +Members: + +- [\_\_wasi\_dircookie\_t](#dircookie) d\_next + + The offset of the next directory entry stored in this + directory. + +- [\_\_wasi\_inode\_t](#inode) d\_ino + + The serial number of the file referred to by this + directory entry. + +- uint32\_t d\_namlen + + The length of the name of the directory entry. + +- [\_\_wasi\_filetype\_t](#filetype) d\_type + + The type of the file referred to by this directory + entry. + +### `__wasi_errno_t` (`uint16_t`) + +Error codes returned by functions. + +Not all of these error codes are returned by the functions +provided by this API; some are used in higher-level library layers, +and others are provided merely for alignment with POSIX. + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_ESUCCESS`** + + No error occurred. System call completed successfully. + +- **`__WASI_E2BIG`** + + Argument list too long. + +- **`__WASI_EACCES`** + + Permission denied. + +- **`__WASI_EADDRINUSE`** + + Address in use. + +- **`__WASI_EADDRNOTAVAIL`** + + Address not available. + +- **`__WASI_EAFNOSUPPORT`** + + Address family not supported. + +- **`__WASI_EAGAIN`** + + Resource unavailable, or operation would block. + +- **`__WASI_EALREADY`** + + Connection already in progress. + +- **`__WASI_EBADF`** + + Bad file descriptor. + +- **`__WASI_EBADMSG`** + + Bad message. + +- **`__WASI_EBUSY`** + + Device or resource busy. + +- **`__WASI_ECANCELED`** + + Operation canceled. + +- **`__WASI_ECHILD`** + + No child processes. + +- **`__WASI_ECONNABORTED`** + + Connection aborted. + +- **`__WASI_ECONNREFUSED`** + + Connection refused. + +- **`__WASI_ECONNRESET`** + + Connection reset. + +- **`__WASI_EDEADLK`** + + Resource deadlock would occur. + +- **`__WASI_EDESTADDRREQ`** + + Destination address required. + +- **`__WASI_EDOM`** + + Mathematics argument out of domain of function. + +- **`__WASI_EDQUOT`** + + Reserved. + +- **`__WASI_EEXIST`** + + File exists. + +- **`__WASI_EFAULT`** + + Bad address. + +- **`__WASI_EFBIG`** + + File too large. + +- **`__WASI_EHOSTUNREACH`** + + Host is unreachable. + +- **`__WASI_EIDRM`** + + Identifier removed. + +- **`__WASI_EILSEQ`** + + Illegal byte sequence. + +- **`__WASI_EINPROGRESS`** + + Operation in progress. + +- **`__WASI_EINTR`** + + Interrupted function. + +- **`__WASI_EINVAL`** + + Invalid argument. + +- **`__WASI_EIO`** + + I/O error. + +- **`__WASI_EISCONN`** + + Socket is connected. + +- **`__WASI_EISDIR`** + + Is a directory. + +- **`__WASI_ELOOP`** + + Too many levels of symbolic links. + +- **`__WASI_EMFILE`** + + File descriptor value too large. + +- **`__WASI_EMLINK`** + + Too many links. + +- **`__WASI_EMSGSIZE`** + + Message too large. + +- **`__WASI_EMULTIHOP`** + + Reserved. + +- **`__WASI_ENAMETOOLONG`** + + Filename too long. + +- **`__WASI_ENETDOWN`** + + Network is down. + +- **`__WASI_ENETRESET`** + + Connection aborted by network. + +- **`__WASI_ENETUNREACH`** + + Network unreachable. + +- **`__WASI_ENFILE`** + + Too many files open in system. + +- **`__WASI_ENOBUFS`** + + No buffer space available. + +- **`__WASI_ENODEV`** + + No such device. + +- **`__WASI_ENOENT`** + + No such file or directory. + +- **`__WASI_ENOEXEC`** + + Executable file format error. + +- **`__WASI_ENOLCK`** + + No locks available. + +- **`__WASI_ENOLINK`** + + Reserved. + +- **`__WASI_ENOMEM`** + + Not enough space. + +- **`__WASI_ENOMSG`** + + No message of the desired type. + +- **`__WASI_ENOPROTOOPT`** + + Protocol not available. + +- **`__WASI_ENOSPC`** + + No space left on device. + +- **`__WASI_ENOSYS`** + + Function not supported. + +- **`__WASI_ENOTCONN`** + + The socket is not connected. + +- **`__WASI_ENOTDIR`** + + Not a directory or a symbolic link to a directory. + +- **`__WASI_ENOTEMPTY`** + + Directory not empty. + +- **`__WASI_ENOTRECOVERABLE`** + + State not recoverable. + +- **`__WASI_ENOTSOCK`** + + Not a socket. + +- **`__WASI_ENOTSUP`** + + Not supported, or operation not supported on socket. + +- **`__WASI_ENOTTY`** + + Inappropriate I/O control operation. + +- **`__WASI_ENXIO`** + + No such device or address. + +- **`__WASI_EOVERFLOW`** + + Value too large to be stored in data type. + +- **`__WASI_EOWNERDEAD`** + + Previous owner died. + +- **`__WASI_EPERM`** + + Operation not permitted. + +- **`__WASI_EPIPE`** + + Broken pipe. + +- **`__WASI_EPROTO`** + + Protocol error. + +- **`__WASI_EPROTONOSUPPORT`** + + Protocol not supported. + +- **`__WASI_EPROTOTYPE`** + + Protocol wrong type for socket. + +- **`__WASI_ERANGE`** + + Result too large. + +- **`__WASI_EROFS`** + + Read-only file system. + +- **`__WASI_ESPIPE`** + + Invalid seek. + +- **`__WASI_ESRCH`** + + No such process. + +- **`__WASI_ESTALE`** + + Reserved. + +- **`__WASI_ETIMEDOUT`** + + Connection timed out. + +- **`__WASI_ETXTBSY`** + + Text file busy. + +- **`__WASI_EXDEV`** + + Cross-device link. + +- **`__WASI_ENOTCAPABLE`** + + Extension: Capabilities insufficient. + +### `__wasi_event_t` (`struct`) + +An event that occurred. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that got attached to + [`__wasi_subscription_t::userdata`](#subscription.userdata). + +- [\_\_wasi\_errno\_t](#errno) error + + If non-zero, an error that occurred while processing + the subscription request. + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event that occurred. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_filesize\_t](#filesize) nbytes + + The number of bytes available for reading or writing. + + - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags + + The state of the file descriptor. + +### `__wasi_eventrwflags_t` (`uint16_t` bitfield) + +The state of the file descriptor subscribed to with +[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_EVENT_FD_READWRITE_HANGUP`** + + The peer of this socket has closed or disconnected. + +### `__wasi_eventtype_t` (`uint8_t`) + +Type of a subscription to an event or its occurrence. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_EVENTTYPE_CLOCK`** + + The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) + has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +- **`__WASI_EVENTTYPE_FD_READ`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + data available for reading. This event always triggers + for regular files. + +- **`__WASI_EVENTTYPE_FD_WRITE`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + capacity available for writing. This event always + triggers for regular files. + +### `__wasi_exitcode_t` (`uint32_t`) + +Exit code generated by a process when exiting. + +Used by [`__wasi_proc_exit()`](#proc_exit). + +### `__wasi_fd_t` (`uint32_t`) + +A file descriptor number. + +Used by many functions in this API. + +As in POSIX, three file descriptor numbers are provided to instances +on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, +and `STDERR_FILENO`). + +Other than these, WASI implementations are not required to allocate +new file descriptors in ascending order. + +### `__wasi_fdflags_t` (`uint16_t` bitfield) + +File descriptor flags. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_FDFLAG_APPEND`** + + Append mode: Data written to the file is always + appended to the file's end. + +- **`__WASI_FDFLAG_DSYNC`** + + Write according to synchronized I/O data integrity + completion. Only the data stored in the file is + synchronized. + +- **`__WASI_FDFLAG_NONBLOCK`** + + Non-blocking mode. + +- **`__WASI_FDFLAG_RSYNC`** + + Synchronized read I/O operations. + +- **`__WASI_FDFLAG_SYNC`** + + Write according to synchronized I/O file integrity completion. + In addition to synchronizing the data stored in the file, the + implementation may also synchronously update the file's metadata. + +### `__wasi_fdstat_t` (`struct`) + +File descriptor attributes. + +Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). + +Members: + +- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype + + File type. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + File descriptor flags. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base + + Rights that apply to this file descriptor. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + Maximum set of rights that may be installed on new + file descriptors that are created through this file + descriptor, e.g., through [`__wasi_path_open()`](#path_open). + +### `__wasi_filedelta_t` (`int64_t`) + +Relative offset within a file. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +### `__wasi_filesize_t` (`uint64_t`) + +Non-negative file size or length of a region within a file. + +Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +### `__wasi_filestat_t` (`struct`) + +File attributes. + +Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). + +Members: + +- [\_\_wasi\_device\_t](#device) st\_dev + + Device ID of device containing the file. + +- [\_\_wasi\_inode\_t](#inode) st\_ino + + File serial number. + +- [\_\_wasi\_filetype\_t](#filetype) st\_filetype + + File type. + +- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink + + Number of hard links to the file. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + For regular files, the file size in bytes. For + symbolic links, the length in bytes of the pathname + contained in the symbolic link. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + Last data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + Last data modification timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim + + Last file status change timestamp. + +### `__wasi_filetype_t` (`uint8_t`) + +The type of a file descriptor or file. + +Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). + +Possible values: + +- **`__WASI_FILETYPE_UNKNOWN`** + + The type of the file descriptor or file is unknown or + is different from any of the other types specified. + +- **`__WASI_FILETYPE_BLOCK_DEVICE`** + + The file descriptor or file refers to a block device + inode. + +- **`__WASI_FILETYPE_CHARACTER_DEVICE`** + + The file descriptor or file refers to a character + device inode. + +- **`__WASI_FILETYPE_DIRECTORY`** + + The file descriptor or file refers to a directory + inode. + +- **`__WASI_FILETYPE_REGULAR_FILE`** + + The file descriptor or file refers to a regular file + inode. + +- **`__WASI_FILETYPE_SOCKET_DGRAM`** + + The file descriptor or file refers to a datagram + socket. + +- **`__WASI_FILETYPE_SOCKET_STREAM`** + + The file descriptor or file refers to a byte-stream + socket. + +- **`__WASI_FILETYPE_SYMBOLIC_LINK`** + + The file refers to a symbolic link inode. + +### `__wasi_fstflags_t` (`uint16_t` bitfield) + +Which file time attributes to adjust. + +Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +Possible values: + +- **`__WASI_FILESTAT_SET_ATIM`** + + Adjust the last data access timestamp to the value + stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). + +- **`__WASI_FILESTAT_SET_ATIM_NOW`** + + Adjust the last data access timestamp to the time + of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +- **`__WASI_FILESTAT_SET_MTIM`** + + Adjust the last data modification timestamp to the + value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). + +- **`__WASI_FILESTAT_SET_MTIM_NOW`** + + Adjust the last data modification timestamp to the + time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +### `__wasi_inode_t` (`uint64_t`) + +File serial number that is unique within its file system. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). + +### `__wasi_iovec_t` (`struct`) + +A region of memory for scatter/gather reads. + +Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). + +Members: + +- void \*buf and size\_t buf\_len + + The address and length of the buffer to be filled. + +### `__wasi_linkcount_t` (`uint32_t`) + +Number of hard links to an inode. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_lookupflags_t` (`uint32_t` bitfield) + +Flags determining the method of how paths are resolved. + +Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** + + As long as the resolved path corresponds to a symbolic + link, it is expanded. + +### `__wasi_oflags_t` (`uint16_t` bitfield) + +Open flags used by [`__wasi_path_open()`](#path_open). + +Used by [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_O_CREAT`** + + Create file if it does not exist. + +- **`__WASI_O_DIRECTORY`** + + Fail if not a directory. + +- **`__WASI_O_EXCL`** + + Fail if file already exists. + +- **`__WASI_O_TRUNC`** + + Truncate file to size 0. + +### `__wasi_riflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_PEEK`** + + Returns the message without removing it from the + socket's receive queue. + +- **`__WASI_SOCK_RECV_WAITALL`** + + On byte-stream sockets, block until the full amount + of data can be returned. + +### `__wasi_rights_t` (`uint64_t` bitfield) + +File descriptor rights, determining which actions may be +performed. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_RIGHT_FD_DATASYNC`** + + The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_READ`** + + The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke + [`__wasi_fd_pread()`](#fd_pread). + +- **`__WASI_RIGHT_FD_SEEK`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies + [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). + +- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** + + The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). + +- **`__WASI_RIGHT_FD_SYNC`** + + The right to invoke [`__wasi_fd_sync()`](#fd_sync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and + [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_TELL`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the + file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with + offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). + +- **`__WASI_RIGHT_FD_WRITE`** + + The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to + invoke [`__wasi_fd_pwrite()`](#fd_pwrite). + +- **`__WASI_RIGHT_FD_ADVISE`** + + The right to invoke [`__wasi_fd_advise()`](#fd_advise). + +- **`__WASI_RIGHT_FD_ALLOCATE`** + + The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). + +- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** + + The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). + +- **`__WASI_RIGHT_PATH_CREATE_FILE`** + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke + [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). + +- **`__WASI_RIGHT_PATH_LINK_SOURCE`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_LINK_TARGET`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_OPEN`** + + The right to invoke [`__wasi_path_open()`](#path_open). + +- **`__WASI_RIGHT_FD_READDIR`** + + The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). + +- **`__WASI_RIGHT_PATH_READLINK`** + + The right to invoke [`__wasi_path_readlink()`](#path_readlink). + +- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_RENAME_TARGET`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_FILESTAT_GET`** + + The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** + + The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +- **`__WASI_RIGHT_FD_FILESTAT_GET`** + + The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** + + The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). + +- **`__WASI_RIGHT_PATH_SYMLINK`** + + The right to invoke [`__wasi_path_symlink()`](#path_symlink). + +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + +- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** + + The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). + +- **`__WASI_RIGHT_POLL_FD_READWRITE`** + + If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). + + If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +- **`__WASI_RIGHT_SOCK_SHUTDOWN`** + + The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). + +### `__wasi_roflags_t` (`uint16_t` bitfield) + +Flags returned by [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** + + Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been + truncated. + +### `__wasi_sdflags_t` (`uint8_t` bitfield) + +Which channels on a socket to shut down. + +Used by [`__wasi_sock_shutdown()`](#sock_shutdown). + +Possible values: + +- **`__WASI_SHUT_RD`** + + Disables further receive operations. + +- **`__WASI_SHUT_WR`** + + Disables further send operations. + +### `__wasi_siflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +Used by [`__wasi_sock_send()`](#sock_send). + +### `__wasi_signal_t` (`uint8_t`) + +Signal condition. + +Used by [`__wasi_proc_raise()`](#proc_raise). + +Possible values: + +- **`__WASI_SIGABRT`** + + Process abort signal. + + Action: Terminates the process. + +- **`__WASI_SIGALRM`** + + Alarm clock. + + Action: Terminates the process. + +- **`__WASI_SIGBUS`** + + Access to an undefined portion of a memory object. + + Action: Terminates the process. + +- **`__WASI_SIGCHLD`** + + Child process terminated, stopped, or continued. + + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGFPE`** + + Erroneous arithmetic operation. + + Action: Terminates the process. + +- **`__WASI_SIGHUP`** + + Hangup. + + Action: Terminates the process. + +- **`__WASI_SIGILL`** + + Illegal instruction. + + Action: Terminates the process. + +- **`__WASI_SIGINT`** + + Terminate interrupt signal. + + Action: Terminates the process. + +- **`__WASI_SIGKILL`** + + Kill. + + Action: Terminates the process. + +- **`__WASI_SIGPIPE`** + + Write on a pipe with no one to read it. + + Action: Ignored. + +- **`__WASI_SIGQUIT`** + + Terminal quit signal. + + Action: Terminates the process. + +- **`__WASI_SIGSEGV`** + + Invalid memory reference. + + Action: Terminates the process. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. + +- **`__WASI_SIGSYS`** + + Bad system call. + + Action: Terminates the process. + +- **`__WASI_SIGTERM`** + + Termination signal. + + Action: Terminates the process. + +- **`__WASI_SIGTRAP`** + + Trace/breakpoint trap. + + Action: Terminates the process. + +- **`__WASI_SIGTSTP`** + + Terminal stop signal. + + Action: Stops executing. + +- **`__WASI_SIGTTIN`** + + Background process attempting read. + + Action: Stops executing. + +- **`__WASI_SIGTTOU`** + + Background process attempting write. + + Action: Stops executing. + +- **`__WASI_SIGURG`** + + High bandwidth data is available at a socket. + + Action: Ignored. + +- **`__WASI_SIGUSR1`** + + User-defined signal 1. + + Action: Terminates the process. + +- **`__WASI_SIGUSR2`** + + User-defined signal 2. + + Action: Terminates the process. + +- **`__WASI_SIGVTALRM`** + + Virtual timer expired. + + Action: Terminates the process. + +- **`__WASI_SIGXCPU`** + + CPU time limit exceeded. + + Action: Terminates the process. + +- **`__WASI_SIGXFSZ`** + + File size limit exceeded. + + Action: Terminates the process. + +### `__wasi_subclockflags_t` (`uint16_t` bitfield) + +Flags determining how to interpret the timestamp provided in +[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +Used by [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** + + If set, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp + of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + + If clear, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current + time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + +### `__wasi_subscription_t` (`struct`) + +Subscription to an event. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that is attached to the subscription in the + implementation and returned through + [`__wasi_event_t::userdata`](#event.userdata). + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event to which to subscribe. + +- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): + + - **`u.clock`** + + - [\_\_wasi\_userdata\_t](#userdata) identifier + + The user-defined unique identifier of the clock. + + - [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock against which to compare the timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) timeout + + The absolute or relative timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) precision + + The amount of time that the implementation may wait additionally + to coalesce with other events. + + - [\_\_wasi\_subclockflags\_t](#subclockflags) flags + + Flags specifying whether the timeout is absolute or relative. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor on which to wait for it to become ready + for reading or writing. + +### `__wasi_timestamp_t` (`uint64_t`) + +Timestamp in nanoseconds. + +Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +### `__wasi_userdata_t` (`uint64_t`) + +User-provided value that may be attached to objects that is +retained when extracted from the implementation. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +### `__wasi_whence_t` (`uint8_t`) + +The position relative to which to set the offset of the file descriptor. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +Possible values: + +- **`__WASI_WHENCE_CUR`** + + Seek relative to current position. + +- **`__WASI_WHENCE_END`** + + Seek relative to end-of-file. + +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + diff --git a/proposals/filesystem/docs/WASI-overview.md b/proposals/filesystem/docs/WASI-overview.md new file mode 100644 index 000000000..faabc2eff --- /dev/null +++ b/proposals/filesystem/docs/WASI-overview.md @@ -0,0 +1,147 @@ +# WASI: WebAssembly System Interface + +WebAssembly System Interface, or WASI, is a family of APIs for WebAssembly +being designed and standardized through the WASI Subgroup of the W3C +WebAssembly Commmunity Group. Initially, the focus is on system-oriented APIs, +covering files, networking, and a few other things. Additional domains are +expected to be added in the future. + +WebAssembly is designed to run well on the Web, however it's +[not limited to the Web](https://github.com/WebAssembly/design/blob/master/NonWeb.md). +The core WebAssembly language is independent of its surrounding +environment, and WebAssembly interacts with the outside world +exclusively through APIs. On the Web, it naturally uses the +existing Web APIs provided by browsers. + +WASI is an effort to provide general-purpose APIs for supporting +non-Web use cases. The focus is on designing clean and portable APIs which +can be implemented on multiple platforms by multiple engines, and which +don't depend on browser functionality (although they still can run in +browsers; see below). + +## Capability-Oriented + +WASI's core design follows +[CloudABI](https://cloudabi.org/)'s +(and in turn +[Capsicum](https://www.cl.cam.ac.uk/research/security/capsicum/))'s concept of +[capability-based security](https://en.wikipedia.org/wiki/Capability-based_security), +which fits well into WebAssembly's sandbox model. Files, +directories, network sockets, and other resources are identified +by UNIX-like file descriptors, which are indices into external +tables whose elements represent capabilities. Similar to how core +WebAssembly provides no ability to access the outside world without +calling imported functions, WASI APIs provide no ability to access +the outside world without an associated capability. + +For example, instead of a typical +[open](http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html) +system call, WASI provides an +[openat](https://linux.die.net/man/2/openat)-like +system call, requiring the calling process to have a file +descriptor for a directory that contains the file, representing the +capability to open files within that directory. (These ideas are +common in capability-based systems.) + +However, the WASI libc implementation still does provide an +implementation of open, by taking the approach of +[libpreopen](https://github.com/musec/libpreopen). +Programs may be granted capabilities for directories on launch, and +the library maintains a mapping from their filesystem path to the +file descriptor indices representing the associated capabilities. +When a program calls open, they look up the file name in the map, +and automatically supply the appropriate directory capability. It +also means WASI doesn't require the use of CloudABI's `program_main` +construct. This eases porting of existing applications without +compromising the underlying capability model. See the diagram below +for how libpreopen fits into the overall software architecture. + +WASI also automatically provides file descriptors for standard +input and output, and WASI libc provides a normal `printf`. In +general, WASI is aiming to support a fairly full-featured libc +implementation, with the current implementation work being based on +[musl](http://www.musl-libc.org/). + +## Portable System Interface for WebAssembly + +WASI is being designed from the ground up for WebAssembly, with +sandboxing, portability, and API tidiness in mind, making natural +use of WebAssembly features such as i64, import functions with +descriptive names and typed arguments, and aiming to avoid being +tied to a particular implementation. + +We often call functions in these APIs "syscalls", because they +serve an analogous purpose to system calls in native executables. +However, they're just functions that are provided by the +surrounding environment that can do I/O on behalf of the program. + +WASI is starting with a basic POSIX-like set of syscall functions, +though adapted to suit the needs of WebAssembly, such as in +excluding functions such as fork and exec which aren't easily +implementable in some of the places people want to run WebAssembly, +and such as in adopting a capabilities-oriented design. + +And, as WebAssembly grows support for +[host bindings](https://github.com/webassembly/host-bindings) +and related features, capabilities can evolve to being represented +as opaque, unforgeable +[reference typed values](https://github.com/WebAssembly/reference-types), +which can allow for finer-grained control over capabilities, and +make the API more accessible beyond the C-like languages that +POSIX-style APIs are typically aimed at. + +## WASI Software Architecture + +To facilitate use of the WASI API, a libc +implementation called WASI libc is being developed, which presents +a relatively normal musl-based libc interface, implemented on top +of a libpreopen-like layer and a system call wrapper layer (derived +from the "bottom half" of +[cloudlibc](https://github.com/NuxiNL/cloudlibc)). +The system call wrapper layer makes calls to the actual WASI +implementation, which may map these calls to whatever the +surrounding environment provides, whether it's native OS resources, +JS runtime resources, or something else entirely. + +[This libc is part of a "sysroot"](https://github.com/CraneStation/wasi-sysroot), +which is a directory containing compiled libraries and C/C++ header +files providing standard library and related facilities laid out in +a standard way to allow compilers to use it directly. + +With the [LLVM 8.0](http://llvm.org/) +release, the WebAssembly backend is now officially stable, but LLVM +itself doesn't provide a libc - a standard C library, which you +need to build anything with clang. This is what the WASI-enabled +sysroot provides, so the combination of clang in LLVM 8.0 and the +new WASI-enabled sysroot provides usable Rust and C compilation +environments that can produce executable wasm programs. + +![WASI software architecture diagram](wasi-software-architecture.png "WASI software architecture diagram") + +## Future Evolution + +The first version of WASI is relatively simple, small, and +POSIX-like in order to make it easy for implementers to prototype +it and port existing code to it, making it a good way to start +building momentum and allow us to start getting feedback based on +experience. + +Future versions will change based on experience +and feedback with the first version, and add features to address +new use cases. They may also see significant architectural +changes. Because all of the APIs are accessed through regular +WebAssembly imports, APIs can be implemented either by wasm +runtimes directly or by other WebAssembly modules. So if WASI APIs +change significantly, the old APIs can be implemented as a library +on top of the new APIs. + +## Can WASI apps run on the Web? + +While this isn't the initial focus, it's possible to implement WASI +APIs from JavaScript, since they're just regular WebAssembly imports, +so it's possible to run WASI modules on the Web. + +And in the future, it's possible that +[builtin modules](https://github.com/tc39/ecma262/issues/395) +could take these ideas even further allowing easier and tighter +integration between .wasm modules importing WASI and the Web. diff --git a/proposals/filesystem/docs/wasi-software-architecture.png b/proposals/filesystem/docs/wasi-software-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..6cb8345cc43cba2410d05ee1db06e929ba335fcb GIT binary patch literal 28267 zcmbTdbySpH)HZI?DP1DnGBk*QG$P&I9Rov3i_{PUN;fj}P$JzDf+CH8zyQL~Eh+uG z!RL8??;r2_*0;XpTCQ35xzD-xIcJ}JUHdwlNHrCCTr5hgJ9qBjzEqIWxO3+o_|BcX zZ!pk+C&YL={&((xd0)y%YQ3J`%EI&~UcT(ng%Lb?fkC$#@3fPE41REr@c|COlH7~L z4+`q)Y6R-)>THX_2KiVzr4xB}>h`j)IM^Q_opD&S4!?!J{-E*jq2xo+Yaix=&hMb+ zDaMT1wAt13)8{!>-aBdD^CxNZej?PNKcg{p<$9LjpQ1{AlM?51vP}1ke7$xezOR5kAz&k6@4c>j=UEvCII`o*@X|VUZoUTFZ-*F z1Py1uBAw4ix=l*=1q21?`0OvABo2rkYiNC4Uss+abonlAY%}^t z%vKS7lbo_z5Z^+-AO>CNpQIl@Vh9~1Yihwue_BBf+|H*_4+Uj?2u!S=8Z}tuoW&p5 zI~jFi9oZ81W`+_-DP)X_4Ni#)@SSgK4y7NBVebYG-b;fUe9#UGyik*TxvR?1?Afk; zsV~cGOBYJ8=t$37eUM!u>VrJFe!YF4w2gTAetE;m`_@RYgnC4KrLPSSFsi@Q>e^aa z;$i>LuuVi5m+YxdrSoh74wcB&SS(@Iu2vA(ydMHsTSK105ug=lK2;y{NnLAZW17VK zy8hMV*CN7Mn?Y#|y8J1tWil@6=T1u}Td!ZJUyWo1>9@1+BF;DYU4YM|%PQ(jJgBj? zG*?u=8mFBso3E6g({ok?I@;62;rsj1eeKdSRHXUD%R$EVi`ld9)n|9j!7@NQ8~qrs zdt3J%c&>pR;^al+!9qLjL4dw>(DD{G_km%EXYDVYsP7yBfzB3YR;Sm=8xwxC>Jv_{ zmCtEU&`zK|--Rf}y+%{EMZKuMaYhnIK@Bzd+)M)YB3GrGKG(d3H1E{;C7CcSEB2~n z;ZZS|Qq?4|i zHXat%_uw)=%vm+{Y_*6{v*@eTKd5|eLlLf}-wa9kT&>IEHb3+FP?g0M z|DsqO9FKM62RDF~g2T6$cB?KwY2({{Uo~lyNefsPm_Fur?A@q4e=JJ8t8{kXodvM6 z_YLNPP}@uy5gM*szF(Z)z;KL&bCV6&%;BTcQYf3E zj!7_cDql6qa*ZVO{#ECm$Ij>xYe?9^=c`S**hw6ct6rWkimuf61(pZ;c(rx*YRd?x=<;nfUC>La(+=ySjdQ|LbZbZi)|))49gA)y}O<& zxujD{c2cQQmWX^w2~{pli2F?XtJb1+zeUzv24fE!JEeTJiqPf2*(w?)zIs( z$WZeTdxK9GPwRV>Q~AuNs|J28Y_YPl8bms>Tv`hAy_aa#9nW zzhemNIe$qrLQ^`)rhgiC!jnQDO5m3IBc^O!oy6t=mJw*wnyIXOD73Nl5~9%JX;}}P z-s7GIx@jAy-Ehkf4qD_wsMZ3Adu8TZ3z^x@G)+P&42aAZ#zW^+pN=8UCsbhwdBWWI zFoc-MSttfoKNb#V490Y(B#5iiq13pEi`9iT7P$@C1{Kbc3ps^2@}%==t&cVcm^Pd=o`%`-)&tXA{JO2Ze`l3W ztjY3?T^y6{5nVj964rEWBr8=Yl(bHg!7su*6_=d6#`~bBA-9|Y?rbw64pI4IO3s7P z`eqrSK`t-ii`5mWg0&MvH8|9OyK}eSQB`+CeMC%VgxdF9RJ8}!hSYgx2@ezGPA(qW zQ-0bh#<4Sd;<=&&1PW@3sneWl*Tg~^4H$+JWj}U51_EPbP-#c$PDogt1N23Q>l4KY zJF4W4*SQ0v;$0x~H0Tc>UhvvC%=fP3$+|+s8tFp zXl=Iz%L2h)TLQcjxqAc1bRPh+E5$(0zA={A^7h!uJS9I^vUJ076eW0U%Zzs>v&k$?RU-?sIXIPSk1G#!tD~+9MO(>;+ zp*daTzylZLBzG2g9y(K;1p>FIcCfTOk4fV{dbVN^O7N(YIOW8cW`mDuxIx{E0G`1D zBR^36+p=`X9w@67t$s{^;8;$>waV>F7~*@KxMzN^Fh4OiH|K^Y>W}BE3@oiAJIre?wru$=~6%CSgCn-Fpw;%58d& zvPS|C(gS-)FFVoz_;oHMk2R_XMj(X&qxxT-sPlsXPq0J&_s+6}c@tt2+^m}s?Qvm0 zmUOpPT3wHWfki3TiT$}mKey=XKX%)VPYsXW%&>j8yZP2|gT9e!+eJ3-$v%_f{05!k z<ROaP#sJ}Ku1zegCwccxVX7Q(2OE$KFR ztj$Qg!lW4osqU}#G;nDYq+)D>b&uePS_D{2KvO#j zfw2+@n2(b4$pwObd4Jm>Wr36??c4luK65Qq;(1w?nsdO_ksQD3{uS1n|T+$*f(HlrUP48U_CpoIWuCiNRG(4ZO` zoX*pH@21Ca18^LJ2Zg<#<~b*-hAl|m?s5;TryMtQLE<$ntEp})J_XO2{Ea=i5X+7= zl!Jzn;g5J{0L2wmbrH?#2er#LJZRe;;!_~lTQKE&P}y{~XRBnEW2gonP@Sp>XsFA2 z?$`Ar&7I%JJy1_|%TOHeN=P(i1;e>PjfVAVQ4|>=s#AGz$`@am$26pXl<4Q8q!>4D zu5VTB6L4o*+H`NT`mNjtg(L(O{xh4Wv{)!`t;har^NM87_RZACh(C|Nn>&RDgE9_? zN5swjhZzWGa)*1p{=`_*hj2xr%mJY$9!8^aoxZoN0s@-PV*l-$j3@EeH}V>z2g8CYO}z+_hZ z0wBx*0kB?nlCIgbiK5et1}gk3T$s!pX=boD`TCL^O5TI^9a($X75JqwI*r-&dH)QX zJO)ny`EiJd7!ObLg;-rj%zeGsA!Xy4k30>>xhHj{kQ)@BNKMO;AxusL{+%4ygHZ9$zz>2PZFLsTZkTpX$+Wny=jTo(%S^3d(d@eQJzviXEE+aExvAO>-J*`BWiu zq>ZUBY_wIr%`HAdlT(SmPLsFr=^Z45jX+LW#=rtaBoH!cgkpw+e?Fe+ zEc^VNZgj~JCHVT!nq_R{wYh`Yba!S3C;=q5Po25LsGGEyX)d*_Ksh}TiNfMzIgW-> z;H0I!?`+x^Sup8(66NK%Uu)(^u1@~aQoDp30lf`~!wnDB+;ZoE-Ea_6H^xGRY&0ZO z3N?;BKp2^W&ECl51({L^HM-w}>j>+ns%UvGQX05PSfRq*Bc|e0q6hCTB34sBwI-k z3?)d@e%Kd|^`6nYM^*+cz#2)g5I+NrbpOJem+KG-kv>8|Qb~{;NEQfKj_9GL?Sy*w zPZ3E$@Y;hn+pe6cf`nrEH=YheJJd>DFa30MhY^(hc^*XCO10md?Li(o0|Rp%8SEU^ z8%+1Ulsv#3xl~NqPY>6E8s%1pBfmddg(5U+EFEJZL?Z%?Q6#BSx~D`%9Xv5(li;{V(Wu}V9-Iqp4M7fAL*=O}B%N(3$mo^R7}Fhlw8U zDJ%rR$>f{92M+*XexI+?Gh>$JpEaQ~Ll%F=K{%4#f-4ZG|NHkhaH?MsA-D~nSw6gJ z_~#Mv-#9EpDFguVO{fOo_V)KJDE|*whUD2H{|UD6o8PzKI?|y2|1bd8>)PMts)@2f z$U>zw@mB!t55A|#XEj$`#4*093aF}B`zM0 zU-o8;Yu|HOt}SnV?NTf_LPfi)lkI;hW<7;K=jYQkGAT)GAe+0){EI#rqOCQ{9Lq88 zs}AAYw3PubG$kMQe>HYLU?2F*Wz_WVTWR*2hGH^}M|1Lak6FKyH&k=CD3un)JKH}f64^X!SZDBFrU2JAYcCu0A$LWeA50A>-UYpi0g`&G~|n$NX%FR z9JgR;e)Poguy&FVo_x z!TManxB6P3l|WYirK-zx;o-V&`S9)M4HZbf#uxqM(zaO6;h5U^qJd1(=^J3ztd|^K+ZdAG`d*74Oux{h-HXl4fFBypFNZ(zC zh?BHmN~6bPRhlf;#|4vi^9wFc{);^4Z$CPNB{8vFoK1hW>*)XvVf5(_vvbZ*+Ckmy zKmI$*uWGD+a<7aVHABW0BrU7BeD}O|2}^-ASG)N!C5TdJHj_q+gf0L*q*iy_p{vPI zOF2b6qIA04Atmx#^pDB;4-SP0eT2!6_Gpk%B?ZWK=IDA;YZiWupI85$3GIgF_H47F zn6L3sqyRZ^JUE`7FutLm)82aF3e;G%smvpf@p@j?M0W9}^5O8tJgxybSJWsuiyRAB z9)AG$Ds7eH5xAe}OOd_tN)W zHkQyZ`%R1H^Q*HmFKV1#DIyy-luiK^MUY%#r$>SgM*wP^0H7e0O#{ZPA~HfJ5%EY@4t2jsj#{de0vKCA>=zwCXvJ2 z#6&$j@+e?`l|1kH<4HHj7GL~#3+Y2Xm1_a}X{7;HEEKc+FEg|%uB%;bjlh2YN@zvL zMMuNJbF=BCHJZ{OE?Z=$r{>#$cDO@TUX=syCs=h(Z7hR!vT(%x*dB+$tfsUFd53ms zU1ocv8zXi1!wC8Uanb^H$zhUVR zzI1A0VUWrn6Pfv?OQ<7|ld0@`fwVy8p9rk^94#Y;EUxubcV^jfC=joz`kmTAz7}G2 zGu15+cLip97}%fKIA`4kZ+?Ew&gpvmgM1x=$-4gYS}vt~>s3$|IEvbrSeZP>kXjzW zLF2oGySn^CqDyIjPiAswa*|NJ(N~(d-w-wNM0UyyiMKI>mFJ}W{*4R?tVD`ba?2Bb{MAxY`wNRKg=@xIyYkA~tSaJR!un9L@Vey zgukVldC0jBFA_`TtWk9Uiqr(;>az7enJ(sPTBz&#KB9kjej&AIE=O3rt+(n4xxfem zNjPrS6M_-GY;;&gdCbi7S;h|X@*jC7r?GV|cHI5HOuDK}Ci7fB(INPF++N_E(_OWX zEeT`iL-k+5W_-JvgnQG#^k7ZuGIk~){diaeaa05uL-TW`ga4@1K%^hweqX}7qdedp zS)BSjGlJka*t#bm5}~0LjD`A{d8v^s1SV;EufMhz6sM4yXWX<9ua5|7|4gvZG;c*~ zm*K4zS2wmf5t<*#mhCf5qtZ#5y3TW;lq zl7mnS(Juag#Y0%**)PxiFZq14;8_Oc-^9%Xg*HdH3Ad*=gf(Ce{BKC`4(KF8>HO5s zOb^+!@-liRkBXOU!`(~VsAo$(9={^H&F5y+4>F>HJ!cHoihn&Fl^bc$PsQl1+Me~7 z^uSKJN%;(m{|7(#9|`&Y&JTKE@c$z}_OSjvlNE)uzYGS{rJ;8hLh3c z%3BllW*R#3af@jXoQ6ktu-(|L!pM@vwFUYd4ZZ)8s0>fo%nc2hM7BhQ36bnKZC}++ z?*{+HI!=4!V}tAXiNT04L0JK;frsI+Y=ys|Ji(EFBYYw+*EBglvMC~XX#^eq$zb&> z-)(4XRMf7U2P>eO#;Cw0TW{*yug zx#T~V_n&kE$SMEOByqx((C%ODi8K#rT5JZRkHVEKKa#SL4rW~f}?X$oiC%NvC`nIFSj z{KA{5Bh91#x*<@XU-KU-e9s08lqR$yzilYCwD-K^%W_g5kVMDwysoI}*P$sb`_%4s z9F{WG*C2MIayteAcO^CL|Mb34Sbj6jZI6t_ApB^!W>~`6BBcZs>Q!$ikIzx zfNuS5zd6NeJ8*7r%&x zXy<5S7z&?Ls)=g79O@e%MBlU&+nPy;?DRddWU)X0a%|CFT$tr|`e?f)rq{z3siqv` z*m<;A`CG3+C-oW6s6=*Nu}#=b7Qxkf+C|O~6)7TIwFTTQj11!UzAYi?(KnJvM)@K6 zGVAri&m%k`oJj18q@nVX^C;V3zh?lH8<2=p+|7Z2_aV0~_aL*SbCiZ3oc+-9&0Adc zhErYRAgvi8a~mMnjN|pZQLMKY&B$H3K=_~+#TKoA!=?KK-|hHROC@A4cV7-K9RIsn z%*Us7UE=08AH|RF=0T+NQf;1oQkgcbu5VFCg}xRGD##q}+SWj}=ua4skY@p9 z?K^PmT-23(H*M9h7phvho@HmigKX zIOLvjSF>|d3Y|!q$Fe?xKkt0k@q^BS3852KA{~m+gZYr*sq0??k(QY319&KA}9hKh(X|hUISGQu&j6km|h02fCqodv24Tv^O}_ zR&B)fY(oj&OG&zrdUl+^hsnfLWslM!srWL9W=dwnGWjnBx&Pp4d+ZG66##j0Zs*0f z_X4S&sbm=EVO9IG-MCVrxM;X1(poui_D5)a{WVc`nNS2~NI1LlRKvFsN&mRZ$QlbL z6goqcgD&~j3Q~6}6O~D*?`i9Qn>PH(+PZ)Pl8X$=MtqPG%R3VvuCNGrcnu#Bp%CG+ zWQbQIIy+p@jf#yNQ@uPQe802BEC}?B{wxwjzt1oYsr}K=5!3Mtdf6%5L6B?kh>)xC zjBtd>lpMJJ!HH{7F}mMh=JW)hJ14p_oXf|MPmqKG3i?coYq;iHP}om7nbZCqj%Svi zhtp?uITK3rtFobkx52I|)SF7I${Zh-;g{P)B=-OfqX*}@i=5mqp57t!o?0wUM~%5? zDh{~-z^zLO$^cSwe!GZVb$AY6AWfe?wYRGA_*Gn*Ug|2$p|8G=TQ3#8v0 zh^YgvVBSVwV%%q>_ko|3r9nbEI>o+-ya1`e$KEsqVyxiL^l29f2N}^$^wxnK_NzMr zzIZOSEoS>RRSM((Zh1l|dmFJWD2(hWMD392u`M009Rwd-g&a>p*OIE}TI^2397IuG zKUtK5oeqb4ux#+1yOuU|wxnbK(7k2c{r+c)waWBVuhVM5Z^TcN8vW6T%<1(?&Hcoo z$v+gUj%9&8&j6_|k$@+}D&%4ANm&aw4>_pf?$GBgqpJRlbM`^y=iD5gO1Jtc{C)cS zOWV>~_v*3Y3sxlL+H4vr+gd#F&DfBCssVDxN=XE*MwrNv-c{aRBiKbY8h z{VVGFHoV!X3)#ADMCedBB?3GkcKjtv+--h5s?dx_)1xAK-sxih4~#)^p|Dr}$~d@^ zC^_}yQufQFTkMXh1_tO2uHY>I@Jtis_3rlR`>400bE5aAzTXV1nfb=JE!6tA&t?95SpS2k> z@0O1+(2mw>&D;0@o&zM52XuM9-97CB=kcZOcAEepUG9Vd1VN5!Op%} zw-MqK4QxDHEenCB?XJb8;~9q_)877(=QvEN&7n=gV|Zf#Gmi7T1?tgU4*&L696(Dd z1xuu4ttxL&ce6F_<6fbZ&e`s-j0$xgmc~=Dr}6!%>gZa|+O_IJE+7bz_7@&1U=#v= zR|I0(du>lNwV|U+{@V7GmR5Xk_$;LcBe)Wa%d>rY?};6X=xfz7Yu~&nsA=<+N*Ae2%FB5M@gw{WsUlxi2vzT62^HB`IdiaA zB9R&e*2@8l$Htk^UuX^DJWdpg$*Ab^Bfzh9PXTS>tejmjjRPgBKMcon~1t=s4!w4nT^3;SD zXnch8z)#zr8b(za2WV)ykZSa<MQx4Gi-m!fT71_?!8gn=eQnPdE-wvbk43H<(rp zeVzUFb!;HDF7|G;|A6v9vo2S;W8r#i59EC((usQ_+RE)P zsus}ucJiwhjtHfoq9Je9t9W{iLeVYh+h2ACrz<}v7!}bpR_L8QHOUJ z%QzQyxigk4nYN8U7}IM%cZrOP#>$i+Wpyd3S6)rpZh@&0v{+zsJ{Or>@IJQcI*RiwP`NUNPyA>q; zNwV}P7h=egCSbm3;#2^+UwwE~H{4JgRRAn1>EC_srh&vVjK8*_AOvLM zQcty0}^oIT~iJ>ipNRv!;Y=)~n}SU7ljto)b`7;)5VYGS{eKYsZLTAcNq^5Xer zv*+XfC6jNgD)uY*?FBu~!EIT{QkSr+*(hMh0>G>L+!|$`V z7)#tj8{FN7As6+ppr(!LLiqb1pPZg~JLd21cu>!*l;&buR!f?Se=+OF+i(*?_6UD# z!R#=D!>H*!37yT5b^$^ir$Swq z_-aew=f$j2Z`+75K+5%o)_a`j4Me|1AH|$UyC<~8LYerN zIeffeBZk`L`joWklY#cUyuN41zM#PVLxKIWYM>&=Tw(BwB9fw)ZI^jn0oyoq`4lp1 zE;4TCr7-4jsYBjbd(cbtbg10yIx`j%j%q5|YHB%E(ReI_^NLJwuq!ROkok)N%J68! z?4+1c9*gtjBp;OyBLTnw2~R{?s6qypS4=3Ztt>evW_CK>)myc~9`Cf4`5{~UYdl(I z!6pRA^2raCC~zxU0!G%9@3={!rpx4kAg-QB`RfccgLIvVKWsO@?q%t)D&K8mAa%4Y427c zTHs#pn&4CZd!K6>t4G;r_pWqdltWAcBkBn;*aBXvY?WV3vYCb}s+lWqm*QKM4GEG3 z!^`BXGi1aJsfhrta%J;dHIZjUh zwe_89(579?%69>#m%>q@A;ij6@JH1v!yP`rP_@?)S}6s>=6X#_CD`@ z-!Up{vb*R^*DVD7c+3^c5VADkqqnQl`~LS-f4D7yWwVb%mk#6Qhw6fQ{@>Cr4k}{? z5k4d~?ywmSyc6f25AqlpC@CKF45XHH=Fgb3vppYMmjol<*8UcR8QLxW2&z|^!;G0#5TQOaDcFkr_sA>6c~*$(Rei)^mZO6wZ08?JK%D z?`E_L7wUP}TM=_m%hO9z9d#NAx<36@L&MJ#F~9@1U`?zY(DQypKq1sjxYgs#^cPoJ ztYfVhSA6tbnz{mpm?BVL-?X{62s0ySWIa?W?(xNp}KGc`d?| zPU}Bw`N4N{S--*zK|@~@Z*n$qv@!Wep0Cffa~kuHV#HE1A160jmY}{qIP5_^=?jDW zSVF5XJo+lrlyO-;aiaU98}j||NKJrhE~cMi28u_48$L8p(0IcBgV3Hn6+6h5!1VTR ziQth%4_7L-g2{g_x|!7k?2)>Mf>R!E5K6 zC=Mv-T)#g41EZLfS0x+wwc~~p|HWX(gP1%BXM6A4!?U-wFsf;$w#p66+boLFgS>D< zS9@9VwR7Av$|6la0Sx8OT}=ytTnb~$^V-fDM|XnYH;_&UQl46Q(po2hIMW$diSRzy zn#NQjJgG*!lswxq8HcSiTtq$s43STGoIm-{{QwZFp9z!Wo)kV&Ng&d?RMozFOAQq4 z?zkUhBlIZ2hT_fMX`z^Oq3?$2c;(cw4P6 z-bMB4ztBhwBSCGojd!qX0x5+vqDVWUXi4;B{$i_ulbWrslhS?e*JYJh9t+=XEm5I| z>l{-VeF5txc2*egE2ALWzokQpZ3o+5;s)$L4LAHcwpZLe1kRQuY_e0*FQH8x)AoAh zu}Z{khtJPIDFpi7HV%5 ztD0qHzhl{K9wUo0IVQqxQGcdcVRL-*EylqVQ9eqcmJvU8(9@tj>hgnoSD)?_usWtT zjCT0sgnMHJeeQU^&SzWZKhSW|!hPZ%eNt!mDNnTi3NJFQYzH_`Kp)ysGmx5QqSdJOS0Os(O1ssha+14w}oz zX-#~{D68KxU9**cG2V}dN!LBiKQ&V$0F;Ib>bwVP>2vS z@LY6K3BiakdfBNLwnkz)FTZV`8rnny<~xsyaXG;tj))>QS@j7@c1AjZ6(*ZVpvBU_ z5-FT;Pj>3n;Nj2uv`wHO5K1YedXTO`Y%NwmDlEh|d0SBx^{*(e{x^XKE-3$(C$|DJ zP?z`rOUcCl%F72j2Rp)=kx_Anr-6sg%o|_*5{YQB} zn{$|Q>_jZ?ScKnQz6|wDr>Rxtzp6c*IZ{oSd*fQEy6irkWd*3-}ms>9*CCPG(j*haB();zwRm4yhXD{eGPKZHpY3 zTjN6YZ+&`7X7Qo+P0oQgory_!gQD!u!l7v`T>UgV0yybBynvb)@O6ISqU!06(BBe{ z`a2Xt#D~z957W5XZXnD*rmeKow&eHC89##k9b!gLmMjV!JW5E*gTL{RE`j_kBtW=- zf<`aSx_Tq*U2VGUH!X8c1NiWQdU*YlOYcLJ$a!>4;5O``BAs>62j&6fNhnoe6TT0x zax#ko;@rtr`7PvNb>f5Q^K?-UyWV;d*2YhM@$KwaN)=UVRx#p^B^;^EbL-e1!;>#` zRarzrvN}N>P;+A>2Q|@kb7|9;Rvu9_gy6D!Lg}-x^=@8sDF{sXF%I=H%MQ_?x_BMP z|EGz}T+H}f13Jj7vshoO^OmpB$$@33CvzQ;YQLiEltH*|%|%~RpGM3CQOwAgi;^>1 zO5#-q*Xg)1V#r|Q-mx%-1PVXxe+R-BmPlnZzXw~rk75|?(9^~u ziVBDx0=)$l*=QGZHZ1r<=7i;|aGd)He1JmkO{|ay)l7pls~BC3^0+{^p}Z1H@}U7% zq@&DojPrr(ysLPFH>jp(jTI*wie=I0@A471pQ@jx0=)NXZoe_lf$&5!^)X=q zpWox1*t?qJi4dZ3c;_7~ccvYQ9sHeKr@oJm`*UAE26cg2djc5fBbI;S)8{tWT3p{s z8TTBKpBCrk&6QAIhqif;gqfDy4VA4|Prv@Axk|w$dthnFPoEt_b$nOT9Ep#R9vCF~ z9!deAhfLuf1=>SGcA3l;9xzmxat6L|u}9XMkkk6xz^ujWovTwSQ{!yf#q;Mhd2A@O z15P-c{*0}Hb`m`Si=x!JN(o~{BUKz@(z=ZPi>(t2{BP0VJw-|F2^ZB?s|PScq8{bP zg7& zIyIv$?)!2LvfDo(8vg-J#2Qn&i4lw+mb6!8^8tnv{Whs*0ND`PX;>pcv?6n}MoRZ% zKuY(gw(A5}idwT`RI2>9M_4IL~Uo$HxWV|7FFL{Uz zHoQC+)iVV3jXc%|5wLa>&PuAP5C#OReg01Pikz&B1+gh3z<=73Pam*W|Xw4v}AupZ_SnL=6+sI)a~sfUx5F;+Pva*I?xKpb!bO8RDJL@@O*6( zxmkYL$p};o-&C*x>BXB!ougR9eFR=f(~wiaW3jw8I7HOzj0v@N`4{-|xxVQDb=ou9 z0XxH`3NRTt?>V~(X12tCFSCEw+s_oUSCo)+iH50Wct9>y0fGCk=G|GS{JK80=4T}g z1^%!0%`r_7)_wT%m3)8kDWG8g1y#MDHJI^ki>Aax-edn1$-S$~D;6kJX5lRVu)0b9 zm3X}Hzj05rN(|-|$GlQ6q7JPAvhVk=M6NKCT8BZqE7X!NcoOvA>(hnG4AtGWfd2i@ z$B;F_G4TAMrEhirc7#4uruw>@;d2c@7*MbGcky%tou9Dt^rflCUoiYTTYGVoR{24M zJrSdI@AbluhYW!?viof!HNfXwsvUNE{+Z|Htm&hbau3(X*wRs--e;y&-9(E=?1jp) zExFVDA}qmSbh1-2gnnxj>s#q4FC+m#ikQpW>^>;W_%O8i_{&yRm#pV4f^p z9x5h)X!AKg%IgbXk{FbF4=<~XI)m?0!^Rc>nvE$rhSsSfybx-eQju{kfGr1bts82} z)I)K^UacX8VeeO{_oD{0kKWH?%8EKO1|4VSxCdCf?x#7s3Z&M&t}G?Q-G z8;k727tp{Qzp)a zJvOP_Z&Ctz%ZLvJk{)6zvo)6ps)jJc=xHiID+>n(Wu8%rz9qP~1K}S;r&coBwTo#O zM>J`UqiILePy=OJQg+i$3SoIXk0ha>eJYy3O#Gj!p;Y3!>pu7up7sRk+JGV|@|DwN z$r(dF!t#Vz@_Pi=0)dvYc-CH5- zL40k?!*1MDCEAGK;H-l7wKBl;9VsGtV6qH>Oh(*L3`j5a?8kQuX0G$=O(n)f*F$%M zFzNW6^9Lkl!f0d^G(Trr9SEkrEzU?a^l8l=67ey_p!0gTZKX3@qn`}%t$9PB`Wfov z@v+ES^T}J7m+Q$UbL{=AM^a9<(|e@TpAF6R)jn$N2@-HCUun#R+bjoB@1+n}h>rFA z?kK~}R%dj%|2y6+Q@g{|^|R^Cr0fN#USlipVNB?gT;QT#0F^#9?@2oz7vwi;iAp)@ zgw=)LjBYm#)osu!UvhrJ^-Jz*aOMHtpI0|?0(WGH`JKlnU(HDe{QK^742GC{u6;F` zyT^f?!mD3pSXUu8WB5Bv6HM6Rvz-S!Xpp(ww=Xzd1)7H3MSgJuYsc07T57zxe=iar z=n#C{!ERdW0gm)uG=j#rP*vd-M1(R=!sWNl1LD6Q$F_K?bySV8rGa&c5{!yZ{BGjS#xaZbwuYyWO9a!xoA%I9))9VZ$uEX@c-$}i z(N`D)!|OZtZ`MRARQS@lJf^;LzhUEyEHP6ni_d<4ZQq9h?Zn{OMt9% zd$swplY?p^FCF3{f1T9L3%IGzna$C;t}10}v)60oD`UN&KOb7EKepyoT|N>85pWs9 zXbiMsJs{H!a|iMhBqnhl1%)XrvQ2%8(U*lmyN9Y`1*O4B`b4P}oFUri7qa}r0t-u{ z?D_RSMFM`Srm8)#5VZ;fKj7B-c!%8E4nu-F&HdpLiE$#}$bF z49N~HwznMO!5%4MEHK*|UUYOkw{F+aNo^@DG@ZCws69n5%o^2gTx!Yf(>_qq*}0tM zU(QY9ON7PsYnoi2TlXF7R%#z#t?J00F2;6Ew=R=zpX*L=4Nv%)eM##x{$A)XW9o7I zvhN3GQbhRS&}CInPRwrff#1%WVe;8fFbPGq{vH|&=&~q=wK-7XI&*TG*EmbOZIO)2 z_()}5Gja6-2p84?)-TUE3rpV+LhlB3snF;O`uBfal$g-6Y17rtu4@j;IlM&4Ctk!H zdYxu2^tq75JY#Ql4%~2yTgP2j&lhrvI1KlQ_ILXE;iBtQ&)R;2PrG%D?4uC_aGuJc zKj3B?GgiCwlf41oM*|zoNSVxaqFA?o{KcTzjEVzDsJy!C>)e37p?kS3PhP zJs?U`w}|mb_)A9z3==qncL}8(-CT+}m1iEfhYAhP8wW&@whHh4-n~rk5MXLKUBvaC zNfTC1jZ618MQlp4Q3sy+R#Rvy~fhqu1b!_jjcV@T~EW&1EQ&*I7Cacl^LPv3o^v>{A5uEX8zF11?hvlTGkp9z<1G$`5 zNY$;E5_#|1+OB+{hNaCZ~L>q(wrB!H`}?}TvR%fl6@9^X0d0jh3j1fBm=#RtpKjlrTxtl-g_Arl*~f zc8p}~*(V_|21U);;}OF8V&*N+qw?RaWi>xl$CW%bLkSCL2eQTO&X2Hr18Xn{qaq%vT z@C0Ju7RQu5Hyr6QHvR!oCg2cwKr?;%z_KabQ*I!;?C@utZ;!ljm&dYq9b&pPqh1K@ zWT-_gK;$RyetzeDkf@h{<4!07xyem+t|=LNaBxx9eXcK#Mmt4FGn2EuF?H!e!B(|9 zsk6M*u=A;Eo*u_0(xeOHInv zdgD*u?9@7hwvbtV$nzs^AyC$8s9kRxmkh?U+tz4~ z5BE?|?=dEA_)9n^V?f`nb_@bwf4 z>SWcHX-feLYe`ryKN=Cp=Qte3Ir8vCEu&5VKMCse7`F+WXT1wHXt zI>tL>`(nRz!1u8>AVvqosta!t!S?)Z47Tc~#?S*IHeNM{g}-lfdA;^lnn*qw?9J@q zckl-lcdpf10r9VKCc<1d-a0$@btQ6M_7f!ZPRdG{n`2>YXZD$Cr^3sFF>P!6=`K5> zZyugXO=lu341s==gEUWp)xx#o&>!VE-PE2`#cV>TnLd!yl0H|qalk>SGo%@C$`q+= ztM;kH`30(JAFG6}UTPn$#|cH8gT+wjTC-n{)}rR5N&KhVa%*(=jgH!Oqy*^rgip@8 zaErEIDnidbj|j($+Q03KuQ|1A@9|jH_eO%2XS)A@clnHKGm(c4&v86uv9xwF63V!RKP2 zV@9|D?kF*7^6bp)Be{Q&Oz=?JvtQ8-sTHZu*s@B#F3CROZY%^%HhQiXSO!`*?TZ@^ zJP-J6%QM^TWY*+B`W}eb+2kVmuI=r;N7a7K-{-m04lNxt4(p)My(Yp`EuiE#{waj&_I$TwbU3-ktdE z)h0~+Qn%GDb4WEytubdE5w^Zz+Afw)`96;RSzUY5dLM)NWuIo{wr2b%QQ~I}HOsE_ zV=TJcFJHxWL>EVYL*TxA74=ls<^A_n9Es03pVZ02m-=4@w2v~-DZK&niptoaAAbAe z!YcIhsNm{!Rm5-1NKE|s?`|TSP`4)b!OcbsGwT&^CEd0WiN~4Mz2nvA=XBW>O6$hy zymz$&yysp&V`vi3B*{lSzobg3K6lf}sgu;x3&;y_G79*H-(f;Co$l~M{7c1(yUcxkc9vAv*%V)m>mb~Ytq{Y`C5njE(u<<4I(Z_TFc2v2k$xLp$Zf}oh*V-JB zQD-sP7p}>U|B=RU#_nj_mPYYqRA9o0iD@m>deU>U`yVXs7%_h=Jo+5PcanS6X4!k( zmF7#Wf>Rum{Y8n&x#&DO=eLj5Bp#JC)0lfBy|DcczfLar&@bz4rRrCuYtOVc-@MECBS5ut zCSO@$__5iqUd08?uds-+?(SM-zsGXXU2R&^z4@;dH1ilEo&0##PyATUy*KI>FY+rb zn!Rac$R_$7M&@KISXeTR&KOE%4NU_K^pl(TM0gzZS+#R)3VSofKhPf->Tvwg6`gC? zVF5l|Pa`?4U#M%cSd-qS@0VI}ky&BV4mOo?S~83!*a!_fM*5`vo_EFh{P}@6+R^tb z7caSfrD-1SHQo2(pUOZ!_@%M|r4sXA|6fN}!B$n*M3s~lk#3Nd?(UKjiA#4~x?7O$ z2I=nZZqQ42H*)Fjj_+jrkHwu91?ISq5hx~cKmneHcl;!HQ3ZegwV+eRR#N^*x67>N8sL?ge1 z@XN1a&g!bKo;`)x*+v&!RnWQm$V!@MORTz;NM{22Vn0~^8n9^omRiV3L;Uuj}UjJj= z7PWzay^yvQ@`H%1&oo+tHM+C}SoHDaBTCWd0UDDgXa_2lY zE>gAbB*}$}j?6;FJmHI|q!&=D$KJ9gCi4y~2Tl-;^V+Q);Y96bQc|kGoe?@4b*Zt9 zoDI}=q@GD36~=N(F^+j7jK#+vDo8qP9{slelzChcp&J|bGF+QY83JJr4wKIw&hoPE=Mo7 zIttE~#+C>?UB_0%hr-r`B@9iQEnPtqr|De6F1*?KXxD?JWJ7o;lLbj8<#nc=C5g9 zY+f;18pa{X$Kj{*4<_Z!!ow4ai$f04$E9}bdQH{FA+GzF7LBO_Ta!LP2g6y9k0+)Z zS{%BmO;#g{5i3JniMJ$L<+R;J@$Rb2(P?!X56aBz_;^_If2OJhdCa}9|J zIL+}kV#k#X%oWn_tx9X*fRf}j?qGPmZTmTwS&LCORr$xH6Oy#bhj7>S;n3dBQ}kt5 zn-qv8ke6N)v##dqC-v?iOAofBu78ky!Q3lgf9@-1rH1 z0`_DjM9}GBT&}uX@u3@mFS91%185A(u&`|r*#C)HoC4= zxri`=Egua3;sqBiBOlNU^E;3b5M8w{>I3;ZVP$-kJb!n=K!#8M4ix=T6F#J>-MWI! zM`G!(sOhp4I^DA%QzXWs&$JmxCX~pgmc(~u5rK~9`fob7HzAH|pRu|Os5SK>n?)C1 zuC49$2pY|QiaEk{BNOw6vC;$|^F2XBIsQ^|GNlO!@Et&{f=68I;MIJcNMdn@0}i^L z&DTygbn<0SQR#z=^EBn3nr9T8JUGm&52<;v`AEmWcuN%mZ>}n$H0?xKmKp+|YL>PB zwji57VinNWf>tr;jT10;(Yx$!KcdEd>vFQ%`^j)~barup=T+bS;P1e$oeJp*qn|v; zBNfSxO&2~n%gf|+#ZM7bq;{!^#Ox3pxJiU~Q{dNX2OnS;QBpO!l`hE=*}il9N{UiY ze68#v`L@H3Bn0F(m%i^K4~t?5_4*uE{J#t4@pT&|EyED+)ucVId2{ua=5juCX9za3 zP0d%?*uP~YVN_=HA`-y0ZTUai%}Vpp=bVVKZM}`|+t^#~xD|3vfFgkJk3+p~1LsbMp|i8Lg$tcJ^gw8{ZqPnG&onjJeYl z3-5!-7;nbdgHpG+BXKkIUOJ9h+lAA>8{n(hRHfPvsQw(foxUSV1H^8tSn70GBgpa1 z7p-u2zdBxqXS(Vu!T+z@iM`@&y-l+6vR+v?`Wyavv8yap+!`^M({}5#E&UF2>)SP0ytmN@icYB3APSHm}$wIXVD|0*yDd=my=cZ@8mc z3S*SENA3|NKYG*3JfyOXO{LXxeW=OC8-F4H=7b;OwEg57*>Co)6`J?^@OU0$ z&vEVUZvh}Ahd5I00yi*RTE=-QTyvRcaegGJ4gU;RjX?eLsO$^+(nXP%70_fEKDZRx z3qO4S_-QBX31IAW9#`P=6LUE|hJk8;NH6$jyQk~IDB)q>iM#JNlmua<@5UQ-<|JMA z!tBADYPv2Y6m3{9sU>aB2a|~1a_euKb2&bmE6Dg^Mwe=4D`kEzM0ECUIscBeeHq5f2qa%-NI(MVeU}~PJRfykKOxpFm z_0DZ3@%)yC-Xb>KD?XE?IFdxGV6oBf(AZbtY46$P3DM;%n{H8@bE{Huej(^>OvTjsLD3U-o=@s1glM595f!MX5+Q4WD95 zpO;F|E*}{uz16=_X1+9UI|TjqF(jMDp2pJK42;z$dpnmV)Y=y3p}wT6Z|ac2)VTR>JM0!;K5!cau?f)*cl2Y09#uIA9=#HZq8==gvK~ z=fXi~P#%+0iU4EV;xxrb;pZ&Fb86M&ooqMr_X8vdQV?>(@$kj+2r1i7-yH`TSSd=s z2C_@xvtZ%DtH;0aPpA^kDuUg1fCG%;P0~PPUWxkX@>HJkBXRsuY4c;pw_Px0S^(@y zkMru{R+Ca+A}Lp9y05mKtVv-NWC$_5lk@^4<1D?no^NK zU`7dTz+dQfh$WGfzzar8ExSk=oHV?Lafxx*n3et+BRr#~uyMQxlav)1L`IP>qYv?h z2O~}BE4opfkSPpeGC#-M2udnRl7zqz4sbBoM?n;hK|<M?(5j@nI!yxvbwC>vlJr_=^X`N5;(F$gyfaFPHrGS3ni-?z3oQH1My z$~EE5e1IIrvWPQEuGi=A!H<%=L8I`P=wJJNB+UGs{cpCLzvKN>{sr|aAT@CxEHD^d zRcr2XZ}p;t@EUtvNQEXNr*JT!*}<}}{1=3umr0u0u3*dYxC<~PFt+`1CO(6a4&Fob zqgSDYAHj&2>Tx)KAMcNt!YM9!3fPx=C>bd#dq;;LXkf&r{?>ohGH>qh0SC3c*H^6% z-z8f_oGxd{@ME);0sVJB&)|f%*j((nKzZ|SrK9ir$#VIWC0sEJ#q`LsFqdthsau** zUL&tsR51DhJg_td_^Bl;p@v>!+0Rlq@Vb4aat7u|w0*_zSMXFdBW z8PL6c133mTH|tqWEBi2I3#mK~8ero4JPJYEm2c3-8o8LKL)QNCsg;QopO}qJIm*%v z8mzoK=f(PWM^hEB>tdZ`&>#bbkjz8rwPSHEjyAK@XbHzxfyYT5VX|X z49x?~FEjpf-;)c5(WdD1jDUxD#(&V5)JumJ<^@c9-YK09&Ks(5` zVusEa)4D`w?mb^MflA%kMMcBKK+$PAAOEDo{r;!$?hS=9WMc4M0&YCI4`XQr(lz*u z-Zv_@(OXfO{JK#=$Q1)!FTwxgTWPQw=piN=F*;CD_SvqM_WZnJhXV?T$-z-X<-EgT zhQCKcg1Rl#m4>W@k%jy3K(6{9f!@_T1MIypr+(g0?sbt;Ai0h4NS&K47jyYz{ut5w z@HQc*(Yd(Mze zc#Uv&|D!cnc+KAXmB#Ju{M=A4t%L*J537Q=kY;AL!t_URYie|z;5@{Dyf45 z%l51)^=}?CQk|7V({ub|jD+>mMtAp5ZH8@eq`4iR(C*@j401l=_qlC7M97psS4h$j zTvWv24n2fekeHaQo*(bHZpmaDQBxIwjeX$yLtp*@=BBo6IdAW&jeQHlC14=nUQGtL zgpHNqmKz48_Jvc*mUL4lTGflr)p0l^v@qhZB@14nU3|_s@gpJS4%1P zcHAMua9IRU`Qa~9PgmPeR5p38qtxT;xJ9zS@r<>|3e&d z3T*+tDoyAMdBUgEl!{&Tq`Y^yYK0{foVReF?H1OrnXDLI&a<`eO75&mafjZ|9eEX& zFjLr8%Yni9dgr@G%ow)HXHVlI1q}6NKQa)fQ7#d-v1s?t<>N@spJR7{z1hV~$hbkA zDR3LiAPTCKA5}**{IdwD+2hkz(w1UWdde#ZJRinbm z%_I=to0Kf-`Ox*aWsTyqnHc9A8t=gw!y2}h^;w60@I45?t@6@7qH}Op_F5#lS(-6^KQ-Ju%KIC-4jBf=QNd)QgLvC#W#J3r=zuGZ z6_Nvz1FY`%O9EO`E&tryE_hwuEMTEcGR*vfE)B}gt!a%IzT7wZ}85>M^O<4qc*+O+AT%EoP5;Ih34_B9Gk2T8Ot2A2{@40>UXy1>6E| z-nPRnVTV5|7!cr-qtfyCq>gb9zA4fys-q74+JHq?$NOGj&iV{HP8AEWS?k=Zw2^Al zGLEm>#`Oca$Jd;5V%L%T|%xeZGwV8gy|t*Tp-#im}{ z!W$b$X8Z}0_%nnyLo%HcniETVA8Fj4J1Hdoz?aanqi;)Cns@`DDHy5D~96g zZ)@+Yp&(wn$OKuOuWmBPX!%{Z4v_fpIW&iH6>%zaR#;xzF<(-%Wkn4_J1vwCMHrN+6v;X)$&=s4< z)mI^yIak2Rc>k>AhgN)Hs7Jp{Kraoc%(O+GRJxTy>Kv|18L>sp~zExB%#)fiqeRcE}< z4mKvgwnAABzixW3>!gV!m#W+_|`0y_YKasGj+ND zo28Voes+91{u?oS-R5VX>P*UI;ZLCg+1hG$@K)vVVy5;0&D-j)A#$0?FM<_Dva>$6i%p3ZWi&@=`h6$L#uJot%mQUJN!8RnxKk(eZz#>`0)=f~}` zI~(&=HWg!A6je$`j;dg=xT<{CVL$ElVS?8wzL)%PeiC6+di#E=17Rz7WbNT%de~5H zX1f!|xaol%qk!+dxE|N-4PC&K`N9})`ENBe(GmcO#(<40YUo86P>;Sahnf!i(w`<> z+vZFs;X@DQ4gugK+e0H3`NWj8<7AW$o$!Y+SoLATuMNEKM<0nsR2GOdHz>;q%>?&%Quwx?i%sI49odg_>eY9R~^DZc{$E#eE^+K z7V_Cy&W2HYIrXr}Ph?(17r2KLHfYDk+D1t6D;XHTc#k04P#qwf(2m~U0@OXH6Gp3) zQ*!VlACa(}-g;HT4vbduxdG9cEc8BeBCLR~ea>Mec;gCHU7U*YOp)m+h$^Tfzf3PJ z?u}BAjxh!T@KGh03r)=LewhXX%r`SO6j`}9cV+-&J;zT77pWqZ2(VztObSE*y_GYQ z1XkK@>+?`ROA=jDvVdvaj-MJiwp=Bu%9_f4dMYCK430HcCb-ach)_P2oTC#muAr2-41DiozH0CoDQF&x_h)bikdtemqP2Kl z6G9KJ6?bnBflcY?`*xYIm?9t(NDFdS-CJOcwFxSH=#TNH?oFs_b2+&$QyY=lHtaeU zk%sS5>FXID%}zSG3tX9Rp#s3^3pZH#6t;o50}^z(6e`x6klM;rJl;7z6yY5P%VA9HR%YDgYgGd-TGAFFOe|_gKddnCG=toC2U1?}O^} z;6ud}QV%As4=25U{w$kea;p}Hw=P6Zu~)>z<*(rb^AEhJSjTzNNEE(CS)#4|FnPe} zD!1ww!5(~KcfG%ZoZRV!V-Dey(Q)O!0M8TiU_)O3L@*q!U|}%P3ZQ4ll14qfVb6|u z!N#4rAub1!1#0=hi2V(kOu)xWn)Gk0Cj|HymQEpKad@PyL;7ee%6~29BR-$38HArN zEJDyQIa`U-Rv~D?a#^SSx`f<#^v7QN7A!=E2UK8E$* zgb17JtF$~k(h>G|NHID@rQ6;*3z8<#3iSp8W|KVS%TlCCVQ z5XFmN@>{#{pC$LA|CwvDLJ5RueTiq11UdIAmX-SZl>}y(g0>g`QI*4Rp3=>El7~7y zwuGZa8{~O4k0%SbuUx}&*xoKg(!J^cH*H_&9<(%*@E>C zB36ONjrgA8ziLfZzZ*tH*;DP`x3GvxjT2-^NVRcxrQ!)t1O6{ zC^GD{Zs-s=0*96$lkE7!H6vQOVUqr_lAUosIdilLR6v$q}OTrG;++O>$teqGyyA7}Ay#9C~2cHRI`PinP^*obQdHw0?z6mEAG{%hrJglaI zV`=K0{fZ|sJwWENz^1FIy(dq6U%LiGfs{_;^-=PSf!VFTSbgJQ9KqcWu9F`;#x)!D zFLGCufKWS`&@hjlX&8Q$AcX#BwNiD)bF1sB>ukPpM*nzmsH~#rhHfT_^X9&D?=*b> za~Ge+@bG(V{OZ@6Q>O=O#?`9Ij>*P;pe-G^<@3$fy&ld_@&UqnAdxlVI36-Rlb@0D zE%+q9qHsd5`_w?*dCzyH_61Pd*3^n^h&dScJSh8*gk9#;ZS_*7Wt4dhHb&B_*Cj0a zEB*wM{(u=hRk7qWL*jW+`>^s~^zK~yq}d&Q9oHH0!^c2e-^yad2}JrWGUhqv(W34o z!-HH`EwSKv(AgBN^KErb7y$9>{+=ET>kgy`>`YMBxP`xdp=$dnEJb{ zUN<&T4G?}Q>%O|a*%5c(HLbaidLKHV{kx<80)D{Xkdk!u!_x^DhkJ+n=R;W()T)p1#%r9n@gp=?6^>35V(ew>5=&>BcCW4DDvY z!I>nwxu5JLDXfKuxY47V`jrp;cIZ3iR9#pU%t-5Pq<}2Qba29h1WS;M#5;a z?A>Y#8v)nF0_k(aLpvS}1u7kGsIny_0`)PGJv2O&hgJULXe~lX|4$u|1~sE-Uu?bQ;vK| zXM~DvCSR_j@P^h()qonnGvuG2yA}ukpjOxX{rL1>n*ob%qi!4h=^R!9L<#i<28-B) zMGlpJu;E0muN7_X$#Hs1eLBy>-74yoClyR3XUmv{(3|V_AqQnxnKaO{jSUuU8^sZ; z+pHLV1BFr#wPf&_Yi!P#OC=50fbCIP9L4Rja&E(}egwm;=x+zUkzIXN#^^owZl<7# za5=G7vF_Pw!R*5Aa*+}qDeY;GAZc3@G5T*){BgFWKx&5@DYg zZqX`diT*8yx28oW%kW=p+*#l3_|H*wEa^k#_&Lp`k6ahz zMa_}hDGo~q7jGNusfd!g!4BTinv15)x9g_Kor|WtIKSC(dVjH!E95x83mc(?FZ>`O zR?hlaVeF$^y?D^K;U^3FFV%w#7*bX5cm?0he3uEEHVO7ovN8TmO>rl*k$NY5OEYo? zeG=Mx;;_+tgW+Pjrug=Bn|F=_{cZ<)s^_*-f*r&U{+k?EzV2`{f26{6&J)Q#s5X%S z-cDd&28unL;Rgvgw z1+k!32`$&q;}DvXkTZUJezX1*p>ZU;$hl1OX-Q@g8?mVy2qqP{y9tl%nxt*&W!Uvhtk5(S;cl@q=cr zHf8oKuDojvl0p0hF+cmN%MVI*rqF-38hak0(^tvbIDXd~t7thU^rUt9himoRvpMIM zoMQHhC_(fEMkQZR&gp_D@`0ZBOh;^VvAihlknd)$Z#)d@oaBuTi#~6`aZ8%bV1>yb zUio>J8uHkjMh~Lt*0OgJ%c=4o$;}q2dQ|%QyD&tGZqd#j)a3oTjzWFJ^6Mh)BY#s? z4drm@t{Hv`m_UT}V764NvF80d3FG4_dZ?tM@|kljc@qO8*{Rr4ky#4#FUj-jb#=Wl_f0I-$>Hc#k?23 z7-{}vAm#hCG<+X4A$&9!4GMXt`MSzEpHphiN=r)C@Y4Jc=02+Aq9xnUFGsNwY=vgF zR$Hih-~<7ET6a%PT`EcXBA<`J2bvcv_cr%Bg1FTKkBC(1%#n<>aSF4Rh*btx$RIShdd)Ij93OZ|UAMqy`VQj9G_-kf6d& zu!V81Kqar8i~4oLv24f#Un58pify3|*8CE)~1-WJU!muyOZ};%W zMYwi)9n|s{g9SnU%va>N@;LKBOosT8+#OMl^%VupbXM;B=iHMkTMTE_s!sa7@%cM* zZizt8&;6>f3^+I1TW;F6&ZsQ;96u!Tl_9*#nxwZ^Ki(vWbaW{z_i-&hIkHjmk!8Yw zu~AVlz@mS8lQd+l8Ab#RMEsKR_KiWj?8D7pDCt@}UCi8Xs?d-?w|24*GyOjo&n;xK zMTw>V?F|X$hzAA>%r*dD&Qw&ySmB^mTn;)1xOnT~Qt8DW&yc zpZHJrOI@5>2({{>i`k;ZM4v7+H!gUue9poF*BkYOMxmj2-55gm(@x`i?R4 zl@Wb4q*(^)q!TqENr@);!)t%%A#gzhHjW1mrjy(4RJ_x_x5LeBPa0{hKI^Xi^z^IM zd|40`m(gwdpS#$ta*5pUw4aepEwf6?L-d+7&Mcf}70jK$z?OcFZGA{dS`eHpRV%^& z1qnAr$?ANW)p#nuB~Z>!Q2#;psb)8ph1gH*|6jNv)g1bAEQ{c##uOQNIXj|V9PHux z@H*)u+-mxeNn#MS0r4<1}Us!+GB=I2QC!z}zA zFK8>0?TPI;m%=1=d402<>{Qn1@MnN +2019 + + From 5872196c277b04a1a982dd4969aa850ad4d1c3c7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 16 Apr 2019 12:56:21 -0700 Subject: [PATCH 0010/1772] Fix markdown syntax for links. --- proposals/clocks/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 4cf122cab..5c77e4bdb 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -8,7 +8,7 @@ deliverables of the group. The repository may contain meeting notes, reports, documentation, specifications and/or software produced by the group (although larger projects may also have their own repositories). -[WebAssembly Community Group](https://www.w3.org/community/webassembly/) +[WebAssembly Community Group]: https://www.w3.org/community/webassembly/ [Charter]: Charter.md We'll be adding more content here before long, but for now, check out these: From 0c58bf27cb93b174681a72632b68b53936e000ce Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 16 Apr 2019 12:56:21 -0700 Subject: [PATCH 0011/1772] Fix markdown syntax for links. --- proposals/random/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/README.md b/proposals/random/README.md index 4cf122cab..5c77e4bdb 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -8,7 +8,7 @@ deliverables of the group. The repository may contain meeting notes, reports, documentation, specifications and/or software produced by the group (although larger projects may also have their own repositories). -[WebAssembly Community Group](https://www.w3.org/community/webassembly/) +[WebAssembly Community Group]: https://www.w3.org/community/webassembly/ [Charter]: Charter.md We'll be adding more content here before long, but for now, check out these: From cba22bf7332d5cc4643a04138f2c4286e245c7d5 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 16 Apr 2019 12:56:21 -0700 Subject: [PATCH 0012/1772] Fix markdown syntax for links. --- proposals/filesystem/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index 4cf122cab..5c77e4bdb 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -8,7 +8,7 @@ deliverables of the group. The repository may contain meeting notes, reports, documentation, specifications and/or software produced by the group (although larger projects may also have their own repositories). -[WebAssembly Community Group](https://www.w3.org/community/webassembly/) +[WebAssembly Community Group]: https://www.w3.org/community/webassembly/ [Charter]: Charter.md We'll be adding more content here before long, but for now, check out these: From 4123ee2e26a60ab7f170c6e0f8930501a62faebe Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 19 Apr 2019 11:23:33 -0700 Subject: [PATCH 0013/1772] Post the schedule for the first meeting. See https://github.com/WebAssembly/WASI/issues/11 for background discussions. --- proposals/clocks/README.md | 5 ++--- .../clocks/meetings/2019/{WASI-liftoff.md => WASI-05-02.md} | 2 +- proposals/clocks/meetings/README.md | 6 ++---- 3 files changed, 5 insertions(+), 8 deletions(-) rename proposals/clocks/meetings/2019/{WASI-liftoff.md => WASI-05-02.md} (98%) diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 5c77e4bdb..7fc421229 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -20,6 +20,5 @@ We'll be adding more content here before long, but for now, check out these: The issue tracker is the place to ask questions, make suggestions, and start discussions. -As a W3C CG Subgroup, we'll also be having [meetings](meetings/README.md). -A tentative agenda for the first meeting is [here](https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-liftoff.md). -Once we have a date and time, we'll post that here also. +Schedules and agendas for video conference and in-person meetings are posted +[here](meetings/README.md). diff --git a/proposals/clocks/meetings/2019/WASI-liftoff.md b/proposals/clocks/meetings/2019/WASI-05-02.md similarity index 98% rename from proposals/clocks/meetings/2019/WASI-liftoff.md rename to proposals/clocks/meetings/2019/WASI-05-02.md index 5d1b50685..142bc90d2 100644 --- a/proposals/clocks/meetings/2019/WASI-liftoff.md +++ b/proposals/clocks/meetings/2019/WASI-05-02.md @@ -3,7 +3,7 @@ ## Agenda for the first video call of WebAssembly's Community Group - **Where**: zoom.us -- **When**: to be determined +- **When**: May 2, 16:00-17:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Dan Gohman diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 46bc08d27..448a1be93 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -3,13 +3,11 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow [the process of the CG](https://github.com/WebAssembly/meetings). -We're currently working on setting up the first WASI video-conference, which we -expect will use the zoom.us service that the CG uses. Once a date is set up, -we'll post details an agenda here. - ## Meetings
2019 + * [WASI May 2nd video call](2019/CG-05-02.md) +
From 8720aadc544f3fc524f42d3573e7b811119d5d3d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 19 Apr 2019 11:23:33 -0700 Subject: [PATCH 0014/1772] Post the schedule for the first meeting. See https://github.com/WebAssembly/WASI/issues/11 for background discussions. --- proposals/random/README.md | 5 ++--- .../random/meetings/2019/{WASI-liftoff.md => WASI-05-02.md} | 2 +- proposals/random/meetings/README.md | 6 ++---- 3 files changed, 5 insertions(+), 8 deletions(-) rename proposals/random/meetings/2019/{WASI-liftoff.md => WASI-05-02.md} (98%) diff --git a/proposals/random/README.md b/proposals/random/README.md index 5c77e4bdb..7fc421229 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -20,6 +20,5 @@ We'll be adding more content here before long, but for now, check out these: The issue tracker is the place to ask questions, make suggestions, and start discussions. -As a W3C CG Subgroup, we'll also be having [meetings](meetings/README.md). -A tentative agenda for the first meeting is [here](https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-liftoff.md). -Once we have a date and time, we'll post that here also. +Schedules and agendas for video conference and in-person meetings are posted +[here](meetings/README.md). diff --git a/proposals/random/meetings/2019/WASI-liftoff.md b/proposals/random/meetings/2019/WASI-05-02.md similarity index 98% rename from proposals/random/meetings/2019/WASI-liftoff.md rename to proposals/random/meetings/2019/WASI-05-02.md index 5d1b50685..142bc90d2 100644 --- a/proposals/random/meetings/2019/WASI-liftoff.md +++ b/proposals/random/meetings/2019/WASI-05-02.md @@ -3,7 +3,7 @@ ## Agenda for the first video call of WebAssembly's Community Group - **Where**: zoom.us -- **When**: to be determined +- **When**: May 2, 16:00-17:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Dan Gohman diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 46bc08d27..448a1be93 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -3,13 +3,11 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow [the process of the CG](https://github.com/WebAssembly/meetings). -We're currently working on setting up the first WASI video-conference, which we -expect will use the zoom.us service that the CG uses. Once a date is set up, -we'll post details an agenda here. - ## Meetings
2019 + * [WASI May 2nd video call](2019/CG-05-02.md) +
From 53b3d48756ab20271a18298dd1ff856fd837db17 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 19 Apr 2019 11:23:33 -0700 Subject: [PATCH 0015/1772] Post the schedule for the first meeting. See https://github.com/WebAssembly/WASI/issues/11 for background discussions. --- proposals/filesystem/README.md | 5 ++--- .../meetings/2019/{WASI-liftoff.md => WASI-05-02.md} | 2 +- proposals/filesystem/meetings/README.md | 6 ++---- 3 files changed, 5 insertions(+), 8 deletions(-) rename proposals/filesystem/meetings/2019/{WASI-liftoff.md => WASI-05-02.md} (98%) diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index 5c77e4bdb..7fc421229 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -20,6 +20,5 @@ We'll be adding more content here before long, but for now, check out these: The issue tracker is the place to ask questions, make suggestions, and start discussions. -As a W3C CG Subgroup, we'll also be having [meetings](meetings/README.md). -A tentative agenda for the first meeting is [here](https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-liftoff.md). -Once we have a date and time, we'll post that here also. +Schedules and agendas for video conference and in-person meetings are posted +[here](meetings/README.md). diff --git a/proposals/filesystem/meetings/2019/WASI-liftoff.md b/proposals/filesystem/meetings/2019/WASI-05-02.md similarity index 98% rename from proposals/filesystem/meetings/2019/WASI-liftoff.md rename to proposals/filesystem/meetings/2019/WASI-05-02.md index 5d1b50685..142bc90d2 100644 --- a/proposals/filesystem/meetings/2019/WASI-liftoff.md +++ b/proposals/filesystem/meetings/2019/WASI-05-02.md @@ -3,7 +3,7 @@ ## Agenda for the first video call of WebAssembly's Community Group - **Where**: zoom.us -- **When**: to be determined +- **When**: May 2, 16:00-17:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Dan Gohman diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 46bc08d27..448a1be93 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -3,13 +3,11 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow [the process of the CG](https://github.com/WebAssembly/meetings). -We're currently working on setting up the first WASI video-conference, which we -expect will use the zoom.us service that the CG uses. Once a date is set up, -we'll post details an agenda here. - ## Meetings
2019 + * [WASI May 2nd video call](2019/CG-05-02.md) +
From b5668a53986744b35f64f261994ec9a8946b0743 Mon Sep 17 00:00:00 2001 From: Sergey Rubanov Date: Fri, 19 Apr 2019 22:18:59 +0300 Subject: [PATCH 0016/1772] Fix May 2nd meeting URL --- proposals/clocks/meetings/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 448a1be93..99a547333 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -8,6 +8,6 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow
2019 - * [WASI May 2nd video call](2019/CG-05-02.md) + * [WASI May 2nd video call](2019/WASI-05-02.md)
From 74fad76fbe0549c175bfa252c74bc05b5bf58158 Mon Sep 17 00:00:00 2001 From: Sergey Rubanov Date: Fri, 19 Apr 2019 22:18:59 +0300 Subject: [PATCH 0017/1772] Fix May 2nd meeting URL --- proposals/random/meetings/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 448a1be93..99a547333 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -8,6 +8,6 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow
2019 - * [WASI May 2nd video call](2019/CG-05-02.md) + * [WASI May 2nd video call](2019/WASI-05-02.md)
From 832a38d827447ed807298f37c80d46b6fd1a355f Mon Sep 17 00:00:00 2001 From: Sergey Rubanov Date: Fri, 19 Apr 2019 22:18:59 +0300 Subject: [PATCH 0018/1772] Fix May 2nd meeting URL --- proposals/filesystem/meetings/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 448a1be93..99a547333 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -8,6 +8,6 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow
2019 - * [WASI May 2nd video call](2019/CG-05-02.md) + * [WASI May 2nd video call](2019/WASI-05-02.md)
From 3d27c20bec8169bfa43f10eaca3c86dabac20bc5 Mon Sep 17 00:00:00 2001 From: Sergey Rubanov Date: Fri, 19 Apr 2019 22:20:39 +0300 Subject: [PATCH 0019/1772] Fix WASI logo URL --- proposals/clocks/meetings/2019/WASI-05-02.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/meetings/2019/WASI-05-02.md b/proposals/clocks/meetings/2019/WASI-05-02.md index 142bc90d2..4abedf7bd 100644 --- a/proposals/clocks/meetings/2019/WASI-05-02.md +++ b/proposals/clocks/meetings/2019/WASI-05-02.md @@ -1,4 +1,4 @@ -![WebAssembly logo](/images/WebAssembly.png) +![WASI logo](/WASI.png) ## Agenda for the first video call of WebAssembly's Community Group From cf1875fb142554b224889b36e11e5127e820095d Mon Sep 17 00:00:00 2001 From: Sergey Rubanov Date: Fri, 19 Apr 2019 22:20:39 +0300 Subject: [PATCH 0020/1772] Fix WASI logo URL --- proposals/random/meetings/2019/WASI-05-02.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/meetings/2019/WASI-05-02.md b/proposals/random/meetings/2019/WASI-05-02.md index 142bc90d2..4abedf7bd 100644 --- a/proposals/random/meetings/2019/WASI-05-02.md +++ b/proposals/random/meetings/2019/WASI-05-02.md @@ -1,4 +1,4 @@ -![WebAssembly logo](/images/WebAssembly.png) +![WASI logo](/WASI.png) ## Agenda for the first video call of WebAssembly's Community Group From 965ee3a5fddaa6980b4f6f749d7ab28a92ec8bb9 Mon Sep 17 00:00:00 2001 From: Sergey Rubanov Date: Fri, 19 Apr 2019 22:20:39 +0300 Subject: [PATCH 0021/1772] Fix WASI logo URL --- proposals/filesystem/meetings/2019/WASI-05-02.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/meetings/2019/WASI-05-02.md b/proposals/filesystem/meetings/2019/WASI-05-02.md index 142bc90d2..4abedf7bd 100644 --- a/proposals/filesystem/meetings/2019/WASI-05-02.md +++ b/proposals/filesystem/meetings/2019/WASI-05-02.md @@ -1,4 +1,4 @@ -![WebAssembly logo](/images/WebAssembly.png) +![WASI logo](/WASI.png) ## Agenda for the first video call of WebAssembly's Community Group From dbda174e917ef446e30d8291740a62c290635b42 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 19 Apr 2019 13:35:25 -0700 Subject: [PATCH 0022/1772] Update another reference to the CG to reference the WASI Subgroup. --- proposals/clocks/meetings/2019/WASI-05-02.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/meetings/2019/WASI-05-02.md b/proposals/clocks/meetings/2019/WASI-05-02.md index 4abedf7bd..4de0e9ff5 100644 --- a/proposals/clocks/meetings/2019/WASI-05-02.md +++ b/proposals/clocks/meetings/2019/WASI-05-02.md @@ -1,6 +1,6 @@ ![WASI logo](/WASI.png) -## Agenda for the first video call of WebAssembly's Community Group +## Agenda for the May 2 video call of WASI Subgroup - **Where**: zoom.us - **When**: May 2, 16:00-17:00 UTC From 90ee77b77a0f05d42bd2a1b49616c1168c3aea1d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 19 Apr 2019 13:35:25 -0700 Subject: [PATCH 0023/1772] Update another reference to the CG to reference the WASI Subgroup. --- proposals/random/meetings/2019/WASI-05-02.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/meetings/2019/WASI-05-02.md b/proposals/random/meetings/2019/WASI-05-02.md index 4abedf7bd..4de0e9ff5 100644 --- a/proposals/random/meetings/2019/WASI-05-02.md +++ b/proposals/random/meetings/2019/WASI-05-02.md @@ -1,6 +1,6 @@ ![WASI logo](/WASI.png) -## Agenda for the first video call of WebAssembly's Community Group +## Agenda for the May 2 video call of WASI Subgroup - **Where**: zoom.us - **When**: May 2, 16:00-17:00 UTC From 11634e7cd37a0e59efa0e09063b3b2114cf29b32 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 19 Apr 2019 13:35:25 -0700 Subject: [PATCH 0024/1772] Update another reference to the CG to reference the WASI Subgroup. --- proposals/filesystem/meetings/2019/WASI-05-02.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/meetings/2019/WASI-05-02.md b/proposals/filesystem/meetings/2019/WASI-05-02.md index 4abedf7bd..4de0e9ff5 100644 --- a/proposals/filesystem/meetings/2019/WASI-05-02.md +++ b/proposals/filesystem/meetings/2019/WASI-05-02.md @@ -1,6 +1,6 @@ ![WASI logo](/WASI.png) -## Agenda for the first video call of WebAssembly's Community Group +## Agenda for the May 2 video call of WASI Subgroup - **Where**: zoom.us - **When**: May 2, 16:00-17:00 UTC From 57f6f68668289ef5e82ce6e29f09b8a31a8917e6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 May 2019 14:08:27 -0700 Subject: [PATCH 0025/1772] Add notes for WASI-05-02 --- proposals/clocks/meetings/2019/WASI-05-02.md | 315 ++++++++++++++++++- 1 file changed, 314 insertions(+), 1 deletion(-) diff --git a/proposals/clocks/meetings/2019/WASI-05-02.md b/proposals/clocks/meetings/2019/WASI-05-02.md index 4de0e9ff5..f23ec4f50 100644 --- a/proposals/clocks/meetings/2019/WASI-05-02.md +++ b/proposals/clocks/meetings/2019/WASI-05-02.md @@ -61,4 +61,317 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-02.md + +Attendees: + +Dan Gohman +Paul Dworzanski +Christopher Serr +Birch Jr, Johnnie L +Eric Sink +Pat Hickey +Mingqiu Sun +Sam Clegg +Till Schneidereit +Luke Wagner +Ryan Levick +Yoshua Wuyts +Mark McCaskey +Alex Beregszaszi +Tyler McMullen +Derek Schuff +Mark Miller +Paul Schoenfelder +Dan Gebhardt +Martin Becze +Nathaniel McCallum +Lin Clark +Alex Crichton +Gus Caplan + +Meeting notes: + +Adoption of Agenda: Tyler McMullen seconds + +Action items: None, first meeting! + +Dan: Process is consensus-driven. We want to avoid coming down to a +vote. When there is disagreement we want to find out the reasons why. We +have a straw poll mechanism to help find that out. + +Categorizing our issues: + +Dan: Issues were initially filed on wasmtime issue tracker, now +they’re on the WASI issue tracker. Need a volunteer to summarize, +organize those issues, bring them onto one tracker. + +Ryan Levick volunteers. + +Dan: First thing to go through is go through and label everything. MVP + +Dan: Which issues belong to the MVP, which belong to other milestones. + +High level goals: + +Dan: with the Wasm standard the first thing we wrote was a high +level goals document. Are there any objections or questions? +https://github.com/WebAssembly/WASI/blob/high-level-goals/docs/HighLevel +Goals.md + +Dan: People have asked about threads and many other features that are +not mentioned in these goals. We’ll eventually come up with a design +roadmap to cover those sort of features. + +Nathaniel McCallum: can you define MVP? + +Dan: Smallest thing we can do and still have some value. Specifically: +IO streams, filesystems, randomness, clocks. There’s lots of work to +do on the details of these, test suites etc, but we have people using +this so far and finding it useful. + +Dan: MVP does not include creating sockets. There are a lot of open +questions about how these will work wrt security, portability. + +Nathaniel: if we’re defining MVP as what we first want to ship, this +may be too large. If its the goal for the body overall it may be too +small. + +Dan: We could take out randomness and clocks if you think they don’t +belong. + +Nathaniel: We don’t intend to ship filesystems at all in the first +version of our product. That set of APIs is pretty large. We should trim +down this list to do something small but do it very well. + +Till: There are people here that consider filesystem support a bare +minimum to be useful. This may be a false dilemma, if we modularize the +spec to make filesystems and network io as different modules, we can +move them out of the subgroup and into the main body for standardization +when they are ready. If you need to focus on network rather than +filesystems, you can push on that module separately. Neither need to +block the other. + +Nathaniel: My question isn’t what we seek to do as a working group +versus what MVP means in this context. This seems to be somewhere in +the middle. I’m ok with leaving it as it is but clarification is +useful Dan: As we get into details if we find filesystem is taking a +lot of time we can move it out of the MVP. + +Nathaniel: I’m OK with this. + +Paul S: what is WASI Core? + +Dan: WASI Core is a set of modules, it should have a module for +filesystems, io streams, arguments and environment variables. + +Dan: The idea of WASI Core isn’t an exhaustive list of primitives but +just enough to be useful for a subset of us. + +Luke: Filesystems are have a lot of ways they can be sliced, io streams +to stdout are enough for some applications, so we don’t have to +provide every single part of the API at once. + +Till: We need to specify how modules hang together on a fundamental +level, and then we may not even need MVP beyond that, since modules can +be moved to standardization whenever they are ready. + +Derek Schuff: People here have different ideas of what they consider +minimum viable, so we should come up with the way modules work and +complete two of them that interoperate, and work out the fundamental +modularity problems like dependencies, then the details of what comes in +particular modules can come later. + +Till: We should do enough that the module system is proven out, we +don’t need to define exactly what that means ahead of time + +Nathaniel: This is a good definition of MVP. There doesn’t appear to +be anything about versioning in the high level goals + +Dan: That is an oversight, versioning is an important thing to solve. +Versioning and/or feature detection. + +Luke: There may be room for a new MVP document describing this ideas +about modules, at least two of them work. + +Derek: We need to iterate on what we consider MVP right now, but that +doesn't mean we have the wrong high level goal. + +Dan: Maybe the goals should say: we want to have an MVP and then defer +what that means. MVP is just for a moment in time, it doesn’t stick +around forever. + +Dan: I’ll take action item to take out the details about what modules +from that document, and also to add versioning and feature detection. + +Nathaniel: assent + +Till: Is the scope of this subgroup exhausted once MVP is reached or is +it an ongoing activity to feed modules into the CG? + +Nathaniel: in IETF we specify exactly what we want to accomplish as a +group and then disband it afterwards. I don't know if that is what W3C +asks us to do. + +Dan: The parent WASM CG doesn’t have a concept of when we’re done. + +Luke: The WG does have a charter that they renew periodically, but that +is a formalism. We should be like the CG and have a work stream and not +worry about the higher level details. + +Derek: In C++ they have standing subgroups with an area of focus, WASI +is like that. We can argue in the CG about how we spec the WASI outputs + +Till: So the goal is to move things out of this subgroup into the CG and +WG in the shape of individual proposals, where the initial proposal is +the core spec of how modules work with at least two modules, and then +individual modules go through their own proposal process after that. + +Luke: Reaching the WG is a long way from where we are now. We are going +to radically change some of these APIs once certain WASM features become +widespread. We will iterate a lot + +Dan: There are different levels of standards here. Does that make sense? +There is kind of an unbounded surface area for APIs and the vision for +this subgroup will be to standardize those. I can imagine a structure +with champions following the CG. Right now there is the core features +and in the future we could setup new champions for new features. + +Dan: Moving on to other activities. We should define what the MVP is. +The very minimal thing we could do is something with just two modules. +Anything more than what WASI core is probably too much. How do we decide +what is in there right now that we should take out? + +Nathaniel: Lets pick a small task and accomplish it + +Derek: Do we want to define any kind of process for phases of APIs? We +want to get proposals out there and give people time to try it out. I +get the sense that we will have even more stakeholders than in the CG. +How do we track changes over time and put our stamp of approval on them. + + +Dan: I suggest we start by copying the CG process. Someone should +volunteer to start by copying the CG document and make proposed changes +to it? There are 5 phases. I think this is roughly what we want to +follow It might be too web focuses. + +Derek: I don’t mind taking that on. + +Eric: The thing about MVP is different perspectives about what is M and +what is V. How far apart are we? Its helpful to envision the data points +of the M and V axis. Somebody said “no need to filesystems” someone +else said they are important for a lot of uses. Just one example. We +maybe want list other cases and cather before we judge and refine. + +Til: Do we even need to decide on the set of functionality. If we do +our job right on the fundamental module system then a lot of the actual +development of the individual modules could happen in parallel. They +don’t need to block each other. Obviously the overarching goal is +consistency between modules but independent development might work. + +Nathanial: The module are really our MVP. Module + versions / feature +detection. But I do think polling would be good to decide what to focus +on first. + +Dan: Not so much who wants what, but who is willing to shut up do the +work and get things done. My main worry with filesystem is that once we +start looking at portability seriously that we might want to move it out +of the MVP. But if people really want to move it forward it would still +make sense. Different to minimal, more about the timeline. + +Nathaniel: Why don’t we define MVP and modules plus versioning. And +move to a time-based process where we release say, every 6 months. + +Eric: We are challenging the definition of Viable. I love the idea of +modules and feature definition but I don't think that is viable. We can +define modules with defining any of them. + +Nathanial: We did mention having 2 modules and minimum. And having +reserved names as part of them module system. Even if we don’t ship +a whole bunch of modules it doesn’t mean that there aren’t modules +yet. + +Derek: Users are going to want the ability to define their own APIs so +even a module system is viable even without any “approved” modules. + +Til: Is viable the right terminology? + +Luke: Perhaps MVP is not right. + +Dan: Should we start by defining a module system and some minimal +modules, or should we try to have a few more features. Poll? + +Jlbirch: What can’t we have both? + +Dan: Initially I proposed a bunch of modules such as filesystems etc + +Nathaniel: The idea of an MVP at least in standards language might carry +a bunch of meaning that we might not want. I quite like the idea that +the only thing you need to be standards compliant is the idea of modules +and namespaces + +Eric: me too. + +Luke: Related thing? Do we want the MVP terminology? + +Nathaniel: Should we call it minimal implementation requirements? + +Til: Is some ways is a minimum viable spec. + +Dan: Should we start with the very first stage which includes modules, +namespacing. + +Alex B: I’m coming from the blockchain space, looking at how to +integrate wasm into ethereum. At least the core WASI filesystem spec +doesn’t make sense for us right now. I was confused that the MVP +discussion presented no use cases. I hope to get out of wasi a process +for how to define modules (and versioning) and we will be able to define +modules relevant to the blockchain space. + +Poll Results: SA: 16 A: 3 N: 2 DA: 0 SDA: 0 + +Dan: Should we have an official adjunct meeting at the CG meeting in +spain? + +Pat: The few of us who have spoken previously discussed meeting the day +before the meeting starts. + +Paul: I’m planning on being there and would like to be there. + +Dan: I will take an action item to look into scheduling. + +Dan: we should probably try to do it during the CG meeting. + +Should we do an offline poll to schedule this? + +Dan: Someone open an issue for scheduling in the wasi repo. + +Final discussions: + +Pat: Is this group going to be responsible for maintaining the sysroot +and the SDK that comes with it? I can still keep on doing the work if +needed. + +Dan: My original idea was that it was going to be moved to this group. +It's becoming more clear it should live outside, but open to opinions +here. + +Nathaniel: It might be handy for us to gather a list of people who are +involved in the standards process what they are working on and how they +are using it. The other thing that might be useful for MVP would be to +decide what does it take to standardize a module? + +Dan: I don’t think this has been done before. I would appreciate +proposals. + +Derek: The phase proposal is going to touch on that . If we have some +phase criteria for the advancement of modules. + +Nathaniel: Tests should be part of this process. + +Luke: WG specs and distinct requirement. + +Dan: Thanks everybody. We are open to ideas about how to do versioning +and feature detection. From 92ae8d3e1979ec35e705684179d47c02c65594e2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 May 2019 14:08:27 -0700 Subject: [PATCH 0026/1772] Add notes for WASI-05-02 --- proposals/random/meetings/2019/WASI-05-02.md | 315 ++++++++++++++++++- 1 file changed, 314 insertions(+), 1 deletion(-) diff --git a/proposals/random/meetings/2019/WASI-05-02.md b/proposals/random/meetings/2019/WASI-05-02.md index 4de0e9ff5..f23ec4f50 100644 --- a/proposals/random/meetings/2019/WASI-05-02.md +++ b/proposals/random/meetings/2019/WASI-05-02.md @@ -61,4 +61,317 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-02.md + +Attendees: + +Dan Gohman +Paul Dworzanski +Christopher Serr +Birch Jr, Johnnie L +Eric Sink +Pat Hickey +Mingqiu Sun +Sam Clegg +Till Schneidereit +Luke Wagner +Ryan Levick +Yoshua Wuyts +Mark McCaskey +Alex Beregszaszi +Tyler McMullen +Derek Schuff +Mark Miller +Paul Schoenfelder +Dan Gebhardt +Martin Becze +Nathaniel McCallum +Lin Clark +Alex Crichton +Gus Caplan + +Meeting notes: + +Adoption of Agenda: Tyler McMullen seconds + +Action items: None, first meeting! + +Dan: Process is consensus-driven. We want to avoid coming down to a +vote. When there is disagreement we want to find out the reasons why. We +have a straw poll mechanism to help find that out. + +Categorizing our issues: + +Dan: Issues were initially filed on wasmtime issue tracker, now +they’re on the WASI issue tracker. Need a volunteer to summarize, +organize those issues, bring them onto one tracker. + +Ryan Levick volunteers. + +Dan: First thing to go through is go through and label everything. MVP + +Dan: Which issues belong to the MVP, which belong to other milestones. + +High level goals: + +Dan: with the Wasm standard the first thing we wrote was a high +level goals document. Are there any objections or questions? +https://github.com/WebAssembly/WASI/blob/high-level-goals/docs/HighLevel +Goals.md + +Dan: People have asked about threads and many other features that are +not mentioned in these goals. We’ll eventually come up with a design +roadmap to cover those sort of features. + +Nathaniel McCallum: can you define MVP? + +Dan: Smallest thing we can do and still have some value. Specifically: +IO streams, filesystems, randomness, clocks. There’s lots of work to +do on the details of these, test suites etc, but we have people using +this so far and finding it useful. + +Dan: MVP does not include creating sockets. There are a lot of open +questions about how these will work wrt security, portability. + +Nathaniel: if we’re defining MVP as what we first want to ship, this +may be too large. If its the goal for the body overall it may be too +small. + +Dan: We could take out randomness and clocks if you think they don’t +belong. + +Nathaniel: We don’t intend to ship filesystems at all in the first +version of our product. That set of APIs is pretty large. We should trim +down this list to do something small but do it very well. + +Till: There are people here that consider filesystem support a bare +minimum to be useful. This may be a false dilemma, if we modularize the +spec to make filesystems and network io as different modules, we can +move them out of the subgroup and into the main body for standardization +when they are ready. If you need to focus on network rather than +filesystems, you can push on that module separately. Neither need to +block the other. + +Nathaniel: My question isn’t what we seek to do as a working group +versus what MVP means in this context. This seems to be somewhere in +the middle. I’m ok with leaving it as it is but clarification is +useful Dan: As we get into details if we find filesystem is taking a +lot of time we can move it out of the MVP. + +Nathaniel: I’m OK with this. + +Paul S: what is WASI Core? + +Dan: WASI Core is a set of modules, it should have a module for +filesystems, io streams, arguments and environment variables. + +Dan: The idea of WASI Core isn’t an exhaustive list of primitives but +just enough to be useful for a subset of us. + +Luke: Filesystems are have a lot of ways they can be sliced, io streams +to stdout are enough for some applications, so we don’t have to +provide every single part of the API at once. + +Till: We need to specify how modules hang together on a fundamental +level, and then we may not even need MVP beyond that, since modules can +be moved to standardization whenever they are ready. + +Derek Schuff: People here have different ideas of what they consider +minimum viable, so we should come up with the way modules work and +complete two of them that interoperate, and work out the fundamental +modularity problems like dependencies, then the details of what comes in +particular modules can come later. + +Till: We should do enough that the module system is proven out, we +don’t need to define exactly what that means ahead of time + +Nathaniel: This is a good definition of MVP. There doesn’t appear to +be anything about versioning in the high level goals + +Dan: That is an oversight, versioning is an important thing to solve. +Versioning and/or feature detection. + +Luke: There may be room for a new MVP document describing this ideas +about modules, at least two of them work. + +Derek: We need to iterate on what we consider MVP right now, but that +doesn't mean we have the wrong high level goal. + +Dan: Maybe the goals should say: we want to have an MVP and then defer +what that means. MVP is just for a moment in time, it doesn’t stick +around forever. + +Dan: I’ll take action item to take out the details about what modules +from that document, and also to add versioning and feature detection. + +Nathaniel: assent + +Till: Is the scope of this subgroup exhausted once MVP is reached or is +it an ongoing activity to feed modules into the CG? + +Nathaniel: in IETF we specify exactly what we want to accomplish as a +group and then disband it afterwards. I don't know if that is what W3C +asks us to do. + +Dan: The parent WASM CG doesn’t have a concept of when we’re done. + +Luke: The WG does have a charter that they renew periodically, but that +is a formalism. We should be like the CG and have a work stream and not +worry about the higher level details. + +Derek: In C++ they have standing subgroups with an area of focus, WASI +is like that. We can argue in the CG about how we spec the WASI outputs + +Till: So the goal is to move things out of this subgroup into the CG and +WG in the shape of individual proposals, where the initial proposal is +the core spec of how modules work with at least two modules, and then +individual modules go through their own proposal process after that. + +Luke: Reaching the WG is a long way from where we are now. We are going +to radically change some of these APIs once certain WASM features become +widespread. We will iterate a lot + +Dan: There are different levels of standards here. Does that make sense? +There is kind of an unbounded surface area for APIs and the vision for +this subgroup will be to standardize those. I can imagine a structure +with champions following the CG. Right now there is the core features +and in the future we could setup new champions for new features. + +Dan: Moving on to other activities. We should define what the MVP is. +The very minimal thing we could do is something with just two modules. +Anything more than what WASI core is probably too much. How do we decide +what is in there right now that we should take out? + +Nathaniel: Lets pick a small task and accomplish it + +Derek: Do we want to define any kind of process for phases of APIs? We +want to get proposals out there and give people time to try it out. I +get the sense that we will have even more stakeholders than in the CG. +How do we track changes over time and put our stamp of approval on them. + + +Dan: I suggest we start by copying the CG process. Someone should +volunteer to start by copying the CG document and make proposed changes +to it? There are 5 phases. I think this is roughly what we want to +follow It might be too web focuses. + +Derek: I don’t mind taking that on. + +Eric: The thing about MVP is different perspectives about what is M and +what is V. How far apart are we? Its helpful to envision the data points +of the M and V axis. Somebody said “no need to filesystems” someone +else said they are important for a lot of uses. Just one example. We +maybe want list other cases and cather before we judge and refine. + +Til: Do we even need to decide on the set of functionality. If we do +our job right on the fundamental module system then a lot of the actual +development of the individual modules could happen in parallel. They +don’t need to block each other. Obviously the overarching goal is +consistency between modules but independent development might work. + +Nathanial: The module are really our MVP. Module + versions / feature +detection. But I do think polling would be good to decide what to focus +on first. + +Dan: Not so much who wants what, but who is willing to shut up do the +work and get things done. My main worry with filesystem is that once we +start looking at portability seriously that we might want to move it out +of the MVP. But if people really want to move it forward it would still +make sense. Different to minimal, more about the timeline. + +Nathaniel: Why don’t we define MVP and modules plus versioning. And +move to a time-based process where we release say, every 6 months. + +Eric: We are challenging the definition of Viable. I love the idea of +modules and feature definition but I don't think that is viable. We can +define modules with defining any of them. + +Nathanial: We did mention having 2 modules and minimum. And having +reserved names as part of them module system. Even if we don’t ship +a whole bunch of modules it doesn’t mean that there aren’t modules +yet. + +Derek: Users are going to want the ability to define their own APIs so +even a module system is viable even without any “approved” modules. + +Til: Is viable the right terminology? + +Luke: Perhaps MVP is not right. + +Dan: Should we start by defining a module system and some minimal +modules, or should we try to have a few more features. Poll? + +Jlbirch: What can’t we have both? + +Dan: Initially I proposed a bunch of modules such as filesystems etc + +Nathaniel: The idea of an MVP at least in standards language might carry +a bunch of meaning that we might not want. I quite like the idea that +the only thing you need to be standards compliant is the idea of modules +and namespaces + +Eric: me too. + +Luke: Related thing? Do we want the MVP terminology? + +Nathaniel: Should we call it minimal implementation requirements? + +Til: Is some ways is a minimum viable spec. + +Dan: Should we start with the very first stage which includes modules, +namespacing. + +Alex B: I’m coming from the blockchain space, looking at how to +integrate wasm into ethereum. At least the core WASI filesystem spec +doesn’t make sense for us right now. I was confused that the MVP +discussion presented no use cases. I hope to get out of wasi a process +for how to define modules (and versioning) and we will be able to define +modules relevant to the blockchain space. + +Poll Results: SA: 16 A: 3 N: 2 DA: 0 SDA: 0 + +Dan: Should we have an official adjunct meeting at the CG meeting in +spain? + +Pat: The few of us who have spoken previously discussed meeting the day +before the meeting starts. + +Paul: I’m planning on being there and would like to be there. + +Dan: I will take an action item to look into scheduling. + +Dan: we should probably try to do it during the CG meeting. + +Should we do an offline poll to schedule this? + +Dan: Someone open an issue for scheduling in the wasi repo. + +Final discussions: + +Pat: Is this group going to be responsible for maintaining the sysroot +and the SDK that comes with it? I can still keep on doing the work if +needed. + +Dan: My original idea was that it was going to be moved to this group. +It's becoming more clear it should live outside, but open to opinions +here. + +Nathaniel: It might be handy for us to gather a list of people who are +involved in the standards process what they are working on and how they +are using it. The other thing that might be useful for MVP would be to +decide what does it take to standardize a module? + +Dan: I don’t think this has been done before. I would appreciate +proposals. + +Derek: The phase proposal is going to touch on that . If we have some +phase criteria for the advancement of modules. + +Nathaniel: Tests should be part of this process. + +Luke: WG specs and distinct requirement. + +Dan: Thanks everybody. We are open to ideas about how to do versioning +and feature detection. From a2099d5b0c380049e5e17ecacfe83cc84e099344 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 May 2019 14:08:27 -0700 Subject: [PATCH 0027/1772] Add notes for WASI-05-02 --- .../filesystem/meetings/2019/WASI-05-02.md | 315 +++++++++++++++++- 1 file changed, 314 insertions(+), 1 deletion(-) diff --git a/proposals/filesystem/meetings/2019/WASI-05-02.md b/proposals/filesystem/meetings/2019/WASI-05-02.md index 4de0e9ff5..f23ec4f50 100644 --- a/proposals/filesystem/meetings/2019/WASI-05-02.md +++ b/proposals/filesystem/meetings/2019/WASI-05-02.md @@ -61,4 +61,317 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-02.md + +Attendees: + +Dan Gohman +Paul Dworzanski +Christopher Serr +Birch Jr, Johnnie L +Eric Sink +Pat Hickey +Mingqiu Sun +Sam Clegg +Till Schneidereit +Luke Wagner +Ryan Levick +Yoshua Wuyts +Mark McCaskey +Alex Beregszaszi +Tyler McMullen +Derek Schuff +Mark Miller +Paul Schoenfelder +Dan Gebhardt +Martin Becze +Nathaniel McCallum +Lin Clark +Alex Crichton +Gus Caplan + +Meeting notes: + +Adoption of Agenda: Tyler McMullen seconds + +Action items: None, first meeting! + +Dan: Process is consensus-driven. We want to avoid coming down to a +vote. When there is disagreement we want to find out the reasons why. We +have a straw poll mechanism to help find that out. + +Categorizing our issues: + +Dan: Issues were initially filed on wasmtime issue tracker, now +they’re on the WASI issue tracker. Need a volunteer to summarize, +organize those issues, bring them onto one tracker. + +Ryan Levick volunteers. + +Dan: First thing to go through is go through and label everything. MVP + +Dan: Which issues belong to the MVP, which belong to other milestones. + +High level goals: + +Dan: with the Wasm standard the first thing we wrote was a high +level goals document. Are there any objections or questions? +https://github.com/WebAssembly/WASI/blob/high-level-goals/docs/HighLevel +Goals.md + +Dan: People have asked about threads and many other features that are +not mentioned in these goals. We’ll eventually come up with a design +roadmap to cover those sort of features. + +Nathaniel McCallum: can you define MVP? + +Dan: Smallest thing we can do and still have some value. Specifically: +IO streams, filesystems, randomness, clocks. There’s lots of work to +do on the details of these, test suites etc, but we have people using +this so far and finding it useful. + +Dan: MVP does not include creating sockets. There are a lot of open +questions about how these will work wrt security, portability. + +Nathaniel: if we’re defining MVP as what we first want to ship, this +may be too large. If its the goal for the body overall it may be too +small. + +Dan: We could take out randomness and clocks if you think they don’t +belong. + +Nathaniel: We don’t intend to ship filesystems at all in the first +version of our product. That set of APIs is pretty large. We should trim +down this list to do something small but do it very well. + +Till: There are people here that consider filesystem support a bare +minimum to be useful. This may be a false dilemma, if we modularize the +spec to make filesystems and network io as different modules, we can +move them out of the subgroup and into the main body for standardization +when they are ready. If you need to focus on network rather than +filesystems, you can push on that module separately. Neither need to +block the other. + +Nathaniel: My question isn’t what we seek to do as a working group +versus what MVP means in this context. This seems to be somewhere in +the middle. I’m ok with leaving it as it is but clarification is +useful Dan: As we get into details if we find filesystem is taking a +lot of time we can move it out of the MVP. + +Nathaniel: I’m OK with this. + +Paul S: what is WASI Core? + +Dan: WASI Core is a set of modules, it should have a module for +filesystems, io streams, arguments and environment variables. + +Dan: The idea of WASI Core isn’t an exhaustive list of primitives but +just enough to be useful for a subset of us. + +Luke: Filesystems are have a lot of ways they can be sliced, io streams +to stdout are enough for some applications, so we don’t have to +provide every single part of the API at once. + +Till: We need to specify how modules hang together on a fundamental +level, and then we may not even need MVP beyond that, since modules can +be moved to standardization whenever they are ready. + +Derek Schuff: People here have different ideas of what they consider +minimum viable, so we should come up with the way modules work and +complete two of them that interoperate, and work out the fundamental +modularity problems like dependencies, then the details of what comes in +particular modules can come later. + +Till: We should do enough that the module system is proven out, we +don’t need to define exactly what that means ahead of time + +Nathaniel: This is a good definition of MVP. There doesn’t appear to +be anything about versioning in the high level goals + +Dan: That is an oversight, versioning is an important thing to solve. +Versioning and/or feature detection. + +Luke: There may be room for a new MVP document describing this ideas +about modules, at least two of them work. + +Derek: We need to iterate on what we consider MVP right now, but that +doesn't mean we have the wrong high level goal. + +Dan: Maybe the goals should say: we want to have an MVP and then defer +what that means. MVP is just for a moment in time, it doesn’t stick +around forever. + +Dan: I’ll take action item to take out the details about what modules +from that document, and also to add versioning and feature detection. + +Nathaniel: assent + +Till: Is the scope of this subgroup exhausted once MVP is reached or is +it an ongoing activity to feed modules into the CG? + +Nathaniel: in IETF we specify exactly what we want to accomplish as a +group and then disband it afterwards. I don't know if that is what W3C +asks us to do. + +Dan: The parent WASM CG doesn’t have a concept of when we’re done. + +Luke: The WG does have a charter that they renew periodically, but that +is a formalism. We should be like the CG and have a work stream and not +worry about the higher level details. + +Derek: In C++ they have standing subgroups with an area of focus, WASI +is like that. We can argue in the CG about how we spec the WASI outputs + +Till: So the goal is to move things out of this subgroup into the CG and +WG in the shape of individual proposals, where the initial proposal is +the core spec of how modules work with at least two modules, and then +individual modules go through their own proposal process after that. + +Luke: Reaching the WG is a long way from where we are now. We are going +to radically change some of these APIs once certain WASM features become +widespread. We will iterate a lot + +Dan: There are different levels of standards here. Does that make sense? +There is kind of an unbounded surface area for APIs and the vision for +this subgroup will be to standardize those. I can imagine a structure +with champions following the CG. Right now there is the core features +and in the future we could setup new champions for new features. + +Dan: Moving on to other activities. We should define what the MVP is. +The very minimal thing we could do is something with just two modules. +Anything more than what WASI core is probably too much. How do we decide +what is in there right now that we should take out? + +Nathaniel: Lets pick a small task and accomplish it + +Derek: Do we want to define any kind of process for phases of APIs? We +want to get proposals out there and give people time to try it out. I +get the sense that we will have even more stakeholders than in the CG. +How do we track changes over time and put our stamp of approval on them. + + +Dan: I suggest we start by copying the CG process. Someone should +volunteer to start by copying the CG document and make proposed changes +to it? There are 5 phases. I think this is roughly what we want to +follow It might be too web focuses. + +Derek: I don’t mind taking that on. + +Eric: The thing about MVP is different perspectives about what is M and +what is V. How far apart are we? Its helpful to envision the data points +of the M and V axis. Somebody said “no need to filesystems” someone +else said they are important for a lot of uses. Just one example. We +maybe want list other cases and cather before we judge and refine. + +Til: Do we even need to decide on the set of functionality. If we do +our job right on the fundamental module system then a lot of the actual +development of the individual modules could happen in parallel. They +don’t need to block each other. Obviously the overarching goal is +consistency between modules but independent development might work. + +Nathanial: The module are really our MVP. Module + versions / feature +detection. But I do think polling would be good to decide what to focus +on first. + +Dan: Not so much who wants what, but who is willing to shut up do the +work and get things done. My main worry with filesystem is that once we +start looking at portability seriously that we might want to move it out +of the MVP. But if people really want to move it forward it would still +make sense. Different to minimal, more about the timeline. + +Nathaniel: Why don’t we define MVP and modules plus versioning. And +move to a time-based process where we release say, every 6 months. + +Eric: We are challenging the definition of Viable. I love the idea of +modules and feature definition but I don't think that is viable. We can +define modules with defining any of them. + +Nathanial: We did mention having 2 modules and minimum. And having +reserved names as part of them module system. Even if we don’t ship +a whole bunch of modules it doesn’t mean that there aren’t modules +yet. + +Derek: Users are going to want the ability to define their own APIs so +even a module system is viable even without any “approved” modules. + +Til: Is viable the right terminology? + +Luke: Perhaps MVP is not right. + +Dan: Should we start by defining a module system and some minimal +modules, or should we try to have a few more features. Poll? + +Jlbirch: What can’t we have both? + +Dan: Initially I proposed a bunch of modules such as filesystems etc + +Nathaniel: The idea of an MVP at least in standards language might carry +a bunch of meaning that we might not want. I quite like the idea that +the only thing you need to be standards compliant is the idea of modules +and namespaces + +Eric: me too. + +Luke: Related thing? Do we want the MVP terminology? + +Nathaniel: Should we call it minimal implementation requirements? + +Til: Is some ways is a minimum viable spec. + +Dan: Should we start with the very first stage which includes modules, +namespacing. + +Alex B: I’m coming from the blockchain space, looking at how to +integrate wasm into ethereum. At least the core WASI filesystem spec +doesn’t make sense for us right now. I was confused that the MVP +discussion presented no use cases. I hope to get out of wasi a process +for how to define modules (and versioning) and we will be able to define +modules relevant to the blockchain space. + +Poll Results: SA: 16 A: 3 N: 2 DA: 0 SDA: 0 + +Dan: Should we have an official adjunct meeting at the CG meeting in +spain? + +Pat: The few of us who have spoken previously discussed meeting the day +before the meeting starts. + +Paul: I’m planning on being there and would like to be there. + +Dan: I will take an action item to look into scheduling. + +Dan: we should probably try to do it during the CG meeting. + +Should we do an offline poll to schedule this? + +Dan: Someone open an issue for scheduling in the wasi repo. + +Final discussions: + +Pat: Is this group going to be responsible for maintaining the sysroot +and the SDK that comes with it? I can still keep on doing the work if +needed. + +Dan: My original idea was that it was going to be moved to this group. +It's becoming more clear it should live outside, but open to opinions +here. + +Nathaniel: It might be handy for us to gather a list of people who are +involved in the standards process what they are working on and how they +are using it. The other thing that might be useful for MVP would be to +decide what does it take to standardize a module? + +Dan: I don’t think this has been done before. I would appreciate +proposals. + +Derek: The phase proposal is going to touch on that . If we have some +phase criteria for the advancement of modules. + +Nathaniel: Tests should be part of this process. + +Luke: WG specs and distinct requirement. + +Dan: Thanks everybody. We are open to ideas about how to do versioning +and feature detection. From a655fd196c8b8e7b55487db5813ecf2a680b9efd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 10 May 2019 16:47:52 -0700 Subject: [PATCH 0028/1772] Change the MVP to focus just on versioning, feature detection, and namespacing. Per discussion in the WASI-05-02.md meeting change the MVP description to scope it to just versioning, feature detection, and namespacing. --- proposals/clocks/docs/HighLevelGoals.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/proposals/clocks/docs/HighLevelGoals.md b/proposals/clocks/docs/HighLevelGoals.md index d6ddcb95c..e871cfd08 100644 --- a/proposals/clocks/docs/HighLevelGoals.md +++ b/proposals/clocks/docs/HighLevelGoals.md @@ -7,9 +7,8 @@ interact with the outside world, that preserves the essential sandboxed nature of WebAssembly through a [Capability-based] API design. 2. Specify and implement incrementally: - * Start with a Minimum Viable Product (MVP) for the standard, covering I/O - streams, filesystems, randomness, clocks, and program startup and - shutdown. + * Start with a Minimum Viable Product (MVP) for the standard, covering + basic API versioning, feature detection, and namespacing. * Then add additional features, prioritized by feedback and experience. 3. Supplement API designs with documentation and tests, and, when feasible, reference implementations which can be shared between wasm engines. From 118595c63bc912b82058d3554a7b848eee4356a2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 10 May 2019 16:47:52 -0700 Subject: [PATCH 0029/1772] Change the MVP to focus just on versioning, feature detection, and namespacing. Per discussion in the WASI-05-02.md meeting change the MVP description to scope it to just versioning, feature detection, and namespacing. --- proposals/random/docs/HighLevelGoals.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/proposals/random/docs/HighLevelGoals.md b/proposals/random/docs/HighLevelGoals.md index d6ddcb95c..e871cfd08 100644 --- a/proposals/random/docs/HighLevelGoals.md +++ b/proposals/random/docs/HighLevelGoals.md @@ -7,9 +7,8 @@ interact with the outside world, that preserves the essential sandboxed nature of WebAssembly through a [Capability-based] API design. 2. Specify and implement incrementally: - * Start with a Minimum Viable Product (MVP) for the standard, covering I/O - streams, filesystems, randomness, clocks, and program startup and - shutdown. + * Start with a Minimum Viable Product (MVP) for the standard, covering + basic API versioning, feature detection, and namespacing. * Then add additional features, prioritized by feedback and experience. 3. Supplement API designs with documentation and tests, and, when feasible, reference implementations which can be shared between wasm engines. From 7b7b6585396eaa2db84626167aeb82927c301aea Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 10 May 2019 16:47:52 -0700 Subject: [PATCH 0030/1772] Change the MVP to focus just on versioning, feature detection, and namespacing. Per discussion in the WASI-05-02.md meeting change the MVP description to scope it to just versioning, feature detection, and namespacing. --- proposals/filesystem/docs/HighLevelGoals.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/docs/HighLevelGoals.md b/proposals/filesystem/docs/HighLevelGoals.md index d6ddcb95c..e871cfd08 100644 --- a/proposals/filesystem/docs/HighLevelGoals.md +++ b/proposals/filesystem/docs/HighLevelGoals.md @@ -7,9 +7,8 @@ interact with the outside world, that preserves the essential sandboxed nature of WebAssembly through a [Capability-based] API design. 2. Specify and implement incrementally: - * Start with a Minimum Viable Product (MVP) for the standard, covering I/O - streams, filesystems, randomness, clocks, and program startup and - shutdown. + * Start with a Minimum Viable Product (MVP) for the standard, covering + basic API versioning, feature detection, and namespacing. * Then add additional features, prioritized by feedback and experience. 3. Supplement API designs with documentation and tests, and, when feasible, reference implementations which can be shared between wasm engines. From 35f804a8c94ad7aa8fd79f90bf57fceeb02ace1e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 10 May 2019 17:41:20 -0700 Subject: [PATCH 0031/1772] Add a preliminary agenda for the WASI-05-16 meeting. --- proposals/clocks/meetings/2019/WASI-05-16.md | 60 ++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 proposals/clocks/meetings/2019/WASI-05-16.md diff --git a/proposals/clocks/meetings/2019/WASI-05-16.md b/proposals/clocks/meetings/2019/WASI-05-16.md new file mode 100644 index 000000000..5879ff868 --- /dev/null +++ b/proposals/clocks/meetings/2019/WASI-05-16.md @@ -0,0 +1,60 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 16 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 16, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Review of action items from prior meeting. + 1. Updated [High-Level Goals] proposal for WASI + 1. The MVP + * Module system issues: https://github.com/WebAssembly/WASI/labels/module_system + * Versioning vs. feature detection + * [Semver]? + - What about wildcards or other requirement specifications? + - If we do semver, we'll be looking for a volunteer to look into + the specifics and make a concrete proposal. + * Weak imports? + - See https://github.com/WebAssembly/WASI/issues/36 for some ideas. + * Namespacing schemes + - "wasi:name:semver" (https://github.com/WebAssembly/WASI/issues/2#issuecomment-482630978) + - Other suggestions? + +1. Closure + +[High-Level Goals]: https://github.com/WebAssembly/WASI/blob/high-level-goals/docs/HighLevelGoals.md +[Semver]: https://semver.org/ + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. From 29d1522e7a3701108f0e355ed28e39e09a101721 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 10 May 2019 17:41:20 -0700 Subject: [PATCH 0032/1772] Add a preliminary agenda for the WASI-05-16 meeting. --- proposals/random/meetings/2019/WASI-05-16.md | 60 ++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 proposals/random/meetings/2019/WASI-05-16.md diff --git a/proposals/random/meetings/2019/WASI-05-16.md b/proposals/random/meetings/2019/WASI-05-16.md new file mode 100644 index 000000000..5879ff868 --- /dev/null +++ b/proposals/random/meetings/2019/WASI-05-16.md @@ -0,0 +1,60 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 16 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 16, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Review of action items from prior meeting. + 1. Updated [High-Level Goals] proposal for WASI + 1. The MVP + * Module system issues: https://github.com/WebAssembly/WASI/labels/module_system + * Versioning vs. feature detection + * [Semver]? + - What about wildcards or other requirement specifications? + - If we do semver, we'll be looking for a volunteer to look into + the specifics and make a concrete proposal. + * Weak imports? + - See https://github.com/WebAssembly/WASI/issues/36 for some ideas. + * Namespacing schemes + - "wasi:name:semver" (https://github.com/WebAssembly/WASI/issues/2#issuecomment-482630978) + - Other suggestions? + +1. Closure + +[High-Level Goals]: https://github.com/WebAssembly/WASI/blob/high-level-goals/docs/HighLevelGoals.md +[Semver]: https://semver.org/ + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. From d66d4f53bf59c05496653c8f49d9e1e0ab120019 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 10 May 2019 17:41:20 -0700 Subject: [PATCH 0033/1772] Add a preliminary agenda for the WASI-05-16 meeting. --- .../filesystem/meetings/2019/WASI-05-16.md | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 proposals/filesystem/meetings/2019/WASI-05-16.md diff --git a/proposals/filesystem/meetings/2019/WASI-05-16.md b/proposals/filesystem/meetings/2019/WASI-05-16.md new file mode 100644 index 000000000..5879ff868 --- /dev/null +++ b/proposals/filesystem/meetings/2019/WASI-05-16.md @@ -0,0 +1,60 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 16 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 16, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Review of action items from prior meeting. + 1. Updated [High-Level Goals] proposal for WASI + 1. The MVP + * Module system issues: https://github.com/WebAssembly/WASI/labels/module_system + * Versioning vs. feature detection + * [Semver]? + - What about wildcards or other requirement specifications? + - If we do semver, we'll be looking for a volunteer to look into + the specifics and make a concrete proposal. + * Weak imports? + - See https://github.com/WebAssembly/WASI/issues/36 for some ideas. + * Namespacing schemes + - "wasi:name:semver" (https://github.com/WebAssembly/WASI/issues/2#issuecomment-482630978) + - Other suggestions? + +1. Closure + +[High-Level Goals]: https://github.com/WebAssembly/WASI/blob/high-level-goals/docs/HighLevelGoals.md +[Semver]: https://semver.org/ + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. From 164a9dc72c6ed4ad9b2f05fd582ef10540e0e6f3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 May 2019 14:43:04 -0700 Subject: [PATCH 0034/1772] Add a few more agenda items for 05-16. --- proposals/clocks/meetings/2019/WASI-05-16.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proposals/clocks/meetings/2019/WASI-05-16.md b/proposals/clocks/meetings/2019/WASI-05-16.md index 5879ff868..2ddf94b2b 100644 --- a/proposals/clocks/meetings/2019/WASI-05-16.md +++ b/proposals/clocks/meetings/2019/WASI-05-16.md @@ -27,6 +27,9 @@ Installation is required, see the calendar invite. 1. Find volunteers for note taking (acting chair to volunteer) 1. Adoption of the agenda 1. Proposals and discussions + 1. Meeting schedule + * We have one report of a scheduling conflict on Thursdays. How do + Wednesdays at this same time work? 1. Review of action items from prior meeting. 1. Updated [High-Level Goals] proposal for WASI 1. The MVP @@ -41,6 +44,8 @@ Installation is required, see the calendar invite. * Namespacing schemes - "wasi:name:semver" (https://github.com/WebAssembly/WASI/issues/2#issuecomment-482630978) - Other suggestions? + 1. Standardization phases + * https://github.com/WebAssembly/WASI/issues/38 1. Closure From 8c809bc76c952ab7190e2c3f3573ec623a395008 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 May 2019 14:43:04 -0700 Subject: [PATCH 0035/1772] Add a few more agenda items for 05-16. --- proposals/random/meetings/2019/WASI-05-16.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proposals/random/meetings/2019/WASI-05-16.md b/proposals/random/meetings/2019/WASI-05-16.md index 5879ff868..2ddf94b2b 100644 --- a/proposals/random/meetings/2019/WASI-05-16.md +++ b/proposals/random/meetings/2019/WASI-05-16.md @@ -27,6 +27,9 @@ Installation is required, see the calendar invite. 1. Find volunteers for note taking (acting chair to volunteer) 1. Adoption of the agenda 1. Proposals and discussions + 1. Meeting schedule + * We have one report of a scheduling conflict on Thursdays. How do + Wednesdays at this same time work? 1. Review of action items from prior meeting. 1. Updated [High-Level Goals] proposal for WASI 1. The MVP @@ -41,6 +44,8 @@ Installation is required, see the calendar invite. * Namespacing schemes - "wasi:name:semver" (https://github.com/WebAssembly/WASI/issues/2#issuecomment-482630978) - Other suggestions? + 1. Standardization phases + * https://github.com/WebAssembly/WASI/issues/38 1. Closure From 27f91de326647da075340f79758712546342a80b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 May 2019 14:43:04 -0700 Subject: [PATCH 0036/1772] Add a few more agenda items for 05-16. --- proposals/filesystem/meetings/2019/WASI-05-16.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proposals/filesystem/meetings/2019/WASI-05-16.md b/proposals/filesystem/meetings/2019/WASI-05-16.md index 5879ff868..2ddf94b2b 100644 --- a/proposals/filesystem/meetings/2019/WASI-05-16.md +++ b/proposals/filesystem/meetings/2019/WASI-05-16.md @@ -27,6 +27,9 @@ Installation is required, see the calendar invite. 1. Find volunteers for note taking (acting chair to volunteer) 1. Adoption of the agenda 1. Proposals and discussions + 1. Meeting schedule + * We have one report of a scheduling conflict on Thursdays. How do + Wednesdays at this same time work? 1. Review of action items from prior meeting. 1. Updated [High-Level Goals] proposal for WASI 1. The MVP @@ -41,6 +44,8 @@ Installation is required, see the calendar invite. * Namespacing schemes - "wasi:name:semver" (https://github.com/WebAssembly/WASI/issues/2#issuecomment-482630978) - Other suggestions? + 1. Standardization phases + * https://github.com/WebAssembly/WASI/issues/38 1. Closure From 86492e33e73eeab5389e2bb0a25670bd65599934 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 16 May 2019 11:24:24 -0700 Subject: [PATCH 0037/1772] Add May 16 meeting to index Also remove used of embedded html in the md file. It seems somewhat unnecessary. --- proposals/clocks/meetings/README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 99a547333..7c574a041 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -5,9 +5,7 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow ## Meetings -
-2019 +### 2019 - * [WASI May 2nd video call](2019/WASI-05-02.md) - -
+ * [WASI May 2nd video call](2019/WASI-05-02.md) + * [WASI May 16nd video call](2019/WASI-05-16.md) From 152c2290cfc5fd59aed20ac2672068578c10c3fc Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 16 May 2019 11:24:24 -0700 Subject: [PATCH 0038/1772] Add May 16 meeting to index Also remove used of embedded html in the md file. It seems somewhat unnecessary. --- proposals/random/meetings/README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 99a547333..7c574a041 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -5,9 +5,7 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow ## Meetings -
-2019 +### 2019 - * [WASI May 2nd video call](2019/WASI-05-02.md) - -
+ * [WASI May 2nd video call](2019/WASI-05-02.md) + * [WASI May 16nd video call](2019/WASI-05-16.md) From 1ed2b78a80cdd6a6cb809a77d1d4cd0d254eb72f Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 16 May 2019 11:24:24 -0700 Subject: [PATCH 0039/1772] Add May 16 meeting to index Also remove used of embedded html in the md file. It seems somewhat unnecessary. --- proposals/filesystem/meetings/README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 99a547333..7c574a041 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -5,9 +5,7 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow ## Meetings -
-2019 +### 2019 - * [WASI May 2nd video call](2019/WASI-05-02.md) - -
+ * [WASI May 2nd video call](2019/WASI-05-02.md) + * [WASI May 16nd video call](2019/WASI-05-16.md) From 1ea095564adb015d02f3e38943af96b933f042b9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 29 May 2019 15:29:46 -0700 Subject: [PATCH 0040/1772] Add notes for WASI-05-16 (#43) --- proposals/clocks/meetings/2019/WASI-05-16.md | 228 ++++++++++++++++++- 1 file changed, 227 insertions(+), 1 deletion(-) diff --git a/proposals/clocks/meetings/2019/WASI-05-16.md b/proposals/clocks/meetings/2019/WASI-05-16.md index 2ddf94b2b..d0101162b 100644 --- a/proposals/clocks/meetings/2019/WASI-05-16.md +++ b/proposals/clocks/meetings/2019/WASI-05-16.md @@ -62,4 +62,230 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-16.md + +Attendees: + +Dan Gohman +Thomas Lively +Luke Imhoff +Sergey Rubanov +Wouter van Oortmerssen +Jacob Gravelle +Mingqiu Sun +Yury Delendik +Ryan Levick +Paul Dworzanski +Alex Crichton +Derek Schuff +Mark S. Miller +Sam Clegg +Nick Fitzgerald +Arun Purushan +Mark McCaskey +Dan Gebhardt +Paul Schoenfelder +Till Schneidereit +Johnie L Birch Jr +Luke Wagner +Pat Hickey +Tyler McMullen + + +Meeting notes: + + +Meeting schedule +We have one report of a scheduling conflict on Thursdays. How do Wednesdays at this same time work? +Conflicts on Wednesday for Google WASM team +Later on Thursday would work, but it doesn’t work for Europe +FINAL: Sticking with same date/time + + Review of action items from prior meeting. + +Dan: Module system issues are up. +Dan: Also took an action to look for an in-person meeting time, not complete yet. +Ryan: I went through and summarized issues in the WASI issue tracker. We can continue to evolve the organization scheme. I looked at moving issues over from the wasmtime tracker and we may need to dedup them first. +Dan: We will follow up offline. + + +Updated [High-Level Goals] proposal for WASI + +Dan: Derek had a question about the meaning of namespacing. My sense is we don’t need to be terribly specific here. +Derek: I may have added some more words in there, but I think we’re all on the same page. +Dan: We can merge the High Level Goals as is, and folks can do PRs to elaborate on it. Do we have consensus to land it? +Luke Imhoff: It says “through a capability based API”, does that imply a focus on security? +Dan: I think capability-based implies that +Mark Miller: Capabilities enable a design for security, they don’t imply security +Dan: Does the current wording capture enough of the intent to build a secure interface? +Luke I: We want to emphasize that capabilities can be subdivided, are unforgable, so that we’re not no better than posix. +Mark: We could write down the important capability design principles elsewhere. +Luke I: Is there an article that summarizes your current thinking on this? +Mark: There’s related topics on object capabilities +Till: We didn’t go with object capabilities because not all languages are capable of expressing those. +Mark: Object capabilities are not specific to programming language object level capabilities. There are operating systems that use object capabilities +Luke I: Lets merge what we have and make a PR later that describes what we mean by object capability? +Mark: I will find some writing on object capability principles to link to +Till: So we can land what we have now? +Luke I, Mark M assent +Dan: I will take an action item to land that. + +The MVP +Module system issues: https://github.com/WebAssembly/WASI/labels/module_system +Versioning vs. feature detection +[Semver]? +What about wildcards or other requirement specifications? +If we do semver, we'll be looking for a volunteer to look into the specifics and make a concrete proposal. + +Weak imports? +See https://github.com/WebAssembly/WASI/issues/36 for some ideas. +Namespacing schemes +"wasi:name:semver" (https://github.com/WebAssembly/WASI/issues/2#issuecomment-482630978) +Other suggestions? + + +Dan: Looks like things got renamed and moved around a bit, lets skip forward to semver. + +Dan: Semver is the default choice, but the question is how you apply it, what sort of wildcards and specifiers you use when encoding dependencies. + +Dan: What im looking for is someone to make a proposal about how the various details of semver wildcards work, and bring it to the meeting next week. I know there are many options but I don’t know which one to pick. + +Mark: To clarify is this for all of WASI or for the various modules? + +Dan: The goal is to specify the foundation of how modules will interact, this is an important part of that. We will probably have opportunities to revise it + +Luke I: How flexible will we be with regards to revisions to the interfaces? E.g. fixing bugs means breaking binary compat + +Dan: We have to assume that we can impose our own rules for how strict we are about bugfixes. We’ll just have to make judgement calls as we go + +Sam K: Will the version be in the import name themselves? + +Dan: That is an obvious place to put it. has a proposal but they’re out sick today + +Till: This would make it hard to make minor updates, because then you’d have to change names every time a version changes. + +Dan: Resolution of imports happens in the VM. So we can program how that works + +Till: If resolution happens in a client they may not have a complete index of all modules available. + +Dan: The current proposal (wasi:package:semver) assumes all modules are packaged & available together. If we want to have something more elaborate - a url, a hash string, those are possibilities. + +Luke I: Its desirable for the resolver to have some way to find other versions, so that you can specify dependencies as “greater than this patch but not incompatible” + +Till: If resolution has to happen using a map, you can put the version numbers in the map, rather than in identifiers + +Dan: Resolution is necessarily not the host, some earlier packaging step can occur that takes advantage of semantic information + +Luke I: is it always a precise version in the import name? (some examples given) + +Dan: We should make a convention about whether the VM is going to download modules for you, or the VM is going to just resolve links as they exist + +Tlively: It sounds like we have differences in opinion about who should be doing resolution of version numbers to packages, and where packages come from. Before agreeing on specifics we should figure out the user story and what goals we’re trying to achieve with the versioning scheme + +Dan: Sounds good, does anyone want to propose a story or a set of scenarios to look at? + +Pat: I can provide a story for our use case, but I want to get input from others as well. + +Dan: Moving on to the next item, Weak Imports. In Issue 36, there is discussion about not wanting a system that forces an additional indirection e.g. through a GC Ref. + +Sam Klegg: In your example of importing v2 features and then an optional v3 feature + +Dan: V2 to V3 is a major semver bump, If it was a minor bump maybe that would be OK. What about e.g. most features from 2.2, and this new feature from 2.3 would be nice to use if its available, but if not I’ll fall back. + +Luke I: If you’re importing from different versions are those versions separate instances + +Dan: That’s up to the VM and the module API + +Sam K: We don’t want to have two versions of the same module instantiated to satisfy a dep. + +Sam K: Would you put a weak dependency on an entire module, or just on an import? +Dan: I think we want the ability to do both. E.g. If we have a filesystem, then we will use it to do stuff, and also if the filesystem supports this individual extra feature, i’ll use it. In both cases we want to be able to fall back. + +Sam K: Seems like lots of overlap with the semver proposal + +Dan: Semver just gives you the minimum requirement to be functional, weak imports are for things that may or may not be present + +Luke I: Semver protects you from the ABA problem, where the function name and signature stays the same but the functionality totally changed. + +Dan: You could have a weak import, and the weak import itself could have a semver tag on it, or other semver relation operators. I’m looking for a general sense from the group whether this general idea is what we want to pursue. Out of all the proposals it has the advantage of not implying indirection. + +Luke I: Does this mean that wasm is going to have to support weak imports so that there is no indirection cost? + +Dan: It would be a requirement of the engine to implement imports so that there is no indirection cost. + +Sam K: We’re explicitly trying to not push a new concept into the core spec + +Dan: Is there consensus about not trying to push new concepts into the core spec? + +Jacob: are we going to expect this in web embeddings? + +Luke Wagner: You could polyfill this on the web using javascript stubs + +Luke Wagner: Rather than mangling the string name maybe you could use a regex to carve out what part of an import name is the name, and the rest is the wasi-specific specifiers like version, weak + +(Some discussion on details of those ideas) + +Dan: Is the basic idea of weak import, somehow mangled into import names, + +Jacob: We could use custom sections for this. + +(Some discussion of how you might use a custom section) + +Luke I: If the custom section gets stripped thats a bad sign about your toolchain in the first place. I prefer this to string mangling, it doesn’t eat names that now become reserved + +Dan: There are escape characters and ways we can make name mangling work. + +Tlively, Luke I, Sam C: all in support of using custom sections as opposed to name mangling + +Luke I: Import maps are separate from the module itself, or you could put a default map in at build time, but the idea is that it makes polyfill possible + +Sam C: There would be a lot of repetition of these annotation in the import names, custom section could solve that + +Dan: Pushback that custom sections are for non-semantic information + +Paul S: Would this mean we now require those custom sections? + +Sam C: its extra information that says the module would like to have the following version, the following weak sym. The engine could throw it away and it would still possibly work + +Jacob: This is roughly what we’re trying to solve in the webidl proposal as well, we’re specifying a custom section. + +(Some discussion) + +Sam C: You’re describing the environment in which you’d like to be run, and the engine may be able to provide the right implementation there + +Luke I: tooling is easier with custom sections, you won’t have to change imports and byte offsets and so on. + +Luke I: The import map proposal says to just specify the bare name to import, and + +Dan: Does someone want to champion writing down how using a custom section for this will work? + +Sam C: I will write something down for the next meeting [action item] + +Standardization phases +https://github.com/WebAssembly/WASI/issues/38 + +Dan: Derek wrote up a proposal of phases (linked above). In the core wasm they use the concept of web engines implementing a proposal as part of gating moving it forward. We have more non-web embeddings to consider here. + +Luke I: We should document why we made certain arguments about compatibility as we go along. + +Dan: Rationale is important, should that process live in the phase document? + +(?): Maybe when we move to stage 3 with a proposal it should come with an agreement about what stage 4 may be. + +Derek: My desire was just to come up with something that mirrors the CG without specific opinions on exactly how. What do we want the role of the subgroup vs the CG to be? Should the CG just rubber-stamp things? + +Derek: We haven’t talked about the goals for the WASI api spec, should it go through the W3C WG process? + +Dan: That is what I want us to do. + +Till: wrt where it lives exactly, it could be a sibling to the JS API. + +Dan: this is a non-web use case and W3C is a web org but I don’t think its a problem in practice. + +Derek: This is something between the core spec and the JS API. WASI will build on top of core. Maybe some of the WASI loading semantics will be baked into the JS spec, or maybe not. + +Dan: How the individual module specs get packaged into a spec document is something we can resolve in the future. + +Till: Volunteers to champion the phases document From c585c64bc8ff143ee188d3376ef19c8d1880a6af Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 29 May 2019 15:29:46 -0700 Subject: [PATCH 0041/1772] Add notes for WASI-05-16 (#43) --- proposals/random/meetings/2019/WASI-05-16.md | 228 ++++++++++++++++++- 1 file changed, 227 insertions(+), 1 deletion(-) diff --git a/proposals/random/meetings/2019/WASI-05-16.md b/proposals/random/meetings/2019/WASI-05-16.md index 2ddf94b2b..d0101162b 100644 --- a/proposals/random/meetings/2019/WASI-05-16.md +++ b/proposals/random/meetings/2019/WASI-05-16.md @@ -62,4 +62,230 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-16.md + +Attendees: + +Dan Gohman +Thomas Lively +Luke Imhoff +Sergey Rubanov +Wouter van Oortmerssen +Jacob Gravelle +Mingqiu Sun +Yury Delendik +Ryan Levick +Paul Dworzanski +Alex Crichton +Derek Schuff +Mark S. Miller +Sam Clegg +Nick Fitzgerald +Arun Purushan +Mark McCaskey +Dan Gebhardt +Paul Schoenfelder +Till Schneidereit +Johnie L Birch Jr +Luke Wagner +Pat Hickey +Tyler McMullen + + +Meeting notes: + + +Meeting schedule +We have one report of a scheduling conflict on Thursdays. How do Wednesdays at this same time work? +Conflicts on Wednesday for Google WASM team +Later on Thursday would work, but it doesn’t work for Europe +FINAL: Sticking with same date/time + + Review of action items from prior meeting. + +Dan: Module system issues are up. +Dan: Also took an action to look for an in-person meeting time, not complete yet. +Ryan: I went through and summarized issues in the WASI issue tracker. We can continue to evolve the organization scheme. I looked at moving issues over from the wasmtime tracker and we may need to dedup them first. +Dan: We will follow up offline. + + +Updated [High-Level Goals] proposal for WASI + +Dan: Derek had a question about the meaning of namespacing. My sense is we don’t need to be terribly specific here. +Derek: I may have added some more words in there, but I think we’re all on the same page. +Dan: We can merge the High Level Goals as is, and folks can do PRs to elaborate on it. Do we have consensus to land it? +Luke Imhoff: It says “through a capability based API”, does that imply a focus on security? +Dan: I think capability-based implies that +Mark Miller: Capabilities enable a design for security, they don’t imply security +Dan: Does the current wording capture enough of the intent to build a secure interface? +Luke I: We want to emphasize that capabilities can be subdivided, are unforgable, so that we’re not no better than posix. +Mark: We could write down the important capability design principles elsewhere. +Luke I: Is there an article that summarizes your current thinking on this? +Mark: There’s related topics on object capabilities +Till: We didn’t go with object capabilities because not all languages are capable of expressing those. +Mark: Object capabilities are not specific to programming language object level capabilities. There are operating systems that use object capabilities +Luke I: Lets merge what we have and make a PR later that describes what we mean by object capability? +Mark: I will find some writing on object capability principles to link to +Till: So we can land what we have now? +Luke I, Mark M assent +Dan: I will take an action item to land that. + +The MVP +Module system issues: https://github.com/WebAssembly/WASI/labels/module_system +Versioning vs. feature detection +[Semver]? +What about wildcards or other requirement specifications? +If we do semver, we'll be looking for a volunteer to look into the specifics and make a concrete proposal. + +Weak imports? +See https://github.com/WebAssembly/WASI/issues/36 for some ideas. +Namespacing schemes +"wasi:name:semver" (https://github.com/WebAssembly/WASI/issues/2#issuecomment-482630978) +Other suggestions? + + +Dan: Looks like things got renamed and moved around a bit, lets skip forward to semver. + +Dan: Semver is the default choice, but the question is how you apply it, what sort of wildcards and specifiers you use when encoding dependencies. + +Dan: What im looking for is someone to make a proposal about how the various details of semver wildcards work, and bring it to the meeting next week. I know there are many options but I don’t know which one to pick. + +Mark: To clarify is this for all of WASI or for the various modules? + +Dan: The goal is to specify the foundation of how modules will interact, this is an important part of that. We will probably have opportunities to revise it + +Luke I: How flexible will we be with regards to revisions to the interfaces? E.g. fixing bugs means breaking binary compat + +Dan: We have to assume that we can impose our own rules for how strict we are about bugfixes. We’ll just have to make judgement calls as we go + +Sam K: Will the version be in the import name themselves? + +Dan: That is an obvious place to put it. has a proposal but they’re out sick today + +Till: This would make it hard to make minor updates, because then you’d have to change names every time a version changes. + +Dan: Resolution of imports happens in the VM. So we can program how that works + +Till: If resolution happens in a client they may not have a complete index of all modules available. + +Dan: The current proposal (wasi:package:semver) assumes all modules are packaged & available together. If we want to have something more elaborate - a url, a hash string, those are possibilities. + +Luke I: Its desirable for the resolver to have some way to find other versions, so that you can specify dependencies as “greater than this patch but not incompatible” + +Till: If resolution has to happen using a map, you can put the version numbers in the map, rather than in identifiers + +Dan: Resolution is necessarily not the host, some earlier packaging step can occur that takes advantage of semantic information + +Luke I: is it always a precise version in the import name? (some examples given) + +Dan: We should make a convention about whether the VM is going to download modules for you, or the VM is going to just resolve links as they exist + +Tlively: It sounds like we have differences in opinion about who should be doing resolution of version numbers to packages, and where packages come from. Before agreeing on specifics we should figure out the user story and what goals we’re trying to achieve with the versioning scheme + +Dan: Sounds good, does anyone want to propose a story or a set of scenarios to look at? + +Pat: I can provide a story for our use case, but I want to get input from others as well. + +Dan: Moving on to the next item, Weak Imports. In Issue 36, there is discussion about not wanting a system that forces an additional indirection e.g. through a GC Ref. + +Sam Klegg: In your example of importing v2 features and then an optional v3 feature + +Dan: V2 to V3 is a major semver bump, If it was a minor bump maybe that would be OK. What about e.g. most features from 2.2, and this new feature from 2.3 would be nice to use if its available, but if not I’ll fall back. + +Luke I: If you’re importing from different versions are those versions separate instances + +Dan: That’s up to the VM and the module API + +Sam K: We don’t want to have two versions of the same module instantiated to satisfy a dep. + +Sam K: Would you put a weak dependency on an entire module, or just on an import? +Dan: I think we want the ability to do both. E.g. If we have a filesystem, then we will use it to do stuff, and also if the filesystem supports this individual extra feature, i’ll use it. In both cases we want to be able to fall back. + +Sam K: Seems like lots of overlap with the semver proposal + +Dan: Semver just gives you the minimum requirement to be functional, weak imports are for things that may or may not be present + +Luke I: Semver protects you from the ABA problem, where the function name and signature stays the same but the functionality totally changed. + +Dan: You could have a weak import, and the weak import itself could have a semver tag on it, or other semver relation operators. I’m looking for a general sense from the group whether this general idea is what we want to pursue. Out of all the proposals it has the advantage of not implying indirection. + +Luke I: Does this mean that wasm is going to have to support weak imports so that there is no indirection cost? + +Dan: It would be a requirement of the engine to implement imports so that there is no indirection cost. + +Sam K: We’re explicitly trying to not push a new concept into the core spec + +Dan: Is there consensus about not trying to push new concepts into the core spec? + +Jacob: are we going to expect this in web embeddings? + +Luke Wagner: You could polyfill this on the web using javascript stubs + +Luke Wagner: Rather than mangling the string name maybe you could use a regex to carve out what part of an import name is the name, and the rest is the wasi-specific specifiers like version, weak + +(Some discussion on details of those ideas) + +Dan: Is the basic idea of weak import, somehow mangled into import names, + +Jacob: We could use custom sections for this. + +(Some discussion of how you might use a custom section) + +Luke I: If the custom section gets stripped thats a bad sign about your toolchain in the first place. I prefer this to string mangling, it doesn’t eat names that now become reserved + +Dan: There are escape characters and ways we can make name mangling work. + +Tlively, Luke I, Sam C: all in support of using custom sections as opposed to name mangling + +Luke I: Import maps are separate from the module itself, or you could put a default map in at build time, but the idea is that it makes polyfill possible + +Sam C: There would be a lot of repetition of these annotation in the import names, custom section could solve that + +Dan: Pushback that custom sections are for non-semantic information + +Paul S: Would this mean we now require those custom sections? + +Sam C: its extra information that says the module would like to have the following version, the following weak sym. The engine could throw it away and it would still possibly work + +Jacob: This is roughly what we’re trying to solve in the webidl proposal as well, we’re specifying a custom section. + +(Some discussion) + +Sam C: You’re describing the environment in which you’d like to be run, and the engine may be able to provide the right implementation there + +Luke I: tooling is easier with custom sections, you won’t have to change imports and byte offsets and so on. + +Luke I: The import map proposal says to just specify the bare name to import, and + +Dan: Does someone want to champion writing down how using a custom section for this will work? + +Sam C: I will write something down for the next meeting [action item] + +Standardization phases +https://github.com/WebAssembly/WASI/issues/38 + +Dan: Derek wrote up a proposal of phases (linked above). In the core wasm they use the concept of web engines implementing a proposal as part of gating moving it forward. We have more non-web embeddings to consider here. + +Luke I: We should document why we made certain arguments about compatibility as we go along. + +Dan: Rationale is important, should that process live in the phase document? + +(?): Maybe when we move to stage 3 with a proposal it should come with an agreement about what stage 4 may be. + +Derek: My desire was just to come up with something that mirrors the CG without specific opinions on exactly how. What do we want the role of the subgroup vs the CG to be? Should the CG just rubber-stamp things? + +Derek: We haven’t talked about the goals for the WASI api spec, should it go through the W3C WG process? + +Dan: That is what I want us to do. + +Till: wrt where it lives exactly, it could be a sibling to the JS API. + +Dan: this is a non-web use case and W3C is a web org but I don’t think its a problem in practice. + +Derek: This is something between the core spec and the JS API. WASI will build on top of core. Maybe some of the WASI loading semantics will be baked into the JS spec, or maybe not. + +Dan: How the individual module specs get packaged into a spec document is something we can resolve in the future. + +Till: Volunteers to champion the phases document From ae22c555876fcdf0d7c336d9311baa1e1a7daaeb Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 29 May 2019 15:29:46 -0700 Subject: [PATCH 0042/1772] Add notes for WASI-05-16 (#43) --- .../filesystem/meetings/2019/WASI-05-16.md | 228 +++++++++++++++++- 1 file changed, 227 insertions(+), 1 deletion(-) diff --git a/proposals/filesystem/meetings/2019/WASI-05-16.md b/proposals/filesystem/meetings/2019/WASI-05-16.md index 2ddf94b2b..d0101162b 100644 --- a/proposals/filesystem/meetings/2019/WASI-05-16.md +++ b/proposals/filesystem/meetings/2019/WASI-05-16.md @@ -62,4 +62,230 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-16.md + +Attendees: + +Dan Gohman +Thomas Lively +Luke Imhoff +Sergey Rubanov +Wouter van Oortmerssen +Jacob Gravelle +Mingqiu Sun +Yury Delendik +Ryan Levick +Paul Dworzanski +Alex Crichton +Derek Schuff +Mark S. Miller +Sam Clegg +Nick Fitzgerald +Arun Purushan +Mark McCaskey +Dan Gebhardt +Paul Schoenfelder +Till Schneidereit +Johnie L Birch Jr +Luke Wagner +Pat Hickey +Tyler McMullen + + +Meeting notes: + + +Meeting schedule +We have one report of a scheduling conflict on Thursdays. How do Wednesdays at this same time work? +Conflicts on Wednesday for Google WASM team +Later on Thursday would work, but it doesn’t work for Europe +FINAL: Sticking with same date/time + + Review of action items from prior meeting. + +Dan: Module system issues are up. +Dan: Also took an action to look for an in-person meeting time, not complete yet. +Ryan: I went through and summarized issues in the WASI issue tracker. We can continue to evolve the organization scheme. I looked at moving issues over from the wasmtime tracker and we may need to dedup them first. +Dan: We will follow up offline. + + +Updated [High-Level Goals] proposal for WASI + +Dan: Derek had a question about the meaning of namespacing. My sense is we don’t need to be terribly specific here. +Derek: I may have added some more words in there, but I think we’re all on the same page. +Dan: We can merge the High Level Goals as is, and folks can do PRs to elaborate on it. Do we have consensus to land it? +Luke Imhoff: It says “through a capability based API”, does that imply a focus on security? +Dan: I think capability-based implies that +Mark Miller: Capabilities enable a design for security, they don’t imply security +Dan: Does the current wording capture enough of the intent to build a secure interface? +Luke I: We want to emphasize that capabilities can be subdivided, are unforgable, so that we’re not no better than posix. +Mark: We could write down the important capability design principles elsewhere. +Luke I: Is there an article that summarizes your current thinking on this? +Mark: There’s related topics on object capabilities +Till: We didn’t go with object capabilities because not all languages are capable of expressing those. +Mark: Object capabilities are not specific to programming language object level capabilities. There are operating systems that use object capabilities +Luke I: Lets merge what we have and make a PR later that describes what we mean by object capability? +Mark: I will find some writing on object capability principles to link to +Till: So we can land what we have now? +Luke I, Mark M assent +Dan: I will take an action item to land that. + +The MVP +Module system issues: https://github.com/WebAssembly/WASI/labels/module_system +Versioning vs. feature detection +[Semver]? +What about wildcards or other requirement specifications? +If we do semver, we'll be looking for a volunteer to look into the specifics and make a concrete proposal. + +Weak imports? +See https://github.com/WebAssembly/WASI/issues/36 for some ideas. +Namespacing schemes +"wasi:name:semver" (https://github.com/WebAssembly/WASI/issues/2#issuecomment-482630978) +Other suggestions? + + +Dan: Looks like things got renamed and moved around a bit, lets skip forward to semver. + +Dan: Semver is the default choice, but the question is how you apply it, what sort of wildcards and specifiers you use when encoding dependencies. + +Dan: What im looking for is someone to make a proposal about how the various details of semver wildcards work, and bring it to the meeting next week. I know there are many options but I don’t know which one to pick. + +Mark: To clarify is this for all of WASI or for the various modules? + +Dan: The goal is to specify the foundation of how modules will interact, this is an important part of that. We will probably have opportunities to revise it + +Luke I: How flexible will we be with regards to revisions to the interfaces? E.g. fixing bugs means breaking binary compat + +Dan: We have to assume that we can impose our own rules for how strict we are about bugfixes. We’ll just have to make judgement calls as we go + +Sam K: Will the version be in the import name themselves? + +Dan: That is an obvious place to put it. has a proposal but they’re out sick today + +Till: This would make it hard to make minor updates, because then you’d have to change names every time a version changes. + +Dan: Resolution of imports happens in the VM. So we can program how that works + +Till: If resolution happens in a client they may not have a complete index of all modules available. + +Dan: The current proposal (wasi:package:semver) assumes all modules are packaged & available together. If we want to have something more elaborate - a url, a hash string, those are possibilities. + +Luke I: Its desirable for the resolver to have some way to find other versions, so that you can specify dependencies as “greater than this patch but not incompatible” + +Till: If resolution has to happen using a map, you can put the version numbers in the map, rather than in identifiers + +Dan: Resolution is necessarily not the host, some earlier packaging step can occur that takes advantage of semantic information + +Luke I: is it always a precise version in the import name? (some examples given) + +Dan: We should make a convention about whether the VM is going to download modules for you, or the VM is going to just resolve links as they exist + +Tlively: It sounds like we have differences in opinion about who should be doing resolution of version numbers to packages, and where packages come from. Before agreeing on specifics we should figure out the user story and what goals we’re trying to achieve with the versioning scheme + +Dan: Sounds good, does anyone want to propose a story or a set of scenarios to look at? + +Pat: I can provide a story for our use case, but I want to get input from others as well. + +Dan: Moving on to the next item, Weak Imports. In Issue 36, there is discussion about not wanting a system that forces an additional indirection e.g. through a GC Ref. + +Sam Klegg: In your example of importing v2 features and then an optional v3 feature + +Dan: V2 to V3 is a major semver bump, If it was a minor bump maybe that would be OK. What about e.g. most features from 2.2, and this new feature from 2.3 would be nice to use if its available, but if not I’ll fall back. + +Luke I: If you’re importing from different versions are those versions separate instances + +Dan: That’s up to the VM and the module API + +Sam K: We don’t want to have two versions of the same module instantiated to satisfy a dep. + +Sam K: Would you put a weak dependency on an entire module, or just on an import? +Dan: I think we want the ability to do both. E.g. If we have a filesystem, then we will use it to do stuff, and also if the filesystem supports this individual extra feature, i’ll use it. In both cases we want to be able to fall back. + +Sam K: Seems like lots of overlap with the semver proposal + +Dan: Semver just gives you the minimum requirement to be functional, weak imports are for things that may or may not be present + +Luke I: Semver protects you from the ABA problem, where the function name and signature stays the same but the functionality totally changed. + +Dan: You could have a weak import, and the weak import itself could have a semver tag on it, or other semver relation operators. I’m looking for a general sense from the group whether this general idea is what we want to pursue. Out of all the proposals it has the advantage of not implying indirection. + +Luke I: Does this mean that wasm is going to have to support weak imports so that there is no indirection cost? + +Dan: It would be a requirement of the engine to implement imports so that there is no indirection cost. + +Sam K: We’re explicitly trying to not push a new concept into the core spec + +Dan: Is there consensus about not trying to push new concepts into the core spec? + +Jacob: are we going to expect this in web embeddings? + +Luke Wagner: You could polyfill this on the web using javascript stubs + +Luke Wagner: Rather than mangling the string name maybe you could use a regex to carve out what part of an import name is the name, and the rest is the wasi-specific specifiers like version, weak + +(Some discussion on details of those ideas) + +Dan: Is the basic idea of weak import, somehow mangled into import names, + +Jacob: We could use custom sections for this. + +(Some discussion of how you might use a custom section) + +Luke I: If the custom section gets stripped thats a bad sign about your toolchain in the first place. I prefer this to string mangling, it doesn’t eat names that now become reserved + +Dan: There are escape characters and ways we can make name mangling work. + +Tlively, Luke I, Sam C: all in support of using custom sections as opposed to name mangling + +Luke I: Import maps are separate from the module itself, or you could put a default map in at build time, but the idea is that it makes polyfill possible + +Sam C: There would be a lot of repetition of these annotation in the import names, custom section could solve that + +Dan: Pushback that custom sections are for non-semantic information + +Paul S: Would this mean we now require those custom sections? + +Sam C: its extra information that says the module would like to have the following version, the following weak sym. The engine could throw it away and it would still possibly work + +Jacob: This is roughly what we’re trying to solve in the webidl proposal as well, we’re specifying a custom section. + +(Some discussion) + +Sam C: You’re describing the environment in which you’d like to be run, and the engine may be able to provide the right implementation there + +Luke I: tooling is easier with custom sections, you won’t have to change imports and byte offsets and so on. + +Luke I: The import map proposal says to just specify the bare name to import, and + +Dan: Does someone want to champion writing down how using a custom section for this will work? + +Sam C: I will write something down for the next meeting [action item] + +Standardization phases +https://github.com/WebAssembly/WASI/issues/38 + +Dan: Derek wrote up a proposal of phases (linked above). In the core wasm they use the concept of web engines implementing a proposal as part of gating moving it forward. We have more non-web embeddings to consider here. + +Luke I: We should document why we made certain arguments about compatibility as we go along. + +Dan: Rationale is important, should that process live in the phase document? + +(?): Maybe when we move to stage 3 with a proposal it should come with an agreement about what stage 4 may be. + +Derek: My desire was just to come up with something that mirrors the CG without specific opinions on exactly how. What do we want the role of the subgroup vs the CG to be? Should the CG just rubber-stamp things? + +Derek: We haven’t talked about the goals for the WASI api spec, should it go through the W3C WG process? + +Dan: That is what I want us to do. + +Till: wrt where it lives exactly, it could be a sibling to the JS API. + +Dan: this is a non-web use case and W3C is a web org but I don’t think its a problem in practice. + +Derek: This is something between the core spec and the JS API. WASI will build on top of core. Maybe some of the WASI loading semantics will be baked into the JS spec, or maybe not. + +Dan: How the individual module specs get packaged into a spec document is something we can resolve in the future. + +Till: Volunteers to champion the phases document From 2bbc0585b8a80149a11c38d47255a67394768c6c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 29 May 2019 15:59:57 -0700 Subject: [PATCH 0043/1772] Add a preliminary agenda for the WASI-05-30 meeting. (#44) --- proposals/clocks/meetings/2019/WASI-05-30.md | 55 ++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 proposals/clocks/meetings/2019/WASI-05-30.md diff --git a/proposals/clocks/meetings/2019/WASI-05-30.md b/proposals/clocks/meetings/2019/WASI-05-30.md new file mode 100644 index 000000000..6cfa0b63e --- /dev/null +++ b/proposals/clocks/meetings/2019/WASI-05-30.md @@ -0,0 +1,55 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 30 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 30, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Review of action items from prior meeting. + - Import names + 1. Weak imports + - https://github.com/WebAssembly/WASI/issues/36 + - Relationship to core wasm feature testing? + - https://github.com/WebAssembly/design/issues/1280 + - Should we push for weak imports in the core wasm spec? + - Looking for volunteers to draft a weak-import custom section doc + 1. Where should wasi-sysroot live? + - https://github.com/WebAssembly/reference-sysroot/pull/11 + 1. Identify a module for an MVP. + 1. (Time permitting) Plan iteration on additional modules + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. From 4cbd43256a0be323c6b6bb45683990c2624b19aa Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 29 May 2019 15:59:57 -0700 Subject: [PATCH 0044/1772] Add a preliminary agenda for the WASI-05-30 meeting. (#44) --- proposals/random/meetings/2019/WASI-05-30.md | 55 ++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 proposals/random/meetings/2019/WASI-05-30.md diff --git a/proposals/random/meetings/2019/WASI-05-30.md b/proposals/random/meetings/2019/WASI-05-30.md new file mode 100644 index 000000000..6cfa0b63e --- /dev/null +++ b/proposals/random/meetings/2019/WASI-05-30.md @@ -0,0 +1,55 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 30 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 30, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Review of action items from prior meeting. + - Import names + 1. Weak imports + - https://github.com/WebAssembly/WASI/issues/36 + - Relationship to core wasm feature testing? + - https://github.com/WebAssembly/design/issues/1280 + - Should we push for weak imports in the core wasm spec? + - Looking for volunteers to draft a weak-import custom section doc + 1. Where should wasi-sysroot live? + - https://github.com/WebAssembly/reference-sysroot/pull/11 + 1. Identify a module for an MVP. + 1. (Time permitting) Plan iteration on additional modules + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. From 5b4bb5b8838c1e681c8c3c31035343012f254e18 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 29 May 2019 15:59:57 -0700 Subject: [PATCH 0045/1772] Add a preliminary agenda for the WASI-05-30 meeting. (#44) --- .../filesystem/meetings/2019/WASI-05-30.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 proposals/filesystem/meetings/2019/WASI-05-30.md diff --git a/proposals/filesystem/meetings/2019/WASI-05-30.md b/proposals/filesystem/meetings/2019/WASI-05-30.md new file mode 100644 index 000000000..6cfa0b63e --- /dev/null +++ b/proposals/filesystem/meetings/2019/WASI-05-30.md @@ -0,0 +1,55 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 30 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 30, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Review of action items from prior meeting. + - Import names + 1. Weak imports + - https://github.com/WebAssembly/WASI/issues/36 + - Relationship to core wasm feature testing? + - https://github.com/WebAssembly/design/issues/1280 + - Should we push for weak imports in the core wasm spec? + - Looking for volunteers to draft a weak-import custom section doc + 1. Where should wasi-sysroot live? + - https://github.com/WebAssembly/reference-sysroot/pull/11 + 1. Identify a module for an MVP. + 1. (Time permitting) Plan iteration on additional modules + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. From e246e9525a14361960c6560c099a72fb013eec9a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 30 May 2019 08:25:36 -0700 Subject: [PATCH 0046/1772] Add a link to WASI-05-30.md. (#45) --- proposals/clocks/meetings/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 7c574a041..1416e2b28 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -9,3 +9,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 2nd video call](2019/WASI-05-02.md) * [WASI May 16nd video call](2019/WASI-05-16.md) + * [WASI May 30nd video call](2019/WASI-05-30.md) From 972eb1fa204acc83da8a307e92dbe57b58c7d168 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 30 May 2019 08:25:36 -0700 Subject: [PATCH 0047/1772] Add a link to WASI-05-30.md. (#45) --- proposals/random/meetings/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 7c574a041..1416e2b28 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -9,3 +9,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 2nd video call](2019/WASI-05-02.md) * [WASI May 16nd video call](2019/WASI-05-16.md) + * [WASI May 30nd video call](2019/WASI-05-30.md) From 0da2281a75229f2fd736a65b534ac340287e1f55 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 30 May 2019 08:25:36 -0700 Subject: [PATCH 0048/1772] Add a link to WASI-05-30.md. (#45) --- proposals/filesystem/meetings/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 7c574a041..1416e2b28 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -9,3 +9,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 2nd video call](2019/WASI-05-02.md) * [WASI May 16nd video call](2019/WASI-05-16.md) + * [WASI May 30nd video call](2019/WASI-05-30.md) From fbba0a7f693522c7ece3f001a2a6462b22624d16 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 6 Jun 2019 14:56:10 -0700 Subject: [PATCH 0049/1772] Add application-abi describing the current unstable WASI application ABI (#48) --- proposals/clocks/design/application-abi.md | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 proposals/clocks/design/application-abi.md diff --git a/proposals/clocks/design/application-abi.md b/proposals/clocks/design/application-abi.md new file mode 100644 index 000000000..b3156081d --- /dev/null +++ b/proposals/clocks/design/application-abi.md @@ -0,0 +1,37 @@ +WASI Application ABI +==================== + +In addition to the APIs defined by the various WASI [modules](modules.md) there +are also certain expectations that the WASI runtime places on an application +that wishes to be portable across WASI implementations. + +This document describes how a conforming WASI application is expected to behave +in terms of lifecycle (startup, shutdown, etc) and any exports it is expected to +include. + +Current Unstable ABI +-------------------- + +The current WASI unstable ABI specifies only two exports from a WASI +application: + +- `_start` - the program entry point +- `memory` - linear memory used by the program + +The `_start` export must be WebAssembly function and will be used as the program +entry point. This is the default name used by `lld` when linking WebAssembly +modules. The embedder is expected to call this function once the module is +instantiated. + +Many of the current WASI unstable APIs require sharing of linear memory between +the application and the embedder. In order to use any such APIs the WASI module +is expected to export its linear memory under the name `memory`. + +Planned Stable ABI +------------------ + +There is ongoing discussion about what the stable ABI might look like: + +- https://github.com/WebAssembly/WASI/issues/13 +- https://github.com/WebAssembly/WASI/issues/19 +- https://github.com/WebAssembly/WASI/issues/24 From 5c8b7e055192fd487658a6a8e11b878075861fd5 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 6 Jun 2019 14:56:10 -0700 Subject: [PATCH 0050/1772] Add application-abi describing the current unstable WASI application ABI (#48) --- proposals/random/design/application-abi.md | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 proposals/random/design/application-abi.md diff --git a/proposals/random/design/application-abi.md b/proposals/random/design/application-abi.md new file mode 100644 index 000000000..b3156081d --- /dev/null +++ b/proposals/random/design/application-abi.md @@ -0,0 +1,37 @@ +WASI Application ABI +==================== + +In addition to the APIs defined by the various WASI [modules](modules.md) there +are also certain expectations that the WASI runtime places on an application +that wishes to be portable across WASI implementations. + +This document describes how a conforming WASI application is expected to behave +in terms of lifecycle (startup, shutdown, etc) and any exports it is expected to +include. + +Current Unstable ABI +-------------------- + +The current WASI unstable ABI specifies only two exports from a WASI +application: + +- `_start` - the program entry point +- `memory` - linear memory used by the program + +The `_start` export must be WebAssembly function and will be used as the program +entry point. This is the default name used by `lld` when linking WebAssembly +modules. The embedder is expected to call this function once the module is +instantiated. + +Many of the current WASI unstable APIs require sharing of linear memory between +the application and the embedder. In order to use any such APIs the WASI module +is expected to export its linear memory under the name `memory`. + +Planned Stable ABI +------------------ + +There is ongoing discussion about what the stable ABI might look like: + +- https://github.com/WebAssembly/WASI/issues/13 +- https://github.com/WebAssembly/WASI/issues/19 +- https://github.com/WebAssembly/WASI/issues/24 From 142fca32f9c157b4dcef14838874f384b0409273 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 6 Jun 2019 14:56:10 -0700 Subject: [PATCH 0051/1772] Add application-abi describing the current unstable WASI application ABI (#48) --- .../filesystem/design/application-abi.md | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 proposals/filesystem/design/application-abi.md diff --git a/proposals/filesystem/design/application-abi.md b/proposals/filesystem/design/application-abi.md new file mode 100644 index 000000000..b3156081d --- /dev/null +++ b/proposals/filesystem/design/application-abi.md @@ -0,0 +1,37 @@ +WASI Application ABI +==================== + +In addition to the APIs defined by the various WASI [modules](modules.md) there +are also certain expectations that the WASI runtime places on an application +that wishes to be portable across WASI implementations. + +This document describes how a conforming WASI application is expected to behave +in terms of lifecycle (startup, shutdown, etc) and any exports it is expected to +include. + +Current Unstable ABI +-------------------- + +The current WASI unstable ABI specifies only two exports from a WASI +application: + +- `_start` - the program entry point +- `memory` - linear memory used by the program + +The `_start` export must be WebAssembly function and will be used as the program +entry point. This is the default name used by `lld` when linking WebAssembly +modules. The embedder is expected to call this function once the module is +instantiated. + +Many of the current WASI unstable APIs require sharing of linear memory between +the application and the embedder. In order to use any such APIs the WASI module +is expected to export its linear memory under the name `memory`. + +Planned Stable ABI +------------------ + +There is ongoing discussion about what the stable ABI might look like: + +- https://github.com/WebAssembly/WASI/issues/13 +- https://github.com/WebAssembly/WASI/issues/19 +- https://github.com/WebAssembly/WASI/issues/24 From 51571dd9c8736b936790906951e08aa2db4d490e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 7 Jun 2019 20:39:33 +0200 Subject: [PATCH 0052/1772] Add a note that there's no meeting on 06-13. Note that there's no meeting next week as several of us will be at the CG meeting that day. --- proposals/clocks/meetings/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 1416e2b28..437325f9d 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -10,3 +10,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 2nd video call](2019/WASI-05-02.md) * [WASI May 16nd video call](2019/WASI-05-16.md) * [WASI May 30nd video call](2019/WASI-05-30.md) + * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) From 836f3b1d568f06e615b43d30ccb6e387faea5376 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 7 Jun 2019 20:39:33 +0200 Subject: [PATCH 0053/1772] Add a note that there's no meeting on 06-13. Note that there's no meeting next week as several of us will be at the CG meeting that day. --- proposals/random/meetings/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 1416e2b28..437325f9d 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -10,3 +10,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 2nd video call](2019/WASI-05-02.md) * [WASI May 16nd video call](2019/WASI-05-16.md) * [WASI May 30nd video call](2019/WASI-05-30.md) + * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) From c3a54a87cfd50c3616d9ccec8c9075e92ec42d2c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 7 Jun 2019 20:39:33 +0200 Subject: [PATCH 0054/1772] Add a note that there's no meeting on 06-13. Note that there's no meeting next week as several of us will be at the CG meeting that day. --- proposals/filesystem/meetings/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 1416e2b28..437325f9d 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -10,3 +10,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 2nd video call](2019/WASI-05-02.md) * [WASI May 16nd video call](2019/WASI-05-16.md) * [WASI May 30nd video call](2019/WASI-05-30.md) + * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) From 8ce864b940418949bd9b52a9b7eb224fa882953b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 24 Jun 2019 15:11:52 -0700 Subject: [PATCH 0055/1772] Add a preliminary agenda for the WASI-06-27 meeting. --- proposals/clocks/meetings/2019/WASI-06-27.md | 58 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 5 +- 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 proposals/clocks/meetings/2019/WASI-06-27.md diff --git a/proposals/clocks/meetings/2019/WASI-06-27.md b/proposals/clocks/meetings/2019/WASI-06-27.md new file mode 100644 index 000000000..ea93d5ccb --- /dev/null +++ b/proposals/clocks/meetings/2019/WASI-06-27.md @@ -0,0 +1,58 @@ +![WASI logo](/WASI.png) + +## Agenda for the June 27 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: June 27, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Review of action items from prior meeting. + - Import names + - https://github.com/WebAssembly/design/issues/1286 + - Weak imports + - https://github.com/WebAssembly/WASI/pull/47 + 1. Meeting Schedule + - It was pointed out that having the WASI meetings the same week + as the CG meetings is inconvenient for some. Should we change + the schedule? + 1. IDL + - Cap'n Proto: - https://github.com/WebAssembly/WASI/pull/58 + - What action items can we take here? + 1. Blockchain call extension + - https://github.com/WebAssembly/WASI/issues/56 + - Meta-discussion: How should we approach new API proposals? + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 437325f9d..7b7b38256 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -8,6 +8,7 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow ### 2019 * [WASI May 2nd video call](2019/WASI-05-02.md) - * [WASI May 16nd video call](2019/WASI-05-16.md) - * [WASI May 30nd video call](2019/WASI-05-30.md) + * [WASI May 16th video call](2019/WASI-05-16.md) + * [WASI May 30th video call](2019/WASI-05-30.md) * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) + * [WASI June 27th video call](2019/WASI-06-27.md) From 13f417fed7df4c1a4a6b75a818d4b46e454f1755 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 24 Jun 2019 15:11:52 -0700 Subject: [PATCH 0056/1772] Add a preliminary agenda for the WASI-06-27 meeting. --- proposals/random/meetings/2019/WASI-06-27.md | 58 ++++++++++++++++++++ proposals/random/meetings/README.md | 5 +- 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 proposals/random/meetings/2019/WASI-06-27.md diff --git a/proposals/random/meetings/2019/WASI-06-27.md b/proposals/random/meetings/2019/WASI-06-27.md new file mode 100644 index 000000000..ea93d5ccb --- /dev/null +++ b/proposals/random/meetings/2019/WASI-06-27.md @@ -0,0 +1,58 @@ +![WASI logo](/WASI.png) + +## Agenda for the June 27 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: June 27, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Review of action items from prior meeting. + - Import names + - https://github.com/WebAssembly/design/issues/1286 + - Weak imports + - https://github.com/WebAssembly/WASI/pull/47 + 1. Meeting Schedule + - It was pointed out that having the WASI meetings the same week + as the CG meetings is inconvenient for some. Should we change + the schedule? + 1. IDL + - Cap'n Proto: - https://github.com/WebAssembly/WASI/pull/58 + - What action items can we take here? + 1. Blockchain call extension + - https://github.com/WebAssembly/WASI/issues/56 + - Meta-discussion: How should we approach new API proposals? + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 437325f9d..7b7b38256 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -8,6 +8,7 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow ### 2019 * [WASI May 2nd video call](2019/WASI-05-02.md) - * [WASI May 16nd video call](2019/WASI-05-16.md) - * [WASI May 30nd video call](2019/WASI-05-30.md) + * [WASI May 16th video call](2019/WASI-05-16.md) + * [WASI May 30th video call](2019/WASI-05-30.md) * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) + * [WASI June 27th video call](2019/WASI-06-27.md) From 3ef9a275840ac9825d8ec58d35076ef9a1d62513 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 24 Jun 2019 15:11:52 -0700 Subject: [PATCH 0057/1772] Add a preliminary agenda for the WASI-06-27 meeting. --- .../filesystem/meetings/2019/WASI-06-27.md | 58 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 5 +- 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 proposals/filesystem/meetings/2019/WASI-06-27.md diff --git a/proposals/filesystem/meetings/2019/WASI-06-27.md b/proposals/filesystem/meetings/2019/WASI-06-27.md new file mode 100644 index 000000000..ea93d5ccb --- /dev/null +++ b/proposals/filesystem/meetings/2019/WASI-06-27.md @@ -0,0 +1,58 @@ +![WASI logo](/WASI.png) + +## Agenda for the June 27 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: June 27, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Review of action items from prior meeting. + - Import names + - https://github.com/WebAssembly/design/issues/1286 + - Weak imports + - https://github.com/WebAssembly/WASI/pull/47 + 1. Meeting Schedule + - It was pointed out that having the WASI meetings the same week + as the CG meetings is inconvenient for some. Should we change + the schedule? + 1. IDL + - Cap'n Proto: - https://github.com/WebAssembly/WASI/pull/58 + - What action items can we take here? + 1. Blockchain call extension + - https://github.com/WebAssembly/WASI/issues/56 + - Meta-discussion: How should we approach new API proposals? + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 437325f9d..7b7b38256 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -8,6 +8,7 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow ### 2019 * [WASI May 2nd video call](2019/WASI-05-02.md) - * [WASI May 16nd video call](2019/WASI-05-16.md) - * [WASI May 30nd video call](2019/WASI-05-30.md) + * [WASI May 16th video call](2019/WASI-05-16.md) + * [WASI May 30th video call](2019/WASI-05-30.md) * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) + * [WASI June 27th video call](2019/WASI-06-27.md) From 277b632daeb9276d80083cd920dfa4181e08c252 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 17 Jul 2019 22:35:04 -0700 Subject: [PATCH 0058/1772] Add a preliminary agenda for the WASI-07-18 meeting. --- proposals/clocks/meetings/2019/WASI-07-18.md | 56 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 57 insertions(+) create mode 100644 proposals/clocks/meetings/2019/WASI-07-18.md diff --git a/proposals/clocks/meetings/2019/WASI-07-18.md b/proposals/clocks/meetings/2019/WASI-07-18.md new file mode 100644 index 000000000..78e3b2d12 --- /dev/null +++ b/proposals/clocks/meetings/2019/WASI-07-18.md @@ -0,0 +1,56 @@ +![WASI logo](/WASI.png) + +## Agenda for the July 18 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: July 18, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Import names + - https://github.com/WebAssembly/design/issues/1286 + - There's a lot of big-picture design work to be done here. + - To unblock modularization and general design work, can we adopt + a new temporary scheme, still containing "wasi_unstable"? + 1. Weak Imports + - https://github.com/WebAssembly/WASI/issues/36 + 1. IDL + - WatIDL: https://github.com/WebAssembly/WASI/pull/64 + 1. What other blockers do we have before we can start designing new + "wasi_unstable" APIs? + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. + +Action item; reschedule meeting diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 7b7b38256..b5b283c62 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -12,3 +12,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 30th video call](2019/WASI-05-30.md) * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) * [WASI June 27th video call](2019/WASI-06-27.md) + * [WASI July 18th video call](2019/WASI-07-18.md) From f0f4385a10358bf40f0f6f5317d646ffd2936a18 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 17 Jul 2019 22:35:04 -0700 Subject: [PATCH 0059/1772] Add a preliminary agenda for the WASI-07-18 meeting. --- proposals/random/meetings/2019/WASI-07-18.md | 56 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 57 insertions(+) create mode 100644 proposals/random/meetings/2019/WASI-07-18.md diff --git a/proposals/random/meetings/2019/WASI-07-18.md b/proposals/random/meetings/2019/WASI-07-18.md new file mode 100644 index 000000000..78e3b2d12 --- /dev/null +++ b/proposals/random/meetings/2019/WASI-07-18.md @@ -0,0 +1,56 @@ +![WASI logo](/WASI.png) + +## Agenda for the July 18 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: July 18, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Import names + - https://github.com/WebAssembly/design/issues/1286 + - There's a lot of big-picture design work to be done here. + - To unblock modularization and general design work, can we adopt + a new temporary scheme, still containing "wasi_unstable"? + 1. Weak Imports + - https://github.com/WebAssembly/WASI/issues/36 + 1. IDL + - WatIDL: https://github.com/WebAssembly/WASI/pull/64 + 1. What other blockers do we have before we can start designing new + "wasi_unstable" APIs? + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. + +Action item; reschedule meeting diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 7b7b38256..b5b283c62 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -12,3 +12,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 30th video call](2019/WASI-05-30.md) * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) * [WASI June 27th video call](2019/WASI-06-27.md) + * [WASI July 18th video call](2019/WASI-07-18.md) From b178f4ffd935d4f0469501db28013f1c0be8a74f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 17 Jul 2019 22:35:04 -0700 Subject: [PATCH 0060/1772] Add a preliminary agenda for the WASI-07-18 meeting. --- .../filesystem/meetings/2019/WASI-07-18.md | 56 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 57 insertions(+) create mode 100644 proposals/filesystem/meetings/2019/WASI-07-18.md diff --git a/proposals/filesystem/meetings/2019/WASI-07-18.md b/proposals/filesystem/meetings/2019/WASI-07-18.md new file mode 100644 index 000000000..78e3b2d12 --- /dev/null +++ b/proposals/filesystem/meetings/2019/WASI-07-18.md @@ -0,0 +1,56 @@ +![WASI logo](/WASI.png) + +## Agenda for the July 18 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: July 18, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Import names + - https://github.com/WebAssembly/design/issues/1286 + - There's a lot of big-picture design work to be done here. + - To unblock modularization and general design work, can we adopt + a new temporary scheme, still containing "wasi_unstable"? + 1. Weak Imports + - https://github.com/WebAssembly/WASI/issues/36 + 1. IDL + - WatIDL: https://github.com/WebAssembly/WASI/pull/64 + 1. What other blockers do we have before we can start designing new + "wasi_unstable" APIs? + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. + +Action item; reschedule meeting diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 7b7b38256..b5b283c62 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -12,3 +12,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 30th video call](2019/WASI-05-30.md) * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) * [WASI June 27th video call](2019/WASI-06-27.md) + * [WASI July 18th video call](2019/WASI-07-18.md) From 384c85e0e898010fe0cbe6e9579d4e5e5ed596ed Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 12 Aug 2019 16:43:48 -0700 Subject: [PATCH 0061/1772] Add placeholder agenda for the 08-15 meeting. --- proposals/clocks/meetings/2019/WASI-08-15.md | 45 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 46 insertions(+) create mode 100644 proposals/clocks/meetings/2019/WASI-08-15.md diff --git a/proposals/clocks/meetings/2019/WASI-08-15.md b/proposals/clocks/meetings/2019/WASI-08-15.md new file mode 100644 index 000000000..6a7309be6 --- /dev/null +++ b/proposals/clocks/meetings/2019/WASI-08-15.md @@ -0,0 +1,45 @@ +![WASI logo](/WASI.png) + +## Agenda for the August 15 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: August 15, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. + +Action item; reschedule meeting diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index b5b283c62..a32a1cf8e 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -13,3 +13,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) * [WASI June 27th video call](2019/WASI-06-27.md) * [WASI July 18th video call](2019/WASI-07-18.md) + * [WASI August 15th video call](2019/WASI-08-15.md) From 47ae9ce3edc3f1e85c155ae690bdaadf23b9184b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 12 Aug 2019 16:43:48 -0700 Subject: [PATCH 0062/1772] Add placeholder agenda for the 08-15 meeting. --- proposals/random/meetings/2019/WASI-08-15.md | 45 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 46 insertions(+) create mode 100644 proposals/random/meetings/2019/WASI-08-15.md diff --git a/proposals/random/meetings/2019/WASI-08-15.md b/proposals/random/meetings/2019/WASI-08-15.md new file mode 100644 index 000000000..6a7309be6 --- /dev/null +++ b/proposals/random/meetings/2019/WASI-08-15.md @@ -0,0 +1,45 @@ +![WASI logo](/WASI.png) + +## Agenda for the August 15 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: August 15, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. + +Action item; reschedule meeting diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index b5b283c62..a32a1cf8e 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -13,3 +13,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) * [WASI June 27th video call](2019/WASI-06-27.md) * [WASI July 18th video call](2019/WASI-07-18.md) + * [WASI August 15th video call](2019/WASI-08-15.md) From 5010da510276a41821a23777eb8f30ad0c76ceea Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 12 Aug 2019 16:43:48 -0700 Subject: [PATCH 0063/1772] Add placeholder agenda for the 08-15 meeting. --- .../filesystem/meetings/2019/WASI-08-15.md | 45 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 46 insertions(+) create mode 100644 proposals/filesystem/meetings/2019/WASI-08-15.md diff --git a/proposals/filesystem/meetings/2019/WASI-08-15.md b/proposals/filesystem/meetings/2019/WASI-08-15.md new file mode 100644 index 000000000..6a7309be6 --- /dev/null +++ b/proposals/filesystem/meetings/2019/WASI-08-15.md @@ -0,0 +1,45 @@ +![WASI logo](/WASI.png) + +## Agenda for the August 15 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: August 15, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. + +Action item; reschedule meeting diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index b5b283c62..a32a1cf8e 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -13,3 +13,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) * [WASI June 27th video call](2019/WASI-06-27.md) * [WASI July 18th video call](2019/WASI-07-18.md) + * [WASI August 15th video call](2019/WASI-08-15.md) From 3d79c6cdf1b99226ed0ea3755a3a4d8bcd647a02 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 14 Aug 2019 22:35:05 -0700 Subject: [PATCH 0064/1772] Add agenda items for the 08-15 meeting. --- proposals/clocks/meetings/2019/WASI-08-15.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/meetings/2019/WASI-08-15.md b/proposals/clocks/meetings/2019/WASI-08-15.md index 6a7309be6..1159c9324 100644 --- a/proposals/clocks/meetings/2019/WASI-08-15.md +++ b/proposals/clocks/meetings/2019/WASI-08-15.md @@ -27,6 +27,16 @@ Installation is required, see the calendar invite. 1. Find volunteers for note taking (acting chair to volunteer) 1. Adoption of the agenda 1. Proposals and discussions + 1. Weak Imports: https://github.com/WebAssembly/WASI/pull/47#issuecomment-521061962 + 1. Interface description based on Module types + - https://github.com/WebAssembly/WASI/pull/74 + - This is a rough sketch, similar to WatIDL, but stripped down, and is + meant to be just enough to let us start describing API proposals. + 1. Meeting time + - I received a request from someone who would like to present a proposal to hold a meeting at an APAC-friendly time. + - We have been following the CG which held some APAC-friendly meeting times for a while but + [dropped them due to low attendance](https://github.com/WebAssembly/meetings/blob/master/2018/CG-04-03.md#drop-apac-timezone). + - Assuming this works for the presenter, move the time of the next meeting to 08-30 at 06:00–07:00 UTC? (This is 08-29 at 11:00pm in Pacific Time)? 1. Closure @@ -41,5 +51,3 @@ Installation is required, see the calendar invite. ## Meeting Notes Posted after meeting. - -Action item; reschedule meeting From c067b39af986107315dda308aff082f2c1faab9c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 14 Aug 2019 22:35:05 -0700 Subject: [PATCH 0065/1772] Add agenda items for the 08-15 meeting. --- proposals/random/meetings/2019/WASI-08-15.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/proposals/random/meetings/2019/WASI-08-15.md b/proposals/random/meetings/2019/WASI-08-15.md index 6a7309be6..1159c9324 100644 --- a/proposals/random/meetings/2019/WASI-08-15.md +++ b/proposals/random/meetings/2019/WASI-08-15.md @@ -27,6 +27,16 @@ Installation is required, see the calendar invite. 1. Find volunteers for note taking (acting chair to volunteer) 1. Adoption of the agenda 1. Proposals and discussions + 1. Weak Imports: https://github.com/WebAssembly/WASI/pull/47#issuecomment-521061962 + 1. Interface description based on Module types + - https://github.com/WebAssembly/WASI/pull/74 + - This is a rough sketch, similar to WatIDL, but stripped down, and is + meant to be just enough to let us start describing API proposals. + 1. Meeting time + - I received a request from someone who would like to present a proposal to hold a meeting at an APAC-friendly time. + - We have been following the CG which held some APAC-friendly meeting times for a while but + [dropped them due to low attendance](https://github.com/WebAssembly/meetings/blob/master/2018/CG-04-03.md#drop-apac-timezone). + - Assuming this works for the presenter, move the time of the next meeting to 08-30 at 06:00–07:00 UTC? (This is 08-29 at 11:00pm in Pacific Time)? 1. Closure @@ -41,5 +51,3 @@ Installation is required, see the calendar invite. ## Meeting Notes Posted after meeting. - -Action item; reschedule meeting From 64a394a69e9f427906a69235b1e3f1080da44d19 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 14 Aug 2019 22:35:05 -0700 Subject: [PATCH 0066/1772] Add agenda items for the 08-15 meeting. --- proposals/filesystem/meetings/2019/WASI-08-15.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/meetings/2019/WASI-08-15.md b/proposals/filesystem/meetings/2019/WASI-08-15.md index 6a7309be6..1159c9324 100644 --- a/proposals/filesystem/meetings/2019/WASI-08-15.md +++ b/proposals/filesystem/meetings/2019/WASI-08-15.md @@ -27,6 +27,16 @@ Installation is required, see the calendar invite. 1. Find volunteers for note taking (acting chair to volunteer) 1. Adoption of the agenda 1. Proposals and discussions + 1. Weak Imports: https://github.com/WebAssembly/WASI/pull/47#issuecomment-521061962 + 1. Interface description based on Module types + - https://github.com/WebAssembly/WASI/pull/74 + - This is a rough sketch, similar to WatIDL, but stripped down, and is + meant to be just enough to let us start describing API proposals. + 1. Meeting time + - I received a request from someone who would like to present a proposal to hold a meeting at an APAC-friendly time. + - We have been following the CG which held some APAC-friendly meeting times for a while but + [dropped them due to low attendance](https://github.com/WebAssembly/meetings/blob/master/2018/CG-04-03.md#drop-apac-timezone). + - Assuming this works for the presenter, move the time of the next meeting to 08-30 at 06:00–07:00 UTC? (This is 08-29 at 11:00pm in Pacific Time)? 1. Closure @@ -41,5 +51,3 @@ Installation is required, see the calendar invite. ## Meeting Notes Posted after meeting. - -Action item; reschedule meeting From b1e19263e248557123544806f10ba24b671a8267 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 14 Aug 2019 23:31:26 -0700 Subject: [PATCH 0067/1772] Add meeeting notes for previous meetings. --- proposals/clocks/meetings/2019/WASI-05-30.md | 63 +++++- proposals/clocks/meetings/2019/WASI-06-27.md | 185 +++++++++++++++- proposals/clocks/meetings/2019/WASI-07-18.md | 210 ++++++++++++++++++- 3 files changed, 454 insertions(+), 4 deletions(-) diff --git a/proposals/clocks/meetings/2019/WASI-05-30.md b/proposals/clocks/meetings/2019/WASI-05-30.md index 6cfa0b63e..a48231332 100644 --- a/proposals/clocks/meetings/2019/WASI-05-30.md +++ b/proposals/clocks/meetings/2019/WASI-05-30.md @@ -52,4 +52,65 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-30.md + +Attendees: + +Dan Gohman +Luke Imhoff +Alex Crichton +Martin Becze +Mark S. Miler +Pat Hickey +Tyler McMullen +Thomas Lively +Dan Gebhardt +Sam Clegg +Mark McCaskey +Nick Hynes +Nathaniel McCallum +Lin Clark +Yury Delendik +Mingqiu Sun + + +Meeting notes: + +Review action items: + +Sam has a document about import naming. TODO: insert the link here. We’ll discuss it in the next meeting. + +Action item: Sam to send out the import naming document. + +Weak imports: + +“Weak” in this context is not related to weak GC references. + +Desire to avoid depending on GC spec +Depend instead of reference types +Pat and others: push back on depending on reference types which aren’t in wasm MVP and not all tools support yet, causing schedule delays. +Mark Miller: How do capabilities work if we don’t have references? +Discussion of the mechanics of i32 file descriptors, which are forgeable, and which don’t enforce PoLA +Luke Wagner: Multiple tables may help i32-based environments have better granularity. +If you’re using C, you have to trust anyone you share your linear memory with. But other tools and languages and implementation strategies could do better. +Discussion of techniques to achieve various granularities of PoLA. + + +Action item: Sam to write up a name mangling proposal. + +Action item: Mark Miller to write up a vision document for using reference types and reference-counted closures in WASI. + +Existing toolchains for C-family and similar languages don’t use references. They typically need bindings tools to interoperate with reference-using APIs + +Discussion of how bindings work in various languages. + + +Action item: Dan to rename wasi-sysroot to wasi-libc + +Discussion of the WASI repo structure, pros and cons of using multiple repos, inside and outside the org + +Discussion about organizations and repos. Emscripten has its own org. LLVM wasm backend is maintained in a third party repository. Concern about having things in the WebAssembly org might raise the barrier to entry for contributing. Having things in the WebAssembly org may make things easier to find. + +Action item: Mark Miller to write up a vision document for using OCAP in WASI. diff --git a/proposals/clocks/meetings/2019/WASI-06-27.md b/proposals/clocks/meetings/2019/WASI-06-27.md index ea93d5ccb..af55fe748 100644 --- a/proposals/clocks/meetings/2019/WASI-06-27.md +++ b/proposals/clocks/meetings/2019/WASI-06-27.md @@ -55,4 +55,187 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-06-27 WebAssembly CG WASI Subgroup Video Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-06-27.md + +Attendees: + +Dan Gohman +Luke Imhoff +Sergey Rubanov +Paul Dworzanski +Pat Hickey +Alex Crichton +Martin Becze +Till Schneidereit +Lin Clark +Mark Miller +Mark McCaskey +Sam Clegg +Nick Hynes +Jakub Konka +Jlbirch +vwo + +Meeting notes: + +DG: Second agenda: +Luke Imhoff seconded. (Till seconds for posterity) + +DG: Import names Proposal: presenter is not here, lets move on to the Weak imports proposal + +SC: We talked about the weak imports proposal at the Wasm CG meeting about whether to represent weakness in the function name versus a custom section. + +DG: … align with the (missed it) proposal + +SC: I can update the proposal to go back to being a custom section. The function is imported as normal but whether or not it is allowed to be missing at runtime is specified in a custom section + +DG: This allows us to skip all the questions about name mangling, polluting the import/export space + +SC: One issue is that the embedders will have programmatic access to the module versus parsing the bytes, e.g. through the javascript api. + +DG: It makes sense for there to be a custom section javascript api that can do this for you. + +SC: I’ll update the PR to go back to custom sections + +DG: What is the point where we can establish a baseline for modularity and move on to breaking up the stuff currently known as wasi core into modules? + +LI: Will the JS embedding have a weak imports attribute on imports? What about support in all the browsers? + +DG: If someone doesnt support the custom section then they just have to resolve all of the weak imports, and if they cant provide all imports then instantiation will fail. + +LI: Can toolchains ship js that detect that instantiation failed, and use a different binary? + +SC: The point of weak imports is that only a single binary is needed + +DG: In web use cases browsers might not support the weak imports natively but you’ll be shipping a JS polyfill for those to implement WASI anyway. You either support WASI or you don’t. Supporting WASI includes support for weak imports. + +LI: Will there be a document that explains the layering of these various features required to support WASI? + +DG: Sam’s document is a start on that. We need to do more to clarify on the layering. Sam, Can you add more to the document to show how it fits into the bigger picture? + +SC: Yes it makes sense to make all of that part of the core wasi spec. The things we’re talking about being in the core so far are the import system, modularity, naming conventions, application lifecycle + +DG: This will be easier to do once we have more of the import stuff in place. I’m proposing we defer more explanation until we have the import system figured out. + +LI: There was back-and-forth about different patterns of WASI modules, reactor and command, in the spec - was there more discussion about that? + +DG: That is ongoing. This can be an adjunct to snowman bindings - the reactor and command model can be adjunct to the spec about bindings, since bindings are specifically about how to use a module, and so is a description of the lifecycle + +SC: ES6 Modules need the same sort of lifecycle support as WASI does + +DG: We’ll also want a custom section to say the entry points of applications and so on. + +LI: Where do I subscribe to updates on this, how far is it in chromium or mozilla? + +DG: I don’t know about that, https://github.com/WebAssembly/esm-integration tracks the ESM integration status but nobody here knows about the status of it in browsers right now. + +TS: The status of Node is they have almost complete implementation. I’m not aware of browser implementations that have made significant progress. + +LC: I’m not aware of any advances of implementations, apple had an early implementation but i’m not aware of updates given the changes to the proposal. + +DG: Let’s move on to the next item, left out of the agenda: last meeting Mark Miller discussed a vision document that laid out the use of Object Capabilities (OCap) in wasi. + +MM: Yes thanks for the reminder. It had dropped out of mind. + +DG: That’s ok we’re all busy here. + +MM: At the wasm blockchain meeting we discussed styles of ocap systems that do not support virtualizability, versus method style, where the behavior of a call on an object is up to the implementer. (...) and I looked at using a Capnp-like IDL to describe APIs in an object style. (unintelligible) looked at an IDL that could fetch type bindings and an adaptor from old style bindings to new style, to realize the virtualizaiblity of ocap systems. + +TS: Mark you’re dropping out a third of the time unfortunately. + +MM: Ok I will put my concerns in the document that I need to write. + +DG: Mark and I discussed this and it is a big idea that I think needs to be explained in detail. + +DG: At the CG we had feedback on the meeting schedule. Right now we’re on the same week as the Wasm meeting, an arbitrary choice. Would people prefer to change it to the opposite week? + +LI: I’m the one that brought it up, it would be nice to have more open time around lunch on these weeks (in my time zone). + +DG: As a poll, does anyone object to moving it to the opposite week from the CG meeting? + +(no objections) +DG: Then we’ll skip next week, the next meeting will be scheduled for 3 weeks out so that it alternates with the WASM CG call. + +DG: We also have an agenda item for talking about the CapnP issue: https://github.com/WebAssembly/WASI/issues/56, Martin can you fill us in: + +MB: I prototyped what it would look like to describe the interface in terms of capnp, we got feedback on that which was helpful. The impression I got from everyone is that customizing the Capnp idl is appropriate, we’ll write a custom IDL that is influenced by capnp and I’m working on that right now. + +MM: You saw my attempt at a BNF of the relevant subset of Capnp? + +MB: Yes I want to rework my pull request with that in mind. We want to pull out the versioning integers on all of the methods, and adding (missed it). It would be nice if we could express things like the ability to import globals, memories, tables, as well as functions. It would be nice if it looked like the rest of the webassembly stack, so I was looking at using s-expressions. + +MB: We need to figure out how this maps to the snowman bindings, I talked to Dan who explained more about how that worked. I see the point of the snowman bindings now. I think it would be interesting to reuse the ideas from the GC proposal re defining structs and so on, and having a binding section from the snowman proposal to describe how they are bound. + +TS: Martin, the original motivation of snowman bindings (prev webidl bindings prev host bindings) was to make DOM apis fast, interacting with them directly from wasm rather than going through javascript. While by now we have lots of reasons to want these bindings, that is still a requirement of the snowman bindings. How are you making sure that your work stays compatible with that, or are you focusing on the syntax layer and it won’t interfere with that? + +MB: I’m not considering how we’re binding to JavaScript, just interested in how to express the structures that these interfaces pass around - e.g. how do we express the structure of a directory entry and how do we read and write to it? That is partially covered by what snowman bindings does so we should reuse that. Maybe snowman bindings does cover everything we need. But the syntax should look like everything else + +TS: It seems like the syntax is purely in the tooling space + +MB: We have the syntax from GC to express struct and arrays, I think that's all we need to express things like directory entries. I want to reuse that syntax, and use that as a path for compatibility with GC implementations in the future. + +DG: Take the set of bindings and types we have in wasi core as the base language, and the IDL describes what those are and gives us the clean descriptions we want + +MB: The tooling is a big hurdle in webidl right now, we want to make it easier for people to read and write these descriptions. + +TS: That makes sense. Luke wagner has had a lot of conversations around this, including with all the webidl people. They are all open to improving things. Its clear that snowman bindings won't be webidl bindings, but they need to be semantically compatible enough to describe the dom bindings pieces. If we end up having different surface syntaxes, thats fine because its mostly about tooling, but I also think we should have something that is not gratuitously different. One constraint is that browser implementers will have to be able to consume webidl in order to make the dom bindings work (already used throughout browsers). Keep in mind that there are constraints that don’t allow us to completely evolve this tooling in ways that break the DOM bindings use case. + +DG: If you can go with whats in snowman bindings now, and build on top of that, then we can achieve the parity we’re going for without defining new semantics. The key vocabulary is the types and the operations. Webidl has a lot of things in it that are distracting, even if you reduce it down to just the parts we need there are still syntax things like how “unsigned long” is the way to write u64, so i’m sympathetic to changing that syntax. + +MM: When I did my minimal BNF subset of capnp, I did take a look at the WASI ABI document and all of the capnp names for the types like u64 seemed obviously much better. I did not include wasm-specific concepts like memory, I agree that's an important thing to figure out how to accommodate. + +DG: Actions going forward: martin will take the capnp PR and make a version with the new syntax. + +MB: I will get that done in the next week and get more feedback. + +MM: There is a long term issue of how we support, at the wasm level, how we manage method dispatch. There are several ways we could map that to the current wasm, none of which are very natural. This problem goes away with GC but I continue to assume that is a long ways out. The smallest step from where we are to a natural method dispatch binding would be to add sum types, where sum types are passed on the stack rather than by separate allocation of reference counts, and the message - the thing that one invokes - would be a sum type where the constructor is the method name, and the contents of that branch of the sum type are the arguments, and the pattern match at the receiver would be the method dispatch. Given that we’re doing an IDL we dont have to decide up-front what the method dispatch representation is, but it would be good to have a candidate in mind. + +DG: My understanding is that not everyone has seen material on dynamic dispatch, so it would be a good thing to start with a paper on how dynamic dispatch works and what use cases it has +MB: Once we have proper function references doesn’t that cover? Are sum types part of GC? + +MM: The repr of sum types I’m thinking of would not require dynamic allocation so we could implement it before GC. It would still be a significant additional piece of engineering. The problem with just using function pointers is that method dispatch with what we have now, the options are 1. You pass by copy a record of function references, and the client of the object invokes a method by looking up the method name in that record, the problem with that is the size of the reference to the object is passed by copy and proportional in size to the num of methods on the type. +2. You pass by reference a … it loses the static type information given our current system, so you’d have to cast after the method lookup to the right signature. +None of these are natural for intra-module communication given the current wasm representation of things. + +DG: One thing we talked about was virtualizing an API and how we might do that. Dynamic dispatch approach allows you to virtualize in more ways. There are a lot of new ideas here and we need to motivate what problems we’re solving here and spread the ideas more broadly. + +DG: Lets move on to the next issue, the blockchain call extension. The main thing I want to address is the meta-discussion of whether this digs inside wasi. Nick are you here? + +DG: I encourage folks in the blockchain space to submit proposals, it fits well with our modularization story. It is a bit ahead of the curve as we’re still figuring out how imports and weak import names and so on. + +DG: Implementers of wasi that don’t have anything to do with blockchain wouldn’t have to implement these interfaces but its good to have the standard for how they work all in one system. + +NH: (missed it) + +MB: It would be nice if we had an interface for persistently storing function references and loading them. One idea is that we could extend the number of file types to one that could load a function reference and put it into an anyfunc table. This would require the call-ref operation to call the method, from in the function refs proposal. + +MB: The file types we have now are a file, directory, block device, character device. Are there problems with extending those filetypes? + +DG: Part of that question we might not quite be ready to answer yet. Does anyone have problems with extending the idea of a stream beyond posix-style streams? + +LI: If plan 9 could do it we can to +DG: We can talk more about stream APIs but I think extending streams to be useful for blockchains is a good idea, as long as it does not incur a cost to implementors that dont need blockchain. + +LI: We say blockchain but is any o f that not descended from etherium? + +NH: I want to generalize this in way for systems beyond etherium descendents + +MB: I worked on ewasm and dfinity, I also want this interface to work beyond etherium family as well. + +MM: The plan at agoric for using blockchain and wasm is not etherium-like, it is consistent with ocap approach, and the issue of dynamic dispatch becomes important to us. + +DG: For some context there's discussion in the CG about webvms and the requirement for 2 implementations that are webvms. In wasi we’ve decided that the committee would accept non webvm implementations and make decisions on what exact vms would be accepted as we go + +LI: Whatever system we come up with should handle more than just one currency, it should handle multiple currencies on a single chain + +MB: We should standardize that we aren’t dealing with one particular currency. This would probably be a good document to put together. + +DG: We should record our thoughts on what requirements we have for blockchains. Martin can you write up … we want diversity, we want to make sure we’re standardizing on something that more than one implementation will use. + +NH and MB will collaborate on that document. + +DG: Any further items? + +Meeting adjourned diff --git a/proposals/clocks/meetings/2019/WASI-07-18.md b/proposals/clocks/meetings/2019/WASI-07-18.md index 78e3b2d12..6d275e700 100644 --- a/proposals/clocks/meetings/2019/WASI-07-18.md +++ b/proposals/clocks/meetings/2019/WASI-07-18.md @@ -51,6 +51,212 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-07-18 WebAssembly CG WASI Subgroup Video Meeting Notes -Action item; reschedule meeting +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-07-18.md + +Attendees: + +Dan Gohman +Martin Becze +Mark McCaskey +Alex Crichton +Andrew Brown +Sam Clegg +Yury Delendik +Arun Purushan +Pat Hickey +Jacob Gravelle +Luke Wagner +Till Schneidereit +Luke Imhoff + +Meeting notes: + +Pat - agenda seconded + +DG: +Import resolution outside of the scope of WASI. + +Pick naming convention that involves the name wasi_unstable + a possible additional identifier, to allow us to continue designing APIs. + +SC: wasi_unstable implies a bulk rename in the future + +DG: agreeing but bringing up additional prefix to clarify. Does anyone have an opinion. Suggested wasi_unstable/ + +_ : Is there any reason to use a / + +DG: We want to split the existing wasi_unstable into multiple modules, :, $, the specific character doesn’t matter. + +DG: is there a problem with / + +_ : Agreeing that separator doesn’t matter, but we should move everything into namespaces + +DG: it will allow us to start design work on other APIs… + +DG: wasi_unstable/identifier is the current proposal. We’ll call that a decision, we can use that to unblock things and start modularizing things. We’ll start queueing up those issues for the next meetings. Let’s have those issues and we’ll start tagging them. Part of that work will be deciding what goes in what modules + +DG: next agenda item. Weak imports + +SC: I got as far as implementing the custom section and realized that there’s quite a lot of redundancy, we’ll have a global corresponding to each global import. All we need is a way of finding that list of globals, we’ll probably use name mangling, so all we need to do is specify the suffix and the runtime can find all imports matching that pattern. Name mangling just for is_present. It would just be a simple custom section saying “is present” + +DG: that strikes me as overkill + +SC: (something)… we can find all weak imports by looking for that suffix + +SC: someone asked why we weren’t going forward with the official Wasm spec proposal of weak imports + +DG: one possibility is that we can take weak imports as being in the same bucket as snowman bindings. It’s a way of describing an interface to Wasm, so maybe we should put it in the snowman bindings custom section. If that’s the case, we can roll it into the snowman bindings proposal. I think it aligns pretty well with the snowman bindings things, because it’s a custom section, and (justification regarding name mangling) + +PH: if you have a whole bunch of weak imports, you can map them to the same global if you want to. So that’s an advantage of a custom section + +SC: what does that mean, if anyone of them is missing + +PH: that’s useful if you’re importing an entire module of things + +SC: that’s useful for all-or-none situations + +SC: yeah, I like it + +DG: alright, so with that, I’ll put that to the group, is this a good way to go forward, put it in a custom section and roll it into snowman bindings? + +(Luke allegedly nods head) + +SC: I don’t see how it fits into snowman bindings +DG: it’s part of a custom section that is the interpretation of the module; it’s not quite the same thing but it’s in the same category. It would be in a different part of the custom section, and eventually things like specifying the entry point + +LW: (missed)... this is in the same kind of layer + +SC: that makes sense when you put it like that + +DG: does anyone want to comment on the issue then? Someone in the WASI repo brought up the question of using a custom section + +J: if that is the case then we should put it in the webidl bindings repo + +LW: the webidl bindings repo is itself a layer of …. + +J: should add assuming it does exist (snowman bindings) + +PH: there’s a large overlap in the people working on both, so it’s probably a non-issue + +J: do we want to use weak imports for something else? Mentioning it there will get more eyes on it. Weak imports in contexts outside of WASI + +… + +SC: should I keep going with specing that in the WASI repo? + +DG: yeah, for now.. We’ll figure it out as it goes + +DG: next agenda item: WAT IDL proposal + +M: So where we got stuck last week is with conflating two things, the way watidl was written made the interface an object, that’s a mistake because an interface is a Wasm module. I rewrote it and I’ll push up the changes today. We should take a key from webidl we can add the extra field that this is a method and then we know that the bindings need to bind some sort of context, so I’ll introduce a method field. It’s also important to remember what the whole point of this was which was partially virtualization, ideally we should be able to have an IDL that Wasm binaries can bind to in two different ways, one using aztrack? Data ADT where all the functions are imported, the other way that would be easy to virtualize, I’m also trying to, I wrote up a little doc on how to do virtualization which I’ll throw up today, so that’s where we’re at with watidl. + +LW: what does virtualization specifically mean? You’ve requested to import this fn but I’ll give you a virtualized one instead + +M: the ability for a Wasm module that a Wasm module can implement a given interface and another module can use that, there’s 2 types of virt. Static: another module importing fd_close, open, sync, which another imports. Dynamic: a module being able to on the fly create a file descriptor or implement it to hand to another module, which is what I meant + +LW: do you mean as a reference to a struct that contains fn refs? + +M: yeah, exactly. SO in that case, the WASI interface, ref to structs of fns, you would just import types at that point. It would be nice to have an IDL that can describe both ways of interacting. + +LW: and who would use the IDL? + +M: used to describe interface and then you’d write bindings. + +LW: so this would be the interface of WASI? + +M: yeah + +LW: would this be equivalent to a list of Wasm function signatures that would be allowed to use snowman binding types in their signatures along with module and field name + +M: list of functions of types, it’s pretty basic + +LW: If we go the snowman bindings format and have a Wasm style and there were fn sigs that could use these types instead of core Wasm types. What if I make a module that just describes the interface… just a subset of the text format. + +M: that’s pretty much what this is + the addition of whether a function can be virtualized or not + +LW: that has some pretty significant runtime and compile time implications + +M: We don’t even have structs or fields, we need partial GC and func ref before we can do dynamic dispatch properly anyways, so we’re looking ahead. + +LW: thanks for explaining that + +M: it’s the text format - bodies, just types and function signatures + +MM: Wasm interfaces are overlapping, we should consolidate these or figure out what’s going on +SC: virtualization isn’t needed for what we need right now, so maybe we shouldn’t push on that too hard if we don’t need it right now. + +M: agreement/partial agreement + +M: I think virt. Is important in a context where you have multiple untrusted modules working together. As WASI is now, it’s generally a single module, they can add object capabilities to each other. In that context it’s not as useful, once we have func refs, …. Then the capab to virt interfaces is more important + +TS: I thought that was a different layer, instead of the runtime built-in you use this instead. I don’t see how that would interact with the IDL, can you explain that more? + +SC: you’re talking about interposition vs method calls, interposition is like intercepting a method call. + +M: Are you all familiar with ADT style? RIght now everything is ADT style, so you can’t really virtualize ADT style. A module can’t really implement those functions, it can’t generate them on the fly. So to be able to generate or implement a file descriptor, that’s /udev/random , so a module can do this and generate a FD on the file when requested by creating a struct and hand it off to the requester, why this matters at an IDL level is, a module may only want to use OO interface and in that scenario, you’d only implement types and the entrypoint fn would only receive capabilities, references to structs which point to functions. One use case for an IDL here is the host system would know that the module wants OO type vs ADT style, does that make sense? + +TS: I think so, thanks for the clarification + +M: that said, since we don’t have, since it’s not given we don’t have GC or func ref, (func ref?) looks more promising, it might not be worthwhile to worry about this. It might not be worth worrying about this yet and just focus on ADT style + +DG: as far as next steps, martin you mentioned that you’ll post an updated version of the proposal? + +M: yep + +DG: we’ll iterate from there. Anything else we want to cover in this meeting? + +M: I also wrote up some stuff about virtualization, should I add that to the repo? + +DG: Sure, make a PR and we can discuss it and decide if we want to incorporate it + +DG: that’s a good point, virt. Is an interesting enough point that we should document what we’re going to do in this space + +DG: next on the agenda, with the theme of setting up the wasi_unstable namespace, what are the blockers that we have before we can split up wasi_unstable into modules and working on them. Having an IDL nicer than a C header file or markdown is good, are there other blockers? + +LW: do you think we should hold off until we can make use of reference types and type imports? Or do we want to do it later + +DG: I think that’s something we can deal with later. When we have full snowman bindings, we’ll want to convert them into that form, and emulating lower level concepts with our higher level types. We need to figure out what is a file and that doesn’t need to wait for (those things) + +TS: maybe we should say that the changes we make going forward should take these concepts into mind, (describes using indirection of fds in a table of anyref to make transition easier) + +DG: that seems reasonable and I think that will somewhat naturally fallout given API design. We want a vocab to talk about things until we have an actual IDL, we can do API design with C headers but it’s not ideal, so we should figure out what to do there. MAking it easier to migrate to future bindings systems seems great + +TS: two advantages, we can do API design now knowing thta API design can map well, later on we have a straight forward way to make it easy to consume in C/CPP/Rust. Two APIs with the AnyRef being the fundamental and an indice-only one on top of it + +DG: how much do we want to do now vs waiting for snowman bindings? If we just design with this in mind, it will be pretty straight forward to retro fit this, that’s my gut feeling here. + +TS: All I’m proposing is making that explicit that we want to have this 1-to-1 relationship, making that relationship straight-forward + +DG: should we have a document about “How to design a WASI API” + +M: that sounds like a good idea + +DG: martin or till do you want to start a document like that? + +TS: I can start that document by writing what I just said and then we can flesh it out with more content + +DG: it can evolve as we get snowman bindings and other tools + +LW: it might be good to have a “future intended steps” section. The intent to move to ref types and binding types are only in our own heads and we should document that somewhere + +DG: looking for someone to document OCAP vision and put it in a repo, if someone wants to do that, that’d be great. It’s been discussed in various places, but we don’t have a document in the repo describing the plan. IF someone could digest that down and start that, that’s what we’re looking for + +LW: I can help there + +DG: we have the docs directory in the WASI repo. Alright, I’m trying to push forward to the point where we can do API design. Are there any other blockers? We’ll have a document, (somethinG) in progress, and a plan … for a module naming system, temporary one, pending discussion about import naming schemes. That’s the end of the agenda. Is there anything else? + +SC: presumably we’ll need an IDL to header file conversion after, +DG: yes (..) + rust interface generation + +M: … +LW: … +TS: s-expressions as type definitions minus the body is the obvious way to define the functions. WHat’s missing is how to fit the binding expressions in there + +LW: importantly, binding expressions don’t fit in there, interface is just the types + +M: to generate a header file, you’d need the IDL and the bindings and they do need to be separate because different languages want different bindings + +LW: I’m not quite sure what you mean by supplying the bindings. You could generate for say, C, there’d be policy choices like what to do with strings, but it’s possible. Sounds like a cool tool though + +DG: that sounds like the end of the meeting, see you all in 2 weeks From 0341c43b738f7a86c8f9e9e7bded523a679ed4c2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 14 Aug 2019 23:31:26 -0700 Subject: [PATCH 0068/1772] Add meeeting notes for previous meetings. --- proposals/random/meetings/2019/WASI-05-30.md | 63 +++++- proposals/random/meetings/2019/WASI-06-27.md | 185 +++++++++++++++- proposals/random/meetings/2019/WASI-07-18.md | 210 ++++++++++++++++++- 3 files changed, 454 insertions(+), 4 deletions(-) diff --git a/proposals/random/meetings/2019/WASI-05-30.md b/proposals/random/meetings/2019/WASI-05-30.md index 6cfa0b63e..a48231332 100644 --- a/proposals/random/meetings/2019/WASI-05-30.md +++ b/proposals/random/meetings/2019/WASI-05-30.md @@ -52,4 +52,65 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-30.md + +Attendees: + +Dan Gohman +Luke Imhoff +Alex Crichton +Martin Becze +Mark S. Miler +Pat Hickey +Tyler McMullen +Thomas Lively +Dan Gebhardt +Sam Clegg +Mark McCaskey +Nick Hynes +Nathaniel McCallum +Lin Clark +Yury Delendik +Mingqiu Sun + + +Meeting notes: + +Review action items: + +Sam has a document about import naming. TODO: insert the link here. We’ll discuss it in the next meeting. + +Action item: Sam to send out the import naming document. + +Weak imports: + +“Weak” in this context is not related to weak GC references. + +Desire to avoid depending on GC spec +Depend instead of reference types +Pat and others: push back on depending on reference types which aren’t in wasm MVP and not all tools support yet, causing schedule delays. +Mark Miller: How do capabilities work if we don’t have references? +Discussion of the mechanics of i32 file descriptors, which are forgeable, and which don’t enforce PoLA +Luke Wagner: Multiple tables may help i32-based environments have better granularity. +If you’re using C, you have to trust anyone you share your linear memory with. But other tools and languages and implementation strategies could do better. +Discussion of techniques to achieve various granularities of PoLA. + + +Action item: Sam to write up a name mangling proposal. + +Action item: Mark Miller to write up a vision document for using reference types and reference-counted closures in WASI. + +Existing toolchains for C-family and similar languages don’t use references. They typically need bindings tools to interoperate with reference-using APIs + +Discussion of how bindings work in various languages. + + +Action item: Dan to rename wasi-sysroot to wasi-libc + +Discussion of the WASI repo structure, pros and cons of using multiple repos, inside and outside the org + +Discussion about organizations and repos. Emscripten has its own org. LLVM wasm backend is maintained in a third party repository. Concern about having things in the WebAssembly org might raise the barrier to entry for contributing. Having things in the WebAssembly org may make things easier to find. + +Action item: Mark Miller to write up a vision document for using OCAP in WASI. diff --git a/proposals/random/meetings/2019/WASI-06-27.md b/proposals/random/meetings/2019/WASI-06-27.md index ea93d5ccb..af55fe748 100644 --- a/proposals/random/meetings/2019/WASI-06-27.md +++ b/proposals/random/meetings/2019/WASI-06-27.md @@ -55,4 +55,187 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-06-27 WebAssembly CG WASI Subgroup Video Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-06-27.md + +Attendees: + +Dan Gohman +Luke Imhoff +Sergey Rubanov +Paul Dworzanski +Pat Hickey +Alex Crichton +Martin Becze +Till Schneidereit +Lin Clark +Mark Miller +Mark McCaskey +Sam Clegg +Nick Hynes +Jakub Konka +Jlbirch +vwo + +Meeting notes: + +DG: Second agenda: +Luke Imhoff seconded. (Till seconds for posterity) + +DG: Import names Proposal: presenter is not here, lets move on to the Weak imports proposal + +SC: We talked about the weak imports proposal at the Wasm CG meeting about whether to represent weakness in the function name versus a custom section. + +DG: … align with the (missed it) proposal + +SC: I can update the proposal to go back to being a custom section. The function is imported as normal but whether or not it is allowed to be missing at runtime is specified in a custom section + +DG: This allows us to skip all the questions about name mangling, polluting the import/export space + +SC: One issue is that the embedders will have programmatic access to the module versus parsing the bytes, e.g. through the javascript api. + +DG: It makes sense for there to be a custom section javascript api that can do this for you. + +SC: I’ll update the PR to go back to custom sections + +DG: What is the point where we can establish a baseline for modularity and move on to breaking up the stuff currently known as wasi core into modules? + +LI: Will the JS embedding have a weak imports attribute on imports? What about support in all the browsers? + +DG: If someone doesnt support the custom section then they just have to resolve all of the weak imports, and if they cant provide all imports then instantiation will fail. + +LI: Can toolchains ship js that detect that instantiation failed, and use a different binary? + +SC: The point of weak imports is that only a single binary is needed + +DG: In web use cases browsers might not support the weak imports natively but you’ll be shipping a JS polyfill for those to implement WASI anyway. You either support WASI or you don’t. Supporting WASI includes support for weak imports. + +LI: Will there be a document that explains the layering of these various features required to support WASI? + +DG: Sam’s document is a start on that. We need to do more to clarify on the layering. Sam, Can you add more to the document to show how it fits into the bigger picture? + +SC: Yes it makes sense to make all of that part of the core wasi spec. The things we’re talking about being in the core so far are the import system, modularity, naming conventions, application lifecycle + +DG: This will be easier to do once we have more of the import stuff in place. I’m proposing we defer more explanation until we have the import system figured out. + +LI: There was back-and-forth about different patterns of WASI modules, reactor and command, in the spec - was there more discussion about that? + +DG: That is ongoing. This can be an adjunct to snowman bindings - the reactor and command model can be adjunct to the spec about bindings, since bindings are specifically about how to use a module, and so is a description of the lifecycle + +SC: ES6 Modules need the same sort of lifecycle support as WASI does + +DG: We’ll also want a custom section to say the entry points of applications and so on. + +LI: Where do I subscribe to updates on this, how far is it in chromium or mozilla? + +DG: I don’t know about that, https://github.com/WebAssembly/esm-integration tracks the ESM integration status but nobody here knows about the status of it in browsers right now. + +TS: The status of Node is they have almost complete implementation. I’m not aware of browser implementations that have made significant progress. + +LC: I’m not aware of any advances of implementations, apple had an early implementation but i’m not aware of updates given the changes to the proposal. + +DG: Let’s move on to the next item, left out of the agenda: last meeting Mark Miller discussed a vision document that laid out the use of Object Capabilities (OCap) in wasi. + +MM: Yes thanks for the reminder. It had dropped out of mind. + +DG: That’s ok we’re all busy here. + +MM: At the wasm blockchain meeting we discussed styles of ocap systems that do not support virtualizability, versus method style, where the behavior of a call on an object is up to the implementer. (...) and I looked at using a Capnp-like IDL to describe APIs in an object style. (unintelligible) looked at an IDL that could fetch type bindings and an adaptor from old style bindings to new style, to realize the virtualizaiblity of ocap systems. + +TS: Mark you’re dropping out a third of the time unfortunately. + +MM: Ok I will put my concerns in the document that I need to write. + +DG: Mark and I discussed this and it is a big idea that I think needs to be explained in detail. + +DG: At the CG we had feedback on the meeting schedule. Right now we’re on the same week as the Wasm meeting, an arbitrary choice. Would people prefer to change it to the opposite week? + +LI: I’m the one that brought it up, it would be nice to have more open time around lunch on these weeks (in my time zone). + +DG: As a poll, does anyone object to moving it to the opposite week from the CG meeting? + +(no objections) +DG: Then we’ll skip next week, the next meeting will be scheduled for 3 weeks out so that it alternates with the WASM CG call. + +DG: We also have an agenda item for talking about the CapnP issue: https://github.com/WebAssembly/WASI/issues/56, Martin can you fill us in: + +MB: I prototyped what it would look like to describe the interface in terms of capnp, we got feedback on that which was helpful. The impression I got from everyone is that customizing the Capnp idl is appropriate, we’ll write a custom IDL that is influenced by capnp and I’m working on that right now. + +MM: You saw my attempt at a BNF of the relevant subset of Capnp? + +MB: Yes I want to rework my pull request with that in mind. We want to pull out the versioning integers on all of the methods, and adding (missed it). It would be nice if we could express things like the ability to import globals, memories, tables, as well as functions. It would be nice if it looked like the rest of the webassembly stack, so I was looking at using s-expressions. + +MB: We need to figure out how this maps to the snowman bindings, I talked to Dan who explained more about how that worked. I see the point of the snowman bindings now. I think it would be interesting to reuse the ideas from the GC proposal re defining structs and so on, and having a binding section from the snowman proposal to describe how they are bound. + +TS: Martin, the original motivation of snowman bindings (prev webidl bindings prev host bindings) was to make DOM apis fast, interacting with them directly from wasm rather than going through javascript. While by now we have lots of reasons to want these bindings, that is still a requirement of the snowman bindings. How are you making sure that your work stays compatible with that, or are you focusing on the syntax layer and it won’t interfere with that? + +MB: I’m not considering how we’re binding to JavaScript, just interested in how to express the structures that these interfaces pass around - e.g. how do we express the structure of a directory entry and how do we read and write to it? That is partially covered by what snowman bindings does so we should reuse that. Maybe snowman bindings does cover everything we need. But the syntax should look like everything else + +TS: It seems like the syntax is purely in the tooling space + +MB: We have the syntax from GC to express struct and arrays, I think that's all we need to express things like directory entries. I want to reuse that syntax, and use that as a path for compatibility with GC implementations in the future. + +DG: Take the set of bindings and types we have in wasi core as the base language, and the IDL describes what those are and gives us the clean descriptions we want + +MB: The tooling is a big hurdle in webidl right now, we want to make it easier for people to read and write these descriptions. + +TS: That makes sense. Luke wagner has had a lot of conversations around this, including with all the webidl people. They are all open to improving things. Its clear that snowman bindings won't be webidl bindings, but they need to be semantically compatible enough to describe the dom bindings pieces. If we end up having different surface syntaxes, thats fine because its mostly about tooling, but I also think we should have something that is not gratuitously different. One constraint is that browser implementers will have to be able to consume webidl in order to make the dom bindings work (already used throughout browsers). Keep in mind that there are constraints that don’t allow us to completely evolve this tooling in ways that break the DOM bindings use case. + +DG: If you can go with whats in snowman bindings now, and build on top of that, then we can achieve the parity we’re going for without defining new semantics. The key vocabulary is the types and the operations. Webidl has a lot of things in it that are distracting, even if you reduce it down to just the parts we need there are still syntax things like how “unsigned long” is the way to write u64, so i’m sympathetic to changing that syntax. + +MM: When I did my minimal BNF subset of capnp, I did take a look at the WASI ABI document and all of the capnp names for the types like u64 seemed obviously much better. I did not include wasm-specific concepts like memory, I agree that's an important thing to figure out how to accommodate. + +DG: Actions going forward: martin will take the capnp PR and make a version with the new syntax. + +MB: I will get that done in the next week and get more feedback. + +MM: There is a long term issue of how we support, at the wasm level, how we manage method dispatch. There are several ways we could map that to the current wasm, none of which are very natural. This problem goes away with GC but I continue to assume that is a long ways out. The smallest step from where we are to a natural method dispatch binding would be to add sum types, where sum types are passed on the stack rather than by separate allocation of reference counts, and the message - the thing that one invokes - would be a sum type where the constructor is the method name, and the contents of that branch of the sum type are the arguments, and the pattern match at the receiver would be the method dispatch. Given that we’re doing an IDL we dont have to decide up-front what the method dispatch representation is, but it would be good to have a candidate in mind. + +DG: My understanding is that not everyone has seen material on dynamic dispatch, so it would be a good thing to start with a paper on how dynamic dispatch works and what use cases it has +MB: Once we have proper function references doesn’t that cover? Are sum types part of GC? + +MM: The repr of sum types I’m thinking of would not require dynamic allocation so we could implement it before GC. It would still be a significant additional piece of engineering. The problem with just using function pointers is that method dispatch with what we have now, the options are 1. You pass by copy a record of function references, and the client of the object invokes a method by looking up the method name in that record, the problem with that is the size of the reference to the object is passed by copy and proportional in size to the num of methods on the type. +2. You pass by reference a … it loses the static type information given our current system, so you’d have to cast after the method lookup to the right signature. +None of these are natural for intra-module communication given the current wasm representation of things. + +DG: One thing we talked about was virtualizing an API and how we might do that. Dynamic dispatch approach allows you to virtualize in more ways. There are a lot of new ideas here and we need to motivate what problems we’re solving here and spread the ideas more broadly. + +DG: Lets move on to the next issue, the blockchain call extension. The main thing I want to address is the meta-discussion of whether this digs inside wasi. Nick are you here? + +DG: I encourage folks in the blockchain space to submit proposals, it fits well with our modularization story. It is a bit ahead of the curve as we’re still figuring out how imports and weak import names and so on. + +DG: Implementers of wasi that don’t have anything to do with blockchain wouldn’t have to implement these interfaces but its good to have the standard for how they work all in one system. + +NH: (missed it) + +MB: It would be nice if we had an interface for persistently storing function references and loading them. One idea is that we could extend the number of file types to one that could load a function reference and put it into an anyfunc table. This would require the call-ref operation to call the method, from in the function refs proposal. + +MB: The file types we have now are a file, directory, block device, character device. Are there problems with extending those filetypes? + +DG: Part of that question we might not quite be ready to answer yet. Does anyone have problems with extending the idea of a stream beyond posix-style streams? + +LI: If plan 9 could do it we can to +DG: We can talk more about stream APIs but I think extending streams to be useful for blockchains is a good idea, as long as it does not incur a cost to implementors that dont need blockchain. + +LI: We say blockchain but is any o f that not descended from etherium? + +NH: I want to generalize this in way for systems beyond etherium descendents + +MB: I worked on ewasm and dfinity, I also want this interface to work beyond etherium family as well. + +MM: The plan at agoric for using blockchain and wasm is not etherium-like, it is consistent with ocap approach, and the issue of dynamic dispatch becomes important to us. + +DG: For some context there's discussion in the CG about webvms and the requirement for 2 implementations that are webvms. In wasi we’ve decided that the committee would accept non webvm implementations and make decisions on what exact vms would be accepted as we go + +LI: Whatever system we come up with should handle more than just one currency, it should handle multiple currencies on a single chain + +MB: We should standardize that we aren’t dealing with one particular currency. This would probably be a good document to put together. + +DG: We should record our thoughts on what requirements we have for blockchains. Martin can you write up … we want diversity, we want to make sure we’re standardizing on something that more than one implementation will use. + +NH and MB will collaborate on that document. + +DG: Any further items? + +Meeting adjourned diff --git a/proposals/random/meetings/2019/WASI-07-18.md b/proposals/random/meetings/2019/WASI-07-18.md index 78e3b2d12..6d275e700 100644 --- a/proposals/random/meetings/2019/WASI-07-18.md +++ b/proposals/random/meetings/2019/WASI-07-18.md @@ -51,6 +51,212 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-07-18 WebAssembly CG WASI Subgroup Video Meeting Notes -Action item; reschedule meeting +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-07-18.md + +Attendees: + +Dan Gohman +Martin Becze +Mark McCaskey +Alex Crichton +Andrew Brown +Sam Clegg +Yury Delendik +Arun Purushan +Pat Hickey +Jacob Gravelle +Luke Wagner +Till Schneidereit +Luke Imhoff + +Meeting notes: + +Pat - agenda seconded + +DG: +Import resolution outside of the scope of WASI. + +Pick naming convention that involves the name wasi_unstable + a possible additional identifier, to allow us to continue designing APIs. + +SC: wasi_unstable implies a bulk rename in the future + +DG: agreeing but bringing up additional prefix to clarify. Does anyone have an opinion. Suggested wasi_unstable/ + +_ : Is there any reason to use a / + +DG: We want to split the existing wasi_unstable into multiple modules, :, $, the specific character doesn’t matter. + +DG: is there a problem with / + +_ : Agreeing that separator doesn’t matter, but we should move everything into namespaces + +DG: it will allow us to start design work on other APIs… + +DG: wasi_unstable/identifier is the current proposal. We’ll call that a decision, we can use that to unblock things and start modularizing things. We’ll start queueing up those issues for the next meetings. Let’s have those issues and we’ll start tagging them. Part of that work will be deciding what goes in what modules + +DG: next agenda item. Weak imports + +SC: I got as far as implementing the custom section and realized that there’s quite a lot of redundancy, we’ll have a global corresponding to each global import. All we need is a way of finding that list of globals, we’ll probably use name mangling, so all we need to do is specify the suffix and the runtime can find all imports matching that pattern. Name mangling just for is_present. It would just be a simple custom section saying “is present” + +DG: that strikes me as overkill + +SC: (something)… we can find all weak imports by looking for that suffix + +SC: someone asked why we weren’t going forward with the official Wasm spec proposal of weak imports + +DG: one possibility is that we can take weak imports as being in the same bucket as snowman bindings. It’s a way of describing an interface to Wasm, so maybe we should put it in the snowman bindings custom section. If that’s the case, we can roll it into the snowman bindings proposal. I think it aligns pretty well with the snowman bindings things, because it’s a custom section, and (justification regarding name mangling) + +PH: if you have a whole bunch of weak imports, you can map them to the same global if you want to. So that’s an advantage of a custom section + +SC: what does that mean, if anyone of them is missing + +PH: that’s useful if you’re importing an entire module of things + +SC: that’s useful for all-or-none situations + +SC: yeah, I like it + +DG: alright, so with that, I’ll put that to the group, is this a good way to go forward, put it in a custom section and roll it into snowman bindings? + +(Luke allegedly nods head) + +SC: I don’t see how it fits into snowman bindings +DG: it’s part of a custom section that is the interpretation of the module; it’s not quite the same thing but it’s in the same category. It would be in a different part of the custom section, and eventually things like specifying the entry point + +LW: (missed)... this is in the same kind of layer + +SC: that makes sense when you put it like that + +DG: does anyone want to comment on the issue then? Someone in the WASI repo brought up the question of using a custom section + +J: if that is the case then we should put it in the webidl bindings repo + +LW: the webidl bindings repo is itself a layer of …. + +J: should add assuming it does exist (snowman bindings) + +PH: there’s a large overlap in the people working on both, so it’s probably a non-issue + +J: do we want to use weak imports for something else? Mentioning it there will get more eyes on it. Weak imports in contexts outside of WASI + +… + +SC: should I keep going with specing that in the WASI repo? + +DG: yeah, for now.. We’ll figure it out as it goes + +DG: next agenda item: WAT IDL proposal + +M: So where we got stuck last week is with conflating two things, the way watidl was written made the interface an object, that’s a mistake because an interface is a Wasm module. I rewrote it and I’ll push up the changes today. We should take a key from webidl we can add the extra field that this is a method and then we know that the bindings need to bind some sort of context, so I’ll introduce a method field. It’s also important to remember what the whole point of this was which was partially virtualization, ideally we should be able to have an IDL that Wasm binaries can bind to in two different ways, one using aztrack? Data ADT where all the functions are imported, the other way that would be easy to virtualize, I’m also trying to, I wrote up a little doc on how to do virtualization which I’ll throw up today, so that’s where we’re at with watidl. + +LW: what does virtualization specifically mean? You’ve requested to import this fn but I’ll give you a virtualized one instead + +M: the ability for a Wasm module that a Wasm module can implement a given interface and another module can use that, there’s 2 types of virt. Static: another module importing fd_close, open, sync, which another imports. Dynamic: a module being able to on the fly create a file descriptor or implement it to hand to another module, which is what I meant + +LW: do you mean as a reference to a struct that contains fn refs? + +M: yeah, exactly. SO in that case, the WASI interface, ref to structs of fns, you would just import types at that point. It would be nice to have an IDL that can describe both ways of interacting. + +LW: and who would use the IDL? + +M: used to describe interface and then you’d write bindings. + +LW: so this would be the interface of WASI? + +M: yeah + +LW: would this be equivalent to a list of Wasm function signatures that would be allowed to use snowman binding types in their signatures along with module and field name + +M: list of functions of types, it’s pretty basic + +LW: If we go the snowman bindings format and have a Wasm style and there were fn sigs that could use these types instead of core Wasm types. What if I make a module that just describes the interface… just a subset of the text format. + +M: that’s pretty much what this is + the addition of whether a function can be virtualized or not + +LW: that has some pretty significant runtime and compile time implications + +M: We don’t even have structs or fields, we need partial GC and func ref before we can do dynamic dispatch properly anyways, so we’re looking ahead. + +LW: thanks for explaining that + +M: it’s the text format - bodies, just types and function signatures + +MM: Wasm interfaces are overlapping, we should consolidate these or figure out what’s going on +SC: virtualization isn’t needed for what we need right now, so maybe we shouldn’t push on that too hard if we don’t need it right now. + +M: agreement/partial agreement + +M: I think virt. Is important in a context where you have multiple untrusted modules working together. As WASI is now, it’s generally a single module, they can add object capabilities to each other. In that context it’s not as useful, once we have func refs, …. Then the capab to virt interfaces is more important + +TS: I thought that was a different layer, instead of the runtime built-in you use this instead. I don’t see how that would interact with the IDL, can you explain that more? + +SC: you’re talking about interposition vs method calls, interposition is like intercepting a method call. + +M: Are you all familiar with ADT style? RIght now everything is ADT style, so you can’t really virtualize ADT style. A module can’t really implement those functions, it can’t generate them on the fly. So to be able to generate or implement a file descriptor, that’s /udev/random , so a module can do this and generate a FD on the file when requested by creating a struct and hand it off to the requester, why this matters at an IDL level is, a module may only want to use OO interface and in that scenario, you’d only implement types and the entrypoint fn would only receive capabilities, references to structs which point to functions. One use case for an IDL here is the host system would know that the module wants OO type vs ADT style, does that make sense? + +TS: I think so, thanks for the clarification + +M: that said, since we don’t have, since it’s not given we don’t have GC or func ref, (func ref?) looks more promising, it might not be worthwhile to worry about this. It might not be worth worrying about this yet and just focus on ADT style + +DG: as far as next steps, martin you mentioned that you’ll post an updated version of the proposal? + +M: yep + +DG: we’ll iterate from there. Anything else we want to cover in this meeting? + +M: I also wrote up some stuff about virtualization, should I add that to the repo? + +DG: Sure, make a PR and we can discuss it and decide if we want to incorporate it + +DG: that’s a good point, virt. Is an interesting enough point that we should document what we’re going to do in this space + +DG: next on the agenda, with the theme of setting up the wasi_unstable namespace, what are the blockers that we have before we can split up wasi_unstable into modules and working on them. Having an IDL nicer than a C header file or markdown is good, are there other blockers? + +LW: do you think we should hold off until we can make use of reference types and type imports? Or do we want to do it later + +DG: I think that’s something we can deal with later. When we have full snowman bindings, we’ll want to convert them into that form, and emulating lower level concepts with our higher level types. We need to figure out what is a file and that doesn’t need to wait for (those things) + +TS: maybe we should say that the changes we make going forward should take these concepts into mind, (describes using indirection of fds in a table of anyref to make transition easier) + +DG: that seems reasonable and I think that will somewhat naturally fallout given API design. We want a vocab to talk about things until we have an actual IDL, we can do API design with C headers but it’s not ideal, so we should figure out what to do there. MAking it easier to migrate to future bindings systems seems great + +TS: two advantages, we can do API design now knowing thta API design can map well, later on we have a straight forward way to make it easy to consume in C/CPP/Rust. Two APIs with the AnyRef being the fundamental and an indice-only one on top of it + +DG: how much do we want to do now vs waiting for snowman bindings? If we just design with this in mind, it will be pretty straight forward to retro fit this, that’s my gut feeling here. + +TS: All I’m proposing is making that explicit that we want to have this 1-to-1 relationship, making that relationship straight-forward + +DG: should we have a document about “How to design a WASI API” + +M: that sounds like a good idea + +DG: martin or till do you want to start a document like that? + +TS: I can start that document by writing what I just said and then we can flesh it out with more content + +DG: it can evolve as we get snowman bindings and other tools + +LW: it might be good to have a “future intended steps” section. The intent to move to ref types and binding types are only in our own heads and we should document that somewhere + +DG: looking for someone to document OCAP vision and put it in a repo, if someone wants to do that, that’d be great. It’s been discussed in various places, but we don’t have a document in the repo describing the plan. IF someone could digest that down and start that, that’s what we’re looking for + +LW: I can help there + +DG: we have the docs directory in the WASI repo. Alright, I’m trying to push forward to the point where we can do API design. Are there any other blockers? We’ll have a document, (somethinG) in progress, and a plan … for a module naming system, temporary one, pending discussion about import naming schemes. That’s the end of the agenda. Is there anything else? + +SC: presumably we’ll need an IDL to header file conversion after, +DG: yes (..) + rust interface generation + +M: … +LW: … +TS: s-expressions as type definitions minus the body is the obvious way to define the functions. WHat’s missing is how to fit the binding expressions in there + +LW: importantly, binding expressions don’t fit in there, interface is just the types + +M: to generate a header file, you’d need the IDL and the bindings and they do need to be separate because different languages want different bindings + +LW: I’m not quite sure what you mean by supplying the bindings. You could generate for say, C, there’d be policy choices like what to do with strings, but it’s possible. Sounds like a cool tool though + +DG: that sounds like the end of the meeting, see you all in 2 weeks From 6719cb6aa0f0a3e8fcdac4abb588b54683dd37da Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 14 Aug 2019 23:31:26 -0700 Subject: [PATCH 0069/1772] Add meeeting notes for previous meetings. --- .../filesystem/meetings/2019/WASI-05-30.md | 63 +++++- .../filesystem/meetings/2019/WASI-06-27.md | 185 ++++++++++++++- .../filesystem/meetings/2019/WASI-07-18.md | 210 +++++++++++++++++- 3 files changed, 454 insertions(+), 4 deletions(-) diff --git a/proposals/filesystem/meetings/2019/WASI-05-30.md b/proposals/filesystem/meetings/2019/WASI-05-30.md index 6cfa0b63e..a48231332 100644 --- a/proposals/filesystem/meetings/2019/WASI-05-30.md +++ b/proposals/filesystem/meetings/2019/WASI-05-30.md @@ -52,4 +52,65 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-30.md + +Attendees: + +Dan Gohman +Luke Imhoff +Alex Crichton +Martin Becze +Mark S. Miler +Pat Hickey +Tyler McMullen +Thomas Lively +Dan Gebhardt +Sam Clegg +Mark McCaskey +Nick Hynes +Nathaniel McCallum +Lin Clark +Yury Delendik +Mingqiu Sun + + +Meeting notes: + +Review action items: + +Sam has a document about import naming. TODO: insert the link here. We’ll discuss it in the next meeting. + +Action item: Sam to send out the import naming document. + +Weak imports: + +“Weak” in this context is not related to weak GC references. + +Desire to avoid depending on GC spec +Depend instead of reference types +Pat and others: push back on depending on reference types which aren’t in wasm MVP and not all tools support yet, causing schedule delays. +Mark Miller: How do capabilities work if we don’t have references? +Discussion of the mechanics of i32 file descriptors, which are forgeable, and which don’t enforce PoLA +Luke Wagner: Multiple tables may help i32-based environments have better granularity. +If you’re using C, you have to trust anyone you share your linear memory with. But other tools and languages and implementation strategies could do better. +Discussion of techniques to achieve various granularities of PoLA. + + +Action item: Sam to write up a name mangling proposal. + +Action item: Mark Miller to write up a vision document for using reference types and reference-counted closures in WASI. + +Existing toolchains for C-family and similar languages don’t use references. They typically need bindings tools to interoperate with reference-using APIs + +Discussion of how bindings work in various languages. + + +Action item: Dan to rename wasi-sysroot to wasi-libc + +Discussion of the WASI repo structure, pros and cons of using multiple repos, inside and outside the org + +Discussion about organizations and repos. Emscripten has its own org. LLVM wasm backend is maintained in a third party repository. Concern about having things in the WebAssembly org might raise the barrier to entry for contributing. Having things in the WebAssembly org may make things easier to find. + +Action item: Mark Miller to write up a vision document for using OCAP in WASI. diff --git a/proposals/filesystem/meetings/2019/WASI-06-27.md b/proposals/filesystem/meetings/2019/WASI-06-27.md index ea93d5ccb..af55fe748 100644 --- a/proposals/filesystem/meetings/2019/WASI-06-27.md +++ b/proposals/filesystem/meetings/2019/WASI-06-27.md @@ -55,4 +55,187 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-06-27 WebAssembly CG WASI Subgroup Video Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-06-27.md + +Attendees: + +Dan Gohman +Luke Imhoff +Sergey Rubanov +Paul Dworzanski +Pat Hickey +Alex Crichton +Martin Becze +Till Schneidereit +Lin Clark +Mark Miller +Mark McCaskey +Sam Clegg +Nick Hynes +Jakub Konka +Jlbirch +vwo + +Meeting notes: + +DG: Second agenda: +Luke Imhoff seconded. (Till seconds for posterity) + +DG: Import names Proposal: presenter is not here, lets move on to the Weak imports proposal + +SC: We talked about the weak imports proposal at the Wasm CG meeting about whether to represent weakness in the function name versus a custom section. + +DG: … align with the (missed it) proposal + +SC: I can update the proposal to go back to being a custom section. The function is imported as normal but whether or not it is allowed to be missing at runtime is specified in a custom section + +DG: This allows us to skip all the questions about name mangling, polluting the import/export space + +SC: One issue is that the embedders will have programmatic access to the module versus parsing the bytes, e.g. through the javascript api. + +DG: It makes sense for there to be a custom section javascript api that can do this for you. + +SC: I’ll update the PR to go back to custom sections + +DG: What is the point where we can establish a baseline for modularity and move on to breaking up the stuff currently known as wasi core into modules? + +LI: Will the JS embedding have a weak imports attribute on imports? What about support in all the browsers? + +DG: If someone doesnt support the custom section then they just have to resolve all of the weak imports, and if they cant provide all imports then instantiation will fail. + +LI: Can toolchains ship js that detect that instantiation failed, and use a different binary? + +SC: The point of weak imports is that only a single binary is needed + +DG: In web use cases browsers might not support the weak imports natively but you’ll be shipping a JS polyfill for those to implement WASI anyway. You either support WASI or you don’t. Supporting WASI includes support for weak imports. + +LI: Will there be a document that explains the layering of these various features required to support WASI? + +DG: Sam’s document is a start on that. We need to do more to clarify on the layering. Sam, Can you add more to the document to show how it fits into the bigger picture? + +SC: Yes it makes sense to make all of that part of the core wasi spec. The things we’re talking about being in the core so far are the import system, modularity, naming conventions, application lifecycle + +DG: This will be easier to do once we have more of the import stuff in place. I’m proposing we defer more explanation until we have the import system figured out. + +LI: There was back-and-forth about different patterns of WASI modules, reactor and command, in the spec - was there more discussion about that? + +DG: That is ongoing. This can be an adjunct to snowman bindings - the reactor and command model can be adjunct to the spec about bindings, since bindings are specifically about how to use a module, and so is a description of the lifecycle + +SC: ES6 Modules need the same sort of lifecycle support as WASI does + +DG: We’ll also want a custom section to say the entry points of applications and so on. + +LI: Where do I subscribe to updates on this, how far is it in chromium or mozilla? + +DG: I don’t know about that, https://github.com/WebAssembly/esm-integration tracks the ESM integration status but nobody here knows about the status of it in browsers right now. + +TS: The status of Node is they have almost complete implementation. I’m not aware of browser implementations that have made significant progress. + +LC: I’m not aware of any advances of implementations, apple had an early implementation but i’m not aware of updates given the changes to the proposal. + +DG: Let’s move on to the next item, left out of the agenda: last meeting Mark Miller discussed a vision document that laid out the use of Object Capabilities (OCap) in wasi. + +MM: Yes thanks for the reminder. It had dropped out of mind. + +DG: That’s ok we’re all busy here. + +MM: At the wasm blockchain meeting we discussed styles of ocap systems that do not support virtualizability, versus method style, where the behavior of a call on an object is up to the implementer. (...) and I looked at using a Capnp-like IDL to describe APIs in an object style. (unintelligible) looked at an IDL that could fetch type bindings and an adaptor from old style bindings to new style, to realize the virtualizaiblity of ocap systems. + +TS: Mark you’re dropping out a third of the time unfortunately. + +MM: Ok I will put my concerns in the document that I need to write. + +DG: Mark and I discussed this and it is a big idea that I think needs to be explained in detail. + +DG: At the CG we had feedback on the meeting schedule. Right now we’re on the same week as the Wasm meeting, an arbitrary choice. Would people prefer to change it to the opposite week? + +LI: I’m the one that brought it up, it would be nice to have more open time around lunch on these weeks (in my time zone). + +DG: As a poll, does anyone object to moving it to the opposite week from the CG meeting? + +(no objections) +DG: Then we’ll skip next week, the next meeting will be scheduled for 3 weeks out so that it alternates with the WASM CG call. + +DG: We also have an agenda item for talking about the CapnP issue: https://github.com/WebAssembly/WASI/issues/56, Martin can you fill us in: + +MB: I prototyped what it would look like to describe the interface in terms of capnp, we got feedback on that which was helpful. The impression I got from everyone is that customizing the Capnp idl is appropriate, we’ll write a custom IDL that is influenced by capnp and I’m working on that right now. + +MM: You saw my attempt at a BNF of the relevant subset of Capnp? + +MB: Yes I want to rework my pull request with that in mind. We want to pull out the versioning integers on all of the methods, and adding (missed it). It would be nice if we could express things like the ability to import globals, memories, tables, as well as functions. It would be nice if it looked like the rest of the webassembly stack, so I was looking at using s-expressions. + +MB: We need to figure out how this maps to the snowman bindings, I talked to Dan who explained more about how that worked. I see the point of the snowman bindings now. I think it would be interesting to reuse the ideas from the GC proposal re defining structs and so on, and having a binding section from the snowman proposal to describe how they are bound. + +TS: Martin, the original motivation of snowman bindings (prev webidl bindings prev host bindings) was to make DOM apis fast, interacting with them directly from wasm rather than going through javascript. While by now we have lots of reasons to want these bindings, that is still a requirement of the snowman bindings. How are you making sure that your work stays compatible with that, or are you focusing on the syntax layer and it won’t interfere with that? + +MB: I’m not considering how we’re binding to JavaScript, just interested in how to express the structures that these interfaces pass around - e.g. how do we express the structure of a directory entry and how do we read and write to it? That is partially covered by what snowman bindings does so we should reuse that. Maybe snowman bindings does cover everything we need. But the syntax should look like everything else + +TS: It seems like the syntax is purely in the tooling space + +MB: We have the syntax from GC to express struct and arrays, I think that's all we need to express things like directory entries. I want to reuse that syntax, and use that as a path for compatibility with GC implementations in the future. + +DG: Take the set of bindings and types we have in wasi core as the base language, and the IDL describes what those are and gives us the clean descriptions we want + +MB: The tooling is a big hurdle in webidl right now, we want to make it easier for people to read and write these descriptions. + +TS: That makes sense. Luke wagner has had a lot of conversations around this, including with all the webidl people. They are all open to improving things. Its clear that snowman bindings won't be webidl bindings, but they need to be semantically compatible enough to describe the dom bindings pieces. If we end up having different surface syntaxes, thats fine because its mostly about tooling, but I also think we should have something that is not gratuitously different. One constraint is that browser implementers will have to be able to consume webidl in order to make the dom bindings work (already used throughout browsers). Keep in mind that there are constraints that don’t allow us to completely evolve this tooling in ways that break the DOM bindings use case. + +DG: If you can go with whats in snowman bindings now, and build on top of that, then we can achieve the parity we’re going for without defining new semantics. The key vocabulary is the types and the operations. Webidl has a lot of things in it that are distracting, even if you reduce it down to just the parts we need there are still syntax things like how “unsigned long” is the way to write u64, so i’m sympathetic to changing that syntax. + +MM: When I did my minimal BNF subset of capnp, I did take a look at the WASI ABI document and all of the capnp names for the types like u64 seemed obviously much better. I did not include wasm-specific concepts like memory, I agree that's an important thing to figure out how to accommodate. + +DG: Actions going forward: martin will take the capnp PR and make a version with the new syntax. + +MB: I will get that done in the next week and get more feedback. + +MM: There is a long term issue of how we support, at the wasm level, how we manage method dispatch. There are several ways we could map that to the current wasm, none of which are very natural. This problem goes away with GC but I continue to assume that is a long ways out. The smallest step from where we are to a natural method dispatch binding would be to add sum types, where sum types are passed on the stack rather than by separate allocation of reference counts, and the message - the thing that one invokes - would be a sum type where the constructor is the method name, and the contents of that branch of the sum type are the arguments, and the pattern match at the receiver would be the method dispatch. Given that we’re doing an IDL we dont have to decide up-front what the method dispatch representation is, but it would be good to have a candidate in mind. + +DG: My understanding is that not everyone has seen material on dynamic dispatch, so it would be a good thing to start with a paper on how dynamic dispatch works and what use cases it has +MB: Once we have proper function references doesn’t that cover? Are sum types part of GC? + +MM: The repr of sum types I’m thinking of would not require dynamic allocation so we could implement it before GC. It would still be a significant additional piece of engineering. The problem with just using function pointers is that method dispatch with what we have now, the options are 1. You pass by copy a record of function references, and the client of the object invokes a method by looking up the method name in that record, the problem with that is the size of the reference to the object is passed by copy and proportional in size to the num of methods on the type. +2. You pass by reference a … it loses the static type information given our current system, so you’d have to cast after the method lookup to the right signature. +None of these are natural for intra-module communication given the current wasm representation of things. + +DG: One thing we talked about was virtualizing an API and how we might do that. Dynamic dispatch approach allows you to virtualize in more ways. There are a lot of new ideas here and we need to motivate what problems we’re solving here and spread the ideas more broadly. + +DG: Lets move on to the next issue, the blockchain call extension. The main thing I want to address is the meta-discussion of whether this digs inside wasi. Nick are you here? + +DG: I encourage folks in the blockchain space to submit proposals, it fits well with our modularization story. It is a bit ahead of the curve as we’re still figuring out how imports and weak import names and so on. + +DG: Implementers of wasi that don’t have anything to do with blockchain wouldn’t have to implement these interfaces but its good to have the standard for how they work all in one system. + +NH: (missed it) + +MB: It would be nice if we had an interface for persistently storing function references and loading them. One idea is that we could extend the number of file types to one that could load a function reference and put it into an anyfunc table. This would require the call-ref operation to call the method, from in the function refs proposal. + +MB: The file types we have now are a file, directory, block device, character device. Are there problems with extending those filetypes? + +DG: Part of that question we might not quite be ready to answer yet. Does anyone have problems with extending the idea of a stream beyond posix-style streams? + +LI: If plan 9 could do it we can to +DG: We can talk more about stream APIs but I think extending streams to be useful for blockchains is a good idea, as long as it does not incur a cost to implementors that dont need blockchain. + +LI: We say blockchain but is any o f that not descended from etherium? + +NH: I want to generalize this in way for systems beyond etherium descendents + +MB: I worked on ewasm and dfinity, I also want this interface to work beyond etherium family as well. + +MM: The plan at agoric for using blockchain and wasm is not etherium-like, it is consistent with ocap approach, and the issue of dynamic dispatch becomes important to us. + +DG: For some context there's discussion in the CG about webvms and the requirement for 2 implementations that are webvms. In wasi we’ve decided that the committee would accept non webvm implementations and make decisions on what exact vms would be accepted as we go + +LI: Whatever system we come up with should handle more than just one currency, it should handle multiple currencies on a single chain + +MB: We should standardize that we aren’t dealing with one particular currency. This would probably be a good document to put together. + +DG: We should record our thoughts on what requirements we have for blockchains. Martin can you write up … we want diversity, we want to make sure we’re standardizing on something that more than one implementation will use. + +NH and MB will collaborate on that document. + +DG: Any further items? + +Meeting adjourned diff --git a/proposals/filesystem/meetings/2019/WASI-07-18.md b/proposals/filesystem/meetings/2019/WASI-07-18.md index 78e3b2d12..6d275e700 100644 --- a/proposals/filesystem/meetings/2019/WASI-07-18.md +++ b/proposals/filesystem/meetings/2019/WASI-07-18.md @@ -51,6 +51,212 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +2019-07-18 WebAssembly CG WASI Subgroup Video Meeting Notes -Action item; reschedule meeting +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-07-18.md + +Attendees: + +Dan Gohman +Martin Becze +Mark McCaskey +Alex Crichton +Andrew Brown +Sam Clegg +Yury Delendik +Arun Purushan +Pat Hickey +Jacob Gravelle +Luke Wagner +Till Schneidereit +Luke Imhoff + +Meeting notes: + +Pat - agenda seconded + +DG: +Import resolution outside of the scope of WASI. + +Pick naming convention that involves the name wasi_unstable + a possible additional identifier, to allow us to continue designing APIs. + +SC: wasi_unstable implies a bulk rename in the future + +DG: agreeing but bringing up additional prefix to clarify. Does anyone have an opinion. Suggested wasi_unstable/ + +_ : Is there any reason to use a / + +DG: We want to split the existing wasi_unstable into multiple modules, :, $, the specific character doesn’t matter. + +DG: is there a problem with / + +_ : Agreeing that separator doesn’t matter, but we should move everything into namespaces + +DG: it will allow us to start design work on other APIs… + +DG: wasi_unstable/identifier is the current proposal. We’ll call that a decision, we can use that to unblock things and start modularizing things. We’ll start queueing up those issues for the next meetings. Let’s have those issues and we’ll start tagging them. Part of that work will be deciding what goes in what modules + +DG: next agenda item. Weak imports + +SC: I got as far as implementing the custom section and realized that there’s quite a lot of redundancy, we’ll have a global corresponding to each global import. All we need is a way of finding that list of globals, we’ll probably use name mangling, so all we need to do is specify the suffix and the runtime can find all imports matching that pattern. Name mangling just for is_present. It would just be a simple custom section saying “is present” + +DG: that strikes me as overkill + +SC: (something)… we can find all weak imports by looking for that suffix + +SC: someone asked why we weren’t going forward with the official Wasm spec proposal of weak imports + +DG: one possibility is that we can take weak imports as being in the same bucket as snowman bindings. It’s a way of describing an interface to Wasm, so maybe we should put it in the snowman bindings custom section. If that’s the case, we can roll it into the snowman bindings proposal. I think it aligns pretty well with the snowman bindings things, because it’s a custom section, and (justification regarding name mangling) + +PH: if you have a whole bunch of weak imports, you can map them to the same global if you want to. So that’s an advantage of a custom section + +SC: what does that mean, if anyone of them is missing + +PH: that’s useful if you’re importing an entire module of things + +SC: that’s useful for all-or-none situations + +SC: yeah, I like it + +DG: alright, so with that, I’ll put that to the group, is this a good way to go forward, put it in a custom section and roll it into snowman bindings? + +(Luke allegedly nods head) + +SC: I don’t see how it fits into snowman bindings +DG: it’s part of a custom section that is the interpretation of the module; it’s not quite the same thing but it’s in the same category. It would be in a different part of the custom section, and eventually things like specifying the entry point + +LW: (missed)... this is in the same kind of layer + +SC: that makes sense when you put it like that + +DG: does anyone want to comment on the issue then? Someone in the WASI repo brought up the question of using a custom section + +J: if that is the case then we should put it in the webidl bindings repo + +LW: the webidl bindings repo is itself a layer of …. + +J: should add assuming it does exist (snowman bindings) + +PH: there’s a large overlap in the people working on both, so it’s probably a non-issue + +J: do we want to use weak imports for something else? Mentioning it there will get more eyes on it. Weak imports in contexts outside of WASI + +… + +SC: should I keep going with specing that in the WASI repo? + +DG: yeah, for now.. We’ll figure it out as it goes + +DG: next agenda item: WAT IDL proposal + +M: So where we got stuck last week is with conflating two things, the way watidl was written made the interface an object, that’s a mistake because an interface is a Wasm module. I rewrote it and I’ll push up the changes today. We should take a key from webidl we can add the extra field that this is a method and then we know that the bindings need to bind some sort of context, so I’ll introduce a method field. It’s also important to remember what the whole point of this was which was partially virtualization, ideally we should be able to have an IDL that Wasm binaries can bind to in two different ways, one using aztrack? Data ADT where all the functions are imported, the other way that would be easy to virtualize, I’m also trying to, I wrote up a little doc on how to do virtualization which I’ll throw up today, so that’s where we’re at with watidl. + +LW: what does virtualization specifically mean? You’ve requested to import this fn but I’ll give you a virtualized one instead + +M: the ability for a Wasm module that a Wasm module can implement a given interface and another module can use that, there’s 2 types of virt. Static: another module importing fd_close, open, sync, which another imports. Dynamic: a module being able to on the fly create a file descriptor or implement it to hand to another module, which is what I meant + +LW: do you mean as a reference to a struct that contains fn refs? + +M: yeah, exactly. SO in that case, the WASI interface, ref to structs of fns, you would just import types at that point. It would be nice to have an IDL that can describe both ways of interacting. + +LW: and who would use the IDL? + +M: used to describe interface and then you’d write bindings. + +LW: so this would be the interface of WASI? + +M: yeah + +LW: would this be equivalent to a list of Wasm function signatures that would be allowed to use snowman binding types in their signatures along with module and field name + +M: list of functions of types, it’s pretty basic + +LW: If we go the snowman bindings format and have a Wasm style and there were fn sigs that could use these types instead of core Wasm types. What if I make a module that just describes the interface… just a subset of the text format. + +M: that’s pretty much what this is + the addition of whether a function can be virtualized or not + +LW: that has some pretty significant runtime and compile time implications + +M: We don’t even have structs or fields, we need partial GC and func ref before we can do dynamic dispatch properly anyways, so we’re looking ahead. + +LW: thanks for explaining that + +M: it’s the text format - bodies, just types and function signatures + +MM: Wasm interfaces are overlapping, we should consolidate these or figure out what’s going on +SC: virtualization isn’t needed for what we need right now, so maybe we shouldn’t push on that too hard if we don’t need it right now. + +M: agreement/partial agreement + +M: I think virt. Is important in a context where you have multiple untrusted modules working together. As WASI is now, it’s generally a single module, they can add object capabilities to each other. In that context it’s not as useful, once we have func refs, …. Then the capab to virt interfaces is more important + +TS: I thought that was a different layer, instead of the runtime built-in you use this instead. I don’t see how that would interact with the IDL, can you explain that more? + +SC: you’re talking about interposition vs method calls, interposition is like intercepting a method call. + +M: Are you all familiar with ADT style? RIght now everything is ADT style, so you can’t really virtualize ADT style. A module can’t really implement those functions, it can’t generate them on the fly. So to be able to generate or implement a file descriptor, that’s /udev/random , so a module can do this and generate a FD on the file when requested by creating a struct and hand it off to the requester, why this matters at an IDL level is, a module may only want to use OO interface and in that scenario, you’d only implement types and the entrypoint fn would only receive capabilities, references to structs which point to functions. One use case for an IDL here is the host system would know that the module wants OO type vs ADT style, does that make sense? + +TS: I think so, thanks for the clarification + +M: that said, since we don’t have, since it’s not given we don’t have GC or func ref, (func ref?) looks more promising, it might not be worthwhile to worry about this. It might not be worth worrying about this yet and just focus on ADT style + +DG: as far as next steps, martin you mentioned that you’ll post an updated version of the proposal? + +M: yep + +DG: we’ll iterate from there. Anything else we want to cover in this meeting? + +M: I also wrote up some stuff about virtualization, should I add that to the repo? + +DG: Sure, make a PR and we can discuss it and decide if we want to incorporate it + +DG: that’s a good point, virt. Is an interesting enough point that we should document what we’re going to do in this space + +DG: next on the agenda, with the theme of setting up the wasi_unstable namespace, what are the blockers that we have before we can split up wasi_unstable into modules and working on them. Having an IDL nicer than a C header file or markdown is good, are there other blockers? + +LW: do you think we should hold off until we can make use of reference types and type imports? Or do we want to do it later + +DG: I think that’s something we can deal with later. When we have full snowman bindings, we’ll want to convert them into that form, and emulating lower level concepts with our higher level types. We need to figure out what is a file and that doesn’t need to wait for (those things) + +TS: maybe we should say that the changes we make going forward should take these concepts into mind, (describes using indirection of fds in a table of anyref to make transition easier) + +DG: that seems reasonable and I think that will somewhat naturally fallout given API design. We want a vocab to talk about things until we have an actual IDL, we can do API design with C headers but it’s not ideal, so we should figure out what to do there. MAking it easier to migrate to future bindings systems seems great + +TS: two advantages, we can do API design now knowing thta API design can map well, later on we have a straight forward way to make it easy to consume in C/CPP/Rust. Two APIs with the AnyRef being the fundamental and an indice-only one on top of it + +DG: how much do we want to do now vs waiting for snowman bindings? If we just design with this in mind, it will be pretty straight forward to retro fit this, that’s my gut feeling here. + +TS: All I’m proposing is making that explicit that we want to have this 1-to-1 relationship, making that relationship straight-forward + +DG: should we have a document about “How to design a WASI API” + +M: that sounds like a good idea + +DG: martin or till do you want to start a document like that? + +TS: I can start that document by writing what I just said and then we can flesh it out with more content + +DG: it can evolve as we get snowman bindings and other tools + +LW: it might be good to have a “future intended steps” section. The intent to move to ref types and binding types are only in our own heads and we should document that somewhere + +DG: looking for someone to document OCAP vision and put it in a repo, if someone wants to do that, that’d be great. It’s been discussed in various places, but we don’t have a document in the repo describing the plan. IF someone could digest that down and start that, that’s what we’re looking for + +LW: I can help there + +DG: we have the docs directory in the WASI repo. Alright, I’m trying to push forward to the point where we can do API design. Are there any other blockers? We’ll have a document, (somethinG) in progress, and a plan … for a module naming system, temporary one, pending discussion about import naming schemes. That’s the end of the agenda. Is there anything else? + +SC: presumably we’ll need an IDL to header file conversion after, +DG: yes (..) + rust interface generation + +M: … +LW: … +TS: s-expressions as type definitions minus the body is the obvious way to define the functions. WHat’s missing is how to fit the binding expressions in there + +LW: importantly, binding expressions don’t fit in there, interface is just the types + +M: to generate a header file, you’d need the IDL and the bindings and they do need to be separate because different languages want different bindings + +LW: I’m not quite sure what you mean by supplying the bindings. You could generate for say, C, there’d be policy choices like what to do with strings, but it’s possible. Sounds like a cool tool though + +DG: that sounds like the end of the meeting, see you all in 2 weeks From 436800ff73da1f083b34795d19bdc0465d3baf90 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Aug 2019 16:50:01 -0700 Subject: [PATCH 0070/1772] Add a preliminary agenda for the WASI-08-30 meeting. Note that as discussed in the previous meeting, we're changing the time for this meeting to accomodate people in different time zones. --- proposals/clocks/meetings/2019/WASI-08-30.md | 46 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 47 insertions(+) create mode 100644 proposals/clocks/meetings/2019/WASI-08-30.md diff --git a/proposals/clocks/meetings/2019/WASI-08-30.md b/proposals/clocks/meetings/2019/WASI-08-30.md new file mode 100644 index 000000000..fd2f274a1 --- /dev/null +++ b/proposals/clocks/meetings/2019/WASI-08-30.md @@ -0,0 +1,46 @@ +![WASI logo](/WASI.png) + +## Agenda for the August 30 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: August 30, 06:00–07:00 UTC -- Note the time change! +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. WASI for Embedded, by Wang, Xin + 1. Update on the Interface description based on Module types: + - https://github.com/WebAssembly/WASI/pull/74 + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index a32a1cf8e..50ce6eeb3 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -14,3 +14,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI June 27th video call](2019/WASI-06-27.md) * [WASI July 18th video call](2019/WASI-07-18.md) * [WASI August 15th video call](2019/WASI-08-15.md) + * [WASI August 30th video call](2019/WASI-08-30.md) From 6afae300cb0227cfbfaa6765da3cf29c495013f6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Aug 2019 16:50:01 -0700 Subject: [PATCH 0071/1772] Add a preliminary agenda for the WASI-08-30 meeting. Note that as discussed in the previous meeting, we're changing the time for this meeting to accomodate people in different time zones. --- proposals/random/meetings/2019/WASI-08-30.md | 46 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 47 insertions(+) create mode 100644 proposals/random/meetings/2019/WASI-08-30.md diff --git a/proposals/random/meetings/2019/WASI-08-30.md b/proposals/random/meetings/2019/WASI-08-30.md new file mode 100644 index 000000000..fd2f274a1 --- /dev/null +++ b/proposals/random/meetings/2019/WASI-08-30.md @@ -0,0 +1,46 @@ +![WASI logo](/WASI.png) + +## Agenda for the August 30 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: August 30, 06:00–07:00 UTC -- Note the time change! +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. WASI for Embedded, by Wang, Xin + 1. Update on the Interface description based on Module types: + - https://github.com/WebAssembly/WASI/pull/74 + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index a32a1cf8e..50ce6eeb3 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -14,3 +14,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI June 27th video call](2019/WASI-06-27.md) * [WASI July 18th video call](2019/WASI-07-18.md) * [WASI August 15th video call](2019/WASI-08-15.md) + * [WASI August 30th video call](2019/WASI-08-30.md) From 77ca4ceea924caa82270f74bd0709ffa6e649664 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Aug 2019 16:50:01 -0700 Subject: [PATCH 0072/1772] Add a preliminary agenda for the WASI-08-30 meeting. Note that as discussed in the previous meeting, we're changing the time for this meeting to accomodate people in different time zones. --- .../filesystem/meetings/2019/WASI-08-30.md | 46 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 47 insertions(+) create mode 100644 proposals/filesystem/meetings/2019/WASI-08-30.md diff --git a/proposals/filesystem/meetings/2019/WASI-08-30.md b/proposals/filesystem/meetings/2019/WASI-08-30.md new file mode 100644 index 000000000..fd2f274a1 --- /dev/null +++ b/proposals/filesystem/meetings/2019/WASI-08-30.md @@ -0,0 +1,46 @@ +![WASI logo](/WASI.png) + +## Agenda for the August 30 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: August 30, 06:00–07:00 UTC -- Note the time change! +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. WASI for Embedded, by Wang, Xin + 1. Update on the Interface description based on Module types: + - https://github.com/WebAssembly/WASI/pull/74 + +1. Closure + +## Agenda items for future meetings + +*None* + +### Schedule constraints + +*None* + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index a32a1cf8e..50ce6eeb3 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -14,3 +14,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI June 27th video call](2019/WASI-06-27.md) * [WASI July 18th video call](2019/WASI-07-18.md) * [WASI August 15th video call](2019/WASI-08-15.md) + * [WASI August 30th video call](2019/WASI-08-30.md) From 567dd2ccdcb9b2b6baa9f53f429919d5f476b8ff Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 30 May 2019 11:44:41 -0700 Subject: [PATCH 0073/1772] Add a writeup of current weak imports design I wrote up this as initially proposed by Dan, using name mangling rather than a custom section. I believe there is still room to switch a custom section if people feel strongly about it. The main downsides I see of using such mangling are: 1. It is that reserves the ".weak" and ".is_present" suffixes 2. It might not play nicely with possible future attributes we might want to add to imports. Fixes #36 --- proposals/clocks/design/weak-imports.md | 68 +++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 proposals/clocks/design/weak-imports.md diff --git a/proposals/clocks/design/weak-imports.md b/proposals/clocks/design/weak-imports.md new file mode 100644 index 000000000..b048e13ba --- /dev/null +++ b/proposals/clocks/design/weak-imports.md @@ -0,0 +1,68 @@ +Weak Imports +============ + +It can be useful for WASI programs to weakly depend on certain functions in a +WASI API. For example, if a WASI API evolves to include a new function a +program might want to continue to run on older systems that don't yet support +the new function. In this case a weak import mechanism allows the program to +run on older systems and detect the presence of the function at runtime. +Another use case might be a API that is not applicable on certain embedding. In +this case weak import would allow program to run continue to run on such an +embedded, albeit with reduced or modified behavior. + +*Note*: The term *weak* here refers to a type of symbol reference used by a +linker and comes from the ELF specification. It is not related to the +JavaScript [weakrefs] proposal or to garbage collection. + +WebAssembly itself does not currently provide a mechanism for weak imports. +There is some discussion of adding it the [spec][spec], and WASI would likely +use such a feature if/when it is added. + +This document describes the mechanism used by WASI to achieve a form of weak +import on top of the existing primitives. Currently this is only defined for +function imports. + +Declaring a weak function import +-------------------------------- + +Weak function imports are implemened by using two imports for each function. +The first being the weak function and the second being a WebAssembly i32 global +to indicate if the function is present at runtime. + +For example, if a module called `wasi:fs` added a new `statvfs` function to its +interface a program could import this new function weakly in the following way: + +```wasm +(func $statvfs (import "wasi:fs" "statvfs.weak")) +(global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) +``` + +On older systems that don't support the new function `$statvfs_is_present` would +be set to zero and calling `$statvfs` would result in a trap. + +On systems that do support the new function `$statvfs_is_present` is set to +one and calling `$statvfs` would work as expected. + +Using a weak function import +---------------------------- + +In order to use the above weak function import its presence should first be +tested for. In C code this would look something like this: + +```c +if (wasm_fs.statvfs) { + wasm_fs.statvfs(...) +} +``` + +At the WebAssembly level it might look like this: + +```wasm +global.get $statvfs_is_present +if i32 + call $statvfs +end +``` + +[weakrefs]: https://github.com/tc39/proposal-weakrefs +[spec]: https://github.com/WebAssembly/design/issues/1281 From d18062d23257f40636ac3c027f1fd5cb1d5944db Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 30 May 2019 11:44:41 -0700 Subject: [PATCH 0074/1772] Add a writeup of current weak imports design I wrote up this as initially proposed by Dan, using name mangling rather than a custom section. I believe there is still room to switch a custom section if people feel strongly about it. The main downsides I see of using such mangling are: 1. It is that reserves the ".weak" and ".is_present" suffixes 2. It might not play nicely with possible future attributes we might want to add to imports. Fixes #36 --- proposals/random/design/weak-imports.md | 68 +++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 proposals/random/design/weak-imports.md diff --git a/proposals/random/design/weak-imports.md b/proposals/random/design/weak-imports.md new file mode 100644 index 000000000..b048e13ba --- /dev/null +++ b/proposals/random/design/weak-imports.md @@ -0,0 +1,68 @@ +Weak Imports +============ + +It can be useful for WASI programs to weakly depend on certain functions in a +WASI API. For example, if a WASI API evolves to include a new function a +program might want to continue to run on older systems that don't yet support +the new function. In this case a weak import mechanism allows the program to +run on older systems and detect the presence of the function at runtime. +Another use case might be a API that is not applicable on certain embedding. In +this case weak import would allow program to run continue to run on such an +embedded, albeit with reduced or modified behavior. + +*Note*: The term *weak* here refers to a type of symbol reference used by a +linker and comes from the ELF specification. It is not related to the +JavaScript [weakrefs] proposal or to garbage collection. + +WebAssembly itself does not currently provide a mechanism for weak imports. +There is some discussion of adding it the [spec][spec], and WASI would likely +use such a feature if/when it is added. + +This document describes the mechanism used by WASI to achieve a form of weak +import on top of the existing primitives. Currently this is only defined for +function imports. + +Declaring a weak function import +-------------------------------- + +Weak function imports are implemened by using two imports for each function. +The first being the weak function and the second being a WebAssembly i32 global +to indicate if the function is present at runtime. + +For example, if a module called `wasi:fs` added a new `statvfs` function to its +interface a program could import this new function weakly in the following way: + +```wasm +(func $statvfs (import "wasi:fs" "statvfs.weak")) +(global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) +``` + +On older systems that don't support the new function `$statvfs_is_present` would +be set to zero and calling `$statvfs` would result in a trap. + +On systems that do support the new function `$statvfs_is_present` is set to +one and calling `$statvfs` would work as expected. + +Using a weak function import +---------------------------- + +In order to use the above weak function import its presence should first be +tested for. In C code this would look something like this: + +```c +if (wasm_fs.statvfs) { + wasm_fs.statvfs(...) +} +``` + +At the WebAssembly level it might look like this: + +```wasm +global.get $statvfs_is_present +if i32 + call $statvfs +end +``` + +[weakrefs]: https://github.com/tc39/proposal-weakrefs +[spec]: https://github.com/WebAssembly/design/issues/1281 From 546d870028c14c9cc3100a51a18b949ae5d8f32c Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 30 May 2019 11:44:41 -0700 Subject: [PATCH 0075/1772] Add a writeup of current weak imports design I wrote up this as initially proposed by Dan, using name mangling rather than a custom section. I believe there is still room to switch a custom section if people feel strongly about it. The main downsides I see of using such mangling are: 1. It is that reserves the ".weak" and ".is_present" suffixes 2. It might not play nicely with possible future attributes we might want to add to imports. Fixes #36 --- proposals/filesystem/design/weak-imports.md | 68 +++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 proposals/filesystem/design/weak-imports.md diff --git a/proposals/filesystem/design/weak-imports.md b/proposals/filesystem/design/weak-imports.md new file mode 100644 index 000000000..b048e13ba --- /dev/null +++ b/proposals/filesystem/design/weak-imports.md @@ -0,0 +1,68 @@ +Weak Imports +============ + +It can be useful for WASI programs to weakly depend on certain functions in a +WASI API. For example, if a WASI API evolves to include a new function a +program might want to continue to run on older systems that don't yet support +the new function. In this case a weak import mechanism allows the program to +run on older systems and detect the presence of the function at runtime. +Another use case might be a API that is not applicable on certain embedding. In +this case weak import would allow program to run continue to run on such an +embedded, albeit with reduced or modified behavior. + +*Note*: The term *weak* here refers to a type of symbol reference used by a +linker and comes from the ELF specification. It is not related to the +JavaScript [weakrefs] proposal or to garbage collection. + +WebAssembly itself does not currently provide a mechanism for weak imports. +There is some discussion of adding it the [spec][spec], and WASI would likely +use such a feature if/when it is added. + +This document describes the mechanism used by WASI to achieve a form of weak +import on top of the existing primitives. Currently this is only defined for +function imports. + +Declaring a weak function import +-------------------------------- + +Weak function imports are implemened by using two imports for each function. +The first being the weak function and the second being a WebAssembly i32 global +to indicate if the function is present at runtime. + +For example, if a module called `wasi:fs` added a new `statvfs` function to its +interface a program could import this new function weakly in the following way: + +```wasm +(func $statvfs (import "wasi:fs" "statvfs.weak")) +(global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) +``` + +On older systems that don't support the new function `$statvfs_is_present` would +be set to zero and calling `$statvfs` would result in a trap. + +On systems that do support the new function `$statvfs_is_present` is set to +one and calling `$statvfs` would work as expected. + +Using a weak function import +---------------------------- + +In order to use the above weak function import its presence should first be +tested for. In C code this would look something like this: + +```c +if (wasm_fs.statvfs) { + wasm_fs.statvfs(...) +} +``` + +At the WebAssembly level it might look like this: + +```wasm +global.get $statvfs_is_present +if i32 + call $statvfs +end +``` + +[weakrefs]: https://github.com/tc39/proposal-weakrefs +[spec]: https://github.com/WebAssembly/design/issues/1281 From a5ad6a783e069bf6edbc81e5c49bf21715550672 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 13 Aug 2019 17:43:27 -0700 Subject: [PATCH 0076/1772] custom section --- proposals/clocks/design/weak-imports.md | 74 +++++++++++++++++++------ 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/proposals/clocks/design/weak-imports.md b/proposals/clocks/design/weak-imports.md index b048e13ba..842f82bec 100644 --- a/proposals/clocks/design/weak-imports.md +++ b/proposals/clocks/design/weak-imports.md @@ -6,28 +6,28 @@ WASI API. For example, if a WASI API evolves to include a new function a program might want to continue to run on older systems that don't yet support the new function. In this case a weak import mechanism allows the program to run on older systems and detect the presence of the function at runtime. -Another use case might be a API that is not applicable on certain embedding. In -this case weak import would allow program to run continue to run on such an -embedded, albeit with reduced or modified behavior. +Another use case is an API that is not applicable on certain embedding. In this +case weak import would allow program to continue to run in such an embedding, +albeit with reduced or modified behavior. *Note*: The term *weak* here refers to a type of symbol reference used by a linker and comes from the ELF specification. It is not related to the JavaScript [weakrefs] proposal or to garbage collection. WebAssembly itself does not currently provide a mechanism for weak imports. -There is some discussion of adding it the [spec][spec], and WASI would likely -use such a feature if/when it is added. +There is some discussion of adding it to the [spec][spec], and WASI would likely +use such a feature if/when it is added. In the absence of first class weak +imports this document describes the mechanism used by WASI to specify weak +imports a custom section. Currently this is only specified for function +imports. -This document describes the mechanism used by WASI to achieve a form of weak -import on top of the existing primitives. Currently this is only defined for -function imports. +Declaring a weak import +----------------------- -Declaring a weak function import --------------------------------- - -Weak function imports are implemened by using two imports for each function. -The first being the weak function and the second being a WebAssembly i32 global -to indicate if the function is present at runtime. +Weak function imports are implemented using two imports for each function. The +first being the weak function itself and the second being an i32 global which +indicates if the function is present at runtime. We call this addition import +the guard. For example, if a module called `wasi:fs` added a new `statvfs` function to its interface a program could import this new function weakly in the following way: @@ -37,11 +37,14 @@ interface a program could import this new function weakly in the following way: (global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) ``` -On older systems that don't support the new function `$statvfs_is_present` would -be set to zero and calling `$statvfs` would result in a trap. +These two imports would also need to be added to the `import.weak` custom +section (See below). + +On older systems that don't support the new function, `$statvfs_is_present` +would be set to 0 and calling `$statvfs` would result in a trap. -On systems that do support the new function `$statvfs_is_present` is set to -one and calling `$statvfs` would work as expected. +On systems that do support the new function, `$statvfs_is_present` is set to +1 and calling `$statvfs` would work as expected. Using a weak function import ---------------------------- @@ -64,5 +67,40 @@ if i32 end ``` +Weak import custom section +-------------------------- + +A custom section is used to specify which imports are weak, and for each weak +import the name of the corresponding guard (the global import which is used to +signal its presence). For each module that contains weak imports the +module name is specified once followed by a list of its weak import along with +their corresponding guards. + +The name of this custom section is `import.weak` and its contents are as +follows: + +| Field | Type | Description | +| ----------------| ------------------- | ------------------------------------| +| count | `varuint32` | count of mod_weak_imports to follow | +| mod_weak_imports| `weak_import_list*` | sequence if weak import lists | + +Each `weak_import_list` has the following content: + +| Field | Type | Description | +| --------------| ------------------- | ------------------------------------- | +| mod_name_len | `varuint32` | the length of `mod_name_data` in bytes| +| mod_name_data | `bytes` | UTF-8 encoding of the module name | +| count | `varuint32` | count of `weak_import` to follow | +| weak_import | `weak_import*` | sequence of `weak_import` | + +Each `weak_import` has the following content: + +| Field | Type | Description | +| --------------- | ---------------- | --------------------------------------- | +| name_len | `varuint32` | the length of `name_data` in bytes | +| name_data | `bytes` | UTF-8 encoding of the import name | +| guard_name_len | `varuint32` | the length of `guard_name_data` in bytes| +| guard_name_data | `bytes` | UTF-8 encoding of the import name | + [weakrefs]: https://github.com/tc39/proposal-weakrefs [spec]: https://github.com/WebAssembly/design/issues/1281 From 6814f03ed4aa346c7d5a1cd0443ae7819b65d8ae Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 13 Aug 2019 17:43:27 -0700 Subject: [PATCH 0077/1772] custom section --- proposals/random/design/weak-imports.md | 74 +++++++++++++++++++------ 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/proposals/random/design/weak-imports.md b/proposals/random/design/weak-imports.md index b048e13ba..842f82bec 100644 --- a/proposals/random/design/weak-imports.md +++ b/proposals/random/design/weak-imports.md @@ -6,28 +6,28 @@ WASI API. For example, if a WASI API evolves to include a new function a program might want to continue to run on older systems that don't yet support the new function. In this case a weak import mechanism allows the program to run on older systems and detect the presence of the function at runtime. -Another use case might be a API that is not applicable on certain embedding. In -this case weak import would allow program to run continue to run on such an -embedded, albeit with reduced or modified behavior. +Another use case is an API that is not applicable on certain embedding. In this +case weak import would allow program to continue to run in such an embedding, +albeit with reduced or modified behavior. *Note*: The term *weak* here refers to a type of symbol reference used by a linker and comes from the ELF specification. It is not related to the JavaScript [weakrefs] proposal or to garbage collection. WebAssembly itself does not currently provide a mechanism for weak imports. -There is some discussion of adding it the [spec][spec], and WASI would likely -use such a feature if/when it is added. +There is some discussion of adding it to the [spec][spec], and WASI would likely +use such a feature if/when it is added. In the absence of first class weak +imports this document describes the mechanism used by WASI to specify weak +imports a custom section. Currently this is only specified for function +imports. -This document describes the mechanism used by WASI to achieve a form of weak -import on top of the existing primitives. Currently this is only defined for -function imports. +Declaring a weak import +----------------------- -Declaring a weak function import --------------------------------- - -Weak function imports are implemened by using two imports for each function. -The first being the weak function and the second being a WebAssembly i32 global -to indicate if the function is present at runtime. +Weak function imports are implemented using two imports for each function. The +first being the weak function itself and the second being an i32 global which +indicates if the function is present at runtime. We call this addition import +the guard. For example, if a module called `wasi:fs` added a new `statvfs` function to its interface a program could import this new function weakly in the following way: @@ -37,11 +37,14 @@ interface a program could import this new function weakly in the following way: (global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) ``` -On older systems that don't support the new function `$statvfs_is_present` would -be set to zero and calling `$statvfs` would result in a trap. +These two imports would also need to be added to the `import.weak` custom +section (See below). + +On older systems that don't support the new function, `$statvfs_is_present` +would be set to 0 and calling `$statvfs` would result in a trap. -On systems that do support the new function `$statvfs_is_present` is set to -one and calling `$statvfs` would work as expected. +On systems that do support the new function, `$statvfs_is_present` is set to +1 and calling `$statvfs` would work as expected. Using a weak function import ---------------------------- @@ -64,5 +67,40 @@ if i32 end ``` +Weak import custom section +-------------------------- + +A custom section is used to specify which imports are weak, and for each weak +import the name of the corresponding guard (the global import which is used to +signal its presence). For each module that contains weak imports the +module name is specified once followed by a list of its weak import along with +their corresponding guards. + +The name of this custom section is `import.weak` and its contents are as +follows: + +| Field | Type | Description | +| ----------------| ------------------- | ------------------------------------| +| count | `varuint32` | count of mod_weak_imports to follow | +| mod_weak_imports| `weak_import_list*` | sequence if weak import lists | + +Each `weak_import_list` has the following content: + +| Field | Type | Description | +| --------------| ------------------- | ------------------------------------- | +| mod_name_len | `varuint32` | the length of `mod_name_data` in bytes| +| mod_name_data | `bytes` | UTF-8 encoding of the module name | +| count | `varuint32` | count of `weak_import` to follow | +| weak_import | `weak_import*` | sequence of `weak_import` | + +Each `weak_import` has the following content: + +| Field | Type | Description | +| --------------- | ---------------- | --------------------------------------- | +| name_len | `varuint32` | the length of `name_data` in bytes | +| name_data | `bytes` | UTF-8 encoding of the import name | +| guard_name_len | `varuint32` | the length of `guard_name_data` in bytes| +| guard_name_data | `bytes` | UTF-8 encoding of the import name | + [weakrefs]: https://github.com/tc39/proposal-weakrefs [spec]: https://github.com/WebAssembly/design/issues/1281 From 6f830f5243dc6350e88e0d8f9061dd39eea7481f Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 13 Aug 2019 17:43:27 -0700 Subject: [PATCH 0078/1772] custom section --- proposals/filesystem/design/weak-imports.md | 74 ++++++++++++++++----- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/proposals/filesystem/design/weak-imports.md b/proposals/filesystem/design/weak-imports.md index b048e13ba..842f82bec 100644 --- a/proposals/filesystem/design/weak-imports.md +++ b/proposals/filesystem/design/weak-imports.md @@ -6,28 +6,28 @@ WASI API. For example, if a WASI API evolves to include a new function a program might want to continue to run on older systems that don't yet support the new function. In this case a weak import mechanism allows the program to run on older systems and detect the presence of the function at runtime. -Another use case might be a API that is not applicable on certain embedding. In -this case weak import would allow program to run continue to run on such an -embedded, albeit with reduced or modified behavior. +Another use case is an API that is not applicable on certain embedding. In this +case weak import would allow program to continue to run in such an embedding, +albeit with reduced or modified behavior. *Note*: The term *weak* here refers to a type of symbol reference used by a linker and comes from the ELF specification. It is not related to the JavaScript [weakrefs] proposal or to garbage collection. WebAssembly itself does not currently provide a mechanism for weak imports. -There is some discussion of adding it the [spec][spec], and WASI would likely -use such a feature if/when it is added. +There is some discussion of adding it to the [spec][spec], and WASI would likely +use such a feature if/when it is added. In the absence of first class weak +imports this document describes the mechanism used by WASI to specify weak +imports a custom section. Currently this is only specified for function +imports. -This document describes the mechanism used by WASI to achieve a form of weak -import on top of the existing primitives. Currently this is only defined for -function imports. +Declaring a weak import +----------------------- -Declaring a weak function import --------------------------------- - -Weak function imports are implemened by using two imports for each function. -The first being the weak function and the second being a WebAssembly i32 global -to indicate if the function is present at runtime. +Weak function imports are implemented using two imports for each function. The +first being the weak function itself and the second being an i32 global which +indicates if the function is present at runtime. We call this addition import +the guard. For example, if a module called `wasi:fs` added a new `statvfs` function to its interface a program could import this new function weakly in the following way: @@ -37,11 +37,14 @@ interface a program could import this new function weakly in the following way: (global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) ``` -On older systems that don't support the new function `$statvfs_is_present` would -be set to zero and calling `$statvfs` would result in a trap. +These two imports would also need to be added to the `import.weak` custom +section (See below). + +On older systems that don't support the new function, `$statvfs_is_present` +would be set to 0 and calling `$statvfs` would result in a trap. -On systems that do support the new function `$statvfs_is_present` is set to -one and calling `$statvfs` would work as expected. +On systems that do support the new function, `$statvfs_is_present` is set to +1 and calling `$statvfs` would work as expected. Using a weak function import ---------------------------- @@ -64,5 +67,40 @@ if i32 end ``` +Weak import custom section +-------------------------- + +A custom section is used to specify which imports are weak, and for each weak +import the name of the corresponding guard (the global import which is used to +signal its presence). For each module that contains weak imports the +module name is specified once followed by a list of its weak import along with +their corresponding guards. + +The name of this custom section is `import.weak` and its contents are as +follows: + +| Field | Type | Description | +| ----------------| ------------------- | ------------------------------------| +| count | `varuint32` | count of mod_weak_imports to follow | +| mod_weak_imports| `weak_import_list*` | sequence if weak import lists | + +Each `weak_import_list` has the following content: + +| Field | Type | Description | +| --------------| ------------------- | ------------------------------------- | +| mod_name_len | `varuint32` | the length of `mod_name_data` in bytes| +| mod_name_data | `bytes` | UTF-8 encoding of the module name | +| count | `varuint32` | count of `weak_import` to follow | +| weak_import | `weak_import*` | sequence of `weak_import` | + +Each `weak_import` has the following content: + +| Field | Type | Description | +| --------------- | ---------------- | --------------------------------------- | +| name_len | `varuint32` | the length of `name_data` in bytes | +| name_data | `bytes` | UTF-8 encoding of the import name | +| guard_name_len | `varuint32` | the length of `guard_name_data` in bytes| +| guard_name_data | `bytes` | UTF-8 encoding of the import name | + [weakrefs]: https://github.com/tc39/proposal-weakrefs [spec]: https://github.com/WebAssembly/design/issues/1281 From 7a3606a7be399637ce814ebbb49eed73a4ef3aaa Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 22 Aug 2019 18:43:39 -0700 Subject: [PATCH 0079/1772] rename weak to optional --- proposals/clocks/design/optional-imports.md | 108 ++++++++++++++++++++ proposals/clocks/design/weak-imports.md | 106 ------------------- 2 files changed, 108 insertions(+), 106 deletions(-) create mode 100644 proposals/clocks/design/optional-imports.md delete mode 100644 proposals/clocks/design/weak-imports.md diff --git a/proposals/clocks/design/optional-imports.md b/proposals/clocks/design/optional-imports.md new file mode 100644 index 000000000..543599a10 --- /dev/null +++ b/proposals/clocks/design/optional-imports.md @@ -0,0 +1,108 @@ +Optional Imports +================ + +It can be useful for WASI programs to optionally depend on certain functions in a +WASI API. For example, if a WASI API evolves to include a new function a +program might want to continue to run on older systems that don't yet support +the new function. In this case a optional import mechanism allows the program +to run on older systems and detect the presence of the function at runtime. +Another use case is an API that is not applicable on certain embedding. In this +case optionals imports would allow program to continue to run in such an +embedding, albeit with reduced or modified behavior. + +*Note*: In the ELF specification this type of import is known as *weak*. +We chose *optional* because the term weak is already used other context in +WebAssembly and JavaScript, specifically in JavaScript [weakrefs] proposal where +it relates to garbage collection. + +WebAssembly itself does not currently provide a mechanism for optional imports. +There is some discussion of adding it to the [spec][spec], and WASI would likely +use such a feature if/when it is added. In the absence of first class optional +imports this document describes the mechanism used by WASI to specify optional +imports using a custom section. Currently this is only specified for function +imports. + +Declaring an optional import +---------------------------- + +Optional function imports are implemented using two imports for each function. +The first being the optional function itself and the second being an i32 global +which indicates if the function is present at runtime. We call this addition +import the guard. + +For example, if a module called `wasi:fs` added a new `statvfs` function to its +interface a program could optionally import this new function in the following +way: + +```wasm +(func $statvfs (import "wasi:fs" "statvfs.optional")) +(global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) +``` + +These two imports would also need to be added to the `import.optional` custom +section (See below). + +On older systems that don't support the new function, `$statvfs_is_present` +would be set to 0 and calling `$statvfs` would result in a trap. + +On systems that do support the new function, `$statvfs_is_present` is set to +1 and calling `$statvfs` would work as expected. + +Using an optional function import +--------------------------------- + +In order to use the above options function its presence should first be tested +for. In C code this would look something like this: + +```c +if (__wasm_is_present(wasm_fs.statvfs)) { + wasm_fs.statvfs(...) +} +``` + +At the WebAssembly level it might look like this: + +```wasm +global.get $statvfs_is_present +if i32 + call $statvfs +end +``` + +Custom section +-------------- + +A custom section is used to specify which imports are optional, and for each +optional import the name of the corresponding guard (the global import which is +used to signal its presence). For each module that contains optional imports +the module name is specified once followed by a list of its optional imports +along with their corresponding guards. + +The name of this custom section is `import.optional` and its contents are as +follows: + +| Field | Type | Description | +| ----------------| ---------------------- | -------------------------------- | +| count | `varuint32` | count of mod_optionals to follow | +| mod_optionals | `optional_import_list*`| sequence if optional_import_list | + +Each `optional_import_list` has the following content: + +| Field | Type | Description | +| --------------| ------------------- | ------------------------------------- | +| mod_name_len | `varuint32` | the length of `mod_name_data` in bytes| +| mod_name_data | `bytes` | UTF-8 encoding of the module name | +| count | `varuint32` | count of `opt_import` to follow | +| opt_import | `opt_import*` | sequence of `opt_import` | + +Each `opt_import` has the following content: + +| Field | Type | Description | +| --------------- | ---------------- | --------------------------------------- | +| name_len | `varuint32` | the length of `name_data` in bytes | +| name_data | `bytes` | UTF-8 encoding of the import name | +| guard_name_len | `varuint32` | the length of `guard_name_data` in bytes| +| guard_name_data | `bytes` | UTF-8 encoding of the import name | + +[weakrefs]: https://github.com/tc39/proposal-weakrefs +[spec]: https://github.com/WebAssembly/design/issues/1281 diff --git a/proposals/clocks/design/weak-imports.md b/proposals/clocks/design/weak-imports.md deleted file mode 100644 index 842f82bec..000000000 --- a/proposals/clocks/design/weak-imports.md +++ /dev/null @@ -1,106 +0,0 @@ -Weak Imports -============ - -It can be useful for WASI programs to weakly depend on certain functions in a -WASI API. For example, if a WASI API evolves to include a new function a -program might want to continue to run on older systems that don't yet support -the new function. In this case a weak import mechanism allows the program to -run on older systems and detect the presence of the function at runtime. -Another use case is an API that is not applicable on certain embedding. In this -case weak import would allow program to continue to run in such an embedding, -albeit with reduced or modified behavior. - -*Note*: The term *weak* here refers to a type of symbol reference used by a -linker and comes from the ELF specification. It is not related to the -JavaScript [weakrefs] proposal or to garbage collection. - -WebAssembly itself does not currently provide a mechanism for weak imports. -There is some discussion of adding it to the [spec][spec], and WASI would likely -use such a feature if/when it is added. In the absence of first class weak -imports this document describes the mechanism used by WASI to specify weak -imports a custom section. Currently this is only specified for function -imports. - -Declaring a weak import ------------------------ - -Weak function imports are implemented using two imports for each function. The -first being the weak function itself and the second being an i32 global which -indicates if the function is present at runtime. We call this addition import -the guard. - -For example, if a module called `wasi:fs` added a new `statvfs` function to its -interface a program could import this new function weakly in the following way: - -```wasm -(func $statvfs (import "wasi:fs" "statvfs.weak")) -(global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) -``` - -These two imports would also need to be added to the `import.weak` custom -section (See below). - -On older systems that don't support the new function, `$statvfs_is_present` -would be set to 0 and calling `$statvfs` would result in a trap. - -On systems that do support the new function, `$statvfs_is_present` is set to -1 and calling `$statvfs` would work as expected. - -Using a weak function import ----------------------------- - -In order to use the above weak function import its presence should first be -tested for. In C code this would look something like this: - -```c -if (wasm_fs.statvfs) { - wasm_fs.statvfs(...) -} -``` - -At the WebAssembly level it might look like this: - -```wasm -global.get $statvfs_is_present -if i32 - call $statvfs -end -``` - -Weak import custom section --------------------------- - -A custom section is used to specify which imports are weak, and for each weak -import the name of the corresponding guard (the global import which is used to -signal its presence). For each module that contains weak imports the -module name is specified once followed by a list of its weak import along with -their corresponding guards. - -The name of this custom section is `import.weak` and its contents are as -follows: - -| Field | Type | Description | -| ----------------| ------------------- | ------------------------------------| -| count | `varuint32` | count of mod_weak_imports to follow | -| mod_weak_imports| `weak_import_list*` | sequence if weak import lists | - -Each `weak_import_list` has the following content: - -| Field | Type | Description | -| --------------| ------------------- | ------------------------------------- | -| mod_name_len | `varuint32` | the length of `mod_name_data` in bytes| -| mod_name_data | `bytes` | UTF-8 encoding of the module name | -| count | `varuint32` | count of `weak_import` to follow | -| weak_import | `weak_import*` | sequence of `weak_import` | - -Each `weak_import` has the following content: - -| Field | Type | Description | -| --------------- | ---------------- | --------------------------------------- | -| name_len | `varuint32` | the length of `name_data` in bytes | -| name_data | `bytes` | UTF-8 encoding of the import name | -| guard_name_len | `varuint32` | the length of `guard_name_data` in bytes| -| guard_name_data | `bytes` | UTF-8 encoding of the import name | - -[weakrefs]: https://github.com/tc39/proposal-weakrefs -[spec]: https://github.com/WebAssembly/design/issues/1281 From 7a9d00c11f91c9835b347a0efe607b4a9cf2d76e Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 22 Aug 2019 18:43:39 -0700 Subject: [PATCH 0080/1772] rename weak to optional --- proposals/random/design/optional-imports.md | 108 ++++++++++++++++++++ proposals/random/design/weak-imports.md | 106 ------------------- 2 files changed, 108 insertions(+), 106 deletions(-) create mode 100644 proposals/random/design/optional-imports.md delete mode 100644 proposals/random/design/weak-imports.md diff --git a/proposals/random/design/optional-imports.md b/proposals/random/design/optional-imports.md new file mode 100644 index 000000000..543599a10 --- /dev/null +++ b/proposals/random/design/optional-imports.md @@ -0,0 +1,108 @@ +Optional Imports +================ + +It can be useful for WASI programs to optionally depend on certain functions in a +WASI API. For example, if a WASI API evolves to include a new function a +program might want to continue to run on older systems that don't yet support +the new function. In this case a optional import mechanism allows the program +to run on older systems and detect the presence of the function at runtime. +Another use case is an API that is not applicable on certain embedding. In this +case optionals imports would allow program to continue to run in such an +embedding, albeit with reduced or modified behavior. + +*Note*: In the ELF specification this type of import is known as *weak*. +We chose *optional* because the term weak is already used other context in +WebAssembly and JavaScript, specifically in JavaScript [weakrefs] proposal where +it relates to garbage collection. + +WebAssembly itself does not currently provide a mechanism for optional imports. +There is some discussion of adding it to the [spec][spec], and WASI would likely +use such a feature if/when it is added. In the absence of first class optional +imports this document describes the mechanism used by WASI to specify optional +imports using a custom section. Currently this is only specified for function +imports. + +Declaring an optional import +---------------------------- + +Optional function imports are implemented using two imports for each function. +The first being the optional function itself and the second being an i32 global +which indicates if the function is present at runtime. We call this addition +import the guard. + +For example, if a module called `wasi:fs` added a new `statvfs` function to its +interface a program could optionally import this new function in the following +way: + +```wasm +(func $statvfs (import "wasi:fs" "statvfs.optional")) +(global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) +``` + +These two imports would also need to be added to the `import.optional` custom +section (See below). + +On older systems that don't support the new function, `$statvfs_is_present` +would be set to 0 and calling `$statvfs` would result in a trap. + +On systems that do support the new function, `$statvfs_is_present` is set to +1 and calling `$statvfs` would work as expected. + +Using an optional function import +--------------------------------- + +In order to use the above options function its presence should first be tested +for. In C code this would look something like this: + +```c +if (__wasm_is_present(wasm_fs.statvfs)) { + wasm_fs.statvfs(...) +} +``` + +At the WebAssembly level it might look like this: + +```wasm +global.get $statvfs_is_present +if i32 + call $statvfs +end +``` + +Custom section +-------------- + +A custom section is used to specify which imports are optional, and for each +optional import the name of the corresponding guard (the global import which is +used to signal its presence). For each module that contains optional imports +the module name is specified once followed by a list of its optional imports +along with their corresponding guards. + +The name of this custom section is `import.optional` and its contents are as +follows: + +| Field | Type | Description | +| ----------------| ---------------------- | -------------------------------- | +| count | `varuint32` | count of mod_optionals to follow | +| mod_optionals | `optional_import_list*`| sequence if optional_import_list | + +Each `optional_import_list` has the following content: + +| Field | Type | Description | +| --------------| ------------------- | ------------------------------------- | +| mod_name_len | `varuint32` | the length of `mod_name_data` in bytes| +| mod_name_data | `bytes` | UTF-8 encoding of the module name | +| count | `varuint32` | count of `opt_import` to follow | +| opt_import | `opt_import*` | sequence of `opt_import` | + +Each `opt_import` has the following content: + +| Field | Type | Description | +| --------------- | ---------------- | --------------------------------------- | +| name_len | `varuint32` | the length of `name_data` in bytes | +| name_data | `bytes` | UTF-8 encoding of the import name | +| guard_name_len | `varuint32` | the length of `guard_name_data` in bytes| +| guard_name_data | `bytes` | UTF-8 encoding of the import name | + +[weakrefs]: https://github.com/tc39/proposal-weakrefs +[spec]: https://github.com/WebAssembly/design/issues/1281 diff --git a/proposals/random/design/weak-imports.md b/proposals/random/design/weak-imports.md deleted file mode 100644 index 842f82bec..000000000 --- a/proposals/random/design/weak-imports.md +++ /dev/null @@ -1,106 +0,0 @@ -Weak Imports -============ - -It can be useful for WASI programs to weakly depend on certain functions in a -WASI API. For example, if a WASI API evolves to include a new function a -program might want to continue to run on older systems that don't yet support -the new function. In this case a weak import mechanism allows the program to -run on older systems and detect the presence of the function at runtime. -Another use case is an API that is not applicable on certain embedding. In this -case weak import would allow program to continue to run in such an embedding, -albeit with reduced or modified behavior. - -*Note*: The term *weak* here refers to a type of symbol reference used by a -linker and comes from the ELF specification. It is not related to the -JavaScript [weakrefs] proposal or to garbage collection. - -WebAssembly itself does not currently provide a mechanism for weak imports. -There is some discussion of adding it to the [spec][spec], and WASI would likely -use such a feature if/when it is added. In the absence of first class weak -imports this document describes the mechanism used by WASI to specify weak -imports a custom section. Currently this is only specified for function -imports. - -Declaring a weak import ------------------------ - -Weak function imports are implemented using two imports for each function. The -first being the weak function itself and the second being an i32 global which -indicates if the function is present at runtime. We call this addition import -the guard. - -For example, if a module called `wasi:fs` added a new `statvfs` function to its -interface a program could import this new function weakly in the following way: - -```wasm -(func $statvfs (import "wasi:fs" "statvfs.weak")) -(global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) -``` - -These two imports would also need to be added to the `import.weak` custom -section (See below). - -On older systems that don't support the new function, `$statvfs_is_present` -would be set to 0 and calling `$statvfs` would result in a trap. - -On systems that do support the new function, `$statvfs_is_present` is set to -1 and calling `$statvfs` would work as expected. - -Using a weak function import ----------------------------- - -In order to use the above weak function import its presence should first be -tested for. In C code this would look something like this: - -```c -if (wasm_fs.statvfs) { - wasm_fs.statvfs(...) -} -``` - -At the WebAssembly level it might look like this: - -```wasm -global.get $statvfs_is_present -if i32 - call $statvfs -end -``` - -Weak import custom section --------------------------- - -A custom section is used to specify which imports are weak, and for each weak -import the name of the corresponding guard (the global import which is used to -signal its presence). For each module that contains weak imports the -module name is specified once followed by a list of its weak import along with -their corresponding guards. - -The name of this custom section is `import.weak` and its contents are as -follows: - -| Field | Type | Description | -| ----------------| ------------------- | ------------------------------------| -| count | `varuint32` | count of mod_weak_imports to follow | -| mod_weak_imports| `weak_import_list*` | sequence if weak import lists | - -Each `weak_import_list` has the following content: - -| Field | Type | Description | -| --------------| ------------------- | ------------------------------------- | -| mod_name_len | `varuint32` | the length of `mod_name_data` in bytes| -| mod_name_data | `bytes` | UTF-8 encoding of the module name | -| count | `varuint32` | count of `weak_import` to follow | -| weak_import | `weak_import*` | sequence of `weak_import` | - -Each `weak_import` has the following content: - -| Field | Type | Description | -| --------------- | ---------------- | --------------------------------------- | -| name_len | `varuint32` | the length of `name_data` in bytes | -| name_data | `bytes` | UTF-8 encoding of the import name | -| guard_name_len | `varuint32` | the length of `guard_name_data` in bytes| -| guard_name_data | `bytes` | UTF-8 encoding of the import name | - -[weakrefs]: https://github.com/tc39/proposal-weakrefs -[spec]: https://github.com/WebAssembly/design/issues/1281 From 84a8198771e3e311fa0e452ae81a5e602bbc2fb2 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 22 Aug 2019 18:43:39 -0700 Subject: [PATCH 0081/1772] rename weak to optional --- .../filesystem/design/optional-imports.md | 108 ++++++++++++++++++ proposals/filesystem/design/weak-imports.md | 106 ----------------- 2 files changed, 108 insertions(+), 106 deletions(-) create mode 100644 proposals/filesystem/design/optional-imports.md delete mode 100644 proposals/filesystem/design/weak-imports.md diff --git a/proposals/filesystem/design/optional-imports.md b/proposals/filesystem/design/optional-imports.md new file mode 100644 index 000000000..543599a10 --- /dev/null +++ b/proposals/filesystem/design/optional-imports.md @@ -0,0 +1,108 @@ +Optional Imports +================ + +It can be useful for WASI programs to optionally depend on certain functions in a +WASI API. For example, if a WASI API evolves to include a new function a +program might want to continue to run on older systems that don't yet support +the new function. In this case a optional import mechanism allows the program +to run on older systems and detect the presence of the function at runtime. +Another use case is an API that is not applicable on certain embedding. In this +case optionals imports would allow program to continue to run in such an +embedding, albeit with reduced or modified behavior. + +*Note*: In the ELF specification this type of import is known as *weak*. +We chose *optional* because the term weak is already used other context in +WebAssembly and JavaScript, specifically in JavaScript [weakrefs] proposal where +it relates to garbage collection. + +WebAssembly itself does not currently provide a mechanism for optional imports. +There is some discussion of adding it to the [spec][spec], and WASI would likely +use such a feature if/when it is added. In the absence of first class optional +imports this document describes the mechanism used by WASI to specify optional +imports using a custom section. Currently this is only specified for function +imports. + +Declaring an optional import +---------------------------- + +Optional function imports are implemented using two imports for each function. +The first being the optional function itself and the second being an i32 global +which indicates if the function is present at runtime. We call this addition +import the guard. + +For example, if a module called `wasi:fs` added a new `statvfs` function to its +interface a program could optionally import this new function in the following +way: + +```wasm +(func $statvfs (import "wasi:fs" "statvfs.optional")) +(global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) +``` + +These two imports would also need to be added to the `import.optional` custom +section (See below). + +On older systems that don't support the new function, `$statvfs_is_present` +would be set to 0 and calling `$statvfs` would result in a trap. + +On systems that do support the new function, `$statvfs_is_present` is set to +1 and calling `$statvfs` would work as expected. + +Using an optional function import +--------------------------------- + +In order to use the above options function its presence should first be tested +for. In C code this would look something like this: + +```c +if (__wasm_is_present(wasm_fs.statvfs)) { + wasm_fs.statvfs(...) +} +``` + +At the WebAssembly level it might look like this: + +```wasm +global.get $statvfs_is_present +if i32 + call $statvfs +end +``` + +Custom section +-------------- + +A custom section is used to specify which imports are optional, and for each +optional import the name of the corresponding guard (the global import which is +used to signal its presence). For each module that contains optional imports +the module name is specified once followed by a list of its optional imports +along with their corresponding guards. + +The name of this custom section is `import.optional` and its contents are as +follows: + +| Field | Type | Description | +| ----------------| ---------------------- | -------------------------------- | +| count | `varuint32` | count of mod_optionals to follow | +| mod_optionals | `optional_import_list*`| sequence if optional_import_list | + +Each `optional_import_list` has the following content: + +| Field | Type | Description | +| --------------| ------------------- | ------------------------------------- | +| mod_name_len | `varuint32` | the length of `mod_name_data` in bytes| +| mod_name_data | `bytes` | UTF-8 encoding of the module name | +| count | `varuint32` | count of `opt_import` to follow | +| opt_import | `opt_import*` | sequence of `opt_import` | + +Each `opt_import` has the following content: + +| Field | Type | Description | +| --------------- | ---------------- | --------------------------------------- | +| name_len | `varuint32` | the length of `name_data` in bytes | +| name_data | `bytes` | UTF-8 encoding of the import name | +| guard_name_len | `varuint32` | the length of `guard_name_data` in bytes| +| guard_name_data | `bytes` | UTF-8 encoding of the import name | + +[weakrefs]: https://github.com/tc39/proposal-weakrefs +[spec]: https://github.com/WebAssembly/design/issues/1281 diff --git a/proposals/filesystem/design/weak-imports.md b/proposals/filesystem/design/weak-imports.md deleted file mode 100644 index 842f82bec..000000000 --- a/proposals/filesystem/design/weak-imports.md +++ /dev/null @@ -1,106 +0,0 @@ -Weak Imports -============ - -It can be useful for WASI programs to weakly depend on certain functions in a -WASI API. For example, if a WASI API evolves to include a new function a -program might want to continue to run on older systems that don't yet support -the new function. In this case a weak import mechanism allows the program to -run on older systems and detect the presence of the function at runtime. -Another use case is an API that is not applicable on certain embedding. In this -case weak import would allow program to continue to run in such an embedding, -albeit with reduced or modified behavior. - -*Note*: The term *weak* here refers to a type of symbol reference used by a -linker and comes from the ELF specification. It is not related to the -JavaScript [weakrefs] proposal or to garbage collection. - -WebAssembly itself does not currently provide a mechanism for weak imports. -There is some discussion of adding it to the [spec][spec], and WASI would likely -use such a feature if/when it is added. In the absence of first class weak -imports this document describes the mechanism used by WASI to specify weak -imports a custom section. Currently this is only specified for function -imports. - -Declaring a weak import ------------------------ - -Weak function imports are implemented using two imports for each function. The -first being the weak function itself and the second being an i32 global which -indicates if the function is present at runtime. We call this addition import -the guard. - -For example, if a module called `wasi:fs` added a new `statvfs` function to its -interface a program could import this new function weakly in the following way: - -```wasm -(func $statvfs (import "wasi:fs" "statvfs.weak")) -(global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) -``` - -These two imports would also need to be added to the `import.weak` custom -section (See below). - -On older systems that don't support the new function, `$statvfs_is_present` -would be set to 0 and calling `$statvfs` would result in a trap. - -On systems that do support the new function, `$statvfs_is_present` is set to -1 and calling `$statvfs` would work as expected. - -Using a weak function import ----------------------------- - -In order to use the above weak function import its presence should first be -tested for. In C code this would look something like this: - -```c -if (wasm_fs.statvfs) { - wasm_fs.statvfs(...) -} -``` - -At the WebAssembly level it might look like this: - -```wasm -global.get $statvfs_is_present -if i32 - call $statvfs -end -``` - -Weak import custom section --------------------------- - -A custom section is used to specify which imports are weak, and for each weak -import the name of the corresponding guard (the global import which is used to -signal its presence). For each module that contains weak imports the -module name is specified once followed by a list of its weak import along with -their corresponding guards. - -The name of this custom section is `import.weak` and its contents are as -follows: - -| Field | Type | Description | -| ----------------| ------------------- | ------------------------------------| -| count | `varuint32` | count of mod_weak_imports to follow | -| mod_weak_imports| `weak_import_list*` | sequence if weak import lists | - -Each `weak_import_list` has the following content: - -| Field | Type | Description | -| --------------| ------------------- | ------------------------------------- | -| mod_name_len | `varuint32` | the length of `mod_name_data` in bytes| -| mod_name_data | `bytes` | UTF-8 encoding of the module name | -| count | `varuint32` | count of `weak_import` to follow | -| weak_import | `weak_import*` | sequence of `weak_import` | - -Each `weak_import` has the following content: - -| Field | Type | Description | -| --------------- | ---------------- | --------------------------------------- | -| name_len | `varuint32` | the length of `name_data` in bytes | -| name_data | `bytes` | UTF-8 encoding of the import name | -| guard_name_len | `varuint32` | the length of `guard_name_data` in bytes| -| guard_name_data | `bytes` | UTF-8 encoding of the import name | - -[weakrefs]: https://github.com/tc39/proposal-weakrefs -[spec]: https://github.com/WebAssembly/design/issues/1281 From 0edf2b1dd163d23dee8591373dad8fdc90b58754 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 12 Sep 2019 06:58:03 -0700 Subject: [PATCH 0082/1772] Add an agenda for 09-12. Note that the time of this meeting is back at 16:00-17:00 UTC. --- proposals/clocks/meetings/2019/WASI-09-12.md | 39 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 40 insertions(+) create mode 100644 proposals/clocks/meetings/2019/WASI-09-12.md diff --git a/proposals/clocks/meetings/2019/WASI-09-12.md b/proposals/clocks/meetings/2019/WASI-09-12.md new file mode 100644 index 000000000..edcf5f95d --- /dev/null +++ b/proposals/clocks/meetings/2019/WASI-09-12.md @@ -0,0 +1,39 @@ +![WASI logo](/WASI.png) + +## Agenda for the September 12 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: September 12, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. `witx` API description files: + - https://github.com/WebAssembly/WASI/pull/74 + 1. Phased API development proposal + - https://github.com/WebAssembly/WASI/pull/88 + +1. Closure + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 50ce6eeb3..4b0b34506 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -15,3 +15,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI July 18th video call](2019/WASI-07-18.md) * [WASI August 15th video call](2019/WASI-08-15.md) * [WASI August 30th video call](2019/WASI-08-30.md) + * [WASI September 12th video call](2019/WASI-09-12.md) From c1c32164d74c6aceb407b0ec85f44c716322ff68 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 12 Sep 2019 06:58:03 -0700 Subject: [PATCH 0083/1772] Add an agenda for 09-12. Note that the time of this meeting is back at 16:00-17:00 UTC. --- proposals/random/meetings/2019/WASI-09-12.md | 39 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 40 insertions(+) create mode 100644 proposals/random/meetings/2019/WASI-09-12.md diff --git a/proposals/random/meetings/2019/WASI-09-12.md b/proposals/random/meetings/2019/WASI-09-12.md new file mode 100644 index 000000000..edcf5f95d --- /dev/null +++ b/proposals/random/meetings/2019/WASI-09-12.md @@ -0,0 +1,39 @@ +![WASI logo](/WASI.png) + +## Agenda for the September 12 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: September 12, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. `witx` API description files: + - https://github.com/WebAssembly/WASI/pull/74 + 1. Phased API development proposal + - https://github.com/WebAssembly/WASI/pull/88 + +1. Closure + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 50ce6eeb3..4b0b34506 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -15,3 +15,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI July 18th video call](2019/WASI-07-18.md) * [WASI August 15th video call](2019/WASI-08-15.md) * [WASI August 30th video call](2019/WASI-08-30.md) + * [WASI September 12th video call](2019/WASI-09-12.md) From 658ce2a94d1b11fc874774aa28c293d106daddda Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 12 Sep 2019 06:58:03 -0700 Subject: [PATCH 0084/1772] Add an agenda for 09-12. Note that the time of this meeting is back at 16:00-17:00 UTC. --- .../filesystem/meetings/2019/WASI-09-12.md | 39 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 40 insertions(+) create mode 100644 proposals/filesystem/meetings/2019/WASI-09-12.md diff --git a/proposals/filesystem/meetings/2019/WASI-09-12.md b/proposals/filesystem/meetings/2019/WASI-09-12.md new file mode 100644 index 000000000..edcf5f95d --- /dev/null +++ b/proposals/filesystem/meetings/2019/WASI-09-12.md @@ -0,0 +1,39 @@ +![WASI logo](/WASI.png) + +## Agenda for the September 12 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: September 12, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. `witx` API description files: + - https://github.com/WebAssembly/WASI/pull/74 + 1. Phased API development proposal + - https://github.com/WebAssembly/WASI/pull/88 + +1. Closure + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 50ce6eeb3..4b0b34506 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -15,3 +15,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI July 18th video call](2019/WASI-07-18.md) * [WASI August 15th video call](2019/WASI-08-15.md) * [WASI August 30th video call](2019/WASI-08-30.md) + * [WASI September 12th video call](2019/WASI-09-12.md) From c6a6f44f8bf4ccd13f4e03f83da5577c3e409fb6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 14 Aug 2019 22:42:24 -0700 Subject: [PATCH 0085/1772] A wasi_unstable description based on module types. This sketches out a description of the current wasi_unstable API, using a syntax which anticipates the "module types" syntax [recently proposed to the CG](https://github.com/WebAssembly/meetings/blob/master/2019/CG-08-06.md#discuss-new-proposal-that-introduces-types-for-modules-and-instances-and-text-format-thereof-as-initially-discussed-in-design1289), though it does use a few extensions which can be easily lowered, and which mostly anticipate the [Interface Types](https://github.com/WebAssembly/webidl-bindings/issues/47#issuecomment-519717553) proposal. This is derived from [the WatIDL proposal](https://github.com/WebAssembly/WASI/pull/64), though it differs in a few ways: - It doesn't yet do anything special for capabilities, for now. File descriptors are just integers, for now. But the idea is that we could add OCAP concepts later. - It uses a new `(flags ...)` construct in place of structs of Bool fields, to describe flags values. This allows us to explicitly declare the underlying wasm type for flags values. - Types used by the API are declared outside of the moduletype, because we're using wat syntax as much as possible, and there, `(type ...)` inside a module declares an entry in the type section, which isn't what's intended here. The extensions to module types are: - It uses `string`, `array`, and `{s,u}{8,16,32,64}` types, which are expected to be provided in some form by the Interface Types proposal. For now though, they can all be lowered in straightforward ways, by assuming that `string` is always just UTF-8. - It adds `typename` declarations, which can name any wasm type, and of the extra types mentioned in the previous item, or `struct`, `enum`, or `flags`. - It declares functions with multiple return values, which for now will need to be lowered to output (pointer) parameters. --- .../design/wasi_unstable/wasi_unstable.wati | 1206 +++++++++++++++++ 1 file changed, 1206 insertions(+) create mode 100644 proposals/clocks/design/wasi_unstable/wasi_unstable.wati diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati new file mode 100644 index 000000000..1dd067917 --- /dev/null +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati @@ -0,0 +1,1206 @@ +;; The wasi_unstable module type. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). + +(typename $size_t u32) +(typename $string_array (array string)) + +;; Non-negative file size or length of a region within a file. +(typename $filesize_t u64) + +;; Timestamp in nanoseconds. +(typename $timestamp_t u64) + +;; Identifiers for clocks. +(typename $clockid_t + (enum u32 + ;; The store-wide monotonic clock, which is defined as a clock measuring + ;; real time, whose value cannot be adjusted and which cannot have negative + ;; clock jumps. The epoch of this clock is undefined. The absolute time + ;; value of this clock therefore has no meaning. + $CLOCK_MONOTONIC + ;; The CPU-time clock associated with the current process. + $CLOCK_PROCESS_CPUTIME_ID + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME + ;; The CPU-time clock associated with the current thread. + $CLOCK_THREAD_CPUTIME_ID + ) +) + +;; Error codes returned by functions. +;; Not all of these error codes are returned by the functions provided by this +;; API; some are used in higher-level library layers, and others are provided +;; merely for alignment with POSIX. +(typename $errno_t + (enum u16 + ;; No error occurred. System call completed successfully. + $ESUCCESS + ;; Argument list too long. + $E2BIG + ;; Permission denied. + $EACCES + ;; Address in use. + $EADDRINUSE + ;; Address not available. + $EADDRNOTAVAIL + ;; Address family not supported. + $EAFNOSUPPORT + ;; Resource unavailable, or operation would block. + $EAGAIN + ;; Connection already in progress. + $EALREADY + ;; Bad file descriptor. + $EBADF + ;; Bad message. + $EBADMSG + ;; Device or resource busy. + $EBUSY + ;; Operation canceled. + $ECANCELED + ;; No child processes. + $ECHILD + ;; Connection aborted. + $ECONNABORTED + ;; Connection refused. + $ECONNREFUSED + ;; Connection reset. + $ECONNRESET + ;; Resource deadlock would occur. + $EDEADLK + ;; Destination address required. + $EDESTADDRREQ + ;; Mathematics argument out of domain of function. + $EDOM + ;; Reserved. + $EDQUOT + ;; File exists. + $EEXIST + ;; Bad address. + $EFAULT + ;; File too large. + $EFBIG + ;; Host is unreachable. + $EHOSTUNREACH + ;; Identifier removed. + $EIDRM + ;; Illegal byte sequence. + $EILSEQ + ;; Operation in progress. + $EINPROGRESS + ;; Interrupted function. + $EINTR + ;; Invalid argument. + $EINVAL + ;; I/O error. + $EIO + ;; Socket is connected. + $EISCONN + ;; Is a directory. + $EISDIR + ;; Too many levels of symbolic links. + $ELOOP + ;; File descriptor value too large. + $EMFILE + ;; Too many links. + $EMLINK + ;; Message too large. + $EMSGSIZE + ;; Reserved. + $EMULTIHOP + ;; Filename too long. + $ENAMETOOLONG + ;; Network is down. + $ENETDOWN + ;; Connection aborted by network. + $ENETRESET + ;; Network unreachable. + $ENETUNREACH + ;; Too many files open in system. + $ENFILE + ;; No buffer space available. + $ENOBUFS + ;; No such device. + $ENODEV + ;; No such file or directory. + $ENOENT + ;; Executable file format error. + $ENOEXEC + ;; No locks available. + $ENOLCK + ;; Reserved. + $ENOLINK + ;; Not enough space. + $ENOMEM + ;; No message of the desired type. + $ENOMSG + ;; Protocol not available. + $ENOPROTOOPT + ;; No space left on device. + $ENOSPC + ;; Function not supported. + $ENOSYS + ;; The socket is not connected. + $ENOTCONN + ;; Not a directory or a symbolic link to a directory. + $ENOTDIR + ;; Directory not empty. + $ENOTEMPTY + ;; State not recoverable. + $ENOTRECOVERABLE + ;; Not a socket. + $ENOTSOCK + ;; Not supported, or operation not supported on socket. + $ENOTSUP + ;; Inappropriate I/O control operation. + $ENOTTY + ;; No such device or address. + $ENXIO + ;; Value too large to be stored in data type. + $EOVERFLOW + ;; Previous owner died. + $EOWNERDEAD + ;; Operation not permitted. + $EPERM + ;; Broken pipe. + $EPIPE + ;; Protocol error. + $EPROTO + ;; Protocol not supported. + $EPROTONOSUPPORT + ;; Protocol wrong type for socket. + $EPROTOTYPE + ;; Result too large. + $ERANGE + ;; Read-only file system. + $EROFS + ;; Invalid seek. + $ESPIPE + ;; No such process. + $ESRCH + ;; Reserved. + $ESTALE + ;; Connection timed out. + $ETIMEDOUT + ;; Text file busy. + $ETXTBSY + ;; Cross-device link. + $EXDEV + ;; Extension: Capabilities insufficient. + $ENOTCAPABLE + ) +) + +;; File descriptor rights, determining which actions may be performed. +(typename $rights_t + (flags u64 + ;; The right to invoke __wasi_fd_datasync(). + ;; + ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke + ;` __wasi_path_open() with __WASI_FDFLAG_DSYNC. + (flag $RIGHT_FD_DATASYNC) + ;; The right to invoke __wasi_fd_read() and __wasi_sock_recv(). + ;; + ;; If __WASI_RIGHT_FD_SEEK is set, includes the right to invoke + ;; __wasi_fd_pread(). + (flag $RIGHT_FD_READ) + ;; The right to invoke __wasi_fd_seek(). This flag implies __WASI_RIGHT_FD_TELL. + (flag $RIGHT_FD_SEEK) + ;; The right to invoke __wasi_fd_fdstat_set_flags(). + (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + ;; The right to invoke __wasi_fd_sync(). + ;; + ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke + ;; __wasi_path_open() with __WASI_FDFLAG_RSYNC and __WASI_FDFLAG_DSYNC. + (flag $RIGHT_FD_SYNC) + ;; The right to invoke __wasi_fd_seek() in such a way that the file offset + ;; remains unaltered (i.e., __WASI_WHENCE_CUR with offset zero), or to + ;; invoke __wasi_fd_tell(). + (flag $RIGHT_FD_TELL) + ;; The right to invoke __wasi_fd_write() and __wasi_sock_send(). + ;; If __WASI_RIGHT_FD_SEEK is set, includes the right to invoke __wasi_fd_pwrite(). + (flag $RIGHT_FD_WRITE) + ;; The right to invoke __wasi_fd_advise(). + (flag $RIGHT_FD_ADVISE) + ;; The right to invoke __wasi_fd_allocate(). + (flag $RIGHT_FD_ALLOCATE) + ;; The right to invoke __wasi_path_create_directory(). + (flag $RIGHT_PATH_CREATE_DIRECTORY) + ;; If __WASI_RIGHT_PATH_OPEN is set, the right to invoke __wasi_path_open() with __WASI_O_CREAT. + (flag $RIGHT_PATH_CREATE_FILE) + ;; The right to invoke __wasi_path_link() with the file descriptor as the source directory. + (flag $RIGHT_PATH_LINK_SOURCE) + ;; The right to invoke __wasi_path_link() with the file descriptor as the target directory. + (flag $RIGHT_PATH_LINK_TARGET) + ;; The right to invoke __wasi_path_open(). + (flag $RIGHT_PATH_OPEN) + ;; The right to invoke __wasi_fd_readdir(). + (flag $RIGHT_FD_READDIR) + ;; The right to invoke __wasi_path_readlink(). + (flag $RIGHT_PATH_READLINK) + ;; The right to invoke __wasi_path_rename() with the file descriptor as the source directory. + (flag $RIGHT_PATH_RENAME_SOURCE) + ;; The right to invoke __wasi_path_rename() with the file descriptor as the target directory. + (flag $RIGHT_PATH_RENAME_TARGET) + ;; The right to invoke __wasi_path_filestat_get(). + (flag $RIGHT_PATH_FILESTAT_GET) + ;; The right to change a file's size (there is no __wasi_path_filestat_set_size()). + ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke __wasi_path_open() with __WASI_O_TRUNC. + (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + ;; The right to invoke __wasi_path_filestat_set_times(). + (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + ;; The right to invoke __wasi_fd_filestat_get(). + (flag $RIGHT_FD_FILESTAT_GET) + ;; The right to invoke __wasi_fd_filestat_set_size(). + (flag $RIGHT_FD_FILESTAT_SET_SIZE) + ;; The right to invoke __wasi_fd_filestat_set_times(). + (flag $RIGHT_FD_FILESTAT_SET_TIMES) + ;; The right to invoke __wasi_path_symlink(). + (flag $RIGHT_PATH_SYMLINK) + ;; The right to invoke __wasi_path_unlink_file(). + (flag $RIGHT_PATH_UNLINK_FILE) + ;; The right to invoke __wasi_path_remove_directory(). + (flag $RIGHT_PATH_REMOVE_DIRECTORY) + ;; If __WASI_RIGHT_FD_READ is set, includes the right to invoke __wasi_poll_oneoff() to subscribe to __WASI_EVENTTYPE_FD_READ. + ;; If __WASI_RIGHT_FD_WRITE is set, includes the right to invoke __wasi_poll_oneoff() to subscribe to __WASI_EVENTTYPE_FD_WRITE. + (flag $RIGHT_POLL_FD_READWRITE) + ;; The right to invoke __wasi_sock_shutdown(). + (flag $RIGHT_SOCK_SHUTDOWN) + ) +) + +;; a file descriptor index +(typename $fd_t u32) + +(typename $iovec_t_array (array $iovec_t)) +(typename $ciovec_t_array (array $ciovec_t)) + +;; A region of memory for scatter/gather reads. +(typename $iovec_t + (struct + ;; The address and length of the buffer to be filled. + (field $buf data) + (field $buf_len data) + ) +) + +;; A region of memory for scatter/gather writes. +(typename $ciovec_t + (struct + ;; The address and length of the buffer to be written. + (field $buf data) + (field $buf_len data) + ) +) + +;; Relative offset within a file. +(typename $filedelta_t s64) + +;; The position relative to which to set the offset of the file descriptor. +(typename $whence_t + (enum u8 + ;; Seek relative to current position. + $WHENCE_CUR + ;; Seek relative to end-of-file. + $WHENCE_END + ;; Seek relative to start-of-file. + $WHENCE_SET + ) +) + +;; A reference to the offset of a directory entry. +(typename $dircookie_t u64) + +;; The type for the $d_namelen field of $dirent_t. +(typename $dirnamlen_t u32) + +;; A directory entry. +(typename $dirent_t + (struct + ;; The offset of the next directory entry stored in this directory. + (field $d_next $dircookie_t) + ;; The serial number of the file referred to by this directory entry. + (field $d_ino $inode_t) + ;; The length of the name of the directory entry. + (field $d_namlen $dirnamelen_t) + ;; The type of the file referred to by this directory entry. + (field $d_type $filetype_t) + ) +) + +;; File or memory access pattern advisory information. +(typename $advice_t + (enum u8 + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE + ;; The application has no advice to give on its behavior with respect to the specified data. + $ADVICE_NORMAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM + ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in the near future. + $ADVICE_WILLNEED + ) +) + +;; File descriptor flags. +(typename $fdflags_t + (flags u16 + ;; Append mode: Data written to the file is always appended to the file's end. + (flag $FDFLAG_APPEND) + ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + (flag $FDFLAG_DSYNC) + ;; Non-blocking mode. + (flag $FDFLAG_NONBLOCK) + ;; Synchronized read I/O operations. + (flag $FDFLAG_RSYNC) + ;; Write according to synchronized I/O file integrity completion. In + ;; addition to synchronizing the data stored in the file, the implementation + ;; may also synchronously update the file's metadata. + (flag $FDFLAG_SYNC) + ) +) + +;; File descriptor attributes. +(typename $fdstat_t + (struct + ;; File type. + (field $fs_filetype $filetype_t) + ;; File descriptor flags. + (field $fs_flags $fdflags_t) + ;; Rights that apply to this file descriptor. + (field $fs_rights_base $rights_t) + ;; Maximum set of rights that may be installed on new file descriptors that + ;; are created through this file descriptor, e.g., through + ;; __wasi_path_open(). + (field $fs_rights_inheriting $rights_t) + ) +) + +;; Identifier for a device containing a file system. Can be used in combination +;; with __wasi_inode_t to uniquely identify a file or directory in the +;; filesystem. +(typename $device_t u64) + +;; The type of a file descriptor or file. +(typename $filetype_t + (enum u8 + ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $FILETYPE_UNKNOWN + ;; The file descriptor or file refers to a block device inode. + $FILETYPE_BLOCK_DEVICE + ;; The file descriptor or file refers to a character device inode. + $FILETYPE_CHARACTER_DEVICE + ;; The file descriptor or file refers to a directory inode. + $FILETYPE_DIRECTORY + ;; The file descriptor or file refers to a regular file inode. + $FILETYPE_REGULAR_FILE + ;; The file descriptor or file refers to a datagram socket. + $FILETYPE_SOCKET_DGRAM + ;; The file descriptor or file refers to a byte-stream socket. + $FILETYPE_SOCKET_STREAM + ;; The file refers to a symbolic link inode. + $FILETYPE_SYMBOLIC_LINK + ) +) + +;; Which file time attributes to adjust. +(typename $fstflags_t + (flags u16 + ;; Adjust the last data access timestamp to the value stored in __wasi_filestat_t::st_atim. + (flag $FILESTAT_SET_ATIM) + ;; Adjust the last data access timestamp to the time of clock __WASI_CLOCK_REALTIME. + (flag $FILESTAT_SET_ATIM_NOW) + ;; Adjust the last data modification timestamp to the value stored in __wasi_filestat_t::st_mtim. + (flag $FILESTAT_SET_MTIM) + ;; Adjust the last data modification timestamp to the time of clock __WASI_CLOCK_REALTIME. + (flag $FILESTAT_SET_MTIM_NOW) + ) +) + +;; File serial number that is unique within its file system. +(typename $inode_t u64) + +;; Flags determining the method of how paths are resolved. +(typename $lookupflags_t + (flags u32 + ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + (flag $LOOKUP_SYMLINK_FOLLOW) + ) +) + +;; Open flags used by __wasi_path_open(). +(typename $oflags_t + (flags u16 + ;; Create file if it does not exist. + (flag $O_CREAT) + ;; Fail if not a directory. + (flag $O_DIRECTORY) + ;; Fail if file already exists. + (flag $O_EXCL) + ;; Truncate file to size 0. + (flag $O_TRUNC) + ) +) + +;; Number of hard links to an inode. +(typename $linkcount_t u32) + +;; File attributes. +(typename $filestat_t + (struct + ;; Device ID of device containing the file. + (field $st_dev $device_t) + ;; File serial number. + (field $st_ino $inode_t) + ;; File type. + (field $st_filetype $filetype_t) + ;; Number of hard links to the file. + (field $st_nlink $linkcount_t) + ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + (field $st_size $filesize_t) + ;; Last data access timestamp. + (field $st_atim $timestamp_t) + ;; Last data modification timestamp. + (field $st_mtim $timestamp_t) + ;; Last file status change timestamp. + (field $st_ctim $timestamp_t) + ) +) + +;; User-provided value that may be attached to objects that is retained when extracted from the implementation. +(typename $userdata_t u64) + +;; An event that occurred. +(typename $event_t + (struct + ;; User-provided value that got attached to __wasi_subscription_t::userdata. + (field $userdata $userdata_t) + ;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno_t) + ;; The type of the event that occurred. + (field $type $eventtype_t) + (field $u + (typename union + ;; When type is __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE: + (field $fd_readwrite + (typename stuct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) + ) + ) + (field $else Null) + ) + ) + ) +) + +;; The state of the file descriptor subscribed to with __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE. +(typename $eventrwflags_t + (flags u16 + ;; The peer of this socket has closed or disconnected. + (flag $EVENT_FD_READWRITE_HANGUP) + ) +) + +;; Type of a subscription to an event or its occurrence. +(typename $eventtype_t + (flags u8 + ;; The time value of clock __wasi_subscription_t::u.clock.clock_id has reached timestamp __wasi_subscription_t::u.clock.timeout. + (flag $EVENTTYPE_CLOCK) + ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has data available for reading. This event always triggers for regular files. + (flag $EVENTTYPE_FD_READ) + ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has capacity available for writing. This event always triggers for regular files. + (flag $EVENTTYPE_FD_WRITE) + ) +) + +;; Flags determining how to interpret the timestamp provided in __wasi_subscription_t::u.clock.timeout. +(typename $subclockflags_t + (flags u16 + ;; If set, treat the timestamp provided in + ;; __wasi_subscription_t::u.clock.timeout as an absolute timestamp of clock + ;; __wasi_subscription_t::u.clock.clock_id. If clear, treat the timestamp + ;; provided in __wasi_subscription_t::u.clock.timeout relative to the + ;; current time value of clock __wasi_subscription_t::u.clock.clock_id. + (flag $SUBSCRIPTION_CLOCK_ABSTIME) + ) +) + +;; Subscription to an event. +(typename $subscription_t + (struct + ;; User-provided value that is attached to the subscription in the implementation and returned through __wasi_event_t::userdata. + (field $userdata $userdata_t) + ;; The type of the event to which to subscribe. + (field $type $eventtype_t) + (field + (type + (union + ;; When type is __WASI_EVENTTYPE_CLOCK + (field $clock + (typename + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally to coalesce with other events. + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) + ) + ) + ;; When type is __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE: + (field $fd_readwrite + (type + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) + ) + ) + ) + ) + ) + ) + ) +) + +;; Exit code generated by a process when exiting. +(typename $exitcode_t u32) + +;; Signal condition. +(typename $signal_t + (enum u8 + ;; Process abort signal. + ;; Action: Terminates the process. + $SIGABRT + ;; Alarm clock. + ;; Action: Terminates the process. + $SIGALRM + ;; Access to an undefined portion of a memory object. + ;; Action: Terminates the process. + $SIGBUS + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT + ;; Erroneous arithmetic operation. + ;; Action: Terminates the process. + $SIGFPE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Kill. + ;; Action: Terminates the process. + $SIGKILL + ;; Write on a pipe with no one to read it. + ;; Action: Ignored. + $SIGPIPE + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Invalid memory reference. + ;; Action: Terminates the process. + $SIGSEGV + ;; Stop executing. + ;; Action: Stops executing. + $SIGSTOP + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS + ;; Termination signal. + ;; Action: Terminates the process. + $SIGTERM + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP + ;; Terminal stop signal. + ;; Action: Stops executing. + $SIGTSTP + ;; Background process attempting read. + ;; Action: Stops executing. + $SIGTTIN + ;; Background process attempting write. + ;; Action: Stops executing. + $SIGTTOU + ;; High bandwidth data is available at a socket. + ;; Action: Ignored. + $SIGURG + ;; User-defined signal 1. + ;; Action: Terminates the process. + $SIGUSR1 + ;; User-defined signal 2. + ;; Action: Terminates the process. + $SIGUSR2 + ;; Virtual timer expired. + ;; Action: Terminates the process. + $SIGVTALRM + ;; CPU time limit exceeded. + ;; Action: Terminates the process. + $SIGXCPU + ;; File size limit exceeded. + ;; Action: Terminates the process. + $SIGXFSZ + ) +) + +;; Flags provided to __wasi_sock_recv(). +(typename $riflags_t + (flags u16 + ;; Returns the message without removing it from the socket's receive queue. + (flag $SOCK_RECV_PEEK) + ;; On byte-stream sockets, block until the full amount of data can be returned. + (flag $SOCK_RECV_WAITALL) + ) +) + +;; Flags returned by __wasi_sock_recv(). +(typename $roflags_t + (flags u16 + ;; Returned by __wasi_sock_recv(): Message data has been truncated. + (flag $SOCK_RECV_DATA_TRUNCATED) + ) +) + +;; Flags provided to __wasi_sock_send(). As there are currently no flags defined, it must be set to zero. +(typename $siflags_t u16) + +;; Which channels on a socket to shut down. +(typename $sdflags_t + (flags u8 + ;; Disables further receive operations. + (flag $SHUT_RD) + ;; Disables further send operations. + (flag $SHUT_WR) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; The wasi_unstable moduletype. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(moduletype $wasi_unstable + ;; Linear memory used by the program. + (import "memory" (memory)) + + ;; The program entry point. + (import "_start" (func)) + + ;; Read command-line argument data. + ;; The size of the array should match that returned by `wasi_args_sizes_get()` + (func (export "args_get") + (result $error $errno_t) + (result $argv $string_array) + ) + ;; Return command-line argument data sizes. + (func (export "args_sizes_get") + (result $error $errno_t) + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Read environment variable data. + ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + (func (export "environ_get") + (result $error $errno_t) + (result $argv $string_array) + ) + ;; Return command-line argument data sizes. + (func (export "environ_sizes_get") + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Return the resolution of a clock. + ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;; Note: This is similar to `clock_getres` in POSIX. + (func (export "clock_res_get") + (result $error $errno_t) + ;; The clock for which to return the resolution. + (param $clock_id $clockid_t) + ;; The resolution of the clock. + (result $resolution $timestamp_t) + ) + ;; Return the time value of a clock. + ;; Note: This is similar to `clock_gettime` in POSIX. + (func (export "clock_time_get") + ;; The clock for which to return the time. + (param $clock_id $clockid_t) + ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp_t) + (result $error $errno_t) + ;; The time value of the clock. + (result $time $timestamp_t) + ) + + ;; Provide file advisory information on a file descriptor. + ;; Note: This is similar to `posix_fadvise` in POSIX. + (func (export "fd_advise") + (param $self $fd_t) + (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. + (param $len $filesize_t) ;; The length of the region to which the advisory applies. + (param $advice $advice_t) ;; The advice. + (result $error $errno_t) + ) + + ;; Force the allocation of space in a file. + ;; Note: This is similar to `posix_fallocate` in POSIX. + (func (export "fd_allocate") + (param $self $fd_t) + ;; The offset at which to start the allocation. + (param $offset $filesize_t) + ;; The length of the area that is allocated. + (param $len $filesize_t) + (result $error $errno_t) + ) + + ;; Close a file descriptor. + ;; Note: This is similar to `close` in POSIX. + (func (export "fd_close") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Synchronize the data of a file to disk. + ;; Note: This is similar to `fdatasync` in POSIX. + (func (export "fd_datasync") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Get the attributes of a file descriptor. + ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (func (export "fd_fdstat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the file descriptor's attributes are stored. + (result $fdstat_t) + ) + + ;; Adjust the flags associated with a file descriptor. + ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (func (export "fd_fdstat_set_flags") + (param $self $fd_t) + ;; The desired values of the file descriptor flags. + (param $flags $fdflags) + (result $error $errno_t) + ) + + ;; Adjust the rights associated with a file descriptor. + ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (func (export "fd_fdstat_set_rights") + (param $self $fd_t) + ;; The desired rights of the file descriptor. + (param $fs_rights_base $rights_t) + (param $fs_rights_inheriting $rights_t) + (result $error $errno_t) + ) + + ;; Return the attributes of an open file. + (func (export "fd_filestat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $fs_rights_base $rights_t) + ) + + ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;; Note: This is similar to `ftruncate` in POSIX. + (func (export "fd_filestat_set_size") + (param $self $fd_t) + ;; The desired file size. + (param $st_size $filesize_t) + (result $error $errno_t) + ) + + ;; Adjust the timestamps of an open file or directory. + ;; Note: This is similar to `futimens` in POSIX. + (func (export "fd_filestat_set_times") + (param $self $fd_t) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `preadv` in POSIX. + (func (export "fd_pread") + (param $self $fd_t) + ;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to read. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Return a description of the given preopened file descriptor. + (func (export "fd_prestat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the description is stored. + (result $buf $prestat_t) + ) + + ;; Return a description of the given preopened file descriptor. + (func (export "fd_prestat_dir_name") + (param $self $fd_t) + ;; A buffer into which to write the preopened directory name. + (param $path string) + (result $error $errno_t) + ) + + ;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `pwritev` in POSIX. + (func (export "fd_pwrite") + (param $self $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to write. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Read from a file descriptor. + ;; Note: This is similar to `readv` in POSIX. + (func (export "fd_read") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Read directory entries from a directory. + ;; When successful, the contents of the output buffer consist of a sequence of + ;; directory entries. Each directory entry consists of a dirent_t object, + ;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;; entry. + ;; + ;; This function fills the output buffer as much as possible, potentially + ;; truncating the last directory entry. This allows the caller to grow its + ;; read buffer size in case it's too small to fit a single large directory + ;; entry, or skip the oversized directory entry. + (func (export "fd_readdir") + (param $self $fd_t) + ;; The buffer where directory entries are stored + (param $buf data) + ;; The location within the directory to start reading + (param $cookie $dircookie_t) + (result $error $errno_t) + ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size_t) + ) + + ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary number, like dup2(). This would be prone to race conditions, as an actual file descriptor with the same number could be allocated by a different thread at the same time. + ;; This function provides a way to atomically renumber file descriptors, which would disappear if dup2() were to be removed entirely. + (func (export "fd_renumber") + (param $self $fd_t) + ;; The file descriptor to overwrite. + (param $to $fd_t) + (result $error $errno_t) + ) + + ;; Move the offset of a file descriptor. + ;; Note: This is similar to `lseek` in POSIX. + (func (export "fd_seek") + (param $self $fd_t) + ;; The number of bytes to move. + (param $offset $filedelta_t) + ;; The base from which the offset is relative. + (param $whence $whence_t) + (result $error $errno_t) + ;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize_t) + ) + + ;; Synchronize the data and metadata of a file to disk. + ;; Note: This is similar to `fsync` in POSIX. + (func (export "fd_sync") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Return the current offset of a file descriptor. + ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (func (export "fd_tell") + (param $self $fd_t) + (result $error $errno_t) + ;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize_t) + ) + + ;; Write to a file descriptor. + ;; Note: This is similar to `writev` in POSIX. + (func (export "fd_write") + (param $self $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Create a directory. + ;; Note: This is similar to `mkdirat` in POSIX. + (func (export "path_create_directory") + (param $self $fd_t) + ;; The path at which to create the directory. + (param $path string) + (result $error $errno_t) + ) + + ;; Return the attributes of a file or directory. + ;; Note: This is similar to `stat` in POSIX. + (func (export "path_filestat_get") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $buf $filestat_t) + ) + + ;; Adjust the timestamps of a file or directory. + ;; Note: This is similar to `utimensat` in POSIX. + (func (export "path_filestat_set_times") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to operate on. + (param $path string) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Create a hard link. + ;; Note: This is similar to `linkat` in POSIX. + (func (export "path_link") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags_t) + ;; The source path from which to link. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $path) + ;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Open a file or directory. + ;; + ;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;; file descriptor not currently open; it is randomized to prevent + ;; applications from depending on making assumptions about indexes, since this + ;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;; guaranteed to be less than 231. + ;; + ;; Note: This is similar to `openat` in POSIX. + (func (export "path_open") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags_t) + ;; The relative path of the file or directory to open, relative to the + ;; `dirfd` directory. + (param $path string) + ;; The method by which to open the file. + (param $o_flags $oflags_t) + ;; The initial rights of the newly created file descriptor. The + ;; implementation is allowed to return a file descriptor with fewer rights + ;; than specified, if and only if those rights do not apply to the type of + ;; file being opened. + ;; + ;; The base rights are rights that will apply to operations using the file + ;; descriptor itself, while the inheriting rights are rights that apply to + ;; file descriptors derived from it. + (param $fs_rights_base $rights_t) + (param $fs_rights_inherting $rights_t) + (result $error $errno_t) + ;; The file descriptor of the file that has been opened. + (result $opened_fd $fd_t) + ) + + ;; Read the contents of a symbolic link. + ;; Note: This is similar to `readlinkat` in POSIX. + (func (export "path_readlink") + (param $self $fd_t) + ;; The path of the symbolic link from which to read. + (param $path) + ;; The buffer to which to write the contents of the symbolic link. + (param $buf string) + (result $error $errno_t) + ;; The number of bytes placed in the buffer. + (result $bufused $size_t) + ) + + ;; Remove a directory. + ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. + ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (func (export "path_remove_directory") + (param $self $fd_t) + ;; The path to a directory to remove. + (param $path string) + (result $error $errno_t) + ) + + ;; Rename a file or directory. + ;; Note: This is similar to `renameat` in POSIX. + (func (export "path_rename") + (param $self $fd_t) + ;; The source path of the file or directory to rename. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd) + ;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Create a symbolic link. + ;; Note: This is similar to `symlinkat` in POSIX. + (func (export "path_symlink") + (param $self $fd_t) + ;; The contents of the symbolic link. + (param $old_path string) + ;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno_t) + ) + + + ;; Unlink a file. + ;; Return __WASI_EISDIR if the path refers to a directory. + ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (func (export "path_unlink_file") + (param $self $fd_t) + ;; The path to a file to unlink. + (param $path string) + (result $error $errno_t) + ) + + ;; Concurrently poll for the occurrence of a set of events. + (func (export "poll_oneoff") + ;; The events to which to subscribe. + (param $in $subscription_t) + ;; The events that have occurred. + (param $out $event_t) + ;; Both the number of subscriptions and events. + (param $nsubscriptions $size_t) + (result $error $errno_t) + ;; The number of events stored. + (result $nevents $size_t) + ) + + ;; Terminate the process normally. An exit code of 0 indicates successful + ;; termination of the program. The meanings of other values is dependent on + ;; the environment. + (func (export "proc_exit") + ;; The exit code returned by the process. + (param $rval $exitcode_t) + ) + + ;; Send a signal to the process of the calling thread. + ;; Note: This is similar to `raise` in POSIX. + (func (export "proc_raise") + ;; The signal condition to trigger. + (param $sig $signal_t) + (result $error $errno_t) + ) + + ;; Temporarily yield execution of the calling thread. + ;; Note: This is similar to `sched_yield` in POSIX. + (func (export "proc_sched_yield") + (result $error $errno_t) + ) + + ;; Write high-quality random data into a buffer. + ;; This function blocks when the implementation is unable to immediately + ;; provide sufficient high-quality random data. + ;; This function may execute slowly, so when large mounts of random data are + ;; required, it's advisable to use this function to seed a pseudo-random + ;; number generator, rather than to provide the random data directly. + (func (export "random_get") + ;; The buffer to fill with random data. + (param $buf data) + (result $error $errno_t) + ) + + ;; Receive a message from a socket. + ;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;; the data into multiple buffers in the manner of `readv`. + (func (export "sock_recv") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_t_array) + ;; Message flags. + (param $ri_flags $riflags_t) + (result $error $errno_t) + ;; Number of bytes stored in ri_data. + (result $ro_datalen $size_t) + ;; Message flags. + (result $ro_flags $roflags_t) + ) + + ;; Send a message on a socket. + ;; Note: This is similar to `send` in POSIX, though it also supports writing + ;; the data from multiple buffers in the manner of `writev`. + (func (export "sock_send") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_t_array) + ;; Message flags. + (param $si_flags $siflags_t) + (result $error $errno_t) + ;; Number of bytes transmitted. + (result $so_datalen $size_t) + ) + + ;; Shut down socket send and receive channels. + ;; Note: This is similar to `shutdown` in POSIX. + (func (export "sock_shutdown") + (param $self $fd_t) + ;; Which channels on the socket to shut down. + (param $how $sdflags_t) + (result $error $errno_t) + ) +) From 8ac533a22eddd4d552682769c9f319d1e3848f55 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 14 Aug 2019 22:42:24 -0700 Subject: [PATCH 0086/1772] A wasi_unstable description based on module types. This sketches out a description of the current wasi_unstable API, using a syntax which anticipates the "module types" syntax [recently proposed to the CG](https://github.com/WebAssembly/meetings/blob/master/2019/CG-08-06.md#discuss-new-proposal-that-introduces-types-for-modules-and-instances-and-text-format-thereof-as-initially-discussed-in-design1289), though it does use a few extensions which can be easily lowered, and which mostly anticipate the [Interface Types](https://github.com/WebAssembly/webidl-bindings/issues/47#issuecomment-519717553) proposal. This is derived from [the WatIDL proposal](https://github.com/WebAssembly/WASI/pull/64), though it differs in a few ways: - It doesn't yet do anything special for capabilities, for now. File descriptors are just integers, for now. But the idea is that we could add OCAP concepts later. - It uses a new `(flags ...)` construct in place of structs of Bool fields, to describe flags values. This allows us to explicitly declare the underlying wasm type for flags values. - Types used by the API are declared outside of the moduletype, because we're using wat syntax as much as possible, and there, `(type ...)` inside a module declares an entry in the type section, which isn't what's intended here. The extensions to module types are: - It uses `string`, `array`, and `{s,u}{8,16,32,64}` types, which are expected to be provided in some form by the Interface Types proposal. For now though, they can all be lowered in straightforward ways, by assuming that `string` is always just UTF-8. - It adds `typename` declarations, which can name any wasm type, and of the extra types mentioned in the previous item, or `struct`, `enum`, or `flags`. - It declares functions with multiple return values, which for now will need to be lowered to output (pointer) parameters. --- .../design/wasi_unstable/wasi_unstable.wati | 1206 +++++++++++++++++ 1 file changed, 1206 insertions(+) create mode 100644 proposals/random/design/wasi_unstable/wasi_unstable.wati diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.wati b/proposals/random/design/wasi_unstable/wasi_unstable.wati new file mode 100644 index 000000000..1dd067917 --- /dev/null +++ b/proposals/random/design/wasi_unstable/wasi_unstable.wati @@ -0,0 +1,1206 @@ +;; The wasi_unstable module type. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). + +(typename $size_t u32) +(typename $string_array (array string)) + +;; Non-negative file size or length of a region within a file. +(typename $filesize_t u64) + +;; Timestamp in nanoseconds. +(typename $timestamp_t u64) + +;; Identifiers for clocks. +(typename $clockid_t + (enum u32 + ;; The store-wide monotonic clock, which is defined as a clock measuring + ;; real time, whose value cannot be adjusted and which cannot have negative + ;; clock jumps. The epoch of this clock is undefined. The absolute time + ;; value of this clock therefore has no meaning. + $CLOCK_MONOTONIC + ;; The CPU-time clock associated with the current process. + $CLOCK_PROCESS_CPUTIME_ID + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME + ;; The CPU-time clock associated with the current thread. + $CLOCK_THREAD_CPUTIME_ID + ) +) + +;; Error codes returned by functions. +;; Not all of these error codes are returned by the functions provided by this +;; API; some are used in higher-level library layers, and others are provided +;; merely for alignment with POSIX. +(typename $errno_t + (enum u16 + ;; No error occurred. System call completed successfully. + $ESUCCESS + ;; Argument list too long. + $E2BIG + ;; Permission denied. + $EACCES + ;; Address in use. + $EADDRINUSE + ;; Address not available. + $EADDRNOTAVAIL + ;; Address family not supported. + $EAFNOSUPPORT + ;; Resource unavailable, or operation would block. + $EAGAIN + ;; Connection already in progress. + $EALREADY + ;; Bad file descriptor. + $EBADF + ;; Bad message. + $EBADMSG + ;; Device or resource busy. + $EBUSY + ;; Operation canceled. + $ECANCELED + ;; No child processes. + $ECHILD + ;; Connection aborted. + $ECONNABORTED + ;; Connection refused. + $ECONNREFUSED + ;; Connection reset. + $ECONNRESET + ;; Resource deadlock would occur. + $EDEADLK + ;; Destination address required. + $EDESTADDRREQ + ;; Mathematics argument out of domain of function. + $EDOM + ;; Reserved. + $EDQUOT + ;; File exists. + $EEXIST + ;; Bad address. + $EFAULT + ;; File too large. + $EFBIG + ;; Host is unreachable. + $EHOSTUNREACH + ;; Identifier removed. + $EIDRM + ;; Illegal byte sequence. + $EILSEQ + ;; Operation in progress. + $EINPROGRESS + ;; Interrupted function. + $EINTR + ;; Invalid argument. + $EINVAL + ;; I/O error. + $EIO + ;; Socket is connected. + $EISCONN + ;; Is a directory. + $EISDIR + ;; Too many levels of symbolic links. + $ELOOP + ;; File descriptor value too large. + $EMFILE + ;; Too many links. + $EMLINK + ;; Message too large. + $EMSGSIZE + ;; Reserved. + $EMULTIHOP + ;; Filename too long. + $ENAMETOOLONG + ;; Network is down. + $ENETDOWN + ;; Connection aborted by network. + $ENETRESET + ;; Network unreachable. + $ENETUNREACH + ;; Too many files open in system. + $ENFILE + ;; No buffer space available. + $ENOBUFS + ;; No such device. + $ENODEV + ;; No such file or directory. + $ENOENT + ;; Executable file format error. + $ENOEXEC + ;; No locks available. + $ENOLCK + ;; Reserved. + $ENOLINK + ;; Not enough space. + $ENOMEM + ;; No message of the desired type. + $ENOMSG + ;; Protocol not available. + $ENOPROTOOPT + ;; No space left on device. + $ENOSPC + ;; Function not supported. + $ENOSYS + ;; The socket is not connected. + $ENOTCONN + ;; Not a directory or a symbolic link to a directory. + $ENOTDIR + ;; Directory not empty. + $ENOTEMPTY + ;; State not recoverable. + $ENOTRECOVERABLE + ;; Not a socket. + $ENOTSOCK + ;; Not supported, or operation not supported on socket. + $ENOTSUP + ;; Inappropriate I/O control operation. + $ENOTTY + ;; No such device or address. + $ENXIO + ;; Value too large to be stored in data type. + $EOVERFLOW + ;; Previous owner died. + $EOWNERDEAD + ;; Operation not permitted. + $EPERM + ;; Broken pipe. + $EPIPE + ;; Protocol error. + $EPROTO + ;; Protocol not supported. + $EPROTONOSUPPORT + ;; Protocol wrong type for socket. + $EPROTOTYPE + ;; Result too large. + $ERANGE + ;; Read-only file system. + $EROFS + ;; Invalid seek. + $ESPIPE + ;; No such process. + $ESRCH + ;; Reserved. + $ESTALE + ;; Connection timed out. + $ETIMEDOUT + ;; Text file busy. + $ETXTBSY + ;; Cross-device link. + $EXDEV + ;; Extension: Capabilities insufficient. + $ENOTCAPABLE + ) +) + +;; File descriptor rights, determining which actions may be performed. +(typename $rights_t + (flags u64 + ;; The right to invoke __wasi_fd_datasync(). + ;; + ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke + ;` __wasi_path_open() with __WASI_FDFLAG_DSYNC. + (flag $RIGHT_FD_DATASYNC) + ;; The right to invoke __wasi_fd_read() and __wasi_sock_recv(). + ;; + ;; If __WASI_RIGHT_FD_SEEK is set, includes the right to invoke + ;; __wasi_fd_pread(). + (flag $RIGHT_FD_READ) + ;; The right to invoke __wasi_fd_seek(). This flag implies __WASI_RIGHT_FD_TELL. + (flag $RIGHT_FD_SEEK) + ;; The right to invoke __wasi_fd_fdstat_set_flags(). + (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + ;; The right to invoke __wasi_fd_sync(). + ;; + ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke + ;; __wasi_path_open() with __WASI_FDFLAG_RSYNC and __WASI_FDFLAG_DSYNC. + (flag $RIGHT_FD_SYNC) + ;; The right to invoke __wasi_fd_seek() in such a way that the file offset + ;; remains unaltered (i.e., __WASI_WHENCE_CUR with offset zero), or to + ;; invoke __wasi_fd_tell(). + (flag $RIGHT_FD_TELL) + ;; The right to invoke __wasi_fd_write() and __wasi_sock_send(). + ;; If __WASI_RIGHT_FD_SEEK is set, includes the right to invoke __wasi_fd_pwrite(). + (flag $RIGHT_FD_WRITE) + ;; The right to invoke __wasi_fd_advise(). + (flag $RIGHT_FD_ADVISE) + ;; The right to invoke __wasi_fd_allocate(). + (flag $RIGHT_FD_ALLOCATE) + ;; The right to invoke __wasi_path_create_directory(). + (flag $RIGHT_PATH_CREATE_DIRECTORY) + ;; If __WASI_RIGHT_PATH_OPEN is set, the right to invoke __wasi_path_open() with __WASI_O_CREAT. + (flag $RIGHT_PATH_CREATE_FILE) + ;; The right to invoke __wasi_path_link() with the file descriptor as the source directory. + (flag $RIGHT_PATH_LINK_SOURCE) + ;; The right to invoke __wasi_path_link() with the file descriptor as the target directory. + (flag $RIGHT_PATH_LINK_TARGET) + ;; The right to invoke __wasi_path_open(). + (flag $RIGHT_PATH_OPEN) + ;; The right to invoke __wasi_fd_readdir(). + (flag $RIGHT_FD_READDIR) + ;; The right to invoke __wasi_path_readlink(). + (flag $RIGHT_PATH_READLINK) + ;; The right to invoke __wasi_path_rename() with the file descriptor as the source directory. + (flag $RIGHT_PATH_RENAME_SOURCE) + ;; The right to invoke __wasi_path_rename() with the file descriptor as the target directory. + (flag $RIGHT_PATH_RENAME_TARGET) + ;; The right to invoke __wasi_path_filestat_get(). + (flag $RIGHT_PATH_FILESTAT_GET) + ;; The right to change a file's size (there is no __wasi_path_filestat_set_size()). + ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke __wasi_path_open() with __WASI_O_TRUNC. + (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + ;; The right to invoke __wasi_path_filestat_set_times(). + (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + ;; The right to invoke __wasi_fd_filestat_get(). + (flag $RIGHT_FD_FILESTAT_GET) + ;; The right to invoke __wasi_fd_filestat_set_size(). + (flag $RIGHT_FD_FILESTAT_SET_SIZE) + ;; The right to invoke __wasi_fd_filestat_set_times(). + (flag $RIGHT_FD_FILESTAT_SET_TIMES) + ;; The right to invoke __wasi_path_symlink(). + (flag $RIGHT_PATH_SYMLINK) + ;; The right to invoke __wasi_path_unlink_file(). + (flag $RIGHT_PATH_UNLINK_FILE) + ;; The right to invoke __wasi_path_remove_directory(). + (flag $RIGHT_PATH_REMOVE_DIRECTORY) + ;; If __WASI_RIGHT_FD_READ is set, includes the right to invoke __wasi_poll_oneoff() to subscribe to __WASI_EVENTTYPE_FD_READ. + ;; If __WASI_RIGHT_FD_WRITE is set, includes the right to invoke __wasi_poll_oneoff() to subscribe to __WASI_EVENTTYPE_FD_WRITE. + (flag $RIGHT_POLL_FD_READWRITE) + ;; The right to invoke __wasi_sock_shutdown(). + (flag $RIGHT_SOCK_SHUTDOWN) + ) +) + +;; a file descriptor index +(typename $fd_t u32) + +(typename $iovec_t_array (array $iovec_t)) +(typename $ciovec_t_array (array $ciovec_t)) + +;; A region of memory for scatter/gather reads. +(typename $iovec_t + (struct + ;; The address and length of the buffer to be filled. + (field $buf data) + (field $buf_len data) + ) +) + +;; A region of memory for scatter/gather writes. +(typename $ciovec_t + (struct + ;; The address and length of the buffer to be written. + (field $buf data) + (field $buf_len data) + ) +) + +;; Relative offset within a file. +(typename $filedelta_t s64) + +;; The position relative to which to set the offset of the file descriptor. +(typename $whence_t + (enum u8 + ;; Seek relative to current position. + $WHENCE_CUR + ;; Seek relative to end-of-file. + $WHENCE_END + ;; Seek relative to start-of-file. + $WHENCE_SET + ) +) + +;; A reference to the offset of a directory entry. +(typename $dircookie_t u64) + +;; The type for the $d_namelen field of $dirent_t. +(typename $dirnamlen_t u32) + +;; A directory entry. +(typename $dirent_t + (struct + ;; The offset of the next directory entry stored in this directory. + (field $d_next $dircookie_t) + ;; The serial number of the file referred to by this directory entry. + (field $d_ino $inode_t) + ;; The length of the name of the directory entry. + (field $d_namlen $dirnamelen_t) + ;; The type of the file referred to by this directory entry. + (field $d_type $filetype_t) + ) +) + +;; File or memory access pattern advisory information. +(typename $advice_t + (enum u8 + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE + ;; The application has no advice to give on its behavior with respect to the specified data. + $ADVICE_NORMAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM + ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in the near future. + $ADVICE_WILLNEED + ) +) + +;; File descriptor flags. +(typename $fdflags_t + (flags u16 + ;; Append mode: Data written to the file is always appended to the file's end. + (flag $FDFLAG_APPEND) + ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + (flag $FDFLAG_DSYNC) + ;; Non-blocking mode. + (flag $FDFLAG_NONBLOCK) + ;; Synchronized read I/O operations. + (flag $FDFLAG_RSYNC) + ;; Write according to synchronized I/O file integrity completion. In + ;; addition to synchronizing the data stored in the file, the implementation + ;; may also synchronously update the file's metadata. + (flag $FDFLAG_SYNC) + ) +) + +;; File descriptor attributes. +(typename $fdstat_t + (struct + ;; File type. + (field $fs_filetype $filetype_t) + ;; File descriptor flags. + (field $fs_flags $fdflags_t) + ;; Rights that apply to this file descriptor. + (field $fs_rights_base $rights_t) + ;; Maximum set of rights that may be installed on new file descriptors that + ;; are created through this file descriptor, e.g., through + ;; __wasi_path_open(). + (field $fs_rights_inheriting $rights_t) + ) +) + +;; Identifier for a device containing a file system. Can be used in combination +;; with __wasi_inode_t to uniquely identify a file or directory in the +;; filesystem. +(typename $device_t u64) + +;; The type of a file descriptor or file. +(typename $filetype_t + (enum u8 + ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $FILETYPE_UNKNOWN + ;; The file descriptor or file refers to a block device inode. + $FILETYPE_BLOCK_DEVICE + ;; The file descriptor or file refers to a character device inode. + $FILETYPE_CHARACTER_DEVICE + ;; The file descriptor or file refers to a directory inode. + $FILETYPE_DIRECTORY + ;; The file descriptor or file refers to a regular file inode. + $FILETYPE_REGULAR_FILE + ;; The file descriptor or file refers to a datagram socket. + $FILETYPE_SOCKET_DGRAM + ;; The file descriptor or file refers to a byte-stream socket. + $FILETYPE_SOCKET_STREAM + ;; The file refers to a symbolic link inode. + $FILETYPE_SYMBOLIC_LINK + ) +) + +;; Which file time attributes to adjust. +(typename $fstflags_t + (flags u16 + ;; Adjust the last data access timestamp to the value stored in __wasi_filestat_t::st_atim. + (flag $FILESTAT_SET_ATIM) + ;; Adjust the last data access timestamp to the time of clock __WASI_CLOCK_REALTIME. + (flag $FILESTAT_SET_ATIM_NOW) + ;; Adjust the last data modification timestamp to the value stored in __wasi_filestat_t::st_mtim. + (flag $FILESTAT_SET_MTIM) + ;; Adjust the last data modification timestamp to the time of clock __WASI_CLOCK_REALTIME. + (flag $FILESTAT_SET_MTIM_NOW) + ) +) + +;; File serial number that is unique within its file system. +(typename $inode_t u64) + +;; Flags determining the method of how paths are resolved. +(typename $lookupflags_t + (flags u32 + ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + (flag $LOOKUP_SYMLINK_FOLLOW) + ) +) + +;; Open flags used by __wasi_path_open(). +(typename $oflags_t + (flags u16 + ;; Create file if it does not exist. + (flag $O_CREAT) + ;; Fail if not a directory. + (flag $O_DIRECTORY) + ;; Fail if file already exists. + (flag $O_EXCL) + ;; Truncate file to size 0. + (flag $O_TRUNC) + ) +) + +;; Number of hard links to an inode. +(typename $linkcount_t u32) + +;; File attributes. +(typename $filestat_t + (struct + ;; Device ID of device containing the file. + (field $st_dev $device_t) + ;; File serial number. + (field $st_ino $inode_t) + ;; File type. + (field $st_filetype $filetype_t) + ;; Number of hard links to the file. + (field $st_nlink $linkcount_t) + ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + (field $st_size $filesize_t) + ;; Last data access timestamp. + (field $st_atim $timestamp_t) + ;; Last data modification timestamp. + (field $st_mtim $timestamp_t) + ;; Last file status change timestamp. + (field $st_ctim $timestamp_t) + ) +) + +;; User-provided value that may be attached to objects that is retained when extracted from the implementation. +(typename $userdata_t u64) + +;; An event that occurred. +(typename $event_t + (struct + ;; User-provided value that got attached to __wasi_subscription_t::userdata. + (field $userdata $userdata_t) + ;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno_t) + ;; The type of the event that occurred. + (field $type $eventtype_t) + (field $u + (typename union + ;; When type is __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE: + (field $fd_readwrite + (typename stuct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) + ) + ) + (field $else Null) + ) + ) + ) +) + +;; The state of the file descriptor subscribed to with __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE. +(typename $eventrwflags_t + (flags u16 + ;; The peer of this socket has closed or disconnected. + (flag $EVENT_FD_READWRITE_HANGUP) + ) +) + +;; Type of a subscription to an event or its occurrence. +(typename $eventtype_t + (flags u8 + ;; The time value of clock __wasi_subscription_t::u.clock.clock_id has reached timestamp __wasi_subscription_t::u.clock.timeout. + (flag $EVENTTYPE_CLOCK) + ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has data available for reading. This event always triggers for regular files. + (flag $EVENTTYPE_FD_READ) + ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has capacity available for writing. This event always triggers for regular files. + (flag $EVENTTYPE_FD_WRITE) + ) +) + +;; Flags determining how to interpret the timestamp provided in __wasi_subscription_t::u.clock.timeout. +(typename $subclockflags_t + (flags u16 + ;; If set, treat the timestamp provided in + ;; __wasi_subscription_t::u.clock.timeout as an absolute timestamp of clock + ;; __wasi_subscription_t::u.clock.clock_id. If clear, treat the timestamp + ;; provided in __wasi_subscription_t::u.clock.timeout relative to the + ;; current time value of clock __wasi_subscription_t::u.clock.clock_id. + (flag $SUBSCRIPTION_CLOCK_ABSTIME) + ) +) + +;; Subscription to an event. +(typename $subscription_t + (struct + ;; User-provided value that is attached to the subscription in the implementation and returned through __wasi_event_t::userdata. + (field $userdata $userdata_t) + ;; The type of the event to which to subscribe. + (field $type $eventtype_t) + (field + (type + (union + ;; When type is __WASI_EVENTTYPE_CLOCK + (field $clock + (typename + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally to coalesce with other events. + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) + ) + ) + ;; When type is __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE: + (field $fd_readwrite + (type + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) + ) + ) + ) + ) + ) + ) + ) +) + +;; Exit code generated by a process when exiting. +(typename $exitcode_t u32) + +;; Signal condition. +(typename $signal_t + (enum u8 + ;; Process abort signal. + ;; Action: Terminates the process. + $SIGABRT + ;; Alarm clock. + ;; Action: Terminates the process. + $SIGALRM + ;; Access to an undefined portion of a memory object. + ;; Action: Terminates the process. + $SIGBUS + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT + ;; Erroneous arithmetic operation. + ;; Action: Terminates the process. + $SIGFPE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Kill. + ;; Action: Terminates the process. + $SIGKILL + ;; Write on a pipe with no one to read it. + ;; Action: Ignored. + $SIGPIPE + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Invalid memory reference. + ;; Action: Terminates the process. + $SIGSEGV + ;; Stop executing. + ;; Action: Stops executing. + $SIGSTOP + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS + ;; Termination signal. + ;; Action: Terminates the process. + $SIGTERM + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP + ;; Terminal stop signal. + ;; Action: Stops executing. + $SIGTSTP + ;; Background process attempting read. + ;; Action: Stops executing. + $SIGTTIN + ;; Background process attempting write. + ;; Action: Stops executing. + $SIGTTOU + ;; High bandwidth data is available at a socket. + ;; Action: Ignored. + $SIGURG + ;; User-defined signal 1. + ;; Action: Terminates the process. + $SIGUSR1 + ;; User-defined signal 2. + ;; Action: Terminates the process. + $SIGUSR2 + ;; Virtual timer expired. + ;; Action: Terminates the process. + $SIGVTALRM + ;; CPU time limit exceeded. + ;; Action: Terminates the process. + $SIGXCPU + ;; File size limit exceeded. + ;; Action: Terminates the process. + $SIGXFSZ + ) +) + +;; Flags provided to __wasi_sock_recv(). +(typename $riflags_t + (flags u16 + ;; Returns the message without removing it from the socket's receive queue. + (flag $SOCK_RECV_PEEK) + ;; On byte-stream sockets, block until the full amount of data can be returned. + (flag $SOCK_RECV_WAITALL) + ) +) + +;; Flags returned by __wasi_sock_recv(). +(typename $roflags_t + (flags u16 + ;; Returned by __wasi_sock_recv(): Message data has been truncated. + (flag $SOCK_RECV_DATA_TRUNCATED) + ) +) + +;; Flags provided to __wasi_sock_send(). As there are currently no flags defined, it must be set to zero. +(typename $siflags_t u16) + +;; Which channels on a socket to shut down. +(typename $sdflags_t + (flags u8 + ;; Disables further receive operations. + (flag $SHUT_RD) + ;; Disables further send operations. + (flag $SHUT_WR) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; The wasi_unstable moduletype. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(moduletype $wasi_unstable + ;; Linear memory used by the program. + (import "memory" (memory)) + + ;; The program entry point. + (import "_start" (func)) + + ;; Read command-line argument data. + ;; The size of the array should match that returned by `wasi_args_sizes_get()` + (func (export "args_get") + (result $error $errno_t) + (result $argv $string_array) + ) + ;; Return command-line argument data sizes. + (func (export "args_sizes_get") + (result $error $errno_t) + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Read environment variable data. + ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + (func (export "environ_get") + (result $error $errno_t) + (result $argv $string_array) + ) + ;; Return command-line argument data sizes. + (func (export "environ_sizes_get") + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Return the resolution of a clock. + ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;; Note: This is similar to `clock_getres` in POSIX. + (func (export "clock_res_get") + (result $error $errno_t) + ;; The clock for which to return the resolution. + (param $clock_id $clockid_t) + ;; The resolution of the clock. + (result $resolution $timestamp_t) + ) + ;; Return the time value of a clock. + ;; Note: This is similar to `clock_gettime` in POSIX. + (func (export "clock_time_get") + ;; The clock for which to return the time. + (param $clock_id $clockid_t) + ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp_t) + (result $error $errno_t) + ;; The time value of the clock. + (result $time $timestamp_t) + ) + + ;; Provide file advisory information on a file descriptor. + ;; Note: This is similar to `posix_fadvise` in POSIX. + (func (export "fd_advise") + (param $self $fd_t) + (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. + (param $len $filesize_t) ;; The length of the region to which the advisory applies. + (param $advice $advice_t) ;; The advice. + (result $error $errno_t) + ) + + ;; Force the allocation of space in a file. + ;; Note: This is similar to `posix_fallocate` in POSIX. + (func (export "fd_allocate") + (param $self $fd_t) + ;; The offset at which to start the allocation. + (param $offset $filesize_t) + ;; The length of the area that is allocated. + (param $len $filesize_t) + (result $error $errno_t) + ) + + ;; Close a file descriptor. + ;; Note: This is similar to `close` in POSIX. + (func (export "fd_close") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Synchronize the data of a file to disk. + ;; Note: This is similar to `fdatasync` in POSIX. + (func (export "fd_datasync") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Get the attributes of a file descriptor. + ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (func (export "fd_fdstat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the file descriptor's attributes are stored. + (result $fdstat_t) + ) + + ;; Adjust the flags associated with a file descriptor. + ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (func (export "fd_fdstat_set_flags") + (param $self $fd_t) + ;; The desired values of the file descriptor flags. + (param $flags $fdflags) + (result $error $errno_t) + ) + + ;; Adjust the rights associated with a file descriptor. + ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (func (export "fd_fdstat_set_rights") + (param $self $fd_t) + ;; The desired rights of the file descriptor. + (param $fs_rights_base $rights_t) + (param $fs_rights_inheriting $rights_t) + (result $error $errno_t) + ) + + ;; Return the attributes of an open file. + (func (export "fd_filestat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $fs_rights_base $rights_t) + ) + + ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;; Note: This is similar to `ftruncate` in POSIX. + (func (export "fd_filestat_set_size") + (param $self $fd_t) + ;; The desired file size. + (param $st_size $filesize_t) + (result $error $errno_t) + ) + + ;; Adjust the timestamps of an open file or directory. + ;; Note: This is similar to `futimens` in POSIX. + (func (export "fd_filestat_set_times") + (param $self $fd_t) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `preadv` in POSIX. + (func (export "fd_pread") + (param $self $fd_t) + ;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to read. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Return a description of the given preopened file descriptor. + (func (export "fd_prestat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the description is stored. + (result $buf $prestat_t) + ) + + ;; Return a description of the given preopened file descriptor. + (func (export "fd_prestat_dir_name") + (param $self $fd_t) + ;; A buffer into which to write the preopened directory name. + (param $path string) + (result $error $errno_t) + ) + + ;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `pwritev` in POSIX. + (func (export "fd_pwrite") + (param $self $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to write. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Read from a file descriptor. + ;; Note: This is similar to `readv` in POSIX. + (func (export "fd_read") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Read directory entries from a directory. + ;; When successful, the contents of the output buffer consist of a sequence of + ;; directory entries. Each directory entry consists of a dirent_t object, + ;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;; entry. + ;; + ;; This function fills the output buffer as much as possible, potentially + ;; truncating the last directory entry. This allows the caller to grow its + ;; read buffer size in case it's too small to fit a single large directory + ;; entry, or skip the oversized directory entry. + (func (export "fd_readdir") + (param $self $fd_t) + ;; The buffer where directory entries are stored + (param $buf data) + ;; The location within the directory to start reading + (param $cookie $dircookie_t) + (result $error $errno_t) + ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size_t) + ) + + ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary number, like dup2(). This would be prone to race conditions, as an actual file descriptor with the same number could be allocated by a different thread at the same time. + ;; This function provides a way to atomically renumber file descriptors, which would disappear if dup2() were to be removed entirely. + (func (export "fd_renumber") + (param $self $fd_t) + ;; The file descriptor to overwrite. + (param $to $fd_t) + (result $error $errno_t) + ) + + ;; Move the offset of a file descriptor. + ;; Note: This is similar to `lseek` in POSIX. + (func (export "fd_seek") + (param $self $fd_t) + ;; The number of bytes to move. + (param $offset $filedelta_t) + ;; The base from which the offset is relative. + (param $whence $whence_t) + (result $error $errno_t) + ;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize_t) + ) + + ;; Synchronize the data and metadata of a file to disk. + ;; Note: This is similar to `fsync` in POSIX. + (func (export "fd_sync") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Return the current offset of a file descriptor. + ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (func (export "fd_tell") + (param $self $fd_t) + (result $error $errno_t) + ;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize_t) + ) + + ;; Write to a file descriptor. + ;; Note: This is similar to `writev` in POSIX. + (func (export "fd_write") + (param $self $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Create a directory. + ;; Note: This is similar to `mkdirat` in POSIX. + (func (export "path_create_directory") + (param $self $fd_t) + ;; The path at which to create the directory. + (param $path string) + (result $error $errno_t) + ) + + ;; Return the attributes of a file or directory. + ;; Note: This is similar to `stat` in POSIX. + (func (export "path_filestat_get") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $buf $filestat_t) + ) + + ;; Adjust the timestamps of a file or directory. + ;; Note: This is similar to `utimensat` in POSIX. + (func (export "path_filestat_set_times") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to operate on. + (param $path string) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Create a hard link. + ;; Note: This is similar to `linkat` in POSIX. + (func (export "path_link") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags_t) + ;; The source path from which to link. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $path) + ;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Open a file or directory. + ;; + ;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;; file descriptor not currently open; it is randomized to prevent + ;; applications from depending on making assumptions about indexes, since this + ;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;; guaranteed to be less than 231. + ;; + ;; Note: This is similar to `openat` in POSIX. + (func (export "path_open") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags_t) + ;; The relative path of the file or directory to open, relative to the + ;; `dirfd` directory. + (param $path string) + ;; The method by which to open the file. + (param $o_flags $oflags_t) + ;; The initial rights of the newly created file descriptor. The + ;; implementation is allowed to return a file descriptor with fewer rights + ;; than specified, if and only if those rights do not apply to the type of + ;; file being opened. + ;; + ;; The base rights are rights that will apply to operations using the file + ;; descriptor itself, while the inheriting rights are rights that apply to + ;; file descriptors derived from it. + (param $fs_rights_base $rights_t) + (param $fs_rights_inherting $rights_t) + (result $error $errno_t) + ;; The file descriptor of the file that has been opened. + (result $opened_fd $fd_t) + ) + + ;; Read the contents of a symbolic link. + ;; Note: This is similar to `readlinkat` in POSIX. + (func (export "path_readlink") + (param $self $fd_t) + ;; The path of the symbolic link from which to read. + (param $path) + ;; The buffer to which to write the contents of the symbolic link. + (param $buf string) + (result $error $errno_t) + ;; The number of bytes placed in the buffer. + (result $bufused $size_t) + ) + + ;; Remove a directory. + ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. + ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (func (export "path_remove_directory") + (param $self $fd_t) + ;; The path to a directory to remove. + (param $path string) + (result $error $errno_t) + ) + + ;; Rename a file or directory. + ;; Note: This is similar to `renameat` in POSIX. + (func (export "path_rename") + (param $self $fd_t) + ;; The source path of the file or directory to rename. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd) + ;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Create a symbolic link. + ;; Note: This is similar to `symlinkat` in POSIX. + (func (export "path_symlink") + (param $self $fd_t) + ;; The contents of the symbolic link. + (param $old_path string) + ;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno_t) + ) + + + ;; Unlink a file. + ;; Return __WASI_EISDIR if the path refers to a directory. + ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (func (export "path_unlink_file") + (param $self $fd_t) + ;; The path to a file to unlink. + (param $path string) + (result $error $errno_t) + ) + + ;; Concurrently poll for the occurrence of a set of events. + (func (export "poll_oneoff") + ;; The events to which to subscribe. + (param $in $subscription_t) + ;; The events that have occurred. + (param $out $event_t) + ;; Both the number of subscriptions and events. + (param $nsubscriptions $size_t) + (result $error $errno_t) + ;; The number of events stored. + (result $nevents $size_t) + ) + + ;; Terminate the process normally. An exit code of 0 indicates successful + ;; termination of the program. The meanings of other values is dependent on + ;; the environment. + (func (export "proc_exit") + ;; The exit code returned by the process. + (param $rval $exitcode_t) + ) + + ;; Send a signal to the process of the calling thread. + ;; Note: This is similar to `raise` in POSIX. + (func (export "proc_raise") + ;; The signal condition to trigger. + (param $sig $signal_t) + (result $error $errno_t) + ) + + ;; Temporarily yield execution of the calling thread. + ;; Note: This is similar to `sched_yield` in POSIX. + (func (export "proc_sched_yield") + (result $error $errno_t) + ) + + ;; Write high-quality random data into a buffer. + ;; This function blocks when the implementation is unable to immediately + ;; provide sufficient high-quality random data. + ;; This function may execute slowly, so when large mounts of random data are + ;; required, it's advisable to use this function to seed a pseudo-random + ;; number generator, rather than to provide the random data directly. + (func (export "random_get") + ;; The buffer to fill with random data. + (param $buf data) + (result $error $errno_t) + ) + + ;; Receive a message from a socket. + ;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;; the data into multiple buffers in the manner of `readv`. + (func (export "sock_recv") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_t_array) + ;; Message flags. + (param $ri_flags $riflags_t) + (result $error $errno_t) + ;; Number of bytes stored in ri_data. + (result $ro_datalen $size_t) + ;; Message flags. + (result $ro_flags $roflags_t) + ) + + ;; Send a message on a socket. + ;; Note: This is similar to `send` in POSIX, though it also supports writing + ;; the data from multiple buffers in the manner of `writev`. + (func (export "sock_send") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_t_array) + ;; Message flags. + (param $si_flags $siflags_t) + (result $error $errno_t) + ;; Number of bytes transmitted. + (result $so_datalen $size_t) + ) + + ;; Shut down socket send and receive channels. + ;; Note: This is similar to `shutdown` in POSIX. + (func (export "sock_shutdown") + (param $self $fd_t) + ;; Which channels on the socket to shut down. + (param $how $sdflags_t) + (result $error $errno_t) + ) +) From 14139c8addca5f82be3e382885880e7ff9444e08 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 14 Aug 2019 22:42:24 -0700 Subject: [PATCH 0087/1772] A wasi_unstable description based on module types. This sketches out a description of the current wasi_unstable API, using a syntax which anticipates the "module types" syntax [recently proposed to the CG](https://github.com/WebAssembly/meetings/blob/master/2019/CG-08-06.md#discuss-new-proposal-that-introduces-types-for-modules-and-instances-and-text-format-thereof-as-initially-discussed-in-design1289), though it does use a few extensions which can be easily lowered, and which mostly anticipate the [Interface Types](https://github.com/WebAssembly/webidl-bindings/issues/47#issuecomment-519717553) proposal. This is derived from [the WatIDL proposal](https://github.com/WebAssembly/WASI/pull/64), though it differs in a few ways: - It doesn't yet do anything special for capabilities, for now. File descriptors are just integers, for now. But the idea is that we could add OCAP concepts later. - It uses a new `(flags ...)` construct in place of structs of Bool fields, to describe flags values. This allows us to explicitly declare the underlying wasm type for flags values. - Types used by the API are declared outside of the moduletype, because we're using wat syntax as much as possible, and there, `(type ...)` inside a module declares an entry in the type section, which isn't what's intended here. The extensions to module types are: - It uses `string`, `array`, and `{s,u}{8,16,32,64}` types, which are expected to be provided in some form by the Interface Types proposal. For now though, they can all be lowered in straightforward ways, by assuming that `string` is always just UTF-8. - It adds `typename` declarations, which can name any wasm type, and of the extra types mentioned in the previous item, or `struct`, `enum`, or `flags`. - It declares functions with multiple return values, which for now will need to be lowered to output (pointer) parameters. --- .../design/wasi_unstable/wasi_unstable.wati | 1206 +++++++++++++++++ 1 file changed, 1206 insertions(+) create mode 100644 proposals/filesystem/design/wasi_unstable/wasi_unstable.wati diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati new file mode 100644 index 000000000..1dd067917 --- /dev/null +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati @@ -0,0 +1,1206 @@ +;; The wasi_unstable module type. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). + +(typename $size_t u32) +(typename $string_array (array string)) + +;; Non-negative file size or length of a region within a file. +(typename $filesize_t u64) + +;; Timestamp in nanoseconds. +(typename $timestamp_t u64) + +;; Identifiers for clocks. +(typename $clockid_t + (enum u32 + ;; The store-wide monotonic clock, which is defined as a clock measuring + ;; real time, whose value cannot be adjusted and which cannot have negative + ;; clock jumps. The epoch of this clock is undefined. The absolute time + ;; value of this clock therefore has no meaning. + $CLOCK_MONOTONIC + ;; The CPU-time clock associated with the current process. + $CLOCK_PROCESS_CPUTIME_ID + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME + ;; The CPU-time clock associated with the current thread. + $CLOCK_THREAD_CPUTIME_ID + ) +) + +;; Error codes returned by functions. +;; Not all of these error codes are returned by the functions provided by this +;; API; some are used in higher-level library layers, and others are provided +;; merely for alignment with POSIX. +(typename $errno_t + (enum u16 + ;; No error occurred. System call completed successfully. + $ESUCCESS + ;; Argument list too long. + $E2BIG + ;; Permission denied. + $EACCES + ;; Address in use. + $EADDRINUSE + ;; Address not available. + $EADDRNOTAVAIL + ;; Address family not supported. + $EAFNOSUPPORT + ;; Resource unavailable, or operation would block. + $EAGAIN + ;; Connection already in progress. + $EALREADY + ;; Bad file descriptor. + $EBADF + ;; Bad message. + $EBADMSG + ;; Device or resource busy. + $EBUSY + ;; Operation canceled. + $ECANCELED + ;; No child processes. + $ECHILD + ;; Connection aborted. + $ECONNABORTED + ;; Connection refused. + $ECONNREFUSED + ;; Connection reset. + $ECONNRESET + ;; Resource deadlock would occur. + $EDEADLK + ;; Destination address required. + $EDESTADDRREQ + ;; Mathematics argument out of domain of function. + $EDOM + ;; Reserved. + $EDQUOT + ;; File exists. + $EEXIST + ;; Bad address. + $EFAULT + ;; File too large. + $EFBIG + ;; Host is unreachable. + $EHOSTUNREACH + ;; Identifier removed. + $EIDRM + ;; Illegal byte sequence. + $EILSEQ + ;; Operation in progress. + $EINPROGRESS + ;; Interrupted function. + $EINTR + ;; Invalid argument. + $EINVAL + ;; I/O error. + $EIO + ;; Socket is connected. + $EISCONN + ;; Is a directory. + $EISDIR + ;; Too many levels of symbolic links. + $ELOOP + ;; File descriptor value too large. + $EMFILE + ;; Too many links. + $EMLINK + ;; Message too large. + $EMSGSIZE + ;; Reserved. + $EMULTIHOP + ;; Filename too long. + $ENAMETOOLONG + ;; Network is down. + $ENETDOWN + ;; Connection aborted by network. + $ENETRESET + ;; Network unreachable. + $ENETUNREACH + ;; Too many files open in system. + $ENFILE + ;; No buffer space available. + $ENOBUFS + ;; No such device. + $ENODEV + ;; No such file or directory. + $ENOENT + ;; Executable file format error. + $ENOEXEC + ;; No locks available. + $ENOLCK + ;; Reserved. + $ENOLINK + ;; Not enough space. + $ENOMEM + ;; No message of the desired type. + $ENOMSG + ;; Protocol not available. + $ENOPROTOOPT + ;; No space left on device. + $ENOSPC + ;; Function not supported. + $ENOSYS + ;; The socket is not connected. + $ENOTCONN + ;; Not a directory or a symbolic link to a directory. + $ENOTDIR + ;; Directory not empty. + $ENOTEMPTY + ;; State not recoverable. + $ENOTRECOVERABLE + ;; Not a socket. + $ENOTSOCK + ;; Not supported, or operation not supported on socket. + $ENOTSUP + ;; Inappropriate I/O control operation. + $ENOTTY + ;; No such device or address. + $ENXIO + ;; Value too large to be stored in data type. + $EOVERFLOW + ;; Previous owner died. + $EOWNERDEAD + ;; Operation not permitted. + $EPERM + ;; Broken pipe. + $EPIPE + ;; Protocol error. + $EPROTO + ;; Protocol not supported. + $EPROTONOSUPPORT + ;; Protocol wrong type for socket. + $EPROTOTYPE + ;; Result too large. + $ERANGE + ;; Read-only file system. + $EROFS + ;; Invalid seek. + $ESPIPE + ;; No such process. + $ESRCH + ;; Reserved. + $ESTALE + ;; Connection timed out. + $ETIMEDOUT + ;; Text file busy. + $ETXTBSY + ;; Cross-device link. + $EXDEV + ;; Extension: Capabilities insufficient. + $ENOTCAPABLE + ) +) + +;; File descriptor rights, determining which actions may be performed. +(typename $rights_t + (flags u64 + ;; The right to invoke __wasi_fd_datasync(). + ;; + ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke + ;` __wasi_path_open() with __WASI_FDFLAG_DSYNC. + (flag $RIGHT_FD_DATASYNC) + ;; The right to invoke __wasi_fd_read() and __wasi_sock_recv(). + ;; + ;; If __WASI_RIGHT_FD_SEEK is set, includes the right to invoke + ;; __wasi_fd_pread(). + (flag $RIGHT_FD_READ) + ;; The right to invoke __wasi_fd_seek(). This flag implies __WASI_RIGHT_FD_TELL. + (flag $RIGHT_FD_SEEK) + ;; The right to invoke __wasi_fd_fdstat_set_flags(). + (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + ;; The right to invoke __wasi_fd_sync(). + ;; + ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke + ;; __wasi_path_open() with __WASI_FDFLAG_RSYNC and __WASI_FDFLAG_DSYNC. + (flag $RIGHT_FD_SYNC) + ;; The right to invoke __wasi_fd_seek() in such a way that the file offset + ;; remains unaltered (i.e., __WASI_WHENCE_CUR with offset zero), or to + ;; invoke __wasi_fd_tell(). + (flag $RIGHT_FD_TELL) + ;; The right to invoke __wasi_fd_write() and __wasi_sock_send(). + ;; If __WASI_RIGHT_FD_SEEK is set, includes the right to invoke __wasi_fd_pwrite(). + (flag $RIGHT_FD_WRITE) + ;; The right to invoke __wasi_fd_advise(). + (flag $RIGHT_FD_ADVISE) + ;; The right to invoke __wasi_fd_allocate(). + (flag $RIGHT_FD_ALLOCATE) + ;; The right to invoke __wasi_path_create_directory(). + (flag $RIGHT_PATH_CREATE_DIRECTORY) + ;; If __WASI_RIGHT_PATH_OPEN is set, the right to invoke __wasi_path_open() with __WASI_O_CREAT. + (flag $RIGHT_PATH_CREATE_FILE) + ;; The right to invoke __wasi_path_link() with the file descriptor as the source directory. + (flag $RIGHT_PATH_LINK_SOURCE) + ;; The right to invoke __wasi_path_link() with the file descriptor as the target directory. + (flag $RIGHT_PATH_LINK_TARGET) + ;; The right to invoke __wasi_path_open(). + (flag $RIGHT_PATH_OPEN) + ;; The right to invoke __wasi_fd_readdir(). + (flag $RIGHT_FD_READDIR) + ;; The right to invoke __wasi_path_readlink(). + (flag $RIGHT_PATH_READLINK) + ;; The right to invoke __wasi_path_rename() with the file descriptor as the source directory. + (flag $RIGHT_PATH_RENAME_SOURCE) + ;; The right to invoke __wasi_path_rename() with the file descriptor as the target directory. + (flag $RIGHT_PATH_RENAME_TARGET) + ;; The right to invoke __wasi_path_filestat_get(). + (flag $RIGHT_PATH_FILESTAT_GET) + ;; The right to change a file's size (there is no __wasi_path_filestat_set_size()). + ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke __wasi_path_open() with __WASI_O_TRUNC. + (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + ;; The right to invoke __wasi_path_filestat_set_times(). + (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + ;; The right to invoke __wasi_fd_filestat_get(). + (flag $RIGHT_FD_FILESTAT_GET) + ;; The right to invoke __wasi_fd_filestat_set_size(). + (flag $RIGHT_FD_FILESTAT_SET_SIZE) + ;; The right to invoke __wasi_fd_filestat_set_times(). + (flag $RIGHT_FD_FILESTAT_SET_TIMES) + ;; The right to invoke __wasi_path_symlink(). + (flag $RIGHT_PATH_SYMLINK) + ;; The right to invoke __wasi_path_unlink_file(). + (flag $RIGHT_PATH_UNLINK_FILE) + ;; The right to invoke __wasi_path_remove_directory(). + (flag $RIGHT_PATH_REMOVE_DIRECTORY) + ;; If __WASI_RIGHT_FD_READ is set, includes the right to invoke __wasi_poll_oneoff() to subscribe to __WASI_EVENTTYPE_FD_READ. + ;; If __WASI_RIGHT_FD_WRITE is set, includes the right to invoke __wasi_poll_oneoff() to subscribe to __WASI_EVENTTYPE_FD_WRITE. + (flag $RIGHT_POLL_FD_READWRITE) + ;; The right to invoke __wasi_sock_shutdown(). + (flag $RIGHT_SOCK_SHUTDOWN) + ) +) + +;; a file descriptor index +(typename $fd_t u32) + +(typename $iovec_t_array (array $iovec_t)) +(typename $ciovec_t_array (array $ciovec_t)) + +;; A region of memory for scatter/gather reads. +(typename $iovec_t + (struct + ;; The address and length of the buffer to be filled. + (field $buf data) + (field $buf_len data) + ) +) + +;; A region of memory for scatter/gather writes. +(typename $ciovec_t + (struct + ;; The address and length of the buffer to be written. + (field $buf data) + (field $buf_len data) + ) +) + +;; Relative offset within a file. +(typename $filedelta_t s64) + +;; The position relative to which to set the offset of the file descriptor. +(typename $whence_t + (enum u8 + ;; Seek relative to current position. + $WHENCE_CUR + ;; Seek relative to end-of-file. + $WHENCE_END + ;; Seek relative to start-of-file. + $WHENCE_SET + ) +) + +;; A reference to the offset of a directory entry. +(typename $dircookie_t u64) + +;; The type for the $d_namelen field of $dirent_t. +(typename $dirnamlen_t u32) + +;; A directory entry. +(typename $dirent_t + (struct + ;; The offset of the next directory entry stored in this directory. + (field $d_next $dircookie_t) + ;; The serial number of the file referred to by this directory entry. + (field $d_ino $inode_t) + ;; The length of the name of the directory entry. + (field $d_namlen $dirnamelen_t) + ;; The type of the file referred to by this directory entry. + (field $d_type $filetype_t) + ) +) + +;; File or memory access pattern advisory information. +(typename $advice_t + (enum u8 + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE + ;; The application has no advice to give on its behavior with respect to the specified data. + $ADVICE_NORMAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM + ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in the near future. + $ADVICE_WILLNEED + ) +) + +;; File descriptor flags. +(typename $fdflags_t + (flags u16 + ;; Append mode: Data written to the file is always appended to the file's end. + (flag $FDFLAG_APPEND) + ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + (flag $FDFLAG_DSYNC) + ;; Non-blocking mode. + (flag $FDFLAG_NONBLOCK) + ;; Synchronized read I/O operations. + (flag $FDFLAG_RSYNC) + ;; Write according to synchronized I/O file integrity completion. In + ;; addition to synchronizing the data stored in the file, the implementation + ;; may also synchronously update the file's metadata. + (flag $FDFLAG_SYNC) + ) +) + +;; File descriptor attributes. +(typename $fdstat_t + (struct + ;; File type. + (field $fs_filetype $filetype_t) + ;; File descriptor flags. + (field $fs_flags $fdflags_t) + ;; Rights that apply to this file descriptor. + (field $fs_rights_base $rights_t) + ;; Maximum set of rights that may be installed on new file descriptors that + ;; are created through this file descriptor, e.g., through + ;; __wasi_path_open(). + (field $fs_rights_inheriting $rights_t) + ) +) + +;; Identifier for a device containing a file system. Can be used in combination +;; with __wasi_inode_t to uniquely identify a file or directory in the +;; filesystem. +(typename $device_t u64) + +;; The type of a file descriptor or file. +(typename $filetype_t + (enum u8 + ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $FILETYPE_UNKNOWN + ;; The file descriptor or file refers to a block device inode. + $FILETYPE_BLOCK_DEVICE + ;; The file descriptor or file refers to a character device inode. + $FILETYPE_CHARACTER_DEVICE + ;; The file descriptor or file refers to a directory inode. + $FILETYPE_DIRECTORY + ;; The file descriptor or file refers to a regular file inode. + $FILETYPE_REGULAR_FILE + ;; The file descriptor or file refers to a datagram socket. + $FILETYPE_SOCKET_DGRAM + ;; The file descriptor or file refers to a byte-stream socket. + $FILETYPE_SOCKET_STREAM + ;; The file refers to a symbolic link inode. + $FILETYPE_SYMBOLIC_LINK + ) +) + +;; Which file time attributes to adjust. +(typename $fstflags_t + (flags u16 + ;; Adjust the last data access timestamp to the value stored in __wasi_filestat_t::st_atim. + (flag $FILESTAT_SET_ATIM) + ;; Adjust the last data access timestamp to the time of clock __WASI_CLOCK_REALTIME. + (flag $FILESTAT_SET_ATIM_NOW) + ;; Adjust the last data modification timestamp to the value stored in __wasi_filestat_t::st_mtim. + (flag $FILESTAT_SET_MTIM) + ;; Adjust the last data modification timestamp to the time of clock __WASI_CLOCK_REALTIME. + (flag $FILESTAT_SET_MTIM_NOW) + ) +) + +;; File serial number that is unique within its file system. +(typename $inode_t u64) + +;; Flags determining the method of how paths are resolved. +(typename $lookupflags_t + (flags u32 + ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + (flag $LOOKUP_SYMLINK_FOLLOW) + ) +) + +;; Open flags used by __wasi_path_open(). +(typename $oflags_t + (flags u16 + ;; Create file if it does not exist. + (flag $O_CREAT) + ;; Fail if not a directory. + (flag $O_DIRECTORY) + ;; Fail if file already exists. + (flag $O_EXCL) + ;; Truncate file to size 0. + (flag $O_TRUNC) + ) +) + +;; Number of hard links to an inode. +(typename $linkcount_t u32) + +;; File attributes. +(typename $filestat_t + (struct + ;; Device ID of device containing the file. + (field $st_dev $device_t) + ;; File serial number. + (field $st_ino $inode_t) + ;; File type. + (field $st_filetype $filetype_t) + ;; Number of hard links to the file. + (field $st_nlink $linkcount_t) + ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + (field $st_size $filesize_t) + ;; Last data access timestamp. + (field $st_atim $timestamp_t) + ;; Last data modification timestamp. + (field $st_mtim $timestamp_t) + ;; Last file status change timestamp. + (field $st_ctim $timestamp_t) + ) +) + +;; User-provided value that may be attached to objects that is retained when extracted from the implementation. +(typename $userdata_t u64) + +;; An event that occurred. +(typename $event_t + (struct + ;; User-provided value that got attached to __wasi_subscription_t::userdata. + (field $userdata $userdata_t) + ;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno_t) + ;; The type of the event that occurred. + (field $type $eventtype_t) + (field $u + (typename union + ;; When type is __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE: + (field $fd_readwrite + (typename stuct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) + ) + ) + (field $else Null) + ) + ) + ) +) + +;; The state of the file descriptor subscribed to with __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE. +(typename $eventrwflags_t + (flags u16 + ;; The peer of this socket has closed or disconnected. + (flag $EVENT_FD_READWRITE_HANGUP) + ) +) + +;; Type of a subscription to an event or its occurrence. +(typename $eventtype_t + (flags u8 + ;; The time value of clock __wasi_subscription_t::u.clock.clock_id has reached timestamp __wasi_subscription_t::u.clock.timeout. + (flag $EVENTTYPE_CLOCK) + ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has data available for reading. This event always triggers for regular files. + (flag $EVENTTYPE_FD_READ) + ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has capacity available for writing. This event always triggers for regular files. + (flag $EVENTTYPE_FD_WRITE) + ) +) + +;; Flags determining how to interpret the timestamp provided in __wasi_subscription_t::u.clock.timeout. +(typename $subclockflags_t + (flags u16 + ;; If set, treat the timestamp provided in + ;; __wasi_subscription_t::u.clock.timeout as an absolute timestamp of clock + ;; __wasi_subscription_t::u.clock.clock_id. If clear, treat the timestamp + ;; provided in __wasi_subscription_t::u.clock.timeout relative to the + ;; current time value of clock __wasi_subscription_t::u.clock.clock_id. + (flag $SUBSCRIPTION_CLOCK_ABSTIME) + ) +) + +;; Subscription to an event. +(typename $subscription_t + (struct + ;; User-provided value that is attached to the subscription in the implementation and returned through __wasi_event_t::userdata. + (field $userdata $userdata_t) + ;; The type of the event to which to subscribe. + (field $type $eventtype_t) + (field + (type + (union + ;; When type is __WASI_EVENTTYPE_CLOCK + (field $clock + (typename + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally to coalesce with other events. + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) + ) + ) + ;; When type is __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE: + (field $fd_readwrite + (type + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) + ) + ) + ) + ) + ) + ) + ) +) + +;; Exit code generated by a process when exiting. +(typename $exitcode_t u32) + +;; Signal condition. +(typename $signal_t + (enum u8 + ;; Process abort signal. + ;; Action: Terminates the process. + $SIGABRT + ;; Alarm clock. + ;; Action: Terminates the process. + $SIGALRM + ;; Access to an undefined portion of a memory object. + ;; Action: Terminates the process. + $SIGBUS + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT + ;; Erroneous arithmetic operation. + ;; Action: Terminates the process. + $SIGFPE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Kill. + ;; Action: Terminates the process. + $SIGKILL + ;; Write on a pipe with no one to read it. + ;; Action: Ignored. + $SIGPIPE + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Invalid memory reference. + ;; Action: Terminates the process. + $SIGSEGV + ;; Stop executing. + ;; Action: Stops executing. + $SIGSTOP + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS + ;; Termination signal. + ;; Action: Terminates the process. + $SIGTERM + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP + ;; Terminal stop signal. + ;; Action: Stops executing. + $SIGTSTP + ;; Background process attempting read. + ;; Action: Stops executing. + $SIGTTIN + ;; Background process attempting write. + ;; Action: Stops executing. + $SIGTTOU + ;; High bandwidth data is available at a socket. + ;; Action: Ignored. + $SIGURG + ;; User-defined signal 1. + ;; Action: Terminates the process. + $SIGUSR1 + ;; User-defined signal 2. + ;; Action: Terminates the process. + $SIGUSR2 + ;; Virtual timer expired. + ;; Action: Terminates the process. + $SIGVTALRM + ;; CPU time limit exceeded. + ;; Action: Terminates the process. + $SIGXCPU + ;; File size limit exceeded. + ;; Action: Terminates the process. + $SIGXFSZ + ) +) + +;; Flags provided to __wasi_sock_recv(). +(typename $riflags_t + (flags u16 + ;; Returns the message without removing it from the socket's receive queue. + (flag $SOCK_RECV_PEEK) + ;; On byte-stream sockets, block until the full amount of data can be returned. + (flag $SOCK_RECV_WAITALL) + ) +) + +;; Flags returned by __wasi_sock_recv(). +(typename $roflags_t + (flags u16 + ;; Returned by __wasi_sock_recv(): Message data has been truncated. + (flag $SOCK_RECV_DATA_TRUNCATED) + ) +) + +;; Flags provided to __wasi_sock_send(). As there are currently no flags defined, it must be set to zero. +(typename $siflags_t u16) + +;; Which channels on a socket to shut down. +(typename $sdflags_t + (flags u8 + ;; Disables further receive operations. + (flag $SHUT_RD) + ;; Disables further send operations. + (flag $SHUT_WR) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; The wasi_unstable moduletype. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(moduletype $wasi_unstable + ;; Linear memory used by the program. + (import "memory" (memory)) + + ;; The program entry point. + (import "_start" (func)) + + ;; Read command-line argument data. + ;; The size of the array should match that returned by `wasi_args_sizes_get()` + (func (export "args_get") + (result $error $errno_t) + (result $argv $string_array) + ) + ;; Return command-line argument data sizes. + (func (export "args_sizes_get") + (result $error $errno_t) + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Read environment variable data. + ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + (func (export "environ_get") + (result $error $errno_t) + (result $argv $string_array) + ) + ;; Return command-line argument data sizes. + (func (export "environ_sizes_get") + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Return the resolution of a clock. + ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;; Note: This is similar to `clock_getres` in POSIX. + (func (export "clock_res_get") + (result $error $errno_t) + ;; The clock for which to return the resolution. + (param $clock_id $clockid_t) + ;; The resolution of the clock. + (result $resolution $timestamp_t) + ) + ;; Return the time value of a clock. + ;; Note: This is similar to `clock_gettime` in POSIX. + (func (export "clock_time_get") + ;; The clock for which to return the time. + (param $clock_id $clockid_t) + ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp_t) + (result $error $errno_t) + ;; The time value of the clock. + (result $time $timestamp_t) + ) + + ;; Provide file advisory information on a file descriptor. + ;; Note: This is similar to `posix_fadvise` in POSIX. + (func (export "fd_advise") + (param $self $fd_t) + (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. + (param $len $filesize_t) ;; The length of the region to which the advisory applies. + (param $advice $advice_t) ;; The advice. + (result $error $errno_t) + ) + + ;; Force the allocation of space in a file. + ;; Note: This is similar to `posix_fallocate` in POSIX. + (func (export "fd_allocate") + (param $self $fd_t) + ;; The offset at which to start the allocation. + (param $offset $filesize_t) + ;; The length of the area that is allocated. + (param $len $filesize_t) + (result $error $errno_t) + ) + + ;; Close a file descriptor. + ;; Note: This is similar to `close` in POSIX. + (func (export "fd_close") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Synchronize the data of a file to disk. + ;; Note: This is similar to `fdatasync` in POSIX. + (func (export "fd_datasync") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Get the attributes of a file descriptor. + ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (func (export "fd_fdstat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the file descriptor's attributes are stored. + (result $fdstat_t) + ) + + ;; Adjust the flags associated with a file descriptor. + ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (func (export "fd_fdstat_set_flags") + (param $self $fd_t) + ;; The desired values of the file descriptor flags. + (param $flags $fdflags) + (result $error $errno_t) + ) + + ;; Adjust the rights associated with a file descriptor. + ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (func (export "fd_fdstat_set_rights") + (param $self $fd_t) + ;; The desired rights of the file descriptor. + (param $fs_rights_base $rights_t) + (param $fs_rights_inheriting $rights_t) + (result $error $errno_t) + ) + + ;; Return the attributes of an open file. + (func (export "fd_filestat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $fs_rights_base $rights_t) + ) + + ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;; Note: This is similar to `ftruncate` in POSIX. + (func (export "fd_filestat_set_size") + (param $self $fd_t) + ;; The desired file size. + (param $st_size $filesize_t) + (result $error $errno_t) + ) + + ;; Adjust the timestamps of an open file or directory. + ;; Note: This is similar to `futimens` in POSIX. + (func (export "fd_filestat_set_times") + (param $self $fd_t) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `preadv` in POSIX. + (func (export "fd_pread") + (param $self $fd_t) + ;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to read. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Return a description of the given preopened file descriptor. + (func (export "fd_prestat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the description is stored. + (result $buf $prestat_t) + ) + + ;; Return a description of the given preopened file descriptor. + (func (export "fd_prestat_dir_name") + (param $self $fd_t) + ;; A buffer into which to write the preopened directory name. + (param $path string) + (result $error $errno_t) + ) + + ;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `pwritev` in POSIX. + (func (export "fd_pwrite") + (param $self $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to write. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Read from a file descriptor. + ;; Note: This is similar to `readv` in POSIX. + (func (export "fd_read") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Read directory entries from a directory. + ;; When successful, the contents of the output buffer consist of a sequence of + ;; directory entries. Each directory entry consists of a dirent_t object, + ;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;; entry. + ;; + ;; This function fills the output buffer as much as possible, potentially + ;; truncating the last directory entry. This allows the caller to grow its + ;; read buffer size in case it's too small to fit a single large directory + ;; entry, or skip the oversized directory entry. + (func (export "fd_readdir") + (param $self $fd_t) + ;; The buffer where directory entries are stored + (param $buf data) + ;; The location within the directory to start reading + (param $cookie $dircookie_t) + (result $error $errno_t) + ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size_t) + ) + + ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary number, like dup2(). This would be prone to race conditions, as an actual file descriptor with the same number could be allocated by a different thread at the same time. + ;; This function provides a way to atomically renumber file descriptors, which would disappear if dup2() were to be removed entirely. + (func (export "fd_renumber") + (param $self $fd_t) + ;; The file descriptor to overwrite. + (param $to $fd_t) + (result $error $errno_t) + ) + + ;; Move the offset of a file descriptor. + ;; Note: This is similar to `lseek` in POSIX. + (func (export "fd_seek") + (param $self $fd_t) + ;; The number of bytes to move. + (param $offset $filedelta_t) + ;; The base from which the offset is relative. + (param $whence $whence_t) + (result $error $errno_t) + ;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize_t) + ) + + ;; Synchronize the data and metadata of a file to disk. + ;; Note: This is similar to `fsync` in POSIX. + (func (export "fd_sync") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Return the current offset of a file descriptor. + ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (func (export "fd_tell") + (param $self $fd_t) + (result $error $errno_t) + ;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize_t) + ) + + ;; Write to a file descriptor. + ;; Note: This is similar to `writev` in POSIX. + (func (export "fd_write") + (param $self $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Create a directory. + ;; Note: This is similar to `mkdirat` in POSIX. + (func (export "path_create_directory") + (param $self $fd_t) + ;; The path at which to create the directory. + (param $path string) + (result $error $errno_t) + ) + + ;; Return the attributes of a file or directory. + ;; Note: This is similar to `stat` in POSIX. + (func (export "path_filestat_get") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $buf $filestat_t) + ) + + ;; Adjust the timestamps of a file or directory. + ;; Note: This is similar to `utimensat` in POSIX. + (func (export "path_filestat_set_times") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to operate on. + (param $path string) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Create a hard link. + ;; Note: This is similar to `linkat` in POSIX. + (func (export "path_link") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags_t) + ;; The source path from which to link. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $path) + ;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Open a file or directory. + ;; + ;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;; file descriptor not currently open; it is randomized to prevent + ;; applications from depending on making assumptions about indexes, since this + ;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;; guaranteed to be less than 231. + ;; + ;; Note: This is similar to `openat` in POSIX. + (func (export "path_open") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags_t) + ;; The relative path of the file or directory to open, relative to the + ;; `dirfd` directory. + (param $path string) + ;; The method by which to open the file. + (param $o_flags $oflags_t) + ;; The initial rights of the newly created file descriptor. The + ;; implementation is allowed to return a file descriptor with fewer rights + ;; than specified, if and only if those rights do not apply to the type of + ;; file being opened. + ;; + ;; The base rights are rights that will apply to operations using the file + ;; descriptor itself, while the inheriting rights are rights that apply to + ;; file descriptors derived from it. + (param $fs_rights_base $rights_t) + (param $fs_rights_inherting $rights_t) + (result $error $errno_t) + ;; The file descriptor of the file that has been opened. + (result $opened_fd $fd_t) + ) + + ;; Read the contents of a symbolic link. + ;; Note: This is similar to `readlinkat` in POSIX. + (func (export "path_readlink") + (param $self $fd_t) + ;; The path of the symbolic link from which to read. + (param $path) + ;; The buffer to which to write the contents of the symbolic link. + (param $buf string) + (result $error $errno_t) + ;; The number of bytes placed in the buffer. + (result $bufused $size_t) + ) + + ;; Remove a directory. + ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. + ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (func (export "path_remove_directory") + (param $self $fd_t) + ;; The path to a directory to remove. + (param $path string) + (result $error $errno_t) + ) + + ;; Rename a file or directory. + ;; Note: This is similar to `renameat` in POSIX. + (func (export "path_rename") + (param $self $fd_t) + ;; The source path of the file or directory to rename. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd) + ;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Create a symbolic link. + ;; Note: This is similar to `symlinkat` in POSIX. + (func (export "path_symlink") + (param $self $fd_t) + ;; The contents of the symbolic link. + (param $old_path string) + ;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno_t) + ) + + + ;; Unlink a file. + ;; Return __WASI_EISDIR if the path refers to a directory. + ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (func (export "path_unlink_file") + (param $self $fd_t) + ;; The path to a file to unlink. + (param $path string) + (result $error $errno_t) + ) + + ;; Concurrently poll for the occurrence of a set of events. + (func (export "poll_oneoff") + ;; The events to which to subscribe. + (param $in $subscription_t) + ;; The events that have occurred. + (param $out $event_t) + ;; Both the number of subscriptions and events. + (param $nsubscriptions $size_t) + (result $error $errno_t) + ;; The number of events stored. + (result $nevents $size_t) + ) + + ;; Terminate the process normally. An exit code of 0 indicates successful + ;; termination of the program. The meanings of other values is dependent on + ;; the environment. + (func (export "proc_exit") + ;; The exit code returned by the process. + (param $rval $exitcode_t) + ) + + ;; Send a signal to the process of the calling thread. + ;; Note: This is similar to `raise` in POSIX. + (func (export "proc_raise") + ;; The signal condition to trigger. + (param $sig $signal_t) + (result $error $errno_t) + ) + + ;; Temporarily yield execution of the calling thread. + ;; Note: This is similar to `sched_yield` in POSIX. + (func (export "proc_sched_yield") + (result $error $errno_t) + ) + + ;; Write high-quality random data into a buffer. + ;; This function blocks when the implementation is unable to immediately + ;; provide sufficient high-quality random data. + ;; This function may execute slowly, so when large mounts of random data are + ;; required, it's advisable to use this function to seed a pseudo-random + ;; number generator, rather than to provide the random data directly. + (func (export "random_get") + ;; The buffer to fill with random data. + (param $buf data) + (result $error $errno_t) + ) + + ;; Receive a message from a socket. + ;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;; the data into multiple buffers in the manner of `readv`. + (func (export "sock_recv") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_t_array) + ;; Message flags. + (param $ri_flags $riflags_t) + (result $error $errno_t) + ;; Number of bytes stored in ri_data. + (result $ro_datalen $size_t) + ;; Message flags. + (result $ro_flags $roflags_t) + ) + + ;; Send a message on a socket. + ;; Note: This is similar to `send` in POSIX, though it also supports writing + ;; the data from multiple buffers in the manner of `writev`. + (func (export "sock_send") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_t_array) + ;; Message flags. + (param $si_flags $siflags_t) + (result $error $errno_t) + ;; Number of bytes transmitted. + (result $so_datalen $size_t) + ) + + ;; Shut down socket send and receive channels. + ;; Note: This is similar to `shutdown` in POSIX. + (func (export "sock_shutdown") + (param $self $fd_t) + ;; Which channels on the socket to shut down. + (param $how $sdflags_t) + (result $error $errno_t) + ) +) From 4670d849952b9104147e676a69f37a347d962d41 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 15:13:53 -0700 Subject: [PATCH 0088/1772] Update design/wasi_unstable/wasi_unstable.wati Co-Authored-By: Stefan Junker --- proposals/clocks/design/wasi_unstable/wasi_unstable.wati | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati index 1dd067917..42c6ba880 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati @@ -198,7 +198,7 @@ ;; The right to invoke __wasi_fd_datasync(). ;; ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke - ;` __wasi_path_open() with __WASI_FDFLAG_DSYNC. + ;; __wasi_path_open() with __WASI_FDFLAG_DSYNC. (flag $RIGHT_FD_DATASYNC) ;; The right to invoke __wasi_fd_read() and __wasi_sock_recv(). ;; From 155d52383ea8829cb340a3e86b56ed4dafc1ed1b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 15:13:53 -0700 Subject: [PATCH 0089/1772] Update design/wasi_unstable/wasi_unstable.wati Co-Authored-By: Stefan Junker --- proposals/random/design/wasi_unstable/wasi_unstable.wati | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.wati b/proposals/random/design/wasi_unstable/wasi_unstable.wati index 1dd067917..42c6ba880 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/random/design/wasi_unstable/wasi_unstable.wati @@ -198,7 +198,7 @@ ;; The right to invoke __wasi_fd_datasync(). ;; ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke - ;` __wasi_path_open() with __WASI_FDFLAG_DSYNC. + ;; __wasi_path_open() with __WASI_FDFLAG_DSYNC. (flag $RIGHT_FD_DATASYNC) ;; The right to invoke __wasi_fd_read() and __wasi_sock_recv(). ;; From 349aa3130d587bb322d6e022d30a58bab58004f9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 15:13:53 -0700 Subject: [PATCH 0090/1772] Update design/wasi_unstable/wasi_unstable.wati Co-Authored-By: Stefan Junker --- proposals/filesystem/design/wasi_unstable/wasi_unstable.wati | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati index 1dd067917..42c6ba880 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati @@ -198,7 +198,7 @@ ;; The right to invoke __wasi_fd_datasync(). ;; ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke - ;` __wasi_path_open() with __WASI_FDFLAG_DSYNC. + ;; __wasi_path_open() with __WASI_FDFLAG_DSYNC. (flag $RIGHT_FD_DATASYNC) ;; The right to invoke __wasi_fd_read() and __wasi_sock_recv(). ;; From b071b6e003328bba018a8fa3edb3955d53038c02 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 10:40:46 -0700 Subject: [PATCH 0091/1772] Give types to iovec_t/ciovec_t's fields. This replaces the "data" type. It'll be desirable to use higher-level types to describe what iovec/ciovec do, however to avoid getting into IDL design questions, for now just use explicit pointer and length values to keep things simple. --- proposals/clocks/design/wasi_unstable/wasi_unstable.wati | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati index 42c6ba880..448c15052 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati @@ -3,6 +3,7 @@ ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). (typename $size_t u32) +(typename $uintptr_t u32) (typename $string_array (array string)) ;; Non-negative file size or length of a region within a file. @@ -280,8 +281,8 @@ (typename $iovec_t (struct ;; The address and length of the buffer to be filled. - (field $buf data) - (field $buf_len data) + (field $buf $uintptr_t) + (field $buf_len $size_t) ) ) @@ -289,8 +290,8 @@ (typename $ciovec_t (struct ;; The address and length of the buffer to be written. - (field $buf data) - (field $buf_len data) + (field $buf $uintptr_t) + (field $buf_len $size_t) ) ) From 71c4211688a2db8cd250073b9fe8c4307a320f09 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 10:40:46 -0700 Subject: [PATCH 0092/1772] Give types to iovec_t/ciovec_t's fields. This replaces the "data" type. It'll be desirable to use higher-level types to describe what iovec/ciovec do, however to avoid getting into IDL design questions, for now just use explicit pointer and length values to keep things simple. --- proposals/random/design/wasi_unstable/wasi_unstable.wati | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.wati b/proposals/random/design/wasi_unstable/wasi_unstable.wati index 42c6ba880..448c15052 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/random/design/wasi_unstable/wasi_unstable.wati @@ -3,6 +3,7 @@ ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). (typename $size_t u32) +(typename $uintptr_t u32) (typename $string_array (array string)) ;; Non-negative file size or length of a region within a file. @@ -280,8 +281,8 @@ (typename $iovec_t (struct ;; The address and length of the buffer to be filled. - (field $buf data) - (field $buf_len data) + (field $buf $uintptr_t) + (field $buf_len $size_t) ) ) @@ -289,8 +290,8 @@ (typename $ciovec_t (struct ;; The address and length of the buffer to be written. - (field $buf data) - (field $buf_len data) + (field $buf $uintptr_t) + (field $buf_len $size_t) ) ) From 27e17f37ae620bf85a4d54c468013111121265d1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 10:40:46 -0700 Subject: [PATCH 0093/1772] Give types to iovec_t/ciovec_t's fields. This replaces the "data" type. It'll be desirable to use higher-level types to describe what iovec/ciovec do, however to avoid getting into IDL design questions, for now just use explicit pointer and length values to keep things simple. --- .../filesystem/design/wasi_unstable/wasi_unstable.wati | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati index 42c6ba880..448c15052 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati @@ -3,6 +3,7 @@ ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). (typename $size_t u32) +(typename $uintptr_t u32) (typename $string_array (array string)) ;; Non-negative file size or length of a region within a file. @@ -280,8 +281,8 @@ (typename $iovec_t (struct ;; The address and length of the buffer to be filled. - (field $buf data) - (field $buf_len data) + (field $buf $uintptr_t) + (field $buf_len $size_t) ) ) @@ -289,8 +290,8 @@ (typename $ciovec_t (struct ;; The address and length of the buffer to be written. - (field $buf data) - (field $buf_len data) + (field $buf $uintptr_t) + (field $buf_len $size_t) ) ) From 3334866fc0cb7b572f6f1d33af56ecf6f22098e0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 10:55:24 -0700 Subject: [PATCH 0094/1772] Code-quote more things. --- .../design/wasi_unstable/wasi_unstable.wati | 112 +++++++++--------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati index 448c15052..d0ee446f0 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati @@ -196,82 +196,82 @@ ;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke __wasi_fd_datasync(). + ;; The right to invoke `__wasi_fd_datasync()`. ;; - ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke - ;; __wasi_path_open() with __WASI_FDFLAG_DSYNC. + ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `__wasi_path_open()` with `__WASI_FDFLAG_DSYNC`. (flag $RIGHT_FD_DATASYNC) - ;; The right to invoke __wasi_fd_read() and __wasi_sock_recv(). + ;; The right to invoke `__wasi_fd_read()` and `__wasi_sock_recv()`. ;; - ;; If __WASI_RIGHT_FD_SEEK is set, includes the right to invoke - ;; __wasi_fd_pread(). + ;; If `__WASI_RIGHT_FD_SEEK` is set, includes the right to invoke + ;; `__wasi_fd_pread()`. (flag $RIGHT_FD_READ) - ;; The right to invoke __wasi_fd_seek(). This flag implies __WASI_RIGHT_FD_TELL. + ;; The right to invoke `__wasi_fd_seek()`. This flag implies `__WASI_RIGHT_FD_TELL`. (flag $RIGHT_FD_SEEK) - ;; The right to invoke __wasi_fd_fdstat_set_flags(). + ;; The right to invoke `__wasi_fd_fdstat_set_flags()`. (flag $RIGHT_FD_FDSTAT_SET_FLAGS) - ;; The right to invoke __wasi_fd_sync(). + ;; The right to invoke `__wasi_fd_sync()`. ;; - ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke - ;; __wasi_path_open() with __WASI_FDFLAG_RSYNC and __WASI_FDFLAG_DSYNC. + ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `__wasi_path_open()` with `__WASI_FDFLAG_RSYNC` and `__WASI_FDFLAG_DSYNC`. (flag $RIGHT_FD_SYNC) - ;; The right to invoke __wasi_fd_seek() in such a way that the file offset - ;; remains unaltered (i.e., __WASI_WHENCE_CUR with offset zero), or to - ;; invoke __wasi_fd_tell(). + ;; The right to invoke `__wasi_fd_seek()` in such a way that the file offset + ;; remains unaltered (i.e., `__WASI_WHENCE_CUR` with offset zero), or to + ;; invoke `__wasi_fd_tell()`. (flag $RIGHT_FD_TELL) - ;; The right to invoke __wasi_fd_write() and __wasi_sock_send(). - ;; If __WASI_RIGHT_FD_SEEK is set, includes the right to invoke __wasi_fd_pwrite(). + ;; The right to invoke `__wasi_fd_write()` and `__wasi_sock_send()`. + ;; If `__WASI_RIGHT_FD_SEEK` is set, includes the right to invoke `__wasi_fd_pwrite()`. (flag $RIGHT_FD_WRITE) - ;; The right to invoke __wasi_fd_advise(). + ;; The right to invoke `__wasi_fd_advise()`. (flag $RIGHT_FD_ADVISE) - ;; The right to invoke __wasi_fd_allocate(). + ;; The right to invoke `__wasi_fd_allocate()`. (flag $RIGHT_FD_ALLOCATE) - ;; The right to invoke __wasi_path_create_directory(). + ;; The right to invoke `__wasi_path_create_directory()`. (flag $RIGHT_PATH_CREATE_DIRECTORY) - ;; If __WASI_RIGHT_PATH_OPEN is set, the right to invoke __wasi_path_open() with __WASI_O_CREAT. + ;; If `__WASI_RIGHT_PATH_OPEN` is set, the right to invoke `__wasi_path_open()` with `__WASI_O_CREAT`. (flag $RIGHT_PATH_CREATE_FILE) - ;; The right to invoke __wasi_path_link() with the file descriptor as the source directory. + ;; The right to invoke `__wasi_path_link()` with the file descriptor as the source directory. (flag $RIGHT_PATH_LINK_SOURCE) - ;; The right to invoke __wasi_path_link() with the file descriptor as the target directory. + ;; The right to invoke `__wasi_path_link()` with the file descriptor as the target directory. (flag $RIGHT_PATH_LINK_TARGET) - ;; The right to invoke __wasi_path_open(). + ;; The right to invoke `__wasi_path_open()`. (flag $RIGHT_PATH_OPEN) - ;; The right to invoke __wasi_fd_readdir(). + ;; The right to invoke `__wasi_fd_readdir()`. (flag $RIGHT_FD_READDIR) - ;; The right to invoke __wasi_path_readlink(). + ;; The right to invoke `__wasi_path_readlink()`. (flag $RIGHT_PATH_READLINK) - ;; The right to invoke __wasi_path_rename() with the file descriptor as the source directory. + ;; The right to invoke `__wasi_path_rename()` with the file descriptor as the source directory. (flag $RIGHT_PATH_RENAME_SOURCE) - ;; The right to invoke __wasi_path_rename() with the file descriptor as the target directory. + ;; The right to invoke `__wasi_path_rename()` with the file descriptor as the target directory. (flag $RIGHT_PATH_RENAME_TARGET) - ;; The right to invoke __wasi_path_filestat_get(). + ;; The right to invoke `__wasi_path_filestat_get()`. (flag $RIGHT_PATH_FILESTAT_GET) - ;; The right to change a file's size (there is no __wasi_path_filestat_set_size()). - ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke __wasi_path_open() with __WASI_O_TRUNC. + ;; The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). + ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke `__wasi_path_open()` with `__WASI_O_TRUNC`. (flag $RIGHT_PATH_FILESTAT_SET_SIZE) - ;; The right to invoke __wasi_path_filestat_set_times(). + ;; The right to invoke `__wasi_path_filestat_set_times()`. (flag $RIGHT_PATH_FILESTAT_SET_TIMES) - ;; The right to invoke __wasi_fd_filestat_get(). + ;; The right to invoke `__wasi_fd_filestat_get()`. (flag $RIGHT_FD_FILESTAT_GET) - ;; The right to invoke __wasi_fd_filestat_set_size(). + ;; The right to invoke `__wasi_fd_filestat_set_size()`. (flag $RIGHT_FD_FILESTAT_SET_SIZE) - ;; The right to invoke __wasi_fd_filestat_set_times(). + ;; The right to invoke `__wasi_fd_filestat_set_times()`. (flag $RIGHT_FD_FILESTAT_SET_TIMES) - ;; The right to invoke __wasi_path_symlink(). + ;; The right to invoke `__wasi_path_symlink()`. (flag $RIGHT_PATH_SYMLINK) - ;; The right to invoke __wasi_path_unlink_file(). + ;; The right to invoke `__wasi_path_unlink_file()`. (flag $RIGHT_PATH_UNLINK_FILE) - ;; The right to invoke __wasi_path_remove_directory(). + ;; The right to invoke `__wasi_path_remove_directory()`. (flag $RIGHT_PATH_REMOVE_DIRECTORY) - ;; If __WASI_RIGHT_FD_READ is set, includes the right to invoke __wasi_poll_oneoff() to subscribe to __WASI_EVENTTYPE_FD_READ. - ;; If __WASI_RIGHT_FD_WRITE is set, includes the right to invoke __wasi_poll_oneoff() to subscribe to __WASI_EVENTTYPE_FD_WRITE. + ;; If `__WASI_RIGHT_FD_READ` is set, includes the right to invoke `__wasi_poll_oneoff()` to subscribe to `__WASI_EVENTTYPE_FD_READ`. + ;; If `__WASI_RIGHT_FD_WRITE` is set, includes the right to invoke `__wasi_poll_oneoff()` to subscribe to `__WASI_EVENTTYPE_FD_WRITE`. (flag $RIGHT_POLL_FD_READWRITE) - ;; The right to invoke __wasi_sock_shutdown(). + ;; The right to invoke `__wasi_sock_shutdown()`. (flag $RIGHT_SOCK_SHUTDOWN) ) ) -;; a file descriptor index +;; A file descriptor index. (typename $fd_t u32) (typename $iovec_t_array (array $iovec_t)) @@ -377,7 +377,7 @@ (field $fs_rights_base $rights_t) ;; Maximum set of rights that may be installed on new file descriptors that ;; are created through this file descriptor, e.g., through - ;; __wasi_path_open(). + ;; `__wasi_path_open()`. (field $fs_rights_inheriting $rights_t) ) ) @@ -414,11 +414,11 @@ (flags u16 ;; Adjust the last data access timestamp to the value stored in __wasi_filestat_t::st_atim. (flag $FILESTAT_SET_ATIM) - ;; Adjust the last data access timestamp to the time of clock __WASI_CLOCK_REALTIME. + ;; Adjust the last data access timestamp to the time of clock `__WASI_CLOCK_REALTIME`. (flag $FILESTAT_SET_ATIM_NOW) ;; Adjust the last data modification timestamp to the value stored in __wasi_filestat_t::st_mtim. (flag $FILESTAT_SET_MTIM) - ;; Adjust the last data modification timestamp to the time of clock __WASI_CLOCK_REALTIME. + ;; Adjust the last data modification timestamp to the time of clock `__WASI_CLOCK_REALTIME`. (flag $FILESTAT_SET_MTIM_NOW) ) ) @@ -434,7 +434,7 @@ ) ) -;; Open flags used by __wasi_path_open(). +;; Open flags used by `__wasi_path_open()`. (typename $oflags_t (flags u16 ;; Create file if it does not exist. @@ -487,7 +487,7 @@ (field $type $eventtype_t) (field $u (typename union - ;; When type is __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE: + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: (field $fd_readwrite (typename stuct ;; The number of bytes available for reading or writing. @@ -502,7 +502,7 @@ ) ) -;; The state of the file descriptor subscribed to with __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE. +;; The state of the file descriptor subscribed to with `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. @@ -544,7 +544,7 @@ (field (type (union - ;; When type is __WASI_EVENTTYPE_CLOCK + ;; When type is `__WASI_EVENTTYPE_CLOCK`: (field $clock (typename (struct @@ -560,7 +560,7 @@ ) ) ) - ;; When type is __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE: + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: (field $fd_readwrite (type (struct @@ -662,7 +662,7 @@ ) ) -;; Flags provided to __wasi_sock_recv(). +;; Flags provided to `__wasi_sock_recv()`. (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. @@ -672,15 +672,15 @@ ) ) -;; Flags returned by __wasi_sock_recv(). +;; Flags returned by `__wasi_sock_recv()`. (typename $roflags_t (flags u16 - ;; Returned by __wasi_sock_recv(): Message data has been truncated. + ;; Returned by `__wasi_sock_recv()`: Message data has been truncated. (flag $SOCK_RECV_DATA_TRUNCATED) ) ) -;; Flags provided to __wasi_sock_send(). As there are currently no flags defined, it must be set to zero. +;; Flags provided to `__wasi_sock_send()`. As there are currently no flags defined, it must be set to zero. (typename $siflags_t u16) ;; Which channels on a socket to shut down. @@ -925,8 +925,8 @@ ) ;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary number, like dup2(). This would be prone to race conditions, as an actual file descriptor with the same number could be allocated by a different thread at the same time. - ;; This function provides a way to atomically renumber file descriptors, which would disappear if dup2() were to be removed entirely. + ;; Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary number, like `dup2()`. This would be prone to race conditions, as an actual file descriptor with the same number could be allocated by a different thread at the same time. + ;; This function provides a way to atomically renumber file descriptors, which would disappear if `dup2()` were to be removed entirely. (func (export "fd_renumber") (param $self $fd_t) ;; The file descriptor to overwrite. @@ -1110,7 +1110,7 @@ ;; Unlink a file. - ;; Return __WASI_EISDIR if the path refers to a directory. + ;; Return `__WASI_EISDIR` if the path refers to a directory. ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (func (export "path_unlink_file") (param $self $fd_t) From bfef62478a17c8ccf80f063375da63abe7a28ecc Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 10:55:24 -0700 Subject: [PATCH 0095/1772] Code-quote more things. --- .../design/wasi_unstable/wasi_unstable.wati | 112 +++++++++--------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.wati b/proposals/random/design/wasi_unstable/wasi_unstable.wati index 448c15052..d0ee446f0 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/random/design/wasi_unstable/wasi_unstable.wati @@ -196,82 +196,82 @@ ;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke __wasi_fd_datasync(). + ;; The right to invoke `__wasi_fd_datasync()`. ;; - ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke - ;; __wasi_path_open() with __WASI_FDFLAG_DSYNC. + ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `__wasi_path_open()` with `__WASI_FDFLAG_DSYNC`. (flag $RIGHT_FD_DATASYNC) - ;; The right to invoke __wasi_fd_read() and __wasi_sock_recv(). + ;; The right to invoke `__wasi_fd_read()` and `__wasi_sock_recv()`. ;; - ;; If __WASI_RIGHT_FD_SEEK is set, includes the right to invoke - ;; __wasi_fd_pread(). + ;; If `__WASI_RIGHT_FD_SEEK` is set, includes the right to invoke + ;; `__wasi_fd_pread()`. (flag $RIGHT_FD_READ) - ;; The right to invoke __wasi_fd_seek(). This flag implies __WASI_RIGHT_FD_TELL. + ;; The right to invoke `__wasi_fd_seek()`. This flag implies `__WASI_RIGHT_FD_TELL`. (flag $RIGHT_FD_SEEK) - ;; The right to invoke __wasi_fd_fdstat_set_flags(). + ;; The right to invoke `__wasi_fd_fdstat_set_flags()`. (flag $RIGHT_FD_FDSTAT_SET_FLAGS) - ;; The right to invoke __wasi_fd_sync(). + ;; The right to invoke `__wasi_fd_sync()`. ;; - ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke - ;; __wasi_path_open() with __WASI_FDFLAG_RSYNC and __WASI_FDFLAG_DSYNC. + ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `__wasi_path_open()` with `__WASI_FDFLAG_RSYNC` and `__WASI_FDFLAG_DSYNC`. (flag $RIGHT_FD_SYNC) - ;; The right to invoke __wasi_fd_seek() in such a way that the file offset - ;; remains unaltered (i.e., __WASI_WHENCE_CUR with offset zero), or to - ;; invoke __wasi_fd_tell(). + ;; The right to invoke `__wasi_fd_seek()` in such a way that the file offset + ;; remains unaltered (i.e., `__WASI_WHENCE_CUR` with offset zero), or to + ;; invoke `__wasi_fd_tell()`. (flag $RIGHT_FD_TELL) - ;; The right to invoke __wasi_fd_write() and __wasi_sock_send(). - ;; If __WASI_RIGHT_FD_SEEK is set, includes the right to invoke __wasi_fd_pwrite(). + ;; The right to invoke `__wasi_fd_write()` and `__wasi_sock_send()`. + ;; If `__WASI_RIGHT_FD_SEEK` is set, includes the right to invoke `__wasi_fd_pwrite()`. (flag $RIGHT_FD_WRITE) - ;; The right to invoke __wasi_fd_advise(). + ;; The right to invoke `__wasi_fd_advise()`. (flag $RIGHT_FD_ADVISE) - ;; The right to invoke __wasi_fd_allocate(). + ;; The right to invoke `__wasi_fd_allocate()`. (flag $RIGHT_FD_ALLOCATE) - ;; The right to invoke __wasi_path_create_directory(). + ;; The right to invoke `__wasi_path_create_directory()`. (flag $RIGHT_PATH_CREATE_DIRECTORY) - ;; If __WASI_RIGHT_PATH_OPEN is set, the right to invoke __wasi_path_open() with __WASI_O_CREAT. + ;; If `__WASI_RIGHT_PATH_OPEN` is set, the right to invoke `__wasi_path_open()` with `__WASI_O_CREAT`. (flag $RIGHT_PATH_CREATE_FILE) - ;; The right to invoke __wasi_path_link() with the file descriptor as the source directory. + ;; The right to invoke `__wasi_path_link()` with the file descriptor as the source directory. (flag $RIGHT_PATH_LINK_SOURCE) - ;; The right to invoke __wasi_path_link() with the file descriptor as the target directory. + ;; The right to invoke `__wasi_path_link()` with the file descriptor as the target directory. (flag $RIGHT_PATH_LINK_TARGET) - ;; The right to invoke __wasi_path_open(). + ;; The right to invoke `__wasi_path_open()`. (flag $RIGHT_PATH_OPEN) - ;; The right to invoke __wasi_fd_readdir(). + ;; The right to invoke `__wasi_fd_readdir()`. (flag $RIGHT_FD_READDIR) - ;; The right to invoke __wasi_path_readlink(). + ;; The right to invoke `__wasi_path_readlink()`. (flag $RIGHT_PATH_READLINK) - ;; The right to invoke __wasi_path_rename() with the file descriptor as the source directory. + ;; The right to invoke `__wasi_path_rename()` with the file descriptor as the source directory. (flag $RIGHT_PATH_RENAME_SOURCE) - ;; The right to invoke __wasi_path_rename() with the file descriptor as the target directory. + ;; The right to invoke `__wasi_path_rename()` with the file descriptor as the target directory. (flag $RIGHT_PATH_RENAME_TARGET) - ;; The right to invoke __wasi_path_filestat_get(). + ;; The right to invoke `__wasi_path_filestat_get()`. (flag $RIGHT_PATH_FILESTAT_GET) - ;; The right to change a file's size (there is no __wasi_path_filestat_set_size()). - ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke __wasi_path_open() with __WASI_O_TRUNC. + ;; The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). + ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke `__wasi_path_open()` with `__WASI_O_TRUNC`. (flag $RIGHT_PATH_FILESTAT_SET_SIZE) - ;; The right to invoke __wasi_path_filestat_set_times(). + ;; The right to invoke `__wasi_path_filestat_set_times()`. (flag $RIGHT_PATH_FILESTAT_SET_TIMES) - ;; The right to invoke __wasi_fd_filestat_get(). + ;; The right to invoke `__wasi_fd_filestat_get()`. (flag $RIGHT_FD_FILESTAT_GET) - ;; The right to invoke __wasi_fd_filestat_set_size(). + ;; The right to invoke `__wasi_fd_filestat_set_size()`. (flag $RIGHT_FD_FILESTAT_SET_SIZE) - ;; The right to invoke __wasi_fd_filestat_set_times(). + ;; The right to invoke `__wasi_fd_filestat_set_times()`. (flag $RIGHT_FD_FILESTAT_SET_TIMES) - ;; The right to invoke __wasi_path_symlink(). + ;; The right to invoke `__wasi_path_symlink()`. (flag $RIGHT_PATH_SYMLINK) - ;; The right to invoke __wasi_path_unlink_file(). + ;; The right to invoke `__wasi_path_unlink_file()`. (flag $RIGHT_PATH_UNLINK_FILE) - ;; The right to invoke __wasi_path_remove_directory(). + ;; The right to invoke `__wasi_path_remove_directory()`. (flag $RIGHT_PATH_REMOVE_DIRECTORY) - ;; If __WASI_RIGHT_FD_READ is set, includes the right to invoke __wasi_poll_oneoff() to subscribe to __WASI_EVENTTYPE_FD_READ. - ;; If __WASI_RIGHT_FD_WRITE is set, includes the right to invoke __wasi_poll_oneoff() to subscribe to __WASI_EVENTTYPE_FD_WRITE. + ;; If `__WASI_RIGHT_FD_READ` is set, includes the right to invoke `__wasi_poll_oneoff()` to subscribe to `__WASI_EVENTTYPE_FD_READ`. + ;; If `__WASI_RIGHT_FD_WRITE` is set, includes the right to invoke `__wasi_poll_oneoff()` to subscribe to `__WASI_EVENTTYPE_FD_WRITE`. (flag $RIGHT_POLL_FD_READWRITE) - ;; The right to invoke __wasi_sock_shutdown(). + ;; The right to invoke `__wasi_sock_shutdown()`. (flag $RIGHT_SOCK_SHUTDOWN) ) ) -;; a file descriptor index +;; A file descriptor index. (typename $fd_t u32) (typename $iovec_t_array (array $iovec_t)) @@ -377,7 +377,7 @@ (field $fs_rights_base $rights_t) ;; Maximum set of rights that may be installed on new file descriptors that ;; are created through this file descriptor, e.g., through - ;; __wasi_path_open(). + ;; `__wasi_path_open()`. (field $fs_rights_inheriting $rights_t) ) ) @@ -414,11 +414,11 @@ (flags u16 ;; Adjust the last data access timestamp to the value stored in __wasi_filestat_t::st_atim. (flag $FILESTAT_SET_ATIM) - ;; Adjust the last data access timestamp to the time of clock __WASI_CLOCK_REALTIME. + ;; Adjust the last data access timestamp to the time of clock `__WASI_CLOCK_REALTIME`. (flag $FILESTAT_SET_ATIM_NOW) ;; Adjust the last data modification timestamp to the value stored in __wasi_filestat_t::st_mtim. (flag $FILESTAT_SET_MTIM) - ;; Adjust the last data modification timestamp to the time of clock __WASI_CLOCK_REALTIME. + ;; Adjust the last data modification timestamp to the time of clock `__WASI_CLOCK_REALTIME`. (flag $FILESTAT_SET_MTIM_NOW) ) ) @@ -434,7 +434,7 @@ ) ) -;; Open flags used by __wasi_path_open(). +;; Open flags used by `__wasi_path_open()`. (typename $oflags_t (flags u16 ;; Create file if it does not exist. @@ -487,7 +487,7 @@ (field $type $eventtype_t) (field $u (typename union - ;; When type is __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE: + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: (field $fd_readwrite (typename stuct ;; The number of bytes available for reading or writing. @@ -502,7 +502,7 @@ ) ) -;; The state of the file descriptor subscribed to with __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE. +;; The state of the file descriptor subscribed to with `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. @@ -544,7 +544,7 @@ (field (type (union - ;; When type is __WASI_EVENTTYPE_CLOCK + ;; When type is `__WASI_EVENTTYPE_CLOCK`: (field $clock (typename (struct @@ -560,7 +560,7 @@ ) ) ) - ;; When type is __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE: + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: (field $fd_readwrite (type (struct @@ -662,7 +662,7 @@ ) ) -;; Flags provided to __wasi_sock_recv(). +;; Flags provided to `__wasi_sock_recv()`. (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. @@ -672,15 +672,15 @@ ) ) -;; Flags returned by __wasi_sock_recv(). +;; Flags returned by `__wasi_sock_recv()`. (typename $roflags_t (flags u16 - ;; Returned by __wasi_sock_recv(): Message data has been truncated. + ;; Returned by `__wasi_sock_recv()`: Message data has been truncated. (flag $SOCK_RECV_DATA_TRUNCATED) ) ) -;; Flags provided to __wasi_sock_send(). As there are currently no flags defined, it must be set to zero. +;; Flags provided to `__wasi_sock_send()`. As there are currently no flags defined, it must be set to zero. (typename $siflags_t u16) ;; Which channels on a socket to shut down. @@ -925,8 +925,8 @@ ) ;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary number, like dup2(). This would be prone to race conditions, as an actual file descriptor with the same number could be allocated by a different thread at the same time. - ;; This function provides a way to atomically renumber file descriptors, which would disappear if dup2() were to be removed entirely. + ;; Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary number, like `dup2()`. This would be prone to race conditions, as an actual file descriptor with the same number could be allocated by a different thread at the same time. + ;; This function provides a way to atomically renumber file descriptors, which would disappear if `dup2()` were to be removed entirely. (func (export "fd_renumber") (param $self $fd_t) ;; The file descriptor to overwrite. @@ -1110,7 +1110,7 @@ ;; Unlink a file. - ;; Return __WASI_EISDIR if the path refers to a directory. + ;; Return `__WASI_EISDIR` if the path refers to a directory. ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (func (export "path_unlink_file") (param $self $fd_t) From 0df64e0a6e737a034e710f1a3c6e1ef1e8c8f21b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 10:55:24 -0700 Subject: [PATCH 0096/1772] Code-quote more things. --- .../design/wasi_unstable/wasi_unstable.wati | 112 +++++++++--------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati index 448c15052..d0ee446f0 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati @@ -196,82 +196,82 @@ ;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke __wasi_fd_datasync(). + ;; The right to invoke `__wasi_fd_datasync()`. ;; - ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke - ;; __wasi_path_open() with __WASI_FDFLAG_DSYNC. + ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `__wasi_path_open()` with `__WASI_FDFLAG_DSYNC`. (flag $RIGHT_FD_DATASYNC) - ;; The right to invoke __wasi_fd_read() and __wasi_sock_recv(). + ;; The right to invoke `__wasi_fd_read()` and `__wasi_sock_recv()`. ;; - ;; If __WASI_RIGHT_FD_SEEK is set, includes the right to invoke - ;; __wasi_fd_pread(). + ;; If `__WASI_RIGHT_FD_SEEK` is set, includes the right to invoke + ;; `__wasi_fd_pread()`. (flag $RIGHT_FD_READ) - ;; The right to invoke __wasi_fd_seek(). This flag implies __WASI_RIGHT_FD_TELL. + ;; The right to invoke `__wasi_fd_seek()`. This flag implies `__WASI_RIGHT_FD_TELL`. (flag $RIGHT_FD_SEEK) - ;; The right to invoke __wasi_fd_fdstat_set_flags(). + ;; The right to invoke `__wasi_fd_fdstat_set_flags()`. (flag $RIGHT_FD_FDSTAT_SET_FLAGS) - ;; The right to invoke __wasi_fd_sync(). + ;; The right to invoke `__wasi_fd_sync()`. ;; - ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke - ;; __wasi_path_open() with __WASI_FDFLAG_RSYNC and __WASI_FDFLAG_DSYNC. + ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `__wasi_path_open()` with `__WASI_FDFLAG_RSYNC` and `__WASI_FDFLAG_DSYNC`. (flag $RIGHT_FD_SYNC) - ;; The right to invoke __wasi_fd_seek() in such a way that the file offset - ;; remains unaltered (i.e., __WASI_WHENCE_CUR with offset zero), or to - ;; invoke __wasi_fd_tell(). + ;; The right to invoke `__wasi_fd_seek()` in such a way that the file offset + ;; remains unaltered (i.e., `__WASI_WHENCE_CUR` with offset zero), or to + ;; invoke `__wasi_fd_tell()`. (flag $RIGHT_FD_TELL) - ;; The right to invoke __wasi_fd_write() and __wasi_sock_send(). - ;; If __WASI_RIGHT_FD_SEEK is set, includes the right to invoke __wasi_fd_pwrite(). + ;; The right to invoke `__wasi_fd_write()` and `__wasi_sock_send()`. + ;; If `__WASI_RIGHT_FD_SEEK` is set, includes the right to invoke `__wasi_fd_pwrite()`. (flag $RIGHT_FD_WRITE) - ;; The right to invoke __wasi_fd_advise(). + ;; The right to invoke `__wasi_fd_advise()`. (flag $RIGHT_FD_ADVISE) - ;; The right to invoke __wasi_fd_allocate(). + ;; The right to invoke `__wasi_fd_allocate()`. (flag $RIGHT_FD_ALLOCATE) - ;; The right to invoke __wasi_path_create_directory(). + ;; The right to invoke `__wasi_path_create_directory()`. (flag $RIGHT_PATH_CREATE_DIRECTORY) - ;; If __WASI_RIGHT_PATH_OPEN is set, the right to invoke __wasi_path_open() with __WASI_O_CREAT. + ;; If `__WASI_RIGHT_PATH_OPEN` is set, the right to invoke `__wasi_path_open()` with `__WASI_O_CREAT`. (flag $RIGHT_PATH_CREATE_FILE) - ;; The right to invoke __wasi_path_link() with the file descriptor as the source directory. + ;; The right to invoke `__wasi_path_link()` with the file descriptor as the source directory. (flag $RIGHT_PATH_LINK_SOURCE) - ;; The right to invoke __wasi_path_link() with the file descriptor as the target directory. + ;; The right to invoke `__wasi_path_link()` with the file descriptor as the target directory. (flag $RIGHT_PATH_LINK_TARGET) - ;; The right to invoke __wasi_path_open(). + ;; The right to invoke `__wasi_path_open()`. (flag $RIGHT_PATH_OPEN) - ;; The right to invoke __wasi_fd_readdir(). + ;; The right to invoke `__wasi_fd_readdir()`. (flag $RIGHT_FD_READDIR) - ;; The right to invoke __wasi_path_readlink(). + ;; The right to invoke `__wasi_path_readlink()`. (flag $RIGHT_PATH_READLINK) - ;; The right to invoke __wasi_path_rename() with the file descriptor as the source directory. + ;; The right to invoke `__wasi_path_rename()` with the file descriptor as the source directory. (flag $RIGHT_PATH_RENAME_SOURCE) - ;; The right to invoke __wasi_path_rename() with the file descriptor as the target directory. + ;; The right to invoke `__wasi_path_rename()` with the file descriptor as the target directory. (flag $RIGHT_PATH_RENAME_TARGET) - ;; The right to invoke __wasi_path_filestat_get(). + ;; The right to invoke `__wasi_path_filestat_get()`. (flag $RIGHT_PATH_FILESTAT_GET) - ;; The right to change a file's size (there is no __wasi_path_filestat_set_size()). - ;; If __WASI_RIGHT_PATH_OPEN is set, includes the right to invoke __wasi_path_open() with __WASI_O_TRUNC. + ;; The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). + ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke `__wasi_path_open()` with `__WASI_O_TRUNC`. (flag $RIGHT_PATH_FILESTAT_SET_SIZE) - ;; The right to invoke __wasi_path_filestat_set_times(). + ;; The right to invoke `__wasi_path_filestat_set_times()`. (flag $RIGHT_PATH_FILESTAT_SET_TIMES) - ;; The right to invoke __wasi_fd_filestat_get(). + ;; The right to invoke `__wasi_fd_filestat_get()`. (flag $RIGHT_FD_FILESTAT_GET) - ;; The right to invoke __wasi_fd_filestat_set_size(). + ;; The right to invoke `__wasi_fd_filestat_set_size()`. (flag $RIGHT_FD_FILESTAT_SET_SIZE) - ;; The right to invoke __wasi_fd_filestat_set_times(). + ;; The right to invoke `__wasi_fd_filestat_set_times()`. (flag $RIGHT_FD_FILESTAT_SET_TIMES) - ;; The right to invoke __wasi_path_symlink(). + ;; The right to invoke `__wasi_path_symlink()`. (flag $RIGHT_PATH_SYMLINK) - ;; The right to invoke __wasi_path_unlink_file(). + ;; The right to invoke `__wasi_path_unlink_file()`. (flag $RIGHT_PATH_UNLINK_FILE) - ;; The right to invoke __wasi_path_remove_directory(). + ;; The right to invoke `__wasi_path_remove_directory()`. (flag $RIGHT_PATH_REMOVE_DIRECTORY) - ;; If __WASI_RIGHT_FD_READ is set, includes the right to invoke __wasi_poll_oneoff() to subscribe to __WASI_EVENTTYPE_FD_READ. - ;; If __WASI_RIGHT_FD_WRITE is set, includes the right to invoke __wasi_poll_oneoff() to subscribe to __WASI_EVENTTYPE_FD_WRITE. + ;; If `__WASI_RIGHT_FD_READ` is set, includes the right to invoke `__wasi_poll_oneoff()` to subscribe to `__WASI_EVENTTYPE_FD_READ`. + ;; If `__WASI_RIGHT_FD_WRITE` is set, includes the right to invoke `__wasi_poll_oneoff()` to subscribe to `__WASI_EVENTTYPE_FD_WRITE`. (flag $RIGHT_POLL_FD_READWRITE) - ;; The right to invoke __wasi_sock_shutdown(). + ;; The right to invoke `__wasi_sock_shutdown()`. (flag $RIGHT_SOCK_SHUTDOWN) ) ) -;; a file descriptor index +;; A file descriptor index. (typename $fd_t u32) (typename $iovec_t_array (array $iovec_t)) @@ -377,7 +377,7 @@ (field $fs_rights_base $rights_t) ;; Maximum set of rights that may be installed on new file descriptors that ;; are created through this file descriptor, e.g., through - ;; __wasi_path_open(). + ;; `__wasi_path_open()`. (field $fs_rights_inheriting $rights_t) ) ) @@ -414,11 +414,11 @@ (flags u16 ;; Adjust the last data access timestamp to the value stored in __wasi_filestat_t::st_atim. (flag $FILESTAT_SET_ATIM) - ;; Adjust the last data access timestamp to the time of clock __WASI_CLOCK_REALTIME. + ;; Adjust the last data access timestamp to the time of clock `__WASI_CLOCK_REALTIME`. (flag $FILESTAT_SET_ATIM_NOW) ;; Adjust the last data modification timestamp to the value stored in __wasi_filestat_t::st_mtim. (flag $FILESTAT_SET_MTIM) - ;; Adjust the last data modification timestamp to the time of clock __WASI_CLOCK_REALTIME. + ;; Adjust the last data modification timestamp to the time of clock `__WASI_CLOCK_REALTIME`. (flag $FILESTAT_SET_MTIM_NOW) ) ) @@ -434,7 +434,7 @@ ) ) -;; Open flags used by __wasi_path_open(). +;; Open flags used by `__wasi_path_open()`. (typename $oflags_t (flags u16 ;; Create file if it does not exist. @@ -487,7 +487,7 @@ (field $type $eventtype_t) (field $u (typename union - ;; When type is __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE: + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: (field $fd_readwrite (typename stuct ;; The number of bytes available for reading or writing. @@ -502,7 +502,7 @@ ) ) -;; The state of the file descriptor subscribed to with __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE. +;; The state of the file descriptor subscribed to with `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. @@ -544,7 +544,7 @@ (field (type (union - ;; When type is __WASI_EVENTTYPE_CLOCK + ;; When type is `__WASI_EVENTTYPE_CLOCK`: (field $clock (typename (struct @@ -560,7 +560,7 @@ ) ) ) - ;; When type is __WASI_EVENTTYPE_FD_READ or __WASI_EVENTTYPE_FD_WRITE: + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: (field $fd_readwrite (type (struct @@ -662,7 +662,7 @@ ) ) -;; Flags provided to __wasi_sock_recv(). +;; Flags provided to `__wasi_sock_recv()`. (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. @@ -672,15 +672,15 @@ ) ) -;; Flags returned by __wasi_sock_recv(). +;; Flags returned by `__wasi_sock_recv()`. (typename $roflags_t (flags u16 - ;; Returned by __wasi_sock_recv(): Message data has been truncated. + ;; Returned by `__wasi_sock_recv()`: Message data has been truncated. (flag $SOCK_RECV_DATA_TRUNCATED) ) ) -;; Flags provided to __wasi_sock_send(). As there are currently no flags defined, it must be set to zero. +;; Flags provided to `__wasi_sock_send()`. As there are currently no flags defined, it must be set to zero. (typename $siflags_t u16) ;; Which channels on a socket to shut down. @@ -925,8 +925,8 @@ ) ;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary number, like dup2(). This would be prone to race conditions, as an actual file descriptor with the same number could be allocated by a different thread at the same time. - ;; This function provides a way to atomically renumber file descriptors, which would disappear if dup2() were to be removed entirely. + ;; Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary number, like `dup2()`. This would be prone to race conditions, as an actual file descriptor with the same number could be allocated by a different thread at the same time. + ;; This function provides a way to atomically renumber file descriptors, which would disappear if `dup2()` were to be removed entirely. (func (export "fd_renumber") (param $self $fd_t) ;; The file descriptor to overwrite. @@ -1110,7 +1110,7 @@ ;; Unlink a file. - ;; Return __WASI_EISDIR if the path refers to a directory. + ;; Return `__WASI_EISDIR` if the path refers to a directory. ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (func (export "path_unlink_file") (param $self $fd_t) From 710d284d7279314cb0288b337beb90a2e3b33168 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 10:57:25 -0700 Subject: [PATCH 0097/1772] Remove the $else field of a union. --- proposals/clocks/design/wasi_unstable/wasi_unstable.wati | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati index d0ee446f0..0570345c8 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati @@ -496,7 +496,6 @@ (field $flags $eventrwflags_t) ) ) - (field $else Null) ) ) ) From 2f8f8c93479c5f0e1dd385f5cb63cb229abf5ed6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 10:57:25 -0700 Subject: [PATCH 0098/1772] Remove the $else field of a union. --- proposals/random/design/wasi_unstable/wasi_unstable.wati | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.wati b/proposals/random/design/wasi_unstable/wasi_unstable.wati index d0ee446f0..0570345c8 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/random/design/wasi_unstable/wasi_unstable.wati @@ -496,7 +496,6 @@ (field $flags $eventrwflags_t) ) ) - (field $else Null) ) ) ) From fd5acd91e601597ee409fd5794dc7b6a22e53440 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 10:57:25 -0700 Subject: [PATCH 0099/1772] Remove the $else field of a union. --- proposals/filesystem/design/wasi_unstable/wasi_unstable.wati | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati index d0ee446f0..0570345c8 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati @@ -496,7 +496,6 @@ (field $flags $eventrwflags_t) ) ) - (field $else Null) ) ) ) From b76afbb4d491b00e89022a46b0b75498d54ad4a8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 10:59:09 -0700 Subject: [PATCH 0100/1772] Clean up a few more `(type ...)` and `(typename ...)` constructs. Only use `(typename ...)` to declare named types; don't use it for inline types. --- .../design/wasi_unstable/wasi_unstable.wati | 48 ++++++++----------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati index 0570345c8..438054823 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati @@ -486,10 +486,10 @@ ;; The type of the event that occurred. (field $type $eventtype_t) (field $u - (typename union + (union ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: (field $fd_readwrite - (typename stuct + (struct ;; The number of bytes available for reading or writing. (field $nbytes $filesize_t) ;; The state of the file descriptor. @@ -541,32 +541,26 @@ ;; The type of the event to which to subscribe. (field $type $eventtype_t) (field - (type - (union - ;; When type is `__WASI_EVENTTYPE_CLOCK`: - (field $clock - (typename - (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) - ;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. - (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally to coalesce with other events. - ;; Flags specifying whether the timeout is absolute or relative - (field $precision $timestamp_t) - ) - ) + (union + ;; When type is `__WASI_EVENTTYPE_CLOCK`: + (field $clock + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally to coalesce with other events. + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) ) - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (type - (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) - ) - ) + ) + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + (field $fd_readwrite + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) ) ) ) From 51c54446320f0edf97cfab5a7671e022a5b6cf77 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 10:59:09 -0700 Subject: [PATCH 0101/1772] Clean up a few more `(type ...)` and `(typename ...)` constructs. Only use `(typename ...)` to declare named types; don't use it for inline types. --- .../design/wasi_unstable/wasi_unstable.wati | 48 ++++++++----------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.wati b/proposals/random/design/wasi_unstable/wasi_unstable.wati index 0570345c8..438054823 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/random/design/wasi_unstable/wasi_unstable.wati @@ -486,10 +486,10 @@ ;; The type of the event that occurred. (field $type $eventtype_t) (field $u - (typename union + (union ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: (field $fd_readwrite - (typename stuct + (struct ;; The number of bytes available for reading or writing. (field $nbytes $filesize_t) ;; The state of the file descriptor. @@ -541,32 +541,26 @@ ;; The type of the event to which to subscribe. (field $type $eventtype_t) (field - (type - (union - ;; When type is `__WASI_EVENTTYPE_CLOCK`: - (field $clock - (typename - (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) - ;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. - (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally to coalesce with other events. - ;; Flags specifying whether the timeout is absolute or relative - (field $precision $timestamp_t) - ) - ) + (union + ;; When type is `__WASI_EVENTTYPE_CLOCK`: + (field $clock + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally to coalesce with other events. + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) ) - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (type - (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) - ) - ) + ) + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + (field $fd_readwrite + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) ) ) ) From 235baa9b35f97dbe532cbb0aa312512e49346569 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 10:59:09 -0700 Subject: [PATCH 0102/1772] Clean up a few more `(type ...)` and `(typename ...)` constructs. Only use `(typename ...)` to declare named types; don't use it for inline types. --- .../design/wasi_unstable/wasi_unstable.wati | 48 ++++++++----------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati index 0570345c8..438054823 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati @@ -486,10 +486,10 @@ ;; The type of the event that occurred. (field $type $eventtype_t) (field $u - (typename union + (union ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: (field $fd_readwrite - (typename stuct + (struct ;; The number of bytes available for reading or writing. (field $nbytes $filesize_t) ;; The state of the file descriptor. @@ -541,32 +541,26 @@ ;; The type of the event to which to subscribe. (field $type $eventtype_t) (field - (type - (union - ;; When type is `__WASI_EVENTTYPE_CLOCK`: - (field $clock - (typename - (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) - ;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. - (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally to coalesce with other events. - ;; Flags specifying whether the timeout is absolute or relative - (field $precision $timestamp_t) - ) - ) + (union + ;; When type is `__WASI_EVENTTYPE_CLOCK`: + (field $clock + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally to coalesce with other events. + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) ) - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (type - (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) - ) - ) + ) + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + (field $fd_readwrite + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) ) ) ) From 5bf68a8426a15caff3eb57f27171faa2e7bc89c0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 11:01:21 -0700 Subject: [PATCH 0103/1772] Wrap some long lines. --- .../design/wasi_unstable/wasi_unstable.wati | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati index 438054823..a2ba1e3e0 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati @@ -230,9 +230,11 @@ (flag $RIGHT_PATH_CREATE_DIRECTORY) ;; If `__WASI_RIGHT_PATH_OPEN` is set, the right to invoke `__wasi_path_open()` with `__WASI_O_CREAT`. (flag $RIGHT_PATH_CREATE_FILE) - ;; The right to invoke `__wasi_path_link()` with the file descriptor as the source directory. + ;; The right to invoke `__wasi_path_link()` with the file descriptor as the + ;; source directory. (flag $RIGHT_PATH_LINK_SOURCE) - ;; The right to invoke `__wasi_path_link()` with the file descriptor as the target directory. + ;; The right to invoke `__wasi_path_link()` with the file descriptor as the + ;; target directory. (flag $RIGHT_PATH_LINK_TARGET) ;; The right to invoke `__wasi_path_open()`. (flag $RIGHT_PATH_OPEN) @@ -473,7 +475,8 @@ ) ) -;; User-provided value that may be attached to objects that is retained when extracted from the implementation. +;; User-provided value that may be attached to objects that is retained when +;; extracted from the implementation. (typename $userdata_t u64) ;; An event that occurred. @@ -501,7 +504,8 @@ ) ) -;; The state of the file descriptor subscribed to with `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. +;; The state of the file descriptor subscribed to with +;; `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. @@ -512,16 +516,20 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (flags u8 - ;; The time value of clock __wasi_subscription_t::u.clock.clock_id has reached timestamp __wasi_subscription_t::u.clock.timeout. + ;; The time value of clock __wasi_subscription_t::u.clock.clock_id has + ;; reached timestamp __wasi_subscription_t::u.clock.timeout. (flag $EVENTTYPE_CLOCK) - ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has data available for reading. This event always triggers for regular files. + ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has data + ;; available for reading. This event always triggers for regular files. (flag $EVENTTYPE_FD_READ) - ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has capacity available for writing. This event always triggers for regular files. + ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has capacity + ;; available for writing. This event always triggers for regular files. (flag $EVENTTYPE_FD_WRITE) ) ) -;; Flags determining how to interpret the timestamp provided in __wasi_subscription_t::u.clock.timeout. +;; Flags determining how to interpret the timestamp provided in +;; __wasi_subscription_t::u.clock.timeout. (typename $subclockflags_t (flags u16 ;; If set, treat the timestamp provided in @@ -536,7 +544,8 @@ ;; Subscription to an event. (typename $subscription_t (struct - ;; User-provided value that is attached to the subscription in the implementation and returned through __wasi_event_t::userdata. + ;; User-provided value that is attached to the subscription in the + ;; implementation and returned through __wasi_event_t::userdata. (field $userdata $userdata_t) ;; The type of the event to which to subscribe. (field $type $eventtype_t) @@ -551,7 +560,9 @@ (field $clock_id $clockid_t) ;; The absolute or relative timestamp. (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally to coalesce with other events. + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; ;; Flags specifying whether the timeout is absolute or relative (field $precision $timestamp_t) ) @@ -673,7 +684,8 @@ ) ) -;; Flags provided to `__wasi_sock_send()`. As there are currently no flags defined, it must be set to zero. +;; Flags provided to `__wasi_sock_send()`. As there are currently no flags +;; defined, it must be set to zero. (typename $siflags_t u16) ;; Which channels on a socket to shut down. @@ -918,8 +930,15 @@ ) ;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary number, like `dup2()`. This would be prone to race conditions, as an actual file descriptor with the same number could be allocated by a different thread at the same time. - ;; This function provides a way to atomically renumber file descriptors, which would disappear if `dup2()` were to be removed entirely. + ;; + ;; Due to the strong focus on thread safety, this environment does not provide + ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;; file descriptor with the same number could be allocated by a different + ;; thread at the same time. + ;; + ;; This function provides a way to atomically renumber file descriptors, which + ;; would disappear if `dup2()` were to be removed entirely. (func (export "fd_renumber") (param $self $fd_t) ;; The file descriptor to overwrite. From 1aa2f24dc69f6851a9a44783f66c6b264b4369fa Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 11:01:21 -0700 Subject: [PATCH 0104/1772] Wrap some long lines. --- .../design/wasi_unstable/wasi_unstable.wati | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.wati b/proposals/random/design/wasi_unstable/wasi_unstable.wati index 438054823..a2ba1e3e0 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/random/design/wasi_unstable/wasi_unstable.wati @@ -230,9 +230,11 @@ (flag $RIGHT_PATH_CREATE_DIRECTORY) ;; If `__WASI_RIGHT_PATH_OPEN` is set, the right to invoke `__wasi_path_open()` with `__WASI_O_CREAT`. (flag $RIGHT_PATH_CREATE_FILE) - ;; The right to invoke `__wasi_path_link()` with the file descriptor as the source directory. + ;; The right to invoke `__wasi_path_link()` with the file descriptor as the + ;; source directory. (flag $RIGHT_PATH_LINK_SOURCE) - ;; The right to invoke `__wasi_path_link()` with the file descriptor as the target directory. + ;; The right to invoke `__wasi_path_link()` with the file descriptor as the + ;; target directory. (flag $RIGHT_PATH_LINK_TARGET) ;; The right to invoke `__wasi_path_open()`. (flag $RIGHT_PATH_OPEN) @@ -473,7 +475,8 @@ ) ) -;; User-provided value that may be attached to objects that is retained when extracted from the implementation. +;; User-provided value that may be attached to objects that is retained when +;; extracted from the implementation. (typename $userdata_t u64) ;; An event that occurred. @@ -501,7 +504,8 @@ ) ) -;; The state of the file descriptor subscribed to with `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. +;; The state of the file descriptor subscribed to with +;; `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. @@ -512,16 +516,20 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (flags u8 - ;; The time value of clock __wasi_subscription_t::u.clock.clock_id has reached timestamp __wasi_subscription_t::u.clock.timeout. + ;; The time value of clock __wasi_subscription_t::u.clock.clock_id has + ;; reached timestamp __wasi_subscription_t::u.clock.timeout. (flag $EVENTTYPE_CLOCK) - ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has data available for reading. This event always triggers for regular files. + ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has data + ;; available for reading. This event always triggers for regular files. (flag $EVENTTYPE_FD_READ) - ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has capacity available for writing. This event always triggers for regular files. + ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has capacity + ;; available for writing. This event always triggers for regular files. (flag $EVENTTYPE_FD_WRITE) ) ) -;; Flags determining how to interpret the timestamp provided in __wasi_subscription_t::u.clock.timeout. +;; Flags determining how to interpret the timestamp provided in +;; __wasi_subscription_t::u.clock.timeout. (typename $subclockflags_t (flags u16 ;; If set, treat the timestamp provided in @@ -536,7 +544,8 @@ ;; Subscription to an event. (typename $subscription_t (struct - ;; User-provided value that is attached to the subscription in the implementation and returned through __wasi_event_t::userdata. + ;; User-provided value that is attached to the subscription in the + ;; implementation and returned through __wasi_event_t::userdata. (field $userdata $userdata_t) ;; The type of the event to which to subscribe. (field $type $eventtype_t) @@ -551,7 +560,9 @@ (field $clock_id $clockid_t) ;; The absolute or relative timestamp. (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally to coalesce with other events. + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; ;; Flags specifying whether the timeout is absolute or relative (field $precision $timestamp_t) ) @@ -673,7 +684,8 @@ ) ) -;; Flags provided to `__wasi_sock_send()`. As there are currently no flags defined, it must be set to zero. +;; Flags provided to `__wasi_sock_send()`. As there are currently no flags +;; defined, it must be set to zero. (typename $siflags_t u16) ;; Which channels on a socket to shut down. @@ -918,8 +930,15 @@ ) ;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary number, like `dup2()`. This would be prone to race conditions, as an actual file descriptor with the same number could be allocated by a different thread at the same time. - ;; This function provides a way to atomically renumber file descriptors, which would disappear if `dup2()` were to be removed entirely. + ;; + ;; Due to the strong focus on thread safety, this environment does not provide + ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;; file descriptor with the same number could be allocated by a different + ;; thread at the same time. + ;; + ;; This function provides a way to atomically renumber file descriptors, which + ;; would disappear if `dup2()` were to be removed entirely. (func (export "fd_renumber") (param $self $fd_t) ;; The file descriptor to overwrite. From 18844d084a07bcb3a1fb1a883aa360f4524d0f70 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 11:01:21 -0700 Subject: [PATCH 0105/1772] Wrap some long lines. --- .../design/wasi_unstable/wasi_unstable.wati | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati index 438054823..a2ba1e3e0 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati @@ -230,9 +230,11 @@ (flag $RIGHT_PATH_CREATE_DIRECTORY) ;; If `__WASI_RIGHT_PATH_OPEN` is set, the right to invoke `__wasi_path_open()` with `__WASI_O_CREAT`. (flag $RIGHT_PATH_CREATE_FILE) - ;; The right to invoke `__wasi_path_link()` with the file descriptor as the source directory. + ;; The right to invoke `__wasi_path_link()` with the file descriptor as the + ;; source directory. (flag $RIGHT_PATH_LINK_SOURCE) - ;; The right to invoke `__wasi_path_link()` with the file descriptor as the target directory. + ;; The right to invoke `__wasi_path_link()` with the file descriptor as the + ;; target directory. (flag $RIGHT_PATH_LINK_TARGET) ;; The right to invoke `__wasi_path_open()`. (flag $RIGHT_PATH_OPEN) @@ -473,7 +475,8 @@ ) ) -;; User-provided value that may be attached to objects that is retained when extracted from the implementation. +;; User-provided value that may be attached to objects that is retained when +;; extracted from the implementation. (typename $userdata_t u64) ;; An event that occurred. @@ -501,7 +504,8 @@ ) ) -;; The state of the file descriptor subscribed to with `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. +;; The state of the file descriptor subscribed to with +;; `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. @@ -512,16 +516,20 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (flags u8 - ;; The time value of clock __wasi_subscription_t::u.clock.clock_id has reached timestamp __wasi_subscription_t::u.clock.timeout. + ;; The time value of clock __wasi_subscription_t::u.clock.clock_id has + ;; reached timestamp __wasi_subscription_t::u.clock.timeout. (flag $EVENTTYPE_CLOCK) - ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has data available for reading. This event always triggers for regular files. + ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has data + ;; available for reading. This event always triggers for regular files. (flag $EVENTTYPE_FD_READ) - ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has capacity available for writing. This event always triggers for regular files. + ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has capacity + ;; available for writing. This event always triggers for regular files. (flag $EVENTTYPE_FD_WRITE) ) ) -;; Flags determining how to interpret the timestamp provided in __wasi_subscription_t::u.clock.timeout. +;; Flags determining how to interpret the timestamp provided in +;; __wasi_subscription_t::u.clock.timeout. (typename $subclockflags_t (flags u16 ;; If set, treat the timestamp provided in @@ -536,7 +544,8 @@ ;; Subscription to an event. (typename $subscription_t (struct - ;; User-provided value that is attached to the subscription in the implementation and returned through __wasi_event_t::userdata. + ;; User-provided value that is attached to the subscription in the + ;; implementation and returned through __wasi_event_t::userdata. (field $userdata $userdata_t) ;; The type of the event to which to subscribe. (field $type $eventtype_t) @@ -551,7 +560,9 @@ (field $clock_id $clockid_t) ;; The absolute or relative timestamp. (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally to coalesce with other events. + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; ;; Flags specifying whether the timeout is absolute or relative (field $precision $timestamp_t) ) @@ -673,7 +684,8 @@ ) ) -;; Flags provided to `__wasi_sock_send()`. As there are currently no flags defined, it must be set to zero. +;; Flags provided to `__wasi_sock_send()`. As there are currently no flags +;; defined, it must be set to zero. (typename $siflags_t u16) ;; Which channels on a socket to shut down. @@ -918,8 +930,15 @@ ) ;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary number, like `dup2()`. This would be prone to race conditions, as an actual file descriptor with the same number could be allocated by a different thread at the same time. - ;; This function provides a way to atomically renumber file descriptors, which would disappear if `dup2()` were to be removed entirely. + ;; + ;; Due to the strong focus on thread safety, this environment does not provide + ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;; file descriptor with the same number could be allocated by a different + ;; thread at the same time. + ;; + ;; This function provides a way to atomically renumber file descriptors, which + ;; would disappear if `dup2()` were to be removed entirely. (func (export "fd_renumber") (param $self $fd_t) ;; The file descriptor to overwrite. From f02aaf9646eee62856d73e85be87d06b9451f702 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 11:05:15 -0700 Subject: [PATCH 0106/1772] Fix field syntax. --- proposals/clocks/design/wasi_unstable/wasi_unstable.wati | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati index a2ba1e3e0..638974498 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati @@ -549,7 +549,7 @@ (field $userdata $userdata_t) ;; The type of the event to which to subscribe. (field $type $eventtype_t) - (field + (field $u (union ;; When type is `__WASI_EVENTTYPE_CLOCK`: (field $clock From 095418ab07c225d753350ae93e0b031a14d3731f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 11:05:15 -0700 Subject: [PATCH 0107/1772] Fix field syntax. --- proposals/random/design/wasi_unstable/wasi_unstable.wati | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.wati b/proposals/random/design/wasi_unstable/wasi_unstable.wati index a2ba1e3e0..638974498 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/random/design/wasi_unstable/wasi_unstable.wati @@ -549,7 +549,7 @@ (field $userdata $userdata_t) ;; The type of the event to which to subscribe. (field $type $eventtype_t) - (field + (field $u (union ;; When type is `__WASI_EVENTTYPE_CLOCK`: (field $clock From e75b05034a9136e3fe5fa6390c9a6dc9054d9adb Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 11:05:15 -0700 Subject: [PATCH 0108/1772] Fix field syntax. --- proposals/filesystem/design/wasi_unstable/wasi_unstable.wati | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati index a2ba1e3e0..638974498 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati @@ -549,7 +549,7 @@ (field $userdata $userdata_t) ;; The type of the event to which to subscribe. (field $type $eventtype_t) - (field + (field $u (union ;; When type is `__WASI_EVENTTYPE_CLOCK`: (field $clock From 27af9bdab472be61ad79ffe3367f478356b28a63 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 11:05:23 -0700 Subject: [PATCH 0109/1772] Fix exponentiation syntax in a comment. --- proposals/clocks/design/wasi_unstable/wasi_unstable.wati | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati index 638974498..5a816adaa 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.wati @@ -1046,7 +1046,7 @@ ;; file descriptor not currently open; it is randomized to prevent ;; applications from depending on making assumptions about indexes, since this ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 231. + ;; guaranteed to be less than 2**31. ;; ;; Note: This is similar to `openat` in POSIX. (func (export "path_open") From 21268ec431128bbe30474d0360cc7a18ae63732c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 11:05:23 -0700 Subject: [PATCH 0110/1772] Fix exponentiation syntax in a comment. --- proposals/random/design/wasi_unstable/wasi_unstable.wati | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.wati b/proposals/random/design/wasi_unstable/wasi_unstable.wati index 638974498..5a816adaa 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/random/design/wasi_unstable/wasi_unstable.wati @@ -1046,7 +1046,7 @@ ;; file descriptor not currently open; it is randomized to prevent ;; applications from depending on making assumptions about indexes, since this ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 231. + ;; guaranteed to be less than 2**31. ;; ;; Note: This is similar to `openat` in POSIX. (func (export "path_open") From 01182b7adfa85a7da218c3644c893574dc205af0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 15 Aug 2019 11:05:23 -0700 Subject: [PATCH 0111/1772] Fix exponentiation syntax in a comment. --- proposals/filesystem/design/wasi_unstable/wasi_unstable.wati | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati index 638974498..5a816adaa 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati @@ -1046,7 +1046,7 @@ ;; file descriptor not currently open; it is randomized to prevent ;; applications from depending on making assumptions about indexes, since this ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 231. + ;; guaranteed to be less than 2**31. ;; ;; Note: This is similar to `openat` in POSIX. (func (export "path_open") From f72b49e02b08f035a57fa7138a119763ca4ed992 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 22 Aug 2019 10:48:08 -0700 Subject: [PATCH 0112/1772] Rename .wati to .widl, use more interface-types syntax, and move types to a separate file. --- .../{wasi_unstable.wati => typenames.widl} | 522 +----------------- .../design/wasi_unstable/wasi_unstable.widl | 519 +++++++++++++++++ 2 files changed, 520 insertions(+), 521 deletions(-) rename proposals/clocks/design/wasi_unstable/{wasi_unstable.wati => typenames.widl} (54%) create mode 100644 proposals/clocks/design/wasi_unstable/wasi_unstable.widl diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati b/proposals/clocks/design/wasi_unstable/typenames.widl similarity index 54% rename from proposals/clocks/design/wasi_unstable/wasi_unstable.wati rename to proposals/clocks/design/wasi_unstable/typenames.widl index 5a816adaa..df97290e0 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/clocks/design/wasi_unstable/typenames.widl @@ -1,4 +1,4 @@ -;; The wasi_unstable module type. +;; Type names used by the wasi_unstable module type. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). @@ -697,523 +697,3 @@ (flag $SHUT_WR) ) ) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; The wasi_unstable moduletype. -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(moduletype $wasi_unstable - ;; Linear memory used by the program. - (import "memory" (memory)) - - ;; The program entry point. - (import "_start" (func)) - - ;; Read command-line argument data. - ;; The size of the array should match that returned by `wasi_args_sizes_get()` - (func (export "args_get") - (result $error $errno_t) - (result $argv $string_array) - ) - ;; Return command-line argument data sizes. - (func (export "args_sizes_get") - (result $error $errno_t) - ;; The number of arguments. - (result $argc $size_t) - ;; The size of the argument string data. - (result $argv_buf_size $size_t) - ) - - ;; Read environment variable data. - ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. - (func (export "environ_get") - (result $error $errno_t) - (result $argv $string_array) - ) - ;; Return command-line argument data sizes. - (func (export "environ_sizes_get") - ;; The number of arguments. - (result $argc $size_t) - ;; The size of the argument string data. - (result $argv_buf_size $size_t) - ) - - ;; Return the resolution of a clock. - ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;; Note: This is similar to `clock_getres` in POSIX. - (func (export "clock_res_get") - (result $error $errno_t) - ;; The clock for which to return the resolution. - (param $clock_id $clockid_t) - ;; The resolution of the clock. - (result $resolution $timestamp_t) - ) - ;; Return the time value of a clock. - ;; Note: This is similar to `clock_gettime` in POSIX. - (func (export "clock_time_get") - ;; The clock for which to return the time. - (param $clock_id $clockid_t) - ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp_t) - (result $error $errno_t) - ;; The time value of the clock. - (result $time $timestamp_t) - ) - - ;; Provide file advisory information on a file descriptor. - ;; Note: This is similar to `posix_fadvise` in POSIX. - (func (export "fd_advise") - (param $self $fd_t) - (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. - (param $len $filesize_t) ;; The length of the region to which the advisory applies. - (param $advice $advice_t) ;; The advice. - (result $error $errno_t) - ) - - ;; Force the allocation of space in a file. - ;; Note: This is similar to `posix_fallocate` in POSIX. - (func (export "fd_allocate") - (param $self $fd_t) - ;; The offset at which to start the allocation. - (param $offset $filesize_t) - ;; The length of the area that is allocated. - (param $len $filesize_t) - (result $error $errno_t) - ) - - ;; Close a file descriptor. - ;; Note: This is similar to `close` in POSIX. - (func (export "fd_close") - (param $self $fd_t) - (result $error $errno_t) - ) - - ;; Synchronize the data of a file to disk. - ;; Note: This is similar to `fdatasync` in POSIX. - (func (export "fd_datasync") - (param $self $fd_t) - (result $error $errno_t) - ) - - ;; Get the attributes of a file descriptor. - ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (func (export "fd_fdstat_get") - (param $self $fd_t) - (result $error $errno_t) - ;; The buffer where the file descriptor's attributes are stored. - (result $fdstat_t) - ) - - ;; Adjust the flags associated with a file descriptor. - ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (func (export "fd_fdstat_set_flags") - (param $self $fd_t) - ;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error $errno_t) - ) - - ;; Adjust the rights associated with a file descriptor. - ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights - (func (export "fd_fdstat_set_rights") - (param $self $fd_t) - ;; The desired rights of the file descriptor. - (param $fs_rights_base $rights_t) - (param $fs_rights_inheriting $rights_t) - (result $error $errno_t) - ) - - ;; Return the attributes of an open file. - (func (export "fd_filestat_get") - (param $self $fd_t) - (result $error $errno_t) - ;; The buffer where the file's attributes are stored. - (result $fs_rights_base $rights_t) - ) - - ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;; Note: This is similar to `ftruncate` in POSIX. - (func (export "fd_filestat_set_size") - (param $self $fd_t) - ;; The desired file size. - (param $st_size $filesize_t) - (result $error $errno_t) - ) - - ;; Adjust the timestamps of an open file or directory. - ;; Note: This is similar to `futimens` in POSIX. - (func (export "fd_filestat_set_times") - (param $self $fd_t) - ;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) - ) - - ;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `preadv` in POSIX. - (func (export "fd_pread") - (param $self $fd_t) - ;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_t_array) - ;; The offset within the file at which to read. - (param $offset $filesize_t) - (result $error $errno_t) - ;; The number of bytes read. - (result $nread $size_t) - ) - - ;; Return a description of the given preopened file descriptor. - (func (export "fd_prestat_get") - (param $self $fd_t) - (result $error $errno_t) - ;; The buffer where the description is stored. - (result $buf $prestat_t) - ) - - ;; Return a description of the given preopened file descriptor. - (func (export "fd_prestat_dir_name") - (param $self $fd_t) - ;; A buffer into which to write the preopened directory name. - (param $path string) - (result $error $errno_t) - ) - - ;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `pwritev` in POSIX. - (func (export "fd_pwrite") - (param $self $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $iovec_t_array) - ;; The offset within the file at which to write. - (param $offset $filesize_t) - (result $error $errno_t) - ;; The number of bytes written. - (result $nwritten $size_t) - ) - - ;; Read from a file descriptor. - ;; Note: This is similar to `readv` in POSIX. - (func (export "fd_read") - (param $self $fd_t) - ;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_t_array) - (result $error $errno_t) - ;; The number of bytes read. - (result $nread $size_t) - ) - - ;; Read directory entries from a directory. - ;; When successful, the contents of the output buffer consist of a sequence of - ;; directory entries. Each directory entry consists of a dirent_t object, - ;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;; entry. - ;; - ;; This function fills the output buffer as much as possible, potentially - ;; truncating the last directory entry. This allows the caller to grow its - ;; read buffer size in case it's too small to fit a single large directory - ;; entry, or skip the oversized directory entry. - (func (export "fd_readdir") - (param $self $fd_t) - ;; The buffer where directory entries are stored - (param $buf data) - ;; The location within the directory to start reading - (param $cookie $dircookie_t) - (result $error $errno_t) - ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size_t) - ) - - ;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;; Due to the strong focus on thread safety, this environment does not provide - ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;; file descriptor with the same number could be allocated by a different - ;; thread at the same time. - ;; - ;; This function provides a way to atomically renumber file descriptors, which - ;; would disappear if `dup2()` were to be removed entirely. - (func (export "fd_renumber") - (param $self $fd_t) - ;; The file descriptor to overwrite. - (param $to $fd_t) - (result $error $errno_t) - ) - - ;; Move the offset of a file descriptor. - ;; Note: This is similar to `lseek` in POSIX. - (func (export "fd_seek") - (param $self $fd_t) - ;; The number of bytes to move. - (param $offset $filedelta_t) - ;; The base from which the offset is relative. - (param $whence $whence_t) - (result $error $errno_t) - ;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize_t) - ) - - ;; Synchronize the data and metadata of a file to disk. - ;; Note: This is similar to `fsync` in POSIX. - (func (export "fd_sync") - (param $self $fd_t) - (result $error $errno_t) - ) - - ;; Return the current offset of a file descriptor. - ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (func (export "fd_tell") - (param $self $fd_t) - (result $error $errno_t) - ;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize_t) - ) - - ;; Write to a file descriptor. - ;; Note: This is similar to `writev` in POSIX. - (func (export "fd_write") - (param $self $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $iovec_t_array) - (result $error $errno_t) - ;; The number of bytes written. - (result $nwritten $size_t) - ) - - ;; Create a directory. - ;; Note: This is similar to `mkdirat` in POSIX. - (func (export "path_create_directory") - (param $self $fd_t) - ;; The path at which to create the directory. - (param $path string) - (result $error $errno_t) - ) - - ;; Return the attributes of a file or directory. - ;; Note: This is similar to `stat` in POSIX. - (func (export "path_filestat_get") - (param $self $fd_t) - ;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) - ;; The path of the file or directory to inspect. - (param $path string) - (result $error $errno_t) - ;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) - ) - - ;; Adjust the timestamps of a file or directory. - ;; Note: This is similar to `utimensat` in POSIX. - (func (export "path_filestat_set_times") - (param $self $fd_t) - ;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) - ;; The path of the file or directory to operate on. - (param $path string) - ;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) - ) - - ;; Create a hard link. - ;; Note: This is similar to `linkat` in POSIX. - (func (export "path_link") - (param $self $fd_t) - ;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags_t) - ;; The source path from which to link. - (param $old_path string) - ;; The working directory at which the resolution of the new path starts. - (param $new_fd $path) - ;; The destination path at which to create the hard link. - (param $new_path string) - (result $error $errno_t) - ) - - ;; Open a file or directory. - ;; - ;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;; file descriptor not currently open; it is randomized to prevent - ;; applications from depending on making assumptions about indexes, since this - ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 2**31. - ;; - ;; Note: This is similar to `openat` in POSIX. - (func (export "path_open") - (param $self $fd_t) - ;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags_t) - ;; The relative path of the file or directory to open, relative to the - ;; `dirfd` directory. - (param $path string) - ;; The method by which to open the file. - (param $o_flags $oflags_t) - ;; The initial rights of the newly created file descriptor. The - ;; implementation is allowed to return a file descriptor with fewer rights - ;; than specified, if and only if those rights do not apply to the type of - ;; file being opened. - ;; - ;; The base rights are rights that will apply to operations using the file - ;; descriptor itself, while the inheriting rights are rights that apply to - ;; file descriptors derived from it. - (param $fs_rights_base $rights_t) - (param $fs_rights_inherting $rights_t) - (result $error $errno_t) - ;; The file descriptor of the file that has been opened. - (result $opened_fd $fd_t) - ) - - ;; Read the contents of a symbolic link. - ;; Note: This is similar to `readlinkat` in POSIX. - (func (export "path_readlink") - (param $self $fd_t) - ;; The path of the symbolic link from which to read. - (param $path) - ;; The buffer to which to write the contents of the symbolic link. - (param $buf string) - (result $error $errno_t) - ;; The number of bytes placed in the buffer. - (result $bufused $size_t) - ) - - ;; Remove a directory. - ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. - ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (func (export "path_remove_directory") - (param $self $fd_t) - ;; The path to a directory to remove. - (param $path string) - (result $error $errno_t) - ) - - ;; Rename a file or directory. - ;; Note: This is similar to `renameat` in POSIX. - (func (export "path_rename") - (param $self $fd_t) - ;; The source path of the file or directory to rename. - (param $old_path string) - ;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error $errno_t) - ) - - ;; Create a symbolic link. - ;; Note: This is similar to `symlinkat` in POSIX. - (func (export "path_symlink") - (param $self $fd_t) - ;; The contents of the symbolic link. - (param $old_path string) - ;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error $errno_t) - ) - - - ;; Unlink a file. - ;; Return `__WASI_EISDIR` if the path refers to a directory. - ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (func (export "path_unlink_file") - (param $self $fd_t) - ;; The path to a file to unlink. - (param $path string) - (result $error $errno_t) - ) - - ;; Concurrently poll for the occurrence of a set of events. - (func (export "poll_oneoff") - ;; The events to which to subscribe. - (param $in $subscription_t) - ;; The events that have occurred. - (param $out $event_t) - ;; Both the number of subscriptions and events. - (param $nsubscriptions $size_t) - (result $error $errno_t) - ;; The number of events stored. - (result $nevents $size_t) - ) - - ;; Terminate the process normally. An exit code of 0 indicates successful - ;; termination of the program. The meanings of other values is dependent on - ;; the environment. - (func (export "proc_exit") - ;; The exit code returned by the process. - (param $rval $exitcode_t) - ) - - ;; Send a signal to the process of the calling thread. - ;; Note: This is similar to `raise` in POSIX. - (func (export "proc_raise") - ;; The signal condition to trigger. - (param $sig $signal_t) - (result $error $errno_t) - ) - - ;; Temporarily yield execution of the calling thread. - ;; Note: This is similar to `sched_yield` in POSIX. - (func (export "proc_sched_yield") - (result $error $errno_t) - ) - - ;; Write high-quality random data into a buffer. - ;; This function blocks when the implementation is unable to immediately - ;; provide sufficient high-quality random data. - ;; This function may execute slowly, so when large mounts of random data are - ;; required, it's advisable to use this function to seed a pseudo-random - ;; number generator, rather than to provide the random data directly. - (func (export "random_get") - ;; The buffer to fill with random data. - (param $buf data) - (result $error $errno_t) - ) - - ;; Receive a message from a socket. - ;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;; the data into multiple buffers in the manner of `readv`. - (func (export "sock_recv") - (param $self $fd_t) - ;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_t_array) - ;; Message flags. - (param $ri_flags $riflags_t) - (result $error $errno_t) - ;; Number of bytes stored in ri_data. - (result $ro_datalen $size_t) - ;; Message flags. - (result $ro_flags $roflags_t) - ) - - ;; Send a message on a socket. - ;; Note: This is similar to `send` in POSIX, though it also supports writing - ;; the data from multiple buffers in the manner of `writev`. - (func (export "sock_send") - (param $self $fd_t) - ;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_t_array) - ;; Message flags. - (param $si_flags $siflags_t) - (result $error $errno_t) - ;; Number of bytes transmitted. - (result $so_datalen $size_t) - ) - - ;; Shut down socket send and receive channels. - ;; Note: This is similar to `shutdown` in POSIX. - (func (export "sock_shutdown") - (param $self $fd_t) - ;; Which channels on the socket to shut down. - (param $how $sdflags_t) - (result $error $errno_t) - ) -) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.widl b/proposals/clocks/design/wasi_unstable/wasi_unstable.widl new file mode 100644 index 000000000..30633d711 --- /dev/null +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.widl @@ -0,0 +1,519 @@ +;; The wasi_unstable module type. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). + +(import "typenames.wid") + +(module $wasi_unstable + ;; Linear memory used by the program. + (import "memory" (memory)) + + ;; The program entry point. + (import "_start" (func)) + + ;; Read command-line argument data. + ;; The size of the array should match that returned by `wasi_args_sizes_get()` + (@interface func (export "args_get") + (result $error $errno_t) + (result $argv $string_array) + ) + ;; Return command-line argument data sizes. + (@interface func (export "args_sizes_get") + (result $error $errno_t) + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Read environment variable data. + ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + (@interface func (export "environ_get") + (result $error $errno_t) + (result $argv $string_array) + ) + ;; Return command-line argument data sizes. + (@interface func (export "environ_sizes_get") + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Return the resolution of a clock. + ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;; Note: This is similar to `clock_getres` in POSIX. + (@interface func (export "clock_res_get") + (result $error $errno_t) + ;; The clock for which to return the resolution. + (param $clock_id $clockid_t) + ;; The resolution of the clock. + (result $resolution $timestamp_t) + ) + ;; Return the time value of a clock. + ;; Note: This is similar to `clock_gettime` in POSIX. + (@interface func (export "clock_time_get") + ;; The clock for which to return the time. + (param $clock_id $clockid_t) + ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp_t) + (result $error $errno_t) + ;; The time value of the clock. + (result $time $timestamp_t) + ) + + ;; Provide file advisory information on a file descriptor. + ;; Note: This is similar to `posix_fadvise` in POSIX. + (@interface func (export "fd_advise") + (param $self $fd_t) + (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. + (param $len $filesize_t) ;; The length of the region to which the advisory applies. + (param $advice $advice_t) ;; The advice. + (result $error $errno_t) + ) + + ;; Force the allocation of space in a file. + ;; Note: This is similar to `posix_fallocate` in POSIX. + (@interface func (export "fd_allocate") + (param $self $fd_t) + ;; The offset at which to start the allocation. + (param $offset $filesize_t) + ;; The length of the area that is allocated. + (param $len $filesize_t) + (result $error $errno_t) + ) + + ;; Close a file descriptor. + ;; Note: This is similar to `close` in POSIX. + (@interface func (export "fd_close") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Synchronize the data of a file to disk. + ;; Note: This is similar to `fdatasync` in POSIX. + (@interface func (export "fd_datasync") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Get the attributes of a file descriptor. + ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (@interface func (export "fd_fdstat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the file descriptor's attributes are stored. + (result $fdstat_t) + ) + + ;; Adjust the flags associated with a file descriptor. + ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (@interface func (export "fd_fdstat_set_flags") + (param $self $fd_t) + ;; The desired values of the file descriptor flags. + (param $flags $fdflags) + (result $error $errno_t) + ) + + ;; Adjust the rights associated with a file descriptor. + ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (@interface func (export "fd_fdstat_set_rights") + (param $self $fd_t) + ;; The desired rights of the file descriptor. + (param $fs_rights_base $rights_t) + (param $fs_rights_inheriting $rights_t) + (result $error $errno_t) + ) + + ;; Return the attributes of an open file. + (@interface func (export "fd_filestat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $fs_rights_base $rights_t) + ) + + ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;; Note: This is similar to `ftruncate` in POSIX. + (@interface func (export "fd_filestat_set_size") + (param $self $fd_t) + ;; The desired file size. + (param $st_size $filesize_t) + (result $error $errno_t) + ) + + ;; Adjust the timestamps of an open file or directory. + ;; Note: This is similar to `futimens` in POSIX. + (@interface func (export "fd_filestat_set_times") + (param $self $fd_t) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `preadv` in POSIX. + (@interface func (export "fd_pread") + (param $self $fd_t) + ;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to read. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the description is stored. + (result $buf $prestat_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_dir_name") + (param $self $fd_t) + ;; A buffer into which to write the preopened directory name. + (param $path string) + (result $error $errno_t) + ) + + ;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `pwritev` in POSIX. + (@interface func (export "fd_pwrite") + (param $self $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to write. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Read from a file descriptor. + ;; Note: This is similar to `readv` in POSIX. + (@interface func (export "fd_read") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Read directory entries from a directory. + ;; When successful, the contents of the output buffer consist of a sequence of + ;; directory entries. Each directory entry consists of a dirent_t object, + ;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;; entry. + ;; + ;; This function fills the output buffer as much as possible, potentially + ;; truncating the last directory entry. This allows the caller to grow its + ;; read buffer size in case it's too small to fit a single large directory + ;; entry, or skip the oversized directory entry. + (@interface func (export "fd_readdir") + (param $self $fd_t) + ;; The buffer where directory entries are stored + (param $buf data) + ;; The location within the directory to start reading + (param $cookie $dircookie_t) + (result $error $errno_t) + ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size_t) + ) + + ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; + ;; Due to the strong focus on thread safety, this environment does not provide + ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;; file descriptor with the same number could be allocated by a different + ;; thread at the same time. + ;; + ;; This function provides a way to atomically renumber file descriptors, which + ;; would disappear if `dup2()` were to be removed entirely. + (@interface func (export "fd_renumber") + (param $self $fd_t) + ;; The file descriptor to overwrite. + (param $to $fd_t) + (result $error $errno_t) + ) + + ;; Move the offset of a file descriptor. + ;; Note: This is similar to `lseek` in POSIX. + (@interface func (export "fd_seek") + (param $self $fd_t) + ;; The number of bytes to move. + (param $offset $filedelta_t) + ;; The base from which the offset is relative. + (param $whence $whence_t) + (result $error $errno_t) + ;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize_t) + ) + + ;; Synchronize the data and metadata of a file to disk. + ;; Note: This is similar to `fsync` in POSIX. + (@interface func (export "fd_sync") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Return the current offset of a file descriptor. + ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (@interface func (export "fd_tell") + (param $self $fd_t) + (result $error $errno_t) + ;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize_t) + ) + + ;; Write to a file descriptor. + ;; Note: This is similar to `writev` in POSIX. + (@interface func (export "fd_write") + (param $self $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Create a directory. + ;; Note: This is similar to `mkdirat` in POSIX. + (@interface func (export "path_create_directory") + (param $self $fd_t) + ;; The path at which to create the directory. + (param $path string) + (result $error $errno_t) + ) + + ;; Return the attributes of a file or directory. + ;; Note: This is similar to `stat` in POSIX. + (@interface func (export "path_filestat_get") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $buf $filestat_t) + ) + + ;; Adjust the timestamps of a file or directory. + ;; Note: This is similar to `utimensat` in POSIX. + (@interface func (export "path_filestat_set_times") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to operate on. + (param $path string) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Create a hard link. + ;; Note: This is similar to `linkat` in POSIX. + (@interface func (export "path_link") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags_t) + ;; The source path from which to link. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $path) + ;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Open a file or directory. + ;; + ;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;; file descriptor not currently open; it is randomized to prevent + ;; applications from depending on making assumptions about indexes, since this + ;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;; guaranteed to be less than 2**31. + ;; + ;; Note: This is similar to `openat` in POSIX. + (@interface func (export "path_open") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags_t) + ;; The relative path of the file or directory to open, relative to the + ;; `dirfd` directory. + (param $path string) + ;; The method by which to open the file. + (param $o_flags $oflags_t) + ;; The initial rights of the newly created file descriptor. The + ;; implementation is allowed to return a file descriptor with fewer rights + ;; than specified, if and only if those rights do not apply to the type of + ;; file being opened. + ;; + ;; The base rights are rights that will apply to operations using the file + ;; descriptor itself, while the inheriting rights are rights that apply to + ;; file descriptors derived from it. + (param $fs_rights_base $rights_t) + (param $fs_rights_inherting $rights_t) + (result $error $errno_t) + ;; The file descriptor of the file that has been opened. + (result $opened_fd $fd_t) + ) + + ;; Read the contents of a symbolic link. + ;; Note: This is similar to `readlinkat` in POSIX. + (@interface func (export "path_readlink") + (param $self $fd_t) + ;; The path of the symbolic link from which to read. + (param $path) + ;; The buffer to which to write the contents of the symbolic link. + (param $buf string) + (result $error $errno_t) + ;; The number of bytes placed in the buffer. + (result $bufused $size_t) + ) + + ;; Remove a directory. + ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. + ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (@interface func (export "path_remove_directory") + (param $self $fd_t) + ;; The path to a directory to remove. + (param $path string) + (result $error $errno_t) + ) + + ;; Rename a file or directory. + ;; Note: This is similar to `renameat` in POSIX. + (@interface func (export "path_rename") + (param $self $fd_t) + ;; The source path of the file or directory to rename. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd) + ;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Create a symbolic link. + ;; Note: This is similar to `symlinkat` in POSIX. + (@interface func (export "path_symlink") + (param $self $fd_t) + ;; The contents of the symbolic link. + (param $old_path string) + ;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno_t) + ) + + + ;; Unlink a file. + ;; Return `__WASI_EISDIR` if the path refers to a directory. + ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (@interface func (export "path_unlink_file") + (param $self $fd_t) + ;; The path to a file to unlink. + (param $path string) + (result $error $errno_t) + ) + + ;; Concurrently poll for the occurrence of a set of events. + (@interface func (export "poll_oneoff") + ;; The events to which to subscribe. + (param $in $subscription_t) + ;; The events that have occurred. + (param $out $event_t) + ;; Both the number of subscriptions and events. + (param $nsubscriptions $size_t) + (result $error $errno_t) + ;; The number of events stored. + (result $nevents $size_t) + ) + + ;; Terminate the process normally. An exit code of 0 indicates successful + ;; termination of the program. The meanings of other values is dependent on + ;; the environment. + (@interface func (export "proc_exit") + ;; The exit code returned by the process. + (param $rval $exitcode_t) + ) + + ;; Send a signal to the process of the calling thread. + ;; Note: This is similar to `raise` in POSIX. + (@interface func (export "proc_raise") + ;; The signal condition to trigger. + (param $sig $signal_t) + (result $error $errno_t) + ) + + ;; Temporarily yield execution of the calling thread. + ;; Note: This is similar to `sched_yield` in POSIX. + (@interface func (export "proc_sched_yield") + (result $error $errno_t) + ) + + ;; Write high-quality random data into a buffer. + ;; This function blocks when the implementation is unable to immediately + ;; provide sufficient high-quality random data. + ;; This function may execute slowly, so when large mounts of random data are + ;; required, it's advisable to use this function to seed a pseudo-random + ;; number generator, rather than to provide the random data directly. + (@interface func (export "random_get") + ;; The buffer to fill with random data. + (param $buf data) + (result $error $errno_t) + ) + + ;; Receive a message from a socket. + ;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;; the data into multiple buffers in the manner of `readv`. + (@interface func (export "sock_recv") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_t_array) + ;; Message flags. + (param $ri_flags $riflags_t) + (result $error $errno_t) + ;; Number of bytes stored in ri_data. + (result $ro_datalen $size_t) + ;; Message flags. + (result $ro_flags $roflags_t) + ) + + ;; Send a message on a socket. + ;; Note: This is similar to `send` in POSIX, though it also supports writing + ;; the data from multiple buffers in the manner of `writev`. + (@interface func (export "sock_send") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_t_array) + ;; Message flags. + (param $si_flags $siflags_t) + (result $error $errno_t) + ;; Number of bytes transmitted. + (result $so_datalen $size_t) + ) + + ;; Shut down socket send and receive channels. + ;; Note: This is similar to `shutdown` in POSIX. + (@interface func (export "sock_shutdown") + (param $self $fd_t) + ;; Which channels on the socket to shut down. + (param $how $sdflags_t) + (result $error $errno_t) + ) +) From 79129474def4ae6d3922c6ce8db69e9b31d75af3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 22 Aug 2019 10:48:08 -0700 Subject: [PATCH 0113/1772] Rename .wati to .widl, use more interface-types syntax, and move types to a separate file. --- .../{wasi_unstable.wati => typenames.widl} | 522 +----------------- .../design/wasi_unstable/wasi_unstable.widl | 519 +++++++++++++++++ 2 files changed, 520 insertions(+), 521 deletions(-) rename proposals/random/design/wasi_unstable/{wasi_unstable.wati => typenames.widl} (54%) create mode 100644 proposals/random/design/wasi_unstable/wasi_unstable.widl diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.wati b/proposals/random/design/wasi_unstable/typenames.widl similarity index 54% rename from proposals/random/design/wasi_unstable/wasi_unstable.wati rename to proposals/random/design/wasi_unstable/typenames.widl index 5a816adaa..df97290e0 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/random/design/wasi_unstable/typenames.widl @@ -1,4 +1,4 @@ -;; The wasi_unstable module type. +;; Type names used by the wasi_unstable module type. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). @@ -697,523 +697,3 @@ (flag $SHUT_WR) ) ) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; The wasi_unstable moduletype. -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(moduletype $wasi_unstable - ;; Linear memory used by the program. - (import "memory" (memory)) - - ;; The program entry point. - (import "_start" (func)) - - ;; Read command-line argument data. - ;; The size of the array should match that returned by `wasi_args_sizes_get()` - (func (export "args_get") - (result $error $errno_t) - (result $argv $string_array) - ) - ;; Return command-line argument data sizes. - (func (export "args_sizes_get") - (result $error $errno_t) - ;; The number of arguments. - (result $argc $size_t) - ;; The size of the argument string data. - (result $argv_buf_size $size_t) - ) - - ;; Read environment variable data. - ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. - (func (export "environ_get") - (result $error $errno_t) - (result $argv $string_array) - ) - ;; Return command-line argument data sizes. - (func (export "environ_sizes_get") - ;; The number of arguments. - (result $argc $size_t) - ;; The size of the argument string data. - (result $argv_buf_size $size_t) - ) - - ;; Return the resolution of a clock. - ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;; Note: This is similar to `clock_getres` in POSIX. - (func (export "clock_res_get") - (result $error $errno_t) - ;; The clock for which to return the resolution. - (param $clock_id $clockid_t) - ;; The resolution of the clock. - (result $resolution $timestamp_t) - ) - ;; Return the time value of a clock. - ;; Note: This is similar to `clock_gettime` in POSIX. - (func (export "clock_time_get") - ;; The clock for which to return the time. - (param $clock_id $clockid_t) - ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp_t) - (result $error $errno_t) - ;; The time value of the clock. - (result $time $timestamp_t) - ) - - ;; Provide file advisory information on a file descriptor. - ;; Note: This is similar to `posix_fadvise` in POSIX. - (func (export "fd_advise") - (param $self $fd_t) - (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. - (param $len $filesize_t) ;; The length of the region to which the advisory applies. - (param $advice $advice_t) ;; The advice. - (result $error $errno_t) - ) - - ;; Force the allocation of space in a file. - ;; Note: This is similar to `posix_fallocate` in POSIX. - (func (export "fd_allocate") - (param $self $fd_t) - ;; The offset at which to start the allocation. - (param $offset $filesize_t) - ;; The length of the area that is allocated. - (param $len $filesize_t) - (result $error $errno_t) - ) - - ;; Close a file descriptor. - ;; Note: This is similar to `close` in POSIX. - (func (export "fd_close") - (param $self $fd_t) - (result $error $errno_t) - ) - - ;; Synchronize the data of a file to disk. - ;; Note: This is similar to `fdatasync` in POSIX. - (func (export "fd_datasync") - (param $self $fd_t) - (result $error $errno_t) - ) - - ;; Get the attributes of a file descriptor. - ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (func (export "fd_fdstat_get") - (param $self $fd_t) - (result $error $errno_t) - ;; The buffer where the file descriptor's attributes are stored. - (result $fdstat_t) - ) - - ;; Adjust the flags associated with a file descriptor. - ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (func (export "fd_fdstat_set_flags") - (param $self $fd_t) - ;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error $errno_t) - ) - - ;; Adjust the rights associated with a file descriptor. - ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights - (func (export "fd_fdstat_set_rights") - (param $self $fd_t) - ;; The desired rights of the file descriptor. - (param $fs_rights_base $rights_t) - (param $fs_rights_inheriting $rights_t) - (result $error $errno_t) - ) - - ;; Return the attributes of an open file. - (func (export "fd_filestat_get") - (param $self $fd_t) - (result $error $errno_t) - ;; The buffer where the file's attributes are stored. - (result $fs_rights_base $rights_t) - ) - - ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;; Note: This is similar to `ftruncate` in POSIX. - (func (export "fd_filestat_set_size") - (param $self $fd_t) - ;; The desired file size. - (param $st_size $filesize_t) - (result $error $errno_t) - ) - - ;; Adjust the timestamps of an open file or directory. - ;; Note: This is similar to `futimens` in POSIX. - (func (export "fd_filestat_set_times") - (param $self $fd_t) - ;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) - ) - - ;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `preadv` in POSIX. - (func (export "fd_pread") - (param $self $fd_t) - ;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_t_array) - ;; The offset within the file at which to read. - (param $offset $filesize_t) - (result $error $errno_t) - ;; The number of bytes read. - (result $nread $size_t) - ) - - ;; Return a description of the given preopened file descriptor. - (func (export "fd_prestat_get") - (param $self $fd_t) - (result $error $errno_t) - ;; The buffer where the description is stored. - (result $buf $prestat_t) - ) - - ;; Return a description of the given preopened file descriptor. - (func (export "fd_prestat_dir_name") - (param $self $fd_t) - ;; A buffer into which to write the preopened directory name. - (param $path string) - (result $error $errno_t) - ) - - ;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `pwritev` in POSIX. - (func (export "fd_pwrite") - (param $self $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $iovec_t_array) - ;; The offset within the file at which to write. - (param $offset $filesize_t) - (result $error $errno_t) - ;; The number of bytes written. - (result $nwritten $size_t) - ) - - ;; Read from a file descriptor. - ;; Note: This is similar to `readv` in POSIX. - (func (export "fd_read") - (param $self $fd_t) - ;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_t_array) - (result $error $errno_t) - ;; The number of bytes read. - (result $nread $size_t) - ) - - ;; Read directory entries from a directory. - ;; When successful, the contents of the output buffer consist of a sequence of - ;; directory entries. Each directory entry consists of a dirent_t object, - ;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;; entry. - ;; - ;; This function fills the output buffer as much as possible, potentially - ;; truncating the last directory entry. This allows the caller to grow its - ;; read buffer size in case it's too small to fit a single large directory - ;; entry, or skip the oversized directory entry. - (func (export "fd_readdir") - (param $self $fd_t) - ;; The buffer where directory entries are stored - (param $buf data) - ;; The location within the directory to start reading - (param $cookie $dircookie_t) - (result $error $errno_t) - ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size_t) - ) - - ;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;; Due to the strong focus on thread safety, this environment does not provide - ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;; file descriptor with the same number could be allocated by a different - ;; thread at the same time. - ;; - ;; This function provides a way to atomically renumber file descriptors, which - ;; would disappear if `dup2()` were to be removed entirely. - (func (export "fd_renumber") - (param $self $fd_t) - ;; The file descriptor to overwrite. - (param $to $fd_t) - (result $error $errno_t) - ) - - ;; Move the offset of a file descriptor. - ;; Note: This is similar to `lseek` in POSIX. - (func (export "fd_seek") - (param $self $fd_t) - ;; The number of bytes to move. - (param $offset $filedelta_t) - ;; The base from which the offset is relative. - (param $whence $whence_t) - (result $error $errno_t) - ;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize_t) - ) - - ;; Synchronize the data and metadata of a file to disk. - ;; Note: This is similar to `fsync` in POSIX. - (func (export "fd_sync") - (param $self $fd_t) - (result $error $errno_t) - ) - - ;; Return the current offset of a file descriptor. - ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (func (export "fd_tell") - (param $self $fd_t) - (result $error $errno_t) - ;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize_t) - ) - - ;; Write to a file descriptor. - ;; Note: This is similar to `writev` in POSIX. - (func (export "fd_write") - (param $self $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $iovec_t_array) - (result $error $errno_t) - ;; The number of bytes written. - (result $nwritten $size_t) - ) - - ;; Create a directory. - ;; Note: This is similar to `mkdirat` in POSIX. - (func (export "path_create_directory") - (param $self $fd_t) - ;; The path at which to create the directory. - (param $path string) - (result $error $errno_t) - ) - - ;; Return the attributes of a file or directory. - ;; Note: This is similar to `stat` in POSIX. - (func (export "path_filestat_get") - (param $self $fd_t) - ;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) - ;; The path of the file or directory to inspect. - (param $path string) - (result $error $errno_t) - ;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) - ) - - ;; Adjust the timestamps of a file or directory. - ;; Note: This is similar to `utimensat` in POSIX. - (func (export "path_filestat_set_times") - (param $self $fd_t) - ;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) - ;; The path of the file or directory to operate on. - (param $path string) - ;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) - ) - - ;; Create a hard link. - ;; Note: This is similar to `linkat` in POSIX. - (func (export "path_link") - (param $self $fd_t) - ;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags_t) - ;; The source path from which to link. - (param $old_path string) - ;; The working directory at which the resolution of the new path starts. - (param $new_fd $path) - ;; The destination path at which to create the hard link. - (param $new_path string) - (result $error $errno_t) - ) - - ;; Open a file or directory. - ;; - ;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;; file descriptor not currently open; it is randomized to prevent - ;; applications from depending on making assumptions about indexes, since this - ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 2**31. - ;; - ;; Note: This is similar to `openat` in POSIX. - (func (export "path_open") - (param $self $fd_t) - ;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags_t) - ;; The relative path of the file or directory to open, relative to the - ;; `dirfd` directory. - (param $path string) - ;; The method by which to open the file. - (param $o_flags $oflags_t) - ;; The initial rights of the newly created file descriptor. The - ;; implementation is allowed to return a file descriptor with fewer rights - ;; than specified, if and only if those rights do not apply to the type of - ;; file being opened. - ;; - ;; The base rights are rights that will apply to operations using the file - ;; descriptor itself, while the inheriting rights are rights that apply to - ;; file descriptors derived from it. - (param $fs_rights_base $rights_t) - (param $fs_rights_inherting $rights_t) - (result $error $errno_t) - ;; The file descriptor of the file that has been opened. - (result $opened_fd $fd_t) - ) - - ;; Read the contents of a symbolic link. - ;; Note: This is similar to `readlinkat` in POSIX. - (func (export "path_readlink") - (param $self $fd_t) - ;; The path of the symbolic link from which to read. - (param $path) - ;; The buffer to which to write the contents of the symbolic link. - (param $buf string) - (result $error $errno_t) - ;; The number of bytes placed in the buffer. - (result $bufused $size_t) - ) - - ;; Remove a directory. - ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. - ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (func (export "path_remove_directory") - (param $self $fd_t) - ;; The path to a directory to remove. - (param $path string) - (result $error $errno_t) - ) - - ;; Rename a file or directory. - ;; Note: This is similar to `renameat` in POSIX. - (func (export "path_rename") - (param $self $fd_t) - ;; The source path of the file or directory to rename. - (param $old_path string) - ;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error $errno_t) - ) - - ;; Create a symbolic link. - ;; Note: This is similar to `symlinkat` in POSIX. - (func (export "path_symlink") - (param $self $fd_t) - ;; The contents of the symbolic link. - (param $old_path string) - ;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error $errno_t) - ) - - - ;; Unlink a file. - ;; Return `__WASI_EISDIR` if the path refers to a directory. - ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (func (export "path_unlink_file") - (param $self $fd_t) - ;; The path to a file to unlink. - (param $path string) - (result $error $errno_t) - ) - - ;; Concurrently poll for the occurrence of a set of events. - (func (export "poll_oneoff") - ;; The events to which to subscribe. - (param $in $subscription_t) - ;; The events that have occurred. - (param $out $event_t) - ;; Both the number of subscriptions and events. - (param $nsubscriptions $size_t) - (result $error $errno_t) - ;; The number of events stored. - (result $nevents $size_t) - ) - - ;; Terminate the process normally. An exit code of 0 indicates successful - ;; termination of the program. The meanings of other values is dependent on - ;; the environment. - (func (export "proc_exit") - ;; The exit code returned by the process. - (param $rval $exitcode_t) - ) - - ;; Send a signal to the process of the calling thread. - ;; Note: This is similar to `raise` in POSIX. - (func (export "proc_raise") - ;; The signal condition to trigger. - (param $sig $signal_t) - (result $error $errno_t) - ) - - ;; Temporarily yield execution of the calling thread. - ;; Note: This is similar to `sched_yield` in POSIX. - (func (export "proc_sched_yield") - (result $error $errno_t) - ) - - ;; Write high-quality random data into a buffer. - ;; This function blocks when the implementation is unable to immediately - ;; provide sufficient high-quality random data. - ;; This function may execute slowly, so when large mounts of random data are - ;; required, it's advisable to use this function to seed a pseudo-random - ;; number generator, rather than to provide the random data directly. - (func (export "random_get") - ;; The buffer to fill with random data. - (param $buf data) - (result $error $errno_t) - ) - - ;; Receive a message from a socket. - ;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;; the data into multiple buffers in the manner of `readv`. - (func (export "sock_recv") - (param $self $fd_t) - ;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_t_array) - ;; Message flags. - (param $ri_flags $riflags_t) - (result $error $errno_t) - ;; Number of bytes stored in ri_data. - (result $ro_datalen $size_t) - ;; Message flags. - (result $ro_flags $roflags_t) - ) - - ;; Send a message on a socket. - ;; Note: This is similar to `send` in POSIX, though it also supports writing - ;; the data from multiple buffers in the manner of `writev`. - (func (export "sock_send") - (param $self $fd_t) - ;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_t_array) - ;; Message flags. - (param $si_flags $siflags_t) - (result $error $errno_t) - ;; Number of bytes transmitted. - (result $so_datalen $size_t) - ) - - ;; Shut down socket send and receive channels. - ;; Note: This is similar to `shutdown` in POSIX. - (func (export "sock_shutdown") - (param $self $fd_t) - ;; Which channels on the socket to shut down. - (param $how $sdflags_t) - (result $error $errno_t) - ) -) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.widl b/proposals/random/design/wasi_unstable/wasi_unstable.widl new file mode 100644 index 000000000..30633d711 --- /dev/null +++ b/proposals/random/design/wasi_unstable/wasi_unstable.widl @@ -0,0 +1,519 @@ +;; The wasi_unstable module type. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). + +(import "typenames.wid") + +(module $wasi_unstable + ;; Linear memory used by the program. + (import "memory" (memory)) + + ;; The program entry point. + (import "_start" (func)) + + ;; Read command-line argument data. + ;; The size of the array should match that returned by `wasi_args_sizes_get()` + (@interface func (export "args_get") + (result $error $errno_t) + (result $argv $string_array) + ) + ;; Return command-line argument data sizes. + (@interface func (export "args_sizes_get") + (result $error $errno_t) + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Read environment variable data. + ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + (@interface func (export "environ_get") + (result $error $errno_t) + (result $argv $string_array) + ) + ;; Return command-line argument data sizes. + (@interface func (export "environ_sizes_get") + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Return the resolution of a clock. + ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;; Note: This is similar to `clock_getres` in POSIX. + (@interface func (export "clock_res_get") + (result $error $errno_t) + ;; The clock for which to return the resolution. + (param $clock_id $clockid_t) + ;; The resolution of the clock. + (result $resolution $timestamp_t) + ) + ;; Return the time value of a clock. + ;; Note: This is similar to `clock_gettime` in POSIX. + (@interface func (export "clock_time_get") + ;; The clock for which to return the time. + (param $clock_id $clockid_t) + ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp_t) + (result $error $errno_t) + ;; The time value of the clock. + (result $time $timestamp_t) + ) + + ;; Provide file advisory information on a file descriptor. + ;; Note: This is similar to `posix_fadvise` in POSIX. + (@interface func (export "fd_advise") + (param $self $fd_t) + (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. + (param $len $filesize_t) ;; The length of the region to which the advisory applies. + (param $advice $advice_t) ;; The advice. + (result $error $errno_t) + ) + + ;; Force the allocation of space in a file. + ;; Note: This is similar to `posix_fallocate` in POSIX. + (@interface func (export "fd_allocate") + (param $self $fd_t) + ;; The offset at which to start the allocation. + (param $offset $filesize_t) + ;; The length of the area that is allocated. + (param $len $filesize_t) + (result $error $errno_t) + ) + + ;; Close a file descriptor. + ;; Note: This is similar to `close` in POSIX. + (@interface func (export "fd_close") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Synchronize the data of a file to disk. + ;; Note: This is similar to `fdatasync` in POSIX. + (@interface func (export "fd_datasync") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Get the attributes of a file descriptor. + ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (@interface func (export "fd_fdstat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the file descriptor's attributes are stored. + (result $fdstat_t) + ) + + ;; Adjust the flags associated with a file descriptor. + ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (@interface func (export "fd_fdstat_set_flags") + (param $self $fd_t) + ;; The desired values of the file descriptor flags. + (param $flags $fdflags) + (result $error $errno_t) + ) + + ;; Adjust the rights associated with a file descriptor. + ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (@interface func (export "fd_fdstat_set_rights") + (param $self $fd_t) + ;; The desired rights of the file descriptor. + (param $fs_rights_base $rights_t) + (param $fs_rights_inheriting $rights_t) + (result $error $errno_t) + ) + + ;; Return the attributes of an open file. + (@interface func (export "fd_filestat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $fs_rights_base $rights_t) + ) + + ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;; Note: This is similar to `ftruncate` in POSIX. + (@interface func (export "fd_filestat_set_size") + (param $self $fd_t) + ;; The desired file size. + (param $st_size $filesize_t) + (result $error $errno_t) + ) + + ;; Adjust the timestamps of an open file or directory. + ;; Note: This is similar to `futimens` in POSIX. + (@interface func (export "fd_filestat_set_times") + (param $self $fd_t) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `preadv` in POSIX. + (@interface func (export "fd_pread") + (param $self $fd_t) + ;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to read. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the description is stored. + (result $buf $prestat_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_dir_name") + (param $self $fd_t) + ;; A buffer into which to write the preopened directory name. + (param $path string) + (result $error $errno_t) + ) + + ;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `pwritev` in POSIX. + (@interface func (export "fd_pwrite") + (param $self $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to write. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Read from a file descriptor. + ;; Note: This is similar to `readv` in POSIX. + (@interface func (export "fd_read") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Read directory entries from a directory. + ;; When successful, the contents of the output buffer consist of a sequence of + ;; directory entries. Each directory entry consists of a dirent_t object, + ;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;; entry. + ;; + ;; This function fills the output buffer as much as possible, potentially + ;; truncating the last directory entry. This allows the caller to grow its + ;; read buffer size in case it's too small to fit a single large directory + ;; entry, or skip the oversized directory entry. + (@interface func (export "fd_readdir") + (param $self $fd_t) + ;; The buffer where directory entries are stored + (param $buf data) + ;; The location within the directory to start reading + (param $cookie $dircookie_t) + (result $error $errno_t) + ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size_t) + ) + + ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; + ;; Due to the strong focus on thread safety, this environment does not provide + ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;; file descriptor with the same number could be allocated by a different + ;; thread at the same time. + ;; + ;; This function provides a way to atomically renumber file descriptors, which + ;; would disappear if `dup2()` were to be removed entirely. + (@interface func (export "fd_renumber") + (param $self $fd_t) + ;; The file descriptor to overwrite. + (param $to $fd_t) + (result $error $errno_t) + ) + + ;; Move the offset of a file descriptor. + ;; Note: This is similar to `lseek` in POSIX. + (@interface func (export "fd_seek") + (param $self $fd_t) + ;; The number of bytes to move. + (param $offset $filedelta_t) + ;; The base from which the offset is relative. + (param $whence $whence_t) + (result $error $errno_t) + ;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize_t) + ) + + ;; Synchronize the data and metadata of a file to disk. + ;; Note: This is similar to `fsync` in POSIX. + (@interface func (export "fd_sync") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Return the current offset of a file descriptor. + ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (@interface func (export "fd_tell") + (param $self $fd_t) + (result $error $errno_t) + ;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize_t) + ) + + ;; Write to a file descriptor. + ;; Note: This is similar to `writev` in POSIX. + (@interface func (export "fd_write") + (param $self $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Create a directory. + ;; Note: This is similar to `mkdirat` in POSIX. + (@interface func (export "path_create_directory") + (param $self $fd_t) + ;; The path at which to create the directory. + (param $path string) + (result $error $errno_t) + ) + + ;; Return the attributes of a file or directory. + ;; Note: This is similar to `stat` in POSIX. + (@interface func (export "path_filestat_get") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $buf $filestat_t) + ) + + ;; Adjust the timestamps of a file or directory. + ;; Note: This is similar to `utimensat` in POSIX. + (@interface func (export "path_filestat_set_times") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to operate on. + (param $path string) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Create a hard link. + ;; Note: This is similar to `linkat` in POSIX. + (@interface func (export "path_link") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags_t) + ;; The source path from which to link. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $path) + ;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Open a file or directory. + ;; + ;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;; file descriptor not currently open; it is randomized to prevent + ;; applications from depending on making assumptions about indexes, since this + ;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;; guaranteed to be less than 2**31. + ;; + ;; Note: This is similar to `openat` in POSIX. + (@interface func (export "path_open") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags_t) + ;; The relative path of the file or directory to open, relative to the + ;; `dirfd` directory. + (param $path string) + ;; The method by which to open the file. + (param $o_flags $oflags_t) + ;; The initial rights of the newly created file descriptor. The + ;; implementation is allowed to return a file descriptor with fewer rights + ;; than specified, if and only if those rights do not apply to the type of + ;; file being opened. + ;; + ;; The base rights are rights that will apply to operations using the file + ;; descriptor itself, while the inheriting rights are rights that apply to + ;; file descriptors derived from it. + (param $fs_rights_base $rights_t) + (param $fs_rights_inherting $rights_t) + (result $error $errno_t) + ;; The file descriptor of the file that has been opened. + (result $opened_fd $fd_t) + ) + + ;; Read the contents of a symbolic link. + ;; Note: This is similar to `readlinkat` in POSIX. + (@interface func (export "path_readlink") + (param $self $fd_t) + ;; The path of the symbolic link from which to read. + (param $path) + ;; The buffer to which to write the contents of the symbolic link. + (param $buf string) + (result $error $errno_t) + ;; The number of bytes placed in the buffer. + (result $bufused $size_t) + ) + + ;; Remove a directory. + ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. + ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (@interface func (export "path_remove_directory") + (param $self $fd_t) + ;; The path to a directory to remove. + (param $path string) + (result $error $errno_t) + ) + + ;; Rename a file or directory. + ;; Note: This is similar to `renameat` in POSIX. + (@interface func (export "path_rename") + (param $self $fd_t) + ;; The source path of the file or directory to rename. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd) + ;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Create a symbolic link. + ;; Note: This is similar to `symlinkat` in POSIX. + (@interface func (export "path_symlink") + (param $self $fd_t) + ;; The contents of the symbolic link. + (param $old_path string) + ;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno_t) + ) + + + ;; Unlink a file. + ;; Return `__WASI_EISDIR` if the path refers to a directory. + ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (@interface func (export "path_unlink_file") + (param $self $fd_t) + ;; The path to a file to unlink. + (param $path string) + (result $error $errno_t) + ) + + ;; Concurrently poll for the occurrence of a set of events. + (@interface func (export "poll_oneoff") + ;; The events to which to subscribe. + (param $in $subscription_t) + ;; The events that have occurred. + (param $out $event_t) + ;; Both the number of subscriptions and events. + (param $nsubscriptions $size_t) + (result $error $errno_t) + ;; The number of events stored. + (result $nevents $size_t) + ) + + ;; Terminate the process normally. An exit code of 0 indicates successful + ;; termination of the program. The meanings of other values is dependent on + ;; the environment. + (@interface func (export "proc_exit") + ;; The exit code returned by the process. + (param $rval $exitcode_t) + ) + + ;; Send a signal to the process of the calling thread. + ;; Note: This is similar to `raise` in POSIX. + (@interface func (export "proc_raise") + ;; The signal condition to trigger. + (param $sig $signal_t) + (result $error $errno_t) + ) + + ;; Temporarily yield execution of the calling thread. + ;; Note: This is similar to `sched_yield` in POSIX. + (@interface func (export "proc_sched_yield") + (result $error $errno_t) + ) + + ;; Write high-quality random data into a buffer. + ;; This function blocks when the implementation is unable to immediately + ;; provide sufficient high-quality random data. + ;; This function may execute slowly, so when large mounts of random data are + ;; required, it's advisable to use this function to seed a pseudo-random + ;; number generator, rather than to provide the random data directly. + (@interface func (export "random_get") + ;; The buffer to fill with random data. + (param $buf data) + (result $error $errno_t) + ) + + ;; Receive a message from a socket. + ;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;; the data into multiple buffers in the manner of `readv`. + (@interface func (export "sock_recv") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_t_array) + ;; Message flags. + (param $ri_flags $riflags_t) + (result $error $errno_t) + ;; Number of bytes stored in ri_data. + (result $ro_datalen $size_t) + ;; Message flags. + (result $ro_flags $roflags_t) + ) + + ;; Send a message on a socket. + ;; Note: This is similar to `send` in POSIX, though it also supports writing + ;; the data from multiple buffers in the manner of `writev`. + (@interface func (export "sock_send") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_t_array) + ;; Message flags. + (param $si_flags $siflags_t) + (result $error $errno_t) + ;; Number of bytes transmitted. + (result $so_datalen $size_t) + ) + + ;; Shut down socket send and receive channels. + ;; Note: This is similar to `shutdown` in POSIX. + (@interface func (export "sock_shutdown") + (param $self $fd_t) + ;; Which channels on the socket to shut down. + (param $how $sdflags_t) + (result $error $errno_t) + ) +) From 9eb955dbfef0dc6db15e6a5aca7f17ff32a0ef8d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 22 Aug 2019 10:48:08 -0700 Subject: [PATCH 0114/1772] Rename .wati to .widl, use more interface-types syntax, and move types to a separate file. --- .../{wasi_unstable.wati => typenames.widl} | 522 +----------------- .../design/wasi_unstable/wasi_unstable.widl | 519 +++++++++++++++++ 2 files changed, 520 insertions(+), 521 deletions(-) rename proposals/filesystem/design/wasi_unstable/{wasi_unstable.wati => typenames.widl} (54%) create mode 100644 proposals/filesystem/design/wasi_unstable/wasi_unstable.widl diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati b/proposals/filesystem/design/wasi_unstable/typenames.widl similarity index 54% rename from proposals/filesystem/design/wasi_unstable/wasi_unstable.wati rename to proposals/filesystem/design/wasi_unstable/typenames.widl index 5a816adaa..df97290e0 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.wati +++ b/proposals/filesystem/design/wasi_unstable/typenames.widl @@ -1,4 +1,4 @@ -;; The wasi_unstable module type. +;; Type names used by the wasi_unstable module type. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). @@ -697,523 +697,3 @@ (flag $SHUT_WR) ) ) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; The wasi_unstable moduletype. -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(moduletype $wasi_unstable - ;; Linear memory used by the program. - (import "memory" (memory)) - - ;; The program entry point. - (import "_start" (func)) - - ;; Read command-line argument data. - ;; The size of the array should match that returned by `wasi_args_sizes_get()` - (func (export "args_get") - (result $error $errno_t) - (result $argv $string_array) - ) - ;; Return command-line argument data sizes. - (func (export "args_sizes_get") - (result $error $errno_t) - ;; The number of arguments. - (result $argc $size_t) - ;; The size of the argument string data. - (result $argv_buf_size $size_t) - ) - - ;; Read environment variable data. - ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. - (func (export "environ_get") - (result $error $errno_t) - (result $argv $string_array) - ) - ;; Return command-line argument data sizes. - (func (export "environ_sizes_get") - ;; The number of arguments. - (result $argc $size_t) - ;; The size of the argument string data. - (result $argv_buf_size $size_t) - ) - - ;; Return the resolution of a clock. - ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;; Note: This is similar to `clock_getres` in POSIX. - (func (export "clock_res_get") - (result $error $errno_t) - ;; The clock for which to return the resolution. - (param $clock_id $clockid_t) - ;; The resolution of the clock. - (result $resolution $timestamp_t) - ) - ;; Return the time value of a clock. - ;; Note: This is similar to `clock_gettime` in POSIX. - (func (export "clock_time_get") - ;; The clock for which to return the time. - (param $clock_id $clockid_t) - ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp_t) - (result $error $errno_t) - ;; The time value of the clock. - (result $time $timestamp_t) - ) - - ;; Provide file advisory information on a file descriptor. - ;; Note: This is similar to `posix_fadvise` in POSIX. - (func (export "fd_advise") - (param $self $fd_t) - (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. - (param $len $filesize_t) ;; The length of the region to which the advisory applies. - (param $advice $advice_t) ;; The advice. - (result $error $errno_t) - ) - - ;; Force the allocation of space in a file. - ;; Note: This is similar to `posix_fallocate` in POSIX. - (func (export "fd_allocate") - (param $self $fd_t) - ;; The offset at which to start the allocation. - (param $offset $filesize_t) - ;; The length of the area that is allocated. - (param $len $filesize_t) - (result $error $errno_t) - ) - - ;; Close a file descriptor. - ;; Note: This is similar to `close` in POSIX. - (func (export "fd_close") - (param $self $fd_t) - (result $error $errno_t) - ) - - ;; Synchronize the data of a file to disk. - ;; Note: This is similar to `fdatasync` in POSIX. - (func (export "fd_datasync") - (param $self $fd_t) - (result $error $errno_t) - ) - - ;; Get the attributes of a file descriptor. - ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (func (export "fd_fdstat_get") - (param $self $fd_t) - (result $error $errno_t) - ;; The buffer where the file descriptor's attributes are stored. - (result $fdstat_t) - ) - - ;; Adjust the flags associated with a file descriptor. - ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (func (export "fd_fdstat_set_flags") - (param $self $fd_t) - ;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error $errno_t) - ) - - ;; Adjust the rights associated with a file descriptor. - ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights - (func (export "fd_fdstat_set_rights") - (param $self $fd_t) - ;; The desired rights of the file descriptor. - (param $fs_rights_base $rights_t) - (param $fs_rights_inheriting $rights_t) - (result $error $errno_t) - ) - - ;; Return the attributes of an open file. - (func (export "fd_filestat_get") - (param $self $fd_t) - (result $error $errno_t) - ;; The buffer where the file's attributes are stored. - (result $fs_rights_base $rights_t) - ) - - ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;; Note: This is similar to `ftruncate` in POSIX. - (func (export "fd_filestat_set_size") - (param $self $fd_t) - ;; The desired file size. - (param $st_size $filesize_t) - (result $error $errno_t) - ) - - ;; Adjust the timestamps of an open file or directory. - ;; Note: This is similar to `futimens` in POSIX. - (func (export "fd_filestat_set_times") - (param $self $fd_t) - ;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) - ) - - ;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `preadv` in POSIX. - (func (export "fd_pread") - (param $self $fd_t) - ;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_t_array) - ;; The offset within the file at which to read. - (param $offset $filesize_t) - (result $error $errno_t) - ;; The number of bytes read. - (result $nread $size_t) - ) - - ;; Return a description of the given preopened file descriptor. - (func (export "fd_prestat_get") - (param $self $fd_t) - (result $error $errno_t) - ;; The buffer where the description is stored. - (result $buf $prestat_t) - ) - - ;; Return a description of the given preopened file descriptor. - (func (export "fd_prestat_dir_name") - (param $self $fd_t) - ;; A buffer into which to write the preopened directory name. - (param $path string) - (result $error $errno_t) - ) - - ;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `pwritev` in POSIX. - (func (export "fd_pwrite") - (param $self $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $iovec_t_array) - ;; The offset within the file at which to write. - (param $offset $filesize_t) - (result $error $errno_t) - ;; The number of bytes written. - (result $nwritten $size_t) - ) - - ;; Read from a file descriptor. - ;; Note: This is similar to `readv` in POSIX. - (func (export "fd_read") - (param $self $fd_t) - ;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_t_array) - (result $error $errno_t) - ;; The number of bytes read. - (result $nread $size_t) - ) - - ;; Read directory entries from a directory. - ;; When successful, the contents of the output buffer consist of a sequence of - ;; directory entries. Each directory entry consists of a dirent_t object, - ;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;; entry. - ;; - ;; This function fills the output buffer as much as possible, potentially - ;; truncating the last directory entry. This allows the caller to grow its - ;; read buffer size in case it's too small to fit a single large directory - ;; entry, or skip the oversized directory entry. - (func (export "fd_readdir") - (param $self $fd_t) - ;; The buffer where directory entries are stored - (param $buf data) - ;; The location within the directory to start reading - (param $cookie $dircookie_t) - (result $error $errno_t) - ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size_t) - ) - - ;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;; Due to the strong focus on thread safety, this environment does not provide - ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;; file descriptor with the same number could be allocated by a different - ;; thread at the same time. - ;; - ;; This function provides a way to atomically renumber file descriptors, which - ;; would disappear if `dup2()` were to be removed entirely. - (func (export "fd_renumber") - (param $self $fd_t) - ;; The file descriptor to overwrite. - (param $to $fd_t) - (result $error $errno_t) - ) - - ;; Move the offset of a file descriptor. - ;; Note: This is similar to `lseek` in POSIX. - (func (export "fd_seek") - (param $self $fd_t) - ;; The number of bytes to move. - (param $offset $filedelta_t) - ;; The base from which the offset is relative. - (param $whence $whence_t) - (result $error $errno_t) - ;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize_t) - ) - - ;; Synchronize the data and metadata of a file to disk. - ;; Note: This is similar to `fsync` in POSIX. - (func (export "fd_sync") - (param $self $fd_t) - (result $error $errno_t) - ) - - ;; Return the current offset of a file descriptor. - ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (func (export "fd_tell") - (param $self $fd_t) - (result $error $errno_t) - ;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize_t) - ) - - ;; Write to a file descriptor. - ;; Note: This is similar to `writev` in POSIX. - (func (export "fd_write") - (param $self $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $iovec_t_array) - (result $error $errno_t) - ;; The number of bytes written. - (result $nwritten $size_t) - ) - - ;; Create a directory. - ;; Note: This is similar to `mkdirat` in POSIX. - (func (export "path_create_directory") - (param $self $fd_t) - ;; The path at which to create the directory. - (param $path string) - (result $error $errno_t) - ) - - ;; Return the attributes of a file or directory. - ;; Note: This is similar to `stat` in POSIX. - (func (export "path_filestat_get") - (param $self $fd_t) - ;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) - ;; The path of the file or directory to inspect. - (param $path string) - (result $error $errno_t) - ;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) - ) - - ;; Adjust the timestamps of a file or directory. - ;; Note: This is similar to `utimensat` in POSIX. - (func (export "path_filestat_set_times") - (param $self $fd_t) - ;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) - ;; The path of the file or directory to operate on. - (param $path string) - ;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) - ) - - ;; Create a hard link. - ;; Note: This is similar to `linkat` in POSIX. - (func (export "path_link") - (param $self $fd_t) - ;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags_t) - ;; The source path from which to link. - (param $old_path string) - ;; The working directory at which the resolution of the new path starts. - (param $new_fd $path) - ;; The destination path at which to create the hard link. - (param $new_path string) - (result $error $errno_t) - ) - - ;; Open a file or directory. - ;; - ;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;; file descriptor not currently open; it is randomized to prevent - ;; applications from depending on making assumptions about indexes, since this - ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 2**31. - ;; - ;; Note: This is similar to `openat` in POSIX. - (func (export "path_open") - (param $self $fd_t) - ;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags_t) - ;; The relative path of the file or directory to open, relative to the - ;; `dirfd` directory. - (param $path string) - ;; The method by which to open the file. - (param $o_flags $oflags_t) - ;; The initial rights of the newly created file descriptor. The - ;; implementation is allowed to return a file descriptor with fewer rights - ;; than specified, if and only if those rights do not apply to the type of - ;; file being opened. - ;; - ;; The base rights are rights that will apply to operations using the file - ;; descriptor itself, while the inheriting rights are rights that apply to - ;; file descriptors derived from it. - (param $fs_rights_base $rights_t) - (param $fs_rights_inherting $rights_t) - (result $error $errno_t) - ;; The file descriptor of the file that has been opened. - (result $opened_fd $fd_t) - ) - - ;; Read the contents of a symbolic link. - ;; Note: This is similar to `readlinkat` in POSIX. - (func (export "path_readlink") - (param $self $fd_t) - ;; The path of the symbolic link from which to read. - (param $path) - ;; The buffer to which to write the contents of the symbolic link. - (param $buf string) - (result $error $errno_t) - ;; The number of bytes placed in the buffer. - (result $bufused $size_t) - ) - - ;; Remove a directory. - ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. - ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (func (export "path_remove_directory") - (param $self $fd_t) - ;; The path to a directory to remove. - (param $path string) - (result $error $errno_t) - ) - - ;; Rename a file or directory. - ;; Note: This is similar to `renameat` in POSIX. - (func (export "path_rename") - (param $self $fd_t) - ;; The source path of the file or directory to rename. - (param $old_path string) - ;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error $errno_t) - ) - - ;; Create a symbolic link. - ;; Note: This is similar to `symlinkat` in POSIX. - (func (export "path_symlink") - (param $self $fd_t) - ;; The contents of the symbolic link. - (param $old_path string) - ;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error $errno_t) - ) - - - ;; Unlink a file. - ;; Return `__WASI_EISDIR` if the path refers to a directory. - ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (func (export "path_unlink_file") - (param $self $fd_t) - ;; The path to a file to unlink. - (param $path string) - (result $error $errno_t) - ) - - ;; Concurrently poll for the occurrence of a set of events. - (func (export "poll_oneoff") - ;; The events to which to subscribe. - (param $in $subscription_t) - ;; The events that have occurred. - (param $out $event_t) - ;; Both the number of subscriptions and events. - (param $nsubscriptions $size_t) - (result $error $errno_t) - ;; The number of events stored. - (result $nevents $size_t) - ) - - ;; Terminate the process normally. An exit code of 0 indicates successful - ;; termination of the program. The meanings of other values is dependent on - ;; the environment. - (func (export "proc_exit") - ;; The exit code returned by the process. - (param $rval $exitcode_t) - ) - - ;; Send a signal to the process of the calling thread. - ;; Note: This is similar to `raise` in POSIX. - (func (export "proc_raise") - ;; The signal condition to trigger. - (param $sig $signal_t) - (result $error $errno_t) - ) - - ;; Temporarily yield execution of the calling thread. - ;; Note: This is similar to `sched_yield` in POSIX. - (func (export "proc_sched_yield") - (result $error $errno_t) - ) - - ;; Write high-quality random data into a buffer. - ;; This function blocks when the implementation is unable to immediately - ;; provide sufficient high-quality random data. - ;; This function may execute slowly, so when large mounts of random data are - ;; required, it's advisable to use this function to seed a pseudo-random - ;; number generator, rather than to provide the random data directly. - (func (export "random_get") - ;; The buffer to fill with random data. - (param $buf data) - (result $error $errno_t) - ) - - ;; Receive a message from a socket. - ;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;; the data into multiple buffers in the manner of `readv`. - (func (export "sock_recv") - (param $self $fd_t) - ;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_t_array) - ;; Message flags. - (param $ri_flags $riflags_t) - (result $error $errno_t) - ;; Number of bytes stored in ri_data. - (result $ro_datalen $size_t) - ;; Message flags. - (result $ro_flags $roflags_t) - ) - - ;; Send a message on a socket. - ;; Note: This is similar to `send` in POSIX, though it also supports writing - ;; the data from multiple buffers in the manner of `writev`. - (func (export "sock_send") - (param $self $fd_t) - ;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_t_array) - ;; Message flags. - (param $si_flags $siflags_t) - (result $error $errno_t) - ;; Number of bytes transmitted. - (result $so_datalen $size_t) - ) - - ;; Shut down socket send and receive channels. - ;; Note: This is similar to `shutdown` in POSIX. - (func (export "sock_shutdown") - (param $self $fd_t) - ;; Which channels on the socket to shut down. - (param $how $sdflags_t) - (result $error $errno_t) - ) -) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl b/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl new file mode 100644 index 000000000..30633d711 --- /dev/null +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl @@ -0,0 +1,519 @@ +;; The wasi_unstable module type. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). + +(import "typenames.wid") + +(module $wasi_unstable + ;; Linear memory used by the program. + (import "memory" (memory)) + + ;; The program entry point. + (import "_start" (func)) + + ;; Read command-line argument data. + ;; The size of the array should match that returned by `wasi_args_sizes_get()` + (@interface func (export "args_get") + (result $error $errno_t) + (result $argv $string_array) + ) + ;; Return command-line argument data sizes. + (@interface func (export "args_sizes_get") + (result $error $errno_t) + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Read environment variable data. + ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + (@interface func (export "environ_get") + (result $error $errno_t) + (result $argv $string_array) + ) + ;; Return command-line argument data sizes. + (@interface func (export "environ_sizes_get") + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Return the resolution of a clock. + ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;; Note: This is similar to `clock_getres` in POSIX. + (@interface func (export "clock_res_get") + (result $error $errno_t) + ;; The clock for which to return the resolution. + (param $clock_id $clockid_t) + ;; The resolution of the clock. + (result $resolution $timestamp_t) + ) + ;; Return the time value of a clock. + ;; Note: This is similar to `clock_gettime` in POSIX. + (@interface func (export "clock_time_get") + ;; The clock for which to return the time. + (param $clock_id $clockid_t) + ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp_t) + (result $error $errno_t) + ;; The time value of the clock. + (result $time $timestamp_t) + ) + + ;; Provide file advisory information on a file descriptor. + ;; Note: This is similar to `posix_fadvise` in POSIX. + (@interface func (export "fd_advise") + (param $self $fd_t) + (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. + (param $len $filesize_t) ;; The length of the region to which the advisory applies. + (param $advice $advice_t) ;; The advice. + (result $error $errno_t) + ) + + ;; Force the allocation of space in a file. + ;; Note: This is similar to `posix_fallocate` in POSIX. + (@interface func (export "fd_allocate") + (param $self $fd_t) + ;; The offset at which to start the allocation. + (param $offset $filesize_t) + ;; The length of the area that is allocated. + (param $len $filesize_t) + (result $error $errno_t) + ) + + ;; Close a file descriptor. + ;; Note: This is similar to `close` in POSIX. + (@interface func (export "fd_close") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Synchronize the data of a file to disk. + ;; Note: This is similar to `fdatasync` in POSIX. + (@interface func (export "fd_datasync") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Get the attributes of a file descriptor. + ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (@interface func (export "fd_fdstat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the file descriptor's attributes are stored. + (result $fdstat_t) + ) + + ;; Adjust the flags associated with a file descriptor. + ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (@interface func (export "fd_fdstat_set_flags") + (param $self $fd_t) + ;; The desired values of the file descriptor flags. + (param $flags $fdflags) + (result $error $errno_t) + ) + + ;; Adjust the rights associated with a file descriptor. + ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (@interface func (export "fd_fdstat_set_rights") + (param $self $fd_t) + ;; The desired rights of the file descriptor. + (param $fs_rights_base $rights_t) + (param $fs_rights_inheriting $rights_t) + (result $error $errno_t) + ) + + ;; Return the attributes of an open file. + (@interface func (export "fd_filestat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $fs_rights_base $rights_t) + ) + + ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;; Note: This is similar to `ftruncate` in POSIX. + (@interface func (export "fd_filestat_set_size") + (param $self $fd_t) + ;; The desired file size. + (param $st_size $filesize_t) + (result $error $errno_t) + ) + + ;; Adjust the timestamps of an open file or directory. + ;; Note: This is similar to `futimens` in POSIX. + (@interface func (export "fd_filestat_set_times") + (param $self $fd_t) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `preadv` in POSIX. + (@interface func (export "fd_pread") + (param $self $fd_t) + ;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to read. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_get") + (param $self $fd_t) + (result $error $errno_t) + ;; The buffer where the description is stored. + (result $buf $prestat_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_dir_name") + (param $self $fd_t) + ;; A buffer into which to write the preopened directory name. + (param $path string) + (result $error $errno_t) + ) + + ;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `pwritev` in POSIX. + (@interface func (export "fd_pwrite") + (param $self $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to write. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Read from a file descriptor. + ;; Note: This is similar to `readv` in POSIX. + (@interface func (export "fd_read") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Read directory entries from a directory. + ;; When successful, the contents of the output buffer consist of a sequence of + ;; directory entries. Each directory entry consists of a dirent_t object, + ;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;; entry. + ;; + ;; This function fills the output buffer as much as possible, potentially + ;; truncating the last directory entry. This allows the caller to grow its + ;; read buffer size in case it's too small to fit a single large directory + ;; entry, or skip the oversized directory entry. + (@interface func (export "fd_readdir") + (param $self $fd_t) + ;; The buffer where directory entries are stored + (param $buf data) + ;; The location within the directory to start reading + (param $cookie $dircookie_t) + (result $error $errno_t) + ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size_t) + ) + + ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; + ;; Due to the strong focus on thread safety, this environment does not provide + ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;; file descriptor with the same number could be allocated by a different + ;; thread at the same time. + ;; + ;; This function provides a way to atomically renumber file descriptors, which + ;; would disappear if `dup2()` were to be removed entirely. + (@interface func (export "fd_renumber") + (param $self $fd_t) + ;; The file descriptor to overwrite. + (param $to $fd_t) + (result $error $errno_t) + ) + + ;; Move the offset of a file descriptor. + ;; Note: This is similar to `lseek` in POSIX. + (@interface func (export "fd_seek") + (param $self $fd_t) + ;; The number of bytes to move. + (param $offset $filedelta_t) + ;; The base from which the offset is relative. + (param $whence $whence_t) + (result $error $errno_t) + ;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize_t) + ) + + ;; Synchronize the data and metadata of a file to disk. + ;; Note: This is similar to `fsync` in POSIX. + (@interface func (export "fd_sync") + (param $self $fd_t) + (result $error $errno_t) + ) + + ;; Return the current offset of a file descriptor. + ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (@interface func (export "fd_tell") + (param $self $fd_t) + (result $error $errno_t) + ;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize_t) + ) + + ;; Write to a file descriptor. + ;; Note: This is similar to `writev` in POSIX. + (@interface func (export "fd_write") + (param $self $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Create a directory. + ;; Note: This is similar to `mkdirat` in POSIX. + (@interface func (export "path_create_directory") + (param $self $fd_t) + ;; The path at which to create the directory. + (param $path string) + (result $error $errno_t) + ) + + ;; Return the attributes of a file or directory. + ;; Note: This is similar to `stat` in POSIX. + (@interface func (export "path_filestat_get") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $buf $filestat_t) + ) + + ;; Adjust the timestamps of a file or directory. + ;; Note: This is similar to `utimensat` in POSIX. + (@interface func (export "path_filestat_set_times") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to operate on. + (param $path string) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Create a hard link. + ;; Note: This is similar to `linkat` in POSIX. + (@interface func (export "path_link") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags_t) + ;; The source path from which to link. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $path) + ;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Open a file or directory. + ;; + ;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;; file descriptor not currently open; it is randomized to prevent + ;; applications from depending on making assumptions about indexes, since this + ;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;; guaranteed to be less than 2**31. + ;; + ;; Note: This is similar to `openat` in POSIX. + (@interface func (export "path_open") + (param $self $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags_t) + ;; The relative path of the file or directory to open, relative to the + ;; `dirfd` directory. + (param $path string) + ;; The method by which to open the file. + (param $o_flags $oflags_t) + ;; The initial rights of the newly created file descriptor. The + ;; implementation is allowed to return a file descriptor with fewer rights + ;; than specified, if and only if those rights do not apply to the type of + ;; file being opened. + ;; + ;; The base rights are rights that will apply to operations using the file + ;; descriptor itself, while the inheriting rights are rights that apply to + ;; file descriptors derived from it. + (param $fs_rights_base $rights_t) + (param $fs_rights_inherting $rights_t) + (result $error $errno_t) + ;; The file descriptor of the file that has been opened. + (result $opened_fd $fd_t) + ) + + ;; Read the contents of a symbolic link. + ;; Note: This is similar to `readlinkat` in POSIX. + (@interface func (export "path_readlink") + (param $self $fd_t) + ;; The path of the symbolic link from which to read. + (param $path) + ;; The buffer to which to write the contents of the symbolic link. + (param $buf string) + (result $error $errno_t) + ;; The number of bytes placed in the buffer. + (result $bufused $size_t) + ) + + ;; Remove a directory. + ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. + ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (@interface func (export "path_remove_directory") + (param $self $fd_t) + ;; The path to a directory to remove. + (param $path string) + (result $error $errno_t) + ) + + ;; Rename a file or directory. + ;; Note: This is similar to `renameat` in POSIX. + (@interface func (export "path_rename") + (param $self $fd_t) + ;; The source path of the file or directory to rename. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd) + ;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Create a symbolic link. + ;; Note: This is similar to `symlinkat` in POSIX. + (@interface func (export "path_symlink") + (param $self $fd_t) + ;; The contents of the symbolic link. + (param $old_path string) + ;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno_t) + ) + + + ;; Unlink a file. + ;; Return `__WASI_EISDIR` if the path refers to a directory. + ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (@interface func (export "path_unlink_file") + (param $self $fd_t) + ;; The path to a file to unlink. + (param $path string) + (result $error $errno_t) + ) + + ;; Concurrently poll for the occurrence of a set of events. + (@interface func (export "poll_oneoff") + ;; The events to which to subscribe. + (param $in $subscription_t) + ;; The events that have occurred. + (param $out $event_t) + ;; Both the number of subscriptions and events. + (param $nsubscriptions $size_t) + (result $error $errno_t) + ;; The number of events stored. + (result $nevents $size_t) + ) + + ;; Terminate the process normally. An exit code of 0 indicates successful + ;; termination of the program. The meanings of other values is dependent on + ;; the environment. + (@interface func (export "proc_exit") + ;; The exit code returned by the process. + (param $rval $exitcode_t) + ) + + ;; Send a signal to the process of the calling thread. + ;; Note: This is similar to `raise` in POSIX. + (@interface func (export "proc_raise") + ;; The signal condition to trigger. + (param $sig $signal_t) + (result $error $errno_t) + ) + + ;; Temporarily yield execution of the calling thread. + ;; Note: This is similar to `sched_yield` in POSIX. + (@interface func (export "proc_sched_yield") + (result $error $errno_t) + ) + + ;; Write high-quality random data into a buffer. + ;; This function blocks when the implementation is unable to immediately + ;; provide sufficient high-quality random data. + ;; This function may execute slowly, so when large mounts of random data are + ;; required, it's advisable to use this function to seed a pseudo-random + ;; number generator, rather than to provide the random data directly. + (@interface func (export "random_get") + ;; The buffer to fill with random data. + (param $buf data) + (result $error $errno_t) + ) + + ;; Receive a message from a socket. + ;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;; the data into multiple buffers in the manner of `readv`. + (@interface func (export "sock_recv") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_t_array) + ;; Message flags. + (param $ri_flags $riflags_t) + (result $error $errno_t) + ;; Number of bytes stored in ri_data. + (result $ro_datalen $size_t) + ;; Message flags. + (result $ro_flags $roflags_t) + ) + + ;; Send a message on a socket. + ;; Note: This is similar to `send` in POSIX, though it also supports writing + ;; the data from multiple buffers in the manner of `writev`. + (@interface func (export "sock_send") + (param $self $fd_t) + ;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_t_array) + ;; Message flags. + (param $si_flags $siflags_t) + (result $error $errno_t) + ;; Number of bytes transmitted. + (result $so_datalen $size_t) + ) + + ;; Shut down socket send and receive channels. + ;; Note: This is similar to `shutdown` in POSIX. + (@interface func (export "sock_shutdown") + (param $self $fd_t) + ;; Which channels on the socket to shut down. + (param $how $sdflags_t) + (result $error $errno_t) + ) +) From fddbaff76748e14f7f85cbacaaec6c6b09d85885 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 29 Aug 2019 21:55:06 -0700 Subject: [PATCH 0115/1772] Rename `import` to `use`, since "import" already means something in wasm. --- proposals/clocks/design/wasi_unstable/wasi_unstable.widl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.widl b/proposals/clocks/design/wasi_unstable/wasi_unstable.widl index 30633d711..730f1c84f 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.widl +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.widl @@ -2,7 +2,7 @@ ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -(import "typenames.wid") +(use "typenames.wid") (module $wasi_unstable ;; Linear memory used by the program. From 867d71673aa59662101bca92369b76298ed68856 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 29 Aug 2019 21:55:06 -0700 Subject: [PATCH 0116/1772] Rename `import` to `use`, since "import" already means something in wasm. --- proposals/random/design/wasi_unstable/wasi_unstable.widl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.widl b/proposals/random/design/wasi_unstable/wasi_unstable.widl index 30633d711..730f1c84f 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.widl +++ b/proposals/random/design/wasi_unstable/wasi_unstable.widl @@ -2,7 +2,7 @@ ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -(import "typenames.wid") +(use "typenames.wid") (module $wasi_unstable ;; Linear memory used by the program. From 75654a83728d0485010e500d46bb9439f9a27d9e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 29 Aug 2019 21:55:06 -0700 Subject: [PATCH 0117/1772] Rename `import` to `use`, since "import" already means something in wasm. --- proposals/filesystem/design/wasi_unstable/wasi_unstable.widl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl b/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl index 30633d711..730f1c84f 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl @@ -2,7 +2,7 @@ ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -(import "typenames.wid") +(use "typenames.wid") (module $wasi_unstable ;; Linear memory used by the program. From c880a967ccf280def187ce67797596d5066fe69c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 11:12:04 -0700 Subject: [PATCH 0118/1772] Remove the `_start` import. It isn't logically part of the `wasi_unstable` module. It's part of the platform-level ABI. --- proposals/clocks/design/wasi_unstable/wasi_unstable.widl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.widl b/proposals/clocks/design/wasi_unstable/wasi_unstable.widl index 730f1c84f..6ec0e7d67 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.widl +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.widl @@ -5,12 +5,9 @@ (use "typenames.wid") (module $wasi_unstable - ;; Linear memory used by the program. + ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) - ;; The program entry point. - (import "_start" (func)) - ;; Read command-line argument data. ;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") From 88bf6e3da73cc28a35b7715f7b65a60f996b0cdf Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 11:12:04 -0700 Subject: [PATCH 0119/1772] Remove the `_start` import. It isn't logically part of the `wasi_unstable` module. It's part of the platform-level ABI. --- proposals/random/design/wasi_unstable/wasi_unstable.widl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.widl b/proposals/random/design/wasi_unstable/wasi_unstable.widl index 730f1c84f..6ec0e7d67 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.widl +++ b/proposals/random/design/wasi_unstable/wasi_unstable.widl @@ -5,12 +5,9 @@ (use "typenames.wid") (module $wasi_unstable - ;; Linear memory used by the program. + ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) - ;; The program entry point. - (import "_start" (func)) - ;; Read command-line argument data. ;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") From d0e4d85efb1f4f2f1c5aebbebd79e5a67de5fdd6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 11:12:04 -0700 Subject: [PATCH 0120/1772] Remove the `_start` import. It isn't logically part of the `wasi_unstable` module. It's part of the platform-level ABI. --- proposals/filesystem/design/wasi_unstable/wasi_unstable.widl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl b/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl index 730f1c84f..6ec0e7d67 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl @@ -5,12 +5,9 @@ (use "typenames.wid") (module $wasi_unstable - ;; Linear memory used by the program. + ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) - ;; The program entry point. - (import "_start" (func)) - ;; Read command-line argument data. ;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") From cb91ccce320380b76884784242c810e9877e0288 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 11:13:56 -0700 Subject: [PATCH 0121/1772] Rename "$self" paramaters to "$fd" to be more descriptive. We're not currently using a method-oriented API, so instead of saying "self", say "fd", which is what these parameters are. --- .../design/wasi_unstable/wasi_unstable.widl | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.widl b/proposals/clocks/design/wasi_unstable/wasi_unstable.widl index 6ec0e7d67..2cb9cfffd 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.widl +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.widl @@ -62,7 +62,7 @@ ;; Provide file advisory information on a file descriptor. ;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") - (param $self $fd_t) + (param $fd $fd_t) (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. (param $len $filesize_t) ;; The length of the region to which the advisory applies. (param $advice $advice_t) ;; The advice. @@ -72,7 +72,7 @@ ;; Force the allocation of space in a file. ;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") - (param $self $fd_t) + (param $fd $fd_t) ;; The offset at which to start the allocation. (param $offset $filesize_t) ;; The length of the area that is allocated. @@ -83,21 +83,21 @@ ;; Close a file descriptor. ;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ) ;; Synchronize the data of a file to disk. ;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ) ;; Get the attributes of a file descriptor. ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file descriptor's attributes are stored. (result $fdstat_t) @@ -106,7 +106,7 @@ ;; Adjust the flags associated with a file descriptor. ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") - (param $self $fd_t) + (param $fd $fd_t) ;; The desired values of the file descriptor flags. (param $flags $fdflags) (result $error $errno_t) @@ -115,7 +115,7 @@ ;; Adjust the rights associated with a file descriptor. ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") - (param $self $fd_t) + (param $fd $fd_t) ;; The desired rights of the file descriptor. (param $fs_rights_base $rights_t) (param $fs_rights_inheriting $rights_t) @@ -124,7 +124,7 @@ ;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file's attributes are stored. (result $fs_rights_base $rights_t) @@ -133,7 +133,7 @@ ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. ;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") - (param $self $fd_t) + (param $fd $fd_t) ;; The desired file size. (param $st_size $filesize_t) (result $error $errno_t) @@ -142,7 +142,7 @@ ;; Adjust the timestamps of an open file or directory. ;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") - (param $self $fd_t) + (param $fd $fd_t) ;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) ;; The desired values of the data modification timestamp. @@ -155,7 +155,7 @@ ;; Read from a file descriptor, without using and updating the file descriptor's offset. ;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors in which to store data. (param $iovs $iovec_t_array) ;; The offset within the file at which to read. @@ -167,7 +167,7 @@ ;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the description is stored. (result $buf $prestat_t) @@ -175,7 +175,7 @@ ;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") - (param $self $fd_t) + (param $fd $fd_t) ;; A buffer into which to write the preopened directory name. (param $path string) (result $error $errno_t) @@ -184,7 +184,7 @@ ;; Write to a file descriptor, without using and updating the file descriptor's offset. ;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors from which to retrieve data. (param $iovs $iovec_t_array) ;; The offset within the file at which to write. @@ -197,7 +197,7 @@ ;; Read from a file descriptor. ;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_t_array) (result $error $errno_t) @@ -216,7 +216,7 @@ ;; read buffer size in case it's too small to fit a single large directory ;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") - (param $self $fd_t) + (param $fd $fd_t) ;; The buffer where directory entries are stored (param $buf data) ;; The location within the directory to start reading @@ -237,7 +237,7 @@ ;; This function provides a way to atomically renumber file descriptors, which ;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") - (param $self $fd_t) + (param $fd $fd_t) ;; The file descriptor to overwrite. (param $to $fd_t) (result $error $errno_t) @@ -246,7 +246,7 @@ ;; Move the offset of a file descriptor. ;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") - (param $self $fd_t) + (param $fd $fd_t) ;; The number of bytes to move. (param $offset $filedelta_t) ;; The base from which the offset is relative. @@ -259,14 +259,14 @@ ;; Synchronize the data and metadata of a file to disk. ;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ) ;; Return the current offset of a file descriptor. ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ;; The current offset of the file descriptor, relative to the start of the file. (result $offset $filesize_t) @@ -275,7 +275,7 @@ ;; Write to a file descriptor. ;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors from which to retrieve data. (param $iovs $iovec_t_array) (result $error $errno_t) @@ -286,7 +286,7 @@ ;; Create a directory. ;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") - (param $self $fd_t) + (param $fd $fd_t) ;; The path at which to create the directory. (param $path string) (result $error $errno_t) @@ -295,7 +295,7 @@ ;; Return the attributes of a file or directory. ;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") - (param $self $fd_t) + (param $fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) ;; The path of the file or directory to inspect. @@ -308,7 +308,7 @@ ;; Adjust the timestamps of a file or directory. ;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") - (param $self $fd_t) + (param $fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) ;; The path of the file or directory to operate on. @@ -325,7 +325,7 @@ ;; Create a hard link. ;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $self $fd_t) + (param $fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) ;; The source path from which to link. @@ -347,7 +347,7 @@ ;; ;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") - (param $self $fd_t) + (param $fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags_t) ;; The relative path of the file or directory to open, relative to the @@ -373,7 +373,7 @@ ;; Read the contents of a symbolic link. ;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") - (param $self $fd_t) + (param $fd $fd_t) ;; The path of the symbolic link from which to read. (param $path) ;; The buffer to which to write the contents of the symbolic link. @@ -387,7 +387,7 @@ ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") - (param $self $fd_t) + (param $fd $fd_t) ;; The path to a directory to remove. (param $path string) (result $error $errno_t) @@ -396,7 +396,7 @@ ;; Rename a file or directory. ;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") - (param $self $fd_t) + (param $fd $fd_t) ;; The source path of the file or directory to rename. (param $old_path string) ;; The working directory at which the resolution of the new path starts. @@ -409,7 +409,7 @@ ;; Create a symbolic link. ;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - (param $self $fd_t) + (param $fd $fd_t) ;; The contents of the symbolic link. (param $old_path string) ;; The destination path at which to create the symbolic link. @@ -422,7 +422,7 @@ ;; Return `__WASI_EISDIR` if the path refers to a directory. ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") - (param $self $fd_t) + (param $fd $fd_t) ;; The path to a file to unlink. (param $path string) (result $error $errno_t) @@ -479,7 +479,7 @@ ;; Note: This is similar to `recv` in POSIX, though it also supports reading ;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors to which to store data. (param $ri_data $iovec_t_array) ;; Message flags. @@ -495,7 +495,7 @@ ;; Note: This is similar to `send` in POSIX, though it also supports writing ;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors to which to retrieve data (param $si_data $ciovec_t_array) ;; Message flags. @@ -508,7 +508,7 @@ ;; Shut down socket send and receive channels. ;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") - (param $self $fd_t) + (param $fd $fd_t) ;; Which channels on the socket to shut down. (param $how $sdflags_t) (result $error $errno_t) From 22db3f570720224ddce077653da9fb6c47d0937d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 11:13:56 -0700 Subject: [PATCH 0122/1772] Rename "$self" paramaters to "$fd" to be more descriptive. We're not currently using a method-oriented API, so instead of saying "self", say "fd", which is what these parameters are. --- .../design/wasi_unstable/wasi_unstable.widl | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.widl b/proposals/random/design/wasi_unstable/wasi_unstable.widl index 6ec0e7d67..2cb9cfffd 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.widl +++ b/proposals/random/design/wasi_unstable/wasi_unstable.widl @@ -62,7 +62,7 @@ ;; Provide file advisory information on a file descriptor. ;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") - (param $self $fd_t) + (param $fd $fd_t) (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. (param $len $filesize_t) ;; The length of the region to which the advisory applies. (param $advice $advice_t) ;; The advice. @@ -72,7 +72,7 @@ ;; Force the allocation of space in a file. ;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") - (param $self $fd_t) + (param $fd $fd_t) ;; The offset at which to start the allocation. (param $offset $filesize_t) ;; The length of the area that is allocated. @@ -83,21 +83,21 @@ ;; Close a file descriptor. ;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ) ;; Synchronize the data of a file to disk. ;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ) ;; Get the attributes of a file descriptor. ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file descriptor's attributes are stored. (result $fdstat_t) @@ -106,7 +106,7 @@ ;; Adjust the flags associated with a file descriptor. ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") - (param $self $fd_t) + (param $fd $fd_t) ;; The desired values of the file descriptor flags. (param $flags $fdflags) (result $error $errno_t) @@ -115,7 +115,7 @@ ;; Adjust the rights associated with a file descriptor. ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") - (param $self $fd_t) + (param $fd $fd_t) ;; The desired rights of the file descriptor. (param $fs_rights_base $rights_t) (param $fs_rights_inheriting $rights_t) @@ -124,7 +124,7 @@ ;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file's attributes are stored. (result $fs_rights_base $rights_t) @@ -133,7 +133,7 @@ ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. ;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") - (param $self $fd_t) + (param $fd $fd_t) ;; The desired file size. (param $st_size $filesize_t) (result $error $errno_t) @@ -142,7 +142,7 @@ ;; Adjust the timestamps of an open file or directory. ;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") - (param $self $fd_t) + (param $fd $fd_t) ;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) ;; The desired values of the data modification timestamp. @@ -155,7 +155,7 @@ ;; Read from a file descriptor, without using and updating the file descriptor's offset. ;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors in which to store data. (param $iovs $iovec_t_array) ;; The offset within the file at which to read. @@ -167,7 +167,7 @@ ;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the description is stored. (result $buf $prestat_t) @@ -175,7 +175,7 @@ ;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") - (param $self $fd_t) + (param $fd $fd_t) ;; A buffer into which to write the preopened directory name. (param $path string) (result $error $errno_t) @@ -184,7 +184,7 @@ ;; Write to a file descriptor, without using and updating the file descriptor's offset. ;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors from which to retrieve data. (param $iovs $iovec_t_array) ;; The offset within the file at which to write. @@ -197,7 +197,7 @@ ;; Read from a file descriptor. ;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_t_array) (result $error $errno_t) @@ -216,7 +216,7 @@ ;; read buffer size in case it's too small to fit a single large directory ;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") - (param $self $fd_t) + (param $fd $fd_t) ;; The buffer where directory entries are stored (param $buf data) ;; The location within the directory to start reading @@ -237,7 +237,7 @@ ;; This function provides a way to atomically renumber file descriptors, which ;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") - (param $self $fd_t) + (param $fd $fd_t) ;; The file descriptor to overwrite. (param $to $fd_t) (result $error $errno_t) @@ -246,7 +246,7 @@ ;; Move the offset of a file descriptor. ;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") - (param $self $fd_t) + (param $fd $fd_t) ;; The number of bytes to move. (param $offset $filedelta_t) ;; The base from which the offset is relative. @@ -259,14 +259,14 @@ ;; Synchronize the data and metadata of a file to disk. ;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ) ;; Return the current offset of a file descriptor. ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ;; The current offset of the file descriptor, relative to the start of the file. (result $offset $filesize_t) @@ -275,7 +275,7 @@ ;; Write to a file descriptor. ;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors from which to retrieve data. (param $iovs $iovec_t_array) (result $error $errno_t) @@ -286,7 +286,7 @@ ;; Create a directory. ;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") - (param $self $fd_t) + (param $fd $fd_t) ;; The path at which to create the directory. (param $path string) (result $error $errno_t) @@ -295,7 +295,7 @@ ;; Return the attributes of a file or directory. ;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") - (param $self $fd_t) + (param $fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) ;; The path of the file or directory to inspect. @@ -308,7 +308,7 @@ ;; Adjust the timestamps of a file or directory. ;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") - (param $self $fd_t) + (param $fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) ;; The path of the file or directory to operate on. @@ -325,7 +325,7 @@ ;; Create a hard link. ;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $self $fd_t) + (param $fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) ;; The source path from which to link. @@ -347,7 +347,7 @@ ;; ;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") - (param $self $fd_t) + (param $fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags_t) ;; The relative path of the file or directory to open, relative to the @@ -373,7 +373,7 @@ ;; Read the contents of a symbolic link. ;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") - (param $self $fd_t) + (param $fd $fd_t) ;; The path of the symbolic link from which to read. (param $path) ;; The buffer to which to write the contents of the symbolic link. @@ -387,7 +387,7 @@ ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") - (param $self $fd_t) + (param $fd $fd_t) ;; The path to a directory to remove. (param $path string) (result $error $errno_t) @@ -396,7 +396,7 @@ ;; Rename a file or directory. ;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") - (param $self $fd_t) + (param $fd $fd_t) ;; The source path of the file or directory to rename. (param $old_path string) ;; The working directory at which the resolution of the new path starts. @@ -409,7 +409,7 @@ ;; Create a symbolic link. ;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - (param $self $fd_t) + (param $fd $fd_t) ;; The contents of the symbolic link. (param $old_path string) ;; The destination path at which to create the symbolic link. @@ -422,7 +422,7 @@ ;; Return `__WASI_EISDIR` if the path refers to a directory. ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") - (param $self $fd_t) + (param $fd $fd_t) ;; The path to a file to unlink. (param $path string) (result $error $errno_t) @@ -479,7 +479,7 @@ ;; Note: This is similar to `recv` in POSIX, though it also supports reading ;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors to which to store data. (param $ri_data $iovec_t_array) ;; Message flags. @@ -495,7 +495,7 @@ ;; Note: This is similar to `send` in POSIX, though it also supports writing ;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors to which to retrieve data (param $si_data $ciovec_t_array) ;; Message flags. @@ -508,7 +508,7 @@ ;; Shut down socket send and receive channels. ;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") - (param $self $fd_t) + (param $fd $fd_t) ;; Which channels on the socket to shut down. (param $how $sdflags_t) (result $error $errno_t) From cbde518bda278b7658df5adb51628d8bbf5ac4e6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 11:13:56 -0700 Subject: [PATCH 0123/1772] Rename "$self" paramaters to "$fd" to be more descriptive. We're not currently using a method-oriented API, so instead of saying "self", say "fd", which is what these parameters are. --- .../design/wasi_unstable/wasi_unstable.widl | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl b/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl index 6ec0e7d67..2cb9cfffd 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl @@ -62,7 +62,7 @@ ;; Provide file advisory information on a file descriptor. ;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") - (param $self $fd_t) + (param $fd $fd_t) (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. (param $len $filesize_t) ;; The length of the region to which the advisory applies. (param $advice $advice_t) ;; The advice. @@ -72,7 +72,7 @@ ;; Force the allocation of space in a file. ;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") - (param $self $fd_t) + (param $fd $fd_t) ;; The offset at which to start the allocation. (param $offset $filesize_t) ;; The length of the area that is allocated. @@ -83,21 +83,21 @@ ;; Close a file descriptor. ;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ) ;; Synchronize the data of a file to disk. ;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ) ;; Get the attributes of a file descriptor. ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file descriptor's attributes are stored. (result $fdstat_t) @@ -106,7 +106,7 @@ ;; Adjust the flags associated with a file descriptor. ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") - (param $self $fd_t) + (param $fd $fd_t) ;; The desired values of the file descriptor flags. (param $flags $fdflags) (result $error $errno_t) @@ -115,7 +115,7 @@ ;; Adjust the rights associated with a file descriptor. ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") - (param $self $fd_t) + (param $fd $fd_t) ;; The desired rights of the file descriptor. (param $fs_rights_base $rights_t) (param $fs_rights_inheriting $rights_t) @@ -124,7 +124,7 @@ ;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file's attributes are stored. (result $fs_rights_base $rights_t) @@ -133,7 +133,7 @@ ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. ;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") - (param $self $fd_t) + (param $fd $fd_t) ;; The desired file size. (param $st_size $filesize_t) (result $error $errno_t) @@ -142,7 +142,7 @@ ;; Adjust the timestamps of an open file or directory. ;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") - (param $self $fd_t) + (param $fd $fd_t) ;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) ;; The desired values of the data modification timestamp. @@ -155,7 +155,7 @@ ;; Read from a file descriptor, without using and updating the file descriptor's offset. ;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors in which to store data. (param $iovs $iovec_t_array) ;; The offset within the file at which to read. @@ -167,7 +167,7 @@ ;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the description is stored. (result $buf $prestat_t) @@ -175,7 +175,7 @@ ;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") - (param $self $fd_t) + (param $fd $fd_t) ;; A buffer into which to write the preopened directory name. (param $path string) (result $error $errno_t) @@ -184,7 +184,7 @@ ;; Write to a file descriptor, without using and updating the file descriptor's offset. ;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors from which to retrieve data. (param $iovs $iovec_t_array) ;; The offset within the file at which to write. @@ -197,7 +197,7 @@ ;; Read from a file descriptor. ;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_t_array) (result $error $errno_t) @@ -216,7 +216,7 @@ ;; read buffer size in case it's too small to fit a single large directory ;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") - (param $self $fd_t) + (param $fd $fd_t) ;; The buffer where directory entries are stored (param $buf data) ;; The location within the directory to start reading @@ -237,7 +237,7 @@ ;; This function provides a way to atomically renumber file descriptors, which ;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") - (param $self $fd_t) + (param $fd $fd_t) ;; The file descriptor to overwrite. (param $to $fd_t) (result $error $errno_t) @@ -246,7 +246,7 @@ ;; Move the offset of a file descriptor. ;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") - (param $self $fd_t) + (param $fd $fd_t) ;; The number of bytes to move. (param $offset $filedelta_t) ;; The base from which the offset is relative. @@ -259,14 +259,14 @@ ;; Synchronize the data and metadata of a file to disk. ;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ) ;; Return the current offset of a file descriptor. ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") - (param $self $fd_t) + (param $fd $fd_t) (result $error $errno_t) ;; The current offset of the file descriptor, relative to the start of the file. (result $offset $filesize_t) @@ -275,7 +275,7 @@ ;; Write to a file descriptor. ;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors from which to retrieve data. (param $iovs $iovec_t_array) (result $error $errno_t) @@ -286,7 +286,7 @@ ;; Create a directory. ;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") - (param $self $fd_t) + (param $fd $fd_t) ;; The path at which to create the directory. (param $path string) (result $error $errno_t) @@ -295,7 +295,7 @@ ;; Return the attributes of a file or directory. ;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") - (param $self $fd_t) + (param $fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) ;; The path of the file or directory to inspect. @@ -308,7 +308,7 @@ ;; Adjust the timestamps of a file or directory. ;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") - (param $self $fd_t) + (param $fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) ;; The path of the file or directory to operate on. @@ -325,7 +325,7 @@ ;; Create a hard link. ;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $self $fd_t) + (param $fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) ;; The source path from which to link. @@ -347,7 +347,7 @@ ;; ;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") - (param $self $fd_t) + (param $fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags_t) ;; The relative path of the file or directory to open, relative to the @@ -373,7 +373,7 @@ ;; Read the contents of a symbolic link. ;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") - (param $self $fd_t) + (param $fd $fd_t) ;; The path of the symbolic link from which to read. (param $path) ;; The buffer to which to write the contents of the symbolic link. @@ -387,7 +387,7 @@ ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") - (param $self $fd_t) + (param $fd $fd_t) ;; The path to a directory to remove. (param $path string) (result $error $errno_t) @@ -396,7 +396,7 @@ ;; Rename a file or directory. ;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") - (param $self $fd_t) + (param $fd $fd_t) ;; The source path of the file or directory to rename. (param $old_path string) ;; The working directory at which the resolution of the new path starts. @@ -409,7 +409,7 @@ ;; Create a symbolic link. ;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - (param $self $fd_t) + (param $fd $fd_t) ;; The contents of the symbolic link. (param $old_path string) ;; The destination path at which to create the symbolic link. @@ -422,7 +422,7 @@ ;; Return `__WASI_EISDIR` if the path refers to a directory. ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") - (param $self $fd_t) + (param $fd $fd_t) ;; The path to a file to unlink. (param $path string) (result $error $errno_t) @@ -479,7 +479,7 @@ ;; Note: This is similar to `recv` in POSIX, though it also supports reading ;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors to which to store data. (param $ri_data $iovec_t_array) ;; Message flags. @@ -495,7 +495,7 @@ ;; Note: This is similar to `send` in POSIX, though it also supports writing ;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") - (param $self $fd_t) + (param $fd $fd_t) ;; List of scatter/gather vectors to which to retrieve data (param $si_data $ciovec_t_array) ;; Message flags. @@ -508,7 +508,7 @@ ;; Shut down socket send and receive channels. ;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") - (param $self $fd_t) + (param $fd $fd_t) ;; Which channels on the socket to shut down. (param $how $sdflags_t) (result $error $errno_t) From bf8ea690ae78d3726176b3589ec5b4b2db5b908f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 15:23:56 -0700 Subject: [PATCH 0124/1772] Give names to union types. --- .../design/wasi_unstable/typenames.widl | 80 ++++++++++--------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/proposals/clocks/design/wasi_unstable/typenames.widl b/proposals/clocks/design/wasi_unstable/typenames.widl index df97290e0..53b01bde0 100644 --- a/proposals/clocks/design/wasi_unstable/typenames.widl +++ b/proposals/clocks/design/wasi_unstable/typenames.widl @@ -488,17 +488,21 @@ (field $error $errno_t) ;; The type of the event that occurred. (field $type $eventtype_t) - (field $u - (union - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (struct - ;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) - ;; The state of the file descriptor. - (field $flags $eventrwflags_t) - ) - ) + ;; The contents of the event. + (field $u $event_u)) + ) +) + +;; The contents of an $event_t. +(typename $event_u + (union + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + (field $fd_readwrite + (struct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) ) ) ) @@ -549,31 +553,35 @@ (field $userdata $userdata_t) ;; The type of the event to which to subscribe. (field $type $eventtype_t) - (field $u - (union - ;; When type is `__WASI_EVENTTYPE_CLOCK`: - (field $clock - (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) - ;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. - (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative - (field $precision $timestamp_t) - ) - ) - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) - ) - ) + ;; The contents of the subscription. + (field $u $subscription_u) + ) +) + +;; The contents of a $subscription_t. +(typename $subscription_u + (union + ;; When type is `__WASI_EVENTTYPE_CLOCK`: + (field $clock + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) + ) + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + (field $fd_readwrite + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) ) ) ) From dbec9f4f3a26745cd4501cc1f43d65a6f0c1288e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 15:23:56 -0700 Subject: [PATCH 0125/1772] Give names to union types. --- .../design/wasi_unstable/typenames.widl | 80 ++++++++++--------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/proposals/random/design/wasi_unstable/typenames.widl b/proposals/random/design/wasi_unstable/typenames.widl index df97290e0..53b01bde0 100644 --- a/proposals/random/design/wasi_unstable/typenames.widl +++ b/proposals/random/design/wasi_unstable/typenames.widl @@ -488,17 +488,21 @@ (field $error $errno_t) ;; The type of the event that occurred. (field $type $eventtype_t) - (field $u - (union - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (struct - ;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) - ;; The state of the file descriptor. - (field $flags $eventrwflags_t) - ) - ) + ;; The contents of the event. + (field $u $event_u)) + ) +) + +;; The contents of an $event_t. +(typename $event_u + (union + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + (field $fd_readwrite + (struct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) ) ) ) @@ -549,31 +553,35 @@ (field $userdata $userdata_t) ;; The type of the event to which to subscribe. (field $type $eventtype_t) - (field $u - (union - ;; When type is `__WASI_EVENTTYPE_CLOCK`: - (field $clock - (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) - ;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. - (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative - (field $precision $timestamp_t) - ) - ) - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) - ) - ) + ;; The contents of the subscription. + (field $u $subscription_u) + ) +) + +;; The contents of a $subscription_t. +(typename $subscription_u + (union + ;; When type is `__WASI_EVENTTYPE_CLOCK`: + (field $clock + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) + ) + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + (field $fd_readwrite + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) ) ) ) From 5ad4988aa899d06edc60ec12c595da90cf9050ad Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 15:23:56 -0700 Subject: [PATCH 0126/1772] Give names to union types. --- .../design/wasi_unstable/typenames.widl | 80 ++++++++++--------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/proposals/filesystem/design/wasi_unstable/typenames.widl b/proposals/filesystem/design/wasi_unstable/typenames.widl index df97290e0..53b01bde0 100644 --- a/proposals/filesystem/design/wasi_unstable/typenames.widl +++ b/proposals/filesystem/design/wasi_unstable/typenames.widl @@ -488,17 +488,21 @@ (field $error $errno_t) ;; The type of the event that occurred. (field $type $eventtype_t) - (field $u - (union - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (struct - ;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) - ;; The state of the file descriptor. - (field $flags $eventrwflags_t) - ) - ) + ;; The contents of the event. + (field $u $event_u)) + ) +) + +;; The contents of an $event_t. +(typename $event_u + (union + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + (field $fd_readwrite + (struct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) ) ) ) @@ -549,31 +553,35 @@ (field $userdata $userdata_t) ;; The type of the event to which to subscribe. (field $type $eventtype_t) - (field $u - (union - ;; When type is `__WASI_EVENTTYPE_CLOCK`: - (field $clock - (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) - ;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. - (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative - (field $precision $timestamp_t) - ) - ) - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) - ) - ) + ;; The contents of the subscription. + (field $u $subscription_u) + ) +) + +;; The contents of a $subscription_t. +(typename $subscription_u + (union + ;; When type is `__WASI_EVENTTYPE_CLOCK`: + (field $clock + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) + ) + ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + (field $fd_readwrite + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) ) ) ) From 773f8cc1f37b846e5df8e27c35bb55e5524d62fd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 15:33:18 -0700 Subject: [PATCH 0127/1772] Give names to struct types. --- .../design/wasi_unstable/typenames.widl | 69 +++++++++++-------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/proposals/clocks/design/wasi_unstable/typenames.widl b/proposals/clocks/design/wasi_unstable/typenames.widl index 53b01bde0..90aac9668 100644 --- a/proposals/clocks/design/wasi_unstable/typenames.widl +++ b/proposals/clocks/design/wasi_unstable/typenames.widl @@ -497,14 +497,18 @@ (typename $event_u (union ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (struct - ;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) - ;; The state of the file descriptor. - (field $flags $eventrwflags_t) - ) - ) + (field $fd_readwrite $event_fd_readwrite_t) + ) +) + +;; The contents of an $event_t when type is `__WASI_EVENTTYPE_FD_READ` or +;; `__WASI_EVENTTYPE_FD_WRITE`. +(typename $event_fd_readwrite_t + (struct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) ) ) @@ -562,28 +566,35 @@ (typename $subscription_u (union ;; When type is `__WASI_EVENTTYPE_CLOCK`: - (field $clock - (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) - ;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. - (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative - (field $precision $timestamp_t) - ) - ) + (field $clock $subscription_clock_t) ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) - ) - ) + (field $fd_readwrite $subscription_fd_readwrite_t) + ) +) + +;; The contents of a $subscription_t when type is `__WASI_EVENTTYPE_CLOCK`. +(typename $subscription_clock_t + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) +) + +;; The contents of a $subscription_t when type is type is +;; `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. +(typename $subscription_fd_readwrite_t + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) ) ) From 1d10951605c5b7d741cd2230187ed4a75f22b34e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 15:33:18 -0700 Subject: [PATCH 0128/1772] Give names to struct types. --- .../design/wasi_unstable/typenames.widl | 69 +++++++++++-------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/proposals/random/design/wasi_unstable/typenames.widl b/proposals/random/design/wasi_unstable/typenames.widl index 53b01bde0..90aac9668 100644 --- a/proposals/random/design/wasi_unstable/typenames.widl +++ b/proposals/random/design/wasi_unstable/typenames.widl @@ -497,14 +497,18 @@ (typename $event_u (union ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (struct - ;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) - ;; The state of the file descriptor. - (field $flags $eventrwflags_t) - ) - ) + (field $fd_readwrite $event_fd_readwrite_t) + ) +) + +;; The contents of an $event_t when type is `__WASI_EVENTTYPE_FD_READ` or +;; `__WASI_EVENTTYPE_FD_WRITE`. +(typename $event_fd_readwrite_t + (struct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) ) ) @@ -562,28 +566,35 @@ (typename $subscription_u (union ;; When type is `__WASI_EVENTTYPE_CLOCK`: - (field $clock - (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) - ;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. - (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative - (field $precision $timestamp_t) - ) - ) + (field $clock $subscription_clock_t) ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) - ) - ) + (field $fd_readwrite $subscription_fd_readwrite_t) + ) +) + +;; The contents of a $subscription_t when type is `__WASI_EVENTTYPE_CLOCK`. +(typename $subscription_clock_t + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) +) + +;; The contents of a $subscription_t when type is type is +;; `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. +(typename $subscription_fd_readwrite_t + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) ) ) From a61f517cf19db028b2c68b20cf5bbbd67ec88358 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 15:33:18 -0700 Subject: [PATCH 0129/1772] Give names to struct types. --- .../design/wasi_unstable/typenames.widl | 69 +++++++++++-------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/proposals/filesystem/design/wasi_unstable/typenames.widl b/proposals/filesystem/design/wasi_unstable/typenames.widl index 53b01bde0..90aac9668 100644 --- a/proposals/filesystem/design/wasi_unstable/typenames.widl +++ b/proposals/filesystem/design/wasi_unstable/typenames.widl @@ -497,14 +497,18 @@ (typename $event_u (union ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (struct - ;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) - ;; The state of the file descriptor. - (field $flags $eventrwflags_t) - ) - ) + (field $fd_readwrite $event_fd_readwrite_t) + ) +) + +;; The contents of an $event_t when type is `__WASI_EVENTTYPE_FD_READ` or +;; `__WASI_EVENTTYPE_FD_WRITE`. +(typename $event_fd_readwrite_t + (struct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) ) ) @@ -562,28 +566,35 @@ (typename $subscription_u (union ;; When type is `__WASI_EVENTTYPE_CLOCK`: - (field $clock - (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) - ;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. - (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative - (field $precision $timestamp_t) - ) - ) + (field $clock $subscription_clock_t) ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: - (field $fd_readwrite - (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) - ) - ) + (field $fd_readwrite $subscription_fd_readwrite_t) + ) +) + +;; The contents of a $subscription_t when type is `__WASI_EVENTTYPE_CLOCK`. +(typename $subscription_clock_t + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) +) + +;; The contents of a $subscription_t when type is type is +;; `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. +(typename $subscription_fd_readwrite_t + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) ) ) From e1cfd087b9f236005d2a3e23da05c69ae0ef9afd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 16:55:50 -0700 Subject: [PATCH 0130/1772] Rename .widl to .witx. --- .../design/wasi_unstable/{typenames.widl => typenames.witx} | 0 .../wasi_unstable/{wasi_unstable.widl => wasi_unstable.witx} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename proposals/clocks/design/wasi_unstable/{typenames.widl => typenames.witx} (100%) rename proposals/clocks/design/wasi_unstable/{wasi_unstable.widl => wasi_unstable.witx} (100%) diff --git a/proposals/clocks/design/wasi_unstable/typenames.widl b/proposals/clocks/design/wasi_unstable/typenames.witx similarity index 100% rename from proposals/clocks/design/wasi_unstable/typenames.widl rename to proposals/clocks/design/wasi_unstable/typenames.witx diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.widl b/proposals/clocks/design/wasi_unstable/wasi_unstable.witx similarity index 100% rename from proposals/clocks/design/wasi_unstable/wasi_unstable.widl rename to proposals/clocks/design/wasi_unstable/wasi_unstable.witx From 57f9f23c5c0c9db1e8d8c4a2380b5c46253bf48c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 16:55:50 -0700 Subject: [PATCH 0131/1772] Rename .widl to .witx. --- .../design/wasi_unstable/{typenames.widl => typenames.witx} | 0 .../wasi_unstable/{wasi_unstable.widl => wasi_unstable.witx} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename proposals/random/design/wasi_unstable/{typenames.widl => typenames.witx} (100%) rename proposals/random/design/wasi_unstable/{wasi_unstable.widl => wasi_unstable.witx} (100%) diff --git a/proposals/random/design/wasi_unstable/typenames.widl b/proposals/random/design/wasi_unstable/typenames.witx similarity index 100% rename from proposals/random/design/wasi_unstable/typenames.widl rename to proposals/random/design/wasi_unstable/typenames.witx diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.widl b/proposals/random/design/wasi_unstable/wasi_unstable.witx similarity index 100% rename from proposals/random/design/wasi_unstable/wasi_unstable.widl rename to proposals/random/design/wasi_unstable/wasi_unstable.witx From 6cd8f8a1f1625d5b8735f16d8e8e6c63065256da Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 16:55:50 -0700 Subject: [PATCH 0132/1772] Rename .widl to .witx. --- .../design/wasi_unstable/{typenames.widl => typenames.witx} | 0 .../wasi_unstable/{wasi_unstable.widl => wasi_unstable.witx} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename proposals/filesystem/design/wasi_unstable/{typenames.widl => typenames.witx} (100%) rename proposals/filesystem/design/wasi_unstable/{wasi_unstable.widl => wasi_unstable.witx} (100%) diff --git a/proposals/filesystem/design/wasi_unstable/typenames.widl b/proposals/filesystem/design/wasi_unstable/typenames.witx similarity index 100% rename from proposals/filesystem/design/wasi_unstable/typenames.widl rename to proposals/filesystem/design/wasi_unstable/typenames.witx diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.widl b/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx similarity index 100% rename from proposals/filesystem/design/wasi_unstable/wasi_unstable.widl rename to proposals/filesystem/design/wasi_unstable/wasi_unstable.witx From 5c53b475a8b260884e49e2a8b10bab2136cfbd51 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 17:10:34 -0700 Subject: [PATCH 0133/1772] Fix extra close paren. --- proposals/clocks/design/wasi_unstable/typenames.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/design/wasi_unstable/typenames.witx b/proposals/clocks/design/wasi_unstable/typenames.witx index 90aac9668..06df21774 100644 --- a/proposals/clocks/design/wasi_unstable/typenames.witx +++ b/proposals/clocks/design/wasi_unstable/typenames.witx @@ -489,7 +489,7 @@ ;; The type of the event that occurred. (field $type $eventtype_t) ;; The contents of the event. - (field $u $event_u)) + (field $u $event_u) ) ) From fb0cff01ede68ab0fd40094f16c02274b5ecc631 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 17:10:34 -0700 Subject: [PATCH 0134/1772] Fix extra close paren. --- proposals/random/design/wasi_unstable/typenames.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/design/wasi_unstable/typenames.witx b/proposals/random/design/wasi_unstable/typenames.witx index 90aac9668..06df21774 100644 --- a/proposals/random/design/wasi_unstable/typenames.witx +++ b/proposals/random/design/wasi_unstable/typenames.witx @@ -489,7 +489,7 @@ ;; The type of the event that occurred. (field $type $eventtype_t) ;; The contents of the event. - (field $u $event_u)) + (field $u $event_u) ) ) From e1e8359fc3faae7b7ba8fc285c9c3b46c3779b7c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 4 Sep 2019 17:10:34 -0700 Subject: [PATCH 0135/1772] Fix extra close paren. --- proposals/filesystem/design/wasi_unstable/typenames.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/design/wasi_unstable/typenames.witx b/proposals/filesystem/design/wasi_unstable/typenames.witx index 90aac9668..06df21774 100644 --- a/proposals/filesystem/design/wasi_unstable/typenames.witx +++ b/proposals/filesystem/design/wasi_unstable/typenames.witx @@ -489,7 +489,7 @@ ;; The type of the event that occurred. (field $type $eventtype_t) ;; The contents of the event. - (field $u $event_u)) + (field $u $event_u) ) ) From fe143d5f0e6a7a8c1e0c5a70b9c41ac647170fb2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 08:57:45 -0700 Subject: [PATCH 0136/1772] Use ciovec_t for fd_write and fd_pwrite. --- proposals/clocks/design/wasi_unstable/wasi_unstable.witx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.witx b/proposals/clocks/design/wasi_unstable/wasi_unstable.witx index 2cb9cfffd..54ea07651 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.witx @@ -186,7 +186,7 @@ (@interface func (export "fd_pwrite") (param $fd $fd_t) ;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $iovec_t_array) + (param $iovs $ciovec_t_array) ;; The offset within the file at which to write. (param $offset $filesize_t) (result $error $errno_t) @@ -277,7 +277,7 @@ (@interface func (export "fd_write") (param $fd $fd_t) ;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $iovec_t_array) + (param $iovs $ciovec_t_array) (result $error $errno_t) ;; The number of bytes written. (result $nwritten $size_t) From 640af1393d9cbd5d853dec00e4960c9cd5e26361 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 08:57:45 -0700 Subject: [PATCH 0137/1772] Use ciovec_t for fd_write and fd_pwrite. --- proposals/random/design/wasi_unstable/wasi_unstable.witx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.witx b/proposals/random/design/wasi_unstable/wasi_unstable.witx index 2cb9cfffd..54ea07651 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/random/design/wasi_unstable/wasi_unstable.witx @@ -186,7 +186,7 @@ (@interface func (export "fd_pwrite") (param $fd $fd_t) ;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $iovec_t_array) + (param $iovs $ciovec_t_array) ;; The offset within the file at which to write. (param $offset $filesize_t) (result $error $errno_t) @@ -277,7 +277,7 @@ (@interface func (export "fd_write") (param $fd $fd_t) ;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $iovec_t_array) + (param $iovs $ciovec_t_array) (result $error $errno_t) ;; The number of bytes written. (result $nwritten $size_t) From 934a954656e920202761e043f0d0db40305bf9cb Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 08:57:45 -0700 Subject: [PATCH 0138/1772] Use ciovec_t for fd_write and fd_pwrite. --- proposals/filesystem/design/wasi_unstable/wasi_unstable.witx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx b/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx index 2cb9cfffd..54ea07651 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx @@ -186,7 +186,7 @@ (@interface func (export "fd_pwrite") (param $fd $fd_t) ;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $iovec_t_array) + (param $iovs $ciovec_t_array) ;; The offset within the file at which to write. (param $offset $filesize_t) (result $error $errno_t) @@ -277,7 +277,7 @@ (@interface func (export "fd_write") (param $fd $fd_t) ;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $iovec_t_array) + (param $iovs $ciovec_t_array) (result $error $errno_t) ;; The number of bytes written. (result $nwritten $size_t) From 835d1935f713c6dcaf1c685de17de73d97e0010c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 09:00:32 -0700 Subject: [PATCH 0139/1772] Don't use interface types to pass mutable buffers. This adds new constructs, (@witx pointer T), and (@witx const_pointer T), and uses them to describe raw pointers to linear memory buffers. For now, these can be treated essentially the same as $uintptr_t, though in the future we may do something more sophisticated. --- .../design/wasi_unstable/typenames.witx | 6 ++--- .../design/wasi_unstable/wasi_unstable.witx | 22 ++++++++++++------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/proposals/clocks/design/wasi_unstable/typenames.witx b/proposals/clocks/design/wasi_unstable/typenames.witx index 06df21774..87ee29d67 100644 --- a/proposals/clocks/design/wasi_unstable/typenames.witx +++ b/proposals/clocks/design/wasi_unstable/typenames.witx @@ -3,8 +3,6 @@ ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). (typename $size_t u32) -(typename $uintptr_t u32) -(typename $string_array (array string)) ;; Non-negative file size or length of a region within a file. (typename $filesize_t u64) @@ -283,7 +281,7 @@ (typename $iovec_t (struct ;; The address and length of the buffer to be filled. - (field $buf $uintptr_t) + (field $buf (@witx pointer u8)) (field $buf_len $size_t) ) ) @@ -292,7 +290,7 @@ (typename $ciovec_t (struct ;; The address and length of the buffer to be written. - (field $buf $uintptr_t) + (field $buf (@witx const_pointer u8)) (field $buf_len $size_t) ) ) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.witx b/proposals/clocks/design/wasi_unstable/wasi_unstable.witx index 54ea07651..23f8931ed 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.witx @@ -11,8 +11,9 @@ ;; Read command-line argument data. ;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") + (param $argv (@witx pointer (@witx pointer u8))) + (param $argv_buf (@witx pointer u8)) (result $error $errno_t) - (result $argv $string_array) ) ;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") @@ -26,8 +27,9 @@ ;; Read environment variable data. ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. (@interface func (export "environ_get") + (param $environ (@witx pointer (@witx pointer u8))) + (param $environ_buf (@witx pointer u8)) (result $error $errno_t) - (result $argv $string_array) ) ;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") @@ -177,7 +179,8 @@ (@interface func (export "fd_prestat_dir_name") (param $fd $fd_t) ;; A buffer into which to write the preopened directory name. - (param $path string) + (param $path (@witx pointer u8)) + (param $path_len $size_t) (result $error $errno_t) ) @@ -218,7 +221,8 @@ (@interface func (export "fd_readdir") (param $fd $fd_t) ;; The buffer where directory entries are stored - (param $buf data) + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) ;; The location within the directory to start reading (param $cookie $dircookie_t) (result $error $errno_t) @@ -377,7 +381,8 @@ ;; The path of the symbolic link from which to read. (param $path) ;; The buffer to which to write the contents of the symbolic link. - (param $buf string) + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) (result $error $errno_t) ;; The number of bytes placed in the buffer. (result $bufused $size_t) @@ -431,9 +436,9 @@ ;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;; The events to which to subscribe. - (param $in $subscription_t) + (param $in (const_pointer $subscription_t)) ;; The events that have occurred. - (param $out $event_t) + (param $out (@witx pointer $event_t)) ;; Both the number of subscriptions and events. (param $nsubscriptions $size_t) (result $error $errno_t) @@ -471,7 +476,8 @@ ;; number generator, rather than to provide the random data directly. (@interface func (export "random_get") ;; The buffer to fill with random data. - (param $buf data) + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) (result $error $errno_t) ) From 31506909997079da57215c807c3414a9a32f9237 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 09:00:32 -0700 Subject: [PATCH 0140/1772] Don't use interface types to pass mutable buffers. This adds new constructs, (@witx pointer T), and (@witx const_pointer T), and uses them to describe raw pointers to linear memory buffers. For now, these can be treated essentially the same as $uintptr_t, though in the future we may do something more sophisticated. --- .../design/wasi_unstable/typenames.witx | 6 ++--- .../design/wasi_unstable/wasi_unstable.witx | 22 ++++++++++++------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/proposals/random/design/wasi_unstable/typenames.witx b/proposals/random/design/wasi_unstable/typenames.witx index 06df21774..87ee29d67 100644 --- a/proposals/random/design/wasi_unstable/typenames.witx +++ b/proposals/random/design/wasi_unstable/typenames.witx @@ -3,8 +3,6 @@ ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). (typename $size_t u32) -(typename $uintptr_t u32) -(typename $string_array (array string)) ;; Non-negative file size or length of a region within a file. (typename $filesize_t u64) @@ -283,7 +281,7 @@ (typename $iovec_t (struct ;; The address and length of the buffer to be filled. - (field $buf $uintptr_t) + (field $buf (@witx pointer u8)) (field $buf_len $size_t) ) ) @@ -292,7 +290,7 @@ (typename $ciovec_t (struct ;; The address and length of the buffer to be written. - (field $buf $uintptr_t) + (field $buf (@witx const_pointer u8)) (field $buf_len $size_t) ) ) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.witx b/proposals/random/design/wasi_unstable/wasi_unstable.witx index 54ea07651..23f8931ed 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/random/design/wasi_unstable/wasi_unstable.witx @@ -11,8 +11,9 @@ ;; Read command-line argument data. ;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") + (param $argv (@witx pointer (@witx pointer u8))) + (param $argv_buf (@witx pointer u8)) (result $error $errno_t) - (result $argv $string_array) ) ;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") @@ -26,8 +27,9 @@ ;; Read environment variable data. ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. (@interface func (export "environ_get") + (param $environ (@witx pointer (@witx pointer u8))) + (param $environ_buf (@witx pointer u8)) (result $error $errno_t) - (result $argv $string_array) ) ;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") @@ -177,7 +179,8 @@ (@interface func (export "fd_prestat_dir_name") (param $fd $fd_t) ;; A buffer into which to write the preopened directory name. - (param $path string) + (param $path (@witx pointer u8)) + (param $path_len $size_t) (result $error $errno_t) ) @@ -218,7 +221,8 @@ (@interface func (export "fd_readdir") (param $fd $fd_t) ;; The buffer where directory entries are stored - (param $buf data) + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) ;; The location within the directory to start reading (param $cookie $dircookie_t) (result $error $errno_t) @@ -377,7 +381,8 @@ ;; The path of the symbolic link from which to read. (param $path) ;; The buffer to which to write the contents of the symbolic link. - (param $buf string) + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) (result $error $errno_t) ;; The number of bytes placed in the buffer. (result $bufused $size_t) @@ -431,9 +436,9 @@ ;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;; The events to which to subscribe. - (param $in $subscription_t) + (param $in (const_pointer $subscription_t)) ;; The events that have occurred. - (param $out $event_t) + (param $out (@witx pointer $event_t)) ;; Both the number of subscriptions and events. (param $nsubscriptions $size_t) (result $error $errno_t) @@ -471,7 +476,8 @@ ;; number generator, rather than to provide the random data directly. (@interface func (export "random_get") ;; The buffer to fill with random data. - (param $buf data) + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) (result $error $errno_t) ) From 2d2db24bb5dbd5ee782d11083a22734652548d90 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 09:00:32 -0700 Subject: [PATCH 0141/1772] Don't use interface types to pass mutable buffers. This adds new constructs, (@witx pointer T), and (@witx const_pointer T), and uses them to describe raw pointers to linear memory buffers. For now, these can be treated essentially the same as $uintptr_t, though in the future we may do something more sophisticated. --- .../design/wasi_unstable/typenames.witx | 6 ++--- .../design/wasi_unstable/wasi_unstable.witx | 22 ++++++++++++------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/proposals/filesystem/design/wasi_unstable/typenames.witx b/proposals/filesystem/design/wasi_unstable/typenames.witx index 06df21774..87ee29d67 100644 --- a/proposals/filesystem/design/wasi_unstable/typenames.witx +++ b/proposals/filesystem/design/wasi_unstable/typenames.witx @@ -3,8 +3,6 @@ ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). (typename $size_t u32) -(typename $uintptr_t u32) -(typename $string_array (array string)) ;; Non-negative file size or length of a region within a file. (typename $filesize_t u64) @@ -283,7 +281,7 @@ (typename $iovec_t (struct ;; The address and length of the buffer to be filled. - (field $buf $uintptr_t) + (field $buf (@witx pointer u8)) (field $buf_len $size_t) ) ) @@ -292,7 +290,7 @@ (typename $ciovec_t (struct ;; The address and length of the buffer to be written. - (field $buf $uintptr_t) + (field $buf (@witx const_pointer u8)) (field $buf_len $size_t) ) ) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx b/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx index 54ea07651..23f8931ed 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx @@ -11,8 +11,9 @@ ;; Read command-line argument data. ;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") + (param $argv (@witx pointer (@witx pointer u8))) + (param $argv_buf (@witx pointer u8)) (result $error $errno_t) - (result $argv $string_array) ) ;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") @@ -26,8 +27,9 @@ ;; Read environment variable data. ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. (@interface func (export "environ_get") + (param $environ (@witx pointer (@witx pointer u8))) + (param $environ_buf (@witx pointer u8)) (result $error $errno_t) - (result $argv $string_array) ) ;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") @@ -177,7 +179,8 @@ (@interface func (export "fd_prestat_dir_name") (param $fd $fd_t) ;; A buffer into which to write the preopened directory name. - (param $path string) + (param $path (@witx pointer u8)) + (param $path_len $size_t) (result $error $errno_t) ) @@ -218,7 +221,8 @@ (@interface func (export "fd_readdir") (param $fd $fd_t) ;; The buffer where directory entries are stored - (param $buf data) + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) ;; The location within the directory to start reading (param $cookie $dircookie_t) (result $error $errno_t) @@ -377,7 +381,8 @@ ;; The path of the symbolic link from which to read. (param $path) ;; The buffer to which to write the contents of the symbolic link. - (param $buf string) + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) (result $error $errno_t) ;; The number of bytes placed in the buffer. (result $bufused $size_t) @@ -431,9 +436,9 @@ ;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;; The events to which to subscribe. - (param $in $subscription_t) + (param $in (const_pointer $subscription_t)) ;; The events that have occurred. - (param $out $event_t) + (param $out (@witx pointer $event_t)) ;; Both the number of subscriptions and events. (param $nsubscriptions $size_t) (result $error $errno_t) @@ -471,7 +476,8 @@ ;; number generator, rather than to provide the random data directly. (@interface func (export "random_get") ;; The buffer to fill with random data. - (param $buf data) + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) (result $error $errno_t) ) From 43a5657a16fe370ab412c025d371b83dbb8f9164 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 09:21:13 -0700 Subject: [PATCH 0142/1772] Fix a missing @witx. --- proposals/clocks/design/wasi_unstable/wasi_unstable.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.witx b/proposals/clocks/design/wasi_unstable/wasi_unstable.witx index 23f8931ed..82b75ef23 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.witx @@ -436,7 +436,7 @@ ;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;; The events to which to subscribe. - (param $in (const_pointer $subscription_t)) + (param $in (@witx const_pointer $subscription_t)) ;; The events that have occurred. (param $out (@witx pointer $event_t)) ;; Both the number of subscriptions and events. From 8408e254696639e8db099e354af953a3add40cab Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 09:21:13 -0700 Subject: [PATCH 0143/1772] Fix a missing @witx. --- proposals/random/design/wasi_unstable/wasi_unstable.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.witx b/proposals/random/design/wasi_unstable/wasi_unstable.witx index 23f8931ed..82b75ef23 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/random/design/wasi_unstable/wasi_unstable.witx @@ -436,7 +436,7 @@ ;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;; The events to which to subscribe. - (param $in (const_pointer $subscription_t)) + (param $in (@witx const_pointer $subscription_t)) ;; The events that have occurred. (param $out (@witx pointer $event_t)) ;; Both the number of subscriptions and events. From af5ca5fe2b785b5cba4788f9a7294bb1546d0aa2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 09:21:13 -0700 Subject: [PATCH 0144/1772] Fix a missing @witx. --- proposals/filesystem/design/wasi_unstable/wasi_unstable.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx b/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx index 23f8931ed..82b75ef23 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx @@ -436,7 +436,7 @@ ;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;; The events to which to subscribe. - (param $in (const_pointer $subscription_t)) + (param $in (@witx const_pointer $subscription_t)) ;; The events that have occurred. (param $out (@witx pointer $event_t)) ;; Both the number of subscriptions and events. From 1b2f0004962325d49b3680bda5209ec49c7c743b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 09:46:18 -0700 Subject: [PATCH 0145/1772] Give each field its own comment, instead of commenting them as a group. --- proposals/clocks/design/wasi_unstable/typenames.witx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/design/wasi_unstable/typenames.witx b/proposals/clocks/design/wasi_unstable/typenames.witx index 87ee29d67..021c750a6 100644 --- a/proposals/clocks/design/wasi_unstable/typenames.witx +++ b/proposals/clocks/design/wasi_unstable/typenames.witx @@ -280,8 +280,9 @@ ;; A region of memory for scatter/gather reads. (typename $iovec_t (struct - ;; The address and length of the buffer to be filled. + ;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) + ;; The length of the buffer to be filled. (field $buf_len $size_t) ) ) @@ -289,8 +290,9 @@ ;; A region of memory for scatter/gather writes. (typename $ciovec_t (struct - ;; The address and length of the buffer to be written. + ;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) + ;; The length of the buffer to be written. (field $buf_len $size_t) ) ) From 3b74be92d6fc444cfc65655628c73e6b7cbce48b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 09:46:18 -0700 Subject: [PATCH 0146/1772] Give each field its own comment, instead of commenting them as a group. --- proposals/random/design/wasi_unstable/typenames.witx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/proposals/random/design/wasi_unstable/typenames.witx b/proposals/random/design/wasi_unstable/typenames.witx index 87ee29d67..021c750a6 100644 --- a/proposals/random/design/wasi_unstable/typenames.witx +++ b/proposals/random/design/wasi_unstable/typenames.witx @@ -280,8 +280,9 @@ ;; A region of memory for scatter/gather reads. (typename $iovec_t (struct - ;; The address and length of the buffer to be filled. + ;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) + ;; The length of the buffer to be filled. (field $buf_len $size_t) ) ) @@ -289,8 +290,9 @@ ;; A region of memory for scatter/gather writes. (typename $ciovec_t (struct - ;; The address and length of the buffer to be written. + ;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) + ;; The length of the buffer to be written. (field $buf_len $size_t) ) ) From 17cfd901a51cffb1dc7b49c0274ed0bd6142e587 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 09:46:18 -0700 Subject: [PATCH 0147/1772] Give each field its own comment, instead of commenting them as a group. --- proposals/filesystem/design/wasi_unstable/typenames.witx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/design/wasi_unstable/typenames.witx b/proposals/filesystem/design/wasi_unstable/typenames.witx index 87ee29d67..021c750a6 100644 --- a/proposals/filesystem/design/wasi_unstable/typenames.witx +++ b/proposals/filesystem/design/wasi_unstable/typenames.witx @@ -280,8 +280,9 @@ ;; A region of memory for scatter/gather reads. (typename $iovec_t (struct - ;; The address and length of the buffer to be filled. + ;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) + ;; The length of the buffer to be filled. (field $buf_len $size_t) ) ) @@ -289,8 +290,9 @@ ;; A region of memory for scatter/gather writes. (typename $ciovec_t (struct - ;; The address and length of the buffer to be written. + ;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) + ;; The length of the buffer to be written. (field $buf_len $size_t) ) ) From 876e393bcd5a08bc5ff67ecde810536aecadbfde Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 12:25:59 -0700 Subject: [PATCH 0148/1772] Add a document on `witx`. --- .../design/wasi_unstable/typenames.witx | 3 ++ .../design/wasi_unstable/wasi_unstable.witx | 3 ++ proposals/clocks/docs/witx.md | 30 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 proposals/clocks/docs/witx.md diff --git a/proposals/clocks/design/wasi_unstable/typenames.witx b/proposals/clocks/design/wasi_unstable/typenames.witx index 021c750a6..14fd81e4e 100644 --- a/proposals/clocks/design/wasi_unstable/typenames.witx +++ b/proposals/clocks/design/wasi_unstable/typenames.witx @@ -1,6 +1,9 @@ ;; Type names used by the wasi_unstable module type. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. (typename $size_t u32) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.witx b/proposals/clocks/design/wasi_unstable/wasi_unstable.witx index 82b75ef23..c47541b9a 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.witx @@ -1,6 +1,9 @@ ;; The wasi_unstable module type. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. (use "typenames.wid") diff --git a/proposals/clocks/docs/witx.md b/proposals/clocks/docs/witx.md new file mode 100644 index 000000000..db267992f --- /dev/null +++ b/proposals/clocks/docs/witx.md @@ -0,0 +1,30 @@ +# Know your `witx` + +The `witx` file format is an experimental format which is based on the +[module types] text format (`wit`), (which is in turn based on the +[wat format], which is based on [S-expressions]). It adds some features +using the same syntax as [interface types], some features with syntax +similar to [gc types], as well as a few special features of its own. + +`witx` is actively evolving. Expect backwards-incompatible changes, +particularly in the areas where `witx` differs from `wit`. + +The initial goal for `witx` is just to have a language suitable for +expressing [WASI] APIs in, to serve as the vocabulary for proposing changes +to existing APIs and proposing new APIs. Initially, while it uses some of +the syntax and concepts from interface types, it doesn't currently imply the +full interface types specification, or the use of the interface types custom +sections. + +We expect that eventually we will transition to using the full interface +types specification. Until then, the goals here are to remain aligned with +interface types and other relevant WebAssembly standards and proposals +wherever practical, and to be an input into the design process of interface +types. + +[module types]: https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md +[interface types]: https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md +[gc types]: https://github.com/WebAssembly/gc +[wat format]: https://webassembly.github.io/spec/core/bikeshed/index.html#text-format%E2%91%A0 +[S-expressions]: https://en.wikipedia.org/wiki/S-expression +[WASI]: https://github.com/WebAssembly/WASI From 0446e280c9e302b7f915e01c4547dcef251d8475 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 12:25:59 -0700 Subject: [PATCH 0149/1772] Add a document on `witx`. --- .../design/wasi_unstable/typenames.witx | 3 ++ .../design/wasi_unstable/wasi_unstable.witx | 3 ++ proposals/random/docs/witx.md | 30 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 proposals/random/docs/witx.md diff --git a/proposals/random/design/wasi_unstable/typenames.witx b/proposals/random/design/wasi_unstable/typenames.witx index 021c750a6..14fd81e4e 100644 --- a/proposals/random/design/wasi_unstable/typenames.witx +++ b/proposals/random/design/wasi_unstable/typenames.witx @@ -1,6 +1,9 @@ ;; Type names used by the wasi_unstable module type. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. (typename $size_t u32) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.witx b/proposals/random/design/wasi_unstable/wasi_unstable.witx index 82b75ef23..c47541b9a 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/random/design/wasi_unstable/wasi_unstable.witx @@ -1,6 +1,9 @@ ;; The wasi_unstable module type. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. (use "typenames.wid") diff --git a/proposals/random/docs/witx.md b/proposals/random/docs/witx.md new file mode 100644 index 000000000..db267992f --- /dev/null +++ b/proposals/random/docs/witx.md @@ -0,0 +1,30 @@ +# Know your `witx` + +The `witx` file format is an experimental format which is based on the +[module types] text format (`wit`), (which is in turn based on the +[wat format], which is based on [S-expressions]). It adds some features +using the same syntax as [interface types], some features with syntax +similar to [gc types], as well as a few special features of its own. + +`witx` is actively evolving. Expect backwards-incompatible changes, +particularly in the areas where `witx` differs from `wit`. + +The initial goal for `witx` is just to have a language suitable for +expressing [WASI] APIs in, to serve as the vocabulary for proposing changes +to existing APIs and proposing new APIs. Initially, while it uses some of +the syntax and concepts from interface types, it doesn't currently imply the +full interface types specification, or the use of the interface types custom +sections. + +We expect that eventually we will transition to using the full interface +types specification. Until then, the goals here are to remain aligned with +interface types and other relevant WebAssembly standards and proposals +wherever practical, and to be an input into the design process of interface +types. + +[module types]: https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md +[interface types]: https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md +[gc types]: https://github.com/WebAssembly/gc +[wat format]: https://webassembly.github.io/spec/core/bikeshed/index.html#text-format%E2%91%A0 +[S-expressions]: https://en.wikipedia.org/wiki/S-expression +[WASI]: https://github.com/WebAssembly/WASI From 77e1a37394f7341cd909f48d653b63f7c5628977 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 5 Sep 2019 12:25:59 -0700 Subject: [PATCH 0150/1772] Add a document on `witx`. --- .../design/wasi_unstable/typenames.witx | 3 ++ .../design/wasi_unstable/wasi_unstable.witx | 3 ++ proposals/filesystem/docs/witx.md | 30 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 proposals/filesystem/docs/witx.md diff --git a/proposals/filesystem/design/wasi_unstable/typenames.witx b/proposals/filesystem/design/wasi_unstable/typenames.witx index 021c750a6..14fd81e4e 100644 --- a/proposals/filesystem/design/wasi_unstable/typenames.witx +++ b/proposals/filesystem/design/wasi_unstable/typenames.witx @@ -1,6 +1,9 @@ ;; Type names used by the wasi_unstable module type. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. (typename $size_t u32) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx b/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx index 82b75ef23..c47541b9a 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx @@ -1,6 +1,9 @@ ;; The wasi_unstable module type. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. (use "typenames.wid") diff --git a/proposals/filesystem/docs/witx.md b/proposals/filesystem/docs/witx.md new file mode 100644 index 000000000..db267992f --- /dev/null +++ b/proposals/filesystem/docs/witx.md @@ -0,0 +1,30 @@ +# Know your `witx` + +The `witx` file format is an experimental format which is based on the +[module types] text format (`wit`), (which is in turn based on the +[wat format], which is based on [S-expressions]). It adds some features +using the same syntax as [interface types], some features with syntax +similar to [gc types], as well as a few special features of its own. + +`witx` is actively evolving. Expect backwards-incompatible changes, +particularly in the areas where `witx` differs from `wit`. + +The initial goal for `witx` is just to have a language suitable for +expressing [WASI] APIs in, to serve as the vocabulary for proposing changes +to existing APIs and proposing new APIs. Initially, while it uses some of +the syntax and concepts from interface types, it doesn't currently imply the +full interface types specification, or the use of the interface types custom +sections. + +We expect that eventually we will transition to using the full interface +types specification. Until then, the goals here are to remain aligned with +interface types and other relevant WebAssembly standards and proposals +wherever practical, and to be an input into the design process of interface +types. + +[module types]: https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md +[interface types]: https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md +[gc types]: https://github.com/WebAssembly/gc +[wat format]: https://webassembly.github.io/spec/core/bikeshed/index.html#text-format%E2%91%A0 +[S-expressions]: https://en.wikipedia.org/wiki/S-expression +[WASI]: https://github.com/WebAssembly/WASI From ccb739956a478562fecfe536af8956824b9b00d2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 9 Sep 2019 10:22:56 -0700 Subject: [PATCH 0151/1772] Add $prestat_t and friends. --- .../design/wasi_unstable/typenames.witx | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/proposals/clocks/design/wasi_unstable/typenames.witx b/proposals/clocks/design/wasi_unstable/typenames.witx index 14fd81e4e..226ec4e78 100644 --- a/proposals/clocks/design/wasi_unstable/typenames.witx +++ b/proposals/clocks/design/wasi_unstable/typenames.witx @@ -719,3 +719,37 @@ (flag $SHUT_WR) ) ) + +;; Information about a pre-opened capability. +(typename $prestat_t + (struct + ;; The type of the pre-opened capability. + (field $pr_type $preopentype_t) + ;; The contents of the information. + (field $u $prestat_u) + ) +) + +;; Identifiers for preopened capabilities. +(typename preopentype_t + (enum u8 + ;; A pre-opened directory. + $PREOPENTYPE_DIR + ) +) + +;; The contents of an $prestat_t. +(typename $prestat_u + (union + ;; When type is `PREOPENTYPE_DIR`: + (field $dir $prestat_dir) + ) +) + +;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +(typename $prestat_dir + (struct + ;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size_t) + ) +) From b5e58cccc763afe3fbb99f58de0dcebdc8c0451f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 9 Sep 2019 10:22:56 -0700 Subject: [PATCH 0152/1772] Add $prestat_t and friends. --- .../design/wasi_unstable/typenames.witx | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/proposals/random/design/wasi_unstable/typenames.witx b/proposals/random/design/wasi_unstable/typenames.witx index 14fd81e4e..226ec4e78 100644 --- a/proposals/random/design/wasi_unstable/typenames.witx +++ b/proposals/random/design/wasi_unstable/typenames.witx @@ -719,3 +719,37 @@ (flag $SHUT_WR) ) ) + +;; Information about a pre-opened capability. +(typename $prestat_t + (struct + ;; The type of the pre-opened capability. + (field $pr_type $preopentype_t) + ;; The contents of the information. + (field $u $prestat_u) + ) +) + +;; Identifiers for preopened capabilities. +(typename preopentype_t + (enum u8 + ;; A pre-opened directory. + $PREOPENTYPE_DIR + ) +) + +;; The contents of an $prestat_t. +(typename $prestat_u + (union + ;; When type is `PREOPENTYPE_DIR`: + (field $dir $prestat_dir) + ) +) + +;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +(typename $prestat_dir + (struct + ;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size_t) + ) +) From 515f3c17d82e0e220d2f12434ec75b818bddf092 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 9 Sep 2019 10:22:56 -0700 Subject: [PATCH 0153/1772] Add $prestat_t and friends. --- .../design/wasi_unstable/typenames.witx | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/proposals/filesystem/design/wasi_unstable/typenames.witx b/proposals/filesystem/design/wasi_unstable/typenames.witx index 14fd81e4e..226ec4e78 100644 --- a/proposals/filesystem/design/wasi_unstable/typenames.witx +++ b/proposals/filesystem/design/wasi_unstable/typenames.witx @@ -719,3 +719,37 @@ (flag $SHUT_WR) ) ) + +;; Information about a pre-opened capability. +(typename $prestat_t + (struct + ;; The type of the pre-opened capability. + (field $pr_type $preopentype_t) + ;; The contents of the information. + (field $u $prestat_u) + ) +) + +;; Identifiers for preopened capabilities. +(typename preopentype_t + (enum u8 + ;; A pre-opened directory. + $PREOPENTYPE_DIR + ) +) + +;; The contents of an $prestat_t. +(typename $prestat_u + (union + ;; When type is `PREOPENTYPE_DIR`: + (field $dir $prestat_dir) + ) +) + +;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +(typename $prestat_dir + (struct + ;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size_t) + ) +) From b08490220a739c877805c5ba665e3b07ff5915db Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 9 Sep 2019 10:28:25 -0700 Subject: [PATCH 0154/1772] Remove `__wasi_` and `__WASI_` prefixes from names in comments. --- .../design/wasi_unstable/typenames.witx | 141 +++++++++--------- .../design/wasi_unstable/wasi_unstable.witx | 4 +- 2 files changed, 71 insertions(+), 74 deletions(-) diff --git a/proposals/clocks/design/wasi_unstable/typenames.witx b/proposals/clocks/design/wasi_unstable/typenames.witx index 226ec4e78..4bab30735 100644 --- a/proposals/clocks/design/wasi_unstable/typenames.witx +++ b/proposals/clocks/design/wasi_unstable/typenames.witx @@ -197,79 +197,78 @@ ;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke `__wasi_fd_datasync()`. + ;; The right to invoke `fd_datasync`. ;; - ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `__wasi_path_open()` with `__WASI_FDFLAG_DSYNC`. + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_DSYNC`. (flag $RIGHT_FD_DATASYNC) - ;; The right to invoke `__wasi_fd_read()` and `__wasi_sock_recv()`. + ;; The right to invoke `fd_read` and `sock_recv`. ;; - ;; If `__WASI_RIGHT_FD_SEEK` is set, includes the right to invoke - ;; `__wasi_fd_pread()`. + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. (flag $RIGHT_FD_READ) - ;; The right to invoke `__wasi_fd_seek()`. This flag implies `__WASI_RIGHT_FD_TELL`. + ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. (flag $RIGHT_FD_SEEK) - ;; The right to invoke `__wasi_fd_fdstat_set_flags()`. + ;; The right to invoke `fd_fdstat_set_flags`. (flag $RIGHT_FD_FDSTAT_SET_FLAGS) - ;; The right to invoke `__wasi_fd_sync()`. + ;; The right to invoke `fd_sync`. ;; - ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `__wasi_path_open()` with `__WASI_FDFLAG_RSYNC` and `__WASI_FDFLAG_DSYNC`. + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. (flag $RIGHT_FD_SYNC) - ;; The right to invoke `__wasi_fd_seek()` in such a way that the file offset - ;; remains unaltered (i.e., `__WASI_WHENCE_CUR` with offset zero), or to - ;; invoke `__wasi_fd_tell()`. + ;; The right to invoke `fd_seek` in such a way that the file offset + ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;; invoke `fd_tell`. (flag $RIGHT_FD_TELL) - ;; The right to invoke `__wasi_fd_write()` and `__wasi_sock_send()`. - ;; If `__WASI_RIGHT_FD_SEEK` is set, includes the right to invoke `__wasi_fd_pwrite()`. + ;; The right to invoke `fd_write` and `sock_send`. + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. (flag $RIGHT_FD_WRITE) - ;; The right to invoke `__wasi_fd_advise()`. + ;; The right to invoke `fd_advise`. (flag $RIGHT_FD_ADVISE) - ;; The right to invoke `__wasi_fd_allocate()`. + ;; The right to invoke `fd_allocate`. (flag $RIGHT_FD_ALLOCATE) - ;; The right to invoke `__wasi_path_create_directory()`. + ;; The right to invoke `path_create_directory`. (flag $RIGHT_PATH_CREATE_DIRECTORY) - ;; If `__WASI_RIGHT_PATH_OPEN` is set, the right to invoke `__wasi_path_open()` with `__WASI_O_CREAT`. + ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. (flag $RIGHT_PATH_CREATE_FILE) - ;; The right to invoke `__wasi_path_link()` with the file descriptor as the + ;; The right to invoke `path_link` with the file descriptor as the ;; source directory. (flag $RIGHT_PATH_LINK_SOURCE) - ;; The right to invoke `__wasi_path_link()` with the file descriptor as the + ;; The right to invoke `path_link` with the file descriptor as the ;; target directory. (flag $RIGHT_PATH_LINK_TARGET) - ;; The right to invoke `__wasi_path_open()`. + ;; The right to invoke `path_open`. (flag $RIGHT_PATH_OPEN) - ;; The right to invoke `__wasi_fd_readdir()`. + ;; The right to invoke `fd_readdir`. (flag $RIGHT_FD_READDIR) - ;; The right to invoke `__wasi_path_readlink()`. + ;; The right to invoke `path_readlink`. (flag $RIGHT_PATH_READLINK) - ;; The right to invoke `__wasi_path_rename()` with the file descriptor as the source directory. + ;; The right to invoke `path_rename` with the file descriptor as the source directory. (flag $RIGHT_PATH_RENAME_SOURCE) - ;; The right to invoke `__wasi_path_rename()` with the file descriptor as the target directory. + ;; The right to invoke `path_rename` with the file descriptor as the target directory. (flag $RIGHT_PATH_RENAME_TARGET) - ;; The right to invoke `__wasi_path_filestat_get()`. + ;; The right to invoke `path_filestat_get`. (flag $RIGHT_PATH_FILESTAT_GET) - ;; The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). - ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke `__wasi_path_open()` with `__WASI_O_TRUNC`. + ;; The right to change a file's size (there is no `path_filestat_set_size`). + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. (flag $RIGHT_PATH_FILESTAT_SET_SIZE) - ;; The right to invoke `__wasi_path_filestat_set_times()`. + ;; The right to invoke `path_filestat_set_times`. (flag $RIGHT_PATH_FILESTAT_SET_TIMES) - ;; The right to invoke `__wasi_fd_filestat_get()`. + ;; The right to invoke `fd_filestat_get`. (flag $RIGHT_FD_FILESTAT_GET) - ;; The right to invoke `__wasi_fd_filestat_set_size()`. + ;; The right to invoke `fd_filestat_set_size`. (flag $RIGHT_FD_FILESTAT_SET_SIZE) - ;; The right to invoke `__wasi_fd_filestat_set_times()`. + ;; The right to invoke `fd_filestat_set_times`. (flag $RIGHT_FD_FILESTAT_SET_TIMES) - ;; The right to invoke `__wasi_path_symlink()`. + ;; The right to invoke `path_symlink`. (flag $RIGHT_PATH_SYMLINK) - ;; The right to invoke `__wasi_path_unlink_file()`. + ;; The right to invoke `path_unlink_file`. (flag $RIGHT_PATH_UNLINK_FILE) - ;; The right to invoke `__wasi_path_remove_directory()`. + ;; The right to invoke `path_remove_directory`. (flag $RIGHT_PATH_REMOVE_DIRECTORY) - ;; If `__WASI_RIGHT_FD_READ` is set, includes the right to invoke `__wasi_poll_oneoff()` to subscribe to `__WASI_EVENTTYPE_FD_READ`. - ;; If `__WASI_RIGHT_FD_WRITE` is set, includes the right to invoke `__wasi_poll_oneoff()` to subscribe to `__WASI_EVENTTYPE_FD_WRITE`. + ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. (flag $RIGHT_POLL_FD_READWRITE) - ;; The right to invoke `__wasi_sock_shutdown()`. + ;; The right to invoke `sock_shutdown`. (flag $RIGHT_SOCK_SHUTDOWN) ) ) @@ -381,15 +380,13 @@ ;; Rights that apply to this file descriptor. (field $fs_rights_base $rights_t) ;; Maximum set of rights that may be installed on new file descriptors that - ;; are created through this file descriptor, e.g., through - ;; `__wasi_path_open()`. + ;; are created through this file descriptor, e.g., through `path_open`. (field $fs_rights_inheriting $rights_t) ) ) ;; Identifier for a device containing a file system. Can be used in combination -;; with __wasi_inode_t to uniquely identify a file or directory in the -;; filesystem. +;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) ;; The type of a file descriptor or file. @@ -417,13 +414,13 @@ ;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 - ;; Adjust the last data access timestamp to the value stored in __wasi_filestat_t::st_atim. + ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. (flag $FILESTAT_SET_ATIM) - ;; Adjust the last data access timestamp to the time of clock `__WASI_CLOCK_REALTIME`. + ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. (flag $FILESTAT_SET_ATIM_NOW) - ;; Adjust the last data modification timestamp to the value stored in __wasi_filestat_t::st_mtim. + ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. (flag $FILESTAT_SET_MTIM) - ;; Adjust the last data modification timestamp to the time of clock `__WASI_CLOCK_REALTIME`. + ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. (flag $FILESTAT_SET_MTIM_NOW) ) ) @@ -439,7 +436,7 @@ ) ) -;; Open flags used by `__wasi_path_open()`. +;; Open flags used by `path_open`. (typename $oflags_t (flags u16 ;; Create file if it does not exist. @@ -485,7 +482,7 @@ ;; An event that occurred. (typename $event_t (struct - ;; User-provided value that got attached to __wasi_subscription_t::userdata. + ;; User-provided value that got attached to `subscription_t::userdata`. (field $userdata $userdata_t) ;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno_t) @@ -499,13 +496,13 @@ ;; The contents of an $event_t. (typename $event_u (union - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; The contents of an $event_t when type is `__WASI_EVENTTYPE_FD_READ` or -;; `__WASI_EVENTTYPE_FD_WRITE`. +;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;; `EVENTTYPE_FD_WRITE`. (typename $event_fd_readwrite_t (struct ;; The number of bytes available for reading or writing. @@ -516,7 +513,7 @@ ) ;; The state of the file descriptor subscribed to with -;; `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. @@ -527,27 +524,27 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (flags u8 - ;; The time value of clock __wasi_subscription_t::u.clock.clock_id has - ;; reached timestamp __wasi_subscription_t::u.clock.timeout. + ;; The time value of clock `subscription_t::u.clock.clock_id` has + ;; reached timestamp `subscription_t::u.clock.timeout`. (flag $EVENTTYPE_CLOCK) - ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has data + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data ;; available for reading. This event always triggers for regular files. (flag $EVENTTYPE_FD_READ) - ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has capacity + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity ;; available for writing. This event always triggers for regular files. (flag $EVENTTYPE_FD_WRITE) ) ) ;; Flags determining how to interpret the timestamp provided in -;; __wasi_subscription_t::u.clock.timeout. +;; `subscription_t::u.clock.timeout.` (typename $subclockflags_t (flags u16 ;; If set, treat the timestamp provided in - ;; __wasi_subscription_t::u.clock.timeout as an absolute timestamp of clock - ;; __wasi_subscription_t::u.clock.clock_id. If clear, treat the timestamp - ;; provided in __wasi_subscription_t::u.clock.timeout relative to the - ;; current time value of clock __wasi_subscription_t::u.clock.clock_id. + ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;; provided in `subscription_t::u.clock.timeout` relative to the + ;; current time value of clock `subscription_t::u.clock.clock_id.` (flag $SUBSCRIPTION_CLOCK_ABSTIME) ) ) @@ -556,7 +553,7 @@ (typename $subscription_t (struct ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through __wasi_event_t::userdata. + ;; implementation and returned through `event_t::userdata`. (field $userdata $userdata_t) ;; The type of the event to which to subscribe. (field $type $eventtype_t) @@ -568,14 +565,14 @@ ;; The contents of a $subscription_t. (typename $subscription_u (union - ;; When type is `__WASI_EVENTTYPE_CLOCK`: + ;; When type is `EVENTTYPE_CLOCK`: (field $clock $subscription_clock_t) - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $subscription_fd_readwrite_t) ) ) -;; The contents of a $subscription_t when type is `__WASI_EVENTTYPE_CLOCK`. +;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct ;; The user-defined unique identifier of the clock. @@ -593,7 +590,7 @@ ) ;; The contents of a $subscription_t when type is type is -;; `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $subscription_fd_readwrite_t (struct ;; The file descriptor on which to wait for it to become ready for reading or writing. @@ -688,7 +685,7 @@ ) ) -;; Flags provided to `__wasi_sock_recv()`. +;; Flags provided to `sock_recv`. (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. @@ -698,15 +695,15 @@ ) ) -;; Flags returned by `__wasi_sock_recv()`. +;; Flags returned by `sock_recv`. (typename $roflags_t (flags u16 - ;; Returned by `__wasi_sock_recv()`: Message data has been truncated. + ;; Returned by `sock_recv`: Message data has been truncated. (flag $SOCK_RECV_DATA_TRUNCATED) ) ) -;; Flags provided to `__wasi_sock_send()`. As there are currently no flags +;; Flags provided to `sock_send`. As there are currently no flags ;; defined, it must be set to zero. (typename $siflags_t u16) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.witx b/proposals/clocks/design/wasi_unstable/wasi_unstable.witx index c47541b9a..4a48cc38b 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.witx @@ -392,7 +392,7 @@ ) ;; Remove a directory. - ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. + ;; Return `ENOTEMPTY` if the directory is not empty. ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd_t) @@ -427,7 +427,7 @@ ;; Unlink a file. - ;; Return `__WASI_EISDIR` if the path refers to a directory. + ;; Return `EISDIR` if the path refers to a directory. ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd_t) From 26518a533d078b37938da49f25d0bd464c11c9c8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 9 Sep 2019 10:28:25 -0700 Subject: [PATCH 0155/1772] Remove `__wasi_` and `__WASI_` prefixes from names in comments. --- .../design/wasi_unstable/typenames.witx | 141 +++++++++--------- .../design/wasi_unstable/wasi_unstable.witx | 4 +- 2 files changed, 71 insertions(+), 74 deletions(-) diff --git a/proposals/random/design/wasi_unstable/typenames.witx b/proposals/random/design/wasi_unstable/typenames.witx index 226ec4e78..4bab30735 100644 --- a/proposals/random/design/wasi_unstable/typenames.witx +++ b/proposals/random/design/wasi_unstable/typenames.witx @@ -197,79 +197,78 @@ ;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke `__wasi_fd_datasync()`. + ;; The right to invoke `fd_datasync`. ;; - ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `__wasi_path_open()` with `__WASI_FDFLAG_DSYNC`. + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_DSYNC`. (flag $RIGHT_FD_DATASYNC) - ;; The right to invoke `__wasi_fd_read()` and `__wasi_sock_recv()`. + ;; The right to invoke `fd_read` and `sock_recv`. ;; - ;; If `__WASI_RIGHT_FD_SEEK` is set, includes the right to invoke - ;; `__wasi_fd_pread()`. + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. (flag $RIGHT_FD_READ) - ;; The right to invoke `__wasi_fd_seek()`. This flag implies `__WASI_RIGHT_FD_TELL`. + ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. (flag $RIGHT_FD_SEEK) - ;; The right to invoke `__wasi_fd_fdstat_set_flags()`. + ;; The right to invoke `fd_fdstat_set_flags`. (flag $RIGHT_FD_FDSTAT_SET_FLAGS) - ;; The right to invoke `__wasi_fd_sync()`. + ;; The right to invoke `fd_sync`. ;; - ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `__wasi_path_open()` with `__WASI_FDFLAG_RSYNC` and `__WASI_FDFLAG_DSYNC`. + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. (flag $RIGHT_FD_SYNC) - ;; The right to invoke `__wasi_fd_seek()` in such a way that the file offset - ;; remains unaltered (i.e., `__WASI_WHENCE_CUR` with offset zero), or to - ;; invoke `__wasi_fd_tell()`. + ;; The right to invoke `fd_seek` in such a way that the file offset + ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;; invoke `fd_tell`. (flag $RIGHT_FD_TELL) - ;; The right to invoke `__wasi_fd_write()` and `__wasi_sock_send()`. - ;; If `__WASI_RIGHT_FD_SEEK` is set, includes the right to invoke `__wasi_fd_pwrite()`. + ;; The right to invoke `fd_write` and `sock_send`. + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. (flag $RIGHT_FD_WRITE) - ;; The right to invoke `__wasi_fd_advise()`. + ;; The right to invoke `fd_advise`. (flag $RIGHT_FD_ADVISE) - ;; The right to invoke `__wasi_fd_allocate()`. + ;; The right to invoke `fd_allocate`. (flag $RIGHT_FD_ALLOCATE) - ;; The right to invoke `__wasi_path_create_directory()`. + ;; The right to invoke `path_create_directory`. (flag $RIGHT_PATH_CREATE_DIRECTORY) - ;; If `__WASI_RIGHT_PATH_OPEN` is set, the right to invoke `__wasi_path_open()` with `__WASI_O_CREAT`. + ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. (flag $RIGHT_PATH_CREATE_FILE) - ;; The right to invoke `__wasi_path_link()` with the file descriptor as the + ;; The right to invoke `path_link` with the file descriptor as the ;; source directory. (flag $RIGHT_PATH_LINK_SOURCE) - ;; The right to invoke `__wasi_path_link()` with the file descriptor as the + ;; The right to invoke `path_link` with the file descriptor as the ;; target directory. (flag $RIGHT_PATH_LINK_TARGET) - ;; The right to invoke `__wasi_path_open()`. + ;; The right to invoke `path_open`. (flag $RIGHT_PATH_OPEN) - ;; The right to invoke `__wasi_fd_readdir()`. + ;; The right to invoke `fd_readdir`. (flag $RIGHT_FD_READDIR) - ;; The right to invoke `__wasi_path_readlink()`. + ;; The right to invoke `path_readlink`. (flag $RIGHT_PATH_READLINK) - ;; The right to invoke `__wasi_path_rename()` with the file descriptor as the source directory. + ;; The right to invoke `path_rename` with the file descriptor as the source directory. (flag $RIGHT_PATH_RENAME_SOURCE) - ;; The right to invoke `__wasi_path_rename()` with the file descriptor as the target directory. + ;; The right to invoke `path_rename` with the file descriptor as the target directory. (flag $RIGHT_PATH_RENAME_TARGET) - ;; The right to invoke `__wasi_path_filestat_get()`. + ;; The right to invoke `path_filestat_get`. (flag $RIGHT_PATH_FILESTAT_GET) - ;; The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). - ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke `__wasi_path_open()` with `__WASI_O_TRUNC`. + ;; The right to change a file's size (there is no `path_filestat_set_size`). + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. (flag $RIGHT_PATH_FILESTAT_SET_SIZE) - ;; The right to invoke `__wasi_path_filestat_set_times()`. + ;; The right to invoke `path_filestat_set_times`. (flag $RIGHT_PATH_FILESTAT_SET_TIMES) - ;; The right to invoke `__wasi_fd_filestat_get()`. + ;; The right to invoke `fd_filestat_get`. (flag $RIGHT_FD_FILESTAT_GET) - ;; The right to invoke `__wasi_fd_filestat_set_size()`. + ;; The right to invoke `fd_filestat_set_size`. (flag $RIGHT_FD_FILESTAT_SET_SIZE) - ;; The right to invoke `__wasi_fd_filestat_set_times()`. + ;; The right to invoke `fd_filestat_set_times`. (flag $RIGHT_FD_FILESTAT_SET_TIMES) - ;; The right to invoke `__wasi_path_symlink()`. + ;; The right to invoke `path_symlink`. (flag $RIGHT_PATH_SYMLINK) - ;; The right to invoke `__wasi_path_unlink_file()`. + ;; The right to invoke `path_unlink_file`. (flag $RIGHT_PATH_UNLINK_FILE) - ;; The right to invoke `__wasi_path_remove_directory()`. + ;; The right to invoke `path_remove_directory`. (flag $RIGHT_PATH_REMOVE_DIRECTORY) - ;; If `__WASI_RIGHT_FD_READ` is set, includes the right to invoke `__wasi_poll_oneoff()` to subscribe to `__WASI_EVENTTYPE_FD_READ`. - ;; If `__WASI_RIGHT_FD_WRITE` is set, includes the right to invoke `__wasi_poll_oneoff()` to subscribe to `__WASI_EVENTTYPE_FD_WRITE`. + ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. (flag $RIGHT_POLL_FD_READWRITE) - ;; The right to invoke `__wasi_sock_shutdown()`. + ;; The right to invoke `sock_shutdown`. (flag $RIGHT_SOCK_SHUTDOWN) ) ) @@ -381,15 +380,13 @@ ;; Rights that apply to this file descriptor. (field $fs_rights_base $rights_t) ;; Maximum set of rights that may be installed on new file descriptors that - ;; are created through this file descriptor, e.g., through - ;; `__wasi_path_open()`. + ;; are created through this file descriptor, e.g., through `path_open`. (field $fs_rights_inheriting $rights_t) ) ) ;; Identifier for a device containing a file system. Can be used in combination -;; with __wasi_inode_t to uniquely identify a file or directory in the -;; filesystem. +;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) ;; The type of a file descriptor or file. @@ -417,13 +414,13 @@ ;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 - ;; Adjust the last data access timestamp to the value stored in __wasi_filestat_t::st_atim. + ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. (flag $FILESTAT_SET_ATIM) - ;; Adjust the last data access timestamp to the time of clock `__WASI_CLOCK_REALTIME`. + ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. (flag $FILESTAT_SET_ATIM_NOW) - ;; Adjust the last data modification timestamp to the value stored in __wasi_filestat_t::st_mtim. + ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. (flag $FILESTAT_SET_MTIM) - ;; Adjust the last data modification timestamp to the time of clock `__WASI_CLOCK_REALTIME`. + ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. (flag $FILESTAT_SET_MTIM_NOW) ) ) @@ -439,7 +436,7 @@ ) ) -;; Open flags used by `__wasi_path_open()`. +;; Open flags used by `path_open`. (typename $oflags_t (flags u16 ;; Create file if it does not exist. @@ -485,7 +482,7 @@ ;; An event that occurred. (typename $event_t (struct - ;; User-provided value that got attached to __wasi_subscription_t::userdata. + ;; User-provided value that got attached to `subscription_t::userdata`. (field $userdata $userdata_t) ;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno_t) @@ -499,13 +496,13 @@ ;; The contents of an $event_t. (typename $event_u (union - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; The contents of an $event_t when type is `__WASI_EVENTTYPE_FD_READ` or -;; `__WASI_EVENTTYPE_FD_WRITE`. +;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;; `EVENTTYPE_FD_WRITE`. (typename $event_fd_readwrite_t (struct ;; The number of bytes available for reading or writing. @@ -516,7 +513,7 @@ ) ;; The state of the file descriptor subscribed to with -;; `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. @@ -527,27 +524,27 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (flags u8 - ;; The time value of clock __wasi_subscription_t::u.clock.clock_id has - ;; reached timestamp __wasi_subscription_t::u.clock.timeout. + ;; The time value of clock `subscription_t::u.clock.clock_id` has + ;; reached timestamp `subscription_t::u.clock.timeout`. (flag $EVENTTYPE_CLOCK) - ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has data + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data ;; available for reading. This event always triggers for regular files. (flag $EVENTTYPE_FD_READ) - ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has capacity + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity ;; available for writing. This event always triggers for regular files. (flag $EVENTTYPE_FD_WRITE) ) ) ;; Flags determining how to interpret the timestamp provided in -;; __wasi_subscription_t::u.clock.timeout. +;; `subscription_t::u.clock.timeout.` (typename $subclockflags_t (flags u16 ;; If set, treat the timestamp provided in - ;; __wasi_subscription_t::u.clock.timeout as an absolute timestamp of clock - ;; __wasi_subscription_t::u.clock.clock_id. If clear, treat the timestamp - ;; provided in __wasi_subscription_t::u.clock.timeout relative to the - ;; current time value of clock __wasi_subscription_t::u.clock.clock_id. + ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;; provided in `subscription_t::u.clock.timeout` relative to the + ;; current time value of clock `subscription_t::u.clock.clock_id.` (flag $SUBSCRIPTION_CLOCK_ABSTIME) ) ) @@ -556,7 +553,7 @@ (typename $subscription_t (struct ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through __wasi_event_t::userdata. + ;; implementation and returned through `event_t::userdata`. (field $userdata $userdata_t) ;; The type of the event to which to subscribe. (field $type $eventtype_t) @@ -568,14 +565,14 @@ ;; The contents of a $subscription_t. (typename $subscription_u (union - ;; When type is `__WASI_EVENTTYPE_CLOCK`: + ;; When type is `EVENTTYPE_CLOCK`: (field $clock $subscription_clock_t) - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $subscription_fd_readwrite_t) ) ) -;; The contents of a $subscription_t when type is `__WASI_EVENTTYPE_CLOCK`. +;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct ;; The user-defined unique identifier of the clock. @@ -593,7 +590,7 @@ ) ;; The contents of a $subscription_t when type is type is -;; `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $subscription_fd_readwrite_t (struct ;; The file descriptor on which to wait for it to become ready for reading or writing. @@ -688,7 +685,7 @@ ) ) -;; Flags provided to `__wasi_sock_recv()`. +;; Flags provided to `sock_recv`. (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. @@ -698,15 +695,15 @@ ) ) -;; Flags returned by `__wasi_sock_recv()`. +;; Flags returned by `sock_recv`. (typename $roflags_t (flags u16 - ;; Returned by `__wasi_sock_recv()`: Message data has been truncated. + ;; Returned by `sock_recv`: Message data has been truncated. (flag $SOCK_RECV_DATA_TRUNCATED) ) ) -;; Flags provided to `__wasi_sock_send()`. As there are currently no flags +;; Flags provided to `sock_send`. As there are currently no flags ;; defined, it must be set to zero. (typename $siflags_t u16) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.witx b/proposals/random/design/wasi_unstable/wasi_unstable.witx index c47541b9a..4a48cc38b 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/random/design/wasi_unstable/wasi_unstable.witx @@ -392,7 +392,7 @@ ) ;; Remove a directory. - ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. + ;; Return `ENOTEMPTY` if the directory is not empty. ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd_t) @@ -427,7 +427,7 @@ ;; Unlink a file. - ;; Return `__WASI_EISDIR` if the path refers to a directory. + ;; Return `EISDIR` if the path refers to a directory. ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd_t) From 4055470ee3d3b009d25ac46aa36832dcecd93952 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 9 Sep 2019 10:28:25 -0700 Subject: [PATCH 0156/1772] Remove `__wasi_` and `__WASI_` prefixes from names in comments. --- .../design/wasi_unstable/typenames.witx | 141 +++++++++--------- .../design/wasi_unstable/wasi_unstable.witx | 4 +- 2 files changed, 71 insertions(+), 74 deletions(-) diff --git a/proposals/filesystem/design/wasi_unstable/typenames.witx b/proposals/filesystem/design/wasi_unstable/typenames.witx index 226ec4e78..4bab30735 100644 --- a/proposals/filesystem/design/wasi_unstable/typenames.witx +++ b/proposals/filesystem/design/wasi_unstable/typenames.witx @@ -197,79 +197,78 @@ ;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke `__wasi_fd_datasync()`. + ;; The right to invoke `fd_datasync`. ;; - ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `__wasi_path_open()` with `__WASI_FDFLAG_DSYNC`. + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_DSYNC`. (flag $RIGHT_FD_DATASYNC) - ;; The right to invoke `__wasi_fd_read()` and `__wasi_sock_recv()`. + ;; The right to invoke `fd_read` and `sock_recv`. ;; - ;; If `__WASI_RIGHT_FD_SEEK` is set, includes the right to invoke - ;; `__wasi_fd_pread()`. + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. (flag $RIGHT_FD_READ) - ;; The right to invoke `__wasi_fd_seek()`. This flag implies `__WASI_RIGHT_FD_TELL`. + ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. (flag $RIGHT_FD_SEEK) - ;; The right to invoke `__wasi_fd_fdstat_set_flags()`. + ;; The right to invoke `fd_fdstat_set_flags`. (flag $RIGHT_FD_FDSTAT_SET_FLAGS) - ;; The right to invoke `__wasi_fd_sync()`. + ;; The right to invoke `fd_sync`. ;; - ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `__wasi_path_open()` with `__WASI_FDFLAG_RSYNC` and `__WASI_FDFLAG_DSYNC`. + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. (flag $RIGHT_FD_SYNC) - ;; The right to invoke `__wasi_fd_seek()` in such a way that the file offset - ;; remains unaltered (i.e., `__WASI_WHENCE_CUR` with offset zero), or to - ;; invoke `__wasi_fd_tell()`. + ;; The right to invoke `fd_seek` in such a way that the file offset + ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;; invoke `fd_tell`. (flag $RIGHT_FD_TELL) - ;; The right to invoke `__wasi_fd_write()` and `__wasi_sock_send()`. - ;; If `__WASI_RIGHT_FD_SEEK` is set, includes the right to invoke `__wasi_fd_pwrite()`. + ;; The right to invoke `fd_write` and `sock_send`. + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. (flag $RIGHT_FD_WRITE) - ;; The right to invoke `__wasi_fd_advise()`. + ;; The right to invoke `fd_advise`. (flag $RIGHT_FD_ADVISE) - ;; The right to invoke `__wasi_fd_allocate()`. + ;; The right to invoke `fd_allocate`. (flag $RIGHT_FD_ALLOCATE) - ;; The right to invoke `__wasi_path_create_directory()`. + ;; The right to invoke `path_create_directory`. (flag $RIGHT_PATH_CREATE_DIRECTORY) - ;; If `__WASI_RIGHT_PATH_OPEN` is set, the right to invoke `__wasi_path_open()` with `__WASI_O_CREAT`. + ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. (flag $RIGHT_PATH_CREATE_FILE) - ;; The right to invoke `__wasi_path_link()` with the file descriptor as the + ;; The right to invoke `path_link` with the file descriptor as the ;; source directory. (flag $RIGHT_PATH_LINK_SOURCE) - ;; The right to invoke `__wasi_path_link()` with the file descriptor as the + ;; The right to invoke `path_link` with the file descriptor as the ;; target directory. (flag $RIGHT_PATH_LINK_TARGET) - ;; The right to invoke `__wasi_path_open()`. + ;; The right to invoke `path_open`. (flag $RIGHT_PATH_OPEN) - ;; The right to invoke `__wasi_fd_readdir()`. + ;; The right to invoke `fd_readdir`. (flag $RIGHT_FD_READDIR) - ;; The right to invoke `__wasi_path_readlink()`. + ;; The right to invoke `path_readlink`. (flag $RIGHT_PATH_READLINK) - ;; The right to invoke `__wasi_path_rename()` with the file descriptor as the source directory. + ;; The right to invoke `path_rename` with the file descriptor as the source directory. (flag $RIGHT_PATH_RENAME_SOURCE) - ;; The right to invoke `__wasi_path_rename()` with the file descriptor as the target directory. + ;; The right to invoke `path_rename` with the file descriptor as the target directory. (flag $RIGHT_PATH_RENAME_TARGET) - ;; The right to invoke `__wasi_path_filestat_get()`. + ;; The right to invoke `path_filestat_get`. (flag $RIGHT_PATH_FILESTAT_GET) - ;; The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). - ;; If `__WASI_RIGHT_PATH_OPEN` is set, includes the right to invoke `__wasi_path_open()` with `__WASI_O_TRUNC`. + ;; The right to change a file's size (there is no `path_filestat_set_size`). + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. (flag $RIGHT_PATH_FILESTAT_SET_SIZE) - ;; The right to invoke `__wasi_path_filestat_set_times()`. + ;; The right to invoke `path_filestat_set_times`. (flag $RIGHT_PATH_FILESTAT_SET_TIMES) - ;; The right to invoke `__wasi_fd_filestat_get()`. + ;; The right to invoke `fd_filestat_get`. (flag $RIGHT_FD_FILESTAT_GET) - ;; The right to invoke `__wasi_fd_filestat_set_size()`. + ;; The right to invoke `fd_filestat_set_size`. (flag $RIGHT_FD_FILESTAT_SET_SIZE) - ;; The right to invoke `__wasi_fd_filestat_set_times()`. + ;; The right to invoke `fd_filestat_set_times`. (flag $RIGHT_FD_FILESTAT_SET_TIMES) - ;; The right to invoke `__wasi_path_symlink()`. + ;; The right to invoke `path_symlink`. (flag $RIGHT_PATH_SYMLINK) - ;; The right to invoke `__wasi_path_unlink_file()`. + ;; The right to invoke `path_unlink_file`. (flag $RIGHT_PATH_UNLINK_FILE) - ;; The right to invoke `__wasi_path_remove_directory()`. + ;; The right to invoke `path_remove_directory`. (flag $RIGHT_PATH_REMOVE_DIRECTORY) - ;; If `__WASI_RIGHT_FD_READ` is set, includes the right to invoke `__wasi_poll_oneoff()` to subscribe to `__WASI_EVENTTYPE_FD_READ`. - ;; If `__WASI_RIGHT_FD_WRITE` is set, includes the right to invoke `__wasi_poll_oneoff()` to subscribe to `__WASI_EVENTTYPE_FD_WRITE`. + ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. (flag $RIGHT_POLL_FD_READWRITE) - ;; The right to invoke `__wasi_sock_shutdown()`. + ;; The right to invoke `sock_shutdown`. (flag $RIGHT_SOCK_SHUTDOWN) ) ) @@ -381,15 +380,13 @@ ;; Rights that apply to this file descriptor. (field $fs_rights_base $rights_t) ;; Maximum set of rights that may be installed on new file descriptors that - ;; are created through this file descriptor, e.g., through - ;; `__wasi_path_open()`. + ;; are created through this file descriptor, e.g., through `path_open`. (field $fs_rights_inheriting $rights_t) ) ) ;; Identifier for a device containing a file system. Can be used in combination -;; with __wasi_inode_t to uniquely identify a file or directory in the -;; filesystem. +;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) ;; The type of a file descriptor or file. @@ -417,13 +414,13 @@ ;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 - ;; Adjust the last data access timestamp to the value stored in __wasi_filestat_t::st_atim. + ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. (flag $FILESTAT_SET_ATIM) - ;; Adjust the last data access timestamp to the time of clock `__WASI_CLOCK_REALTIME`. + ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. (flag $FILESTAT_SET_ATIM_NOW) - ;; Adjust the last data modification timestamp to the value stored in __wasi_filestat_t::st_mtim. + ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. (flag $FILESTAT_SET_MTIM) - ;; Adjust the last data modification timestamp to the time of clock `__WASI_CLOCK_REALTIME`. + ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. (flag $FILESTAT_SET_MTIM_NOW) ) ) @@ -439,7 +436,7 @@ ) ) -;; Open flags used by `__wasi_path_open()`. +;; Open flags used by `path_open`. (typename $oflags_t (flags u16 ;; Create file if it does not exist. @@ -485,7 +482,7 @@ ;; An event that occurred. (typename $event_t (struct - ;; User-provided value that got attached to __wasi_subscription_t::userdata. + ;; User-provided value that got attached to `subscription_t::userdata`. (field $userdata $userdata_t) ;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno_t) @@ -499,13 +496,13 @@ ;; The contents of an $event_t. (typename $event_u (union - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; The contents of an $event_t when type is `__WASI_EVENTTYPE_FD_READ` or -;; `__WASI_EVENTTYPE_FD_WRITE`. +;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;; `EVENTTYPE_FD_WRITE`. (typename $event_fd_readwrite_t (struct ;; The number of bytes available for reading or writing. @@ -516,7 +513,7 @@ ) ;; The state of the file descriptor subscribed to with -;; `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. @@ -527,27 +524,27 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (flags u8 - ;; The time value of clock __wasi_subscription_t::u.clock.clock_id has - ;; reached timestamp __wasi_subscription_t::u.clock.timeout. + ;; The time value of clock `subscription_t::u.clock.clock_id` has + ;; reached timestamp `subscription_t::u.clock.timeout`. (flag $EVENTTYPE_CLOCK) - ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has data + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data ;; available for reading. This event always triggers for regular files. (flag $EVENTTYPE_FD_READ) - ;; File descriptor __wasi_subscription_t::u.fd_readwrite.fd has capacity + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity ;; available for writing. This event always triggers for regular files. (flag $EVENTTYPE_FD_WRITE) ) ) ;; Flags determining how to interpret the timestamp provided in -;; __wasi_subscription_t::u.clock.timeout. +;; `subscription_t::u.clock.timeout.` (typename $subclockflags_t (flags u16 ;; If set, treat the timestamp provided in - ;; __wasi_subscription_t::u.clock.timeout as an absolute timestamp of clock - ;; __wasi_subscription_t::u.clock.clock_id. If clear, treat the timestamp - ;; provided in __wasi_subscription_t::u.clock.timeout relative to the - ;; current time value of clock __wasi_subscription_t::u.clock.clock_id. + ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;; provided in `subscription_t::u.clock.timeout` relative to the + ;; current time value of clock `subscription_t::u.clock.clock_id.` (flag $SUBSCRIPTION_CLOCK_ABSTIME) ) ) @@ -556,7 +553,7 @@ (typename $subscription_t (struct ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through __wasi_event_t::userdata. + ;; implementation and returned through `event_t::userdata`. (field $userdata $userdata_t) ;; The type of the event to which to subscribe. (field $type $eventtype_t) @@ -568,14 +565,14 @@ ;; The contents of a $subscription_t. (typename $subscription_u (union - ;; When type is `__WASI_EVENTTYPE_CLOCK`: + ;; When type is `EVENTTYPE_CLOCK`: (field $clock $subscription_clock_t) - ;; When type is `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`: + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $subscription_fd_readwrite_t) ) ) -;; The contents of a $subscription_t when type is `__WASI_EVENTTYPE_CLOCK`. +;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct ;; The user-defined unique identifier of the clock. @@ -593,7 +590,7 @@ ) ;; The contents of a $subscription_t when type is type is -;; `__WASI_EVENTTYPE_FD_READ` or `__WASI_EVENTTYPE_FD_WRITE`. +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $subscription_fd_readwrite_t (struct ;; The file descriptor on which to wait for it to become ready for reading or writing. @@ -688,7 +685,7 @@ ) ) -;; Flags provided to `__wasi_sock_recv()`. +;; Flags provided to `sock_recv`. (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. @@ -698,15 +695,15 @@ ) ) -;; Flags returned by `__wasi_sock_recv()`. +;; Flags returned by `sock_recv`. (typename $roflags_t (flags u16 - ;; Returned by `__wasi_sock_recv()`: Message data has been truncated. + ;; Returned by `sock_recv`: Message data has been truncated. (flag $SOCK_RECV_DATA_TRUNCATED) ) ) -;; Flags provided to `__wasi_sock_send()`. As there are currently no flags +;; Flags provided to `sock_send`. As there are currently no flags ;; defined, it must be set to zero. (typename $siflags_t u16) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx b/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx index c47541b9a..4a48cc38b 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx @@ -392,7 +392,7 @@ ) ;; Remove a directory. - ;; Return `__WASI_ENOTEMPTY` if the directory is not empty. + ;; Return `ENOTEMPTY` if the directory is not empty. ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd_t) @@ -427,7 +427,7 @@ ;; Unlink a file. - ;; Return `__WASI_EISDIR` if the path refers to a directory. + ;; Return `EISDIR` if the path refers to a directory. ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd_t) From 0c5d5b8d0d08424d3ec9f1136eee003a12d75cb8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 10 Sep 2019 15:12:48 -0700 Subject: [PATCH 0157/1772] Pick up some validation fixes from lucet-idl. See https://github.com/fastly/lucet/pull/275/files#diff-1ac8557cf1c286d69d13ccaa4b21d291 --- .../clocks/design/wasi_unstable/wasi_unstable.witx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.witx b/proposals/clocks/design/wasi_unstable/wasi_unstable.witx index 4a48cc38b..6d4bea545 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/clocks/design/wasi_unstable/wasi_unstable.witx @@ -5,7 +5,7 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(use "typenames.wid") +(use "typenames.witx") (module $wasi_unstable ;; Linear memory to be accessed by WASI functions that need it. @@ -105,7 +105,7 @@ (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file descriptor's attributes are stored. - (result $fdstat_t) + (result $stat $fdstat_t) ) ;; Adjust the flags associated with a file descriptor. @@ -113,7 +113,7 @@ (@interface func (export "fd_fdstat_set_flags") (param $fd $fd_t) ;; The desired values of the file descriptor flags. - (param $flags $fdflags) + (param $flags $fdflags_t) (result $error $errno_t) ) @@ -332,13 +332,13 @@ ;; Create a hard link. ;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $fd $fd_t) + (param $old_fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) ;; The source path from which to link. (param $old_path string) ;; The working directory at which the resolution of the new path starts. - (param $new_fd $path) + (param $new_fd $fd_t) ;; The destination path at which to create the hard link. (param $new_path string) (result $error $errno_t) @@ -382,7 +382,7 @@ (@interface func (export "path_readlink") (param $fd $fd_t) ;; The path of the symbolic link from which to read. - (param $path) + (param $path string) ;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size_t) @@ -408,7 +408,7 @@ ;; The source path of the file or directory to rename. (param $old_path string) ;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) + (param $new_fd $fd_t) ;; The destination path to which to rename the file or directory. (param $new_path string) (result $error $errno_t) From d431563782937ced574afc5b88ab75f35b7de151 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 10 Sep 2019 15:12:48 -0700 Subject: [PATCH 0158/1772] Pick up some validation fixes from lucet-idl. See https://github.com/fastly/lucet/pull/275/files#diff-1ac8557cf1c286d69d13ccaa4b21d291 --- .../random/design/wasi_unstable/wasi_unstable.witx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.witx b/proposals/random/design/wasi_unstable/wasi_unstable.witx index 4a48cc38b..6d4bea545 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/random/design/wasi_unstable/wasi_unstable.witx @@ -5,7 +5,7 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(use "typenames.wid") +(use "typenames.witx") (module $wasi_unstable ;; Linear memory to be accessed by WASI functions that need it. @@ -105,7 +105,7 @@ (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file descriptor's attributes are stored. - (result $fdstat_t) + (result $stat $fdstat_t) ) ;; Adjust the flags associated with a file descriptor. @@ -113,7 +113,7 @@ (@interface func (export "fd_fdstat_set_flags") (param $fd $fd_t) ;; The desired values of the file descriptor flags. - (param $flags $fdflags) + (param $flags $fdflags_t) (result $error $errno_t) ) @@ -332,13 +332,13 @@ ;; Create a hard link. ;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $fd $fd_t) + (param $old_fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) ;; The source path from which to link. (param $old_path string) ;; The working directory at which the resolution of the new path starts. - (param $new_fd $path) + (param $new_fd $fd_t) ;; The destination path at which to create the hard link. (param $new_path string) (result $error $errno_t) @@ -382,7 +382,7 @@ (@interface func (export "path_readlink") (param $fd $fd_t) ;; The path of the symbolic link from which to read. - (param $path) + (param $path string) ;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size_t) @@ -408,7 +408,7 @@ ;; The source path of the file or directory to rename. (param $old_path string) ;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) + (param $new_fd $fd_t) ;; The destination path to which to rename the file or directory. (param $new_path string) (result $error $errno_t) From eaf67edd6cb2e521271b1b32048b945d4f5128c8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 10 Sep 2019 15:12:48 -0700 Subject: [PATCH 0159/1772] Pick up some validation fixes from lucet-idl. See https://github.com/fastly/lucet/pull/275/files#diff-1ac8557cf1c286d69d13ccaa4b21d291 --- .../design/wasi_unstable/wasi_unstable.witx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx b/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx index 4a48cc38b..6d4bea545 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx @@ -5,7 +5,7 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(use "typenames.wid") +(use "typenames.witx") (module $wasi_unstable ;; Linear memory to be accessed by WASI functions that need it. @@ -105,7 +105,7 @@ (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file descriptor's attributes are stored. - (result $fdstat_t) + (result $stat $fdstat_t) ) ;; Adjust the flags associated with a file descriptor. @@ -113,7 +113,7 @@ (@interface func (export "fd_fdstat_set_flags") (param $fd $fd_t) ;; The desired values of the file descriptor flags. - (param $flags $fdflags) + (param $flags $fdflags_t) (result $error $errno_t) ) @@ -332,13 +332,13 @@ ;; Create a hard link. ;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $fd $fd_t) + (param $old_fd $fd_t) ;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) ;; The source path from which to link. (param $old_path string) ;; The working directory at which the resolution of the new path starts. - (param $new_fd $path) + (param $new_fd $fd_t) ;; The destination path at which to create the hard link. (param $new_path string) (result $error $errno_t) @@ -382,7 +382,7 @@ (@interface func (export "path_readlink") (param $fd $fd_t) ;; The path of the symbolic link from which to read. - (param $path) + (param $path string) ;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size_t) @@ -408,7 +408,7 @@ ;; The source path of the file or directory to rename. (param $old_path string) ;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) + (param $new_fd $fd_t) ;; The destination path to which to rename the file or directory. (param $new_path string) (result $error $errno_t) From c6d054d51d68a50b45a98f295d2e5a4619fe819e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 10 Sep 2019 15:24:32 -0700 Subject: [PATCH 0160/1772] Reorder typenames so that definitions precede uses. The wat format allows forward references to '$' identifiers, so we'll probably have to support this eventually too, but for now, reorder things to make it easy to process. --- .../design/wasi_unstable/typenames.witx | 202 +++++++++--------- 1 file changed, 101 insertions(+), 101 deletions(-) diff --git a/proposals/clocks/design/wasi_unstable/typenames.witx b/proposals/clocks/design/wasi_unstable/typenames.witx index 4bab30735..1d33a35f0 100644 --- a/proposals/clocks/design/wasi_unstable/typenames.witx +++ b/proposals/clocks/design/wasi_unstable/typenames.witx @@ -276,9 +276,6 @@ ;; A file descriptor index. (typename $fd_t u32) -(typename $iovec_t_array (array $iovec_t)) -(typename $ciovec_t_array (array $ciovec_t)) - ;; A region of memory for scatter/gather reads. (typename $iovec_t (struct @@ -299,6 +296,9 @@ ) ) +(typename $iovec_t_array (array $iovec_t)) +(typename $ciovec_t_array (array $ciovec_t)) + ;; Relative offset within a file. (typename $filedelta_t s64) @@ -317,9 +317,34 @@ ;; A reference to the offset of a directory entry. (typename $dircookie_t u64) -;; The type for the $d_namelen field of $dirent_t. +;; The type for the $d_namlen field of $dirent_t. (typename $dirnamlen_t u32) +;; File serial number that is unique within its file system. +(typename $inode_t u64) + +;; The type of a file descriptor or file. +(typename $filetype_t + (enum u8 + ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $FILETYPE_UNKNOWN + ;; The file descriptor or file refers to a block device inode. + $FILETYPE_BLOCK_DEVICE + ;; The file descriptor or file refers to a character device inode. + $FILETYPE_CHARACTER_DEVICE + ;; The file descriptor or file refers to a directory inode. + $FILETYPE_DIRECTORY + ;; The file descriptor or file refers to a regular file inode. + $FILETYPE_REGULAR_FILE + ;; The file descriptor or file refers to a datagram socket. + $FILETYPE_SOCKET_DGRAM + ;; The file descriptor or file refers to a byte-stream socket. + $FILETYPE_SOCKET_STREAM + ;; The file refers to a symbolic link inode. + $FILETYPE_SYMBOLIC_LINK + ) +) + ;; A directory entry. (typename $dirent_t (struct @@ -328,7 +353,7 @@ ;; The serial number of the file referred to by this directory entry. (field $d_ino $inode_t) ;; The length of the name of the directory entry. - (field $d_namlen $dirnamelen_t) + (field $d_namlen $dirnamlen_t) ;; The type of the file referred to by this directory entry. (field $d_type $filetype_t) ) @@ -389,28 +414,6 @@ ;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) -;; The type of a file descriptor or file. -(typename $filetype_t - (enum u8 - ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $FILETYPE_UNKNOWN - ;; The file descriptor or file refers to a block device inode. - $FILETYPE_BLOCK_DEVICE - ;; The file descriptor or file refers to a character device inode. - $FILETYPE_CHARACTER_DEVICE - ;; The file descriptor or file refers to a directory inode. - $FILETYPE_DIRECTORY - ;; The file descriptor or file refers to a regular file inode. - $FILETYPE_REGULAR_FILE - ;; The file descriptor or file refers to a datagram socket. - $FILETYPE_SOCKET_DGRAM - ;; The file descriptor or file refers to a byte-stream socket. - $FILETYPE_SOCKET_STREAM - ;; The file refers to a symbolic link inode. - $FILETYPE_SYMBOLIC_LINK - ) -) - ;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 @@ -425,9 +428,6 @@ ) ) -;; File serial number that is unique within its file system. -(typename $inode_t u64) - ;; Flags determining the method of how paths are resolved. (typename $lookupflags_t (flags u32 @@ -479,25 +479,27 @@ ;; extracted from the implementation. (typename $userdata_t u64) -;; An event that occurred. -(typename $event_t - (struct - ;; User-provided value that got attached to `subscription_t::userdata`. - (field $userdata $userdata_t) - ;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno_t) - ;; The type of the event that occurred. - (field $type $eventtype_t) - ;; The contents of the event. - (field $u $event_u) +;; Type of a subscription to an event or its occurrence. +(typename $eventtype_t + (flags u8 + ;; The time value of clock `subscription_t::u.clock.clock_id` has + ;; reached timestamp `subscription_t::u.clock.timeout`. + (flag $EVENTTYPE_CLOCK) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;; available for reading. This event always triggers for regular files. + (flag $EVENTTYPE_FD_READ) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;; available for writing. This event always triggers for regular files. + (flag $EVENTTYPE_FD_WRITE) ) ) -;; The contents of an $event_t. -(typename $event_u - (union - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $event_fd_readwrite_t) +;; The state of the file descriptor subscribed to with +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $eventrwflags_t + (flags u16 + ;; The peer of this socket has closed or disconnected. + (flag $EVENT_FD_READWRITE_HANGUP) ) ) @@ -512,27 +514,25 @@ ) ) -;; The state of the file descriptor subscribed to with -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $eventrwflags_t - (flags u16 - ;; The peer of this socket has closed or disconnected. - (flag $EVENT_FD_READWRITE_HANGUP) +;; The contents of an $event_t. +(typename $event_u + (union + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; Type of a subscription to an event or its occurrence. -(typename $eventtype_t - (flags u8 - ;; The time value of clock `subscription_t::u.clock.clock_id` has - ;; reached timestamp `subscription_t::u.clock.timeout`. - (flag $EVENTTYPE_CLOCK) - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data - ;; available for reading. This event always triggers for regular files. - (flag $EVENTTYPE_FD_READ) - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity - ;; available for writing. This event always triggers for regular files. - (flag $EVENTTYPE_FD_WRITE) +;; An event that occurred. +(typename $event_t + (struct + ;; User-provided value that got attached to `subscription_t::userdata`. + (field $userdata $userdata_t) + ;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno_t) + ;; The type of the event that occurred. + (field $type $eventtype_t) + ;; The contents of the event. + (field $u $event_u) ) ) @@ -549,29 +549,6 @@ ) ) -;; Subscription to an event. -(typename $subscription_t - (struct - ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through `event_t::userdata`. - (field $userdata $userdata_t) - ;; The type of the event to which to subscribe. - (field $type $eventtype_t) - ;; The contents of the subscription. - (field $u $subscription_u) - ) -) - -;; The contents of a $subscription_t. -(typename $subscription_u - (union - ;; When type is `EVENTTYPE_CLOCK`: - (field $clock $subscription_clock_t) - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $subscription_fd_readwrite_t) - ) -) - ;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct @@ -598,6 +575,29 @@ ) ) +;; The contents of a $subscription_t. +(typename $subscription_u + (union + ;; When type is `EVENTTYPE_CLOCK`: + (field $clock $subscription_clock_t) + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $subscription_fd_readwrite_t) + ) +) + +;; Subscription to an event. +(typename $subscription_t + (struct + ;; User-provided value that is attached to the subscription in the + ;; implementation and returned through `event_t::userdata`. + (field $userdata $userdata_t) + ;; The type of the event to which to subscribe. + (field $type $eventtype_t) + ;; The contents of the subscription. + (field $u $subscription_u) + ) +) + ;; Exit code generated by a process when exiting. (typename $exitcode_t u32) @@ -717,16 +717,6 @@ ) ) -;; Information about a pre-opened capability. -(typename $prestat_t - (struct - ;; The type of the pre-opened capability. - (field $pr_type $preopentype_t) - ;; The contents of the information. - (field $u $prestat_u) - ) -) - ;; Identifiers for preopened capabilities. (typename preopentype_t (enum u8 @@ -735,6 +725,14 @@ ) ) +;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +(typename $prestat_dir + (struct + ;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size_t) + ) +) + ;; The contents of an $prestat_t. (typename $prestat_u (union @@ -743,10 +741,12 @@ ) ) -;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. -(typename $prestat_dir +;; Information about a pre-opened capability. +(typename $prestat_t (struct - ;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size_t) + ;; The type of the pre-opened capability. + (field $pr_type $preopentype_t) + ;; The contents of the information. + (field $u $prestat_u) ) ) From 01ba2ca3cfe047be501dc3dd047f58b72969a553 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 10 Sep 2019 15:24:32 -0700 Subject: [PATCH 0161/1772] Reorder typenames so that definitions precede uses. The wat format allows forward references to '$' identifiers, so we'll probably have to support this eventually too, but for now, reorder things to make it easy to process. --- .../design/wasi_unstable/typenames.witx | 202 +++++++++--------- 1 file changed, 101 insertions(+), 101 deletions(-) diff --git a/proposals/random/design/wasi_unstable/typenames.witx b/proposals/random/design/wasi_unstable/typenames.witx index 4bab30735..1d33a35f0 100644 --- a/proposals/random/design/wasi_unstable/typenames.witx +++ b/proposals/random/design/wasi_unstable/typenames.witx @@ -276,9 +276,6 @@ ;; A file descriptor index. (typename $fd_t u32) -(typename $iovec_t_array (array $iovec_t)) -(typename $ciovec_t_array (array $ciovec_t)) - ;; A region of memory for scatter/gather reads. (typename $iovec_t (struct @@ -299,6 +296,9 @@ ) ) +(typename $iovec_t_array (array $iovec_t)) +(typename $ciovec_t_array (array $ciovec_t)) + ;; Relative offset within a file. (typename $filedelta_t s64) @@ -317,9 +317,34 @@ ;; A reference to the offset of a directory entry. (typename $dircookie_t u64) -;; The type for the $d_namelen field of $dirent_t. +;; The type for the $d_namlen field of $dirent_t. (typename $dirnamlen_t u32) +;; File serial number that is unique within its file system. +(typename $inode_t u64) + +;; The type of a file descriptor or file. +(typename $filetype_t + (enum u8 + ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $FILETYPE_UNKNOWN + ;; The file descriptor or file refers to a block device inode. + $FILETYPE_BLOCK_DEVICE + ;; The file descriptor or file refers to a character device inode. + $FILETYPE_CHARACTER_DEVICE + ;; The file descriptor or file refers to a directory inode. + $FILETYPE_DIRECTORY + ;; The file descriptor or file refers to a regular file inode. + $FILETYPE_REGULAR_FILE + ;; The file descriptor or file refers to a datagram socket. + $FILETYPE_SOCKET_DGRAM + ;; The file descriptor or file refers to a byte-stream socket. + $FILETYPE_SOCKET_STREAM + ;; The file refers to a symbolic link inode. + $FILETYPE_SYMBOLIC_LINK + ) +) + ;; A directory entry. (typename $dirent_t (struct @@ -328,7 +353,7 @@ ;; The serial number of the file referred to by this directory entry. (field $d_ino $inode_t) ;; The length of the name of the directory entry. - (field $d_namlen $dirnamelen_t) + (field $d_namlen $dirnamlen_t) ;; The type of the file referred to by this directory entry. (field $d_type $filetype_t) ) @@ -389,28 +414,6 @@ ;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) -;; The type of a file descriptor or file. -(typename $filetype_t - (enum u8 - ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $FILETYPE_UNKNOWN - ;; The file descriptor or file refers to a block device inode. - $FILETYPE_BLOCK_DEVICE - ;; The file descriptor or file refers to a character device inode. - $FILETYPE_CHARACTER_DEVICE - ;; The file descriptor or file refers to a directory inode. - $FILETYPE_DIRECTORY - ;; The file descriptor or file refers to a regular file inode. - $FILETYPE_REGULAR_FILE - ;; The file descriptor or file refers to a datagram socket. - $FILETYPE_SOCKET_DGRAM - ;; The file descriptor or file refers to a byte-stream socket. - $FILETYPE_SOCKET_STREAM - ;; The file refers to a symbolic link inode. - $FILETYPE_SYMBOLIC_LINK - ) -) - ;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 @@ -425,9 +428,6 @@ ) ) -;; File serial number that is unique within its file system. -(typename $inode_t u64) - ;; Flags determining the method of how paths are resolved. (typename $lookupflags_t (flags u32 @@ -479,25 +479,27 @@ ;; extracted from the implementation. (typename $userdata_t u64) -;; An event that occurred. -(typename $event_t - (struct - ;; User-provided value that got attached to `subscription_t::userdata`. - (field $userdata $userdata_t) - ;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno_t) - ;; The type of the event that occurred. - (field $type $eventtype_t) - ;; The contents of the event. - (field $u $event_u) +;; Type of a subscription to an event or its occurrence. +(typename $eventtype_t + (flags u8 + ;; The time value of clock `subscription_t::u.clock.clock_id` has + ;; reached timestamp `subscription_t::u.clock.timeout`. + (flag $EVENTTYPE_CLOCK) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;; available for reading. This event always triggers for regular files. + (flag $EVENTTYPE_FD_READ) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;; available for writing. This event always triggers for regular files. + (flag $EVENTTYPE_FD_WRITE) ) ) -;; The contents of an $event_t. -(typename $event_u - (union - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $event_fd_readwrite_t) +;; The state of the file descriptor subscribed to with +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $eventrwflags_t + (flags u16 + ;; The peer of this socket has closed or disconnected. + (flag $EVENT_FD_READWRITE_HANGUP) ) ) @@ -512,27 +514,25 @@ ) ) -;; The state of the file descriptor subscribed to with -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $eventrwflags_t - (flags u16 - ;; The peer of this socket has closed or disconnected. - (flag $EVENT_FD_READWRITE_HANGUP) +;; The contents of an $event_t. +(typename $event_u + (union + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; Type of a subscription to an event or its occurrence. -(typename $eventtype_t - (flags u8 - ;; The time value of clock `subscription_t::u.clock.clock_id` has - ;; reached timestamp `subscription_t::u.clock.timeout`. - (flag $EVENTTYPE_CLOCK) - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data - ;; available for reading. This event always triggers for regular files. - (flag $EVENTTYPE_FD_READ) - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity - ;; available for writing. This event always triggers for regular files. - (flag $EVENTTYPE_FD_WRITE) +;; An event that occurred. +(typename $event_t + (struct + ;; User-provided value that got attached to `subscription_t::userdata`. + (field $userdata $userdata_t) + ;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno_t) + ;; The type of the event that occurred. + (field $type $eventtype_t) + ;; The contents of the event. + (field $u $event_u) ) ) @@ -549,29 +549,6 @@ ) ) -;; Subscription to an event. -(typename $subscription_t - (struct - ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through `event_t::userdata`. - (field $userdata $userdata_t) - ;; The type of the event to which to subscribe. - (field $type $eventtype_t) - ;; The contents of the subscription. - (field $u $subscription_u) - ) -) - -;; The contents of a $subscription_t. -(typename $subscription_u - (union - ;; When type is `EVENTTYPE_CLOCK`: - (field $clock $subscription_clock_t) - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $subscription_fd_readwrite_t) - ) -) - ;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct @@ -598,6 +575,29 @@ ) ) +;; The contents of a $subscription_t. +(typename $subscription_u + (union + ;; When type is `EVENTTYPE_CLOCK`: + (field $clock $subscription_clock_t) + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $subscription_fd_readwrite_t) + ) +) + +;; Subscription to an event. +(typename $subscription_t + (struct + ;; User-provided value that is attached to the subscription in the + ;; implementation and returned through `event_t::userdata`. + (field $userdata $userdata_t) + ;; The type of the event to which to subscribe. + (field $type $eventtype_t) + ;; The contents of the subscription. + (field $u $subscription_u) + ) +) + ;; Exit code generated by a process when exiting. (typename $exitcode_t u32) @@ -717,16 +717,6 @@ ) ) -;; Information about a pre-opened capability. -(typename $prestat_t - (struct - ;; The type of the pre-opened capability. - (field $pr_type $preopentype_t) - ;; The contents of the information. - (field $u $prestat_u) - ) -) - ;; Identifiers for preopened capabilities. (typename preopentype_t (enum u8 @@ -735,6 +725,14 @@ ) ) +;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +(typename $prestat_dir + (struct + ;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size_t) + ) +) + ;; The contents of an $prestat_t. (typename $prestat_u (union @@ -743,10 +741,12 @@ ) ) -;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. -(typename $prestat_dir +;; Information about a pre-opened capability. +(typename $prestat_t (struct - ;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size_t) + ;; The type of the pre-opened capability. + (field $pr_type $preopentype_t) + ;; The contents of the information. + (field $u $prestat_u) ) ) From ae94560add17f1f0ed8265abe02b02fa786845bf Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 10 Sep 2019 15:24:32 -0700 Subject: [PATCH 0162/1772] Reorder typenames so that definitions precede uses. The wat format allows forward references to '$' identifiers, so we'll probably have to support this eventually too, but for now, reorder things to make it easy to process. --- .../design/wasi_unstable/typenames.witx | 202 +++++++++--------- 1 file changed, 101 insertions(+), 101 deletions(-) diff --git a/proposals/filesystem/design/wasi_unstable/typenames.witx b/proposals/filesystem/design/wasi_unstable/typenames.witx index 4bab30735..1d33a35f0 100644 --- a/proposals/filesystem/design/wasi_unstable/typenames.witx +++ b/proposals/filesystem/design/wasi_unstable/typenames.witx @@ -276,9 +276,6 @@ ;; A file descriptor index. (typename $fd_t u32) -(typename $iovec_t_array (array $iovec_t)) -(typename $ciovec_t_array (array $ciovec_t)) - ;; A region of memory for scatter/gather reads. (typename $iovec_t (struct @@ -299,6 +296,9 @@ ) ) +(typename $iovec_t_array (array $iovec_t)) +(typename $ciovec_t_array (array $ciovec_t)) + ;; Relative offset within a file. (typename $filedelta_t s64) @@ -317,9 +317,34 @@ ;; A reference to the offset of a directory entry. (typename $dircookie_t u64) -;; The type for the $d_namelen field of $dirent_t. +;; The type for the $d_namlen field of $dirent_t. (typename $dirnamlen_t u32) +;; File serial number that is unique within its file system. +(typename $inode_t u64) + +;; The type of a file descriptor or file. +(typename $filetype_t + (enum u8 + ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $FILETYPE_UNKNOWN + ;; The file descriptor or file refers to a block device inode. + $FILETYPE_BLOCK_DEVICE + ;; The file descriptor or file refers to a character device inode. + $FILETYPE_CHARACTER_DEVICE + ;; The file descriptor or file refers to a directory inode. + $FILETYPE_DIRECTORY + ;; The file descriptor or file refers to a regular file inode. + $FILETYPE_REGULAR_FILE + ;; The file descriptor or file refers to a datagram socket. + $FILETYPE_SOCKET_DGRAM + ;; The file descriptor or file refers to a byte-stream socket. + $FILETYPE_SOCKET_STREAM + ;; The file refers to a symbolic link inode. + $FILETYPE_SYMBOLIC_LINK + ) +) + ;; A directory entry. (typename $dirent_t (struct @@ -328,7 +353,7 @@ ;; The serial number of the file referred to by this directory entry. (field $d_ino $inode_t) ;; The length of the name of the directory entry. - (field $d_namlen $dirnamelen_t) + (field $d_namlen $dirnamlen_t) ;; The type of the file referred to by this directory entry. (field $d_type $filetype_t) ) @@ -389,28 +414,6 @@ ;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) -;; The type of a file descriptor or file. -(typename $filetype_t - (enum u8 - ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $FILETYPE_UNKNOWN - ;; The file descriptor or file refers to a block device inode. - $FILETYPE_BLOCK_DEVICE - ;; The file descriptor or file refers to a character device inode. - $FILETYPE_CHARACTER_DEVICE - ;; The file descriptor or file refers to a directory inode. - $FILETYPE_DIRECTORY - ;; The file descriptor or file refers to a regular file inode. - $FILETYPE_REGULAR_FILE - ;; The file descriptor or file refers to a datagram socket. - $FILETYPE_SOCKET_DGRAM - ;; The file descriptor or file refers to a byte-stream socket. - $FILETYPE_SOCKET_STREAM - ;; The file refers to a symbolic link inode. - $FILETYPE_SYMBOLIC_LINK - ) -) - ;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 @@ -425,9 +428,6 @@ ) ) -;; File serial number that is unique within its file system. -(typename $inode_t u64) - ;; Flags determining the method of how paths are resolved. (typename $lookupflags_t (flags u32 @@ -479,25 +479,27 @@ ;; extracted from the implementation. (typename $userdata_t u64) -;; An event that occurred. -(typename $event_t - (struct - ;; User-provided value that got attached to `subscription_t::userdata`. - (field $userdata $userdata_t) - ;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno_t) - ;; The type of the event that occurred. - (field $type $eventtype_t) - ;; The contents of the event. - (field $u $event_u) +;; Type of a subscription to an event or its occurrence. +(typename $eventtype_t + (flags u8 + ;; The time value of clock `subscription_t::u.clock.clock_id` has + ;; reached timestamp `subscription_t::u.clock.timeout`. + (flag $EVENTTYPE_CLOCK) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;; available for reading. This event always triggers for regular files. + (flag $EVENTTYPE_FD_READ) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;; available for writing. This event always triggers for regular files. + (flag $EVENTTYPE_FD_WRITE) ) ) -;; The contents of an $event_t. -(typename $event_u - (union - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $event_fd_readwrite_t) +;; The state of the file descriptor subscribed to with +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $eventrwflags_t + (flags u16 + ;; The peer of this socket has closed or disconnected. + (flag $EVENT_FD_READWRITE_HANGUP) ) ) @@ -512,27 +514,25 @@ ) ) -;; The state of the file descriptor subscribed to with -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $eventrwflags_t - (flags u16 - ;; The peer of this socket has closed or disconnected. - (flag $EVENT_FD_READWRITE_HANGUP) +;; The contents of an $event_t. +(typename $event_u + (union + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; Type of a subscription to an event or its occurrence. -(typename $eventtype_t - (flags u8 - ;; The time value of clock `subscription_t::u.clock.clock_id` has - ;; reached timestamp `subscription_t::u.clock.timeout`. - (flag $EVENTTYPE_CLOCK) - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data - ;; available for reading. This event always triggers for regular files. - (flag $EVENTTYPE_FD_READ) - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity - ;; available for writing. This event always triggers for regular files. - (flag $EVENTTYPE_FD_WRITE) +;; An event that occurred. +(typename $event_t + (struct + ;; User-provided value that got attached to `subscription_t::userdata`. + (field $userdata $userdata_t) + ;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno_t) + ;; The type of the event that occurred. + (field $type $eventtype_t) + ;; The contents of the event. + (field $u $event_u) ) ) @@ -549,29 +549,6 @@ ) ) -;; Subscription to an event. -(typename $subscription_t - (struct - ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through `event_t::userdata`. - (field $userdata $userdata_t) - ;; The type of the event to which to subscribe. - (field $type $eventtype_t) - ;; The contents of the subscription. - (field $u $subscription_u) - ) -) - -;; The contents of a $subscription_t. -(typename $subscription_u - (union - ;; When type is `EVENTTYPE_CLOCK`: - (field $clock $subscription_clock_t) - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $subscription_fd_readwrite_t) - ) -) - ;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct @@ -598,6 +575,29 @@ ) ) +;; The contents of a $subscription_t. +(typename $subscription_u + (union + ;; When type is `EVENTTYPE_CLOCK`: + (field $clock $subscription_clock_t) + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $subscription_fd_readwrite_t) + ) +) + +;; Subscription to an event. +(typename $subscription_t + (struct + ;; User-provided value that is attached to the subscription in the + ;; implementation and returned through `event_t::userdata`. + (field $userdata $userdata_t) + ;; The type of the event to which to subscribe. + (field $type $eventtype_t) + ;; The contents of the subscription. + (field $u $subscription_u) + ) +) + ;; Exit code generated by a process when exiting. (typename $exitcode_t u32) @@ -717,16 +717,6 @@ ) ) -;; Information about a pre-opened capability. -(typename $prestat_t - (struct - ;; The type of the pre-opened capability. - (field $pr_type $preopentype_t) - ;; The contents of the information. - (field $u $prestat_u) - ) -) - ;; Identifiers for preopened capabilities. (typename preopentype_t (enum u8 @@ -735,6 +725,14 @@ ) ) +;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +(typename $prestat_dir + (struct + ;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size_t) + ) +) + ;; The contents of an $prestat_t. (typename $prestat_u (union @@ -743,10 +741,12 @@ ) ) -;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. -(typename $prestat_dir +;; Information about a pre-opened capability. +(typename $prestat_t (struct - ;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size_t) + ;; The type of the pre-opened capability. + (field $pr_type $preopentype_t) + ;; The contents of the information. + (field $u $prestat_u) ) ) From b771ea33838ac6e9aa6fb59232d62e6fbc68545c Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 13 Sep 2019 10:27:21 -0700 Subject: [PATCH 0163/1772] Add witx crate, to parse and validate witx (#90) * import witx-frontend crate * witx-frontend: add test that wasi_unstable.witx validates * witx-frontend: better error reporting * witx-frontend: add witx-specific pointer and constpointer constructions * wasi_unstable: fix syntax of preopentype_t * witx-frontend: add LICENSE file, fix repo capitalization * rename witx-frontend to witx --- .../design/wasi_unstable/typenames.witx | 2 +- proposals/clocks/tools/witx/.gitignore | 2 + proposals/clocks/tools/witx/Cargo.toml | 21 + proposals/clocks/tools/witx/LICENSE | 13 + proposals/clocks/tools/witx/src/ast.rs | 163 +++++ proposals/clocks/tools/witx/src/lexer.rs | 354 +++++++++++ proposals/clocks/tools/witx/src/lib.rs | 93 +++ proposals/clocks/tools/witx/src/main.rs | 38 ++ proposals/clocks/tools/witx/src/parser.rs | 583 ++++++++++++++++++ proposals/clocks/tools/witx/src/sexpr.rs | 236 +++++++ proposals/clocks/tools/witx/src/toplevel.rs | 243 ++++++++ proposals/clocks/tools/witx/src/validate.rs | 390 ++++++++++++ .../clocks/tools/witx/tests/wasi_unstable.rs | 7 + 13 files changed, 2144 insertions(+), 1 deletion(-) create mode 100644 proposals/clocks/tools/witx/.gitignore create mode 100644 proposals/clocks/tools/witx/Cargo.toml create mode 100644 proposals/clocks/tools/witx/LICENSE create mode 100644 proposals/clocks/tools/witx/src/ast.rs create mode 100644 proposals/clocks/tools/witx/src/lexer.rs create mode 100644 proposals/clocks/tools/witx/src/lib.rs create mode 100644 proposals/clocks/tools/witx/src/main.rs create mode 100644 proposals/clocks/tools/witx/src/parser.rs create mode 100644 proposals/clocks/tools/witx/src/sexpr.rs create mode 100644 proposals/clocks/tools/witx/src/toplevel.rs create mode 100644 proposals/clocks/tools/witx/src/validate.rs create mode 100644 proposals/clocks/tools/witx/tests/wasi_unstable.rs diff --git a/proposals/clocks/design/wasi_unstable/typenames.witx b/proposals/clocks/design/wasi_unstable/typenames.witx index 1d33a35f0..046ed0bf6 100644 --- a/proposals/clocks/design/wasi_unstable/typenames.witx +++ b/proposals/clocks/design/wasi_unstable/typenames.witx @@ -718,7 +718,7 @@ ) ;; Identifiers for preopened capabilities. -(typename preopentype_t +(typename $preopentype_t (enum u8 ;; A pre-opened directory. $PREOPENTYPE_DIR diff --git a/proposals/clocks/tools/witx/.gitignore b/proposals/clocks/tools/witx/.gitignore new file mode 100644 index 000000000..a9d37c560 --- /dev/null +++ b/proposals/clocks/tools/witx/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml new file mode 100644 index 000000000..f24cb7183 --- /dev/null +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "witx" +version = "0.1.0" +description = "Parse and validate witx file format" +homepage = "https://github.com/WebAssembly/WASI" +repository = "https://github.com/WebAssembly/WASI" +license = "Apache-2.0" +categories = ["wasm"] +authors = ["Pat Hickey "] +edition = "2018" + +[lib] +crate-type=["rlib"] + +[[bin]] +name = "witx" +path = "src/main.rs" + +[dependencies] +clap = "2" +failure = "0.1" diff --git a/proposals/clocks/tools/witx/LICENSE b/proposals/clocks/tools/witx/LICENSE new file mode 100644 index 000000000..e061f56ab --- /dev/null +++ b/proposals/clocks/tools/witx/LICENSE @@ -0,0 +1,13 @@ +Copyright 2019 WebAssembly Community Group participants + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs new file mode 100644 index 000000000..4df4d1e24 --- /dev/null +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -0,0 +1,163 @@ +#![allow(dead_code)] +use std::collections::HashMap; +use std::rc::{Rc, Weak}; + +pub use crate::parser::BuiltinType; + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Id(String); + +impl Id { + pub fn new>(s: S) -> Self { + Id(s.as_ref().to_string()) + } + pub fn as_str(&self) -> &str { + self.0.as_str() + } +} + +#[derive(Debug, Clone)] +pub struct Document { + pub definitions: Vec, + pub entries: HashMap, +} + +#[derive(Debug, Clone)] +pub enum Definition { + Datatype(Rc), + Module(Rc), +} + +#[derive(Debug, Clone)] +pub enum Entry { + Datatype(Weak), + Module(Weak), +} + +impl Entry { + pub fn kind(&self) -> &'static str { + match self { + Entry::Datatype { .. } => "datatype", + Entry::Module { .. } => "module", + } + } +} + +#[derive(Debug, Clone)] +pub enum DatatypeIdent { + Builtin(BuiltinType), + Array(Box), + Pointer(Box), + ConstPointer(Box), + Ident(Rc), +} + +#[derive(Debug, Clone)] +pub struct Datatype { + pub name: Id, + pub variant: DatatypeVariant, +} + +#[derive(Debug, Clone)] +pub enum DatatypeVariant { + Alias(AliasDatatype), + Enum(EnumDatatype), + Flags(FlagsDatatype), + Struct(StructDatatype), + Union(UnionDatatype), +} + +#[derive(Debug, Clone)] +pub struct AliasDatatype { + pub name: Id, + pub to: DatatypeIdent, +} + +#[derive(Debug, Clone)] +pub enum IntRepr { + I8, + I16, + I32, + I64, +} + +#[derive(Debug, Clone)] +pub struct EnumDatatype { + pub name: Id, + pub repr: IntRepr, + pub variants: Vec, +} + +#[derive(Debug, Clone)] +pub struct FlagsDatatype { + pub name: Id, + pub repr: IntRepr, + pub flags: Vec, +} + +#[derive(Debug, Clone)] +pub struct StructDatatype { + pub name: Id, + pub members: Vec, +} + +#[derive(Debug, Clone)] +pub struct StructMember { + pub name: Id, + pub type_: DatatypeIdent, +} + +#[derive(Debug, Clone)] +pub struct UnionDatatype { + pub name: Id, + pub variants: Vec, +} + +#[derive(Debug, Clone)] +pub struct UnionVariant { + pub name: Id, + pub type_: DatatypeIdent, +} + +#[derive(Debug, Clone)] +pub struct Module { + pub name: Id, + pub definitions: Vec, + pub entries: HashMap, +} + +#[derive(Debug, Clone)] +pub enum ModuleDefinition { + Import(Rc), + Func(Rc), +} + +#[derive(Debug, Clone)] +pub enum ModuleEntry { + Import(Weak), + Func(Weak), +} + +#[derive(Debug, Clone)] +pub struct ModuleImport { + pub name: Id, + pub variant: ModuleImportVariant, +} + +#[derive(Debug, Clone)] +pub enum ModuleImportVariant { + Memory, +} + +#[derive(Debug, Clone)] +pub struct InterfaceFunc { + pub name: Id, + pub params: Vec, + pub results: Vec, +} + +#[derive(Debug, Clone)] +pub struct InterfaceFuncParam { + pub name: Id, + pub type_: DatatypeIdent, +} diff --git a/proposals/clocks/tools/witx/src/lexer.rs b/proposals/clocks/tools/witx/src/lexer.rs new file mode 100644 index 000000000..b004acf07 --- /dev/null +++ b/proposals/clocks/tools/witx/src/lexer.rs @@ -0,0 +1,354 @@ +use crate::Location; +use failure::Fail; +use std::path::{Path, PathBuf}; +use std::str::CharIndices; + +///! The lexer turns a string into a stream of located tokens. +///! The tokens are meant for consumption by the s-expression parser. +///! +///! Comments in source text look like `;; rest of line ...`. +///! Words look like `abcde_` +///! Idents look like `$abcde_` +///! Annotations look like `@abcde_` +///! Quotes look like `"a b cde 123 @#$%^&*() _"` +///! +///! This implementation was heavily influenced by `cranelift-reader` + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum Token<'a> { + LPar, // ( + RPar, // ) + Word(&'a str), // Bare word + Ident(&'a str), // Starts with $ + Annot(&'a str), // Starts with @. short for annotation. + Quote(&'a str), // Found between balanced "". No escaping. +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct LocatedToken<'a> { + pub token: Token<'a>, + pub location: Location, +} + +fn token(token: Token<'_>, location: Location) -> Result, LocatedError> { + Ok(LocatedToken { token, location }) +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy, Fail)] +pub enum LexError { + #[fail(display = "Invalid character '{}'", _0)] + InvalidChar(char), + #[fail(display = "Empty identifier '$'")] + EmptyIdentifier, + #[fail(display = "Empty annotation '@'")] + EmptyAnnotation, + #[fail(display = "Unterminated quote")] + UnterminatedQuote, +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct LocatedError { + pub error: LexError, + pub location: Location, +} + +fn error<'a>(error: LexError, location: Location) -> Result, LocatedError> { + Err(LocatedError { error, location }) +} + +pub struct Lexer<'a> { + source: &'a str, + chars: CharIndices<'a>, + lookahead: Option, + pos: usize, + line_number: usize, + column_start: usize, + tab_compensation: usize, + path: PathBuf, +} + +impl<'a> Lexer<'a> { + pub fn new>(s: &'a str, path: P) -> Lexer<'_> { + let mut lex = Lexer { + source: s, + chars: s.char_indices(), + lookahead: None, + pos: 0, + line_number: 1, + column_start: 0, + tab_compensation: 0, + path: path.as_ref().into(), + }; + lex.next_ch(); + lex + } + + fn next_ch(&mut self) -> Option { + if self.lookahead == Some('\n') { + self.line_number += 1; + self.column_start = self.pos + 1; // Next column starts a fresh line + self.tab_compensation = 0; + } else if self.lookahead == Some('\t') { + self.tab_compensation += 7; // One column for the position of the char itself, add 7 more for a tabwidth of 8 + } + match self.chars.next() { + Some((idx, ch)) => { + self.pos = idx; + self.lookahead = Some(ch); + } + None => { + self.pos = self.source.len(); + self.lookahead = None; + } + } + self.lookahead + } + + fn loc(&self) -> Location { + Location { + path: self.path.clone(), + line: self.line_number, + column: self.pos - self.column_start + self.tab_compensation, + } + } + + fn looking_at(&self, prefix: &str) -> bool { + self.source[self.pos..].starts_with(prefix) + } + + fn scan_char(&mut self, tok: Token<'a>) -> Result, LocatedError> { + assert!(self.lookahead.is_some()); + let loc = self.loc(); + self.next_ch(); + token(tok, loc) + } + + pub fn rest_of_line(&mut self) -> &'a str { + let begin = self.pos; + loop { + match self.next_ch() { + None | Some('\n') => return &self.source[begin..self.pos], + _ => {} + } + } + } + + fn scan_word(&mut self) -> Result, LocatedError> { + let begin = self.pos; + let loc = self.loc(); + assert!(self.lookahead == Some('_') || self.lookahead.unwrap().is_alphabetic()); + loop { + match self.next_ch() { + Some('_') | Some('-') => {} + Some(ch) if ch.is_alphanumeric() => {} + _ => break, + } + } + let text = &self.source[begin..self.pos]; + token(Token::Word(text), loc) + } + + fn scan_ident(&mut self) -> Result, LocatedError> { + let loc = self.loc(); + assert!(self.lookahead == Some('$')); + match self.next_ch() { + Some(ch) if ch.is_alphanumeric() || ch == '_' => {} + _ => Err(LocatedError { + error: LexError::EmptyIdentifier, + location: loc.clone(), + })?, + } + let begin = self.pos; + + loop { + match self.next_ch() { + Some('_') | Some('-') => {} + Some(ch) if ch.is_alphanumeric() => {} + _ => break, + } + } + + let text = &self.source[begin..self.pos]; + token(Token::Ident(text), loc) + } + + fn scan_annotation(&mut self) -> Result, LocatedError> { + let loc = self.loc(); + assert!(self.lookahead == Some('@')); + match self.next_ch() { + Some(ch) if ch.is_alphanumeric() || ch == '_' => {} + _ => Err(LocatedError { + error: LexError::EmptyAnnotation, + location: loc.clone(), + })?, + } + let begin = self.pos; + + loop { + match self.next_ch() { + Some('_') | Some('-') => {} + Some(ch) if ch.is_alphanumeric() => {} + _ => break, + } + } + + let text = &self.source[begin..self.pos]; + token(Token::Annot(text), loc) + } + + fn scan_quote(&mut self) -> Result, LocatedError> { + let begin = self.pos; + let loc = self.loc(); + assert!(self.lookahead == Some('"')); + loop { + match self.next_ch() { + None => Err(LocatedError { + error: LexError::UnterminatedQuote, + location: loc.clone(), + })?, + Some('"') => { + self.next_ch(); + break; + } + _ => {} + } + } + let text = &self.source[(begin + 1)..(self.pos - 1)]; + token(Token::Quote(text), loc) + } + + #[allow(clippy::should_implement_trait)] + pub fn next(&mut self) -> Option, LocatedError>> { + loop { + let loc = self.loc(); + return match self.lookahead { + None => None, + Some(c) => Some(match c { + '(' => self.scan_char(Token::LPar), + ')' => self.scan_char(Token::RPar), + '$' => self.scan_ident(), + '@' => self.scan_annotation(), + ';' => { + if self.looking_at(";;") { + self.rest_of_line(); + continue; + } else { + self.next_ch(); + error(LexError::InvalidChar(';'), loc) + } + } + '"' => self.scan_quote(), + '_' => self.scan_word(), + ch if ch.is_alphabetic() => self.scan_word(), + ch if ch.is_whitespace() => { + self.next_ch(); + continue; + } + _ => { + self.next_ch(); + error(LexError::InvalidChar(c), loc) + } + }), + }; + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use std::path::{Path, PathBuf}; + + fn testlexer(input: &str) -> Lexer { + Lexer::new(input, Path::new("/test")) + } + + fn token( + token: Token<'_>, + line: usize, + column: usize, + ) -> Option, LocatedError>> { + Some(super::token( + token, + Location { + path: PathBuf::from("/test"), + line, + column, + }, + )) + } + + fn error<'a>( + err: LexError, + line: usize, + column: usize, + ) -> Option, LocatedError>> { + Some(super::error( + err, + Location { + path: PathBuf::from("/test"), + line, + column, + }, + )) + } + #[test] + fn words_and_idents() { + let mut lex = testlexer("$gussie is a good $dog"); + // ruler 0 5 10 15 20 + assert_eq!(lex.next(), token(Token::Ident("gussie"), 1, 0)); + assert_eq!(lex.next(), token(Token::Word("is"), 1, 8)); + assert_eq!(lex.next(), token(Token::Word("a"), 1, 11)); + assert_eq!(lex.next(), token(Token::Word("good"), 1, 13)); + assert_eq!(lex.next(), token(Token::Ident("dog"), 1, 18)); + assert_eq!(lex.next(), None); + + let mut lex = + testlexer("$ok $a $_ $ _\nkebab-case\nsnake_case\n$kebab-ident\n$snake_ident"); + assert_eq!(lex.next(), token(Token::Ident("ok"), 1, 0)); + assert_eq!(lex.next(), token(Token::Ident("a"), 1, 4)); + assert_eq!(lex.next(), token(Token::Ident("_"), 1, 7)); + assert_eq!(lex.next(), error(LexError::EmptyIdentifier, 1, 10)); + assert_eq!(lex.next(), token(Token::Word("_"), 1, 12)); + assert_eq!(lex.next(), token(Token::Word("kebab-case"), 2, 0)); + assert_eq!(lex.next(), token(Token::Word("snake_case"), 3, 0)); + assert_eq!(lex.next(), token(Token::Ident("kebab-ident"), 4, 0)); + assert_eq!(lex.next(), token(Token::Ident("snake_ident"), 5, 0)); + assert_eq!(lex.next(), None); + } + + #[test] + fn comments() { + let mut lex = testlexer("the quick ;; brown fox\njumped\n;;over the three\nlazy;;dogs"); + assert_eq!(lex.next(), token(Token::Word("the"), 1, 0)); + assert_eq!(lex.next(), token(Token::Word("quick"), 1, 4)); + assert_eq!(lex.next(), token(Token::Word("jumped"), 2, 0)); + assert_eq!(lex.next(), token(Token::Word("lazy"), 4, 0)); + assert_eq!(lex.next(), None); + + let mut lex = testlexer("line1 ;;\n$sym_2;\n\t\tl3;;;333"); + assert_eq!(lex.next(), token(Token::Word("line1"), 1, 0)); + assert_eq!(lex.next(), token(Token::Ident("sym_2"), 2, 0)); + assert_eq!(lex.next(), error(LexError::InvalidChar(';'), 2, 6)); + assert_eq!(lex.next(), token(Token::Word("l3"), 3, 16)); // Two tabs = 16 columns + assert_eq!(lex.next(), None); + } + + #[test] + fn quotes() { + let mut lex = testlexer("a \"bc\" d"); + assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); + assert_eq!(lex.next(), token(Token::Quote("bc"), 1, 2)); + assert_eq!(lex.next(), token(Token::Word("d"), 1, 7)); + + let mut lex = testlexer("a \"b\nc\" d"); + assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); + assert_eq!(lex.next(), token(Token::Quote("b\nc"), 1, 2)); + assert_eq!(lex.next(), token(Token::Word("d"), 2, 3)); + + let mut lex = testlexer("a \"b"); + assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); + assert_eq!(lex.next(), error(LexError::UnterminatedQuote, 1, 2)); + } +} diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs new file mode 100644 index 000000000..7d5040d00 --- /dev/null +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -0,0 +1,93 @@ +/// Types describing a validated witx document +mod ast; +/// Lexer text into tokens +mod lexer; +/// Witx syntax parsing from SExprs +mod parser; +/// SExpr parsing from tokens +mod sexpr; +/// Resolve toplevel `use` declarations across files +mod toplevel; +/// Validate declarations into ast +mod validate; + +pub use ast::{ + AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, + Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, Module, + ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, + UnionDatatype, UnionVariant, +}; +pub use lexer::LexError; +pub use parser::{DeclSyntax, ParseError}; +pub use sexpr::SExprParseError; +pub use validate::ValidationError; + +use failure::Fail; +use std::io; +use std::path::{Path, PathBuf}; + +pub fn load>(path: P) -> Result { + use toplevel::parse_witx; + use validate::validate_document; + let parsed_decls = parse_witx(path)?; + validate_document(&parsed_decls).map_err(WitxError::Validation) +} + +/// Location in the source text +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct Location { + pub path: PathBuf, + pub line: usize, + pub column: usize, +} + +#[derive(Debug, Fail)] +pub enum WitxError { + #[fail(display = "{}", _0)] + SExpr(#[cause] SExprParseError), + #[fail(display = "when resolving use declaration for {:?}: {}", _0, _1)] + UseResolution(PathBuf, #[cause] io::Error), + #[fail(display = "{}", _0)] + Parse(#[cause] ParseError), + #[fail(display = "{}", _0)] + Validation(#[cause] ValidationError), +} + +impl WitxError { + pub fn report(&self) -> String { + use WitxError::*; + match self { + SExpr(sexpr) => sexpr.report(), + UseResolution(path, ioerr) => format!("when resolving `use {:?}`: {}", path, ioerr), + Parse(parse) => parse.report(), + Validation(validation) => validation.report(), + } + } +} +impl Location { + pub fn highlight_source(&self) -> String { + let mut msg = format!("in {:?}:\n", self.path); + if let Ok(src_line) = self.source_line() { + msg += &format!( + "{line_num: >5} | {src_line}\n{blank: >5} {caret: >column$}", + line_num = self.line, + src_line = src_line, + blank = " ", + caret = "^", + column = self.column, + ); + } + msg + } + pub fn source_line(&self) -> Result { + use std::fs::File; + use std::io::{BufRead, BufReader}; + let f = BufReader::new(File::open(&self.path)?); + let l = f + .lines() + .skip(self.line - 1) + .next() + .unwrap_or_else(|| Err(io::Error::new(io::ErrorKind::Other, "TODO")))?; + Ok(l) + } +} diff --git a/proposals/clocks/tools/witx/src/main.rs b/proposals/clocks/tools/witx/src/main.rs new file mode 100644 index 000000000..c2ad70322 --- /dev/null +++ b/proposals/clocks/tools/witx/src/main.rs @@ -0,0 +1,38 @@ +use clap::{App, Arg}; +use std::path::Path; +use std::process; +use witx::load; + +pub fn main() { + let app = App::new("witx") + .version(env!("CARGO_PKG_VERSION")) + .about("Validate witx file format") + .arg( + Arg::with_name("input") + .required(true) + .help("path to root of witx document"), + ) + .arg( + Arg::with_name("verbose") + .short("v") + .long("verbose") + .takes_value(false) + .required(false), + ) + .get_matches(); + + match load(Path::new(app.value_of("input").expect("required arg"))) { + Ok(doc) => { + if app.is_present("verbose") { + println!("{:?}", doc) + } + } + Err(e) => { + println!("{}", e.report()); + if app.is_present("verbose") { + println!("{:?}", e); + } + process::exit(1) + } + } +} diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs new file mode 100644 index 000000000..a99df5fa4 --- /dev/null +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -0,0 +1,583 @@ +use crate::sexpr::SExpr; +use crate::Location; +use failure::Fail; + +///! Parser turns s-expressions into unvalidated syntax constructs. +///! conventions: +///! `Type::starts_parsing(s-expr) -> bool` is for look-ahead: we use +///! this predicate to combine parsers for different `Type`s where both +///! alternatives are accepted. +///! `Type::parse(sexpr: &SExpr) -> Result` takes a single +///! s-expression and parses it into a `Self`. +///! for parsers that take a subset of a vector s-expression, the signature +///! `Type::parse(sexprs: &[SExpr], location: Location) -> Result` +///! has an additional `Location` argument, which should point to the parent SExpr::Vec. +///! This is used for error reporting in case the slice doesn't have the number of elements +///! expected. + +#[derive(Debug, Fail)] +#[fail(display = "{} at {:?}", _0, _1)] +pub struct ParseError { + pub message: String, + pub location: Location, +} + +impl ParseError { + pub fn report(&self) -> String { + format!("{}\n{}", self.location.highlight_source(), self.message) + } +} + +macro_rules! parse_err { + ($loc:expr, $msg:expr) => { + ParseError { message: $msg.to_string(), location: $loc.clone() } + }; + ($loc:expr, $fmt:expr, $( $arg:expr ),+ ) => { + ParseError { message: format!($fmt, $( $arg ),+), location: $loc.clone() } + }; +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct IdentSyntax { + pub name: String, + pub location: Location, +} + +macro_rules! id { + ($s:expr, $loc: expr) => { + IdentSyntax { + name: $s.to_string(), + location: $loc.clone(), + } + }; +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum BuiltinType { + String, + Data, + U8, + U16, + U32, + U64, + S8, + S16, + S32, + S64, + F32, + F64, +} + +impl BuiltinType { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + match sexpr { + SExpr::Word("string", _) + | SExpr::Word("data", _) + | SExpr::Word("u8", _) + | SExpr::Word("u16", _) + | SExpr::Word("u32", _) + | SExpr::Word("u64", _) + | SExpr::Word("s8", _) + | SExpr::Word("s16", _) + | SExpr::Word("s32", _) + | SExpr::Word("s64", _) + | SExpr::Word("f32", _) + | SExpr::Word("f64", _) => true, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + match sexpr { + SExpr::Word("string", _loc) => Ok(BuiltinType::String), + SExpr::Word("data", _loc) => Ok(BuiltinType::Data), + SExpr::Word("u8", _loc) => Ok(BuiltinType::U8), + SExpr::Word("u16", _loc) => Ok(BuiltinType::U16), + SExpr::Word("u32", _loc) => Ok(BuiltinType::U32), + SExpr::Word("u64", _loc) => Ok(BuiltinType::U64), + SExpr::Word("s8", _loc) => Ok(BuiltinType::S8), + SExpr::Word("s16", _loc) => Ok(BuiltinType::S16), + SExpr::Word("s32", _loc) => Ok(BuiltinType::S32), + SExpr::Word("s64", _loc) => Ok(BuiltinType::S64), + SExpr::Word("f32", _loc) => Ok(BuiltinType::F32), + SExpr::Word("f64", _loc) => Ok(BuiltinType::F64), + _ => Err(parse_err!(sexpr.location(), "invalid builtin type")), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum DatatypeIdentSyntax { + Builtin(BuiltinType), + Array(Box), + Pointer(Box), + ConstPointer(Box), + Ident(IdentSyntax), +} + +impl DatatypeIdentSyntax { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + BuiltinType::starts_parsing(sexpr) + || match sexpr { + SExpr::Ident(_, _) => true, + SExpr::Vec(v, _) => match (v.get(0), v.get(1)) { + (Some(SExpr::Word("array", _)), Some(_)) => true, + (Some(SExpr::Annot("witx", _)), Some(SExpr::Word("pointer", _))) => true, + (Some(SExpr::Annot("witx", _)), Some(SExpr::Word("const_pointer", _))) => true, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + if BuiltinType::starts_parsing(sexpr) { + let builtin = BuiltinType::parse(sexpr)?; + Ok(DatatypeIdentSyntax::Builtin(builtin)) + } else { + match sexpr { + SExpr::Ident(i, loc) => Ok(DatatypeIdentSyntax::Ident(id!(i, loc))), + SExpr::Vec(v, loc) => match (v.get(0), v.get(1), v.get(2)) { + (Some(SExpr::Word("array", _)), Some(expr), None) => Ok( + DatatypeIdentSyntax::Array(Box::new(DatatypeIdentSyntax::parse(expr)?)), + ), + ( + Some(SExpr::Annot("witx", _)), + Some(SExpr::Word("pointer", _)), + Some(expr), + ) => Ok(DatatypeIdentSyntax::Pointer(Box::new( + DatatypeIdentSyntax::parse(expr)?, + ))), + ( + Some(SExpr::Annot("witx", _)), + Some(SExpr::Word("const_pointer", _)), + Some(expr), + ) => Ok(DatatypeIdentSyntax::ConstPointer(Box::new( + DatatypeIdentSyntax::parse(expr)?, + ))), + _ => Err(parse_err!(loc, "expected type identifier")), + }, + _ => Err(parse_err!(sexpr.location(), "expected type identifier")), + } + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum TopLevelSyntax { + Decl(DeclSyntax), + Use(IdentSyntax), +} + +impl TopLevelSyntax { + pub fn parse(sexpr: &SExpr) -> Result { + if DeclSyntax::starts_parsing(sexpr) { + let decl = DeclSyntax::parse(sexpr)?; + Ok(TopLevelSyntax::Decl(decl)) + } else { + match sexpr { + SExpr::Vec(v, vec_loc) => match v.get(0) { + Some(SExpr::Word("use", loc)) => match v.get(1) { + Some(SExpr::Quote(u, loc)) => Ok(TopLevelSyntax::Use(id!(u, loc))), + _ => Err(parse_err!(loc, "invalid use declaration")), + }, + _ => Err(parse_err!(vec_loc, "expected top level declaration")), + }, + _ => Err(parse_err!( + sexpr.location(), + "expected top level declaration" + )), + } + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum DeclSyntax { + Typename(TypenameSyntax), + Module(ModuleSyntax), +} + +impl DeclSyntax { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + match sexpr { + SExpr::Vec(v, _) => match v.get(0) { + Some(SExpr::Word("typename", _)) => true, + Some(SExpr::Word("module", _)) => true, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + match sexpr { + SExpr::Vec(v, loc) => match v.get(0) { + Some(SExpr::Word("typename", loc)) => { + Ok(DeclSyntax::Typename(TypenameSyntax::parse(&v[1..], loc)?)) + } + Some(SExpr::Word("module", loc)) => { + Ok(DeclSyntax::Module(ModuleSyntax::parse(&v[1..], loc)?)) + } + _ => Err(parse_err!(loc, "invalid declaration")), + }, + _ => Err(parse_err!(sexpr.location(), "expected vec")), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TypenameSyntax { + pub ident: IdentSyntax, + pub def: TypedefSyntax, +} + +impl TypenameSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + let ident = match sexpr.get(0) { + Some(SExpr::Ident(i, loc)) => id!(i, loc), + Some(s) => Err(parse_err!(s.location(), "expected typename identifier"))?, + None => Err(parse_err!(loc, "expected typename identifier"))?, + }; + let def = match sexpr.get(1) { + Some(expr) => TypedefSyntax::parse(expr)?, + _ => Err(parse_err!(loc, "expected type definition"))?, + }; + Ok(TypenameSyntax { ident, def }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum TypedefSyntax { + Ident(DatatypeIdentSyntax), + Enum(EnumSyntax), + Flags(FlagsSyntax), + Struct(StructSyntax), + Union(UnionSyntax), +} + +impl TypedefSyntax { + pub fn parse(sexpr: &SExpr) -> Result { + if DatatypeIdentSyntax::starts_parsing(sexpr) { + let ident = DatatypeIdentSyntax::parse(sexpr)?; + Ok(TypedefSyntax::Ident(ident)) + } else { + match sexpr { + SExpr::Vec(vs, loc) => match vs.get(0) { + Some(SExpr::Word("enum", loc)) => { + Ok(TypedefSyntax::Enum(EnumSyntax::parse(&vs[1..], loc)?)) + } + Some(SExpr::Word("flags", loc)) => { + Ok(TypedefSyntax::Flags(FlagsSyntax::parse(&vs[1..], loc)?)) + } + Some(SExpr::Word("struct", loc)) => { + Ok(TypedefSyntax::Struct(StructSyntax::parse(&vs[1..], loc)?)) + } + Some(SExpr::Word("union", loc)) => { + Ok(TypedefSyntax::Union(UnionSyntax::parse(&vs[1..], loc)?)) + } + _ => Err(parse_err!( + loc, + "expected type identifier or type definition" + )), + }, + _ => Err(parse_err!( + sexpr.location(), + "expected type identifier or type definition" + )), + } + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct EnumSyntax { + pub repr: BuiltinType, + pub members: Vec, +} + +impl EnumSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + let repr = match sexpr.get(0) { + Some(e) => BuiltinType::parse(e)?, + _ => Err(parse_err!(loc, "no enum repr"))?, + }; + let members = sexpr[1..] + .iter() + .map(|m| match m { + SExpr::Ident(i, loc) => Ok(id!(i, loc)), + s => Err(parse_err!(s.location(), "expected enum member identifier")), + }) + .collect::, ParseError>>()?; + if members.is_empty() { + Err(parse_err!(loc, "expected at least one enum member"))? + } + Ok(EnumSyntax { repr, members }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FlagsSyntax { + pub repr: BuiltinType, + pub flags: Vec, +} + +impl FlagsSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + let repr = BuiltinType::parse( + sexpr + .get(0) + .ok_or_else(|| parse_err!(loc, "expected flag repr type"))?, + )?; + let flags = sexpr[1..] + .iter() + .map(|f| match f { + SExpr::Vec(vs, loc) => match (vs.get(0), vs.get(1)) { + (Some(SExpr::Word("flag", _)), Some(SExpr::Ident(i, loc))) => Ok(id!(i, loc)), + _ => Err(parse_err!(loc, "expected flag specifier")), + }, + s => Err(parse_err!(s.location(), "expected flag specifier")), + }) + .collect::, ParseError>>()?; + Ok(FlagsSyntax { repr, flags }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct StructSyntax { + pub fields: Vec, +} + +impl StructSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + if sexpr.is_empty() { + Err(parse_err!(loc, "expected at least one struct member"))? + } + let fields = sexpr + .iter() + .map(|f| FieldSyntax::parse(f, "field")) + .collect::, ParseError>>()?; + Ok(StructSyntax { fields }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FieldSyntax { + pub name: IdentSyntax, + pub type_: DatatypeIdentSyntax, +} + +impl FieldSyntax { + pub fn starts_parsing(sexpr: &SExpr, constructor: &str) -> bool { + match sexpr { + SExpr::Vec(v, _) => match v.get(0) { + Some(SExpr::Word(c, _)) => *c == constructor, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr, constructor: &str) -> Result { + match sexpr { + SExpr::Vec(v, loc) => match v.get(0) { + Some(SExpr::Word(c, _)) if *c == constructor => { + let name = match v.get(1) { + Some(SExpr::Ident(i, loc)) => id!(i, loc), + _ => Err(parse_err!(loc, "expected {} name identifier", constructor))?, + }; + let type_ = DatatypeIdentSyntax::parse(v.get(2).ok_or_else(|| { + parse_err!(loc, "expected {} type identifier", constructor) + })?)?; + Ok(FieldSyntax { name, type_ }) + } + _ => Err(parse_err!(loc, "expected {}", constructor)), + }, + _ => Err(parse_err!(sexpr.location(), "expected {}", constructor)), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct UnionSyntax { + pub fields: Vec, +} + +impl UnionSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + if sexpr.is_empty() { + Err(parse_err!(loc, "expected at least one union member"))? + } + let fields = sexpr + .iter() + .map(|f| FieldSyntax::parse(f, "field")) + .collect::, ParseError>>()?; + Ok(UnionSyntax { fields }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ModuleSyntax { + pub name: IdentSyntax, + pub decls: Vec, +} + +impl ModuleSyntax { + pub fn parse(sexprs: &[SExpr], loc: &Location) -> Result { + let name = match sexprs.get(0) { + Some(SExpr::Ident(i, loc)) => id!(i, loc), + _ => Err(parse_err!(loc, "expected module name"))?, + }; + let decls = sexprs[1..] + .iter() + .map(|s| ModuleDeclSyntax::parse(s)) + .collect::, _>>()?; + Ok(ModuleSyntax { name, decls }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ModuleDeclSyntax { + Import(ModuleImportSyntax), + Func(InterfaceFuncSyntax), +} + +impl ModuleDeclSyntax { + pub fn parse(sexpr: &SExpr) -> Result { + if ModuleImportSyntax::starts_parsing(sexpr) { + Ok(ModuleDeclSyntax::Import(ModuleImportSyntax::parse(sexpr)?)) + } else if InterfaceFuncSyntax::starts_parsing(sexpr) { + Ok(ModuleDeclSyntax::Func(InterfaceFuncSyntax::parse(sexpr)?)) + } else { + Err(parse_err!(sexpr.location(), "expected import or function")) + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ModuleImportSyntax { + pub name: IdentSyntax, + pub type_: ImportTypeSyntax, +} + +impl ModuleImportSyntax { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + match sexpr { + SExpr::Vec(vs, _) => match vs.get(0) { + Some(SExpr::Word("import", _)) => true, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + match sexpr { + SExpr::Vec(vs, vec_loc) => match (vs.get(0), vs.get(1)) { + (Some(SExpr::Word("import", _)), Some(SExpr::Quote(name, loc))) => { + let name = id!(name, loc); + let type_ = ImportTypeSyntax::parse(&vs[2..], vec_loc)?; + Ok(ModuleImportSyntax { name, type_ }) + } + _ => Err(parse_err!(vec_loc, "expected module import")), + }, + _ => Err(parse_err!(sexpr.location(), "expected module import")), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ImportTypeSyntax { + Memory, +} + +impl ImportTypeSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + if sexpr.len() > 1 { + Err(parse_err!(loc, "too many elements for an import type"))?; + } + match sexpr.get(0) { + Some(SExpr::Vec(vs, loc)) => match vs.get(0) { + Some(SExpr::Word("memory", _)) => { + if vs.len() == 1 { + Ok(ImportTypeSyntax::Memory) + } else { + Err(parse_err!(loc, "too many elements for memory declaration")) + } + } + _ => Err(parse_err!(loc, "expected import type")), + }, + _ => Err(parse_err!(loc, "expected import type")), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct InterfaceFuncSyntax { + pub export: IdentSyntax, + pub params: Vec, + pub results: Vec, +} + +impl InterfaceFuncSyntax { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + match sexpr { + SExpr::Vec(vs, _) => match (vs.get(0), vs.get(1)) { + (Some(SExpr::Annot("interface", _)), Some(SExpr::Word("func", _))) => true, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + match sexpr { + SExpr::Vec(vs, loc) => match (vs.get(0), vs.get(1)) { + (Some(SExpr::Annot("interface", _)), Some(SExpr::Word("func", _))) => { + let export = match vs.get(2) { + Some(SExpr::Vec(es, loc)) => match (es.get(0), es.get(1)) { + ( + Some(SExpr::Word("export", _)), + Some(SExpr::Quote(name, name_loc)), + ) => { + if es.len() == 2 { + id!(name, name_loc) + } else { + Err(parse_err!( + loc, + "too many elements for export declaration" + ))? + } + } + _ => Err(parse_err!(loc, "expected export declaration"))?, + }, + _ => Err(parse_err!(loc, "expected export declaration"))?, + }; + let mut params = Vec::new(); + let mut results = Vec::new(); + + for sexpr in &vs[3..] { + if FieldSyntax::starts_parsing(sexpr, "param") { + let param = FieldSyntax::parse(sexpr, "param")?; + params.push(param); + } else if FieldSyntax::starts_parsing(sexpr, "result") { + let result = FieldSyntax::parse(sexpr, "result")?; + results.push(result); + } else { + Err(parse_err!( + sexpr.location(), + "expected param or result field" + ))?; + } + } + + Ok(InterfaceFuncSyntax { + export, + params, + results, + }) + } + _ => Err(parse_err!(loc, "expected interface func declaration")), + }, + + _ => Err(parse_err!( + sexpr.location(), + "expected interface func declaration" + )), + } + } +} diff --git a/proposals/clocks/tools/witx/src/sexpr.rs b/proposals/clocks/tools/witx/src/sexpr.rs new file mode 100644 index 000000000..6a34cf83b --- /dev/null +++ b/proposals/clocks/tools/witx/src/sexpr.rs @@ -0,0 +1,236 @@ +pub use crate::lexer::LexError; +use crate::lexer::{Lexer, LocatedError, LocatedToken, Token}; +use crate::Location; +use failure::Fail; +use std::path::{Path, PathBuf}; + +///! The s-expression parser turns a string into a stream of SExprs. +///! It uses the `Lexer` under the hood. +///! This implementation was heavily influenced by `cranelift-reader` + +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum SExpr<'a> { + Vec(Vec>, Location), + Word(&'a str, Location), + Ident(&'a str, Location), + Quote(&'a str, Location), + /// Short for Annotation + Annot(&'a str, Location), +} + +impl<'a> SExpr<'a> { + pub fn location(&self) -> Location { + match self { + SExpr::Vec(_, loc) => loc.clone(), + SExpr::Word(_, loc) => loc.clone(), + SExpr::Ident(_, loc) => loc.clone(), + SExpr::Quote(_, loc) => loc.clone(), + SExpr::Annot(_, loc) => loc.clone(), + } + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Fail)] +pub enum SExprParseError { + #[fail(display = "Lexical error: {}", _0)] + Lex(LexError, Location), + #[fail(display = "Unexpected ')'")] + UnexpectedCloseParen(Location), + #[fail(display = "Unexpected end of input in {:?}", _0)] + UnexpectedEof(PathBuf), +} + +impl SExprParseError { + pub fn report(&self) -> String { + use SExprParseError::*; + match self { + Lex(lex_err, loc) => format!("{}\n{}", loc.highlight_source(), lex_err), + UnexpectedCloseParen(loc) => format!("{}\n{}", loc.highlight_source(), self), + UnexpectedEof(_path) => format!("{}", self), + } + } +} + +pub struct SExprParser<'a> { + lex: Lexer<'a>, + lookahead: Option>, + location: Location, +} + +impl<'a> SExprParser<'a> { + pub fn new>(text: &'a str, path: P) -> SExprParser<'_> { + SExprParser { + lex: Lexer::new(text, path.as_ref()), + lookahead: None, + location: Location { + path: path.as_ref().into(), + line: 0, + column: 0, + }, + } + } + fn consume(&mut self) -> Token<'a> { + self.lookahead.take().expect("no token to consume") + } + fn token(&mut self) -> Result>, SExprParseError> { + while self.lookahead == None { + match self.lex.next() { + Some(Ok(LocatedToken { token, location })) => { + self.location = location; + self.lookahead = Some(token) + } + Some(Err(LocatedError { error, location })) => { + self.location = location.clone(); + Err(SExprParseError::Lex(error, location))?; + } + None => break, + } + } + Ok(self.lookahead) + } + + pub fn match_sexpr(&mut self) -> Result, SExprParseError> { + let location = self.location.clone(); + match self.token()? { + Some(Token::LPar) => { + self.consume(); + let mut members = Vec::new(); + loop { + match self.token()? { + Some(Token::RPar) => { + self.consume(); + break; + } + _ => { + members.push(self.match_sexpr()?); + } + } + } + Ok(SExpr::Vec(members, location)) + } + Some(Token::Word(word)) => { + self.consume(); + Ok(SExpr::Word(word, location)) + } + Some(Token::Ident(id)) => { + self.consume(); + Ok(SExpr::Ident(id, location)) + } + Some(Token::Annot(id)) => { + self.consume(); + Ok(SExpr::Annot(id, location)) + } + Some(Token::Quote(q)) => { + self.consume(); + Ok(SExpr::Quote(q, location)) + } + Some(Token::RPar) => Err(SExprParseError::UnexpectedCloseParen(location)), + None => Err(SExprParseError::UnexpectedEof(self.location.path.clone())), + } + } + + pub fn match_sexprs(&mut self) -> Result>, SExprParseError> { + let mut sexprs = Vec::new(); + while self.token()?.is_some() { + sexprs.push(self.match_sexpr()?); + } + Ok(sexprs) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::path::PathBuf; + + fn loc(line: usize, col: usize) -> Location { + Location { + path: PathBuf::from("/test"), + line: line, + column: col, + } + } + + fn testparser(input: &str) -> SExprParser { + SExprParser::new(input, Path::new("/test")) + } + + #[test] + fn empty() { + let mut parser = testparser(""); + assert_eq!(parser.match_sexprs().expect("valid parse"), Vec::new()); + let mut parser = testparser(" ;; just a comment\n;;another"); + assert_eq!(parser.match_sexprs().expect("valid parse"), Vec::new()); + } + + #[test] + fn atoms() { + let mut parser = testparser("hello\n$world\n\"a quotation\""); + assert_eq!( + parser.match_sexprs().expect("valid parse"), + vec![ + SExpr::Word("hello", loc(1, 0)), + SExpr::Ident("world", loc(2, 0)), + SExpr::Quote("a quotation", loc(3, 0)), + ] + ); + } + + #[test] + fn lists() { + let mut parser = testparser("()"); + assert_eq!( + parser.match_sexprs().expect("valid parse"), + vec![SExpr::Vec(vec![], loc(1, 0))] + ); + + let mut parser = testparser("(hello\n$world\n\"a quotation\")"); + assert_eq!( + parser.match_sexprs().expect("valid parse"), + vec![SExpr::Vec( + vec![ + SExpr::Word("hello", loc(1, 1)), + SExpr::Ident("world", loc(2, 0)), + SExpr::Quote("a quotation", loc(3, 0)), + ], + loc(1, 0) + )] + ); + + let mut parser = testparser("((($deep)))"); + assert_eq!( + parser.match_sexprs().expect("valid parse"), + vec![SExpr::Vec( + vec![SExpr::Vec( + vec![SExpr::Vec(vec![SExpr::Ident("deep", loc(1, 3))], loc(1, 2))], + loc(1, 1) + )], + loc(1, 0) + )] + ); + } + + #[test] + fn errors() { + let mut parser = testparser("("); + assert_eq!( + parser.match_sexprs().err().expect("dies"), + SExprParseError::UnexpectedEof(PathBuf::from("/test")) + ); + let mut parser = testparser(")"); + assert_eq!( + parser.match_sexprs().err().expect("dies"), + SExprParseError::UnexpectedCloseParen(loc(1, 0)) + ); + let mut parser = testparser("())"); + assert_eq!( + parser.match_sexprs().err().expect("dies"), + SExprParseError::UnexpectedCloseParen(loc(1, 2)) + ); + let mut parser = testparser("$ ;; should be a lex error"); + assert_eq!( + parser.match_sexprs().err().expect("dies"), + SExprParseError::Lex(LexError::EmptyIdentifier, loc(1, 0),), + ); + } +} diff --git a/proposals/clocks/tools/witx/src/toplevel.rs b/proposals/clocks/tools/witx/src/toplevel.rs new file mode 100644 index 000000000..cf3a5e377 --- /dev/null +++ b/proposals/clocks/tools/witx/src/toplevel.rs @@ -0,0 +1,243 @@ +use crate::parser::{DeclSyntax, ParseError, TopLevelSyntax}; +use crate::sexpr::SExprParser; +use crate::WitxError; +use std::collections::HashSet; +use std::fs; +use std::path::{Path, PathBuf}; + +trait WitxIo { + fn fgets(&self, path: &Path) -> Result; + fn canonicalize(&self, path: &Path) -> Result; +} + +struct Filesystem; + +impl WitxIo for Filesystem { + fn fgets(&self, path: &Path) -> Result { + fs::read_to_string(path).map_err(|e| WitxError::UseResolution(path.to_path_buf(), e)) + } + fn canonicalize(&self, path: &Path) -> Result { + path.canonicalize() + .map_err(|e| WitxError::UseResolution(path.to_path_buf(), e)) + } +} + +pub fn parse_witx>(i: P) -> Result, WitxError> { + parse_witx_with(i, &Filesystem) +} + +fn parse_witx_with>( + i: P, + witxio: &dyn WitxIo, +) -> Result, WitxError> { + let input_path = witxio.canonicalize(&i.as_ref())?; + + let input = witxio.fgets(&input_path)?; + + let toplevel = parse_toplevel(&input, &input_path)?; + let mut resolved = HashSet::new(); + resolved.insert(input_path.clone()); + let search_path = input_path.parent().unwrap_or(Path::new(".")); + resolve_uses(toplevel, &search_path, &mut resolved, witxio) +} + +fn parse_toplevel(source_text: &str, file_path: &Path) -> Result, WitxError> { + let mut sexpr_parser = SExprParser::new(source_text, file_path); + let sexprs = sexpr_parser.match_sexprs().map_err(WitxError::SExpr)?; + let top_levels = sexprs + .iter() + .map(|s| TopLevelSyntax::parse(s)) + .collect::, ParseError>>() + .map_err(WitxError::Parse)?; + Ok(top_levels) +} + +fn resolve_uses( + toplevel: Vec, + search_path: &Path, + used: &mut HashSet, + witxio: &dyn WitxIo, +) -> Result, WitxError> { + let mut decls = Vec::new(); + + for t in toplevel { + match t { + TopLevelSyntax::Decl(d) => decls.push(d), + TopLevelSyntax::Use(u) => { + let abs_path = witxio.canonicalize(&search_path.join(u.name))?; + // Include the decls from a use declaration only once + // in a given toplevel. Same idea as #pragma once. + if !used.contains(&abs_path) { + used.insert(abs_path.clone()); + + let source_text = witxio.fgets(&abs_path)?; + let inner_toplevels = parse_toplevel(&source_text, &abs_path)?; + + let inner_decls = resolve_uses(inner_toplevels, search_path, used, witxio)?; + decls.extend(inner_decls) + } + } + } + } + + Ok(decls) +} + +#[cfg(test)] +mod test { + use super::*; + use crate::parser::*; + use crate::Location; + use std::collections::HashMap; + + struct MockFs { + map: HashMap<&'static str, &'static str>, + } + + impl MockFs { + pub fn new(strings: Vec<(&'static str, &'static str)>) -> Self { + MockFs { + map: strings.into_iter().collect(), + } + } + } + + impl WitxIo for MockFs { + fn fgets(&self, path: &Path) -> Result { + if let Some(entry) = self.map.get(path.to_str().unwrap()) { + Ok(entry.to_string()) + } else { + use std::io::{Error, ErrorKind}; + Err(WitxError::UseResolution( + path.to_path_buf(), + Error::new(ErrorKind::Other, "mock fs: file not found"), + )) + } + } + fn canonicalize(&self, path: &Path) -> Result { + Ok(PathBuf::from(path)) + } + } + + #[test] + fn empty() { + assert_eq!( + parse_witx_with(&Path::new("/a"), &MockFs::new(vec![("/a", ";; empty")])) + .expect("parse"), + Vec::new(), + ); + } + + #[test] + fn one_use() { + assert_eq!( + parse_witx_with( + &Path::new("/a"), + &MockFs::new(vec![("/a", "(use \"b\")"), ("/b", ";; empty")]) + ) + .expect("parse"), + Vec::new(), + ); + } + + #[test] + fn multi_use() { + assert_eq!( + parse_witx_with( + &Path::new("/a"), + &MockFs::new(vec![ + ("/a", "(use \"b\")"), + ("/b", "(use \"c\")\n(typename $b_float f64)"), + ("/c", "(typename $c_int u32)") + ]) + ) + .expect("parse"), + vec![ + DeclSyntax::Typename(TypenameSyntax { + ident: IdentSyntax { + name: "c_int".to_owned(), + location: Location { + path: PathBuf::from("/c"), + line: 1, + column: 10, + } + }, + def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::U32)) + }), + DeclSyntax::Typename(TypenameSyntax { + ident: IdentSyntax { + name: "b_float".to_owned(), + location: Location { + path: PathBuf::from("/b"), + line: 2, + column: 10, + } + }, + def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::F64)) + }) + ], + ); + } + + #[test] + fn diamond_dependency() { + assert_eq!( + parse_witx_with( + &Path::new("/a"), + &MockFs::new(vec![ + ("/a", "(use \"b\")\n(use \"c\")"), + ("/b", "(use \"d\")"), + ("/c", "(use \"d\")"), + ("/d", "(typename $d_char u8)") + ]) + ) + .expect("parse"), + vec![DeclSyntax::Typename(TypenameSyntax { + ident: IdentSyntax { + name: "d_char".to_owned(), + location: Location { + path: PathBuf::from("/d"), + line: 1, + column: 10, + } + }, + def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::U8)) + })], + ); + } + + #[test] + fn use_not_found() { + match parse_witx_with(&Path::new("/a"), &MockFs::new(vec![("/a", "(use \"b\")")])) + .err() + .unwrap() + { + WitxError::UseResolution(path, _error) => assert_eq!(path, PathBuf::from("/b")), + e => panic!("wrong error: {:?}", e), + } + } + + #[test] + fn use_invalid() { + match parse_witx_with( + &Path::new("/a"), + &MockFs::new(vec![("/a", "(use bbbbbbb)")]), + ) + .err() + .unwrap() + { + WitxError::Parse(e) => { + assert_eq!(e.message, "invalid use declaration"); + assert_eq!( + e.location, + Location { + path: PathBuf::from("/a"), + line: 1, + column: 1 + } + ); + } + e => panic!("wrong error: {:?}", e), + } + } +} diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs new file mode 100644 index 000000000..7041fca98 --- /dev/null +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -0,0 +1,390 @@ +use crate::{ + parser::{ + DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, IdentSyntax, ImportTypeSyntax, + ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + }, + AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, + Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, Location, + Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, + StructMember, UnionDatatype, UnionVariant, +}; +use failure::Fail; +use std::collections::HashMap; +use std::rc::Rc; + +#[derive(Debug, Fail)] +pub enum ValidationError { + #[fail(display = "Unknown name `{}`", name)] + UnknownName { name: String, location: Location }, + #[fail(display = "Redefinition of name `{}`", name)] + NameAlreadyExists { + name: String, + at_location: Location, + previous_location: Location, + }, + #[fail( + display = "Wrong kind of name `{}`: expected {}, got {}", + name, expected, got + )] + WrongKindName { + name: String, + location: Location, + expected: &'static str, + got: &'static str, + }, + #[fail(display = "Recursive definition of name `{}`", name)] + Recursive { name: String, location: Location }, + #[fail(display = "Invalid representation `{:?}`", repr)] + InvalidRepr { + repr: BuiltinType, + location: Location, + }, +} + +impl ValidationError { + pub fn report(&self) -> String { + use ValidationError::*; + match self { + UnknownName { location, .. } + | WrongKindName { location, .. } + | Recursive { location, .. } + | InvalidRepr { location, .. } => format!("{}\n{}", location.highlight_source(), &self), + NameAlreadyExists { + at_location, + previous_location, + .. + } => format!( + "{}\n{}\nOriginally defined at:\n{}", + at_location.highlight_source(), + &self, + previous_location.highlight_source(), + ), + } + } +} + +pub fn validate_document(decls: &[DeclSyntax]) -> Result { + let mut validator = DocValidation::new(); + let mut definitions = Vec::new(); + for d in decls { + definitions.push(validator.validate_decl(&d)?); + } + + Ok(Document { + entries: validator.entries, + definitions, + }) +} + +struct IdentValidation { + names: HashMap, +} + +impl IdentValidation { + fn new() -> Self { + Self { + names: HashMap::new(), + } + } + fn introduce(&mut self, syntax: &IdentSyntax) -> Result { + if let Some(introduced) = self.names.get(&syntax.name) { + Err(ValidationError::NameAlreadyExists { + name: syntax.name.clone(), + at_location: syntax.location.clone(), + previous_location: introduced.clone(), + }) + } else { + self.names + .insert(syntax.name.clone(), syntax.location.clone()); + Ok(Id::new(&syntax.name)) + } + } + + fn get(&self, syntax: &IdentSyntax) -> Result { + if self.names.get(&syntax.name).is_some() { + Ok(Id::new(&syntax.name)) + } else { + Err(ValidationError::UnknownName { + name: syntax.name.clone(), + location: syntax.location.clone(), + }) + } + } +} + +struct DocValidation { + scope: IdentValidation, + pub entries: HashMap, +} + +impl DocValidation { + fn new() -> Self { + Self { + scope: IdentValidation::new(), + entries: HashMap::new(), + } + } + + fn validate_decl(&mut self, decl: &DeclSyntax) -> Result { + match decl { + DeclSyntax::Typename(decl) => { + let name = self.scope.introduce(&decl.ident)?; + let variant = + match &decl.def { + TypedefSyntax::Ident(syntax) => DatatypeVariant::Alias(AliasDatatype { + name: name.clone(), + to: self.validate_datatype_ident(&syntax)?, + }), + TypedefSyntax::Enum(syntax) => DatatypeVariant::Enum(self.validate_enum( + &name, + &syntax, + &decl.ident.location, + )?), + TypedefSyntax::Flags(syntax) => DatatypeVariant::Flags( + self.validate_flags(&name, &syntax, &decl.ident.location)?, + ), + TypedefSyntax::Struct(syntax) => DatatypeVariant::Struct( + self.validate_struct(&name, &syntax, &decl.ident.location)?, + ), + TypedefSyntax::Union(syntax) => DatatypeVariant::Union( + self.validate_union(&name, &syntax, &decl.ident.location)?, + ), + }; + let rc_datatype = Rc::new(Datatype { + name: name.clone(), + variant, + }); + self.entries + .insert(name, Entry::Datatype(Rc::downgrade(&rc_datatype))); + Ok(Definition::Datatype(rc_datatype)) + } + DeclSyntax::Module(syntax) => { + let name = self.scope.introduce(&syntax.name)?; + let mut module_validator = ModuleValidation::new(self); + let definitions = syntax + .decls + .iter() + .map(|d| module_validator.validate_decl(&d)) + .collect::, _>>()?; + + let rc_module = Rc::new(Module { + name: name.clone(), + definitions, + entries: module_validator.entries, + }); + self.entries + .insert(name, Entry::Module(Rc::downgrade(&rc_module))); + Ok(Definition::Module(rc_module)) + } + } + } + + fn validate_datatype_ident( + &self, + syntax: &DatatypeIdentSyntax, + ) -> Result { + match syntax { + DatatypeIdentSyntax::Builtin(b) => Ok(DatatypeIdent::Builtin(*b)), + DatatypeIdentSyntax::Array(a) => Ok(DatatypeIdent::Array(Box::new( + self.validate_datatype_ident(&a)?, + ))), + DatatypeIdentSyntax::Pointer(a) => Ok(DatatypeIdent::Pointer(Box::new( + self.validate_datatype_ident(&a)?, + ))), + DatatypeIdentSyntax::ConstPointer(a) => Ok(DatatypeIdent::ConstPointer(Box::new( + self.validate_datatype_ident(&a)?, + ))), + DatatypeIdentSyntax::Ident(i) => { + let id = self.scope.get(i)?; + match self.entries.get(&id) { + Some(Entry::Datatype(weak_d)) => Ok(DatatypeIdent::Ident( + weak_d.upgrade().expect("weak backref to defined type"), + )), + Some(e) => Err(ValidationError::WrongKindName { + name: i.name.clone(), + location: i.location.clone(), + expected: "datatype", + got: e.kind(), + }), + None => Err(ValidationError::Recursive { + name: i.name.clone(), + location: i.location.clone(), + }), + } + } + } + } + + fn validate_enum( + &self, + name: &Id, + syntax: &EnumSyntax, + location: &Location, + ) -> Result { + let mut enum_scope = IdentValidation::new(); + let repr = validate_int_repr(&syntax.repr, location)?; + let variants = syntax + .members + .iter() + .map(|i| enum_scope.introduce(i)) + .collect::, _>>()?; + + Ok(EnumDatatype { + name: name.clone(), + repr, + variants, + }) + } + + fn validate_flags( + &self, + name: &Id, + syntax: &FlagsSyntax, + location: &Location, + ) -> Result { + let mut flags_scope = IdentValidation::new(); + let repr = validate_int_repr(&syntax.repr, location)?; + let flags = syntax + .flags + .iter() + .map(|i| flags_scope.introduce(i)) + .collect::, _>>()?; + + Ok(FlagsDatatype { + name: name.clone(), + repr, + flags, + }) + } + + fn validate_struct( + &self, + name: &Id, + syntax: &StructSyntax, + _location: &Location, + ) -> Result { + let mut member_scope = IdentValidation::new(); + let members = syntax + .fields + .iter() + .map(|f| { + Ok(StructMember { + name: member_scope.introduce(&f.name)?, + type_: self.validate_datatype_ident(&f.type_)?, + }) + }) + .collect::, _>>()?; + + Ok(StructDatatype { + name: name.clone(), + members, + }) + } + + fn validate_union( + &self, + name: &Id, + syntax: &UnionSyntax, + _location: &Location, + ) -> Result { + let mut variant_scope = IdentValidation::new(); + let variants = syntax + .fields + .iter() + .map(|f| { + Ok(UnionVariant { + name: variant_scope.introduce(&f.name)?, + type_: self.validate_datatype_ident(&f.type_)?, + }) + }) + .collect::, _>>()?; + + Ok(UnionDatatype { + name: name.clone(), + variants, + }) + } +} + +fn validate_int_repr(type_: &BuiltinType, location: &Location) -> Result { + match type_ { + BuiltinType::U8 => Ok(IntRepr::I8), + BuiltinType::U16 => Ok(IntRepr::I16), + BuiltinType::U32 => Ok(IntRepr::I32), + BuiltinType::U64 => Ok(IntRepr::I64), + _ => Err(ValidationError::InvalidRepr { + repr: type_.clone(), + location: location.clone(), + }), + } +} + +struct ModuleValidation<'a> { + doc: &'a DocValidation, + scope: IdentValidation, + pub entries: HashMap, +} + +impl<'a> ModuleValidation<'a> { + fn new(doc: &'a DocValidation) -> Self { + Self { + doc, + scope: IdentValidation::new(), + entries: HashMap::new(), + } + } + + fn validate_decl( + &mut self, + decl: &ModuleDeclSyntax, + ) -> Result { + match decl { + ModuleDeclSyntax::Import(syntax) => { + let name = self.scope.introduce(&syntax.name)?; + let variant = match syntax.type_ { + ImportTypeSyntax::Memory => ModuleImportVariant::Memory, + }; + let rc_import = Rc::new(ModuleImport { + name: name.clone(), + variant, + }); + self.entries + .insert(name, ModuleEntry::Import(Rc::downgrade(&rc_import))); + Ok(ModuleDefinition::Import(rc_import)) + } + ModuleDeclSyntax::Func(syntax) => { + let name = self.scope.introduce(&syntax.export)?; + let mut argnames = IdentValidation::new(); + let params = syntax + .params + .iter() + .map(|f| { + Ok(InterfaceFuncParam { + name: argnames.introduce(&f.name)?, + type_: self.doc.validate_datatype_ident(&f.type_)?, + }) + }) + .collect::, _>>()?; + let results = syntax + .results + .iter() + .map(|f| { + Ok(InterfaceFuncParam { + name: argnames.introduce(&f.name)?, + type_: self.doc.validate_datatype_ident(&f.type_)?, + }) + }) + .collect::, _>>()?; + + let rc_func = Rc::new(InterfaceFunc { + name: name.clone(), + params, + results, + }); + self.entries + .insert(name, ModuleEntry::Func(Rc::downgrade(&rc_func))); + Ok(ModuleDefinition::Func(rc_func)) + } + } + } +} diff --git a/proposals/clocks/tools/witx/tests/wasi_unstable.rs b/proposals/clocks/tools/witx/tests/wasi_unstable.rs new file mode 100644 index 000000000..e9188db67 --- /dev/null +++ b/proposals/clocks/tools/witx/tests/wasi_unstable.rs @@ -0,0 +1,7 @@ +use std::path::Path; +use witx_frontend; + +#[test] +fn validate_wasi_unstable() { + witx_frontend::load(Path::new("../../design/wasi_unstable/wasi_unstable.witx")).unwrap(); +} From e721eb0f1969e9da9c432d7e6b29f6da8f0b1f9e Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 13 Sep 2019 10:27:21 -0700 Subject: [PATCH 0164/1772] Add witx crate, to parse and validate witx (#90) * import witx-frontend crate * witx-frontend: add test that wasi_unstable.witx validates * witx-frontend: better error reporting * witx-frontend: add witx-specific pointer and constpointer constructions * wasi_unstable: fix syntax of preopentype_t * witx-frontend: add LICENSE file, fix repo capitalization * rename witx-frontend to witx --- .../design/wasi_unstable/typenames.witx | 2 +- proposals/random/tools/witx/.gitignore | 2 + proposals/random/tools/witx/Cargo.toml | 21 + proposals/random/tools/witx/LICENSE | 13 + proposals/random/tools/witx/src/ast.rs | 163 +++++ proposals/random/tools/witx/src/lexer.rs | 354 +++++++++++ proposals/random/tools/witx/src/lib.rs | 93 +++ proposals/random/tools/witx/src/main.rs | 38 ++ proposals/random/tools/witx/src/parser.rs | 583 ++++++++++++++++++ proposals/random/tools/witx/src/sexpr.rs | 236 +++++++ proposals/random/tools/witx/src/toplevel.rs | 243 ++++++++ proposals/random/tools/witx/src/validate.rs | 390 ++++++++++++ .../random/tools/witx/tests/wasi_unstable.rs | 7 + 13 files changed, 2144 insertions(+), 1 deletion(-) create mode 100644 proposals/random/tools/witx/.gitignore create mode 100644 proposals/random/tools/witx/Cargo.toml create mode 100644 proposals/random/tools/witx/LICENSE create mode 100644 proposals/random/tools/witx/src/ast.rs create mode 100644 proposals/random/tools/witx/src/lexer.rs create mode 100644 proposals/random/tools/witx/src/lib.rs create mode 100644 proposals/random/tools/witx/src/main.rs create mode 100644 proposals/random/tools/witx/src/parser.rs create mode 100644 proposals/random/tools/witx/src/sexpr.rs create mode 100644 proposals/random/tools/witx/src/toplevel.rs create mode 100644 proposals/random/tools/witx/src/validate.rs create mode 100644 proposals/random/tools/witx/tests/wasi_unstable.rs diff --git a/proposals/random/design/wasi_unstable/typenames.witx b/proposals/random/design/wasi_unstable/typenames.witx index 1d33a35f0..046ed0bf6 100644 --- a/proposals/random/design/wasi_unstable/typenames.witx +++ b/proposals/random/design/wasi_unstable/typenames.witx @@ -718,7 +718,7 @@ ) ;; Identifiers for preopened capabilities. -(typename preopentype_t +(typename $preopentype_t (enum u8 ;; A pre-opened directory. $PREOPENTYPE_DIR diff --git a/proposals/random/tools/witx/.gitignore b/proposals/random/tools/witx/.gitignore new file mode 100644 index 000000000..a9d37c560 --- /dev/null +++ b/proposals/random/tools/witx/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml new file mode 100644 index 000000000..f24cb7183 --- /dev/null +++ b/proposals/random/tools/witx/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "witx" +version = "0.1.0" +description = "Parse and validate witx file format" +homepage = "https://github.com/WebAssembly/WASI" +repository = "https://github.com/WebAssembly/WASI" +license = "Apache-2.0" +categories = ["wasm"] +authors = ["Pat Hickey "] +edition = "2018" + +[lib] +crate-type=["rlib"] + +[[bin]] +name = "witx" +path = "src/main.rs" + +[dependencies] +clap = "2" +failure = "0.1" diff --git a/proposals/random/tools/witx/LICENSE b/proposals/random/tools/witx/LICENSE new file mode 100644 index 000000000..e061f56ab --- /dev/null +++ b/proposals/random/tools/witx/LICENSE @@ -0,0 +1,13 @@ +Copyright 2019 WebAssembly Community Group participants + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs new file mode 100644 index 000000000..4df4d1e24 --- /dev/null +++ b/proposals/random/tools/witx/src/ast.rs @@ -0,0 +1,163 @@ +#![allow(dead_code)] +use std::collections::HashMap; +use std::rc::{Rc, Weak}; + +pub use crate::parser::BuiltinType; + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Id(String); + +impl Id { + pub fn new>(s: S) -> Self { + Id(s.as_ref().to_string()) + } + pub fn as_str(&self) -> &str { + self.0.as_str() + } +} + +#[derive(Debug, Clone)] +pub struct Document { + pub definitions: Vec, + pub entries: HashMap, +} + +#[derive(Debug, Clone)] +pub enum Definition { + Datatype(Rc), + Module(Rc), +} + +#[derive(Debug, Clone)] +pub enum Entry { + Datatype(Weak), + Module(Weak), +} + +impl Entry { + pub fn kind(&self) -> &'static str { + match self { + Entry::Datatype { .. } => "datatype", + Entry::Module { .. } => "module", + } + } +} + +#[derive(Debug, Clone)] +pub enum DatatypeIdent { + Builtin(BuiltinType), + Array(Box), + Pointer(Box), + ConstPointer(Box), + Ident(Rc), +} + +#[derive(Debug, Clone)] +pub struct Datatype { + pub name: Id, + pub variant: DatatypeVariant, +} + +#[derive(Debug, Clone)] +pub enum DatatypeVariant { + Alias(AliasDatatype), + Enum(EnumDatatype), + Flags(FlagsDatatype), + Struct(StructDatatype), + Union(UnionDatatype), +} + +#[derive(Debug, Clone)] +pub struct AliasDatatype { + pub name: Id, + pub to: DatatypeIdent, +} + +#[derive(Debug, Clone)] +pub enum IntRepr { + I8, + I16, + I32, + I64, +} + +#[derive(Debug, Clone)] +pub struct EnumDatatype { + pub name: Id, + pub repr: IntRepr, + pub variants: Vec, +} + +#[derive(Debug, Clone)] +pub struct FlagsDatatype { + pub name: Id, + pub repr: IntRepr, + pub flags: Vec, +} + +#[derive(Debug, Clone)] +pub struct StructDatatype { + pub name: Id, + pub members: Vec, +} + +#[derive(Debug, Clone)] +pub struct StructMember { + pub name: Id, + pub type_: DatatypeIdent, +} + +#[derive(Debug, Clone)] +pub struct UnionDatatype { + pub name: Id, + pub variants: Vec, +} + +#[derive(Debug, Clone)] +pub struct UnionVariant { + pub name: Id, + pub type_: DatatypeIdent, +} + +#[derive(Debug, Clone)] +pub struct Module { + pub name: Id, + pub definitions: Vec, + pub entries: HashMap, +} + +#[derive(Debug, Clone)] +pub enum ModuleDefinition { + Import(Rc), + Func(Rc), +} + +#[derive(Debug, Clone)] +pub enum ModuleEntry { + Import(Weak), + Func(Weak), +} + +#[derive(Debug, Clone)] +pub struct ModuleImport { + pub name: Id, + pub variant: ModuleImportVariant, +} + +#[derive(Debug, Clone)] +pub enum ModuleImportVariant { + Memory, +} + +#[derive(Debug, Clone)] +pub struct InterfaceFunc { + pub name: Id, + pub params: Vec, + pub results: Vec, +} + +#[derive(Debug, Clone)] +pub struct InterfaceFuncParam { + pub name: Id, + pub type_: DatatypeIdent, +} diff --git a/proposals/random/tools/witx/src/lexer.rs b/proposals/random/tools/witx/src/lexer.rs new file mode 100644 index 000000000..b004acf07 --- /dev/null +++ b/proposals/random/tools/witx/src/lexer.rs @@ -0,0 +1,354 @@ +use crate::Location; +use failure::Fail; +use std::path::{Path, PathBuf}; +use std::str::CharIndices; + +///! The lexer turns a string into a stream of located tokens. +///! The tokens are meant for consumption by the s-expression parser. +///! +///! Comments in source text look like `;; rest of line ...`. +///! Words look like `abcde_` +///! Idents look like `$abcde_` +///! Annotations look like `@abcde_` +///! Quotes look like `"a b cde 123 @#$%^&*() _"` +///! +///! This implementation was heavily influenced by `cranelift-reader` + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum Token<'a> { + LPar, // ( + RPar, // ) + Word(&'a str), // Bare word + Ident(&'a str), // Starts with $ + Annot(&'a str), // Starts with @. short for annotation. + Quote(&'a str), // Found between balanced "". No escaping. +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct LocatedToken<'a> { + pub token: Token<'a>, + pub location: Location, +} + +fn token(token: Token<'_>, location: Location) -> Result, LocatedError> { + Ok(LocatedToken { token, location }) +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy, Fail)] +pub enum LexError { + #[fail(display = "Invalid character '{}'", _0)] + InvalidChar(char), + #[fail(display = "Empty identifier '$'")] + EmptyIdentifier, + #[fail(display = "Empty annotation '@'")] + EmptyAnnotation, + #[fail(display = "Unterminated quote")] + UnterminatedQuote, +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct LocatedError { + pub error: LexError, + pub location: Location, +} + +fn error<'a>(error: LexError, location: Location) -> Result, LocatedError> { + Err(LocatedError { error, location }) +} + +pub struct Lexer<'a> { + source: &'a str, + chars: CharIndices<'a>, + lookahead: Option, + pos: usize, + line_number: usize, + column_start: usize, + tab_compensation: usize, + path: PathBuf, +} + +impl<'a> Lexer<'a> { + pub fn new>(s: &'a str, path: P) -> Lexer<'_> { + let mut lex = Lexer { + source: s, + chars: s.char_indices(), + lookahead: None, + pos: 0, + line_number: 1, + column_start: 0, + tab_compensation: 0, + path: path.as_ref().into(), + }; + lex.next_ch(); + lex + } + + fn next_ch(&mut self) -> Option { + if self.lookahead == Some('\n') { + self.line_number += 1; + self.column_start = self.pos + 1; // Next column starts a fresh line + self.tab_compensation = 0; + } else if self.lookahead == Some('\t') { + self.tab_compensation += 7; // One column for the position of the char itself, add 7 more for a tabwidth of 8 + } + match self.chars.next() { + Some((idx, ch)) => { + self.pos = idx; + self.lookahead = Some(ch); + } + None => { + self.pos = self.source.len(); + self.lookahead = None; + } + } + self.lookahead + } + + fn loc(&self) -> Location { + Location { + path: self.path.clone(), + line: self.line_number, + column: self.pos - self.column_start + self.tab_compensation, + } + } + + fn looking_at(&self, prefix: &str) -> bool { + self.source[self.pos..].starts_with(prefix) + } + + fn scan_char(&mut self, tok: Token<'a>) -> Result, LocatedError> { + assert!(self.lookahead.is_some()); + let loc = self.loc(); + self.next_ch(); + token(tok, loc) + } + + pub fn rest_of_line(&mut self) -> &'a str { + let begin = self.pos; + loop { + match self.next_ch() { + None | Some('\n') => return &self.source[begin..self.pos], + _ => {} + } + } + } + + fn scan_word(&mut self) -> Result, LocatedError> { + let begin = self.pos; + let loc = self.loc(); + assert!(self.lookahead == Some('_') || self.lookahead.unwrap().is_alphabetic()); + loop { + match self.next_ch() { + Some('_') | Some('-') => {} + Some(ch) if ch.is_alphanumeric() => {} + _ => break, + } + } + let text = &self.source[begin..self.pos]; + token(Token::Word(text), loc) + } + + fn scan_ident(&mut self) -> Result, LocatedError> { + let loc = self.loc(); + assert!(self.lookahead == Some('$')); + match self.next_ch() { + Some(ch) if ch.is_alphanumeric() || ch == '_' => {} + _ => Err(LocatedError { + error: LexError::EmptyIdentifier, + location: loc.clone(), + })?, + } + let begin = self.pos; + + loop { + match self.next_ch() { + Some('_') | Some('-') => {} + Some(ch) if ch.is_alphanumeric() => {} + _ => break, + } + } + + let text = &self.source[begin..self.pos]; + token(Token::Ident(text), loc) + } + + fn scan_annotation(&mut self) -> Result, LocatedError> { + let loc = self.loc(); + assert!(self.lookahead == Some('@')); + match self.next_ch() { + Some(ch) if ch.is_alphanumeric() || ch == '_' => {} + _ => Err(LocatedError { + error: LexError::EmptyAnnotation, + location: loc.clone(), + })?, + } + let begin = self.pos; + + loop { + match self.next_ch() { + Some('_') | Some('-') => {} + Some(ch) if ch.is_alphanumeric() => {} + _ => break, + } + } + + let text = &self.source[begin..self.pos]; + token(Token::Annot(text), loc) + } + + fn scan_quote(&mut self) -> Result, LocatedError> { + let begin = self.pos; + let loc = self.loc(); + assert!(self.lookahead == Some('"')); + loop { + match self.next_ch() { + None => Err(LocatedError { + error: LexError::UnterminatedQuote, + location: loc.clone(), + })?, + Some('"') => { + self.next_ch(); + break; + } + _ => {} + } + } + let text = &self.source[(begin + 1)..(self.pos - 1)]; + token(Token::Quote(text), loc) + } + + #[allow(clippy::should_implement_trait)] + pub fn next(&mut self) -> Option, LocatedError>> { + loop { + let loc = self.loc(); + return match self.lookahead { + None => None, + Some(c) => Some(match c { + '(' => self.scan_char(Token::LPar), + ')' => self.scan_char(Token::RPar), + '$' => self.scan_ident(), + '@' => self.scan_annotation(), + ';' => { + if self.looking_at(";;") { + self.rest_of_line(); + continue; + } else { + self.next_ch(); + error(LexError::InvalidChar(';'), loc) + } + } + '"' => self.scan_quote(), + '_' => self.scan_word(), + ch if ch.is_alphabetic() => self.scan_word(), + ch if ch.is_whitespace() => { + self.next_ch(); + continue; + } + _ => { + self.next_ch(); + error(LexError::InvalidChar(c), loc) + } + }), + }; + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use std::path::{Path, PathBuf}; + + fn testlexer(input: &str) -> Lexer { + Lexer::new(input, Path::new("/test")) + } + + fn token( + token: Token<'_>, + line: usize, + column: usize, + ) -> Option, LocatedError>> { + Some(super::token( + token, + Location { + path: PathBuf::from("/test"), + line, + column, + }, + )) + } + + fn error<'a>( + err: LexError, + line: usize, + column: usize, + ) -> Option, LocatedError>> { + Some(super::error( + err, + Location { + path: PathBuf::from("/test"), + line, + column, + }, + )) + } + #[test] + fn words_and_idents() { + let mut lex = testlexer("$gussie is a good $dog"); + // ruler 0 5 10 15 20 + assert_eq!(lex.next(), token(Token::Ident("gussie"), 1, 0)); + assert_eq!(lex.next(), token(Token::Word("is"), 1, 8)); + assert_eq!(lex.next(), token(Token::Word("a"), 1, 11)); + assert_eq!(lex.next(), token(Token::Word("good"), 1, 13)); + assert_eq!(lex.next(), token(Token::Ident("dog"), 1, 18)); + assert_eq!(lex.next(), None); + + let mut lex = + testlexer("$ok $a $_ $ _\nkebab-case\nsnake_case\n$kebab-ident\n$snake_ident"); + assert_eq!(lex.next(), token(Token::Ident("ok"), 1, 0)); + assert_eq!(lex.next(), token(Token::Ident("a"), 1, 4)); + assert_eq!(lex.next(), token(Token::Ident("_"), 1, 7)); + assert_eq!(lex.next(), error(LexError::EmptyIdentifier, 1, 10)); + assert_eq!(lex.next(), token(Token::Word("_"), 1, 12)); + assert_eq!(lex.next(), token(Token::Word("kebab-case"), 2, 0)); + assert_eq!(lex.next(), token(Token::Word("snake_case"), 3, 0)); + assert_eq!(lex.next(), token(Token::Ident("kebab-ident"), 4, 0)); + assert_eq!(lex.next(), token(Token::Ident("snake_ident"), 5, 0)); + assert_eq!(lex.next(), None); + } + + #[test] + fn comments() { + let mut lex = testlexer("the quick ;; brown fox\njumped\n;;over the three\nlazy;;dogs"); + assert_eq!(lex.next(), token(Token::Word("the"), 1, 0)); + assert_eq!(lex.next(), token(Token::Word("quick"), 1, 4)); + assert_eq!(lex.next(), token(Token::Word("jumped"), 2, 0)); + assert_eq!(lex.next(), token(Token::Word("lazy"), 4, 0)); + assert_eq!(lex.next(), None); + + let mut lex = testlexer("line1 ;;\n$sym_2;\n\t\tl3;;;333"); + assert_eq!(lex.next(), token(Token::Word("line1"), 1, 0)); + assert_eq!(lex.next(), token(Token::Ident("sym_2"), 2, 0)); + assert_eq!(lex.next(), error(LexError::InvalidChar(';'), 2, 6)); + assert_eq!(lex.next(), token(Token::Word("l3"), 3, 16)); // Two tabs = 16 columns + assert_eq!(lex.next(), None); + } + + #[test] + fn quotes() { + let mut lex = testlexer("a \"bc\" d"); + assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); + assert_eq!(lex.next(), token(Token::Quote("bc"), 1, 2)); + assert_eq!(lex.next(), token(Token::Word("d"), 1, 7)); + + let mut lex = testlexer("a \"b\nc\" d"); + assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); + assert_eq!(lex.next(), token(Token::Quote("b\nc"), 1, 2)); + assert_eq!(lex.next(), token(Token::Word("d"), 2, 3)); + + let mut lex = testlexer("a \"b"); + assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); + assert_eq!(lex.next(), error(LexError::UnterminatedQuote, 1, 2)); + } +} diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs new file mode 100644 index 000000000..7d5040d00 --- /dev/null +++ b/proposals/random/tools/witx/src/lib.rs @@ -0,0 +1,93 @@ +/// Types describing a validated witx document +mod ast; +/// Lexer text into tokens +mod lexer; +/// Witx syntax parsing from SExprs +mod parser; +/// SExpr parsing from tokens +mod sexpr; +/// Resolve toplevel `use` declarations across files +mod toplevel; +/// Validate declarations into ast +mod validate; + +pub use ast::{ + AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, + Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, Module, + ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, + UnionDatatype, UnionVariant, +}; +pub use lexer::LexError; +pub use parser::{DeclSyntax, ParseError}; +pub use sexpr::SExprParseError; +pub use validate::ValidationError; + +use failure::Fail; +use std::io; +use std::path::{Path, PathBuf}; + +pub fn load>(path: P) -> Result { + use toplevel::parse_witx; + use validate::validate_document; + let parsed_decls = parse_witx(path)?; + validate_document(&parsed_decls).map_err(WitxError::Validation) +} + +/// Location in the source text +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct Location { + pub path: PathBuf, + pub line: usize, + pub column: usize, +} + +#[derive(Debug, Fail)] +pub enum WitxError { + #[fail(display = "{}", _0)] + SExpr(#[cause] SExprParseError), + #[fail(display = "when resolving use declaration for {:?}: {}", _0, _1)] + UseResolution(PathBuf, #[cause] io::Error), + #[fail(display = "{}", _0)] + Parse(#[cause] ParseError), + #[fail(display = "{}", _0)] + Validation(#[cause] ValidationError), +} + +impl WitxError { + pub fn report(&self) -> String { + use WitxError::*; + match self { + SExpr(sexpr) => sexpr.report(), + UseResolution(path, ioerr) => format!("when resolving `use {:?}`: {}", path, ioerr), + Parse(parse) => parse.report(), + Validation(validation) => validation.report(), + } + } +} +impl Location { + pub fn highlight_source(&self) -> String { + let mut msg = format!("in {:?}:\n", self.path); + if let Ok(src_line) = self.source_line() { + msg += &format!( + "{line_num: >5} | {src_line}\n{blank: >5} {caret: >column$}", + line_num = self.line, + src_line = src_line, + blank = " ", + caret = "^", + column = self.column, + ); + } + msg + } + pub fn source_line(&self) -> Result { + use std::fs::File; + use std::io::{BufRead, BufReader}; + let f = BufReader::new(File::open(&self.path)?); + let l = f + .lines() + .skip(self.line - 1) + .next() + .unwrap_or_else(|| Err(io::Error::new(io::ErrorKind::Other, "TODO")))?; + Ok(l) + } +} diff --git a/proposals/random/tools/witx/src/main.rs b/proposals/random/tools/witx/src/main.rs new file mode 100644 index 000000000..c2ad70322 --- /dev/null +++ b/proposals/random/tools/witx/src/main.rs @@ -0,0 +1,38 @@ +use clap::{App, Arg}; +use std::path::Path; +use std::process; +use witx::load; + +pub fn main() { + let app = App::new("witx") + .version(env!("CARGO_PKG_VERSION")) + .about("Validate witx file format") + .arg( + Arg::with_name("input") + .required(true) + .help("path to root of witx document"), + ) + .arg( + Arg::with_name("verbose") + .short("v") + .long("verbose") + .takes_value(false) + .required(false), + ) + .get_matches(); + + match load(Path::new(app.value_of("input").expect("required arg"))) { + Ok(doc) => { + if app.is_present("verbose") { + println!("{:?}", doc) + } + } + Err(e) => { + println!("{}", e.report()); + if app.is_present("verbose") { + println!("{:?}", e); + } + process::exit(1) + } + } +} diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs new file mode 100644 index 000000000..a99df5fa4 --- /dev/null +++ b/proposals/random/tools/witx/src/parser.rs @@ -0,0 +1,583 @@ +use crate::sexpr::SExpr; +use crate::Location; +use failure::Fail; + +///! Parser turns s-expressions into unvalidated syntax constructs. +///! conventions: +///! `Type::starts_parsing(s-expr) -> bool` is for look-ahead: we use +///! this predicate to combine parsers for different `Type`s where both +///! alternatives are accepted. +///! `Type::parse(sexpr: &SExpr) -> Result` takes a single +///! s-expression and parses it into a `Self`. +///! for parsers that take a subset of a vector s-expression, the signature +///! `Type::parse(sexprs: &[SExpr], location: Location) -> Result` +///! has an additional `Location` argument, which should point to the parent SExpr::Vec. +///! This is used for error reporting in case the slice doesn't have the number of elements +///! expected. + +#[derive(Debug, Fail)] +#[fail(display = "{} at {:?}", _0, _1)] +pub struct ParseError { + pub message: String, + pub location: Location, +} + +impl ParseError { + pub fn report(&self) -> String { + format!("{}\n{}", self.location.highlight_source(), self.message) + } +} + +macro_rules! parse_err { + ($loc:expr, $msg:expr) => { + ParseError { message: $msg.to_string(), location: $loc.clone() } + }; + ($loc:expr, $fmt:expr, $( $arg:expr ),+ ) => { + ParseError { message: format!($fmt, $( $arg ),+), location: $loc.clone() } + }; +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct IdentSyntax { + pub name: String, + pub location: Location, +} + +macro_rules! id { + ($s:expr, $loc: expr) => { + IdentSyntax { + name: $s.to_string(), + location: $loc.clone(), + } + }; +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum BuiltinType { + String, + Data, + U8, + U16, + U32, + U64, + S8, + S16, + S32, + S64, + F32, + F64, +} + +impl BuiltinType { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + match sexpr { + SExpr::Word("string", _) + | SExpr::Word("data", _) + | SExpr::Word("u8", _) + | SExpr::Word("u16", _) + | SExpr::Word("u32", _) + | SExpr::Word("u64", _) + | SExpr::Word("s8", _) + | SExpr::Word("s16", _) + | SExpr::Word("s32", _) + | SExpr::Word("s64", _) + | SExpr::Word("f32", _) + | SExpr::Word("f64", _) => true, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + match sexpr { + SExpr::Word("string", _loc) => Ok(BuiltinType::String), + SExpr::Word("data", _loc) => Ok(BuiltinType::Data), + SExpr::Word("u8", _loc) => Ok(BuiltinType::U8), + SExpr::Word("u16", _loc) => Ok(BuiltinType::U16), + SExpr::Word("u32", _loc) => Ok(BuiltinType::U32), + SExpr::Word("u64", _loc) => Ok(BuiltinType::U64), + SExpr::Word("s8", _loc) => Ok(BuiltinType::S8), + SExpr::Word("s16", _loc) => Ok(BuiltinType::S16), + SExpr::Word("s32", _loc) => Ok(BuiltinType::S32), + SExpr::Word("s64", _loc) => Ok(BuiltinType::S64), + SExpr::Word("f32", _loc) => Ok(BuiltinType::F32), + SExpr::Word("f64", _loc) => Ok(BuiltinType::F64), + _ => Err(parse_err!(sexpr.location(), "invalid builtin type")), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum DatatypeIdentSyntax { + Builtin(BuiltinType), + Array(Box), + Pointer(Box), + ConstPointer(Box), + Ident(IdentSyntax), +} + +impl DatatypeIdentSyntax { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + BuiltinType::starts_parsing(sexpr) + || match sexpr { + SExpr::Ident(_, _) => true, + SExpr::Vec(v, _) => match (v.get(0), v.get(1)) { + (Some(SExpr::Word("array", _)), Some(_)) => true, + (Some(SExpr::Annot("witx", _)), Some(SExpr::Word("pointer", _))) => true, + (Some(SExpr::Annot("witx", _)), Some(SExpr::Word("const_pointer", _))) => true, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + if BuiltinType::starts_parsing(sexpr) { + let builtin = BuiltinType::parse(sexpr)?; + Ok(DatatypeIdentSyntax::Builtin(builtin)) + } else { + match sexpr { + SExpr::Ident(i, loc) => Ok(DatatypeIdentSyntax::Ident(id!(i, loc))), + SExpr::Vec(v, loc) => match (v.get(0), v.get(1), v.get(2)) { + (Some(SExpr::Word("array", _)), Some(expr), None) => Ok( + DatatypeIdentSyntax::Array(Box::new(DatatypeIdentSyntax::parse(expr)?)), + ), + ( + Some(SExpr::Annot("witx", _)), + Some(SExpr::Word("pointer", _)), + Some(expr), + ) => Ok(DatatypeIdentSyntax::Pointer(Box::new( + DatatypeIdentSyntax::parse(expr)?, + ))), + ( + Some(SExpr::Annot("witx", _)), + Some(SExpr::Word("const_pointer", _)), + Some(expr), + ) => Ok(DatatypeIdentSyntax::ConstPointer(Box::new( + DatatypeIdentSyntax::parse(expr)?, + ))), + _ => Err(parse_err!(loc, "expected type identifier")), + }, + _ => Err(parse_err!(sexpr.location(), "expected type identifier")), + } + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum TopLevelSyntax { + Decl(DeclSyntax), + Use(IdentSyntax), +} + +impl TopLevelSyntax { + pub fn parse(sexpr: &SExpr) -> Result { + if DeclSyntax::starts_parsing(sexpr) { + let decl = DeclSyntax::parse(sexpr)?; + Ok(TopLevelSyntax::Decl(decl)) + } else { + match sexpr { + SExpr::Vec(v, vec_loc) => match v.get(0) { + Some(SExpr::Word("use", loc)) => match v.get(1) { + Some(SExpr::Quote(u, loc)) => Ok(TopLevelSyntax::Use(id!(u, loc))), + _ => Err(parse_err!(loc, "invalid use declaration")), + }, + _ => Err(parse_err!(vec_loc, "expected top level declaration")), + }, + _ => Err(parse_err!( + sexpr.location(), + "expected top level declaration" + )), + } + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum DeclSyntax { + Typename(TypenameSyntax), + Module(ModuleSyntax), +} + +impl DeclSyntax { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + match sexpr { + SExpr::Vec(v, _) => match v.get(0) { + Some(SExpr::Word("typename", _)) => true, + Some(SExpr::Word("module", _)) => true, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + match sexpr { + SExpr::Vec(v, loc) => match v.get(0) { + Some(SExpr::Word("typename", loc)) => { + Ok(DeclSyntax::Typename(TypenameSyntax::parse(&v[1..], loc)?)) + } + Some(SExpr::Word("module", loc)) => { + Ok(DeclSyntax::Module(ModuleSyntax::parse(&v[1..], loc)?)) + } + _ => Err(parse_err!(loc, "invalid declaration")), + }, + _ => Err(parse_err!(sexpr.location(), "expected vec")), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TypenameSyntax { + pub ident: IdentSyntax, + pub def: TypedefSyntax, +} + +impl TypenameSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + let ident = match sexpr.get(0) { + Some(SExpr::Ident(i, loc)) => id!(i, loc), + Some(s) => Err(parse_err!(s.location(), "expected typename identifier"))?, + None => Err(parse_err!(loc, "expected typename identifier"))?, + }; + let def = match sexpr.get(1) { + Some(expr) => TypedefSyntax::parse(expr)?, + _ => Err(parse_err!(loc, "expected type definition"))?, + }; + Ok(TypenameSyntax { ident, def }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum TypedefSyntax { + Ident(DatatypeIdentSyntax), + Enum(EnumSyntax), + Flags(FlagsSyntax), + Struct(StructSyntax), + Union(UnionSyntax), +} + +impl TypedefSyntax { + pub fn parse(sexpr: &SExpr) -> Result { + if DatatypeIdentSyntax::starts_parsing(sexpr) { + let ident = DatatypeIdentSyntax::parse(sexpr)?; + Ok(TypedefSyntax::Ident(ident)) + } else { + match sexpr { + SExpr::Vec(vs, loc) => match vs.get(0) { + Some(SExpr::Word("enum", loc)) => { + Ok(TypedefSyntax::Enum(EnumSyntax::parse(&vs[1..], loc)?)) + } + Some(SExpr::Word("flags", loc)) => { + Ok(TypedefSyntax::Flags(FlagsSyntax::parse(&vs[1..], loc)?)) + } + Some(SExpr::Word("struct", loc)) => { + Ok(TypedefSyntax::Struct(StructSyntax::parse(&vs[1..], loc)?)) + } + Some(SExpr::Word("union", loc)) => { + Ok(TypedefSyntax::Union(UnionSyntax::parse(&vs[1..], loc)?)) + } + _ => Err(parse_err!( + loc, + "expected type identifier or type definition" + )), + }, + _ => Err(parse_err!( + sexpr.location(), + "expected type identifier or type definition" + )), + } + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct EnumSyntax { + pub repr: BuiltinType, + pub members: Vec, +} + +impl EnumSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + let repr = match sexpr.get(0) { + Some(e) => BuiltinType::parse(e)?, + _ => Err(parse_err!(loc, "no enum repr"))?, + }; + let members = sexpr[1..] + .iter() + .map(|m| match m { + SExpr::Ident(i, loc) => Ok(id!(i, loc)), + s => Err(parse_err!(s.location(), "expected enum member identifier")), + }) + .collect::, ParseError>>()?; + if members.is_empty() { + Err(parse_err!(loc, "expected at least one enum member"))? + } + Ok(EnumSyntax { repr, members }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FlagsSyntax { + pub repr: BuiltinType, + pub flags: Vec, +} + +impl FlagsSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + let repr = BuiltinType::parse( + sexpr + .get(0) + .ok_or_else(|| parse_err!(loc, "expected flag repr type"))?, + )?; + let flags = sexpr[1..] + .iter() + .map(|f| match f { + SExpr::Vec(vs, loc) => match (vs.get(0), vs.get(1)) { + (Some(SExpr::Word("flag", _)), Some(SExpr::Ident(i, loc))) => Ok(id!(i, loc)), + _ => Err(parse_err!(loc, "expected flag specifier")), + }, + s => Err(parse_err!(s.location(), "expected flag specifier")), + }) + .collect::, ParseError>>()?; + Ok(FlagsSyntax { repr, flags }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct StructSyntax { + pub fields: Vec, +} + +impl StructSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + if sexpr.is_empty() { + Err(parse_err!(loc, "expected at least one struct member"))? + } + let fields = sexpr + .iter() + .map(|f| FieldSyntax::parse(f, "field")) + .collect::, ParseError>>()?; + Ok(StructSyntax { fields }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FieldSyntax { + pub name: IdentSyntax, + pub type_: DatatypeIdentSyntax, +} + +impl FieldSyntax { + pub fn starts_parsing(sexpr: &SExpr, constructor: &str) -> bool { + match sexpr { + SExpr::Vec(v, _) => match v.get(0) { + Some(SExpr::Word(c, _)) => *c == constructor, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr, constructor: &str) -> Result { + match sexpr { + SExpr::Vec(v, loc) => match v.get(0) { + Some(SExpr::Word(c, _)) if *c == constructor => { + let name = match v.get(1) { + Some(SExpr::Ident(i, loc)) => id!(i, loc), + _ => Err(parse_err!(loc, "expected {} name identifier", constructor))?, + }; + let type_ = DatatypeIdentSyntax::parse(v.get(2).ok_or_else(|| { + parse_err!(loc, "expected {} type identifier", constructor) + })?)?; + Ok(FieldSyntax { name, type_ }) + } + _ => Err(parse_err!(loc, "expected {}", constructor)), + }, + _ => Err(parse_err!(sexpr.location(), "expected {}", constructor)), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct UnionSyntax { + pub fields: Vec, +} + +impl UnionSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + if sexpr.is_empty() { + Err(parse_err!(loc, "expected at least one union member"))? + } + let fields = sexpr + .iter() + .map(|f| FieldSyntax::parse(f, "field")) + .collect::, ParseError>>()?; + Ok(UnionSyntax { fields }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ModuleSyntax { + pub name: IdentSyntax, + pub decls: Vec, +} + +impl ModuleSyntax { + pub fn parse(sexprs: &[SExpr], loc: &Location) -> Result { + let name = match sexprs.get(0) { + Some(SExpr::Ident(i, loc)) => id!(i, loc), + _ => Err(parse_err!(loc, "expected module name"))?, + }; + let decls = sexprs[1..] + .iter() + .map(|s| ModuleDeclSyntax::parse(s)) + .collect::, _>>()?; + Ok(ModuleSyntax { name, decls }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ModuleDeclSyntax { + Import(ModuleImportSyntax), + Func(InterfaceFuncSyntax), +} + +impl ModuleDeclSyntax { + pub fn parse(sexpr: &SExpr) -> Result { + if ModuleImportSyntax::starts_parsing(sexpr) { + Ok(ModuleDeclSyntax::Import(ModuleImportSyntax::parse(sexpr)?)) + } else if InterfaceFuncSyntax::starts_parsing(sexpr) { + Ok(ModuleDeclSyntax::Func(InterfaceFuncSyntax::parse(sexpr)?)) + } else { + Err(parse_err!(sexpr.location(), "expected import or function")) + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ModuleImportSyntax { + pub name: IdentSyntax, + pub type_: ImportTypeSyntax, +} + +impl ModuleImportSyntax { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + match sexpr { + SExpr::Vec(vs, _) => match vs.get(0) { + Some(SExpr::Word("import", _)) => true, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + match sexpr { + SExpr::Vec(vs, vec_loc) => match (vs.get(0), vs.get(1)) { + (Some(SExpr::Word("import", _)), Some(SExpr::Quote(name, loc))) => { + let name = id!(name, loc); + let type_ = ImportTypeSyntax::parse(&vs[2..], vec_loc)?; + Ok(ModuleImportSyntax { name, type_ }) + } + _ => Err(parse_err!(vec_loc, "expected module import")), + }, + _ => Err(parse_err!(sexpr.location(), "expected module import")), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ImportTypeSyntax { + Memory, +} + +impl ImportTypeSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + if sexpr.len() > 1 { + Err(parse_err!(loc, "too many elements for an import type"))?; + } + match sexpr.get(0) { + Some(SExpr::Vec(vs, loc)) => match vs.get(0) { + Some(SExpr::Word("memory", _)) => { + if vs.len() == 1 { + Ok(ImportTypeSyntax::Memory) + } else { + Err(parse_err!(loc, "too many elements for memory declaration")) + } + } + _ => Err(parse_err!(loc, "expected import type")), + }, + _ => Err(parse_err!(loc, "expected import type")), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct InterfaceFuncSyntax { + pub export: IdentSyntax, + pub params: Vec, + pub results: Vec, +} + +impl InterfaceFuncSyntax { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + match sexpr { + SExpr::Vec(vs, _) => match (vs.get(0), vs.get(1)) { + (Some(SExpr::Annot("interface", _)), Some(SExpr::Word("func", _))) => true, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + match sexpr { + SExpr::Vec(vs, loc) => match (vs.get(0), vs.get(1)) { + (Some(SExpr::Annot("interface", _)), Some(SExpr::Word("func", _))) => { + let export = match vs.get(2) { + Some(SExpr::Vec(es, loc)) => match (es.get(0), es.get(1)) { + ( + Some(SExpr::Word("export", _)), + Some(SExpr::Quote(name, name_loc)), + ) => { + if es.len() == 2 { + id!(name, name_loc) + } else { + Err(parse_err!( + loc, + "too many elements for export declaration" + ))? + } + } + _ => Err(parse_err!(loc, "expected export declaration"))?, + }, + _ => Err(parse_err!(loc, "expected export declaration"))?, + }; + let mut params = Vec::new(); + let mut results = Vec::new(); + + for sexpr in &vs[3..] { + if FieldSyntax::starts_parsing(sexpr, "param") { + let param = FieldSyntax::parse(sexpr, "param")?; + params.push(param); + } else if FieldSyntax::starts_parsing(sexpr, "result") { + let result = FieldSyntax::parse(sexpr, "result")?; + results.push(result); + } else { + Err(parse_err!( + sexpr.location(), + "expected param or result field" + ))?; + } + } + + Ok(InterfaceFuncSyntax { + export, + params, + results, + }) + } + _ => Err(parse_err!(loc, "expected interface func declaration")), + }, + + _ => Err(parse_err!( + sexpr.location(), + "expected interface func declaration" + )), + } + } +} diff --git a/proposals/random/tools/witx/src/sexpr.rs b/proposals/random/tools/witx/src/sexpr.rs new file mode 100644 index 000000000..6a34cf83b --- /dev/null +++ b/proposals/random/tools/witx/src/sexpr.rs @@ -0,0 +1,236 @@ +pub use crate::lexer::LexError; +use crate::lexer::{Lexer, LocatedError, LocatedToken, Token}; +use crate::Location; +use failure::Fail; +use std::path::{Path, PathBuf}; + +///! The s-expression parser turns a string into a stream of SExprs. +///! It uses the `Lexer` under the hood. +///! This implementation was heavily influenced by `cranelift-reader` + +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum SExpr<'a> { + Vec(Vec>, Location), + Word(&'a str, Location), + Ident(&'a str, Location), + Quote(&'a str, Location), + /// Short for Annotation + Annot(&'a str, Location), +} + +impl<'a> SExpr<'a> { + pub fn location(&self) -> Location { + match self { + SExpr::Vec(_, loc) => loc.clone(), + SExpr::Word(_, loc) => loc.clone(), + SExpr::Ident(_, loc) => loc.clone(), + SExpr::Quote(_, loc) => loc.clone(), + SExpr::Annot(_, loc) => loc.clone(), + } + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Fail)] +pub enum SExprParseError { + #[fail(display = "Lexical error: {}", _0)] + Lex(LexError, Location), + #[fail(display = "Unexpected ')'")] + UnexpectedCloseParen(Location), + #[fail(display = "Unexpected end of input in {:?}", _0)] + UnexpectedEof(PathBuf), +} + +impl SExprParseError { + pub fn report(&self) -> String { + use SExprParseError::*; + match self { + Lex(lex_err, loc) => format!("{}\n{}", loc.highlight_source(), lex_err), + UnexpectedCloseParen(loc) => format!("{}\n{}", loc.highlight_source(), self), + UnexpectedEof(_path) => format!("{}", self), + } + } +} + +pub struct SExprParser<'a> { + lex: Lexer<'a>, + lookahead: Option>, + location: Location, +} + +impl<'a> SExprParser<'a> { + pub fn new>(text: &'a str, path: P) -> SExprParser<'_> { + SExprParser { + lex: Lexer::new(text, path.as_ref()), + lookahead: None, + location: Location { + path: path.as_ref().into(), + line: 0, + column: 0, + }, + } + } + fn consume(&mut self) -> Token<'a> { + self.lookahead.take().expect("no token to consume") + } + fn token(&mut self) -> Result>, SExprParseError> { + while self.lookahead == None { + match self.lex.next() { + Some(Ok(LocatedToken { token, location })) => { + self.location = location; + self.lookahead = Some(token) + } + Some(Err(LocatedError { error, location })) => { + self.location = location.clone(); + Err(SExprParseError::Lex(error, location))?; + } + None => break, + } + } + Ok(self.lookahead) + } + + pub fn match_sexpr(&mut self) -> Result, SExprParseError> { + let location = self.location.clone(); + match self.token()? { + Some(Token::LPar) => { + self.consume(); + let mut members = Vec::new(); + loop { + match self.token()? { + Some(Token::RPar) => { + self.consume(); + break; + } + _ => { + members.push(self.match_sexpr()?); + } + } + } + Ok(SExpr::Vec(members, location)) + } + Some(Token::Word(word)) => { + self.consume(); + Ok(SExpr::Word(word, location)) + } + Some(Token::Ident(id)) => { + self.consume(); + Ok(SExpr::Ident(id, location)) + } + Some(Token::Annot(id)) => { + self.consume(); + Ok(SExpr::Annot(id, location)) + } + Some(Token::Quote(q)) => { + self.consume(); + Ok(SExpr::Quote(q, location)) + } + Some(Token::RPar) => Err(SExprParseError::UnexpectedCloseParen(location)), + None => Err(SExprParseError::UnexpectedEof(self.location.path.clone())), + } + } + + pub fn match_sexprs(&mut self) -> Result>, SExprParseError> { + let mut sexprs = Vec::new(); + while self.token()?.is_some() { + sexprs.push(self.match_sexpr()?); + } + Ok(sexprs) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::path::PathBuf; + + fn loc(line: usize, col: usize) -> Location { + Location { + path: PathBuf::from("/test"), + line: line, + column: col, + } + } + + fn testparser(input: &str) -> SExprParser { + SExprParser::new(input, Path::new("/test")) + } + + #[test] + fn empty() { + let mut parser = testparser(""); + assert_eq!(parser.match_sexprs().expect("valid parse"), Vec::new()); + let mut parser = testparser(" ;; just a comment\n;;another"); + assert_eq!(parser.match_sexprs().expect("valid parse"), Vec::new()); + } + + #[test] + fn atoms() { + let mut parser = testparser("hello\n$world\n\"a quotation\""); + assert_eq!( + parser.match_sexprs().expect("valid parse"), + vec![ + SExpr::Word("hello", loc(1, 0)), + SExpr::Ident("world", loc(2, 0)), + SExpr::Quote("a quotation", loc(3, 0)), + ] + ); + } + + #[test] + fn lists() { + let mut parser = testparser("()"); + assert_eq!( + parser.match_sexprs().expect("valid parse"), + vec![SExpr::Vec(vec![], loc(1, 0))] + ); + + let mut parser = testparser("(hello\n$world\n\"a quotation\")"); + assert_eq!( + parser.match_sexprs().expect("valid parse"), + vec![SExpr::Vec( + vec![ + SExpr::Word("hello", loc(1, 1)), + SExpr::Ident("world", loc(2, 0)), + SExpr::Quote("a quotation", loc(3, 0)), + ], + loc(1, 0) + )] + ); + + let mut parser = testparser("((($deep)))"); + assert_eq!( + parser.match_sexprs().expect("valid parse"), + vec![SExpr::Vec( + vec![SExpr::Vec( + vec![SExpr::Vec(vec![SExpr::Ident("deep", loc(1, 3))], loc(1, 2))], + loc(1, 1) + )], + loc(1, 0) + )] + ); + } + + #[test] + fn errors() { + let mut parser = testparser("("); + assert_eq!( + parser.match_sexprs().err().expect("dies"), + SExprParseError::UnexpectedEof(PathBuf::from("/test")) + ); + let mut parser = testparser(")"); + assert_eq!( + parser.match_sexprs().err().expect("dies"), + SExprParseError::UnexpectedCloseParen(loc(1, 0)) + ); + let mut parser = testparser("())"); + assert_eq!( + parser.match_sexprs().err().expect("dies"), + SExprParseError::UnexpectedCloseParen(loc(1, 2)) + ); + let mut parser = testparser("$ ;; should be a lex error"); + assert_eq!( + parser.match_sexprs().err().expect("dies"), + SExprParseError::Lex(LexError::EmptyIdentifier, loc(1, 0),), + ); + } +} diff --git a/proposals/random/tools/witx/src/toplevel.rs b/proposals/random/tools/witx/src/toplevel.rs new file mode 100644 index 000000000..cf3a5e377 --- /dev/null +++ b/proposals/random/tools/witx/src/toplevel.rs @@ -0,0 +1,243 @@ +use crate::parser::{DeclSyntax, ParseError, TopLevelSyntax}; +use crate::sexpr::SExprParser; +use crate::WitxError; +use std::collections::HashSet; +use std::fs; +use std::path::{Path, PathBuf}; + +trait WitxIo { + fn fgets(&self, path: &Path) -> Result; + fn canonicalize(&self, path: &Path) -> Result; +} + +struct Filesystem; + +impl WitxIo for Filesystem { + fn fgets(&self, path: &Path) -> Result { + fs::read_to_string(path).map_err(|e| WitxError::UseResolution(path.to_path_buf(), e)) + } + fn canonicalize(&self, path: &Path) -> Result { + path.canonicalize() + .map_err(|e| WitxError::UseResolution(path.to_path_buf(), e)) + } +} + +pub fn parse_witx>(i: P) -> Result, WitxError> { + parse_witx_with(i, &Filesystem) +} + +fn parse_witx_with>( + i: P, + witxio: &dyn WitxIo, +) -> Result, WitxError> { + let input_path = witxio.canonicalize(&i.as_ref())?; + + let input = witxio.fgets(&input_path)?; + + let toplevel = parse_toplevel(&input, &input_path)?; + let mut resolved = HashSet::new(); + resolved.insert(input_path.clone()); + let search_path = input_path.parent().unwrap_or(Path::new(".")); + resolve_uses(toplevel, &search_path, &mut resolved, witxio) +} + +fn parse_toplevel(source_text: &str, file_path: &Path) -> Result, WitxError> { + let mut sexpr_parser = SExprParser::new(source_text, file_path); + let sexprs = sexpr_parser.match_sexprs().map_err(WitxError::SExpr)?; + let top_levels = sexprs + .iter() + .map(|s| TopLevelSyntax::parse(s)) + .collect::, ParseError>>() + .map_err(WitxError::Parse)?; + Ok(top_levels) +} + +fn resolve_uses( + toplevel: Vec, + search_path: &Path, + used: &mut HashSet, + witxio: &dyn WitxIo, +) -> Result, WitxError> { + let mut decls = Vec::new(); + + for t in toplevel { + match t { + TopLevelSyntax::Decl(d) => decls.push(d), + TopLevelSyntax::Use(u) => { + let abs_path = witxio.canonicalize(&search_path.join(u.name))?; + // Include the decls from a use declaration only once + // in a given toplevel. Same idea as #pragma once. + if !used.contains(&abs_path) { + used.insert(abs_path.clone()); + + let source_text = witxio.fgets(&abs_path)?; + let inner_toplevels = parse_toplevel(&source_text, &abs_path)?; + + let inner_decls = resolve_uses(inner_toplevels, search_path, used, witxio)?; + decls.extend(inner_decls) + } + } + } + } + + Ok(decls) +} + +#[cfg(test)] +mod test { + use super::*; + use crate::parser::*; + use crate::Location; + use std::collections::HashMap; + + struct MockFs { + map: HashMap<&'static str, &'static str>, + } + + impl MockFs { + pub fn new(strings: Vec<(&'static str, &'static str)>) -> Self { + MockFs { + map: strings.into_iter().collect(), + } + } + } + + impl WitxIo for MockFs { + fn fgets(&self, path: &Path) -> Result { + if let Some(entry) = self.map.get(path.to_str().unwrap()) { + Ok(entry.to_string()) + } else { + use std::io::{Error, ErrorKind}; + Err(WitxError::UseResolution( + path.to_path_buf(), + Error::new(ErrorKind::Other, "mock fs: file not found"), + )) + } + } + fn canonicalize(&self, path: &Path) -> Result { + Ok(PathBuf::from(path)) + } + } + + #[test] + fn empty() { + assert_eq!( + parse_witx_with(&Path::new("/a"), &MockFs::new(vec![("/a", ";; empty")])) + .expect("parse"), + Vec::new(), + ); + } + + #[test] + fn one_use() { + assert_eq!( + parse_witx_with( + &Path::new("/a"), + &MockFs::new(vec![("/a", "(use \"b\")"), ("/b", ";; empty")]) + ) + .expect("parse"), + Vec::new(), + ); + } + + #[test] + fn multi_use() { + assert_eq!( + parse_witx_with( + &Path::new("/a"), + &MockFs::new(vec![ + ("/a", "(use \"b\")"), + ("/b", "(use \"c\")\n(typename $b_float f64)"), + ("/c", "(typename $c_int u32)") + ]) + ) + .expect("parse"), + vec![ + DeclSyntax::Typename(TypenameSyntax { + ident: IdentSyntax { + name: "c_int".to_owned(), + location: Location { + path: PathBuf::from("/c"), + line: 1, + column: 10, + } + }, + def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::U32)) + }), + DeclSyntax::Typename(TypenameSyntax { + ident: IdentSyntax { + name: "b_float".to_owned(), + location: Location { + path: PathBuf::from("/b"), + line: 2, + column: 10, + } + }, + def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::F64)) + }) + ], + ); + } + + #[test] + fn diamond_dependency() { + assert_eq!( + parse_witx_with( + &Path::new("/a"), + &MockFs::new(vec![ + ("/a", "(use \"b\")\n(use \"c\")"), + ("/b", "(use \"d\")"), + ("/c", "(use \"d\")"), + ("/d", "(typename $d_char u8)") + ]) + ) + .expect("parse"), + vec![DeclSyntax::Typename(TypenameSyntax { + ident: IdentSyntax { + name: "d_char".to_owned(), + location: Location { + path: PathBuf::from("/d"), + line: 1, + column: 10, + } + }, + def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::U8)) + })], + ); + } + + #[test] + fn use_not_found() { + match parse_witx_with(&Path::new("/a"), &MockFs::new(vec![("/a", "(use \"b\")")])) + .err() + .unwrap() + { + WitxError::UseResolution(path, _error) => assert_eq!(path, PathBuf::from("/b")), + e => panic!("wrong error: {:?}", e), + } + } + + #[test] + fn use_invalid() { + match parse_witx_with( + &Path::new("/a"), + &MockFs::new(vec![("/a", "(use bbbbbbb)")]), + ) + .err() + .unwrap() + { + WitxError::Parse(e) => { + assert_eq!(e.message, "invalid use declaration"); + assert_eq!( + e.location, + Location { + path: PathBuf::from("/a"), + line: 1, + column: 1 + } + ); + } + e => panic!("wrong error: {:?}", e), + } + } +} diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs new file mode 100644 index 000000000..7041fca98 --- /dev/null +++ b/proposals/random/tools/witx/src/validate.rs @@ -0,0 +1,390 @@ +use crate::{ + parser::{ + DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, IdentSyntax, ImportTypeSyntax, + ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + }, + AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, + Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, Location, + Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, + StructMember, UnionDatatype, UnionVariant, +}; +use failure::Fail; +use std::collections::HashMap; +use std::rc::Rc; + +#[derive(Debug, Fail)] +pub enum ValidationError { + #[fail(display = "Unknown name `{}`", name)] + UnknownName { name: String, location: Location }, + #[fail(display = "Redefinition of name `{}`", name)] + NameAlreadyExists { + name: String, + at_location: Location, + previous_location: Location, + }, + #[fail( + display = "Wrong kind of name `{}`: expected {}, got {}", + name, expected, got + )] + WrongKindName { + name: String, + location: Location, + expected: &'static str, + got: &'static str, + }, + #[fail(display = "Recursive definition of name `{}`", name)] + Recursive { name: String, location: Location }, + #[fail(display = "Invalid representation `{:?}`", repr)] + InvalidRepr { + repr: BuiltinType, + location: Location, + }, +} + +impl ValidationError { + pub fn report(&self) -> String { + use ValidationError::*; + match self { + UnknownName { location, .. } + | WrongKindName { location, .. } + | Recursive { location, .. } + | InvalidRepr { location, .. } => format!("{}\n{}", location.highlight_source(), &self), + NameAlreadyExists { + at_location, + previous_location, + .. + } => format!( + "{}\n{}\nOriginally defined at:\n{}", + at_location.highlight_source(), + &self, + previous_location.highlight_source(), + ), + } + } +} + +pub fn validate_document(decls: &[DeclSyntax]) -> Result { + let mut validator = DocValidation::new(); + let mut definitions = Vec::new(); + for d in decls { + definitions.push(validator.validate_decl(&d)?); + } + + Ok(Document { + entries: validator.entries, + definitions, + }) +} + +struct IdentValidation { + names: HashMap, +} + +impl IdentValidation { + fn new() -> Self { + Self { + names: HashMap::new(), + } + } + fn introduce(&mut self, syntax: &IdentSyntax) -> Result { + if let Some(introduced) = self.names.get(&syntax.name) { + Err(ValidationError::NameAlreadyExists { + name: syntax.name.clone(), + at_location: syntax.location.clone(), + previous_location: introduced.clone(), + }) + } else { + self.names + .insert(syntax.name.clone(), syntax.location.clone()); + Ok(Id::new(&syntax.name)) + } + } + + fn get(&self, syntax: &IdentSyntax) -> Result { + if self.names.get(&syntax.name).is_some() { + Ok(Id::new(&syntax.name)) + } else { + Err(ValidationError::UnknownName { + name: syntax.name.clone(), + location: syntax.location.clone(), + }) + } + } +} + +struct DocValidation { + scope: IdentValidation, + pub entries: HashMap, +} + +impl DocValidation { + fn new() -> Self { + Self { + scope: IdentValidation::new(), + entries: HashMap::new(), + } + } + + fn validate_decl(&mut self, decl: &DeclSyntax) -> Result { + match decl { + DeclSyntax::Typename(decl) => { + let name = self.scope.introduce(&decl.ident)?; + let variant = + match &decl.def { + TypedefSyntax::Ident(syntax) => DatatypeVariant::Alias(AliasDatatype { + name: name.clone(), + to: self.validate_datatype_ident(&syntax)?, + }), + TypedefSyntax::Enum(syntax) => DatatypeVariant::Enum(self.validate_enum( + &name, + &syntax, + &decl.ident.location, + )?), + TypedefSyntax::Flags(syntax) => DatatypeVariant::Flags( + self.validate_flags(&name, &syntax, &decl.ident.location)?, + ), + TypedefSyntax::Struct(syntax) => DatatypeVariant::Struct( + self.validate_struct(&name, &syntax, &decl.ident.location)?, + ), + TypedefSyntax::Union(syntax) => DatatypeVariant::Union( + self.validate_union(&name, &syntax, &decl.ident.location)?, + ), + }; + let rc_datatype = Rc::new(Datatype { + name: name.clone(), + variant, + }); + self.entries + .insert(name, Entry::Datatype(Rc::downgrade(&rc_datatype))); + Ok(Definition::Datatype(rc_datatype)) + } + DeclSyntax::Module(syntax) => { + let name = self.scope.introduce(&syntax.name)?; + let mut module_validator = ModuleValidation::new(self); + let definitions = syntax + .decls + .iter() + .map(|d| module_validator.validate_decl(&d)) + .collect::, _>>()?; + + let rc_module = Rc::new(Module { + name: name.clone(), + definitions, + entries: module_validator.entries, + }); + self.entries + .insert(name, Entry::Module(Rc::downgrade(&rc_module))); + Ok(Definition::Module(rc_module)) + } + } + } + + fn validate_datatype_ident( + &self, + syntax: &DatatypeIdentSyntax, + ) -> Result { + match syntax { + DatatypeIdentSyntax::Builtin(b) => Ok(DatatypeIdent::Builtin(*b)), + DatatypeIdentSyntax::Array(a) => Ok(DatatypeIdent::Array(Box::new( + self.validate_datatype_ident(&a)?, + ))), + DatatypeIdentSyntax::Pointer(a) => Ok(DatatypeIdent::Pointer(Box::new( + self.validate_datatype_ident(&a)?, + ))), + DatatypeIdentSyntax::ConstPointer(a) => Ok(DatatypeIdent::ConstPointer(Box::new( + self.validate_datatype_ident(&a)?, + ))), + DatatypeIdentSyntax::Ident(i) => { + let id = self.scope.get(i)?; + match self.entries.get(&id) { + Some(Entry::Datatype(weak_d)) => Ok(DatatypeIdent::Ident( + weak_d.upgrade().expect("weak backref to defined type"), + )), + Some(e) => Err(ValidationError::WrongKindName { + name: i.name.clone(), + location: i.location.clone(), + expected: "datatype", + got: e.kind(), + }), + None => Err(ValidationError::Recursive { + name: i.name.clone(), + location: i.location.clone(), + }), + } + } + } + } + + fn validate_enum( + &self, + name: &Id, + syntax: &EnumSyntax, + location: &Location, + ) -> Result { + let mut enum_scope = IdentValidation::new(); + let repr = validate_int_repr(&syntax.repr, location)?; + let variants = syntax + .members + .iter() + .map(|i| enum_scope.introduce(i)) + .collect::, _>>()?; + + Ok(EnumDatatype { + name: name.clone(), + repr, + variants, + }) + } + + fn validate_flags( + &self, + name: &Id, + syntax: &FlagsSyntax, + location: &Location, + ) -> Result { + let mut flags_scope = IdentValidation::new(); + let repr = validate_int_repr(&syntax.repr, location)?; + let flags = syntax + .flags + .iter() + .map(|i| flags_scope.introduce(i)) + .collect::, _>>()?; + + Ok(FlagsDatatype { + name: name.clone(), + repr, + flags, + }) + } + + fn validate_struct( + &self, + name: &Id, + syntax: &StructSyntax, + _location: &Location, + ) -> Result { + let mut member_scope = IdentValidation::new(); + let members = syntax + .fields + .iter() + .map(|f| { + Ok(StructMember { + name: member_scope.introduce(&f.name)?, + type_: self.validate_datatype_ident(&f.type_)?, + }) + }) + .collect::, _>>()?; + + Ok(StructDatatype { + name: name.clone(), + members, + }) + } + + fn validate_union( + &self, + name: &Id, + syntax: &UnionSyntax, + _location: &Location, + ) -> Result { + let mut variant_scope = IdentValidation::new(); + let variants = syntax + .fields + .iter() + .map(|f| { + Ok(UnionVariant { + name: variant_scope.introduce(&f.name)?, + type_: self.validate_datatype_ident(&f.type_)?, + }) + }) + .collect::, _>>()?; + + Ok(UnionDatatype { + name: name.clone(), + variants, + }) + } +} + +fn validate_int_repr(type_: &BuiltinType, location: &Location) -> Result { + match type_ { + BuiltinType::U8 => Ok(IntRepr::I8), + BuiltinType::U16 => Ok(IntRepr::I16), + BuiltinType::U32 => Ok(IntRepr::I32), + BuiltinType::U64 => Ok(IntRepr::I64), + _ => Err(ValidationError::InvalidRepr { + repr: type_.clone(), + location: location.clone(), + }), + } +} + +struct ModuleValidation<'a> { + doc: &'a DocValidation, + scope: IdentValidation, + pub entries: HashMap, +} + +impl<'a> ModuleValidation<'a> { + fn new(doc: &'a DocValidation) -> Self { + Self { + doc, + scope: IdentValidation::new(), + entries: HashMap::new(), + } + } + + fn validate_decl( + &mut self, + decl: &ModuleDeclSyntax, + ) -> Result { + match decl { + ModuleDeclSyntax::Import(syntax) => { + let name = self.scope.introduce(&syntax.name)?; + let variant = match syntax.type_ { + ImportTypeSyntax::Memory => ModuleImportVariant::Memory, + }; + let rc_import = Rc::new(ModuleImport { + name: name.clone(), + variant, + }); + self.entries + .insert(name, ModuleEntry::Import(Rc::downgrade(&rc_import))); + Ok(ModuleDefinition::Import(rc_import)) + } + ModuleDeclSyntax::Func(syntax) => { + let name = self.scope.introduce(&syntax.export)?; + let mut argnames = IdentValidation::new(); + let params = syntax + .params + .iter() + .map(|f| { + Ok(InterfaceFuncParam { + name: argnames.introduce(&f.name)?, + type_: self.doc.validate_datatype_ident(&f.type_)?, + }) + }) + .collect::, _>>()?; + let results = syntax + .results + .iter() + .map(|f| { + Ok(InterfaceFuncParam { + name: argnames.introduce(&f.name)?, + type_: self.doc.validate_datatype_ident(&f.type_)?, + }) + }) + .collect::, _>>()?; + + let rc_func = Rc::new(InterfaceFunc { + name: name.clone(), + params, + results, + }); + self.entries + .insert(name, ModuleEntry::Func(Rc::downgrade(&rc_func))); + Ok(ModuleDefinition::Func(rc_func)) + } + } + } +} diff --git a/proposals/random/tools/witx/tests/wasi_unstable.rs b/proposals/random/tools/witx/tests/wasi_unstable.rs new file mode 100644 index 000000000..e9188db67 --- /dev/null +++ b/proposals/random/tools/witx/tests/wasi_unstable.rs @@ -0,0 +1,7 @@ +use std::path::Path; +use witx_frontend; + +#[test] +fn validate_wasi_unstable() { + witx_frontend::load(Path::new("../../design/wasi_unstable/wasi_unstable.witx")).unwrap(); +} From 0312e1b28e4bb794951a58b17ea2999fe829cba7 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 13 Sep 2019 10:27:21 -0700 Subject: [PATCH 0165/1772] Add witx crate, to parse and validate witx (#90) * import witx-frontend crate * witx-frontend: add test that wasi_unstable.witx validates * witx-frontend: better error reporting * witx-frontend: add witx-specific pointer and constpointer constructions * wasi_unstable: fix syntax of preopentype_t * witx-frontend: add LICENSE file, fix repo capitalization * rename witx-frontend to witx --- .../design/wasi_unstable/typenames.witx | 2 +- proposals/filesystem/tools/witx/.gitignore | 2 + proposals/filesystem/tools/witx/Cargo.toml | 21 + proposals/filesystem/tools/witx/LICENSE | 13 + proposals/filesystem/tools/witx/src/ast.rs | 163 +++++ proposals/filesystem/tools/witx/src/lexer.rs | 354 +++++++++++ proposals/filesystem/tools/witx/src/lib.rs | 93 +++ proposals/filesystem/tools/witx/src/main.rs | 38 ++ proposals/filesystem/tools/witx/src/parser.rs | 583 ++++++++++++++++++ proposals/filesystem/tools/witx/src/sexpr.rs | 236 +++++++ .../filesystem/tools/witx/src/toplevel.rs | 243 ++++++++ .../filesystem/tools/witx/src/validate.rs | 390 ++++++++++++ .../tools/witx/tests/wasi_unstable.rs | 7 + 13 files changed, 2144 insertions(+), 1 deletion(-) create mode 100644 proposals/filesystem/tools/witx/.gitignore create mode 100644 proposals/filesystem/tools/witx/Cargo.toml create mode 100644 proposals/filesystem/tools/witx/LICENSE create mode 100644 proposals/filesystem/tools/witx/src/ast.rs create mode 100644 proposals/filesystem/tools/witx/src/lexer.rs create mode 100644 proposals/filesystem/tools/witx/src/lib.rs create mode 100644 proposals/filesystem/tools/witx/src/main.rs create mode 100644 proposals/filesystem/tools/witx/src/parser.rs create mode 100644 proposals/filesystem/tools/witx/src/sexpr.rs create mode 100644 proposals/filesystem/tools/witx/src/toplevel.rs create mode 100644 proposals/filesystem/tools/witx/src/validate.rs create mode 100644 proposals/filesystem/tools/witx/tests/wasi_unstable.rs diff --git a/proposals/filesystem/design/wasi_unstable/typenames.witx b/proposals/filesystem/design/wasi_unstable/typenames.witx index 1d33a35f0..046ed0bf6 100644 --- a/proposals/filesystem/design/wasi_unstable/typenames.witx +++ b/proposals/filesystem/design/wasi_unstable/typenames.witx @@ -718,7 +718,7 @@ ) ;; Identifiers for preopened capabilities. -(typename preopentype_t +(typename $preopentype_t (enum u8 ;; A pre-opened directory. $PREOPENTYPE_DIR diff --git a/proposals/filesystem/tools/witx/.gitignore b/proposals/filesystem/tools/witx/.gitignore new file mode 100644 index 000000000..a9d37c560 --- /dev/null +++ b/proposals/filesystem/tools/witx/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml new file mode 100644 index 000000000..f24cb7183 --- /dev/null +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "witx" +version = "0.1.0" +description = "Parse and validate witx file format" +homepage = "https://github.com/WebAssembly/WASI" +repository = "https://github.com/WebAssembly/WASI" +license = "Apache-2.0" +categories = ["wasm"] +authors = ["Pat Hickey "] +edition = "2018" + +[lib] +crate-type=["rlib"] + +[[bin]] +name = "witx" +path = "src/main.rs" + +[dependencies] +clap = "2" +failure = "0.1" diff --git a/proposals/filesystem/tools/witx/LICENSE b/proposals/filesystem/tools/witx/LICENSE new file mode 100644 index 000000000..e061f56ab --- /dev/null +++ b/proposals/filesystem/tools/witx/LICENSE @@ -0,0 +1,13 @@ +Copyright 2019 WebAssembly Community Group participants + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs new file mode 100644 index 000000000..4df4d1e24 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -0,0 +1,163 @@ +#![allow(dead_code)] +use std::collections::HashMap; +use std::rc::{Rc, Weak}; + +pub use crate::parser::BuiltinType; + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Id(String); + +impl Id { + pub fn new>(s: S) -> Self { + Id(s.as_ref().to_string()) + } + pub fn as_str(&self) -> &str { + self.0.as_str() + } +} + +#[derive(Debug, Clone)] +pub struct Document { + pub definitions: Vec, + pub entries: HashMap, +} + +#[derive(Debug, Clone)] +pub enum Definition { + Datatype(Rc), + Module(Rc), +} + +#[derive(Debug, Clone)] +pub enum Entry { + Datatype(Weak), + Module(Weak), +} + +impl Entry { + pub fn kind(&self) -> &'static str { + match self { + Entry::Datatype { .. } => "datatype", + Entry::Module { .. } => "module", + } + } +} + +#[derive(Debug, Clone)] +pub enum DatatypeIdent { + Builtin(BuiltinType), + Array(Box), + Pointer(Box), + ConstPointer(Box), + Ident(Rc), +} + +#[derive(Debug, Clone)] +pub struct Datatype { + pub name: Id, + pub variant: DatatypeVariant, +} + +#[derive(Debug, Clone)] +pub enum DatatypeVariant { + Alias(AliasDatatype), + Enum(EnumDatatype), + Flags(FlagsDatatype), + Struct(StructDatatype), + Union(UnionDatatype), +} + +#[derive(Debug, Clone)] +pub struct AliasDatatype { + pub name: Id, + pub to: DatatypeIdent, +} + +#[derive(Debug, Clone)] +pub enum IntRepr { + I8, + I16, + I32, + I64, +} + +#[derive(Debug, Clone)] +pub struct EnumDatatype { + pub name: Id, + pub repr: IntRepr, + pub variants: Vec, +} + +#[derive(Debug, Clone)] +pub struct FlagsDatatype { + pub name: Id, + pub repr: IntRepr, + pub flags: Vec, +} + +#[derive(Debug, Clone)] +pub struct StructDatatype { + pub name: Id, + pub members: Vec, +} + +#[derive(Debug, Clone)] +pub struct StructMember { + pub name: Id, + pub type_: DatatypeIdent, +} + +#[derive(Debug, Clone)] +pub struct UnionDatatype { + pub name: Id, + pub variants: Vec, +} + +#[derive(Debug, Clone)] +pub struct UnionVariant { + pub name: Id, + pub type_: DatatypeIdent, +} + +#[derive(Debug, Clone)] +pub struct Module { + pub name: Id, + pub definitions: Vec, + pub entries: HashMap, +} + +#[derive(Debug, Clone)] +pub enum ModuleDefinition { + Import(Rc), + Func(Rc), +} + +#[derive(Debug, Clone)] +pub enum ModuleEntry { + Import(Weak), + Func(Weak), +} + +#[derive(Debug, Clone)] +pub struct ModuleImport { + pub name: Id, + pub variant: ModuleImportVariant, +} + +#[derive(Debug, Clone)] +pub enum ModuleImportVariant { + Memory, +} + +#[derive(Debug, Clone)] +pub struct InterfaceFunc { + pub name: Id, + pub params: Vec, + pub results: Vec, +} + +#[derive(Debug, Clone)] +pub struct InterfaceFuncParam { + pub name: Id, + pub type_: DatatypeIdent, +} diff --git a/proposals/filesystem/tools/witx/src/lexer.rs b/proposals/filesystem/tools/witx/src/lexer.rs new file mode 100644 index 000000000..b004acf07 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/lexer.rs @@ -0,0 +1,354 @@ +use crate::Location; +use failure::Fail; +use std::path::{Path, PathBuf}; +use std::str::CharIndices; + +///! The lexer turns a string into a stream of located tokens. +///! The tokens are meant for consumption by the s-expression parser. +///! +///! Comments in source text look like `;; rest of line ...`. +///! Words look like `abcde_` +///! Idents look like `$abcde_` +///! Annotations look like `@abcde_` +///! Quotes look like `"a b cde 123 @#$%^&*() _"` +///! +///! This implementation was heavily influenced by `cranelift-reader` + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum Token<'a> { + LPar, // ( + RPar, // ) + Word(&'a str), // Bare word + Ident(&'a str), // Starts with $ + Annot(&'a str), // Starts with @. short for annotation. + Quote(&'a str), // Found between balanced "". No escaping. +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct LocatedToken<'a> { + pub token: Token<'a>, + pub location: Location, +} + +fn token(token: Token<'_>, location: Location) -> Result, LocatedError> { + Ok(LocatedToken { token, location }) +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy, Fail)] +pub enum LexError { + #[fail(display = "Invalid character '{}'", _0)] + InvalidChar(char), + #[fail(display = "Empty identifier '$'")] + EmptyIdentifier, + #[fail(display = "Empty annotation '@'")] + EmptyAnnotation, + #[fail(display = "Unterminated quote")] + UnterminatedQuote, +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct LocatedError { + pub error: LexError, + pub location: Location, +} + +fn error<'a>(error: LexError, location: Location) -> Result, LocatedError> { + Err(LocatedError { error, location }) +} + +pub struct Lexer<'a> { + source: &'a str, + chars: CharIndices<'a>, + lookahead: Option, + pos: usize, + line_number: usize, + column_start: usize, + tab_compensation: usize, + path: PathBuf, +} + +impl<'a> Lexer<'a> { + pub fn new>(s: &'a str, path: P) -> Lexer<'_> { + let mut lex = Lexer { + source: s, + chars: s.char_indices(), + lookahead: None, + pos: 0, + line_number: 1, + column_start: 0, + tab_compensation: 0, + path: path.as_ref().into(), + }; + lex.next_ch(); + lex + } + + fn next_ch(&mut self) -> Option { + if self.lookahead == Some('\n') { + self.line_number += 1; + self.column_start = self.pos + 1; // Next column starts a fresh line + self.tab_compensation = 0; + } else if self.lookahead == Some('\t') { + self.tab_compensation += 7; // One column for the position of the char itself, add 7 more for a tabwidth of 8 + } + match self.chars.next() { + Some((idx, ch)) => { + self.pos = idx; + self.lookahead = Some(ch); + } + None => { + self.pos = self.source.len(); + self.lookahead = None; + } + } + self.lookahead + } + + fn loc(&self) -> Location { + Location { + path: self.path.clone(), + line: self.line_number, + column: self.pos - self.column_start + self.tab_compensation, + } + } + + fn looking_at(&self, prefix: &str) -> bool { + self.source[self.pos..].starts_with(prefix) + } + + fn scan_char(&mut self, tok: Token<'a>) -> Result, LocatedError> { + assert!(self.lookahead.is_some()); + let loc = self.loc(); + self.next_ch(); + token(tok, loc) + } + + pub fn rest_of_line(&mut self) -> &'a str { + let begin = self.pos; + loop { + match self.next_ch() { + None | Some('\n') => return &self.source[begin..self.pos], + _ => {} + } + } + } + + fn scan_word(&mut self) -> Result, LocatedError> { + let begin = self.pos; + let loc = self.loc(); + assert!(self.lookahead == Some('_') || self.lookahead.unwrap().is_alphabetic()); + loop { + match self.next_ch() { + Some('_') | Some('-') => {} + Some(ch) if ch.is_alphanumeric() => {} + _ => break, + } + } + let text = &self.source[begin..self.pos]; + token(Token::Word(text), loc) + } + + fn scan_ident(&mut self) -> Result, LocatedError> { + let loc = self.loc(); + assert!(self.lookahead == Some('$')); + match self.next_ch() { + Some(ch) if ch.is_alphanumeric() || ch == '_' => {} + _ => Err(LocatedError { + error: LexError::EmptyIdentifier, + location: loc.clone(), + })?, + } + let begin = self.pos; + + loop { + match self.next_ch() { + Some('_') | Some('-') => {} + Some(ch) if ch.is_alphanumeric() => {} + _ => break, + } + } + + let text = &self.source[begin..self.pos]; + token(Token::Ident(text), loc) + } + + fn scan_annotation(&mut self) -> Result, LocatedError> { + let loc = self.loc(); + assert!(self.lookahead == Some('@')); + match self.next_ch() { + Some(ch) if ch.is_alphanumeric() || ch == '_' => {} + _ => Err(LocatedError { + error: LexError::EmptyAnnotation, + location: loc.clone(), + })?, + } + let begin = self.pos; + + loop { + match self.next_ch() { + Some('_') | Some('-') => {} + Some(ch) if ch.is_alphanumeric() => {} + _ => break, + } + } + + let text = &self.source[begin..self.pos]; + token(Token::Annot(text), loc) + } + + fn scan_quote(&mut self) -> Result, LocatedError> { + let begin = self.pos; + let loc = self.loc(); + assert!(self.lookahead == Some('"')); + loop { + match self.next_ch() { + None => Err(LocatedError { + error: LexError::UnterminatedQuote, + location: loc.clone(), + })?, + Some('"') => { + self.next_ch(); + break; + } + _ => {} + } + } + let text = &self.source[(begin + 1)..(self.pos - 1)]; + token(Token::Quote(text), loc) + } + + #[allow(clippy::should_implement_trait)] + pub fn next(&mut self) -> Option, LocatedError>> { + loop { + let loc = self.loc(); + return match self.lookahead { + None => None, + Some(c) => Some(match c { + '(' => self.scan_char(Token::LPar), + ')' => self.scan_char(Token::RPar), + '$' => self.scan_ident(), + '@' => self.scan_annotation(), + ';' => { + if self.looking_at(";;") { + self.rest_of_line(); + continue; + } else { + self.next_ch(); + error(LexError::InvalidChar(';'), loc) + } + } + '"' => self.scan_quote(), + '_' => self.scan_word(), + ch if ch.is_alphabetic() => self.scan_word(), + ch if ch.is_whitespace() => { + self.next_ch(); + continue; + } + _ => { + self.next_ch(); + error(LexError::InvalidChar(c), loc) + } + }), + }; + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use std::path::{Path, PathBuf}; + + fn testlexer(input: &str) -> Lexer { + Lexer::new(input, Path::new("/test")) + } + + fn token( + token: Token<'_>, + line: usize, + column: usize, + ) -> Option, LocatedError>> { + Some(super::token( + token, + Location { + path: PathBuf::from("/test"), + line, + column, + }, + )) + } + + fn error<'a>( + err: LexError, + line: usize, + column: usize, + ) -> Option, LocatedError>> { + Some(super::error( + err, + Location { + path: PathBuf::from("/test"), + line, + column, + }, + )) + } + #[test] + fn words_and_idents() { + let mut lex = testlexer("$gussie is a good $dog"); + // ruler 0 5 10 15 20 + assert_eq!(lex.next(), token(Token::Ident("gussie"), 1, 0)); + assert_eq!(lex.next(), token(Token::Word("is"), 1, 8)); + assert_eq!(lex.next(), token(Token::Word("a"), 1, 11)); + assert_eq!(lex.next(), token(Token::Word("good"), 1, 13)); + assert_eq!(lex.next(), token(Token::Ident("dog"), 1, 18)); + assert_eq!(lex.next(), None); + + let mut lex = + testlexer("$ok $a $_ $ _\nkebab-case\nsnake_case\n$kebab-ident\n$snake_ident"); + assert_eq!(lex.next(), token(Token::Ident("ok"), 1, 0)); + assert_eq!(lex.next(), token(Token::Ident("a"), 1, 4)); + assert_eq!(lex.next(), token(Token::Ident("_"), 1, 7)); + assert_eq!(lex.next(), error(LexError::EmptyIdentifier, 1, 10)); + assert_eq!(lex.next(), token(Token::Word("_"), 1, 12)); + assert_eq!(lex.next(), token(Token::Word("kebab-case"), 2, 0)); + assert_eq!(lex.next(), token(Token::Word("snake_case"), 3, 0)); + assert_eq!(lex.next(), token(Token::Ident("kebab-ident"), 4, 0)); + assert_eq!(lex.next(), token(Token::Ident("snake_ident"), 5, 0)); + assert_eq!(lex.next(), None); + } + + #[test] + fn comments() { + let mut lex = testlexer("the quick ;; brown fox\njumped\n;;over the three\nlazy;;dogs"); + assert_eq!(lex.next(), token(Token::Word("the"), 1, 0)); + assert_eq!(lex.next(), token(Token::Word("quick"), 1, 4)); + assert_eq!(lex.next(), token(Token::Word("jumped"), 2, 0)); + assert_eq!(lex.next(), token(Token::Word("lazy"), 4, 0)); + assert_eq!(lex.next(), None); + + let mut lex = testlexer("line1 ;;\n$sym_2;\n\t\tl3;;;333"); + assert_eq!(lex.next(), token(Token::Word("line1"), 1, 0)); + assert_eq!(lex.next(), token(Token::Ident("sym_2"), 2, 0)); + assert_eq!(lex.next(), error(LexError::InvalidChar(';'), 2, 6)); + assert_eq!(lex.next(), token(Token::Word("l3"), 3, 16)); // Two tabs = 16 columns + assert_eq!(lex.next(), None); + } + + #[test] + fn quotes() { + let mut lex = testlexer("a \"bc\" d"); + assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); + assert_eq!(lex.next(), token(Token::Quote("bc"), 1, 2)); + assert_eq!(lex.next(), token(Token::Word("d"), 1, 7)); + + let mut lex = testlexer("a \"b\nc\" d"); + assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); + assert_eq!(lex.next(), token(Token::Quote("b\nc"), 1, 2)); + assert_eq!(lex.next(), token(Token::Word("d"), 2, 3)); + + let mut lex = testlexer("a \"b"); + assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); + assert_eq!(lex.next(), error(LexError::UnterminatedQuote, 1, 2)); + } +} diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs new file mode 100644 index 000000000..7d5040d00 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -0,0 +1,93 @@ +/// Types describing a validated witx document +mod ast; +/// Lexer text into tokens +mod lexer; +/// Witx syntax parsing from SExprs +mod parser; +/// SExpr parsing from tokens +mod sexpr; +/// Resolve toplevel `use` declarations across files +mod toplevel; +/// Validate declarations into ast +mod validate; + +pub use ast::{ + AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, + Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, Module, + ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, + UnionDatatype, UnionVariant, +}; +pub use lexer::LexError; +pub use parser::{DeclSyntax, ParseError}; +pub use sexpr::SExprParseError; +pub use validate::ValidationError; + +use failure::Fail; +use std::io; +use std::path::{Path, PathBuf}; + +pub fn load>(path: P) -> Result { + use toplevel::parse_witx; + use validate::validate_document; + let parsed_decls = parse_witx(path)?; + validate_document(&parsed_decls).map_err(WitxError::Validation) +} + +/// Location in the source text +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct Location { + pub path: PathBuf, + pub line: usize, + pub column: usize, +} + +#[derive(Debug, Fail)] +pub enum WitxError { + #[fail(display = "{}", _0)] + SExpr(#[cause] SExprParseError), + #[fail(display = "when resolving use declaration for {:?}: {}", _0, _1)] + UseResolution(PathBuf, #[cause] io::Error), + #[fail(display = "{}", _0)] + Parse(#[cause] ParseError), + #[fail(display = "{}", _0)] + Validation(#[cause] ValidationError), +} + +impl WitxError { + pub fn report(&self) -> String { + use WitxError::*; + match self { + SExpr(sexpr) => sexpr.report(), + UseResolution(path, ioerr) => format!("when resolving `use {:?}`: {}", path, ioerr), + Parse(parse) => parse.report(), + Validation(validation) => validation.report(), + } + } +} +impl Location { + pub fn highlight_source(&self) -> String { + let mut msg = format!("in {:?}:\n", self.path); + if let Ok(src_line) = self.source_line() { + msg += &format!( + "{line_num: >5} | {src_line}\n{blank: >5} {caret: >column$}", + line_num = self.line, + src_line = src_line, + blank = " ", + caret = "^", + column = self.column, + ); + } + msg + } + pub fn source_line(&self) -> Result { + use std::fs::File; + use std::io::{BufRead, BufReader}; + let f = BufReader::new(File::open(&self.path)?); + let l = f + .lines() + .skip(self.line - 1) + .next() + .unwrap_or_else(|| Err(io::Error::new(io::ErrorKind::Other, "TODO")))?; + Ok(l) + } +} diff --git a/proposals/filesystem/tools/witx/src/main.rs b/proposals/filesystem/tools/witx/src/main.rs new file mode 100644 index 000000000..c2ad70322 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/main.rs @@ -0,0 +1,38 @@ +use clap::{App, Arg}; +use std::path::Path; +use std::process; +use witx::load; + +pub fn main() { + let app = App::new("witx") + .version(env!("CARGO_PKG_VERSION")) + .about("Validate witx file format") + .arg( + Arg::with_name("input") + .required(true) + .help("path to root of witx document"), + ) + .arg( + Arg::with_name("verbose") + .short("v") + .long("verbose") + .takes_value(false) + .required(false), + ) + .get_matches(); + + match load(Path::new(app.value_of("input").expect("required arg"))) { + Ok(doc) => { + if app.is_present("verbose") { + println!("{:?}", doc) + } + } + Err(e) => { + println!("{}", e.report()); + if app.is_present("verbose") { + println!("{:?}", e); + } + process::exit(1) + } + } +} diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs new file mode 100644 index 000000000..a99df5fa4 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -0,0 +1,583 @@ +use crate::sexpr::SExpr; +use crate::Location; +use failure::Fail; + +///! Parser turns s-expressions into unvalidated syntax constructs. +///! conventions: +///! `Type::starts_parsing(s-expr) -> bool` is for look-ahead: we use +///! this predicate to combine parsers for different `Type`s where both +///! alternatives are accepted. +///! `Type::parse(sexpr: &SExpr) -> Result` takes a single +///! s-expression and parses it into a `Self`. +///! for parsers that take a subset of a vector s-expression, the signature +///! `Type::parse(sexprs: &[SExpr], location: Location) -> Result` +///! has an additional `Location` argument, which should point to the parent SExpr::Vec. +///! This is used for error reporting in case the slice doesn't have the number of elements +///! expected. + +#[derive(Debug, Fail)] +#[fail(display = "{} at {:?}", _0, _1)] +pub struct ParseError { + pub message: String, + pub location: Location, +} + +impl ParseError { + pub fn report(&self) -> String { + format!("{}\n{}", self.location.highlight_source(), self.message) + } +} + +macro_rules! parse_err { + ($loc:expr, $msg:expr) => { + ParseError { message: $msg.to_string(), location: $loc.clone() } + }; + ($loc:expr, $fmt:expr, $( $arg:expr ),+ ) => { + ParseError { message: format!($fmt, $( $arg ),+), location: $loc.clone() } + }; +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct IdentSyntax { + pub name: String, + pub location: Location, +} + +macro_rules! id { + ($s:expr, $loc: expr) => { + IdentSyntax { + name: $s.to_string(), + location: $loc.clone(), + } + }; +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum BuiltinType { + String, + Data, + U8, + U16, + U32, + U64, + S8, + S16, + S32, + S64, + F32, + F64, +} + +impl BuiltinType { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + match sexpr { + SExpr::Word("string", _) + | SExpr::Word("data", _) + | SExpr::Word("u8", _) + | SExpr::Word("u16", _) + | SExpr::Word("u32", _) + | SExpr::Word("u64", _) + | SExpr::Word("s8", _) + | SExpr::Word("s16", _) + | SExpr::Word("s32", _) + | SExpr::Word("s64", _) + | SExpr::Word("f32", _) + | SExpr::Word("f64", _) => true, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + match sexpr { + SExpr::Word("string", _loc) => Ok(BuiltinType::String), + SExpr::Word("data", _loc) => Ok(BuiltinType::Data), + SExpr::Word("u8", _loc) => Ok(BuiltinType::U8), + SExpr::Word("u16", _loc) => Ok(BuiltinType::U16), + SExpr::Word("u32", _loc) => Ok(BuiltinType::U32), + SExpr::Word("u64", _loc) => Ok(BuiltinType::U64), + SExpr::Word("s8", _loc) => Ok(BuiltinType::S8), + SExpr::Word("s16", _loc) => Ok(BuiltinType::S16), + SExpr::Word("s32", _loc) => Ok(BuiltinType::S32), + SExpr::Word("s64", _loc) => Ok(BuiltinType::S64), + SExpr::Word("f32", _loc) => Ok(BuiltinType::F32), + SExpr::Word("f64", _loc) => Ok(BuiltinType::F64), + _ => Err(parse_err!(sexpr.location(), "invalid builtin type")), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum DatatypeIdentSyntax { + Builtin(BuiltinType), + Array(Box), + Pointer(Box), + ConstPointer(Box), + Ident(IdentSyntax), +} + +impl DatatypeIdentSyntax { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + BuiltinType::starts_parsing(sexpr) + || match sexpr { + SExpr::Ident(_, _) => true, + SExpr::Vec(v, _) => match (v.get(0), v.get(1)) { + (Some(SExpr::Word("array", _)), Some(_)) => true, + (Some(SExpr::Annot("witx", _)), Some(SExpr::Word("pointer", _))) => true, + (Some(SExpr::Annot("witx", _)), Some(SExpr::Word("const_pointer", _))) => true, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + if BuiltinType::starts_parsing(sexpr) { + let builtin = BuiltinType::parse(sexpr)?; + Ok(DatatypeIdentSyntax::Builtin(builtin)) + } else { + match sexpr { + SExpr::Ident(i, loc) => Ok(DatatypeIdentSyntax::Ident(id!(i, loc))), + SExpr::Vec(v, loc) => match (v.get(0), v.get(1), v.get(2)) { + (Some(SExpr::Word("array", _)), Some(expr), None) => Ok( + DatatypeIdentSyntax::Array(Box::new(DatatypeIdentSyntax::parse(expr)?)), + ), + ( + Some(SExpr::Annot("witx", _)), + Some(SExpr::Word("pointer", _)), + Some(expr), + ) => Ok(DatatypeIdentSyntax::Pointer(Box::new( + DatatypeIdentSyntax::parse(expr)?, + ))), + ( + Some(SExpr::Annot("witx", _)), + Some(SExpr::Word("const_pointer", _)), + Some(expr), + ) => Ok(DatatypeIdentSyntax::ConstPointer(Box::new( + DatatypeIdentSyntax::parse(expr)?, + ))), + _ => Err(parse_err!(loc, "expected type identifier")), + }, + _ => Err(parse_err!(sexpr.location(), "expected type identifier")), + } + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum TopLevelSyntax { + Decl(DeclSyntax), + Use(IdentSyntax), +} + +impl TopLevelSyntax { + pub fn parse(sexpr: &SExpr) -> Result { + if DeclSyntax::starts_parsing(sexpr) { + let decl = DeclSyntax::parse(sexpr)?; + Ok(TopLevelSyntax::Decl(decl)) + } else { + match sexpr { + SExpr::Vec(v, vec_loc) => match v.get(0) { + Some(SExpr::Word("use", loc)) => match v.get(1) { + Some(SExpr::Quote(u, loc)) => Ok(TopLevelSyntax::Use(id!(u, loc))), + _ => Err(parse_err!(loc, "invalid use declaration")), + }, + _ => Err(parse_err!(vec_loc, "expected top level declaration")), + }, + _ => Err(parse_err!( + sexpr.location(), + "expected top level declaration" + )), + } + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum DeclSyntax { + Typename(TypenameSyntax), + Module(ModuleSyntax), +} + +impl DeclSyntax { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + match sexpr { + SExpr::Vec(v, _) => match v.get(0) { + Some(SExpr::Word("typename", _)) => true, + Some(SExpr::Word("module", _)) => true, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + match sexpr { + SExpr::Vec(v, loc) => match v.get(0) { + Some(SExpr::Word("typename", loc)) => { + Ok(DeclSyntax::Typename(TypenameSyntax::parse(&v[1..], loc)?)) + } + Some(SExpr::Word("module", loc)) => { + Ok(DeclSyntax::Module(ModuleSyntax::parse(&v[1..], loc)?)) + } + _ => Err(parse_err!(loc, "invalid declaration")), + }, + _ => Err(parse_err!(sexpr.location(), "expected vec")), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TypenameSyntax { + pub ident: IdentSyntax, + pub def: TypedefSyntax, +} + +impl TypenameSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + let ident = match sexpr.get(0) { + Some(SExpr::Ident(i, loc)) => id!(i, loc), + Some(s) => Err(parse_err!(s.location(), "expected typename identifier"))?, + None => Err(parse_err!(loc, "expected typename identifier"))?, + }; + let def = match sexpr.get(1) { + Some(expr) => TypedefSyntax::parse(expr)?, + _ => Err(parse_err!(loc, "expected type definition"))?, + }; + Ok(TypenameSyntax { ident, def }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum TypedefSyntax { + Ident(DatatypeIdentSyntax), + Enum(EnumSyntax), + Flags(FlagsSyntax), + Struct(StructSyntax), + Union(UnionSyntax), +} + +impl TypedefSyntax { + pub fn parse(sexpr: &SExpr) -> Result { + if DatatypeIdentSyntax::starts_parsing(sexpr) { + let ident = DatatypeIdentSyntax::parse(sexpr)?; + Ok(TypedefSyntax::Ident(ident)) + } else { + match sexpr { + SExpr::Vec(vs, loc) => match vs.get(0) { + Some(SExpr::Word("enum", loc)) => { + Ok(TypedefSyntax::Enum(EnumSyntax::parse(&vs[1..], loc)?)) + } + Some(SExpr::Word("flags", loc)) => { + Ok(TypedefSyntax::Flags(FlagsSyntax::parse(&vs[1..], loc)?)) + } + Some(SExpr::Word("struct", loc)) => { + Ok(TypedefSyntax::Struct(StructSyntax::parse(&vs[1..], loc)?)) + } + Some(SExpr::Word("union", loc)) => { + Ok(TypedefSyntax::Union(UnionSyntax::parse(&vs[1..], loc)?)) + } + _ => Err(parse_err!( + loc, + "expected type identifier or type definition" + )), + }, + _ => Err(parse_err!( + sexpr.location(), + "expected type identifier or type definition" + )), + } + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct EnumSyntax { + pub repr: BuiltinType, + pub members: Vec, +} + +impl EnumSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + let repr = match sexpr.get(0) { + Some(e) => BuiltinType::parse(e)?, + _ => Err(parse_err!(loc, "no enum repr"))?, + }; + let members = sexpr[1..] + .iter() + .map(|m| match m { + SExpr::Ident(i, loc) => Ok(id!(i, loc)), + s => Err(parse_err!(s.location(), "expected enum member identifier")), + }) + .collect::, ParseError>>()?; + if members.is_empty() { + Err(parse_err!(loc, "expected at least one enum member"))? + } + Ok(EnumSyntax { repr, members }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FlagsSyntax { + pub repr: BuiltinType, + pub flags: Vec, +} + +impl FlagsSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + let repr = BuiltinType::parse( + sexpr + .get(0) + .ok_or_else(|| parse_err!(loc, "expected flag repr type"))?, + )?; + let flags = sexpr[1..] + .iter() + .map(|f| match f { + SExpr::Vec(vs, loc) => match (vs.get(0), vs.get(1)) { + (Some(SExpr::Word("flag", _)), Some(SExpr::Ident(i, loc))) => Ok(id!(i, loc)), + _ => Err(parse_err!(loc, "expected flag specifier")), + }, + s => Err(parse_err!(s.location(), "expected flag specifier")), + }) + .collect::, ParseError>>()?; + Ok(FlagsSyntax { repr, flags }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct StructSyntax { + pub fields: Vec, +} + +impl StructSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + if sexpr.is_empty() { + Err(parse_err!(loc, "expected at least one struct member"))? + } + let fields = sexpr + .iter() + .map(|f| FieldSyntax::parse(f, "field")) + .collect::, ParseError>>()?; + Ok(StructSyntax { fields }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FieldSyntax { + pub name: IdentSyntax, + pub type_: DatatypeIdentSyntax, +} + +impl FieldSyntax { + pub fn starts_parsing(sexpr: &SExpr, constructor: &str) -> bool { + match sexpr { + SExpr::Vec(v, _) => match v.get(0) { + Some(SExpr::Word(c, _)) => *c == constructor, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr, constructor: &str) -> Result { + match sexpr { + SExpr::Vec(v, loc) => match v.get(0) { + Some(SExpr::Word(c, _)) if *c == constructor => { + let name = match v.get(1) { + Some(SExpr::Ident(i, loc)) => id!(i, loc), + _ => Err(parse_err!(loc, "expected {} name identifier", constructor))?, + }; + let type_ = DatatypeIdentSyntax::parse(v.get(2).ok_or_else(|| { + parse_err!(loc, "expected {} type identifier", constructor) + })?)?; + Ok(FieldSyntax { name, type_ }) + } + _ => Err(parse_err!(loc, "expected {}", constructor)), + }, + _ => Err(parse_err!(sexpr.location(), "expected {}", constructor)), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct UnionSyntax { + pub fields: Vec, +} + +impl UnionSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + if sexpr.is_empty() { + Err(parse_err!(loc, "expected at least one union member"))? + } + let fields = sexpr + .iter() + .map(|f| FieldSyntax::parse(f, "field")) + .collect::, ParseError>>()?; + Ok(UnionSyntax { fields }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ModuleSyntax { + pub name: IdentSyntax, + pub decls: Vec, +} + +impl ModuleSyntax { + pub fn parse(sexprs: &[SExpr], loc: &Location) -> Result { + let name = match sexprs.get(0) { + Some(SExpr::Ident(i, loc)) => id!(i, loc), + _ => Err(parse_err!(loc, "expected module name"))?, + }; + let decls = sexprs[1..] + .iter() + .map(|s| ModuleDeclSyntax::parse(s)) + .collect::, _>>()?; + Ok(ModuleSyntax { name, decls }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ModuleDeclSyntax { + Import(ModuleImportSyntax), + Func(InterfaceFuncSyntax), +} + +impl ModuleDeclSyntax { + pub fn parse(sexpr: &SExpr) -> Result { + if ModuleImportSyntax::starts_parsing(sexpr) { + Ok(ModuleDeclSyntax::Import(ModuleImportSyntax::parse(sexpr)?)) + } else if InterfaceFuncSyntax::starts_parsing(sexpr) { + Ok(ModuleDeclSyntax::Func(InterfaceFuncSyntax::parse(sexpr)?)) + } else { + Err(parse_err!(sexpr.location(), "expected import or function")) + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ModuleImportSyntax { + pub name: IdentSyntax, + pub type_: ImportTypeSyntax, +} + +impl ModuleImportSyntax { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + match sexpr { + SExpr::Vec(vs, _) => match vs.get(0) { + Some(SExpr::Word("import", _)) => true, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + match sexpr { + SExpr::Vec(vs, vec_loc) => match (vs.get(0), vs.get(1)) { + (Some(SExpr::Word("import", _)), Some(SExpr::Quote(name, loc))) => { + let name = id!(name, loc); + let type_ = ImportTypeSyntax::parse(&vs[2..], vec_loc)?; + Ok(ModuleImportSyntax { name, type_ }) + } + _ => Err(parse_err!(vec_loc, "expected module import")), + }, + _ => Err(parse_err!(sexpr.location(), "expected module import")), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ImportTypeSyntax { + Memory, +} + +impl ImportTypeSyntax { + pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { + if sexpr.len() > 1 { + Err(parse_err!(loc, "too many elements for an import type"))?; + } + match sexpr.get(0) { + Some(SExpr::Vec(vs, loc)) => match vs.get(0) { + Some(SExpr::Word("memory", _)) => { + if vs.len() == 1 { + Ok(ImportTypeSyntax::Memory) + } else { + Err(parse_err!(loc, "too many elements for memory declaration")) + } + } + _ => Err(parse_err!(loc, "expected import type")), + }, + _ => Err(parse_err!(loc, "expected import type")), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct InterfaceFuncSyntax { + pub export: IdentSyntax, + pub params: Vec, + pub results: Vec, +} + +impl InterfaceFuncSyntax { + pub fn starts_parsing(sexpr: &SExpr) -> bool { + match sexpr { + SExpr::Vec(vs, _) => match (vs.get(0), vs.get(1)) { + (Some(SExpr::Annot("interface", _)), Some(SExpr::Word("func", _))) => true, + _ => false, + }, + _ => false, + } + } + pub fn parse(sexpr: &SExpr) -> Result { + match sexpr { + SExpr::Vec(vs, loc) => match (vs.get(0), vs.get(1)) { + (Some(SExpr::Annot("interface", _)), Some(SExpr::Word("func", _))) => { + let export = match vs.get(2) { + Some(SExpr::Vec(es, loc)) => match (es.get(0), es.get(1)) { + ( + Some(SExpr::Word("export", _)), + Some(SExpr::Quote(name, name_loc)), + ) => { + if es.len() == 2 { + id!(name, name_loc) + } else { + Err(parse_err!( + loc, + "too many elements for export declaration" + ))? + } + } + _ => Err(parse_err!(loc, "expected export declaration"))?, + }, + _ => Err(parse_err!(loc, "expected export declaration"))?, + }; + let mut params = Vec::new(); + let mut results = Vec::new(); + + for sexpr in &vs[3..] { + if FieldSyntax::starts_parsing(sexpr, "param") { + let param = FieldSyntax::parse(sexpr, "param")?; + params.push(param); + } else if FieldSyntax::starts_parsing(sexpr, "result") { + let result = FieldSyntax::parse(sexpr, "result")?; + results.push(result); + } else { + Err(parse_err!( + sexpr.location(), + "expected param or result field" + ))?; + } + } + + Ok(InterfaceFuncSyntax { + export, + params, + results, + }) + } + _ => Err(parse_err!(loc, "expected interface func declaration")), + }, + + _ => Err(parse_err!( + sexpr.location(), + "expected interface func declaration" + )), + } + } +} diff --git a/proposals/filesystem/tools/witx/src/sexpr.rs b/proposals/filesystem/tools/witx/src/sexpr.rs new file mode 100644 index 000000000..6a34cf83b --- /dev/null +++ b/proposals/filesystem/tools/witx/src/sexpr.rs @@ -0,0 +1,236 @@ +pub use crate::lexer::LexError; +use crate::lexer::{Lexer, LocatedError, LocatedToken, Token}; +use crate::Location; +use failure::Fail; +use std::path::{Path, PathBuf}; + +///! The s-expression parser turns a string into a stream of SExprs. +///! It uses the `Lexer` under the hood. +///! This implementation was heavily influenced by `cranelift-reader` + +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum SExpr<'a> { + Vec(Vec>, Location), + Word(&'a str, Location), + Ident(&'a str, Location), + Quote(&'a str, Location), + /// Short for Annotation + Annot(&'a str, Location), +} + +impl<'a> SExpr<'a> { + pub fn location(&self) -> Location { + match self { + SExpr::Vec(_, loc) => loc.clone(), + SExpr::Word(_, loc) => loc.clone(), + SExpr::Ident(_, loc) => loc.clone(), + SExpr::Quote(_, loc) => loc.clone(), + SExpr::Annot(_, loc) => loc.clone(), + } + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Fail)] +pub enum SExprParseError { + #[fail(display = "Lexical error: {}", _0)] + Lex(LexError, Location), + #[fail(display = "Unexpected ')'")] + UnexpectedCloseParen(Location), + #[fail(display = "Unexpected end of input in {:?}", _0)] + UnexpectedEof(PathBuf), +} + +impl SExprParseError { + pub fn report(&self) -> String { + use SExprParseError::*; + match self { + Lex(lex_err, loc) => format!("{}\n{}", loc.highlight_source(), lex_err), + UnexpectedCloseParen(loc) => format!("{}\n{}", loc.highlight_source(), self), + UnexpectedEof(_path) => format!("{}", self), + } + } +} + +pub struct SExprParser<'a> { + lex: Lexer<'a>, + lookahead: Option>, + location: Location, +} + +impl<'a> SExprParser<'a> { + pub fn new>(text: &'a str, path: P) -> SExprParser<'_> { + SExprParser { + lex: Lexer::new(text, path.as_ref()), + lookahead: None, + location: Location { + path: path.as_ref().into(), + line: 0, + column: 0, + }, + } + } + fn consume(&mut self) -> Token<'a> { + self.lookahead.take().expect("no token to consume") + } + fn token(&mut self) -> Result>, SExprParseError> { + while self.lookahead == None { + match self.lex.next() { + Some(Ok(LocatedToken { token, location })) => { + self.location = location; + self.lookahead = Some(token) + } + Some(Err(LocatedError { error, location })) => { + self.location = location.clone(); + Err(SExprParseError::Lex(error, location))?; + } + None => break, + } + } + Ok(self.lookahead) + } + + pub fn match_sexpr(&mut self) -> Result, SExprParseError> { + let location = self.location.clone(); + match self.token()? { + Some(Token::LPar) => { + self.consume(); + let mut members = Vec::new(); + loop { + match self.token()? { + Some(Token::RPar) => { + self.consume(); + break; + } + _ => { + members.push(self.match_sexpr()?); + } + } + } + Ok(SExpr::Vec(members, location)) + } + Some(Token::Word(word)) => { + self.consume(); + Ok(SExpr::Word(word, location)) + } + Some(Token::Ident(id)) => { + self.consume(); + Ok(SExpr::Ident(id, location)) + } + Some(Token::Annot(id)) => { + self.consume(); + Ok(SExpr::Annot(id, location)) + } + Some(Token::Quote(q)) => { + self.consume(); + Ok(SExpr::Quote(q, location)) + } + Some(Token::RPar) => Err(SExprParseError::UnexpectedCloseParen(location)), + None => Err(SExprParseError::UnexpectedEof(self.location.path.clone())), + } + } + + pub fn match_sexprs(&mut self) -> Result>, SExprParseError> { + let mut sexprs = Vec::new(); + while self.token()?.is_some() { + sexprs.push(self.match_sexpr()?); + } + Ok(sexprs) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::path::PathBuf; + + fn loc(line: usize, col: usize) -> Location { + Location { + path: PathBuf::from("/test"), + line: line, + column: col, + } + } + + fn testparser(input: &str) -> SExprParser { + SExprParser::new(input, Path::new("/test")) + } + + #[test] + fn empty() { + let mut parser = testparser(""); + assert_eq!(parser.match_sexprs().expect("valid parse"), Vec::new()); + let mut parser = testparser(" ;; just a comment\n;;another"); + assert_eq!(parser.match_sexprs().expect("valid parse"), Vec::new()); + } + + #[test] + fn atoms() { + let mut parser = testparser("hello\n$world\n\"a quotation\""); + assert_eq!( + parser.match_sexprs().expect("valid parse"), + vec![ + SExpr::Word("hello", loc(1, 0)), + SExpr::Ident("world", loc(2, 0)), + SExpr::Quote("a quotation", loc(3, 0)), + ] + ); + } + + #[test] + fn lists() { + let mut parser = testparser("()"); + assert_eq!( + parser.match_sexprs().expect("valid parse"), + vec![SExpr::Vec(vec![], loc(1, 0))] + ); + + let mut parser = testparser("(hello\n$world\n\"a quotation\")"); + assert_eq!( + parser.match_sexprs().expect("valid parse"), + vec![SExpr::Vec( + vec![ + SExpr::Word("hello", loc(1, 1)), + SExpr::Ident("world", loc(2, 0)), + SExpr::Quote("a quotation", loc(3, 0)), + ], + loc(1, 0) + )] + ); + + let mut parser = testparser("((($deep)))"); + assert_eq!( + parser.match_sexprs().expect("valid parse"), + vec![SExpr::Vec( + vec![SExpr::Vec( + vec![SExpr::Vec(vec![SExpr::Ident("deep", loc(1, 3))], loc(1, 2))], + loc(1, 1) + )], + loc(1, 0) + )] + ); + } + + #[test] + fn errors() { + let mut parser = testparser("("); + assert_eq!( + parser.match_sexprs().err().expect("dies"), + SExprParseError::UnexpectedEof(PathBuf::from("/test")) + ); + let mut parser = testparser(")"); + assert_eq!( + parser.match_sexprs().err().expect("dies"), + SExprParseError::UnexpectedCloseParen(loc(1, 0)) + ); + let mut parser = testparser("())"); + assert_eq!( + parser.match_sexprs().err().expect("dies"), + SExprParseError::UnexpectedCloseParen(loc(1, 2)) + ); + let mut parser = testparser("$ ;; should be a lex error"); + assert_eq!( + parser.match_sexprs().err().expect("dies"), + SExprParseError::Lex(LexError::EmptyIdentifier, loc(1, 0),), + ); + } +} diff --git a/proposals/filesystem/tools/witx/src/toplevel.rs b/proposals/filesystem/tools/witx/src/toplevel.rs new file mode 100644 index 000000000..cf3a5e377 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/toplevel.rs @@ -0,0 +1,243 @@ +use crate::parser::{DeclSyntax, ParseError, TopLevelSyntax}; +use crate::sexpr::SExprParser; +use crate::WitxError; +use std::collections::HashSet; +use std::fs; +use std::path::{Path, PathBuf}; + +trait WitxIo { + fn fgets(&self, path: &Path) -> Result; + fn canonicalize(&self, path: &Path) -> Result; +} + +struct Filesystem; + +impl WitxIo for Filesystem { + fn fgets(&self, path: &Path) -> Result { + fs::read_to_string(path).map_err(|e| WitxError::UseResolution(path.to_path_buf(), e)) + } + fn canonicalize(&self, path: &Path) -> Result { + path.canonicalize() + .map_err(|e| WitxError::UseResolution(path.to_path_buf(), e)) + } +} + +pub fn parse_witx>(i: P) -> Result, WitxError> { + parse_witx_with(i, &Filesystem) +} + +fn parse_witx_with>( + i: P, + witxio: &dyn WitxIo, +) -> Result, WitxError> { + let input_path = witxio.canonicalize(&i.as_ref())?; + + let input = witxio.fgets(&input_path)?; + + let toplevel = parse_toplevel(&input, &input_path)?; + let mut resolved = HashSet::new(); + resolved.insert(input_path.clone()); + let search_path = input_path.parent().unwrap_or(Path::new(".")); + resolve_uses(toplevel, &search_path, &mut resolved, witxio) +} + +fn parse_toplevel(source_text: &str, file_path: &Path) -> Result, WitxError> { + let mut sexpr_parser = SExprParser::new(source_text, file_path); + let sexprs = sexpr_parser.match_sexprs().map_err(WitxError::SExpr)?; + let top_levels = sexprs + .iter() + .map(|s| TopLevelSyntax::parse(s)) + .collect::, ParseError>>() + .map_err(WitxError::Parse)?; + Ok(top_levels) +} + +fn resolve_uses( + toplevel: Vec, + search_path: &Path, + used: &mut HashSet, + witxio: &dyn WitxIo, +) -> Result, WitxError> { + let mut decls = Vec::new(); + + for t in toplevel { + match t { + TopLevelSyntax::Decl(d) => decls.push(d), + TopLevelSyntax::Use(u) => { + let abs_path = witxio.canonicalize(&search_path.join(u.name))?; + // Include the decls from a use declaration only once + // in a given toplevel. Same idea as #pragma once. + if !used.contains(&abs_path) { + used.insert(abs_path.clone()); + + let source_text = witxio.fgets(&abs_path)?; + let inner_toplevels = parse_toplevel(&source_text, &abs_path)?; + + let inner_decls = resolve_uses(inner_toplevels, search_path, used, witxio)?; + decls.extend(inner_decls) + } + } + } + } + + Ok(decls) +} + +#[cfg(test)] +mod test { + use super::*; + use crate::parser::*; + use crate::Location; + use std::collections::HashMap; + + struct MockFs { + map: HashMap<&'static str, &'static str>, + } + + impl MockFs { + pub fn new(strings: Vec<(&'static str, &'static str)>) -> Self { + MockFs { + map: strings.into_iter().collect(), + } + } + } + + impl WitxIo for MockFs { + fn fgets(&self, path: &Path) -> Result { + if let Some(entry) = self.map.get(path.to_str().unwrap()) { + Ok(entry.to_string()) + } else { + use std::io::{Error, ErrorKind}; + Err(WitxError::UseResolution( + path.to_path_buf(), + Error::new(ErrorKind::Other, "mock fs: file not found"), + )) + } + } + fn canonicalize(&self, path: &Path) -> Result { + Ok(PathBuf::from(path)) + } + } + + #[test] + fn empty() { + assert_eq!( + parse_witx_with(&Path::new("/a"), &MockFs::new(vec![("/a", ";; empty")])) + .expect("parse"), + Vec::new(), + ); + } + + #[test] + fn one_use() { + assert_eq!( + parse_witx_with( + &Path::new("/a"), + &MockFs::new(vec![("/a", "(use \"b\")"), ("/b", ";; empty")]) + ) + .expect("parse"), + Vec::new(), + ); + } + + #[test] + fn multi_use() { + assert_eq!( + parse_witx_with( + &Path::new("/a"), + &MockFs::new(vec![ + ("/a", "(use \"b\")"), + ("/b", "(use \"c\")\n(typename $b_float f64)"), + ("/c", "(typename $c_int u32)") + ]) + ) + .expect("parse"), + vec![ + DeclSyntax::Typename(TypenameSyntax { + ident: IdentSyntax { + name: "c_int".to_owned(), + location: Location { + path: PathBuf::from("/c"), + line: 1, + column: 10, + } + }, + def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::U32)) + }), + DeclSyntax::Typename(TypenameSyntax { + ident: IdentSyntax { + name: "b_float".to_owned(), + location: Location { + path: PathBuf::from("/b"), + line: 2, + column: 10, + } + }, + def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::F64)) + }) + ], + ); + } + + #[test] + fn diamond_dependency() { + assert_eq!( + parse_witx_with( + &Path::new("/a"), + &MockFs::new(vec![ + ("/a", "(use \"b\")\n(use \"c\")"), + ("/b", "(use \"d\")"), + ("/c", "(use \"d\")"), + ("/d", "(typename $d_char u8)") + ]) + ) + .expect("parse"), + vec![DeclSyntax::Typename(TypenameSyntax { + ident: IdentSyntax { + name: "d_char".to_owned(), + location: Location { + path: PathBuf::from("/d"), + line: 1, + column: 10, + } + }, + def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::U8)) + })], + ); + } + + #[test] + fn use_not_found() { + match parse_witx_with(&Path::new("/a"), &MockFs::new(vec![("/a", "(use \"b\")")])) + .err() + .unwrap() + { + WitxError::UseResolution(path, _error) => assert_eq!(path, PathBuf::from("/b")), + e => panic!("wrong error: {:?}", e), + } + } + + #[test] + fn use_invalid() { + match parse_witx_with( + &Path::new("/a"), + &MockFs::new(vec![("/a", "(use bbbbbbb)")]), + ) + .err() + .unwrap() + { + WitxError::Parse(e) => { + assert_eq!(e.message, "invalid use declaration"); + assert_eq!( + e.location, + Location { + path: PathBuf::from("/a"), + line: 1, + column: 1 + } + ); + } + e => panic!("wrong error: {:?}", e), + } + } +} diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs new file mode 100644 index 000000000..7041fca98 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -0,0 +1,390 @@ +use crate::{ + parser::{ + DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, IdentSyntax, ImportTypeSyntax, + ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + }, + AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, + Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, Location, + Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, + StructMember, UnionDatatype, UnionVariant, +}; +use failure::Fail; +use std::collections::HashMap; +use std::rc::Rc; + +#[derive(Debug, Fail)] +pub enum ValidationError { + #[fail(display = "Unknown name `{}`", name)] + UnknownName { name: String, location: Location }, + #[fail(display = "Redefinition of name `{}`", name)] + NameAlreadyExists { + name: String, + at_location: Location, + previous_location: Location, + }, + #[fail( + display = "Wrong kind of name `{}`: expected {}, got {}", + name, expected, got + )] + WrongKindName { + name: String, + location: Location, + expected: &'static str, + got: &'static str, + }, + #[fail(display = "Recursive definition of name `{}`", name)] + Recursive { name: String, location: Location }, + #[fail(display = "Invalid representation `{:?}`", repr)] + InvalidRepr { + repr: BuiltinType, + location: Location, + }, +} + +impl ValidationError { + pub fn report(&self) -> String { + use ValidationError::*; + match self { + UnknownName { location, .. } + | WrongKindName { location, .. } + | Recursive { location, .. } + | InvalidRepr { location, .. } => format!("{}\n{}", location.highlight_source(), &self), + NameAlreadyExists { + at_location, + previous_location, + .. + } => format!( + "{}\n{}\nOriginally defined at:\n{}", + at_location.highlight_source(), + &self, + previous_location.highlight_source(), + ), + } + } +} + +pub fn validate_document(decls: &[DeclSyntax]) -> Result { + let mut validator = DocValidation::new(); + let mut definitions = Vec::new(); + for d in decls { + definitions.push(validator.validate_decl(&d)?); + } + + Ok(Document { + entries: validator.entries, + definitions, + }) +} + +struct IdentValidation { + names: HashMap, +} + +impl IdentValidation { + fn new() -> Self { + Self { + names: HashMap::new(), + } + } + fn introduce(&mut self, syntax: &IdentSyntax) -> Result { + if let Some(introduced) = self.names.get(&syntax.name) { + Err(ValidationError::NameAlreadyExists { + name: syntax.name.clone(), + at_location: syntax.location.clone(), + previous_location: introduced.clone(), + }) + } else { + self.names + .insert(syntax.name.clone(), syntax.location.clone()); + Ok(Id::new(&syntax.name)) + } + } + + fn get(&self, syntax: &IdentSyntax) -> Result { + if self.names.get(&syntax.name).is_some() { + Ok(Id::new(&syntax.name)) + } else { + Err(ValidationError::UnknownName { + name: syntax.name.clone(), + location: syntax.location.clone(), + }) + } + } +} + +struct DocValidation { + scope: IdentValidation, + pub entries: HashMap, +} + +impl DocValidation { + fn new() -> Self { + Self { + scope: IdentValidation::new(), + entries: HashMap::new(), + } + } + + fn validate_decl(&mut self, decl: &DeclSyntax) -> Result { + match decl { + DeclSyntax::Typename(decl) => { + let name = self.scope.introduce(&decl.ident)?; + let variant = + match &decl.def { + TypedefSyntax::Ident(syntax) => DatatypeVariant::Alias(AliasDatatype { + name: name.clone(), + to: self.validate_datatype_ident(&syntax)?, + }), + TypedefSyntax::Enum(syntax) => DatatypeVariant::Enum(self.validate_enum( + &name, + &syntax, + &decl.ident.location, + )?), + TypedefSyntax::Flags(syntax) => DatatypeVariant::Flags( + self.validate_flags(&name, &syntax, &decl.ident.location)?, + ), + TypedefSyntax::Struct(syntax) => DatatypeVariant::Struct( + self.validate_struct(&name, &syntax, &decl.ident.location)?, + ), + TypedefSyntax::Union(syntax) => DatatypeVariant::Union( + self.validate_union(&name, &syntax, &decl.ident.location)?, + ), + }; + let rc_datatype = Rc::new(Datatype { + name: name.clone(), + variant, + }); + self.entries + .insert(name, Entry::Datatype(Rc::downgrade(&rc_datatype))); + Ok(Definition::Datatype(rc_datatype)) + } + DeclSyntax::Module(syntax) => { + let name = self.scope.introduce(&syntax.name)?; + let mut module_validator = ModuleValidation::new(self); + let definitions = syntax + .decls + .iter() + .map(|d| module_validator.validate_decl(&d)) + .collect::, _>>()?; + + let rc_module = Rc::new(Module { + name: name.clone(), + definitions, + entries: module_validator.entries, + }); + self.entries + .insert(name, Entry::Module(Rc::downgrade(&rc_module))); + Ok(Definition::Module(rc_module)) + } + } + } + + fn validate_datatype_ident( + &self, + syntax: &DatatypeIdentSyntax, + ) -> Result { + match syntax { + DatatypeIdentSyntax::Builtin(b) => Ok(DatatypeIdent::Builtin(*b)), + DatatypeIdentSyntax::Array(a) => Ok(DatatypeIdent::Array(Box::new( + self.validate_datatype_ident(&a)?, + ))), + DatatypeIdentSyntax::Pointer(a) => Ok(DatatypeIdent::Pointer(Box::new( + self.validate_datatype_ident(&a)?, + ))), + DatatypeIdentSyntax::ConstPointer(a) => Ok(DatatypeIdent::ConstPointer(Box::new( + self.validate_datatype_ident(&a)?, + ))), + DatatypeIdentSyntax::Ident(i) => { + let id = self.scope.get(i)?; + match self.entries.get(&id) { + Some(Entry::Datatype(weak_d)) => Ok(DatatypeIdent::Ident( + weak_d.upgrade().expect("weak backref to defined type"), + )), + Some(e) => Err(ValidationError::WrongKindName { + name: i.name.clone(), + location: i.location.clone(), + expected: "datatype", + got: e.kind(), + }), + None => Err(ValidationError::Recursive { + name: i.name.clone(), + location: i.location.clone(), + }), + } + } + } + } + + fn validate_enum( + &self, + name: &Id, + syntax: &EnumSyntax, + location: &Location, + ) -> Result { + let mut enum_scope = IdentValidation::new(); + let repr = validate_int_repr(&syntax.repr, location)?; + let variants = syntax + .members + .iter() + .map(|i| enum_scope.introduce(i)) + .collect::, _>>()?; + + Ok(EnumDatatype { + name: name.clone(), + repr, + variants, + }) + } + + fn validate_flags( + &self, + name: &Id, + syntax: &FlagsSyntax, + location: &Location, + ) -> Result { + let mut flags_scope = IdentValidation::new(); + let repr = validate_int_repr(&syntax.repr, location)?; + let flags = syntax + .flags + .iter() + .map(|i| flags_scope.introduce(i)) + .collect::, _>>()?; + + Ok(FlagsDatatype { + name: name.clone(), + repr, + flags, + }) + } + + fn validate_struct( + &self, + name: &Id, + syntax: &StructSyntax, + _location: &Location, + ) -> Result { + let mut member_scope = IdentValidation::new(); + let members = syntax + .fields + .iter() + .map(|f| { + Ok(StructMember { + name: member_scope.introduce(&f.name)?, + type_: self.validate_datatype_ident(&f.type_)?, + }) + }) + .collect::, _>>()?; + + Ok(StructDatatype { + name: name.clone(), + members, + }) + } + + fn validate_union( + &self, + name: &Id, + syntax: &UnionSyntax, + _location: &Location, + ) -> Result { + let mut variant_scope = IdentValidation::new(); + let variants = syntax + .fields + .iter() + .map(|f| { + Ok(UnionVariant { + name: variant_scope.introduce(&f.name)?, + type_: self.validate_datatype_ident(&f.type_)?, + }) + }) + .collect::, _>>()?; + + Ok(UnionDatatype { + name: name.clone(), + variants, + }) + } +} + +fn validate_int_repr(type_: &BuiltinType, location: &Location) -> Result { + match type_ { + BuiltinType::U8 => Ok(IntRepr::I8), + BuiltinType::U16 => Ok(IntRepr::I16), + BuiltinType::U32 => Ok(IntRepr::I32), + BuiltinType::U64 => Ok(IntRepr::I64), + _ => Err(ValidationError::InvalidRepr { + repr: type_.clone(), + location: location.clone(), + }), + } +} + +struct ModuleValidation<'a> { + doc: &'a DocValidation, + scope: IdentValidation, + pub entries: HashMap, +} + +impl<'a> ModuleValidation<'a> { + fn new(doc: &'a DocValidation) -> Self { + Self { + doc, + scope: IdentValidation::new(), + entries: HashMap::new(), + } + } + + fn validate_decl( + &mut self, + decl: &ModuleDeclSyntax, + ) -> Result { + match decl { + ModuleDeclSyntax::Import(syntax) => { + let name = self.scope.introduce(&syntax.name)?; + let variant = match syntax.type_ { + ImportTypeSyntax::Memory => ModuleImportVariant::Memory, + }; + let rc_import = Rc::new(ModuleImport { + name: name.clone(), + variant, + }); + self.entries + .insert(name, ModuleEntry::Import(Rc::downgrade(&rc_import))); + Ok(ModuleDefinition::Import(rc_import)) + } + ModuleDeclSyntax::Func(syntax) => { + let name = self.scope.introduce(&syntax.export)?; + let mut argnames = IdentValidation::new(); + let params = syntax + .params + .iter() + .map(|f| { + Ok(InterfaceFuncParam { + name: argnames.introduce(&f.name)?, + type_: self.doc.validate_datatype_ident(&f.type_)?, + }) + }) + .collect::, _>>()?; + let results = syntax + .results + .iter() + .map(|f| { + Ok(InterfaceFuncParam { + name: argnames.introduce(&f.name)?, + type_: self.doc.validate_datatype_ident(&f.type_)?, + }) + }) + .collect::, _>>()?; + + let rc_func = Rc::new(InterfaceFunc { + name: name.clone(), + params, + results, + }); + self.entries + .insert(name, ModuleEntry::Func(Rc::downgrade(&rc_func))); + Ok(ModuleDefinition::Func(rc_func)) + } + } + } +} diff --git a/proposals/filesystem/tools/witx/tests/wasi_unstable.rs b/proposals/filesystem/tools/witx/tests/wasi_unstable.rs new file mode 100644 index 000000000..e9188db67 --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/wasi_unstable.rs @@ -0,0 +1,7 @@ +use std::path::Path; +use witx_frontend; + +#[test] +fn validate_wasi_unstable() { + witx_frontend::load(Path::new("../../design/wasi_unstable/wasi_unstable.witx")).unwrap(); +} From d32ed60c6172da0a74a3749acefbce3d292d8e3a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 18 Sep 2019 12:51:09 -0700 Subject: [PATCH 0166/1772] Create a phased structure for API development (#88) * Create a structure for phased development. This PR takes the `witx` concept from #74 and creates a directory structure around it for enabling phased development of new APIs and changes to existing APIs. See the README.md changes for details. * Apply the validation fix from #90 to the new copies. --- proposals/clocks/README.md | 2 + proposals/clocks/phases/README.md | 53 + .../ephemeral/docs/wasi_ephemeral_preview.md} | 16 +- .../ephemeral/witx}/typenames.witx | 2 +- .../witx/wasi_ephemeral_preview.witx | 526 ++++ .../phases/old/docs/wasi_unstable_preview0.md | 2319 +++++++++++++++++ .../clocks/phases/old/witx/typenames.witx | 752 ++++++ .../old/witx}/wasi_unstable.witx | 6 +- .../unstable/docs/wasi_unstable_preview0.md | 2319 +++++++++++++++++ .../phases/unstable/witx/typenames.witx | 752 ++++++ .../unstable/witx/wasi_unstable_preview0.witx | 526 ++++ 11 files changed, 7265 insertions(+), 8 deletions(-) create mode 100644 proposals/clocks/phases/README.md rename proposals/clocks/{design/WASI-core.md => phases/ephemeral/docs/wasi_ephemeral_preview.md} (99%) rename proposals/clocks/{design/wasi_unstable => phases/ephemeral/witx}/typenames.witx (99%) create mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx create mode 100644 proposals/clocks/phases/old/docs/wasi_unstable_preview0.md create mode 100644 proposals/clocks/phases/old/witx/typenames.witx rename proposals/clocks/{design/wasi_unstable => phases/old/witx}/wasi_unstable.witx (98%) create mode 100644 proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md create mode 100644 proposals/clocks/phases/unstable/witx/typenames.witx create mode 100644 proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 7fc421229..31bb340e1 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -22,3 +22,5 @@ discussions. Schedules and agendas for video conference and in-person meetings are posted [here](meetings/README.md). + +API specification proposals are [here](phases/README.md). diff --git a/proposals/clocks/phases/README.md b/proposals/clocks/phases/README.md new file mode 100644 index 000000000..00d49afef --- /dev/null +++ b/proposals/clocks/phases/README.md @@ -0,0 +1,53 @@ +# WASI development process + +## WASI uses a 3-phase process: + +- [`ephemeral`](ephemeral): The development staging area. New API + proposals API-changing fixes to existing APIs should be submitted + as Pull Requests making changes to this directory. This directory + provides no API stability or versioning. APIs in this directory use + API module names starting with `wasi_ephemeral_`. + +- [`unstable`](unstable): Usable APIs. APIs in `ephemeral` will be + occasionally snapshotted and promoted into `unstable`, with approval + from the Subgroup, considering the overall suitability of the APIs + themselves, their documentation, test coverage, and availability of + polyfills when appropriate. Once merged, the API modules will be + considered stable, though they may be superseded by newer versions. + Proposals to promote specific APIs should be submitted as Pull Requests + that: + - Move any superseded files out of `unstable` into `old`. + - Optionally add polyfills for superseded APIs using `unstable` APIs. + - Move all files supporting the APIs out of `ephemeral into `unstable`. + - Rename the API modules from `wasi_ephemeral_` to `wasi_unstable_` + and append a version number. + + Pull Requests may also add additional tests, documentation, or + polyfills for existing `unstable` APIs. + +- [`old`](old): When APIs in `current` spec are replaced by new + versions, the old API modules are moved to the `old` directory. When + possible, `old` APIs may be accompanied by polyfill modules which + implement their API in terms of newer versions of the API. + +## Rationale + +### Relationship to the CG's phases + +When WASI becomes more mature, such that we have an established base +and we're adding incremental functionality to it, we may want to adopt +a process like [the CG's phases]. However, right now, everything in +WASI is undergoing changes, so we have a greater need to iterate with +flexibility. + +### Relationship to standards + +WASI should eventually become a standard at the level of WebAssembly +itself. Right now, it needs a lot of work before it's ready. The +`unstable` tree is meant to serve a practical purpose for people who +want to work with APIs today, with the understanding that everything +is still evolving. It's not meant as a replacement for proper +standardization, which will happen once the overall API is more +mature. + +[the CG's phases]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md diff --git a/proposals/clocks/design/WASI-core.md b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md similarity index 99% rename from proposals/clocks/design/WASI-core.md rename to proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md index c4b256ad3..9db4a382e 100644 --- a/proposals/clocks/design/WASI-core.md +++ b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -34,13 +34,12 @@ This file is automatically generated. Do not edit. Source: https://github.com/NuxiNL/cloudabi --> -# WASI Core API +# The WASI Preview API -This is the API-level documentation for WASI Core. The function names +This is the API-level documentation for WASI Preview. The function names are prefixed with "\_\_wasi\_" to reflect how they are spelled in flat-namespace contexts, however at the wasm module level, they are -unprefixed, because they're inside a module namespace (currently -"wasi\_unstable"). +unprefixed, because they're inside a module namespace. Functions that start with `__wasi_fd_` operate on file descriptors, while functions that start with `__wasi_path_` operate on filesystem @@ -48,16 +47,21 @@ paths, which are relative to directory file descriptors. Much inspiration and content here is derived from [CloudABI] and [POSIX], though there are also several differences from CloudABI and POSIX. For -example, WASI Core has no concept of processes in the traditional Unix +example, WASI Preview has no concept of processes in the traditional Unix sense. While wasm linear memories have some of the aspects of processes, and it's possible to *emulate* the full semantics of processes on top of them, this can sometimes be unnatural and inefficient. The goal for -WASI Core is to be a WebAssembly-native API that exposes APIs that fit +WASI Preview is to be a WebAssembly-native API that exposes APIs that fit well into the underlying WebAssembly platform, rather than to directly emulate other platforms. This is also a work in progress, and the API here is still evolving. +Historical note: this API was originally named "WASI Core", and used the +API module name "wasi\_unstable". We've since sought to deemphasize the +"Core" name, as the goal is to split this API up into independent +modules so that embedders need not implement all of it. + [CloudABI]: https://github.com/NuxiNL/cloudabi [POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ diff --git a/proposals/clocks/design/wasi_unstable/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx similarity index 99% rename from proposals/clocks/design/wasi_unstable/typenames.witx rename to proposals/clocks/phases/ephemeral/witx/typenames.witx index 046ed0bf6..e04a188d9 100644 --- a/proposals/clocks/design/wasi_unstable/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -1,4 +1,4 @@ -;; Type names used by the wasi_unstable module type. +;; Type names used by low-level WASI interfaces. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). ;; diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx new file mode 100644 index 000000000..4f31fe510 --- /dev/null +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -0,0 +1,526 @@ +;; WASI Preview. This is an evolution of the API that WASI initially +;; launched with. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_preview + ;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;; Read command-line argument data. + ;; The size of the array should match that returned by `wasi_args_sizes_get()` + (@interface func (export "args_get") + (param $argv (@witx pointer (@witx pointer u8))) + (param $argv_buf (@witx pointer u8)) + (result $error $errno_t) + ) + ;; Return command-line argument data sizes. + (@interface func (export "args_sizes_get") + (result $error $errno_t) + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Read environment variable data. + ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + (@interface func (export "environ_get") + (param $environ (@witx pointer (@witx pointer u8))) + (param $environ_buf (@witx pointer u8)) + (result $error $errno_t) + ) + ;; Return command-line argument data sizes. + (@interface func (export "environ_sizes_get") + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Return the resolution of a clock. + ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;; Note: This is similar to `clock_getres` in POSIX. + (@interface func (export "clock_res_get") + (result $error $errno_t) + ;; The clock for which to return the resolution. + (param $clock_id $clockid_t) + ;; The resolution of the clock. + (result $resolution $timestamp_t) + ) + ;; Return the time value of a clock. + ;; Note: This is similar to `clock_gettime` in POSIX. + (@interface func (export "clock_time_get") + ;; The clock for which to return the time. + (param $clock_id $clockid_t) + ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp_t) + (result $error $errno_t) + ;; The time value of the clock. + (result $time $timestamp_t) + ) + + ;; Provide file advisory information on a file descriptor. + ;; Note: This is similar to `posix_fadvise` in POSIX. + (@interface func (export "fd_advise") + (param $fd $fd_t) + (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. + (param $len $filesize_t) ;; The length of the region to which the advisory applies. + (param $advice $advice_t) ;; The advice. + (result $error $errno_t) + ) + + ;; Force the allocation of space in a file. + ;; Note: This is similar to `posix_fallocate` in POSIX. + (@interface func (export "fd_allocate") + (param $fd $fd_t) + ;; The offset at which to start the allocation. + (param $offset $filesize_t) + ;; The length of the area that is allocated. + (param $len $filesize_t) + (result $error $errno_t) + ) + + ;; Close a file descriptor. + ;; Note: This is similar to `close` in POSIX. + (@interface func (export "fd_close") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Synchronize the data of a file to disk. + ;; Note: This is similar to `fdatasync` in POSIX. + (@interface func (export "fd_datasync") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Get the attributes of a file descriptor. + ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (@interface func (export "fd_fdstat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the file descriptor's attributes are stored. + (result $stat $fdstat_t) + ) + + ;; Adjust the flags associated with a file descriptor. + ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (@interface func (export "fd_fdstat_set_flags") + (param $fd $fd_t) + ;; The desired values of the file descriptor flags. + (param $flags $fdflags_t) + (result $error $errno_t) + ) + + ;; Adjust the rights associated with a file descriptor. + ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (@interface func (export "fd_fdstat_set_rights") + (param $fd $fd_t) + ;; The desired rights of the file descriptor. + (param $fs_rights_base $rights_t) + (param $fs_rights_inheriting $rights_t) + (result $error $errno_t) + ) + + ;; Return the attributes of an open file. + (@interface func (export "fd_filestat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $fs_rights_base $rights_t) + ) + + ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;; Note: This is similar to `ftruncate` in POSIX. + (@interface func (export "fd_filestat_set_size") + (param $fd $fd_t) + ;; The desired file size. + (param $st_size $filesize_t) + (result $error $errno_t) + ) + + ;; Adjust the timestamps of an open file or directory. + ;; Note: This is similar to `futimens` in POSIX. + (@interface func (export "fd_filestat_set_times") + (param $fd $fd_t) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `preadv` in POSIX. + (@interface func (export "fd_pread") + (param $fd $fd_t) + ;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to read. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the description is stored. + (result $buf $prestat_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_dir_name") + (param $fd $fd_t) + ;; A buffer into which to write the preopened directory name. + (param $path (@witx pointer u8)) + (param $path_len $size_t) + (result $error $errno_t) + ) + + ;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `pwritev` in POSIX. + (@interface func (export "fd_pwrite") + (param $fd $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_t_array) + ;; The offset within the file at which to write. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Read from a file descriptor. + ;; Note: This is similar to `readv` in POSIX. + (@interface func (export "fd_read") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Read directory entries from a directory. + ;; When successful, the contents of the output buffer consist of a sequence of + ;; directory entries. Each directory entry consists of a dirent_t object, + ;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;; entry. + ;; + ;; This function fills the output buffer as much as possible, potentially + ;; truncating the last directory entry. This allows the caller to grow its + ;; read buffer size in case it's too small to fit a single large directory + ;; entry, or skip the oversized directory entry. + (@interface func (export "fd_readdir") + (param $fd $fd_t) + ;; The buffer where directory entries are stored + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + ;; The location within the directory to start reading + (param $cookie $dircookie_t) + (result $error $errno_t) + ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size_t) + ) + + ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; + ;; Due to the strong focus on thread safety, this environment does not provide + ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;; file descriptor with the same number could be allocated by a different + ;; thread at the same time. + ;; + ;; This function provides a way to atomically renumber file descriptors, which + ;; would disappear if `dup2()` were to be removed entirely. + (@interface func (export "fd_renumber") + (param $fd $fd_t) + ;; The file descriptor to overwrite. + (param $to $fd_t) + (result $error $errno_t) + ) + + ;; Move the offset of a file descriptor. + ;; Note: This is similar to `lseek` in POSIX. + (@interface func (export "fd_seek") + (param $fd $fd_t) + ;; The number of bytes to move. + (param $offset $filedelta_t) + ;; The base from which the offset is relative. + (param $whence $whence_t) + (result $error $errno_t) + ;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize_t) + ) + + ;; Synchronize the data and metadata of a file to disk. + ;; Note: This is similar to `fsync` in POSIX. + (@interface func (export "fd_sync") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Return the current offset of a file descriptor. + ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (@interface func (export "fd_tell") + (param $fd $fd_t) + (result $error $errno_t) + ;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize_t) + ) + + ;; Write to a file descriptor. + ;; Note: This is similar to `writev` in POSIX. + (@interface func (export "fd_write") + (param $fd $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_t_array) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Create a directory. + ;; Note: This is similar to `mkdirat` in POSIX. + (@interface func (export "path_create_directory") + (param $fd $fd_t) + ;; The path at which to create the directory. + (param $path string) + (result $error $errno_t) + ) + + ;; Return the attributes of a file or directory. + ;; Note: This is similar to `stat` in POSIX. + (@interface func (export "path_filestat_get") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $buf $filestat_t) + ) + + ;; Adjust the timestamps of a file or directory. + ;; Note: This is similar to `utimensat` in POSIX. + (@interface func (export "path_filestat_set_times") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to operate on. + (param $path string) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Create a hard link. + ;; Note: This is similar to `linkat` in POSIX. + (@interface func (export "path_link") + (param $old_fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags_t) + ;; The source path from which to link. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd_t) + ;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Open a file or directory. + ;; + ;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;; file descriptor not currently open; it is randomized to prevent + ;; applications from depending on making assumptions about indexes, since this + ;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;; guaranteed to be less than 2**31. + ;; + ;; Note: This is similar to `openat` in POSIX. + (@interface func (export "path_open") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags_t) + ;; The relative path of the file or directory to open, relative to the + ;; `dirfd` directory. + (param $path string) + ;; The method by which to open the file. + (param $o_flags $oflags_t) + ;; The initial rights of the newly created file descriptor. The + ;; implementation is allowed to return a file descriptor with fewer rights + ;; than specified, if and only if those rights do not apply to the type of + ;; file being opened. + ;; + ;; The base rights are rights that will apply to operations using the file + ;; descriptor itself, while the inheriting rights are rights that apply to + ;; file descriptors derived from it. + (param $fs_rights_base $rights_t) + (param $fs_rights_inherting $rights_t) + (result $error $errno_t) + ;; The file descriptor of the file that has been opened. + (result $opened_fd $fd_t) + ) + + ;; Read the contents of a symbolic link. + ;; Note: This is similar to `readlinkat` in POSIX. + (@interface func (export "path_readlink") + (param $fd $fd_t) + ;; The path of the symbolic link from which to read. + (param $path string) + ;; The buffer to which to write the contents of the symbolic link. + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + (result $error $errno_t) + ;; The number of bytes placed in the buffer. + (result $bufused $size_t) + ) + + ;; Remove a directory. + ;; Return `ENOTEMPTY` if the directory is not empty. + ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (@interface func (export "path_remove_directory") + (param $fd $fd_t) + ;; The path to a directory to remove. + (param $path string) + (result $error $errno_t) + ) + + ;; Rename a file or directory. + ;; Note: This is similar to `renameat` in POSIX. + (@interface func (export "path_rename") + (param $fd $fd_t) + ;; The source path of the file or directory to rename. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd_t) + ;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Create a symbolic link. + ;; Note: This is similar to `symlinkat` in POSIX. + (@interface func (export "path_symlink") + (param $fd $fd_t) + ;; The contents of the symbolic link. + (param $old_path string) + ;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno_t) + ) + + + ;; Unlink a file. + ;; Return `EISDIR` if the path refers to a directory. + ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (@interface func (export "path_unlink_file") + (param $fd $fd_t) + ;; The path to a file to unlink. + (param $path string) + (result $error $errno_t) + ) + + ;; Concurrently poll for the occurrence of a set of events. + (@interface func (export "poll_oneoff") + ;; The events to which to subscribe. + (param $in (@witx const_pointer $subscription_t)) + ;; The events that have occurred. + (param $out (@witx pointer $event_t)) + ;; Both the number of subscriptions and events. + (param $nsubscriptions $size_t) + (result $error $errno_t) + ;; The number of events stored. + (result $nevents $size_t) + ) + + ;; Terminate the process normally. An exit code of 0 indicates successful + ;; termination of the program. The meanings of other values is dependent on + ;; the environment. + (@interface func (export "proc_exit") + ;; The exit code returned by the process. + (param $rval $exitcode_t) + ) + + ;; Send a signal to the process of the calling thread. + ;; Note: This is similar to `raise` in POSIX. + (@interface func (export "proc_raise") + ;; The signal condition to trigger. + (param $sig $signal_t) + (result $error $errno_t) + ) + + ;; Temporarily yield execution of the calling thread. + ;; Note: This is similar to `sched_yield` in POSIX. + (@interface func (export "proc_sched_yield") + (result $error $errno_t) + ) + + ;; Write high-quality random data into a buffer. + ;; This function blocks when the implementation is unable to immediately + ;; provide sufficient high-quality random data. + ;; This function may execute slowly, so when large mounts of random data are + ;; required, it's advisable to use this function to seed a pseudo-random + ;; number generator, rather than to provide the random data directly. + (@interface func (export "random_get") + ;; The buffer to fill with random data. + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + (result $error $errno_t) + ) + + ;; Receive a message from a socket. + ;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;; the data into multiple buffers in the manner of `readv`. + (@interface func (export "sock_recv") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_t_array) + ;; Message flags. + (param $ri_flags $riflags_t) + (result $error $errno_t) + ;; Number of bytes stored in ri_data. + (result $ro_datalen $size_t) + ;; Message flags. + (result $ro_flags $roflags_t) + ) + + ;; Send a message on a socket. + ;; Note: This is similar to `send` in POSIX, though it also supports writing + ;; the data from multiple buffers in the manner of `writev`. + (@interface func (export "sock_send") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_t_array) + ;; Message flags. + (param $si_flags $siflags_t) + (result $error $errno_t) + ;; Number of bytes transmitted. + (result $so_datalen $size_t) + ) + + ;; Shut down socket send and receive channels. + ;; Note: This is similar to `shutdown` in POSIX. + (@interface func (export "sock_shutdown") + (param $fd $fd_t) + ;; Which channels on the socket to shut down. + (param $how $sdflags_t) + (result $error $errno_t) + ) +) diff --git a/proposals/clocks/phases/old/docs/wasi_unstable_preview0.md b/proposals/clocks/phases/old/docs/wasi_unstable_preview0.md new file mode 100644 index 000000000..9db4a382e --- /dev/null +++ b/proposals/clocks/phases/old/docs/wasi_unstable_preview0.md @@ -0,0 +1,2319 @@ + + +# The WASI Preview API + +This is the API-level documentation for WASI Preview. The function names +are prefixed with "\_\_wasi\_" to reflect how they are spelled in +flat-namespace contexts, however at the wasm module level, they are +unprefixed, because they're inside a module namespace. + +Functions that start with `__wasi_fd_` operate on file descriptors, +while functions that start with `__wasi_path_` operate on filesystem +paths, which are relative to directory file descriptors. + +Much inspiration and content here is derived from [CloudABI] and [POSIX], +though there are also several differences from CloudABI and POSIX. For +example, WASI Preview has no concept of processes in the traditional Unix +sense. While wasm linear memories have some of the aspects of processes, +and it's possible to *emulate* the full semantics of processes on top of +them, this can sometimes be unnatural and inefficient. The goal for +WASI Preview is to be a WebAssembly-native API that exposes APIs that fit +well into the underlying WebAssembly platform, rather than to directly +emulate other platforms. + +This is also a work in progress, and the API here is still evolving. + +Historical note: this API was originally named "WASI Core", and used the +API module name "wasi\_unstable". We've since sought to deemphasize the +"Core" name, as the goal is to split this API up into independent +modules so that embedders need not implement all of it. + +[CloudABI]: https://github.com/NuxiNL/cloudabi +[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ + +## System calls + +- [`__wasi_args_get()`](#args_get) +- [`__wasi_args_sizes_get()`](#args_sizes_get) +- [`__wasi_clock_res_get()`](#clock_res_get) +- [`__wasi_clock_time_get()`](#clock_time_get) +- [`__wasi_environ_get()`](#environ_get) +- [`__wasi_environ_sizes_get()`](#environ_sizes_get) +- [`__wasi_fd_advise()`](#fd_advise) +- [`__wasi_fd_allocate()`](#fd_allocate) +- [`__wasi_fd_close()`](#fd_close) +- [`__wasi_fd_datasync()`](#fd_datasync) +- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) +- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) +- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) +- [`__wasi_fd_filestat_get()`](#fd_filestat_get) +- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) +- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) +- [`__wasi_fd_pread()`](#fd_pread) +- [`__wasi_fd_prestat_get()`](#fd_prestat_get) +- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) +- [`__wasi_fd_pwrite()`](#fd_pwrite) +- [`__wasi_fd_read()`](#fd_read) +- [`__wasi_fd_readdir()`](#fd_readdir) +- [`__wasi_fd_renumber()`](#fd_renumber) +- [`__wasi_fd_seek()`](#fd_seek) +- [`__wasi_fd_sync()`](#fd_sync) +- [`__wasi_fd_tell()`](#fd_tell) +- [`__wasi_fd_write()`](#fd_write) +- [`__wasi_path_create_directory()`](#path_create_directory) +- [`__wasi_path_filestat_get()`](#path_filestat_get) +- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) +- [`__wasi_path_link()`](#path_link) +- [`__wasi_path_open()`](#path_open) +- [`__wasi_path_readlink()`](#path_readlink) +- [`__wasi_path_remove_directory()`](#path_remove_directory) +- [`__wasi_path_rename()`](#path_rename) +- [`__wasi_path_symlink()`](#path_symlink) +- [`__wasi_path_unlink_file()`](#path_unlink_file) +- [`__wasi_poll_oneoff()`](#poll_oneoff) +- [`__wasi_proc_exit()`](#proc_exit) +- [`__wasi_proc_raise()`](#proc_raise) +- [`__wasi_random_get()`](#random_get) +- [`__wasi_sched_yield()`](#sched_yield) +- [`__wasi_sock_recv()`](#sock_recv) +- [`__wasi_sock_send()`](#sock_send) +- [`__wasi_sock_shutdown()`](#sock_shutdown) + +###
`__wasi_args_get()` + +Read command-line argument data. + +The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + +Inputs: + +- char \*\*argv + + A pointer to a buffer to write the argument pointers. + +- char \*argv\_buf + + A pointer to a buffer to write the argument string data. + +### `__wasi_args_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*argc + + The number of arguments. + +- size\_t \*argv\_buf\_size + + The size of the argument string data. + +### `__wasi_clock_res_get()` + +Return the resolution of a clock. + +Implementations are required to provide a non-zero value for supported clocks. +For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). + +Note: This is similar to `clock_getres` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the resolution. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) resolution + + The resolution of the clock. + +### `__wasi_clock_time_get()` + +Return the time value of a clock. + +Note: This is similar to `clock_gettime` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the time. + +- [\_\_wasi\_timestamp\_t](#timestamp) precision + + The maximum lag (exclusive) that the returned + time value may have, compared to its actual + value. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) time + + The time value of the clock. + +### `__wasi_environ_get()` + +Read environment variable data. + +The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + +Inputs: + +- char \*\*environ + + A pointer to a buffer to write the environment variable pointers. + +- char \*environ\_buf + + A pointer to a buffer to write the environment variable string data. + +### `__wasi_environ_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*environ\_count + + The number of environment variables. + +- size\_t \*environ\_buf\_size + + The size of the environment variable string data. + +### `__wasi_fd_advise()` + +Provide file advisory information on a file descriptor. + +Note: This is similar to `posix_fadvise` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file for which to provide file advisory information. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file to which the advisory applies. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the region to which the advisory applies. + +- [\_\_wasi\_advice\_t](#advice) advice + + The advice. + +### `__wasi_fd_allocate()` + +Force the allocation of space in a file. + +Note: This is similar to `posix_fallocate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file in which to allocate space. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset at which to start the allocation. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the area that is allocated. + +### `__wasi_fd_close()` + +Close a file descriptor. + +Note: This is similar to `close` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to close. + +### `__wasi_fd_datasync()` + +Synchronize the data of a file to disk. + +Note: This is similar to `fdatasync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file to synchronize to disk. + +### `__wasi_fd_fdstat_get()` + +Get the attributes of a file descriptor. + +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well +as additional fields. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_fdstat\_t](#fdstat) \*buf + + The buffer where the file descriptor's attributes are stored. + +### `__wasi_fd_fdstat_set_flags()` + +Adjust the flags associated with a file descriptor. + +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_fdflags\_t](#fdflags) flags + + The desired values of the file descriptor + flags. + +### `__wasi_fd_fdstat_set_rights()` + +Adjust the rights associated with a file descriptor. + +This can only be used to remove rights, and returns +[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt +to add rights. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The desired rights of the file descriptor. + +### `__wasi_fd_filestat_get()` + +Return the attributes of an open file. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_fd_filestat_set_size()` + +Adjust the size of an open file. If this increases the file's size, the extra +bytes are filled with zeros. + +Note: This is similar to `ftruncate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + A file descriptor for the file to adjust. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + The desired file size. + +### `__wasi_fd_filestat_set_times()` + +Adjust the timestamps of an open file or directory. + +Note: This is similar to `futimens` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_fd_pread()` + +Read from a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `preadv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors in which to store data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to read. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_prestat_get()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- [\_\_wasi\_prestat\_t](#prestat) \*buf + + The buffer where the description is stored. + +### `__wasi_fd_prestat_dir_name()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- const char \*path and size\_t path\_len + + A buffer into which to write the preopened directory name. + +### `__wasi_fd_pwrite()` + +Write to a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `pwritev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to write. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_fd_read()` + +Read from a file descriptor. + +Note: This is similar to `readv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors to which to store data. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_readdir()` + +Read directory entries from a directory. + +When successful, the contents of the output buffer consist of +a sequence of directory entries. Each directory entry consists +of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes +holding the name of the directory entry. + +This function fills the output buffer as much as possible, +potentially truncating the last directory entry. This allows +the caller to grow its read buffer size in case it's too small +to fit a single large directory entry, or skip the oversized +directory entry. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The directory from which to read the directory + entries. + +- void \*buf and size\_t buf\_len + + The buffer where directory entries are stored. + +- [\_\_wasi\_dircookie\_t](#dircookie) cookie + + The location within the directory to start + reading. + +Outputs: + +- size\_t bufused + + The number of bytes stored in the read buffer. + If less than the size of the read buffer, the + end of the directory has been reached. + +### `__wasi_fd_renumber()` + +Atomically replace a file descriptor by renumbering another +file descriptor. + +Due to the strong focus on thread safety, this environment +does not provide a mechanism to duplicate or renumber a file +descriptor to an arbitrary number, like dup2(). This would be +prone to race conditions, as an actual file descriptor with the +same number could be allocated by a different thread at the same +time. + +This function provides a way to atomically renumber file +descriptors, which would disappear if dup2() were to be +removed entirely. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) from + + The file descriptor to renumber. + +- [\_\_wasi\_fd\_t](#fd) to + + The file descriptor to overwrite. + +### `__wasi_fd_seek()` + +Move the offset of a file descriptor. + +Note: This is similar to `lseek` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_filedelta\_t](#filedelta) offset + + The number of bytes to move. + +- [\_\_wasi\_whence\_t](#whence) whence + + The base from which the offset is relative. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) newoffset + + The new offset of the file descriptor, + relative to the start of the file. + +### `__wasi_fd_sync()` + +Synchronize the data and metadata of a file to disk. + +Note: This is similar to `fsync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file containing the data + and metadata to synchronize to disk. + +### `__wasi_fd_tell()` + +Return the current offset of a file descriptor. + +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The current offset of the file descriptor, relative to the start of the file. + +### `__wasi_fd_write()` + +Write to a file descriptor. + +Note: This is similar to `writev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_path_create_directory()` + +Create a directory. + +Note: This is similar to `mkdirat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path at which to create the directory. + +### `__wasi_path_filestat_get()` + +Return the attributes of a file or directory. + +Note: This is similar to `stat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_path_filestat_set_times()` + +Adjust the timestamps of a file or directory. + +Note: This is similar to `utimensat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_path_link()` + +Create a hard link. + +Note: This is similar to `linkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags + + Flags determining the method of how the path is resolved. + +- const char \*old\_path and size\_t old\_path\_len + + The source path from which to link. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the hard link. + +### `__wasi_path_open()` + +Open a file or directory. + +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since +this is error-prone in multi-threaded contexts. The returned file +descriptor is guaranteed to be less than 231. + +Note: This is similar to `openat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) dirfd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The relative path of the file or directory to open, relative to + the [`dirfd`](#path_open.dirfd) directory. + +- [\_\_wasi\_oflags\_t](#oflags) o_flags + + The method by which to open the file. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The initial rights of the newly created file descriptor. The + implementation is allowed to return a file descriptor with fewer + rights than specified, if and only if those rights do not apply + to the type of file being opened. + + The *base* rights are rights that will apply to operations using + the file descriptor itself, while the *inheriting* rights are + rights that apply to file descriptors derived from it. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + The initial flags of the file descriptor. + +Outputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file that has been + opened. + +### `__wasi_path_readlink()` + +Read the contents of a symbolic link. + +Note: This is similar to `readlinkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path of the symbolic link from which to read. + +- char \*buf and size\_t buf\_len + + The buffer to which to write the contents of the symbolic link. + +Outputs: + +- size\_t bufused + + The number of bytes placed in the buffer. + +### `__wasi_path_remove_directory()` + +Remove a directory. + +Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. + +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a directory to remove. + +### `__wasi_path_rename()` + +Rename a file or directory. + +Note: This is similar to `renameat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- const char \*old\_path and size\_t old\_path\_len + + The source path of the file or directory to rename. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path to which to rename the file or directory. + +### `__wasi_path_symlink()` + +Create a symbolic link. + +Note: This is similar to `symlinkat` in POSIX. + +Inputs: + +- const char \*old\_path and size\_t old_path\_len + + The contents of the symbolic link. + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the symbolic link. + +### `__wasi_path_unlink_file()` + +Unlink a file. + +Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. + +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a file to unlink. + +### `__wasi_poll_oneoff()` + +Concurrently poll for the occurrence of a set of events. + +Inputs: + +- const [\_\_wasi\_subscription\_t](#subscription) \*in + + The events to which to subscribe. + +- [\_\_wasi\_event\_t](#event) \*out + + The events that have occurred. + +- size\_t nsubscriptions + + Both the number of subscriptions and events. + +Outputs: + +- size\_t nevents + + The number of events stored. + +### `__wasi_proc_exit()` + +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +Note: This is similar to `_Exit` in POSIX. + +Inputs: + +- [\_\_wasi\_exitcode\_t](#exitcode) rval + + The exit code returned by the process. + +Does not return. + +### `__wasi_proc_raise()` + +Send a signal to the process of the calling thread. + +Note: This is similar to `raise` in POSIX. + +Inputs: + +- [\_\_wasi\_signal\_t](#signal) sig + + The signal condition to trigger. + +### `__wasi_random_get()` + +Write high-quality random data into a buffer. + +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. + +This function may execute slowly, so when large mounts of random +data are required, it's advisable to use this function to seed a +pseudo-random number generator, rather than to provide the +random data directly. + +Inputs: + +- void \*buf and size\_t buf\_len + + The buffer to fill with random data. + +### `__wasi_sched_yield()` + +Temporarily yield execution of the calling thread. + +Note: This is similar to `sched_yield` in POSIX. + +### `__wasi_sock_recv()` + +Receive a message from a socket. + +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to receive data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len + + List of scatter/gather vectors to which to store data. + +- [\_\_wasi\_riflags\_t](#riflags) ri\_flags + + Message flags. + +Outputs: + +- size\_t ro\_datalen + + Number of bytes stored in [`ri_data`](#sock_recv.ri_data). + +- [\_\_wasi\_roflags\_t](#roflags) ro\_flags + + Message flags. + +### `__wasi_sock_send()` + +Send a message on a socket. + +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to send data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len + + List of scatter/gather vectors to which to retrieve data + +- [\_\_wasi\_siflags\_t](#siflags) si\_flags + + Message flags. + +Outputs: + +- size\_t so\_datalen + + Number of bytes transmitted. + +### `__wasi_sock_shutdown()` + +Shut down socket send and receive channels. + +Note: This is similar to `shutdown` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to shutdown channels. + +- [\_\_wasi\_sdflags\_t](#sdflags) how + + Which channels on the socket to shut down. + +## Types + +### `__wasi_advice_t` (`uint8_t`) + +File or memory access pattern advisory information. + +Used by [`__wasi_fd_advise()`](#fd_advise). + +Possible values: + +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + +- **`__WASI_ADVICE_NORMAL`** + + The application has no advice to give on its behavior + with respect to the specified data. + +- **`__WASI_ADVICE_RANDOM`** + + The application expects to access the specified data + in a random order. + +- **`__WASI_ADVICE_SEQUENTIAL`** + + The application expects to access the specified data + sequentially from lower offsets to higher offsets. + +- **`__WASI_ADVICE_WILLNEED`** + + The application expects to access the specified data + in the near future. + +### `__wasi_ciovec_t` (`struct`) + +A region of memory for scatter/gather writes. + +Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). + +Members: + +- const void \*buf and size\_t buf\_len + + The address and length of the buffer to be written. + +### `__wasi_clockid_t` (`uint32_t`) + +Identifiers for clocks. + +Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). + +Possible values: + +- **`__WASI_CLOCK_MONOTONIC`** + + The store-wide monotonic clock, which is defined as a + clock measuring real time, whose value cannot be + adjusted and which cannot have negative clock jumps. + + The epoch of this clock is undefined. The absolute + time value of this clock therefore has no meaning. + +- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** + + The CPU-time clock associated with the current + process. + +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + +- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** + + The CPU-time clock associated with the current thread. + +### `__wasi_device_t` (`uint64_t`) + +Identifier for a device containing a file system. Can be used +in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or +directory in the filesystem. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_dircookie_t` (`uint64_t`) + +A reference to the offset of a directory entry. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). + +Special values: + +- **`__WASI_DIRCOOKIE_START`** + + Permanent reference to the first directory entry + within a directory. + +### `__wasi_dirent_t` (`struct`) + +A directory entry. + +Members: + +- [\_\_wasi\_dircookie\_t](#dircookie) d\_next + + The offset of the next directory entry stored in this + directory. + +- [\_\_wasi\_inode\_t](#inode) d\_ino + + The serial number of the file referred to by this + directory entry. + +- uint32\_t d\_namlen + + The length of the name of the directory entry. + +- [\_\_wasi\_filetype\_t](#filetype) d\_type + + The type of the file referred to by this directory + entry. + +### `__wasi_errno_t` (`uint16_t`) + +Error codes returned by functions. + +Not all of these error codes are returned by the functions +provided by this API; some are used in higher-level library layers, +and others are provided merely for alignment with POSIX. + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_ESUCCESS`** + + No error occurred. System call completed successfully. + +- **`__WASI_E2BIG`** + + Argument list too long. + +- **`__WASI_EACCES`** + + Permission denied. + +- **`__WASI_EADDRINUSE`** + + Address in use. + +- **`__WASI_EADDRNOTAVAIL`** + + Address not available. + +- **`__WASI_EAFNOSUPPORT`** + + Address family not supported. + +- **`__WASI_EAGAIN`** + + Resource unavailable, or operation would block. + +- **`__WASI_EALREADY`** + + Connection already in progress. + +- **`__WASI_EBADF`** + + Bad file descriptor. + +- **`__WASI_EBADMSG`** + + Bad message. + +- **`__WASI_EBUSY`** + + Device or resource busy. + +- **`__WASI_ECANCELED`** + + Operation canceled. + +- **`__WASI_ECHILD`** + + No child processes. + +- **`__WASI_ECONNABORTED`** + + Connection aborted. + +- **`__WASI_ECONNREFUSED`** + + Connection refused. + +- **`__WASI_ECONNRESET`** + + Connection reset. + +- **`__WASI_EDEADLK`** + + Resource deadlock would occur. + +- **`__WASI_EDESTADDRREQ`** + + Destination address required. + +- **`__WASI_EDOM`** + + Mathematics argument out of domain of function. + +- **`__WASI_EDQUOT`** + + Reserved. + +- **`__WASI_EEXIST`** + + File exists. + +- **`__WASI_EFAULT`** + + Bad address. + +- **`__WASI_EFBIG`** + + File too large. + +- **`__WASI_EHOSTUNREACH`** + + Host is unreachable. + +- **`__WASI_EIDRM`** + + Identifier removed. + +- **`__WASI_EILSEQ`** + + Illegal byte sequence. + +- **`__WASI_EINPROGRESS`** + + Operation in progress. + +- **`__WASI_EINTR`** + + Interrupted function. + +- **`__WASI_EINVAL`** + + Invalid argument. + +- **`__WASI_EIO`** + + I/O error. + +- **`__WASI_EISCONN`** + + Socket is connected. + +- **`__WASI_EISDIR`** + + Is a directory. + +- **`__WASI_ELOOP`** + + Too many levels of symbolic links. + +- **`__WASI_EMFILE`** + + File descriptor value too large. + +- **`__WASI_EMLINK`** + + Too many links. + +- **`__WASI_EMSGSIZE`** + + Message too large. + +- **`__WASI_EMULTIHOP`** + + Reserved. + +- **`__WASI_ENAMETOOLONG`** + + Filename too long. + +- **`__WASI_ENETDOWN`** + + Network is down. + +- **`__WASI_ENETRESET`** + + Connection aborted by network. + +- **`__WASI_ENETUNREACH`** + + Network unreachable. + +- **`__WASI_ENFILE`** + + Too many files open in system. + +- **`__WASI_ENOBUFS`** + + No buffer space available. + +- **`__WASI_ENODEV`** + + No such device. + +- **`__WASI_ENOENT`** + + No such file or directory. + +- **`__WASI_ENOEXEC`** + + Executable file format error. + +- **`__WASI_ENOLCK`** + + No locks available. + +- **`__WASI_ENOLINK`** + + Reserved. + +- **`__WASI_ENOMEM`** + + Not enough space. + +- **`__WASI_ENOMSG`** + + No message of the desired type. + +- **`__WASI_ENOPROTOOPT`** + + Protocol not available. + +- **`__WASI_ENOSPC`** + + No space left on device. + +- **`__WASI_ENOSYS`** + + Function not supported. + +- **`__WASI_ENOTCONN`** + + The socket is not connected. + +- **`__WASI_ENOTDIR`** + + Not a directory or a symbolic link to a directory. + +- **`__WASI_ENOTEMPTY`** + + Directory not empty. + +- **`__WASI_ENOTRECOVERABLE`** + + State not recoverable. + +- **`__WASI_ENOTSOCK`** + + Not a socket. + +- **`__WASI_ENOTSUP`** + + Not supported, or operation not supported on socket. + +- **`__WASI_ENOTTY`** + + Inappropriate I/O control operation. + +- **`__WASI_ENXIO`** + + No such device or address. + +- **`__WASI_EOVERFLOW`** + + Value too large to be stored in data type. + +- **`__WASI_EOWNERDEAD`** + + Previous owner died. + +- **`__WASI_EPERM`** + + Operation not permitted. + +- **`__WASI_EPIPE`** + + Broken pipe. + +- **`__WASI_EPROTO`** + + Protocol error. + +- **`__WASI_EPROTONOSUPPORT`** + + Protocol not supported. + +- **`__WASI_EPROTOTYPE`** + + Protocol wrong type for socket. + +- **`__WASI_ERANGE`** + + Result too large. + +- **`__WASI_EROFS`** + + Read-only file system. + +- **`__WASI_ESPIPE`** + + Invalid seek. + +- **`__WASI_ESRCH`** + + No such process. + +- **`__WASI_ESTALE`** + + Reserved. + +- **`__WASI_ETIMEDOUT`** + + Connection timed out. + +- **`__WASI_ETXTBSY`** + + Text file busy. + +- **`__WASI_EXDEV`** + + Cross-device link. + +- **`__WASI_ENOTCAPABLE`** + + Extension: Capabilities insufficient. + +### `__wasi_event_t` (`struct`) + +An event that occurred. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that got attached to + [`__wasi_subscription_t::userdata`](#subscription.userdata). + +- [\_\_wasi\_errno\_t](#errno) error + + If non-zero, an error that occurred while processing + the subscription request. + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event that occurred. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_filesize\_t](#filesize) nbytes + + The number of bytes available for reading or writing. + + - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags + + The state of the file descriptor. + +### `__wasi_eventrwflags_t` (`uint16_t` bitfield) + +The state of the file descriptor subscribed to with +[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_EVENT_FD_READWRITE_HANGUP`** + + The peer of this socket has closed or disconnected. + +### `__wasi_eventtype_t` (`uint8_t`) + +Type of a subscription to an event or its occurrence. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_EVENTTYPE_CLOCK`** + + The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) + has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +- **`__WASI_EVENTTYPE_FD_READ`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + data available for reading. This event always triggers + for regular files. + +- **`__WASI_EVENTTYPE_FD_WRITE`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + capacity available for writing. This event always + triggers for regular files. + +### `__wasi_exitcode_t` (`uint32_t`) + +Exit code generated by a process when exiting. + +Used by [`__wasi_proc_exit()`](#proc_exit). + +### `__wasi_fd_t` (`uint32_t`) + +A file descriptor number. + +Used by many functions in this API. + +As in POSIX, three file descriptor numbers are provided to instances +on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, +and `STDERR_FILENO`). + +Other than these, WASI implementations are not required to allocate +new file descriptors in ascending order. + +### `__wasi_fdflags_t` (`uint16_t` bitfield) + +File descriptor flags. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_FDFLAG_APPEND`** + + Append mode: Data written to the file is always + appended to the file's end. + +- **`__WASI_FDFLAG_DSYNC`** + + Write according to synchronized I/O data integrity + completion. Only the data stored in the file is + synchronized. + +- **`__WASI_FDFLAG_NONBLOCK`** + + Non-blocking mode. + +- **`__WASI_FDFLAG_RSYNC`** + + Synchronized read I/O operations. + +- **`__WASI_FDFLAG_SYNC`** + + Write according to synchronized I/O file integrity completion. + In addition to synchronizing the data stored in the file, the + implementation may also synchronously update the file's metadata. + +### `__wasi_fdstat_t` (`struct`) + +File descriptor attributes. + +Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). + +Members: + +- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype + + File type. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + File descriptor flags. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base + + Rights that apply to this file descriptor. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + Maximum set of rights that may be installed on new + file descriptors that are created through this file + descriptor, e.g., through [`__wasi_path_open()`](#path_open). + +### `__wasi_filedelta_t` (`int64_t`) + +Relative offset within a file. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +### `__wasi_filesize_t` (`uint64_t`) + +Non-negative file size or length of a region within a file. + +Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +### `__wasi_filestat_t` (`struct`) + +File attributes. + +Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). + +Members: + +- [\_\_wasi\_device\_t](#device) st\_dev + + Device ID of device containing the file. + +- [\_\_wasi\_inode\_t](#inode) st\_ino + + File serial number. + +- [\_\_wasi\_filetype\_t](#filetype) st\_filetype + + File type. + +- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink + + Number of hard links to the file. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + For regular files, the file size in bytes. For + symbolic links, the length in bytes of the pathname + contained in the symbolic link. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + Last data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + Last data modification timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim + + Last file status change timestamp. + +### `__wasi_filetype_t` (`uint8_t`) + +The type of a file descriptor or file. + +Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). + +Possible values: + +- **`__WASI_FILETYPE_UNKNOWN`** + + The type of the file descriptor or file is unknown or + is different from any of the other types specified. + +- **`__WASI_FILETYPE_BLOCK_DEVICE`** + + The file descriptor or file refers to a block device + inode. + +- **`__WASI_FILETYPE_CHARACTER_DEVICE`** + + The file descriptor or file refers to a character + device inode. + +- **`__WASI_FILETYPE_DIRECTORY`** + + The file descriptor or file refers to a directory + inode. + +- **`__WASI_FILETYPE_REGULAR_FILE`** + + The file descriptor or file refers to a regular file + inode. + +- **`__WASI_FILETYPE_SOCKET_DGRAM`** + + The file descriptor or file refers to a datagram + socket. + +- **`__WASI_FILETYPE_SOCKET_STREAM`** + + The file descriptor or file refers to a byte-stream + socket. + +- **`__WASI_FILETYPE_SYMBOLIC_LINK`** + + The file refers to a symbolic link inode. + +### `__wasi_fstflags_t` (`uint16_t` bitfield) + +Which file time attributes to adjust. + +Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +Possible values: + +- **`__WASI_FILESTAT_SET_ATIM`** + + Adjust the last data access timestamp to the value + stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). + +- **`__WASI_FILESTAT_SET_ATIM_NOW`** + + Adjust the last data access timestamp to the time + of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +- **`__WASI_FILESTAT_SET_MTIM`** + + Adjust the last data modification timestamp to the + value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). + +- **`__WASI_FILESTAT_SET_MTIM_NOW`** + + Adjust the last data modification timestamp to the + time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +### `__wasi_inode_t` (`uint64_t`) + +File serial number that is unique within its file system. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). + +### `__wasi_iovec_t` (`struct`) + +A region of memory for scatter/gather reads. + +Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). + +Members: + +- void \*buf and size\_t buf\_len + + The address and length of the buffer to be filled. + +### `__wasi_linkcount_t` (`uint32_t`) + +Number of hard links to an inode. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_lookupflags_t` (`uint32_t` bitfield) + +Flags determining the method of how paths are resolved. + +Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** + + As long as the resolved path corresponds to a symbolic + link, it is expanded. + +### `__wasi_oflags_t` (`uint16_t` bitfield) + +Open flags used by [`__wasi_path_open()`](#path_open). + +Used by [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_O_CREAT`** + + Create file if it does not exist. + +- **`__WASI_O_DIRECTORY`** + + Fail if not a directory. + +- **`__WASI_O_EXCL`** + + Fail if file already exists. + +- **`__WASI_O_TRUNC`** + + Truncate file to size 0. + +### `__wasi_riflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_PEEK`** + + Returns the message without removing it from the + socket's receive queue. + +- **`__WASI_SOCK_RECV_WAITALL`** + + On byte-stream sockets, block until the full amount + of data can be returned. + +### `__wasi_rights_t` (`uint64_t` bitfield) + +File descriptor rights, determining which actions may be +performed. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_RIGHT_FD_DATASYNC`** + + The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_READ`** + + The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke + [`__wasi_fd_pread()`](#fd_pread). + +- **`__WASI_RIGHT_FD_SEEK`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies + [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). + +- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** + + The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). + +- **`__WASI_RIGHT_FD_SYNC`** + + The right to invoke [`__wasi_fd_sync()`](#fd_sync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and + [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_TELL`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the + file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with + offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). + +- **`__WASI_RIGHT_FD_WRITE`** + + The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to + invoke [`__wasi_fd_pwrite()`](#fd_pwrite). + +- **`__WASI_RIGHT_FD_ADVISE`** + + The right to invoke [`__wasi_fd_advise()`](#fd_advise). + +- **`__WASI_RIGHT_FD_ALLOCATE`** + + The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). + +- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** + + The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). + +- **`__WASI_RIGHT_PATH_CREATE_FILE`** + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke + [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). + +- **`__WASI_RIGHT_PATH_LINK_SOURCE`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_LINK_TARGET`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_OPEN`** + + The right to invoke [`__wasi_path_open()`](#path_open). + +- **`__WASI_RIGHT_FD_READDIR`** + + The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). + +- **`__WASI_RIGHT_PATH_READLINK`** + + The right to invoke [`__wasi_path_readlink()`](#path_readlink). + +- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_RENAME_TARGET`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_FILESTAT_GET`** + + The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** + + The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +- **`__WASI_RIGHT_FD_FILESTAT_GET`** + + The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** + + The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). + +- **`__WASI_RIGHT_PATH_SYMLINK`** + + The right to invoke [`__wasi_path_symlink()`](#path_symlink). + +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + +- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** + + The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). + +- **`__WASI_RIGHT_POLL_FD_READWRITE`** + + If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). + + If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +- **`__WASI_RIGHT_SOCK_SHUTDOWN`** + + The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). + +### `__wasi_roflags_t` (`uint16_t` bitfield) + +Flags returned by [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** + + Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been + truncated. + +### `__wasi_sdflags_t` (`uint8_t` bitfield) + +Which channels on a socket to shut down. + +Used by [`__wasi_sock_shutdown()`](#sock_shutdown). + +Possible values: + +- **`__WASI_SHUT_RD`** + + Disables further receive operations. + +- **`__WASI_SHUT_WR`** + + Disables further send operations. + +### `__wasi_siflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +Used by [`__wasi_sock_send()`](#sock_send). + +### `__wasi_signal_t` (`uint8_t`) + +Signal condition. + +Used by [`__wasi_proc_raise()`](#proc_raise). + +Possible values: + +- **`__WASI_SIGABRT`** + + Process abort signal. + + Action: Terminates the process. + +- **`__WASI_SIGALRM`** + + Alarm clock. + + Action: Terminates the process. + +- **`__WASI_SIGBUS`** + + Access to an undefined portion of a memory object. + + Action: Terminates the process. + +- **`__WASI_SIGCHLD`** + + Child process terminated, stopped, or continued. + + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGFPE`** + + Erroneous arithmetic operation. + + Action: Terminates the process. + +- **`__WASI_SIGHUP`** + + Hangup. + + Action: Terminates the process. + +- **`__WASI_SIGILL`** + + Illegal instruction. + + Action: Terminates the process. + +- **`__WASI_SIGINT`** + + Terminate interrupt signal. + + Action: Terminates the process. + +- **`__WASI_SIGKILL`** + + Kill. + + Action: Terminates the process. + +- **`__WASI_SIGPIPE`** + + Write on a pipe with no one to read it. + + Action: Ignored. + +- **`__WASI_SIGQUIT`** + + Terminal quit signal. + + Action: Terminates the process. + +- **`__WASI_SIGSEGV`** + + Invalid memory reference. + + Action: Terminates the process. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. + +- **`__WASI_SIGSYS`** + + Bad system call. + + Action: Terminates the process. + +- **`__WASI_SIGTERM`** + + Termination signal. + + Action: Terminates the process. + +- **`__WASI_SIGTRAP`** + + Trace/breakpoint trap. + + Action: Terminates the process. + +- **`__WASI_SIGTSTP`** + + Terminal stop signal. + + Action: Stops executing. + +- **`__WASI_SIGTTIN`** + + Background process attempting read. + + Action: Stops executing. + +- **`__WASI_SIGTTOU`** + + Background process attempting write. + + Action: Stops executing. + +- **`__WASI_SIGURG`** + + High bandwidth data is available at a socket. + + Action: Ignored. + +- **`__WASI_SIGUSR1`** + + User-defined signal 1. + + Action: Terminates the process. + +- **`__WASI_SIGUSR2`** + + User-defined signal 2. + + Action: Terminates the process. + +- **`__WASI_SIGVTALRM`** + + Virtual timer expired. + + Action: Terminates the process. + +- **`__WASI_SIGXCPU`** + + CPU time limit exceeded. + + Action: Terminates the process. + +- **`__WASI_SIGXFSZ`** + + File size limit exceeded. + + Action: Terminates the process. + +### `__wasi_subclockflags_t` (`uint16_t` bitfield) + +Flags determining how to interpret the timestamp provided in +[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +Used by [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** + + If set, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp + of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + + If clear, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current + time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + +### `__wasi_subscription_t` (`struct`) + +Subscription to an event. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that is attached to the subscription in the + implementation and returned through + [`__wasi_event_t::userdata`](#event.userdata). + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event to which to subscribe. + +- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): + + - **`u.clock`** + + - [\_\_wasi\_userdata\_t](#userdata) identifier + + The user-defined unique identifier of the clock. + + - [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock against which to compare the timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) timeout + + The absolute or relative timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) precision + + The amount of time that the implementation may wait additionally + to coalesce with other events. + + - [\_\_wasi\_subclockflags\_t](#subclockflags) flags + + Flags specifying whether the timeout is absolute or relative. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor on which to wait for it to become ready + for reading or writing. + +### `__wasi_timestamp_t` (`uint64_t`) + +Timestamp in nanoseconds. + +Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +### `__wasi_userdata_t` (`uint64_t`) + +User-provided value that may be attached to objects that is +retained when extracted from the implementation. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +### `__wasi_whence_t` (`uint8_t`) + +The position relative to which to set the offset of the file descriptor. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +Possible values: + +- **`__WASI_WHENCE_CUR`** + + Seek relative to current position. + +- **`__WASI_WHENCE_END`** + + Seek relative to end-of-file. + +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + diff --git a/proposals/clocks/phases/old/witx/typenames.witx b/proposals/clocks/phases/old/witx/typenames.witx new file mode 100644 index 000000000..e04a188d9 --- /dev/null +++ b/proposals/clocks/phases/old/witx/typenames.witx @@ -0,0 +1,752 @@ +;; Type names used by low-level WASI interfaces. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(typename $size_t u32) + +;; Non-negative file size or length of a region within a file. +(typename $filesize_t u64) + +;; Timestamp in nanoseconds. +(typename $timestamp_t u64) + +;; Identifiers for clocks. +(typename $clockid_t + (enum u32 + ;; The store-wide monotonic clock, which is defined as a clock measuring + ;; real time, whose value cannot be adjusted and which cannot have negative + ;; clock jumps. The epoch of this clock is undefined. The absolute time + ;; value of this clock therefore has no meaning. + $CLOCK_MONOTONIC + ;; The CPU-time clock associated with the current process. + $CLOCK_PROCESS_CPUTIME_ID + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME + ;; The CPU-time clock associated with the current thread. + $CLOCK_THREAD_CPUTIME_ID + ) +) + +;; Error codes returned by functions. +;; Not all of these error codes are returned by the functions provided by this +;; API; some are used in higher-level library layers, and others are provided +;; merely for alignment with POSIX. +(typename $errno_t + (enum u16 + ;; No error occurred. System call completed successfully. + $ESUCCESS + ;; Argument list too long. + $E2BIG + ;; Permission denied. + $EACCES + ;; Address in use. + $EADDRINUSE + ;; Address not available. + $EADDRNOTAVAIL + ;; Address family not supported. + $EAFNOSUPPORT + ;; Resource unavailable, or operation would block. + $EAGAIN + ;; Connection already in progress. + $EALREADY + ;; Bad file descriptor. + $EBADF + ;; Bad message. + $EBADMSG + ;; Device or resource busy. + $EBUSY + ;; Operation canceled. + $ECANCELED + ;; No child processes. + $ECHILD + ;; Connection aborted. + $ECONNABORTED + ;; Connection refused. + $ECONNREFUSED + ;; Connection reset. + $ECONNRESET + ;; Resource deadlock would occur. + $EDEADLK + ;; Destination address required. + $EDESTADDRREQ + ;; Mathematics argument out of domain of function. + $EDOM + ;; Reserved. + $EDQUOT + ;; File exists. + $EEXIST + ;; Bad address. + $EFAULT + ;; File too large. + $EFBIG + ;; Host is unreachable. + $EHOSTUNREACH + ;; Identifier removed. + $EIDRM + ;; Illegal byte sequence. + $EILSEQ + ;; Operation in progress. + $EINPROGRESS + ;; Interrupted function. + $EINTR + ;; Invalid argument. + $EINVAL + ;; I/O error. + $EIO + ;; Socket is connected. + $EISCONN + ;; Is a directory. + $EISDIR + ;; Too many levels of symbolic links. + $ELOOP + ;; File descriptor value too large. + $EMFILE + ;; Too many links. + $EMLINK + ;; Message too large. + $EMSGSIZE + ;; Reserved. + $EMULTIHOP + ;; Filename too long. + $ENAMETOOLONG + ;; Network is down. + $ENETDOWN + ;; Connection aborted by network. + $ENETRESET + ;; Network unreachable. + $ENETUNREACH + ;; Too many files open in system. + $ENFILE + ;; No buffer space available. + $ENOBUFS + ;; No such device. + $ENODEV + ;; No such file or directory. + $ENOENT + ;; Executable file format error. + $ENOEXEC + ;; No locks available. + $ENOLCK + ;; Reserved. + $ENOLINK + ;; Not enough space. + $ENOMEM + ;; No message of the desired type. + $ENOMSG + ;; Protocol not available. + $ENOPROTOOPT + ;; No space left on device. + $ENOSPC + ;; Function not supported. + $ENOSYS + ;; The socket is not connected. + $ENOTCONN + ;; Not a directory or a symbolic link to a directory. + $ENOTDIR + ;; Directory not empty. + $ENOTEMPTY + ;; State not recoverable. + $ENOTRECOVERABLE + ;; Not a socket. + $ENOTSOCK + ;; Not supported, or operation not supported on socket. + $ENOTSUP + ;; Inappropriate I/O control operation. + $ENOTTY + ;; No such device or address. + $ENXIO + ;; Value too large to be stored in data type. + $EOVERFLOW + ;; Previous owner died. + $EOWNERDEAD + ;; Operation not permitted. + $EPERM + ;; Broken pipe. + $EPIPE + ;; Protocol error. + $EPROTO + ;; Protocol not supported. + $EPROTONOSUPPORT + ;; Protocol wrong type for socket. + $EPROTOTYPE + ;; Result too large. + $ERANGE + ;; Read-only file system. + $EROFS + ;; Invalid seek. + $ESPIPE + ;; No such process. + $ESRCH + ;; Reserved. + $ESTALE + ;; Connection timed out. + $ETIMEDOUT + ;; Text file busy. + $ETXTBSY + ;; Cross-device link. + $EXDEV + ;; Extension: Capabilities insufficient. + $ENOTCAPABLE + ) +) + +;; File descriptor rights, determining which actions may be performed. +(typename $rights_t + (flags u64 + ;; The right to invoke `fd_datasync`. + ;; + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_DSYNC`. + (flag $RIGHT_FD_DATASYNC) + ;; The right to invoke `fd_read` and `sock_recv`. + ;; + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + (flag $RIGHT_FD_READ) + ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + (flag $RIGHT_FD_SEEK) + ;; The right to invoke `fd_fdstat_set_flags`. + (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + ;; The right to invoke `fd_sync`. + ;; + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + (flag $RIGHT_FD_SYNC) + ;; The right to invoke `fd_seek` in such a way that the file offset + ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;; invoke `fd_tell`. + (flag $RIGHT_FD_TELL) + ;; The right to invoke `fd_write` and `sock_send`. + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + (flag $RIGHT_FD_WRITE) + ;; The right to invoke `fd_advise`. + (flag $RIGHT_FD_ADVISE) + ;; The right to invoke `fd_allocate`. + (flag $RIGHT_FD_ALLOCATE) + ;; The right to invoke `path_create_directory`. + (flag $RIGHT_PATH_CREATE_DIRECTORY) + ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + (flag $RIGHT_PATH_CREATE_FILE) + ;; The right to invoke `path_link` with the file descriptor as the + ;; source directory. + (flag $RIGHT_PATH_LINK_SOURCE) + ;; The right to invoke `path_link` with the file descriptor as the + ;; target directory. + (flag $RIGHT_PATH_LINK_TARGET) + ;; The right to invoke `path_open`. + (flag $RIGHT_PATH_OPEN) + ;; The right to invoke `fd_readdir`. + (flag $RIGHT_FD_READDIR) + ;; The right to invoke `path_readlink`. + (flag $RIGHT_PATH_READLINK) + ;; The right to invoke `path_rename` with the file descriptor as the source directory. + (flag $RIGHT_PATH_RENAME_SOURCE) + ;; The right to invoke `path_rename` with the file descriptor as the target directory. + (flag $RIGHT_PATH_RENAME_TARGET) + ;; The right to invoke `path_filestat_get`. + (flag $RIGHT_PATH_FILESTAT_GET) + ;; The right to change a file's size (there is no `path_filestat_set_size`). + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + ;; The right to invoke `path_filestat_set_times`. + (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + ;; The right to invoke `fd_filestat_get`. + (flag $RIGHT_FD_FILESTAT_GET) + ;; The right to invoke `fd_filestat_set_size`. + (flag $RIGHT_FD_FILESTAT_SET_SIZE) + ;; The right to invoke `fd_filestat_set_times`. + (flag $RIGHT_FD_FILESTAT_SET_TIMES) + ;; The right to invoke `path_symlink`. + (flag $RIGHT_PATH_SYMLINK) + ;; The right to invoke `path_unlink_file`. + (flag $RIGHT_PATH_UNLINK_FILE) + ;; The right to invoke `path_remove_directory`. + (flag $RIGHT_PATH_REMOVE_DIRECTORY) + ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + (flag $RIGHT_POLL_FD_READWRITE) + ;; The right to invoke `sock_shutdown`. + (flag $RIGHT_SOCK_SHUTDOWN) + ) +) + +;; A file descriptor index. +(typename $fd_t u32) + +;; A region of memory for scatter/gather reads. +(typename $iovec_t + (struct + ;; The address of the buffer to be filled. + (field $buf (@witx pointer u8)) + ;; The length of the buffer to be filled. + (field $buf_len $size_t) + ) +) + +;; A region of memory for scatter/gather writes. +(typename $ciovec_t + (struct + ;; The address of the buffer to be written. + (field $buf (@witx const_pointer u8)) + ;; The length of the buffer to be written. + (field $buf_len $size_t) + ) +) + +(typename $iovec_t_array (array $iovec_t)) +(typename $ciovec_t_array (array $ciovec_t)) + +;; Relative offset within a file. +(typename $filedelta_t s64) + +;; The position relative to which to set the offset of the file descriptor. +(typename $whence_t + (enum u8 + ;; Seek relative to current position. + $WHENCE_CUR + ;; Seek relative to end-of-file. + $WHENCE_END + ;; Seek relative to start-of-file. + $WHENCE_SET + ) +) + +;; A reference to the offset of a directory entry. +(typename $dircookie_t u64) + +;; The type for the $d_namlen field of $dirent_t. +(typename $dirnamlen_t u32) + +;; File serial number that is unique within its file system. +(typename $inode_t u64) + +;; The type of a file descriptor or file. +(typename $filetype_t + (enum u8 + ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $FILETYPE_UNKNOWN + ;; The file descriptor or file refers to a block device inode. + $FILETYPE_BLOCK_DEVICE + ;; The file descriptor or file refers to a character device inode. + $FILETYPE_CHARACTER_DEVICE + ;; The file descriptor or file refers to a directory inode. + $FILETYPE_DIRECTORY + ;; The file descriptor or file refers to a regular file inode. + $FILETYPE_REGULAR_FILE + ;; The file descriptor or file refers to a datagram socket. + $FILETYPE_SOCKET_DGRAM + ;; The file descriptor or file refers to a byte-stream socket. + $FILETYPE_SOCKET_STREAM + ;; The file refers to a symbolic link inode. + $FILETYPE_SYMBOLIC_LINK + ) +) + +;; A directory entry. +(typename $dirent_t + (struct + ;; The offset of the next directory entry stored in this directory. + (field $d_next $dircookie_t) + ;; The serial number of the file referred to by this directory entry. + (field $d_ino $inode_t) + ;; The length of the name of the directory entry. + (field $d_namlen $dirnamlen_t) + ;; The type of the file referred to by this directory entry. + (field $d_type $filetype_t) + ) +) + +;; File or memory access pattern advisory information. +(typename $advice_t + (enum u8 + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE + ;; The application has no advice to give on its behavior with respect to the specified data. + $ADVICE_NORMAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM + ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in the near future. + $ADVICE_WILLNEED + ) +) + +;; File descriptor flags. +(typename $fdflags_t + (flags u16 + ;; Append mode: Data written to the file is always appended to the file's end. + (flag $FDFLAG_APPEND) + ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + (flag $FDFLAG_DSYNC) + ;; Non-blocking mode. + (flag $FDFLAG_NONBLOCK) + ;; Synchronized read I/O operations. + (flag $FDFLAG_RSYNC) + ;; Write according to synchronized I/O file integrity completion. In + ;; addition to synchronizing the data stored in the file, the implementation + ;; may also synchronously update the file's metadata. + (flag $FDFLAG_SYNC) + ) +) + +;; File descriptor attributes. +(typename $fdstat_t + (struct + ;; File type. + (field $fs_filetype $filetype_t) + ;; File descriptor flags. + (field $fs_flags $fdflags_t) + ;; Rights that apply to this file descriptor. + (field $fs_rights_base $rights_t) + ;; Maximum set of rights that may be installed on new file descriptors that + ;; are created through this file descriptor, e.g., through `path_open`. + (field $fs_rights_inheriting $rights_t) + ) +) + +;; Identifier for a device containing a file system. Can be used in combination +;; with `inode_t` to uniquely identify a file or directory in the filesystem. +(typename $device_t u64) + +;; Which file time attributes to adjust. +(typename $fstflags_t + (flags u16 + ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + (flag $FILESTAT_SET_ATIM) + ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + (flag $FILESTAT_SET_ATIM_NOW) + ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + (flag $FILESTAT_SET_MTIM) + ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + (flag $FILESTAT_SET_MTIM_NOW) + ) +) + +;; Flags determining the method of how paths are resolved. +(typename $lookupflags_t + (flags u32 + ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + (flag $LOOKUP_SYMLINK_FOLLOW) + ) +) + +;; Open flags used by `path_open`. +(typename $oflags_t + (flags u16 + ;; Create file if it does not exist. + (flag $O_CREAT) + ;; Fail if not a directory. + (flag $O_DIRECTORY) + ;; Fail if file already exists. + (flag $O_EXCL) + ;; Truncate file to size 0. + (flag $O_TRUNC) + ) +) + +;; Number of hard links to an inode. +(typename $linkcount_t u32) + +;; File attributes. +(typename $filestat_t + (struct + ;; Device ID of device containing the file. + (field $st_dev $device_t) + ;; File serial number. + (field $st_ino $inode_t) + ;; File type. + (field $st_filetype $filetype_t) + ;; Number of hard links to the file. + (field $st_nlink $linkcount_t) + ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + (field $st_size $filesize_t) + ;; Last data access timestamp. + (field $st_atim $timestamp_t) + ;; Last data modification timestamp. + (field $st_mtim $timestamp_t) + ;; Last file status change timestamp. + (field $st_ctim $timestamp_t) + ) +) + +;; User-provided value that may be attached to objects that is retained when +;; extracted from the implementation. +(typename $userdata_t u64) + +;; Type of a subscription to an event or its occurrence. +(typename $eventtype_t + (flags u8 + ;; The time value of clock `subscription_t::u.clock.clock_id` has + ;; reached timestamp `subscription_t::u.clock.timeout`. + (flag $EVENTTYPE_CLOCK) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;; available for reading. This event always triggers for regular files. + (flag $EVENTTYPE_FD_READ) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;; available for writing. This event always triggers for regular files. + (flag $EVENTTYPE_FD_WRITE) + ) +) + +;; The state of the file descriptor subscribed to with +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $eventrwflags_t + (flags u16 + ;; The peer of this socket has closed or disconnected. + (flag $EVENT_FD_READWRITE_HANGUP) + ) +) + +;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;; `EVENTTYPE_FD_WRITE`. +(typename $event_fd_readwrite_t + (struct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) + ) +) + +;; The contents of an $event_t. +(typename $event_u + (union + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $event_fd_readwrite_t) + ) +) + +;; An event that occurred. +(typename $event_t + (struct + ;; User-provided value that got attached to `subscription_t::userdata`. + (field $userdata $userdata_t) + ;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno_t) + ;; The type of the event that occurred. + (field $type $eventtype_t) + ;; The contents of the event. + (field $u $event_u) + ) +) + +;; Flags determining how to interpret the timestamp provided in +;; `subscription_t::u.clock.timeout.` +(typename $subclockflags_t + (flags u16 + ;; If set, treat the timestamp provided in + ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;; provided in `subscription_t::u.clock.timeout` relative to the + ;; current time value of clock `subscription_t::u.clock.clock_id.` + (flag $SUBSCRIPTION_CLOCK_ABSTIME) + ) +) + +;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +(typename $subscription_clock_t + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) +) + +;; The contents of a $subscription_t when type is type is +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $subscription_fd_readwrite_t + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) + ) +) + +;; The contents of a $subscription_t. +(typename $subscription_u + (union + ;; When type is `EVENTTYPE_CLOCK`: + (field $clock $subscription_clock_t) + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $subscription_fd_readwrite_t) + ) +) + +;; Subscription to an event. +(typename $subscription_t + (struct + ;; User-provided value that is attached to the subscription in the + ;; implementation and returned through `event_t::userdata`. + (field $userdata $userdata_t) + ;; The type of the event to which to subscribe. + (field $type $eventtype_t) + ;; The contents of the subscription. + (field $u $subscription_u) + ) +) + +;; Exit code generated by a process when exiting. +(typename $exitcode_t u32) + +;; Signal condition. +(typename $signal_t + (enum u8 + ;; Process abort signal. + ;; Action: Terminates the process. + $SIGABRT + ;; Alarm clock. + ;; Action: Terminates the process. + $SIGALRM + ;; Access to an undefined portion of a memory object. + ;; Action: Terminates the process. + $SIGBUS + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT + ;; Erroneous arithmetic operation. + ;; Action: Terminates the process. + $SIGFPE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Kill. + ;; Action: Terminates the process. + $SIGKILL + ;; Write on a pipe with no one to read it. + ;; Action: Ignored. + $SIGPIPE + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Invalid memory reference. + ;; Action: Terminates the process. + $SIGSEGV + ;; Stop executing. + ;; Action: Stops executing. + $SIGSTOP + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS + ;; Termination signal. + ;; Action: Terminates the process. + $SIGTERM + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP + ;; Terminal stop signal. + ;; Action: Stops executing. + $SIGTSTP + ;; Background process attempting read. + ;; Action: Stops executing. + $SIGTTIN + ;; Background process attempting write. + ;; Action: Stops executing. + $SIGTTOU + ;; High bandwidth data is available at a socket. + ;; Action: Ignored. + $SIGURG + ;; User-defined signal 1. + ;; Action: Terminates the process. + $SIGUSR1 + ;; User-defined signal 2. + ;; Action: Terminates the process. + $SIGUSR2 + ;; Virtual timer expired. + ;; Action: Terminates the process. + $SIGVTALRM + ;; CPU time limit exceeded. + ;; Action: Terminates the process. + $SIGXCPU + ;; File size limit exceeded. + ;; Action: Terminates the process. + $SIGXFSZ + ) +) + +;; Flags provided to `sock_recv`. +(typename $riflags_t + (flags u16 + ;; Returns the message without removing it from the socket's receive queue. + (flag $SOCK_RECV_PEEK) + ;; On byte-stream sockets, block until the full amount of data can be returned. + (flag $SOCK_RECV_WAITALL) + ) +) + +;; Flags returned by `sock_recv`. +(typename $roflags_t + (flags u16 + ;; Returned by `sock_recv`: Message data has been truncated. + (flag $SOCK_RECV_DATA_TRUNCATED) + ) +) + +;; Flags provided to `sock_send`. As there are currently no flags +;; defined, it must be set to zero. +(typename $siflags_t u16) + +;; Which channels on a socket to shut down. +(typename $sdflags_t + (flags u8 + ;; Disables further receive operations. + (flag $SHUT_RD) + ;; Disables further send operations. + (flag $SHUT_WR) + ) +) + +;; Identifiers for preopened capabilities. +(typename $preopentype_t + (enum u8 + ;; A pre-opened directory. + $PREOPENTYPE_DIR + ) +) + +;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +(typename $prestat_dir + (struct + ;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size_t) + ) +) + +;; The contents of an $prestat_t. +(typename $prestat_u + (union + ;; When type is `PREOPENTYPE_DIR`: + (field $dir $prestat_dir) + ) +) + +;; Information about a pre-opened capability. +(typename $prestat_t + (struct + ;; The type of the pre-opened capability. + (field $pr_type $preopentype_t) + ;; The contents of the information. + (field $u $prestat_u) + ) +) diff --git a/proposals/clocks/design/wasi_unstable/wasi_unstable.witx b/proposals/clocks/phases/old/witx/wasi_unstable.witx similarity index 98% rename from proposals/clocks/design/wasi_unstable/wasi_unstable.witx rename to proposals/clocks/phases/old/witx/wasi_unstable.witx index 6d4bea545..f9586ff1e 100644 --- a/proposals/clocks/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/clocks/phases/old/witx/wasi_unstable.witx @@ -1,4 +1,5 @@ -;; The wasi_unstable module type. +;; WASI Preview. This is an evolution of the API that WASI initially +;; launched with. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). ;; @@ -7,6 +8,9 @@ (use "typenames.witx") +;; This API predated the convention of naming modules with a `wasi_unstable_` +;; prefix and a version number. It is preserved here for compatibility, but +;; we shouldn't follow this pattern in new APIs. (module $wasi_unstable ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) diff --git a/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md new file mode 100644 index 000000000..9db4a382e --- /dev/null +++ b/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md @@ -0,0 +1,2319 @@ + + +# The WASI Preview API + +This is the API-level documentation for WASI Preview. The function names +are prefixed with "\_\_wasi\_" to reflect how they are spelled in +flat-namespace contexts, however at the wasm module level, they are +unprefixed, because they're inside a module namespace. + +Functions that start with `__wasi_fd_` operate on file descriptors, +while functions that start with `__wasi_path_` operate on filesystem +paths, which are relative to directory file descriptors. + +Much inspiration and content here is derived from [CloudABI] and [POSIX], +though there are also several differences from CloudABI and POSIX. For +example, WASI Preview has no concept of processes in the traditional Unix +sense. While wasm linear memories have some of the aspects of processes, +and it's possible to *emulate* the full semantics of processes on top of +them, this can sometimes be unnatural and inefficient. The goal for +WASI Preview is to be a WebAssembly-native API that exposes APIs that fit +well into the underlying WebAssembly platform, rather than to directly +emulate other platforms. + +This is also a work in progress, and the API here is still evolving. + +Historical note: this API was originally named "WASI Core", and used the +API module name "wasi\_unstable". We've since sought to deemphasize the +"Core" name, as the goal is to split this API up into independent +modules so that embedders need not implement all of it. + +[CloudABI]: https://github.com/NuxiNL/cloudabi +[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ + +## System calls + +- [`__wasi_args_get()`](#args_get) +- [`__wasi_args_sizes_get()`](#args_sizes_get) +- [`__wasi_clock_res_get()`](#clock_res_get) +- [`__wasi_clock_time_get()`](#clock_time_get) +- [`__wasi_environ_get()`](#environ_get) +- [`__wasi_environ_sizes_get()`](#environ_sizes_get) +- [`__wasi_fd_advise()`](#fd_advise) +- [`__wasi_fd_allocate()`](#fd_allocate) +- [`__wasi_fd_close()`](#fd_close) +- [`__wasi_fd_datasync()`](#fd_datasync) +- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) +- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) +- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) +- [`__wasi_fd_filestat_get()`](#fd_filestat_get) +- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) +- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) +- [`__wasi_fd_pread()`](#fd_pread) +- [`__wasi_fd_prestat_get()`](#fd_prestat_get) +- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) +- [`__wasi_fd_pwrite()`](#fd_pwrite) +- [`__wasi_fd_read()`](#fd_read) +- [`__wasi_fd_readdir()`](#fd_readdir) +- [`__wasi_fd_renumber()`](#fd_renumber) +- [`__wasi_fd_seek()`](#fd_seek) +- [`__wasi_fd_sync()`](#fd_sync) +- [`__wasi_fd_tell()`](#fd_tell) +- [`__wasi_fd_write()`](#fd_write) +- [`__wasi_path_create_directory()`](#path_create_directory) +- [`__wasi_path_filestat_get()`](#path_filestat_get) +- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) +- [`__wasi_path_link()`](#path_link) +- [`__wasi_path_open()`](#path_open) +- [`__wasi_path_readlink()`](#path_readlink) +- [`__wasi_path_remove_directory()`](#path_remove_directory) +- [`__wasi_path_rename()`](#path_rename) +- [`__wasi_path_symlink()`](#path_symlink) +- [`__wasi_path_unlink_file()`](#path_unlink_file) +- [`__wasi_poll_oneoff()`](#poll_oneoff) +- [`__wasi_proc_exit()`](#proc_exit) +- [`__wasi_proc_raise()`](#proc_raise) +- [`__wasi_random_get()`](#random_get) +- [`__wasi_sched_yield()`](#sched_yield) +- [`__wasi_sock_recv()`](#sock_recv) +- [`__wasi_sock_send()`](#sock_send) +- [`__wasi_sock_shutdown()`](#sock_shutdown) + +### `__wasi_args_get()` + +Read command-line argument data. + +The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + +Inputs: + +- char \*\*argv + + A pointer to a buffer to write the argument pointers. + +- char \*argv\_buf + + A pointer to a buffer to write the argument string data. + +### `__wasi_args_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*argc + + The number of arguments. + +- size\_t \*argv\_buf\_size + + The size of the argument string data. + +### `__wasi_clock_res_get()` + +Return the resolution of a clock. + +Implementations are required to provide a non-zero value for supported clocks. +For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). + +Note: This is similar to `clock_getres` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the resolution. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) resolution + + The resolution of the clock. + +### `__wasi_clock_time_get()` + +Return the time value of a clock. + +Note: This is similar to `clock_gettime` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the time. + +- [\_\_wasi\_timestamp\_t](#timestamp) precision + + The maximum lag (exclusive) that the returned + time value may have, compared to its actual + value. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) time + + The time value of the clock. + +### `__wasi_environ_get()` + +Read environment variable data. + +The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + +Inputs: + +- char \*\*environ + + A pointer to a buffer to write the environment variable pointers. + +- char \*environ\_buf + + A pointer to a buffer to write the environment variable string data. + +### `__wasi_environ_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*environ\_count + + The number of environment variables. + +- size\_t \*environ\_buf\_size + + The size of the environment variable string data. + +### `__wasi_fd_advise()` + +Provide file advisory information on a file descriptor. + +Note: This is similar to `posix_fadvise` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file for which to provide file advisory information. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file to which the advisory applies. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the region to which the advisory applies. + +- [\_\_wasi\_advice\_t](#advice) advice + + The advice. + +### `__wasi_fd_allocate()` + +Force the allocation of space in a file. + +Note: This is similar to `posix_fallocate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file in which to allocate space. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset at which to start the allocation. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the area that is allocated. + +### `__wasi_fd_close()` + +Close a file descriptor. + +Note: This is similar to `close` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to close. + +### `__wasi_fd_datasync()` + +Synchronize the data of a file to disk. + +Note: This is similar to `fdatasync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file to synchronize to disk. + +### `__wasi_fd_fdstat_get()` + +Get the attributes of a file descriptor. + +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well +as additional fields. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_fdstat\_t](#fdstat) \*buf + + The buffer where the file descriptor's attributes are stored. + +### `__wasi_fd_fdstat_set_flags()` + +Adjust the flags associated with a file descriptor. + +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_fdflags\_t](#fdflags) flags + + The desired values of the file descriptor + flags. + +### `__wasi_fd_fdstat_set_rights()` + +Adjust the rights associated with a file descriptor. + +This can only be used to remove rights, and returns +[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt +to add rights. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The desired rights of the file descriptor. + +### `__wasi_fd_filestat_get()` + +Return the attributes of an open file. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_fd_filestat_set_size()` + +Adjust the size of an open file. If this increases the file's size, the extra +bytes are filled with zeros. + +Note: This is similar to `ftruncate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + A file descriptor for the file to adjust. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + The desired file size. + +### `__wasi_fd_filestat_set_times()` + +Adjust the timestamps of an open file or directory. + +Note: This is similar to `futimens` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_fd_pread()` + +Read from a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `preadv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors in which to store data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to read. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_prestat_get()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- [\_\_wasi\_prestat\_t](#prestat) \*buf + + The buffer where the description is stored. + +### `__wasi_fd_prestat_dir_name()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- const char \*path and size\_t path\_len + + A buffer into which to write the preopened directory name. + +### `__wasi_fd_pwrite()` + +Write to a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `pwritev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to write. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_fd_read()` + +Read from a file descriptor. + +Note: This is similar to `readv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors to which to store data. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_readdir()` + +Read directory entries from a directory. + +When successful, the contents of the output buffer consist of +a sequence of directory entries. Each directory entry consists +of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes +holding the name of the directory entry. + +This function fills the output buffer as much as possible, +potentially truncating the last directory entry. This allows +the caller to grow its read buffer size in case it's too small +to fit a single large directory entry, or skip the oversized +directory entry. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The directory from which to read the directory + entries. + +- void \*buf and size\_t buf\_len + + The buffer where directory entries are stored. + +- [\_\_wasi\_dircookie\_t](#dircookie) cookie + + The location within the directory to start + reading. + +Outputs: + +- size\_t bufused + + The number of bytes stored in the read buffer. + If less than the size of the read buffer, the + end of the directory has been reached. + +### `__wasi_fd_renumber()` + +Atomically replace a file descriptor by renumbering another +file descriptor. + +Due to the strong focus on thread safety, this environment +does not provide a mechanism to duplicate or renumber a file +descriptor to an arbitrary number, like dup2(). This would be +prone to race conditions, as an actual file descriptor with the +same number could be allocated by a different thread at the same +time. + +This function provides a way to atomically renumber file +descriptors, which would disappear if dup2() were to be +removed entirely. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) from + + The file descriptor to renumber. + +- [\_\_wasi\_fd\_t](#fd) to + + The file descriptor to overwrite. + +### `__wasi_fd_seek()` + +Move the offset of a file descriptor. + +Note: This is similar to `lseek` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_filedelta\_t](#filedelta) offset + + The number of bytes to move. + +- [\_\_wasi\_whence\_t](#whence) whence + + The base from which the offset is relative. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) newoffset + + The new offset of the file descriptor, + relative to the start of the file. + +### `__wasi_fd_sync()` + +Synchronize the data and metadata of a file to disk. + +Note: This is similar to `fsync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file containing the data + and metadata to synchronize to disk. + +### `__wasi_fd_tell()` + +Return the current offset of a file descriptor. + +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The current offset of the file descriptor, relative to the start of the file. + +### `__wasi_fd_write()` + +Write to a file descriptor. + +Note: This is similar to `writev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_path_create_directory()` + +Create a directory. + +Note: This is similar to `mkdirat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path at which to create the directory. + +### `__wasi_path_filestat_get()` + +Return the attributes of a file or directory. + +Note: This is similar to `stat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_path_filestat_set_times()` + +Adjust the timestamps of a file or directory. + +Note: This is similar to `utimensat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_path_link()` + +Create a hard link. + +Note: This is similar to `linkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags + + Flags determining the method of how the path is resolved. + +- const char \*old\_path and size\_t old\_path\_len + + The source path from which to link. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the hard link. + +### `__wasi_path_open()` + +Open a file or directory. + +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since +this is error-prone in multi-threaded contexts. The returned file +descriptor is guaranteed to be less than 231. + +Note: This is similar to `openat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) dirfd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The relative path of the file or directory to open, relative to + the [`dirfd`](#path_open.dirfd) directory. + +- [\_\_wasi\_oflags\_t](#oflags) o_flags + + The method by which to open the file. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The initial rights of the newly created file descriptor. The + implementation is allowed to return a file descriptor with fewer + rights than specified, if and only if those rights do not apply + to the type of file being opened. + + The *base* rights are rights that will apply to operations using + the file descriptor itself, while the *inheriting* rights are + rights that apply to file descriptors derived from it. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + The initial flags of the file descriptor. + +Outputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file that has been + opened. + +### `__wasi_path_readlink()` + +Read the contents of a symbolic link. + +Note: This is similar to `readlinkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path of the symbolic link from which to read. + +- char \*buf and size\_t buf\_len + + The buffer to which to write the contents of the symbolic link. + +Outputs: + +- size\_t bufused + + The number of bytes placed in the buffer. + +### `__wasi_path_remove_directory()` + +Remove a directory. + +Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. + +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a directory to remove. + +### `__wasi_path_rename()` + +Rename a file or directory. + +Note: This is similar to `renameat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- const char \*old\_path and size\_t old\_path\_len + + The source path of the file or directory to rename. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path to which to rename the file or directory. + +### `__wasi_path_symlink()` + +Create a symbolic link. + +Note: This is similar to `symlinkat` in POSIX. + +Inputs: + +- const char \*old\_path and size\_t old_path\_len + + The contents of the symbolic link. + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the symbolic link. + +### `__wasi_path_unlink_file()` + +Unlink a file. + +Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. + +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a file to unlink. + +### `__wasi_poll_oneoff()` + +Concurrently poll for the occurrence of a set of events. + +Inputs: + +- const [\_\_wasi\_subscription\_t](#subscription) \*in + + The events to which to subscribe. + +- [\_\_wasi\_event\_t](#event) \*out + + The events that have occurred. + +- size\_t nsubscriptions + + Both the number of subscriptions and events. + +Outputs: + +- size\_t nevents + + The number of events stored. + +### `__wasi_proc_exit()` + +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +Note: This is similar to `_Exit` in POSIX. + +Inputs: + +- [\_\_wasi\_exitcode\_t](#exitcode) rval + + The exit code returned by the process. + +Does not return. + +### `__wasi_proc_raise()` + +Send a signal to the process of the calling thread. + +Note: This is similar to `raise` in POSIX. + +Inputs: + +- [\_\_wasi\_signal\_t](#signal) sig + + The signal condition to trigger. + +### `__wasi_random_get()` + +Write high-quality random data into a buffer. + +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. + +This function may execute slowly, so when large mounts of random +data are required, it's advisable to use this function to seed a +pseudo-random number generator, rather than to provide the +random data directly. + +Inputs: + +- void \*buf and size\_t buf\_len + + The buffer to fill with random data. + +### `__wasi_sched_yield()` + +Temporarily yield execution of the calling thread. + +Note: This is similar to `sched_yield` in POSIX. + +### `__wasi_sock_recv()` + +Receive a message from a socket. + +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to receive data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len + + List of scatter/gather vectors to which to store data. + +- [\_\_wasi\_riflags\_t](#riflags) ri\_flags + + Message flags. + +Outputs: + +- size\_t ro\_datalen + + Number of bytes stored in [`ri_data`](#sock_recv.ri_data). + +- [\_\_wasi\_roflags\_t](#roflags) ro\_flags + + Message flags. + +### `__wasi_sock_send()` + +Send a message on a socket. + +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to send data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len + + List of scatter/gather vectors to which to retrieve data + +- [\_\_wasi\_siflags\_t](#siflags) si\_flags + + Message flags. + +Outputs: + +- size\_t so\_datalen + + Number of bytes transmitted. + +### `__wasi_sock_shutdown()` + +Shut down socket send and receive channels. + +Note: This is similar to `shutdown` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to shutdown channels. + +- [\_\_wasi\_sdflags\_t](#sdflags) how + + Which channels on the socket to shut down. + +## Types + +### `__wasi_advice_t` (`uint8_t`) + +File or memory access pattern advisory information. + +Used by [`__wasi_fd_advise()`](#fd_advise). + +Possible values: + +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + +- **`__WASI_ADVICE_NORMAL`** + + The application has no advice to give on its behavior + with respect to the specified data. + +- **`__WASI_ADVICE_RANDOM`** + + The application expects to access the specified data + in a random order. + +- **`__WASI_ADVICE_SEQUENTIAL`** + + The application expects to access the specified data + sequentially from lower offsets to higher offsets. + +- **`__WASI_ADVICE_WILLNEED`** + + The application expects to access the specified data + in the near future. + +### `__wasi_ciovec_t` (`struct`) + +A region of memory for scatter/gather writes. + +Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). + +Members: + +- const void \*buf and size\_t buf\_len + + The address and length of the buffer to be written. + +### `__wasi_clockid_t` (`uint32_t`) + +Identifiers for clocks. + +Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). + +Possible values: + +- **`__WASI_CLOCK_MONOTONIC`** + + The store-wide monotonic clock, which is defined as a + clock measuring real time, whose value cannot be + adjusted and which cannot have negative clock jumps. + + The epoch of this clock is undefined. The absolute + time value of this clock therefore has no meaning. + +- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** + + The CPU-time clock associated with the current + process. + +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + +- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** + + The CPU-time clock associated with the current thread. + +### `__wasi_device_t` (`uint64_t`) + +Identifier for a device containing a file system. Can be used +in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or +directory in the filesystem. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_dircookie_t` (`uint64_t`) + +A reference to the offset of a directory entry. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). + +Special values: + +- **`__WASI_DIRCOOKIE_START`** + + Permanent reference to the first directory entry + within a directory. + +### `__wasi_dirent_t` (`struct`) + +A directory entry. + +Members: + +- [\_\_wasi\_dircookie\_t](#dircookie) d\_next + + The offset of the next directory entry stored in this + directory. + +- [\_\_wasi\_inode\_t](#inode) d\_ino + + The serial number of the file referred to by this + directory entry. + +- uint32\_t d\_namlen + + The length of the name of the directory entry. + +- [\_\_wasi\_filetype\_t](#filetype) d\_type + + The type of the file referred to by this directory + entry. + +### `__wasi_errno_t` (`uint16_t`) + +Error codes returned by functions. + +Not all of these error codes are returned by the functions +provided by this API; some are used in higher-level library layers, +and others are provided merely for alignment with POSIX. + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_ESUCCESS`** + + No error occurred. System call completed successfully. + +- **`__WASI_E2BIG`** + + Argument list too long. + +- **`__WASI_EACCES`** + + Permission denied. + +- **`__WASI_EADDRINUSE`** + + Address in use. + +- **`__WASI_EADDRNOTAVAIL`** + + Address not available. + +- **`__WASI_EAFNOSUPPORT`** + + Address family not supported. + +- **`__WASI_EAGAIN`** + + Resource unavailable, or operation would block. + +- **`__WASI_EALREADY`** + + Connection already in progress. + +- **`__WASI_EBADF`** + + Bad file descriptor. + +- **`__WASI_EBADMSG`** + + Bad message. + +- **`__WASI_EBUSY`** + + Device or resource busy. + +- **`__WASI_ECANCELED`** + + Operation canceled. + +- **`__WASI_ECHILD`** + + No child processes. + +- **`__WASI_ECONNABORTED`** + + Connection aborted. + +- **`__WASI_ECONNREFUSED`** + + Connection refused. + +- **`__WASI_ECONNRESET`** + + Connection reset. + +- **`__WASI_EDEADLK`** + + Resource deadlock would occur. + +- **`__WASI_EDESTADDRREQ`** + + Destination address required. + +- **`__WASI_EDOM`** + + Mathematics argument out of domain of function. + +- **`__WASI_EDQUOT`** + + Reserved. + +- **`__WASI_EEXIST`** + + File exists. + +- **`__WASI_EFAULT`** + + Bad address. + +- **`__WASI_EFBIG`** + + File too large. + +- **`__WASI_EHOSTUNREACH`** + + Host is unreachable. + +- **`__WASI_EIDRM`** + + Identifier removed. + +- **`__WASI_EILSEQ`** + + Illegal byte sequence. + +- **`__WASI_EINPROGRESS`** + + Operation in progress. + +- **`__WASI_EINTR`** + + Interrupted function. + +- **`__WASI_EINVAL`** + + Invalid argument. + +- **`__WASI_EIO`** + + I/O error. + +- **`__WASI_EISCONN`** + + Socket is connected. + +- **`__WASI_EISDIR`** + + Is a directory. + +- **`__WASI_ELOOP`** + + Too many levels of symbolic links. + +- **`__WASI_EMFILE`** + + File descriptor value too large. + +- **`__WASI_EMLINK`** + + Too many links. + +- **`__WASI_EMSGSIZE`** + + Message too large. + +- **`__WASI_EMULTIHOP`** + + Reserved. + +- **`__WASI_ENAMETOOLONG`** + + Filename too long. + +- **`__WASI_ENETDOWN`** + + Network is down. + +- **`__WASI_ENETRESET`** + + Connection aborted by network. + +- **`__WASI_ENETUNREACH`** + + Network unreachable. + +- **`__WASI_ENFILE`** + + Too many files open in system. + +- **`__WASI_ENOBUFS`** + + No buffer space available. + +- **`__WASI_ENODEV`** + + No such device. + +- **`__WASI_ENOENT`** + + No such file or directory. + +- **`__WASI_ENOEXEC`** + + Executable file format error. + +- **`__WASI_ENOLCK`** + + No locks available. + +- **`__WASI_ENOLINK`** + + Reserved. + +- **`__WASI_ENOMEM`** + + Not enough space. + +- **`__WASI_ENOMSG`** + + No message of the desired type. + +- **`__WASI_ENOPROTOOPT`** + + Protocol not available. + +- **`__WASI_ENOSPC`** + + No space left on device. + +- **`__WASI_ENOSYS`** + + Function not supported. + +- **`__WASI_ENOTCONN`** + + The socket is not connected. + +- **`__WASI_ENOTDIR`** + + Not a directory or a symbolic link to a directory. + +- **`__WASI_ENOTEMPTY`** + + Directory not empty. + +- **`__WASI_ENOTRECOVERABLE`** + + State not recoverable. + +- **`__WASI_ENOTSOCK`** + + Not a socket. + +- **`__WASI_ENOTSUP`** + + Not supported, or operation not supported on socket. + +- **`__WASI_ENOTTY`** + + Inappropriate I/O control operation. + +- **`__WASI_ENXIO`** + + No such device or address. + +- **`__WASI_EOVERFLOW`** + + Value too large to be stored in data type. + +- **`__WASI_EOWNERDEAD`** + + Previous owner died. + +- **`__WASI_EPERM`** + + Operation not permitted. + +- **`__WASI_EPIPE`** + + Broken pipe. + +- **`__WASI_EPROTO`** + + Protocol error. + +- **`__WASI_EPROTONOSUPPORT`** + + Protocol not supported. + +- **`__WASI_EPROTOTYPE`** + + Protocol wrong type for socket. + +- **`__WASI_ERANGE`** + + Result too large. + +- **`__WASI_EROFS`** + + Read-only file system. + +- **`__WASI_ESPIPE`** + + Invalid seek. + +- **`__WASI_ESRCH`** + + No such process. + +- **`__WASI_ESTALE`** + + Reserved. + +- **`__WASI_ETIMEDOUT`** + + Connection timed out. + +- **`__WASI_ETXTBSY`** + + Text file busy. + +- **`__WASI_EXDEV`** + + Cross-device link. + +- **`__WASI_ENOTCAPABLE`** + + Extension: Capabilities insufficient. + +### `__wasi_event_t` (`struct`) + +An event that occurred. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that got attached to + [`__wasi_subscription_t::userdata`](#subscription.userdata). + +- [\_\_wasi\_errno\_t](#errno) error + + If non-zero, an error that occurred while processing + the subscription request. + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event that occurred. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_filesize\_t](#filesize) nbytes + + The number of bytes available for reading or writing. + + - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags + + The state of the file descriptor. + +### `__wasi_eventrwflags_t` (`uint16_t` bitfield) + +The state of the file descriptor subscribed to with +[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_EVENT_FD_READWRITE_HANGUP`** + + The peer of this socket has closed or disconnected. + +### `__wasi_eventtype_t` (`uint8_t`) + +Type of a subscription to an event or its occurrence. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_EVENTTYPE_CLOCK`** + + The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) + has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +- **`__WASI_EVENTTYPE_FD_READ`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + data available for reading. This event always triggers + for regular files. + +- **`__WASI_EVENTTYPE_FD_WRITE`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + capacity available for writing. This event always + triggers for regular files. + +### `__wasi_exitcode_t` (`uint32_t`) + +Exit code generated by a process when exiting. + +Used by [`__wasi_proc_exit()`](#proc_exit). + +### `__wasi_fd_t` (`uint32_t`) + +A file descriptor number. + +Used by many functions in this API. + +As in POSIX, three file descriptor numbers are provided to instances +on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, +and `STDERR_FILENO`). + +Other than these, WASI implementations are not required to allocate +new file descriptors in ascending order. + +### `__wasi_fdflags_t` (`uint16_t` bitfield) + +File descriptor flags. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_FDFLAG_APPEND`** + + Append mode: Data written to the file is always + appended to the file's end. + +- **`__WASI_FDFLAG_DSYNC`** + + Write according to synchronized I/O data integrity + completion. Only the data stored in the file is + synchronized. + +- **`__WASI_FDFLAG_NONBLOCK`** + + Non-blocking mode. + +- **`__WASI_FDFLAG_RSYNC`** + + Synchronized read I/O operations. + +- **`__WASI_FDFLAG_SYNC`** + + Write according to synchronized I/O file integrity completion. + In addition to synchronizing the data stored in the file, the + implementation may also synchronously update the file's metadata. + +### `__wasi_fdstat_t` (`struct`) + +File descriptor attributes. + +Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). + +Members: + +- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype + + File type. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + File descriptor flags. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base + + Rights that apply to this file descriptor. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + Maximum set of rights that may be installed on new + file descriptors that are created through this file + descriptor, e.g., through [`__wasi_path_open()`](#path_open). + +### `__wasi_filedelta_t` (`int64_t`) + +Relative offset within a file. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +### `__wasi_filesize_t` (`uint64_t`) + +Non-negative file size or length of a region within a file. + +Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +### `__wasi_filestat_t` (`struct`) + +File attributes. + +Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). + +Members: + +- [\_\_wasi\_device\_t](#device) st\_dev + + Device ID of device containing the file. + +- [\_\_wasi\_inode\_t](#inode) st\_ino + + File serial number. + +- [\_\_wasi\_filetype\_t](#filetype) st\_filetype + + File type. + +- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink + + Number of hard links to the file. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + For regular files, the file size in bytes. For + symbolic links, the length in bytes of the pathname + contained in the symbolic link. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + Last data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + Last data modification timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim + + Last file status change timestamp. + +### `__wasi_filetype_t` (`uint8_t`) + +The type of a file descriptor or file. + +Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). + +Possible values: + +- **`__WASI_FILETYPE_UNKNOWN`** + + The type of the file descriptor or file is unknown or + is different from any of the other types specified. + +- **`__WASI_FILETYPE_BLOCK_DEVICE`** + + The file descriptor or file refers to a block device + inode. + +- **`__WASI_FILETYPE_CHARACTER_DEVICE`** + + The file descriptor or file refers to a character + device inode. + +- **`__WASI_FILETYPE_DIRECTORY`** + + The file descriptor or file refers to a directory + inode. + +- **`__WASI_FILETYPE_REGULAR_FILE`** + + The file descriptor or file refers to a regular file + inode. + +- **`__WASI_FILETYPE_SOCKET_DGRAM`** + + The file descriptor or file refers to a datagram + socket. + +- **`__WASI_FILETYPE_SOCKET_STREAM`** + + The file descriptor or file refers to a byte-stream + socket. + +- **`__WASI_FILETYPE_SYMBOLIC_LINK`** + + The file refers to a symbolic link inode. + +### `__wasi_fstflags_t` (`uint16_t` bitfield) + +Which file time attributes to adjust. + +Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +Possible values: + +- **`__WASI_FILESTAT_SET_ATIM`** + + Adjust the last data access timestamp to the value + stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). + +- **`__WASI_FILESTAT_SET_ATIM_NOW`** + + Adjust the last data access timestamp to the time + of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +- **`__WASI_FILESTAT_SET_MTIM`** + + Adjust the last data modification timestamp to the + value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). + +- **`__WASI_FILESTAT_SET_MTIM_NOW`** + + Adjust the last data modification timestamp to the + time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +### `__wasi_inode_t` (`uint64_t`) + +File serial number that is unique within its file system. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). + +### `__wasi_iovec_t` (`struct`) + +A region of memory for scatter/gather reads. + +Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). + +Members: + +- void \*buf and size\_t buf\_len + + The address and length of the buffer to be filled. + +### `__wasi_linkcount_t` (`uint32_t`) + +Number of hard links to an inode. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_lookupflags_t` (`uint32_t` bitfield) + +Flags determining the method of how paths are resolved. + +Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** + + As long as the resolved path corresponds to a symbolic + link, it is expanded. + +### `__wasi_oflags_t` (`uint16_t` bitfield) + +Open flags used by [`__wasi_path_open()`](#path_open). + +Used by [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_O_CREAT`** + + Create file if it does not exist. + +- **`__WASI_O_DIRECTORY`** + + Fail if not a directory. + +- **`__WASI_O_EXCL`** + + Fail if file already exists. + +- **`__WASI_O_TRUNC`** + + Truncate file to size 0. + +### `__wasi_riflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_PEEK`** + + Returns the message without removing it from the + socket's receive queue. + +- **`__WASI_SOCK_RECV_WAITALL`** + + On byte-stream sockets, block until the full amount + of data can be returned. + +### `__wasi_rights_t` (`uint64_t` bitfield) + +File descriptor rights, determining which actions may be +performed. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_RIGHT_FD_DATASYNC`** + + The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_READ`** + + The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke + [`__wasi_fd_pread()`](#fd_pread). + +- **`__WASI_RIGHT_FD_SEEK`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies + [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). + +- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** + + The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). + +- **`__WASI_RIGHT_FD_SYNC`** + + The right to invoke [`__wasi_fd_sync()`](#fd_sync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and + [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_TELL`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the + file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with + offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). + +- **`__WASI_RIGHT_FD_WRITE`** + + The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to + invoke [`__wasi_fd_pwrite()`](#fd_pwrite). + +- **`__WASI_RIGHT_FD_ADVISE`** + + The right to invoke [`__wasi_fd_advise()`](#fd_advise). + +- **`__WASI_RIGHT_FD_ALLOCATE`** + + The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). + +- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** + + The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). + +- **`__WASI_RIGHT_PATH_CREATE_FILE`** + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke + [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). + +- **`__WASI_RIGHT_PATH_LINK_SOURCE`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_LINK_TARGET`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_OPEN`** + + The right to invoke [`__wasi_path_open()`](#path_open). + +- **`__WASI_RIGHT_FD_READDIR`** + + The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). + +- **`__WASI_RIGHT_PATH_READLINK`** + + The right to invoke [`__wasi_path_readlink()`](#path_readlink). + +- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_RENAME_TARGET`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_FILESTAT_GET`** + + The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** + + The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +- **`__WASI_RIGHT_FD_FILESTAT_GET`** + + The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** + + The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). + +- **`__WASI_RIGHT_PATH_SYMLINK`** + + The right to invoke [`__wasi_path_symlink()`](#path_symlink). + +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + +- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** + + The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). + +- **`__WASI_RIGHT_POLL_FD_READWRITE`** + + If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). + + If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +- **`__WASI_RIGHT_SOCK_SHUTDOWN`** + + The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). + +### `__wasi_roflags_t` (`uint16_t` bitfield) + +Flags returned by [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** + + Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been + truncated. + +### `__wasi_sdflags_t` (`uint8_t` bitfield) + +Which channels on a socket to shut down. + +Used by [`__wasi_sock_shutdown()`](#sock_shutdown). + +Possible values: + +- **`__WASI_SHUT_RD`** + + Disables further receive operations. + +- **`__WASI_SHUT_WR`** + + Disables further send operations. + +### `__wasi_siflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +Used by [`__wasi_sock_send()`](#sock_send). + +### `__wasi_signal_t` (`uint8_t`) + +Signal condition. + +Used by [`__wasi_proc_raise()`](#proc_raise). + +Possible values: + +- **`__WASI_SIGABRT`** + + Process abort signal. + + Action: Terminates the process. + +- **`__WASI_SIGALRM`** + + Alarm clock. + + Action: Terminates the process. + +- **`__WASI_SIGBUS`** + + Access to an undefined portion of a memory object. + + Action: Terminates the process. + +- **`__WASI_SIGCHLD`** + + Child process terminated, stopped, or continued. + + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGFPE`** + + Erroneous arithmetic operation. + + Action: Terminates the process. + +- **`__WASI_SIGHUP`** + + Hangup. + + Action: Terminates the process. + +- **`__WASI_SIGILL`** + + Illegal instruction. + + Action: Terminates the process. + +- **`__WASI_SIGINT`** + + Terminate interrupt signal. + + Action: Terminates the process. + +- **`__WASI_SIGKILL`** + + Kill. + + Action: Terminates the process. + +- **`__WASI_SIGPIPE`** + + Write on a pipe with no one to read it. + + Action: Ignored. + +- **`__WASI_SIGQUIT`** + + Terminal quit signal. + + Action: Terminates the process. + +- **`__WASI_SIGSEGV`** + + Invalid memory reference. + + Action: Terminates the process. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. + +- **`__WASI_SIGSYS`** + + Bad system call. + + Action: Terminates the process. + +- **`__WASI_SIGTERM`** + + Termination signal. + + Action: Terminates the process. + +- **`__WASI_SIGTRAP`** + + Trace/breakpoint trap. + + Action: Terminates the process. + +- **`__WASI_SIGTSTP`** + + Terminal stop signal. + + Action: Stops executing. + +- **`__WASI_SIGTTIN`** + + Background process attempting read. + + Action: Stops executing. + +- **`__WASI_SIGTTOU`** + + Background process attempting write. + + Action: Stops executing. + +- **`__WASI_SIGURG`** + + High bandwidth data is available at a socket. + + Action: Ignored. + +- **`__WASI_SIGUSR1`** + + User-defined signal 1. + + Action: Terminates the process. + +- **`__WASI_SIGUSR2`** + + User-defined signal 2. + + Action: Terminates the process. + +- **`__WASI_SIGVTALRM`** + + Virtual timer expired. + + Action: Terminates the process. + +- **`__WASI_SIGXCPU`** + + CPU time limit exceeded. + + Action: Terminates the process. + +- **`__WASI_SIGXFSZ`** + + File size limit exceeded. + + Action: Terminates the process. + +### `__wasi_subclockflags_t` (`uint16_t` bitfield) + +Flags determining how to interpret the timestamp provided in +[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +Used by [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** + + If set, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp + of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + + If clear, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current + time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + +### `__wasi_subscription_t` (`struct`) + +Subscription to an event. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that is attached to the subscription in the + implementation and returned through + [`__wasi_event_t::userdata`](#event.userdata). + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event to which to subscribe. + +- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): + + - **`u.clock`** + + - [\_\_wasi\_userdata\_t](#userdata) identifier + + The user-defined unique identifier of the clock. + + - [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock against which to compare the timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) timeout + + The absolute or relative timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) precision + + The amount of time that the implementation may wait additionally + to coalesce with other events. + + - [\_\_wasi\_subclockflags\_t](#subclockflags) flags + + Flags specifying whether the timeout is absolute or relative. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor on which to wait for it to become ready + for reading or writing. + +### `__wasi_timestamp_t` (`uint64_t`) + +Timestamp in nanoseconds. + +Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +### `__wasi_userdata_t` (`uint64_t`) + +User-provided value that may be attached to objects that is +retained when extracted from the implementation. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +### `__wasi_whence_t` (`uint8_t`) + +The position relative to which to set the offset of the file descriptor. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +Possible values: + +- **`__WASI_WHENCE_CUR`** + + Seek relative to current position. + +- **`__WASI_WHENCE_END`** + + Seek relative to end-of-file. + +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + diff --git a/proposals/clocks/phases/unstable/witx/typenames.witx b/proposals/clocks/phases/unstable/witx/typenames.witx new file mode 100644 index 000000000..e04a188d9 --- /dev/null +++ b/proposals/clocks/phases/unstable/witx/typenames.witx @@ -0,0 +1,752 @@ +;; Type names used by low-level WASI interfaces. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(typename $size_t u32) + +;; Non-negative file size or length of a region within a file. +(typename $filesize_t u64) + +;; Timestamp in nanoseconds. +(typename $timestamp_t u64) + +;; Identifiers for clocks. +(typename $clockid_t + (enum u32 + ;; The store-wide monotonic clock, which is defined as a clock measuring + ;; real time, whose value cannot be adjusted and which cannot have negative + ;; clock jumps. The epoch of this clock is undefined. The absolute time + ;; value of this clock therefore has no meaning. + $CLOCK_MONOTONIC + ;; The CPU-time clock associated with the current process. + $CLOCK_PROCESS_CPUTIME_ID + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME + ;; The CPU-time clock associated with the current thread. + $CLOCK_THREAD_CPUTIME_ID + ) +) + +;; Error codes returned by functions. +;; Not all of these error codes are returned by the functions provided by this +;; API; some are used in higher-level library layers, and others are provided +;; merely for alignment with POSIX. +(typename $errno_t + (enum u16 + ;; No error occurred. System call completed successfully. + $ESUCCESS + ;; Argument list too long. + $E2BIG + ;; Permission denied. + $EACCES + ;; Address in use. + $EADDRINUSE + ;; Address not available. + $EADDRNOTAVAIL + ;; Address family not supported. + $EAFNOSUPPORT + ;; Resource unavailable, or operation would block. + $EAGAIN + ;; Connection already in progress. + $EALREADY + ;; Bad file descriptor. + $EBADF + ;; Bad message. + $EBADMSG + ;; Device or resource busy. + $EBUSY + ;; Operation canceled. + $ECANCELED + ;; No child processes. + $ECHILD + ;; Connection aborted. + $ECONNABORTED + ;; Connection refused. + $ECONNREFUSED + ;; Connection reset. + $ECONNRESET + ;; Resource deadlock would occur. + $EDEADLK + ;; Destination address required. + $EDESTADDRREQ + ;; Mathematics argument out of domain of function. + $EDOM + ;; Reserved. + $EDQUOT + ;; File exists. + $EEXIST + ;; Bad address. + $EFAULT + ;; File too large. + $EFBIG + ;; Host is unreachable. + $EHOSTUNREACH + ;; Identifier removed. + $EIDRM + ;; Illegal byte sequence. + $EILSEQ + ;; Operation in progress. + $EINPROGRESS + ;; Interrupted function. + $EINTR + ;; Invalid argument. + $EINVAL + ;; I/O error. + $EIO + ;; Socket is connected. + $EISCONN + ;; Is a directory. + $EISDIR + ;; Too many levels of symbolic links. + $ELOOP + ;; File descriptor value too large. + $EMFILE + ;; Too many links. + $EMLINK + ;; Message too large. + $EMSGSIZE + ;; Reserved. + $EMULTIHOP + ;; Filename too long. + $ENAMETOOLONG + ;; Network is down. + $ENETDOWN + ;; Connection aborted by network. + $ENETRESET + ;; Network unreachable. + $ENETUNREACH + ;; Too many files open in system. + $ENFILE + ;; No buffer space available. + $ENOBUFS + ;; No such device. + $ENODEV + ;; No such file or directory. + $ENOENT + ;; Executable file format error. + $ENOEXEC + ;; No locks available. + $ENOLCK + ;; Reserved. + $ENOLINK + ;; Not enough space. + $ENOMEM + ;; No message of the desired type. + $ENOMSG + ;; Protocol not available. + $ENOPROTOOPT + ;; No space left on device. + $ENOSPC + ;; Function not supported. + $ENOSYS + ;; The socket is not connected. + $ENOTCONN + ;; Not a directory or a symbolic link to a directory. + $ENOTDIR + ;; Directory not empty. + $ENOTEMPTY + ;; State not recoverable. + $ENOTRECOVERABLE + ;; Not a socket. + $ENOTSOCK + ;; Not supported, or operation not supported on socket. + $ENOTSUP + ;; Inappropriate I/O control operation. + $ENOTTY + ;; No such device or address. + $ENXIO + ;; Value too large to be stored in data type. + $EOVERFLOW + ;; Previous owner died. + $EOWNERDEAD + ;; Operation not permitted. + $EPERM + ;; Broken pipe. + $EPIPE + ;; Protocol error. + $EPROTO + ;; Protocol not supported. + $EPROTONOSUPPORT + ;; Protocol wrong type for socket. + $EPROTOTYPE + ;; Result too large. + $ERANGE + ;; Read-only file system. + $EROFS + ;; Invalid seek. + $ESPIPE + ;; No such process. + $ESRCH + ;; Reserved. + $ESTALE + ;; Connection timed out. + $ETIMEDOUT + ;; Text file busy. + $ETXTBSY + ;; Cross-device link. + $EXDEV + ;; Extension: Capabilities insufficient. + $ENOTCAPABLE + ) +) + +;; File descriptor rights, determining which actions may be performed. +(typename $rights_t + (flags u64 + ;; The right to invoke `fd_datasync`. + ;; + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_DSYNC`. + (flag $RIGHT_FD_DATASYNC) + ;; The right to invoke `fd_read` and `sock_recv`. + ;; + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + (flag $RIGHT_FD_READ) + ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + (flag $RIGHT_FD_SEEK) + ;; The right to invoke `fd_fdstat_set_flags`. + (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + ;; The right to invoke `fd_sync`. + ;; + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + (flag $RIGHT_FD_SYNC) + ;; The right to invoke `fd_seek` in such a way that the file offset + ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;; invoke `fd_tell`. + (flag $RIGHT_FD_TELL) + ;; The right to invoke `fd_write` and `sock_send`. + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + (flag $RIGHT_FD_WRITE) + ;; The right to invoke `fd_advise`. + (flag $RIGHT_FD_ADVISE) + ;; The right to invoke `fd_allocate`. + (flag $RIGHT_FD_ALLOCATE) + ;; The right to invoke `path_create_directory`. + (flag $RIGHT_PATH_CREATE_DIRECTORY) + ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + (flag $RIGHT_PATH_CREATE_FILE) + ;; The right to invoke `path_link` with the file descriptor as the + ;; source directory. + (flag $RIGHT_PATH_LINK_SOURCE) + ;; The right to invoke `path_link` with the file descriptor as the + ;; target directory. + (flag $RIGHT_PATH_LINK_TARGET) + ;; The right to invoke `path_open`. + (flag $RIGHT_PATH_OPEN) + ;; The right to invoke `fd_readdir`. + (flag $RIGHT_FD_READDIR) + ;; The right to invoke `path_readlink`. + (flag $RIGHT_PATH_READLINK) + ;; The right to invoke `path_rename` with the file descriptor as the source directory. + (flag $RIGHT_PATH_RENAME_SOURCE) + ;; The right to invoke `path_rename` with the file descriptor as the target directory. + (flag $RIGHT_PATH_RENAME_TARGET) + ;; The right to invoke `path_filestat_get`. + (flag $RIGHT_PATH_FILESTAT_GET) + ;; The right to change a file's size (there is no `path_filestat_set_size`). + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + ;; The right to invoke `path_filestat_set_times`. + (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + ;; The right to invoke `fd_filestat_get`. + (flag $RIGHT_FD_FILESTAT_GET) + ;; The right to invoke `fd_filestat_set_size`. + (flag $RIGHT_FD_FILESTAT_SET_SIZE) + ;; The right to invoke `fd_filestat_set_times`. + (flag $RIGHT_FD_FILESTAT_SET_TIMES) + ;; The right to invoke `path_symlink`. + (flag $RIGHT_PATH_SYMLINK) + ;; The right to invoke `path_unlink_file`. + (flag $RIGHT_PATH_UNLINK_FILE) + ;; The right to invoke `path_remove_directory`. + (flag $RIGHT_PATH_REMOVE_DIRECTORY) + ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + (flag $RIGHT_POLL_FD_READWRITE) + ;; The right to invoke `sock_shutdown`. + (flag $RIGHT_SOCK_SHUTDOWN) + ) +) + +;; A file descriptor index. +(typename $fd_t u32) + +;; A region of memory for scatter/gather reads. +(typename $iovec_t + (struct + ;; The address of the buffer to be filled. + (field $buf (@witx pointer u8)) + ;; The length of the buffer to be filled. + (field $buf_len $size_t) + ) +) + +;; A region of memory for scatter/gather writes. +(typename $ciovec_t + (struct + ;; The address of the buffer to be written. + (field $buf (@witx const_pointer u8)) + ;; The length of the buffer to be written. + (field $buf_len $size_t) + ) +) + +(typename $iovec_t_array (array $iovec_t)) +(typename $ciovec_t_array (array $ciovec_t)) + +;; Relative offset within a file. +(typename $filedelta_t s64) + +;; The position relative to which to set the offset of the file descriptor. +(typename $whence_t + (enum u8 + ;; Seek relative to current position. + $WHENCE_CUR + ;; Seek relative to end-of-file. + $WHENCE_END + ;; Seek relative to start-of-file. + $WHENCE_SET + ) +) + +;; A reference to the offset of a directory entry. +(typename $dircookie_t u64) + +;; The type for the $d_namlen field of $dirent_t. +(typename $dirnamlen_t u32) + +;; File serial number that is unique within its file system. +(typename $inode_t u64) + +;; The type of a file descriptor or file. +(typename $filetype_t + (enum u8 + ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $FILETYPE_UNKNOWN + ;; The file descriptor or file refers to a block device inode. + $FILETYPE_BLOCK_DEVICE + ;; The file descriptor or file refers to a character device inode. + $FILETYPE_CHARACTER_DEVICE + ;; The file descriptor or file refers to a directory inode. + $FILETYPE_DIRECTORY + ;; The file descriptor or file refers to a regular file inode. + $FILETYPE_REGULAR_FILE + ;; The file descriptor or file refers to a datagram socket. + $FILETYPE_SOCKET_DGRAM + ;; The file descriptor or file refers to a byte-stream socket. + $FILETYPE_SOCKET_STREAM + ;; The file refers to a symbolic link inode. + $FILETYPE_SYMBOLIC_LINK + ) +) + +;; A directory entry. +(typename $dirent_t + (struct + ;; The offset of the next directory entry stored in this directory. + (field $d_next $dircookie_t) + ;; The serial number of the file referred to by this directory entry. + (field $d_ino $inode_t) + ;; The length of the name of the directory entry. + (field $d_namlen $dirnamlen_t) + ;; The type of the file referred to by this directory entry. + (field $d_type $filetype_t) + ) +) + +;; File or memory access pattern advisory information. +(typename $advice_t + (enum u8 + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE + ;; The application has no advice to give on its behavior with respect to the specified data. + $ADVICE_NORMAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM + ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in the near future. + $ADVICE_WILLNEED + ) +) + +;; File descriptor flags. +(typename $fdflags_t + (flags u16 + ;; Append mode: Data written to the file is always appended to the file's end. + (flag $FDFLAG_APPEND) + ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + (flag $FDFLAG_DSYNC) + ;; Non-blocking mode. + (flag $FDFLAG_NONBLOCK) + ;; Synchronized read I/O operations. + (flag $FDFLAG_RSYNC) + ;; Write according to synchronized I/O file integrity completion. In + ;; addition to synchronizing the data stored in the file, the implementation + ;; may also synchronously update the file's metadata. + (flag $FDFLAG_SYNC) + ) +) + +;; File descriptor attributes. +(typename $fdstat_t + (struct + ;; File type. + (field $fs_filetype $filetype_t) + ;; File descriptor flags. + (field $fs_flags $fdflags_t) + ;; Rights that apply to this file descriptor. + (field $fs_rights_base $rights_t) + ;; Maximum set of rights that may be installed on new file descriptors that + ;; are created through this file descriptor, e.g., through `path_open`. + (field $fs_rights_inheriting $rights_t) + ) +) + +;; Identifier for a device containing a file system. Can be used in combination +;; with `inode_t` to uniquely identify a file or directory in the filesystem. +(typename $device_t u64) + +;; Which file time attributes to adjust. +(typename $fstflags_t + (flags u16 + ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + (flag $FILESTAT_SET_ATIM) + ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + (flag $FILESTAT_SET_ATIM_NOW) + ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + (flag $FILESTAT_SET_MTIM) + ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + (flag $FILESTAT_SET_MTIM_NOW) + ) +) + +;; Flags determining the method of how paths are resolved. +(typename $lookupflags_t + (flags u32 + ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + (flag $LOOKUP_SYMLINK_FOLLOW) + ) +) + +;; Open flags used by `path_open`. +(typename $oflags_t + (flags u16 + ;; Create file if it does not exist. + (flag $O_CREAT) + ;; Fail if not a directory. + (flag $O_DIRECTORY) + ;; Fail if file already exists. + (flag $O_EXCL) + ;; Truncate file to size 0. + (flag $O_TRUNC) + ) +) + +;; Number of hard links to an inode. +(typename $linkcount_t u32) + +;; File attributes. +(typename $filestat_t + (struct + ;; Device ID of device containing the file. + (field $st_dev $device_t) + ;; File serial number. + (field $st_ino $inode_t) + ;; File type. + (field $st_filetype $filetype_t) + ;; Number of hard links to the file. + (field $st_nlink $linkcount_t) + ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + (field $st_size $filesize_t) + ;; Last data access timestamp. + (field $st_atim $timestamp_t) + ;; Last data modification timestamp. + (field $st_mtim $timestamp_t) + ;; Last file status change timestamp. + (field $st_ctim $timestamp_t) + ) +) + +;; User-provided value that may be attached to objects that is retained when +;; extracted from the implementation. +(typename $userdata_t u64) + +;; Type of a subscription to an event or its occurrence. +(typename $eventtype_t + (flags u8 + ;; The time value of clock `subscription_t::u.clock.clock_id` has + ;; reached timestamp `subscription_t::u.clock.timeout`. + (flag $EVENTTYPE_CLOCK) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;; available for reading. This event always triggers for regular files. + (flag $EVENTTYPE_FD_READ) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;; available for writing. This event always triggers for regular files. + (flag $EVENTTYPE_FD_WRITE) + ) +) + +;; The state of the file descriptor subscribed to with +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $eventrwflags_t + (flags u16 + ;; The peer of this socket has closed or disconnected. + (flag $EVENT_FD_READWRITE_HANGUP) + ) +) + +;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;; `EVENTTYPE_FD_WRITE`. +(typename $event_fd_readwrite_t + (struct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) + ) +) + +;; The contents of an $event_t. +(typename $event_u + (union + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $event_fd_readwrite_t) + ) +) + +;; An event that occurred. +(typename $event_t + (struct + ;; User-provided value that got attached to `subscription_t::userdata`. + (field $userdata $userdata_t) + ;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno_t) + ;; The type of the event that occurred. + (field $type $eventtype_t) + ;; The contents of the event. + (field $u $event_u) + ) +) + +;; Flags determining how to interpret the timestamp provided in +;; `subscription_t::u.clock.timeout.` +(typename $subclockflags_t + (flags u16 + ;; If set, treat the timestamp provided in + ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;; provided in `subscription_t::u.clock.timeout` relative to the + ;; current time value of clock `subscription_t::u.clock.clock_id.` + (flag $SUBSCRIPTION_CLOCK_ABSTIME) + ) +) + +;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +(typename $subscription_clock_t + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) +) + +;; The contents of a $subscription_t when type is type is +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $subscription_fd_readwrite_t + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) + ) +) + +;; The contents of a $subscription_t. +(typename $subscription_u + (union + ;; When type is `EVENTTYPE_CLOCK`: + (field $clock $subscription_clock_t) + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $subscription_fd_readwrite_t) + ) +) + +;; Subscription to an event. +(typename $subscription_t + (struct + ;; User-provided value that is attached to the subscription in the + ;; implementation and returned through `event_t::userdata`. + (field $userdata $userdata_t) + ;; The type of the event to which to subscribe. + (field $type $eventtype_t) + ;; The contents of the subscription. + (field $u $subscription_u) + ) +) + +;; Exit code generated by a process when exiting. +(typename $exitcode_t u32) + +;; Signal condition. +(typename $signal_t + (enum u8 + ;; Process abort signal. + ;; Action: Terminates the process. + $SIGABRT + ;; Alarm clock. + ;; Action: Terminates the process. + $SIGALRM + ;; Access to an undefined portion of a memory object. + ;; Action: Terminates the process. + $SIGBUS + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT + ;; Erroneous arithmetic operation. + ;; Action: Terminates the process. + $SIGFPE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Kill. + ;; Action: Terminates the process. + $SIGKILL + ;; Write on a pipe with no one to read it. + ;; Action: Ignored. + $SIGPIPE + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Invalid memory reference. + ;; Action: Terminates the process. + $SIGSEGV + ;; Stop executing. + ;; Action: Stops executing. + $SIGSTOP + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS + ;; Termination signal. + ;; Action: Terminates the process. + $SIGTERM + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP + ;; Terminal stop signal. + ;; Action: Stops executing. + $SIGTSTP + ;; Background process attempting read. + ;; Action: Stops executing. + $SIGTTIN + ;; Background process attempting write. + ;; Action: Stops executing. + $SIGTTOU + ;; High bandwidth data is available at a socket. + ;; Action: Ignored. + $SIGURG + ;; User-defined signal 1. + ;; Action: Terminates the process. + $SIGUSR1 + ;; User-defined signal 2. + ;; Action: Terminates the process. + $SIGUSR2 + ;; Virtual timer expired. + ;; Action: Terminates the process. + $SIGVTALRM + ;; CPU time limit exceeded. + ;; Action: Terminates the process. + $SIGXCPU + ;; File size limit exceeded. + ;; Action: Terminates the process. + $SIGXFSZ + ) +) + +;; Flags provided to `sock_recv`. +(typename $riflags_t + (flags u16 + ;; Returns the message without removing it from the socket's receive queue. + (flag $SOCK_RECV_PEEK) + ;; On byte-stream sockets, block until the full amount of data can be returned. + (flag $SOCK_RECV_WAITALL) + ) +) + +;; Flags returned by `sock_recv`. +(typename $roflags_t + (flags u16 + ;; Returned by `sock_recv`: Message data has been truncated. + (flag $SOCK_RECV_DATA_TRUNCATED) + ) +) + +;; Flags provided to `sock_send`. As there are currently no flags +;; defined, it must be set to zero. +(typename $siflags_t u16) + +;; Which channels on a socket to shut down. +(typename $sdflags_t + (flags u8 + ;; Disables further receive operations. + (flag $SHUT_RD) + ;; Disables further send operations. + (flag $SHUT_WR) + ) +) + +;; Identifiers for preopened capabilities. +(typename $preopentype_t + (enum u8 + ;; A pre-opened directory. + $PREOPENTYPE_DIR + ) +) + +;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +(typename $prestat_dir + (struct + ;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size_t) + ) +) + +;; The contents of an $prestat_t. +(typename $prestat_u + (union + ;; When type is `PREOPENTYPE_DIR`: + (field $dir $prestat_dir) + ) +) + +;; Information about a pre-opened capability. +(typename $prestat_t + (struct + ;; The type of the pre-opened capability. + (field $pr_type $preopentype_t) + ;; The contents of the information. + (field $u $prestat_u) + ) +) diff --git a/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx new file mode 100644 index 000000000..08efc87fa --- /dev/null +++ b/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx @@ -0,0 +1,526 @@ +;; WASI Preview. This is an evolution of the API that WASI initially +;; launched with. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_unstable_preview0 + ;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;; Read command-line argument data. + ;; The size of the array should match that returned by `wasi_args_sizes_get()` + (@interface func (export "args_get") + (param $argv (@witx pointer (@witx pointer u8))) + (param $argv_buf (@witx pointer u8)) + (result $error $errno_t) + ) + ;; Return command-line argument data sizes. + (@interface func (export "args_sizes_get") + (result $error $errno_t) + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Read environment variable data. + ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + (@interface func (export "environ_get") + (param $environ (@witx pointer (@witx pointer u8))) + (param $environ_buf (@witx pointer u8)) + (result $error $errno_t) + ) + ;; Return command-line argument data sizes. + (@interface func (export "environ_sizes_get") + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Return the resolution of a clock. + ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;; Note: This is similar to `clock_getres` in POSIX. + (@interface func (export "clock_res_get") + (result $error $errno_t) + ;; The clock for which to return the resolution. + (param $clock_id $clockid_t) + ;; The resolution of the clock. + (result $resolution $timestamp_t) + ) + ;; Return the time value of a clock. + ;; Note: This is similar to `clock_gettime` in POSIX. + (@interface func (export "clock_time_get") + ;; The clock for which to return the time. + (param $clock_id $clockid_t) + ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp_t) + (result $error $errno_t) + ;; The time value of the clock. + (result $time $timestamp_t) + ) + + ;; Provide file advisory information on a file descriptor. + ;; Note: This is similar to `posix_fadvise` in POSIX. + (@interface func (export "fd_advise") + (param $fd $fd_t) + (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. + (param $len $filesize_t) ;; The length of the region to which the advisory applies. + (param $advice $advice_t) ;; The advice. + (result $error $errno_t) + ) + + ;; Force the allocation of space in a file. + ;; Note: This is similar to `posix_fallocate` in POSIX. + (@interface func (export "fd_allocate") + (param $fd $fd_t) + ;; The offset at which to start the allocation. + (param $offset $filesize_t) + ;; The length of the area that is allocated. + (param $len $filesize_t) + (result $error $errno_t) + ) + + ;; Close a file descriptor. + ;; Note: This is similar to `close` in POSIX. + (@interface func (export "fd_close") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Synchronize the data of a file to disk. + ;; Note: This is similar to `fdatasync` in POSIX. + (@interface func (export "fd_datasync") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Get the attributes of a file descriptor. + ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (@interface func (export "fd_fdstat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the file descriptor's attributes are stored. + (result $stat $fdstat_t) + ) + + ;; Adjust the flags associated with a file descriptor. + ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (@interface func (export "fd_fdstat_set_flags") + (param $fd $fd_t) + ;; The desired values of the file descriptor flags. + (param $flags $fdflags_t) + (result $error $errno_t) + ) + + ;; Adjust the rights associated with a file descriptor. + ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (@interface func (export "fd_fdstat_set_rights") + (param $fd $fd_t) + ;; The desired rights of the file descriptor. + (param $fs_rights_base $rights_t) + (param $fs_rights_inheriting $rights_t) + (result $error $errno_t) + ) + + ;; Return the attributes of an open file. + (@interface func (export "fd_filestat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $fs_rights_base $rights_t) + ) + + ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;; Note: This is similar to `ftruncate` in POSIX. + (@interface func (export "fd_filestat_set_size") + (param $fd $fd_t) + ;; The desired file size. + (param $st_size $filesize_t) + (result $error $errno_t) + ) + + ;; Adjust the timestamps of an open file or directory. + ;; Note: This is similar to `futimens` in POSIX. + (@interface func (export "fd_filestat_set_times") + (param $fd $fd_t) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `preadv` in POSIX. + (@interface func (export "fd_pread") + (param $fd $fd_t) + ;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to read. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the description is stored. + (result $buf $prestat_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_dir_name") + (param $fd $fd_t) + ;; A buffer into which to write the preopened directory name. + (param $path (@witx pointer u8)) + (param $path_len $size_t) + (result $error $errno_t) + ) + + ;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `pwritev` in POSIX. + (@interface func (export "fd_pwrite") + (param $fd $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_t_array) + ;; The offset within the file at which to write. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Read from a file descriptor. + ;; Note: This is similar to `readv` in POSIX. + (@interface func (export "fd_read") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Read directory entries from a directory. + ;; When successful, the contents of the output buffer consist of a sequence of + ;; directory entries. Each directory entry consists of a dirent_t object, + ;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;; entry. + ;; + ;; This function fills the output buffer as much as possible, potentially + ;; truncating the last directory entry. This allows the caller to grow its + ;; read buffer size in case it's too small to fit a single large directory + ;; entry, or skip the oversized directory entry. + (@interface func (export "fd_readdir") + (param $fd $fd_t) + ;; The buffer where directory entries are stored + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + ;; The location within the directory to start reading + (param $cookie $dircookie_t) + (result $error $errno_t) + ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size_t) + ) + + ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; + ;; Due to the strong focus on thread safety, this environment does not provide + ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;; file descriptor with the same number could be allocated by a different + ;; thread at the same time. + ;; + ;; This function provides a way to atomically renumber file descriptors, which + ;; would disappear if `dup2()` were to be removed entirely. + (@interface func (export "fd_renumber") + (param $fd $fd_t) + ;; The file descriptor to overwrite. + (param $to $fd_t) + (result $error $errno_t) + ) + + ;; Move the offset of a file descriptor. + ;; Note: This is similar to `lseek` in POSIX. + (@interface func (export "fd_seek") + (param $fd $fd_t) + ;; The number of bytes to move. + (param $offset $filedelta_t) + ;; The base from which the offset is relative. + (param $whence $whence_t) + (result $error $errno_t) + ;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize_t) + ) + + ;; Synchronize the data and metadata of a file to disk. + ;; Note: This is similar to `fsync` in POSIX. + (@interface func (export "fd_sync") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Return the current offset of a file descriptor. + ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (@interface func (export "fd_tell") + (param $fd $fd_t) + (result $error $errno_t) + ;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize_t) + ) + + ;; Write to a file descriptor. + ;; Note: This is similar to `writev` in POSIX. + (@interface func (export "fd_write") + (param $fd $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_t_array) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Create a directory. + ;; Note: This is similar to `mkdirat` in POSIX. + (@interface func (export "path_create_directory") + (param $fd $fd_t) + ;; The path at which to create the directory. + (param $path string) + (result $error $errno_t) + ) + + ;; Return the attributes of a file or directory. + ;; Note: This is similar to `stat` in POSIX. + (@interface func (export "path_filestat_get") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $buf $filestat_t) + ) + + ;; Adjust the timestamps of a file or directory. + ;; Note: This is similar to `utimensat` in POSIX. + (@interface func (export "path_filestat_set_times") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to operate on. + (param $path string) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Create a hard link. + ;; Note: This is similar to `linkat` in POSIX. + (@interface func (export "path_link") + (param $old_fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags_t) + ;; The source path from which to link. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd_t) + ;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Open a file or directory. + ;; + ;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;; file descriptor not currently open; it is randomized to prevent + ;; applications from depending on making assumptions about indexes, since this + ;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;; guaranteed to be less than 2**31. + ;; + ;; Note: This is similar to `openat` in POSIX. + (@interface func (export "path_open") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags_t) + ;; The relative path of the file or directory to open, relative to the + ;; `dirfd` directory. + (param $path string) + ;; The method by which to open the file. + (param $o_flags $oflags_t) + ;; The initial rights of the newly created file descriptor. The + ;; implementation is allowed to return a file descriptor with fewer rights + ;; than specified, if and only if those rights do not apply to the type of + ;; file being opened. + ;; + ;; The base rights are rights that will apply to operations using the file + ;; descriptor itself, while the inheriting rights are rights that apply to + ;; file descriptors derived from it. + (param $fs_rights_base $rights_t) + (param $fs_rights_inherting $rights_t) + (result $error $errno_t) + ;; The file descriptor of the file that has been opened. + (result $opened_fd $fd_t) + ) + + ;; Read the contents of a symbolic link. + ;; Note: This is similar to `readlinkat` in POSIX. + (@interface func (export "path_readlink") + (param $fd $fd_t) + ;; The path of the symbolic link from which to read. + (param $path string) + ;; The buffer to which to write the contents of the symbolic link. + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + (result $error $errno_t) + ;; The number of bytes placed in the buffer. + (result $bufused $size_t) + ) + + ;; Remove a directory. + ;; Return `ENOTEMPTY` if the directory is not empty. + ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (@interface func (export "path_remove_directory") + (param $fd $fd_t) + ;; The path to a directory to remove. + (param $path string) + (result $error $errno_t) + ) + + ;; Rename a file or directory. + ;; Note: This is similar to `renameat` in POSIX. + (@interface func (export "path_rename") + (param $fd $fd_t) + ;; The source path of the file or directory to rename. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd_t) + ;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Create a symbolic link. + ;; Note: This is similar to `symlinkat` in POSIX. + (@interface func (export "path_symlink") + (param $fd $fd_t) + ;; The contents of the symbolic link. + (param $old_path string) + ;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno_t) + ) + + + ;; Unlink a file. + ;; Return `EISDIR` if the path refers to a directory. + ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (@interface func (export "path_unlink_file") + (param $fd $fd_t) + ;; The path to a file to unlink. + (param $path string) + (result $error $errno_t) + ) + + ;; Concurrently poll for the occurrence of a set of events. + (@interface func (export "poll_oneoff") + ;; The events to which to subscribe. + (param $in (@witx const_pointer $subscription_t)) + ;; The events that have occurred. + (param $out (@witx pointer $event_t)) + ;; Both the number of subscriptions and events. + (param $nsubscriptions $size_t) + (result $error $errno_t) + ;; The number of events stored. + (result $nevents $size_t) + ) + + ;; Terminate the process normally. An exit code of 0 indicates successful + ;; termination of the program. The meanings of other values is dependent on + ;; the environment. + (@interface func (export "proc_exit") + ;; The exit code returned by the process. + (param $rval $exitcode_t) + ) + + ;; Send a signal to the process of the calling thread. + ;; Note: This is similar to `raise` in POSIX. + (@interface func (export "proc_raise") + ;; The signal condition to trigger. + (param $sig $signal_t) + (result $error $errno_t) + ) + + ;; Temporarily yield execution of the calling thread. + ;; Note: This is similar to `sched_yield` in POSIX. + (@interface func (export "proc_sched_yield") + (result $error $errno_t) + ) + + ;; Write high-quality random data into a buffer. + ;; This function blocks when the implementation is unable to immediately + ;; provide sufficient high-quality random data. + ;; This function may execute slowly, so when large mounts of random data are + ;; required, it's advisable to use this function to seed a pseudo-random + ;; number generator, rather than to provide the random data directly. + (@interface func (export "random_get") + ;; The buffer to fill with random data. + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + (result $error $errno_t) + ) + + ;; Receive a message from a socket. + ;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;; the data into multiple buffers in the manner of `readv`. + (@interface func (export "sock_recv") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_t_array) + ;; Message flags. + (param $ri_flags $riflags_t) + (result $error $errno_t) + ;; Number of bytes stored in ri_data. + (result $ro_datalen $size_t) + ;; Message flags. + (result $ro_flags $roflags_t) + ) + + ;; Send a message on a socket. + ;; Note: This is similar to `send` in POSIX, though it also supports writing + ;; the data from multiple buffers in the manner of `writev`. + (@interface func (export "sock_send") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_t_array) + ;; Message flags. + (param $si_flags $siflags_t) + (result $error $errno_t) + ;; Number of bytes transmitted. + (result $so_datalen $size_t) + ) + + ;; Shut down socket send and receive channels. + ;; Note: This is similar to `shutdown` in POSIX. + (@interface func (export "sock_shutdown") + (param $fd $fd_t) + ;; Which channels on the socket to shut down. + (param $how $sdflags_t) + (result $error $errno_t) + ) +) From cde962505ce6f236e7d79165317e771d30a9c1d7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 18 Sep 2019 12:51:09 -0700 Subject: [PATCH 0167/1772] Create a phased structure for API development (#88) * Create a structure for phased development. This PR takes the `witx` concept from #74 and creates a directory structure around it for enabling phased development of new APIs and changes to existing APIs. See the README.md changes for details. * Apply the validation fix from #90 to the new copies. --- proposals/random/README.md | 2 + proposals/random/phases/README.md | 53 + .../ephemeral/docs/wasi_ephemeral_preview.md} | 16 +- .../ephemeral/witx}/typenames.witx | 2 +- .../witx/wasi_ephemeral_preview.witx | 526 ++++ .../phases/old/docs/wasi_unstable_preview0.md | 2319 +++++++++++++++++ .../random/phases/old/witx/typenames.witx | 752 ++++++ .../old/witx}/wasi_unstable.witx | 6 +- .../unstable/docs/wasi_unstable_preview0.md | 2319 +++++++++++++++++ .../phases/unstable/witx/typenames.witx | 752 ++++++ .../unstable/witx/wasi_unstable_preview0.witx | 526 ++++ 11 files changed, 7265 insertions(+), 8 deletions(-) create mode 100644 proposals/random/phases/README.md rename proposals/random/{design/WASI-core.md => phases/ephemeral/docs/wasi_ephemeral_preview.md} (99%) rename proposals/random/{design/wasi_unstable => phases/ephemeral/witx}/typenames.witx (99%) create mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx create mode 100644 proposals/random/phases/old/docs/wasi_unstable_preview0.md create mode 100644 proposals/random/phases/old/witx/typenames.witx rename proposals/random/{design/wasi_unstable => phases/old/witx}/wasi_unstable.witx (98%) create mode 100644 proposals/random/phases/unstable/docs/wasi_unstable_preview0.md create mode 100644 proposals/random/phases/unstable/witx/typenames.witx create mode 100644 proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx diff --git a/proposals/random/README.md b/proposals/random/README.md index 7fc421229..31bb340e1 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -22,3 +22,5 @@ discussions. Schedules and agendas for video conference and in-person meetings are posted [here](meetings/README.md). + +API specification proposals are [here](phases/README.md). diff --git a/proposals/random/phases/README.md b/proposals/random/phases/README.md new file mode 100644 index 000000000..00d49afef --- /dev/null +++ b/proposals/random/phases/README.md @@ -0,0 +1,53 @@ +# WASI development process + +## WASI uses a 3-phase process: + +- [`ephemeral`](ephemeral): The development staging area. New API + proposals API-changing fixes to existing APIs should be submitted + as Pull Requests making changes to this directory. This directory + provides no API stability or versioning. APIs in this directory use + API module names starting with `wasi_ephemeral_`. + +- [`unstable`](unstable): Usable APIs. APIs in `ephemeral` will be + occasionally snapshotted and promoted into `unstable`, with approval + from the Subgroup, considering the overall suitability of the APIs + themselves, their documentation, test coverage, and availability of + polyfills when appropriate. Once merged, the API modules will be + considered stable, though they may be superseded by newer versions. + Proposals to promote specific APIs should be submitted as Pull Requests + that: + - Move any superseded files out of `unstable` into `old`. + - Optionally add polyfills for superseded APIs using `unstable` APIs. + - Move all files supporting the APIs out of `ephemeral into `unstable`. + - Rename the API modules from `wasi_ephemeral_` to `wasi_unstable_` + and append a version number. + + Pull Requests may also add additional tests, documentation, or + polyfills for existing `unstable` APIs. + +- [`old`](old): When APIs in `current` spec are replaced by new + versions, the old API modules are moved to the `old` directory. When + possible, `old` APIs may be accompanied by polyfill modules which + implement their API in terms of newer versions of the API. + +## Rationale + +### Relationship to the CG's phases + +When WASI becomes more mature, such that we have an established base +and we're adding incremental functionality to it, we may want to adopt +a process like [the CG's phases]. However, right now, everything in +WASI is undergoing changes, so we have a greater need to iterate with +flexibility. + +### Relationship to standards + +WASI should eventually become a standard at the level of WebAssembly +itself. Right now, it needs a lot of work before it's ready. The +`unstable` tree is meant to serve a practical purpose for people who +want to work with APIs today, with the understanding that everything +is still evolving. It's not meant as a replacement for proper +standardization, which will happen once the overall API is more +mature. + +[the CG's phases]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md diff --git a/proposals/random/design/WASI-core.md b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md similarity index 99% rename from proposals/random/design/WASI-core.md rename to proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md index c4b256ad3..9db4a382e 100644 --- a/proposals/random/design/WASI-core.md +++ b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -34,13 +34,12 @@ This file is automatically generated. Do not edit. Source: https://github.com/NuxiNL/cloudabi --> -# WASI Core API +# The WASI Preview API -This is the API-level documentation for WASI Core. The function names +This is the API-level documentation for WASI Preview. The function names are prefixed with "\_\_wasi\_" to reflect how they are spelled in flat-namespace contexts, however at the wasm module level, they are -unprefixed, because they're inside a module namespace (currently -"wasi\_unstable"). +unprefixed, because they're inside a module namespace. Functions that start with `__wasi_fd_` operate on file descriptors, while functions that start with `__wasi_path_` operate on filesystem @@ -48,16 +47,21 @@ paths, which are relative to directory file descriptors. Much inspiration and content here is derived from [CloudABI] and [POSIX], though there are also several differences from CloudABI and POSIX. For -example, WASI Core has no concept of processes in the traditional Unix +example, WASI Preview has no concept of processes in the traditional Unix sense. While wasm linear memories have some of the aspects of processes, and it's possible to *emulate* the full semantics of processes on top of them, this can sometimes be unnatural and inefficient. The goal for -WASI Core is to be a WebAssembly-native API that exposes APIs that fit +WASI Preview is to be a WebAssembly-native API that exposes APIs that fit well into the underlying WebAssembly platform, rather than to directly emulate other platforms. This is also a work in progress, and the API here is still evolving. +Historical note: this API was originally named "WASI Core", and used the +API module name "wasi\_unstable". We've since sought to deemphasize the +"Core" name, as the goal is to split this API up into independent +modules so that embedders need not implement all of it. + [CloudABI]: https://github.com/NuxiNL/cloudabi [POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ diff --git a/proposals/random/design/wasi_unstable/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx similarity index 99% rename from proposals/random/design/wasi_unstable/typenames.witx rename to proposals/random/phases/ephemeral/witx/typenames.witx index 046ed0bf6..e04a188d9 100644 --- a/proposals/random/design/wasi_unstable/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -1,4 +1,4 @@ -;; Type names used by the wasi_unstable module type. +;; Type names used by low-level WASI interfaces. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). ;; diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx new file mode 100644 index 000000000..4f31fe510 --- /dev/null +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -0,0 +1,526 @@ +;; WASI Preview. This is an evolution of the API that WASI initially +;; launched with. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_preview + ;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;; Read command-line argument data. + ;; The size of the array should match that returned by `wasi_args_sizes_get()` + (@interface func (export "args_get") + (param $argv (@witx pointer (@witx pointer u8))) + (param $argv_buf (@witx pointer u8)) + (result $error $errno_t) + ) + ;; Return command-line argument data sizes. + (@interface func (export "args_sizes_get") + (result $error $errno_t) + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Read environment variable data. + ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + (@interface func (export "environ_get") + (param $environ (@witx pointer (@witx pointer u8))) + (param $environ_buf (@witx pointer u8)) + (result $error $errno_t) + ) + ;; Return command-line argument data sizes. + (@interface func (export "environ_sizes_get") + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Return the resolution of a clock. + ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;; Note: This is similar to `clock_getres` in POSIX. + (@interface func (export "clock_res_get") + (result $error $errno_t) + ;; The clock for which to return the resolution. + (param $clock_id $clockid_t) + ;; The resolution of the clock. + (result $resolution $timestamp_t) + ) + ;; Return the time value of a clock. + ;; Note: This is similar to `clock_gettime` in POSIX. + (@interface func (export "clock_time_get") + ;; The clock for which to return the time. + (param $clock_id $clockid_t) + ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp_t) + (result $error $errno_t) + ;; The time value of the clock. + (result $time $timestamp_t) + ) + + ;; Provide file advisory information on a file descriptor. + ;; Note: This is similar to `posix_fadvise` in POSIX. + (@interface func (export "fd_advise") + (param $fd $fd_t) + (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. + (param $len $filesize_t) ;; The length of the region to which the advisory applies. + (param $advice $advice_t) ;; The advice. + (result $error $errno_t) + ) + + ;; Force the allocation of space in a file. + ;; Note: This is similar to `posix_fallocate` in POSIX. + (@interface func (export "fd_allocate") + (param $fd $fd_t) + ;; The offset at which to start the allocation. + (param $offset $filesize_t) + ;; The length of the area that is allocated. + (param $len $filesize_t) + (result $error $errno_t) + ) + + ;; Close a file descriptor. + ;; Note: This is similar to `close` in POSIX. + (@interface func (export "fd_close") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Synchronize the data of a file to disk. + ;; Note: This is similar to `fdatasync` in POSIX. + (@interface func (export "fd_datasync") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Get the attributes of a file descriptor. + ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (@interface func (export "fd_fdstat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the file descriptor's attributes are stored. + (result $stat $fdstat_t) + ) + + ;; Adjust the flags associated with a file descriptor. + ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (@interface func (export "fd_fdstat_set_flags") + (param $fd $fd_t) + ;; The desired values of the file descriptor flags. + (param $flags $fdflags_t) + (result $error $errno_t) + ) + + ;; Adjust the rights associated with a file descriptor. + ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (@interface func (export "fd_fdstat_set_rights") + (param $fd $fd_t) + ;; The desired rights of the file descriptor. + (param $fs_rights_base $rights_t) + (param $fs_rights_inheriting $rights_t) + (result $error $errno_t) + ) + + ;; Return the attributes of an open file. + (@interface func (export "fd_filestat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $fs_rights_base $rights_t) + ) + + ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;; Note: This is similar to `ftruncate` in POSIX. + (@interface func (export "fd_filestat_set_size") + (param $fd $fd_t) + ;; The desired file size. + (param $st_size $filesize_t) + (result $error $errno_t) + ) + + ;; Adjust the timestamps of an open file or directory. + ;; Note: This is similar to `futimens` in POSIX. + (@interface func (export "fd_filestat_set_times") + (param $fd $fd_t) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `preadv` in POSIX. + (@interface func (export "fd_pread") + (param $fd $fd_t) + ;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to read. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the description is stored. + (result $buf $prestat_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_dir_name") + (param $fd $fd_t) + ;; A buffer into which to write the preopened directory name. + (param $path (@witx pointer u8)) + (param $path_len $size_t) + (result $error $errno_t) + ) + + ;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `pwritev` in POSIX. + (@interface func (export "fd_pwrite") + (param $fd $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_t_array) + ;; The offset within the file at which to write. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Read from a file descriptor. + ;; Note: This is similar to `readv` in POSIX. + (@interface func (export "fd_read") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Read directory entries from a directory. + ;; When successful, the contents of the output buffer consist of a sequence of + ;; directory entries. Each directory entry consists of a dirent_t object, + ;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;; entry. + ;; + ;; This function fills the output buffer as much as possible, potentially + ;; truncating the last directory entry. This allows the caller to grow its + ;; read buffer size in case it's too small to fit a single large directory + ;; entry, or skip the oversized directory entry. + (@interface func (export "fd_readdir") + (param $fd $fd_t) + ;; The buffer where directory entries are stored + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + ;; The location within the directory to start reading + (param $cookie $dircookie_t) + (result $error $errno_t) + ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size_t) + ) + + ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; + ;; Due to the strong focus on thread safety, this environment does not provide + ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;; file descriptor with the same number could be allocated by a different + ;; thread at the same time. + ;; + ;; This function provides a way to atomically renumber file descriptors, which + ;; would disappear if `dup2()` were to be removed entirely. + (@interface func (export "fd_renumber") + (param $fd $fd_t) + ;; The file descriptor to overwrite. + (param $to $fd_t) + (result $error $errno_t) + ) + + ;; Move the offset of a file descriptor. + ;; Note: This is similar to `lseek` in POSIX. + (@interface func (export "fd_seek") + (param $fd $fd_t) + ;; The number of bytes to move. + (param $offset $filedelta_t) + ;; The base from which the offset is relative. + (param $whence $whence_t) + (result $error $errno_t) + ;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize_t) + ) + + ;; Synchronize the data and metadata of a file to disk. + ;; Note: This is similar to `fsync` in POSIX. + (@interface func (export "fd_sync") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Return the current offset of a file descriptor. + ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (@interface func (export "fd_tell") + (param $fd $fd_t) + (result $error $errno_t) + ;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize_t) + ) + + ;; Write to a file descriptor. + ;; Note: This is similar to `writev` in POSIX. + (@interface func (export "fd_write") + (param $fd $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_t_array) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Create a directory. + ;; Note: This is similar to `mkdirat` in POSIX. + (@interface func (export "path_create_directory") + (param $fd $fd_t) + ;; The path at which to create the directory. + (param $path string) + (result $error $errno_t) + ) + + ;; Return the attributes of a file or directory. + ;; Note: This is similar to `stat` in POSIX. + (@interface func (export "path_filestat_get") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $buf $filestat_t) + ) + + ;; Adjust the timestamps of a file or directory. + ;; Note: This is similar to `utimensat` in POSIX. + (@interface func (export "path_filestat_set_times") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to operate on. + (param $path string) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Create a hard link. + ;; Note: This is similar to `linkat` in POSIX. + (@interface func (export "path_link") + (param $old_fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags_t) + ;; The source path from which to link. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd_t) + ;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Open a file or directory. + ;; + ;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;; file descriptor not currently open; it is randomized to prevent + ;; applications from depending on making assumptions about indexes, since this + ;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;; guaranteed to be less than 2**31. + ;; + ;; Note: This is similar to `openat` in POSIX. + (@interface func (export "path_open") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags_t) + ;; The relative path of the file or directory to open, relative to the + ;; `dirfd` directory. + (param $path string) + ;; The method by which to open the file. + (param $o_flags $oflags_t) + ;; The initial rights of the newly created file descriptor. The + ;; implementation is allowed to return a file descriptor with fewer rights + ;; than specified, if and only if those rights do not apply to the type of + ;; file being opened. + ;; + ;; The base rights are rights that will apply to operations using the file + ;; descriptor itself, while the inheriting rights are rights that apply to + ;; file descriptors derived from it. + (param $fs_rights_base $rights_t) + (param $fs_rights_inherting $rights_t) + (result $error $errno_t) + ;; The file descriptor of the file that has been opened. + (result $opened_fd $fd_t) + ) + + ;; Read the contents of a symbolic link. + ;; Note: This is similar to `readlinkat` in POSIX. + (@interface func (export "path_readlink") + (param $fd $fd_t) + ;; The path of the symbolic link from which to read. + (param $path string) + ;; The buffer to which to write the contents of the symbolic link. + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + (result $error $errno_t) + ;; The number of bytes placed in the buffer. + (result $bufused $size_t) + ) + + ;; Remove a directory. + ;; Return `ENOTEMPTY` if the directory is not empty. + ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (@interface func (export "path_remove_directory") + (param $fd $fd_t) + ;; The path to a directory to remove. + (param $path string) + (result $error $errno_t) + ) + + ;; Rename a file or directory. + ;; Note: This is similar to `renameat` in POSIX. + (@interface func (export "path_rename") + (param $fd $fd_t) + ;; The source path of the file or directory to rename. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd_t) + ;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Create a symbolic link. + ;; Note: This is similar to `symlinkat` in POSIX. + (@interface func (export "path_symlink") + (param $fd $fd_t) + ;; The contents of the symbolic link. + (param $old_path string) + ;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno_t) + ) + + + ;; Unlink a file. + ;; Return `EISDIR` if the path refers to a directory. + ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (@interface func (export "path_unlink_file") + (param $fd $fd_t) + ;; The path to a file to unlink. + (param $path string) + (result $error $errno_t) + ) + + ;; Concurrently poll for the occurrence of a set of events. + (@interface func (export "poll_oneoff") + ;; The events to which to subscribe. + (param $in (@witx const_pointer $subscription_t)) + ;; The events that have occurred. + (param $out (@witx pointer $event_t)) + ;; Both the number of subscriptions and events. + (param $nsubscriptions $size_t) + (result $error $errno_t) + ;; The number of events stored. + (result $nevents $size_t) + ) + + ;; Terminate the process normally. An exit code of 0 indicates successful + ;; termination of the program. The meanings of other values is dependent on + ;; the environment. + (@interface func (export "proc_exit") + ;; The exit code returned by the process. + (param $rval $exitcode_t) + ) + + ;; Send a signal to the process of the calling thread. + ;; Note: This is similar to `raise` in POSIX. + (@interface func (export "proc_raise") + ;; The signal condition to trigger. + (param $sig $signal_t) + (result $error $errno_t) + ) + + ;; Temporarily yield execution of the calling thread. + ;; Note: This is similar to `sched_yield` in POSIX. + (@interface func (export "proc_sched_yield") + (result $error $errno_t) + ) + + ;; Write high-quality random data into a buffer. + ;; This function blocks when the implementation is unable to immediately + ;; provide sufficient high-quality random data. + ;; This function may execute slowly, so when large mounts of random data are + ;; required, it's advisable to use this function to seed a pseudo-random + ;; number generator, rather than to provide the random data directly. + (@interface func (export "random_get") + ;; The buffer to fill with random data. + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + (result $error $errno_t) + ) + + ;; Receive a message from a socket. + ;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;; the data into multiple buffers in the manner of `readv`. + (@interface func (export "sock_recv") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_t_array) + ;; Message flags. + (param $ri_flags $riflags_t) + (result $error $errno_t) + ;; Number of bytes stored in ri_data. + (result $ro_datalen $size_t) + ;; Message flags. + (result $ro_flags $roflags_t) + ) + + ;; Send a message on a socket. + ;; Note: This is similar to `send` in POSIX, though it also supports writing + ;; the data from multiple buffers in the manner of `writev`. + (@interface func (export "sock_send") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_t_array) + ;; Message flags. + (param $si_flags $siflags_t) + (result $error $errno_t) + ;; Number of bytes transmitted. + (result $so_datalen $size_t) + ) + + ;; Shut down socket send and receive channels. + ;; Note: This is similar to `shutdown` in POSIX. + (@interface func (export "sock_shutdown") + (param $fd $fd_t) + ;; Which channels on the socket to shut down. + (param $how $sdflags_t) + (result $error $errno_t) + ) +) diff --git a/proposals/random/phases/old/docs/wasi_unstable_preview0.md b/proposals/random/phases/old/docs/wasi_unstable_preview0.md new file mode 100644 index 000000000..9db4a382e --- /dev/null +++ b/proposals/random/phases/old/docs/wasi_unstable_preview0.md @@ -0,0 +1,2319 @@ + + +# The WASI Preview API + +This is the API-level documentation for WASI Preview. The function names +are prefixed with "\_\_wasi\_" to reflect how they are spelled in +flat-namespace contexts, however at the wasm module level, they are +unprefixed, because they're inside a module namespace. + +Functions that start with `__wasi_fd_` operate on file descriptors, +while functions that start with `__wasi_path_` operate on filesystem +paths, which are relative to directory file descriptors. + +Much inspiration and content here is derived from [CloudABI] and [POSIX], +though there are also several differences from CloudABI and POSIX. For +example, WASI Preview has no concept of processes in the traditional Unix +sense. While wasm linear memories have some of the aspects of processes, +and it's possible to *emulate* the full semantics of processes on top of +them, this can sometimes be unnatural and inefficient. The goal for +WASI Preview is to be a WebAssembly-native API that exposes APIs that fit +well into the underlying WebAssembly platform, rather than to directly +emulate other platforms. + +This is also a work in progress, and the API here is still evolving. + +Historical note: this API was originally named "WASI Core", and used the +API module name "wasi\_unstable". We've since sought to deemphasize the +"Core" name, as the goal is to split this API up into independent +modules so that embedders need not implement all of it. + +[CloudABI]: https://github.com/NuxiNL/cloudabi +[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ + +## System calls + +- [`__wasi_args_get()`](#args_get) +- [`__wasi_args_sizes_get()`](#args_sizes_get) +- [`__wasi_clock_res_get()`](#clock_res_get) +- [`__wasi_clock_time_get()`](#clock_time_get) +- [`__wasi_environ_get()`](#environ_get) +- [`__wasi_environ_sizes_get()`](#environ_sizes_get) +- [`__wasi_fd_advise()`](#fd_advise) +- [`__wasi_fd_allocate()`](#fd_allocate) +- [`__wasi_fd_close()`](#fd_close) +- [`__wasi_fd_datasync()`](#fd_datasync) +- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) +- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) +- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) +- [`__wasi_fd_filestat_get()`](#fd_filestat_get) +- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) +- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) +- [`__wasi_fd_pread()`](#fd_pread) +- [`__wasi_fd_prestat_get()`](#fd_prestat_get) +- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) +- [`__wasi_fd_pwrite()`](#fd_pwrite) +- [`__wasi_fd_read()`](#fd_read) +- [`__wasi_fd_readdir()`](#fd_readdir) +- [`__wasi_fd_renumber()`](#fd_renumber) +- [`__wasi_fd_seek()`](#fd_seek) +- [`__wasi_fd_sync()`](#fd_sync) +- [`__wasi_fd_tell()`](#fd_tell) +- [`__wasi_fd_write()`](#fd_write) +- [`__wasi_path_create_directory()`](#path_create_directory) +- [`__wasi_path_filestat_get()`](#path_filestat_get) +- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) +- [`__wasi_path_link()`](#path_link) +- [`__wasi_path_open()`](#path_open) +- [`__wasi_path_readlink()`](#path_readlink) +- [`__wasi_path_remove_directory()`](#path_remove_directory) +- [`__wasi_path_rename()`](#path_rename) +- [`__wasi_path_symlink()`](#path_symlink) +- [`__wasi_path_unlink_file()`](#path_unlink_file) +- [`__wasi_poll_oneoff()`](#poll_oneoff) +- [`__wasi_proc_exit()`](#proc_exit) +- [`__wasi_proc_raise()`](#proc_raise) +- [`__wasi_random_get()`](#random_get) +- [`__wasi_sched_yield()`](#sched_yield) +- [`__wasi_sock_recv()`](#sock_recv) +- [`__wasi_sock_send()`](#sock_send) +- [`__wasi_sock_shutdown()`](#sock_shutdown) + +### `__wasi_args_get()` + +Read command-line argument data. + +The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + +Inputs: + +- char \*\*argv + + A pointer to a buffer to write the argument pointers. + +- char \*argv\_buf + + A pointer to a buffer to write the argument string data. + +### `__wasi_args_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*argc + + The number of arguments. + +- size\_t \*argv\_buf\_size + + The size of the argument string data. + +### `__wasi_clock_res_get()` + +Return the resolution of a clock. + +Implementations are required to provide a non-zero value for supported clocks. +For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). + +Note: This is similar to `clock_getres` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the resolution. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) resolution + + The resolution of the clock. + +### `__wasi_clock_time_get()` + +Return the time value of a clock. + +Note: This is similar to `clock_gettime` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the time. + +- [\_\_wasi\_timestamp\_t](#timestamp) precision + + The maximum lag (exclusive) that the returned + time value may have, compared to its actual + value. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) time + + The time value of the clock. + +### `__wasi_environ_get()` + +Read environment variable data. + +The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + +Inputs: + +- char \*\*environ + + A pointer to a buffer to write the environment variable pointers. + +- char \*environ\_buf + + A pointer to a buffer to write the environment variable string data. + +### `__wasi_environ_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*environ\_count + + The number of environment variables. + +- size\_t \*environ\_buf\_size + + The size of the environment variable string data. + +### `__wasi_fd_advise()` + +Provide file advisory information on a file descriptor. + +Note: This is similar to `posix_fadvise` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file for which to provide file advisory information. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file to which the advisory applies. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the region to which the advisory applies. + +- [\_\_wasi\_advice\_t](#advice) advice + + The advice. + +### `__wasi_fd_allocate()` + +Force the allocation of space in a file. + +Note: This is similar to `posix_fallocate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file in which to allocate space. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset at which to start the allocation. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the area that is allocated. + +### `__wasi_fd_close()` + +Close a file descriptor. + +Note: This is similar to `close` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to close. + +### `__wasi_fd_datasync()` + +Synchronize the data of a file to disk. + +Note: This is similar to `fdatasync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file to synchronize to disk. + +### `__wasi_fd_fdstat_get()` + +Get the attributes of a file descriptor. + +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well +as additional fields. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_fdstat\_t](#fdstat) \*buf + + The buffer where the file descriptor's attributes are stored. + +### `__wasi_fd_fdstat_set_flags()` + +Adjust the flags associated with a file descriptor. + +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_fdflags\_t](#fdflags) flags + + The desired values of the file descriptor + flags. + +### `__wasi_fd_fdstat_set_rights()` + +Adjust the rights associated with a file descriptor. + +This can only be used to remove rights, and returns +[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt +to add rights. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The desired rights of the file descriptor. + +### `__wasi_fd_filestat_get()` + +Return the attributes of an open file. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_fd_filestat_set_size()` + +Adjust the size of an open file. If this increases the file's size, the extra +bytes are filled with zeros. + +Note: This is similar to `ftruncate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + A file descriptor for the file to adjust. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + The desired file size. + +### `__wasi_fd_filestat_set_times()` + +Adjust the timestamps of an open file or directory. + +Note: This is similar to `futimens` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_fd_pread()` + +Read from a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `preadv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors in which to store data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to read. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_prestat_get()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- [\_\_wasi\_prestat\_t](#prestat) \*buf + + The buffer where the description is stored. + +### `__wasi_fd_prestat_dir_name()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- const char \*path and size\_t path\_len + + A buffer into which to write the preopened directory name. + +### `__wasi_fd_pwrite()` + +Write to a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `pwritev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to write. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_fd_read()` + +Read from a file descriptor. + +Note: This is similar to `readv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors to which to store data. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_readdir()` + +Read directory entries from a directory. + +When successful, the contents of the output buffer consist of +a sequence of directory entries. Each directory entry consists +of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes +holding the name of the directory entry. + +This function fills the output buffer as much as possible, +potentially truncating the last directory entry. This allows +the caller to grow its read buffer size in case it's too small +to fit a single large directory entry, or skip the oversized +directory entry. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The directory from which to read the directory + entries. + +- void \*buf and size\_t buf\_len + + The buffer where directory entries are stored. + +- [\_\_wasi\_dircookie\_t](#dircookie) cookie + + The location within the directory to start + reading. + +Outputs: + +- size\_t bufused + + The number of bytes stored in the read buffer. + If less than the size of the read buffer, the + end of the directory has been reached. + +### `__wasi_fd_renumber()` + +Atomically replace a file descriptor by renumbering another +file descriptor. + +Due to the strong focus on thread safety, this environment +does not provide a mechanism to duplicate or renumber a file +descriptor to an arbitrary number, like dup2(). This would be +prone to race conditions, as an actual file descriptor with the +same number could be allocated by a different thread at the same +time. + +This function provides a way to atomically renumber file +descriptors, which would disappear if dup2() were to be +removed entirely. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) from + + The file descriptor to renumber. + +- [\_\_wasi\_fd\_t](#fd) to + + The file descriptor to overwrite. + +### `__wasi_fd_seek()` + +Move the offset of a file descriptor. + +Note: This is similar to `lseek` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_filedelta\_t](#filedelta) offset + + The number of bytes to move. + +- [\_\_wasi\_whence\_t](#whence) whence + + The base from which the offset is relative. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) newoffset + + The new offset of the file descriptor, + relative to the start of the file. + +### `__wasi_fd_sync()` + +Synchronize the data and metadata of a file to disk. + +Note: This is similar to `fsync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file containing the data + and metadata to synchronize to disk. + +### `__wasi_fd_tell()` + +Return the current offset of a file descriptor. + +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The current offset of the file descriptor, relative to the start of the file. + +### `__wasi_fd_write()` + +Write to a file descriptor. + +Note: This is similar to `writev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_path_create_directory()` + +Create a directory. + +Note: This is similar to `mkdirat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path at which to create the directory. + +### `__wasi_path_filestat_get()` + +Return the attributes of a file or directory. + +Note: This is similar to `stat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_path_filestat_set_times()` + +Adjust the timestamps of a file or directory. + +Note: This is similar to `utimensat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_path_link()` + +Create a hard link. + +Note: This is similar to `linkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags + + Flags determining the method of how the path is resolved. + +- const char \*old\_path and size\_t old\_path\_len + + The source path from which to link. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the hard link. + +### `__wasi_path_open()` + +Open a file or directory. + +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since +this is error-prone in multi-threaded contexts. The returned file +descriptor is guaranteed to be less than 231. + +Note: This is similar to `openat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) dirfd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The relative path of the file or directory to open, relative to + the [`dirfd`](#path_open.dirfd) directory. + +- [\_\_wasi\_oflags\_t](#oflags) o_flags + + The method by which to open the file. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The initial rights of the newly created file descriptor. The + implementation is allowed to return a file descriptor with fewer + rights than specified, if and only if those rights do not apply + to the type of file being opened. + + The *base* rights are rights that will apply to operations using + the file descriptor itself, while the *inheriting* rights are + rights that apply to file descriptors derived from it. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + The initial flags of the file descriptor. + +Outputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file that has been + opened. + +### `__wasi_path_readlink()` + +Read the contents of a symbolic link. + +Note: This is similar to `readlinkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path of the symbolic link from which to read. + +- char \*buf and size\_t buf\_len + + The buffer to which to write the contents of the symbolic link. + +Outputs: + +- size\_t bufused + + The number of bytes placed in the buffer. + +### `__wasi_path_remove_directory()` + +Remove a directory. + +Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. + +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a directory to remove. + +### `__wasi_path_rename()` + +Rename a file or directory. + +Note: This is similar to `renameat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- const char \*old\_path and size\_t old\_path\_len + + The source path of the file or directory to rename. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path to which to rename the file or directory. + +### `__wasi_path_symlink()` + +Create a symbolic link. + +Note: This is similar to `symlinkat` in POSIX. + +Inputs: + +- const char \*old\_path and size\_t old_path\_len + + The contents of the symbolic link. + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the symbolic link. + +### `__wasi_path_unlink_file()` + +Unlink a file. + +Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. + +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a file to unlink. + +### `__wasi_poll_oneoff()` + +Concurrently poll for the occurrence of a set of events. + +Inputs: + +- const [\_\_wasi\_subscription\_t](#subscription) \*in + + The events to which to subscribe. + +- [\_\_wasi\_event\_t](#event) \*out + + The events that have occurred. + +- size\_t nsubscriptions + + Both the number of subscriptions and events. + +Outputs: + +- size\_t nevents + + The number of events stored. + +### `__wasi_proc_exit()` + +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +Note: This is similar to `_Exit` in POSIX. + +Inputs: + +- [\_\_wasi\_exitcode\_t](#exitcode) rval + + The exit code returned by the process. + +Does not return. + +### `__wasi_proc_raise()` + +Send a signal to the process of the calling thread. + +Note: This is similar to `raise` in POSIX. + +Inputs: + +- [\_\_wasi\_signal\_t](#signal) sig + + The signal condition to trigger. + +### `__wasi_random_get()` + +Write high-quality random data into a buffer. + +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. + +This function may execute slowly, so when large mounts of random +data are required, it's advisable to use this function to seed a +pseudo-random number generator, rather than to provide the +random data directly. + +Inputs: + +- void \*buf and size\_t buf\_len + + The buffer to fill with random data. + +### `__wasi_sched_yield()` + +Temporarily yield execution of the calling thread. + +Note: This is similar to `sched_yield` in POSIX. + +### `__wasi_sock_recv()` + +Receive a message from a socket. + +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to receive data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len + + List of scatter/gather vectors to which to store data. + +- [\_\_wasi\_riflags\_t](#riflags) ri\_flags + + Message flags. + +Outputs: + +- size\_t ro\_datalen + + Number of bytes stored in [`ri_data`](#sock_recv.ri_data). + +- [\_\_wasi\_roflags\_t](#roflags) ro\_flags + + Message flags. + +### `__wasi_sock_send()` + +Send a message on a socket. + +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to send data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len + + List of scatter/gather vectors to which to retrieve data + +- [\_\_wasi\_siflags\_t](#siflags) si\_flags + + Message flags. + +Outputs: + +- size\_t so\_datalen + + Number of bytes transmitted. + +### `__wasi_sock_shutdown()` + +Shut down socket send and receive channels. + +Note: This is similar to `shutdown` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to shutdown channels. + +- [\_\_wasi\_sdflags\_t](#sdflags) how + + Which channels on the socket to shut down. + +## Types + +### `__wasi_advice_t` (`uint8_t`) + +File or memory access pattern advisory information. + +Used by [`__wasi_fd_advise()`](#fd_advise). + +Possible values: + +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + +- **`__WASI_ADVICE_NORMAL`** + + The application has no advice to give on its behavior + with respect to the specified data. + +- **`__WASI_ADVICE_RANDOM`** + + The application expects to access the specified data + in a random order. + +- **`__WASI_ADVICE_SEQUENTIAL`** + + The application expects to access the specified data + sequentially from lower offsets to higher offsets. + +- **`__WASI_ADVICE_WILLNEED`** + + The application expects to access the specified data + in the near future. + +### `__wasi_ciovec_t` (`struct`) + +A region of memory for scatter/gather writes. + +Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). + +Members: + +- const void \*buf and size\_t buf\_len + + The address and length of the buffer to be written. + +### `__wasi_clockid_t` (`uint32_t`) + +Identifiers for clocks. + +Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). + +Possible values: + +- **`__WASI_CLOCK_MONOTONIC`** + + The store-wide monotonic clock, which is defined as a + clock measuring real time, whose value cannot be + adjusted and which cannot have negative clock jumps. + + The epoch of this clock is undefined. The absolute + time value of this clock therefore has no meaning. + +- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** + + The CPU-time clock associated with the current + process. + +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + +- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** + + The CPU-time clock associated with the current thread. + +### `__wasi_device_t` (`uint64_t`) + +Identifier for a device containing a file system. Can be used +in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or +directory in the filesystem. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_dircookie_t` (`uint64_t`) + +A reference to the offset of a directory entry. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). + +Special values: + +- **`__WASI_DIRCOOKIE_START`** + + Permanent reference to the first directory entry + within a directory. + +### `__wasi_dirent_t` (`struct`) + +A directory entry. + +Members: + +- [\_\_wasi\_dircookie\_t](#dircookie) d\_next + + The offset of the next directory entry stored in this + directory. + +- [\_\_wasi\_inode\_t](#inode) d\_ino + + The serial number of the file referred to by this + directory entry. + +- uint32\_t d\_namlen + + The length of the name of the directory entry. + +- [\_\_wasi\_filetype\_t](#filetype) d\_type + + The type of the file referred to by this directory + entry. + +### `__wasi_errno_t` (`uint16_t`) + +Error codes returned by functions. + +Not all of these error codes are returned by the functions +provided by this API; some are used in higher-level library layers, +and others are provided merely for alignment with POSIX. + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_ESUCCESS`** + + No error occurred. System call completed successfully. + +- **`__WASI_E2BIG`** + + Argument list too long. + +- **`__WASI_EACCES`** + + Permission denied. + +- **`__WASI_EADDRINUSE`** + + Address in use. + +- **`__WASI_EADDRNOTAVAIL`** + + Address not available. + +- **`__WASI_EAFNOSUPPORT`** + + Address family not supported. + +- **`__WASI_EAGAIN`** + + Resource unavailable, or operation would block. + +- **`__WASI_EALREADY`** + + Connection already in progress. + +- **`__WASI_EBADF`** + + Bad file descriptor. + +- **`__WASI_EBADMSG`** + + Bad message. + +- **`__WASI_EBUSY`** + + Device or resource busy. + +- **`__WASI_ECANCELED`** + + Operation canceled. + +- **`__WASI_ECHILD`** + + No child processes. + +- **`__WASI_ECONNABORTED`** + + Connection aborted. + +- **`__WASI_ECONNREFUSED`** + + Connection refused. + +- **`__WASI_ECONNRESET`** + + Connection reset. + +- **`__WASI_EDEADLK`** + + Resource deadlock would occur. + +- **`__WASI_EDESTADDRREQ`** + + Destination address required. + +- **`__WASI_EDOM`** + + Mathematics argument out of domain of function. + +- **`__WASI_EDQUOT`** + + Reserved. + +- **`__WASI_EEXIST`** + + File exists. + +- **`__WASI_EFAULT`** + + Bad address. + +- **`__WASI_EFBIG`** + + File too large. + +- **`__WASI_EHOSTUNREACH`** + + Host is unreachable. + +- **`__WASI_EIDRM`** + + Identifier removed. + +- **`__WASI_EILSEQ`** + + Illegal byte sequence. + +- **`__WASI_EINPROGRESS`** + + Operation in progress. + +- **`__WASI_EINTR`** + + Interrupted function. + +- **`__WASI_EINVAL`** + + Invalid argument. + +- **`__WASI_EIO`** + + I/O error. + +- **`__WASI_EISCONN`** + + Socket is connected. + +- **`__WASI_EISDIR`** + + Is a directory. + +- **`__WASI_ELOOP`** + + Too many levels of symbolic links. + +- **`__WASI_EMFILE`** + + File descriptor value too large. + +- **`__WASI_EMLINK`** + + Too many links. + +- **`__WASI_EMSGSIZE`** + + Message too large. + +- **`__WASI_EMULTIHOP`** + + Reserved. + +- **`__WASI_ENAMETOOLONG`** + + Filename too long. + +- **`__WASI_ENETDOWN`** + + Network is down. + +- **`__WASI_ENETRESET`** + + Connection aborted by network. + +- **`__WASI_ENETUNREACH`** + + Network unreachable. + +- **`__WASI_ENFILE`** + + Too many files open in system. + +- **`__WASI_ENOBUFS`** + + No buffer space available. + +- **`__WASI_ENODEV`** + + No such device. + +- **`__WASI_ENOENT`** + + No such file or directory. + +- **`__WASI_ENOEXEC`** + + Executable file format error. + +- **`__WASI_ENOLCK`** + + No locks available. + +- **`__WASI_ENOLINK`** + + Reserved. + +- **`__WASI_ENOMEM`** + + Not enough space. + +- **`__WASI_ENOMSG`** + + No message of the desired type. + +- **`__WASI_ENOPROTOOPT`** + + Protocol not available. + +- **`__WASI_ENOSPC`** + + No space left on device. + +- **`__WASI_ENOSYS`** + + Function not supported. + +- **`__WASI_ENOTCONN`** + + The socket is not connected. + +- **`__WASI_ENOTDIR`** + + Not a directory or a symbolic link to a directory. + +- **`__WASI_ENOTEMPTY`** + + Directory not empty. + +- **`__WASI_ENOTRECOVERABLE`** + + State not recoverable. + +- **`__WASI_ENOTSOCK`** + + Not a socket. + +- **`__WASI_ENOTSUP`** + + Not supported, or operation not supported on socket. + +- **`__WASI_ENOTTY`** + + Inappropriate I/O control operation. + +- **`__WASI_ENXIO`** + + No such device or address. + +- **`__WASI_EOVERFLOW`** + + Value too large to be stored in data type. + +- **`__WASI_EOWNERDEAD`** + + Previous owner died. + +- **`__WASI_EPERM`** + + Operation not permitted. + +- **`__WASI_EPIPE`** + + Broken pipe. + +- **`__WASI_EPROTO`** + + Protocol error. + +- **`__WASI_EPROTONOSUPPORT`** + + Protocol not supported. + +- **`__WASI_EPROTOTYPE`** + + Protocol wrong type for socket. + +- **`__WASI_ERANGE`** + + Result too large. + +- **`__WASI_EROFS`** + + Read-only file system. + +- **`__WASI_ESPIPE`** + + Invalid seek. + +- **`__WASI_ESRCH`** + + No such process. + +- **`__WASI_ESTALE`** + + Reserved. + +- **`__WASI_ETIMEDOUT`** + + Connection timed out. + +- **`__WASI_ETXTBSY`** + + Text file busy. + +- **`__WASI_EXDEV`** + + Cross-device link. + +- **`__WASI_ENOTCAPABLE`** + + Extension: Capabilities insufficient. + +### `__wasi_event_t` (`struct`) + +An event that occurred. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that got attached to + [`__wasi_subscription_t::userdata`](#subscription.userdata). + +- [\_\_wasi\_errno\_t](#errno) error + + If non-zero, an error that occurred while processing + the subscription request. + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event that occurred. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_filesize\_t](#filesize) nbytes + + The number of bytes available for reading or writing. + + - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags + + The state of the file descriptor. + +### `__wasi_eventrwflags_t` (`uint16_t` bitfield) + +The state of the file descriptor subscribed to with +[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_EVENT_FD_READWRITE_HANGUP`** + + The peer of this socket has closed or disconnected. + +### `__wasi_eventtype_t` (`uint8_t`) + +Type of a subscription to an event or its occurrence. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_EVENTTYPE_CLOCK`** + + The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) + has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +- **`__WASI_EVENTTYPE_FD_READ`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + data available for reading. This event always triggers + for regular files. + +- **`__WASI_EVENTTYPE_FD_WRITE`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + capacity available for writing. This event always + triggers for regular files. + +### `__wasi_exitcode_t` (`uint32_t`) + +Exit code generated by a process when exiting. + +Used by [`__wasi_proc_exit()`](#proc_exit). + +### `__wasi_fd_t` (`uint32_t`) + +A file descriptor number. + +Used by many functions in this API. + +As in POSIX, three file descriptor numbers are provided to instances +on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, +and `STDERR_FILENO`). + +Other than these, WASI implementations are not required to allocate +new file descriptors in ascending order. + +### `__wasi_fdflags_t` (`uint16_t` bitfield) + +File descriptor flags. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_FDFLAG_APPEND`** + + Append mode: Data written to the file is always + appended to the file's end. + +- **`__WASI_FDFLAG_DSYNC`** + + Write according to synchronized I/O data integrity + completion. Only the data stored in the file is + synchronized. + +- **`__WASI_FDFLAG_NONBLOCK`** + + Non-blocking mode. + +- **`__WASI_FDFLAG_RSYNC`** + + Synchronized read I/O operations. + +- **`__WASI_FDFLAG_SYNC`** + + Write according to synchronized I/O file integrity completion. + In addition to synchronizing the data stored in the file, the + implementation may also synchronously update the file's metadata. + +### `__wasi_fdstat_t` (`struct`) + +File descriptor attributes. + +Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). + +Members: + +- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype + + File type. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + File descriptor flags. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base + + Rights that apply to this file descriptor. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + Maximum set of rights that may be installed on new + file descriptors that are created through this file + descriptor, e.g., through [`__wasi_path_open()`](#path_open). + +### `__wasi_filedelta_t` (`int64_t`) + +Relative offset within a file. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +### `__wasi_filesize_t` (`uint64_t`) + +Non-negative file size or length of a region within a file. + +Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +### `__wasi_filestat_t` (`struct`) + +File attributes. + +Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). + +Members: + +- [\_\_wasi\_device\_t](#device) st\_dev + + Device ID of device containing the file. + +- [\_\_wasi\_inode\_t](#inode) st\_ino + + File serial number. + +- [\_\_wasi\_filetype\_t](#filetype) st\_filetype + + File type. + +- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink + + Number of hard links to the file. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + For regular files, the file size in bytes. For + symbolic links, the length in bytes of the pathname + contained in the symbolic link. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + Last data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + Last data modification timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim + + Last file status change timestamp. + +### `__wasi_filetype_t` (`uint8_t`) + +The type of a file descriptor or file. + +Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). + +Possible values: + +- **`__WASI_FILETYPE_UNKNOWN`** + + The type of the file descriptor or file is unknown or + is different from any of the other types specified. + +- **`__WASI_FILETYPE_BLOCK_DEVICE`** + + The file descriptor or file refers to a block device + inode. + +- **`__WASI_FILETYPE_CHARACTER_DEVICE`** + + The file descriptor or file refers to a character + device inode. + +- **`__WASI_FILETYPE_DIRECTORY`** + + The file descriptor or file refers to a directory + inode. + +- **`__WASI_FILETYPE_REGULAR_FILE`** + + The file descriptor or file refers to a regular file + inode. + +- **`__WASI_FILETYPE_SOCKET_DGRAM`** + + The file descriptor or file refers to a datagram + socket. + +- **`__WASI_FILETYPE_SOCKET_STREAM`** + + The file descriptor or file refers to a byte-stream + socket. + +- **`__WASI_FILETYPE_SYMBOLIC_LINK`** + + The file refers to a symbolic link inode. + +### `__wasi_fstflags_t` (`uint16_t` bitfield) + +Which file time attributes to adjust. + +Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +Possible values: + +- **`__WASI_FILESTAT_SET_ATIM`** + + Adjust the last data access timestamp to the value + stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). + +- **`__WASI_FILESTAT_SET_ATIM_NOW`** + + Adjust the last data access timestamp to the time + of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +- **`__WASI_FILESTAT_SET_MTIM`** + + Adjust the last data modification timestamp to the + value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). + +- **`__WASI_FILESTAT_SET_MTIM_NOW`** + + Adjust the last data modification timestamp to the + time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +### `__wasi_inode_t` (`uint64_t`) + +File serial number that is unique within its file system. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). + +### `__wasi_iovec_t` (`struct`) + +A region of memory for scatter/gather reads. + +Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). + +Members: + +- void \*buf and size\_t buf\_len + + The address and length of the buffer to be filled. + +### `__wasi_linkcount_t` (`uint32_t`) + +Number of hard links to an inode. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_lookupflags_t` (`uint32_t` bitfield) + +Flags determining the method of how paths are resolved. + +Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** + + As long as the resolved path corresponds to a symbolic + link, it is expanded. + +### `__wasi_oflags_t` (`uint16_t` bitfield) + +Open flags used by [`__wasi_path_open()`](#path_open). + +Used by [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_O_CREAT`** + + Create file if it does not exist. + +- **`__WASI_O_DIRECTORY`** + + Fail if not a directory. + +- **`__WASI_O_EXCL`** + + Fail if file already exists. + +- **`__WASI_O_TRUNC`** + + Truncate file to size 0. + +### `__wasi_riflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_PEEK`** + + Returns the message without removing it from the + socket's receive queue. + +- **`__WASI_SOCK_RECV_WAITALL`** + + On byte-stream sockets, block until the full amount + of data can be returned. + +### `__wasi_rights_t` (`uint64_t` bitfield) + +File descriptor rights, determining which actions may be +performed. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_RIGHT_FD_DATASYNC`** + + The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_READ`** + + The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke + [`__wasi_fd_pread()`](#fd_pread). + +- **`__WASI_RIGHT_FD_SEEK`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies + [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). + +- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** + + The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). + +- **`__WASI_RIGHT_FD_SYNC`** + + The right to invoke [`__wasi_fd_sync()`](#fd_sync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and + [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_TELL`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the + file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with + offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). + +- **`__WASI_RIGHT_FD_WRITE`** + + The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to + invoke [`__wasi_fd_pwrite()`](#fd_pwrite). + +- **`__WASI_RIGHT_FD_ADVISE`** + + The right to invoke [`__wasi_fd_advise()`](#fd_advise). + +- **`__WASI_RIGHT_FD_ALLOCATE`** + + The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). + +- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** + + The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). + +- **`__WASI_RIGHT_PATH_CREATE_FILE`** + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke + [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). + +- **`__WASI_RIGHT_PATH_LINK_SOURCE`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_LINK_TARGET`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_OPEN`** + + The right to invoke [`__wasi_path_open()`](#path_open). + +- **`__WASI_RIGHT_FD_READDIR`** + + The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). + +- **`__WASI_RIGHT_PATH_READLINK`** + + The right to invoke [`__wasi_path_readlink()`](#path_readlink). + +- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_RENAME_TARGET`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_FILESTAT_GET`** + + The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** + + The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +- **`__WASI_RIGHT_FD_FILESTAT_GET`** + + The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** + + The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). + +- **`__WASI_RIGHT_PATH_SYMLINK`** + + The right to invoke [`__wasi_path_symlink()`](#path_symlink). + +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + +- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** + + The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). + +- **`__WASI_RIGHT_POLL_FD_READWRITE`** + + If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). + + If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +- **`__WASI_RIGHT_SOCK_SHUTDOWN`** + + The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). + +### `__wasi_roflags_t` (`uint16_t` bitfield) + +Flags returned by [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** + + Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been + truncated. + +### `__wasi_sdflags_t` (`uint8_t` bitfield) + +Which channels on a socket to shut down. + +Used by [`__wasi_sock_shutdown()`](#sock_shutdown). + +Possible values: + +- **`__WASI_SHUT_RD`** + + Disables further receive operations. + +- **`__WASI_SHUT_WR`** + + Disables further send operations. + +### `__wasi_siflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +Used by [`__wasi_sock_send()`](#sock_send). + +### `__wasi_signal_t` (`uint8_t`) + +Signal condition. + +Used by [`__wasi_proc_raise()`](#proc_raise). + +Possible values: + +- **`__WASI_SIGABRT`** + + Process abort signal. + + Action: Terminates the process. + +- **`__WASI_SIGALRM`** + + Alarm clock. + + Action: Terminates the process. + +- **`__WASI_SIGBUS`** + + Access to an undefined portion of a memory object. + + Action: Terminates the process. + +- **`__WASI_SIGCHLD`** + + Child process terminated, stopped, or continued. + + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGFPE`** + + Erroneous arithmetic operation. + + Action: Terminates the process. + +- **`__WASI_SIGHUP`** + + Hangup. + + Action: Terminates the process. + +- **`__WASI_SIGILL`** + + Illegal instruction. + + Action: Terminates the process. + +- **`__WASI_SIGINT`** + + Terminate interrupt signal. + + Action: Terminates the process. + +- **`__WASI_SIGKILL`** + + Kill. + + Action: Terminates the process. + +- **`__WASI_SIGPIPE`** + + Write on a pipe with no one to read it. + + Action: Ignored. + +- **`__WASI_SIGQUIT`** + + Terminal quit signal. + + Action: Terminates the process. + +- **`__WASI_SIGSEGV`** + + Invalid memory reference. + + Action: Terminates the process. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. + +- **`__WASI_SIGSYS`** + + Bad system call. + + Action: Terminates the process. + +- **`__WASI_SIGTERM`** + + Termination signal. + + Action: Terminates the process. + +- **`__WASI_SIGTRAP`** + + Trace/breakpoint trap. + + Action: Terminates the process. + +- **`__WASI_SIGTSTP`** + + Terminal stop signal. + + Action: Stops executing. + +- **`__WASI_SIGTTIN`** + + Background process attempting read. + + Action: Stops executing. + +- **`__WASI_SIGTTOU`** + + Background process attempting write. + + Action: Stops executing. + +- **`__WASI_SIGURG`** + + High bandwidth data is available at a socket. + + Action: Ignored. + +- **`__WASI_SIGUSR1`** + + User-defined signal 1. + + Action: Terminates the process. + +- **`__WASI_SIGUSR2`** + + User-defined signal 2. + + Action: Terminates the process. + +- **`__WASI_SIGVTALRM`** + + Virtual timer expired. + + Action: Terminates the process. + +- **`__WASI_SIGXCPU`** + + CPU time limit exceeded. + + Action: Terminates the process. + +- **`__WASI_SIGXFSZ`** + + File size limit exceeded. + + Action: Terminates the process. + +### `__wasi_subclockflags_t` (`uint16_t` bitfield) + +Flags determining how to interpret the timestamp provided in +[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +Used by [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** + + If set, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp + of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + + If clear, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current + time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + +### `__wasi_subscription_t` (`struct`) + +Subscription to an event. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that is attached to the subscription in the + implementation and returned through + [`__wasi_event_t::userdata`](#event.userdata). + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event to which to subscribe. + +- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): + + - **`u.clock`** + + - [\_\_wasi\_userdata\_t](#userdata) identifier + + The user-defined unique identifier of the clock. + + - [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock against which to compare the timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) timeout + + The absolute or relative timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) precision + + The amount of time that the implementation may wait additionally + to coalesce with other events. + + - [\_\_wasi\_subclockflags\_t](#subclockflags) flags + + Flags specifying whether the timeout is absolute or relative. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor on which to wait for it to become ready + for reading or writing. + +### `__wasi_timestamp_t` (`uint64_t`) + +Timestamp in nanoseconds. + +Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +### `__wasi_userdata_t` (`uint64_t`) + +User-provided value that may be attached to objects that is +retained when extracted from the implementation. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +### `__wasi_whence_t` (`uint8_t`) + +The position relative to which to set the offset of the file descriptor. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +Possible values: + +- **`__WASI_WHENCE_CUR`** + + Seek relative to current position. + +- **`__WASI_WHENCE_END`** + + Seek relative to end-of-file. + +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + diff --git a/proposals/random/phases/old/witx/typenames.witx b/proposals/random/phases/old/witx/typenames.witx new file mode 100644 index 000000000..e04a188d9 --- /dev/null +++ b/proposals/random/phases/old/witx/typenames.witx @@ -0,0 +1,752 @@ +;; Type names used by low-level WASI interfaces. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(typename $size_t u32) + +;; Non-negative file size or length of a region within a file. +(typename $filesize_t u64) + +;; Timestamp in nanoseconds. +(typename $timestamp_t u64) + +;; Identifiers for clocks. +(typename $clockid_t + (enum u32 + ;; The store-wide monotonic clock, which is defined as a clock measuring + ;; real time, whose value cannot be adjusted and which cannot have negative + ;; clock jumps. The epoch of this clock is undefined. The absolute time + ;; value of this clock therefore has no meaning. + $CLOCK_MONOTONIC + ;; The CPU-time clock associated with the current process. + $CLOCK_PROCESS_CPUTIME_ID + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME + ;; The CPU-time clock associated with the current thread. + $CLOCK_THREAD_CPUTIME_ID + ) +) + +;; Error codes returned by functions. +;; Not all of these error codes are returned by the functions provided by this +;; API; some are used in higher-level library layers, and others are provided +;; merely for alignment with POSIX. +(typename $errno_t + (enum u16 + ;; No error occurred. System call completed successfully. + $ESUCCESS + ;; Argument list too long. + $E2BIG + ;; Permission denied. + $EACCES + ;; Address in use. + $EADDRINUSE + ;; Address not available. + $EADDRNOTAVAIL + ;; Address family not supported. + $EAFNOSUPPORT + ;; Resource unavailable, or operation would block. + $EAGAIN + ;; Connection already in progress. + $EALREADY + ;; Bad file descriptor. + $EBADF + ;; Bad message. + $EBADMSG + ;; Device or resource busy. + $EBUSY + ;; Operation canceled. + $ECANCELED + ;; No child processes. + $ECHILD + ;; Connection aborted. + $ECONNABORTED + ;; Connection refused. + $ECONNREFUSED + ;; Connection reset. + $ECONNRESET + ;; Resource deadlock would occur. + $EDEADLK + ;; Destination address required. + $EDESTADDRREQ + ;; Mathematics argument out of domain of function. + $EDOM + ;; Reserved. + $EDQUOT + ;; File exists. + $EEXIST + ;; Bad address. + $EFAULT + ;; File too large. + $EFBIG + ;; Host is unreachable. + $EHOSTUNREACH + ;; Identifier removed. + $EIDRM + ;; Illegal byte sequence. + $EILSEQ + ;; Operation in progress. + $EINPROGRESS + ;; Interrupted function. + $EINTR + ;; Invalid argument. + $EINVAL + ;; I/O error. + $EIO + ;; Socket is connected. + $EISCONN + ;; Is a directory. + $EISDIR + ;; Too many levels of symbolic links. + $ELOOP + ;; File descriptor value too large. + $EMFILE + ;; Too many links. + $EMLINK + ;; Message too large. + $EMSGSIZE + ;; Reserved. + $EMULTIHOP + ;; Filename too long. + $ENAMETOOLONG + ;; Network is down. + $ENETDOWN + ;; Connection aborted by network. + $ENETRESET + ;; Network unreachable. + $ENETUNREACH + ;; Too many files open in system. + $ENFILE + ;; No buffer space available. + $ENOBUFS + ;; No such device. + $ENODEV + ;; No such file or directory. + $ENOENT + ;; Executable file format error. + $ENOEXEC + ;; No locks available. + $ENOLCK + ;; Reserved. + $ENOLINK + ;; Not enough space. + $ENOMEM + ;; No message of the desired type. + $ENOMSG + ;; Protocol not available. + $ENOPROTOOPT + ;; No space left on device. + $ENOSPC + ;; Function not supported. + $ENOSYS + ;; The socket is not connected. + $ENOTCONN + ;; Not a directory or a symbolic link to a directory. + $ENOTDIR + ;; Directory not empty. + $ENOTEMPTY + ;; State not recoverable. + $ENOTRECOVERABLE + ;; Not a socket. + $ENOTSOCK + ;; Not supported, or operation not supported on socket. + $ENOTSUP + ;; Inappropriate I/O control operation. + $ENOTTY + ;; No such device or address. + $ENXIO + ;; Value too large to be stored in data type. + $EOVERFLOW + ;; Previous owner died. + $EOWNERDEAD + ;; Operation not permitted. + $EPERM + ;; Broken pipe. + $EPIPE + ;; Protocol error. + $EPROTO + ;; Protocol not supported. + $EPROTONOSUPPORT + ;; Protocol wrong type for socket. + $EPROTOTYPE + ;; Result too large. + $ERANGE + ;; Read-only file system. + $EROFS + ;; Invalid seek. + $ESPIPE + ;; No such process. + $ESRCH + ;; Reserved. + $ESTALE + ;; Connection timed out. + $ETIMEDOUT + ;; Text file busy. + $ETXTBSY + ;; Cross-device link. + $EXDEV + ;; Extension: Capabilities insufficient. + $ENOTCAPABLE + ) +) + +;; File descriptor rights, determining which actions may be performed. +(typename $rights_t + (flags u64 + ;; The right to invoke `fd_datasync`. + ;; + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_DSYNC`. + (flag $RIGHT_FD_DATASYNC) + ;; The right to invoke `fd_read` and `sock_recv`. + ;; + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + (flag $RIGHT_FD_READ) + ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + (flag $RIGHT_FD_SEEK) + ;; The right to invoke `fd_fdstat_set_flags`. + (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + ;; The right to invoke `fd_sync`. + ;; + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + (flag $RIGHT_FD_SYNC) + ;; The right to invoke `fd_seek` in such a way that the file offset + ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;; invoke `fd_tell`. + (flag $RIGHT_FD_TELL) + ;; The right to invoke `fd_write` and `sock_send`. + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + (flag $RIGHT_FD_WRITE) + ;; The right to invoke `fd_advise`. + (flag $RIGHT_FD_ADVISE) + ;; The right to invoke `fd_allocate`. + (flag $RIGHT_FD_ALLOCATE) + ;; The right to invoke `path_create_directory`. + (flag $RIGHT_PATH_CREATE_DIRECTORY) + ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + (flag $RIGHT_PATH_CREATE_FILE) + ;; The right to invoke `path_link` with the file descriptor as the + ;; source directory. + (flag $RIGHT_PATH_LINK_SOURCE) + ;; The right to invoke `path_link` with the file descriptor as the + ;; target directory. + (flag $RIGHT_PATH_LINK_TARGET) + ;; The right to invoke `path_open`. + (flag $RIGHT_PATH_OPEN) + ;; The right to invoke `fd_readdir`. + (flag $RIGHT_FD_READDIR) + ;; The right to invoke `path_readlink`. + (flag $RIGHT_PATH_READLINK) + ;; The right to invoke `path_rename` with the file descriptor as the source directory. + (flag $RIGHT_PATH_RENAME_SOURCE) + ;; The right to invoke `path_rename` with the file descriptor as the target directory. + (flag $RIGHT_PATH_RENAME_TARGET) + ;; The right to invoke `path_filestat_get`. + (flag $RIGHT_PATH_FILESTAT_GET) + ;; The right to change a file's size (there is no `path_filestat_set_size`). + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + ;; The right to invoke `path_filestat_set_times`. + (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + ;; The right to invoke `fd_filestat_get`. + (flag $RIGHT_FD_FILESTAT_GET) + ;; The right to invoke `fd_filestat_set_size`. + (flag $RIGHT_FD_FILESTAT_SET_SIZE) + ;; The right to invoke `fd_filestat_set_times`. + (flag $RIGHT_FD_FILESTAT_SET_TIMES) + ;; The right to invoke `path_symlink`. + (flag $RIGHT_PATH_SYMLINK) + ;; The right to invoke `path_unlink_file`. + (flag $RIGHT_PATH_UNLINK_FILE) + ;; The right to invoke `path_remove_directory`. + (flag $RIGHT_PATH_REMOVE_DIRECTORY) + ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + (flag $RIGHT_POLL_FD_READWRITE) + ;; The right to invoke `sock_shutdown`. + (flag $RIGHT_SOCK_SHUTDOWN) + ) +) + +;; A file descriptor index. +(typename $fd_t u32) + +;; A region of memory for scatter/gather reads. +(typename $iovec_t + (struct + ;; The address of the buffer to be filled. + (field $buf (@witx pointer u8)) + ;; The length of the buffer to be filled. + (field $buf_len $size_t) + ) +) + +;; A region of memory for scatter/gather writes. +(typename $ciovec_t + (struct + ;; The address of the buffer to be written. + (field $buf (@witx const_pointer u8)) + ;; The length of the buffer to be written. + (field $buf_len $size_t) + ) +) + +(typename $iovec_t_array (array $iovec_t)) +(typename $ciovec_t_array (array $ciovec_t)) + +;; Relative offset within a file. +(typename $filedelta_t s64) + +;; The position relative to which to set the offset of the file descriptor. +(typename $whence_t + (enum u8 + ;; Seek relative to current position. + $WHENCE_CUR + ;; Seek relative to end-of-file. + $WHENCE_END + ;; Seek relative to start-of-file. + $WHENCE_SET + ) +) + +;; A reference to the offset of a directory entry. +(typename $dircookie_t u64) + +;; The type for the $d_namlen field of $dirent_t. +(typename $dirnamlen_t u32) + +;; File serial number that is unique within its file system. +(typename $inode_t u64) + +;; The type of a file descriptor or file. +(typename $filetype_t + (enum u8 + ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $FILETYPE_UNKNOWN + ;; The file descriptor or file refers to a block device inode. + $FILETYPE_BLOCK_DEVICE + ;; The file descriptor or file refers to a character device inode. + $FILETYPE_CHARACTER_DEVICE + ;; The file descriptor or file refers to a directory inode. + $FILETYPE_DIRECTORY + ;; The file descriptor or file refers to a regular file inode. + $FILETYPE_REGULAR_FILE + ;; The file descriptor or file refers to a datagram socket. + $FILETYPE_SOCKET_DGRAM + ;; The file descriptor or file refers to a byte-stream socket. + $FILETYPE_SOCKET_STREAM + ;; The file refers to a symbolic link inode. + $FILETYPE_SYMBOLIC_LINK + ) +) + +;; A directory entry. +(typename $dirent_t + (struct + ;; The offset of the next directory entry stored in this directory. + (field $d_next $dircookie_t) + ;; The serial number of the file referred to by this directory entry. + (field $d_ino $inode_t) + ;; The length of the name of the directory entry. + (field $d_namlen $dirnamlen_t) + ;; The type of the file referred to by this directory entry. + (field $d_type $filetype_t) + ) +) + +;; File or memory access pattern advisory information. +(typename $advice_t + (enum u8 + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE + ;; The application has no advice to give on its behavior with respect to the specified data. + $ADVICE_NORMAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM + ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in the near future. + $ADVICE_WILLNEED + ) +) + +;; File descriptor flags. +(typename $fdflags_t + (flags u16 + ;; Append mode: Data written to the file is always appended to the file's end. + (flag $FDFLAG_APPEND) + ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + (flag $FDFLAG_DSYNC) + ;; Non-blocking mode. + (flag $FDFLAG_NONBLOCK) + ;; Synchronized read I/O operations. + (flag $FDFLAG_RSYNC) + ;; Write according to synchronized I/O file integrity completion. In + ;; addition to synchronizing the data stored in the file, the implementation + ;; may also synchronously update the file's metadata. + (flag $FDFLAG_SYNC) + ) +) + +;; File descriptor attributes. +(typename $fdstat_t + (struct + ;; File type. + (field $fs_filetype $filetype_t) + ;; File descriptor flags. + (field $fs_flags $fdflags_t) + ;; Rights that apply to this file descriptor. + (field $fs_rights_base $rights_t) + ;; Maximum set of rights that may be installed on new file descriptors that + ;; are created through this file descriptor, e.g., through `path_open`. + (field $fs_rights_inheriting $rights_t) + ) +) + +;; Identifier for a device containing a file system. Can be used in combination +;; with `inode_t` to uniquely identify a file or directory in the filesystem. +(typename $device_t u64) + +;; Which file time attributes to adjust. +(typename $fstflags_t + (flags u16 + ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + (flag $FILESTAT_SET_ATIM) + ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + (flag $FILESTAT_SET_ATIM_NOW) + ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + (flag $FILESTAT_SET_MTIM) + ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + (flag $FILESTAT_SET_MTIM_NOW) + ) +) + +;; Flags determining the method of how paths are resolved. +(typename $lookupflags_t + (flags u32 + ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + (flag $LOOKUP_SYMLINK_FOLLOW) + ) +) + +;; Open flags used by `path_open`. +(typename $oflags_t + (flags u16 + ;; Create file if it does not exist. + (flag $O_CREAT) + ;; Fail if not a directory. + (flag $O_DIRECTORY) + ;; Fail if file already exists. + (flag $O_EXCL) + ;; Truncate file to size 0. + (flag $O_TRUNC) + ) +) + +;; Number of hard links to an inode. +(typename $linkcount_t u32) + +;; File attributes. +(typename $filestat_t + (struct + ;; Device ID of device containing the file. + (field $st_dev $device_t) + ;; File serial number. + (field $st_ino $inode_t) + ;; File type. + (field $st_filetype $filetype_t) + ;; Number of hard links to the file. + (field $st_nlink $linkcount_t) + ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + (field $st_size $filesize_t) + ;; Last data access timestamp. + (field $st_atim $timestamp_t) + ;; Last data modification timestamp. + (field $st_mtim $timestamp_t) + ;; Last file status change timestamp. + (field $st_ctim $timestamp_t) + ) +) + +;; User-provided value that may be attached to objects that is retained when +;; extracted from the implementation. +(typename $userdata_t u64) + +;; Type of a subscription to an event or its occurrence. +(typename $eventtype_t + (flags u8 + ;; The time value of clock `subscription_t::u.clock.clock_id` has + ;; reached timestamp `subscription_t::u.clock.timeout`. + (flag $EVENTTYPE_CLOCK) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;; available for reading. This event always triggers for regular files. + (flag $EVENTTYPE_FD_READ) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;; available for writing. This event always triggers for regular files. + (flag $EVENTTYPE_FD_WRITE) + ) +) + +;; The state of the file descriptor subscribed to with +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $eventrwflags_t + (flags u16 + ;; The peer of this socket has closed or disconnected. + (flag $EVENT_FD_READWRITE_HANGUP) + ) +) + +;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;; `EVENTTYPE_FD_WRITE`. +(typename $event_fd_readwrite_t + (struct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) + ) +) + +;; The contents of an $event_t. +(typename $event_u + (union + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $event_fd_readwrite_t) + ) +) + +;; An event that occurred. +(typename $event_t + (struct + ;; User-provided value that got attached to `subscription_t::userdata`. + (field $userdata $userdata_t) + ;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno_t) + ;; The type of the event that occurred. + (field $type $eventtype_t) + ;; The contents of the event. + (field $u $event_u) + ) +) + +;; Flags determining how to interpret the timestamp provided in +;; `subscription_t::u.clock.timeout.` +(typename $subclockflags_t + (flags u16 + ;; If set, treat the timestamp provided in + ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;; provided in `subscription_t::u.clock.timeout` relative to the + ;; current time value of clock `subscription_t::u.clock.clock_id.` + (flag $SUBSCRIPTION_CLOCK_ABSTIME) + ) +) + +;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +(typename $subscription_clock_t + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) +) + +;; The contents of a $subscription_t when type is type is +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $subscription_fd_readwrite_t + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) + ) +) + +;; The contents of a $subscription_t. +(typename $subscription_u + (union + ;; When type is `EVENTTYPE_CLOCK`: + (field $clock $subscription_clock_t) + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $subscription_fd_readwrite_t) + ) +) + +;; Subscription to an event. +(typename $subscription_t + (struct + ;; User-provided value that is attached to the subscription in the + ;; implementation and returned through `event_t::userdata`. + (field $userdata $userdata_t) + ;; The type of the event to which to subscribe. + (field $type $eventtype_t) + ;; The contents of the subscription. + (field $u $subscription_u) + ) +) + +;; Exit code generated by a process when exiting. +(typename $exitcode_t u32) + +;; Signal condition. +(typename $signal_t + (enum u8 + ;; Process abort signal. + ;; Action: Terminates the process. + $SIGABRT + ;; Alarm clock. + ;; Action: Terminates the process. + $SIGALRM + ;; Access to an undefined portion of a memory object. + ;; Action: Terminates the process. + $SIGBUS + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT + ;; Erroneous arithmetic operation. + ;; Action: Terminates the process. + $SIGFPE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Kill. + ;; Action: Terminates the process. + $SIGKILL + ;; Write on a pipe with no one to read it. + ;; Action: Ignored. + $SIGPIPE + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Invalid memory reference. + ;; Action: Terminates the process. + $SIGSEGV + ;; Stop executing. + ;; Action: Stops executing. + $SIGSTOP + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS + ;; Termination signal. + ;; Action: Terminates the process. + $SIGTERM + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP + ;; Terminal stop signal. + ;; Action: Stops executing. + $SIGTSTP + ;; Background process attempting read. + ;; Action: Stops executing. + $SIGTTIN + ;; Background process attempting write. + ;; Action: Stops executing. + $SIGTTOU + ;; High bandwidth data is available at a socket. + ;; Action: Ignored. + $SIGURG + ;; User-defined signal 1. + ;; Action: Terminates the process. + $SIGUSR1 + ;; User-defined signal 2. + ;; Action: Terminates the process. + $SIGUSR2 + ;; Virtual timer expired. + ;; Action: Terminates the process. + $SIGVTALRM + ;; CPU time limit exceeded. + ;; Action: Terminates the process. + $SIGXCPU + ;; File size limit exceeded. + ;; Action: Terminates the process. + $SIGXFSZ + ) +) + +;; Flags provided to `sock_recv`. +(typename $riflags_t + (flags u16 + ;; Returns the message without removing it from the socket's receive queue. + (flag $SOCK_RECV_PEEK) + ;; On byte-stream sockets, block until the full amount of data can be returned. + (flag $SOCK_RECV_WAITALL) + ) +) + +;; Flags returned by `sock_recv`. +(typename $roflags_t + (flags u16 + ;; Returned by `sock_recv`: Message data has been truncated. + (flag $SOCK_RECV_DATA_TRUNCATED) + ) +) + +;; Flags provided to `sock_send`. As there are currently no flags +;; defined, it must be set to zero. +(typename $siflags_t u16) + +;; Which channels on a socket to shut down. +(typename $sdflags_t + (flags u8 + ;; Disables further receive operations. + (flag $SHUT_RD) + ;; Disables further send operations. + (flag $SHUT_WR) + ) +) + +;; Identifiers for preopened capabilities. +(typename $preopentype_t + (enum u8 + ;; A pre-opened directory. + $PREOPENTYPE_DIR + ) +) + +;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +(typename $prestat_dir + (struct + ;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size_t) + ) +) + +;; The contents of an $prestat_t. +(typename $prestat_u + (union + ;; When type is `PREOPENTYPE_DIR`: + (field $dir $prestat_dir) + ) +) + +;; Information about a pre-opened capability. +(typename $prestat_t + (struct + ;; The type of the pre-opened capability. + (field $pr_type $preopentype_t) + ;; The contents of the information. + (field $u $prestat_u) + ) +) diff --git a/proposals/random/design/wasi_unstable/wasi_unstable.witx b/proposals/random/phases/old/witx/wasi_unstable.witx similarity index 98% rename from proposals/random/design/wasi_unstable/wasi_unstable.witx rename to proposals/random/phases/old/witx/wasi_unstable.witx index 6d4bea545..f9586ff1e 100644 --- a/proposals/random/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/random/phases/old/witx/wasi_unstable.witx @@ -1,4 +1,5 @@ -;; The wasi_unstable module type. +;; WASI Preview. This is an evolution of the API that WASI initially +;; launched with. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). ;; @@ -7,6 +8,9 @@ (use "typenames.witx") +;; This API predated the convention of naming modules with a `wasi_unstable_` +;; prefix and a version number. It is preserved here for compatibility, but +;; we shouldn't follow this pattern in new APIs. (module $wasi_unstable ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) diff --git a/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md new file mode 100644 index 000000000..9db4a382e --- /dev/null +++ b/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md @@ -0,0 +1,2319 @@ + + +# The WASI Preview API + +This is the API-level documentation for WASI Preview. The function names +are prefixed with "\_\_wasi\_" to reflect how they are spelled in +flat-namespace contexts, however at the wasm module level, they are +unprefixed, because they're inside a module namespace. + +Functions that start with `__wasi_fd_` operate on file descriptors, +while functions that start with `__wasi_path_` operate on filesystem +paths, which are relative to directory file descriptors. + +Much inspiration and content here is derived from [CloudABI] and [POSIX], +though there are also several differences from CloudABI and POSIX. For +example, WASI Preview has no concept of processes in the traditional Unix +sense. While wasm linear memories have some of the aspects of processes, +and it's possible to *emulate* the full semantics of processes on top of +them, this can sometimes be unnatural and inefficient. The goal for +WASI Preview is to be a WebAssembly-native API that exposes APIs that fit +well into the underlying WebAssembly platform, rather than to directly +emulate other platforms. + +This is also a work in progress, and the API here is still evolving. + +Historical note: this API was originally named "WASI Core", and used the +API module name "wasi\_unstable". We've since sought to deemphasize the +"Core" name, as the goal is to split this API up into independent +modules so that embedders need not implement all of it. + +[CloudABI]: https://github.com/NuxiNL/cloudabi +[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ + +## System calls + +- [`__wasi_args_get()`](#args_get) +- [`__wasi_args_sizes_get()`](#args_sizes_get) +- [`__wasi_clock_res_get()`](#clock_res_get) +- [`__wasi_clock_time_get()`](#clock_time_get) +- [`__wasi_environ_get()`](#environ_get) +- [`__wasi_environ_sizes_get()`](#environ_sizes_get) +- [`__wasi_fd_advise()`](#fd_advise) +- [`__wasi_fd_allocate()`](#fd_allocate) +- [`__wasi_fd_close()`](#fd_close) +- [`__wasi_fd_datasync()`](#fd_datasync) +- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) +- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) +- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) +- [`__wasi_fd_filestat_get()`](#fd_filestat_get) +- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) +- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) +- [`__wasi_fd_pread()`](#fd_pread) +- [`__wasi_fd_prestat_get()`](#fd_prestat_get) +- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) +- [`__wasi_fd_pwrite()`](#fd_pwrite) +- [`__wasi_fd_read()`](#fd_read) +- [`__wasi_fd_readdir()`](#fd_readdir) +- [`__wasi_fd_renumber()`](#fd_renumber) +- [`__wasi_fd_seek()`](#fd_seek) +- [`__wasi_fd_sync()`](#fd_sync) +- [`__wasi_fd_tell()`](#fd_tell) +- [`__wasi_fd_write()`](#fd_write) +- [`__wasi_path_create_directory()`](#path_create_directory) +- [`__wasi_path_filestat_get()`](#path_filestat_get) +- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) +- [`__wasi_path_link()`](#path_link) +- [`__wasi_path_open()`](#path_open) +- [`__wasi_path_readlink()`](#path_readlink) +- [`__wasi_path_remove_directory()`](#path_remove_directory) +- [`__wasi_path_rename()`](#path_rename) +- [`__wasi_path_symlink()`](#path_symlink) +- [`__wasi_path_unlink_file()`](#path_unlink_file) +- [`__wasi_poll_oneoff()`](#poll_oneoff) +- [`__wasi_proc_exit()`](#proc_exit) +- [`__wasi_proc_raise()`](#proc_raise) +- [`__wasi_random_get()`](#random_get) +- [`__wasi_sched_yield()`](#sched_yield) +- [`__wasi_sock_recv()`](#sock_recv) +- [`__wasi_sock_send()`](#sock_send) +- [`__wasi_sock_shutdown()`](#sock_shutdown) + +### `__wasi_args_get()` + +Read command-line argument data. + +The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + +Inputs: + +- char \*\*argv + + A pointer to a buffer to write the argument pointers. + +- char \*argv\_buf + + A pointer to a buffer to write the argument string data. + +### `__wasi_args_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*argc + + The number of arguments. + +- size\_t \*argv\_buf\_size + + The size of the argument string data. + +### `__wasi_clock_res_get()` + +Return the resolution of a clock. + +Implementations are required to provide a non-zero value for supported clocks. +For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). + +Note: This is similar to `clock_getres` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the resolution. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) resolution + + The resolution of the clock. + +### `__wasi_clock_time_get()` + +Return the time value of a clock. + +Note: This is similar to `clock_gettime` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the time. + +- [\_\_wasi\_timestamp\_t](#timestamp) precision + + The maximum lag (exclusive) that the returned + time value may have, compared to its actual + value. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) time + + The time value of the clock. + +### `__wasi_environ_get()` + +Read environment variable data. + +The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + +Inputs: + +- char \*\*environ + + A pointer to a buffer to write the environment variable pointers. + +- char \*environ\_buf + + A pointer to a buffer to write the environment variable string data. + +### `__wasi_environ_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*environ\_count + + The number of environment variables. + +- size\_t \*environ\_buf\_size + + The size of the environment variable string data. + +### `__wasi_fd_advise()` + +Provide file advisory information on a file descriptor. + +Note: This is similar to `posix_fadvise` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file for which to provide file advisory information. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file to which the advisory applies. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the region to which the advisory applies. + +- [\_\_wasi\_advice\_t](#advice) advice + + The advice. + +### `__wasi_fd_allocate()` + +Force the allocation of space in a file. + +Note: This is similar to `posix_fallocate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file in which to allocate space. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset at which to start the allocation. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the area that is allocated. + +### `__wasi_fd_close()` + +Close a file descriptor. + +Note: This is similar to `close` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to close. + +### `__wasi_fd_datasync()` + +Synchronize the data of a file to disk. + +Note: This is similar to `fdatasync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file to synchronize to disk. + +### `__wasi_fd_fdstat_get()` + +Get the attributes of a file descriptor. + +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well +as additional fields. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_fdstat\_t](#fdstat) \*buf + + The buffer where the file descriptor's attributes are stored. + +### `__wasi_fd_fdstat_set_flags()` + +Adjust the flags associated with a file descriptor. + +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_fdflags\_t](#fdflags) flags + + The desired values of the file descriptor + flags. + +### `__wasi_fd_fdstat_set_rights()` + +Adjust the rights associated with a file descriptor. + +This can only be used to remove rights, and returns +[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt +to add rights. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The desired rights of the file descriptor. + +### `__wasi_fd_filestat_get()` + +Return the attributes of an open file. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_fd_filestat_set_size()` + +Adjust the size of an open file. If this increases the file's size, the extra +bytes are filled with zeros. + +Note: This is similar to `ftruncate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + A file descriptor for the file to adjust. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + The desired file size. + +### `__wasi_fd_filestat_set_times()` + +Adjust the timestamps of an open file or directory. + +Note: This is similar to `futimens` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_fd_pread()` + +Read from a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `preadv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors in which to store data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to read. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_prestat_get()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- [\_\_wasi\_prestat\_t](#prestat) \*buf + + The buffer where the description is stored. + +### `__wasi_fd_prestat_dir_name()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- const char \*path and size\_t path\_len + + A buffer into which to write the preopened directory name. + +### `__wasi_fd_pwrite()` + +Write to a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `pwritev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to write. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_fd_read()` + +Read from a file descriptor. + +Note: This is similar to `readv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors to which to store data. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_readdir()` + +Read directory entries from a directory. + +When successful, the contents of the output buffer consist of +a sequence of directory entries. Each directory entry consists +of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes +holding the name of the directory entry. + +This function fills the output buffer as much as possible, +potentially truncating the last directory entry. This allows +the caller to grow its read buffer size in case it's too small +to fit a single large directory entry, or skip the oversized +directory entry. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The directory from which to read the directory + entries. + +- void \*buf and size\_t buf\_len + + The buffer where directory entries are stored. + +- [\_\_wasi\_dircookie\_t](#dircookie) cookie + + The location within the directory to start + reading. + +Outputs: + +- size\_t bufused + + The number of bytes stored in the read buffer. + If less than the size of the read buffer, the + end of the directory has been reached. + +### `__wasi_fd_renumber()` + +Atomically replace a file descriptor by renumbering another +file descriptor. + +Due to the strong focus on thread safety, this environment +does not provide a mechanism to duplicate or renumber a file +descriptor to an arbitrary number, like dup2(). This would be +prone to race conditions, as an actual file descriptor with the +same number could be allocated by a different thread at the same +time. + +This function provides a way to atomically renumber file +descriptors, which would disappear if dup2() were to be +removed entirely. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) from + + The file descriptor to renumber. + +- [\_\_wasi\_fd\_t](#fd) to + + The file descriptor to overwrite. + +### `__wasi_fd_seek()` + +Move the offset of a file descriptor. + +Note: This is similar to `lseek` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_filedelta\_t](#filedelta) offset + + The number of bytes to move. + +- [\_\_wasi\_whence\_t](#whence) whence + + The base from which the offset is relative. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) newoffset + + The new offset of the file descriptor, + relative to the start of the file. + +### `__wasi_fd_sync()` + +Synchronize the data and metadata of a file to disk. + +Note: This is similar to `fsync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file containing the data + and metadata to synchronize to disk. + +### `__wasi_fd_tell()` + +Return the current offset of a file descriptor. + +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The current offset of the file descriptor, relative to the start of the file. + +### `__wasi_fd_write()` + +Write to a file descriptor. + +Note: This is similar to `writev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_path_create_directory()` + +Create a directory. + +Note: This is similar to `mkdirat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path at which to create the directory. + +### `__wasi_path_filestat_get()` + +Return the attributes of a file or directory. + +Note: This is similar to `stat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_path_filestat_set_times()` + +Adjust the timestamps of a file or directory. + +Note: This is similar to `utimensat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_path_link()` + +Create a hard link. + +Note: This is similar to `linkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags + + Flags determining the method of how the path is resolved. + +- const char \*old\_path and size\_t old\_path\_len + + The source path from which to link. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the hard link. + +### `__wasi_path_open()` + +Open a file or directory. + +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since +this is error-prone in multi-threaded contexts. The returned file +descriptor is guaranteed to be less than 231. + +Note: This is similar to `openat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) dirfd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The relative path of the file or directory to open, relative to + the [`dirfd`](#path_open.dirfd) directory. + +- [\_\_wasi\_oflags\_t](#oflags) o_flags + + The method by which to open the file. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The initial rights of the newly created file descriptor. The + implementation is allowed to return a file descriptor with fewer + rights than specified, if and only if those rights do not apply + to the type of file being opened. + + The *base* rights are rights that will apply to operations using + the file descriptor itself, while the *inheriting* rights are + rights that apply to file descriptors derived from it. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + The initial flags of the file descriptor. + +Outputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file that has been + opened. + +### `__wasi_path_readlink()` + +Read the contents of a symbolic link. + +Note: This is similar to `readlinkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path of the symbolic link from which to read. + +- char \*buf and size\_t buf\_len + + The buffer to which to write the contents of the symbolic link. + +Outputs: + +- size\_t bufused + + The number of bytes placed in the buffer. + +### `__wasi_path_remove_directory()` + +Remove a directory. + +Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. + +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a directory to remove. + +### `__wasi_path_rename()` + +Rename a file or directory. + +Note: This is similar to `renameat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- const char \*old\_path and size\_t old\_path\_len + + The source path of the file or directory to rename. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path to which to rename the file or directory. + +### `__wasi_path_symlink()` + +Create a symbolic link. + +Note: This is similar to `symlinkat` in POSIX. + +Inputs: + +- const char \*old\_path and size\_t old_path\_len + + The contents of the symbolic link. + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the symbolic link. + +### `__wasi_path_unlink_file()` + +Unlink a file. + +Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. + +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a file to unlink. + +### `__wasi_poll_oneoff()` + +Concurrently poll for the occurrence of a set of events. + +Inputs: + +- const [\_\_wasi\_subscription\_t](#subscription) \*in + + The events to which to subscribe. + +- [\_\_wasi\_event\_t](#event) \*out + + The events that have occurred. + +- size\_t nsubscriptions + + Both the number of subscriptions and events. + +Outputs: + +- size\_t nevents + + The number of events stored. + +### `__wasi_proc_exit()` + +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +Note: This is similar to `_Exit` in POSIX. + +Inputs: + +- [\_\_wasi\_exitcode\_t](#exitcode) rval + + The exit code returned by the process. + +Does not return. + +### `__wasi_proc_raise()` + +Send a signal to the process of the calling thread. + +Note: This is similar to `raise` in POSIX. + +Inputs: + +- [\_\_wasi\_signal\_t](#signal) sig + + The signal condition to trigger. + +### `__wasi_random_get()` + +Write high-quality random data into a buffer. + +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. + +This function may execute slowly, so when large mounts of random +data are required, it's advisable to use this function to seed a +pseudo-random number generator, rather than to provide the +random data directly. + +Inputs: + +- void \*buf and size\_t buf\_len + + The buffer to fill with random data. + +### `__wasi_sched_yield()` + +Temporarily yield execution of the calling thread. + +Note: This is similar to `sched_yield` in POSIX. + +### `__wasi_sock_recv()` + +Receive a message from a socket. + +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to receive data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len + + List of scatter/gather vectors to which to store data. + +- [\_\_wasi\_riflags\_t](#riflags) ri\_flags + + Message flags. + +Outputs: + +- size\_t ro\_datalen + + Number of bytes stored in [`ri_data`](#sock_recv.ri_data). + +- [\_\_wasi\_roflags\_t](#roflags) ro\_flags + + Message flags. + +### `__wasi_sock_send()` + +Send a message on a socket. + +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to send data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len + + List of scatter/gather vectors to which to retrieve data + +- [\_\_wasi\_siflags\_t](#siflags) si\_flags + + Message flags. + +Outputs: + +- size\_t so\_datalen + + Number of bytes transmitted. + +### `__wasi_sock_shutdown()` + +Shut down socket send and receive channels. + +Note: This is similar to `shutdown` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to shutdown channels. + +- [\_\_wasi\_sdflags\_t](#sdflags) how + + Which channels on the socket to shut down. + +## Types + +### `__wasi_advice_t` (`uint8_t`) + +File or memory access pattern advisory information. + +Used by [`__wasi_fd_advise()`](#fd_advise). + +Possible values: + +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + +- **`__WASI_ADVICE_NORMAL`** + + The application has no advice to give on its behavior + with respect to the specified data. + +- **`__WASI_ADVICE_RANDOM`** + + The application expects to access the specified data + in a random order. + +- **`__WASI_ADVICE_SEQUENTIAL`** + + The application expects to access the specified data + sequentially from lower offsets to higher offsets. + +- **`__WASI_ADVICE_WILLNEED`** + + The application expects to access the specified data + in the near future. + +### `__wasi_ciovec_t` (`struct`) + +A region of memory for scatter/gather writes. + +Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). + +Members: + +- const void \*buf and size\_t buf\_len + + The address and length of the buffer to be written. + +### `__wasi_clockid_t` (`uint32_t`) + +Identifiers for clocks. + +Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). + +Possible values: + +- **`__WASI_CLOCK_MONOTONIC`** + + The store-wide monotonic clock, which is defined as a + clock measuring real time, whose value cannot be + adjusted and which cannot have negative clock jumps. + + The epoch of this clock is undefined. The absolute + time value of this clock therefore has no meaning. + +- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** + + The CPU-time clock associated with the current + process. + +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + +- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** + + The CPU-time clock associated with the current thread. + +### `__wasi_device_t` (`uint64_t`) + +Identifier for a device containing a file system. Can be used +in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or +directory in the filesystem. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_dircookie_t` (`uint64_t`) + +A reference to the offset of a directory entry. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). + +Special values: + +- **`__WASI_DIRCOOKIE_START`** + + Permanent reference to the first directory entry + within a directory. + +### `__wasi_dirent_t` (`struct`) + +A directory entry. + +Members: + +- [\_\_wasi\_dircookie\_t](#dircookie) d\_next + + The offset of the next directory entry stored in this + directory. + +- [\_\_wasi\_inode\_t](#inode) d\_ino + + The serial number of the file referred to by this + directory entry. + +- uint32\_t d\_namlen + + The length of the name of the directory entry. + +- [\_\_wasi\_filetype\_t](#filetype) d\_type + + The type of the file referred to by this directory + entry. + +### `__wasi_errno_t` (`uint16_t`) + +Error codes returned by functions. + +Not all of these error codes are returned by the functions +provided by this API; some are used in higher-level library layers, +and others are provided merely for alignment with POSIX. + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_ESUCCESS`** + + No error occurred. System call completed successfully. + +- **`__WASI_E2BIG`** + + Argument list too long. + +- **`__WASI_EACCES`** + + Permission denied. + +- **`__WASI_EADDRINUSE`** + + Address in use. + +- **`__WASI_EADDRNOTAVAIL`** + + Address not available. + +- **`__WASI_EAFNOSUPPORT`** + + Address family not supported. + +- **`__WASI_EAGAIN`** + + Resource unavailable, or operation would block. + +- **`__WASI_EALREADY`** + + Connection already in progress. + +- **`__WASI_EBADF`** + + Bad file descriptor. + +- **`__WASI_EBADMSG`** + + Bad message. + +- **`__WASI_EBUSY`** + + Device or resource busy. + +- **`__WASI_ECANCELED`** + + Operation canceled. + +- **`__WASI_ECHILD`** + + No child processes. + +- **`__WASI_ECONNABORTED`** + + Connection aborted. + +- **`__WASI_ECONNREFUSED`** + + Connection refused. + +- **`__WASI_ECONNRESET`** + + Connection reset. + +- **`__WASI_EDEADLK`** + + Resource deadlock would occur. + +- **`__WASI_EDESTADDRREQ`** + + Destination address required. + +- **`__WASI_EDOM`** + + Mathematics argument out of domain of function. + +- **`__WASI_EDQUOT`** + + Reserved. + +- **`__WASI_EEXIST`** + + File exists. + +- **`__WASI_EFAULT`** + + Bad address. + +- **`__WASI_EFBIG`** + + File too large. + +- **`__WASI_EHOSTUNREACH`** + + Host is unreachable. + +- **`__WASI_EIDRM`** + + Identifier removed. + +- **`__WASI_EILSEQ`** + + Illegal byte sequence. + +- **`__WASI_EINPROGRESS`** + + Operation in progress. + +- **`__WASI_EINTR`** + + Interrupted function. + +- **`__WASI_EINVAL`** + + Invalid argument. + +- **`__WASI_EIO`** + + I/O error. + +- **`__WASI_EISCONN`** + + Socket is connected. + +- **`__WASI_EISDIR`** + + Is a directory. + +- **`__WASI_ELOOP`** + + Too many levels of symbolic links. + +- **`__WASI_EMFILE`** + + File descriptor value too large. + +- **`__WASI_EMLINK`** + + Too many links. + +- **`__WASI_EMSGSIZE`** + + Message too large. + +- **`__WASI_EMULTIHOP`** + + Reserved. + +- **`__WASI_ENAMETOOLONG`** + + Filename too long. + +- **`__WASI_ENETDOWN`** + + Network is down. + +- **`__WASI_ENETRESET`** + + Connection aborted by network. + +- **`__WASI_ENETUNREACH`** + + Network unreachable. + +- **`__WASI_ENFILE`** + + Too many files open in system. + +- **`__WASI_ENOBUFS`** + + No buffer space available. + +- **`__WASI_ENODEV`** + + No such device. + +- **`__WASI_ENOENT`** + + No such file or directory. + +- **`__WASI_ENOEXEC`** + + Executable file format error. + +- **`__WASI_ENOLCK`** + + No locks available. + +- **`__WASI_ENOLINK`** + + Reserved. + +- **`__WASI_ENOMEM`** + + Not enough space. + +- **`__WASI_ENOMSG`** + + No message of the desired type. + +- **`__WASI_ENOPROTOOPT`** + + Protocol not available. + +- **`__WASI_ENOSPC`** + + No space left on device. + +- **`__WASI_ENOSYS`** + + Function not supported. + +- **`__WASI_ENOTCONN`** + + The socket is not connected. + +- **`__WASI_ENOTDIR`** + + Not a directory or a symbolic link to a directory. + +- **`__WASI_ENOTEMPTY`** + + Directory not empty. + +- **`__WASI_ENOTRECOVERABLE`** + + State not recoverable. + +- **`__WASI_ENOTSOCK`** + + Not a socket. + +- **`__WASI_ENOTSUP`** + + Not supported, or operation not supported on socket. + +- **`__WASI_ENOTTY`** + + Inappropriate I/O control operation. + +- **`__WASI_ENXIO`** + + No such device or address. + +- **`__WASI_EOVERFLOW`** + + Value too large to be stored in data type. + +- **`__WASI_EOWNERDEAD`** + + Previous owner died. + +- **`__WASI_EPERM`** + + Operation not permitted. + +- **`__WASI_EPIPE`** + + Broken pipe. + +- **`__WASI_EPROTO`** + + Protocol error. + +- **`__WASI_EPROTONOSUPPORT`** + + Protocol not supported. + +- **`__WASI_EPROTOTYPE`** + + Protocol wrong type for socket. + +- **`__WASI_ERANGE`** + + Result too large. + +- **`__WASI_EROFS`** + + Read-only file system. + +- **`__WASI_ESPIPE`** + + Invalid seek. + +- **`__WASI_ESRCH`** + + No such process. + +- **`__WASI_ESTALE`** + + Reserved. + +- **`__WASI_ETIMEDOUT`** + + Connection timed out. + +- **`__WASI_ETXTBSY`** + + Text file busy. + +- **`__WASI_EXDEV`** + + Cross-device link. + +- **`__WASI_ENOTCAPABLE`** + + Extension: Capabilities insufficient. + +### `__wasi_event_t` (`struct`) + +An event that occurred. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that got attached to + [`__wasi_subscription_t::userdata`](#subscription.userdata). + +- [\_\_wasi\_errno\_t](#errno) error + + If non-zero, an error that occurred while processing + the subscription request. + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event that occurred. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_filesize\_t](#filesize) nbytes + + The number of bytes available for reading or writing. + + - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags + + The state of the file descriptor. + +### `__wasi_eventrwflags_t` (`uint16_t` bitfield) + +The state of the file descriptor subscribed to with +[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_EVENT_FD_READWRITE_HANGUP`** + + The peer of this socket has closed or disconnected. + +### `__wasi_eventtype_t` (`uint8_t`) + +Type of a subscription to an event or its occurrence. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_EVENTTYPE_CLOCK`** + + The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) + has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +- **`__WASI_EVENTTYPE_FD_READ`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + data available for reading. This event always triggers + for regular files. + +- **`__WASI_EVENTTYPE_FD_WRITE`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + capacity available for writing. This event always + triggers for regular files. + +### `__wasi_exitcode_t` (`uint32_t`) + +Exit code generated by a process when exiting. + +Used by [`__wasi_proc_exit()`](#proc_exit). + +### `__wasi_fd_t` (`uint32_t`) + +A file descriptor number. + +Used by many functions in this API. + +As in POSIX, three file descriptor numbers are provided to instances +on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, +and `STDERR_FILENO`). + +Other than these, WASI implementations are not required to allocate +new file descriptors in ascending order. + +### `__wasi_fdflags_t` (`uint16_t` bitfield) + +File descriptor flags. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_FDFLAG_APPEND`** + + Append mode: Data written to the file is always + appended to the file's end. + +- **`__WASI_FDFLAG_DSYNC`** + + Write according to synchronized I/O data integrity + completion. Only the data stored in the file is + synchronized. + +- **`__WASI_FDFLAG_NONBLOCK`** + + Non-blocking mode. + +- **`__WASI_FDFLAG_RSYNC`** + + Synchronized read I/O operations. + +- **`__WASI_FDFLAG_SYNC`** + + Write according to synchronized I/O file integrity completion. + In addition to synchronizing the data stored in the file, the + implementation may also synchronously update the file's metadata. + +### `__wasi_fdstat_t` (`struct`) + +File descriptor attributes. + +Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). + +Members: + +- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype + + File type. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + File descriptor flags. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base + + Rights that apply to this file descriptor. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + Maximum set of rights that may be installed on new + file descriptors that are created through this file + descriptor, e.g., through [`__wasi_path_open()`](#path_open). + +### `__wasi_filedelta_t` (`int64_t`) + +Relative offset within a file. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +### `__wasi_filesize_t` (`uint64_t`) + +Non-negative file size or length of a region within a file. + +Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +### `__wasi_filestat_t` (`struct`) + +File attributes. + +Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). + +Members: + +- [\_\_wasi\_device\_t](#device) st\_dev + + Device ID of device containing the file. + +- [\_\_wasi\_inode\_t](#inode) st\_ino + + File serial number. + +- [\_\_wasi\_filetype\_t](#filetype) st\_filetype + + File type. + +- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink + + Number of hard links to the file. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + For regular files, the file size in bytes. For + symbolic links, the length in bytes of the pathname + contained in the symbolic link. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + Last data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + Last data modification timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim + + Last file status change timestamp. + +### `__wasi_filetype_t` (`uint8_t`) + +The type of a file descriptor or file. + +Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). + +Possible values: + +- **`__WASI_FILETYPE_UNKNOWN`** + + The type of the file descriptor or file is unknown or + is different from any of the other types specified. + +- **`__WASI_FILETYPE_BLOCK_DEVICE`** + + The file descriptor or file refers to a block device + inode. + +- **`__WASI_FILETYPE_CHARACTER_DEVICE`** + + The file descriptor or file refers to a character + device inode. + +- **`__WASI_FILETYPE_DIRECTORY`** + + The file descriptor or file refers to a directory + inode. + +- **`__WASI_FILETYPE_REGULAR_FILE`** + + The file descriptor or file refers to a regular file + inode. + +- **`__WASI_FILETYPE_SOCKET_DGRAM`** + + The file descriptor or file refers to a datagram + socket. + +- **`__WASI_FILETYPE_SOCKET_STREAM`** + + The file descriptor or file refers to a byte-stream + socket. + +- **`__WASI_FILETYPE_SYMBOLIC_LINK`** + + The file refers to a symbolic link inode. + +### `__wasi_fstflags_t` (`uint16_t` bitfield) + +Which file time attributes to adjust. + +Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +Possible values: + +- **`__WASI_FILESTAT_SET_ATIM`** + + Adjust the last data access timestamp to the value + stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). + +- **`__WASI_FILESTAT_SET_ATIM_NOW`** + + Adjust the last data access timestamp to the time + of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +- **`__WASI_FILESTAT_SET_MTIM`** + + Adjust the last data modification timestamp to the + value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). + +- **`__WASI_FILESTAT_SET_MTIM_NOW`** + + Adjust the last data modification timestamp to the + time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +### `__wasi_inode_t` (`uint64_t`) + +File serial number that is unique within its file system. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). + +### `__wasi_iovec_t` (`struct`) + +A region of memory for scatter/gather reads. + +Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). + +Members: + +- void \*buf and size\_t buf\_len + + The address and length of the buffer to be filled. + +### `__wasi_linkcount_t` (`uint32_t`) + +Number of hard links to an inode. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_lookupflags_t` (`uint32_t` bitfield) + +Flags determining the method of how paths are resolved. + +Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** + + As long as the resolved path corresponds to a symbolic + link, it is expanded. + +### `__wasi_oflags_t` (`uint16_t` bitfield) + +Open flags used by [`__wasi_path_open()`](#path_open). + +Used by [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_O_CREAT`** + + Create file if it does not exist. + +- **`__WASI_O_DIRECTORY`** + + Fail if not a directory. + +- **`__WASI_O_EXCL`** + + Fail if file already exists. + +- **`__WASI_O_TRUNC`** + + Truncate file to size 0. + +### `__wasi_riflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_PEEK`** + + Returns the message without removing it from the + socket's receive queue. + +- **`__WASI_SOCK_RECV_WAITALL`** + + On byte-stream sockets, block until the full amount + of data can be returned. + +### `__wasi_rights_t` (`uint64_t` bitfield) + +File descriptor rights, determining which actions may be +performed. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_RIGHT_FD_DATASYNC`** + + The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_READ`** + + The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke + [`__wasi_fd_pread()`](#fd_pread). + +- **`__WASI_RIGHT_FD_SEEK`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies + [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). + +- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** + + The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). + +- **`__WASI_RIGHT_FD_SYNC`** + + The right to invoke [`__wasi_fd_sync()`](#fd_sync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and + [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_TELL`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the + file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with + offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). + +- **`__WASI_RIGHT_FD_WRITE`** + + The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to + invoke [`__wasi_fd_pwrite()`](#fd_pwrite). + +- **`__WASI_RIGHT_FD_ADVISE`** + + The right to invoke [`__wasi_fd_advise()`](#fd_advise). + +- **`__WASI_RIGHT_FD_ALLOCATE`** + + The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). + +- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** + + The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). + +- **`__WASI_RIGHT_PATH_CREATE_FILE`** + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke + [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). + +- **`__WASI_RIGHT_PATH_LINK_SOURCE`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_LINK_TARGET`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_OPEN`** + + The right to invoke [`__wasi_path_open()`](#path_open). + +- **`__WASI_RIGHT_FD_READDIR`** + + The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). + +- **`__WASI_RIGHT_PATH_READLINK`** + + The right to invoke [`__wasi_path_readlink()`](#path_readlink). + +- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_RENAME_TARGET`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_FILESTAT_GET`** + + The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** + + The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +- **`__WASI_RIGHT_FD_FILESTAT_GET`** + + The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** + + The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). + +- **`__WASI_RIGHT_PATH_SYMLINK`** + + The right to invoke [`__wasi_path_symlink()`](#path_symlink). + +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + +- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** + + The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). + +- **`__WASI_RIGHT_POLL_FD_READWRITE`** + + If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). + + If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +- **`__WASI_RIGHT_SOCK_SHUTDOWN`** + + The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). + +### `__wasi_roflags_t` (`uint16_t` bitfield) + +Flags returned by [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** + + Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been + truncated. + +### `__wasi_sdflags_t` (`uint8_t` bitfield) + +Which channels on a socket to shut down. + +Used by [`__wasi_sock_shutdown()`](#sock_shutdown). + +Possible values: + +- **`__WASI_SHUT_RD`** + + Disables further receive operations. + +- **`__WASI_SHUT_WR`** + + Disables further send operations. + +### `__wasi_siflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +Used by [`__wasi_sock_send()`](#sock_send). + +### `__wasi_signal_t` (`uint8_t`) + +Signal condition. + +Used by [`__wasi_proc_raise()`](#proc_raise). + +Possible values: + +- **`__WASI_SIGABRT`** + + Process abort signal. + + Action: Terminates the process. + +- **`__WASI_SIGALRM`** + + Alarm clock. + + Action: Terminates the process. + +- **`__WASI_SIGBUS`** + + Access to an undefined portion of a memory object. + + Action: Terminates the process. + +- **`__WASI_SIGCHLD`** + + Child process terminated, stopped, or continued. + + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGFPE`** + + Erroneous arithmetic operation. + + Action: Terminates the process. + +- **`__WASI_SIGHUP`** + + Hangup. + + Action: Terminates the process. + +- **`__WASI_SIGILL`** + + Illegal instruction. + + Action: Terminates the process. + +- **`__WASI_SIGINT`** + + Terminate interrupt signal. + + Action: Terminates the process. + +- **`__WASI_SIGKILL`** + + Kill. + + Action: Terminates the process. + +- **`__WASI_SIGPIPE`** + + Write on a pipe with no one to read it. + + Action: Ignored. + +- **`__WASI_SIGQUIT`** + + Terminal quit signal. + + Action: Terminates the process. + +- **`__WASI_SIGSEGV`** + + Invalid memory reference. + + Action: Terminates the process. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. + +- **`__WASI_SIGSYS`** + + Bad system call. + + Action: Terminates the process. + +- **`__WASI_SIGTERM`** + + Termination signal. + + Action: Terminates the process. + +- **`__WASI_SIGTRAP`** + + Trace/breakpoint trap. + + Action: Terminates the process. + +- **`__WASI_SIGTSTP`** + + Terminal stop signal. + + Action: Stops executing. + +- **`__WASI_SIGTTIN`** + + Background process attempting read. + + Action: Stops executing. + +- **`__WASI_SIGTTOU`** + + Background process attempting write. + + Action: Stops executing. + +- **`__WASI_SIGURG`** + + High bandwidth data is available at a socket. + + Action: Ignored. + +- **`__WASI_SIGUSR1`** + + User-defined signal 1. + + Action: Terminates the process. + +- **`__WASI_SIGUSR2`** + + User-defined signal 2. + + Action: Terminates the process. + +- **`__WASI_SIGVTALRM`** + + Virtual timer expired. + + Action: Terminates the process. + +- **`__WASI_SIGXCPU`** + + CPU time limit exceeded. + + Action: Terminates the process. + +- **`__WASI_SIGXFSZ`** + + File size limit exceeded. + + Action: Terminates the process. + +### `__wasi_subclockflags_t` (`uint16_t` bitfield) + +Flags determining how to interpret the timestamp provided in +[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +Used by [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** + + If set, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp + of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + + If clear, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current + time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + +### `__wasi_subscription_t` (`struct`) + +Subscription to an event. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that is attached to the subscription in the + implementation and returned through + [`__wasi_event_t::userdata`](#event.userdata). + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event to which to subscribe. + +- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): + + - **`u.clock`** + + - [\_\_wasi\_userdata\_t](#userdata) identifier + + The user-defined unique identifier of the clock. + + - [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock against which to compare the timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) timeout + + The absolute or relative timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) precision + + The amount of time that the implementation may wait additionally + to coalesce with other events. + + - [\_\_wasi\_subclockflags\_t](#subclockflags) flags + + Flags specifying whether the timeout is absolute or relative. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor on which to wait for it to become ready + for reading or writing. + +### `__wasi_timestamp_t` (`uint64_t`) + +Timestamp in nanoseconds. + +Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +### `__wasi_userdata_t` (`uint64_t`) + +User-provided value that may be attached to objects that is +retained when extracted from the implementation. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +### `__wasi_whence_t` (`uint8_t`) + +The position relative to which to set the offset of the file descriptor. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +Possible values: + +- **`__WASI_WHENCE_CUR`** + + Seek relative to current position. + +- **`__WASI_WHENCE_END`** + + Seek relative to end-of-file. + +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + diff --git a/proposals/random/phases/unstable/witx/typenames.witx b/proposals/random/phases/unstable/witx/typenames.witx new file mode 100644 index 000000000..e04a188d9 --- /dev/null +++ b/proposals/random/phases/unstable/witx/typenames.witx @@ -0,0 +1,752 @@ +;; Type names used by low-level WASI interfaces. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(typename $size_t u32) + +;; Non-negative file size or length of a region within a file. +(typename $filesize_t u64) + +;; Timestamp in nanoseconds. +(typename $timestamp_t u64) + +;; Identifiers for clocks. +(typename $clockid_t + (enum u32 + ;; The store-wide monotonic clock, which is defined as a clock measuring + ;; real time, whose value cannot be adjusted and which cannot have negative + ;; clock jumps. The epoch of this clock is undefined. The absolute time + ;; value of this clock therefore has no meaning. + $CLOCK_MONOTONIC + ;; The CPU-time clock associated with the current process. + $CLOCK_PROCESS_CPUTIME_ID + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME + ;; The CPU-time clock associated with the current thread. + $CLOCK_THREAD_CPUTIME_ID + ) +) + +;; Error codes returned by functions. +;; Not all of these error codes are returned by the functions provided by this +;; API; some are used in higher-level library layers, and others are provided +;; merely for alignment with POSIX. +(typename $errno_t + (enum u16 + ;; No error occurred. System call completed successfully. + $ESUCCESS + ;; Argument list too long. + $E2BIG + ;; Permission denied. + $EACCES + ;; Address in use. + $EADDRINUSE + ;; Address not available. + $EADDRNOTAVAIL + ;; Address family not supported. + $EAFNOSUPPORT + ;; Resource unavailable, or operation would block. + $EAGAIN + ;; Connection already in progress. + $EALREADY + ;; Bad file descriptor. + $EBADF + ;; Bad message. + $EBADMSG + ;; Device or resource busy. + $EBUSY + ;; Operation canceled. + $ECANCELED + ;; No child processes. + $ECHILD + ;; Connection aborted. + $ECONNABORTED + ;; Connection refused. + $ECONNREFUSED + ;; Connection reset. + $ECONNRESET + ;; Resource deadlock would occur. + $EDEADLK + ;; Destination address required. + $EDESTADDRREQ + ;; Mathematics argument out of domain of function. + $EDOM + ;; Reserved. + $EDQUOT + ;; File exists. + $EEXIST + ;; Bad address. + $EFAULT + ;; File too large. + $EFBIG + ;; Host is unreachable. + $EHOSTUNREACH + ;; Identifier removed. + $EIDRM + ;; Illegal byte sequence. + $EILSEQ + ;; Operation in progress. + $EINPROGRESS + ;; Interrupted function. + $EINTR + ;; Invalid argument. + $EINVAL + ;; I/O error. + $EIO + ;; Socket is connected. + $EISCONN + ;; Is a directory. + $EISDIR + ;; Too many levels of symbolic links. + $ELOOP + ;; File descriptor value too large. + $EMFILE + ;; Too many links. + $EMLINK + ;; Message too large. + $EMSGSIZE + ;; Reserved. + $EMULTIHOP + ;; Filename too long. + $ENAMETOOLONG + ;; Network is down. + $ENETDOWN + ;; Connection aborted by network. + $ENETRESET + ;; Network unreachable. + $ENETUNREACH + ;; Too many files open in system. + $ENFILE + ;; No buffer space available. + $ENOBUFS + ;; No such device. + $ENODEV + ;; No such file or directory. + $ENOENT + ;; Executable file format error. + $ENOEXEC + ;; No locks available. + $ENOLCK + ;; Reserved. + $ENOLINK + ;; Not enough space. + $ENOMEM + ;; No message of the desired type. + $ENOMSG + ;; Protocol not available. + $ENOPROTOOPT + ;; No space left on device. + $ENOSPC + ;; Function not supported. + $ENOSYS + ;; The socket is not connected. + $ENOTCONN + ;; Not a directory or a symbolic link to a directory. + $ENOTDIR + ;; Directory not empty. + $ENOTEMPTY + ;; State not recoverable. + $ENOTRECOVERABLE + ;; Not a socket. + $ENOTSOCK + ;; Not supported, or operation not supported on socket. + $ENOTSUP + ;; Inappropriate I/O control operation. + $ENOTTY + ;; No such device or address. + $ENXIO + ;; Value too large to be stored in data type. + $EOVERFLOW + ;; Previous owner died. + $EOWNERDEAD + ;; Operation not permitted. + $EPERM + ;; Broken pipe. + $EPIPE + ;; Protocol error. + $EPROTO + ;; Protocol not supported. + $EPROTONOSUPPORT + ;; Protocol wrong type for socket. + $EPROTOTYPE + ;; Result too large. + $ERANGE + ;; Read-only file system. + $EROFS + ;; Invalid seek. + $ESPIPE + ;; No such process. + $ESRCH + ;; Reserved. + $ESTALE + ;; Connection timed out. + $ETIMEDOUT + ;; Text file busy. + $ETXTBSY + ;; Cross-device link. + $EXDEV + ;; Extension: Capabilities insufficient. + $ENOTCAPABLE + ) +) + +;; File descriptor rights, determining which actions may be performed. +(typename $rights_t + (flags u64 + ;; The right to invoke `fd_datasync`. + ;; + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_DSYNC`. + (flag $RIGHT_FD_DATASYNC) + ;; The right to invoke `fd_read` and `sock_recv`. + ;; + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + (flag $RIGHT_FD_READ) + ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + (flag $RIGHT_FD_SEEK) + ;; The right to invoke `fd_fdstat_set_flags`. + (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + ;; The right to invoke `fd_sync`. + ;; + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + (flag $RIGHT_FD_SYNC) + ;; The right to invoke `fd_seek` in such a way that the file offset + ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;; invoke `fd_tell`. + (flag $RIGHT_FD_TELL) + ;; The right to invoke `fd_write` and `sock_send`. + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + (flag $RIGHT_FD_WRITE) + ;; The right to invoke `fd_advise`. + (flag $RIGHT_FD_ADVISE) + ;; The right to invoke `fd_allocate`. + (flag $RIGHT_FD_ALLOCATE) + ;; The right to invoke `path_create_directory`. + (flag $RIGHT_PATH_CREATE_DIRECTORY) + ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + (flag $RIGHT_PATH_CREATE_FILE) + ;; The right to invoke `path_link` with the file descriptor as the + ;; source directory. + (flag $RIGHT_PATH_LINK_SOURCE) + ;; The right to invoke `path_link` with the file descriptor as the + ;; target directory. + (flag $RIGHT_PATH_LINK_TARGET) + ;; The right to invoke `path_open`. + (flag $RIGHT_PATH_OPEN) + ;; The right to invoke `fd_readdir`. + (flag $RIGHT_FD_READDIR) + ;; The right to invoke `path_readlink`. + (flag $RIGHT_PATH_READLINK) + ;; The right to invoke `path_rename` with the file descriptor as the source directory. + (flag $RIGHT_PATH_RENAME_SOURCE) + ;; The right to invoke `path_rename` with the file descriptor as the target directory. + (flag $RIGHT_PATH_RENAME_TARGET) + ;; The right to invoke `path_filestat_get`. + (flag $RIGHT_PATH_FILESTAT_GET) + ;; The right to change a file's size (there is no `path_filestat_set_size`). + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + ;; The right to invoke `path_filestat_set_times`. + (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + ;; The right to invoke `fd_filestat_get`. + (flag $RIGHT_FD_FILESTAT_GET) + ;; The right to invoke `fd_filestat_set_size`. + (flag $RIGHT_FD_FILESTAT_SET_SIZE) + ;; The right to invoke `fd_filestat_set_times`. + (flag $RIGHT_FD_FILESTAT_SET_TIMES) + ;; The right to invoke `path_symlink`. + (flag $RIGHT_PATH_SYMLINK) + ;; The right to invoke `path_unlink_file`. + (flag $RIGHT_PATH_UNLINK_FILE) + ;; The right to invoke `path_remove_directory`. + (flag $RIGHT_PATH_REMOVE_DIRECTORY) + ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + (flag $RIGHT_POLL_FD_READWRITE) + ;; The right to invoke `sock_shutdown`. + (flag $RIGHT_SOCK_SHUTDOWN) + ) +) + +;; A file descriptor index. +(typename $fd_t u32) + +;; A region of memory for scatter/gather reads. +(typename $iovec_t + (struct + ;; The address of the buffer to be filled. + (field $buf (@witx pointer u8)) + ;; The length of the buffer to be filled. + (field $buf_len $size_t) + ) +) + +;; A region of memory for scatter/gather writes. +(typename $ciovec_t + (struct + ;; The address of the buffer to be written. + (field $buf (@witx const_pointer u8)) + ;; The length of the buffer to be written. + (field $buf_len $size_t) + ) +) + +(typename $iovec_t_array (array $iovec_t)) +(typename $ciovec_t_array (array $ciovec_t)) + +;; Relative offset within a file. +(typename $filedelta_t s64) + +;; The position relative to which to set the offset of the file descriptor. +(typename $whence_t + (enum u8 + ;; Seek relative to current position. + $WHENCE_CUR + ;; Seek relative to end-of-file. + $WHENCE_END + ;; Seek relative to start-of-file. + $WHENCE_SET + ) +) + +;; A reference to the offset of a directory entry. +(typename $dircookie_t u64) + +;; The type for the $d_namlen field of $dirent_t. +(typename $dirnamlen_t u32) + +;; File serial number that is unique within its file system. +(typename $inode_t u64) + +;; The type of a file descriptor or file. +(typename $filetype_t + (enum u8 + ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $FILETYPE_UNKNOWN + ;; The file descriptor or file refers to a block device inode. + $FILETYPE_BLOCK_DEVICE + ;; The file descriptor or file refers to a character device inode. + $FILETYPE_CHARACTER_DEVICE + ;; The file descriptor or file refers to a directory inode. + $FILETYPE_DIRECTORY + ;; The file descriptor or file refers to a regular file inode. + $FILETYPE_REGULAR_FILE + ;; The file descriptor or file refers to a datagram socket. + $FILETYPE_SOCKET_DGRAM + ;; The file descriptor or file refers to a byte-stream socket. + $FILETYPE_SOCKET_STREAM + ;; The file refers to a symbolic link inode. + $FILETYPE_SYMBOLIC_LINK + ) +) + +;; A directory entry. +(typename $dirent_t + (struct + ;; The offset of the next directory entry stored in this directory. + (field $d_next $dircookie_t) + ;; The serial number of the file referred to by this directory entry. + (field $d_ino $inode_t) + ;; The length of the name of the directory entry. + (field $d_namlen $dirnamlen_t) + ;; The type of the file referred to by this directory entry. + (field $d_type $filetype_t) + ) +) + +;; File or memory access pattern advisory information. +(typename $advice_t + (enum u8 + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE + ;; The application has no advice to give on its behavior with respect to the specified data. + $ADVICE_NORMAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM + ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in the near future. + $ADVICE_WILLNEED + ) +) + +;; File descriptor flags. +(typename $fdflags_t + (flags u16 + ;; Append mode: Data written to the file is always appended to the file's end. + (flag $FDFLAG_APPEND) + ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + (flag $FDFLAG_DSYNC) + ;; Non-blocking mode. + (flag $FDFLAG_NONBLOCK) + ;; Synchronized read I/O operations. + (flag $FDFLAG_RSYNC) + ;; Write according to synchronized I/O file integrity completion. In + ;; addition to synchronizing the data stored in the file, the implementation + ;; may also synchronously update the file's metadata. + (flag $FDFLAG_SYNC) + ) +) + +;; File descriptor attributes. +(typename $fdstat_t + (struct + ;; File type. + (field $fs_filetype $filetype_t) + ;; File descriptor flags. + (field $fs_flags $fdflags_t) + ;; Rights that apply to this file descriptor. + (field $fs_rights_base $rights_t) + ;; Maximum set of rights that may be installed on new file descriptors that + ;; are created through this file descriptor, e.g., through `path_open`. + (field $fs_rights_inheriting $rights_t) + ) +) + +;; Identifier for a device containing a file system. Can be used in combination +;; with `inode_t` to uniquely identify a file or directory in the filesystem. +(typename $device_t u64) + +;; Which file time attributes to adjust. +(typename $fstflags_t + (flags u16 + ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + (flag $FILESTAT_SET_ATIM) + ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + (flag $FILESTAT_SET_ATIM_NOW) + ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + (flag $FILESTAT_SET_MTIM) + ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + (flag $FILESTAT_SET_MTIM_NOW) + ) +) + +;; Flags determining the method of how paths are resolved. +(typename $lookupflags_t + (flags u32 + ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + (flag $LOOKUP_SYMLINK_FOLLOW) + ) +) + +;; Open flags used by `path_open`. +(typename $oflags_t + (flags u16 + ;; Create file if it does not exist. + (flag $O_CREAT) + ;; Fail if not a directory. + (flag $O_DIRECTORY) + ;; Fail if file already exists. + (flag $O_EXCL) + ;; Truncate file to size 0. + (flag $O_TRUNC) + ) +) + +;; Number of hard links to an inode. +(typename $linkcount_t u32) + +;; File attributes. +(typename $filestat_t + (struct + ;; Device ID of device containing the file. + (field $st_dev $device_t) + ;; File serial number. + (field $st_ino $inode_t) + ;; File type. + (field $st_filetype $filetype_t) + ;; Number of hard links to the file. + (field $st_nlink $linkcount_t) + ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + (field $st_size $filesize_t) + ;; Last data access timestamp. + (field $st_atim $timestamp_t) + ;; Last data modification timestamp. + (field $st_mtim $timestamp_t) + ;; Last file status change timestamp. + (field $st_ctim $timestamp_t) + ) +) + +;; User-provided value that may be attached to objects that is retained when +;; extracted from the implementation. +(typename $userdata_t u64) + +;; Type of a subscription to an event or its occurrence. +(typename $eventtype_t + (flags u8 + ;; The time value of clock `subscription_t::u.clock.clock_id` has + ;; reached timestamp `subscription_t::u.clock.timeout`. + (flag $EVENTTYPE_CLOCK) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;; available for reading. This event always triggers for regular files. + (flag $EVENTTYPE_FD_READ) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;; available for writing. This event always triggers for regular files. + (flag $EVENTTYPE_FD_WRITE) + ) +) + +;; The state of the file descriptor subscribed to with +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $eventrwflags_t + (flags u16 + ;; The peer of this socket has closed or disconnected. + (flag $EVENT_FD_READWRITE_HANGUP) + ) +) + +;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;; `EVENTTYPE_FD_WRITE`. +(typename $event_fd_readwrite_t + (struct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) + ) +) + +;; The contents of an $event_t. +(typename $event_u + (union + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $event_fd_readwrite_t) + ) +) + +;; An event that occurred. +(typename $event_t + (struct + ;; User-provided value that got attached to `subscription_t::userdata`. + (field $userdata $userdata_t) + ;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno_t) + ;; The type of the event that occurred. + (field $type $eventtype_t) + ;; The contents of the event. + (field $u $event_u) + ) +) + +;; Flags determining how to interpret the timestamp provided in +;; `subscription_t::u.clock.timeout.` +(typename $subclockflags_t + (flags u16 + ;; If set, treat the timestamp provided in + ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;; provided in `subscription_t::u.clock.timeout` relative to the + ;; current time value of clock `subscription_t::u.clock.clock_id.` + (flag $SUBSCRIPTION_CLOCK_ABSTIME) + ) +) + +;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +(typename $subscription_clock_t + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) +) + +;; The contents of a $subscription_t when type is type is +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $subscription_fd_readwrite_t + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) + ) +) + +;; The contents of a $subscription_t. +(typename $subscription_u + (union + ;; When type is `EVENTTYPE_CLOCK`: + (field $clock $subscription_clock_t) + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $subscription_fd_readwrite_t) + ) +) + +;; Subscription to an event. +(typename $subscription_t + (struct + ;; User-provided value that is attached to the subscription in the + ;; implementation and returned through `event_t::userdata`. + (field $userdata $userdata_t) + ;; The type of the event to which to subscribe. + (field $type $eventtype_t) + ;; The contents of the subscription. + (field $u $subscription_u) + ) +) + +;; Exit code generated by a process when exiting. +(typename $exitcode_t u32) + +;; Signal condition. +(typename $signal_t + (enum u8 + ;; Process abort signal. + ;; Action: Terminates the process. + $SIGABRT + ;; Alarm clock. + ;; Action: Terminates the process. + $SIGALRM + ;; Access to an undefined portion of a memory object. + ;; Action: Terminates the process. + $SIGBUS + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT + ;; Erroneous arithmetic operation. + ;; Action: Terminates the process. + $SIGFPE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Kill. + ;; Action: Terminates the process. + $SIGKILL + ;; Write on a pipe with no one to read it. + ;; Action: Ignored. + $SIGPIPE + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Invalid memory reference. + ;; Action: Terminates the process. + $SIGSEGV + ;; Stop executing. + ;; Action: Stops executing. + $SIGSTOP + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS + ;; Termination signal. + ;; Action: Terminates the process. + $SIGTERM + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP + ;; Terminal stop signal. + ;; Action: Stops executing. + $SIGTSTP + ;; Background process attempting read. + ;; Action: Stops executing. + $SIGTTIN + ;; Background process attempting write. + ;; Action: Stops executing. + $SIGTTOU + ;; High bandwidth data is available at a socket. + ;; Action: Ignored. + $SIGURG + ;; User-defined signal 1. + ;; Action: Terminates the process. + $SIGUSR1 + ;; User-defined signal 2. + ;; Action: Terminates the process. + $SIGUSR2 + ;; Virtual timer expired. + ;; Action: Terminates the process. + $SIGVTALRM + ;; CPU time limit exceeded. + ;; Action: Terminates the process. + $SIGXCPU + ;; File size limit exceeded. + ;; Action: Terminates the process. + $SIGXFSZ + ) +) + +;; Flags provided to `sock_recv`. +(typename $riflags_t + (flags u16 + ;; Returns the message without removing it from the socket's receive queue. + (flag $SOCK_RECV_PEEK) + ;; On byte-stream sockets, block until the full amount of data can be returned. + (flag $SOCK_RECV_WAITALL) + ) +) + +;; Flags returned by `sock_recv`. +(typename $roflags_t + (flags u16 + ;; Returned by `sock_recv`: Message data has been truncated. + (flag $SOCK_RECV_DATA_TRUNCATED) + ) +) + +;; Flags provided to `sock_send`. As there are currently no flags +;; defined, it must be set to zero. +(typename $siflags_t u16) + +;; Which channels on a socket to shut down. +(typename $sdflags_t + (flags u8 + ;; Disables further receive operations. + (flag $SHUT_RD) + ;; Disables further send operations. + (flag $SHUT_WR) + ) +) + +;; Identifiers for preopened capabilities. +(typename $preopentype_t + (enum u8 + ;; A pre-opened directory. + $PREOPENTYPE_DIR + ) +) + +;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +(typename $prestat_dir + (struct + ;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size_t) + ) +) + +;; The contents of an $prestat_t. +(typename $prestat_u + (union + ;; When type is `PREOPENTYPE_DIR`: + (field $dir $prestat_dir) + ) +) + +;; Information about a pre-opened capability. +(typename $prestat_t + (struct + ;; The type of the pre-opened capability. + (field $pr_type $preopentype_t) + ;; The contents of the information. + (field $u $prestat_u) + ) +) diff --git a/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx new file mode 100644 index 000000000..08efc87fa --- /dev/null +++ b/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx @@ -0,0 +1,526 @@ +;; WASI Preview. This is an evolution of the API that WASI initially +;; launched with. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_unstable_preview0 + ;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;; Read command-line argument data. + ;; The size of the array should match that returned by `wasi_args_sizes_get()` + (@interface func (export "args_get") + (param $argv (@witx pointer (@witx pointer u8))) + (param $argv_buf (@witx pointer u8)) + (result $error $errno_t) + ) + ;; Return command-line argument data sizes. + (@interface func (export "args_sizes_get") + (result $error $errno_t) + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Read environment variable data. + ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + (@interface func (export "environ_get") + (param $environ (@witx pointer (@witx pointer u8))) + (param $environ_buf (@witx pointer u8)) + (result $error $errno_t) + ) + ;; Return command-line argument data sizes. + (@interface func (export "environ_sizes_get") + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Return the resolution of a clock. + ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;; Note: This is similar to `clock_getres` in POSIX. + (@interface func (export "clock_res_get") + (result $error $errno_t) + ;; The clock for which to return the resolution. + (param $clock_id $clockid_t) + ;; The resolution of the clock. + (result $resolution $timestamp_t) + ) + ;; Return the time value of a clock. + ;; Note: This is similar to `clock_gettime` in POSIX. + (@interface func (export "clock_time_get") + ;; The clock for which to return the time. + (param $clock_id $clockid_t) + ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp_t) + (result $error $errno_t) + ;; The time value of the clock. + (result $time $timestamp_t) + ) + + ;; Provide file advisory information on a file descriptor. + ;; Note: This is similar to `posix_fadvise` in POSIX. + (@interface func (export "fd_advise") + (param $fd $fd_t) + (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. + (param $len $filesize_t) ;; The length of the region to which the advisory applies. + (param $advice $advice_t) ;; The advice. + (result $error $errno_t) + ) + + ;; Force the allocation of space in a file. + ;; Note: This is similar to `posix_fallocate` in POSIX. + (@interface func (export "fd_allocate") + (param $fd $fd_t) + ;; The offset at which to start the allocation. + (param $offset $filesize_t) + ;; The length of the area that is allocated. + (param $len $filesize_t) + (result $error $errno_t) + ) + + ;; Close a file descriptor. + ;; Note: This is similar to `close` in POSIX. + (@interface func (export "fd_close") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Synchronize the data of a file to disk. + ;; Note: This is similar to `fdatasync` in POSIX. + (@interface func (export "fd_datasync") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Get the attributes of a file descriptor. + ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (@interface func (export "fd_fdstat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the file descriptor's attributes are stored. + (result $stat $fdstat_t) + ) + + ;; Adjust the flags associated with a file descriptor. + ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (@interface func (export "fd_fdstat_set_flags") + (param $fd $fd_t) + ;; The desired values of the file descriptor flags. + (param $flags $fdflags_t) + (result $error $errno_t) + ) + + ;; Adjust the rights associated with a file descriptor. + ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (@interface func (export "fd_fdstat_set_rights") + (param $fd $fd_t) + ;; The desired rights of the file descriptor. + (param $fs_rights_base $rights_t) + (param $fs_rights_inheriting $rights_t) + (result $error $errno_t) + ) + + ;; Return the attributes of an open file. + (@interface func (export "fd_filestat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $fs_rights_base $rights_t) + ) + + ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;; Note: This is similar to `ftruncate` in POSIX. + (@interface func (export "fd_filestat_set_size") + (param $fd $fd_t) + ;; The desired file size. + (param $st_size $filesize_t) + (result $error $errno_t) + ) + + ;; Adjust the timestamps of an open file or directory. + ;; Note: This is similar to `futimens` in POSIX. + (@interface func (export "fd_filestat_set_times") + (param $fd $fd_t) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `preadv` in POSIX. + (@interface func (export "fd_pread") + (param $fd $fd_t) + ;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to read. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the description is stored. + (result $buf $prestat_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_dir_name") + (param $fd $fd_t) + ;; A buffer into which to write the preopened directory name. + (param $path (@witx pointer u8)) + (param $path_len $size_t) + (result $error $errno_t) + ) + + ;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `pwritev` in POSIX. + (@interface func (export "fd_pwrite") + (param $fd $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_t_array) + ;; The offset within the file at which to write. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Read from a file descriptor. + ;; Note: This is similar to `readv` in POSIX. + (@interface func (export "fd_read") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Read directory entries from a directory. + ;; When successful, the contents of the output buffer consist of a sequence of + ;; directory entries. Each directory entry consists of a dirent_t object, + ;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;; entry. + ;; + ;; This function fills the output buffer as much as possible, potentially + ;; truncating the last directory entry. This allows the caller to grow its + ;; read buffer size in case it's too small to fit a single large directory + ;; entry, or skip the oversized directory entry. + (@interface func (export "fd_readdir") + (param $fd $fd_t) + ;; The buffer where directory entries are stored + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + ;; The location within the directory to start reading + (param $cookie $dircookie_t) + (result $error $errno_t) + ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size_t) + ) + + ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; + ;; Due to the strong focus on thread safety, this environment does not provide + ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;; file descriptor with the same number could be allocated by a different + ;; thread at the same time. + ;; + ;; This function provides a way to atomically renumber file descriptors, which + ;; would disappear if `dup2()` were to be removed entirely. + (@interface func (export "fd_renumber") + (param $fd $fd_t) + ;; The file descriptor to overwrite. + (param $to $fd_t) + (result $error $errno_t) + ) + + ;; Move the offset of a file descriptor. + ;; Note: This is similar to `lseek` in POSIX. + (@interface func (export "fd_seek") + (param $fd $fd_t) + ;; The number of bytes to move. + (param $offset $filedelta_t) + ;; The base from which the offset is relative. + (param $whence $whence_t) + (result $error $errno_t) + ;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize_t) + ) + + ;; Synchronize the data and metadata of a file to disk. + ;; Note: This is similar to `fsync` in POSIX. + (@interface func (export "fd_sync") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Return the current offset of a file descriptor. + ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (@interface func (export "fd_tell") + (param $fd $fd_t) + (result $error $errno_t) + ;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize_t) + ) + + ;; Write to a file descriptor. + ;; Note: This is similar to `writev` in POSIX. + (@interface func (export "fd_write") + (param $fd $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_t_array) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Create a directory. + ;; Note: This is similar to `mkdirat` in POSIX. + (@interface func (export "path_create_directory") + (param $fd $fd_t) + ;; The path at which to create the directory. + (param $path string) + (result $error $errno_t) + ) + + ;; Return the attributes of a file or directory. + ;; Note: This is similar to `stat` in POSIX. + (@interface func (export "path_filestat_get") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $buf $filestat_t) + ) + + ;; Adjust the timestamps of a file or directory. + ;; Note: This is similar to `utimensat` in POSIX. + (@interface func (export "path_filestat_set_times") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to operate on. + (param $path string) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Create a hard link. + ;; Note: This is similar to `linkat` in POSIX. + (@interface func (export "path_link") + (param $old_fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags_t) + ;; The source path from which to link. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd_t) + ;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Open a file or directory. + ;; + ;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;; file descriptor not currently open; it is randomized to prevent + ;; applications from depending on making assumptions about indexes, since this + ;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;; guaranteed to be less than 2**31. + ;; + ;; Note: This is similar to `openat` in POSIX. + (@interface func (export "path_open") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags_t) + ;; The relative path of the file or directory to open, relative to the + ;; `dirfd` directory. + (param $path string) + ;; The method by which to open the file. + (param $o_flags $oflags_t) + ;; The initial rights of the newly created file descriptor. The + ;; implementation is allowed to return a file descriptor with fewer rights + ;; than specified, if and only if those rights do not apply to the type of + ;; file being opened. + ;; + ;; The base rights are rights that will apply to operations using the file + ;; descriptor itself, while the inheriting rights are rights that apply to + ;; file descriptors derived from it. + (param $fs_rights_base $rights_t) + (param $fs_rights_inherting $rights_t) + (result $error $errno_t) + ;; The file descriptor of the file that has been opened. + (result $opened_fd $fd_t) + ) + + ;; Read the contents of a symbolic link. + ;; Note: This is similar to `readlinkat` in POSIX. + (@interface func (export "path_readlink") + (param $fd $fd_t) + ;; The path of the symbolic link from which to read. + (param $path string) + ;; The buffer to which to write the contents of the symbolic link. + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + (result $error $errno_t) + ;; The number of bytes placed in the buffer. + (result $bufused $size_t) + ) + + ;; Remove a directory. + ;; Return `ENOTEMPTY` if the directory is not empty. + ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (@interface func (export "path_remove_directory") + (param $fd $fd_t) + ;; The path to a directory to remove. + (param $path string) + (result $error $errno_t) + ) + + ;; Rename a file or directory. + ;; Note: This is similar to `renameat` in POSIX. + (@interface func (export "path_rename") + (param $fd $fd_t) + ;; The source path of the file or directory to rename. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd_t) + ;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Create a symbolic link. + ;; Note: This is similar to `symlinkat` in POSIX. + (@interface func (export "path_symlink") + (param $fd $fd_t) + ;; The contents of the symbolic link. + (param $old_path string) + ;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno_t) + ) + + + ;; Unlink a file. + ;; Return `EISDIR` if the path refers to a directory. + ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (@interface func (export "path_unlink_file") + (param $fd $fd_t) + ;; The path to a file to unlink. + (param $path string) + (result $error $errno_t) + ) + + ;; Concurrently poll for the occurrence of a set of events. + (@interface func (export "poll_oneoff") + ;; The events to which to subscribe. + (param $in (@witx const_pointer $subscription_t)) + ;; The events that have occurred. + (param $out (@witx pointer $event_t)) + ;; Both the number of subscriptions and events. + (param $nsubscriptions $size_t) + (result $error $errno_t) + ;; The number of events stored. + (result $nevents $size_t) + ) + + ;; Terminate the process normally. An exit code of 0 indicates successful + ;; termination of the program. The meanings of other values is dependent on + ;; the environment. + (@interface func (export "proc_exit") + ;; The exit code returned by the process. + (param $rval $exitcode_t) + ) + + ;; Send a signal to the process of the calling thread. + ;; Note: This is similar to `raise` in POSIX. + (@interface func (export "proc_raise") + ;; The signal condition to trigger. + (param $sig $signal_t) + (result $error $errno_t) + ) + + ;; Temporarily yield execution of the calling thread. + ;; Note: This is similar to `sched_yield` in POSIX. + (@interface func (export "proc_sched_yield") + (result $error $errno_t) + ) + + ;; Write high-quality random data into a buffer. + ;; This function blocks when the implementation is unable to immediately + ;; provide sufficient high-quality random data. + ;; This function may execute slowly, so when large mounts of random data are + ;; required, it's advisable to use this function to seed a pseudo-random + ;; number generator, rather than to provide the random data directly. + (@interface func (export "random_get") + ;; The buffer to fill with random data. + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + (result $error $errno_t) + ) + + ;; Receive a message from a socket. + ;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;; the data into multiple buffers in the manner of `readv`. + (@interface func (export "sock_recv") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_t_array) + ;; Message flags. + (param $ri_flags $riflags_t) + (result $error $errno_t) + ;; Number of bytes stored in ri_data. + (result $ro_datalen $size_t) + ;; Message flags. + (result $ro_flags $roflags_t) + ) + + ;; Send a message on a socket. + ;; Note: This is similar to `send` in POSIX, though it also supports writing + ;; the data from multiple buffers in the manner of `writev`. + (@interface func (export "sock_send") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_t_array) + ;; Message flags. + (param $si_flags $siflags_t) + (result $error $errno_t) + ;; Number of bytes transmitted. + (result $so_datalen $size_t) + ) + + ;; Shut down socket send and receive channels. + ;; Note: This is similar to `shutdown` in POSIX. + (@interface func (export "sock_shutdown") + (param $fd $fd_t) + ;; Which channels on the socket to shut down. + (param $how $sdflags_t) + (result $error $errno_t) + ) +) From a60945a7f54aa84bcbb6b3ca44ccdbd4eb35ff40 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 18 Sep 2019 12:51:09 -0700 Subject: [PATCH 0168/1772] Create a phased structure for API development (#88) * Create a structure for phased development. This PR takes the `witx` concept from #74 and creates a directory structure around it for enabling phased development of new APIs and changes to existing APIs. See the README.md changes for details. * Apply the validation fix from #90 to the new copies. --- proposals/filesystem/README.md | 2 + proposals/filesystem/phases/README.md | 53 + .../ephemeral/docs/wasi_ephemeral_preview.md} | 16 +- .../ephemeral/witx}/typenames.witx | 2 +- .../witx/wasi_ephemeral_preview.witx | 526 ++++ .../phases/old/docs/wasi_unstable_preview0.md | 2319 +++++++++++++++++ .../filesystem/phases/old/witx/typenames.witx | 752 ++++++ .../old/witx}/wasi_unstable.witx | 6 +- .../unstable/docs/wasi_unstable_preview0.md | 2319 +++++++++++++++++ .../phases/unstable/witx/typenames.witx | 752 ++++++ .../unstable/witx/wasi_unstable_preview0.witx | 526 ++++ 11 files changed, 7265 insertions(+), 8 deletions(-) create mode 100644 proposals/filesystem/phases/README.md rename proposals/filesystem/{design/WASI-core.md => phases/ephemeral/docs/wasi_ephemeral_preview.md} (99%) rename proposals/filesystem/{design/wasi_unstable => phases/ephemeral/witx}/typenames.witx (99%) create mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx create mode 100644 proposals/filesystem/phases/old/docs/wasi_unstable_preview0.md create mode 100644 proposals/filesystem/phases/old/witx/typenames.witx rename proposals/filesystem/{design/wasi_unstable => phases/old/witx}/wasi_unstable.witx (98%) create mode 100644 proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md create mode 100644 proposals/filesystem/phases/unstable/witx/typenames.witx create mode 100644 proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index 7fc421229..31bb340e1 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -22,3 +22,5 @@ discussions. Schedules and agendas for video conference and in-person meetings are posted [here](meetings/README.md). + +API specification proposals are [here](phases/README.md). diff --git a/proposals/filesystem/phases/README.md b/proposals/filesystem/phases/README.md new file mode 100644 index 000000000..00d49afef --- /dev/null +++ b/proposals/filesystem/phases/README.md @@ -0,0 +1,53 @@ +# WASI development process + +## WASI uses a 3-phase process: + +- [`ephemeral`](ephemeral): The development staging area. New API + proposals API-changing fixes to existing APIs should be submitted + as Pull Requests making changes to this directory. This directory + provides no API stability or versioning. APIs in this directory use + API module names starting with `wasi_ephemeral_`. + +- [`unstable`](unstable): Usable APIs. APIs in `ephemeral` will be + occasionally snapshotted and promoted into `unstable`, with approval + from the Subgroup, considering the overall suitability of the APIs + themselves, their documentation, test coverage, and availability of + polyfills when appropriate. Once merged, the API modules will be + considered stable, though they may be superseded by newer versions. + Proposals to promote specific APIs should be submitted as Pull Requests + that: + - Move any superseded files out of `unstable` into `old`. + - Optionally add polyfills for superseded APIs using `unstable` APIs. + - Move all files supporting the APIs out of `ephemeral into `unstable`. + - Rename the API modules from `wasi_ephemeral_` to `wasi_unstable_` + and append a version number. + + Pull Requests may also add additional tests, documentation, or + polyfills for existing `unstable` APIs. + +- [`old`](old): When APIs in `current` spec are replaced by new + versions, the old API modules are moved to the `old` directory. When + possible, `old` APIs may be accompanied by polyfill modules which + implement their API in terms of newer versions of the API. + +## Rationale + +### Relationship to the CG's phases + +When WASI becomes more mature, such that we have an established base +and we're adding incremental functionality to it, we may want to adopt +a process like [the CG's phases]. However, right now, everything in +WASI is undergoing changes, so we have a greater need to iterate with +flexibility. + +### Relationship to standards + +WASI should eventually become a standard at the level of WebAssembly +itself. Right now, it needs a lot of work before it's ready. The +`unstable` tree is meant to serve a practical purpose for people who +want to work with APIs today, with the understanding that everything +is still evolving. It's not meant as a replacement for proper +standardization, which will happen once the overall API is more +mature. + +[the CG's phases]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md diff --git a/proposals/filesystem/design/WASI-core.md b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md similarity index 99% rename from proposals/filesystem/design/WASI-core.md rename to proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md index c4b256ad3..9db4a382e 100644 --- a/proposals/filesystem/design/WASI-core.md +++ b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -34,13 +34,12 @@ This file is automatically generated. Do not edit. Source: https://github.com/NuxiNL/cloudabi --> -# WASI Core API +# The WASI Preview API -This is the API-level documentation for WASI Core. The function names +This is the API-level documentation for WASI Preview. The function names are prefixed with "\_\_wasi\_" to reflect how they are spelled in flat-namespace contexts, however at the wasm module level, they are -unprefixed, because they're inside a module namespace (currently -"wasi\_unstable"). +unprefixed, because they're inside a module namespace. Functions that start with `__wasi_fd_` operate on file descriptors, while functions that start with `__wasi_path_` operate on filesystem @@ -48,16 +47,21 @@ paths, which are relative to directory file descriptors. Much inspiration and content here is derived from [CloudABI] and [POSIX], though there are also several differences from CloudABI and POSIX. For -example, WASI Core has no concept of processes in the traditional Unix +example, WASI Preview has no concept of processes in the traditional Unix sense. While wasm linear memories have some of the aspects of processes, and it's possible to *emulate* the full semantics of processes on top of them, this can sometimes be unnatural and inefficient. The goal for -WASI Core is to be a WebAssembly-native API that exposes APIs that fit +WASI Preview is to be a WebAssembly-native API that exposes APIs that fit well into the underlying WebAssembly platform, rather than to directly emulate other platforms. This is also a work in progress, and the API here is still evolving. +Historical note: this API was originally named "WASI Core", and used the +API module name "wasi\_unstable". We've since sought to deemphasize the +"Core" name, as the goal is to split this API up into independent +modules so that embedders need not implement all of it. + [CloudABI]: https://github.com/NuxiNL/cloudabi [POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ diff --git a/proposals/filesystem/design/wasi_unstable/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx similarity index 99% rename from proposals/filesystem/design/wasi_unstable/typenames.witx rename to proposals/filesystem/phases/ephemeral/witx/typenames.witx index 046ed0bf6..e04a188d9 100644 --- a/proposals/filesystem/design/wasi_unstable/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -1,4 +1,4 @@ -;; Type names used by the wasi_unstable module type. +;; Type names used by low-level WASI interfaces. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). ;; diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx new file mode 100644 index 000000000..4f31fe510 --- /dev/null +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -0,0 +1,526 @@ +;; WASI Preview. This is an evolution of the API that WASI initially +;; launched with. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_preview + ;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;; Read command-line argument data. + ;; The size of the array should match that returned by `wasi_args_sizes_get()` + (@interface func (export "args_get") + (param $argv (@witx pointer (@witx pointer u8))) + (param $argv_buf (@witx pointer u8)) + (result $error $errno_t) + ) + ;; Return command-line argument data sizes. + (@interface func (export "args_sizes_get") + (result $error $errno_t) + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Read environment variable data. + ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + (@interface func (export "environ_get") + (param $environ (@witx pointer (@witx pointer u8))) + (param $environ_buf (@witx pointer u8)) + (result $error $errno_t) + ) + ;; Return command-line argument data sizes. + (@interface func (export "environ_sizes_get") + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Return the resolution of a clock. + ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;; Note: This is similar to `clock_getres` in POSIX. + (@interface func (export "clock_res_get") + (result $error $errno_t) + ;; The clock for which to return the resolution. + (param $clock_id $clockid_t) + ;; The resolution of the clock. + (result $resolution $timestamp_t) + ) + ;; Return the time value of a clock. + ;; Note: This is similar to `clock_gettime` in POSIX. + (@interface func (export "clock_time_get") + ;; The clock for which to return the time. + (param $clock_id $clockid_t) + ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp_t) + (result $error $errno_t) + ;; The time value of the clock. + (result $time $timestamp_t) + ) + + ;; Provide file advisory information on a file descriptor. + ;; Note: This is similar to `posix_fadvise` in POSIX. + (@interface func (export "fd_advise") + (param $fd $fd_t) + (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. + (param $len $filesize_t) ;; The length of the region to which the advisory applies. + (param $advice $advice_t) ;; The advice. + (result $error $errno_t) + ) + + ;; Force the allocation of space in a file. + ;; Note: This is similar to `posix_fallocate` in POSIX. + (@interface func (export "fd_allocate") + (param $fd $fd_t) + ;; The offset at which to start the allocation. + (param $offset $filesize_t) + ;; The length of the area that is allocated. + (param $len $filesize_t) + (result $error $errno_t) + ) + + ;; Close a file descriptor. + ;; Note: This is similar to `close` in POSIX. + (@interface func (export "fd_close") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Synchronize the data of a file to disk. + ;; Note: This is similar to `fdatasync` in POSIX. + (@interface func (export "fd_datasync") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Get the attributes of a file descriptor. + ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (@interface func (export "fd_fdstat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the file descriptor's attributes are stored. + (result $stat $fdstat_t) + ) + + ;; Adjust the flags associated with a file descriptor. + ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (@interface func (export "fd_fdstat_set_flags") + (param $fd $fd_t) + ;; The desired values of the file descriptor flags. + (param $flags $fdflags_t) + (result $error $errno_t) + ) + + ;; Adjust the rights associated with a file descriptor. + ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (@interface func (export "fd_fdstat_set_rights") + (param $fd $fd_t) + ;; The desired rights of the file descriptor. + (param $fs_rights_base $rights_t) + (param $fs_rights_inheriting $rights_t) + (result $error $errno_t) + ) + + ;; Return the attributes of an open file. + (@interface func (export "fd_filestat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $fs_rights_base $rights_t) + ) + + ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;; Note: This is similar to `ftruncate` in POSIX. + (@interface func (export "fd_filestat_set_size") + (param $fd $fd_t) + ;; The desired file size. + (param $st_size $filesize_t) + (result $error $errno_t) + ) + + ;; Adjust the timestamps of an open file or directory. + ;; Note: This is similar to `futimens` in POSIX. + (@interface func (export "fd_filestat_set_times") + (param $fd $fd_t) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `preadv` in POSIX. + (@interface func (export "fd_pread") + (param $fd $fd_t) + ;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to read. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the description is stored. + (result $buf $prestat_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_dir_name") + (param $fd $fd_t) + ;; A buffer into which to write the preopened directory name. + (param $path (@witx pointer u8)) + (param $path_len $size_t) + (result $error $errno_t) + ) + + ;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `pwritev` in POSIX. + (@interface func (export "fd_pwrite") + (param $fd $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_t_array) + ;; The offset within the file at which to write. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Read from a file descriptor. + ;; Note: This is similar to `readv` in POSIX. + (@interface func (export "fd_read") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Read directory entries from a directory. + ;; When successful, the contents of the output buffer consist of a sequence of + ;; directory entries. Each directory entry consists of a dirent_t object, + ;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;; entry. + ;; + ;; This function fills the output buffer as much as possible, potentially + ;; truncating the last directory entry. This allows the caller to grow its + ;; read buffer size in case it's too small to fit a single large directory + ;; entry, or skip the oversized directory entry. + (@interface func (export "fd_readdir") + (param $fd $fd_t) + ;; The buffer where directory entries are stored + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + ;; The location within the directory to start reading + (param $cookie $dircookie_t) + (result $error $errno_t) + ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size_t) + ) + + ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; + ;; Due to the strong focus on thread safety, this environment does not provide + ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;; file descriptor with the same number could be allocated by a different + ;; thread at the same time. + ;; + ;; This function provides a way to atomically renumber file descriptors, which + ;; would disappear if `dup2()` were to be removed entirely. + (@interface func (export "fd_renumber") + (param $fd $fd_t) + ;; The file descriptor to overwrite. + (param $to $fd_t) + (result $error $errno_t) + ) + + ;; Move the offset of a file descriptor. + ;; Note: This is similar to `lseek` in POSIX. + (@interface func (export "fd_seek") + (param $fd $fd_t) + ;; The number of bytes to move. + (param $offset $filedelta_t) + ;; The base from which the offset is relative. + (param $whence $whence_t) + (result $error $errno_t) + ;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize_t) + ) + + ;; Synchronize the data and metadata of a file to disk. + ;; Note: This is similar to `fsync` in POSIX. + (@interface func (export "fd_sync") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Return the current offset of a file descriptor. + ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (@interface func (export "fd_tell") + (param $fd $fd_t) + (result $error $errno_t) + ;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize_t) + ) + + ;; Write to a file descriptor. + ;; Note: This is similar to `writev` in POSIX. + (@interface func (export "fd_write") + (param $fd $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_t_array) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Create a directory. + ;; Note: This is similar to `mkdirat` in POSIX. + (@interface func (export "path_create_directory") + (param $fd $fd_t) + ;; The path at which to create the directory. + (param $path string) + (result $error $errno_t) + ) + + ;; Return the attributes of a file or directory. + ;; Note: This is similar to `stat` in POSIX. + (@interface func (export "path_filestat_get") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $buf $filestat_t) + ) + + ;; Adjust the timestamps of a file or directory. + ;; Note: This is similar to `utimensat` in POSIX. + (@interface func (export "path_filestat_set_times") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to operate on. + (param $path string) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Create a hard link. + ;; Note: This is similar to `linkat` in POSIX. + (@interface func (export "path_link") + (param $old_fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags_t) + ;; The source path from which to link. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd_t) + ;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Open a file or directory. + ;; + ;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;; file descriptor not currently open; it is randomized to prevent + ;; applications from depending on making assumptions about indexes, since this + ;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;; guaranteed to be less than 2**31. + ;; + ;; Note: This is similar to `openat` in POSIX. + (@interface func (export "path_open") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags_t) + ;; The relative path of the file or directory to open, relative to the + ;; `dirfd` directory. + (param $path string) + ;; The method by which to open the file. + (param $o_flags $oflags_t) + ;; The initial rights of the newly created file descriptor. The + ;; implementation is allowed to return a file descriptor with fewer rights + ;; than specified, if and only if those rights do not apply to the type of + ;; file being opened. + ;; + ;; The base rights are rights that will apply to operations using the file + ;; descriptor itself, while the inheriting rights are rights that apply to + ;; file descriptors derived from it. + (param $fs_rights_base $rights_t) + (param $fs_rights_inherting $rights_t) + (result $error $errno_t) + ;; The file descriptor of the file that has been opened. + (result $opened_fd $fd_t) + ) + + ;; Read the contents of a symbolic link. + ;; Note: This is similar to `readlinkat` in POSIX. + (@interface func (export "path_readlink") + (param $fd $fd_t) + ;; The path of the symbolic link from which to read. + (param $path string) + ;; The buffer to which to write the contents of the symbolic link. + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + (result $error $errno_t) + ;; The number of bytes placed in the buffer. + (result $bufused $size_t) + ) + + ;; Remove a directory. + ;; Return `ENOTEMPTY` if the directory is not empty. + ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (@interface func (export "path_remove_directory") + (param $fd $fd_t) + ;; The path to a directory to remove. + (param $path string) + (result $error $errno_t) + ) + + ;; Rename a file or directory. + ;; Note: This is similar to `renameat` in POSIX. + (@interface func (export "path_rename") + (param $fd $fd_t) + ;; The source path of the file or directory to rename. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd_t) + ;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Create a symbolic link. + ;; Note: This is similar to `symlinkat` in POSIX. + (@interface func (export "path_symlink") + (param $fd $fd_t) + ;; The contents of the symbolic link. + (param $old_path string) + ;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno_t) + ) + + + ;; Unlink a file. + ;; Return `EISDIR` if the path refers to a directory. + ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (@interface func (export "path_unlink_file") + (param $fd $fd_t) + ;; The path to a file to unlink. + (param $path string) + (result $error $errno_t) + ) + + ;; Concurrently poll for the occurrence of a set of events. + (@interface func (export "poll_oneoff") + ;; The events to which to subscribe. + (param $in (@witx const_pointer $subscription_t)) + ;; The events that have occurred. + (param $out (@witx pointer $event_t)) + ;; Both the number of subscriptions and events. + (param $nsubscriptions $size_t) + (result $error $errno_t) + ;; The number of events stored. + (result $nevents $size_t) + ) + + ;; Terminate the process normally. An exit code of 0 indicates successful + ;; termination of the program. The meanings of other values is dependent on + ;; the environment. + (@interface func (export "proc_exit") + ;; The exit code returned by the process. + (param $rval $exitcode_t) + ) + + ;; Send a signal to the process of the calling thread. + ;; Note: This is similar to `raise` in POSIX. + (@interface func (export "proc_raise") + ;; The signal condition to trigger. + (param $sig $signal_t) + (result $error $errno_t) + ) + + ;; Temporarily yield execution of the calling thread. + ;; Note: This is similar to `sched_yield` in POSIX. + (@interface func (export "proc_sched_yield") + (result $error $errno_t) + ) + + ;; Write high-quality random data into a buffer. + ;; This function blocks when the implementation is unable to immediately + ;; provide sufficient high-quality random data. + ;; This function may execute slowly, so when large mounts of random data are + ;; required, it's advisable to use this function to seed a pseudo-random + ;; number generator, rather than to provide the random data directly. + (@interface func (export "random_get") + ;; The buffer to fill with random data. + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + (result $error $errno_t) + ) + + ;; Receive a message from a socket. + ;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;; the data into multiple buffers in the manner of `readv`. + (@interface func (export "sock_recv") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_t_array) + ;; Message flags. + (param $ri_flags $riflags_t) + (result $error $errno_t) + ;; Number of bytes stored in ri_data. + (result $ro_datalen $size_t) + ;; Message flags. + (result $ro_flags $roflags_t) + ) + + ;; Send a message on a socket. + ;; Note: This is similar to `send` in POSIX, though it also supports writing + ;; the data from multiple buffers in the manner of `writev`. + (@interface func (export "sock_send") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_t_array) + ;; Message flags. + (param $si_flags $siflags_t) + (result $error $errno_t) + ;; Number of bytes transmitted. + (result $so_datalen $size_t) + ) + + ;; Shut down socket send and receive channels. + ;; Note: This is similar to `shutdown` in POSIX. + (@interface func (export "sock_shutdown") + (param $fd $fd_t) + ;; Which channels on the socket to shut down. + (param $how $sdflags_t) + (result $error $errno_t) + ) +) diff --git a/proposals/filesystem/phases/old/docs/wasi_unstable_preview0.md b/proposals/filesystem/phases/old/docs/wasi_unstable_preview0.md new file mode 100644 index 000000000..9db4a382e --- /dev/null +++ b/proposals/filesystem/phases/old/docs/wasi_unstable_preview0.md @@ -0,0 +1,2319 @@ + + +# The WASI Preview API + +This is the API-level documentation for WASI Preview. The function names +are prefixed with "\_\_wasi\_" to reflect how they are spelled in +flat-namespace contexts, however at the wasm module level, they are +unprefixed, because they're inside a module namespace. + +Functions that start with `__wasi_fd_` operate on file descriptors, +while functions that start with `__wasi_path_` operate on filesystem +paths, which are relative to directory file descriptors. + +Much inspiration and content here is derived from [CloudABI] and [POSIX], +though there are also several differences from CloudABI and POSIX. For +example, WASI Preview has no concept of processes in the traditional Unix +sense. While wasm linear memories have some of the aspects of processes, +and it's possible to *emulate* the full semantics of processes on top of +them, this can sometimes be unnatural and inefficient. The goal for +WASI Preview is to be a WebAssembly-native API that exposes APIs that fit +well into the underlying WebAssembly platform, rather than to directly +emulate other platforms. + +This is also a work in progress, and the API here is still evolving. + +Historical note: this API was originally named "WASI Core", and used the +API module name "wasi\_unstable". We've since sought to deemphasize the +"Core" name, as the goal is to split this API up into independent +modules so that embedders need not implement all of it. + +[CloudABI]: https://github.com/NuxiNL/cloudabi +[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ + +## System calls + +- [`__wasi_args_get()`](#args_get) +- [`__wasi_args_sizes_get()`](#args_sizes_get) +- [`__wasi_clock_res_get()`](#clock_res_get) +- [`__wasi_clock_time_get()`](#clock_time_get) +- [`__wasi_environ_get()`](#environ_get) +- [`__wasi_environ_sizes_get()`](#environ_sizes_get) +- [`__wasi_fd_advise()`](#fd_advise) +- [`__wasi_fd_allocate()`](#fd_allocate) +- [`__wasi_fd_close()`](#fd_close) +- [`__wasi_fd_datasync()`](#fd_datasync) +- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) +- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) +- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) +- [`__wasi_fd_filestat_get()`](#fd_filestat_get) +- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) +- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) +- [`__wasi_fd_pread()`](#fd_pread) +- [`__wasi_fd_prestat_get()`](#fd_prestat_get) +- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) +- [`__wasi_fd_pwrite()`](#fd_pwrite) +- [`__wasi_fd_read()`](#fd_read) +- [`__wasi_fd_readdir()`](#fd_readdir) +- [`__wasi_fd_renumber()`](#fd_renumber) +- [`__wasi_fd_seek()`](#fd_seek) +- [`__wasi_fd_sync()`](#fd_sync) +- [`__wasi_fd_tell()`](#fd_tell) +- [`__wasi_fd_write()`](#fd_write) +- [`__wasi_path_create_directory()`](#path_create_directory) +- [`__wasi_path_filestat_get()`](#path_filestat_get) +- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) +- [`__wasi_path_link()`](#path_link) +- [`__wasi_path_open()`](#path_open) +- [`__wasi_path_readlink()`](#path_readlink) +- [`__wasi_path_remove_directory()`](#path_remove_directory) +- [`__wasi_path_rename()`](#path_rename) +- [`__wasi_path_symlink()`](#path_symlink) +- [`__wasi_path_unlink_file()`](#path_unlink_file) +- [`__wasi_poll_oneoff()`](#poll_oneoff) +- [`__wasi_proc_exit()`](#proc_exit) +- [`__wasi_proc_raise()`](#proc_raise) +- [`__wasi_random_get()`](#random_get) +- [`__wasi_sched_yield()`](#sched_yield) +- [`__wasi_sock_recv()`](#sock_recv) +- [`__wasi_sock_send()`](#sock_send) +- [`__wasi_sock_shutdown()`](#sock_shutdown) + +### `__wasi_args_get()` + +Read command-line argument data. + +The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + +Inputs: + +- char \*\*argv + + A pointer to a buffer to write the argument pointers. + +- char \*argv\_buf + + A pointer to a buffer to write the argument string data. + +### `__wasi_args_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*argc + + The number of arguments. + +- size\_t \*argv\_buf\_size + + The size of the argument string data. + +### `__wasi_clock_res_get()` + +Return the resolution of a clock. + +Implementations are required to provide a non-zero value for supported clocks. +For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). + +Note: This is similar to `clock_getres` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the resolution. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) resolution + + The resolution of the clock. + +### `__wasi_clock_time_get()` + +Return the time value of a clock. + +Note: This is similar to `clock_gettime` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the time. + +- [\_\_wasi\_timestamp\_t](#timestamp) precision + + The maximum lag (exclusive) that the returned + time value may have, compared to its actual + value. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) time + + The time value of the clock. + +### `__wasi_environ_get()` + +Read environment variable data. + +The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + +Inputs: + +- char \*\*environ + + A pointer to a buffer to write the environment variable pointers. + +- char \*environ\_buf + + A pointer to a buffer to write the environment variable string data. + +### `__wasi_environ_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*environ\_count + + The number of environment variables. + +- size\_t \*environ\_buf\_size + + The size of the environment variable string data. + +### `__wasi_fd_advise()` + +Provide file advisory information on a file descriptor. + +Note: This is similar to `posix_fadvise` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file for which to provide file advisory information. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file to which the advisory applies. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the region to which the advisory applies. + +- [\_\_wasi\_advice\_t](#advice) advice + + The advice. + +### `__wasi_fd_allocate()` + +Force the allocation of space in a file. + +Note: This is similar to `posix_fallocate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file in which to allocate space. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset at which to start the allocation. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the area that is allocated. + +### `__wasi_fd_close()` + +Close a file descriptor. + +Note: This is similar to `close` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to close. + +### `__wasi_fd_datasync()` + +Synchronize the data of a file to disk. + +Note: This is similar to `fdatasync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file to synchronize to disk. + +### `__wasi_fd_fdstat_get()` + +Get the attributes of a file descriptor. + +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well +as additional fields. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_fdstat\_t](#fdstat) \*buf + + The buffer where the file descriptor's attributes are stored. + +### `__wasi_fd_fdstat_set_flags()` + +Adjust the flags associated with a file descriptor. + +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_fdflags\_t](#fdflags) flags + + The desired values of the file descriptor + flags. + +### `__wasi_fd_fdstat_set_rights()` + +Adjust the rights associated with a file descriptor. + +This can only be used to remove rights, and returns +[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt +to add rights. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The desired rights of the file descriptor. + +### `__wasi_fd_filestat_get()` + +Return the attributes of an open file. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_fd_filestat_set_size()` + +Adjust the size of an open file. If this increases the file's size, the extra +bytes are filled with zeros. + +Note: This is similar to `ftruncate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + A file descriptor for the file to adjust. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + The desired file size. + +### `__wasi_fd_filestat_set_times()` + +Adjust the timestamps of an open file or directory. + +Note: This is similar to `futimens` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_fd_pread()` + +Read from a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `preadv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors in which to store data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to read. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_prestat_get()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- [\_\_wasi\_prestat\_t](#prestat) \*buf + + The buffer where the description is stored. + +### `__wasi_fd_prestat_dir_name()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- const char \*path and size\_t path\_len + + A buffer into which to write the preopened directory name. + +### `__wasi_fd_pwrite()` + +Write to a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `pwritev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to write. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_fd_read()` + +Read from a file descriptor. + +Note: This is similar to `readv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors to which to store data. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_readdir()` + +Read directory entries from a directory. + +When successful, the contents of the output buffer consist of +a sequence of directory entries. Each directory entry consists +of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes +holding the name of the directory entry. + +This function fills the output buffer as much as possible, +potentially truncating the last directory entry. This allows +the caller to grow its read buffer size in case it's too small +to fit a single large directory entry, or skip the oversized +directory entry. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The directory from which to read the directory + entries. + +- void \*buf and size\_t buf\_len + + The buffer where directory entries are stored. + +- [\_\_wasi\_dircookie\_t](#dircookie) cookie + + The location within the directory to start + reading. + +Outputs: + +- size\_t bufused + + The number of bytes stored in the read buffer. + If less than the size of the read buffer, the + end of the directory has been reached. + +### `__wasi_fd_renumber()` + +Atomically replace a file descriptor by renumbering another +file descriptor. + +Due to the strong focus on thread safety, this environment +does not provide a mechanism to duplicate or renumber a file +descriptor to an arbitrary number, like dup2(). This would be +prone to race conditions, as an actual file descriptor with the +same number could be allocated by a different thread at the same +time. + +This function provides a way to atomically renumber file +descriptors, which would disappear if dup2() were to be +removed entirely. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) from + + The file descriptor to renumber. + +- [\_\_wasi\_fd\_t](#fd) to + + The file descriptor to overwrite. + +### `__wasi_fd_seek()` + +Move the offset of a file descriptor. + +Note: This is similar to `lseek` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_filedelta\_t](#filedelta) offset + + The number of bytes to move. + +- [\_\_wasi\_whence\_t](#whence) whence + + The base from which the offset is relative. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) newoffset + + The new offset of the file descriptor, + relative to the start of the file. + +### `__wasi_fd_sync()` + +Synchronize the data and metadata of a file to disk. + +Note: This is similar to `fsync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file containing the data + and metadata to synchronize to disk. + +### `__wasi_fd_tell()` + +Return the current offset of a file descriptor. + +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The current offset of the file descriptor, relative to the start of the file. + +### `__wasi_fd_write()` + +Write to a file descriptor. + +Note: This is similar to `writev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_path_create_directory()` + +Create a directory. + +Note: This is similar to `mkdirat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path at which to create the directory. + +### `__wasi_path_filestat_get()` + +Return the attributes of a file or directory. + +Note: This is similar to `stat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_path_filestat_set_times()` + +Adjust the timestamps of a file or directory. + +Note: This is similar to `utimensat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_path_link()` + +Create a hard link. + +Note: This is similar to `linkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags + + Flags determining the method of how the path is resolved. + +- const char \*old\_path and size\_t old\_path\_len + + The source path from which to link. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the hard link. + +### `__wasi_path_open()` + +Open a file or directory. + +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since +this is error-prone in multi-threaded contexts. The returned file +descriptor is guaranteed to be less than 231. + +Note: This is similar to `openat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) dirfd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The relative path of the file or directory to open, relative to + the [`dirfd`](#path_open.dirfd) directory. + +- [\_\_wasi\_oflags\_t](#oflags) o_flags + + The method by which to open the file. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The initial rights of the newly created file descriptor. The + implementation is allowed to return a file descriptor with fewer + rights than specified, if and only if those rights do not apply + to the type of file being opened. + + The *base* rights are rights that will apply to operations using + the file descriptor itself, while the *inheriting* rights are + rights that apply to file descriptors derived from it. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + The initial flags of the file descriptor. + +Outputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file that has been + opened. + +### `__wasi_path_readlink()` + +Read the contents of a symbolic link. + +Note: This is similar to `readlinkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path of the symbolic link from which to read. + +- char \*buf and size\_t buf\_len + + The buffer to which to write the contents of the symbolic link. + +Outputs: + +- size\_t bufused + + The number of bytes placed in the buffer. + +### `__wasi_path_remove_directory()` + +Remove a directory. + +Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. + +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a directory to remove. + +### `__wasi_path_rename()` + +Rename a file or directory. + +Note: This is similar to `renameat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- const char \*old\_path and size\_t old\_path\_len + + The source path of the file or directory to rename. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path to which to rename the file or directory. + +### `__wasi_path_symlink()` + +Create a symbolic link. + +Note: This is similar to `symlinkat` in POSIX. + +Inputs: + +- const char \*old\_path and size\_t old_path\_len + + The contents of the symbolic link. + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the symbolic link. + +### `__wasi_path_unlink_file()` + +Unlink a file. + +Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. + +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a file to unlink. + +### `__wasi_poll_oneoff()` + +Concurrently poll for the occurrence of a set of events. + +Inputs: + +- const [\_\_wasi\_subscription\_t](#subscription) \*in + + The events to which to subscribe. + +- [\_\_wasi\_event\_t](#event) \*out + + The events that have occurred. + +- size\_t nsubscriptions + + Both the number of subscriptions and events. + +Outputs: + +- size\_t nevents + + The number of events stored. + +### `__wasi_proc_exit()` + +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +Note: This is similar to `_Exit` in POSIX. + +Inputs: + +- [\_\_wasi\_exitcode\_t](#exitcode) rval + + The exit code returned by the process. + +Does not return. + +### `__wasi_proc_raise()` + +Send a signal to the process of the calling thread. + +Note: This is similar to `raise` in POSIX. + +Inputs: + +- [\_\_wasi\_signal\_t](#signal) sig + + The signal condition to trigger. + +### `__wasi_random_get()` + +Write high-quality random data into a buffer. + +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. + +This function may execute slowly, so when large mounts of random +data are required, it's advisable to use this function to seed a +pseudo-random number generator, rather than to provide the +random data directly. + +Inputs: + +- void \*buf and size\_t buf\_len + + The buffer to fill with random data. + +### `__wasi_sched_yield()` + +Temporarily yield execution of the calling thread. + +Note: This is similar to `sched_yield` in POSIX. + +### `__wasi_sock_recv()` + +Receive a message from a socket. + +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to receive data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len + + List of scatter/gather vectors to which to store data. + +- [\_\_wasi\_riflags\_t](#riflags) ri\_flags + + Message flags. + +Outputs: + +- size\_t ro\_datalen + + Number of bytes stored in [`ri_data`](#sock_recv.ri_data). + +- [\_\_wasi\_roflags\_t](#roflags) ro\_flags + + Message flags. + +### `__wasi_sock_send()` + +Send a message on a socket. + +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to send data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len + + List of scatter/gather vectors to which to retrieve data + +- [\_\_wasi\_siflags\_t](#siflags) si\_flags + + Message flags. + +Outputs: + +- size\_t so\_datalen + + Number of bytes transmitted. + +### `__wasi_sock_shutdown()` + +Shut down socket send and receive channels. + +Note: This is similar to `shutdown` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to shutdown channels. + +- [\_\_wasi\_sdflags\_t](#sdflags) how + + Which channels on the socket to shut down. + +## Types + +### `__wasi_advice_t` (`uint8_t`) + +File or memory access pattern advisory information. + +Used by [`__wasi_fd_advise()`](#fd_advise). + +Possible values: + +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + +- **`__WASI_ADVICE_NORMAL`** + + The application has no advice to give on its behavior + with respect to the specified data. + +- **`__WASI_ADVICE_RANDOM`** + + The application expects to access the specified data + in a random order. + +- **`__WASI_ADVICE_SEQUENTIAL`** + + The application expects to access the specified data + sequentially from lower offsets to higher offsets. + +- **`__WASI_ADVICE_WILLNEED`** + + The application expects to access the specified data + in the near future. + +### `__wasi_ciovec_t` (`struct`) + +A region of memory for scatter/gather writes. + +Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). + +Members: + +- const void \*buf and size\_t buf\_len + + The address and length of the buffer to be written. + +### `__wasi_clockid_t` (`uint32_t`) + +Identifiers for clocks. + +Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). + +Possible values: + +- **`__WASI_CLOCK_MONOTONIC`** + + The store-wide monotonic clock, which is defined as a + clock measuring real time, whose value cannot be + adjusted and which cannot have negative clock jumps. + + The epoch of this clock is undefined. The absolute + time value of this clock therefore has no meaning. + +- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** + + The CPU-time clock associated with the current + process. + +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + +- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** + + The CPU-time clock associated with the current thread. + +### `__wasi_device_t` (`uint64_t`) + +Identifier for a device containing a file system. Can be used +in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or +directory in the filesystem. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_dircookie_t` (`uint64_t`) + +A reference to the offset of a directory entry. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). + +Special values: + +- **`__WASI_DIRCOOKIE_START`** + + Permanent reference to the first directory entry + within a directory. + +### `__wasi_dirent_t` (`struct`) + +A directory entry. + +Members: + +- [\_\_wasi\_dircookie\_t](#dircookie) d\_next + + The offset of the next directory entry stored in this + directory. + +- [\_\_wasi\_inode\_t](#inode) d\_ino + + The serial number of the file referred to by this + directory entry. + +- uint32\_t d\_namlen + + The length of the name of the directory entry. + +- [\_\_wasi\_filetype\_t](#filetype) d\_type + + The type of the file referred to by this directory + entry. + +### `__wasi_errno_t` (`uint16_t`) + +Error codes returned by functions. + +Not all of these error codes are returned by the functions +provided by this API; some are used in higher-level library layers, +and others are provided merely for alignment with POSIX. + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_ESUCCESS`** + + No error occurred. System call completed successfully. + +- **`__WASI_E2BIG`** + + Argument list too long. + +- **`__WASI_EACCES`** + + Permission denied. + +- **`__WASI_EADDRINUSE`** + + Address in use. + +- **`__WASI_EADDRNOTAVAIL`** + + Address not available. + +- **`__WASI_EAFNOSUPPORT`** + + Address family not supported. + +- **`__WASI_EAGAIN`** + + Resource unavailable, or operation would block. + +- **`__WASI_EALREADY`** + + Connection already in progress. + +- **`__WASI_EBADF`** + + Bad file descriptor. + +- **`__WASI_EBADMSG`** + + Bad message. + +- **`__WASI_EBUSY`** + + Device or resource busy. + +- **`__WASI_ECANCELED`** + + Operation canceled. + +- **`__WASI_ECHILD`** + + No child processes. + +- **`__WASI_ECONNABORTED`** + + Connection aborted. + +- **`__WASI_ECONNREFUSED`** + + Connection refused. + +- **`__WASI_ECONNRESET`** + + Connection reset. + +- **`__WASI_EDEADLK`** + + Resource deadlock would occur. + +- **`__WASI_EDESTADDRREQ`** + + Destination address required. + +- **`__WASI_EDOM`** + + Mathematics argument out of domain of function. + +- **`__WASI_EDQUOT`** + + Reserved. + +- **`__WASI_EEXIST`** + + File exists. + +- **`__WASI_EFAULT`** + + Bad address. + +- **`__WASI_EFBIG`** + + File too large. + +- **`__WASI_EHOSTUNREACH`** + + Host is unreachable. + +- **`__WASI_EIDRM`** + + Identifier removed. + +- **`__WASI_EILSEQ`** + + Illegal byte sequence. + +- **`__WASI_EINPROGRESS`** + + Operation in progress. + +- **`__WASI_EINTR`** + + Interrupted function. + +- **`__WASI_EINVAL`** + + Invalid argument. + +- **`__WASI_EIO`** + + I/O error. + +- **`__WASI_EISCONN`** + + Socket is connected. + +- **`__WASI_EISDIR`** + + Is a directory. + +- **`__WASI_ELOOP`** + + Too many levels of symbolic links. + +- **`__WASI_EMFILE`** + + File descriptor value too large. + +- **`__WASI_EMLINK`** + + Too many links. + +- **`__WASI_EMSGSIZE`** + + Message too large. + +- **`__WASI_EMULTIHOP`** + + Reserved. + +- **`__WASI_ENAMETOOLONG`** + + Filename too long. + +- **`__WASI_ENETDOWN`** + + Network is down. + +- **`__WASI_ENETRESET`** + + Connection aborted by network. + +- **`__WASI_ENETUNREACH`** + + Network unreachable. + +- **`__WASI_ENFILE`** + + Too many files open in system. + +- **`__WASI_ENOBUFS`** + + No buffer space available. + +- **`__WASI_ENODEV`** + + No such device. + +- **`__WASI_ENOENT`** + + No such file or directory. + +- **`__WASI_ENOEXEC`** + + Executable file format error. + +- **`__WASI_ENOLCK`** + + No locks available. + +- **`__WASI_ENOLINK`** + + Reserved. + +- **`__WASI_ENOMEM`** + + Not enough space. + +- **`__WASI_ENOMSG`** + + No message of the desired type. + +- **`__WASI_ENOPROTOOPT`** + + Protocol not available. + +- **`__WASI_ENOSPC`** + + No space left on device. + +- **`__WASI_ENOSYS`** + + Function not supported. + +- **`__WASI_ENOTCONN`** + + The socket is not connected. + +- **`__WASI_ENOTDIR`** + + Not a directory or a symbolic link to a directory. + +- **`__WASI_ENOTEMPTY`** + + Directory not empty. + +- **`__WASI_ENOTRECOVERABLE`** + + State not recoverable. + +- **`__WASI_ENOTSOCK`** + + Not a socket. + +- **`__WASI_ENOTSUP`** + + Not supported, or operation not supported on socket. + +- **`__WASI_ENOTTY`** + + Inappropriate I/O control operation. + +- **`__WASI_ENXIO`** + + No such device or address. + +- **`__WASI_EOVERFLOW`** + + Value too large to be stored in data type. + +- **`__WASI_EOWNERDEAD`** + + Previous owner died. + +- **`__WASI_EPERM`** + + Operation not permitted. + +- **`__WASI_EPIPE`** + + Broken pipe. + +- **`__WASI_EPROTO`** + + Protocol error. + +- **`__WASI_EPROTONOSUPPORT`** + + Protocol not supported. + +- **`__WASI_EPROTOTYPE`** + + Protocol wrong type for socket. + +- **`__WASI_ERANGE`** + + Result too large. + +- **`__WASI_EROFS`** + + Read-only file system. + +- **`__WASI_ESPIPE`** + + Invalid seek. + +- **`__WASI_ESRCH`** + + No such process. + +- **`__WASI_ESTALE`** + + Reserved. + +- **`__WASI_ETIMEDOUT`** + + Connection timed out. + +- **`__WASI_ETXTBSY`** + + Text file busy. + +- **`__WASI_EXDEV`** + + Cross-device link. + +- **`__WASI_ENOTCAPABLE`** + + Extension: Capabilities insufficient. + +### `__wasi_event_t` (`struct`) + +An event that occurred. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that got attached to + [`__wasi_subscription_t::userdata`](#subscription.userdata). + +- [\_\_wasi\_errno\_t](#errno) error + + If non-zero, an error that occurred while processing + the subscription request. + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event that occurred. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_filesize\_t](#filesize) nbytes + + The number of bytes available for reading or writing. + + - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags + + The state of the file descriptor. + +### `__wasi_eventrwflags_t` (`uint16_t` bitfield) + +The state of the file descriptor subscribed to with +[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_EVENT_FD_READWRITE_HANGUP`** + + The peer of this socket has closed or disconnected. + +### `__wasi_eventtype_t` (`uint8_t`) + +Type of a subscription to an event or its occurrence. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_EVENTTYPE_CLOCK`** + + The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) + has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +- **`__WASI_EVENTTYPE_FD_READ`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + data available for reading. This event always triggers + for regular files. + +- **`__WASI_EVENTTYPE_FD_WRITE`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + capacity available for writing. This event always + triggers for regular files. + +### `__wasi_exitcode_t` (`uint32_t`) + +Exit code generated by a process when exiting. + +Used by [`__wasi_proc_exit()`](#proc_exit). + +### `__wasi_fd_t` (`uint32_t`) + +A file descriptor number. + +Used by many functions in this API. + +As in POSIX, three file descriptor numbers are provided to instances +on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, +and `STDERR_FILENO`). + +Other than these, WASI implementations are not required to allocate +new file descriptors in ascending order. + +### `__wasi_fdflags_t` (`uint16_t` bitfield) + +File descriptor flags. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_FDFLAG_APPEND`** + + Append mode: Data written to the file is always + appended to the file's end. + +- **`__WASI_FDFLAG_DSYNC`** + + Write according to synchronized I/O data integrity + completion. Only the data stored in the file is + synchronized. + +- **`__WASI_FDFLAG_NONBLOCK`** + + Non-blocking mode. + +- **`__WASI_FDFLAG_RSYNC`** + + Synchronized read I/O operations. + +- **`__WASI_FDFLAG_SYNC`** + + Write according to synchronized I/O file integrity completion. + In addition to synchronizing the data stored in the file, the + implementation may also synchronously update the file's metadata. + +### `__wasi_fdstat_t` (`struct`) + +File descriptor attributes. + +Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). + +Members: + +- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype + + File type. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + File descriptor flags. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base + + Rights that apply to this file descriptor. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + Maximum set of rights that may be installed on new + file descriptors that are created through this file + descriptor, e.g., through [`__wasi_path_open()`](#path_open). + +### `__wasi_filedelta_t` (`int64_t`) + +Relative offset within a file. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +### `__wasi_filesize_t` (`uint64_t`) + +Non-negative file size or length of a region within a file. + +Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +### `__wasi_filestat_t` (`struct`) + +File attributes. + +Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). + +Members: + +- [\_\_wasi\_device\_t](#device) st\_dev + + Device ID of device containing the file. + +- [\_\_wasi\_inode\_t](#inode) st\_ino + + File serial number. + +- [\_\_wasi\_filetype\_t](#filetype) st\_filetype + + File type. + +- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink + + Number of hard links to the file. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + For regular files, the file size in bytes. For + symbolic links, the length in bytes of the pathname + contained in the symbolic link. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + Last data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + Last data modification timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim + + Last file status change timestamp. + +### `__wasi_filetype_t` (`uint8_t`) + +The type of a file descriptor or file. + +Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). + +Possible values: + +- **`__WASI_FILETYPE_UNKNOWN`** + + The type of the file descriptor or file is unknown or + is different from any of the other types specified. + +- **`__WASI_FILETYPE_BLOCK_DEVICE`** + + The file descriptor or file refers to a block device + inode. + +- **`__WASI_FILETYPE_CHARACTER_DEVICE`** + + The file descriptor or file refers to a character + device inode. + +- **`__WASI_FILETYPE_DIRECTORY`** + + The file descriptor or file refers to a directory + inode. + +- **`__WASI_FILETYPE_REGULAR_FILE`** + + The file descriptor or file refers to a regular file + inode. + +- **`__WASI_FILETYPE_SOCKET_DGRAM`** + + The file descriptor or file refers to a datagram + socket. + +- **`__WASI_FILETYPE_SOCKET_STREAM`** + + The file descriptor or file refers to a byte-stream + socket. + +- **`__WASI_FILETYPE_SYMBOLIC_LINK`** + + The file refers to a symbolic link inode. + +### `__wasi_fstflags_t` (`uint16_t` bitfield) + +Which file time attributes to adjust. + +Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +Possible values: + +- **`__WASI_FILESTAT_SET_ATIM`** + + Adjust the last data access timestamp to the value + stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). + +- **`__WASI_FILESTAT_SET_ATIM_NOW`** + + Adjust the last data access timestamp to the time + of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +- **`__WASI_FILESTAT_SET_MTIM`** + + Adjust the last data modification timestamp to the + value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). + +- **`__WASI_FILESTAT_SET_MTIM_NOW`** + + Adjust the last data modification timestamp to the + time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +### `__wasi_inode_t` (`uint64_t`) + +File serial number that is unique within its file system. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). + +### `__wasi_iovec_t` (`struct`) + +A region of memory for scatter/gather reads. + +Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). + +Members: + +- void \*buf and size\_t buf\_len + + The address and length of the buffer to be filled. + +### `__wasi_linkcount_t` (`uint32_t`) + +Number of hard links to an inode. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_lookupflags_t` (`uint32_t` bitfield) + +Flags determining the method of how paths are resolved. + +Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** + + As long as the resolved path corresponds to a symbolic + link, it is expanded. + +### `__wasi_oflags_t` (`uint16_t` bitfield) + +Open flags used by [`__wasi_path_open()`](#path_open). + +Used by [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_O_CREAT`** + + Create file if it does not exist. + +- **`__WASI_O_DIRECTORY`** + + Fail if not a directory. + +- **`__WASI_O_EXCL`** + + Fail if file already exists. + +- **`__WASI_O_TRUNC`** + + Truncate file to size 0. + +### `__wasi_riflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_PEEK`** + + Returns the message without removing it from the + socket's receive queue. + +- **`__WASI_SOCK_RECV_WAITALL`** + + On byte-stream sockets, block until the full amount + of data can be returned. + +### `__wasi_rights_t` (`uint64_t` bitfield) + +File descriptor rights, determining which actions may be +performed. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_RIGHT_FD_DATASYNC`** + + The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_READ`** + + The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke + [`__wasi_fd_pread()`](#fd_pread). + +- **`__WASI_RIGHT_FD_SEEK`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies + [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). + +- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** + + The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). + +- **`__WASI_RIGHT_FD_SYNC`** + + The right to invoke [`__wasi_fd_sync()`](#fd_sync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and + [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_TELL`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the + file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with + offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). + +- **`__WASI_RIGHT_FD_WRITE`** + + The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to + invoke [`__wasi_fd_pwrite()`](#fd_pwrite). + +- **`__WASI_RIGHT_FD_ADVISE`** + + The right to invoke [`__wasi_fd_advise()`](#fd_advise). + +- **`__WASI_RIGHT_FD_ALLOCATE`** + + The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). + +- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** + + The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). + +- **`__WASI_RIGHT_PATH_CREATE_FILE`** + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke + [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). + +- **`__WASI_RIGHT_PATH_LINK_SOURCE`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_LINK_TARGET`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_OPEN`** + + The right to invoke [`__wasi_path_open()`](#path_open). + +- **`__WASI_RIGHT_FD_READDIR`** + + The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). + +- **`__WASI_RIGHT_PATH_READLINK`** + + The right to invoke [`__wasi_path_readlink()`](#path_readlink). + +- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_RENAME_TARGET`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_FILESTAT_GET`** + + The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** + + The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +- **`__WASI_RIGHT_FD_FILESTAT_GET`** + + The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** + + The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). + +- **`__WASI_RIGHT_PATH_SYMLINK`** + + The right to invoke [`__wasi_path_symlink()`](#path_symlink). + +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + +- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** + + The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). + +- **`__WASI_RIGHT_POLL_FD_READWRITE`** + + If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). + + If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +- **`__WASI_RIGHT_SOCK_SHUTDOWN`** + + The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). + +### `__wasi_roflags_t` (`uint16_t` bitfield) + +Flags returned by [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** + + Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been + truncated. + +### `__wasi_sdflags_t` (`uint8_t` bitfield) + +Which channels on a socket to shut down. + +Used by [`__wasi_sock_shutdown()`](#sock_shutdown). + +Possible values: + +- **`__WASI_SHUT_RD`** + + Disables further receive operations. + +- **`__WASI_SHUT_WR`** + + Disables further send operations. + +### `__wasi_siflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +Used by [`__wasi_sock_send()`](#sock_send). + +### `__wasi_signal_t` (`uint8_t`) + +Signal condition. + +Used by [`__wasi_proc_raise()`](#proc_raise). + +Possible values: + +- **`__WASI_SIGABRT`** + + Process abort signal. + + Action: Terminates the process. + +- **`__WASI_SIGALRM`** + + Alarm clock. + + Action: Terminates the process. + +- **`__WASI_SIGBUS`** + + Access to an undefined portion of a memory object. + + Action: Terminates the process. + +- **`__WASI_SIGCHLD`** + + Child process terminated, stopped, or continued. + + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGFPE`** + + Erroneous arithmetic operation. + + Action: Terminates the process. + +- **`__WASI_SIGHUP`** + + Hangup. + + Action: Terminates the process. + +- **`__WASI_SIGILL`** + + Illegal instruction. + + Action: Terminates the process. + +- **`__WASI_SIGINT`** + + Terminate interrupt signal. + + Action: Terminates the process. + +- **`__WASI_SIGKILL`** + + Kill. + + Action: Terminates the process. + +- **`__WASI_SIGPIPE`** + + Write on a pipe with no one to read it. + + Action: Ignored. + +- **`__WASI_SIGQUIT`** + + Terminal quit signal. + + Action: Terminates the process. + +- **`__WASI_SIGSEGV`** + + Invalid memory reference. + + Action: Terminates the process. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. + +- **`__WASI_SIGSYS`** + + Bad system call. + + Action: Terminates the process. + +- **`__WASI_SIGTERM`** + + Termination signal. + + Action: Terminates the process. + +- **`__WASI_SIGTRAP`** + + Trace/breakpoint trap. + + Action: Terminates the process. + +- **`__WASI_SIGTSTP`** + + Terminal stop signal. + + Action: Stops executing. + +- **`__WASI_SIGTTIN`** + + Background process attempting read. + + Action: Stops executing. + +- **`__WASI_SIGTTOU`** + + Background process attempting write. + + Action: Stops executing. + +- **`__WASI_SIGURG`** + + High bandwidth data is available at a socket. + + Action: Ignored. + +- **`__WASI_SIGUSR1`** + + User-defined signal 1. + + Action: Terminates the process. + +- **`__WASI_SIGUSR2`** + + User-defined signal 2. + + Action: Terminates the process. + +- **`__WASI_SIGVTALRM`** + + Virtual timer expired. + + Action: Terminates the process. + +- **`__WASI_SIGXCPU`** + + CPU time limit exceeded. + + Action: Terminates the process. + +- **`__WASI_SIGXFSZ`** + + File size limit exceeded. + + Action: Terminates the process. + +### `__wasi_subclockflags_t` (`uint16_t` bitfield) + +Flags determining how to interpret the timestamp provided in +[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +Used by [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** + + If set, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp + of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + + If clear, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current + time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + +### `__wasi_subscription_t` (`struct`) + +Subscription to an event. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that is attached to the subscription in the + implementation and returned through + [`__wasi_event_t::userdata`](#event.userdata). + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event to which to subscribe. + +- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): + + - **`u.clock`** + + - [\_\_wasi\_userdata\_t](#userdata) identifier + + The user-defined unique identifier of the clock. + + - [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock against which to compare the timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) timeout + + The absolute or relative timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) precision + + The amount of time that the implementation may wait additionally + to coalesce with other events. + + - [\_\_wasi\_subclockflags\_t](#subclockflags) flags + + Flags specifying whether the timeout is absolute or relative. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor on which to wait for it to become ready + for reading or writing. + +### `__wasi_timestamp_t` (`uint64_t`) + +Timestamp in nanoseconds. + +Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +### `__wasi_userdata_t` (`uint64_t`) + +User-provided value that may be attached to objects that is +retained when extracted from the implementation. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +### `__wasi_whence_t` (`uint8_t`) + +The position relative to which to set the offset of the file descriptor. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +Possible values: + +- **`__WASI_WHENCE_CUR`** + + Seek relative to current position. + +- **`__WASI_WHENCE_END`** + + Seek relative to end-of-file. + +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + diff --git a/proposals/filesystem/phases/old/witx/typenames.witx b/proposals/filesystem/phases/old/witx/typenames.witx new file mode 100644 index 000000000..e04a188d9 --- /dev/null +++ b/proposals/filesystem/phases/old/witx/typenames.witx @@ -0,0 +1,752 @@ +;; Type names used by low-level WASI interfaces. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(typename $size_t u32) + +;; Non-negative file size or length of a region within a file. +(typename $filesize_t u64) + +;; Timestamp in nanoseconds. +(typename $timestamp_t u64) + +;; Identifiers for clocks. +(typename $clockid_t + (enum u32 + ;; The store-wide monotonic clock, which is defined as a clock measuring + ;; real time, whose value cannot be adjusted and which cannot have negative + ;; clock jumps. The epoch of this clock is undefined. The absolute time + ;; value of this clock therefore has no meaning. + $CLOCK_MONOTONIC + ;; The CPU-time clock associated with the current process. + $CLOCK_PROCESS_CPUTIME_ID + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME + ;; The CPU-time clock associated with the current thread. + $CLOCK_THREAD_CPUTIME_ID + ) +) + +;; Error codes returned by functions. +;; Not all of these error codes are returned by the functions provided by this +;; API; some are used in higher-level library layers, and others are provided +;; merely for alignment with POSIX. +(typename $errno_t + (enum u16 + ;; No error occurred. System call completed successfully. + $ESUCCESS + ;; Argument list too long. + $E2BIG + ;; Permission denied. + $EACCES + ;; Address in use. + $EADDRINUSE + ;; Address not available. + $EADDRNOTAVAIL + ;; Address family not supported. + $EAFNOSUPPORT + ;; Resource unavailable, or operation would block. + $EAGAIN + ;; Connection already in progress. + $EALREADY + ;; Bad file descriptor. + $EBADF + ;; Bad message. + $EBADMSG + ;; Device or resource busy. + $EBUSY + ;; Operation canceled. + $ECANCELED + ;; No child processes. + $ECHILD + ;; Connection aborted. + $ECONNABORTED + ;; Connection refused. + $ECONNREFUSED + ;; Connection reset. + $ECONNRESET + ;; Resource deadlock would occur. + $EDEADLK + ;; Destination address required. + $EDESTADDRREQ + ;; Mathematics argument out of domain of function. + $EDOM + ;; Reserved. + $EDQUOT + ;; File exists. + $EEXIST + ;; Bad address. + $EFAULT + ;; File too large. + $EFBIG + ;; Host is unreachable. + $EHOSTUNREACH + ;; Identifier removed. + $EIDRM + ;; Illegal byte sequence. + $EILSEQ + ;; Operation in progress. + $EINPROGRESS + ;; Interrupted function. + $EINTR + ;; Invalid argument. + $EINVAL + ;; I/O error. + $EIO + ;; Socket is connected. + $EISCONN + ;; Is a directory. + $EISDIR + ;; Too many levels of symbolic links. + $ELOOP + ;; File descriptor value too large. + $EMFILE + ;; Too many links. + $EMLINK + ;; Message too large. + $EMSGSIZE + ;; Reserved. + $EMULTIHOP + ;; Filename too long. + $ENAMETOOLONG + ;; Network is down. + $ENETDOWN + ;; Connection aborted by network. + $ENETRESET + ;; Network unreachable. + $ENETUNREACH + ;; Too many files open in system. + $ENFILE + ;; No buffer space available. + $ENOBUFS + ;; No such device. + $ENODEV + ;; No such file or directory. + $ENOENT + ;; Executable file format error. + $ENOEXEC + ;; No locks available. + $ENOLCK + ;; Reserved. + $ENOLINK + ;; Not enough space. + $ENOMEM + ;; No message of the desired type. + $ENOMSG + ;; Protocol not available. + $ENOPROTOOPT + ;; No space left on device. + $ENOSPC + ;; Function not supported. + $ENOSYS + ;; The socket is not connected. + $ENOTCONN + ;; Not a directory or a symbolic link to a directory. + $ENOTDIR + ;; Directory not empty. + $ENOTEMPTY + ;; State not recoverable. + $ENOTRECOVERABLE + ;; Not a socket. + $ENOTSOCK + ;; Not supported, or operation not supported on socket. + $ENOTSUP + ;; Inappropriate I/O control operation. + $ENOTTY + ;; No such device or address. + $ENXIO + ;; Value too large to be stored in data type. + $EOVERFLOW + ;; Previous owner died. + $EOWNERDEAD + ;; Operation not permitted. + $EPERM + ;; Broken pipe. + $EPIPE + ;; Protocol error. + $EPROTO + ;; Protocol not supported. + $EPROTONOSUPPORT + ;; Protocol wrong type for socket. + $EPROTOTYPE + ;; Result too large. + $ERANGE + ;; Read-only file system. + $EROFS + ;; Invalid seek. + $ESPIPE + ;; No such process. + $ESRCH + ;; Reserved. + $ESTALE + ;; Connection timed out. + $ETIMEDOUT + ;; Text file busy. + $ETXTBSY + ;; Cross-device link. + $EXDEV + ;; Extension: Capabilities insufficient. + $ENOTCAPABLE + ) +) + +;; File descriptor rights, determining which actions may be performed. +(typename $rights_t + (flags u64 + ;; The right to invoke `fd_datasync`. + ;; + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_DSYNC`. + (flag $RIGHT_FD_DATASYNC) + ;; The right to invoke `fd_read` and `sock_recv`. + ;; + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + (flag $RIGHT_FD_READ) + ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + (flag $RIGHT_FD_SEEK) + ;; The right to invoke `fd_fdstat_set_flags`. + (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + ;; The right to invoke `fd_sync`. + ;; + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + (flag $RIGHT_FD_SYNC) + ;; The right to invoke `fd_seek` in such a way that the file offset + ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;; invoke `fd_tell`. + (flag $RIGHT_FD_TELL) + ;; The right to invoke `fd_write` and `sock_send`. + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + (flag $RIGHT_FD_WRITE) + ;; The right to invoke `fd_advise`. + (flag $RIGHT_FD_ADVISE) + ;; The right to invoke `fd_allocate`. + (flag $RIGHT_FD_ALLOCATE) + ;; The right to invoke `path_create_directory`. + (flag $RIGHT_PATH_CREATE_DIRECTORY) + ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + (flag $RIGHT_PATH_CREATE_FILE) + ;; The right to invoke `path_link` with the file descriptor as the + ;; source directory. + (flag $RIGHT_PATH_LINK_SOURCE) + ;; The right to invoke `path_link` with the file descriptor as the + ;; target directory. + (flag $RIGHT_PATH_LINK_TARGET) + ;; The right to invoke `path_open`. + (flag $RIGHT_PATH_OPEN) + ;; The right to invoke `fd_readdir`. + (flag $RIGHT_FD_READDIR) + ;; The right to invoke `path_readlink`. + (flag $RIGHT_PATH_READLINK) + ;; The right to invoke `path_rename` with the file descriptor as the source directory. + (flag $RIGHT_PATH_RENAME_SOURCE) + ;; The right to invoke `path_rename` with the file descriptor as the target directory. + (flag $RIGHT_PATH_RENAME_TARGET) + ;; The right to invoke `path_filestat_get`. + (flag $RIGHT_PATH_FILESTAT_GET) + ;; The right to change a file's size (there is no `path_filestat_set_size`). + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + ;; The right to invoke `path_filestat_set_times`. + (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + ;; The right to invoke `fd_filestat_get`. + (flag $RIGHT_FD_FILESTAT_GET) + ;; The right to invoke `fd_filestat_set_size`. + (flag $RIGHT_FD_FILESTAT_SET_SIZE) + ;; The right to invoke `fd_filestat_set_times`. + (flag $RIGHT_FD_FILESTAT_SET_TIMES) + ;; The right to invoke `path_symlink`. + (flag $RIGHT_PATH_SYMLINK) + ;; The right to invoke `path_unlink_file`. + (flag $RIGHT_PATH_UNLINK_FILE) + ;; The right to invoke `path_remove_directory`. + (flag $RIGHT_PATH_REMOVE_DIRECTORY) + ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + (flag $RIGHT_POLL_FD_READWRITE) + ;; The right to invoke `sock_shutdown`. + (flag $RIGHT_SOCK_SHUTDOWN) + ) +) + +;; A file descriptor index. +(typename $fd_t u32) + +;; A region of memory for scatter/gather reads. +(typename $iovec_t + (struct + ;; The address of the buffer to be filled. + (field $buf (@witx pointer u8)) + ;; The length of the buffer to be filled. + (field $buf_len $size_t) + ) +) + +;; A region of memory for scatter/gather writes. +(typename $ciovec_t + (struct + ;; The address of the buffer to be written. + (field $buf (@witx const_pointer u8)) + ;; The length of the buffer to be written. + (field $buf_len $size_t) + ) +) + +(typename $iovec_t_array (array $iovec_t)) +(typename $ciovec_t_array (array $ciovec_t)) + +;; Relative offset within a file. +(typename $filedelta_t s64) + +;; The position relative to which to set the offset of the file descriptor. +(typename $whence_t + (enum u8 + ;; Seek relative to current position. + $WHENCE_CUR + ;; Seek relative to end-of-file. + $WHENCE_END + ;; Seek relative to start-of-file. + $WHENCE_SET + ) +) + +;; A reference to the offset of a directory entry. +(typename $dircookie_t u64) + +;; The type for the $d_namlen field of $dirent_t. +(typename $dirnamlen_t u32) + +;; File serial number that is unique within its file system. +(typename $inode_t u64) + +;; The type of a file descriptor or file. +(typename $filetype_t + (enum u8 + ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $FILETYPE_UNKNOWN + ;; The file descriptor or file refers to a block device inode. + $FILETYPE_BLOCK_DEVICE + ;; The file descriptor or file refers to a character device inode. + $FILETYPE_CHARACTER_DEVICE + ;; The file descriptor or file refers to a directory inode. + $FILETYPE_DIRECTORY + ;; The file descriptor or file refers to a regular file inode. + $FILETYPE_REGULAR_FILE + ;; The file descriptor or file refers to a datagram socket. + $FILETYPE_SOCKET_DGRAM + ;; The file descriptor or file refers to a byte-stream socket. + $FILETYPE_SOCKET_STREAM + ;; The file refers to a symbolic link inode. + $FILETYPE_SYMBOLIC_LINK + ) +) + +;; A directory entry. +(typename $dirent_t + (struct + ;; The offset of the next directory entry stored in this directory. + (field $d_next $dircookie_t) + ;; The serial number of the file referred to by this directory entry. + (field $d_ino $inode_t) + ;; The length of the name of the directory entry. + (field $d_namlen $dirnamlen_t) + ;; The type of the file referred to by this directory entry. + (field $d_type $filetype_t) + ) +) + +;; File or memory access pattern advisory information. +(typename $advice_t + (enum u8 + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE + ;; The application has no advice to give on its behavior with respect to the specified data. + $ADVICE_NORMAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM + ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in the near future. + $ADVICE_WILLNEED + ) +) + +;; File descriptor flags. +(typename $fdflags_t + (flags u16 + ;; Append mode: Data written to the file is always appended to the file's end. + (flag $FDFLAG_APPEND) + ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + (flag $FDFLAG_DSYNC) + ;; Non-blocking mode. + (flag $FDFLAG_NONBLOCK) + ;; Synchronized read I/O operations. + (flag $FDFLAG_RSYNC) + ;; Write according to synchronized I/O file integrity completion. In + ;; addition to synchronizing the data stored in the file, the implementation + ;; may also synchronously update the file's metadata. + (flag $FDFLAG_SYNC) + ) +) + +;; File descriptor attributes. +(typename $fdstat_t + (struct + ;; File type. + (field $fs_filetype $filetype_t) + ;; File descriptor flags. + (field $fs_flags $fdflags_t) + ;; Rights that apply to this file descriptor. + (field $fs_rights_base $rights_t) + ;; Maximum set of rights that may be installed on new file descriptors that + ;; are created through this file descriptor, e.g., through `path_open`. + (field $fs_rights_inheriting $rights_t) + ) +) + +;; Identifier for a device containing a file system. Can be used in combination +;; with `inode_t` to uniquely identify a file or directory in the filesystem. +(typename $device_t u64) + +;; Which file time attributes to adjust. +(typename $fstflags_t + (flags u16 + ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + (flag $FILESTAT_SET_ATIM) + ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + (flag $FILESTAT_SET_ATIM_NOW) + ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + (flag $FILESTAT_SET_MTIM) + ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + (flag $FILESTAT_SET_MTIM_NOW) + ) +) + +;; Flags determining the method of how paths are resolved. +(typename $lookupflags_t + (flags u32 + ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + (flag $LOOKUP_SYMLINK_FOLLOW) + ) +) + +;; Open flags used by `path_open`. +(typename $oflags_t + (flags u16 + ;; Create file if it does not exist. + (flag $O_CREAT) + ;; Fail if not a directory. + (flag $O_DIRECTORY) + ;; Fail if file already exists. + (flag $O_EXCL) + ;; Truncate file to size 0. + (flag $O_TRUNC) + ) +) + +;; Number of hard links to an inode. +(typename $linkcount_t u32) + +;; File attributes. +(typename $filestat_t + (struct + ;; Device ID of device containing the file. + (field $st_dev $device_t) + ;; File serial number. + (field $st_ino $inode_t) + ;; File type. + (field $st_filetype $filetype_t) + ;; Number of hard links to the file. + (field $st_nlink $linkcount_t) + ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + (field $st_size $filesize_t) + ;; Last data access timestamp. + (field $st_atim $timestamp_t) + ;; Last data modification timestamp. + (field $st_mtim $timestamp_t) + ;; Last file status change timestamp. + (field $st_ctim $timestamp_t) + ) +) + +;; User-provided value that may be attached to objects that is retained when +;; extracted from the implementation. +(typename $userdata_t u64) + +;; Type of a subscription to an event or its occurrence. +(typename $eventtype_t + (flags u8 + ;; The time value of clock `subscription_t::u.clock.clock_id` has + ;; reached timestamp `subscription_t::u.clock.timeout`. + (flag $EVENTTYPE_CLOCK) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;; available for reading. This event always triggers for regular files. + (flag $EVENTTYPE_FD_READ) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;; available for writing. This event always triggers for regular files. + (flag $EVENTTYPE_FD_WRITE) + ) +) + +;; The state of the file descriptor subscribed to with +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $eventrwflags_t + (flags u16 + ;; The peer of this socket has closed or disconnected. + (flag $EVENT_FD_READWRITE_HANGUP) + ) +) + +;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;; `EVENTTYPE_FD_WRITE`. +(typename $event_fd_readwrite_t + (struct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) + ) +) + +;; The contents of an $event_t. +(typename $event_u + (union + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $event_fd_readwrite_t) + ) +) + +;; An event that occurred. +(typename $event_t + (struct + ;; User-provided value that got attached to `subscription_t::userdata`. + (field $userdata $userdata_t) + ;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno_t) + ;; The type of the event that occurred. + (field $type $eventtype_t) + ;; The contents of the event. + (field $u $event_u) + ) +) + +;; Flags determining how to interpret the timestamp provided in +;; `subscription_t::u.clock.timeout.` +(typename $subclockflags_t + (flags u16 + ;; If set, treat the timestamp provided in + ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;; provided in `subscription_t::u.clock.timeout` relative to the + ;; current time value of clock `subscription_t::u.clock.clock_id.` + (flag $SUBSCRIPTION_CLOCK_ABSTIME) + ) +) + +;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +(typename $subscription_clock_t + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) +) + +;; The contents of a $subscription_t when type is type is +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $subscription_fd_readwrite_t + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) + ) +) + +;; The contents of a $subscription_t. +(typename $subscription_u + (union + ;; When type is `EVENTTYPE_CLOCK`: + (field $clock $subscription_clock_t) + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $subscription_fd_readwrite_t) + ) +) + +;; Subscription to an event. +(typename $subscription_t + (struct + ;; User-provided value that is attached to the subscription in the + ;; implementation and returned through `event_t::userdata`. + (field $userdata $userdata_t) + ;; The type of the event to which to subscribe. + (field $type $eventtype_t) + ;; The contents of the subscription. + (field $u $subscription_u) + ) +) + +;; Exit code generated by a process when exiting. +(typename $exitcode_t u32) + +;; Signal condition. +(typename $signal_t + (enum u8 + ;; Process abort signal. + ;; Action: Terminates the process. + $SIGABRT + ;; Alarm clock. + ;; Action: Terminates the process. + $SIGALRM + ;; Access to an undefined portion of a memory object. + ;; Action: Terminates the process. + $SIGBUS + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT + ;; Erroneous arithmetic operation. + ;; Action: Terminates the process. + $SIGFPE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Kill. + ;; Action: Terminates the process. + $SIGKILL + ;; Write on a pipe with no one to read it. + ;; Action: Ignored. + $SIGPIPE + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Invalid memory reference. + ;; Action: Terminates the process. + $SIGSEGV + ;; Stop executing. + ;; Action: Stops executing. + $SIGSTOP + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS + ;; Termination signal. + ;; Action: Terminates the process. + $SIGTERM + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP + ;; Terminal stop signal. + ;; Action: Stops executing. + $SIGTSTP + ;; Background process attempting read. + ;; Action: Stops executing. + $SIGTTIN + ;; Background process attempting write. + ;; Action: Stops executing. + $SIGTTOU + ;; High bandwidth data is available at a socket. + ;; Action: Ignored. + $SIGURG + ;; User-defined signal 1. + ;; Action: Terminates the process. + $SIGUSR1 + ;; User-defined signal 2. + ;; Action: Terminates the process. + $SIGUSR2 + ;; Virtual timer expired. + ;; Action: Terminates the process. + $SIGVTALRM + ;; CPU time limit exceeded. + ;; Action: Terminates the process. + $SIGXCPU + ;; File size limit exceeded. + ;; Action: Terminates the process. + $SIGXFSZ + ) +) + +;; Flags provided to `sock_recv`. +(typename $riflags_t + (flags u16 + ;; Returns the message without removing it from the socket's receive queue. + (flag $SOCK_RECV_PEEK) + ;; On byte-stream sockets, block until the full amount of data can be returned. + (flag $SOCK_RECV_WAITALL) + ) +) + +;; Flags returned by `sock_recv`. +(typename $roflags_t + (flags u16 + ;; Returned by `sock_recv`: Message data has been truncated. + (flag $SOCK_RECV_DATA_TRUNCATED) + ) +) + +;; Flags provided to `sock_send`. As there are currently no flags +;; defined, it must be set to zero. +(typename $siflags_t u16) + +;; Which channels on a socket to shut down. +(typename $sdflags_t + (flags u8 + ;; Disables further receive operations. + (flag $SHUT_RD) + ;; Disables further send operations. + (flag $SHUT_WR) + ) +) + +;; Identifiers for preopened capabilities. +(typename $preopentype_t + (enum u8 + ;; A pre-opened directory. + $PREOPENTYPE_DIR + ) +) + +;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +(typename $prestat_dir + (struct + ;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size_t) + ) +) + +;; The contents of an $prestat_t. +(typename $prestat_u + (union + ;; When type is `PREOPENTYPE_DIR`: + (field $dir $prestat_dir) + ) +) + +;; Information about a pre-opened capability. +(typename $prestat_t + (struct + ;; The type of the pre-opened capability. + (field $pr_type $preopentype_t) + ;; The contents of the information. + (field $u $prestat_u) + ) +) diff --git a/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx b/proposals/filesystem/phases/old/witx/wasi_unstable.witx similarity index 98% rename from proposals/filesystem/design/wasi_unstable/wasi_unstable.witx rename to proposals/filesystem/phases/old/witx/wasi_unstable.witx index 6d4bea545..f9586ff1e 100644 --- a/proposals/filesystem/design/wasi_unstable/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/witx/wasi_unstable.witx @@ -1,4 +1,5 @@ -;; The wasi_unstable module type. +;; WASI Preview. This is an evolution of the API that WASI initially +;; launched with. ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). ;; @@ -7,6 +8,9 @@ (use "typenames.witx") +;; This API predated the convention of naming modules with a `wasi_unstable_` +;; prefix and a version number. It is preserved here for compatibility, but +;; we shouldn't follow this pattern in new APIs. (module $wasi_unstable ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) diff --git a/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md new file mode 100644 index 000000000..9db4a382e --- /dev/null +++ b/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md @@ -0,0 +1,2319 @@ + + +# The WASI Preview API + +This is the API-level documentation for WASI Preview. The function names +are prefixed with "\_\_wasi\_" to reflect how they are spelled in +flat-namespace contexts, however at the wasm module level, they are +unprefixed, because they're inside a module namespace. + +Functions that start with `__wasi_fd_` operate on file descriptors, +while functions that start with `__wasi_path_` operate on filesystem +paths, which are relative to directory file descriptors. + +Much inspiration and content here is derived from [CloudABI] and [POSIX], +though there are also several differences from CloudABI and POSIX. For +example, WASI Preview has no concept of processes in the traditional Unix +sense. While wasm linear memories have some of the aspects of processes, +and it's possible to *emulate* the full semantics of processes on top of +them, this can sometimes be unnatural and inefficient. The goal for +WASI Preview is to be a WebAssembly-native API that exposes APIs that fit +well into the underlying WebAssembly platform, rather than to directly +emulate other platforms. + +This is also a work in progress, and the API here is still evolving. + +Historical note: this API was originally named "WASI Core", and used the +API module name "wasi\_unstable". We've since sought to deemphasize the +"Core" name, as the goal is to split this API up into independent +modules so that embedders need not implement all of it. + +[CloudABI]: https://github.com/NuxiNL/cloudabi +[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ + +## System calls + +- [`__wasi_args_get()`](#args_get) +- [`__wasi_args_sizes_get()`](#args_sizes_get) +- [`__wasi_clock_res_get()`](#clock_res_get) +- [`__wasi_clock_time_get()`](#clock_time_get) +- [`__wasi_environ_get()`](#environ_get) +- [`__wasi_environ_sizes_get()`](#environ_sizes_get) +- [`__wasi_fd_advise()`](#fd_advise) +- [`__wasi_fd_allocate()`](#fd_allocate) +- [`__wasi_fd_close()`](#fd_close) +- [`__wasi_fd_datasync()`](#fd_datasync) +- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) +- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) +- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) +- [`__wasi_fd_filestat_get()`](#fd_filestat_get) +- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) +- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) +- [`__wasi_fd_pread()`](#fd_pread) +- [`__wasi_fd_prestat_get()`](#fd_prestat_get) +- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) +- [`__wasi_fd_pwrite()`](#fd_pwrite) +- [`__wasi_fd_read()`](#fd_read) +- [`__wasi_fd_readdir()`](#fd_readdir) +- [`__wasi_fd_renumber()`](#fd_renumber) +- [`__wasi_fd_seek()`](#fd_seek) +- [`__wasi_fd_sync()`](#fd_sync) +- [`__wasi_fd_tell()`](#fd_tell) +- [`__wasi_fd_write()`](#fd_write) +- [`__wasi_path_create_directory()`](#path_create_directory) +- [`__wasi_path_filestat_get()`](#path_filestat_get) +- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) +- [`__wasi_path_link()`](#path_link) +- [`__wasi_path_open()`](#path_open) +- [`__wasi_path_readlink()`](#path_readlink) +- [`__wasi_path_remove_directory()`](#path_remove_directory) +- [`__wasi_path_rename()`](#path_rename) +- [`__wasi_path_symlink()`](#path_symlink) +- [`__wasi_path_unlink_file()`](#path_unlink_file) +- [`__wasi_poll_oneoff()`](#poll_oneoff) +- [`__wasi_proc_exit()`](#proc_exit) +- [`__wasi_proc_raise()`](#proc_raise) +- [`__wasi_random_get()`](#random_get) +- [`__wasi_sched_yield()`](#sched_yield) +- [`__wasi_sock_recv()`](#sock_recv) +- [`__wasi_sock_send()`](#sock_send) +- [`__wasi_sock_shutdown()`](#sock_shutdown) + +### `__wasi_args_get()` + +Read command-line argument data. + +The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + +Inputs: + +- char \*\*argv + + A pointer to a buffer to write the argument pointers. + +- char \*argv\_buf + + A pointer to a buffer to write the argument string data. + +### `__wasi_args_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*argc + + The number of arguments. + +- size\_t \*argv\_buf\_size + + The size of the argument string data. + +### `__wasi_clock_res_get()` + +Return the resolution of a clock. + +Implementations are required to provide a non-zero value for supported clocks. +For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). + +Note: This is similar to `clock_getres` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the resolution. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) resolution + + The resolution of the clock. + +### `__wasi_clock_time_get()` + +Return the time value of a clock. + +Note: This is similar to `clock_gettime` in POSIX. + +Inputs: + +- [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock for which to return the time. + +- [\_\_wasi\_timestamp\_t](#timestamp) precision + + The maximum lag (exclusive) that the returned + time value may have, compared to its actual + value. + +Outputs: + +- [\_\_wasi\_timestamp\_t](#timestamp) time + + The time value of the clock. + +### `__wasi_environ_get()` + +Read environment variable data. + +The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + +Inputs: + +- char \*\*environ + + A pointer to a buffer to write the environment variable pointers. + +- char \*environ\_buf + + A pointer to a buffer to write the environment variable string data. + +### `__wasi_environ_sizes_get()` + +Return command-line argument data sizes. + +Outputs: + +- size\_t \*environ\_count + + The number of environment variables. + +- size\_t \*environ\_buf\_size + + The size of the environment variable string data. + +### `__wasi_fd_advise()` + +Provide file advisory information on a file descriptor. + +Note: This is similar to `posix_fadvise` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file for which to provide file advisory information. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file to which the advisory applies. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the region to which the advisory applies. + +- [\_\_wasi\_advice\_t](#advice) advice + + The advice. + +### `__wasi_fd_allocate()` + +Force the allocation of space in a file. + +Note: This is similar to `posix_fallocate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor for the file in which to allocate space. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset at which to start the allocation. + +- [\_\_wasi\_filesize\_t](#filesize) len + + The length of the area that is allocated. + +### `__wasi_fd_close()` + +Close a file descriptor. + +Note: This is similar to `close` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to close. + +### `__wasi_fd_datasync()` + +Synchronize the data of a file to disk. + +Note: This is similar to `fdatasync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file to synchronize to disk. + +### `__wasi_fd_fdstat_get()` + +Get the attributes of a file descriptor. + +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well +as additional fields. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_fdstat\_t](#fdstat) \*buf + + The buffer where the file descriptor's attributes are stored. + +### `__wasi_fd_fdstat_set_flags()` + +Adjust the flags associated with a file descriptor. + +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_fdflags\_t](#fdflags) flags + + The desired values of the file descriptor + flags. + +### `__wasi_fd_fdstat_set_rights()` + +Adjust the rights associated with a file descriptor. + +This can only be used to remove rights, and returns +[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt +to add rights. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The desired rights of the file descriptor. + +### `__wasi_fd_filestat_get()` + +Return the attributes of an open file. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_fd_filestat_set_size()` + +Adjust the size of an open file. If this increases the file's size, the extra +bytes are filled with zeros. + +Note: This is similar to `ftruncate` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + A file descriptor for the file to adjust. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + The desired file size. + +### `__wasi_fd_filestat_set_times()` + +Adjust the timestamps of an open file or directory. + +Note: This is similar to `futimens` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_fd_pread()` + +Read from a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `preadv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors in which to store data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to read. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_prestat_get()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- [\_\_wasi\_prestat\_t](#prestat) \*buf + + The buffer where the description is stored. + +### `__wasi_fd_prestat_dir_name()` + +Return a description of the given preopened file descriptor. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor about which to retrieve information. + +- const char \*path and size\_t path\_len + + A buffer into which to write the preopened directory name. + +### `__wasi_fd_pwrite()` + +Write to a file descriptor, without using and updating the +file descriptor's offset. + +Note: This is similar to `pwritev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The offset within the file at which to write. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_fd_read()` + +Read from a file descriptor. + +Note: This is similar to `readv` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor from which to read data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors to which to store data. + +Outputs: + +- size\_t nread + + The number of bytes read. + +### `__wasi_fd_readdir()` + +Read directory entries from a directory. + +When successful, the contents of the output buffer consist of +a sequence of directory entries. Each directory entry consists +of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes +holding the name of the directory entry. + +This function fills the output buffer as much as possible, +potentially truncating the last directory entry. This allows +the caller to grow its read buffer size in case it's too small +to fit a single large directory entry, or skip the oversized +directory entry. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The directory from which to read the directory + entries. + +- void \*buf and size\_t buf\_len + + The buffer where directory entries are stored. + +- [\_\_wasi\_dircookie\_t](#dircookie) cookie + + The location within the directory to start + reading. + +Outputs: + +- size\_t bufused + + The number of bytes stored in the read buffer. + If less than the size of the read buffer, the + end of the directory has been reached. + +### `__wasi_fd_renumber()` + +Atomically replace a file descriptor by renumbering another +file descriptor. + +Due to the strong focus on thread safety, this environment +does not provide a mechanism to duplicate or renumber a file +descriptor to an arbitrary number, like dup2(). This would be +prone to race conditions, as an actual file descriptor with the +same number could be allocated by a different thread at the same +time. + +This function provides a way to atomically renumber file +descriptors, which would disappear if dup2() were to be +removed entirely. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) from + + The file descriptor to renumber. + +- [\_\_wasi\_fd\_t](#fd) to + + The file descriptor to overwrite. + +### `__wasi_fd_seek()` + +Move the offset of a file descriptor. + +Note: This is similar to `lseek` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to operate on. + +- [\_\_wasi\_filedelta\_t](#filedelta) offset + + The number of bytes to move. + +- [\_\_wasi\_whence\_t](#whence) whence + + The base from which the offset is relative. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) newoffset + + The new offset of the file descriptor, + relative to the start of the file. + +### `__wasi_fd_sync()` + +Synchronize the data and metadata of a file to disk. + +Note: This is similar to `fsync` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file containing the data + and metadata to synchronize to disk. + +### `__wasi_fd_tell()` + +Return the current offset of a file descriptor. + +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to inspect. + +Outputs: + +- [\_\_wasi\_filesize\_t](#filesize) offset + + The current offset of the file descriptor, relative to the start of the file. + +### `__wasi_fd_write()` + +Write to a file descriptor. + +Note: This is similar to `writev` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor to which to write data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len + + List of scatter/gather vectors from which to retrieve data. + +Outputs: + +- size\_t nwritten + + The number of bytes written. + +### `__wasi_path_create_directory()` + +Create a directory. + +Note: This is similar to `mkdirat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path at which to create the directory. + +### `__wasi_path_filestat_get()` + +Return the attributes of a file or directory. + +Note: This is similar to `stat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to inspect. + +- [\_\_wasi\_filestat\_t](#filestat) \*buf + + The buffer where the file's attributes are + stored. + +### `__wasi_path_filestat_set_times()` + +Adjust the timestamps of a file or directory. + +Note: This is similar to `utimensat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) flags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The path of the file or directory to operate on. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + The desired values of the data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + The desired values of the data modification timestamp. + +- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags + + A bitmask indicating which timestamps to adjust. + +### `__wasi_path_link()` + +Create a hard link. + +Note: This is similar to `linkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags + + Flags determining the method of how the path is resolved. + +- const char \*old\_path and size\_t old\_path\_len + + The source path from which to link. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the hard link. + +### `__wasi_path_open()` + +Open a file or directory. + +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since +this is error-prone in multi-threaded contexts. The returned file +descriptor is guaranteed to be less than 231. + +Note: This is similar to `openat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) dirfd + + The working directory at which the resolution of the path starts. + +- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags + + Flags determining the method of how the path is resolved. + +- const char \*path and size\_t path\_len + + The relative path of the file or directory to open, relative to + the [`dirfd`](#path_open.dirfd) directory. + +- [\_\_wasi\_oflags\_t](#oflags) o_flags + + The method by which to open the file. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + The initial rights of the newly created file descriptor. The + implementation is allowed to return a file descriptor with fewer + rights than specified, if and only if those rights do not apply + to the type of file being opened. + + The *base* rights are rights that will apply to operations using + the file descriptor itself, while the *inheriting* rights are + rights that apply to file descriptors derived from it. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + The initial flags of the file descriptor. + +Outputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor of the file that has been + opened. + +### `__wasi_path_readlink()` + +Read the contents of a symbolic link. + +Note: This is similar to `readlinkat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path of the symbolic link from which to read. + +- char \*buf and size\_t buf\_len + + The buffer to which to write the contents of the symbolic link. + +Outputs: + +- size\_t bufused + + The number of bytes placed in the buffer. + +### `__wasi_path_remove_directory()` + +Remove a directory. + +Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. + +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a directory to remove. + +### `__wasi_path_rename()` + +Rename a file or directory. + +Note: This is similar to `renameat` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) old\_fd + + The working directory at which the resolution of the old path starts. + +- const char \*old\_path and size\_t old\_path\_len + + The source path of the file or directory to rename. + +- [\_\_wasi\_fd\_t](#fd) new\_fd + + The working directory at which the resolution of the new path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path to which to rename the file or directory. + +### `__wasi_path_symlink()` + +Create a symbolic link. + +Note: This is similar to `symlinkat` in POSIX. + +Inputs: + +- const char \*old\_path and size\_t old_path\_len + + The contents of the symbolic link. + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*new\_path and size\_t new\_path\_len + + The destination path at which to create the symbolic link. + +### `__wasi_path_unlink_file()` + +Unlink a file. + +Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. + +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) fd + + The working directory at which the resolution of the path starts. + +- const char \*path and size\_t path\_len + + The path to a file to unlink. + +### `__wasi_poll_oneoff()` + +Concurrently poll for the occurrence of a set of events. + +Inputs: + +- const [\_\_wasi\_subscription\_t](#subscription) \*in + + The events to which to subscribe. + +- [\_\_wasi\_event\_t](#event) \*out + + The events that have occurred. + +- size\_t nsubscriptions + + Both the number of subscriptions and events. + +Outputs: + +- size\_t nevents + + The number of events stored. + +### `__wasi_proc_exit()` + +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +Note: This is similar to `_Exit` in POSIX. + +Inputs: + +- [\_\_wasi\_exitcode\_t](#exitcode) rval + + The exit code returned by the process. + +Does not return. + +### `__wasi_proc_raise()` + +Send a signal to the process of the calling thread. + +Note: This is similar to `raise` in POSIX. + +Inputs: + +- [\_\_wasi\_signal\_t](#signal) sig + + The signal condition to trigger. + +### `__wasi_random_get()` + +Write high-quality random data into a buffer. + +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. + +This function may execute slowly, so when large mounts of random +data are required, it's advisable to use this function to seed a +pseudo-random number generator, rather than to provide the +random data directly. + +Inputs: + +- void \*buf and size\_t buf\_len + + The buffer to fill with random data. + +### `__wasi_sched_yield()` + +Temporarily yield execution of the calling thread. + +Note: This is similar to `sched_yield` in POSIX. + +### `__wasi_sock_recv()` + +Receive a message from a socket. + +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to receive data. + +- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len + + List of scatter/gather vectors to which to store data. + +- [\_\_wasi\_riflags\_t](#riflags) ri\_flags + + Message flags. + +Outputs: + +- size\_t ro\_datalen + + Number of bytes stored in [`ri_data`](#sock_recv.ri_data). + +- [\_\_wasi\_roflags\_t](#roflags) ro\_flags + + Message flags. + +### `__wasi_sock_send()` + +Send a message on a socket. + +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to send data. + +- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len + + List of scatter/gather vectors to which to retrieve data + +- [\_\_wasi\_siflags\_t](#siflags) si\_flags + + Message flags. + +Outputs: + +- size\_t so\_datalen + + Number of bytes transmitted. + +### `__wasi_sock_shutdown()` + +Shut down socket send and receive channels. + +Note: This is similar to `shutdown` in POSIX. + +Inputs: + +- [\_\_wasi\_fd\_t](#fd) sock + + The socket on which to shutdown channels. + +- [\_\_wasi\_sdflags\_t](#sdflags) how + + Which channels on the socket to shut down. + +## Types + +### `__wasi_advice_t` (`uint8_t`) + +File or memory access pattern advisory information. + +Used by [`__wasi_fd_advise()`](#fd_advise). + +Possible values: + +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + +- **`__WASI_ADVICE_NORMAL`** + + The application has no advice to give on its behavior + with respect to the specified data. + +- **`__WASI_ADVICE_RANDOM`** + + The application expects to access the specified data + in a random order. + +- **`__WASI_ADVICE_SEQUENTIAL`** + + The application expects to access the specified data + sequentially from lower offsets to higher offsets. + +- **`__WASI_ADVICE_WILLNEED`** + + The application expects to access the specified data + in the near future. + +### `__wasi_ciovec_t` (`struct`) + +A region of memory for scatter/gather writes. + +Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). + +Members: + +- const void \*buf and size\_t buf\_len + + The address and length of the buffer to be written. + +### `__wasi_clockid_t` (`uint32_t`) + +Identifiers for clocks. + +Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). + +Possible values: + +- **`__WASI_CLOCK_MONOTONIC`** + + The store-wide monotonic clock, which is defined as a + clock measuring real time, whose value cannot be + adjusted and which cannot have negative clock jumps. + + The epoch of this clock is undefined. The absolute + time value of this clock therefore has no meaning. + +- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** + + The CPU-time clock associated with the current + process. + +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + +- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** + + The CPU-time clock associated with the current thread. + +### `__wasi_device_t` (`uint64_t`) + +Identifier for a device containing a file system. Can be used +in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or +directory in the filesystem. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_dircookie_t` (`uint64_t`) + +A reference to the offset of a directory entry. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). + +Special values: + +- **`__WASI_DIRCOOKIE_START`** + + Permanent reference to the first directory entry + within a directory. + +### `__wasi_dirent_t` (`struct`) + +A directory entry. + +Members: + +- [\_\_wasi\_dircookie\_t](#dircookie) d\_next + + The offset of the next directory entry stored in this + directory. + +- [\_\_wasi\_inode\_t](#inode) d\_ino + + The serial number of the file referred to by this + directory entry. + +- uint32\_t d\_namlen + + The length of the name of the directory entry. + +- [\_\_wasi\_filetype\_t](#filetype) d\_type + + The type of the file referred to by this directory + entry. + +### `__wasi_errno_t` (`uint16_t`) + +Error codes returned by functions. + +Not all of these error codes are returned by the functions +provided by this API; some are used in higher-level library layers, +and others are provided merely for alignment with POSIX. + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_ESUCCESS`** + + No error occurred. System call completed successfully. + +- **`__WASI_E2BIG`** + + Argument list too long. + +- **`__WASI_EACCES`** + + Permission denied. + +- **`__WASI_EADDRINUSE`** + + Address in use. + +- **`__WASI_EADDRNOTAVAIL`** + + Address not available. + +- **`__WASI_EAFNOSUPPORT`** + + Address family not supported. + +- **`__WASI_EAGAIN`** + + Resource unavailable, or operation would block. + +- **`__WASI_EALREADY`** + + Connection already in progress. + +- **`__WASI_EBADF`** + + Bad file descriptor. + +- **`__WASI_EBADMSG`** + + Bad message. + +- **`__WASI_EBUSY`** + + Device or resource busy. + +- **`__WASI_ECANCELED`** + + Operation canceled. + +- **`__WASI_ECHILD`** + + No child processes. + +- **`__WASI_ECONNABORTED`** + + Connection aborted. + +- **`__WASI_ECONNREFUSED`** + + Connection refused. + +- **`__WASI_ECONNRESET`** + + Connection reset. + +- **`__WASI_EDEADLK`** + + Resource deadlock would occur. + +- **`__WASI_EDESTADDRREQ`** + + Destination address required. + +- **`__WASI_EDOM`** + + Mathematics argument out of domain of function. + +- **`__WASI_EDQUOT`** + + Reserved. + +- **`__WASI_EEXIST`** + + File exists. + +- **`__WASI_EFAULT`** + + Bad address. + +- **`__WASI_EFBIG`** + + File too large. + +- **`__WASI_EHOSTUNREACH`** + + Host is unreachable. + +- **`__WASI_EIDRM`** + + Identifier removed. + +- **`__WASI_EILSEQ`** + + Illegal byte sequence. + +- **`__WASI_EINPROGRESS`** + + Operation in progress. + +- **`__WASI_EINTR`** + + Interrupted function. + +- **`__WASI_EINVAL`** + + Invalid argument. + +- **`__WASI_EIO`** + + I/O error. + +- **`__WASI_EISCONN`** + + Socket is connected. + +- **`__WASI_EISDIR`** + + Is a directory. + +- **`__WASI_ELOOP`** + + Too many levels of symbolic links. + +- **`__WASI_EMFILE`** + + File descriptor value too large. + +- **`__WASI_EMLINK`** + + Too many links. + +- **`__WASI_EMSGSIZE`** + + Message too large. + +- **`__WASI_EMULTIHOP`** + + Reserved. + +- **`__WASI_ENAMETOOLONG`** + + Filename too long. + +- **`__WASI_ENETDOWN`** + + Network is down. + +- **`__WASI_ENETRESET`** + + Connection aborted by network. + +- **`__WASI_ENETUNREACH`** + + Network unreachable. + +- **`__WASI_ENFILE`** + + Too many files open in system. + +- **`__WASI_ENOBUFS`** + + No buffer space available. + +- **`__WASI_ENODEV`** + + No such device. + +- **`__WASI_ENOENT`** + + No such file or directory. + +- **`__WASI_ENOEXEC`** + + Executable file format error. + +- **`__WASI_ENOLCK`** + + No locks available. + +- **`__WASI_ENOLINK`** + + Reserved. + +- **`__WASI_ENOMEM`** + + Not enough space. + +- **`__WASI_ENOMSG`** + + No message of the desired type. + +- **`__WASI_ENOPROTOOPT`** + + Protocol not available. + +- **`__WASI_ENOSPC`** + + No space left on device. + +- **`__WASI_ENOSYS`** + + Function not supported. + +- **`__WASI_ENOTCONN`** + + The socket is not connected. + +- **`__WASI_ENOTDIR`** + + Not a directory or a symbolic link to a directory. + +- **`__WASI_ENOTEMPTY`** + + Directory not empty. + +- **`__WASI_ENOTRECOVERABLE`** + + State not recoverable. + +- **`__WASI_ENOTSOCK`** + + Not a socket. + +- **`__WASI_ENOTSUP`** + + Not supported, or operation not supported on socket. + +- **`__WASI_ENOTTY`** + + Inappropriate I/O control operation. + +- **`__WASI_ENXIO`** + + No such device or address. + +- **`__WASI_EOVERFLOW`** + + Value too large to be stored in data type. + +- **`__WASI_EOWNERDEAD`** + + Previous owner died. + +- **`__WASI_EPERM`** + + Operation not permitted. + +- **`__WASI_EPIPE`** + + Broken pipe. + +- **`__WASI_EPROTO`** + + Protocol error. + +- **`__WASI_EPROTONOSUPPORT`** + + Protocol not supported. + +- **`__WASI_EPROTOTYPE`** + + Protocol wrong type for socket. + +- **`__WASI_ERANGE`** + + Result too large. + +- **`__WASI_EROFS`** + + Read-only file system. + +- **`__WASI_ESPIPE`** + + Invalid seek. + +- **`__WASI_ESRCH`** + + No such process. + +- **`__WASI_ESTALE`** + + Reserved. + +- **`__WASI_ETIMEDOUT`** + + Connection timed out. + +- **`__WASI_ETXTBSY`** + + Text file busy. + +- **`__WASI_EXDEV`** + + Cross-device link. + +- **`__WASI_ENOTCAPABLE`** + + Extension: Capabilities insufficient. + +### `__wasi_event_t` (`struct`) + +An event that occurred. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that got attached to + [`__wasi_subscription_t::userdata`](#subscription.userdata). + +- [\_\_wasi\_errno\_t](#errno) error + + If non-zero, an error that occurred while processing + the subscription request. + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event that occurred. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_filesize\_t](#filesize) nbytes + + The number of bytes available for reading or writing. + + - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags + + The state of the file descriptor. + +### `__wasi_eventrwflags_t` (`uint16_t` bitfield) + +The state of the file descriptor subscribed to with +[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +Used by [`__wasi_event_t`](#event). + +Possible values: + +- **`__WASI_EVENT_FD_READWRITE_HANGUP`** + + The peer of this socket has closed or disconnected. + +### `__wasi_eventtype_t` (`uint8_t`) + +Type of a subscription to an event or its occurrence. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_EVENTTYPE_CLOCK`** + + The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) + has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +- **`__WASI_EVENTTYPE_FD_READ`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + data available for reading. This event always triggers + for regular files. + +- **`__WASI_EVENTTYPE_FD_WRITE`** + + File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has + capacity available for writing. This event always + triggers for regular files. + +### `__wasi_exitcode_t` (`uint32_t`) + +Exit code generated by a process when exiting. + +Used by [`__wasi_proc_exit()`](#proc_exit). + +### `__wasi_fd_t` (`uint32_t`) + +A file descriptor number. + +Used by many functions in this API. + +As in POSIX, three file descriptor numbers are provided to instances +on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, +and `STDERR_FILENO`). + +Other than these, WASI implementations are not required to allocate +new file descriptors in ascending order. + +### `__wasi_fdflags_t` (`uint16_t` bitfield) + +File descriptor flags. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_FDFLAG_APPEND`** + + Append mode: Data written to the file is always + appended to the file's end. + +- **`__WASI_FDFLAG_DSYNC`** + + Write according to synchronized I/O data integrity + completion. Only the data stored in the file is + synchronized. + +- **`__WASI_FDFLAG_NONBLOCK`** + + Non-blocking mode. + +- **`__WASI_FDFLAG_RSYNC`** + + Synchronized read I/O operations. + +- **`__WASI_FDFLAG_SYNC`** + + Write according to synchronized I/O file integrity completion. + In addition to synchronizing the data stored in the file, the + implementation may also synchronously update the file's metadata. + +### `__wasi_fdstat_t` (`struct`) + +File descriptor attributes. + +Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). + +Members: + +- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype + + File type. + +- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags + + File descriptor flags. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base + + Rights that apply to this file descriptor. + +- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting + + Maximum set of rights that may be installed on new + file descriptors that are created through this file + descriptor, e.g., through [`__wasi_path_open()`](#path_open). + +### `__wasi_filedelta_t` (`int64_t`) + +Relative offset within a file. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +### `__wasi_filesize_t` (`uint64_t`) + +Non-negative file size or length of a region within a file. + +Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +### `__wasi_filestat_t` (`struct`) + +File attributes. + +Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). + +Members: + +- [\_\_wasi\_device\_t](#device) st\_dev + + Device ID of device containing the file. + +- [\_\_wasi\_inode\_t](#inode) st\_ino + + File serial number. + +- [\_\_wasi\_filetype\_t](#filetype) st\_filetype + + File type. + +- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink + + Number of hard links to the file. + +- [\_\_wasi\_filesize\_t](#filesize) st\_size + + For regular files, the file size in bytes. For + symbolic links, the length in bytes of the pathname + contained in the symbolic link. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim + + Last data access timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim + + Last data modification timestamp. + +- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim + + Last file status change timestamp. + +### `__wasi_filetype_t` (`uint8_t`) + +The type of a file descriptor or file. + +Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). + +Possible values: + +- **`__WASI_FILETYPE_UNKNOWN`** + + The type of the file descriptor or file is unknown or + is different from any of the other types specified. + +- **`__WASI_FILETYPE_BLOCK_DEVICE`** + + The file descriptor or file refers to a block device + inode. + +- **`__WASI_FILETYPE_CHARACTER_DEVICE`** + + The file descriptor or file refers to a character + device inode. + +- **`__WASI_FILETYPE_DIRECTORY`** + + The file descriptor or file refers to a directory + inode. + +- **`__WASI_FILETYPE_REGULAR_FILE`** + + The file descriptor or file refers to a regular file + inode. + +- **`__WASI_FILETYPE_SOCKET_DGRAM`** + + The file descriptor or file refers to a datagram + socket. + +- **`__WASI_FILETYPE_SOCKET_STREAM`** + + The file descriptor or file refers to a byte-stream + socket. + +- **`__WASI_FILETYPE_SYMBOLIC_LINK`** + + The file refers to a symbolic link inode. + +### `__wasi_fstflags_t` (`uint16_t` bitfield) + +Which file time attributes to adjust. + +Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +Possible values: + +- **`__WASI_FILESTAT_SET_ATIM`** + + Adjust the last data access timestamp to the value + stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). + +- **`__WASI_FILESTAT_SET_ATIM_NOW`** + + Adjust the last data access timestamp to the time + of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +- **`__WASI_FILESTAT_SET_MTIM`** + + Adjust the last data modification timestamp to the + value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). + +- **`__WASI_FILESTAT_SET_MTIM_NOW`** + + Adjust the last data modification timestamp to the + time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). + +### `__wasi_inode_t` (`uint64_t`) + +File serial number that is unique within its file system. + +Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). + +### `__wasi_iovec_t` (`struct`) + +A region of memory for scatter/gather reads. + +Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). + +Members: + +- void \*buf and size\_t buf\_len + + The address and length of the buffer to be filled. + +### `__wasi_linkcount_t` (`uint32_t`) + +Number of hard links to an inode. + +Used by [`__wasi_filestat_t`](#filestat). + +### `__wasi_lookupflags_t` (`uint32_t` bitfield) + +Flags determining the method of how paths are resolved. + +Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** + + As long as the resolved path corresponds to a symbolic + link, it is expanded. + +### `__wasi_oflags_t` (`uint16_t` bitfield) + +Open flags used by [`__wasi_path_open()`](#path_open). + +Used by [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_O_CREAT`** + + Create file if it does not exist. + +- **`__WASI_O_DIRECTORY`** + + Fail if not a directory. + +- **`__WASI_O_EXCL`** + + Fail if file already exists. + +- **`__WASI_O_TRUNC`** + + Truncate file to size 0. + +### `__wasi_riflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_PEEK`** + + Returns the message without removing it from the + socket's receive queue. + +- **`__WASI_SOCK_RECV_WAITALL`** + + On byte-stream sockets, block until the full amount + of data can be returned. + +### `__wasi_rights_t` (`uint64_t` bitfield) + +File descriptor rights, determining which actions may be +performed. + +Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). + +Possible values: + +- **`__WASI_RIGHT_FD_DATASYNC`** + + The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_READ`** + + The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke + [`__wasi_fd_pread()`](#fd_pread). + +- **`__WASI_RIGHT_FD_SEEK`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies + [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). + +- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** + + The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). + +- **`__WASI_RIGHT_FD_SYNC`** + + The right to invoke [`__wasi_fd_sync()`](#fd_sync). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and + [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). + +- **`__WASI_RIGHT_FD_TELL`** + + The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the + file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with + offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). + +- **`__WASI_RIGHT_FD_WRITE`** + + The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). + + If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to + invoke [`__wasi_fd_pwrite()`](#fd_pwrite). + +- **`__WASI_RIGHT_FD_ADVISE`** + + The right to invoke [`__wasi_fd_advise()`](#fd_advise). + +- **`__WASI_RIGHT_FD_ALLOCATE`** + + The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). + +- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** + + The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). + +- **`__WASI_RIGHT_PATH_CREATE_FILE`** + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke + [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). + +- **`__WASI_RIGHT_PATH_LINK_SOURCE`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_LINK_TARGET`** + + The right to invoke [`__wasi_path_link()`](#path_link) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_OPEN`** + + The right to invoke [`__wasi_path_open()`](#path_open). + +- **`__WASI_RIGHT_FD_READDIR`** + + The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). + +- **`__WASI_RIGHT_PATH_READLINK`** + + The right to invoke [`__wasi_path_readlink()`](#path_readlink). + +- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the source directory. + +- **`__WASI_RIGHT_PATH_RENAME_TARGET`** + + The right to invoke [`__wasi_path_rename()`](#path_rename) with the file + descriptor as the target directory. + +- **`__WASI_RIGHT_PATH_FILESTAT_GET`** + + The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** + + The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). + + If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to + invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). + +- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +- **`__WASI_RIGHT_FD_FILESTAT_GET`** + + The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** + + The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). + +- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** + + The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). + +- **`__WASI_RIGHT_PATH_SYMLINK`** + + The right to invoke [`__wasi_path_symlink()`](#path_symlink). + +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + +- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** + + The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). + +- **`__WASI_RIGHT_POLL_FD_READWRITE`** + + If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). + + If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to + invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). + +- **`__WASI_RIGHT_SOCK_SHUTDOWN`** + + The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). + +### `__wasi_roflags_t` (`uint16_t` bitfield) + +Flags returned by [`__wasi_sock_recv()`](#sock_recv). + +Used by [`__wasi_sock_recv()`](#sock_recv). + +Possible values: + +- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** + + Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been + truncated. + +### `__wasi_sdflags_t` (`uint8_t` bitfield) + +Which channels on a socket to shut down. + +Used by [`__wasi_sock_shutdown()`](#sock_shutdown). + +Possible values: + +- **`__WASI_SHUT_RD`** + + Disables further receive operations. + +- **`__WASI_SHUT_WR`** + + Disables further send operations. + +### `__wasi_siflags_t` (`uint16_t` bitfield) + +Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +Used by [`__wasi_sock_send()`](#sock_send). + +### `__wasi_signal_t` (`uint8_t`) + +Signal condition. + +Used by [`__wasi_proc_raise()`](#proc_raise). + +Possible values: + +- **`__WASI_SIGABRT`** + + Process abort signal. + + Action: Terminates the process. + +- **`__WASI_SIGALRM`** + + Alarm clock. + + Action: Terminates the process. + +- **`__WASI_SIGBUS`** + + Access to an undefined portion of a memory object. + + Action: Terminates the process. + +- **`__WASI_SIGCHLD`** + + Child process terminated, stopped, or continued. + + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGFPE`** + + Erroneous arithmetic operation. + + Action: Terminates the process. + +- **`__WASI_SIGHUP`** + + Hangup. + + Action: Terminates the process. + +- **`__WASI_SIGILL`** + + Illegal instruction. + + Action: Terminates the process. + +- **`__WASI_SIGINT`** + + Terminate interrupt signal. + + Action: Terminates the process. + +- **`__WASI_SIGKILL`** + + Kill. + + Action: Terminates the process. + +- **`__WASI_SIGPIPE`** + + Write on a pipe with no one to read it. + + Action: Ignored. + +- **`__WASI_SIGQUIT`** + + Terminal quit signal. + + Action: Terminates the process. + +- **`__WASI_SIGSEGV`** + + Invalid memory reference. + + Action: Terminates the process. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. + +- **`__WASI_SIGSYS`** + + Bad system call. + + Action: Terminates the process. + +- **`__WASI_SIGTERM`** + + Termination signal. + + Action: Terminates the process. + +- **`__WASI_SIGTRAP`** + + Trace/breakpoint trap. + + Action: Terminates the process. + +- **`__WASI_SIGTSTP`** + + Terminal stop signal. + + Action: Stops executing. + +- **`__WASI_SIGTTIN`** + + Background process attempting read. + + Action: Stops executing. + +- **`__WASI_SIGTTOU`** + + Background process attempting write. + + Action: Stops executing. + +- **`__WASI_SIGURG`** + + High bandwidth data is available at a socket. + + Action: Ignored. + +- **`__WASI_SIGUSR1`** + + User-defined signal 1. + + Action: Terminates the process. + +- **`__WASI_SIGUSR2`** + + User-defined signal 2. + + Action: Terminates the process. + +- **`__WASI_SIGVTALRM`** + + Virtual timer expired. + + Action: Terminates the process. + +- **`__WASI_SIGXCPU`** + + CPU time limit exceeded. + + Action: Terminates the process. + +- **`__WASI_SIGXFSZ`** + + File size limit exceeded. + + Action: Terminates the process. + +### `__wasi_subclockflags_t` (`uint16_t` bitfield) + +Flags determining how to interpret the timestamp provided in +[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). + +Used by [`__wasi_subscription_t`](#subscription). + +Possible values: + +- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** + + If set, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp + of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + + If clear, treat the timestamp provided in + [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current + time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). + +### `__wasi_subscription_t` (`struct`) + +Subscription to an event. + +Used by [`__wasi_poll_oneoff()`](#poll_oneoff). + +Members: + +- [\_\_wasi\_userdata\_t](#userdata) userdata + + User-provided value that is attached to the subscription in the + implementation and returned through + [`__wasi_event_t::userdata`](#event.userdata). + +- [\_\_wasi\_eventtype\_t](#eventtype) type + + The type of the event to which to subscribe. + +- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): + + - **`u.clock`** + + - [\_\_wasi\_userdata\_t](#userdata) identifier + + The user-defined unique identifier of the clock. + + - [\_\_wasi\_clockid\_t](#clockid) clock\_id + + The clock against which to compare the timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) timeout + + The absolute or relative timestamp. + + - [\_\_wasi\_timestamp\_t](#timestamp) precision + + The amount of time that the implementation may wait additionally + to coalesce with other events. + + - [\_\_wasi\_subclockflags\_t](#subclockflags) flags + + Flags specifying whether the timeout is absolute or relative. + +- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): + + - **`u.fd_readwrite`** + + - [\_\_wasi\_fd\_t](#fd) fd + + The file descriptor on which to wait for it to become ready + for reading or writing. + +### `__wasi_timestamp_t` (`uint64_t`) + +Timestamp in nanoseconds. + +Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). + +### `__wasi_userdata_t` (`uint64_t`) + +User-provided value that may be attached to objects that is +retained when extracted from the implementation. + +Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). + +### `__wasi_whence_t` (`uint8_t`) + +The position relative to which to set the offset of the file descriptor. + +Used by [`__wasi_fd_seek()`](#fd_seek). + +Possible values: + +- **`__WASI_WHENCE_CUR`** + + Seek relative to current position. + +- **`__WASI_WHENCE_END`** + + Seek relative to end-of-file. + +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + diff --git a/proposals/filesystem/phases/unstable/witx/typenames.witx b/proposals/filesystem/phases/unstable/witx/typenames.witx new file mode 100644 index 000000000..e04a188d9 --- /dev/null +++ b/proposals/filesystem/phases/unstable/witx/typenames.witx @@ -0,0 +1,752 @@ +;; Type names used by low-level WASI interfaces. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(typename $size_t u32) + +;; Non-negative file size or length of a region within a file. +(typename $filesize_t u64) + +;; Timestamp in nanoseconds. +(typename $timestamp_t u64) + +;; Identifiers for clocks. +(typename $clockid_t + (enum u32 + ;; The store-wide monotonic clock, which is defined as a clock measuring + ;; real time, whose value cannot be adjusted and which cannot have negative + ;; clock jumps. The epoch of this clock is undefined. The absolute time + ;; value of this clock therefore has no meaning. + $CLOCK_MONOTONIC + ;; The CPU-time clock associated with the current process. + $CLOCK_PROCESS_CPUTIME_ID + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME + ;; The CPU-time clock associated with the current thread. + $CLOCK_THREAD_CPUTIME_ID + ) +) + +;; Error codes returned by functions. +;; Not all of these error codes are returned by the functions provided by this +;; API; some are used in higher-level library layers, and others are provided +;; merely for alignment with POSIX. +(typename $errno_t + (enum u16 + ;; No error occurred. System call completed successfully. + $ESUCCESS + ;; Argument list too long. + $E2BIG + ;; Permission denied. + $EACCES + ;; Address in use. + $EADDRINUSE + ;; Address not available. + $EADDRNOTAVAIL + ;; Address family not supported. + $EAFNOSUPPORT + ;; Resource unavailable, or operation would block. + $EAGAIN + ;; Connection already in progress. + $EALREADY + ;; Bad file descriptor. + $EBADF + ;; Bad message. + $EBADMSG + ;; Device or resource busy. + $EBUSY + ;; Operation canceled. + $ECANCELED + ;; No child processes. + $ECHILD + ;; Connection aborted. + $ECONNABORTED + ;; Connection refused. + $ECONNREFUSED + ;; Connection reset. + $ECONNRESET + ;; Resource deadlock would occur. + $EDEADLK + ;; Destination address required. + $EDESTADDRREQ + ;; Mathematics argument out of domain of function. + $EDOM + ;; Reserved. + $EDQUOT + ;; File exists. + $EEXIST + ;; Bad address. + $EFAULT + ;; File too large. + $EFBIG + ;; Host is unreachable. + $EHOSTUNREACH + ;; Identifier removed. + $EIDRM + ;; Illegal byte sequence. + $EILSEQ + ;; Operation in progress. + $EINPROGRESS + ;; Interrupted function. + $EINTR + ;; Invalid argument. + $EINVAL + ;; I/O error. + $EIO + ;; Socket is connected. + $EISCONN + ;; Is a directory. + $EISDIR + ;; Too many levels of symbolic links. + $ELOOP + ;; File descriptor value too large. + $EMFILE + ;; Too many links. + $EMLINK + ;; Message too large. + $EMSGSIZE + ;; Reserved. + $EMULTIHOP + ;; Filename too long. + $ENAMETOOLONG + ;; Network is down. + $ENETDOWN + ;; Connection aborted by network. + $ENETRESET + ;; Network unreachable. + $ENETUNREACH + ;; Too many files open in system. + $ENFILE + ;; No buffer space available. + $ENOBUFS + ;; No such device. + $ENODEV + ;; No such file or directory. + $ENOENT + ;; Executable file format error. + $ENOEXEC + ;; No locks available. + $ENOLCK + ;; Reserved. + $ENOLINK + ;; Not enough space. + $ENOMEM + ;; No message of the desired type. + $ENOMSG + ;; Protocol not available. + $ENOPROTOOPT + ;; No space left on device. + $ENOSPC + ;; Function not supported. + $ENOSYS + ;; The socket is not connected. + $ENOTCONN + ;; Not a directory or a symbolic link to a directory. + $ENOTDIR + ;; Directory not empty. + $ENOTEMPTY + ;; State not recoverable. + $ENOTRECOVERABLE + ;; Not a socket. + $ENOTSOCK + ;; Not supported, or operation not supported on socket. + $ENOTSUP + ;; Inappropriate I/O control operation. + $ENOTTY + ;; No such device or address. + $ENXIO + ;; Value too large to be stored in data type. + $EOVERFLOW + ;; Previous owner died. + $EOWNERDEAD + ;; Operation not permitted. + $EPERM + ;; Broken pipe. + $EPIPE + ;; Protocol error. + $EPROTO + ;; Protocol not supported. + $EPROTONOSUPPORT + ;; Protocol wrong type for socket. + $EPROTOTYPE + ;; Result too large. + $ERANGE + ;; Read-only file system. + $EROFS + ;; Invalid seek. + $ESPIPE + ;; No such process. + $ESRCH + ;; Reserved. + $ESTALE + ;; Connection timed out. + $ETIMEDOUT + ;; Text file busy. + $ETXTBSY + ;; Cross-device link. + $EXDEV + ;; Extension: Capabilities insufficient. + $ENOTCAPABLE + ) +) + +;; File descriptor rights, determining which actions may be performed. +(typename $rights_t + (flags u64 + ;; The right to invoke `fd_datasync`. + ;; + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_DSYNC`. + (flag $RIGHT_FD_DATASYNC) + ;; The right to invoke `fd_read` and `sock_recv`. + ;; + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + (flag $RIGHT_FD_READ) + ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + (flag $RIGHT_FD_SEEK) + ;; The right to invoke `fd_fdstat_set_flags`. + (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + ;; The right to invoke `fd_sync`. + ;; + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + (flag $RIGHT_FD_SYNC) + ;; The right to invoke `fd_seek` in such a way that the file offset + ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;; invoke `fd_tell`. + (flag $RIGHT_FD_TELL) + ;; The right to invoke `fd_write` and `sock_send`. + ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + (flag $RIGHT_FD_WRITE) + ;; The right to invoke `fd_advise`. + (flag $RIGHT_FD_ADVISE) + ;; The right to invoke `fd_allocate`. + (flag $RIGHT_FD_ALLOCATE) + ;; The right to invoke `path_create_directory`. + (flag $RIGHT_PATH_CREATE_DIRECTORY) + ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + (flag $RIGHT_PATH_CREATE_FILE) + ;; The right to invoke `path_link` with the file descriptor as the + ;; source directory. + (flag $RIGHT_PATH_LINK_SOURCE) + ;; The right to invoke `path_link` with the file descriptor as the + ;; target directory. + (flag $RIGHT_PATH_LINK_TARGET) + ;; The right to invoke `path_open`. + (flag $RIGHT_PATH_OPEN) + ;; The right to invoke `fd_readdir`. + (flag $RIGHT_FD_READDIR) + ;; The right to invoke `path_readlink`. + (flag $RIGHT_PATH_READLINK) + ;; The right to invoke `path_rename` with the file descriptor as the source directory. + (flag $RIGHT_PATH_RENAME_SOURCE) + ;; The right to invoke `path_rename` with the file descriptor as the target directory. + (flag $RIGHT_PATH_RENAME_TARGET) + ;; The right to invoke `path_filestat_get`. + (flag $RIGHT_PATH_FILESTAT_GET) + ;; The right to change a file's size (there is no `path_filestat_set_size`). + ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + ;; The right to invoke `path_filestat_set_times`. + (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + ;; The right to invoke `fd_filestat_get`. + (flag $RIGHT_FD_FILESTAT_GET) + ;; The right to invoke `fd_filestat_set_size`. + (flag $RIGHT_FD_FILESTAT_SET_SIZE) + ;; The right to invoke `fd_filestat_set_times`. + (flag $RIGHT_FD_FILESTAT_SET_TIMES) + ;; The right to invoke `path_symlink`. + (flag $RIGHT_PATH_SYMLINK) + ;; The right to invoke `path_unlink_file`. + (flag $RIGHT_PATH_UNLINK_FILE) + ;; The right to invoke `path_remove_directory`. + (flag $RIGHT_PATH_REMOVE_DIRECTORY) + ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + (flag $RIGHT_POLL_FD_READWRITE) + ;; The right to invoke `sock_shutdown`. + (flag $RIGHT_SOCK_SHUTDOWN) + ) +) + +;; A file descriptor index. +(typename $fd_t u32) + +;; A region of memory for scatter/gather reads. +(typename $iovec_t + (struct + ;; The address of the buffer to be filled. + (field $buf (@witx pointer u8)) + ;; The length of the buffer to be filled. + (field $buf_len $size_t) + ) +) + +;; A region of memory for scatter/gather writes. +(typename $ciovec_t + (struct + ;; The address of the buffer to be written. + (field $buf (@witx const_pointer u8)) + ;; The length of the buffer to be written. + (field $buf_len $size_t) + ) +) + +(typename $iovec_t_array (array $iovec_t)) +(typename $ciovec_t_array (array $ciovec_t)) + +;; Relative offset within a file. +(typename $filedelta_t s64) + +;; The position relative to which to set the offset of the file descriptor. +(typename $whence_t + (enum u8 + ;; Seek relative to current position. + $WHENCE_CUR + ;; Seek relative to end-of-file. + $WHENCE_END + ;; Seek relative to start-of-file. + $WHENCE_SET + ) +) + +;; A reference to the offset of a directory entry. +(typename $dircookie_t u64) + +;; The type for the $d_namlen field of $dirent_t. +(typename $dirnamlen_t u32) + +;; File serial number that is unique within its file system. +(typename $inode_t u64) + +;; The type of a file descriptor or file. +(typename $filetype_t + (enum u8 + ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $FILETYPE_UNKNOWN + ;; The file descriptor or file refers to a block device inode. + $FILETYPE_BLOCK_DEVICE + ;; The file descriptor or file refers to a character device inode. + $FILETYPE_CHARACTER_DEVICE + ;; The file descriptor or file refers to a directory inode. + $FILETYPE_DIRECTORY + ;; The file descriptor or file refers to a regular file inode. + $FILETYPE_REGULAR_FILE + ;; The file descriptor or file refers to a datagram socket. + $FILETYPE_SOCKET_DGRAM + ;; The file descriptor or file refers to a byte-stream socket. + $FILETYPE_SOCKET_STREAM + ;; The file refers to a symbolic link inode. + $FILETYPE_SYMBOLIC_LINK + ) +) + +;; A directory entry. +(typename $dirent_t + (struct + ;; The offset of the next directory entry stored in this directory. + (field $d_next $dircookie_t) + ;; The serial number of the file referred to by this directory entry. + (field $d_ino $inode_t) + ;; The length of the name of the directory entry. + (field $d_namlen $dirnamlen_t) + ;; The type of the file referred to by this directory entry. + (field $d_type $filetype_t) + ) +) + +;; File or memory access pattern advisory information. +(typename $advice_t + (enum u8 + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE + ;; The application has no advice to give on its behavior with respect to the specified data. + $ADVICE_NORMAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM + ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in the near future. + $ADVICE_WILLNEED + ) +) + +;; File descriptor flags. +(typename $fdflags_t + (flags u16 + ;; Append mode: Data written to the file is always appended to the file's end. + (flag $FDFLAG_APPEND) + ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + (flag $FDFLAG_DSYNC) + ;; Non-blocking mode. + (flag $FDFLAG_NONBLOCK) + ;; Synchronized read I/O operations. + (flag $FDFLAG_RSYNC) + ;; Write according to synchronized I/O file integrity completion. In + ;; addition to synchronizing the data stored in the file, the implementation + ;; may also synchronously update the file's metadata. + (flag $FDFLAG_SYNC) + ) +) + +;; File descriptor attributes. +(typename $fdstat_t + (struct + ;; File type. + (field $fs_filetype $filetype_t) + ;; File descriptor flags. + (field $fs_flags $fdflags_t) + ;; Rights that apply to this file descriptor. + (field $fs_rights_base $rights_t) + ;; Maximum set of rights that may be installed on new file descriptors that + ;; are created through this file descriptor, e.g., through `path_open`. + (field $fs_rights_inheriting $rights_t) + ) +) + +;; Identifier for a device containing a file system. Can be used in combination +;; with `inode_t` to uniquely identify a file or directory in the filesystem. +(typename $device_t u64) + +;; Which file time attributes to adjust. +(typename $fstflags_t + (flags u16 + ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + (flag $FILESTAT_SET_ATIM) + ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + (flag $FILESTAT_SET_ATIM_NOW) + ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + (flag $FILESTAT_SET_MTIM) + ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + (flag $FILESTAT_SET_MTIM_NOW) + ) +) + +;; Flags determining the method of how paths are resolved. +(typename $lookupflags_t + (flags u32 + ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + (flag $LOOKUP_SYMLINK_FOLLOW) + ) +) + +;; Open flags used by `path_open`. +(typename $oflags_t + (flags u16 + ;; Create file if it does not exist. + (flag $O_CREAT) + ;; Fail if not a directory. + (flag $O_DIRECTORY) + ;; Fail if file already exists. + (flag $O_EXCL) + ;; Truncate file to size 0. + (flag $O_TRUNC) + ) +) + +;; Number of hard links to an inode. +(typename $linkcount_t u32) + +;; File attributes. +(typename $filestat_t + (struct + ;; Device ID of device containing the file. + (field $st_dev $device_t) + ;; File serial number. + (field $st_ino $inode_t) + ;; File type. + (field $st_filetype $filetype_t) + ;; Number of hard links to the file. + (field $st_nlink $linkcount_t) + ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + (field $st_size $filesize_t) + ;; Last data access timestamp. + (field $st_atim $timestamp_t) + ;; Last data modification timestamp. + (field $st_mtim $timestamp_t) + ;; Last file status change timestamp. + (field $st_ctim $timestamp_t) + ) +) + +;; User-provided value that may be attached to objects that is retained when +;; extracted from the implementation. +(typename $userdata_t u64) + +;; Type of a subscription to an event or its occurrence. +(typename $eventtype_t + (flags u8 + ;; The time value of clock `subscription_t::u.clock.clock_id` has + ;; reached timestamp `subscription_t::u.clock.timeout`. + (flag $EVENTTYPE_CLOCK) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;; available for reading. This event always triggers for regular files. + (flag $EVENTTYPE_FD_READ) + ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;; available for writing. This event always triggers for regular files. + (flag $EVENTTYPE_FD_WRITE) + ) +) + +;; The state of the file descriptor subscribed to with +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $eventrwflags_t + (flags u16 + ;; The peer of this socket has closed or disconnected. + (flag $EVENT_FD_READWRITE_HANGUP) + ) +) + +;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;; `EVENTTYPE_FD_WRITE`. +(typename $event_fd_readwrite_t + (struct + ;; The number of bytes available for reading or writing. + (field $nbytes $filesize_t) + ;; The state of the file descriptor. + (field $flags $eventrwflags_t) + ) +) + +;; The contents of an $event_t. +(typename $event_u + (union + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $event_fd_readwrite_t) + ) +) + +;; An event that occurred. +(typename $event_t + (struct + ;; User-provided value that got attached to `subscription_t::userdata`. + (field $userdata $userdata_t) + ;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno_t) + ;; The type of the event that occurred. + (field $type $eventtype_t) + ;; The contents of the event. + (field $u $event_u) + ) +) + +;; Flags determining how to interpret the timestamp provided in +;; `subscription_t::u.clock.timeout.` +(typename $subclockflags_t + (flags u16 + ;; If set, treat the timestamp provided in + ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;; provided in `subscription_t::u.clock.timeout` relative to the + ;; current time value of clock `subscription_t::u.clock.clock_id.` + (flag $SUBSCRIPTION_CLOCK_ABSTIME) + ) +) + +;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +(typename $subscription_clock_t + (struct + ;; The user-defined unique identifier of the clock. + (field $identifier $userdata_t) + ;; The clock against which to compare the timestamp. + (field $clock_id $clockid_t) + ;; The absolute or relative timestamp. + (field $timeout $timestamp_t) + ;; The amount of time that the implementation may wait additionally + ;; to coalesce with other events. + ;; + ;; Flags specifying whether the timeout is absolute or relative + (field $precision $timestamp_t) + ) +) + +;; The contents of a $subscription_t when type is type is +;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +(typename $subscription_fd_readwrite_t + (struct + ;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $file_descriptor $fd_t) + ) +) + +;; The contents of a $subscription_t. +(typename $subscription_u + (union + ;; When type is `EVENTTYPE_CLOCK`: + (field $clock $subscription_clock_t) + ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + (field $fd_readwrite $subscription_fd_readwrite_t) + ) +) + +;; Subscription to an event. +(typename $subscription_t + (struct + ;; User-provided value that is attached to the subscription in the + ;; implementation and returned through `event_t::userdata`. + (field $userdata $userdata_t) + ;; The type of the event to which to subscribe. + (field $type $eventtype_t) + ;; The contents of the subscription. + (field $u $subscription_u) + ) +) + +;; Exit code generated by a process when exiting. +(typename $exitcode_t u32) + +;; Signal condition. +(typename $signal_t + (enum u8 + ;; Process abort signal. + ;; Action: Terminates the process. + $SIGABRT + ;; Alarm clock. + ;; Action: Terminates the process. + $SIGALRM + ;; Access to an undefined portion of a memory object. + ;; Action: Terminates the process. + $SIGBUS + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT + ;; Erroneous arithmetic operation. + ;; Action: Terminates the process. + $SIGFPE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Kill. + ;; Action: Terminates the process. + $SIGKILL + ;; Write on a pipe with no one to read it. + ;; Action: Ignored. + $SIGPIPE + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Invalid memory reference. + ;; Action: Terminates the process. + $SIGSEGV + ;; Stop executing. + ;; Action: Stops executing. + $SIGSTOP + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS + ;; Termination signal. + ;; Action: Terminates the process. + $SIGTERM + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP + ;; Terminal stop signal. + ;; Action: Stops executing. + $SIGTSTP + ;; Background process attempting read. + ;; Action: Stops executing. + $SIGTTIN + ;; Background process attempting write. + ;; Action: Stops executing. + $SIGTTOU + ;; High bandwidth data is available at a socket. + ;; Action: Ignored. + $SIGURG + ;; User-defined signal 1. + ;; Action: Terminates the process. + $SIGUSR1 + ;; User-defined signal 2. + ;; Action: Terminates the process. + $SIGUSR2 + ;; Virtual timer expired. + ;; Action: Terminates the process. + $SIGVTALRM + ;; CPU time limit exceeded. + ;; Action: Terminates the process. + $SIGXCPU + ;; File size limit exceeded. + ;; Action: Terminates the process. + $SIGXFSZ + ) +) + +;; Flags provided to `sock_recv`. +(typename $riflags_t + (flags u16 + ;; Returns the message without removing it from the socket's receive queue. + (flag $SOCK_RECV_PEEK) + ;; On byte-stream sockets, block until the full amount of data can be returned. + (flag $SOCK_RECV_WAITALL) + ) +) + +;; Flags returned by `sock_recv`. +(typename $roflags_t + (flags u16 + ;; Returned by `sock_recv`: Message data has been truncated. + (flag $SOCK_RECV_DATA_TRUNCATED) + ) +) + +;; Flags provided to `sock_send`. As there are currently no flags +;; defined, it must be set to zero. +(typename $siflags_t u16) + +;; Which channels on a socket to shut down. +(typename $sdflags_t + (flags u8 + ;; Disables further receive operations. + (flag $SHUT_RD) + ;; Disables further send operations. + (flag $SHUT_WR) + ) +) + +;; Identifiers for preopened capabilities. +(typename $preopentype_t + (enum u8 + ;; A pre-opened directory. + $PREOPENTYPE_DIR + ) +) + +;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +(typename $prestat_dir + (struct + ;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size_t) + ) +) + +;; The contents of an $prestat_t. +(typename $prestat_u + (union + ;; When type is `PREOPENTYPE_DIR`: + (field $dir $prestat_dir) + ) +) + +;; Information about a pre-opened capability. +(typename $prestat_t + (struct + ;; The type of the pre-opened capability. + (field $pr_type $preopentype_t) + ;; The contents of the information. + (field $u $prestat_u) + ) +) diff --git a/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx new file mode 100644 index 000000000..08efc87fa --- /dev/null +++ b/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx @@ -0,0 +1,526 @@ +;; WASI Preview. This is an evolution of the API that WASI initially +;; launched with. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_unstable_preview0 + ;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;; Read command-line argument data. + ;; The size of the array should match that returned by `wasi_args_sizes_get()` + (@interface func (export "args_get") + (param $argv (@witx pointer (@witx pointer u8))) + (param $argv_buf (@witx pointer u8)) + (result $error $errno_t) + ) + ;; Return command-line argument data sizes. + (@interface func (export "args_sizes_get") + (result $error $errno_t) + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Read environment variable data. + ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + (@interface func (export "environ_get") + (param $environ (@witx pointer (@witx pointer u8))) + (param $environ_buf (@witx pointer u8)) + (result $error $errno_t) + ) + ;; Return command-line argument data sizes. + (@interface func (export "environ_sizes_get") + ;; The number of arguments. + (result $argc $size_t) + ;; The size of the argument string data. + (result $argv_buf_size $size_t) + ) + + ;; Return the resolution of a clock. + ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;; Note: This is similar to `clock_getres` in POSIX. + (@interface func (export "clock_res_get") + (result $error $errno_t) + ;; The clock for which to return the resolution. + (param $clock_id $clockid_t) + ;; The resolution of the clock. + (result $resolution $timestamp_t) + ) + ;; Return the time value of a clock. + ;; Note: This is similar to `clock_gettime` in POSIX. + (@interface func (export "clock_time_get") + ;; The clock for which to return the time. + (param $clock_id $clockid_t) + ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp_t) + (result $error $errno_t) + ;; The time value of the clock. + (result $time $timestamp_t) + ) + + ;; Provide file advisory information on a file descriptor. + ;; Note: This is similar to `posix_fadvise` in POSIX. + (@interface func (export "fd_advise") + (param $fd $fd_t) + (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. + (param $len $filesize_t) ;; The length of the region to which the advisory applies. + (param $advice $advice_t) ;; The advice. + (result $error $errno_t) + ) + + ;; Force the allocation of space in a file. + ;; Note: This is similar to `posix_fallocate` in POSIX. + (@interface func (export "fd_allocate") + (param $fd $fd_t) + ;; The offset at which to start the allocation. + (param $offset $filesize_t) + ;; The length of the area that is allocated. + (param $len $filesize_t) + (result $error $errno_t) + ) + + ;; Close a file descriptor. + ;; Note: This is similar to `close` in POSIX. + (@interface func (export "fd_close") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Synchronize the data of a file to disk. + ;; Note: This is similar to `fdatasync` in POSIX. + (@interface func (export "fd_datasync") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Get the attributes of a file descriptor. + ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (@interface func (export "fd_fdstat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the file descriptor's attributes are stored. + (result $stat $fdstat_t) + ) + + ;; Adjust the flags associated with a file descriptor. + ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (@interface func (export "fd_fdstat_set_flags") + (param $fd $fd_t) + ;; The desired values of the file descriptor flags. + (param $flags $fdflags_t) + (result $error $errno_t) + ) + + ;; Adjust the rights associated with a file descriptor. + ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (@interface func (export "fd_fdstat_set_rights") + (param $fd $fd_t) + ;; The desired rights of the file descriptor. + (param $fs_rights_base $rights_t) + (param $fs_rights_inheriting $rights_t) + (result $error $errno_t) + ) + + ;; Return the attributes of an open file. + (@interface func (export "fd_filestat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $fs_rights_base $rights_t) + ) + + ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;; Note: This is similar to `ftruncate` in POSIX. + (@interface func (export "fd_filestat_set_size") + (param $fd $fd_t) + ;; The desired file size. + (param $st_size $filesize_t) + (result $error $errno_t) + ) + + ;; Adjust the timestamps of an open file or directory. + ;; Note: This is similar to `futimens` in POSIX. + (@interface func (export "fd_filestat_set_times") + (param $fd $fd_t) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `preadv` in POSIX. + (@interface func (export "fd_pread") + (param $fd $fd_t) + ;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_t_array) + ;; The offset within the file at which to read. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_get") + (param $fd $fd_t) + (result $error $errno_t) + ;; The buffer where the description is stored. + (result $buf $prestat_t) + ) + + ;; Return a description of the given preopened file descriptor. + (@interface func (export "fd_prestat_dir_name") + (param $fd $fd_t) + ;; A buffer into which to write the preopened directory name. + (param $path (@witx pointer u8)) + (param $path_len $size_t) + (result $error $errno_t) + ) + + ;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;; Note: This is similar to `pwritev` in POSIX. + (@interface func (export "fd_pwrite") + (param $fd $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_t_array) + ;; The offset within the file at which to write. + (param $offset $filesize_t) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Read from a file descriptor. + ;; Note: This is similar to `readv` in POSIX. + (@interface func (export "fd_read") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_t_array) + (result $error $errno_t) + ;; The number of bytes read. + (result $nread $size_t) + ) + + ;; Read directory entries from a directory. + ;; When successful, the contents of the output buffer consist of a sequence of + ;; directory entries. Each directory entry consists of a dirent_t object, + ;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;; entry. + ;; + ;; This function fills the output buffer as much as possible, potentially + ;; truncating the last directory entry. This allows the caller to grow its + ;; read buffer size in case it's too small to fit a single large directory + ;; entry, or skip the oversized directory entry. + (@interface func (export "fd_readdir") + (param $fd $fd_t) + ;; The buffer where directory entries are stored + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + ;; The location within the directory to start reading + (param $cookie $dircookie_t) + (result $error $errno_t) + ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size_t) + ) + + ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; + ;; Due to the strong focus on thread safety, this environment does not provide + ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;; file descriptor with the same number could be allocated by a different + ;; thread at the same time. + ;; + ;; This function provides a way to atomically renumber file descriptors, which + ;; would disappear if `dup2()` were to be removed entirely. + (@interface func (export "fd_renumber") + (param $fd $fd_t) + ;; The file descriptor to overwrite. + (param $to $fd_t) + (result $error $errno_t) + ) + + ;; Move the offset of a file descriptor. + ;; Note: This is similar to `lseek` in POSIX. + (@interface func (export "fd_seek") + (param $fd $fd_t) + ;; The number of bytes to move. + (param $offset $filedelta_t) + ;; The base from which the offset is relative. + (param $whence $whence_t) + (result $error $errno_t) + ;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize_t) + ) + + ;; Synchronize the data and metadata of a file to disk. + ;; Note: This is similar to `fsync` in POSIX. + (@interface func (export "fd_sync") + (param $fd $fd_t) + (result $error $errno_t) + ) + + ;; Return the current offset of a file descriptor. + ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (@interface func (export "fd_tell") + (param $fd $fd_t) + (result $error $errno_t) + ;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize_t) + ) + + ;; Write to a file descriptor. + ;; Note: This is similar to `writev` in POSIX. + (@interface func (export "fd_write") + (param $fd $fd_t) + ;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_t_array) + (result $error $errno_t) + ;; The number of bytes written. + (result $nwritten $size_t) + ) + + ;; Create a directory. + ;; Note: This is similar to `mkdirat` in POSIX. + (@interface func (export "path_create_directory") + (param $fd $fd_t) + ;; The path at which to create the directory. + (param $path string) + (result $error $errno_t) + ) + + ;; Return the attributes of a file or directory. + ;; Note: This is similar to `stat` in POSIX. + (@interface func (export "path_filestat_get") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno_t) + ;; The buffer where the file's attributes are stored. + (result $buf $filestat_t) + ) + + ;; Adjust the timestamps of a file or directory. + ;; Note: This is similar to `utimensat` in POSIX. + (@interface func (export "path_filestat_set_times") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags_t) + ;; The path of the file or directory to operate on. + (param $path string) + ;; The desired values of the data access timestamp. + (param $st_atim $timestamp_t) + ;; The desired values of the data modification timestamp. + (param $st_mtim $timestamp_t) + ;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags_t) + (result $error $errno_t) + ) + + ;; Create a hard link. + ;; Note: This is similar to `linkat` in POSIX. + (@interface func (export "path_link") + (param $old_fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags_t) + ;; The source path from which to link. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd_t) + ;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Open a file or directory. + ;; + ;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;; file descriptor not currently open; it is randomized to prevent + ;; applications from depending on making assumptions about indexes, since this + ;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;; guaranteed to be less than 2**31. + ;; + ;; Note: This is similar to `openat` in POSIX. + (@interface func (export "path_open") + (param $fd $fd_t) + ;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags_t) + ;; The relative path of the file or directory to open, relative to the + ;; `dirfd` directory. + (param $path string) + ;; The method by which to open the file. + (param $o_flags $oflags_t) + ;; The initial rights of the newly created file descriptor. The + ;; implementation is allowed to return a file descriptor with fewer rights + ;; than specified, if and only if those rights do not apply to the type of + ;; file being opened. + ;; + ;; The base rights are rights that will apply to operations using the file + ;; descriptor itself, while the inheriting rights are rights that apply to + ;; file descriptors derived from it. + (param $fs_rights_base $rights_t) + (param $fs_rights_inherting $rights_t) + (result $error $errno_t) + ;; The file descriptor of the file that has been opened. + (result $opened_fd $fd_t) + ) + + ;; Read the contents of a symbolic link. + ;; Note: This is similar to `readlinkat` in POSIX. + (@interface func (export "path_readlink") + (param $fd $fd_t) + ;; The path of the symbolic link from which to read. + (param $path string) + ;; The buffer to which to write the contents of the symbolic link. + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + (result $error $errno_t) + ;; The number of bytes placed in the buffer. + (result $bufused $size_t) + ) + + ;; Remove a directory. + ;; Return `ENOTEMPTY` if the directory is not empty. + ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (@interface func (export "path_remove_directory") + (param $fd $fd_t) + ;; The path to a directory to remove. + (param $path string) + (result $error $errno_t) + ) + + ;; Rename a file or directory. + ;; Note: This is similar to `renameat` in POSIX. + (@interface func (export "path_rename") + (param $fd $fd_t) + ;; The source path of the file or directory to rename. + (param $old_path string) + ;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd_t) + ;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno_t) + ) + + ;; Create a symbolic link. + ;; Note: This is similar to `symlinkat` in POSIX. + (@interface func (export "path_symlink") + (param $fd $fd_t) + ;; The contents of the symbolic link. + (param $old_path string) + ;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno_t) + ) + + + ;; Unlink a file. + ;; Return `EISDIR` if the path refers to a directory. + ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (@interface func (export "path_unlink_file") + (param $fd $fd_t) + ;; The path to a file to unlink. + (param $path string) + (result $error $errno_t) + ) + + ;; Concurrently poll for the occurrence of a set of events. + (@interface func (export "poll_oneoff") + ;; The events to which to subscribe. + (param $in (@witx const_pointer $subscription_t)) + ;; The events that have occurred. + (param $out (@witx pointer $event_t)) + ;; Both the number of subscriptions and events. + (param $nsubscriptions $size_t) + (result $error $errno_t) + ;; The number of events stored. + (result $nevents $size_t) + ) + + ;; Terminate the process normally. An exit code of 0 indicates successful + ;; termination of the program. The meanings of other values is dependent on + ;; the environment. + (@interface func (export "proc_exit") + ;; The exit code returned by the process. + (param $rval $exitcode_t) + ) + + ;; Send a signal to the process of the calling thread. + ;; Note: This is similar to `raise` in POSIX. + (@interface func (export "proc_raise") + ;; The signal condition to trigger. + (param $sig $signal_t) + (result $error $errno_t) + ) + + ;; Temporarily yield execution of the calling thread. + ;; Note: This is similar to `sched_yield` in POSIX. + (@interface func (export "proc_sched_yield") + (result $error $errno_t) + ) + + ;; Write high-quality random data into a buffer. + ;; This function blocks when the implementation is unable to immediately + ;; provide sufficient high-quality random data. + ;; This function may execute slowly, so when large mounts of random data are + ;; required, it's advisable to use this function to seed a pseudo-random + ;; number generator, rather than to provide the random data directly. + (@interface func (export "random_get") + ;; The buffer to fill with random data. + (param $buf (@witx pointer u8)) + (param $buf_len $size_t) + (result $error $errno_t) + ) + + ;; Receive a message from a socket. + ;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;; the data into multiple buffers in the manner of `readv`. + (@interface func (export "sock_recv") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_t_array) + ;; Message flags. + (param $ri_flags $riflags_t) + (result $error $errno_t) + ;; Number of bytes stored in ri_data. + (result $ro_datalen $size_t) + ;; Message flags. + (result $ro_flags $roflags_t) + ) + + ;; Send a message on a socket. + ;; Note: This is similar to `send` in POSIX, though it also supports writing + ;; the data from multiple buffers in the manner of `writev`. + (@interface func (export "sock_send") + (param $fd $fd_t) + ;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_t_array) + ;; Message flags. + (param $si_flags $siflags_t) + (result $error $errno_t) + ;; Number of bytes transmitted. + (result $so_datalen $size_t) + ) + + ;; Shut down socket send and receive channels. + ;; Note: This is similar to `shutdown` in POSIX. + (@interface func (export "sock_shutdown") + (param $fd $fd_t) + ;; Which channels on the socket to shut down. + (param $how $sdflags_t) + (result $error $errno_t) + ) +) From 78dbd5b34d896bfa2086866dbe7076c4d1b2c142 Mon Sep 17 00:00:00 2001 From: Leon Wang Date: Thu, 19 Sep 2019 11:05:52 +0800 Subject: [PATCH 0169/1772] Fix a format error in phases module (#93) --- proposals/clocks/phases/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/phases/README.md b/proposals/clocks/phases/README.md index 00d49afef..53cb649bb 100644 --- a/proposals/clocks/phases/README.md +++ b/proposals/clocks/phases/README.md @@ -18,7 +18,7 @@ that: - Move any superseded files out of `unstable` into `old`. - Optionally add polyfills for superseded APIs using `unstable` APIs. - - Move all files supporting the APIs out of `ephemeral into `unstable`. + - Move all files supporting the APIs out of `ephemeral` into `unstable`. - Rename the API modules from `wasi_ephemeral_` to `wasi_unstable_` and append a version number. From 431506fe0c6e64697578bd950f74017880c5a70a Mon Sep 17 00:00:00 2001 From: Leon Wang Date: Thu, 19 Sep 2019 11:05:52 +0800 Subject: [PATCH 0170/1772] Fix a format error in phases module (#93) --- proposals/random/phases/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/phases/README.md b/proposals/random/phases/README.md index 00d49afef..53cb649bb 100644 --- a/proposals/random/phases/README.md +++ b/proposals/random/phases/README.md @@ -18,7 +18,7 @@ that: - Move any superseded files out of `unstable` into `old`. - Optionally add polyfills for superseded APIs using `unstable` APIs. - - Move all files supporting the APIs out of `ephemeral into `unstable`. + - Move all files supporting the APIs out of `ephemeral` into `unstable`. - Rename the API modules from `wasi_ephemeral_` to `wasi_unstable_` and append a version number. From dd2375a467715c18f2fa884eba672ec73f148053 Mon Sep 17 00:00:00 2001 From: Leon Wang Date: Thu, 19 Sep 2019 11:05:52 +0800 Subject: [PATCH 0171/1772] Fix a format error in phases module (#93) --- proposals/filesystem/phases/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/phases/README.md b/proposals/filesystem/phases/README.md index 00d49afef..53cb649bb 100644 --- a/proposals/filesystem/phases/README.md +++ b/proposals/filesystem/phases/README.md @@ -18,7 +18,7 @@ that: - Move any superseded files out of `unstable` into `old`. - Optionally add polyfills for superseded APIs using `unstable` APIs. - - Move all files supporting the APIs out of `ephemeral into `unstable`. + - Move all files supporting the APIs out of `ephemeral` into `unstable`. - Rename the API modules from `wasi_ephemeral_` to `wasi_unstable_` and append a version number. From f500326673a3f776a344bff6d862e28e205a4b0b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 20 Sep 2019 19:44:31 -0500 Subject: [PATCH 0172/1772] Add GitHub Actions CI (#95) --- proposals/clocks/.github/workflows/main.yml | 36 +++++++++++++++++++ .../clocks/tools/witx/tests/wasi_unstable.rs | 6 ++-- 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 proposals/clocks/.github/workflows/main.yml diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml new file mode 100644 index 000000000..434ba393d --- /dev/null +++ b/proposals/clocks/.github/workflows/main.yml @@ -0,0 +1,36 @@ +name: CI +on: [push, pull_request] + +jobs: + test: + name: Test + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + steps: + - uses: actions/checkout@master + - name: Install Rust (rustup) + run: rustup update stable --no-self-update && rustup default stable + if: matrix.os != 'macos-latest' + - name: Install Rust (macos) + run: | + curl https://sh.rustup.rs | sh -s -- -y + echo "##[add-path]$HOME/.cargo/bin" + if: matrix.os == 'macos-latest' + - run: cargo fetch + working-directory: tools/witx + - run: cargo build + working-directory: tools/witx + - run: cargo test + working-directory: tools/witx + + rustfmt: + name: Rustfmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Install Rust + run: rustup update stable && rustup default stable && rustup component add rustfmt + - run: cargo fmt -- --check + working-directory: tools/witx diff --git a/proposals/clocks/tools/witx/tests/wasi_unstable.rs b/proposals/clocks/tools/witx/tests/wasi_unstable.rs index e9188db67..a12619955 100644 --- a/proposals/clocks/tools/witx/tests/wasi_unstable.rs +++ b/proposals/clocks/tools/witx/tests/wasi_unstable.rs @@ -1,7 +1,9 @@ use std::path::Path; -use witx_frontend; #[test] fn validate_wasi_unstable() { - witx_frontend::load(Path::new("../../design/wasi_unstable/wasi_unstable.witx")).unwrap(); + witx::load(Path::new( + "../../phases/unstable/witx/wasi_unstable_preview0.witx", + )) + .unwrap(); } From 279db3c9b330551ab7f51b5e9451c5b0981fbbb0 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 20 Sep 2019 19:44:31 -0500 Subject: [PATCH 0173/1772] Add GitHub Actions CI (#95) --- proposals/random/.github/workflows/main.yml | 36 +++++++++++++++++++ .../random/tools/witx/tests/wasi_unstable.rs | 6 ++-- 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 proposals/random/.github/workflows/main.yml diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml new file mode 100644 index 000000000..434ba393d --- /dev/null +++ b/proposals/random/.github/workflows/main.yml @@ -0,0 +1,36 @@ +name: CI +on: [push, pull_request] + +jobs: + test: + name: Test + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + steps: + - uses: actions/checkout@master + - name: Install Rust (rustup) + run: rustup update stable --no-self-update && rustup default stable + if: matrix.os != 'macos-latest' + - name: Install Rust (macos) + run: | + curl https://sh.rustup.rs | sh -s -- -y + echo "##[add-path]$HOME/.cargo/bin" + if: matrix.os == 'macos-latest' + - run: cargo fetch + working-directory: tools/witx + - run: cargo build + working-directory: tools/witx + - run: cargo test + working-directory: tools/witx + + rustfmt: + name: Rustfmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Install Rust + run: rustup update stable && rustup default stable && rustup component add rustfmt + - run: cargo fmt -- --check + working-directory: tools/witx diff --git a/proposals/random/tools/witx/tests/wasi_unstable.rs b/proposals/random/tools/witx/tests/wasi_unstable.rs index e9188db67..a12619955 100644 --- a/proposals/random/tools/witx/tests/wasi_unstable.rs +++ b/proposals/random/tools/witx/tests/wasi_unstable.rs @@ -1,7 +1,9 @@ use std::path::Path; -use witx_frontend; #[test] fn validate_wasi_unstable() { - witx_frontend::load(Path::new("../../design/wasi_unstable/wasi_unstable.witx")).unwrap(); + witx::load(Path::new( + "../../phases/unstable/witx/wasi_unstable_preview0.witx", + )) + .unwrap(); } From b1d9966c197780210369658ff65e16d1f8f55c7b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 20 Sep 2019 19:44:31 -0500 Subject: [PATCH 0174/1772] Add GitHub Actions CI (#95) --- .../filesystem/.github/workflows/main.yml | 36 +++++++++++++++++++ .../tools/witx/tests/wasi_unstable.rs | 6 ++-- 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 proposals/filesystem/.github/workflows/main.yml diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml new file mode 100644 index 000000000..434ba393d --- /dev/null +++ b/proposals/filesystem/.github/workflows/main.yml @@ -0,0 +1,36 @@ +name: CI +on: [push, pull_request] + +jobs: + test: + name: Test + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + steps: + - uses: actions/checkout@master + - name: Install Rust (rustup) + run: rustup update stable --no-self-update && rustup default stable + if: matrix.os != 'macos-latest' + - name: Install Rust (macos) + run: | + curl https://sh.rustup.rs | sh -s -- -y + echo "##[add-path]$HOME/.cargo/bin" + if: matrix.os == 'macos-latest' + - run: cargo fetch + working-directory: tools/witx + - run: cargo build + working-directory: tools/witx + - run: cargo test + working-directory: tools/witx + + rustfmt: + name: Rustfmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Install Rust + run: rustup update stable && rustup default stable && rustup component add rustfmt + - run: cargo fmt -- --check + working-directory: tools/witx diff --git a/proposals/filesystem/tools/witx/tests/wasi_unstable.rs b/proposals/filesystem/tools/witx/tests/wasi_unstable.rs index e9188db67..a12619955 100644 --- a/proposals/filesystem/tools/witx/tests/wasi_unstable.rs +++ b/proposals/filesystem/tools/witx/tests/wasi_unstable.rs @@ -1,7 +1,9 @@ use std::path::Path; -use witx_frontend; #[test] fn validate_wasi_unstable() { - witx_frontend::load(Path::new("../../design/wasi_unstable/wasi_unstable.witx")).unwrap(); + witx::load(Path::new( + "../../phases/unstable/witx/wasi_unstable_preview0.witx", + )) + .unwrap(); } From 0c8273548ec0ffed7dd1a57bf45370b093e5c432 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 23 Sep 2019 15:08:37 -0700 Subject: [PATCH 0175/1772] Fix the name of `wasi_ephemeral_preview0` and update tests. (#92) `wasi_ephemeral_preview0` is meant to be versioned, so that it can be superceded by new versions in the future. Also, update the witx testsuite to test all the current witx files. --- ...preview.witx => wasi_ephemeral_preview0.witx} | 2 +- .../clocks/tools/witx/tests/wasi_unstable.rs | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) rename proposals/clocks/phases/ephemeral/witx/{wasi_ephemeral_preview.witx => wasi_ephemeral_preview0.witx} (99%) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview0.witx similarity index 99% rename from proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx rename to proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview0.witx index 4f31fe510..2c85e5e69 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview0.witx @@ -8,7 +8,7 @@ (use "typenames.witx") -(module $wasi_ephemeral_preview +(module $wasi_ephemeral_preview0 ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) diff --git a/proposals/clocks/tools/witx/tests/wasi_unstable.rs b/proposals/clocks/tools/witx/tests/wasi_unstable.rs index a12619955..6e196cb4a 100644 --- a/proposals/clocks/tools/witx/tests/wasi_unstable.rs +++ b/proposals/clocks/tools/witx/tests/wasi_unstable.rs @@ -1,9 +1,23 @@ use std::path::Path; +use witx; #[test] -fn validate_wasi_unstable() { +fn validate_wasi_unstable_preview0() { witx::load(Path::new( "../../phases/unstable/witx/wasi_unstable_preview0.witx", )) .unwrap(); } + +#[test] +fn validate_wasi_ephemeral_preview0() { + witx::load(Path::new( + "../../phases/ephemeral/witx/wasi_ephemeral_preview0.witx", + )) + .unwrap(); +} + +#[test] +fn validate_wasi_old_preview0() { + witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")).unwrap(); +} From 96e8123a2ea0aa56c22e5ec141cbb5c5e23c2b71 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 23 Sep 2019 15:08:37 -0700 Subject: [PATCH 0176/1772] Fix the name of `wasi_ephemeral_preview0` and update tests. (#92) `wasi_ephemeral_preview0` is meant to be versioned, so that it can be superceded by new versions in the future. Also, update the witx testsuite to test all the current witx files. --- ...preview.witx => wasi_ephemeral_preview0.witx} | 2 +- .../random/tools/witx/tests/wasi_unstable.rs | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) rename proposals/random/phases/ephemeral/witx/{wasi_ephemeral_preview.witx => wasi_ephemeral_preview0.witx} (99%) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview0.witx similarity index 99% rename from proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx rename to proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview0.witx index 4f31fe510..2c85e5e69 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview0.witx @@ -8,7 +8,7 @@ (use "typenames.witx") -(module $wasi_ephemeral_preview +(module $wasi_ephemeral_preview0 ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) diff --git a/proposals/random/tools/witx/tests/wasi_unstable.rs b/proposals/random/tools/witx/tests/wasi_unstable.rs index a12619955..6e196cb4a 100644 --- a/proposals/random/tools/witx/tests/wasi_unstable.rs +++ b/proposals/random/tools/witx/tests/wasi_unstable.rs @@ -1,9 +1,23 @@ use std::path::Path; +use witx; #[test] -fn validate_wasi_unstable() { +fn validate_wasi_unstable_preview0() { witx::load(Path::new( "../../phases/unstable/witx/wasi_unstable_preview0.witx", )) .unwrap(); } + +#[test] +fn validate_wasi_ephemeral_preview0() { + witx::load(Path::new( + "../../phases/ephemeral/witx/wasi_ephemeral_preview0.witx", + )) + .unwrap(); +} + +#[test] +fn validate_wasi_old_preview0() { + witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")).unwrap(); +} From f8fae2cdea780b312d43adcae04b500d4a909a6a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 23 Sep 2019 15:08:37 -0700 Subject: [PATCH 0177/1772] Fix the name of `wasi_ephemeral_preview0` and update tests. (#92) `wasi_ephemeral_preview0` is meant to be versioned, so that it can be superceded by new versions in the future. Also, update the witx testsuite to test all the current witx files. --- ...preview.witx => wasi_ephemeral_preview0.witx} | 2 +- .../filesystem/tools/witx/tests/wasi_unstable.rs | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) rename proposals/filesystem/phases/ephemeral/witx/{wasi_ephemeral_preview.witx => wasi_ephemeral_preview0.witx} (99%) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview0.witx similarity index 99% rename from proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx rename to proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview0.witx index 4f31fe510..2c85e5e69 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview0.witx @@ -8,7 +8,7 @@ (use "typenames.witx") -(module $wasi_ephemeral_preview +(module $wasi_ephemeral_preview0 ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) diff --git a/proposals/filesystem/tools/witx/tests/wasi_unstable.rs b/proposals/filesystem/tools/witx/tests/wasi_unstable.rs index a12619955..6e196cb4a 100644 --- a/proposals/filesystem/tools/witx/tests/wasi_unstable.rs +++ b/proposals/filesystem/tools/witx/tests/wasi_unstable.rs @@ -1,9 +1,23 @@ use std::path::Path; +use witx; #[test] -fn validate_wasi_unstable() { +fn validate_wasi_unstable_preview0() { witx::load(Path::new( "../../phases/unstable/witx/wasi_unstable_preview0.witx", )) .unwrap(); } + +#[test] +fn validate_wasi_ephemeral_preview0() { + witx::load(Path::new( + "../../phases/ephemeral/witx/wasi_ephemeral_preview0.witx", + )) + .unwrap(); +} + +#[test] +fn validate_wasi_old_preview0() { + witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")).unwrap(); +} From dfd2d137a0e132f7b03d1af99bc2d428f5691b36 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 26 Sep 2019 00:33:22 -0700 Subject: [PATCH 0178/1772] Add an agenda for 09-26. (#99) --- proposals/clocks/meetings/2019/WASI-09-26.md | 37 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 38 insertions(+) create mode 100644 proposals/clocks/meetings/2019/WASI-09-26.md diff --git a/proposals/clocks/meetings/2019/WASI-09-26.md b/proposals/clocks/meetings/2019/WASI-09-26.md new file mode 100644 index 000000000..2534b24a3 --- /dev/null +++ b/proposals/clocks/meetings/2019/WASI-09-26.md @@ -0,0 +1,37 @@ +![WASI logo](/WASI.png) + +## Agenda for the September 26 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: September 26, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Initial WASI modularization draft + - https://github.com/WebAssembly/WASI/pull/98 + +1. Closure + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 4b0b34506..6d5887075 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -16,3 +16,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI August 15th video call](2019/WASI-08-15.md) * [WASI August 30th video call](2019/WASI-08-30.md) * [WASI September 12th video call](2019/WASI-09-12.md) + * [WASI September 25th video call](2019/WASI-09-25.md) From 60365e965811c7f0342965473c68b0e7c6255c54 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 26 Sep 2019 00:33:22 -0700 Subject: [PATCH 0179/1772] Add an agenda for 09-26. (#99) --- proposals/random/meetings/2019/WASI-09-26.md | 37 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 38 insertions(+) create mode 100644 proposals/random/meetings/2019/WASI-09-26.md diff --git a/proposals/random/meetings/2019/WASI-09-26.md b/proposals/random/meetings/2019/WASI-09-26.md new file mode 100644 index 000000000..2534b24a3 --- /dev/null +++ b/proposals/random/meetings/2019/WASI-09-26.md @@ -0,0 +1,37 @@ +![WASI logo](/WASI.png) + +## Agenda for the September 26 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: September 26, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Initial WASI modularization draft + - https://github.com/WebAssembly/WASI/pull/98 + +1. Closure + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 4b0b34506..6d5887075 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -16,3 +16,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI August 15th video call](2019/WASI-08-15.md) * [WASI August 30th video call](2019/WASI-08-30.md) * [WASI September 12th video call](2019/WASI-09-12.md) + * [WASI September 25th video call](2019/WASI-09-25.md) From e91d17020ccb3fee4b4cac5399100dd14666ee2e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 26 Sep 2019 00:33:22 -0700 Subject: [PATCH 0180/1772] Add an agenda for 09-26. (#99) --- .../filesystem/meetings/2019/WASI-09-26.md | 37 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 38 insertions(+) create mode 100644 proposals/filesystem/meetings/2019/WASI-09-26.md diff --git a/proposals/filesystem/meetings/2019/WASI-09-26.md b/proposals/filesystem/meetings/2019/WASI-09-26.md new file mode 100644 index 000000000..2534b24a3 --- /dev/null +++ b/proposals/filesystem/meetings/2019/WASI-09-26.md @@ -0,0 +1,37 @@ +![WASI logo](/WASI.png) + +## Agenda for the September 26 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: September 26, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Initial WASI modularization draft + - https://github.com/WebAssembly/WASI/pull/98 + +1. Closure + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 4b0b34506..6d5887075 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -16,3 +16,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI August 15th video call](2019/WASI-08-15.md) * [WASI August 30th video call](2019/WASI-08-30.md) * [WASI September 12th video call](2019/WASI-09-12.md) + * [WASI September 25th video call](2019/WASI-09-25.md) From efc4d9c6c6c0b55a8c7ce1fbf468bafbda3f2ef6 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 26 Sep 2019 16:17:20 -0700 Subject: [PATCH 0181/1772] witx crate: improve public API (#96) * witx tool: improve public api so you don't have to know about internal invariants the definitions/entries pattern involves upgrading Weak into Rc and also its not super intuitive, especially given ive written zero (0) docs. This is a bit nicer to use * witx: add render trait, make sure it roundtrips by implementing Eq * witx crate: IntRepr variants are U8, U16... to reflect syntax as "u8"... * witx crate: doc comments --- proposals/clocks/tools/witx/src/ast.rs | 173 ++++++++++-- proposals/clocks/tools/witx/src/io.rs | 91 ++++++ proposals/clocks/tools/witx/src/lib.rs | 51 ++-- proposals/clocks/tools/witx/src/parser.rs | 10 +- proposals/clocks/tools/witx/src/render.rs | 266 ++++++++++++++++++ proposals/clocks/tools/witx/src/sexpr.rs | 10 +- proposals/clocks/tools/witx/src/toplevel.rs | 74 +---- proposals/clocks/tools/witx/src/validate.rs | 35 +-- .../clocks/tools/witx/tests/wasi_unstable.rs | 16 ++ 9 files changed, 601 insertions(+), 125 deletions(-) create mode 100644 proposals/clocks/tools/witx/src/io.rs create mode 100644 proposals/clocks/tools/witx/src/render.rs diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 4df4d1e24..3713b3dd9 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -18,10 +18,71 @@ impl Id { #[derive(Debug, Clone)] pub struct Document { - pub definitions: Vec, - pub entries: HashMap, + definitions: Vec, + entries: HashMap, } +impl Document { + pub(crate) fn new(definitions: Vec, entries: HashMap) -> Self { + Document { + definitions, + entries, + } + } + pub fn datatype(&self, name: &Id) -> Option> { + self.entries.get(name).and_then(|e| match e { + Entry::Datatype(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + _ => None, + }) + } + pub fn datatypes<'a>(&'a self) -> impl Iterator> + 'a { + self.definitions.iter().filter_map(|d| match d { + Definition::Datatype(d) => Some(d.clone()), + _ => None, + }) + } + pub fn module(&self, name: &Id) -> Option> { + self.entries.get(&name).and_then(|e| match e { + Entry::Module(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + _ => None, + }) + } + pub fn modules<'a>(&'a self) -> impl Iterator> + 'a { + self.definitions.iter().filter_map(|d| match d { + Definition::Module(d) => Some(d.clone()), + _ => None, + }) + } +} + +impl PartialEq for Document { + fn eq(&self, rhs: &Document) -> bool { + if self.definitions.len() != rhs.definitions.len() { + return false; + } + for d in self.datatypes() { + if let Some(d_rhs) = rhs.datatype(&d.name) { + if d != d_rhs { + return false; + } + } else { + return false; + } + } + for m in self.modules() { + if let Some(m_rhs) = rhs.module(&m.name) { + if m != m_rhs { + return false; + } + } else { + return false; + } + } + true + } +} +impl Eq for Document {} + #[derive(Debug, Clone)] pub enum Definition { Datatype(Rc), @@ -43,7 +104,7 @@ impl Entry { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum DatatypeIdent { Builtin(BuiltinType), Array(Box), @@ -52,13 +113,13 @@ pub enum DatatypeIdent { Ident(Rc), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Datatype { pub name: Id, pub variant: DatatypeVariant, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum DatatypeVariant { Alias(AliasDatatype), Enum(EnumDatatype), @@ -67,53 +128,53 @@ pub enum DatatypeVariant { Union(UnionDatatype), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct AliasDatatype { pub name: Id, pub to: DatatypeIdent, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum IntRepr { - I8, - I16, - I32, - I64, + U8, + U16, + U32, + U64, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumDatatype { pub name: Id, pub repr: IntRepr, pub variants: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsDatatype { pub name: Id, pub repr: IntRepr, pub flags: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct StructDatatype { pub name: Id, pub members: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct StructMember { pub name: Id, pub type_: DatatypeIdent, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionDatatype { pub name: Id, pub variants: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionVariant { pub name: Id, pub type_: DatatypeIdent, @@ -122,10 +183,76 @@ pub struct UnionVariant { #[derive(Debug, Clone)] pub struct Module { pub name: Id, - pub definitions: Vec, - pub entries: HashMap, + definitions: Vec, + entries: HashMap, +} + +impl Module { + pub(crate) fn new( + name: Id, + definitions: Vec, + entries: HashMap, + ) -> Self { + Module { + name, + definitions, + entries, + } + } + pub fn import(&self, name: &Id) -> Option> { + self.entries.get(name).and_then(|e| match e { + ModuleEntry::Import(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + _ => None, + }) + } + pub fn imports<'a>(&'a self) -> impl Iterator> + 'a { + self.definitions.iter().filter_map(|d| match d { + ModuleDefinition::Import(d) => Some(d.clone()), + _ => None, + }) + } + pub fn func(&self, name: &Id) -> Option> { + self.entries.get(name).and_then(|e| match e { + ModuleEntry::Func(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + _ => None, + }) + } + pub fn funcs<'a>(&'a self) -> impl Iterator> + 'a { + self.definitions.iter().filter_map(|d| match d { + ModuleDefinition::Func(d) => Some(d.clone()), + _ => None, + }) + } } +impl PartialEq for Module { + fn eq(&self, rhs: &Module) -> bool { + if self.definitions.len() != rhs.definitions.len() { + return false; + } + for i in self.imports() { + if let Some(i_rhs) = rhs.import(&i.name) { + if i != i_rhs { + return false; + } + } else { + return false; + } + } + for f in self.funcs() { + if let Some(f_rhs) = rhs.func(&f.name) { + if f != f_rhs { + return false; + } + } else { + return false; + } + } + true + } +} +impl Eq for Module {} + #[derive(Debug, Clone)] pub enum ModuleDefinition { Import(Rc), @@ -138,25 +265,25 @@ pub enum ModuleEntry { Func(Weak), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ModuleImport { pub name: Id, pub variant: ModuleImportVariant, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum ModuleImportVariant { Memory, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct InterfaceFunc { pub name: Id, pub params: Vec, pub results: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct InterfaceFuncParam { pub name: Id, pub type_: DatatypeIdent, diff --git a/proposals/clocks/tools/witx/src/io.rs b/proposals/clocks/tools/witx/src/io.rs new file mode 100644 index 000000000..4f40d8947 --- /dev/null +++ b/proposals/clocks/tools/witx/src/io.rs @@ -0,0 +1,91 @@ +use crate::WitxError; +use std::collections::HashMap; +use std::fs::{read_to_string, File}; +use std::io::{BufRead, BufReader, Error, ErrorKind}; +use std::path::{Path, PathBuf}; + +pub trait WitxIo { + /// Read the entire file into a String. Used to resolve `use` declarations. + fn fgets(&self, path: &Path) -> Result; + /// Read a line of a file into a String. Used for error reporting. + fn fget_line(&self, path: &Path, line_num: usize) -> Result; + /// Return the canonical (non-symlinked) path of a file. Used to resolve `use` declarations. + fn canonicalize(&self, path: &Path) -> Result; +} + +pub struct Filesystem; + +impl WitxIo for Filesystem { + fn fgets(&self, path: &Path) -> Result { + read_to_string(path).map_err(|e| WitxError::Io(path.to_path_buf(), e)) + } + fn fget_line(&self, path: &Path, line_num: usize) -> Result { + let f = File::open(path).map_err(|e| WitxError::Io(path.into(), e))?; + let buf = BufReader::new(f); + let l = buf + .lines() + .skip(line_num - 1) + .next() + .ok_or_else(|| { + WitxError::Io(path.into(), Error::new(ErrorKind::Other, "Line not found")) + })? + .map_err(|e| WitxError::Io(path.into(), e))?; + + Ok(l) + } + fn canonicalize(&self, path: &Path) -> Result { + path.canonicalize() + .map_err(|e| WitxError::Io(path.to_path_buf(), e)) + } +} + +pub struct MockFs { + map: HashMap, +} + +impl MockFs { + pub fn new(strings: &[(&str, &str)]) -> Self { + MockFs { + map: strings + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + } + } +} + +impl WitxIo for MockFs { + fn fgets(&self, path: &Path) -> Result { + if let Some(entry) = self.map.get(path.to_str().unwrap()) { + Ok(entry.to_string()) + } else { + Err(WitxError::Io( + path.to_path_buf(), + Error::new(ErrorKind::Other, "mock fs: file not found"), + )) + } + } + fn fget_line(&self, path: &Path, line: usize) -> Result { + if let Some(entry) = self.map.get(path.to_str().unwrap()) { + entry + .lines() + .skip(line - 1) + .next() + .map(|s| s.to_string()) + .ok_or_else(|| { + WitxError::Io( + path.to_path_buf(), + Error::new(ErrorKind::Other, "mock fs: file not found"), + ) + }) + } else { + Err(WitxError::Io( + path.to_path_buf(), + Error::new(ErrorKind::Other, "mock fs: file not found"), + )) + } + } + fn canonicalize(&self, path: &Path) -> Result { + Ok(PathBuf::from(path)) + } +} diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 7d5040d00..34876cf7b 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -1,9 +1,13 @@ /// Types describing a validated witx document mod ast; +/// Interface for filesystem or mock IO +mod io; /// Lexer text into tokens mod lexer; /// Witx syntax parsing from SExprs mod parser; +/// Render ast to text +mod render; /// SExpr parsing from tokens mod sexpr; /// Resolve toplevel `use` declarations across files @@ -17,15 +21,17 @@ pub use ast::{ ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; +pub use io::{Filesystem, MockFs, WitxIo}; pub use lexer::LexError; pub use parser::{DeclSyntax, ParseError}; +pub use render::{Render, SExpr as RenderSExpr}; pub use sexpr::SExprParseError; pub use validate::ValidationError; use failure::Fail; -use std::io; use std::path::{Path, PathBuf}; +/// Load a witx document from the filesystem pub fn load>(path: P) -> Result { use toplevel::parse_witx; use validate::validate_document; @@ -33,6 +39,15 @@ pub fn load>(path: P) -> Result { validate_document(&parsed_decls).map_err(WitxError::Validation) } +/// Parse a witx document from a str. `(use ...)` directives are not permitted. +pub fn parse(source: &str) -> Result { + use toplevel::parse_witx_with; + use validate::validate_document; + let mockfs = MockFs::new(&[("-", source)]); + let parsed_decls = parse_witx_with(Path::new("-"), &mockfs)?; + validate_document(&parsed_decls).map_err(WitxError::Validation) +} + /// Location in the source text #[derive(Debug, PartialEq, Eq, Clone)] pub struct Location { @@ -45,8 +60,8 @@ pub struct Location { pub enum WitxError { #[fail(display = "{}", _0)] SExpr(#[cause] SExprParseError), - #[fail(display = "when resolving use declaration for {:?}: {}", _0, _1)] - UseResolution(PathBuf, #[cause] io::Error), + #[fail(display = "with file {:?}: {}", _0, _1)] + Io(PathBuf, #[cause] ::std::io::Error), #[fail(display = "{}", _0)] Parse(#[cause] ParseError), #[fail(display = "{}", _0)] @@ -54,20 +69,24 @@ pub enum WitxError { } impl WitxError { - pub fn report(&self) -> String { + pub fn report_with(&self, witxio: &dyn WitxIo) -> String { use WitxError::*; match self { - SExpr(sexpr) => sexpr.report(), - UseResolution(path, ioerr) => format!("when resolving `use {:?}`: {}", path, ioerr), - Parse(parse) => parse.report(), - Validation(validation) => validation.report(), + SExpr(sexpr) => sexpr.report_with(witxio), + Io(path, ioerr) => format!("with file {:?}: {}", path, ioerr), + Parse(parse) => parse.report_with(witxio), + Validation(validation) => validation.report_with(witxio), } } + pub fn report(&self) -> String { + self.report_with(&Filesystem) + } } + impl Location { - pub fn highlight_source(&self) -> String { + pub fn highlight_source_with(&self, witxio: &dyn WitxIo) -> String { let mut msg = format!("in {:?}:\n", self.path); - if let Ok(src_line) = self.source_line() { + if let Ok(src_line) = witxio.fget_line(&self.path, self.line) { msg += &format!( "{line_num: >5} | {src_line}\n{blank: >5} {caret: >column$}", line_num = self.line, @@ -79,15 +98,7 @@ impl Location { } msg } - pub fn source_line(&self) -> Result { - use std::fs::File; - use std::io::{BufRead, BufReader}; - let f = BufReader::new(File::open(&self.path)?); - let l = f - .lines() - .skip(self.line - 1) - .next() - .unwrap_or_else(|| Err(io::Error::new(io::ErrorKind::Other, "TODO")))?; - Ok(l) + pub fn highlight_source(&self) -> String { + self.highlight_source_with(&Filesystem) } } diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index a99df5fa4..1f627b27c 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -1,3 +1,4 @@ +use crate::io::{Filesystem, WitxIo}; use crate::sexpr::SExpr; use crate::Location; use failure::Fail; @@ -23,8 +24,15 @@ pub struct ParseError { } impl ParseError { + pub fn report_with(&self, witxio: &dyn WitxIo) -> String { + format!( + "{}\n{}", + self.location.highlight_source_with(witxio), + self.message + ) + } pub fn report(&self) -> String { - format!("{}\n{}", self.location.highlight_source(), self.message) + self.report_with(&Filesystem) } } diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs new file mode 100644 index 000000000..912d59508 --- /dev/null +++ b/proposals/clocks/tools/witx/src/render.rs @@ -0,0 +1,266 @@ +use crate::ast::*; +use std::fmt; + +impl fmt::Display for Document { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for d in self.datatypes() { + write!(f, "{}\n", d.to_sexpr())?; + } + for m in self.modules() { + write!(f, "{}\n", m.to_sexpr())?; + } + Ok(()) + } +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum SExpr { + Vec(Vec), + Word(String), + Ident(String), + Quote(String), + /// Short for Annotation + Annot(String), +} + +impl fmt::Display for SExpr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + SExpr::Vec(vs) => { + write!(f, "(")?; + let mut vss = Vec::new(); + for v in vs { + vss.push(format!("{}", v)); + } + f.write_str(&vss.join(" "))?; + write!(f, ")") + } + SExpr::Word(w) => write!(f, "{}", w), + SExpr::Ident(i) => write!(f, "${}", i), + SExpr::Quote(q) => write!(f, "\"{}\"", q), + SExpr::Annot(a) => write!(f, "@{}", a), + } + } +} + +impl SExpr { + fn word(s: &str) -> SExpr { + SExpr::Word(s.to_string()) + } + fn ident(s: &str) -> SExpr { + SExpr::Ident(s.to_string()) + } + fn quote(s: &str) -> SExpr { + SExpr::Quote(s.to_string()) + } + fn annot(s: &str) -> SExpr { + SExpr::Annot(s.to_string()) + } +} + +pub trait Render { + fn to_sexpr(&self) -> SExpr; +} + +impl Render for Id { + fn to_sexpr(&self) -> SExpr { + SExpr::ident(self.as_str()) + } +} + +impl Render for BuiltinType { + fn to_sexpr(&self) -> SExpr { + match self { + BuiltinType::String => SExpr::word("string"), + BuiltinType::Data => SExpr::word("data"), + BuiltinType::U8 => SExpr::word("u8"), + BuiltinType::U16 => SExpr::word("u16"), + BuiltinType::U32 => SExpr::word("u32"), + BuiltinType::U64 => SExpr::word("u64"), + BuiltinType::S8 => SExpr::word("s8"), + BuiltinType::S16 => SExpr::word("s16"), + BuiltinType::S32 => SExpr::word("s32"), + BuiltinType::S64 => SExpr::word("s64"), + BuiltinType::F32 => SExpr::word("f32"), + BuiltinType::F64 => SExpr::word("f64"), + } + } +} + +impl Render for DatatypeIdent { + fn to_sexpr(&self) -> SExpr { + match self { + DatatypeIdent::Builtin(b) => b.to_sexpr(), + DatatypeIdent::Array(a) => SExpr::Vec(vec![SExpr::word("array"), a.to_sexpr()]), + DatatypeIdent::Pointer(p) => SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("pointer"), + p.to_sexpr(), + ]), + DatatypeIdent::ConstPointer(p) => SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("const_pointer"), + p.to_sexpr(), + ]), + DatatypeIdent::Ident(i) => i.name.to_sexpr(), + } + } +} + +impl Render for Datatype { + fn to_sexpr(&self) -> SExpr { + let name = self.name.to_sexpr(); + let body = self.variant.to_sexpr(); + SExpr::Vec(vec![SExpr::word("typename"), name, body]) + } +} + +impl Render for DatatypeVariant { + fn to_sexpr(&self) -> SExpr { + match self { + DatatypeVariant::Alias(a) => a.to_sexpr(), + DatatypeVariant::Enum(a) => a.to_sexpr(), + DatatypeVariant::Flags(a) => a.to_sexpr(), + DatatypeVariant::Struct(a) => a.to_sexpr(), + DatatypeVariant::Union(a) => a.to_sexpr(), + } + } +} + +impl Render for AliasDatatype { + fn to_sexpr(&self) -> SExpr { + self.to.to_sexpr() + } +} + +impl Render for EnumDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("enum"), self.repr.to_sexpr()]; + let variants = self + .variants + .iter() + .map(|v| v.to_sexpr()) + .collect::>(); + SExpr::Vec([header, variants].concat()) + } +} + +impl Render for FlagsDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; + let flags = self + .flags + .iter() + .map(|f| SExpr::Vec(vec![SExpr::word("flag"), f.to_sexpr()])) + .collect::>(); + SExpr::Vec([header, flags].concat()) + } +} + +impl Render for StructDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("struct")]; + let members = self + .members + .iter() + .map(|m| { + SExpr::Vec(vec![ + SExpr::word("field"), + m.name.to_sexpr(), + m.type_.to_sexpr(), + ]) + }) + .collect::>(); + SExpr::Vec([header, members].concat()) + } +} + +impl Render for UnionDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("union")]; + let variants = self + .variants + .iter() + .map(|v| { + SExpr::Vec(vec![ + SExpr::word("field"), + v.name.to_sexpr(), + v.type_.to_sexpr(), + ]) + }) + .collect::>(); + SExpr::Vec([header, variants].concat()) + } +} + +impl Render for IntRepr { + fn to_sexpr(&self) -> SExpr { + match self { + IntRepr::U8 => SExpr::word("u8"), + IntRepr::U16 => SExpr::word("u16"), + IntRepr::U32 => SExpr::word("u32"), + IntRepr::U64 => SExpr::word("u64"), + } + } +} + +impl Render for Module { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("module"), self.name.to_sexpr()]; + let definitions = self + .imports() + .map(|i| i.to_sexpr()) + .chain(self.funcs().map(|f| f.to_sexpr())) + .collect::>(); + SExpr::Vec([header, definitions].concat()) + } +} + +impl Render for ModuleImport { + fn to_sexpr(&self) -> SExpr { + let variant = match self.variant { + ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), + }; + SExpr::Vec(vec![ + SExpr::word("import"), + SExpr::quote(self.name.as_str()), + variant, + ]) + } +} + +impl Render for InterfaceFunc { + fn to_sexpr(&self) -> SExpr { + let header = vec![ + SExpr::annot("interface"), + SExpr::word("func"), + SExpr::Vec(vec![ + SExpr::word("export"), + SExpr::quote(self.name.as_str()), + ]), + ]; + let params = self + .params + .iter() + .map(|f| { + SExpr::Vec(vec![ + SExpr::word("param"), + f.name.to_sexpr(), + f.type_.to_sexpr(), + ]) + }) + .collect(); + let results = self + .results + .iter() + .map(|f| { + SExpr::Vec(vec![ + SExpr::word("result"), + f.name.to_sexpr(), + f.type_.to_sexpr(), + ]) + }) + .collect(); + SExpr::Vec([header, params, results].concat()) + } +} diff --git a/proposals/clocks/tools/witx/src/sexpr.rs b/proposals/clocks/tools/witx/src/sexpr.rs index 6a34cf83b..d87d427e3 100644 --- a/proposals/clocks/tools/witx/src/sexpr.rs +++ b/proposals/clocks/tools/witx/src/sexpr.rs @@ -1,3 +1,4 @@ +use crate::io::{Filesystem, WitxIo}; pub use crate::lexer::LexError; use crate::lexer::{Lexer, LocatedError, LocatedToken, Token}; use crate::Location; @@ -41,14 +42,17 @@ pub enum SExprParseError { } impl SExprParseError { - pub fn report(&self) -> String { + pub fn report_with(&self, witxio: &dyn WitxIo) -> String { use SExprParseError::*; match self { - Lex(lex_err, loc) => format!("{}\n{}", loc.highlight_source(), lex_err), - UnexpectedCloseParen(loc) => format!("{}\n{}", loc.highlight_source(), self), + Lex(lex_err, loc) => format!("{}\n{}", loc.highlight_source_with(witxio), lex_err), + UnexpectedCloseParen(loc) => format!("{}\n{}", loc.highlight_source_with(witxio), self), UnexpectedEof(_path) => format!("{}", self), } } + pub fn report(&self) -> String { + self.report_with(&Filesystem) + } } pub struct SExprParser<'a> { diff --git a/proposals/clocks/tools/witx/src/toplevel.rs b/proposals/clocks/tools/witx/src/toplevel.rs index cf3a5e377..98325b39c 100644 --- a/proposals/clocks/tools/witx/src/toplevel.rs +++ b/proposals/clocks/tools/witx/src/toplevel.rs @@ -1,32 +1,15 @@ +use crate::io::{Filesystem, WitxIo}; use crate::parser::{DeclSyntax, ParseError, TopLevelSyntax}; use crate::sexpr::SExprParser; use crate::WitxError; use std::collections::HashSet; -use std::fs; use std::path::{Path, PathBuf}; -trait WitxIo { - fn fgets(&self, path: &Path) -> Result; - fn canonicalize(&self, path: &Path) -> Result; -} - -struct Filesystem; - -impl WitxIo for Filesystem { - fn fgets(&self, path: &Path) -> Result { - fs::read_to_string(path).map_err(|e| WitxError::UseResolution(path.to_path_buf(), e)) - } - fn canonicalize(&self, path: &Path) -> Result { - path.canonicalize() - .map_err(|e| WitxError::UseResolution(path.to_path_buf(), e)) - } -} - pub fn parse_witx>(i: P) -> Result, WitxError> { parse_witx_with(i, &Filesystem) } -fn parse_witx_with>( +pub fn parse_witx_with>( i: P, witxio: &dyn WitxIo, ) -> Result, WitxError> { @@ -86,44 +69,14 @@ fn resolve_uses( #[cfg(test)] mod test { use super::*; + use crate::io::MockFs; use crate::parser::*; use crate::Location; - use std::collections::HashMap; - - struct MockFs { - map: HashMap<&'static str, &'static str>, - } - - impl MockFs { - pub fn new(strings: Vec<(&'static str, &'static str)>) -> Self { - MockFs { - map: strings.into_iter().collect(), - } - } - } - - impl WitxIo for MockFs { - fn fgets(&self, path: &Path) -> Result { - if let Some(entry) = self.map.get(path.to_str().unwrap()) { - Ok(entry.to_string()) - } else { - use std::io::{Error, ErrorKind}; - Err(WitxError::UseResolution( - path.to_path_buf(), - Error::new(ErrorKind::Other, "mock fs: file not found"), - )) - } - } - fn canonicalize(&self, path: &Path) -> Result { - Ok(PathBuf::from(path)) - } - } #[test] fn empty() { assert_eq!( - parse_witx_with(&Path::new("/a"), &MockFs::new(vec![("/a", ";; empty")])) - .expect("parse"), + parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", ";; empty")])).expect("parse"), Vec::new(), ); } @@ -133,7 +86,7 @@ mod test { assert_eq!( parse_witx_with( &Path::new("/a"), - &MockFs::new(vec![("/a", "(use \"b\")"), ("/b", ";; empty")]) + &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]) ) .expect("parse"), Vec::new(), @@ -145,7 +98,7 @@ mod test { assert_eq!( parse_witx_with( &Path::new("/a"), - &MockFs::new(vec![ + &MockFs::new(&[ ("/a", "(use \"b\")"), ("/b", "(use \"c\")\n(typename $b_float f64)"), ("/c", "(typename $c_int u32)") @@ -184,7 +137,7 @@ mod test { assert_eq!( parse_witx_with( &Path::new("/a"), - &MockFs::new(vec![ + &MockFs::new(&[ ("/a", "(use \"b\")\n(use \"c\")"), ("/b", "(use \"d\")"), ("/c", "(use \"d\")"), @@ -208,23 +161,20 @@ mod test { #[test] fn use_not_found() { - match parse_witx_with(&Path::new("/a"), &MockFs::new(vec![("/a", "(use \"b\")")])) + match parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", "(use \"b\")")])) .err() .unwrap() { - WitxError::UseResolution(path, _error) => assert_eq!(path, PathBuf::from("/b")), + WitxError::Io(path, _error) => assert_eq!(path, PathBuf::from("/b")), e => panic!("wrong error: {:?}", e), } } #[test] fn use_invalid() { - match parse_witx_with( - &Path::new("/a"), - &MockFs::new(vec![("/a", "(use bbbbbbb)")]), - ) - .err() - .unwrap() + match parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", "(use bbbbbbb)")])) + .err() + .unwrap() { WitxError::Parse(e) => { assert_eq!(e.message, "invalid use declaration"); diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 7041fca98..0fecf1178 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -1,4 +1,5 @@ use crate::{ + io::{Filesystem, WitxIo}, parser::{ DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, IdentSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, @@ -42,25 +43,30 @@ pub enum ValidationError { } impl ValidationError { - pub fn report(&self) -> String { + pub fn report_with(&self, witxio: &dyn WitxIo) -> String { use ValidationError::*; match self { UnknownName { location, .. } | WrongKindName { location, .. } | Recursive { location, .. } - | InvalidRepr { location, .. } => format!("{}\n{}", location.highlight_source(), &self), + | InvalidRepr { location, .. } => { + format!("{}\n{}", location.highlight_source_with(witxio), &self) + } NameAlreadyExists { at_location, previous_location, .. } => format!( "{}\n{}\nOriginally defined at:\n{}", - at_location.highlight_source(), + at_location.highlight_source_with(witxio), &self, - previous_location.highlight_source(), + previous_location.highlight_source_with(witxio), ), } } + pub fn report(&self) -> String { + self.report_with(&Filesystem) + } } pub fn validate_document(decls: &[DeclSyntax]) -> Result { @@ -70,10 +76,7 @@ pub fn validate_document(decls: &[DeclSyntax]) -> Result, _>>()?; - let rc_module = Rc::new(Module { - name: name.clone(), + let rc_module = Rc::new(Module::new( + name.clone(), definitions, - entries: module_validator.entries, - }); + module_validator.entries, + )); self.entries .insert(name, Entry::Module(Rc::downgrade(&rc_module))); Ok(Definition::Module(rc_module)) @@ -308,10 +311,10 @@ impl DocValidation { fn validate_int_repr(type_: &BuiltinType, location: &Location) -> Result { match type_ { - BuiltinType::U8 => Ok(IntRepr::I8), - BuiltinType::U16 => Ok(IntRepr::I16), - BuiltinType::U32 => Ok(IntRepr::I32), - BuiltinType::U64 => Ok(IntRepr::I64), + BuiltinType::U8 => Ok(IntRepr::U8), + BuiltinType::U16 => Ok(IntRepr::U16), + BuiltinType::U32 => Ok(IntRepr::U32), + BuiltinType::U64 => Ok(IntRepr::U64), _ => Err(ValidationError::InvalidRepr { repr: type_.clone(), location: location.clone(), diff --git a/proposals/clocks/tools/witx/tests/wasi_unstable.rs b/proposals/clocks/tools/witx/tests/wasi_unstable.rs index 6e196cb4a..2722e8d04 100644 --- a/proposals/clocks/tools/witx/tests/wasi_unstable.rs +++ b/proposals/clocks/tools/witx/tests/wasi_unstable.rs @@ -21,3 +21,19 @@ fn validate_wasi_ephemeral_preview0() { fn validate_wasi_old_preview0() { witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")).unwrap(); } + +#[test] +fn render_roundtrip() { + let doc = witx::load(Path::new( + "../../phases/unstable/witx/wasi_unstable_preview0.witx", + )) + .unwrap(); + + let back_to_sexprs = format!("{}", doc); + println!("{}", back_to_sexprs); + let doc2 = witx::parse(&back_to_sexprs) + .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) + .unwrap(); + + assert_eq!(doc, doc2); +} From 615ff150ab4063f577993fdd4dc4824198ae6616 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 26 Sep 2019 16:17:20 -0700 Subject: [PATCH 0182/1772] witx crate: improve public API (#96) * witx tool: improve public api so you don't have to know about internal invariants the definitions/entries pattern involves upgrading Weak into Rc and also its not super intuitive, especially given ive written zero (0) docs. This is a bit nicer to use * witx: add render trait, make sure it roundtrips by implementing Eq * witx crate: IntRepr variants are U8, U16... to reflect syntax as "u8"... * witx crate: doc comments --- proposals/random/tools/witx/src/ast.rs | 173 ++++++++++-- proposals/random/tools/witx/src/io.rs | 91 ++++++ proposals/random/tools/witx/src/lib.rs | 51 ++-- proposals/random/tools/witx/src/parser.rs | 10 +- proposals/random/tools/witx/src/render.rs | 266 ++++++++++++++++++ proposals/random/tools/witx/src/sexpr.rs | 10 +- proposals/random/tools/witx/src/toplevel.rs | 74 +---- proposals/random/tools/witx/src/validate.rs | 35 +-- .../random/tools/witx/tests/wasi_unstable.rs | 16 ++ 9 files changed, 601 insertions(+), 125 deletions(-) create mode 100644 proposals/random/tools/witx/src/io.rs create mode 100644 proposals/random/tools/witx/src/render.rs diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 4df4d1e24..3713b3dd9 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -18,10 +18,71 @@ impl Id { #[derive(Debug, Clone)] pub struct Document { - pub definitions: Vec, - pub entries: HashMap, + definitions: Vec, + entries: HashMap, } +impl Document { + pub(crate) fn new(definitions: Vec, entries: HashMap) -> Self { + Document { + definitions, + entries, + } + } + pub fn datatype(&self, name: &Id) -> Option> { + self.entries.get(name).and_then(|e| match e { + Entry::Datatype(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + _ => None, + }) + } + pub fn datatypes<'a>(&'a self) -> impl Iterator> + 'a { + self.definitions.iter().filter_map(|d| match d { + Definition::Datatype(d) => Some(d.clone()), + _ => None, + }) + } + pub fn module(&self, name: &Id) -> Option> { + self.entries.get(&name).and_then(|e| match e { + Entry::Module(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + _ => None, + }) + } + pub fn modules<'a>(&'a self) -> impl Iterator> + 'a { + self.definitions.iter().filter_map(|d| match d { + Definition::Module(d) => Some(d.clone()), + _ => None, + }) + } +} + +impl PartialEq for Document { + fn eq(&self, rhs: &Document) -> bool { + if self.definitions.len() != rhs.definitions.len() { + return false; + } + for d in self.datatypes() { + if let Some(d_rhs) = rhs.datatype(&d.name) { + if d != d_rhs { + return false; + } + } else { + return false; + } + } + for m in self.modules() { + if let Some(m_rhs) = rhs.module(&m.name) { + if m != m_rhs { + return false; + } + } else { + return false; + } + } + true + } +} +impl Eq for Document {} + #[derive(Debug, Clone)] pub enum Definition { Datatype(Rc), @@ -43,7 +104,7 @@ impl Entry { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum DatatypeIdent { Builtin(BuiltinType), Array(Box), @@ -52,13 +113,13 @@ pub enum DatatypeIdent { Ident(Rc), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Datatype { pub name: Id, pub variant: DatatypeVariant, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum DatatypeVariant { Alias(AliasDatatype), Enum(EnumDatatype), @@ -67,53 +128,53 @@ pub enum DatatypeVariant { Union(UnionDatatype), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct AliasDatatype { pub name: Id, pub to: DatatypeIdent, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum IntRepr { - I8, - I16, - I32, - I64, + U8, + U16, + U32, + U64, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumDatatype { pub name: Id, pub repr: IntRepr, pub variants: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsDatatype { pub name: Id, pub repr: IntRepr, pub flags: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct StructDatatype { pub name: Id, pub members: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct StructMember { pub name: Id, pub type_: DatatypeIdent, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionDatatype { pub name: Id, pub variants: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionVariant { pub name: Id, pub type_: DatatypeIdent, @@ -122,10 +183,76 @@ pub struct UnionVariant { #[derive(Debug, Clone)] pub struct Module { pub name: Id, - pub definitions: Vec, - pub entries: HashMap, + definitions: Vec, + entries: HashMap, +} + +impl Module { + pub(crate) fn new( + name: Id, + definitions: Vec, + entries: HashMap, + ) -> Self { + Module { + name, + definitions, + entries, + } + } + pub fn import(&self, name: &Id) -> Option> { + self.entries.get(name).and_then(|e| match e { + ModuleEntry::Import(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + _ => None, + }) + } + pub fn imports<'a>(&'a self) -> impl Iterator> + 'a { + self.definitions.iter().filter_map(|d| match d { + ModuleDefinition::Import(d) => Some(d.clone()), + _ => None, + }) + } + pub fn func(&self, name: &Id) -> Option> { + self.entries.get(name).and_then(|e| match e { + ModuleEntry::Func(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + _ => None, + }) + } + pub fn funcs<'a>(&'a self) -> impl Iterator> + 'a { + self.definitions.iter().filter_map(|d| match d { + ModuleDefinition::Func(d) => Some(d.clone()), + _ => None, + }) + } } +impl PartialEq for Module { + fn eq(&self, rhs: &Module) -> bool { + if self.definitions.len() != rhs.definitions.len() { + return false; + } + for i in self.imports() { + if let Some(i_rhs) = rhs.import(&i.name) { + if i != i_rhs { + return false; + } + } else { + return false; + } + } + for f in self.funcs() { + if let Some(f_rhs) = rhs.func(&f.name) { + if f != f_rhs { + return false; + } + } else { + return false; + } + } + true + } +} +impl Eq for Module {} + #[derive(Debug, Clone)] pub enum ModuleDefinition { Import(Rc), @@ -138,25 +265,25 @@ pub enum ModuleEntry { Func(Weak), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ModuleImport { pub name: Id, pub variant: ModuleImportVariant, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum ModuleImportVariant { Memory, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct InterfaceFunc { pub name: Id, pub params: Vec, pub results: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct InterfaceFuncParam { pub name: Id, pub type_: DatatypeIdent, diff --git a/proposals/random/tools/witx/src/io.rs b/proposals/random/tools/witx/src/io.rs new file mode 100644 index 000000000..4f40d8947 --- /dev/null +++ b/proposals/random/tools/witx/src/io.rs @@ -0,0 +1,91 @@ +use crate::WitxError; +use std::collections::HashMap; +use std::fs::{read_to_string, File}; +use std::io::{BufRead, BufReader, Error, ErrorKind}; +use std::path::{Path, PathBuf}; + +pub trait WitxIo { + /// Read the entire file into a String. Used to resolve `use` declarations. + fn fgets(&self, path: &Path) -> Result; + /// Read a line of a file into a String. Used for error reporting. + fn fget_line(&self, path: &Path, line_num: usize) -> Result; + /// Return the canonical (non-symlinked) path of a file. Used to resolve `use` declarations. + fn canonicalize(&self, path: &Path) -> Result; +} + +pub struct Filesystem; + +impl WitxIo for Filesystem { + fn fgets(&self, path: &Path) -> Result { + read_to_string(path).map_err(|e| WitxError::Io(path.to_path_buf(), e)) + } + fn fget_line(&self, path: &Path, line_num: usize) -> Result { + let f = File::open(path).map_err(|e| WitxError::Io(path.into(), e))?; + let buf = BufReader::new(f); + let l = buf + .lines() + .skip(line_num - 1) + .next() + .ok_or_else(|| { + WitxError::Io(path.into(), Error::new(ErrorKind::Other, "Line not found")) + })? + .map_err(|e| WitxError::Io(path.into(), e))?; + + Ok(l) + } + fn canonicalize(&self, path: &Path) -> Result { + path.canonicalize() + .map_err(|e| WitxError::Io(path.to_path_buf(), e)) + } +} + +pub struct MockFs { + map: HashMap, +} + +impl MockFs { + pub fn new(strings: &[(&str, &str)]) -> Self { + MockFs { + map: strings + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + } + } +} + +impl WitxIo for MockFs { + fn fgets(&self, path: &Path) -> Result { + if let Some(entry) = self.map.get(path.to_str().unwrap()) { + Ok(entry.to_string()) + } else { + Err(WitxError::Io( + path.to_path_buf(), + Error::new(ErrorKind::Other, "mock fs: file not found"), + )) + } + } + fn fget_line(&self, path: &Path, line: usize) -> Result { + if let Some(entry) = self.map.get(path.to_str().unwrap()) { + entry + .lines() + .skip(line - 1) + .next() + .map(|s| s.to_string()) + .ok_or_else(|| { + WitxError::Io( + path.to_path_buf(), + Error::new(ErrorKind::Other, "mock fs: file not found"), + ) + }) + } else { + Err(WitxError::Io( + path.to_path_buf(), + Error::new(ErrorKind::Other, "mock fs: file not found"), + )) + } + } + fn canonicalize(&self, path: &Path) -> Result { + Ok(PathBuf::from(path)) + } +} diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 7d5040d00..34876cf7b 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -1,9 +1,13 @@ /// Types describing a validated witx document mod ast; +/// Interface for filesystem or mock IO +mod io; /// Lexer text into tokens mod lexer; /// Witx syntax parsing from SExprs mod parser; +/// Render ast to text +mod render; /// SExpr parsing from tokens mod sexpr; /// Resolve toplevel `use` declarations across files @@ -17,15 +21,17 @@ pub use ast::{ ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; +pub use io::{Filesystem, MockFs, WitxIo}; pub use lexer::LexError; pub use parser::{DeclSyntax, ParseError}; +pub use render::{Render, SExpr as RenderSExpr}; pub use sexpr::SExprParseError; pub use validate::ValidationError; use failure::Fail; -use std::io; use std::path::{Path, PathBuf}; +/// Load a witx document from the filesystem pub fn load>(path: P) -> Result { use toplevel::parse_witx; use validate::validate_document; @@ -33,6 +39,15 @@ pub fn load>(path: P) -> Result { validate_document(&parsed_decls).map_err(WitxError::Validation) } +/// Parse a witx document from a str. `(use ...)` directives are not permitted. +pub fn parse(source: &str) -> Result { + use toplevel::parse_witx_with; + use validate::validate_document; + let mockfs = MockFs::new(&[("-", source)]); + let parsed_decls = parse_witx_with(Path::new("-"), &mockfs)?; + validate_document(&parsed_decls).map_err(WitxError::Validation) +} + /// Location in the source text #[derive(Debug, PartialEq, Eq, Clone)] pub struct Location { @@ -45,8 +60,8 @@ pub struct Location { pub enum WitxError { #[fail(display = "{}", _0)] SExpr(#[cause] SExprParseError), - #[fail(display = "when resolving use declaration for {:?}: {}", _0, _1)] - UseResolution(PathBuf, #[cause] io::Error), + #[fail(display = "with file {:?}: {}", _0, _1)] + Io(PathBuf, #[cause] ::std::io::Error), #[fail(display = "{}", _0)] Parse(#[cause] ParseError), #[fail(display = "{}", _0)] @@ -54,20 +69,24 @@ pub enum WitxError { } impl WitxError { - pub fn report(&self) -> String { + pub fn report_with(&self, witxio: &dyn WitxIo) -> String { use WitxError::*; match self { - SExpr(sexpr) => sexpr.report(), - UseResolution(path, ioerr) => format!("when resolving `use {:?}`: {}", path, ioerr), - Parse(parse) => parse.report(), - Validation(validation) => validation.report(), + SExpr(sexpr) => sexpr.report_with(witxio), + Io(path, ioerr) => format!("with file {:?}: {}", path, ioerr), + Parse(parse) => parse.report_with(witxio), + Validation(validation) => validation.report_with(witxio), } } + pub fn report(&self) -> String { + self.report_with(&Filesystem) + } } + impl Location { - pub fn highlight_source(&self) -> String { + pub fn highlight_source_with(&self, witxio: &dyn WitxIo) -> String { let mut msg = format!("in {:?}:\n", self.path); - if let Ok(src_line) = self.source_line() { + if let Ok(src_line) = witxio.fget_line(&self.path, self.line) { msg += &format!( "{line_num: >5} | {src_line}\n{blank: >5} {caret: >column$}", line_num = self.line, @@ -79,15 +98,7 @@ impl Location { } msg } - pub fn source_line(&self) -> Result { - use std::fs::File; - use std::io::{BufRead, BufReader}; - let f = BufReader::new(File::open(&self.path)?); - let l = f - .lines() - .skip(self.line - 1) - .next() - .unwrap_or_else(|| Err(io::Error::new(io::ErrorKind::Other, "TODO")))?; - Ok(l) + pub fn highlight_source(&self) -> String { + self.highlight_source_with(&Filesystem) } } diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index a99df5fa4..1f627b27c 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -1,3 +1,4 @@ +use crate::io::{Filesystem, WitxIo}; use crate::sexpr::SExpr; use crate::Location; use failure::Fail; @@ -23,8 +24,15 @@ pub struct ParseError { } impl ParseError { + pub fn report_with(&self, witxio: &dyn WitxIo) -> String { + format!( + "{}\n{}", + self.location.highlight_source_with(witxio), + self.message + ) + } pub fn report(&self) -> String { - format!("{}\n{}", self.location.highlight_source(), self.message) + self.report_with(&Filesystem) } } diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs new file mode 100644 index 000000000..912d59508 --- /dev/null +++ b/proposals/random/tools/witx/src/render.rs @@ -0,0 +1,266 @@ +use crate::ast::*; +use std::fmt; + +impl fmt::Display for Document { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for d in self.datatypes() { + write!(f, "{}\n", d.to_sexpr())?; + } + for m in self.modules() { + write!(f, "{}\n", m.to_sexpr())?; + } + Ok(()) + } +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum SExpr { + Vec(Vec), + Word(String), + Ident(String), + Quote(String), + /// Short for Annotation + Annot(String), +} + +impl fmt::Display for SExpr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + SExpr::Vec(vs) => { + write!(f, "(")?; + let mut vss = Vec::new(); + for v in vs { + vss.push(format!("{}", v)); + } + f.write_str(&vss.join(" "))?; + write!(f, ")") + } + SExpr::Word(w) => write!(f, "{}", w), + SExpr::Ident(i) => write!(f, "${}", i), + SExpr::Quote(q) => write!(f, "\"{}\"", q), + SExpr::Annot(a) => write!(f, "@{}", a), + } + } +} + +impl SExpr { + fn word(s: &str) -> SExpr { + SExpr::Word(s.to_string()) + } + fn ident(s: &str) -> SExpr { + SExpr::Ident(s.to_string()) + } + fn quote(s: &str) -> SExpr { + SExpr::Quote(s.to_string()) + } + fn annot(s: &str) -> SExpr { + SExpr::Annot(s.to_string()) + } +} + +pub trait Render { + fn to_sexpr(&self) -> SExpr; +} + +impl Render for Id { + fn to_sexpr(&self) -> SExpr { + SExpr::ident(self.as_str()) + } +} + +impl Render for BuiltinType { + fn to_sexpr(&self) -> SExpr { + match self { + BuiltinType::String => SExpr::word("string"), + BuiltinType::Data => SExpr::word("data"), + BuiltinType::U8 => SExpr::word("u8"), + BuiltinType::U16 => SExpr::word("u16"), + BuiltinType::U32 => SExpr::word("u32"), + BuiltinType::U64 => SExpr::word("u64"), + BuiltinType::S8 => SExpr::word("s8"), + BuiltinType::S16 => SExpr::word("s16"), + BuiltinType::S32 => SExpr::word("s32"), + BuiltinType::S64 => SExpr::word("s64"), + BuiltinType::F32 => SExpr::word("f32"), + BuiltinType::F64 => SExpr::word("f64"), + } + } +} + +impl Render for DatatypeIdent { + fn to_sexpr(&self) -> SExpr { + match self { + DatatypeIdent::Builtin(b) => b.to_sexpr(), + DatatypeIdent::Array(a) => SExpr::Vec(vec![SExpr::word("array"), a.to_sexpr()]), + DatatypeIdent::Pointer(p) => SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("pointer"), + p.to_sexpr(), + ]), + DatatypeIdent::ConstPointer(p) => SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("const_pointer"), + p.to_sexpr(), + ]), + DatatypeIdent::Ident(i) => i.name.to_sexpr(), + } + } +} + +impl Render for Datatype { + fn to_sexpr(&self) -> SExpr { + let name = self.name.to_sexpr(); + let body = self.variant.to_sexpr(); + SExpr::Vec(vec![SExpr::word("typename"), name, body]) + } +} + +impl Render for DatatypeVariant { + fn to_sexpr(&self) -> SExpr { + match self { + DatatypeVariant::Alias(a) => a.to_sexpr(), + DatatypeVariant::Enum(a) => a.to_sexpr(), + DatatypeVariant::Flags(a) => a.to_sexpr(), + DatatypeVariant::Struct(a) => a.to_sexpr(), + DatatypeVariant::Union(a) => a.to_sexpr(), + } + } +} + +impl Render for AliasDatatype { + fn to_sexpr(&self) -> SExpr { + self.to.to_sexpr() + } +} + +impl Render for EnumDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("enum"), self.repr.to_sexpr()]; + let variants = self + .variants + .iter() + .map(|v| v.to_sexpr()) + .collect::>(); + SExpr::Vec([header, variants].concat()) + } +} + +impl Render for FlagsDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; + let flags = self + .flags + .iter() + .map(|f| SExpr::Vec(vec![SExpr::word("flag"), f.to_sexpr()])) + .collect::>(); + SExpr::Vec([header, flags].concat()) + } +} + +impl Render for StructDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("struct")]; + let members = self + .members + .iter() + .map(|m| { + SExpr::Vec(vec![ + SExpr::word("field"), + m.name.to_sexpr(), + m.type_.to_sexpr(), + ]) + }) + .collect::>(); + SExpr::Vec([header, members].concat()) + } +} + +impl Render for UnionDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("union")]; + let variants = self + .variants + .iter() + .map(|v| { + SExpr::Vec(vec![ + SExpr::word("field"), + v.name.to_sexpr(), + v.type_.to_sexpr(), + ]) + }) + .collect::>(); + SExpr::Vec([header, variants].concat()) + } +} + +impl Render for IntRepr { + fn to_sexpr(&self) -> SExpr { + match self { + IntRepr::U8 => SExpr::word("u8"), + IntRepr::U16 => SExpr::word("u16"), + IntRepr::U32 => SExpr::word("u32"), + IntRepr::U64 => SExpr::word("u64"), + } + } +} + +impl Render for Module { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("module"), self.name.to_sexpr()]; + let definitions = self + .imports() + .map(|i| i.to_sexpr()) + .chain(self.funcs().map(|f| f.to_sexpr())) + .collect::>(); + SExpr::Vec([header, definitions].concat()) + } +} + +impl Render for ModuleImport { + fn to_sexpr(&self) -> SExpr { + let variant = match self.variant { + ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), + }; + SExpr::Vec(vec![ + SExpr::word("import"), + SExpr::quote(self.name.as_str()), + variant, + ]) + } +} + +impl Render for InterfaceFunc { + fn to_sexpr(&self) -> SExpr { + let header = vec![ + SExpr::annot("interface"), + SExpr::word("func"), + SExpr::Vec(vec![ + SExpr::word("export"), + SExpr::quote(self.name.as_str()), + ]), + ]; + let params = self + .params + .iter() + .map(|f| { + SExpr::Vec(vec![ + SExpr::word("param"), + f.name.to_sexpr(), + f.type_.to_sexpr(), + ]) + }) + .collect(); + let results = self + .results + .iter() + .map(|f| { + SExpr::Vec(vec![ + SExpr::word("result"), + f.name.to_sexpr(), + f.type_.to_sexpr(), + ]) + }) + .collect(); + SExpr::Vec([header, params, results].concat()) + } +} diff --git a/proposals/random/tools/witx/src/sexpr.rs b/proposals/random/tools/witx/src/sexpr.rs index 6a34cf83b..d87d427e3 100644 --- a/proposals/random/tools/witx/src/sexpr.rs +++ b/proposals/random/tools/witx/src/sexpr.rs @@ -1,3 +1,4 @@ +use crate::io::{Filesystem, WitxIo}; pub use crate::lexer::LexError; use crate::lexer::{Lexer, LocatedError, LocatedToken, Token}; use crate::Location; @@ -41,14 +42,17 @@ pub enum SExprParseError { } impl SExprParseError { - pub fn report(&self) -> String { + pub fn report_with(&self, witxio: &dyn WitxIo) -> String { use SExprParseError::*; match self { - Lex(lex_err, loc) => format!("{}\n{}", loc.highlight_source(), lex_err), - UnexpectedCloseParen(loc) => format!("{}\n{}", loc.highlight_source(), self), + Lex(lex_err, loc) => format!("{}\n{}", loc.highlight_source_with(witxio), lex_err), + UnexpectedCloseParen(loc) => format!("{}\n{}", loc.highlight_source_with(witxio), self), UnexpectedEof(_path) => format!("{}", self), } } + pub fn report(&self) -> String { + self.report_with(&Filesystem) + } } pub struct SExprParser<'a> { diff --git a/proposals/random/tools/witx/src/toplevel.rs b/proposals/random/tools/witx/src/toplevel.rs index cf3a5e377..98325b39c 100644 --- a/proposals/random/tools/witx/src/toplevel.rs +++ b/proposals/random/tools/witx/src/toplevel.rs @@ -1,32 +1,15 @@ +use crate::io::{Filesystem, WitxIo}; use crate::parser::{DeclSyntax, ParseError, TopLevelSyntax}; use crate::sexpr::SExprParser; use crate::WitxError; use std::collections::HashSet; -use std::fs; use std::path::{Path, PathBuf}; -trait WitxIo { - fn fgets(&self, path: &Path) -> Result; - fn canonicalize(&self, path: &Path) -> Result; -} - -struct Filesystem; - -impl WitxIo for Filesystem { - fn fgets(&self, path: &Path) -> Result { - fs::read_to_string(path).map_err(|e| WitxError::UseResolution(path.to_path_buf(), e)) - } - fn canonicalize(&self, path: &Path) -> Result { - path.canonicalize() - .map_err(|e| WitxError::UseResolution(path.to_path_buf(), e)) - } -} - pub fn parse_witx>(i: P) -> Result, WitxError> { parse_witx_with(i, &Filesystem) } -fn parse_witx_with>( +pub fn parse_witx_with>( i: P, witxio: &dyn WitxIo, ) -> Result, WitxError> { @@ -86,44 +69,14 @@ fn resolve_uses( #[cfg(test)] mod test { use super::*; + use crate::io::MockFs; use crate::parser::*; use crate::Location; - use std::collections::HashMap; - - struct MockFs { - map: HashMap<&'static str, &'static str>, - } - - impl MockFs { - pub fn new(strings: Vec<(&'static str, &'static str)>) -> Self { - MockFs { - map: strings.into_iter().collect(), - } - } - } - - impl WitxIo for MockFs { - fn fgets(&self, path: &Path) -> Result { - if let Some(entry) = self.map.get(path.to_str().unwrap()) { - Ok(entry.to_string()) - } else { - use std::io::{Error, ErrorKind}; - Err(WitxError::UseResolution( - path.to_path_buf(), - Error::new(ErrorKind::Other, "mock fs: file not found"), - )) - } - } - fn canonicalize(&self, path: &Path) -> Result { - Ok(PathBuf::from(path)) - } - } #[test] fn empty() { assert_eq!( - parse_witx_with(&Path::new("/a"), &MockFs::new(vec![("/a", ";; empty")])) - .expect("parse"), + parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", ";; empty")])).expect("parse"), Vec::new(), ); } @@ -133,7 +86,7 @@ mod test { assert_eq!( parse_witx_with( &Path::new("/a"), - &MockFs::new(vec![("/a", "(use \"b\")"), ("/b", ";; empty")]) + &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]) ) .expect("parse"), Vec::new(), @@ -145,7 +98,7 @@ mod test { assert_eq!( parse_witx_with( &Path::new("/a"), - &MockFs::new(vec![ + &MockFs::new(&[ ("/a", "(use \"b\")"), ("/b", "(use \"c\")\n(typename $b_float f64)"), ("/c", "(typename $c_int u32)") @@ -184,7 +137,7 @@ mod test { assert_eq!( parse_witx_with( &Path::new("/a"), - &MockFs::new(vec![ + &MockFs::new(&[ ("/a", "(use \"b\")\n(use \"c\")"), ("/b", "(use \"d\")"), ("/c", "(use \"d\")"), @@ -208,23 +161,20 @@ mod test { #[test] fn use_not_found() { - match parse_witx_with(&Path::new("/a"), &MockFs::new(vec![("/a", "(use \"b\")")])) + match parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", "(use \"b\")")])) .err() .unwrap() { - WitxError::UseResolution(path, _error) => assert_eq!(path, PathBuf::from("/b")), + WitxError::Io(path, _error) => assert_eq!(path, PathBuf::from("/b")), e => panic!("wrong error: {:?}", e), } } #[test] fn use_invalid() { - match parse_witx_with( - &Path::new("/a"), - &MockFs::new(vec![("/a", "(use bbbbbbb)")]), - ) - .err() - .unwrap() + match parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", "(use bbbbbbb)")])) + .err() + .unwrap() { WitxError::Parse(e) => { assert_eq!(e.message, "invalid use declaration"); diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 7041fca98..0fecf1178 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -1,4 +1,5 @@ use crate::{ + io::{Filesystem, WitxIo}, parser::{ DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, IdentSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, @@ -42,25 +43,30 @@ pub enum ValidationError { } impl ValidationError { - pub fn report(&self) -> String { + pub fn report_with(&self, witxio: &dyn WitxIo) -> String { use ValidationError::*; match self { UnknownName { location, .. } | WrongKindName { location, .. } | Recursive { location, .. } - | InvalidRepr { location, .. } => format!("{}\n{}", location.highlight_source(), &self), + | InvalidRepr { location, .. } => { + format!("{}\n{}", location.highlight_source_with(witxio), &self) + } NameAlreadyExists { at_location, previous_location, .. } => format!( "{}\n{}\nOriginally defined at:\n{}", - at_location.highlight_source(), + at_location.highlight_source_with(witxio), &self, - previous_location.highlight_source(), + previous_location.highlight_source_with(witxio), ), } } + pub fn report(&self) -> String { + self.report_with(&Filesystem) + } } pub fn validate_document(decls: &[DeclSyntax]) -> Result { @@ -70,10 +76,7 @@ pub fn validate_document(decls: &[DeclSyntax]) -> Result, _>>()?; - let rc_module = Rc::new(Module { - name: name.clone(), + let rc_module = Rc::new(Module::new( + name.clone(), definitions, - entries: module_validator.entries, - }); + module_validator.entries, + )); self.entries .insert(name, Entry::Module(Rc::downgrade(&rc_module))); Ok(Definition::Module(rc_module)) @@ -308,10 +311,10 @@ impl DocValidation { fn validate_int_repr(type_: &BuiltinType, location: &Location) -> Result { match type_ { - BuiltinType::U8 => Ok(IntRepr::I8), - BuiltinType::U16 => Ok(IntRepr::I16), - BuiltinType::U32 => Ok(IntRepr::I32), - BuiltinType::U64 => Ok(IntRepr::I64), + BuiltinType::U8 => Ok(IntRepr::U8), + BuiltinType::U16 => Ok(IntRepr::U16), + BuiltinType::U32 => Ok(IntRepr::U32), + BuiltinType::U64 => Ok(IntRepr::U64), _ => Err(ValidationError::InvalidRepr { repr: type_.clone(), location: location.clone(), diff --git a/proposals/random/tools/witx/tests/wasi_unstable.rs b/proposals/random/tools/witx/tests/wasi_unstable.rs index 6e196cb4a..2722e8d04 100644 --- a/proposals/random/tools/witx/tests/wasi_unstable.rs +++ b/proposals/random/tools/witx/tests/wasi_unstable.rs @@ -21,3 +21,19 @@ fn validate_wasi_ephemeral_preview0() { fn validate_wasi_old_preview0() { witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")).unwrap(); } + +#[test] +fn render_roundtrip() { + let doc = witx::load(Path::new( + "../../phases/unstable/witx/wasi_unstable_preview0.witx", + )) + .unwrap(); + + let back_to_sexprs = format!("{}", doc); + println!("{}", back_to_sexprs); + let doc2 = witx::parse(&back_to_sexprs) + .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) + .unwrap(); + + assert_eq!(doc, doc2); +} From 32aeccf42182cf0687b35e42d05e94aa776f2e30 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 26 Sep 2019 16:17:20 -0700 Subject: [PATCH 0183/1772] witx crate: improve public API (#96) * witx tool: improve public api so you don't have to know about internal invariants the definitions/entries pattern involves upgrading Weak into Rc and also its not super intuitive, especially given ive written zero (0) docs. This is a bit nicer to use * witx: add render trait, make sure it roundtrips by implementing Eq * witx crate: IntRepr variants are U8, U16... to reflect syntax as "u8"... * witx crate: doc comments --- proposals/filesystem/tools/witx/src/ast.rs | 173 ++++++++++-- proposals/filesystem/tools/witx/src/io.rs | 91 ++++++ proposals/filesystem/tools/witx/src/lib.rs | 51 ++-- proposals/filesystem/tools/witx/src/parser.rs | 10 +- proposals/filesystem/tools/witx/src/render.rs | 266 ++++++++++++++++++ proposals/filesystem/tools/witx/src/sexpr.rs | 10 +- .../filesystem/tools/witx/src/toplevel.rs | 74 +---- .../filesystem/tools/witx/src/validate.rs | 35 +-- .../tools/witx/tests/wasi_unstable.rs | 16 ++ 9 files changed, 601 insertions(+), 125 deletions(-) create mode 100644 proposals/filesystem/tools/witx/src/io.rs create mode 100644 proposals/filesystem/tools/witx/src/render.rs diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 4df4d1e24..3713b3dd9 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -18,10 +18,71 @@ impl Id { #[derive(Debug, Clone)] pub struct Document { - pub definitions: Vec, - pub entries: HashMap, + definitions: Vec, + entries: HashMap, } +impl Document { + pub(crate) fn new(definitions: Vec, entries: HashMap) -> Self { + Document { + definitions, + entries, + } + } + pub fn datatype(&self, name: &Id) -> Option> { + self.entries.get(name).and_then(|e| match e { + Entry::Datatype(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + _ => None, + }) + } + pub fn datatypes<'a>(&'a self) -> impl Iterator> + 'a { + self.definitions.iter().filter_map(|d| match d { + Definition::Datatype(d) => Some(d.clone()), + _ => None, + }) + } + pub fn module(&self, name: &Id) -> Option> { + self.entries.get(&name).and_then(|e| match e { + Entry::Module(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + _ => None, + }) + } + pub fn modules<'a>(&'a self) -> impl Iterator> + 'a { + self.definitions.iter().filter_map(|d| match d { + Definition::Module(d) => Some(d.clone()), + _ => None, + }) + } +} + +impl PartialEq for Document { + fn eq(&self, rhs: &Document) -> bool { + if self.definitions.len() != rhs.definitions.len() { + return false; + } + for d in self.datatypes() { + if let Some(d_rhs) = rhs.datatype(&d.name) { + if d != d_rhs { + return false; + } + } else { + return false; + } + } + for m in self.modules() { + if let Some(m_rhs) = rhs.module(&m.name) { + if m != m_rhs { + return false; + } + } else { + return false; + } + } + true + } +} +impl Eq for Document {} + #[derive(Debug, Clone)] pub enum Definition { Datatype(Rc), @@ -43,7 +104,7 @@ impl Entry { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum DatatypeIdent { Builtin(BuiltinType), Array(Box), @@ -52,13 +113,13 @@ pub enum DatatypeIdent { Ident(Rc), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Datatype { pub name: Id, pub variant: DatatypeVariant, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum DatatypeVariant { Alias(AliasDatatype), Enum(EnumDatatype), @@ -67,53 +128,53 @@ pub enum DatatypeVariant { Union(UnionDatatype), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct AliasDatatype { pub name: Id, pub to: DatatypeIdent, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum IntRepr { - I8, - I16, - I32, - I64, + U8, + U16, + U32, + U64, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumDatatype { pub name: Id, pub repr: IntRepr, pub variants: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsDatatype { pub name: Id, pub repr: IntRepr, pub flags: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct StructDatatype { pub name: Id, pub members: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct StructMember { pub name: Id, pub type_: DatatypeIdent, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionDatatype { pub name: Id, pub variants: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionVariant { pub name: Id, pub type_: DatatypeIdent, @@ -122,10 +183,76 @@ pub struct UnionVariant { #[derive(Debug, Clone)] pub struct Module { pub name: Id, - pub definitions: Vec, - pub entries: HashMap, + definitions: Vec, + entries: HashMap, +} + +impl Module { + pub(crate) fn new( + name: Id, + definitions: Vec, + entries: HashMap, + ) -> Self { + Module { + name, + definitions, + entries, + } + } + pub fn import(&self, name: &Id) -> Option> { + self.entries.get(name).and_then(|e| match e { + ModuleEntry::Import(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + _ => None, + }) + } + pub fn imports<'a>(&'a self) -> impl Iterator> + 'a { + self.definitions.iter().filter_map(|d| match d { + ModuleDefinition::Import(d) => Some(d.clone()), + _ => None, + }) + } + pub fn func(&self, name: &Id) -> Option> { + self.entries.get(name).and_then(|e| match e { + ModuleEntry::Func(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + _ => None, + }) + } + pub fn funcs<'a>(&'a self) -> impl Iterator> + 'a { + self.definitions.iter().filter_map(|d| match d { + ModuleDefinition::Func(d) => Some(d.clone()), + _ => None, + }) + } } +impl PartialEq for Module { + fn eq(&self, rhs: &Module) -> bool { + if self.definitions.len() != rhs.definitions.len() { + return false; + } + for i in self.imports() { + if let Some(i_rhs) = rhs.import(&i.name) { + if i != i_rhs { + return false; + } + } else { + return false; + } + } + for f in self.funcs() { + if let Some(f_rhs) = rhs.func(&f.name) { + if f != f_rhs { + return false; + } + } else { + return false; + } + } + true + } +} +impl Eq for Module {} + #[derive(Debug, Clone)] pub enum ModuleDefinition { Import(Rc), @@ -138,25 +265,25 @@ pub enum ModuleEntry { Func(Weak), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ModuleImport { pub name: Id, pub variant: ModuleImportVariant, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum ModuleImportVariant { Memory, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct InterfaceFunc { pub name: Id, pub params: Vec, pub results: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct InterfaceFuncParam { pub name: Id, pub type_: DatatypeIdent, diff --git a/proposals/filesystem/tools/witx/src/io.rs b/proposals/filesystem/tools/witx/src/io.rs new file mode 100644 index 000000000..4f40d8947 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/io.rs @@ -0,0 +1,91 @@ +use crate::WitxError; +use std::collections::HashMap; +use std::fs::{read_to_string, File}; +use std::io::{BufRead, BufReader, Error, ErrorKind}; +use std::path::{Path, PathBuf}; + +pub trait WitxIo { + /// Read the entire file into a String. Used to resolve `use` declarations. + fn fgets(&self, path: &Path) -> Result; + /// Read a line of a file into a String. Used for error reporting. + fn fget_line(&self, path: &Path, line_num: usize) -> Result; + /// Return the canonical (non-symlinked) path of a file. Used to resolve `use` declarations. + fn canonicalize(&self, path: &Path) -> Result; +} + +pub struct Filesystem; + +impl WitxIo for Filesystem { + fn fgets(&self, path: &Path) -> Result { + read_to_string(path).map_err(|e| WitxError::Io(path.to_path_buf(), e)) + } + fn fget_line(&self, path: &Path, line_num: usize) -> Result { + let f = File::open(path).map_err(|e| WitxError::Io(path.into(), e))?; + let buf = BufReader::new(f); + let l = buf + .lines() + .skip(line_num - 1) + .next() + .ok_or_else(|| { + WitxError::Io(path.into(), Error::new(ErrorKind::Other, "Line not found")) + })? + .map_err(|e| WitxError::Io(path.into(), e))?; + + Ok(l) + } + fn canonicalize(&self, path: &Path) -> Result { + path.canonicalize() + .map_err(|e| WitxError::Io(path.to_path_buf(), e)) + } +} + +pub struct MockFs { + map: HashMap, +} + +impl MockFs { + pub fn new(strings: &[(&str, &str)]) -> Self { + MockFs { + map: strings + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + } + } +} + +impl WitxIo for MockFs { + fn fgets(&self, path: &Path) -> Result { + if let Some(entry) = self.map.get(path.to_str().unwrap()) { + Ok(entry.to_string()) + } else { + Err(WitxError::Io( + path.to_path_buf(), + Error::new(ErrorKind::Other, "mock fs: file not found"), + )) + } + } + fn fget_line(&self, path: &Path, line: usize) -> Result { + if let Some(entry) = self.map.get(path.to_str().unwrap()) { + entry + .lines() + .skip(line - 1) + .next() + .map(|s| s.to_string()) + .ok_or_else(|| { + WitxError::Io( + path.to_path_buf(), + Error::new(ErrorKind::Other, "mock fs: file not found"), + ) + }) + } else { + Err(WitxError::Io( + path.to_path_buf(), + Error::new(ErrorKind::Other, "mock fs: file not found"), + )) + } + } + fn canonicalize(&self, path: &Path) -> Result { + Ok(PathBuf::from(path)) + } +} diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 7d5040d00..34876cf7b 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -1,9 +1,13 @@ /// Types describing a validated witx document mod ast; +/// Interface for filesystem or mock IO +mod io; /// Lexer text into tokens mod lexer; /// Witx syntax parsing from SExprs mod parser; +/// Render ast to text +mod render; /// SExpr parsing from tokens mod sexpr; /// Resolve toplevel `use` declarations across files @@ -17,15 +21,17 @@ pub use ast::{ ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; +pub use io::{Filesystem, MockFs, WitxIo}; pub use lexer::LexError; pub use parser::{DeclSyntax, ParseError}; +pub use render::{Render, SExpr as RenderSExpr}; pub use sexpr::SExprParseError; pub use validate::ValidationError; use failure::Fail; -use std::io; use std::path::{Path, PathBuf}; +/// Load a witx document from the filesystem pub fn load>(path: P) -> Result { use toplevel::parse_witx; use validate::validate_document; @@ -33,6 +39,15 @@ pub fn load>(path: P) -> Result { validate_document(&parsed_decls).map_err(WitxError::Validation) } +/// Parse a witx document from a str. `(use ...)` directives are not permitted. +pub fn parse(source: &str) -> Result { + use toplevel::parse_witx_with; + use validate::validate_document; + let mockfs = MockFs::new(&[("-", source)]); + let parsed_decls = parse_witx_with(Path::new("-"), &mockfs)?; + validate_document(&parsed_decls).map_err(WitxError::Validation) +} + /// Location in the source text #[derive(Debug, PartialEq, Eq, Clone)] pub struct Location { @@ -45,8 +60,8 @@ pub struct Location { pub enum WitxError { #[fail(display = "{}", _0)] SExpr(#[cause] SExprParseError), - #[fail(display = "when resolving use declaration for {:?}: {}", _0, _1)] - UseResolution(PathBuf, #[cause] io::Error), + #[fail(display = "with file {:?}: {}", _0, _1)] + Io(PathBuf, #[cause] ::std::io::Error), #[fail(display = "{}", _0)] Parse(#[cause] ParseError), #[fail(display = "{}", _0)] @@ -54,20 +69,24 @@ pub enum WitxError { } impl WitxError { - pub fn report(&self) -> String { + pub fn report_with(&self, witxio: &dyn WitxIo) -> String { use WitxError::*; match self { - SExpr(sexpr) => sexpr.report(), - UseResolution(path, ioerr) => format!("when resolving `use {:?}`: {}", path, ioerr), - Parse(parse) => parse.report(), - Validation(validation) => validation.report(), + SExpr(sexpr) => sexpr.report_with(witxio), + Io(path, ioerr) => format!("with file {:?}: {}", path, ioerr), + Parse(parse) => parse.report_with(witxio), + Validation(validation) => validation.report_with(witxio), } } + pub fn report(&self) -> String { + self.report_with(&Filesystem) + } } + impl Location { - pub fn highlight_source(&self) -> String { + pub fn highlight_source_with(&self, witxio: &dyn WitxIo) -> String { let mut msg = format!("in {:?}:\n", self.path); - if let Ok(src_line) = self.source_line() { + if let Ok(src_line) = witxio.fget_line(&self.path, self.line) { msg += &format!( "{line_num: >5} | {src_line}\n{blank: >5} {caret: >column$}", line_num = self.line, @@ -79,15 +98,7 @@ impl Location { } msg } - pub fn source_line(&self) -> Result { - use std::fs::File; - use std::io::{BufRead, BufReader}; - let f = BufReader::new(File::open(&self.path)?); - let l = f - .lines() - .skip(self.line - 1) - .next() - .unwrap_or_else(|| Err(io::Error::new(io::ErrorKind::Other, "TODO")))?; - Ok(l) + pub fn highlight_source(&self) -> String { + self.highlight_source_with(&Filesystem) } } diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index a99df5fa4..1f627b27c 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -1,3 +1,4 @@ +use crate::io::{Filesystem, WitxIo}; use crate::sexpr::SExpr; use crate::Location; use failure::Fail; @@ -23,8 +24,15 @@ pub struct ParseError { } impl ParseError { + pub fn report_with(&self, witxio: &dyn WitxIo) -> String { + format!( + "{}\n{}", + self.location.highlight_source_with(witxio), + self.message + ) + } pub fn report(&self) -> String { - format!("{}\n{}", self.location.highlight_source(), self.message) + self.report_with(&Filesystem) } } diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs new file mode 100644 index 000000000..912d59508 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -0,0 +1,266 @@ +use crate::ast::*; +use std::fmt; + +impl fmt::Display for Document { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for d in self.datatypes() { + write!(f, "{}\n", d.to_sexpr())?; + } + for m in self.modules() { + write!(f, "{}\n", m.to_sexpr())?; + } + Ok(()) + } +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum SExpr { + Vec(Vec), + Word(String), + Ident(String), + Quote(String), + /// Short for Annotation + Annot(String), +} + +impl fmt::Display for SExpr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + SExpr::Vec(vs) => { + write!(f, "(")?; + let mut vss = Vec::new(); + for v in vs { + vss.push(format!("{}", v)); + } + f.write_str(&vss.join(" "))?; + write!(f, ")") + } + SExpr::Word(w) => write!(f, "{}", w), + SExpr::Ident(i) => write!(f, "${}", i), + SExpr::Quote(q) => write!(f, "\"{}\"", q), + SExpr::Annot(a) => write!(f, "@{}", a), + } + } +} + +impl SExpr { + fn word(s: &str) -> SExpr { + SExpr::Word(s.to_string()) + } + fn ident(s: &str) -> SExpr { + SExpr::Ident(s.to_string()) + } + fn quote(s: &str) -> SExpr { + SExpr::Quote(s.to_string()) + } + fn annot(s: &str) -> SExpr { + SExpr::Annot(s.to_string()) + } +} + +pub trait Render { + fn to_sexpr(&self) -> SExpr; +} + +impl Render for Id { + fn to_sexpr(&self) -> SExpr { + SExpr::ident(self.as_str()) + } +} + +impl Render for BuiltinType { + fn to_sexpr(&self) -> SExpr { + match self { + BuiltinType::String => SExpr::word("string"), + BuiltinType::Data => SExpr::word("data"), + BuiltinType::U8 => SExpr::word("u8"), + BuiltinType::U16 => SExpr::word("u16"), + BuiltinType::U32 => SExpr::word("u32"), + BuiltinType::U64 => SExpr::word("u64"), + BuiltinType::S8 => SExpr::word("s8"), + BuiltinType::S16 => SExpr::word("s16"), + BuiltinType::S32 => SExpr::word("s32"), + BuiltinType::S64 => SExpr::word("s64"), + BuiltinType::F32 => SExpr::word("f32"), + BuiltinType::F64 => SExpr::word("f64"), + } + } +} + +impl Render for DatatypeIdent { + fn to_sexpr(&self) -> SExpr { + match self { + DatatypeIdent::Builtin(b) => b.to_sexpr(), + DatatypeIdent::Array(a) => SExpr::Vec(vec![SExpr::word("array"), a.to_sexpr()]), + DatatypeIdent::Pointer(p) => SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("pointer"), + p.to_sexpr(), + ]), + DatatypeIdent::ConstPointer(p) => SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("const_pointer"), + p.to_sexpr(), + ]), + DatatypeIdent::Ident(i) => i.name.to_sexpr(), + } + } +} + +impl Render for Datatype { + fn to_sexpr(&self) -> SExpr { + let name = self.name.to_sexpr(); + let body = self.variant.to_sexpr(); + SExpr::Vec(vec![SExpr::word("typename"), name, body]) + } +} + +impl Render for DatatypeVariant { + fn to_sexpr(&self) -> SExpr { + match self { + DatatypeVariant::Alias(a) => a.to_sexpr(), + DatatypeVariant::Enum(a) => a.to_sexpr(), + DatatypeVariant::Flags(a) => a.to_sexpr(), + DatatypeVariant::Struct(a) => a.to_sexpr(), + DatatypeVariant::Union(a) => a.to_sexpr(), + } + } +} + +impl Render for AliasDatatype { + fn to_sexpr(&self) -> SExpr { + self.to.to_sexpr() + } +} + +impl Render for EnumDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("enum"), self.repr.to_sexpr()]; + let variants = self + .variants + .iter() + .map(|v| v.to_sexpr()) + .collect::>(); + SExpr::Vec([header, variants].concat()) + } +} + +impl Render for FlagsDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; + let flags = self + .flags + .iter() + .map(|f| SExpr::Vec(vec![SExpr::word("flag"), f.to_sexpr()])) + .collect::>(); + SExpr::Vec([header, flags].concat()) + } +} + +impl Render for StructDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("struct")]; + let members = self + .members + .iter() + .map(|m| { + SExpr::Vec(vec![ + SExpr::word("field"), + m.name.to_sexpr(), + m.type_.to_sexpr(), + ]) + }) + .collect::>(); + SExpr::Vec([header, members].concat()) + } +} + +impl Render for UnionDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("union")]; + let variants = self + .variants + .iter() + .map(|v| { + SExpr::Vec(vec![ + SExpr::word("field"), + v.name.to_sexpr(), + v.type_.to_sexpr(), + ]) + }) + .collect::>(); + SExpr::Vec([header, variants].concat()) + } +} + +impl Render for IntRepr { + fn to_sexpr(&self) -> SExpr { + match self { + IntRepr::U8 => SExpr::word("u8"), + IntRepr::U16 => SExpr::word("u16"), + IntRepr::U32 => SExpr::word("u32"), + IntRepr::U64 => SExpr::word("u64"), + } + } +} + +impl Render for Module { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("module"), self.name.to_sexpr()]; + let definitions = self + .imports() + .map(|i| i.to_sexpr()) + .chain(self.funcs().map(|f| f.to_sexpr())) + .collect::>(); + SExpr::Vec([header, definitions].concat()) + } +} + +impl Render for ModuleImport { + fn to_sexpr(&self) -> SExpr { + let variant = match self.variant { + ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), + }; + SExpr::Vec(vec![ + SExpr::word("import"), + SExpr::quote(self.name.as_str()), + variant, + ]) + } +} + +impl Render for InterfaceFunc { + fn to_sexpr(&self) -> SExpr { + let header = vec![ + SExpr::annot("interface"), + SExpr::word("func"), + SExpr::Vec(vec![ + SExpr::word("export"), + SExpr::quote(self.name.as_str()), + ]), + ]; + let params = self + .params + .iter() + .map(|f| { + SExpr::Vec(vec![ + SExpr::word("param"), + f.name.to_sexpr(), + f.type_.to_sexpr(), + ]) + }) + .collect(); + let results = self + .results + .iter() + .map(|f| { + SExpr::Vec(vec![ + SExpr::word("result"), + f.name.to_sexpr(), + f.type_.to_sexpr(), + ]) + }) + .collect(); + SExpr::Vec([header, params, results].concat()) + } +} diff --git a/proposals/filesystem/tools/witx/src/sexpr.rs b/proposals/filesystem/tools/witx/src/sexpr.rs index 6a34cf83b..d87d427e3 100644 --- a/proposals/filesystem/tools/witx/src/sexpr.rs +++ b/proposals/filesystem/tools/witx/src/sexpr.rs @@ -1,3 +1,4 @@ +use crate::io::{Filesystem, WitxIo}; pub use crate::lexer::LexError; use crate::lexer::{Lexer, LocatedError, LocatedToken, Token}; use crate::Location; @@ -41,14 +42,17 @@ pub enum SExprParseError { } impl SExprParseError { - pub fn report(&self) -> String { + pub fn report_with(&self, witxio: &dyn WitxIo) -> String { use SExprParseError::*; match self { - Lex(lex_err, loc) => format!("{}\n{}", loc.highlight_source(), lex_err), - UnexpectedCloseParen(loc) => format!("{}\n{}", loc.highlight_source(), self), + Lex(lex_err, loc) => format!("{}\n{}", loc.highlight_source_with(witxio), lex_err), + UnexpectedCloseParen(loc) => format!("{}\n{}", loc.highlight_source_with(witxio), self), UnexpectedEof(_path) => format!("{}", self), } } + pub fn report(&self) -> String { + self.report_with(&Filesystem) + } } pub struct SExprParser<'a> { diff --git a/proposals/filesystem/tools/witx/src/toplevel.rs b/proposals/filesystem/tools/witx/src/toplevel.rs index cf3a5e377..98325b39c 100644 --- a/proposals/filesystem/tools/witx/src/toplevel.rs +++ b/proposals/filesystem/tools/witx/src/toplevel.rs @@ -1,32 +1,15 @@ +use crate::io::{Filesystem, WitxIo}; use crate::parser::{DeclSyntax, ParseError, TopLevelSyntax}; use crate::sexpr::SExprParser; use crate::WitxError; use std::collections::HashSet; -use std::fs; use std::path::{Path, PathBuf}; -trait WitxIo { - fn fgets(&self, path: &Path) -> Result; - fn canonicalize(&self, path: &Path) -> Result; -} - -struct Filesystem; - -impl WitxIo for Filesystem { - fn fgets(&self, path: &Path) -> Result { - fs::read_to_string(path).map_err(|e| WitxError::UseResolution(path.to_path_buf(), e)) - } - fn canonicalize(&self, path: &Path) -> Result { - path.canonicalize() - .map_err(|e| WitxError::UseResolution(path.to_path_buf(), e)) - } -} - pub fn parse_witx>(i: P) -> Result, WitxError> { parse_witx_with(i, &Filesystem) } -fn parse_witx_with>( +pub fn parse_witx_with>( i: P, witxio: &dyn WitxIo, ) -> Result, WitxError> { @@ -86,44 +69,14 @@ fn resolve_uses( #[cfg(test)] mod test { use super::*; + use crate::io::MockFs; use crate::parser::*; use crate::Location; - use std::collections::HashMap; - - struct MockFs { - map: HashMap<&'static str, &'static str>, - } - - impl MockFs { - pub fn new(strings: Vec<(&'static str, &'static str)>) -> Self { - MockFs { - map: strings.into_iter().collect(), - } - } - } - - impl WitxIo for MockFs { - fn fgets(&self, path: &Path) -> Result { - if let Some(entry) = self.map.get(path.to_str().unwrap()) { - Ok(entry.to_string()) - } else { - use std::io::{Error, ErrorKind}; - Err(WitxError::UseResolution( - path.to_path_buf(), - Error::new(ErrorKind::Other, "mock fs: file not found"), - )) - } - } - fn canonicalize(&self, path: &Path) -> Result { - Ok(PathBuf::from(path)) - } - } #[test] fn empty() { assert_eq!( - parse_witx_with(&Path::new("/a"), &MockFs::new(vec![("/a", ";; empty")])) - .expect("parse"), + parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", ";; empty")])).expect("parse"), Vec::new(), ); } @@ -133,7 +86,7 @@ mod test { assert_eq!( parse_witx_with( &Path::new("/a"), - &MockFs::new(vec![("/a", "(use \"b\")"), ("/b", ";; empty")]) + &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]) ) .expect("parse"), Vec::new(), @@ -145,7 +98,7 @@ mod test { assert_eq!( parse_witx_with( &Path::new("/a"), - &MockFs::new(vec![ + &MockFs::new(&[ ("/a", "(use \"b\")"), ("/b", "(use \"c\")\n(typename $b_float f64)"), ("/c", "(typename $c_int u32)") @@ -184,7 +137,7 @@ mod test { assert_eq!( parse_witx_with( &Path::new("/a"), - &MockFs::new(vec![ + &MockFs::new(&[ ("/a", "(use \"b\")\n(use \"c\")"), ("/b", "(use \"d\")"), ("/c", "(use \"d\")"), @@ -208,23 +161,20 @@ mod test { #[test] fn use_not_found() { - match parse_witx_with(&Path::new("/a"), &MockFs::new(vec![("/a", "(use \"b\")")])) + match parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", "(use \"b\")")])) .err() .unwrap() { - WitxError::UseResolution(path, _error) => assert_eq!(path, PathBuf::from("/b")), + WitxError::Io(path, _error) => assert_eq!(path, PathBuf::from("/b")), e => panic!("wrong error: {:?}", e), } } #[test] fn use_invalid() { - match parse_witx_with( - &Path::new("/a"), - &MockFs::new(vec![("/a", "(use bbbbbbb)")]), - ) - .err() - .unwrap() + match parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", "(use bbbbbbb)")])) + .err() + .unwrap() { WitxError::Parse(e) => { assert_eq!(e.message, "invalid use declaration"); diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 7041fca98..0fecf1178 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -1,4 +1,5 @@ use crate::{ + io::{Filesystem, WitxIo}, parser::{ DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, IdentSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, @@ -42,25 +43,30 @@ pub enum ValidationError { } impl ValidationError { - pub fn report(&self) -> String { + pub fn report_with(&self, witxio: &dyn WitxIo) -> String { use ValidationError::*; match self { UnknownName { location, .. } | WrongKindName { location, .. } | Recursive { location, .. } - | InvalidRepr { location, .. } => format!("{}\n{}", location.highlight_source(), &self), + | InvalidRepr { location, .. } => { + format!("{}\n{}", location.highlight_source_with(witxio), &self) + } NameAlreadyExists { at_location, previous_location, .. } => format!( "{}\n{}\nOriginally defined at:\n{}", - at_location.highlight_source(), + at_location.highlight_source_with(witxio), &self, - previous_location.highlight_source(), + previous_location.highlight_source_with(witxio), ), } } + pub fn report(&self) -> String { + self.report_with(&Filesystem) + } } pub fn validate_document(decls: &[DeclSyntax]) -> Result { @@ -70,10 +76,7 @@ pub fn validate_document(decls: &[DeclSyntax]) -> Result, _>>()?; - let rc_module = Rc::new(Module { - name: name.clone(), + let rc_module = Rc::new(Module::new( + name.clone(), definitions, - entries: module_validator.entries, - }); + module_validator.entries, + )); self.entries .insert(name, Entry::Module(Rc::downgrade(&rc_module))); Ok(Definition::Module(rc_module)) @@ -308,10 +311,10 @@ impl DocValidation { fn validate_int_repr(type_: &BuiltinType, location: &Location) -> Result { match type_ { - BuiltinType::U8 => Ok(IntRepr::I8), - BuiltinType::U16 => Ok(IntRepr::I16), - BuiltinType::U32 => Ok(IntRepr::I32), - BuiltinType::U64 => Ok(IntRepr::I64), + BuiltinType::U8 => Ok(IntRepr::U8), + BuiltinType::U16 => Ok(IntRepr::U16), + BuiltinType::U32 => Ok(IntRepr::U32), + BuiltinType::U64 => Ok(IntRepr::U64), _ => Err(ValidationError::InvalidRepr { repr: type_.clone(), location: location.clone(), diff --git a/proposals/filesystem/tools/witx/tests/wasi_unstable.rs b/proposals/filesystem/tools/witx/tests/wasi_unstable.rs index 6e196cb4a..2722e8d04 100644 --- a/proposals/filesystem/tools/witx/tests/wasi_unstable.rs +++ b/proposals/filesystem/tools/witx/tests/wasi_unstable.rs @@ -21,3 +21,19 @@ fn validate_wasi_ephemeral_preview0() { fn validate_wasi_old_preview0() { witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")).unwrap(); } + +#[test] +fn render_roundtrip() { + let doc = witx::load(Path::new( + "../../phases/unstable/witx/wasi_unstable_preview0.witx", + )) + .unwrap(); + + let back_to_sexprs = format!("{}", doc); + println!("{}", back_to_sexprs); + let doc2 = witx::parse(&back_to_sexprs) + .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) + .unwrap(); + + assert_eq!(doc, doc2); +} From a5146e672c6893debbe6762aa1644b8f87cba4a0 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 26 Sep 2019 16:24:52 -0700 Subject: [PATCH 0184/1772] witx crate: version 0.2.0 --- proposals/clocks/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index f24cb7183..df1e60ec7 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.1.0" +version = "0.2.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 96333789d14414041d8b9d6e395fe1e2b81df117 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 26 Sep 2019 16:24:52 -0700 Subject: [PATCH 0185/1772] witx crate: version 0.2.0 --- proposals/random/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index f24cb7183..df1e60ec7 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.1.0" +version = "0.2.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 73664d4c9edabd5b91aece7c91061ba06a7bf8f9 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 26 Sep 2019 16:24:52 -0700 Subject: [PATCH 0186/1772] witx crate: version 0.2.0 --- proposals/filesystem/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index f24cb7183..df1e60ec7 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.1.0" +version = "0.2.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From b2d0ded1bcd4717c1e017d9d01693f03741f7434 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 30 Sep 2019 11:27:43 -0700 Subject: [PATCH 0187/1772] wasi .witx: fixes to match current implementations (#100) * wasi_unstable_preview0.witx: fixes to match current implementations * old/wasi_unstable.witx: fixes to match current implementations * wasi_ephemeral_preview0.witx: fixes to match current implementations --- .../clocks/phases/ephemeral/witx/wasi_ephemeral_preview0.witx | 4 +++- proposals/clocks/phases/old/witx/wasi_unstable.witx | 4 +++- .../clocks/phases/unstable/witx/wasi_unstable_preview0.witx | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview0.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview0.witx index 2c85e5e69..b951ee3e8 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview0.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview0.witx @@ -37,6 +37,7 @@ ) ;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") + (result $error $errno_t) ;; The number of arguments. (result $argc $size_t) ;; The size of the argument string data. @@ -373,6 +374,7 @@ ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) + (param $flags $fdflags_t) (result $error $errno_t) ;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) @@ -468,7 +470,7 @@ ;; Temporarily yield execution of the calling thread. ;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "proc_sched_yield") + (@interface func (export "sched_yield") (result $error $errno_t) ) diff --git a/proposals/clocks/phases/old/witx/wasi_unstable.witx b/proposals/clocks/phases/old/witx/wasi_unstable.witx index f9586ff1e..8b7806dc7 100644 --- a/proposals/clocks/phases/old/witx/wasi_unstable.witx +++ b/proposals/clocks/phases/old/witx/wasi_unstable.witx @@ -40,6 +40,7 @@ ) ;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") + (result $error $errno_t) ;; The number of arguments. (result $argc $size_t) ;; The size of the argument string data. @@ -376,6 +377,7 @@ ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) + (param $flags $fdflags_t) (result $error $errno_t) ;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) @@ -471,7 +473,7 @@ ;; Temporarily yield execution of the calling thread. ;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "proc_sched_yield") + (@interface func (export "sched_yield") (result $error $errno_t) ) diff --git a/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx index 08efc87fa..7b4d1b241 100644 --- a/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx @@ -37,6 +37,7 @@ ) ;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") + (result $error $errno_t) ;; The number of arguments. (result $argc $size_t) ;; The size of the argument string data. @@ -373,6 +374,7 @@ ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) + (param $flags $fdflags_t) (result $error $errno_t) ;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) @@ -468,7 +470,7 @@ ;; Temporarily yield execution of the calling thread. ;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "proc_sched_yield") + (@interface func (export "sched_yield") (result $error $errno_t) ) From cff4956901719dbf54e6357dc5d126a433cb8c02 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 30 Sep 2019 11:27:43 -0700 Subject: [PATCH 0188/1772] wasi .witx: fixes to match current implementations (#100) * wasi_unstable_preview0.witx: fixes to match current implementations * old/wasi_unstable.witx: fixes to match current implementations * wasi_ephemeral_preview0.witx: fixes to match current implementations --- .../random/phases/ephemeral/witx/wasi_ephemeral_preview0.witx | 4 +++- proposals/random/phases/old/witx/wasi_unstable.witx | 4 +++- .../random/phases/unstable/witx/wasi_unstable_preview0.witx | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview0.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview0.witx index 2c85e5e69..b951ee3e8 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview0.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview0.witx @@ -37,6 +37,7 @@ ) ;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") + (result $error $errno_t) ;; The number of arguments. (result $argc $size_t) ;; The size of the argument string data. @@ -373,6 +374,7 @@ ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) + (param $flags $fdflags_t) (result $error $errno_t) ;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) @@ -468,7 +470,7 @@ ;; Temporarily yield execution of the calling thread. ;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "proc_sched_yield") + (@interface func (export "sched_yield") (result $error $errno_t) ) diff --git a/proposals/random/phases/old/witx/wasi_unstable.witx b/proposals/random/phases/old/witx/wasi_unstable.witx index f9586ff1e..8b7806dc7 100644 --- a/proposals/random/phases/old/witx/wasi_unstable.witx +++ b/proposals/random/phases/old/witx/wasi_unstable.witx @@ -40,6 +40,7 @@ ) ;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") + (result $error $errno_t) ;; The number of arguments. (result $argc $size_t) ;; The size of the argument string data. @@ -376,6 +377,7 @@ ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) + (param $flags $fdflags_t) (result $error $errno_t) ;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) @@ -471,7 +473,7 @@ ;; Temporarily yield execution of the calling thread. ;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "proc_sched_yield") + (@interface func (export "sched_yield") (result $error $errno_t) ) diff --git a/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx index 08efc87fa..7b4d1b241 100644 --- a/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx @@ -37,6 +37,7 @@ ) ;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") + (result $error $errno_t) ;; The number of arguments. (result $argc $size_t) ;; The size of the argument string data. @@ -373,6 +374,7 @@ ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) + (param $flags $fdflags_t) (result $error $errno_t) ;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) @@ -468,7 +470,7 @@ ;; Temporarily yield execution of the calling thread. ;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "proc_sched_yield") + (@interface func (export "sched_yield") (result $error $errno_t) ) From 4ab22d83b5650af17426792c652cfd5b589a8580 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 30 Sep 2019 11:27:43 -0700 Subject: [PATCH 0189/1772] wasi .witx: fixes to match current implementations (#100) * wasi_unstable_preview0.witx: fixes to match current implementations * old/wasi_unstable.witx: fixes to match current implementations * wasi_ephemeral_preview0.witx: fixes to match current implementations --- .../phases/ephemeral/witx/wasi_ephemeral_preview0.witx | 4 +++- proposals/filesystem/phases/old/witx/wasi_unstable.witx | 4 +++- .../phases/unstable/witx/wasi_unstable_preview0.witx | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview0.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview0.witx index 2c85e5e69..b951ee3e8 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview0.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview0.witx @@ -37,6 +37,7 @@ ) ;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") + (result $error $errno_t) ;; The number of arguments. (result $argc $size_t) ;; The size of the argument string data. @@ -373,6 +374,7 @@ ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) + (param $flags $fdflags_t) (result $error $errno_t) ;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) @@ -468,7 +470,7 @@ ;; Temporarily yield execution of the calling thread. ;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "proc_sched_yield") + (@interface func (export "sched_yield") (result $error $errno_t) ) diff --git a/proposals/filesystem/phases/old/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/witx/wasi_unstable.witx index f9586ff1e..8b7806dc7 100644 --- a/proposals/filesystem/phases/old/witx/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/witx/wasi_unstable.witx @@ -40,6 +40,7 @@ ) ;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") + (result $error $errno_t) ;; The number of arguments. (result $argc $size_t) ;; The size of the argument string data. @@ -376,6 +377,7 @@ ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) + (param $flags $fdflags_t) (result $error $errno_t) ;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) @@ -471,7 +473,7 @@ ;; Temporarily yield execution of the calling thread. ;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "proc_sched_yield") + (@interface func (export "sched_yield") (result $error $errno_t) ) diff --git a/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx index 08efc87fa..7b4d1b241 100644 --- a/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx @@ -37,6 +37,7 @@ ) ;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") + (result $error $errno_t) ;; The number of arguments. (result $argc $size_t) ;; The size of the argument string data. @@ -373,6 +374,7 @@ ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) + (param $flags $fdflags_t) (result $error $errno_t) ;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) @@ -468,7 +470,7 @@ ;; Temporarily yield execution of the calling thread. ;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "proc_sched_yield") + (@interface func (export "sched_yield") (result $error $errno_t) ) From af65e29f65e1da8cf88bfd9febb56b7ea3657247 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 1 Oct 2019 17:58:51 -0700 Subject: [PATCH 0190/1772] Post the in-person meeting to discuss HTTP APIs on 10-15. (#104) --- proposals/clocks/meetings/2019/WASI-10-15.md | 23 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 24 insertions(+) create mode 100644 proposals/clocks/meetings/2019/WASI-10-15.md diff --git a/proposals/clocks/meetings/2019/WASI-10-15.md b/proposals/clocks/meetings/2019/WASI-10-15.md new file mode 100644 index 000000000..1cd7d1258 --- /dev/null +++ b/proposals/clocks/meetings/2019/WASI-10-15.md @@ -0,0 +1,23 @@ +![WASI logo](/WASI.png) + +## Agenda for the October 15 in-person meeting of the WASI Subgroup + +- **Where**: 10355 N De Anza Blvd, Cupertino, CA 95014, USA +- **When**: October 15, 1:00pm PDT +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Agenda items + +The topic for this meeting is low-level WebAssembly APIs for +HTTP (servers and clients). + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 6d5887075..87354bb78 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -17,3 +17,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI August 30th video call](2019/WASI-08-30.md) * [WASI September 12th video call](2019/WASI-09-12.md) * [WASI September 25th video call](2019/WASI-09-25.md) + * [WASI October 15th in-person meeting](2019/WASI-10-15.md) From 4aec2187cc351939f293d72c763e3c231b154990 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 1 Oct 2019 17:58:51 -0700 Subject: [PATCH 0191/1772] Post the in-person meeting to discuss HTTP APIs on 10-15. (#104) --- proposals/random/meetings/2019/WASI-10-15.md | 23 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 24 insertions(+) create mode 100644 proposals/random/meetings/2019/WASI-10-15.md diff --git a/proposals/random/meetings/2019/WASI-10-15.md b/proposals/random/meetings/2019/WASI-10-15.md new file mode 100644 index 000000000..1cd7d1258 --- /dev/null +++ b/proposals/random/meetings/2019/WASI-10-15.md @@ -0,0 +1,23 @@ +![WASI logo](/WASI.png) + +## Agenda for the October 15 in-person meeting of the WASI Subgroup + +- **Where**: 10355 N De Anza Blvd, Cupertino, CA 95014, USA +- **When**: October 15, 1:00pm PDT +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Agenda items + +The topic for this meeting is low-level WebAssembly APIs for +HTTP (servers and clients). + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 6d5887075..87354bb78 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -17,3 +17,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI August 30th video call](2019/WASI-08-30.md) * [WASI September 12th video call](2019/WASI-09-12.md) * [WASI September 25th video call](2019/WASI-09-25.md) + * [WASI October 15th in-person meeting](2019/WASI-10-15.md) From 63bba1fb6c4de920c5ac9564bb03d2efaaf735f3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 1 Oct 2019 17:58:51 -0700 Subject: [PATCH 0192/1772] Post the in-person meeting to discuss HTTP APIs on 10-15. (#104) --- .../filesystem/meetings/2019/WASI-10-15.md | 23 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 24 insertions(+) create mode 100644 proposals/filesystem/meetings/2019/WASI-10-15.md diff --git a/proposals/filesystem/meetings/2019/WASI-10-15.md b/proposals/filesystem/meetings/2019/WASI-10-15.md new file mode 100644 index 000000000..1cd7d1258 --- /dev/null +++ b/proposals/filesystem/meetings/2019/WASI-10-15.md @@ -0,0 +1,23 @@ +![WASI logo](/WASI.png) + +## Agenda for the October 15 in-person meeting of the WASI Subgroup + +- **Where**: 10355 N De Anza Blvd, Cupertino, CA 95014, USA +- **When**: October 15, 1:00pm PDT +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Agenda items + +The topic for this meeting is low-level WebAssembly APIs for +HTTP (servers and clients). + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 6d5887075..87354bb78 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -17,3 +17,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI August 30th video call](2019/WASI-08-30.md) * [WASI September 12th video call](2019/WASI-09-12.md) * [WASI September 25th video call](2019/WASI-09-25.md) + * [WASI October 15th in-person meeting](2019/WASI-10-15.md) From 5c215f7160dd91e39097dc8b5cabf7d34cabcaff Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 2 Oct 2019 09:13:40 -0700 Subject: [PATCH 0193/1772] Remove the "data" builtin type. (#102) * Remove the "data" builtin type. "data" isn't currently used by any witx files; we're using `pointer` and `const_pointer` with explicit lengths instead, as these handle mutable buffers in a much simpler way. * Remove "data" from `BuiltinType::starts_parsing` too. * Remove one more use of `BuiltinType::Data`. --- proposals/clocks/tools/witx/src/parser.rs | 3 --- proposals/clocks/tools/witx/src/render.rs | 1 - 2 files changed, 4 deletions(-) diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 1f627b27c..d12d643ed 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -63,7 +63,6 @@ macro_rules! id { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum BuiltinType { String, - Data, U8, U16, U32, @@ -80,7 +79,6 @@ impl BuiltinType { pub fn starts_parsing(sexpr: &SExpr) -> bool { match sexpr { SExpr::Word("string", _) - | SExpr::Word("data", _) | SExpr::Word("u8", _) | SExpr::Word("u16", _) | SExpr::Word("u32", _) @@ -97,7 +95,6 @@ impl BuiltinType { pub fn parse(sexpr: &SExpr) -> Result { match sexpr { SExpr::Word("string", _loc) => Ok(BuiltinType::String), - SExpr::Word("data", _loc) => Ok(BuiltinType::Data), SExpr::Word("u8", _loc) => Ok(BuiltinType::U8), SExpr::Word("u16", _loc) => Ok(BuiltinType::U16), SExpr::Word("u32", _loc) => Ok(BuiltinType::U32), diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 912d59508..fa6d86f35 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -72,7 +72,6 @@ impl Render for BuiltinType { fn to_sexpr(&self) -> SExpr { match self { BuiltinType::String => SExpr::word("string"), - BuiltinType::Data => SExpr::word("data"), BuiltinType::U8 => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), BuiltinType::U32 => SExpr::word("u32"), From 25172c06ef34d44873ae180ed8bfb6f7082a87bd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 2 Oct 2019 09:13:40 -0700 Subject: [PATCH 0194/1772] Remove the "data" builtin type. (#102) * Remove the "data" builtin type. "data" isn't currently used by any witx files; we're using `pointer` and `const_pointer` with explicit lengths instead, as these handle mutable buffers in a much simpler way. * Remove "data" from `BuiltinType::starts_parsing` too. * Remove one more use of `BuiltinType::Data`. --- proposals/random/tools/witx/src/parser.rs | 3 --- proposals/random/tools/witx/src/render.rs | 1 - 2 files changed, 4 deletions(-) diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 1f627b27c..d12d643ed 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -63,7 +63,6 @@ macro_rules! id { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum BuiltinType { String, - Data, U8, U16, U32, @@ -80,7 +79,6 @@ impl BuiltinType { pub fn starts_parsing(sexpr: &SExpr) -> bool { match sexpr { SExpr::Word("string", _) - | SExpr::Word("data", _) | SExpr::Word("u8", _) | SExpr::Word("u16", _) | SExpr::Word("u32", _) @@ -97,7 +95,6 @@ impl BuiltinType { pub fn parse(sexpr: &SExpr) -> Result { match sexpr { SExpr::Word("string", _loc) => Ok(BuiltinType::String), - SExpr::Word("data", _loc) => Ok(BuiltinType::Data), SExpr::Word("u8", _loc) => Ok(BuiltinType::U8), SExpr::Word("u16", _loc) => Ok(BuiltinType::U16), SExpr::Word("u32", _loc) => Ok(BuiltinType::U32), diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 912d59508..fa6d86f35 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -72,7 +72,6 @@ impl Render for BuiltinType { fn to_sexpr(&self) -> SExpr { match self { BuiltinType::String => SExpr::word("string"), - BuiltinType::Data => SExpr::word("data"), BuiltinType::U8 => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), BuiltinType::U32 => SExpr::word("u32"), From 59b07b5552b39d86acd8f0ecb4fa2f6263745fe1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 2 Oct 2019 09:13:40 -0700 Subject: [PATCH 0195/1772] Remove the "data" builtin type. (#102) * Remove the "data" builtin type. "data" isn't currently used by any witx files; we're using `pointer` and `const_pointer` with explicit lengths instead, as these handle mutable buffers in a much simpler way. * Remove "data" from `BuiltinType::starts_parsing` too. * Remove one more use of `BuiltinType::Data`. --- proposals/filesystem/tools/witx/src/parser.rs | 3 --- proposals/filesystem/tools/witx/src/render.rs | 1 - 2 files changed, 4 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 1f627b27c..d12d643ed 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -63,7 +63,6 @@ macro_rules! id { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum BuiltinType { String, - Data, U8, U16, U32, @@ -80,7 +79,6 @@ impl BuiltinType { pub fn starts_parsing(sexpr: &SExpr) -> bool { match sexpr { SExpr::Word("string", _) - | SExpr::Word("data", _) | SExpr::Word("u8", _) | SExpr::Word("u16", _) | SExpr::Word("u32", _) @@ -97,7 +95,6 @@ impl BuiltinType { pub fn parse(sexpr: &SExpr) -> Result { match sexpr { SExpr::Word("string", _loc) => Ok(BuiltinType::String), - SExpr::Word("data", _loc) => Ok(BuiltinType::Data), SExpr::Word("u8", _loc) => Ok(BuiltinType::U8), SExpr::Word("u16", _loc) => Ok(BuiltinType::U16), SExpr::Word("u32", _loc) => Ok(BuiltinType::U32), diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 912d59508..fa6d86f35 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -72,7 +72,6 @@ impl Render for BuiltinType { fn to_sexpr(&self) -> SExpr { match self { BuiltinType::String => SExpr::word("string"), - BuiltinType::Data => SExpr::word("data"), BuiltinType::U8 => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), BuiltinType::U32 => SExpr::word("u32"), From e23700a5eb0e1b61befcba91f835fcc9baf09efb Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 2 Oct 2019 12:20:15 -0700 Subject: [PATCH 0196/1772] witx crate: calculate module type signature of an interface function (#101) * witx crate: fix equality impl for document, module dan pointed this out in the review for PR #96 but I somehow lost the commit in a rebase. * witx crate: calculate module type signature of an interface func * witx crate: rename moduletype to core / WebAssembly type --- proposals/clocks/tools/witx/src/ast.rs | 103 ++++++----- proposals/clocks/tools/witx/src/coretypes.rs | 176 +++++++++++++++++++ proposals/clocks/tools/witx/src/lib.rs | 9 +- proposals/clocks/tools/witx/src/validate.rs | 33 +++- 4 files changed, 265 insertions(+), 56 deletions(-) create mode 100644 proposals/clocks/tools/witx/src/coretypes.rs diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 3713b3dd9..62d5bf502 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -57,28 +57,9 @@ impl Document { impl PartialEq for Document { fn eq(&self, rhs: &Document) -> bool { - if self.definitions.len() != rhs.definitions.len() { - return false; - } - for d in self.datatypes() { - if let Some(d_rhs) = rhs.datatype(&d.name) { - if d != d_rhs { - return false; - } - } else { - return false; - } - } - for m in self.modules() { - if let Some(m_rhs) = rhs.module(&m.name) { - if m != m_rhs { - return false; - } - } else { - return false; - } - } - true + // For equality, we don't care about the ordering of definitions, + // so we only need to check that the entries map is equal + self.entries == rhs.entries } } impl Eq for Document {} @@ -104,6 +85,28 @@ impl Entry { } } +impl PartialEq for Entry { + fn eq(&self, rhs: &Entry) -> bool { + match (self, rhs) { + (Entry::Datatype(d), Entry::Datatype(d_rhs)) => { + d.upgrade() + .expect("possible to upgrade entry when part of document") + == d_rhs + .upgrade() + .expect("possible to upgrade entry when part of document") + } + (Entry::Module(m), Entry::Module(m_rhs)) => { + m.upgrade() + .expect("possible to upgrade entry when part of document") + == m_rhs + .upgrade() + .expect("possible to upgrade entry when part of document") + } + _ => false, + } + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum DatatypeIdent { Builtin(BuiltinType), @@ -134,7 +137,7 @@ pub struct AliasDatatype { pub to: DatatypeIdent, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum IntRepr { U8, U16, @@ -227,28 +230,9 @@ impl Module { impl PartialEq for Module { fn eq(&self, rhs: &Module) -> bool { - if self.definitions.len() != rhs.definitions.len() { - return false; - } - for i in self.imports() { - if let Some(i_rhs) = rhs.import(&i.name) { - if i != i_rhs { - return false; - } - } else { - return false; - } - } - for f in self.funcs() { - if let Some(f_rhs) = rhs.func(&f.name) { - if f != f_rhs { - return false; - } - } else { - return false; - } - } - true + // For equality, we don't care about the ordering of definitions, + // so we only need to check that the entries map is equal + self.entries == rhs.entries } } impl Eq for Module {} @@ -265,6 +249,28 @@ pub enum ModuleEntry { Func(Weak), } +impl PartialEq for ModuleEntry { + fn eq(&self, rhs: &ModuleEntry) -> bool { + match (self, rhs) { + (ModuleEntry::Import(i), ModuleEntry::Import(i_rhs)) => { + i.upgrade() + .expect("always possible to upgrade moduleentry when part of module") + == i_rhs + .upgrade() + .expect("always possible to upgrade moduleentry when part of module") + } + (ModuleEntry::Func(i), ModuleEntry::Func(i_rhs)) => { + i.upgrade() + .expect("always possible to upgrade moduleentry when part of module") + == i_rhs + .upgrade() + .expect("always possible to upgrade moduleentry when part of module") + } + _ => false, + } + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct ModuleImport { pub name: Id, @@ -287,4 +293,11 @@ pub struct InterfaceFunc { pub struct InterfaceFuncParam { pub name: Id, pub type_: DatatypeIdent, + pub position: InterfaceFuncParamPosition, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum InterfaceFuncParamPosition { + Param(usize), + Result(usize), } diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs new file mode 100644 index 000000000..bcb9b34af --- /dev/null +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -0,0 +1,176 @@ +use crate::{ + BuiltinType, DatatypeIdent, DatatypeVariant, IntRepr, InterfaceFunc, InterfaceFuncParam, +}; + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +/// Enumerates the types permitted for function arguments in the WebAssembly spec +pub enum AtomType { + I32, + I64, + F32, + F64, +} + +impl From for AtomType { + fn from(i: IntRepr) -> AtomType { + match i { + IntRepr::U8 | IntRepr::U16 | IntRepr::U32 => AtomType::I32, + IntRepr::U64 => AtomType::I64, + } + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +/// Enumerates the strategies which may be used to pass a datatype as an argument +pub enum DatatypePassedBy { + /// Pass by value specifies the AtomType used to represent that value + Value(AtomType), + /// Pass by a pointer into linear memory + Pointer, + /// Pass by a pointer and length pair, into linear memory + PointerLengthPair, +} + +impl DatatypeIdent { + /// Determine the simplest strategy by which a type may be passed. Value always preferred over + /// Pointer. + pub fn passed_by(&self) -> DatatypePassedBy { + match &self { + DatatypeIdent::Builtin(b) => match b { + BuiltinType::String | BuiltinType::Data => DatatypePassedBy::PointerLengthPair, + BuiltinType::U8 + | BuiltinType::U16 + | BuiltinType::U32 + | BuiltinType::S8 + | BuiltinType::S16 + | BuiltinType::S32 => DatatypePassedBy::Value(AtomType::I32), + BuiltinType::U64 | BuiltinType::S64 => DatatypePassedBy::Value(AtomType::I64), + BuiltinType::F32 => DatatypePassedBy::Value(AtomType::F32), + BuiltinType::F64 => DatatypePassedBy::Value(AtomType::F64), + }, + DatatypeIdent::Array { .. } => DatatypePassedBy::PointerLengthPair, + DatatypeIdent::Pointer { .. } | DatatypeIdent::ConstPointer { .. } => { + DatatypePassedBy::Value(AtomType::I32) + } + DatatypeIdent::Ident(i) => match &i.variant { + DatatypeVariant::Alias(a) => a.to.passed_by(), + DatatypeVariant::Enum(e) => DatatypePassedBy::Value(e.repr.into()), + DatatypeVariant::Flags(f) => DatatypePassedBy::Value(f.repr.into()), + DatatypeVariant::Struct { .. } | DatatypeVariant::Union { .. } => { + DatatypePassedBy::Pointer + } + }, + } + } +} + +/// A parameter in the WebAssembly type of a function. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CoreParamType { + /// The interface function parameter to which this + pub param: InterfaceFuncParam, + /// The relationship of the WebAssembly parameter to the function interface parameter + pub signifies: CoreParamSignifies, +} + +impl CoreParamType { + /// Representation of the WebAssembly parameter. This is the type that will appear + /// in the function's WebAssembly type signature. + pub fn repr(&self) -> AtomType { + self.signifies.repr() + } +} + +/// Enumerates the sort of relationship an WebAssembly parameter to an interface function +/// parameter. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum CoreParamSignifies { + /// Core type represents the value using an AtomType + Value(AtomType), + /// Core type represents a pointer into linear memory + PointerTo, + /// Core type represents a length of a region of linear memory + LengthOf, +} + +impl CoreParamSignifies { + /// Representation of the WebAssembly parameter. + pub fn repr(&self) -> AtomType { + match self { + CoreParamSignifies::Value(a) => *a, + CoreParamSignifies::PointerTo | CoreParamSignifies::LengthOf => AtomType::I32, + } + } +} + +impl InterfaceFuncParam { + /// Gives the WebAssembly type that corresponds to passing this interface func parameter by value. + /// Not all types can be passed by value: those which cannot return None + pub fn pass_by_value(&self) -> Option { + match self.type_.passed_by() { + DatatypePassedBy::Value(atom) => Some(CoreParamType { + signifies: CoreParamSignifies::Value(atom), + param: self.clone(), + }), + DatatypePassedBy::Pointer | DatatypePassedBy::PointerLengthPair => None, + } + } + + /// Gives the WebAssembly types that correspond to passing this interface func parameter + /// by reference. Some types are passed by reference using a single pointer, others + /// require both a pointer and length. + pub fn pass_by_reference(&self) -> Vec { + match self.type_.passed_by() { + DatatypePassedBy::Value(_) | DatatypePassedBy::Pointer => vec![CoreParamType { + signifies: CoreParamSignifies::PointerTo, + param: self.clone(), + }], + DatatypePassedBy::PointerLengthPair => vec![ + CoreParamType { + signifies: CoreParamSignifies::PointerTo, + param: self.clone(), + }, + CoreParamType { + signifies: CoreParamSignifies::LengthOf, + param: self.clone(), + }, + ], + } + } +} + +/// Describes the WebAssembly signature of a function +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CoreFuncType { + pub args: Vec, + pub ret: Option, +} + +impl InterfaceFunc { + /// Get the WebAssembly type signature for this interface function + pub fn core_type(&self) -> CoreFuncType { + let mut results = self.results.iter(); + // The ret value is the first result (if there is one), passed + // by value. + let ret = results.next().map(|param| { + param + .pass_by_value() + .expect("validation ensures first result can be passed by value") + }); + let args = self + .params + .iter() + .flat_map(|param| { + // interface function parameters are passed by value if possible, + // and fall back on passing by reference. + param + .pass_by_value() + .map(|ptype| vec![ptype]) + .unwrap_or_else(|| param.pass_by_reference()) + }) + // Then, the remaining results are passed by reference. + .chain(results.flat_map(|param| param.pass_by_reference())) + .collect(); + CoreFuncType { args, ret } + } +} diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 34876cf7b..af315a9df 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -1,5 +1,7 @@ /// Types describing a validated witx document mod ast; +/// Map witx types to core (wasm standard) types +mod coretypes; /// Interface for filesystem or mock IO mod io; /// Lexer text into tokens @@ -17,10 +19,11 @@ mod validate; pub use ast::{ AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, Module, - ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, - UnionDatatype, UnionVariant, + Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, + InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, ModuleImport, + ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; +pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; pub use io::{Filesystem, MockFs, WitxIo}; pub use lexer::LexError; pub use parser::{DeclSyntax, ParseError}; diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 0fecf1178..526409e62 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -4,10 +4,11 @@ use crate::{ DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, IdentSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, - AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, Location, - Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, - StructMember, UnionDatatype, UnionVariant, + AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, + Definition, Document, Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, + InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, + ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, + UnionVariant, }; use failure::Fail; use std::collections::HashMap; @@ -40,6 +41,8 @@ pub enum ValidationError { repr: BuiltinType, location: Location, }, + #[fail(display = "First result type must be pass-by-value")] + InvalidFirstResultType { location: Location }, } impl ValidationError { @@ -49,7 +52,8 @@ impl ValidationError { UnknownName { location, .. } | WrongKindName { location, .. } | Recursive { location, .. } - | InvalidRepr { location, .. } => { + | InvalidRepr { location, .. } + | InvalidFirstResultType { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } NameAlreadyExists { @@ -361,20 +365,33 @@ impl<'a> ModuleValidation<'a> { let params = syntax .params .iter() - .map(|f| { + .enumerate() + .map(|(ix, f)| { Ok(InterfaceFuncParam { name: argnames.introduce(&f.name)?, type_: self.doc.validate_datatype_ident(&f.type_)?, + position: InterfaceFuncParamPosition::Param(ix), }) }) .collect::, _>>()?; let results = syntax .results .iter() - .map(|f| { + .enumerate() + .map(|(ix, f)| { + let type_ = self.doc.validate_datatype_ident(&f.type_)?; + if ix == 0 { + match type_.passed_by() { + DatatypePassedBy::Value(_) => {} + _ => Err(ValidationError::InvalidFirstResultType { + location: f.name.location.clone(), + })?, + } + } Ok(InterfaceFuncParam { name: argnames.introduce(&f.name)?, - type_: self.doc.validate_datatype_ident(&f.type_)?, + type_, + position: InterfaceFuncParamPosition::Result(ix), }) }) .collect::, _>>()?; From 54bbd345d35113e0102387702c31be3b34896755 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 2 Oct 2019 12:20:15 -0700 Subject: [PATCH 0197/1772] witx crate: calculate module type signature of an interface function (#101) * witx crate: fix equality impl for document, module dan pointed this out in the review for PR #96 but I somehow lost the commit in a rebase. * witx crate: calculate module type signature of an interface func * witx crate: rename moduletype to core / WebAssembly type --- proposals/random/tools/witx/src/ast.rs | 103 ++++++----- proposals/random/tools/witx/src/coretypes.rs | 176 +++++++++++++++++++ proposals/random/tools/witx/src/lib.rs | 9 +- proposals/random/tools/witx/src/validate.rs | 33 +++- 4 files changed, 265 insertions(+), 56 deletions(-) create mode 100644 proposals/random/tools/witx/src/coretypes.rs diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 3713b3dd9..62d5bf502 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -57,28 +57,9 @@ impl Document { impl PartialEq for Document { fn eq(&self, rhs: &Document) -> bool { - if self.definitions.len() != rhs.definitions.len() { - return false; - } - for d in self.datatypes() { - if let Some(d_rhs) = rhs.datatype(&d.name) { - if d != d_rhs { - return false; - } - } else { - return false; - } - } - for m in self.modules() { - if let Some(m_rhs) = rhs.module(&m.name) { - if m != m_rhs { - return false; - } - } else { - return false; - } - } - true + // For equality, we don't care about the ordering of definitions, + // so we only need to check that the entries map is equal + self.entries == rhs.entries } } impl Eq for Document {} @@ -104,6 +85,28 @@ impl Entry { } } +impl PartialEq for Entry { + fn eq(&self, rhs: &Entry) -> bool { + match (self, rhs) { + (Entry::Datatype(d), Entry::Datatype(d_rhs)) => { + d.upgrade() + .expect("possible to upgrade entry when part of document") + == d_rhs + .upgrade() + .expect("possible to upgrade entry when part of document") + } + (Entry::Module(m), Entry::Module(m_rhs)) => { + m.upgrade() + .expect("possible to upgrade entry when part of document") + == m_rhs + .upgrade() + .expect("possible to upgrade entry when part of document") + } + _ => false, + } + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum DatatypeIdent { Builtin(BuiltinType), @@ -134,7 +137,7 @@ pub struct AliasDatatype { pub to: DatatypeIdent, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum IntRepr { U8, U16, @@ -227,28 +230,9 @@ impl Module { impl PartialEq for Module { fn eq(&self, rhs: &Module) -> bool { - if self.definitions.len() != rhs.definitions.len() { - return false; - } - for i in self.imports() { - if let Some(i_rhs) = rhs.import(&i.name) { - if i != i_rhs { - return false; - } - } else { - return false; - } - } - for f in self.funcs() { - if let Some(f_rhs) = rhs.func(&f.name) { - if f != f_rhs { - return false; - } - } else { - return false; - } - } - true + // For equality, we don't care about the ordering of definitions, + // so we only need to check that the entries map is equal + self.entries == rhs.entries } } impl Eq for Module {} @@ -265,6 +249,28 @@ pub enum ModuleEntry { Func(Weak), } +impl PartialEq for ModuleEntry { + fn eq(&self, rhs: &ModuleEntry) -> bool { + match (self, rhs) { + (ModuleEntry::Import(i), ModuleEntry::Import(i_rhs)) => { + i.upgrade() + .expect("always possible to upgrade moduleentry when part of module") + == i_rhs + .upgrade() + .expect("always possible to upgrade moduleentry when part of module") + } + (ModuleEntry::Func(i), ModuleEntry::Func(i_rhs)) => { + i.upgrade() + .expect("always possible to upgrade moduleentry when part of module") + == i_rhs + .upgrade() + .expect("always possible to upgrade moduleentry when part of module") + } + _ => false, + } + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct ModuleImport { pub name: Id, @@ -287,4 +293,11 @@ pub struct InterfaceFunc { pub struct InterfaceFuncParam { pub name: Id, pub type_: DatatypeIdent, + pub position: InterfaceFuncParamPosition, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum InterfaceFuncParamPosition { + Param(usize), + Result(usize), } diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs new file mode 100644 index 000000000..bcb9b34af --- /dev/null +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -0,0 +1,176 @@ +use crate::{ + BuiltinType, DatatypeIdent, DatatypeVariant, IntRepr, InterfaceFunc, InterfaceFuncParam, +}; + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +/// Enumerates the types permitted for function arguments in the WebAssembly spec +pub enum AtomType { + I32, + I64, + F32, + F64, +} + +impl From for AtomType { + fn from(i: IntRepr) -> AtomType { + match i { + IntRepr::U8 | IntRepr::U16 | IntRepr::U32 => AtomType::I32, + IntRepr::U64 => AtomType::I64, + } + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +/// Enumerates the strategies which may be used to pass a datatype as an argument +pub enum DatatypePassedBy { + /// Pass by value specifies the AtomType used to represent that value + Value(AtomType), + /// Pass by a pointer into linear memory + Pointer, + /// Pass by a pointer and length pair, into linear memory + PointerLengthPair, +} + +impl DatatypeIdent { + /// Determine the simplest strategy by which a type may be passed. Value always preferred over + /// Pointer. + pub fn passed_by(&self) -> DatatypePassedBy { + match &self { + DatatypeIdent::Builtin(b) => match b { + BuiltinType::String | BuiltinType::Data => DatatypePassedBy::PointerLengthPair, + BuiltinType::U8 + | BuiltinType::U16 + | BuiltinType::U32 + | BuiltinType::S8 + | BuiltinType::S16 + | BuiltinType::S32 => DatatypePassedBy::Value(AtomType::I32), + BuiltinType::U64 | BuiltinType::S64 => DatatypePassedBy::Value(AtomType::I64), + BuiltinType::F32 => DatatypePassedBy::Value(AtomType::F32), + BuiltinType::F64 => DatatypePassedBy::Value(AtomType::F64), + }, + DatatypeIdent::Array { .. } => DatatypePassedBy::PointerLengthPair, + DatatypeIdent::Pointer { .. } | DatatypeIdent::ConstPointer { .. } => { + DatatypePassedBy::Value(AtomType::I32) + } + DatatypeIdent::Ident(i) => match &i.variant { + DatatypeVariant::Alias(a) => a.to.passed_by(), + DatatypeVariant::Enum(e) => DatatypePassedBy::Value(e.repr.into()), + DatatypeVariant::Flags(f) => DatatypePassedBy::Value(f.repr.into()), + DatatypeVariant::Struct { .. } | DatatypeVariant::Union { .. } => { + DatatypePassedBy::Pointer + } + }, + } + } +} + +/// A parameter in the WebAssembly type of a function. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CoreParamType { + /// The interface function parameter to which this + pub param: InterfaceFuncParam, + /// The relationship of the WebAssembly parameter to the function interface parameter + pub signifies: CoreParamSignifies, +} + +impl CoreParamType { + /// Representation of the WebAssembly parameter. This is the type that will appear + /// in the function's WebAssembly type signature. + pub fn repr(&self) -> AtomType { + self.signifies.repr() + } +} + +/// Enumerates the sort of relationship an WebAssembly parameter to an interface function +/// parameter. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum CoreParamSignifies { + /// Core type represents the value using an AtomType + Value(AtomType), + /// Core type represents a pointer into linear memory + PointerTo, + /// Core type represents a length of a region of linear memory + LengthOf, +} + +impl CoreParamSignifies { + /// Representation of the WebAssembly parameter. + pub fn repr(&self) -> AtomType { + match self { + CoreParamSignifies::Value(a) => *a, + CoreParamSignifies::PointerTo | CoreParamSignifies::LengthOf => AtomType::I32, + } + } +} + +impl InterfaceFuncParam { + /// Gives the WebAssembly type that corresponds to passing this interface func parameter by value. + /// Not all types can be passed by value: those which cannot return None + pub fn pass_by_value(&self) -> Option { + match self.type_.passed_by() { + DatatypePassedBy::Value(atom) => Some(CoreParamType { + signifies: CoreParamSignifies::Value(atom), + param: self.clone(), + }), + DatatypePassedBy::Pointer | DatatypePassedBy::PointerLengthPair => None, + } + } + + /// Gives the WebAssembly types that correspond to passing this interface func parameter + /// by reference. Some types are passed by reference using a single pointer, others + /// require both a pointer and length. + pub fn pass_by_reference(&self) -> Vec { + match self.type_.passed_by() { + DatatypePassedBy::Value(_) | DatatypePassedBy::Pointer => vec![CoreParamType { + signifies: CoreParamSignifies::PointerTo, + param: self.clone(), + }], + DatatypePassedBy::PointerLengthPair => vec![ + CoreParamType { + signifies: CoreParamSignifies::PointerTo, + param: self.clone(), + }, + CoreParamType { + signifies: CoreParamSignifies::LengthOf, + param: self.clone(), + }, + ], + } + } +} + +/// Describes the WebAssembly signature of a function +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CoreFuncType { + pub args: Vec, + pub ret: Option, +} + +impl InterfaceFunc { + /// Get the WebAssembly type signature for this interface function + pub fn core_type(&self) -> CoreFuncType { + let mut results = self.results.iter(); + // The ret value is the first result (if there is one), passed + // by value. + let ret = results.next().map(|param| { + param + .pass_by_value() + .expect("validation ensures first result can be passed by value") + }); + let args = self + .params + .iter() + .flat_map(|param| { + // interface function parameters are passed by value if possible, + // and fall back on passing by reference. + param + .pass_by_value() + .map(|ptype| vec![ptype]) + .unwrap_or_else(|| param.pass_by_reference()) + }) + // Then, the remaining results are passed by reference. + .chain(results.flat_map(|param| param.pass_by_reference())) + .collect(); + CoreFuncType { args, ret } + } +} diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 34876cf7b..af315a9df 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -1,5 +1,7 @@ /// Types describing a validated witx document mod ast; +/// Map witx types to core (wasm standard) types +mod coretypes; /// Interface for filesystem or mock IO mod io; /// Lexer text into tokens @@ -17,10 +19,11 @@ mod validate; pub use ast::{ AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, Module, - ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, - UnionDatatype, UnionVariant, + Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, + InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, ModuleImport, + ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; +pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; pub use io::{Filesystem, MockFs, WitxIo}; pub use lexer::LexError; pub use parser::{DeclSyntax, ParseError}; diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 0fecf1178..526409e62 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -4,10 +4,11 @@ use crate::{ DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, IdentSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, - AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, Location, - Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, - StructMember, UnionDatatype, UnionVariant, + AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, + Definition, Document, Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, + InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, + ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, + UnionVariant, }; use failure::Fail; use std::collections::HashMap; @@ -40,6 +41,8 @@ pub enum ValidationError { repr: BuiltinType, location: Location, }, + #[fail(display = "First result type must be pass-by-value")] + InvalidFirstResultType { location: Location }, } impl ValidationError { @@ -49,7 +52,8 @@ impl ValidationError { UnknownName { location, .. } | WrongKindName { location, .. } | Recursive { location, .. } - | InvalidRepr { location, .. } => { + | InvalidRepr { location, .. } + | InvalidFirstResultType { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } NameAlreadyExists { @@ -361,20 +365,33 @@ impl<'a> ModuleValidation<'a> { let params = syntax .params .iter() - .map(|f| { + .enumerate() + .map(|(ix, f)| { Ok(InterfaceFuncParam { name: argnames.introduce(&f.name)?, type_: self.doc.validate_datatype_ident(&f.type_)?, + position: InterfaceFuncParamPosition::Param(ix), }) }) .collect::, _>>()?; let results = syntax .results .iter() - .map(|f| { + .enumerate() + .map(|(ix, f)| { + let type_ = self.doc.validate_datatype_ident(&f.type_)?; + if ix == 0 { + match type_.passed_by() { + DatatypePassedBy::Value(_) => {} + _ => Err(ValidationError::InvalidFirstResultType { + location: f.name.location.clone(), + })?, + } + } Ok(InterfaceFuncParam { name: argnames.introduce(&f.name)?, - type_: self.doc.validate_datatype_ident(&f.type_)?, + type_, + position: InterfaceFuncParamPosition::Result(ix), }) }) .collect::, _>>()?; From 756db73a4912f395b34e3eae916404c1c01ef58b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 2 Oct 2019 12:20:15 -0700 Subject: [PATCH 0198/1772] witx crate: calculate module type signature of an interface function (#101) * witx crate: fix equality impl for document, module dan pointed this out in the review for PR #96 but I somehow lost the commit in a rebase. * witx crate: calculate module type signature of an interface func * witx crate: rename moduletype to core / WebAssembly type --- proposals/filesystem/tools/witx/src/ast.rs | 103 +++++----- .../filesystem/tools/witx/src/coretypes.rs | 176 ++++++++++++++++++ proposals/filesystem/tools/witx/src/lib.rs | 9 +- .../filesystem/tools/witx/src/validate.rs | 33 +++- 4 files changed, 265 insertions(+), 56 deletions(-) create mode 100644 proposals/filesystem/tools/witx/src/coretypes.rs diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 3713b3dd9..62d5bf502 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -57,28 +57,9 @@ impl Document { impl PartialEq for Document { fn eq(&self, rhs: &Document) -> bool { - if self.definitions.len() != rhs.definitions.len() { - return false; - } - for d in self.datatypes() { - if let Some(d_rhs) = rhs.datatype(&d.name) { - if d != d_rhs { - return false; - } - } else { - return false; - } - } - for m in self.modules() { - if let Some(m_rhs) = rhs.module(&m.name) { - if m != m_rhs { - return false; - } - } else { - return false; - } - } - true + // For equality, we don't care about the ordering of definitions, + // so we only need to check that the entries map is equal + self.entries == rhs.entries } } impl Eq for Document {} @@ -104,6 +85,28 @@ impl Entry { } } +impl PartialEq for Entry { + fn eq(&self, rhs: &Entry) -> bool { + match (self, rhs) { + (Entry::Datatype(d), Entry::Datatype(d_rhs)) => { + d.upgrade() + .expect("possible to upgrade entry when part of document") + == d_rhs + .upgrade() + .expect("possible to upgrade entry when part of document") + } + (Entry::Module(m), Entry::Module(m_rhs)) => { + m.upgrade() + .expect("possible to upgrade entry when part of document") + == m_rhs + .upgrade() + .expect("possible to upgrade entry when part of document") + } + _ => false, + } + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum DatatypeIdent { Builtin(BuiltinType), @@ -134,7 +137,7 @@ pub struct AliasDatatype { pub to: DatatypeIdent, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum IntRepr { U8, U16, @@ -227,28 +230,9 @@ impl Module { impl PartialEq for Module { fn eq(&self, rhs: &Module) -> bool { - if self.definitions.len() != rhs.definitions.len() { - return false; - } - for i in self.imports() { - if let Some(i_rhs) = rhs.import(&i.name) { - if i != i_rhs { - return false; - } - } else { - return false; - } - } - for f in self.funcs() { - if let Some(f_rhs) = rhs.func(&f.name) { - if f != f_rhs { - return false; - } - } else { - return false; - } - } - true + // For equality, we don't care about the ordering of definitions, + // so we only need to check that the entries map is equal + self.entries == rhs.entries } } impl Eq for Module {} @@ -265,6 +249,28 @@ pub enum ModuleEntry { Func(Weak), } +impl PartialEq for ModuleEntry { + fn eq(&self, rhs: &ModuleEntry) -> bool { + match (self, rhs) { + (ModuleEntry::Import(i), ModuleEntry::Import(i_rhs)) => { + i.upgrade() + .expect("always possible to upgrade moduleentry when part of module") + == i_rhs + .upgrade() + .expect("always possible to upgrade moduleentry when part of module") + } + (ModuleEntry::Func(i), ModuleEntry::Func(i_rhs)) => { + i.upgrade() + .expect("always possible to upgrade moduleentry when part of module") + == i_rhs + .upgrade() + .expect("always possible to upgrade moduleentry when part of module") + } + _ => false, + } + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct ModuleImport { pub name: Id, @@ -287,4 +293,11 @@ pub struct InterfaceFunc { pub struct InterfaceFuncParam { pub name: Id, pub type_: DatatypeIdent, + pub position: InterfaceFuncParamPosition, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum InterfaceFuncParamPosition { + Param(usize), + Result(usize), } diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs new file mode 100644 index 000000000..bcb9b34af --- /dev/null +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -0,0 +1,176 @@ +use crate::{ + BuiltinType, DatatypeIdent, DatatypeVariant, IntRepr, InterfaceFunc, InterfaceFuncParam, +}; + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +/// Enumerates the types permitted for function arguments in the WebAssembly spec +pub enum AtomType { + I32, + I64, + F32, + F64, +} + +impl From for AtomType { + fn from(i: IntRepr) -> AtomType { + match i { + IntRepr::U8 | IntRepr::U16 | IntRepr::U32 => AtomType::I32, + IntRepr::U64 => AtomType::I64, + } + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +/// Enumerates the strategies which may be used to pass a datatype as an argument +pub enum DatatypePassedBy { + /// Pass by value specifies the AtomType used to represent that value + Value(AtomType), + /// Pass by a pointer into linear memory + Pointer, + /// Pass by a pointer and length pair, into linear memory + PointerLengthPair, +} + +impl DatatypeIdent { + /// Determine the simplest strategy by which a type may be passed. Value always preferred over + /// Pointer. + pub fn passed_by(&self) -> DatatypePassedBy { + match &self { + DatatypeIdent::Builtin(b) => match b { + BuiltinType::String | BuiltinType::Data => DatatypePassedBy::PointerLengthPair, + BuiltinType::U8 + | BuiltinType::U16 + | BuiltinType::U32 + | BuiltinType::S8 + | BuiltinType::S16 + | BuiltinType::S32 => DatatypePassedBy::Value(AtomType::I32), + BuiltinType::U64 | BuiltinType::S64 => DatatypePassedBy::Value(AtomType::I64), + BuiltinType::F32 => DatatypePassedBy::Value(AtomType::F32), + BuiltinType::F64 => DatatypePassedBy::Value(AtomType::F64), + }, + DatatypeIdent::Array { .. } => DatatypePassedBy::PointerLengthPair, + DatatypeIdent::Pointer { .. } | DatatypeIdent::ConstPointer { .. } => { + DatatypePassedBy::Value(AtomType::I32) + } + DatatypeIdent::Ident(i) => match &i.variant { + DatatypeVariant::Alias(a) => a.to.passed_by(), + DatatypeVariant::Enum(e) => DatatypePassedBy::Value(e.repr.into()), + DatatypeVariant::Flags(f) => DatatypePassedBy::Value(f.repr.into()), + DatatypeVariant::Struct { .. } | DatatypeVariant::Union { .. } => { + DatatypePassedBy::Pointer + } + }, + } + } +} + +/// A parameter in the WebAssembly type of a function. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CoreParamType { + /// The interface function parameter to which this + pub param: InterfaceFuncParam, + /// The relationship of the WebAssembly parameter to the function interface parameter + pub signifies: CoreParamSignifies, +} + +impl CoreParamType { + /// Representation of the WebAssembly parameter. This is the type that will appear + /// in the function's WebAssembly type signature. + pub fn repr(&self) -> AtomType { + self.signifies.repr() + } +} + +/// Enumerates the sort of relationship an WebAssembly parameter to an interface function +/// parameter. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum CoreParamSignifies { + /// Core type represents the value using an AtomType + Value(AtomType), + /// Core type represents a pointer into linear memory + PointerTo, + /// Core type represents a length of a region of linear memory + LengthOf, +} + +impl CoreParamSignifies { + /// Representation of the WebAssembly parameter. + pub fn repr(&self) -> AtomType { + match self { + CoreParamSignifies::Value(a) => *a, + CoreParamSignifies::PointerTo | CoreParamSignifies::LengthOf => AtomType::I32, + } + } +} + +impl InterfaceFuncParam { + /// Gives the WebAssembly type that corresponds to passing this interface func parameter by value. + /// Not all types can be passed by value: those which cannot return None + pub fn pass_by_value(&self) -> Option { + match self.type_.passed_by() { + DatatypePassedBy::Value(atom) => Some(CoreParamType { + signifies: CoreParamSignifies::Value(atom), + param: self.clone(), + }), + DatatypePassedBy::Pointer | DatatypePassedBy::PointerLengthPair => None, + } + } + + /// Gives the WebAssembly types that correspond to passing this interface func parameter + /// by reference. Some types are passed by reference using a single pointer, others + /// require both a pointer and length. + pub fn pass_by_reference(&self) -> Vec { + match self.type_.passed_by() { + DatatypePassedBy::Value(_) | DatatypePassedBy::Pointer => vec![CoreParamType { + signifies: CoreParamSignifies::PointerTo, + param: self.clone(), + }], + DatatypePassedBy::PointerLengthPair => vec![ + CoreParamType { + signifies: CoreParamSignifies::PointerTo, + param: self.clone(), + }, + CoreParamType { + signifies: CoreParamSignifies::LengthOf, + param: self.clone(), + }, + ], + } + } +} + +/// Describes the WebAssembly signature of a function +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CoreFuncType { + pub args: Vec, + pub ret: Option, +} + +impl InterfaceFunc { + /// Get the WebAssembly type signature for this interface function + pub fn core_type(&self) -> CoreFuncType { + let mut results = self.results.iter(); + // The ret value is the first result (if there is one), passed + // by value. + let ret = results.next().map(|param| { + param + .pass_by_value() + .expect("validation ensures first result can be passed by value") + }); + let args = self + .params + .iter() + .flat_map(|param| { + // interface function parameters are passed by value if possible, + // and fall back on passing by reference. + param + .pass_by_value() + .map(|ptype| vec![ptype]) + .unwrap_or_else(|| param.pass_by_reference()) + }) + // Then, the remaining results are passed by reference. + .chain(results.flat_map(|param| param.pass_by_reference())) + .collect(); + CoreFuncType { args, ret } + } +} diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 34876cf7b..af315a9df 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -1,5 +1,7 @@ /// Types describing a validated witx document mod ast; +/// Map witx types to core (wasm standard) types +mod coretypes; /// Interface for filesystem or mock IO mod io; /// Lexer text into tokens @@ -17,10 +19,11 @@ mod validate; pub use ast::{ AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, Module, - ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, - UnionDatatype, UnionVariant, + Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, + InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, ModuleImport, + ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; +pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; pub use io::{Filesystem, MockFs, WitxIo}; pub use lexer::LexError; pub use parser::{DeclSyntax, ParseError}; diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 0fecf1178..526409e62 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -4,10 +4,11 @@ use crate::{ DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, IdentSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, - AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, Location, - Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, - StructMember, UnionDatatype, UnionVariant, + AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, + Definition, Document, Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, + InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, + ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, + UnionVariant, }; use failure::Fail; use std::collections::HashMap; @@ -40,6 +41,8 @@ pub enum ValidationError { repr: BuiltinType, location: Location, }, + #[fail(display = "First result type must be pass-by-value")] + InvalidFirstResultType { location: Location }, } impl ValidationError { @@ -49,7 +52,8 @@ impl ValidationError { UnknownName { location, .. } | WrongKindName { location, .. } | Recursive { location, .. } - | InvalidRepr { location, .. } => { + | InvalidRepr { location, .. } + | InvalidFirstResultType { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } NameAlreadyExists { @@ -361,20 +365,33 @@ impl<'a> ModuleValidation<'a> { let params = syntax .params .iter() - .map(|f| { + .enumerate() + .map(|(ix, f)| { Ok(InterfaceFuncParam { name: argnames.introduce(&f.name)?, type_: self.doc.validate_datatype_ident(&f.type_)?, + position: InterfaceFuncParamPosition::Param(ix), }) }) .collect::, _>>()?; let results = syntax .results .iter() - .map(|f| { + .enumerate() + .map(|(ix, f)| { + let type_ = self.doc.validate_datatype_ident(&f.type_)?; + if ix == 0 { + match type_.passed_by() { + DatatypePassedBy::Value(_) => {} + _ => Err(ValidationError::InvalidFirstResultType { + location: f.name.location.clone(), + })?, + } + } Ok(InterfaceFuncParam { name: argnames.introduce(&f.name)?, - type_: self.doc.validate_datatype_ident(&f.type_)?, + type_, + position: InterfaceFuncParamPosition::Result(ix), }) }) .collect::, _>>()?; From 4d7b9baff00262a6f0ca5dbeec690848f218753f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 2 Oct 2019 12:38:42 -0700 Subject: [PATCH 0199/1772] fix & release witx 0.3.0 (#105) * witx: fix merged-in use of deleted variant BuiltinType::Data correct CI of the PR merge commit would have caught this :( * witx: bump to version 0.3.0 --- proposals/clocks/tools/witx/Cargo.toml | 2 +- proposals/clocks/tools/witx/src/coretypes.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index df1e60ec7..2fe71c419 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.2.0" +version = "0.3.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index bcb9b34af..5b3c89d8d 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -37,7 +37,7 @@ impl DatatypeIdent { pub fn passed_by(&self) -> DatatypePassedBy { match &self { DatatypeIdent::Builtin(b) => match b { - BuiltinType::String | BuiltinType::Data => DatatypePassedBy::PointerLengthPair, + BuiltinType::String => DatatypePassedBy::PointerLengthPair, BuiltinType::U8 | BuiltinType::U16 | BuiltinType::U32 From 0504a338b889a356d7b781d9f7c4d38db469b261 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 2 Oct 2019 12:38:42 -0700 Subject: [PATCH 0200/1772] fix & release witx 0.3.0 (#105) * witx: fix merged-in use of deleted variant BuiltinType::Data correct CI of the PR merge commit would have caught this :( * witx: bump to version 0.3.0 --- proposals/random/tools/witx/Cargo.toml | 2 +- proposals/random/tools/witx/src/coretypes.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index df1e60ec7..2fe71c419 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.2.0" +version = "0.3.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index bcb9b34af..5b3c89d8d 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -37,7 +37,7 @@ impl DatatypeIdent { pub fn passed_by(&self) -> DatatypePassedBy { match &self { DatatypeIdent::Builtin(b) => match b { - BuiltinType::String | BuiltinType::Data => DatatypePassedBy::PointerLengthPair, + BuiltinType::String => DatatypePassedBy::PointerLengthPair, BuiltinType::U8 | BuiltinType::U16 | BuiltinType::U32 From c0fe373d47d1060a023c5b187c6a06bb914588a0 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 2 Oct 2019 12:38:42 -0700 Subject: [PATCH 0201/1772] fix & release witx 0.3.0 (#105) * witx: fix merged-in use of deleted variant BuiltinType::Data correct CI of the PR merge commit would have caught this :( * witx: bump to version 0.3.0 --- proposals/filesystem/tools/witx/Cargo.toml | 2 +- proposals/filesystem/tools/witx/src/coretypes.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index df1e60ec7..2fe71c419 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.2.0" +version = "0.3.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index bcb9b34af..5b3c89d8d 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -37,7 +37,7 @@ impl DatatypeIdent { pub fn passed_by(&self) -> DatatypePassedBy { match &self { DatatypeIdent::Builtin(b) => match b { - BuiltinType::String | BuiltinType::Data => DatatypePassedBy::PointerLengthPair, + BuiltinType::String => DatatypePassedBy::PointerLengthPair, BuiltinType::U8 | BuiltinType::U16 | BuiltinType::U32 From 79b4a706a1575d1c88de840d3b532931b21eda81 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 10 Oct 2019 10:43:31 -0700 Subject: [PATCH 0202/1772] Update the logistics for the 10-15 in-person meeting. (#110) Attendees of this meeting should be members of the WebAssembly CG; see the included link for details. And, the host for this in-person meeting has requested we provide a list of attendees, so please email Dan Gohman if you plan on attending. --- proposals/clocks/meetings/2019/WASI-10-15.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/meetings/2019/WASI-10-15.md b/proposals/clocks/meetings/2019/WASI-10-15.md index 1cd7d1258..e914a2484 100644 --- a/proposals/clocks/meetings/2019/WASI-10-15.md +++ b/proposals/clocks/meetings/2019/WASI-10-15.md @@ -10,8 +10,13 @@ ### Registration -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. +This meeting is open to WebAssembly CG members only. To register, please +visit the CG participants page: + +https://www.w3.org/community/webassembly/participants + +Also, the host for this in-person meeting has requested we provide a list +of attendees, so please email Dan Gohman if you plan on attending. ## Agenda items From a1b50a369440601e01a7f8584d8438fc4f5c1cae Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 10 Oct 2019 10:43:31 -0700 Subject: [PATCH 0203/1772] Update the logistics for the 10-15 in-person meeting. (#110) Attendees of this meeting should be members of the WebAssembly CG; see the included link for details. And, the host for this in-person meeting has requested we provide a list of attendees, so please email Dan Gohman if you plan on attending. --- proposals/random/meetings/2019/WASI-10-15.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/proposals/random/meetings/2019/WASI-10-15.md b/proposals/random/meetings/2019/WASI-10-15.md index 1cd7d1258..e914a2484 100644 --- a/proposals/random/meetings/2019/WASI-10-15.md +++ b/proposals/random/meetings/2019/WASI-10-15.md @@ -10,8 +10,13 @@ ### Registration -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. +This meeting is open to WebAssembly CG members only. To register, please +visit the CG participants page: + +https://www.w3.org/community/webassembly/participants + +Also, the host for this in-person meeting has requested we provide a list +of attendees, so please email Dan Gohman if you plan on attending. ## Agenda items From 499ee4c933548531ec48f812fbee1c697ad59f89 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 10 Oct 2019 10:43:31 -0700 Subject: [PATCH 0204/1772] Update the logistics for the 10-15 in-person meeting. (#110) Attendees of this meeting should be members of the WebAssembly CG; see the included link for details. And, the host for this in-person meeting has requested we provide a list of attendees, so please email Dan Gohman if you plan on attending. --- proposals/filesystem/meetings/2019/WASI-10-15.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/meetings/2019/WASI-10-15.md b/proposals/filesystem/meetings/2019/WASI-10-15.md index 1cd7d1258..e914a2484 100644 --- a/proposals/filesystem/meetings/2019/WASI-10-15.md +++ b/proposals/filesystem/meetings/2019/WASI-10-15.md @@ -10,8 +10,13 @@ ### Registration -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. +This meeting is open to WebAssembly CG members only. To register, please +visit the CG participants page: + +https://www.w3.org/community/webassembly/participants + +Also, the host for this in-person meeting has requested we provide a list +of attendees, so please email Dan Gohman if you plan on attending. ## Agenda items From 78b029ba7cd32010e93035af701e6af0cfa33b08 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 11 Oct 2019 06:17:49 -0700 Subject: [PATCH 0205/1772] Change whence_t constant values to match pre-existing agreed-upon values. (#106) * Change whence_t constant values to match existing agreed-upon values. --- .../phases/ephemeral/docs/wasi_ephemeral_preview.md | 8 ++++---- proposals/clocks/phases/ephemeral/witx/typenames.witx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md index 9db4a382e..0e93982fa 100644 --- a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -2305,6 +2305,10 @@ Used by [`__wasi_fd_seek()`](#fd_seek). Possible values: +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + - **`__WASI_WHENCE_CUR`** Seek relative to current position. @@ -2313,7 +2317,3 @@ Possible values: Seek relative to end-of-file. -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index e04a188d9..9c98fa79f 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -305,12 +305,12 @@ ;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 + ;; Seek relative to start-of-file. + $WHENCE_SET ;; Seek relative to current position. $WHENCE_CUR ;; Seek relative to end-of-file. $WHENCE_END - ;; Seek relative to start-of-file. - $WHENCE_SET ) ) From 24f0a01047e1e5bf6105948bd74e3775f4dc78de Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 11 Oct 2019 06:17:49 -0700 Subject: [PATCH 0206/1772] Change whence_t constant values to match pre-existing agreed-upon values. (#106) * Change whence_t constant values to match existing agreed-upon values. --- .../phases/ephemeral/docs/wasi_ephemeral_preview.md | 8 ++++---- proposals/random/phases/ephemeral/witx/typenames.witx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md index 9db4a382e..0e93982fa 100644 --- a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -2305,6 +2305,10 @@ Used by [`__wasi_fd_seek()`](#fd_seek). Possible values: +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + - **`__WASI_WHENCE_CUR`** Seek relative to current position. @@ -2313,7 +2317,3 @@ Possible values: Seek relative to end-of-file. -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index e04a188d9..9c98fa79f 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -305,12 +305,12 @@ ;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 + ;; Seek relative to start-of-file. + $WHENCE_SET ;; Seek relative to current position. $WHENCE_CUR ;; Seek relative to end-of-file. $WHENCE_END - ;; Seek relative to start-of-file. - $WHENCE_SET ) ) From 22a8a2ceda5ecbb9bc85957aa02a140d40770c18 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 11 Oct 2019 06:17:49 -0700 Subject: [PATCH 0207/1772] Change whence_t constant values to match pre-existing agreed-upon values. (#106) * Change whence_t constant values to match existing agreed-upon values. --- .../phases/ephemeral/docs/wasi_ephemeral_preview.md | 8 ++++---- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md index 9db4a382e..0e93982fa 100644 --- a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -2305,6 +2305,10 @@ Used by [`__wasi_fd_seek()`](#fd_seek). Possible values: +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + - **`__WASI_WHENCE_CUR`** Seek relative to current position. @@ -2313,7 +2317,3 @@ Possible values: Seek relative to end-of-file. -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index e04a188d9..9c98fa79f 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -305,12 +305,12 @@ ;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 + ;; Seek relative to start-of-file. + $WHENCE_SET ;; Seek relative to current position. $WHENCE_CUR ;; Seek relative to end-of-file. $WHENCE_END - ;; Seek relative to start-of-file. - $WHENCE_SET ) ) From 2eccbfde9284bfcded554a238c3ee3bd206adf1a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 11 Oct 2019 08:41:21 -0700 Subject: [PATCH 0208/1772] Catch up on posting the meeting notes to the WASI repository. (#113) --- proposals/clocks/meetings/2019/WASI-08-15.md | 70 +++++++++++++++++++- proposals/clocks/meetings/2019/WASI-08-30.md | 20 +++++- proposals/clocks/meetings/2019/WASI-09-12.md | 55 ++++++++++++++- proposals/clocks/meetings/2019/WASI-09-26.md | 25 ++++++- 4 files changed, 166 insertions(+), 4 deletions(-) diff --git a/proposals/clocks/meetings/2019/WASI-08-15.md b/proposals/clocks/meetings/2019/WASI-08-15.md index 1159c9324..8062b2745 100644 --- a/proposals/clocks/meetings/2019/WASI-08-15.md +++ b/proposals/clocks/meetings/2019/WASI-08-15.md @@ -50,4 +50,72 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Till Schneidereit +Alex Crichton +Luke Wagner +Jacob Gravelle +Sam Clegg +Andrew Scheidecker +Mark S. Miller +Johnnie Birch +Stefan Junker +Andrew Brown + +Meeting notes: +Topic: Weak Imports: https://github.com/WebAssembly/WASI/pull/47#issuecomment-521061962 +sbc: moved back to custom section design +[please fill in notes here] +MarkM: could a rename be considered—I always think of weak references +Sbc: very strong precedence in C/C++ +MarkM: weak/optional imports should be brought up with TC39 +Luke: [posts a link https://github.com/guybedford/proposal-weak-imports] +Dan: good question, should we rename? +Stefan: +1 on “optional” +Mark: would “optional” be confusing? +Seems like “no” +Dan: seems like consensus +Sbc: [takes an action item to rename] +Dan: anyone opposed to landing the PR once the rename is done? +[no] +Dan: let’s do it +Topic: Interface description based on Module types (https://github.com/WebAssembly/WASI/pull/74) +Dan: lots of stuff going on around OCap, and that should go on +But in parallel, we need a simple text format +This PR introduces a stripped down text format (see PR description for details) + +Mark: should we introduce a term such as “compartment” to describe sets of instances which share memories and tables? +Sam: This relates to the concept of “shared-nothing linking” which we have been introducing. +Luke: In full generality, we won’t need the term compartment, because we’ll just have references and different linking approaches. +Luke: if we want wasi_unstable to become wasi, we need to spec ways to send capabilities between modules. We don’t if we just have references +Till: brings up the question if we need to support wasi_unstable, instead of just breaking it +[discussion] +Mark: This is a useful concept, whether or not it’s something +[discussion] +Luke: getting back to the proposal, looks good for the transitional role +Dan: idea is, once we have a parser for this, we could land it, and have it be the specification +Could generate header files and documentation from it +Sbc: comments go into some kind of comment syntax? +Dan: double-semicolon +Sbc: need some kind of include mechanism +Dan: yes, good point. Want to really keep this simple +Luke: same requirement came up in conversations with Andreas about defining types in one module and using them in another +Luke: but as long this is all structural, can just agree on structure of types +Dan: + +Dan: We need to factor out types so they can be shared between multiple modules. Maybe something like a #include mechanism? +Mark: #include would be unfortunate in any kind of standards context. +Luke: We could put multiple modules in one file +Dan: Could we design a more declarative form which achieves the same goal but doesn’t have the same problem? +Mark: It’s premature to do a lot of IDL design work +Dan: agree + +Timezone discussion +Till, Johnnie: conversations about voting, and people not being able to attend all meetings. Perhaps we can find a way to do votes offline to allow people to vote even if they can’t attend the meeting. +Sam: Another option is to do the vote in the meeting, but hold it open for a week or so after to allow others to vote. +Till: That does change the dynamics. +Johnnie: Would it makes sense to record the meetings? +Dan: What if we ask the CG to record their meetings? We can follow their lead. +Johnnie volunteers to take that to the CG. diff --git a/proposals/clocks/meetings/2019/WASI-08-30.md b/proposals/clocks/meetings/2019/WASI-08-30.md index fd2f274a1..cbd14a725 100644 --- a/proposals/clocks/meetings/2019/WASI-08-30.md +++ b/proposals/clocks/meetings/2019/WASI-08-30.md @@ -43,4 +43,22 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Xin Wang +Leon Wang +Arun Purushan +Till Schneidereit +Tyler McMullen +Sam Clegg + +Meeting notes: + +Time zone: +XW: Seems like we can move to the previous time. +DG: We can be flexible in the future too. + +XW: Presentation on WASI for Embedded + +DG: Update on https://github.com/WebAssembly/WASI/pull/74 diff --git a/proposals/clocks/meetings/2019/WASI-09-12.md b/proposals/clocks/meetings/2019/WASI-09-12.md index edcf5f95d..e8bf1a518 100644 --- a/proposals/clocks/meetings/2019/WASI-09-12.md +++ b/proposals/clocks/meetings/2019/WASI-09-12.md @@ -36,4 +36,57 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Sam Clegg +Pat Hickey +Yury Delendik +Artur Jamro +Mark McCaskey +Alex Crichton +Jacob Gravelle +Mingqiu Sun +Nathaniel McCallum +Luke Wagner +Johnnie Birch + +Meeting notes: + +Agenda seconded by Pat + +Dan: Last meeting was at a different time than usual. There were only 6 attendees. We are going to resume meetings at the normal time, 1600 UTC. + +Dan: Next topic is WITX. + +Independent of WASI, there is a new file format called WIT from the interface-types proposal. Its a lot like WAT, but it does not have function bodies. + +WITX is WIT with extensions. It has some of the types from interface-types. The idea is that WITX is not a stable format, its going to evolve to align with WIT as interface types evolves. + +Fortunately our needs are pretty simple at the moment: we are adding strings, arrays, enums, and structs to the wit file. + +We want WITX to be the way we specify WASI apis. It feels like a better place than the C header file we started with. + +Pat: lucet-idl tool has a witx parser in development. + +Working on hooking up this parser to the C and Rust interface generators. +Goal, be able to feed witx files into lucet-idl and generate C headers and Rust interfaces. + +Can be used to generate libc definitions for WASI + + +Stefan: Does WITX have modules? + +Dan: Yes, but the file we have at the moment attempts to be the exact same wasi_unstable module we have right now. Once we land this, we can immediately start factoring that module into multiple modules, and witx should support that. + +Sam: Is there a way to use types from a different module? + +Dan: Yes, there is a `use` mechanism, and in the PR there’s two witx files, wasi_unstable’s first declaration is to `use “typenames.witx”` + +Dan: Next agenda item: Phased API development (PR 88). Apologies for getting this up late. + +Stefan: Could there be a standalone parser implementation somewhere? + +tdoPat: I’ll make the lucet-idl parser and validator for witx into its own crate, and that crate will live in the WASI repo. + +Johnnie: I followed up on whether we can record these meetings, I talked to the W3C and they expressed the same concerns we heard here about privacy, making people feel comfortable speaking up. They suggested I talk to the WASM CG, but given that I’ve heard the same feedback from multiple places, I’m going to just drop the issue. diff --git a/proposals/clocks/meetings/2019/WASI-09-26.md b/proposals/clocks/meetings/2019/WASI-09-26.md index 2534b24a3..704aed13a 100644 --- a/proposals/clocks/meetings/2019/WASI-09-26.md +++ b/proposals/clocks/meetings/2019/WASI-09-26.md @@ -34,4 +34,27 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Andrew Brown +Mark Bestavros +Leon Wang +Alex Crichton +Peter Huene +Luke Wagner +Yury Delendik +Pat Hickey +Artur Jamro + +Meeting notes: + +DG: WASI modularization draft PR is up, comments are welcome + +Also, this makes the start of the point where we can start taking PRs for new API proposals, in the form of PRs which add and modify witx files. + +Pat: We’re working on an HTTP API proposal. + +Dan: There are also people working on Berkeley sockets APIs. Note that though there is a potential for overlap here, it makes sense to develop both. + +Pat: In cases of overlap like this, the higher-level APIs may even by polyfillable on top of the lower-level APIs. From 5994991125c0de276101640d453d8b091d7639d3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 11 Oct 2019 08:41:21 -0700 Subject: [PATCH 0209/1772] Catch up on posting the meeting notes to the WASI repository. (#113) --- proposals/random/meetings/2019/WASI-08-15.md | 70 +++++++++++++++++++- proposals/random/meetings/2019/WASI-08-30.md | 20 +++++- proposals/random/meetings/2019/WASI-09-12.md | 55 ++++++++++++++- proposals/random/meetings/2019/WASI-09-26.md | 25 ++++++- 4 files changed, 166 insertions(+), 4 deletions(-) diff --git a/proposals/random/meetings/2019/WASI-08-15.md b/proposals/random/meetings/2019/WASI-08-15.md index 1159c9324..8062b2745 100644 --- a/proposals/random/meetings/2019/WASI-08-15.md +++ b/proposals/random/meetings/2019/WASI-08-15.md @@ -50,4 +50,72 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Till Schneidereit +Alex Crichton +Luke Wagner +Jacob Gravelle +Sam Clegg +Andrew Scheidecker +Mark S. Miller +Johnnie Birch +Stefan Junker +Andrew Brown + +Meeting notes: +Topic: Weak Imports: https://github.com/WebAssembly/WASI/pull/47#issuecomment-521061962 +sbc: moved back to custom section design +[please fill in notes here] +MarkM: could a rename be considered—I always think of weak references +Sbc: very strong precedence in C/C++ +MarkM: weak/optional imports should be brought up with TC39 +Luke: [posts a link https://github.com/guybedford/proposal-weak-imports] +Dan: good question, should we rename? +Stefan: +1 on “optional” +Mark: would “optional” be confusing? +Seems like “no” +Dan: seems like consensus +Sbc: [takes an action item to rename] +Dan: anyone opposed to landing the PR once the rename is done? +[no] +Dan: let’s do it +Topic: Interface description based on Module types (https://github.com/WebAssembly/WASI/pull/74) +Dan: lots of stuff going on around OCap, and that should go on +But in parallel, we need a simple text format +This PR introduces a stripped down text format (see PR description for details) + +Mark: should we introduce a term such as “compartment” to describe sets of instances which share memories and tables? +Sam: This relates to the concept of “shared-nothing linking” which we have been introducing. +Luke: In full generality, we won’t need the term compartment, because we’ll just have references and different linking approaches. +Luke: if we want wasi_unstable to become wasi, we need to spec ways to send capabilities between modules. We don’t if we just have references +Till: brings up the question if we need to support wasi_unstable, instead of just breaking it +[discussion] +Mark: This is a useful concept, whether or not it’s something +[discussion] +Luke: getting back to the proposal, looks good for the transitional role +Dan: idea is, once we have a parser for this, we could land it, and have it be the specification +Could generate header files and documentation from it +Sbc: comments go into some kind of comment syntax? +Dan: double-semicolon +Sbc: need some kind of include mechanism +Dan: yes, good point. Want to really keep this simple +Luke: same requirement came up in conversations with Andreas about defining types in one module and using them in another +Luke: but as long this is all structural, can just agree on structure of types +Dan: + +Dan: We need to factor out types so they can be shared between multiple modules. Maybe something like a #include mechanism? +Mark: #include would be unfortunate in any kind of standards context. +Luke: We could put multiple modules in one file +Dan: Could we design a more declarative form which achieves the same goal but doesn’t have the same problem? +Mark: It’s premature to do a lot of IDL design work +Dan: agree + +Timezone discussion +Till, Johnnie: conversations about voting, and people not being able to attend all meetings. Perhaps we can find a way to do votes offline to allow people to vote even if they can’t attend the meeting. +Sam: Another option is to do the vote in the meeting, but hold it open for a week or so after to allow others to vote. +Till: That does change the dynamics. +Johnnie: Would it makes sense to record the meetings? +Dan: What if we ask the CG to record their meetings? We can follow their lead. +Johnnie volunteers to take that to the CG. diff --git a/proposals/random/meetings/2019/WASI-08-30.md b/proposals/random/meetings/2019/WASI-08-30.md index fd2f274a1..cbd14a725 100644 --- a/proposals/random/meetings/2019/WASI-08-30.md +++ b/proposals/random/meetings/2019/WASI-08-30.md @@ -43,4 +43,22 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Xin Wang +Leon Wang +Arun Purushan +Till Schneidereit +Tyler McMullen +Sam Clegg + +Meeting notes: + +Time zone: +XW: Seems like we can move to the previous time. +DG: We can be flexible in the future too. + +XW: Presentation on WASI for Embedded + +DG: Update on https://github.com/WebAssembly/WASI/pull/74 diff --git a/proposals/random/meetings/2019/WASI-09-12.md b/proposals/random/meetings/2019/WASI-09-12.md index edcf5f95d..e8bf1a518 100644 --- a/proposals/random/meetings/2019/WASI-09-12.md +++ b/proposals/random/meetings/2019/WASI-09-12.md @@ -36,4 +36,57 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Sam Clegg +Pat Hickey +Yury Delendik +Artur Jamro +Mark McCaskey +Alex Crichton +Jacob Gravelle +Mingqiu Sun +Nathaniel McCallum +Luke Wagner +Johnnie Birch + +Meeting notes: + +Agenda seconded by Pat + +Dan: Last meeting was at a different time than usual. There were only 6 attendees. We are going to resume meetings at the normal time, 1600 UTC. + +Dan: Next topic is WITX. + +Independent of WASI, there is a new file format called WIT from the interface-types proposal. Its a lot like WAT, but it does not have function bodies. + +WITX is WIT with extensions. It has some of the types from interface-types. The idea is that WITX is not a stable format, its going to evolve to align with WIT as interface types evolves. + +Fortunately our needs are pretty simple at the moment: we are adding strings, arrays, enums, and structs to the wit file. + +We want WITX to be the way we specify WASI apis. It feels like a better place than the C header file we started with. + +Pat: lucet-idl tool has a witx parser in development. + +Working on hooking up this parser to the C and Rust interface generators. +Goal, be able to feed witx files into lucet-idl and generate C headers and Rust interfaces. + +Can be used to generate libc definitions for WASI + + +Stefan: Does WITX have modules? + +Dan: Yes, but the file we have at the moment attempts to be the exact same wasi_unstable module we have right now. Once we land this, we can immediately start factoring that module into multiple modules, and witx should support that. + +Sam: Is there a way to use types from a different module? + +Dan: Yes, there is a `use` mechanism, and in the PR there’s two witx files, wasi_unstable’s first declaration is to `use “typenames.witx”` + +Dan: Next agenda item: Phased API development (PR 88). Apologies for getting this up late. + +Stefan: Could there be a standalone parser implementation somewhere? + +tdoPat: I’ll make the lucet-idl parser and validator for witx into its own crate, and that crate will live in the WASI repo. + +Johnnie: I followed up on whether we can record these meetings, I talked to the W3C and they expressed the same concerns we heard here about privacy, making people feel comfortable speaking up. They suggested I talk to the WASM CG, but given that I’ve heard the same feedback from multiple places, I’m going to just drop the issue. diff --git a/proposals/random/meetings/2019/WASI-09-26.md b/proposals/random/meetings/2019/WASI-09-26.md index 2534b24a3..704aed13a 100644 --- a/proposals/random/meetings/2019/WASI-09-26.md +++ b/proposals/random/meetings/2019/WASI-09-26.md @@ -34,4 +34,27 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Andrew Brown +Mark Bestavros +Leon Wang +Alex Crichton +Peter Huene +Luke Wagner +Yury Delendik +Pat Hickey +Artur Jamro + +Meeting notes: + +DG: WASI modularization draft PR is up, comments are welcome + +Also, this makes the start of the point where we can start taking PRs for new API proposals, in the form of PRs which add and modify witx files. + +Pat: We’re working on an HTTP API proposal. + +Dan: There are also people working on Berkeley sockets APIs. Note that though there is a potential for overlap here, it makes sense to develop both. + +Pat: In cases of overlap like this, the higher-level APIs may even by polyfillable on top of the lower-level APIs. From 50458d76deeaedffe29a602f959caa388b227f48 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 11 Oct 2019 08:41:21 -0700 Subject: [PATCH 0210/1772] Catch up on posting the meeting notes to the WASI repository. (#113) --- .../filesystem/meetings/2019/WASI-08-15.md | 70 ++++++++++++++++++- .../filesystem/meetings/2019/WASI-08-30.md | 20 +++++- .../filesystem/meetings/2019/WASI-09-12.md | 55 ++++++++++++++- .../filesystem/meetings/2019/WASI-09-26.md | 25 ++++++- 4 files changed, 166 insertions(+), 4 deletions(-) diff --git a/proposals/filesystem/meetings/2019/WASI-08-15.md b/proposals/filesystem/meetings/2019/WASI-08-15.md index 1159c9324..8062b2745 100644 --- a/proposals/filesystem/meetings/2019/WASI-08-15.md +++ b/proposals/filesystem/meetings/2019/WASI-08-15.md @@ -50,4 +50,72 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Till Schneidereit +Alex Crichton +Luke Wagner +Jacob Gravelle +Sam Clegg +Andrew Scheidecker +Mark S. Miller +Johnnie Birch +Stefan Junker +Andrew Brown + +Meeting notes: +Topic: Weak Imports: https://github.com/WebAssembly/WASI/pull/47#issuecomment-521061962 +sbc: moved back to custom section design +[please fill in notes here] +MarkM: could a rename be considered—I always think of weak references +Sbc: very strong precedence in C/C++ +MarkM: weak/optional imports should be brought up with TC39 +Luke: [posts a link https://github.com/guybedford/proposal-weak-imports] +Dan: good question, should we rename? +Stefan: +1 on “optional” +Mark: would “optional” be confusing? +Seems like “no” +Dan: seems like consensus +Sbc: [takes an action item to rename] +Dan: anyone opposed to landing the PR once the rename is done? +[no] +Dan: let’s do it +Topic: Interface description based on Module types (https://github.com/WebAssembly/WASI/pull/74) +Dan: lots of stuff going on around OCap, and that should go on +But in parallel, we need a simple text format +This PR introduces a stripped down text format (see PR description for details) + +Mark: should we introduce a term such as “compartment” to describe sets of instances which share memories and tables? +Sam: This relates to the concept of “shared-nothing linking” which we have been introducing. +Luke: In full generality, we won’t need the term compartment, because we’ll just have references and different linking approaches. +Luke: if we want wasi_unstable to become wasi, we need to spec ways to send capabilities between modules. We don’t if we just have references +Till: brings up the question if we need to support wasi_unstable, instead of just breaking it +[discussion] +Mark: This is a useful concept, whether or not it’s something +[discussion] +Luke: getting back to the proposal, looks good for the transitional role +Dan: idea is, once we have a parser for this, we could land it, and have it be the specification +Could generate header files and documentation from it +Sbc: comments go into some kind of comment syntax? +Dan: double-semicolon +Sbc: need some kind of include mechanism +Dan: yes, good point. Want to really keep this simple +Luke: same requirement came up in conversations with Andreas about defining types in one module and using them in another +Luke: but as long this is all structural, can just agree on structure of types +Dan: + +Dan: We need to factor out types so they can be shared between multiple modules. Maybe something like a #include mechanism? +Mark: #include would be unfortunate in any kind of standards context. +Luke: We could put multiple modules in one file +Dan: Could we design a more declarative form which achieves the same goal but doesn’t have the same problem? +Mark: It’s premature to do a lot of IDL design work +Dan: agree + +Timezone discussion +Till, Johnnie: conversations about voting, and people not being able to attend all meetings. Perhaps we can find a way to do votes offline to allow people to vote even if they can’t attend the meeting. +Sam: Another option is to do the vote in the meeting, but hold it open for a week or so after to allow others to vote. +Till: That does change the dynamics. +Johnnie: Would it makes sense to record the meetings? +Dan: What if we ask the CG to record their meetings? We can follow their lead. +Johnnie volunteers to take that to the CG. diff --git a/proposals/filesystem/meetings/2019/WASI-08-30.md b/proposals/filesystem/meetings/2019/WASI-08-30.md index fd2f274a1..cbd14a725 100644 --- a/proposals/filesystem/meetings/2019/WASI-08-30.md +++ b/proposals/filesystem/meetings/2019/WASI-08-30.md @@ -43,4 +43,22 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Xin Wang +Leon Wang +Arun Purushan +Till Schneidereit +Tyler McMullen +Sam Clegg + +Meeting notes: + +Time zone: +XW: Seems like we can move to the previous time. +DG: We can be flexible in the future too. + +XW: Presentation on WASI for Embedded + +DG: Update on https://github.com/WebAssembly/WASI/pull/74 diff --git a/proposals/filesystem/meetings/2019/WASI-09-12.md b/proposals/filesystem/meetings/2019/WASI-09-12.md index edcf5f95d..e8bf1a518 100644 --- a/proposals/filesystem/meetings/2019/WASI-09-12.md +++ b/proposals/filesystem/meetings/2019/WASI-09-12.md @@ -36,4 +36,57 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Sam Clegg +Pat Hickey +Yury Delendik +Artur Jamro +Mark McCaskey +Alex Crichton +Jacob Gravelle +Mingqiu Sun +Nathaniel McCallum +Luke Wagner +Johnnie Birch + +Meeting notes: + +Agenda seconded by Pat + +Dan: Last meeting was at a different time than usual. There were only 6 attendees. We are going to resume meetings at the normal time, 1600 UTC. + +Dan: Next topic is WITX. + +Independent of WASI, there is a new file format called WIT from the interface-types proposal. Its a lot like WAT, but it does not have function bodies. + +WITX is WIT with extensions. It has some of the types from interface-types. The idea is that WITX is not a stable format, its going to evolve to align with WIT as interface types evolves. + +Fortunately our needs are pretty simple at the moment: we are adding strings, arrays, enums, and structs to the wit file. + +We want WITX to be the way we specify WASI apis. It feels like a better place than the C header file we started with. + +Pat: lucet-idl tool has a witx parser in development. + +Working on hooking up this parser to the C and Rust interface generators. +Goal, be able to feed witx files into lucet-idl and generate C headers and Rust interfaces. + +Can be used to generate libc definitions for WASI + + +Stefan: Does WITX have modules? + +Dan: Yes, but the file we have at the moment attempts to be the exact same wasi_unstable module we have right now. Once we land this, we can immediately start factoring that module into multiple modules, and witx should support that. + +Sam: Is there a way to use types from a different module? + +Dan: Yes, there is a `use` mechanism, and in the PR there’s two witx files, wasi_unstable’s first declaration is to `use “typenames.witx”` + +Dan: Next agenda item: Phased API development (PR 88). Apologies for getting this up late. + +Stefan: Could there be a standalone parser implementation somewhere? + +tdoPat: I’ll make the lucet-idl parser and validator for witx into its own crate, and that crate will live in the WASI repo. + +Johnnie: I followed up on whether we can record these meetings, I talked to the W3C and they expressed the same concerns we heard here about privacy, making people feel comfortable speaking up. They suggested I talk to the WASM CG, but given that I’ve heard the same feedback from multiple places, I’m going to just drop the issue. diff --git a/proposals/filesystem/meetings/2019/WASI-09-26.md b/proposals/filesystem/meetings/2019/WASI-09-26.md index 2534b24a3..704aed13a 100644 --- a/proposals/filesystem/meetings/2019/WASI-09-26.md +++ b/proposals/filesystem/meetings/2019/WASI-09-26.md @@ -34,4 +34,27 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Andrew Brown +Mark Bestavros +Leon Wang +Alex Crichton +Peter Huene +Luke Wagner +Yury Delendik +Pat Hickey +Artur Jamro + +Meeting notes: + +DG: WASI modularization draft PR is up, comments are welcome + +Also, this makes the start of the point where we can start taking PRs for new API proposals, in the form of PRs which add and modify witx files. + +Pat: We’re working on an HTTP API proposal. + +Dan: There are also people working on Berkeley sockets APIs. Note that though there is a potential for overlap here, it makes sense to develop both. + +Pat: In cases of overlap like this, the higher-level APIs may even by polyfillable on top of the lower-level APIs. From a13089b380db81efabc1c6bd45a2b4545c1ba8c8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 17 Oct 2019 16:26:30 -0700 Subject: [PATCH 0211/1772] Remove the "0" from the ephemeral module name. (#111) * Remove the "0" from the ephemeral module name. The ephemeral module isn't meant to be versioned, so remove the "0" version number. * Fix the tests to use "wasi_ephemeral_preview". --- ...si_ephemeral_preview0.witx => wasi_ephemeral_preview.witx} | 2 +- proposals/clocks/tools/witx/tests/wasi_unstable.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename proposals/clocks/phases/ephemeral/witx/{wasi_ephemeral_preview0.witx => wasi_ephemeral_preview.witx} (99%) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview0.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx similarity index 99% rename from proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview0.witx rename to proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx index b951ee3e8..c473a9a9b 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview0.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -8,7 +8,7 @@ (use "typenames.witx") -(module $wasi_ephemeral_preview0 +(module $wasi_ephemeral_preview ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) diff --git a/proposals/clocks/tools/witx/tests/wasi_unstable.rs b/proposals/clocks/tools/witx/tests/wasi_unstable.rs index 2722e8d04..482224344 100644 --- a/proposals/clocks/tools/witx/tests/wasi_unstable.rs +++ b/proposals/clocks/tools/witx/tests/wasi_unstable.rs @@ -10,9 +10,9 @@ fn validate_wasi_unstable_preview0() { } #[test] -fn validate_wasi_ephemeral_preview0() { +fn validate_wasi_ephemeral_preview() { witx::load(Path::new( - "../../phases/ephemeral/witx/wasi_ephemeral_preview0.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_preview.witx", )) .unwrap(); } From 5ecf0d9c257be4941096fe0dc2b0fe7ce0bbda8b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 17 Oct 2019 16:26:30 -0700 Subject: [PATCH 0212/1772] Remove the "0" from the ephemeral module name. (#111) * Remove the "0" from the ephemeral module name. The ephemeral module isn't meant to be versioned, so remove the "0" version number. * Fix the tests to use "wasi_ephemeral_preview". --- ...si_ephemeral_preview0.witx => wasi_ephemeral_preview.witx} | 2 +- proposals/random/tools/witx/tests/wasi_unstable.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename proposals/random/phases/ephemeral/witx/{wasi_ephemeral_preview0.witx => wasi_ephemeral_preview.witx} (99%) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview0.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx similarity index 99% rename from proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview0.witx rename to proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx index b951ee3e8..c473a9a9b 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview0.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -8,7 +8,7 @@ (use "typenames.witx") -(module $wasi_ephemeral_preview0 +(module $wasi_ephemeral_preview ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) diff --git a/proposals/random/tools/witx/tests/wasi_unstable.rs b/proposals/random/tools/witx/tests/wasi_unstable.rs index 2722e8d04..482224344 100644 --- a/proposals/random/tools/witx/tests/wasi_unstable.rs +++ b/proposals/random/tools/witx/tests/wasi_unstable.rs @@ -10,9 +10,9 @@ fn validate_wasi_unstable_preview0() { } #[test] -fn validate_wasi_ephemeral_preview0() { +fn validate_wasi_ephemeral_preview() { witx::load(Path::new( - "../../phases/ephemeral/witx/wasi_ephemeral_preview0.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_preview.witx", )) .unwrap(); } From 357ee10bacda69246933bc36f021ab03c2baaaa3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 17 Oct 2019 16:26:30 -0700 Subject: [PATCH 0213/1772] Remove the "0" from the ephemeral module name. (#111) * Remove the "0" from the ephemeral module name. The ephemeral module isn't meant to be versioned, so remove the "0" version number. * Fix the tests to use "wasi_ephemeral_preview". --- ...si_ephemeral_preview0.witx => wasi_ephemeral_preview.witx} | 2 +- proposals/filesystem/tools/witx/tests/wasi_unstable.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename proposals/filesystem/phases/ephemeral/witx/{wasi_ephemeral_preview0.witx => wasi_ephemeral_preview.witx} (99%) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview0.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx similarity index 99% rename from proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview0.witx rename to proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx index b951ee3e8..c473a9a9b 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview0.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -8,7 +8,7 @@ (use "typenames.witx") -(module $wasi_ephemeral_preview0 +(module $wasi_ephemeral_preview ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) diff --git a/proposals/filesystem/tools/witx/tests/wasi_unstable.rs b/proposals/filesystem/tools/witx/tests/wasi_unstable.rs index 2722e8d04..482224344 100644 --- a/proposals/filesystem/tools/witx/tests/wasi_unstable.rs +++ b/proposals/filesystem/tools/witx/tests/wasi_unstable.rs @@ -10,9 +10,9 @@ fn validate_wasi_unstable_preview0() { } #[test] -fn validate_wasi_ephemeral_preview0() { +fn validate_wasi_ephemeral_preview() { witx::load(Path::new( - "../../phases/ephemeral/witx/wasi_ephemeral_preview0.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_preview.witx", )) .unwrap(); } From ba01c0b05c93dabfe9df05a6c3f293c2e3a0fe5a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 17 Oct 2019 16:54:13 -0700 Subject: [PATCH 0214/1772] Add a meeting agenda for a 10-24 video call. (#120) --- proposals/clocks/meetings/2019/WASI-10-24.md | 55 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 3 +- 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 proposals/clocks/meetings/2019/WASI-10-24.md diff --git a/proposals/clocks/meetings/2019/WASI-10-24.md b/proposals/clocks/meetings/2019/WASI-10-24.md new file mode 100644 index 000000000..2c0e0bfc6 --- /dev/null +++ b/proposals/clocks/meetings/2019/WASI-10-24.md @@ -0,0 +1,55 @@ +![WASI logo](/WASI.png) + +## Agenda for the Octoper 24 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: October 24, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. WASI and OCap + 1. https://github.com/WebAssembly/WASI/issues/109#issuecomment-541191297 + 1. https://github.com/WebAssembly/WASI/pull/69 + 1. "Handle" terminology + 1. https://github.com/WebAssembly/WASI/issues/62 + 1. https://github.com/WebAssembly/WASI/pull/117 + 1. Quick ping on reordering `clockid_t` values + 1. https://github.com/WebAssembly/WASI/pull/112/files + 1. Modularization update + 1. https://github.com/WebAssembly/WASI/pull/98 + 1. https://github.com/WebAssembly/WASI/issues/2 + 1. Some good first issues + 1. Make __wasi_linkcount_t 64-bit + 1. https://github.com/WebAssembly/WASI/issues/70 + 1. Incorrect size returned by __wasi_environ_sizes_get + 1. https://github.com/WebAssembly/WASI/issues/27 + 1. Make clocks/random into capabilities + 1. https://github.com/WebAssembly/WASI/issues/118 + 1. Should random continue to be `random_get`, or should it become + `fd_read` from a special stream? + +1. Closure + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 87354bb78..9b8689d9f 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -16,5 +16,6 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI August 15th video call](2019/WASI-08-15.md) * [WASI August 30th video call](2019/WASI-08-30.md) * [WASI September 12th video call](2019/WASI-09-12.md) - * [WASI September 25th video call](2019/WASI-09-25.md) + * [WASI September 26th video call](2019/WASI-09-26.md) * [WASI October 15th in-person meeting](2019/WASI-10-15.md) + * [WASI October 24th video call](2019/WASI-10-24.md) From 7da189f072cb7aaf14cf9ff4acc4b2f37f77897a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 17 Oct 2019 16:54:13 -0700 Subject: [PATCH 0215/1772] Add a meeting agenda for a 10-24 video call. (#120) --- proposals/random/meetings/2019/WASI-10-24.md | 55 ++++++++++++++++++++ proposals/random/meetings/README.md | 3 +- 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 proposals/random/meetings/2019/WASI-10-24.md diff --git a/proposals/random/meetings/2019/WASI-10-24.md b/proposals/random/meetings/2019/WASI-10-24.md new file mode 100644 index 000000000..2c0e0bfc6 --- /dev/null +++ b/proposals/random/meetings/2019/WASI-10-24.md @@ -0,0 +1,55 @@ +![WASI logo](/WASI.png) + +## Agenda for the Octoper 24 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: October 24, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. WASI and OCap + 1. https://github.com/WebAssembly/WASI/issues/109#issuecomment-541191297 + 1. https://github.com/WebAssembly/WASI/pull/69 + 1. "Handle" terminology + 1. https://github.com/WebAssembly/WASI/issues/62 + 1. https://github.com/WebAssembly/WASI/pull/117 + 1. Quick ping on reordering `clockid_t` values + 1. https://github.com/WebAssembly/WASI/pull/112/files + 1. Modularization update + 1. https://github.com/WebAssembly/WASI/pull/98 + 1. https://github.com/WebAssembly/WASI/issues/2 + 1. Some good first issues + 1. Make __wasi_linkcount_t 64-bit + 1. https://github.com/WebAssembly/WASI/issues/70 + 1. Incorrect size returned by __wasi_environ_sizes_get + 1. https://github.com/WebAssembly/WASI/issues/27 + 1. Make clocks/random into capabilities + 1. https://github.com/WebAssembly/WASI/issues/118 + 1. Should random continue to be `random_get`, or should it become + `fd_read` from a special stream? + +1. Closure + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 87354bb78..9b8689d9f 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -16,5 +16,6 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI August 15th video call](2019/WASI-08-15.md) * [WASI August 30th video call](2019/WASI-08-30.md) * [WASI September 12th video call](2019/WASI-09-12.md) - * [WASI September 25th video call](2019/WASI-09-25.md) + * [WASI September 26th video call](2019/WASI-09-26.md) * [WASI October 15th in-person meeting](2019/WASI-10-15.md) + * [WASI October 24th video call](2019/WASI-10-24.md) From d771a32743d2f71b17b4bab85fb7f03d34bad055 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 17 Oct 2019 16:54:13 -0700 Subject: [PATCH 0216/1772] Add a meeting agenda for a 10-24 video call. (#120) --- .../filesystem/meetings/2019/WASI-10-24.md | 55 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 3 +- 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 proposals/filesystem/meetings/2019/WASI-10-24.md diff --git a/proposals/filesystem/meetings/2019/WASI-10-24.md b/proposals/filesystem/meetings/2019/WASI-10-24.md new file mode 100644 index 000000000..2c0e0bfc6 --- /dev/null +++ b/proposals/filesystem/meetings/2019/WASI-10-24.md @@ -0,0 +1,55 @@ +![WASI logo](/WASI.png) + +## Agenda for the Octoper 24 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: October 24, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. WASI and OCap + 1. https://github.com/WebAssembly/WASI/issues/109#issuecomment-541191297 + 1. https://github.com/WebAssembly/WASI/pull/69 + 1. "Handle" terminology + 1. https://github.com/WebAssembly/WASI/issues/62 + 1. https://github.com/WebAssembly/WASI/pull/117 + 1. Quick ping on reordering `clockid_t` values + 1. https://github.com/WebAssembly/WASI/pull/112/files + 1. Modularization update + 1. https://github.com/WebAssembly/WASI/pull/98 + 1. https://github.com/WebAssembly/WASI/issues/2 + 1. Some good first issues + 1. Make __wasi_linkcount_t 64-bit + 1. https://github.com/WebAssembly/WASI/issues/70 + 1. Incorrect size returned by __wasi_environ_sizes_get + 1. https://github.com/WebAssembly/WASI/issues/27 + 1. Make clocks/random into capabilities + 1. https://github.com/WebAssembly/WASI/issues/118 + 1. Should random continue to be `random_get`, or should it become + `fd_read` from a special stream? + +1. Closure + +## Meeting Notes + +Posted after meeting. diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 87354bb78..9b8689d9f 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -16,5 +16,6 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI August 15th video call](2019/WASI-08-15.md) * [WASI August 30th video call](2019/WASI-08-30.md) * [WASI September 12th video call](2019/WASI-09-12.md) - * [WASI September 25th video call](2019/WASI-09-25.md) + * [WASI September 26th video call](2019/WASI-09-26.md) * [WASI October 15th in-person meeting](2019/WASI-10-15.md) + * [WASI October 24th video call](2019/WASI-10-24.md) From fe82d47a9c51c41150fc3ad21b751f2128e86e3f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 17 Oct 2019 17:04:09 -0700 Subject: [PATCH 0217/1772] Post the minutes for the 10-15 in-person meeting. (#121) --- proposals/clocks/meetings/2019/WASI-10-15.md | 90 +++++++++++++++++- .../2019/What HTTP Needs from WebAssembly.pdf | Bin 0 -> 82687 bytes 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 proposals/clocks/meetings/2019/What HTTP Needs from WebAssembly.pdf diff --git a/proposals/clocks/meetings/2019/WASI-10-15.md b/proposals/clocks/meetings/2019/WASI-10-15.md index e914a2484..96df21e3f 100644 --- a/proposals/clocks/meetings/2019/WASI-10-15.md +++ b/proposals/clocks/meetings/2019/WASI-10-15.md @@ -25,4 +25,92 @@ HTTP (servers and clients). ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Syrus Akbary +John Plevyak +Pitor Sikora +Alon Zakai +Mark Nottingham +Leif Hedstrom +Jorge Lopez Silva +Pat Hickey +Johnnie Birch +Roberto Peon + +Meeting Notes: + +Presentation: [Proxy-WASM: a “standard” WebAssembly interface for the data plane, Piotr Sikora, John Plevyak](https://docs.google.com/presentation/d/1QMGEuVD9p5iNbzxzgT4p2PXpxg1MjfSbpbJdw6g6Q_Y/edit?usp=sharing) +Resources: +[WebAssembly in Envoy](https://docs.google.com/document/d/1HLV35OZP0A_a8dVjDo4kwTsovDkaycS83ZLKFpG9W8Q/edit) + +Described the envoy use case and then reviewed an API (logs, network, http, etc) + +Dan: Is there a main function? +Piotr: No, there is no main. The module functions are the entry points + +Dan: How is `__post_instantiate` used? +Piotr: It’s an initialization function which is called at Vm startup, which may live across multiple requests. + +Dan: Does `proxy_set_effective_context` imply persistent state? +Piotr: That’s an ABI design question, it could work that way or by passing in the context to each call. + +Roberto: Is there an api for caching +Piotr: Not at the moment. Not supported by envoy. +Roberto: What about streaming? What if the data you’re receiving is not in order? +Pat: We have a different proposal that addresses this. +Piotr: We don’t have an answer for this yet. + +Syrus: Have you thought about using this proxy api on the client-side (browser, [via extensions](https://developer.chrome.com/extensions/webRequest)) as well? +Piotr: Our use case is not focused on that + +Roberto: Are you thinking about having a Session abstraction in addition to Connection? +John: We don’t have it yet, but we may add it in the future + +Jorge: Version management? + limitations of current toolchains mean that the abi version is encoded as numbers in a function symbol name. But this can change as tools and standardization progress. +Pat: optional imports may alleviate some of the versioning problems too + + +Presentation: [“What HTTP Needs from WebAssembly”](https://github.com/WebAssembly/WASI/blob/master/meetings/2019/What%20HTTP%20Needs%20from%20WebAssembly.pdf), Mark Nottingham + +Roberto: What about multiple headers with one name? +Mark: [paraphrase] we probably need to talk about that + +Dan: Does this include DNS? +Mark: Yes, the API accepts names, and they are translated implicitly + +Discussion of optional imports, which will be important as different use cases will need different parts of these APIs. +Spec: https://github.com/WebAssembly/WASI/blob/master/design/optional-imports.md + +(general presentation of the people in the meeting) + +Dan: Could you use this for general-purpose HTTP programming? +Mark: Yes, there are some features which are proxy-specific, but this could be used for clients and servers + + +Presentation: [WASI HTTP proposal](https://github.com/pchickey/wasi_http_strawman), Pat Hickey + +John: This concept of futures doesn’t allow you to chain futures, right? +Pat: Yes, this is a difference from JS futures + +Pat: This is a low-level API; most customers would be using higher-level libraries on top of this + +John: This API allows you to decide what you want to poll for + +Pat: The `future_close` function allows you to release resources + +Roberto: How much would this API change if you had threads? +Pat: Our goal is mostly to have threads in the background, so that users don’t need to worry about them. But some users may want more threads in the future. We don’t have all the answers here yet. + +Alon: The `request_new` function takes a string url; how does this relate to `path_open` which doesn’t support absolute paths? +Dan: That’s a good point; one possibility is to change this API to make URL access more capability-oriented +John: That enables nested sandboxing +Alon: This model entails some overhead. If every WASI API uses OCAP, it could add up + +Action items: +Dan to post a skeleton Reactor design document +Dan to finish WASI modularization API +Pat to make a Futures proposal +John, Piotr, Mark. Pat to flesh out their API proposals offline and figure out next steps diff --git a/proposals/clocks/meetings/2019/What HTTP Needs from WebAssembly.pdf b/proposals/clocks/meetings/2019/What HTTP Needs from WebAssembly.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7aa294ee64e815455dd95821e1aca68f98bd9fcd GIT binary patch literal 82687 zcmdqJbyQtTw)RcX;10pv-QAtw?(Xg`!Civ8yF0;yTkzoS5Q4jZz&Yu@N5&of-R^(h z9vLH>wRi2gX6;q;sb9$~A{jwpDmrRL2qN5#&9Ny6MhIF6YdtdvPEH6K1y>tG2pR!h z2VDzmV+a~4T}wmzw-3a1opj~(?M!VPAQ)cC%Rz8+L(s_R8XHRJ>KR)6Rz}Lv(jG$n z<Q=wM-L^{4)ly05BwbHTQdQ=KoRrH}_xNdUeju(CYQ}uhwZK4Gm0n`K?{v z{G)|np{Iplq-A>Xi$=iO%HgG;Jp{{dCFKn5tsU+3U%X`f?F~LFE9;k!>1cnu6tS~* zwE0y<1v_0Udz;rg>ASv|dabmflc~O;oCyD`i~scU)%dSU37c9t7}`P52wUhn7z!Hd zTN}K%D`9A5>|g@H_I8t(@7X)NRNWH7C9PaR(*8Rw)U<>(xri5FkS4draDrtr22_9- zrb+TRHYpfr!LsgT7s}H!u5oG~**;Q31ab9)-YuD%U4m$zUNtI3kmdO40UPxMx;dE$ zctQ&@%WiWK)b5_X=!DbyA+0SlA+=N(3-NZ-SN&F*7$U1SGjHm470&y7s4aTLe1|Z1 z*9MerKGOEh69_U-7;GR*FHEC$^9J z%_28t#!YaHK`xasto&^_|7HQwC=DFUw0b=@x}k zO$DnymM%HpMSfrvJ!4Br9gU52ro@S7I4J1MH%>Yj)p z*%UityapoOZ4;e2FTIR%dte+qg4GY$d~X3ZuDTo30(gId{^0%SfY{CU!?+}ur!IPC zD(aym+DncH6-q=8{ovX~bJ~g|*F@!>z1MWeJE43I$KwN6*=r;I{Yn4coL?KjYeQjV zVf)p>-&)@5d+IOk_4i_Qe~sGzW3#7wjklKw`DeSQdkv|VcYZbe-{au_*6`oV|0^w@ z?zi~+pH06_WzlMp`NPf{M+NT!fV*E#aHG`vtxZ#Bb^3P|^RdV&#+DDvb)9QY9~+0c z`d0Ehzj{6p^@5RU?uggugyfNWZ9PANJ+-dWBXVl4?tl7 znIPj@u{$ht_T|GHUMkmk^B=~@A2*)kM~$qP)Eo8N83Y&bg$4cZR^^k9bE|&hwzD0 zSE;E7Wv`x$Dm3@OK8sE_iQ0D@{g=_MS5Q<8PMxDNKdL{?&}B#$^(UoY-#)N-(XYDm zqd-oH^IMx0D#ASD@VCHv_Jw?C+^0xo-izgPHE+CGG`WKU%tufS?^~SoO@kHwD6d{3 zE`tWuK*5PdPvL+>-O1~Z;d{T4Dd!M@tD0G92)Tv)eTU2)n8~FFCJPDZ!JE+0wYQ?8 z=q!zK7caGn?BJ3uKG{oq1OoVx`udEfV4q}rBgWwDM9LRbbuZ-$&RG&SwD zM+DC)nV=J4pb{(;0;v6$=S&kCIjM5ga$VMCIzIXbxlJ}0`QH@JuG6y}5A*TM)- zOOy*GQ)F|*x*~@)5gw4SWf&mDc430n3){(Al!}mQBUzV>(x43>lp|hr@R~k=`-$%~ zWUYC_^k1`D!Y$B}L}{X)VJZ{&Fc&LUbC^-6e2dAa}1iq>QlM;91Ls0oy~>nT6E3bOCE zKSd3}lei*D+D=K9Au-6~>G!>tVOcuM)mP5TmRAIVL4zmjIq8S#0dtSlUFXyO07(~5 zjV)rm!{wR9XC5k##E0oFT>{!HgX4=C1|n%ku?$mJ3=Wu(Y4F(G2^z_3vvt>^(+LmpA2z~{KCv0$K$ln4be~hAf)!KP#c!ps=S5<@rT%GYIF<&bW92bx`(X8xj>T19 z-UaXJ@4FFSQ0>uiuPdpHa4*;UmUwD15grQT$`rLcSC>kN zMEgj)28F4gB)4sx2$>-ir{%1OvwAj^K>K&19^|98ngVXrfg8dS<2!Otf_OX8(BsAf z`M1>`WX8K^4h@&zed)%HXw%O**b{0qO)tE4kLlblWOtXo>ywr2ParYVfyd*U=R9YN z>DLd<7s^=WCqW#CA5+$Y*J1lv+8IM2*A25HKwarXe7Sz2EIt4s%iC5%$2H)}3Fb#uOeZ}BtRG7;eQWIMT3VEEby>vVQ)EX{~@;THiat64QBpIYX0oW zS4gTCGOmBa+R7PZ5UsIaG@k3K=BGh6_fP#<;xEc>6heJfU_uSNf`FcgMFv&P-i-y% zY$k18omkrG*Sya1XMY@x=Ahn(-ksi$oO0aX6%O;wkqXh#g}(wS9bS#=}wY!fJ- zz>M;l&B&SVld064D3}dP;?E2%oAk10AhQpr8{JR4JK^#xE!5;rgYLBVn{5F^88!+o zFvn}XgD^Jm-mw%OU>DSElBV8iR(i5Or)k&WliJk!5KE1FRPX-=Mqz)k`oSD9P6Tfcttgwu3t_Z!D*vilfvJL>6*0fN2l zE3j{{Z4x*>=zqZSab(Gcl<25KcU$u-g(O?Nny}8ygk8>v1u6+$VmUZnqHE(zyL99Hn+)`OySjup7B6hS(QYVUa<(74Ue(D;2v5ykSAU?5EO>bX^L%{O zPc77^>rDnwS?=y)S0w&WJWFQ};mO`r9F5&VctKp82$l$G*p1k7zgs^YVsh)Ue(E3o z9(4(O$n^gfA-|dbm&EmN z2w7>-YKj+5vuCmWWB~S)AfLrGy}LVbez83HL|AGaBPXtmdUjoO7eQtxn7va(HDX~7 zaHDE32lm)q_}I76(KHG?S9BT*pS<3O)0nX)B)O73-}pGHgk#;ff{#{dmr^_1wL8Ke z56Hk7+8tsmP(8XT0qA#AD~+^ixJA95px=v&$PL|N^c#B+qXy2S>u(2CxK~| zGByF|Z~I9|0Cb^aIeug^S0HQ)S5>SuXY~GxkOt1w5fL|7ZaryHcakD%YX=9gi=KK1 zi>jSiMN@gZb22>bJQ9IQ{K!Z%hLW4~fQ!)C^8t&dlr}!|hT+P;t(R5jcuwF7>6|%L z3Xh#xSENh_sG;9!o_leAZQHnAvEtC@lrV03q2emn>rq>!S+aFt@B`|mVyW7x9G|;6 zD&UOVqexF&0>1EB!wUT<7=5UcxF#smy5aCvF>V>7Y%{Q5+YJ6u=U7U!R&-fqyWzVn zB-fm1D3F>>JcLbv*>@bBt*K1vKa(PuV-gV(2VKw2R+Z;HVG5fJ^bha!=lnL)s*82fv`x%K(@vnHVw_UQ3WZ zeiJ2uO~rRAd&^mtz;0OB&HVTAFCc5<3E8vCMk?Mzkh4d}4?15i z^}=P7FB{zWwzs^q4)D6rNc1$2D;TN3N&L=cDo7g*?!fl*UWUG)80o!{=ba{|RxxZZ#L<3~CdWl2Pol)Q$ylcF2@m zG3auA&$#`>LvnM3XVPKz6~U=;AxM&*p()Hu&EJRS?a$D^NlT(PV5@;K@+D&K0?stk zfCX??plMb&^-m5}1nuRT)cg2u7JbQ>{H%oSKm`%~j)TBdD&)ZToWLz|fX5Y!-v_@Z za>l9=rsb;ymj^hT#WC4j-=>?P9G$$>U8v=BC?eT9-}r_SG{%;r>3v86gGDt*uD&2} z#NPSwxaxO6Dk3&xB(U4EN8dfkAmuQl0aF8b#0azzu>{2Ed1LF{S_fleb=dqb#xbA7 z0-an-rpNpukvYd7l_*f`&<^V$rav(mFsKE=2?WByj+T77l&zrvl&t}H?^^N}%zx4nhW{8fF#LrY82(5N4F482yqW)(wB&E7 zL2>v+OOTjS(piFuyvK2E9=)o7Bqzs(&0?ft&eU*aFkYFV@C5beEq5eW^5~YVY*(-f zqV{UjRrMH`eOsQdE&5{Z>|@XRaXyLGJ|s`N{&^7ETMw>I?rCz13W2Ah7H3M%JpptUYd}asVCSzDO_v;v*H>u3 zTaX94D&NXMuxkK%&&K9s9rFNDEnoL;AHR7uyVrPu>S`scJ_aqnX}N90?3O3mCDXxd zSU^SEc-t&b-eo^rb=bK35*8derWUS_VH(vieO7!geTLajPQP06%-=Y$6yOZNPr90K z$qxtFu^bmoIl~akzm)?wYJe^yNJbcT=mS5442S|^Jp!^kuYl(s(T@Q{AWg#$>9|*z zpJhFlky2x4T|iH^^J^wkM1nCsYnxt`=1ppaa(6$w1jMf&CK()N&ZdlIPk-_1-zr9hD1+TRRup-#Ycl~6%@BzuxNDs&j9 zAx@$^YUVa|d#wl_MvG;Ug$`;Zv3XT0&L8indD!Zbr@H__HA9ope{XhRMXQ@ET<_$> zveh<)vS_U?RnYo3k@>5aXJ+_EFaH)Ae~!%mSTE1`mtLOnkG(wOztzjXng3TJlku;; ze7T~e^-C{bU)R`VvkR4@-ZQg`v&3tPkP^&%*uY1G30D*$qb9npeM;hbWmKEWh)hJ7 zJGXf{$KW-#nI22ZD&(q2mV$AiZDk_Wx~2hq06jaX?+H~nw;Wy5_cCf5OYzz2+b{ZN zVhOiM7O{`Qx8rbPbftfnJas882uE*%m*&pf*0Msr6<2X(3Y^@CABsc=-heEp4r{#5 z86}GAFH1j=U^DOyBG<(CW2H1$*qczwiRt{nc39@dnDgXR=V-ewL z8w<;!WA!N}Pa}InTF$k8Nbj4#L02i9Z+=Zq@q;*yY1E?;n)@iHJzGf9HTJL_J+bN7 z9Nku&W|whhdMyk_HEfkbR%2UpG-ir^8Cx4Ap7~m%Ti^3>$SY?!YEfjf zm|erip{H6lgS`Kwr`h%nB|QC8ad>(*mymm!aAL^uY0Q*>4Ns2-?A-xpjY2igAmZr+ zo782@IT;Ex%0)+i4Xg9#pU2}))gy4V(^tkPp;x*!k#n;4vQBn3g_?MrRT?~xXI(#` zw5^Xf4-(?(lh?`w(%NGo%;^U|tEafe$YATx`#Qvw7}pgQz9&#JqP@Ut^S^wIDaEW+ zD5%x}qab4S^@>sYj>-7sspPxB$|4ma2vdV)57!BgU$!2lFj|V_Jme3uG)dNmw*iy! zKED;VU53=rJWs@K|Gt|`>!87Q<^xgUcRLy@~dY7aQxoST}DDJInw7e3Wkt@iA@Ug~8ieCb9jm7B7fIv+QQ(&a~4 zQ9Iqb9nq`j`mzQ?(ZJ+zC~<{ zQ0r4G!WIaZw-l_+he@brVk&h*uR^ZEyal;?^k#bdm#kX@Z)Tzb8>$j(}bxw z&z!CwBbILyxi^mqc31k!ktgVcGbd)CpGb^R_gejcB+ta*i&v@*Z&35HM7Wkd{W zaoh2(PFV=D)W)yQu=YchnW(Qe@np>>etE#5bVIeO-^OEXqEcY83P>DH0&QZN=Bc6} zG{!SA4n3(EH79Z?t+U`Ou2#XA2H+KBHf;|m?>Vs5djfv2@_F>s2#TJ~TJ(2H$q+i8 z>-2%Xzqo%t}<7tI{w1Xdeqo0-QHxLu}&4xgW5?NFn9!0SWbMSb|iA!gL##~~m; zRGNr^|FarYD9k#g6H)r)a8h~~ZaB2Ek2<-Yk_7dz;b1;5 zxer22#htAylLF=ncO*taW0-iyi};I?L%QmQZ0f0+qJ)j4ZVC@&2NW`gF~cO2izbmE zZ7)J}hS#TvZzm&&e^jtB2NpQ2pfF}4iZO%pZ7HHGY$P|Il3kRYX%YK@yhs1;@xf-= z7MZMZ1$3_OB>mJp)dy~4!4Xj0&<~(Dtw~mCNUVOLg6VtYeAJsLOok(6T^p7HNJYW)87z%*V}jz?^r^;)eA_ocDD0x z#OD_)urf3LLwx>bVTJKO#tKY-VFji?vI5h;#R_lc{}u6J`YS86sjONrGQ;hxu~_j= z04`276zUWuN)ic$#$mItHeh1dr`?LAIKg&@GJjaI+P^CNX+6K%cpRBP^pQEmtwulv zUz#wg^|)n|?pjVnT<(@zp-lYb>9D*tkz7vPm|8M!8~c)(ed3^;k@{5X^h9w!SaE|& zQK@DoYd2kE$XUjYCiAiC?)*rZX!QXEntilvX63lJ-P=BTh~xH7olU5z(&T&DXUKx- zYDY45^Gxy@U z>Vvw35=(|uu3)kRn;ejG*@vT8Z-}Y-9I{hg8g=ntK?vaF&_tS+Np+)sf|DIHDnZA0 zITw6IY{B(VIhhk*P*8PLA~PUG-J-W#u4P-+@qp^6`LF2;e&~NqFchQ5NBbySxhgxk!Gp(Me#mCw0R3ybS54yX16OhiMl-C(^7*Sask=+p3UB;w%HGq zr(QnB@a%gSVj`RyD0BYR`Uz1zyBpvc+I8UxA1#0@rzI({!OJPR-l;hfy`!qNZDKf$ z2-cBajE+x&X4Q%EnRPhS`Y2qj%m(a>Lp4F6Ge-f`c9T-=9zLV*Wcy`@>1#m<_z&+{ ztNCv57}VHCDC$Li49!|r>j=OeWRZlbCGtz*8|L*pr@1d{5!b!a82TFgD}HGWE1gmU zP%QY?$g+hRTWMntk>!{nc?J&!81Og@nf|Khthv5swa)uV+OsZ}`8nF_ic=V+58dtG#n{v+** zqYf*KWC!V1RA3m)1%bXh?Y4?7iDFjF@4)yo8cP2aTp8(xHyQ+v4Rc+(tPwH&XcAU| z<+@dH+I6EIZm3q)xC_Dk-V`@SERbAgS=2eX7Xj%WU z`RGmG{={}nuSE7swf?O=cTB&N+&?!TG5tnazcwE+y(;<3UZnrqy7im+UylB7+wNXi z_VqS@ShrSMmP4fb5HZ#AHJttoPQh^Sc`RSb2QX4iLoMEIeGgz0sctX#hLSUL_hZYl zWlOjUYU=*ZVk`~YynW0_WYag`!Wu5{@Twvn?K3*mWH|a}od7YkuxrtrA2H^}ZHUG9 zMXj=3ZUUXbG)v=`zOXmQqJ18_w|n=!B%Nd4pMINfO*pypAR2=7y7Ir4=|dJy{vh93 zC5MI@P3Z}j2Tb}h->R4;3y!ufBq1|VDQILMSSXNfjYeb}hEY;K)JiXGw+Z)YG@h*& zN8aNz0Z+#chx=-U7kPze!G58O7xOXxNOuzD-iO@H+n$04$W^^=DyN~98vPk#%^5ue z*(ff(Zf5t8tZpr!I+GuTd0OHJjjm7e$2%0#{SfgWrv9aw3Um)Rge_sNFB^?^M<}vF zUFk`!57XR{_i%p3iW|_OTZcVvdeEw+ESRYB8PckxC*pohpdjK1h?PzjnXr_=LQ_9E zeE)PQdtFd~t-z_NpGx}_S5CmKdV#6}cFO(3EVH?l>HG01k8U>}#;2G`*oko=RB<)y z^C(UpLLLlP4;;fC|2iu%|M_N9e=u^jY=RjR8%R!AFQy>_F6xhjCui@^_@+|{IR{t8 zCIos~eqw#M>V)D4B^9-JM>q&86RV9g`JPMAgcDTsV|EySUrfldQ6|vXTG^!0t?tnv z8ri0Il~G85(;|bY7sH}?9pY8>1+3Bg!_>Adpn1kmOAdzs?(z6`J0sr%QEJ$~nxIZZ z{>al38LScbUcL|697X3m!K@0X+2Au1fiz|Ajx)e)KVr>VTASrxA=@HbuFtM==_yYN zB5k|nA1IAkE)b08C-E*7SI2BWR}dI;UC~CtS6qkQ3<71jbZs@0^8+Engpd{78pgog zv=nwRiE(4a?6^^%7{M+N5%c_};&OAk)WinE#E{!02ZqQt3r+pi>EA^8FJ5AyqyNQF zZ&CKAAZLChpI@=_Zv{E?@5J=aAZPxKW_|_v3(Wl+LH=g`m!tn%kTd^=YJUiF<;6%0 zAvnveMq-3_+lX*#xwMPd8D4~E3oDuwD~=xO2-t9>s(2(-J|f(HJnv3D(@K)7`!m47 zBipQ83!0k?OPi%Mn~(EGTpX*+73FHZXe=CzLrwNltYdk<2k$I`vr7p8{Om zF6`~@U7k)Sb*SrjiFgFDr0HtQBWTp({mPjL}mA66iG0NMNJrXE0#Z;q-}6@XYrn*Vn0h?SC97|4wy05MLQ2Wlczq-Yc2(%Ns| zkEs)P+D>}DE{XOjj$*%6)~lWy)QgPL3g!S2tO&Bg!*3I_BYc_5wd|O**VC|TL7x9Z zZ7H;CxCO72b1$>&z`d$nLkHz`BO8YzlUL98wW=GU#M>@KbPTqykNpdr(ym79F`XEK z!dnMbL$Xj zm;?70Iq<*SBd8hT5W?^)Ep41=AU|2hmAgk({)F~7(_3#E@hT>Cv@iQIeqShh)2Bbn z)XHf!=XDD6>GZEB|V3rL-1W#!Y~uC5%$G8mSp>`5H62{l(0unIXB zGFJyUiXrkHU&RV453&z#C!!k(=%r}Q>YfC#^8>b^Aq zpZb8G=pI70pmr!N9Z__X#L&lvLPOHvv*qFO?F^SOfz1tLf453E;K)71Sn*4q#?Mc? zGMt3ZaGZ5*aImhpx%!M``G}CpX&t5vNxndC!aGOq}3~j|7xP^6X`W_UL$sxltX(qA?9w(U> zQ&bEmNNhFTWI+A^ z-aW(7dNgP*Sz#A`fgcNa?B-OnIO`&FKxz3nsep06xC*Q_#Phu_v@k^C=P#J-+@Lte z&MH$4?1u|dLlHC@<5I^N)jY_V%ZZiOEes8!eTJ1S>0Y$94v#=VSL`}}g+=CHut-Ns z`;Q^vn;!j14q5(Vw8-)oT4ebnEwcPuwD@NJUy(zWztUoF(yBEk6I?&l_J|<9P_Q#L zF9`T7c9eIUf{dp9?A3S13$MIrRA4g#2dcc2=deo8`K6=70@TPaX^vXQWzNP|47IhJ zZE?b;$&1bh@63Y^E3LQlzl)p4dN`yEhaY-M45cxoo^`^O^3ZrqoQ-IY>yTE{;Vsd6JR8x(qn=$ho*^C9d&)I2>*iutfGS=^QW+1moO>eEw1Ej+k#0DxlPh}gyA?8leefrtv zVe`=6(jm5xW%2Ymt?kH-Zn3j0N0Q8yO})kRDz%lS9mU?3xK9rs#vk?L&xjuB4N(&d zX}tUDi;t&e-)`Z!z33vXPAYnQ0%m3ugaO=ur0!GU1O|gOBe?r6zXUpktJy(+pIQ0lTxE zVMN>lXV!go-NB-Ip*guNW8s33Rb&*lB1zlv-jg7;|kV$;Br9}yY zAPrY0n(9Z1z}`3H$t@BYB%&Rjp9&EiJt0wcA5oArHQ9GvFT zAYos{MY}xBDP%hr2oi^FNs_Xg4|UCVWJ{fjAwrUo0x;PG8kD=@E~F&Fs3fL`*&u}B z{kp1L9Ys|HIK;w-UF2${DJ;n0a0^=1izkX7T1tA%xF{otRkn>YR&>exTtI0 zx6|_m|0bWePbQOD7UoBWJv$Y%PGY!l$7K`#Aq`a(TU+wm;IqZ^#S`Ag-`evBV!p20G_9b2Aw_*6(B^|_@m%k_a+F9$%8#=rs zAkw@f55J@d8@f0^(1=;SB----{wnbMtJrV3zQ1bv%C^6LkN=k|@|I5XUr~|&mM8MI zGxxvYiM(wK{BNkp+b*jAii-TV#K_xP^?$Y%I%=dpqMSg9?_VJJgO@W=OdVXQL|>0IvDbg$IbAD<*KfTZ@xt=kl;z9mDGJt#R;F(!n6Ugd zY57meeM8g#yFXN7FNe^W>i_?7i}kn7I)8AB^*5;fr(17~{C{#w;N@HxQ$sr`L+5|} zmty^m&;RJsKPdfoN`Cw4e!29&tzfbKb&A$dZrI9?7OwRinY$q9y@lw4==)-E#Sj4; z@O9e2l|am!`-K)Ubh(c@Moz}Y5iHBI()EYL3GMfMEVR`PwSC>Jm~Eg1Yvc3& zkVfoW>2U3iG@3D>whU2-7xk7wd6cSm@V=W{#tm+ae!eY)p68$*#;_Kb_11t^k)w~i zuugiaa*E%0F(BGRugTqY$cAR>!B4GHX8Fz&PuVzh0O<;iE_8GpE5>m!52VWfGfmpNIYtF zr+$}|F5fub3@tx`hQ>h$m)5G z+U<{1QGM%IXP*;wk2tK8ua8=;(^gfFno#}W`60~sFeiGytfogJ>jea zZ}Y!eBRDA?F(EM%=n#0v2(@ycc41$K9%4d{*#x5b9_L-;GiDHkWf3|T#Ni3)0@$pU ze}za(G!7V~b`Hk4_>tw!w77wY;T|R5|r$ z(i31egu^W_d2+RBrNlfte{S)7~R50kOuAKfQ?gg0%VFHbk%hw zb#ZS68B+$etVA{BV4awXbnxToNwUhh@IsyX0dQRG3c~o;PRx&$2|Z?_GMRFmgZ4j zd4yNklW+GI^r&umQKBYa&Tmx0^qkc=9!A-&<15#l%RHTEt$rp3JlCwxnBM%9gE*9| zSt65rsC#%9^bOsqeWwT>1YWSu@lZrlgERw$OJldjH$37DYvta)C^?Jc_IuiM5n!9( zH+r0?+F{C@9H);iI9`z6e4}`=1Au2#EQ#hjUcH%+nIR7dPsFu0#q^mz!&b`ZIm0BCTLBG+6vhI#rkGMfw0+n`! z^bYOlSzY(uKm_g-A%u^?H9QfE>D?;a+TG%-!Qr<4Tshd$1fbk!_~o4j*6e`hyLz>e z@}M!NBN~sS)iKnp^n1wb_fhXL0(Skmy5MDFt>QjE>=02o6aNU;QHgsu6 z!`{(CmCJjqh3^-E~uJ5h6^;%WPs`6#cvdARFknJv@qbl#Y$q!JUV#$h5U$~<``vRDr za(>dq)Hg2nDB4N%ctG-NdI#U)1Y}V^4);L$TA=;n#9>|_?B~_kRUjT|k=ieGz^w5W zJ>~LyqIW^8jQjB6wTmNxZeEfxc%niZ7wK0 zV9SwaC-r;w7f7N)`8G`|M0Y3V2G|`5E;bnW4-6+xsv41OoncmeY)9`-)z98FBOLB3 zUVvY7e)risEz#}QE4nvdU(Pq;QP>6QC;Vk!JXlgPENpV;4@ zT5r(^%0o(L-$UAuZwIu<;C%I)4lrMj#F#MNgQFw$Lg z{T2}Y=Ouf$XMXcS8#qspOzp1G`K~Y%s%P$$;2)3&5XXSd*MRXNZ= z@W3vt!1JF)?yi_8zdcwZ z*vhDc5aBP-`Du0c@{4Bkl4 z_|yr}%=MwK_CYT_5jPTNJtT`Wtfk8GxrM(v2PZ3yl=EzbCYJRwZFctVJTMgo#ya+i zdJOtRof9yp8y4e6QHZSzy6XJgc&Kt0!RCeJo_g{z3kO>owrL8EwPMUJ@oq)>DzGM^ z)?z4iD|s~&CbJU?OwP&4&4L*8prE-Y;XJFpibEJ`dD}^eB_07b`=dnWin>GMe3d%p zD1P?5J3?*C7+t8QRIx0oQzK;olXxU>ph?77xPT;j%!!nrDV;m58izft2B>$$2d`;% zNH+tmQu;d6a&CX@!VYU>IXC+DtIYSTxbwG{`yxh2QNd)7nZYq}(#@*Sqv{Uk#8YaD zLaKu35S|c@oT-PfdsFVJ9Ad<%`?hnu=h>&@4Gic(3IgXO2z7qemMr5$RZ|P}*_}&K zxgYV>Kg*_@S`bNINCY|du_R}hR*yP7w~~RUEd>@e{Vak2^WCkyJ>UxaR^11GZsX1E_ zZPAcyY(a%)X@(Pw%819>zy>HQwxpS8Pf$b7AZ{|*&8*hm2Z@e|&q_ck7Nl(eH)EU% zOI(LtqMxn&d4|$G-J$@p)LWbc>ACeRrxwr-0}?*Q*m5;Fk<1HRm1#1z4(g>{bycVn zloQM_@vD#Y3hQWu3O1>aJ;}CqcN_#DKLFa?!!;g zY>|DwX2e1c6QsbzC2<2MPlG}q8Ay)dS|AH=BM#x8Nfub$CPo}|QTsD=fc-A#Nu7}s zJfU;~Bup1u*u*grFS!!nMxYI!zUn2yiGM+;KtlQucQnX4YdZ-y4vw_Tu_pcakpkfh!GS!Mm)Py7zI#q+DWC*TZ3e(s2GP^>csQtjk)8J!Vx@5Piui*3*Xdx6l z=((c_tw#SeJVO76j_i^K2e zhaeGdR*!LP!#6Cf+0o7# zG}WWXVX~HmF6$d5-GB3SxdVs6@jA4Wd{o@XhL}f}T$7Ih_u1DbVb|C&}I4lpJUQr!A`ZEj$4fn zzw>15-JPU9IJ=^m-C8^$dLZ7|k)yY0f`Gb6S@ds4Fdm?nZLsGdz&J&-s-V-u{9K~= zYPJaQ*wHE60?B@`hu4O92RuE6a93W6*s?V5FA`orfcOv9a=Y z<|1i4JZ!ybcg=}DlM*=Nz|tS(vk)elU;kHv*kJzvAsfD6Z3lI@xpf&Sp74@>hpU6I zlyxF7LXX{O@uhZ8j>An&nX=6}LHG9;AioB|*XHfu0)pLb z)P#1fn2K`xVT4nLGCHtTF?BuJK49SS1$5JRW*39MYqq~l!HF1^dsmYm>_hMu8PI*u{ZVNd3M-2rfJ(Dw7$2&%+rAMN7Pr=+PM zHn%WOt7HQfssS0a88cZ0$lR+B){b6(gEpS!-mrI(%$<# z_lsFyoS5sLYYQBCPjI7AWI7fvDlQUn&h5pG-DMki^A(V`8Y8 zd(S!>Zf8RK*nMJY@lC~>H1>4w$cO3i(TgRxJc+VY)ZM{b^4W))E1fd7XAp8_rOM)9 z(tfw&agRfJx#>LFywYmG+_EPd-eo^$^9E}eN?)V0Pl*B_u4Qov;ZR^ z19|LuoOZV4YdGBAD~WbrJzLG8A+QBI5XF`H53Qh zo4@FX9mP5?<=VHc*TWK+bHLl%${%hg^GORXY@)Wh2xzp2@vfoT=`1H3o(V2E@dvex zOa7;*>EoZd+uRD0s)X{=!)=enH=mEd%&b^+VHuGM!&JuDOy-ub>DhMj`}f)!yUIsU zapPt?m{o?K=cbATCwC_btAo&h#*jvlw2`zBwBxkmwZp^->V++1^nI9zZR_vN#;A^# zkH)$(g(Cgy6D??5L%wa?XZkv2Kk%#&J z07yW$zehQHOm8PoY#Zmou67*UPTv60DsRI?Q!PPNEkRYOpfWU5mjvDh=B2`lUnDC~ z9O-zlp}Dr#lj-CNas!w}yGS`I#dmCBVwVFDK9-?a%;c@EtFFGYD|g7{rn~~hYR4HF z2SBr_nUE!egHaCW78fNkO zZhR2$^nCw^w~w9w^q$A2#Wrm^r*3A)^?N_NbivOaT751WqX& z=Ka8X8Qivm3o?*zFLEFyw)KE-TPSGI&I?8nrm~UIU1>+a!AlsPi)o)y>+?lS zqq2590A9w&2X~PtP>9Sm6sV;D)wH{5_mb)HE8-*`q#_b;k*rH4>r$!v zQfWz=!FC#>w4NsLrbl0(ze=y~6KuzWw}#%vyYOJp=N*Qv8>83vZpU{Oxg*ob_@ju& zM>Dx@SnfJR8o*_Eq!et@E}ezWU|z*B4wm>&Er@FW!5(fNu)kzq<9tYajJKOqO3a z^TwNRj&FZ;&emDeA3P)WtJ^#B|2#~sg)ktN4wkkG?fb$`q!o@E&(rp?i;Qs?go~_H zOgLwyz~EeDrD8%mDI}d5L?GyohA*EjAb`;(53Py{_`@}4}`ul6DgQ?y)O2xWPKddvgp&zX~R_DsnPR?dmpON7K51dXXbT_!TJCPj> zKzA0<_8r4kljX|#WI4X1q>kRA5tsq4F}#{#%W5s-vzn34YGqN__Q^8rXvCTS{6iV= zq6Xj^SB)>};#`>A({(d>=x49I(v}~9r$5QJ*3=0ZMt8b?9a#7qko-CPd~%l=3iR(alO*ko7mch;{bqD6|t{ zXl*-fUL19(F`qB$rYg+l2-L#4yPU9 z#_-UJ7>*6#138?A4;L%-f|JK@Qz!!UVz_AaT+{U{^c(a$bYB1e0F@vEl^{kzJxGEU zs07!?-MjGsI(s&uy)9~;7h&P)$$n`0ay+(6~wd; zZU#T0@rP{F6K?=yJPBWd1E4`ZuLPE1dh)M)_g{8n+op9Ft?Tv7?c{^57slOuX9t#- z-gfkNUARSGd+XlE9@sjr-cSDie16%q{INg0dgs=I6j8yhCK8;heNTSJ?~>xQV=GL|5b4W+I-^vAosj5>ig+@f zpeJ0kmgDUN>KVarQ`@nfsx+(4m?|8!J!Lgf%Hph4H)o}m=!~<#*Vh5y;02GoKy6=r zeQ!Xv!G+0;HNbWw3G5}nQl+R z)MGtauhUd&OqoG575R)_N)=j9lmedvOX&*cUWgLaWNvEdB+HOXA4K&U_V!>y?!>lW z?~x0poHO|na?b8KZCyWo>*l}Y4?T3t7n?rr8Z_?qv5TL0?3$~e~H=& zvnl_tKd$Y(9*@G;;%8poxaZ`@xn~>OAHHw%W@ynFpxgYy)5wk%8IHYn%)>t-^9m>r z3N(EQ<`vDpgyRTp$Z^c(<4D*kFH!!6#sM=;CtN*juD~~d0~B%;g^`Ain(M|K?HsEg zquv7b%c(7xb!AP%4+M_J4@AU?QgWc%J!l5EeO?#6%I!XMwX?(V!hf1>@P zP53MP>Vq^QHW8#I1X2?~Nz|7cu@gltS3S&NSPB+pr+BoC?N_t1k7egoc4K$?)aA^x zFJqDv?cNWw{Yp#l`mp;_s+yfhv(o%IWt=jG8i6ERWf6?5BT)S_U4gQGiG+#utm7(r#zX*n8{U?-hH&I(^~)>T}$ zOmpQvjb83!cl0rt_MM6koF06j9!h66+Z}^=fmKAbDk7Q{ImBWSPD}9@pHGhgandNG z2kB$!FMUkw_}H7CdOz!7@GM+itbp~Uurg?XA6NQE`bVY@YhU&il)m^nbRE8yUn)1- z7He19uMXUb*5Y;iDtU$NW^I-Iw!oXNS3K@AfRC-wc$jYD@oKv16Hil2301~56bm8^ zsQXh5~DD}Ks2`GB?T+H$Q+a@UX-ye%5-B*W{J~?1J*b(a_UavY{z#R zq5eSzFhK?|K?X3vC9NFh+Q}TlSI$nBvyx$#GhBJ&TY(*tUY-j!uMBRJym_Q0H;0EFi+y6o^v z9bYY2xcavIu@64TAG`CCRSV{>yyen4Yle(mKXJvzO*h`~G#9D7Z~lf44{W&f-pby4 z*X%AJj63dl8Bdyf^G(xduD_#gdMhN{3b>UlM5BQ%6?+$iMSZ=6&vT6PEEroeI$N+ys5U^XeCN587sBKr__q_lXsvy;Ucc}nbYJ5G<8viiW1aq zBwCsp<(hG>@jpz$ZmaNYGN87CYH8Ra5FfXTg$vV|35kzM&!SEKYiCTnZu~$z@Wq8Y zPGaemJ36nq`tOfD{~>wf$)(G;K6CALkK&2?)t8UH;ZKXS;FJYe{?h@hKal@x{=59= z`E9>^iL3p^j=c}A162)DvJ+gBReYL_4GlKpynsYWAz~fR)nSoWNgbH{h|oyjqjGUX zpqc93PMwVdWEnJg2GscIP|ePL`}T2-`}UoDdfz^{Hye9k_jaI_M)eZgO}3xe9=9E_ z3CM=i>L7K5Iz^qWZdX55C7bGy=rg4{Q4}1!?Kzc>QzV5to>gN7LV_sO@#tw(qSdk4f+pw*#jTl_41%g)(YOh8rHeOReD*!>wTF&aCZI`fymYbz4pGb|zWzKu-HGL}2uaxTJaE6yZ2}%tw!LabEMnuauY|$T5)<+sPtBL9+IxK`X9U@nv8*ebU9Iok>)5+@wP0?6 zJ4UtICXQ;2O_-Y$~J3ov}#rN#|>20@C%kv(vlD`E0a#4>BuiS}v=&4FN z!ou?-l2ekGCYLBTE8@KHmBJzgWJkEkCRX?rE?7|&^Oq==?b#g*U;%^(bNCgHJ62Uy zS&5=0F=*-1Sj>fFK=wTQMbH9Ds(B1M^+JMaQKKdvsHnq6is}K;O?7}M(tZ?WS}T!p zj_9RaB~D6NckAgP9Wy-iZmF~urFYX*dJm0qUERry^y*lg4K&1yqYTHG z8e&9ogyDD_V=$8t%`pd+jWgsjXHE-tk0Iphx}dBZ%l5~Zp+NKRRM;540LXQK6;vZ; zTv-|xG^2uayrIUG=n?XBkR(p@HzUUBWCG3&q6kgtdq{fY8%r*ov+|CMT3%k4{~11O z#o!A@jkxjQ{6~16D72{`Q$@5n5W(f^IHZj~)=7 zo~w&BG@PPiWnd;Q#sQH}mX$-J zy31?&^8qPM6&>+;-Bi`_ZF|nj|K_vK{QJMyjEC;|GwyxnOEr6b_RL?WEj+yH@lOfq z_w9+7@#TN~3{T#2@Qpqj?s_c$?VT^?zg)YUYPN>~zo&wHIZ+7?8SZ!~9x9vi;L>AG zBnK=G?m3cp%qT0qn1V}LtX^S^sikS zw-`G1BMe>K&7H=@{rV2Q${5H+Bw3UNnU{Gn6buK6Xj4JzR8I8yy?&3M6C+$8f!z)$ zf^sy0{i-WLV*{B?75uHhIm+rKu+?b<>{sS5M^@T?9C5qq2`0|qvbD5LxayJXRHs$M|&)YXajljj= zSHc@A=rQ9g_J(&zxcepH1s{x)xQ&po?f=(XQ5S?T_0L`<{~zz9o;mHmzSAKyEbjKT&qBbToq#_nJk|(Dyb&L1s=z;yJ=o2am!pI`KvF11 z7(n=FJunsnF$V`;u7Yv8B2{ilQn@8b8HrGcP_3YR2ffW5u@6S!2*BS$E_C z8U*&uQJ^f17J>W>oy6fXrUY)kaC>{aQ=XF1_6YliAG*G4;VMd#f>Hl z@5sNk;ZONT+P2~GA3cKcUFpq<++%mZcyJ+i7F6c zlL0ZTE|aY;lWCVJ49eq@B+|heW(UA|>cj%Y;DgYgABko3FQ-e$niaUxRi$39)VPSu7)BTTQLG?bFxX z_Np|u$&|S*iJ9AA*vz1)vg@^RVZE?f08s*)`wp}LwIaS68E8B@fQ}%+9fyPK5hs}A zXtY^_#peFnYVL2W=B9$l40hJskMZv{_Ru&(r!{PC0joUM*u1!|tJ~_O18hulTYt1Y zU)n>>T4=dJh0nPe%#!`g&}Wl5;!<*@xW>N5B`ORx+H4dw+Hn{hcBi6PtfyG4r*yNP zl2+9pXU!dqGt)L2r=YK9vqq+D=H-kqjV5};U}1GzF7Cl`kKq~bY4Y$MoJOYAY^JkV zZ1(3OrjBy&u$rP%&ov+GHXXr{Fdh2N4738u6^C#J4uD2rLG|>Ro25lFN6zoHr}5<* zU*3l|1UFtgbjkJHcPB&buh0L4$|YF)!i7{WiN}a>WrMP^GNeKsAP!W|Q!nCHaqn}| zGW7%Q15n)*3z?zOOIXLR6`tk4k_DB=1NirNn$vX9P~3@HE=~(D-L`32H$A!y_T}Q1 zr`r;??bzn_)8n5QXNBOIsnl7r5(=FK2&AZrtO^{@#|70Z2(Sl&FMJC?}tUL5tg;J^xa)-=EH=bgCI#TRX%AhfOhq65VmPN84 zc%SU>1L@C-w5@IKtX$^J@`g7{+kSfrNME*x%h*V7jGGtdGKl(?RGe@E!#~M&&mQt8 zEOp&aZY-d#V@Cj`D#`m@zdU&#Is8?gFY*#!#jA-327mct|^W+DJ&mge{JB z0mr(4`=8CIWB*~2ia%zO9?qFo6SXaq=OLk9Ub~xZ*|Z#kW9wxQe-7WmP!l|MOJdG@}gdJc4%U}!B7pHe)1iQ(LWD0U4 zolG(8Me9$rI)vR8(IJh@(dwhj7Xa2bUnbWBolTyN7&jo|l)WS(^UJhV+V7w#wUOFL zCs)a*?7bZg+{OGd`*O!>yKEzZoV5>hj3cACVUi(_v7hTu?<4nf_el518@ZA@4xRQ>le@)D+`Gs|WXJus3URp|_X9*$ zR2JGY16gX^&~C6{+b(!v2e!dgq#ZU+jI2N{(^V`KkK)cnI@a6Clo#Sclh7i7rXw4- zxu_`+qB+XBx?mT>X&M89y>O4+Lpc-#d$>;T@d@jlEHMa(r=Le`o-nj)fQVQ#R)tgk2}TyYu|}r8zZvt-W@weWM!kjN%qf50P-|AvLgg!f0Lv~lV%>dEt!=Z zUifZe55CHgU9X6Z-CBjInhGr zd4N~;vG5LZpa}LGqry(?)xF+GAQItuo%h-Twg~@BV29%s2NwtgBP3p8xW;+L1&nZm z(4btTPj*fBObtvAP6=NWxixS<(L*tgbH{9o&oZ!lR-gN*q%lR|OUJ>DwGyXU;wK&)y$JaVh@B1MQ5IJ zX|3Q0}w2iPzwPZ{QKnwdHrbv_HRV zrWpXEO@<41fK z$eA4l(Gepy+qJ+;M(Lxx7wZ>$d7BmkL_~q0>Fv9%COs_^atBMvN;A*O#d2v_KvdR? z3gxKLhrYQSj)yV)3kU72$?UAj?5xS`|JO*te?~t-J@xmgAZfGNw8dt%!XM0A0?(C& zg<=F+Hj!`v-5n7km3NJ~?5@Ud@~`FB;A?h2oEzQm=KL+fE{A*ej)gDgySkp|@VXnO z-Q=^=7+gc)cHtY~VIS&+A2;rvo_-`vLcu{kVvF*n)cN+7dXr+6&?k^dpDEM@hNMRe zqXQ$;Ibm|LA$^5#4R^J$j$0?(jUM2hK+kdSqIdnDq0a)J1;bGxgQ|ox1wJR-6}%_? zZkkW|tJ1apY5wgmf%o6p8p$G>8Q3?H<%8Z}l`ur$3Fq&{NxjlRzktL9=Lrjh?jWH&7ISh$E{{n{ z*y{GM)$QT#ka{@n3DVB;Sfb;xd=C$mA=+IYOLQn96IA;aIeos;1_} zDStppSBO0#7F4+4=)j^>xu}Q@N>}jzT)jB^@I#OP_SO9E&8>L&YgE!M?>fA3;d3Bh zALKv9kw4F!cJb_oa+%fHYcB4<(?0wF&)W5J{>cxw=MUUgoqG^xw_^2Y`Su8;+CE_Mgoy?ToAn=KG8NU zx-hy}S?;*Xxl&!@yx0DWv)%cH<8!ADwqV@l^txP5ms3;R5t0b|Rnbi|{e_^S_ygfk zEWq4hGuGT;_-HQ%0w__&U?d0(4VMHm+a|5rp2|EnHOQm^bkV~<6!4jl>>Bh}Q>Dgp~QZm^TBW*Pft z!oJWwm#W7fRgWwgSCtKC)~OG1xrb1NiJO_ND3^qcpALqF%Rn97)PNw2#XzB4rV2i>R=OBZ$Q5$;qk9Z1e349G7}$2d}bSZNJ)ioqlEclGG}0 zt?d^3TIX&0%JQ31ciHc8-s6iEU9LWfv^$axE9pv{MyN9E=KJ?cquGE1_C8ldZi$dc z%5U!zt4QIL;1?)HnnT#JK1wX+=a?~&0X)l@fnB=Eu^j*EPV*Bn`lQMocAJohmc$~m zB=Q^)ajLuwj)_7n(kEJyiVG(X--Rd}w$Kxiv2(QN?ZpW>LqYr%~eKgeg z0>w%?=^4W+CUz-lREaC8dE{^qnyYuzD5dwT4EIlHJusc+lt2sMw3`~)^kTOqhVJfh zb@wDHt)YI!Sa)vBAr_u04y{>$UmRc4yK0ccADX(A&Tx|YBaZJwV4fy#06Dq16($ikBPygL@S3Em${IoOkmra;A=lbt{ z{`kLF3A>z|o@sqFI~ae^&~o*v6A!(b|Hu9Kef{#=E;@I~u;Fu(ff<=WkI%m1&)%TuH3(5>6cWp`hwlHi{)K>VuVD7UlJ=t7J-%iTO3wo5m@O* z;;=4C2_y!+kJu6#N;_GyEpFx+ydcIgsixU;7;neLnDrNijp3tQ1jp~J@W`hYN}jY( zF>ku%^p5h5`+G)8=uBt5>rn2n&gRe77emqAe{}i)9g`uRdz2RJ@kv@LF8ywIZk9 zG_gE6((TC+y*T!A&^UudHga)4j{C>^Nt1t(zs1k_f5aeV<1m(+sm6;_JWMsBTKuba zs}Yqi#y3ngqIRnhHRq%5+$l9;#`nhPxnk(G+u&y=X$IwRjjL$rv%o8h!MgaSJ+tyB z-uZq0_@X`MZMyEg9m1}YTRzU8eEfE7|B@Sba_dXmFWG~=(5ed979;448{BDlgx-v0 z7@+dOVvxBz?0lRNsD~TW9fW}y7AMbP3)Bq#Zvux*xQC=)LW1bj~f zFCl^gkNPsMB3YR&L6%duf2s%sr)%m|k$%Ko*HXY<&mj5B?zky$7--aE%#jslnu&uHXF;Uw1}nSs%Ra zm99PDalhZPX!&x!l8s}42`Vk4)+f1^=8NXd;FCEN_{7{?0&5hY*`6<$}dJDg6<>v6k%{y;DYUQ^vR z0R`i9tGQitYfSaYN*oDv%?H3PjDmtJ$9zGr&lhxSiW2j=fpohxr!%g*yt?jkE1Dei z2~L*|AO=+uxS;NIDvB%t zi|SbbJ34_KU6gCxDov;|c{BwFt4{G~F}CP{Bil4XFb11!yEuos14BLZ0u`K6MVZeD!IKhB)Sk!DH27>_G+DXVzR8`>!0Is8*1i{x*E;Q5@m8k7_J2aI|izDvB zapVq$ciRmGnA>YPP=<{e30l!G__Sy$kl+rxV^4x&V20^4Y7cbMBvraOOznX>pjrGL zICAwFnT!lDD6mvTO0A{|iaHddS_8m4QJR`4Yl_D2DjY>z;V8=}W`-SR9+ScbrQplA z7e3h%qR!B%OymEA#)Rt>F1pB>U2lAi6XS=U`x6}fwCe@3kQv*6LKlB_nm)}~$g9D4Elz%2a@5URcKYu~t3qH!9je4O$ zWTVkru`5*}d$_97UR9N~5A+R+45=Dfm9yun=G*60HT7L{N7XK#>}Piyv#Cfwf36!Z~MP9u0gd9%`>#-`SNpWUi0U{o7{KWwfS*BNl~V6E;zEiVf*g|7Q^U45+Oz z=W3o!m_y|E`Mmx>GR=vSgP2MAa1mEGYv=sUyU$y4{(uD^&cQXq*W7SbNo(-(w{BVU z?08)Xlhqf}9(UGHsWhzuX`&-PIx4}h8P{MzbCwGOgyDivU)owqN=wV4 zHPLgUi%Qp*ibFhg{<`pJ|LAZ|&e^X1FzbDfv_FAsN=exQ9A_%QUT=j*`N zp}&?KEG?9V;zG5v+S^yCcN)TI=Xl{#;lq-D^2c>e_c?fxphy&Skm`#%Y(Xo|5wvU; znp13~7;~4uWy8A7ur=9QY`mF6X=4&&3l@iMk697ABUZkKxd4rg&eUWfP0CplY2VwH z0ywcnS{S>yYLJ@=2hZezHwTQE16E^NSDd-XNs5pT49@!o+=`E2z7*HvahSu@#;02l`f2rWkR`vd1ZW(Joj2$-?}f6}Vl(rM9Roj| zjY#$2Rx=D+&ytQ!+-_csniEOzX28{s5uc8dWfdHF+NUN)^?AB&@s>+AHyioyezki6 zshxc1vgen`sf(k30tklgmm3w#|wT>H{*lEKwwP+DQJ@1a%q+pb{VTVtWX@g0u!6Y^} zh^}J@D`EwC&0cb-SkdwN=_*3Fj!A?!3ZzgOhV&ik<1cEZ?aKs52Kg#q3H(Tm6=^+NB&=o~Ujn61q8 zHbpy1-x1#Rd>s1B^O^VCz~4fjF>LXdmS(~fkVb_mI!R}MD}0832pM1>MTXl)ct=Jr zQm5GG*gq3L_aDbc9Xj@bhpjsSb8M0e0qAh2fzJ0YFwm)?{rTMstQS)*r**;UOi;m? zAf@YXxv=gsTurVP7vK`*ToavKZVCx5rj992xkSq6E{0Yv7A&Ft=yK40bXkcSE-N8} z5=Ijfq@`|iK@D?l2gVKVa)~+l<|X30ErAne~%D(#p;kfr$ znD6Hv66zN{$2}%|PIQ8MTIj;)4EMtDjOcQ4x$hV`7Sxd+JMDqMcs~tHasH@ty}m&w zy3R+Us)TltXQ`A}$lhVFuF^rE@Ad#J1gsShPFpgJnKc2!4)zfXS=p`SN$gf?pq<`I zsi>-LwPSm@l;+Z<(zSH^0yTq5ajBo`hG}euXN?J_#n}Li5A<@$D6guu`r4Fw69M8q z`aR0}-NcG0>v5L#O8fnE4U@~Tah5}H40zxei{Oswo@xju%*lpzUCnjHsd>d&EiBW_ zf(3Jo+$$wm{0t}9A^{@zlU=>P+4*JuTkQSwyV!wGexYt%Idfgthh%~_c*-r;K7*$O z9&f{?phGp>EB{IU-+FxWuDST`RYT`KMRkq`*r7#u8wGHs5%Vh88LAHT4H=)R6?X)=L}vtpCsws$10Y zZMaudN5`D z-+P2@L}Ga5q{O7kdD6_p%*v+TExkXi_#*L5^4khmz%TmR$(FWWQIEt_u^vZ#nIdjM z9q26to(#Fp(1mE!sSYoTYO3E?ld9>t?ALeJ%*pSK3KjxQ1%qz|upTf1O@WpG-y6Dw zOzzFlIKa?2(2d3chQ@S(40iM@6OHLrbis@w8VAgDKSmt4Wc|1?mvPQgCr+WVQpQZB zjG0OqGnJOV#ls?&9>Bh;h*%`|8 zUYelroEdvcOq+{CGI~#hW)RK9_ZVG2=1_5V@F6q0-3%%`K&Rm_U!uaC0ZdUkFu+PN z?m2h<(#^L1LziB+Cg{M+T0c5+`5$iEef3kbKicr?ukL^9x@$LXx_bG>hVX<`|5;N9 zwcd*BKE4m*b@#QLod5m)<7v6r*NfZ9%~u3idOF z>o?eBs$Q)0(vDTA2kTa!WnJoJo$pPVxoA4n>IhvSG!EQ*5b-Q+rWnpSZUh)w z@Ya-s9vNxJO+Nq;1`mX}9bA3Be-RlZUX8)Pc15 z$0_TT4N9xhp&U?-C=yail|@R6@<{Q}L8YLmr3%>Z5>Gfqq{(|mANJJiF%kulS4Al$ zApQ}41K-Mb@CSLZgFnI(#K-x!V2|fbSC7yq7rUQl-OsD^`8-n;yrn33Ysin)Q>CoH zkClJO1dHp~qGZt38EnOxsh}_JIqrJ;ADf#F{k^8Gt&RWN{{1I>eEP(PR7#;Yx$oKB zfme2L){xVw5h<&`zBBrnt5UF@GS`bM(#)U`r-)M(&T0RLa7^SBYre0UC8Jt|Vi8<% zZ5eU$WbUUbaf@*e3&S4S=B}V&*&}VRbqnl3f*mk!h9e@+3%oc;Igb}oVjs0Z{V8{) z`XTpMQF=7uk$+D-Bz`IVOZ>O&bE~Sr zaXg_D6%-kE6j@H0(-SzJPnlB|ROoJ=4r=iN9jLI`kjl4Xr=bWu3kH_SbZ>Z^d1Jbn znz$Z}x#H{u1`sxL4Ym|AM`{Q=XpYg46vkjz)T41AQgl*DKL!mf`y82*Xc&jkm;^up zbMX-KHBm^j|0QwWr9Bk`UAssxnhSLBzWEp(ya%VQdyE3?^+1-6it*Mo20EWX(&ak2 zj$>tUgvUNg!KKR098rRHn#&5#pSjMRp(?#gvWi?%Qb*?@Y%QVF5#HGvXPYgF;%as* z5xE($xePmzSm@ZAU^%Z_{dDumR-H{^fDPNz*k+5(N@S*PCViCqV;;+1KRnIrtz!jE zNZJ~tKmK}4#Jn8m8qL_+sgwg$obFJAaS}_w?)cd+^YigbpX49CLD+S2H*U=@>zYMM zug=qTq;CQN7{q2}jWO&!aqKkgD$c~}fmElVleu(LPb@kOf6OskfuRkXc{OOTIRmS9 zfVu74&)k-oGqj8ps7a?#Dm)?_5cqLW91*xuVUf@x6a*ghib^Om2H&{+O-_@VeigP_G(TWs%#f3yp3 zYGV_)OglhKgEg5XpYBASBBba&a#>BnWf3J-^F=KpVi94BD6tmGh+0I%BElA-S%dC& zi*Q(k(;_^U{is`n+ag>R;jzpR-6Gr;;j#$3m2D|o1RY#5#@Ot&DgF?DNcl_Pv$*iC za4b#&ay+R7BXNb}lCh}hqlTY^#bh|7t8b<7`qYLLNd*F7M{2zbyLc8pV9A~?7LRA) z120=Vr?{{lP=o~$G!{f)k$9JttlJ}$fOAGHDECO&W6T;%t&iXcdqAZ70TK3q2n}Po z=mR3mN{O&&Q-p#QGnXP7eN@B>`bX#!dLdGiWVcT;uuC$qOQ!H!2-DCSDMb|WI0kto z{{eX{K9BrGo9LwFJsmZ?%s4Vx(qW=td8!>R-}0u30k%XHv#gl&)zij$ zwEt7{m)%=>{p$}uyDd5G>_tCsYnU~9#SlJy_t@!|H0;{EqpN~EblLPFcR$f}FWI_$ z`S=I!?E0W+Q6C0L^5ZRrN8m&c*{HYcf8{>+9N~_6M4sx&GGMu@bbO!wR`6i35ai>s z*WvZM!J@{Z->%vnn!{pRhb3{2VjdY#oyGkY-58Iwt7>$I(Q^V76ms1TZ0`zKFE<8pP%uK zpYf2NagRS`&f9Uhiqpw{)SOm-U{1SwnA3a_-8u~S56$zj0k*PI_n&ECA7v)?X(uw) zd`&hDq`vc%jqMj*iYlv;%87c~B|0M5sk(~{L+5HYQzgn6qd3IVgDX})cIC%SkB-;X zwyFi^FL|0z-@AGEqA~ri>smrqUB2*~yWZ?#>rD(Re8E>h&)ZQ5zqG>_EGBk;!9<&` zr)SKjREV8$OKM0vPds0qA~wo%#Cft@s}FGx@ec?N*GIWW`G*Im3DcAd^_)BBzc9E^ zSg6d>7rGbvX9a(XeTpd9FXko*lhli~%edLXZ1plt4Mcg#1whp^_v@&Y4feg^Va`x_ zg!$MJ#yV2>lI{|Vbrz%f*02mCiW57`1^9}SKN!(rILcGCeI<+}U5eAmpWUm2_B#M* zMXy*$!(>1^7`r&kycfnaj&h_qXlRD5GK1J)0*W&3V1ckAelWB|Y$`7@;Bgd~2x1|$ z;v)TQeI(Q`OhaYG<@tMZg5I3Tfti&%ojaE0sD{fzw|4Y}tzukyq*#71lZ~o!8 zZ@dnbU7erDCx9#5D2DGbmTGz*{VaWy&ez9V5?t^dBU&OPMEN+aNpzk6Ss~Y(shD+V&C33 z-hJcs_bD2jpP$Dagnrji6fZX}vylv`3Z6+uk*hSZ-d7(Q6-QSj`*(ou=u6+RZy=aWm?9UB?GjPWP~=A%p)IY9|iyF|1xwqa*{YP zZ}*0yHpwA+qdatWz)^#&{_Z)}RSdi#It=2(y3=qrIa~gp_Pzv8isJ11>FS>Dp4pk5 zYwv4@yeTDyN;)-o_gwNzg8d>Zw0c% z{ZjGfZ&SSarQ*#m6>t7#Yc(9(xitLNUKZW*K1H^0i|wyzBz|9`_@o(+#2K(++1^ME zn;|u9Mus&;v-IEj1smTJbN!+xHeP$pPg-XSv+qcyn_{eOz4?i|j-9Xmbno65U)g`~6_%85LE*lP zat+dZu?s81N~)0 z@bM8VyH2l}Y8xT^GZswfN_E*-o*;i&$|*fz6go0A&XP8|+RIl7QfiQ)XJb`DLa z!0wf)awqJRg?uoORVysTw1Ix`mUaDR*Iqoe-+%#qr=}HXrH?KcdhU~DLu#ilY}t=E z*Tz3mHz8-btB`yw)x9OeX3J}N!l~1ip)}!;<)hB|F_xjoF%&w6PL3hUNnIwjOoeHM z=emcx2NsVnoLRWUeV2Ph@e|<wDDWY6T3 z$==DnIp!Sq9M7DTIo>(GEu~w^{JiMBxO4B~NuK(Y8KpDI7Z)uqZYaLj^RV}x^835~ zsQY7{r@cQZd#rqO=}V;<<<1DA&@mJ_hGNHHr&o89pgW1uon-1fM0zh4DyW`hmX&xt zT28byT}$bfpTkP_!tAbciZZ)4dsOzc?2XxPWb6LyNcQ~f_p`M~_TAYc`{&?*bnv5` z{fecr_W*Cl4k-H+K}tZ8r*CXd%jhX*#rRMIMd>yr3=54!*_AEGj(y=lrGkaSZO%Am7mfjN5-I2S(l#Et9Dh1 z+Ny>sQN9lxfMSv9hxYid<=3OM`(>ARJKjLSHnO+~r2D;yMeLf;3n=r55Ek zcJ|~d8$IpKG zyKlUuoR>Fu;mm>O6=juF4O>2P$PML@ilN`RJnN##7xgL1%MW{sd-Pv2dD5B*&v4sX z9RFN&aXmnpN`$|N(dwMr+O{sg)j93oGU$%MBahE1Wi8~cSRD)v*$OFMpGQ$CBjB#^ zdmsy`DgHnq6)L_H#1oGto_LkGVGeQ+nr>WeG@SiqR9s!qFo*^ZjdTd^5Zv9}9fG^N zyL$+3!QI{6J-BOd3+@h$Go9z1?|yUd+#j=Mtv>tgT~)jM^pEa+s<5^=Sbu!)ShQeu z!+t^3wexQV2@xhuP`5yj>@zM(PO>la6vRqx8at+mQL1&VDmAcSF}j6uB^KRnveHOd zlk_y1O%mW85S%M-vi#=Ls+9nGhLn+vB%6S{!SDuRosski5`#p-1gBuwQl?JZjRp_Q zbCA>%F?rj`XY3ES9ar!pm}>5)c(g9MYORs2|IDZn?l7d&aM+jNWgo~-pHb!iMcll2 z)THG}Tx|GOiI(vfvF7WPq!1j2=(}PpqPb4`-_O|Cw!3pt@s+X!f(IkBmc@7}W+8if zx@**fvMZjZ&C!x9^JkX4-fk4iw)E%A`?L9?0DP6L0qtetV3 zcerpEzU{P8XeR2_@EtEK#@)F0=3n?;h}cb@yA)nD$1G&q-;8LIxAAIB(T>iRYRg}= zN|@#3YBZQT$P>6}WtHn}sw&$OipP#+7QiU^`VlhZABsFP-Ys;t?Xd*44M0uP>n4lH z3rTwGiffjwFU7C;wf@rT*y~-$i2@YbNWtr|nN8^Ww(xeE9wilc(R~Fq+H~KZ5gVUe zbjzs_`s0$N_p^9XD#jj79#;6+<DD8WYZ`fCygzm z@mga~H1fm{H5J>jLu7yslu;z@ zeuD#E{Ep8~3`DT8A5KnoKb2C{dEJ~+xuCySQD&I_j zqFM^aojBcC@>HXy8LT>?-ete_z95{p0s(oaXSk=QEi>vy8#456I_2Pa{fmIS!^fp1 zH1WHm`G^W!*Hi-qln0I-MtM=$^d|BOhY1Fqa1!P#(QSViT4>|WusIo)e z+B&H^$L=-&dq}k{M)okO&9;ljyG*hT1LsoC9ejlVMWgdL2T$I;I(FWpkm0KMo$@>C zO<@*{$Tr+Z5;y6K1}60&nO1{{wt{cPXvMGl923bo2PQ4DmTB<`;CHO39yBLxo#FdV zP^UTm2JbuomLBwXva!vVgjz%MUn^ZV{qgC;O;lf9y-!uOEXO0p4`aL3*3Blxujzl- zZa4n2#<{es<(kA<8Xw*AsbLHHeWFp;2ZYi70$BJps=A3!WP9wC{%P~zfqG!ekjv_L57GL**)FyiG+yIrx#)P?IY)ca zWOue2Z#5})5usX7g_Yo@@LhETK}cuz%>X+`onZ15iCXy9LMXP%w)r`q$p6H^etUbf z*U$4TuB%C+K45VJrPP z(l!zewBS<1Q+e3lAVMF_$~Tx5ZxsTGrZykN%fdk>(3C12MQg<<`4aiEbo5xf_xiUvJ$g+aW#qN*BRRpY}BEb?s*+4)}qj^yI84b_nG z^XpUta|NOi1S|;~H^tAwr?tzpu>x$*Ml*~B;*4nJ4%n9TDRB`_^w&kjPd;Vju*c{G zEJ%Hx<4GHtzrIKPGJ6i%RLP0b`}{_k(>-=BGcs+S>@nAk_=v_YUDsFgoSsBsoP9(Y z%e>VP1?mWMWCE4uG7GfQj;u)!4=O>@o3>}JDa}IiJyqVAK8|ZDAy0K*9VJp}{xZIv zrkhQyRJL!a&nV9Ad`IZ0idqmv3Yv^UiH>Uz*Y;7gSK%cT_*pkaEFFEhCcN>cxUef? zyH!+5IJ?{+pH1IvpU?+)(VwTh5jI5Ngk6O#&^QY2zeD_zNx}c!U`s6u^2(+W`XxQ; z;&p(WTjH#CbK&8t*&&TthtbcXfudaO7|)v~#h14a98;?kocQ5z8$iotU){lW>+>i} zu6$y*0%(_9vw7sNY#V|sopKUN)%3YXyV~jX-2+?K)LMI;>$tOmyC16Dok(bq_kb#0 zh5j0i8NR?oj$BfzwG5RaMt*aoV&-bJaHMrHqF9W>i8Jg$(0vk1jN9hiy!l1yq zH>cjin#y0DbU=rxjRPRn`)`}m(vI1cKMAiOOHdlHkpF0Ff3@h6S?{*vtuE>WkL^qz zv=8k?by!TRej&|7BZAuKRlsj*bn-T4HGPt3o4@j6HI}`g53{KTZ1q2X@!b|t7%3~D z(gVP}Y4VSR-r(Yu+1#9x`s`hQ*3G^h$W&D{wAaWiIxRPB--xL0@Z`WEwGY$hAG`#? zC=tN}^dnA?JY0INydfFp$L&xkiQRGHw9&g$d?RWGDvCY3%7@R@RP&5QkMHBnRV3k& zZt3nZyk1j|E{d3dUVm+wd>c23rW*tVl5td1B7Q55oEi3!^)&XVQSq4FjRyjuBm|Po z_nXuap70Gbj!TyH5i1^E)YIcvs%Snh1>iIc9aPbkX+Hg-x>+uJwX!!fYXa1El_|Rl zUJS|Cr~!CXJB&SThY=UYHIcaBrq%9F`Iy^6FZ)?8t-&h&SNwI5$shJ$145wzz}6-{h-|7kUB{oCb8FN*XGQR2Ns>xd?u# z_n0Yk5k#wMQTuaUQ`hK?hqA#F)$q$0fVh?0F<87%)0nmr4%C$wI&J(V6=wVEehH+1 zy%o1Do~W)I@#LVewwHGc2wyNCwWD`$5QuGo?8NL~u4(7B?es5@h<-Ane6sKaWkYmh z>A6$(r=U~IP~9d!d3k%kcop$~k);AAg@&3fgr4-@A2*0J^f%1g&(z#+eCcF5AG*`_ z*+SR^pAqP!wrx5rOFV>{hH)=^8@xSiWbmO2teM;Kgh4(v`>A~6#P%Wh0q8lIwu|g8 zvPWn-uRY%dc|%#O5hI(G1ox8>E8x)jG2mRrqbX=fM^H>;tSY(qecFe)5jEYM;*DFP zwaU3CVKB0sG_s*BVn;&=x6I2TMzKnwsmpQq0@Wx6(b5+KwhyfJEUt~jFDrUT_PK=6B z<3_JC#?Tr*WOVxoQ`#Y<3b!@ZdhM$6E$0jNEmwYOZNEFo^)-;;0~S4^$z~{^4$Mb5 zq&0o3k6lNyjx2fYTFn1#YU$gth&YLu+^(cm^E%jp9vl||Y;K%7)nE4=eax;(5x}Qp zn94exUK-OTXf=C^w;o*It+B)Vu0PzV6QkxR;K8NpX;?Am_9MGVl5~OAE#q6Eisp-= zer%iJ_h8)WBLfUMe3MBM=?=%|->pV={uYxoV{ zwC)KXbUsFRKn+qKQ;f^7O{UJ81h_XnwLTRaIaF<6NM2ISXt#P6xGR=wp&YjJ{l4>% zMho23p?vK^atyD4qybm)Q?1Ay^knxw-krjnK4cMR1&9k>H7cQ$? zI4(mf%PDFveAJ$3QNm0xFUz+fHAR~&;VdInh|jn2H*ln|>(*GYt5N|p*8X(});Ykl zFvM4r+wNaYPX_K+Lwb9lNWK;M#ury93mXcoX;QIif-Ls4M?K-!7@8gFoz%1>%os{j zaMjza{c1+1(+m<~oA=c^CZpDGH5P5gDx0U&MoTd)1?9!Pp@wC`y{NoUatiXWy1ZSa z88Bn%(wDiVvu1C8zv3QH=ByW_Kl3d$$-c$B5WgP`q3kJ1`YCMYqLqgSyQF+)RX~!F zOfUB0Wy7*J<-lh9;#%KQ#&(wus$yuBv;Qm5ferLY*EIFD>Q0Cz@lFCgP+xX;tG`Qr z&w2(jjoxc_k|g+HW^|H!8#i+r;lW3OqCx#TNW0Os%a&(|k4fyv};*sV4H$sCx4miK;uXS*#Waiz{ zFk81R4f)DXQAPgeuqv<=b9~}B%`4g{(|GZ7u$9WaU0&E(C5(cWmTWfZ?yb~bN>Wj{ zRmno*f)5Vo-(9Xnkh8{%C;}#}MlNlw{}>usR~TjuXmr7~K>3HJlsEC}{!X>8SNRwa zKjC3qU%=0L@@OiEg&}*!PFNmEQ2>KPx5HHajh|iVV8Q&r+)|h+iPdq06Aj}f%Ga=N zd>I`hTHIKpl4UV?kZ*|3&@sVLSwqKG2OooFGR-o7sSE6i{;^%ThUwd@sqU;6be9=(x1mwXnqnd!93r+ilDZ98FbQ zvfFX9&VH_Q%ATkgtee}yA;dCDxXvf$=ScFNl#r_%=^RDdok%PGQf%}M?hG1p1e#{s zJ$O}#A|d7c?Hb8;!k}dAIU+ubz$qeYoR0}!Mjl-|8)TEOsukxI<&zjmsZQqeTIEh& zQ|U;)Ej^g|^ipGMyU||Nbiev`Tk?7~7X;e!-=51U8^*ZM|I8s~qkXp)j45lI>GjbU z1PUU0JD-;Ks!#P+eQA*Qfjq>Gqj~Am6|w8|PwzQEU|Ax4uX@R?M3`R^2W@!S7?1Bm zFn86q|J9EpaA13GiYdH>aGXnFIwZ$Bq3Uz?%aEG%37CJh&Y{p6Bm%`2y( zHb+{Qoy@r46Ja?$BmAff^!A^@$HRCZhPZ@c>-8WScI)`k3SDZ<^J;fk>oN4_6;BFt zmXt;KR(E%o&ST5BTHONU>hr{DBk+i-E4}*X8`ICVGL(BmfzQr4-PvmWZ-(nVh<337 z@;~1cQz=Mv+}F<7FA8mn1CT*e9#iLTUgHaxr7g{r?{I}h1k-rnnmq1Nu=t2k0Xd9E zpA3p_02{@fU-d&@a$Q(9d*U|&1KIH-4%dIYG<{Y_e3@iCBqHE0B|L&oj5Pn81;Gc@ z3cpjRokQvrR(D8WoBR2==E#k$h9^M^dHKrqowR(H@JBo9PI6R60;BA?5K^vlppHS* zvW&VF=C2>GUcL9kWrz+0hx6XOo~wvB@Et!q7TcOvqq10$1ncv;66yf*5RxRosWanBPxXez zBg9kr2F|1Z9&q!;F@e{*=r4+9wpy0wf*(dtNy0ngWYcVT&ggxxCx+w79&g4e+HI5w zng4W>&j*J*#jOgi*v3469x)!ACS0F3^1fFnr?YRXLR7(;AR#p2)&%ePwKL@*!fpBl z>H>VmB57e$M` z&-yQdM_aU<8L|^)`D-OBzR)mKY<*p1!m;$H;7Ko5% zs>HcuAgt&(Xxv&J~0KHrx3A1{gM?3evhw3L#wLGyahzYtb^eoxpHD8lm!8}?( zdoX9bz}n@Qegv@NwEo#ydaPrAUzdvw+Pt_j|C%!;x1(UstWU1I(vs`zenPcVHzp;} z61zU+h&y_Y*TNF>VUqsk-P?%oF?H>47wc&CQZRc6NsNEvDgUZrBIu`w4k4bu($-gh zX{5oNxe9}K{Ot&Va2Nfp#S;0bmen^)^Ad)pb*jN*30=M;=?*?`*=CNMd7!BPx8Bfn zm3^UU^)97*V<2<4^*MLgt7zw;)qLC`a1LKmqPhL+J<3I|$rP$4hN$K`gF{Z~`{$<# z-`OmehG*{)1iWTA7*l^m8PqSJjX5M=YGpTPxm?$03YDU05$%phGY3saZccukhXb}f zmibwEyxfMSlD`yLyjLx12SQQVi9UUXhr)%zdRQrO5ZUIy z&7YpBw~*5d^T*$)6nuoOb#^TvPi6|lq4**KDf9GrgUxwk9CkVBKc|qqoD$9smg=|U z*|sCuB1^sJpb1pl33`EhQy`ZjjT9gy?pp~GOeI+omTKCbNmmP;cu|`Y%=-UyOWhAA zoCP%ka0;i3c>cPTAe@tKdh@KS<-WT~Z0H7Gp>%AJcY33*bJ@_1Gt-hd_%a!xE#em9 z2{I$omTbSB4BwSwTWi{9)y7p&Jy|L35aO13VLLfdzx#DkV!2A-C23vEvs@iqreiDm+#=X) z0^+b>?TFm!?M^4RWc%!ot6L;jAa+82wdr?b(eQoo^IN@^1qbI11Xaf1DKAsktL|Z$^#0;2|1At zXA<6FR=*T3KapYB;*(qyBK2xrvuD-lNpess47wBP!%-Mo;}FsvH5X+~B}W(J4e^_7MYpX~VOpt9`uc-kIkOx7 z(N$q&Si=Y>>*mwsBj%MnWHfWrONc*@-3R^m?(qOBX8#ZIV+^2TxfA0%@{z|r5zK;h zZ_uYR^F9K%n|UgV)-9TigfU>JaOUCY#puJH6JLU^O|fOT!((nV;YFSwVim@Fph-tt z#xv7hio<15!ue`~c`xZnKL3a#BrrM4W=TR3TLg`ynhOus71^SpCy*V|poh6LHiWVD zf_VTVYAK-krOV^PUF2uu{9XOt&My~mv;*LJ>ejYx%(!;i=e5Oeo!m69*XrRh z_%Q5Re`9Ol4tihRKfOI&y9?=m(nb347ivY%?Ww(Jkqvs&+V)%)2=pajL^-$&Dh_gk z`7QYQ@1=1quhSgooq)Uo-}|FFl}YmWm+8-^oq{Q(vBdADCy9sH7B?FGR39v}&{;xX zn{FVCiv@%)tYz_DeCDx+^C+hmMJ;xB=zdXk(MmMXj^8vS653J^+bhKkdWX;9jn%V^ z*U<7byaJv}7qDARe1@($^@qkUIKHl_?NjnWLI>z%Oav-a4V&1K>8B>vg>1@f=`Z()QNvtre1a zx|{f<=pD~SIgkCAFS)=!SnW3wmu>oLUo8uJH|svQ@BGqHzA7 zK0x01^AZXYqW8er$xPOijlEK-_Px^v_%+-s&tUriU80>RPFr^AYPX=h1=ncaH zsbop|wF@p=q7B>EVqkW@FMFz;m}KlZ-lL%^C!^Xw#?JxrS%d?G?{VqDMZv0W%y)5k zC&CsCyUM-CDv>hrOm$InXNUI7D@v5_2F|6KJq;GJDV6}sFwg-vgE$-IUMZ$?MZgyDoC5u`Z9%;4Et_~1dZ7;0(U18{vZX2W z_EaM&cC)uUc;X_+yv@IjcFmd9Ge5ZNa#1uI;C<{*L{Q>wr^vjmcZYP18;95$`-pMP zsmqT^0d+CB^(8iLG~i`q&m-6OH)r#`X_Qdn!ou= z2Vw6c$NQ&%Iwzk1q()Ci0;n43H<|!PS07m(E%%@U%~Qrq(7+{3`={M1cgN+$!%BCV z$^7D00nYOOuR8A*3?B*+ks9av6i34k=8>x%%neBI?QtIzl~7r?)z-&oPTL+ zOrc!6CzhM9&JR3M8yOUt+1$Z*(u18oaLX`7c173yJklo3MKRz^u{19|jX~7|y-gwa z!m{)7>3ksdoP9}D>5Cpmd*8e7-D&LHef8x`^g&Xi@&_XL&&q}weX%=BmGk!S5N>1b zH)*Gi&R+;NR@KGhQPmFm3X10niHCadZFYpw;@S6(n;Y!z_TO>Vb87Es;y(gvXaW#S zGEwwL3~`1QEvMQcmeBS_5wUaPoTiQ~=NQE)mQe0C`b*axL>|fu*VZ)~)jqx+&k&cW zjd(t3x^222K2hvCaj!MSOJ~(}_+dTqCi5ciKXFPBep)$KJO@xQgzR-DR{<>wrdT|> zs{${!o4$@ZMUzN0jiNQjXB$=CbNe{2x z0#j@}7nh~_kTYaYePG1Fl{;2axsJobqo)GBixkNmL$=d&|&%(3OTd zW(T3dx2J>XMjRzs73G_jls3G++U9hazhnD|KQo-nv?AZ8mn%@DNyU;bgm*``I;zcn)b_TypFa9m~#8t2`(Np z(;RY2e$^X}HNAZgUGgI)`={Xq4@z^Uzt)jE37&y?Jjw?gl%t*<@%yi61)ECaQozt$ zz(bJ9zz4D8$-OJoJ>hOwfM+s{aSII9hd>`M-YD5-rVD zmeeBQKRx5sLM$8a>cO5!BiE=Zng7T!8@rFNHI&~8;$dPpU3T++i>?-_XQ{9B>b3T# z{r*;VGn{I9oug>BpPq?3=F*ApvbsyKK|b+m z$92(zyBqnf5aB(jdXQD46XPTNRJ;*BXHegjE{OKiwl0m$S##ZD{M!!hx$CcX9bjj6 zwmkGuGYsNG5Qq+vpk?1S*%(vH;;mtSlYpV*T=gT|1+T=Wt(%p6c&VUi1#5n~*ybK} zJ+!m;R_=ssA?F3LiNl0O&)K=FOE1|Kcp0d5MXWDgp+L4^uczOCYW1m&Jaqin^bX?e z!xVcHdn-leZBD0gx2Ggb=OxJ7Ne-CZXPu=%uf&w^5Dlpx6}ZK8tzS_g6uSCI;efuw zlWi7>?vl)nu>05dm;2n`?oX*eXN*$9QaA$G>Y|3C7jPXdrbjpxqzC=LcE)D+zH=H} zca7~Ar_Qb;cn{??oZP}0)cVyfN){CmPzi5tsf3NRo6VH z=*vBwhmVdeFOI&_L3|AswFIzggYK=*!|s%X%F*oMKPZ(6XAn%^+WGtpxK5BhwW0e% zKk$9?)D2)!uv1=Auxvi%5--Rb$_=Sh$B8D&7bE?>ES3yZ$a;^}LHr)Ya>~U$sWvg?VPtp^eqXS)7 zPOc3MO1mz+li37dvC&)=8Wzivtz(tD$%e17%F)}<51+q>Hs{HK#uAqrne12UiGB>_ zp!EE8wCw~=tA@>X>dAz3E#ssNY3jd;1h^&xDJBFqh97(QddT7r^5i-6U5cBq&9y2V zqvYwwGA(mSp1O#86u|x_ybWSAbJZ+QG zf3$aD8P6E1*qn-LDrf~fR0wv6oZQ(rWlI<~%0ba?_`F(s=L9X3)Z4}EE3wI31dY^z z*sg9v*PgZ8?DORm))Iyswa0DC&saQcIfg7P?9Ck3zPTv_ubckBQo)git$iy?!3*F- z{-u&GhS?#9Eoe6jW!bj$<0SSn*;c9ik6GEzLpEpckoP64nwvj(6>nc(s@Nqv;RKLl zApQTg;SeZ{GqKf#dT2e!4OhA;H3wIQ{?xpXs2fu7s}AY}9?0Ir(`nmD=1+6o$vWlX zn+4$?n0!2}BR$90o+aq#O?5W6*shB$h*U?vC*ai}4*Dhwt?v6sY|)Ryo0?3X(~Ryy zW>5dEcOAM*-mG->hs-h)dYI3Q^$*cG5bE&`^nqLDIGM7JH}U`Q`Th976rv+ipFxmfohJ0R8S_0v>n-F=L=W--q6hXJ z7O(M6h0gwZlXxnn`FaLNPhh5f;~x3u)YK^h^Lul5f4uqvtk#H^BkU!O!AO@f@?wFW zBTskOJ;%)w89bZ<@b0eAX9KwoYnj-6>Wi1ZaFpZ+Nt`#eB4E{FtBMjsG9<4euFF#t z`zi%0-I-6(?oyeA&{qU{9WQuGI8k|4Bj4z5hs>Xhnno;HA@s53M=7M|AN1)e(ao$b zblRV_eD5LhE|M9Ts0_@f$|GInHIU0hF9D3+u{iQdSp1)*s~)zwdc=D0Ii3<9CLi-5-fv!Td4_t`1rfRy`zX*=LwPND^+x zDc)#8G+X~^)=2^GosRa^Z2gXLcCtoGgQ*4z|EO2W$YxYn@M1VX98m2T}!S_$L)DweK+_Jp!pPR`d%{brbimc-=L<>`L=udIyR%z*5 z3mjjq)gswL=PF*`rj-gjw2C^#9kYNo&~A`8a>@wX1ih}T=wrD!aUDi^xm{`88};~dI|3f0`4YU<3|n0LBh@69*WrNf~v zvobijRy{w-$ulF0!w!4=(@MRQvZsy~F{8zng#(dy(kvs3WJ^z9rPZMPM^Z7kd}8MH;1>pcld51-OIj~!W2VT2W0i4^nSVA!TEB@*fK(sVGTjN*~doY z7i;oHpx)zwTii0Z7Pe}i@vNe5n-UTsz4nEw4k@jznK)7L53S$)ovOKm3Y9bt-hHN) zxGoJ&-9gsdL*1h5e__dIdXx=EO)wpBNH5XccOecEULb=M07BGirMu@^G>~Fj-qptg?~>g za+?dj(=qqnoNHnD>0@m79H$+S&Gq;Po;Rb~Y@1A>Vd&gd=bS^_T&=uiY8fl7Do!#D z5}S0tN>QG$<%lv4ATcC$?kdv>xjtVg+?K0P3x8Y*=YbMQKotjr3aLn1Bz*3BC97x> zf1TNEnWY9$3RbGVO+cM{=Jq-7{yI{AWLAFrN!|k0ZRZ*GOG+~quNVT|^a_kDxMg8k z)7i#URr;2HsRs&#z9>_t#e%%IfEJ$r}YyEys) zf+*qGh+qajAid9Qu;sqT_v6)`uuU*1RHwG8TE|$!^g7ajz z`Dh2? zveq$#5vmS^sm0?!zMEvbU{*`y&)s9URNo8Gm1i8R5GzOq!rCFm!iIEHX2WC(qV*Ti z*=Vwv5^!|Ipc02>KI1UC3GQ;ClcYyKibeZUi?iYsFl4t%DPEL^S{JldY39|TW+ZX) zY{ai&ar^JMDJ5>xxgRjo_3TeQdyS2?HnUf-FED8Ed2CbB&!1cWrbuXzXFTNCfcU*(#{65~Fdn$nc zKGu>pVLq5r1cZE!2~toe(>XS?livoR{Iasw%KQYyw@>`yJzw0$w9-4E=Ejs0l@zy* z=x}C^pdJ@B-=ve9x}8huOxX#Sui0tkHBqGDS+~n|ap% zNtlVD-;ZslOM{Vh5$YX;W1NDh)0k=@YMj!J65V7>F1K!i<&ZTcWyQPXC?kcvfVXAJ zput^nEoH#Kj8nSXW{}dbN)k|DWss2?Wz{vVcAGuhTsX7!URfBP$rn0;XYQ{AU>}c>TYiy8ps$Y6s2> ztN)4e|2+r)FM04^UdS8Tg0u7gH|@l249%SZtpAfb!ov0*U=eie?5qGf7G_oe^FQsu zCa{4OVGwdQ{+DSS;0QDPWBzYJ#|#b}gOrP*jis@WowWV~0FO*lrE$9;#xI>OG(I*!l*?aG^(sZ>19`xt2dJp7!sLj$DCg}< zYqtzmDZ0SajkK(!P?IhG=0)i2&L=6?FOLS54~z;DH31+8#$;2jCGlYWpZ09h!|{|C z$y~k5tA<8${RyDu%pm>8ji79=R`bz{rR`|GtBz@3OhR#PkLUkPa7YFCPs1ONnJ8| zB90-aCY{^O8jCD7T*R@!pef*n?kJuA6-Njtr9YP;dys;&gLM1HhB=@?VgA(3!0`3}aVk|Wz>%cF{J1**N0I4n>24N1@(iw#N6Z_JzXImdp=`%7x^zAV{9 zp*IUyt;v##<4cWUE;GZ~GslNGG=?qgSMJAxc6^#kLESQrq&eZr11YcM&HUISIQ9s+ zeSW_-Rtffz`2|i_frCt0T?-=qAWO7AGi)w&oNkzZuDy%y`zV68P=jP86QeaTzXL0K z0G(dh?}M4Nfkh3-l>)efQkP;1L8EXk_!*_Nw#uG=D;=a9X^aE`y=7poun zKL6@2zD$dDHRRJo$r!6PiClp?`@}P%XTor6#UHrUpOez5gg&%MpP=&%m~c4G07tdV z*UGPf=_Axsc7MWjkI)3a?h%Jezl1n5cT@^aD0T^M z3l?s)JykrjPFi{8_iEK@Wdi27QR`KSdro{;4a-PE{^W~d^=0Ebf;Fnat1cU?twB3O zcB*VMY4_R`MAJKUy#Xj2#@K{z!^q`t5lI)uTXQXUUs9ejCMYhA){amz3-5i%^=a2u zES~t=!s&kLCzJW5yWKDhat>j6Vv1{v4w%*HNy-&y-T?_jrf<%dgWK+)-})^MGHNez zse(Wyb~XXaxPCEH+b*1%OuB*2a|0J_wA=0tMRO&*KfuMs{B!PEX>-fO;i^oKe8TQ% zd7=|QpZAKQ99sXsxQqZDG5Q0VQ2SeA=>}Wv}p?gR)eBw>71LzT!COnL`(e zs1EcseaBgF$eNZ6&s*@(bqTVPMZ3J4pFN|4?O1jbK|u#NqPxpWoJv3krJQdIQ(sld< zGWN0M<^o!5hp$sd;lNK1bsZa7m&AF)7BO)RIt-5Jo)nOmeunkXsF^ef{CbPb>yuw~B)_K3|dB`+p!`?;#g=-Y2m zC7;ojH)zB)enWTgJX~N>XDB9Xt!R|Mr%)y}LzlcuPK5p1NoE9qpz3n@z1Lg&7rlr~ zii#>}MH6DtJ>K0Ypwk!9EobrPvsFKIlrK~Sdz5*I26ENyf+@akNB67{sDA#q<}@?8_+2+J2)ldcSy-)O6*;;>NeK3z8%kE>Ms^ z1Iq}%8MwI{m@)&Befy?OUd*~= zNmbP*nG|hdMuEz5gB*Yb&6~iRDiw^0a7<6H+&;f5wK0n*kc8L;nNWws0(sEQW{uA$ z+IB?9Sjf|v-L!?$yy5*287V{lQ#$H6=2DV0*nt%R>!klUU>fsiS#czI4ih(=>tXI@ zqrL%y?Z)R4FBA^?tiTZcNNt4#j#ohnrK7!iRsl5*egU~==9VBmRYl<)Pv10PDJ;F< zZ~C%gelfew{Cd|A!u5v2Z{0|wROWR5^O)A7xnn*^+6!QL$05LJR)(4uR9^ z`E*HIMtaPDrA(2J!OL<_xMhYFiq8l0&|5FD$HEK6noL$>YTGnLy-L@*t+bl(ZfdpZ ztux!t+ImsmLdBZGix2s7Rm2BwtIkc{QqDsH_fP+6JmlM=x)I8}CQy>5gx^)K*~}v= zrwUtB)o}!Z!fkRN{XX-$o6VQ{bnd&lVU7`?Cm*qimW6A! zMD?Z-l?FVM9$^f0E|s(S!>-kt(U$e=!f9+(jgf&OXZnh2c|$4~DrtZ*1C#g6c~Z?S zY*$|m;%tZ8n+wKz0rkBym;MC|VLLA01tC9qMv?Yh)n?dTC4mhQ%RwqYu0XlCXhgSx zTWddaB1&>p{`kBrjh~8pZjOv;{&2irbV!3X&e75i(>XfKje;6Gnci;nq`Y>xu2uX& z!T$v>mWgER!cqYp`4W!-RDS+8Ra(8UIqT=H+Fh?vPP!m~u7-13>?dZvpA1yvOWNf^1)4q2o6XOV!ZTI}R!X?)k6Gw_VSLrm_ zJV*@M=;69sc#Zg(eZGUd$}ow=cTc!T&iZP7G_vB}>9&PQMf=}$R!9p)Vw|*- zpgCSE0l;z7%&e9{&%`LV2S7cS&AM9hdY5eNwZNYsHsowqpNfVn8x=$OdrOIVOK?vu zUzJH6Vmq;-eb?|vRc7cKVc9q(H^-5b~40VY_Bqj(0z&bpKp@wF%>`T;De>(*$Q?Chd_rqocbGyC~B`PaH9>DO>IS4F6hV~P6{9K(vNjqa*6_){I)j~g|7 zQ9fCYYM$59`PVzsiv~}^p!ysWBY%Dhn=;nJKn>kT7=>W5(Q#UL+^V8z&endtOB{R& zVmJdFnCUV(tnA^wGq-^zu-`uPKHe)7YB$$nuCfL0jbo>(@l`txOVBwUG(hc~n(6_B zU3I7MiP924MZlv0tjIcn&JMIXHMDwETG{E&64}T#dkBiD;Ur zwzM=URRq`hXyQRY*1^wh8?3L)xKtEmW?UR%wvjuEiuJ?zd96g)iqWs+{z_59iGSrD zmfz?V)a!Z9oX;+Ul)L7by^eSO&hLwu$CBd-gV^D^}BT6VLeXUY}0m?P+-XeZ{_=J#t`X?5wack?Ro#lFw-56_;oof%uy#Nx?y z7wN03PiGB(&25eaRCO&lDv_iEBou{_2P5TXSf4b{qKi)u4NbdO4?N}y;j8Ey_*2HQ z4(A3Mb8~}VG4`a`tL>FsqGU!K{Zu4lyz%zRj3si)EtMdioI)F zrI<=aP9_V)Maa%~#yY09GGtuI#A#UVF}1tf)!xJ^A?iVb&lDFIW6`4cH!bQL%cv21 zLFc!*&e=XZWM_F3$GxUF2Jx|&k-WHF5_5^MxVUJaHUXa5i8e0&?jIA1vZ>2DUl-#- z<~&jzs1+DloJ4!&gL9Iei}I9&pr4UG)5&uJ)3QY{y=;Oj%`SS2~2US^N0w z&z}dGWnIH$!QEg8H5)Op_L!<{i9gP_8rh^1v1Y!Vvw8hSDurJc_j`X+0i)i=<+4@b z)F?m(0&3 zQOvo=+h7n3>dIo5e@;0_RS> z*q#>25@G6J<3hLeJvlFB)vF|zl^ivNvPLf{vtr(ji`z9gJ>6Jzeh*oznxD96dFiI) zM%^3D$$#M91_3C^goaLq>`QX+d{F;`H(2aYs&b)a3zOFKve)}&Kx%A&i7*LHI~sfX9fu3(Pyv|A8CHNpB-cHXJk4Q3=zlQgyHB^-tuCV_H- z^#7pk9)m>p+6B?KZSJ;h+qSLUwr$(J+qUi9wr$(CG5vqvI`__;IWu?W!~Kw|WTleI zT1hIYG`XkR>t^j`kS1wc{l0gC8+{ z98o&#D{v?ijDSq;9+=TSvu@T@b`zc#hEzO zt}3;nE-QH6yIv{7dh9E;mg&3TY0&vujw28Qy=vORkTLVOYh}TdusK@9LNSLH>wo0V zri^r*vhU6VBOTwjp5U0^<<#9B_s)Q^48RksJ*jNdGwscm4j!RBb=Mm+w|N*!v~u>h zK??9e{_Fxr0X$nBZf*SZ8J(G;p|X3gbb)_uaBNc)l?(_)31t+EPkb%IP||$ytUXKTL0>YU zb&8|knvDVS#?WTk1?{tX-kao|ItXm>aebKB4mh^yJX%cyXPvxaur)BR^t@LoSem{Z zvM~XjzU2Mh=-p9juW>WDr*S=4pl-LCOO??I-F_vEiSi(27rKgl0xl(km_2#c6(77^t9z+`vaR~(0ukvL_+m^MpMAlbydUJ>kW()L>Q)ntJl+KBmJCEjhhOiJb@_L&=02qKuT zVc43mh-8U|O6zq7r#J!-dTC2NzJ6HUm!YOtv$$?iO5aoBQ|u_!~vykl(b++fw%g_2%!c)y7q7 zETVlv*YudtoKZfBA((6mSJT%HKCQm5F_erfDOH=6P*^HKNXsy97ajXmM8+5EnCdX` zyf*B(8EwShJ#yuF9P;|d_T>-vBnp3p<_)KD4Mb>w<}4=Jrve$dgh4=2{vavJv7$4} z8)a4}*Xv+b+2YNKClSn_y~|i?VlVBX95Dv5d!gt=9GUGw*o@=aFNb~P0Xw$E^69FR zn07Q-DTHp8)qqWdjR*7M1vrxV>uEeZ0$Pf3bzF%)K7z?hw8lez425gq!>A)RAZEHDt#kSwnA2tEm`7ab@oQI<|< zo7)rRQ$*KEA#Kh^^m>Q0tnP=_)cYAjs%=bAa`&O?-|!iJ#8@Gc<*>PvZ^lo}PY*-J zaLm)5O4`S;e*p>}4Ra;&RpXuh?dsiDWy`7-b=cAvVdH)3?oj8y-Ci!eY4KzmaqpiC$6!&Np$P<>2*wn{vSU*JZc$ zboDYNXM!%r&dPazEXk_ac|_&Y!sFQKqLq3#Vf9n(g3rlPcrx>jR)-PkzM?Ir!{fx- za42e)aFgy;CS)^F-0}kle63^+eN}DUwqX;ua~#{uwQ;j#7R^99AB0OpqahP<2&BcR zDaW-BZh;F;7{^2);z$CP0repJce|Av9W+U&QY|<=*9>eE3vaJ zLac4M_jdLd+6RIf&ypo2C72!*4q4DcA=MgZyE9GL6WW0Yy109U+MFS}OR@L0RL#RN zY4t{GN8Qfg?&IZo^4~cww9OAT)0PRvYbahr9wut|YV~cW-?EuxsOJ^I+B6AFzk>t5 zf+34R?$OSL#)OjP4EQ3{CP*7z=@8ilY!#Z-pCq3#WN@fKZzB^$l0gxn_oFqahZRn+ zcM=Ve_w=#%kqq{JL)Q$t43j|Yo6!%ZI_P7|O#G&gry!WJ5)3jBtIa^LWgs>gB1wgT zQxnOg_k4PZ*aJBd|CLV9tM3w!32@y)07<5;KH-9xtqsg&{?cQ&g@5=f0(K*Ahp`nV zJozd%bYUC8-V8kFQMG41}X5(eB`-UQ5Xme&ZL*PQ5^eY2g6LGPaxT@+=#h^ra_V&YUs_Wl8CE z59%SP=6%C zvbj&{y$=T#p{EjB@v`wANRU`acEZ8LZ{^1p<#UB!CA?J`oeH1Ry#p>fGRbZs@M5UA822tCCq2YZf;aE`DmsiBDXxLu>I1h_ir&3s?no`X9)lpw z#ixIYZMUeiFtuqfbnRL@u(_l2em>Ij*#A}a4dSzD8vGqoD@r)fN(qy;t%f~tyiivB&Hea3Ilqc1Z z^O!n-?2{pDDps)M%Ze6z5XwGcP73?(Pch-76DPDFVr3$F6^-Hvk>#@uXqkqN=fWa< zq-%W(o;4=ZZL`E+ZkWg+i|bI`yNiw(+Qi&Dl(JHHp7lU&Yh_{RSPsnNaI`iaR*Bukqni&kOd9slOqlLY@=#7OJ2M_(p!mB5o_lhk9BP4@ZghYj;a5jyLp< zwpEV!2H>bu)C1f4xPs~hcM0*i5=fGM$ZLkmpK3<7vLJ)pbofNkMVckA3vcfAS9i^l z53kG+&lE(qKUw}aLa)?;WqcR-{R-uuwV+0bIi^?M^ijhT#4fo`?DOsF8Z3nKq4bR9 zpx4l&2g?)3j(igOqr2o*`WC&sW>h#S_X)^1*BF6j)|2VIolJfxX@m z%F5eH?zC!#cn`j#S3iBeH-hb`S7p*|3BFPy%|wMP9B(7 z%;@)RxQl)sbn|-pG+ME5*)?z8eBr`tuz?i}eO}0|9TY1y))~p0Pjq|2nQxgLXP2ln z0Ksp~sBZNe?F%j{+c%VFj2KpAKa|AjCHkDookfC+bG5i@Hv1YD0uF3X|GAa84OXEE z0vMSo!5O#i&}{G+ATqy}-UclHFL8JdpsK8C!puN$&$Seh&0rDm~E|*^u=n|CHu(K&e)GGY>DV|gRn zTM=8NxgA5*^w>poEIwVLuKrU=di!N}mNzm_ zhu>^FHCRt`%7uJv9mVD9(=vO~c zV0Ducaz{NIOLlE;^n8)#;(cO5CGMBP3G`F@^vPK7g$9dX7X>n+9TZw=g;f7V%e zKDbqar=GU`GW;b<$9uT>dj9H=I$;cXEV3t(V&vqXDsrWpRra~*$wxE9Ce&WhWmuoF zKSsv!Tp~3W1;~|t6IzME{xzC=SaoF9oM)R>Xf_dJVAJP|<|-ZiB_>&V&0!DM#KfK= zImkPrbc*&$`p8tdk2eQ+gLQak)+Sp)M42#EF+GlqsMA9#$!5uER^K7QLz5M95#F`G zpb?UCDr+d0zTw3;3#ObH{)&ZHAZJuLYnNkk&ldbxx8gZ(@#uJnQ~7QGCe9niI{Fa4 zi&2Mmlbg|8ELnBUbJnz{EBV(${ws5O!CU6LhQmDFJ4??d>WVA?NB;HPfn6QDS;+7O2kH`+`@jy>=J)K0f5HfyvribEgV>E*gd|aj645v+!M% zHP-@zQ|zhuC?~$h`M53Gq$u+5Y*L8VC2x$)9EGxI*$;eF zp%fUlOaIEKBJWa4Qbk*^t670a{%*)T32-hb4<0kJh1f*w2h=%WcU&DYVxGV@UxR6r zQ7Q@zS~b38P9fUN+Iu<$j`#QwNf(Q_9RF&YLgx`aLa}*oML!gCKG4QH^wDu2W#1jT zisQre-@_3LY6mP%CEVF}g`6Jp9x9(;j6~r+Ay~V z=%2z^uW*zAIa`2p&Y0L+0YjhYZY7|P5D`3^v=;&PpiW!oGu}xz8u_JY&mYO9Wo&i` zmz4b7{2FqFb-os^g_Gp{yx>^;);-FJ1<`NBW0D8NnW#E)G(xMWrMAKxPk&F@e?szx z!+bcPSDcs!{cOOh0d0WZ01M}Hwik~J;DB}f88@y|Xin~V?%c(<;XWWTft!KOXO4Lm zOaYBY=)j7hSHF_8qytsW~eFw3*kzb*bso>930;eMJo7#-R79@+4+ zZ~MaBC&tA3Zjr~*k}PBGQ^<>dAw6#2|0(@hTcQ`gagp;miUGa){(+$LweF)G=~mEm zp@Z!!9XDKFBSp0UJlSP}N~;1ONPCq*9rXbLUjN2E+j zzibCjgXEKV1f2<*k1&r?PS|`_tdDurXI|nZ8(CEYxea}H2cmj=KXXbr1?+sM|ep1E zr*_}Ng*OBDd;*-oE_%Nx?hWej1$ENy;JKDRdJF>a4$mF>!PLW$3vgr65i$Hr;by$} zvPYuRII|qKEKDqRr}7i)`9ya1 z!{Us9pReq>cDM|D2KS`rIv>{orn673=PJ@v)3$cy<{oJC+9Ygs^>gRgv&WJqTVa#V zudU_b7_X8j4#>wEFlWgB3r2Us-QHAiS=6$s7`_!*zoI}2Cn!Sz ziGMwubHOn07^0>>rK{7YT_ z5 zaN1AF4^Le1Cq~ih@6LP=8Nd*XPw1UQZoce`3zHwrZwClSk8jckcvaw=*MMgNUo7&E zm7ReZxBTyQe)xl3!?{E8X~J7YwQtv;hWMBT@9mwRDz63Rz;ik0jz39dKn6SOx=7jX zeyluw!hl+igmDk#0+EZtZbSJfKl2^lnWH>|+9T+1ggY|l&Rm}mM^5GD9T?dn!hU_u zl9dxo0hUfGrz__(DjKUrdl~fXe2dYrRt=F%RS-SSgr{-WS=XVGh4~?#FcH%Do6U0p zZ-)SnpKC6?`v!2YyTmMd*K^~Vav+(AJhnSD70Yns`8V|oUEfv2ZQ)|6o{a3J`w_w9 zG$Mn3)gjb_cL3=x!<~$WLZqU&H$qYh2IW$&+)zA~sD)wr*f-4UVxxY>Gt0B62d(sP zCVmU$j3_R3LW8H0^h-S$P(<)ek&RG z=L``7qU6zE?pFTjfdwCFSG<~q+4fHh!KShM>NLGd&s~_VsC`86#xKtykpz#yy5fge z`%OE@-xDnBSMKI9)GT;Wt%w&PdmFR{0TE^|8=M`F+J+Ihrb77=U8Gou)D!`6T+uS_33hMv@XM8hhR82H?J z3Eod?&Cg^u9wV19f59Srg*u?a(qDmgCZ|PR{yyh5B#l}x?I_D;;4SMimki>*$~BnO z3yfy%5Gp@)Jd6B%Cwnr7w24lY{@~(5HKlPA-)4GL0jSH0xckjB26Q8T7vBx_N)<2G zLE3eW{y|>I_p}f5rL~N>hYgNM2WH<4VHz`_p;dkkEEqNR)D(shMeqTujz6aPVv*Fw zw;IuWb3XW{HG5licld2hO*U2QruN`DO-m==1nKZT8El$vLBWOgL3=SB@_DkPyp&_; zvldZ&#!PP1Dmh|rx%T$=@B8GZi7&vu=)=0Wr;N=SAhx-H9F(?O z*YkSZFCFlUB({0D9dT$6#eUmvwoI!I=>4r=`vwMG)+0}#dmewEzVB~fKX8L+F=>T0 zOgTucmr!*{CQxa#C_{mqtY4-jqT7fN_dFBB^m={gmf4POA2Z(Hdd~{k&{^N$FAd(W z+nUdKlbs|xDbmQi5@EQDTbsJfroC(v@0=cxtwS%cCu}zw16%<-3%~lxw*M5|+`F1X zb%JOIHq(XLovAt0ittnsBrb1L&2U6{=G+=aMLQyR@No$YsCN(If$sBvRV%#tLFtA+ zBYH?TL%!2^g+~hxhdSx$H3VBE!X_4+&MG<4U0h)i$|m8Jlo9ya0^wV!l4q;R)XQ~h zd6F6yQn@Fcv8LuC$5dd!6qw}!94+$(=@T3Pz2|-h^g#D8-W=c`IR(PqPJuCqkv%f( zATC69SIi>+3bWt!1<#rBR)OslIvjV>V|J5Mf0itNtKUU@#9Q-pEbh$7i2bAjq>azc zN7|+P{Z%8?Pp;~@T_3F2@Xx&Zv>SpL;t0F%Num^HvADD#aYNMHJEgG>Jr8iE-?aNfTFf9TB&%RBuDV31aN z@A|x7ub3GTIyhTI2QtGOsSfHQWDTM*Fv=ErrW?8dchS1SL$=-^7Cr8#+yL&`bj`-v zdsSInR#M{Jo=*kLvI5&DM>*$FpR4r(Q)|u3)er)O?qxL(_)@nPk(H}T^SF@v9-@PO?16Xmf%>y(KT!4H&TLqY7NKIU{p`PSLR53Qms|>O?K+p6#71Oi z(^l&_uOPlA{oj?HjnT>ayfzc2b#66L%um1$=pJ;ojb^-uFbiV8yWC5+G2djB;ynLhY(M^8H z^4kcW#V+@pH^ogh)&&i$<41zz>xjS}*rM6us`j>hTzgB}V{U)_FIv18F8pQJ%wr#zP9DwV zk^bkUcHb!*qr=CmoQ-Hw)$6a>&5<;|wa>u!#&^%3Y&q8(z?)>8SI&5X72V72Sewy| zn%3tlBhPP_SI$?6sT=0c2G2=X72KMONfh`#6`n|(D$bP-YHpZ=KcZXmYIzbpD4yr88!O>Q)v7HZo*BR|G#{tbMV$fl&h9-f=$mZ9F zXZQGudSIm)yQ%c-T=oMg7%RKD=e+Q{>S+|@$3URGi~)_+GN3v~ZK{XQ0qD(-oZLl- zCgVp`%OQQ&tP@;V^gUuFfT+}L%WFv3M@H;N7I<(#zbAbR6_Gkw-=F9eg4g--H+u3TG%|I{4(8*aX6P=jjY``dFRlq(Jh<57 z-dS9B*k?zsHJLs~y5N8ca4mx`=vppsJqkp+IEQu?kvQwxzUYQFv4%c+f<`ow+OVY; zwll06W2joZ+K*g%eBfB{u+JO`;!v)(2`_P7-1l%|Wc&3&f?MzhWFTU-x~h}`#%Axt)mg7~FS2$1hQ zo%n((5o&DE-n4{B9s{Fd{5*9-oR5 zWi3`tSYJzq;^0 zkMsYxpZf2H_TP-^=cxZ>oc_a6u`sax+fgwvv9LpNaIpQa85KR-|H!Cl7#L~)6QyGL zuPN2P=+6H@ss4d)|IwfSEv5SRx%-i1{|}||{(mWzG(6%_d^xxgg``Tj5FX_vxL>Ed z)S&th_RD*^P68{(0uovS7n81gW@h>DSbEPNHokI9pzEkb++zDDC^zWNI_k+*R!S=f zR~F_N5(RBKCBMA-&5^MLvg|p z))AwE?rlA;N^6D+cbFP3qXah8NgC%OCa zqe=wB;D=2lkjK+g7y|D_Nm|w9=LQf`8nkqr&(P#5Bh3J;vG4dHyF?m#(w&H0R1}NQ zt$kuDK5D%ylYm%#zIHw@zjsytX*$-=V!3R3u7*MYm=Pee!=LCpgEG%>?+PP<2Q<5C zb$T_HYPagA1Z)HaD2J!ha=0vFVdLdQ?1_@G2%$;k^W5@W)}sSpUNY#d1y%p8F0!Ah z7xQ`(P^6~qh~MZ+aCANRHJ4!QXxh)BqR!`n?$_mVdSRJd@h$ZSn*PwzijJn+>+8<6 zr5YYUn#I5y{Tmd(7ygC*$ZQlG1@F_bvc)}EuHzUywGc7J$ z9~V2M$c}9z)>!4h+6@Tlckf+)4prg){(bGlZzu?qcn2GFdq z*_4uQqUn3^dB>e?iOjBPK2TdhJjlDaHjYl(PLfZAglFQE^>4*C!cG)VnNYY^q-rr3 z&fS(9H1mRjldp%%FeR$JTFh*JHt|I8t{+MRs`ZV<4dA&0ZwJ8}G!03BrpV7Z+I~ zL-fM5TbeCfF#ngV7rbDHFg0*tBaEE~5PTP6Ho<~1fq10K2)r}m_zgZ+`gVsO>Zf3@ zFPoJ>IxiU4Ey-P`(jonuHC0OI-U%=K(`~Ah$?YKII$1usz#t&5d5s zmfZO~d~r^XyLTKg5(=TI#je-EvDOVqmmVSo>EnSMvt%SkAJ)54S@}ci!`Z|5DLg*N z>xv5s^DdX1A4b??lO5AVpjz#<)(tCmXg5I;`%nF}!eC)RBd9dVYGLYZ;_Wz}GvTkr zIg-W<+@t&rtq+*5vM(J9v2w0Q8Op4!Y}sNx$?mcn*I!ffVc2G&hqa2kD>j+O#_V9< zu-p6C7D)Ws!wI)9UGO_EVk71#WHg=eSGndkC@ub6Bc3ndis*&O#kk^+g%$J2^3Ck> z{@~@e7~ylwIBRwndPFRE{?;RDxQW@%yEOwcABCBjVzk6ng@M%g<0B6B0hNTyL@GJ> z?IXN*ysu2JREK5hoN=-WoGD-FHihjcfN#7!Lx5~amWQf#6|K=5v{yJ+bR9kD_lF-K zU4h-n-LjyRvX={8?rY8-=HHoL;O}~pNyX`kkxJ)^bcI`T-pQB&+XOW1`9!({?725ph_~5(snht@2Z~;3aU$a1vh`U` ze@sX34?rE_It0Fic?q`V16ES@kcDVcW$6Z8-QsLYB;F8tx97hn5A6rFNz?`x?QvdM zEnC-byswUVcX^K~u6L+je(G3!si2mmm$b<>i8%8=rk_bQ<#w@K5>2TieAwB}p}%n2 zKw1S$B<^<=`sUj^0P~3Wh&hfzvun|^g=Yw3nZuB;hAMWU2v4FlRVJ4~1QZ8G3$V>2 z*?{E?W9&jLu;rr9YMFy`%Vq~FIZ;clscdLDQDqHU?_TeokAT-=9)nmA^6>*R$8jEP zw$}o2DED0+Y?~03H*T0ODq2X^>~_m5T*;Y%iy@A6%F+^g8zDIpHW@t7Lg?$_d;iJ_ z#e6}O{K91fwsglhiAmW+ncNO%;gou#&AEKaP~Y%?1TDdzS7w~) zl6mw#m$pCO#FvDkg#CE)rTS%?#Ik+n;g#Z8BSwigQVVhqwnxjiEjMa+%lm6iP*q1& zcJSN~bbA(eA^MFBhSNfcQh-*jV;I>El0oJi{qx>1h=7*eG$aIPzWGWSmuuMcg&aCF~nZYw`K$kl;X#DR!nO zZ{2xpQsxQPtW|prSTSHdvQ!IHZ?Q?_H?S>E;}YC)BzWnVU92F-Lrn~OF9<+!Bp@R- zr)>TtaweM0t9%#uBl%;4h|3#g5Wer{{G|EZH z&MjmkH%Bfu#^4g4yaJU`OmGsP98Io3tF*o{>)UOEc^i`7_wtrta5{xeW&TZh3Pp2G zSk0MFTw397gbrE-887J}Br_=?R~oJ#cR)DVa7;obV`FV|H|n4zVV}S}1v@DrXy!DB zq>|2Gz$l}*nYuteFAlxB-osf|@$%Z_`T#{=LS&JNp3dfJVwsS!IdoJjYQI%nc;04s z#iW6~v9!`=VpbKawSJ*XUU#w9WLbEyG+HHOX^hs~wEJr%MO2e>sd;C?6(4a}F3FD7 zLrTjsVIx3E@*nZRTVqped3wj%BM!BGsX4=tZ`PI#mza@_5OB>7xoU7g12qQr+86$A{k@Pp5NkY~iEhcx!qn9=U1vG1^IXKn(5B_LF&Wcm)QjCi& zL_vuy(1}r3;wJY%U$kCxTU~laiA+8v9zG>L9}BaOgGkMyqb3}UwU`_iRazxIF7*@{ zlFR6-%vckpg<*;&@r-ED69W<_FLJ6)JS0vIyagfY#NrWCJzW0-aH4GCUc^5-eMyp=XbwIG zF>zUx#wbA1F9-Qn)yjI8QZ};*2;1mX#?m>^3O(5rVG0TNV1Y`SeZ+pYXs*6G55m0` zUa>I?9rWiG^79rt2yYKL=!<<}_1Kduv@}H2~2U5aBQ%cv`y@N5#lDTw%qGU0sSSFeas{utHLAx-|{($!e{4$yaVOGAUb_aNb zTIm_Zo#%;}O*!DbXf4AL+H?r+a8yNG;W7M*pLkLH^@|oN(Rjp@3!`|dKE~}{%+qw^TO}@!_W*u+6|Tw)UKL{O;EDX_mhqE1 zOxStnOb^`=*^cbnlCWL(TkOzvRHkkTbf5}I7FwldGHL1(@T^{xlI=O*V-jDhrtOW|`iBa4Ek6}@>h3EyW+?y!a390LW5WXiB?0Vo5BUy60&DWZ>T!6ILzjzaip@hm-RBP*9Q3Q2B#@ z5qWBuXO-V`5)=a3>>$ zKiqfeFN>CWE|KrObkhSRjIsr4$ksNn`A$g&A@TU_2^9?~vemgO+%#_A_J{`03~VV5 zKUncBZCWPl=^AQUa%%6y#@8O zUzHkNWz133a)W}+1_L|@H67^@ydH@$qnoS#?)qT`eJL~}8ru+h`QG)=jWy={q#fDn z0$NiWAuyOc3$8p7QAuJ+l!^0C%v8b7raj$mB-wccQ?#wEH4ffBfAkehvAXr-0c4Ci z9J;BVFVJ?$ShsFyZ>7_5X+K{;-x#Mh@#B;gD|-7YV|H6PlQ7bNIk63>j9IGsh(nO1 z8K^t6<`?7~(51~MF@4I@{3=Iou`#6zR9a)ojMT-49cmSo!1e;QL|y)H#fHIHRv>J^ z;5*It)Uc|e*M`V6;6I@B`Jf9L+7{$Q3m4E^JRd5-BYD(wQ37tl=W4TvA77~fH221~ zk|`{SV|**C0-VtI2~S1@bszW!e`{MLXjUcN&Ww%>tf!h>2XrTIaGxQ|lmB}Q_r~oF z9yTGiFXRF7ORyUGS*Cv^bKt-_T?}|#@-MdxF~WXLt=?tl*fPb|UZ>c`!DjU;CGVMc zxmC-NhGRC~o$g5GXP%PF8VIPlK=dzSqQZ>z{V%ua#=fh#dGbL}$3>t{%sS>1Z zp>&LJfJ1FhvZX63+#h{)g5C0{wmtpM1G7Cs2Q9#p3ZtpqKY8lpy1Emn=tEIMK(_<} zQ;W4w$l?i^^c?3jj1+&)55w=MU-jKfI`nu6EsbrfEWQ6$nmmp#z*jt1#Fn}@nYzt( z38C)Ys&yLB37L6Uh2YmKDjG2W@Xn7F`biplVsIo zoOQ|BTk}n@{Q+0^?-DsfPb$l?Su-uYkFwrda6W$@SR-?B9Xm;I_7<^Cdz;PmZ;q!O zbzr}@+-Lv22&kabYqPy-g16Ci*_=n)Z9b9`JK1Ed*!szyKe_SMFReS$trZ+zM{!J- z$^aerOfvG0LEgk+_R^7=q6{1jXc6!-TlBRw2=0$lXn905tRwDmS7R^#{zVq1)28 z(-+_()>{7u*_vTFU6U%Ao&cpv0Zg<}{x0`-uu)sN&b&>k7_ABogSLd)soHA|?8enL zmK$v=*BGjt|*BmEl$dtAPlvzYvJiEOwqF47UEp1Y;Bm&y4_`LdjS2 z`=4k!ra`T|71pa3yluznVVIYnoE6?AkDrm?ie$R(QLC(7F{=slH9Q}9-?#KY7Edk* zQ*H|rgzR-%OIXy8Ft8UTf+{+U0oud1e?kTwzT# zZP4V-j|C`U@pRBeL$*@|-Y`jmW(mR7&APv)|7-I47>=AjRoF11E}LutyeOZY1zz4#W_OFQ(t&tS+hS)jPutforj7*vfUK>;CD zXflzA?;1uQyz@{V!J<5`Ji#+9O=z!POGml$e#@J#tJ``CO9?w*k>xvnc}qNtFoaEa zN18)g>I>nf&C8IpyW=~)-;gYv*3#+0ps(`{jDb<76|t-{YjYjHlh6CDBOg?x6<#0e zHyEly5@J$BLhjPFiAX@r#Nqv49f9sG4CYUQaNAjw42hXD?mOl-?EH6FQ$pdY6u;WQ=0<|&+Ly@R_9d^hjwE)A#2y1pHJabH5`4@N1*%8Hx5 z?7QxPnY__KlV6iTY#ugu*E1VdzoW(+iX3gH0I&Qme@_W?YrfYnQc1J|X*n9Fgrrn~ z?K9h2QNXW{ z9DnK(VZjX9?q$#;=Q*zjpY9RhTYpd8i=8MvL+((qD<%8A_4(=u#78SUb(x&b19W}K->!?DOXLw9I zEOR{4xN3ABBW2EORgkQoU4XxURIV0DiUCFT`vZG}E zXM@2~Qb);?Rc%vF-n$XyTu@vUK1yz`i%)%3DxRMv<;F|DV+`<}D3est3wL5wTS(9En~3z^V^*MI$DDw~K#eVc0jb$Lvk^xl*5<0BqM zuL!M;ZQrgpeP|vGs@1io@&yf1si^Ifck9)-4*uL~i%rlRJt zEH;;qxFnddf*8lEE>` zc^7#A|4p$WiJc=p&3hYOh_!SnbFtK&^(y7qTXbtuO)+SpG2k!UlWrkz+YqqSPusge znWmn&KfOT1`Uq-wg{V;c&lkjqQ)zys3IbB}3-tVWI{h9MG2rhH1lqbxb>JgCSvHexqLPx%Dl7CZH#hzK(zkdrj(yqeQ33eu5g`brnb3RY zh{}{TktVIkssd#;waAS1O{Bym%3PPP?%Ou-ZCuAoC)~;Tdl?uMLk+U&nIjRbWDE-1 zqqYKBL_n^HY&UH$?fh@wy)AC^CUIlL$#8jen`#oJnbVOQE5}Uip>A>K!B&am0%-y6 z2rnb_yV6ETs=F=;2Wf=x!-1@>w@GXmmzA-h&bQDuht?p0){x5{#Nx_yo%tOA;7Q22 z+8_Ii&iBnR6Pt}^pB%Q_dY=aci@Ve75OvB20X z<-GynjJz+#_k9Xcx0(z`o@!9?L%=pt<(QY+g;~uU{er z^3LjJ4v!6^piM=gpdE<>4943LV<%gb52mM|#hJCNl0bw55Y#RQiKv8u7;%WiK<|1zx=`Jk{G0|d3J!M_=hh>FPicv*WLz%fS z9aB{!TDl$j8N**az&*e0KR)S3Ifj@T$QhHmB$3;n zd5<8x#pScsvwh-Rx%!Tz2B2O}-1efaSSU6xZhI1DTTmEMr~)|d76cCSn5w!^aU6q$ z#W_-g5lq9a(soK8iJ>|(Ff68Josqy#tHwmi*3PM)`8cRpT*gh#^NBMk;U~*}vMjRZ zsv414EbuOnBeIOaUWT7>#3aRJ;Iw{VYNag)`6yD|$6MJ9lUA^tfH_6`iK_~vl3$>+ z_wHj@z^78YU~t|1VcofEpy_d)0D@tk7Mj4^JLA`WE>N2jj6|{@x09-J4>B$!vB5Bw zP{*X1xan7W)fo}JBFG>;EWKscHX7)xHMsq=g z@i@tuQ%#JKePnZmjT)(Yi2A;9_$p4!X9U>OAH{uG}}O z8;H!CVdlA^cGot}P1gw2V5`|Luq{q!TT+u$C&S9${A-tRhtd+O!&w^nLSt)QCgyNi z?W#Eyg}xdch59kt?G6Wn{XKzNlKYYyuVwH#HN6_@AxDQ?umA;eP$!?_9(ljoPoi;loy9@*X*p5aRqZ0&8FmXM`dz5 zUTd47b}Ge=c0m1exUiK+zMt1C(GJzxhAPy{%aeYXahpybVjNSc*;wojj4IbAXX(mL z_4rV^r2Y>*x-5^)h`cWyRaMm%7Sy-ptmW@XjPGh|m3^Ae?QA0alkLqc-o9Z4L6{vv zL*yn_vTGC_*(-bwGq>0;jYqunXPE!i+E<4~-L!2ZEg&hK(#XNX0Gd+nOzRfIXBvp zUucMA^siDsrrw}Viq~456mqd<6t;|VNtJ#N>~7p|TgcNiDZdv?!6~my{t9Dxz;DY? zNI%A5(#!=jC68jvBFVGiH1ag}G*BmdizDNpW)S;^`&LcO!9jJgkqSukgPE)RxCJe4 zwYJKXMKJ0#!ye@SaF`?6LU~lq6f?UaS)TRSvWHvkTVPXHk;xq@t?_Fa(+kD0S2R`! zG*()^%Z6M|gNsA2aOpKn=57`iiA3SJ4ziX};gLg?)(+N?*4k2tdn_t%X*Cyn--ne9 z_4rY|&RiASc{GdqtmVT|g(XD(bN_y|{dw%Q@e{8N?9weuY9yDz@pm7llRg>wh>~*C zDFozC#OrR)ZYS~d)TuY1az$F(;MRbrb)IKrMx{<+5PUva@)cOhg9dsQuh_tx%C|=EXSi z>8fB$zXS^}ApVDJQ3A_omR!sono+(l7lU!kbW63(j;=N9o%UI=rb`)*^2$|WI)2pb zo=O%f9Y`LnGbW|vn#&N!`Rr|BrI0YscwHFV_pgLl8aS@)PUr1|cpyVuu3ar1H-oI^ zr-Nq39gakU#yl8y?df*~vCWsx#7UJe2JC1bb_N!Y2ruv)r~Syohv8UwtTq*Y3|WeE zs6Wd8k}|LIqcA&VkBRqF!+!8b#q z3&V%o0qnrqh$FU))sZXnS&s9KZhyF3WZwDCX|MiT1hL%n_U`mPtzvxCrxF=jk!G?| z8p_f-snA1KOTy3dwkuPf4oTt(g-NDO+Xy^%Q3H*B)i{c;!%oW&Y^E(g=bTIt1Y)Fb*E}d#qKBGxE zJDBtCqJlvb!u0PY4h!kc6j${3g!}hW7 zmDL?g6m_!a`lZv?M6~Gzh?dpa<=P7B?L)K|0pY$I-MgfQBE2S1C(k)#`dIG6GIjgm zqv&M))JKYn&$_&WQ$HG)5dr)5$#(Bt@Lvc^t{zoAQX*_4V07{?j8@Sjp|I;AP{@2= z`>-W%Z@+9l8rfayT;LgvpyeEt$dq(W8J(TQ3+?z$v#%>3YhJ95H|?~%Vu@Y%Lpmti z_1G#UmZDT%&m|nA)r$?&tR~RU4s4Nju!T`G<&q`0(mt55)4ovYXMBy69{HNDkD)+G zN|-NYVUfteM^gzovMQGH3sWz*UOBhQWx-*1CjAX4-Fd|<=DUVw1>cN|KvAj4lxyo9 zqQ~Q}zfmzHw!8@zC{<<^%vXNfq?*yvF5O)s_ZiS}+pH;)gG%#g^ITnHVz=C_R*>si z8Q0`nr&{%x`i*803$n-gdwb0uNrWa_r@i*^)3#q#w4GORO5=BR-JpHx2Zsg4MI$0g zy)vw%6{hEoM8tQ_CddYp-KE3Zwutp5U3Y%0;K`Pc zUa-F|&H_I$@X;T_F*jE|@IQ|JYCGyd;;9QfETn}e;%DrV#eDvj6|v#=&2YG(Kr%;D z-~7|pk6mXqCzLHeaVziL1NZuGFYN}(^z6~uMdH8hH?G9jNXgx$A$-=wcD+E7irB^^ z(079S8PS5BmyieREh=go7uEDLf+c)}YX5HPIf8c|L*fUIF}?WV4WZ??^Y5H)WqE~U zHwZbace1ag$|g<&+`T;mnhFSgXDo@NR$fZime_G&(b-deu7B56fcV+ov@Yd#0Wo(h ztaobL*L)em*<=^}tIA|iO*giW#1t16#N&3s{5eI9BS}mnL?ON8P*JCy;G&-nC}I$b zl67B^lF%{9N}v7y4o79-tIpHcIM8_OFu63SRhJ$IofoxPG5MZ(ypSK@diCA;5`LV$ z;2~B;C!*a0K{x)nBi)J*iAE1Yge@c4F%n|FOFw<#ul|MU3+W9}6G8aVD@2i3%>B}8 zC2iqZx3jjMdEZ*)H3ffK-F0MuSxTB_0jui_9Y%^y?*oafmxo9?2|VIQl3XG(Rr{9X zqM&6y(i54^;%$rLq|HVci~aP@M1JdVufl*o;mkx)$vnL|ed$JK`v_m2p>cbf8kKm8 zf`y7IEs4pdn|o&fX;NJ7m`c^8>li{oh?YIeEV?&ZwmD5Vba+B;LMS^yoBB1OjA-c~ zv`&DG#nTViY>XLW#0zrFAw+V<7~R+?tmS@cD=1H=Z}3fcbZ@C; zy{Pk+N7G#C`#5seaU|;&TN|mb8MSPke#IpIS~*^-#I2lF6VEh}n-tHw-Uc?Qn3|7x zepBJIoW4ipm$pWp6Brgd89!b%F;luzwc4o?n}i<)LJ6soi99c>zYou2&?NS{fs`=N zsFG8s(|2z1gJf^z?q(O?vV8e{H650oCSIMq94AC~yN=;>Fw@{`EeF^`bHk0Ax5EHP zRmAp{Ow}_;mDJJ=a|l7Pn96;Bn<)3>^5kU#x)30`#OpU1ZTxVJp zOrXk@(i9yPbrZRm6I)P1RO(tsGrdiX9~GJUIQdYD@B~x-Q$c*OOXzZkh{ZOjRYShu zedU~LS)$=wO|MJRYMH%nT6AW(8udDu*xUOWgL=#ZuNH-QlcVgLhs9SqC}{ zxqClXI&5cu*846T^-)SVDRjf!e&KnS%$TeblkGlxw~bh^zf~m{SyuUKNDYCkB@4p z=b8pwr?Px1NOyiB^Xu@ClJB|R;o@!CpZ%%uO~C=rijNNMnYR*p=)!weag`oxkbFPn ztvgQ@-m1cR=1DE4-Wj`t`akxWVNkK#IjgIPcPgSDCvat-nN0?~ugZJqqs+{ZpS?FY zBY0cD?%feP6bE^YzVfS%rB+@*wAn`5zKux1#Bok@H#~%99Nj|?!G)T&C_;;?7dXooO0LImJ*gd#$4$_ zmL-13!=N<{C$)5|CjC=4C7zM&!*_=~gjyT)4WlNX*5nzQLL{A#!$3H5GXEr5QgR44mo+Mt&VlD1G-q%v1MMHRM7@hVG}%n^Mqa53m_zUV=7p%$z<9@G2M%>4&WO$CDE5=`S*j^h@BUA)W5w-&H?-nEJh zr7Bh;_Bh~-*AC6y^_=vU1s8bLK9Mr-Pw<5_BcED7f3D3fDak-U^}_$KTaoAHO_|I$ zlwT9hJsU0XRD&s@eAfyM&4+-a9jg?k211X)=0*468jr|Ai?8!LwT(|{cSKg19_8Fq9rZXfh-vZAL#(lZI&Zd-{Sup_Z2j`9 z_=$#@ki26i*eb=2Ge`y4PhqVo7x3s{Df}$UIy=#0xK8kyhyUfs6Uu4!ho(qLi{VLp_-_JN!8{fSpDY`mq($Hlh5KC-G zCcYV9iqEslW5>m@O>4{YaO~cU|Kc`c#5O2l&KoXeyDjJ?y}2ZyO6crBS(`96k5$r4 zq;;d=g@!wgh%xYRjM#3|o=MU8+CED~Gm{pHnzS#zl7H;hak($W|!)+mC$ zv;)rpODSm8hO49k&N;EoeA4YkmcD$?+Y>QfHtjDL8CVvYclHkB$ zCy|@4;}2R~;`8d6%p?RRz5Y>2_Y4?H#WFUxwO@UF=)-x=?w@5V{c)9b8d8#|f(06z zzxf47An(Y3m;t4!VEr!q8FM))U+kFz!)j ztO@g-Hs7IXW4m_5nGt}}x)Y=Hff3}>t)C5yb-^S|zHUb9r_LrV6|~&7#u!@o_gM;| zEx5@&tuZTK^r$S1=49*}bw+ef&K{kcg&BHzDy|{)gMdIj#(XG+PwW_t+=z) zrli9p_2k;{4}#Xk@5te^jRdSNY4>xY0oK5Kq*a-<_1hN=?&}xC!z&k9HK@1nrd0i( zeeL;uf5Ckn>3n&v8~x(*1rR6wB*7q~=GrMIswp4~$2>N;)_G1SH8+c~gw1V8N+?Mj z8Sz7XTi5q3i`2f2uW)L?uF&R%_&MP(oC|-SriMAgZJ}f8GfBLfxJHz}hVn<#_`}uc-{0Q(t#O|%eZpgE5Mk}Z=p_n zSlq&7nTZ1^R>WRK6l=TQ6fG4H^bEh$^RMqyTp9l?`=(t1txq^T)!fUvW7TpF+_eDF zN6?)I)on=vO?Lv)ZDb5<$%Cx=+Cephb$nPq=|yVR;rl8aQ{Bof4)x^ys?EWQH9C3v zh3^u0*3A_^7$}Td4)OETljFt?G~c!-fKeXtUb7d5sRVO5_SL`$9VmdG7YJ+iV%;%e za>1WFoM7#XrD-=79rZ$@B}w*_X(HOhLOL7-rj`A6UoIzRyl|=US=REPSQrR|LvBTB zb$JFB;>*WIYtt0T!2=t41g?(;-e;4zp@(&NcaG*dQURlbV>_?oeRx4j@-VKWZ|ZZN3wzjbA{< zBsUiP=EbR!as{~O>FSY@gLEO}= z-7k*wv1&0eWe2;0&hdjt!&w0St8BpCD4LUF|C2FEL+fmf3GaYNxw!|gb{)^kCv#(G zt_7Ce$}0JS$U+7=^#hs>Jj<2JJAX%a=?dE4g>reG*KFF1}JWY zdBb;wJLBVpxl~&3RygJ=uc>f^D7 z-ASy#o3l>uh3Km*OC<{R#cKEZp$-P>KZ>fqYRgxE&tu-O(G%Bxb|k5vGEQ9L{6Q~S z38@vR7SQe@U!SVlxr;c=xHufp5kb~klQ8zbtr`(ORneIgdlC0dG-aZ{0_%ED%As#B zYc}IuB;(!HioKzEq<)}mlI!#AvxWiqr8++MSHvNB+JLk+jT|euo1rdTyxQ7bC%OJFnN{jDf_5? zWnT|TPk>;+6ME1uDP z2ka>}N+zMg39JX)@j5iqBXAJK(SracoSGJ{>M&P=o^Lm;!@IWVy`OooG~mfp2v`$^ zsU(wXsVm4RU=`dJFjcoWoCTJvZ_%5UJrO$bu2O6?v9SWzq)g!v_zw;*6s3y!zfy=mIEw!Jf0aUn zpyVL`RSFS)$r=4W_`8=fk(a>&frT$adHE~+QWo+z282WZMt^G|{zg&s;s4Y`DN+8Z z2^5B+)EECkFR8wNYJ&d8{?hydqG%g`_xV@zO9j$DnexEc(%hLq=$^Hi^CeFk)sgBS z5m40Qa#*SaD5c2Xk3S{QpAt&q^AZIADS`i#P*m?r5c)^N@wY^$D#35LOw~)jqGEv( zl>~zRAq?s6WNtwKU_r@hqO>Ugd1_OXs#sUxq3k#!TU~~)$yxJBBfkF{i+k#-QtMdS$ z)K1aHjM6(r#}H`o1w!C3G#`Lb(y&+Uf?)`B3=Txc5O6f#Ljka>b3>&Xx(x^%-3A1K zZUYMV7aPJbG@n9Y2sHme;lO{vKxh~Y0JxfeKqwe3PXVZKpxK4Np#Orw(J|CEc*V~^ zC=@-ua5&;>Jpc;&7Yu}kAyBfjXg1)mtGNLL2&3ga3PblZ9F@^m`vZUgXfX$X(QUv0 zFtmE8?GEd&TbiyP{03^bpjmgUuY5C9b21{{R8H$i~t z7!VEvU(F#X7~OxU;i0W9C>Q~`>QhuLz}2+?2LObx&KC*+qOBuT`a!SeIO-GwU&Y`6 zFyv~CP#BsIP-h<6`aogASLchu(AGH$`{($cIvJxhnVo)Xj;mRFnxllYQR3rIo;*d} k&vJQK3;k9k|8sEvzAMDo>FMuN84kGAg680my)Q@bKLL Date: Thu, 17 Oct 2019 17:04:09 -0700 Subject: [PATCH 0218/1772] Post the minutes for the 10-15 in-person meeting. (#121) --- proposals/random/meetings/2019/WASI-10-15.md | 90 +++++++++++++++++- .../2019/What HTTP Needs from WebAssembly.pdf | Bin 0 -> 82687 bytes 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 proposals/random/meetings/2019/What HTTP Needs from WebAssembly.pdf diff --git a/proposals/random/meetings/2019/WASI-10-15.md b/proposals/random/meetings/2019/WASI-10-15.md index e914a2484..96df21e3f 100644 --- a/proposals/random/meetings/2019/WASI-10-15.md +++ b/proposals/random/meetings/2019/WASI-10-15.md @@ -25,4 +25,92 @@ HTTP (servers and clients). ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Syrus Akbary +John Plevyak +Pitor Sikora +Alon Zakai +Mark Nottingham +Leif Hedstrom +Jorge Lopez Silva +Pat Hickey +Johnnie Birch +Roberto Peon + +Meeting Notes: + +Presentation: [Proxy-WASM: a “standard” WebAssembly interface for the data plane, Piotr Sikora, John Plevyak](https://docs.google.com/presentation/d/1QMGEuVD9p5iNbzxzgT4p2PXpxg1MjfSbpbJdw6g6Q_Y/edit?usp=sharing) +Resources: +[WebAssembly in Envoy](https://docs.google.com/document/d/1HLV35OZP0A_a8dVjDo4kwTsovDkaycS83ZLKFpG9W8Q/edit) + +Described the envoy use case and then reviewed an API (logs, network, http, etc) + +Dan: Is there a main function? +Piotr: No, there is no main. The module functions are the entry points + +Dan: How is `__post_instantiate` used? +Piotr: It’s an initialization function which is called at Vm startup, which may live across multiple requests. + +Dan: Does `proxy_set_effective_context` imply persistent state? +Piotr: That’s an ABI design question, it could work that way or by passing in the context to each call. + +Roberto: Is there an api for caching +Piotr: Not at the moment. Not supported by envoy. +Roberto: What about streaming? What if the data you’re receiving is not in order? +Pat: We have a different proposal that addresses this. +Piotr: We don’t have an answer for this yet. + +Syrus: Have you thought about using this proxy api on the client-side (browser, [via extensions](https://developer.chrome.com/extensions/webRequest)) as well? +Piotr: Our use case is not focused on that + +Roberto: Are you thinking about having a Session abstraction in addition to Connection? +John: We don’t have it yet, but we may add it in the future + +Jorge: Version management? + limitations of current toolchains mean that the abi version is encoded as numbers in a function symbol name. But this can change as tools and standardization progress. +Pat: optional imports may alleviate some of the versioning problems too + + +Presentation: [“What HTTP Needs from WebAssembly”](https://github.com/WebAssembly/WASI/blob/master/meetings/2019/What%20HTTP%20Needs%20from%20WebAssembly.pdf), Mark Nottingham + +Roberto: What about multiple headers with one name? +Mark: [paraphrase] we probably need to talk about that + +Dan: Does this include DNS? +Mark: Yes, the API accepts names, and they are translated implicitly + +Discussion of optional imports, which will be important as different use cases will need different parts of these APIs. +Spec: https://github.com/WebAssembly/WASI/blob/master/design/optional-imports.md + +(general presentation of the people in the meeting) + +Dan: Could you use this for general-purpose HTTP programming? +Mark: Yes, there are some features which are proxy-specific, but this could be used for clients and servers + + +Presentation: [WASI HTTP proposal](https://github.com/pchickey/wasi_http_strawman), Pat Hickey + +John: This concept of futures doesn’t allow you to chain futures, right? +Pat: Yes, this is a difference from JS futures + +Pat: This is a low-level API; most customers would be using higher-level libraries on top of this + +John: This API allows you to decide what you want to poll for + +Pat: The `future_close` function allows you to release resources + +Roberto: How much would this API change if you had threads? +Pat: Our goal is mostly to have threads in the background, so that users don’t need to worry about them. But some users may want more threads in the future. We don’t have all the answers here yet. + +Alon: The `request_new` function takes a string url; how does this relate to `path_open` which doesn’t support absolute paths? +Dan: That’s a good point; one possibility is to change this API to make URL access more capability-oriented +John: That enables nested sandboxing +Alon: This model entails some overhead. If every WASI API uses OCAP, it could add up + +Action items: +Dan to post a skeleton Reactor design document +Dan to finish WASI modularization API +Pat to make a Futures proposal +John, Piotr, Mark. Pat to flesh out their API proposals offline and figure out next steps diff --git a/proposals/random/meetings/2019/What HTTP Needs from WebAssembly.pdf b/proposals/random/meetings/2019/What HTTP Needs from WebAssembly.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7aa294ee64e815455dd95821e1aca68f98bd9fcd GIT binary patch literal 82687 zcmdqJbyQtTw)RcX;10pv-QAtw?(Xg`!Civ8yF0;yTkzoS5Q4jZz&Yu@N5&of-R^(h z9vLH>wRi2gX6;q;sb9$~A{jwpDmrRL2qN5#&9Ny6MhIF6YdtdvPEH6K1y>tG2pR!h z2VDzmV+a~4T}wmzw-3a1opj~(?M!VPAQ)cC%Rz8+L(s_R8XHRJ>KR)6Rz}Lv(jG$n z<Q=wM-L^{4)ly05BwbHTQdQ=KoRrH}_xNdUeju(CYQ}uhwZK4Gm0n`K?{v z{G)|np{Iplq-A>Xi$=iO%HgG;Jp{{dCFKn5tsU+3U%X`f?F~LFE9;k!>1cnu6tS~* zwE0y<1v_0Udz;rg>ASv|dabmflc~O;oCyD`i~scU)%dSU37c9t7}`P52wUhn7z!Hd zTN}K%D`9A5>|g@H_I8t(@7X)NRNWH7C9PaR(*8Rw)U<>(xri5FkS4draDrtr22_9- zrb+TRHYpfr!LsgT7s}H!u5oG~**;Q31ab9)-YuD%U4m$zUNtI3kmdO40UPxMx;dE$ zctQ&@%WiWK)b5_X=!DbyA+0SlA+=N(3-NZ-SN&F*7$U1SGjHm470&y7s4aTLe1|Z1 z*9MerKGOEh69_U-7;GR*FHEC$^9J z%_28t#!YaHK`xasto&^_|7HQwC=DFUw0b=@x}k zO$DnymM%HpMSfrvJ!4Br9gU52ro@S7I4J1MH%>Yj)p z*%UityapoOZ4;e2FTIR%dte+qg4GY$d~X3ZuDTo30(gId{^0%SfY{CU!?+}ur!IPC zD(aym+DncH6-q=8{ovX~bJ~g|*F@!>z1MWeJE43I$KwN6*=r;I{Yn4coL?KjYeQjV zVf)p>-&)@5d+IOk_4i_Qe~sGzW3#7wjklKw`DeSQdkv|VcYZbe-{au_*6`oV|0^w@ z?zi~+pH06_WzlMp`NPf{M+NT!fV*E#aHG`vtxZ#Bb^3P|^RdV&#+DDvb)9QY9~+0c z`d0Ehzj{6p^@5RU?uggugyfNWZ9PANJ+-dWBXVl4?tl7 znIPj@u{$ht_T|GHUMkmk^B=~@A2*)kM~$qP)Eo8N83Y&bg$4cZR^^k9bE|&hwzD0 zSE;E7Wv`x$Dm3@OK8sE_iQ0D@{g=_MS5Q<8PMxDNKdL{?&}B#$^(UoY-#)N-(XYDm zqd-oH^IMx0D#ASD@VCHv_Jw?C+^0xo-izgPHE+CGG`WKU%tufS?^~SoO@kHwD6d{3 zE`tWuK*5PdPvL+>-O1~Z;d{T4Dd!M@tD0G92)Tv)eTU2)n8~FFCJPDZ!JE+0wYQ?8 z=q!zK7caGn?BJ3uKG{oq1OoVx`udEfV4q}rBgWwDM9LRbbuZ-$&RG&SwD zM+DC)nV=J4pb{(;0;v6$=S&kCIjM5ga$VMCIzIXbxlJ}0`QH@JuG6y}5A*TM)- zOOy*GQ)F|*x*~@)5gw4SWf&mDc430n3){(Al!}mQBUzV>(x43>lp|hr@R~k=`-$%~ zWUYC_^k1`D!Y$B}L}{X)VJZ{&Fc&LUbC^-6e2dAa}1iq>QlM;91Ls0oy~>nT6E3bOCE zKSd3}lei*D+D=K9Au-6~>G!>tVOcuM)mP5TmRAIVL4zmjIq8S#0dtSlUFXyO07(~5 zjV)rm!{wR9XC5k##E0oFT>{!HgX4=C1|n%ku?$mJ3=Wu(Y4F(G2^z_3vvt>^(+LmpA2z~{KCv0$K$ln4be~hAf)!KP#c!ps=S5<@rT%GYIF<&bW92bx`(X8xj>T19 z-UaXJ@4FFSQ0>uiuPdpHa4*;UmUwD15grQT$`rLcSC>kN zMEgj)28F4gB)4sx2$>-ir{%1OvwAj^K>K&19^|98ngVXrfg8dS<2!Otf_OX8(BsAf z`M1>`WX8K^4h@&zed)%HXw%O**b{0qO)tE4kLlblWOtXo>ywr2ParYVfyd*U=R9YN z>DLd<7s^=WCqW#CA5+$Y*J1lv+8IM2*A25HKwarXe7Sz2EIt4s%iC5%$2H)}3Fb#uOeZ}BtRG7;eQWIMT3VEEby>vVQ)EX{~@;THiat64QBpIYX0oW zS4gTCGOmBa+R7PZ5UsIaG@k3K=BGh6_fP#<;xEc>6heJfU_uSNf`FcgMFv&P-i-y% zY$k18omkrG*Sya1XMY@x=Ahn(-ksi$oO0aX6%O;wkqXh#g}(wS9bS#=}wY!fJ- zz>M;l&B&SVld064D3}dP;?E2%oAk10AhQpr8{JR4JK^#xE!5;rgYLBVn{5F^88!+o zFvn}XgD^Jm-mw%OU>DSElBV8iR(i5Or)k&WliJk!5KE1FRPX-=Mqz)k`oSD9P6Tfcttgwu3t_Z!D*vilfvJL>6*0fN2l zE3j{{Z4x*>=zqZSab(Gcl<25KcU$u-g(O?Nny}8ygk8>v1u6+$VmUZnqHE(zyL99Hn+)`OySjup7B6hS(QYVUa<(74Ue(D;2v5ykSAU?5EO>bX^L%{O zPc77^>rDnwS?=y)S0w&WJWFQ};mO`r9F5&VctKp82$l$G*p1k7zgs^YVsh)Ue(E3o z9(4(O$n^gfA-|dbm&EmN z2w7>-YKj+5vuCmWWB~S)AfLrGy}LVbez83HL|AGaBPXtmdUjoO7eQtxn7va(HDX~7 zaHDE32lm)q_}I76(KHG?S9BT*pS<3O)0nX)B)O73-}pGHgk#;ff{#{dmr^_1wL8Ke z56Hk7+8tsmP(8XT0qA#AD~+^ixJA95px=v&$PL|N^c#B+qXy2S>u(2CxK~| zGByF|Z~I9|0Cb^aIeug^S0HQ)S5>SuXY~GxkOt1w5fL|7ZaryHcakD%YX=9gi=KK1 zi>jSiMN@gZb22>bJQ9IQ{K!Z%hLW4~fQ!)C^8t&dlr}!|hT+P;t(R5jcuwF7>6|%L z3Xh#xSENh_sG;9!o_leAZQHnAvEtC@lrV03q2emn>rq>!S+aFt@B`|mVyW7x9G|;6 zD&UOVqexF&0>1EB!wUT<7=5UcxF#smy5aCvF>V>7Y%{Q5+YJ6u=U7U!R&-fqyWzVn zB-fm1D3F>>JcLbv*>@bBt*K1vKa(PuV-gV(2VKw2R+Z;HVG5fJ^bha!=lnL)s*82fv`x%K(@vnHVw_UQ3WZ zeiJ2uO~rRAd&^mtz;0OB&HVTAFCc5<3E8vCMk?Mzkh4d}4?15i z^}=P7FB{zWwzs^q4)D6rNc1$2D;TN3N&L=cDo7g*?!fl*UWUG)80o!{=ba{|RxxZZ#L<3~CdWl2Pol)Q$ylcF2@m zG3auA&$#`>LvnM3XVPKz6~U=;AxM&*p()Hu&EJRS?a$D^NlT(PV5@;K@+D&K0?stk zfCX??plMb&^-m5}1nuRT)cg2u7JbQ>{H%oSKm`%~j)TBdD&)ZToWLz|fX5Y!-v_@Z za>l9=rsb;ymj^hT#WC4j-=>?P9G$$>U8v=BC?eT9-}r_SG{%;r>3v86gGDt*uD&2} z#NPSwxaxO6Dk3&xB(U4EN8dfkAmuQl0aF8b#0azzu>{2Ed1LF{S_fleb=dqb#xbA7 z0-an-rpNpukvYd7l_*f`&<^V$rav(mFsKE=2?WByj+T77l&zrvl&t}H?^^N}%zx4nhW{8fF#LrY82(5N4F482yqW)(wB&E7 zL2>v+OOTjS(piFuyvK2E9=)o7Bqzs(&0?ft&eU*aFkYFV@C5beEq5eW^5~YVY*(-f zqV{UjRrMH`eOsQdE&5{Z>|@XRaXyLGJ|s`N{&^7ETMw>I?rCz13W2Ah7H3M%JpptUYd}asVCSzDO_v;v*H>u3 zTaX94D&NXMuxkK%&&K9s9rFNDEnoL;AHR7uyVrPu>S`scJ_aqnX}N90?3O3mCDXxd zSU^SEc-t&b-eo^rb=bK35*8derWUS_VH(vieO7!geTLajPQP06%-=Y$6yOZNPr90K z$qxtFu^bmoIl~akzm)?wYJe^yNJbcT=mS5442S|^Jp!^kuYl(s(T@Q{AWg#$>9|*z zpJhFlky2x4T|iH^^J^wkM1nCsYnxt`=1ppaa(6$w1jMf&CK()N&ZdlIPk-_1-zr9hD1+TRRup-#Ycl~6%@BzuxNDs&j9 zAx@$^YUVa|d#wl_MvG;Ug$`;Zv3XT0&L8indD!Zbr@H__HA9ope{XhRMXQ@ET<_$> zveh<)vS_U?RnYo3k@>5aXJ+_EFaH)Ae~!%mSTE1`mtLOnkG(wOztzjXng3TJlku;; ze7T~e^-C{bU)R`VvkR4@-ZQg`v&3tPkP^&%*uY1G30D*$qb9npeM;hbWmKEWh)hJ7 zJGXf{$KW-#nI22ZD&(q2mV$AiZDk_Wx~2hq06jaX?+H~nw;Wy5_cCf5OYzz2+b{ZN zVhOiM7O{`Qx8rbPbftfnJas882uE*%m*&pf*0Msr6<2X(3Y^@CABsc=-heEp4r{#5 z86}GAFH1j=U^DOyBG<(CW2H1$*qczwiRt{nc39@dnDgXR=V-ewL z8w<;!WA!N}Pa}InTF$k8Nbj4#L02i9Z+=Zq@q;*yY1E?;n)@iHJzGf9HTJL_J+bN7 z9Nku&W|whhdMyk_HEfkbR%2UpG-ir^8Cx4Ap7~m%Ti^3>$SY?!YEfjf zm|erip{H6lgS`Kwr`h%nB|QC8ad>(*mymm!aAL^uY0Q*>4Ns2-?A-xpjY2igAmZr+ zo782@IT;Ex%0)+i4Xg9#pU2}))gy4V(^tkPp;x*!k#n;4vQBn3g_?MrRT?~xXI(#` zw5^Xf4-(?(lh?`w(%NGo%;^U|tEafe$YATx`#Qvw7}pgQz9&#JqP@Ut^S^wIDaEW+ zD5%x}qab4S^@>sYj>-7sspPxB$|4ma2vdV)57!BgU$!2lFj|V_Jme3uG)dNmw*iy! zKED;VU53=rJWs@K|Gt|`>!87Q<^xgUcRLy@~dY7aQxoST}DDJInw7e3Wkt@iA@Ug~8ieCb9jm7B7fIv+QQ(&a~4 zQ9Iqb9nq`j`mzQ?(ZJ+zC~<{ zQ0r4G!WIaZw-l_+he@brVk&h*uR^ZEyal;?^k#bdm#kX@Z)Tzb8>$j(}bxw z&z!CwBbILyxi^mqc31k!ktgVcGbd)CpGb^R_gejcB+ta*i&v@*Z&35HM7Wkd{W zaoh2(PFV=D)W)yQu=YchnW(Qe@np>>etE#5bVIeO-^OEXqEcY83P>DH0&QZN=Bc6} zG{!SA4n3(EH79Z?t+U`Ou2#XA2H+KBHf;|m?>Vs5djfv2@_F>s2#TJ~TJ(2H$q+i8 z>-2%Xzqo%t}<7tI{w1Xdeqo0-QHxLu}&4xgW5?NFn9!0SWbMSb|iA!gL##~~m; zRGNr^|FarYD9k#g6H)r)a8h~~ZaB2Ek2<-Yk_7dz;b1;5 zxer22#htAylLF=ncO*taW0-iyi};I?L%QmQZ0f0+qJ)j4ZVC@&2NW`gF~cO2izbmE zZ7)J}hS#TvZzm&&e^jtB2NpQ2pfF}4iZO%pZ7HHGY$P|Il3kRYX%YK@yhs1;@xf-= z7MZMZ1$3_OB>mJp)dy~4!4Xj0&<~(Dtw~mCNUVOLg6VtYeAJsLOok(6T^p7HNJYW)87z%*V}jz?^r^;)eA_ocDD0x z#OD_)urf3LLwx>bVTJKO#tKY-VFji?vI5h;#R_lc{}u6J`YS86sjONrGQ;hxu~_j= z04`276zUWuN)ic$#$mItHeh1dr`?LAIKg&@GJjaI+P^CNX+6K%cpRBP^pQEmtwulv zUz#wg^|)n|?pjVnT<(@zp-lYb>9D*tkz7vPm|8M!8~c)(ed3^;k@{5X^h9w!SaE|& zQK@DoYd2kE$XUjYCiAiC?)*rZX!QXEntilvX63lJ-P=BTh~xH7olU5z(&T&DXUKx- zYDY45^Gxy@U z>Vvw35=(|uu3)kRn;ejG*@vT8Z-}Y-9I{hg8g=ntK?vaF&_tS+Np+)sf|DIHDnZA0 zITw6IY{B(VIhhk*P*8PLA~PUG-J-W#u4P-+@qp^6`LF2;e&~NqFchQ5NBbySxhgxk!Gp(Me#mCw0R3ybS54yX16OhiMl-C(^7*Sask=+p3UB;w%HGq zr(QnB@a%gSVj`RyD0BYR`Uz1zyBpvc+I8UxA1#0@rzI({!OJPR-l;hfy`!qNZDKf$ z2-cBajE+x&X4Q%EnRPhS`Y2qj%m(a>Lp4F6Ge-f`c9T-=9zLV*Wcy`@>1#m<_z&+{ ztNCv57}VHCDC$Li49!|r>j=OeWRZlbCGtz*8|L*pr@1d{5!b!a82TFgD}HGWE1gmU zP%QY?$g+hRTWMntk>!{nc?J&!81Og@nf|Khthv5swa)uV+OsZ}`8nF_ic=V+58dtG#n{v+** zqYf*KWC!V1RA3m)1%bXh?Y4?7iDFjF@4)yo8cP2aTp8(xHyQ+v4Rc+(tPwH&XcAU| z<+@dH+I6EIZm3q)xC_Dk-V`@SERbAgS=2eX7Xj%WU z`RGmG{={}nuSE7swf?O=cTB&N+&?!TG5tnazcwE+y(;<3UZnrqy7im+UylB7+wNXi z_VqS@ShrSMmP4fb5HZ#AHJttoPQh^Sc`RSb2QX4iLoMEIeGgz0sctX#hLSUL_hZYl zWlOjUYU=*ZVk`~YynW0_WYag`!Wu5{@Twvn?K3*mWH|a}od7YkuxrtrA2H^}ZHUG9 zMXj=3ZUUXbG)v=`zOXmQqJ18_w|n=!B%Nd4pMINfO*pypAR2=7y7Ir4=|dJy{vh93 zC5MI@P3Z}j2Tb}h->R4;3y!ufBq1|VDQILMSSXNfjYeb}hEY;K)JiXGw+Z)YG@h*& zN8aNz0Z+#chx=-U7kPze!G58O7xOXxNOuzD-iO@H+n$04$W^^=DyN~98vPk#%^5ue z*(ff(Zf5t8tZpr!I+GuTd0OHJjjm7e$2%0#{SfgWrv9aw3Um)Rge_sNFB^?^M<}vF zUFk`!57XR{_i%p3iW|_OTZcVvdeEw+ESRYB8PckxC*pohpdjK1h?PzjnXr_=LQ_9E zeE)PQdtFd~t-z_NpGx}_S5CmKdV#6}cFO(3EVH?l>HG01k8U>}#;2G`*oko=RB<)y z^C(UpLLLlP4;;fC|2iu%|M_N9e=u^jY=RjR8%R!AFQy>_F6xhjCui@^_@+|{IR{t8 zCIos~eqw#M>V)D4B^9-JM>q&86RV9g`JPMAgcDTsV|EySUrfldQ6|vXTG^!0t?tnv z8ri0Il~G85(;|bY7sH}?9pY8>1+3Bg!_>Adpn1kmOAdzs?(z6`J0sr%QEJ$~nxIZZ z{>al38LScbUcL|697X3m!K@0X+2Au1fiz|Ajx)e)KVr>VTASrxA=@HbuFtM==_yYN zB5k|nA1IAkE)b08C-E*7SI2BWR}dI;UC~CtS6qkQ3<71jbZs@0^8+Engpd{78pgog zv=nwRiE(4a?6^^%7{M+N5%c_};&OAk)WinE#E{!02ZqQt3r+pi>EA^8FJ5AyqyNQF zZ&CKAAZLChpI@=_Zv{E?@5J=aAZPxKW_|_v3(Wl+LH=g`m!tn%kTd^=YJUiF<;6%0 zAvnveMq-3_+lX*#xwMPd8D4~E3oDuwD~=xO2-t9>s(2(-J|f(HJnv3D(@K)7`!m47 zBipQ83!0k?OPi%Mn~(EGTpX*+73FHZXe=CzLrwNltYdk<2k$I`vr7p8{Om zF6`~@U7k)Sb*SrjiFgFDr0HtQBWTp({mPjL}mA66iG0NMNJrXE0#Z;q-}6@XYrn*Vn0h?SC97|4wy05MLQ2Wlczq-Yc2(%Ns| zkEs)P+D>}DE{XOjj$*%6)~lWy)QgPL3g!S2tO&Bg!*3I_BYc_5wd|O**VC|TL7x9Z zZ7H;CxCO72b1$>&z`d$nLkHz`BO8YzlUL98wW=GU#M>@KbPTqykNpdr(ym79F`XEK z!dnMbL$Xj zm;?70Iq<*SBd8hT5W?^)Ep41=AU|2hmAgk({)F~7(_3#E@hT>Cv@iQIeqShh)2Bbn z)XHf!=XDD6>GZEB|V3rL-1W#!Y~uC5%$G8mSp>`5H62{l(0unIXB zGFJyUiXrkHU&RV453&z#C!!k(=%r}Q>YfC#^8>b^Aq zpZb8G=pI70pmr!N9Z__X#L&lvLPOHvv*qFO?F^SOfz1tLf453E;K)71Sn*4q#?Mc? zGMt3ZaGZ5*aImhpx%!M``G}CpX&t5vNxndC!aGOq}3~j|7xP^6X`W_UL$sxltX(qA?9w(U> zQ&bEmNNhFTWI+A^ z-aW(7dNgP*Sz#A`fgcNa?B-OnIO`&FKxz3nsep06xC*Q_#Phu_v@k^C=P#J-+@Lte z&MH$4?1u|dLlHC@<5I^N)jY_V%ZZiOEes8!eTJ1S>0Y$94v#=VSL`}}g+=CHut-Ns z`;Q^vn;!j14q5(Vw8-)oT4ebnEwcPuwD@NJUy(zWztUoF(yBEk6I?&l_J|<9P_Q#L zF9`T7c9eIUf{dp9?A3S13$MIrRA4g#2dcc2=deo8`K6=70@TPaX^vXQWzNP|47IhJ zZE?b;$&1bh@63Y^E3LQlzl)p4dN`yEhaY-M45cxoo^`^O^3ZrqoQ-IY>yTE{;Vsd6JR8x(qn=$ho*^C9d&)I2>*iutfGS=^QW+1moO>eEw1Ej+k#0DxlPh}gyA?8leefrtv zVe`=6(jm5xW%2Ymt?kH-Zn3j0N0Q8yO})kRDz%lS9mU?3xK9rs#vk?L&xjuB4N(&d zX}tUDi;t&e-)`Z!z33vXPAYnQ0%m3ugaO=ur0!GU1O|gOBe?r6zXUpktJy(+pIQ0lTxE zVMN>lXV!go-NB-Ip*guNW8s33Rb&*lB1zlv-jg7;|kV$;Br9}yY zAPrY0n(9Z1z}`3H$t@BYB%&Rjp9&EiJt0wcA5oArHQ9GvFT zAYos{MY}xBDP%hr2oi^FNs_Xg4|UCVWJ{fjAwrUo0x;PG8kD=@E~F&Fs3fL`*&u}B z{kp1L9Ys|HIK;w-UF2${DJ;n0a0^=1izkX7T1tA%xF{otRkn>YR&>exTtI0 zx6|_m|0bWePbQOD7UoBWJv$Y%PGY!l$7K`#Aq`a(TU+wm;IqZ^#S`Ag-`evBV!p20G_9b2Aw_*6(B^|_@m%k_a+F9$%8#=rs zAkw@f55J@d8@f0^(1=;SB----{wnbMtJrV3zQ1bv%C^6LkN=k|@|I5XUr~|&mM8MI zGxxvYiM(wK{BNkp+b*jAii-TV#K_xP^?$Y%I%=dpqMSg9?_VJJgO@W=OdVXQL|>0IvDbg$IbAD<*KfTZ@xt=kl;z9mDGJt#R;F(!n6Ugd zY57meeM8g#yFXN7FNe^W>i_?7i}kn7I)8AB^*5;fr(17~{C{#w;N@HxQ$sr`L+5|} zmty^m&;RJsKPdfoN`Cw4e!29&tzfbKb&A$dZrI9?7OwRinY$q9y@lw4==)-E#Sj4; z@O9e2l|am!`-K)Ubh(c@Moz}Y5iHBI()EYL3GMfMEVR`PwSC>Jm~Eg1Yvc3& zkVfoW>2U3iG@3D>whU2-7xk7wd6cSm@V=W{#tm+ae!eY)p68$*#;_Kb_11t^k)w~i zuugiaa*E%0F(BGRugTqY$cAR>!B4GHX8Fz&PuVzh0O<;iE_8GpE5>m!52VWfGfmpNIYtF zr+$}|F5fub3@tx`hQ>h$m)5G z+U<{1QGM%IXP*;wk2tK8ua8=;(^gfFno#}W`60~sFeiGytfogJ>jea zZ}Y!eBRDA?F(EM%=n#0v2(@ycc41$K9%4d{*#x5b9_L-;GiDHkWf3|T#Ni3)0@$pU ze}za(G!7V~b`Hk4_>tw!w77wY;T|R5|r$ z(i31egu^W_d2+RBrNlfte{S)7~R50kOuAKfQ?gg0%VFHbk%hw zb#ZS68B+$etVA{BV4awXbnxToNwUhh@IsyX0dQRG3c~o;PRx&$2|Z?_GMRFmgZ4j zd4yNklW+GI^r&umQKBYa&Tmx0^qkc=9!A-&<15#l%RHTEt$rp3JlCwxnBM%9gE*9| zSt65rsC#%9^bOsqeWwT>1YWSu@lZrlgERw$OJldjH$37DYvta)C^?Jc_IuiM5n!9( zH+r0?+F{C@9H);iI9`z6e4}`=1Au2#EQ#hjUcH%+nIR7dPsFu0#q^mz!&b`ZIm0BCTLBG+6vhI#rkGMfw0+n`! z^bYOlSzY(uKm_g-A%u^?H9QfE>D?;a+TG%-!Qr<4Tshd$1fbk!_~o4j*6e`hyLz>e z@}M!NBN~sS)iKnp^n1wb_fhXL0(Skmy5MDFt>QjE>=02o6aNU;QHgsu6 z!`{(CmCJjqh3^-E~uJ5h6^;%WPs`6#cvdARFknJv@qbl#Y$q!JUV#$h5U$~<``vRDr za(>dq)Hg2nDB4N%ctG-NdI#U)1Y}V^4);L$TA=;n#9>|_?B~_kRUjT|k=ieGz^w5W zJ>~LyqIW^8jQjB6wTmNxZeEfxc%niZ7wK0 zV9SwaC-r;w7f7N)`8G`|M0Y3V2G|`5E;bnW4-6+xsv41OoncmeY)9`-)z98FBOLB3 zUVvY7e)risEz#}QE4nvdU(Pq;QP>6QC;Vk!JXlgPENpV;4@ zT5r(^%0o(L-$UAuZwIu<;C%I)4lrMj#F#MNgQFw$Lg z{T2}Y=Ouf$XMXcS8#qspOzp1G`K~Y%s%P$$;2)3&5XXSd*MRXNZ= z@W3vt!1JF)?yi_8zdcwZ z*vhDc5aBP-`Du0c@{4Bkl4 z_|yr}%=MwK_CYT_5jPTNJtT`Wtfk8GxrM(v2PZ3yl=EzbCYJRwZFctVJTMgo#ya+i zdJOtRof9yp8y4e6QHZSzy6XJgc&Kt0!RCeJo_g{z3kO>owrL8EwPMUJ@oq)>DzGM^ z)?z4iD|s~&CbJU?OwP&4&4L*8prE-Y;XJFpibEJ`dD}^eB_07b`=dnWin>GMe3d%p zD1P?5J3?*C7+t8QRIx0oQzK;olXxU>ph?77xPT;j%!!nrDV;m58izft2B>$$2d`;% zNH+tmQu;d6a&CX@!VYU>IXC+DtIYSTxbwG{`yxh2QNd)7nZYq}(#@*Sqv{Uk#8YaD zLaKu35S|c@oT-PfdsFVJ9Ad<%`?hnu=h>&@4Gic(3IgXO2z7qemMr5$RZ|P}*_}&K zxgYV>Kg*_@S`bNINCY|du_R}hR*yP7w~~RUEd>@e{Vak2^WCkyJ>UxaR^11GZsX1E_ zZPAcyY(a%)X@(Pw%819>zy>HQwxpS8Pf$b7AZ{|*&8*hm2Z@e|&q_ck7Nl(eH)EU% zOI(LtqMxn&d4|$G-J$@p)LWbc>ACeRrxwr-0}?*Q*m5;Fk<1HRm1#1z4(g>{bycVn zloQM_@vD#Y3hQWu3O1>aJ;}CqcN_#DKLFa?!!;g zY>|DwX2e1c6QsbzC2<2MPlG}q8Ay)dS|AH=BM#x8Nfub$CPo}|QTsD=fc-A#Nu7}s zJfU;~Bup1u*u*grFS!!nMxYI!zUn2yiGM+;KtlQucQnX4YdZ-y4vw_Tu_pcakpkfh!GS!Mm)Py7zI#q+DWC*TZ3e(s2GP^>csQtjk)8J!Vx@5Piui*3*Xdx6l z=((c_tw#SeJVO76j_i^K2e zhaeGdR*!LP!#6Cf+0o7# zG}WWXVX~HmF6$d5-GB3SxdVs6@jA4Wd{o@XhL}f}T$7Ih_u1DbVb|C&}I4lpJUQr!A`ZEj$4fn zzw>15-JPU9IJ=^m-C8^$dLZ7|k)yY0f`Gb6S@ds4Fdm?nZLsGdz&J&-s-V-u{9K~= zYPJaQ*wHE60?B@`hu4O92RuE6a93W6*s?V5FA`orfcOv9a=Y z<|1i4JZ!ybcg=}DlM*=Nz|tS(vk)elU;kHv*kJzvAsfD6Z3lI@xpf&Sp74@>hpU6I zlyxF7LXX{O@uhZ8j>An&nX=6}LHG9;AioB|*XHfu0)pLb z)P#1fn2K`xVT4nLGCHtTF?BuJK49SS1$5JRW*39MYqq~l!HF1^dsmYm>_hMu8PI*u{ZVNd3M-2rfJ(Dw7$2&%+rAMN7Pr=+PM zHn%WOt7HQfssS0a88cZ0$lR+B){b6(gEpS!-mrI(%$<# z_lsFyoS5sLYYQBCPjI7AWI7fvDlQUn&h5pG-DMki^A(V`8Y8 zd(S!>Zf8RK*nMJY@lC~>H1>4w$cO3i(TgRxJc+VY)ZM{b^4W))E1fd7XAp8_rOM)9 z(tfw&agRfJx#>LFywYmG+_EPd-eo^$^9E}eN?)V0Pl*B_u4Qov;ZR^ z19|LuoOZV4YdGBAD~WbrJzLG8A+QBI5XF`H53Qh zo4@FX9mP5?<=VHc*TWK+bHLl%${%hg^GORXY@)Wh2xzp2@vfoT=`1H3o(V2E@dvex zOa7;*>EoZd+uRD0s)X{=!)=enH=mEd%&b^+VHuGM!&JuDOy-ub>DhMj`}f)!yUIsU zapPt?m{o?K=cbATCwC_btAo&h#*jvlw2`zBwBxkmwZp^->V++1^nI9zZR_vN#;A^# zkH)$(g(Cgy6D??5L%wa?XZkv2Kk%#&J z07yW$zehQHOm8PoY#Zmou67*UPTv60DsRI?Q!PPNEkRYOpfWU5mjvDh=B2`lUnDC~ z9O-zlp}Dr#lj-CNas!w}yGS`I#dmCBVwVFDK9-?a%;c@EtFFGYD|g7{rn~~hYR4HF z2SBr_nUE!egHaCW78fNkO zZhR2$^nCw^w~w9w^q$A2#Wrm^r*3A)^?N_NbivOaT751WqX& z=Ka8X8Qivm3o?*zFLEFyw)KE-TPSGI&I?8nrm~UIU1>+a!AlsPi)o)y>+?lS zqq2590A9w&2X~PtP>9Sm6sV;D)wH{5_mb)HE8-*`q#_b;k*rH4>r$!v zQfWz=!FC#>w4NsLrbl0(ze=y~6KuzWw}#%vyYOJp=N*Qv8>83vZpU{Oxg*ob_@ju& zM>Dx@SnfJR8o*_Eq!et@E}ezWU|z*B4wm>&Er@FW!5(fNu)kzq<9tYajJKOqO3a z^TwNRj&FZ;&emDeA3P)WtJ^#B|2#~sg)ktN4wkkG?fb$`q!o@E&(rp?i;Qs?go~_H zOgLwyz~EeDrD8%mDI}d5L?GyohA*EjAb`;(53Py{_`@}4}`ul6DgQ?y)O2xWPKddvgp&zX~R_DsnPR?dmpON7K51dXXbT_!TJCPj> zKzA0<_8r4kljX|#WI4X1q>kRA5tsq4F}#{#%W5s-vzn34YGqN__Q^8rXvCTS{6iV= zq6Xj^SB)>};#`>A({(d>=x49I(v}~9r$5QJ*3=0ZMt8b?9a#7qko-CPd~%l=3iR(alO*ko7mch;{bqD6|t{ zXl*-fUL19(F`qB$rYg+l2-L#4yPU9 z#_-UJ7>*6#138?A4;L%-f|JK@Qz!!UVz_AaT+{U{^c(a$bYB1e0F@vEl^{kzJxGEU zs07!?-MjGsI(s&uy)9~;7h&P)$$n`0ay+(6~wd; zZU#T0@rP{F6K?=yJPBWd1E4`ZuLPE1dh)M)_g{8n+op9Ft?Tv7?c{^57slOuX9t#- z-gfkNUARSGd+XlE9@sjr-cSDie16%q{INg0dgs=I6j8yhCK8;heNTSJ?~>xQV=GL|5b4W+I-^vAosj5>ig+@f zpeJ0kmgDUN>KVarQ`@nfsx+(4m?|8!J!Lgf%Hph4H)o}m=!~<#*Vh5y;02GoKy6=r zeQ!Xv!G+0;HNbWw3G5}nQl+R z)MGtauhUd&OqoG575R)_N)=j9lmedvOX&*cUWgLaWNvEdB+HOXA4K&U_V!>y?!>lW z?~x0poHO|na?b8KZCyWo>*l}Y4?T3t7n?rr8Z_?qv5TL0?3$~e~H=& zvnl_tKd$Y(9*@G;;%8poxaZ`@xn~>OAHHw%W@ynFpxgYy)5wk%8IHYn%)>t-^9m>r z3N(EQ<`vDpgyRTp$Z^c(<4D*kFH!!6#sM=;CtN*juD~~d0~B%;g^`Ain(M|K?HsEg zquv7b%c(7xb!AP%4+M_J4@AU?QgWc%J!l5EeO?#6%I!XMwX?(V!hf1>@P zP53MP>Vq^QHW8#I1X2?~Nz|7cu@gltS3S&NSPB+pr+BoC?N_t1k7egoc4K$?)aA^x zFJqDv?cNWw{Yp#l`mp;_s+yfhv(o%IWt=jG8i6ERWf6?5BT)S_U4gQGiG+#utm7(r#zX*n8{U?-hH&I(^~)>T}$ zOmpQvjb83!cl0rt_MM6koF06j9!h66+Z}^=fmKAbDk7Q{ImBWSPD}9@pHGhgandNG z2kB$!FMUkw_}H7CdOz!7@GM+itbp~Uurg?XA6NQE`bVY@YhU&il)m^nbRE8yUn)1- z7He19uMXUb*5Y;iDtU$NW^I-Iw!oXNS3K@AfRC-wc$jYD@oKv16Hil2301~56bm8^ zsQXh5~DD}Ks2`GB?T+H$Q+a@UX-ye%5-B*W{J~?1J*b(a_UavY{z#R zq5eSzFhK?|K?X3vC9NFh+Q}TlSI$nBvyx$#GhBJ&TY(*tUY-j!uMBRJym_Q0H;0EFi+y6o^v z9bYY2xcavIu@64TAG`CCRSV{>yyen4Yle(mKXJvzO*h`~G#9D7Z~lf44{W&f-pby4 z*X%AJj63dl8Bdyf^G(xduD_#gdMhN{3b>UlM5BQ%6?+$iMSZ=6&vT6PEEroeI$N+ys5U^XeCN587sBKr__q_lXsvy;Ucc}nbYJ5G<8viiW1aq zBwCsp<(hG>@jpz$ZmaNYGN87CYH8Ra5FfXTg$vV|35kzM&!SEKYiCTnZu~$z@Wq8Y zPGaemJ36nq`tOfD{~>wf$)(G;K6CALkK&2?)t8UH;ZKXS;FJYe{?h@hKal@x{=59= z`E9>^iL3p^j=c}A162)DvJ+gBReYL_4GlKpynsYWAz~fR)nSoWNgbH{h|oyjqjGUX zpqc93PMwVdWEnJg2GscIP|ePL`}T2-`}UoDdfz^{Hye9k_jaI_M)eZgO}3xe9=9E_ z3CM=i>L7K5Iz^qWZdX55C7bGy=rg4{Q4}1!?Kzc>QzV5to>gN7LV_sO@#tw(qSdk4f+pw*#jTl_41%g)(YOh8rHeOReD*!>wTF&aCZI`fymYbz4pGb|zWzKu-HGL}2uaxTJaE6yZ2}%tw!LabEMnuauY|$T5)<+sPtBL9+IxK`X9U@nv8*ebU9Iok>)5+@wP0?6 zJ4UtICXQ;2O_-Y$~J3ov}#rN#|>20@C%kv(vlD`E0a#4>BuiS}v=&4FN z!ou?-l2ekGCYLBTE8@KHmBJzgWJkEkCRX?rE?7|&^Oq==?b#g*U;%^(bNCgHJ62Uy zS&5=0F=*-1Sj>fFK=wTQMbH9Ds(B1M^+JMaQKKdvsHnq6is}K;O?7}M(tZ?WS}T!p zj_9RaB~D6NckAgP9Wy-iZmF~urFYX*dJm0qUERry^y*lg4K&1yqYTHG z8e&9ogyDD_V=$8t%`pd+jWgsjXHE-tk0Iphx}dBZ%l5~Zp+NKRRM;540LXQK6;vZ; zTv-|xG^2uayrIUG=n?XBkR(p@HzUUBWCG3&q6kgtdq{fY8%r*ov+|CMT3%k4{~11O z#o!A@jkxjQ{6~16D72{`Q$@5n5W(f^IHZj~)=7 zo~w&BG@PPiWnd;Q#sQH}mX$-J zy31?&^8qPM6&>+;-Bi`_ZF|nj|K_vK{QJMyjEC;|GwyxnOEr6b_RL?WEj+yH@lOfq z_w9+7@#TN~3{T#2@Qpqj?s_c$?VT^?zg)YUYPN>~zo&wHIZ+7?8SZ!~9x9vi;L>AG zBnK=G?m3cp%qT0qn1V}LtX^S^sikS zw-`G1BMe>K&7H=@{rV2Q${5H+Bw3UNnU{Gn6buK6Xj4JzR8I8yy?&3M6C+$8f!z)$ zf^sy0{i-WLV*{B?75uHhIm+rKu+?b<>{sS5M^@T?9C5qq2`0|qvbD5LxayJXRHs$M|&)YXajljj= zSHc@A=rQ9g_J(&zxcepH1s{x)xQ&po?f=(XQ5S?T_0L`<{~zz9o;mHmzSAKyEbjKT&qBbToq#_nJk|(Dyb&L1s=z;yJ=o2am!pI`KvF11 z7(n=FJunsnF$V`;u7Yv8B2{ilQn@8b8HrGcP_3YR2ffW5u@6S!2*BS$E_C z8U*&uQJ^f17J>W>oy6fXrUY)kaC>{aQ=XF1_6YliAG*G4;VMd#f>Hl z@5sNk;ZONT+P2~GA3cKcUFpq<++%mZcyJ+i7F6c zlL0ZTE|aY;lWCVJ49eq@B+|heW(UA|>cj%Y;DgYgABko3FQ-e$niaUxRi$39)VPSu7)BTTQLG?bFxX z_Np|u$&|S*iJ9AA*vz1)vg@^RVZE?f08s*)`wp}LwIaS68E8B@fQ}%+9fyPK5hs}A zXtY^_#peFnYVL2W=B9$l40hJskMZv{_Ru&(r!{PC0joUM*u1!|tJ~_O18hulTYt1Y zU)n>>T4=dJh0nPe%#!`g&}Wl5;!<*@xW>N5B`ORx+H4dw+Hn{hcBi6PtfyG4r*yNP zl2+9pXU!dqGt)L2r=YK9vqq+D=H-kqjV5};U}1GzF7Cl`kKq~bY4Y$MoJOYAY^JkV zZ1(3OrjBy&u$rP%&ov+GHXXr{Fdh2N4738u6^C#J4uD2rLG|>Ro25lFN6zoHr}5<* zU*3l|1UFtgbjkJHcPB&buh0L4$|YF)!i7{WiN}a>WrMP^GNeKsAP!W|Q!nCHaqn}| zGW7%Q15n)*3z?zOOIXLR6`tk4k_DB=1NirNn$vX9P~3@HE=~(D-L`32H$A!y_T}Q1 zr`r;??bzn_)8n5QXNBOIsnl7r5(=FK2&AZrtO^{@#|70Z2(Sl&FMJC?}tUL5tg;J^xa)-=EH=bgCI#TRX%AhfOhq65VmPN84 zc%SU>1L@C-w5@IKtX$^J@`g7{+kSfrNME*x%h*V7jGGtdGKl(?RGe@E!#~M&&mQt8 zEOp&aZY-d#V@Cj`D#`m@zdU&#Is8?gFY*#!#jA-327mct|^W+DJ&mge{JB z0mr(4`=8CIWB*~2ia%zO9?qFo6SXaq=OLk9Ub~xZ*|Z#kW9wxQe-7WmP!l|MOJdG@}gdJc4%U}!B7pHe)1iQ(LWD0U4 zolG(8Me9$rI)vR8(IJh@(dwhj7Xa2bUnbWBolTyN7&jo|l)WS(^UJhV+V7w#wUOFL zCs)a*?7bZg+{OGd`*O!>yKEzZoV5>hj3cACVUi(_v7hTu?<4nf_el518@ZA@4xRQ>le@)D+`Gs|WXJus3URp|_X9*$ zR2JGY16gX^&~C6{+b(!v2e!dgq#ZU+jI2N{(^V`KkK)cnI@a6Clo#Sclh7i7rXw4- zxu_`+qB+XBx?mT>X&M89y>O4+Lpc-#d$>;T@d@jlEHMa(r=Le`o-nj)fQVQ#R)tgk2}TyYu|}r8zZvt-W@weWM!kjN%qf50P-|AvLgg!f0Lv~lV%>dEt!=Z zUifZe55CHgU9X6Z-CBjInhGr zd4N~;vG5LZpa}LGqry(?)xF+GAQItuo%h-Twg~@BV29%s2NwtgBP3p8xW;+L1&nZm z(4btTPj*fBObtvAP6=NWxixS<(L*tgbH{9o&oZ!lR-gN*q%lR|OUJ>DwGyXU;wK&)y$JaVh@B1MQ5IJ zX|3Q0}w2iPzwPZ{QKnwdHrbv_HRV zrWpXEO@<41fK z$eA4l(Gepy+qJ+;M(Lxx7wZ>$d7BmkL_~q0>Fv9%COs_^atBMvN;A*O#d2v_KvdR? z3gxKLhrYQSj)yV)3kU72$?UAj?5xS`|JO*te?~t-J@xmgAZfGNw8dt%!XM0A0?(C& zg<=F+Hj!`v-5n7km3NJ~?5@Ud@~`FB;A?h2oEzQm=KL+fE{A*ej)gDgySkp|@VXnO z-Q=^=7+gc)cHtY~VIS&+A2;rvo_-`vLcu{kVvF*n)cN+7dXr+6&?k^dpDEM@hNMRe zqXQ$;Ibm|LA$^5#4R^J$j$0?(jUM2hK+kdSqIdnDq0a)J1;bGxgQ|ox1wJR-6}%_? zZkkW|tJ1apY5wgmf%o6p8p$G>8Q3?H<%8Z}l`ur$3Fq&{NxjlRzktL9=Lrjh?jWH&7ISh$E{{n{ z*y{GM)$QT#ka{@n3DVB;Sfb;xd=C$mA=+IYOLQn96IA;aIeos;1_} zDStppSBO0#7F4+4=)j^>xu}Q@N>}jzT)jB^@I#OP_SO9E&8>L&YgE!M?>fA3;d3Bh zALKv9kw4F!cJb_oa+%fHYcB4<(?0wF&)W5J{>cxw=MUUgoqG^xw_^2Y`Su8;+CE_Mgoy?ToAn=KG8NU zx-hy}S?;*Xxl&!@yx0DWv)%cH<8!ADwqV@l^txP5ms3;R5t0b|Rnbi|{e_^S_ygfk zEWq4hGuGT;_-HQ%0w__&U?d0(4VMHm+a|5rp2|EnHOQm^bkV~<6!4jl>>Bh}Q>Dgp~QZm^TBW*Pft z!oJWwm#W7fRgWwgSCtKC)~OG1xrb1NiJO_ND3^qcpALqF%Rn97)PNw2#XzB4rV2i>R=OBZ$Q5$;qk9Z1e349G7}$2d}bSZNJ)ioqlEclGG}0 zt?d^3TIX&0%JQ31ciHc8-s6iEU9LWfv^$axE9pv{MyN9E=KJ?cquGE1_C8ldZi$dc z%5U!zt4QIL;1?)HnnT#JK1wX+=a?~&0X)l@fnB=Eu^j*EPV*Bn`lQMocAJohmc$~m zB=Q^)ajLuwj)_7n(kEJyiVG(X--Rd}w$Kxiv2(QN?ZpW>LqYr%~eKgeg z0>w%?=^4W+CUz-lREaC8dE{^qnyYuzD5dwT4EIlHJusc+lt2sMw3`~)^kTOqhVJfh zb@wDHt)YI!Sa)vBAr_u04y{>$UmRc4yK0ccADX(A&Tx|YBaZJwV4fy#06Dq16($ikBPygL@S3Em${IoOkmra;A=lbt{ z{`kLF3A>z|o@sqFI~ae^&~o*v6A!(b|Hu9Kef{#=E;@I~u;Fu(ff<=WkI%m1&)%TuH3(5>6cWp`hwlHi{)K>VuVD7UlJ=t7J-%iTO3wo5m@O* z;;=4C2_y!+kJu6#N;_GyEpFx+ydcIgsixU;7;neLnDrNijp3tQ1jp~J@W`hYN}jY( zF>ku%^p5h5`+G)8=uBt5>rn2n&gRe77emqAe{}i)9g`uRdz2RJ@kv@LF8ywIZk9 zG_gE6((TC+y*T!A&^UudHga)4j{C>^Nt1t(zs1k_f5aeV<1m(+sm6;_JWMsBTKuba zs}Yqi#y3ngqIRnhHRq%5+$l9;#`nhPxnk(G+u&y=X$IwRjjL$rv%o8h!MgaSJ+tyB z-uZq0_@X`MZMyEg9m1}YTRzU8eEfE7|B@Sba_dXmFWG~=(5ed979;448{BDlgx-v0 z7@+dOVvxBz?0lRNsD~TW9fW}y7AMbP3)Bq#Zvux*xQC=)LW1bj~f zFCl^gkNPsMB3YR&L6%duf2s%sr)%m|k$%Ko*HXY<&mj5B?zky$7--aE%#jslnu&uHXF;Uw1}nSs%Ra zm99PDalhZPX!&x!l8s}42`Vk4)+f1^=8NXd;FCEN_{7{?0&5hY*`6<$}dJDg6<>v6k%{y;DYUQ^vR z0R`i9tGQitYfSaYN*oDv%?H3PjDmtJ$9zGr&lhxSiW2j=fpohxr!%g*yt?jkE1Dei z2~L*|AO=+uxS;NIDvB%t zi|SbbJ34_KU6gCxDov;|c{BwFt4{G~F}CP{Bil4XFb11!yEuos14BLZ0u`K6MVZeD!IKhB)Sk!DH27>_G+DXVzR8`>!0Is8*1i{x*E;Q5@m8k7_J2aI|izDvB zapVq$ciRmGnA>YPP=<{e30l!G__Sy$kl+rxV^4x&V20^4Y7cbMBvraOOznX>pjrGL zICAwFnT!lDD6mvTO0A{|iaHddS_8m4QJR`4Yl_D2DjY>z;V8=}W`-SR9+ScbrQplA z7e3h%qR!B%OymEA#)Rt>F1pB>U2lAi6XS=U`x6}fwCe@3kQv*6LKlB_nm)}~$g9D4Elz%2a@5URcKYu~t3qH!9je4O$ zWTVkru`5*}d$_97UR9N~5A+R+45=Dfm9yun=G*60HT7L{N7XK#>}Piyv#Cfwf36!Z~MP9u0gd9%`>#-`SNpWUi0U{o7{KWwfS*BNl~V6E;zEiVf*g|7Q^U45+Oz z=W3o!m_y|E`Mmx>GR=vSgP2MAa1mEGYv=sUyU$y4{(uD^&cQXq*W7SbNo(-(w{BVU z?08)Xlhqf}9(UGHsWhzuX`&-PIx4}h8P{MzbCwGOgyDivU)owqN=wV4 zHPLgUi%Qp*ibFhg{<`pJ|LAZ|&e^X1FzbDfv_FAsN=exQ9A_%QUT=j*`N zp}&?KEG?9V;zG5v+S^yCcN)TI=Xl{#;lq-D^2c>e_c?fxphy&Skm`#%Y(Xo|5wvU; znp13~7;~4uWy8A7ur=9QY`mF6X=4&&3l@iMk697ABUZkKxd4rg&eUWfP0CplY2VwH z0ywcnS{S>yYLJ@=2hZezHwTQE16E^NSDd-XNs5pT49@!o+=`E2z7*HvahSu@#;02l`f2rWkR`vd1ZW(Joj2$-?}f6}Vl(rM9Roj| zjY#$2Rx=D+&ytQ!+-_csniEOzX28{s5uc8dWfdHF+NUN)^?AB&@s>+AHyioyezki6 zshxc1vgen`sf(k30tklgmm3w#|wT>H{*lEKwwP+DQJ@1a%q+pb{VTVtWX@g0u!6Y^} zh^}J@D`EwC&0cb-SkdwN=_*3Fj!A?!3ZzgOhV&ik<1cEZ?aKs52Kg#q3H(Tm6=^+NB&=o~Ujn61q8 zHbpy1-x1#Rd>s1B^O^VCz~4fjF>LXdmS(~fkVb_mI!R}MD}0832pM1>MTXl)ct=Jr zQm5GG*gq3L_aDbc9Xj@bhpjsSb8M0e0qAh2fzJ0YFwm)?{rTMstQS)*r**;UOi;m? zAf@YXxv=gsTurVP7vK`*ToavKZVCx5rj992xkSq6E{0Yv7A&Ft=yK40bXkcSE-N8} z5=Ijfq@`|iK@D?l2gVKVa)~+l<|X30ErAne~%D(#p;kfr$ znD6Hv66zN{$2}%|PIQ8MTIj;)4EMtDjOcQ4x$hV`7Sxd+JMDqMcs~tHasH@ty}m&w zy3R+Us)TltXQ`A}$lhVFuF^rE@Ad#J1gsShPFpgJnKc2!4)zfXS=p`SN$gf?pq<`I zsi>-LwPSm@l;+Z<(zSH^0yTq5ajBo`hG}euXN?J_#n}Li5A<@$D6guu`r4Fw69M8q z`aR0}-NcG0>v5L#O8fnE4U@~Tah5}H40zxei{Oswo@xju%*lpzUCnjHsd>d&EiBW_ zf(3Jo+$$wm{0t}9A^{@zlU=>P+4*JuTkQSwyV!wGexYt%Idfgthh%~_c*-r;K7*$O z9&f{?phGp>EB{IU-+FxWuDST`RYT`KMRkq`*r7#u8wGHs5%Vh88LAHT4H=)R6?X)=L}vtpCsws$10Y zZMaudN5`D z-+P2@L}Ga5q{O7kdD6_p%*v+TExkXi_#*L5^4khmz%TmR$(FWWQIEt_u^vZ#nIdjM z9q26to(#Fp(1mE!sSYoTYO3E?ld9>t?ALeJ%*pSK3KjxQ1%qz|upTf1O@WpG-y6Dw zOzzFlIKa?2(2d3chQ@S(40iM@6OHLrbis@w8VAgDKSmt4Wc|1?mvPQgCr+WVQpQZB zjG0OqGnJOV#ls?&9>Bh;h*%`|8 zUYelroEdvcOq+{CGI~#hW)RK9_ZVG2=1_5V@F6q0-3%%`K&Rm_U!uaC0ZdUkFu+PN z?m2h<(#^L1LziB+Cg{M+T0c5+`5$iEef3kbKicr?ukL^9x@$LXx_bG>hVX<`|5;N9 zwcd*BKE4m*b@#QLod5m)<7v6r*NfZ9%~u3idOF z>o?eBs$Q)0(vDTA2kTa!WnJoJo$pPVxoA4n>IhvSG!EQ*5b-Q+rWnpSZUh)w z@Ya-s9vNxJO+Nq;1`mX}9bA3Be-RlZUX8)Pc15 z$0_TT4N9xhp&U?-C=yail|@R6@<{Q}L8YLmr3%>Z5>Gfqq{(|mANJJiF%kulS4Al$ zApQ}41K-Mb@CSLZgFnI(#K-x!V2|fbSC7yq7rUQl-OsD^`8-n;yrn33Ysin)Q>CoH zkClJO1dHp~qGZt38EnOxsh}_JIqrJ;ADf#F{k^8Gt&RWN{{1I>eEP(PR7#;Yx$oKB zfme2L){xVw5h<&`zBBrnt5UF@GS`bM(#)U`r-)M(&T0RLa7^SBYre0UC8Jt|Vi8<% zZ5eU$WbUUbaf@*e3&S4S=B}V&*&}VRbqnl3f*mk!h9e@+3%oc;Igb}oVjs0Z{V8{) z`XTpMQF=7uk$+D-Bz`IVOZ>O&bE~Sr zaXg_D6%-kE6j@H0(-SzJPnlB|ROoJ=4r=iN9jLI`kjl4Xr=bWu3kH_SbZ>Z^d1Jbn znz$Z}x#H{u1`sxL4Ym|AM`{Q=XpYg46vkjz)T41AQgl*DKL!mf`y82*Xc&jkm;^up zbMX-KHBm^j|0QwWr9Bk`UAssxnhSLBzWEp(ya%VQdyE3?^+1-6it*Mo20EWX(&ak2 zj$>tUgvUNg!KKR098rRHn#&5#pSjMRp(?#gvWi?%Qb*?@Y%QVF5#HGvXPYgF;%as* z5xE($xePmzSm@ZAU^%Z_{dDumR-H{^fDPNz*k+5(N@S*PCViCqV;;+1KRnIrtz!jE zNZJ~tKmK}4#Jn8m8qL_+sgwg$obFJAaS}_w?)cd+^YigbpX49CLD+S2H*U=@>zYMM zug=qTq;CQN7{q2}jWO&!aqKkgD$c~}fmElVleu(LPb@kOf6OskfuRkXc{OOTIRmS9 zfVu74&)k-oGqj8ps7a?#Dm)?_5cqLW91*xuVUf@x6a*ghib^Om2H&{+O-_@VeigP_G(TWs%#f3yp3 zYGV_)OglhKgEg5XpYBASBBba&a#>BnWf3J-^F=KpVi94BD6tmGh+0I%BElA-S%dC& zi*Q(k(;_^U{is`n+ag>R;jzpR-6Gr;;j#$3m2D|o1RY#5#@Ot&DgF?DNcl_Pv$*iC za4b#&ay+R7BXNb}lCh}hqlTY^#bh|7t8b<7`qYLLNd*F7M{2zbyLc8pV9A~?7LRA) z120=Vr?{{lP=o~$G!{f)k$9JttlJ}$fOAGHDECO&W6T;%t&iXcdqAZ70TK3q2n}Po z=mR3mN{O&&Q-p#QGnXP7eN@B>`bX#!dLdGiWVcT;uuC$qOQ!H!2-DCSDMb|WI0kto z{{eX{K9BrGo9LwFJsmZ?%s4Vx(qW=td8!>R-}0u30k%XHv#gl&)zij$ zwEt7{m)%=>{p$}uyDd5G>_tCsYnU~9#SlJy_t@!|H0;{EqpN~EblLPFcR$f}FWI_$ z`S=I!?E0W+Q6C0L^5ZRrN8m&c*{HYcf8{>+9N~_6M4sx&GGMu@bbO!wR`6i35ai>s z*WvZM!J@{Z->%vnn!{pRhb3{2VjdY#oyGkY-58Iwt7>$I(Q^V76ms1TZ0`zKFE<8pP%uK zpYf2NagRS`&f9Uhiqpw{)SOm-U{1SwnA3a_-8u~S56$zj0k*PI_n&ECA7v)?X(uw) zd`&hDq`vc%jqMj*iYlv;%87c~B|0M5sk(~{L+5HYQzgn6qd3IVgDX})cIC%SkB-;X zwyFi^FL|0z-@AGEqA~ri>smrqUB2*~yWZ?#>rD(Re8E>h&)ZQ5zqG>_EGBk;!9<&` zr)SKjREV8$OKM0vPds0qA~wo%#Cft@s}FGx@ec?N*GIWW`G*Im3DcAd^_)BBzc9E^ zSg6d>7rGbvX9a(XeTpd9FXko*lhli~%edLXZ1plt4Mcg#1whp^_v@&Y4feg^Va`x_ zg!$MJ#yV2>lI{|Vbrz%f*02mCiW57`1^9}SKN!(rILcGCeI<+}U5eAmpWUm2_B#M* zMXy*$!(>1^7`r&kycfnaj&h_qXlRD5GK1J)0*W&3V1ckAelWB|Y$`7@;Bgd~2x1|$ z;v)TQeI(Q`OhaYG<@tMZg5I3Tfti&%ojaE0sD{fzw|4Y}tzukyq*#71lZ~o!8 zZ@dnbU7erDCx9#5D2DGbmTGz*{VaWy&ez9V5?t^dBU&OPMEN+aNpzk6Ss~Y(shD+V&C33 z-hJcs_bD2jpP$Dagnrji6fZX}vylv`3Z6+uk*hSZ-d7(Q6-QSj`*(ou=u6+RZy=aWm?9UB?GjPWP~=A%p)IY9|iyF|1xwqa*{YP zZ}*0yHpwA+qdatWz)^#&{_Z)}RSdi#It=2(y3=qrIa~gp_Pzv8isJ11>FS>Dp4pk5 zYwv4@yeTDyN;)-o_gwNzg8d>Zw0c% z{ZjGfZ&SSarQ*#m6>t7#Yc(9(xitLNUKZW*K1H^0i|wyzBz|9`_@o(+#2K(++1^ME zn;|u9Mus&;v-IEj1smTJbN!+xHeP$pPg-XSv+qcyn_{eOz4?i|j-9Xmbno65U)g`~6_%85LE*lP zat+dZu?s81N~)0 z@bM8VyH2l}Y8xT^GZswfN_E*-o*;i&$|*fz6go0A&XP8|+RIl7QfiQ)XJb`DLa z!0wf)awqJRg?uoORVysTw1Ix`mUaDR*Iqoe-+%#qr=}HXrH?KcdhU~DLu#ilY}t=E z*Tz3mHz8-btB`yw)x9OeX3J}N!l~1ip)}!;<)hB|F_xjoF%&w6PL3hUNnIwjOoeHM z=emcx2NsVnoLRWUeV2Ph@e|<wDDWY6T3 z$==DnIp!Sq9M7DTIo>(GEu~w^{JiMBxO4B~NuK(Y8KpDI7Z)uqZYaLj^RV}x^835~ zsQY7{r@cQZd#rqO=}V;<<<1DA&@mJ_hGNHHr&o89pgW1uon-1fM0zh4DyW`hmX&xt zT28byT}$bfpTkP_!tAbciZZ)4dsOzc?2XxPWb6LyNcQ~f_p`M~_TAYc`{&?*bnv5` z{fecr_W*Cl4k-H+K}tZ8r*CXd%jhX*#rRMIMd>yr3=54!*_AEGj(y=lrGkaSZO%Am7mfjN5-I2S(l#Et9Dh1 z+Ny>sQN9lxfMSv9hxYid<=3OM`(>ARJKjLSHnO+~r2D;yMeLf;3n=r55Ek zcJ|~d8$IpKG zyKlUuoR>Fu;mm>O6=juF4O>2P$PML@ilN`RJnN##7xgL1%MW{sd-Pv2dD5B*&v4sX z9RFN&aXmnpN`$|N(dwMr+O{sg)j93oGU$%MBahE1Wi8~cSRD)v*$OFMpGQ$CBjB#^ zdmsy`DgHnq6)L_H#1oGto_LkGVGeQ+nr>WeG@SiqR9s!qFo*^ZjdTd^5Zv9}9fG^N zyL$+3!QI{6J-BOd3+@h$Go9z1?|yUd+#j=Mtv>tgT~)jM^pEa+s<5^=Sbu!)ShQeu z!+t^3wexQV2@xhuP`5yj>@zM(PO>la6vRqx8at+mQL1&VDmAcSF}j6uB^KRnveHOd zlk_y1O%mW85S%M-vi#=Ls+9nGhLn+vB%6S{!SDuRosski5`#p-1gBuwQl?JZjRp_Q zbCA>%F?rj`XY3ES9ar!pm}>5)c(g9MYORs2|IDZn?l7d&aM+jNWgo~-pHb!iMcll2 z)THG}Tx|GOiI(vfvF7WPq!1j2=(}PpqPb4`-_O|Cw!3pt@s+X!f(IkBmc@7}W+8if zx@**fvMZjZ&C!x9^JkX4-fk4iw)E%A`?L9?0DP6L0qtetV3 zcerpEzU{P8XeR2_@EtEK#@)F0=3n?;h}cb@yA)nD$1G&q-;8LIxAAIB(T>iRYRg}= zN|@#3YBZQT$P>6}WtHn}sw&$OipP#+7QiU^`VlhZABsFP-Ys;t?Xd*44M0uP>n4lH z3rTwGiffjwFU7C;wf@rT*y~-$i2@YbNWtr|nN8^Ww(xeE9wilc(R~Fq+H~KZ5gVUe zbjzs_`s0$N_p^9XD#jj79#;6+<DD8WYZ`fCygzm z@mga~H1fm{H5J>jLu7yslu;z@ zeuD#E{Ep8~3`DT8A5KnoKb2C{dEJ~+xuCySQD&I_j zqFM^aojBcC@>HXy8LT>?-ete_z95{p0s(oaXSk=QEi>vy8#456I_2Pa{fmIS!^fp1 zH1WHm`G^W!*Hi-qln0I-MtM=$^d|BOhY1Fqa1!P#(QSViT4>|WusIo)e z+B&H^$L=-&dq}k{M)okO&9;ljyG*hT1LsoC9ejlVMWgdL2T$I;I(FWpkm0KMo$@>C zO<@*{$Tr+Z5;y6K1}60&nO1{{wt{cPXvMGl923bo2PQ4DmTB<`;CHO39yBLxo#FdV zP^UTm2JbuomLBwXva!vVgjz%MUn^ZV{qgC;O;lf9y-!uOEXO0p4`aL3*3Blxujzl- zZa4n2#<{es<(kA<8Xw*AsbLHHeWFp;2ZYi70$BJps=A3!WP9wC{%P~zfqG!ekjv_L57GL**)FyiG+yIrx#)P?IY)ca zWOue2Z#5})5usX7g_Yo@@LhETK}cuz%>X+`onZ15iCXy9LMXP%w)r`q$p6H^etUbf z*U$4TuB%C+K45VJrPP z(l!zewBS<1Q+e3lAVMF_$~Tx5ZxsTGrZykN%fdk>(3C12MQg<<`4aiEbo5xf_xiUvJ$g+aW#qN*BRRpY}BEb?s*+4)}qj^yI84b_nG z^XpUta|NOi1S|;~H^tAwr?tzpu>x$*Ml*~B;*4nJ4%n9TDRB`_^w&kjPd;Vju*c{G zEJ%Hx<4GHtzrIKPGJ6i%RLP0b`}{_k(>-=BGcs+S>@nAk_=v_YUDsFgoSsBsoP9(Y z%e>VP1?mWMWCE4uG7GfQj;u)!4=O>@o3>}JDa}IiJyqVAK8|ZDAy0K*9VJp}{xZIv zrkhQyRJL!a&nV9Ad`IZ0idqmv3Yv^UiH>Uz*Y;7gSK%cT_*pkaEFFEhCcN>cxUef? zyH!+5IJ?{+pH1IvpU?+)(VwTh5jI5Ngk6O#&^QY2zeD_zNx}c!U`s6u^2(+W`XxQ; z;&p(WTjH#CbK&8t*&&TthtbcXfudaO7|)v~#h14a98;?kocQ5z8$iotU){lW>+>i} zu6$y*0%(_9vw7sNY#V|sopKUN)%3YXyV~jX-2+?K)LMI;>$tOmyC16Dok(bq_kb#0 zh5j0i8NR?oj$BfzwG5RaMt*aoV&-bJaHMrHqF9W>i8Jg$(0vk1jN9hiy!l1yq zH>cjin#y0DbU=rxjRPRn`)`}m(vI1cKMAiOOHdlHkpF0Ff3@h6S?{*vtuE>WkL^qz zv=8k?by!TRej&|7BZAuKRlsj*bn-T4HGPt3o4@j6HI}`g53{KTZ1q2X@!b|t7%3~D z(gVP}Y4VSR-r(Yu+1#9x`s`hQ*3G^h$W&D{wAaWiIxRPB--xL0@Z`WEwGY$hAG`#? zC=tN}^dnA?JY0INydfFp$L&xkiQRGHw9&g$d?RWGDvCY3%7@R@RP&5QkMHBnRV3k& zZt3nZyk1j|E{d3dUVm+wd>c23rW*tVl5td1B7Q55oEi3!^)&XVQSq4FjRyjuBm|Po z_nXuap70Gbj!TyH5i1^E)YIcvs%Snh1>iIc9aPbkX+Hg-x>+uJwX!!fYXa1El_|Rl zUJS|Cr~!CXJB&SThY=UYHIcaBrq%9F`Iy^6FZ)?8t-&h&SNwI5$shJ$145wzz}6-{h-|7kUB{oCb8FN*XGQR2Ns>xd?u# z_n0Yk5k#wMQTuaUQ`hK?hqA#F)$q$0fVh?0F<87%)0nmr4%C$wI&J(V6=wVEehH+1 zy%o1Do~W)I@#LVewwHGc2wyNCwWD`$5QuGo?8NL~u4(7B?es5@h<-Ane6sKaWkYmh z>A6$(r=U~IP~9d!d3k%kcop$~k);AAg@&3fgr4-@A2*0J^f%1g&(z#+eCcF5AG*`_ z*+SR^pAqP!wrx5rOFV>{hH)=^8@xSiWbmO2teM;Kgh4(v`>A~6#P%Wh0q8lIwu|g8 zvPWn-uRY%dc|%#O5hI(G1ox8>E8x)jG2mRrqbX=fM^H>;tSY(qecFe)5jEYM;*DFP zwaU3CVKB0sG_s*BVn;&=x6I2TMzKnwsmpQq0@Wx6(b5+KwhyfJEUt~jFDrUT_PK=6B z<3_JC#?Tr*WOVxoQ`#Y<3b!@ZdhM$6E$0jNEmwYOZNEFo^)-;;0~S4^$z~{^4$Mb5 zq&0o3k6lNyjx2fYTFn1#YU$gth&YLu+^(cm^E%jp9vl||Y;K%7)nE4=eax;(5x}Qp zn94exUK-OTXf=C^w;o*It+B)Vu0PzV6QkxR;K8NpX;?Am_9MGVl5~OAE#q6Eisp-= zer%iJ_h8)WBLfUMe3MBM=?=%|->pV={uYxoV{ zwC)KXbUsFRKn+qKQ;f^7O{UJ81h_XnwLTRaIaF<6NM2ISXt#P6xGR=wp&YjJ{l4>% zMho23p?vK^atyD4qybm)Q?1Ay^knxw-krjnK4cMR1&9k>H7cQ$? zI4(mf%PDFveAJ$3QNm0xFUz+fHAR~&;VdInh|jn2H*ln|>(*GYt5N|p*8X(});Ykl zFvM4r+wNaYPX_K+Lwb9lNWK;M#ury93mXcoX;QIif-Ls4M?K-!7@8gFoz%1>%os{j zaMjza{c1+1(+m<~oA=c^CZpDGH5P5gDx0U&MoTd)1?9!Pp@wC`y{NoUatiXWy1ZSa z88Bn%(wDiVvu1C8zv3QH=ByW_Kl3d$$-c$B5WgP`q3kJ1`YCMYqLqgSyQF+)RX~!F zOfUB0Wy7*J<-lh9;#%KQ#&(wus$yuBv;Qm5ferLY*EIFD>Q0Cz@lFCgP+xX;tG`Qr z&w2(jjoxc_k|g+HW^|H!8#i+r;lW3OqCx#TNW0Os%a&(|k4fyv};*sV4H$sCx4miK;uXS*#Waiz{ zFk81R4f)DXQAPgeuqv<=b9~}B%`4g{(|GZ7u$9WaU0&E(C5(cWmTWfZ?yb~bN>Wj{ zRmno*f)5Vo-(9Xnkh8{%C;}#}MlNlw{}>usR~TjuXmr7~K>3HJlsEC}{!X>8SNRwa zKjC3qU%=0L@@OiEg&}*!PFNmEQ2>KPx5HHajh|iVV8Q&r+)|h+iPdq06Aj}f%Ga=N zd>I`hTHIKpl4UV?kZ*|3&@sVLSwqKG2OooFGR-o7sSE6i{;^%ThUwd@sqU;6be9=(x1mwXnqnd!93r+ilDZ98FbQ zvfFX9&VH_Q%ATkgtee}yA;dCDxXvf$=ScFNl#r_%=^RDdok%PGQf%}M?hG1p1e#{s zJ$O}#A|d7c?Hb8;!k}dAIU+ubz$qeYoR0}!Mjl-|8)TEOsukxI<&zjmsZQqeTIEh& zQ|U;)Ej^g|^ipGMyU||Nbiev`Tk?7~7X;e!-=51U8^*ZM|I8s~qkXp)j45lI>GjbU z1PUU0JD-;Ks!#P+eQA*Qfjq>Gqj~Am6|w8|PwzQEU|Ax4uX@R?M3`R^2W@!S7?1Bm zFn86q|J9EpaA13GiYdH>aGXnFIwZ$Bq3Uz?%aEG%37CJh&Y{p6Bm%`2y( zHb+{Qoy@r46Ja?$BmAff^!A^@$HRCZhPZ@c>-8WScI)`k3SDZ<^J;fk>oN4_6;BFt zmXt;KR(E%o&ST5BTHONU>hr{DBk+i-E4}*X8`ICVGL(BmfzQr4-PvmWZ-(nVh<337 z@;~1cQz=Mv+}F<7FA8mn1CT*e9#iLTUgHaxr7g{r?{I}h1k-rnnmq1Nu=t2k0Xd9E zpA3p_02{@fU-d&@a$Q(9d*U|&1KIH-4%dIYG<{Y_e3@iCBqHE0B|L&oj5Pn81;Gc@ z3cpjRokQvrR(D8WoBR2==E#k$h9^M^dHKrqowR(H@JBo9PI6R60;BA?5K^vlppHS* zvW&VF=C2>GUcL9kWrz+0hx6XOo~wvB@Et!q7TcOvqq10$1ncv;66yf*5RxRosWanBPxXez zBg9kr2F|1Z9&q!;F@e{*=r4+9wpy0wf*(dtNy0ngWYcVT&ggxxCx+w79&g4e+HI5w zng4W>&j*J*#jOgi*v3469x)!ACS0F3^1fFnr?YRXLR7(;AR#p2)&%ePwKL@*!fpBl z>H>VmB57e$M` z&-yQdM_aU<8L|^)`D-OBzR)mKY<*p1!m;$H;7Ko5% zs>HcuAgt&(Xxv&J~0KHrx3A1{gM?3evhw3L#wLGyahzYtb^eoxpHD8lm!8}?( zdoX9bz}n@Qegv@NwEo#ydaPrAUzdvw+Pt_j|C%!;x1(UstWU1I(vs`zenPcVHzp;} z61zU+h&y_Y*TNF>VUqsk-P?%oF?H>47wc&CQZRc6NsNEvDgUZrBIu`w4k4bu($-gh zX{5oNxe9}K{Ot&Va2Nfp#S;0bmen^)^Ad)pb*jN*30=M;=?*?`*=CNMd7!BPx8Bfn zm3^UU^)97*V<2<4^*MLgt7zw;)qLC`a1LKmqPhL+J<3I|$rP$4hN$K`gF{Z~`{$<# z-`OmehG*{)1iWTA7*l^m8PqSJjX5M=YGpTPxm?$03YDU05$%phGY3saZccukhXb}f zmibwEyxfMSlD`yLyjLx12SQQVi9UUXhr)%zdRQrO5ZUIy z&7YpBw~*5d^T*$)6nuoOb#^TvPi6|lq4**KDf9GrgUxwk9CkVBKc|qqoD$9smg=|U z*|sCuB1^sJpb1pl33`EhQy`ZjjT9gy?pp~GOeI+omTKCbNmmP;cu|`Y%=-UyOWhAA zoCP%ka0;i3c>cPTAe@tKdh@KS<-WT~Z0H7Gp>%AJcY33*bJ@_1Gt-hd_%a!xE#em9 z2{I$omTbSB4BwSwTWi{9)y7p&Jy|L35aO13VLLfdzx#DkV!2A-C23vEvs@iqreiDm+#=X) z0^+b>?TFm!?M^4RWc%!ot6L;jAa+82wdr?b(eQoo^IN@^1qbI11Xaf1DKAsktL|Z$^#0;2|1At zXA<6FR=*T3KapYB;*(qyBK2xrvuD-lNpess47wBP!%-Mo;}FsvH5X+~B}W(J4e^_7MYpX~VOpt9`uc-kIkOx7 z(N$q&Si=Y>>*mwsBj%MnWHfWrONc*@-3R^m?(qOBX8#ZIV+^2TxfA0%@{z|r5zK;h zZ_uYR^F9K%n|UgV)-9TigfU>JaOUCY#puJH6JLU^O|fOT!((nV;YFSwVim@Fph-tt z#xv7hio<15!ue`~c`xZnKL3a#BrrM4W=TR3TLg`ynhOus71^SpCy*V|poh6LHiWVD zf_VTVYAK-krOV^PUF2uu{9XOt&My~mv;*LJ>ejYx%(!;i=e5Oeo!m69*XrRh z_%Q5Re`9Ol4tihRKfOI&y9?=m(nb347ivY%?Ww(Jkqvs&+V)%)2=pajL^-$&Dh_gk z`7QYQ@1=1quhSgooq)Uo-}|FFl}YmWm+8-^oq{Q(vBdADCy9sH7B?FGR39v}&{;xX zn{FVCiv@%)tYz_DeCDx+^C+hmMJ;xB=zdXk(MmMXj^8vS653J^+bhKkdWX;9jn%V^ z*U<7byaJv}7qDARe1@($^@qkUIKHl_?NjnWLI>z%Oav-a4V&1K>8B>vg>1@f=`Z()QNvtre1a zx|{f<=pD~SIgkCAFS)=!SnW3wmu>oLUo8uJH|svQ@BGqHzA7 zK0x01^AZXYqW8er$xPOijlEK-_Px^v_%+-s&tUriU80>RPFr^AYPX=h1=ncaH zsbop|wF@p=q7B>EVqkW@FMFz;m}KlZ-lL%^C!^Xw#?JxrS%d?G?{VqDMZv0W%y)5k zC&CsCyUM-CDv>hrOm$InXNUI7D@v5_2F|6KJq;GJDV6}sFwg-vgE$-IUMZ$?MZgyDoC5u`Z9%;4Et_~1dZ7;0(U18{vZX2W z_EaM&cC)uUc;X_+yv@IjcFmd9Ge5ZNa#1uI;C<{*L{Q>wr^vjmcZYP18;95$`-pMP zsmqT^0d+CB^(8iLG~i`q&m-6OH)r#`X_Qdn!ou= z2Vw6c$NQ&%Iwzk1q()Ci0;n43H<|!PS07m(E%%@U%~Qrq(7+{3`={M1cgN+$!%BCV z$^7D00nYOOuR8A*3?B*+ks9av6i34k=8>x%%neBI?QtIzl~7r?)z-&oPTL+ zOrc!6CzhM9&JR3M8yOUt+1$Z*(u18oaLX`7c173yJklo3MKRz^u{19|jX~7|y-gwa z!m{)7>3ksdoP9}D>5Cpmd*8e7-D&LHef8x`^g&Xi@&_XL&&q}weX%=BmGk!S5N>1b zH)*Gi&R+;NR@KGhQPmFm3X10niHCadZFYpw;@S6(n;Y!z_TO>Vb87Es;y(gvXaW#S zGEwwL3~`1QEvMQcmeBS_5wUaPoTiQ~=NQE)mQe0C`b*axL>|fu*VZ)~)jqx+&k&cW zjd(t3x^222K2hvCaj!MSOJ~(}_+dTqCi5ciKXFPBep)$KJO@xQgzR-DR{<>wrdT|> zs{${!o4$@ZMUzN0jiNQjXB$=CbNe{2x z0#j@}7nh~_kTYaYePG1Fl{;2axsJobqo)GBixkNmL$=d&|&%(3OTd zW(T3dx2J>XMjRzs73G_jls3G++U9hazhnD|KQo-nv?AZ8mn%@DNyU;bgm*``I;zcn)b_TypFa9m~#8t2`(Np z(;RY2e$^X}HNAZgUGgI)`={Xq4@z^Uzt)jE37&y?Jjw?gl%t*<@%yi61)ECaQozt$ zz(bJ9zz4D8$-OJoJ>hOwfM+s{aSII9hd>`M-YD5-rVD zmeeBQKRx5sLM$8a>cO5!BiE=Zng7T!8@rFNHI&~8;$dPpU3T++i>?-_XQ{9B>b3T# z{r*;VGn{I9oug>BpPq?3=F*ApvbsyKK|b+m z$92(zyBqnf5aB(jdXQD46XPTNRJ;*BXHegjE{OKiwl0m$S##ZD{M!!hx$CcX9bjj6 zwmkGuGYsNG5Qq+vpk?1S*%(vH;;mtSlYpV*T=gT|1+T=Wt(%p6c&VUi1#5n~*ybK} zJ+!m;R_=ssA?F3LiNl0O&)K=FOE1|Kcp0d5MXWDgp+L4^uczOCYW1m&Jaqin^bX?e z!xVcHdn-leZBD0gx2Ggb=OxJ7Ne-CZXPu=%uf&w^5Dlpx6}ZK8tzS_g6uSCI;efuw zlWi7>?vl)nu>05dm;2n`?oX*eXN*$9QaA$G>Y|3C7jPXdrbjpxqzC=LcE)D+zH=H} zca7~Ar_Qb;cn{??oZP}0)cVyfN){CmPzi5tsf3NRo6VH z=*vBwhmVdeFOI&_L3|AswFIzggYK=*!|s%X%F*oMKPZ(6XAn%^+WGtpxK5BhwW0e% zKk$9?)D2)!uv1=Auxvi%5--Rb$_=Sh$B8D&7bE?>ES3yZ$a;^}LHr)Ya>~U$sWvg?VPtp^eqXS)7 zPOc3MO1mz+li37dvC&)=8Wzivtz(tD$%e17%F)}<51+q>Hs{HK#uAqrne12UiGB>_ zp!EE8wCw~=tA@>X>dAz3E#ssNY3jd;1h^&xDJBFqh97(QddT7r^5i-6U5cBq&9y2V zqvYwwGA(mSp1O#86u|x_ybWSAbJZ+QG zf3$aD8P6E1*qn-LDrf~fR0wv6oZQ(rWlI<~%0ba?_`F(s=L9X3)Z4}EE3wI31dY^z z*sg9v*PgZ8?DORm))Iyswa0DC&saQcIfg7P?9Ck3zPTv_ubckBQo)git$iy?!3*F- z{-u&GhS?#9Eoe6jW!bj$<0SSn*;c9ik6GEzLpEpckoP64nwvj(6>nc(s@Nqv;RKLl zApQTg;SeZ{GqKf#dT2e!4OhA;H3wIQ{?xpXs2fu7s}AY}9?0Ir(`nmD=1+6o$vWlX zn+4$?n0!2}BR$90o+aq#O?5W6*shB$h*U?vC*ai}4*Dhwt?v6sY|)Ryo0?3X(~Ryy zW>5dEcOAM*-mG->hs-h)dYI3Q^$*cG5bE&`^nqLDIGM7JH}U`Q`Th976rv+ipFxmfohJ0R8S_0v>n-F=L=W--q6hXJ z7O(M6h0gwZlXxnn`FaLNPhh5f;~x3u)YK^h^Lul5f4uqvtk#H^BkU!O!AO@f@?wFW zBTskOJ;%)w89bZ<@b0eAX9KwoYnj-6>Wi1ZaFpZ+Nt`#eB4E{FtBMjsG9<4euFF#t z`zi%0-I-6(?oyeA&{qU{9WQuGI8k|4Bj4z5hs>Xhnno;HA@s53M=7M|AN1)e(ao$b zblRV_eD5LhE|M9Ts0_@f$|GInHIU0hF9D3+u{iQdSp1)*s~)zwdc=D0Ii3<9CLi-5-fv!Td4_t`1rfRy`zX*=LwPND^+x zDc)#8G+X~^)=2^GosRa^Z2gXLcCtoGgQ*4z|EO2W$YxYn@M1VX98m2T}!S_$L)DweK+_Jp!pPR`d%{brbimc-=L<>`L=udIyR%z*5 z3mjjq)gswL=PF*`rj-gjw2C^#9kYNo&~A`8a>@wX1ih}T=wrD!aUDi^xm{`88};~dI|3f0`4YU<3|n0LBh@69*WrNf~v zvobijRy{w-$ulF0!w!4=(@MRQvZsy~F{8zng#(dy(kvs3WJ^z9rPZMPM^Z7kd}8MH;1>pcld51-OIj~!W2VT2W0i4^nSVA!TEB@*fK(sVGTjN*~doY z7i;oHpx)zwTii0Z7Pe}i@vNe5n-UTsz4nEw4k@jznK)7L53S$)ovOKm3Y9bt-hHN) zxGoJ&-9gsdL*1h5e__dIdXx=EO)wpBNH5XccOecEULb=M07BGirMu@^G>~Fj-qptg?~>g za+?dj(=qqnoNHnD>0@m79H$+S&Gq;Po;Rb~Y@1A>Vd&gd=bS^_T&=uiY8fl7Do!#D z5}S0tN>QG$<%lv4ATcC$?kdv>xjtVg+?K0P3x8Y*=YbMQKotjr3aLn1Bz*3BC97x> zf1TNEnWY9$3RbGVO+cM{=Jq-7{yI{AWLAFrN!|k0ZRZ*GOG+~quNVT|^a_kDxMg8k z)7i#URr;2HsRs&#z9>_t#e%%IfEJ$r}YyEys) zf+*qGh+qajAid9Qu;sqT_v6)`uuU*1RHwG8TE|$!^g7ajz z`Dh2? zveq$#5vmS^sm0?!zMEvbU{*`y&)s9URNo8Gm1i8R5GzOq!rCFm!iIEHX2WC(qV*Ti z*=Vwv5^!|Ipc02>KI1UC3GQ;ClcYyKibeZUi?iYsFl4t%DPEL^S{JldY39|TW+ZX) zY{ai&ar^JMDJ5>xxgRjo_3TeQdyS2?HnUf-FED8Ed2CbB&!1cWrbuXzXFTNCfcU*(#{65~Fdn$nc zKGu>pVLq5r1cZE!2~toe(>XS?livoR{Iasw%KQYyw@>`yJzw0$w9-4E=Ejs0l@zy* z=x}C^pdJ@B-=ve9x}8huOxX#Sui0tkHBqGDS+~n|ap% zNtlVD-;ZslOM{Vh5$YX;W1NDh)0k=@YMj!J65V7>F1K!i<&ZTcWyQPXC?kcvfVXAJ zput^nEoH#Kj8nSXW{}dbN)k|DWss2?Wz{vVcAGuhTsX7!URfBP$rn0;XYQ{AU>}c>TYiy8ps$Y6s2> ztN)4e|2+r)FM04^UdS8Tg0u7gH|@l249%SZtpAfb!ov0*U=eie?5qGf7G_oe^FQsu zCa{4OVGwdQ{+DSS;0QDPWBzYJ#|#b}gOrP*jis@WowWV~0FO*lrE$9;#xI>OG(I*!l*?aG^(sZ>19`xt2dJp7!sLj$DCg}< zYqtzmDZ0SajkK(!P?IhG=0)i2&L=6?FOLS54~z;DH31+8#$;2jCGlYWpZ09h!|{|C z$y~k5tA<8${RyDu%pm>8ji79=R`bz{rR`|GtBz@3OhR#PkLUkPa7YFCPs1ONnJ8| zB90-aCY{^O8jCD7T*R@!pef*n?kJuA6-Njtr9YP;dys;&gLM1HhB=@?VgA(3!0`3}aVk|Wz>%cF{J1**N0I4n>24N1@(iw#N6Z_JzXImdp=`%7x^zAV{9 zp*IUyt;v##<4cWUE;GZ~GslNGG=?qgSMJAxc6^#kLESQrq&eZr11YcM&HUISIQ9s+ zeSW_-Rtffz`2|i_frCt0T?-=qAWO7AGi)w&oNkzZuDy%y`zV68P=jP86QeaTzXL0K z0G(dh?}M4Nfkh3-l>)efQkP;1L8EXk_!*_Nw#uG=D;=a9X^aE`y=7poun zKL6@2zD$dDHRRJo$r!6PiClp?`@}P%XTor6#UHrUpOez5gg&%MpP=&%m~c4G07tdV z*UGPf=_Axsc7MWjkI)3a?h%Jezl1n5cT@^aD0T^M z3l?s)JykrjPFi{8_iEK@Wdi27QR`KSdro{;4a-PE{^W~d^=0Ebf;Fnat1cU?twB3O zcB*VMY4_R`MAJKUy#Xj2#@K{z!^q`t5lI)uTXQXUUs9ejCMYhA){amz3-5i%^=a2u zES~t=!s&kLCzJW5yWKDhat>j6Vv1{v4w%*HNy-&y-T?_jrf<%dgWK+)-})^MGHNez zse(Wyb~XXaxPCEH+b*1%OuB*2a|0J_wA=0tMRO&*KfuMs{B!PEX>-fO;i^oKe8TQ% zd7=|QpZAKQ99sXsxQqZDG5Q0VQ2SeA=>}Wv}p?gR)eBw>71LzT!COnL`(e zs1EcseaBgF$eNZ6&s*@(bqTVPMZ3J4pFN|4?O1jbK|u#NqPxpWoJv3krJQdIQ(sld< zGWN0M<^o!5hp$sd;lNK1bsZa7m&AF)7BO)RIt-5Jo)nOmeunkXsF^ef{CbPb>yuw~B)_K3|dB`+p!`?;#g=-Y2m zC7;ojH)zB)enWTgJX~N>XDB9Xt!R|Mr%)y}LzlcuPK5p1NoE9qpz3n@z1Lg&7rlr~ zii#>}MH6DtJ>K0Ypwk!9EobrPvsFKIlrK~Sdz5*I26ENyf+@akNB67{sDA#q<}@?8_+2+J2)ldcSy-)O6*;;>NeK3z8%kE>Ms^ z1Iq}%8MwI{m@)&Befy?OUd*~= zNmbP*nG|hdMuEz5gB*Yb&6~iRDiw^0a7<6H+&;f5wK0n*kc8L;nNWws0(sEQW{uA$ z+IB?9Sjf|v-L!?$yy5*287V{lQ#$H6=2DV0*nt%R>!klUU>fsiS#czI4ih(=>tXI@ zqrL%y?Z)R4FBA^?tiTZcNNt4#j#ohnrK7!iRsl5*egU~==9VBmRYl<)Pv10PDJ;F< zZ~C%gelfew{Cd|A!u5v2Z{0|wROWR5^O)A7xnn*^+6!QL$05LJR)(4uR9^ z`E*HIMtaPDrA(2J!OL<_xMhYFiq8l0&|5FD$HEK6noL$>YTGnLy-L@*t+bl(ZfdpZ ztux!t+ImsmLdBZGix2s7Rm2BwtIkc{QqDsH_fP+6JmlM=x)I8}CQy>5gx^)K*~}v= zrwUtB)o}!Z!fkRN{XX-$o6VQ{bnd&lVU7`?Cm*qimW6A! zMD?Z-l?FVM9$^f0E|s(S!>-kt(U$e=!f9+(jgf&OXZnh2c|$4~DrtZ*1C#g6c~Z?S zY*$|m;%tZ8n+wKz0rkBym;MC|VLLA01tC9qMv?Yh)n?dTC4mhQ%RwqYu0XlCXhgSx zTWddaB1&>p{`kBrjh~8pZjOv;{&2irbV!3X&e75i(>XfKje;6Gnci;nq`Y>xu2uX& z!T$v>mWgER!cqYp`4W!-RDS+8Ra(8UIqT=H+Fh?vPP!m~u7-13>?dZvpA1yvOWNf^1)4q2o6XOV!ZTI}R!X?)k6Gw_VSLrm_ zJV*@M=;69sc#Zg(eZGUd$}ow=cTc!T&iZP7G_vB}>9&PQMf=}$R!9p)Vw|*- zpgCSE0l;z7%&e9{&%`LV2S7cS&AM9hdY5eNwZNYsHsowqpNfVn8x=$OdrOIVOK?vu zUzJH6Vmq;-eb?|vRc7cKVc9q(H^-5b~40VY_Bqj(0z&bpKp@wF%>`T;De>(*$Q?Chd_rqocbGyC~B`PaH9>DO>IS4F6hV~P6{9K(vNjqa*6_){I)j~g|7 zQ9fCYYM$59`PVzsiv~}^p!ysWBY%Dhn=;nJKn>kT7=>W5(Q#UL+^V8z&endtOB{R& zVmJdFnCUV(tnA^wGq-^zu-`uPKHe)7YB$$nuCfL0jbo>(@l`txOVBwUG(hc~n(6_B zU3I7MiP924MZlv0tjIcn&JMIXHMDwETG{E&64}T#dkBiD;Ur zwzM=URRq`hXyQRY*1^wh8?3L)xKtEmW?UR%wvjuEiuJ?zd96g)iqWs+{z_59iGSrD zmfz?V)a!Z9oX;+Ul)L7by^eSO&hLwu$CBd-gV^D^}BT6VLeXUY}0m?P+-XeZ{_=J#t`X?5wack?Ro#lFw-56_;oof%uy#Nx?y z7wN03PiGB(&25eaRCO&lDv_iEBou{_2P5TXSf4b{qKi)u4NbdO4?N}y;j8Ey_*2HQ z4(A3Mb8~}VG4`a`tL>FsqGU!K{Zu4lyz%zRj3si)EtMdioI)F zrI<=aP9_V)Maa%~#yY09GGtuI#A#UVF}1tf)!xJ^A?iVb&lDFIW6`4cH!bQL%cv21 zLFc!*&e=XZWM_F3$GxUF2Jx|&k-WHF5_5^MxVUJaHUXa5i8e0&?jIA1vZ>2DUl-#- z<~&jzs1+DloJ4!&gL9Iei}I9&pr4UG)5&uJ)3QY{y=;Oj%`SS2~2US^N0w z&z}dGWnIH$!QEg8H5)Op_L!<{i9gP_8rh^1v1Y!Vvw8hSDurJc_j`X+0i)i=<+4@b z)F?m(0&3 zQOvo=+h7n3>dIo5e@;0_RS> z*q#>25@G6J<3hLeJvlFB)vF|zl^ivNvPLf{vtr(ji`z9gJ>6Jzeh*oznxD96dFiI) zM%^3D$$#M91_3C^goaLq>`QX+d{F;`H(2aYs&b)a3zOFKve)}&Kx%A&i7*LHI~sfX9fu3(Pyv|A8CHNpB-cHXJk4Q3=zlQgyHB^-tuCV_H- z^#7pk9)m>p+6B?KZSJ;h+qSLUwr$(J+qUi9wr$(CG5vqvI`__;IWu?W!~Kw|WTleI zT1hIYG`XkR>t^j`kS1wc{l0gC8+{ z98o&#D{v?ijDSq;9+=TSvu@T@b`zc#hEzO zt}3;nE-QH6yIv{7dh9E;mg&3TY0&vujw28Qy=vORkTLVOYh}TdusK@9LNSLH>wo0V zri^r*vhU6VBOTwjp5U0^<<#9B_s)Q^48RksJ*jNdGwscm4j!RBb=Mm+w|N*!v~u>h zK??9e{_Fxr0X$nBZf*SZ8J(G;p|X3gbb)_uaBNc)l?(_)31t+EPkb%IP||$ytUXKTL0>YU zb&8|knvDVS#?WTk1?{tX-kao|ItXm>aebKB4mh^yJX%cyXPvxaur)BR^t@LoSem{Z zvM~XjzU2Mh=-p9juW>WDr*S=4pl-LCOO??I-F_vEiSi(27rKgl0xl(km_2#c6(77^t9z+`vaR~(0ukvL_+m^MpMAlbydUJ>kW()L>Q)ntJl+KBmJCEjhhOiJb@_L&=02qKuT zVc43mh-8U|O6zq7r#J!-dTC2NzJ6HUm!YOtv$$?iO5aoBQ|u_!~vykl(b++fw%g_2%!c)y7q7 zETVlv*YudtoKZfBA((6mSJT%HKCQm5F_erfDOH=6P*^HKNXsy97ajXmM8+5EnCdX` zyf*B(8EwShJ#yuF9P;|d_T>-vBnp3p<_)KD4Mb>w<}4=Jrve$dgh4=2{vavJv7$4} z8)a4}*Xv+b+2YNKClSn_y~|i?VlVBX95Dv5d!gt=9GUGw*o@=aFNb~P0Xw$E^69FR zn07Q-DTHp8)qqWdjR*7M1vrxV>uEeZ0$Pf3bzF%)K7z?hw8lez425gq!>A)RAZEHDt#kSwnA2tEm`7ab@oQI<|< zo7)rRQ$*KEA#Kh^^m>Q0tnP=_)cYAjs%=bAa`&O?-|!iJ#8@Gc<*>PvZ^lo}PY*-J zaLm)5O4`S;e*p>}4Ra;&RpXuh?dsiDWy`7-b=cAvVdH)3?oj8y-Ci!eY4KzmaqpiC$6!&Np$P<>2*wn{vSU*JZc$ zboDYNXM!%r&dPazEXk_ac|_&Y!sFQKqLq3#Vf9n(g3rlPcrx>jR)-PkzM?Ir!{fx- za42e)aFgy;CS)^F-0}kle63^+eN}DUwqX;ua~#{uwQ;j#7R^99AB0OpqahP<2&BcR zDaW-BZh;F;7{^2);z$CP0repJce|Av9W+U&QY|<=*9>eE3vaJ zLac4M_jdLd+6RIf&ypo2C72!*4q4DcA=MgZyE9GL6WW0Yy109U+MFS}OR@L0RL#RN zY4t{GN8Qfg?&IZo^4~cww9OAT)0PRvYbahr9wut|YV~cW-?EuxsOJ^I+B6AFzk>t5 zf+34R?$OSL#)OjP4EQ3{CP*7z=@8ilY!#Z-pCq3#WN@fKZzB^$l0gxn_oFqahZRn+ zcM=Ve_w=#%kqq{JL)Q$t43j|Yo6!%ZI_P7|O#G&gry!WJ5)3jBtIa^LWgs>gB1wgT zQxnOg_k4PZ*aJBd|CLV9tM3w!32@y)07<5;KH-9xtqsg&{?cQ&g@5=f0(K*Ahp`nV zJozd%bYUC8-V8kFQMG41}X5(eB`-UQ5Xme&ZL*PQ5^eY2g6LGPaxT@+=#h^ra_V&YUs_Wl8CE z59%SP=6%C zvbj&{y$=T#p{EjB@v`wANRU`acEZ8LZ{^1p<#UB!CA?J`oeH1Ry#p>fGRbZs@M5UA822tCCq2YZf;aE`DmsiBDXxLu>I1h_ir&3s?no`X9)lpw z#ixIYZMUeiFtuqfbnRL@u(_l2em>Ij*#A}a4dSzD8vGqoD@r)fN(qy;t%f~tyiivB&Hea3Ilqc1Z z^O!n-?2{pDDps)M%Ze6z5XwGcP73?(Pch-76DPDFVr3$F6^-Hvk>#@uXqkqN=fWa< zq-%W(o;4=ZZL`E+ZkWg+i|bI`yNiw(+Qi&Dl(JHHp7lU&Yh_{RSPsnNaI`iaR*Bukqni&kOd9slOqlLY@=#7OJ2M_(p!mB5o_lhk9BP4@ZghYj;a5jyLp< zwpEV!2H>bu)C1f4xPs~hcM0*i5=fGM$ZLkmpK3<7vLJ)pbofNkMVckA3vcfAS9i^l z53kG+&lE(qKUw}aLa)?;WqcR-{R-uuwV+0bIi^?M^ijhT#4fo`?DOsF8Z3nKq4bR9 zpx4l&2g?)3j(igOqr2o*`WC&sW>h#S_X)^1*BF6j)|2VIolJfxX@m z%F5eH?zC!#cn`j#S3iBeH-hb`S7p*|3BFPy%|wMP9B(7 z%;@)RxQl)sbn|-pG+ME5*)?z8eBr`tuz?i}eO}0|9TY1y))~p0Pjq|2nQxgLXP2ln z0Ksp~sBZNe?F%j{+c%VFj2KpAKa|AjCHkDookfC+bG5i@Hv1YD0uF3X|GAa84OXEE z0vMSo!5O#i&}{G+ATqy}-UclHFL8JdpsK8C!puN$&$Seh&0rDm~E|*^u=n|CHu(K&e)GGY>DV|gRn zTM=8NxgA5*^w>poEIwVLuKrU=di!N}mNzm_ zhu>^FHCRt`%7uJv9mVD9(=vO~c zV0Ducaz{NIOLlE;^n8)#;(cO5CGMBP3G`F@^vPK7g$9dX7X>n+9TZw=g;f7V%e zKDbqar=GU`GW;b<$9uT>dj9H=I$;cXEV3t(V&vqXDsrWpRra~*$wxE9Ce&WhWmuoF zKSsv!Tp~3W1;~|t6IzME{xzC=SaoF9oM)R>Xf_dJVAJP|<|-ZiB_>&V&0!DM#KfK= zImkPrbc*&$`p8tdk2eQ+gLQak)+Sp)M42#EF+GlqsMA9#$!5uER^K7QLz5M95#F`G zpb?UCDr+d0zTw3;3#ObH{)&ZHAZJuLYnNkk&ldbxx8gZ(@#uJnQ~7QGCe9niI{Fa4 zi&2Mmlbg|8ELnBUbJnz{EBV(${ws5O!CU6LhQmDFJ4??d>WVA?NB;HPfn6QDS;+7O2kH`+`@jy>=J)K0f5HfyvribEgV>E*gd|aj645v+!M% zHP-@zQ|zhuC?~$h`M53Gq$u+5Y*L8VC2x$)9EGxI*$;eF zp%fUlOaIEKBJWa4Qbk*^t670a{%*)T32-hb4<0kJh1f*w2h=%WcU&DYVxGV@UxR6r zQ7Q@zS~b38P9fUN+Iu<$j`#QwNf(Q_9RF&YLgx`aLa}*oML!gCKG4QH^wDu2W#1jT zisQre-@_3LY6mP%CEVF}g`6Jp9x9(;j6~r+Ay~V z=%2z^uW*zAIa`2p&Y0L+0YjhYZY7|P5D`3^v=;&PpiW!oGu}xz8u_JY&mYO9Wo&i` zmz4b7{2FqFb-os^g_Gp{yx>^;);-FJ1<`NBW0D8NnW#E)G(xMWrMAKxPk&F@e?szx z!+bcPSDcs!{cOOh0d0WZ01M}Hwik~J;DB}f88@y|Xin~V?%c(<;XWWTft!KOXO4Lm zOaYBY=)j7hSHF_8qytsW~eFw3*kzb*bso>930;eMJo7#-R79@+4+ zZ~MaBC&tA3Zjr~*k}PBGQ^<>dAw6#2|0(@hTcQ`gagp;miUGa){(+$LweF)G=~mEm zp@Z!!9XDKFBSp0UJlSP}N~;1ONPCq*9rXbLUjN2E+j zzibCjgXEKV1f2<*k1&r?PS|`_tdDurXI|nZ8(CEYxea}H2cmj=KXXbr1?+sM|ep1E zr*_}Ng*OBDd;*-oE_%Nx?hWej1$ENy;JKDRdJF>a4$mF>!PLW$3vgr65i$Hr;by$} zvPYuRII|qKEKDqRr}7i)`9ya1 z!{Us9pReq>cDM|D2KS`rIv>{orn673=PJ@v)3$cy<{oJC+9Ygs^>gRgv&WJqTVa#V zudU_b7_X8j4#>wEFlWgB3r2Us-QHAiS=6$s7`_!*zoI}2Cn!Sz ziGMwubHOn07^0>>rK{7YT_ z5 zaN1AF4^Le1Cq~ih@6LP=8Nd*XPw1UQZoce`3zHwrZwClSk8jckcvaw=*MMgNUo7&E zm7ReZxBTyQe)xl3!?{E8X~J7YwQtv;hWMBT@9mwRDz63Rz;ik0jz39dKn6SOx=7jX zeyluw!hl+igmDk#0+EZtZbSJfKl2^lnWH>|+9T+1ggY|l&Rm}mM^5GD9T?dn!hU_u zl9dxo0hUfGrz__(DjKUrdl~fXe2dYrRt=F%RS-SSgr{-WS=XVGh4~?#FcH%Do6U0p zZ-)SnpKC6?`v!2YyTmMd*K^~Vav+(AJhnSD70Yns`8V|oUEfv2ZQ)|6o{a3J`w_w9 zG$Mn3)gjb_cL3=x!<~$WLZqU&H$qYh2IW$&+)zA~sD)wr*f-4UVxxY>Gt0B62d(sP zCVmU$j3_R3LW8H0^h-S$P(<)ek&RG z=L``7qU6zE?pFTjfdwCFSG<~q+4fHh!KShM>NLGd&s~_VsC`86#xKtykpz#yy5fge z`%OE@-xDnBSMKI9)GT;Wt%w&PdmFR{0TE^|8=M`F+J+Ihrb77=U8Gou)D!`6T+uS_33hMv@XM8hhR82H?J z3Eod?&Cg^u9wV19f59Srg*u?a(qDmgCZ|PR{yyh5B#l}x?I_D;;4SMimki>*$~BnO z3yfy%5Gp@)Jd6B%Cwnr7w24lY{@~(5HKlPA-)4GL0jSH0xckjB26Q8T7vBx_N)<2G zLE3eW{y|>I_p}f5rL~N>hYgNM2WH<4VHz`_p;dkkEEqNR)D(shMeqTujz6aPVv*Fw zw;IuWb3XW{HG5licld2hO*U2QruN`DO-m==1nKZT8El$vLBWOgL3=SB@_DkPyp&_; zvldZ&#!PP1Dmh|rx%T$=@B8GZi7&vu=)=0Wr;N=SAhx-H9F(?O z*YkSZFCFlUB({0D9dT$6#eUmvwoI!I=>4r=`vwMG)+0}#dmewEzVB~fKX8L+F=>T0 zOgTucmr!*{CQxa#C_{mqtY4-jqT7fN_dFBB^m={gmf4POA2Z(Hdd~{k&{^N$FAd(W z+nUdKlbs|xDbmQi5@EQDTbsJfroC(v@0=cxtwS%cCu}zw16%<-3%~lxw*M5|+`F1X zb%JOIHq(XLovAt0ittnsBrb1L&2U6{=G+=aMLQyR@No$YsCN(If$sBvRV%#tLFtA+ zBYH?TL%!2^g+~hxhdSx$H3VBE!X_4+&MG<4U0h)i$|m8Jlo9ya0^wV!l4q;R)XQ~h zd6F6yQn@Fcv8LuC$5dd!6qw}!94+$(=@T3Pz2|-h^g#D8-W=c`IR(PqPJuCqkv%f( zATC69SIi>+3bWt!1<#rBR)OslIvjV>V|J5Mf0itNtKUU@#9Q-pEbh$7i2bAjq>azc zN7|+P{Z%8?Pp;~@T_3F2@Xx&Zv>SpL;t0F%Num^HvADD#aYNMHJEgG>Jr8iE-?aNfTFf9TB&%RBuDV31aN z@A|x7ub3GTIyhTI2QtGOsSfHQWDTM*Fv=ErrW?8dchS1SL$=-^7Cr8#+yL&`bj`-v zdsSInR#M{Jo=*kLvI5&DM>*$FpR4r(Q)|u3)er)O?qxL(_)@nPk(H}T^SF@v9-@PO?16Xmf%>y(KT!4H&TLqY7NKIU{p`PSLR53Qms|>O?K+p6#71Oi z(^l&_uOPlA{oj?HjnT>ayfzc2b#66L%um1$=pJ;ojb^-uFbiV8yWC5+G2djB;ynLhY(M^8H z^4kcW#V+@pH^ogh)&&i$<41zz>xjS}*rM6us`j>hTzgB}V{U)_FIv18F8pQJ%wr#zP9DwV zk^bkUcHb!*qr=CmoQ-Hw)$6a>&5<;|wa>u!#&^%3Y&q8(z?)>8SI&5X72V72Sewy| zn%3tlBhPP_SI$?6sT=0c2G2=X72KMONfh`#6`n|(D$bP-YHpZ=KcZXmYIzbpD4yr88!O>Q)v7HZo*BR|G#{tbMV$fl&h9-f=$mZ9F zXZQGudSIm)yQ%c-T=oMg7%RKD=e+Q{>S+|@$3URGi~)_+GN3v~ZK{XQ0qD(-oZLl- zCgVp`%OQQ&tP@;V^gUuFfT+}L%WFv3M@H;N7I<(#zbAbR6_Gkw-=F9eg4g--H+u3TG%|I{4(8*aX6P=jjY``dFRlq(Jh<57 z-dS9B*k?zsHJLs~y5N8ca4mx`=vppsJqkp+IEQu?kvQwxzUYQFv4%c+f<`ow+OVY; zwll06W2joZ+K*g%eBfB{u+JO`;!v)(2`_P7-1l%|Wc&3&f?MzhWFTU-x~h}`#%Axt)mg7~FS2$1hQ zo%n((5o&DE-n4{B9s{Fd{5*9-oR5 zWi3`tSYJzq;^0 zkMsYxpZf2H_TP-^=cxZ>oc_a6u`sax+fgwvv9LpNaIpQa85KR-|H!Cl7#L~)6QyGL zuPN2P=+6H@ss4d)|IwfSEv5SRx%-i1{|}||{(mWzG(6%_d^xxgg``Tj5FX_vxL>Ed z)S&th_RD*^P68{(0uovS7n81gW@h>DSbEPNHokI9pzEkb++zDDC^zWNI_k+*R!S=f zR~F_N5(RBKCBMA-&5^MLvg|p z))AwE?rlA;N^6D+cbFP3qXah8NgC%OCa zqe=wB;D=2lkjK+g7y|D_Nm|w9=LQf`8nkqr&(P#5Bh3J;vG4dHyF?m#(w&H0R1}NQ zt$kuDK5D%ylYm%#zIHw@zjsytX*$-=V!3R3u7*MYm=Pee!=LCpgEG%>?+PP<2Q<5C zb$T_HYPagA1Z)HaD2J!ha=0vFVdLdQ?1_@G2%$;k^W5@W)}sSpUNY#d1y%p8F0!Ah z7xQ`(P^6~qh~MZ+aCANRHJ4!QXxh)BqR!`n?$_mVdSRJd@h$ZSn*PwzijJn+>+8<6 zr5YYUn#I5y{Tmd(7ygC*$ZQlG1@F_bvc)}EuHzUywGc7J$ z9~V2M$c}9z)>!4h+6@Tlckf+)4prg){(bGlZzu?qcn2GFdq z*_4uQqUn3^dB>e?iOjBPK2TdhJjlDaHjYl(PLfZAglFQE^>4*C!cG)VnNYY^q-rr3 z&fS(9H1mRjldp%%FeR$JTFh*JHt|I8t{+MRs`ZV<4dA&0ZwJ8}G!03BrpV7Z+I~ zL-fM5TbeCfF#ngV7rbDHFg0*tBaEE~5PTP6Ho<~1fq10K2)r}m_zgZ+`gVsO>Zf3@ zFPoJ>IxiU4Ey-P`(jonuHC0OI-U%=K(`~Ah$?YKII$1usz#t&5d5s zmfZO~d~r^XyLTKg5(=TI#je-EvDOVqmmVSo>EnSMvt%SkAJ)54S@}ci!`Z|5DLg*N z>xv5s^DdX1A4b??lO5AVpjz#<)(tCmXg5I;`%nF}!eC)RBd9dVYGLYZ;_Wz}GvTkr zIg-W<+@t&rtq+*5vM(J9v2w0Q8Op4!Y}sNx$?mcn*I!ffVc2G&hqa2kD>j+O#_V9< zu-p6C7D)Ws!wI)9UGO_EVk71#WHg=eSGndkC@ub6Bc3ndis*&O#kk^+g%$J2^3Ck> z{@~@e7~ylwIBRwndPFRE{?;RDxQW@%yEOwcABCBjVzk6ng@M%g<0B6B0hNTyL@GJ> z?IXN*ysu2JREK5hoN=-WoGD-FHihjcfN#7!Lx5~amWQf#6|K=5v{yJ+bR9kD_lF-K zU4h-n-LjyRvX={8?rY8-=HHoL;O}~pNyX`kkxJ)^bcI`T-pQB&+XOW1`9!({?725ph_~5(snht@2Z~;3aU$a1vh`U` ze@sX34?rE_It0Fic?q`V16ES@kcDVcW$6Z8-QsLYB;F8tx97hn5A6rFNz?`x?QvdM zEnC-byswUVcX^K~u6L+je(G3!si2mmm$b<>i8%8=rk_bQ<#w@K5>2TieAwB}p}%n2 zKw1S$B<^<=`sUj^0P~3Wh&hfzvun|^g=Yw3nZuB;hAMWU2v4FlRVJ4~1QZ8G3$V>2 z*?{E?W9&jLu;rr9YMFy`%Vq~FIZ;clscdLDQDqHU?_TeokAT-=9)nmA^6>*R$8jEP zw$}o2DED0+Y?~03H*T0ODq2X^>~_m5T*;Y%iy@A6%F+^g8zDIpHW@t7Lg?$_d;iJ_ z#e6}O{K91fwsglhiAmW+ncNO%;gou#&AEKaP~Y%?1TDdzS7w~) zl6mw#m$pCO#FvDkg#CE)rTS%?#Ik+n;g#Z8BSwigQVVhqwnxjiEjMa+%lm6iP*q1& zcJSN~bbA(eA^MFBhSNfcQh-*jV;I>El0oJi{qx>1h=7*eG$aIPzWGWSmuuMcg&aCF~nZYw`K$kl;X#DR!nO zZ{2xpQsxQPtW|prSTSHdvQ!IHZ?Q?_H?S>E;}YC)BzWnVU92F-Lrn~OF9<+!Bp@R- zr)>TtaweM0t9%#uBl%;4h|3#g5Wer{{G|EZH z&MjmkH%Bfu#^4g4yaJU`OmGsP98Io3tF*o{>)UOEc^i`7_wtrta5{xeW&TZh3Pp2G zSk0MFTw397gbrE-887J}Br_=?R~oJ#cR)DVa7;obV`FV|H|n4zVV}S}1v@DrXy!DB zq>|2Gz$l}*nYuteFAlxB-osf|@$%Z_`T#{=LS&JNp3dfJVwsS!IdoJjYQI%nc;04s z#iW6~v9!`=VpbKawSJ*XUU#w9WLbEyG+HHOX^hs~wEJr%MO2e>sd;C?6(4a}F3FD7 zLrTjsVIx3E@*nZRTVqped3wj%BM!BGsX4=tZ`PI#mza@_5OB>7xoU7g12qQr+86$A{k@Pp5NkY~iEhcx!qn9=U1vG1^IXKn(5B_LF&Wcm)QjCi& zL_vuy(1}r3;wJY%U$kCxTU~laiA+8v9zG>L9}BaOgGkMyqb3}UwU`_iRazxIF7*@{ zlFR6-%vckpg<*;&@r-ED69W<_FLJ6)JS0vIyagfY#NrWCJzW0-aH4GCUc^5-eMyp=XbwIG zF>zUx#wbA1F9-Qn)yjI8QZ};*2;1mX#?m>^3O(5rVG0TNV1Y`SeZ+pYXs*6G55m0` zUa>I?9rWiG^79rt2yYKL=!<<}_1Kduv@}H2~2U5aBQ%cv`y@N5#lDTw%qGU0sSSFeas{utHLAx-|{($!e{4$yaVOGAUb_aNb zTIm_Zo#%;}O*!DbXf4AL+H?r+a8yNG;W7M*pLkLH^@|oN(Rjp@3!`|dKE~}{%+qw^TO}@!_W*u+6|Tw)UKL{O;EDX_mhqE1 zOxStnOb^`=*^cbnlCWL(TkOzvRHkkTbf5}I7FwldGHL1(@T^{xlI=O*V-jDhrtOW|`iBa4Ek6}@>h3EyW+?y!a390LW5WXiB?0Vo5BUy60&DWZ>T!6ILzjzaip@hm-RBP*9Q3Q2B#@ z5qWBuXO-V`5)=a3>>$ zKiqfeFN>CWE|KrObkhSRjIsr4$ksNn`A$g&A@TU_2^9?~vemgO+%#_A_J{`03~VV5 zKUncBZCWPl=^AQUa%%6y#@8O zUzHkNWz133a)W}+1_L|@H67^@ydH@$qnoS#?)qT`eJL~}8ru+h`QG)=jWy={q#fDn z0$NiWAuyOc3$8p7QAuJ+l!^0C%v8b7raj$mB-wccQ?#wEH4ffBfAkehvAXr-0c4Ci z9J;BVFVJ?$ShsFyZ>7_5X+K{;-x#Mh@#B;gD|-7YV|H6PlQ7bNIk63>j9IGsh(nO1 z8K^t6<`?7~(51~MF@4I@{3=Iou`#6zR9a)ojMT-49cmSo!1e;QL|y)H#fHIHRv>J^ z;5*It)Uc|e*M`V6;6I@B`Jf9L+7{$Q3m4E^JRd5-BYD(wQ37tl=W4TvA77~fH221~ zk|`{SV|**C0-VtI2~S1@bszW!e`{MLXjUcN&Ww%>tf!h>2XrTIaGxQ|lmB}Q_r~oF z9yTGiFXRF7ORyUGS*Cv^bKt-_T?}|#@-MdxF~WXLt=?tl*fPb|UZ>c`!DjU;CGVMc zxmC-NhGRC~o$g5GXP%PF8VIPlK=dzSqQZ>z{V%ua#=fh#dGbL}$3>t{%sS>1Z zp>&LJfJ1FhvZX63+#h{)g5C0{wmtpM1G7Cs2Q9#p3ZtpqKY8lpy1Emn=tEIMK(_<} zQ;W4w$l?i^^c?3jj1+&)55w=MU-jKfI`nu6EsbrfEWQ6$nmmp#z*jt1#Fn}@nYzt( z38C)Ys&yLB37L6Uh2YmKDjG2W@Xn7F`biplVsIo zoOQ|BTk}n@{Q+0^?-DsfPb$l?Su-uYkFwrda6W$@SR-?B9Xm;I_7<^Cdz;PmZ;q!O zbzr}@+-Lv22&kabYqPy-g16Ci*_=n)Z9b9`JK1Ed*!szyKe_SMFReS$trZ+zM{!J- z$^aerOfvG0LEgk+_R^7=q6{1jXc6!-TlBRw2=0$lXn905tRwDmS7R^#{zVq1)28 z(-+_()>{7u*_vTFU6U%Ao&cpv0Zg<}{x0`-uu)sN&b&>k7_ABogSLd)soHA|?8enL zmK$v=*BGjt|*BmEl$dtAPlvzYvJiEOwqF47UEp1Y;Bm&y4_`LdjS2 z`=4k!ra`T|71pa3yluznVVIYnoE6?AkDrm?ie$R(QLC(7F{=slH9Q}9-?#KY7Edk* zQ*H|rgzR-%OIXy8Ft8UTf+{+U0oud1e?kTwzT# zZP4V-j|C`U@pRBeL$*@|-Y`jmW(mR7&APv)|7-I47>=AjRoF11E}LutyeOZY1zz4#W_OFQ(t&tS+hS)jPutforj7*vfUK>;CD zXflzA?;1uQyz@{V!J<5`Ji#+9O=z!POGml$e#@J#tJ``CO9?w*k>xvnc}qNtFoaEa zN18)g>I>nf&C8IpyW=~)-;gYv*3#+0ps(`{jDb<76|t-{YjYjHlh6CDBOg?x6<#0e zHyEly5@J$BLhjPFiAX@r#Nqv49f9sG4CYUQaNAjw42hXD?mOl-?EH6FQ$pdY6u;WQ=0<|&+Ly@R_9d^hjwE)A#2y1pHJabH5`4@N1*%8Hx5 z?7QxPnY__KlV6iTY#ugu*E1VdzoW(+iX3gH0I&Qme@_W?YrfYnQc1J|X*n9Fgrrn~ z?K9h2QNXW{ z9DnK(VZjX9?q$#;=Q*zjpY9RhTYpd8i=8MvL+((qD<%8A_4(=u#78SUb(x&b19W}K->!?DOXLw9I zEOR{4xN3ABBW2EORgkQoU4XxURIV0DiUCFT`vZG}E zXM@2~Qb);?Rc%vF-n$XyTu@vUK1yz`i%)%3DxRMv<;F|DV+`<}D3est3wL5wTS(9En~3z^V^*MI$DDw~K#eVc0jb$Lvk^xl*5<0BqM zuL!M;ZQrgpeP|vGs@1io@&yf1si^Ifck9)-4*uL~i%rlRJt zEH;;qxFnddf*8lEE>` zc^7#A|4p$WiJc=p&3hYOh_!SnbFtK&^(y7qTXbtuO)+SpG2k!UlWrkz+YqqSPusge znWmn&KfOT1`Uq-wg{V;c&lkjqQ)zys3IbB}3-tVWI{h9MG2rhH1lqbxb>JgCSvHexqLPx%Dl7CZH#hzK(zkdrj(yqeQ33eu5g`brnb3RY zh{}{TktVIkssd#;waAS1O{Bym%3PPP?%Ou-ZCuAoC)~;Tdl?uMLk+U&nIjRbWDE-1 zqqYKBL_n^HY&UH$?fh@wy)AC^CUIlL$#8jen`#oJnbVOQE5}Uip>A>K!B&am0%-y6 z2rnb_yV6ETs=F=;2Wf=x!-1@>w@GXmmzA-h&bQDuht?p0){x5{#Nx_yo%tOA;7Q22 z+8_Ii&iBnR6Pt}^pB%Q_dY=aci@Ve75OvB20X z<-GynjJz+#_k9Xcx0(z`o@!9?L%=pt<(QY+g;~uU{er z^3LjJ4v!6^piM=gpdE<>4943LV<%gb52mM|#hJCNl0bw55Y#RQiKv8u7;%WiK<|1zx=`Jk{G0|d3J!M_=hh>FPicv*WLz%fS z9aB{!TDl$j8N**az&*e0KR)S3Ifj@T$QhHmB$3;n zd5<8x#pScsvwh-Rx%!Tz2B2O}-1efaSSU6xZhI1DTTmEMr~)|d76cCSn5w!^aU6q$ z#W_-g5lq9a(soK8iJ>|(Ff68Josqy#tHwmi*3PM)`8cRpT*gh#^NBMk;U~*}vMjRZ zsv414EbuOnBeIOaUWT7>#3aRJ;Iw{VYNag)`6yD|$6MJ9lUA^tfH_6`iK_~vl3$>+ z_wHj@z^78YU~t|1VcofEpy_d)0D@tk7Mj4^JLA`WE>N2jj6|{@x09-J4>B$!vB5Bw zP{*X1xan7W)fo}JBFG>;EWKscHX7)xHMsq=g z@i@tuQ%#JKePnZmjT)(Yi2A;9_$p4!X9U>OAH{uG}}O z8;H!CVdlA^cGot}P1gw2V5`|Luq{q!TT+u$C&S9${A-tRhtd+O!&w^nLSt)QCgyNi z?W#Eyg}xdch59kt?G6Wn{XKzNlKYYyuVwH#HN6_@AxDQ?umA;eP$!?_9(ljoPoi;loy9@*X*p5aRqZ0&8FmXM`dz5 zUTd47b}Ge=c0m1exUiK+zMt1C(GJzxhAPy{%aeYXahpybVjNSc*;wojj4IbAXX(mL z_4rV^r2Y>*x-5^)h`cWyRaMm%7Sy-ptmW@XjPGh|m3^Ae?QA0alkLqc-o9Z4L6{vv zL*yn_vTGC_*(-bwGq>0;jYqunXPE!i+E<4~-L!2ZEg&hK(#XNX0Gd+nOzRfIXBvp zUucMA^siDsrrw}Viq~456mqd<6t;|VNtJ#N>~7p|TgcNiDZdv?!6~my{t9Dxz;DY? zNI%A5(#!=jC68jvBFVGiH1ag}G*BmdizDNpW)S;^`&LcO!9jJgkqSukgPE)RxCJe4 zwYJKXMKJ0#!ye@SaF`?6LU~lq6f?UaS)TRSvWHvkTVPXHk;xq@t?_Fa(+kD0S2R`! zG*()^%Z6M|gNsA2aOpKn=57`iiA3SJ4ziX};gLg?)(+N?*4k2tdn_t%X*Cyn--ne9 z_4rY|&RiASc{GdqtmVT|g(XD(bN_y|{dw%Q@e{8N?9weuY9yDz@pm7llRg>wh>~*C zDFozC#OrR)ZYS~d)TuY1az$F(;MRbrb)IKrMx{<+5PUva@)cOhg9dsQuh_tx%C|=EXSi z>8fB$zXS^}ApVDJQ3A_omR!sono+(l7lU!kbW63(j;=N9o%UI=rb`)*^2$|WI)2pb zo=O%f9Y`LnGbW|vn#&N!`Rr|BrI0YscwHFV_pgLl8aS@)PUr1|cpyVuu3ar1H-oI^ zr-Nq39gakU#yl8y?df*~vCWsx#7UJe2JC1bb_N!Y2ruv)r~Syohv8UwtTq*Y3|WeE zs6Wd8k}|LIqcA&VkBRqF!+!8b#q z3&V%o0qnrqh$FU))sZXnS&s9KZhyF3WZwDCX|MiT1hL%n_U`mPtzvxCrxF=jk!G?| z8p_f-snA1KOTy3dwkuPf4oTt(g-NDO+Xy^%Q3H*B)i{c;!%oW&Y^E(g=bTIt1Y)Fb*E}d#qKBGxE zJDBtCqJlvb!u0PY4h!kc6j${3g!}hW7 zmDL?g6m_!a`lZv?M6~Gzh?dpa<=P7B?L)K|0pY$I-MgfQBE2S1C(k)#`dIG6GIjgm zqv&M))JKYn&$_&WQ$HG)5dr)5$#(Bt@Lvc^t{zoAQX*_4V07{?j8@Sjp|I;AP{@2= z`>-W%Z@+9l8rfayT;LgvpyeEt$dq(W8J(TQ3+?z$v#%>3YhJ95H|?~%Vu@Y%Lpmti z_1G#UmZDT%&m|nA)r$?&tR~RU4s4Nju!T`G<&q`0(mt55)4ovYXMBy69{HNDkD)+G zN|-NYVUfteM^gzovMQGH3sWz*UOBhQWx-*1CjAX4-Fd|<=DUVw1>cN|KvAj4lxyo9 zqQ~Q}zfmzHw!8@zC{<<^%vXNfq?*yvF5O)s_ZiS}+pH;)gG%#g^ITnHVz=C_R*>si z8Q0`nr&{%x`i*803$n-gdwb0uNrWa_r@i*^)3#q#w4GORO5=BR-JpHx2Zsg4MI$0g zy)vw%6{hEoM8tQ_CddYp-KE3Zwutp5U3Y%0;K`Pc zUa-F|&H_I$@X;T_F*jE|@IQ|JYCGyd;;9QfETn}e;%DrV#eDvj6|v#=&2YG(Kr%;D z-~7|pk6mXqCzLHeaVziL1NZuGFYN}(^z6~uMdH8hH?G9jNXgx$A$-=wcD+E7irB^^ z(079S8PS5BmyieREh=go7uEDLf+c)}YX5HPIf8c|L*fUIF}?WV4WZ??^Y5H)WqE~U zHwZbace1ag$|g<&+`T;mnhFSgXDo@NR$fZime_G&(b-deu7B56fcV+ov@Yd#0Wo(h ztaobL*L)em*<=^}tIA|iO*giW#1t16#N&3s{5eI9BS}mnL?ON8P*JCy;G&-nC}I$b zl67B^lF%{9N}v7y4o79-tIpHcIM8_OFu63SRhJ$IofoxPG5MZ(ypSK@diCA;5`LV$ z;2~B;C!*a0K{x)nBi)J*iAE1Yge@c4F%n|FOFw<#ul|MU3+W9}6G8aVD@2i3%>B}8 zC2iqZx3jjMdEZ*)H3ffK-F0MuSxTB_0jui_9Y%^y?*oafmxo9?2|VIQl3XG(Rr{9X zqM&6y(i54^;%$rLq|HVci~aP@M1JdVufl*o;mkx)$vnL|ed$JK`v_m2p>cbf8kKm8 zf`y7IEs4pdn|o&fX;NJ7m`c^8>li{oh?YIeEV?&ZwmD5Vba+B;LMS^yoBB1OjA-c~ zv`&DG#nTViY>XLW#0zrFAw+V<7~R+?tmS@cD=1H=Z}3fcbZ@C; zy{Pk+N7G#C`#5seaU|;&TN|mb8MSPke#IpIS~*^-#I2lF6VEh}n-tHw-Uc?Qn3|7x zepBJIoW4ipm$pWp6Brgd89!b%F;luzwc4o?n}i<)LJ6soi99c>zYou2&?NS{fs`=N zsFG8s(|2z1gJf^z?q(O?vV8e{H650oCSIMq94AC~yN=;>Fw@{`EeF^`bHk0Ax5EHP zRmAp{Ow}_;mDJJ=a|l7Pn96;Bn<)3>^5kU#x)30`#OpU1ZTxVJp zOrXk@(i9yPbrZRm6I)P1RO(tsGrdiX9~GJUIQdYD@B~x-Q$c*OOXzZkh{ZOjRYShu zedU~LS)$=wO|MJRYMH%nT6AW(8udDu*xUOWgL=#ZuNH-QlcVgLhs9SqC}{ zxqClXI&5cu*846T^-)SVDRjf!e&KnS%$TeblkGlxw~bh^zf~m{SyuUKNDYCkB@4p z=b8pwr?Px1NOyiB^Xu@ClJB|R;o@!CpZ%%uO~C=rijNNMnYR*p=)!weag`oxkbFPn ztvgQ@-m1cR=1DE4-Wj`t`akxWVNkK#IjgIPcPgSDCvat-nN0?~ugZJqqs+{ZpS?FY zBY0cD?%feP6bE^YzVfS%rB+@*wAn`5zKux1#Bok@H#~%99Nj|?!G)T&C_;;?7dXooO0LImJ*gd#$4$_ zmL-13!=N<{C$)5|CjC=4C7zM&!*_=~gjyT)4WlNX*5nzQLL{A#!$3H5GXEr5QgR44mo+Mt&VlD1G-q%v1MMHRM7@hVG}%n^Mqa53m_zUV=7p%$z<9@G2M%>4&WO$CDE5=`S*j^h@BUA)W5w-&H?-nEJh zr7Bh;_Bh~-*AC6y^_=vU1s8bLK9Mr-Pw<5_BcED7f3D3fDak-U^}_$KTaoAHO_|I$ zlwT9hJsU0XRD&s@eAfyM&4+-a9jg?k211X)=0*468jr|Ai?8!LwT(|{cSKg19_8Fq9rZXfh-vZAL#(lZI&Zd-{Sup_Z2j`9 z_=$#@ki26i*eb=2Ge`y4PhqVo7x3s{Df}$UIy=#0xK8kyhyUfs6Uu4!ho(qLi{VLp_-_JN!8{fSpDY`mq($Hlh5KC-G zCcYV9iqEslW5>m@O>4{YaO~cU|Kc`c#5O2l&KoXeyDjJ?y}2ZyO6crBS(`96k5$r4 zq;;d=g@!wgh%xYRjM#3|o=MU8+CED~Gm{pHnzS#zl7H;hak($W|!)+mC$ zv;)rpODSm8hO49k&N;EoeA4YkmcD$?+Y>QfHtjDL8CVvYclHkB$ zCy|@4;}2R~;`8d6%p?RRz5Y>2_Y4?H#WFUxwO@UF=)-x=?w@5V{c)9b8d8#|f(06z zzxf47An(Y3m;t4!VEr!q8FM))U+kFz!)j ztO@g-Hs7IXW4m_5nGt}}x)Y=Hff3}>t)C5yb-^S|zHUb9r_LrV6|~&7#u!@o_gM;| zEx5@&tuZTK^r$S1=49*}bw+ef&K{kcg&BHzDy|{)gMdIj#(XG+PwW_t+=z) zrli9p_2k;{4}#Xk@5te^jRdSNY4>xY0oK5Kq*a-<_1hN=?&}xC!z&k9HK@1nrd0i( zeeL;uf5Ckn>3n&v8~x(*1rR6wB*7q~=GrMIswp4~$2>N;)_G1SH8+c~gw1V8N+?Mj z8Sz7XTi5q3i`2f2uW)L?uF&R%_&MP(oC|-SriMAgZJ}f8GfBLfxJHz}hVn<#_`}uc-{0Q(t#O|%eZpgE5Mk}Z=p_n zSlq&7nTZ1^R>WRK6l=TQ6fG4H^bEh$^RMqyTp9l?`=(t1txq^T)!fUvW7TpF+_eDF zN6?)I)on=vO?Lv)ZDb5<$%Cx=+Cephb$nPq=|yVR;rl8aQ{Bof4)x^ys?EWQH9C3v zh3^u0*3A_^7$}Td4)OETljFt?G~c!-fKeXtUb7d5sRVO5_SL`$9VmdG7YJ+iV%;%e za>1WFoM7#XrD-=79rZ$@B}w*_X(HOhLOL7-rj`A6UoIzRyl|=US=REPSQrR|LvBTB zb$JFB;>*WIYtt0T!2=t41g?(;-e;4zp@(&NcaG*dQURlbV>_?oeRx4j@-VKWZ|ZZN3wzjbA{< zBsUiP=EbR!as{~O>FSY@gLEO}= z-7k*wv1&0eWe2;0&hdjt!&w0St8BpCD4LUF|C2FEL+fmf3GaYNxw!|gb{)^kCv#(G zt_7Ce$}0JS$U+7=^#hs>Jj<2JJAX%a=?dE4g>reG*KFF1}JWY zdBb;wJLBVpxl~&3RygJ=uc>f^D7 z-ASy#o3l>uh3Km*OC<{R#cKEZp$-P>KZ>fqYRgxE&tu-O(G%Bxb|k5vGEQ9L{6Q~S z38@vR7SQe@U!SVlxr;c=xHufp5kb~klQ8zbtr`(ORneIgdlC0dG-aZ{0_%ED%As#B zYc}IuB;(!HioKzEq<)}mlI!#AvxWiqr8++MSHvNB+JLk+jT|euo1rdTyxQ7bC%OJFnN{jDf_5? zWnT|TPk>;+6ME1uDP z2ka>}N+zMg39JX)@j5iqBXAJK(SracoSGJ{>M&P=o^Lm;!@IWVy`OooG~mfp2v`$^ zsU(wXsVm4RU=`dJFjcoWoCTJvZ_%5UJrO$bu2O6?v9SWzq)g!v_zw;*6s3y!zfy=mIEw!Jf0aUn zpyVL`RSFS)$r=4W_`8=fk(a>&frT$adHE~+QWo+z282WZMt^G|{zg&s;s4Y`DN+8Z z2^5B+)EECkFR8wNYJ&d8{?hydqG%g`_xV@zO9j$DnexEc(%hLq=$^Hi^CeFk)sgBS z5m40Qa#*SaD5c2Xk3S{QpAt&q^AZIADS`i#P*m?r5c)^N@wY^$D#35LOw~)jqGEv( zl>~zRAq?s6WNtwKU_r@hqO>Ugd1_OXs#sUxq3k#!TU~~)$yxJBBfkF{i+k#-QtMdS$ z)K1aHjM6(r#}H`o1w!C3G#`Lb(y&+Uf?)`B3=Txc5O6f#Ljka>b3>&Xx(x^%-3A1K zZUYMV7aPJbG@n9Y2sHme;lO{vKxh~Y0JxfeKqwe3PXVZKpxK4Np#Orw(J|CEc*V~^ zC=@-ua5&;>Jpc;&7Yu}kAyBfjXg1)mtGNLL2&3ga3PblZ9F@^m`vZUgXfX$X(QUv0 zFtmE8?GEd&TbiyP{03^bpjmgUuY5C9b21{{R8H$i~t z7!VEvU(F#X7~OxU;i0W9C>Q~`>QhuLz}2+?2LObx&KC*+qOBuT`a!SeIO-GwU&Y`6 zFyv~CP#BsIP-h<6`aogASLchu(AGH$`{($cIvJxhnVo)Xj;mRFnxllYQR3rIo;*d} k&vJQK3;k9k|8sEvzAMDo>FMuN84kGAg680my)Q@bKLL Date: Thu, 17 Oct 2019 17:04:09 -0700 Subject: [PATCH 0219/1772] Post the minutes for the 10-15 in-person meeting. (#121) --- .../filesystem/meetings/2019/WASI-10-15.md | 90 +++++++++++++++++- .../2019/What HTTP Needs from WebAssembly.pdf | Bin 0 -> 82687 bytes 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 proposals/filesystem/meetings/2019/What HTTP Needs from WebAssembly.pdf diff --git a/proposals/filesystem/meetings/2019/WASI-10-15.md b/proposals/filesystem/meetings/2019/WASI-10-15.md index e914a2484..96df21e3f 100644 --- a/proposals/filesystem/meetings/2019/WASI-10-15.md +++ b/proposals/filesystem/meetings/2019/WASI-10-15.md @@ -25,4 +25,92 @@ HTTP (servers and clients). ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Syrus Akbary +John Plevyak +Pitor Sikora +Alon Zakai +Mark Nottingham +Leif Hedstrom +Jorge Lopez Silva +Pat Hickey +Johnnie Birch +Roberto Peon + +Meeting Notes: + +Presentation: [Proxy-WASM: a “standard” WebAssembly interface for the data plane, Piotr Sikora, John Plevyak](https://docs.google.com/presentation/d/1QMGEuVD9p5iNbzxzgT4p2PXpxg1MjfSbpbJdw6g6Q_Y/edit?usp=sharing) +Resources: +[WebAssembly in Envoy](https://docs.google.com/document/d/1HLV35OZP0A_a8dVjDo4kwTsovDkaycS83ZLKFpG9W8Q/edit) + +Described the envoy use case and then reviewed an API (logs, network, http, etc) + +Dan: Is there a main function? +Piotr: No, there is no main. The module functions are the entry points + +Dan: How is `__post_instantiate` used? +Piotr: It’s an initialization function which is called at Vm startup, which may live across multiple requests. + +Dan: Does `proxy_set_effective_context` imply persistent state? +Piotr: That’s an ABI design question, it could work that way or by passing in the context to each call. + +Roberto: Is there an api for caching +Piotr: Not at the moment. Not supported by envoy. +Roberto: What about streaming? What if the data you’re receiving is not in order? +Pat: We have a different proposal that addresses this. +Piotr: We don’t have an answer for this yet. + +Syrus: Have you thought about using this proxy api on the client-side (browser, [via extensions](https://developer.chrome.com/extensions/webRequest)) as well? +Piotr: Our use case is not focused on that + +Roberto: Are you thinking about having a Session abstraction in addition to Connection? +John: We don’t have it yet, but we may add it in the future + +Jorge: Version management? + limitations of current toolchains mean that the abi version is encoded as numbers in a function symbol name. But this can change as tools and standardization progress. +Pat: optional imports may alleviate some of the versioning problems too + + +Presentation: [“What HTTP Needs from WebAssembly”](https://github.com/WebAssembly/WASI/blob/master/meetings/2019/What%20HTTP%20Needs%20from%20WebAssembly.pdf), Mark Nottingham + +Roberto: What about multiple headers with one name? +Mark: [paraphrase] we probably need to talk about that + +Dan: Does this include DNS? +Mark: Yes, the API accepts names, and they are translated implicitly + +Discussion of optional imports, which will be important as different use cases will need different parts of these APIs. +Spec: https://github.com/WebAssembly/WASI/blob/master/design/optional-imports.md + +(general presentation of the people in the meeting) + +Dan: Could you use this for general-purpose HTTP programming? +Mark: Yes, there are some features which are proxy-specific, but this could be used for clients and servers + + +Presentation: [WASI HTTP proposal](https://github.com/pchickey/wasi_http_strawman), Pat Hickey + +John: This concept of futures doesn’t allow you to chain futures, right? +Pat: Yes, this is a difference from JS futures + +Pat: This is a low-level API; most customers would be using higher-level libraries on top of this + +John: This API allows you to decide what you want to poll for + +Pat: The `future_close` function allows you to release resources + +Roberto: How much would this API change if you had threads? +Pat: Our goal is mostly to have threads in the background, so that users don’t need to worry about them. But some users may want more threads in the future. We don’t have all the answers here yet. + +Alon: The `request_new` function takes a string url; how does this relate to `path_open` which doesn’t support absolute paths? +Dan: That’s a good point; one possibility is to change this API to make URL access more capability-oriented +John: That enables nested sandboxing +Alon: This model entails some overhead. If every WASI API uses OCAP, it could add up + +Action items: +Dan to post a skeleton Reactor design document +Dan to finish WASI modularization API +Pat to make a Futures proposal +John, Piotr, Mark. Pat to flesh out their API proposals offline and figure out next steps diff --git a/proposals/filesystem/meetings/2019/What HTTP Needs from WebAssembly.pdf b/proposals/filesystem/meetings/2019/What HTTP Needs from WebAssembly.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7aa294ee64e815455dd95821e1aca68f98bd9fcd GIT binary patch literal 82687 zcmdqJbyQtTw)RcX;10pv-QAtw?(Xg`!Civ8yF0;yTkzoS5Q4jZz&Yu@N5&of-R^(h z9vLH>wRi2gX6;q;sb9$~A{jwpDmrRL2qN5#&9Ny6MhIF6YdtdvPEH6K1y>tG2pR!h z2VDzmV+a~4T}wmzw-3a1opj~(?M!VPAQ)cC%Rz8+L(s_R8XHRJ>KR)6Rz}Lv(jG$n z<Q=wM-L^{4)ly05BwbHTQdQ=KoRrH}_xNdUeju(CYQ}uhwZK4Gm0n`K?{v z{G)|np{Iplq-A>Xi$=iO%HgG;Jp{{dCFKn5tsU+3U%X`f?F~LFE9;k!>1cnu6tS~* zwE0y<1v_0Udz;rg>ASv|dabmflc~O;oCyD`i~scU)%dSU37c9t7}`P52wUhn7z!Hd zTN}K%D`9A5>|g@H_I8t(@7X)NRNWH7C9PaR(*8Rw)U<>(xri5FkS4draDrtr22_9- zrb+TRHYpfr!LsgT7s}H!u5oG~**;Q31ab9)-YuD%U4m$zUNtI3kmdO40UPxMx;dE$ zctQ&@%WiWK)b5_X=!DbyA+0SlA+=N(3-NZ-SN&F*7$U1SGjHm470&y7s4aTLe1|Z1 z*9MerKGOEh69_U-7;GR*FHEC$^9J z%_28t#!YaHK`xasto&^_|7HQwC=DFUw0b=@x}k zO$DnymM%HpMSfrvJ!4Br9gU52ro@S7I4J1MH%>Yj)p z*%UityapoOZ4;e2FTIR%dte+qg4GY$d~X3ZuDTo30(gId{^0%SfY{CU!?+}ur!IPC zD(aym+DncH6-q=8{ovX~bJ~g|*F@!>z1MWeJE43I$KwN6*=r;I{Yn4coL?KjYeQjV zVf)p>-&)@5d+IOk_4i_Qe~sGzW3#7wjklKw`DeSQdkv|VcYZbe-{au_*6`oV|0^w@ z?zi~+pH06_WzlMp`NPf{M+NT!fV*E#aHG`vtxZ#Bb^3P|^RdV&#+DDvb)9QY9~+0c z`d0Ehzj{6p^@5RU?uggugyfNWZ9PANJ+-dWBXVl4?tl7 znIPj@u{$ht_T|GHUMkmk^B=~@A2*)kM~$qP)Eo8N83Y&bg$4cZR^^k9bE|&hwzD0 zSE;E7Wv`x$Dm3@OK8sE_iQ0D@{g=_MS5Q<8PMxDNKdL{?&}B#$^(UoY-#)N-(XYDm zqd-oH^IMx0D#ASD@VCHv_Jw?C+^0xo-izgPHE+CGG`WKU%tufS?^~SoO@kHwD6d{3 zE`tWuK*5PdPvL+>-O1~Z;d{T4Dd!M@tD0G92)Tv)eTU2)n8~FFCJPDZ!JE+0wYQ?8 z=q!zK7caGn?BJ3uKG{oq1OoVx`udEfV4q}rBgWwDM9LRbbuZ-$&RG&SwD zM+DC)nV=J4pb{(;0;v6$=S&kCIjM5ga$VMCIzIXbxlJ}0`QH@JuG6y}5A*TM)- zOOy*GQ)F|*x*~@)5gw4SWf&mDc430n3){(Al!}mQBUzV>(x43>lp|hr@R~k=`-$%~ zWUYC_^k1`D!Y$B}L}{X)VJZ{&Fc&LUbC^-6e2dAa}1iq>QlM;91Ls0oy~>nT6E3bOCE zKSd3}lei*D+D=K9Au-6~>G!>tVOcuM)mP5TmRAIVL4zmjIq8S#0dtSlUFXyO07(~5 zjV)rm!{wR9XC5k##E0oFT>{!HgX4=C1|n%ku?$mJ3=Wu(Y4F(G2^z_3vvt>^(+LmpA2z~{KCv0$K$ln4be~hAf)!KP#c!ps=S5<@rT%GYIF<&bW92bx`(X8xj>T19 z-UaXJ@4FFSQ0>uiuPdpHa4*;UmUwD15grQT$`rLcSC>kN zMEgj)28F4gB)4sx2$>-ir{%1OvwAj^K>K&19^|98ngVXrfg8dS<2!Otf_OX8(BsAf z`M1>`WX8K^4h@&zed)%HXw%O**b{0qO)tE4kLlblWOtXo>ywr2ParYVfyd*U=R9YN z>DLd<7s^=WCqW#CA5+$Y*J1lv+8IM2*A25HKwarXe7Sz2EIt4s%iC5%$2H)}3Fb#uOeZ}BtRG7;eQWIMT3VEEby>vVQ)EX{~@;THiat64QBpIYX0oW zS4gTCGOmBa+R7PZ5UsIaG@k3K=BGh6_fP#<;xEc>6heJfU_uSNf`FcgMFv&P-i-y% zY$k18omkrG*Sya1XMY@x=Ahn(-ksi$oO0aX6%O;wkqXh#g}(wS9bS#=}wY!fJ- zz>M;l&B&SVld064D3}dP;?E2%oAk10AhQpr8{JR4JK^#xE!5;rgYLBVn{5F^88!+o zFvn}XgD^Jm-mw%OU>DSElBV8iR(i5Or)k&WliJk!5KE1FRPX-=Mqz)k`oSD9P6Tfcttgwu3t_Z!D*vilfvJL>6*0fN2l zE3j{{Z4x*>=zqZSab(Gcl<25KcU$u-g(O?Nny}8ygk8>v1u6+$VmUZnqHE(zyL99Hn+)`OySjup7B6hS(QYVUa<(74Ue(D;2v5ykSAU?5EO>bX^L%{O zPc77^>rDnwS?=y)S0w&WJWFQ};mO`r9F5&VctKp82$l$G*p1k7zgs^YVsh)Ue(E3o z9(4(O$n^gfA-|dbm&EmN z2w7>-YKj+5vuCmWWB~S)AfLrGy}LVbez83HL|AGaBPXtmdUjoO7eQtxn7va(HDX~7 zaHDE32lm)q_}I76(KHG?S9BT*pS<3O)0nX)B)O73-}pGHgk#;ff{#{dmr^_1wL8Ke z56Hk7+8tsmP(8XT0qA#AD~+^ixJA95px=v&$PL|N^c#B+qXy2S>u(2CxK~| zGByF|Z~I9|0Cb^aIeug^S0HQ)S5>SuXY~GxkOt1w5fL|7ZaryHcakD%YX=9gi=KK1 zi>jSiMN@gZb22>bJQ9IQ{K!Z%hLW4~fQ!)C^8t&dlr}!|hT+P;t(R5jcuwF7>6|%L z3Xh#xSENh_sG;9!o_leAZQHnAvEtC@lrV03q2emn>rq>!S+aFt@B`|mVyW7x9G|;6 zD&UOVqexF&0>1EB!wUT<7=5UcxF#smy5aCvF>V>7Y%{Q5+YJ6u=U7U!R&-fqyWzVn zB-fm1D3F>>JcLbv*>@bBt*K1vKa(PuV-gV(2VKw2R+Z;HVG5fJ^bha!=lnL)s*82fv`x%K(@vnHVw_UQ3WZ zeiJ2uO~rRAd&^mtz;0OB&HVTAFCc5<3E8vCMk?Mzkh4d}4?15i z^}=P7FB{zWwzs^q4)D6rNc1$2D;TN3N&L=cDo7g*?!fl*UWUG)80o!{=ba{|RxxZZ#L<3~CdWl2Pol)Q$ylcF2@m zG3auA&$#`>LvnM3XVPKz6~U=;AxM&*p()Hu&EJRS?a$D^NlT(PV5@;K@+D&K0?stk zfCX??plMb&^-m5}1nuRT)cg2u7JbQ>{H%oSKm`%~j)TBdD&)ZToWLz|fX5Y!-v_@Z za>l9=rsb;ymj^hT#WC4j-=>?P9G$$>U8v=BC?eT9-}r_SG{%;r>3v86gGDt*uD&2} z#NPSwxaxO6Dk3&xB(U4EN8dfkAmuQl0aF8b#0azzu>{2Ed1LF{S_fleb=dqb#xbA7 z0-an-rpNpukvYd7l_*f`&<^V$rav(mFsKE=2?WByj+T77l&zrvl&t}H?^^N}%zx4nhW{8fF#LrY82(5N4F482yqW)(wB&E7 zL2>v+OOTjS(piFuyvK2E9=)o7Bqzs(&0?ft&eU*aFkYFV@C5beEq5eW^5~YVY*(-f zqV{UjRrMH`eOsQdE&5{Z>|@XRaXyLGJ|s`N{&^7ETMw>I?rCz13W2Ah7H3M%JpptUYd}asVCSzDO_v;v*H>u3 zTaX94D&NXMuxkK%&&K9s9rFNDEnoL;AHR7uyVrPu>S`scJ_aqnX}N90?3O3mCDXxd zSU^SEc-t&b-eo^rb=bK35*8derWUS_VH(vieO7!geTLajPQP06%-=Y$6yOZNPr90K z$qxtFu^bmoIl~akzm)?wYJe^yNJbcT=mS5442S|^Jp!^kuYl(s(T@Q{AWg#$>9|*z zpJhFlky2x4T|iH^^J^wkM1nCsYnxt`=1ppaa(6$w1jMf&CK()N&ZdlIPk-_1-zr9hD1+TRRup-#Ycl~6%@BzuxNDs&j9 zAx@$^YUVa|d#wl_MvG;Ug$`;Zv3XT0&L8indD!Zbr@H__HA9ope{XhRMXQ@ET<_$> zveh<)vS_U?RnYo3k@>5aXJ+_EFaH)Ae~!%mSTE1`mtLOnkG(wOztzjXng3TJlku;; ze7T~e^-C{bU)R`VvkR4@-ZQg`v&3tPkP^&%*uY1G30D*$qb9npeM;hbWmKEWh)hJ7 zJGXf{$KW-#nI22ZD&(q2mV$AiZDk_Wx~2hq06jaX?+H~nw;Wy5_cCf5OYzz2+b{ZN zVhOiM7O{`Qx8rbPbftfnJas882uE*%m*&pf*0Msr6<2X(3Y^@CABsc=-heEp4r{#5 z86}GAFH1j=U^DOyBG<(CW2H1$*qczwiRt{nc39@dnDgXR=V-ewL z8w<;!WA!N}Pa}InTF$k8Nbj4#L02i9Z+=Zq@q;*yY1E?;n)@iHJzGf9HTJL_J+bN7 z9Nku&W|whhdMyk_HEfkbR%2UpG-ir^8Cx4Ap7~m%Ti^3>$SY?!YEfjf zm|erip{H6lgS`Kwr`h%nB|QC8ad>(*mymm!aAL^uY0Q*>4Ns2-?A-xpjY2igAmZr+ zo782@IT;Ex%0)+i4Xg9#pU2}))gy4V(^tkPp;x*!k#n;4vQBn3g_?MrRT?~xXI(#` zw5^Xf4-(?(lh?`w(%NGo%;^U|tEafe$YATx`#Qvw7}pgQz9&#JqP@Ut^S^wIDaEW+ zD5%x}qab4S^@>sYj>-7sspPxB$|4ma2vdV)57!BgU$!2lFj|V_Jme3uG)dNmw*iy! zKED;VU53=rJWs@K|Gt|`>!87Q<^xgUcRLy@~dY7aQxoST}DDJInw7e3Wkt@iA@Ug~8ieCb9jm7B7fIv+QQ(&a~4 zQ9Iqb9nq`j`mzQ?(ZJ+zC~<{ zQ0r4G!WIaZw-l_+he@brVk&h*uR^ZEyal;?^k#bdm#kX@Z)Tzb8>$j(}bxw z&z!CwBbILyxi^mqc31k!ktgVcGbd)CpGb^R_gejcB+ta*i&v@*Z&35HM7Wkd{W zaoh2(PFV=D)W)yQu=YchnW(Qe@np>>etE#5bVIeO-^OEXqEcY83P>DH0&QZN=Bc6} zG{!SA4n3(EH79Z?t+U`Ou2#XA2H+KBHf;|m?>Vs5djfv2@_F>s2#TJ~TJ(2H$q+i8 z>-2%Xzqo%t}<7tI{w1Xdeqo0-QHxLu}&4xgW5?NFn9!0SWbMSb|iA!gL##~~m; zRGNr^|FarYD9k#g6H)r)a8h~~ZaB2Ek2<-Yk_7dz;b1;5 zxer22#htAylLF=ncO*taW0-iyi};I?L%QmQZ0f0+qJ)j4ZVC@&2NW`gF~cO2izbmE zZ7)J}hS#TvZzm&&e^jtB2NpQ2pfF}4iZO%pZ7HHGY$P|Il3kRYX%YK@yhs1;@xf-= z7MZMZ1$3_OB>mJp)dy~4!4Xj0&<~(Dtw~mCNUVOLg6VtYeAJsLOok(6T^p7HNJYW)87z%*V}jz?^r^;)eA_ocDD0x z#OD_)urf3LLwx>bVTJKO#tKY-VFji?vI5h;#R_lc{}u6J`YS86sjONrGQ;hxu~_j= z04`276zUWuN)ic$#$mItHeh1dr`?LAIKg&@GJjaI+P^CNX+6K%cpRBP^pQEmtwulv zUz#wg^|)n|?pjVnT<(@zp-lYb>9D*tkz7vPm|8M!8~c)(ed3^;k@{5X^h9w!SaE|& zQK@DoYd2kE$XUjYCiAiC?)*rZX!QXEntilvX63lJ-P=BTh~xH7olU5z(&T&DXUKx- zYDY45^Gxy@U z>Vvw35=(|uu3)kRn;ejG*@vT8Z-}Y-9I{hg8g=ntK?vaF&_tS+Np+)sf|DIHDnZA0 zITw6IY{B(VIhhk*P*8PLA~PUG-J-W#u4P-+@qp^6`LF2;e&~NqFchQ5NBbySxhgxk!Gp(Me#mCw0R3ybS54yX16OhiMl-C(^7*Sask=+p3UB;w%HGq zr(QnB@a%gSVj`RyD0BYR`Uz1zyBpvc+I8UxA1#0@rzI({!OJPR-l;hfy`!qNZDKf$ z2-cBajE+x&X4Q%EnRPhS`Y2qj%m(a>Lp4F6Ge-f`c9T-=9zLV*Wcy`@>1#m<_z&+{ ztNCv57}VHCDC$Li49!|r>j=OeWRZlbCGtz*8|L*pr@1d{5!b!a82TFgD}HGWE1gmU zP%QY?$g+hRTWMntk>!{nc?J&!81Og@nf|Khthv5swa)uV+OsZ}`8nF_ic=V+58dtG#n{v+** zqYf*KWC!V1RA3m)1%bXh?Y4?7iDFjF@4)yo8cP2aTp8(xHyQ+v4Rc+(tPwH&XcAU| z<+@dH+I6EIZm3q)xC_Dk-V`@SERbAgS=2eX7Xj%WU z`RGmG{={}nuSE7swf?O=cTB&N+&?!TG5tnazcwE+y(;<3UZnrqy7im+UylB7+wNXi z_VqS@ShrSMmP4fb5HZ#AHJttoPQh^Sc`RSb2QX4iLoMEIeGgz0sctX#hLSUL_hZYl zWlOjUYU=*ZVk`~YynW0_WYag`!Wu5{@Twvn?K3*mWH|a}od7YkuxrtrA2H^}ZHUG9 zMXj=3ZUUXbG)v=`zOXmQqJ18_w|n=!B%Nd4pMINfO*pypAR2=7y7Ir4=|dJy{vh93 zC5MI@P3Z}j2Tb}h->R4;3y!ufBq1|VDQILMSSXNfjYeb}hEY;K)JiXGw+Z)YG@h*& zN8aNz0Z+#chx=-U7kPze!G58O7xOXxNOuzD-iO@H+n$04$W^^=DyN~98vPk#%^5ue z*(ff(Zf5t8tZpr!I+GuTd0OHJjjm7e$2%0#{SfgWrv9aw3Um)Rge_sNFB^?^M<}vF zUFk`!57XR{_i%p3iW|_OTZcVvdeEw+ESRYB8PckxC*pohpdjK1h?PzjnXr_=LQ_9E zeE)PQdtFd~t-z_NpGx}_S5CmKdV#6}cFO(3EVH?l>HG01k8U>}#;2G`*oko=RB<)y z^C(UpLLLlP4;;fC|2iu%|M_N9e=u^jY=RjR8%R!AFQy>_F6xhjCui@^_@+|{IR{t8 zCIos~eqw#M>V)D4B^9-JM>q&86RV9g`JPMAgcDTsV|EySUrfldQ6|vXTG^!0t?tnv z8ri0Il~G85(;|bY7sH}?9pY8>1+3Bg!_>Adpn1kmOAdzs?(z6`J0sr%QEJ$~nxIZZ z{>al38LScbUcL|697X3m!K@0X+2Au1fiz|Ajx)e)KVr>VTASrxA=@HbuFtM==_yYN zB5k|nA1IAkE)b08C-E*7SI2BWR}dI;UC~CtS6qkQ3<71jbZs@0^8+Engpd{78pgog zv=nwRiE(4a?6^^%7{M+N5%c_};&OAk)WinE#E{!02ZqQt3r+pi>EA^8FJ5AyqyNQF zZ&CKAAZLChpI@=_Zv{E?@5J=aAZPxKW_|_v3(Wl+LH=g`m!tn%kTd^=YJUiF<;6%0 zAvnveMq-3_+lX*#xwMPd8D4~E3oDuwD~=xO2-t9>s(2(-J|f(HJnv3D(@K)7`!m47 zBipQ83!0k?OPi%Mn~(EGTpX*+73FHZXe=CzLrwNltYdk<2k$I`vr7p8{Om zF6`~@U7k)Sb*SrjiFgFDr0HtQBWTp({mPjL}mA66iG0NMNJrXE0#Z;q-}6@XYrn*Vn0h?SC97|4wy05MLQ2Wlczq-Yc2(%Ns| zkEs)P+D>}DE{XOjj$*%6)~lWy)QgPL3g!S2tO&Bg!*3I_BYc_5wd|O**VC|TL7x9Z zZ7H;CxCO72b1$>&z`d$nLkHz`BO8YzlUL98wW=GU#M>@KbPTqykNpdr(ym79F`XEK z!dnMbL$Xj zm;?70Iq<*SBd8hT5W?^)Ep41=AU|2hmAgk({)F~7(_3#E@hT>Cv@iQIeqShh)2Bbn z)XHf!=XDD6>GZEB|V3rL-1W#!Y~uC5%$G8mSp>`5H62{l(0unIXB zGFJyUiXrkHU&RV453&z#C!!k(=%r}Q>YfC#^8>b^Aq zpZb8G=pI70pmr!N9Z__X#L&lvLPOHvv*qFO?F^SOfz1tLf453E;K)71Sn*4q#?Mc? zGMt3ZaGZ5*aImhpx%!M``G}CpX&t5vNxndC!aGOq}3~j|7xP^6X`W_UL$sxltX(qA?9w(U> zQ&bEmNNhFTWI+A^ z-aW(7dNgP*Sz#A`fgcNa?B-OnIO`&FKxz3nsep06xC*Q_#Phu_v@k^C=P#J-+@Lte z&MH$4?1u|dLlHC@<5I^N)jY_V%ZZiOEes8!eTJ1S>0Y$94v#=VSL`}}g+=CHut-Ns z`;Q^vn;!j14q5(Vw8-)oT4ebnEwcPuwD@NJUy(zWztUoF(yBEk6I?&l_J|<9P_Q#L zF9`T7c9eIUf{dp9?A3S13$MIrRA4g#2dcc2=deo8`K6=70@TPaX^vXQWzNP|47IhJ zZE?b;$&1bh@63Y^E3LQlzl)p4dN`yEhaY-M45cxoo^`^O^3ZrqoQ-IY>yTE{;Vsd6JR8x(qn=$ho*^C9d&)I2>*iutfGS=^QW+1moO>eEw1Ej+k#0DxlPh}gyA?8leefrtv zVe`=6(jm5xW%2Ymt?kH-Zn3j0N0Q8yO})kRDz%lS9mU?3xK9rs#vk?L&xjuB4N(&d zX}tUDi;t&e-)`Z!z33vXPAYnQ0%m3ugaO=ur0!GU1O|gOBe?r6zXUpktJy(+pIQ0lTxE zVMN>lXV!go-NB-Ip*guNW8s33Rb&*lB1zlv-jg7;|kV$;Br9}yY zAPrY0n(9Z1z}`3H$t@BYB%&Rjp9&EiJt0wcA5oArHQ9GvFT zAYos{MY}xBDP%hr2oi^FNs_Xg4|UCVWJ{fjAwrUo0x;PG8kD=@E~F&Fs3fL`*&u}B z{kp1L9Ys|HIK;w-UF2${DJ;n0a0^=1izkX7T1tA%xF{otRkn>YR&>exTtI0 zx6|_m|0bWePbQOD7UoBWJv$Y%PGY!l$7K`#Aq`a(TU+wm;IqZ^#S`Ag-`evBV!p20G_9b2Aw_*6(B^|_@m%k_a+F9$%8#=rs zAkw@f55J@d8@f0^(1=;SB----{wnbMtJrV3zQ1bv%C^6LkN=k|@|I5XUr~|&mM8MI zGxxvYiM(wK{BNkp+b*jAii-TV#K_xP^?$Y%I%=dpqMSg9?_VJJgO@W=OdVXQL|>0IvDbg$IbAD<*KfTZ@xt=kl;z9mDGJt#R;F(!n6Ugd zY57meeM8g#yFXN7FNe^W>i_?7i}kn7I)8AB^*5;fr(17~{C{#w;N@HxQ$sr`L+5|} zmty^m&;RJsKPdfoN`Cw4e!29&tzfbKb&A$dZrI9?7OwRinY$q9y@lw4==)-E#Sj4; z@O9e2l|am!`-K)Ubh(c@Moz}Y5iHBI()EYL3GMfMEVR`PwSC>Jm~Eg1Yvc3& zkVfoW>2U3iG@3D>whU2-7xk7wd6cSm@V=W{#tm+ae!eY)p68$*#;_Kb_11t^k)w~i zuugiaa*E%0F(BGRugTqY$cAR>!B4GHX8Fz&PuVzh0O<;iE_8GpE5>m!52VWfGfmpNIYtF zr+$}|F5fub3@tx`hQ>h$m)5G z+U<{1QGM%IXP*;wk2tK8ua8=;(^gfFno#}W`60~sFeiGytfogJ>jea zZ}Y!eBRDA?F(EM%=n#0v2(@ycc41$K9%4d{*#x5b9_L-;GiDHkWf3|T#Ni3)0@$pU ze}za(G!7V~b`Hk4_>tw!w77wY;T|R5|r$ z(i31egu^W_d2+RBrNlfte{S)7~R50kOuAKfQ?gg0%VFHbk%hw zb#ZS68B+$etVA{BV4awXbnxToNwUhh@IsyX0dQRG3c~o;PRx&$2|Z?_GMRFmgZ4j zd4yNklW+GI^r&umQKBYa&Tmx0^qkc=9!A-&<15#l%RHTEt$rp3JlCwxnBM%9gE*9| zSt65rsC#%9^bOsqeWwT>1YWSu@lZrlgERw$OJldjH$37DYvta)C^?Jc_IuiM5n!9( zH+r0?+F{C@9H);iI9`z6e4}`=1Au2#EQ#hjUcH%+nIR7dPsFu0#q^mz!&b`ZIm0BCTLBG+6vhI#rkGMfw0+n`! z^bYOlSzY(uKm_g-A%u^?H9QfE>D?;a+TG%-!Qr<4Tshd$1fbk!_~o4j*6e`hyLz>e z@}M!NBN~sS)iKnp^n1wb_fhXL0(Skmy5MDFt>QjE>=02o6aNU;QHgsu6 z!`{(CmCJjqh3^-E~uJ5h6^;%WPs`6#cvdARFknJv@qbl#Y$q!JUV#$h5U$~<``vRDr za(>dq)Hg2nDB4N%ctG-NdI#U)1Y}V^4);L$TA=;n#9>|_?B~_kRUjT|k=ieGz^w5W zJ>~LyqIW^8jQjB6wTmNxZeEfxc%niZ7wK0 zV9SwaC-r;w7f7N)`8G`|M0Y3V2G|`5E;bnW4-6+xsv41OoncmeY)9`-)z98FBOLB3 zUVvY7e)risEz#}QE4nvdU(Pq;QP>6QC;Vk!JXlgPENpV;4@ zT5r(^%0o(L-$UAuZwIu<;C%I)4lrMj#F#MNgQFw$Lg z{T2}Y=Ouf$XMXcS8#qspOzp1G`K~Y%s%P$$;2)3&5XXSd*MRXNZ= z@W3vt!1JF)?yi_8zdcwZ z*vhDc5aBP-`Du0c@{4Bkl4 z_|yr}%=MwK_CYT_5jPTNJtT`Wtfk8GxrM(v2PZ3yl=EzbCYJRwZFctVJTMgo#ya+i zdJOtRof9yp8y4e6QHZSzy6XJgc&Kt0!RCeJo_g{z3kO>owrL8EwPMUJ@oq)>DzGM^ z)?z4iD|s~&CbJU?OwP&4&4L*8prE-Y;XJFpibEJ`dD}^eB_07b`=dnWin>GMe3d%p zD1P?5J3?*C7+t8QRIx0oQzK;olXxU>ph?77xPT;j%!!nrDV;m58izft2B>$$2d`;% zNH+tmQu;d6a&CX@!VYU>IXC+DtIYSTxbwG{`yxh2QNd)7nZYq}(#@*Sqv{Uk#8YaD zLaKu35S|c@oT-PfdsFVJ9Ad<%`?hnu=h>&@4Gic(3IgXO2z7qemMr5$RZ|P}*_}&K zxgYV>Kg*_@S`bNINCY|du_R}hR*yP7w~~RUEd>@e{Vak2^WCkyJ>UxaR^11GZsX1E_ zZPAcyY(a%)X@(Pw%819>zy>HQwxpS8Pf$b7AZ{|*&8*hm2Z@e|&q_ck7Nl(eH)EU% zOI(LtqMxn&d4|$G-J$@p)LWbc>ACeRrxwr-0}?*Q*m5;Fk<1HRm1#1z4(g>{bycVn zloQM_@vD#Y3hQWu3O1>aJ;}CqcN_#DKLFa?!!;g zY>|DwX2e1c6QsbzC2<2MPlG}q8Ay)dS|AH=BM#x8Nfub$CPo}|QTsD=fc-A#Nu7}s zJfU;~Bup1u*u*grFS!!nMxYI!zUn2yiGM+;KtlQucQnX4YdZ-y4vw_Tu_pcakpkfh!GS!Mm)Py7zI#q+DWC*TZ3e(s2GP^>csQtjk)8J!Vx@5Piui*3*Xdx6l z=((c_tw#SeJVO76j_i^K2e zhaeGdR*!LP!#6Cf+0o7# zG}WWXVX~HmF6$d5-GB3SxdVs6@jA4Wd{o@XhL}f}T$7Ih_u1DbVb|C&}I4lpJUQr!A`ZEj$4fn zzw>15-JPU9IJ=^m-C8^$dLZ7|k)yY0f`Gb6S@ds4Fdm?nZLsGdz&J&-s-V-u{9K~= zYPJaQ*wHE60?B@`hu4O92RuE6a93W6*s?V5FA`orfcOv9a=Y z<|1i4JZ!ybcg=}DlM*=Nz|tS(vk)elU;kHv*kJzvAsfD6Z3lI@xpf&Sp74@>hpU6I zlyxF7LXX{O@uhZ8j>An&nX=6}LHG9;AioB|*XHfu0)pLb z)P#1fn2K`xVT4nLGCHtTF?BuJK49SS1$5JRW*39MYqq~l!HF1^dsmYm>_hMu8PI*u{ZVNd3M-2rfJ(Dw7$2&%+rAMN7Pr=+PM zHn%WOt7HQfssS0a88cZ0$lR+B){b6(gEpS!-mrI(%$<# z_lsFyoS5sLYYQBCPjI7AWI7fvDlQUn&h5pG-DMki^A(V`8Y8 zd(S!>Zf8RK*nMJY@lC~>H1>4w$cO3i(TgRxJc+VY)ZM{b^4W))E1fd7XAp8_rOM)9 z(tfw&agRfJx#>LFywYmG+_EPd-eo^$^9E}eN?)V0Pl*B_u4Qov;ZR^ z19|LuoOZV4YdGBAD~WbrJzLG8A+QBI5XF`H53Qh zo4@FX9mP5?<=VHc*TWK+bHLl%${%hg^GORXY@)Wh2xzp2@vfoT=`1H3o(V2E@dvex zOa7;*>EoZd+uRD0s)X{=!)=enH=mEd%&b^+VHuGM!&JuDOy-ub>DhMj`}f)!yUIsU zapPt?m{o?K=cbATCwC_btAo&h#*jvlw2`zBwBxkmwZp^->V++1^nI9zZR_vN#;A^# zkH)$(g(Cgy6D??5L%wa?XZkv2Kk%#&J z07yW$zehQHOm8PoY#Zmou67*UPTv60DsRI?Q!PPNEkRYOpfWU5mjvDh=B2`lUnDC~ z9O-zlp}Dr#lj-CNas!w}yGS`I#dmCBVwVFDK9-?a%;c@EtFFGYD|g7{rn~~hYR4HF z2SBr_nUE!egHaCW78fNkO zZhR2$^nCw^w~w9w^q$A2#Wrm^r*3A)^?N_NbivOaT751WqX& z=Ka8X8Qivm3o?*zFLEFyw)KE-TPSGI&I?8nrm~UIU1>+a!AlsPi)o)y>+?lS zqq2590A9w&2X~PtP>9Sm6sV;D)wH{5_mb)HE8-*`q#_b;k*rH4>r$!v zQfWz=!FC#>w4NsLrbl0(ze=y~6KuzWw}#%vyYOJp=N*Qv8>83vZpU{Oxg*ob_@ju& zM>Dx@SnfJR8o*_Eq!et@E}ezWU|z*B4wm>&Er@FW!5(fNu)kzq<9tYajJKOqO3a z^TwNRj&FZ;&emDeA3P)WtJ^#B|2#~sg)ktN4wkkG?fb$`q!o@E&(rp?i;Qs?go~_H zOgLwyz~EeDrD8%mDI}d5L?GyohA*EjAb`;(53Py{_`@}4}`ul6DgQ?y)O2xWPKddvgp&zX~R_DsnPR?dmpON7K51dXXbT_!TJCPj> zKzA0<_8r4kljX|#WI4X1q>kRA5tsq4F}#{#%W5s-vzn34YGqN__Q^8rXvCTS{6iV= zq6Xj^SB)>};#`>A({(d>=x49I(v}~9r$5QJ*3=0ZMt8b?9a#7qko-CPd~%l=3iR(alO*ko7mch;{bqD6|t{ zXl*-fUL19(F`qB$rYg+l2-L#4yPU9 z#_-UJ7>*6#138?A4;L%-f|JK@Qz!!UVz_AaT+{U{^c(a$bYB1e0F@vEl^{kzJxGEU zs07!?-MjGsI(s&uy)9~;7h&P)$$n`0ay+(6~wd; zZU#T0@rP{F6K?=yJPBWd1E4`ZuLPE1dh)M)_g{8n+op9Ft?Tv7?c{^57slOuX9t#- z-gfkNUARSGd+XlE9@sjr-cSDie16%q{INg0dgs=I6j8yhCK8;heNTSJ?~>xQV=GL|5b4W+I-^vAosj5>ig+@f zpeJ0kmgDUN>KVarQ`@nfsx+(4m?|8!J!Lgf%Hph4H)o}m=!~<#*Vh5y;02GoKy6=r zeQ!Xv!G+0;HNbWw3G5}nQl+R z)MGtauhUd&OqoG575R)_N)=j9lmedvOX&*cUWgLaWNvEdB+HOXA4K&U_V!>y?!>lW z?~x0poHO|na?b8KZCyWo>*l}Y4?T3t7n?rr8Z_?qv5TL0?3$~e~H=& zvnl_tKd$Y(9*@G;;%8poxaZ`@xn~>OAHHw%W@ynFpxgYy)5wk%8IHYn%)>t-^9m>r z3N(EQ<`vDpgyRTp$Z^c(<4D*kFH!!6#sM=;CtN*juD~~d0~B%;g^`Ain(M|K?HsEg zquv7b%c(7xb!AP%4+M_J4@AU?QgWc%J!l5EeO?#6%I!XMwX?(V!hf1>@P zP53MP>Vq^QHW8#I1X2?~Nz|7cu@gltS3S&NSPB+pr+BoC?N_t1k7egoc4K$?)aA^x zFJqDv?cNWw{Yp#l`mp;_s+yfhv(o%IWt=jG8i6ERWf6?5BT)S_U4gQGiG+#utm7(r#zX*n8{U?-hH&I(^~)>T}$ zOmpQvjb83!cl0rt_MM6koF06j9!h66+Z}^=fmKAbDk7Q{ImBWSPD}9@pHGhgandNG z2kB$!FMUkw_}H7CdOz!7@GM+itbp~Uurg?XA6NQE`bVY@YhU&il)m^nbRE8yUn)1- z7He19uMXUb*5Y;iDtU$NW^I-Iw!oXNS3K@AfRC-wc$jYD@oKv16Hil2301~56bm8^ zsQXh5~DD}Ks2`GB?T+H$Q+a@UX-ye%5-B*W{J~?1J*b(a_UavY{z#R zq5eSzFhK?|K?X3vC9NFh+Q}TlSI$nBvyx$#GhBJ&TY(*tUY-j!uMBRJym_Q0H;0EFi+y6o^v z9bYY2xcavIu@64TAG`CCRSV{>yyen4Yle(mKXJvzO*h`~G#9D7Z~lf44{W&f-pby4 z*X%AJj63dl8Bdyf^G(xduD_#gdMhN{3b>UlM5BQ%6?+$iMSZ=6&vT6PEEroeI$N+ys5U^XeCN587sBKr__q_lXsvy;Ucc}nbYJ5G<8viiW1aq zBwCsp<(hG>@jpz$ZmaNYGN87CYH8Ra5FfXTg$vV|35kzM&!SEKYiCTnZu~$z@Wq8Y zPGaemJ36nq`tOfD{~>wf$)(G;K6CALkK&2?)t8UH;ZKXS;FJYe{?h@hKal@x{=59= z`E9>^iL3p^j=c}A162)DvJ+gBReYL_4GlKpynsYWAz~fR)nSoWNgbH{h|oyjqjGUX zpqc93PMwVdWEnJg2GscIP|ePL`}T2-`}UoDdfz^{Hye9k_jaI_M)eZgO}3xe9=9E_ z3CM=i>L7K5Iz^qWZdX55C7bGy=rg4{Q4}1!?Kzc>QzV5to>gN7LV_sO@#tw(qSdk4f+pw*#jTl_41%g)(YOh8rHeOReD*!>wTF&aCZI`fymYbz4pGb|zWzKu-HGL}2uaxTJaE6yZ2}%tw!LabEMnuauY|$T5)<+sPtBL9+IxK`X9U@nv8*ebU9Iok>)5+@wP0?6 zJ4UtICXQ;2O_-Y$~J3ov}#rN#|>20@C%kv(vlD`E0a#4>BuiS}v=&4FN z!ou?-l2ekGCYLBTE8@KHmBJzgWJkEkCRX?rE?7|&^Oq==?b#g*U;%^(bNCgHJ62Uy zS&5=0F=*-1Sj>fFK=wTQMbH9Ds(B1M^+JMaQKKdvsHnq6is}K;O?7}M(tZ?WS}T!p zj_9RaB~D6NckAgP9Wy-iZmF~urFYX*dJm0qUERry^y*lg4K&1yqYTHG z8e&9ogyDD_V=$8t%`pd+jWgsjXHE-tk0Iphx}dBZ%l5~Zp+NKRRM;540LXQK6;vZ; zTv-|xG^2uayrIUG=n?XBkR(p@HzUUBWCG3&q6kgtdq{fY8%r*ov+|CMT3%k4{~11O z#o!A@jkxjQ{6~16D72{`Q$@5n5W(f^IHZj~)=7 zo~w&BG@PPiWnd;Q#sQH}mX$-J zy31?&^8qPM6&>+;-Bi`_ZF|nj|K_vK{QJMyjEC;|GwyxnOEr6b_RL?WEj+yH@lOfq z_w9+7@#TN~3{T#2@Qpqj?s_c$?VT^?zg)YUYPN>~zo&wHIZ+7?8SZ!~9x9vi;L>AG zBnK=G?m3cp%qT0qn1V}LtX^S^sikS zw-`G1BMe>K&7H=@{rV2Q${5H+Bw3UNnU{Gn6buK6Xj4JzR8I8yy?&3M6C+$8f!z)$ zf^sy0{i-WLV*{B?75uHhIm+rKu+?b<>{sS5M^@T?9C5qq2`0|qvbD5LxayJXRHs$M|&)YXajljj= zSHc@A=rQ9g_J(&zxcepH1s{x)xQ&po?f=(XQ5S?T_0L`<{~zz9o;mHmzSAKyEbjKT&qBbToq#_nJk|(Dyb&L1s=z;yJ=o2am!pI`KvF11 z7(n=FJunsnF$V`;u7Yv8B2{ilQn@8b8HrGcP_3YR2ffW5u@6S!2*BS$E_C z8U*&uQJ^f17J>W>oy6fXrUY)kaC>{aQ=XF1_6YliAG*G4;VMd#f>Hl z@5sNk;ZONT+P2~GA3cKcUFpq<++%mZcyJ+i7F6c zlL0ZTE|aY;lWCVJ49eq@B+|heW(UA|>cj%Y;DgYgABko3FQ-e$niaUxRi$39)VPSu7)BTTQLG?bFxX z_Np|u$&|S*iJ9AA*vz1)vg@^RVZE?f08s*)`wp}LwIaS68E8B@fQ}%+9fyPK5hs}A zXtY^_#peFnYVL2W=B9$l40hJskMZv{_Ru&(r!{PC0joUM*u1!|tJ~_O18hulTYt1Y zU)n>>T4=dJh0nPe%#!`g&}Wl5;!<*@xW>N5B`ORx+H4dw+Hn{hcBi6PtfyG4r*yNP zl2+9pXU!dqGt)L2r=YK9vqq+D=H-kqjV5};U}1GzF7Cl`kKq~bY4Y$MoJOYAY^JkV zZ1(3OrjBy&u$rP%&ov+GHXXr{Fdh2N4738u6^C#J4uD2rLG|>Ro25lFN6zoHr}5<* zU*3l|1UFtgbjkJHcPB&buh0L4$|YF)!i7{WiN}a>WrMP^GNeKsAP!W|Q!nCHaqn}| zGW7%Q15n)*3z?zOOIXLR6`tk4k_DB=1NirNn$vX9P~3@HE=~(D-L`32H$A!y_T}Q1 zr`r;??bzn_)8n5QXNBOIsnl7r5(=FK2&AZrtO^{@#|70Z2(Sl&FMJC?}tUL5tg;J^xa)-=EH=bgCI#TRX%AhfOhq65VmPN84 zc%SU>1L@C-w5@IKtX$^J@`g7{+kSfrNME*x%h*V7jGGtdGKl(?RGe@E!#~M&&mQt8 zEOp&aZY-d#V@Cj`D#`m@zdU&#Is8?gFY*#!#jA-327mct|^W+DJ&mge{JB z0mr(4`=8CIWB*~2ia%zO9?qFo6SXaq=OLk9Ub~xZ*|Z#kW9wxQe-7WmP!l|MOJdG@}gdJc4%U}!B7pHe)1iQ(LWD0U4 zolG(8Me9$rI)vR8(IJh@(dwhj7Xa2bUnbWBolTyN7&jo|l)WS(^UJhV+V7w#wUOFL zCs)a*?7bZg+{OGd`*O!>yKEzZoV5>hj3cACVUi(_v7hTu?<4nf_el518@ZA@4xRQ>le@)D+`Gs|WXJus3URp|_X9*$ zR2JGY16gX^&~C6{+b(!v2e!dgq#ZU+jI2N{(^V`KkK)cnI@a6Clo#Sclh7i7rXw4- zxu_`+qB+XBx?mT>X&M89y>O4+Lpc-#d$>;T@d@jlEHMa(r=Le`o-nj)fQVQ#R)tgk2}TyYu|}r8zZvt-W@weWM!kjN%qf50P-|AvLgg!f0Lv~lV%>dEt!=Z zUifZe55CHgU9X6Z-CBjInhGr zd4N~;vG5LZpa}LGqry(?)xF+GAQItuo%h-Twg~@BV29%s2NwtgBP3p8xW;+L1&nZm z(4btTPj*fBObtvAP6=NWxixS<(L*tgbH{9o&oZ!lR-gN*q%lR|OUJ>DwGyXU;wK&)y$JaVh@B1MQ5IJ zX|3Q0}w2iPzwPZ{QKnwdHrbv_HRV zrWpXEO@<41fK z$eA4l(Gepy+qJ+;M(Lxx7wZ>$d7BmkL_~q0>Fv9%COs_^atBMvN;A*O#d2v_KvdR? z3gxKLhrYQSj)yV)3kU72$?UAj?5xS`|JO*te?~t-J@xmgAZfGNw8dt%!XM0A0?(C& zg<=F+Hj!`v-5n7km3NJ~?5@Ud@~`FB;A?h2oEzQm=KL+fE{A*ej)gDgySkp|@VXnO z-Q=^=7+gc)cHtY~VIS&+A2;rvo_-`vLcu{kVvF*n)cN+7dXr+6&?k^dpDEM@hNMRe zqXQ$;Ibm|LA$^5#4R^J$j$0?(jUM2hK+kdSqIdnDq0a)J1;bGxgQ|ox1wJR-6}%_? zZkkW|tJ1apY5wgmf%o6p8p$G>8Q3?H<%8Z}l`ur$3Fq&{NxjlRzktL9=Lrjh?jWH&7ISh$E{{n{ z*y{GM)$QT#ka{@n3DVB;Sfb;xd=C$mA=+IYOLQn96IA;aIeos;1_} zDStppSBO0#7F4+4=)j^>xu}Q@N>}jzT)jB^@I#OP_SO9E&8>L&YgE!M?>fA3;d3Bh zALKv9kw4F!cJb_oa+%fHYcB4<(?0wF&)W5J{>cxw=MUUgoqG^xw_^2Y`Su8;+CE_Mgoy?ToAn=KG8NU zx-hy}S?;*Xxl&!@yx0DWv)%cH<8!ADwqV@l^txP5ms3;R5t0b|Rnbi|{e_^S_ygfk zEWq4hGuGT;_-HQ%0w__&U?d0(4VMHm+a|5rp2|EnHOQm^bkV~<6!4jl>>Bh}Q>Dgp~QZm^TBW*Pft z!oJWwm#W7fRgWwgSCtKC)~OG1xrb1NiJO_ND3^qcpALqF%Rn97)PNw2#XzB4rV2i>R=OBZ$Q5$;qk9Z1e349G7}$2d}bSZNJ)ioqlEclGG}0 zt?d^3TIX&0%JQ31ciHc8-s6iEU9LWfv^$axE9pv{MyN9E=KJ?cquGE1_C8ldZi$dc z%5U!zt4QIL;1?)HnnT#JK1wX+=a?~&0X)l@fnB=Eu^j*EPV*Bn`lQMocAJohmc$~m zB=Q^)ajLuwj)_7n(kEJyiVG(X--Rd}w$Kxiv2(QN?ZpW>LqYr%~eKgeg z0>w%?=^4W+CUz-lREaC8dE{^qnyYuzD5dwT4EIlHJusc+lt2sMw3`~)^kTOqhVJfh zb@wDHt)YI!Sa)vBAr_u04y{>$UmRc4yK0ccADX(A&Tx|YBaZJwV4fy#06Dq16($ikBPygL@S3Em${IoOkmra;A=lbt{ z{`kLF3A>z|o@sqFI~ae^&~o*v6A!(b|Hu9Kef{#=E;@I~u;Fu(ff<=WkI%m1&)%TuH3(5>6cWp`hwlHi{)K>VuVD7UlJ=t7J-%iTO3wo5m@O* z;;=4C2_y!+kJu6#N;_GyEpFx+ydcIgsixU;7;neLnDrNijp3tQ1jp~J@W`hYN}jY( zF>ku%^p5h5`+G)8=uBt5>rn2n&gRe77emqAe{}i)9g`uRdz2RJ@kv@LF8ywIZk9 zG_gE6((TC+y*T!A&^UudHga)4j{C>^Nt1t(zs1k_f5aeV<1m(+sm6;_JWMsBTKuba zs}Yqi#y3ngqIRnhHRq%5+$l9;#`nhPxnk(G+u&y=X$IwRjjL$rv%o8h!MgaSJ+tyB z-uZq0_@X`MZMyEg9m1}YTRzU8eEfE7|B@Sba_dXmFWG~=(5ed979;448{BDlgx-v0 z7@+dOVvxBz?0lRNsD~TW9fW}y7AMbP3)Bq#Zvux*xQC=)LW1bj~f zFCl^gkNPsMB3YR&L6%duf2s%sr)%m|k$%Ko*HXY<&mj5B?zky$7--aE%#jslnu&uHXF;Uw1}nSs%Ra zm99PDalhZPX!&x!l8s}42`Vk4)+f1^=8NXd;FCEN_{7{?0&5hY*`6<$}dJDg6<>v6k%{y;DYUQ^vR z0R`i9tGQitYfSaYN*oDv%?H3PjDmtJ$9zGr&lhxSiW2j=fpohxr!%g*yt?jkE1Dei z2~L*|AO=+uxS;NIDvB%t zi|SbbJ34_KU6gCxDov;|c{BwFt4{G~F}CP{Bil4XFb11!yEuos14BLZ0u`K6MVZeD!IKhB)Sk!DH27>_G+DXVzR8`>!0Is8*1i{x*E;Q5@m8k7_J2aI|izDvB zapVq$ciRmGnA>YPP=<{e30l!G__Sy$kl+rxV^4x&V20^4Y7cbMBvraOOznX>pjrGL zICAwFnT!lDD6mvTO0A{|iaHddS_8m4QJR`4Yl_D2DjY>z;V8=}W`-SR9+ScbrQplA z7e3h%qR!B%OymEA#)Rt>F1pB>U2lAi6XS=U`x6}fwCe@3kQv*6LKlB_nm)}~$g9D4Elz%2a@5URcKYu~t3qH!9je4O$ zWTVkru`5*}d$_97UR9N~5A+R+45=Dfm9yun=G*60HT7L{N7XK#>}Piyv#Cfwf36!Z~MP9u0gd9%`>#-`SNpWUi0U{o7{KWwfS*BNl~V6E;zEiVf*g|7Q^U45+Oz z=W3o!m_y|E`Mmx>GR=vSgP2MAa1mEGYv=sUyU$y4{(uD^&cQXq*W7SbNo(-(w{BVU z?08)Xlhqf}9(UGHsWhzuX`&-PIx4}h8P{MzbCwGOgyDivU)owqN=wV4 zHPLgUi%Qp*ibFhg{<`pJ|LAZ|&e^X1FzbDfv_FAsN=exQ9A_%QUT=j*`N zp}&?KEG?9V;zG5v+S^yCcN)TI=Xl{#;lq-D^2c>e_c?fxphy&Skm`#%Y(Xo|5wvU; znp13~7;~4uWy8A7ur=9QY`mF6X=4&&3l@iMk697ABUZkKxd4rg&eUWfP0CplY2VwH z0ywcnS{S>yYLJ@=2hZezHwTQE16E^NSDd-XNs5pT49@!o+=`E2z7*HvahSu@#;02l`f2rWkR`vd1ZW(Joj2$-?}f6}Vl(rM9Roj| zjY#$2Rx=D+&ytQ!+-_csniEOzX28{s5uc8dWfdHF+NUN)^?AB&@s>+AHyioyezki6 zshxc1vgen`sf(k30tklgmm3w#|wT>H{*lEKwwP+DQJ@1a%q+pb{VTVtWX@g0u!6Y^} zh^}J@D`EwC&0cb-SkdwN=_*3Fj!A?!3ZzgOhV&ik<1cEZ?aKs52Kg#q3H(Tm6=^+NB&=o~Ujn61q8 zHbpy1-x1#Rd>s1B^O^VCz~4fjF>LXdmS(~fkVb_mI!R}MD}0832pM1>MTXl)ct=Jr zQm5GG*gq3L_aDbc9Xj@bhpjsSb8M0e0qAh2fzJ0YFwm)?{rTMstQS)*r**;UOi;m? zAf@YXxv=gsTurVP7vK`*ToavKZVCx5rj992xkSq6E{0Yv7A&Ft=yK40bXkcSE-N8} z5=Ijfq@`|iK@D?l2gVKVa)~+l<|X30ErAne~%D(#p;kfr$ znD6Hv66zN{$2}%|PIQ8MTIj;)4EMtDjOcQ4x$hV`7Sxd+JMDqMcs~tHasH@ty}m&w zy3R+Us)TltXQ`A}$lhVFuF^rE@Ad#J1gsShPFpgJnKc2!4)zfXS=p`SN$gf?pq<`I zsi>-LwPSm@l;+Z<(zSH^0yTq5ajBo`hG}euXN?J_#n}Li5A<@$D6guu`r4Fw69M8q z`aR0}-NcG0>v5L#O8fnE4U@~Tah5}H40zxei{Oswo@xju%*lpzUCnjHsd>d&EiBW_ zf(3Jo+$$wm{0t}9A^{@zlU=>P+4*JuTkQSwyV!wGexYt%Idfgthh%~_c*-r;K7*$O z9&f{?phGp>EB{IU-+FxWuDST`RYT`KMRkq`*r7#u8wGHs5%Vh88LAHT4H=)R6?X)=L}vtpCsws$10Y zZMaudN5`D z-+P2@L}Ga5q{O7kdD6_p%*v+TExkXi_#*L5^4khmz%TmR$(FWWQIEt_u^vZ#nIdjM z9q26to(#Fp(1mE!sSYoTYO3E?ld9>t?ALeJ%*pSK3KjxQ1%qz|upTf1O@WpG-y6Dw zOzzFlIKa?2(2d3chQ@S(40iM@6OHLrbis@w8VAgDKSmt4Wc|1?mvPQgCr+WVQpQZB zjG0OqGnJOV#ls?&9>Bh;h*%`|8 zUYelroEdvcOq+{CGI~#hW)RK9_ZVG2=1_5V@F6q0-3%%`K&Rm_U!uaC0ZdUkFu+PN z?m2h<(#^L1LziB+Cg{M+T0c5+`5$iEef3kbKicr?ukL^9x@$LXx_bG>hVX<`|5;N9 zwcd*BKE4m*b@#QLod5m)<7v6r*NfZ9%~u3idOF z>o?eBs$Q)0(vDTA2kTa!WnJoJo$pPVxoA4n>IhvSG!EQ*5b-Q+rWnpSZUh)w z@Ya-s9vNxJO+Nq;1`mX}9bA3Be-RlZUX8)Pc15 z$0_TT4N9xhp&U?-C=yail|@R6@<{Q}L8YLmr3%>Z5>Gfqq{(|mANJJiF%kulS4Al$ zApQ}41K-Mb@CSLZgFnI(#K-x!V2|fbSC7yq7rUQl-OsD^`8-n;yrn33Ysin)Q>CoH zkClJO1dHp~qGZt38EnOxsh}_JIqrJ;ADf#F{k^8Gt&RWN{{1I>eEP(PR7#;Yx$oKB zfme2L){xVw5h<&`zBBrnt5UF@GS`bM(#)U`r-)M(&T0RLa7^SBYre0UC8Jt|Vi8<% zZ5eU$WbUUbaf@*e3&S4S=B}V&*&}VRbqnl3f*mk!h9e@+3%oc;Igb}oVjs0Z{V8{) z`XTpMQF=7uk$+D-Bz`IVOZ>O&bE~Sr zaXg_D6%-kE6j@H0(-SzJPnlB|ROoJ=4r=iN9jLI`kjl4Xr=bWu3kH_SbZ>Z^d1Jbn znz$Z}x#H{u1`sxL4Ym|AM`{Q=XpYg46vkjz)T41AQgl*DKL!mf`y82*Xc&jkm;^up zbMX-KHBm^j|0QwWr9Bk`UAssxnhSLBzWEp(ya%VQdyE3?^+1-6it*Mo20EWX(&ak2 zj$>tUgvUNg!KKR098rRHn#&5#pSjMRp(?#gvWi?%Qb*?@Y%QVF5#HGvXPYgF;%as* z5xE($xePmzSm@ZAU^%Z_{dDumR-H{^fDPNz*k+5(N@S*PCViCqV;;+1KRnIrtz!jE zNZJ~tKmK}4#Jn8m8qL_+sgwg$obFJAaS}_w?)cd+^YigbpX49CLD+S2H*U=@>zYMM zug=qTq;CQN7{q2}jWO&!aqKkgD$c~}fmElVleu(LPb@kOf6OskfuRkXc{OOTIRmS9 zfVu74&)k-oGqj8ps7a?#Dm)?_5cqLW91*xuVUf@x6a*ghib^Om2H&{+O-_@VeigP_G(TWs%#f3yp3 zYGV_)OglhKgEg5XpYBASBBba&a#>BnWf3J-^F=KpVi94BD6tmGh+0I%BElA-S%dC& zi*Q(k(;_^U{is`n+ag>R;jzpR-6Gr;;j#$3m2D|o1RY#5#@Ot&DgF?DNcl_Pv$*iC za4b#&ay+R7BXNb}lCh}hqlTY^#bh|7t8b<7`qYLLNd*F7M{2zbyLc8pV9A~?7LRA) z120=Vr?{{lP=o~$G!{f)k$9JttlJ}$fOAGHDECO&W6T;%t&iXcdqAZ70TK3q2n}Po z=mR3mN{O&&Q-p#QGnXP7eN@B>`bX#!dLdGiWVcT;uuC$qOQ!H!2-DCSDMb|WI0kto z{{eX{K9BrGo9LwFJsmZ?%s4Vx(qW=td8!>R-}0u30k%XHv#gl&)zij$ zwEt7{m)%=>{p$}uyDd5G>_tCsYnU~9#SlJy_t@!|H0;{EqpN~EblLPFcR$f}FWI_$ z`S=I!?E0W+Q6C0L^5ZRrN8m&c*{HYcf8{>+9N~_6M4sx&GGMu@bbO!wR`6i35ai>s z*WvZM!J@{Z->%vnn!{pRhb3{2VjdY#oyGkY-58Iwt7>$I(Q^V76ms1TZ0`zKFE<8pP%uK zpYf2NagRS`&f9Uhiqpw{)SOm-U{1SwnA3a_-8u~S56$zj0k*PI_n&ECA7v)?X(uw) zd`&hDq`vc%jqMj*iYlv;%87c~B|0M5sk(~{L+5HYQzgn6qd3IVgDX})cIC%SkB-;X zwyFi^FL|0z-@AGEqA~ri>smrqUB2*~yWZ?#>rD(Re8E>h&)ZQ5zqG>_EGBk;!9<&` zr)SKjREV8$OKM0vPds0qA~wo%#Cft@s}FGx@ec?N*GIWW`G*Im3DcAd^_)BBzc9E^ zSg6d>7rGbvX9a(XeTpd9FXko*lhli~%edLXZ1plt4Mcg#1whp^_v@&Y4feg^Va`x_ zg!$MJ#yV2>lI{|Vbrz%f*02mCiW57`1^9}SKN!(rILcGCeI<+}U5eAmpWUm2_B#M* zMXy*$!(>1^7`r&kycfnaj&h_qXlRD5GK1J)0*W&3V1ckAelWB|Y$`7@;Bgd~2x1|$ z;v)TQeI(Q`OhaYG<@tMZg5I3Tfti&%ojaE0sD{fzw|4Y}tzukyq*#71lZ~o!8 zZ@dnbU7erDCx9#5D2DGbmTGz*{VaWy&ez9V5?t^dBU&OPMEN+aNpzk6Ss~Y(shD+V&C33 z-hJcs_bD2jpP$Dagnrji6fZX}vylv`3Z6+uk*hSZ-d7(Q6-QSj`*(ou=u6+RZy=aWm?9UB?GjPWP~=A%p)IY9|iyF|1xwqa*{YP zZ}*0yHpwA+qdatWz)^#&{_Z)}RSdi#It=2(y3=qrIa~gp_Pzv8isJ11>FS>Dp4pk5 zYwv4@yeTDyN;)-o_gwNzg8d>Zw0c% z{ZjGfZ&SSarQ*#m6>t7#Yc(9(xitLNUKZW*K1H^0i|wyzBz|9`_@o(+#2K(++1^ME zn;|u9Mus&;v-IEj1smTJbN!+xHeP$pPg-XSv+qcyn_{eOz4?i|j-9Xmbno65U)g`~6_%85LE*lP zat+dZu?s81N~)0 z@bM8VyH2l}Y8xT^GZswfN_E*-o*;i&$|*fz6go0A&XP8|+RIl7QfiQ)XJb`DLa z!0wf)awqJRg?uoORVysTw1Ix`mUaDR*Iqoe-+%#qr=}HXrH?KcdhU~DLu#ilY}t=E z*Tz3mHz8-btB`yw)x9OeX3J}N!l~1ip)}!;<)hB|F_xjoF%&w6PL3hUNnIwjOoeHM z=emcx2NsVnoLRWUeV2Ph@e|<wDDWY6T3 z$==DnIp!Sq9M7DTIo>(GEu~w^{JiMBxO4B~NuK(Y8KpDI7Z)uqZYaLj^RV}x^835~ zsQY7{r@cQZd#rqO=}V;<<<1DA&@mJ_hGNHHr&o89pgW1uon-1fM0zh4DyW`hmX&xt zT28byT}$bfpTkP_!tAbciZZ)4dsOzc?2XxPWb6LyNcQ~f_p`M~_TAYc`{&?*bnv5` z{fecr_W*Cl4k-H+K}tZ8r*CXd%jhX*#rRMIMd>yr3=54!*_AEGj(y=lrGkaSZO%Am7mfjN5-I2S(l#Et9Dh1 z+Ny>sQN9lxfMSv9hxYid<=3OM`(>ARJKjLSHnO+~r2D;yMeLf;3n=r55Ek zcJ|~d8$IpKG zyKlUuoR>Fu;mm>O6=juF4O>2P$PML@ilN`RJnN##7xgL1%MW{sd-Pv2dD5B*&v4sX z9RFN&aXmnpN`$|N(dwMr+O{sg)j93oGU$%MBahE1Wi8~cSRD)v*$OFMpGQ$CBjB#^ zdmsy`DgHnq6)L_H#1oGto_LkGVGeQ+nr>WeG@SiqR9s!qFo*^ZjdTd^5Zv9}9fG^N zyL$+3!QI{6J-BOd3+@h$Go9z1?|yUd+#j=Mtv>tgT~)jM^pEa+s<5^=Sbu!)ShQeu z!+t^3wexQV2@xhuP`5yj>@zM(PO>la6vRqx8at+mQL1&VDmAcSF}j6uB^KRnveHOd zlk_y1O%mW85S%M-vi#=Ls+9nGhLn+vB%6S{!SDuRosski5`#p-1gBuwQl?JZjRp_Q zbCA>%F?rj`XY3ES9ar!pm}>5)c(g9MYORs2|IDZn?l7d&aM+jNWgo~-pHb!iMcll2 z)THG}Tx|GOiI(vfvF7WPq!1j2=(}PpqPb4`-_O|Cw!3pt@s+X!f(IkBmc@7}W+8if zx@**fvMZjZ&C!x9^JkX4-fk4iw)E%A`?L9?0DP6L0qtetV3 zcerpEzU{P8XeR2_@EtEK#@)F0=3n?;h}cb@yA)nD$1G&q-;8LIxAAIB(T>iRYRg}= zN|@#3YBZQT$P>6}WtHn}sw&$OipP#+7QiU^`VlhZABsFP-Ys;t?Xd*44M0uP>n4lH z3rTwGiffjwFU7C;wf@rT*y~-$i2@YbNWtr|nN8^Ww(xeE9wilc(R~Fq+H~KZ5gVUe zbjzs_`s0$N_p^9XD#jj79#;6+<DD8WYZ`fCygzm z@mga~H1fm{H5J>jLu7yslu;z@ zeuD#E{Ep8~3`DT8A5KnoKb2C{dEJ~+xuCySQD&I_j zqFM^aojBcC@>HXy8LT>?-ete_z95{p0s(oaXSk=QEi>vy8#456I_2Pa{fmIS!^fp1 zH1WHm`G^W!*Hi-qln0I-MtM=$^d|BOhY1Fqa1!P#(QSViT4>|WusIo)e z+B&H^$L=-&dq}k{M)okO&9;ljyG*hT1LsoC9ejlVMWgdL2T$I;I(FWpkm0KMo$@>C zO<@*{$Tr+Z5;y6K1}60&nO1{{wt{cPXvMGl923bo2PQ4DmTB<`;CHO39yBLxo#FdV zP^UTm2JbuomLBwXva!vVgjz%MUn^ZV{qgC;O;lf9y-!uOEXO0p4`aL3*3Blxujzl- zZa4n2#<{es<(kA<8Xw*AsbLHHeWFp;2ZYi70$BJps=A3!WP9wC{%P~zfqG!ekjv_L57GL**)FyiG+yIrx#)P?IY)ca zWOue2Z#5})5usX7g_Yo@@LhETK}cuz%>X+`onZ15iCXy9LMXP%w)r`q$p6H^etUbf z*U$4TuB%C+K45VJrPP z(l!zewBS<1Q+e3lAVMF_$~Tx5ZxsTGrZykN%fdk>(3C12MQg<<`4aiEbo5xf_xiUvJ$g+aW#qN*BRRpY}BEb?s*+4)}qj^yI84b_nG z^XpUta|NOi1S|;~H^tAwr?tzpu>x$*Ml*~B;*4nJ4%n9TDRB`_^w&kjPd;Vju*c{G zEJ%Hx<4GHtzrIKPGJ6i%RLP0b`}{_k(>-=BGcs+S>@nAk_=v_YUDsFgoSsBsoP9(Y z%e>VP1?mWMWCE4uG7GfQj;u)!4=O>@o3>}JDa}IiJyqVAK8|ZDAy0K*9VJp}{xZIv zrkhQyRJL!a&nV9Ad`IZ0idqmv3Yv^UiH>Uz*Y;7gSK%cT_*pkaEFFEhCcN>cxUef? zyH!+5IJ?{+pH1IvpU?+)(VwTh5jI5Ngk6O#&^QY2zeD_zNx}c!U`s6u^2(+W`XxQ; z;&p(WTjH#CbK&8t*&&TthtbcXfudaO7|)v~#h14a98;?kocQ5z8$iotU){lW>+>i} zu6$y*0%(_9vw7sNY#V|sopKUN)%3YXyV~jX-2+?K)LMI;>$tOmyC16Dok(bq_kb#0 zh5j0i8NR?oj$BfzwG5RaMt*aoV&-bJaHMrHqF9W>i8Jg$(0vk1jN9hiy!l1yq zH>cjin#y0DbU=rxjRPRn`)`}m(vI1cKMAiOOHdlHkpF0Ff3@h6S?{*vtuE>WkL^qz zv=8k?by!TRej&|7BZAuKRlsj*bn-T4HGPt3o4@j6HI}`g53{KTZ1q2X@!b|t7%3~D z(gVP}Y4VSR-r(Yu+1#9x`s`hQ*3G^h$W&D{wAaWiIxRPB--xL0@Z`WEwGY$hAG`#? zC=tN}^dnA?JY0INydfFp$L&xkiQRGHw9&g$d?RWGDvCY3%7@R@RP&5QkMHBnRV3k& zZt3nZyk1j|E{d3dUVm+wd>c23rW*tVl5td1B7Q55oEi3!^)&XVQSq4FjRyjuBm|Po z_nXuap70Gbj!TyH5i1^E)YIcvs%Snh1>iIc9aPbkX+Hg-x>+uJwX!!fYXa1El_|Rl zUJS|Cr~!CXJB&SThY=UYHIcaBrq%9F`Iy^6FZ)?8t-&h&SNwI5$shJ$145wzz}6-{h-|7kUB{oCb8FN*XGQR2Ns>xd?u# z_n0Yk5k#wMQTuaUQ`hK?hqA#F)$q$0fVh?0F<87%)0nmr4%C$wI&J(V6=wVEehH+1 zy%o1Do~W)I@#LVewwHGc2wyNCwWD`$5QuGo?8NL~u4(7B?es5@h<-Ane6sKaWkYmh z>A6$(r=U~IP~9d!d3k%kcop$~k);AAg@&3fgr4-@A2*0J^f%1g&(z#+eCcF5AG*`_ z*+SR^pAqP!wrx5rOFV>{hH)=^8@xSiWbmO2teM;Kgh4(v`>A~6#P%Wh0q8lIwu|g8 zvPWn-uRY%dc|%#O5hI(G1ox8>E8x)jG2mRrqbX=fM^H>;tSY(qecFe)5jEYM;*DFP zwaU3CVKB0sG_s*BVn;&=x6I2TMzKnwsmpQq0@Wx6(b5+KwhyfJEUt~jFDrUT_PK=6B z<3_JC#?Tr*WOVxoQ`#Y<3b!@ZdhM$6E$0jNEmwYOZNEFo^)-;;0~S4^$z~{^4$Mb5 zq&0o3k6lNyjx2fYTFn1#YU$gth&YLu+^(cm^E%jp9vl||Y;K%7)nE4=eax;(5x}Qp zn94exUK-OTXf=C^w;o*It+B)Vu0PzV6QkxR;K8NpX;?Am_9MGVl5~OAE#q6Eisp-= zer%iJ_h8)WBLfUMe3MBM=?=%|->pV={uYxoV{ zwC)KXbUsFRKn+qKQ;f^7O{UJ81h_XnwLTRaIaF<6NM2ISXt#P6xGR=wp&YjJ{l4>% zMho23p?vK^atyD4qybm)Q?1Ay^knxw-krjnK4cMR1&9k>H7cQ$? zI4(mf%PDFveAJ$3QNm0xFUz+fHAR~&;VdInh|jn2H*ln|>(*GYt5N|p*8X(});Ykl zFvM4r+wNaYPX_K+Lwb9lNWK;M#ury93mXcoX;QIif-Ls4M?K-!7@8gFoz%1>%os{j zaMjza{c1+1(+m<~oA=c^CZpDGH5P5gDx0U&MoTd)1?9!Pp@wC`y{NoUatiXWy1ZSa z88Bn%(wDiVvu1C8zv3QH=ByW_Kl3d$$-c$B5WgP`q3kJ1`YCMYqLqgSyQF+)RX~!F zOfUB0Wy7*J<-lh9;#%KQ#&(wus$yuBv;Qm5ferLY*EIFD>Q0Cz@lFCgP+xX;tG`Qr z&w2(jjoxc_k|g+HW^|H!8#i+r;lW3OqCx#TNW0Os%a&(|k4fyv};*sV4H$sCx4miK;uXS*#Waiz{ zFk81R4f)DXQAPgeuqv<=b9~}B%`4g{(|GZ7u$9WaU0&E(C5(cWmTWfZ?yb~bN>Wj{ zRmno*f)5Vo-(9Xnkh8{%C;}#}MlNlw{}>usR~TjuXmr7~K>3HJlsEC}{!X>8SNRwa zKjC3qU%=0L@@OiEg&}*!PFNmEQ2>KPx5HHajh|iVV8Q&r+)|h+iPdq06Aj}f%Ga=N zd>I`hTHIKpl4UV?kZ*|3&@sVLSwqKG2OooFGR-o7sSE6i{;^%ThUwd@sqU;6be9=(x1mwXnqnd!93r+ilDZ98FbQ zvfFX9&VH_Q%ATkgtee}yA;dCDxXvf$=ScFNl#r_%=^RDdok%PGQf%}M?hG1p1e#{s zJ$O}#A|d7c?Hb8;!k}dAIU+ubz$qeYoR0}!Mjl-|8)TEOsukxI<&zjmsZQqeTIEh& zQ|U;)Ej^g|^ipGMyU||Nbiev`Tk?7~7X;e!-=51U8^*ZM|I8s~qkXp)j45lI>GjbU z1PUU0JD-;Ks!#P+eQA*Qfjq>Gqj~Am6|w8|PwzQEU|Ax4uX@R?M3`R^2W@!S7?1Bm zFn86q|J9EpaA13GiYdH>aGXnFIwZ$Bq3Uz?%aEG%37CJh&Y{p6Bm%`2y( zHb+{Qoy@r46Ja?$BmAff^!A^@$HRCZhPZ@c>-8WScI)`k3SDZ<^J;fk>oN4_6;BFt zmXt;KR(E%o&ST5BTHONU>hr{DBk+i-E4}*X8`ICVGL(BmfzQr4-PvmWZ-(nVh<337 z@;~1cQz=Mv+}F<7FA8mn1CT*e9#iLTUgHaxr7g{r?{I}h1k-rnnmq1Nu=t2k0Xd9E zpA3p_02{@fU-d&@a$Q(9d*U|&1KIH-4%dIYG<{Y_e3@iCBqHE0B|L&oj5Pn81;Gc@ z3cpjRokQvrR(D8WoBR2==E#k$h9^M^dHKrqowR(H@JBo9PI6R60;BA?5K^vlppHS* zvW&VF=C2>GUcL9kWrz+0hx6XOo~wvB@Et!q7TcOvqq10$1ncv;66yf*5RxRosWanBPxXez zBg9kr2F|1Z9&q!;F@e{*=r4+9wpy0wf*(dtNy0ngWYcVT&ggxxCx+w79&g4e+HI5w zng4W>&j*J*#jOgi*v3469x)!ACS0F3^1fFnr?YRXLR7(;AR#p2)&%ePwKL@*!fpBl z>H>VmB57e$M` z&-yQdM_aU<8L|^)`D-OBzR)mKY<*p1!m;$H;7Ko5% zs>HcuAgt&(Xxv&J~0KHrx3A1{gM?3evhw3L#wLGyahzYtb^eoxpHD8lm!8}?( zdoX9bz}n@Qegv@NwEo#ydaPrAUzdvw+Pt_j|C%!;x1(UstWU1I(vs`zenPcVHzp;} z61zU+h&y_Y*TNF>VUqsk-P?%oF?H>47wc&CQZRc6NsNEvDgUZrBIu`w4k4bu($-gh zX{5oNxe9}K{Ot&Va2Nfp#S;0bmen^)^Ad)pb*jN*30=M;=?*?`*=CNMd7!BPx8Bfn zm3^UU^)97*V<2<4^*MLgt7zw;)qLC`a1LKmqPhL+J<3I|$rP$4hN$K`gF{Z~`{$<# z-`OmehG*{)1iWTA7*l^m8PqSJjX5M=YGpTPxm?$03YDU05$%phGY3saZccukhXb}f zmibwEyxfMSlD`yLyjLx12SQQVi9UUXhr)%zdRQrO5ZUIy z&7YpBw~*5d^T*$)6nuoOb#^TvPi6|lq4**KDf9GrgUxwk9CkVBKc|qqoD$9smg=|U z*|sCuB1^sJpb1pl33`EhQy`ZjjT9gy?pp~GOeI+omTKCbNmmP;cu|`Y%=-UyOWhAA zoCP%ka0;i3c>cPTAe@tKdh@KS<-WT~Z0H7Gp>%AJcY33*bJ@_1Gt-hd_%a!xE#em9 z2{I$omTbSB4BwSwTWi{9)y7p&Jy|L35aO13VLLfdzx#DkV!2A-C23vEvs@iqreiDm+#=X) z0^+b>?TFm!?M^4RWc%!ot6L;jAa+82wdr?b(eQoo^IN@^1qbI11Xaf1DKAsktL|Z$^#0;2|1At zXA<6FR=*T3KapYB;*(qyBK2xrvuD-lNpess47wBP!%-Mo;}FsvH5X+~B}W(J4e^_7MYpX~VOpt9`uc-kIkOx7 z(N$q&Si=Y>>*mwsBj%MnWHfWrONc*@-3R^m?(qOBX8#ZIV+^2TxfA0%@{z|r5zK;h zZ_uYR^F9K%n|UgV)-9TigfU>JaOUCY#puJH6JLU^O|fOT!((nV;YFSwVim@Fph-tt z#xv7hio<15!ue`~c`xZnKL3a#BrrM4W=TR3TLg`ynhOus71^SpCy*V|poh6LHiWVD zf_VTVYAK-krOV^PUF2uu{9XOt&My~mv;*LJ>ejYx%(!;i=e5Oeo!m69*XrRh z_%Q5Re`9Ol4tihRKfOI&y9?=m(nb347ivY%?Ww(Jkqvs&+V)%)2=pajL^-$&Dh_gk z`7QYQ@1=1quhSgooq)Uo-}|FFl}YmWm+8-^oq{Q(vBdADCy9sH7B?FGR39v}&{;xX zn{FVCiv@%)tYz_DeCDx+^C+hmMJ;xB=zdXk(MmMXj^8vS653J^+bhKkdWX;9jn%V^ z*U<7byaJv}7qDARe1@($^@qkUIKHl_?NjnWLI>z%Oav-a4V&1K>8B>vg>1@f=`Z()QNvtre1a zx|{f<=pD~SIgkCAFS)=!SnW3wmu>oLUo8uJH|svQ@BGqHzA7 zK0x01^AZXYqW8er$xPOijlEK-_Px^v_%+-s&tUriU80>RPFr^AYPX=h1=ncaH zsbop|wF@p=q7B>EVqkW@FMFz;m}KlZ-lL%^C!^Xw#?JxrS%d?G?{VqDMZv0W%y)5k zC&CsCyUM-CDv>hrOm$InXNUI7D@v5_2F|6KJq;GJDV6}sFwg-vgE$-IUMZ$?MZgyDoC5u`Z9%;4Et_~1dZ7;0(U18{vZX2W z_EaM&cC)uUc;X_+yv@IjcFmd9Ge5ZNa#1uI;C<{*L{Q>wr^vjmcZYP18;95$`-pMP zsmqT^0d+CB^(8iLG~i`q&m-6OH)r#`X_Qdn!ou= z2Vw6c$NQ&%Iwzk1q()Ci0;n43H<|!PS07m(E%%@U%~Qrq(7+{3`={M1cgN+$!%BCV z$^7D00nYOOuR8A*3?B*+ks9av6i34k=8>x%%neBI?QtIzl~7r?)z-&oPTL+ zOrc!6CzhM9&JR3M8yOUt+1$Z*(u18oaLX`7c173yJklo3MKRz^u{19|jX~7|y-gwa z!m{)7>3ksdoP9}D>5Cpmd*8e7-D&LHef8x`^g&Xi@&_XL&&q}weX%=BmGk!S5N>1b zH)*Gi&R+;NR@KGhQPmFm3X10niHCadZFYpw;@S6(n;Y!z_TO>Vb87Es;y(gvXaW#S zGEwwL3~`1QEvMQcmeBS_5wUaPoTiQ~=NQE)mQe0C`b*axL>|fu*VZ)~)jqx+&k&cW zjd(t3x^222K2hvCaj!MSOJ~(}_+dTqCi5ciKXFPBep)$KJO@xQgzR-DR{<>wrdT|> zs{${!o4$@ZMUzN0jiNQjXB$=CbNe{2x z0#j@}7nh~_kTYaYePG1Fl{;2axsJobqo)GBixkNmL$=d&|&%(3OTd zW(T3dx2J>XMjRzs73G_jls3G++U9hazhnD|KQo-nv?AZ8mn%@DNyU;bgm*``I;zcn)b_TypFa9m~#8t2`(Np z(;RY2e$^X}HNAZgUGgI)`={Xq4@z^Uzt)jE37&y?Jjw?gl%t*<@%yi61)ECaQozt$ zz(bJ9zz4D8$-OJoJ>hOwfM+s{aSII9hd>`M-YD5-rVD zmeeBQKRx5sLM$8a>cO5!BiE=Zng7T!8@rFNHI&~8;$dPpU3T++i>?-_XQ{9B>b3T# z{r*;VGn{I9oug>BpPq?3=F*ApvbsyKK|b+m z$92(zyBqnf5aB(jdXQD46XPTNRJ;*BXHegjE{OKiwl0m$S##ZD{M!!hx$CcX9bjj6 zwmkGuGYsNG5Qq+vpk?1S*%(vH;;mtSlYpV*T=gT|1+T=Wt(%p6c&VUi1#5n~*ybK} zJ+!m;R_=ssA?F3LiNl0O&)K=FOE1|Kcp0d5MXWDgp+L4^uczOCYW1m&Jaqin^bX?e z!xVcHdn-leZBD0gx2Ggb=OxJ7Ne-CZXPu=%uf&w^5Dlpx6}ZK8tzS_g6uSCI;efuw zlWi7>?vl)nu>05dm;2n`?oX*eXN*$9QaA$G>Y|3C7jPXdrbjpxqzC=LcE)D+zH=H} zca7~Ar_Qb;cn{??oZP}0)cVyfN){CmPzi5tsf3NRo6VH z=*vBwhmVdeFOI&_L3|AswFIzggYK=*!|s%X%F*oMKPZ(6XAn%^+WGtpxK5BhwW0e% zKk$9?)D2)!uv1=Auxvi%5--Rb$_=Sh$B8D&7bE?>ES3yZ$a;^}LHr)Ya>~U$sWvg?VPtp^eqXS)7 zPOc3MO1mz+li37dvC&)=8Wzivtz(tD$%e17%F)}<51+q>Hs{HK#uAqrne12UiGB>_ zp!EE8wCw~=tA@>X>dAz3E#ssNY3jd;1h^&xDJBFqh97(QddT7r^5i-6U5cBq&9y2V zqvYwwGA(mSp1O#86u|x_ybWSAbJZ+QG zf3$aD8P6E1*qn-LDrf~fR0wv6oZQ(rWlI<~%0ba?_`F(s=L9X3)Z4}EE3wI31dY^z z*sg9v*PgZ8?DORm))Iyswa0DC&saQcIfg7P?9Ck3zPTv_ubckBQo)git$iy?!3*F- z{-u&GhS?#9Eoe6jW!bj$<0SSn*;c9ik6GEzLpEpckoP64nwvj(6>nc(s@Nqv;RKLl zApQTg;SeZ{GqKf#dT2e!4OhA;H3wIQ{?xpXs2fu7s}AY}9?0Ir(`nmD=1+6o$vWlX zn+4$?n0!2}BR$90o+aq#O?5W6*shB$h*U?vC*ai}4*Dhwt?v6sY|)Ryo0?3X(~Ryy zW>5dEcOAM*-mG->hs-h)dYI3Q^$*cG5bE&`^nqLDIGM7JH}U`Q`Th976rv+ipFxmfohJ0R8S_0v>n-F=L=W--q6hXJ z7O(M6h0gwZlXxnn`FaLNPhh5f;~x3u)YK^h^Lul5f4uqvtk#H^BkU!O!AO@f@?wFW zBTskOJ;%)w89bZ<@b0eAX9KwoYnj-6>Wi1ZaFpZ+Nt`#eB4E{FtBMjsG9<4euFF#t z`zi%0-I-6(?oyeA&{qU{9WQuGI8k|4Bj4z5hs>Xhnno;HA@s53M=7M|AN1)e(ao$b zblRV_eD5LhE|M9Ts0_@f$|GInHIU0hF9D3+u{iQdSp1)*s~)zwdc=D0Ii3<9CLi-5-fv!Td4_t`1rfRy`zX*=LwPND^+x zDc)#8G+X~^)=2^GosRa^Z2gXLcCtoGgQ*4z|EO2W$YxYn@M1VX98m2T}!S_$L)DweK+_Jp!pPR`d%{brbimc-=L<>`L=udIyR%z*5 z3mjjq)gswL=PF*`rj-gjw2C^#9kYNo&~A`8a>@wX1ih}T=wrD!aUDi^xm{`88};~dI|3f0`4YU<3|n0LBh@69*WrNf~v zvobijRy{w-$ulF0!w!4=(@MRQvZsy~F{8zng#(dy(kvs3WJ^z9rPZMPM^Z7kd}8MH;1>pcld51-OIj~!W2VT2W0i4^nSVA!TEB@*fK(sVGTjN*~doY z7i;oHpx)zwTii0Z7Pe}i@vNe5n-UTsz4nEw4k@jznK)7L53S$)ovOKm3Y9bt-hHN) zxGoJ&-9gsdL*1h5e__dIdXx=EO)wpBNH5XccOecEULb=M07BGirMu@^G>~Fj-qptg?~>g za+?dj(=qqnoNHnD>0@m79H$+S&Gq;Po;Rb~Y@1A>Vd&gd=bS^_T&=uiY8fl7Do!#D z5}S0tN>QG$<%lv4ATcC$?kdv>xjtVg+?K0P3x8Y*=YbMQKotjr3aLn1Bz*3BC97x> zf1TNEnWY9$3RbGVO+cM{=Jq-7{yI{AWLAFrN!|k0ZRZ*GOG+~quNVT|^a_kDxMg8k z)7i#URr;2HsRs&#z9>_t#e%%IfEJ$r}YyEys) zf+*qGh+qajAid9Qu;sqT_v6)`uuU*1RHwG8TE|$!^g7ajz z`Dh2? zveq$#5vmS^sm0?!zMEvbU{*`y&)s9URNo8Gm1i8R5GzOq!rCFm!iIEHX2WC(qV*Ti z*=Vwv5^!|Ipc02>KI1UC3GQ;ClcYyKibeZUi?iYsFl4t%DPEL^S{JldY39|TW+ZX) zY{ai&ar^JMDJ5>xxgRjo_3TeQdyS2?HnUf-FED8Ed2CbB&!1cWrbuXzXFTNCfcU*(#{65~Fdn$nc zKGu>pVLq5r1cZE!2~toe(>XS?livoR{Iasw%KQYyw@>`yJzw0$w9-4E=Ejs0l@zy* z=x}C^pdJ@B-=ve9x}8huOxX#Sui0tkHBqGDS+~n|ap% zNtlVD-;ZslOM{Vh5$YX;W1NDh)0k=@YMj!J65V7>F1K!i<&ZTcWyQPXC?kcvfVXAJ zput^nEoH#Kj8nSXW{}dbN)k|DWss2?Wz{vVcAGuhTsX7!URfBP$rn0;XYQ{AU>}c>TYiy8ps$Y6s2> ztN)4e|2+r)FM04^UdS8Tg0u7gH|@l249%SZtpAfb!ov0*U=eie?5qGf7G_oe^FQsu zCa{4OVGwdQ{+DSS;0QDPWBzYJ#|#b}gOrP*jis@WowWV~0FO*lrE$9;#xI>OG(I*!l*?aG^(sZ>19`xt2dJp7!sLj$DCg}< zYqtzmDZ0SajkK(!P?IhG=0)i2&L=6?FOLS54~z;DH31+8#$;2jCGlYWpZ09h!|{|C z$y~k5tA<8${RyDu%pm>8ji79=R`bz{rR`|GtBz@3OhR#PkLUkPa7YFCPs1ONnJ8| zB90-aCY{^O8jCD7T*R@!pef*n?kJuA6-Njtr9YP;dys;&gLM1HhB=@?VgA(3!0`3}aVk|Wz>%cF{J1**N0I4n>24N1@(iw#N6Z_JzXImdp=`%7x^zAV{9 zp*IUyt;v##<4cWUE;GZ~GslNGG=?qgSMJAxc6^#kLESQrq&eZr11YcM&HUISIQ9s+ zeSW_-Rtffz`2|i_frCt0T?-=qAWO7AGi)w&oNkzZuDy%y`zV68P=jP86QeaTzXL0K z0G(dh?}M4Nfkh3-l>)efQkP;1L8EXk_!*_Nw#uG=D;=a9X^aE`y=7poun zKL6@2zD$dDHRRJo$r!6PiClp?`@}P%XTor6#UHrUpOez5gg&%MpP=&%m~c4G07tdV z*UGPf=_Axsc7MWjkI)3a?h%Jezl1n5cT@^aD0T^M z3l?s)JykrjPFi{8_iEK@Wdi27QR`KSdro{;4a-PE{^W~d^=0Ebf;Fnat1cU?twB3O zcB*VMY4_R`MAJKUy#Xj2#@K{z!^q`t5lI)uTXQXUUs9ejCMYhA){amz3-5i%^=a2u zES~t=!s&kLCzJW5yWKDhat>j6Vv1{v4w%*HNy-&y-T?_jrf<%dgWK+)-})^MGHNez zse(Wyb~XXaxPCEH+b*1%OuB*2a|0J_wA=0tMRO&*KfuMs{B!PEX>-fO;i^oKe8TQ% zd7=|QpZAKQ99sXsxQqZDG5Q0VQ2SeA=>}Wv}p?gR)eBw>71LzT!COnL`(e zs1EcseaBgF$eNZ6&s*@(bqTVPMZ3J4pFN|4?O1jbK|u#NqPxpWoJv3krJQdIQ(sld< zGWN0M<^o!5hp$sd;lNK1bsZa7m&AF)7BO)RIt-5Jo)nOmeunkXsF^ef{CbPb>yuw~B)_K3|dB`+p!`?;#g=-Y2m zC7;ojH)zB)enWTgJX~N>XDB9Xt!R|Mr%)y}LzlcuPK5p1NoE9qpz3n@z1Lg&7rlr~ zii#>}MH6DtJ>K0Ypwk!9EobrPvsFKIlrK~Sdz5*I26ENyf+@akNB67{sDA#q<}@?8_+2+J2)ldcSy-)O6*;;>NeK3z8%kE>Ms^ z1Iq}%8MwI{m@)&Befy?OUd*~= zNmbP*nG|hdMuEz5gB*Yb&6~iRDiw^0a7<6H+&;f5wK0n*kc8L;nNWws0(sEQW{uA$ z+IB?9Sjf|v-L!?$yy5*287V{lQ#$H6=2DV0*nt%R>!klUU>fsiS#czI4ih(=>tXI@ zqrL%y?Z)R4FBA^?tiTZcNNt4#j#ohnrK7!iRsl5*egU~==9VBmRYl<)Pv10PDJ;F< zZ~C%gelfew{Cd|A!u5v2Z{0|wROWR5^O)A7xnn*^+6!QL$05LJR)(4uR9^ z`E*HIMtaPDrA(2J!OL<_xMhYFiq8l0&|5FD$HEK6noL$>YTGnLy-L@*t+bl(ZfdpZ ztux!t+ImsmLdBZGix2s7Rm2BwtIkc{QqDsH_fP+6JmlM=x)I8}CQy>5gx^)K*~}v= zrwUtB)o}!Z!fkRN{XX-$o6VQ{bnd&lVU7`?Cm*qimW6A! zMD?Z-l?FVM9$^f0E|s(S!>-kt(U$e=!f9+(jgf&OXZnh2c|$4~DrtZ*1C#g6c~Z?S zY*$|m;%tZ8n+wKz0rkBym;MC|VLLA01tC9qMv?Yh)n?dTC4mhQ%RwqYu0XlCXhgSx zTWddaB1&>p{`kBrjh~8pZjOv;{&2irbV!3X&e75i(>XfKje;6Gnci;nq`Y>xu2uX& z!T$v>mWgER!cqYp`4W!-RDS+8Ra(8UIqT=H+Fh?vPP!m~u7-13>?dZvpA1yvOWNf^1)4q2o6XOV!ZTI}R!X?)k6Gw_VSLrm_ zJV*@M=;69sc#Zg(eZGUd$}ow=cTc!T&iZP7G_vB}>9&PQMf=}$R!9p)Vw|*- zpgCSE0l;z7%&e9{&%`LV2S7cS&AM9hdY5eNwZNYsHsowqpNfVn8x=$OdrOIVOK?vu zUzJH6Vmq;-eb?|vRc7cKVc9q(H^-5b~40VY_Bqj(0z&bpKp@wF%>`T;De>(*$Q?Chd_rqocbGyC~B`PaH9>DO>IS4F6hV~P6{9K(vNjqa*6_){I)j~g|7 zQ9fCYYM$59`PVzsiv~}^p!ysWBY%Dhn=;nJKn>kT7=>W5(Q#UL+^V8z&endtOB{R& zVmJdFnCUV(tnA^wGq-^zu-`uPKHe)7YB$$nuCfL0jbo>(@l`txOVBwUG(hc~n(6_B zU3I7MiP924MZlv0tjIcn&JMIXHMDwETG{E&64}T#dkBiD;Ur zwzM=URRq`hXyQRY*1^wh8?3L)xKtEmW?UR%wvjuEiuJ?zd96g)iqWs+{z_59iGSrD zmfz?V)a!Z9oX;+Ul)L7by^eSO&hLwu$CBd-gV^D^}BT6VLeXUY}0m?P+-XeZ{_=J#t`X?5wack?Ro#lFw-56_;oof%uy#Nx?y z7wN03PiGB(&25eaRCO&lDv_iEBou{_2P5TXSf4b{qKi)u4NbdO4?N}y;j8Ey_*2HQ z4(A3Mb8~}VG4`a`tL>FsqGU!K{Zu4lyz%zRj3si)EtMdioI)F zrI<=aP9_V)Maa%~#yY09GGtuI#A#UVF}1tf)!xJ^A?iVb&lDFIW6`4cH!bQL%cv21 zLFc!*&e=XZWM_F3$GxUF2Jx|&k-WHF5_5^MxVUJaHUXa5i8e0&?jIA1vZ>2DUl-#- z<~&jzs1+DloJ4!&gL9Iei}I9&pr4UG)5&uJ)3QY{y=;Oj%`SS2~2US^N0w z&z}dGWnIH$!QEg8H5)Op_L!<{i9gP_8rh^1v1Y!Vvw8hSDurJc_j`X+0i)i=<+4@b z)F?m(0&3 zQOvo=+h7n3>dIo5e@;0_RS> z*q#>25@G6J<3hLeJvlFB)vF|zl^ivNvPLf{vtr(ji`z9gJ>6Jzeh*oznxD96dFiI) zM%^3D$$#M91_3C^goaLq>`QX+d{F;`H(2aYs&b)a3zOFKve)}&Kx%A&i7*LHI~sfX9fu3(Pyv|A8CHNpB-cHXJk4Q3=zlQgyHB^-tuCV_H- z^#7pk9)m>p+6B?KZSJ;h+qSLUwr$(J+qUi9wr$(CG5vqvI`__;IWu?W!~Kw|WTleI zT1hIYG`XkR>t^j`kS1wc{l0gC8+{ z98o&#D{v?ijDSq;9+=TSvu@T@b`zc#hEzO zt}3;nE-QH6yIv{7dh9E;mg&3TY0&vujw28Qy=vORkTLVOYh}TdusK@9LNSLH>wo0V zri^r*vhU6VBOTwjp5U0^<<#9B_s)Q^48RksJ*jNdGwscm4j!RBb=Mm+w|N*!v~u>h zK??9e{_Fxr0X$nBZf*SZ8J(G;p|X3gbb)_uaBNc)l?(_)31t+EPkb%IP||$ytUXKTL0>YU zb&8|knvDVS#?WTk1?{tX-kao|ItXm>aebKB4mh^yJX%cyXPvxaur)BR^t@LoSem{Z zvM~XjzU2Mh=-p9juW>WDr*S=4pl-LCOO??I-F_vEiSi(27rKgl0xl(km_2#c6(77^t9z+`vaR~(0ukvL_+m^MpMAlbydUJ>kW()L>Q)ntJl+KBmJCEjhhOiJb@_L&=02qKuT zVc43mh-8U|O6zq7r#J!-dTC2NzJ6HUm!YOtv$$?iO5aoBQ|u_!~vykl(b++fw%g_2%!c)y7q7 zETVlv*YudtoKZfBA((6mSJT%HKCQm5F_erfDOH=6P*^HKNXsy97ajXmM8+5EnCdX` zyf*B(8EwShJ#yuF9P;|d_T>-vBnp3p<_)KD4Mb>w<}4=Jrve$dgh4=2{vavJv7$4} z8)a4}*Xv+b+2YNKClSn_y~|i?VlVBX95Dv5d!gt=9GUGw*o@=aFNb~P0Xw$E^69FR zn07Q-DTHp8)qqWdjR*7M1vrxV>uEeZ0$Pf3bzF%)K7z?hw8lez425gq!>A)RAZEHDt#kSwnA2tEm`7ab@oQI<|< zo7)rRQ$*KEA#Kh^^m>Q0tnP=_)cYAjs%=bAa`&O?-|!iJ#8@Gc<*>PvZ^lo}PY*-J zaLm)5O4`S;e*p>}4Ra;&RpXuh?dsiDWy`7-b=cAvVdH)3?oj8y-Ci!eY4KzmaqpiC$6!&Np$P<>2*wn{vSU*JZc$ zboDYNXM!%r&dPazEXk_ac|_&Y!sFQKqLq3#Vf9n(g3rlPcrx>jR)-PkzM?Ir!{fx- za42e)aFgy;CS)^F-0}kle63^+eN}DUwqX;ua~#{uwQ;j#7R^99AB0OpqahP<2&BcR zDaW-BZh;F;7{^2);z$CP0repJce|Av9W+U&QY|<=*9>eE3vaJ zLac4M_jdLd+6RIf&ypo2C72!*4q4DcA=MgZyE9GL6WW0Yy109U+MFS}OR@L0RL#RN zY4t{GN8Qfg?&IZo^4~cww9OAT)0PRvYbahr9wut|YV~cW-?EuxsOJ^I+B6AFzk>t5 zf+34R?$OSL#)OjP4EQ3{CP*7z=@8ilY!#Z-pCq3#WN@fKZzB^$l0gxn_oFqahZRn+ zcM=Ve_w=#%kqq{JL)Q$t43j|Yo6!%ZI_P7|O#G&gry!WJ5)3jBtIa^LWgs>gB1wgT zQxnOg_k4PZ*aJBd|CLV9tM3w!32@y)07<5;KH-9xtqsg&{?cQ&g@5=f0(K*Ahp`nV zJozd%bYUC8-V8kFQMG41}X5(eB`-UQ5Xme&ZL*PQ5^eY2g6LGPaxT@+=#h^ra_V&YUs_Wl8CE z59%SP=6%C zvbj&{y$=T#p{EjB@v`wANRU`acEZ8LZ{^1p<#UB!CA?J`oeH1Ry#p>fGRbZs@M5UA822tCCq2YZf;aE`DmsiBDXxLu>I1h_ir&3s?no`X9)lpw z#ixIYZMUeiFtuqfbnRL@u(_l2em>Ij*#A}a4dSzD8vGqoD@r)fN(qy;t%f~tyiivB&Hea3Ilqc1Z z^O!n-?2{pDDps)M%Ze6z5XwGcP73?(Pch-76DPDFVr3$F6^-Hvk>#@uXqkqN=fWa< zq-%W(o;4=ZZL`E+ZkWg+i|bI`yNiw(+Qi&Dl(JHHp7lU&Yh_{RSPsnNaI`iaR*Bukqni&kOd9slOqlLY@=#7OJ2M_(p!mB5o_lhk9BP4@ZghYj;a5jyLp< zwpEV!2H>bu)C1f4xPs~hcM0*i5=fGM$ZLkmpK3<7vLJ)pbofNkMVckA3vcfAS9i^l z53kG+&lE(qKUw}aLa)?;WqcR-{R-uuwV+0bIi^?M^ijhT#4fo`?DOsF8Z3nKq4bR9 zpx4l&2g?)3j(igOqr2o*`WC&sW>h#S_X)^1*BF6j)|2VIolJfxX@m z%F5eH?zC!#cn`j#S3iBeH-hb`S7p*|3BFPy%|wMP9B(7 z%;@)RxQl)sbn|-pG+ME5*)?z8eBr`tuz?i}eO}0|9TY1y))~p0Pjq|2nQxgLXP2ln z0Ksp~sBZNe?F%j{+c%VFj2KpAKa|AjCHkDookfC+bG5i@Hv1YD0uF3X|GAa84OXEE z0vMSo!5O#i&}{G+ATqy}-UclHFL8JdpsK8C!puN$&$Seh&0rDm~E|*^u=n|CHu(K&e)GGY>DV|gRn zTM=8NxgA5*^w>poEIwVLuKrU=di!N}mNzm_ zhu>^FHCRt`%7uJv9mVD9(=vO~c zV0Ducaz{NIOLlE;^n8)#;(cO5CGMBP3G`F@^vPK7g$9dX7X>n+9TZw=g;f7V%e zKDbqar=GU`GW;b<$9uT>dj9H=I$;cXEV3t(V&vqXDsrWpRra~*$wxE9Ce&WhWmuoF zKSsv!Tp~3W1;~|t6IzME{xzC=SaoF9oM)R>Xf_dJVAJP|<|-ZiB_>&V&0!DM#KfK= zImkPrbc*&$`p8tdk2eQ+gLQak)+Sp)M42#EF+GlqsMA9#$!5uER^K7QLz5M95#F`G zpb?UCDr+d0zTw3;3#ObH{)&ZHAZJuLYnNkk&ldbxx8gZ(@#uJnQ~7QGCe9niI{Fa4 zi&2Mmlbg|8ELnBUbJnz{EBV(${ws5O!CU6LhQmDFJ4??d>WVA?NB;HPfn6QDS;+7O2kH`+`@jy>=J)K0f5HfyvribEgV>E*gd|aj645v+!M% zHP-@zQ|zhuC?~$h`M53Gq$u+5Y*L8VC2x$)9EGxI*$;eF zp%fUlOaIEKBJWa4Qbk*^t670a{%*)T32-hb4<0kJh1f*w2h=%WcU&DYVxGV@UxR6r zQ7Q@zS~b38P9fUN+Iu<$j`#QwNf(Q_9RF&YLgx`aLa}*oML!gCKG4QH^wDu2W#1jT zisQre-@_3LY6mP%CEVF}g`6Jp9x9(;j6~r+Ay~V z=%2z^uW*zAIa`2p&Y0L+0YjhYZY7|P5D`3^v=;&PpiW!oGu}xz8u_JY&mYO9Wo&i` zmz4b7{2FqFb-os^g_Gp{yx>^;);-FJ1<`NBW0D8NnW#E)G(xMWrMAKxPk&F@e?szx z!+bcPSDcs!{cOOh0d0WZ01M}Hwik~J;DB}f88@y|Xin~V?%c(<;XWWTft!KOXO4Lm zOaYBY=)j7hSHF_8qytsW~eFw3*kzb*bso>930;eMJo7#-R79@+4+ zZ~MaBC&tA3Zjr~*k}PBGQ^<>dAw6#2|0(@hTcQ`gagp;miUGa){(+$LweF)G=~mEm zp@Z!!9XDKFBSp0UJlSP}N~;1ONPCq*9rXbLUjN2E+j zzibCjgXEKV1f2<*k1&r?PS|`_tdDurXI|nZ8(CEYxea}H2cmj=KXXbr1?+sM|ep1E zr*_}Ng*OBDd;*-oE_%Nx?hWej1$ENy;JKDRdJF>a4$mF>!PLW$3vgr65i$Hr;by$} zvPYuRII|qKEKDqRr}7i)`9ya1 z!{Us9pReq>cDM|D2KS`rIv>{orn673=PJ@v)3$cy<{oJC+9Ygs^>gRgv&WJqTVa#V zudU_b7_X8j4#>wEFlWgB3r2Us-QHAiS=6$s7`_!*zoI}2Cn!Sz ziGMwubHOn07^0>>rK{7YT_ z5 zaN1AF4^Le1Cq~ih@6LP=8Nd*XPw1UQZoce`3zHwrZwClSk8jckcvaw=*MMgNUo7&E zm7ReZxBTyQe)xl3!?{E8X~J7YwQtv;hWMBT@9mwRDz63Rz;ik0jz39dKn6SOx=7jX zeyluw!hl+igmDk#0+EZtZbSJfKl2^lnWH>|+9T+1ggY|l&Rm}mM^5GD9T?dn!hU_u zl9dxo0hUfGrz__(DjKUrdl~fXe2dYrRt=F%RS-SSgr{-WS=XVGh4~?#FcH%Do6U0p zZ-)SnpKC6?`v!2YyTmMd*K^~Vav+(AJhnSD70Yns`8V|oUEfv2ZQ)|6o{a3J`w_w9 zG$Mn3)gjb_cL3=x!<~$WLZqU&H$qYh2IW$&+)zA~sD)wr*f-4UVxxY>Gt0B62d(sP zCVmU$j3_R3LW8H0^h-S$P(<)ek&RG z=L``7qU6zE?pFTjfdwCFSG<~q+4fHh!KShM>NLGd&s~_VsC`86#xKtykpz#yy5fge z`%OE@-xDnBSMKI9)GT;Wt%w&PdmFR{0TE^|8=M`F+J+Ihrb77=U8Gou)D!`6T+uS_33hMv@XM8hhR82H?J z3Eod?&Cg^u9wV19f59Srg*u?a(qDmgCZ|PR{yyh5B#l}x?I_D;;4SMimki>*$~BnO z3yfy%5Gp@)Jd6B%Cwnr7w24lY{@~(5HKlPA-)4GL0jSH0xckjB26Q8T7vBx_N)<2G zLE3eW{y|>I_p}f5rL~N>hYgNM2WH<4VHz`_p;dkkEEqNR)D(shMeqTujz6aPVv*Fw zw;IuWb3XW{HG5licld2hO*U2QruN`DO-m==1nKZT8El$vLBWOgL3=SB@_DkPyp&_; zvldZ&#!PP1Dmh|rx%T$=@B8GZi7&vu=)=0Wr;N=SAhx-H9F(?O z*YkSZFCFlUB({0D9dT$6#eUmvwoI!I=>4r=`vwMG)+0}#dmewEzVB~fKX8L+F=>T0 zOgTucmr!*{CQxa#C_{mqtY4-jqT7fN_dFBB^m={gmf4POA2Z(Hdd~{k&{^N$FAd(W z+nUdKlbs|xDbmQi5@EQDTbsJfroC(v@0=cxtwS%cCu}zw16%<-3%~lxw*M5|+`F1X zb%JOIHq(XLovAt0ittnsBrb1L&2U6{=G+=aMLQyR@No$YsCN(If$sBvRV%#tLFtA+ zBYH?TL%!2^g+~hxhdSx$H3VBE!X_4+&MG<4U0h)i$|m8Jlo9ya0^wV!l4q;R)XQ~h zd6F6yQn@Fcv8LuC$5dd!6qw}!94+$(=@T3Pz2|-h^g#D8-W=c`IR(PqPJuCqkv%f( zATC69SIi>+3bWt!1<#rBR)OslIvjV>V|J5Mf0itNtKUU@#9Q-pEbh$7i2bAjq>azc zN7|+P{Z%8?Pp;~@T_3F2@Xx&Zv>SpL;t0F%Num^HvADD#aYNMHJEgG>Jr8iE-?aNfTFf9TB&%RBuDV31aN z@A|x7ub3GTIyhTI2QtGOsSfHQWDTM*Fv=ErrW?8dchS1SL$=-^7Cr8#+yL&`bj`-v zdsSInR#M{Jo=*kLvI5&DM>*$FpR4r(Q)|u3)er)O?qxL(_)@nPk(H}T^SF@v9-@PO?16Xmf%>y(KT!4H&TLqY7NKIU{p`PSLR53Qms|>O?K+p6#71Oi z(^l&_uOPlA{oj?HjnT>ayfzc2b#66L%um1$=pJ;ojb^-uFbiV8yWC5+G2djB;ynLhY(M^8H z^4kcW#V+@pH^ogh)&&i$<41zz>xjS}*rM6us`j>hTzgB}V{U)_FIv18F8pQJ%wr#zP9DwV zk^bkUcHb!*qr=CmoQ-Hw)$6a>&5<;|wa>u!#&^%3Y&q8(z?)>8SI&5X72V72Sewy| zn%3tlBhPP_SI$?6sT=0c2G2=X72KMONfh`#6`n|(D$bP-YHpZ=KcZXmYIzbpD4yr88!O>Q)v7HZo*BR|G#{tbMV$fl&h9-f=$mZ9F zXZQGudSIm)yQ%c-T=oMg7%RKD=e+Q{>S+|@$3URGi~)_+GN3v~ZK{XQ0qD(-oZLl- zCgVp`%OQQ&tP@;V^gUuFfT+}L%WFv3M@H;N7I<(#zbAbR6_Gkw-=F9eg4g--H+u3TG%|I{4(8*aX6P=jjY``dFRlq(Jh<57 z-dS9B*k?zsHJLs~y5N8ca4mx`=vppsJqkp+IEQu?kvQwxzUYQFv4%c+f<`ow+OVY; zwll06W2joZ+K*g%eBfB{u+JO`;!v)(2`_P7-1l%|Wc&3&f?MzhWFTU-x~h}`#%Axt)mg7~FS2$1hQ zo%n((5o&DE-n4{B9s{Fd{5*9-oR5 zWi3`tSYJzq;^0 zkMsYxpZf2H_TP-^=cxZ>oc_a6u`sax+fgwvv9LpNaIpQa85KR-|H!Cl7#L~)6QyGL zuPN2P=+6H@ss4d)|IwfSEv5SRx%-i1{|}||{(mWzG(6%_d^xxgg``Tj5FX_vxL>Ed z)S&th_RD*^P68{(0uovS7n81gW@h>DSbEPNHokI9pzEkb++zDDC^zWNI_k+*R!S=f zR~F_N5(RBKCBMA-&5^MLvg|p z))AwE?rlA;N^6D+cbFP3qXah8NgC%OCa zqe=wB;D=2lkjK+g7y|D_Nm|w9=LQf`8nkqr&(P#5Bh3J;vG4dHyF?m#(w&H0R1}NQ zt$kuDK5D%ylYm%#zIHw@zjsytX*$-=V!3R3u7*MYm=Pee!=LCpgEG%>?+PP<2Q<5C zb$T_HYPagA1Z)HaD2J!ha=0vFVdLdQ?1_@G2%$;k^W5@W)}sSpUNY#d1y%p8F0!Ah z7xQ`(P^6~qh~MZ+aCANRHJ4!QXxh)BqR!`n?$_mVdSRJd@h$ZSn*PwzijJn+>+8<6 zr5YYUn#I5y{Tmd(7ygC*$ZQlG1@F_bvc)}EuHzUywGc7J$ z9~V2M$c}9z)>!4h+6@Tlckf+)4prg){(bGlZzu?qcn2GFdq z*_4uQqUn3^dB>e?iOjBPK2TdhJjlDaHjYl(PLfZAglFQE^>4*C!cG)VnNYY^q-rr3 z&fS(9H1mRjldp%%FeR$JTFh*JHt|I8t{+MRs`ZV<4dA&0ZwJ8}G!03BrpV7Z+I~ zL-fM5TbeCfF#ngV7rbDHFg0*tBaEE~5PTP6Ho<~1fq10K2)r}m_zgZ+`gVsO>Zf3@ zFPoJ>IxiU4Ey-P`(jonuHC0OI-U%=K(`~Ah$?YKII$1usz#t&5d5s zmfZO~d~r^XyLTKg5(=TI#je-EvDOVqmmVSo>EnSMvt%SkAJ)54S@}ci!`Z|5DLg*N z>xv5s^DdX1A4b??lO5AVpjz#<)(tCmXg5I;`%nF}!eC)RBd9dVYGLYZ;_Wz}GvTkr zIg-W<+@t&rtq+*5vM(J9v2w0Q8Op4!Y}sNx$?mcn*I!ffVc2G&hqa2kD>j+O#_V9< zu-p6C7D)Ws!wI)9UGO_EVk71#WHg=eSGndkC@ub6Bc3ndis*&O#kk^+g%$J2^3Ck> z{@~@e7~ylwIBRwndPFRE{?;RDxQW@%yEOwcABCBjVzk6ng@M%g<0B6B0hNTyL@GJ> z?IXN*ysu2JREK5hoN=-WoGD-FHihjcfN#7!Lx5~amWQf#6|K=5v{yJ+bR9kD_lF-K zU4h-n-LjyRvX={8?rY8-=HHoL;O}~pNyX`kkxJ)^bcI`T-pQB&+XOW1`9!({?725ph_~5(snht@2Z~;3aU$a1vh`U` ze@sX34?rE_It0Fic?q`V16ES@kcDVcW$6Z8-QsLYB;F8tx97hn5A6rFNz?`x?QvdM zEnC-byswUVcX^K~u6L+je(G3!si2mmm$b<>i8%8=rk_bQ<#w@K5>2TieAwB}p}%n2 zKw1S$B<^<=`sUj^0P~3Wh&hfzvun|^g=Yw3nZuB;hAMWU2v4FlRVJ4~1QZ8G3$V>2 z*?{E?W9&jLu;rr9YMFy`%Vq~FIZ;clscdLDQDqHU?_TeokAT-=9)nmA^6>*R$8jEP zw$}o2DED0+Y?~03H*T0ODq2X^>~_m5T*;Y%iy@A6%F+^g8zDIpHW@t7Lg?$_d;iJ_ z#e6}O{K91fwsglhiAmW+ncNO%;gou#&AEKaP~Y%?1TDdzS7w~) zl6mw#m$pCO#FvDkg#CE)rTS%?#Ik+n;g#Z8BSwigQVVhqwnxjiEjMa+%lm6iP*q1& zcJSN~bbA(eA^MFBhSNfcQh-*jV;I>El0oJi{qx>1h=7*eG$aIPzWGWSmuuMcg&aCF~nZYw`K$kl;X#DR!nO zZ{2xpQsxQPtW|prSTSHdvQ!IHZ?Q?_H?S>E;}YC)BzWnVU92F-Lrn~OF9<+!Bp@R- zr)>TtaweM0t9%#uBl%;4h|3#g5Wer{{G|EZH z&MjmkH%Bfu#^4g4yaJU`OmGsP98Io3tF*o{>)UOEc^i`7_wtrta5{xeW&TZh3Pp2G zSk0MFTw397gbrE-887J}Br_=?R~oJ#cR)DVa7;obV`FV|H|n4zVV}S}1v@DrXy!DB zq>|2Gz$l}*nYuteFAlxB-osf|@$%Z_`T#{=LS&JNp3dfJVwsS!IdoJjYQI%nc;04s z#iW6~v9!`=VpbKawSJ*XUU#w9WLbEyG+HHOX^hs~wEJr%MO2e>sd;C?6(4a}F3FD7 zLrTjsVIx3E@*nZRTVqped3wj%BM!BGsX4=tZ`PI#mza@_5OB>7xoU7g12qQr+86$A{k@Pp5NkY~iEhcx!qn9=U1vG1^IXKn(5B_LF&Wcm)QjCi& zL_vuy(1}r3;wJY%U$kCxTU~laiA+8v9zG>L9}BaOgGkMyqb3}UwU`_iRazxIF7*@{ zlFR6-%vckpg<*;&@r-ED69W<_FLJ6)JS0vIyagfY#NrWCJzW0-aH4GCUc^5-eMyp=XbwIG zF>zUx#wbA1F9-Qn)yjI8QZ};*2;1mX#?m>^3O(5rVG0TNV1Y`SeZ+pYXs*6G55m0` zUa>I?9rWiG^79rt2yYKL=!<<}_1Kduv@}H2~2U5aBQ%cv`y@N5#lDTw%qGU0sSSFeas{utHLAx-|{($!e{4$yaVOGAUb_aNb zTIm_Zo#%;}O*!DbXf4AL+H?r+a8yNG;W7M*pLkLH^@|oN(Rjp@3!`|dKE~}{%+qw^TO}@!_W*u+6|Tw)UKL{O;EDX_mhqE1 zOxStnOb^`=*^cbnlCWL(TkOzvRHkkTbf5}I7FwldGHL1(@T^{xlI=O*V-jDhrtOW|`iBa4Ek6}@>h3EyW+?y!a390LW5WXiB?0Vo5BUy60&DWZ>T!6ILzjzaip@hm-RBP*9Q3Q2B#@ z5qWBuXO-V`5)=a3>>$ zKiqfeFN>CWE|KrObkhSRjIsr4$ksNn`A$g&A@TU_2^9?~vemgO+%#_A_J{`03~VV5 zKUncBZCWPl=^AQUa%%6y#@8O zUzHkNWz133a)W}+1_L|@H67^@ydH@$qnoS#?)qT`eJL~}8ru+h`QG)=jWy={q#fDn z0$NiWAuyOc3$8p7QAuJ+l!^0C%v8b7raj$mB-wccQ?#wEH4ffBfAkehvAXr-0c4Ci z9J;BVFVJ?$ShsFyZ>7_5X+K{;-x#Mh@#B;gD|-7YV|H6PlQ7bNIk63>j9IGsh(nO1 z8K^t6<`?7~(51~MF@4I@{3=Iou`#6zR9a)ojMT-49cmSo!1e;QL|y)H#fHIHRv>J^ z;5*It)Uc|e*M`V6;6I@B`Jf9L+7{$Q3m4E^JRd5-BYD(wQ37tl=W4TvA77~fH221~ zk|`{SV|**C0-VtI2~S1@bszW!e`{MLXjUcN&Ww%>tf!h>2XrTIaGxQ|lmB}Q_r~oF z9yTGiFXRF7ORyUGS*Cv^bKt-_T?}|#@-MdxF~WXLt=?tl*fPb|UZ>c`!DjU;CGVMc zxmC-NhGRC~o$g5GXP%PF8VIPlK=dzSqQZ>z{V%ua#=fh#dGbL}$3>t{%sS>1Z zp>&LJfJ1FhvZX63+#h{)g5C0{wmtpM1G7Cs2Q9#p3ZtpqKY8lpy1Emn=tEIMK(_<} zQ;W4w$l?i^^c?3jj1+&)55w=MU-jKfI`nu6EsbrfEWQ6$nmmp#z*jt1#Fn}@nYzt( z38C)Ys&yLB37L6Uh2YmKDjG2W@Xn7F`biplVsIo zoOQ|BTk}n@{Q+0^?-DsfPb$l?Su-uYkFwrda6W$@SR-?B9Xm;I_7<^Cdz;PmZ;q!O zbzr}@+-Lv22&kabYqPy-g16Ci*_=n)Z9b9`JK1Ed*!szyKe_SMFReS$trZ+zM{!J- z$^aerOfvG0LEgk+_R^7=q6{1jXc6!-TlBRw2=0$lXn905tRwDmS7R^#{zVq1)28 z(-+_()>{7u*_vTFU6U%Ao&cpv0Zg<}{x0`-uu)sN&b&>k7_ABogSLd)soHA|?8enL zmK$v=*BGjt|*BmEl$dtAPlvzYvJiEOwqF47UEp1Y;Bm&y4_`LdjS2 z`=4k!ra`T|71pa3yluznVVIYnoE6?AkDrm?ie$R(QLC(7F{=slH9Q}9-?#KY7Edk* zQ*H|rgzR-%OIXy8Ft8UTf+{+U0oud1e?kTwzT# zZP4V-j|C`U@pRBeL$*@|-Y`jmW(mR7&APv)|7-I47>=AjRoF11E}LutyeOZY1zz4#W_OFQ(t&tS+hS)jPutforj7*vfUK>;CD zXflzA?;1uQyz@{V!J<5`Ji#+9O=z!POGml$e#@J#tJ``CO9?w*k>xvnc}qNtFoaEa zN18)g>I>nf&C8IpyW=~)-;gYv*3#+0ps(`{jDb<76|t-{YjYjHlh6CDBOg?x6<#0e zHyEly5@J$BLhjPFiAX@r#Nqv49f9sG4CYUQaNAjw42hXD?mOl-?EH6FQ$pdY6u;WQ=0<|&+Ly@R_9d^hjwE)A#2y1pHJabH5`4@N1*%8Hx5 z?7QxPnY__KlV6iTY#ugu*E1VdzoW(+iX3gH0I&Qme@_W?YrfYnQc1J|X*n9Fgrrn~ z?K9h2QNXW{ z9DnK(VZjX9?q$#;=Q*zjpY9RhTYpd8i=8MvL+((qD<%8A_4(=u#78SUb(x&b19W}K->!?DOXLw9I zEOR{4xN3ABBW2EORgkQoU4XxURIV0DiUCFT`vZG}E zXM@2~Qb);?Rc%vF-n$XyTu@vUK1yz`i%)%3DxRMv<;F|DV+`<}D3est3wL5wTS(9En~3z^V^*MI$DDw~K#eVc0jb$Lvk^xl*5<0BqM zuL!M;ZQrgpeP|vGs@1io@&yf1si^Ifck9)-4*uL~i%rlRJt zEH;;qxFnddf*8lEE>` zc^7#A|4p$WiJc=p&3hYOh_!SnbFtK&^(y7qTXbtuO)+SpG2k!UlWrkz+YqqSPusge znWmn&KfOT1`Uq-wg{V;c&lkjqQ)zys3IbB}3-tVWI{h9MG2rhH1lqbxb>JgCSvHexqLPx%Dl7CZH#hzK(zkdrj(yqeQ33eu5g`brnb3RY zh{}{TktVIkssd#;waAS1O{Bym%3PPP?%Ou-ZCuAoC)~;Tdl?uMLk+U&nIjRbWDE-1 zqqYKBL_n^HY&UH$?fh@wy)AC^CUIlL$#8jen`#oJnbVOQE5}Uip>A>K!B&am0%-y6 z2rnb_yV6ETs=F=;2Wf=x!-1@>w@GXmmzA-h&bQDuht?p0){x5{#Nx_yo%tOA;7Q22 z+8_Ii&iBnR6Pt}^pB%Q_dY=aci@Ve75OvB20X z<-GynjJz+#_k9Xcx0(z`o@!9?L%=pt<(QY+g;~uU{er z^3LjJ4v!6^piM=gpdE<>4943LV<%gb52mM|#hJCNl0bw55Y#RQiKv8u7;%WiK<|1zx=`Jk{G0|d3J!M_=hh>FPicv*WLz%fS z9aB{!TDl$j8N**az&*e0KR)S3Ifj@T$QhHmB$3;n zd5<8x#pScsvwh-Rx%!Tz2B2O}-1efaSSU6xZhI1DTTmEMr~)|d76cCSn5w!^aU6q$ z#W_-g5lq9a(soK8iJ>|(Ff68Josqy#tHwmi*3PM)`8cRpT*gh#^NBMk;U~*}vMjRZ zsv414EbuOnBeIOaUWT7>#3aRJ;Iw{VYNag)`6yD|$6MJ9lUA^tfH_6`iK_~vl3$>+ z_wHj@z^78YU~t|1VcofEpy_d)0D@tk7Mj4^JLA`WE>N2jj6|{@x09-J4>B$!vB5Bw zP{*X1xan7W)fo}JBFG>;EWKscHX7)xHMsq=g z@i@tuQ%#JKePnZmjT)(Yi2A;9_$p4!X9U>OAH{uG}}O z8;H!CVdlA^cGot}P1gw2V5`|Luq{q!TT+u$C&S9${A-tRhtd+O!&w^nLSt)QCgyNi z?W#Eyg}xdch59kt?G6Wn{XKzNlKYYyuVwH#HN6_@AxDQ?umA;eP$!?_9(ljoPoi;loy9@*X*p5aRqZ0&8FmXM`dz5 zUTd47b}Ge=c0m1exUiK+zMt1C(GJzxhAPy{%aeYXahpybVjNSc*;wojj4IbAXX(mL z_4rV^r2Y>*x-5^)h`cWyRaMm%7Sy-ptmW@XjPGh|m3^Ae?QA0alkLqc-o9Z4L6{vv zL*yn_vTGC_*(-bwGq>0;jYqunXPE!i+E<4~-L!2ZEg&hK(#XNX0Gd+nOzRfIXBvp zUucMA^siDsrrw}Viq~456mqd<6t;|VNtJ#N>~7p|TgcNiDZdv?!6~my{t9Dxz;DY? zNI%A5(#!=jC68jvBFVGiH1ag}G*BmdizDNpW)S;^`&LcO!9jJgkqSukgPE)RxCJe4 zwYJKXMKJ0#!ye@SaF`?6LU~lq6f?UaS)TRSvWHvkTVPXHk;xq@t?_Fa(+kD0S2R`! zG*()^%Z6M|gNsA2aOpKn=57`iiA3SJ4ziX};gLg?)(+N?*4k2tdn_t%X*Cyn--ne9 z_4rY|&RiASc{GdqtmVT|g(XD(bN_y|{dw%Q@e{8N?9weuY9yDz@pm7llRg>wh>~*C zDFozC#OrR)ZYS~d)TuY1az$F(;MRbrb)IKrMx{<+5PUva@)cOhg9dsQuh_tx%C|=EXSi z>8fB$zXS^}ApVDJQ3A_omR!sono+(l7lU!kbW63(j;=N9o%UI=rb`)*^2$|WI)2pb zo=O%f9Y`LnGbW|vn#&N!`Rr|BrI0YscwHFV_pgLl8aS@)PUr1|cpyVuu3ar1H-oI^ zr-Nq39gakU#yl8y?df*~vCWsx#7UJe2JC1bb_N!Y2ruv)r~Syohv8UwtTq*Y3|WeE zs6Wd8k}|LIqcA&VkBRqF!+!8b#q z3&V%o0qnrqh$FU))sZXnS&s9KZhyF3WZwDCX|MiT1hL%n_U`mPtzvxCrxF=jk!G?| z8p_f-snA1KOTy3dwkuPf4oTt(g-NDO+Xy^%Q3H*B)i{c;!%oW&Y^E(g=bTIt1Y)Fb*E}d#qKBGxE zJDBtCqJlvb!u0PY4h!kc6j${3g!}hW7 zmDL?g6m_!a`lZv?M6~Gzh?dpa<=P7B?L)K|0pY$I-MgfQBE2S1C(k)#`dIG6GIjgm zqv&M))JKYn&$_&WQ$HG)5dr)5$#(Bt@Lvc^t{zoAQX*_4V07{?j8@Sjp|I;AP{@2= z`>-W%Z@+9l8rfayT;LgvpyeEt$dq(W8J(TQ3+?z$v#%>3YhJ95H|?~%Vu@Y%Lpmti z_1G#UmZDT%&m|nA)r$?&tR~RU4s4Nju!T`G<&q`0(mt55)4ovYXMBy69{HNDkD)+G zN|-NYVUfteM^gzovMQGH3sWz*UOBhQWx-*1CjAX4-Fd|<=DUVw1>cN|KvAj4lxyo9 zqQ~Q}zfmzHw!8@zC{<<^%vXNfq?*yvF5O)s_ZiS}+pH;)gG%#g^ITnHVz=C_R*>si z8Q0`nr&{%x`i*803$n-gdwb0uNrWa_r@i*^)3#q#w4GORO5=BR-JpHx2Zsg4MI$0g zy)vw%6{hEoM8tQ_CddYp-KE3Zwutp5U3Y%0;K`Pc zUa-F|&H_I$@X;T_F*jE|@IQ|JYCGyd;;9QfETn}e;%DrV#eDvj6|v#=&2YG(Kr%;D z-~7|pk6mXqCzLHeaVziL1NZuGFYN}(^z6~uMdH8hH?G9jNXgx$A$-=wcD+E7irB^^ z(079S8PS5BmyieREh=go7uEDLf+c)}YX5HPIf8c|L*fUIF}?WV4WZ??^Y5H)WqE~U zHwZbace1ag$|g<&+`T;mnhFSgXDo@NR$fZime_G&(b-deu7B56fcV+ov@Yd#0Wo(h ztaobL*L)em*<=^}tIA|iO*giW#1t16#N&3s{5eI9BS}mnL?ON8P*JCy;G&-nC}I$b zl67B^lF%{9N}v7y4o79-tIpHcIM8_OFu63SRhJ$IofoxPG5MZ(ypSK@diCA;5`LV$ z;2~B;C!*a0K{x)nBi)J*iAE1Yge@c4F%n|FOFw<#ul|MU3+W9}6G8aVD@2i3%>B}8 zC2iqZx3jjMdEZ*)H3ffK-F0MuSxTB_0jui_9Y%^y?*oafmxo9?2|VIQl3XG(Rr{9X zqM&6y(i54^;%$rLq|HVci~aP@M1JdVufl*o;mkx)$vnL|ed$JK`v_m2p>cbf8kKm8 zf`y7IEs4pdn|o&fX;NJ7m`c^8>li{oh?YIeEV?&ZwmD5Vba+B;LMS^yoBB1OjA-c~ zv`&DG#nTViY>XLW#0zrFAw+V<7~R+?tmS@cD=1H=Z}3fcbZ@C; zy{Pk+N7G#C`#5seaU|;&TN|mb8MSPke#IpIS~*^-#I2lF6VEh}n-tHw-Uc?Qn3|7x zepBJIoW4ipm$pWp6Brgd89!b%F;luzwc4o?n}i<)LJ6soi99c>zYou2&?NS{fs`=N zsFG8s(|2z1gJf^z?q(O?vV8e{H650oCSIMq94AC~yN=;>Fw@{`EeF^`bHk0Ax5EHP zRmAp{Ow}_;mDJJ=a|l7Pn96;Bn<)3>^5kU#x)30`#OpU1ZTxVJp zOrXk@(i9yPbrZRm6I)P1RO(tsGrdiX9~GJUIQdYD@B~x-Q$c*OOXzZkh{ZOjRYShu zedU~LS)$=wO|MJRYMH%nT6AW(8udDu*xUOWgL=#ZuNH-QlcVgLhs9SqC}{ zxqClXI&5cu*846T^-)SVDRjf!e&KnS%$TeblkGlxw~bh^zf~m{SyuUKNDYCkB@4p z=b8pwr?Px1NOyiB^Xu@ClJB|R;o@!CpZ%%uO~C=rijNNMnYR*p=)!weag`oxkbFPn ztvgQ@-m1cR=1DE4-Wj`t`akxWVNkK#IjgIPcPgSDCvat-nN0?~ugZJqqs+{ZpS?FY zBY0cD?%feP6bE^YzVfS%rB+@*wAn`5zKux1#Bok@H#~%99Nj|?!G)T&C_;;?7dXooO0LImJ*gd#$4$_ zmL-13!=N<{C$)5|CjC=4C7zM&!*_=~gjyT)4WlNX*5nzQLL{A#!$3H5GXEr5QgR44mo+Mt&VlD1G-q%v1MMHRM7@hVG}%n^Mqa53m_zUV=7p%$z<9@G2M%>4&WO$CDE5=`S*j^h@BUA)W5w-&H?-nEJh zr7Bh;_Bh~-*AC6y^_=vU1s8bLK9Mr-Pw<5_BcED7f3D3fDak-U^}_$KTaoAHO_|I$ zlwT9hJsU0XRD&s@eAfyM&4+-a9jg?k211X)=0*468jr|Ai?8!LwT(|{cSKg19_8Fq9rZXfh-vZAL#(lZI&Zd-{Sup_Z2j`9 z_=$#@ki26i*eb=2Ge`y4PhqVo7x3s{Df}$UIy=#0xK8kyhyUfs6Uu4!ho(qLi{VLp_-_JN!8{fSpDY`mq($Hlh5KC-G zCcYV9iqEslW5>m@O>4{YaO~cU|Kc`c#5O2l&KoXeyDjJ?y}2ZyO6crBS(`96k5$r4 zq;;d=g@!wgh%xYRjM#3|o=MU8+CED~Gm{pHnzS#zl7H;hak($W|!)+mC$ zv;)rpODSm8hO49k&N;EoeA4YkmcD$?+Y>QfHtjDL8CVvYclHkB$ zCy|@4;}2R~;`8d6%p?RRz5Y>2_Y4?H#WFUxwO@UF=)-x=?w@5V{c)9b8d8#|f(06z zzxf47An(Y3m;t4!VEr!q8FM))U+kFz!)j ztO@g-Hs7IXW4m_5nGt}}x)Y=Hff3}>t)C5yb-^S|zHUb9r_LrV6|~&7#u!@o_gM;| zEx5@&tuZTK^r$S1=49*}bw+ef&K{kcg&BHzDy|{)gMdIj#(XG+PwW_t+=z) zrli9p_2k;{4}#Xk@5te^jRdSNY4>xY0oK5Kq*a-<_1hN=?&}xC!z&k9HK@1nrd0i( zeeL;uf5Ckn>3n&v8~x(*1rR6wB*7q~=GrMIswp4~$2>N;)_G1SH8+c~gw1V8N+?Mj z8Sz7XTi5q3i`2f2uW)L?uF&R%_&MP(oC|-SriMAgZJ}f8GfBLfxJHz}hVn<#_`}uc-{0Q(t#O|%eZpgE5Mk}Z=p_n zSlq&7nTZ1^R>WRK6l=TQ6fG4H^bEh$^RMqyTp9l?`=(t1txq^T)!fUvW7TpF+_eDF zN6?)I)on=vO?Lv)ZDb5<$%Cx=+Cephb$nPq=|yVR;rl8aQ{Bof4)x^ys?EWQH9C3v zh3^u0*3A_^7$}Td4)OETljFt?G~c!-fKeXtUb7d5sRVO5_SL`$9VmdG7YJ+iV%;%e za>1WFoM7#XrD-=79rZ$@B}w*_X(HOhLOL7-rj`A6UoIzRyl|=US=REPSQrR|LvBTB zb$JFB;>*WIYtt0T!2=t41g?(;-e;4zp@(&NcaG*dQURlbV>_?oeRx4j@-VKWZ|ZZN3wzjbA{< zBsUiP=EbR!as{~O>FSY@gLEO}= z-7k*wv1&0eWe2;0&hdjt!&w0St8BpCD4LUF|C2FEL+fmf3GaYNxw!|gb{)^kCv#(G zt_7Ce$}0JS$U+7=^#hs>Jj<2JJAX%a=?dE4g>reG*KFF1}JWY zdBb;wJLBVpxl~&3RygJ=uc>f^D7 z-ASy#o3l>uh3Km*OC<{R#cKEZp$-P>KZ>fqYRgxE&tu-O(G%Bxb|k5vGEQ9L{6Q~S z38@vR7SQe@U!SVlxr;c=xHufp5kb~klQ8zbtr`(ORneIgdlC0dG-aZ{0_%ED%As#B zYc}IuB;(!HioKzEq<)}mlI!#AvxWiqr8++MSHvNB+JLk+jT|euo1rdTyxQ7bC%OJFnN{jDf_5? zWnT|TPk>;+6ME1uDP z2ka>}N+zMg39JX)@j5iqBXAJK(SracoSGJ{>M&P=o^Lm;!@IWVy`OooG~mfp2v`$^ zsU(wXsVm4RU=`dJFjcoWoCTJvZ_%5UJrO$bu2O6?v9SWzq)g!v_zw;*6s3y!zfy=mIEw!Jf0aUn zpyVL`RSFS)$r=4W_`8=fk(a>&frT$adHE~+QWo+z282WZMt^G|{zg&s;s4Y`DN+8Z z2^5B+)EECkFR8wNYJ&d8{?hydqG%g`_xV@zO9j$DnexEc(%hLq=$^Hi^CeFk)sgBS z5m40Qa#*SaD5c2Xk3S{QpAt&q^AZIADS`i#P*m?r5c)^N@wY^$D#35LOw~)jqGEv( zl>~zRAq?s6WNtwKU_r@hqO>Ugd1_OXs#sUxq3k#!TU~~)$yxJBBfkF{i+k#-QtMdS$ z)K1aHjM6(r#}H`o1w!C3G#`Lb(y&+Uf?)`B3=Txc5O6f#Ljka>b3>&Xx(x^%-3A1K zZUYMV7aPJbG@n9Y2sHme;lO{vKxh~Y0JxfeKqwe3PXVZKpxK4Np#Orw(J|CEc*V~^ zC=@-ua5&;>Jpc;&7Yu}kAyBfjXg1)mtGNLL2&3ga3PblZ9F@^m`vZUgXfX$X(QUv0 zFtmE8?GEd&TbiyP{03^bpjmgUuY5C9b21{{R8H$i~t z7!VEvU(F#X7~OxU;i0W9C>Q~`>QhuLz}2+?2LObx&KC*+qOBuT`a!SeIO-GwU&Y`6 zFyv~CP#BsIP-h<6`aogASLchu(AGH$`{($cIvJxhnVo)Xj;mRFnxllYQR3rIo;*d} k&vJQK3;k9k|8sEvzAMDo>FMuN84kGAg680my)Q@bKLL Date: Tue, 22 Oct 2019 11:54:40 -0500 Subject: [PATCH 0220/1772] Switch to the Rust `wast` crate for parsing `*.witx` (#124) This commit switches to the recently-published `wast` crate to parse `*.witx` file. The `wast` crate is intended to be a way to easily write recursive descent and composable parsers. It includes built-in parsers for all of `*.wat` and `*.wast` syntax, but only a few limited ones were used for `*.witx`, otherwise it's just the idioms that were used for the `Parse` trait and such! The hope here is that this can consolidate lexing/handling of s-expressions and simplify the parsing strategy as well. Eventually it's intended that `wast` is flexible enough to have built-in parsers for interface types as well! The crate was refactored slightly in implementing this change, prominently: * The `validate` pass is not baked into the `src/toplevel.rs` parsing. * The `src/toplevel.rs` parsing was simplified slightly to have only one recursive function for parsing includes. * All `*Syntax` data types now have a `'a` lifetime parameter and are consumed immediately on the stack frame while parsing. * `Location` is no longer manufactured while parsing, but rather it's created on-demand while the ast is being constructed. This required a small refactoring to have a `DocValidationScope` which carries metadata about the current file that was parsed to manufacture `Location`. --- proposals/clocks/tools/witx/Cargo.toml | 1 + proposals/clocks/tools/witx/src/io.rs | 12 + proposals/clocks/tools/witx/src/lexer.rs | 354 -------- proposals/clocks/tools/witx/src/lib.rs | 25 +- proposals/clocks/tools/witx/src/parser.rs | 830 ++++++++---------- proposals/clocks/tools/witx/src/sexpr.rs | 240 ----- proposals/clocks/tools/witx/src/toplevel.rs | 234 +++-- proposals/clocks/tools/witx/src/validate.rs | 179 ++-- .../clocks/tools/witx/tests/wasi_unstable.rs | 9 +- 9 files changed, 608 insertions(+), 1276 deletions(-) delete mode 100644 proposals/clocks/tools/witx/src/lexer.rs delete mode 100644 proposals/clocks/tools/witx/src/sexpr.rs diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 2fe71c419..9a38ed265 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -18,4 +18,5 @@ path = "src/main.rs" [dependencies] clap = "2" +wast = "3.0.1" failure = "0.1" diff --git a/proposals/clocks/tools/witx/src/io.rs b/proposals/clocks/tools/witx/src/io.rs index 4f40d8947..f46ab1766 100644 --- a/proposals/clocks/tools/witx/src/io.rs +++ b/proposals/clocks/tools/witx/src/io.rs @@ -13,6 +13,18 @@ pub trait WitxIo { fn canonicalize(&self, path: &Path) -> Result; } +impl WitxIo for &'_ T { + fn fgets(&self, path: &Path) -> Result { + T::fgets(self, path) + } + fn fget_line(&self, path: &Path, line_num: usize) -> Result { + T::fget_line(self, path, line_num) + } + fn canonicalize(&self, path: &Path) -> Result { + T::canonicalize(self, path) + } +} + pub struct Filesystem; impl WitxIo for Filesystem { diff --git a/proposals/clocks/tools/witx/src/lexer.rs b/proposals/clocks/tools/witx/src/lexer.rs deleted file mode 100644 index b004acf07..000000000 --- a/proposals/clocks/tools/witx/src/lexer.rs +++ /dev/null @@ -1,354 +0,0 @@ -use crate::Location; -use failure::Fail; -use std::path::{Path, PathBuf}; -use std::str::CharIndices; - -///! The lexer turns a string into a stream of located tokens. -///! The tokens are meant for consumption by the s-expression parser. -///! -///! Comments in source text look like `;; rest of line ...`. -///! Words look like `abcde_` -///! Idents look like `$abcde_` -///! Annotations look like `@abcde_` -///! Quotes look like `"a b cde 123 @#$%^&*() _"` -///! -///! This implementation was heavily influenced by `cranelift-reader` - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum Token<'a> { - LPar, // ( - RPar, // ) - Word(&'a str), // Bare word - Ident(&'a str), // Starts with $ - Annot(&'a str), // Starts with @. short for annotation. - Quote(&'a str), // Found between balanced "". No escaping. -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct LocatedToken<'a> { - pub token: Token<'a>, - pub location: Location, -} - -fn token(token: Token<'_>, location: Location) -> Result, LocatedError> { - Ok(LocatedToken { token, location }) -} - -#[derive(Debug, PartialEq, Eq, Clone, Copy, Fail)] -pub enum LexError { - #[fail(display = "Invalid character '{}'", _0)] - InvalidChar(char), - #[fail(display = "Empty identifier '$'")] - EmptyIdentifier, - #[fail(display = "Empty annotation '@'")] - EmptyAnnotation, - #[fail(display = "Unterminated quote")] - UnterminatedQuote, -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct LocatedError { - pub error: LexError, - pub location: Location, -} - -fn error<'a>(error: LexError, location: Location) -> Result, LocatedError> { - Err(LocatedError { error, location }) -} - -pub struct Lexer<'a> { - source: &'a str, - chars: CharIndices<'a>, - lookahead: Option, - pos: usize, - line_number: usize, - column_start: usize, - tab_compensation: usize, - path: PathBuf, -} - -impl<'a> Lexer<'a> { - pub fn new>(s: &'a str, path: P) -> Lexer<'_> { - let mut lex = Lexer { - source: s, - chars: s.char_indices(), - lookahead: None, - pos: 0, - line_number: 1, - column_start: 0, - tab_compensation: 0, - path: path.as_ref().into(), - }; - lex.next_ch(); - lex - } - - fn next_ch(&mut self) -> Option { - if self.lookahead == Some('\n') { - self.line_number += 1; - self.column_start = self.pos + 1; // Next column starts a fresh line - self.tab_compensation = 0; - } else if self.lookahead == Some('\t') { - self.tab_compensation += 7; // One column for the position of the char itself, add 7 more for a tabwidth of 8 - } - match self.chars.next() { - Some((idx, ch)) => { - self.pos = idx; - self.lookahead = Some(ch); - } - None => { - self.pos = self.source.len(); - self.lookahead = None; - } - } - self.lookahead - } - - fn loc(&self) -> Location { - Location { - path: self.path.clone(), - line: self.line_number, - column: self.pos - self.column_start + self.tab_compensation, - } - } - - fn looking_at(&self, prefix: &str) -> bool { - self.source[self.pos..].starts_with(prefix) - } - - fn scan_char(&mut self, tok: Token<'a>) -> Result, LocatedError> { - assert!(self.lookahead.is_some()); - let loc = self.loc(); - self.next_ch(); - token(tok, loc) - } - - pub fn rest_of_line(&mut self) -> &'a str { - let begin = self.pos; - loop { - match self.next_ch() { - None | Some('\n') => return &self.source[begin..self.pos], - _ => {} - } - } - } - - fn scan_word(&mut self) -> Result, LocatedError> { - let begin = self.pos; - let loc = self.loc(); - assert!(self.lookahead == Some('_') || self.lookahead.unwrap().is_alphabetic()); - loop { - match self.next_ch() { - Some('_') | Some('-') => {} - Some(ch) if ch.is_alphanumeric() => {} - _ => break, - } - } - let text = &self.source[begin..self.pos]; - token(Token::Word(text), loc) - } - - fn scan_ident(&mut self) -> Result, LocatedError> { - let loc = self.loc(); - assert!(self.lookahead == Some('$')); - match self.next_ch() { - Some(ch) if ch.is_alphanumeric() || ch == '_' => {} - _ => Err(LocatedError { - error: LexError::EmptyIdentifier, - location: loc.clone(), - })?, - } - let begin = self.pos; - - loop { - match self.next_ch() { - Some('_') | Some('-') => {} - Some(ch) if ch.is_alphanumeric() => {} - _ => break, - } - } - - let text = &self.source[begin..self.pos]; - token(Token::Ident(text), loc) - } - - fn scan_annotation(&mut self) -> Result, LocatedError> { - let loc = self.loc(); - assert!(self.lookahead == Some('@')); - match self.next_ch() { - Some(ch) if ch.is_alphanumeric() || ch == '_' => {} - _ => Err(LocatedError { - error: LexError::EmptyAnnotation, - location: loc.clone(), - })?, - } - let begin = self.pos; - - loop { - match self.next_ch() { - Some('_') | Some('-') => {} - Some(ch) if ch.is_alphanumeric() => {} - _ => break, - } - } - - let text = &self.source[begin..self.pos]; - token(Token::Annot(text), loc) - } - - fn scan_quote(&mut self) -> Result, LocatedError> { - let begin = self.pos; - let loc = self.loc(); - assert!(self.lookahead == Some('"')); - loop { - match self.next_ch() { - None => Err(LocatedError { - error: LexError::UnterminatedQuote, - location: loc.clone(), - })?, - Some('"') => { - self.next_ch(); - break; - } - _ => {} - } - } - let text = &self.source[(begin + 1)..(self.pos - 1)]; - token(Token::Quote(text), loc) - } - - #[allow(clippy::should_implement_trait)] - pub fn next(&mut self) -> Option, LocatedError>> { - loop { - let loc = self.loc(); - return match self.lookahead { - None => None, - Some(c) => Some(match c { - '(' => self.scan_char(Token::LPar), - ')' => self.scan_char(Token::RPar), - '$' => self.scan_ident(), - '@' => self.scan_annotation(), - ';' => { - if self.looking_at(";;") { - self.rest_of_line(); - continue; - } else { - self.next_ch(); - error(LexError::InvalidChar(';'), loc) - } - } - '"' => self.scan_quote(), - '_' => self.scan_word(), - ch if ch.is_alphabetic() => self.scan_word(), - ch if ch.is_whitespace() => { - self.next_ch(); - continue; - } - _ => { - self.next_ch(); - error(LexError::InvalidChar(c), loc) - } - }), - }; - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use std::path::{Path, PathBuf}; - - fn testlexer(input: &str) -> Lexer { - Lexer::new(input, Path::new("/test")) - } - - fn token( - token: Token<'_>, - line: usize, - column: usize, - ) -> Option, LocatedError>> { - Some(super::token( - token, - Location { - path: PathBuf::from("/test"), - line, - column, - }, - )) - } - - fn error<'a>( - err: LexError, - line: usize, - column: usize, - ) -> Option, LocatedError>> { - Some(super::error( - err, - Location { - path: PathBuf::from("/test"), - line, - column, - }, - )) - } - #[test] - fn words_and_idents() { - let mut lex = testlexer("$gussie is a good $dog"); - // ruler 0 5 10 15 20 - assert_eq!(lex.next(), token(Token::Ident("gussie"), 1, 0)); - assert_eq!(lex.next(), token(Token::Word("is"), 1, 8)); - assert_eq!(lex.next(), token(Token::Word("a"), 1, 11)); - assert_eq!(lex.next(), token(Token::Word("good"), 1, 13)); - assert_eq!(lex.next(), token(Token::Ident("dog"), 1, 18)); - assert_eq!(lex.next(), None); - - let mut lex = - testlexer("$ok $a $_ $ _\nkebab-case\nsnake_case\n$kebab-ident\n$snake_ident"); - assert_eq!(lex.next(), token(Token::Ident("ok"), 1, 0)); - assert_eq!(lex.next(), token(Token::Ident("a"), 1, 4)); - assert_eq!(lex.next(), token(Token::Ident("_"), 1, 7)); - assert_eq!(lex.next(), error(LexError::EmptyIdentifier, 1, 10)); - assert_eq!(lex.next(), token(Token::Word("_"), 1, 12)); - assert_eq!(lex.next(), token(Token::Word("kebab-case"), 2, 0)); - assert_eq!(lex.next(), token(Token::Word("snake_case"), 3, 0)); - assert_eq!(lex.next(), token(Token::Ident("kebab-ident"), 4, 0)); - assert_eq!(lex.next(), token(Token::Ident("snake_ident"), 5, 0)); - assert_eq!(lex.next(), None); - } - - #[test] - fn comments() { - let mut lex = testlexer("the quick ;; brown fox\njumped\n;;over the three\nlazy;;dogs"); - assert_eq!(lex.next(), token(Token::Word("the"), 1, 0)); - assert_eq!(lex.next(), token(Token::Word("quick"), 1, 4)); - assert_eq!(lex.next(), token(Token::Word("jumped"), 2, 0)); - assert_eq!(lex.next(), token(Token::Word("lazy"), 4, 0)); - assert_eq!(lex.next(), None); - - let mut lex = testlexer("line1 ;;\n$sym_2;\n\t\tl3;;;333"); - assert_eq!(lex.next(), token(Token::Word("line1"), 1, 0)); - assert_eq!(lex.next(), token(Token::Ident("sym_2"), 2, 0)); - assert_eq!(lex.next(), error(LexError::InvalidChar(';'), 2, 6)); - assert_eq!(lex.next(), token(Token::Word("l3"), 3, 16)); // Two tabs = 16 columns - assert_eq!(lex.next(), None); - } - - #[test] - fn quotes() { - let mut lex = testlexer("a \"bc\" d"); - assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); - assert_eq!(lex.next(), token(Token::Quote("bc"), 1, 2)); - assert_eq!(lex.next(), token(Token::Word("d"), 1, 7)); - - let mut lex = testlexer("a \"b\nc\" d"); - assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); - assert_eq!(lex.next(), token(Token::Quote("b\nc"), 1, 2)); - assert_eq!(lex.next(), token(Token::Word("d"), 2, 3)); - - let mut lex = testlexer("a \"b"); - assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); - assert_eq!(lex.next(), error(LexError::UnterminatedQuote, 1, 2)); - } -} diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index af315a9df..60ccf2c9b 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -4,14 +4,10 @@ mod ast; mod coretypes; /// Interface for filesystem or mock IO mod io; -/// Lexer text into tokens -mod lexer; /// Witx syntax parsing from SExprs mod parser; /// Render ast to text mod render; -/// SExpr parsing from tokens -mod sexpr; /// Resolve toplevel `use` declarations across files mod toplevel; /// Validate declarations into ast @@ -25,10 +21,8 @@ pub use ast::{ }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; pub use io::{Filesystem, MockFs, WitxIo}; -pub use lexer::LexError; -pub use parser::{DeclSyntax, ParseError}; +pub use parser::DeclSyntax; pub use render::{Render, SExpr as RenderSExpr}; -pub use sexpr::SExprParseError; pub use validate::ValidationError; use failure::Fail; @@ -36,19 +30,13 @@ use std::path::{Path, PathBuf}; /// Load a witx document from the filesystem pub fn load>(path: P) -> Result { - use toplevel::parse_witx; - use validate::validate_document; - let parsed_decls = parse_witx(path)?; - validate_document(&parsed_decls).map_err(WitxError::Validation) + toplevel::parse_witx(path.as_ref()) } /// Parse a witx document from a str. `(use ...)` directives are not permitted. pub fn parse(source: &str) -> Result { - use toplevel::parse_witx_with; - use validate::validate_document; let mockfs = MockFs::new(&[("-", source)]); - let parsed_decls = parse_witx_with(Path::new("-"), &mockfs)?; - validate_document(&parsed_decls).map_err(WitxError::Validation) + toplevel::parse_witx_with(Path::new("-"), &mockfs) } /// Location in the source text @@ -61,12 +49,10 @@ pub struct Location { #[derive(Debug, Fail)] pub enum WitxError { - #[fail(display = "{}", _0)] - SExpr(#[cause] SExprParseError), #[fail(display = "with file {:?}: {}", _0, _1)] Io(PathBuf, #[cause] ::std::io::Error), #[fail(display = "{}", _0)] - Parse(#[cause] ParseError), + Parse(#[cause] wast::Error), #[fail(display = "{}", _0)] Validation(#[cause] ValidationError), } @@ -75,9 +61,8 @@ impl WitxError { pub fn report_with(&self, witxio: &dyn WitxIo) -> String { use WitxError::*; match self { - SExpr(sexpr) => sexpr.report_with(witxio), Io(path, ioerr) => format!("with file {:?}: {}", path, ioerr), - Parse(parse) => parse.report_with(witxio), + Parse(parse) => parse.to_string(), Validation(validation) => validation.report_with(witxio), } } diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index d12d643ed..8c7a1eecf 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -1,7 +1,4 @@ -use crate::io::{Filesystem, WitxIo}; -use crate::sexpr::SExpr; -use crate::Location; -use failure::Fail; +use wast::parser::{Cursor, Parse, Parser, Peek, Result}; ///! Parser turns s-expressions into unvalidated syntax constructs. ///! conventions: @@ -16,48 +13,31 @@ use failure::Fail; ///! This is used for error reporting in case the slice doesn't have the number of elements ///! expected. -#[derive(Debug, Fail)] -#[fail(display = "{} at {:?}", _0, _1)] -pub struct ParseError { - pub message: String, - pub location: Location, -} - -impl ParseError { - pub fn report_with(&self, witxio: &dyn WitxIo) -> String { - format!( - "{}\n{}", - self.location.highlight_source_with(witxio), - self.message - ) - } - pub fn report(&self) -> String { - self.report_with(&Filesystem) - } -} - -macro_rules! parse_err { - ($loc:expr, $msg:expr) => { - ParseError { message: $msg.to_string(), location: $loc.clone() } - }; - ($loc:expr, $fmt:expr, $( $arg:expr ),+ ) => { - ParseError { message: format!($fmt, $( $arg ),+), location: $loc.clone() } - }; -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct IdentSyntax { - pub name: String, - pub location: Location, -} - -macro_rules! id { - ($s:expr, $loc: expr) => { - IdentSyntax { - name: $s.to_string(), - location: $loc.clone(), - } - }; +mod kw { + pub use wast::kw::{export, func, import, memory, module, param, result}; + + wast::custom_keyword!(array); + wast::custom_keyword!(const_pointer); + wast::custom_keyword!(f32); + wast::custom_keyword!(f64); + wast::custom_keyword!(field); + wast::custom_keyword!(flag); + wast::custom_keyword!(flags); + wast::custom_keyword!(pointer); + wast::custom_keyword!(r#enum = "enum"); + wast::custom_keyword!(r#struct = "struct"); + wast::custom_keyword!(r#union = "union"); + wast::custom_keyword!(r#use = "use"); + wast::custom_keyword!(s16); + wast::custom_keyword!(s32); + wast::custom_keyword!(s64); + wast::custom_keyword!(s8); + wast::custom_keyword!(string); + wast::custom_keyword!(typename); + wast::custom_keyword!(u16); + wast::custom_keyword!(u32); + wast::custom_keyword!(u64); + wast::custom_keyword!(u8); } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -75,514 +55,450 @@ pub enum BuiltinType { F64, } -impl BuiltinType { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - match sexpr { - SExpr::Word("string", _) - | SExpr::Word("u8", _) - | SExpr::Word("u16", _) - | SExpr::Word("u32", _) - | SExpr::Word("u64", _) - | SExpr::Word("s8", _) - | SExpr::Word("s16", _) - | SExpr::Word("s32", _) - | SExpr::Word("s64", _) - | SExpr::Word("f32", _) - | SExpr::Word("f64", _) => true, - _ => false, - } - } - pub fn parse(sexpr: &SExpr) -> Result { - match sexpr { - SExpr::Word("string", _loc) => Ok(BuiltinType::String), - SExpr::Word("u8", _loc) => Ok(BuiltinType::U8), - SExpr::Word("u16", _loc) => Ok(BuiltinType::U16), - SExpr::Word("u32", _loc) => Ok(BuiltinType::U32), - SExpr::Word("u64", _loc) => Ok(BuiltinType::U64), - SExpr::Word("s8", _loc) => Ok(BuiltinType::S8), - SExpr::Word("s16", _loc) => Ok(BuiltinType::S16), - SExpr::Word("s32", _loc) => Ok(BuiltinType::S32), - SExpr::Word("s64", _loc) => Ok(BuiltinType::S64), - SExpr::Word("f32", _loc) => Ok(BuiltinType::F32), - SExpr::Word("f64", _loc) => Ok(BuiltinType::F64), - _ => Err(parse_err!(sexpr.location(), "invalid builtin type")), +impl Parse<'_> for BuiltinType { + fn parse(parser: Parser<'_>) -> Result { + let mut l = parser.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::String) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::U8) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::U16) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::U32) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::U64) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::S8) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::S16) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::S32) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::S64) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::F32) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::F64) + } else { + Err(l.error()) } } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum DatatypeIdentSyntax { +pub enum DatatypeIdentSyntax<'a> { Builtin(BuiltinType), - Array(Box), - Pointer(Box), - ConstPointer(Box), - Ident(IdentSyntax), -} - -impl DatatypeIdentSyntax { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - BuiltinType::starts_parsing(sexpr) - || match sexpr { - SExpr::Ident(_, _) => true, - SExpr::Vec(v, _) => match (v.get(0), v.get(1)) { - (Some(SExpr::Word("array", _)), Some(_)) => true, - (Some(SExpr::Annot("witx", _)), Some(SExpr::Word("pointer", _))) => true, - (Some(SExpr::Annot("witx", _)), Some(SExpr::Word("const_pointer", _))) => true, - _ => false, - }, - _ => false, + Array(Box>), + Pointer(Box>), + ConstPointer(Box>), + Ident(wast::Id<'a>), +} + +impl<'a> Parse<'a> for DatatypeIdentSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + if parser.peek::() { + Ok(DatatypeIdentSyntax::Ident(parser.parse()?)) + } else if parser.peek2::() { + Ok(DatatypeIdentSyntax::Array(parser.parens(|p| { + p.parse::()?; + Ok(Box::new(parser.parse()?)) + })?)) + } else if parser.peek::() { + parser.parens(|p| { + p.parse::()?; + if p.peek::() { + p.parse::()?; + Ok(DatatypeIdentSyntax::ConstPointer(Box::new(p.parse()?))) + } else { + p.parse::()?; + Ok(DatatypeIdentSyntax::Pointer(Box::new(p.parse()?))) + } + }) + } else { + Ok(DatatypeIdentSyntax::Builtin(parser.parse()?)) + } + } +} + +struct AtWitx; + +impl Parse<'_> for AtWitx { + fn parse(parser: Parser<'_>) -> Result { + parser.step(|c| { + if let Some(("@witx", rest)) = c.reserved() { + return Ok((AtWitx, rest)); } + Err(c.error("expected `@witx`")) + }) } - pub fn parse(sexpr: &SExpr) -> Result { - if BuiltinType::starts_parsing(sexpr) { - let builtin = BuiltinType::parse(sexpr)?; - Ok(DatatypeIdentSyntax::Builtin(builtin)) - } else { - match sexpr { - SExpr::Ident(i, loc) => Ok(DatatypeIdentSyntax::Ident(id!(i, loc))), - SExpr::Vec(v, loc) => match (v.get(0), v.get(1), v.get(2)) { - (Some(SExpr::Word("array", _)), Some(expr), None) => Ok( - DatatypeIdentSyntax::Array(Box::new(DatatypeIdentSyntax::parse(expr)?)), - ), - ( - Some(SExpr::Annot("witx", _)), - Some(SExpr::Word("pointer", _)), - Some(expr), - ) => Ok(DatatypeIdentSyntax::Pointer(Box::new( - DatatypeIdentSyntax::parse(expr)?, - ))), - ( - Some(SExpr::Annot("witx", _)), - Some(SExpr::Word("const_pointer", _)), - Some(expr), - ) => Ok(DatatypeIdentSyntax::ConstPointer(Box::new( - DatatypeIdentSyntax::parse(expr)?, - ))), - _ => Err(parse_err!(loc, "expected type identifier")), - }, - _ => Err(parse_err!(sexpr.location(), "expected type identifier")), +} + +impl Peek for AtWitx { + fn peek(cursor: Cursor<'_>) -> bool { + cursor.reserved().map(|s| s.0) == Some("@witx") + } + + fn display() -> &'static str { + "`@witx`" + } +} + +struct AtInterface; + +impl Parse<'_> for AtInterface { + fn parse(parser: Parser<'_>) -> Result { + parser.step(|c| { + if let Some(("@interface", rest)) = c.reserved() { + return Ok((AtInterface, rest)); } - } + Err(c.error("expected `@interface`")) + }) + } +} + +impl Peek for AtInterface { + fn peek(cursor: Cursor<'_>) -> bool { + cursor.reserved().map(|s| s.0) == Some("@interface") + } + + fn display() -> &'static str { + "`@interface`" } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum TopLevelSyntax { - Decl(DeclSyntax), - Use(IdentSyntax), +pub struct TopLevelDocument<'a> { + pub items: Vec>, } -impl TopLevelSyntax { - pub fn parse(sexpr: &SExpr) -> Result { - if DeclSyntax::starts_parsing(sexpr) { - let decl = DeclSyntax::parse(sexpr)?; - Ok(TopLevelSyntax::Decl(decl)) - } else { - match sexpr { - SExpr::Vec(v, vec_loc) => match v.get(0) { - Some(SExpr::Word("use", loc)) => match v.get(1) { - Some(SExpr::Quote(u, loc)) => Ok(TopLevelSyntax::Use(id!(u, loc))), - _ => Err(parse_err!(loc, "invalid use declaration")), - }, - _ => Err(parse_err!(vec_loc, "expected top level declaration")), - }, - _ => Err(parse_err!( - sexpr.location(), - "expected top level declaration" - )), - } +impl<'a> Parse<'a> for TopLevelDocument<'a> { + fn parse(parser: Parser<'a>) -> Result { + let mut items = Vec::new(); + while !parser.is_empty() { + items.push(parser.parens(|p| p.parse())?); } + Ok(TopLevelDocument { items }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum DeclSyntax { - Typename(TypenameSyntax), - Module(ModuleSyntax), -} - -impl DeclSyntax { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - match sexpr { - SExpr::Vec(v, _) => match v.get(0) { - Some(SExpr::Word("typename", _)) => true, - Some(SExpr::Word("module", _)) => true, - _ => false, - }, - _ => false, +pub enum TopLevelSyntax<'a> { + Decl(DeclSyntax<'a>), + Use(&'a str), +} + +impl<'a> Parse<'a> for TopLevelSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + if parser.peek::() { + parser.parse::()?; + Ok(TopLevelSyntax::Use(parser.parse()?)) + } else { + Ok(TopLevelSyntax::Decl(parser.parse()?)) } } - pub fn parse(sexpr: &SExpr) -> Result { - match sexpr { - SExpr::Vec(v, loc) => match v.get(0) { - Some(SExpr::Word("typename", loc)) => { - Ok(DeclSyntax::Typename(TypenameSyntax::parse(&v[1..], loc)?)) - } - Some(SExpr::Word("module", loc)) => { - Ok(DeclSyntax::Module(ModuleSyntax::parse(&v[1..], loc)?)) - } - _ => Err(parse_err!(loc, "invalid declaration")), - }, - _ => Err(parse_err!(sexpr.location(), "expected vec")), +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum DeclSyntax<'a> { + Typename(TypenameSyntax<'a>), + Module(ModuleSyntax<'a>), +} + +impl<'a> Parse<'a> for DeclSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(DeclSyntax::Module(parser.parse()?)) + } else if l.peek::() { + Ok(DeclSyntax::Typename(parser.parse()?)) + } else { + Err(l.error()) } } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct TypenameSyntax { - pub ident: IdentSyntax, - pub def: TypedefSyntax, -} - -impl TypenameSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - let ident = match sexpr.get(0) { - Some(SExpr::Ident(i, loc)) => id!(i, loc), - Some(s) => Err(parse_err!(s.location(), "expected typename identifier"))?, - None => Err(parse_err!(loc, "expected typename identifier"))?, - }; - let def = match sexpr.get(1) { - Some(expr) => TypedefSyntax::parse(expr)?, - _ => Err(parse_err!(loc, "expected type definition"))?, - }; +pub struct TypenameSyntax<'a> { + pub ident: wast::Id<'a>, + pub def: TypedefSyntax<'a>, +} + +impl<'a> Parse<'a> for TypenameSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let ident = parser.parse()?; + let def = parser.parse()?; Ok(TypenameSyntax { ident, def }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum TypedefSyntax { - Ident(DatatypeIdentSyntax), - Enum(EnumSyntax), - Flags(FlagsSyntax), - Struct(StructSyntax), - Union(UnionSyntax), -} - -impl TypedefSyntax { - pub fn parse(sexpr: &SExpr) -> Result { - if DatatypeIdentSyntax::starts_parsing(sexpr) { - let ident = DatatypeIdentSyntax::parse(sexpr)?; - Ok(TypedefSyntax::Ident(ident)) - } else { - match sexpr { - SExpr::Vec(vs, loc) => match vs.get(0) { - Some(SExpr::Word("enum", loc)) => { - Ok(TypedefSyntax::Enum(EnumSyntax::parse(&vs[1..], loc)?)) - } - Some(SExpr::Word("flags", loc)) => { - Ok(TypedefSyntax::Flags(FlagsSyntax::parse(&vs[1..], loc)?)) - } - Some(SExpr::Word("struct", loc)) => { - Ok(TypedefSyntax::Struct(StructSyntax::parse(&vs[1..], loc)?)) - } - Some(SExpr::Word("union", loc)) => { - Ok(TypedefSyntax::Union(UnionSyntax::parse(&vs[1..], loc)?)) - } - _ => Err(parse_err!( - loc, - "expected type identifier or type definition" - )), - }, - _ => Err(parse_err!( - sexpr.location(), - "expected type identifier or type definition" - )), - } +pub enum TypedefSyntax<'a> { + Ident(DatatypeIdentSyntax<'a>), + Enum(EnumSyntax<'a>), + Flags(FlagsSyntax<'a>), + Struct(StructSyntax<'a>), + Union(UnionSyntax<'a>), +} + +impl<'a> Parse<'a> for TypedefSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + if !parser.peek::() || parser.peek2::() || parser.peek2::() + { + return Ok(TypedefSyntax::Ident(parser.parse()?)); } + parser.parens(|parser| { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(TypedefSyntax::Enum(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Flags(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Struct(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Union(parser.parse()?)) + } else { + Err(l.error()) + } + }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct EnumSyntax { +pub struct EnumSyntax<'a> { pub repr: BuiltinType, - pub members: Vec, -} - -impl EnumSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - let repr = match sexpr.get(0) { - Some(e) => BuiltinType::parse(e)?, - _ => Err(parse_err!(loc, "no enum repr"))?, - }; - let members = sexpr[1..] - .iter() - .map(|m| match m { - SExpr::Ident(i, loc) => Ok(id!(i, loc)), - s => Err(parse_err!(s.location(), "expected enum member identifier")), - }) - .collect::, ParseError>>()?; - if members.is_empty() { - Err(parse_err!(loc, "expected at least one enum member"))? + pub members: Vec>, +} + +impl<'a> Parse<'a> for EnumSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let repr = parser.parse()?; + let mut members = Vec::new(); + members.push(parser.parse()?); + while !parser.is_empty() { + members.push(parser.parse()?); } Ok(EnumSyntax { repr, members }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct FlagsSyntax { +pub struct FlagsSyntax<'a> { pub repr: BuiltinType, - pub flags: Vec, -} - -impl FlagsSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - let repr = BuiltinType::parse( - sexpr - .get(0) - .ok_or_else(|| parse_err!(loc, "expected flag repr type"))?, - )?; - let flags = sexpr[1..] - .iter() - .map(|f| match f { - SExpr::Vec(vs, loc) => match (vs.get(0), vs.get(1)) { - (Some(SExpr::Word("flag", _)), Some(SExpr::Ident(i, loc))) => Ok(id!(i, loc)), - _ => Err(parse_err!(loc, "expected flag specifier")), - }, - s => Err(parse_err!(s.location(), "expected flag specifier")), - }) - .collect::, ParseError>>()?; + pub flags: Vec>, +} + +impl<'a> Parse<'a> for FlagsSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let repr = parser.parse()?; + let mut flags = Vec::new(); + while !parser.is_empty() { + flags.push(parser.parens(|parser| { + parser.parse::()?; + parser.parse() + })?); + } Ok(FlagsSyntax { repr, flags }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct StructSyntax { - pub fields: Vec, +pub struct StructSyntax<'a> { + pub fields: Vec>, } -impl StructSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - if sexpr.is_empty() { - Err(parse_err!(loc, "expected at least one struct member"))? +impl<'a> Parse<'a> for StructSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let mut fields = Vec::new(); + fields.push(parser.parens(|p| p.parse())?); + while !parser.is_empty() { + fields.push(parser.parens(|p| p.parse())?); } - let fields = sexpr - .iter() - .map(|f| FieldSyntax::parse(f, "field")) - .collect::, ParseError>>()?; Ok(StructSyntax { fields }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct FieldSyntax { - pub name: IdentSyntax, - pub type_: DatatypeIdentSyntax, -} - -impl FieldSyntax { - pub fn starts_parsing(sexpr: &SExpr, constructor: &str) -> bool { - match sexpr { - SExpr::Vec(v, _) => match v.get(0) { - Some(SExpr::Word(c, _)) => *c == constructor, - _ => false, - }, - _ => false, - } - } - pub fn parse(sexpr: &SExpr, constructor: &str) -> Result { - match sexpr { - SExpr::Vec(v, loc) => match v.get(0) { - Some(SExpr::Word(c, _)) if *c == constructor => { - let name = match v.get(1) { - Some(SExpr::Ident(i, loc)) => id!(i, loc), - _ => Err(parse_err!(loc, "expected {} name identifier", constructor))?, - }; - let type_ = DatatypeIdentSyntax::parse(v.get(2).ok_or_else(|| { - parse_err!(loc, "expected {} type identifier", constructor) - })?)?; - Ok(FieldSyntax { name, type_ }) - } - _ => Err(parse_err!(loc, "expected {}", constructor)), - }, - _ => Err(parse_err!(sexpr.location(), "expected {}", constructor)), - } +pub struct FieldSyntax<'a> { + pub name: wast::Id<'a>, + pub type_: DatatypeIdentSyntax<'a>, +} + +impl<'a> Parse<'a> for FieldSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let name = parser.parse()?; + let type_ = parser.parse()?; + Ok(FieldSyntax { name, type_ }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct UnionSyntax { - pub fields: Vec, +pub struct UnionSyntax<'a> { + pub fields: Vec>, } -impl UnionSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - if sexpr.is_empty() { - Err(parse_err!(loc, "expected at least one union member"))? +impl<'a> Parse<'a> for UnionSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let mut fields = Vec::new(); + fields.push(parser.parens(|p| p.parse())?); + while !parser.is_empty() { + fields.push(parser.parens(|p| p.parse())?); } - let fields = sexpr - .iter() - .map(|f| FieldSyntax::parse(f, "field")) - .collect::, ParseError>>()?; Ok(UnionSyntax { fields }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct ModuleSyntax { - pub name: IdentSyntax, - pub decls: Vec, -} - -impl ModuleSyntax { - pub fn parse(sexprs: &[SExpr], loc: &Location) -> Result { - let name = match sexprs.get(0) { - Some(SExpr::Ident(i, loc)) => id!(i, loc), - _ => Err(parse_err!(loc, "expected module name"))?, - }; - let decls = sexprs[1..] - .iter() - .map(|s| ModuleDeclSyntax::parse(s)) - .collect::, _>>()?; +pub struct ModuleSyntax<'a> { + pub name: wast::Id<'a>, + pub decls: Vec>, +} + +impl<'a> Parse<'a> for ModuleSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let name = parser.parse()?; + let mut decls = Vec::new(); + while !parser.is_empty() { + decls.push(parser.parens(|p| p.parse())?); + } Ok(ModuleSyntax { name, decls }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum ModuleDeclSyntax { - Import(ModuleImportSyntax), - Func(InterfaceFuncSyntax), -} - -impl ModuleDeclSyntax { - pub fn parse(sexpr: &SExpr) -> Result { - if ModuleImportSyntax::starts_parsing(sexpr) { - Ok(ModuleDeclSyntax::Import(ModuleImportSyntax::parse(sexpr)?)) - } else if InterfaceFuncSyntax::starts_parsing(sexpr) { - Ok(ModuleDeclSyntax::Func(InterfaceFuncSyntax::parse(sexpr)?)) +pub enum ModuleDeclSyntax<'a> { + Import(ModuleImportSyntax<'a>), + Func(InterfaceFuncSyntax<'a>), +} + +impl<'a> Parse<'a> for ModuleDeclSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(ModuleDeclSyntax::Import(parser.parse()?)) + } else if l.peek::() { + Ok(ModuleDeclSyntax::Func(parser.parse()?)) } else { - Err(parse_err!(sexpr.location(), "expected import or function")) + Err(l.error()) } } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ModuleImportSyntax { - pub name: IdentSyntax, +#[derive(Debug, Clone)] +pub struct ModuleImportSyntax<'a> { + pub name: &'a str, + pub name_loc: wast::Span, pub type_: ImportTypeSyntax, } -impl ModuleImportSyntax { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - match sexpr { - SExpr::Vec(vs, _) => match vs.get(0) { - Some(SExpr::Word("import", _)) => true, - _ => false, - }, - _ => false, - } +impl<'a> Parse<'a> for ModuleImportSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let name_loc = parser.cur_span(); + Ok(ModuleImportSyntax { + name: parser.parse()?, + name_loc, + type_: parser.parens(|p| p.parse())?, + }) } - pub fn parse(sexpr: &SExpr) -> Result { - match sexpr { - SExpr::Vec(vs, vec_loc) => match (vs.get(0), vs.get(1)) { - (Some(SExpr::Word("import", _)), Some(SExpr::Quote(name, loc))) => { - let name = id!(name, loc); - let type_ = ImportTypeSyntax::parse(&vs[2..], vec_loc)?; - Ok(ModuleImportSyntax { name, type_ }) - } - _ => Err(parse_err!(vec_loc, "expected module import")), - }, - _ => Err(parse_err!(sexpr.location(), "expected module import")), - } +} + +impl PartialEq for ModuleImportSyntax<'_> { + fn eq(&self, other: &ModuleImportSyntax<'_>) -> bool { + // skip the `name_loc` field + self.name == other.name && self.type_ == other.type_ } } +impl Eq for ModuleImportSyntax<'_> {} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum ImportTypeSyntax { Memory, } -impl ImportTypeSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - if sexpr.len() > 1 { - Err(parse_err!(loc, "too many elements for an import type"))?; - } - match sexpr.get(0) { - Some(SExpr::Vec(vs, loc)) => match vs.get(0) { - Some(SExpr::Word("memory", _)) => { - if vs.len() == 1 { - Ok(ImportTypeSyntax::Memory) - } else { - Err(parse_err!(loc, "too many elements for memory declaration")) - } - } - _ => Err(parse_err!(loc, "expected import type")), - }, - _ => Err(parse_err!(loc, "expected import type")), - } +impl Parse<'_> for ImportTypeSyntax { + fn parse(parser: Parser<'_>) -> Result { + parser.parse::()?; + Ok(ImportTypeSyntax::Memory) } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct InterfaceFuncSyntax { - pub export: IdentSyntax, - pub params: Vec, - pub results: Vec, -} - -impl InterfaceFuncSyntax { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - match sexpr { - SExpr::Vec(vs, _) => match (vs.get(0), vs.get(1)) { - (Some(SExpr::Annot("interface", _)), Some(SExpr::Word("func", _))) => true, - _ => false, - }, - _ => false, +#[derive(Debug, Clone)] +pub struct InterfaceFuncSyntax<'a> { + pub export: &'a str, + pub export_loc: wast::Span, + pub params: Vec>, + pub results: Vec>, +} + +impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + parser.parse::()?; + + let (export_loc, export) = parser.parens(|p| { + p.parse::()?; + Ok((p.cur_span(), p.parse()?)) + })?; + + let mut params = Vec::new(); + let mut results = Vec::new(); + + while !parser.is_empty() { + parser.parens(|p| { + let mut l = p.lookahead1(); + if l.peek::() { + parser.parse::()?; + params.push(FieldSyntax { + name: parser.parse()?, + type_: parser.parse()?, + }); + } else if l.peek::() { + parser.parse::()?; + results.push(FieldSyntax { + name: parser.parse()?, + type_: parser.parse()?, + }); + } else { + return Err(l.error()); + } + Ok(()) + })?; } + + Ok(InterfaceFuncSyntax { + export, + export_loc, + params, + results, + }) } - pub fn parse(sexpr: &SExpr) -> Result { - match sexpr { - SExpr::Vec(vs, loc) => match (vs.get(0), vs.get(1)) { - (Some(SExpr::Annot("interface", _)), Some(SExpr::Word("func", _))) => { - let export = match vs.get(2) { - Some(SExpr::Vec(es, loc)) => match (es.get(0), es.get(1)) { - ( - Some(SExpr::Word("export", _)), - Some(SExpr::Quote(name, name_loc)), - ) => { - if es.len() == 2 { - id!(name, name_loc) - } else { - Err(parse_err!( - loc, - "too many elements for export declaration" - ))? - } - } - _ => Err(parse_err!(loc, "expected export declaration"))?, - }, - _ => Err(parse_err!(loc, "expected export declaration"))?, - }; - let mut params = Vec::new(); - let mut results = Vec::new(); - - for sexpr in &vs[3..] { - if FieldSyntax::starts_parsing(sexpr, "param") { - let param = FieldSyntax::parse(sexpr, "param")?; - params.push(param); - } else if FieldSyntax::starts_parsing(sexpr, "result") { - let result = FieldSyntax::parse(sexpr, "result")?; - results.push(result); - } else { - Err(parse_err!( - sexpr.location(), - "expected param or result field" - ))?; - } - } - - Ok(InterfaceFuncSyntax { - export, - params, - results, - }) - } - _ => Err(parse_err!(loc, "expected interface func declaration")), - }, +} - _ => Err(parse_err!( - sexpr.location(), - "expected interface func declaration" - )), - } +impl PartialEq for InterfaceFuncSyntax<'_> { + fn eq(&self, other: &InterfaceFuncSyntax<'_>) -> bool { + // skip the `export_loc` field + self.export == other.export && self.params == other.params && self.results == other.results } } + +impl Eq for InterfaceFuncSyntax<'_> {} diff --git a/proposals/clocks/tools/witx/src/sexpr.rs b/proposals/clocks/tools/witx/src/sexpr.rs deleted file mode 100644 index d87d427e3..000000000 --- a/proposals/clocks/tools/witx/src/sexpr.rs +++ /dev/null @@ -1,240 +0,0 @@ -use crate::io::{Filesystem, WitxIo}; -pub use crate::lexer::LexError; -use crate::lexer::{Lexer, LocatedError, LocatedToken, Token}; -use crate::Location; -use failure::Fail; -use std::path::{Path, PathBuf}; - -///! The s-expression parser turns a string into a stream of SExprs. -///! It uses the `Lexer` under the hood. -///! This implementation was heavily influenced by `cranelift-reader` - -#[derive(Debug, PartialEq, Eq, Clone)] -pub enum SExpr<'a> { - Vec(Vec>, Location), - Word(&'a str, Location), - Ident(&'a str, Location), - Quote(&'a str, Location), - /// Short for Annotation - Annot(&'a str, Location), -} - -impl<'a> SExpr<'a> { - pub fn location(&self) -> Location { - match self { - SExpr::Vec(_, loc) => loc.clone(), - SExpr::Word(_, loc) => loc.clone(), - SExpr::Ident(_, loc) => loc.clone(), - SExpr::Quote(_, loc) => loc.clone(), - SExpr::Annot(_, loc) => loc.clone(), - } - } -} - -#[derive(Debug, PartialEq, Eq, Clone, Fail)] -pub enum SExprParseError { - #[fail(display = "Lexical error: {}", _0)] - Lex(LexError, Location), - #[fail(display = "Unexpected ')'")] - UnexpectedCloseParen(Location), - #[fail(display = "Unexpected end of input in {:?}", _0)] - UnexpectedEof(PathBuf), -} - -impl SExprParseError { - pub fn report_with(&self, witxio: &dyn WitxIo) -> String { - use SExprParseError::*; - match self { - Lex(lex_err, loc) => format!("{}\n{}", loc.highlight_source_with(witxio), lex_err), - UnexpectedCloseParen(loc) => format!("{}\n{}", loc.highlight_source_with(witxio), self), - UnexpectedEof(_path) => format!("{}", self), - } - } - pub fn report(&self) -> String { - self.report_with(&Filesystem) - } -} - -pub struct SExprParser<'a> { - lex: Lexer<'a>, - lookahead: Option>, - location: Location, -} - -impl<'a> SExprParser<'a> { - pub fn new>(text: &'a str, path: P) -> SExprParser<'_> { - SExprParser { - lex: Lexer::new(text, path.as_ref()), - lookahead: None, - location: Location { - path: path.as_ref().into(), - line: 0, - column: 0, - }, - } - } - fn consume(&mut self) -> Token<'a> { - self.lookahead.take().expect("no token to consume") - } - fn token(&mut self) -> Result>, SExprParseError> { - while self.lookahead == None { - match self.lex.next() { - Some(Ok(LocatedToken { token, location })) => { - self.location = location; - self.lookahead = Some(token) - } - Some(Err(LocatedError { error, location })) => { - self.location = location.clone(); - Err(SExprParseError::Lex(error, location))?; - } - None => break, - } - } - Ok(self.lookahead) - } - - pub fn match_sexpr(&mut self) -> Result, SExprParseError> { - let location = self.location.clone(); - match self.token()? { - Some(Token::LPar) => { - self.consume(); - let mut members = Vec::new(); - loop { - match self.token()? { - Some(Token::RPar) => { - self.consume(); - break; - } - _ => { - members.push(self.match_sexpr()?); - } - } - } - Ok(SExpr::Vec(members, location)) - } - Some(Token::Word(word)) => { - self.consume(); - Ok(SExpr::Word(word, location)) - } - Some(Token::Ident(id)) => { - self.consume(); - Ok(SExpr::Ident(id, location)) - } - Some(Token::Annot(id)) => { - self.consume(); - Ok(SExpr::Annot(id, location)) - } - Some(Token::Quote(q)) => { - self.consume(); - Ok(SExpr::Quote(q, location)) - } - Some(Token::RPar) => Err(SExprParseError::UnexpectedCloseParen(location)), - None => Err(SExprParseError::UnexpectedEof(self.location.path.clone())), - } - } - - pub fn match_sexprs(&mut self) -> Result>, SExprParseError> { - let mut sexprs = Vec::new(); - while self.token()?.is_some() { - sexprs.push(self.match_sexpr()?); - } - Ok(sexprs) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use std::path::PathBuf; - - fn loc(line: usize, col: usize) -> Location { - Location { - path: PathBuf::from("/test"), - line: line, - column: col, - } - } - - fn testparser(input: &str) -> SExprParser { - SExprParser::new(input, Path::new("/test")) - } - - #[test] - fn empty() { - let mut parser = testparser(""); - assert_eq!(parser.match_sexprs().expect("valid parse"), Vec::new()); - let mut parser = testparser(" ;; just a comment\n;;another"); - assert_eq!(parser.match_sexprs().expect("valid parse"), Vec::new()); - } - - #[test] - fn atoms() { - let mut parser = testparser("hello\n$world\n\"a quotation\""); - assert_eq!( - parser.match_sexprs().expect("valid parse"), - vec![ - SExpr::Word("hello", loc(1, 0)), - SExpr::Ident("world", loc(2, 0)), - SExpr::Quote("a quotation", loc(3, 0)), - ] - ); - } - - #[test] - fn lists() { - let mut parser = testparser("()"); - assert_eq!( - parser.match_sexprs().expect("valid parse"), - vec![SExpr::Vec(vec![], loc(1, 0))] - ); - - let mut parser = testparser("(hello\n$world\n\"a quotation\")"); - assert_eq!( - parser.match_sexprs().expect("valid parse"), - vec![SExpr::Vec( - vec![ - SExpr::Word("hello", loc(1, 1)), - SExpr::Ident("world", loc(2, 0)), - SExpr::Quote("a quotation", loc(3, 0)), - ], - loc(1, 0) - )] - ); - - let mut parser = testparser("((($deep)))"); - assert_eq!( - parser.match_sexprs().expect("valid parse"), - vec![SExpr::Vec( - vec![SExpr::Vec( - vec![SExpr::Vec(vec![SExpr::Ident("deep", loc(1, 3))], loc(1, 2))], - loc(1, 1) - )], - loc(1, 0) - )] - ); - } - - #[test] - fn errors() { - let mut parser = testparser("("); - assert_eq!( - parser.match_sexprs().err().expect("dies"), - SExprParseError::UnexpectedEof(PathBuf::from("/test")) - ); - let mut parser = testparser(")"); - assert_eq!( - parser.match_sexprs().err().expect("dies"), - SExprParseError::UnexpectedCloseParen(loc(1, 0)) - ); - let mut parser = testparser("())"); - assert_eq!( - parser.match_sexprs().err().expect("dies"), - SExprParseError::UnexpectedCloseParen(loc(1, 2)) - ); - let mut parser = testparser("$ ;; should be a lex error"); - assert_eq!( - parser.match_sexprs().err().expect("dies"), - SExprParseError::Lex(LexError::EmptyIdentifier, loc(1, 0),), - ); - } -} diff --git a/proposals/clocks/tools/witx/src/toplevel.rs b/proposals/clocks/tools/witx/src/toplevel.rs index 98325b39c..927bdd4de 100644 --- a/proposals/clocks/tools/witx/src/toplevel.rs +++ b/proposals/clocks/tools/witx/src/toplevel.rs @@ -1,162 +1,144 @@ +use crate::ast::{Definition, Document}; use crate::io::{Filesystem, WitxIo}; -use crate::parser::{DeclSyntax, ParseError, TopLevelSyntax}; -use crate::sexpr::SExprParser; +use crate::parser::{TopLevelDocument, TopLevelSyntax}; +use crate::validate::DocValidation; use crate::WitxError; use std::collections::HashSet; use std::path::{Path, PathBuf}; -pub fn parse_witx>(i: P) -> Result, WitxError> { - parse_witx_with(i, &Filesystem) +pub fn parse_witx(i: impl AsRef) -> Result { + _parse_witx_with(i.as_ref(), &Filesystem) } -pub fn parse_witx_with>( - i: P, - witxio: &dyn WitxIo, -) -> Result, WitxError> { - let input_path = witxio.canonicalize(&i.as_ref())?; - - let input = witxio.fgets(&input_path)?; - - let toplevel = parse_toplevel(&input, &input_path)?; - let mut resolved = HashSet::new(); - resolved.insert(input_path.clone()); - let search_path = input_path.parent().unwrap_or(Path::new(".")); - resolve_uses(toplevel, &search_path, &mut resolved, witxio) +pub fn parse_witx_with(i: impl AsRef, witxio: impl WitxIo) -> Result { + _parse_witx_with(i.as_ref(), &witxio) } -fn parse_toplevel(source_text: &str, file_path: &Path) -> Result, WitxError> { - let mut sexpr_parser = SExprParser::new(source_text, file_path); - let sexprs = sexpr_parser.match_sexprs().map_err(WitxError::SExpr)?; - let top_levels = sexprs - .iter() - .map(|s| TopLevelSyntax::parse(s)) - .collect::, ParseError>>() - .map_err(WitxError::Parse)?; - Ok(top_levels) +fn _parse_witx_with(path: &Path, io: &dyn WitxIo) -> Result { + let mut validator = DocValidation::new(); + let mut definitions = Vec::new(); + let root = path.parent().unwrap_or(Path::new(".")); + + parse_file( + path.file_name().unwrap().as_ref(), + io, + root, + &mut validator, + &mut definitions, + &mut HashSet::new(), + )?; + Ok(Document::new(definitions, validator.entries)) } -fn resolve_uses( - toplevel: Vec, - search_path: &Path, - used: &mut HashSet, - witxio: &dyn WitxIo, -) -> Result, WitxError> { - let mut decls = Vec::new(); +fn parse_file( + path: &Path, + io: &dyn WitxIo, + root: &Path, + validator: &mut DocValidation, + definitions: &mut Vec, + parsed: &mut HashSet, +) -> Result<(), WitxError> { + let path = io.canonicalize(&root.join(path))?; + if !parsed.insert(path.clone()) { + return Ok(()); + } + let input = io.fgets(&path)?; + + let adjust_err = |mut error: wast::Error| { + error.set_path(&path); + error.set_text(&input); + WitxError::Parse(error) + }; + let buf = wast::parser::ParseBuffer::new(&input).map_err(adjust_err)?; + let doc = wast::parser::parse::(&buf).map_err(adjust_err)?; - for t in toplevel { + for t in doc.items { match t { - TopLevelSyntax::Decl(d) => decls.push(d), + TopLevelSyntax::Decl(d) => { + let def = validator + .scope(&input, &path) + .validate_decl(&d) + .map_err(WitxError::Validation)?; + definitions.push(def); + } TopLevelSyntax::Use(u) => { - let abs_path = witxio.canonicalize(&search_path.join(u.name))?; - // Include the decls from a use declaration only once - // in a given toplevel. Same idea as #pragma once. - if !used.contains(&abs_path) { - used.insert(abs_path.clone()); - - let source_text = witxio.fgets(&abs_path)?; - let inner_toplevels = parse_toplevel(&source_text, &abs_path)?; - - let inner_decls = resolve_uses(inner_toplevels, search_path, used, witxio)?; - decls.extend(inner_decls) - } + parse_file(u.as_ref(), io, root, validator, definitions, parsed)?; } } } - Ok(decls) + Ok(()) } #[cfg(test)] mod test { use super::*; + use crate::ast::*; use crate::io::MockFs; - use crate::parser::*; - use crate::Location; #[test] fn empty() { - assert_eq!( - parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", ";; empty")])).expect("parse"), - Vec::new(), - ); + parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", ";; empty")])).expect("parse"); } #[test] fn one_use() { - assert_eq!( - parse_witx_with( - &Path::new("/a"), - &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]) - ) - .expect("parse"), - Vec::new(), - ); + parse_witx_with( + &Path::new("/a"), + &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]), + ) + .unwrap(); } #[test] fn multi_use() { - assert_eq!( - parse_witx_with( - &Path::new("/a"), - &MockFs::new(&[ - ("/a", "(use \"b\")"), - ("/b", "(use \"c\")\n(typename $b_float f64)"), - ("/c", "(typename $c_int u32)") - ]) - ) - .expect("parse"), - vec![ - DeclSyntax::Typename(TypenameSyntax { - ident: IdentSyntax { - name: "c_int".to_owned(), - location: Location { - path: PathBuf::from("/c"), - line: 1, - column: 10, - } - }, - def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::U32)) - }), - DeclSyntax::Typename(TypenameSyntax { - ident: IdentSyntax { - name: "b_float".to_owned(), - location: Location { - path: PathBuf::from("/b"), - line: 2, - column: 10, - } - }, - def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::F64)) - }) - ], - ); + let doc = parse_witx_with( + &Path::new("/a"), + &MockFs::new(&[ + ("/a", "(use \"b\")"), + ("/b", "(use \"c\")\n(typename $b_float f64)"), + ("/c", "(typename $c_int u32)"), + ]), + ) + .expect("parse"); + + match &doc.datatype(&Id::new("b_float")).unwrap().variant { + DatatypeVariant::Alias(a) => { + assert_eq!(a.name.as_str(), "b_float"); + assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::F64)); + } + other => panic!("expected alias, got {:?}", other), + } + + match &doc.datatype(&Id::new("c_int")).unwrap().variant { + DatatypeVariant::Alias(a) => { + assert_eq!(a.name.as_str(), "c_int"); + assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::U32)); + } + other => panic!("expected alias, got {:?}", other), + } } #[test] fn diamond_dependency() { - assert_eq!( - parse_witx_with( - &Path::new("/a"), - &MockFs::new(&[ - ("/a", "(use \"b\")\n(use \"c\")"), - ("/b", "(use \"d\")"), - ("/c", "(use \"d\")"), - ("/d", "(typename $d_char u8)") - ]) - ) - .expect("parse"), - vec![DeclSyntax::Typename(TypenameSyntax { - ident: IdentSyntax { - name: "d_char".to_owned(), - location: Location { - path: PathBuf::from("/d"), - line: 1, - column: 10, - } - }, - def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::U8)) - })], - ); + let doc = parse_witx_with( + &Path::new("/a"), + &MockFs::new(&[ + ("/a", "(use \"b\")\n(use \"c\")"), + ("/b", "(use \"d\")"), + ("/c", "(use \"d\")"), + ("/d", "(typename $d_char u8)"), + ]), + ) + .expect("parse"); + + match &doc.datatype(&Id::new("d_char")).unwrap().variant { + DatatypeVariant::Alias(a) => { + assert_eq!(a.name.as_str(), "d_char"); + assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::U8)); + } + other => panic!("expected alias, got {:?}", other), + } } #[test] @@ -177,15 +159,9 @@ mod test { .unwrap() { WitxError::Parse(e) => { - assert_eq!(e.message, "invalid use declaration"); - assert_eq!( - e.location, - Location { - path: PathBuf::from("/a"), - line: 1, - column: 1 - } - ); + let err = e.to_string(); + assert!(err.contains("expected a string"), "bad error: {}", err); + assert!(err.contains("/a:1:6")); } e => panic!("wrong error: {:?}", e), } diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 526409e62..df11c521c 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -1,17 +1,17 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ - DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, IdentSyntax, ImportTypeSyntax, + DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, - Definition, Document, Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, - InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, - ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, - UnionVariant, + Definition, Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, + InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, + ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; use failure::Fail; use std::collections::HashMap; +use std::path::Path; use std::rc::Rc; #[derive(Debug, Fail)] @@ -73,16 +73,6 @@ impl ValidationError { } } -pub fn validate_document(decls: &[DeclSyntax]) -> Result { - let mut validator = DocValidation::new(); - let mut definitions = Vec::new(); - for d in decls { - definitions.push(validator.validate_decl(&d)?); - } - - Ok(Document::new(definitions, validator.entries)) -} - struct IdentValidation { names: HashMap, } @@ -93,49 +83,84 @@ impl IdentValidation { names: HashMap::new(), } } - fn introduce(&mut self, syntax: &IdentSyntax) -> Result { - if let Some(introduced) = self.names.get(&syntax.name) { + + fn introduce(&mut self, syntax: &str, location: Location) -> Result { + if let Some(introduced) = self.names.get(syntax) { Err(ValidationError::NameAlreadyExists { - name: syntax.name.clone(), - at_location: syntax.location.clone(), + name: syntax.to_string(), + at_location: location, previous_location: introduced.clone(), }) } else { - self.names - .insert(syntax.name.clone(), syntax.location.clone()); - Ok(Id::new(&syntax.name)) + self.names.insert(syntax.to_string(), location); + Ok(Id::new(syntax)) } } - fn get(&self, syntax: &IdentSyntax) -> Result { - if self.names.get(&syntax.name).is_some() { - Ok(Id::new(&syntax.name)) + fn get(&self, syntax: &str, location: Location) -> Result { + if self.names.get(syntax).is_some() { + Ok(Id::new(syntax)) } else { Err(ValidationError::UnknownName { - name: syntax.name.clone(), - location: syntax.location.clone(), + name: syntax.to_string(), + location, }) } } } -struct DocValidation { +pub struct DocValidation { scope: IdentValidation, pub entries: HashMap, } +pub struct DocValidationScope<'a> { + doc: &'a mut DocValidation, + text: &'a str, + path: &'a Path, +} + impl DocValidation { - fn new() -> Self { + pub fn new() -> Self { Self { scope: IdentValidation::new(), entries: HashMap::new(), } } - fn validate_decl(&mut self, decl: &DeclSyntax) -> Result { + pub fn scope<'a>(&'a mut self, text: &'a str, path: &'a Path) -> DocValidationScope<'a> { + DocValidationScope { + doc: self, + text, + path, + } + } +} + +impl DocValidationScope<'_> { + fn location(&self, span: wast::Span) -> Location { + let (line, column) = span.linecol_in(self.text); + Location { + line, + column, + path: self.path.to_path_buf(), + } + } + + fn introduce(&mut self, name: &wast::Id<'_>) -> Result { + let loc = self.location(name.span()); + self.doc.scope.introduce(name.name(), loc) + } + + fn get(&self, name: &wast::Id<'_>) -> Result { + let loc = self.location(name.span()); + self.doc.scope.get(name.name(), loc) + } + + pub fn validate_decl(&mut self, decl: &DeclSyntax) -> Result { match decl { DeclSyntax::Typename(decl) => { - let name = self.scope.introduce(&decl.ident)?; + let name = self.introduce(&decl.ident)?; let variant = match &decl.def { TypedefSyntax::Ident(syntax) => DatatypeVariant::Alias(AliasDatatype { @@ -145,28 +170,29 @@ impl DocValidation { TypedefSyntax::Enum(syntax) => DatatypeVariant::Enum(self.validate_enum( &name, &syntax, - &decl.ident.location, + decl.ident.span(), )?), TypedefSyntax::Flags(syntax) => DatatypeVariant::Flags( - self.validate_flags(&name, &syntax, &decl.ident.location)?, + self.validate_flags(&name, &syntax, decl.ident.span())?, ), TypedefSyntax::Struct(syntax) => DatatypeVariant::Struct( - self.validate_struct(&name, &syntax, &decl.ident.location)?, + self.validate_struct(&name, &syntax, decl.ident.span())?, ), TypedefSyntax::Union(syntax) => DatatypeVariant::Union( - self.validate_union(&name, &syntax, &decl.ident.location)?, + self.validate_union(&name, &syntax, decl.ident.span())?, ), }; let rc_datatype = Rc::new(Datatype { name: name.clone(), variant, }); - self.entries + self.doc + .entries .insert(name, Entry::Datatype(Rc::downgrade(&rc_datatype))); Ok(Definition::Datatype(rc_datatype)) } DeclSyntax::Module(syntax) => { - let name = self.scope.introduce(&syntax.name)?; + let name = self.introduce(&syntax.name)?; let mut module_validator = ModuleValidation::new(self); let definitions = syntax .decls @@ -179,7 +205,8 @@ impl DocValidation { definitions, module_validator.entries, )); - self.entries + self.doc + .entries .insert(name, Entry::Module(Rc::downgrade(&rc_module))); Ok(Definition::Module(rc_module)) } @@ -202,20 +229,20 @@ impl DocValidation { self.validate_datatype_ident(&a)?, ))), DatatypeIdentSyntax::Ident(i) => { - let id = self.scope.get(i)?; - match self.entries.get(&id) { + let id = self.get(i)?; + match self.doc.entries.get(&id) { Some(Entry::Datatype(weak_d)) => Ok(DatatypeIdent::Ident( weak_d.upgrade().expect("weak backref to defined type"), )), Some(e) => Err(ValidationError::WrongKindName { - name: i.name.clone(), - location: i.location.clone(), + name: i.name().to_string(), + location: self.location(i.span()), expected: "datatype", got: e.kind(), }), None => Err(ValidationError::Recursive { - name: i.name.clone(), - location: i.location.clone(), + name: i.name().to_string(), + location: self.location(i.span()), }), } } @@ -226,14 +253,14 @@ impl DocValidation { &self, name: &Id, syntax: &EnumSyntax, - location: &Location, + span: wast::Span, ) -> Result { let mut enum_scope = IdentValidation::new(); - let repr = validate_int_repr(&syntax.repr, location)?; + let repr = self.validate_int_repr(&syntax.repr, span)?; let variants = syntax .members .iter() - .map(|i| enum_scope.introduce(i)) + .map(|i| enum_scope.introduce(i.name(), self.location(i.span()))) .collect::, _>>()?; Ok(EnumDatatype { @@ -247,14 +274,14 @@ impl DocValidation { &self, name: &Id, syntax: &FlagsSyntax, - location: &Location, + span: wast::Span, ) -> Result { let mut flags_scope = IdentValidation::new(); - let repr = validate_int_repr(&syntax.repr, location)?; + let repr = self.validate_int_repr(&syntax.repr, span)?; let flags = syntax .flags .iter() - .map(|i| flags_scope.introduce(i)) + .map(|i| flags_scope.introduce(i.name(), self.location(i.span()))) .collect::, _>>()?; Ok(FlagsDatatype { @@ -268,7 +295,7 @@ impl DocValidation { &self, name: &Id, syntax: &StructSyntax, - _location: &Location, + _span: wast::Span, ) -> Result { let mut member_scope = IdentValidation::new(); let members = syntax @@ -276,7 +303,7 @@ impl DocValidation { .iter() .map(|f| { Ok(StructMember { - name: member_scope.introduce(&f.name)?, + name: member_scope.introduce(f.name.name(), self.location(f.name.span()))?, type_: self.validate_datatype_ident(&f.type_)?, }) }) @@ -292,7 +319,7 @@ impl DocValidation { &self, name: &Id, syntax: &UnionSyntax, - _location: &Location, + _span: wast::Span, ) -> Result { let mut variant_scope = IdentValidation::new(); let variants = syntax @@ -300,7 +327,7 @@ impl DocValidation { .iter() .map(|f| { Ok(UnionVariant { - name: variant_scope.introduce(&f.name)?, + name: variant_scope.introduce(f.name.name(), self.location(f.name.span()))?, type_: self.validate_datatype_ident(&f.type_)?, }) }) @@ -311,29 +338,33 @@ impl DocValidation { variants, }) } -} -fn validate_int_repr(type_: &BuiltinType, location: &Location) -> Result { - match type_ { - BuiltinType::U8 => Ok(IntRepr::U8), - BuiltinType::U16 => Ok(IntRepr::U16), - BuiltinType::U32 => Ok(IntRepr::U32), - BuiltinType::U64 => Ok(IntRepr::U64), - _ => Err(ValidationError::InvalidRepr { - repr: type_.clone(), - location: location.clone(), - }), + fn validate_int_repr( + &self, + type_: &BuiltinType, + span: wast::Span, + ) -> Result { + match type_ { + BuiltinType::U8 => Ok(IntRepr::U8), + BuiltinType::U16 => Ok(IntRepr::U16), + BuiltinType::U32 => Ok(IntRepr::U32), + BuiltinType::U64 => Ok(IntRepr::U64), + _ => Err(ValidationError::InvalidRepr { + repr: type_.clone(), + location: self.location(span), + }), + } } } struct ModuleValidation<'a> { - doc: &'a DocValidation, + doc: &'a DocValidationScope<'a>, scope: IdentValidation, pub entries: HashMap, } impl<'a> ModuleValidation<'a> { - fn new(doc: &'a DocValidation) -> Self { + fn new(doc: &'a DocValidationScope<'a>) -> Self { Self { doc, scope: IdentValidation::new(), @@ -347,7 +378,8 @@ impl<'a> ModuleValidation<'a> { ) -> Result { match decl { ModuleDeclSyntax::Import(syntax) => { - let name = self.scope.introduce(&syntax.name)?; + let loc = self.doc.location(syntax.name_loc); + let name = self.scope.introduce(syntax.name, loc)?; let variant = match syntax.type_ { ImportTypeSyntax::Memory => ModuleImportVariant::Memory, }; @@ -360,7 +392,8 @@ impl<'a> ModuleValidation<'a> { Ok(ModuleDefinition::Import(rc_import)) } ModuleDeclSyntax::Func(syntax) => { - let name = self.scope.introduce(&syntax.export)?; + let loc = self.doc.location(syntax.export_loc); + let name = self.scope.introduce(syntax.export, loc)?; let mut argnames = IdentValidation::new(); let params = syntax .params @@ -368,7 +401,8 @@ impl<'a> ModuleValidation<'a> { .enumerate() .map(|(ix, f)| { Ok(InterfaceFuncParam { - name: argnames.introduce(&f.name)?, + name: argnames + .introduce(f.name.name(), self.doc.location(f.name.span()))?, type_: self.doc.validate_datatype_ident(&f.type_)?, position: InterfaceFuncParamPosition::Param(ix), }) @@ -384,12 +418,13 @@ impl<'a> ModuleValidation<'a> { match type_.passed_by() { DatatypePassedBy::Value(_) => {} _ => Err(ValidationError::InvalidFirstResultType { - location: f.name.location.clone(), + location: self.doc.location(f.name.span()), })?, } } Ok(InterfaceFuncParam { - name: argnames.introduce(&f.name)?, + name: argnames + .introduce(f.name.name(), self.doc.location(f.name.span()))?, type_, position: InterfaceFuncParamPosition::Result(ix), }) diff --git a/proposals/clocks/tools/witx/tests/wasi_unstable.rs b/proposals/clocks/tools/witx/tests/wasi_unstable.rs index 482224344..68e65186a 100644 --- a/proposals/clocks/tools/witx/tests/wasi_unstable.rs +++ b/proposals/clocks/tools/witx/tests/wasi_unstable.rs @@ -6,7 +6,7 @@ fn validate_wasi_unstable_preview0() { witx::load(Path::new( "../../phases/unstable/witx/wasi_unstable_preview0.witx", )) - .unwrap(); + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] @@ -14,12 +14,13 @@ fn validate_wasi_ephemeral_preview() { witx::load(Path::new( "../../phases/ephemeral/witx/wasi_ephemeral_preview.witx", )) - .unwrap(); + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_old_preview0() { - witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")).unwrap(); + witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] @@ -27,7 +28,7 @@ fn render_roundtrip() { let doc = witx::load(Path::new( "../../phases/unstable/witx/wasi_unstable_preview0.witx", )) - .unwrap(); + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); let back_to_sexprs = format!("{}", doc); println!("{}", back_to_sexprs); From c139381845212f6a0d1465db7786450a25f0f3d0 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 22 Oct 2019 11:54:40 -0500 Subject: [PATCH 0221/1772] Switch to the Rust `wast` crate for parsing `*.witx` (#124) This commit switches to the recently-published `wast` crate to parse `*.witx` file. The `wast` crate is intended to be a way to easily write recursive descent and composable parsers. It includes built-in parsers for all of `*.wat` and `*.wast` syntax, but only a few limited ones were used for `*.witx`, otherwise it's just the idioms that were used for the `Parse` trait and such! The hope here is that this can consolidate lexing/handling of s-expressions and simplify the parsing strategy as well. Eventually it's intended that `wast` is flexible enough to have built-in parsers for interface types as well! The crate was refactored slightly in implementing this change, prominently: * The `validate` pass is not baked into the `src/toplevel.rs` parsing. * The `src/toplevel.rs` parsing was simplified slightly to have only one recursive function for parsing includes. * All `*Syntax` data types now have a `'a` lifetime parameter and are consumed immediately on the stack frame while parsing. * `Location` is no longer manufactured while parsing, but rather it's created on-demand while the ast is being constructed. This required a small refactoring to have a `DocValidationScope` which carries metadata about the current file that was parsed to manufacture `Location`. --- proposals/random/tools/witx/Cargo.toml | 1 + proposals/random/tools/witx/src/io.rs | 12 + proposals/random/tools/witx/src/lexer.rs | 354 -------- proposals/random/tools/witx/src/lib.rs | 25 +- proposals/random/tools/witx/src/parser.rs | 830 ++++++++---------- proposals/random/tools/witx/src/sexpr.rs | 240 ----- proposals/random/tools/witx/src/toplevel.rs | 234 +++-- proposals/random/tools/witx/src/validate.rs | 179 ++-- .../random/tools/witx/tests/wasi_unstable.rs | 9 +- 9 files changed, 608 insertions(+), 1276 deletions(-) delete mode 100644 proposals/random/tools/witx/src/lexer.rs delete mode 100644 proposals/random/tools/witx/src/sexpr.rs diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 2fe71c419..9a38ed265 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -18,4 +18,5 @@ path = "src/main.rs" [dependencies] clap = "2" +wast = "3.0.1" failure = "0.1" diff --git a/proposals/random/tools/witx/src/io.rs b/proposals/random/tools/witx/src/io.rs index 4f40d8947..f46ab1766 100644 --- a/proposals/random/tools/witx/src/io.rs +++ b/proposals/random/tools/witx/src/io.rs @@ -13,6 +13,18 @@ pub trait WitxIo { fn canonicalize(&self, path: &Path) -> Result; } +impl WitxIo for &'_ T { + fn fgets(&self, path: &Path) -> Result { + T::fgets(self, path) + } + fn fget_line(&self, path: &Path, line_num: usize) -> Result { + T::fget_line(self, path, line_num) + } + fn canonicalize(&self, path: &Path) -> Result { + T::canonicalize(self, path) + } +} + pub struct Filesystem; impl WitxIo for Filesystem { diff --git a/proposals/random/tools/witx/src/lexer.rs b/proposals/random/tools/witx/src/lexer.rs deleted file mode 100644 index b004acf07..000000000 --- a/proposals/random/tools/witx/src/lexer.rs +++ /dev/null @@ -1,354 +0,0 @@ -use crate::Location; -use failure::Fail; -use std::path::{Path, PathBuf}; -use std::str::CharIndices; - -///! The lexer turns a string into a stream of located tokens. -///! The tokens are meant for consumption by the s-expression parser. -///! -///! Comments in source text look like `;; rest of line ...`. -///! Words look like `abcde_` -///! Idents look like `$abcde_` -///! Annotations look like `@abcde_` -///! Quotes look like `"a b cde 123 @#$%^&*() _"` -///! -///! This implementation was heavily influenced by `cranelift-reader` - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum Token<'a> { - LPar, // ( - RPar, // ) - Word(&'a str), // Bare word - Ident(&'a str), // Starts with $ - Annot(&'a str), // Starts with @. short for annotation. - Quote(&'a str), // Found between balanced "". No escaping. -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct LocatedToken<'a> { - pub token: Token<'a>, - pub location: Location, -} - -fn token(token: Token<'_>, location: Location) -> Result, LocatedError> { - Ok(LocatedToken { token, location }) -} - -#[derive(Debug, PartialEq, Eq, Clone, Copy, Fail)] -pub enum LexError { - #[fail(display = "Invalid character '{}'", _0)] - InvalidChar(char), - #[fail(display = "Empty identifier '$'")] - EmptyIdentifier, - #[fail(display = "Empty annotation '@'")] - EmptyAnnotation, - #[fail(display = "Unterminated quote")] - UnterminatedQuote, -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct LocatedError { - pub error: LexError, - pub location: Location, -} - -fn error<'a>(error: LexError, location: Location) -> Result, LocatedError> { - Err(LocatedError { error, location }) -} - -pub struct Lexer<'a> { - source: &'a str, - chars: CharIndices<'a>, - lookahead: Option, - pos: usize, - line_number: usize, - column_start: usize, - tab_compensation: usize, - path: PathBuf, -} - -impl<'a> Lexer<'a> { - pub fn new>(s: &'a str, path: P) -> Lexer<'_> { - let mut lex = Lexer { - source: s, - chars: s.char_indices(), - lookahead: None, - pos: 0, - line_number: 1, - column_start: 0, - tab_compensation: 0, - path: path.as_ref().into(), - }; - lex.next_ch(); - lex - } - - fn next_ch(&mut self) -> Option { - if self.lookahead == Some('\n') { - self.line_number += 1; - self.column_start = self.pos + 1; // Next column starts a fresh line - self.tab_compensation = 0; - } else if self.lookahead == Some('\t') { - self.tab_compensation += 7; // One column for the position of the char itself, add 7 more for a tabwidth of 8 - } - match self.chars.next() { - Some((idx, ch)) => { - self.pos = idx; - self.lookahead = Some(ch); - } - None => { - self.pos = self.source.len(); - self.lookahead = None; - } - } - self.lookahead - } - - fn loc(&self) -> Location { - Location { - path: self.path.clone(), - line: self.line_number, - column: self.pos - self.column_start + self.tab_compensation, - } - } - - fn looking_at(&self, prefix: &str) -> bool { - self.source[self.pos..].starts_with(prefix) - } - - fn scan_char(&mut self, tok: Token<'a>) -> Result, LocatedError> { - assert!(self.lookahead.is_some()); - let loc = self.loc(); - self.next_ch(); - token(tok, loc) - } - - pub fn rest_of_line(&mut self) -> &'a str { - let begin = self.pos; - loop { - match self.next_ch() { - None | Some('\n') => return &self.source[begin..self.pos], - _ => {} - } - } - } - - fn scan_word(&mut self) -> Result, LocatedError> { - let begin = self.pos; - let loc = self.loc(); - assert!(self.lookahead == Some('_') || self.lookahead.unwrap().is_alphabetic()); - loop { - match self.next_ch() { - Some('_') | Some('-') => {} - Some(ch) if ch.is_alphanumeric() => {} - _ => break, - } - } - let text = &self.source[begin..self.pos]; - token(Token::Word(text), loc) - } - - fn scan_ident(&mut self) -> Result, LocatedError> { - let loc = self.loc(); - assert!(self.lookahead == Some('$')); - match self.next_ch() { - Some(ch) if ch.is_alphanumeric() || ch == '_' => {} - _ => Err(LocatedError { - error: LexError::EmptyIdentifier, - location: loc.clone(), - })?, - } - let begin = self.pos; - - loop { - match self.next_ch() { - Some('_') | Some('-') => {} - Some(ch) if ch.is_alphanumeric() => {} - _ => break, - } - } - - let text = &self.source[begin..self.pos]; - token(Token::Ident(text), loc) - } - - fn scan_annotation(&mut self) -> Result, LocatedError> { - let loc = self.loc(); - assert!(self.lookahead == Some('@')); - match self.next_ch() { - Some(ch) if ch.is_alphanumeric() || ch == '_' => {} - _ => Err(LocatedError { - error: LexError::EmptyAnnotation, - location: loc.clone(), - })?, - } - let begin = self.pos; - - loop { - match self.next_ch() { - Some('_') | Some('-') => {} - Some(ch) if ch.is_alphanumeric() => {} - _ => break, - } - } - - let text = &self.source[begin..self.pos]; - token(Token::Annot(text), loc) - } - - fn scan_quote(&mut self) -> Result, LocatedError> { - let begin = self.pos; - let loc = self.loc(); - assert!(self.lookahead == Some('"')); - loop { - match self.next_ch() { - None => Err(LocatedError { - error: LexError::UnterminatedQuote, - location: loc.clone(), - })?, - Some('"') => { - self.next_ch(); - break; - } - _ => {} - } - } - let text = &self.source[(begin + 1)..(self.pos - 1)]; - token(Token::Quote(text), loc) - } - - #[allow(clippy::should_implement_trait)] - pub fn next(&mut self) -> Option, LocatedError>> { - loop { - let loc = self.loc(); - return match self.lookahead { - None => None, - Some(c) => Some(match c { - '(' => self.scan_char(Token::LPar), - ')' => self.scan_char(Token::RPar), - '$' => self.scan_ident(), - '@' => self.scan_annotation(), - ';' => { - if self.looking_at(";;") { - self.rest_of_line(); - continue; - } else { - self.next_ch(); - error(LexError::InvalidChar(';'), loc) - } - } - '"' => self.scan_quote(), - '_' => self.scan_word(), - ch if ch.is_alphabetic() => self.scan_word(), - ch if ch.is_whitespace() => { - self.next_ch(); - continue; - } - _ => { - self.next_ch(); - error(LexError::InvalidChar(c), loc) - } - }), - }; - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use std::path::{Path, PathBuf}; - - fn testlexer(input: &str) -> Lexer { - Lexer::new(input, Path::new("/test")) - } - - fn token( - token: Token<'_>, - line: usize, - column: usize, - ) -> Option, LocatedError>> { - Some(super::token( - token, - Location { - path: PathBuf::from("/test"), - line, - column, - }, - )) - } - - fn error<'a>( - err: LexError, - line: usize, - column: usize, - ) -> Option, LocatedError>> { - Some(super::error( - err, - Location { - path: PathBuf::from("/test"), - line, - column, - }, - )) - } - #[test] - fn words_and_idents() { - let mut lex = testlexer("$gussie is a good $dog"); - // ruler 0 5 10 15 20 - assert_eq!(lex.next(), token(Token::Ident("gussie"), 1, 0)); - assert_eq!(lex.next(), token(Token::Word("is"), 1, 8)); - assert_eq!(lex.next(), token(Token::Word("a"), 1, 11)); - assert_eq!(lex.next(), token(Token::Word("good"), 1, 13)); - assert_eq!(lex.next(), token(Token::Ident("dog"), 1, 18)); - assert_eq!(lex.next(), None); - - let mut lex = - testlexer("$ok $a $_ $ _\nkebab-case\nsnake_case\n$kebab-ident\n$snake_ident"); - assert_eq!(lex.next(), token(Token::Ident("ok"), 1, 0)); - assert_eq!(lex.next(), token(Token::Ident("a"), 1, 4)); - assert_eq!(lex.next(), token(Token::Ident("_"), 1, 7)); - assert_eq!(lex.next(), error(LexError::EmptyIdentifier, 1, 10)); - assert_eq!(lex.next(), token(Token::Word("_"), 1, 12)); - assert_eq!(lex.next(), token(Token::Word("kebab-case"), 2, 0)); - assert_eq!(lex.next(), token(Token::Word("snake_case"), 3, 0)); - assert_eq!(lex.next(), token(Token::Ident("kebab-ident"), 4, 0)); - assert_eq!(lex.next(), token(Token::Ident("snake_ident"), 5, 0)); - assert_eq!(lex.next(), None); - } - - #[test] - fn comments() { - let mut lex = testlexer("the quick ;; brown fox\njumped\n;;over the three\nlazy;;dogs"); - assert_eq!(lex.next(), token(Token::Word("the"), 1, 0)); - assert_eq!(lex.next(), token(Token::Word("quick"), 1, 4)); - assert_eq!(lex.next(), token(Token::Word("jumped"), 2, 0)); - assert_eq!(lex.next(), token(Token::Word("lazy"), 4, 0)); - assert_eq!(lex.next(), None); - - let mut lex = testlexer("line1 ;;\n$sym_2;\n\t\tl3;;;333"); - assert_eq!(lex.next(), token(Token::Word("line1"), 1, 0)); - assert_eq!(lex.next(), token(Token::Ident("sym_2"), 2, 0)); - assert_eq!(lex.next(), error(LexError::InvalidChar(';'), 2, 6)); - assert_eq!(lex.next(), token(Token::Word("l3"), 3, 16)); // Two tabs = 16 columns - assert_eq!(lex.next(), None); - } - - #[test] - fn quotes() { - let mut lex = testlexer("a \"bc\" d"); - assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); - assert_eq!(lex.next(), token(Token::Quote("bc"), 1, 2)); - assert_eq!(lex.next(), token(Token::Word("d"), 1, 7)); - - let mut lex = testlexer("a \"b\nc\" d"); - assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); - assert_eq!(lex.next(), token(Token::Quote("b\nc"), 1, 2)); - assert_eq!(lex.next(), token(Token::Word("d"), 2, 3)); - - let mut lex = testlexer("a \"b"); - assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); - assert_eq!(lex.next(), error(LexError::UnterminatedQuote, 1, 2)); - } -} diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index af315a9df..60ccf2c9b 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -4,14 +4,10 @@ mod ast; mod coretypes; /// Interface for filesystem or mock IO mod io; -/// Lexer text into tokens -mod lexer; /// Witx syntax parsing from SExprs mod parser; /// Render ast to text mod render; -/// SExpr parsing from tokens -mod sexpr; /// Resolve toplevel `use` declarations across files mod toplevel; /// Validate declarations into ast @@ -25,10 +21,8 @@ pub use ast::{ }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; pub use io::{Filesystem, MockFs, WitxIo}; -pub use lexer::LexError; -pub use parser::{DeclSyntax, ParseError}; +pub use parser::DeclSyntax; pub use render::{Render, SExpr as RenderSExpr}; -pub use sexpr::SExprParseError; pub use validate::ValidationError; use failure::Fail; @@ -36,19 +30,13 @@ use std::path::{Path, PathBuf}; /// Load a witx document from the filesystem pub fn load>(path: P) -> Result { - use toplevel::parse_witx; - use validate::validate_document; - let parsed_decls = parse_witx(path)?; - validate_document(&parsed_decls).map_err(WitxError::Validation) + toplevel::parse_witx(path.as_ref()) } /// Parse a witx document from a str. `(use ...)` directives are not permitted. pub fn parse(source: &str) -> Result { - use toplevel::parse_witx_with; - use validate::validate_document; let mockfs = MockFs::new(&[("-", source)]); - let parsed_decls = parse_witx_with(Path::new("-"), &mockfs)?; - validate_document(&parsed_decls).map_err(WitxError::Validation) + toplevel::parse_witx_with(Path::new("-"), &mockfs) } /// Location in the source text @@ -61,12 +49,10 @@ pub struct Location { #[derive(Debug, Fail)] pub enum WitxError { - #[fail(display = "{}", _0)] - SExpr(#[cause] SExprParseError), #[fail(display = "with file {:?}: {}", _0, _1)] Io(PathBuf, #[cause] ::std::io::Error), #[fail(display = "{}", _0)] - Parse(#[cause] ParseError), + Parse(#[cause] wast::Error), #[fail(display = "{}", _0)] Validation(#[cause] ValidationError), } @@ -75,9 +61,8 @@ impl WitxError { pub fn report_with(&self, witxio: &dyn WitxIo) -> String { use WitxError::*; match self { - SExpr(sexpr) => sexpr.report_with(witxio), Io(path, ioerr) => format!("with file {:?}: {}", path, ioerr), - Parse(parse) => parse.report_with(witxio), + Parse(parse) => parse.to_string(), Validation(validation) => validation.report_with(witxio), } } diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index d12d643ed..8c7a1eecf 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -1,7 +1,4 @@ -use crate::io::{Filesystem, WitxIo}; -use crate::sexpr::SExpr; -use crate::Location; -use failure::Fail; +use wast::parser::{Cursor, Parse, Parser, Peek, Result}; ///! Parser turns s-expressions into unvalidated syntax constructs. ///! conventions: @@ -16,48 +13,31 @@ use failure::Fail; ///! This is used for error reporting in case the slice doesn't have the number of elements ///! expected. -#[derive(Debug, Fail)] -#[fail(display = "{} at {:?}", _0, _1)] -pub struct ParseError { - pub message: String, - pub location: Location, -} - -impl ParseError { - pub fn report_with(&self, witxio: &dyn WitxIo) -> String { - format!( - "{}\n{}", - self.location.highlight_source_with(witxio), - self.message - ) - } - pub fn report(&self) -> String { - self.report_with(&Filesystem) - } -} - -macro_rules! parse_err { - ($loc:expr, $msg:expr) => { - ParseError { message: $msg.to_string(), location: $loc.clone() } - }; - ($loc:expr, $fmt:expr, $( $arg:expr ),+ ) => { - ParseError { message: format!($fmt, $( $arg ),+), location: $loc.clone() } - }; -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct IdentSyntax { - pub name: String, - pub location: Location, -} - -macro_rules! id { - ($s:expr, $loc: expr) => { - IdentSyntax { - name: $s.to_string(), - location: $loc.clone(), - } - }; +mod kw { + pub use wast::kw::{export, func, import, memory, module, param, result}; + + wast::custom_keyword!(array); + wast::custom_keyword!(const_pointer); + wast::custom_keyword!(f32); + wast::custom_keyword!(f64); + wast::custom_keyword!(field); + wast::custom_keyword!(flag); + wast::custom_keyword!(flags); + wast::custom_keyword!(pointer); + wast::custom_keyword!(r#enum = "enum"); + wast::custom_keyword!(r#struct = "struct"); + wast::custom_keyword!(r#union = "union"); + wast::custom_keyword!(r#use = "use"); + wast::custom_keyword!(s16); + wast::custom_keyword!(s32); + wast::custom_keyword!(s64); + wast::custom_keyword!(s8); + wast::custom_keyword!(string); + wast::custom_keyword!(typename); + wast::custom_keyword!(u16); + wast::custom_keyword!(u32); + wast::custom_keyword!(u64); + wast::custom_keyword!(u8); } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -75,514 +55,450 @@ pub enum BuiltinType { F64, } -impl BuiltinType { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - match sexpr { - SExpr::Word("string", _) - | SExpr::Word("u8", _) - | SExpr::Word("u16", _) - | SExpr::Word("u32", _) - | SExpr::Word("u64", _) - | SExpr::Word("s8", _) - | SExpr::Word("s16", _) - | SExpr::Word("s32", _) - | SExpr::Word("s64", _) - | SExpr::Word("f32", _) - | SExpr::Word("f64", _) => true, - _ => false, - } - } - pub fn parse(sexpr: &SExpr) -> Result { - match sexpr { - SExpr::Word("string", _loc) => Ok(BuiltinType::String), - SExpr::Word("u8", _loc) => Ok(BuiltinType::U8), - SExpr::Word("u16", _loc) => Ok(BuiltinType::U16), - SExpr::Word("u32", _loc) => Ok(BuiltinType::U32), - SExpr::Word("u64", _loc) => Ok(BuiltinType::U64), - SExpr::Word("s8", _loc) => Ok(BuiltinType::S8), - SExpr::Word("s16", _loc) => Ok(BuiltinType::S16), - SExpr::Word("s32", _loc) => Ok(BuiltinType::S32), - SExpr::Word("s64", _loc) => Ok(BuiltinType::S64), - SExpr::Word("f32", _loc) => Ok(BuiltinType::F32), - SExpr::Word("f64", _loc) => Ok(BuiltinType::F64), - _ => Err(parse_err!(sexpr.location(), "invalid builtin type")), +impl Parse<'_> for BuiltinType { + fn parse(parser: Parser<'_>) -> Result { + let mut l = parser.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::String) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::U8) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::U16) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::U32) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::U64) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::S8) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::S16) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::S32) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::S64) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::F32) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::F64) + } else { + Err(l.error()) } } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum DatatypeIdentSyntax { +pub enum DatatypeIdentSyntax<'a> { Builtin(BuiltinType), - Array(Box), - Pointer(Box), - ConstPointer(Box), - Ident(IdentSyntax), -} - -impl DatatypeIdentSyntax { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - BuiltinType::starts_parsing(sexpr) - || match sexpr { - SExpr::Ident(_, _) => true, - SExpr::Vec(v, _) => match (v.get(0), v.get(1)) { - (Some(SExpr::Word("array", _)), Some(_)) => true, - (Some(SExpr::Annot("witx", _)), Some(SExpr::Word("pointer", _))) => true, - (Some(SExpr::Annot("witx", _)), Some(SExpr::Word("const_pointer", _))) => true, - _ => false, - }, - _ => false, + Array(Box>), + Pointer(Box>), + ConstPointer(Box>), + Ident(wast::Id<'a>), +} + +impl<'a> Parse<'a> for DatatypeIdentSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + if parser.peek::() { + Ok(DatatypeIdentSyntax::Ident(parser.parse()?)) + } else if parser.peek2::() { + Ok(DatatypeIdentSyntax::Array(parser.parens(|p| { + p.parse::()?; + Ok(Box::new(parser.parse()?)) + })?)) + } else if parser.peek::() { + parser.parens(|p| { + p.parse::()?; + if p.peek::() { + p.parse::()?; + Ok(DatatypeIdentSyntax::ConstPointer(Box::new(p.parse()?))) + } else { + p.parse::()?; + Ok(DatatypeIdentSyntax::Pointer(Box::new(p.parse()?))) + } + }) + } else { + Ok(DatatypeIdentSyntax::Builtin(parser.parse()?)) + } + } +} + +struct AtWitx; + +impl Parse<'_> for AtWitx { + fn parse(parser: Parser<'_>) -> Result { + parser.step(|c| { + if let Some(("@witx", rest)) = c.reserved() { + return Ok((AtWitx, rest)); } + Err(c.error("expected `@witx`")) + }) } - pub fn parse(sexpr: &SExpr) -> Result { - if BuiltinType::starts_parsing(sexpr) { - let builtin = BuiltinType::parse(sexpr)?; - Ok(DatatypeIdentSyntax::Builtin(builtin)) - } else { - match sexpr { - SExpr::Ident(i, loc) => Ok(DatatypeIdentSyntax::Ident(id!(i, loc))), - SExpr::Vec(v, loc) => match (v.get(0), v.get(1), v.get(2)) { - (Some(SExpr::Word("array", _)), Some(expr), None) => Ok( - DatatypeIdentSyntax::Array(Box::new(DatatypeIdentSyntax::parse(expr)?)), - ), - ( - Some(SExpr::Annot("witx", _)), - Some(SExpr::Word("pointer", _)), - Some(expr), - ) => Ok(DatatypeIdentSyntax::Pointer(Box::new( - DatatypeIdentSyntax::parse(expr)?, - ))), - ( - Some(SExpr::Annot("witx", _)), - Some(SExpr::Word("const_pointer", _)), - Some(expr), - ) => Ok(DatatypeIdentSyntax::ConstPointer(Box::new( - DatatypeIdentSyntax::parse(expr)?, - ))), - _ => Err(parse_err!(loc, "expected type identifier")), - }, - _ => Err(parse_err!(sexpr.location(), "expected type identifier")), +} + +impl Peek for AtWitx { + fn peek(cursor: Cursor<'_>) -> bool { + cursor.reserved().map(|s| s.0) == Some("@witx") + } + + fn display() -> &'static str { + "`@witx`" + } +} + +struct AtInterface; + +impl Parse<'_> for AtInterface { + fn parse(parser: Parser<'_>) -> Result { + parser.step(|c| { + if let Some(("@interface", rest)) = c.reserved() { + return Ok((AtInterface, rest)); } - } + Err(c.error("expected `@interface`")) + }) + } +} + +impl Peek for AtInterface { + fn peek(cursor: Cursor<'_>) -> bool { + cursor.reserved().map(|s| s.0) == Some("@interface") + } + + fn display() -> &'static str { + "`@interface`" } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum TopLevelSyntax { - Decl(DeclSyntax), - Use(IdentSyntax), +pub struct TopLevelDocument<'a> { + pub items: Vec>, } -impl TopLevelSyntax { - pub fn parse(sexpr: &SExpr) -> Result { - if DeclSyntax::starts_parsing(sexpr) { - let decl = DeclSyntax::parse(sexpr)?; - Ok(TopLevelSyntax::Decl(decl)) - } else { - match sexpr { - SExpr::Vec(v, vec_loc) => match v.get(0) { - Some(SExpr::Word("use", loc)) => match v.get(1) { - Some(SExpr::Quote(u, loc)) => Ok(TopLevelSyntax::Use(id!(u, loc))), - _ => Err(parse_err!(loc, "invalid use declaration")), - }, - _ => Err(parse_err!(vec_loc, "expected top level declaration")), - }, - _ => Err(parse_err!( - sexpr.location(), - "expected top level declaration" - )), - } +impl<'a> Parse<'a> for TopLevelDocument<'a> { + fn parse(parser: Parser<'a>) -> Result { + let mut items = Vec::new(); + while !parser.is_empty() { + items.push(parser.parens(|p| p.parse())?); } + Ok(TopLevelDocument { items }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum DeclSyntax { - Typename(TypenameSyntax), - Module(ModuleSyntax), -} - -impl DeclSyntax { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - match sexpr { - SExpr::Vec(v, _) => match v.get(0) { - Some(SExpr::Word("typename", _)) => true, - Some(SExpr::Word("module", _)) => true, - _ => false, - }, - _ => false, +pub enum TopLevelSyntax<'a> { + Decl(DeclSyntax<'a>), + Use(&'a str), +} + +impl<'a> Parse<'a> for TopLevelSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + if parser.peek::() { + parser.parse::()?; + Ok(TopLevelSyntax::Use(parser.parse()?)) + } else { + Ok(TopLevelSyntax::Decl(parser.parse()?)) } } - pub fn parse(sexpr: &SExpr) -> Result { - match sexpr { - SExpr::Vec(v, loc) => match v.get(0) { - Some(SExpr::Word("typename", loc)) => { - Ok(DeclSyntax::Typename(TypenameSyntax::parse(&v[1..], loc)?)) - } - Some(SExpr::Word("module", loc)) => { - Ok(DeclSyntax::Module(ModuleSyntax::parse(&v[1..], loc)?)) - } - _ => Err(parse_err!(loc, "invalid declaration")), - }, - _ => Err(parse_err!(sexpr.location(), "expected vec")), +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum DeclSyntax<'a> { + Typename(TypenameSyntax<'a>), + Module(ModuleSyntax<'a>), +} + +impl<'a> Parse<'a> for DeclSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(DeclSyntax::Module(parser.parse()?)) + } else if l.peek::() { + Ok(DeclSyntax::Typename(parser.parse()?)) + } else { + Err(l.error()) } } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct TypenameSyntax { - pub ident: IdentSyntax, - pub def: TypedefSyntax, -} - -impl TypenameSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - let ident = match sexpr.get(0) { - Some(SExpr::Ident(i, loc)) => id!(i, loc), - Some(s) => Err(parse_err!(s.location(), "expected typename identifier"))?, - None => Err(parse_err!(loc, "expected typename identifier"))?, - }; - let def = match sexpr.get(1) { - Some(expr) => TypedefSyntax::parse(expr)?, - _ => Err(parse_err!(loc, "expected type definition"))?, - }; +pub struct TypenameSyntax<'a> { + pub ident: wast::Id<'a>, + pub def: TypedefSyntax<'a>, +} + +impl<'a> Parse<'a> for TypenameSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let ident = parser.parse()?; + let def = parser.parse()?; Ok(TypenameSyntax { ident, def }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum TypedefSyntax { - Ident(DatatypeIdentSyntax), - Enum(EnumSyntax), - Flags(FlagsSyntax), - Struct(StructSyntax), - Union(UnionSyntax), -} - -impl TypedefSyntax { - pub fn parse(sexpr: &SExpr) -> Result { - if DatatypeIdentSyntax::starts_parsing(sexpr) { - let ident = DatatypeIdentSyntax::parse(sexpr)?; - Ok(TypedefSyntax::Ident(ident)) - } else { - match sexpr { - SExpr::Vec(vs, loc) => match vs.get(0) { - Some(SExpr::Word("enum", loc)) => { - Ok(TypedefSyntax::Enum(EnumSyntax::parse(&vs[1..], loc)?)) - } - Some(SExpr::Word("flags", loc)) => { - Ok(TypedefSyntax::Flags(FlagsSyntax::parse(&vs[1..], loc)?)) - } - Some(SExpr::Word("struct", loc)) => { - Ok(TypedefSyntax::Struct(StructSyntax::parse(&vs[1..], loc)?)) - } - Some(SExpr::Word("union", loc)) => { - Ok(TypedefSyntax::Union(UnionSyntax::parse(&vs[1..], loc)?)) - } - _ => Err(parse_err!( - loc, - "expected type identifier or type definition" - )), - }, - _ => Err(parse_err!( - sexpr.location(), - "expected type identifier or type definition" - )), - } +pub enum TypedefSyntax<'a> { + Ident(DatatypeIdentSyntax<'a>), + Enum(EnumSyntax<'a>), + Flags(FlagsSyntax<'a>), + Struct(StructSyntax<'a>), + Union(UnionSyntax<'a>), +} + +impl<'a> Parse<'a> for TypedefSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + if !parser.peek::() || parser.peek2::() || parser.peek2::() + { + return Ok(TypedefSyntax::Ident(parser.parse()?)); } + parser.parens(|parser| { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(TypedefSyntax::Enum(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Flags(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Struct(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Union(parser.parse()?)) + } else { + Err(l.error()) + } + }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct EnumSyntax { +pub struct EnumSyntax<'a> { pub repr: BuiltinType, - pub members: Vec, -} - -impl EnumSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - let repr = match sexpr.get(0) { - Some(e) => BuiltinType::parse(e)?, - _ => Err(parse_err!(loc, "no enum repr"))?, - }; - let members = sexpr[1..] - .iter() - .map(|m| match m { - SExpr::Ident(i, loc) => Ok(id!(i, loc)), - s => Err(parse_err!(s.location(), "expected enum member identifier")), - }) - .collect::, ParseError>>()?; - if members.is_empty() { - Err(parse_err!(loc, "expected at least one enum member"))? + pub members: Vec>, +} + +impl<'a> Parse<'a> for EnumSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let repr = parser.parse()?; + let mut members = Vec::new(); + members.push(parser.parse()?); + while !parser.is_empty() { + members.push(parser.parse()?); } Ok(EnumSyntax { repr, members }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct FlagsSyntax { +pub struct FlagsSyntax<'a> { pub repr: BuiltinType, - pub flags: Vec, -} - -impl FlagsSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - let repr = BuiltinType::parse( - sexpr - .get(0) - .ok_or_else(|| parse_err!(loc, "expected flag repr type"))?, - )?; - let flags = sexpr[1..] - .iter() - .map(|f| match f { - SExpr::Vec(vs, loc) => match (vs.get(0), vs.get(1)) { - (Some(SExpr::Word("flag", _)), Some(SExpr::Ident(i, loc))) => Ok(id!(i, loc)), - _ => Err(parse_err!(loc, "expected flag specifier")), - }, - s => Err(parse_err!(s.location(), "expected flag specifier")), - }) - .collect::, ParseError>>()?; + pub flags: Vec>, +} + +impl<'a> Parse<'a> for FlagsSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let repr = parser.parse()?; + let mut flags = Vec::new(); + while !parser.is_empty() { + flags.push(parser.parens(|parser| { + parser.parse::()?; + parser.parse() + })?); + } Ok(FlagsSyntax { repr, flags }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct StructSyntax { - pub fields: Vec, +pub struct StructSyntax<'a> { + pub fields: Vec>, } -impl StructSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - if sexpr.is_empty() { - Err(parse_err!(loc, "expected at least one struct member"))? +impl<'a> Parse<'a> for StructSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let mut fields = Vec::new(); + fields.push(parser.parens(|p| p.parse())?); + while !parser.is_empty() { + fields.push(parser.parens(|p| p.parse())?); } - let fields = sexpr - .iter() - .map(|f| FieldSyntax::parse(f, "field")) - .collect::, ParseError>>()?; Ok(StructSyntax { fields }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct FieldSyntax { - pub name: IdentSyntax, - pub type_: DatatypeIdentSyntax, -} - -impl FieldSyntax { - pub fn starts_parsing(sexpr: &SExpr, constructor: &str) -> bool { - match sexpr { - SExpr::Vec(v, _) => match v.get(0) { - Some(SExpr::Word(c, _)) => *c == constructor, - _ => false, - }, - _ => false, - } - } - pub fn parse(sexpr: &SExpr, constructor: &str) -> Result { - match sexpr { - SExpr::Vec(v, loc) => match v.get(0) { - Some(SExpr::Word(c, _)) if *c == constructor => { - let name = match v.get(1) { - Some(SExpr::Ident(i, loc)) => id!(i, loc), - _ => Err(parse_err!(loc, "expected {} name identifier", constructor))?, - }; - let type_ = DatatypeIdentSyntax::parse(v.get(2).ok_or_else(|| { - parse_err!(loc, "expected {} type identifier", constructor) - })?)?; - Ok(FieldSyntax { name, type_ }) - } - _ => Err(parse_err!(loc, "expected {}", constructor)), - }, - _ => Err(parse_err!(sexpr.location(), "expected {}", constructor)), - } +pub struct FieldSyntax<'a> { + pub name: wast::Id<'a>, + pub type_: DatatypeIdentSyntax<'a>, +} + +impl<'a> Parse<'a> for FieldSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let name = parser.parse()?; + let type_ = parser.parse()?; + Ok(FieldSyntax { name, type_ }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct UnionSyntax { - pub fields: Vec, +pub struct UnionSyntax<'a> { + pub fields: Vec>, } -impl UnionSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - if sexpr.is_empty() { - Err(parse_err!(loc, "expected at least one union member"))? +impl<'a> Parse<'a> for UnionSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let mut fields = Vec::new(); + fields.push(parser.parens(|p| p.parse())?); + while !parser.is_empty() { + fields.push(parser.parens(|p| p.parse())?); } - let fields = sexpr - .iter() - .map(|f| FieldSyntax::parse(f, "field")) - .collect::, ParseError>>()?; Ok(UnionSyntax { fields }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct ModuleSyntax { - pub name: IdentSyntax, - pub decls: Vec, -} - -impl ModuleSyntax { - pub fn parse(sexprs: &[SExpr], loc: &Location) -> Result { - let name = match sexprs.get(0) { - Some(SExpr::Ident(i, loc)) => id!(i, loc), - _ => Err(parse_err!(loc, "expected module name"))?, - }; - let decls = sexprs[1..] - .iter() - .map(|s| ModuleDeclSyntax::parse(s)) - .collect::, _>>()?; +pub struct ModuleSyntax<'a> { + pub name: wast::Id<'a>, + pub decls: Vec>, +} + +impl<'a> Parse<'a> for ModuleSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let name = parser.parse()?; + let mut decls = Vec::new(); + while !parser.is_empty() { + decls.push(parser.parens(|p| p.parse())?); + } Ok(ModuleSyntax { name, decls }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum ModuleDeclSyntax { - Import(ModuleImportSyntax), - Func(InterfaceFuncSyntax), -} - -impl ModuleDeclSyntax { - pub fn parse(sexpr: &SExpr) -> Result { - if ModuleImportSyntax::starts_parsing(sexpr) { - Ok(ModuleDeclSyntax::Import(ModuleImportSyntax::parse(sexpr)?)) - } else if InterfaceFuncSyntax::starts_parsing(sexpr) { - Ok(ModuleDeclSyntax::Func(InterfaceFuncSyntax::parse(sexpr)?)) +pub enum ModuleDeclSyntax<'a> { + Import(ModuleImportSyntax<'a>), + Func(InterfaceFuncSyntax<'a>), +} + +impl<'a> Parse<'a> for ModuleDeclSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(ModuleDeclSyntax::Import(parser.parse()?)) + } else if l.peek::() { + Ok(ModuleDeclSyntax::Func(parser.parse()?)) } else { - Err(parse_err!(sexpr.location(), "expected import or function")) + Err(l.error()) } } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ModuleImportSyntax { - pub name: IdentSyntax, +#[derive(Debug, Clone)] +pub struct ModuleImportSyntax<'a> { + pub name: &'a str, + pub name_loc: wast::Span, pub type_: ImportTypeSyntax, } -impl ModuleImportSyntax { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - match sexpr { - SExpr::Vec(vs, _) => match vs.get(0) { - Some(SExpr::Word("import", _)) => true, - _ => false, - }, - _ => false, - } +impl<'a> Parse<'a> for ModuleImportSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let name_loc = parser.cur_span(); + Ok(ModuleImportSyntax { + name: parser.parse()?, + name_loc, + type_: parser.parens(|p| p.parse())?, + }) } - pub fn parse(sexpr: &SExpr) -> Result { - match sexpr { - SExpr::Vec(vs, vec_loc) => match (vs.get(0), vs.get(1)) { - (Some(SExpr::Word("import", _)), Some(SExpr::Quote(name, loc))) => { - let name = id!(name, loc); - let type_ = ImportTypeSyntax::parse(&vs[2..], vec_loc)?; - Ok(ModuleImportSyntax { name, type_ }) - } - _ => Err(parse_err!(vec_loc, "expected module import")), - }, - _ => Err(parse_err!(sexpr.location(), "expected module import")), - } +} + +impl PartialEq for ModuleImportSyntax<'_> { + fn eq(&self, other: &ModuleImportSyntax<'_>) -> bool { + // skip the `name_loc` field + self.name == other.name && self.type_ == other.type_ } } +impl Eq for ModuleImportSyntax<'_> {} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum ImportTypeSyntax { Memory, } -impl ImportTypeSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - if sexpr.len() > 1 { - Err(parse_err!(loc, "too many elements for an import type"))?; - } - match sexpr.get(0) { - Some(SExpr::Vec(vs, loc)) => match vs.get(0) { - Some(SExpr::Word("memory", _)) => { - if vs.len() == 1 { - Ok(ImportTypeSyntax::Memory) - } else { - Err(parse_err!(loc, "too many elements for memory declaration")) - } - } - _ => Err(parse_err!(loc, "expected import type")), - }, - _ => Err(parse_err!(loc, "expected import type")), - } +impl Parse<'_> for ImportTypeSyntax { + fn parse(parser: Parser<'_>) -> Result { + parser.parse::()?; + Ok(ImportTypeSyntax::Memory) } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct InterfaceFuncSyntax { - pub export: IdentSyntax, - pub params: Vec, - pub results: Vec, -} - -impl InterfaceFuncSyntax { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - match sexpr { - SExpr::Vec(vs, _) => match (vs.get(0), vs.get(1)) { - (Some(SExpr::Annot("interface", _)), Some(SExpr::Word("func", _))) => true, - _ => false, - }, - _ => false, +#[derive(Debug, Clone)] +pub struct InterfaceFuncSyntax<'a> { + pub export: &'a str, + pub export_loc: wast::Span, + pub params: Vec>, + pub results: Vec>, +} + +impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + parser.parse::()?; + + let (export_loc, export) = parser.parens(|p| { + p.parse::()?; + Ok((p.cur_span(), p.parse()?)) + })?; + + let mut params = Vec::new(); + let mut results = Vec::new(); + + while !parser.is_empty() { + parser.parens(|p| { + let mut l = p.lookahead1(); + if l.peek::() { + parser.parse::()?; + params.push(FieldSyntax { + name: parser.parse()?, + type_: parser.parse()?, + }); + } else if l.peek::() { + parser.parse::()?; + results.push(FieldSyntax { + name: parser.parse()?, + type_: parser.parse()?, + }); + } else { + return Err(l.error()); + } + Ok(()) + })?; } + + Ok(InterfaceFuncSyntax { + export, + export_loc, + params, + results, + }) } - pub fn parse(sexpr: &SExpr) -> Result { - match sexpr { - SExpr::Vec(vs, loc) => match (vs.get(0), vs.get(1)) { - (Some(SExpr::Annot("interface", _)), Some(SExpr::Word("func", _))) => { - let export = match vs.get(2) { - Some(SExpr::Vec(es, loc)) => match (es.get(0), es.get(1)) { - ( - Some(SExpr::Word("export", _)), - Some(SExpr::Quote(name, name_loc)), - ) => { - if es.len() == 2 { - id!(name, name_loc) - } else { - Err(parse_err!( - loc, - "too many elements for export declaration" - ))? - } - } - _ => Err(parse_err!(loc, "expected export declaration"))?, - }, - _ => Err(parse_err!(loc, "expected export declaration"))?, - }; - let mut params = Vec::new(); - let mut results = Vec::new(); - - for sexpr in &vs[3..] { - if FieldSyntax::starts_parsing(sexpr, "param") { - let param = FieldSyntax::parse(sexpr, "param")?; - params.push(param); - } else if FieldSyntax::starts_parsing(sexpr, "result") { - let result = FieldSyntax::parse(sexpr, "result")?; - results.push(result); - } else { - Err(parse_err!( - sexpr.location(), - "expected param or result field" - ))?; - } - } - - Ok(InterfaceFuncSyntax { - export, - params, - results, - }) - } - _ => Err(parse_err!(loc, "expected interface func declaration")), - }, +} - _ => Err(parse_err!( - sexpr.location(), - "expected interface func declaration" - )), - } +impl PartialEq for InterfaceFuncSyntax<'_> { + fn eq(&self, other: &InterfaceFuncSyntax<'_>) -> bool { + // skip the `export_loc` field + self.export == other.export && self.params == other.params && self.results == other.results } } + +impl Eq for InterfaceFuncSyntax<'_> {} diff --git a/proposals/random/tools/witx/src/sexpr.rs b/proposals/random/tools/witx/src/sexpr.rs deleted file mode 100644 index d87d427e3..000000000 --- a/proposals/random/tools/witx/src/sexpr.rs +++ /dev/null @@ -1,240 +0,0 @@ -use crate::io::{Filesystem, WitxIo}; -pub use crate::lexer::LexError; -use crate::lexer::{Lexer, LocatedError, LocatedToken, Token}; -use crate::Location; -use failure::Fail; -use std::path::{Path, PathBuf}; - -///! The s-expression parser turns a string into a stream of SExprs. -///! It uses the `Lexer` under the hood. -///! This implementation was heavily influenced by `cranelift-reader` - -#[derive(Debug, PartialEq, Eq, Clone)] -pub enum SExpr<'a> { - Vec(Vec>, Location), - Word(&'a str, Location), - Ident(&'a str, Location), - Quote(&'a str, Location), - /// Short for Annotation - Annot(&'a str, Location), -} - -impl<'a> SExpr<'a> { - pub fn location(&self) -> Location { - match self { - SExpr::Vec(_, loc) => loc.clone(), - SExpr::Word(_, loc) => loc.clone(), - SExpr::Ident(_, loc) => loc.clone(), - SExpr::Quote(_, loc) => loc.clone(), - SExpr::Annot(_, loc) => loc.clone(), - } - } -} - -#[derive(Debug, PartialEq, Eq, Clone, Fail)] -pub enum SExprParseError { - #[fail(display = "Lexical error: {}", _0)] - Lex(LexError, Location), - #[fail(display = "Unexpected ')'")] - UnexpectedCloseParen(Location), - #[fail(display = "Unexpected end of input in {:?}", _0)] - UnexpectedEof(PathBuf), -} - -impl SExprParseError { - pub fn report_with(&self, witxio: &dyn WitxIo) -> String { - use SExprParseError::*; - match self { - Lex(lex_err, loc) => format!("{}\n{}", loc.highlight_source_with(witxio), lex_err), - UnexpectedCloseParen(loc) => format!("{}\n{}", loc.highlight_source_with(witxio), self), - UnexpectedEof(_path) => format!("{}", self), - } - } - pub fn report(&self) -> String { - self.report_with(&Filesystem) - } -} - -pub struct SExprParser<'a> { - lex: Lexer<'a>, - lookahead: Option>, - location: Location, -} - -impl<'a> SExprParser<'a> { - pub fn new>(text: &'a str, path: P) -> SExprParser<'_> { - SExprParser { - lex: Lexer::new(text, path.as_ref()), - lookahead: None, - location: Location { - path: path.as_ref().into(), - line: 0, - column: 0, - }, - } - } - fn consume(&mut self) -> Token<'a> { - self.lookahead.take().expect("no token to consume") - } - fn token(&mut self) -> Result>, SExprParseError> { - while self.lookahead == None { - match self.lex.next() { - Some(Ok(LocatedToken { token, location })) => { - self.location = location; - self.lookahead = Some(token) - } - Some(Err(LocatedError { error, location })) => { - self.location = location.clone(); - Err(SExprParseError::Lex(error, location))?; - } - None => break, - } - } - Ok(self.lookahead) - } - - pub fn match_sexpr(&mut self) -> Result, SExprParseError> { - let location = self.location.clone(); - match self.token()? { - Some(Token::LPar) => { - self.consume(); - let mut members = Vec::new(); - loop { - match self.token()? { - Some(Token::RPar) => { - self.consume(); - break; - } - _ => { - members.push(self.match_sexpr()?); - } - } - } - Ok(SExpr::Vec(members, location)) - } - Some(Token::Word(word)) => { - self.consume(); - Ok(SExpr::Word(word, location)) - } - Some(Token::Ident(id)) => { - self.consume(); - Ok(SExpr::Ident(id, location)) - } - Some(Token::Annot(id)) => { - self.consume(); - Ok(SExpr::Annot(id, location)) - } - Some(Token::Quote(q)) => { - self.consume(); - Ok(SExpr::Quote(q, location)) - } - Some(Token::RPar) => Err(SExprParseError::UnexpectedCloseParen(location)), - None => Err(SExprParseError::UnexpectedEof(self.location.path.clone())), - } - } - - pub fn match_sexprs(&mut self) -> Result>, SExprParseError> { - let mut sexprs = Vec::new(); - while self.token()?.is_some() { - sexprs.push(self.match_sexpr()?); - } - Ok(sexprs) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use std::path::PathBuf; - - fn loc(line: usize, col: usize) -> Location { - Location { - path: PathBuf::from("/test"), - line: line, - column: col, - } - } - - fn testparser(input: &str) -> SExprParser { - SExprParser::new(input, Path::new("/test")) - } - - #[test] - fn empty() { - let mut parser = testparser(""); - assert_eq!(parser.match_sexprs().expect("valid parse"), Vec::new()); - let mut parser = testparser(" ;; just a comment\n;;another"); - assert_eq!(parser.match_sexprs().expect("valid parse"), Vec::new()); - } - - #[test] - fn atoms() { - let mut parser = testparser("hello\n$world\n\"a quotation\""); - assert_eq!( - parser.match_sexprs().expect("valid parse"), - vec![ - SExpr::Word("hello", loc(1, 0)), - SExpr::Ident("world", loc(2, 0)), - SExpr::Quote("a quotation", loc(3, 0)), - ] - ); - } - - #[test] - fn lists() { - let mut parser = testparser("()"); - assert_eq!( - parser.match_sexprs().expect("valid parse"), - vec![SExpr::Vec(vec![], loc(1, 0))] - ); - - let mut parser = testparser("(hello\n$world\n\"a quotation\")"); - assert_eq!( - parser.match_sexprs().expect("valid parse"), - vec![SExpr::Vec( - vec![ - SExpr::Word("hello", loc(1, 1)), - SExpr::Ident("world", loc(2, 0)), - SExpr::Quote("a quotation", loc(3, 0)), - ], - loc(1, 0) - )] - ); - - let mut parser = testparser("((($deep)))"); - assert_eq!( - parser.match_sexprs().expect("valid parse"), - vec![SExpr::Vec( - vec![SExpr::Vec( - vec![SExpr::Vec(vec![SExpr::Ident("deep", loc(1, 3))], loc(1, 2))], - loc(1, 1) - )], - loc(1, 0) - )] - ); - } - - #[test] - fn errors() { - let mut parser = testparser("("); - assert_eq!( - parser.match_sexprs().err().expect("dies"), - SExprParseError::UnexpectedEof(PathBuf::from("/test")) - ); - let mut parser = testparser(")"); - assert_eq!( - parser.match_sexprs().err().expect("dies"), - SExprParseError::UnexpectedCloseParen(loc(1, 0)) - ); - let mut parser = testparser("())"); - assert_eq!( - parser.match_sexprs().err().expect("dies"), - SExprParseError::UnexpectedCloseParen(loc(1, 2)) - ); - let mut parser = testparser("$ ;; should be a lex error"); - assert_eq!( - parser.match_sexprs().err().expect("dies"), - SExprParseError::Lex(LexError::EmptyIdentifier, loc(1, 0),), - ); - } -} diff --git a/proposals/random/tools/witx/src/toplevel.rs b/proposals/random/tools/witx/src/toplevel.rs index 98325b39c..927bdd4de 100644 --- a/proposals/random/tools/witx/src/toplevel.rs +++ b/proposals/random/tools/witx/src/toplevel.rs @@ -1,162 +1,144 @@ +use crate::ast::{Definition, Document}; use crate::io::{Filesystem, WitxIo}; -use crate::parser::{DeclSyntax, ParseError, TopLevelSyntax}; -use crate::sexpr::SExprParser; +use crate::parser::{TopLevelDocument, TopLevelSyntax}; +use crate::validate::DocValidation; use crate::WitxError; use std::collections::HashSet; use std::path::{Path, PathBuf}; -pub fn parse_witx>(i: P) -> Result, WitxError> { - parse_witx_with(i, &Filesystem) +pub fn parse_witx(i: impl AsRef) -> Result { + _parse_witx_with(i.as_ref(), &Filesystem) } -pub fn parse_witx_with>( - i: P, - witxio: &dyn WitxIo, -) -> Result, WitxError> { - let input_path = witxio.canonicalize(&i.as_ref())?; - - let input = witxio.fgets(&input_path)?; - - let toplevel = parse_toplevel(&input, &input_path)?; - let mut resolved = HashSet::new(); - resolved.insert(input_path.clone()); - let search_path = input_path.parent().unwrap_or(Path::new(".")); - resolve_uses(toplevel, &search_path, &mut resolved, witxio) +pub fn parse_witx_with(i: impl AsRef, witxio: impl WitxIo) -> Result { + _parse_witx_with(i.as_ref(), &witxio) } -fn parse_toplevel(source_text: &str, file_path: &Path) -> Result, WitxError> { - let mut sexpr_parser = SExprParser::new(source_text, file_path); - let sexprs = sexpr_parser.match_sexprs().map_err(WitxError::SExpr)?; - let top_levels = sexprs - .iter() - .map(|s| TopLevelSyntax::parse(s)) - .collect::, ParseError>>() - .map_err(WitxError::Parse)?; - Ok(top_levels) +fn _parse_witx_with(path: &Path, io: &dyn WitxIo) -> Result { + let mut validator = DocValidation::new(); + let mut definitions = Vec::new(); + let root = path.parent().unwrap_or(Path::new(".")); + + parse_file( + path.file_name().unwrap().as_ref(), + io, + root, + &mut validator, + &mut definitions, + &mut HashSet::new(), + )?; + Ok(Document::new(definitions, validator.entries)) } -fn resolve_uses( - toplevel: Vec, - search_path: &Path, - used: &mut HashSet, - witxio: &dyn WitxIo, -) -> Result, WitxError> { - let mut decls = Vec::new(); +fn parse_file( + path: &Path, + io: &dyn WitxIo, + root: &Path, + validator: &mut DocValidation, + definitions: &mut Vec, + parsed: &mut HashSet, +) -> Result<(), WitxError> { + let path = io.canonicalize(&root.join(path))?; + if !parsed.insert(path.clone()) { + return Ok(()); + } + let input = io.fgets(&path)?; + + let adjust_err = |mut error: wast::Error| { + error.set_path(&path); + error.set_text(&input); + WitxError::Parse(error) + }; + let buf = wast::parser::ParseBuffer::new(&input).map_err(adjust_err)?; + let doc = wast::parser::parse::(&buf).map_err(adjust_err)?; - for t in toplevel { + for t in doc.items { match t { - TopLevelSyntax::Decl(d) => decls.push(d), + TopLevelSyntax::Decl(d) => { + let def = validator + .scope(&input, &path) + .validate_decl(&d) + .map_err(WitxError::Validation)?; + definitions.push(def); + } TopLevelSyntax::Use(u) => { - let abs_path = witxio.canonicalize(&search_path.join(u.name))?; - // Include the decls from a use declaration only once - // in a given toplevel. Same idea as #pragma once. - if !used.contains(&abs_path) { - used.insert(abs_path.clone()); - - let source_text = witxio.fgets(&abs_path)?; - let inner_toplevels = parse_toplevel(&source_text, &abs_path)?; - - let inner_decls = resolve_uses(inner_toplevels, search_path, used, witxio)?; - decls.extend(inner_decls) - } + parse_file(u.as_ref(), io, root, validator, definitions, parsed)?; } } } - Ok(decls) + Ok(()) } #[cfg(test)] mod test { use super::*; + use crate::ast::*; use crate::io::MockFs; - use crate::parser::*; - use crate::Location; #[test] fn empty() { - assert_eq!( - parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", ";; empty")])).expect("parse"), - Vec::new(), - ); + parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", ";; empty")])).expect("parse"); } #[test] fn one_use() { - assert_eq!( - parse_witx_with( - &Path::new("/a"), - &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]) - ) - .expect("parse"), - Vec::new(), - ); + parse_witx_with( + &Path::new("/a"), + &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]), + ) + .unwrap(); } #[test] fn multi_use() { - assert_eq!( - parse_witx_with( - &Path::new("/a"), - &MockFs::new(&[ - ("/a", "(use \"b\")"), - ("/b", "(use \"c\")\n(typename $b_float f64)"), - ("/c", "(typename $c_int u32)") - ]) - ) - .expect("parse"), - vec![ - DeclSyntax::Typename(TypenameSyntax { - ident: IdentSyntax { - name: "c_int".to_owned(), - location: Location { - path: PathBuf::from("/c"), - line: 1, - column: 10, - } - }, - def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::U32)) - }), - DeclSyntax::Typename(TypenameSyntax { - ident: IdentSyntax { - name: "b_float".to_owned(), - location: Location { - path: PathBuf::from("/b"), - line: 2, - column: 10, - } - }, - def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::F64)) - }) - ], - ); + let doc = parse_witx_with( + &Path::new("/a"), + &MockFs::new(&[ + ("/a", "(use \"b\")"), + ("/b", "(use \"c\")\n(typename $b_float f64)"), + ("/c", "(typename $c_int u32)"), + ]), + ) + .expect("parse"); + + match &doc.datatype(&Id::new("b_float")).unwrap().variant { + DatatypeVariant::Alias(a) => { + assert_eq!(a.name.as_str(), "b_float"); + assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::F64)); + } + other => panic!("expected alias, got {:?}", other), + } + + match &doc.datatype(&Id::new("c_int")).unwrap().variant { + DatatypeVariant::Alias(a) => { + assert_eq!(a.name.as_str(), "c_int"); + assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::U32)); + } + other => panic!("expected alias, got {:?}", other), + } } #[test] fn diamond_dependency() { - assert_eq!( - parse_witx_with( - &Path::new("/a"), - &MockFs::new(&[ - ("/a", "(use \"b\")\n(use \"c\")"), - ("/b", "(use \"d\")"), - ("/c", "(use \"d\")"), - ("/d", "(typename $d_char u8)") - ]) - ) - .expect("parse"), - vec![DeclSyntax::Typename(TypenameSyntax { - ident: IdentSyntax { - name: "d_char".to_owned(), - location: Location { - path: PathBuf::from("/d"), - line: 1, - column: 10, - } - }, - def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::U8)) - })], - ); + let doc = parse_witx_with( + &Path::new("/a"), + &MockFs::new(&[ + ("/a", "(use \"b\")\n(use \"c\")"), + ("/b", "(use \"d\")"), + ("/c", "(use \"d\")"), + ("/d", "(typename $d_char u8)"), + ]), + ) + .expect("parse"); + + match &doc.datatype(&Id::new("d_char")).unwrap().variant { + DatatypeVariant::Alias(a) => { + assert_eq!(a.name.as_str(), "d_char"); + assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::U8)); + } + other => panic!("expected alias, got {:?}", other), + } } #[test] @@ -177,15 +159,9 @@ mod test { .unwrap() { WitxError::Parse(e) => { - assert_eq!(e.message, "invalid use declaration"); - assert_eq!( - e.location, - Location { - path: PathBuf::from("/a"), - line: 1, - column: 1 - } - ); + let err = e.to_string(); + assert!(err.contains("expected a string"), "bad error: {}", err); + assert!(err.contains("/a:1:6")); } e => panic!("wrong error: {:?}", e), } diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 526409e62..df11c521c 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -1,17 +1,17 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ - DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, IdentSyntax, ImportTypeSyntax, + DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, - Definition, Document, Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, - InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, - ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, - UnionVariant, + Definition, Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, + InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, + ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; use failure::Fail; use std::collections::HashMap; +use std::path::Path; use std::rc::Rc; #[derive(Debug, Fail)] @@ -73,16 +73,6 @@ impl ValidationError { } } -pub fn validate_document(decls: &[DeclSyntax]) -> Result { - let mut validator = DocValidation::new(); - let mut definitions = Vec::new(); - for d in decls { - definitions.push(validator.validate_decl(&d)?); - } - - Ok(Document::new(definitions, validator.entries)) -} - struct IdentValidation { names: HashMap, } @@ -93,49 +83,84 @@ impl IdentValidation { names: HashMap::new(), } } - fn introduce(&mut self, syntax: &IdentSyntax) -> Result { - if let Some(introduced) = self.names.get(&syntax.name) { + + fn introduce(&mut self, syntax: &str, location: Location) -> Result { + if let Some(introduced) = self.names.get(syntax) { Err(ValidationError::NameAlreadyExists { - name: syntax.name.clone(), - at_location: syntax.location.clone(), + name: syntax.to_string(), + at_location: location, previous_location: introduced.clone(), }) } else { - self.names - .insert(syntax.name.clone(), syntax.location.clone()); - Ok(Id::new(&syntax.name)) + self.names.insert(syntax.to_string(), location); + Ok(Id::new(syntax)) } } - fn get(&self, syntax: &IdentSyntax) -> Result { - if self.names.get(&syntax.name).is_some() { - Ok(Id::new(&syntax.name)) + fn get(&self, syntax: &str, location: Location) -> Result { + if self.names.get(syntax).is_some() { + Ok(Id::new(syntax)) } else { Err(ValidationError::UnknownName { - name: syntax.name.clone(), - location: syntax.location.clone(), + name: syntax.to_string(), + location, }) } } } -struct DocValidation { +pub struct DocValidation { scope: IdentValidation, pub entries: HashMap, } +pub struct DocValidationScope<'a> { + doc: &'a mut DocValidation, + text: &'a str, + path: &'a Path, +} + impl DocValidation { - fn new() -> Self { + pub fn new() -> Self { Self { scope: IdentValidation::new(), entries: HashMap::new(), } } - fn validate_decl(&mut self, decl: &DeclSyntax) -> Result { + pub fn scope<'a>(&'a mut self, text: &'a str, path: &'a Path) -> DocValidationScope<'a> { + DocValidationScope { + doc: self, + text, + path, + } + } +} + +impl DocValidationScope<'_> { + fn location(&self, span: wast::Span) -> Location { + let (line, column) = span.linecol_in(self.text); + Location { + line, + column, + path: self.path.to_path_buf(), + } + } + + fn introduce(&mut self, name: &wast::Id<'_>) -> Result { + let loc = self.location(name.span()); + self.doc.scope.introduce(name.name(), loc) + } + + fn get(&self, name: &wast::Id<'_>) -> Result { + let loc = self.location(name.span()); + self.doc.scope.get(name.name(), loc) + } + + pub fn validate_decl(&mut self, decl: &DeclSyntax) -> Result { match decl { DeclSyntax::Typename(decl) => { - let name = self.scope.introduce(&decl.ident)?; + let name = self.introduce(&decl.ident)?; let variant = match &decl.def { TypedefSyntax::Ident(syntax) => DatatypeVariant::Alias(AliasDatatype { @@ -145,28 +170,29 @@ impl DocValidation { TypedefSyntax::Enum(syntax) => DatatypeVariant::Enum(self.validate_enum( &name, &syntax, - &decl.ident.location, + decl.ident.span(), )?), TypedefSyntax::Flags(syntax) => DatatypeVariant::Flags( - self.validate_flags(&name, &syntax, &decl.ident.location)?, + self.validate_flags(&name, &syntax, decl.ident.span())?, ), TypedefSyntax::Struct(syntax) => DatatypeVariant::Struct( - self.validate_struct(&name, &syntax, &decl.ident.location)?, + self.validate_struct(&name, &syntax, decl.ident.span())?, ), TypedefSyntax::Union(syntax) => DatatypeVariant::Union( - self.validate_union(&name, &syntax, &decl.ident.location)?, + self.validate_union(&name, &syntax, decl.ident.span())?, ), }; let rc_datatype = Rc::new(Datatype { name: name.clone(), variant, }); - self.entries + self.doc + .entries .insert(name, Entry::Datatype(Rc::downgrade(&rc_datatype))); Ok(Definition::Datatype(rc_datatype)) } DeclSyntax::Module(syntax) => { - let name = self.scope.introduce(&syntax.name)?; + let name = self.introduce(&syntax.name)?; let mut module_validator = ModuleValidation::new(self); let definitions = syntax .decls @@ -179,7 +205,8 @@ impl DocValidation { definitions, module_validator.entries, )); - self.entries + self.doc + .entries .insert(name, Entry::Module(Rc::downgrade(&rc_module))); Ok(Definition::Module(rc_module)) } @@ -202,20 +229,20 @@ impl DocValidation { self.validate_datatype_ident(&a)?, ))), DatatypeIdentSyntax::Ident(i) => { - let id = self.scope.get(i)?; - match self.entries.get(&id) { + let id = self.get(i)?; + match self.doc.entries.get(&id) { Some(Entry::Datatype(weak_d)) => Ok(DatatypeIdent::Ident( weak_d.upgrade().expect("weak backref to defined type"), )), Some(e) => Err(ValidationError::WrongKindName { - name: i.name.clone(), - location: i.location.clone(), + name: i.name().to_string(), + location: self.location(i.span()), expected: "datatype", got: e.kind(), }), None => Err(ValidationError::Recursive { - name: i.name.clone(), - location: i.location.clone(), + name: i.name().to_string(), + location: self.location(i.span()), }), } } @@ -226,14 +253,14 @@ impl DocValidation { &self, name: &Id, syntax: &EnumSyntax, - location: &Location, + span: wast::Span, ) -> Result { let mut enum_scope = IdentValidation::new(); - let repr = validate_int_repr(&syntax.repr, location)?; + let repr = self.validate_int_repr(&syntax.repr, span)?; let variants = syntax .members .iter() - .map(|i| enum_scope.introduce(i)) + .map(|i| enum_scope.introduce(i.name(), self.location(i.span()))) .collect::, _>>()?; Ok(EnumDatatype { @@ -247,14 +274,14 @@ impl DocValidation { &self, name: &Id, syntax: &FlagsSyntax, - location: &Location, + span: wast::Span, ) -> Result { let mut flags_scope = IdentValidation::new(); - let repr = validate_int_repr(&syntax.repr, location)?; + let repr = self.validate_int_repr(&syntax.repr, span)?; let flags = syntax .flags .iter() - .map(|i| flags_scope.introduce(i)) + .map(|i| flags_scope.introduce(i.name(), self.location(i.span()))) .collect::, _>>()?; Ok(FlagsDatatype { @@ -268,7 +295,7 @@ impl DocValidation { &self, name: &Id, syntax: &StructSyntax, - _location: &Location, + _span: wast::Span, ) -> Result { let mut member_scope = IdentValidation::new(); let members = syntax @@ -276,7 +303,7 @@ impl DocValidation { .iter() .map(|f| { Ok(StructMember { - name: member_scope.introduce(&f.name)?, + name: member_scope.introduce(f.name.name(), self.location(f.name.span()))?, type_: self.validate_datatype_ident(&f.type_)?, }) }) @@ -292,7 +319,7 @@ impl DocValidation { &self, name: &Id, syntax: &UnionSyntax, - _location: &Location, + _span: wast::Span, ) -> Result { let mut variant_scope = IdentValidation::new(); let variants = syntax @@ -300,7 +327,7 @@ impl DocValidation { .iter() .map(|f| { Ok(UnionVariant { - name: variant_scope.introduce(&f.name)?, + name: variant_scope.introduce(f.name.name(), self.location(f.name.span()))?, type_: self.validate_datatype_ident(&f.type_)?, }) }) @@ -311,29 +338,33 @@ impl DocValidation { variants, }) } -} -fn validate_int_repr(type_: &BuiltinType, location: &Location) -> Result { - match type_ { - BuiltinType::U8 => Ok(IntRepr::U8), - BuiltinType::U16 => Ok(IntRepr::U16), - BuiltinType::U32 => Ok(IntRepr::U32), - BuiltinType::U64 => Ok(IntRepr::U64), - _ => Err(ValidationError::InvalidRepr { - repr: type_.clone(), - location: location.clone(), - }), + fn validate_int_repr( + &self, + type_: &BuiltinType, + span: wast::Span, + ) -> Result { + match type_ { + BuiltinType::U8 => Ok(IntRepr::U8), + BuiltinType::U16 => Ok(IntRepr::U16), + BuiltinType::U32 => Ok(IntRepr::U32), + BuiltinType::U64 => Ok(IntRepr::U64), + _ => Err(ValidationError::InvalidRepr { + repr: type_.clone(), + location: self.location(span), + }), + } } } struct ModuleValidation<'a> { - doc: &'a DocValidation, + doc: &'a DocValidationScope<'a>, scope: IdentValidation, pub entries: HashMap, } impl<'a> ModuleValidation<'a> { - fn new(doc: &'a DocValidation) -> Self { + fn new(doc: &'a DocValidationScope<'a>) -> Self { Self { doc, scope: IdentValidation::new(), @@ -347,7 +378,8 @@ impl<'a> ModuleValidation<'a> { ) -> Result { match decl { ModuleDeclSyntax::Import(syntax) => { - let name = self.scope.introduce(&syntax.name)?; + let loc = self.doc.location(syntax.name_loc); + let name = self.scope.introduce(syntax.name, loc)?; let variant = match syntax.type_ { ImportTypeSyntax::Memory => ModuleImportVariant::Memory, }; @@ -360,7 +392,8 @@ impl<'a> ModuleValidation<'a> { Ok(ModuleDefinition::Import(rc_import)) } ModuleDeclSyntax::Func(syntax) => { - let name = self.scope.introduce(&syntax.export)?; + let loc = self.doc.location(syntax.export_loc); + let name = self.scope.introduce(syntax.export, loc)?; let mut argnames = IdentValidation::new(); let params = syntax .params @@ -368,7 +401,8 @@ impl<'a> ModuleValidation<'a> { .enumerate() .map(|(ix, f)| { Ok(InterfaceFuncParam { - name: argnames.introduce(&f.name)?, + name: argnames + .introduce(f.name.name(), self.doc.location(f.name.span()))?, type_: self.doc.validate_datatype_ident(&f.type_)?, position: InterfaceFuncParamPosition::Param(ix), }) @@ -384,12 +418,13 @@ impl<'a> ModuleValidation<'a> { match type_.passed_by() { DatatypePassedBy::Value(_) => {} _ => Err(ValidationError::InvalidFirstResultType { - location: f.name.location.clone(), + location: self.doc.location(f.name.span()), })?, } } Ok(InterfaceFuncParam { - name: argnames.introduce(&f.name)?, + name: argnames + .introduce(f.name.name(), self.doc.location(f.name.span()))?, type_, position: InterfaceFuncParamPosition::Result(ix), }) diff --git a/proposals/random/tools/witx/tests/wasi_unstable.rs b/proposals/random/tools/witx/tests/wasi_unstable.rs index 482224344..68e65186a 100644 --- a/proposals/random/tools/witx/tests/wasi_unstable.rs +++ b/proposals/random/tools/witx/tests/wasi_unstable.rs @@ -6,7 +6,7 @@ fn validate_wasi_unstable_preview0() { witx::load(Path::new( "../../phases/unstable/witx/wasi_unstable_preview0.witx", )) - .unwrap(); + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] @@ -14,12 +14,13 @@ fn validate_wasi_ephemeral_preview() { witx::load(Path::new( "../../phases/ephemeral/witx/wasi_ephemeral_preview.witx", )) - .unwrap(); + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_old_preview0() { - witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")).unwrap(); + witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] @@ -27,7 +28,7 @@ fn render_roundtrip() { let doc = witx::load(Path::new( "../../phases/unstable/witx/wasi_unstable_preview0.witx", )) - .unwrap(); + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); let back_to_sexprs = format!("{}", doc); println!("{}", back_to_sexprs); From 68f9b5ca7c66dd7f5d280cc8ce0f73749ae1ac26 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 22 Oct 2019 11:54:40 -0500 Subject: [PATCH 0222/1772] Switch to the Rust `wast` crate for parsing `*.witx` (#124) This commit switches to the recently-published `wast` crate to parse `*.witx` file. The `wast` crate is intended to be a way to easily write recursive descent and composable parsers. It includes built-in parsers for all of `*.wat` and `*.wast` syntax, but only a few limited ones were used for `*.witx`, otherwise it's just the idioms that were used for the `Parse` trait and such! The hope here is that this can consolidate lexing/handling of s-expressions and simplify the parsing strategy as well. Eventually it's intended that `wast` is flexible enough to have built-in parsers for interface types as well! The crate was refactored slightly in implementing this change, prominently: * The `validate` pass is not baked into the `src/toplevel.rs` parsing. * The `src/toplevel.rs` parsing was simplified slightly to have only one recursive function for parsing includes. * All `*Syntax` data types now have a `'a` lifetime parameter and are consumed immediately on the stack frame while parsing. * `Location` is no longer manufactured while parsing, but rather it's created on-demand while the ast is being constructed. This required a small refactoring to have a `DocValidationScope` which carries metadata about the current file that was parsed to manufacture `Location`. --- proposals/filesystem/tools/witx/Cargo.toml | 1 + proposals/filesystem/tools/witx/src/io.rs | 12 + proposals/filesystem/tools/witx/src/lexer.rs | 354 -------- proposals/filesystem/tools/witx/src/lib.rs | 25 +- proposals/filesystem/tools/witx/src/parser.rs | 830 ++++++++---------- proposals/filesystem/tools/witx/src/sexpr.rs | 240 ----- .../filesystem/tools/witx/src/toplevel.rs | 234 +++-- .../filesystem/tools/witx/src/validate.rs | 179 ++-- .../tools/witx/tests/wasi_unstable.rs | 9 +- 9 files changed, 608 insertions(+), 1276 deletions(-) delete mode 100644 proposals/filesystem/tools/witx/src/lexer.rs delete mode 100644 proposals/filesystem/tools/witx/src/sexpr.rs diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 2fe71c419..9a38ed265 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -18,4 +18,5 @@ path = "src/main.rs" [dependencies] clap = "2" +wast = "3.0.1" failure = "0.1" diff --git a/proposals/filesystem/tools/witx/src/io.rs b/proposals/filesystem/tools/witx/src/io.rs index 4f40d8947..f46ab1766 100644 --- a/proposals/filesystem/tools/witx/src/io.rs +++ b/proposals/filesystem/tools/witx/src/io.rs @@ -13,6 +13,18 @@ pub trait WitxIo { fn canonicalize(&self, path: &Path) -> Result; } +impl WitxIo for &'_ T { + fn fgets(&self, path: &Path) -> Result { + T::fgets(self, path) + } + fn fget_line(&self, path: &Path, line_num: usize) -> Result { + T::fget_line(self, path, line_num) + } + fn canonicalize(&self, path: &Path) -> Result { + T::canonicalize(self, path) + } +} + pub struct Filesystem; impl WitxIo for Filesystem { diff --git a/proposals/filesystem/tools/witx/src/lexer.rs b/proposals/filesystem/tools/witx/src/lexer.rs deleted file mode 100644 index b004acf07..000000000 --- a/proposals/filesystem/tools/witx/src/lexer.rs +++ /dev/null @@ -1,354 +0,0 @@ -use crate::Location; -use failure::Fail; -use std::path::{Path, PathBuf}; -use std::str::CharIndices; - -///! The lexer turns a string into a stream of located tokens. -///! The tokens are meant for consumption by the s-expression parser. -///! -///! Comments in source text look like `;; rest of line ...`. -///! Words look like `abcde_` -///! Idents look like `$abcde_` -///! Annotations look like `@abcde_` -///! Quotes look like `"a b cde 123 @#$%^&*() _"` -///! -///! This implementation was heavily influenced by `cranelift-reader` - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum Token<'a> { - LPar, // ( - RPar, // ) - Word(&'a str), // Bare word - Ident(&'a str), // Starts with $ - Annot(&'a str), // Starts with @. short for annotation. - Quote(&'a str), // Found between balanced "". No escaping. -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct LocatedToken<'a> { - pub token: Token<'a>, - pub location: Location, -} - -fn token(token: Token<'_>, location: Location) -> Result, LocatedError> { - Ok(LocatedToken { token, location }) -} - -#[derive(Debug, PartialEq, Eq, Clone, Copy, Fail)] -pub enum LexError { - #[fail(display = "Invalid character '{}'", _0)] - InvalidChar(char), - #[fail(display = "Empty identifier '$'")] - EmptyIdentifier, - #[fail(display = "Empty annotation '@'")] - EmptyAnnotation, - #[fail(display = "Unterminated quote")] - UnterminatedQuote, -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct LocatedError { - pub error: LexError, - pub location: Location, -} - -fn error<'a>(error: LexError, location: Location) -> Result, LocatedError> { - Err(LocatedError { error, location }) -} - -pub struct Lexer<'a> { - source: &'a str, - chars: CharIndices<'a>, - lookahead: Option, - pos: usize, - line_number: usize, - column_start: usize, - tab_compensation: usize, - path: PathBuf, -} - -impl<'a> Lexer<'a> { - pub fn new>(s: &'a str, path: P) -> Lexer<'_> { - let mut lex = Lexer { - source: s, - chars: s.char_indices(), - lookahead: None, - pos: 0, - line_number: 1, - column_start: 0, - tab_compensation: 0, - path: path.as_ref().into(), - }; - lex.next_ch(); - lex - } - - fn next_ch(&mut self) -> Option { - if self.lookahead == Some('\n') { - self.line_number += 1; - self.column_start = self.pos + 1; // Next column starts a fresh line - self.tab_compensation = 0; - } else if self.lookahead == Some('\t') { - self.tab_compensation += 7; // One column for the position of the char itself, add 7 more for a tabwidth of 8 - } - match self.chars.next() { - Some((idx, ch)) => { - self.pos = idx; - self.lookahead = Some(ch); - } - None => { - self.pos = self.source.len(); - self.lookahead = None; - } - } - self.lookahead - } - - fn loc(&self) -> Location { - Location { - path: self.path.clone(), - line: self.line_number, - column: self.pos - self.column_start + self.tab_compensation, - } - } - - fn looking_at(&self, prefix: &str) -> bool { - self.source[self.pos..].starts_with(prefix) - } - - fn scan_char(&mut self, tok: Token<'a>) -> Result, LocatedError> { - assert!(self.lookahead.is_some()); - let loc = self.loc(); - self.next_ch(); - token(tok, loc) - } - - pub fn rest_of_line(&mut self) -> &'a str { - let begin = self.pos; - loop { - match self.next_ch() { - None | Some('\n') => return &self.source[begin..self.pos], - _ => {} - } - } - } - - fn scan_word(&mut self) -> Result, LocatedError> { - let begin = self.pos; - let loc = self.loc(); - assert!(self.lookahead == Some('_') || self.lookahead.unwrap().is_alphabetic()); - loop { - match self.next_ch() { - Some('_') | Some('-') => {} - Some(ch) if ch.is_alphanumeric() => {} - _ => break, - } - } - let text = &self.source[begin..self.pos]; - token(Token::Word(text), loc) - } - - fn scan_ident(&mut self) -> Result, LocatedError> { - let loc = self.loc(); - assert!(self.lookahead == Some('$')); - match self.next_ch() { - Some(ch) if ch.is_alphanumeric() || ch == '_' => {} - _ => Err(LocatedError { - error: LexError::EmptyIdentifier, - location: loc.clone(), - })?, - } - let begin = self.pos; - - loop { - match self.next_ch() { - Some('_') | Some('-') => {} - Some(ch) if ch.is_alphanumeric() => {} - _ => break, - } - } - - let text = &self.source[begin..self.pos]; - token(Token::Ident(text), loc) - } - - fn scan_annotation(&mut self) -> Result, LocatedError> { - let loc = self.loc(); - assert!(self.lookahead == Some('@')); - match self.next_ch() { - Some(ch) if ch.is_alphanumeric() || ch == '_' => {} - _ => Err(LocatedError { - error: LexError::EmptyAnnotation, - location: loc.clone(), - })?, - } - let begin = self.pos; - - loop { - match self.next_ch() { - Some('_') | Some('-') => {} - Some(ch) if ch.is_alphanumeric() => {} - _ => break, - } - } - - let text = &self.source[begin..self.pos]; - token(Token::Annot(text), loc) - } - - fn scan_quote(&mut self) -> Result, LocatedError> { - let begin = self.pos; - let loc = self.loc(); - assert!(self.lookahead == Some('"')); - loop { - match self.next_ch() { - None => Err(LocatedError { - error: LexError::UnterminatedQuote, - location: loc.clone(), - })?, - Some('"') => { - self.next_ch(); - break; - } - _ => {} - } - } - let text = &self.source[(begin + 1)..(self.pos - 1)]; - token(Token::Quote(text), loc) - } - - #[allow(clippy::should_implement_trait)] - pub fn next(&mut self) -> Option, LocatedError>> { - loop { - let loc = self.loc(); - return match self.lookahead { - None => None, - Some(c) => Some(match c { - '(' => self.scan_char(Token::LPar), - ')' => self.scan_char(Token::RPar), - '$' => self.scan_ident(), - '@' => self.scan_annotation(), - ';' => { - if self.looking_at(";;") { - self.rest_of_line(); - continue; - } else { - self.next_ch(); - error(LexError::InvalidChar(';'), loc) - } - } - '"' => self.scan_quote(), - '_' => self.scan_word(), - ch if ch.is_alphabetic() => self.scan_word(), - ch if ch.is_whitespace() => { - self.next_ch(); - continue; - } - _ => { - self.next_ch(); - error(LexError::InvalidChar(c), loc) - } - }), - }; - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use std::path::{Path, PathBuf}; - - fn testlexer(input: &str) -> Lexer { - Lexer::new(input, Path::new("/test")) - } - - fn token( - token: Token<'_>, - line: usize, - column: usize, - ) -> Option, LocatedError>> { - Some(super::token( - token, - Location { - path: PathBuf::from("/test"), - line, - column, - }, - )) - } - - fn error<'a>( - err: LexError, - line: usize, - column: usize, - ) -> Option, LocatedError>> { - Some(super::error( - err, - Location { - path: PathBuf::from("/test"), - line, - column, - }, - )) - } - #[test] - fn words_and_idents() { - let mut lex = testlexer("$gussie is a good $dog"); - // ruler 0 5 10 15 20 - assert_eq!(lex.next(), token(Token::Ident("gussie"), 1, 0)); - assert_eq!(lex.next(), token(Token::Word("is"), 1, 8)); - assert_eq!(lex.next(), token(Token::Word("a"), 1, 11)); - assert_eq!(lex.next(), token(Token::Word("good"), 1, 13)); - assert_eq!(lex.next(), token(Token::Ident("dog"), 1, 18)); - assert_eq!(lex.next(), None); - - let mut lex = - testlexer("$ok $a $_ $ _\nkebab-case\nsnake_case\n$kebab-ident\n$snake_ident"); - assert_eq!(lex.next(), token(Token::Ident("ok"), 1, 0)); - assert_eq!(lex.next(), token(Token::Ident("a"), 1, 4)); - assert_eq!(lex.next(), token(Token::Ident("_"), 1, 7)); - assert_eq!(lex.next(), error(LexError::EmptyIdentifier, 1, 10)); - assert_eq!(lex.next(), token(Token::Word("_"), 1, 12)); - assert_eq!(lex.next(), token(Token::Word("kebab-case"), 2, 0)); - assert_eq!(lex.next(), token(Token::Word("snake_case"), 3, 0)); - assert_eq!(lex.next(), token(Token::Ident("kebab-ident"), 4, 0)); - assert_eq!(lex.next(), token(Token::Ident("snake_ident"), 5, 0)); - assert_eq!(lex.next(), None); - } - - #[test] - fn comments() { - let mut lex = testlexer("the quick ;; brown fox\njumped\n;;over the three\nlazy;;dogs"); - assert_eq!(lex.next(), token(Token::Word("the"), 1, 0)); - assert_eq!(lex.next(), token(Token::Word("quick"), 1, 4)); - assert_eq!(lex.next(), token(Token::Word("jumped"), 2, 0)); - assert_eq!(lex.next(), token(Token::Word("lazy"), 4, 0)); - assert_eq!(lex.next(), None); - - let mut lex = testlexer("line1 ;;\n$sym_2;\n\t\tl3;;;333"); - assert_eq!(lex.next(), token(Token::Word("line1"), 1, 0)); - assert_eq!(lex.next(), token(Token::Ident("sym_2"), 2, 0)); - assert_eq!(lex.next(), error(LexError::InvalidChar(';'), 2, 6)); - assert_eq!(lex.next(), token(Token::Word("l3"), 3, 16)); // Two tabs = 16 columns - assert_eq!(lex.next(), None); - } - - #[test] - fn quotes() { - let mut lex = testlexer("a \"bc\" d"); - assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); - assert_eq!(lex.next(), token(Token::Quote("bc"), 1, 2)); - assert_eq!(lex.next(), token(Token::Word("d"), 1, 7)); - - let mut lex = testlexer("a \"b\nc\" d"); - assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); - assert_eq!(lex.next(), token(Token::Quote("b\nc"), 1, 2)); - assert_eq!(lex.next(), token(Token::Word("d"), 2, 3)); - - let mut lex = testlexer("a \"b"); - assert_eq!(lex.next(), token(Token::Word("a"), 1, 0)); - assert_eq!(lex.next(), error(LexError::UnterminatedQuote, 1, 2)); - } -} diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index af315a9df..60ccf2c9b 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -4,14 +4,10 @@ mod ast; mod coretypes; /// Interface for filesystem or mock IO mod io; -/// Lexer text into tokens -mod lexer; /// Witx syntax parsing from SExprs mod parser; /// Render ast to text mod render; -/// SExpr parsing from tokens -mod sexpr; /// Resolve toplevel `use` declarations across files mod toplevel; /// Validate declarations into ast @@ -25,10 +21,8 @@ pub use ast::{ }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; pub use io::{Filesystem, MockFs, WitxIo}; -pub use lexer::LexError; -pub use parser::{DeclSyntax, ParseError}; +pub use parser::DeclSyntax; pub use render::{Render, SExpr as RenderSExpr}; -pub use sexpr::SExprParseError; pub use validate::ValidationError; use failure::Fail; @@ -36,19 +30,13 @@ use std::path::{Path, PathBuf}; /// Load a witx document from the filesystem pub fn load>(path: P) -> Result { - use toplevel::parse_witx; - use validate::validate_document; - let parsed_decls = parse_witx(path)?; - validate_document(&parsed_decls).map_err(WitxError::Validation) + toplevel::parse_witx(path.as_ref()) } /// Parse a witx document from a str. `(use ...)` directives are not permitted. pub fn parse(source: &str) -> Result { - use toplevel::parse_witx_with; - use validate::validate_document; let mockfs = MockFs::new(&[("-", source)]); - let parsed_decls = parse_witx_with(Path::new("-"), &mockfs)?; - validate_document(&parsed_decls).map_err(WitxError::Validation) + toplevel::parse_witx_with(Path::new("-"), &mockfs) } /// Location in the source text @@ -61,12 +49,10 @@ pub struct Location { #[derive(Debug, Fail)] pub enum WitxError { - #[fail(display = "{}", _0)] - SExpr(#[cause] SExprParseError), #[fail(display = "with file {:?}: {}", _0, _1)] Io(PathBuf, #[cause] ::std::io::Error), #[fail(display = "{}", _0)] - Parse(#[cause] ParseError), + Parse(#[cause] wast::Error), #[fail(display = "{}", _0)] Validation(#[cause] ValidationError), } @@ -75,9 +61,8 @@ impl WitxError { pub fn report_with(&self, witxio: &dyn WitxIo) -> String { use WitxError::*; match self { - SExpr(sexpr) => sexpr.report_with(witxio), Io(path, ioerr) => format!("with file {:?}: {}", path, ioerr), - Parse(parse) => parse.report_with(witxio), + Parse(parse) => parse.to_string(), Validation(validation) => validation.report_with(witxio), } } diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index d12d643ed..8c7a1eecf 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -1,7 +1,4 @@ -use crate::io::{Filesystem, WitxIo}; -use crate::sexpr::SExpr; -use crate::Location; -use failure::Fail; +use wast::parser::{Cursor, Parse, Parser, Peek, Result}; ///! Parser turns s-expressions into unvalidated syntax constructs. ///! conventions: @@ -16,48 +13,31 @@ use failure::Fail; ///! This is used for error reporting in case the slice doesn't have the number of elements ///! expected. -#[derive(Debug, Fail)] -#[fail(display = "{} at {:?}", _0, _1)] -pub struct ParseError { - pub message: String, - pub location: Location, -} - -impl ParseError { - pub fn report_with(&self, witxio: &dyn WitxIo) -> String { - format!( - "{}\n{}", - self.location.highlight_source_with(witxio), - self.message - ) - } - pub fn report(&self) -> String { - self.report_with(&Filesystem) - } -} - -macro_rules! parse_err { - ($loc:expr, $msg:expr) => { - ParseError { message: $msg.to_string(), location: $loc.clone() } - }; - ($loc:expr, $fmt:expr, $( $arg:expr ),+ ) => { - ParseError { message: format!($fmt, $( $arg ),+), location: $loc.clone() } - }; -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct IdentSyntax { - pub name: String, - pub location: Location, -} - -macro_rules! id { - ($s:expr, $loc: expr) => { - IdentSyntax { - name: $s.to_string(), - location: $loc.clone(), - } - }; +mod kw { + pub use wast::kw::{export, func, import, memory, module, param, result}; + + wast::custom_keyword!(array); + wast::custom_keyword!(const_pointer); + wast::custom_keyword!(f32); + wast::custom_keyword!(f64); + wast::custom_keyword!(field); + wast::custom_keyword!(flag); + wast::custom_keyword!(flags); + wast::custom_keyword!(pointer); + wast::custom_keyword!(r#enum = "enum"); + wast::custom_keyword!(r#struct = "struct"); + wast::custom_keyword!(r#union = "union"); + wast::custom_keyword!(r#use = "use"); + wast::custom_keyword!(s16); + wast::custom_keyword!(s32); + wast::custom_keyword!(s64); + wast::custom_keyword!(s8); + wast::custom_keyword!(string); + wast::custom_keyword!(typename); + wast::custom_keyword!(u16); + wast::custom_keyword!(u32); + wast::custom_keyword!(u64); + wast::custom_keyword!(u8); } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -75,514 +55,450 @@ pub enum BuiltinType { F64, } -impl BuiltinType { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - match sexpr { - SExpr::Word("string", _) - | SExpr::Word("u8", _) - | SExpr::Word("u16", _) - | SExpr::Word("u32", _) - | SExpr::Word("u64", _) - | SExpr::Word("s8", _) - | SExpr::Word("s16", _) - | SExpr::Word("s32", _) - | SExpr::Word("s64", _) - | SExpr::Word("f32", _) - | SExpr::Word("f64", _) => true, - _ => false, - } - } - pub fn parse(sexpr: &SExpr) -> Result { - match sexpr { - SExpr::Word("string", _loc) => Ok(BuiltinType::String), - SExpr::Word("u8", _loc) => Ok(BuiltinType::U8), - SExpr::Word("u16", _loc) => Ok(BuiltinType::U16), - SExpr::Word("u32", _loc) => Ok(BuiltinType::U32), - SExpr::Word("u64", _loc) => Ok(BuiltinType::U64), - SExpr::Word("s8", _loc) => Ok(BuiltinType::S8), - SExpr::Word("s16", _loc) => Ok(BuiltinType::S16), - SExpr::Word("s32", _loc) => Ok(BuiltinType::S32), - SExpr::Word("s64", _loc) => Ok(BuiltinType::S64), - SExpr::Word("f32", _loc) => Ok(BuiltinType::F32), - SExpr::Word("f64", _loc) => Ok(BuiltinType::F64), - _ => Err(parse_err!(sexpr.location(), "invalid builtin type")), +impl Parse<'_> for BuiltinType { + fn parse(parser: Parser<'_>) -> Result { + let mut l = parser.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::String) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::U8) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::U16) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::U32) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::U64) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::S8) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::S16) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::S32) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::S64) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::F32) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::F64) + } else { + Err(l.error()) } } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum DatatypeIdentSyntax { +pub enum DatatypeIdentSyntax<'a> { Builtin(BuiltinType), - Array(Box), - Pointer(Box), - ConstPointer(Box), - Ident(IdentSyntax), -} - -impl DatatypeIdentSyntax { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - BuiltinType::starts_parsing(sexpr) - || match sexpr { - SExpr::Ident(_, _) => true, - SExpr::Vec(v, _) => match (v.get(0), v.get(1)) { - (Some(SExpr::Word("array", _)), Some(_)) => true, - (Some(SExpr::Annot("witx", _)), Some(SExpr::Word("pointer", _))) => true, - (Some(SExpr::Annot("witx", _)), Some(SExpr::Word("const_pointer", _))) => true, - _ => false, - }, - _ => false, + Array(Box>), + Pointer(Box>), + ConstPointer(Box>), + Ident(wast::Id<'a>), +} + +impl<'a> Parse<'a> for DatatypeIdentSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + if parser.peek::() { + Ok(DatatypeIdentSyntax::Ident(parser.parse()?)) + } else if parser.peek2::() { + Ok(DatatypeIdentSyntax::Array(parser.parens(|p| { + p.parse::()?; + Ok(Box::new(parser.parse()?)) + })?)) + } else if parser.peek::() { + parser.parens(|p| { + p.parse::()?; + if p.peek::() { + p.parse::()?; + Ok(DatatypeIdentSyntax::ConstPointer(Box::new(p.parse()?))) + } else { + p.parse::()?; + Ok(DatatypeIdentSyntax::Pointer(Box::new(p.parse()?))) + } + }) + } else { + Ok(DatatypeIdentSyntax::Builtin(parser.parse()?)) + } + } +} + +struct AtWitx; + +impl Parse<'_> for AtWitx { + fn parse(parser: Parser<'_>) -> Result { + parser.step(|c| { + if let Some(("@witx", rest)) = c.reserved() { + return Ok((AtWitx, rest)); } + Err(c.error("expected `@witx`")) + }) } - pub fn parse(sexpr: &SExpr) -> Result { - if BuiltinType::starts_parsing(sexpr) { - let builtin = BuiltinType::parse(sexpr)?; - Ok(DatatypeIdentSyntax::Builtin(builtin)) - } else { - match sexpr { - SExpr::Ident(i, loc) => Ok(DatatypeIdentSyntax::Ident(id!(i, loc))), - SExpr::Vec(v, loc) => match (v.get(0), v.get(1), v.get(2)) { - (Some(SExpr::Word("array", _)), Some(expr), None) => Ok( - DatatypeIdentSyntax::Array(Box::new(DatatypeIdentSyntax::parse(expr)?)), - ), - ( - Some(SExpr::Annot("witx", _)), - Some(SExpr::Word("pointer", _)), - Some(expr), - ) => Ok(DatatypeIdentSyntax::Pointer(Box::new( - DatatypeIdentSyntax::parse(expr)?, - ))), - ( - Some(SExpr::Annot("witx", _)), - Some(SExpr::Word("const_pointer", _)), - Some(expr), - ) => Ok(DatatypeIdentSyntax::ConstPointer(Box::new( - DatatypeIdentSyntax::parse(expr)?, - ))), - _ => Err(parse_err!(loc, "expected type identifier")), - }, - _ => Err(parse_err!(sexpr.location(), "expected type identifier")), +} + +impl Peek for AtWitx { + fn peek(cursor: Cursor<'_>) -> bool { + cursor.reserved().map(|s| s.0) == Some("@witx") + } + + fn display() -> &'static str { + "`@witx`" + } +} + +struct AtInterface; + +impl Parse<'_> for AtInterface { + fn parse(parser: Parser<'_>) -> Result { + parser.step(|c| { + if let Some(("@interface", rest)) = c.reserved() { + return Ok((AtInterface, rest)); } - } + Err(c.error("expected `@interface`")) + }) + } +} + +impl Peek for AtInterface { + fn peek(cursor: Cursor<'_>) -> bool { + cursor.reserved().map(|s| s.0) == Some("@interface") + } + + fn display() -> &'static str { + "`@interface`" } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum TopLevelSyntax { - Decl(DeclSyntax), - Use(IdentSyntax), +pub struct TopLevelDocument<'a> { + pub items: Vec>, } -impl TopLevelSyntax { - pub fn parse(sexpr: &SExpr) -> Result { - if DeclSyntax::starts_parsing(sexpr) { - let decl = DeclSyntax::parse(sexpr)?; - Ok(TopLevelSyntax::Decl(decl)) - } else { - match sexpr { - SExpr::Vec(v, vec_loc) => match v.get(0) { - Some(SExpr::Word("use", loc)) => match v.get(1) { - Some(SExpr::Quote(u, loc)) => Ok(TopLevelSyntax::Use(id!(u, loc))), - _ => Err(parse_err!(loc, "invalid use declaration")), - }, - _ => Err(parse_err!(vec_loc, "expected top level declaration")), - }, - _ => Err(parse_err!( - sexpr.location(), - "expected top level declaration" - )), - } +impl<'a> Parse<'a> for TopLevelDocument<'a> { + fn parse(parser: Parser<'a>) -> Result { + let mut items = Vec::new(); + while !parser.is_empty() { + items.push(parser.parens(|p| p.parse())?); } + Ok(TopLevelDocument { items }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum DeclSyntax { - Typename(TypenameSyntax), - Module(ModuleSyntax), -} - -impl DeclSyntax { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - match sexpr { - SExpr::Vec(v, _) => match v.get(0) { - Some(SExpr::Word("typename", _)) => true, - Some(SExpr::Word("module", _)) => true, - _ => false, - }, - _ => false, +pub enum TopLevelSyntax<'a> { + Decl(DeclSyntax<'a>), + Use(&'a str), +} + +impl<'a> Parse<'a> for TopLevelSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + if parser.peek::() { + parser.parse::()?; + Ok(TopLevelSyntax::Use(parser.parse()?)) + } else { + Ok(TopLevelSyntax::Decl(parser.parse()?)) } } - pub fn parse(sexpr: &SExpr) -> Result { - match sexpr { - SExpr::Vec(v, loc) => match v.get(0) { - Some(SExpr::Word("typename", loc)) => { - Ok(DeclSyntax::Typename(TypenameSyntax::parse(&v[1..], loc)?)) - } - Some(SExpr::Word("module", loc)) => { - Ok(DeclSyntax::Module(ModuleSyntax::parse(&v[1..], loc)?)) - } - _ => Err(parse_err!(loc, "invalid declaration")), - }, - _ => Err(parse_err!(sexpr.location(), "expected vec")), +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum DeclSyntax<'a> { + Typename(TypenameSyntax<'a>), + Module(ModuleSyntax<'a>), +} + +impl<'a> Parse<'a> for DeclSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(DeclSyntax::Module(parser.parse()?)) + } else if l.peek::() { + Ok(DeclSyntax::Typename(parser.parse()?)) + } else { + Err(l.error()) } } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct TypenameSyntax { - pub ident: IdentSyntax, - pub def: TypedefSyntax, -} - -impl TypenameSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - let ident = match sexpr.get(0) { - Some(SExpr::Ident(i, loc)) => id!(i, loc), - Some(s) => Err(parse_err!(s.location(), "expected typename identifier"))?, - None => Err(parse_err!(loc, "expected typename identifier"))?, - }; - let def = match sexpr.get(1) { - Some(expr) => TypedefSyntax::parse(expr)?, - _ => Err(parse_err!(loc, "expected type definition"))?, - }; +pub struct TypenameSyntax<'a> { + pub ident: wast::Id<'a>, + pub def: TypedefSyntax<'a>, +} + +impl<'a> Parse<'a> for TypenameSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let ident = parser.parse()?; + let def = parser.parse()?; Ok(TypenameSyntax { ident, def }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum TypedefSyntax { - Ident(DatatypeIdentSyntax), - Enum(EnumSyntax), - Flags(FlagsSyntax), - Struct(StructSyntax), - Union(UnionSyntax), -} - -impl TypedefSyntax { - pub fn parse(sexpr: &SExpr) -> Result { - if DatatypeIdentSyntax::starts_parsing(sexpr) { - let ident = DatatypeIdentSyntax::parse(sexpr)?; - Ok(TypedefSyntax::Ident(ident)) - } else { - match sexpr { - SExpr::Vec(vs, loc) => match vs.get(0) { - Some(SExpr::Word("enum", loc)) => { - Ok(TypedefSyntax::Enum(EnumSyntax::parse(&vs[1..], loc)?)) - } - Some(SExpr::Word("flags", loc)) => { - Ok(TypedefSyntax::Flags(FlagsSyntax::parse(&vs[1..], loc)?)) - } - Some(SExpr::Word("struct", loc)) => { - Ok(TypedefSyntax::Struct(StructSyntax::parse(&vs[1..], loc)?)) - } - Some(SExpr::Word("union", loc)) => { - Ok(TypedefSyntax::Union(UnionSyntax::parse(&vs[1..], loc)?)) - } - _ => Err(parse_err!( - loc, - "expected type identifier or type definition" - )), - }, - _ => Err(parse_err!( - sexpr.location(), - "expected type identifier or type definition" - )), - } +pub enum TypedefSyntax<'a> { + Ident(DatatypeIdentSyntax<'a>), + Enum(EnumSyntax<'a>), + Flags(FlagsSyntax<'a>), + Struct(StructSyntax<'a>), + Union(UnionSyntax<'a>), +} + +impl<'a> Parse<'a> for TypedefSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + if !parser.peek::() || parser.peek2::() || parser.peek2::() + { + return Ok(TypedefSyntax::Ident(parser.parse()?)); } + parser.parens(|parser| { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(TypedefSyntax::Enum(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Flags(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Struct(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Union(parser.parse()?)) + } else { + Err(l.error()) + } + }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct EnumSyntax { +pub struct EnumSyntax<'a> { pub repr: BuiltinType, - pub members: Vec, -} - -impl EnumSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - let repr = match sexpr.get(0) { - Some(e) => BuiltinType::parse(e)?, - _ => Err(parse_err!(loc, "no enum repr"))?, - }; - let members = sexpr[1..] - .iter() - .map(|m| match m { - SExpr::Ident(i, loc) => Ok(id!(i, loc)), - s => Err(parse_err!(s.location(), "expected enum member identifier")), - }) - .collect::, ParseError>>()?; - if members.is_empty() { - Err(parse_err!(loc, "expected at least one enum member"))? + pub members: Vec>, +} + +impl<'a> Parse<'a> for EnumSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let repr = parser.parse()?; + let mut members = Vec::new(); + members.push(parser.parse()?); + while !parser.is_empty() { + members.push(parser.parse()?); } Ok(EnumSyntax { repr, members }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct FlagsSyntax { +pub struct FlagsSyntax<'a> { pub repr: BuiltinType, - pub flags: Vec, -} - -impl FlagsSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - let repr = BuiltinType::parse( - sexpr - .get(0) - .ok_or_else(|| parse_err!(loc, "expected flag repr type"))?, - )?; - let flags = sexpr[1..] - .iter() - .map(|f| match f { - SExpr::Vec(vs, loc) => match (vs.get(0), vs.get(1)) { - (Some(SExpr::Word("flag", _)), Some(SExpr::Ident(i, loc))) => Ok(id!(i, loc)), - _ => Err(parse_err!(loc, "expected flag specifier")), - }, - s => Err(parse_err!(s.location(), "expected flag specifier")), - }) - .collect::, ParseError>>()?; + pub flags: Vec>, +} + +impl<'a> Parse<'a> for FlagsSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let repr = parser.parse()?; + let mut flags = Vec::new(); + while !parser.is_empty() { + flags.push(parser.parens(|parser| { + parser.parse::()?; + parser.parse() + })?); + } Ok(FlagsSyntax { repr, flags }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct StructSyntax { - pub fields: Vec, +pub struct StructSyntax<'a> { + pub fields: Vec>, } -impl StructSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - if sexpr.is_empty() { - Err(parse_err!(loc, "expected at least one struct member"))? +impl<'a> Parse<'a> for StructSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let mut fields = Vec::new(); + fields.push(parser.parens(|p| p.parse())?); + while !parser.is_empty() { + fields.push(parser.parens(|p| p.parse())?); } - let fields = sexpr - .iter() - .map(|f| FieldSyntax::parse(f, "field")) - .collect::, ParseError>>()?; Ok(StructSyntax { fields }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct FieldSyntax { - pub name: IdentSyntax, - pub type_: DatatypeIdentSyntax, -} - -impl FieldSyntax { - pub fn starts_parsing(sexpr: &SExpr, constructor: &str) -> bool { - match sexpr { - SExpr::Vec(v, _) => match v.get(0) { - Some(SExpr::Word(c, _)) => *c == constructor, - _ => false, - }, - _ => false, - } - } - pub fn parse(sexpr: &SExpr, constructor: &str) -> Result { - match sexpr { - SExpr::Vec(v, loc) => match v.get(0) { - Some(SExpr::Word(c, _)) if *c == constructor => { - let name = match v.get(1) { - Some(SExpr::Ident(i, loc)) => id!(i, loc), - _ => Err(parse_err!(loc, "expected {} name identifier", constructor))?, - }; - let type_ = DatatypeIdentSyntax::parse(v.get(2).ok_or_else(|| { - parse_err!(loc, "expected {} type identifier", constructor) - })?)?; - Ok(FieldSyntax { name, type_ }) - } - _ => Err(parse_err!(loc, "expected {}", constructor)), - }, - _ => Err(parse_err!(sexpr.location(), "expected {}", constructor)), - } +pub struct FieldSyntax<'a> { + pub name: wast::Id<'a>, + pub type_: DatatypeIdentSyntax<'a>, +} + +impl<'a> Parse<'a> for FieldSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let name = parser.parse()?; + let type_ = parser.parse()?; + Ok(FieldSyntax { name, type_ }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct UnionSyntax { - pub fields: Vec, +pub struct UnionSyntax<'a> { + pub fields: Vec>, } -impl UnionSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - if sexpr.is_empty() { - Err(parse_err!(loc, "expected at least one union member"))? +impl<'a> Parse<'a> for UnionSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let mut fields = Vec::new(); + fields.push(parser.parens(|p| p.parse())?); + while !parser.is_empty() { + fields.push(parser.parens(|p| p.parse())?); } - let fields = sexpr - .iter() - .map(|f| FieldSyntax::parse(f, "field")) - .collect::, ParseError>>()?; Ok(UnionSyntax { fields }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct ModuleSyntax { - pub name: IdentSyntax, - pub decls: Vec, -} - -impl ModuleSyntax { - pub fn parse(sexprs: &[SExpr], loc: &Location) -> Result { - let name = match sexprs.get(0) { - Some(SExpr::Ident(i, loc)) => id!(i, loc), - _ => Err(parse_err!(loc, "expected module name"))?, - }; - let decls = sexprs[1..] - .iter() - .map(|s| ModuleDeclSyntax::parse(s)) - .collect::, _>>()?; +pub struct ModuleSyntax<'a> { + pub name: wast::Id<'a>, + pub decls: Vec>, +} + +impl<'a> Parse<'a> for ModuleSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let name = parser.parse()?; + let mut decls = Vec::new(); + while !parser.is_empty() { + decls.push(parser.parens(|p| p.parse())?); + } Ok(ModuleSyntax { name, decls }) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum ModuleDeclSyntax { - Import(ModuleImportSyntax), - Func(InterfaceFuncSyntax), -} - -impl ModuleDeclSyntax { - pub fn parse(sexpr: &SExpr) -> Result { - if ModuleImportSyntax::starts_parsing(sexpr) { - Ok(ModuleDeclSyntax::Import(ModuleImportSyntax::parse(sexpr)?)) - } else if InterfaceFuncSyntax::starts_parsing(sexpr) { - Ok(ModuleDeclSyntax::Func(InterfaceFuncSyntax::parse(sexpr)?)) +pub enum ModuleDeclSyntax<'a> { + Import(ModuleImportSyntax<'a>), + Func(InterfaceFuncSyntax<'a>), +} + +impl<'a> Parse<'a> for ModuleDeclSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(ModuleDeclSyntax::Import(parser.parse()?)) + } else if l.peek::() { + Ok(ModuleDeclSyntax::Func(parser.parse()?)) } else { - Err(parse_err!(sexpr.location(), "expected import or function")) + Err(l.error()) } } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ModuleImportSyntax { - pub name: IdentSyntax, +#[derive(Debug, Clone)] +pub struct ModuleImportSyntax<'a> { + pub name: &'a str, + pub name_loc: wast::Span, pub type_: ImportTypeSyntax, } -impl ModuleImportSyntax { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - match sexpr { - SExpr::Vec(vs, _) => match vs.get(0) { - Some(SExpr::Word("import", _)) => true, - _ => false, - }, - _ => false, - } +impl<'a> Parse<'a> for ModuleImportSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let name_loc = parser.cur_span(); + Ok(ModuleImportSyntax { + name: parser.parse()?, + name_loc, + type_: parser.parens(|p| p.parse())?, + }) } - pub fn parse(sexpr: &SExpr) -> Result { - match sexpr { - SExpr::Vec(vs, vec_loc) => match (vs.get(0), vs.get(1)) { - (Some(SExpr::Word("import", _)), Some(SExpr::Quote(name, loc))) => { - let name = id!(name, loc); - let type_ = ImportTypeSyntax::parse(&vs[2..], vec_loc)?; - Ok(ModuleImportSyntax { name, type_ }) - } - _ => Err(parse_err!(vec_loc, "expected module import")), - }, - _ => Err(parse_err!(sexpr.location(), "expected module import")), - } +} + +impl PartialEq for ModuleImportSyntax<'_> { + fn eq(&self, other: &ModuleImportSyntax<'_>) -> bool { + // skip the `name_loc` field + self.name == other.name && self.type_ == other.type_ } } +impl Eq for ModuleImportSyntax<'_> {} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum ImportTypeSyntax { Memory, } -impl ImportTypeSyntax { - pub fn parse(sexpr: &[SExpr], loc: &Location) -> Result { - if sexpr.len() > 1 { - Err(parse_err!(loc, "too many elements for an import type"))?; - } - match sexpr.get(0) { - Some(SExpr::Vec(vs, loc)) => match vs.get(0) { - Some(SExpr::Word("memory", _)) => { - if vs.len() == 1 { - Ok(ImportTypeSyntax::Memory) - } else { - Err(parse_err!(loc, "too many elements for memory declaration")) - } - } - _ => Err(parse_err!(loc, "expected import type")), - }, - _ => Err(parse_err!(loc, "expected import type")), - } +impl Parse<'_> for ImportTypeSyntax { + fn parse(parser: Parser<'_>) -> Result { + parser.parse::()?; + Ok(ImportTypeSyntax::Memory) } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct InterfaceFuncSyntax { - pub export: IdentSyntax, - pub params: Vec, - pub results: Vec, -} - -impl InterfaceFuncSyntax { - pub fn starts_parsing(sexpr: &SExpr) -> bool { - match sexpr { - SExpr::Vec(vs, _) => match (vs.get(0), vs.get(1)) { - (Some(SExpr::Annot("interface", _)), Some(SExpr::Word("func", _))) => true, - _ => false, - }, - _ => false, +#[derive(Debug, Clone)] +pub struct InterfaceFuncSyntax<'a> { + pub export: &'a str, + pub export_loc: wast::Span, + pub params: Vec>, + pub results: Vec>, +} + +impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + parser.parse::()?; + + let (export_loc, export) = parser.parens(|p| { + p.parse::()?; + Ok((p.cur_span(), p.parse()?)) + })?; + + let mut params = Vec::new(); + let mut results = Vec::new(); + + while !parser.is_empty() { + parser.parens(|p| { + let mut l = p.lookahead1(); + if l.peek::() { + parser.parse::()?; + params.push(FieldSyntax { + name: parser.parse()?, + type_: parser.parse()?, + }); + } else if l.peek::() { + parser.parse::()?; + results.push(FieldSyntax { + name: parser.parse()?, + type_: parser.parse()?, + }); + } else { + return Err(l.error()); + } + Ok(()) + })?; } + + Ok(InterfaceFuncSyntax { + export, + export_loc, + params, + results, + }) } - pub fn parse(sexpr: &SExpr) -> Result { - match sexpr { - SExpr::Vec(vs, loc) => match (vs.get(0), vs.get(1)) { - (Some(SExpr::Annot("interface", _)), Some(SExpr::Word("func", _))) => { - let export = match vs.get(2) { - Some(SExpr::Vec(es, loc)) => match (es.get(0), es.get(1)) { - ( - Some(SExpr::Word("export", _)), - Some(SExpr::Quote(name, name_loc)), - ) => { - if es.len() == 2 { - id!(name, name_loc) - } else { - Err(parse_err!( - loc, - "too many elements for export declaration" - ))? - } - } - _ => Err(parse_err!(loc, "expected export declaration"))?, - }, - _ => Err(parse_err!(loc, "expected export declaration"))?, - }; - let mut params = Vec::new(); - let mut results = Vec::new(); - - for sexpr in &vs[3..] { - if FieldSyntax::starts_parsing(sexpr, "param") { - let param = FieldSyntax::parse(sexpr, "param")?; - params.push(param); - } else if FieldSyntax::starts_parsing(sexpr, "result") { - let result = FieldSyntax::parse(sexpr, "result")?; - results.push(result); - } else { - Err(parse_err!( - sexpr.location(), - "expected param or result field" - ))?; - } - } - - Ok(InterfaceFuncSyntax { - export, - params, - results, - }) - } - _ => Err(parse_err!(loc, "expected interface func declaration")), - }, +} - _ => Err(parse_err!( - sexpr.location(), - "expected interface func declaration" - )), - } +impl PartialEq for InterfaceFuncSyntax<'_> { + fn eq(&self, other: &InterfaceFuncSyntax<'_>) -> bool { + // skip the `export_loc` field + self.export == other.export && self.params == other.params && self.results == other.results } } + +impl Eq for InterfaceFuncSyntax<'_> {} diff --git a/proposals/filesystem/tools/witx/src/sexpr.rs b/proposals/filesystem/tools/witx/src/sexpr.rs deleted file mode 100644 index d87d427e3..000000000 --- a/proposals/filesystem/tools/witx/src/sexpr.rs +++ /dev/null @@ -1,240 +0,0 @@ -use crate::io::{Filesystem, WitxIo}; -pub use crate::lexer::LexError; -use crate::lexer::{Lexer, LocatedError, LocatedToken, Token}; -use crate::Location; -use failure::Fail; -use std::path::{Path, PathBuf}; - -///! The s-expression parser turns a string into a stream of SExprs. -///! It uses the `Lexer` under the hood. -///! This implementation was heavily influenced by `cranelift-reader` - -#[derive(Debug, PartialEq, Eq, Clone)] -pub enum SExpr<'a> { - Vec(Vec>, Location), - Word(&'a str, Location), - Ident(&'a str, Location), - Quote(&'a str, Location), - /// Short for Annotation - Annot(&'a str, Location), -} - -impl<'a> SExpr<'a> { - pub fn location(&self) -> Location { - match self { - SExpr::Vec(_, loc) => loc.clone(), - SExpr::Word(_, loc) => loc.clone(), - SExpr::Ident(_, loc) => loc.clone(), - SExpr::Quote(_, loc) => loc.clone(), - SExpr::Annot(_, loc) => loc.clone(), - } - } -} - -#[derive(Debug, PartialEq, Eq, Clone, Fail)] -pub enum SExprParseError { - #[fail(display = "Lexical error: {}", _0)] - Lex(LexError, Location), - #[fail(display = "Unexpected ')'")] - UnexpectedCloseParen(Location), - #[fail(display = "Unexpected end of input in {:?}", _0)] - UnexpectedEof(PathBuf), -} - -impl SExprParseError { - pub fn report_with(&self, witxio: &dyn WitxIo) -> String { - use SExprParseError::*; - match self { - Lex(lex_err, loc) => format!("{}\n{}", loc.highlight_source_with(witxio), lex_err), - UnexpectedCloseParen(loc) => format!("{}\n{}", loc.highlight_source_with(witxio), self), - UnexpectedEof(_path) => format!("{}", self), - } - } - pub fn report(&self) -> String { - self.report_with(&Filesystem) - } -} - -pub struct SExprParser<'a> { - lex: Lexer<'a>, - lookahead: Option>, - location: Location, -} - -impl<'a> SExprParser<'a> { - pub fn new>(text: &'a str, path: P) -> SExprParser<'_> { - SExprParser { - lex: Lexer::new(text, path.as_ref()), - lookahead: None, - location: Location { - path: path.as_ref().into(), - line: 0, - column: 0, - }, - } - } - fn consume(&mut self) -> Token<'a> { - self.lookahead.take().expect("no token to consume") - } - fn token(&mut self) -> Result>, SExprParseError> { - while self.lookahead == None { - match self.lex.next() { - Some(Ok(LocatedToken { token, location })) => { - self.location = location; - self.lookahead = Some(token) - } - Some(Err(LocatedError { error, location })) => { - self.location = location.clone(); - Err(SExprParseError::Lex(error, location))?; - } - None => break, - } - } - Ok(self.lookahead) - } - - pub fn match_sexpr(&mut self) -> Result, SExprParseError> { - let location = self.location.clone(); - match self.token()? { - Some(Token::LPar) => { - self.consume(); - let mut members = Vec::new(); - loop { - match self.token()? { - Some(Token::RPar) => { - self.consume(); - break; - } - _ => { - members.push(self.match_sexpr()?); - } - } - } - Ok(SExpr::Vec(members, location)) - } - Some(Token::Word(word)) => { - self.consume(); - Ok(SExpr::Word(word, location)) - } - Some(Token::Ident(id)) => { - self.consume(); - Ok(SExpr::Ident(id, location)) - } - Some(Token::Annot(id)) => { - self.consume(); - Ok(SExpr::Annot(id, location)) - } - Some(Token::Quote(q)) => { - self.consume(); - Ok(SExpr::Quote(q, location)) - } - Some(Token::RPar) => Err(SExprParseError::UnexpectedCloseParen(location)), - None => Err(SExprParseError::UnexpectedEof(self.location.path.clone())), - } - } - - pub fn match_sexprs(&mut self) -> Result>, SExprParseError> { - let mut sexprs = Vec::new(); - while self.token()?.is_some() { - sexprs.push(self.match_sexpr()?); - } - Ok(sexprs) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use std::path::PathBuf; - - fn loc(line: usize, col: usize) -> Location { - Location { - path: PathBuf::from("/test"), - line: line, - column: col, - } - } - - fn testparser(input: &str) -> SExprParser { - SExprParser::new(input, Path::new("/test")) - } - - #[test] - fn empty() { - let mut parser = testparser(""); - assert_eq!(parser.match_sexprs().expect("valid parse"), Vec::new()); - let mut parser = testparser(" ;; just a comment\n;;another"); - assert_eq!(parser.match_sexprs().expect("valid parse"), Vec::new()); - } - - #[test] - fn atoms() { - let mut parser = testparser("hello\n$world\n\"a quotation\""); - assert_eq!( - parser.match_sexprs().expect("valid parse"), - vec![ - SExpr::Word("hello", loc(1, 0)), - SExpr::Ident("world", loc(2, 0)), - SExpr::Quote("a quotation", loc(3, 0)), - ] - ); - } - - #[test] - fn lists() { - let mut parser = testparser("()"); - assert_eq!( - parser.match_sexprs().expect("valid parse"), - vec![SExpr::Vec(vec![], loc(1, 0))] - ); - - let mut parser = testparser("(hello\n$world\n\"a quotation\")"); - assert_eq!( - parser.match_sexprs().expect("valid parse"), - vec![SExpr::Vec( - vec![ - SExpr::Word("hello", loc(1, 1)), - SExpr::Ident("world", loc(2, 0)), - SExpr::Quote("a quotation", loc(3, 0)), - ], - loc(1, 0) - )] - ); - - let mut parser = testparser("((($deep)))"); - assert_eq!( - parser.match_sexprs().expect("valid parse"), - vec![SExpr::Vec( - vec![SExpr::Vec( - vec![SExpr::Vec(vec![SExpr::Ident("deep", loc(1, 3))], loc(1, 2))], - loc(1, 1) - )], - loc(1, 0) - )] - ); - } - - #[test] - fn errors() { - let mut parser = testparser("("); - assert_eq!( - parser.match_sexprs().err().expect("dies"), - SExprParseError::UnexpectedEof(PathBuf::from("/test")) - ); - let mut parser = testparser(")"); - assert_eq!( - parser.match_sexprs().err().expect("dies"), - SExprParseError::UnexpectedCloseParen(loc(1, 0)) - ); - let mut parser = testparser("())"); - assert_eq!( - parser.match_sexprs().err().expect("dies"), - SExprParseError::UnexpectedCloseParen(loc(1, 2)) - ); - let mut parser = testparser("$ ;; should be a lex error"); - assert_eq!( - parser.match_sexprs().err().expect("dies"), - SExprParseError::Lex(LexError::EmptyIdentifier, loc(1, 0),), - ); - } -} diff --git a/proposals/filesystem/tools/witx/src/toplevel.rs b/proposals/filesystem/tools/witx/src/toplevel.rs index 98325b39c..927bdd4de 100644 --- a/proposals/filesystem/tools/witx/src/toplevel.rs +++ b/proposals/filesystem/tools/witx/src/toplevel.rs @@ -1,162 +1,144 @@ +use crate::ast::{Definition, Document}; use crate::io::{Filesystem, WitxIo}; -use crate::parser::{DeclSyntax, ParseError, TopLevelSyntax}; -use crate::sexpr::SExprParser; +use crate::parser::{TopLevelDocument, TopLevelSyntax}; +use crate::validate::DocValidation; use crate::WitxError; use std::collections::HashSet; use std::path::{Path, PathBuf}; -pub fn parse_witx>(i: P) -> Result, WitxError> { - parse_witx_with(i, &Filesystem) +pub fn parse_witx(i: impl AsRef) -> Result { + _parse_witx_with(i.as_ref(), &Filesystem) } -pub fn parse_witx_with>( - i: P, - witxio: &dyn WitxIo, -) -> Result, WitxError> { - let input_path = witxio.canonicalize(&i.as_ref())?; - - let input = witxio.fgets(&input_path)?; - - let toplevel = parse_toplevel(&input, &input_path)?; - let mut resolved = HashSet::new(); - resolved.insert(input_path.clone()); - let search_path = input_path.parent().unwrap_or(Path::new(".")); - resolve_uses(toplevel, &search_path, &mut resolved, witxio) +pub fn parse_witx_with(i: impl AsRef, witxio: impl WitxIo) -> Result { + _parse_witx_with(i.as_ref(), &witxio) } -fn parse_toplevel(source_text: &str, file_path: &Path) -> Result, WitxError> { - let mut sexpr_parser = SExprParser::new(source_text, file_path); - let sexprs = sexpr_parser.match_sexprs().map_err(WitxError::SExpr)?; - let top_levels = sexprs - .iter() - .map(|s| TopLevelSyntax::parse(s)) - .collect::, ParseError>>() - .map_err(WitxError::Parse)?; - Ok(top_levels) +fn _parse_witx_with(path: &Path, io: &dyn WitxIo) -> Result { + let mut validator = DocValidation::new(); + let mut definitions = Vec::new(); + let root = path.parent().unwrap_or(Path::new(".")); + + parse_file( + path.file_name().unwrap().as_ref(), + io, + root, + &mut validator, + &mut definitions, + &mut HashSet::new(), + )?; + Ok(Document::new(definitions, validator.entries)) } -fn resolve_uses( - toplevel: Vec, - search_path: &Path, - used: &mut HashSet, - witxio: &dyn WitxIo, -) -> Result, WitxError> { - let mut decls = Vec::new(); +fn parse_file( + path: &Path, + io: &dyn WitxIo, + root: &Path, + validator: &mut DocValidation, + definitions: &mut Vec, + parsed: &mut HashSet, +) -> Result<(), WitxError> { + let path = io.canonicalize(&root.join(path))?; + if !parsed.insert(path.clone()) { + return Ok(()); + } + let input = io.fgets(&path)?; + + let adjust_err = |mut error: wast::Error| { + error.set_path(&path); + error.set_text(&input); + WitxError::Parse(error) + }; + let buf = wast::parser::ParseBuffer::new(&input).map_err(adjust_err)?; + let doc = wast::parser::parse::(&buf).map_err(adjust_err)?; - for t in toplevel { + for t in doc.items { match t { - TopLevelSyntax::Decl(d) => decls.push(d), + TopLevelSyntax::Decl(d) => { + let def = validator + .scope(&input, &path) + .validate_decl(&d) + .map_err(WitxError::Validation)?; + definitions.push(def); + } TopLevelSyntax::Use(u) => { - let abs_path = witxio.canonicalize(&search_path.join(u.name))?; - // Include the decls from a use declaration only once - // in a given toplevel. Same idea as #pragma once. - if !used.contains(&abs_path) { - used.insert(abs_path.clone()); - - let source_text = witxio.fgets(&abs_path)?; - let inner_toplevels = parse_toplevel(&source_text, &abs_path)?; - - let inner_decls = resolve_uses(inner_toplevels, search_path, used, witxio)?; - decls.extend(inner_decls) - } + parse_file(u.as_ref(), io, root, validator, definitions, parsed)?; } } } - Ok(decls) + Ok(()) } #[cfg(test)] mod test { use super::*; + use crate::ast::*; use crate::io::MockFs; - use crate::parser::*; - use crate::Location; #[test] fn empty() { - assert_eq!( - parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", ";; empty")])).expect("parse"), - Vec::new(), - ); + parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", ";; empty")])).expect("parse"); } #[test] fn one_use() { - assert_eq!( - parse_witx_with( - &Path::new("/a"), - &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]) - ) - .expect("parse"), - Vec::new(), - ); + parse_witx_with( + &Path::new("/a"), + &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]), + ) + .unwrap(); } #[test] fn multi_use() { - assert_eq!( - parse_witx_with( - &Path::new("/a"), - &MockFs::new(&[ - ("/a", "(use \"b\")"), - ("/b", "(use \"c\")\n(typename $b_float f64)"), - ("/c", "(typename $c_int u32)") - ]) - ) - .expect("parse"), - vec![ - DeclSyntax::Typename(TypenameSyntax { - ident: IdentSyntax { - name: "c_int".to_owned(), - location: Location { - path: PathBuf::from("/c"), - line: 1, - column: 10, - } - }, - def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::U32)) - }), - DeclSyntax::Typename(TypenameSyntax { - ident: IdentSyntax { - name: "b_float".to_owned(), - location: Location { - path: PathBuf::from("/b"), - line: 2, - column: 10, - } - }, - def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::F64)) - }) - ], - ); + let doc = parse_witx_with( + &Path::new("/a"), + &MockFs::new(&[ + ("/a", "(use \"b\")"), + ("/b", "(use \"c\")\n(typename $b_float f64)"), + ("/c", "(typename $c_int u32)"), + ]), + ) + .expect("parse"); + + match &doc.datatype(&Id::new("b_float")).unwrap().variant { + DatatypeVariant::Alias(a) => { + assert_eq!(a.name.as_str(), "b_float"); + assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::F64)); + } + other => panic!("expected alias, got {:?}", other), + } + + match &doc.datatype(&Id::new("c_int")).unwrap().variant { + DatatypeVariant::Alias(a) => { + assert_eq!(a.name.as_str(), "c_int"); + assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::U32)); + } + other => panic!("expected alias, got {:?}", other), + } } #[test] fn diamond_dependency() { - assert_eq!( - parse_witx_with( - &Path::new("/a"), - &MockFs::new(&[ - ("/a", "(use \"b\")\n(use \"c\")"), - ("/b", "(use \"d\")"), - ("/c", "(use \"d\")"), - ("/d", "(typename $d_char u8)") - ]) - ) - .expect("parse"), - vec![DeclSyntax::Typename(TypenameSyntax { - ident: IdentSyntax { - name: "d_char".to_owned(), - location: Location { - path: PathBuf::from("/d"), - line: 1, - column: 10, - } - }, - def: TypedefSyntax::Ident(DatatypeIdentSyntax::Builtin(BuiltinType::U8)) - })], - ); + let doc = parse_witx_with( + &Path::new("/a"), + &MockFs::new(&[ + ("/a", "(use \"b\")\n(use \"c\")"), + ("/b", "(use \"d\")"), + ("/c", "(use \"d\")"), + ("/d", "(typename $d_char u8)"), + ]), + ) + .expect("parse"); + + match &doc.datatype(&Id::new("d_char")).unwrap().variant { + DatatypeVariant::Alias(a) => { + assert_eq!(a.name.as_str(), "d_char"); + assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::U8)); + } + other => panic!("expected alias, got {:?}", other), + } } #[test] @@ -177,15 +159,9 @@ mod test { .unwrap() { WitxError::Parse(e) => { - assert_eq!(e.message, "invalid use declaration"); - assert_eq!( - e.location, - Location { - path: PathBuf::from("/a"), - line: 1, - column: 1 - } - ); + let err = e.to_string(); + assert!(err.contains("expected a string"), "bad error: {}", err); + assert!(err.contains("/a:1:6")); } e => panic!("wrong error: {:?}", e), } diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 526409e62..df11c521c 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -1,17 +1,17 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ - DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, IdentSyntax, ImportTypeSyntax, + DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, - Definition, Document, Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, - InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, - ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, - UnionVariant, + Definition, Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, + InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, + ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; use failure::Fail; use std::collections::HashMap; +use std::path::Path; use std::rc::Rc; #[derive(Debug, Fail)] @@ -73,16 +73,6 @@ impl ValidationError { } } -pub fn validate_document(decls: &[DeclSyntax]) -> Result { - let mut validator = DocValidation::new(); - let mut definitions = Vec::new(); - for d in decls { - definitions.push(validator.validate_decl(&d)?); - } - - Ok(Document::new(definitions, validator.entries)) -} - struct IdentValidation { names: HashMap, } @@ -93,49 +83,84 @@ impl IdentValidation { names: HashMap::new(), } } - fn introduce(&mut self, syntax: &IdentSyntax) -> Result { - if let Some(introduced) = self.names.get(&syntax.name) { + + fn introduce(&mut self, syntax: &str, location: Location) -> Result { + if let Some(introduced) = self.names.get(syntax) { Err(ValidationError::NameAlreadyExists { - name: syntax.name.clone(), - at_location: syntax.location.clone(), + name: syntax.to_string(), + at_location: location, previous_location: introduced.clone(), }) } else { - self.names - .insert(syntax.name.clone(), syntax.location.clone()); - Ok(Id::new(&syntax.name)) + self.names.insert(syntax.to_string(), location); + Ok(Id::new(syntax)) } } - fn get(&self, syntax: &IdentSyntax) -> Result { - if self.names.get(&syntax.name).is_some() { - Ok(Id::new(&syntax.name)) + fn get(&self, syntax: &str, location: Location) -> Result { + if self.names.get(syntax).is_some() { + Ok(Id::new(syntax)) } else { Err(ValidationError::UnknownName { - name: syntax.name.clone(), - location: syntax.location.clone(), + name: syntax.to_string(), + location, }) } } } -struct DocValidation { +pub struct DocValidation { scope: IdentValidation, pub entries: HashMap, } +pub struct DocValidationScope<'a> { + doc: &'a mut DocValidation, + text: &'a str, + path: &'a Path, +} + impl DocValidation { - fn new() -> Self { + pub fn new() -> Self { Self { scope: IdentValidation::new(), entries: HashMap::new(), } } - fn validate_decl(&mut self, decl: &DeclSyntax) -> Result { + pub fn scope<'a>(&'a mut self, text: &'a str, path: &'a Path) -> DocValidationScope<'a> { + DocValidationScope { + doc: self, + text, + path, + } + } +} + +impl DocValidationScope<'_> { + fn location(&self, span: wast::Span) -> Location { + let (line, column) = span.linecol_in(self.text); + Location { + line, + column, + path: self.path.to_path_buf(), + } + } + + fn introduce(&mut self, name: &wast::Id<'_>) -> Result { + let loc = self.location(name.span()); + self.doc.scope.introduce(name.name(), loc) + } + + fn get(&self, name: &wast::Id<'_>) -> Result { + let loc = self.location(name.span()); + self.doc.scope.get(name.name(), loc) + } + + pub fn validate_decl(&mut self, decl: &DeclSyntax) -> Result { match decl { DeclSyntax::Typename(decl) => { - let name = self.scope.introduce(&decl.ident)?; + let name = self.introduce(&decl.ident)?; let variant = match &decl.def { TypedefSyntax::Ident(syntax) => DatatypeVariant::Alias(AliasDatatype { @@ -145,28 +170,29 @@ impl DocValidation { TypedefSyntax::Enum(syntax) => DatatypeVariant::Enum(self.validate_enum( &name, &syntax, - &decl.ident.location, + decl.ident.span(), )?), TypedefSyntax::Flags(syntax) => DatatypeVariant::Flags( - self.validate_flags(&name, &syntax, &decl.ident.location)?, + self.validate_flags(&name, &syntax, decl.ident.span())?, ), TypedefSyntax::Struct(syntax) => DatatypeVariant::Struct( - self.validate_struct(&name, &syntax, &decl.ident.location)?, + self.validate_struct(&name, &syntax, decl.ident.span())?, ), TypedefSyntax::Union(syntax) => DatatypeVariant::Union( - self.validate_union(&name, &syntax, &decl.ident.location)?, + self.validate_union(&name, &syntax, decl.ident.span())?, ), }; let rc_datatype = Rc::new(Datatype { name: name.clone(), variant, }); - self.entries + self.doc + .entries .insert(name, Entry::Datatype(Rc::downgrade(&rc_datatype))); Ok(Definition::Datatype(rc_datatype)) } DeclSyntax::Module(syntax) => { - let name = self.scope.introduce(&syntax.name)?; + let name = self.introduce(&syntax.name)?; let mut module_validator = ModuleValidation::new(self); let definitions = syntax .decls @@ -179,7 +205,8 @@ impl DocValidation { definitions, module_validator.entries, )); - self.entries + self.doc + .entries .insert(name, Entry::Module(Rc::downgrade(&rc_module))); Ok(Definition::Module(rc_module)) } @@ -202,20 +229,20 @@ impl DocValidation { self.validate_datatype_ident(&a)?, ))), DatatypeIdentSyntax::Ident(i) => { - let id = self.scope.get(i)?; - match self.entries.get(&id) { + let id = self.get(i)?; + match self.doc.entries.get(&id) { Some(Entry::Datatype(weak_d)) => Ok(DatatypeIdent::Ident( weak_d.upgrade().expect("weak backref to defined type"), )), Some(e) => Err(ValidationError::WrongKindName { - name: i.name.clone(), - location: i.location.clone(), + name: i.name().to_string(), + location: self.location(i.span()), expected: "datatype", got: e.kind(), }), None => Err(ValidationError::Recursive { - name: i.name.clone(), - location: i.location.clone(), + name: i.name().to_string(), + location: self.location(i.span()), }), } } @@ -226,14 +253,14 @@ impl DocValidation { &self, name: &Id, syntax: &EnumSyntax, - location: &Location, + span: wast::Span, ) -> Result { let mut enum_scope = IdentValidation::new(); - let repr = validate_int_repr(&syntax.repr, location)?; + let repr = self.validate_int_repr(&syntax.repr, span)?; let variants = syntax .members .iter() - .map(|i| enum_scope.introduce(i)) + .map(|i| enum_scope.introduce(i.name(), self.location(i.span()))) .collect::, _>>()?; Ok(EnumDatatype { @@ -247,14 +274,14 @@ impl DocValidation { &self, name: &Id, syntax: &FlagsSyntax, - location: &Location, + span: wast::Span, ) -> Result { let mut flags_scope = IdentValidation::new(); - let repr = validate_int_repr(&syntax.repr, location)?; + let repr = self.validate_int_repr(&syntax.repr, span)?; let flags = syntax .flags .iter() - .map(|i| flags_scope.introduce(i)) + .map(|i| flags_scope.introduce(i.name(), self.location(i.span()))) .collect::, _>>()?; Ok(FlagsDatatype { @@ -268,7 +295,7 @@ impl DocValidation { &self, name: &Id, syntax: &StructSyntax, - _location: &Location, + _span: wast::Span, ) -> Result { let mut member_scope = IdentValidation::new(); let members = syntax @@ -276,7 +303,7 @@ impl DocValidation { .iter() .map(|f| { Ok(StructMember { - name: member_scope.introduce(&f.name)?, + name: member_scope.introduce(f.name.name(), self.location(f.name.span()))?, type_: self.validate_datatype_ident(&f.type_)?, }) }) @@ -292,7 +319,7 @@ impl DocValidation { &self, name: &Id, syntax: &UnionSyntax, - _location: &Location, + _span: wast::Span, ) -> Result { let mut variant_scope = IdentValidation::new(); let variants = syntax @@ -300,7 +327,7 @@ impl DocValidation { .iter() .map(|f| { Ok(UnionVariant { - name: variant_scope.introduce(&f.name)?, + name: variant_scope.introduce(f.name.name(), self.location(f.name.span()))?, type_: self.validate_datatype_ident(&f.type_)?, }) }) @@ -311,29 +338,33 @@ impl DocValidation { variants, }) } -} -fn validate_int_repr(type_: &BuiltinType, location: &Location) -> Result { - match type_ { - BuiltinType::U8 => Ok(IntRepr::U8), - BuiltinType::U16 => Ok(IntRepr::U16), - BuiltinType::U32 => Ok(IntRepr::U32), - BuiltinType::U64 => Ok(IntRepr::U64), - _ => Err(ValidationError::InvalidRepr { - repr: type_.clone(), - location: location.clone(), - }), + fn validate_int_repr( + &self, + type_: &BuiltinType, + span: wast::Span, + ) -> Result { + match type_ { + BuiltinType::U8 => Ok(IntRepr::U8), + BuiltinType::U16 => Ok(IntRepr::U16), + BuiltinType::U32 => Ok(IntRepr::U32), + BuiltinType::U64 => Ok(IntRepr::U64), + _ => Err(ValidationError::InvalidRepr { + repr: type_.clone(), + location: self.location(span), + }), + } } } struct ModuleValidation<'a> { - doc: &'a DocValidation, + doc: &'a DocValidationScope<'a>, scope: IdentValidation, pub entries: HashMap, } impl<'a> ModuleValidation<'a> { - fn new(doc: &'a DocValidation) -> Self { + fn new(doc: &'a DocValidationScope<'a>) -> Self { Self { doc, scope: IdentValidation::new(), @@ -347,7 +378,8 @@ impl<'a> ModuleValidation<'a> { ) -> Result { match decl { ModuleDeclSyntax::Import(syntax) => { - let name = self.scope.introduce(&syntax.name)?; + let loc = self.doc.location(syntax.name_loc); + let name = self.scope.introduce(syntax.name, loc)?; let variant = match syntax.type_ { ImportTypeSyntax::Memory => ModuleImportVariant::Memory, }; @@ -360,7 +392,8 @@ impl<'a> ModuleValidation<'a> { Ok(ModuleDefinition::Import(rc_import)) } ModuleDeclSyntax::Func(syntax) => { - let name = self.scope.introduce(&syntax.export)?; + let loc = self.doc.location(syntax.export_loc); + let name = self.scope.introduce(syntax.export, loc)?; let mut argnames = IdentValidation::new(); let params = syntax .params @@ -368,7 +401,8 @@ impl<'a> ModuleValidation<'a> { .enumerate() .map(|(ix, f)| { Ok(InterfaceFuncParam { - name: argnames.introduce(&f.name)?, + name: argnames + .introduce(f.name.name(), self.doc.location(f.name.span()))?, type_: self.doc.validate_datatype_ident(&f.type_)?, position: InterfaceFuncParamPosition::Param(ix), }) @@ -384,12 +418,13 @@ impl<'a> ModuleValidation<'a> { match type_.passed_by() { DatatypePassedBy::Value(_) => {} _ => Err(ValidationError::InvalidFirstResultType { - location: f.name.location.clone(), + location: self.doc.location(f.name.span()), })?, } } Ok(InterfaceFuncParam { - name: argnames.introduce(&f.name)?, + name: argnames + .introduce(f.name.name(), self.doc.location(f.name.span()))?, type_, position: InterfaceFuncParamPosition::Result(ix), }) diff --git a/proposals/filesystem/tools/witx/tests/wasi_unstable.rs b/proposals/filesystem/tools/witx/tests/wasi_unstable.rs index 482224344..68e65186a 100644 --- a/proposals/filesystem/tools/witx/tests/wasi_unstable.rs +++ b/proposals/filesystem/tools/witx/tests/wasi_unstable.rs @@ -6,7 +6,7 @@ fn validate_wasi_unstable_preview0() { witx::load(Path::new( "../../phases/unstable/witx/wasi_unstable_preview0.witx", )) - .unwrap(); + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] @@ -14,12 +14,13 @@ fn validate_wasi_ephemeral_preview() { witx::load(Path::new( "../../phases/ephemeral/witx/wasi_ephemeral_preview.witx", )) - .unwrap(); + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_old_preview0() { - witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")).unwrap(); + witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] @@ -27,7 +28,7 @@ fn render_roundtrip() { let doc = witx::load(Path::new( "../../phases/unstable/witx/wasi_unstable_preview0.witx", )) - .unwrap(); + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); let back_to_sexprs = format!("{}", doc); println!("{}", back_to_sexprs); From 626bfc37335455d7a4e5a481abccc0d1b88ecc9e Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 22 Oct 2019 09:55:46 -0700 Subject: [PATCH 0223/1772] witx: add alex as author, bump to 0.3.1 --- proposals/clocks/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 9a38ed265..90a2b48b5 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "witx" -version = "0.3.0" +version = "0.3.1" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" license = "Apache-2.0" categories = ["wasm"] -authors = ["Pat Hickey "] +authors = ["Pat Hickey ", "Alex Crichton "] edition = "2018" [lib] From 8d3e3408714bde6d034eb2a1ee1b9a7e70bfdd64 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 22 Oct 2019 09:55:46 -0700 Subject: [PATCH 0224/1772] witx: add alex as author, bump to 0.3.1 --- proposals/random/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 9a38ed265..90a2b48b5 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "witx" -version = "0.3.0" +version = "0.3.1" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" license = "Apache-2.0" categories = ["wasm"] -authors = ["Pat Hickey "] +authors = ["Pat Hickey ", "Alex Crichton "] edition = "2018" [lib] From f0cf06675d56a535c62fade73b7b9448115fb5e9 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 22 Oct 2019 09:55:46 -0700 Subject: [PATCH 0225/1772] witx: add alex as author, bump to 0.3.1 --- proposals/filesystem/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 9a38ed265..90a2b48b5 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "witx" -version = "0.3.0" +version = "0.3.1" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" license = "Apache-2.0" categories = ["wasm"] -authors = ["Pat Hickey "] +authors = ["Pat Hickey ", "Alex Crichton "] edition = "2018" [lib] From 92643e6a45177553fa913435025544b4bb09fba0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 25 Oct 2019 23:53:39 -0700 Subject: [PATCH 0226/1772] Reorder the `clockid_t` values to match existing practice. (#112) Move `CLOCK_REALTIME` to be the first `clockid_t` value. This change reflects the definitions used in [existing practice], so this patch updates the `wasi_unstable_preview0` and `wasi_unstable` definitions as well. This is the same change as #41, but updated for the WASI repository's new phases directory structure. [existing practice]: https://github.com/CraneStation/wasi-libc/blob/master/libc-bottom-half/headers/public/wasi/core.h#L42 --- .../phases/ephemeral/docs/wasi_ephemeral_preview.md | 10 +++++----- proposals/clocks/phases/ephemeral/witx/typenames.witx | 6 +++--- .../clocks/phases/old/docs/wasi_unstable_preview0.md | 10 +++++----- proposals/clocks/phases/old/witx/typenames.witx | 6 +++--- .../phases/unstable/docs/wasi_unstable_preview0.md | 10 +++++----- proposals/clocks/phases/unstable/witx/typenames.witx | 6 +++--- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md index 0e93982fa..a0bdd1825 100644 --- a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -1113,6 +1113,11 @@ Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#cl Possible values: +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + - **`__WASI_CLOCK_MONOTONIC`** The store-wide monotonic clock, which is defined as a @@ -1127,11 +1132,6 @@ Possible values: The CPU-time clock associated with the current process. -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - - **`__WASI_CLOCK_THREAD_CPUTIME_ID`** The CPU-time clock associated with the current thread. diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 9c98fa79f..5cccd2cda 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -16,6 +16,9 @@ ;; Identifiers for clocks. (typename $clockid_t (enum u32 + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME ;; The store-wide monotonic clock, which is defined as a clock measuring ;; real time, whose value cannot be adjusted and which cannot have negative ;; clock jumps. The epoch of this clock is undefined. The absolute time @@ -23,9 +26,6 @@ $CLOCK_MONOTONIC ;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME ;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) diff --git a/proposals/clocks/phases/old/docs/wasi_unstable_preview0.md b/proposals/clocks/phases/old/docs/wasi_unstable_preview0.md index 9db4a382e..260fd58b6 100644 --- a/proposals/clocks/phases/old/docs/wasi_unstable_preview0.md +++ b/proposals/clocks/phases/old/docs/wasi_unstable_preview0.md @@ -1113,6 +1113,11 @@ Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#cl Possible values: +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + - **`__WASI_CLOCK_MONOTONIC`** The store-wide monotonic clock, which is defined as a @@ -1127,11 +1132,6 @@ Possible values: The CPU-time clock associated with the current process. -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - - **`__WASI_CLOCK_THREAD_CPUTIME_ID`** The CPU-time clock associated with the current thread. diff --git a/proposals/clocks/phases/old/witx/typenames.witx b/proposals/clocks/phases/old/witx/typenames.witx index e04a188d9..a00c8ce14 100644 --- a/proposals/clocks/phases/old/witx/typenames.witx +++ b/proposals/clocks/phases/old/witx/typenames.witx @@ -16,6 +16,9 @@ ;; Identifiers for clocks. (typename $clockid_t (enum u32 + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME ;; The store-wide monotonic clock, which is defined as a clock measuring ;; real time, whose value cannot be adjusted and which cannot have negative ;; clock jumps. The epoch of this clock is undefined. The absolute time @@ -23,9 +26,6 @@ $CLOCK_MONOTONIC ;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME ;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) diff --git a/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md index 9db4a382e..260fd58b6 100644 --- a/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md +++ b/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md @@ -1113,6 +1113,11 @@ Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#cl Possible values: +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + - **`__WASI_CLOCK_MONOTONIC`** The store-wide monotonic clock, which is defined as a @@ -1127,11 +1132,6 @@ Possible values: The CPU-time clock associated with the current process. -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - - **`__WASI_CLOCK_THREAD_CPUTIME_ID`** The CPU-time clock associated with the current thread. diff --git a/proposals/clocks/phases/unstable/witx/typenames.witx b/proposals/clocks/phases/unstable/witx/typenames.witx index e04a188d9..a00c8ce14 100644 --- a/proposals/clocks/phases/unstable/witx/typenames.witx +++ b/proposals/clocks/phases/unstable/witx/typenames.witx @@ -16,6 +16,9 @@ ;; Identifiers for clocks. (typename $clockid_t (enum u32 + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME ;; The store-wide monotonic clock, which is defined as a clock measuring ;; real time, whose value cannot be adjusted and which cannot have negative ;; clock jumps. The epoch of this clock is undefined. The absolute time @@ -23,9 +26,6 @@ $CLOCK_MONOTONIC ;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME ;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) From d7b0150890e2230d6df5300bcad28946b7fb0239 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 25 Oct 2019 23:53:39 -0700 Subject: [PATCH 0227/1772] Reorder the `clockid_t` values to match existing practice. (#112) Move `CLOCK_REALTIME` to be the first `clockid_t` value. This change reflects the definitions used in [existing practice], so this patch updates the `wasi_unstable_preview0` and `wasi_unstable` definitions as well. This is the same change as #41, but updated for the WASI repository's new phases directory structure. [existing practice]: https://github.com/CraneStation/wasi-libc/blob/master/libc-bottom-half/headers/public/wasi/core.h#L42 --- .../phases/ephemeral/docs/wasi_ephemeral_preview.md | 10 +++++----- proposals/random/phases/ephemeral/witx/typenames.witx | 6 +++--- .../random/phases/old/docs/wasi_unstable_preview0.md | 10 +++++----- proposals/random/phases/old/witx/typenames.witx | 6 +++--- .../phases/unstable/docs/wasi_unstable_preview0.md | 10 +++++----- proposals/random/phases/unstable/witx/typenames.witx | 6 +++--- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md index 0e93982fa..a0bdd1825 100644 --- a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -1113,6 +1113,11 @@ Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#cl Possible values: +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + - **`__WASI_CLOCK_MONOTONIC`** The store-wide monotonic clock, which is defined as a @@ -1127,11 +1132,6 @@ Possible values: The CPU-time clock associated with the current process. -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - - **`__WASI_CLOCK_THREAD_CPUTIME_ID`** The CPU-time clock associated with the current thread. diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 9c98fa79f..5cccd2cda 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -16,6 +16,9 @@ ;; Identifiers for clocks. (typename $clockid_t (enum u32 + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME ;; The store-wide monotonic clock, which is defined as a clock measuring ;; real time, whose value cannot be adjusted and which cannot have negative ;; clock jumps. The epoch of this clock is undefined. The absolute time @@ -23,9 +26,6 @@ $CLOCK_MONOTONIC ;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME ;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) diff --git a/proposals/random/phases/old/docs/wasi_unstable_preview0.md b/proposals/random/phases/old/docs/wasi_unstable_preview0.md index 9db4a382e..260fd58b6 100644 --- a/proposals/random/phases/old/docs/wasi_unstable_preview0.md +++ b/proposals/random/phases/old/docs/wasi_unstable_preview0.md @@ -1113,6 +1113,11 @@ Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#cl Possible values: +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + - **`__WASI_CLOCK_MONOTONIC`** The store-wide monotonic clock, which is defined as a @@ -1127,11 +1132,6 @@ Possible values: The CPU-time clock associated with the current process. -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - - **`__WASI_CLOCK_THREAD_CPUTIME_ID`** The CPU-time clock associated with the current thread. diff --git a/proposals/random/phases/old/witx/typenames.witx b/proposals/random/phases/old/witx/typenames.witx index e04a188d9..a00c8ce14 100644 --- a/proposals/random/phases/old/witx/typenames.witx +++ b/proposals/random/phases/old/witx/typenames.witx @@ -16,6 +16,9 @@ ;; Identifiers for clocks. (typename $clockid_t (enum u32 + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME ;; The store-wide monotonic clock, which is defined as a clock measuring ;; real time, whose value cannot be adjusted and which cannot have negative ;; clock jumps. The epoch of this clock is undefined. The absolute time @@ -23,9 +26,6 @@ $CLOCK_MONOTONIC ;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME ;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) diff --git a/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md index 9db4a382e..260fd58b6 100644 --- a/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md +++ b/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md @@ -1113,6 +1113,11 @@ Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#cl Possible values: +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + - **`__WASI_CLOCK_MONOTONIC`** The store-wide monotonic clock, which is defined as a @@ -1127,11 +1132,6 @@ Possible values: The CPU-time clock associated with the current process. -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - - **`__WASI_CLOCK_THREAD_CPUTIME_ID`** The CPU-time clock associated with the current thread. diff --git a/proposals/random/phases/unstable/witx/typenames.witx b/proposals/random/phases/unstable/witx/typenames.witx index e04a188d9..a00c8ce14 100644 --- a/proposals/random/phases/unstable/witx/typenames.witx +++ b/proposals/random/phases/unstable/witx/typenames.witx @@ -16,6 +16,9 @@ ;; Identifiers for clocks. (typename $clockid_t (enum u32 + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME ;; The store-wide monotonic clock, which is defined as a clock measuring ;; real time, whose value cannot be adjusted and which cannot have negative ;; clock jumps. The epoch of this clock is undefined. The absolute time @@ -23,9 +26,6 @@ $CLOCK_MONOTONIC ;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME ;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) From 6b533dc5aa24dc39ec1b3c2c1df1cc587c46dadb Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 25 Oct 2019 23:53:39 -0700 Subject: [PATCH 0228/1772] Reorder the `clockid_t` values to match existing practice. (#112) Move `CLOCK_REALTIME` to be the first `clockid_t` value. This change reflects the definitions used in [existing practice], so this patch updates the `wasi_unstable_preview0` and `wasi_unstable` definitions as well. This is the same change as #41, but updated for the WASI repository's new phases directory structure. [existing practice]: https://github.com/CraneStation/wasi-libc/blob/master/libc-bottom-half/headers/public/wasi/core.h#L42 --- .../phases/ephemeral/docs/wasi_ephemeral_preview.md | 10 +++++----- .../filesystem/phases/ephemeral/witx/typenames.witx | 6 +++--- .../phases/old/docs/wasi_unstable_preview0.md | 10 +++++----- proposals/filesystem/phases/old/witx/typenames.witx | 6 +++--- .../phases/unstable/docs/wasi_unstable_preview0.md | 10 +++++----- .../filesystem/phases/unstable/witx/typenames.witx | 6 +++--- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md index 0e93982fa..a0bdd1825 100644 --- a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -1113,6 +1113,11 @@ Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#cl Possible values: +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + - **`__WASI_CLOCK_MONOTONIC`** The store-wide monotonic clock, which is defined as a @@ -1127,11 +1132,6 @@ Possible values: The CPU-time clock associated with the current process. -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - - **`__WASI_CLOCK_THREAD_CPUTIME_ID`** The CPU-time clock associated with the current thread. diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 9c98fa79f..5cccd2cda 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -16,6 +16,9 @@ ;; Identifiers for clocks. (typename $clockid_t (enum u32 + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME ;; The store-wide monotonic clock, which is defined as a clock measuring ;; real time, whose value cannot be adjusted and which cannot have negative ;; clock jumps. The epoch of this clock is undefined. The absolute time @@ -23,9 +26,6 @@ $CLOCK_MONOTONIC ;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME ;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) diff --git a/proposals/filesystem/phases/old/docs/wasi_unstable_preview0.md b/proposals/filesystem/phases/old/docs/wasi_unstable_preview0.md index 9db4a382e..260fd58b6 100644 --- a/proposals/filesystem/phases/old/docs/wasi_unstable_preview0.md +++ b/proposals/filesystem/phases/old/docs/wasi_unstable_preview0.md @@ -1113,6 +1113,11 @@ Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#cl Possible values: +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + - **`__WASI_CLOCK_MONOTONIC`** The store-wide monotonic clock, which is defined as a @@ -1127,11 +1132,6 @@ Possible values: The CPU-time clock associated with the current process. -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - - **`__WASI_CLOCK_THREAD_CPUTIME_ID`** The CPU-time clock associated with the current thread. diff --git a/proposals/filesystem/phases/old/witx/typenames.witx b/proposals/filesystem/phases/old/witx/typenames.witx index e04a188d9..a00c8ce14 100644 --- a/proposals/filesystem/phases/old/witx/typenames.witx +++ b/proposals/filesystem/phases/old/witx/typenames.witx @@ -16,6 +16,9 @@ ;; Identifiers for clocks. (typename $clockid_t (enum u32 + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME ;; The store-wide monotonic clock, which is defined as a clock measuring ;; real time, whose value cannot be adjusted and which cannot have negative ;; clock jumps. The epoch of this clock is undefined. The absolute time @@ -23,9 +26,6 @@ $CLOCK_MONOTONIC ;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME ;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) diff --git a/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md index 9db4a382e..260fd58b6 100644 --- a/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md +++ b/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md @@ -1113,6 +1113,11 @@ Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#cl Possible values: +- **`__WASI_CLOCK_REALTIME`** + + The clock measuring real time. Time value + zero corresponds with 1970-01-01T00:00:00Z. + - **`__WASI_CLOCK_MONOTONIC`** The store-wide monotonic clock, which is defined as a @@ -1127,11 +1132,6 @@ Possible values: The CPU-time clock associated with the current process. -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - - **`__WASI_CLOCK_THREAD_CPUTIME_ID`** The CPU-time clock associated with the current thread. diff --git a/proposals/filesystem/phases/unstable/witx/typenames.witx b/proposals/filesystem/phases/unstable/witx/typenames.witx index e04a188d9..a00c8ce14 100644 --- a/proposals/filesystem/phases/unstable/witx/typenames.witx +++ b/proposals/filesystem/phases/unstable/witx/typenames.witx @@ -16,6 +16,9 @@ ;; Identifiers for clocks. (typename $clockid_t (enum u32 + ;; The clock measuring real time. Time value zero corresponds with + ;; 1970-01-01T00:00:00Z. + $CLOCK_REALTIME ;; The store-wide monotonic clock, which is defined as a clock measuring ;; real time, whose value cannot be adjusted and which cannot have negative ;; clock jumps. The epoch of this clock is undefined. The absolute time @@ -23,9 +26,6 @@ $CLOCK_MONOTONIC ;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME ;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) From cdbdb12105561d45e59f415329f1bea89d861c9b Mon Sep 17 00:00:00 2001 From: Peter Huene Date: Mon, 28 Oct 2019 12:29:41 -0700 Subject: [PATCH 0229/1772] Fix CI on Windows. (#131) Use `bash` as the default shell for installing Rust as `&&` is not a valid command separator in PowerShell. --- proposals/clocks/.github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 434ba393d..797e4f1ca 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -11,6 +11,7 @@ jobs: steps: - uses: actions/checkout@master - name: Install Rust (rustup) + shell: bash run: rustup update stable --no-self-update && rustup default stable if: matrix.os != 'macos-latest' - name: Install Rust (macos) From aa99daf4ae5a5f03736bc31c1b5e348ed67cb3ac Mon Sep 17 00:00:00 2001 From: Peter Huene Date: Mon, 28 Oct 2019 12:29:41 -0700 Subject: [PATCH 0230/1772] Fix CI on Windows. (#131) Use `bash` as the default shell for installing Rust as `&&` is not a valid command separator in PowerShell. --- proposals/random/.github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index 434ba393d..797e4f1ca 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -11,6 +11,7 @@ jobs: steps: - uses: actions/checkout@master - name: Install Rust (rustup) + shell: bash run: rustup update stable --no-self-update && rustup default stable if: matrix.os != 'macos-latest' - name: Install Rust (macos) From 3b2703a1627fdb5b65499e12400c07774df4dd28 Mon Sep 17 00:00:00 2001 From: Peter Huene Date: Mon, 28 Oct 2019 12:29:41 -0700 Subject: [PATCH 0231/1772] Fix CI on Windows. (#131) Use `bash` as the default shell for installing Rust as `&&` is not a valid command separator in PowerShell. --- proposals/filesystem/.github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index 434ba393d..797e4f1ca 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -11,6 +11,7 @@ jobs: steps: - uses: actions/checkout@master - name: Install Rust (rustup) + shell: bash run: rustup update stable --no-self-update && rustup default stable if: matrix.os != 'macos-latest' - name: Install Rust (macos) From 874fad1c8c3408927730ea1e58d8224384e555f3 Mon Sep 17 00:00:00 2001 From: Peter Huene Date: Thu, 31 Oct 2019 13:48:04 -0700 Subject: [PATCH 0232/1772] Make `__wasi_args_get` and `__wasi_environ_get` docs more explicit. (#128) This commit updates the documentation for `__wasi_args_get` and `__wasi_environ_get` to make it explicit that it is the caller's responsibility to allocate a terminating NULL pointer, if necessary. Fixes #27. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md index a0bdd1825..ad7bd9bf0 100644 --- a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -117,18 +117,22 @@ modules so that embedders need not implement all of it. Read command-line argument data. -The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - Inputs: - char \*\*argv A pointer to a buffer to write the argument pointers. + The count of elements for the buffer should be at least the value of `argc` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + + The caller of `__wasi_args_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. + - char \*argv\_buf A pointer to a buffer to write the argument string data. + The size of this buffer should be the value of `argv_buf_size` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + ### `__wasi_args_sizes_get()` Return command-line argument data sizes. @@ -192,21 +196,25 @@ Outputs: Read environment variable data. -The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - Inputs: - char \*\*environ A pointer to a buffer to write the environment variable pointers. + The count of elements for the buffer should be at least the value of `environ_count` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + + The caller of `__wasi_environ_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. + - char \*environ\_buf A pointer to a buffer to write the environment variable string data. + The size of this buffer should be the value of `environ_buf_size` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + ### `__wasi_environ_sizes_get()` -Return command-line argument data sizes. +Return enviroment variable data sizes. Outputs: From d9ead1c527f5407131cb9fd86b28a875e0d6f050 Mon Sep 17 00:00:00 2001 From: Peter Huene Date: Thu, 31 Oct 2019 13:48:04 -0700 Subject: [PATCH 0233/1772] Make `__wasi_args_get` and `__wasi_environ_get` docs more explicit. (#128) This commit updates the documentation for `__wasi_args_get` and `__wasi_environ_get` to make it explicit that it is the caller's responsibility to allocate a terminating NULL pointer, if necessary. Fixes #27. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md index a0bdd1825..ad7bd9bf0 100644 --- a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -117,18 +117,22 @@ modules so that embedders need not implement all of it. Read command-line argument data. -The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - Inputs: - char \*\*argv A pointer to a buffer to write the argument pointers. + The count of elements for the buffer should be at least the value of `argc` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + + The caller of `__wasi_args_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. + - char \*argv\_buf A pointer to a buffer to write the argument string data. + The size of this buffer should be the value of `argv_buf_size` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + ### `__wasi_args_sizes_get()` Return command-line argument data sizes. @@ -192,21 +196,25 @@ Outputs: Read environment variable data. -The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - Inputs: - char \*\*environ A pointer to a buffer to write the environment variable pointers. + The count of elements for the buffer should be at least the value of `environ_count` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + + The caller of `__wasi_environ_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. + - char \*environ\_buf A pointer to a buffer to write the environment variable string data. + The size of this buffer should be the value of `environ_buf_size` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + ### `__wasi_environ_sizes_get()` -Return command-line argument data sizes. +Return enviroment variable data sizes. Outputs: From 75964a4a3077191e64bb0ec59800a7dbb67c01c4 Mon Sep 17 00:00:00 2001 From: Peter Huene Date: Thu, 31 Oct 2019 13:48:04 -0700 Subject: [PATCH 0234/1772] Make `__wasi_args_get` and `__wasi_environ_get` docs more explicit. (#128) This commit updates the documentation for `__wasi_args_get` and `__wasi_environ_get` to make it explicit that it is the caller's responsibility to allocate a terminating NULL pointer, if necessary. Fixes #27. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md index a0bdd1825..ad7bd9bf0 100644 --- a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -117,18 +117,22 @@ modules so that embedders need not implement all of it. Read command-line argument data. -The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - Inputs: - char \*\*argv A pointer to a buffer to write the argument pointers. + The count of elements for the buffer should be at least the value of `argc` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + + The caller of `__wasi_args_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. + - char \*argv\_buf A pointer to a buffer to write the argument string data. + The size of this buffer should be the value of `argv_buf_size` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + ### `__wasi_args_sizes_get()` Return command-line argument data sizes. @@ -192,21 +196,25 @@ Outputs: Read environment variable data. -The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - Inputs: - char \*\*environ A pointer to a buffer to write the environment variable pointers. + The count of elements for the buffer should be at least the value of `environ_count` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + + The caller of `__wasi_environ_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. + - char \*environ\_buf A pointer to a buffer to write the environment variable string data. + The size of this buffer should be the value of `environ_buf_size` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + ### `__wasi_environ_sizes_get()` -Return command-line argument data sizes. +Return enviroment variable data sizes. Outputs: From 0e019c6b7950b48831cc27647ff7c22c823c9a42 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 31 Oct 2019 13:50:13 -0700 Subject: [PATCH 0235/1772] Remove `subscription_t`'s `clock.identifier` field. (#125) As noticed in https://github.com/rust-lang/rust/pull/65617#issue-330088745, the `clock.identifier` field in `subscription_t` isn't used for anything. It came from CloudABI, where it appears to be a holdover from an earlier API feature which is no longer present. --- proposals/clocks/phases/ephemeral/witx/typenames.witx | 2 -- 1 file changed, 2 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 5cccd2cda..7d513e791 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -552,8 +552,6 @@ ;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) ;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) ;; The absolute or relative timestamp. From e854b5a0aa4b37911fe9585ec7f3c3180e5d3844 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 31 Oct 2019 13:50:13 -0700 Subject: [PATCH 0236/1772] Remove `subscription_t`'s `clock.identifier` field. (#125) As noticed in https://github.com/rust-lang/rust/pull/65617#issue-330088745, the `clock.identifier` field in `subscription_t` isn't used for anything. It came from CloudABI, where it appears to be a holdover from an earlier API feature which is no longer present. --- proposals/random/phases/ephemeral/witx/typenames.witx | 2 -- 1 file changed, 2 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 5cccd2cda..7d513e791 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -552,8 +552,6 @@ ;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) ;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) ;; The absolute or relative timestamp. From df8382b79375e9cc57e1aed06948f1c27def1ecf Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 31 Oct 2019 13:50:13 -0700 Subject: [PATCH 0237/1772] Remove `subscription_t`'s `clock.identifier` field. (#125) As noticed in https://github.com/rust-lang/rust/pull/65617#issue-330088745, the `clock.identifier` field in `subscription_t` isn't used for anything. It came from CloudABI, where it appears to be a holdover from an earlier API feature which is no longer present. --- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 2 -- 1 file changed, 2 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 5cccd2cda..7d513e791 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -552,8 +552,6 @@ ;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) ;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) ;; The absolute or relative timestamp. From 5cf89e9f3febcc19e0778f015cfa174904f6c105 Mon Sep 17 00:00:00 2001 From: Peter Huene Date: Thu, 31 Oct 2019 13:51:55 -0700 Subject: [PATCH 0238/1772] Change hard link count to 64-bits. (#127) This commit changes the type for `__wasi_linkcount_t` to 64-bits to support large link counts. Fixes #70. --- .../clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md | 2 +- proposals/clocks/phases/ephemeral/witx/typenames.witx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md index ad7bd9bf0..e7f1eeef0 100644 --- a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -1807,7 +1807,7 @@ Members: The address and length of the buffer to be filled. -### `__wasi_linkcount_t` (`uint32_t`) +### `__wasi_linkcount_t` (`uint64_t`) Number of hard links to an inode. diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 7d513e791..e3e6f3024 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -451,7 +451,7 @@ ) ;; Number of hard links to an inode. -(typename $linkcount_t u32) +(typename $linkcount_t u64) ;; File attributes. (typename $filestat_t From 18dd9ca65fc5a9d7334dbfcff4e649f410fe3bfd Mon Sep 17 00:00:00 2001 From: Peter Huene Date: Thu, 31 Oct 2019 13:51:55 -0700 Subject: [PATCH 0239/1772] Change hard link count to 64-bits. (#127) This commit changes the type for `__wasi_linkcount_t` to 64-bits to support large link counts. Fixes #70. --- .../random/phases/ephemeral/docs/wasi_ephemeral_preview.md | 2 +- proposals/random/phases/ephemeral/witx/typenames.witx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md index ad7bd9bf0..e7f1eeef0 100644 --- a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -1807,7 +1807,7 @@ Members: The address and length of the buffer to be filled. -### `__wasi_linkcount_t` (`uint32_t`) +### `__wasi_linkcount_t` (`uint64_t`) Number of hard links to an inode. diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 7d513e791..e3e6f3024 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -451,7 +451,7 @@ ) ;; Number of hard links to an inode. -(typename $linkcount_t u32) +(typename $linkcount_t u64) ;; File attributes. (typename $filestat_t From 582099b47b778435578b796f53d6add3934e9197 Mon Sep 17 00:00:00 2001 From: Peter Huene Date: Thu, 31 Oct 2019 13:51:55 -0700 Subject: [PATCH 0240/1772] Change hard link count to 64-bits. (#127) This commit changes the type for `__wasi_linkcount_t` to 64-bits to support large link counts. Fixes #70. --- .../filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md | 2 +- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md index ad7bd9bf0..e7f1eeef0 100644 --- a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -1807,7 +1807,7 @@ Members: The address and length of the buffer to be filled. -### `__wasi_linkcount_t` (`uint32_t`) +### `__wasi_linkcount_t` (`uint64_t`) Number of hard links to an inode. diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 7d513e791..e3e6f3024 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -451,7 +451,7 @@ ) ;; Number of hard links to an inode. -(typename $linkcount_t u32) +(typename $linkcount_t u64) ;; File attributes. (typename $filestat_t From 7755adcba306e6b53128fa2b4e6392eb6d09b21e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 31 Oct 2019 14:01:47 -0700 Subject: [PATCH 0241/1772] Fix the missing `flags` field in `subscription_clock_t`. (#129) Add the `flags` field to `subscription_clock_t`, which was accidentally omitted. This change reflects the definitions used in [existing practice], so this patch updates the `wasi_unstable_preview0` and `wasi_unstable` definitions as well. [existing practice]: https://github.com/CraneStation/wasi-libc/blob/master/libc-bottom-half/headers/public/wasi/core.h#L421 --- proposals/clocks/phases/ephemeral/witx/typenames.witx | 4 ++-- proposals/clocks/phases/old/witx/typenames.witx | 4 ++-- proposals/clocks/phases/unstable/witx/typenames.witx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index e3e6f3024..5c08ec81a 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -558,9 +558,9 @@ (field $timeout $timestamp_t) ;; The amount of time that the implementation may wait additionally ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative (field $precision $timestamp_t) + ;; Flags specifying whether the timeout is absolute or relative + (field $flags $subclockflags_t) ) ) diff --git a/proposals/clocks/phases/old/witx/typenames.witx b/proposals/clocks/phases/old/witx/typenames.witx index a00c8ce14..c265e1bb6 100644 --- a/proposals/clocks/phases/old/witx/typenames.witx +++ b/proposals/clocks/phases/old/witx/typenames.witx @@ -560,9 +560,9 @@ (field $timeout $timestamp_t) ;; The amount of time that the implementation may wait additionally ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative (field $precision $timestamp_t) + ;; Flags specifying whether the timeout is absolute or relative + (field $flags $subclockflags_t) ) ) diff --git a/proposals/clocks/phases/unstable/witx/typenames.witx b/proposals/clocks/phases/unstable/witx/typenames.witx index a00c8ce14..c265e1bb6 100644 --- a/proposals/clocks/phases/unstable/witx/typenames.witx +++ b/proposals/clocks/phases/unstable/witx/typenames.witx @@ -560,9 +560,9 @@ (field $timeout $timestamp_t) ;; The amount of time that the implementation may wait additionally ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative (field $precision $timestamp_t) + ;; Flags specifying whether the timeout is absolute or relative + (field $flags $subclockflags_t) ) ) From c5ce59aed11bfcc22d3711e54660a9bdee0febe1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 31 Oct 2019 14:01:47 -0700 Subject: [PATCH 0242/1772] Fix the missing `flags` field in `subscription_clock_t`. (#129) Add the `flags` field to `subscription_clock_t`, which was accidentally omitted. This change reflects the definitions used in [existing practice], so this patch updates the `wasi_unstable_preview0` and `wasi_unstable` definitions as well. [existing practice]: https://github.com/CraneStation/wasi-libc/blob/master/libc-bottom-half/headers/public/wasi/core.h#L421 --- proposals/random/phases/ephemeral/witx/typenames.witx | 4 ++-- proposals/random/phases/old/witx/typenames.witx | 4 ++-- proposals/random/phases/unstable/witx/typenames.witx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index e3e6f3024..5c08ec81a 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -558,9 +558,9 @@ (field $timeout $timestamp_t) ;; The amount of time that the implementation may wait additionally ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative (field $precision $timestamp_t) + ;; Flags specifying whether the timeout is absolute or relative + (field $flags $subclockflags_t) ) ) diff --git a/proposals/random/phases/old/witx/typenames.witx b/proposals/random/phases/old/witx/typenames.witx index a00c8ce14..c265e1bb6 100644 --- a/proposals/random/phases/old/witx/typenames.witx +++ b/proposals/random/phases/old/witx/typenames.witx @@ -560,9 +560,9 @@ (field $timeout $timestamp_t) ;; The amount of time that the implementation may wait additionally ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative (field $precision $timestamp_t) + ;; Flags specifying whether the timeout is absolute or relative + (field $flags $subclockflags_t) ) ) diff --git a/proposals/random/phases/unstable/witx/typenames.witx b/proposals/random/phases/unstable/witx/typenames.witx index a00c8ce14..c265e1bb6 100644 --- a/proposals/random/phases/unstable/witx/typenames.witx +++ b/proposals/random/phases/unstable/witx/typenames.witx @@ -560,9 +560,9 @@ (field $timeout $timestamp_t) ;; The amount of time that the implementation may wait additionally ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative (field $precision $timestamp_t) + ;; Flags specifying whether the timeout is absolute or relative + (field $flags $subclockflags_t) ) ) From 298f998755e765aa7226c7a668012225ed4cbcb1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 31 Oct 2019 14:01:47 -0700 Subject: [PATCH 0243/1772] Fix the missing `flags` field in `subscription_clock_t`. (#129) Add the `flags` field to `subscription_clock_t`, which was accidentally omitted. This change reflects the definitions used in [existing practice], so this patch updates the `wasi_unstable_preview0` and `wasi_unstable` definitions as well. [existing practice]: https://github.com/CraneStation/wasi-libc/blob/master/libc-bottom-half/headers/public/wasi/core.h#L421 --- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 4 ++-- proposals/filesystem/phases/old/witx/typenames.witx | 4 ++-- proposals/filesystem/phases/unstable/witx/typenames.witx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index e3e6f3024..5c08ec81a 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -558,9 +558,9 @@ (field $timeout $timestamp_t) ;; The amount of time that the implementation may wait additionally ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative (field $precision $timestamp_t) + ;; Flags specifying whether the timeout is absolute or relative + (field $flags $subclockflags_t) ) ) diff --git a/proposals/filesystem/phases/old/witx/typenames.witx b/proposals/filesystem/phases/old/witx/typenames.witx index a00c8ce14..c265e1bb6 100644 --- a/proposals/filesystem/phases/old/witx/typenames.witx +++ b/proposals/filesystem/phases/old/witx/typenames.witx @@ -560,9 +560,9 @@ (field $timeout $timestamp_t) ;; The amount of time that the implementation may wait additionally ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative (field $precision $timestamp_t) + ;; Flags specifying whether the timeout is absolute or relative + (field $flags $subclockflags_t) ) ) diff --git a/proposals/filesystem/phases/unstable/witx/typenames.witx b/proposals/filesystem/phases/unstable/witx/typenames.witx index a00c8ce14..c265e1bb6 100644 --- a/proposals/filesystem/phases/unstable/witx/typenames.witx +++ b/proposals/filesystem/phases/unstable/witx/typenames.witx @@ -560,9 +560,9 @@ (field $timeout $timestamp_t) ;; The amount of time that the implementation may wait additionally ;; to coalesce with other events. - ;; - ;; Flags specifying whether the timeout is absolute or relative (field $precision $timestamp_t) + ;; Flags specifying whether the timeout is absolute or relative + (field $flags $subclockflags_t) ) ) From 95d88eb8f38266227e382451194020791ae77cac Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 31 Oct 2019 14:02:29 -0700 Subject: [PATCH 0244/1772] Document the special meaning of `dircookie_t` value 0. (#130) Add a comment mentioning the special value of `dircookie_t`. --- proposals/clocks/phases/ephemeral/witx/typenames.witx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 5c08ec81a..c6d2ce9e8 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -315,6 +315,8 @@ ) ;; A reference to the offset of a directory entry. +;; +;; The value 0 signifies the start of the directory. (typename $dircookie_t u64) ;; The type for the $d_namlen field of $dirent_t. From b307f7a9a615f8122d0289c87273e2751ef63469 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 31 Oct 2019 14:02:29 -0700 Subject: [PATCH 0245/1772] Document the special meaning of `dircookie_t` value 0. (#130) Add a comment mentioning the special value of `dircookie_t`. --- proposals/random/phases/ephemeral/witx/typenames.witx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 5c08ec81a..c6d2ce9e8 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -315,6 +315,8 @@ ) ;; A reference to the offset of a directory entry. +;; +;; The value 0 signifies the start of the directory. (typename $dircookie_t u64) ;; The type for the $d_namlen field of $dirent_t. From 58ebef9133c32bb2dad5a2ef5d67ce1742c24a34 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 31 Oct 2019 14:02:29 -0700 Subject: [PATCH 0246/1772] Document the special meaning of `dircookie_t` value 0. (#130) Add a comment mentioning the special value of `dircookie_t`. --- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 5c08ec81a..c6d2ce9e8 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -315,6 +315,8 @@ ) ;; A reference to the offset of a directory entry. +;; +;; The value 0 signifies the start of the directory. (typename $dircookie_t u64) ;; The type for the $d_namlen field of $dirent_t. From b88fca46d59316229fc57c7d1df17d11dd1c718c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 09:52:44 -0800 Subject: [PATCH 0247/1772] Make `eventtype_t` an enum rather than a flags. (#133) This matches existing practice, so update the `unstable` and `old` definitions too. --- proposals/clocks/phases/ephemeral/witx/typenames.witx | 8 ++++---- proposals/clocks/phases/old/witx/typenames.witx | 8 ++++---- proposals/clocks/phases/unstable/witx/typenames.witx | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index c6d2ce9e8..1c5babbdd 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -483,16 +483,16 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t - (flags u8 + (enum u8 ;; The time value of clock `subscription_t::u.clock.clock_id` has ;; reached timestamp `subscription_t::u.clock.timeout`. - (flag $EVENTTYPE_CLOCK) + $EVENTTYPE_CLOCK ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data ;; available for reading. This event always triggers for regular files. - (flag $EVENTTYPE_FD_READ) + $EVENTTYPE_FD_READ ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity ;; available for writing. This event always triggers for regular files. - (flag $EVENTTYPE_FD_WRITE) + $EVENTTYPE_FD_WRITE ) ) diff --git a/proposals/clocks/phases/old/witx/typenames.witx b/proposals/clocks/phases/old/witx/typenames.witx index c265e1bb6..68f2ef15f 100644 --- a/proposals/clocks/phases/old/witx/typenames.witx +++ b/proposals/clocks/phases/old/witx/typenames.witx @@ -481,16 +481,16 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t - (flags u8 + (enum u8 ;; The time value of clock `subscription_t::u.clock.clock_id` has ;; reached timestamp `subscription_t::u.clock.timeout`. - (flag $EVENTTYPE_CLOCK) + $EVENTTYPE_CLOCK ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data ;; available for reading. This event always triggers for regular files. - (flag $EVENTTYPE_FD_READ) + $EVENTTYPE_FD_READ ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity ;; available for writing. This event always triggers for regular files. - (flag $EVENTTYPE_FD_WRITE) + $EVENTTYPE_FD_WRITE ) ) diff --git a/proposals/clocks/phases/unstable/witx/typenames.witx b/proposals/clocks/phases/unstable/witx/typenames.witx index c265e1bb6..68f2ef15f 100644 --- a/proposals/clocks/phases/unstable/witx/typenames.witx +++ b/proposals/clocks/phases/unstable/witx/typenames.witx @@ -481,16 +481,16 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t - (flags u8 + (enum u8 ;; The time value of clock `subscription_t::u.clock.clock_id` has ;; reached timestamp `subscription_t::u.clock.timeout`. - (flag $EVENTTYPE_CLOCK) + $EVENTTYPE_CLOCK ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data ;; available for reading. This event always triggers for regular files. - (flag $EVENTTYPE_FD_READ) + $EVENTTYPE_FD_READ ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity ;; available for writing. This event always triggers for regular files. - (flag $EVENTTYPE_FD_WRITE) + $EVENTTYPE_FD_WRITE ) ) From f05c4605037adb83c22f66cf5ac08c989e7eea1f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 09:52:44 -0800 Subject: [PATCH 0248/1772] Make `eventtype_t` an enum rather than a flags. (#133) This matches existing practice, so update the `unstable` and `old` definitions too. --- proposals/random/phases/ephemeral/witx/typenames.witx | 8 ++++---- proposals/random/phases/old/witx/typenames.witx | 8 ++++---- proposals/random/phases/unstable/witx/typenames.witx | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index c6d2ce9e8..1c5babbdd 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -483,16 +483,16 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t - (flags u8 + (enum u8 ;; The time value of clock `subscription_t::u.clock.clock_id` has ;; reached timestamp `subscription_t::u.clock.timeout`. - (flag $EVENTTYPE_CLOCK) + $EVENTTYPE_CLOCK ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data ;; available for reading. This event always triggers for regular files. - (flag $EVENTTYPE_FD_READ) + $EVENTTYPE_FD_READ ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity ;; available for writing. This event always triggers for regular files. - (flag $EVENTTYPE_FD_WRITE) + $EVENTTYPE_FD_WRITE ) ) diff --git a/proposals/random/phases/old/witx/typenames.witx b/proposals/random/phases/old/witx/typenames.witx index c265e1bb6..68f2ef15f 100644 --- a/proposals/random/phases/old/witx/typenames.witx +++ b/proposals/random/phases/old/witx/typenames.witx @@ -481,16 +481,16 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t - (flags u8 + (enum u8 ;; The time value of clock `subscription_t::u.clock.clock_id` has ;; reached timestamp `subscription_t::u.clock.timeout`. - (flag $EVENTTYPE_CLOCK) + $EVENTTYPE_CLOCK ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data ;; available for reading. This event always triggers for regular files. - (flag $EVENTTYPE_FD_READ) + $EVENTTYPE_FD_READ ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity ;; available for writing. This event always triggers for regular files. - (flag $EVENTTYPE_FD_WRITE) + $EVENTTYPE_FD_WRITE ) ) diff --git a/proposals/random/phases/unstable/witx/typenames.witx b/proposals/random/phases/unstable/witx/typenames.witx index c265e1bb6..68f2ef15f 100644 --- a/proposals/random/phases/unstable/witx/typenames.witx +++ b/proposals/random/phases/unstable/witx/typenames.witx @@ -481,16 +481,16 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t - (flags u8 + (enum u8 ;; The time value of clock `subscription_t::u.clock.clock_id` has ;; reached timestamp `subscription_t::u.clock.timeout`. - (flag $EVENTTYPE_CLOCK) + $EVENTTYPE_CLOCK ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data ;; available for reading. This event always triggers for regular files. - (flag $EVENTTYPE_FD_READ) + $EVENTTYPE_FD_READ ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity ;; available for writing. This event always triggers for regular files. - (flag $EVENTTYPE_FD_WRITE) + $EVENTTYPE_FD_WRITE ) ) From 3c3f4405b533c334c4fcea47fdf5cf64a7b1e394 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 09:52:44 -0800 Subject: [PATCH 0249/1772] Make `eventtype_t` an enum rather than a flags. (#133) This matches existing practice, so update the `unstable` and `old` definitions too. --- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 8 ++++---- proposals/filesystem/phases/old/witx/typenames.witx | 8 ++++---- proposals/filesystem/phases/unstable/witx/typenames.witx | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index c6d2ce9e8..1c5babbdd 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -483,16 +483,16 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t - (flags u8 + (enum u8 ;; The time value of clock `subscription_t::u.clock.clock_id` has ;; reached timestamp `subscription_t::u.clock.timeout`. - (flag $EVENTTYPE_CLOCK) + $EVENTTYPE_CLOCK ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data ;; available for reading. This event always triggers for regular files. - (flag $EVENTTYPE_FD_READ) + $EVENTTYPE_FD_READ ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity ;; available for writing. This event always triggers for regular files. - (flag $EVENTTYPE_FD_WRITE) + $EVENTTYPE_FD_WRITE ) ) diff --git a/proposals/filesystem/phases/old/witx/typenames.witx b/proposals/filesystem/phases/old/witx/typenames.witx index c265e1bb6..68f2ef15f 100644 --- a/proposals/filesystem/phases/old/witx/typenames.witx +++ b/proposals/filesystem/phases/old/witx/typenames.witx @@ -481,16 +481,16 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t - (flags u8 + (enum u8 ;; The time value of clock `subscription_t::u.clock.clock_id` has ;; reached timestamp `subscription_t::u.clock.timeout`. - (flag $EVENTTYPE_CLOCK) + $EVENTTYPE_CLOCK ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data ;; available for reading. This event always triggers for regular files. - (flag $EVENTTYPE_FD_READ) + $EVENTTYPE_FD_READ ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity ;; available for writing. This event always triggers for regular files. - (flag $EVENTTYPE_FD_WRITE) + $EVENTTYPE_FD_WRITE ) ) diff --git a/proposals/filesystem/phases/unstable/witx/typenames.witx b/proposals/filesystem/phases/unstable/witx/typenames.witx index c265e1bb6..68f2ef15f 100644 --- a/proposals/filesystem/phases/unstable/witx/typenames.witx +++ b/proposals/filesystem/phases/unstable/witx/typenames.witx @@ -481,16 +481,16 @@ ;; Type of a subscription to an event or its occurrence. (typename $eventtype_t - (flags u8 + (enum u8 ;; The time value of clock `subscription_t::u.clock.clock_id` has ;; reached timestamp `subscription_t::u.clock.timeout`. - (flag $EVENTTYPE_CLOCK) + $EVENTTYPE_CLOCK ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data ;; available for reading. This event always triggers for regular files. - (flag $EVENTTYPE_FD_READ) + $EVENTTYPE_FD_READ ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity ;; available for writing. This event always triggers for regular files. - (flag $EVENTTYPE_FD_WRITE) + $EVENTTYPE_FD_WRITE ) ) From 2695d5c59a8973928dab94e7e52203f59be3a839 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 09:53:30 -0800 Subject: [PATCH 0250/1772] Change the `flags` syntax to be more consistent with `enum`. (#134) Instead of defining `flags` with `(flag $FOO)`, just use `$FOO`, which is more consistent with `enum`. --- .../phases/ephemeral/witx/typenames.witx | 100 +++++++++--------- .../clocks/phases/old/witx/typenames.witx | 100 +++++++++--------- .../phases/unstable/witx/typenames.witx | 100 +++++++++--------- proposals/clocks/tools/witx/src/parser.rs | 6 +- proposals/clocks/tools/witx/src/render.rs | 2 +- 5 files changed, 152 insertions(+), 156 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 1c5babbdd..dae464146 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -201,75 +201,75 @@ ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_DSYNC`. - (flag $RIGHT_FD_DATASYNC) + $RIGHT_FD_DATASYNC ;; The right to invoke `fd_read` and `sock_recv`. ;; ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - (flag $RIGHT_FD_READ) + $RIGHT_FD_READ ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - (flag $RIGHT_FD_SEEK) + $RIGHT_FD_SEEK ;; The right to invoke `fd_fdstat_set_flags`. - (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + $RIGHT_FD_FDSTAT_SET_FLAGS ;; The right to invoke `fd_sync`. ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - (flag $RIGHT_FD_SYNC) + $RIGHT_FD_SYNC ;; The right to invoke `fd_seek` in such a way that the file offset ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;; invoke `fd_tell`. - (flag $RIGHT_FD_TELL) + $RIGHT_FD_TELL ;; The right to invoke `fd_write` and `sock_send`. ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - (flag $RIGHT_FD_WRITE) + $RIGHT_FD_WRITE ;; The right to invoke `fd_advise`. - (flag $RIGHT_FD_ADVISE) + $RIGHT_FD_ADVISE ;; The right to invoke `fd_allocate`. - (flag $RIGHT_FD_ALLOCATE) + $RIGHT_FD_ALLOCATE ;; The right to invoke `path_create_directory`. - (flag $RIGHT_PATH_CREATE_DIRECTORY) + $RIGHT_PATH_CREATE_DIRECTORY ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - (flag $RIGHT_PATH_CREATE_FILE) + $RIGHT_PATH_CREATE_FILE ;; The right to invoke `path_link` with the file descriptor as the ;; source directory. - (flag $RIGHT_PATH_LINK_SOURCE) + $RIGHT_PATH_LINK_SOURCE ;; The right to invoke `path_link` with the file descriptor as the ;; target directory. - (flag $RIGHT_PATH_LINK_TARGET) + $RIGHT_PATH_LINK_TARGET ;; The right to invoke `path_open`. - (flag $RIGHT_PATH_OPEN) + $RIGHT_PATH_OPEN ;; The right to invoke `fd_readdir`. - (flag $RIGHT_FD_READDIR) + $RIGHT_FD_READDIR ;; The right to invoke `path_readlink`. - (flag $RIGHT_PATH_READLINK) + $RIGHT_PATH_READLINK ;; The right to invoke `path_rename` with the file descriptor as the source directory. - (flag $RIGHT_PATH_RENAME_SOURCE) + $RIGHT_PATH_RENAME_SOURCE ;; The right to invoke `path_rename` with the file descriptor as the target directory. - (flag $RIGHT_PATH_RENAME_TARGET) + $RIGHT_PATH_RENAME_TARGET ;; The right to invoke `path_filestat_get`. - (flag $RIGHT_PATH_FILESTAT_GET) + $RIGHT_PATH_FILESTAT_GET ;; The right to change a file's size (there is no `path_filestat_set_size`). ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + $RIGHT_PATH_FILESTAT_SET_SIZE ;; The right to invoke `path_filestat_set_times`. - (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + $RIGHT_PATH_FILESTAT_SET_TIMES ;; The right to invoke `fd_filestat_get`. - (flag $RIGHT_FD_FILESTAT_GET) + $RIGHT_FD_FILESTAT_GET ;; The right to invoke `fd_filestat_set_size`. - (flag $RIGHT_FD_FILESTAT_SET_SIZE) + $RIGHT_FD_FILESTAT_SET_SIZE ;; The right to invoke `fd_filestat_set_times`. - (flag $RIGHT_FD_FILESTAT_SET_TIMES) + $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. - (flag $RIGHT_PATH_SYMLINK) + $RIGHT_PATH_SYMLINK ;; The right to invoke `path_unlink_file`. - (flag $RIGHT_PATH_UNLINK_FILE) + $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. - (flag $RIGHT_PATH_REMOVE_DIRECTORY) + $RIGHT_PATH_REMOVE_DIRECTORY ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - (flag $RIGHT_POLL_FD_READWRITE) + $RIGHT_POLL_FD_READWRITE ;; The right to invoke `sock_shutdown`. - (flag $RIGHT_SOCK_SHUTDOWN) + $RIGHT_SOCK_SHUTDOWN ) ) @@ -383,17 +383,17 @@ (typename $fdflags_t (flags u16 ;; Append mode: Data written to the file is always appended to the file's end. - (flag $FDFLAG_APPEND) + $FDFLAG_APPEND ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - (flag $FDFLAG_DSYNC) + $FDFLAG_DSYNC ;; Non-blocking mode. - (flag $FDFLAG_NONBLOCK) + $FDFLAG_NONBLOCK ;; Synchronized read I/O operations. - (flag $FDFLAG_RSYNC) + $FDFLAG_RSYNC ;; Write according to synchronized I/O file integrity completion. In ;; addition to synchronizing the data stored in the file, the implementation ;; may also synchronously update the file's metadata. - (flag $FDFLAG_SYNC) + $FDFLAG_SYNC ) ) @@ -420,13 +420,13 @@ (typename $fstflags_t (flags u16 ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - (flag $FILESTAT_SET_ATIM) + $FILESTAT_SET_ATIM ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_ATIM_NOW) + $FILESTAT_SET_ATIM_NOW ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - (flag $FILESTAT_SET_MTIM) + $FILESTAT_SET_MTIM ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_MTIM_NOW) + $FILESTAT_SET_MTIM_NOW ) ) @@ -434,7 +434,7 @@ (typename $lookupflags_t (flags u32 ;; As long as the resolved path corresponds to a symbolic link, it is expanded. - (flag $LOOKUP_SYMLINK_FOLLOW) + $LOOKUP_SYMLINK_FOLLOW ) ) @@ -442,13 +442,13 @@ (typename $oflags_t (flags u16 ;; Create file if it does not exist. - (flag $O_CREAT) + $O_CREAT ;; Fail if not a directory. - (flag $O_DIRECTORY) + $O_DIRECTORY ;; Fail if file already exists. - (flag $O_EXCL) + $O_EXCL ;; Truncate file to size 0. - (flag $O_TRUNC) + $O_TRUNC ) ) @@ -501,7 +501,7 @@ (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. - (flag $EVENT_FD_READWRITE_HANGUP) + $EVENT_FD_READWRITE_HANGUP ) ) @@ -547,7 +547,7 @@ ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp ;; provided in `subscription_t::u.clock.timeout` relative to the ;; current time value of clock `subscription_t::u.clock.clock_id.` - (flag $SUBSCRIPTION_CLOCK_ABSTIME) + $SUBSCRIPTION_CLOCK_ABSTIME ) ) @@ -689,9 +689,9 @@ (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. - (flag $SOCK_RECV_PEEK) + $SOCK_RECV_PEEK ;; On byte-stream sockets, block until the full amount of data can be returned. - (flag $SOCK_RECV_WAITALL) + $SOCK_RECV_WAITALL ) ) @@ -699,7 +699,7 @@ (typename $roflags_t (flags u16 ;; Returned by `sock_recv`: Message data has been truncated. - (flag $SOCK_RECV_DATA_TRUNCATED) + $SOCK_RECV_DATA_TRUNCATED ) ) @@ -711,9 +711,9 @@ (typename $sdflags_t (flags u8 ;; Disables further receive operations. - (flag $SHUT_RD) + $SHUT_RD ;; Disables further send operations. - (flag $SHUT_WR) + $SHUT_WR ) ) diff --git a/proposals/clocks/phases/old/witx/typenames.witx b/proposals/clocks/phases/old/witx/typenames.witx index 68f2ef15f..e79f51925 100644 --- a/proposals/clocks/phases/old/witx/typenames.witx +++ b/proposals/clocks/phases/old/witx/typenames.witx @@ -201,75 +201,75 @@ ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_DSYNC`. - (flag $RIGHT_FD_DATASYNC) + $RIGHT_FD_DATASYNC ;; The right to invoke `fd_read` and `sock_recv`. ;; ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - (flag $RIGHT_FD_READ) + $RIGHT_FD_READ ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - (flag $RIGHT_FD_SEEK) + $RIGHT_FD_SEEK ;; The right to invoke `fd_fdstat_set_flags`. - (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + $RIGHT_FD_FDSTAT_SET_FLAGS ;; The right to invoke `fd_sync`. ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - (flag $RIGHT_FD_SYNC) + $RIGHT_FD_SYNC ;; The right to invoke `fd_seek` in such a way that the file offset ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;; invoke `fd_tell`. - (flag $RIGHT_FD_TELL) + $RIGHT_FD_TELL ;; The right to invoke `fd_write` and `sock_send`. ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - (flag $RIGHT_FD_WRITE) + $RIGHT_FD_WRITE ;; The right to invoke `fd_advise`. - (flag $RIGHT_FD_ADVISE) + $RIGHT_FD_ADVISE ;; The right to invoke `fd_allocate`. - (flag $RIGHT_FD_ALLOCATE) + $RIGHT_FD_ALLOCATE ;; The right to invoke `path_create_directory`. - (flag $RIGHT_PATH_CREATE_DIRECTORY) + $RIGHT_PATH_CREATE_DIRECTORY ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - (flag $RIGHT_PATH_CREATE_FILE) + $RIGHT_PATH_CREATE_FILE ;; The right to invoke `path_link` with the file descriptor as the ;; source directory. - (flag $RIGHT_PATH_LINK_SOURCE) + $RIGHT_PATH_LINK_SOURCE ;; The right to invoke `path_link` with the file descriptor as the ;; target directory. - (flag $RIGHT_PATH_LINK_TARGET) + $RIGHT_PATH_LINK_TARGET ;; The right to invoke `path_open`. - (flag $RIGHT_PATH_OPEN) + $RIGHT_PATH_OPEN ;; The right to invoke `fd_readdir`. - (flag $RIGHT_FD_READDIR) + $RIGHT_FD_READDIR ;; The right to invoke `path_readlink`. - (flag $RIGHT_PATH_READLINK) + $RIGHT_PATH_READLINK ;; The right to invoke `path_rename` with the file descriptor as the source directory. - (flag $RIGHT_PATH_RENAME_SOURCE) + $RIGHT_PATH_RENAME_SOURCE ;; The right to invoke `path_rename` with the file descriptor as the target directory. - (flag $RIGHT_PATH_RENAME_TARGET) + $RIGHT_PATH_RENAME_TARGET ;; The right to invoke `path_filestat_get`. - (flag $RIGHT_PATH_FILESTAT_GET) + $RIGHT_PATH_FILESTAT_GET ;; The right to change a file's size (there is no `path_filestat_set_size`). ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + $RIGHT_PATH_FILESTAT_SET_SIZE ;; The right to invoke `path_filestat_set_times`. - (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + $RIGHT_PATH_FILESTAT_SET_TIMES ;; The right to invoke `fd_filestat_get`. - (flag $RIGHT_FD_FILESTAT_GET) + $RIGHT_FD_FILESTAT_GET ;; The right to invoke `fd_filestat_set_size`. - (flag $RIGHT_FD_FILESTAT_SET_SIZE) + $RIGHT_FD_FILESTAT_SET_SIZE ;; The right to invoke `fd_filestat_set_times`. - (flag $RIGHT_FD_FILESTAT_SET_TIMES) + $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. - (flag $RIGHT_PATH_SYMLINK) + $RIGHT_PATH_SYMLINK ;; The right to invoke `path_unlink_file`. - (flag $RIGHT_PATH_UNLINK_FILE) + $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. - (flag $RIGHT_PATH_REMOVE_DIRECTORY) + $RIGHT_PATH_REMOVE_DIRECTORY ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - (flag $RIGHT_POLL_FD_READWRITE) + $RIGHT_POLL_FD_READWRITE ;; The right to invoke `sock_shutdown`. - (flag $RIGHT_SOCK_SHUTDOWN) + $RIGHT_SOCK_SHUTDOWN ) ) @@ -381,17 +381,17 @@ (typename $fdflags_t (flags u16 ;; Append mode: Data written to the file is always appended to the file's end. - (flag $FDFLAG_APPEND) + $FDFLAG_APPEND ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - (flag $FDFLAG_DSYNC) + $FDFLAG_DSYNC ;; Non-blocking mode. - (flag $FDFLAG_NONBLOCK) + $FDFLAG_NONBLOCK ;; Synchronized read I/O operations. - (flag $FDFLAG_RSYNC) + $FDFLAG_RSYNC ;; Write according to synchronized I/O file integrity completion. In ;; addition to synchronizing the data stored in the file, the implementation ;; may also synchronously update the file's metadata. - (flag $FDFLAG_SYNC) + $FDFLAG_SYNC ) ) @@ -418,13 +418,13 @@ (typename $fstflags_t (flags u16 ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - (flag $FILESTAT_SET_ATIM) + $FILESTAT_SET_ATIM ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_ATIM_NOW) + $FILESTAT_SET_ATIM_NOW ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - (flag $FILESTAT_SET_MTIM) + $FILESTAT_SET_MTIM ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_MTIM_NOW) + $FILESTAT_SET_MTIM_NOW ) ) @@ -432,7 +432,7 @@ (typename $lookupflags_t (flags u32 ;; As long as the resolved path corresponds to a symbolic link, it is expanded. - (flag $LOOKUP_SYMLINK_FOLLOW) + $LOOKUP_SYMLINK_FOLLOW ) ) @@ -440,13 +440,13 @@ (typename $oflags_t (flags u16 ;; Create file if it does not exist. - (flag $O_CREAT) + $O_CREAT ;; Fail if not a directory. - (flag $O_DIRECTORY) + $O_DIRECTORY ;; Fail if file already exists. - (flag $O_EXCL) + $O_EXCL ;; Truncate file to size 0. - (flag $O_TRUNC) + $O_TRUNC ) ) @@ -499,7 +499,7 @@ (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. - (flag $EVENT_FD_READWRITE_HANGUP) + $EVENT_FD_READWRITE_HANGUP ) ) @@ -545,7 +545,7 @@ ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp ;; provided in `subscription_t::u.clock.timeout` relative to the ;; current time value of clock `subscription_t::u.clock.clock_id.` - (flag $SUBSCRIPTION_CLOCK_ABSTIME) + $SUBSCRIPTION_CLOCK_ABSTIME ) ) @@ -689,9 +689,9 @@ (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. - (flag $SOCK_RECV_PEEK) + $SOCK_RECV_PEEK ;; On byte-stream sockets, block until the full amount of data can be returned. - (flag $SOCK_RECV_WAITALL) + $SOCK_RECV_WAITALL ) ) @@ -699,7 +699,7 @@ (typename $roflags_t (flags u16 ;; Returned by `sock_recv`: Message data has been truncated. - (flag $SOCK_RECV_DATA_TRUNCATED) + $SOCK_RECV_DATA_TRUNCATED ) ) @@ -711,9 +711,9 @@ (typename $sdflags_t (flags u8 ;; Disables further receive operations. - (flag $SHUT_RD) + $SHUT_RD ;; Disables further send operations. - (flag $SHUT_WR) + $SHUT_WR ) ) diff --git a/proposals/clocks/phases/unstable/witx/typenames.witx b/proposals/clocks/phases/unstable/witx/typenames.witx index 68f2ef15f..e79f51925 100644 --- a/proposals/clocks/phases/unstable/witx/typenames.witx +++ b/proposals/clocks/phases/unstable/witx/typenames.witx @@ -201,75 +201,75 @@ ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_DSYNC`. - (flag $RIGHT_FD_DATASYNC) + $RIGHT_FD_DATASYNC ;; The right to invoke `fd_read` and `sock_recv`. ;; ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - (flag $RIGHT_FD_READ) + $RIGHT_FD_READ ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - (flag $RIGHT_FD_SEEK) + $RIGHT_FD_SEEK ;; The right to invoke `fd_fdstat_set_flags`. - (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + $RIGHT_FD_FDSTAT_SET_FLAGS ;; The right to invoke `fd_sync`. ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - (flag $RIGHT_FD_SYNC) + $RIGHT_FD_SYNC ;; The right to invoke `fd_seek` in such a way that the file offset ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;; invoke `fd_tell`. - (flag $RIGHT_FD_TELL) + $RIGHT_FD_TELL ;; The right to invoke `fd_write` and `sock_send`. ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - (flag $RIGHT_FD_WRITE) + $RIGHT_FD_WRITE ;; The right to invoke `fd_advise`. - (flag $RIGHT_FD_ADVISE) + $RIGHT_FD_ADVISE ;; The right to invoke `fd_allocate`. - (flag $RIGHT_FD_ALLOCATE) + $RIGHT_FD_ALLOCATE ;; The right to invoke `path_create_directory`. - (flag $RIGHT_PATH_CREATE_DIRECTORY) + $RIGHT_PATH_CREATE_DIRECTORY ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - (flag $RIGHT_PATH_CREATE_FILE) + $RIGHT_PATH_CREATE_FILE ;; The right to invoke `path_link` with the file descriptor as the ;; source directory. - (flag $RIGHT_PATH_LINK_SOURCE) + $RIGHT_PATH_LINK_SOURCE ;; The right to invoke `path_link` with the file descriptor as the ;; target directory. - (flag $RIGHT_PATH_LINK_TARGET) + $RIGHT_PATH_LINK_TARGET ;; The right to invoke `path_open`. - (flag $RIGHT_PATH_OPEN) + $RIGHT_PATH_OPEN ;; The right to invoke `fd_readdir`. - (flag $RIGHT_FD_READDIR) + $RIGHT_FD_READDIR ;; The right to invoke `path_readlink`. - (flag $RIGHT_PATH_READLINK) + $RIGHT_PATH_READLINK ;; The right to invoke `path_rename` with the file descriptor as the source directory. - (flag $RIGHT_PATH_RENAME_SOURCE) + $RIGHT_PATH_RENAME_SOURCE ;; The right to invoke `path_rename` with the file descriptor as the target directory. - (flag $RIGHT_PATH_RENAME_TARGET) + $RIGHT_PATH_RENAME_TARGET ;; The right to invoke `path_filestat_get`. - (flag $RIGHT_PATH_FILESTAT_GET) + $RIGHT_PATH_FILESTAT_GET ;; The right to change a file's size (there is no `path_filestat_set_size`). ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + $RIGHT_PATH_FILESTAT_SET_SIZE ;; The right to invoke `path_filestat_set_times`. - (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + $RIGHT_PATH_FILESTAT_SET_TIMES ;; The right to invoke `fd_filestat_get`. - (flag $RIGHT_FD_FILESTAT_GET) + $RIGHT_FD_FILESTAT_GET ;; The right to invoke `fd_filestat_set_size`. - (flag $RIGHT_FD_FILESTAT_SET_SIZE) + $RIGHT_FD_FILESTAT_SET_SIZE ;; The right to invoke `fd_filestat_set_times`. - (flag $RIGHT_FD_FILESTAT_SET_TIMES) + $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. - (flag $RIGHT_PATH_SYMLINK) + $RIGHT_PATH_SYMLINK ;; The right to invoke `path_unlink_file`. - (flag $RIGHT_PATH_UNLINK_FILE) + $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. - (flag $RIGHT_PATH_REMOVE_DIRECTORY) + $RIGHT_PATH_REMOVE_DIRECTORY ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - (flag $RIGHT_POLL_FD_READWRITE) + $RIGHT_POLL_FD_READWRITE ;; The right to invoke `sock_shutdown`. - (flag $RIGHT_SOCK_SHUTDOWN) + $RIGHT_SOCK_SHUTDOWN ) ) @@ -381,17 +381,17 @@ (typename $fdflags_t (flags u16 ;; Append mode: Data written to the file is always appended to the file's end. - (flag $FDFLAG_APPEND) + $FDFLAG_APPEND ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - (flag $FDFLAG_DSYNC) + $FDFLAG_DSYNC ;; Non-blocking mode. - (flag $FDFLAG_NONBLOCK) + $FDFLAG_NONBLOCK ;; Synchronized read I/O operations. - (flag $FDFLAG_RSYNC) + $FDFLAG_RSYNC ;; Write according to synchronized I/O file integrity completion. In ;; addition to synchronizing the data stored in the file, the implementation ;; may also synchronously update the file's metadata. - (flag $FDFLAG_SYNC) + $FDFLAG_SYNC ) ) @@ -418,13 +418,13 @@ (typename $fstflags_t (flags u16 ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - (flag $FILESTAT_SET_ATIM) + $FILESTAT_SET_ATIM ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_ATIM_NOW) + $FILESTAT_SET_ATIM_NOW ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - (flag $FILESTAT_SET_MTIM) + $FILESTAT_SET_MTIM ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_MTIM_NOW) + $FILESTAT_SET_MTIM_NOW ) ) @@ -432,7 +432,7 @@ (typename $lookupflags_t (flags u32 ;; As long as the resolved path corresponds to a symbolic link, it is expanded. - (flag $LOOKUP_SYMLINK_FOLLOW) + $LOOKUP_SYMLINK_FOLLOW ) ) @@ -440,13 +440,13 @@ (typename $oflags_t (flags u16 ;; Create file if it does not exist. - (flag $O_CREAT) + $O_CREAT ;; Fail if not a directory. - (flag $O_DIRECTORY) + $O_DIRECTORY ;; Fail if file already exists. - (flag $O_EXCL) + $O_EXCL ;; Truncate file to size 0. - (flag $O_TRUNC) + $O_TRUNC ) ) @@ -499,7 +499,7 @@ (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. - (flag $EVENT_FD_READWRITE_HANGUP) + $EVENT_FD_READWRITE_HANGUP ) ) @@ -545,7 +545,7 @@ ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp ;; provided in `subscription_t::u.clock.timeout` relative to the ;; current time value of clock `subscription_t::u.clock.clock_id.` - (flag $SUBSCRIPTION_CLOCK_ABSTIME) + $SUBSCRIPTION_CLOCK_ABSTIME ) ) @@ -689,9 +689,9 @@ (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. - (flag $SOCK_RECV_PEEK) + $SOCK_RECV_PEEK ;; On byte-stream sockets, block until the full amount of data can be returned. - (flag $SOCK_RECV_WAITALL) + $SOCK_RECV_WAITALL ) ) @@ -699,7 +699,7 @@ (typename $roflags_t (flags u16 ;; Returned by `sock_recv`: Message data has been truncated. - (flag $SOCK_RECV_DATA_TRUNCATED) + $SOCK_RECV_DATA_TRUNCATED ) ) @@ -711,9 +711,9 @@ (typename $sdflags_t (flags u8 ;; Disables further receive operations. - (flag $SHUT_RD) + $SHUT_RD ;; Disables further send operations. - (flag $SHUT_WR) + $SHUT_WR ) ) diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 8c7a1eecf..9e699267e 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -21,7 +21,6 @@ mod kw { wast::custom_keyword!(f32); wast::custom_keyword!(f64); wast::custom_keyword!(field); - wast::custom_keyword!(flag); wast::custom_keyword!(flags); wast::custom_keyword!(pointer); wast::custom_keyword!(r#enum = "enum"); @@ -307,10 +306,7 @@ impl<'a> Parse<'a> for FlagsSyntax<'a> { let repr = parser.parse()?; let mut flags = Vec::new(); while !parser.is_empty() { - flags.push(parser.parens(|parser| { - parser.parse::()?; - parser.parse() - })?); + flags.push(parser.parse()?); } Ok(FlagsSyntax { repr, flags }) } diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index fa6d86f35..8e23a5fa8 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -150,7 +150,7 @@ impl Render for FlagsDatatype { let flags = self .flags .iter() - .map(|f| SExpr::Vec(vec![SExpr::word("flag"), f.to_sexpr()])) + .map(|f| f.to_sexpr()) .collect::>(); SExpr::Vec([header, flags].concat()) } From 4a5f15e02966cb9a3dbb724e0fc22395a102f132 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 09:53:30 -0800 Subject: [PATCH 0251/1772] Change the `flags` syntax to be more consistent with `enum`. (#134) Instead of defining `flags` with `(flag $FOO)`, just use `$FOO`, which is more consistent with `enum`. --- .../phases/ephemeral/witx/typenames.witx | 100 +++++++++--------- .../random/phases/old/witx/typenames.witx | 100 +++++++++--------- .../phases/unstable/witx/typenames.witx | 100 +++++++++--------- proposals/random/tools/witx/src/parser.rs | 6 +- proposals/random/tools/witx/src/render.rs | 2 +- 5 files changed, 152 insertions(+), 156 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 1c5babbdd..dae464146 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -201,75 +201,75 @@ ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_DSYNC`. - (flag $RIGHT_FD_DATASYNC) + $RIGHT_FD_DATASYNC ;; The right to invoke `fd_read` and `sock_recv`. ;; ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - (flag $RIGHT_FD_READ) + $RIGHT_FD_READ ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - (flag $RIGHT_FD_SEEK) + $RIGHT_FD_SEEK ;; The right to invoke `fd_fdstat_set_flags`. - (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + $RIGHT_FD_FDSTAT_SET_FLAGS ;; The right to invoke `fd_sync`. ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - (flag $RIGHT_FD_SYNC) + $RIGHT_FD_SYNC ;; The right to invoke `fd_seek` in such a way that the file offset ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;; invoke `fd_tell`. - (flag $RIGHT_FD_TELL) + $RIGHT_FD_TELL ;; The right to invoke `fd_write` and `sock_send`. ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - (flag $RIGHT_FD_WRITE) + $RIGHT_FD_WRITE ;; The right to invoke `fd_advise`. - (flag $RIGHT_FD_ADVISE) + $RIGHT_FD_ADVISE ;; The right to invoke `fd_allocate`. - (flag $RIGHT_FD_ALLOCATE) + $RIGHT_FD_ALLOCATE ;; The right to invoke `path_create_directory`. - (flag $RIGHT_PATH_CREATE_DIRECTORY) + $RIGHT_PATH_CREATE_DIRECTORY ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - (flag $RIGHT_PATH_CREATE_FILE) + $RIGHT_PATH_CREATE_FILE ;; The right to invoke `path_link` with the file descriptor as the ;; source directory. - (flag $RIGHT_PATH_LINK_SOURCE) + $RIGHT_PATH_LINK_SOURCE ;; The right to invoke `path_link` with the file descriptor as the ;; target directory. - (flag $RIGHT_PATH_LINK_TARGET) + $RIGHT_PATH_LINK_TARGET ;; The right to invoke `path_open`. - (flag $RIGHT_PATH_OPEN) + $RIGHT_PATH_OPEN ;; The right to invoke `fd_readdir`. - (flag $RIGHT_FD_READDIR) + $RIGHT_FD_READDIR ;; The right to invoke `path_readlink`. - (flag $RIGHT_PATH_READLINK) + $RIGHT_PATH_READLINK ;; The right to invoke `path_rename` with the file descriptor as the source directory. - (flag $RIGHT_PATH_RENAME_SOURCE) + $RIGHT_PATH_RENAME_SOURCE ;; The right to invoke `path_rename` with the file descriptor as the target directory. - (flag $RIGHT_PATH_RENAME_TARGET) + $RIGHT_PATH_RENAME_TARGET ;; The right to invoke `path_filestat_get`. - (flag $RIGHT_PATH_FILESTAT_GET) + $RIGHT_PATH_FILESTAT_GET ;; The right to change a file's size (there is no `path_filestat_set_size`). ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + $RIGHT_PATH_FILESTAT_SET_SIZE ;; The right to invoke `path_filestat_set_times`. - (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + $RIGHT_PATH_FILESTAT_SET_TIMES ;; The right to invoke `fd_filestat_get`. - (flag $RIGHT_FD_FILESTAT_GET) + $RIGHT_FD_FILESTAT_GET ;; The right to invoke `fd_filestat_set_size`. - (flag $RIGHT_FD_FILESTAT_SET_SIZE) + $RIGHT_FD_FILESTAT_SET_SIZE ;; The right to invoke `fd_filestat_set_times`. - (flag $RIGHT_FD_FILESTAT_SET_TIMES) + $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. - (flag $RIGHT_PATH_SYMLINK) + $RIGHT_PATH_SYMLINK ;; The right to invoke `path_unlink_file`. - (flag $RIGHT_PATH_UNLINK_FILE) + $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. - (flag $RIGHT_PATH_REMOVE_DIRECTORY) + $RIGHT_PATH_REMOVE_DIRECTORY ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - (flag $RIGHT_POLL_FD_READWRITE) + $RIGHT_POLL_FD_READWRITE ;; The right to invoke `sock_shutdown`. - (flag $RIGHT_SOCK_SHUTDOWN) + $RIGHT_SOCK_SHUTDOWN ) ) @@ -383,17 +383,17 @@ (typename $fdflags_t (flags u16 ;; Append mode: Data written to the file is always appended to the file's end. - (flag $FDFLAG_APPEND) + $FDFLAG_APPEND ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - (flag $FDFLAG_DSYNC) + $FDFLAG_DSYNC ;; Non-blocking mode. - (flag $FDFLAG_NONBLOCK) + $FDFLAG_NONBLOCK ;; Synchronized read I/O operations. - (flag $FDFLAG_RSYNC) + $FDFLAG_RSYNC ;; Write according to synchronized I/O file integrity completion. In ;; addition to synchronizing the data stored in the file, the implementation ;; may also synchronously update the file's metadata. - (flag $FDFLAG_SYNC) + $FDFLAG_SYNC ) ) @@ -420,13 +420,13 @@ (typename $fstflags_t (flags u16 ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - (flag $FILESTAT_SET_ATIM) + $FILESTAT_SET_ATIM ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_ATIM_NOW) + $FILESTAT_SET_ATIM_NOW ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - (flag $FILESTAT_SET_MTIM) + $FILESTAT_SET_MTIM ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_MTIM_NOW) + $FILESTAT_SET_MTIM_NOW ) ) @@ -434,7 +434,7 @@ (typename $lookupflags_t (flags u32 ;; As long as the resolved path corresponds to a symbolic link, it is expanded. - (flag $LOOKUP_SYMLINK_FOLLOW) + $LOOKUP_SYMLINK_FOLLOW ) ) @@ -442,13 +442,13 @@ (typename $oflags_t (flags u16 ;; Create file if it does not exist. - (flag $O_CREAT) + $O_CREAT ;; Fail if not a directory. - (flag $O_DIRECTORY) + $O_DIRECTORY ;; Fail if file already exists. - (flag $O_EXCL) + $O_EXCL ;; Truncate file to size 0. - (flag $O_TRUNC) + $O_TRUNC ) ) @@ -501,7 +501,7 @@ (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. - (flag $EVENT_FD_READWRITE_HANGUP) + $EVENT_FD_READWRITE_HANGUP ) ) @@ -547,7 +547,7 @@ ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp ;; provided in `subscription_t::u.clock.timeout` relative to the ;; current time value of clock `subscription_t::u.clock.clock_id.` - (flag $SUBSCRIPTION_CLOCK_ABSTIME) + $SUBSCRIPTION_CLOCK_ABSTIME ) ) @@ -689,9 +689,9 @@ (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. - (flag $SOCK_RECV_PEEK) + $SOCK_RECV_PEEK ;; On byte-stream sockets, block until the full amount of data can be returned. - (flag $SOCK_RECV_WAITALL) + $SOCK_RECV_WAITALL ) ) @@ -699,7 +699,7 @@ (typename $roflags_t (flags u16 ;; Returned by `sock_recv`: Message data has been truncated. - (flag $SOCK_RECV_DATA_TRUNCATED) + $SOCK_RECV_DATA_TRUNCATED ) ) @@ -711,9 +711,9 @@ (typename $sdflags_t (flags u8 ;; Disables further receive operations. - (flag $SHUT_RD) + $SHUT_RD ;; Disables further send operations. - (flag $SHUT_WR) + $SHUT_WR ) ) diff --git a/proposals/random/phases/old/witx/typenames.witx b/proposals/random/phases/old/witx/typenames.witx index 68f2ef15f..e79f51925 100644 --- a/proposals/random/phases/old/witx/typenames.witx +++ b/proposals/random/phases/old/witx/typenames.witx @@ -201,75 +201,75 @@ ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_DSYNC`. - (flag $RIGHT_FD_DATASYNC) + $RIGHT_FD_DATASYNC ;; The right to invoke `fd_read` and `sock_recv`. ;; ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - (flag $RIGHT_FD_READ) + $RIGHT_FD_READ ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - (flag $RIGHT_FD_SEEK) + $RIGHT_FD_SEEK ;; The right to invoke `fd_fdstat_set_flags`. - (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + $RIGHT_FD_FDSTAT_SET_FLAGS ;; The right to invoke `fd_sync`. ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - (flag $RIGHT_FD_SYNC) + $RIGHT_FD_SYNC ;; The right to invoke `fd_seek` in such a way that the file offset ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;; invoke `fd_tell`. - (flag $RIGHT_FD_TELL) + $RIGHT_FD_TELL ;; The right to invoke `fd_write` and `sock_send`. ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - (flag $RIGHT_FD_WRITE) + $RIGHT_FD_WRITE ;; The right to invoke `fd_advise`. - (flag $RIGHT_FD_ADVISE) + $RIGHT_FD_ADVISE ;; The right to invoke `fd_allocate`. - (flag $RIGHT_FD_ALLOCATE) + $RIGHT_FD_ALLOCATE ;; The right to invoke `path_create_directory`. - (flag $RIGHT_PATH_CREATE_DIRECTORY) + $RIGHT_PATH_CREATE_DIRECTORY ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - (flag $RIGHT_PATH_CREATE_FILE) + $RIGHT_PATH_CREATE_FILE ;; The right to invoke `path_link` with the file descriptor as the ;; source directory. - (flag $RIGHT_PATH_LINK_SOURCE) + $RIGHT_PATH_LINK_SOURCE ;; The right to invoke `path_link` with the file descriptor as the ;; target directory. - (flag $RIGHT_PATH_LINK_TARGET) + $RIGHT_PATH_LINK_TARGET ;; The right to invoke `path_open`. - (flag $RIGHT_PATH_OPEN) + $RIGHT_PATH_OPEN ;; The right to invoke `fd_readdir`. - (flag $RIGHT_FD_READDIR) + $RIGHT_FD_READDIR ;; The right to invoke `path_readlink`. - (flag $RIGHT_PATH_READLINK) + $RIGHT_PATH_READLINK ;; The right to invoke `path_rename` with the file descriptor as the source directory. - (flag $RIGHT_PATH_RENAME_SOURCE) + $RIGHT_PATH_RENAME_SOURCE ;; The right to invoke `path_rename` with the file descriptor as the target directory. - (flag $RIGHT_PATH_RENAME_TARGET) + $RIGHT_PATH_RENAME_TARGET ;; The right to invoke `path_filestat_get`. - (flag $RIGHT_PATH_FILESTAT_GET) + $RIGHT_PATH_FILESTAT_GET ;; The right to change a file's size (there is no `path_filestat_set_size`). ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + $RIGHT_PATH_FILESTAT_SET_SIZE ;; The right to invoke `path_filestat_set_times`. - (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + $RIGHT_PATH_FILESTAT_SET_TIMES ;; The right to invoke `fd_filestat_get`. - (flag $RIGHT_FD_FILESTAT_GET) + $RIGHT_FD_FILESTAT_GET ;; The right to invoke `fd_filestat_set_size`. - (flag $RIGHT_FD_FILESTAT_SET_SIZE) + $RIGHT_FD_FILESTAT_SET_SIZE ;; The right to invoke `fd_filestat_set_times`. - (flag $RIGHT_FD_FILESTAT_SET_TIMES) + $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. - (flag $RIGHT_PATH_SYMLINK) + $RIGHT_PATH_SYMLINK ;; The right to invoke `path_unlink_file`. - (flag $RIGHT_PATH_UNLINK_FILE) + $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. - (flag $RIGHT_PATH_REMOVE_DIRECTORY) + $RIGHT_PATH_REMOVE_DIRECTORY ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - (flag $RIGHT_POLL_FD_READWRITE) + $RIGHT_POLL_FD_READWRITE ;; The right to invoke `sock_shutdown`. - (flag $RIGHT_SOCK_SHUTDOWN) + $RIGHT_SOCK_SHUTDOWN ) ) @@ -381,17 +381,17 @@ (typename $fdflags_t (flags u16 ;; Append mode: Data written to the file is always appended to the file's end. - (flag $FDFLAG_APPEND) + $FDFLAG_APPEND ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - (flag $FDFLAG_DSYNC) + $FDFLAG_DSYNC ;; Non-blocking mode. - (flag $FDFLAG_NONBLOCK) + $FDFLAG_NONBLOCK ;; Synchronized read I/O operations. - (flag $FDFLAG_RSYNC) + $FDFLAG_RSYNC ;; Write according to synchronized I/O file integrity completion. In ;; addition to synchronizing the data stored in the file, the implementation ;; may also synchronously update the file's metadata. - (flag $FDFLAG_SYNC) + $FDFLAG_SYNC ) ) @@ -418,13 +418,13 @@ (typename $fstflags_t (flags u16 ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - (flag $FILESTAT_SET_ATIM) + $FILESTAT_SET_ATIM ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_ATIM_NOW) + $FILESTAT_SET_ATIM_NOW ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - (flag $FILESTAT_SET_MTIM) + $FILESTAT_SET_MTIM ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_MTIM_NOW) + $FILESTAT_SET_MTIM_NOW ) ) @@ -432,7 +432,7 @@ (typename $lookupflags_t (flags u32 ;; As long as the resolved path corresponds to a symbolic link, it is expanded. - (flag $LOOKUP_SYMLINK_FOLLOW) + $LOOKUP_SYMLINK_FOLLOW ) ) @@ -440,13 +440,13 @@ (typename $oflags_t (flags u16 ;; Create file if it does not exist. - (flag $O_CREAT) + $O_CREAT ;; Fail if not a directory. - (flag $O_DIRECTORY) + $O_DIRECTORY ;; Fail if file already exists. - (flag $O_EXCL) + $O_EXCL ;; Truncate file to size 0. - (flag $O_TRUNC) + $O_TRUNC ) ) @@ -499,7 +499,7 @@ (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. - (flag $EVENT_FD_READWRITE_HANGUP) + $EVENT_FD_READWRITE_HANGUP ) ) @@ -545,7 +545,7 @@ ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp ;; provided in `subscription_t::u.clock.timeout` relative to the ;; current time value of clock `subscription_t::u.clock.clock_id.` - (flag $SUBSCRIPTION_CLOCK_ABSTIME) + $SUBSCRIPTION_CLOCK_ABSTIME ) ) @@ -689,9 +689,9 @@ (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. - (flag $SOCK_RECV_PEEK) + $SOCK_RECV_PEEK ;; On byte-stream sockets, block until the full amount of data can be returned. - (flag $SOCK_RECV_WAITALL) + $SOCK_RECV_WAITALL ) ) @@ -699,7 +699,7 @@ (typename $roflags_t (flags u16 ;; Returned by `sock_recv`: Message data has been truncated. - (flag $SOCK_RECV_DATA_TRUNCATED) + $SOCK_RECV_DATA_TRUNCATED ) ) @@ -711,9 +711,9 @@ (typename $sdflags_t (flags u8 ;; Disables further receive operations. - (flag $SHUT_RD) + $SHUT_RD ;; Disables further send operations. - (flag $SHUT_WR) + $SHUT_WR ) ) diff --git a/proposals/random/phases/unstable/witx/typenames.witx b/proposals/random/phases/unstable/witx/typenames.witx index 68f2ef15f..e79f51925 100644 --- a/proposals/random/phases/unstable/witx/typenames.witx +++ b/proposals/random/phases/unstable/witx/typenames.witx @@ -201,75 +201,75 @@ ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_DSYNC`. - (flag $RIGHT_FD_DATASYNC) + $RIGHT_FD_DATASYNC ;; The right to invoke `fd_read` and `sock_recv`. ;; ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - (flag $RIGHT_FD_READ) + $RIGHT_FD_READ ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - (flag $RIGHT_FD_SEEK) + $RIGHT_FD_SEEK ;; The right to invoke `fd_fdstat_set_flags`. - (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + $RIGHT_FD_FDSTAT_SET_FLAGS ;; The right to invoke `fd_sync`. ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - (flag $RIGHT_FD_SYNC) + $RIGHT_FD_SYNC ;; The right to invoke `fd_seek` in such a way that the file offset ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;; invoke `fd_tell`. - (flag $RIGHT_FD_TELL) + $RIGHT_FD_TELL ;; The right to invoke `fd_write` and `sock_send`. ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - (flag $RIGHT_FD_WRITE) + $RIGHT_FD_WRITE ;; The right to invoke `fd_advise`. - (flag $RIGHT_FD_ADVISE) + $RIGHT_FD_ADVISE ;; The right to invoke `fd_allocate`. - (flag $RIGHT_FD_ALLOCATE) + $RIGHT_FD_ALLOCATE ;; The right to invoke `path_create_directory`. - (flag $RIGHT_PATH_CREATE_DIRECTORY) + $RIGHT_PATH_CREATE_DIRECTORY ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - (flag $RIGHT_PATH_CREATE_FILE) + $RIGHT_PATH_CREATE_FILE ;; The right to invoke `path_link` with the file descriptor as the ;; source directory. - (flag $RIGHT_PATH_LINK_SOURCE) + $RIGHT_PATH_LINK_SOURCE ;; The right to invoke `path_link` with the file descriptor as the ;; target directory. - (flag $RIGHT_PATH_LINK_TARGET) + $RIGHT_PATH_LINK_TARGET ;; The right to invoke `path_open`. - (flag $RIGHT_PATH_OPEN) + $RIGHT_PATH_OPEN ;; The right to invoke `fd_readdir`. - (flag $RIGHT_FD_READDIR) + $RIGHT_FD_READDIR ;; The right to invoke `path_readlink`. - (flag $RIGHT_PATH_READLINK) + $RIGHT_PATH_READLINK ;; The right to invoke `path_rename` with the file descriptor as the source directory. - (flag $RIGHT_PATH_RENAME_SOURCE) + $RIGHT_PATH_RENAME_SOURCE ;; The right to invoke `path_rename` with the file descriptor as the target directory. - (flag $RIGHT_PATH_RENAME_TARGET) + $RIGHT_PATH_RENAME_TARGET ;; The right to invoke `path_filestat_get`. - (flag $RIGHT_PATH_FILESTAT_GET) + $RIGHT_PATH_FILESTAT_GET ;; The right to change a file's size (there is no `path_filestat_set_size`). ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + $RIGHT_PATH_FILESTAT_SET_SIZE ;; The right to invoke `path_filestat_set_times`. - (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + $RIGHT_PATH_FILESTAT_SET_TIMES ;; The right to invoke `fd_filestat_get`. - (flag $RIGHT_FD_FILESTAT_GET) + $RIGHT_FD_FILESTAT_GET ;; The right to invoke `fd_filestat_set_size`. - (flag $RIGHT_FD_FILESTAT_SET_SIZE) + $RIGHT_FD_FILESTAT_SET_SIZE ;; The right to invoke `fd_filestat_set_times`. - (flag $RIGHT_FD_FILESTAT_SET_TIMES) + $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. - (flag $RIGHT_PATH_SYMLINK) + $RIGHT_PATH_SYMLINK ;; The right to invoke `path_unlink_file`. - (flag $RIGHT_PATH_UNLINK_FILE) + $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. - (flag $RIGHT_PATH_REMOVE_DIRECTORY) + $RIGHT_PATH_REMOVE_DIRECTORY ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - (flag $RIGHT_POLL_FD_READWRITE) + $RIGHT_POLL_FD_READWRITE ;; The right to invoke `sock_shutdown`. - (flag $RIGHT_SOCK_SHUTDOWN) + $RIGHT_SOCK_SHUTDOWN ) ) @@ -381,17 +381,17 @@ (typename $fdflags_t (flags u16 ;; Append mode: Data written to the file is always appended to the file's end. - (flag $FDFLAG_APPEND) + $FDFLAG_APPEND ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - (flag $FDFLAG_DSYNC) + $FDFLAG_DSYNC ;; Non-blocking mode. - (flag $FDFLAG_NONBLOCK) + $FDFLAG_NONBLOCK ;; Synchronized read I/O operations. - (flag $FDFLAG_RSYNC) + $FDFLAG_RSYNC ;; Write according to synchronized I/O file integrity completion. In ;; addition to synchronizing the data stored in the file, the implementation ;; may also synchronously update the file's metadata. - (flag $FDFLAG_SYNC) + $FDFLAG_SYNC ) ) @@ -418,13 +418,13 @@ (typename $fstflags_t (flags u16 ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - (flag $FILESTAT_SET_ATIM) + $FILESTAT_SET_ATIM ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_ATIM_NOW) + $FILESTAT_SET_ATIM_NOW ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - (flag $FILESTAT_SET_MTIM) + $FILESTAT_SET_MTIM ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_MTIM_NOW) + $FILESTAT_SET_MTIM_NOW ) ) @@ -432,7 +432,7 @@ (typename $lookupflags_t (flags u32 ;; As long as the resolved path corresponds to a symbolic link, it is expanded. - (flag $LOOKUP_SYMLINK_FOLLOW) + $LOOKUP_SYMLINK_FOLLOW ) ) @@ -440,13 +440,13 @@ (typename $oflags_t (flags u16 ;; Create file if it does not exist. - (flag $O_CREAT) + $O_CREAT ;; Fail if not a directory. - (flag $O_DIRECTORY) + $O_DIRECTORY ;; Fail if file already exists. - (flag $O_EXCL) + $O_EXCL ;; Truncate file to size 0. - (flag $O_TRUNC) + $O_TRUNC ) ) @@ -499,7 +499,7 @@ (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. - (flag $EVENT_FD_READWRITE_HANGUP) + $EVENT_FD_READWRITE_HANGUP ) ) @@ -545,7 +545,7 @@ ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp ;; provided in `subscription_t::u.clock.timeout` relative to the ;; current time value of clock `subscription_t::u.clock.clock_id.` - (flag $SUBSCRIPTION_CLOCK_ABSTIME) + $SUBSCRIPTION_CLOCK_ABSTIME ) ) @@ -689,9 +689,9 @@ (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. - (flag $SOCK_RECV_PEEK) + $SOCK_RECV_PEEK ;; On byte-stream sockets, block until the full amount of data can be returned. - (flag $SOCK_RECV_WAITALL) + $SOCK_RECV_WAITALL ) ) @@ -699,7 +699,7 @@ (typename $roflags_t (flags u16 ;; Returned by `sock_recv`: Message data has been truncated. - (flag $SOCK_RECV_DATA_TRUNCATED) + $SOCK_RECV_DATA_TRUNCATED ) ) @@ -711,9 +711,9 @@ (typename $sdflags_t (flags u8 ;; Disables further receive operations. - (flag $SHUT_RD) + $SHUT_RD ;; Disables further send operations. - (flag $SHUT_WR) + $SHUT_WR ) ) diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 8c7a1eecf..9e699267e 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -21,7 +21,6 @@ mod kw { wast::custom_keyword!(f32); wast::custom_keyword!(f64); wast::custom_keyword!(field); - wast::custom_keyword!(flag); wast::custom_keyword!(flags); wast::custom_keyword!(pointer); wast::custom_keyword!(r#enum = "enum"); @@ -307,10 +306,7 @@ impl<'a> Parse<'a> for FlagsSyntax<'a> { let repr = parser.parse()?; let mut flags = Vec::new(); while !parser.is_empty() { - flags.push(parser.parens(|parser| { - parser.parse::()?; - parser.parse() - })?); + flags.push(parser.parse()?); } Ok(FlagsSyntax { repr, flags }) } diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index fa6d86f35..8e23a5fa8 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -150,7 +150,7 @@ impl Render for FlagsDatatype { let flags = self .flags .iter() - .map(|f| SExpr::Vec(vec![SExpr::word("flag"), f.to_sexpr()])) + .map(|f| f.to_sexpr()) .collect::>(); SExpr::Vec([header, flags].concat()) } From 005812b93e1422ebeb534c39712b4db17775fd8a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 09:53:30 -0800 Subject: [PATCH 0252/1772] Change the `flags` syntax to be more consistent with `enum`. (#134) Instead of defining `flags` with `(flag $FOO)`, just use `$FOO`, which is more consistent with `enum`. --- .../phases/ephemeral/witx/typenames.witx | 100 +++++++++--------- .../filesystem/phases/old/witx/typenames.witx | 100 +++++++++--------- .../phases/unstable/witx/typenames.witx | 100 +++++++++--------- proposals/filesystem/tools/witx/src/parser.rs | 6 +- proposals/filesystem/tools/witx/src/render.rs | 2 +- 5 files changed, 152 insertions(+), 156 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 1c5babbdd..dae464146 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -201,75 +201,75 @@ ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_DSYNC`. - (flag $RIGHT_FD_DATASYNC) + $RIGHT_FD_DATASYNC ;; The right to invoke `fd_read` and `sock_recv`. ;; ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - (flag $RIGHT_FD_READ) + $RIGHT_FD_READ ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - (flag $RIGHT_FD_SEEK) + $RIGHT_FD_SEEK ;; The right to invoke `fd_fdstat_set_flags`. - (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + $RIGHT_FD_FDSTAT_SET_FLAGS ;; The right to invoke `fd_sync`. ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - (flag $RIGHT_FD_SYNC) + $RIGHT_FD_SYNC ;; The right to invoke `fd_seek` in such a way that the file offset ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;; invoke `fd_tell`. - (flag $RIGHT_FD_TELL) + $RIGHT_FD_TELL ;; The right to invoke `fd_write` and `sock_send`. ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - (flag $RIGHT_FD_WRITE) + $RIGHT_FD_WRITE ;; The right to invoke `fd_advise`. - (flag $RIGHT_FD_ADVISE) + $RIGHT_FD_ADVISE ;; The right to invoke `fd_allocate`. - (flag $RIGHT_FD_ALLOCATE) + $RIGHT_FD_ALLOCATE ;; The right to invoke `path_create_directory`. - (flag $RIGHT_PATH_CREATE_DIRECTORY) + $RIGHT_PATH_CREATE_DIRECTORY ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - (flag $RIGHT_PATH_CREATE_FILE) + $RIGHT_PATH_CREATE_FILE ;; The right to invoke `path_link` with the file descriptor as the ;; source directory. - (flag $RIGHT_PATH_LINK_SOURCE) + $RIGHT_PATH_LINK_SOURCE ;; The right to invoke `path_link` with the file descriptor as the ;; target directory. - (flag $RIGHT_PATH_LINK_TARGET) + $RIGHT_PATH_LINK_TARGET ;; The right to invoke `path_open`. - (flag $RIGHT_PATH_OPEN) + $RIGHT_PATH_OPEN ;; The right to invoke `fd_readdir`. - (flag $RIGHT_FD_READDIR) + $RIGHT_FD_READDIR ;; The right to invoke `path_readlink`. - (flag $RIGHT_PATH_READLINK) + $RIGHT_PATH_READLINK ;; The right to invoke `path_rename` with the file descriptor as the source directory. - (flag $RIGHT_PATH_RENAME_SOURCE) + $RIGHT_PATH_RENAME_SOURCE ;; The right to invoke `path_rename` with the file descriptor as the target directory. - (flag $RIGHT_PATH_RENAME_TARGET) + $RIGHT_PATH_RENAME_TARGET ;; The right to invoke `path_filestat_get`. - (flag $RIGHT_PATH_FILESTAT_GET) + $RIGHT_PATH_FILESTAT_GET ;; The right to change a file's size (there is no `path_filestat_set_size`). ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + $RIGHT_PATH_FILESTAT_SET_SIZE ;; The right to invoke `path_filestat_set_times`. - (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + $RIGHT_PATH_FILESTAT_SET_TIMES ;; The right to invoke `fd_filestat_get`. - (flag $RIGHT_FD_FILESTAT_GET) + $RIGHT_FD_FILESTAT_GET ;; The right to invoke `fd_filestat_set_size`. - (flag $RIGHT_FD_FILESTAT_SET_SIZE) + $RIGHT_FD_FILESTAT_SET_SIZE ;; The right to invoke `fd_filestat_set_times`. - (flag $RIGHT_FD_FILESTAT_SET_TIMES) + $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. - (flag $RIGHT_PATH_SYMLINK) + $RIGHT_PATH_SYMLINK ;; The right to invoke `path_unlink_file`. - (flag $RIGHT_PATH_UNLINK_FILE) + $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. - (flag $RIGHT_PATH_REMOVE_DIRECTORY) + $RIGHT_PATH_REMOVE_DIRECTORY ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - (flag $RIGHT_POLL_FD_READWRITE) + $RIGHT_POLL_FD_READWRITE ;; The right to invoke `sock_shutdown`. - (flag $RIGHT_SOCK_SHUTDOWN) + $RIGHT_SOCK_SHUTDOWN ) ) @@ -383,17 +383,17 @@ (typename $fdflags_t (flags u16 ;; Append mode: Data written to the file is always appended to the file's end. - (flag $FDFLAG_APPEND) + $FDFLAG_APPEND ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - (flag $FDFLAG_DSYNC) + $FDFLAG_DSYNC ;; Non-blocking mode. - (flag $FDFLAG_NONBLOCK) + $FDFLAG_NONBLOCK ;; Synchronized read I/O operations. - (flag $FDFLAG_RSYNC) + $FDFLAG_RSYNC ;; Write according to synchronized I/O file integrity completion. In ;; addition to synchronizing the data stored in the file, the implementation ;; may also synchronously update the file's metadata. - (flag $FDFLAG_SYNC) + $FDFLAG_SYNC ) ) @@ -420,13 +420,13 @@ (typename $fstflags_t (flags u16 ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - (flag $FILESTAT_SET_ATIM) + $FILESTAT_SET_ATIM ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_ATIM_NOW) + $FILESTAT_SET_ATIM_NOW ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - (flag $FILESTAT_SET_MTIM) + $FILESTAT_SET_MTIM ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_MTIM_NOW) + $FILESTAT_SET_MTIM_NOW ) ) @@ -434,7 +434,7 @@ (typename $lookupflags_t (flags u32 ;; As long as the resolved path corresponds to a symbolic link, it is expanded. - (flag $LOOKUP_SYMLINK_FOLLOW) + $LOOKUP_SYMLINK_FOLLOW ) ) @@ -442,13 +442,13 @@ (typename $oflags_t (flags u16 ;; Create file if it does not exist. - (flag $O_CREAT) + $O_CREAT ;; Fail if not a directory. - (flag $O_DIRECTORY) + $O_DIRECTORY ;; Fail if file already exists. - (flag $O_EXCL) + $O_EXCL ;; Truncate file to size 0. - (flag $O_TRUNC) + $O_TRUNC ) ) @@ -501,7 +501,7 @@ (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. - (flag $EVENT_FD_READWRITE_HANGUP) + $EVENT_FD_READWRITE_HANGUP ) ) @@ -547,7 +547,7 @@ ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp ;; provided in `subscription_t::u.clock.timeout` relative to the ;; current time value of clock `subscription_t::u.clock.clock_id.` - (flag $SUBSCRIPTION_CLOCK_ABSTIME) + $SUBSCRIPTION_CLOCK_ABSTIME ) ) @@ -689,9 +689,9 @@ (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. - (flag $SOCK_RECV_PEEK) + $SOCK_RECV_PEEK ;; On byte-stream sockets, block until the full amount of data can be returned. - (flag $SOCK_RECV_WAITALL) + $SOCK_RECV_WAITALL ) ) @@ -699,7 +699,7 @@ (typename $roflags_t (flags u16 ;; Returned by `sock_recv`: Message data has been truncated. - (flag $SOCK_RECV_DATA_TRUNCATED) + $SOCK_RECV_DATA_TRUNCATED ) ) @@ -711,9 +711,9 @@ (typename $sdflags_t (flags u8 ;; Disables further receive operations. - (flag $SHUT_RD) + $SHUT_RD ;; Disables further send operations. - (flag $SHUT_WR) + $SHUT_WR ) ) diff --git a/proposals/filesystem/phases/old/witx/typenames.witx b/proposals/filesystem/phases/old/witx/typenames.witx index 68f2ef15f..e79f51925 100644 --- a/proposals/filesystem/phases/old/witx/typenames.witx +++ b/proposals/filesystem/phases/old/witx/typenames.witx @@ -201,75 +201,75 @@ ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_DSYNC`. - (flag $RIGHT_FD_DATASYNC) + $RIGHT_FD_DATASYNC ;; The right to invoke `fd_read` and `sock_recv`. ;; ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - (flag $RIGHT_FD_READ) + $RIGHT_FD_READ ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - (flag $RIGHT_FD_SEEK) + $RIGHT_FD_SEEK ;; The right to invoke `fd_fdstat_set_flags`. - (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + $RIGHT_FD_FDSTAT_SET_FLAGS ;; The right to invoke `fd_sync`. ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - (flag $RIGHT_FD_SYNC) + $RIGHT_FD_SYNC ;; The right to invoke `fd_seek` in such a way that the file offset ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;; invoke `fd_tell`. - (flag $RIGHT_FD_TELL) + $RIGHT_FD_TELL ;; The right to invoke `fd_write` and `sock_send`. ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - (flag $RIGHT_FD_WRITE) + $RIGHT_FD_WRITE ;; The right to invoke `fd_advise`. - (flag $RIGHT_FD_ADVISE) + $RIGHT_FD_ADVISE ;; The right to invoke `fd_allocate`. - (flag $RIGHT_FD_ALLOCATE) + $RIGHT_FD_ALLOCATE ;; The right to invoke `path_create_directory`. - (flag $RIGHT_PATH_CREATE_DIRECTORY) + $RIGHT_PATH_CREATE_DIRECTORY ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - (flag $RIGHT_PATH_CREATE_FILE) + $RIGHT_PATH_CREATE_FILE ;; The right to invoke `path_link` with the file descriptor as the ;; source directory. - (flag $RIGHT_PATH_LINK_SOURCE) + $RIGHT_PATH_LINK_SOURCE ;; The right to invoke `path_link` with the file descriptor as the ;; target directory. - (flag $RIGHT_PATH_LINK_TARGET) + $RIGHT_PATH_LINK_TARGET ;; The right to invoke `path_open`. - (flag $RIGHT_PATH_OPEN) + $RIGHT_PATH_OPEN ;; The right to invoke `fd_readdir`. - (flag $RIGHT_FD_READDIR) + $RIGHT_FD_READDIR ;; The right to invoke `path_readlink`. - (flag $RIGHT_PATH_READLINK) + $RIGHT_PATH_READLINK ;; The right to invoke `path_rename` with the file descriptor as the source directory. - (flag $RIGHT_PATH_RENAME_SOURCE) + $RIGHT_PATH_RENAME_SOURCE ;; The right to invoke `path_rename` with the file descriptor as the target directory. - (flag $RIGHT_PATH_RENAME_TARGET) + $RIGHT_PATH_RENAME_TARGET ;; The right to invoke `path_filestat_get`. - (flag $RIGHT_PATH_FILESTAT_GET) + $RIGHT_PATH_FILESTAT_GET ;; The right to change a file's size (there is no `path_filestat_set_size`). ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + $RIGHT_PATH_FILESTAT_SET_SIZE ;; The right to invoke `path_filestat_set_times`. - (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + $RIGHT_PATH_FILESTAT_SET_TIMES ;; The right to invoke `fd_filestat_get`. - (flag $RIGHT_FD_FILESTAT_GET) + $RIGHT_FD_FILESTAT_GET ;; The right to invoke `fd_filestat_set_size`. - (flag $RIGHT_FD_FILESTAT_SET_SIZE) + $RIGHT_FD_FILESTAT_SET_SIZE ;; The right to invoke `fd_filestat_set_times`. - (flag $RIGHT_FD_FILESTAT_SET_TIMES) + $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. - (flag $RIGHT_PATH_SYMLINK) + $RIGHT_PATH_SYMLINK ;; The right to invoke `path_unlink_file`. - (flag $RIGHT_PATH_UNLINK_FILE) + $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. - (flag $RIGHT_PATH_REMOVE_DIRECTORY) + $RIGHT_PATH_REMOVE_DIRECTORY ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - (flag $RIGHT_POLL_FD_READWRITE) + $RIGHT_POLL_FD_READWRITE ;; The right to invoke `sock_shutdown`. - (flag $RIGHT_SOCK_SHUTDOWN) + $RIGHT_SOCK_SHUTDOWN ) ) @@ -381,17 +381,17 @@ (typename $fdflags_t (flags u16 ;; Append mode: Data written to the file is always appended to the file's end. - (flag $FDFLAG_APPEND) + $FDFLAG_APPEND ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - (flag $FDFLAG_DSYNC) + $FDFLAG_DSYNC ;; Non-blocking mode. - (flag $FDFLAG_NONBLOCK) + $FDFLAG_NONBLOCK ;; Synchronized read I/O operations. - (flag $FDFLAG_RSYNC) + $FDFLAG_RSYNC ;; Write according to synchronized I/O file integrity completion. In ;; addition to synchronizing the data stored in the file, the implementation ;; may also synchronously update the file's metadata. - (flag $FDFLAG_SYNC) + $FDFLAG_SYNC ) ) @@ -418,13 +418,13 @@ (typename $fstflags_t (flags u16 ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - (flag $FILESTAT_SET_ATIM) + $FILESTAT_SET_ATIM ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_ATIM_NOW) + $FILESTAT_SET_ATIM_NOW ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - (flag $FILESTAT_SET_MTIM) + $FILESTAT_SET_MTIM ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_MTIM_NOW) + $FILESTAT_SET_MTIM_NOW ) ) @@ -432,7 +432,7 @@ (typename $lookupflags_t (flags u32 ;; As long as the resolved path corresponds to a symbolic link, it is expanded. - (flag $LOOKUP_SYMLINK_FOLLOW) + $LOOKUP_SYMLINK_FOLLOW ) ) @@ -440,13 +440,13 @@ (typename $oflags_t (flags u16 ;; Create file if it does not exist. - (flag $O_CREAT) + $O_CREAT ;; Fail if not a directory. - (flag $O_DIRECTORY) + $O_DIRECTORY ;; Fail if file already exists. - (flag $O_EXCL) + $O_EXCL ;; Truncate file to size 0. - (flag $O_TRUNC) + $O_TRUNC ) ) @@ -499,7 +499,7 @@ (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. - (flag $EVENT_FD_READWRITE_HANGUP) + $EVENT_FD_READWRITE_HANGUP ) ) @@ -545,7 +545,7 @@ ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp ;; provided in `subscription_t::u.clock.timeout` relative to the ;; current time value of clock `subscription_t::u.clock.clock_id.` - (flag $SUBSCRIPTION_CLOCK_ABSTIME) + $SUBSCRIPTION_CLOCK_ABSTIME ) ) @@ -689,9 +689,9 @@ (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. - (flag $SOCK_RECV_PEEK) + $SOCK_RECV_PEEK ;; On byte-stream sockets, block until the full amount of data can be returned. - (flag $SOCK_RECV_WAITALL) + $SOCK_RECV_WAITALL ) ) @@ -699,7 +699,7 @@ (typename $roflags_t (flags u16 ;; Returned by `sock_recv`: Message data has been truncated. - (flag $SOCK_RECV_DATA_TRUNCATED) + $SOCK_RECV_DATA_TRUNCATED ) ) @@ -711,9 +711,9 @@ (typename $sdflags_t (flags u8 ;; Disables further receive operations. - (flag $SHUT_RD) + $SHUT_RD ;; Disables further send operations. - (flag $SHUT_WR) + $SHUT_WR ) ) diff --git a/proposals/filesystem/phases/unstable/witx/typenames.witx b/proposals/filesystem/phases/unstable/witx/typenames.witx index 68f2ef15f..e79f51925 100644 --- a/proposals/filesystem/phases/unstable/witx/typenames.witx +++ b/proposals/filesystem/phases/unstable/witx/typenames.witx @@ -201,75 +201,75 @@ ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_DSYNC`. - (flag $RIGHT_FD_DATASYNC) + $RIGHT_FD_DATASYNC ;; The right to invoke `fd_read` and `sock_recv`. ;; ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - (flag $RIGHT_FD_READ) + $RIGHT_FD_READ ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - (flag $RIGHT_FD_SEEK) + $RIGHT_FD_SEEK ;; The right to invoke `fd_fdstat_set_flags`. - (flag $RIGHT_FD_FDSTAT_SET_FLAGS) + $RIGHT_FD_FDSTAT_SET_FLAGS ;; The right to invoke `fd_sync`. ;; ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - (flag $RIGHT_FD_SYNC) + $RIGHT_FD_SYNC ;; The right to invoke `fd_seek` in such a way that the file offset ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;; invoke `fd_tell`. - (flag $RIGHT_FD_TELL) + $RIGHT_FD_TELL ;; The right to invoke `fd_write` and `sock_send`. ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - (flag $RIGHT_FD_WRITE) + $RIGHT_FD_WRITE ;; The right to invoke `fd_advise`. - (flag $RIGHT_FD_ADVISE) + $RIGHT_FD_ADVISE ;; The right to invoke `fd_allocate`. - (flag $RIGHT_FD_ALLOCATE) + $RIGHT_FD_ALLOCATE ;; The right to invoke `path_create_directory`. - (flag $RIGHT_PATH_CREATE_DIRECTORY) + $RIGHT_PATH_CREATE_DIRECTORY ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - (flag $RIGHT_PATH_CREATE_FILE) + $RIGHT_PATH_CREATE_FILE ;; The right to invoke `path_link` with the file descriptor as the ;; source directory. - (flag $RIGHT_PATH_LINK_SOURCE) + $RIGHT_PATH_LINK_SOURCE ;; The right to invoke `path_link` with the file descriptor as the ;; target directory. - (flag $RIGHT_PATH_LINK_TARGET) + $RIGHT_PATH_LINK_TARGET ;; The right to invoke `path_open`. - (flag $RIGHT_PATH_OPEN) + $RIGHT_PATH_OPEN ;; The right to invoke `fd_readdir`. - (flag $RIGHT_FD_READDIR) + $RIGHT_FD_READDIR ;; The right to invoke `path_readlink`. - (flag $RIGHT_PATH_READLINK) + $RIGHT_PATH_READLINK ;; The right to invoke `path_rename` with the file descriptor as the source directory. - (flag $RIGHT_PATH_RENAME_SOURCE) + $RIGHT_PATH_RENAME_SOURCE ;; The right to invoke `path_rename` with the file descriptor as the target directory. - (flag $RIGHT_PATH_RENAME_TARGET) + $RIGHT_PATH_RENAME_TARGET ;; The right to invoke `path_filestat_get`. - (flag $RIGHT_PATH_FILESTAT_GET) + $RIGHT_PATH_FILESTAT_GET ;; The right to change a file's size (there is no `path_filestat_set_size`). ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - (flag $RIGHT_PATH_FILESTAT_SET_SIZE) + $RIGHT_PATH_FILESTAT_SET_SIZE ;; The right to invoke `path_filestat_set_times`. - (flag $RIGHT_PATH_FILESTAT_SET_TIMES) + $RIGHT_PATH_FILESTAT_SET_TIMES ;; The right to invoke `fd_filestat_get`. - (flag $RIGHT_FD_FILESTAT_GET) + $RIGHT_FD_FILESTAT_GET ;; The right to invoke `fd_filestat_set_size`. - (flag $RIGHT_FD_FILESTAT_SET_SIZE) + $RIGHT_FD_FILESTAT_SET_SIZE ;; The right to invoke `fd_filestat_set_times`. - (flag $RIGHT_FD_FILESTAT_SET_TIMES) + $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. - (flag $RIGHT_PATH_SYMLINK) + $RIGHT_PATH_SYMLINK ;; The right to invoke `path_unlink_file`. - (flag $RIGHT_PATH_UNLINK_FILE) + $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. - (flag $RIGHT_PATH_REMOVE_DIRECTORY) + $RIGHT_PATH_REMOVE_DIRECTORY ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - (flag $RIGHT_POLL_FD_READWRITE) + $RIGHT_POLL_FD_READWRITE ;; The right to invoke `sock_shutdown`. - (flag $RIGHT_SOCK_SHUTDOWN) + $RIGHT_SOCK_SHUTDOWN ) ) @@ -381,17 +381,17 @@ (typename $fdflags_t (flags u16 ;; Append mode: Data written to the file is always appended to the file's end. - (flag $FDFLAG_APPEND) + $FDFLAG_APPEND ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - (flag $FDFLAG_DSYNC) + $FDFLAG_DSYNC ;; Non-blocking mode. - (flag $FDFLAG_NONBLOCK) + $FDFLAG_NONBLOCK ;; Synchronized read I/O operations. - (flag $FDFLAG_RSYNC) + $FDFLAG_RSYNC ;; Write according to synchronized I/O file integrity completion. In ;; addition to synchronizing the data stored in the file, the implementation ;; may also synchronously update the file's metadata. - (flag $FDFLAG_SYNC) + $FDFLAG_SYNC ) ) @@ -418,13 +418,13 @@ (typename $fstflags_t (flags u16 ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - (flag $FILESTAT_SET_ATIM) + $FILESTAT_SET_ATIM ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_ATIM_NOW) + $FILESTAT_SET_ATIM_NOW ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - (flag $FILESTAT_SET_MTIM) + $FILESTAT_SET_MTIM ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - (flag $FILESTAT_SET_MTIM_NOW) + $FILESTAT_SET_MTIM_NOW ) ) @@ -432,7 +432,7 @@ (typename $lookupflags_t (flags u32 ;; As long as the resolved path corresponds to a symbolic link, it is expanded. - (flag $LOOKUP_SYMLINK_FOLLOW) + $LOOKUP_SYMLINK_FOLLOW ) ) @@ -440,13 +440,13 @@ (typename $oflags_t (flags u16 ;; Create file if it does not exist. - (flag $O_CREAT) + $O_CREAT ;; Fail if not a directory. - (flag $O_DIRECTORY) + $O_DIRECTORY ;; Fail if file already exists. - (flag $O_EXCL) + $O_EXCL ;; Truncate file to size 0. - (flag $O_TRUNC) + $O_TRUNC ) ) @@ -499,7 +499,7 @@ (typename $eventrwflags_t (flags u16 ;; The peer of this socket has closed or disconnected. - (flag $EVENT_FD_READWRITE_HANGUP) + $EVENT_FD_READWRITE_HANGUP ) ) @@ -545,7 +545,7 @@ ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp ;; provided in `subscription_t::u.clock.timeout` relative to the ;; current time value of clock `subscription_t::u.clock.clock_id.` - (flag $SUBSCRIPTION_CLOCK_ABSTIME) + $SUBSCRIPTION_CLOCK_ABSTIME ) ) @@ -689,9 +689,9 @@ (typename $riflags_t (flags u16 ;; Returns the message without removing it from the socket's receive queue. - (flag $SOCK_RECV_PEEK) + $SOCK_RECV_PEEK ;; On byte-stream sockets, block until the full amount of data can be returned. - (flag $SOCK_RECV_WAITALL) + $SOCK_RECV_WAITALL ) ) @@ -699,7 +699,7 @@ (typename $roflags_t (flags u16 ;; Returned by `sock_recv`: Message data has been truncated. - (flag $SOCK_RECV_DATA_TRUNCATED) + $SOCK_RECV_DATA_TRUNCATED ) ) @@ -711,9 +711,9 @@ (typename $sdflags_t (flags u8 ;; Disables further receive operations. - (flag $SHUT_RD) + $SHUT_RD ;; Disables further send operations. - (flag $SHUT_WR) + $SHUT_WR ) ) diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 8c7a1eecf..9e699267e 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -21,7 +21,6 @@ mod kw { wast::custom_keyword!(f32); wast::custom_keyword!(f64); wast::custom_keyword!(field); - wast::custom_keyword!(flag); wast::custom_keyword!(flags); wast::custom_keyword!(pointer); wast::custom_keyword!(r#enum = "enum"); @@ -307,10 +306,7 @@ impl<'a> Parse<'a> for FlagsSyntax<'a> { let repr = parser.parse()?; let mut flags = Vec::new(); while !parser.is_empty() { - flags.push(parser.parens(|parser| { - parser.parse::()?; - parser.parse() - })?); + flags.push(parser.parse()?); } Ok(FlagsSyntax { repr, flags }) } diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index fa6d86f35..8e23a5fa8 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -150,7 +150,7 @@ impl Render for FlagsDatatype { let flags = self .flags .iter() - .map(|f| SExpr::Vec(vec![SExpr::word("flag"), f.to_sexpr()])) + .map(|f| f.to_sexpr()) .collect::>(); SExpr::Vec([header, flags].concat()) } From 1a32a6cd87a1e207a635f496403be5c887a0e076 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 12:23:48 -0800 Subject: [PATCH 0253/1772] Rename old's documentation file to match its witx file. --- .../old/docs/{wasi_unstable_preview0.md => wasi_unstable.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/clocks/phases/old/docs/{wasi_unstable_preview0.md => wasi_unstable.md} (100%) diff --git a/proposals/clocks/phases/old/docs/wasi_unstable_preview0.md b/proposals/clocks/phases/old/docs/wasi_unstable.md similarity index 100% rename from proposals/clocks/phases/old/docs/wasi_unstable_preview0.md rename to proposals/clocks/phases/old/docs/wasi_unstable.md From 33c89835a3032696d6591a7677e0f4f15ebe6915 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 12:23:48 -0800 Subject: [PATCH 0254/1772] Rename old's documentation file to match its witx file. --- .../old/docs/{wasi_unstable_preview0.md => wasi_unstable.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/random/phases/old/docs/{wasi_unstable_preview0.md => wasi_unstable.md} (100%) diff --git a/proposals/random/phases/old/docs/wasi_unstable_preview0.md b/proposals/random/phases/old/docs/wasi_unstable.md similarity index 100% rename from proposals/random/phases/old/docs/wasi_unstable_preview0.md rename to proposals/random/phases/old/docs/wasi_unstable.md From 446c2cee0014ad6851a6ed86c9306bcc6764a12c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 12:23:48 -0800 Subject: [PATCH 0255/1772] Rename old's documentation file to match its witx file. --- .../old/docs/{wasi_unstable_preview0.md => wasi_unstable.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/filesystem/phases/old/docs/{wasi_unstable_preview0.md => wasi_unstable.md} (100%) diff --git a/proposals/filesystem/phases/old/docs/wasi_unstable_preview0.md b/proposals/filesystem/phases/old/docs/wasi_unstable.md similarity index 100% rename from proposals/filesystem/phases/old/docs/wasi_unstable_preview0.md rename to proposals/filesystem/phases/old/docs/wasi_unstable.md From 29deb89e8a24f843dab06806d33e65a22b15ceb5 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 09:42:12 -0800 Subject: [PATCH 0256/1772] Fix the order for advice and rights enums. This reflects existing practice, so update old and unstable too. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 36 +++++++++---------- .../phases/ephemeral/witx/typenames.witx | 16 ++++----- .../clocks/phases/old/docs/wasi_unstable.md | 36 +++++++++---------- .../clocks/phases/old/witx/typenames.witx | 16 ++++----- .../unstable/docs/wasi_unstable_preview0.md | 36 +++++++++---------- .../phases/unstable/witx/typenames.witx | 16 ++++----- 6 files changed, 78 insertions(+), 78 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md index e7f1eeef0..b51b9a4b2 100644 --- a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -1071,36 +1071,36 @@ Used by [`__wasi_fd_advise()`](#fd_advise). Possible values: -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - - **`__WASI_ADVICE_NORMAL`** The application has no advice to give on its behavior with respect to the specified data. -- **`__WASI_ADVICE_RANDOM`** +- **`__WASI_ADVICE_SEQUENTIAL`** The application expects to access the specified data - in a random order. + sequentially from lower offsets to higher offsets. -- **`__WASI_ADVICE_SEQUENTIAL`** +- **`__WASI_ADVICE_RANDOM`** The application expects to access the specified data - sequentially from lower offsets to higher offsets. + in a random order. - **`__WASI_ADVICE_WILLNEED`** The application expects to access the specified data in the near future. +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + ### `__wasi_ciovec_t` (`struct`) A region of memory for scatter/gather writes. @@ -2001,14 +2001,14 @@ Possible values: The right to invoke [`__wasi_path_symlink()`](#path_symlink). -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - - **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + - **`__WASI_RIGHT_POLL_FD_READWRITE`** If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index dae464146..4271b709d 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -261,10 +261,10 @@ $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY + ;; The right to invoke `path_unlink_file`. + $RIGHT_PATH_UNLINK_FILE ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE @@ -364,18 +364,18 @@ ;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE ;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM ;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE ) ) diff --git a/proposals/clocks/phases/old/docs/wasi_unstable.md b/proposals/clocks/phases/old/docs/wasi_unstable.md index 260fd58b6..4a1540f7d 100644 --- a/proposals/clocks/phases/old/docs/wasi_unstable.md +++ b/proposals/clocks/phases/old/docs/wasi_unstable.md @@ -1063,36 +1063,36 @@ Used by [`__wasi_fd_advise()`](#fd_advise). Possible values: -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - - **`__WASI_ADVICE_NORMAL`** The application has no advice to give on its behavior with respect to the specified data. -- **`__WASI_ADVICE_RANDOM`** +- **`__WASI_ADVICE_SEQUENTIAL`** The application expects to access the specified data - in a random order. + sequentially from lower offsets to higher offsets. -- **`__WASI_ADVICE_SEQUENTIAL`** +- **`__WASI_ADVICE_RANDOM`** The application expects to access the specified data - sequentially from lower offsets to higher offsets. + in a random order. - **`__WASI_ADVICE_WILLNEED`** The application expects to access the specified data in the near future. +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + ### `__wasi_ciovec_t` (`struct`) A region of memory for scatter/gather writes. @@ -1993,14 +1993,14 @@ Possible values: The right to invoke [`__wasi_path_symlink()`](#path_symlink). -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - - **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + - **`__WASI_RIGHT_POLL_FD_READWRITE`** If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to diff --git a/proposals/clocks/phases/old/witx/typenames.witx b/proposals/clocks/phases/old/witx/typenames.witx index e79f51925..c9261f1d9 100644 --- a/proposals/clocks/phases/old/witx/typenames.witx +++ b/proposals/clocks/phases/old/witx/typenames.witx @@ -261,10 +261,10 @@ $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY + ;; The right to invoke `path_unlink_file`. + $RIGHT_PATH_UNLINK_FILE ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE @@ -362,18 +362,18 @@ ;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE ;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM ;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE ) ) diff --git a/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md index 260fd58b6..4a1540f7d 100644 --- a/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md +++ b/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md @@ -1063,36 +1063,36 @@ Used by [`__wasi_fd_advise()`](#fd_advise). Possible values: -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - - **`__WASI_ADVICE_NORMAL`** The application has no advice to give on its behavior with respect to the specified data. -- **`__WASI_ADVICE_RANDOM`** +- **`__WASI_ADVICE_SEQUENTIAL`** The application expects to access the specified data - in a random order. + sequentially from lower offsets to higher offsets. -- **`__WASI_ADVICE_SEQUENTIAL`** +- **`__WASI_ADVICE_RANDOM`** The application expects to access the specified data - sequentially from lower offsets to higher offsets. + in a random order. - **`__WASI_ADVICE_WILLNEED`** The application expects to access the specified data in the near future. +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + ### `__wasi_ciovec_t` (`struct`) A region of memory for scatter/gather writes. @@ -1993,14 +1993,14 @@ Possible values: The right to invoke [`__wasi_path_symlink()`](#path_symlink). -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - - **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + - **`__WASI_RIGHT_POLL_FD_READWRITE`** If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to diff --git a/proposals/clocks/phases/unstable/witx/typenames.witx b/proposals/clocks/phases/unstable/witx/typenames.witx index e79f51925..c9261f1d9 100644 --- a/proposals/clocks/phases/unstable/witx/typenames.witx +++ b/proposals/clocks/phases/unstable/witx/typenames.witx @@ -261,10 +261,10 @@ $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY + ;; The right to invoke `path_unlink_file`. + $RIGHT_PATH_UNLINK_FILE ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE @@ -362,18 +362,18 @@ ;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE ;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM ;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE ) ) From 170aee7e0ad682357aef15284dc6654634af766b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 09:42:12 -0800 Subject: [PATCH 0257/1772] Fix the order for advice and rights enums. This reflects existing practice, so update old and unstable too. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 36 +++++++++---------- .../phases/ephemeral/witx/typenames.witx | 16 ++++----- .../random/phases/old/docs/wasi_unstable.md | 36 +++++++++---------- .../random/phases/old/witx/typenames.witx | 16 ++++----- .../unstable/docs/wasi_unstable_preview0.md | 36 +++++++++---------- .../phases/unstable/witx/typenames.witx | 16 ++++----- 6 files changed, 78 insertions(+), 78 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md index e7f1eeef0..b51b9a4b2 100644 --- a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -1071,36 +1071,36 @@ Used by [`__wasi_fd_advise()`](#fd_advise). Possible values: -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - - **`__WASI_ADVICE_NORMAL`** The application has no advice to give on its behavior with respect to the specified data. -- **`__WASI_ADVICE_RANDOM`** +- **`__WASI_ADVICE_SEQUENTIAL`** The application expects to access the specified data - in a random order. + sequentially from lower offsets to higher offsets. -- **`__WASI_ADVICE_SEQUENTIAL`** +- **`__WASI_ADVICE_RANDOM`** The application expects to access the specified data - sequentially from lower offsets to higher offsets. + in a random order. - **`__WASI_ADVICE_WILLNEED`** The application expects to access the specified data in the near future. +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + ### `__wasi_ciovec_t` (`struct`) A region of memory for scatter/gather writes. @@ -2001,14 +2001,14 @@ Possible values: The right to invoke [`__wasi_path_symlink()`](#path_symlink). -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - - **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + - **`__WASI_RIGHT_POLL_FD_READWRITE`** If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index dae464146..4271b709d 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -261,10 +261,10 @@ $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY + ;; The right to invoke `path_unlink_file`. + $RIGHT_PATH_UNLINK_FILE ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE @@ -364,18 +364,18 @@ ;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE ;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM ;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE ) ) diff --git a/proposals/random/phases/old/docs/wasi_unstable.md b/proposals/random/phases/old/docs/wasi_unstable.md index 260fd58b6..4a1540f7d 100644 --- a/proposals/random/phases/old/docs/wasi_unstable.md +++ b/proposals/random/phases/old/docs/wasi_unstable.md @@ -1063,36 +1063,36 @@ Used by [`__wasi_fd_advise()`](#fd_advise). Possible values: -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - - **`__WASI_ADVICE_NORMAL`** The application has no advice to give on its behavior with respect to the specified data. -- **`__WASI_ADVICE_RANDOM`** +- **`__WASI_ADVICE_SEQUENTIAL`** The application expects to access the specified data - in a random order. + sequentially from lower offsets to higher offsets. -- **`__WASI_ADVICE_SEQUENTIAL`** +- **`__WASI_ADVICE_RANDOM`** The application expects to access the specified data - sequentially from lower offsets to higher offsets. + in a random order. - **`__WASI_ADVICE_WILLNEED`** The application expects to access the specified data in the near future. +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + ### `__wasi_ciovec_t` (`struct`) A region of memory for scatter/gather writes. @@ -1993,14 +1993,14 @@ Possible values: The right to invoke [`__wasi_path_symlink()`](#path_symlink). -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - - **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + - **`__WASI_RIGHT_POLL_FD_READWRITE`** If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to diff --git a/proposals/random/phases/old/witx/typenames.witx b/proposals/random/phases/old/witx/typenames.witx index e79f51925..c9261f1d9 100644 --- a/proposals/random/phases/old/witx/typenames.witx +++ b/proposals/random/phases/old/witx/typenames.witx @@ -261,10 +261,10 @@ $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY + ;; The right to invoke `path_unlink_file`. + $RIGHT_PATH_UNLINK_FILE ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE @@ -362,18 +362,18 @@ ;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE ;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM ;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE ) ) diff --git a/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md index 260fd58b6..4a1540f7d 100644 --- a/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md +++ b/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md @@ -1063,36 +1063,36 @@ Used by [`__wasi_fd_advise()`](#fd_advise). Possible values: -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - - **`__WASI_ADVICE_NORMAL`** The application has no advice to give on its behavior with respect to the specified data. -- **`__WASI_ADVICE_RANDOM`** +- **`__WASI_ADVICE_SEQUENTIAL`** The application expects to access the specified data - in a random order. + sequentially from lower offsets to higher offsets. -- **`__WASI_ADVICE_SEQUENTIAL`** +- **`__WASI_ADVICE_RANDOM`** The application expects to access the specified data - sequentially from lower offsets to higher offsets. + in a random order. - **`__WASI_ADVICE_WILLNEED`** The application expects to access the specified data in the near future. +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + ### `__wasi_ciovec_t` (`struct`) A region of memory for scatter/gather writes. @@ -1993,14 +1993,14 @@ Possible values: The right to invoke [`__wasi_path_symlink()`](#path_symlink). -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - - **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + - **`__WASI_RIGHT_POLL_FD_READWRITE`** If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to diff --git a/proposals/random/phases/unstable/witx/typenames.witx b/proposals/random/phases/unstable/witx/typenames.witx index e79f51925..c9261f1d9 100644 --- a/proposals/random/phases/unstable/witx/typenames.witx +++ b/proposals/random/phases/unstable/witx/typenames.witx @@ -261,10 +261,10 @@ $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY + ;; The right to invoke `path_unlink_file`. + $RIGHT_PATH_UNLINK_FILE ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE @@ -362,18 +362,18 @@ ;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE ;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM ;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE ) ) From fd6660a33b1704df6e69139aca71f3382b901fbf Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 09:42:12 -0800 Subject: [PATCH 0258/1772] Fix the order for advice and rights enums. This reflects existing practice, so update old and unstable too. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 36 +++++++++---------- .../phases/ephemeral/witx/typenames.witx | 16 ++++----- .../phases/old/docs/wasi_unstable.md | 36 +++++++++---------- .../filesystem/phases/old/witx/typenames.witx | 16 ++++----- .../unstable/docs/wasi_unstable_preview0.md | 36 +++++++++---------- .../phases/unstable/witx/typenames.witx | 16 ++++----- 6 files changed, 78 insertions(+), 78 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md index e7f1eeef0..b51b9a4b2 100644 --- a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -1071,36 +1071,36 @@ Used by [`__wasi_fd_advise()`](#fd_advise). Possible values: -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - - **`__WASI_ADVICE_NORMAL`** The application has no advice to give on its behavior with respect to the specified data. -- **`__WASI_ADVICE_RANDOM`** +- **`__WASI_ADVICE_SEQUENTIAL`** The application expects to access the specified data - in a random order. + sequentially from lower offsets to higher offsets. -- **`__WASI_ADVICE_SEQUENTIAL`** +- **`__WASI_ADVICE_RANDOM`** The application expects to access the specified data - sequentially from lower offsets to higher offsets. + in a random order. - **`__WASI_ADVICE_WILLNEED`** The application expects to access the specified data in the near future. +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + ### `__wasi_ciovec_t` (`struct`) A region of memory for scatter/gather writes. @@ -2001,14 +2001,14 @@ Possible values: The right to invoke [`__wasi_path_symlink()`](#path_symlink). -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - - **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + - **`__WASI_RIGHT_POLL_FD_READWRITE`** If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index dae464146..4271b709d 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -261,10 +261,10 @@ $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY + ;; The right to invoke `path_unlink_file`. + $RIGHT_PATH_UNLINK_FILE ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE @@ -364,18 +364,18 @@ ;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE ;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM ;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE ) ) diff --git a/proposals/filesystem/phases/old/docs/wasi_unstable.md b/proposals/filesystem/phases/old/docs/wasi_unstable.md index 260fd58b6..4a1540f7d 100644 --- a/proposals/filesystem/phases/old/docs/wasi_unstable.md +++ b/proposals/filesystem/phases/old/docs/wasi_unstable.md @@ -1063,36 +1063,36 @@ Used by [`__wasi_fd_advise()`](#fd_advise). Possible values: -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - - **`__WASI_ADVICE_NORMAL`** The application has no advice to give on its behavior with respect to the specified data. -- **`__WASI_ADVICE_RANDOM`** +- **`__WASI_ADVICE_SEQUENTIAL`** The application expects to access the specified data - in a random order. + sequentially from lower offsets to higher offsets. -- **`__WASI_ADVICE_SEQUENTIAL`** +- **`__WASI_ADVICE_RANDOM`** The application expects to access the specified data - sequentially from lower offsets to higher offsets. + in a random order. - **`__WASI_ADVICE_WILLNEED`** The application expects to access the specified data in the near future. +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + ### `__wasi_ciovec_t` (`struct`) A region of memory for scatter/gather writes. @@ -1993,14 +1993,14 @@ Possible values: The right to invoke [`__wasi_path_symlink()`](#path_symlink). -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - - **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + - **`__WASI_RIGHT_POLL_FD_READWRITE`** If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to diff --git a/proposals/filesystem/phases/old/witx/typenames.witx b/proposals/filesystem/phases/old/witx/typenames.witx index e79f51925..c9261f1d9 100644 --- a/proposals/filesystem/phases/old/witx/typenames.witx +++ b/proposals/filesystem/phases/old/witx/typenames.witx @@ -261,10 +261,10 @@ $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY + ;; The right to invoke `path_unlink_file`. + $RIGHT_PATH_UNLINK_FILE ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE @@ -362,18 +362,18 @@ ;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE ;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM ;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE ) ) diff --git a/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md index 260fd58b6..4a1540f7d 100644 --- a/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md +++ b/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md @@ -1063,36 +1063,36 @@ Used by [`__wasi_fd_advise()`](#fd_advise). Possible values: -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - - **`__WASI_ADVICE_NORMAL`** The application has no advice to give on its behavior with respect to the specified data. -- **`__WASI_ADVICE_RANDOM`** +- **`__WASI_ADVICE_SEQUENTIAL`** The application expects to access the specified data - in a random order. + sequentially from lower offsets to higher offsets. -- **`__WASI_ADVICE_SEQUENTIAL`** +- **`__WASI_ADVICE_RANDOM`** The application expects to access the specified data - sequentially from lower offsets to higher offsets. + in a random order. - **`__WASI_ADVICE_WILLNEED`** The application expects to access the specified data in the near future. +- **`__WASI_ADVICE_DONTNEED`** + + The application expects that it will not access the + specified data in the near future. + +- **`__WASI_ADVICE_NOREUSE`** + + The application expects to access the specified data + once and then not reuse it thereafter. + ### `__wasi_ciovec_t` (`struct`) A region of memory for scatter/gather writes. @@ -1993,14 +1993,14 @@ Possible values: The right to invoke [`__wasi_path_symlink()`](#path_symlink). -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - - **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). +- **`__WASI_RIGHT_PATH_UNLINK_FILE`** + + The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). + - **`__WASI_RIGHT_POLL_FD_READWRITE`** If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to diff --git a/proposals/filesystem/phases/unstable/witx/typenames.witx b/proposals/filesystem/phases/unstable/witx/typenames.witx index e79f51925..c9261f1d9 100644 --- a/proposals/filesystem/phases/unstable/witx/typenames.witx +++ b/proposals/filesystem/phases/unstable/witx/typenames.witx @@ -261,10 +261,10 @@ $RIGHT_FD_FILESTAT_SET_TIMES ;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE ;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY + ;; The right to invoke `path_unlink_file`. + $RIGHT_PATH_UNLINK_FILE ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE @@ -362,18 +362,18 @@ ;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE ;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL + ;; The application expects to access the specified data in a random order. + $ADVICE_RANDOM ;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED + ;; The application expects that it will not access the specified data in the near future. + $ADVICE_DONTNEED + ;; The application expects to access the specified data once and then not reuse it thereafter. + $ADVICE_NOREUSE ) ) From dd9413ff1048c85bc495757f6d509510283e68a8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 10:04:49 -0800 Subject: [PATCH 0259/1772] Add emphasis in comments, from the original document. --- .../clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx | 4 ++-- proposals/clocks/phases/old/witx/wasi_unstable.witx | 4 ++-- .../clocks/phases/unstable/witx/wasi_unstable_preview0.witx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx index c473a9a9b..54aaa0d11 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -369,8 +369,8 @@ ;; than specified, if and only if those rights do not apply to the type of ;; file being opened. ;; - ;; The base rights are rights that will apply to operations using the file - ;; descriptor itself, while the inheriting rights are rights that apply to + ;; The *base* rights are rights that will apply to operations using the file + ;; descriptor itself, while the *inheriting* rights are rights that apply to ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) diff --git a/proposals/clocks/phases/old/witx/wasi_unstable.witx b/proposals/clocks/phases/old/witx/wasi_unstable.witx index 8b7806dc7..6ce2f03af 100644 --- a/proposals/clocks/phases/old/witx/wasi_unstable.witx +++ b/proposals/clocks/phases/old/witx/wasi_unstable.witx @@ -372,8 +372,8 @@ ;; than specified, if and only if those rights do not apply to the type of ;; file being opened. ;; - ;; The base rights are rights that will apply to operations using the file - ;; descriptor itself, while the inheriting rights are rights that apply to + ;; The *base* rights are rights that will apply to operations using the file + ;; descriptor itself, while the *inheriting* rights are rights that apply to ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) diff --git a/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx index 7b4d1b241..e6c4c67aa 100644 --- a/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx @@ -369,8 +369,8 @@ ;; than specified, if and only if those rights do not apply to the type of ;; file being opened. ;; - ;; The base rights are rights that will apply to operations using the file - ;; descriptor itself, while the inheriting rights are rights that apply to + ;; The *base* rights are rights that will apply to operations using the file + ;; descriptor itself, while the *inheriting* rights are rights that apply to ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) From b13be710062b94c35efd5cc0ee45f10fe6bebb35 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 10:04:49 -0800 Subject: [PATCH 0260/1772] Add emphasis in comments, from the original document. --- .../random/phases/ephemeral/witx/wasi_ephemeral_preview.witx | 4 ++-- proposals/random/phases/old/witx/wasi_unstable.witx | 4 ++-- .../random/phases/unstable/witx/wasi_unstable_preview0.witx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx index c473a9a9b..54aaa0d11 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -369,8 +369,8 @@ ;; than specified, if and only if those rights do not apply to the type of ;; file being opened. ;; - ;; The base rights are rights that will apply to operations using the file - ;; descriptor itself, while the inheriting rights are rights that apply to + ;; The *base* rights are rights that will apply to operations using the file + ;; descriptor itself, while the *inheriting* rights are rights that apply to ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) diff --git a/proposals/random/phases/old/witx/wasi_unstable.witx b/proposals/random/phases/old/witx/wasi_unstable.witx index 8b7806dc7..6ce2f03af 100644 --- a/proposals/random/phases/old/witx/wasi_unstable.witx +++ b/proposals/random/phases/old/witx/wasi_unstable.witx @@ -372,8 +372,8 @@ ;; than specified, if and only if those rights do not apply to the type of ;; file being opened. ;; - ;; The base rights are rights that will apply to operations using the file - ;; descriptor itself, while the inheriting rights are rights that apply to + ;; The *base* rights are rights that will apply to operations using the file + ;; descriptor itself, while the *inheriting* rights are rights that apply to ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) diff --git a/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx index 7b4d1b241..e6c4c67aa 100644 --- a/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx @@ -369,8 +369,8 @@ ;; than specified, if and only if those rights do not apply to the type of ;; file being opened. ;; - ;; The base rights are rights that will apply to operations using the file - ;; descriptor itself, while the inheriting rights are rights that apply to + ;; The *base* rights are rights that will apply to operations using the file + ;; descriptor itself, while the *inheriting* rights are rights that apply to ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) From 4ea45a544754944e1c2d22702bd97da12f042dbe Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 10:04:49 -0800 Subject: [PATCH 0261/1772] Add emphasis in comments, from the original document. --- .../phases/ephemeral/witx/wasi_ephemeral_preview.witx | 4 ++-- proposals/filesystem/phases/old/witx/wasi_unstable.witx | 4 ++-- .../phases/unstable/witx/wasi_unstable_preview0.witx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx index c473a9a9b..54aaa0d11 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -369,8 +369,8 @@ ;; than specified, if and only if those rights do not apply to the type of ;; file being opened. ;; - ;; The base rights are rights that will apply to operations using the file - ;; descriptor itself, while the inheriting rights are rights that apply to + ;; The *base* rights are rights that will apply to operations using the file + ;; descriptor itself, while the *inheriting* rights are rights that apply to ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) diff --git a/proposals/filesystem/phases/old/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/witx/wasi_unstable.witx index 8b7806dc7..6ce2f03af 100644 --- a/proposals/filesystem/phases/old/witx/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/witx/wasi_unstable.witx @@ -372,8 +372,8 @@ ;; than specified, if and only if those rights do not apply to the type of ;; file being opened. ;; - ;; The base rights are rights that will apply to operations using the file - ;; descriptor itself, while the inheriting rights are rights that apply to + ;; The *base* rights are rights that will apply to operations using the file + ;; descriptor itself, while the *inheriting* rights are rights that apply to ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) diff --git a/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx index 7b4d1b241..e6c4c67aa 100644 --- a/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx @@ -369,8 +369,8 @@ ;; than specified, if and only if those rights do not apply to the type of ;; file being opened. ;; - ;; The base rights are rights that will apply to operations using the file - ;; descriptor itself, while the inheriting rights are rights that apply to + ;; The *base* rights are rights that will apply to operations using the file + ;; descriptor itself, while the *inheriting* rights are rights that apply to ;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) From 3126caacc8190c59fb54d22edef11d35030a8309 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 12:27:00 -0800 Subject: [PATCH 0262/1772] Sync the signal constants with existing practice. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 116 +++++++++++------- .../phases/ephemeral/witx/typenames.witx | 91 ++++++++------ .../clocks/phases/old/docs/wasi_unstable.md | 116 +++++++++++------- .../clocks/phases/old/witx/typenames.witx | 91 ++++++++------ .../unstable/docs/wasi_unstable_preview0.md | 116 +++++++++++------- .../phases/unstable/witx/typenames.witx | 91 ++++++++------ 6 files changed, 369 insertions(+), 252 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md index b51b9a4b2..6de15f1d2 100644 --- a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -2065,57 +2065,51 @@ Used by [`__wasi_proc_raise()`](#proc_raise). Possible values: -- **`__WASI_SIGABRT`** +- **`__WASI_SIGHUP`** - Process abort signal. + Hangup. Action: Terminates the process. -- **`__WASI_SIGALRM`** +- **`__WASI_SIGINT`** - Alarm clock. + Terminate interrupt signal. Action: Terminates the process. -- **`__WASI_SIGBUS`** +- **`__WASI_SIGQUIT`** - Access to an undefined portion of a memory object. + Terminal quit signal. Action: Terminates the process. -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** +- **`__WASI_SIGILL`** - Continue executing, if stopped. + Illegal instruction. - Action: Continues executing, if stopped. + Action: Terminates the process. -- **`__WASI_SIGFPE`** +- **`__WASI_SIGTRAP`** - Erroneous arithmetic operation. + Trace/breakpoint trap. Action: Terminates the process. -- **`__WASI_SIGHUP`** +- **`__WASI_SIGABRT`** - Hangup. + Process abort signal. Action: Terminates the process. -- **`__WASI_SIGILL`** +- **`__WASI_SIGBUS`** - Illegal instruction. + Access to an undefined portion of a memory object. Action: Terminates the process. -- **`__WASI_SIGINT`** +- **`__WASI_SIGFPE`** - Terminate interrupt signal. + Erroneous arithmetic operation. Action: Terminates the process. @@ -2125,33 +2119,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGPIPE`** +- **`__WASI_SIGUSR1`** - Write on a pipe with no one to read it. + User-defined signal 1. - Action: Ignored. + Action: Terminates the process. -- **`__WASI_SIGQUIT`** +- **`__WASI_SIGSEGV`** - Terminal quit signal. + Invalid memory reference. Action: Terminates the process. -- **`__WASI_SIGSEGV`** +- **`__WASI_SIGUSR2`** - Invalid memory reference. + User-defined signal 2. Action: Terminates the process. -- **`__WASI_SIGSTOP`** +- **`__WASI_SIGPIPE`** - Stop executing. + Write on a pipe with no one to read it. - Action: Stops executing. + Action: Ignored. -- **`__WASI_SIGSYS`** +- **`__WASI_SIGALRM`** - Bad system call. + Alarm clock. Action: Terminates the process. @@ -2161,11 +2155,23 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGTRAP`** +- **`__WASI_SIGCHLD`** - Trace/breakpoint trap. + Child process terminated, stopped, or continued. - Action: Terminates the process. + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. - **`__WASI_SIGTSTP`** @@ -2191,15 +2197,15 @@ Possible values: Action: Ignored. -- **`__WASI_SIGUSR1`** +- **`__WASI_SIGXCPU`** - User-defined signal 1. + CPU time limit exceeded. Action: Terminates the process. -- **`__WASI_SIGUSR2`** +- **`__WASI_SIGXFSZ`** - User-defined signal 2. + File size limit exceeded. Action: Terminates the process. @@ -2209,15 +2215,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGXCPU`** +- **`__WASI_SIGPROF`** - CPU time limit exceeded. + Profiling timer expired. Action: Terminates the process. -- **`__WASI_SIGXFSZ`** +- **`__WASI_SIGWINCH`** - File size limit exceeded. + Window changed. + + Action: Ignored. + +- **`__WASI_SIGPOLL`** + + I/O possible. + + Action: Terminates the process. + +- **`__WASI_SIGPWR`** + + Power failure. + + Action: Terminates the process. + +- **`__WASI_SIGSYS`** + + Bad system call. Action: Terminates the process. diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 4271b709d..1a45be1fd 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -604,57 +604,63 @@ ;; Signal condition. (typename $signal_t (enum u8 + ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;; so this value is reserved. + $SIGNONE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP ;; Process abort signal. ;; Action: Terminates the process. $SIGABRT - ;; Alarm clock. - ;; Action: Terminates the process. - $SIGALRM ;; Access to an undefined portion of a memory object. ;; Action: Terminates the process. $SIGBUS - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. - $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. - $SIGCONT ;; Erroneous arithmetic operation. ;; Action: Terminates the process. $SIGFPE - ;; Hangup. + ;; Kill. ;; Action: Terminates the process. - $SIGHUP - ;; Illegal instruction. + $SIGKILL + ;; User-defined signal 1. ;; Action: Terminates the process. - $SIGILL - ;; Terminate interrupt signal. + $SIGUSR1 + ;; Invalid memory reference. ;; Action: Terminates the process. - $SIGINT - ;; Kill. + $SIGSEGV + ;; User-defined signal 2. ;; Action: Terminates the process. - $SIGKILL + $SIGUSR2 ;; Write on a pipe with no one to read it. ;; Action: Ignored. $SIGPIPE - ;; Terminal quit signal. + ;; Alarm clock. ;; Action: Terminates the process. - $SIGQUIT - ;; Invalid memory reference. + $SIGALRM + ;; Termination signal. ;; Action: Terminates the process. - $SIGSEGV + $SIGTERM + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT ;; Stop executing. ;; Action: Stops executing. $SIGSTOP - ;; Bad system call. - ;; Action: Terminates the process. - $SIGSYS - ;; Termination signal. - ;; Action: Terminates the process. - $SIGTERM - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. - $SIGTRAP ;; Terminal stop signal. ;; Action: Stops executing. $SIGTSTP @@ -667,21 +673,30 @@ ;; High bandwidth data is available at a socket. ;; Action: Ignored. $SIGURG - ;; User-defined signal 1. + ;; CPU time limit exceeded. ;; Action: Terminates the process. - $SIGUSR1 - ;; User-defined signal 2. + $SIGXCPU + ;; File size limit exceeded. ;; Action: Terminates the process. - $SIGUSR2 + $SIGXFSZ ;; Virtual timer expired. ;; Action: Terminates the process. $SIGVTALRM - ;; CPU time limit exceeded. + ;; Profiling timer expired. ;; Action: Terminates the process. - $SIGXCPU - ;; File size limit exceeded. + $SIGPROF + ;; Window changed. + ;; Action: Ignored. + $SIGWINCH + ;; I/O possible. ;; Action: Terminates the process. - $SIGXFSZ + $SIGPOLL + ;; Power failure. + ;; Action: Terminates the process. + $SIGPWR + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS ) ) diff --git a/proposals/clocks/phases/old/docs/wasi_unstable.md b/proposals/clocks/phases/old/docs/wasi_unstable.md index 4a1540f7d..2464f2342 100644 --- a/proposals/clocks/phases/old/docs/wasi_unstable.md +++ b/proposals/clocks/phases/old/docs/wasi_unstable.md @@ -2057,57 +2057,51 @@ Used by [`__wasi_proc_raise()`](#proc_raise). Possible values: -- **`__WASI_SIGABRT`** +- **`__WASI_SIGHUP`** - Process abort signal. + Hangup. Action: Terminates the process. -- **`__WASI_SIGALRM`** +- **`__WASI_SIGINT`** - Alarm clock. + Terminate interrupt signal. Action: Terminates the process. -- **`__WASI_SIGBUS`** +- **`__WASI_SIGQUIT`** - Access to an undefined portion of a memory object. + Terminal quit signal. Action: Terminates the process. -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** +- **`__WASI_SIGILL`** - Continue executing, if stopped. + Illegal instruction. - Action: Continues executing, if stopped. + Action: Terminates the process. -- **`__WASI_SIGFPE`** +- **`__WASI_SIGTRAP`** - Erroneous arithmetic operation. + Trace/breakpoint trap. Action: Terminates the process. -- **`__WASI_SIGHUP`** +- **`__WASI_SIGABRT`** - Hangup. + Process abort signal. Action: Terminates the process. -- **`__WASI_SIGILL`** +- **`__WASI_SIGBUS`** - Illegal instruction. + Access to an undefined portion of a memory object. Action: Terminates the process. -- **`__WASI_SIGINT`** +- **`__WASI_SIGFPE`** - Terminate interrupt signal. + Erroneous arithmetic operation. Action: Terminates the process. @@ -2117,33 +2111,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGPIPE`** +- **`__WASI_SIGUSR1`** - Write on a pipe with no one to read it. + User-defined signal 1. - Action: Ignored. + Action: Terminates the process. -- **`__WASI_SIGQUIT`** +- **`__WASI_SIGSEGV`** - Terminal quit signal. + Invalid memory reference. Action: Terminates the process. -- **`__WASI_SIGSEGV`** +- **`__WASI_SIGUSR2`** - Invalid memory reference. + User-defined signal 2. Action: Terminates the process. -- **`__WASI_SIGSTOP`** +- **`__WASI_SIGPIPE`** - Stop executing. + Write on a pipe with no one to read it. - Action: Stops executing. + Action: Ignored. -- **`__WASI_SIGSYS`** +- **`__WASI_SIGALRM`** - Bad system call. + Alarm clock. Action: Terminates the process. @@ -2153,11 +2147,23 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGTRAP`** +- **`__WASI_SIGCHLD`** - Trace/breakpoint trap. + Child process terminated, stopped, or continued. - Action: Terminates the process. + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. - **`__WASI_SIGTSTP`** @@ -2183,15 +2189,15 @@ Possible values: Action: Ignored. -- **`__WASI_SIGUSR1`** +- **`__WASI_SIGXCPU`** - User-defined signal 1. + CPU time limit exceeded. Action: Terminates the process. -- **`__WASI_SIGUSR2`** +- **`__WASI_SIGXFSZ`** - User-defined signal 2. + File size limit exceeded. Action: Terminates the process. @@ -2201,15 +2207,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGXCPU`** +- **`__WASI_SIGPROF`** - CPU time limit exceeded. + Profiling timer expired. Action: Terminates the process. -- **`__WASI_SIGXFSZ`** +- **`__WASI_SIGWINCH`** - File size limit exceeded. + Window changed. + + Action: Ignored. + +- **`__WASI_SIGPOLL`** + + I/O possible. + + Action: Terminates the process. + +- **`__WASI_SIGPWR`** + + Power failure. + + Action: Terminates the process. + +- **`__WASI_SIGSYS`** + + Bad system call. Action: Terminates the process. diff --git a/proposals/clocks/phases/old/witx/typenames.witx b/proposals/clocks/phases/old/witx/typenames.witx index c9261f1d9..15b53af51 100644 --- a/proposals/clocks/phases/old/witx/typenames.witx +++ b/proposals/clocks/phases/old/witx/typenames.witx @@ -604,57 +604,63 @@ ;; Signal condition. (typename $signal_t (enum u8 + ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;; so this value is reserved. + $SIGNONE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP ;; Process abort signal. ;; Action: Terminates the process. $SIGABRT - ;; Alarm clock. - ;; Action: Terminates the process. - $SIGALRM ;; Access to an undefined portion of a memory object. ;; Action: Terminates the process. $SIGBUS - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. - $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. - $SIGCONT ;; Erroneous arithmetic operation. ;; Action: Terminates the process. $SIGFPE - ;; Hangup. + ;; Kill. ;; Action: Terminates the process. - $SIGHUP - ;; Illegal instruction. + $SIGKILL + ;; User-defined signal 1. ;; Action: Terminates the process. - $SIGILL - ;; Terminate interrupt signal. + $SIGUSR1 + ;; Invalid memory reference. ;; Action: Terminates the process. - $SIGINT - ;; Kill. + $SIGSEGV + ;; User-defined signal 2. ;; Action: Terminates the process. - $SIGKILL + $SIGUSR2 ;; Write on a pipe with no one to read it. ;; Action: Ignored. $SIGPIPE - ;; Terminal quit signal. + ;; Alarm clock. ;; Action: Terminates the process. - $SIGQUIT - ;; Invalid memory reference. + $SIGALRM + ;; Termination signal. ;; Action: Terminates the process. - $SIGSEGV + $SIGTERM + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT ;; Stop executing. ;; Action: Stops executing. $SIGSTOP - ;; Bad system call. - ;; Action: Terminates the process. - $SIGSYS - ;; Termination signal. - ;; Action: Terminates the process. - $SIGTERM - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. - $SIGTRAP ;; Terminal stop signal. ;; Action: Stops executing. $SIGTSTP @@ -667,21 +673,30 @@ ;; High bandwidth data is available at a socket. ;; Action: Ignored. $SIGURG - ;; User-defined signal 1. + ;; CPU time limit exceeded. ;; Action: Terminates the process. - $SIGUSR1 - ;; User-defined signal 2. + $SIGXCPU + ;; File size limit exceeded. ;; Action: Terminates the process. - $SIGUSR2 + $SIGXFSZ ;; Virtual timer expired. ;; Action: Terminates the process. $SIGVTALRM - ;; CPU time limit exceeded. + ;; Profiling timer expired. ;; Action: Terminates the process. - $SIGXCPU - ;; File size limit exceeded. + $SIGPROF + ;; Window changed. + ;; Action: Ignored. + $SIGWINCH + ;; I/O possible. ;; Action: Terminates the process. - $SIGXFSZ + $SIGPOLL + ;; Power failure. + ;; Action: Terminates the process. + $SIGPWR + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS ) ) diff --git a/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md index 4a1540f7d..2464f2342 100644 --- a/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md +++ b/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md @@ -2057,57 +2057,51 @@ Used by [`__wasi_proc_raise()`](#proc_raise). Possible values: -- **`__WASI_SIGABRT`** +- **`__WASI_SIGHUP`** - Process abort signal. + Hangup. Action: Terminates the process. -- **`__WASI_SIGALRM`** +- **`__WASI_SIGINT`** - Alarm clock. + Terminate interrupt signal. Action: Terminates the process. -- **`__WASI_SIGBUS`** +- **`__WASI_SIGQUIT`** - Access to an undefined portion of a memory object. + Terminal quit signal. Action: Terminates the process. -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** +- **`__WASI_SIGILL`** - Continue executing, if stopped. + Illegal instruction. - Action: Continues executing, if stopped. + Action: Terminates the process. -- **`__WASI_SIGFPE`** +- **`__WASI_SIGTRAP`** - Erroneous arithmetic operation. + Trace/breakpoint trap. Action: Terminates the process. -- **`__WASI_SIGHUP`** +- **`__WASI_SIGABRT`** - Hangup. + Process abort signal. Action: Terminates the process. -- **`__WASI_SIGILL`** +- **`__WASI_SIGBUS`** - Illegal instruction. + Access to an undefined portion of a memory object. Action: Terminates the process. -- **`__WASI_SIGINT`** +- **`__WASI_SIGFPE`** - Terminate interrupt signal. + Erroneous arithmetic operation. Action: Terminates the process. @@ -2117,33 +2111,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGPIPE`** +- **`__WASI_SIGUSR1`** - Write on a pipe with no one to read it. + User-defined signal 1. - Action: Ignored. + Action: Terminates the process. -- **`__WASI_SIGQUIT`** +- **`__WASI_SIGSEGV`** - Terminal quit signal. + Invalid memory reference. Action: Terminates the process. -- **`__WASI_SIGSEGV`** +- **`__WASI_SIGUSR2`** - Invalid memory reference. + User-defined signal 2. Action: Terminates the process. -- **`__WASI_SIGSTOP`** +- **`__WASI_SIGPIPE`** - Stop executing. + Write on a pipe with no one to read it. - Action: Stops executing. + Action: Ignored. -- **`__WASI_SIGSYS`** +- **`__WASI_SIGALRM`** - Bad system call. + Alarm clock. Action: Terminates the process. @@ -2153,11 +2147,23 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGTRAP`** +- **`__WASI_SIGCHLD`** - Trace/breakpoint trap. + Child process terminated, stopped, or continued. - Action: Terminates the process. + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. - **`__WASI_SIGTSTP`** @@ -2183,15 +2189,15 @@ Possible values: Action: Ignored. -- **`__WASI_SIGUSR1`** +- **`__WASI_SIGXCPU`** - User-defined signal 1. + CPU time limit exceeded. Action: Terminates the process. -- **`__WASI_SIGUSR2`** +- **`__WASI_SIGXFSZ`** - User-defined signal 2. + File size limit exceeded. Action: Terminates the process. @@ -2201,15 +2207,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGXCPU`** +- **`__WASI_SIGPROF`** - CPU time limit exceeded. + Profiling timer expired. Action: Terminates the process. -- **`__WASI_SIGXFSZ`** +- **`__WASI_SIGWINCH`** - File size limit exceeded. + Window changed. + + Action: Ignored. + +- **`__WASI_SIGPOLL`** + + I/O possible. + + Action: Terminates the process. + +- **`__WASI_SIGPWR`** + + Power failure. + + Action: Terminates the process. + +- **`__WASI_SIGSYS`** + + Bad system call. Action: Terminates the process. diff --git a/proposals/clocks/phases/unstable/witx/typenames.witx b/proposals/clocks/phases/unstable/witx/typenames.witx index c9261f1d9..15b53af51 100644 --- a/proposals/clocks/phases/unstable/witx/typenames.witx +++ b/proposals/clocks/phases/unstable/witx/typenames.witx @@ -604,57 +604,63 @@ ;; Signal condition. (typename $signal_t (enum u8 + ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;; so this value is reserved. + $SIGNONE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP ;; Process abort signal. ;; Action: Terminates the process. $SIGABRT - ;; Alarm clock. - ;; Action: Terminates the process. - $SIGALRM ;; Access to an undefined portion of a memory object. ;; Action: Terminates the process. $SIGBUS - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. - $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. - $SIGCONT ;; Erroneous arithmetic operation. ;; Action: Terminates the process. $SIGFPE - ;; Hangup. + ;; Kill. ;; Action: Terminates the process. - $SIGHUP - ;; Illegal instruction. + $SIGKILL + ;; User-defined signal 1. ;; Action: Terminates the process. - $SIGILL - ;; Terminate interrupt signal. + $SIGUSR1 + ;; Invalid memory reference. ;; Action: Terminates the process. - $SIGINT - ;; Kill. + $SIGSEGV + ;; User-defined signal 2. ;; Action: Terminates the process. - $SIGKILL + $SIGUSR2 ;; Write on a pipe with no one to read it. ;; Action: Ignored. $SIGPIPE - ;; Terminal quit signal. + ;; Alarm clock. ;; Action: Terminates the process. - $SIGQUIT - ;; Invalid memory reference. + $SIGALRM + ;; Termination signal. ;; Action: Terminates the process. - $SIGSEGV + $SIGTERM + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT ;; Stop executing. ;; Action: Stops executing. $SIGSTOP - ;; Bad system call. - ;; Action: Terminates the process. - $SIGSYS - ;; Termination signal. - ;; Action: Terminates the process. - $SIGTERM - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. - $SIGTRAP ;; Terminal stop signal. ;; Action: Stops executing. $SIGTSTP @@ -667,21 +673,30 @@ ;; High bandwidth data is available at a socket. ;; Action: Ignored. $SIGURG - ;; User-defined signal 1. + ;; CPU time limit exceeded. ;; Action: Terminates the process. - $SIGUSR1 - ;; User-defined signal 2. + $SIGXCPU + ;; File size limit exceeded. ;; Action: Terminates the process. - $SIGUSR2 + $SIGXFSZ ;; Virtual timer expired. ;; Action: Terminates the process. $SIGVTALRM - ;; CPU time limit exceeded. + ;; Profiling timer expired. ;; Action: Terminates the process. - $SIGXCPU - ;; File size limit exceeded. + $SIGPROF + ;; Window changed. + ;; Action: Ignored. + $SIGWINCH + ;; I/O possible. ;; Action: Terminates the process. - $SIGXFSZ + $SIGPOLL + ;; Power failure. + ;; Action: Terminates the process. + $SIGPWR + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS ) ) From 4329a695442bc1806638b6c217299336fe524ccd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 12:27:00 -0800 Subject: [PATCH 0263/1772] Sync the signal constants with existing practice. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 116 +++++++++++------- .../phases/ephemeral/witx/typenames.witx | 91 ++++++++------ .../random/phases/old/docs/wasi_unstable.md | 116 +++++++++++------- .../random/phases/old/witx/typenames.witx | 91 ++++++++------ .../unstable/docs/wasi_unstable_preview0.md | 116 +++++++++++------- .../phases/unstable/witx/typenames.witx | 91 ++++++++------ 6 files changed, 369 insertions(+), 252 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md index b51b9a4b2..6de15f1d2 100644 --- a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -2065,57 +2065,51 @@ Used by [`__wasi_proc_raise()`](#proc_raise). Possible values: -- **`__WASI_SIGABRT`** +- **`__WASI_SIGHUP`** - Process abort signal. + Hangup. Action: Terminates the process. -- **`__WASI_SIGALRM`** +- **`__WASI_SIGINT`** - Alarm clock. + Terminate interrupt signal. Action: Terminates the process. -- **`__WASI_SIGBUS`** +- **`__WASI_SIGQUIT`** - Access to an undefined portion of a memory object. + Terminal quit signal. Action: Terminates the process. -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** +- **`__WASI_SIGILL`** - Continue executing, if stopped. + Illegal instruction. - Action: Continues executing, if stopped. + Action: Terminates the process. -- **`__WASI_SIGFPE`** +- **`__WASI_SIGTRAP`** - Erroneous arithmetic operation. + Trace/breakpoint trap. Action: Terminates the process. -- **`__WASI_SIGHUP`** +- **`__WASI_SIGABRT`** - Hangup. + Process abort signal. Action: Terminates the process. -- **`__WASI_SIGILL`** +- **`__WASI_SIGBUS`** - Illegal instruction. + Access to an undefined portion of a memory object. Action: Terminates the process. -- **`__WASI_SIGINT`** +- **`__WASI_SIGFPE`** - Terminate interrupt signal. + Erroneous arithmetic operation. Action: Terminates the process. @@ -2125,33 +2119,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGPIPE`** +- **`__WASI_SIGUSR1`** - Write on a pipe with no one to read it. + User-defined signal 1. - Action: Ignored. + Action: Terminates the process. -- **`__WASI_SIGQUIT`** +- **`__WASI_SIGSEGV`** - Terminal quit signal. + Invalid memory reference. Action: Terminates the process. -- **`__WASI_SIGSEGV`** +- **`__WASI_SIGUSR2`** - Invalid memory reference. + User-defined signal 2. Action: Terminates the process. -- **`__WASI_SIGSTOP`** +- **`__WASI_SIGPIPE`** - Stop executing. + Write on a pipe with no one to read it. - Action: Stops executing. + Action: Ignored. -- **`__WASI_SIGSYS`** +- **`__WASI_SIGALRM`** - Bad system call. + Alarm clock. Action: Terminates the process. @@ -2161,11 +2155,23 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGTRAP`** +- **`__WASI_SIGCHLD`** - Trace/breakpoint trap. + Child process terminated, stopped, or continued. - Action: Terminates the process. + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. - **`__WASI_SIGTSTP`** @@ -2191,15 +2197,15 @@ Possible values: Action: Ignored. -- **`__WASI_SIGUSR1`** +- **`__WASI_SIGXCPU`** - User-defined signal 1. + CPU time limit exceeded. Action: Terminates the process. -- **`__WASI_SIGUSR2`** +- **`__WASI_SIGXFSZ`** - User-defined signal 2. + File size limit exceeded. Action: Terminates the process. @@ -2209,15 +2215,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGXCPU`** +- **`__WASI_SIGPROF`** - CPU time limit exceeded. + Profiling timer expired. Action: Terminates the process. -- **`__WASI_SIGXFSZ`** +- **`__WASI_SIGWINCH`** - File size limit exceeded. + Window changed. + + Action: Ignored. + +- **`__WASI_SIGPOLL`** + + I/O possible. + + Action: Terminates the process. + +- **`__WASI_SIGPWR`** + + Power failure. + + Action: Terminates the process. + +- **`__WASI_SIGSYS`** + + Bad system call. Action: Terminates the process. diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 4271b709d..1a45be1fd 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -604,57 +604,63 @@ ;; Signal condition. (typename $signal_t (enum u8 + ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;; so this value is reserved. + $SIGNONE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP ;; Process abort signal. ;; Action: Terminates the process. $SIGABRT - ;; Alarm clock. - ;; Action: Terminates the process. - $SIGALRM ;; Access to an undefined portion of a memory object. ;; Action: Terminates the process. $SIGBUS - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. - $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. - $SIGCONT ;; Erroneous arithmetic operation. ;; Action: Terminates the process. $SIGFPE - ;; Hangup. + ;; Kill. ;; Action: Terminates the process. - $SIGHUP - ;; Illegal instruction. + $SIGKILL + ;; User-defined signal 1. ;; Action: Terminates the process. - $SIGILL - ;; Terminate interrupt signal. + $SIGUSR1 + ;; Invalid memory reference. ;; Action: Terminates the process. - $SIGINT - ;; Kill. + $SIGSEGV + ;; User-defined signal 2. ;; Action: Terminates the process. - $SIGKILL + $SIGUSR2 ;; Write on a pipe with no one to read it. ;; Action: Ignored. $SIGPIPE - ;; Terminal quit signal. + ;; Alarm clock. ;; Action: Terminates the process. - $SIGQUIT - ;; Invalid memory reference. + $SIGALRM + ;; Termination signal. ;; Action: Terminates the process. - $SIGSEGV + $SIGTERM + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT ;; Stop executing. ;; Action: Stops executing. $SIGSTOP - ;; Bad system call. - ;; Action: Terminates the process. - $SIGSYS - ;; Termination signal. - ;; Action: Terminates the process. - $SIGTERM - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. - $SIGTRAP ;; Terminal stop signal. ;; Action: Stops executing. $SIGTSTP @@ -667,21 +673,30 @@ ;; High bandwidth data is available at a socket. ;; Action: Ignored. $SIGURG - ;; User-defined signal 1. + ;; CPU time limit exceeded. ;; Action: Terminates the process. - $SIGUSR1 - ;; User-defined signal 2. + $SIGXCPU + ;; File size limit exceeded. ;; Action: Terminates the process. - $SIGUSR2 + $SIGXFSZ ;; Virtual timer expired. ;; Action: Terminates the process. $SIGVTALRM - ;; CPU time limit exceeded. + ;; Profiling timer expired. ;; Action: Terminates the process. - $SIGXCPU - ;; File size limit exceeded. + $SIGPROF + ;; Window changed. + ;; Action: Ignored. + $SIGWINCH + ;; I/O possible. ;; Action: Terminates the process. - $SIGXFSZ + $SIGPOLL + ;; Power failure. + ;; Action: Terminates the process. + $SIGPWR + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS ) ) diff --git a/proposals/random/phases/old/docs/wasi_unstable.md b/proposals/random/phases/old/docs/wasi_unstable.md index 4a1540f7d..2464f2342 100644 --- a/proposals/random/phases/old/docs/wasi_unstable.md +++ b/proposals/random/phases/old/docs/wasi_unstable.md @@ -2057,57 +2057,51 @@ Used by [`__wasi_proc_raise()`](#proc_raise). Possible values: -- **`__WASI_SIGABRT`** +- **`__WASI_SIGHUP`** - Process abort signal. + Hangup. Action: Terminates the process. -- **`__WASI_SIGALRM`** +- **`__WASI_SIGINT`** - Alarm clock. + Terminate interrupt signal. Action: Terminates the process. -- **`__WASI_SIGBUS`** +- **`__WASI_SIGQUIT`** - Access to an undefined portion of a memory object. + Terminal quit signal. Action: Terminates the process. -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** +- **`__WASI_SIGILL`** - Continue executing, if stopped. + Illegal instruction. - Action: Continues executing, if stopped. + Action: Terminates the process. -- **`__WASI_SIGFPE`** +- **`__WASI_SIGTRAP`** - Erroneous arithmetic operation. + Trace/breakpoint trap. Action: Terminates the process. -- **`__WASI_SIGHUP`** +- **`__WASI_SIGABRT`** - Hangup. + Process abort signal. Action: Terminates the process. -- **`__WASI_SIGILL`** +- **`__WASI_SIGBUS`** - Illegal instruction. + Access to an undefined portion of a memory object. Action: Terminates the process. -- **`__WASI_SIGINT`** +- **`__WASI_SIGFPE`** - Terminate interrupt signal. + Erroneous arithmetic operation. Action: Terminates the process. @@ -2117,33 +2111,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGPIPE`** +- **`__WASI_SIGUSR1`** - Write on a pipe with no one to read it. + User-defined signal 1. - Action: Ignored. + Action: Terminates the process. -- **`__WASI_SIGQUIT`** +- **`__WASI_SIGSEGV`** - Terminal quit signal. + Invalid memory reference. Action: Terminates the process. -- **`__WASI_SIGSEGV`** +- **`__WASI_SIGUSR2`** - Invalid memory reference. + User-defined signal 2. Action: Terminates the process. -- **`__WASI_SIGSTOP`** +- **`__WASI_SIGPIPE`** - Stop executing. + Write on a pipe with no one to read it. - Action: Stops executing. + Action: Ignored. -- **`__WASI_SIGSYS`** +- **`__WASI_SIGALRM`** - Bad system call. + Alarm clock. Action: Terminates the process. @@ -2153,11 +2147,23 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGTRAP`** +- **`__WASI_SIGCHLD`** - Trace/breakpoint trap. + Child process terminated, stopped, or continued. - Action: Terminates the process. + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. - **`__WASI_SIGTSTP`** @@ -2183,15 +2189,15 @@ Possible values: Action: Ignored. -- **`__WASI_SIGUSR1`** +- **`__WASI_SIGXCPU`** - User-defined signal 1. + CPU time limit exceeded. Action: Terminates the process. -- **`__WASI_SIGUSR2`** +- **`__WASI_SIGXFSZ`** - User-defined signal 2. + File size limit exceeded. Action: Terminates the process. @@ -2201,15 +2207,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGXCPU`** +- **`__WASI_SIGPROF`** - CPU time limit exceeded. + Profiling timer expired. Action: Terminates the process. -- **`__WASI_SIGXFSZ`** +- **`__WASI_SIGWINCH`** - File size limit exceeded. + Window changed. + + Action: Ignored. + +- **`__WASI_SIGPOLL`** + + I/O possible. + + Action: Terminates the process. + +- **`__WASI_SIGPWR`** + + Power failure. + + Action: Terminates the process. + +- **`__WASI_SIGSYS`** + + Bad system call. Action: Terminates the process. diff --git a/proposals/random/phases/old/witx/typenames.witx b/proposals/random/phases/old/witx/typenames.witx index c9261f1d9..15b53af51 100644 --- a/proposals/random/phases/old/witx/typenames.witx +++ b/proposals/random/phases/old/witx/typenames.witx @@ -604,57 +604,63 @@ ;; Signal condition. (typename $signal_t (enum u8 + ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;; so this value is reserved. + $SIGNONE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP ;; Process abort signal. ;; Action: Terminates the process. $SIGABRT - ;; Alarm clock. - ;; Action: Terminates the process. - $SIGALRM ;; Access to an undefined portion of a memory object. ;; Action: Terminates the process. $SIGBUS - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. - $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. - $SIGCONT ;; Erroneous arithmetic operation. ;; Action: Terminates the process. $SIGFPE - ;; Hangup. + ;; Kill. ;; Action: Terminates the process. - $SIGHUP - ;; Illegal instruction. + $SIGKILL + ;; User-defined signal 1. ;; Action: Terminates the process. - $SIGILL - ;; Terminate interrupt signal. + $SIGUSR1 + ;; Invalid memory reference. ;; Action: Terminates the process. - $SIGINT - ;; Kill. + $SIGSEGV + ;; User-defined signal 2. ;; Action: Terminates the process. - $SIGKILL + $SIGUSR2 ;; Write on a pipe with no one to read it. ;; Action: Ignored. $SIGPIPE - ;; Terminal quit signal. + ;; Alarm clock. ;; Action: Terminates the process. - $SIGQUIT - ;; Invalid memory reference. + $SIGALRM + ;; Termination signal. ;; Action: Terminates the process. - $SIGSEGV + $SIGTERM + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT ;; Stop executing. ;; Action: Stops executing. $SIGSTOP - ;; Bad system call. - ;; Action: Terminates the process. - $SIGSYS - ;; Termination signal. - ;; Action: Terminates the process. - $SIGTERM - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. - $SIGTRAP ;; Terminal stop signal. ;; Action: Stops executing. $SIGTSTP @@ -667,21 +673,30 @@ ;; High bandwidth data is available at a socket. ;; Action: Ignored. $SIGURG - ;; User-defined signal 1. + ;; CPU time limit exceeded. ;; Action: Terminates the process. - $SIGUSR1 - ;; User-defined signal 2. + $SIGXCPU + ;; File size limit exceeded. ;; Action: Terminates the process. - $SIGUSR2 + $SIGXFSZ ;; Virtual timer expired. ;; Action: Terminates the process. $SIGVTALRM - ;; CPU time limit exceeded. + ;; Profiling timer expired. ;; Action: Terminates the process. - $SIGXCPU - ;; File size limit exceeded. + $SIGPROF + ;; Window changed. + ;; Action: Ignored. + $SIGWINCH + ;; I/O possible. ;; Action: Terminates the process. - $SIGXFSZ + $SIGPOLL + ;; Power failure. + ;; Action: Terminates the process. + $SIGPWR + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS ) ) diff --git a/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md index 4a1540f7d..2464f2342 100644 --- a/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md +++ b/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md @@ -2057,57 +2057,51 @@ Used by [`__wasi_proc_raise()`](#proc_raise). Possible values: -- **`__WASI_SIGABRT`** +- **`__WASI_SIGHUP`** - Process abort signal. + Hangup. Action: Terminates the process. -- **`__WASI_SIGALRM`** +- **`__WASI_SIGINT`** - Alarm clock. + Terminate interrupt signal. Action: Terminates the process. -- **`__WASI_SIGBUS`** +- **`__WASI_SIGQUIT`** - Access to an undefined portion of a memory object. + Terminal quit signal. Action: Terminates the process. -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** +- **`__WASI_SIGILL`** - Continue executing, if stopped. + Illegal instruction. - Action: Continues executing, if stopped. + Action: Terminates the process. -- **`__WASI_SIGFPE`** +- **`__WASI_SIGTRAP`** - Erroneous arithmetic operation. + Trace/breakpoint trap. Action: Terminates the process. -- **`__WASI_SIGHUP`** +- **`__WASI_SIGABRT`** - Hangup. + Process abort signal. Action: Terminates the process. -- **`__WASI_SIGILL`** +- **`__WASI_SIGBUS`** - Illegal instruction. + Access to an undefined portion of a memory object. Action: Terminates the process. -- **`__WASI_SIGINT`** +- **`__WASI_SIGFPE`** - Terminate interrupt signal. + Erroneous arithmetic operation. Action: Terminates the process. @@ -2117,33 +2111,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGPIPE`** +- **`__WASI_SIGUSR1`** - Write on a pipe with no one to read it. + User-defined signal 1. - Action: Ignored. + Action: Terminates the process. -- **`__WASI_SIGQUIT`** +- **`__WASI_SIGSEGV`** - Terminal quit signal. + Invalid memory reference. Action: Terminates the process. -- **`__WASI_SIGSEGV`** +- **`__WASI_SIGUSR2`** - Invalid memory reference. + User-defined signal 2. Action: Terminates the process. -- **`__WASI_SIGSTOP`** +- **`__WASI_SIGPIPE`** - Stop executing. + Write on a pipe with no one to read it. - Action: Stops executing. + Action: Ignored. -- **`__WASI_SIGSYS`** +- **`__WASI_SIGALRM`** - Bad system call. + Alarm clock. Action: Terminates the process. @@ -2153,11 +2147,23 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGTRAP`** +- **`__WASI_SIGCHLD`** - Trace/breakpoint trap. + Child process terminated, stopped, or continued. - Action: Terminates the process. + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. - **`__WASI_SIGTSTP`** @@ -2183,15 +2189,15 @@ Possible values: Action: Ignored. -- **`__WASI_SIGUSR1`** +- **`__WASI_SIGXCPU`** - User-defined signal 1. + CPU time limit exceeded. Action: Terminates the process. -- **`__WASI_SIGUSR2`** +- **`__WASI_SIGXFSZ`** - User-defined signal 2. + File size limit exceeded. Action: Terminates the process. @@ -2201,15 +2207,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGXCPU`** +- **`__WASI_SIGPROF`** - CPU time limit exceeded. + Profiling timer expired. Action: Terminates the process. -- **`__WASI_SIGXFSZ`** +- **`__WASI_SIGWINCH`** - File size limit exceeded. + Window changed. + + Action: Ignored. + +- **`__WASI_SIGPOLL`** + + I/O possible. + + Action: Terminates the process. + +- **`__WASI_SIGPWR`** + + Power failure. + + Action: Terminates the process. + +- **`__WASI_SIGSYS`** + + Bad system call. Action: Terminates the process. diff --git a/proposals/random/phases/unstable/witx/typenames.witx b/proposals/random/phases/unstable/witx/typenames.witx index c9261f1d9..15b53af51 100644 --- a/proposals/random/phases/unstable/witx/typenames.witx +++ b/proposals/random/phases/unstable/witx/typenames.witx @@ -604,57 +604,63 @@ ;; Signal condition. (typename $signal_t (enum u8 + ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;; so this value is reserved. + $SIGNONE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP ;; Process abort signal. ;; Action: Terminates the process. $SIGABRT - ;; Alarm clock. - ;; Action: Terminates the process. - $SIGALRM ;; Access to an undefined portion of a memory object. ;; Action: Terminates the process. $SIGBUS - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. - $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. - $SIGCONT ;; Erroneous arithmetic operation. ;; Action: Terminates the process. $SIGFPE - ;; Hangup. + ;; Kill. ;; Action: Terminates the process. - $SIGHUP - ;; Illegal instruction. + $SIGKILL + ;; User-defined signal 1. ;; Action: Terminates the process. - $SIGILL - ;; Terminate interrupt signal. + $SIGUSR1 + ;; Invalid memory reference. ;; Action: Terminates the process. - $SIGINT - ;; Kill. + $SIGSEGV + ;; User-defined signal 2. ;; Action: Terminates the process. - $SIGKILL + $SIGUSR2 ;; Write on a pipe with no one to read it. ;; Action: Ignored. $SIGPIPE - ;; Terminal quit signal. + ;; Alarm clock. ;; Action: Terminates the process. - $SIGQUIT - ;; Invalid memory reference. + $SIGALRM + ;; Termination signal. ;; Action: Terminates the process. - $SIGSEGV + $SIGTERM + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT ;; Stop executing. ;; Action: Stops executing. $SIGSTOP - ;; Bad system call. - ;; Action: Terminates the process. - $SIGSYS - ;; Termination signal. - ;; Action: Terminates the process. - $SIGTERM - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. - $SIGTRAP ;; Terminal stop signal. ;; Action: Stops executing. $SIGTSTP @@ -667,21 +673,30 @@ ;; High bandwidth data is available at a socket. ;; Action: Ignored. $SIGURG - ;; User-defined signal 1. + ;; CPU time limit exceeded. ;; Action: Terminates the process. - $SIGUSR1 - ;; User-defined signal 2. + $SIGXCPU + ;; File size limit exceeded. ;; Action: Terminates the process. - $SIGUSR2 + $SIGXFSZ ;; Virtual timer expired. ;; Action: Terminates the process. $SIGVTALRM - ;; CPU time limit exceeded. + ;; Profiling timer expired. ;; Action: Terminates the process. - $SIGXCPU - ;; File size limit exceeded. + $SIGPROF + ;; Window changed. + ;; Action: Ignored. + $SIGWINCH + ;; I/O possible. ;; Action: Terminates the process. - $SIGXFSZ + $SIGPOLL + ;; Power failure. + ;; Action: Terminates the process. + $SIGPWR + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS ) ) From dd6aad4338e66c46ea13fafb93c8b1145b0bb053 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 12:27:00 -0800 Subject: [PATCH 0264/1772] Sync the signal constants with existing practice. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 116 +++++++++++------- .../phases/ephemeral/witx/typenames.witx | 91 ++++++++------ .../phases/old/docs/wasi_unstable.md | 116 +++++++++++------- .../filesystem/phases/old/witx/typenames.witx | 91 ++++++++------ .../unstable/docs/wasi_unstable_preview0.md | 116 +++++++++++------- .../phases/unstable/witx/typenames.witx | 91 ++++++++------ 6 files changed, 369 insertions(+), 252 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md index b51b9a4b2..6de15f1d2 100644 --- a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -2065,57 +2065,51 @@ Used by [`__wasi_proc_raise()`](#proc_raise). Possible values: -- **`__WASI_SIGABRT`** +- **`__WASI_SIGHUP`** - Process abort signal. + Hangup. Action: Terminates the process. -- **`__WASI_SIGALRM`** +- **`__WASI_SIGINT`** - Alarm clock. + Terminate interrupt signal. Action: Terminates the process. -- **`__WASI_SIGBUS`** +- **`__WASI_SIGQUIT`** - Access to an undefined portion of a memory object. + Terminal quit signal. Action: Terminates the process. -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** +- **`__WASI_SIGILL`** - Continue executing, if stopped. + Illegal instruction. - Action: Continues executing, if stopped. + Action: Terminates the process. -- **`__WASI_SIGFPE`** +- **`__WASI_SIGTRAP`** - Erroneous arithmetic operation. + Trace/breakpoint trap. Action: Terminates the process. -- **`__WASI_SIGHUP`** +- **`__WASI_SIGABRT`** - Hangup. + Process abort signal. Action: Terminates the process. -- **`__WASI_SIGILL`** +- **`__WASI_SIGBUS`** - Illegal instruction. + Access to an undefined portion of a memory object. Action: Terminates the process. -- **`__WASI_SIGINT`** +- **`__WASI_SIGFPE`** - Terminate interrupt signal. + Erroneous arithmetic operation. Action: Terminates the process. @@ -2125,33 +2119,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGPIPE`** +- **`__WASI_SIGUSR1`** - Write on a pipe with no one to read it. + User-defined signal 1. - Action: Ignored. + Action: Terminates the process. -- **`__WASI_SIGQUIT`** +- **`__WASI_SIGSEGV`** - Terminal quit signal. + Invalid memory reference. Action: Terminates the process. -- **`__WASI_SIGSEGV`** +- **`__WASI_SIGUSR2`** - Invalid memory reference. + User-defined signal 2. Action: Terminates the process. -- **`__WASI_SIGSTOP`** +- **`__WASI_SIGPIPE`** - Stop executing. + Write on a pipe with no one to read it. - Action: Stops executing. + Action: Ignored. -- **`__WASI_SIGSYS`** +- **`__WASI_SIGALRM`** - Bad system call. + Alarm clock. Action: Terminates the process. @@ -2161,11 +2155,23 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGTRAP`** +- **`__WASI_SIGCHLD`** - Trace/breakpoint trap. + Child process terminated, stopped, or continued. - Action: Terminates the process. + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. - **`__WASI_SIGTSTP`** @@ -2191,15 +2197,15 @@ Possible values: Action: Ignored. -- **`__WASI_SIGUSR1`** +- **`__WASI_SIGXCPU`** - User-defined signal 1. + CPU time limit exceeded. Action: Terminates the process. -- **`__WASI_SIGUSR2`** +- **`__WASI_SIGXFSZ`** - User-defined signal 2. + File size limit exceeded. Action: Terminates the process. @@ -2209,15 +2215,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGXCPU`** +- **`__WASI_SIGPROF`** - CPU time limit exceeded. + Profiling timer expired. Action: Terminates the process. -- **`__WASI_SIGXFSZ`** +- **`__WASI_SIGWINCH`** - File size limit exceeded. + Window changed. + + Action: Ignored. + +- **`__WASI_SIGPOLL`** + + I/O possible. + + Action: Terminates the process. + +- **`__WASI_SIGPWR`** + + Power failure. + + Action: Terminates the process. + +- **`__WASI_SIGSYS`** + + Bad system call. Action: Terminates the process. diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 4271b709d..1a45be1fd 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -604,57 +604,63 @@ ;; Signal condition. (typename $signal_t (enum u8 + ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;; so this value is reserved. + $SIGNONE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP ;; Process abort signal. ;; Action: Terminates the process. $SIGABRT - ;; Alarm clock. - ;; Action: Terminates the process. - $SIGALRM ;; Access to an undefined portion of a memory object. ;; Action: Terminates the process. $SIGBUS - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. - $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. - $SIGCONT ;; Erroneous arithmetic operation. ;; Action: Terminates the process. $SIGFPE - ;; Hangup. + ;; Kill. ;; Action: Terminates the process. - $SIGHUP - ;; Illegal instruction. + $SIGKILL + ;; User-defined signal 1. ;; Action: Terminates the process. - $SIGILL - ;; Terminate interrupt signal. + $SIGUSR1 + ;; Invalid memory reference. ;; Action: Terminates the process. - $SIGINT - ;; Kill. + $SIGSEGV + ;; User-defined signal 2. ;; Action: Terminates the process. - $SIGKILL + $SIGUSR2 ;; Write on a pipe with no one to read it. ;; Action: Ignored. $SIGPIPE - ;; Terminal quit signal. + ;; Alarm clock. ;; Action: Terminates the process. - $SIGQUIT - ;; Invalid memory reference. + $SIGALRM + ;; Termination signal. ;; Action: Terminates the process. - $SIGSEGV + $SIGTERM + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT ;; Stop executing. ;; Action: Stops executing. $SIGSTOP - ;; Bad system call. - ;; Action: Terminates the process. - $SIGSYS - ;; Termination signal. - ;; Action: Terminates the process. - $SIGTERM - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. - $SIGTRAP ;; Terminal stop signal. ;; Action: Stops executing. $SIGTSTP @@ -667,21 +673,30 @@ ;; High bandwidth data is available at a socket. ;; Action: Ignored. $SIGURG - ;; User-defined signal 1. + ;; CPU time limit exceeded. ;; Action: Terminates the process. - $SIGUSR1 - ;; User-defined signal 2. + $SIGXCPU + ;; File size limit exceeded. ;; Action: Terminates the process. - $SIGUSR2 + $SIGXFSZ ;; Virtual timer expired. ;; Action: Terminates the process. $SIGVTALRM - ;; CPU time limit exceeded. + ;; Profiling timer expired. ;; Action: Terminates the process. - $SIGXCPU - ;; File size limit exceeded. + $SIGPROF + ;; Window changed. + ;; Action: Ignored. + $SIGWINCH + ;; I/O possible. ;; Action: Terminates the process. - $SIGXFSZ + $SIGPOLL + ;; Power failure. + ;; Action: Terminates the process. + $SIGPWR + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS ) ) diff --git a/proposals/filesystem/phases/old/docs/wasi_unstable.md b/proposals/filesystem/phases/old/docs/wasi_unstable.md index 4a1540f7d..2464f2342 100644 --- a/proposals/filesystem/phases/old/docs/wasi_unstable.md +++ b/proposals/filesystem/phases/old/docs/wasi_unstable.md @@ -2057,57 +2057,51 @@ Used by [`__wasi_proc_raise()`](#proc_raise). Possible values: -- **`__WASI_SIGABRT`** +- **`__WASI_SIGHUP`** - Process abort signal. + Hangup. Action: Terminates the process. -- **`__WASI_SIGALRM`** +- **`__WASI_SIGINT`** - Alarm clock. + Terminate interrupt signal. Action: Terminates the process. -- **`__WASI_SIGBUS`** +- **`__WASI_SIGQUIT`** - Access to an undefined portion of a memory object. + Terminal quit signal. Action: Terminates the process. -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** +- **`__WASI_SIGILL`** - Continue executing, if stopped. + Illegal instruction. - Action: Continues executing, if stopped. + Action: Terminates the process. -- **`__WASI_SIGFPE`** +- **`__WASI_SIGTRAP`** - Erroneous arithmetic operation. + Trace/breakpoint trap. Action: Terminates the process. -- **`__WASI_SIGHUP`** +- **`__WASI_SIGABRT`** - Hangup. + Process abort signal. Action: Terminates the process. -- **`__WASI_SIGILL`** +- **`__WASI_SIGBUS`** - Illegal instruction. + Access to an undefined portion of a memory object. Action: Terminates the process. -- **`__WASI_SIGINT`** +- **`__WASI_SIGFPE`** - Terminate interrupt signal. + Erroneous arithmetic operation. Action: Terminates the process. @@ -2117,33 +2111,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGPIPE`** +- **`__WASI_SIGUSR1`** - Write on a pipe with no one to read it. + User-defined signal 1. - Action: Ignored. + Action: Terminates the process. -- **`__WASI_SIGQUIT`** +- **`__WASI_SIGSEGV`** - Terminal quit signal. + Invalid memory reference. Action: Terminates the process. -- **`__WASI_SIGSEGV`** +- **`__WASI_SIGUSR2`** - Invalid memory reference. + User-defined signal 2. Action: Terminates the process. -- **`__WASI_SIGSTOP`** +- **`__WASI_SIGPIPE`** - Stop executing. + Write on a pipe with no one to read it. - Action: Stops executing. + Action: Ignored. -- **`__WASI_SIGSYS`** +- **`__WASI_SIGALRM`** - Bad system call. + Alarm clock. Action: Terminates the process. @@ -2153,11 +2147,23 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGTRAP`** +- **`__WASI_SIGCHLD`** - Trace/breakpoint trap. + Child process terminated, stopped, or continued. - Action: Terminates the process. + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. - **`__WASI_SIGTSTP`** @@ -2183,15 +2189,15 @@ Possible values: Action: Ignored. -- **`__WASI_SIGUSR1`** +- **`__WASI_SIGXCPU`** - User-defined signal 1. + CPU time limit exceeded. Action: Terminates the process. -- **`__WASI_SIGUSR2`** +- **`__WASI_SIGXFSZ`** - User-defined signal 2. + File size limit exceeded. Action: Terminates the process. @@ -2201,15 +2207,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGXCPU`** +- **`__WASI_SIGPROF`** - CPU time limit exceeded. + Profiling timer expired. Action: Terminates the process. -- **`__WASI_SIGXFSZ`** +- **`__WASI_SIGWINCH`** - File size limit exceeded. + Window changed. + + Action: Ignored. + +- **`__WASI_SIGPOLL`** + + I/O possible. + + Action: Terminates the process. + +- **`__WASI_SIGPWR`** + + Power failure. + + Action: Terminates the process. + +- **`__WASI_SIGSYS`** + + Bad system call. Action: Terminates the process. diff --git a/proposals/filesystem/phases/old/witx/typenames.witx b/proposals/filesystem/phases/old/witx/typenames.witx index c9261f1d9..15b53af51 100644 --- a/proposals/filesystem/phases/old/witx/typenames.witx +++ b/proposals/filesystem/phases/old/witx/typenames.witx @@ -604,57 +604,63 @@ ;; Signal condition. (typename $signal_t (enum u8 + ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;; so this value is reserved. + $SIGNONE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP ;; Process abort signal. ;; Action: Terminates the process. $SIGABRT - ;; Alarm clock. - ;; Action: Terminates the process. - $SIGALRM ;; Access to an undefined portion of a memory object. ;; Action: Terminates the process. $SIGBUS - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. - $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. - $SIGCONT ;; Erroneous arithmetic operation. ;; Action: Terminates the process. $SIGFPE - ;; Hangup. + ;; Kill. ;; Action: Terminates the process. - $SIGHUP - ;; Illegal instruction. + $SIGKILL + ;; User-defined signal 1. ;; Action: Terminates the process. - $SIGILL - ;; Terminate interrupt signal. + $SIGUSR1 + ;; Invalid memory reference. ;; Action: Terminates the process. - $SIGINT - ;; Kill. + $SIGSEGV + ;; User-defined signal 2. ;; Action: Terminates the process. - $SIGKILL + $SIGUSR2 ;; Write on a pipe with no one to read it. ;; Action: Ignored. $SIGPIPE - ;; Terminal quit signal. + ;; Alarm clock. ;; Action: Terminates the process. - $SIGQUIT - ;; Invalid memory reference. + $SIGALRM + ;; Termination signal. ;; Action: Terminates the process. - $SIGSEGV + $SIGTERM + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT ;; Stop executing. ;; Action: Stops executing. $SIGSTOP - ;; Bad system call. - ;; Action: Terminates the process. - $SIGSYS - ;; Termination signal. - ;; Action: Terminates the process. - $SIGTERM - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. - $SIGTRAP ;; Terminal stop signal. ;; Action: Stops executing. $SIGTSTP @@ -667,21 +673,30 @@ ;; High bandwidth data is available at a socket. ;; Action: Ignored. $SIGURG - ;; User-defined signal 1. + ;; CPU time limit exceeded. ;; Action: Terminates the process. - $SIGUSR1 - ;; User-defined signal 2. + $SIGXCPU + ;; File size limit exceeded. ;; Action: Terminates the process. - $SIGUSR2 + $SIGXFSZ ;; Virtual timer expired. ;; Action: Terminates the process. $SIGVTALRM - ;; CPU time limit exceeded. + ;; Profiling timer expired. ;; Action: Terminates the process. - $SIGXCPU - ;; File size limit exceeded. + $SIGPROF + ;; Window changed. + ;; Action: Ignored. + $SIGWINCH + ;; I/O possible. ;; Action: Terminates the process. - $SIGXFSZ + $SIGPOLL + ;; Power failure. + ;; Action: Terminates the process. + $SIGPWR + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS ) ) diff --git a/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md index 4a1540f7d..2464f2342 100644 --- a/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md +++ b/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md @@ -2057,57 +2057,51 @@ Used by [`__wasi_proc_raise()`](#proc_raise). Possible values: -- **`__WASI_SIGABRT`** +- **`__WASI_SIGHUP`** - Process abort signal. + Hangup. Action: Terminates the process. -- **`__WASI_SIGALRM`** +- **`__WASI_SIGINT`** - Alarm clock. + Terminate interrupt signal. Action: Terminates the process. -- **`__WASI_SIGBUS`** +- **`__WASI_SIGQUIT`** - Access to an undefined portion of a memory object. + Terminal quit signal. Action: Terminates the process. -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** +- **`__WASI_SIGILL`** - Continue executing, if stopped. + Illegal instruction. - Action: Continues executing, if stopped. + Action: Terminates the process. -- **`__WASI_SIGFPE`** +- **`__WASI_SIGTRAP`** - Erroneous arithmetic operation. + Trace/breakpoint trap. Action: Terminates the process. -- **`__WASI_SIGHUP`** +- **`__WASI_SIGABRT`** - Hangup. + Process abort signal. Action: Terminates the process. -- **`__WASI_SIGILL`** +- **`__WASI_SIGBUS`** - Illegal instruction. + Access to an undefined portion of a memory object. Action: Terminates the process. -- **`__WASI_SIGINT`** +- **`__WASI_SIGFPE`** - Terminate interrupt signal. + Erroneous arithmetic operation. Action: Terminates the process. @@ -2117,33 +2111,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGPIPE`** +- **`__WASI_SIGUSR1`** - Write on a pipe with no one to read it. + User-defined signal 1. - Action: Ignored. + Action: Terminates the process. -- **`__WASI_SIGQUIT`** +- **`__WASI_SIGSEGV`** - Terminal quit signal. + Invalid memory reference. Action: Terminates the process. -- **`__WASI_SIGSEGV`** +- **`__WASI_SIGUSR2`** - Invalid memory reference. + User-defined signal 2. Action: Terminates the process. -- **`__WASI_SIGSTOP`** +- **`__WASI_SIGPIPE`** - Stop executing. + Write on a pipe with no one to read it. - Action: Stops executing. + Action: Ignored. -- **`__WASI_SIGSYS`** +- **`__WASI_SIGALRM`** - Bad system call. + Alarm clock. Action: Terminates the process. @@ -2153,11 +2147,23 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGTRAP`** +- **`__WASI_SIGCHLD`** - Trace/breakpoint trap. + Child process terminated, stopped, or continued. - Action: Terminates the process. + Action: Ignored. + +- **`__WASI_SIGCONT`** + + Continue executing, if stopped. + + Action: Continues executing, if stopped. + +- **`__WASI_SIGSTOP`** + + Stop executing. + + Action: Stops executing. - **`__WASI_SIGTSTP`** @@ -2183,15 +2189,15 @@ Possible values: Action: Ignored. -- **`__WASI_SIGUSR1`** +- **`__WASI_SIGXCPU`** - User-defined signal 1. + CPU time limit exceeded. Action: Terminates the process. -- **`__WASI_SIGUSR2`** +- **`__WASI_SIGXFSZ`** - User-defined signal 2. + File size limit exceeded. Action: Terminates the process. @@ -2201,15 +2207,33 @@ Possible values: Action: Terminates the process. -- **`__WASI_SIGXCPU`** +- **`__WASI_SIGPROF`** - CPU time limit exceeded. + Profiling timer expired. Action: Terminates the process. -- **`__WASI_SIGXFSZ`** +- **`__WASI_SIGWINCH`** - File size limit exceeded. + Window changed. + + Action: Ignored. + +- **`__WASI_SIGPOLL`** + + I/O possible. + + Action: Terminates the process. + +- **`__WASI_SIGPWR`** + + Power failure. + + Action: Terminates the process. + +- **`__WASI_SIGSYS`** + + Bad system call. Action: Terminates the process. diff --git a/proposals/filesystem/phases/unstable/witx/typenames.witx b/proposals/filesystem/phases/unstable/witx/typenames.witx index c9261f1d9..15b53af51 100644 --- a/proposals/filesystem/phases/unstable/witx/typenames.witx +++ b/proposals/filesystem/phases/unstable/witx/typenames.witx @@ -604,57 +604,63 @@ ;; Signal condition. (typename $signal_t (enum u8 + ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;; so this value is reserved. + $SIGNONE + ;; Hangup. + ;; Action: Terminates the process. + $SIGHUP + ;; Terminate interrupt signal. + ;; Action: Terminates the process. + $SIGINT + ;; Terminal quit signal. + ;; Action: Terminates the process. + $SIGQUIT + ;; Illegal instruction. + ;; Action: Terminates the process. + $SIGILL + ;; Trace/breakpoint trap. + ;; Action: Terminates the process. + $SIGTRAP ;; Process abort signal. ;; Action: Terminates the process. $SIGABRT - ;; Alarm clock. - ;; Action: Terminates the process. - $SIGALRM ;; Access to an undefined portion of a memory object. ;; Action: Terminates the process. $SIGBUS - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. - $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. - $SIGCONT ;; Erroneous arithmetic operation. ;; Action: Terminates the process. $SIGFPE - ;; Hangup. + ;; Kill. ;; Action: Terminates the process. - $SIGHUP - ;; Illegal instruction. + $SIGKILL + ;; User-defined signal 1. ;; Action: Terminates the process. - $SIGILL - ;; Terminate interrupt signal. + $SIGUSR1 + ;; Invalid memory reference. ;; Action: Terminates the process. - $SIGINT - ;; Kill. + $SIGSEGV + ;; User-defined signal 2. ;; Action: Terminates the process. - $SIGKILL + $SIGUSR2 ;; Write on a pipe with no one to read it. ;; Action: Ignored. $SIGPIPE - ;; Terminal quit signal. + ;; Alarm clock. ;; Action: Terminates the process. - $SIGQUIT - ;; Invalid memory reference. + $SIGALRM + ;; Termination signal. ;; Action: Terminates the process. - $SIGSEGV + $SIGTERM + ;; Child process terminated, stopped, or continued. + ;; Action: Ignored. + $SIGCHLD + ;; Continue executing, if stopped. + ;; Action: Continues executing, if stopped. + $SIGCONT ;; Stop executing. ;; Action: Stops executing. $SIGSTOP - ;; Bad system call. - ;; Action: Terminates the process. - $SIGSYS - ;; Termination signal. - ;; Action: Terminates the process. - $SIGTERM - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. - $SIGTRAP ;; Terminal stop signal. ;; Action: Stops executing. $SIGTSTP @@ -667,21 +673,30 @@ ;; High bandwidth data is available at a socket. ;; Action: Ignored. $SIGURG - ;; User-defined signal 1. + ;; CPU time limit exceeded. ;; Action: Terminates the process. - $SIGUSR1 - ;; User-defined signal 2. + $SIGXCPU + ;; File size limit exceeded. ;; Action: Terminates the process. - $SIGUSR2 + $SIGXFSZ ;; Virtual timer expired. ;; Action: Terminates the process. $SIGVTALRM - ;; CPU time limit exceeded. + ;; Profiling timer expired. ;; Action: Terminates the process. - $SIGXCPU - ;; File size limit exceeded. + $SIGPROF + ;; Window changed. + ;; Action: Ignored. + $SIGWINCH + ;; I/O possible. ;; Action: Terminates the process. - $SIGXFSZ + $SIGPOLL + ;; Power failure. + ;; Action: Terminates the process. + $SIGPWR + ;; Bad system call. + ;; Action: Terminates the process. + $SIGSYS ) ) From 4c64a0f86a312f1b2abfb1a0cbdc623a2f08b3c1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 17:41:30 -0800 Subject: [PATCH 0265/1772] Post an initial agenda for the 11-07 meeting. Note the time change, due to daylight savings time changes in some locales. We can of course discuss changing back for the following meeting if people prefer that. Also post the 10-24 meeting notes. --- proposals/clocks/meetings/2019/WASI-10-24.md | 120 ++++++++++++++++++- proposals/clocks/meetings/2019/WASI-11-07.md | 45 +++++++ proposals/clocks/meetings/README.md | 1 + 3 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 proposals/clocks/meetings/2019/WASI-11-07.md diff --git a/proposals/clocks/meetings/2019/WASI-10-24.md b/proposals/clocks/meetings/2019/WASI-10-24.md index 2c0e0bfc6..c9dae6238 100644 --- a/proposals/clocks/meetings/2019/WASI-10-24.md +++ b/proposals/clocks/meetings/2019/WASI-10-24.md @@ -1,6 +1,6 @@ ![WASI logo](/WASI.png) -## Agenda for the Octoper 24 video call of WASI Subgroup +## Agenda for the October 24 video call of WASI Subgroup - **Where**: zoom.us - **When**: October 24, 16:00-17:00 UTC @@ -52,4 +52,120 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Mark Miller +Mark McCaskey +Pat Hickey +Barbara Nichols +Andrew Brown +Peter Huene +Artur Jamro +Till Schneidereit +Luke Wagner +Yury Delendik +Alon Zakai +Alex Crichton +Aaron Turner +Jacob Gravelle +Wvo +Sam Clegg + +Meeting notes: + +Dan: First discussion is WASI and OCAP. We have Mark Miller here. First off, what does OCAP mean and why is it interesting, and second what do we want to do. Mark can you please talk about what fine grained OCAP means. + +Mark: We have to distinguish two forms of fine grain. What is the unit of computation being protected, and what is the nature of a permission that can be separately reified (turned into something that can be passed around). Wasm has a coarse-grained unit of protected computation - a wasm module instance. It has a flat address space (two: memory for data, and functions, are separate). All toolchains are currently built around the assumption that all Wasm modules that are linked together share a memory and function table. I’ll introduce the term “compartment” for all Wasm instances that share those address spaces. Inside that compartment, all computations inside are vulnerable to all other computations inside. We’ll eventually address that better with the GC proposal but thats a way out and we wont address it further in this conversation. +The other issue is what is the unit of passable permission. Thats permission to access outside resources and also for units of computation to effect each other. We’ll assume that there are a set of separate compartments that are units of protection - their only initial relationship is through imported and exported functions. As far as the Wasm mechanism is concerned, import functions between compartments are a perfect OCAP protection mechanism. (details this by example) +Currently the only things that Wasm can pass over function interfaces are numbers (ints and floats). As a result the permissions communicated between compartments are only communicated statically - you can't pass them dynamically once compartments are linked. So you can convey permission at whatever fine-grain you want by having many different exported functions. You can use procedural abstraction to attenuate permissions, e.g. you can use a function to provide an abstraction of a read-write file as an append-only file. + +Dan: I want to temporarily ignore address spaces and tables: in a world where we have references, does it make sense to talk about compartments still? + +Mark: Current Wasm architecture plus references still has flat address spaces - our current toolchains push us into it, there will still be multiple module instances linked together sharing address spaces. + +Dan: I’m trying to hypothetically see if we take address spaces out of the situation and have wasm gc everywhere, are compartments still relevant? + +Mark: In that hypothetical the Wasm module can use the memory and table space as empty, and Wasm becomes a fine-grained object capability machine. + +Dan: The question that came up on github is that we currently are trying to do much finer grained permissions than the function level. + +Mark: Yes in the hypothetical GC situation you have capabilities that are fine grained at the level of the objects in your programming language + +Dan: How do we bridge the gap between the situation we have now, with these compartments and the failures of granularity associated with that, and where we want to be with GC with finer grained permissions. + +Till: What about the host? (I didn’t follow this close enough for good note taking) + +Mark: There are OCAP languages and operating systems, and research on running OCAP languages on a OCAP operating system with a bridge between the language’s idea of capabilities and the operating system - when you’re writing in the language its as if the operating system’s view of capabilities are just ordinary programming language capabilities. + +Mark: If you design that all interfaces between compartments are designed around reference types, the inter-compartment protocols that are natural to future GC based compartments. + +Mark: Even with reference types, the notion of a virtualizable capability is the natural way to express capabilities in the + +In the Wasm GC machine there’s support for both virtualizable and abstract datatype capabilities, theres no penalty for virtualizable capabilities and its quite natural. In the current world the only way cross-compartment is abstract datatype capabilities. That’s going to be an impedance mismatch. + +Dan: I’d like to steer this back towards what do we do with WASI right now for languages that don't have GC or reference types. Its going to be a long term problem because we’re going to have C/C++ forever. How can we deal with an integer based approach that can approximate reference types in a useful way, at the penalty of being coarser grained? + +Mark: Let’s take very basic C++ as the representative (worst) case. There’s two approaches: one is the approach the Cheri team (University of Cambridge) has taken, they’ve added reference types to existing RISC machine architectures as additional instructions and registers and used that to put protection boundaries inside existing C/C++ code. They built a compiler and LLVM fork that can run in two modes: one mode every C++ pointer is turned into a Cheri capability, at which point you’re treating the Cheri hardware like we’d eventaully do Wasm GC. + +Dan: In Cheri pointers are still bit patterns right? + +Mark: Sort of, in the other compilation mode: in that mode the pointers are still bit patterns that are readable, but the capability gives you a range of addressable memory (which is potentially very fine grained) that is valid to dereference. This is expensive and not really what we’re doing with Wasm GC. + +(at this point i lost the ability to follow and take good notes) + +Dan: Any solution that involves users annotating their source code is going to get a lot of resistance from our users. Any solution where capabilities are held on by a side table and theres bit patterns in the wasm, is better for C compatibility but not the best for actually doing OCAP. Cheri is cool but it doesn't magically solve our problems here yet. + +Mark: A completely different way to approach this issue: Let’s say all your inter-compartment capability interfaces are defined in an IDL, and then we can generate (like capnp) bindings to particular non-capability-based ABIs, so only the code generated from the IDL directly handles the reference types and does the context switch between compartments. All of the C code just uses the C ABI bindings generated by the IDL. Those ABI bindings use integers that require the capabilities be looked up from tables + +Till: A lot of this is actively in the works as the interface types proposal. A lot of these concerns are actively being addressed by how WASI and interface types are developing. The biggest thing is that moving capabilities from being expressed as integers to references, and all compartment interfaces are in terms of reference. Inside a compartment you can do whatever you like. + +Dan: We have an IDL now where we’re moving to talk about APIs in terms of references. At the WASI level we should design in references using OCAP. + +Jacob: In the interface types polyfill we have a way to automate the side-table translation so you don’t have to even generate glue code, its just done in javascript (the host) for you. You can add an interface instruction to convert an index into a ref. This lets us use C without annotations beyond the toolchain knowing about interface types. + +Dan: Next topic: there's a virtualization doc that is coming along, and a paper +http://www.cs.cmu.edu/~aldrich/papers/ecoop17modules.pdf +(summarizes part of paper in way I couldnt follow for notes) + +Dan: Mark’s idea of virtualizatbility is an object with vtables inside them. +(more discussion of the paper) + +Mark: I’ll have to read the paper to understand this fully. + +http://www.cs.cmu.edu/~aldrich/papers/ecoop17modules.pdf + +Mark: Just followed the link, I know this paper. The language in the paper is fine-grained OCAP, individual objects are vtable-like. In that language, there’s still an issue of how you start the world off - a static configuration with good safety properties so you can move forward with dynamic properties. This paper is about the initial permissions with least-authority linkage between the modules. It is in the context of a dynamic system with full fine-grained virtualizability. I don’t see exactly how that addresses our Wasm representation problem, we still cant use references as fine-grained virtualizable capabilities. + +Dan: I think we should table and continue this discussion at a different time. I’d like to go to the rest of the agenda for the remaining 15 mins. + +Dan: What do we call handles, or descriptors? PR 117, or the last comments on issue 62 on file descriptors vs handles. POSIX has called things file descriptors when they're not really files. I want to talk about OCAP capabilities as handles. + +Mark: Historically, descriptors and capabilities are aligned, and the numbers you are familiar with as file descriptors are often just called indices, so clists are the list of capabilities and clist indices are the file descriptor ints you know. + +Dan: We settled more or less on Handle as an identifier that refers to a capability. When we say handles we’re just saying the OCAP sense. Does that make sense? + +Mark: Yes! + +Dan: Let’s call that a decision then. + +Dan: Witx files are up in the repos, you can make a PR into the ephemeral phase and we can then promote that to unstable when a decent number are landed and move on to implementing it. + + +Dan: Moving on to the modularization update: look at PR 98 for the basic change. This wont be the end of the story for modularization, but its a logical first step. + +Sam: Does this change the import field name strings? + +Dan: Yes, right now “wasi\_unstable” is the module name everything imports from. + +Sam: Yes I see that there are N different modules. + +Dan: Does it make sense to limit witx to one module per file? Wat only allows one module per file. + +Pat: We have to figure out how to deal with type names being global, we’ll need some sort of namespacing and import mechanism. + +Dan: Ok, we’ll figure that out and move forward. + +Dan: I put some basic issues in the agenda that are hopefully straightforward to implement. I’d like to encourage more people to step in and make PRs on the witx files and get involved. + +Dan: for example on the issue about using capabilities for randomness, we can propose solutions with PRs that change the witx. diff --git a/proposals/clocks/meetings/2019/WASI-11-07.md b/proposals/clocks/meetings/2019/WASI-11-07.md new file mode 100644 index 000000000..b23bb73c7 --- /dev/null +++ b/proposals/clocks/meetings/2019/WASI-11-07.md @@ -0,0 +1,45 @@ +![WASI logo](/WASI.png) + +## Agenda for the November 24 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: November 24, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Publishing a first snapshot + 1. https://github.com/WebAssembly/WASI/issues/138 + 1. Issues for discussion + 1. Make clocks/random into capabilities + 1. https://github.com/WebAssembly/WASI/issues/118 + 1. Should random continue to be `random_get`, or should it become + `fd_read` from a special stream? + 1. Increase the timestamp range + 1. https://github.com/WebAssembly/WASI/issues/33 + 1. Remove remaining "process" dependencies + 1. https://github.com/WebAssembly/WASI/issues/26 + 1. Remove `CLOCK_PROCESS_CPUTIME_ID`? + +1. Closure + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 9b8689d9f..2988c76ac 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -19,3 +19,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI September 26th video call](2019/WASI-09-26.md) * [WASI October 15th in-person meeting](2019/WASI-10-15.md) * [WASI October 24th video call](2019/WASI-10-24.md) + * [WASI November 7th video call](2019/WASI-11-07.md) From ae0bda352bc91a180a6eaa1bf08de11499c8c8f2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 17:41:30 -0800 Subject: [PATCH 0266/1772] Post an initial agenda for the 11-07 meeting. Note the time change, due to daylight savings time changes in some locales. We can of course discuss changing back for the following meeting if people prefer that. Also post the 10-24 meeting notes. --- proposals/random/meetings/2019/WASI-10-24.md | 120 ++++++++++++++++++- proposals/random/meetings/2019/WASI-11-07.md | 45 +++++++ proposals/random/meetings/README.md | 1 + 3 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 proposals/random/meetings/2019/WASI-11-07.md diff --git a/proposals/random/meetings/2019/WASI-10-24.md b/proposals/random/meetings/2019/WASI-10-24.md index 2c0e0bfc6..c9dae6238 100644 --- a/proposals/random/meetings/2019/WASI-10-24.md +++ b/proposals/random/meetings/2019/WASI-10-24.md @@ -1,6 +1,6 @@ ![WASI logo](/WASI.png) -## Agenda for the Octoper 24 video call of WASI Subgroup +## Agenda for the October 24 video call of WASI Subgroup - **Where**: zoom.us - **When**: October 24, 16:00-17:00 UTC @@ -52,4 +52,120 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Mark Miller +Mark McCaskey +Pat Hickey +Barbara Nichols +Andrew Brown +Peter Huene +Artur Jamro +Till Schneidereit +Luke Wagner +Yury Delendik +Alon Zakai +Alex Crichton +Aaron Turner +Jacob Gravelle +Wvo +Sam Clegg + +Meeting notes: + +Dan: First discussion is WASI and OCAP. We have Mark Miller here. First off, what does OCAP mean and why is it interesting, and second what do we want to do. Mark can you please talk about what fine grained OCAP means. + +Mark: We have to distinguish two forms of fine grain. What is the unit of computation being protected, and what is the nature of a permission that can be separately reified (turned into something that can be passed around). Wasm has a coarse-grained unit of protected computation - a wasm module instance. It has a flat address space (two: memory for data, and functions, are separate). All toolchains are currently built around the assumption that all Wasm modules that are linked together share a memory and function table. I’ll introduce the term “compartment” for all Wasm instances that share those address spaces. Inside that compartment, all computations inside are vulnerable to all other computations inside. We’ll eventually address that better with the GC proposal but thats a way out and we wont address it further in this conversation. +The other issue is what is the unit of passable permission. Thats permission to access outside resources and also for units of computation to effect each other. We’ll assume that there are a set of separate compartments that are units of protection - their only initial relationship is through imported and exported functions. As far as the Wasm mechanism is concerned, import functions between compartments are a perfect OCAP protection mechanism. (details this by example) +Currently the only things that Wasm can pass over function interfaces are numbers (ints and floats). As a result the permissions communicated between compartments are only communicated statically - you can't pass them dynamically once compartments are linked. So you can convey permission at whatever fine-grain you want by having many different exported functions. You can use procedural abstraction to attenuate permissions, e.g. you can use a function to provide an abstraction of a read-write file as an append-only file. + +Dan: I want to temporarily ignore address spaces and tables: in a world where we have references, does it make sense to talk about compartments still? + +Mark: Current Wasm architecture plus references still has flat address spaces - our current toolchains push us into it, there will still be multiple module instances linked together sharing address spaces. + +Dan: I’m trying to hypothetically see if we take address spaces out of the situation and have wasm gc everywhere, are compartments still relevant? + +Mark: In that hypothetical the Wasm module can use the memory and table space as empty, and Wasm becomes a fine-grained object capability machine. + +Dan: The question that came up on github is that we currently are trying to do much finer grained permissions than the function level. + +Mark: Yes in the hypothetical GC situation you have capabilities that are fine grained at the level of the objects in your programming language + +Dan: How do we bridge the gap between the situation we have now, with these compartments and the failures of granularity associated with that, and where we want to be with GC with finer grained permissions. + +Till: What about the host? (I didn’t follow this close enough for good note taking) + +Mark: There are OCAP languages and operating systems, and research on running OCAP languages on a OCAP operating system with a bridge between the language’s idea of capabilities and the operating system - when you’re writing in the language its as if the operating system’s view of capabilities are just ordinary programming language capabilities. + +Mark: If you design that all interfaces between compartments are designed around reference types, the inter-compartment protocols that are natural to future GC based compartments. + +Mark: Even with reference types, the notion of a virtualizable capability is the natural way to express capabilities in the + +In the Wasm GC machine there’s support for both virtualizable and abstract datatype capabilities, theres no penalty for virtualizable capabilities and its quite natural. In the current world the only way cross-compartment is abstract datatype capabilities. That’s going to be an impedance mismatch. + +Dan: I’d like to steer this back towards what do we do with WASI right now for languages that don't have GC or reference types. Its going to be a long term problem because we’re going to have C/C++ forever. How can we deal with an integer based approach that can approximate reference types in a useful way, at the penalty of being coarser grained? + +Mark: Let’s take very basic C++ as the representative (worst) case. There’s two approaches: one is the approach the Cheri team (University of Cambridge) has taken, they’ve added reference types to existing RISC machine architectures as additional instructions and registers and used that to put protection boundaries inside existing C/C++ code. They built a compiler and LLVM fork that can run in two modes: one mode every C++ pointer is turned into a Cheri capability, at which point you’re treating the Cheri hardware like we’d eventaully do Wasm GC. + +Dan: In Cheri pointers are still bit patterns right? + +Mark: Sort of, in the other compilation mode: in that mode the pointers are still bit patterns that are readable, but the capability gives you a range of addressable memory (which is potentially very fine grained) that is valid to dereference. This is expensive and not really what we’re doing with Wasm GC. + +(at this point i lost the ability to follow and take good notes) + +Dan: Any solution that involves users annotating their source code is going to get a lot of resistance from our users. Any solution where capabilities are held on by a side table and theres bit patterns in the wasm, is better for C compatibility but not the best for actually doing OCAP. Cheri is cool but it doesn't magically solve our problems here yet. + +Mark: A completely different way to approach this issue: Let’s say all your inter-compartment capability interfaces are defined in an IDL, and then we can generate (like capnp) bindings to particular non-capability-based ABIs, so only the code generated from the IDL directly handles the reference types and does the context switch between compartments. All of the C code just uses the C ABI bindings generated by the IDL. Those ABI bindings use integers that require the capabilities be looked up from tables + +Till: A lot of this is actively in the works as the interface types proposal. A lot of these concerns are actively being addressed by how WASI and interface types are developing. The biggest thing is that moving capabilities from being expressed as integers to references, and all compartment interfaces are in terms of reference. Inside a compartment you can do whatever you like. + +Dan: We have an IDL now where we’re moving to talk about APIs in terms of references. At the WASI level we should design in references using OCAP. + +Jacob: In the interface types polyfill we have a way to automate the side-table translation so you don’t have to even generate glue code, its just done in javascript (the host) for you. You can add an interface instruction to convert an index into a ref. This lets us use C without annotations beyond the toolchain knowing about interface types. + +Dan: Next topic: there's a virtualization doc that is coming along, and a paper +http://www.cs.cmu.edu/~aldrich/papers/ecoop17modules.pdf +(summarizes part of paper in way I couldnt follow for notes) + +Dan: Mark’s idea of virtualizatbility is an object with vtables inside them. +(more discussion of the paper) + +Mark: I’ll have to read the paper to understand this fully. + +http://www.cs.cmu.edu/~aldrich/papers/ecoop17modules.pdf + +Mark: Just followed the link, I know this paper. The language in the paper is fine-grained OCAP, individual objects are vtable-like. In that language, there’s still an issue of how you start the world off - a static configuration with good safety properties so you can move forward with dynamic properties. This paper is about the initial permissions with least-authority linkage between the modules. It is in the context of a dynamic system with full fine-grained virtualizability. I don’t see exactly how that addresses our Wasm representation problem, we still cant use references as fine-grained virtualizable capabilities. + +Dan: I think we should table and continue this discussion at a different time. I’d like to go to the rest of the agenda for the remaining 15 mins. + +Dan: What do we call handles, or descriptors? PR 117, or the last comments on issue 62 on file descriptors vs handles. POSIX has called things file descriptors when they're not really files. I want to talk about OCAP capabilities as handles. + +Mark: Historically, descriptors and capabilities are aligned, and the numbers you are familiar with as file descriptors are often just called indices, so clists are the list of capabilities and clist indices are the file descriptor ints you know. + +Dan: We settled more or less on Handle as an identifier that refers to a capability. When we say handles we’re just saying the OCAP sense. Does that make sense? + +Mark: Yes! + +Dan: Let’s call that a decision then. + +Dan: Witx files are up in the repos, you can make a PR into the ephemeral phase and we can then promote that to unstable when a decent number are landed and move on to implementing it. + + +Dan: Moving on to the modularization update: look at PR 98 for the basic change. This wont be the end of the story for modularization, but its a logical first step. + +Sam: Does this change the import field name strings? + +Dan: Yes, right now “wasi\_unstable” is the module name everything imports from. + +Sam: Yes I see that there are N different modules. + +Dan: Does it make sense to limit witx to one module per file? Wat only allows one module per file. + +Pat: We have to figure out how to deal with type names being global, we’ll need some sort of namespacing and import mechanism. + +Dan: Ok, we’ll figure that out and move forward. + +Dan: I put some basic issues in the agenda that are hopefully straightforward to implement. I’d like to encourage more people to step in and make PRs on the witx files and get involved. + +Dan: for example on the issue about using capabilities for randomness, we can propose solutions with PRs that change the witx. diff --git a/proposals/random/meetings/2019/WASI-11-07.md b/proposals/random/meetings/2019/WASI-11-07.md new file mode 100644 index 000000000..b23bb73c7 --- /dev/null +++ b/proposals/random/meetings/2019/WASI-11-07.md @@ -0,0 +1,45 @@ +![WASI logo](/WASI.png) + +## Agenda for the November 24 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: November 24, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Publishing a first snapshot + 1. https://github.com/WebAssembly/WASI/issues/138 + 1. Issues for discussion + 1. Make clocks/random into capabilities + 1. https://github.com/WebAssembly/WASI/issues/118 + 1. Should random continue to be `random_get`, or should it become + `fd_read` from a special stream? + 1. Increase the timestamp range + 1. https://github.com/WebAssembly/WASI/issues/33 + 1. Remove remaining "process" dependencies + 1. https://github.com/WebAssembly/WASI/issues/26 + 1. Remove `CLOCK_PROCESS_CPUTIME_ID`? + +1. Closure + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 9b8689d9f..2988c76ac 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -19,3 +19,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI September 26th video call](2019/WASI-09-26.md) * [WASI October 15th in-person meeting](2019/WASI-10-15.md) * [WASI October 24th video call](2019/WASI-10-24.md) + * [WASI November 7th video call](2019/WASI-11-07.md) From 59a610d265a99e68735897c5af34be52b43b2832 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 17:41:30 -0800 Subject: [PATCH 0267/1772] Post an initial agenda for the 11-07 meeting. Note the time change, due to daylight savings time changes in some locales. We can of course discuss changing back for the following meeting if people prefer that. Also post the 10-24 meeting notes. --- .../filesystem/meetings/2019/WASI-10-24.md | 120 +++++++++++++++++- .../filesystem/meetings/2019/WASI-11-07.md | 45 +++++++ proposals/filesystem/meetings/README.md | 1 + 3 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 proposals/filesystem/meetings/2019/WASI-11-07.md diff --git a/proposals/filesystem/meetings/2019/WASI-10-24.md b/proposals/filesystem/meetings/2019/WASI-10-24.md index 2c0e0bfc6..c9dae6238 100644 --- a/proposals/filesystem/meetings/2019/WASI-10-24.md +++ b/proposals/filesystem/meetings/2019/WASI-10-24.md @@ -1,6 +1,6 @@ ![WASI logo](/WASI.png) -## Agenda for the Octoper 24 video call of WASI Subgroup +## Agenda for the October 24 video call of WASI Subgroup - **Where**: zoom.us - **When**: October 24, 16:00-17:00 UTC @@ -52,4 +52,120 @@ Installation is required, see the calendar invite. ## Meeting Notes -Posted after meeting. +Attendees: + +Dan Gohman +Mark Miller +Mark McCaskey +Pat Hickey +Barbara Nichols +Andrew Brown +Peter Huene +Artur Jamro +Till Schneidereit +Luke Wagner +Yury Delendik +Alon Zakai +Alex Crichton +Aaron Turner +Jacob Gravelle +Wvo +Sam Clegg + +Meeting notes: + +Dan: First discussion is WASI and OCAP. We have Mark Miller here. First off, what does OCAP mean and why is it interesting, and second what do we want to do. Mark can you please talk about what fine grained OCAP means. + +Mark: We have to distinguish two forms of fine grain. What is the unit of computation being protected, and what is the nature of a permission that can be separately reified (turned into something that can be passed around). Wasm has a coarse-grained unit of protected computation - a wasm module instance. It has a flat address space (two: memory for data, and functions, are separate). All toolchains are currently built around the assumption that all Wasm modules that are linked together share a memory and function table. I’ll introduce the term “compartment” for all Wasm instances that share those address spaces. Inside that compartment, all computations inside are vulnerable to all other computations inside. We’ll eventually address that better with the GC proposal but thats a way out and we wont address it further in this conversation. +The other issue is what is the unit of passable permission. Thats permission to access outside resources and also for units of computation to effect each other. We’ll assume that there are a set of separate compartments that are units of protection - their only initial relationship is through imported and exported functions. As far as the Wasm mechanism is concerned, import functions between compartments are a perfect OCAP protection mechanism. (details this by example) +Currently the only things that Wasm can pass over function interfaces are numbers (ints and floats). As a result the permissions communicated between compartments are only communicated statically - you can't pass them dynamically once compartments are linked. So you can convey permission at whatever fine-grain you want by having many different exported functions. You can use procedural abstraction to attenuate permissions, e.g. you can use a function to provide an abstraction of a read-write file as an append-only file. + +Dan: I want to temporarily ignore address spaces and tables: in a world where we have references, does it make sense to talk about compartments still? + +Mark: Current Wasm architecture plus references still has flat address spaces - our current toolchains push us into it, there will still be multiple module instances linked together sharing address spaces. + +Dan: I’m trying to hypothetically see if we take address spaces out of the situation and have wasm gc everywhere, are compartments still relevant? + +Mark: In that hypothetical the Wasm module can use the memory and table space as empty, and Wasm becomes a fine-grained object capability machine. + +Dan: The question that came up on github is that we currently are trying to do much finer grained permissions than the function level. + +Mark: Yes in the hypothetical GC situation you have capabilities that are fine grained at the level of the objects in your programming language + +Dan: How do we bridge the gap between the situation we have now, with these compartments and the failures of granularity associated with that, and where we want to be with GC with finer grained permissions. + +Till: What about the host? (I didn’t follow this close enough for good note taking) + +Mark: There are OCAP languages and operating systems, and research on running OCAP languages on a OCAP operating system with a bridge between the language’s idea of capabilities and the operating system - when you’re writing in the language its as if the operating system’s view of capabilities are just ordinary programming language capabilities. + +Mark: If you design that all interfaces between compartments are designed around reference types, the inter-compartment protocols that are natural to future GC based compartments. + +Mark: Even with reference types, the notion of a virtualizable capability is the natural way to express capabilities in the + +In the Wasm GC machine there’s support for both virtualizable and abstract datatype capabilities, theres no penalty for virtualizable capabilities and its quite natural. In the current world the only way cross-compartment is abstract datatype capabilities. That’s going to be an impedance mismatch. + +Dan: I’d like to steer this back towards what do we do with WASI right now for languages that don't have GC or reference types. Its going to be a long term problem because we’re going to have C/C++ forever. How can we deal with an integer based approach that can approximate reference types in a useful way, at the penalty of being coarser grained? + +Mark: Let’s take very basic C++ as the representative (worst) case. There’s two approaches: one is the approach the Cheri team (University of Cambridge) has taken, they’ve added reference types to existing RISC machine architectures as additional instructions and registers and used that to put protection boundaries inside existing C/C++ code. They built a compiler and LLVM fork that can run in two modes: one mode every C++ pointer is turned into a Cheri capability, at which point you’re treating the Cheri hardware like we’d eventaully do Wasm GC. + +Dan: In Cheri pointers are still bit patterns right? + +Mark: Sort of, in the other compilation mode: in that mode the pointers are still bit patterns that are readable, but the capability gives you a range of addressable memory (which is potentially very fine grained) that is valid to dereference. This is expensive and not really what we’re doing with Wasm GC. + +(at this point i lost the ability to follow and take good notes) + +Dan: Any solution that involves users annotating their source code is going to get a lot of resistance from our users. Any solution where capabilities are held on by a side table and theres bit patterns in the wasm, is better for C compatibility but not the best for actually doing OCAP. Cheri is cool but it doesn't magically solve our problems here yet. + +Mark: A completely different way to approach this issue: Let’s say all your inter-compartment capability interfaces are defined in an IDL, and then we can generate (like capnp) bindings to particular non-capability-based ABIs, so only the code generated from the IDL directly handles the reference types and does the context switch between compartments. All of the C code just uses the C ABI bindings generated by the IDL. Those ABI bindings use integers that require the capabilities be looked up from tables + +Till: A lot of this is actively in the works as the interface types proposal. A lot of these concerns are actively being addressed by how WASI and interface types are developing. The biggest thing is that moving capabilities from being expressed as integers to references, and all compartment interfaces are in terms of reference. Inside a compartment you can do whatever you like. + +Dan: We have an IDL now where we’re moving to talk about APIs in terms of references. At the WASI level we should design in references using OCAP. + +Jacob: In the interface types polyfill we have a way to automate the side-table translation so you don’t have to even generate glue code, its just done in javascript (the host) for you. You can add an interface instruction to convert an index into a ref. This lets us use C without annotations beyond the toolchain knowing about interface types. + +Dan: Next topic: there's a virtualization doc that is coming along, and a paper +http://www.cs.cmu.edu/~aldrich/papers/ecoop17modules.pdf +(summarizes part of paper in way I couldnt follow for notes) + +Dan: Mark’s idea of virtualizatbility is an object with vtables inside them. +(more discussion of the paper) + +Mark: I’ll have to read the paper to understand this fully. + +http://www.cs.cmu.edu/~aldrich/papers/ecoop17modules.pdf + +Mark: Just followed the link, I know this paper. The language in the paper is fine-grained OCAP, individual objects are vtable-like. In that language, there’s still an issue of how you start the world off - a static configuration with good safety properties so you can move forward with dynamic properties. This paper is about the initial permissions with least-authority linkage between the modules. It is in the context of a dynamic system with full fine-grained virtualizability. I don’t see exactly how that addresses our Wasm representation problem, we still cant use references as fine-grained virtualizable capabilities. + +Dan: I think we should table and continue this discussion at a different time. I’d like to go to the rest of the agenda for the remaining 15 mins. + +Dan: What do we call handles, or descriptors? PR 117, or the last comments on issue 62 on file descriptors vs handles. POSIX has called things file descriptors when they're not really files. I want to talk about OCAP capabilities as handles. + +Mark: Historically, descriptors and capabilities are aligned, and the numbers you are familiar with as file descriptors are often just called indices, so clists are the list of capabilities and clist indices are the file descriptor ints you know. + +Dan: We settled more or less on Handle as an identifier that refers to a capability. When we say handles we’re just saying the OCAP sense. Does that make sense? + +Mark: Yes! + +Dan: Let’s call that a decision then. + +Dan: Witx files are up in the repos, you can make a PR into the ephemeral phase and we can then promote that to unstable when a decent number are landed and move on to implementing it. + + +Dan: Moving on to the modularization update: look at PR 98 for the basic change. This wont be the end of the story for modularization, but its a logical first step. + +Sam: Does this change the import field name strings? + +Dan: Yes, right now “wasi\_unstable” is the module name everything imports from. + +Sam: Yes I see that there are N different modules. + +Dan: Does it make sense to limit witx to one module per file? Wat only allows one module per file. + +Pat: We have to figure out how to deal with type names being global, we’ll need some sort of namespacing and import mechanism. + +Dan: Ok, we’ll figure that out and move forward. + +Dan: I put some basic issues in the agenda that are hopefully straightforward to implement. I’d like to encourage more people to step in and make PRs on the witx files and get involved. + +Dan: for example on the issue about using capabilities for randomness, we can propose solutions with PRs that change the witx. diff --git a/proposals/filesystem/meetings/2019/WASI-11-07.md b/proposals/filesystem/meetings/2019/WASI-11-07.md new file mode 100644 index 000000000..b23bb73c7 --- /dev/null +++ b/proposals/filesystem/meetings/2019/WASI-11-07.md @@ -0,0 +1,45 @@ +![WASI logo](/WASI.png) + +## Agenda for the November 24 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: November 24, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Publishing a first snapshot + 1. https://github.com/WebAssembly/WASI/issues/138 + 1. Issues for discussion + 1. Make clocks/random into capabilities + 1. https://github.com/WebAssembly/WASI/issues/118 + 1. Should random continue to be `random_get`, or should it become + `fd_read` from a special stream? + 1. Increase the timestamp range + 1. https://github.com/WebAssembly/WASI/issues/33 + 1. Remove remaining "process" dependencies + 1. https://github.com/WebAssembly/WASI/issues/26 + 1. Remove `CLOCK_PROCESS_CPUTIME_ID`? + +1. Closure + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 9b8689d9f..2988c76ac 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -19,3 +19,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI September 26th video call](2019/WASI-09-26.md) * [WASI October 15th in-person meeting](2019/WASI-10-15.md) * [WASI October 24th video call](2019/WASI-10-24.md) + * [WASI November 7th video call](2019/WASI-11-07.md) From 264e28e875e117729a0c7a7893eb784d2bb09d81 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 21:01:29 -0800 Subject: [PATCH 0268/1772] Correct the return type of `fd_filestat_get`. This fixes the old versions too, as this change reflects current practice. --- .../clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx | 2 +- proposals/clocks/phases/old/witx/wasi_unstable.witx | 2 +- .../clocks/phases/unstable/witx/wasi_unstable_preview0.witx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx index 54aaa0d11..284a1d5e3 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -134,7 +134,7 @@ (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file's attributes are stored. - (result $fs_rights_base $rights_t) + (result $buf $filestat_t) ) ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. diff --git a/proposals/clocks/phases/old/witx/wasi_unstable.witx b/proposals/clocks/phases/old/witx/wasi_unstable.witx index 6ce2f03af..77f5fcb8f 100644 --- a/proposals/clocks/phases/old/witx/wasi_unstable.witx +++ b/proposals/clocks/phases/old/witx/wasi_unstable.witx @@ -137,7 +137,7 @@ (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file's attributes are stored. - (result $fs_rights_base $rights_t) + (result $buf $filestat_t) ) ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. diff --git a/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx index e6c4c67aa..598ff9f9d 100644 --- a/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx @@ -134,7 +134,7 @@ (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file's attributes are stored. - (result $fs_rights_base $rights_t) + (result $buf $filestat_t) ) ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. From 2c2fcd5b8b1641401c4d6a4a749793626db53bfd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 21:01:29 -0800 Subject: [PATCH 0269/1772] Correct the return type of `fd_filestat_get`. This fixes the old versions too, as this change reflects current practice. --- .../random/phases/ephemeral/witx/wasi_ephemeral_preview.witx | 2 +- proposals/random/phases/old/witx/wasi_unstable.witx | 2 +- .../random/phases/unstable/witx/wasi_unstable_preview0.witx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx index 54aaa0d11..284a1d5e3 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -134,7 +134,7 @@ (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file's attributes are stored. - (result $fs_rights_base $rights_t) + (result $buf $filestat_t) ) ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. diff --git a/proposals/random/phases/old/witx/wasi_unstable.witx b/proposals/random/phases/old/witx/wasi_unstable.witx index 6ce2f03af..77f5fcb8f 100644 --- a/proposals/random/phases/old/witx/wasi_unstable.witx +++ b/proposals/random/phases/old/witx/wasi_unstable.witx @@ -137,7 +137,7 @@ (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file's attributes are stored. - (result $fs_rights_base $rights_t) + (result $buf $filestat_t) ) ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. diff --git a/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx index e6c4c67aa..598ff9f9d 100644 --- a/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx @@ -134,7 +134,7 @@ (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file's attributes are stored. - (result $fs_rights_base $rights_t) + (result $buf $filestat_t) ) ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. From eec79cf974cf9c86cbe1f65020cd44f3a34531e2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 21:01:29 -0800 Subject: [PATCH 0270/1772] Correct the return type of `fd_filestat_get`. This fixes the old versions too, as this change reflects current practice. --- .../phases/ephemeral/witx/wasi_ephemeral_preview.witx | 2 +- proposals/filesystem/phases/old/witx/wasi_unstable.witx | 2 +- .../filesystem/phases/unstable/witx/wasi_unstable_preview0.witx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx index 54aaa0d11..284a1d5e3 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -134,7 +134,7 @@ (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file's attributes are stored. - (result $fs_rights_base $rights_t) + (result $buf $filestat_t) ) ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. diff --git a/proposals/filesystem/phases/old/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/witx/wasi_unstable.witx index 6ce2f03af..77f5fcb8f 100644 --- a/proposals/filesystem/phases/old/witx/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/witx/wasi_unstable.witx @@ -137,7 +137,7 @@ (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file's attributes are stored. - (result $fs_rights_base $rights_t) + (result $buf $filestat_t) ) ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. diff --git a/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx index e6c4c67aa..598ff9f9d 100644 --- a/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx @@ -134,7 +134,7 @@ (param $fd $fd_t) (result $error $errno_t) ;; The buffer where the file's attributes are stored. - (result $fs_rights_base $rights_t) + (result $buf $filestat_t) ) ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. From 9451ac6121d0aa58824cd58f1e8aa23f1a58c5ce Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 5 Nov 2019 15:22:36 -0800 Subject: [PATCH 0271/1772] * witx: bump to version 0.4.0 --- proposals/clocks/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 90a2b48b5..909e0a690 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.3.1" +version = "0.4.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From cb8dfebe8cdfb2c6ad893a73b587a31dd825feab Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 5 Nov 2019 15:22:36 -0800 Subject: [PATCH 0272/1772] * witx: bump to version 0.4.0 --- proposals/random/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 90a2b48b5..909e0a690 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.3.1" +version = "0.4.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From f24054d7f55ab6e45f2d880a03c8bc8fbe0a3cfd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 5 Nov 2019 15:22:36 -0800 Subject: [PATCH 0273/1772] * witx: bump to version 0.4.0 --- proposals/filesystem/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 90a2b48b5..909e0a690 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.3.1" +version = "0.4.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 55d30cfc88f4d72eaad53129b25afb3b71e28ddf Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 6 Nov 2019 13:00:58 -0800 Subject: [PATCH 0274/1772] witx: convert from 0-indexed line and col to 1-indexed (#143) * witx: convert from 0-indexed line and col to 1-indexed * rustfmt * fix missed column + 1 --- proposals/clocks/tools/witx/src/validate.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index df11c521c..a0d9ea96b 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -139,10 +139,11 @@ impl DocValidation { impl DocValidationScope<'_> { fn location(&self, span: wast::Span) -> Location { + // Wast Span gives 0-indexed lines and columns. Location is 1-indexed. let (line, column) = span.linecol_in(self.text); Location { - line, - column, + line: line + 1, + column: column + 1, path: self.path.to_path_buf(), } } From 1d129ac2f4e4bdc48f11664b8ebd5c0b89970a12 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 6 Nov 2019 13:00:58 -0800 Subject: [PATCH 0275/1772] witx: convert from 0-indexed line and col to 1-indexed (#143) * witx: convert from 0-indexed line and col to 1-indexed * rustfmt * fix missed column + 1 --- proposals/random/tools/witx/src/validate.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index df11c521c..a0d9ea96b 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -139,10 +139,11 @@ impl DocValidation { impl DocValidationScope<'_> { fn location(&self, span: wast::Span) -> Location { + // Wast Span gives 0-indexed lines and columns. Location is 1-indexed. let (line, column) = span.linecol_in(self.text); Location { - line, - column, + line: line + 1, + column: column + 1, path: self.path.to_path_buf(), } } From 797c72c8cec461513160848688716d8b212ef334 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 6 Nov 2019 13:00:58 -0800 Subject: [PATCH 0276/1772] witx: convert from 0-indexed line and col to 1-indexed (#143) * witx: convert from 0-indexed line and col to 1-indexed * rustfmt * fix missed column + 1 --- proposals/filesystem/tools/witx/src/validate.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index df11c521c..a0d9ea96b 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -139,10 +139,11 @@ impl DocValidation { impl DocValidationScope<'_> { fn location(&self, span: wast::Span) -> Location { + // Wast Span gives 0-indexed lines and columns. Location is 1-indexed. let (line, column) = span.linecol_in(self.text); Location { - line, - column, + line: line + 1, + column: column + 1, path: self.path.to_path_buf(), } } From b552b11a647a2923d21d6e32b0d4c58a42f5d2d8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 6 Nov 2019 14:49:45 -0800 Subject: [PATCH 0277/1772] Fix old definition of `path_symlink` This fixes the `*.witx` for the old definition of `path_symlink` to ensure that the `old_path` argument comes first. --- .../clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx | 2 +- proposals/clocks/phases/old/witx/wasi_unstable.witx | 2 +- .../clocks/phases/unstable/witx/wasi_unstable_preview0.witx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx index 284a1d5e3..f98ff129b 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -420,9 +420,9 @@ ;; Create a symbolic link. ;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - (param $fd $fd_t) ;; The contents of the symbolic link. (param $old_path string) + (param $fd $fd_t) ;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) diff --git a/proposals/clocks/phases/old/witx/wasi_unstable.witx b/proposals/clocks/phases/old/witx/wasi_unstable.witx index 77f5fcb8f..74bce70c6 100644 --- a/proposals/clocks/phases/old/witx/wasi_unstable.witx +++ b/proposals/clocks/phases/old/witx/wasi_unstable.witx @@ -423,9 +423,9 @@ ;; Create a symbolic link. ;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - (param $fd $fd_t) ;; The contents of the symbolic link. (param $old_path string) + (param $fd $fd_t) ;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) diff --git a/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx index 598ff9f9d..d5686dabb 100644 --- a/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx @@ -420,9 +420,9 @@ ;; Create a symbolic link. ;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - (param $fd $fd_t) ;; The contents of the symbolic link. (param $old_path string) + (param $fd $fd_t) ;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) From 1ede476511baf8761dc69b017f47e476328f1d7b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 6 Nov 2019 14:49:45 -0800 Subject: [PATCH 0278/1772] Fix old definition of `path_symlink` This fixes the `*.witx` for the old definition of `path_symlink` to ensure that the `old_path` argument comes first. --- .../random/phases/ephemeral/witx/wasi_ephemeral_preview.witx | 2 +- proposals/random/phases/old/witx/wasi_unstable.witx | 2 +- .../random/phases/unstable/witx/wasi_unstable_preview0.witx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx index 284a1d5e3..f98ff129b 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -420,9 +420,9 @@ ;; Create a symbolic link. ;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - (param $fd $fd_t) ;; The contents of the symbolic link. (param $old_path string) + (param $fd $fd_t) ;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) diff --git a/proposals/random/phases/old/witx/wasi_unstable.witx b/proposals/random/phases/old/witx/wasi_unstable.witx index 77f5fcb8f..74bce70c6 100644 --- a/proposals/random/phases/old/witx/wasi_unstable.witx +++ b/proposals/random/phases/old/witx/wasi_unstable.witx @@ -423,9 +423,9 @@ ;; Create a symbolic link. ;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - (param $fd $fd_t) ;; The contents of the symbolic link. (param $old_path string) + (param $fd $fd_t) ;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) diff --git a/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx index 598ff9f9d..d5686dabb 100644 --- a/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx @@ -420,9 +420,9 @@ ;; Create a symbolic link. ;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - (param $fd $fd_t) ;; The contents of the symbolic link. (param $old_path string) + (param $fd $fd_t) ;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) From 208453afa715988d4695b7842db5533c533f4511 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 6 Nov 2019 14:49:45 -0800 Subject: [PATCH 0279/1772] Fix old definition of `path_symlink` This fixes the `*.witx` for the old definition of `path_symlink` to ensure that the `old_path` argument comes first. --- .../phases/ephemeral/witx/wasi_ephemeral_preview.witx | 2 +- proposals/filesystem/phases/old/witx/wasi_unstable.witx | 2 +- .../filesystem/phases/unstable/witx/wasi_unstable_preview0.witx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx index 284a1d5e3..f98ff129b 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -420,9 +420,9 @@ ;; Create a symbolic link. ;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - (param $fd $fd_t) ;; The contents of the symbolic link. (param $old_path string) + (param $fd $fd_t) ;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) diff --git a/proposals/filesystem/phases/old/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/witx/wasi_unstable.witx index 77f5fcb8f..74bce70c6 100644 --- a/proposals/filesystem/phases/old/witx/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/witx/wasi_unstable.witx @@ -423,9 +423,9 @@ ;; Create a symbolic link. ;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - (param $fd $fd_t) ;; The contents of the symbolic link. (param $old_path string) + (param $fd $fd_t) ;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) diff --git a/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx index 598ff9f9d..d5686dabb 100644 --- a/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx @@ -420,9 +420,9 @@ ;; Create a symbolic link. ;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - (param $fd $fd_t) ;; The contents of the symbolic link. (param $old_path string) + (param $fd $fd_t) ;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) From 37a8959ded1c9e8ca4de2721786de589d21aa89d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 8 Nov 2019 12:33:43 -0800 Subject: [PATCH 0280/1772] Add a basic .gitignore file for working with Rust code. --- proposals/clocks/.gitignore | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 proposals/clocks/.gitignore diff --git a/proposals/clocks/.gitignore b/proposals/clocks/.gitignore new file mode 100644 index 000000000..c0476d12f --- /dev/null +++ b/proposals/clocks/.gitignore @@ -0,0 +1,11 @@ +*.bk +*.swp +*.swo +*.swx +tags +target +Cargo.lock +.*.rustfmt +rusty-tags.* +*~ +\#*\# From d41b0a9c7200091f1062be024bfa8128e80a41f9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 8 Nov 2019 12:33:43 -0800 Subject: [PATCH 0281/1772] Add a basic .gitignore file for working with Rust code. --- proposals/random/.gitignore | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 proposals/random/.gitignore diff --git a/proposals/random/.gitignore b/proposals/random/.gitignore new file mode 100644 index 000000000..c0476d12f --- /dev/null +++ b/proposals/random/.gitignore @@ -0,0 +1,11 @@ +*.bk +*.swp +*.swo +*.swx +tags +target +Cargo.lock +.*.rustfmt +rusty-tags.* +*~ +\#*\# From 038d1535c7c593ed38485cf2525245cb0623f53c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 8 Nov 2019 12:33:43 -0800 Subject: [PATCH 0282/1772] Add a basic .gitignore file for working with Rust code. --- proposals/filesystem/.gitignore | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 proposals/filesystem/.gitignore diff --git a/proposals/filesystem/.gitignore b/proposals/filesystem/.gitignore new file mode 100644 index 000000000..c0476d12f --- /dev/null +++ b/proposals/filesystem/.gitignore @@ -0,0 +1,11 @@ +*.bk +*.swp +*.swo +*.swx +tags +target +Cargo.lock +.*.rustfmt +rusty-tags.* +*~ +\#*\# From 15dbd2e2e08aad295fe9a869b7f3f3b20b0670f1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 8 Nov 2019 12:34:29 -0800 Subject: [PATCH 0283/1772] Add a `keywords` field to witx's Cargo.toml --- proposals/clocks/tools/witx/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 909e0a690..f25555c0f 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -6,6 +6,7 @@ homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" license = "Apache-2.0" categories = ["wasm"] +keywords = ["webassembly", "wasm"] authors = ["Pat Hickey ", "Alex Crichton "] edition = "2018" From 3a49aed2d16b0403e5dc703e169cccd3ca3d01c0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 8 Nov 2019 12:34:29 -0800 Subject: [PATCH 0284/1772] Add a `keywords` field to witx's Cargo.toml --- proposals/random/tools/witx/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 909e0a690..f25555c0f 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -6,6 +6,7 @@ homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" license = "Apache-2.0" categories = ["wasm"] +keywords = ["webassembly", "wasm"] authors = ["Pat Hickey ", "Alex Crichton "] edition = "2018" From 2f79ac1eecf69f7ada0ba1e661221c3e65b56e39 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 8 Nov 2019 12:34:29 -0800 Subject: [PATCH 0285/1772] Add a `keywords` field to witx's Cargo.toml --- proposals/filesystem/tools/witx/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 909e0a690..f25555c0f 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -6,6 +6,7 @@ homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" license = "Apache-2.0" categories = ["wasm"] +keywords = ["webassembly", "wasm"] authors = ["Pat Hickey ", "Alex Crichton "] edition = "2018" From d6d30112de9ef28c777b50ecce07dc946f331b5a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 16:10:15 -0800 Subject: [PATCH 0286/1772] Create snapshot 1 (#147) * archive: contents of `old` moved underneath `snapshot_0` The contents of `old` are identical to the current `unstable/wasi_unstable_preview0` in every sense except the name of the module and file. So, for this snapshotting, rather than move the contents of the current "unstable" (which will be renamed "snapshot" as part of this PR) under a new directory under phases/old, we're just moving the current contents under a directory, so that future snapshots can be archived without changing these paths. * delete current unstable (snapshot), rather than move it under old. Special case of this first-time snapshotting process. * copy phases/ephemeral/* into phases/snapshot/ * rename files in snapshot to snapshot_preview1 * update phases/README to rename `unstable` to `snapshot` Per https://github.com/WebAssembly/WASI/issues/138 and discussion on 07nov19 wasi video call. Updates the steps for PR based on what I did for this first snapshot. * witx: tests point at newly snapshotted and archived witx specs and the test file gets renamed to just regular wasi.rs * fixes in phases readme per dan's code review --- proposals/clocks/phases/README.md | 28 ++++++++++++------- .../{ => snapshot_0}/docs/wasi_unstable.md | 0 .../old/{ => snapshot_0}/witx/typenames.witx | 0 .../{ => snapshot_0}/witx/wasi_unstable.witx | 0 .../docs/wasi_unstable_preview1.md} | 28 ++++++++++++------- .../witx/typenames.witx | 10 +++---- .../witx/wasi_snapshot_preview1.witx} | 2 +- .../witx/tests/{wasi_unstable.rs => wasi.rs} | 16 ++++++----- 8 files changed, 51 insertions(+), 33 deletions(-) rename proposals/clocks/phases/old/{ => snapshot_0}/docs/wasi_unstable.md (100%) rename proposals/clocks/phases/old/{ => snapshot_0}/witx/typenames.witx (100%) rename proposals/clocks/phases/old/{ => snapshot_0}/witx/wasi_unstable.witx (100%) rename proposals/clocks/phases/{unstable/docs/wasi_unstable_preview0.md => snapshot/docs/wasi_unstable_preview1.md} (98%) rename proposals/clocks/phases/{unstable => snapshot}/witx/typenames.witx (99%) rename proposals/clocks/phases/{unstable/witx/wasi_unstable_preview0.witx => snapshot/witx/wasi_snapshot_preview1.witx} (99%) rename proposals/clocks/tools/witx/tests/{wasi_unstable.rs => wasi.rs} (65%) diff --git a/proposals/clocks/phases/README.md b/proposals/clocks/phases/README.md index 53cb649bb..86f5fb4ba 100644 --- a/proposals/clocks/phases/README.md +++ b/proposals/clocks/phases/README.md @@ -8,24 +8,32 @@ provides no API stability or versioning. APIs in this directory use API module names starting with `wasi_ephemeral_`. -- [`unstable`](unstable): Usable APIs. APIs in `ephemeral` will be - occasionally snapshotted and promoted into `unstable`, with approval +- [`snapshot`](snapshot): Usable APIs. APIs in `ephemeral` will be + occasionally snapshotted and promoted into `snapshot`, with approval from the Subgroup, considering the overall suitability of the APIs themselves, their documentation, test coverage, and availability of polyfills when appropriate. Once merged, the API modules will be considered stable, though they may be superseded by newer versions. Proposals to promote specific APIs should be submitted as Pull Requests that: - - Move any superseded files out of `unstable` into `old`. - - Optionally add polyfills for superseded APIs using `unstable` APIs. - - Move all files supporting the APIs out of `ephemeral` into `unstable`. - - Rename the API modules from `wasi_ephemeral_` to `wasi_unstable_` - and append a version number. + 1. `git mv` contents of `phases/snapshot/` to + `phases/old/snapshot_{old_snapshot_number}`. + 2. `cp -R` contents of `phases/ephemeral/` into `phases/snapshot/`. + 3. Rename files copied into `phases/snapshot/` to substitute `ephemeral` + for `snapshot` in file names. Append the new snapshot number to each + name. + 4. Update module names given in `.witx` files according to the previous + step. + 5. Update tests in `tools/witx/tests/wasi.rs` to point at new snapshot, and + add a test pointing at the just-archived snapshot under `old`. + 6. Optionally, under `phases/old/snapshot_{old_snapshot_number}, add + polyfills for superceded APIs using the new APIs. + Pull Requests may also add additional tests, documentation, or - polyfills for existing `unstable` APIs. + polyfills for existing `snapshot` APIs. -- [`old`](old): When APIs in `current` spec are replaced by new +- [`old`](old): When APIs in `snapshot` spec are replaced by new versions, the old API modules are moved to the `old` directory. When possible, `old` APIs may be accompanied by polyfill modules which implement their API in terms of newer versions of the API. @@ -44,7 +52,7 @@ flexibility. WASI should eventually become a standard at the level of WebAssembly itself. Right now, it needs a lot of work before it's ready. The -`unstable` tree is meant to serve a practical purpose for people who +`snapshot` tree is meant to serve a practical purpose for people who want to work with APIs today, with the understanding that everything is still evolving. It's not meant as a replacement for proper standardization, which will happen once the overall API is more diff --git a/proposals/clocks/phases/old/docs/wasi_unstable.md b/proposals/clocks/phases/old/snapshot_0/docs/wasi_unstable.md similarity index 100% rename from proposals/clocks/phases/old/docs/wasi_unstable.md rename to proposals/clocks/phases/old/snapshot_0/docs/wasi_unstable.md diff --git a/proposals/clocks/phases/old/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx similarity index 100% rename from proposals/clocks/phases/old/witx/typenames.witx rename to proposals/clocks/phases/old/snapshot_0/witx/typenames.witx diff --git a/proposals/clocks/phases/old/witx/wasi_unstable.witx b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx similarity index 100% rename from proposals/clocks/phases/old/witx/wasi_unstable.witx rename to proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx diff --git a/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md similarity index 98% rename from proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md rename to proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md index 2464f2342..6de15f1d2 100644 --- a/proposals/clocks/phases/unstable/docs/wasi_unstable_preview0.md +++ b/proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md @@ -117,18 +117,22 @@ modules so that embedders need not implement all of it. Read command-line argument data. -The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - Inputs: - char \*\*argv A pointer to a buffer to write the argument pointers. + The count of elements for the buffer should be at least the value of `argc` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + + The caller of `__wasi_args_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. + - char \*argv\_buf A pointer to a buffer to write the argument string data. + The size of this buffer should be the value of `argv_buf_size` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + ### `__wasi_args_sizes_get()` Return command-line argument data sizes. @@ -192,21 +196,25 @@ Outputs: Read environment variable data. -The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - Inputs: - char \*\*environ A pointer to a buffer to write the environment variable pointers. + The count of elements for the buffer should be at least the value of `environ_count` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + + The caller of `__wasi_environ_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. + - char \*environ\_buf A pointer to a buffer to write the environment variable string data. + The size of this buffer should be the value of `environ_buf_size` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + ### `__wasi_environ_sizes_get()` -Return command-line argument data sizes. +Return enviroment variable data sizes. Outputs: @@ -1799,7 +1807,7 @@ Members: The address and length of the buffer to be filled. -### `__wasi_linkcount_t` (`uint32_t`) +### `__wasi_linkcount_t` (`uint64_t`) Number of hard links to an inode. @@ -2329,6 +2337,10 @@ Used by [`__wasi_fd_seek()`](#fd_seek). Possible values: +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + - **`__WASI_WHENCE_CUR`** Seek relative to current position. @@ -2337,7 +2349,3 @@ Possible values: Seek relative to end-of-file. -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - diff --git a/proposals/clocks/phases/unstable/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx similarity index 99% rename from proposals/clocks/phases/unstable/witx/typenames.witx rename to proposals/clocks/phases/snapshot/witx/typenames.witx index 15b53af51..1a45be1fd 100644 --- a/proposals/clocks/phases/unstable/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -305,16 +305,18 @@ ;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 + ;; Seek relative to start-of-file. + $WHENCE_SET ;; Seek relative to current position. $WHENCE_CUR ;; Seek relative to end-of-file. $WHENCE_END - ;; Seek relative to start-of-file. - $WHENCE_SET ) ) ;; A reference to the offset of a directory entry. +;; +;; The value 0 signifies the start of the directory. (typename $dircookie_t u64) ;; The type for the $d_namlen field of $dirent_t. @@ -451,7 +453,7 @@ ) ;; Number of hard links to an inode. -(typename $linkcount_t u32) +(typename $linkcount_t u64) ;; File attributes. (typename $filestat_t @@ -552,8 +554,6 @@ ;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) ;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) ;; The absolute or relative timestamp. diff --git a/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx similarity index 99% rename from proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx rename to proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx index d5686dabb..630537416 100644 --- a/proposals/clocks/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -8,7 +8,7 @@ (use "typenames.witx") -(module $wasi_unstable_preview0 +(module $wasi_snapshot_preview1 ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) diff --git a/proposals/clocks/tools/witx/tests/wasi_unstable.rs b/proposals/clocks/tools/witx/tests/wasi.rs similarity index 65% rename from proposals/clocks/tools/witx/tests/wasi_unstable.rs rename to proposals/clocks/tools/witx/tests/wasi.rs index 68e65186a..2b2566997 100644 --- a/proposals/clocks/tools/witx/tests/wasi_unstable.rs +++ b/proposals/clocks/tools/witx/tests/wasi.rs @@ -2,15 +2,15 @@ use std::path::Path; use witx; #[test] -fn validate_wasi_unstable_preview0() { +fn validate_wasi_snapshot() { witx::load(Path::new( - "../../phases/unstable/witx/wasi_unstable_preview0.witx", + "../../phases/snapshot/witx/wasi_snapshot_preview1.witx", )) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] -fn validate_wasi_ephemeral_preview() { +fn validate_wasi_ephemeral() { witx::load(Path::new( "../../phases/ephemeral/witx/wasi_ephemeral_preview.witx", )) @@ -18,15 +18,17 @@ fn validate_wasi_ephemeral_preview() { } #[test] -fn validate_wasi_old_preview0() { - witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); +fn validate_wasi_old_snapshot_0() { + witx::load(Path::new( + "../../phases/old/snapshot_0/witx/wasi_unstable.witx", + )) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn render_roundtrip() { let doc = witx::load(Path::new( - "../../phases/unstable/witx/wasi_unstable_preview0.witx", + "../../phases/snapshot/witx/wasi_snapshot_preview1.witx", )) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); From 068ea6d909a3e408dd99754364bd6900c3c35fbc Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 16:10:15 -0800 Subject: [PATCH 0287/1772] Create snapshot 1 (#147) * archive: contents of `old` moved underneath `snapshot_0` The contents of `old` are identical to the current `unstable/wasi_unstable_preview0` in every sense except the name of the module and file. So, for this snapshotting, rather than move the contents of the current "unstable" (which will be renamed "snapshot" as part of this PR) under a new directory under phases/old, we're just moving the current contents under a directory, so that future snapshots can be archived without changing these paths. * delete current unstable (snapshot), rather than move it under old. Special case of this first-time snapshotting process. * copy phases/ephemeral/* into phases/snapshot/ * rename files in snapshot to snapshot_preview1 * update phases/README to rename `unstable` to `snapshot` Per https://github.com/WebAssembly/WASI/issues/138 and discussion on 07nov19 wasi video call. Updates the steps for PR based on what I did for this first snapshot. * witx: tests point at newly snapshotted and archived witx specs and the test file gets renamed to just regular wasi.rs * fixes in phases readme per dan's code review --- proposals/random/phases/README.md | 28 ++++++++++++------- .../{ => snapshot_0}/docs/wasi_unstable.md | 0 .../old/{ => snapshot_0}/witx/typenames.witx | 0 .../{ => snapshot_0}/witx/wasi_unstable.witx | 0 .../docs/wasi_unstable_preview1.md} | 28 ++++++++++++------- .../witx/typenames.witx | 10 +++---- .../witx/wasi_snapshot_preview1.witx} | 2 +- .../witx/tests/{wasi_unstable.rs => wasi.rs} | 16 ++++++----- 8 files changed, 51 insertions(+), 33 deletions(-) rename proposals/random/phases/old/{ => snapshot_0}/docs/wasi_unstable.md (100%) rename proposals/random/phases/old/{ => snapshot_0}/witx/typenames.witx (100%) rename proposals/random/phases/old/{ => snapshot_0}/witx/wasi_unstable.witx (100%) rename proposals/random/phases/{unstable/docs/wasi_unstable_preview0.md => snapshot/docs/wasi_unstable_preview1.md} (98%) rename proposals/random/phases/{unstable => snapshot}/witx/typenames.witx (99%) rename proposals/random/phases/{unstable/witx/wasi_unstable_preview0.witx => snapshot/witx/wasi_snapshot_preview1.witx} (99%) rename proposals/random/tools/witx/tests/{wasi_unstable.rs => wasi.rs} (65%) diff --git a/proposals/random/phases/README.md b/proposals/random/phases/README.md index 53cb649bb..86f5fb4ba 100644 --- a/proposals/random/phases/README.md +++ b/proposals/random/phases/README.md @@ -8,24 +8,32 @@ provides no API stability or versioning. APIs in this directory use API module names starting with `wasi_ephemeral_`. -- [`unstable`](unstable): Usable APIs. APIs in `ephemeral` will be - occasionally snapshotted and promoted into `unstable`, with approval +- [`snapshot`](snapshot): Usable APIs. APIs in `ephemeral` will be + occasionally snapshotted and promoted into `snapshot`, with approval from the Subgroup, considering the overall suitability of the APIs themselves, their documentation, test coverage, and availability of polyfills when appropriate. Once merged, the API modules will be considered stable, though they may be superseded by newer versions. Proposals to promote specific APIs should be submitted as Pull Requests that: - - Move any superseded files out of `unstable` into `old`. - - Optionally add polyfills for superseded APIs using `unstable` APIs. - - Move all files supporting the APIs out of `ephemeral` into `unstable`. - - Rename the API modules from `wasi_ephemeral_` to `wasi_unstable_` - and append a version number. + 1. `git mv` contents of `phases/snapshot/` to + `phases/old/snapshot_{old_snapshot_number}`. + 2. `cp -R` contents of `phases/ephemeral/` into `phases/snapshot/`. + 3. Rename files copied into `phases/snapshot/` to substitute `ephemeral` + for `snapshot` in file names. Append the new snapshot number to each + name. + 4. Update module names given in `.witx` files according to the previous + step. + 5. Update tests in `tools/witx/tests/wasi.rs` to point at new snapshot, and + add a test pointing at the just-archived snapshot under `old`. + 6. Optionally, under `phases/old/snapshot_{old_snapshot_number}, add + polyfills for superceded APIs using the new APIs. + Pull Requests may also add additional tests, documentation, or - polyfills for existing `unstable` APIs. + polyfills for existing `snapshot` APIs. -- [`old`](old): When APIs in `current` spec are replaced by new +- [`old`](old): When APIs in `snapshot` spec are replaced by new versions, the old API modules are moved to the `old` directory. When possible, `old` APIs may be accompanied by polyfill modules which implement their API in terms of newer versions of the API. @@ -44,7 +52,7 @@ flexibility. WASI should eventually become a standard at the level of WebAssembly itself. Right now, it needs a lot of work before it's ready. The -`unstable` tree is meant to serve a practical purpose for people who +`snapshot` tree is meant to serve a practical purpose for people who want to work with APIs today, with the understanding that everything is still evolving. It's not meant as a replacement for proper standardization, which will happen once the overall API is more diff --git a/proposals/random/phases/old/docs/wasi_unstable.md b/proposals/random/phases/old/snapshot_0/docs/wasi_unstable.md similarity index 100% rename from proposals/random/phases/old/docs/wasi_unstable.md rename to proposals/random/phases/old/snapshot_0/docs/wasi_unstable.md diff --git a/proposals/random/phases/old/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx similarity index 100% rename from proposals/random/phases/old/witx/typenames.witx rename to proposals/random/phases/old/snapshot_0/witx/typenames.witx diff --git a/proposals/random/phases/old/witx/wasi_unstable.witx b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx similarity index 100% rename from proposals/random/phases/old/witx/wasi_unstable.witx rename to proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx diff --git a/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md similarity index 98% rename from proposals/random/phases/unstable/docs/wasi_unstable_preview0.md rename to proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md index 2464f2342..6de15f1d2 100644 --- a/proposals/random/phases/unstable/docs/wasi_unstable_preview0.md +++ b/proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md @@ -117,18 +117,22 @@ modules so that embedders need not implement all of it. Read command-line argument data. -The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - Inputs: - char \*\*argv A pointer to a buffer to write the argument pointers. + The count of elements for the buffer should be at least the value of `argc` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + + The caller of `__wasi_args_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. + - char \*argv\_buf A pointer to a buffer to write the argument string data. + The size of this buffer should be the value of `argv_buf_size` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + ### `__wasi_args_sizes_get()` Return command-line argument data sizes. @@ -192,21 +196,25 @@ Outputs: Read environment variable data. -The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - Inputs: - char \*\*environ A pointer to a buffer to write the environment variable pointers. + The count of elements for the buffer should be at least the value of `environ_count` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + + The caller of `__wasi_environ_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. + - char \*environ\_buf A pointer to a buffer to write the environment variable string data. + The size of this buffer should be the value of `environ_buf_size` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + ### `__wasi_environ_sizes_get()` -Return command-line argument data sizes. +Return enviroment variable data sizes. Outputs: @@ -1799,7 +1807,7 @@ Members: The address and length of the buffer to be filled. -### `__wasi_linkcount_t` (`uint32_t`) +### `__wasi_linkcount_t` (`uint64_t`) Number of hard links to an inode. @@ -2329,6 +2337,10 @@ Used by [`__wasi_fd_seek()`](#fd_seek). Possible values: +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + - **`__WASI_WHENCE_CUR`** Seek relative to current position. @@ -2337,7 +2349,3 @@ Possible values: Seek relative to end-of-file. -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - diff --git a/proposals/random/phases/unstable/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx similarity index 99% rename from proposals/random/phases/unstable/witx/typenames.witx rename to proposals/random/phases/snapshot/witx/typenames.witx index 15b53af51..1a45be1fd 100644 --- a/proposals/random/phases/unstable/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -305,16 +305,18 @@ ;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 + ;; Seek relative to start-of-file. + $WHENCE_SET ;; Seek relative to current position. $WHENCE_CUR ;; Seek relative to end-of-file. $WHENCE_END - ;; Seek relative to start-of-file. - $WHENCE_SET ) ) ;; A reference to the offset of a directory entry. +;; +;; The value 0 signifies the start of the directory. (typename $dircookie_t u64) ;; The type for the $d_namlen field of $dirent_t. @@ -451,7 +453,7 @@ ) ;; Number of hard links to an inode. -(typename $linkcount_t u32) +(typename $linkcount_t u64) ;; File attributes. (typename $filestat_t @@ -552,8 +554,6 @@ ;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) ;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) ;; The absolute or relative timestamp. diff --git a/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx similarity index 99% rename from proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx rename to proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx index d5686dabb..630537416 100644 --- a/proposals/random/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -8,7 +8,7 @@ (use "typenames.witx") -(module $wasi_unstable_preview0 +(module $wasi_snapshot_preview1 ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) diff --git a/proposals/random/tools/witx/tests/wasi_unstable.rs b/proposals/random/tools/witx/tests/wasi.rs similarity index 65% rename from proposals/random/tools/witx/tests/wasi_unstable.rs rename to proposals/random/tools/witx/tests/wasi.rs index 68e65186a..2b2566997 100644 --- a/proposals/random/tools/witx/tests/wasi_unstable.rs +++ b/proposals/random/tools/witx/tests/wasi.rs @@ -2,15 +2,15 @@ use std::path::Path; use witx; #[test] -fn validate_wasi_unstable_preview0() { +fn validate_wasi_snapshot() { witx::load(Path::new( - "../../phases/unstable/witx/wasi_unstable_preview0.witx", + "../../phases/snapshot/witx/wasi_snapshot_preview1.witx", )) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] -fn validate_wasi_ephemeral_preview() { +fn validate_wasi_ephemeral() { witx::load(Path::new( "../../phases/ephemeral/witx/wasi_ephemeral_preview.witx", )) @@ -18,15 +18,17 @@ fn validate_wasi_ephemeral_preview() { } #[test] -fn validate_wasi_old_preview0() { - witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); +fn validate_wasi_old_snapshot_0() { + witx::load(Path::new( + "../../phases/old/snapshot_0/witx/wasi_unstable.witx", + )) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn render_roundtrip() { let doc = witx::load(Path::new( - "../../phases/unstable/witx/wasi_unstable_preview0.witx", + "../../phases/snapshot/witx/wasi_snapshot_preview1.witx", )) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); From a50c9c9cf2ef21f25ffb6984531a3bcb2d317bce Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 16:10:15 -0800 Subject: [PATCH 0288/1772] Create snapshot 1 (#147) * archive: contents of `old` moved underneath `snapshot_0` The contents of `old` are identical to the current `unstable/wasi_unstable_preview0` in every sense except the name of the module and file. So, for this snapshotting, rather than move the contents of the current "unstable" (which will be renamed "snapshot" as part of this PR) under a new directory under phases/old, we're just moving the current contents under a directory, so that future snapshots can be archived without changing these paths. * delete current unstable (snapshot), rather than move it under old. Special case of this first-time snapshotting process. * copy phases/ephemeral/* into phases/snapshot/ * rename files in snapshot to snapshot_preview1 * update phases/README to rename `unstable` to `snapshot` Per https://github.com/WebAssembly/WASI/issues/138 and discussion on 07nov19 wasi video call. Updates the steps for PR based on what I did for this first snapshot. * witx: tests point at newly snapshotted and archived witx specs and the test file gets renamed to just regular wasi.rs * fixes in phases readme per dan's code review --- proposals/filesystem/phases/README.md | 28 ++++++++++++------- .../{ => snapshot_0}/docs/wasi_unstable.md | 0 .../old/{ => snapshot_0}/witx/typenames.witx | 0 .../{ => snapshot_0}/witx/wasi_unstable.witx | 0 .../docs/wasi_unstable_preview1.md} | 28 ++++++++++++------- .../witx/typenames.witx | 10 +++---- .../witx/wasi_snapshot_preview1.witx} | 2 +- .../witx/tests/{wasi_unstable.rs => wasi.rs} | 16 ++++++----- 8 files changed, 51 insertions(+), 33 deletions(-) rename proposals/filesystem/phases/old/{ => snapshot_0}/docs/wasi_unstable.md (100%) rename proposals/filesystem/phases/old/{ => snapshot_0}/witx/typenames.witx (100%) rename proposals/filesystem/phases/old/{ => snapshot_0}/witx/wasi_unstable.witx (100%) rename proposals/filesystem/phases/{unstable/docs/wasi_unstable_preview0.md => snapshot/docs/wasi_unstable_preview1.md} (98%) rename proposals/filesystem/phases/{unstable => snapshot}/witx/typenames.witx (99%) rename proposals/filesystem/phases/{unstable/witx/wasi_unstable_preview0.witx => snapshot/witx/wasi_snapshot_preview1.witx} (99%) rename proposals/filesystem/tools/witx/tests/{wasi_unstable.rs => wasi.rs} (65%) diff --git a/proposals/filesystem/phases/README.md b/proposals/filesystem/phases/README.md index 53cb649bb..86f5fb4ba 100644 --- a/proposals/filesystem/phases/README.md +++ b/proposals/filesystem/phases/README.md @@ -8,24 +8,32 @@ provides no API stability or versioning. APIs in this directory use API module names starting with `wasi_ephemeral_`. -- [`unstable`](unstable): Usable APIs. APIs in `ephemeral` will be - occasionally snapshotted and promoted into `unstable`, with approval +- [`snapshot`](snapshot): Usable APIs. APIs in `ephemeral` will be + occasionally snapshotted and promoted into `snapshot`, with approval from the Subgroup, considering the overall suitability of the APIs themselves, their documentation, test coverage, and availability of polyfills when appropriate. Once merged, the API modules will be considered stable, though they may be superseded by newer versions. Proposals to promote specific APIs should be submitted as Pull Requests that: - - Move any superseded files out of `unstable` into `old`. - - Optionally add polyfills for superseded APIs using `unstable` APIs. - - Move all files supporting the APIs out of `ephemeral` into `unstable`. - - Rename the API modules from `wasi_ephemeral_` to `wasi_unstable_` - and append a version number. + 1. `git mv` contents of `phases/snapshot/` to + `phases/old/snapshot_{old_snapshot_number}`. + 2. `cp -R` contents of `phases/ephemeral/` into `phases/snapshot/`. + 3. Rename files copied into `phases/snapshot/` to substitute `ephemeral` + for `snapshot` in file names. Append the new snapshot number to each + name. + 4. Update module names given in `.witx` files according to the previous + step. + 5. Update tests in `tools/witx/tests/wasi.rs` to point at new snapshot, and + add a test pointing at the just-archived snapshot under `old`. + 6. Optionally, under `phases/old/snapshot_{old_snapshot_number}, add + polyfills for superceded APIs using the new APIs. + Pull Requests may also add additional tests, documentation, or - polyfills for existing `unstable` APIs. + polyfills for existing `snapshot` APIs. -- [`old`](old): When APIs in `current` spec are replaced by new +- [`old`](old): When APIs in `snapshot` spec are replaced by new versions, the old API modules are moved to the `old` directory. When possible, `old` APIs may be accompanied by polyfill modules which implement their API in terms of newer versions of the API. @@ -44,7 +52,7 @@ flexibility. WASI should eventually become a standard at the level of WebAssembly itself. Right now, it needs a lot of work before it's ready. The -`unstable` tree is meant to serve a practical purpose for people who +`snapshot` tree is meant to serve a practical purpose for people who want to work with APIs today, with the understanding that everything is still evolving. It's not meant as a replacement for proper standardization, which will happen once the overall API is more diff --git a/proposals/filesystem/phases/old/docs/wasi_unstable.md b/proposals/filesystem/phases/old/snapshot_0/docs/wasi_unstable.md similarity index 100% rename from proposals/filesystem/phases/old/docs/wasi_unstable.md rename to proposals/filesystem/phases/old/snapshot_0/docs/wasi_unstable.md diff --git a/proposals/filesystem/phases/old/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx similarity index 100% rename from proposals/filesystem/phases/old/witx/typenames.witx rename to proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx diff --git a/proposals/filesystem/phases/old/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx similarity index 100% rename from proposals/filesystem/phases/old/witx/wasi_unstable.witx rename to proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx diff --git a/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md b/proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md similarity index 98% rename from proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md rename to proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md index 2464f2342..6de15f1d2 100644 --- a/proposals/filesystem/phases/unstable/docs/wasi_unstable_preview0.md +++ b/proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md @@ -117,18 +117,22 @@ modules so that embedders need not implement all of it. Read command-line argument data. -The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - Inputs: - char \*\*argv A pointer to a buffer to write the argument pointers. + The count of elements for the buffer should be at least the value of `argc` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + + The caller of `__wasi_args_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. + - char \*argv\_buf A pointer to a buffer to write the argument string data. + The size of this buffer should be the value of `argv_buf_size` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). + ### `__wasi_args_sizes_get()` Return command-line argument data sizes. @@ -192,21 +196,25 @@ Outputs: Read environment variable data. -The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - Inputs: - char \*\*environ A pointer to a buffer to write the environment variable pointers. + The count of elements for the buffer should be at least the value of `environ_count` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + + The caller of `__wasi_environ_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. + - char \*environ\_buf A pointer to a buffer to write the environment variable string data. + The size of this buffer should be the value of `environ_buf_size` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). + ### `__wasi_environ_sizes_get()` -Return command-line argument data sizes. +Return enviroment variable data sizes. Outputs: @@ -1799,7 +1807,7 @@ Members: The address and length of the buffer to be filled. -### `__wasi_linkcount_t` (`uint32_t`) +### `__wasi_linkcount_t` (`uint64_t`) Number of hard links to an inode. @@ -2329,6 +2337,10 @@ Used by [`__wasi_fd_seek()`](#fd_seek). Possible values: +- **`__WASI_WHENCE_SET`** + + Seek relative to start-of-file. + - **`__WASI_WHENCE_CUR`** Seek relative to current position. @@ -2337,7 +2349,3 @@ Possible values: Seek relative to end-of-file. -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - diff --git a/proposals/filesystem/phases/unstable/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx similarity index 99% rename from proposals/filesystem/phases/unstable/witx/typenames.witx rename to proposals/filesystem/phases/snapshot/witx/typenames.witx index 15b53af51..1a45be1fd 100644 --- a/proposals/filesystem/phases/unstable/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -305,16 +305,18 @@ ;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 + ;; Seek relative to start-of-file. + $WHENCE_SET ;; Seek relative to current position. $WHENCE_CUR ;; Seek relative to end-of-file. $WHENCE_END - ;; Seek relative to start-of-file. - $WHENCE_SET ) ) ;; A reference to the offset of a directory entry. +;; +;; The value 0 signifies the start of the directory. (typename $dircookie_t u64) ;; The type for the $d_namlen field of $dirent_t. @@ -451,7 +453,7 @@ ) ;; Number of hard links to an inode. -(typename $linkcount_t u32) +(typename $linkcount_t u64) ;; File attributes. (typename $filestat_t @@ -552,8 +554,6 @@ ;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) ;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) ;; The absolute or relative timestamp. diff --git a/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx similarity index 99% rename from proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx rename to proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx index d5686dabb..630537416 100644 --- a/proposals/filesystem/phases/unstable/witx/wasi_unstable_preview0.witx +++ b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -8,7 +8,7 @@ (use "typenames.witx") -(module $wasi_unstable_preview0 +(module $wasi_snapshot_preview1 ;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) diff --git a/proposals/filesystem/tools/witx/tests/wasi_unstable.rs b/proposals/filesystem/tools/witx/tests/wasi.rs similarity index 65% rename from proposals/filesystem/tools/witx/tests/wasi_unstable.rs rename to proposals/filesystem/tools/witx/tests/wasi.rs index 68e65186a..2b2566997 100644 --- a/proposals/filesystem/tools/witx/tests/wasi_unstable.rs +++ b/proposals/filesystem/tools/witx/tests/wasi.rs @@ -2,15 +2,15 @@ use std::path::Path; use witx; #[test] -fn validate_wasi_unstable_preview0() { +fn validate_wasi_snapshot() { witx::load(Path::new( - "../../phases/unstable/witx/wasi_unstable_preview0.witx", + "../../phases/snapshot/witx/wasi_snapshot_preview1.witx", )) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] -fn validate_wasi_ephemeral_preview() { +fn validate_wasi_ephemeral() { witx::load(Path::new( "../../phases/ephemeral/witx/wasi_ephemeral_preview.witx", )) @@ -18,15 +18,17 @@ fn validate_wasi_ephemeral_preview() { } #[test] -fn validate_wasi_old_preview0() { - witx::load(Path::new("../../phases/old/witx/wasi_unstable.witx")) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); +fn validate_wasi_old_snapshot_0() { + witx::load(Path::new( + "../../phases/old/snapshot_0/witx/wasi_unstable.witx", + )) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn render_roundtrip() { let doc = witx::load(Path::new( - "../../phases/unstable/witx/wasi_unstable_preview0.witx", + "../../phases/snapshot/witx/wasi_snapshot_preview1.witx", )) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); From d4ba28fefba21fea9a7ade17b5c629940adaa07a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 16:35:24 -0800 Subject: [PATCH 0289/1772] witx: add support for parsing multiple top-level files (#145) * witx: add support for parsing multiple top-level witx files * tests: test parsing multiple top-level witx files * witx: add a multimodule test that rejects redefined names and rename the path to be a litle shorter --- proposals/clocks/tools/witx/src/lib.rs | 6 +- proposals/clocks/tools/witx/src/main.rs | 12 +++- proposals/clocks/tools/witx/src/toplevel.rs | 47 +++++++------- .../clocks/tools/witx/tests/multimodule.rs | 62 +++++++++++++++++++ .../witx/tests/multimodule/redefine_a.witx | 1 + .../tools/witx/tests/multimodule/type_a.witx | 1 + .../tools/witx/tests/multimodule/type_b.witx | 2 + .../tools/witx/tests/multimodule/type_c.witx | 2 + proposals/clocks/tools/witx/tests/wasi.rs | 25 +++----- 9 files changed, 115 insertions(+), 43 deletions(-) create mode 100644 proposals/clocks/tools/witx/tests/multimodule.rs create mode 100644 proposals/clocks/tools/witx/tests/multimodule/redefine_a.witx create mode 100644 proposals/clocks/tools/witx/tests/multimodule/type_a.witx create mode 100644 proposals/clocks/tools/witx/tests/multimodule/type_b.witx create mode 100644 proposals/clocks/tools/witx/tests/multimodule/type_c.witx diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 60ccf2c9b..3c2d945ec 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -29,14 +29,14 @@ use failure::Fail; use std::path::{Path, PathBuf}; /// Load a witx document from the filesystem -pub fn load>(path: P) -> Result { - toplevel::parse_witx(path.as_ref()) +pub fn load>(paths: &[P]) -> Result { + toplevel::parse_witx(paths) } /// Parse a witx document from a str. `(use ...)` directives are not permitted. pub fn parse(source: &str) -> Result { let mockfs = MockFs::new(&[("-", source)]); - toplevel::parse_witx_with(Path::new("-"), &mockfs) + toplevel::parse_witx_with(&[Path::new("-")], &mockfs) } /// Location in the source text diff --git a/proposals/clocks/tools/witx/src/main.rs b/proposals/clocks/tools/witx/src/main.rs index c2ad70322..8b1cab6ea 100644 --- a/proposals/clocks/tools/witx/src/main.rs +++ b/proposals/clocks/tools/witx/src/main.rs @@ -1,5 +1,5 @@ use clap::{App, Arg}; -use std::path::Path; +use std::path::PathBuf; use std::process; use witx::load; @@ -10,6 +10,7 @@ pub fn main() { .arg( Arg::with_name("input") .required(true) + .multiple(true) .help("path to root of witx document"), ) .arg( @@ -21,7 +22,14 @@ pub fn main() { ) .get_matches(); - match load(Path::new(app.value_of("input").expect("required arg"))) { + let inputs = app + .values_of("input") + .expect("at least one input required") + .into_iter() + .map(|i| PathBuf::from(i)) + .collect::>(); + + match load(&inputs) { Ok(doc) => { if app.is_present("verbose") { println!("{:?}", doc) diff --git a/proposals/clocks/tools/witx/src/toplevel.rs b/proposals/clocks/tools/witx/src/toplevel.rs index 927bdd4de..281ad4757 100644 --- a/proposals/clocks/tools/witx/src/toplevel.rs +++ b/proposals/clocks/tools/witx/src/toplevel.rs @@ -6,27 +6,32 @@ use crate::WitxError; use std::collections::HashSet; use std::path::{Path, PathBuf}; -pub fn parse_witx(i: impl AsRef) -> Result { - _parse_witx_with(i.as_ref(), &Filesystem) +pub fn parse_witx(i: &[impl AsRef]) -> Result { + let paths = i.iter().map(|p| p.as_ref()).collect::>(); + _parse_witx_with(&paths, &Filesystem) } -pub fn parse_witx_with(i: impl AsRef, witxio: impl WitxIo) -> Result { - _parse_witx_with(i.as_ref(), &witxio) +pub fn parse_witx_with(i: &[impl AsRef], witxio: impl WitxIo) -> Result { + let paths = i.iter().map(|p| p.as_ref()).collect::>(); + _parse_witx_with(&paths, &witxio) } -fn _parse_witx_with(path: &Path, io: &dyn WitxIo) -> Result { +fn _parse_witx_with(paths: &[&Path], io: &dyn WitxIo) -> Result { let mut validator = DocValidation::new(); let mut definitions = Vec::new(); - let root = path.parent().unwrap_or(Path::new(".")); - - parse_file( - path.file_name().unwrap().as_ref(), - io, - root, - &mut validator, - &mut definitions, - &mut HashSet::new(), - )?; + let mut parsed = HashSet::new(); + for path in paths { + let root = path.parent().unwrap_or(Path::new(".")); + + parse_file( + path.file_name().unwrap().as_ref(), + io, + root, + &mut validator, + &mut definitions, + &mut parsed, + )?; + } Ok(Document::new(definitions, validator.entries)) } @@ -78,13 +83,13 @@ mod test { #[test] fn empty() { - parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", ";; empty")])).expect("parse"); + parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", ";; empty")])).expect("parse"); } #[test] fn one_use() { parse_witx_with( - &Path::new("/a"), + &[Path::new("/a")], &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]), ) .unwrap(); @@ -93,7 +98,7 @@ mod test { #[test] fn multi_use() { let doc = parse_witx_with( - &Path::new("/a"), + &[Path::new("/a")], &MockFs::new(&[ ("/a", "(use \"b\")"), ("/b", "(use \"c\")\n(typename $b_float f64)"), @@ -122,7 +127,7 @@ mod test { #[test] fn diamond_dependency() { let doc = parse_witx_with( - &Path::new("/a"), + &[Path::new("/a")], &MockFs::new(&[ ("/a", "(use \"b\")\n(use \"c\")"), ("/b", "(use \"d\")"), @@ -143,7 +148,7 @@ mod test { #[test] fn use_not_found() { - match parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", "(use \"b\")")])) + match parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", "(use \"b\")")])) .err() .unwrap() { @@ -154,7 +159,7 @@ mod test { #[test] fn use_invalid() { - match parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", "(use bbbbbbb)")])) + match parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", "(use bbbbbbb)")])) .err() .unwrap() { diff --git a/proposals/clocks/tools/witx/tests/multimodule.rs b/proposals/clocks/tools/witx/tests/multimodule.rs new file mode 100644 index 000000000..e9cc5ecb9 --- /dev/null +++ b/proposals/clocks/tools/witx/tests/multimodule.rs @@ -0,0 +1,62 @@ +use witx::{load, BuiltinType, DatatypeIdent, DatatypeVariant, Id}; + +#[test] +fn validate_multimodule() { + // B uses A, and C uses A. + let doc = load(&[ + "tests/multimodule/type_b.witx", + "tests/multimodule/type_c.witx", + ]) + .unwrap_or_else(|e| panic!("failed to validate: {}", e)); + + println!("{}", doc); + + // Check that the `a` both modules use is what we expect: + let type_a = doc.datatype(&Id::new("a")).expect("type a exists"); + match &type_a.variant { + DatatypeVariant::Alias(alias) => match alias.to { + DatatypeIdent::Builtin(b) => assert_eq!(b, BuiltinType::U32), + _ => panic!("a is an alias u32"), + }, + _ => panic!("a is an alias to u32"), + } + + // `b` is a struct with a single member of type `a` + let type_b = doc.datatype(&Id::new("b")).expect("type b exists"); + match &type_b.variant { + DatatypeVariant::Struct(struct_) => { + assert_eq!(struct_.members.len(), 1); + match &struct_.members.get(0).unwrap().type_ { + DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), + _ => panic!("b.0 has type a"), + } + } + _ => panic!("b is a struct"), + } + + // `c` is a struct with a two members of type `a` + let type_c = doc.datatype(&Id::new("c")).expect("type c exists"); + match &type_c.variant { + DatatypeVariant::Struct(struct_) => { + assert_eq!(struct_.members.len(), 2); + match &struct_.members.get(0).unwrap().type_ { + DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), + _ => panic!("c.0 has type a"), + } + match &struct_.members.get(1).unwrap().type_ { + DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), + _ => panic!("c.1 has type a"), + } + } + _ => panic!("c is a struct"), + } +} + +#[test] +fn multimodule_reject_redefinition() { + assert!(load(&[ + "tests/multimodule/type_a.witx", + "tests/multimodule/redefine_a.witx", + ]) + .is_err()) +} diff --git a/proposals/clocks/tools/witx/tests/multimodule/redefine_a.witx b/proposals/clocks/tools/witx/tests/multimodule/redefine_a.witx new file mode 100644 index 000000000..e5d99d82c --- /dev/null +++ b/proposals/clocks/tools/witx/tests/multimodule/redefine_a.witx @@ -0,0 +1 @@ +(typename $a u8) diff --git a/proposals/clocks/tools/witx/tests/multimodule/type_a.witx b/proposals/clocks/tools/witx/tests/multimodule/type_a.witx new file mode 100644 index 000000000..5499ff3db --- /dev/null +++ b/proposals/clocks/tools/witx/tests/multimodule/type_a.witx @@ -0,0 +1 @@ +(typename $a u32) diff --git a/proposals/clocks/tools/witx/tests/multimodule/type_b.witx b/proposals/clocks/tools/witx/tests/multimodule/type_b.witx new file mode 100644 index 000000000..fe8315da9 --- /dev/null +++ b/proposals/clocks/tools/witx/tests/multimodule/type_b.witx @@ -0,0 +1,2 @@ +(use "type_a.witx") +(typename $b (struct (field $member_a $a))) diff --git a/proposals/clocks/tools/witx/tests/multimodule/type_c.witx b/proposals/clocks/tools/witx/tests/multimodule/type_c.witx new file mode 100644 index 000000000..9f8819162 --- /dev/null +++ b/proposals/clocks/tools/witx/tests/multimodule/type_c.witx @@ -0,0 +1,2 @@ +(use "type_a.witx") +(typename $c (struct (field $first_a $a) (field $second_a $a))) diff --git a/proposals/clocks/tools/witx/tests/wasi.rs b/proposals/clocks/tools/witx/tests/wasi.rs index 2b2566997..b5a9d527c 100644 --- a/proposals/clocks/tools/witx/tests/wasi.rs +++ b/proposals/clocks/tools/witx/tests/wasi.rs @@ -1,36 +1,27 @@ -use std::path::Path; use witx; #[test] fn validate_wasi_snapshot() { - witx::load(Path::new( - "../../phases/snapshot/witx/wasi_snapshot_preview1.witx", - )) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_ephemeral() { - witx::load(Path::new( - "../../phases/ephemeral/witx/wasi_ephemeral_preview.witx", - )) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&["../../phases/ephemeral/witx/wasi_ephemeral_preview.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_old_snapshot_0() { - witx::load(Path::new( - "../../phases/old/snapshot_0/witx/wasi_unstable.witx", - )) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&["../../phases/old/snapshot_0/witx/wasi_unstable.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn render_roundtrip() { - let doc = witx::load(Path::new( - "../../phases/snapshot/witx/wasi_snapshot_preview1.witx", - )) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + let doc = witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); let back_to_sexprs = format!("{}", doc); println!("{}", back_to_sexprs); From cddf8d916ea0a91df7324a5f93b4386903ae4225 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 16:35:24 -0800 Subject: [PATCH 0290/1772] witx: add support for parsing multiple top-level files (#145) * witx: add support for parsing multiple top-level witx files * tests: test parsing multiple top-level witx files * witx: add a multimodule test that rejects redefined names and rename the path to be a litle shorter --- proposals/random/tools/witx/src/lib.rs | 6 +- proposals/random/tools/witx/src/main.rs | 12 +++- proposals/random/tools/witx/src/toplevel.rs | 47 +++++++------- .../random/tools/witx/tests/multimodule.rs | 62 +++++++++++++++++++ .../witx/tests/multimodule/redefine_a.witx | 1 + .../tools/witx/tests/multimodule/type_a.witx | 1 + .../tools/witx/tests/multimodule/type_b.witx | 2 + .../tools/witx/tests/multimodule/type_c.witx | 2 + proposals/random/tools/witx/tests/wasi.rs | 25 +++----- 9 files changed, 115 insertions(+), 43 deletions(-) create mode 100644 proposals/random/tools/witx/tests/multimodule.rs create mode 100644 proposals/random/tools/witx/tests/multimodule/redefine_a.witx create mode 100644 proposals/random/tools/witx/tests/multimodule/type_a.witx create mode 100644 proposals/random/tools/witx/tests/multimodule/type_b.witx create mode 100644 proposals/random/tools/witx/tests/multimodule/type_c.witx diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 60ccf2c9b..3c2d945ec 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -29,14 +29,14 @@ use failure::Fail; use std::path::{Path, PathBuf}; /// Load a witx document from the filesystem -pub fn load>(path: P) -> Result { - toplevel::parse_witx(path.as_ref()) +pub fn load>(paths: &[P]) -> Result { + toplevel::parse_witx(paths) } /// Parse a witx document from a str. `(use ...)` directives are not permitted. pub fn parse(source: &str) -> Result { let mockfs = MockFs::new(&[("-", source)]); - toplevel::parse_witx_with(Path::new("-"), &mockfs) + toplevel::parse_witx_with(&[Path::new("-")], &mockfs) } /// Location in the source text diff --git a/proposals/random/tools/witx/src/main.rs b/proposals/random/tools/witx/src/main.rs index c2ad70322..8b1cab6ea 100644 --- a/proposals/random/tools/witx/src/main.rs +++ b/proposals/random/tools/witx/src/main.rs @@ -1,5 +1,5 @@ use clap::{App, Arg}; -use std::path::Path; +use std::path::PathBuf; use std::process; use witx::load; @@ -10,6 +10,7 @@ pub fn main() { .arg( Arg::with_name("input") .required(true) + .multiple(true) .help("path to root of witx document"), ) .arg( @@ -21,7 +22,14 @@ pub fn main() { ) .get_matches(); - match load(Path::new(app.value_of("input").expect("required arg"))) { + let inputs = app + .values_of("input") + .expect("at least one input required") + .into_iter() + .map(|i| PathBuf::from(i)) + .collect::>(); + + match load(&inputs) { Ok(doc) => { if app.is_present("verbose") { println!("{:?}", doc) diff --git a/proposals/random/tools/witx/src/toplevel.rs b/proposals/random/tools/witx/src/toplevel.rs index 927bdd4de..281ad4757 100644 --- a/proposals/random/tools/witx/src/toplevel.rs +++ b/proposals/random/tools/witx/src/toplevel.rs @@ -6,27 +6,32 @@ use crate::WitxError; use std::collections::HashSet; use std::path::{Path, PathBuf}; -pub fn parse_witx(i: impl AsRef) -> Result { - _parse_witx_with(i.as_ref(), &Filesystem) +pub fn parse_witx(i: &[impl AsRef]) -> Result { + let paths = i.iter().map(|p| p.as_ref()).collect::>(); + _parse_witx_with(&paths, &Filesystem) } -pub fn parse_witx_with(i: impl AsRef, witxio: impl WitxIo) -> Result { - _parse_witx_with(i.as_ref(), &witxio) +pub fn parse_witx_with(i: &[impl AsRef], witxio: impl WitxIo) -> Result { + let paths = i.iter().map(|p| p.as_ref()).collect::>(); + _parse_witx_with(&paths, &witxio) } -fn _parse_witx_with(path: &Path, io: &dyn WitxIo) -> Result { +fn _parse_witx_with(paths: &[&Path], io: &dyn WitxIo) -> Result { let mut validator = DocValidation::new(); let mut definitions = Vec::new(); - let root = path.parent().unwrap_or(Path::new(".")); - - parse_file( - path.file_name().unwrap().as_ref(), - io, - root, - &mut validator, - &mut definitions, - &mut HashSet::new(), - )?; + let mut parsed = HashSet::new(); + for path in paths { + let root = path.parent().unwrap_or(Path::new(".")); + + parse_file( + path.file_name().unwrap().as_ref(), + io, + root, + &mut validator, + &mut definitions, + &mut parsed, + )?; + } Ok(Document::new(definitions, validator.entries)) } @@ -78,13 +83,13 @@ mod test { #[test] fn empty() { - parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", ";; empty")])).expect("parse"); + parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", ";; empty")])).expect("parse"); } #[test] fn one_use() { parse_witx_with( - &Path::new("/a"), + &[Path::new("/a")], &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]), ) .unwrap(); @@ -93,7 +98,7 @@ mod test { #[test] fn multi_use() { let doc = parse_witx_with( - &Path::new("/a"), + &[Path::new("/a")], &MockFs::new(&[ ("/a", "(use \"b\")"), ("/b", "(use \"c\")\n(typename $b_float f64)"), @@ -122,7 +127,7 @@ mod test { #[test] fn diamond_dependency() { let doc = parse_witx_with( - &Path::new("/a"), + &[Path::new("/a")], &MockFs::new(&[ ("/a", "(use \"b\")\n(use \"c\")"), ("/b", "(use \"d\")"), @@ -143,7 +148,7 @@ mod test { #[test] fn use_not_found() { - match parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", "(use \"b\")")])) + match parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", "(use \"b\")")])) .err() .unwrap() { @@ -154,7 +159,7 @@ mod test { #[test] fn use_invalid() { - match parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", "(use bbbbbbb)")])) + match parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", "(use bbbbbbb)")])) .err() .unwrap() { diff --git a/proposals/random/tools/witx/tests/multimodule.rs b/proposals/random/tools/witx/tests/multimodule.rs new file mode 100644 index 000000000..e9cc5ecb9 --- /dev/null +++ b/proposals/random/tools/witx/tests/multimodule.rs @@ -0,0 +1,62 @@ +use witx::{load, BuiltinType, DatatypeIdent, DatatypeVariant, Id}; + +#[test] +fn validate_multimodule() { + // B uses A, and C uses A. + let doc = load(&[ + "tests/multimodule/type_b.witx", + "tests/multimodule/type_c.witx", + ]) + .unwrap_or_else(|e| panic!("failed to validate: {}", e)); + + println!("{}", doc); + + // Check that the `a` both modules use is what we expect: + let type_a = doc.datatype(&Id::new("a")).expect("type a exists"); + match &type_a.variant { + DatatypeVariant::Alias(alias) => match alias.to { + DatatypeIdent::Builtin(b) => assert_eq!(b, BuiltinType::U32), + _ => panic!("a is an alias u32"), + }, + _ => panic!("a is an alias to u32"), + } + + // `b` is a struct with a single member of type `a` + let type_b = doc.datatype(&Id::new("b")).expect("type b exists"); + match &type_b.variant { + DatatypeVariant::Struct(struct_) => { + assert_eq!(struct_.members.len(), 1); + match &struct_.members.get(0).unwrap().type_ { + DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), + _ => panic!("b.0 has type a"), + } + } + _ => panic!("b is a struct"), + } + + // `c` is a struct with a two members of type `a` + let type_c = doc.datatype(&Id::new("c")).expect("type c exists"); + match &type_c.variant { + DatatypeVariant::Struct(struct_) => { + assert_eq!(struct_.members.len(), 2); + match &struct_.members.get(0).unwrap().type_ { + DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), + _ => panic!("c.0 has type a"), + } + match &struct_.members.get(1).unwrap().type_ { + DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), + _ => panic!("c.1 has type a"), + } + } + _ => panic!("c is a struct"), + } +} + +#[test] +fn multimodule_reject_redefinition() { + assert!(load(&[ + "tests/multimodule/type_a.witx", + "tests/multimodule/redefine_a.witx", + ]) + .is_err()) +} diff --git a/proposals/random/tools/witx/tests/multimodule/redefine_a.witx b/proposals/random/tools/witx/tests/multimodule/redefine_a.witx new file mode 100644 index 000000000..e5d99d82c --- /dev/null +++ b/proposals/random/tools/witx/tests/multimodule/redefine_a.witx @@ -0,0 +1 @@ +(typename $a u8) diff --git a/proposals/random/tools/witx/tests/multimodule/type_a.witx b/proposals/random/tools/witx/tests/multimodule/type_a.witx new file mode 100644 index 000000000..5499ff3db --- /dev/null +++ b/proposals/random/tools/witx/tests/multimodule/type_a.witx @@ -0,0 +1 @@ +(typename $a u32) diff --git a/proposals/random/tools/witx/tests/multimodule/type_b.witx b/proposals/random/tools/witx/tests/multimodule/type_b.witx new file mode 100644 index 000000000..fe8315da9 --- /dev/null +++ b/proposals/random/tools/witx/tests/multimodule/type_b.witx @@ -0,0 +1,2 @@ +(use "type_a.witx") +(typename $b (struct (field $member_a $a))) diff --git a/proposals/random/tools/witx/tests/multimodule/type_c.witx b/proposals/random/tools/witx/tests/multimodule/type_c.witx new file mode 100644 index 000000000..9f8819162 --- /dev/null +++ b/proposals/random/tools/witx/tests/multimodule/type_c.witx @@ -0,0 +1,2 @@ +(use "type_a.witx") +(typename $c (struct (field $first_a $a) (field $second_a $a))) diff --git a/proposals/random/tools/witx/tests/wasi.rs b/proposals/random/tools/witx/tests/wasi.rs index 2b2566997..b5a9d527c 100644 --- a/proposals/random/tools/witx/tests/wasi.rs +++ b/proposals/random/tools/witx/tests/wasi.rs @@ -1,36 +1,27 @@ -use std::path::Path; use witx; #[test] fn validate_wasi_snapshot() { - witx::load(Path::new( - "../../phases/snapshot/witx/wasi_snapshot_preview1.witx", - )) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_ephemeral() { - witx::load(Path::new( - "../../phases/ephemeral/witx/wasi_ephemeral_preview.witx", - )) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&["../../phases/ephemeral/witx/wasi_ephemeral_preview.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_old_snapshot_0() { - witx::load(Path::new( - "../../phases/old/snapshot_0/witx/wasi_unstable.witx", - )) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&["../../phases/old/snapshot_0/witx/wasi_unstable.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn render_roundtrip() { - let doc = witx::load(Path::new( - "../../phases/snapshot/witx/wasi_snapshot_preview1.witx", - )) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + let doc = witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); let back_to_sexprs = format!("{}", doc); println!("{}", back_to_sexprs); From 019a7cf7b56d6e23390e50558d15932e943f3e65 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 16:35:24 -0800 Subject: [PATCH 0291/1772] witx: add support for parsing multiple top-level files (#145) * witx: add support for parsing multiple top-level witx files * tests: test parsing multiple top-level witx files * witx: add a multimodule test that rejects redefined names and rename the path to be a litle shorter --- proposals/filesystem/tools/witx/src/lib.rs | 6 +- proposals/filesystem/tools/witx/src/main.rs | 12 +++- .../filesystem/tools/witx/src/toplevel.rs | 47 +++++++------- .../tools/witx/tests/multimodule.rs | 62 +++++++++++++++++++ .../witx/tests/multimodule/redefine_a.witx | 1 + .../tools/witx/tests/multimodule/type_a.witx | 1 + .../tools/witx/tests/multimodule/type_b.witx | 2 + .../tools/witx/tests/multimodule/type_c.witx | 2 + proposals/filesystem/tools/witx/tests/wasi.rs | 25 +++----- 9 files changed, 115 insertions(+), 43 deletions(-) create mode 100644 proposals/filesystem/tools/witx/tests/multimodule.rs create mode 100644 proposals/filesystem/tools/witx/tests/multimodule/redefine_a.witx create mode 100644 proposals/filesystem/tools/witx/tests/multimodule/type_a.witx create mode 100644 proposals/filesystem/tools/witx/tests/multimodule/type_b.witx create mode 100644 proposals/filesystem/tools/witx/tests/multimodule/type_c.witx diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 60ccf2c9b..3c2d945ec 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -29,14 +29,14 @@ use failure::Fail; use std::path::{Path, PathBuf}; /// Load a witx document from the filesystem -pub fn load>(path: P) -> Result { - toplevel::parse_witx(path.as_ref()) +pub fn load>(paths: &[P]) -> Result { + toplevel::parse_witx(paths) } /// Parse a witx document from a str. `(use ...)` directives are not permitted. pub fn parse(source: &str) -> Result { let mockfs = MockFs::new(&[("-", source)]); - toplevel::parse_witx_with(Path::new("-"), &mockfs) + toplevel::parse_witx_with(&[Path::new("-")], &mockfs) } /// Location in the source text diff --git a/proposals/filesystem/tools/witx/src/main.rs b/proposals/filesystem/tools/witx/src/main.rs index c2ad70322..8b1cab6ea 100644 --- a/proposals/filesystem/tools/witx/src/main.rs +++ b/proposals/filesystem/tools/witx/src/main.rs @@ -1,5 +1,5 @@ use clap::{App, Arg}; -use std::path::Path; +use std::path::PathBuf; use std::process; use witx::load; @@ -10,6 +10,7 @@ pub fn main() { .arg( Arg::with_name("input") .required(true) + .multiple(true) .help("path to root of witx document"), ) .arg( @@ -21,7 +22,14 @@ pub fn main() { ) .get_matches(); - match load(Path::new(app.value_of("input").expect("required arg"))) { + let inputs = app + .values_of("input") + .expect("at least one input required") + .into_iter() + .map(|i| PathBuf::from(i)) + .collect::>(); + + match load(&inputs) { Ok(doc) => { if app.is_present("verbose") { println!("{:?}", doc) diff --git a/proposals/filesystem/tools/witx/src/toplevel.rs b/proposals/filesystem/tools/witx/src/toplevel.rs index 927bdd4de..281ad4757 100644 --- a/proposals/filesystem/tools/witx/src/toplevel.rs +++ b/proposals/filesystem/tools/witx/src/toplevel.rs @@ -6,27 +6,32 @@ use crate::WitxError; use std::collections::HashSet; use std::path::{Path, PathBuf}; -pub fn parse_witx(i: impl AsRef) -> Result { - _parse_witx_with(i.as_ref(), &Filesystem) +pub fn parse_witx(i: &[impl AsRef]) -> Result { + let paths = i.iter().map(|p| p.as_ref()).collect::>(); + _parse_witx_with(&paths, &Filesystem) } -pub fn parse_witx_with(i: impl AsRef, witxio: impl WitxIo) -> Result { - _parse_witx_with(i.as_ref(), &witxio) +pub fn parse_witx_with(i: &[impl AsRef], witxio: impl WitxIo) -> Result { + let paths = i.iter().map(|p| p.as_ref()).collect::>(); + _parse_witx_with(&paths, &witxio) } -fn _parse_witx_with(path: &Path, io: &dyn WitxIo) -> Result { +fn _parse_witx_with(paths: &[&Path], io: &dyn WitxIo) -> Result { let mut validator = DocValidation::new(); let mut definitions = Vec::new(); - let root = path.parent().unwrap_or(Path::new(".")); - - parse_file( - path.file_name().unwrap().as_ref(), - io, - root, - &mut validator, - &mut definitions, - &mut HashSet::new(), - )?; + let mut parsed = HashSet::new(); + for path in paths { + let root = path.parent().unwrap_or(Path::new(".")); + + parse_file( + path.file_name().unwrap().as_ref(), + io, + root, + &mut validator, + &mut definitions, + &mut parsed, + )?; + } Ok(Document::new(definitions, validator.entries)) } @@ -78,13 +83,13 @@ mod test { #[test] fn empty() { - parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", ";; empty")])).expect("parse"); + parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", ";; empty")])).expect("parse"); } #[test] fn one_use() { parse_witx_with( - &Path::new("/a"), + &[Path::new("/a")], &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]), ) .unwrap(); @@ -93,7 +98,7 @@ mod test { #[test] fn multi_use() { let doc = parse_witx_with( - &Path::new("/a"), + &[Path::new("/a")], &MockFs::new(&[ ("/a", "(use \"b\")"), ("/b", "(use \"c\")\n(typename $b_float f64)"), @@ -122,7 +127,7 @@ mod test { #[test] fn diamond_dependency() { let doc = parse_witx_with( - &Path::new("/a"), + &[Path::new("/a")], &MockFs::new(&[ ("/a", "(use \"b\")\n(use \"c\")"), ("/b", "(use \"d\")"), @@ -143,7 +148,7 @@ mod test { #[test] fn use_not_found() { - match parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", "(use \"b\")")])) + match parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", "(use \"b\")")])) .err() .unwrap() { @@ -154,7 +159,7 @@ mod test { #[test] fn use_invalid() { - match parse_witx_with(&Path::new("/a"), &MockFs::new(&[("/a", "(use bbbbbbb)")])) + match parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", "(use bbbbbbb)")])) .err() .unwrap() { diff --git a/proposals/filesystem/tools/witx/tests/multimodule.rs b/proposals/filesystem/tools/witx/tests/multimodule.rs new file mode 100644 index 000000000..e9cc5ecb9 --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/multimodule.rs @@ -0,0 +1,62 @@ +use witx::{load, BuiltinType, DatatypeIdent, DatatypeVariant, Id}; + +#[test] +fn validate_multimodule() { + // B uses A, and C uses A. + let doc = load(&[ + "tests/multimodule/type_b.witx", + "tests/multimodule/type_c.witx", + ]) + .unwrap_or_else(|e| panic!("failed to validate: {}", e)); + + println!("{}", doc); + + // Check that the `a` both modules use is what we expect: + let type_a = doc.datatype(&Id::new("a")).expect("type a exists"); + match &type_a.variant { + DatatypeVariant::Alias(alias) => match alias.to { + DatatypeIdent::Builtin(b) => assert_eq!(b, BuiltinType::U32), + _ => panic!("a is an alias u32"), + }, + _ => panic!("a is an alias to u32"), + } + + // `b` is a struct with a single member of type `a` + let type_b = doc.datatype(&Id::new("b")).expect("type b exists"); + match &type_b.variant { + DatatypeVariant::Struct(struct_) => { + assert_eq!(struct_.members.len(), 1); + match &struct_.members.get(0).unwrap().type_ { + DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), + _ => panic!("b.0 has type a"), + } + } + _ => panic!("b is a struct"), + } + + // `c` is a struct with a two members of type `a` + let type_c = doc.datatype(&Id::new("c")).expect("type c exists"); + match &type_c.variant { + DatatypeVariant::Struct(struct_) => { + assert_eq!(struct_.members.len(), 2); + match &struct_.members.get(0).unwrap().type_ { + DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), + _ => panic!("c.0 has type a"), + } + match &struct_.members.get(1).unwrap().type_ { + DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), + _ => panic!("c.1 has type a"), + } + } + _ => panic!("c is a struct"), + } +} + +#[test] +fn multimodule_reject_redefinition() { + assert!(load(&[ + "tests/multimodule/type_a.witx", + "tests/multimodule/redefine_a.witx", + ]) + .is_err()) +} diff --git a/proposals/filesystem/tools/witx/tests/multimodule/redefine_a.witx b/proposals/filesystem/tools/witx/tests/multimodule/redefine_a.witx new file mode 100644 index 000000000..e5d99d82c --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/multimodule/redefine_a.witx @@ -0,0 +1 @@ +(typename $a u8) diff --git a/proposals/filesystem/tools/witx/tests/multimodule/type_a.witx b/proposals/filesystem/tools/witx/tests/multimodule/type_a.witx new file mode 100644 index 000000000..5499ff3db --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/multimodule/type_a.witx @@ -0,0 +1 @@ +(typename $a u32) diff --git a/proposals/filesystem/tools/witx/tests/multimodule/type_b.witx b/proposals/filesystem/tools/witx/tests/multimodule/type_b.witx new file mode 100644 index 000000000..fe8315da9 --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/multimodule/type_b.witx @@ -0,0 +1,2 @@ +(use "type_a.witx") +(typename $b (struct (field $member_a $a))) diff --git a/proposals/filesystem/tools/witx/tests/multimodule/type_c.witx b/proposals/filesystem/tools/witx/tests/multimodule/type_c.witx new file mode 100644 index 000000000..9f8819162 --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/multimodule/type_c.witx @@ -0,0 +1,2 @@ +(use "type_a.witx") +(typename $c (struct (field $first_a $a) (field $second_a $a))) diff --git a/proposals/filesystem/tools/witx/tests/wasi.rs b/proposals/filesystem/tools/witx/tests/wasi.rs index 2b2566997..b5a9d527c 100644 --- a/proposals/filesystem/tools/witx/tests/wasi.rs +++ b/proposals/filesystem/tools/witx/tests/wasi.rs @@ -1,36 +1,27 @@ -use std::path::Path; use witx; #[test] fn validate_wasi_snapshot() { - witx::load(Path::new( - "../../phases/snapshot/witx/wasi_snapshot_preview1.witx", - )) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_ephemeral() { - witx::load(Path::new( - "../../phases/ephemeral/witx/wasi_ephemeral_preview.witx", - )) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&["../../phases/ephemeral/witx/wasi_ephemeral_preview.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_old_snapshot_0() { - witx::load(Path::new( - "../../phases/old/snapshot_0/witx/wasi_unstable.witx", - )) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&["../../phases/old/snapshot_0/witx/wasi_unstable.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn render_roundtrip() { - let doc = witx::load(Path::new( - "../../phases/snapshot/witx/wasi_snapshot_preview1.witx", - )) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + let doc = witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); let back_to_sexprs = format!("{}", doc); println!("{}", back_to_sexprs); From bda38319c299ca5ae41f4aa5d0702b992e1e565a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 16:54:40 -0800 Subject: [PATCH 0292/1772] witx: Parse comments into documentation in AST (#140) * witx: add support for parsing multiple top-level witx files * tests: test parsing multiple top-level witx files * witx: add a multimodule test that rejects redefined names and rename the path to be a litle shorter * witx: add `CommentSyntax` and `Documented` parsers Derived from ca26654f7747e2c9ce9d80d05c23a4ed48ec126c in https://github.com/alexcrichton/wat (PR #26) * witx: Parse comments of top level definitions, render crude markdown * filter for doc comments, trim whitespace * some progress on doc comments. wip * more wip! * complete adding doc parsing to AST * bugfixes, use a subcommand to emit docs * witx: forgot to add docs to module. add docs to output for roundtrip testing * wasi documents: convert all comments to doc-comments sed -i -E "s/ ;; / ;;; /" **/*.witx sed -i -E "s/^;; /;;; /" **/*.witx * fix fd_advise doc comments to come before parameters * tests: try to narrow failure a bit * witx files: normalize leading whitespace in doc-comments this was stopping the roundtripping test from passing, since the whitespace in the AST is slightly different after a roundtrip. I am not feeling clever enough to think of an elegant solution now, so I'll just hack up these files to not hit the bug. * witx files: very top comment is not a doc --- .../phases/ephemeral/witx/typenames.witx | 678 ++++++++--------- .../witx/wasi_ephemeral_preview.witx | 413 +++++------ .../phases/old/snapshot_0/witx/typenames.witx | 678 ++++++++--------- .../old/snapshot_0/witx/wasi_unstable.witx | 419 +++++------ .../phases/snapshot/witx/typenames.witx | 680 +++++++++--------- .../snapshot/witx/wasi_snapshot_preview1.witx | 413 +++++------ proposals/clocks/tools/witx/src/ast.rs | 25 +- proposals/clocks/tools/witx/src/docs.rs | 227 ++++++ proposals/clocks/tools/witx/src/lib.rs | 9 +- proposals/clocks/tools/witx/src/main.rs | 29 +- proposals/clocks/tools/witx/src/parser.rs | 206 ++++-- proposals/clocks/tools/witx/src/render.rs | 88 ++- proposals/clocks/tools/witx/src/toplevel.rs | 4 +- proposals/clocks/tools/witx/src/validate.rs | 80 ++- proposals/clocks/tools/witx/tests/wasi.rs | 26 + 15 files changed, 2224 insertions(+), 1751 deletions(-) create mode 100644 proposals/clocks/tools/witx/src/docs.rs diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 1a45be1fd..a614d8528 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -7,291 +7,291 @@ (typename $size_t u32) -;; Non-negative file size or length of a region within a file. +;;; Non-negative file size or length of a region within a file. (typename $filesize_t u64) -;; Timestamp in nanoseconds. +;;; Timestamp in nanoseconds. (typename $timestamp_t u64) -;; Identifiers for clocks. +;;; Identifiers for clocks. (typename $clockid_t (enum u32 - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. + ;;; The clock measuring real time. Time value zero corresponds with + ;;; 1970-01-01T00:00:00Z. $CLOCK_REALTIME - ;; The store-wide monotonic clock, which is defined as a clock measuring - ;; real time, whose value cannot be adjusted and which cannot have negative - ;; clock jumps. The epoch of this clock is undefined. The absolute time - ;; value of this clock therefore has no meaning. + ;;; The store-wide monotonic clock, which is defined as a clock measuring + ;;; real time, whose value cannot be adjusted and which cannot have negative + ;;; clock jumps. The epoch of this clock is undefined. The absolute time + ;;; value of this clock therefore has no meaning. $CLOCK_MONOTONIC - ;; The CPU-time clock associated with the current process. + ;;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The CPU-time clock associated with the current thread. + ;;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) ) -;; Error codes returned by functions. -;; Not all of these error codes are returned by the functions provided by this -;; API; some are used in higher-level library layers, and others are provided -;; merely for alignment with POSIX. +;;; Error codes returned by functions. +;;; Not all of these error codes are returned by the functions provided by this +;;; API; some are used in higher-level library layers, and others are provided +;;; merely for alignment with POSIX. (typename $errno_t (enum u16 - ;; No error occurred. System call completed successfully. + ;;; No error occurred. System call completed successfully. $ESUCCESS - ;; Argument list too long. + ;;; Argument list too long. $E2BIG - ;; Permission denied. + ;;; Permission denied. $EACCES - ;; Address in use. + ;;; Address in use. $EADDRINUSE - ;; Address not available. + ;;; Address not available. $EADDRNOTAVAIL - ;; Address family not supported. + ;;; Address family not supported. $EAFNOSUPPORT - ;; Resource unavailable, or operation would block. + ;;; Resource unavailable, or operation would block. $EAGAIN - ;; Connection already in progress. + ;;; Connection already in progress. $EALREADY - ;; Bad file descriptor. + ;;; Bad file descriptor. $EBADF - ;; Bad message. + ;;; Bad message. $EBADMSG - ;; Device or resource busy. + ;;; Device or resource busy. $EBUSY - ;; Operation canceled. + ;;; Operation canceled. $ECANCELED - ;; No child processes. + ;;; No child processes. $ECHILD - ;; Connection aborted. + ;;; Connection aborted. $ECONNABORTED - ;; Connection refused. + ;;; Connection refused. $ECONNREFUSED - ;; Connection reset. + ;;; Connection reset. $ECONNRESET - ;; Resource deadlock would occur. + ;;; Resource deadlock would occur. $EDEADLK - ;; Destination address required. + ;;; Destination address required. $EDESTADDRREQ - ;; Mathematics argument out of domain of function. + ;;; Mathematics argument out of domain of function. $EDOM - ;; Reserved. + ;;; Reserved. $EDQUOT - ;; File exists. + ;;; File exists. $EEXIST - ;; Bad address. + ;;; Bad address. $EFAULT - ;; File too large. + ;;; File too large. $EFBIG - ;; Host is unreachable. + ;;; Host is unreachable. $EHOSTUNREACH - ;; Identifier removed. + ;;; Identifier removed. $EIDRM - ;; Illegal byte sequence. + ;;; Illegal byte sequence. $EILSEQ - ;; Operation in progress. + ;;; Operation in progress. $EINPROGRESS - ;; Interrupted function. + ;;; Interrupted function. $EINTR - ;; Invalid argument. + ;;; Invalid argument. $EINVAL - ;; I/O error. + ;;; I/O error. $EIO - ;; Socket is connected. + ;;; Socket is connected. $EISCONN - ;; Is a directory. + ;;; Is a directory. $EISDIR - ;; Too many levels of symbolic links. + ;;; Too many levels of symbolic links. $ELOOP - ;; File descriptor value too large. + ;;; File descriptor value too large. $EMFILE - ;; Too many links. + ;;; Too many links. $EMLINK - ;; Message too large. + ;;; Message too large. $EMSGSIZE - ;; Reserved. + ;;; Reserved. $EMULTIHOP - ;; Filename too long. + ;;; Filename too long. $ENAMETOOLONG - ;; Network is down. + ;;; Network is down. $ENETDOWN - ;; Connection aborted by network. + ;;; Connection aborted by network. $ENETRESET - ;; Network unreachable. + ;;; Network unreachable. $ENETUNREACH - ;; Too many files open in system. + ;;; Too many files open in system. $ENFILE - ;; No buffer space available. + ;;; No buffer space available. $ENOBUFS - ;; No such device. + ;;; No such device. $ENODEV - ;; No such file or directory. + ;;; No such file or directory. $ENOENT - ;; Executable file format error. + ;;; Executable file format error. $ENOEXEC - ;; No locks available. + ;;; No locks available. $ENOLCK - ;; Reserved. + ;;; Reserved. $ENOLINK - ;; Not enough space. + ;;; Not enough space. $ENOMEM - ;; No message of the desired type. + ;;; No message of the desired type. $ENOMSG - ;; Protocol not available. + ;;; Protocol not available. $ENOPROTOOPT - ;; No space left on device. + ;;; No space left on device. $ENOSPC - ;; Function not supported. + ;;; Function not supported. $ENOSYS - ;; The socket is not connected. + ;;; The socket is not connected. $ENOTCONN - ;; Not a directory or a symbolic link to a directory. + ;;; Not a directory or a symbolic link to a directory. $ENOTDIR - ;; Directory not empty. + ;;; Directory not empty. $ENOTEMPTY - ;; State not recoverable. + ;;; State not recoverable. $ENOTRECOVERABLE - ;; Not a socket. + ;;; Not a socket. $ENOTSOCK - ;; Not supported, or operation not supported on socket. + ;;; Not supported, or operation not supported on socket. $ENOTSUP - ;; Inappropriate I/O control operation. + ;;; Inappropriate I/O control operation. $ENOTTY - ;; No such device or address. + ;;; No such device or address. $ENXIO - ;; Value too large to be stored in data type. + ;;; Value too large to be stored in data type. $EOVERFLOW - ;; Previous owner died. + ;;; Previous owner died. $EOWNERDEAD - ;; Operation not permitted. + ;;; Operation not permitted. $EPERM - ;; Broken pipe. + ;;; Broken pipe. $EPIPE - ;; Protocol error. + ;;; Protocol error. $EPROTO - ;; Protocol not supported. + ;;; Protocol not supported. $EPROTONOSUPPORT - ;; Protocol wrong type for socket. + ;;; Protocol wrong type for socket. $EPROTOTYPE - ;; Result too large. + ;;; Result too large. $ERANGE - ;; Read-only file system. + ;;; Read-only file system. $EROFS - ;; Invalid seek. + ;;; Invalid seek. $ESPIPE - ;; No such process. + ;;; No such process. $ESRCH - ;; Reserved. + ;;; Reserved. $ESTALE - ;; Connection timed out. + ;;; Connection timed out. $ETIMEDOUT - ;; Text file busy. + ;;; Text file busy. $ETXTBSY - ;; Cross-device link. + ;;; Cross-device link. $EXDEV - ;; Extension: Capabilities insufficient. + ;;; Extension: Capabilities insufficient. $ENOTCAPABLE ) ) -;; File descriptor rights, determining which actions may be performed. +;;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke `fd_datasync`. + ;;; The right to invoke `fd_datasync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_DSYNC`. $RIGHT_FD_DATASYNC - ;; The right to invoke `fd_read` and `sock_recv`. + ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. $RIGHT_FD_READ - ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. $RIGHT_FD_SEEK - ;; The right to invoke `fd_fdstat_set_flags`. + ;;; The right to invoke `fd_fdstat_set_flags`. $RIGHT_FD_FDSTAT_SET_FLAGS - ;; The right to invoke `fd_sync`. + ;;; The right to invoke `fd_sync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. $RIGHT_FD_SYNC - ;; The right to invoke `fd_seek` in such a way that the file offset - ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to - ;; invoke `fd_tell`. + ;;; The right to invoke `fd_seek` in such a way that the file offset + ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; invoke `fd_tell`. $RIGHT_FD_TELL - ;; The right to invoke `fd_write` and `sock_send`. - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + ;;; The right to invoke `fd_write` and `sock_send`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. $RIGHT_FD_WRITE - ;; The right to invoke `fd_advise`. + ;;; The right to invoke `fd_advise`. $RIGHT_FD_ADVISE - ;; The right to invoke `fd_allocate`. + ;;; The right to invoke `fd_allocate`. $RIGHT_FD_ALLOCATE - ;; The right to invoke `path_create_directory`. + ;;; The right to invoke `path_create_directory`. $RIGHT_PATH_CREATE_DIRECTORY - ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. $RIGHT_PATH_CREATE_FILE - ;; The right to invoke `path_link` with the file descriptor as the - ;; source directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; source directory. $RIGHT_PATH_LINK_SOURCE - ;; The right to invoke `path_link` with the file descriptor as the - ;; target directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; target directory. $RIGHT_PATH_LINK_TARGET - ;; The right to invoke `path_open`. + ;;; The right to invoke `path_open`. $RIGHT_PATH_OPEN - ;; The right to invoke `fd_readdir`. + ;;; The right to invoke `fd_readdir`. $RIGHT_FD_READDIR - ;; The right to invoke `path_readlink`. + ;;; The right to invoke `path_readlink`. $RIGHT_PATH_READLINK - ;; The right to invoke `path_rename` with the file descriptor as the source directory. + ;;; The right to invoke `path_rename` with the file descriptor as the source directory. $RIGHT_PATH_RENAME_SOURCE - ;; The right to invoke `path_rename` with the file descriptor as the target directory. + ;;; The right to invoke `path_rename` with the file descriptor as the target directory. $RIGHT_PATH_RENAME_TARGET - ;; The right to invoke `path_filestat_get`. + ;;; The right to invoke `path_filestat_get`. $RIGHT_PATH_FILESTAT_GET - ;; The right to change a file's size (there is no `path_filestat_set_size`). - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + ;;; The right to change a file's size (there is no `path_filestat_set_size`). + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. $RIGHT_PATH_FILESTAT_SET_SIZE - ;; The right to invoke `path_filestat_set_times`. + ;;; The right to invoke `path_filestat_set_times`. $RIGHT_PATH_FILESTAT_SET_TIMES - ;; The right to invoke `fd_filestat_get`. + ;;; The right to invoke `fd_filestat_get`. $RIGHT_FD_FILESTAT_GET - ;; The right to invoke `fd_filestat_set_size`. + ;;; The right to invoke `fd_filestat_set_size`. $RIGHT_FD_FILESTAT_SET_SIZE - ;; The right to invoke `fd_filestat_set_times`. + ;;; The right to invoke `fd_filestat_set_times`. $RIGHT_FD_FILESTAT_SET_TIMES - ;; The right to invoke `path_symlink`. + ;;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_remove_directory`. + ;;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY - ;; The right to invoke `path_unlink_file`. + ;;; The right to invoke `path_unlink_file`. $RIGHT_PATH_UNLINK_FILE - ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE - ;; The right to invoke `sock_shutdown`. + ;;; The right to invoke `sock_shutdown`. $RIGHT_SOCK_SHUTDOWN ) ) -;; A file descriptor index. +;;; A file descriptor index. (typename $fd_t u32) -;; A region of memory for scatter/gather reads. +;;; A region of memory for scatter/gather reads. (typename $iovec_t (struct - ;; The address of the buffer to be filled. + ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) - ;; The length of the buffer to be filled. + ;;; The length of the buffer to be filled. (field $buf_len $size_t) ) ) -;; A region of memory for scatter/gather writes. +;;; A region of memory for scatter/gather writes. (typename $ciovec_t (struct - ;; The address of the buffer to be written. + ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) - ;; The length of the buffer to be written. + ;;; The length of the buffer to be written. (field $buf_len $size_t) ) ) @@ -299,469 +299,469 @@ (typename $iovec_t_array (array $iovec_t)) (typename $ciovec_t_array (array $ciovec_t)) -;; Relative offset within a file. +;;; Relative offset within a file. (typename $filedelta_t s64) -;; The position relative to which to set the offset of the file descriptor. +;;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 - ;; Seek relative to start-of-file. + ;;; Seek relative to start-of-file. $WHENCE_SET - ;; Seek relative to current position. + ;;; Seek relative to current position. $WHENCE_CUR - ;; Seek relative to end-of-file. + ;;; Seek relative to end-of-file. $WHENCE_END ) ) -;; A reference to the offset of a directory entry. +;;; A reference to the offset of a directory entry. ;; -;; The value 0 signifies the start of the directory. +;;; The value 0 signifies the start of the directory. (typename $dircookie_t u64) -;; The type for the $d_namlen field of $dirent_t. +;;; The type for the $d_namlen field of $dirent_t. (typename $dirnamlen_t u32) -;; File serial number that is unique within its file system. +;;; File serial number that is unique within its file system. (typename $inode_t u64) -;; The type of a file descriptor or file. +;;; The type of a file descriptor or file. (typename $filetype_t (enum u8 - ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $FILETYPE_UNKNOWN - ;; The file descriptor or file refers to a block device inode. + ;;; The file descriptor or file refers to a block device inode. $FILETYPE_BLOCK_DEVICE - ;; The file descriptor or file refers to a character device inode. + ;;; The file descriptor or file refers to a character device inode. $FILETYPE_CHARACTER_DEVICE - ;; The file descriptor or file refers to a directory inode. + ;;; The file descriptor or file refers to a directory inode. $FILETYPE_DIRECTORY - ;; The file descriptor or file refers to a regular file inode. + ;;; The file descriptor or file refers to a regular file inode. $FILETYPE_REGULAR_FILE - ;; The file descriptor or file refers to a datagram socket. + ;;; The file descriptor or file refers to a datagram socket. $FILETYPE_SOCKET_DGRAM - ;; The file descriptor or file refers to a byte-stream socket. + ;;; The file descriptor or file refers to a byte-stream socket. $FILETYPE_SOCKET_STREAM - ;; The file refers to a symbolic link inode. + ;;; The file refers to a symbolic link inode. $FILETYPE_SYMBOLIC_LINK ) ) -;; A directory entry. +;;; A directory entry. (typename $dirent_t (struct - ;; The offset of the next directory entry stored in this directory. + ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie_t) - ;; The serial number of the file referred to by this directory entry. + ;;; The serial number of the file referred to by this directory entry. (field $d_ino $inode_t) - ;; The length of the name of the directory entry. + ;;; The length of the name of the directory entry. (field $d_namlen $dirnamlen_t) - ;; The type of the file referred to by this directory entry. + ;;; The type of the file referred to by this directory entry. (field $d_type $filetype_t) ) ) -;; File or memory access pattern advisory information. +;;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application has no advice to give on its behavior with respect to the specified data. + ;;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL - ;; The application expects to access the specified data in a random order. + ;;; The application expects to access the specified data in a random order. $ADVICE_RANDOM - ;; The application expects to access the specified data in the near future. + ;;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED - ;; The application expects that it will not access the specified data in the near future. + ;;; The application expects that it will not access the specified data in the near future. $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. + ;;; The application expects to access the specified data once and then not reuse it thereafter. $ADVICE_NOREUSE ) ) -;; File descriptor flags. +;;; File descriptor flags. (typename $fdflags_t (flags u16 - ;; Append mode: Data written to the file is always appended to the file's end. + ;;; Append mode: Data written to the file is always appended to the file's end. $FDFLAG_APPEND - ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. $FDFLAG_DSYNC - ;; Non-blocking mode. + ;;; Non-blocking mode. $FDFLAG_NONBLOCK - ;; Synchronized read I/O operations. + ;;; Synchronized read I/O operations. $FDFLAG_RSYNC - ;; Write according to synchronized I/O file integrity completion. In - ;; addition to synchronizing the data stored in the file, the implementation - ;; may also synchronously update the file's metadata. + ;;; Write according to synchronized I/O file integrity completion. In + ;;; addition to synchronizing the data stored in the file, the implementation + ;;; may also synchronously update the file's metadata. $FDFLAG_SYNC ) ) -;; File descriptor attributes. +;;; File descriptor attributes. (typename $fdstat_t (struct - ;; File type. + ;;; File type. (field $fs_filetype $filetype_t) - ;; File descriptor flags. + ;;; File descriptor flags. (field $fs_flags $fdflags_t) - ;; Rights that apply to this file descriptor. + ;;; Rights that apply to this file descriptor. (field $fs_rights_base $rights_t) - ;; Maximum set of rights that may be installed on new file descriptors that - ;; are created through this file descriptor, e.g., through `path_open`. + ;;; Maximum set of rights that may be installed on new file descriptors that + ;;; are created through this file descriptor, e.g., through `path_open`. (field $fs_rights_inheriting $rights_t) ) ) -;; Identifier for a device containing a file system. Can be used in combination -;; with `inode_t` to uniquely identify a file or directory in the filesystem. +;;; Identifier for a device containing a file system. Can be used in combination +;;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) -;; Which file time attributes to adjust. +;;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 - ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. $FILESTAT_SET_ATIM - ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_ATIM_NOW - ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. $FILESTAT_SET_MTIM - ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_MTIM_NOW ) ) -;; Flags determining the method of how paths are resolved. +;;; Flags determining the method of how paths are resolved. (typename $lookupflags_t (flags u32 - ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $LOOKUP_SYMLINK_FOLLOW ) ) -;; Open flags used by `path_open`. +;;; Open flags used by `path_open`. (typename $oflags_t (flags u16 - ;; Create file if it does not exist. + ;;; Create file if it does not exist. $O_CREAT - ;; Fail if not a directory. + ;;; Fail if not a directory. $O_DIRECTORY - ;; Fail if file already exists. + ;;; Fail if file already exists. $O_EXCL - ;; Truncate file to size 0. + ;;; Truncate file to size 0. $O_TRUNC ) ) -;; Number of hard links to an inode. +;;; Number of hard links to an inode. (typename $linkcount_t u64) -;; File attributes. +;;; File attributes. (typename $filestat_t (struct - ;; Device ID of device containing the file. + ;;; Device ID of device containing the file. (field $st_dev $device_t) - ;; File serial number. + ;;; File serial number. (field $st_ino $inode_t) - ;; File type. + ;;; File type. (field $st_filetype $filetype_t) - ;; Number of hard links to the file. + ;;; Number of hard links to the file. (field $st_nlink $linkcount_t) - ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. (field $st_size $filesize_t) - ;; Last data access timestamp. + ;;; Last data access timestamp. (field $st_atim $timestamp_t) - ;; Last data modification timestamp. + ;;; Last data modification timestamp. (field $st_mtim $timestamp_t) - ;; Last file status change timestamp. + ;;; Last file status change timestamp. (field $st_ctim $timestamp_t) ) ) -;; User-provided value that may be attached to objects that is retained when -;; extracted from the implementation. +;;; User-provided value that may be attached to objects that is retained when +;;; extracted from the implementation. (typename $userdata_t u64) -;; Type of a subscription to an event or its occurrence. +;;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (enum u8 - ;; The time value of clock `subscription_t::u.clock.clock_id` has - ;; reached timestamp `subscription_t::u.clock.timeout`. + ;;; The time value of clock `subscription_t::u.clock.clock_id` has + ;;; reached timestamp `subscription_t::u.clock.timeout`. $EVENTTYPE_CLOCK - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data - ;; available for reading. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; available for reading. This event always triggers for regular files. $EVENTTYPE_FD_READ - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity - ;; available for writing. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;;; available for writing. This event always triggers for regular files. $EVENTTYPE_FD_WRITE ) ) -;; The state of the file descriptor subscribed to with -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The state of the file descriptor subscribed to with +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 - ;; The peer of this socket has closed or disconnected. + ;;; The peer of this socket has closed or disconnected. $EVENT_FD_READWRITE_HANGUP ) ) -;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;; `EVENTTYPE_FD_WRITE`. +;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;;; `EVENTTYPE_FD_WRITE`. (typename $event_fd_readwrite_t (struct - ;; The number of bytes available for reading or writing. + ;;; The number of bytes available for reading or writing. (field $nbytes $filesize_t) - ;; The state of the file descriptor. + ;;; The state of the file descriptor. (field $flags $eventrwflags_t) ) ) -;; The contents of an $event_t. +;;; The contents of an $event_t. (typename $event_u (union - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; An event that occurred. +;;; An event that occurred. (typename $event_t (struct - ;; User-provided value that got attached to `subscription_t::userdata`. + ;;; User-provided value that got attached to `subscription_t::userdata`. (field $userdata $userdata_t) - ;; If non-zero, an error that occurred while processing the subscription request. + ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno_t) - ;; The type of the event that occurred. + ;;; The type of the event that occurred. (field $type $eventtype_t) - ;; The contents of the event. + ;;; The contents of the event. (field $u $event_u) ) ) -;; Flags determining how to interpret the timestamp provided in -;; `subscription_t::u.clock.timeout.` +;;; Flags determining how to interpret the timestamp provided in +;;; `subscription_t::u.clock.timeout.` (typename $subclockflags_t (flags u16 - ;; If set, treat the timestamp provided in - ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;; provided in `subscription_t::u.clock.timeout` relative to the - ;; current time value of clock `subscription_t::u.clock.clock_id.` + ;;; If set, treat the timestamp provided in + ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription_t::u.clock.timeout` relative to the + ;;; current time value of clock `subscription_t::u.clock.clock_id.` $SUBSCRIPTION_CLOCK_ABSTIME ) ) -;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The clock against which to compare the timestamp. + ;;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. + ;;; The absolute or relative timestamp. (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. + ;;; The amount of time that the implementation may wait additionally + ;;; to coalesce with other events. (field $precision $timestamp_t) - ;; Flags specifying whether the timeout is absolute or relative + ;;; Flags specifying whether the timeout is absolute or relative (field $flags $subclockflags_t) ) ) -;; The contents of a $subscription_t when type is type is -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The contents of a $subscription_t when type is type is +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $subscription_fd_readwrite_t (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. + ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd_t) ) ) -;; The contents of a $subscription_t. +;;; The contents of a $subscription_t. (typename $subscription_u (union - ;; When type is `EVENTTYPE_CLOCK`: + ;;; When type is `EVENTTYPE_CLOCK`: (field $clock $subscription_clock_t) - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $subscription_fd_readwrite_t) ) ) -;; Subscription to an event. +;;; Subscription to an event. (typename $subscription_t (struct - ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through `event_t::userdata`. + ;;; User-provided value that is attached to the subscription in the + ;;; implementation and returned through `event_t::userdata`. (field $userdata $userdata_t) - ;; The type of the event to which to subscribe. + ;;; The type of the event to which to subscribe. (field $type $eventtype_t) - ;; The contents of the subscription. + ;;; The contents of the subscription. (field $u $subscription_u) ) ) -;; Exit code generated by a process when exiting. +;;; Exit code generated by a process when exiting. (typename $exitcode_t u32) -;; Signal condition. +;;; Signal condition. (typename $signal_t (enum u8 - ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;; so this value is reserved. + ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;;; so this value is reserved. $SIGNONE - ;; Hangup. - ;; Action: Terminates the process. + ;;; Hangup. + ;;; Action: Terminates the process. $SIGHUP - ;; Terminate interrupt signal. - ;; Action: Terminates the process. + ;;; Terminate interrupt signal. + ;;; Action: Terminates the process. $SIGINT - ;; Terminal quit signal. - ;; Action: Terminates the process. + ;;; Terminal quit signal. + ;;; Action: Terminates the process. $SIGQUIT - ;; Illegal instruction. - ;; Action: Terminates the process. + ;;; Illegal instruction. + ;;; Action: Terminates the process. $SIGILL - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. + ;;; Trace/breakpoint trap. + ;;; Action: Terminates the process. $SIGTRAP - ;; Process abort signal. - ;; Action: Terminates the process. + ;;; Process abort signal. + ;;; Action: Terminates the process. $SIGABRT - ;; Access to an undefined portion of a memory object. - ;; Action: Terminates the process. + ;;; Access to an undefined portion of a memory object. + ;;; Action: Terminates the process. $SIGBUS - ;; Erroneous arithmetic operation. - ;; Action: Terminates the process. + ;;; Erroneous arithmetic operation. + ;;; Action: Terminates the process. $SIGFPE - ;; Kill. - ;; Action: Terminates the process. + ;;; Kill. + ;;; Action: Terminates the process. $SIGKILL - ;; User-defined signal 1. - ;; Action: Terminates the process. + ;;; User-defined signal 1. + ;;; Action: Terminates the process. $SIGUSR1 - ;; Invalid memory reference. - ;; Action: Terminates the process. + ;;; Invalid memory reference. + ;;; Action: Terminates the process. $SIGSEGV - ;; User-defined signal 2. - ;; Action: Terminates the process. + ;;; User-defined signal 2. + ;;; Action: Terminates the process. $SIGUSR2 - ;; Write on a pipe with no one to read it. - ;; Action: Ignored. + ;;; Write on a pipe with no one to read it. + ;;; Action: Ignored. $SIGPIPE - ;; Alarm clock. - ;; Action: Terminates the process. + ;;; Alarm clock. + ;;; Action: Terminates the process. $SIGALRM - ;; Termination signal. - ;; Action: Terminates the process. + ;;; Termination signal. + ;;; Action: Terminates the process. $SIGTERM - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. + ;;; Child process terminated, stopped, or continued. + ;;; Action: Ignored. $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. + ;;; Continue executing, if stopped. + ;;; Action: Continues executing, if stopped. $SIGCONT - ;; Stop executing. - ;; Action: Stops executing. + ;;; Stop executing. + ;;; Action: Stops executing. $SIGSTOP - ;; Terminal stop signal. - ;; Action: Stops executing. + ;;; Terminal stop signal. + ;;; Action: Stops executing. $SIGTSTP - ;; Background process attempting read. - ;; Action: Stops executing. + ;;; Background process attempting read. + ;;; Action: Stops executing. $SIGTTIN - ;; Background process attempting write. - ;; Action: Stops executing. + ;;; Background process attempting write. + ;;; Action: Stops executing. $SIGTTOU - ;; High bandwidth data is available at a socket. - ;; Action: Ignored. + ;;; High bandwidth data is available at a socket. + ;;; Action: Ignored. $SIGURG - ;; CPU time limit exceeded. - ;; Action: Terminates the process. + ;;; CPU time limit exceeded. + ;;; Action: Terminates the process. $SIGXCPU - ;; File size limit exceeded. - ;; Action: Terminates the process. + ;;; File size limit exceeded. + ;;; Action: Terminates the process. $SIGXFSZ - ;; Virtual timer expired. - ;; Action: Terminates the process. + ;;; Virtual timer expired. + ;;; Action: Terminates the process. $SIGVTALRM - ;; Profiling timer expired. - ;; Action: Terminates the process. + ;;; Profiling timer expired. + ;;; Action: Terminates the process. $SIGPROF - ;; Window changed. - ;; Action: Ignored. + ;;; Window changed. + ;;; Action: Ignored. $SIGWINCH - ;; I/O possible. - ;; Action: Terminates the process. + ;;; I/O possible. + ;;; Action: Terminates the process. $SIGPOLL - ;; Power failure. - ;; Action: Terminates the process. + ;;; Power failure. + ;;; Action: Terminates the process. $SIGPWR - ;; Bad system call. - ;; Action: Terminates the process. + ;;; Bad system call. + ;;; Action: Terminates the process. $SIGSYS ) ) -;; Flags provided to `sock_recv`. +;;; Flags provided to `sock_recv`. (typename $riflags_t (flags u16 - ;; Returns the message without removing it from the socket's receive queue. + ;;; Returns the message without removing it from the socket's receive queue. $SOCK_RECV_PEEK - ;; On byte-stream sockets, block until the full amount of data can be returned. + ;;; On byte-stream sockets, block until the full amount of data can be returned. $SOCK_RECV_WAITALL ) ) -;; Flags returned by `sock_recv`. +;;; Flags returned by `sock_recv`. (typename $roflags_t (flags u16 - ;; Returned by `sock_recv`: Message data has been truncated. + ;;; Returned by `sock_recv`: Message data has been truncated. $SOCK_RECV_DATA_TRUNCATED ) ) -;; Flags provided to `sock_send`. As there are currently no flags -;; defined, it must be set to zero. +;;; Flags provided to `sock_send`. As there are currently no flags +;;; defined, it must be set to zero. (typename $siflags_t u16) -;; Which channels on a socket to shut down. +;;; Which channels on a socket to shut down. (typename $sdflags_t (flags u8 - ;; Disables further receive operations. + ;;; Disables further receive operations. $SHUT_RD - ;; Disables further send operations. + ;;; Disables further send operations. $SHUT_WR ) ) -;; Identifiers for preopened capabilities. +;;; Identifiers for preopened capabilities. (typename $preopentype_t (enum u8 - ;; A pre-opened directory. + ;;; A pre-opened directory. $PREOPENTYPE_DIR ) ) -;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. (typename $prestat_dir (struct - ;; The length of the directory name for use with `fd_prestat_dir_name`. + ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size_t) ) ) -;; The contents of an $prestat_t. +;;; The contents of an $prestat_t. (typename $prestat_u (union - ;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `PREOPENTYPE_DIR`: (field $dir $prestat_dir) ) ) -;; Information about a pre-opened capability. +;;; Information about a pre-opened capability. (typename $prestat_t (struct - ;; The type of the pre-opened capability. + ;;; The type of the pre-opened capability. (field $pr_type $preopentype_t) - ;; The contents of the information. + ;;; The contents of the information. (field $u $prestat_u) ) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx index f98ff129b..d15b8c514 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -9,519 +9,522 @@ (use "typenames.witx") (module $wasi_ephemeral_preview - ;; Linear memory to be accessed by WASI functions that need it. + ;;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) - ;; Read command-line argument data. - ;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; Read command-line argument data. + ;;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Read environment variable data. - ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; Read environment variable data. + ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Return the resolution of a clock. - ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;; Note: This is similar to `clock_getres` in POSIX. + ;;; Return the resolution of a clock. + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno_t) - ;; The clock for which to return the resolution. + ;;; The clock for which to return the resolution. (param $clock_id $clockid_t) - ;; The resolution of the clock. + ;;; The resolution of the clock. (result $resolution $timestamp_t) ) - ;; Return the time value of a clock. - ;; Note: This is similar to `clock_gettime` in POSIX. + ;;; Return the time value of a clock. + ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") - ;; The clock for which to return the time. + ;;; The clock for which to return the time. (param $clock_id $clockid_t) - ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp_t) (result $error $errno_t) - ;; The time value of the clock. + ;;; The time value of the clock. (result $time $timestamp_t) ) - ;; Provide file advisory information on a file descriptor. - ;; Note: This is similar to `posix_fadvise` in POSIX. + ;;; Provide file advisory information on a file descriptor. + ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") (param $fd $fd_t) - (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. - (param $len $filesize_t) ;; The length of the region to which the advisory applies. - (param $advice $advice_t) ;; The advice. + ;;; The offset within the file to which the advisory applies. + (param $offset $filesize_t) + ;;; The length of the region to which the advisory applies. + (param $len $filesize_t) + ;;; The advice. + (param $advice $advice_t) (result $error $errno_t) ) - ;; Force the allocation of space in a file. - ;; Note: This is similar to `posix_fallocate` in POSIX. + ;;; Force the allocation of space in a file. + ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") (param $fd $fd_t) - ;; The offset at which to start the allocation. + ;;; The offset at which to start the allocation. (param $offset $filesize_t) - ;; The length of the area that is allocated. + ;;; The length of the area that is allocated. (param $len $filesize_t) (result $error $errno_t) ) - ;; Close a file descriptor. - ;; Note: This is similar to `close` in POSIX. + ;;; Close a file descriptor. + ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd_t) (result $error $errno_t) ) - ;; Synchronize the data of a file to disk. - ;; Note: This is similar to `fdatasync` in POSIX. + ;;; Synchronize the data of a file to disk. + ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Get the attributes of a file descriptor. - ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + ;;; Get the attributes of a file descriptor. + ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file descriptor's attributes are stored. + ;;; The buffer where the file descriptor's attributes are stored. (result $stat $fdstat_t) ) - ;; Adjust the flags associated with a file descriptor. - ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + ;;; Adjust the flags associated with a file descriptor. + ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") (param $fd $fd_t) - ;; The desired values of the file descriptor flags. + ;;; The desired values of the file descriptor flags. (param $flags $fdflags_t) (result $error $errno_t) ) - ;; Adjust the rights associated with a file descriptor. - ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; Adjust the rights associated with a file descriptor. + ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd_t) - ;; The desired rights of the file descriptor. + ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights_t) (param $fs_rights_inheriting $rights_t) (result $error $errno_t) ) - ;; Return the attributes of an open file. + ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;; Note: This is similar to `ftruncate` in POSIX. + ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") (param $fd $fd_t) - ;; The desired file size. + ;;; The desired file size. (param $st_size $filesize_t) (result $error $errno_t) ) - ;; Adjust the timestamps of an open file or directory. - ;; Note: This is similar to `futimens` in POSIX. + ;;; Adjust the timestamps of an open file or directory. + ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") (param $fd $fd_t) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `preadv` in POSIX. + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") (param $fd $fd_t) - ;; List of scatter/gather vectors in which to store data. + ;;; List of scatter/gather vectors in which to store data. (param $iovs $iovec_t_array) - ;; The offset within the file at which to read. + ;;; The offset within the file at which to read. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the description is stored. + ;;; The buffer where the description is stored. (result $buf $prestat_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") (param $fd $fd_t) - ;; A buffer into which to write the preopened directory name. + ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size_t) (result $error $errno_t) ) - ;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `pwritev` in POSIX. + ;;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) - ;; The offset within the file at which to write. + ;;; The offset within the file at which to write. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Read from a file descriptor. - ;; Note: This is similar to `readv` in POSIX. + ;;; Read from a file descriptor. + ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_t_array) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Read directory entries from a directory. - ;; When successful, the contents of the output buffer consist of a sequence of - ;; directory entries. Each directory entry consists of a dirent_t object, - ;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;; entry. + ;;; Read directory entries from a directory. + ;;; When successful, the contents of the output buffer consist of a sequence of + ;;; directory entries. Each directory entry consists of a dirent_t object, + ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; entry. ;; - ;; This function fills the output buffer as much as possible, potentially - ;; truncating the last directory entry. This allows the caller to grow its - ;; read buffer size in case it's too small to fit a single large directory - ;; entry, or skip the oversized directory entry. + ;;; This function fills the output buffer as much as possible, potentially + ;;; truncating the last directory entry. This allows the caller to grow its + ;;; read buffer size in case it's too small to fit a single large directory + ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") (param $fd $fd_t) - ;; The buffer where directory entries are stored + ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) (param $buf_len $size_t) - ;; The location within the directory to start reading + ;;; The location within the directory to start reading (param $cookie $dircookie_t) (result $error $errno_t) - ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. (result $bufused $size_t) ) - ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;;; Atomically replace a file descriptor by renumbering another file descriptor. ;; - ;; Due to the strong focus on thread safety, this environment does not provide - ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;; file descriptor with the same number could be allocated by a different - ;; thread at the same time. + ;;; Due to the strong focus on thread safety, this environment does not provide + ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;;; file descriptor with the same number could be allocated by a different + ;;; thread at the same time. ;; - ;; This function provides a way to atomically renumber file descriptors, which - ;; would disappear if `dup2()` were to be removed entirely. + ;;; This function provides a way to atomically renumber file descriptors, which + ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") (param $fd $fd_t) - ;; The file descriptor to overwrite. + ;;; The file descriptor to overwrite. (param $to $fd_t) (result $error $errno_t) ) - ;; Move the offset of a file descriptor. - ;; Note: This is similar to `lseek` in POSIX. + ;;; Move the offset of a file descriptor. + ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") (param $fd $fd_t) - ;; The number of bytes to move. + ;;; The number of bytes to move. (param $offset $filedelta_t) - ;; The base from which the offset is relative. + ;;; The base from which the offset is relative. (param $whence $whence_t) (result $error $errno_t) - ;; The new offset of the file descriptor, relative to the start of the file. + ;;; The new offset of the file descriptor, relative to the start of the file. (result $newoffset $filesize_t) ) - ;; Synchronize the data and metadata of a file to disk. - ;; Note: This is similar to `fsync` in POSIX. + ;;; Synchronize the data and metadata of a file to disk. + ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Return the current offset of a file descriptor. - ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + ;;; Return the current offset of a file descriptor. + ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd_t) (result $error $errno_t) - ;; The current offset of the file descriptor, relative to the start of the file. + ;;; The current offset of the file descriptor, relative to the start of the file. (result $offset $filesize_t) ) - ;; Write to a file descriptor. - ;; Note: This is similar to `writev` in POSIX. + ;;; Write to a file descriptor. + ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Create a directory. - ;; Note: This is similar to `mkdirat` in POSIX. + ;;; Create a directory. + ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") (param $fd $fd_t) - ;; The path at which to create the directory. + ;;; The path at which to create the directory. (param $path string) (result $error $errno_t) ) - ;; Return the attributes of a file or directory. - ;; Note: This is similar to `stat` in POSIX. + ;;; Return the attributes of a file or directory. + ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to inspect. + ;;; The path of the file or directory to inspect. (param $path string) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the timestamps of a file or directory. - ;; Note: This is similar to `utimensat` in POSIX. + ;;; Adjust the timestamps of a file or directory. + ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to operate on. + ;;; The path of the file or directory to operate on. (param $path string) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Create a hard link. - ;; Note: This is similar to `linkat` in POSIX. + ;;; Create a hard link. + ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") (param $old_fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) - ;; The source path from which to link. + ;;; The source path from which to link. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path at which to create the hard link. + ;;; The destination path at which to create the hard link. (param $new_path string) (result $error $errno_t) ) - ;; Open a file or directory. + ;;; Open a file or directory. ;; - ;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;; file descriptor not currently open; it is randomized to prevent - ;; applications from depending on making assumptions about indexes, since this - ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 2**31. + ;;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;;; file descriptor not currently open; it is randomized to prevent + ;;; applications from depending on making assumptions about indexes, since this + ;;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;;; guaranteed to be less than 2**31. ;; - ;; Note: This is similar to `openat` in POSIX. + ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags_t) - ;; The relative path of the file or directory to open, relative to the - ;; `dirfd` directory. + ;;; The relative path of the file or directory to open, relative to the + ;;; `dirfd` directory. (param $path string) - ;; The method by which to open the file. + ;;; The method by which to open the file. (param $o_flags $oflags_t) - ;; The initial rights of the newly created file descriptor. The - ;; implementation is allowed to return a file descriptor with fewer rights - ;; than specified, if and only if those rights do not apply to the type of - ;; file being opened. + ;;; The initial rights of the newly created file descriptor. The + ;;; implementation is allowed to return a file descriptor with fewer rights + ;;; than specified, if and only if those rights do not apply to the type of + ;;; file being opened. ;; - ;; The *base* rights are rights that will apply to operations using the file - ;; descriptor itself, while the *inheriting* rights are rights that apply to - ;; file descriptors derived from it. + ;;; The *base* rights are rights that will apply to operations using the file + ;;; descriptor itself, while the *inheriting* rights are rights that apply to + ;;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) (param $flags $fdflags_t) (result $error $errno_t) - ;; The file descriptor of the file that has been opened. + ;;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) ) - ;; Read the contents of a symbolic link. - ;; Note: This is similar to `readlinkat` in POSIX. + ;;; Read the contents of a symbolic link. + ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") (param $fd $fd_t) - ;; The path of the symbolic link from which to read. + ;;; The path of the symbolic link from which to read. (param $path string) - ;; The buffer to which to write the contents of the symbolic link. + ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) - ;; The number of bytes placed in the buffer. + ;;; The number of bytes placed in the buffer. (result $bufused $size_t) ) - ;; Remove a directory. - ;; Return `ENOTEMPTY` if the directory is not empty. - ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + ;;; Remove a directory. + ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd_t) - ;; The path to a directory to remove. + ;;; The path to a directory to remove. (param $path string) (result $error $errno_t) ) - ;; Rename a file or directory. - ;; Note: This is similar to `renameat` in POSIX. + ;;; Rename a file or directory. + ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") (param $fd $fd_t) - ;; The source path of the file or directory to rename. + ;;; The source path of the file or directory to rename. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path to which to rename the file or directory. + ;;; The destination path to which to rename the file or directory. (param $new_path string) (result $error $errno_t) ) - ;; Create a symbolic link. - ;; Note: This is similar to `symlinkat` in POSIX. + ;;; Create a symbolic link. + ;;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - ;; The contents of the symbolic link. + ;;; The contents of the symbolic link. (param $old_path string) (param $fd $fd_t) - ;; The destination path at which to create the symbolic link. + ;;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) ) - ;; Unlink a file. - ;; Return `EISDIR` if the path refers to a directory. - ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + ;;; Unlink a file. + ;;; Return `EISDIR` if the path refers to a directory. + ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd_t) - ;; The path to a file to unlink. + ;;; The path to a file to unlink. (param $path string) (result $error $errno_t) ) - ;; Concurrently poll for the occurrence of a set of events. + ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") - ;; The events to which to subscribe. + ;;; The events to which to subscribe. (param $in (@witx const_pointer $subscription_t)) - ;; The events that have occurred. + ;;; The events that have occurred. (param $out (@witx pointer $event_t)) - ;; Both the number of subscriptions and events. + ;;; Both the number of subscriptions and events. (param $nsubscriptions $size_t) (result $error $errno_t) - ;; The number of events stored. + ;;; The number of events stored. (result $nevents $size_t) ) - ;; Terminate the process normally. An exit code of 0 indicates successful - ;; termination of the program. The meanings of other values is dependent on - ;; the environment. + ;;; Terminate the process normally. An exit code of 0 indicates successful + ;;; termination of the program. The meanings of other values is dependent on + ;;; the environment. (@interface func (export "proc_exit") - ;; The exit code returned by the process. + ;;; The exit code returned by the process. (param $rval $exitcode_t) ) - ;; Send a signal to the process of the calling thread. - ;; Note: This is similar to `raise` in POSIX. + ;;; Send a signal to the process of the calling thread. + ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") - ;; The signal condition to trigger. + ;;; The signal condition to trigger. (param $sig $signal_t) (result $error $errno_t) ) - ;; Temporarily yield execution of the calling thread. - ;; Note: This is similar to `sched_yield` in POSIX. + ;;; Temporarily yield execution of the calling thread. + ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") (result $error $errno_t) ) - ;; Write high-quality random data into a buffer. - ;; This function blocks when the implementation is unable to immediately - ;; provide sufficient high-quality random data. - ;; This function may execute slowly, so when large mounts of random data are - ;; required, it's advisable to use this function to seed a pseudo-random - ;; number generator, rather than to provide the random data directly. + ;;; Write high-quality random data into a buffer. + ;;; This function blocks when the implementation is unable to immediately + ;;; provide sufficient high-quality random data. + ;;; This function may execute slowly, so when large mounts of random data are + ;;; required, it's advisable to use this function to seed a pseudo-random + ;;; number generator, rather than to provide the random data directly. (@interface func (export "random_get") - ;; The buffer to fill with random data. + ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) ) - ;; Receive a message from a socket. - ;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;; the data into multiple buffers in the manner of `readv`. + ;;; Receive a message from a socket. + ;;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $ri_data $iovec_t_array) - ;; Message flags. + ;;; Message flags. (param $ri_flags $riflags_t) (result $error $errno_t) - ;; Number of bytes stored in ri_data. + ;;; Number of bytes stored in ri_data. (result $ro_datalen $size_t) - ;; Message flags. + ;;; Message flags. (result $ro_flags $roflags_t) ) - ;; Send a message on a socket. - ;; Note: This is similar to `send` in POSIX, though it also supports writing - ;; the data from multiple buffers in the manner of `writev`. + ;;; Send a message on a socket. + ;;; Note: This is similar to `send` in POSIX, though it also supports writing + ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to retrieve data + ;;; List of scatter/gather vectors to which to retrieve data (param $si_data $ciovec_t_array) - ;; Message flags. + ;;; Message flags. (param $si_flags $siflags_t) (result $error $errno_t) - ;; Number of bytes transmitted. + ;;; Number of bytes transmitted. (result $so_datalen $size_t) ) - ;; Shut down socket send and receive channels. - ;; Note: This is similar to `shutdown` in POSIX. + ;;; Shut down socket send and receive channels. + ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") (param $fd $fd_t) - ;; Which channels on the socket to shut down. + ;;; Which channels on the socket to shut down. (param $how $sdflags_t) (result $error $errno_t) ) diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx index 15b53af51..cf39a2deb 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx @@ -7,291 +7,291 @@ (typename $size_t u32) -;; Non-negative file size or length of a region within a file. +;;; Non-negative file size or length of a region within a file. (typename $filesize_t u64) -;; Timestamp in nanoseconds. +;;; Timestamp in nanoseconds. (typename $timestamp_t u64) -;; Identifiers for clocks. +;;; Identifiers for clocks. (typename $clockid_t (enum u32 - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. + ;;; The clock measuring real time. Time value zero corresponds with + ;;; 1970-01-01T00:00:00Z. $CLOCK_REALTIME - ;; The store-wide monotonic clock, which is defined as a clock measuring - ;; real time, whose value cannot be adjusted and which cannot have negative - ;; clock jumps. The epoch of this clock is undefined. The absolute time - ;; value of this clock therefore has no meaning. + ;;; The store-wide monotonic clock, which is defined as a clock measuring + ;;; real time, whose value cannot be adjusted and which cannot have negative + ;;; clock jumps. The epoch of this clock is undefined. The absolute time + ;;; value of this clock therefore has no meaning. $CLOCK_MONOTONIC - ;; The CPU-time clock associated with the current process. + ;;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The CPU-time clock associated with the current thread. + ;;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) ) -;; Error codes returned by functions. -;; Not all of these error codes are returned by the functions provided by this -;; API; some are used in higher-level library layers, and others are provided -;; merely for alignment with POSIX. +;;; Error codes returned by functions. +;;; Not all of these error codes are returned by the functions provided by this +;;; API; some are used in higher-level library layers, and others are provided +;;; merely for alignment with POSIX. (typename $errno_t (enum u16 - ;; No error occurred. System call completed successfully. + ;;; No error occurred. System call completed successfully. $ESUCCESS - ;; Argument list too long. + ;;; Argument list too long. $E2BIG - ;; Permission denied. + ;;; Permission denied. $EACCES - ;; Address in use. + ;;; Address in use. $EADDRINUSE - ;; Address not available. + ;;; Address not available. $EADDRNOTAVAIL - ;; Address family not supported. + ;;; Address family not supported. $EAFNOSUPPORT - ;; Resource unavailable, or operation would block. + ;;; Resource unavailable, or operation would block. $EAGAIN - ;; Connection already in progress. + ;;; Connection already in progress. $EALREADY - ;; Bad file descriptor. + ;;; Bad file descriptor. $EBADF - ;; Bad message. + ;;; Bad message. $EBADMSG - ;; Device or resource busy. + ;;; Device or resource busy. $EBUSY - ;; Operation canceled. + ;;; Operation canceled. $ECANCELED - ;; No child processes. + ;;; No child processes. $ECHILD - ;; Connection aborted. + ;;; Connection aborted. $ECONNABORTED - ;; Connection refused. + ;;; Connection refused. $ECONNREFUSED - ;; Connection reset. + ;;; Connection reset. $ECONNRESET - ;; Resource deadlock would occur. + ;;; Resource deadlock would occur. $EDEADLK - ;; Destination address required. + ;;; Destination address required. $EDESTADDRREQ - ;; Mathematics argument out of domain of function. + ;;; Mathematics argument out of domain of function. $EDOM - ;; Reserved. + ;;; Reserved. $EDQUOT - ;; File exists. + ;;; File exists. $EEXIST - ;; Bad address. + ;;; Bad address. $EFAULT - ;; File too large. + ;;; File too large. $EFBIG - ;; Host is unreachable. + ;;; Host is unreachable. $EHOSTUNREACH - ;; Identifier removed. + ;;; Identifier removed. $EIDRM - ;; Illegal byte sequence. + ;;; Illegal byte sequence. $EILSEQ - ;; Operation in progress. + ;;; Operation in progress. $EINPROGRESS - ;; Interrupted function. + ;;; Interrupted function. $EINTR - ;; Invalid argument. + ;;; Invalid argument. $EINVAL - ;; I/O error. + ;;; I/O error. $EIO - ;; Socket is connected. + ;;; Socket is connected. $EISCONN - ;; Is a directory. + ;;; Is a directory. $EISDIR - ;; Too many levels of symbolic links. + ;;; Too many levels of symbolic links. $ELOOP - ;; File descriptor value too large. + ;;; File descriptor value too large. $EMFILE - ;; Too many links. + ;;; Too many links. $EMLINK - ;; Message too large. + ;;; Message too large. $EMSGSIZE - ;; Reserved. + ;;; Reserved. $EMULTIHOP - ;; Filename too long. + ;;; Filename too long. $ENAMETOOLONG - ;; Network is down. + ;;; Network is down. $ENETDOWN - ;; Connection aborted by network. + ;;; Connection aborted by network. $ENETRESET - ;; Network unreachable. + ;;; Network unreachable. $ENETUNREACH - ;; Too many files open in system. + ;;; Too many files open in system. $ENFILE - ;; No buffer space available. + ;;; No buffer space available. $ENOBUFS - ;; No such device. + ;;; No such device. $ENODEV - ;; No such file or directory. + ;;; No such file or directory. $ENOENT - ;; Executable file format error. + ;;; Executable file format error. $ENOEXEC - ;; No locks available. + ;;; No locks available. $ENOLCK - ;; Reserved. + ;;; Reserved. $ENOLINK - ;; Not enough space. + ;;; Not enough space. $ENOMEM - ;; No message of the desired type. + ;;; No message of the desired type. $ENOMSG - ;; Protocol not available. + ;;; Protocol not available. $ENOPROTOOPT - ;; No space left on device. + ;;; No space left on device. $ENOSPC - ;; Function not supported. + ;;; Function not supported. $ENOSYS - ;; The socket is not connected. + ;;; The socket is not connected. $ENOTCONN - ;; Not a directory or a symbolic link to a directory. + ;;; Not a directory or a symbolic link to a directory. $ENOTDIR - ;; Directory not empty. + ;;; Directory not empty. $ENOTEMPTY - ;; State not recoverable. + ;;; State not recoverable. $ENOTRECOVERABLE - ;; Not a socket. + ;;; Not a socket. $ENOTSOCK - ;; Not supported, or operation not supported on socket. + ;;; Not supported, or operation not supported on socket. $ENOTSUP - ;; Inappropriate I/O control operation. + ;;; Inappropriate I/O control operation. $ENOTTY - ;; No such device or address. + ;;; No such device or address. $ENXIO - ;; Value too large to be stored in data type. + ;;; Value too large to be stored in data type. $EOVERFLOW - ;; Previous owner died. + ;;; Previous owner died. $EOWNERDEAD - ;; Operation not permitted. + ;;; Operation not permitted. $EPERM - ;; Broken pipe. + ;;; Broken pipe. $EPIPE - ;; Protocol error. + ;;; Protocol error. $EPROTO - ;; Protocol not supported. + ;;; Protocol not supported. $EPROTONOSUPPORT - ;; Protocol wrong type for socket. + ;;; Protocol wrong type for socket. $EPROTOTYPE - ;; Result too large. + ;;; Result too large. $ERANGE - ;; Read-only file system. + ;;; Read-only file system. $EROFS - ;; Invalid seek. + ;;; Invalid seek. $ESPIPE - ;; No such process. + ;;; No such process. $ESRCH - ;; Reserved. + ;;; Reserved. $ESTALE - ;; Connection timed out. + ;;; Connection timed out. $ETIMEDOUT - ;; Text file busy. + ;;; Text file busy. $ETXTBSY - ;; Cross-device link. + ;;; Cross-device link. $EXDEV - ;; Extension: Capabilities insufficient. + ;;; Extension: Capabilities insufficient. $ENOTCAPABLE ) ) -;; File descriptor rights, determining which actions may be performed. +;;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke `fd_datasync`. + ;;; The right to invoke `fd_datasync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_DSYNC`. $RIGHT_FD_DATASYNC - ;; The right to invoke `fd_read` and `sock_recv`. + ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. $RIGHT_FD_READ - ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. $RIGHT_FD_SEEK - ;; The right to invoke `fd_fdstat_set_flags`. + ;;; The right to invoke `fd_fdstat_set_flags`. $RIGHT_FD_FDSTAT_SET_FLAGS - ;; The right to invoke `fd_sync`. + ;;; The right to invoke `fd_sync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. $RIGHT_FD_SYNC - ;; The right to invoke `fd_seek` in such a way that the file offset - ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to - ;; invoke `fd_tell`. + ;;; The right to invoke `fd_seek` in such a way that the file offset + ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; invoke `fd_tell`. $RIGHT_FD_TELL - ;; The right to invoke `fd_write` and `sock_send`. - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + ;;; The right to invoke `fd_write` and `sock_send`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. $RIGHT_FD_WRITE - ;; The right to invoke `fd_advise`. + ;;; The right to invoke `fd_advise`. $RIGHT_FD_ADVISE - ;; The right to invoke `fd_allocate`. + ;;; The right to invoke `fd_allocate`. $RIGHT_FD_ALLOCATE - ;; The right to invoke `path_create_directory`. + ;;; The right to invoke `path_create_directory`. $RIGHT_PATH_CREATE_DIRECTORY - ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. $RIGHT_PATH_CREATE_FILE - ;; The right to invoke `path_link` with the file descriptor as the - ;; source directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; source directory. $RIGHT_PATH_LINK_SOURCE - ;; The right to invoke `path_link` with the file descriptor as the - ;; target directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; target directory. $RIGHT_PATH_LINK_TARGET - ;; The right to invoke `path_open`. + ;;; The right to invoke `path_open`. $RIGHT_PATH_OPEN - ;; The right to invoke `fd_readdir`. + ;;; The right to invoke `fd_readdir`. $RIGHT_FD_READDIR - ;; The right to invoke `path_readlink`. + ;;; The right to invoke `path_readlink`. $RIGHT_PATH_READLINK - ;; The right to invoke `path_rename` with the file descriptor as the source directory. + ;;; The right to invoke `path_rename` with the file descriptor as the source directory. $RIGHT_PATH_RENAME_SOURCE - ;; The right to invoke `path_rename` with the file descriptor as the target directory. + ;;; The right to invoke `path_rename` with the file descriptor as the target directory. $RIGHT_PATH_RENAME_TARGET - ;; The right to invoke `path_filestat_get`. + ;;; The right to invoke `path_filestat_get`. $RIGHT_PATH_FILESTAT_GET - ;; The right to change a file's size (there is no `path_filestat_set_size`). - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + ;;; The right to change a file's size (there is no `path_filestat_set_size`). + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. $RIGHT_PATH_FILESTAT_SET_SIZE - ;; The right to invoke `path_filestat_set_times`. + ;;; The right to invoke `path_filestat_set_times`. $RIGHT_PATH_FILESTAT_SET_TIMES - ;; The right to invoke `fd_filestat_get`. + ;;; The right to invoke `fd_filestat_get`. $RIGHT_FD_FILESTAT_GET - ;; The right to invoke `fd_filestat_set_size`. + ;;; The right to invoke `fd_filestat_set_size`. $RIGHT_FD_FILESTAT_SET_SIZE - ;; The right to invoke `fd_filestat_set_times`. + ;;; The right to invoke `fd_filestat_set_times`. $RIGHT_FD_FILESTAT_SET_TIMES - ;; The right to invoke `path_symlink`. + ;;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_remove_directory`. + ;;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY - ;; The right to invoke `path_unlink_file`. + ;;; The right to invoke `path_unlink_file`. $RIGHT_PATH_UNLINK_FILE - ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE - ;; The right to invoke `sock_shutdown`. + ;;; The right to invoke `sock_shutdown`. $RIGHT_SOCK_SHUTDOWN ) ) -;; A file descriptor index. +;;; A file descriptor index. (typename $fd_t u32) -;; A region of memory for scatter/gather reads. +;;; A region of memory for scatter/gather reads. (typename $iovec_t (struct - ;; The address of the buffer to be filled. + ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) - ;; The length of the buffer to be filled. + ;;; The length of the buffer to be filled. (field $buf_len $size_t) ) ) -;; A region of memory for scatter/gather writes. +;;; A region of memory for scatter/gather writes. (typename $ciovec_t (struct - ;; The address of the buffer to be written. + ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) - ;; The length of the buffer to be written. + ;;; The length of the buffer to be written. (field $buf_len $size_t) ) ) @@ -299,469 +299,469 @@ (typename $iovec_t_array (array $iovec_t)) (typename $ciovec_t_array (array $ciovec_t)) -;; Relative offset within a file. +;;; Relative offset within a file. (typename $filedelta_t s64) -;; The position relative to which to set the offset of the file descriptor. +;;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 - ;; Seek relative to current position. + ;;; Seek relative to current position. $WHENCE_CUR - ;; Seek relative to end-of-file. + ;;; Seek relative to end-of-file. $WHENCE_END - ;; Seek relative to start-of-file. + ;;; Seek relative to start-of-file. $WHENCE_SET ) ) -;; A reference to the offset of a directory entry. +;;; A reference to the offset of a directory entry. (typename $dircookie_t u64) -;; The type for the $d_namlen field of $dirent_t. +;;; The type for the $d_namlen field of $dirent_t. (typename $dirnamlen_t u32) -;; File serial number that is unique within its file system. +;;; File serial number that is unique within its file system. (typename $inode_t u64) -;; The type of a file descriptor or file. +;;; The type of a file descriptor or file. (typename $filetype_t (enum u8 - ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $FILETYPE_UNKNOWN - ;; The file descriptor or file refers to a block device inode. + ;;; The file descriptor or file refers to a block device inode. $FILETYPE_BLOCK_DEVICE - ;; The file descriptor or file refers to a character device inode. + ;;; The file descriptor or file refers to a character device inode. $FILETYPE_CHARACTER_DEVICE - ;; The file descriptor or file refers to a directory inode. + ;;; The file descriptor or file refers to a directory inode. $FILETYPE_DIRECTORY - ;; The file descriptor or file refers to a regular file inode. + ;;; The file descriptor or file refers to a regular file inode. $FILETYPE_REGULAR_FILE - ;; The file descriptor or file refers to a datagram socket. + ;;; The file descriptor or file refers to a datagram socket. $FILETYPE_SOCKET_DGRAM - ;; The file descriptor or file refers to a byte-stream socket. + ;;; The file descriptor or file refers to a byte-stream socket. $FILETYPE_SOCKET_STREAM - ;; The file refers to a symbolic link inode. + ;;; The file refers to a symbolic link inode. $FILETYPE_SYMBOLIC_LINK ) ) -;; A directory entry. +;;; A directory entry. (typename $dirent_t (struct - ;; The offset of the next directory entry stored in this directory. + ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie_t) - ;; The serial number of the file referred to by this directory entry. + ;;; The serial number of the file referred to by this directory entry. (field $d_ino $inode_t) - ;; The length of the name of the directory entry. + ;;; The length of the name of the directory entry. (field $d_namlen $dirnamlen_t) - ;; The type of the file referred to by this directory entry. + ;;; The type of the file referred to by this directory entry. (field $d_type $filetype_t) ) ) -;; File or memory access pattern advisory information. +;;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application has no advice to give on its behavior with respect to the specified data. + ;;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL - ;; The application expects to access the specified data in a random order. + ;;; The application expects to access the specified data in a random order. $ADVICE_RANDOM - ;; The application expects to access the specified data in the near future. + ;;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED - ;; The application expects that it will not access the specified data in the near future. + ;;; The application expects that it will not access the specified data in the near future. $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. + ;;; The application expects to access the specified data once and then not reuse it thereafter. $ADVICE_NOREUSE ) ) -;; File descriptor flags. +;;; File descriptor flags. (typename $fdflags_t (flags u16 - ;; Append mode: Data written to the file is always appended to the file's end. + ;;; Append mode: Data written to the file is always appended to the file's end. $FDFLAG_APPEND - ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. $FDFLAG_DSYNC - ;; Non-blocking mode. + ;;; Non-blocking mode. $FDFLAG_NONBLOCK - ;; Synchronized read I/O operations. + ;;; Synchronized read I/O operations. $FDFLAG_RSYNC - ;; Write according to synchronized I/O file integrity completion. In - ;; addition to synchronizing the data stored in the file, the implementation - ;; may also synchronously update the file's metadata. + ;;; Write according to synchronized I/O file integrity completion. In + ;;; addition to synchronizing the data stored in the file, the implementation + ;;; may also synchronously update the file's metadata. $FDFLAG_SYNC ) ) -;; File descriptor attributes. +;;; File descriptor attributes. (typename $fdstat_t (struct - ;; File type. + ;;; File type. (field $fs_filetype $filetype_t) - ;; File descriptor flags. + ;;; File descriptor flags. (field $fs_flags $fdflags_t) - ;; Rights that apply to this file descriptor. + ;;; Rights that apply to this file descriptor. (field $fs_rights_base $rights_t) - ;; Maximum set of rights that may be installed on new file descriptors that - ;; are created through this file descriptor, e.g., through `path_open`. + ;;; Maximum set of rights that may be installed on new file descriptors that + ;;; are created through this file descriptor, e.g., through `path_open`. (field $fs_rights_inheriting $rights_t) ) ) -;; Identifier for a device containing a file system. Can be used in combination -;; with `inode_t` to uniquely identify a file or directory in the filesystem. +;;; Identifier for a device containing a file system. Can be used in combination +;;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) -;; Which file time attributes to adjust. +;;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 - ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. $FILESTAT_SET_ATIM - ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_ATIM_NOW - ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. $FILESTAT_SET_MTIM - ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_MTIM_NOW ) ) -;; Flags determining the method of how paths are resolved. +;;; Flags determining the method of how paths are resolved. (typename $lookupflags_t (flags u32 - ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $LOOKUP_SYMLINK_FOLLOW ) ) -;; Open flags used by `path_open`. +;;; Open flags used by `path_open`. (typename $oflags_t (flags u16 - ;; Create file if it does not exist. + ;;; Create file if it does not exist. $O_CREAT - ;; Fail if not a directory. + ;;; Fail if not a directory. $O_DIRECTORY - ;; Fail if file already exists. + ;;; Fail if file already exists. $O_EXCL - ;; Truncate file to size 0. + ;;; Truncate file to size 0. $O_TRUNC ) ) -;; Number of hard links to an inode. +;;; Number of hard links to an inode. (typename $linkcount_t u32) -;; File attributes. +;;; File attributes. (typename $filestat_t (struct - ;; Device ID of device containing the file. + ;;; Device ID of device containing the file. (field $st_dev $device_t) - ;; File serial number. + ;;; File serial number. (field $st_ino $inode_t) - ;; File type. + ;;; File type. (field $st_filetype $filetype_t) - ;; Number of hard links to the file. + ;;; Number of hard links to the file. (field $st_nlink $linkcount_t) - ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. (field $st_size $filesize_t) - ;; Last data access timestamp. + ;;; Last data access timestamp. (field $st_atim $timestamp_t) - ;; Last data modification timestamp. + ;;; Last data modification timestamp. (field $st_mtim $timestamp_t) - ;; Last file status change timestamp. + ;;; Last file status change timestamp. (field $st_ctim $timestamp_t) ) ) -;; User-provided value that may be attached to objects that is retained when -;; extracted from the implementation. +;;; User-provided value that may be attached to objects that is retained when +;;; extracted from the implementation. (typename $userdata_t u64) -;; Type of a subscription to an event or its occurrence. +;;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (enum u8 - ;; The time value of clock `subscription_t::u.clock.clock_id` has - ;; reached timestamp `subscription_t::u.clock.timeout`. + ;;; The time value of clock `subscription_t::u.clock.clock_id` has + ;;; reached timestamp `subscription_t::u.clock.timeout`. $EVENTTYPE_CLOCK - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data - ;; available for reading. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; available for reading. This event always triggers for regular files. $EVENTTYPE_FD_READ - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity - ;; available for writing. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;;; available for writing. This event always triggers for regular files. $EVENTTYPE_FD_WRITE ) ) -;; The state of the file descriptor subscribed to with -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The state of the file descriptor subscribed to with +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 - ;; The peer of this socket has closed or disconnected. + ;;; The peer of this socket has closed or disconnected. $EVENT_FD_READWRITE_HANGUP ) ) -;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;; `EVENTTYPE_FD_WRITE`. +;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;;; `EVENTTYPE_FD_WRITE`. (typename $event_fd_readwrite_t (struct - ;; The number of bytes available for reading or writing. + ;;; The number of bytes available for reading or writing. (field $nbytes $filesize_t) - ;; The state of the file descriptor. + ;;; The state of the file descriptor. (field $flags $eventrwflags_t) ) ) -;; The contents of an $event_t. +;;; The contents of an $event_t. (typename $event_u (union - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; An event that occurred. +;;; An event that occurred. (typename $event_t (struct - ;; User-provided value that got attached to `subscription_t::userdata`. + ;;; User-provided value that got attached to `subscription_t::userdata`. (field $userdata $userdata_t) - ;; If non-zero, an error that occurred while processing the subscription request. + ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno_t) - ;; The type of the event that occurred. + ;;; The type of the event that occurred. (field $type $eventtype_t) - ;; The contents of the event. + ;;; The contents of the event. (field $u $event_u) ) ) -;; Flags determining how to interpret the timestamp provided in -;; `subscription_t::u.clock.timeout.` +;;; Flags determining how to interpret the timestamp provided in +;;; `subscription_t::u.clock.timeout.` (typename $subclockflags_t (flags u16 - ;; If set, treat the timestamp provided in - ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;; provided in `subscription_t::u.clock.timeout` relative to the - ;; current time value of clock `subscription_t::u.clock.clock_id.` + ;;; If set, treat the timestamp provided in + ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription_t::u.clock.timeout` relative to the + ;;; current time value of clock `subscription_t::u.clock.clock_id.` $SUBSCRIPTION_CLOCK_ABSTIME ) ) -;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The user-defined unique identifier of the clock. + ;;; The user-defined unique identifier of the clock. (field $identifier $userdata_t) - ;; The clock against which to compare the timestamp. + ;;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. + ;;; The absolute or relative timestamp. (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. + ;;; The amount of time that the implementation may wait additionally + ;;; to coalesce with other events. (field $precision $timestamp_t) - ;; Flags specifying whether the timeout is absolute or relative + ;;; Flags specifying whether the timeout is absolute or relative (field $flags $subclockflags_t) ) ) -;; The contents of a $subscription_t when type is type is -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The contents of a $subscription_t when type is type is +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $subscription_fd_readwrite_t (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. + ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd_t) ) ) -;; The contents of a $subscription_t. +;;; The contents of a $subscription_t. (typename $subscription_u (union - ;; When type is `EVENTTYPE_CLOCK`: + ;;; When type is `EVENTTYPE_CLOCK`: (field $clock $subscription_clock_t) - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $subscription_fd_readwrite_t) ) ) -;; Subscription to an event. +;;; Subscription to an event. (typename $subscription_t (struct - ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through `event_t::userdata`. + ;;; User-provided value that is attached to the subscription in the + ;;; implementation and returned through `event_t::userdata`. (field $userdata $userdata_t) - ;; The type of the event to which to subscribe. + ;;; The type of the event to which to subscribe. (field $type $eventtype_t) - ;; The contents of the subscription. + ;;; The contents of the subscription. (field $u $subscription_u) ) ) -;; Exit code generated by a process when exiting. +;;; Exit code generated by a process when exiting. (typename $exitcode_t u32) -;; Signal condition. +;;; Signal condition. (typename $signal_t (enum u8 - ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;; so this value is reserved. + ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;;; so this value is reserved. $SIGNONE - ;; Hangup. - ;; Action: Terminates the process. + ;;; Hangup. + ;;; Action: Terminates the process. $SIGHUP - ;; Terminate interrupt signal. - ;; Action: Terminates the process. + ;;; Terminate interrupt signal. + ;;; Action: Terminates the process. $SIGINT - ;; Terminal quit signal. - ;; Action: Terminates the process. + ;;; Terminal quit signal. + ;;; Action: Terminates the process. $SIGQUIT - ;; Illegal instruction. - ;; Action: Terminates the process. + ;;; Illegal instruction. + ;;; Action: Terminates the process. $SIGILL - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. + ;;; Trace/breakpoint trap. + ;;; Action: Terminates the process. $SIGTRAP - ;; Process abort signal. - ;; Action: Terminates the process. + ;;; Process abort signal. + ;;; Action: Terminates the process. $SIGABRT - ;; Access to an undefined portion of a memory object. - ;; Action: Terminates the process. + ;;; Access to an undefined portion of a memory object. + ;;; Action: Terminates the process. $SIGBUS - ;; Erroneous arithmetic operation. - ;; Action: Terminates the process. + ;;; Erroneous arithmetic operation. + ;;; Action: Terminates the process. $SIGFPE - ;; Kill. - ;; Action: Terminates the process. + ;;; Kill. + ;;; Action: Terminates the process. $SIGKILL - ;; User-defined signal 1. - ;; Action: Terminates the process. + ;;; User-defined signal 1. + ;;; Action: Terminates the process. $SIGUSR1 - ;; Invalid memory reference. - ;; Action: Terminates the process. + ;;; Invalid memory reference. + ;;; Action: Terminates the process. $SIGSEGV - ;; User-defined signal 2. - ;; Action: Terminates the process. + ;;; User-defined signal 2. + ;;; Action: Terminates the process. $SIGUSR2 - ;; Write on a pipe with no one to read it. - ;; Action: Ignored. + ;;; Write on a pipe with no one to read it. + ;;; Action: Ignored. $SIGPIPE - ;; Alarm clock. - ;; Action: Terminates the process. + ;;; Alarm clock. + ;;; Action: Terminates the process. $SIGALRM - ;; Termination signal. - ;; Action: Terminates the process. + ;;; Termination signal. + ;;; Action: Terminates the process. $SIGTERM - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. + ;;; Child process terminated, stopped, or continued. + ;;; Action: Ignored. $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. + ;;; Continue executing, if stopped. + ;;; Action: Continues executing, if stopped. $SIGCONT - ;; Stop executing. - ;; Action: Stops executing. + ;;; Stop executing. + ;;; Action: Stops executing. $SIGSTOP - ;; Terminal stop signal. - ;; Action: Stops executing. + ;;; Terminal stop signal. + ;;; Action: Stops executing. $SIGTSTP - ;; Background process attempting read. - ;; Action: Stops executing. + ;;; Background process attempting read. + ;;; Action: Stops executing. $SIGTTIN - ;; Background process attempting write. - ;; Action: Stops executing. + ;;; Background process attempting write. + ;;; Action: Stops executing. $SIGTTOU - ;; High bandwidth data is available at a socket. - ;; Action: Ignored. + ;;; High bandwidth data is available at a socket. + ;;; Action: Ignored. $SIGURG - ;; CPU time limit exceeded. - ;; Action: Terminates the process. + ;;; CPU time limit exceeded. + ;;; Action: Terminates the process. $SIGXCPU - ;; File size limit exceeded. - ;; Action: Terminates the process. + ;;; File size limit exceeded. + ;;; Action: Terminates the process. $SIGXFSZ - ;; Virtual timer expired. - ;; Action: Terminates the process. + ;;; Virtual timer expired. + ;;; Action: Terminates the process. $SIGVTALRM - ;; Profiling timer expired. - ;; Action: Terminates the process. + ;;; Profiling timer expired. + ;;; Action: Terminates the process. $SIGPROF - ;; Window changed. - ;; Action: Ignored. + ;;; Window changed. + ;;; Action: Ignored. $SIGWINCH - ;; I/O possible. - ;; Action: Terminates the process. + ;;; I/O possible. + ;;; Action: Terminates the process. $SIGPOLL - ;; Power failure. - ;; Action: Terminates the process. + ;;; Power failure. + ;;; Action: Terminates the process. $SIGPWR - ;; Bad system call. - ;; Action: Terminates the process. + ;;; Bad system call. + ;;; Action: Terminates the process. $SIGSYS ) ) -;; Flags provided to `sock_recv`. +;;; Flags provided to `sock_recv`. (typename $riflags_t (flags u16 - ;; Returns the message without removing it from the socket's receive queue. + ;;; Returns the message without removing it from the socket's receive queue. $SOCK_RECV_PEEK - ;; On byte-stream sockets, block until the full amount of data can be returned. + ;;; On byte-stream sockets, block until the full amount of data can be returned. $SOCK_RECV_WAITALL ) ) -;; Flags returned by `sock_recv`. +;;; Flags returned by `sock_recv`. (typename $roflags_t (flags u16 - ;; Returned by `sock_recv`: Message data has been truncated. + ;;; Returned by `sock_recv`: Message data has been truncated. $SOCK_RECV_DATA_TRUNCATED ) ) -;; Flags provided to `sock_send`. As there are currently no flags -;; defined, it must be set to zero. +;;; Flags provided to `sock_send`. As there are currently no flags +;;; defined, it must be set to zero. (typename $siflags_t u16) -;; Which channels on a socket to shut down. +;;; Which channels on a socket to shut down. (typename $sdflags_t (flags u8 - ;; Disables further receive operations. + ;;; Disables further receive operations. $SHUT_RD - ;; Disables further send operations. + ;;; Disables further send operations. $SHUT_WR ) ) -;; Identifiers for preopened capabilities. +;;; Identifiers for preopened capabilities. (typename $preopentype_t (enum u8 - ;; A pre-opened directory. + ;;; A pre-opened directory. $PREOPENTYPE_DIR ) ) -;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. (typename $prestat_dir (struct - ;; The length of the directory name for use with `fd_prestat_dir_name`. + ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size_t) ) ) -;; The contents of an $prestat_t. +;;; The contents of an $prestat_t. (typename $prestat_u (union - ;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `PREOPENTYPE_DIR`: (field $dir $prestat_dir) ) ) -;; Information about a pre-opened capability. +;;; Information about a pre-opened capability. (typename $prestat_t (struct - ;; The type of the pre-opened capability. + ;;; The type of the pre-opened capability. (field $pr_type $preopentype_t) - ;; The contents of the information. + ;;; The contents of the information. (field $u $prestat_u) ) ) diff --git a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx index 74bce70c6..4cf5f4ffa 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -8,523 +8,526 @@ (use "typenames.witx") -;; This API predated the convention of naming modules with a `wasi_unstable_` -;; prefix and a version number. It is preserved here for compatibility, but -;; we shouldn't follow this pattern in new APIs. +;;; This API predated the convention of naming modules with a `wasi_unstable_` +;;; prefix and a version number. It is preserved here for compatibility, but +;;; we shouldn't follow this pattern in new APIs. (module $wasi_unstable - ;; Linear memory to be accessed by WASI functions that need it. + ;;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) - ;; Read command-line argument data. - ;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; Read command-line argument data. + ;;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Read environment variable data. - ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; Read environment variable data. + ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Return the resolution of a clock. - ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;; Note: This is similar to `clock_getres` in POSIX. + ;;; Return the resolution of a clock. + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno_t) - ;; The clock for which to return the resolution. + ;;; The clock for which to return the resolution. (param $clock_id $clockid_t) - ;; The resolution of the clock. + ;;; The resolution of the clock. (result $resolution $timestamp_t) ) - ;; Return the time value of a clock. - ;; Note: This is similar to `clock_gettime` in POSIX. + ;;; Return the time value of a clock. + ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") - ;; The clock for which to return the time. + ;;; The clock for which to return the time. (param $clock_id $clockid_t) - ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp_t) (result $error $errno_t) - ;; The time value of the clock. + ;;; The time value of the clock. (result $time $timestamp_t) ) - ;; Provide file advisory information on a file descriptor. - ;; Note: This is similar to `posix_fadvise` in POSIX. + ;;; Provide file advisory information on a file descriptor. + ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") (param $fd $fd_t) - (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. - (param $len $filesize_t) ;; The length of the region to which the advisory applies. - (param $advice $advice_t) ;; The advice. + ;;; The offset within the file to which the advisory applies. + (param $offset $filesize_t) + ;;; The length of the region to which the advisory applies. + (param $len $filesize_t) + ;;; The advice. + (param $advice $advice_t) (result $error $errno_t) ) - ;; Force the allocation of space in a file. - ;; Note: This is similar to `posix_fallocate` in POSIX. + ;;; Force the allocation of space in a file. + ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") (param $fd $fd_t) - ;; The offset at which to start the allocation. + ;;; The offset at which to start the allocation. (param $offset $filesize_t) - ;; The length of the area that is allocated. + ;;; The length of the area that is allocated. (param $len $filesize_t) (result $error $errno_t) ) - ;; Close a file descriptor. - ;; Note: This is similar to `close` in POSIX. + ;;; Close a file descriptor. + ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd_t) (result $error $errno_t) ) - ;; Synchronize the data of a file to disk. - ;; Note: This is similar to `fdatasync` in POSIX. + ;;; Synchronize the data of a file to disk. + ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Get the attributes of a file descriptor. - ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + ;;; Get the attributes of a file descriptor. + ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file descriptor's attributes are stored. + ;;; The buffer where the file descriptor's attributes are stored. (result $stat $fdstat_t) ) - ;; Adjust the flags associated with a file descriptor. - ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + ;;; Adjust the flags associated with a file descriptor. + ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") (param $fd $fd_t) - ;; The desired values of the file descriptor flags. + ;;; The desired values of the file descriptor flags. (param $flags $fdflags_t) (result $error $errno_t) ) - ;; Adjust the rights associated with a file descriptor. - ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; Adjust the rights associated with a file descriptor. + ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd_t) - ;; The desired rights of the file descriptor. + ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights_t) (param $fs_rights_inheriting $rights_t) (result $error $errno_t) ) - ;; Return the attributes of an open file. + ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;; Note: This is similar to `ftruncate` in POSIX. + ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") (param $fd $fd_t) - ;; The desired file size. + ;;; The desired file size. (param $st_size $filesize_t) (result $error $errno_t) ) - ;; Adjust the timestamps of an open file or directory. - ;; Note: This is similar to `futimens` in POSIX. + ;;; Adjust the timestamps of an open file or directory. + ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") (param $fd $fd_t) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `preadv` in POSIX. + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") (param $fd $fd_t) - ;; List of scatter/gather vectors in which to store data. + ;;; List of scatter/gather vectors in which to store data. (param $iovs $iovec_t_array) - ;; The offset within the file at which to read. + ;;; The offset within the file at which to read. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the description is stored. + ;;; The buffer where the description is stored. (result $buf $prestat_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") (param $fd $fd_t) - ;; A buffer into which to write the preopened directory name. + ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size_t) (result $error $errno_t) ) - ;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `pwritev` in POSIX. + ;;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) - ;; The offset within the file at which to write. + ;;; The offset within the file at which to write. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Read from a file descriptor. - ;; Note: This is similar to `readv` in POSIX. + ;;; Read from a file descriptor. + ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_t_array) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Read directory entries from a directory. - ;; When successful, the contents of the output buffer consist of a sequence of - ;; directory entries. Each directory entry consists of a dirent_t object, - ;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;; entry. + ;;; Read directory entries from a directory. + ;;; When successful, the contents of the output buffer consist of a sequence of + ;;; directory entries. Each directory entry consists of a dirent_t object, + ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; entry. ;; - ;; This function fills the output buffer as much as possible, potentially - ;; truncating the last directory entry. This allows the caller to grow its - ;; read buffer size in case it's too small to fit a single large directory - ;; entry, or skip the oversized directory entry. + ;;; This function fills the output buffer as much as possible, potentially + ;;; truncating the last directory entry. This allows the caller to grow its + ;;; read buffer size in case it's too small to fit a single large directory + ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") (param $fd $fd_t) - ;; The buffer where directory entries are stored + ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) (param $buf_len $size_t) - ;; The location within the directory to start reading + ;;; The location within the directory to start reading (param $cookie $dircookie_t) (result $error $errno_t) - ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. (result $bufused $size_t) ) - ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;;; Atomically replace a file descriptor by renumbering another file descriptor. ;; - ;; Due to the strong focus on thread safety, this environment does not provide - ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;; file descriptor with the same number could be allocated by a different - ;; thread at the same time. + ;;; Due to the strong focus on thread safety, this environment does not provide + ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;;; file descriptor with the same number could be allocated by a different + ;;; thread at the same time. ;; - ;; This function provides a way to atomically renumber file descriptors, which - ;; would disappear if `dup2()` were to be removed entirely. + ;;; This function provides a way to atomically renumber file descriptors, which + ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") (param $fd $fd_t) - ;; The file descriptor to overwrite. + ;;; The file descriptor to overwrite. (param $to $fd_t) (result $error $errno_t) ) - ;; Move the offset of a file descriptor. - ;; Note: This is similar to `lseek` in POSIX. + ;;; Move the offset of a file descriptor. + ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") (param $fd $fd_t) - ;; The number of bytes to move. + ;;; The number of bytes to move. (param $offset $filedelta_t) - ;; The base from which the offset is relative. + ;;; The base from which the offset is relative. (param $whence $whence_t) (result $error $errno_t) - ;; The new offset of the file descriptor, relative to the start of the file. + ;;; The new offset of the file descriptor, relative to the start of the file. (result $newoffset $filesize_t) ) - ;; Synchronize the data and metadata of a file to disk. - ;; Note: This is similar to `fsync` in POSIX. + ;;; Synchronize the data and metadata of a file to disk. + ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Return the current offset of a file descriptor. - ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + ;;; Return the current offset of a file descriptor. + ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd_t) (result $error $errno_t) - ;; The current offset of the file descriptor, relative to the start of the file. + ;;; The current offset of the file descriptor, relative to the start of the file. (result $offset $filesize_t) ) - ;; Write to a file descriptor. - ;; Note: This is similar to `writev` in POSIX. + ;;; Write to a file descriptor. + ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Create a directory. - ;; Note: This is similar to `mkdirat` in POSIX. + ;;; Create a directory. + ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") (param $fd $fd_t) - ;; The path at which to create the directory. + ;;; The path at which to create the directory. (param $path string) (result $error $errno_t) ) - ;; Return the attributes of a file or directory. - ;; Note: This is similar to `stat` in POSIX. + ;;; Return the attributes of a file or directory. + ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to inspect. + ;;; The path of the file or directory to inspect. (param $path string) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the timestamps of a file or directory. - ;; Note: This is similar to `utimensat` in POSIX. + ;;; Adjust the timestamps of a file or directory. + ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to operate on. + ;;; The path of the file or directory to operate on. (param $path string) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Create a hard link. - ;; Note: This is similar to `linkat` in POSIX. + ;;; Create a hard link. + ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") (param $old_fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) - ;; The source path from which to link. + ;;; The source path from which to link. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path at which to create the hard link. + ;;; The destination path at which to create the hard link. (param $new_path string) (result $error $errno_t) ) - ;; Open a file or directory. + ;;; Open a file or directory. ;; - ;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;; file descriptor not currently open; it is randomized to prevent - ;; applications from depending on making assumptions about indexes, since this - ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 2**31. + ;;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;;; file descriptor not currently open; it is randomized to prevent + ;;; applications from depending on making assumptions about indexes, since this + ;;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;;; guaranteed to be less than 2**31. ;; - ;; Note: This is similar to `openat` in POSIX. + ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags_t) - ;; The relative path of the file or directory to open, relative to the - ;; `dirfd` directory. + ;;; The relative path of the file or directory to open, relative to the + ;;; `dirfd` directory. (param $path string) - ;; The method by which to open the file. + ;;; The method by which to open the file. (param $o_flags $oflags_t) - ;; The initial rights of the newly created file descriptor. The - ;; implementation is allowed to return a file descriptor with fewer rights - ;; than specified, if and only if those rights do not apply to the type of - ;; file being opened. + ;;; The initial rights of the newly created file descriptor. The + ;;; implementation is allowed to return a file descriptor with fewer rights + ;;; than specified, if and only if those rights do not apply to the type of + ;;; file being opened. ;; - ;; The *base* rights are rights that will apply to operations using the file - ;; descriptor itself, while the *inheriting* rights are rights that apply to - ;; file descriptors derived from it. + ;;; The *base* rights are rights that will apply to operations using the file + ;;; descriptor itself, while the *inheriting* rights are rights that apply to + ;;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) (param $flags $fdflags_t) (result $error $errno_t) - ;; The file descriptor of the file that has been opened. + ;;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) ) - ;; Read the contents of a symbolic link. - ;; Note: This is similar to `readlinkat` in POSIX. + ;;; Read the contents of a symbolic link. + ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") (param $fd $fd_t) - ;; The path of the symbolic link from which to read. + ;;; The path of the symbolic link from which to read. (param $path string) - ;; The buffer to which to write the contents of the symbolic link. + ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) - ;; The number of bytes placed in the buffer. + ;;; The number of bytes placed in the buffer. (result $bufused $size_t) ) - ;; Remove a directory. - ;; Return `ENOTEMPTY` if the directory is not empty. - ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + ;;; Remove a directory. + ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd_t) - ;; The path to a directory to remove. + ;;; The path to a directory to remove. (param $path string) (result $error $errno_t) ) - ;; Rename a file or directory. - ;; Note: This is similar to `renameat` in POSIX. + ;;; Rename a file or directory. + ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") (param $fd $fd_t) - ;; The source path of the file or directory to rename. + ;;; The source path of the file or directory to rename. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path to which to rename the file or directory. + ;;; The destination path to which to rename the file or directory. (param $new_path string) (result $error $errno_t) ) - ;; Create a symbolic link. - ;; Note: This is similar to `symlinkat` in POSIX. + ;;; Create a symbolic link. + ;;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - ;; The contents of the symbolic link. + ;;; The contents of the symbolic link. (param $old_path string) (param $fd $fd_t) - ;; The destination path at which to create the symbolic link. + ;;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) ) - ;; Unlink a file. - ;; Return `EISDIR` if the path refers to a directory. - ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + ;;; Unlink a file. + ;;; Return `EISDIR` if the path refers to a directory. + ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd_t) - ;; The path to a file to unlink. + ;;; The path to a file to unlink. (param $path string) (result $error $errno_t) ) - ;; Concurrently poll for the occurrence of a set of events. + ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") - ;; The events to which to subscribe. + ;;; The events to which to subscribe. (param $in (@witx const_pointer $subscription_t)) - ;; The events that have occurred. + ;;; The events that have occurred. (param $out (@witx pointer $event_t)) - ;; Both the number of subscriptions and events. + ;;; Both the number of subscriptions and events. (param $nsubscriptions $size_t) (result $error $errno_t) - ;; The number of events stored. + ;;; The number of events stored. (result $nevents $size_t) ) - ;; Terminate the process normally. An exit code of 0 indicates successful - ;; termination of the program. The meanings of other values is dependent on - ;; the environment. + ;;; Terminate the process normally. An exit code of 0 indicates successful + ;;; termination of the program. The meanings of other values is dependent on + ;;; the environment. (@interface func (export "proc_exit") - ;; The exit code returned by the process. + ;;; The exit code returned by the process. (param $rval $exitcode_t) ) - ;; Send a signal to the process of the calling thread. - ;; Note: This is similar to `raise` in POSIX. + ;;; Send a signal to the process of the calling thread. + ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") - ;; The signal condition to trigger. + ;;; The signal condition to trigger. (param $sig $signal_t) (result $error $errno_t) ) - ;; Temporarily yield execution of the calling thread. - ;; Note: This is similar to `sched_yield` in POSIX. + ;;; Temporarily yield execution of the calling thread. + ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") (result $error $errno_t) ) - ;; Write high-quality random data into a buffer. - ;; This function blocks when the implementation is unable to immediately - ;; provide sufficient high-quality random data. - ;; This function may execute slowly, so when large mounts of random data are - ;; required, it's advisable to use this function to seed a pseudo-random - ;; number generator, rather than to provide the random data directly. + ;;; Write high-quality random data into a buffer. + ;;; This function blocks when the implementation is unable to immediately + ;;; provide sufficient high-quality random data. + ;;; This function may execute slowly, so when large mounts of random data are + ;;; required, it's advisable to use this function to seed a pseudo-random + ;;; number generator, rather than to provide the random data directly. (@interface func (export "random_get") - ;; The buffer to fill with random data. + ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) ) - ;; Receive a message from a socket. - ;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;; the data into multiple buffers in the manner of `readv`. + ;;; Receive a message from a socket. + ;;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $ri_data $iovec_t_array) - ;; Message flags. + ;;; Message flags. (param $ri_flags $riflags_t) (result $error $errno_t) - ;; Number of bytes stored in ri_data. + ;;; Number of bytes stored in ri_data. (result $ro_datalen $size_t) - ;; Message flags. + ;;; Message flags. (result $ro_flags $roflags_t) ) - ;; Send a message on a socket. - ;; Note: This is similar to `send` in POSIX, though it also supports writing - ;; the data from multiple buffers in the manner of `writev`. + ;;; Send a message on a socket. + ;;; Note: This is similar to `send` in POSIX, though it also supports writing + ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to retrieve data + ;;; List of scatter/gather vectors to which to retrieve data (param $si_data $ciovec_t_array) - ;; Message flags. + ;;; Message flags. (param $si_flags $siflags_t) (result $error $errno_t) - ;; Number of bytes transmitted. + ;;; Number of bytes transmitted. (result $so_datalen $size_t) ) - ;; Shut down socket send and receive channels. - ;; Note: This is similar to `shutdown` in POSIX. + ;;; Shut down socket send and receive channels. + ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") (param $fd $fd_t) - ;; Which channels on the socket to shut down. + ;;; Which channels on the socket to shut down. (param $how $sdflags_t) (result $error $errno_t) ) diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx index 1a45be1fd..68f6fac4a 100644 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -7,291 +7,291 @@ (typename $size_t u32) -;; Non-negative file size or length of a region within a file. +;;; Non-negative file size or length of a region within a file. (typename $filesize_t u64) -;; Timestamp in nanoseconds. +;;; Timestamp in nanoseconds. (typename $timestamp_t u64) -;; Identifiers for clocks. +;;; Identifiers for clocks. (typename $clockid_t (enum u32 - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. + ;;; The clock measuring real time. Time value zero corresponds with + ;;; 1970-01-01T00:00:00Z. $CLOCK_REALTIME - ;; The store-wide monotonic clock, which is defined as a clock measuring - ;; real time, whose value cannot be adjusted and which cannot have negative - ;; clock jumps. The epoch of this clock is undefined. The absolute time - ;; value of this clock therefore has no meaning. + ;;; The store-wide monotonic clock, which is defined as a clock measuring + ;;; real time, whose value cannot be adjusted and which cannot have negative + ;;; clock jumps. The epoch of this clock is undefined. The absolute time + ;;; value of this clock therefore has no meaning. $CLOCK_MONOTONIC - ;; The CPU-time clock associated with the current process. + ;;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The CPU-time clock associated with the current thread. + ;;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) ) -;; Error codes returned by functions. -;; Not all of these error codes are returned by the functions provided by this -;; API; some are used in higher-level library layers, and others are provided -;; merely for alignment with POSIX. +;;; Error codes returned by functions. +;;; Not all of these error codes are returned by the functions provided by this +;;; API; some are used in higher-level library layers, and others are provided +;;; merely for alignment with POSIX. (typename $errno_t (enum u16 - ;; No error occurred. System call completed successfully. + ;;; No error occurred. System call completed successfully. $ESUCCESS - ;; Argument list too long. + ;;; Argument list too long. $E2BIG - ;; Permission denied. + ;;; Permission denied. $EACCES - ;; Address in use. + ;;; Address in use. $EADDRINUSE - ;; Address not available. + ;;; Address not available. $EADDRNOTAVAIL - ;; Address family not supported. + ;;; Address family not supported. $EAFNOSUPPORT - ;; Resource unavailable, or operation would block. + ;;; Resource unavailable, or operation would block. $EAGAIN - ;; Connection already in progress. + ;;; Connection already in progress. $EALREADY - ;; Bad file descriptor. + ;;; Bad file descriptor. $EBADF - ;; Bad message. + ;;; Bad message. $EBADMSG - ;; Device or resource busy. + ;;; Device or resource busy. $EBUSY - ;; Operation canceled. + ;;; Operation canceled. $ECANCELED - ;; No child processes. + ;;; No child processes. $ECHILD - ;; Connection aborted. + ;;; Connection aborted. $ECONNABORTED - ;; Connection refused. + ;;; Connection refused. $ECONNREFUSED - ;; Connection reset. + ;;; Connection reset. $ECONNRESET - ;; Resource deadlock would occur. + ;;; Resource deadlock would occur. $EDEADLK - ;; Destination address required. + ;;; Destination address required. $EDESTADDRREQ - ;; Mathematics argument out of domain of function. + ;;; Mathematics argument out of domain of function. $EDOM - ;; Reserved. + ;;; Reserved. $EDQUOT - ;; File exists. + ;;; File exists. $EEXIST - ;; Bad address. + ;;; Bad address. $EFAULT - ;; File too large. + ;;; File too large. $EFBIG - ;; Host is unreachable. + ;;; Host is unreachable. $EHOSTUNREACH - ;; Identifier removed. + ;;; Identifier removed. $EIDRM - ;; Illegal byte sequence. + ;;; Illegal byte sequence. $EILSEQ - ;; Operation in progress. + ;;; Operation in progress. $EINPROGRESS - ;; Interrupted function. + ;;; Interrupted function. $EINTR - ;; Invalid argument. + ;;; Invalid argument. $EINVAL - ;; I/O error. + ;;; I/O error. $EIO - ;; Socket is connected. + ;;; Socket is connected. $EISCONN - ;; Is a directory. + ;;; Is a directory. $EISDIR - ;; Too many levels of symbolic links. + ;;; Too many levels of symbolic links. $ELOOP - ;; File descriptor value too large. + ;;; File descriptor value too large. $EMFILE - ;; Too many links. + ;;; Too many links. $EMLINK - ;; Message too large. + ;;; Message too large. $EMSGSIZE - ;; Reserved. + ;;; Reserved. $EMULTIHOP - ;; Filename too long. + ;;; Filename too long. $ENAMETOOLONG - ;; Network is down. + ;;; Network is down. $ENETDOWN - ;; Connection aborted by network. + ;;; Connection aborted by network. $ENETRESET - ;; Network unreachable. + ;;; Network unreachable. $ENETUNREACH - ;; Too many files open in system. + ;;; Too many files open in system. $ENFILE - ;; No buffer space available. + ;;; No buffer space available. $ENOBUFS - ;; No such device. + ;;; No such device. $ENODEV - ;; No such file or directory. + ;;; No such file or directory. $ENOENT - ;; Executable file format error. + ;;; Executable file format error. $ENOEXEC - ;; No locks available. + ;;; No locks available. $ENOLCK - ;; Reserved. + ;;; Reserved. $ENOLINK - ;; Not enough space. + ;;; Not enough space. $ENOMEM - ;; No message of the desired type. + ;;; No message of the desired type. $ENOMSG - ;; Protocol not available. + ;;; Protocol not available. $ENOPROTOOPT - ;; No space left on device. + ;;; No space left on device. $ENOSPC - ;; Function not supported. + ;;; Function not supported. $ENOSYS - ;; The socket is not connected. + ;;; The socket is not connected. $ENOTCONN - ;; Not a directory or a symbolic link to a directory. + ;;; Not a directory or a symbolic link to a directory. $ENOTDIR - ;; Directory not empty. + ;;; Directory not empty. $ENOTEMPTY - ;; State not recoverable. + ;;; State not recoverable. $ENOTRECOVERABLE - ;; Not a socket. + ;;; Not a socket. $ENOTSOCK - ;; Not supported, or operation not supported on socket. + ;;; Not supported, or operation not supported on socket. $ENOTSUP - ;; Inappropriate I/O control operation. + ;;; Inappropriate I/O control operation. $ENOTTY - ;; No such device or address. + ;;; No such device or address. $ENXIO - ;; Value too large to be stored in data type. + ;;; Value too large to be stored in data type. $EOVERFLOW - ;; Previous owner died. + ;;; Previous owner died. $EOWNERDEAD - ;; Operation not permitted. + ;;; Operation not permitted. $EPERM - ;; Broken pipe. + ;;; Broken pipe. $EPIPE - ;; Protocol error. + ;;; Protocol error. $EPROTO - ;; Protocol not supported. + ;;; Protocol not supported. $EPROTONOSUPPORT - ;; Protocol wrong type for socket. + ;;; Protocol wrong type for socket. $EPROTOTYPE - ;; Result too large. + ;;; Result too large. $ERANGE - ;; Read-only file system. + ;;; Read-only file system. $EROFS - ;; Invalid seek. + ;;; Invalid seek. $ESPIPE - ;; No such process. + ;;; No such process. $ESRCH - ;; Reserved. + ;;; Reserved. $ESTALE - ;; Connection timed out. + ;;; Connection timed out. $ETIMEDOUT - ;; Text file busy. + ;;; Text file busy. $ETXTBSY - ;; Cross-device link. + ;;; Cross-device link. $EXDEV - ;; Extension: Capabilities insufficient. + ;;; Extension: Capabilities insufficient. $ENOTCAPABLE ) ) -;; File descriptor rights, determining which actions may be performed. +;;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke `fd_datasync`. + ;;; The right to invoke `fd_datasync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_DSYNC`. $RIGHT_FD_DATASYNC - ;; The right to invoke `fd_read` and `sock_recv`. + ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. $RIGHT_FD_READ - ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. $RIGHT_FD_SEEK - ;; The right to invoke `fd_fdstat_set_flags`. + ;;; The right to invoke `fd_fdstat_set_flags`. $RIGHT_FD_FDSTAT_SET_FLAGS - ;; The right to invoke `fd_sync`. + ;;; The right to invoke `fd_sync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. $RIGHT_FD_SYNC - ;; The right to invoke `fd_seek` in such a way that the file offset - ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to - ;; invoke `fd_tell`. + ;;; The right to invoke `fd_seek` in such a way that the file offset + ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; invoke `fd_tell`. $RIGHT_FD_TELL - ;; The right to invoke `fd_write` and `sock_send`. - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + ;;; The right to invoke `fd_write` and `sock_send`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. $RIGHT_FD_WRITE - ;; The right to invoke `fd_advise`. + ;;; The right to invoke `fd_advise`. $RIGHT_FD_ADVISE - ;; The right to invoke `fd_allocate`. + ;;; The right to invoke `fd_allocate`. $RIGHT_FD_ALLOCATE - ;; The right to invoke `path_create_directory`. + ;;; The right to invoke `path_create_directory`. $RIGHT_PATH_CREATE_DIRECTORY - ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. $RIGHT_PATH_CREATE_FILE - ;; The right to invoke `path_link` with the file descriptor as the - ;; source directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; source directory. $RIGHT_PATH_LINK_SOURCE - ;; The right to invoke `path_link` with the file descriptor as the - ;; target directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; target directory. $RIGHT_PATH_LINK_TARGET - ;; The right to invoke `path_open`. + ;;; The right to invoke `path_open`. $RIGHT_PATH_OPEN - ;; The right to invoke `fd_readdir`. + ;;; The right to invoke `fd_readdir`. $RIGHT_FD_READDIR - ;; The right to invoke `path_readlink`. + ;;; The right to invoke `path_readlink`. $RIGHT_PATH_READLINK - ;; The right to invoke `path_rename` with the file descriptor as the source directory. + ;;; The right to invoke `path_rename` with the file descriptor as the source directory. $RIGHT_PATH_RENAME_SOURCE - ;; The right to invoke `path_rename` with the file descriptor as the target directory. + ;;; The right to invoke `path_rename` with the file descriptor as the target directory. $RIGHT_PATH_RENAME_TARGET - ;; The right to invoke `path_filestat_get`. + ;;; The right to invoke `path_filestat_get`. $RIGHT_PATH_FILESTAT_GET - ;; The right to change a file's size (there is no `path_filestat_set_size`). - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + ;;; The right to change a file's size (there is no `path_filestat_set_size`). + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. $RIGHT_PATH_FILESTAT_SET_SIZE - ;; The right to invoke `path_filestat_set_times`. + ;;; The right to invoke `path_filestat_set_times`. $RIGHT_PATH_FILESTAT_SET_TIMES - ;; The right to invoke `fd_filestat_get`. + ;;; The right to invoke `fd_filestat_get`. $RIGHT_FD_FILESTAT_GET - ;; The right to invoke `fd_filestat_set_size`. + ;;; The right to invoke `fd_filestat_set_size`. $RIGHT_FD_FILESTAT_SET_SIZE - ;; The right to invoke `fd_filestat_set_times`. + ;;; The right to invoke `fd_filestat_set_times`. $RIGHT_FD_FILESTAT_SET_TIMES - ;; The right to invoke `path_symlink`. + ;;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_remove_directory`. + ;;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY - ;; The right to invoke `path_unlink_file`. + ;;; The right to invoke `path_unlink_file`. $RIGHT_PATH_UNLINK_FILE - ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE - ;; The right to invoke `sock_shutdown`. + ;;; The right to invoke `sock_shutdown`. $RIGHT_SOCK_SHUTDOWN ) ) -;; A file descriptor index. +;;; A file descriptor index. (typename $fd_t u32) -;; A region of memory for scatter/gather reads. +;;; A region of memory for scatter/gather reads. (typename $iovec_t (struct - ;; The address of the buffer to be filled. + ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) - ;; The length of the buffer to be filled. + ;;; The length of the buffer to be filled. (field $buf_len $size_t) ) ) -;; A region of memory for scatter/gather writes. +;;; A region of memory for scatter/gather writes. (typename $ciovec_t (struct - ;; The address of the buffer to be written. + ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) - ;; The length of the buffer to be written. + ;;; The length of the buffer to be written. (field $buf_len $size_t) ) ) @@ -299,469 +299,469 @@ (typename $iovec_t_array (array $iovec_t)) (typename $ciovec_t_array (array $ciovec_t)) -;; Relative offset within a file. +;;; Relative offset within a file. (typename $filedelta_t s64) -;; The position relative to which to set the offset of the file descriptor. +;;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 - ;; Seek relative to start-of-file. + ;;; Seek relative to start-of-file. $WHENCE_SET - ;; Seek relative to current position. + ;;; Seek relative to current position. $WHENCE_CUR - ;; Seek relative to end-of-file. + ;;; Seek relative to end-of-file. $WHENCE_END ) ) -;; A reference to the offset of a directory entry. -;; -;; The value 0 signifies the start of the directory. +;;; A reference to the offset of a directory entry. +;;; +;;; The value 0 signifies the start of the directory. (typename $dircookie_t u64) -;; The type for the $d_namlen field of $dirent_t. +;;; The type for the $d_namlen field of $dirent_t. (typename $dirnamlen_t u32) -;; File serial number that is unique within its file system. +;;; File serial number that is unique within its file system. (typename $inode_t u64) -;; The type of a file descriptor or file. +;;; The type of a file descriptor or file. (typename $filetype_t (enum u8 - ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $FILETYPE_UNKNOWN - ;; The file descriptor or file refers to a block device inode. + ;;; The file descriptor or file refers to a block device inode. $FILETYPE_BLOCK_DEVICE - ;; The file descriptor or file refers to a character device inode. + ;;; The file descriptor or file refers to a character device inode. $FILETYPE_CHARACTER_DEVICE - ;; The file descriptor or file refers to a directory inode. + ;;; The file descriptor or file refers to a directory inode. $FILETYPE_DIRECTORY - ;; The file descriptor or file refers to a regular file inode. + ;;; The file descriptor or file refers to a regular file inode. $FILETYPE_REGULAR_FILE - ;; The file descriptor or file refers to a datagram socket. + ;;; The file descriptor or file refers to a datagram socket. $FILETYPE_SOCKET_DGRAM - ;; The file descriptor or file refers to a byte-stream socket. + ;;; The file descriptor or file refers to a byte-stream socket. $FILETYPE_SOCKET_STREAM - ;; The file refers to a symbolic link inode. + ;;; The file refers to a symbolic link inode. $FILETYPE_SYMBOLIC_LINK ) ) -;; A directory entry. +;;; A directory entry. (typename $dirent_t (struct - ;; The offset of the next directory entry stored in this directory. + ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie_t) - ;; The serial number of the file referred to by this directory entry. + ;;; The serial number of the file referred to by this directory entry. (field $d_ino $inode_t) - ;; The length of the name of the directory entry. + ;;; The length of the name of the directory entry. (field $d_namlen $dirnamlen_t) - ;; The type of the file referred to by this directory entry. + ;;; The type of the file referred to by this directory entry. (field $d_type $filetype_t) ) ) -;; File or memory access pattern advisory information. +;;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application has no advice to give on its behavior with respect to the specified data. + ;;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL - ;; The application expects to access the specified data in a random order. + ;;; The application expects to access the specified data in a random order. $ADVICE_RANDOM - ;; The application expects to access the specified data in the near future. + ;;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED - ;; The application expects that it will not access the specified data in the near future. + ;;; The application expects that it will not access the specified data in the near future. $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. + ;;; The application expects to access the specified data once and then not reuse it thereafter. $ADVICE_NOREUSE ) ) -;; File descriptor flags. +;;; File descriptor flags. (typename $fdflags_t (flags u16 - ;; Append mode: Data written to the file is always appended to the file's end. + ;;; Append mode: Data written to the file is always appended to the file's end. $FDFLAG_APPEND - ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. $FDFLAG_DSYNC - ;; Non-blocking mode. + ;;; Non-blocking mode. $FDFLAG_NONBLOCK - ;; Synchronized read I/O operations. + ;;; Synchronized read I/O operations. $FDFLAG_RSYNC - ;; Write according to synchronized I/O file integrity completion. In - ;; addition to synchronizing the data stored in the file, the implementation - ;; may also synchronously update the file's metadata. + ;;; Write according to synchronized I/O file integrity completion. In + ;;; addition to synchronizing the data stored in the file, the implementation + ;;; may also synchronously update the file's metadata. $FDFLAG_SYNC ) ) -;; File descriptor attributes. +;;; File descriptor attributes. (typename $fdstat_t (struct - ;; File type. + ;;; File type. (field $fs_filetype $filetype_t) - ;; File descriptor flags. + ;;; File descriptor flags. (field $fs_flags $fdflags_t) - ;; Rights that apply to this file descriptor. + ;;; Rights that apply to this file descriptor. (field $fs_rights_base $rights_t) - ;; Maximum set of rights that may be installed on new file descriptors that - ;; are created through this file descriptor, e.g., through `path_open`. + ;;; Maximum set of rights that may be installed on new file descriptors that + ;;; are created through this file descriptor, e.g., through `path_open`. (field $fs_rights_inheriting $rights_t) ) ) -;; Identifier for a device containing a file system. Can be used in combination -;; with `inode_t` to uniquely identify a file or directory in the filesystem. +;;; Identifier for a device containing a file system. Can be used in combination +;;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) -;; Which file time attributes to adjust. +;;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 - ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. $FILESTAT_SET_ATIM - ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_ATIM_NOW - ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. $FILESTAT_SET_MTIM - ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_MTIM_NOW ) ) -;; Flags determining the method of how paths are resolved. +;;; Flags determining the method of how paths are resolved. (typename $lookupflags_t (flags u32 - ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $LOOKUP_SYMLINK_FOLLOW ) ) -;; Open flags used by `path_open`. +;;; Open flags used by `path_open`. (typename $oflags_t (flags u16 - ;; Create file if it does not exist. + ;;; Create file if it does not exist. $O_CREAT - ;; Fail if not a directory. + ;;; Fail if not a directory. $O_DIRECTORY - ;; Fail if file already exists. + ;;; Fail if file already exists. $O_EXCL - ;; Truncate file to size 0. + ;;; Truncate file to size 0. $O_TRUNC ) ) -;; Number of hard links to an inode. +;;; Number of hard links to an inode. (typename $linkcount_t u64) -;; File attributes. +;;; File attributes. (typename $filestat_t (struct - ;; Device ID of device containing the file. + ;;; Device ID of device containing the file. (field $st_dev $device_t) - ;; File serial number. + ;;; File serial number. (field $st_ino $inode_t) - ;; File type. + ;;; File type. (field $st_filetype $filetype_t) - ;; Number of hard links to the file. + ;;; Number of hard links to the file. (field $st_nlink $linkcount_t) - ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. (field $st_size $filesize_t) - ;; Last data access timestamp. + ;;; Last data access timestamp. (field $st_atim $timestamp_t) - ;; Last data modification timestamp. + ;;; Last data modification timestamp. (field $st_mtim $timestamp_t) - ;; Last file status change timestamp. + ;;; Last file status change timestamp. (field $st_ctim $timestamp_t) ) ) -;; User-provided value that may be attached to objects that is retained when -;; extracted from the implementation. +;;; User-provided value that may be attached to objects that is retained when +;;; extracted from the implementation. (typename $userdata_t u64) -;; Type of a subscription to an event or its occurrence. +;;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (enum u8 - ;; The time value of clock `subscription_t::u.clock.clock_id` has - ;; reached timestamp `subscription_t::u.clock.timeout`. + ;;; The time value of clock `subscription_t::u.clock.clock_id` has + ;;; reached timestamp `subscription_t::u.clock.timeout`. $EVENTTYPE_CLOCK - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data - ;; available for reading. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; available for reading. This event always triggers for regular files. $EVENTTYPE_FD_READ - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity - ;; available for writing. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;;; available for writing. This event always triggers for regular files. $EVENTTYPE_FD_WRITE ) ) -;; The state of the file descriptor subscribed to with -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The state of the file descriptor subscribed to with +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 - ;; The peer of this socket has closed or disconnected. + ;;; The peer of this socket has closed or disconnected. $EVENT_FD_READWRITE_HANGUP ) ) -;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;; `EVENTTYPE_FD_WRITE`. +;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;;; `EVENTTYPE_FD_WRITE`. (typename $event_fd_readwrite_t (struct - ;; The number of bytes available for reading or writing. + ;;; The number of bytes available for reading or writing. (field $nbytes $filesize_t) - ;; The state of the file descriptor. + ;;; The state of the file descriptor. (field $flags $eventrwflags_t) ) ) -;; The contents of an $event_t. +;;; The contents of an $event_t. (typename $event_u (union - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; An event that occurred. +;;; An event that occurred. (typename $event_t (struct - ;; User-provided value that got attached to `subscription_t::userdata`. + ;;; User-provided value that got attached to `subscription_t::userdata`. (field $userdata $userdata_t) - ;; If non-zero, an error that occurred while processing the subscription request. + ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno_t) - ;; The type of the event that occurred. + ;;; The type of the event that occurred. (field $type $eventtype_t) - ;; The contents of the event. + ;;; The contents of the event. (field $u $event_u) ) ) -;; Flags determining how to interpret the timestamp provided in -;; `subscription_t::u.clock.timeout.` +;;; Flags determining how to interpret the timestamp provided in +;;; `subscription_t::u.clock.timeout.` (typename $subclockflags_t (flags u16 - ;; If set, treat the timestamp provided in - ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;; provided in `subscription_t::u.clock.timeout` relative to the - ;; current time value of clock `subscription_t::u.clock.clock_id.` + ;;; If set, treat the timestamp provided in + ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription_t::u.clock.timeout` relative to the + ;;; current time value of clock `subscription_t::u.clock.clock_id.` $SUBSCRIPTION_CLOCK_ABSTIME ) ) -;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The clock against which to compare the timestamp. + ;;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. + ;;; The absolute or relative timestamp. (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. + ;;; The amount of time that the implementation may wait additionally + ;;; to coalesce with other events. (field $precision $timestamp_t) - ;; Flags specifying whether the timeout is absolute or relative + ;;; Flags specifying whether the timeout is absolute or relative (field $flags $subclockflags_t) ) ) -;; The contents of a $subscription_t when type is type is -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The contents of a $subscription_t when type is type is +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $subscription_fd_readwrite_t (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. + ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd_t) ) ) -;; The contents of a $subscription_t. +;;; The contents of a $subscription_t. (typename $subscription_u (union - ;; When type is `EVENTTYPE_CLOCK`: + ;;; When type is `EVENTTYPE_CLOCK`: (field $clock $subscription_clock_t) - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $subscription_fd_readwrite_t) ) ) -;; Subscription to an event. +;;; Subscription to an event. (typename $subscription_t (struct - ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through `event_t::userdata`. + ;;; User-provided value that is attached to the subscription in the + ;;; implementation and returned through `event_t::userdata`. (field $userdata $userdata_t) - ;; The type of the event to which to subscribe. + ;;; The type of the event to which to subscribe. (field $type $eventtype_t) - ;; The contents of the subscription. + ;;; The contents of the subscription. (field $u $subscription_u) ) ) -;; Exit code generated by a process when exiting. +;;; Exit code generated by a process when exiting. (typename $exitcode_t u32) -;; Signal condition. +;;; Signal condition. (typename $signal_t (enum u8 - ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;; so this value is reserved. + ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;;; so this value is reserved. $SIGNONE - ;; Hangup. - ;; Action: Terminates the process. + ;;; Hangup. + ;;; Action: Terminates the process. $SIGHUP - ;; Terminate interrupt signal. - ;; Action: Terminates the process. + ;;; Terminate interrupt signal. + ;;; Action: Terminates the process. $SIGINT - ;; Terminal quit signal. - ;; Action: Terminates the process. + ;;; Terminal quit signal. + ;;; Action: Terminates the process. $SIGQUIT - ;; Illegal instruction. - ;; Action: Terminates the process. + ;;; Illegal instruction. + ;;; Action: Terminates the process. $SIGILL - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. + ;;; Trace/breakpoint trap. + ;;; Action: Terminates the process. $SIGTRAP - ;; Process abort signal. - ;; Action: Terminates the process. + ;;; Process abort signal. + ;;; Action: Terminates the process. $SIGABRT - ;; Access to an undefined portion of a memory object. - ;; Action: Terminates the process. + ;;; Access to an undefined portion of a memory object. + ;;; Action: Terminates the process. $SIGBUS - ;; Erroneous arithmetic operation. - ;; Action: Terminates the process. + ;;; Erroneous arithmetic operation. + ;;; Action: Terminates the process. $SIGFPE - ;; Kill. - ;; Action: Terminates the process. + ;;; Kill. + ;;; Action: Terminates the process. $SIGKILL - ;; User-defined signal 1. - ;; Action: Terminates the process. + ;;; User-defined signal 1. + ;;; Action: Terminates the process. $SIGUSR1 - ;; Invalid memory reference. - ;; Action: Terminates the process. + ;;; Invalid memory reference. + ;;; Action: Terminates the process. $SIGSEGV - ;; User-defined signal 2. - ;; Action: Terminates the process. + ;;; User-defined signal 2. + ;;; Action: Terminates the process. $SIGUSR2 - ;; Write on a pipe with no one to read it. - ;; Action: Ignored. + ;;; Write on a pipe with no one to read it. + ;;; Action: Ignored. $SIGPIPE - ;; Alarm clock. - ;; Action: Terminates the process. + ;;; Alarm clock. + ;;; Action: Terminates the process. $SIGALRM - ;; Termination signal. - ;; Action: Terminates the process. + ;;; Termination signal. + ;;; Action: Terminates the process. $SIGTERM - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. + ;;; Child process terminated, stopped, or continued. + ;;; Action: Ignored. $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. + ;;; Continue executing, if stopped. + ;;; Action: Continues executing, if stopped. $SIGCONT - ;; Stop executing. - ;; Action: Stops executing. + ;;; Stop executing. + ;;; Action: Stops executing. $SIGSTOP - ;; Terminal stop signal. - ;; Action: Stops executing. + ;;; Terminal stop signal. + ;;; Action: Stops executing. $SIGTSTP - ;; Background process attempting read. - ;; Action: Stops executing. + ;;; Background process attempting read. + ;;; Action: Stops executing. $SIGTTIN - ;; Background process attempting write. - ;; Action: Stops executing. + ;;; Background process attempting write. + ;;; Action: Stops executing. $SIGTTOU - ;; High bandwidth data is available at a socket. - ;; Action: Ignored. + ;;; High bandwidth data is available at a socket. + ;;; Action: Ignored. $SIGURG - ;; CPU time limit exceeded. - ;; Action: Terminates the process. + ;;; CPU time limit exceeded. + ;;; Action: Terminates the process. $SIGXCPU - ;; File size limit exceeded. - ;; Action: Terminates the process. + ;;; File size limit exceeded. + ;;; Action: Terminates the process. $SIGXFSZ - ;; Virtual timer expired. - ;; Action: Terminates the process. + ;;; Virtual timer expired. + ;;; Action: Terminates the process. $SIGVTALRM - ;; Profiling timer expired. - ;; Action: Terminates the process. + ;;; Profiling timer expired. + ;;; Action: Terminates the process. $SIGPROF - ;; Window changed. - ;; Action: Ignored. + ;;; Window changed. + ;;; Action: Ignored. $SIGWINCH - ;; I/O possible. - ;; Action: Terminates the process. + ;;; I/O possible. + ;;; Action: Terminates the process. $SIGPOLL - ;; Power failure. - ;; Action: Terminates the process. + ;;; Power failure. + ;;; Action: Terminates the process. $SIGPWR - ;; Bad system call. - ;; Action: Terminates the process. + ;;; Bad system call. + ;;; Action: Terminates the process. $SIGSYS ) ) -;; Flags provided to `sock_recv`. +;;; Flags provided to `sock_recv`. (typename $riflags_t (flags u16 - ;; Returns the message without removing it from the socket's receive queue. + ;;; Returns the message without removing it from the socket's receive queue. $SOCK_RECV_PEEK - ;; On byte-stream sockets, block until the full amount of data can be returned. + ;;; On byte-stream sockets, block until the full amount of data can be returned. $SOCK_RECV_WAITALL ) ) -;; Flags returned by `sock_recv`. +;;; Flags returned by `sock_recv`. (typename $roflags_t (flags u16 - ;; Returned by `sock_recv`: Message data has been truncated. + ;;; Returned by `sock_recv`: Message data has been truncated. $SOCK_RECV_DATA_TRUNCATED ) ) -;; Flags provided to `sock_send`. As there are currently no flags -;; defined, it must be set to zero. +;;; Flags provided to `sock_send`. As there are currently no flags +;;; defined, it must be set to zero. (typename $siflags_t u16) -;; Which channels on a socket to shut down. +;;; Which channels on a socket to shut down. (typename $sdflags_t (flags u8 - ;; Disables further receive operations. + ;;; Disables further receive operations. $SHUT_RD - ;; Disables further send operations. + ;;; Disables further send operations. $SHUT_WR ) ) -;; Identifiers for preopened capabilities. +;;; Identifiers for preopened capabilities. (typename $preopentype_t (enum u8 - ;; A pre-opened directory. + ;;; A pre-opened directory. $PREOPENTYPE_DIR ) ) -;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. (typename $prestat_dir (struct - ;; The length of the directory name for use with `fd_prestat_dir_name`. + ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size_t) ) ) -;; The contents of an $prestat_t. +;;; The contents of an $prestat_t. (typename $prestat_u (union - ;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `PREOPENTYPE_DIR`: (field $dir $prestat_dir) ) ) -;; Information about a pre-opened capability. +;;; Information about a pre-opened capability. (typename $prestat_t (struct - ;; The type of the pre-opened capability. + ;;; The type of the pre-opened capability. (field $pr_type $preopentype_t) - ;; The contents of the information. + ;;; The contents of the information. (field $u $prestat_u) ) ) diff --git a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx index 630537416..e69b788dc 100644 --- a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -9,519 +9,522 @@ (use "typenames.witx") (module $wasi_snapshot_preview1 - ;; Linear memory to be accessed by WASI functions that need it. + ;;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) - ;; Read command-line argument data. - ;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; Read command-line argument data. + ;;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Read environment variable data. - ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; Read environment variable data. + ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Return the resolution of a clock. - ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;; Note: This is similar to `clock_getres` in POSIX. + ;;; Return the resolution of a clock. + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno_t) - ;; The clock for which to return the resolution. + ;;; The clock for which to return the resolution. (param $clock_id $clockid_t) - ;; The resolution of the clock. + ;;; The resolution of the clock. (result $resolution $timestamp_t) ) - ;; Return the time value of a clock. - ;; Note: This is similar to `clock_gettime` in POSIX. + ;;; Return the time value of a clock. + ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") - ;; The clock for which to return the time. + ;;; The clock for which to return the time. (param $clock_id $clockid_t) - ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp_t) (result $error $errno_t) - ;; The time value of the clock. + ;;; The time value of the clock. (result $time $timestamp_t) ) - ;; Provide file advisory information on a file descriptor. - ;; Note: This is similar to `posix_fadvise` in POSIX. + ;;; Provide file advisory information on a file descriptor. + ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") (param $fd $fd_t) - (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. - (param $len $filesize_t) ;; The length of the region to which the advisory applies. - (param $advice $advice_t) ;; The advice. + ;;; The offset within the file to which the advisory applies. + (param $offset $filesize_t) + ;;; The length of the region to which the advisory applies. + (param $len $filesize_t) + ;;; The advice. + (param $advice $advice_t) (result $error $errno_t) ) - ;; Force the allocation of space in a file. - ;; Note: This is similar to `posix_fallocate` in POSIX. + ;;; Force the allocation of space in a file. + ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") (param $fd $fd_t) - ;; The offset at which to start the allocation. + ;;; The offset at which to start the allocation. (param $offset $filesize_t) - ;; The length of the area that is allocated. + ;;; The length of the area that is allocated. (param $len $filesize_t) (result $error $errno_t) ) - ;; Close a file descriptor. - ;; Note: This is similar to `close` in POSIX. + ;;; Close a file descriptor. + ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd_t) (result $error $errno_t) ) - ;; Synchronize the data of a file to disk. - ;; Note: This is similar to `fdatasync` in POSIX. + ;;; Synchronize the data of a file to disk. + ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Get the attributes of a file descriptor. - ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + ;;; Get the attributes of a file descriptor. + ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file descriptor's attributes are stored. + ;;; The buffer where the file descriptor's attributes are stored. (result $stat $fdstat_t) ) - ;; Adjust the flags associated with a file descriptor. - ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + ;;; Adjust the flags associated with a file descriptor. + ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") (param $fd $fd_t) - ;; The desired values of the file descriptor flags. + ;;; The desired values of the file descriptor flags. (param $flags $fdflags_t) (result $error $errno_t) ) - ;; Adjust the rights associated with a file descriptor. - ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; Adjust the rights associated with a file descriptor. + ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd_t) - ;; The desired rights of the file descriptor. + ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights_t) (param $fs_rights_inheriting $rights_t) (result $error $errno_t) ) - ;; Return the attributes of an open file. + ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;; Note: This is similar to `ftruncate` in POSIX. + ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") (param $fd $fd_t) - ;; The desired file size. + ;;; The desired file size. (param $st_size $filesize_t) (result $error $errno_t) ) - ;; Adjust the timestamps of an open file or directory. - ;; Note: This is similar to `futimens` in POSIX. + ;;; Adjust the timestamps of an open file or directory. + ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") (param $fd $fd_t) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `preadv` in POSIX. + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") (param $fd $fd_t) - ;; List of scatter/gather vectors in which to store data. + ;;; List of scatter/gather vectors in which to store data. (param $iovs $iovec_t_array) - ;; The offset within the file at which to read. + ;;; The offset within the file at which to read. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the description is stored. + ;;; The buffer where the description is stored. (result $buf $prestat_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") (param $fd $fd_t) - ;; A buffer into which to write the preopened directory name. + ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size_t) (result $error $errno_t) ) - ;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `pwritev` in POSIX. + ;;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) - ;; The offset within the file at which to write. + ;;; The offset within the file at which to write. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Read from a file descriptor. - ;; Note: This is similar to `readv` in POSIX. + ;;; Read from a file descriptor. + ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_t_array) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Read directory entries from a directory. - ;; When successful, the contents of the output buffer consist of a sequence of - ;; directory entries. Each directory entry consists of a dirent_t object, - ;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;; entry. + ;;; Read directory entries from a directory. + ;;; When successful, the contents of the output buffer consist of a sequence of + ;;; directory entries. Each directory entry consists of a dirent_t object, + ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; entry. ;; - ;; This function fills the output buffer as much as possible, potentially - ;; truncating the last directory entry. This allows the caller to grow its - ;; read buffer size in case it's too small to fit a single large directory - ;; entry, or skip the oversized directory entry. + ;;; This function fills the output buffer as much as possible, potentially + ;;; truncating the last directory entry. This allows the caller to grow its + ;;; read buffer size in case it's too small to fit a single large directory + ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") (param $fd $fd_t) - ;; The buffer where directory entries are stored + ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) (param $buf_len $size_t) - ;; The location within the directory to start reading + ;;; The location within the directory to start reading (param $cookie $dircookie_t) (result $error $errno_t) - ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. (result $bufused $size_t) ) - ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;;; Atomically replace a file descriptor by renumbering another file descriptor. ;; - ;; Due to the strong focus on thread safety, this environment does not provide - ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;; file descriptor with the same number could be allocated by a different - ;; thread at the same time. + ;;; Due to the strong focus on thread safety, this environment does not provide + ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;;; file descriptor with the same number could be allocated by a different + ;;; thread at the same time. ;; - ;; This function provides a way to atomically renumber file descriptors, which - ;; would disappear if `dup2()` were to be removed entirely. + ;;; This function provides a way to atomically renumber file descriptors, which + ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") (param $fd $fd_t) - ;; The file descriptor to overwrite. + ;;; The file descriptor to overwrite. (param $to $fd_t) (result $error $errno_t) ) - ;; Move the offset of a file descriptor. - ;; Note: This is similar to `lseek` in POSIX. + ;;; Move the offset of a file descriptor. + ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") (param $fd $fd_t) - ;; The number of bytes to move. + ;;; The number of bytes to move. (param $offset $filedelta_t) - ;; The base from which the offset is relative. + ;;; The base from which the offset is relative. (param $whence $whence_t) (result $error $errno_t) - ;; The new offset of the file descriptor, relative to the start of the file. + ;;; The new offset of the file descriptor, relative to the start of the file. (result $newoffset $filesize_t) ) - ;; Synchronize the data and metadata of a file to disk. - ;; Note: This is similar to `fsync` in POSIX. + ;;; Synchronize the data and metadata of a file to disk. + ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Return the current offset of a file descriptor. - ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + ;;; Return the current offset of a file descriptor. + ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd_t) (result $error $errno_t) - ;; The current offset of the file descriptor, relative to the start of the file. + ;;; The current offset of the file descriptor, relative to the start of the file. (result $offset $filesize_t) ) - ;; Write to a file descriptor. - ;; Note: This is similar to `writev` in POSIX. + ;;; Write to a file descriptor. + ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Create a directory. - ;; Note: This is similar to `mkdirat` in POSIX. + ;;; Create a directory. + ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") (param $fd $fd_t) - ;; The path at which to create the directory. + ;;; The path at which to create the directory. (param $path string) (result $error $errno_t) ) - ;; Return the attributes of a file or directory. - ;; Note: This is similar to `stat` in POSIX. + ;;; Return the attributes of a file or directory. + ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to inspect. + ;;; The path of the file or directory to inspect. (param $path string) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the timestamps of a file or directory. - ;; Note: This is similar to `utimensat` in POSIX. + ;;; Adjust the timestamps of a file or directory. + ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to operate on. + ;;; The path of the file or directory to operate on. (param $path string) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Create a hard link. - ;; Note: This is similar to `linkat` in POSIX. + ;;; Create a hard link. + ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") (param $old_fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) - ;; The source path from which to link. + ;;; The source path from which to link. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path at which to create the hard link. + ;;; The destination path at which to create the hard link. (param $new_path string) (result $error $errno_t) ) - ;; Open a file or directory. + ;;; Open a file or directory. ;; - ;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;; file descriptor not currently open; it is randomized to prevent - ;; applications from depending on making assumptions about indexes, since this - ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 2**31. + ;;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;;; file descriptor not currently open; it is randomized to prevent + ;;; applications from depending on making assumptions about indexes, since this + ;;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;;; guaranteed to be less than 2**31. ;; - ;; Note: This is similar to `openat` in POSIX. + ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags_t) - ;; The relative path of the file or directory to open, relative to the - ;; `dirfd` directory. + ;;; The relative path of the file or directory to open, relative to the + ;;; `dirfd` directory. (param $path string) - ;; The method by which to open the file. + ;;; The method by which to open the file. (param $o_flags $oflags_t) - ;; The initial rights of the newly created file descriptor. The - ;; implementation is allowed to return a file descriptor with fewer rights - ;; than specified, if and only if those rights do not apply to the type of - ;; file being opened. + ;;; The initial rights of the newly created file descriptor. The + ;;; implementation is allowed to return a file descriptor with fewer rights + ;;; than specified, if and only if those rights do not apply to the type of + ;;; file being opened. ;; - ;; The *base* rights are rights that will apply to operations using the file - ;; descriptor itself, while the *inheriting* rights are rights that apply to - ;; file descriptors derived from it. + ;;; The *base* rights are rights that will apply to operations using the file + ;;; descriptor itself, while the *inheriting* rights are rights that apply to + ;;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) (param $flags $fdflags_t) (result $error $errno_t) - ;; The file descriptor of the file that has been opened. + ;;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) ) - ;; Read the contents of a symbolic link. - ;; Note: This is similar to `readlinkat` in POSIX. + ;;; Read the contents of a symbolic link. + ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") (param $fd $fd_t) - ;; The path of the symbolic link from which to read. + ;;; The path of the symbolic link from which to read. (param $path string) - ;; The buffer to which to write the contents of the symbolic link. + ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) - ;; The number of bytes placed in the buffer. + ;;; The number of bytes placed in the buffer. (result $bufused $size_t) ) - ;; Remove a directory. - ;; Return `ENOTEMPTY` if the directory is not empty. - ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + ;;; Remove a directory. + ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd_t) - ;; The path to a directory to remove. + ;;; The path to a directory to remove. (param $path string) (result $error $errno_t) ) - ;; Rename a file or directory. - ;; Note: This is similar to `renameat` in POSIX. + ;;; Rename a file or directory. + ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") (param $fd $fd_t) - ;; The source path of the file or directory to rename. + ;;; The source path of the file or directory to rename. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path to which to rename the file or directory. + ;;; The destination path to which to rename the file or directory. (param $new_path string) (result $error $errno_t) ) - ;; Create a symbolic link. - ;; Note: This is similar to `symlinkat` in POSIX. + ;;; Create a symbolic link. + ;;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - ;; The contents of the symbolic link. + ;;; The contents of the symbolic link. (param $old_path string) (param $fd $fd_t) - ;; The destination path at which to create the symbolic link. + ;;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) ) - ;; Unlink a file. - ;; Return `EISDIR` if the path refers to a directory. - ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + ;;; Unlink a file. + ;;; Return `EISDIR` if the path refers to a directory. + ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd_t) - ;; The path to a file to unlink. + ;;; The path to a file to unlink. (param $path string) (result $error $errno_t) ) - ;; Concurrently poll for the occurrence of a set of events. + ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") - ;; The events to which to subscribe. + ;;; The events to which to subscribe. (param $in (@witx const_pointer $subscription_t)) - ;; The events that have occurred. + ;;; The events that have occurred. (param $out (@witx pointer $event_t)) - ;; Both the number of subscriptions and events. + ;;; Both the number of subscriptions and events. (param $nsubscriptions $size_t) (result $error $errno_t) - ;; The number of events stored. + ;;; The number of events stored. (result $nevents $size_t) ) - ;; Terminate the process normally. An exit code of 0 indicates successful - ;; termination of the program. The meanings of other values is dependent on - ;; the environment. + ;;; Terminate the process normally. An exit code of 0 indicates successful + ;;; termination of the program. The meanings of other values is dependent on + ;;; the environment. (@interface func (export "proc_exit") - ;; The exit code returned by the process. + ;;; The exit code returned by the process. (param $rval $exitcode_t) ) - ;; Send a signal to the process of the calling thread. - ;; Note: This is similar to `raise` in POSIX. + ;;; Send a signal to the process of the calling thread. + ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") - ;; The signal condition to trigger. + ;;; The signal condition to trigger. (param $sig $signal_t) (result $error $errno_t) ) - ;; Temporarily yield execution of the calling thread. - ;; Note: This is similar to `sched_yield` in POSIX. + ;;; Temporarily yield execution of the calling thread. + ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") (result $error $errno_t) ) - ;; Write high-quality random data into a buffer. - ;; This function blocks when the implementation is unable to immediately - ;; provide sufficient high-quality random data. - ;; This function may execute slowly, so when large mounts of random data are - ;; required, it's advisable to use this function to seed a pseudo-random - ;; number generator, rather than to provide the random data directly. + ;;; Write high-quality random data into a buffer. + ;;; This function blocks when the implementation is unable to immediately + ;;; provide sufficient high-quality random data. + ;;; This function may execute slowly, so when large mounts of random data are + ;;; required, it's advisable to use this function to seed a pseudo-random + ;;; number generator, rather than to provide the random data directly. (@interface func (export "random_get") - ;; The buffer to fill with random data. + ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) ) - ;; Receive a message from a socket. - ;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;; the data into multiple buffers in the manner of `readv`. + ;;; Receive a message from a socket. + ;;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $ri_data $iovec_t_array) - ;; Message flags. + ;;; Message flags. (param $ri_flags $riflags_t) (result $error $errno_t) - ;; Number of bytes stored in ri_data. + ;;; Number of bytes stored in ri_data. (result $ro_datalen $size_t) - ;; Message flags. + ;;; Message flags. (result $ro_flags $roflags_t) ) - ;; Send a message on a socket. - ;; Note: This is similar to `send` in POSIX, though it also supports writing - ;; the data from multiple buffers in the manner of `writev`. + ;;; Send a message on a socket. + ;;; Note: This is similar to `send` in POSIX, though it also supports writing + ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to retrieve data + ;;; List of scatter/gather vectors to which to retrieve data (param $si_data $ciovec_t_array) - ;; Message flags. + ;;; Message flags. (param $si_flags $siflags_t) (result $error $errno_t) - ;; Number of bytes transmitted. + ;;; Number of bytes transmitted. (result $so_datalen $size_t) ) - ;; Shut down socket send and receive channels. - ;; Note: This is similar to `shutdown` in POSIX. + ;;; Shut down socket send and receive channels. + ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") (param $fd $fd_t) - ;; Which channels on the socket to shut down. + ;;; Which channels on the socket to shut down. (param $how $sdflags_t) (result $error $errno_t) ) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 62d5bf502..48c776ba9 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -120,6 +120,7 @@ pub enum DatatypeIdent { pub struct Datatype { pub name: Id, pub variant: DatatypeVariant, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -149,14 +150,26 @@ pub enum IntRepr { pub struct EnumDatatype { pub name: Id, pub repr: IntRepr, - pub variants: Vec, + pub variants: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct EnumVariant { + pub name: Id, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsDatatype { pub name: Id, pub repr: IntRepr, - pub flags: Vec, + pub flags: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FlagsMember { + pub name: Id, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -169,6 +182,7 @@ pub struct StructDatatype { pub struct StructMember { pub name: Id, pub type_: DatatypeIdent, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -181,6 +195,7 @@ pub struct UnionDatatype { pub struct UnionVariant { pub name: Id, pub type_: DatatypeIdent, + pub docs: String, } #[derive(Debug, Clone)] @@ -188,6 +203,7 @@ pub struct Module { pub name: Id, definitions: Vec, entries: HashMap, + pub docs: String, } impl Module { @@ -195,11 +211,13 @@ impl Module { name: Id, definitions: Vec, entries: HashMap, + docs: String, ) -> Self { Module { name, definitions, entries, + docs, } } pub fn import(&self, name: &Id) -> Option> { @@ -275,6 +293,7 @@ impl PartialEq for ModuleEntry { pub struct ModuleImport { pub name: Id, pub variant: ModuleImportVariant, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -287,6 +306,7 @@ pub struct InterfaceFunc { pub name: Id, pub params: Vec, pub results: Vec, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -294,6 +314,7 @@ pub struct InterfaceFuncParam { pub name: Id, pub type_: DatatypeIdent, pub position: InterfaceFuncParamPosition, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs new file mode 100644 index 000000000..532b3d902 --- /dev/null +++ b/proposals/clocks/tools/witx/src/docs.rs @@ -0,0 +1,227 @@ +use crate::ast::*; + +pub trait Documentation { + fn to_md(&self) -> String; +} + +impl Documentation for Document { + fn to_md(&self) -> String { + let mut ret = "# Types\n".to_string(); + for d in self.datatypes() { + ret += &d.to_md(); + } + + ret += "\n# Modules\n"; + for m in self.modules() { + ret += &m.to_md(); + } + ret + } +} + +impl BuiltinType { + fn name(&self) -> &'static str { + match self { + BuiltinType::String => "string", + BuiltinType::U8 => "u8", + BuiltinType::U16 => "u16", + BuiltinType::U32 => "u32", + BuiltinType::U64 => "u64", + BuiltinType::S8 => "s8", + BuiltinType::S16 => "s16", + BuiltinType::S32 => "s32", + BuiltinType::S64 => "s64", + BuiltinType::F32 => "f32", + BuiltinType::F64 => "f64", + } + } +} + +impl DatatypeIdent { + fn name(&self) -> String { + match self { + DatatypeIdent::Builtin(b) => b.name().to_string(), + DatatypeIdent::Array(a) => format!("Array<{}>", a.name()), + DatatypeIdent::Pointer(p) => format!("Pointer<{}>", p.name()), + DatatypeIdent::ConstPointer(p) => format!("ConstPointer<{}>", p.name()), + DatatypeIdent::Ident(i) => i.name.as_str().to_string(), + } + } +} + +impl Documentation for Datatype { + fn to_md(&self) -> String { + format!( + "## `{}`\n{}\n{}\n", + self.name.as_str(), + self.docs, + self.variant.to_md() + ) + } +} + +impl Documentation for DatatypeVariant { + fn to_md(&self) -> String { + match self { + DatatypeVariant::Alias(a) => a.to_md(), + DatatypeVariant::Enum(a) => a.to_md(), + DatatypeVariant::Flags(a) => a.to_md(), + DatatypeVariant::Struct(a) => a.to_md(), + DatatypeVariant::Union(a) => a.to_md(), + } + } +} + +impl Documentation for AliasDatatype { + fn to_md(&self) -> String { + format!("Alias to `{}`", self.to.name()) + } +} + +impl Documentation for EnumDatatype { + fn to_md(&self) -> String { + let variants = self + .variants + .iter() + .map(|v| format!("#### `{}`\n{}", v.name.as_str(), v.docs)) + .collect::>() + .join("\n"); + format!( + "Enum represented by `{}`\n\n### Variants:\n{}\n", + self.repr.name(), + variants + ) + } +} + +impl Documentation for FlagsDatatype { + fn to_md(&self) -> String { + let flags = self + .flags + .iter() + .map(|f| format!("#### `{}`\n{}\n", f.name.as_str(), f.docs)) + .collect::>() + .join("\n"); + format!( + "Flags represented by `{}`\n\n### Flags:\n{}", + self.repr.name(), + flags + ) + } +} + +impl Documentation for StructDatatype { + fn to_md(&self) -> String { + let members = self + .members + .iter() + .map(|m| { + format!( + "#### `{}`\nMember type: `{}`\n{}", + m.name.as_str(), + m.type_.name(), + m.docs, + ) + }) + .collect::>() + .join("\n"); + format!("### Struct members:\n{}", members) + } +} + +impl Documentation for UnionDatatype { + fn to_md(&self) -> String { + let variants = self + .variants + .iter() + .map(|v| { + format!( + "#### `{}`\nVariant type: `{}`\n{}", + v.name.as_str(), + v.type_.name(), + v.docs, + ) + }) + .collect::>() + .join("\n"); + format!("### Union variants:\n{}\n", variants) + } +} + +impl IntRepr { + fn name(&self) -> &'static str { + match self { + IntRepr::U8 => "u8", + IntRepr::U16 => "u16", + IntRepr::U32 => "u32", + IntRepr::U64 => "u64", + } + } +} + +impl Documentation for Module { + fn to_md(&self) -> String { + let imports = self + .imports() + .map(|i| i.to_md()) + .collect::>() + .join("\n"); + let funcs = self + .funcs() + .map(|i| i.to_md()) + .collect::>() + .join("\n"); + format!( + "## `{}`\n### Imports\n{}\n### Functions\n{}", + self.name.as_str(), + imports, + funcs, + ) + } +} + +impl Documentation for ModuleImport { + fn to_md(&self) -> String { + match self.variant { + ModuleImportVariant::Memory => format!("* {}: Memory", self.name.as_str()), + } + } +} + +impl Documentation for InterfaceFunc { + fn to_md(&self) -> String { + let params = self + .params + .iter() + .map(|f| { + format!( + "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", + name = f.name.as_str(), + type_ = f.type_.name(), + docs = f.docs + ) + }) + .collect::>() + .join("\n"); + let results = self + .results + .iter() + .map(|f| { + format!( + "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", + name = f.name.as_str(), + type_ = f.type_.name(), + docs = f.docs + ) + }) + .collect::>() + .join("\n"); + format!( + "### {}\n{}\n#### Parameters:\n{}#### Results:\n{}", + self.name.as_str(), + self.docs, + params, + results, + ) + } +} diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 3c2d945ec..60b0e0663 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -2,6 +2,8 @@ mod ast; /// Map witx types to core (wasm standard) types mod coretypes; +/// Render documentation +mod docs; /// Interface for filesystem or mock IO mod io; /// Witx syntax parsing from SExprs @@ -15,11 +17,12 @@ mod validate; pub use ast::{ AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, - InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, + Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, Id, IntRepr, InterfaceFunc, + InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, + ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; +pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; pub use render::{Render, SExpr as RenderSExpr}; diff --git a/proposals/clocks/tools/witx/src/main.rs b/proposals/clocks/tools/witx/src/main.rs index 8b1cab6ea..6251c3efa 100644 --- a/proposals/clocks/tools/witx/src/main.rs +++ b/proposals/clocks/tools/witx/src/main.rs @@ -1,12 +1,14 @@ -use clap::{App, Arg}; +use clap::{App, Arg, SubCommand}; +use std::fs::File; +use std::io::Write; use std::path::PathBuf; use std::process; -use witx::load; +use witx::{load, Documentation}; pub fn main() { let app = App::new("witx") .version(env!("CARGO_PKG_VERSION")) - .about("Validate witx file format") + .about("Validate and process witx files") .arg( Arg::with_name("input") .required(true) @@ -20,6 +22,17 @@ pub fn main() { .takes_value(false) .required(false), ) + .subcommand( + SubCommand::with_name("docs") + .about("Output documentation") + .arg( + Arg::with_name("output") + .short("o") + .long("output") + .takes_value(true) + .required(false), + ), + ) .get_matches(); let inputs = app @@ -34,6 +47,16 @@ pub fn main() { if app.is_present("verbose") { println!("{:?}", doc) } + + if let Some(subcommand) = app.subcommand_matches("docs") { + let md = doc.to_md(); + if let Some(output) = subcommand.value_of("output") { + let mut file = File::create(output).expect("create output file"); + file.write_all(md.as_bytes()).expect("write output file"); + } else { + println!("{}", md) + } + } } Err(e) => { println!("{}", e.report()); diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 9e699267e..77a1c0b03 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -1,3 +1,4 @@ +use wast::lexer::Comment; use wast::parser::{Cursor, Parse, Parser, Peek, Result}; ///! Parser turns s-expressions into unvalidated syntax constructs. @@ -96,6 +97,86 @@ impl Parse<'_> for BuiltinType { } } +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct CommentSyntax<'a> { + pub comments: Vec<&'a str>, +} + +impl<'a> Parse<'a> for CommentSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result> { + let comments = parser.step(|mut cursor| { + let mut comments = Vec::new(); + loop { + let (comment, c) = match cursor.comment() { + Some(pair) => pair, + None => break, + }; + cursor = c; + comments.push(match comment { + Comment::Block(s) => &s[2..s.len() - 2], + Comment::Line(s) => &s[2..], + }); + } + Ok((comments, cursor)) + })?; + Ok(CommentSyntax { comments }) + } +} + +impl<'a> CommentSyntax<'a> { + pub fn docs(&self) -> String { + // Perform a small amount of preprocessing by removing all trailing + // whitespace, and then also filter for only "doc comments" which are `;;;` + // or `(;; ... ;)`. + let docs = self + .comments + .iter() + .map(|d| d.trim_end()) + .filter_map(|d| { + if d.starts_with(";") { + Some(&d[1..]) + } else { + None + } + }) + .collect::>(); + + // Figure out how much leading whitespace we're going to be trimming from + // all docs, trimming the minimum amount in each doc comment. + let to_trim = docs + .iter() + .filter(|d| !d.is_empty()) + .map(|d| d.len() - d.trim().len()) + .min() + .unwrap_or(0); + + // Separate all documents by a newline and collect everything into a single + // string. + let mut ret = String::new(); + for doc in docs { + if !doc.is_empty() { + ret.push_str(doc[to_trim..].trim_end()); + } + ret.push_str("\n"); + } + return ret; + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct Documented<'a, T> { + pub comments: CommentSyntax<'a>, + pub item: T, +} + +impl<'a, T: Parse<'a>> Parse<'a> for Documented<'a, T> { + fn parse(parser: Parser<'a>) -> Result { + let comments = parser.parse()?; + let item = parser.parse()?; + Ok(Documented { comments, item }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum DatatypeIdentSyntax<'a> { Builtin(BuiltinType), @@ -179,14 +260,14 @@ impl Peek for AtInterface { #[derive(Debug, Clone, PartialEq, Eq)] pub struct TopLevelDocument<'a> { - pub items: Vec>, + pub items: Vec>>, } impl<'a> Parse<'a> for TopLevelDocument<'a> { fn parse(parser: Parser<'a>) -> Result { let mut items = Vec::new(); while !parser.is_empty() { - items.push(parser.parens(|p| p.parse())?); + items.push(parser.parse()?); } Ok(TopLevelDocument { items }) } @@ -200,12 +281,14 @@ pub enum TopLevelSyntax<'a> { impl<'a> Parse<'a> for TopLevelSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - if parser.peek::() { - parser.parse::()?; - Ok(TopLevelSyntax::Use(parser.parse()?)) - } else { - Ok(TopLevelSyntax::Decl(parser.parse()?)) - } + parser.parens(|p| { + if p.peek::() { + p.parse::()?; + Ok(TopLevelSyntax::Use(p.parse()?)) + } else { + Ok(TopLevelSyntax::Decl(p.parse()?)) + } + }) } } @@ -278,7 +361,7 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumSyntax<'a> { pub repr: BuiltinType, - pub members: Vec>, + pub members: Vec>>, } impl<'a> Parse<'a> for EnumSyntax<'a> { @@ -297,7 +380,7 @@ impl<'a> Parse<'a> for EnumSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsSyntax<'a> { pub repr: BuiltinType, - pub flags: Vec>, + pub flags: Vec>>, } impl<'a> Parse<'a> for FlagsSyntax<'a> { @@ -314,16 +397,16 @@ impl<'a> Parse<'a> for FlagsSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct StructSyntax<'a> { - pub fields: Vec>, + pub fields: Vec>>, } impl<'a> Parse<'a> for StructSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; let mut fields = Vec::new(); - fields.push(parser.parens(|p| p.parse())?); + fields.push(parser.parse()?); while !parser.is_empty() { - fields.push(parser.parens(|p| p.parse())?); + fields.push(parser.parse()?); } Ok(StructSyntax { fields }) } @@ -337,25 +420,27 @@ pub struct FieldSyntax<'a> { impl<'a> Parse<'a> for FieldSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let name = parser.parse()?; - let type_ = parser.parse()?; - Ok(FieldSyntax { name, type_ }) + parser.parens(|p| { + p.parse::()?; + let name = p.parse()?; + let type_ = p.parse()?; + Ok(FieldSyntax { name, type_ }) + }) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionSyntax<'a> { - pub fields: Vec>, + pub fields: Vec>>, } impl<'a> Parse<'a> for UnionSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; let mut fields = Vec::new(); - fields.push(parser.parens(|p| p.parse())?); + fields.push(parser.parse()?); while !parser.is_empty() { - fields.push(parser.parens(|p| p.parse())?); + fields.push(parser.parse()?); } Ok(UnionSyntax { fields }) } @@ -364,7 +449,7 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct ModuleSyntax<'a> { pub name: wast::Id<'a>, - pub decls: Vec>, + pub decls: Vec>>, } impl<'a> Parse<'a> for ModuleSyntax<'a> { @@ -373,7 +458,7 @@ impl<'a> Parse<'a> for ModuleSyntax<'a> { let name = parser.parse()?; let mut decls = Vec::new(); while !parser.is_empty() { - decls.push(parser.parens(|p| p.parse())?); + decls.push(parser.parse()?); } Ok(ModuleSyntax { name, decls }) } @@ -387,14 +472,16 @@ pub enum ModuleDeclSyntax<'a> { impl<'a> Parse<'a> for ModuleDeclSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(ModuleDeclSyntax::Import(parser.parse()?)) - } else if l.peek::() { - Ok(ModuleDeclSyntax::Func(parser.parse()?)) - } else { - Err(l.error()) - } + parser.parens(|p| { + let mut l = p.lookahead1(); + if l.peek::() { + Ok(ModuleDeclSyntax::Import(p.parse()?)) + } else if l.peek::() { + Ok(ModuleDeclSyntax::Func(p.parse()?)) + } else { + Err(l.error()) + } + }) } } @@ -442,8 +529,8 @@ impl Parse<'_> for ImportTypeSyntax { pub struct InterfaceFuncSyntax<'a> { pub export: &'a str, pub export_loc: wast::Span, - pub params: Vec>, - pub results: Vec>, + pub params: Vec>>, + pub results: Vec>>, } impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { @@ -460,25 +547,21 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { let mut results = Vec::new(); while !parser.is_empty() { - parser.parens(|p| { - let mut l = p.lookahead1(); - if l.peek::() { - parser.parse::()?; - params.push(FieldSyntax { - name: parser.parse()?, - type_: parser.parse()?, + let func_field = parser.parse::>()?; + match func_field.item { + InterfaceFuncField::Param(item) => { + params.push(Documented { + comments: func_field.comments, + item, }); - } else if l.peek::() { - parser.parse::()?; - results.push(FieldSyntax { - name: parser.parse()?, - type_: parser.parse()?, + } + InterfaceFuncField::Result(item) => { + results.push(Documented { + comments: func_field.comments, + item, }); - } else { - return Err(l.error()); } - Ok(()) - })?; + } } Ok(InterfaceFuncSyntax { @@ -490,6 +573,33 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { } } +enum InterfaceFuncField<'a> { + Param(FieldSyntax<'a>), + Result(FieldSyntax<'a>), +} +impl<'a> Parse<'a> for InterfaceFuncField<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parens(|p| { + let mut l = p.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(InterfaceFuncField::Param(FieldSyntax { + name: parser.parse()?, + type_: parser.parse()?, + })) + } else if l.peek::() { + parser.parse::()?; + Ok(InterfaceFuncField::Result(FieldSyntax { + name: parser.parse()?, + type_: parser.parse()?, + })) + } else { + Err(l.error()) + } + }) + } +} + impl PartialEq for InterfaceFuncSyntax<'_> { fn eq(&self, other: &InterfaceFuncSyntax<'_>) -> bool { // skip the `export_loc` field diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 8e23a5fa8..4bb7df729 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -21,6 +21,8 @@ pub enum SExpr { Quote(String), /// Short for Annotation Annot(String), + /// Doc comment + Docs(String, Box), } impl fmt::Display for SExpr { @@ -39,6 +41,7 @@ impl fmt::Display for SExpr { SExpr::Ident(i) => write!(f, "${}", i), SExpr::Quote(q) => write!(f, "\"{}\"", q), SExpr::Annot(a) => write!(f, "@{}", a), + SExpr::Docs(d, s) => write!(f, "(;; {} ;) {}", d, s), } } } @@ -56,6 +59,13 @@ impl SExpr { fn annot(s: &str) -> SExpr { SExpr::Annot(s.to_string()) } + fn docs(d: &str, s: SExpr) -> SExpr { + if d.is_empty() { + s + } else { + SExpr::Docs(d.to_string(), Box::new(s)) + } + } } pub trait Render { @@ -110,7 +120,10 @@ impl Render for Datatype { fn to_sexpr(&self) -> SExpr { let name = self.name.to_sexpr(); let body = self.variant.to_sexpr(); - SExpr::Vec(vec![SExpr::word("typename"), name, body]) + SExpr::docs( + &self.docs, + SExpr::Vec(vec![SExpr::word("typename"), name, body]), + ) } } @@ -138,7 +151,7 @@ impl Render for EnumDatatype { let variants = self .variants .iter() - .map(|v| v.to_sexpr()) + .map(|v| SExpr::docs(&v.docs, v.name.to_sexpr())) .collect::>(); SExpr::Vec([header, variants].concat()) } @@ -150,7 +163,7 @@ impl Render for FlagsDatatype { let flags = self .flags .iter() - .map(|f| f.to_sexpr()) + .map(|f| SExpr::docs(&f.docs, f.name.to_sexpr())) .collect::>(); SExpr::Vec([header, flags].concat()) } @@ -163,11 +176,14 @@ impl Render for StructDatatype { .members .iter() .map(|m| { - SExpr::Vec(vec![ - SExpr::word("field"), - m.name.to_sexpr(), - m.type_.to_sexpr(), - ]) + SExpr::docs( + &m.docs, + SExpr::Vec(vec![ + SExpr::word("field"), + m.name.to_sexpr(), + m.type_.to_sexpr(), + ]), + ) }) .collect::>(); SExpr::Vec([header, members].concat()) @@ -181,11 +197,14 @@ impl Render for UnionDatatype { .variants .iter() .map(|v| { - SExpr::Vec(vec![ - SExpr::word("field"), - v.name.to_sexpr(), - v.type_.to_sexpr(), - ]) + SExpr::docs( + &v.docs, + SExpr::Vec(vec![ + SExpr::word("field"), + v.name.to_sexpr(), + v.type_.to_sexpr(), + ]), + ) }) .collect::>(); SExpr::Vec([header, variants].concat()) @@ -211,7 +230,7 @@ impl Render for Module { .map(|i| i.to_sexpr()) .chain(self.funcs().map(|f| f.to_sexpr())) .collect::>(); - SExpr::Vec([header, definitions].concat()) + SExpr::docs(&self.docs, SExpr::Vec([header, definitions].concat())) } } @@ -220,11 +239,14 @@ impl Render for ModuleImport { let variant = match self.variant { ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), }; - SExpr::Vec(vec![ - SExpr::word("import"), - SExpr::quote(self.name.as_str()), - variant, - ]) + SExpr::docs( + &self.docs, + SExpr::Vec(vec![ + SExpr::word("import"), + SExpr::quote(self.name.as_str()), + variant, + ]), + ) } } @@ -242,24 +264,30 @@ impl Render for InterfaceFunc { .params .iter() .map(|f| { - SExpr::Vec(vec![ - SExpr::word("param"), - f.name.to_sexpr(), - f.type_.to_sexpr(), - ]) + SExpr::docs( + &f.docs, + SExpr::Vec(vec![ + SExpr::word("param"), + f.name.to_sexpr(), + f.type_.to_sexpr(), + ]), + ) }) .collect(); let results = self .results .iter() .map(|f| { - SExpr::Vec(vec![ - SExpr::word("result"), - f.name.to_sexpr(), - f.type_.to_sexpr(), - ]) + SExpr::docs( + &f.docs, + SExpr::Vec(vec![ + SExpr::word("result"), + f.name.to_sexpr(), + f.type_.to_sexpr(), + ]), + ) }) .collect(); - SExpr::Vec([header, params, results].concat()) + SExpr::docs(&self.docs, SExpr::Vec([header, params, results].concat())) } } diff --git a/proposals/clocks/tools/witx/src/toplevel.rs b/proposals/clocks/tools/witx/src/toplevel.rs index 281ad4757..2e0738a6b 100644 --- a/proposals/clocks/tools/witx/src/toplevel.rs +++ b/proposals/clocks/tools/witx/src/toplevel.rs @@ -58,11 +58,11 @@ fn parse_file( let doc = wast::parser::parse::(&buf).map_err(adjust_err)?; for t in doc.items { - match t { + match t.item { TopLevelSyntax::Decl(d) => { let def = validator .scope(&input, &path) - .validate_decl(&d) + .validate_decl(&d, &t.comments) .map_err(WitxError::Validation)?; definitions.push(def); } diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index a0d9ea96b..eba087e8c 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -1,13 +1,14 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ - DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, ImportTypeSyntax, - ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + CommentSyntax, DatatypeIdentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, + ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, - Definition, Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, - InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, + Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, Id, IntRepr, + InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, + ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, + UnionDatatype, UnionVariant, }; use failure::Fail; use std::collections::HashMap; @@ -158,10 +159,15 @@ impl DocValidationScope<'_> { self.doc.scope.get(name.name(), loc) } - pub fn validate_decl(&mut self, decl: &DeclSyntax) -> Result { + pub fn validate_decl( + &mut self, + decl: &DeclSyntax, + comments: &CommentSyntax, + ) -> Result { match decl { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; + let docs = comments.docs(); let variant = match &decl.def { TypedefSyntax::Ident(syntax) => DatatypeVariant::Alias(AliasDatatype { @@ -186,6 +192,7 @@ impl DocValidationScope<'_> { let rc_datatype = Rc::new(Datatype { name: name.clone(), variant, + docs, }); self.doc .entries @@ -205,6 +212,7 @@ impl DocValidationScope<'_> { name.clone(), definitions, module_validator.entries, + comments.docs(), )); self.doc .entries @@ -261,8 +269,12 @@ impl DocValidationScope<'_> { let variants = syntax .members .iter() - .map(|i| enum_scope.introduce(i.name(), self.location(i.span()))) - .collect::, _>>()?; + .map(|i| { + let name = enum_scope.introduce(i.item.name(), self.location(i.item.span()))?; + let docs = i.comments.docs(); + Ok(EnumVariant { name, docs }) + }) + .collect::, _>>()?; Ok(EnumDatatype { name: name.clone(), @@ -282,8 +294,12 @@ impl DocValidationScope<'_> { let flags = syntax .flags .iter() - .map(|i| flags_scope.introduce(i.name(), self.location(i.span()))) - .collect::, _>>()?; + .map(|i| { + let name = flags_scope.introduce(i.item.name(), self.location(i.item.span()))?; + let docs = i.comments.docs(); + Ok(FlagsMember { name, docs }) + }) + .collect::, _>>()?; Ok(FlagsDatatype { name: name.clone(), @@ -303,10 +319,11 @@ impl DocValidationScope<'_> { .fields .iter() .map(|f| { - Ok(StructMember { - name: member_scope.introduce(f.name.name(), self.location(f.name.span()))?, - type_: self.validate_datatype_ident(&f.type_)?, - }) + let name = member_scope + .introduce(f.item.name.name(), self.location(f.item.name.span()))?; + let type_ = self.validate_datatype_ident(&f.item.type_)?; + let docs = f.comments.docs(); + Ok(StructMember { name, type_, docs }) }) .collect::, _>>()?; @@ -327,10 +344,11 @@ impl DocValidationScope<'_> { .fields .iter() .map(|f| { - Ok(UnionVariant { - name: variant_scope.introduce(f.name.name(), self.location(f.name.span()))?, - type_: self.validate_datatype_ident(&f.type_)?, - }) + let name = variant_scope + .introduce(f.item.name.name(), self.location(f.item.name.span()))?; + let type_ = self.validate_datatype_ident(&f.item.type_)?; + let docs = f.comments.docs(); + Ok(UnionVariant { name, type_, docs }) }) .collect::, _>>()?; @@ -375,9 +393,9 @@ impl<'a> ModuleValidation<'a> { fn validate_decl( &mut self, - decl: &ModuleDeclSyntax, + decl: &Documented, ) -> Result { - match decl { + match &decl.item { ModuleDeclSyntax::Import(syntax) => { let loc = self.doc.location(syntax.name_loc); let name = self.scope.introduce(syntax.name, loc)?; @@ -387,6 +405,7 @@ impl<'a> ModuleValidation<'a> { let rc_import = Rc::new(ModuleImport { name: name.clone(), variant, + docs: decl.comments.docs(), }); self.entries .insert(name, ModuleEntry::Import(Rc::downgrade(&rc_import))); @@ -402,10 +421,13 @@ impl<'a> ModuleValidation<'a> { .enumerate() .map(|(ix, f)| { Ok(InterfaceFuncParam { - name: argnames - .introduce(f.name.name(), self.doc.location(f.name.span()))?, - type_: self.doc.validate_datatype_ident(&f.type_)?, + name: argnames.introduce( + f.item.name.name(), + self.doc.location(f.item.name.span()), + )?, + type_: self.doc.validate_datatype_ident(&f.item.type_)?, position: InterfaceFuncParamPosition::Param(ix), + docs: f.comments.docs(), }) }) .collect::, _>>()?; @@ -414,20 +436,23 @@ impl<'a> ModuleValidation<'a> { .iter() .enumerate() .map(|(ix, f)| { - let type_ = self.doc.validate_datatype_ident(&f.type_)?; + let type_ = self.doc.validate_datatype_ident(&f.item.type_)?; if ix == 0 { match type_.passed_by() { DatatypePassedBy::Value(_) => {} _ => Err(ValidationError::InvalidFirstResultType { - location: self.doc.location(f.name.span()), + location: self.doc.location(f.item.name.span()), })?, } } Ok(InterfaceFuncParam { - name: argnames - .introduce(f.name.name(), self.doc.location(f.name.span()))?, + name: argnames.introduce( + f.item.name.name(), + self.doc.location(f.item.name.span()), + )?, type_, position: InterfaceFuncParamPosition::Result(ix), + docs: f.comments.docs(), }) }) .collect::, _>>()?; @@ -436,6 +461,7 @@ impl<'a> ModuleValidation<'a> { name: name.clone(), params, results, + docs: decl.comments.docs(), }); self.entries .insert(name, ModuleEntry::Func(Rc::downgrade(&rc_func))); diff --git a/proposals/clocks/tools/witx/tests/wasi.rs b/proposals/clocks/tools/witx/tests/wasi.rs index b5a9d527c..aef954236 100644 --- a/proposals/clocks/tools/witx/tests/wasi.rs +++ b/proposals/clocks/tools/witx/tests/wasi.rs @@ -29,5 +29,31 @@ fn render_roundtrip() { .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) .unwrap(); + let back_to_sexprs = format!("{}", doc); + + let doc2 = witx::parse(&back_to_sexprs) + .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) + .unwrap(); + + // I'd just assert_eq, but when it fails the debug print is thousands of lines long and impossible + // to figure out where they are unequal. + if doc != doc2 { + for type_ in doc.datatypes() { + let type2 = doc2.datatype(&type_.name).expect("doc2 missing datatype"); + assert_eq!(type_, type2); + } + for mod_ in doc.modules() { + let mod2 = doc2.module(&mod_.name).expect("doc2 missing module"); + for import in mod_.imports() { + let import2 = mod2.import(&import.name).expect("mod2 missing import"); + assert_eq!(import, import2); + } + for func in mod_.funcs() { + let func2 = mod2.func(&func.name).expect("mod2 missing func"); + assert_eq!(func, func2); + } + } + } + // This should be equivelant to the above, but just in case some code changes where it isnt: assert_eq!(doc, doc2); } From 316cc553a1a5b652a05ef7a11854e8e6b6b84e10 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 16:54:40 -0800 Subject: [PATCH 0293/1772] witx: Parse comments into documentation in AST (#140) * witx: add support for parsing multiple top-level witx files * tests: test parsing multiple top-level witx files * witx: add a multimodule test that rejects redefined names and rename the path to be a litle shorter * witx: add `CommentSyntax` and `Documented` parsers Derived from ca26654f7747e2c9ce9d80d05c23a4ed48ec126c in https://github.com/alexcrichton/wat (PR #26) * witx: Parse comments of top level definitions, render crude markdown * filter for doc comments, trim whitespace * some progress on doc comments. wip * more wip! * complete adding doc parsing to AST * bugfixes, use a subcommand to emit docs * witx: forgot to add docs to module. add docs to output for roundtrip testing * wasi documents: convert all comments to doc-comments sed -i -E "s/ ;; / ;;; /" **/*.witx sed -i -E "s/^;; /;;; /" **/*.witx * fix fd_advise doc comments to come before parameters * tests: try to narrow failure a bit * witx files: normalize leading whitespace in doc-comments this was stopping the roundtripping test from passing, since the whitespace in the AST is slightly different after a roundtrip. I am not feeling clever enough to think of an elegant solution now, so I'll just hack up these files to not hit the bug. * witx files: very top comment is not a doc --- .../phases/ephemeral/witx/typenames.witx | 678 ++++++++--------- .../witx/wasi_ephemeral_preview.witx | 413 +++++------ .../phases/old/snapshot_0/witx/typenames.witx | 678 ++++++++--------- .../old/snapshot_0/witx/wasi_unstable.witx | 419 +++++------ .../phases/snapshot/witx/typenames.witx | 680 +++++++++--------- .../snapshot/witx/wasi_snapshot_preview1.witx | 413 +++++------ proposals/random/tools/witx/src/ast.rs | 25 +- proposals/random/tools/witx/src/docs.rs | 227 ++++++ proposals/random/tools/witx/src/lib.rs | 9 +- proposals/random/tools/witx/src/main.rs | 29 +- proposals/random/tools/witx/src/parser.rs | 206 ++++-- proposals/random/tools/witx/src/render.rs | 88 ++- proposals/random/tools/witx/src/toplevel.rs | 4 +- proposals/random/tools/witx/src/validate.rs | 80 ++- proposals/random/tools/witx/tests/wasi.rs | 26 + 15 files changed, 2224 insertions(+), 1751 deletions(-) create mode 100644 proposals/random/tools/witx/src/docs.rs diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 1a45be1fd..a614d8528 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -7,291 +7,291 @@ (typename $size_t u32) -;; Non-negative file size or length of a region within a file. +;;; Non-negative file size or length of a region within a file. (typename $filesize_t u64) -;; Timestamp in nanoseconds. +;;; Timestamp in nanoseconds. (typename $timestamp_t u64) -;; Identifiers for clocks. +;;; Identifiers for clocks. (typename $clockid_t (enum u32 - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. + ;;; The clock measuring real time. Time value zero corresponds with + ;;; 1970-01-01T00:00:00Z. $CLOCK_REALTIME - ;; The store-wide monotonic clock, which is defined as a clock measuring - ;; real time, whose value cannot be adjusted and which cannot have negative - ;; clock jumps. The epoch of this clock is undefined. The absolute time - ;; value of this clock therefore has no meaning. + ;;; The store-wide monotonic clock, which is defined as a clock measuring + ;;; real time, whose value cannot be adjusted and which cannot have negative + ;;; clock jumps. The epoch of this clock is undefined. The absolute time + ;;; value of this clock therefore has no meaning. $CLOCK_MONOTONIC - ;; The CPU-time clock associated with the current process. + ;;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The CPU-time clock associated with the current thread. + ;;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) ) -;; Error codes returned by functions. -;; Not all of these error codes are returned by the functions provided by this -;; API; some are used in higher-level library layers, and others are provided -;; merely for alignment with POSIX. +;;; Error codes returned by functions. +;;; Not all of these error codes are returned by the functions provided by this +;;; API; some are used in higher-level library layers, and others are provided +;;; merely for alignment with POSIX. (typename $errno_t (enum u16 - ;; No error occurred. System call completed successfully. + ;;; No error occurred. System call completed successfully. $ESUCCESS - ;; Argument list too long. + ;;; Argument list too long. $E2BIG - ;; Permission denied. + ;;; Permission denied. $EACCES - ;; Address in use. + ;;; Address in use. $EADDRINUSE - ;; Address not available. + ;;; Address not available. $EADDRNOTAVAIL - ;; Address family not supported. + ;;; Address family not supported. $EAFNOSUPPORT - ;; Resource unavailable, or operation would block. + ;;; Resource unavailable, or operation would block. $EAGAIN - ;; Connection already in progress. + ;;; Connection already in progress. $EALREADY - ;; Bad file descriptor. + ;;; Bad file descriptor. $EBADF - ;; Bad message. + ;;; Bad message. $EBADMSG - ;; Device or resource busy. + ;;; Device or resource busy. $EBUSY - ;; Operation canceled. + ;;; Operation canceled. $ECANCELED - ;; No child processes. + ;;; No child processes. $ECHILD - ;; Connection aborted. + ;;; Connection aborted. $ECONNABORTED - ;; Connection refused. + ;;; Connection refused. $ECONNREFUSED - ;; Connection reset. + ;;; Connection reset. $ECONNRESET - ;; Resource deadlock would occur. + ;;; Resource deadlock would occur. $EDEADLK - ;; Destination address required. + ;;; Destination address required. $EDESTADDRREQ - ;; Mathematics argument out of domain of function. + ;;; Mathematics argument out of domain of function. $EDOM - ;; Reserved. + ;;; Reserved. $EDQUOT - ;; File exists. + ;;; File exists. $EEXIST - ;; Bad address. + ;;; Bad address. $EFAULT - ;; File too large. + ;;; File too large. $EFBIG - ;; Host is unreachable. + ;;; Host is unreachable. $EHOSTUNREACH - ;; Identifier removed. + ;;; Identifier removed. $EIDRM - ;; Illegal byte sequence. + ;;; Illegal byte sequence. $EILSEQ - ;; Operation in progress. + ;;; Operation in progress. $EINPROGRESS - ;; Interrupted function. + ;;; Interrupted function. $EINTR - ;; Invalid argument. + ;;; Invalid argument. $EINVAL - ;; I/O error. + ;;; I/O error. $EIO - ;; Socket is connected. + ;;; Socket is connected. $EISCONN - ;; Is a directory. + ;;; Is a directory. $EISDIR - ;; Too many levels of symbolic links. + ;;; Too many levels of symbolic links. $ELOOP - ;; File descriptor value too large. + ;;; File descriptor value too large. $EMFILE - ;; Too many links. + ;;; Too many links. $EMLINK - ;; Message too large. + ;;; Message too large. $EMSGSIZE - ;; Reserved. + ;;; Reserved. $EMULTIHOP - ;; Filename too long. + ;;; Filename too long. $ENAMETOOLONG - ;; Network is down. + ;;; Network is down. $ENETDOWN - ;; Connection aborted by network. + ;;; Connection aborted by network. $ENETRESET - ;; Network unreachable. + ;;; Network unreachable. $ENETUNREACH - ;; Too many files open in system. + ;;; Too many files open in system. $ENFILE - ;; No buffer space available. + ;;; No buffer space available. $ENOBUFS - ;; No such device. + ;;; No such device. $ENODEV - ;; No such file or directory. + ;;; No such file or directory. $ENOENT - ;; Executable file format error. + ;;; Executable file format error. $ENOEXEC - ;; No locks available. + ;;; No locks available. $ENOLCK - ;; Reserved. + ;;; Reserved. $ENOLINK - ;; Not enough space. + ;;; Not enough space. $ENOMEM - ;; No message of the desired type. + ;;; No message of the desired type. $ENOMSG - ;; Protocol not available. + ;;; Protocol not available. $ENOPROTOOPT - ;; No space left on device. + ;;; No space left on device. $ENOSPC - ;; Function not supported. + ;;; Function not supported. $ENOSYS - ;; The socket is not connected. + ;;; The socket is not connected. $ENOTCONN - ;; Not a directory or a symbolic link to a directory. + ;;; Not a directory or a symbolic link to a directory. $ENOTDIR - ;; Directory not empty. + ;;; Directory not empty. $ENOTEMPTY - ;; State not recoverable. + ;;; State not recoverable. $ENOTRECOVERABLE - ;; Not a socket. + ;;; Not a socket. $ENOTSOCK - ;; Not supported, or operation not supported on socket. + ;;; Not supported, or operation not supported on socket. $ENOTSUP - ;; Inappropriate I/O control operation. + ;;; Inappropriate I/O control operation. $ENOTTY - ;; No such device or address. + ;;; No such device or address. $ENXIO - ;; Value too large to be stored in data type. + ;;; Value too large to be stored in data type. $EOVERFLOW - ;; Previous owner died. + ;;; Previous owner died. $EOWNERDEAD - ;; Operation not permitted. + ;;; Operation not permitted. $EPERM - ;; Broken pipe. + ;;; Broken pipe. $EPIPE - ;; Protocol error. + ;;; Protocol error. $EPROTO - ;; Protocol not supported. + ;;; Protocol not supported. $EPROTONOSUPPORT - ;; Protocol wrong type for socket. + ;;; Protocol wrong type for socket. $EPROTOTYPE - ;; Result too large. + ;;; Result too large. $ERANGE - ;; Read-only file system. + ;;; Read-only file system. $EROFS - ;; Invalid seek. + ;;; Invalid seek. $ESPIPE - ;; No such process. + ;;; No such process. $ESRCH - ;; Reserved. + ;;; Reserved. $ESTALE - ;; Connection timed out. + ;;; Connection timed out. $ETIMEDOUT - ;; Text file busy. + ;;; Text file busy. $ETXTBSY - ;; Cross-device link. + ;;; Cross-device link. $EXDEV - ;; Extension: Capabilities insufficient. + ;;; Extension: Capabilities insufficient. $ENOTCAPABLE ) ) -;; File descriptor rights, determining which actions may be performed. +;;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke `fd_datasync`. + ;;; The right to invoke `fd_datasync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_DSYNC`. $RIGHT_FD_DATASYNC - ;; The right to invoke `fd_read` and `sock_recv`. + ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. $RIGHT_FD_READ - ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. $RIGHT_FD_SEEK - ;; The right to invoke `fd_fdstat_set_flags`. + ;;; The right to invoke `fd_fdstat_set_flags`. $RIGHT_FD_FDSTAT_SET_FLAGS - ;; The right to invoke `fd_sync`. + ;;; The right to invoke `fd_sync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. $RIGHT_FD_SYNC - ;; The right to invoke `fd_seek` in such a way that the file offset - ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to - ;; invoke `fd_tell`. + ;;; The right to invoke `fd_seek` in such a way that the file offset + ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; invoke `fd_tell`. $RIGHT_FD_TELL - ;; The right to invoke `fd_write` and `sock_send`. - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + ;;; The right to invoke `fd_write` and `sock_send`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. $RIGHT_FD_WRITE - ;; The right to invoke `fd_advise`. + ;;; The right to invoke `fd_advise`. $RIGHT_FD_ADVISE - ;; The right to invoke `fd_allocate`. + ;;; The right to invoke `fd_allocate`. $RIGHT_FD_ALLOCATE - ;; The right to invoke `path_create_directory`. + ;;; The right to invoke `path_create_directory`. $RIGHT_PATH_CREATE_DIRECTORY - ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. $RIGHT_PATH_CREATE_FILE - ;; The right to invoke `path_link` with the file descriptor as the - ;; source directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; source directory. $RIGHT_PATH_LINK_SOURCE - ;; The right to invoke `path_link` with the file descriptor as the - ;; target directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; target directory. $RIGHT_PATH_LINK_TARGET - ;; The right to invoke `path_open`. + ;;; The right to invoke `path_open`. $RIGHT_PATH_OPEN - ;; The right to invoke `fd_readdir`. + ;;; The right to invoke `fd_readdir`. $RIGHT_FD_READDIR - ;; The right to invoke `path_readlink`. + ;;; The right to invoke `path_readlink`. $RIGHT_PATH_READLINK - ;; The right to invoke `path_rename` with the file descriptor as the source directory. + ;;; The right to invoke `path_rename` with the file descriptor as the source directory. $RIGHT_PATH_RENAME_SOURCE - ;; The right to invoke `path_rename` with the file descriptor as the target directory. + ;;; The right to invoke `path_rename` with the file descriptor as the target directory. $RIGHT_PATH_RENAME_TARGET - ;; The right to invoke `path_filestat_get`. + ;;; The right to invoke `path_filestat_get`. $RIGHT_PATH_FILESTAT_GET - ;; The right to change a file's size (there is no `path_filestat_set_size`). - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + ;;; The right to change a file's size (there is no `path_filestat_set_size`). + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. $RIGHT_PATH_FILESTAT_SET_SIZE - ;; The right to invoke `path_filestat_set_times`. + ;;; The right to invoke `path_filestat_set_times`. $RIGHT_PATH_FILESTAT_SET_TIMES - ;; The right to invoke `fd_filestat_get`. + ;;; The right to invoke `fd_filestat_get`. $RIGHT_FD_FILESTAT_GET - ;; The right to invoke `fd_filestat_set_size`. + ;;; The right to invoke `fd_filestat_set_size`. $RIGHT_FD_FILESTAT_SET_SIZE - ;; The right to invoke `fd_filestat_set_times`. + ;;; The right to invoke `fd_filestat_set_times`. $RIGHT_FD_FILESTAT_SET_TIMES - ;; The right to invoke `path_symlink`. + ;;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_remove_directory`. + ;;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY - ;; The right to invoke `path_unlink_file`. + ;;; The right to invoke `path_unlink_file`. $RIGHT_PATH_UNLINK_FILE - ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE - ;; The right to invoke `sock_shutdown`. + ;;; The right to invoke `sock_shutdown`. $RIGHT_SOCK_SHUTDOWN ) ) -;; A file descriptor index. +;;; A file descriptor index. (typename $fd_t u32) -;; A region of memory for scatter/gather reads. +;;; A region of memory for scatter/gather reads. (typename $iovec_t (struct - ;; The address of the buffer to be filled. + ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) - ;; The length of the buffer to be filled. + ;;; The length of the buffer to be filled. (field $buf_len $size_t) ) ) -;; A region of memory for scatter/gather writes. +;;; A region of memory for scatter/gather writes. (typename $ciovec_t (struct - ;; The address of the buffer to be written. + ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) - ;; The length of the buffer to be written. + ;;; The length of the buffer to be written. (field $buf_len $size_t) ) ) @@ -299,469 +299,469 @@ (typename $iovec_t_array (array $iovec_t)) (typename $ciovec_t_array (array $ciovec_t)) -;; Relative offset within a file. +;;; Relative offset within a file. (typename $filedelta_t s64) -;; The position relative to which to set the offset of the file descriptor. +;;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 - ;; Seek relative to start-of-file. + ;;; Seek relative to start-of-file. $WHENCE_SET - ;; Seek relative to current position. + ;;; Seek relative to current position. $WHENCE_CUR - ;; Seek relative to end-of-file. + ;;; Seek relative to end-of-file. $WHENCE_END ) ) -;; A reference to the offset of a directory entry. +;;; A reference to the offset of a directory entry. ;; -;; The value 0 signifies the start of the directory. +;;; The value 0 signifies the start of the directory. (typename $dircookie_t u64) -;; The type for the $d_namlen field of $dirent_t. +;;; The type for the $d_namlen field of $dirent_t. (typename $dirnamlen_t u32) -;; File serial number that is unique within its file system. +;;; File serial number that is unique within its file system. (typename $inode_t u64) -;; The type of a file descriptor or file. +;;; The type of a file descriptor or file. (typename $filetype_t (enum u8 - ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $FILETYPE_UNKNOWN - ;; The file descriptor or file refers to a block device inode. + ;;; The file descriptor or file refers to a block device inode. $FILETYPE_BLOCK_DEVICE - ;; The file descriptor or file refers to a character device inode. + ;;; The file descriptor or file refers to a character device inode. $FILETYPE_CHARACTER_DEVICE - ;; The file descriptor or file refers to a directory inode. + ;;; The file descriptor or file refers to a directory inode. $FILETYPE_DIRECTORY - ;; The file descriptor or file refers to a regular file inode. + ;;; The file descriptor or file refers to a regular file inode. $FILETYPE_REGULAR_FILE - ;; The file descriptor or file refers to a datagram socket. + ;;; The file descriptor or file refers to a datagram socket. $FILETYPE_SOCKET_DGRAM - ;; The file descriptor or file refers to a byte-stream socket. + ;;; The file descriptor or file refers to a byte-stream socket. $FILETYPE_SOCKET_STREAM - ;; The file refers to a symbolic link inode. + ;;; The file refers to a symbolic link inode. $FILETYPE_SYMBOLIC_LINK ) ) -;; A directory entry. +;;; A directory entry. (typename $dirent_t (struct - ;; The offset of the next directory entry stored in this directory. + ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie_t) - ;; The serial number of the file referred to by this directory entry. + ;;; The serial number of the file referred to by this directory entry. (field $d_ino $inode_t) - ;; The length of the name of the directory entry. + ;;; The length of the name of the directory entry. (field $d_namlen $dirnamlen_t) - ;; The type of the file referred to by this directory entry. + ;;; The type of the file referred to by this directory entry. (field $d_type $filetype_t) ) ) -;; File or memory access pattern advisory information. +;;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application has no advice to give on its behavior with respect to the specified data. + ;;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL - ;; The application expects to access the specified data in a random order. + ;;; The application expects to access the specified data in a random order. $ADVICE_RANDOM - ;; The application expects to access the specified data in the near future. + ;;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED - ;; The application expects that it will not access the specified data in the near future. + ;;; The application expects that it will not access the specified data in the near future. $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. + ;;; The application expects to access the specified data once and then not reuse it thereafter. $ADVICE_NOREUSE ) ) -;; File descriptor flags. +;;; File descriptor flags. (typename $fdflags_t (flags u16 - ;; Append mode: Data written to the file is always appended to the file's end. + ;;; Append mode: Data written to the file is always appended to the file's end. $FDFLAG_APPEND - ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. $FDFLAG_DSYNC - ;; Non-blocking mode. + ;;; Non-blocking mode. $FDFLAG_NONBLOCK - ;; Synchronized read I/O operations. + ;;; Synchronized read I/O operations. $FDFLAG_RSYNC - ;; Write according to synchronized I/O file integrity completion. In - ;; addition to synchronizing the data stored in the file, the implementation - ;; may also synchronously update the file's metadata. + ;;; Write according to synchronized I/O file integrity completion. In + ;;; addition to synchronizing the data stored in the file, the implementation + ;;; may also synchronously update the file's metadata. $FDFLAG_SYNC ) ) -;; File descriptor attributes. +;;; File descriptor attributes. (typename $fdstat_t (struct - ;; File type. + ;;; File type. (field $fs_filetype $filetype_t) - ;; File descriptor flags. + ;;; File descriptor flags. (field $fs_flags $fdflags_t) - ;; Rights that apply to this file descriptor. + ;;; Rights that apply to this file descriptor. (field $fs_rights_base $rights_t) - ;; Maximum set of rights that may be installed on new file descriptors that - ;; are created through this file descriptor, e.g., through `path_open`. + ;;; Maximum set of rights that may be installed on new file descriptors that + ;;; are created through this file descriptor, e.g., through `path_open`. (field $fs_rights_inheriting $rights_t) ) ) -;; Identifier for a device containing a file system. Can be used in combination -;; with `inode_t` to uniquely identify a file or directory in the filesystem. +;;; Identifier for a device containing a file system. Can be used in combination +;;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) -;; Which file time attributes to adjust. +;;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 - ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. $FILESTAT_SET_ATIM - ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_ATIM_NOW - ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. $FILESTAT_SET_MTIM - ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_MTIM_NOW ) ) -;; Flags determining the method of how paths are resolved. +;;; Flags determining the method of how paths are resolved. (typename $lookupflags_t (flags u32 - ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $LOOKUP_SYMLINK_FOLLOW ) ) -;; Open flags used by `path_open`. +;;; Open flags used by `path_open`. (typename $oflags_t (flags u16 - ;; Create file if it does not exist. + ;;; Create file if it does not exist. $O_CREAT - ;; Fail if not a directory. + ;;; Fail if not a directory. $O_DIRECTORY - ;; Fail if file already exists. + ;;; Fail if file already exists. $O_EXCL - ;; Truncate file to size 0. + ;;; Truncate file to size 0. $O_TRUNC ) ) -;; Number of hard links to an inode. +;;; Number of hard links to an inode. (typename $linkcount_t u64) -;; File attributes. +;;; File attributes. (typename $filestat_t (struct - ;; Device ID of device containing the file. + ;;; Device ID of device containing the file. (field $st_dev $device_t) - ;; File serial number. + ;;; File serial number. (field $st_ino $inode_t) - ;; File type. + ;;; File type. (field $st_filetype $filetype_t) - ;; Number of hard links to the file. + ;;; Number of hard links to the file. (field $st_nlink $linkcount_t) - ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. (field $st_size $filesize_t) - ;; Last data access timestamp. + ;;; Last data access timestamp. (field $st_atim $timestamp_t) - ;; Last data modification timestamp. + ;;; Last data modification timestamp. (field $st_mtim $timestamp_t) - ;; Last file status change timestamp. + ;;; Last file status change timestamp. (field $st_ctim $timestamp_t) ) ) -;; User-provided value that may be attached to objects that is retained when -;; extracted from the implementation. +;;; User-provided value that may be attached to objects that is retained when +;;; extracted from the implementation. (typename $userdata_t u64) -;; Type of a subscription to an event or its occurrence. +;;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (enum u8 - ;; The time value of clock `subscription_t::u.clock.clock_id` has - ;; reached timestamp `subscription_t::u.clock.timeout`. + ;;; The time value of clock `subscription_t::u.clock.clock_id` has + ;;; reached timestamp `subscription_t::u.clock.timeout`. $EVENTTYPE_CLOCK - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data - ;; available for reading. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; available for reading. This event always triggers for regular files. $EVENTTYPE_FD_READ - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity - ;; available for writing. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;;; available for writing. This event always triggers for regular files. $EVENTTYPE_FD_WRITE ) ) -;; The state of the file descriptor subscribed to with -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The state of the file descriptor subscribed to with +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 - ;; The peer of this socket has closed or disconnected. + ;;; The peer of this socket has closed or disconnected. $EVENT_FD_READWRITE_HANGUP ) ) -;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;; `EVENTTYPE_FD_WRITE`. +;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;;; `EVENTTYPE_FD_WRITE`. (typename $event_fd_readwrite_t (struct - ;; The number of bytes available for reading or writing. + ;;; The number of bytes available for reading or writing. (field $nbytes $filesize_t) - ;; The state of the file descriptor. + ;;; The state of the file descriptor. (field $flags $eventrwflags_t) ) ) -;; The contents of an $event_t. +;;; The contents of an $event_t. (typename $event_u (union - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; An event that occurred. +;;; An event that occurred. (typename $event_t (struct - ;; User-provided value that got attached to `subscription_t::userdata`. + ;;; User-provided value that got attached to `subscription_t::userdata`. (field $userdata $userdata_t) - ;; If non-zero, an error that occurred while processing the subscription request. + ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno_t) - ;; The type of the event that occurred. + ;;; The type of the event that occurred. (field $type $eventtype_t) - ;; The contents of the event. + ;;; The contents of the event. (field $u $event_u) ) ) -;; Flags determining how to interpret the timestamp provided in -;; `subscription_t::u.clock.timeout.` +;;; Flags determining how to interpret the timestamp provided in +;;; `subscription_t::u.clock.timeout.` (typename $subclockflags_t (flags u16 - ;; If set, treat the timestamp provided in - ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;; provided in `subscription_t::u.clock.timeout` relative to the - ;; current time value of clock `subscription_t::u.clock.clock_id.` + ;;; If set, treat the timestamp provided in + ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription_t::u.clock.timeout` relative to the + ;;; current time value of clock `subscription_t::u.clock.clock_id.` $SUBSCRIPTION_CLOCK_ABSTIME ) ) -;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The clock against which to compare the timestamp. + ;;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. + ;;; The absolute or relative timestamp. (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. + ;;; The amount of time that the implementation may wait additionally + ;;; to coalesce with other events. (field $precision $timestamp_t) - ;; Flags specifying whether the timeout is absolute or relative + ;;; Flags specifying whether the timeout is absolute or relative (field $flags $subclockflags_t) ) ) -;; The contents of a $subscription_t when type is type is -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The contents of a $subscription_t when type is type is +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $subscription_fd_readwrite_t (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. + ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd_t) ) ) -;; The contents of a $subscription_t. +;;; The contents of a $subscription_t. (typename $subscription_u (union - ;; When type is `EVENTTYPE_CLOCK`: + ;;; When type is `EVENTTYPE_CLOCK`: (field $clock $subscription_clock_t) - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $subscription_fd_readwrite_t) ) ) -;; Subscription to an event. +;;; Subscription to an event. (typename $subscription_t (struct - ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through `event_t::userdata`. + ;;; User-provided value that is attached to the subscription in the + ;;; implementation and returned through `event_t::userdata`. (field $userdata $userdata_t) - ;; The type of the event to which to subscribe. + ;;; The type of the event to which to subscribe. (field $type $eventtype_t) - ;; The contents of the subscription. + ;;; The contents of the subscription. (field $u $subscription_u) ) ) -;; Exit code generated by a process when exiting. +;;; Exit code generated by a process when exiting. (typename $exitcode_t u32) -;; Signal condition. +;;; Signal condition. (typename $signal_t (enum u8 - ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;; so this value is reserved. + ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;;; so this value is reserved. $SIGNONE - ;; Hangup. - ;; Action: Terminates the process. + ;;; Hangup. + ;;; Action: Terminates the process. $SIGHUP - ;; Terminate interrupt signal. - ;; Action: Terminates the process. + ;;; Terminate interrupt signal. + ;;; Action: Terminates the process. $SIGINT - ;; Terminal quit signal. - ;; Action: Terminates the process. + ;;; Terminal quit signal. + ;;; Action: Terminates the process. $SIGQUIT - ;; Illegal instruction. - ;; Action: Terminates the process. + ;;; Illegal instruction. + ;;; Action: Terminates the process. $SIGILL - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. + ;;; Trace/breakpoint trap. + ;;; Action: Terminates the process. $SIGTRAP - ;; Process abort signal. - ;; Action: Terminates the process. + ;;; Process abort signal. + ;;; Action: Terminates the process. $SIGABRT - ;; Access to an undefined portion of a memory object. - ;; Action: Terminates the process. + ;;; Access to an undefined portion of a memory object. + ;;; Action: Terminates the process. $SIGBUS - ;; Erroneous arithmetic operation. - ;; Action: Terminates the process. + ;;; Erroneous arithmetic operation. + ;;; Action: Terminates the process. $SIGFPE - ;; Kill. - ;; Action: Terminates the process. + ;;; Kill. + ;;; Action: Terminates the process. $SIGKILL - ;; User-defined signal 1. - ;; Action: Terminates the process. + ;;; User-defined signal 1. + ;;; Action: Terminates the process. $SIGUSR1 - ;; Invalid memory reference. - ;; Action: Terminates the process. + ;;; Invalid memory reference. + ;;; Action: Terminates the process. $SIGSEGV - ;; User-defined signal 2. - ;; Action: Terminates the process. + ;;; User-defined signal 2. + ;;; Action: Terminates the process. $SIGUSR2 - ;; Write on a pipe with no one to read it. - ;; Action: Ignored. + ;;; Write on a pipe with no one to read it. + ;;; Action: Ignored. $SIGPIPE - ;; Alarm clock. - ;; Action: Terminates the process. + ;;; Alarm clock. + ;;; Action: Terminates the process. $SIGALRM - ;; Termination signal. - ;; Action: Terminates the process. + ;;; Termination signal. + ;;; Action: Terminates the process. $SIGTERM - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. + ;;; Child process terminated, stopped, or continued. + ;;; Action: Ignored. $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. + ;;; Continue executing, if stopped. + ;;; Action: Continues executing, if stopped. $SIGCONT - ;; Stop executing. - ;; Action: Stops executing. + ;;; Stop executing. + ;;; Action: Stops executing. $SIGSTOP - ;; Terminal stop signal. - ;; Action: Stops executing. + ;;; Terminal stop signal. + ;;; Action: Stops executing. $SIGTSTP - ;; Background process attempting read. - ;; Action: Stops executing. + ;;; Background process attempting read. + ;;; Action: Stops executing. $SIGTTIN - ;; Background process attempting write. - ;; Action: Stops executing. + ;;; Background process attempting write. + ;;; Action: Stops executing. $SIGTTOU - ;; High bandwidth data is available at a socket. - ;; Action: Ignored. + ;;; High bandwidth data is available at a socket. + ;;; Action: Ignored. $SIGURG - ;; CPU time limit exceeded. - ;; Action: Terminates the process. + ;;; CPU time limit exceeded. + ;;; Action: Terminates the process. $SIGXCPU - ;; File size limit exceeded. - ;; Action: Terminates the process. + ;;; File size limit exceeded. + ;;; Action: Terminates the process. $SIGXFSZ - ;; Virtual timer expired. - ;; Action: Terminates the process. + ;;; Virtual timer expired. + ;;; Action: Terminates the process. $SIGVTALRM - ;; Profiling timer expired. - ;; Action: Terminates the process. + ;;; Profiling timer expired. + ;;; Action: Terminates the process. $SIGPROF - ;; Window changed. - ;; Action: Ignored. + ;;; Window changed. + ;;; Action: Ignored. $SIGWINCH - ;; I/O possible. - ;; Action: Terminates the process. + ;;; I/O possible. + ;;; Action: Terminates the process. $SIGPOLL - ;; Power failure. - ;; Action: Terminates the process. + ;;; Power failure. + ;;; Action: Terminates the process. $SIGPWR - ;; Bad system call. - ;; Action: Terminates the process. + ;;; Bad system call. + ;;; Action: Terminates the process. $SIGSYS ) ) -;; Flags provided to `sock_recv`. +;;; Flags provided to `sock_recv`. (typename $riflags_t (flags u16 - ;; Returns the message without removing it from the socket's receive queue. + ;;; Returns the message without removing it from the socket's receive queue. $SOCK_RECV_PEEK - ;; On byte-stream sockets, block until the full amount of data can be returned. + ;;; On byte-stream sockets, block until the full amount of data can be returned. $SOCK_RECV_WAITALL ) ) -;; Flags returned by `sock_recv`. +;;; Flags returned by `sock_recv`. (typename $roflags_t (flags u16 - ;; Returned by `sock_recv`: Message data has been truncated. + ;;; Returned by `sock_recv`: Message data has been truncated. $SOCK_RECV_DATA_TRUNCATED ) ) -;; Flags provided to `sock_send`. As there are currently no flags -;; defined, it must be set to zero. +;;; Flags provided to `sock_send`. As there are currently no flags +;;; defined, it must be set to zero. (typename $siflags_t u16) -;; Which channels on a socket to shut down. +;;; Which channels on a socket to shut down. (typename $sdflags_t (flags u8 - ;; Disables further receive operations. + ;;; Disables further receive operations. $SHUT_RD - ;; Disables further send operations. + ;;; Disables further send operations. $SHUT_WR ) ) -;; Identifiers for preopened capabilities. +;;; Identifiers for preopened capabilities. (typename $preopentype_t (enum u8 - ;; A pre-opened directory. + ;;; A pre-opened directory. $PREOPENTYPE_DIR ) ) -;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. (typename $prestat_dir (struct - ;; The length of the directory name for use with `fd_prestat_dir_name`. + ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size_t) ) ) -;; The contents of an $prestat_t. +;;; The contents of an $prestat_t. (typename $prestat_u (union - ;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `PREOPENTYPE_DIR`: (field $dir $prestat_dir) ) ) -;; Information about a pre-opened capability. +;;; Information about a pre-opened capability. (typename $prestat_t (struct - ;; The type of the pre-opened capability. + ;;; The type of the pre-opened capability. (field $pr_type $preopentype_t) - ;; The contents of the information. + ;;; The contents of the information. (field $u $prestat_u) ) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx index f98ff129b..d15b8c514 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -9,519 +9,522 @@ (use "typenames.witx") (module $wasi_ephemeral_preview - ;; Linear memory to be accessed by WASI functions that need it. + ;;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) - ;; Read command-line argument data. - ;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; Read command-line argument data. + ;;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Read environment variable data. - ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; Read environment variable data. + ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Return the resolution of a clock. - ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;; Note: This is similar to `clock_getres` in POSIX. + ;;; Return the resolution of a clock. + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno_t) - ;; The clock for which to return the resolution. + ;;; The clock for which to return the resolution. (param $clock_id $clockid_t) - ;; The resolution of the clock. + ;;; The resolution of the clock. (result $resolution $timestamp_t) ) - ;; Return the time value of a clock. - ;; Note: This is similar to `clock_gettime` in POSIX. + ;;; Return the time value of a clock. + ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") - ;; The clock for which to return the time. + ;;; The clock for which to return the time. (param $clock_id $clockid_t) - ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp_t) (result $error $errno_t) - ;; The time value of the clock. + ;;; The time value of the clock. (result $time $timestamp_t) ) - ;; Provide file advisory information on a file descriptor. - ;; Note: This is similar to `posix_fadvise` in POSIX. + ;;; Provide file advisory information on a file descriptor. + ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") (param $fd $fd_t) - (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. - (param $len $filesize_t) ;; The length of the region to which the advisory applies. - (param $advice $advice_t) ;; The advice. + ;;; The offset within the file to which the advisory applies. + (param $offset $filesize_t) + ;;; The length of the region to which the advisory applies. + (param $len $filesize_t) + ;;; The advice. + (param $advice $advice_t) (result $error $errno_t) ) - ;; Force the allocation of space in a file. - ;; Note: This is similar to `posix_fallocate` in POSIX. + ;;; Force the allocation of space in a file. + ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") (param $fd $fd_t) - ;; The offset at which to start the allocation. + ;;; The offset at which to start the allocation. (param $offset $filesize_t) - ;; The length of the area that is allocated. + ;;; The length of the area that is allocated. (param $len $filesize_t) (result $error $errno_t) ) - ;; Close a file descriptor. - ;; Note: This is similar to `close` in POSIX. + ;;; Close a file descriptor. + ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd_t) (result $error $errno_t) ) - ;; Synchronize the data of a file to disk. - ;; Note: This is similar to `fdatasync` in POSIX. + ;;; Synchronize the data of a file to disk. + ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Get the attributes of a file descriptor. - ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + ;;; Get the attributes of a file descriptor. + ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file descriptor's attributes are stored. + ;;; The buffer where the file descriptor's attributes are stored. (result $stat $fdstat_t) ) - ;; Adjust the flags associated with a file descriptor. - ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + ;;; Adjust the flags associated with a file descriptor. + ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") (param $fd $fd_t) - ;; The desired values of the file descriptor flags. + ;;; The desired values of the file descriptor flags. (param $flags $fdflags_t) (result $error $errno_t) ) - ;; Adjust the rights associated with a file descriptor. - ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; Adjust the rights associated with a file descriptor. + ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd_t) - ;; The desired rights of the file descriptor. + ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights_t) (param $fs_rights_inheriting $rights_t) (result $error $errno_t) ) - ;; Return the attributes of an open file. + ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;; Note: This is similar to `ftruncate` in POSIX. + ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") (param $fd $fd_t) - ;; The desired file size. + ;;; The desired file size. (param $st_size $filesize_t) (result $error $errno_t) ) - ;; Adjust the timestamps of an open file or directory. - ;; Note: This is similar to `futimens` in POSIX. + ;;; Adjust the timestamps of an open file or directory. + ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") (param $fd $fd_t) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `preadv` in POSIX. + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") (param $fd $fd_t) - ;; List of scatter/gather vectors in which to store data. + ;;; List of scatter/gather vectors in which to store data. (param $iovs $iovec_t_array) - ;; The offset within the file at which to read. + ;;; The offset within the file at which to read. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the description is stored. + ;;; The buffer where the description is stored. (result $buf $prestat_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") (param $fd $fd_t) - ;; A buffer into which to write the preopened directory name. + ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size_t) (result $error $errno_t) ) - ;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `pwritev` in POSIX. + ;;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) - ;; The offset within the file at which to write. + ;;; The offset within the file at which to write. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Read from a file descriptor. - ;; Note: This is similar to `readv` in POSIX. + ;;; Read from a file descriptor. + ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_t_array) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Read directory entries from a directory. - ;; When successful, the contents of the output buffer consist of a sequence of - ;; directory entries. Each directory entry consists of a dirent_t object, - ;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;; entry. + ;;; Read directory entries from a directory. + ;;; When successful, the contents of the output buffer consist of a sequence of + ;;; directory entries. Each directory entry consists of a dirent_t object, + ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; entry. ;; - ;; This function fills the output buffer as much as possible, potentially - ;; truncating the last directory entry. This allows the caller to grow its - ;; read buffer size in case it's too small to fit a single large directory - ;; entry, or skip the oversized directory entry. + ;;; This function fills the output buffer as much as possible, potentially + ;;; truncating the last directory entry. This allows the caller to grow its + ;;; read buffer size in case it's too small to fit a single large directory + ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") (param $fd $fd_t) - ;; The buffer where directory entries are stored + ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) (param $buf_len $size_t) - ;; The location within the directory to start reading + ;;; The location within the directory to start reading (param $cookie $dircookie_t) (result $error $errno_t) - ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. (result $bufused $size_t) ) - ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;;; Atomically replace a file descriptor by renumbering another file descriptor. ;; - ;; Due to the strong focus on thread safety, this environment does not provide - ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;; file descriptor with the same number could be allocated by a different - ;; thread at the same time. + ;;; Due to the strong focus on thread safety, this environment does not provide + ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;;; file descriptor with the same number could be allocated by a different + ;;; thread at the same time. ;; - ;; This function provides a way to atomically renumber file descriptors, which - ;; would disappear if `dup2()` were to be removed entirely. + ;;; This function provides a way to atomically renumber file descriptors, which + ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") (param $fd $fd_t) - ;; The file descriptor to overwrite. + ;;; The file descriptor to overwrite. (param $to $fd_t) (result $error $errno_t) ) - ;; Move the offset of a file descriptor. - ;; Note: This is similar to `lseek` in POSIX. + ;;; Move the offset of a file descriptor. + ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") (param $fd $fd_t) - ;; The number of bytes to move. + ;;; The number of bytes to move. (param $offset $filedelta_t) - ;; The base from which the offset is relative. + ;;; The base from which the offset is relative. (param $whence $whence_t) (result $error $errno_t) - ;; The new offset of the file descriptor, relative to the start of the file. + ;;; The new offset of the file descriptor, relative to the start of the file. (result $newoffset $filesize_t) ) - ;; Synchronize the data and metadata of a file to disk. - ;; Note: This is similar to `fsync` in POSIX. + ;;; Synchronize the data and metadata of a file to disk. + ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Return the current offset of a file descriptor. - ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + ;;; Return the current offset of a file descriptor. + ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd_t) (result $error $errno_t) - ;; The current offset of the file descriptor, relative to the start of the file. + ;;; The current offset of the file descriptor, relative to the start of the file. (result $offset $filesize_t) ) - ;; Write to a file descriptor. - ;; Note: This is similar to `writev` in POSIX. + ;;; Write to a file descriptor. + ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Create a directory. - ;; Note: This is similar to `mkdirat` in POSIX. + ;;; Create a directory. + ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") (param $fd $fd_t) - ;; The path at which to create the directory. + ;;; The path at which to create the directory. (param $path string) (result $error $errno_t) ) - ;; Return the attributes of a file or directory. - ;; Note: This is similar to `stat` in POSIX. + ;;; Return the attributes of a file or directory. + ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to inspect. + ;;; The path of the file or directory to inspect. (param $path string) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the timestamps of a file or directory. - ;; Note: This is similar to `utimensat` in POSIX. + ;;; Adjust the timestamps of a file or directory. + ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to operate on. + ;;; The path of the file or directory to operate on. (param $path string) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Create a hard link. - ;; Note: This is similar to `linkat` in POSIX. + ;;; Create a hard link. + ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") (param $old_fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) - ;; The source path from which to link. + ;;; The source path from which to link. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path at which to create the hard link. + ;;; The destination path at which to create the hard link. (param $new_path string) (result $error $errno_t) ) - ;; Open a file or directory. + ;;; Open a file or directory. ;; - ;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;; file descriptor not currently open; it is randomized to prevent - ;; applications from depending on making assumptions about indexes, since this - ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 2**31. + ;;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;;; file descriptor not currently open; it is randomized to prevent + ;;; applications from depending on making assumptions about indexes, since this + ;;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;;; guaranteed to be less than 2**31. ;; - ;; Note: This is similar to `openat` in POSIX. + ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags_t) - ;; The relative path of the file or directory to open, relative to the - ;; `dirfd` directory. + ;;; The relative path of the file or directory to open, relative to the + ;;; `dirfd` directory. (param $path string) - ;; The method by which to open the file. + ;;; The method by which to open the file. (param $o_flags $oflags_t) - ;; The initial rights of the newly created file descriptor. The - ;; implementation is allowed to return a file descriptor with fewer rights - ;; than specified, if and only if those rights do not apply to the type of - ;; file being opened. + ;;; The initial rights of the newly created file descriptor. The + ;;; implementation is allowed to return a file descriptor with fewer rights + ;;; than specified, if and only if those rights do not apply to the type of + ;;; file being opened. ;; - ;; The *base* rights are rights that will apply to operations using the file - ;; descriptor itself, while the *inheriting* rights are rights that apply to - ;; file descriptors derived from it. + ;;; The *base* rights are rights that will apply to operations using the file + ;;; descriptor itself, while the *inheriting* rights are rights that apply to + ;;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) (param $flags $fdflags_t) (result $error $errno_t) - ;; The file descriptor of the file that has been opened. + ;;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) ) - ;; Read the contents of a symbolic link. - ;; Note: This is similar to `readlinkat` in POSIX. + ;;; Read the contents of a symbolic link. + ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") (param $fd $fd_t) - ;; The path of the symbolic link from which to read. + ;;; The path of the symbolic link from which to read. (param $path string) - ;; The buffer to which to write the contents of the symbolic link. + ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) - ;; The number of bytes placed in the buffer. + ;;; The number of bytes placed in the buffer. (result $bufused $size_t) ) - ;; Remove a directory. - ;; Return `ENOTEMPTY` if the directory is not empty. - ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + ;;; Remove a directory. + ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd_t) - ;; The path to a directory to remove. + ;;; The path to a directory to remove. (param $path string) (result $error $errno_t) ) - ;; Rename a file or directory. - ;; Note: This is similar to `renameat` in POSIX. + ;;; Rename a file or directory. + ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") (param $fd $fd_t) - ;; The source path of the file or directory to rename. + ;;; The source path of the file or directory to rename. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path to which to rename the file or directory. + ;;; The destination path to which to rename the file or directory. (param $new_path string) (result $error $errno_t) ) - ;; Create a symbolic link. - ;; Note: This is similar to `symlinkat` in POSIX. + ;;; Create a symbolic link. + ;;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - ;; The contents of the symbolic link. + ;;; The contents of the symbolic link. (param $old_path string) (param $fd $fd_t) - ;; The destination path at which to create the symbolic link. + ;;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) ) - ;; Unlink a file. - ;; Return `EISDIR` if the path refers to a directory. - ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + ;;; Unlink a file. + ;;; Return `EISDIR` if the path refers to a directory. + ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd_t) - ;; The path to a file to unlink. + ;;; The path to a file to unlink. (param $path string) (result $error $errno_t) ) - ;; Concurrently poll for the occurrence of a set of events. + ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") - ;; The events to which to subscribe. + ;;; The events to which to subscribe. (param $in (@witx const_pointer $subscription_t)) - ;; The events that have occurred. + ;;; The events that have occurred. (param $out (@witx pointer $event_t)) - ;; Both the number of subscriptions and events. + ;;; Both the number of subscriptions and events. (param $nsubscriptions $size_t) (result $error $errno_t) - ;; The number of events stored. + ;;; The number of events stored. (result $nevents $size_t) ) - ;; Terminate the process normally. An exit code of 0 indicates successful - ;; termination of the program. The meanings of other values is dependent on - ;; the environment. + ;;; Terminate the process normally. An exit code of 0 indicates successful + ;;; termination of the program. The meanings of other values is dependent on + ;;; the environment. (@interface func (export "proc_exit") - ;; The exit code returned by the process. + ;;; The exit code returned by the process. (param $rval $exitcode_t) ) - ;; Send a signal to the process of the calling thread. - ;; Note: This is similar to `raise` in POSIX. + ;;; Send a signal to the process of the calling thread. + ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") - ;; The signal condition to trigger. + ;;; The signal condition to trigger. (param $sig $signal_t) (result $error $errno_t) ) - ;; Temporarily yield execution of the calling thread. - ;; Note: This is similar to `sched_yield` in POSIX. + ;;; Temporarily yield execution of the calling thread. + ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") (result $error $errno_t) ) - ;; Write high-quality random data into a buffer. - ;; This function blocks when the implementation is unable to immediately - ;; provide sufficient high-quality random data. - ;; This function may execute slowly, so when large mounts of random data are - ;; required, it's advisable to use this function to seed a pseudo-random - ;; number generator, rather than to provide the random data directly. + ;;; Write high-quality random data into a buffer. + ;;; This function blocks when the implementation is unable to immediately + ;;; provide sufficient high-quality random data. + ;;; This function may execute slowly, so when large mounts of random data are + ;;; required, it's advisable to use this function to seed a pseudo-random + ;;; number generator, rather than to provide the random data directly. (@interface func (export "random_get") - ;; The buffer to fill with random data. + ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) ) - ;; Receive a message from a socket. - ;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;; the data into multiple buffers in the manner of `readv`. + ;;; Receive a message from a socket. + ;;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $ri_data $iovec_t_array) - ;; Message flags. + ;;; Message flags. (param $ri_flags $riflags_t) (result $error $errno_t) - ;; Number of bytes stored in ri_data. + ;;; Number of bytes stored in ri_data. (result $ro_datalen $size_t) - ;; Message flags. + ;;; Message flags. (result $ro_flags $roflags_t) ) - ;; Send a message on a socket. - ;; Note: This is similar to `send` in POSIX, though it also supports writing - ;; the data from multiple buffers in the manner of `writev`. + ;;; Send a message on a socket. + ;;; Note: This is similar to `send` in POSIX, though it also supports writing + ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to retrieve data + ;;; List of scatter/gather vectors to which to retrieve data (param $si_data $ciovec_t_array) - ;; Message flags. + ;;; Message flags. (param $si_flags $siflags_t) (result $error $errno_t) - ;; Number of bytes transmitted. + ;;; Number of bytes transmitted. (result $so_datalen $size_t) ) - ;; Shut down socket send and receive channels. - ;; Note: This is similar to `shutdown` in POSIX. + ;;; Shut down socket send and receive channels. + ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") (param $fd $fd_t) - ;; Which channels on the socket to shut down. + ;;; Which channels on the socket to shut down. (param $how $sdflags_t) (result $error $errno_t) ) diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx index 15b53af51..cf39a2deb 100644 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/random/phases/old/snapshot_0/witx/typenames.witx @@ -7,291 +7,291 @@ (typename $size_t u32) -;; Non-negative file size or length of a region within a file. +;;; Non-negative file size or length of a region within a file. (typename $filesize_t u64) -;; Timestamp in nanoseconds. +;;; Timestamp in nanoseconds. (typename $timestamp_t u64) -;; Identifiers for clocks. +;;; Identifiers for clocks. (typename $clockid_t (enum u32 - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. + ;;; The clock measuring real time. Time value zero corresponds with + ;;; 1970-01-01T00:00:00Z. $CLOCK_REALTIME - ;; The store-wide monotonic clock, which is defined as a clock measuring - ;; real time, whose value cannot be adjusted and which cannot have negative - ;; clock jumps. The epoch of this clock is undefined. The absolute time - ;; value of this clock therefore has no meaning. + ;;; The store-wide monotonic clock, which is defined as a clock measuring + ;;; real time, whose value cannot be adjusted and which cannot have negative + ;;; clock jumps. The epoch of this clock is undefined. The absolute time + ;;; value of this clock therefore has no meaning. $CLOCK_MONOTONIC - ;; The CPU-time clock associated with the current process. + ;;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The CPU-time clock associated with the current thread. + ;;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) ) -;; Error codes returned by functions. -;; Not all of these error codes are returned by the functions provided by this -;; API; some are used in higher-level library layers, and others are provided -;; merely for alignment with POSIX. +;;; Error codes returned by functions. +;;; Not all of these error codes are returned by the functions provided by this +;;; API; some are used in higher-level library layers, and others are provided +;;; merely for alignment with POSIX. (typename $errno_t (enum u16 - ;; No error occurred. System call completed successfully. + ;;; No error occurred. System call completed successfully. $ESUCCESS - ;; Argument list too long. + ;;; Argument list too long. $E2BIG - ;; Permission denied. + ;;; Permission denied. $EACCES - ;; Address in use. + ;;; Address in use. $EADDRINUSE - ;; Address not available. + ;;; Address not available. $EADDRNOTAVAIL - ;; Address family not supported. + ;;; Address family not supported. $EAFNOSUPPORT - ;; Resource unavailable, or operation would block. + ;;; Resource unavailable, or operation would block. $EAGAIN - ;; Connection already in progress. + ;;; Connection already in progress. $EALREADY - ;; Bad file descriptor. + ;;; Bad file descriptor. $EBADF - ;; Bad message. + ;;; Bad message. $EBADMSG - ;; Device or resource busy. + ;;; Device or resource busy. $EBUSY - ;; Operation canceled. + ;;; Operation canceled. $ECANCELED - ;; No child processes. + ;;; No child processes. $ECHILD - ;; Connection aborted. + ;;; Connection aborted. $ECONNABORTED - ;; Connection refused. + ;;; Connection refused. $ECONNREFUSED - ;; Connection reset. + ;;; Connection reset. $ECONNRESET - ;; Resource deadlock would occur. + ;;; Resource deadlock would occur. $EDEADLK - ;; Destination address required. + ;;; Destination address required. $EDESTADDRREQ - ;; Mathematics argument out of domain of function. + ;;; Mathematics argument out of domain of function. $EDOM - ;; Reserved. + ;;; Reserved. $EDQUOT - ;; File exists. + ;;; File exists. $EEXIST - ;; Bad address. + ;;; Bad address. $EFAULT - ;; File too large. + ;;; File too large. $EFBIG - ;; Host is unreachable. + ;;; Host is unreachable. $EHOSTUNREACH - ;; Identifier removed. + ;;; Identifier removed. $EIDRM - ;; Illegal byte sequence. + ;;; Illegal byte sequence. $EILSEQ - ;; Operation in progress. + ;;; Operation in progress. $EINPROGRESS - ;; Interrupted function. + ;;; Interrupted function. $EINTR - ;; Invalid argument. + ;;; Invalid argument. $EINVAL - ;; I/O error. + ;;; I/O error. $EIO - ;; Socket is connected. + ;;; Socket is connected. $EISCONN - ;; Is a directory. + ;;; Is a directory. $EISDIR - ;; Too many levels of symbolic links. + ;;; Too many levels of symbolic links. $ELOOP - ;; File descriptor value too large. + ;;; File descriptor value too large. $EMFILE - ;; Too many links. + ;;; Too many links. $EMLINK - ;; Message too large. + ;;; Message too large. $EMSGSIZE - ;; Reserved. + ;;; Reserved. $EMULTIHOP - ;; Filename too long. + ;;; Filename too long. $ENAMETOOLONG - ;; Network is down. + ;;; Network is down. $ENETDOWN - ;; Connection aborted by network. + ;;; Connection aborted by network. $ENETRESET - ;; Network unreachable. + ;;; Network unreachable. $ENETUNREACH - ;; Too many files open in system. + ;;; Too many files open in system. $ENFILE - ;; No buffer space available. + ;;; No buffer space available. $ENOBUFS - ;; No such device. + ;;; No such device. $ENODEV - ;; No such file or directory. + ;;; No such file or directory. $ENOENT - ;; Executable file format error. + ;;; Executable file format error. $ENOEXEC - ;; No locks available. + ;;; No locks available. $ENOLCK - ;; Reserved. + ;;; Reserved. $ENOLINK - ;; Not enough space. + ;;; Not enough space. $ENOMEM - ;; No message of the desired type. + ;;; No message of the desired type. $ENOMSG - ;; Protocol not available. + ;;; Protocol not available. $ENOPROTOOPT - ;; No space left on device. + ;;; No space left on device. $ENOSPC - ;; Function not supported. + ;;; Function not supported. $ENOSYS - ;; The socket is not connected. + ;;; The socket is not connected. $ENOTCONN - ;; Not a directory or a symbolic link to a directory. + ;;; Not a directory or a symbolic link to a directory. $ENOTDIR - ;; Directory not empty. + ;;; Directory not empty. $ENOTEMPTY - ;; State not recoverable. + ;;; State not recoverable. $ENOTRECOVERABLE - ;; Not a socket. + ;;; Not a socket. $ENOTSOCK - ;; Not supported, or operation not supported on socket. + ;;; Not supported, or operation not supported on socket. $ENOTSUP - ;; Inappropriate I/O control operation. + ;;; Inappropriate I/O control operation. $ENOTTY - ;; No such device or address. + ;;; No such device or address. $ENXIO - ;; Value too large to be stored in data type. + ;;; Value too large to be stored in data type. $EOVERFLOW - ;; Previous owner died. + ;;; Previous owner died. $EOWNERDEAD - ;; Operation not permitted. + ;;; Operation not permitted. $EPERM - ;; Broken pipe. + ;;; Broken pipe. $EPIPE - ;; Protocol error. + ;;; Protocol error. $EPROTO - ;; Protocol not supported. + ;;; Protocol not supported. $EPROTONOSUPPORT - ;; Protocol wrong type for socket. + ;;; Protocol wrong type for socket. $EPROTOTYPE - ;; Result too large. + ;;; Result too large. $ERANGE - ;; Read-only file system. + ;;; Read-only file system. $EROFS - ;; Invalid seek. + ;;; Invalid seek. $ESPIPE - ;; No such process. + ;;; No such process. $ESRCH - ;; Reserved. + ;;; Reserved. $ESTALE - ;; Connection timed out. + ;;; Connection timed out. $ETIMEDOUT - ;; Text file busy. + ;;; Text file busy. $ETXTBSY - ;; Cross-device link. + ;;; Cross-device link. $EXDEV - ;; Extension: Capabilities insufficient. + ;;; Extension: Capabilities insufficient. $ENOTCAPABLE ) ) -;; File descriptor rights, determining which actions may be performed. +;;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke `fd_datasync`. + ;;; The right to invoke `fd_datasync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_DSYNC`. $RIGHT_FD_DATASYNC - ;; The right to invoke `fd_read` and `sock_recv`. + ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. $RIGHT_FD_READ - ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. $RIGHT_FD_SEEK - ;; The right to invoke `fd_fdstat_set_flags`. + ;;; The right to invoke `fd_fdstat_set_flags`. $RIGHT_FD_FDSTAT_SET_FLAGS - ;; The right to invoke `fd_sync`. + ;;; The right to invoke `fd_sync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. $RIGHT_FD_SYNC - ;; The right to invoke `fd_seek` in such a way that the file offset - ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to - ;; invoke `fd_tell`. + ;;; The right to invoke `fd_seek` in such a way that the file offset + ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; invoke `fd_tell`. $RIGHT_FD_TELL - ;; The right to invoke `fd_write` and `sock_send`. - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + ;;; The right to invoke `fd_write` and `sock_send`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. $RIGHT_FD_WRITE - ;; The right to invoke `fd_advise`. + ;;; The right to invoke `fd_advise`. $RIGHT_FD_ADVISE - ;; The right to invoke `fd_allocate`. + ;;; The right to invoke `fd_allocate`. $RIGHT_FD_ALLOCATE - ;; The right to invoke `path_create_directory`. + ;;; The right to invoke `path_create_directory`. $RIGHT_PATH_CREATE_DIRECTORY - ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. $RIGHT_PATH_CREATE_FILE - ;; The right to invoke `path_link` with the file descriptor as the - ;; source directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; source directory. $RIGHT_PATH_LINK_SOURCE - ;; The right to invoke `path_link` with the file descriptor as the - ;; target directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; target directory. $RIGHT_PATH_LINK_TARGET - ;; The right to invoke `path_open`. + ;;; The right to invoke `path_open`. $RIGHT_PATH_OPEN - ;; The right to invoke `fd_readdir`. + ;;; The right to invoke `fd_readdir`. $RIGHT_FD_READDIR - ;; The right to invoke `path_readlink`. + ;;; The right to invoke `path_readlink`. $RIGHT_PATH_READLINK - ;; The right to invoke `path_rename` with the file descriptor as the source directory. + ;;; The right to invoke `path_rename` with the file descriptor as the source directory. $RIGHT_PATH_RENAME_SOURCE - ;; The right to invoke `path_rename` with the file descriptor as the target directory. + ;;; The right to invoke `path_rename` with the file descriptor as the target directory. $RIGHT_PATH_RENAME_TARGET - ;; The right to invoke `path_filestat_get`. + ;;; The right to invoke `path_filestat_get`. $RIGHT_PATH_FILESTAT_GET - ;; The right to change a file's size (there is no `path_filestat_set_size`). - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + ;;; The right to change a file's size (there is no `path_filestat_set_size`). + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. $RIGHT_PATH_FILESTAT_SET_SIZE - ;; The right to invoke `path_filestat_set_times`. + ;;; The right to invoke `path_filestat_set_times`. $RIGHT_PATH_FILESTAT_SET_TIMES - ;; The right to invoke `fd_filestat_get`. + ;;; The right to invoke `fd_filestat_get`. $RIGHT_FD_FILESTAT_GET - ;; The right to invoke `fd_filestat_set_size`. + ;;; The right to invoke `fd_filestat_set_size`. $RIGHT_FD_FILESTAT_SET_SIZE - ;; The right to invoke `fd_filestat_set_times`. + ;;; The right to invoke `fd_filestat_set_times`. $RIGHT_FD_FILESTAT_SET_TIMES - ;; The right to invoke `path_symlink`. + ;;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_remove_directory`. + ;;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY - ;; The right to invoke `path_unlink_file`. + ;;; The right to invoke `path_unlink_file`. $RIGHT_PATH_UNLINK_FILE - ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE - ;; The right to invoke `sock_shutdown`. + ;;; The right to invoke `sock_shutdown`. $RIGHT_SOCK_SHUTDOWN ) ) -;; A file descriptor index. +;;; A file descriptor index. (typename $fd_t u32) -;; A region of memory for scatter/gather reads. +;;; A region of memory for scatter/gather reads. (typename $iovec_t (struct - ;; The address of the buffer to be filled. + ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) - ;; The length of the buffer to be filled. + ;;; The length of the buffer to be filled. (field $buf_len $size_t) ) ) -;; A region of memory for scatter/gather writes. +;;; A region of memory for scatter/gather writes. (typename $ciovec_t (struct - ;; The address of the buffer to be written. + ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) - ;; The length of the buffer to be written. + ;;; The length of the buffer to be written. (field $buf_len $size_t) ) ) @@ -299,469 +299,469 @@ (typename $iovec_t_array (array $iovec_t)) (typename $ciovec_t_array (array $ciovec_t)) -;; Relative offset within a file. +;;; Relative offset within a file. (typename $filedelta_t s64) -;; The position relative to which to set the offset of the file descriptor. +;;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 - ;; Seek relative to current position. + ;;; Seek relative to current position. $WHENCE_CUR - ;; Seek relative to end-of-file. + ;;; Seek relative to end-of-file. $WHENCE_END - ;; Seek relative to start-of-file. + ;;; Seek relative to start-of-file. $WHENCE_SET ) ) -;; A reference to the offset of a directory entry. +;;; A reference to the offset of a directory entry. (typename $dircookie_t u64) -;; The type for the $d_namlen field of $dirent_t. +;;; The type for the $d_namlen field of $dirent_t. (typename $dirnamlen_t u32) -;; File serial number that is unique within its file system. +;;; File serial number that is unique within its file system. (typename $inode_t u64) -;; The type of a file descriptor or file. +;;; The type of a file descriptor or file. (typename $filetype_t (enum u8 - ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $FILETYPE_UNKNOWN - ;; The file descriptor or file refers to a block device inode. + ;;; The file descriptor or file refers to a block device inode. $FILETYPE_BLOCK_DEVICE - ;; The file descriptor or file refers to a character device inode. + ;;; The file descriptor or file refers to a character device inode. $FILETYPE_CHARACTER_DEVICE - ;; The file descriptor or file refers to a directory inode. + ;;; The file descriptor or file refers to a directory inode. $FILETYPE_DIRECTORY - ;; The file descriptor or file refers to a regular file inode. + ;;; The file descriptor or file refers to a regular file inode. $FILETYPE_REGULAR_FILE - ;; The file descriptor or file refers to a datagram socket. + ;;; The file descriptor or file refers to a datagram socket. $FILETYPE_SOCKET_DGRAM - ;; The file descriptor or file refers to a byte-stream socket. + ;;; The file descriptor or file refers to a byte-stream socket. $FILETYPE_SOCKET_STREAM - ;; The file refers to a symbolic link inode. + ;;; The file refers to a symbolic link inode. $FILETYPE_SYMBOLIC_LINK ) ) -;; A directory entry. +;;; A directory entry. (typename $dirent_t (struct - ;; The offset of the next directory entry stored in this directory. + ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie_t) - ;; The serial number of the file referred to by this directory entry. + ;;; The serial number of the file referred to by this directory entry. (field $d_ino $inode_t) - ;; The length of the name of the directory entry. + ;;; The length of the name of the directory entry. (field $d_namlen $dirnamlen_t) - ;; The type of the file referred to by this directory entry. + ;;; The type of the file referred to by this directory entry. (field $d_type $filetype_t) ) ) -;; File or memory access pattern advisory information. +;;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application has no advice to give on its behavior with respect to the specified data. + ;;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL - ;; The application expects to access the specified data in a random order. + ;;; The application expects to access the specified data in a random order. $ADVICE_RANDOM - ;; The application expects to access the specified data in the near future. + ;;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED - ;; The application expects that it will not access the specified data in the near future. + ;;; The application expects that it will not access the specified data in the near future. $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. + ;;; The application expects to access the specified data once and then not reuse it thereafter. $ADVICE_NOREUSE ) ) -;; File descriptor flags. +;;; File descriptor flags. (typename $fdflags_t (flags u16 - ;; Append mode: Data written to the file is always appended to the file's end. + ;;; Append mode: Data written to the file is always appended to the file's end. $FDFLAG_APPEND - ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. $FDFLAG_DSYNC - ;; Non-blocking mode. + ;;; Non-blocking mode. $FDFLAG_NONBLOCK - ;; Synchronized read I/O operations. + ;;; Synchronized read I/O operations. $FDFLAG_RSYNC - ;; Write according to synchronized I/O file integrity completion. In - ;; addition to synchronizing the data stored in the file, the implementation - ;; may also synchronously update the file's metadata. + ;;; Write according to synchronized I/O file integrity completion. In + ;;; addition to synchronizing the data stored in the file, the implementation + ;;; may also synchronously update the file's metadata. $FDFLAG_SYNC ) ) -;; File descriptor attributes. +;;; File descriptor attributes. (typename $fdstat_t (struct - ;; File type. + ;;; File type. (field $fs_filetype $filetype_t) - ;; File descriptor flags. + ;;; File descriptor flags. (field $fs_flags $fdflags_t) - ;; Rights that apply to this file descriptor. + ;;; Rights that apply to this file descriptor. (field $fs_rights_base $rights_t) - ;; Maximum set of rights that may be installed on new file descriptors that - ;; are created through this file descriptor, e.g., through `path_open`. + ;;; Maximum set of rights that may be installed on new file descriptors that + ;;; are created through this file descriptor, e.g., through `path_open`. (field $fs_rights_inheriting $rights_t) ) ) -;; Identifier for a device containing a file system. Can be used in combination -;; with `inode_t` to uniquely identify a file or directory in the filesystem. +;;; Identifier for a device containing a file system. Can be used in combination +;;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) -;; Which file time attributes to adjust. +;;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 - ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. $FILESTAT_SET_ATIM - ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_ATIM_NOW - ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. $FILESTAT_SET_MTIM - ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_MTIM_NOW ) ) -;; Flags determining the method of how paths are resolved. +;;; Flags determining the method of how paths are resolved. (typename $lookupflags_t (flags u32 - ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $LOOKUP_SYMLINK_FOLLOW ) ) -;; Open flags used by `path_open`. +;;; Open flags used by `path_open`. (typename $oflags_t (flags u16 - ;; Create file if it does not exist. + ;;; Create file if it does not exist. $O_CREAT - ;; Fail if not a directory. + ;;; Fail if not a directory. $O_DIRECTORY - ;; Fail if file already exists. + ;;; Fail if file already exists. $O_EXCL - ;; Truncate file to size 0. + ;;; Truncate file to size 0. $O_TRUNC ) ) -;; Number of hard links to an inode. +;;; Number of hard links to an inode. (typename $linkcount_t u32) -;; File attributes. +;;; File attributes. (typename $filestat_t (struct - ;; Device ID of device containing the file. + ;;; Device ID of device containing the file. (field $st_dev $device_t) - ;; File serial number. + ;;; File serial number. (field $st_ino $inode_t) - ;; File type. + ;;; File type. (field $st_filetype $filetype_t) - ;; Number of hard links to the file. + ;;; Number of hard links to the file. (field $st_nlink $linkcount_t) - ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. (field $st_size $filesize_t) - ;; Last data access timestamp. + ;;; Last data access timestamp. (field $st_atim $timestamp_t) - ;; Last data modification timestamp. + ;;; Last data modification timestamp. (field $st_mtim $timestamp_t) - ;; Last file status change timestamp. + ;;; Last file status change timestamp. (field $st_ctim $timestamp_t) ) ) -;; User-provided value that may be attached to objects that is retained when -;; extracted from the implementation. +;;; User-provided value that may be attached to objects that is retained when +;;; extracted from the implementation. (typename $userdata_t u64) -;; Type of a subscription to an event or its occurrence. +;;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (enum u8 - ;; The time value of clock `subscription_t::u.clock.clock_id` has - ;; reached timestamp `subscription_t::u.clock.timeout`. + ;;; The time value of clock `subscription_t::u.clock.clock_id` has + ;;; reached timestamp `subscription_t::u.clock.timeout`. $EVENTTYPE_CLOCK - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data - ;; available for reading. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; available for reading. This event always triggers for regular files. $EVENTTYPE_FD_READ - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity - ;; available for writing. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;;; available for writing. This event always triggers for regular files. $EVENTTYPE_FD_WRITE ) ) -;; The state of the file descriptor subscribed to with -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The state of the file descriptor subscribed to with +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 - ;; The peer of this socket has closed or disconnected. + ;;; The peer of this socket has closed or disconnected. $EVENT_FD_READWRITE_HANGUP ) ) -;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;; `EVENTTYPE_FD_WRITE`. +;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;;; `EVENTTYPE_FD_WRITE`. (typename $event_fd_readwrite_t (struct - ;; The number of bytes available for reading or writing. + ;;; The number of bytes available for reading or writing. (field $nbytes $filesize_t) - ;; The state of the file descriptor. + ;;; The state of the file descriptor. (field $flags $eventrwflags_t) ) ) -;; The contents of an $event_t. +;;; The contents of an $event_t. (typename $event_u (union - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; An event that occurred. +;;; An event that occurred. (typename $event_t (struct - ;; User-provided value that got attached to `subscription_t::userdata`. + ;;; User-provided value that got attached to `subscription_t::userdata`. (field $userdata $userdata_t) - ;; If non-zero, an error that occurred while processing the subscription request. + ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno_t) - ;; The type of the event that occurred. + ;;; The type of the event that occurred. (field $type $eventtype_t) - ;; The contents of the event. + ;;; The contents of the event. (field $u $event_u) ) ) -;; Flags determining how to interpret the timestamp provided in -;; `subscription_t::u.clock.timeout.` +;;; Flags determining how to interpret the timestamp provided in +;;; `subscription_t::u.clock.timeout.` (typename $subclockflags_t (flags u16 - ;; If set, treat the timestamp provided in - ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;; provided in `subscription_t::u.clock.timeout` relative to the - ;; current time value of clock `subscription_t::u.clock.clock_id.` + ;;; If set, treat the timestamp provided in + ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription_t::u.clock.timeout` relative to the + ;;; current time value of clock `subscription_t::u.clock.clock_id.` $SUBSCRIPTION_CLOCK_ABSTIME ) ) -;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The user-defined unique identifier of the clock. + ;;; The user-defined unique identifier of the clock. (field $identifier $userdata_t) - ;; The clock against which to compare the timestamp. + ;;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. + ;;; The absolute or relative timestamp. (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. + ;;; The amount of time that the implementation may wait additionally + ;;; to coalesce with other events. (field $precision $timestamp_t) - ;; Flags specifying whether the timeout is absolute or relative + ;;; Flags specifying whether the timeout is absolute or relative (field $flags $subclockflags_t) ) ) -;; The contents of a $subscription_t when type is type is -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The contents of a $subscription_t when type is type is +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $subscription_fd_readwrite_t (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. + ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd_t) ) ) -;; The contents of a $subscription_t. +;;; The contents of a $subscription_t. (typename $subscription_u (union - ;; When type is `EVENTTYPE_CLOCK`: + ;;; When type is `EVENTTYPE_CLOCK`: (field $clock $subscription_clock_t) - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $subscription_fd_readwrite_t) ) ) -;; Subscription to an event. +;;; Subscription to an event. (typename $subscription_t (struct - ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through `event_t::userdata`. + ;;; User-provided value that is attached to the subscription in the + ;;; implementation and returned through `event_t::userdata`. (field $userdata $userdata_t) - ;; The type of the event to which to subscribe. + ;;; The type of the event to which to subscribe. (field $type $eventtype_t) - ;; The contents of the subscription. + ;;; The contents of the subscription. (field $u $subscription_u) ) ) -;; Exit code generated by a process when exiting. +;;; Exit code generated by a process when exiting. (typename $exitcode_t u32) -;; Signal condition. +;;; Signal condition. (typename $signal_t (enum u8 - ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;; so this value is reserved. + ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;;; so this value is reserved. $SIGNONE - ;; Hangup. - ;; Action: Terminates the process. + ;;; Hangup. + ;;; Action: Terminates the process. $SIGHUP - ;; Terminate interrupt signal. - ;; Action: Terminates the process. + ;;; Terminate interrupt signal. + ;;; Action: Terminates the process. $SIGINT - ;; Terminal quit signal. - ;; Action: Terminates the process. + ;;; Terminal quit signal. + ;;; Action: Terminates the process. $SIGQUIT - ;; Illegal instruction. - ;; Action: Terminates the process. + ;;; Illegal instruction. + ;;; Action: Terminates the process. $SIGILL - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. + ;;; Trace/breakpoint trap. + ;;; Action: Terminates the process. $SIGTRAP - ;; Process abort signal. - ;; Action: Terminates the process. + ;;; Process abort signal. + ;;; Action: Terminates the process. $SIGABRT - ;; Access to an undefined portion of a memory object. - ;; Action: Terminates the process. + ;;; Access to an undefined portion of a memory object. + ;;; Action: Terminates the process. $SIGBUS - ;; Erroneous arithmetic operation. - ;; Action: Terminates the process. + ;;; Erroneous arithmetic operation. + ;;; Action: Terminates the process. $SIGFPE - ;; Kill. - ;; Action: Terminates the process. + ;;; Kill. + ;;; Action: Terminates the process. $SIGKILL - ;; User-defined signal 1. - ;; Action: Terminates the process. + ;;; User-defined signal 1. + ;;; Action: Terminates the process. $SIGUSR1 - ;; Invalid memory reference. - ;; Action: Terminates the process. + ;;; Invalid memory reference. + ;;; Action: Terminates the process. $SIGSEGV - ;; User-defined signal 2. - ;; Action: Terminates the process. + ;;; User-defined signal 2. + ;;; Action: Terminates the process. $SIGUSR2 - ;; Write on a pipe with no one to read it. - ;; Action: Ignored. + ;;; Write on a pipe with no one to read it. + ;;; Action: Ignored. $SIGPIPE - ;; Alarm clock. - ;; Action: Terminates the process. + ;;; Alarm clock. + ;;; Action: Terminates the process. $SIGALRM - ;; Termination signal. - ;; Action: Terminates the process. + ;;; Termination signal. + ;;; Action: Terminates the process. $SIGTERM - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. + ;;; Child process terminated, stopped, or continued. + ;;; Action: Ignored. $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. + ;;; Continue executing, if stopped. + ;;; Action: Continues executing, if stopped. $SIGCONT - ;; Stop executing. - ;; Action: Stops executing. + ;;; Stop executing. + ;;; Action: Stops executing. $SIGSTOP - ;; Terminal stop signal. - ;; Action: Stops executing. + ;;; Terminal stop signal. + ;;; Action: Stops executing. $SIGTSTP - ;; Background process attempting read. - ;; Action: Stops executing. + ;;; Background process attempting read. + ;;; Action: Stops executing. $SIGTTIN - ;; Background process attempting write. - ;; Action: Stops executing. + ;;; Background process attempting write. + ;;; Action: Stops executing. $SIGTTOU - ;; High bandwidth data is available at a socket. - ;; Action: Ignored. + ;;; High bandwidth data is available at a socket. + ;;; Action: Ignored. $SIGURG - ;; CPU time limit exceeded. - ;; Action: Terminates the process. + ;;; CPU time limit exceeded. + ;;; Action: Terminates the process. $SIGXCPU - ;; File size limit exceeded. - ;; Action: Terminates the process. + ;;; File size limit exceeded. + ;;; Action: Terminates the process. $SIGXFSZ - ;; Virtual timer expired. - ;; Action: Terminates the process. + ;;; Virtual timer expired. + ;;; Action: Terminates the process. $SIGVTALRM - ;; Profiling timer expired. - ;; Action: Terminates the process. + ;;; Profiling timer expired. + ;;; Action: Terminates the process. $SIGPROF - ;; Window changed. - ;; Action: Ignored. + ;;; Window changed. + ;;; Action: Ignored. $SIGWINCH - ;; I/O possible. - ;; Action: Terminates the process. + ;;; I/O possible. + ;;; Action: Terminates the process. $SIGPOLL - ;; Power failure. - ;; Action: Terminates the process. + ;;; Power failure. + ;;; Action: Terminates the process. $SIGPWR - ;; Bad system call. - ;; Action: Terminates the process. + ;;; Bad system call. + ;;; Action: Terminates the process. $SIGSYS ) ) -;; Flags provided to `sock_recv`. +;;; Flags provided to `sock_recv`. (typename $riflags_t (flags u16 - ;; Returns the message without removing it from the socket's receive queue. + ;;; Returns the message without removing it from the socket's receive queue. $SOCK_RECV_PEEK - ;; On byte-stream sockets, block until the full amount of data can be returned. + ;;; On byte-stream sockets, block until the full amount of data can be returned. $SOCK_RECV_WAITALL ) ) -;; Flags returned by `sock_recv`. +;;; Flags returned by `sock_recv`. (typename $roflags_t (flags u16 - ;; Returned by `sock_recv`: Message data has been truncated. + ;;; Returned by `sock_recv`: Message data has been truncated. $SOCK_RECV_DATA_TRUNCATED ) ) -;; Flags provided to `sock_send`. As there are currently no flags -;; defined, it must be set to zero. +;;; Flags provided to `sock_send`. As there are currently no flags +;;; defined, it must be set to zero. (typename $siflags_t u16) -;; Which channels on a socket to shut down. +;;; Which channels on a socket to shut down. (typename $sdflags_t (flags u8 - ;; Disables further receive operations. + ;;; Disables further receive operations. $SHUT_RD - ;; Disables further send operations. + ;;; Disables further send operations. $SHUT_WR ) ) -;; Identifiers for preopened capabilities. +;;; Identifiers for preopened capabilities. (typename $preopentype_t (enum u8 - ;; A pre-opened directory. + ;;; A pre-opened directory. $PREOPENTYPE_DIR ) ) -;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. (typename $prestat_dir (struct - ;; The length of the directory name for use with `fd_prestat_dir_name`. + ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size_t) ) ) -;; The contents of an $prestat_t. +;;; The contents of an $prestat_t. (typename $prestat_u (union - ;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `PREOPENTYPE_DIR`: (field $dir $prestat_dir) ) ) -;; Information about a pre-opened capability. +;;; Information about a pre-opened capability. (typename $prestat_t (struct - ;; The type of the pre-opened capability. + ;;; The type of the pre-opened capability. (field $pr_type $preopentype_t) - ;; The contents of the information. + ;;; The contents of the information. (field $u $prestat_u) ) ) diff --git a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx index 74bce70c6..4cf5f4ffa 100644 --- a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -8,523 +8,526 @@ (use "typenames.witx") -;; This API predated the convention of naming modules with a `wasi_unstable_` -;; prefix and a version number. It is preserved here for compatibility, but -;; we shouldn't follow this pattern in new APIs. +;;; This API predated the convention of naming modules with a `wasi_unstable_` +;;; prefix and a version number. It is preserved here for compatibility, but +;;; we shouldn't follow this pattern in new APIs. (module $wasi_unstable - ;; Linear memory to be accessed by WASI functions that need it. + ;;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) - ;; Read command-line argument data. - ;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; Read command-line argument data. + ;;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Read environment variable data. - ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; Read environment variable data. + ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Return the resolution of a clock. - ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;; Note: This is similar to `clock_getres` in POSIX. + ;;; Return the resolution of a clock. + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno_t) - ;; The clock for which to return the resolution. + ;;; The clock for which to return the resolution. (param $clock_id $clockid_t) - ;; The resolution of the clock. + ;;; The resolution of the clock. (result $resolution $timestamp_t) ) - ;; Return the time value of a clock. - ;; Note: This is similar to `clock_gettime` in POSIX. + ;;; Return the time value of a clock. + ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") - ;; The clock for which to return the time. + ;;; The clock for which to return the time. (param $clock_id $clockid_t) - ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp_t) (result $error $errno_t) - ;; The time value of the clock. + ;;; The time value of the clock. (result $time $timestamp_t) ) - ;; Provide file advisory information on a file descriptor. - ;; Note: This is similar to `posix_fadvise` in POSIX. + ;;; Provide file advisory information on a file descriptor. + ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") (param $fd $fd_t) - (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. - (param $len $filesize_t) ;; The length of the region to which the advisory applies. - (param $advice $advice_t) ;; The advice. + ;;; The offset within the file to which the advisory applies. + (param $offset $filesize_t) + ;;; The length of the region to which the advisory applies. + (param $len $filesize_t) + ;;; The advice. + (param $advice $advice_t) (result $error $errno_t) ) - ;; Force the allocation of space in a file. - ;; Note: This is similar to `posix_fallocate` in POSIX. + ;;; Force the allocation of space in a file. + ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") (param $fd $fd_t) - ;; The offset at which to start the allocation. + ;;; The offset at which to start the allocation. (param $offset $filesize_t) - ;; The length of the area that is allocated. + ;;; The length of the area that is allocated. (param $len $filesize_t) (result $error $errno_t) ) - ;; Close a file descriptor. - ;; Note: This is similar to `close` in POSIX. + ;;; Close a file descriptor. + ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd_t) (result $error $errno_t) ) - ;; Synchronize the data of a file to disk. - ;; Note: This is similar to `fdatasync` in POSIX. + ;;; Synchronize the data of a file to disk. + ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Get the attributes of a file descriptor. - ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + ;;; Get the attributes of a file descriptor. + ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file descriptor's attributes are stored. + ;;; The buffer where the file descriptor's attributes are stored. (result $stat $fdstat_t) ) - ;; Adjust the flags associated with a file descriptor. - ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + ;;; Adjust the flags associated with a file descriptor. + ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") (param $fd $fd_t) - ;; The desired values of the file descriptor flags. + ;;; The desired values of the file descriptor flags. (param $flags $fdflags_t) (result $error $errno_t) ) - ;; Adjust the rights associated with a file descriptor. - ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; Adjust the rights associated with a file descriptor. + ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd_t) - ;; The desired rights of the file descriptor. + ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights_t) (param $fs_rights_inheriting $rights_t) (result $error $errno_t) ) - ;; Return the attributes of an open file. + ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;; Note: This is similar to `ftruncate` in POSIX. + ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") (param $fd $fd_t) - ;; The desired file size. + ;;; The desired file size. (param $st_size $filesize_t) (result $error $errno_t) ) - ;; Adjust the timestamps of an open file or directory. - ;; Note: This is similar to `futimens` in POSIX. + ;;; Adjust the timestamps of an open file or directory. + ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") (param $fd $fd_t) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `preadv` in POSIX. + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") (param $fd $fd_t) - ;; List of scatter/gather vectors in which to store data. + ;;; List of scatter/gather vectors in which to store data. (param $iovs $iovec_t_array) - ;; The offset within the file at which to read. + ;;; The offset within the file at which to read. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the description is stored. + ;;; The buffer where the description is stored. (result $buf $prestat_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") (param $fd $fd_t) - ;; A buffer into which to write the preopened directory name. + ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size_t) (result $error $errno_t) ) - ;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `pwritev` in POSIX. + ;;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) - ;; The offset within the file at which to write. + ;;; The offset within the file at which to write. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Read from a file descriptor. - ;; Note: This is similar to `readv` in POSIX. + ;;; Read from a file descriptor. + ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_t_array) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Read directory entries from a directory. - ;; When successful, the contents of the output buffer consist of a sequence of - ;; directory entries. Each directory entry consists of a dirent_t object, - ;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;; entry. + ;;; Read directory entries from a directory. + ;;; When successful, the contents of the output buffer consist of a sequence of + ;;; directory entries. Each directory entry consists of a dirent_t object, + ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; entry. ;; - ;; This function fills the output buffer as much as possible, potentially - ;; truncating the last directory entry. This allows the caller to grow its - ;; read buffer size in case it's too small to fit a single large directory - ;; entry, or skip the oversized directory entry. + ;;; This function fills the output buffer as much as possible, potentially + ;;; truncating the last directory entry. This allows the caller to grow its + ;;; read buffer size in case it's too small to fit a single large directory + ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") (param $fd $fd_t) - ;; The buffer where directory entries are stored + ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) (param $buf_len $size_t) - ;; The location within the directory to start reading + ;;; The location within the directory to start reading (param $cookie $dircookie_t) (result $error $errno_t) - ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. (result $bufused $size_t) ) - ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;;; Atomically replace a file descriptor by renumbering another file descriptor. ;; - ;; Due to the strong focus on thread safety, this environment does not provide - ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;; file descriptor with the same number could be allocated by a different - ;; thread at the same time. + ;;; Due to the strong focus on thread safety, this environment does not provide + ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;;; file descriptor with the same number could be allocated by a different + ;;; thread at the same time. ;; - ;; This function provides a way to atomically renumber file descriptors, which - ;; would disappear if `dup2()` were to be removed entirely. + ;;; This function provides a way to atomically renumber file descriptors, which + ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") (param $fd $fd_t) - ;; The file descriptor to overwrite. + ;;; The file descriptor to overwrite. (param $to $fd_t) (result $error $errno_t) ) - ;; Move the offset of a file descriptor. - ;; Note: This is similar to `lseek` in POSIX. + ;;; Move the offset of a file descriptor. + ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") (param $fd $fd_t) - ;; The number of bytes to move. + ;;; The number of bytes to move. (param $offset $filedelta_t) - ;; The base from which the offset is relative. + ;;; The base from which the offset is relative. (param $whence $whence_t) (result $error $errno_t) - ;; The new offset of the file descriptor, relative to the start of the file. + ;;; The new offset of the file descriptor, relative to the start of the file. (result $newoffset $filesize_t) ) - ;; Synchronize the data and metadata of a file to disk. - ;; Note: This is similar to `fsync` in POSIX. + ;;; Synchronize the data and metadata of a file to disk. + ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Return the current offset of a file descriptor. - ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + ;;; Return the current offset of a file descriptor. + ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd_t) (result $error $errno_t) - ;; The current offset of the file descriptor, relative to the start of the file. + ;;; The current offset of the file descriptor, relative to the start of the file. (result $offset $filesize_t) ) - ;; Write to a file descriptor. - ;; Note: This is similar to `writev` in POSIX. + ;;; Write to a file descriptor. + ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Create a directory. - ;; Note: This is similar to `mkdirat` in POSIX. + ;;; Create a directory. + ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") (param $fd $fd_t) - ;; The path at which to create the directory. + ;;; The path at which to create the directory. (param $path string) (result $error $errno_t) ) - ;; Return the attributes of a file or directory. - ;; Note: This is similar to `stat` in POSIX. + ;;; Return the attributes of a file or directory. + ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to inspect. + ;;; The path of the file or directory to inspect. (param $path string) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the timestamps of a file or directory. - ;; Note: This is similar to `utimensat` in POSIX. + ;;; Adjust the timestamps of a file or directory. + ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to operate on. + ;;; The path of the file or directory to operate on. (param $path string) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Create a hard link. - ;; Note: This is similar to `linkat` in POSIX. + ;;; Create a hard link. + ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") (param $old_fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) - ;; The source path from which to link. + ;;; The source path from which to link. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path at which to create the hard link. + ;;; The destination path at which to create the hard link. (param $new_path string) (result $error $errno_t) ) - ;; Open a file or directory. + ;;; Open a file or directory. ;; - ;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;; file descriptor not currently open; it is randomized to prevent - ;; applications from depending on making assumptions about indexes, since this - ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 2**31. + ;;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;;; file descriptor not currently open; it is randomized to prevent + ;;; applications from depending on making assumptions about indexes, since this + ;;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;;; guaranteed to be less than 2**31. ;; - ;; Note: This is similar to `openat` in POSIX. + ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags_t) - ;; The relative path of the file or directory to open, relative to the - ;; `dirfd` directory. + ;;; The relative path of the file or directory to open, relative to the + ;;; `dirfd` directory. (param $path string) - ;; The method by which to open the file. + ;;; The method by which to open the file. (param $o_flags $oflags_t) - ;; The initial rights of the newly created file descriptor. The - ;; implementation is allowed to return a file descriptor with fewer rights - ;; than specified, if and only if those rights do not apply to the type of - ;; file being opened. + ;;; The initial rights of the newly created file descriptor. The + ;;; implementation is allowed to return a file descriptor with fewer rights + ;;; than specified, if and only if those rights do not apply to the type of + ;;; file being opened. ;; - ;; The *base* rights are rights that will apply to operations using the file - ;; descriptor itself, while the *inheriting* rights are rights that apply to - ;; file descriptors derived from it. + ;;; The *base* rights are rights that will apply to operations using the file + ;;; descriptor itself, while the *inheriting* rights are rights that apply to + ;;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) (param $flags $fdflags_t) (result $error $errno_t) - ;; The file descriptor of the file that has been opened. + ;;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) ) - ;; Read the contents of a symbolic link. - ;; Note: This is similar to `readlinkat` in POSIX. + ;;; Read the contents of a symbolic link. + ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") (param $fd $fd_t) - ;; The path of the symbolic link from which to read. + ;;; The path of the symbolic link from which to read. (param $path string) - ;; The buffer to which to write the contents of the symbolic link. + ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) - ;; The number of bytes placed in the buffer. + ;;; The number of bytes placed in the buffer. (result $bufused $size_t) ) - ;; Remove a directory. - ;; Return `ENOTEMPTY` if the directory is not empty. - ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + ;;; Remove a directory. + ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd_t) - ;; The path to a directory to remove. + ;;; The path to a directory to remove. (param $path string) (result $error $errno_t) ) - ;; Rename a file or directory. - ;; Note: This is similar to `renameat` in POSIX. + ;;; Rename a file or directory. + ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") (param $fd $fd_t) - ;; The source path of the file or directory to rename. + ;;; The source path of the file or directory to rename. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path to which to rename the file or directory. + ;;; The destination path to which to rename the file or directory. (param $new_path string) (result $error $errno_t) ) - ;; Create a symbolic link. - ;; Note: This is similar to `symlinkat` in POSIX. + ;;; Create a symbolic link. + ;;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - ;; The contents of the symbolic link. + ;;; The contents of the symbolic link. (param $old_path string) (param $fd $fd_t) - ;; The destination path at which to create the symbolic link. + ;;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) ) - ;; Unlink a file. - ;; Return `EISDIR` if the path refers to a directory. - ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + ;;; Unlink a file. + ;;; Return `EISDIR` if the path refers to a directory. + ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd_t) - ;; The path to a file to unlink. + ;;; The path to a file to unlink. (param $path string) (result $error $errno_t) ) - ;; Concurrently poll for the occurrence of a set of events. + ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") - ;; The events to which to subscribe. + ;;; The events to which to subscribe. (param $in (@witx const_pointer $subscription_t)) - ;; The events that have occurred. + ;;; The events that have occurred. (param $out (@witx pointer $event_t)) - ;; Both the number of subscriptions and events. + ;;; Both the number of subscriptions and events. (param $nsubscriptions $size_t) (result $error $errno_t) - ;; The number of events stored. + ;;; The number of events stored. (result $nevents $size_t) ) - ;; Terminate the process normally. An exit code of 0 indicates successful - ;; termination of the program. The meanings of other values is dependent on - ;; the environment. + ;;; Terminate the process normally. An exit code of 0 indicates successful + ;;; termination of the program. The meanings of other values is dependent on + ;;; the environment. (@interface func (export "proc_exit") - ;; The exit code returned by the process. + ;;; The exit code returned by the process. (param $rval $exitcode_t) ) - ;; Send a signal to the process of the calling thread. - ;; Note: This is similar to `raise` in POSIX. + ;;; Send a signal to the process of the calling thread. + ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") - ;; The signal condition to trigger. + ;;; The signal condition to trigger. (param $sig $signal_t) (result $error $errno_t) ) - ;; Temporarily yield execution of the calling thread. - ;; Note: This is similar to `sched_yield` in POSIX. + ;;; Temporarily yield execution of the calling thread. + ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") (result $error $errno_t) ) - ;; Write high-quality random data into a buffer. - ;; This function blocks when the implementation is unable to immediately - ;; provide sufficient high-quality random data. - ;; This function may execute slowly, so when large mounts of random data are - ;; required, it's advisable to use this function to seed a pseudo-random - ;; number generator, rather than to provide the random data directly. + ;;; Write high-quality random data into a buffer. + ;;; This function blocks when the implementation is unable to immediately + ;;; provide sufficient high-quality random data. + ;;; This function may execute slowly, so when large mounts of random data are + ;;; required, it's advisable to use this function to seed a pseudo-random + ;;; number generator, rather than to provide the random data directly. (@interface func (export "random_get") - ;; The buffer to fill with random data. + ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) ) - ;; Receive a message from a socket. - ;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;; the data into multiple buffers in the manner of `readv`. + ;;; Receive a message from a socket. + ;;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $ri_data $iovec_t_array) - ;; Message flags. + ;;; Message flags. (param $ri_flags $riflags_t) (result $error $errno_t) - ;; Number of bytes stored in ri_data. + ;;; Number of bytes stored in ri_data. (result $ro_datalen $size_t) - ;; Message flags. + ;;; Message flags. (result $ro_flags $roflags_t) ) - ;; Send a message on a socket. - ;; Note: This is similar to `send` in POSIX, though it also supports writing - ;; the data from multiple buffers in the manner of `writev`. + ;;; Send a message on a socket. + ;;; Note: This is similar to `send` in POSIX, though it also supports writing + ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to retrieve data + ;;; List of scatter/gather vectors to which to retrieve data (param $si_data $ciovec_t_array) - ;; Message flags. + ;;; Message flags. (param $si_flags $siflags_t) (result $error $errno_t) - ;; Number of bytes transmitted. + ;;; Number of bytes transmitted. (result $so_datalen $size_t) ) - ;; Shut down socket send and receive channels. - ;; Note: This is similar to `shutdown` in POSIX. + ;;; Shut down socket send and receive channels. + ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") (param $fd $fd_t) - ;; Which channels on the socket to shut down. + ;;; Which channels on the socket to shut down. (param $how $sdflags_t) (result $error $errno_t) ) diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx index 1a45be1fd..68f6fac4a 100644 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -7,291 +7,291 @@ (typename $size_t u32) -;; Non-negative file size or length of a region within a file. +;;; Non-negative file size or length of a region within a file. (typename $filesize_t u64) -;; Timestamp in nanoseconds. +;;; Timestamp in nanoseconds. (typename $timestamp_t u64) -;; Identifiers for clocks. +;;; Identifiers for clocks. (typename $clockid_t (enum u32 - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. + ;;; The clock measuring real time. Time value zero corresponds with + ;;; 1970-01-01T00:00:00Z. $CLOCK_REALTIME - ;; The store-wide monotonic clock, which is defined as a clock measuring - ;; real time, whose value cannot be adjusted and which cannot have negative - ;; clock jumps. The epoch of this clock is undefined. The absolute time - ;; value of this clock therefore has no meaning. + ;;; The store-wide monotonic clock, which is defined as a clock measuring + ;;; real time, whose value cannot be adjusted and which cannot have negative + ;;; clock jumps. The epoch of this clock is undefined. The absolute time + ;;; value of this clock therefore has no meaning. $CLOCK_MONOTONIC - ;; The CPU-time clock associated with the current process. + ;;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The CPU-time clock associated with the current thread. + ;;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) ) -;; Error codes returned by functions. -;; Not all of these error codes are returned by the functions provided by this -;; API; some are used in higher-level library layers, and others are provided -;; merely for alignment with POSIX. +;;; Error codes returned by functions. +;;; Not all of these error codes are returned by the functions provided by this +;;; API; some are used in higher-level library layers, and others are provided +;;; merely for alignment with POSIX. (typename $errno_t (enum u16 - ;; No error occurred. System call completed successfully. + ;;; No error occurred. System call completed successfully. $ESUCCESS - ;; Argument list too long. + ;;; Argument list too long. $E2BIG - ;; Permission denied. + ;;; Permission denied. $EACCES - ;; Address in use. + ;;; Address in use. $EADDRINUSE - ;; Address not available. + ;;; Address not available. $EADDRNOTAVAIL - ;; Address family not supported. + ;;; Address family not supported. $EAFNOSUPPORT - ;; Resource unavailable, or operation would block. + ;;; Resource unavailable, or operation would block. $EAGAIN - ;; Connection already in progress. + ;;; Connection already in progress. $EALREADY - ;; Bad file descriptor. + ;;; Bad file descriptor. $EBADF - ;; Bad message. + ;;; Bad message. $EBADMSG - ;; Device or resource busy. + ;;; Device or resource busy. $EBUSY - ;; Operation canceled. + ;;; Operation canceled. $ECANCELED - ;; No child processes. + ;;; No child processes. $ECHILD - ;; Connection aborted. + ;;; Connection aborted. $ECONNABORTED - ;; Connection refused. + ;;; Connection refused. $ECONNREFUSED - ;; Connection reset. + ;;; Connection reset. $ECONNRESET - ;; Resource deadlock would occur. + ;;; Resource deadlock would occur. $EDEADLK - ;; Destination address required. + ;;; Destination address required. $EDESTADDRREQ - ;; Mathematics argument out of domain of function. + ;;; Mathematics argument out of domain of function. $EDOM - ;; Reserved. + ;;; Reserved. $EDQUOT - ;; File exists. + ;;; File exists. $EEXIST - ;; Bad address. + ;;; Bad address. $EFAULT - ;; File too large. + ;;; File too large. $EFBIG - ;; Host is unreachable. + ;;; Host is unreachable. $EHOSTUNREACH - ;; Identifier removed. + ;;; Identifier removed. $EIDRM - ;; Illegal byte sequence. + ;;; Illegal byte sequence. $EILSEQ - ;; Operation in progress. + ;;; Operation in progress. $EINPROGRESS - ;; Interrupted function. + ;;; Interrupted function. $EINTR - ;; Invalid argument. + ;;; Invalid argument. $EINVAL - ;; I/O error. + ;;; I/O error. $EIO - ;; Socket is connected. + ;;; Socket is connected. $EISCONN - ;; Is a directory. + ;;; Is a directory. $EISDIR - ;; Too many levels of symbolic links. + ;;; Too many levels of symbolic links. $ELOOP - ;; File descriptor value too large. + ;;; File descriptor value too large. $EMFILE - ;; Too many links. + ;;; Too many links. $EMLINK - ;; Message too large. + ;;; Message too large. $EMSGSIZE - ;; Reserved. + ;;; Reserved. $EMULTIHOP - ;; Filename too long. + ;;; Filename too long. $ENAMETOOLONG - ;; Network is down. + ;;; Network is down. $ENETDOWN - ;; Connection aborted by network. + ;;; Connection aborted by network. $ENETRESET - ;; Network unreachable. + ;;; Network unreachable. $ENETUNREACH - ;; Too many files open in system. + ;;; Too many files open in system. $ENFILE - ;; No buffer space available. + ;;; No buffer space available. $ENOBUFS - ;; No such device. + ;;; No such device. $ENODEV - ;; No such file or directory. + ;;; No such file or directory. $ENOENT - ;; Executable file format error. + ;;; Executable file format error. $ENOEXEC - ;; No locks available. + ;;; No locks available. $ENOLCK - ;; Reserved. + ;;; Reserved. $ENOLINK - ;; Not enough space. + ;;; Not enough space. $ENOMEM - ;; No message of the desired type. + ;;; No message of the desired type. $ENOMSG - ;; Protocol not available. + ;;; Protocol not available. $ENOPROTOOPT - ;; No space left on device. + ;;; No space left on device. $ENOSPC - ;; Function not supported. + ;;; Function not supported. $ENOSYS - ;; The socket is not connected. + ;;; The socket is not connected. $ENOTCONN - ;; Not a directory or a symbolic link to a directory. + ;;; Not a directory or a symbolic link to a directory. $ENOTDIR - ;; Directory not empty. + ;;; Directory not empty. $ENOTEMPTY - ;; State not recoverable. + ;;; State not recoverable. $ENOTRECOVERABLE - ;; Not a socket. + ;;; Not a socket. $ENOTSOCK - ;; Not supported, or operation not supported on socket. + ;;; Not supported, or operation not supported on socket. $ENOTSUP - ;; Inappropriate I/O control operation. + ;;; Inappropriate I/O control operation. $ENOTTY - ;; No such device or address. + ;;; No such device or address. $ENXIO - ;; Value too large to be stored in data type. + ;;; Value too large to be stored in data type. $EOVERFLOW - ;; Previous owner died. + ;;; Previous owner died. $EOWNERDEAD - ;; Operation not permitted. + ;;; Operation not permitted. $EPERM - ;; Broken pipe. + ;;; Broken pipe. $EPIPE - ;; Protocol error. + ;;; Protocol error. $EPROTO - ;; Protocol not supported. + ;;; Protocol not supported. $EPROTONOSUPPORT - ;; Protocol wrong type for socket. + ;;; Protocol wrong type for socket. $EPROTOTYPE - ;; Result too large. + ;;; Result too large. $ERANGE - ;; Read-only file system. + ;;; Read-only file system. $EROFS - ;; Invalid seek. + ;;; Invalid seek. $ESPIPE - ;; No such process. + ;;; No such process. $ESRCH - ;; Reserved. + ;;; Reserved. $ESTALE - ;; Connection timed out. + ;;; Connection timed out. $ETIMEDOUT - ;; Text file busy. + ;;; Text file busy. $ETXTBSY - ;; Cross-device link. + ;;; Cross-device link. $EXDEV - ;; Extension: Capabilities insufficient. + ;;; Extension: Capabilities insufficient. $ENOTCAPABLE ) ) -;; File descriptor rights, determining which actions may be performed. +;;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke `fd_datasync`. + ;;; The right to invoke `fd_datasync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_DSYNC`. $RIGHT_FD_DATASYNC - ;; The right to invoke `fd_read` and `sock_recv`. + ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. $RIGHT_FD_READ - ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. $RIGHT_FD_SEEK - ;; The right to invoke `fd_fdstat_set_flags`. + ;;; The right to invoke `fd_fdstat_set_flags`. $RIGHT_FD_FDSTAT_SET_FLAGS - ;; The right to invoke `fd_sync`. + ;;; The right to invoke `fd_sync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. $RIGHT_FD_SYNC - ;; The right to invoke `fd_seek` in such a way that the file offset - ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to - ;; invoke `fd_tell`. + ;;; The right to invoke `fd_seek` in such a way that the file offset + ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; invoke `fd_tell`. $RIGHT_FD_TELL - ;; The right to invoke `fd_write` and `sock_send`. - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + ;;; The right to invoke `fd_write` and `sock_send`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. $RIGHT_FD_WRITE - ;; The right to invoke `fd_advise`. + ;;; The right to invoke `fd_advise`. $RIGHT_FD_ADVISE - ;; The right to invoke `fd_allocate`. + ;;; The right to invoke `fd_allocate`. $RIGHT_FD_ALLOCATE - ;; The right to invoke `path_create_directory`. + ;;; The right to invoke `path_create_directory`. $RIGHT_PATH_CREATE_DIRECTORY - ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. $RIGHT_PATH_CREATE_FILE - ;; The right to invoke `path_link` with the file descriptor as the - ;; source directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; source directory. $RIGHT_PATH_LINK_SOURCE - ;; The right to invoke `path_link` with the file descriptor as the - ;; target directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; target directory. $RIGHT_PATH_LINK_TARGET - ;; The right to invoke `path_open`. + ;;; The right to invoke `path_open`. $RIGHT_PATH_OPEN - ;; The right to invoke `fd_readdir`. + ;;; The right to invoke `fd_readdir`. $RIGHT_FD_READDIR - ;; The right to invoke `path_readlink`. + ;;; The right to invoke `path_readlink`. $RIGHT_PATH_READLINK - ;; The right to invoke `path_rename` with the file descriptor as the source directory. + ;;; The right to invoke `path_rename` with the file descriptor as the source directory. $RIGHT_PATH_RENAME_SOURCE - ;; The right to invoke `path_rename` with the file descriptor as the target directory. + ;;; The right to invoke `path_rename` with the file descriptor as the target directory. $RIGHT_PATH_RENAME_TARGET - ;; The right to invoke `path_filestat_get`. + ;;; The right to invoke `path_filestat_get`. $RIGHT_PATH_FILESTAT_GET - ;; The right to change a file's size (there is no `path_filestat_set_size`). - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + ;;; The right to change a file's size (there is no `path_filestat_set_size`). + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. $RIGHT_PATH_FILESTAT_SET_SIZE - ;; The right to invoke `path_filestat_set_times`. + ;;; The right to invoke `path_filestat_set_times`. $RIGHT_PATH_FILESTAT_SET_TIMES - ;; The right to invoke `fd_filestat_get`. + ;;; The right to invoke `fd_filestat_get`. $RIGHT_FD_FILESTAT_GET - ;; The right to invoke `fd_filestat_set_size`. + ;;; The right to invoke `fd_filestat_set_size`. $RIGHT_FD_FILESTAT_SET_SIZE - ;; The right to invoke `fd_filestat_set_times`. + ;;; The right to invoke `fd_filestat_set_times`. $RIGHT_FD_FILESTAT_SET_TIMES - ;; The right to invoke `path_symlink`. + ;;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_remove_directory`. + ;;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY - ;; The right to invoke `path_unlink_file`. + ;;; The right to invoke `path_unlink_file`. $RIGHT_PATH_UNLINK_FILE - ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE - ;; The right to invoke `sock_shutdown`. + ;;; The right to invoke `sock_shutdown`. $RIGHT_SOCK_SHUTDOWN ) ) -;; A file descriptor index. +;;; A file descriptor index. (typename $fd_t u32) -;; A region of memory for scatter/gather reads. +;;; A region of memory for scatter/gather reads. (typename $iovec_t (struct - ;; The address of the buffer to be filled. + ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) - ;; The length of the buffer to be filled. + ;;; The length of the buffer to be filled. (field $buf_len $size_t) ) ) -;; A region of memory for scatter/gather writes. +;;; A region of memory for scatter/gather writes. (typename $ciovec_t (struct - ;; The address of the buffer to be written. + ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) - ;; The length of the buffer to be written. + ;;; The length of the buffer to be written. (field $buf_len $size_t) ) ) @@ -299,469 +299,469 @@ (typename $iovec_t_array (array $iovec_t)) (typename $ciovec_t_array (array $ciovec_t)) -;; Relative offset within a file. +;;; Relative offset within a file. (typename $filedelta_t s64) -;; The position relative to which to set the offset of the file descriptor. +;;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 - ;; Seek relative to start-of-file. + ;;; Seek relative to start-of-file. $WHENCE_SET - ;; Seek relative to current position. + ;;; Seek relative to current position. $WHENCE_CUR - ;; Seek relative to end-of-file. + ;;; Seek relative to end-of-file. $WHENCE_END ) ) -;; A reference to the offset of a directory entry. -;; -;; The value 0 signifies the start of the directory. +;;; A reference to the offset of a directory entry. +;;; +;;; The value 0 signifies the start of the directory. (typename $dircookie_t u64) -;; The type for the $d_namlen field of $dirent_t. +;;; The type for the $d_namlen field of $dirent_t. (typename $dirnamlen_t u32) -;; File serial number that is unique within its file system. +;;; File serial number that is unique within its file system. (typename $inode_t u64) -;; The type of a file descriptor or file. +;;; The type of a file descriptor or file. (typename $filetype_t (enum u8 - ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $FILETYPE_UNKNOWN - ;; The file descriptor or file refers to a block device inode. + ;;; The file descriptor or file refers to a block device inode. $FILETYPE_BLOCK_DEVICE - ;; The file descriptor or file refers to a character device inode. + ;;; The file descriptor or file refers to a character device inode. $FILETYPE_CHARACTER_DEVICE - ;; The file descriptor or file refers to a directory inode. + ;;; The file descriptor or file refers to a directory inode. $FILETYPE_DIRECTORY - ;; The file descriptor or file refers to a regular file inode. + ;;; The file descriptor or file refers to a regular file inode. $FILETYPE_REGULAR_FILE - ;; The file descriptor or file refers to a datagram socket. + ;;; The file descriptor or file refers to a datagram socket. $FILETYPE_SOCKET_DGRAM - ;; The file descriptor or file refers to a byte-stream socket. + ;;; The file descriptor or file refers to a byte-stream socket. $FILETYPE_SOCKET_STREAM - ;; The file refers to a symbolic link inode. + ;;; The file refers to a symbolic link inode. $FILETYPE_SYMBOLIC_LINK ) ) -;; A directory entry. +;;; A directory entry. (typename $dirent_t (struct - ;; The offset of the next directory entry stored in this directory. + ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie_t) - ;; The serial number of the file referred to by this directory entry. + ;;; The serial number of the file referred to by this directory entry. (field $d_ino $inode_t) - ;; The length of the name of the directory entry. + ;;; The length of the name of the directory entry. (field $d_namlen $dirnamlen_t) - ;; The type of the file referred to by this directory entry. + ;;; The type of the file referred to by this directory entry. (field $d_type $filetype_t) ) ) -;; File or memory access pattern advisory information. +;;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application has no advice to give on its behavior with respect to the specified data. + ;;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL - ;; The application expects to access the specified data in a random order. + ;;; The application expects to access the specified data in a random order. $ADVICE_RANDOM - ;; The application expects to access the specified data in the near future. + ;;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED - ;; The application expects that it will not access the specified data in the near future. + ;;; The application expects that it will not access the specified data in the near future. $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. + ;;; The application expects to access the specified data once and then not reuse it thereafter. $ADVICE_NOREUSE ) ) -;; File descriptor flags. +;;; File descriptor flags. (typename $fdflags_t (flags u16 - ;; Append mode: Data written to the file is always appended to the file's end. + ;;; Append mode: Data written to the file is always appended to the file's end. $FDFLAG_APPEND - ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. $FDFLAG_DSYNC - ;; Non-blocking mode. + ;;; Non-blocking mode. $FDFLAG_NONBLOCK - ;; Synchronized read I/O operations. + ;;; Synchronized read I/O operations. $FDFLAG_RSYNC - ;; Write according to synchronized I/O file integrity completion. In - ;; addition to synchronizing the data stored in the file, the implementation - ;; may also synchronously update the file's metadata. + ;;; Write according to synchronized I/O file integrity completion. In + ;;; addition to synchronizing the data stored in the file, the implementation + ;;; may also synchronously update the file's metadata. $FDFLAG_SYNC ) ) -;; File descriptor attributes. +;;; File descriptor attributes. (typename $fdstat_t (struct - ;; File type. + ;;; File type. (field $fs_filetype $filetype_t) - ;; File descriptor flags. + ;;; File descriptor flags. (field $fs_flags $fdflags_t) - ;; Rights that apply to this file descriptor. + ;;; Rights that apply to this file descriptor. (field $fs_rights_base $rights_t) - ;; Maximum set of rights that may be installed on new file descriptors that - ;; are created through this file descriptor, e.g., through `path_open`. + ;;; Maximum set of rights that may be installed on new file descriptors that + ;;; are created through this file descriptor, e.g., through `path_open`. (field $fs_rights_inheriting $rights_t) ) ) -;; Identifier for a device containing a file system. Can be used in combination -;; with `inode_t` to uniquely identify a file or directory in the filesystem. +;;; Identifier for a device containing a file system. Can be used in combination +;;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) -;; Which file time attributes to adjust. +;;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 - ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. $FILESTAT_SET_ATIM - ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_ATIM_NOW - ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. $FILESTAT_SET_MTIM - ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_MTIM_NOW ) ) -;; Flags determining the method of how paths are resolved. +;;; Flags determining the method of how paths are resolved. (typename $lookupflags_t (flags u32 - ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $LOOKUP_SYMLINK_FOLLOW ) ) -;; Open flags used by `path_open`. +;;; Open flags used by `path_open`. (typename $oflags_t (flags u16 - ;; Create file if it does not exist. + ;;; Create file if it does not exist. $O_CREAT - ;; Fail if not a directory. + ;;; Fail if not a directory. $O_DIRECTORY - ;; Fail if file already exists. + ;;; Fail if file already exists. $O_EXCL - ;; Truncate file to size 0. + ;;; Truncate file to size 0. $O_TRUNC ) ) -;; Number of hard links to an inode. +;;; Number of hard links to an inode. (typename $linkcount_t u64) -;; File attributes. +;;; File attributes. (typename $filestat_t (struct - ;; Device ID of device containing the file. + ;;; Device ID of device containing the file. (field $st_dev $device_t) - ;; File serial number. + ;;; File serial number. (field $st_ino $inode_t) - ;; File type. + ;;; File type. (field $st_filetype $filetype_t) - ;; Number of hard links to the file. + ;;; Number of hard links to the file. (field $st_nlink $linkcount_t) - ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. (field $st_size $filesize_t) - ;; Last data access timestamp. + ;;; Last data access timestamp. (field $st_atim $timestamp_t) - ;; Last data modification timestamp. + ;;; Last data modification timestamp. (field $st_mtim $timestamp_t) - ;; Last file status change timestamp. + ;;; Last file status change timestamp. (field $st_ctim $timestamp_t) ) ) -;; User-provided value that may be attached to objects that is retained when -;; extracted from the implementation. +;;; User-provided value that may be attached to objects that is retained when +;;; extracted from the implementation. (typename $userdata_t u64) -;; Type of a subscription to an event or its occurrence. +;;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (enum u8 - ;; The time value of clock `subscription_t::u.clock.clock_id` has - ;; reached timestamp `subscription_t::u.clock.timeout`. + ;;; The time value of clock `subscription_t::u.clock.clock_id` has + ;;; reached timestamp `subscription_t::u.clock.timeout`. $EVENTTYPE_CLOCK - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data - ;; available for reading. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; available for reading. This event always triggers for regular files. $EVENTTYPE_FD_READ - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity - ;; available for writing. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;;; available for writing. This event always triggers for regular files. $EVENTTYPE_FD_WRITE ) ) -;; The state of the file descriptor subscribed to with -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The state of the file descriptor subscribed to with +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 - ;; The peer of this socket has closed or disconnected. + ;;; The peer of this socket has closed or disconnected. $EVENT_FD_READWRITE_HANGUP ) ) -;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;; `EVENTTYPE_FD_WRITE`. +;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;;; `EVENTTYPE_FD_WRITE`. (typename $event_fd_readwrite_t (struct - ;; The number of bytes available for reading or writing. + ;;; The number of bytes available for reading or writing. (field $nbytes $filesize_t) - ;; The state of the file descriptor. + ;;; The state of the file descriptor. (field $flags $eventrwflags_t) ) ) -;; The contents of an $event_t. +;;; The contents of an $event_t. (typename $event_u (union - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; An event that occurred. +;;; An event that occurred. (typename $event_t (struct - ;; User-provided value that got attached to `subscription_t::userdata`. + ;;; User-provided value that got attached to `subscription_t::userdata`. (field $userdata $userdata_t) - ;; If non-zero, an error that occurred while processing the subscription request. + ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno_t) - ;; The type of the event that occurred. + ;;; The type of the event that occurred. (field $type $eventtype_t) - ;; The contents of the event. + ;;; The contents of the event. (field $u $event_u) ) ) -;; Flags determining how to interpret the timestamp provided in -;; `subscription_t::u.clock.timeout.` +;;; Flags determining how to interpret the timestamp provided in +;;; `subscription_t::u.clock.timeout.` (typename $subclockflags_t (flags u16 - ;; If set, treat the timestamp provided in - ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;; provided in `subscription_t::u.clock.timeout` relative to the - ;; current time value of clock `subscription_t::u.clock.clock_id.` + ;;; If set, treat the timestamp provided in + ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription_t::u.clock.timeout` relative to the + ;;; current time value of clock `subscription_t::u.clock.clock_id.` $SUBSCRIPTION_CLOCK_ABSTIME ) ) -;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The clock against which to compare the timestamp. + ;;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. + ;;; The absolute or relative timestamp. (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. + ;;; The amount of time that the implementation may wait additionally + ;;; to coalesce with other events. (field $precision $timestamp_t) - ;; Flags specifying whether the timeout is absolute or relative + ;;; Flags specifying whether the timeout is absolute or relative (field $flags $subclockflags_t) ) ) -;; The contents of a $subscription_t when type is type is -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The contents of a $subscription_t when type is type is +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $subscription_fd_readwrite_t (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. + ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd_t) ) ) -;; The contents of a $subscription_t. +;;; The contents of a $subscription_t. (typename $subscription_u (union - ;; When type is `EVENTTYPE_CLOCK`: + ;;; When type is `EVENTTYPE_CLOCK`: (field $clock $subscription_clock_t) - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $subscription_fd_readwrite_t) ) ) -;; Subscription to an event. +;;; Subscription to an event. (typename $subscription_t (struct - ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through `event_t::userdata`. + ;;; User-provided value that is attached to the subscription in the + ;;; implementation and returned through `event_t::userdata`. (field $userdata $userdata_t) - ;; The type of the event to which to subscribe. + ;;; The type of the event to which to subscribe. (field $type $eventtype_t) - ;; The contents of the subscription. + ;;; The contents of the subscription. (field $u $subscription_u) ) ) -;; Exit code generated by a process when exiting. +;;; Exit code generated by a process when exiting. (typename $exitcode_t u32) -;; Signal condition. +;;; Signal condition. (typename $signal_t (enum u8 - ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;; so this value is reserved. + ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;;; so this value is reserved. $SIGNONE - ;; Hangup. - ;; Action: Terminates the process. + ;;; Hangup. + ;;; Action: Terminates the process. $SIGHUP - ;; Terminate interrupt signal. - ;; Action: Terminates the process. + ;;; Terminate interrupt signal. + ;;; Action: Terminates the process. $SIGINT - ;; Terminal quit signal. - ;; Action: Terminates the process. + ;;; Terminal quit signal. + ;;; Action: Terminates the process. $SIGQUIT - ;; Illegal instruction. - ;; Action: Terminates the process. + ;;; Illegal instruction. + ;;; Action: Terminates the process. $SIGILL - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. + ;;; Trace/breakpoint trap. + ;;; Action: Terminates the process. $SIGTRAP - ;; Process abort signal. - ;; Action: Terminates the process. + ;;; Process abort signal. + ;;; Action: Terminates the process. $SIGABRT - ;; Access to an undefined portion of a memory object. - ;; Action: Terminates the process. + ;;; Access to an undefined portion of a memory object. + ;;; Action: Terminates the process. $SIGBUS - ;; Erroneous arithmetic operation. - ;; Action: Terminates the process. + ;;; Erroneous arithmetic operation. + ;;; Action: Terminates the process. $SIGFPE - ;; Kill. - ;; Action: Terminates the process. + ;;; Kill. + ;;; Action: Terminates the process. $SIGKILL - ;; User-defined signal 1. - ;; Action: Terminates the process. + ;;; User-defined signal 1. + ;;; Action: Terminates the process. $SIGUSR1 - ;; Invalid memory reference. - ;; Action: Terminates the process. + ;;; Invalid memory reference. + ;;; Action: Terminates the process. $SIGSEGV - ;; User-defined signal 2. - ;; Action: Terminates the process. + ;;; User-defined signal 2. + ;;; Action: Terminates the process. $SIGUSR2 - ;; Write on a pipe with no one to read it. - ;; Action: Ignored. + ;;; Write on a pipe with no one to read it. + ;;; Action: Ignored. $SIGPIPE - ;; Alarm clock. - ;; Action: Terminates the process. + ;;; Alarm clock. + ;;; Action: Terminates the process. $SIGALRM - ;; Termination signal. - ;; Action: Terminates the process. + ;;; Termination signal. + ;;; Action: Terminates the process. $SIGTERM - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. + ;;; Child process terminated, stopped, or continued. + ;;; Action: Ignored. $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. + ;;; Continue executing, if stopped. + ;;; Action: Continues executing, if stopped. $SIGCONT - ;; Stop executing. - ;; Action: Stops executing. + ;;; Stop executing. + ;;; Action: Stops executing. $SIGSTOP - ;; Terminal stop signal. - ;; Action: Stops executing. + ;;; Terminal stop signal. + ;;; Action: Stops executing. $SIGTSTP - ;; Background process attempting read. - ;; Action: Stops executing. + ;;; Background process attempting read. + ;;; Action: Stops executing. $SIGTTIN - ;; Background process attempting write. - ;; Action: Stops executing. + ;;; Background process attempting write. + ;;; Action: Stops executing. $SIGTTOU - ;; High bandwidth data is available at a socket. - ;; Action: Ignored. + ;;; High bandwidth data is available at a socket. + ;;; Action: Ignored. $SIGURG - ;; CPU time limit exceeded. - ;; Action: Terminates the process. + ;;; CPU time limit exceeded. + ;;; Action: Terminates the process. $SIGXCPU - ;; File size limit exceeded. - ;; Action: Terminates the process. + ;;; File size limit exceeded. + ;;; Action: Terminates the process. $SIGXFSZ - ;; Virtual timer expired. - ;; Action: Terminates the process. + ;;; Virtual timer expired. + ;;; Action: Terminates the process. $SIGVTALRM - ;; Profiling timer expired. - ;; Action: Terminates the process. + ;;; Profiling timer expired. + ;;; Action: Terminates the process. $SIGPROF - ;; Window changed. - ;; Action: Ignored. + ;;; Window changed. + ;;; Action: Ignored. $SIGWINCH - ;; I/O possible. - ;; Action: Terminates the process. + ;;; I/O possible. + ;;; Action: Terminates the process. $SIGPOLL - ;; Power failure. - ;; Action: Terminates the process. + ;;; Power failure. + ;;; Action: Terminates the process. $SIGPWR - ;; Bad system call. - ;; Action: Terminates the process. + ;;; Bad system call. + ;;; Action: Terminates the process. $SIGSYS ) ) -;; Flags provided to `sock_recv`. +;;; Flags provided to `sock_recv`. (typename $riflags_t (flags u16 - ;; Returns the message without removing it from the socket's receive queue. + ;;; Returns the message without removing it from the socket's receive queue. $SOCK_RECV_PEEK - ;; On byte-stream sockets, block until the full amount of data can be returned. + ;;; On byte-stream sockets, block until the full amount of data can be returned. $SOCK_RECV_WAITALL ) ) -;; Flags returned by `sock_recv`. +;;; Flags returned by `sock_recv`. (typename $roflags_t (flags u16 - ;; Returned by `sock_recv`: Message data has been truncated. + ;;; Returned by `sock_recv`: Message data has been truncated. $SOCK_RECV_DATA_TRUNCATED ) ) -;; Flags provided to `sock_send`. As there are currently no flags -;; defined, it must be set to zero. +;;; Flags provided to `sock_send`. As there are currently no flags +;;; defined, it must be set to zero. (typename $siflags_t u16) -;; Which channels on a socket to shut down. +;;; Which channels on a socket to shut down. (typename $sdflags_t (flags u8 - ;; Disables further receive operations. + ;;; Disables further receive operations. $SHUT_RD - ;; Disables further send operations. + ;;; Disables further send operations. $SHUT_WR ) ) -;; Identifiers for preopened capabilities. +;;; Identifiers for preopened capabilities. (typename $preopentype_t (enum u8 - ;; A pre-opened directory. + ;;; A pre-opened directory. $PREOPENTYPE_DIR ) ) -;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. (typename $prestat_dir (struct - ;; The length of the directory name for use with `fd_prestat_dir_name`. + ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size_t) ) ) -;; The contents of an $prestat_t. +;;; The contents of an $prestat_t. (typename $prestat_u (union - ;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `PREOPENTYPE_DIR`: (field $dir $prestat_dir) ) ) -;; Information about a pre-opened capability. +;;; Information about a pre-opened capability. (typename $prestat_t (struct - ;; The type of the pre-opened capability. + ;;; The type of the pre-opened capability. (field $pr_type $preopentype_t) - ;; The contents of the information. + ;;; The contents of the information. (field $u $prestat_u) ) ) diff --git a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx index 630537416..e69b788dc 100644 --- a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -9,519 +9,522 @@ (use "typenames.witx") (module $wasi_snapshot_preview1 - ;; Linear memory to be accessed by WASI functions that need it. + ;;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) - ;; Read command-line argument data. - ;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; Read command-line argument data. + ;;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Read environment variable data. - ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; Read environment variable data. + ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Return the resolution of a clock. - ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;; Note: This is similar to `clock_getres` in POSIX. + ;;; Return the resolution of a clock. + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno_t) - ;; The clock for which to return the resolution. + ;;; The clock for which to return the resolution. (param $clock_id $clockid_t) - ;; The resolution of the clock. + ;;; The resolution of the clock. (result $resolution $timestamp_t) ) - ;; Return the time value of a clock. - ;; Note: This is similar to `clock_gettime` in POSIX. + ;;; Return the time value of a clock. + ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") - ;; The clock for which to return the time. + ;;; The clock for which to return the time. (param $clock_id $clockid_t) - ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp_t) (result $error $errno_t) - ;; The time value of the clock. + ;;; The time value of the clock. (result $time $timestamp_t) ) - ;; Provide file advisory information on a file descriptor. - ;; Note: This is similar to `posix_fadvise` in POSIX. + ;;; Provide file advisory information on a file descriptor. + ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") (param $fd $fd_t) - (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. - (param $len $filesize_t) ;; The length of the region to which the advisory applies. - (param $advice $advice_t) ;; The advice. + ;;; The offset within the file to which the advisory applies. + (param $offset $filesize_t) + ;;; The length of the region to which the advisory applies. + (param $len $filesize_t) + ;;; The advice. + (param $advice $advice_t) (result $error $errno_t) ) - ;; Force the allocation of space in a file. - ;; Note: This is similar to `posix_fallocate` in POSIX. + ;;; Force the allocation of space in a file. + ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") (param $fd $fd_t) - ;; The offset at which to start the allocation. + ;;; The offset at which to start the allocation. (param $offset $filesize_t) - ;; The length of the area that is allocated. + ;;; The length of the area that is allocated. (param $len $filesize_t) (result $error $errno_t) ) - ;; Close a file descriptor. - ;; Note: This is similar to `close` in POSIX. + ;;; Close a file descriptor. + ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd_t) (result $error $errno_t) ) - ;; Synchronize the data of a file to disk. - ;; Note: This is similar to `fdatasync` in POSIX. + ;;; Synchronize the data of a file to disk. + ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Get the attributes of a file descriptor. - ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + ;;; Get the attributes of a file descriptor. + ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file descriptor's attributes are stored. + ;;; The buffer where the file descriptor's attributes are stored. (result $stat $fdstat_t) ) - ;; Adjust the flags associated with a file descriptor. - ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + ;;; Adjust the flags associated with a file descriptor. + ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") (param $fd $fd_t) - ;; The desired values of the file descriptor flags. + ;;; The desired values of the file descriptor flags. (param $flags $fdflags_t) (result $error $errno_t) ) - ;; Adjust the rights associated with a file descriptor. - ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; Adjust the rights associated with a file descriptor. + ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd_t) - ;; The desired rights of the file descriptor. + ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights_t) (param $fs_rights_inheriting $rights_t) (result $error $errno_t) ) - ;; Return the attributes of an open file. + ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;; Note: This is similar to `ftruncate` in POSIX. + ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") (param $fd $fd_t) - ;; The desired file size. + ;;; The desired file size. (param $st_size $filesize_t) (result $error $errno_t) ) - ;; Adjust the timestamps of an open file or directory. - ;; Note: This is similar to `futimens` in POSIX. + ;;; Adjust the timestamps of an open file or directory. + ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") (param $fd $fd_t) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `preadv` in POSIX. + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") (param $fd $fd_t) - ;; List of scatter/gather vectors in which to store data. + ;;; List of scatter/gather vectors in which to store data. (param $iovs $iovec_t_array) - ;; The offset within the file at which to read. + ;;; The offset within the file at which to read. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the description is stored. + ;;; The buffer where the description is stored. (result $buf $prestat_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") (param $fd $fd_t) - ;; A buffer into which to write the preopened directory name. + ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size_t) (result $error $errno_t) ) - ;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `pwritev` in POSIX. + ;;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) - ;; The offset within the file at which to write. + ;;; The offset within the file at which to write. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Read from a file descriptor. - ;; Note: This is similar to `readv` in POSIX. + ;;; Read from a file descriptor. + ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_t_array) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Read directory entries from a directory. - ;; When successful, the contents of the output buffer consist of a sequence of - ;; directory entries. Each directory entry consists of a dirent_t object, - ;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;; entry. + ;;; Read directory entries from a directory. + ;;; When successful, the contents of the output buffer consist of a sequence of + ;;; directory entries. Each directory entry consists of a dirent_t object, + ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; entry. ;; - ;; This function fills the output buffer as much as possible, potentially - ;; truncating the last directory entry. This allows the caller to grow its - ;; read buffer size in case it's too small to fit a single large directory - ;; entry, or skip the oversized directory entry. + ;;; This function fills the output buffer as much as possible, potentially + ;;; truncating the last directory entry. This allows the caller to grow its + ;;; read buffer size in case it's too small to fit a single large directory + ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") (param $fd $fd_t) - ;; The buffer where directory entries are stored + ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) (param $buf_len $size_t) - ;; The location within the directory to start reading + ;;; The location within the directory to start reading (param $cookie $dircookie_t) (result $error $errno_t) - ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. (result $bufused $size_t) ) - ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;;; Atomically replace a file descriptor by renumbering another file descriptor. ;; - ;; Due to the strong focus on thread safety, this environment does not provide - ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;; file descriptor with the same number could be allocated by a different - ;; thread at the same time. + ;;; Due to the strong focus on thread safety, this environment does not provide + ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;;; file descriptor with the same number could be allocated by a different + ;;; thread at the same time. ;; - ;; This function provides a way to atomically renumber file descriptors, which - ;; would disappear if `dup2()` were to be removed entirely. + ;;; This function provides a way to atomically renumber file descriptors, which + ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") (param $fd $fd_t) - ;; The file descriptor to overwrite. + ;;; The file descriptor to overwrite. (param $to $fd_t) (result $error $errno_t) ) - ;; Move the offset of a file descriptor. - ;; Note: This is similar to `lseek` in POSIX. + ;;; Move the offset of a file descriptor. + ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") (param $fd $fd_t) - ;; The number of bytes to move. + ;;; The number of bytes to move. (param $offset $filedelta_t) - ;; The base from which the offset is relative. + ;;; The base from which the offset is relative. (param $whence $whence_t) (result $error $errno_t) - ;; The new offset of the file descriptor, relative to the start of the file. + ;;; The new offset of the file descriptor, relative to the start of the file. (result $newoffset $filesize_t) ) - ;; Synchronize the data and metadata of a file to disk. - ;; Note: This is similar to `fsync` in POSIX. + ;;; Synchronize the data and metadata of a file to disk. + ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Return the current offset of a file descriptor. - ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + ;;; Return the current offset of a file descriptor. + ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd_t) (result $error $errno_t) - ;; The current offset of the file descriptor, relative to the start of the file. + ;;; The current offset of the file descriptor, relative to the start of the file. (result $offset $filesize_t) ) - ;; Write to a file descriptor. - ;; Note: This is similar to `writev` in POSIX. + ;;; Write to a file descriptor. + ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Create a directory. - ;; Note: This is similar to `mkdirat` in POSIX. + ;;; Create a directory. + ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") (param $fd $fd_t) - ;; The path at which to create the directory. + ;;; The path at which to create the directory. (param $path string) (result $error $errno_t) ) - ;; Return the attributes of a file or directory. - ;; Note: This is similar to `stat` in POSIX. + ;;; Return the attributes of a file or directory. + ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to inspect. + ;;; The path of the file or directory to inspect. (param $path string) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the timestamps of a file or directory. - ;; Note: This is similar to `utimensat` in POSIX. + ;;; Adjust the timestamps of a file or directory. + ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to operate on. + ;;; The path of the file or directory to operate on. (param $path string) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Create a hard link. - ;; Note: This is similar to `linkat` in POSIX. + ;;; Create a hard link. + ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") (param $old_fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) - ;; The source path from which to link. + ;;; The source path from which to link. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path at which to create the hard link. + ;;; The destination path at which to create the hard link. (param $new_path string) (result $error $errno_t) ) - ;; Open a file or directory. + ;;; Open a file or directory. ;; - ;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;; file descriptor not currently open; it is randomized to prevent - ;; applications from depending on making assumptions about indexes, since this - ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 2**31. + ;;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;;; file descriptor not currently open; it is randomized to prevent + ;;; applications from depending on making assumptions about indexes, since this + ;;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;;; guaranteed to be less than 2**31. ;; - ;; Note: This is similar to `openat` in POSIX. + ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags_t) - ;; The relative path of the file or directory to open, relative to the - ;; `dirfd` directory. + ;;; The relative path of the file or directory to open, relative to the + ;;; `dirfd` directory. (param $path string) - ;; The method by which to open the file. + ;;; The method by which to open the file. (param $o_flags $oflags_t) - ;; The initial rights of the newly created file descriptor. The - ;; implementation is allowed to return a file descriptor with fewer rights - ;; than specified, if and only if those rights do not apply to the type of - ;; file being opened. + ;;; The initial rights of the newly created file descriptor. The + ;;; implementation is allowed to return a file descriptor with fewer rights + ;;; than specified, if and only if those rights do not apply to the type of + ;;; file being opened. ;; - ;; The *base* rights are rights that will apply to operations using the file - ;; descriptor itself, while the *inheriting* rights are rights that apply to - ;; file descriptors derived from it. + ;;; The *base* rights are rights that will apply to operations using the file + ;;; descriptor itself, while the *inheriting* rights are rights that apply to + ;;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) (param $flags $fdflags_t) (result $error $errno_t) - ;; The file descriptor of the file that has been opened. + ;;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) ) - ;; Read the contents of a symbolic link. - ;; Note: This is similar to `readlinkat` in POSIX. + ;;; Read the contents of a symbolic link. + ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") (param $fd $fd_t) - ;; The path of the symbolic link from which to read. + ;;; The path of the symbolic link from which to read. (param $path string) - ;; The buffer to which to write the contents of the symbolic link. + ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) - ;; The number of bytes placed in the buffer. + ;;; The number of bytes placed in the buffer. (result $bufused $size_t) ) - ;; Remove a directory. - ;; Return `ENOTEMPTY` if the directory is not empty. - ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + ;;; Remove a directory. + ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd_t) - ;; The path to a directory to remove. + ;;; The path to a directory to remove. (param $path string) (result $error $errno_t) ) - ;; Rename a file or directory. - ;; Note: This is similar to `renameat` in POSIX. + ;;; Rename a file or directory. + ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") (param $fd $fd_t) - ;; The source path of the file or directory to rename. + ;;; The source path of the file or directory to rename. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path to which to rename the file or directory. + ;;; The destination path to which to rename the file or directory. (param $new_path string) (result $error $errno_t) ) - ;; Create a symbolic link. - ;; Note: This is similar to `symlinkat` in POSIX. + ;;; Create a symbolic link. + ;;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - ;; The contents of the symbolic link. + ;;; The contents of the symbolic link. (param $old_path string) (param $fd $fd_t) - ;; The destination path at which to create the symbolic link. + ;;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) ) - ;; Unlink a file. - ;; Return `EISDIR` if the path refers to a directory. - ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + ;;; Unlink a file. + ;;; Return `EISDIR` if the path refers to a directory. + ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd_t) - ;; The path to a file to unlink. + ;;; The path to a file to unlink. (param $path string) (result $error $errno_t) ) - ;; Concurrently poll for the occurrence of a set of events. + ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") - ;; The events to which to subscribe. + ;;; The events to which to subscribe. (param $in (@witx const_pointer $subscription_t)) - ;; The events that have occurred. + ;;; The events that have occurred. (param $out (@witx pointer $event_t)) - ;; Both the number of subscriptions and events. + ;;; Both the number of subscriptions and events. (param $nsubscriptions $size_t) (result $error $errno_t) - ;; The number of events stored. + ;;; The number of events stored. (result $nevents $size_t) ) - ;; Terminate the process normally. An exit code of 0 indicates successful - ;; termination of the program. The meanings of other values is dependent on - ;; the environment. + ;;; Terminate the process normally. An exit code of 0 indicates successful + ;;; termination of the program. The meanings of other values is dependent on + ;;; the environment. (@interface func (export "proc_exit") - ;; The exit code returned by the process. + ;;; The exit code returned by the process. (param $rval $exitcode_t) ) - ;; Send a signal to the process of the calling thread. - ;; Note: This is similar to `raise` in POSIX. + ;;; Send a signal to the process of the calling thread. + ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") - ;; The signal condition to trigger. + ;;; The signal condition to trigger. (param $sig $signal_t) (result $error $errno_t) ) - ;; Temporarily yield execution of the calling thread. - ;; Note: This is similar to `sched_yield` in POSIX. + ;;; Temporarily yield execution of the calling thread. + ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") (result $error $errno_t) ) - ;; Write high-quality random data into a buffer. - ;; This function blocks when the implementation is unable to immediately - ;; provide sufficient high-quality random data. - ;; This function may execute slowly, so when large mounts of random data are - ;; required, it's advisable to use this function to seed a pseudo-random - ;; number generator, rather than to provide the random data directly. + ;;; Write high-quality random data into a buffer. + ;;; This function blocks when the implementation is unable to immediately + ;;; provide sufficient high-quality random data. + ;;; This function may execute slowly, so when large mounts of random data are + ;;; required, it's advisable to use this function to seed a pseudo-random + ;;; number generator, rather than to provide the random data directly. (@interface func (export "random_get") - ;; The buffer to fill with random data. + ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) ) - ;; Receive a message from a socket. - ;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;; the data into multiple buffers in the manner of `readv`. + ;;; Receive a message from a socket. + ;;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $ri_data $iovec_t_array) - ;; Message flags. + ;;; Message flags. (param $ri_flags $riflags_t) (result $error $errno_t) - ;; Number of bytes stored in ri_data. + ;;; Number of bytes stored in ri_data. (result $ro_datalen $size_t) - ;; Message flags. + ;;; Message flags. (result $ro_flags $roflags_t) ) - ;; Send a message on a socket. - ;; Note: This is similar to `send` in POSIX, though it also supports writing - ;; the data from multiple buffers in the manner of `writev`. + ;;; Send a message on a socket. + ;;; Note: This is similar to `send` in POSIX, though it also supports writing + ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to retrieve data + ;;; List of scatter/gather vectors to which to retrieve data (param $si_data $ciovec_t_array) - ;; Message flags. + ;;; Message flags. (param $si_flags $siflags_t) (result $error $errno_t) - ;; Number of bytes transmitted. + ;;; Number of bytes transmitted. (result $so_datalen $size_t) ) - ;; Shut down socket send and receive channels. - ;; Note: This is similar to `shutdown` in POSIX. + ;;; Shut down socket send and receive channels. + ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") (param $fd $fd_t) - ;; Which channels on the socket to shut down. + ;;; Which channels on the socket to shut down. (param $how $sdflags_t) (result $error $errno_t) ) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 62d5bf502..48c776ba9 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -120,6 +120,7 @@ pub enum DatatypeIdent { pub struct Datatype { pub name: Id, pub variant: DatatypeVariant, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -149,14 +150,26 @@ pub enum IntRepr { pub struct EnumDatatype { pub name: Id, pub repr: IntRepr, - pub variants: Vec, + pub variants: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct EnumVariant { + pub name: Id, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsDatatype { pub name: Id, pub repr: IntRepr, - pub flags: Vec, + pub flags: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FlagsMember { + pub name: Id, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -169,6 +182,7 @@ pub struct StructDatatype { pub struct StructMember { pub name: Id, pub type_: DatatypeIdent, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -181,6 +195,7 @@ pub struct UnionDatatype { pub struct UnionVariant { pub name: Id, pub type_: DatatypeIdent, + pub docs: String, } #[derive(Debug, Clone)] @@ -188,6 +203,7 @@ pub struct Module { pub name: Id, definitions: Vec, entries: HashMap, + pub docs: String, } impl Module { @@ -195,11 +211,13 @@ impl Module { name: Id, definitions: Vec, entries: HashMap, + docs: String, ) -> Self { Module { name, definitions, entries, + docs, } } pub fn import(&self, name: &Id) -> Option> { @@ -275,6 +293,7 @@ impl PartialEq for ModuleEntry { pub struct ModuleImport { pub name: Id, pub variant: ModuleImportVariant, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -287,6 +306,7 @@ pub struct InterfaceFunc { pub name: Id, pub params: Vec, pub results: Vec, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -294,6 +314,7 @@ pub struct InterfaceFuncParam { pub name: Id, pub type_: DatatypeIdent, pub position: InterfaceFuncParamPosition, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs new file mode 100644 index 000000000..532b3d902 --- /dev/null +++ b/proposals/random/tools/witx/src/docs.rs @@ -0,0 +1,227 @@ +use crate::ast::*; + +pub trait Documentation { + fn to_md(&self) -> String; +} + +impl Documentation for Document { + fn to_md(&self) -> String { + let mut ret = "# Types\n".to_string(); + for d in self.datatypes() { + ret += &d.to_md(); + } + + ret += "\n# Modules\n"; + for m in self.modules() { + ret += &m.to_md(); + } + ret + } +} + +impl BuiltinType { + fn name(&self) -> &'static str { + match self { + BuiltinType::String => "string", + BuiltinType::U8 => "u8", + BuiltinType::U16 => "u16", + BuiltinType::U32 => "u32", + BuiltinType::U64 => "u64", + BuiltinType::S8 => "s8", + BuiltinType::S16 => "s16", + BuiltinType::S32 => "s32", + BuiltinType::S64 => "s64", + BuiltinType::F32 => "f32", + BuiltinType::F64 => "f64", + } + } +} + +impl DatatypeIdent { + fn name(&self) -> String { + match self { + DatatypeIdent::Builtin(b) => b.name().to_string(), + DatatypeIdent::Array(a) => format!("Array<{}>", a.name()), + DatatypeIdent::Pointer(p) => format!("Pointer<{}>", p.name()), + DatatypeIdent::ConstPointer(p) => format!("ConstPointer<{}>", p.name()), + DatatypeIdent::Ident(i) => i.name.as_str().to_string(), + } + } +} + +impl Documentation for Datatype { + fn to_md(&self) -> String { + format!( + "## `{}`\n{}\n{}\n", + self.name.as_str(), + self.docs, + self.variant.to_md() + ) + } +} + +impl Documentation for DatatypeVariant { + fn to_md(&self) -> String { + match self { + DatatypeVariant::Alias(a) => a.to_md(), + DatatypeVariant::Enum(a) => a.to_md(), + DatatypeVariant::Flags(a) => a.to_md(), + DatatypeVariant::Struct(a) => a.to_md(), + DatatypeVariant::Union(a) => a.to_md(), + } + } +} + +impl Documentation for AliasDatatype { + fn to_md(&self) -> String { + format!("Alias to `{}`", self.to.name()) + } +} + +impl Documentation for EnumDatatype { + fn to_md(&self) -> String { + let variants = self + .variants + .iter() + .map(|v| format!("#### `{}`\n{}", v.name.as_str(), v.docs)) + .collect::>() + .join("\n"); + format!( + "Enum represented by `{}`\n\n### Variants:\n{}\n", + self.repr.name(), + variants + ) + } +} + +impl Documentation for FlagsDatatype { + fn to_md(&self) -> String { + let flags = self + .flags + .iter() + .map(|f| format!("#### `{}`\n{}\n", f.name.as_str(), f.docs)) + .collect::>() + .join("\n"); + format!( + "Flags represented by `{}`\n\n### Flags:\n{}", + self.repr.name(), + flags + ) + } +} + +impl Documentation for StructDatatype { + fn to_md(&self) -> String { + let members = self + .members + .iter() + .map(|m| { + format!( + "#### `{}`\nMember type: `{}`\n{}", + m.name.as_str(), + m.type_.name(), + m.docs, + ) + }) + .collect::>() + .join("\n"); + format!("### Struct members:\n{}", members) + } +} + +impl Documentation for UnionDatatype { + fn to_md(&self) -> String { + let variants = self + .variants + .iter() + .map(|v| { + format!( + "#### `{}`\nVariant type: `{}`\n{}", + v.name.as_str(), + v.type_.name(), + v.docs, + ) + }) + .collect::>() + .join("\n"); + format!("### Union variants:\n{}\n", variants) + } +} + +impl IntRepr { + fn name(&self) -> &'static str { + match self { + IntRepr::U8 => "u8", + IntRepr::U16 => "u16", + IntRepr::U32 => "u32", + IntRepr::U64 => "u64", + } + } +} + +impl Documentation for Module { + fn to_md(&self) -> String { + let imports = self + .imports() + .map(|i| i.to_md()) + .collect::>() + .join("\n"); + let funcs = self + .funcs() + .map(|i| i.to_md()) + .collect::>() + .join("\n"); + format!( + "## `{}`\n### Imports\n{}\n### Functions\n{}", + self.name.as_str(), + imports, + funcs, + ) + } +} + +impl Documentation for ModuleImport { + fn to_md(&self) -> String { + match self.variant { + ModuleImportVariant::Memory => format!("* {}: Memory", self.name.as_str()), + } + } +} + +impl Documentation for InterfaceFunc { + fn to_md(&self) -> String { + let params = self + .params + .iter() + .map(|f| { + format!( + "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", + name = f.name.as_str(), + type_ = f.type_.name(), + docs = f.docs + ) + }) + .collect::>() + .join("\n"); + let results = self + .results + .iter() + .map(|f| { + format!( + "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", + name = f.name.as_str(), + type_ = f.type_.name(), + docs = f.docs + ) + }) + .collect::>() + .join("\n"); + format!( + "### {}\n{}\n#### Parameters:\n{}#### Results:\n{}", + self.name.as_str(), + self.docs, + params, + results, + ) + } +} diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 3c2d945ec..60b0e0663 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -2,6 +2,8 @@ mod ast; /// Map witx types to core (wasm standard) types mod coretypes; +/// Render documentation +mod docs; /// Interface for filesystem or mock IO mod io; /// Witx syntax parsing from SExprs @@ -15,11 +17,12 @@ mod validate; pub use ast::{ AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, - InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, + Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, Id, IntRepr, InterfaceFunc, + InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, + ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; +pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; pub use render::{Render, SExpr as RenderSExpr}; diff --git a/proposals/random/tools/witx/src/main.rs b/proposals/random/tools/witx/src/main.rs index 8b1cab6ea..6251c3efa 100644 --- a/proposals/random/tools/witx/src/main.rs +++ b/proposals/random/tools/witx/src/main.rs @@ -1,12 +1,14 @@ -use clap::{App, Arg}; +use clap::{App, Arg, SubCommand}; +use std::fs::File; +use std::io::Write; use std::path::PathBuf; use std::process; -use witx::load; +use witx::{load, Documentation}; pub fn main() { let app = App::new("witx") .version(env!("CARGO_PKG_VERSION")) - .about("Validate witx file format") + .about("Validate and process witx files") .arg( Arg::with_name("input") .required(true) @@ -20,6 +22,17 @@ pub fn main() { .takes_value(false) .required(false), ) + .subcommand( + SubCommand::with_name("docs") + .about("Output documentation") + .arg( + Arg::with_name("output") + .short("o") + .long("output") + .takes_value(true) + .required(false), + ), + ) .get_matches(); let inputs = app @@ -34,6 +47,16 @@ pub fn main() { if app.is_present("verbose") { println!("{:?}", doc) } + + if let Some(subcommand) = app.subcommand_matches("docs") { + let md = doc.to_md(); + if let Some(output) = subcommand.value_of("output") { + let mut file = File::create(output).expect("create output file"); + file.write_all(md.as_bytes()).expect("write output file"); + } else { + println!("{}", md) + } + } } Err(e) => { println!("{}", e.report()); diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 9e699267e..77a1c0b03 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -1,3 +1,4 @@ +use wast::lexer::Comment; use wast::parser::{Cursor, Parse, Parser, Peek, Result}; ///! Parser turns s-expressions into unvalidated syntax constructs. @@ -96,6 +97,86 @@ impl Parse<'_> for BuiltinType { } } +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct CommentSyntax<'a> { + pub comments: Vec<&'a str>, +} + +impl<'a> Parse<'a> for CommentSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result> { + let comments = parser.step(|mut cursor| { + let mut comments = Vec::new(); + loop { + let (comment, c) = match cursor.comment() { + Some(pair) => pair, + None => break, + }; + cursor = c; + comments.push(match comment { + Comment::Block(s) => &s[2..s.len() - 2], + Comment::Line(s) => &s[2..], + }); + } + Ok((comments, cursor)) + })?; + Ok(CommentSyntax { comments }) + } +} + +impl<'a> CommentSyntax<'a> { + pub fn docs(&self) -> String { + // Perform a small amount of preprocessing by removing all trailing + // whitespace, and then also filter for only "doc comments" which are `;;;` + // or `(;; ... ;)`. + let docs = self + .comments + .iter() + .map(|d| d.trim_end()) + .filter_map(|d| { + if d.starts_with(";") { + Some(&d[1..]) + } else { + None + } + }) + .collect::>(); + + // Figure out how much leading whitespace we're going to be trimming from + // all docs, trimming the minimum amount in each doc comment. + let to_trim = docs + .iter() + .filter(|d| !d.is_empty()) + .map(|d| d.len() - d.trim().len()) + .min() + .unwrap_or(0); + + // Separate all documents by a newline and collect everything into a single + // string. + let mut ret = String::new(); + for doc in docs { + if !doc.is_empty() { + ret.push_str(doc[to_trim..].trim_end()); + } + ret.push_str("\n"); + } + return ret; + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct Documented<'a, T> { + pub comments: CommentSyntax<'a>, + pub item: T, +} + +impl<'a, T: Parse<'a>> Parse<'a> for Documented<'a, T> { + fn parse(parser: Parser<'a>) -> Result { + let comments = parser.parse()?; + let item = parser.parse()?; + Ok(Documented { comments, item }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum DatatypeIdentSyntax<'a> { Builtin(BuiltinType), @@ -179,14 +260,14 @@ impl Peek for AtInterface { #[derive(Debug, Clone, PartialEq, Eq)] pub struct TopLevelDocument<'a> { - pub items: Vec>, + pub items: Vec>>, } impl<'a> Parse<'a> for TopLevelDocument<'a> { fn parse(parser: Parser<'a>) -> Result { let mut items = Vec::new(); while !parser.is_empty() { - items.push(parser.parens(|p| p.parse())?); + items.push(parser.parse()?); } Ok(TopLevelDocument { items }) } @@ -200,12 +281,14 @@ pub enum TopLevelSyntax<'a> { impl<'a> Parse<'a> for TopLevelSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - if parser.peek::() { - parser.parse::()?; - Ok(TopLevelSyntax::Use(parser.parse()?)) - } else { - Ok(TopLevelSyntax::Decl(parser.parse()?)) - } + parser.parens(|p| { + if p.peek::() { + p.parse::()?; + Ok(TopLevelSyntax::Use(p.parse()?)) + } else { + Ok(TopLevelSyntax::Decl(p.parse()?)) + } + }) } } @@ -278,7 +361,7 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumSyntax<'a> { pub repr: BuiltinType, - pub members: Vec>, + pub members: Vec>>, } impl<'a> Parse<'a> for EnumSyntax<'a> { @@ -297,7 +380,7 @@ impl<'a> Parse<'a> for EnumSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsSyntax<'a> { pub repr: BuiltinType, - pub flags: Vec>, + pub flags: Vec>>, } impl<'a> Parse<'a> for FlagsSyntax<'a> { @@ -314,16 +397,16 @@ impl<'a> Parse<'a> for FlagsSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct StructSyntax<'a> { - pub fields: Vec>, + pub fields: Vec>>, } impl<'a> Parse<'a> for StructSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; let mut fields = Vec::new(); - fields.push(parser.parens(|p| p.parse())?); + fields.push(parser.parse()?); while !parser.is_empty() { - fields.push(parser.parens(|p| p.parse())?); + fields.push(parser.parse()?); } Ok(StructSyntax { fields }) } @@ -337,25 +420,27 @@ pub struct FieldSyntax<'a> { impl<'a> Parse<'a> for FieldSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let name = parser.parse()?; - let type_ = parser.parse()?; - Ok(FieldSyntax { name, type_ }) + parser.parens(|p| { + p.parse::()?; + let name = p.parse()?; + let type_ = p.parse()?; + Ok(FieldSyntax { name, type_ }) + }) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionSyntax<'a> { - pub fields: Vec>, + pub fields: Vec>>, } impl<'a> Parse<'a> for UnionSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; let mut fields = Vec::new(); - fields.push(parser.parens(|p| p.parse())?); + fields.push(parser.parse()?); while !parser.is_empty() { - fields.push(parser.parens(|p| p.parse())?); + fields.push(parser.parse()?); } Ok(UnionSyntax { fields }) } @@ -364,7 +449,7 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct ModuleSyntax<'a> { pub name: wast::Id<'a>, - pub decls: Vec>, + pub decls: Vec>>, } impl<'a> Parse<'a> for ModuleSyntax<'a> { @@ -373,7 +458,7 @@ impl<'a> Parse<'a> for ModuleSyntax<'a> { let name = parser.parse()?; let mut decls = Vec::new(); while !parser.is_empty() { - decls.push(parser.parens(|p| p.parse())?); + decls.push(parser.parse()?); } Ok(ModuleSyntax { name, decls }) } @@ -387,14 +472,16 @@ pub enum ModuleDeclSyntax<'a> { impl<'a> Parse<'a> for ModuleDeclSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(ModuleDeclSyntax::Import(parser.parse()?)) - } else if l.peek::() { - Ok(ModuleDeclSyntax::Func(parser.parse()?)) - } else { - Err(l.error()) - } + parser.parens(|p| { + let mut l = p.lookahead1(); + if l.peek::() { + Ok(ModuleDeclSyntax::Import(p.parse()?)) + } else if l.peek::() { + Ok(ModuleDeclSyntax::Func(p.parse()?)) + } else { + Err(l.error()) + } + }) } } @@ -442,8 +529,8 @@ impl Parse<'_> for ImportTypeSyntax { pub struct InterfaceFuncSyntax<'a> { pub export: &'a str, pub export_loc: wast::Span, - pub params: Vec>, - pub results: Vec>, + pub params: Vec>>, + pub results: Vec>>, } impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { @@ -460,25 +547,21 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { let mut results = Vec::new(); while !parser.is_empty() { - parser.parens(|p| { - let mut l = p.lookahead1(); - if l.peek::() { - parser.parse::()?; - params.push(FieldSyntax { - name: parser.parse()?, - type_: parser.parse()?, + let func_field = parser.parse::>()?; + match func_field.item { + InterfaceFuncField::Param(item) => { + params.push(Documented { + comments: func_field.comments, + item, }); - } else if l.peek::() { - parser.parse::()?; - results.push(FieldSyntax { - name: parser.parse()?, - type_: parser.parse()?, + } + InterfaceFuncField::Result(item) => { + results.push(Documented { + comments: func_field.comments, + item, }); - } else { - return Err(l.error()); } - Ok(()) - })?; + } } Ok(InterfaceFuncSyntax { @@ -490,6 +573,33 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { } } +enum InterfaceFuncField<'a> { + Param(FieldSyntax<'a>), + Result(FieldSyntax<'a>), +} +impl<'a> Parse<'a> for InterfaceFuncField<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parens(|p| { + let mut l = p.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(InterfaceFuncField::Param(FieldSyntax { + name: parser.parse()?, + type_: parser.parse()?, + })) + } else if l.peek::() { + parser.parse::()?; + Ok(InterfaceFuncField::Result(FieldSyntax { + name: parser.parse()?, + type_: parser.parse()?, + })) + } else { + Err(l.error()) + } + }) + } +} + impl PartialEq for InterfaceFuncSyntax<'_> { fn eq(&self, other: &InterfaceFuncSyntax<'_>) -> bool { // skip the `export_loc` field diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 8e23a5fa8..4bb7df729 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -21,6 +21,8 @@ pub enum SExpr { Quote(String), /// Short for Annotation Annot(String), + /// Doc comment + Docs(String, Box), } impl fmt::Display for SExpr { @@ -39,6 +41,7 @@ impl fmt::Display for SExpr { SExpr::Ident(i) => write!(f, "${}", i), SExpr::Quote(q) => write!(f, "\"{}\"", q), SExpr::Annot(a) => write!(f, "@{}", a), + SExpr::Docs(d, s) => write!(f, "(;; {} ;) {}", d, s), } } } @@ -56,6 +59,13 @@ impl SExpr { fn annot(s: &str) -> SExpr { SExpr::Annot(s.to_string()) } + fn docs(d: &str, s: SExpr) -> SExpr { + if d.is_empty() { + s + } else { + SExpr::Docs(d.to_string(), Box::new(s)) + } + } } pub trait Render { @@ -110,7 +120,10 @@ impl Render for Datatype { fn to_sexpr(&self) -> SExpr { let name = self.name.to_sexpr(); let body = self.variant.to_sexpr(); - SExpr::Vec(vec![SExpr::word("typename"), name, body]) + SExpr::docs( + &self.docs, + SExpr::Vec(vec![SExpr::word("typename"), name, body]), + ) } } @@ -138,7 +151,7 @@ impl Render for EnumDatatype { let variants = self .variants .iter() - .map(|v| v.to_sexpr()) + .map(|v| SExpr::docs(&v.docs, v.name.to_sexpr())) .collect::>(); SExpr::Vec([header, variants].concat()) } @@ -150,7 +163,7 @@ impl Render for FlagsDatatype { let flags = self .flags .iter() - .map(|f| f.to_sexpr()) + .map(|f| SExpr::docs(&f.docs, f.name.to_sexpr())) .collect::>(); SExpr::Vec([header, flags].concat()) } @@ -163,11 +176,14 @@ impl Render for StructDatatype { .members .iter() .map(|m| { - SExpr::Vec(vec![ - SExpr::word("field"), - m.name.to_sexpr(), - m.type_.to_sexpr(), - ]) + SExpr::docs( + &m.docs, + SExpr::Vec(vec![ + SExpr::word("field"), + m.name.to_sexpr(), + m.type_.to_sexpr(), + ]), + ) }) .collect::>(); SExpr::Vec([header, members].concat()) @@ -181,11 +197,14 @@ impl Render for UnionDatatype { .variants .iter() .map(|v| { - SExpr::Vec(vec![ - SExpr::word("field"), - v.name.to_sexpr(), - v.type_.to_sexpr(), - ]) + SExpr::docs( + &v.docs, + SExpr::Vec(vec![ + SExpr::word("field"), + v.name.to_sexpr(), + v.type_.to_sexpr(), + ]), + ) }) .collect::>(); SExpr::Vec([header, variants].concat()) @@ -211,7 +230,7 @@ impl Render for Module { .map(|i| i.to_sexpr()) .chain(self.funcs().map(|f| f.to_sexpr())) .collect::>(); - SExpr::Vec([header, definitions].concat()) + SExpr::docs(&self.docs, SExpr::Vec([header, definitions].concat())) } } @@ -220,11 +239,14 @@ impl Render for ModuleImport { let variant = match self.variant { ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), }; - SExpr::Vec(vec![ - SExpr::word("import"), - SExpr::quote(self.name.as_str()), - variant, - ]) + SExpr::docs( + &self.docs, + SExpr::Vec(vec![ + SExpr::word("import"), + SExpr::quote(self.name.as_str()), + variant, + ]), + ) } } @@ -242,24 +264,30 @@ impl Render for InterfaceFunc { .params .iter() .map(|f| { - SExpr::Vec(vec![ - SExpr::word("param"), - f.name.to_sexpr(), - f.type_.to_sexpr(), - ]) + SExpr::docs( + &f.docs, + SExpr::Vec(vec![ + SExpr::word("param"), + f.name.to_sexpr(), + f.type_.to_sexpr(), + ]), + ) }) .collect(); let results = self .results .iter() .map(|f| { - SExpr::Vec(vec![ - SExpr::word("result"), - f.name.to_sexpr(), - f.type_.to_sexpr(), - ]) + SExpr::docs( + &f.docs, + SExpr::Vec(vec![ + SExpr::word("result"), + f.name.to_sexpr(), + f.type_.to_sexpr(), + ]), + ) }) .collect(); - SExpr::Vec([header, params, results].concat()) + SExpr::docs(&self.docs, SExpr::Vec([header, params, results].concat())) } } diff --git a/proposals/random/tools/witx/src/toplevel.rs b/proposals/random/tools/witx/src/toplevel.rs index 281ad4757..2e0738a6b 100644 --- a/proposals/random/tools/witx/src/toplevel.rs +++ b/proposals/random/tools/witx/src/toplevel.rs @@ -58,11 +58,11 @@ fn parse_file( let doc = wast::parser::parse::(&buf).map_err(adjust_err)?; for t in doc.items { - match t { + match t.item { TopLevelSyntax::Decl(d) => { let def = validator .scope(&input, &path) - .validate_decl(&d) + .validate_decl(&d, &t.comments) .map_err(WitxError::Validation)?; definitions.push(def); } diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index a0d9ea96b..eba087e8c 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -1,13 +1,14 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ - DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, ImportTypeSyntax, - ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + CommentSyntax, DatatypeIdentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, + ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, - Definition, Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, - InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, + Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, Id, IntRepr, + InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, + ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, + UnionDatatype, UnionVariant, }; use failure::Fail; use std::collections::HashMap; @@ -158,10 +159,15 @@ impl DocValidationScope<'_> { self.doc.scope.get(name.name(), loc) } - pub fn validate_decl(&mut self, decl: &DeclSyntax) -> Result { + pub fn validate_decl( + &mut self, + decl: &DeclSyntax, + comments: &CommentSyntax, + ) -> Result { match decl { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; + let docs = comments.docs(); let variant = match &decl.def { TypedefSyntax::Ident(syntax) => DatatypeVariant::Alias(AliasDatatype { @@ -186,6 +192,7 @@ impl DocValidationScope<'_> { let rc_datatype = Rc::new(Datatype { name: name.clone(), variant, + docs, }); self.doc .entries @@ -205,6 +212,7 @@ impl DocValidationScope<'_> { name.clone(), definitions, module_validator.entries, + comments.docs(), )); self.doc .entries @@ -261,8 +269,12 @@ impl DocValidationScope<'_> { let variants = syntax .members .iter() - .map(|i| enum_scope.introduce(i.name(), self.location(i.span()))) - .collect::, _>>()?; + .map(|i| { + let name = enum_scope.introduce(i.item.name(), self.location(i.item.span()))?; + let docs = i.comments.docs(); + Ok(EnumVariant { name, docs }) + }) + .collect::, _>>()?; Ok(EnumDatatype { name: name.clone(), @@ -282,8 +294,12 @@ impl DocValidationScope<'_> { let flags = syntax .flags .iter() - .map(|i| flags_scope.introduce(i.name(), self.location(i.span()))) - .collect::, _>>()?; + .map(|i| { + let name = flags_scope.introduce(i.item.name(), self.location(i.item.span()))?; + let docs = i.comments.docs(); + Ok(FlagsMember { name, docs }) + }) + .collect::, _>>()?; Ok(FlagsDatatype { name: name.clone(), @@ -303,10 +319,11 @@ impl DocValidationScope<'_> { .fields .iter() .map(|f| { - Ok(StructMember { - name: member_scope.introduce(f.name.name(), self.location(f.name.span()))?, - type_: self.validate_datatype_ident(&f.type_)?, - }) + let name = member_scope + .introduce(f.item.name.name(), self.location(f.item.name.span()))?; + let type_ = self.validate_datatype_ident(&f.item.type_)?; + let docs = f.comments.docs(); + Ok(StructMember { name, type_, docs }) }) .collect::, _>>()?; @@ -327,10 +344,11 @@ impl DocValidationScope<'_> { .fields .iter() .map(|f| { - Ok(UnionVariant { - name: variant_scope.introduce(f.name.name(), self.location(f.name.span()))?, - type_: self.validate_datatype_ident(&f.type_)?, - }) + let name = variant_scope + .introduce(f.item.name.name(), self.location(f.item.name.span()))?; + let type_ = self.validate_datatype_ident(&f.item.type_)?; + let docs = f.comments.docs(); + Ok(UnionVariant { name, type_, docs }) }) .collect::, _>>()?; @@ -375,9 +393,9 @@ impl<'a> ModuleValidation<'a> { fn validate_decl( &mut self, - decl: &ModuleDeclSyntax, + decl: &Documented, ) -> Result { - match decl { + match &decl.item { ModuleDeclSyntax::Import(syntax) => { let loc = self.doc.location(syntax.name_loc); let name = self.scope.introduce(syntax.name, loc)?; @@ -387,6 +405,7 @@ impl<'a> ModuleValidation<'a> { let rc_import = Rc::new(ModuleImport { name: name.clone(), variant, + docs: decl.comments.docs(), }); self.entries .insert(name, ModuleEntry::Import(Rc::downgrade(&rc_import))); @@ -402,10 +421,13 @@ impl<'a> ModuleValidation<'a> { .enumerate() .map(|(ix, f)| { Ok(InterfaceFuncParam { - name: argnames - .introduce(f.name.name(), self.doc.location(f.name.span()))?, - type_: self.doc.validate_datatype_ident(&f.type_)?, + name: argnames.introduce( + f.item.name.name(), + self.doc.location(f.item.name.span()), + )?, + type_: self.doc.validate_datatype_ident(&f.item.type_)?, position: InterfaceFuncParamPosition::Param(ix), + docs: f.comments.docs(), }) }) .collect::, _>>()?; @@ -414,20 +436,23 @@ impl<'a> ModuleValidation<'a> { .iter() .enumerate() .map(|(ix, f)| { - let type_ = self.doc.validate_datatype_ident(&f.type_)?; + let type_ = self.doc.validate_datatype_ident(&f.item.type_)?; if ix == 0 { match type_.passed_by() { DatatypePassedBy::Value(_) => {} _ => Err(ValidationError::InvalidFirstResultType { - location: self.doc.location(f.name.span()), + location: self.doc.location(f.item.name.span()), })?, } } Ok(InterfaceFuncParam { - name: argnames - .introduce(f.name.name(), self.doc.location(f.name.span()))?, + name: argnames.introduce( + f.item.name.name(), + self.doc.location(f.item.name.span()), + )?, type_, position: InterfaceFuncParamPosition::Result(ix), + docs: f.comments.docs(), }) }) .collect::, _>>()?; @@ -436,6 +461,7 @@ impl<'a> ModuleValidation<'a> { name: name.clone(), params, results, + docs: decl.comments.docs(), }); self.entries .insert(name, ModuleEntry::Func(Rc::downgrade(&rc_func))); diff --git a/proposals/random/tools/witx/tests/wasi.rs b/proposals/random/tools/witx/tests/wasi.rs index b5a9d527c..aef954236 100644 --- a/proposals/random/tools/witx/tests/wasi.rs +++ b/proposals/random/tools/witx/tests/wasi.rs @@ -29,5 +29,31 @@ fn render_roundtrip() { .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) .unwrap(); + let back_to_sexprs = format!("{}", doc); + + let doc2 = witx::parse(&back_to_sexprs) + .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) + .unwrap(); + + // I'd just assert_eq, but when it fails the debug print is thousands of lines long and impossible + // to figure out where they are unequal. + if doc != doc2 { + for type_ in doc.datatypes() { + let type2 = doc2.datatype(&type_.name).expect("doc2 missing datatype"); + assert_eq!(type_, type2); + } + for mod_ in doc.modules() { + let mod2 = doc2.module(&mod_.name).expect("doc2 missing module"); + for import in mod_.imports() { + let import2 = mod2.import(&import.name).expect("mod2 missing import"); + assert_eq!(import, import2); + } + for func in mod_.funcs() { + let func2 = mod2.func(&func.name).expect("mod2 missing func"); + assert_eq!(func, func2); + } + } + } + // This should be equivelant to the above, but just in case some code changes where it isnt: assert_eq!(doc, doc2); } From 9d6bc5396c853daf43a34118b21f6bf63c49ca0a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 16:54:40 -0800 Subject: [PATCH 0294/1772] witx: Parse comments into documentation in AST (#140) * witx: add support for parsing multiple top-level witx files * tests: test parsing multiple top-level witx files * witx: add a multimodule test that rejects redefined names and rename the path to be a litle shorter * witx: add `CommentSyntax` and `Documented` parsers Derived from ca26654f7747e2c9ce9d80d05c23a4ed48ec126c in https://github.com/alexcrichton/wat (PR #26) * witx: Parse comments of top level definitions, render crude markdown * filter for doc comments, trim whitespace * some progress on doc comments. wip * more wip! * complete adding doc parsing to AST * bugfixes, use a subcommand to emit docs * witx: forgot to add docs to module. add docs to output for roundtrip testing * wasi documents: convert all comments to doc-comments sed -i -E "s/ ;; / ;;; /" **/*.witx sed -i -E "s/^;; /;;; /" **/*.witx * fix fd_advise doc comments to come before parameters * tests: try to narrow failure a bit * witx files: normalize leading whitespace in doc-comments this was stopping the roundtripping test from passing, since the whitespace in the AST is slightly different after a roundtrip. I am not feeling clever enough to think of an elegant solution now, so I'll just hack up these files to not hit the bug. * witx files: very top comment is not a doc --- .../phases/ephemeral/witx/typenames.witx | 678 ++++++++--------- .../witx/wasi_ephemeral_preview.witx | 413 +++++------ .../phases/old/snapshot_0/witx/typenames.witx | 678 ++++++++--------- .../old/snapshot_0/witx/wasi_unstable.witx | 419 +++++------ .../phases/snapshot/witx/typenames.witx | 680 +++++++++--------- .../snapshot/witx/wasi_snapshot_preview1.witx | 413 +++++------ proposals/filesystem/tools/witx/src/ast.rs | 25 +- proposals/filesystem/tools/witx/src/docs.rs | 227 ++++++ proposals/filesystem/tools/witx/src/lib.rs | 9 +- proposals/filesystem/tools/witx/src/main.rs | 29 +- proposals/filesystem/tools/witx/src/parser.rs | 206 ++++-- proposals/filesystem/tools/witx/src/render.rs | 88 ++- .../filesystem/tools/witx/src/toplevel.rs | 4 +- .../filesystem/tools/witx/src/validate.rs | 80 ++- proposals/filesystem/tools/witx/tests/wasi.rs | 26 + 15 files changed, 2224 insertions(+), 1751 deletions(-) create mode 100644 proposals/filesystem/tools/witx/src/docs.rs diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 1a45be1fd..a614d8528 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -7,291 +7,291 @@ (typename $size_t u32) -;; Non-negative file size or length of a region within a file. +;;; Non-negative file size or length of a region within a file. (typename $filesize_t u64) -;; Timestamp in nanoseconds. +;;; Timestamp in nanoseconds. (typename $timestamp_t u64) -;; Identifiers for clocks. +;;; Identifiers for clocks. (typename $clockid_t (enum u32 - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. + ;;; The clock measuring real time. Time value zero corresponds with + ;;; 1970-01-01T00:00:00Z. $CLOCK_REALTIME - ;; The store-wide monotonic clock, which is defined as a clock measuring - ;; real time, whose value cannot be adjusted and which cannot have negative - ;; clock jumps. The epoch of this clock is undefined. The absolute time - ;; value of this clock therefore has no meaning. + ;;; The store-wide monotonic clock, which is defined as a clock measuring + ;;; real time, whose value cannot be adjusted and which cannot have negative + ;;; clock jumps. The epoch of this clock is undefined. The absolute time + ;;; value of this clock therefore has no meaning. $CLOCK_MONOTONIC - ;; The CPU-time clock associated with the current process. + ;;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The CPU-time clock associated with the current thread. + ;;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) ) -;; Error codes returned by functions. -;; Not all of these error codes are returned by the functions provided by this -;; API; some are used in higher-level library layers, and others are provided -;; merely for alignment with POSIX. +;;; Error codes returned by functions. +;;; Not all of these error codes are returned by the functions provided by this +;;; API; some are used in higher-level library layers, and others are provided +;;; merely for alignment with POSIX. (typename $errno_t (enum u16 - ;; No error occurred. System call completed successfully. + ;;; No error occurred. System call completed successfully. $ESUCCESS - ;; Argument list too long. + ;;; Argument list too long. $E2BIG - ;; Permission denied. + ;;; Permission denied. $EACCES - ;; Address in use. + ;;; Address in use. $EADDRINUSE - ;; Address not available. + ;;; Address not available. $EADDRNOTAVAIL - ;; Address family not supported. + ;;; Address family not supported. $EAFNOSUPPORT - ;; Resource unavailable, or operation would block. + ;;; Resource unavailable, or operation would block. $EAGAIN - ;; Connection already in progress. + ;;; Connection already in progress. $EALREADY - ;; Bad file descriptor. + ;;; Bad file descriptor. $EBADF - ;; Bad message. + ;;; Bad message. $EBADMSG - ;; Device or resource busy. + ;;; Device or resource busy. $EBUSY - ;; Operation canceled. + ;;; Operation canceled. $ECANCELED - ;; No child processes. + ;;; No child processes. $ECHILD - ;; Connection aborted. + ;;; Connection aborted. $ECONNABORTED - ;; Connection refused. + ;;; Connection refused. $ECONNREFUSED - ;; Connection reset. + ;;; Connection reset. $ECONNRESET - ;; Resource deadlock would occur. + ;;; Resource deadlock would occur. $EDEADLK - ;; Destination address required. + ;;; Destination address required. $EDESTADDRREQ - ;; Mathematics argument out of domain of function. + ;;; Mathematics argument out of domain of function. $EDOM - ;; Reserved. + ;;; Reserved. $EDQUOT - ;; File exists. + ;;; File exists. $EEXIST - ;; Bad address. + ;;; Bad address. $EFAULT - ;; File too large. + ;;; File too large. $EFBIG - ;; Host is unreachable. + ;;; Host is unreachable. $EHOSTUNREACH - ;; Identifier removed. + ;;; Identifier removed. $EIDRM - ;; Illegal byte sequence. + ;;; Illegal byte sequence. $EILSEQ - ;; Operation in progress. + ;;; Operation in progress. $EINPROGRESS - ;; Interrupted function. + ;;; Interrupted function. $EINTR - ;; Invalid argument. + ;;; Invalid argument. $EINVAL - ;; I/O error. + ;;; I/O error. $EIO - ;; Socket is connected. + ;;; Socket is connected. $EISCONN - ;; Is a directory. + ;;; Is a directory. $EISDIR - ;; Too many levels of symbolic links. + ;;; Too many levels of symbolic links. $ELOOP - ;; File descriptor value too large. + ;;; File descriptor value too large. $EMFILE - ;; Too many links. + ;;; Too many links. $EMLINK - ;; Message too large. + ;;; Message too large. $EMSGSIZE - ;; Reserved. + ;;; Reserved. $EMULTIHOP - ;; Filename too long. + ;;; Filename too long. $ENAMETOOLONG - ;; Network is down. + ;;; Network is down. $ENETDOWN - ;; Connection aborted by network. + ;;; Connection aborted by network. $ENETRESET - ;; Network unreachable. + ;;; Network unreachable. $ENETUNREACH - ;; Too many files open in system. + ;;; Too many files open in system. $ENFILE - ;; No buffer space available. + ;;; No buffer space available. $ENOBUFS - ;; No such device. + ;;; No such device. $ENODEV - ;; No such file or directory. + ;;; No such file or directory. $ENOENT - ;; Executable file format error. + ;;; Executable file format error. $ENOEXEC - ;; No locks available. + ;;; No locks available. $ENOLCK - ;; Reserved. + ;;; Reserved. $ENOLINK - ;; Not enough space. + ;;; Not enough space. $ENOMEM - ;; No message of the desired type. + ;;; No message of the desired type. $ENOMSG - ;; Protocol not available. + ;;; Protocol not available. $ENOPROTOOPT - ;; No space left on device. + ;;; No space left on device. $ENOSPC - ;; Function not supported. + ;;; Function not supported. $ENOSYS - ;; The socket is not connected. + ;;; The socket is not connected. $ENOTCONN - ;; Not a directory or a symbolic link to a directory. + ;;; Not a directory or a symbolic link to a directory. $ENOTDIR - ;; Directory not empty. + ;;; Directory not empty. $ENOTEMPTY - ;; State not recoverable. + ;;; State not recoverable. $ENOTRECOVERABLE - ;; Not a socket. + ;;; Not a socket. $ENOTSOCK - ;; Not supported, or operation not supported on socket. + ;;; Not supported, or operation not supported on socket. $ENOTSUP - ;; Inappropriate I/O control operation. + ;;; Inappropriate I/O control operation. $ENOTTY - ;; No such device or address. + ;;; No such device or address. $ENXIO - ;; Value too large to be stored in data type. + ;;; Value too large to be stored in data type. $EOVERFLOW - ;; Previous owner died. + ;;; Previous owner died. $EOWNERDEAD - ;; Operation not permitted. + ;;; Operation not permitted. $EPERM - ;; Broken pipe. + ;;; Broken pipe. $EPIPE - ;; Protocol error. + ;;; Protocol error. $EPROTO - ;; Protocol not supported. + ;;; Protocol not supported. $EPROTONOSUPPORT - ;; Protocol wrong type for socket. + ;;; Protocol wrong type for socket. $EPROTOTYPE - ;; Result too large. + ;;; Result too large. $ERANGE - ;; Read-only file system. + ;;; Read-only file system. $EROFS - ;; Invalid seek. + ;;; Invalid seek. $ESPIPE - ;; No such process. + ;;; No such process. $ESRCH - ;; Reserved. + ;;; Reserved. $ESTALE - ;; Connection timed out. + ;;; Connection timed out. $ETIMEDOUT - ;; Text file busy. + ;;; Text file busy. $ETXTBSY - ;; Cross-device link. + ;;; Cross-device link. $EXDEV - ;; Extension: Capabilities insufficient. + ;;; Extension: Capabilities insufficient. $ENOTCAPABLE ) ) -;; File descriptor rights, determining which actions may be performed. +;;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke `fd_datasync`. + ;;; The right to invoke `fd_datasync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_DSYNC`. $RIGHT_FD_DATASYNC - ;; The right to invoke `fd_read` and `sock_recv`. + ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. $RIGHT_FD_READ - ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. $RIGHT_FD_SEEK - ;; The right to invoke `fd_fdstat_set_flags`. + ;;; The right to invoke `fd_fdstat_set_flags`. $RIGHT_FD_FDSTAT_SET_FLAGS - ;; The right to invoke `fd_sync`. + ;;; The right to invoke `fd_sync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. $RIGHT_FD_SYNC - ;; The right to invoke `fd_seek` in such a way that the file offset - ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to - ;; invoke `fd_tell`. + ;;; The right to invoke `fd_seek` in such a way that the file offset + ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; invoke `fd_tell`. $RIGHT_FD_TELL - ;; The right to invoke `fd_write` and `sock_send`. - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + ;;; The right to invoke `fd_write` and `sock_send`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. $RIGHT_FD_WRITE - ;; The right to invoke `fd_advise`. + ;;; The right to invoke `fd_advise`. $RIGHT_FD_ADVISE - ;; The right to invoke `fd_allocate`. + ;;; The right to invoke `fd_allocate`. $RIGHT_FD_ALLOCATE - ;; The right to invoke `path_create_directory`. + ;;; The right to invoke `path_create_directory`. $RIGHT_PATH_CREATE_DIRECTORY - ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. $RIGHT_PATH_CREATE_FILE - ;; The right to invoke `path_link` with the file descriptor as the - ;; source directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; source directory. $RIGHT_PATH_LINK_SOURCE - ;; The right to invoke `path_link` with the file descriptor as the - ;; target directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; target directory. $RIGHT_PATH_LINK_TARGET - ;; The right to invoke `path_open`. + ;;; The right to invoke `path_open`. $RIGHT_PATH_OPEN - ;; The right to invoke `fd_readdir`. + ;;; The right to invoke `fd_readdir`. $RIGHT_FD_READDIR - ;; The right to invoke `path_readlink`. + ;;; The right to invoke `path_readlink`. $RIGHT_PATH_READLINK - ;; The right to invoke `path_rename` with the file descriptor as the source directory. + ;;; The right to invoke `path_rename` with the file descriptor as the source directory. $RIGHT_PATH_RENAME_SOURCE - ;; The right to invoke `path_rename` with the file descriptor as the target directory. + ;;; The right to invoke `path_rename` with the file descriptor as the target directory. $RIGHT_PATH_RENAME_TARGET - ;; The right to invoke `path_filestat_get`. + ;;; The right to invoke `path_filestat_get`. $RIGHT_PATH_FILESTAT_GET - ;; The right to change a file's size (there is no `path_filestat_set_size`). - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + ;;; The right to change a file's size (there is no `path_filestat_set_size`). + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. $RIGHT_PATH_FILESTAT_SET_SIZE - ;; The right to invoke `path_filestat_set_times`. + ;;; The right to invoke `path_filestat_set_times`. $RIGHT_PATH_FILESTAT_SET_TIMES - ;; The right to invoke `fd_filestat_get`. + ;;; The right to invoke `fd_filestat_get`. $RIGHT_FD_FILESTAT_GET - ;; The right to invoke `fd_filestat_set_size`. + ;;; The right to invoke `fd_filestat_set_size`. $RIGHT_FD_FILESTAT_SET_SIZE - ;; The right to invoke `fd_filestat_set_times`. + ;;; The right to invoke `fd_filestat_set_times`. $RIGHT_FD_FILESTAT_SET_TIMES - ;; The right to invoke `path_symlink`. + ;;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_remove_directory`. + ;;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY - ;; The right to invoke `path_unlink_file`. + ;;; The right to invoke `path_unlink_file`. $RIGHT_PATH_UNLINK_FILE - ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE - ;; The right to invoke `sock_shutdown`. + ;;; The right to invoke `sock_shutdown`. $RIGHT_SOCK_SHUTDOWN ) ) -;; A file descriptor index. +;;; A file descriptor index. (typename $fd_t u32) -;; A region of memory for scatter/gather reads. +;;; A region of memory for scatter/gather reads. (typename $iovec_t (struct - ;; The address of the buffer to be filled. + ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) - ;; The length of the buffer to be filled. + ;;; The length of the buffer to be filled. (field $buf_len $size_t) ) ) -;; A region of memory for scatter/gather writes. +;;; A region of memory for scatter/gather writes. (typename $ciovec_t (struct - ;; The address of the buffer to be written. + ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) - ;; The length of the buffer to be written. + ;;; The length of the buffer to be written. (field $buf_len $size_t) ) ) @@ -299,469 +299,469 @@ (typename $iovec_t_array (array $iovec_t)) (typename $ciovec_t_array (array $ciovec_t)) -;; Relative offset within a file. +;;; Relative offset within a file. (typename $filedelta_t s64) -;; The position relative to which to set the offset of the file descriptor. +;;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 - ;; Seek relative to start-of-file. + ;;; Seek relative to start-of-file. $WHENCE_SET - ;; Seek relative to current position. + ;;; Seek relative to current position. $WHENCE_CUR - ;; Seek relative to end-of-file. + ;;; Seek relative to end-of-file. $WHENCE_END ) ) -;; A reference to the offset of a directory entry. +;;; A reference to the offset of a directory entry. ;; -;; The value 0 signifies the start of the directory. +;;; The value 0 signifies the start of the directory. (typename $dircookie_t u64) -;; The type for the $d_namlen field of $dirent_t. +;;; The type for the $d_namlen field of $dirent_t. (typename $dirnamlen_t u32) -;; File serial number that is unique within its file system. +;;; File serial number that is unique within its file system. (typename $inode_t u64) -;; The type of a file descriptor or file. +;;; The type of a file descriptor or file. (typename $filetype_t (enum u8 - ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $FILETYPE_UNKNOWN - ;; The file descriptor or file refers to a block device inode. + ;;; The file descriptor or file refers to a block device inode. $FILETYPE_BLOCK_DEVICE - ;; The file descriptor or file refers to a character device inode. + ;;; The file descriptor or file refers to a character device inode. $FILETYPE_CHARACTER_DEVICE - ;; The file descriptor or file refers to a directory inode. + ;;; The file descriptor or file refers to a directory inode. $FILETYPE_DIRECTORY - ;; The file descriptor or file refers to a regular file inode. + ;;; The file descriptor or file refers to a regular file inode. $FILETYPE_REGULAR_FILE - ;; The file descriptor or file refers to a datagram socket. + ;;; The file descriptor or file refers to a datagram socket. $FILETYPE_SOCKET_DGRAM - ;; The file descriptor or file refers to a byte-stream socket. + ;;; The file descriptor or file refers to a byte-stream socket. $FILETYPE_SOCKET_STREAM - ;; The file refers to a symbolic link inode. + ;;; The file refers to a symbolic link inode. $FILETYPE_SYMBOLIC_LINK ) ) -;; A directory entry. +;;; A directory entry. (typename $dirent_t (struct - ;; The offset of the next directory entry stored in this directory. + ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie_t) - ;; The serial number of the file referred to by this directory entry. + ;;; The serial number of the file referred to by this directory entry. (field $d_ino $inode_t) - ;; The length of the name of the directory entry. + ;;; The length of the name of the directory entry. (field $d_namlen $dirnamlen_t) - ;; The type of the file referred to by this directory entry. + ;;; The type of the file referred to by this directory entry. (field $d_type $filetype_t) ) ) -;; File or memory access pattern advisory information. +;;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application has no advice to give on its behavior with respect to the specified data. + ;;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL - ;; The application expects to access the specified data in a random order. + ;;; The application expects to access the specified data in a random order. $ADVICE_RANDOM - ;; The application expects to access the specified data in the near future. + ;;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED - ;; The application expects that it will not access the specified data in the near future. + ;;; The application expects that it will not access the specified data in the near future. $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. + ;;; The application expects to access the specified data once and then not reuse it thereafter. $ADVICE_NOREUSE ) ) -;; File descriptor flags. +;;; File descriptor flags. (typename $fdflags_t (flags u16 - ;; Append mode: Data written to the file is always appended to the file's end. + ;;; Append mode: Data written to the file is always appended to the file's end. $FDFLAG_APPEND - ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. $FDFLAG_DSYNC - ;; Non-blocking mode. + ;;; Non-blocking mode. $FDFLAG_NONBLOCK - ;; Synchronized read I/O operations. + ;;; Synchronized read I/O operations. $FDFLAG_RSYNC - ;; Write according to synchronized I/O file integrity completion. In - ;; addition to synchronizing the data stored in the file, the implementation - ;; may also synchronously update the file's metadata. + ;;; Write according to synchronized I/O file integrity completion. In + ;;; addition to synchronizing the data stored in the file, the implementation + ;;; may also synchronously update the file's metadata. $FDFLAG_SYNC ) ) -;; File descriptor attributes. +;;; File descriptor attributes. (typename $fdstat_t (struct - ;; File type. + ;;; File type. (field $fs_filetype $filetype_t) - ;; File descriptor flags. + ;;; File descriptor flags. (field $fs_flags $fdflags_t) - ;; Rights that apply to this file descriptor. + ;;; Rights that apply to this file descriptor. (field $fs_rights_base $rights_t) - ;; Maximum set of rights that may be installed on new file descriptors that - ;; are created through this file descriptor, e.g., through `path_open`. + ;;; Maximum set of rights that may be installed on new file descriptors that + ;;; are created through this file descriptor, e.g., through `path_open`. (field $fs_rights_inheriting $rights_t) ) ) -;; Identifier for a device containing a file system. Can be used in combination -;; with `inode_t` to uniquely identify a file or directory in the filesystem. +;;; Identifier for a device containing a file system. Can be used in combination +;;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) -;; Which file time attributes to adjust. +;;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 - ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. $FILESTAT_SET_ATIM - ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_ATIM_NOW - ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. $FILESTAT_SET_MTIM - ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_MTIM_NOW ) ) -;; Flags determining the method of how paths are resolved. +;;; Flags determining the method of how paths are resolved. (typename $lookupflags_t (flags u32 - ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $LOOKUP_SYMLINK_FOLLOW ) ) -;; Open flags used by `path_open`. +;;; Open flags used by `path_open`. (typename $oflags_t (flags u16 - ;; Create file if it does not exist. + ;;; Create file if it does not exist. $O_CREAT - ;; Fail if not a directory. + ;;; Fail if not a directory. $O_DIRECTORY - ;; Fail if file already exists. + ;;; Fail if file already exists. $O_EXCL - ;; Truncate file to size 0. + ;;; Truncate file to size 0. $O_TRUNC ) ) -;; Number of hard links to an inode. +;;; Number of hard links to an inode. (typename $linkcount_t u64) -;; File attributes. +;;; File attributes. (typename $filestat_t (struct - ;; Device ID of device containing the file. + ;;; Device ID of device containing the file. (field $st_dev $device_t) - ;; File serial number. + ;;; File serial number. (field $st_ino $inode_t) - ;; File type. + ;;; File type. (field $st_filetype $filetype_t) - ;; Number of hard links to the file. + ;;; Number of hard links to the file. (field $st_nlink $linkcount_t) - ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. (field $st_size $filesize_t) - ;; Last data access timestamp. + ;;; Last data access timestamp. (field $st_atim $timestamp_t) - ;; Last data modification timestamp. + ;;; Last data modification timestamp. (field $st_mtim $timestamp_t) - ;; Last file status change timestamp. + ;;; Last file status change timestamp. (field $st_ctim $timestamp_t) ) ) -;; User-provided value that may be attached to objects that is retained when -;; extracted from the implementation. +;;; User-provided value that may be attached to objects that is retained when +;;; extracted from the implementation. (typename $userdata_t u64) -;; Type of a subscription to an event or its occurrence. +;;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (enum u8 - ;; The time value of clock `subscription_t::u.clock.clock_id` has - ;; reached timestamp `subscription_t::u.clock.timeout`. + ;;; The time value of clock `subscription_t::u.clock.clock_id` has + ;;; reached timestamp `subscription_t::u.clock.timeout`. $EVENTTYPE_CLOCK - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data - ;; available for reading. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; available for reading. This event always triggers for regular files. $EVENTTYPE_FD_READ - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity - ;; available for writing. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;;; available for writing. This event always triggers for regular files. $EVENTTYPE_FD_WRITE ) ) -;; The state of the file descriptor subscribed to with -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The state of the file descriptor subscribed to with +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 - ;; The peer of this socket has closed or disconnected. + ;;; The peer of this socket has closed or disconnected. $EVENT_FD_READWRITE_HANGUP ) ) -;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;; `EVENTTYPE_FD_WRITE`. +;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;;; `EVENTTYPE_FD_WRITE`. (typename $event_fd_readwrite_t (struct - ;; The number of bytes available for reading or writing. + ;;; The number of bytes available for reading or writing. (field $nbytes $filesize_t) - ;; The state of the file descriptor. + ;;; The state of the file descriptor. (field $flags $eventrwflags_t) ) ) -;; The contents of an $event_t. +;;; The contents of an $event_t. (typename $event_u (union - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; An event that occurred. +;;; An event that occurred. (typename $event_t (struct - ;; User-provided value that got attached to `subscription_t::userdata`. + ;;; User-provided value that got attached to `subscription_t::userdata`. (field $userdata $userdata_t) - ;; If non-zero, an error that occurred while processing the subscription request. + ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno_t) - ;; The type of the event that occurred. + ;;; The type of the event that occurred. (field $type $eventtype_t) - ;; The contents of the event. + ;;; The contents of the event. (field $u $event_u) ) ) -;; Flags determining how to interpret the timestamp provided in -;; `subscription_t::u.clock.timeout.` +;;; Flags determining how to interpret the timestamp provided in +;;; `subscription_t::u.clock.timeout.` (typename $subclockflags_t (flags u16 - ;; If set, treat the timestamp provided in - ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;; provided in `subscription_t::u.clock.timeout` relative to the - ;; current time value of clock `subscription_t::u.clock.clock_id.` + ;;; If set, treat the timestamp provided in + ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription_t::u.clock.timeout` relative to the + ;;; current time value of clock `subscription_t::u.clock.clock_id.` $SUBSCRIPTION_CLOCK_ABSTIME ) ) -;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The clock against which to compare the timestamp. + ;;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. + ;;; The absolute or relative timestamp. (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. + ;;; The amount of time that the implementation may wait additionally + ;;; to coalesce with other events. (field $precision $timestamp_t) - ;; Flags specifying whether the timeout is absolute or relative + ;;; Flags specifying whether the timeout is absolute or relative (field $flags $subclockflags_t) ) ) -;; The contents of a $subscription_t when type is type is -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The contents of a $subscription_t when type is type is +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $subscription_fd_readwrite_t (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. + ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd_t) ) ) -;; The contents of a $subscription_t. +;;; The contents of a $subscription_t. (typename $subscription_u (union - ;; When type is `EVENTTYPE_CLOCK`: + ;;; When type is `EVENTTYPE_CLOCK`: (field $clock $subscription_clock_t) - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $subscription_fd_readwrite_t) ) ) -;; Subscription to an event. +;;; Subscription to an event. (typename $subscription_t (struct - ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through `event_t::userdata`. + ;;; User-provided value that is attached to the subscription in the + ;;; implementation and returned through `event_t::userdata`. (field $userdata $userdata_t) - ;; The type of the event to which to subscribe. + ;;; The type of the event to which to subscribe. (field $type $eventtype_t) - ;; The contents of the subscription. + ;;; The contents of the subscription. (field $u $subscription_u) ) ) -;; Exit code generated by a process when exiting. +;;; Exit code generated by a process when exiting. (typename $exitcode_t u32) -;; Signal condition. +;;; Signal condition. (typename $signal_t (enum u8 - ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;; so this value is reserved. + ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;;; so this value is reserved. $SIGNONE - ;; Hangup. - ;; Action: Terminates the process. + ;;; Hangup. + ;;; Action: Terminates the process. $SIGHUP - ;; Terminate interrupt signal. - ;; Action: Terminates the process. + ;;; Terminate interrupt signal. + ;;; Action: Terminates the process. $SIGINT - ;; Terminal quit signal. - ;; Action: Terminates the process. + ;;; Terminal quit signal. + ;;; Action: Terminates the process. $SIGQUIT - ;; Illegal instruction. - ;; Action: Terminates the process. + ;;; Illegal instruction. + ;;; Action: Terminates the process. $SIGILL - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. + ;;; Trace/breakpoint trap. + ;;; Action: Terminates the process. $SIGTRAP - ;; Process abort signal. - ;; Action: Terminates the process. + ;;; Process abort signal. + ;;; Action: Terminates the process. $SIGABRT - ;; Access to an undefined portion of a memory object. - ;; Action: Terminates the process. + ;;; Access to an undefined portion of a memory object. + ;;; Action: Terminates the process. $SIGBUS - ;; Erroneous arithmetic operation. - ;; Action: Terminates the process. + ;;; Erroneous arithmetic operation. + ;;; Action: Terminates the process. $SIGFPE - ;; Kill. - ;; Action: Terminates the process. + ;;; Kill. + ;;; Action: Terminates the process. $SIGKILL - ;; User-defined signal 1. - ;; Action: Terminates the process. + ;;; User-defined signal 1. + ;;; Action: Terminates the process. $SIGUSR1 - ;; Invalid memory reference. - ;; Action: Terminates the process. + ;;; Invalid memory reference. + ;;; Action: Terminates the process. $SIGSEGV - ;; User-defined signal 2. - ;; Action: Terminates the process. + ;;; User-defined signal 2. + ;;; Action: Terminates the process. $SIGUSR2 - ;; Write on a pipe with no one to read it. - ;; Action: Ignored. + ;;; Write on a pipe with no one to read it. + ;;; Action: Ignored. $SIGPIPE - ;; Alarm clock. - ;; Action: Terminates the process. + ;;; Alarm clock. + ;;; Action: Terminates the process. $SIGALRM - ;; Termination signal. - ;; Action: Terminates the process. + ;;; Termination signal. + ;;; Action: Terminates the process. $SIGTERM - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. + ;;; Child process terminated, stopped, or continued. + ;;; Action: Ignored. $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. + ;;; Continue executing, if stopped. + ;;; Action: Continues executing, if stopped. $SIGCONT - ;; Stop executing. - ;; Action: Stops executing. + ;;; Stop executing. + ;;; Action: Stops executing. $SIGSTOP - ;; Terminal stop signal. - ;; Action: Stops executing. + ;;; Terminal stop signal. + ;;; Action: Stops executing. $SIGTSTP - ;; Background process attempting read. - ;; Action: Stops executing. + ;;; Background process attempting read. + ;;; Action: Stops executing. $SIGTTIN - ;; Background process attempting write. - ;; Action: Stops executing. + ;;; Background process attempting write. + ;;; Action: Stops executing. $SIGTTOU - ;; High bandwidth data is available at a socket. - ;; Action: Ignored. + ;;; High bandwidth data is available at a socket. + ;;; Action: Ignored. $SIGURG - ;; CPU time limit exceeded. - ;; Action: Terminates the process. + ;;; CPU time limit exceeded. + ;;; Action: Terminates the process. $SIGXCPU - ;; File size limit exceeded. - ;; Action: Terminates the process. + ;;; File size limit exceeded. + ;;; Action: Terminates the process. $SIGXFSZ - ;; Virtual timer expired. - ;; Action: Terminates the process. + ;;; Virtual timer expired. + ;;; Action: Terminates the process. $SIGVTALRM - ;; Profiling timer expired. - ;; Action: Terminates the process. + ;;; Profiling timer expired. + ;;; Action: Terminates the process. $SIGPROF - ;; Window changed. - ;; Action: Ignored. + ;;; Window changed. + ;;; Action: Ignored. $SIGWINCH - ;; I/O possible. - ;; Action: Terminates the process. + ;;; I/O possible. + ;;; Action: Terminates the process. $SIGPOLL - ;; Power failure. - ;; Action: Terminates the process. + ;;; Power failure. + ;;; Action: Terminates the process. $SIGPWR - ;; Bad system call. - ;; Action: Terminates the process. + ;;; Bad system call. + ;;; Action: Terminates the process. $SIGSYS ) ) -;; Flags provided to `sock_recv`. +;;; Flags provided to `sock_recv`. (typename $riflags_t (flags u16 - ;; Returns the message without removing it from the socket's receive queue. + ;;; Returns the message without removing it from the socket's receive queue. $SOCK_RECV_PEEK - ;; On byte-stream sockets, block until the full amount of data can be returned. + ;;; On byte-stream sockets, block until the full amount of data can be returned. $SOCK_RECV_WAITALL ) ) -;; Flags returned by `sock_recv`. +;;; Flags returned by `sock_recv`. (typename $roflags_t (flags u16 - ;; Returned by `sock_recv`: Message data has been truncated. + ;;; Returned by `sock_recv`: Message data has been truncated. $SOCK_RECV_DATA_TRUNCATED ) ) -;; Flags provided to `sock_send`. As there are currently no flags -;; defined, it must be set to zero. +;;; Flags provided to `sock_send`. As there are currently no flags +;;; defined, it must be set to zero. (typename $siflags_t u16) -;; Which channels on a socket to shut down. +;;; Which channels on a socket to shut down. (typename $sdflags_t (flags u8 - ;; Disables further receive operations. + ;;; Disables further receive operations. $SHUT_RD - ;; Disables further send operations. + ;;; Disables further send operations. $SHUT_WR ) ) -;; Identifiers for preopened capabilities. +;;; Identifiers for preopened capabilities. (typename $preopentype_t (enum u8 - ;; A pre-opened directory. + ;;; A pre-opened directory. $PREOPENTYPE_DIR ) ) -;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. (typename $prestat_dir (struct - ;; The length of the directory name for use with `fd_prestat_dir_name`. + ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size_t) ) ) -;; The contents of an $prestat_t. +;;; The contents of an $prestat_t. (typename $prestat_u (union - ;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `PREOPENTYPE_DIR`: (field $dir $prestat_dir) ) ) -;; Information about a pre-opened capability. +;;; Information about a pre-opened capability. (typename $prestat_t (struct - ;; The type of the pre-opened capability. + ;;; The type of the pre-opened capability. (field $pr_type $preopentype_t) - ;; The contents of the information. + ;;; The contents of the information. (field $u $prestat_u) ) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx index f98ff129b..d15b8c514 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -9,519 +9,522 @@ (use "typenames.witx") (module $wasi_ephemeral_preview - ;; Linear memory to be accessed by WASI functions that need it. + ;;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) - ;; Read command-line argument data. - ;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; Read command-line argument data. + ;;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Read environment variable data. - ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; Read environment variable data. + ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Return the resolution of a clock. - ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;; Note: This is similar to `clock_getres` in POSIX. + ;;; Return the resolution of a clock. + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno_t) - ;; The clock for which to return the resolution. + ;;; The clock for which to return the resolution. (param $clock_id $clockid_t) - ;; The resolution of the clock. + ;;; The resolution of the clock. (result $resolution $timestamp_t) ) - ;; Return the time value of a clock. - ;; Note: This is similar to `clock_gettime` in POSIX. + ;;; Return the time value of a clock. + ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") - ;; The clock for which to return the time. + ;;; The clock for which to return the time. (param $clock_id $clockid_t) - ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp_t) (result $error $errno_t) - ;; The time value of the clock. + ;;; The time value of the clock. (result $time $timestamp_t) ) - ;; Provide file advisory information on a file descriptor. - ;; Note: This is similar to `posix_fadvise` in POSIX. + ;;; Provide file advisory information on a file descriptor. + ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") (param $fd $fd_t) - (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. - (param $len $filesize_t) ;; The length of the region to which the advisory applies. - (param $advice $advice_t) ;; The advice. + ;;; The offset within the file to which the advisory applies. + (param $offset $filesize_t) + ;;; The length of the region to which the advisory applies. + (param $len $filesize_t) + ;;; The advice. + (param $advice $advice_t) (result $error $errno_t) ) - ;; Force the allocation of space in a file. - ;; Note: This is similar to `posix_fallocate` in POSIX. + ;;; Force the allocation of space in a file. + ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") (param $fd $fd_t) - ;; The offset at which to start the allocation. + ;;; The offset at which to start the allocation. (param $offset $filesize_t) - ;; The length of the area that is allocated. + ;;; The length of the area that is allocated. (param $len $filesize_t) (result $error $errno_t) ) - ;; Close a file descriptor. - ;; Note: This is similar to `close` in POSIX. + ;;; Close a file descriptor. + ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd_t) (result $error $errno_t) ) - ;; Synchronize the data of a file to disk. - ;; Note: This is similar to `fdatasync` in POSIX. + ;;; Synchronize the data of a file to disk. + ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Get the attributes of a file descriptor. - ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + ;;; Get the attributes of a file descriptor. + ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file descriptor's attributes are stored. + ;;; The buffer where the file descriptor's attributes are stored. (result $stat $fdstat_t) ) - ;; Adjust the flags associated with a file descriptor. - ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + ;;; Adjust the flags associated with a file descriptor. + ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") (param $fd $fd_t) - ;; The desired values of the file descriptor flags. + ;;; The desired values of the file descriptor flags. (param $flags $fdflags_t) (result $error $errno_t) ) - ;; Adjust the rights associated with a file descriptor. - ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; Adjust the rights associated with a file descriptor. + ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd_t) - ;; The desired rights of the file descriptor. + ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights_t) (param $fs_rights_inheriting $rights_t) (result $error $errno_t) ) - ;; Return the attributes of an open file. + ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;; Note: This is similar to `ftruncate` in POSIX. + ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") (param $fd $fd_t) - ;; The desired file size. + ;;; The desired file size. (param $st_size $filesize_t) (result $error $errno_t) ) - ;; Adjust the timestamps of an open file or directory. - ;; Note: This is similar to `futimens` in POSIX. + ;;; Adjust the timestamps of an open file or directory. + ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") (param $fd $fd_t) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `preadv` in POSIX. + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") (param $fd $fd_t) - ;; List of scatter/gather vectors in which to store data. + ;;; List of scatter/gather vectors in which to store data. (param $iovs $iovec_t_array) - ;; The offset within the file at which to read. + ;;; The offset within the file at which to read. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the description is stored. + ;;; The buffer where the description is stored. (result $buf $prestat_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") (param $fd $fd_t) - ;; A buffer into which to write the preopened directory name. + ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size_t) (result $error $errno_t) ) - ;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `pwritev` in POSIX. + ;;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) - ;; The offset within the file at which to write. + ;;; The offset within the file at which to write. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Read from a file descriptor. - ;; Note: This is similar to `readv` in POSIX. + ;;; Read from a file descriptor. + ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_t_array) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Read directory entries from a directory. - ;; When successful, the contents of the output buffer consist of a sequence of - ;; directory entries. Each directory entry consists of a dirent_t object, - ;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;; entry. + ;;; Read directory entries from a directory. + ;;; When successful, the contents of the output buffer consist of a sequence of + ;;; directory entries. Each directory entry consists of a dirent_t object, + ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; entry. ;; - ;; This function fills the output buffer as much as possible, potentially - ;; truncating the last directory entry. This allows the caller to grow its - ;; read buffer size in case it's too small to fit a single large directory - ;; entry, or skip the oversized directory entry. + ;;; This function fills the output buffer as much as possible, potentially + ;;; truncating the last directory entry. This allows the caller to grow its + ;;; read buffer size in case it's too small to fit a single large directory + ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") (param $fd $fd_t) - ;; The buffer where directory entries are stored + ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) (param $buf_len $size_t) - ;; The location within the directory to start reading + ;;; The location within the directory to start reading (param $cookie $dircookie_t) (result $error $errno_t) - ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. (result $bufused $size_t) ) - ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;;; Atomically replace a file descriptor by renumbering another file descriptor. ;; - ;; Due to the strong focus on thread safety, this environment does not provide - ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;; file descriptor with the same number could be allocated by a different - ;; thread at the same time. + ;;; Due to the strong focus on thread safety, this environment does not provide + ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;;; file descriptor with the same number could be allocated by a different + ;;; thread at the same time. ;; - ;; This function provides a way to atomically renumber file descriptors, which - ;; would disappear if `dup2()` were to be removed entirely. + ;;; This function provides a way to atomically renumber file descriptors, which + ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") (param $fd $fd_t) - ;; The file descriptor to overwrite. + ;;; The file descriptor to overwrite. (param $to $fd_t) (result $error $errno_t) ) - ;; Move the offset of a file descriptor. - ;; Note: This is similar to `lseek` in POSIX. + ;;; Move the offset of a file descriptor. + ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") (param $fd $fd_t) - ;; The number of bytes to move. + ;;; The number of bytes to move. (param $offset $filedelta_t) - ;; The base from which the offset is relative. + ;;; The base from which the offset is relative. (param $whence $whence_t) (result $error $errno_t) - ;; The new offset of the file descriptor, relative to the start of the file. + ;;; The new offset of the file descriptor, relative to the start of the file. (result $newoffset $filesize_t) ) - ;; Synchronize the data and metadata of a file to disk. - ;; Note: This is similar to `fsync` in POSIX. + ;;; Synchronize the data and metadata of a file to disk. + ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Return the current offset of a file descriptor. - ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + ;;; Return the current offset of a file descriptor. + ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd_t) (result $error $errno_t) - ;; The current offset of the file descriptor, relative to the start of the file. + ;;; The current offset of the file descriptor, relative to the start of the file. (result $offset $filesize_t) ) - ;; Write to a file descriptor. - ;; Note: This is similar to `writev` in POSIX. + ;;; Write to a file descriptor. + ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Create a directory. - ;; Note: This is similar to `mkdirat` in POSIX. + ;;; Create a directory. + ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") (param $fd $fd_t) - ;; The path at which to create the directory. + ;;; The path at which to create the directory. (param $path string) (result $error $errno_t) ) - ;; Return the attributes of a file or directory. - ;; Note: This is similar to `stat` in POSIX. + ;;; Return the attributes of a file or directory. + ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to inspect. + ;;; The path of the file or directory to inspect. (param $path string) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the timestamps of a file or directory. - ;; Note: This is similar to `utimensat` in POSIX. + ;;; Adjust the timestamps of a file or directory. + ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to operate on. + ;;; The path of the file or directory to operate on. (param $path string) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Create a hard link. - ;; Note: This is similar to `linkat` in POSIX. + ;;; Create a hard link. + ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") (param $old_fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) - ;; The source path from which to link. + ;;; The source path from which to link. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path at which to create the hard link. + ;;; The destination path at which to create the hard link. (param $new_path string) (result $error $errno_t) ) - ;; Open a file or directory. + ;;; Open a file or directory. ;; - ;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;; file descriptor not currently open; it is randomized to prevent - ;; applications from depending on making assumptions about indexes, since this - ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 2**31. + ;;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;;; file descriptor not currently open; it is randomized to prevent + ;;; applications from depending on making assumptions about indexes, since this + ;;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;;; guaranteed to be less than 2**31. ;; - ;; Note: This is similar to `openat` in POSIX. + ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags_t) - ;; The relative path of the file or directory to open, relative to the - ;; `dirfd` directory. + ;;; The relative path of the file or directory to open, relative to the + ;;; `dirfd` directory. (param $path string) - ;; The method by which to open the file. + ;;; The method by which to open the file. (param $o_flags $oflags_t) - ;; The initial rights of the newly created file descriptor. The - ;; implementation is allowed to return a file descriptor with fewer rights - ;; than specified, if and only if those rights do not apply to the type of - ;; file being opened. + ;;; The initial rights of the newly created file descriptor. The + ;;; implementation is allowed to return a file descriptor with fewer rights + ;;; than specified, if and only if those rights do not apply to the type of + ;;; file being opened. ;; - ;; The *base* rights are rights that will apply to operations using the file - ;; descriptor itself, while the *inheriting* rights are rights that apply to - ;; file descriptors derived from it. + ;;; The *base* rights are rights that will apply to operations using the file + ;;; descriptor itself, while the *inheriting* rights are rights that apply to + ;;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) (param $flags $fdflags_t) (result $error $errno_t) - ;; The file descriptor of the file that has been opened. + ;;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) ) - ;; Read the contents of a symbolic link. - ;; Note: This is similar to `readlinkat` in POSIX. + ;;; Read the contents of a symbolic link. + ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") (param $fd $fd_t) - ;; The path of the symbolic link from which to read. + ;;; The path of the symbolic link from which to read. (param $path string) - ;; The buffer to which to write the contents of the symbolic link. + ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) - ;; The number of bytes placed in the buffer. + ;;; The number of bytes placed in the buffer. (result $bufused $size_t) ) - ;; Remove a directory. - ;; Return `ENOTEMPTY` if the directory is not empty. - ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + ;;; Remove a directory. + ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd_t) - ;; The path to a directory to remove. + ;;; The path to a directory to remove. (param $path string) (result $error $errno_t) ) - ;; Rename a file or directory. - ;; Note: This is similar to `renameat` in POSIX. + ;;; Rename a file or directory. + ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") (param $fd $fd_t) - ;; The source path of the file or directory to rename. + ;;; The source path of the file or directory to rename. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path to which to rename the file or directory. + ;;; The destination path to which to rename the file or directory. (param $new_path string) (result $error $errno_t) ) - ;; Create a symbolic link. - ;; Note: This is similar to `symlinkat` in POSIX. + ;;; Create a symbolic link. + ;;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - ;; The contents of the symbolic link. + ;;; The contents of the symbolic link. (param $old_path string) (param $fd $fd_t) - ;; The destination path at which to create the symbolic link. + ;;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) ) - ;; Unlink a file. - ;; Return `EISDIR` if the path refers to a directory. - ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + ;;; Unlink a file. + ;;; Return `EISDIR` if the path refers to a directory. + ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd_t) - ;; The path to a file to unlink. + ;;; The path to a file to unlink. (param $path string) (result $error $errno_t) ) - ;; Concurrently poll for the occurrence of a set of events. + ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") - ;; The events to which to subscribe. + ;;; The events to which to subscribe. (param $in (@witx const_pointer $subscription_t)) - ;; The events that have occurred. + ;;; The events that have occurred. (param $out (@witx pointer $event_t)) - ;; Both the number of subscriptions and events. + ;;; Both the number of subscriptions and events. (param $nsubscriptions $size_t) (result $error $errno_t) - ;; The number of events stored. + ;;; The number of events stored. (result $nevents $size_t) ) - ;; Terminate the process normally. An exit code of 0 indicates successful - ;; termination of the program. The meanings of other values is dependent on - ;; the environment. + ;;; Terminate the process normally. An exit code of 0 indicates successful + ;;; termination of the program. The meanings of other values is dependent on + ;;; the environment. (@interface func (export "proc_exit") - ;; The exit code returned by the process. + ;;; The exit code returned by the process. (param $rval $exitcode_t) ) - ;; Send a signal to the process of the calling thread. - ;; Note: This is similar to `raise` in POSIX. + ;;; Send a signal to the process of the calling thread. + ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") - ;; The signal condition to trigger. + ;;; The signal condition to trigger. (param $sig $signal_t) (result $error $errno_t) ) - ;; Temporarily yield execution of the calling thread. - ;; Note: This is similar to `sched_yield` in POSIX. + ;;; Temporarily yield execution of the calling thread. + ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") (result $error $errno_t) ) - ;; Write high-quality random data into a buffer. - ;; This function blocks when the implementation is unable to immediately - ;; provide sufficient high-quality random data. - ;; This function may execute slowly, so when large mounts of random data are - ;; required, it's advisable to use this function to seed a pseudo-random - ;; number generator, rather than to provide the random data directly. + ;;; Write high-quality random data into a buffer. + ;;; This function blocks when the implementation is unable to immediately + ;;; provide sufficient high-quality random data. + ;;; This function may execute slowly, so when large mounts of random data are + ;;; required, it's advisable to use this function to seed a pseudo-random + ;;; number generator, rather than to provide the random data directly. (@interface func (export "random_get") - ;; The buffer to fill with random data. + ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) ) - ;; Receive a message from a socket. - ;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;; the data into multiple buffers in the manner of `readv`. + ;;; Receive a message from a socket. + ;;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $ri_data $iovec_t_array) - ;; Message flags. + ;;; Message flags. (param $ri_flags $riflags_t) (result $error $errno_t) - ;; Number of bytes stored in ri_data. + ;;; Number of bytes stored in ri_data. (result $ro_datalen $size_t) - ;; Message flags. + ;;; Message flags. (result $ro_flags $roflags_t) ) - ;; Send a message on a socket. - ;; Note: This is similar to `send` in POSIX, though it also supports writing - ;; the data from multiple buffers in the manner of `writev`. + ;;; Send a message on a socket. + ;;; Note: This is similar to `send` in POSIX, though it also supports writing + ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to retrieve data + ;;; List of scatter/gather vectors to which to retrieve data (param $si_data $ciovec_t_array) - ;; Message flags. + ;;; Message flags. (param $si_flags $siflags_t) (result $error $errno_t) - ;; Number of bytes transmitted. + ;;; Number of bytes transmitted. (result $so_datalen $size_t) ) - ;; Shut down socket send and receive channels. - ;; Note: This is similar to `shutdown` in POSIX. + ;;; Shut down socket send and receive channels. + ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") (param $fd $fd_t) - ;; Which channels on the socket to shut down. + ;;; Which channels on the socket to shut down. (param $how $sdflags_t) (result $error $errno_t) ) diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx index 15b53af51..cf39a2deb 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx @@ -7,291 +7,291 @@ (typename $size_t u32) -;; Non-negative file size or length of a region within a file. +;;; Non-negative file size or length of a region within a file. (typename $filesize_t u64) -;; Timestamp in nanoseconds. +;;; Timestamp in nanoseconds. (typename $timestamp_t u64) -;; Identifiers for clocks. +;;; Identifiers for clocks. (typename $clockid_t (enum u32 - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. + ;;; The clock measuring real time. Time value zero corresponds with + ;;; 1970-01-01T00:00:00Z. $CLOCK_REALTIME - ;; The store-wide monotonic clock, which is defined as a clock measuring - ;; real time, whose value cannot be adjusted and which cannot have negative - ;; clock jumps. The epoch of this clock is undefined. The absolute time - ;; value of this clock therefore has no meaning. + ;;; The store-wide monotonic clock, which is defined as a clock measuring + ;;; real time, whose value cannot be adjusted and which cannot have negative + ;;; clock jumps. The epoch of this clock is undefined. The absolute time + ;;; value of this clock therefore has no meaning. $CLOCK_MONOTONIC - ;; The CPU-time clock associated with the current process. + ;;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The CPU-time clock associated with the current thread. + ;;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) ) -;; Error codes returned by functions. -;; Not all of these error codes are returned by the functions provided by this -;; API; some are used in higher-level library layers, and others are provided -;; merely for alignment with POSIX. +;;; Error codes returned by functions. +;;; Not all of these error codes are returned by the functions provided by this +;;; API; some are used in higher-level library layers, and others are provided +;;; merely for alignment with POSIX. (typename $errno_t (enum u16 - ;; No error occurred. System call completed successfully. + ;;; No error occurred. System call completed successfully. $ESUCCESS - ;; Argument list too long. + ;;; Argument list too long. $E2BIG - ;; Permission denied. + ;;; Permission denied. $EACCES - ;; Address in use. + ;;; Address in use. $EADDRINUSE - ;; Address not available. + ;;; Address not available. $EADDRNOTAVAIL - ;; Address family not supported. + ;;; Address family not supported. $EAFNOSUPPORT - ;; Resource unavailable, or operation would block. + ;;; Resource unavailable, or operation would block. $EAGAIN - ;; Connection already in progress. + ;;; Connection already in progress. $EALREADY - ;; Bad file descriptor. + ;;; Bad file descriptor. $EBADF - ;; Bad message. + ;;; Bad message. $EBADMSG - ;; Device or resource busy. + ;;; Device or resource busy. $EBUSY - ;; Operation canceled. + ;;; Operation canceled. $ECANCELED - ;; No child processes. + ;;; No child processes. $ECHILD - ;; Connection aborted. + ;;; Connection aborted. $ECONNABORTED - ;; Connection refused. + ;;; Connection refused. $ECONNREFUSED - ;; Connection reset. + ;;; Connection reset. $ECONNRESET - ;; Resource deadlock would occur. + ;;; Resource deadlock would occur. $EDEADLK - ;; Destination address required. + ;;; Destination address required. $EDESTADDRREQ - ;; Mathematics argument out of domain of function. + ;;; Mathematics argument out of domain of function. $EDOM - ;; Reserved. + ;;; Reserved. $EDQUOT - ;; File exists. + ;;; File exists. $EEXIST - ;; Bad address. + ;;; Bad address. $EFAULT - ;; File too large. + ;;; File too large. $EFBIG - ;; Host is unreachable. + ;;; Host is unreachable. $EHOSTUNREACH - ;; Identifier removed. + ;;; Identifier removed. $EIDRM - ;; Illegal byte sequence. + ;;; Illegal byte sequence. $EILSEQ - ;; Operation in progress. + ;;; Operation in progress. $EINPROGRESS - ;; Interrupted function. + ;;; Interrupted function. $EINTR - ;; Invalid argument. + ;;; Invalid argument. $EINVAL - ;; I/O error. + ;;; I/O error. $EIO - ;; Socket is connected. + ;;; Socket is connected. $EISCONN - ;; Is a directory. + ;;; Is a directory. $EISDIR - ;; Too many levels of symbolic links. + ;;; Too many levels of symbolic links. $ELOOP - ;; File descriptor value too large. + ;;; File descriptor value too large. $EMFILE - ;; Too many links. + ;;; Too many links. $EMLINK - ;; Message too large. + ;;; Message too large. $EMSGSIZE - ;; Reserved. + ;;; Reserved. $EMULTIHOP - ;; Filename too long. + ;;; Filename too long. $ENAMETOOLONG - ;; Network is down. + ;;; Network is down. $ENETDOWN - ;; Connection aborted by network. + ;;; Connection aborted by network. $ENETRESET - ;; Network unreachable. + ;;; Network unreachable. $ENETUNREACH - ;; Too many files open in system. + ;;; Too many files open in system. $ENFILE - ;; No buffer space available. + ;;; No buffer space available. $ENOBUFS - ;; No such device. + ;;; No such device. $ENODEV - ;; No such file or directory. + ;;; No such file or directory. $ENOENT - ;; Executable file format error. + ;;; Executable file format error. $ENOEXEC - ;; No locks available. + ;;; No locks available. $ENOLCK - ;; Reserved. + ;;; Reserved. $ENOLINK - ;; Not enough space. + ;;; Not enough space. $ENOMEM - ;; No message of the desired type. + ;;; No message of the desired type. $ENOMSG - ;; Protocol not available. + ;;; Protocol not available. $ENOPROTOOPT - ;; No space left on device. + ;;; No space left on device. $ENOSPC - ;; Function not supported. + ;;; Function not supported. $ENOSYS - ;; The socket is not connected. + ;;; The socket is not connected. $ENOTCONN - ;; Not a directory or a symbolic link to a directory. + ;;; Not a directory or a symbolic link to a directory. $ENOTDIR - ;; Directory not empty. + ;;; Directory not empty. $ENOTEMPTY - ;; State not recoverable. + ;;; State not recoverable. $ENOTRECOVERABLE - ;; Not a socket. + ;;; Not a socket. $ENOTSOCK - ;; Not supported, or operation not supported on socket. + ;;; Not supported, or operation not supported on socket. $ENOTSUP - ;; Inappropriate I/O control operation. + ;;; Inappropriate I/O control operation. $ENOTTY - ;; No such device or address. + ;;; No such device or address. $ENXIO - ;; Value too large to be stored in data type. + ;;; Value too large to be stored in data type. $EOVERFLOW - ;; Previous owner died. + ;;; Previous owner died. $EOWNERDEAD - ;; Operation not permitted. + ;;; Operation not permitted. $EPERM - ;; Broken pipe. + ;;; Broken pipe. $EPIPE - ;; Protocol error. + ;;; Protocol error. $EPROTO - ;; Protocol not supported. + ;;; Protocol not supported. $EPROTONOSUPPORT - ;; Protocol wrong type for socket. + ;;; Protocol wrong type for socket. $EPROTOTYPE - ;; Result too large. + ;;; Result too large. $ERANGE - ;; Read-only file system. + ;;; Read-only file system. $EROFS - ;; Invalid seek. + ;;; Invalid seek. $ESPIPE - ;; No such process. + ;;; No such process. $ESRCH - ;; Reserved. + ;;; Reserved. $ESTALE - ;; Connection timed out. + ;;; Connection timed out. $ETIMEDOUT - ;; Text file busy. + ;;; Text file busy. $ETXTBSY - ;; Cross-device link. + ;;; Cross-device link. $EXDEV - ;; Extension: Capabilities insufficient. + ;;; Extension: Capabilities insufficient. $ENOTCAPABLE ) ) -;; File descriptor rights, determining which actions may be performed. +;;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke `fd_datasync`. + ;;; The right to invoke `fd_datasync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_DSYNC`. $RIGHT_FD_DATASYNC - ;; The right to invoke `fd_read` and `sock_recv`. + ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. $RIGHT_FD_READ - ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. $RIGHT_FD_SEEK - ;; The right to invoke `fd_fdstat_set_flags`. + ;;; The right to invoke `fd_fdstat_set_flags`. $RIGHT_FD_FDSTAT_SET_FLAGS - ;; The right to invoke `fd_sync`. + ;;; The right to invoke `fd_sync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. $RIGHT_FD_SYNC - ;; The right to invoke `fd_seek` in such a way that the file offset - ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to - ;; invoke `fd_tell`. + ;;; The right to invoke `fd_seek` in such a way that the file offset + ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; invoke `fd_tell`. $RIGHT_FD_TELL - ;; The right to invoke `fd_write` and `sock_send`. - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + ;;; The right to invoke `fd_write` and `sock_send`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. $RIGHT_FD_WRITE - ;; The right to invoke `fd_advise`. + ;;; The right to invoke `fd_advise`. $RIGHT_FD_ADVISE - ;; The right to invoke `fd_allocate`. + ;;; The right to invoke `fd_allocate`. $RIGHT_FD_ALLOCATE - ;; The right to invoke `path_create_directory`. + ;;; The right to invoke `path_create_directory`. $RIGHT_PATH_CREATE_DIRECTORY - ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. $RIGHT_PATH_CREATE_FILE - ;; The right to invoke `path_link` with the file descriptor as the - ;; source directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; source directory. $RIGHT_PATH_LINK_SOURCE - ;; The right to invoke `path_link` with the file descriptor as the - ;; target directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; target directory. $RIGHT_PATH_LINK_TARGET - ;; The right to invoke `path_open`. + ;;; The right to invoke `path_open`. $RIGHT_PATH_OPEN - ;; The right to invoke `fd_readdir`. + ;;; The right to invoke `fd_readdir`. $RIGHT_FD_READDIR - ;; The right to invoke `path_readlink`. + ;;; The right to invoke `path_readlink`. $RIGHT_PATH_READLINK - ;; The right to invoke `path_rename` with the file descriptor as the source directory. + ;;; The right to invoke `path_rename` with the file descriptor as the source directory. $RIGHT_PATH_RENAME_SOURCE - ;; The right to invoke `path_rename` with the file descriptor as the target directory. + ;;; The right to invoke `path_rename` with the file descriptor as the target directory. $RIGHT_PATH_RENAME_TARGET - ;; The right to invoke `path_filestat_get`. + ;;; The right to invoke `path_filestat_get`. $RIGHT_PATH_FILESTAT_GET - ;; The right to change a file's size (there is no `path_filestat_set_size`). - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + ;;; The right to change a file's size (there is no `path_filestat_set_size`). + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. $RIGHT_PATH_FILESTAT_SET_SIZE - ;; The right to invoke `path_filestat_set_times`. + ;;; The right to invoke `path_filestat_set_times`. $RIGHT_PATH_FILESTAT_SET_TIMES - ;; The right to invoke `fd_filestat_get`. + ;;; The right to invoke `fd_filestat_get`. $RIGHT_FD_FILESTAT_GET - ;; The right to invoke `fd_filestat_set_size`. + ;;; The right to invoke `fd_filestat_set_size`. $RIGHT_FD_FILESTAT_SET_SIZE - ;; The right to invoke `fd_filestat_set_times`. + ;;; The right to invoke `fd_filestat_set_times`. $RIGHT_FD_FILESTAT_SET_TIMES - ;; The right to invoke `path_symlink`. + ;;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_remove_directory`. + ;;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY - ;; The right to invoke `path_unlink_file`. + ;;; The right to invoke `path_unlink_file`. $RIGHT_PATH_UNLINK_FILE - ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE - ;; The right to invoke `sock_shutdown`. + ;;; The right to invoke `sock_shutdown`. $RIGHT_SOCK_SHUTDOWN ) ) -;; A file descriptor index. +;;; A file descriptor index. (typename $fd_t u32) -;; A region of memory for scatter/gather reads. +;;; A region of memory for scatter/gather reads. (typename $iovec_t (struct - ;; The address of the buffer to be filled. + ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) - ;; The length of the buffer to be filled. + ;;; The length of the buffer to be filled. (field $buf_len $size_t) ) ) -;; A region of memory for scatter/gather writes. +;;; A region of memory for scatter/gather writes. (typename $ciovec_t (struct - ;; The address of the buffer to be written. + ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) - ;; The length of the buffer to be written. + ;;; The length of the buffer to be written. (field $buf_len $size_t) ) ) @@ -299,469 +299,469 @@ (typename $iovec_t_array (array $iovec_t)) (typename $ciovec_t_array (array $ciovec_t)) -;; Relative offset within a file. +;;; Relative offset within a file. (typename $filedelta_t s64) -;; The position relative to which to set the offset of the file descriptor. +;;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 - ;; Seek relative to current position. + ;;; Seek relative to current position. $WHENCE_CUR - ;; Seek relative to end-of-file. + ;;; Seek relative to end-of-file. $WHENCE_END - ;; Seek relative to start-of-file. + ;;; Seek relative to start-of-file. $WHENCE_SET ) ) -;; A reference to the offset of a directory entry. +;;; A reference to the offset of a directory entry. (typename $dircookie_t u64) -;; The type for the $d_namlen field of $dirent_t. +;;; The type for the $d_namlen field of $dirent_t. (typename $dirnamlen_t u32) -;; File serial number that is unique within its file system. +;;; File serial number that is unique within its file system. (typename $inode_t u64) -;; The type of a file descriptor or file. +;;; The type of a file descriptor or file. (typename $filetype_t (enum u8 - ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $FILETYPE_UNKNOWN - ;; The file descriptor or file refers to a block device inode. + ;;; The file descriptor or file refers to a block device inode. $FILETYPE_BLOCK_DEVICE - ;; The file descriptor or file refers to a character device inode. + ;;; The file descriptor or file refers to a character device inode. $FILETYPE_CHARACTER_DEVICE - ;; The file descriptor or file refers to a directory inode. + ;;; The file descriptor or file refers to a directory inode. $FILETYPE_DIRECTORY - ;; The file descriptor or file refers to a regular file inode. + ;;; The file descriptor or file refers to a regular file inode. $FILETYPE_REGULAR_FILE - ;; The file descriptor or file refers to a datagram socket. + ;;; The file descriptor or file refers to a datagram socket. $FILETYPE_SOCKET_DGRAM - ;; The file descriptor or file refers to a byte-stream socket. + ;;; The file descriptor or file refers to a byte-stream socket. $FILETYPE_SOCKET_STREAM - ;; The file refers to a symbolic link inode. + ;;; The file refers to a symbolic link inode. $FILETYPE_SYMBOLIC_LINK ) ) -;; A directory entry. +;;; A directory entry. (typename $dirent_t (struct - ;; The offset of the next directory entry stored in this directory. + ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie_t) - ;; The serial number of the file referred to by this directory entry. + ;;; The serial number of the file referred to by this directory entry. (field $d_ino $inode_t) - ;; The length of the name of the directory entry. + ;;; The length of the name of the directory entry. (field $d_namlen $dirnamlen_t) - ;; The type of the file referred to by this directory entry. + ;;; The type of the file referred to by this directory entry. (field $d_type $filetype_t) ) ) -;; File or memory access pattern advisory information. +;;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application has no advice to give on its behavior with respect to the specified data. + ;;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL - ;; The application expects to access the specified data in a random order. + ;;; The application expects to access the specified data in a random order. $ADVICE_RANDOM - ;; The application expects to access the specified data in the near future. + ;;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED - ;; The application expects that it will not access the specified data in the near future. + ;;; The application expects that it will not access the specified data in the near future. $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. + ;;; The application expects to access the specified data once and then not reuse it thereafter. $ADVICE_NOREUSE ) ) -;; File descriptor flags. +;;; File descriptor flags. (typename $fdflags_t (flags u16 - ;; Append mode: Data written to the file is always appended to the file's end. + ;;; Append mode: Data written to the file is always appended to the file's end. $FDFLAG_APPEND - ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. $FDFLAG_DSYNC - ;; Non-blocking mode. + ;;; Non-blocking mode. $FDFLAG_NONBLOCK - ;; Synchronized read I/O operations. + ;;; Synchronized read I/O operations. $FDFLAG_RSYNC - ;; Write according to synchronized I/O file integrity completion. In - ;; addition to synchronizing the data stored in the file, the implementation - ;; may also synchronously update the file's metadata. + ;;; Write according to synchronized I/O file integrity completion. In + ;;; addition to synchronizing the data stored in the file, the implementation + ;;; may also synchronously update the file's metadata. $FDFLAG_SYNC ) ) -;; File descriptor attributes. +;;; File descriptor attributes. (typename $fdstat_t (struct - ;; File type. + ;;; File type. (field $fs_filetype $filetype_t) - ;; File descriptor flags. + ;;; File descriptor flags. (field $fs_flags $fdflags_t) - ;; Rights that apply to this file descriptor. + ;;; Rights that apply to this file descriptor. (field $fs_rights_base $rights_t) - ;; Maximum set of rights that may be installed on new file descriptors that - ;; are created through this file descriptor, e.g., through `path_open`. + ;;; Maximum set of rights that may be installed on new file descriptors that + ;;; are created through this file descriptor, e.g., through `path_open`. (field $fs_rights_inheriting $rights_t) ) ) -;; Identifier for a device containing a file system. Can be used in combination -;; with `inode_t` to uniquely identify a file or directory in the filesystem. +;;; Identifier for a device containing a file system. Can be used in combination +;;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) -;; Which file time attributes to adjust. +;;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 - ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. $FILESTAT_SET_ATIM - ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_ATIM_NOW - ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. $FILESTAT_SET_MTIM - ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_MTIM_NOW ) ) -;; Flags determining the method of how paths are resolved. +;;; Flags determining the method of how paths are resolved. (typename $lookupflags_t (flags u32 - ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $LOOKUP_SYMLINK_FOLLOW ) ) -;; Open flags used by `path_open`. +;;; Open flags used by `path_open`. (typename $oflags_t (flags u16 - ;; Create file if it does not exist. + ;;; Create file if it does not exist. $O_CREAT - ;; Fail if not a directory. + ;;; Fail if not a directory. $O_DIRECTORY - ;; Fail if file already exists. + ;;; Fail if file already exists. $O_EXCL - ;; Truncate file to size 0. + ;;; Truncate file to size 0. $O_TRUNC ) ) -;; Number of hard links to an inode. +;;; Number of hard links to an inode. (typename $linkcount_t u32) -;; File attributes. +;;; File attributes. (typename $filestat_t (struct - ;; Device ID of device containing the file. + ;;; Device ID of device containing the file. (field $st_dev $device_t) - ;; File serial number. + ;;; File serial number. (field $st_ino $inode_t) - ;; File type. + ;;; File type. (field $st_filetype $filetype_t) - ;; Number of hard links to the file. + ;;; Number of hard links to the file. (field $st_nlink $linkcount_t) - ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. (field $st_size $filesize_t) - ;; Last data access timestamp. + ;;; Last data access timestamp. (field $st_atim $timestamp_t) - ;; Last data modification timestamp. + ;;; Last data modification timestamp. (field $st_mtim $timestamp_t) - ;; Last file status change timestamp. + ;;; Last file status change timestamp. (field $st_ctim $timestamp_t) ) ) -;; User-provided value that may be attached to objects that is retained when -;; extracted from the implementation. +;;; User-provided value that may be attached to objects that is retained when +;;; extracted from the implementation. (typename $userdata_t u64) -;; Type of a subscription to an event or its occurrence. +;;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (enum u8 - ;; The time value of clock `subscription_t::u.clock.clock_id` has - ;; reached timestamp `subscription_t::u.clock.timeout`. + ;;; The time value of clock `subscription_t::u.clock.clock_id` has + ;;; reached timestamp `subscription_t::u.clock.timeout`. $EVENTTYPE_CLOCK - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data - ;; available for reading. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; available for reading. This event always triggers for regular files. $EVENTTYPE_FD_READ - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity - ;; available for writing. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;;; available for writing. This event always triggers for regular files. $EVENTTYPE_FD_WRITE ) ) -;; The state of the file descriptor subscribed to with -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The state of the file descriptor subscribed to with +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 - ;; The peer of this socket has closed or disconnected. + ;;; The peer of this socket has closed or disconnected. $EVENT_FD_READWRITE_HANGUP ) ) -;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;; `EVENTTYPE_FD_WRITE`. +;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;;; `EVENTTYPE_FD_WRITE`. (typename $event_fd_readwrite_t (struct - ;; The number of bytes available for reading or writing. + ;;; The number of bytes available for reading or writing. (field $nbytes $filesize_t) - ;; The state of the file descriptor. + ;;; The state of the file descriptor. (field $flags $eventrwflags_t) ) ) -;; The contents of an $event_t. +;;; The contents of an $event_t. (typename $event_u (union - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; An event that occurred. +;;; An event that occurred. (typename $event_t (struct - ;; User-provided value that got attached to `subscription_t::userdata`. + ;;; User-provided value that got attached to `subscription_t::userdata`. (field $userdata $userdata_t) - ;; If non-zero, an error that occurred while processing the subscription request. + ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno_t) - ;; The type of the event that occurred. + ;;; The type of the event that occurred. (field $type $eventtype_t) - ;; The contents of the event. + ;;; The contents of the event. (field $u $event_u) ) ) -;; Flags determining how to interpret the timestamp provided in -;; `subscription_t::u.clock.timeout.` +;;; Flags determining how to interpret the timestamp provided in +;;; `subscription_t::u.clock.timeout.` (typename $subclockflags_t (flags u16 - ;; If set, treat the timestamp provided in - ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;; provided in `subscription_t::u.clock.timeout` relative to the - ;; current time value of clock `subscription_t::u.clock.clock_id.` + ;;; If set, treat the timestamp provided in + ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription_t::u.clock.timeout` relative to the + ;;; current time value of clock `subscription_t::u.clock.clock_id.` $SUBSCRIPTION_CLOCK_ABSTIME ) ) -;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The user-defined unique identifier of the clock. + ;;; The user-defined unique identifier of the clock. (field $identifier $userdata_t) - ;; The clock against which to compare the timestamp. + ;;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. + ;;; The absolute or relative timestamp. (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. + ;;; The amount of time that the implementation may wait additionally + ;;; to coalesce with other events. (field $precision $timestamp_t) - ;; Flags specifying whether the timeout is absolute or relative + ;;; Flags specifying whether the timeout is absolute or relative (field $flags $subclockflags_t) ) ) -;; The contents of a $subscription_t when type is type is -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The contents of a $subscription_t when type is type is +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $subscription_fd_readwrite_t (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. + ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd_t) ) ) -;; The contents of a $subscription_t. +;;; The contents of a $subscription_t. (typename $subscription_u (union - ;; When type is `EVENTTYPE_CLOCK`: + ;;; When type is `EVENTTYPE_CLOCK`: (field $clock $subscription_clock_t) - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $subscription_fd_readwrite_t) ) ) -;; Subscription to an event. +;;; Subscription to an event. (typename $subscription_t (struct - ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through `event_t::userdata`. + ;;; User-provided value that is attached to the subscription in the + ;;; implementation and returned through `event_t::userdata`. (field $userdata $userdata_t) - ;; The type of the event to which to subscribe. + ;;; The type of the event to which to subscribe. (field $type $eventtype_t) - ;; The contents of the subscription. + ;;; The contents of the subscription. (field $u $subscription_u) ) ) -;; Exit code generated by a process when exiting. +;;; Exit code generated by a process when exiting. (typename $exitcode_t u32) -;; Signal condition. +;;; Signal condition. (typename $signal_t (enum u8 - ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;; so this value is reserved. + ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;;; so this value is reserved. $SIGNONE - ;; Hangup. - ;; Action: Terminates the process. + ;;; Hangup. + ;;; Action: Terminates the process. $SIGHUP - ;; Terminate interrupt signal. - ;; Action: Terminates the process. + ;;; Terminate interrupt signal. + ;;; Action: Terminates the process. $SIGINT - ;; Terminal quit signal. - ;; Action: Terminates the process. + ;;; Terminal quit signal. + ;;; Action: Terminates the process. $SIGQUIT - ;; Illegal instruction. - ;; Action: Terminates the process. + ;;; Illegal instruction. + ;;; Action: Terminates the process. $SIGILL - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. + ;;; Trace/breakpoint trap. + ;;; Action: Terminates the process. $SIGTRAP - ;; Process abort signal. - ;; Action: Terminates the process. + ;;; Process abort signal. + ;;; Action: Terminates the process. $SIGABRT - ;; Access to an undefined portion of a memory object. - ;; Action: Terminates the process. + ;;; Access to an undefined portion of a memory object. + ;;; Action: Terminates the process. $SIGBUS - ;; Erroneous arithmetic operation. - ;; Action: Terminates the process. + ;;; Erroneous arithmetic operation. + ;;; Action: Terminates the process. $SIGFPE - ;; Kill. - ;; Action: Terminates the process. + ;;; Kill. + ;;; Action: Terminates the process. $SIGKILL - ;; User-defined signal 1. - ;; Action: Terminates the process. + ;;; User-defined signal 1. + ;;; Action: Terminates the process. $SIGUSR1 - ;; Invalid memory reference. - ;; Action: Terminates the process. + ;;; Invalid memory reference. + ;;; Action: Terminates the process. $SIGSEGV - ;; User-defined signal 2. - ;; Action: Terminates the process. + ;;; User-defined signal 2. + ;;; Action: Terminates the process. $SIGUSR2 - ;; Write on a pipe with no one to read it. - ;; Action: Ignored. + ;;; Write on a pipe with no one to read it. + ;;; Action: Ignored. $SIGPIPE - ;; Alarm clock. - ;; Action: Terminates the process. + ;;; Alarm clock. + ;;; Action: Terminates the process. $SIGALRM - ;; Termination signal. - ;; Action: Terminates the process. + ;;; Termination signal. + ;;; Action: Terminates the process. $SIGTERM - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. + ;;; Child process terminated, stopped, or continued. + ;;; Action: Ignored. $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. + ;;; Continue executing, if stopped. + ;;; Action: Continues executing, if stopped. $SIGCONT - ;; Stop executing. - ;; Action: Stops executing. + ;;; Stop executing. + ;;; Action: Stops executing. $SIGSTOP - ;; Terminal stop signal. - ;; Action: Stops executing. + ;;; Terminal stop signal. + ;;; Action: Stops executing. $SIGTSTP - ;; Background process attempting read. - ;; Action: Stops executing. + ;;; Background process attempting read. + ;;; Action: Stops executing. $SIGTTIN - ;; Background process attempting write. - ;; Action: Stops executing. + ;;; Background process attempting write. + ;;; Action: Stops executing. $SIGTTOU - ;; High bandwidth data is available at a socket. - ;; Action: Ignored. + ;;; High bandwidth data is available at a socket. + ;;; Action: Ignored. $SIGURG - ;; CPU time limit exceeded. - ;; Action: Terminates the process. + ;;; CPU time limit exceeded. + ;;; Action: Terminates the process. $SIGXCPU - ;; File size limit exceeded. - ;; Action: Terminates the process. + ;;; File size limit exceeded. + ;;; Action: Terminates the process. $SIGXFSZ - ;; Virtual timer expired. - ;; Action: Terminates the process. + ;;; Virtual timer expired. + ;;; Action: Terminates the process. $SIGVTALRM - ;; Profiling timer expired. - ;; Action: Terminates the process. + ;;; Profiling timer expired. + ;;; Action: Terminates the process. $SIGPROF - ;; Window changed. - ;; Action: Ignored. + ;;; Window changed. + ;;; Action: Ignored. $SIGWINCH - ;; I/O possible. - ;; Action: Terminates the process. + ;;; I/O possible. + ;;; Action: Terminates the process. $SIGPOLL - ;; Power failure. - ;; Action: Terminates the process. + ;;; Power failure. + ;;; Action: Terminates the process. $SIGPWR - ;; Bad system call. - ;; Action: Terminates the process. + ;;; Bad system call. + ;;; Action: Terminates the process. $SIGSYS ) ) -;; Flags provided to `sock_recv`. +;;; Flags provided to `sock_recv`. (typename $riflags_t (flags u16 - ;; Returns the message without removing it from the socket's receive queue. + ;;; Returns the message without removing it from the socket's receive queue. $SOCK_RECV_PEEK - ;; On byte-stream sockets, block until the full amount of data can be returned. + ;;; On byte-stream sockets, block until the full amount of data can be returned. $SOCK_RECV_WAITALL ) ) -;; Flags returned by `sock_recv`. +;;; Flags returned by `sock_recv`. (typename $roflags_t (flags u16 - ;; Returned by `sock_recv`: Message data has been truncated. + ;;; Returned by `sock_recv`: Message data has been truncated. $SOCK_RECV_DATA_TRUNCATED ) ) -;; Flags provided to `sock_send`. As there are currently no flags -;; defined, it must be set to zero. +;;; Flags provided to `sock_send`. As there are currently no flags +;;; defined, it must be set to zero. (typename $siflags_t u16) -;; Which channels on a socket to shut down. +;;; Which channels on a socket to shut down. (typename $sdflags_t (flags u8 - ;; Disables further receive operations. + ;;; Disables further receive operations. $SHUT_RD - ;; Disables further send operations. + ;;; Disables further send operations. $SHUT_WR ) ) -;; Identifiers for preopened capabilities. +;;; Identifiers for preopened capabilities. (typename $preopentype_t (enum u8 - ;; A pre-opened directory. + ;;; A pre-opened directory. $PREOPENTYPE_DIR ) ) -;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. (typename $prestat_dir (struct - ;; The length of the directory name for use with `fd_prestat_dir_name`. + ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size_t) ) ) -;; The contents of an $prestat_t. +;;; The contents of an $prestat_t. (typename $prestat_u (union - ;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `PREOPENTYPE_DIR`: (field $dir $prestat_dir) ) ) -;; Information about a pre-opened capability. +;;; Information about a pre-opened capability. (typename $prestat_t (struct - ;; The type of the pre-opened capability. + ;;; The type of the pre-opened capability. (field $pr_type $preopentype_t) - ;; The contents of the information. + ;;; The contents of the information. (field $u $prestat_u) ) ) diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx index 74bce70c6..4cf5f4ffa 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -8,523 +8,526 @@ (use "typenames.witx") -;; This API predated the convention of naming modules with a `wasi_unstable_` -;; prefix and a version number. It is preserved here for compatibility, but -;; we shouldn't follow this pattern in new APIs. +;;; This API predated the convention of naming modules with a `wasi_unstable_` +;;; prefix and a version number. It is preserved here for compatibility, but +;;; we shouldn't follow this pattern in new APIs. (module $wasi_unstable - ;; Linear memory to be accessed by WASI functions that need it. + ;;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) - ;; Read command-line argument data. - ;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; Read command-line argument data. + ;;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Read environment variable data. - ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; Read environment variable data. + ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Return the resolution of a clock. - ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;; Note: This is similar to `clock_getres` in POSIX. + ;;; Return the resolution of a clock. + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno_t) - ;; The clock for which to return the resolution. + ;;; The clock for which to return the resolution. (param $clock_id $clockid_t) - ;; The resolution of the clock. + ;;; The resolution of the clock. (result $resolution $timestamp_t) ) - ;; Return the time value of a clock. - ;; Note: This is similar to `clock_gettime` in POSIX. + ;;; Return the time value of a clock. + ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") - ;; The clock for which to return the time. + ;;; The clock for which to return the time. (param $clock_id $clockid_t) - ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp_t) (result $error $errno_t) - ;; The time value of the clock. + ;;; The time value of the clock. (result $time $timestamp_t) ) - ;; Provide file advisory information on a file descriptor. - ;; Note: This is similar to `posix_fadvise` in POSIX. + ;;; Provide file advisory information on a file descriptor. + ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") (param $fd $fd_t) - (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. - (param $len $filesize_t) ;; The length of the region to which the advisory applies. - (param $advice $advice_t) ;; The advice. + ;;; The offset within the file to which the advisory applies. + (param $offset $filesize_t) + ;;; The length of the region to which the advisory applies. + (param $len $filesize_t) + ;;; The advice. + (param $advice $advice_t) (result $error $errno_t) ) - ;; Force the allocation of space in a file. - ;; Note: This is similar to `posix_fallocate` in POSIX. + ;;; Force the allocation of space in a file. + ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") (param $fd $fd_t) - ;; The offset at which to start the allocation. + ;;; The offset at which to start the allocation. (param $offset $filesize_t) - ;; The length of the area that is allocated. + ;;; The length of the area that is allocated. (param $len $filesize_t) (result $error $errno_t) ) - ;; Close a file descriptor. - ;; Note: This is similar to `close` in POSIX. + ;;; Close a file descriptor. + ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd_t) (result $error $errno_t) ) - ;; Synchronize the data of a file to disk. - ;; Note: This is similar to `fdatasync` in POSIX. + ;;; Synchronize the data of a file to disk. + ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Get the attributes of a file descriptor. - ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + ;;; Get the attributes of a file descriptor. + ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file descriptor's attributes are stored. + ;;; The buffer where the file descriptor's attributes are stored. (result $stat $fdstat_t) ) - ;; Adjust the flags associated with a file descriptor. - ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + ;;; Adjust the flags associated with a file descriptor. + ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") (param $fd $fd_t) - ;; The desired values of the file descriptor flags. + ;;; The desired values of the file descriptor flags. (param $flags $fdflags_t) (result $error $errno_t) ) - ;; Adjust the rights associated with a file descriptor. - ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; Adjust the rights associated with a file descriptor. + ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd_t) - ;; The desired rights of the file descriptor. + ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights_t) (param $fs_rights_inheriting $rights_t) (result $error $errno_t) ) - ;; Return the attributes of an open file. + ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;; Note: This is similar to `ftruncate` in POSIX. + ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") (param $fd $fd_t) - ;; The desired file size. + ;;; The desired file size. (param $st_size $filesize_t) (result $error $errno_t) ) - ;; Adjust the timestamps of an open file or directory. - ;; Note: This is similar to `futimens` in POSIX. + ;;; Adjust the timestamps of an open file or directory. + ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") (param $fd $fd_t) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `preadv` in POSIX. + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") (param $fd $fd_t) - ;; List of scatter/gather vectors in which to store data. + ;;; List of scatter/gather vectors in which to store data. (param $iovs $iovec_t_array) - ;; The offset within the file at which to read. + ;;; The offset within the file at which to read. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the description is stored. + ;;; The buffer where the description is stored. (result $buf $prestat_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") (param $fd $fd_t) - ;; A buffer into which to write the preopened directory name. + ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size_t) (result $error $errno_t) ) - ;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `pwritev` in POSIX. + ;;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) - ;; The offset within the file at which to write. + ;;; The offset within the file at which to write. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Read from a file descriptor. - ;; Note: This is similar to `readv` in POSIX. + ;;; Read from a file descriptor. + ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_t_array) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Read directory entries from a directory. - ;; When successful, the contents of the output buffer consist of a sequence of - ;; directory entries. Each directory entry consists of a dirent_t object, - ;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;; entry. + ;;; Read directory entries from a directory. + ;;; When successful, the contents of the output buffer consist of a sequence of + ;;; directory entries. Each directory entry consists of a dirent_t object, + ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; entry. ;; - ;; This function fills the output buffer as much as possible, potentially - ;; truncating the last directory entry. This allows the caller to grow its - ;; read buffer size in case it's too small to fit a single large directory - ;; entry, or skip the oversized directory entry. + ;;; This function fills the output buffer as much as possible, potentially + ;;; truncating the last directory entry. This allows the caller to grow its + ;;; read buffer size in case it's too small to fit a single large directory + ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") (param $fd $fd_t) - ;; The buffer where directory entries are stored + ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) (param $buf_len $size_t) - ;; The location within the directory to start reading + ;;; The location within the directory to start reading (param $cookie $dircookie_t) (result $error $errno_t) - ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. (result $bufused $size_t) ) - ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;;; Atomically replace a file descriptor by renumbering another file descriptor. ;; - ;; Due to the strong focus on thread safety, this environment does not provide - ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;; file descriptor with the same number could be allocated by a different - ;; thread at the same time. + ;;; Due to the strong focus on thread safety, this environment does not provide + ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;;; file descriptor with the same number could be allocated by a different + ;;; thread at the same time. ;; - ;; This function provides a way to atomically renumber file descriptors, which - ;; would disappear if `dup2()` were to be removed entirely. + ;;; This function provides a way to atomically renumber file descriptors, which + ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") (param $fd $fd_t) - ;; The file descriptor to overwrite. + ;;; The file descriptor to overwrite. (param $to $fd_t) (result $error $errno_t) ) - ;; Move the offset of a file descriptor. - ;; Note: This is similar to `lseek` in POSIX. + ;;; Move the offset of a file descriptor. + ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") (param $fd $fd_t) - ;; The number of bytes to move. + ;;; The number of bytes to move. (param $offset $filedelta_t) - ;; The base from which the offset is relative. + ;;; The base from which the offset is relative. (param $whence $whence_t) (result $error $errno_t) - ;; The new offset of the file descriptor, relative to the start of the file. + ;;; The new offset of the file descriptor, relative to the start of the file. (result $newoffset $filesize_t) ) - ;; Synchronize the data and metadata of a file to disk. - ;; Note: This is similar to `fsync` in POSIX. + ;;; Synchronize the data and metadata of a file to disk. + ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Return the current offset of a file descriptor. - ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + ;;; Return the current offset of a file descriptor. + ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd_t) (result $error $errno_t) - ;; The current offset of the file descriptor, relative to the start of the file. + ;;; The current offset of the file descriptor, relative to the start of the file. (result $offset $filesize_t) ) - ;; Write to a file descriptor. - ;; Note: This is similar to `writev` in POSIX. + ;;; Write to a file descriptor. + ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Create a directory. - ;; Note: This is similar to `mkdirat` in POSIX. + ;;; Create a directory. + ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") (param $fd $fd_t) - ;; The path at which to create the directory. + ;;; The path at which to create the directory. (param $path string) (result $error $errno_t) ) - ;; Return the attributes of a file or directory. - ;; Note: This is similar to `stat` in POSIX. + ;;; Return the attributes of a file or directory. + ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to inspect. + ;;; The path of the file or directory to inspect. (param $path string) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the timestamps of a file or directory. - ;; Note: This is similar to `utimensat` in POSIX. + ;;; Adjust the timestamps of a file or directory. + ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to operate on. + ;;; The path of the file or directory to operate on. (param $path string) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Create a hard link. - ;; Note: This is similar to `linkat` in POSIX. + ;;; Create a hard link. + ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") (param $old_fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) - ;; The source path from which to link. + ;;; The source path from which to link. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path at which to create the hard link. + ;;; The destination path at which to create the hard link. (param $new_path string) (result $error $errno_t) ) - ;; Open a file or directory. + ;;; Open a file or directory. ;; - ;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;; file descriptor not currently open; it is randomized to prevent - ;; applications from depending on making assumptions about indexes, since this - ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 2**31. + ;;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;;; file descriptor not currently open; it is randomized to prevent + ;;; applications from depending on making assumptions about indexes, since this + ;;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;;; guaranteed to be less than 2**31. ;; - ;; Note: This is similar to `openat` in POSIX. + ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags_t) - ;; The relative path of the file or directory to open, relative to the - ;; `dirfd` directory. + ;;; The relative path of the file or directory to open, relative to the + ;;; `dirfd` directory. (param $path string) - ;; The method by which to open the file. + ;;; The method by which to open the file. (param $o_flags $oflags_t) - ;; The initial rights of the newly created file descriptor. The - ;; implementation is allowed to return a file descriptor with fewer rights - ;; than specified, if and only if those rights do not apply to the type of - ;; file being opened. + ;;; The initial rights of the newly created file descriptor. The + ;;; implementation is allowed to return a file descriptor with fewer rights + ;;; than specified, if and only if those rights do not apply to the type of + ;;; file being opened. ;; - ;; The *base* rights are rights that will apply to operations using the file - ;; descriptor itself, while the *inheriting* rights are rights that apply to - ;; file descriptors derived from it. + ;;; The *base* rights are rights that will apply to operations using the file + ;;; descriptor itself, while the *inheriting* rights are rights that apply to + ;;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) (param $flags $fdflags_t) (result $error $errno_t) - ;; The file descriptor of the file that has been opened. + ;;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) ) - ;; Read the contents of a symbolic link. - ;; Note: This is similar to `readlinkat` in POSIX. + ;;; Read the contents of a symbolic link. + ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") (param $fd $fd_t) - ;; The path of the symbolic link from which to read. + ;;; The path of the symbolic link from which to read. (param $path string) - ;; The buffer to which to write the contents of the symbolic link. + ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) - ;; The number of bytes placed in the buffer. + ;;; The number of bytes placed in the buffer. (result $bufused $size_t) ) - ;; Remove a directory. - ;; Return `ENOTEMPTY` if the directory is not empty. - ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + ;;; Remove a directory. + ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd_t) - ;; The path to a directory to remove. + ;;; The path to a directory to remove. (param $path string) (result $error $errno_t) ) - ;; Rename a file or directory. - ;; Note: This is similar to `renameat` in POSIX. + ;;; Rename a file or directory. + ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") (param $fd $fd_t) - ;; The source path of the file or directory to rename. + ;;; The source path of the file or directory to rename. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path to which to rename the file or directory. + ;;; The destination path to which to rename the file or directory. (param $new_path string) (result $error $errno_t) ) - ;; Create a symbolic link. - ;; Note: This is similar to `symlinkat` in POSIX. + ;;; Create a symbolic link. + ;;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - ;; The contents of the symbolic link. + ;;; The contents of the symbolic link. (param $old_path string) (param $fd $fd_t) - ;; The destination path at which to create the symbolic link. + ;;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) ) - ;; Unlink a file. - ;; Return `EISDIR` if the path refers to a directory. - ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + ;;; Unlink a file. + ;;; Return `EISDIR` if the path refers to a directory. + ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd_t) - ;; The path to a file to unlink. + ;;; The path to a file to unlink. (param $path string) (result $error $errno_t) ) - ;; Concurrently poll for the occurrence of a set of events. + ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") - ;; The events to which to subscribe. + ;;; The events to which to subscribe. (param $in (@witx const_pointer $subscription_t)) - ;; The events that have occurred. + ;;; The events that have occurred. (param $out (@witx pointer $event_t)) - ;; Both the number of subscriptions and events. + ;;; Both the number of subscriptions and events. (param $nsubscriptions $size_t) (result $error $errno_t) - ;; The number of events stored. + ;;; The number of events stored. (result $nevents $size_t) ) - ;; Terminate the process normally. An exit code of 0 indicates successful - ;; termination of the program. The meanings of other values is dependent on - ;; the environment. + ;;; Terminate the process normally. An exit code of 0 indicates successful + ;;; termination of the program. The meanings of other values is dependent on + ;;; the environment. (@interface func (export "proc_exit") - ;; The exit code returned by the process. + ;;; The exit code returned by the process. (param $rval $exitcode_t) ) - ;; Send a signal to the process of the calling thread. - ;; Note: This is similar to `raise` in POSIX. + ;;; Send a signal to the process of the calling thread. + ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") - ;; The signal condition to trigger. + ;;; The signal condition to trigger. (param $sig $signal_t) (result $error $errno_t) ) - ;; Temporarily yield execution of the calling thread. - ;; Note: This is similar to `sched_yield` in POSIX. + ;;; Temporarily yield execution of the calling thread. + ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") (result $error $errno_t) ) - ;; Write high-quality random data into a buffer. - ;; This function blocks when the implementation is unable to immediately - ;; provide sufficient high-quality random data. - ;; This function may execute slowly, so when large mounts of random data are - ;; required, it's advisable to use this function to seed a pseudo-random - ;; number generator, rather than to provide the random data directly. + ;;; Write high-quality random data into a buffer. + ;;; This function blocks when the implementation is unable to immediately + ;;; provide sufficient high-quality random data. + ;;; This function may execute slowly, so when large mounts of random data are + ;;; required, it's advisable to use this function to seed a pseudo-random + ;;; number generator, rather than to provide the random data directly. (@interface func (export "random_get") - ;; The buffer to fill with random data. + ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) ) - ;; Receive a message from a socket. - ;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;; the data into multiple buffers in the manner of `readv`. + ;;; Receive a message from a socket. + ;;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $ri_data $iovec_t_array) - ;; Message flags. + ;;; Message flags. (param $ri_flags $riflags_t) (result $error $errno_t) - ;; Number of bytes stored in ri_data. + ;;; Number of bytes stored in ri_data. (result $ro_datalen $size_t) - ;; Message flags. + ;;; Message flags. (result $ro_flags $roflags_t) ) - ;; Send a message on a socket. - ;; Note: This is similar to `send` in POSIX, though it also supports writing - ;; the data from multiple buffers in the manner of `writev`. + ;;; Send a message on a socket. + ;;; Note: This is similar to `send` in POSIX, though it also supports writing + ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to retrieve data + ;;; List of scatter/gather vectors to which to retrieve data (param $si_data $ciovec_t_array) - ;; Message flags. + ;;; Message flags. (param $si_flags $siflags_t) (result $error $errno_t) - ;; Number of bytes transmitted. + ;;; Number of bytes transmitted. (result $so_datalen $size_t) ) - ;; Shut down socket send and receive channels. - ;; Note: This is similar to `shutdown` in POSIX. + ;;; Shut down socket send and receive channels. + ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") (param $fd $fd_t) - ;; Which channels on the socket to shut down. + ;;; Which channels on the socket to shut down. (param $how $sdflags_t) (result $error $errno_t) ) diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx index 1a45be1fd..68f6fac4a 100644 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -7,291 +7,291 @@ (typename $size_t u32) -;; Non-negative file size or length of a region within a file. +;;; Non-negative file size or length of a region within a file. (typename $filesize_t u64) -;; Timestamp in nanoseconds. +;;; Timestamp in nanoseconds. (typename $timestamp_t u64) -;; Identifiers for clocks. +;;; Identifiers for clocks. (typename $clockid_t (enum u32 - ;; The clock measuring real time. Time value zero corresponds with - ;; 1970-01-01T00:00:00Z. + ;;; The clock measuring real time. Time value zero corresponds with + ;;; 1970-01-01T00:00:00Z. $CLOCK_REALTIME - ;; The store-wide monotonic clock, which is defined as a clock measuring - ;; real time, whose value cannot be adjusted and which cannot have negative - ;; clock jumps. The epoch of this clock is undefined. The absolute time - ;; value of this clock therefore has no meaning. + ;;; The store-wide monotonic clock, which is defined as a clock measuring + ;;; real time, whose value cannot be adjusted and which cannot have negative + ;;; clock jumps. The epoch of this clock is undefined. The absolute time + ;;; value of this clock therefore has no meaning. $CLOCK_MONOTONIC - ;; The CPU-time clock associated with the current process. + ;;; The CPU-time clock associated with the current process. $CLOCK_PROCESS_CPUTIME_ID - ;; The CPU-time clock associated with the current thread. + ;;; The CPU-time clock associated with the current thread. $CLOCK_THREAD_CPUTIME_ID ) ) -;; Error codes returned by functions. -;; Not all of these error codes are returned by the functions provided by this -;; API; some are used in higher-level library layers, and others are provided -;; merely for alignment with POSIX. +;;; Error codes returned by functions. +;;; Not all of these error codes are returned by the functions provided by this +;;; API; some are used in higher-level library layers, and others are provided +;;; merely for alignment with POSIX. (typename $errno_t (enum u16 - ;; No error occurred. System call completed successfully. + ;;; No error occurred. System call completed successfully. $ESUCCESS - ;; Argument list too long. + ;;; Argument list too long. $E2BIG - ;; Permission denied. + ;;; Permission denied. $EACCES - ;; Address in use. + ;;; Address in use. $EADDRINUSE - ;; Address not available. + ;;; Address not available. $EADDRNOTAVAIL - ;; Address family not supported. + ;;; Address family not supported. $EAFNOSUPPORT - ;; Resource unavailable, or operation would block. + ;;; Resource unavailable, or operation would block. $EAGAIN - ;; Connection already in progress. + ;;; Connection already in progress. $EALREADY - ;; Bad file descriptor. + ;;; Bad file descriptor. $EBADF - ;; Bad message. + ;;; Bad message. $EBADMSG - ;; Device or resource busy. + ;;; Device or resource busy. $EBUSY - ;; Operation canceled. + ;;; Operation canceled. $ECANCELED - ;; No child processes. + ;;; No child processes. $ECHILD - ;; Connection aborted. + ;;; Connection aborted. $ECONNABORTED - ;; Connection refused. + ;;; Connection refused. $ECONNREFUSED - ;; Connection reset. + ;;; Connection reset. $ECONNRESET - ;; Resource deadlock would occur. + ;;; Resource deadlock would occur. $EDEADLK - ;; Destination address required. + ;;; Destination address required. $EDESTADDRREQ - ;; Mathematics argument out of domain of function. + ;;; Mathematics argument out of domain of function. $EDOM - ;; Reserved. + ;;; Reserved. $EDQUOT - ;; File exists. + ;;; File exists. $EEXIST - ;; Bad address. + ;;; Bad address. $EFAULT - ;; File too large. + ;;; File too large. $EFBIG - ;; Host is unreachable. + ;;; Host is unreachable. $EHOSTUNREACH - ;; Identifier removed. + ;;; Identifier removed. $EIDRM - ;; Illegal byte sequence. + ;;; Illegal byte sequence. $EILSEQ - ;; Operation in progress. + ;;; Operation in progress. $EINPROGRESS - ;; Interrupted function. + ;;; Interrupted function. $EINTR - ;; Invalid argument. + ;;; Invalid argument. $EINVAL - ;; I/O error. + ;;; I/O error. $EIO - ;; Socket is connected. + ;;; Socket is connected. $EISCONN - ;; Is a directory. + ;;; Is a directory. $EISDIR - ;; Too many levels of symbolic links. + ;;; Too many levels of symbolic links. $ELOOP - ;; File descriptor value too large. + ;;; File descriptor value too large. $EMFILE - ;; Too many links. + ;;; Too many links. $EMLINK - ;; Message too large. + ;;; Message too large. $EMSGSIZE - ;; Reserved. + ;;; Reserved. $EMULTIHOP - ;; Filename too long. + ;;; Filename too long. $ENAMETOOLONG - ;; Network is down. + ;;; Network is down. $ENETDOWN - ;; Connection aborted by network. + ;;; Connection aborted by network. $ENETRESET - ;; Network unreachable. + ;;; Network unreachable. $ENETUNREACH - ;; Too many files open in system. + ;;; Too many files open in system. $ENFILE - ;; No buffer space available. + ;;; No buffer space available. $ENOBUFS - ;; No such device. + ;;; No such device. $ENODEV - ;; No such file or directory. + ;;; No such file or directory. $ENOENT - ;; Executable file format error. + ;;; Executable file format error. $ENOEXEC - ;; No locks available. + ;;; No locks available. $ENOLCK - ;; Reserved. + ;;; Reserved. $ENOLINK - ;; Not enough space. + ;;; Not enough space. $ENOMEM - ;; No message of the desired type. + ;;; No message of the desired type. $ENOMSG - ;; Protocol not available. + ;;; Protocol not available. $ENOPROTOOPT - ;; No space left on device. + ;;; No space left on device. $ENOSPC - ;; Function not supported. + ;;; Function not supported. $ENOSYS - ;; The socket is not connected. + ;;; The socket is not connected. $ENOTCONN - ;; Not a directory or a symbolic link to a directory. + ;;; Not a directory or a symbolic link to a directory. $ENOTDIR - ;; Directory not empty. + ;;; Directory not empty. $ENOTEMPTY - ;; State not recoverable. + ;;; State not recoverable. $ENOTRECOVERABLE - ;; Not a socket. + ;;; Not a socket. $ENOTSOCK - ;; Not supported, or operation not supported on socket. + ;;; Not supported, or operation not supported on socket. $ENOTSUP - ;; Inappropriate I/O control operation. + ;;; Inappropriate I/O control operation. $ENOTTY - ;; No such device or address. + ;;; No such device or address. $ENXIO - ;; Value too large to be stored in data type. + ;;; Value too large to be stored in data type. $EOVERFLOW - ;; Previous owner died. + ;;; Previous owner died. $EOWNERDEAD - ;; Operation not permitted. + ;;; Operation not permitted. $EPERM - ;; Broken pipe. + ;;; Broken pipe. $EPIPE - ;; Protocol error. + ;;; Protocol error. $EPROTO - ;; Protocol not supported. + ;;; Protocol not supported. $EPROTONOSUPPORT - ;; Protocol wrong type for socket. + ;;; Protocol wrong type for socket. $EPROTOTYPE - ;; Result too large. + ;;; Result too large. $ERANGE - ;; Read-only file system. + ;;; Read-only file system. $EROFS - ;; Invalid seek. + ;;; Invalid seek. $ESPIPE - ;; No such process. + ;;; No such process. $ESRCH - ;; Reserved. + ;;; Reserved. $ESTALE - ;; Connection timed out. + ;;; Connection timed out. $ETIMEDOUT - ;; Text file busy. + ;;; Text file busy. $ETXTBSY - ;; Cross-device link. + ;;; Cross-device link. $EXDEV - ;; Extension: Capabilities insufficient. + ;;; Extension: Capabilities insufficient. $ENOTCAPABLE ) ) -;; File descriptor rights, determining which actions may be performed. +;;; File descriptor rights, determining which actions may be performed. (typename $rights_t (flags u64 - ;; The right to invoke `fd_datasync`. + ;;; The right to invoke `fd_datasync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_DSYNC`. $RIGHT_FD_DATASYNC - ;; The right to invoke `fd_read` and `sock_recv`. + ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. $RIGHT_FD_READ - ;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. + ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. $RIGHT_FD_SEEK - ;; The right to invoke `fd_fdstat_set_flags`. + ;;; The right to invoke `fd_fdstat_set_flags`. $RIGHT_FD_FDSTAT_SET_FLAGS - ;; The right to invoke `fd_sync`. + ;;; The right to invoke `fd_sync`. ;; - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. $RIGHT_FD_SYNC - ;; The right to invoke `fd_seek` in such a way that the file offset - ;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to - ;; invoke `fd_tell`. + ;;; The right to invoke `fd_seek` in such a way that the file offset + ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; invoke `fd_tell`. $RIGHT_FD_TELL - ;; The right to invoke `fd_write` and `sock_send`. - ;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. + ;;; The right to invoke `fd_write` and `sock_send`. + ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. $RIGHT_FD_WRITE - ;; The right to invoke `fd_advise`. + ;;; The right to invoke `fd_advise`. $RIGHT_FD_ADVISE - ;; The right to invoke `fd_allocate`. + ;;; The right to invoke `fd_allocate`. $RIGHT_FD_ALLOCATE - ;; The right to invoke `path_create_directory`. + ;;; The right to invoke `path_create_directory`. $RIGHT_PATH_CREATE_DIRECTORY - ;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. + ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. $RIGHT_PATH_CREATE_FILE - ;; The right to invoke `path_link` with the file descriptor as the - ;; source directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; source directory. $RIGHT_PATH_LINK_SOURCE - ;; The right to invoke `path_link` with the file descriptor as the - ;; target directory. + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; target directory. $RIGHT_PATH_LINK_TARGET - ;; The right to invoke `path_open`. + ;;; The right to invoke `path_open`. $RIGHT_PATH_OPEN - ;; The right to invoke `fd_readdir`. + ;;; The right to invoke `fd_readdir`. $RIGHT_FD_READDIR - ;; The right to invoke `path_readlink`. + ;;; The right to invoke `path_readlink`. $RIGHT_PATH_READLINK - ;; The right to invoke `path_rename` with the file descriptor as the source directory. + ;;; The right to invoke `path_rename` with the file descriptor as the source directory. $RIGHT_PATH_RENAME_SOURCE - ;; The right to invoke `path_rename` with the file descriptor as the target directory. + ;;; The right to invoke `path_rename` with the file descriptor as the target directory. $RIGHT_PATH_RENAME_TARGET - ;; The right to invoke `path_filestat_get`. + ;;; The right to invoke `path_filestat_get`. $RIGHT_PATH_FILESTAT_GET - ;; The right to change a file's size (there is no `path_filestat_set_size`). - ;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. + ;;; The right to change a file's size (there is no `path_filestat_set_size`). + ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. $RIGHT_PATH_FILESTAT_SET_SIZE - ;; The right to invoke `path_filestat_set_times`. + ;;; The right to invoke `path_filestat_set_times`. $RIGHT_PATH_FILESTAT_SET_TIMES - ;; The right to invoke `fd_filestat_get`. + ;;; The right to invoke `fd_filestat_get`. $RIGHT_FD_FILESTAT_GET - ;; The right to invoke `fd_filestat_set_size`. + ;;; The right to invoke `fd_filestat_set_size`. $RIGHT_FD_FILESTAT_SET_SIZE - ;; The right to invoke `fd_filestat_set_times`. + ;;; The right to invoke `fd_filestat_set_times`. $RIGHT_FD_FILESTAT_SET_TIMES - ;; The right to invoke `path_symlink`. + ;;; The right to invoke `path_symlink`. $RIGHT_PATH_SYMLINK - ;; The right to invoke `path_remove_directory`. + ;;; The right to invoke `path_remove_directory`. $RIGHT_PATH_REMOVE_DIRECTORY - ;; The right to invoke `path_unlink_file`. + ;;; The right to invoke `path_unlink_file`. $RIGHT_PATH_UNLINK_FILE - ;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. + ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. + ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. $RIGHT_POLL_FD_READWRITE - ;; The right to invoke `sock_shutdown`. + ;;; The right to invoke `sock_shutdown`. $RIGHT_SOCK_SHUTDOWN ) ) -;; A file descriptor index. +;;; A file descriptor index. (typename $fd_t u32) -;; A region of memory for scatter/gather reads. +;;; A region of memory for scatter/gather reads. (typename $iovec_t (struct - ;; The address of the buffer to be filled. + ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) - ;; The length of the buffer to be filled. + ;;; The length of the buffer to be filled. (field $buf_len $size_t) ) ) -;; A region of memory for scatter/gather writes. +;;; A region of memory for scatter/gather writes. (typename $ciovec_t (struct - ;; The address of the buffer to be written. + ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) - ;; The length of the buffer to be written. + ;;; The length of the buffer to be written. (field $buf_len $size_t) ) ) @@ -299,469 +299,469 @@ (typename $iovec_t_array (array $iovec_t)) (typename $ciovec_t_array (array $ciovec_t)) -;; Relative offset within a file. +;;; Relative offset within a file. (typename $filedelta_t s64) -;; The position relative to which to set the offset of the file descriptor. +;;; The position relative to which to set the offset of the file descriptor. (typename $whence_t (enum u8 - ;; Seek relative to start-of-file. + ;;; Seek relative to start-of-file. $WHENCE_SET - ;; Seek relative to current position. + ;;; Seek relative to current position. $WHENCE_CUR - ;; Seek relative to end-of-file. + ;;; Seek relative to end-of-file. $WHENCE_END ) ) -;; A reference to the offset of a directory entry. -;; -;; The value 0 signifies the start of the directory. +;;; A reference to the offset of a directory entry. +;;; +;;; The value 0 signifies the start of the directory. (typename $dircookie_t u64) -;; The type for the $d_namlen field of $dirent_t. +;;; The type for the $d_namlen field of $dirent_t. (typename $dirnamlen_t u32) -;; File serial number that is unique within its file system. +;;; File serial number that is unique within its file system. (typename $inode_t u64) -;; The type of a file descriptor or file. +;;; The type of a file descriptor or file. (typename $filetype_t (enum u8 - ;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $FILETYPE_UNKNOWN - ;; The file descriptor or file refers to a block device inode. + ;;; The file descriptor or file refers to a block device inode. $FILETYPE_BLOCK_DEVICE - ;; The file descriptor or file refers to a character device inode. + ;;; The file descriptor or file refers to a character device inode. $FILETYPE_CHARACTER_DEVICE - ;; The file descriptor or file refers to a directory inode. + ;;; The file descriptor or file refers to a directory inode. $FILETYPE_DIRECTORY - ;; The file descriptor or file refers to a regular file inode. + ;;; The file descriptor or file refers to a regular file inode. $FILETYPE_REGULAR_FILE - ;; The file descriptor or file refers to a datagram socket. + ;;; The file descriptor or file refers to a datagram socket. $FILETYPE_SOCKET_DGRAM - ;; The file descriptor or file refers to a byte-stream socket. + ;;; The file descriptor or file refers to a byte-stream socket. $FILETYPE_SOCKET_STREAM - ;; The file refers to a symbolic link inode. + ;;; The file refers to a symbolic link inode. $FILETYPE_SYMBOLIC_LINK ) ) -;; A directory entry. +;;; A directory entry. (typename $dirent_t (struct - ;; The offset of the next directory entry stored in this directory. + ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie_t) - ;; The serial number of the file referred to by this directory entry. + ;;; The serial number of the file referred to by this directory entry. (field $d_ino $inode_t) - ;; The length of the name of the directory entry. + ;;; The length of the name of the directory entry. (field $d_namlen $dirnamlen_t) - ;; The type of the file referred to by this directory entry. + ;;; The type of the file referred to by this directory entry. (field $d_type $filetype_t) ) ) -;; File or memory access pattern advisory information. +;;; File or memory access pattern advisory information. (typename $advice_t (enum u8 - ;; The application has no advice to give on its behavior with respect to the specified data. + ;;; The application has no advice to give on its behavior with respect to the specified data. $ADVICE_NORMAL - ;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. $ADVICE_SEQUENTIAL - ;; The application expects to access the specified data in a random order. + ;;; The application expects to access the specified data in a random order. $ADVICE_RANDOM - ;; The application expects to access the specified data in the near future. + ;;; The application expects to access the specified data in the near future. $ADVICE_WILLNEED - ;; The application expects that it will not access the specified data in the near future. + ;;; The application expects that it will not access the specified data in the near future. $ADVICE_DONTNEED - ;; The application expects to access the specified data once and then not reuse it thereafter. + ;;; The application expects to access the specified data once and then not reuse it thereafter. $ADVICE_NOREUSE ) ) -;; File descriptor flags. +;;; File descriptor flags. (typename $fdflags_t (flags u16 - ;; Append mode: Data written to the file is always appended to the file's end. + ;;; Append mode: Data written to the file is always appended to the file's end. $FDFLAG_APPEND - ;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. $FDFLAG_DSYNC - ;; Non-blocking mode. + ;;; Non-blocking mode. $FDFLAG_NONBLOCK - ;; Synchronized read I/O operations. + ;;; Synchronized read I/O operations. $FDFLAG_RSYNC - ;; Write according to synchronized I/O file integrity completion. In - ;; addition to synchronizing the data stored in the file, the implementation - ;; may also synchronously update the file's metadata. + ;;; Write according to synchronized I/O file integrity completion. In + ;;; addition to synchronizing the data stored in the file, the implementation + ;;; may also synchronously update the file's metadata. $FDFLAG_SYNC ) ) -;; File descriptor attributes. +;;; File descriptor attributes. (typename $fdstat_t (struct - ;; File type. + ;;; File type. (field $fs_filetype $filetype_t) - ;; File descriptor flags. + ;;; File descriptor flags. (field $fs_flags $fdflags_t) - ;; Rights that apply to this file descriptor. + ;;; Rights that apply to this file descriptor. (field $fs_rights_base $rights_t) - ;; Maximum set of rights that may be installed on new file descriptors that - ;; are created through this file descriptor, e.g., through `path_open`. + ;;; Maximum set of rights that may be installed on new file descriptors that + ;;; are created through this file descriptor, e.g., through `path_open`. (field $fs_rights_inheriting $rights_t) ) ) -;; Identifier for a device containing a file system. Can be used in combination -;; with `inode_t` to uniquely identify a file or directory in the filesystem. +;;; Identifier for a device containing a file system. Can be used in combination +;;; with `inode_t` to uniquely identify a file or directory in the filesystem. (typename $device_t u64) -;; Which file time attributes to adjust. +;;; Which file time attributes to adjust. (typename $fstflags_t (flags u16 - ;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. $FILESTAT_SET_ATIM - ;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_ATIM_NOW - ;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. $FILESTAT_SET_MTIM - ;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. + ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. $FILESTAT_SET_MTIM_NOW ) ) -;; Flags determining the method of how paths are resolved. +;;; Flags determining the method of how paths are resolved. (typename $lookupflags_t (flags u32 - ;; As long as the resolved path corresponds to a symbolic link, it is expanded. + ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $LOOKUP_SYMLINK_FOLLOW ) ) -;; Open flags used by `path_open`. +;;; Open flags used by `path_open`. (typename $oflags_t (flags u16 - ;; Create file if it does not exist. + ;;; Create file if it does not exist. $O_CREAT - ;; Fail if not a directory. + ;;; Fail if not a directory. $O_DIRECTORY - ;; Fail if file already exists. + ;;; Fail if file already exists. $O_EXCL - ;; Truncate file to size 0. + ;;; Truncate file to size 0. $O_TRUNC ) ) -;; Number of hard links to an inode. +;;; Number of hard links to an inode. (typename $linkcount_t u64) -;; File attributes. +;;; File attributes. (typename $filestat_t (struct - ;; Device ID of device containing the file. + ;;; Device ID of device containing the file. (field $st_dev $device_t) - ;; File serial number. + ;;; File serial number. (field $st_ino $inode_t) - ;; File type. + ;;; File type. (field $st_filetype $filetype_t) - ;; Number of hard links to the file. + ;;; Number of hard links to the file. (field $st_nlink $linkcount_t) - ;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. (field $st_size $filesize_t) - ;; Last data access timestamp. + ;;; Last data access timestamp. (field $st_atim $timestamp_t) - ;; Last data modification timestamp. + ;;; Last data modification timestamp. (field $st_mtim $timestamp_t) - ;; Last file status change timestamp. + ;;; Last file status change timestamp. (field $st_ctim $timestamp_t) ) ) -;; User-provided value that may be attached to objects that is retained when -;; extracted from the implementation. +;;; User-provided value that may be attached to objects that is retained when +;;; extracted from the implementation. (typename $userdata_t u64) -;; Type of a subscription to an event or its occurrence. +;;; Type of a subscription to an event or its occurrence. (typename $eventtype_t (enum u8 - ;; The time value of clock `subscription_t::u.clock.clock_id` has - ;; reached timestamp `subscription_t::u.clock.timeout`. + ;;; The time value of clock `subscription_t::u.clock.clock_id` has + ;;; reached timestamp `subscription_t::u.clock.timeout`. $EVENTTYPE_CLOCK - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has data - ;; available for reading. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; available for reading. This event always triggers for regular files. $EVENTTYPE_FD_READ - ;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity - ;; available for writing. This event always triggers for regular files. + ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + ;;; available for writing. This event always triggers for regular files. $EVENTTYPE_FD_WRITE ) ) -;; The state of the file descriptor subscribed to with -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The state of the file descriptor subscribed to with +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $eventrwflags_t (flags u16 - ;; The peer of this socket has closed or disconnected. + ;;; The peer of this socket has closed or disconnected. $EVENT_FD_READWRITE_HANGUP ) ) -;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;; `EVENTTYPE_FD_WRITE`. +;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or +;;; `EVENTTYPE_FD_WRITE`. (typename $event_fd_readwrite_t (struct - ;; The number of bytes available for reading or writing. + ;;; The number of bytes available for reading or writing. (field $nbytes $filesize_t) - ;; The state of the file descriptor. + ;;; The state of the file descriptor. (field $flags $eventrwflags_t) ) ) -;; The contents of an $event_t. +;;; The contents of an $event_t. (typename $event_u (union - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $event_fd_readwrite_t) ) ) -;; An event that occurred. +;;; An event that occurred. (typename $event_t (struct - ;; User-provided value that got attached to `subscription_t::userdata`. + ;;; User-provided value that got attached to `subscription_t::userdata`. (field $userdata $userdata_t) - ;; If non-zero, an error that occurred while processing the subscription request. + ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno_t) - ;; The type of the event that occurred. + ;;; The type of the event that occurred. (field $type $eventtype_t) - ;; The contents of the event. + ;;; The contents of the event. (field $u $event_u) ) ) -;; Flags determining how to interpret the timestamp provided in -;; `subscription_t::u.clock.timeout.` +;;; Flags determining how to interpret the timestamp provided in +;;; `subscription_t::u.clock.timeout.` (typename $subclockflags_t (flags u16 - ;; If set, treat the timestamp provided in - ;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;; provided in `subscription_t::u.clock.timeout` relative to the - ;; current time value of clock `subscription_t::u.clock.clock_id.` + ;;; If set, treat the timestamp provided in + ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription_t::u.clock.timeout` relative to the + ;;; current time value of clock `subscription_t::u.clock.clock_id.` $SUBSCRIPTION_CLOCK_ABSTIME ) ) -;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. +;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. (typename $subscription_clock_t (struct - ;; The clock against which to compare the timestamp. + ;;; The clock against which to compare the timestamp. (field $clock_id $clockid_t) - ;; The absolute or relative timestamp. + ;;; The absolute or relative timestamp. (field $timeout $timestamp_t) - ;; The amount of time that the implementation may wait additionally - ;; to coalesce with other events. + ;;; The amount of time that the implementation may wait additionally + ;;; to coalesce with other events. (field $precision $timestamp_t) - ;; Flags specifying whether the timeout is absolute or relative + ;;; Flags specifying whether the timeout is absolute or relative (field $flags $subclockflags_t) ) ) -;; The contents of a $subscription_t when type is type is -;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. +;;; The contents of a $subscription_t when type is type is +;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. (typename $subscription_fd_readwrite_t (struct - ;; The file descriptor on which to wait for it to become ready for reading or writing. + ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd_t) ) ) -;; The contents of a $subscription_t. +;;; The contents of a $subscription_t. (typename $subscription_u (union - ;; When type is `EVENTTYPE_CLOCK`: + ;;; When type is `EVENTTYPE_CLOCK`: (field $clock $subscription_clock_t) - ;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: + ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: (field $fd_readwrite $subscription_fd_readwrite_t) ) ) -;; Subscription to an event. +;;; Subscription to an event. (typename $subscription_t (struct - ;; User-provided value that is attached to the subscription in the - ;; implementation and returned through `event_t::userdata`. + ;;; User-provided value that is attached to the subscription in the + ;;; implementation and returned through `event_t::userdata`. (field $userdata $userdata_t) - ;; The type of the event to which to subscribe. + ;;; The type of the event to which to subscribe. (field $type $eventtype_t) - ;; The contents of the subscription. + ;;; The contents of the subscription. (field $u $subscription_u) ) ) -;; Exit code generated by a process when exiting. +;;; Exit code generated by a process when exiting. (typename $exitcode_t u32) -;; Signal condition. +;;; Signal condition. (typename $signal_t (enum u8 - ;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;; so this value is reserved. + ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, + ;;; so this value is reserved. $SIGNONE - ;; Hangup. - ;; Action: Terminates the process. + ;;; Hangup. + ;;; Action: Terminates the process. $SIGHUP - ;; Terminate interrupt signal. - ;; Action: Terminates the process. + ;;; Terminate interrupt signal. + ;;; Action: Terminates the process. $SIGINT - ;; Terminal quit signal. - ;; Action: Terminates the process. + ;;; Terminal quit signal. + ;;; Action: Terminates the process. $SIGQUIT - ;; Illegal instruction. - ;; Action: Terminates the process. + ;;; Illegal instruction. + ;;; Action: Terminates the process. $SIGILL - ;; Trace/breakpoint trap. - ;; Action: Terminates the process. + ;;; Trace/breakpoint trap. + ;;; Action: Terminates the process. $SIGTRAP - ;; Process abort signal. - ;; Action: Terminates the process. + ;;; Process abort signal. + ;;; Action: Terminates the process. $SIGABRT - ;; Access to an undefined portion of a memory object. - ;; Action: Terminates the process. + ;;; Access to an undefined portion of a memory object. + ;;; Action: Terminates the process. $SIGBUS - ;; Erroneous arithmetic operation. - ;; Action: Terminates the process. + ;;; Erroneous arithmetic operation. + ;;; Action: Terminates the process. $SIGFPE - ;; Kill. - ;; Action: Terminates the process. + ;;; Kill. + ;;; Action: Terminates the process. $SIGKILL - ;; User-defined signal 1. - ;; Action: Terminates the process. + ;;; User-defined signal 1. + ;;; Action: Terminates the process. $SIGUSR1 - ;; Invalid memory reference. - ;; Action: Terminates the process. + ;;; Invalid memory reference. + ;;; Action: Terminates the process. $SIGSEGV - ;; User-defined signal 2. - ;; Action: Terminates the process. + ;;; User-defined signal 2. + ;;; Action: Terminates the process. $SIGUSR2 - ;; Write on a pipe with no one to read it. - ;; Action: Ignored. + ;;; Write on a pipe with no one to read it. + ;;; Action: Ignored. $SIGPIPE - ;; Alarm clock. - ;; Action: Terminates the process. + ;;; Alarm clock. + ;;; Action: Terminates the process. $SIGALRM - ;; Termination signal. - ;; Action: Terminates the process. + ;;; Termination signal. + ;;; Action: Terminates the process. $SIGTERM - ;; Child process terminated, stopped, or continued. - ;; Action: Ignored. + ;;; Child process terminated, stopped, or continued. + ;;; Action: Ignored. $SIGCHLD - ;; Continue executing, if stopped. - ;; Action: Continues executing, if stopped. + ;;; Continue executing, if stopped. + ;;; Action: Continues executing, if stopped. $SIGCONT - ;; Stop executing. - ;; Action: Stops executing. + ;;; Stop executing. + ;;; Action: Stops executing. $SIGSTOP - ;; Terminal stop signal. - ;; Action: Stops executing. + ;;; Terminal stop signal. + ;;; Action: Stops executing. $SIGTSTP - ;; Background process attempting read. - ;; Action: Stops executing. + ;;; Background process attempting read. + ;;; Action: Stops executing. $SIGTTIN - ;; Background process attempting write. - ;; Action: Stops executing. + ;;; Background process attempting write. + ;;; Action: Stops executing. $SIGTTOU - ;; High bandwidth data is available at a socket. - ;; Action: Ignored. + ;;; High bandwidth data is available at a socket. + ;;; Action: Ignored. $SIGURG - ;; CPU time limit exceeded. - ;; Action: Terminates the process. + ;;; CPU time limit exceeded. + ;;; Action: Terminates the process. $SIGXCPU - ;; File size limit exceeded. - ;; Action: Terminates the process. + ;;; File size limit exceeded. + ;;; Action: Terminates the process. $SIGXFSZ - ;; Virtual timer expired. - ;; Action: Terminates the process. + ;;; Virtual timer expired. + ;;; Action: Terminates the process. $SIGVTALRM - ;; Profiling timer expired. - ;; Action: Terminates the process. + ;;; Profiling timer expired. + ;;; Action: Terminates the process. $SIGPROF - ;; Window changed. - ;; Action: Ignored. + ;;; Window changed. + ;;; Action: Ignored. $SIGWINCH - ;; I/O possible. - ;; Action: Terminates the process. + ;;; I/O possible. + ;;; Action: Terminates the process. $SIGPOLL - ;; Power failure. - ;; Action: Terminates the process. + ;;; Power failure. + ;;; Action: Terminates the process. $SIGPWR - ;; Bad system call. - ;; Action: Terminates the process. + ;;; Bad system call. + ;;; Action: Terminates the process. $SIGSYS ) ) -;; Flags provided to `sock_recv`. +;;; Flags provided to `sock_recv`. (typename $riflags_t (flags u16 - ;; Returns the message without removing it from the socket's receive queue. + ;;; Returns the message without removing it from the socket's receive queue. $SOCK_RECV_PEEK - ;; On byte-stream sockets, block until the full amount of data can be returned. + ;;; On byte-stream sockets, block until the full amount of data can be returned. $SOCK_RECV_WAITALL ) ) -;; Flags returned by `sock_recv`. +;;; Flags returned by `sock_recv`. (typename $roflags_t (flags u16 - ;; Returned by `sock_recv`: Message data has been truncated. + ;;; Returned by `sock_recv`: Message data has been truncated. $SOCK_RECV_DATA_TRUNCATED ) ) -;; Flags provided to `sock_send`. As there are currently no flags -;; defined, it must be set to zero. +;;; Flags provided to `sock_send`. As there are currently no flags +;;; defined, it must be set to zero. (typename $siflags_t u16) -;; Which channels on a socket to shut down. +;;; Which channels on a socket to shut down. (typename $sdflags_t (flags u8 - ;; Disables further receive operations. + ;;; Disables further receive operations. $SHUT_RD - ;; Disables further send operations. + ;;; Disables further send operations. $SHUT_WR ) ) -;; Identifiers for preopened capabilities. +;;; Identifiers for preopened capabilities. (typename $preopentype_t (enum u8 - ;; A pre-opened directory. + ;;; A pre-opened directory. $PREOPENTYPE_DIR ) ) -;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. (typename $prestat_dir (struct - ;; The length of the directory name for use with `fd_prestat_dir_name`. + ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size_t) ) ) -;; The contents of an $prestat_t. +;;; The contents of an $prestat_t. (typename $prestat_u (union - ;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `PREOPENTYPE_DIR`: (field $dir $prestat_dir) ) ) -;; Information about a pre-opened capability. +;;; Information about a pre-opened capability. (typename $prestat_t (struct - ;; The type of the pre-opened capability. + ;;; The type of the pre-opened capability. (field $pr_type $preopentype_t) - ;; The contents of the information. + ;;; The contents of the information. (field $u $prestat_u) ) ) diff --git a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx index 630537416..e69b788dc 100644 --- a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -9,519 +9,522 @@ (use "typenames.witx") (module $wasi_snapshot_preview1 - ;; Linear memory to be accessed by WASI functions that need it. + ;;; Linear memory to be accessed by WASI functions that need it. (import "memory" (memory)) - ;; Read command-line argument data. - ;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; Read command-line argument data. + ;;; The size of the array should match that returned by `wasi_args_sizes_get()` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Read environment variable data. - ;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; Read environment variable data. + ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) (result $error $errno_t) ) - ;; Return command-line argument data sizes. + ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") (result $error $errno_t) - ;; The number of arguments. + ;;; The number of arguments. (result $argc $size_t) - ;; The size of the argument string data. + ;;; The size of the argument string data. (result $argv_buf_size $size_t) ) - ;; Return the resolution of a clock. - ;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;; Note: This is similar to `clock_getres` in POSIX. + ;;; Return the resolution of a clock. + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno_t) - ;; The clock for which to return the resolution. + ;;; The clock for which to return the resolution. (param $clock_id $clockid_t) - ;; The resolution of the clock. + ;;; The resolution of the clock. (result $resolution $timestamp_t) ) - ;; Return the time value of a clock. - ;; Note: This is similar to `clock_gettime` in POSIX. + ;;; Return the time value of a clock. + ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") - ;; The clock for which to return the time. + ;;; The clock for which to return the time. (param $clock_id $clockid_t) - ;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp_t) (result $error $errno_t) - ;; The time value of the clock. + ;;; The time value of the clock. (result $time $timestamp_t) ) - ;; Provide file advisory information on a file descriptor. - ;; Note: This is similar to `posix_fadvise` in POSIX. + ;;; Provide file advisory information on a file descriptor. + ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") (param $fd $fd_t) - (param $offset $filesize_t) ;; The offset within the file to which the advisory applies. - (param $len $filesize_t) ;; The length of the region to which the advisory applies. - (param $advice $advice_t) ;; The advice. + ;;; The offset within the file to which the advisory applies. + (param $offset $filesize_t) + ;;; The length of the region to which the advisory applies. + (param $len $filesize_t) + ;;; The advice. + (param $advice $advice_t) (result $error $errno_t) ) - ;; Force the allocation of space in a file. - ;; Note: This is similar to `posix_fallocate` in POSIX. + ;;; Force the allocation of space in a file. + ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") (param $fd $fd_t) - ;; The offset at which to start the allocation. + ;;; The offset at which to start the allocation. (param $offset $filesize_t) - ;; The length of the area that is allocated. + ;;; The length of the area that is allocated. (param $len $filesize_t) (result $error $errno_t) ) - ;; Close a file descriptor. - ;; Note: This is similar to `close` in POSIX. + ;;; Close a file descriptor. + ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd_t) (result $error $errno_t) ) - ;; Synchronize the data of a file to disk. - ;; Note: This is similar to `fdatasync` in POSIX. + ;;; Synchronize the data of a file to disk. + ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Get the attributes of a file descriptor. - ;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + ;;; Get the attributes of a file descriptor. + ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file descriptor's attributes are stored. + ;;; The buffer where the file descriptor's attributes are stored. (result $stat $fdstat_t) ) - ;; Adjust the flags associated with a file descriptor. - ;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + ;;; Adjust the flags associated with a file descriptor. + ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") (param $fd $fd_t) - ;; The desired values of the file descriptor flags. + ;;; The desired values of the file descriptor flags. (param $flags $fdflags_t) (result $error $errno_t) ) - ;; Adjust the rights associated with a file descriptor. - ;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; Adjust the rights associated with a file descriptor. + ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd_t) - ;; The desired rights of the file descriptor. + ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights_t) (param $fs_rights_inheriting $rights_t) (result $error $errno_t) ) - ;; Return the attributes of an open file. + ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;; Note: This is similar to `ftruncate` in POSIX. + ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") (param $fd $fd_t) - ;; The desired file size. + ;;; The desired file size. (param $st_size $filesize_t) (result $error $errno_t) ) - ;; Adjust the timestamps of an open file or directory. - ;; Note: This is similar to `futimens` in POSIX. + ;;; Adjust the timestamps of an open file or directory. + ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") (param $fd $fd_t) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `preadv` in POSIX. + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") (param $fd $fd_t) - ;; List of scatter/gather vectors in which to store data. + ;;; List of scatter/gather vectors in which to store data. (param $iovs $iovec_t_array) - ;; The offset within the file at which to read. + ;;; The offset within the file at which to read. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd_t) (result $error $errno_t) - ;; The buffer where the description is stored. + ;;; The buffer where the description is stored. (result $buf $prestat_t) ) - ;; Return a description of the given preopened file descriptor. + ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") (param $fd $fd_t) - ;; A buffer into which to write the preopened directory name. + ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size_t) (result $error $errno_t) ) - ;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;; Note: This is similar to `pwritev` in POSIX. + ;;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) - ;; The offset within the file at which to write. + ;;; The offset within the file at which to write. (param $offset $filesize_t) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Read from a file descriptor. - ;; Note: This is similar to `readv` in POSIX. + ;;; Read from a file descriptor. + ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_t_array) (result $error $errno_t) - ;; The number of bytes read. + ;;; The number of bytes read. (result $nread $size_t) ) - ;; Read directory entries from a directory. - ;; When successful, the contents of the output buffer consist of a sequence of - ;; directory entries. Each directory entry consists of a dirent_t object, - ;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;; entry. + ;;; Read directory entries from a directory. + ;;; When successful, the contents of the output buffer consist of a sequence of + ;;; directory entries. Each directory entry consists of a dirent_t object, + ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; entry. ;; - ;; This function fills the output buffer as much as possible, potentially - ;; truncating the last directory entry. This allows the caller to grow its - ;; read buffer size in case it's too small to fit a single large directory - ;; entry, or skip the oversized directory entry. + ;;; This function fills the output buffer as much as possible, potentially + ;;; truncating the last directory entry. This allows the caller to grow its + ;;; read buffer size in case it's too small to fit a single large directory + ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") (param $fd $fd_t) - ;; The buffer where directory entries are stored + ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) (param $buf_len $size_t) - ;; The location within the directory to start reading + ;;; The location within the directory to start reading (param $cookie $dircookie_t) (result $error $errno_t) - ;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. (result $bufused $size_t) ) - ;; Atomically replace a file descriptor by renumbering another file descriptor. + ;;; Atomically replace a file descriptor by renumbering another file descriptor. ;; - ;; Due to the strong focus on thread safety, this environment does not provide - ;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;; file descriptor with the same number could be allocated by a different - ;; thread at the same time. + ;;; Due to the strong focus on thread safety, this environment does not provide + ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;;; file descriptor with the same number could be allocated by a different + ;;; thread at the same time. ;; - ;; This function provides a way to atomically renumber file descriptors, which - ;; would disappear if `dup2()` were to be removed entirely. + ;;; This function provides a way to atomically renumber file descriptors, which + ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") (param $fd $fd_t) - ;; The file descriptor to overwrite. + ;;; The file descriptor to overwrite. (param $to $fd_t) (result $error $errno_t) ) - ;; Move the offset of a file descriptor. - ;; Note: This is similar to `lseek` in POSIX. + ;;; Move the offset of a file descriptor. + ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") (param $fd $fd_t) - ;; The number of bytes to move. + ;;; The number of bytes to move. (param $offset $filedelta_t) - ;; The base from which the offset is relative. + ;;; The base from which the offset is relative. (param $whence $whence_t) (result $error $errno_t) - ;; The new offset of the file descriptor, relative to the start of the file. + ;;; The new offset of the file descriptor, relative to the start of the file. (result $newoffset $filesize_t) ) - ;; Synchronize the data and metadata of a file to disk. - ;; Note: This is similar to `fsync` in POSIX. + ;;; Synchronize the data and metadata of a file to disk. + ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd_t) (result $error $errno_t) ) - ;; Return the current offset of a file descriptor. - ;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + ;;; Return the current offset of a file descriptor. + ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd_t) (result $error $errno_t) - ;; The current offset of the file descriptor, relative to the start of the file. + ;;; The current offset of the file descriptor, relative to the start of the file. (result $offset $filesize_t) ) - ;; Write to a file descriptor. - ;; Note: This is similar to `writev` in POSIX. + ;;; Write to a file descriptor. + ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") (param $fd $fd_t) - ;; List of scatter/gather vectors from which to retrieve data. + ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_t_array) (result $error $errno_t) - ;; The number of bytes written. + ;;; The number of bytes written. (result $nwritten $size_t) ) - ;; Create a directory. - ;; Note: This is similar to `mkdirat` in POSIX. + ;;; Create a directory. + ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") (param $fd $fd_t) - ;; The path at which to create the directory. + ;;; The path at which to create the directory. (param $path string) (result $error $errno_t) ) - ;; Return the attributes of a file or directory. - ;; Note: This is similar to `stat` in POSIX. + ;;; Return the attributes of a file or directory. + ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to inspect. + ;;; The path of the file or directory to inspect. (param $path string) (result $error $errno_t) - ;; The buffer where the file's attributes are stored. + ;;; The buffer where the file's attributes are stored. (result $buf $filestat_t) ) - ;; Adjust the timestamps of a file or directory. - ;; Note: This is similar to `utimensat` in POSIX. + ;;; Adjust the timestamps of a file or directory. + ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $flags $lookupflags_t) - ;; The path of the file or directory to operate on. + ;;; The path of the file or directory to operate on. (param $path string) - ;; The desired values of the data access timestamp. + ;;; The desired values of the data access timestamp. (param $st_atim $timestamp_t) - ;; The desired values of the data modification timestamp. + ;;; The desired values of the data modification timestamp. (param $st_mtim $timestamp_t) - ;; A bitmask indicating which timestamps to adjust. + ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags_t) (result $error $errno_t) ) - ;; Create a hard link. - ;; Note: This is similar to `linkat` in POSIX. + ;;; Create a hard link. + ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") (param $old_fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $old_flags $lookupflags_t) - ;; The source path from which to link. + ;;; The source path from which to link. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path at which to create the hard link. + ;;; The destination path at which to create the hard link. (param $new_path string) (result $error $errno_t) ) - ;; Open a file or directory. + ;;; Open a file or directory. ;; - ;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;; file descriptor not currently open; it is randomized to prevent - ;; applications from depending on making assumptions about indexes, since this - ;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;; guaranteed to be less than 2**31. + ;;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;;; file descriptor not currently open; it is randomized to prevent + ;;; applications from depending on making assumptions about indexes, since this + ;;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;;; guaranteed to be less than 2**31. ;; - ;; Note: This is similar to `openat` in POSIX. + ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") (param $fd $fd_t) - ;; Flags determining the method of how the path is resolved. + ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags_t) - ;; The relative path of the file or directory to open, relative to the - ;; `dirfd` directory. + ;;; The relative path of the file or directory to open, relative to the + ;;; `dirfd` directory. (param $path string) - ;; The method by which to open the file. + ;;; The method by which to open the file. (param $o_flags $oflags_t) - ;; The initial rights of the newly created file descriptor. The - ;; implementation is allowed to return a file descriptor with fewer rights - ;; than specified, if and only if those rights do not apply to the type of - ;; file being opened. + ;;; The initial rights of the newly created file descriptor. The + ;;; implementation is allowed to return a file descriptor with fewer rights + ;;; than specified, if and only if those rights do not apply to the type of + ;;; file being opened. ;; - ;; The *base* rights are rights that will apply to operations using the file - ;; descriptor itself, while the *inheriting* rights are rights that apply to - ;; file descriptors derived from it. + ;;; The *base* rights are rights that will apply to operations using the file + ;;; descriptor itself, while the *inheriting* rights are rights that apply to + ;;; file descriptors derived from it. (param $fs_rights_base $rights_t) (param $fs_rights_inherting $rights_t) (param $flags $fdflags_t) (result $error $errno_t) - ;; The file descriptor of the file that has been opened. + ;;; The file descriptor of the file that has been opened. (result $opened_fd $fd_t) ) - ;; Read the contents of a symbolic link. - ;; Note: This is similar to `readlinkat` in POSIX. + ;;; Read the contents of a symbolic link. + ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") (param $fd $fd_t) - ;; The path of the symbolic link from which to read. + ;;; The path of the symbolic link from which to read. (param $path string) - ;; The buffer to which to write the contents of the symbolic link. + ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) - ;; The number of bytes placed in the buffer. + ;;; The number of bytes placed in the buffer. (result $bufused $size_t) ) - ;; Remove a directory. - ;; Return `ENOTEMPTY` if the directory is not empty. - ;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + ;;; Remove a directory. + ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd_t) - ;; The path to a directory to remove. + ;;; The path to a directory to remove. (param $path string) (result $error $errno_t) ) - ;; Rename a file or directory. - ;; Note: This is similar to `renameat` in POSIX. + ;;; Rename a file or directory. + ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") (param $fd $fd_t) - ;; The source path of the file or directory to rename. + ;;; The source path of the file or directory to rename. (param $old_path string) - ;; The working directory at which the resolution of the new path starts. + ;;; The working directory at which the resolution of the new path starts. (param $new_fd $fd_t) - ;; The destination path to which to rename the file or directory. + ;;; The destination path to which to rename the file or directory. (param $new_path string) (result $error $errno_t) ) - ;; Create a symbolic link. - ;; Note: This is similar to `symlinkat` in POSIX. + ;;; Create a symbolic link. + ;;; Note: This is similar to `symlinkat` in POSIX. (@interface func (export "path_symlink") - ;; The contents of the symbolic link. + ;;; The contents of the symbolic link. (param $old_path string) (param $fd $fd_t) - ;; The destination path at which to create the symbolic link. + ;;; The destination path at which to create the symbolic link. (param $new_path string) (result $error $errno_t) ) - ;; Unlink a file. - ;; Return `EISDIR` if the path refers to a directory. - ;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + ;;; Unlink a file. + ;;; Return `EISDIR` if the path refers to a directory. + ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd_t) - ;; The path to a file to unlink. + ;;; The path to a file to unlink. (param $path string) (result $error $errno_t) ) - ;; Concurrently poll for the occurrence of a set of events. + ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") - ;; The events to which to subscribe. + ;;; The events to which to subscribe. (param $in (@witx const_pointer $subscription_t)) - ;; The events that have occurred. + ;;; The events that have occurred. (param $out (@witx pointer $event_t)) - ;; Both the number of subscriptions and events. + ;;; Both the number of subscriptions and events. (param $nsubscriptions $size_t) (result $error $errno_t) - ;; The number of events stored. + ;;; The number of events stored. (result $nevents $size_t) ) - ;; Terminate the process normally. An exit code of 0 indicates successful - ;; termination of the program. The meanings of other values is dependent on - ;; the environment. + ;;; Terminate the process normally. An exit code of 0 indicates successful + ;;; termination of the program. The meanings of other values is dependent on + ;;; the environment. (@interface func (export "proc_exit") - ;; The exit code returned by the process. + ;;; The exit code returned by the process. (param $rval $exitcode_t) ) - ;; Send a signal to the process of the calling thread. - ;; Note: This is similar to `raise` in POSIX. + ;;; Send a signal to the process of the calling thread. + ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") - ;; The signal condition to trigger. + ;;; The signal condition to trigger. (param $sig $signal_t) (result $error $errno_t) ) - ;; Temporarily yield execution of the calling thread. - ;; Note: This is similar to `sched_yield` in POSIX. + ;;; Temporarily yield execution of the calling thread. + ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") (result $error $errno_t) ) - ;; Write high-quality random data into a buffer. - ;; This function blocks when the implementation is unable to immediately - ;; provide sufficient high-quality random data. - ;; This function may execute slowly, so when large mounts of random data are - ;; required, it's advisable to use this function to seed a pseudo-random - ;; number generator, rather than to provide the random data directly. + ;;; Write high-quality random data into a buffer. + ;;; This function blocks when the implementation is unable to immediately + ;;; provide sufficient high-quality random data. + ;;; This function may execute slowly, so when large mounts of random data are + ;;; required, it's advisable to use this function to seed a pseudo-random + ;;; number generator, rather than to provide the random data directly. (@interface func (export "random_get") - ;; The buffer to fill with random data. + ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size_t) (result $error $errno_t) ) - ;; Receive a message from a socket. - ;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;; the data into multiple buffers in the manner of `readv`. + ;;; Receive a message from a socket. + ;;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to store data. + ;;; List of scatter/gather vectors to which to store data. (param $ri_data $iovec_t_array) - ;; Message flags. + ;;; Message flags. (param $ri_flags $riflags_t) (result $error $errno_t) - ;; Number of bytes stored in ri_data. + ;;; Number of bytes stored in ri_data. (result $ro_datalen $size_t) - ;; Message flags. + ;;; Message flags. (result $ro_flags $roflags_t) ) - ;; Send a message on a socket. - ;; Note: This is similar to `send` in POSIX, though it also supports writing - ;; the data from multiple buffers in the manner of `writev`. + ;;; Send a message on a socket. + ;;; Note: This is similar to `send` in POSIX, though it also supports writing + ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") (param $fd $fd_t) - ;; List of scatter/gather vectors to which to retrieve data + ;;; List of scatter/gather vectors to which to retrieve data (param $si_data $ciovec_t_array) - ;; Message flags. + ;;; Message flags. (param $si_flags $siflags_t) (result $error $errno_t) - ;; Number of bytes transmitted. + ;;; Number of bytes transmitted. (result $so_datalen $size_t) ) - ;; Shut down socket send and receive channels. - ;; Note: This is similar to `shutdown` in POSIX. + ;;; Shut down socket send and receive channels. + ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") (param $fd $fd_t) - ;; Which channels on the socket to shut down. + ;;; Which channels on the socket to shut down. (param $how $sdflags_t) (result $error $errno_t) ) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 62d5bf502..48c776ba9 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -120,6 +120,7 @@ pub enum DatatypeIdent { pub struct Datatype { pub name: Id, pub variant: DatatypeVariant, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -149,14 +150,26 @@ pub enum IntRepr { pub struct EnumDatatype { pub name: Id, pub repr: IntRepr, - pub variants: Vec, + pub variants: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct EnumVariant { + pub name: Id, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsDatatype { pub name: Id, pub repr: IntRepr, - pub flags: Vec, + pub flags: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FlagsMember { + pub name: Id, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -169,6 +182,7 @@ pub struct StructDatatype { pub struct StructMember { pub name: Id, pub type_: DatatypeIdent, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -181,6 +195,7 @@ pub struct UnionDatatype { pub struct UnionVariant { pub name: Id, pub type_: DatatypeIdent, + pub docs: String, } #[derive(Debug, Clone)] @@ -188,6 +203,7 @@ pub struct Module { pub name: Id, definitions: Vec, entries: HashMap, + pub docs: String, } impl Module { @@ -195,11 +211,13 @@ impl Module { name: Id, definitions: Vec, entries: HashMap, + docs: String, ) -> Self { Module { name, definitions, entries, + docs, } } pub fn import(&self, name: &Id) -> Option> { @@ -275,6 +293,7 @@ impl PartialEq for ModuleEntry { pub struct ModuleImport { pub name: Id, pub variant: ModuleImportVariant, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -287,6 +306,7 @@ pub struct InterfaceFunc { pub name: Id, pub params: Vec, pub results: Vec, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -294,6 +314,7 @@ pub struct InterfaceFuncParam { pub name: Id, pub type_: DatatypeIdent, pub position: InterfaceFuncParamPosition, + pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs new file mode 100644 index 000000000..532b3d902 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/docs.rs @@ -0,0 +1,227 @@ +use crate::ast::*; + +pub trait Documentation { + fn to_md(&self) -> String; +} + +impl Documentation for Document { + fn to_md(&self) -> String { + let mut ret = "# Types\n".to_string(); + for d in self.datatypes() { + ret += &d.to_md(); + } + + ret += "\n# Modules\n"; + for m in self.modules() { + ret += &m.to_md(); + } + ret + } +} + +impl BuiltinType { + fn name(&self) -> &'static str { + match self { + BuiltinType::String => "string", + BuiltinType::U8 => "u8", + BuiltinType::U16 => "u16", + BuiltinType::U32 => "u32", + BuiltinType::U64 => "u64", + BuiltinType::S8 => "s8", + BuiltinType::S16 => "s16", + BuiltinType::S32 => "s32", + BuiltinType::S64 => "s64", + BuiltinType::F32 => "f32", + BuiltinType::F64 => "f64", + } + } +} + +impl DatatypeIdent { + fn name(&self) -> String { + match self { + DatatypeIdent::Builtin(b) => b.name().to_string(), + DatatypeIdent::Array(a) => format!("Array<{}>", a.name()), + DatatypeIdent::Pointer(p) => format!("Pointer<{}>", p.name()), + DatatypeIdent::ConstPointer(p) => format!("ConstPointer<{}>", p.name()), + DatatypeIdent::Ident(i) => i.name.as_str().to_string(), + } + } +} + +impl Documentation for Datatype { + fn to_md(&self) -> String { + format!( + "## `{}`\n{}\n{}\n", + self.name.as_str(), + self.docs, + self.variant.to_md() + ) + } +} + +impl Documentation for DatatypeVariant { + fn to_md(&self) -> String { + match self { + DatatypeVariant::Alias(a) => a.to_md(), + DatatypeVariant::Enum(a) => a.to_md(), + DatatypeVariant::Flags(a) => a.to_md(), + DatatypeVariant::Struct(a) => a.to_md(), + DatatypeVariant::Union(a) => a.to_md(), + } + } +} + +impl Documentation for AliasDatatype { + fn to_md(&self) -> String { + format!("Alias to `{}`", self.to.name()) + } +} + +impl Documentation for EnumDatatype { + fn to_md(&self) -> String { + let variants = self + .variants + .iter() + .map(|v| format!("#### `{}`\n{}", v.name.as_str(), v.docs)) + .collect::>() + .join("\n"); + format!( + "Enum represented by `{}`\n\n### Variants:\n{}\n", + self.repr.name(), + variants + ) + } +} + +impl Documentation for FlagsDatatype { + fn to_md(&self) -> String { + let flags = self + .flags + .iter() + .map(|f| format!("#### `{}`\n{}\n", f.name.as_str(), f.docs)) + .collect::>() + .join("\n"); + format!( + "Flags represented by `{}`\n\n### Flags:\n{}", + self.repr.name(), + flags + ) + } +} + +impl Documentation for StructDatatype { + fn to_md(&self) -> String { + let members = self + .members + .iter() + .map(|m| { + format!( + "#### `{}`\nMember type: `{}`\n{}", + m.name.as_str(), + m.type_.name(), + m.docs, + ) + }) + .collect::>() + .join("\n"); + format!("### Struct members:\n{}", members) + } +} + +impl Documentation for UnionDatatype { + fn to_md(&self) -> String { + let variants = self + .variants + .iter() + .map(|v| { + format!( + "#### `{}`\nVariant type: `{}`\n{}", + v.name.as_str(), + v.type_.name(), + v.docs, + ) + }) + .collect::>() + .join("\n"); + format!("### Union variants:\n{}\n", variants) + } +} + +impl IntRepr { + fn name(&self) -> &'static str { + match self { + IntRepr::U8 => "u8", + IntRepr::U16 => "u16", + IntRepr::U32 => "u32", + IntRepr::U64 => "u64", + } + } +} + +impl Documentation for Module { + fn to_md(&self) -> String { + let imports = self + .imports() + .map(|i| i.to_md()) + .collect::>() + .join("\n"); + let funcs = self + .funcs() + .map(|i| i.to_md()) + .collect::>() + .join("\n"); + format!( + "## `{}`\n### Imports\n{}\n### Functions\n{}", + self.name.as_str(), + imports, + funcs, + ) + } +} + +impl Documentation for ModuleImport { + fn to_md(&self) -> String { + match self.variant { + ModuleImportVariant::Memory => format!("* {}: Memory", self.name.as_str()), + } + } +} + +impl Documentation for InterfaceFunc { + fn to_md(&self) -> String { + let params = self + .params + .iter() + .map(|f| { + format!( + "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", + name = f.name.as_str(), + type_ = f.type_.name(), + docs = f.docs + ) + }) + .collect::>() + .join("\n"); + let results = self + .results + .iter() + .map(|f| { + format!( + "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", + name = f.name.as_str(), + type_ = f.type_.name(), + docs = f.docs + ) + }) + .collect::>() + .join("\n"); + format!( + "### {}\n{}\n#### Parameters:\n{}#### Results:\n{}", + self.name.as_str(), + self.docs, + params, + results, + ) + } +} diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 3c2d945ec..60b0e0663 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -2,6 +2,8 @@ mod ast; /// Map witx types to core (wasm standard) types mod coretypes; +/// Render documentation +mod docs; /// Interface for filesystem or mock IO mod io; /// Witx syntax parsing from SExprs @@ -15,11 +17,12 @@ mod validate; pub use ast::{ AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, - InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, + Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, Id, IntRepr, InterfaceFunc, + InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, + ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; +pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; pub use render::{Render, SExpr as RenderSExpr}; diff --git a/proposals/filesystem/tools/witx/src/main.rs b/proposals/filesystem/tools/witx/src/main.rs index 8b1cab6ea..6251c3efa 100644 --- a/proposals/filesystem/tools/witx/src/main.rs +++ b/proposals/filesystem/tools/witx/src/main.rs @@ -1,12 +1,14 @@ -use clap::{App, Arg}; +use clap::{App, Arg, SubCommand}; +use std::fs::File; +use std::io::Write; use std::path::PathBuf; use std::process; -use witx::load; +use witx::{load, Documentation}; pub fn main() { let app = App::new("witx") .version(env!("CARGO_PKG_VERSION")) - .about("Validate witx file format") + .about("Validate and process witx files") .arg( Arg::with_name("input") .required(true) @@ -20,6 +22,17 @@ pub fn main() { .takes_value(false) .required(false), ) + .subcommand( + SubCommand::with_name("docs") + .about("Output documentation") + .arg( + Arg::with_name("output") + .short("o") + .long("output") + .takes_value(true) + .required(false), + ), + ) .get_matches(); let inputs = app @@ -34,6 +47,16 @@ pub fn main() { if app.is_present("verbose") { println!("{:?}", doc) } + + if let Some(subcommand) = app.subcommand_matches("docs") { + let md = doc.to_md(); + if let Some(output) = subcommand.value_of("output") { + let mut file = File::create(output).expect("create output file"); + file.write_all(md.as_bytes()).expect("write output file"); + } else { + println!("{}", md) + } + } } Err(e) => { println!("{}", e.report()); diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 9e699267e..77a1c0b03 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -1,3 +1,4 @@ +use wast::lexer::Comment; use wast::parser::{Cursor, Parse, Parser, Peek, Result}; ///! Parser turns s-expressions into unvalidated syntax constructs. @@ -96,6 +97,86 @@ impl Parse<'_> for BuiltinType { } } +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct CommentSyntax<'a> { + pub comments: Vec<&'a str>, +} + +impl<'a> Parse<'a> for CommentSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result> { + let comments = parser.step(|mut cursor| { + let mut comments = Vec::new(); + loop { + let (comment, c) = match cursor.comment() { + Some(pair) => pair, + None => break, + }; + cursor = c; + comments.push(match comment { + Comment::Block(s) => &s[2..s.len() - 2], + Comment::Line(s) => &s[2..], + }); + } + Ok((comments, cursor)) + })?; + Ok(CommentSyntax { comments }) + } +} + +impl<'a> CommentSyntax<'a> { + pub fn docs(&self) -> String { + // Perform a small amount of preprocessing by removing all trailing + // whitespace, and then also filter for only "doc comments" which are `;;;` + // or `(;; ... ;)`. + let docs = self + .comments + .iter() + .map(|d| d.trim_end()) + .filter_map(|d| { + if d.starts_with(";") { + Some(&d[1..]) + } else { + None + } + }) + .collect::>(); + + // Figure out how much leading whitespace we're going to be trimming from + // all docs, trimming the minimum amount in each doc comment. + let to_trim = docs + .iter() + .filter(|d| !d.is_empty()) + .map(|d| d.len() - d.trim().len()) + .min() + .unwrap_or(0); + + // Separate all documents by a newline and collect everything into a single + // string. + let mut ret = String::new(); + for doc in docs { + if !doc.is_empty() { + ret.push_str(doc[to_trim..].trim_end()); + } + ret.push_str("\n"); + } + return ret; + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct Documented<'a, T> { + pub comments: CommentSyntax<'a>, + pub item: T, +} + +impl<'a, T: Parse<'a>> Parse<'a> for Documented<'a, T> { + fn parse(parser: Parser<'a>) -> Result { + let comments = parser.parse()?; + let item = parser.parse()?; + Ok(Documented { comments, item }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum DatatypeIdentSyntax<'a> { Builtin(BuiltinType), @@ -179,14 +260,14 @@ impl Peek for AtInterface { #[derive(Debug, Clone, PartialEq, Eq)] pub struct TopLevelDocument<'a> { - pub items: Vec>, + pub items: Vec>>, } impl<'a> Parse<'a> for TopLevelDocument<'a> { fn parse(parser: Parser<'a>) -> Result { let mut items = Vec::new(); while !parser.is_empty() { - items.push(parser.parens(|p| p.parse())?); + items.push(parser.parse()?); } Ok(TopLevelDocument { items }) } @@ -200,12 +281,14 @@ pub enum TopLevelSyntax<'a> { impl<'a> Parse<'a> for TopLevelSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - if parser.peek::() { - parser.parse::()?; - Ok(TopLevelSyntax::Use(parser.parse()?)) - } else { - Ok(TopLevelSyntax::Decl(parser.parse()?)) - } + parser.parens(|p| { + if p.peek::() { + p.parse::()?; + Ok(TopLevelSyntax::Use(p.parse()?)) + } else { + Ok(TopLevelSyntax::Decl(p.parse()?)) + } + }) } } @@ -278,7 +361,7 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumSyntax<'a> { pub repr: BuiltinType, - pub members: Vec>, + pub members: Vec>>, } impl<'a> Parse<'a> for EnumSyntax<'a> { @@ -297,7 +380,7 @@ impl<'a> Parse<'a> for EnumSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsSyntax<'a> { pub repr: BuiltinType, - pub flags: Vec>, + pub flags: Vec>>, } impl<'a> Parse<'a> for FlagsSyntax<'a> { @@ -314,16 +397,16 @@ impl<'a> Parse<'a> for FlagsSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct StructSyntax<'a> { - pub fields: Vec>, + pub fields: Vec>>, } impl<'a> Parse<'a> for StructSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; let mut fields = Vec::new(); - fields.push(parser.parens(|p| p.parse())?); + fields.push(parser.parse()?); while !parser.is_empty() { - fields.push(parser.parens(|p| p.parse())?); + fields.push(parser.parse()?); } Ok(StructSyntax { fields }) } @@ -337,25 +420,27 @@ pub struct FieldSyntax<'a> { impl<'a> Parse<'a> for FieldSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let name = parser.parse()?; - let type_ = parser.parse()?; - Ok(FieldSyntax { name, type_ }) + parser.parens(|p| { + p.parse::()?; + let name = p.parse()?; + let type_ = p.parse()?; + Ok(FieldSyntax { name, type_ }) + }) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionSyntax<'a> { - pub fields: Vec>, + pub fields: Vec>>, } impl<'a> Parse<'a> for UnionSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; let mut fields = Vec::new(); - fields.push(parser.parens(|p| p.parse())?); + fields.push(parser.parse()?); while !parser.is_empty() { - fields.push(parser.parens(|p| p.parse())?); + fields.push(parser.parse()?); } Ok(UnionSyntax { fields }) } @@ -364,7 +449,7 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct ModuleSyntax<'a> { pub name: wast::Id<'a>, - pub decls: Vec>, + pub decls: Vec>>, } impl<'a> Parse<'a> for ModuleSyntax<'a> { @@ -373,7 +458,7 @@ impl<'a> Parse<'a> for ModuleSyntax<'a> { let name = parser.parse()?; let mut decls = Vec::new(); while !parser.is_empty() { - decls.push(parser.parens(|p| p.parse())?); + decls.push(parser.parse()?); } Ok(ModuleSyntax { name, decls }) } @@ -387,14 +472,16 @@ pub enum ModuleDeclSyntax<'a> { impl<'a> Parse<'a> for ModuleDeclSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(ModuleDeclSyntax::Import(parser.parse()?)) - } else if l.peek::() { - Ok(ModuleDeclSyntax::Func(parser.parse()?)) - } else { - Err(l.error()) - } + parser.parens(|p| { + let mut l = p.lookahead1(); + if l.peek::() { + Ok(ModuleDeclSyntax::Import(p.parse()?)) + } else if l.peek::() { + Ok(ModuleDeclSyntax::Func(p.parse()?)) + } else { + Err(l.error()) + } + }) } } @@ -442,8 +529,8 @@ impl Parse<'_> for ImportTypeSyntax { pub struct InterfaceFuncSyntax<'a> { pub export: &'a str, pub export_loc: wast::Span, - pub params: Vec>, - pub results: Vec>, + pub params: Vec>>, + pub results: Vec>>, } impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { @@ -460,25 +547,21 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { let mut results = Vec::new(); while !parser.is_empty() { - parser.parens(|p| { - let mut l = p.lookahead1(); - if l.peek::() { - parser.parse::()?; - params.push(FieldSyntax { - name: parser.parse()?, - type_: parser.parse()?, + let func_field = parser.parse::>()?; + match func_field.item { + InterfaceFuncField::Param(item) => { + params.push(Documented { + comments: func_field.comments, + item, }); - } else if l.peek::() { - parser.parse::()?; - results.push(FieldSyntax { - name: parser.parse()?, - type_: parser.parse()?, + } + InterfaceFuncField::Result(item) => { + results.push(Documented { + comments: func_field.comments, + item, }); - } else { - return Err(l.error()); } - Ok(()) - })?; + } } Ok(InterfaceFuncSyntax { @@ -490,6 +573,33 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { } } +enum InterfaceFuncField<'a> { + Param(FieldSyntax<'a>), + Result(FieldSyntax<'a>), +} +impl<'a> Parse<'a> for InterfaceFuncField<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parens(|p| { + let mut l = p.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(InterfaceFuncField::Param(FieldSyntax { + name: parser.parse()?, + type_: parser.parse()?, + })) + } else if l.peek::() { + parser.parse::()?; + Ok(InterfaceFuncField::Result(FieldSyntax { + name: parser.parse()?, + type_: parser.parse()?, + })) + } else { + Err(l.error()) + } + }) + } +} + impl PartialEq for InterfaceFuncSyntax<'_> { fn eq(&self, other: &InterfaceFuncSyntax<'_>) -> bool { // skip the `export_loc` field diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 8e23a5fa8..4bb7df729 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -21,6 +21,8 @@ pub enum SExpr { Quote(String), /// Short for Annotation Annot(String), + /// Doc comment + Docs(String, Box), } impl fmt::Display for SExpr { @@ -39,6 +41,7 @@ impl fmt::Display for SExpr { SExpr::Ident(i) => write!(f, "${}", i), SExpr::Quote(q) => write!(f, "\"{}\"", q), SExpr::Annot(a) => write!(f, "@{}", a), + SExpr::Docs(d, s) => write!(f, "(;; {} ;) {}", d, s), } } } @@ -56,6 +59,13 @@ impl SExpr { fn annot(s: &str) -> SExpr { SExpr::Annot(s.to_string()) } + fn docs(d: &str, s: SExpr) -> SExpr { + if d.is_empty() { + s + } else { + SExpr::Docs(d.to_string(), Box::new(s)) + } + } } pub trait Render { @@ -110,7 +120,10 @@ impl Render for Datatype { fn to_sexpr(&self) -> SExpr { let name = self.name.to_sexpr(); let body = self.variant.to_sexpr(); - SExpr::Vec(vec![SExpr::word("typename"), name, body]) + SExpr::docs( + &self.docs, + SExpr::Vec(vec![SExpr::word("typename"), name, body]), + ) } } @@ -138,7 +151,7 @@ impl Render for EnumDatatype { let variants = self .variants .iter() - .map(|v| v.to_sexpr()) + .map(|v| SExpr::docs(&v.docs, v.name.to_sexpr())) .collect::>(); SExpr::Vec([header, variants].concat()) } @@ -150,7 +163,7 @@ impl Render for FlagsDatatype { let flags = self .flags .iter() - .map(|f| f.to_sexpr()) + .map(|f| SExpr::docs(&f.docs, f.name.to_sexpr())) .collect::>(); SExpr::Vec([header, flags].concat()) } @@ -163,11 +176,14 @@ impl Render for StructDatatype { .members .iter() .map(|m| { - SExpr::Vec(vec![ - SExpr::word("field"), - m.name.to_sexpr(), - m.type_.to_sexpr(), - ]) + SExpr::docs( + &m.docs, + SExpr::Vec(vec![ + SExpr::word("field"), + m.name.to_sexpr(), + m.type_.to_sexpr(), + ]), + ) }) .collect::>(); SExpr::Vec([header, members].concat()) @@ -181,11 +197,14 @@ impl Render for UnionDatatype { .variants .iter() .map(|v| { - SExpr::Vec(vec![ - SExpr::word("field"), - v.name.to_sexpr(), - v.type_.to_sexpr(), - ]) + SExpr::docs( + &v.docs, + SExpr::Vec(vec![ + SExpr::word("field"), + v.name.to_sexpr(), + v.type_.to_sexpr(), + ]), + ) }) .collect::>(); SExpr::Vec([header, variants].concat()) @@ -211,7 +230,7 @@ impl Render for Module { .map(|i| i.to_sexpr()) .chain(self.funcs().map(|f| f.to_sexpr())) .collect::>(); - SExpr::Vec([header, definitions].concat()) + SExpr::docs(&self.docs, SExpr::Vec([header, definitions].concat())) } } @@ -220,11 +239,14 @@ impl Render for ModuleImport { let variant = match self.variant { ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), }; - SExpr::Vec(vec![ - SExpr::word("import"), - SExpr::quote(self.name.as_str()), - variant, - ]) + SExpr::docs( + &self.docs, + SExpr::Vec(vec![ + SExpr::word("import"), + SExpr::quote(self.name.as_str()), + variant, + ]), + ) } } @@ -242,24 +264,30 @@ impl Render for InterfaceFunc { .params .iter() .map(|f| { - SExpr::Vec(vec![ - SExpr::word("param"), - f.name.to_sexpr(), - f.type_.to_sexpr(), - ]) + SExpr::docs( + &f.docs, + SExpr::Vec(vec![ + SExpr::word("param"), + f.name.to_sexpr(), + f.type_.to_sexpr(), + ]), + ) }) .collect(); let results = self .results .iter() .map(|f| { - SExpr::Vec(vec![ - SExpr::word("result"), - f.name.to_sexpr(), - f.type_.to_sexpr(), - ]) + SExpr::docs( + &f.docs, + SExpr::Vec(vec![ + SExpr::word("result"), + f.name.to_sexpr(), + f.type_.to_sexpr(), + ]), + ) }) .collect(); - SExpr::Vec([header, params, results].concat()) + SExpr::docs(&self.docs, SExpr::Vec([header, params, results].concat())) } } diff --git a/proposals/filesystem/tools/witx/src/toplevel.rs b/proposals/filesystem/tools/witx/src/toplevel.rs index 281ad4757..2e0738a6b 100644 --- a/proposals/filesystem/tools/witx/src/toplevel.rs +++ b/proposals/filesystem/tools/witx/src/toplevel.rs @@ -58,11 +58,11 @@ fn parse_file( let doc = wast::parser::parse::(&buf).map_err(adjust_err)?; for t in doc.items { - match t { + match t.item { TopLevelSyntax::Decl(d) => { let def = validator .scope(&input, &path) - .validate_decl(&d) + .validate_decl(&d, &t.comments) .map_err(WitxError::Validation)?; definitions.push(def); } diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index a0d9ea96b..eba087e8c 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -1,13 +1,14 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ - DatatypeIdentSyntax, DeclSyntax, EnumSyntax, FlagsSyntax, ImportTypeSyntax, - ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + CommentSyntax, DatatypeIdentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, + ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, - Definition, Entry, EnumDatatype, FlagsDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, - InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, + Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, Id, IntRepr, + InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, + ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, + UnionDatatype, UnionVariant, }; use failure::Fail; use std::collections::HashMap; @@ -158,10 +159,15 @@ impl DocValidationScope<'_> { self.doc.scope.get(name.name(), loc) } - pub fn validate_decl(&mut self, decl: &DeclSyntax) -> Result { + pub fn validate_decl( + &mut self, + decl: &DeclSyntax, + comments: &CommentSyntax, + ) -> Result { match decl { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; + let docs = comments.docs(); let variant = match &decl.def { TypedefSyntax::Ident(syntax) => DatatypeVariant::Alias(AliasDatatype { @@ -186,6 +192,7 @@ impl DocValidationScope<'_> { let rc_datatype = Rc::new(Datatype { name: name.clone(), variant, + docs, }); self.doc .entries @@ -205,6 +212,7 @@ impl DocValidationScope<'_> { name.clone(), definitions, module_validator.entries, + comments.docs(), )); self.doc .entries @@ -261,8 +269,12 @@ impl DocValidationScope<'_> { let variants = syntax .members .iter() - .map(|i| enum_scope.introduce(i.name(), self.location(i.span()))) - .collect::, _>>()?; + .map(|i| { + let name = enum_scope.introduce(i.item.name(), self.location(i.item.span()))?; + let docs = i.comments.docs(); + Ok(EnumVariant { name, docs }) + }) + .collect::, _>>()?; Ok(EnumDatatype { name: name.clone(), @@ -282,8 +294,12 @@ impl DocValidationScope<'_> { let flags = syntax .flags .iter() - .map(|i| flags_scope.introduce(i.name(), self.location(i.span()))) - .collect::, _>>()?; + .map(|i| { + let name = flags_scope.introduce(i.item.name(), self.location(i.item.span()))?; + let docs = i.comments.docs(); + Ok(FlagsMember { name, docs }) + }) + .collect::, _>>()?; Ok(FlagsDatatype { name: name.clone(), @@ -303,10 +319,11 @@ impl DocValidationScope<'_> { .fields .iter() .map(|f| { - Ok(StructMember { - name: member_scope.introduce(f.name.name(), self.location(f.name.span()))?, - type_: self.validate_datatype_ident(&f.type_)?, - }) + let name = member_scope + .introduce(f.item.name.name(), self.location(f.item.name.span()))?; + let type_ = self.validate_datatype_ident(&f.item.type_)?; + let docs = f.comments.docs(); + Ok(StructMember { name, type_, docs }) }) .collect::, _>>()?; @@ -327,10 +344,11 @@ impl DocValidationScope<'_> { .fields .iter() .map(|f| { - Ok(UnionVariant { - name: variant_scope.introduce(f.name.name(), self.location(f.name.span()))?, - type_: self.validate_datatype_ident(&f.type_)?, - }) + let name = variant_scope + .introduce(f.item.name.name(), self.location(f.item.name.span()))?; + let type_ = self.validate_datatype_ident(&f.item.type_)?; + let docs = f.comments.docs(); + Ok(UnionVariant { name, type_, docs }) }) .collect::, _>>()?; @@ -375,9 +393,9 @@ impl<'a> ModuleValidation<'a> { fn validate_decl( &mut self, - decl: &ModuleDeclSyntax, + decl: &Documented, ) -> Result { - match decl { + match &decl.item { ModuleDeclSyntax::Import(syntax) => { let loc = self.doc.location(syntax.name_loc); let name = self.scope.introduce(syntax.name, loc)?; @@ -387,6 +405,7 @@ impl<'a> ModuleValidation<'a> { let rc_import = Rc::new(ModuleImport { name: name.clone(), variant, + docs: decl.comments.docs(), }); self.entries .insert(name, ModuleEntry::Import(Rc::downgrade(&rc_import))); @@ -402,10 +421,13 @@ impl<'a> ModuleValidation<'a> { .enumerate() .map(|(ix, f)| { Ok(InterfaceFuncParam { - name: argnames - .introduce(f.name.name(), self.doc.location(f.name.span()))?, - type_: self.doc.validate_datatype_ident(&f.type_)?, + name: argnames.introduce( + f.item.name.name(), + self.doc.location(f.item.name.span()), + )?, + type_: self.doc.validate_datatype_ident(&f.item.type_)?, position: InterfaceFuncParamPosition::Param(ix), + docs: f.comments.docs(), }) }) .collect::, _>>()?; @@ -414,20 +436,23 @@ impl<'a> ModuleValidation<'a> { .iter() .enumerate() .map(|(ix, f)| { - let type_ = self.doc.validate_datatype_ident(&f.type_)?; + let type_ = self.doc.validate_datatype_ident(&f.item.type_)?; if ix == 0 { match type_.passed_by() { DatatypePassedBy::Value(_) => {} _ => Err(ValidationError::InvalidFirstResultType { - location: self.doc.location(f.name.span()), + location: self.doc.location(f.item.name.span()), })?, } } Ok(InterfaceFuncParam { - name: argnames - .introduce(f.name.name(), self.doc.location(f.name.span()))?, + name: argnames.introduce( + f.item.name.name(), + self.doc.location(f.item.name.span()), + )?, type_, position: InterfaceFuncParamPosition::Result(ix), + docs: f.comments.docs(), }) }) .collect::, _>>()?; @@ -436,6 +461,7 @@ impl<'a> ModuleValidation<'a> { name: name.clone(), params, results, + docs: decl.comments.docs(), }); self.entries .insert(name, ModuleEntry::Func(Rc::downgrade(&rc_func))); diff --git a/proposals/filesystem/tools/witx/tests/wasi.rs b/proposals/filesystem/tools/witx/tests/wasi.rs index b5a9d527c..aef954236 100644 --- a/proposals/filesystem/tools/witx/tests/wasi.rs +++ b/proposals/filesystem/tools/witx/tests/wasi.rs @@ -29,5 +29,31 @@ fn render_roundtrip() { .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) .unwrap(); + let back_to_sexprs = format!("{}", doc); + + let doc2 = witx::parse(&back_to_sexprs) + .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) + .unwrap(); + + // I'd just assert_eq, but when it fails the debug print is thousands of lines long and impossible + // to figure out where they are unequal. + if doc != doc2 { + for type_ in doc.datatypes() { + let type2 = doc2.datatype(&type_.name).expect("doc2 missing datatype"); + assert_eq!(type_, type2); + } + for mod_ in doc.modules() { + let mod2 = doc2.module(&mod_.name).expect("doc2 missing module"); + for import in mod_.imports() { + let import2 = mod2.import(&import.name).expect("mod2 missing import"); + assert_eq!(import, import2); + } + for func in mod_.funcs() { + let func2 = mod2.func(&func.name).expect("mod2 missing func"); + assert_eq!(func, func2); + } + } + } + // This should be equivelant to the above, but just in case some code changes where it isnt: assert_eq!(doc, doc2); } From 63063341ae13d3192cf259cd557e43f858cff0c5 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 17:15:57 -0800 Subject: [PATCH 0295/1772] Mechanical witx naming convention changes (#137) * witx: drop trailing `_t` from all typenames this suffix is not appropriate for all languages that may need to generate code from witx, so this change removes it from all witx files and leaves the code generator in charge of putting the appropriate suffix onto any type names it produces. sed -i -E 's/\$([a-z_]+)_t([)\n\r ])?/\$\1\2/g' **/*.witx * witx: change identifiers to snake case Change all $SHOUTY_SNAKE_CASE identifers to $snake_case. It is the responsibility of a code generator backend to select the right case and style of these identifiers for the target language. In witx, we should standardize on snake case (lowercase with a single underscore as a word separator) sed -i -E 's/\$([A-Z0-9_]+)([)\n\r ])?/\$\L\1\2/g' **/*.witx * witx: mechanically remove repeated prefixes from flags, enums once again, the code translation tool is responsible for putting the right prefix in the generated code. languages with proper namespacing facilities don't need the identifiers themselves to be namespaced. otherwise, you can derive the namespacing prefix from the type name. sed -i -E 's/\$(clock_|right_|whence_|filetype_|advice_|fdflag_|filestat_set_|lookup_|o_|st_|sock_|shut_|preopentype_)/\$/g' **/*.witx * restore fields named pr_type and d_type * remove $event_ prefix from eventrwflags member doing so by regexp would delete various other valid event_ prefixes * remove eventtype_ prefix from enum fields this one could have been mechanical, but i left it out of the regexp * restore oflags, fdflags argument names in path_open * witx: delete leading `sig` from each $signal enum variant * witx: delete leading `e` from each $errno enum variant * fixup test * witx: fix up old style names in comments --- .../phases/ephemeral/witx/typenames.witx | 608 +++++++++--------- .../witx/wasi_ephemeral_preview.witx | 306 ++++----- .../phases/old/snapshot_0/witx/typenames.witx | 604 ++++++++--------- .../old/snapshot_0/witx/wasi_unstable.witx | 306 ++++----- .../phases/snapshot/witx/typenames.witx | 608 +++++++++--------- .../snapshot/witx/wasi_snapshot_preview1.witx | 306 ++++----- proposals/clocks/tools/witx/tests/wasi.rs | 5 - 7 files changed, 1369 insertions(+), 1374 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index a614d8528..00ae3d15e 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -5,29 +5,29 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(typename $size_t u32) +(typename $size u32) ;;; Non-negative file size or length of a region within a file. -(typename $filesize_t u64) +(typename $filesize u64) ;;; Timestamp in nanoseconds. -(typename $timestamp_t u64) +(typename $timestamp u64) ;;; Identifiers for clocks. -(typename $clockid_t +(typename $clockid (enum u32 ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME + $realtime ;;; The store-wide monotonic clock, which is defined as a clock measuring ;;; real time, whose value cannot be adjusted and which cannot have negative ;;; clock jumps. The epoch of this clock is undefined. The absolute time ;;; value of this clock therefore has no meaning. - $CLOCK_MONOTONIC + $monotonic ;;; The CPU-time clock associated with the current process. - $CLOCK_PROCESS_CPUTIME_ID + $process_cputime_id ;;; The CPU-time clock associated with the current thread. - $CLOCK_THREAD_CPUTIME_ID + $thread_cputime_id ) ) @@ -35,732 +35,732 @@ ;;; Not all of these error codes are returned by the functions provided by this ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. -(typename $errno_t +(typename $errno (enum u16 ;;; No error occurred. System call completed successfully. - $ESUCCESS + $success ;;; Argument list too long. - $E2BIG + $2big ;;; Permission denied. - $EACCES + $acces ;;; Address in use. - $EADDRINUSE + $addrinuse ;;; Address not available. - $EADDRNOTAVAIL + $addrnotavail ;;; Address family not supported. - $EAFNOSUPPORT + $afnosupport ;;; Resource unavailable, or operation would block. - $EAGAIN + $again ;;; Connection already in progress. - $EALREADY + $already ;;; Bad file descriptor. - $EBADF + $badf ;;; Bad message. - $EBADMSG + $badmsg ;;; Device or resource busy. - $EBUSY + $busy ;;; Operation canceled. - $ECANCELED + $canceled ;;; No child processes. - $ECHILD + $child ;;; Connection aborted. - $ECONNABORTED + $connaborted ;;; Connection refused. - $ECONNREFUSED + $connrefused ;;; Connection reset. - $ECONNRESET + $connreset ;;; Resource deadlock would occur. - $EDEADLK + $deadlk ;;; Destination address required. - $EDESTADDRREQ + $destaddrreq ;;; Mathematics argument out of domain of function. - $EDOM + $dom ;;; Reserved. - $EDQUOT + $dquot ;;; File exists. - $EEXIST + $exist ;;; Bad address. - $EFAULT + $fault ;;; File too large. - $EFBIG + $fbig ;;; Host is unreachable. - $EHOSTUNREACH + $hostunreach ;;; Identifier removed. - $EIDRM + $idrm ;;; Illegal byte sequence. - $EILSEQ + $ilseq ;;; Operation in progress. - $EINPROGRESS + $inprogress ;;; Interrupted function. - $EINTR + $intr ;;; Invalid argument. - $EINVAL + $inval ;;; I/O error. - $EIO + $io ;;; Socket is connected. - $EISCONN + $isconn ;;; Is a directory. - $EISDIR + $isdir ;;; Too many levels of symbolic links. - $ELOOP + $loop ;;; File descriptor value too large. - $EMFILE + $mfile ;;; Too many links. - $EMLINK + $mlink ;;; Message too large. - $EMSGSIZE + $msgsize ;;; Reserved. - $EMULTIHOP + $multihop ;;; Filename too long. - $ENAMETOOLONG + $nametoolong ;;; Network is down. - $ENETDOWN + $netdown ;;; Connection aborted by network. - $ENETRESET + $netreset ;;; Network unreachable. - $ENETUNREACH + $netunreach ;;; Too many files open in system. - $ENFILE + $nfile ;;; No buffer space available. - $ENOBUFS + $nobufs ;;; No such device. - $ENODEV + $nodev ;;; No such file or directory. - $ENOENT + $noent ;;; Executable file format error. - $ENOEXEC + $noexec ;;; No locks available. - $ENOLCK + $nolck ;;; Reserved. - $ENOLINK + $nolink ;;; Not enough space. - $ENOMEM + $nomem ;;; No message of the desired type. - $ENOMSG + $nomsg ;;; Protocol not available. - $ENOPROTOOPT + $noprotoopt ;;; No space left on device. - $ENOSPC + $nospc ;;; Function not supported. - $ENOSYS + $nosys ;;; The socket is not connected. - $ENOTCONN + $notconn ;;; Not a directory or a symbolic link to a directory. - $ENOTDIR + $notdir ;;; Directory not empty. - $ENOTEMPTY + $notempty ;;; State not recoverable. - $ENOTRECOVERABLE + $notrecoverable ;;; Not a socket. - $ENOTSOCK + $notsock ;;; Not supported, or operation not supported on socket. - $ENOTSUP + $notsup ;;; Inappropriate I/O control operation. - $ENOTTY + $notty ;;; No such device or address. - $ENXIO + $nxio ;;; Value too large to be stored in data type. - $EOVERFLOW + $overflow ;;; Previous owner died. - $EOWNERDEAD + $ownerdead ;;; Operation not permitted. - $EPERM + $perm ;;; Broken pipe. - $EPIPE + $pipe ;;; Protocol error. - $EPROTO + $proto ;;; Protocol not supported. - $EPROTONOSUPPORT + $protonosupport ;;; Protocol wrong type for socket. - $EPROTOTYPE + $prototype ;;; Result too large. - $ERANGE + $range ;;; Read-only file system. - $EROFS + $rofs ;;; Invalid seek. - $ESPIPE + $spipe ;;; No such process. - $ESRCH + $srch ;;; Reserved. - $ESTALE + $stale ;;; Connection timed out. - $ETIMEDOUT + $timedout ;;; Text file busy. - $ETXTBSY + $txtbsy ;;; Cross-device link. - $EXDEV + $xdev ;;; Extension: Capabilities insufficient. - $ENOTCAPABLE + $notcapable ) ) ;;; File descriptor rights, determining which actions may be performed. -(typename $rights_t +(typename $rights (flags u64 ;;; The right to invoke `fd_datasync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_DSYNC`. - $RIGHT_FD_DATASYNC + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflag::dsync`. + $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - $RIGHT_FD_READ - ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - $RIGHT_FD_SEEK + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. + $fd_read + ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. + $fd_seek ;;; The right to invoke `fd_fdstat_set_flags`. - $RIGHT_FD_FDSTAT_SET_FLAGS + $fd_fdstat_set_flags ;;; The right to invoke `fd_sync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - $RIGHT_FD_SYNC + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflag::rsync` and `fdflag::dsync`. + $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;;; invoke `fd_tell`. - $RIGHT_FD_TELL + $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - $RIGHT_FD_WRITE + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. + $fd_write ;;; The right to invoke `fd_advise`. - $RIGHT_FD_ADVISE + $fd_advise ;;; The right to invoke `fd_allocate`. - $RIGHT_FD_ALLOCATE + $fd_allocate ;;; The right to invoke `path_create_directory`. - $RIGHT_PATH_CREATE_DIRECTORY - ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - $RIGHT_PATH_CREATE_FILE + $path_create_directory + ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::creat`. + $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. - $RIGHT_PATH_LINK_SOURCE + $path_link_source ;;; The right to invoke `path_link` with the file descriptor as the ;;; target directory. - $RIGHT_PATH_LINK_TARGET + $path_link_target ;;; The right to invoke `path_open`. - $RIGHT_PATH_OPEN + $path_open ;;; The right to invoke `fd_readdir`. - $RIGHT_FD_READDIR + $fd_readdir ;;; The right to invoke `path_readlink`. - $RIGHT_PATH_READLINK + $path_readlink ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $RIGHT_PATH_RENAME_SOURCE + $path_rename_source ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $RIGHT_PATH_RENAME_TARGET + $path_rename_target ;;; The right to invoke `path_filestat_get`. - $RIGHT_PATH_FILESTAT_GET + $path_filestat_get ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - $RIGHT_PATH_FILESTAT_SET_SIZE + ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. + $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. - $RIGHT_PATH_FILESTAT_SET_TIMES + $path_filestat_set_times ;;; The right to invoke `fd_filestat_get`. - $RIGHT_FD_FILESTAT_GET + $fd_filestat_get ;;; The right to invoke `fd_filestat_set_size`. - $RIGHT_FD_FILESTAT_SET_SIZE + $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. - $RIGHT_FD_FILESTAT_SET_TIMES + $fd_filestat_set_times ;;; The right to invoke `path_symlink`. - $RIGHT_PATH_SYMLINK + $path_symlink ;;; The right to invoke `path_remove_directory`. - $RIGHT_PATH_REMOVE_DIRECTORY + $path_remove_directory ;;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE - ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - $RIGHT_POLL_FD_READWRITE + $path_unlink_file + ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. + ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. + $poll_fd_readwrite ;;; The right to invoke `sock_shutdown`. - $RIGHT_SOCK_SHUTDOWN + $sock_shutdown ) ) ;;; A file descriptor index. -(typename $fd_t u32) +(typename $fd u32) ;;; A region of memory for scatter/gather reads. -(typename $iovec_t +(typename $iovec (struct ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. - (field $buf_len $size_t) + (field $buf_len $size) ) ) ;;; A region of memory for scatter/gather writes. -(typename $ciovec_t +(typename $ciovec (struct ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. - (field $buf_len $size_t) + (field $buf_len $size) ) ) -(typename $iovec_t_array (array $iovec_t)) -(typename $ciovec_t_array (array $ciovec_t)) +(typename $iovec_array (array $iovec)) +(typename $ciovec_array (array $ciovec)) ;;; Relative offset within a file. -(typename $filedelta_t s64) +(typename $filedelta s64) ;;; The position relative to which to set the offset of the file descriptor. -(typename $whence_t +(typename $whence (enum u8 ;;; Seek relative to start-of-file. - $WHENCE_SET + $set ;;; Seek relative to current position. - $WHENCE_CUR + $cur ;;; Seek relative to end-of-file. - $WHENCE_END + $end ) ) ;;; A reference to the offset of a directory entry. ;; ;;; The value 0 signifies the start of the directory. -(typename $dircookie_t u64) +(typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent_t. -(typename $dirnamlen_t u32) +;;; The type for the $d_namlen field of $dirent. +(typename $dirnamlen u32) ;;; File serial number that is unique within its file system. -(typename $inode_t u64) +(typename $inode u64) ;;; The type of a file descriptor or file. -(typename $filetype_t +(typename $filetype (enum u8 ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $FILETYPE_UNKNOWN + $unknown ;;; The file descriptor or file refers to a block device inode. - $FILETYPE_BLOCK_DEVICE + $block_device ;;; The file descriptor or file refers to a character device inode. - $FILETYPE_CHARACTER_DEVICE + $character_device ;;; The file descriptor or file refers to a directory inode. - $FILETYPE_DIRECTORY + $directory ;;; The file descriptor or file refers to a regular file inode. - $FILETYPE_REGULAR_FILE + $regular_file ;;; The file descriptor or file refers to a datagram socket. - $FILETYPE_SOCKET_DGRAM + $socket_dgram ;;; The file descriptor or file refers to a byte-stream socket. - $FILETYPE_SOCKET_STREAM + $socket_stream ;;; The file refers to a symbolic link inode. - $FILETYPE_SYMBOLIC_LINK + $symbolic_link ) ) ;;; A directory entry. -(typename $dirent_t +(typename $dirent (struct ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie_t) + (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode_t) + (field $d_ino $inode) ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen_t) + (field $d_namlen $dirnamlen) ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype_t) + (field $d_type $filetype) ) ) ;;; File or memory access pattern advisory information. -(typename $advice_t +(typename $advice (enum u8 ;;; The application has no advice to give on its behavior with respect to the specified data. - $ADVICE_NORMAL + $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $ADVICE_SEQUENTIAL + $sequential ;;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM + $random ;;; The application expects to access the specified data in the near future. - $ADVICE_WILLNEED + $willneed ;;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED + $dontneed ;;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE + $noreuse ) ) ;;; File descriptor flags. -(typename $fdflags_t +(typename $fdflags (flags u16 ;;; Append mode: Data written to the file is always appended to the file's end. - $FDFLAG_APPEND + $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $FDFLAG_DSYNC + $dsync ;;; Non-blocking mode. - $FDFLAG_NONBLOCK + $nonblock ;;; Synchronized read I/O operations. - $FDFLAG_RSYNC + $rsync ;;; Write according to synchronized I/O file integrity completion. In ;;; addition to synchronizing the data stored in the file, the implementation ;;; may also synchronously update the file's metadata. - $FDFLAG_SYNC + $sync ) ) ;;; File descriptor attributes. -(typename $fdstat_t +(typename $fdstat (struct ;;; File type. - (field $fs_filetype $filetype_t) + (field $fs_filetype $filetype) ;;; File descriptor flags. - (field $fs_flags $fdflags_t) + (field $fs_flags $fdflags) ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights_t) + (field $fs_rights_base $rights) ;;; Maximum set of rights that may be installed on new file descriptors that ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights_t) + (field $fs_rights_inheriting $rights) ) ) ;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode_t` to uniquely identify a file or directory in the filesystem. -(typename $device_t u64) +;;; with `inode` to uniquely identify a file or directory in the filesystem. +(typename $device u64) ;;; Which file time attributes to adjust. -(typename $fstflags_t +(typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - $FILESTAT_SET_ATIM - ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_ATIM_NOW - ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - $FILESTAT_SET_MTIM - ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_MTIM_NOW + ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + $atim + ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + $atim_now + ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + $mtim + ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + $mtim_now ) ) ;;; Flags determining the method of how paths are resolved. -(typename $lookupflags_t +(typename $lookupflags (flags u32 ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $LOOKUP_SYMLINK_FOLLOW + $symlink_follow ) ) ;;; Open flags used by `path_open`. -(typename $oflags_t +(typename $oflags (flags u16 ;;; Create file if it does not exist. - $O_CREAT + $creat ;;; Fail if not a directory. - $O_DIRECTORY + $directory ;;; Fail if file already exists. - $O_EXCL + $excl ;;; Truncate file to size 0. - $O_TRUNC + $trunc ) ) ;;; Number of hard links to an inode. -(typename $linkcount_t u64) +(typename $linkcount u64) ;;; File attributes. -(typename $filestat_t +(typename $filestat (struct ;;; Device ID of device containing the file. - (field $st_dev $device_t) + (field $dev $device) ;;; File serial number. - (field $st_ino $inode_t) + (field $ino $inode) ;;; File type. - (field $st_filetype $filetype_t) + (field $filetype $filetype) ;;; Number of hard links to the file. - (field $st_nlink $linkcount_t) + (field $nlink $linkcount) ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $st_size $filesize_t) + (field $size $filesize) ;;; Last data access timestamp. - (field $st_atim $timestamp_t) + (field $atim $timestamp) ;;; Last data modification timestamp. - (field $st_mtim $timestamp_t) + (field $mtim $timestamp) ;;; Last file status change timestamp. - (field $st_ctim $timestamp_t) + (field $ctim $timestamp) ) ) ;;; User-provided value that may be attached to objects that is retained when ;;; extracted from the implementation. -(typename $userdata_t u64) +(typename $userdata u64) ;;; Type of a subscription to an event or its occurrence. -(typename $eventtype_t +(typename $eventtype (enum u8 - ;;; The time value of clock `subscription_t::u.clock.clock_id` has - ;;; reached timestamp `subscription_t::u.clock.timeout`. - $EVENTTYPE_CLOCK - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; The time value of clock `subscription::u.clock.clock_id` has + ;;; reached timestamp `subscription::u.clock.timeout`. + $clock + ;;; File descriptor `subscription::u.fd_readwrite.fd` has data ;;; available for reading. This event always triggers for regular files. - $EVENTTYPE_FD_READ - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + $fd_read + ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity ;;; available for writing. This event always triggers for regular files. - $EVENTTYPE_FD_WRITE + $fd_write ) ) ;;; The state of the file descriptor subscribed to with -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $eventrwflags_t +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $eventrwflags (flags u16 ;;; The peer of this socket has closed or disconnected. - $EVENT_FD_READWRITE_HANGUP + $fd_readwrite_hangup ) ) -;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;;; `EVENTTYPE_FD_WRITE`. -(typename $event_fd_readwrite_t +;;; The contents of an $event when type is `eventtype::fd_read` or +;;; `eventtype::fd_write`. +(typename $event_fd_readwrite (struct ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) + (field $nbytes $filesize) ;;; The state of the file descriptor. - (field $flags $eventrwflags_t) + (field $flags $eventrwflags) ) ) -;;; The contents of an $event_t. +;;; The contents of an $event. (typename $event_u (union - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $event_fd_readwrite_t) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $event_fd_readwrite) ) ) ;;; An event that occurred. -(typename $event_t +(typename $event (struct - ;;; User-provided value that got attached to `subscription_t::userdata`. - (field $userdata $userdata_t) + ;;; User-provided value that got attached to `subscription::userdata`. + (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno_t) + (field $error $errno) ;;; The type of the event that occurred. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the event. (field $u $event_u) ) ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_t::u.clock.timeout.` -(typename $subclockflags_t +;;; `subscription::u.clock.timeout.` +(typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription_t::u.clock.timeout` relative to the - ;;; current time value of clock `subscription_t::u.clock.clock_id.` - $SUBSCRIPTION_CLOCK_ABSTIME + ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription::u.clock.timeout` relative to the + ;;; current time value of clock `subscription::u.clock.clock_id.` + $subscription_clock_abstime ) ) -;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. -(typename $subscription_clock_t +;;; The contents of a $subscription when type is `eventtype::clock`. +(typename $subscription_clock (struct ;;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) + (field $id $clockid) ;;; The absolute or relative timestamp. - (field $timeout $timestamp_t) + (field $timeout $timestamp) ;;; The amount of time that the implementation may wait additionally ;;; to coalesce with other events. - (field $precision $timestamp_t) + (field $precision $timestamp) ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags_t) + (field $flags $subclockflags) ) ) -;;; The contents of a $subscription_t when type is type is -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $subscription_fd_readwrite_t +;;; The contents of a $subscription when type is type is +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $subscription_fd_readwrite (struct ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) + (field $file_descriptor $fd) ) ) -;;; The contents of a $subscription_t. +;;; The contents of a $subscription. (typename $subscription_u (union - ;;; When type is `EVENTTYPE_CLOCK`: - (field $clock $subscription_clock_t) - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $subscription_fd_readwrite_t) + ;;; When type is `eventtype::clock`: + (field $clock $subscription_clock) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $subscription_fd_readwrite) ) ) ;;; Subscription to an event. -(typename $subscription_t +(typename $subscription (struct ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event_t::userdata`. - (field $userdata $userdata_t) + ;;; implementation and returned through `event::userdata`. + (field $userdata $userdata) ;;; The type of the event to which to subscribe. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the subscription. (field $u $subscription_u) ) ) ;;; Exit code generated by a process when exiting. -(typename $exitcode_t u32) +(typename $exitcode u32) ;;; Signal condition. -(typename $signal_t +(typename $signal (enum u8 ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. - $SIGNONE + $none ;;; Hangup. ;;; Action: Terminates the process. - $SIGHUP + $hup ;;; Terminate interrupt signal. ;;; Action: Terminates the process. - $SIGINT + $int ;;; Terminal quit signal. ;;; Action: Terminates the process. - $SIGQUIT + $quit ;;; Illegal instruction. ;;; Action: Terminates the process. - $SIGILL + $ill ;;; Trace/breakpoint trap. ;;; Action: Terminates the process. - $SIGTRAP + $trap ;;; Process abort signal. ;;; Action: Terminates the process. - $SIGABRT + $abrt ;;; Access to an undefined portion of a memory object. ;;; Action: Terminates the process. - $SIGBUS + $bus ;;; Erroneous arithmetic operation. ;;; Action: Terminates the process. - $SIGFPE + $fpe ;;; Kill. ;;; Action: Terminates the process. - $SIGKILL + $kill ;;; User-defined signal 1. ;;; Action: Terminates the process. - $SIGUSR1 + $usr1 ;;; Invalid memory reference. ;;; Action: Terminates the process. - $SIGSEGV + $segv ;;; User-defined signal 2. ;;; Action: Terminates the process. - $SIGUSR2 + $usr2 ;;; Write on a pipe with no one to read it. ;;; Action: Ignored. - $SIGPIPE + $pipe ;;; Alarm clock. ;;; Action: Terminates the process. - $SIGALRM + $alrm ;;; Termination signal. ;;; Action: Terminates the process. - $SIGTERM + $term ;;; Child process terminated, stopped, or continued. ;;; Action: Ignored. - $SIGCHLD + $chld ;;; Continue executing, if stopped. ;;; Action: Continues executing, if stopped. - $SIGCONT + $cont ;;; Stop executing. ;;; Action: Stops executing. - $SIGSTOP + $stop ;;; Terminal stop signal. ;;; Action: Stops executing. - $SIGTSTP + $tstp ;;; Background process attempting read. ;;; Action: Stops executing. - $SIGTTIN + $ttin ;;; Background process attempting write. ;;; Action: Stops executing. - $SIGTTOU + $ttou ;;; High bandwidth data is available at a socket. ;;; Action: Ignored. - $SIGURG + $urg ;;; CPU time limit exceeded. ;;; Action: Terminates the process. - $SIGXCPU + $xcpu ;;; File size limit exceeded. ;;; Action: Terminates the process. - $SIGXFSZ + $xfsz ;;; Virtual timer expired. ;;; Action: Terminates the process. - $SIGVTALRM + $vtalrm ;;; Profiling timer expired. ;;; Action: Terminates the process. - $SIGPROF + $prof ;;; Window changed. ;;; Action: Ignored. - $SIGWINCH + $winch ;;; I/O possible. ;;; Action: Terminates the process. - $SIGPOLL + $poll ;;; Power failure. ;;; Action: Terminates the process. - $SIGPWR + $pwr ;;; Bad system call. ;;; Action: Terminates the process. - $SIGSYS + $sys ) ) ;;; Flags provided to `sock_recv`. -(typename $riflags_t +(typename $riflags (flags u16 ;;; Returns the message without removing it from the socket's receive queue. - $SOCK_RECV_PEEK + $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. - $SOCK_RECV_WAITALL + $recv_waitall ) ) ;;; Flags returned by `sock_recv`. -(typename $roflags_t +(typename $roflags (flags u16 ;;; Returned by `sock_recv`: Message data has been truncated. - $SOCK_RECV_DATA_TRUNCATED + $recv_data_truncated ) ) ;;; Flags provided to `sock_send`. As there are currently no flags ;;; defined, it must be set to zero. -(typename $siflags_t u16) +(typename $siflags u16) ;;; Which channels on a socket to shut down. -(typename $sdflags_t +(typename $sdflags (flags u8 ;;; Disables further receive operations. - $SHUT_RD + $rd ;;; Disables further send operations. - $SHUT_WR + $wr ) ) ;;; Identifiers for preopened capabilities. -(typename $preopentype_t +(typename $preopentype (enum u8 ;;; A pre-opened directory. - $PREOPENTYPE_DIR + $dir ) ) -;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size_t) + (field $pr_name_len $size) ) ) -;;; The contents of an $prestat_t. +;;; The contents of an $prestat. (typename $prestat_u (union - ;;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `preopentype::dir`: (field $dir $prestat_dir) ) ) ;;; Information about a pre-opened capability. -(typename $prestat_t +(typename $prestat (struct ;;; The type of the pre-opened capability. - (field $pr_type $preopentype_t) + (field $pr_type $preopentype) ;;; The contents of the information. (field $u $prestat_u) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx index d15b8c514..43bd57e4b 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -17,15 +17,15 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Read environment variable data. @@ -33,187 +33,187 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Return the resolution of a clock. ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno_t) + (result $error $errno) ;;; The clock for which to return the resolution. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The resolution of the clock. - (result $resolution $timestamp_t) + (result $resolution $timestamp) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") ;;; The clock for which to return the time. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp_t) - (result $error $errno_t) + (param $precision $timestamp) + (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp_t) + (result $time $timestamp) ) ;;; Provide file advisory information on a file descriptor. ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset within the file to which the advisory applies. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the region to which the advisory applies. - (param $len $filesize_t) + (param $len $filesize) ;;; The advice. - (param $advice $advice_t) - (result $error $errno_t) + (param $advice $advice) + (result $error $errno) ) ;;; Force the allocation of space in a file. ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset at which to start the allocation. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the area that is allocated. - (param $len $filesize_t) - (result $error $errno_t) + (param $len $filesize) + (result $error $errno) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat_t) + (result $stat $fdstat) ) ;;; Adjust the flags associated with a file descriptor. ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the file descriptor flags. - (param $flags $fdflags_t) - (result $error $errno_t) + (param $flags $fdflags) + (result $error $errno) ) ;;; Adjust the rights associated with a file descriptor. ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights_t) - (param $fs_rights_inheriting $rights_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inheriting $rights) + (result $error $errno) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired file size. - (param $st_size $filesize_t) - (result $error $errno_t) + (param $size $filesize) + (result $error $errno) ) ;;; Adjust the timestamps of an open file or directory. ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_t_array) + (param $iovs $iovec_array) ;;; The offset within the file at which to read. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat_t) + (result $buf $prestat) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") - (param $fd $fd_t) + (param $fd $fd) ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) - (param $path_len $size_t) - (result $error $errno_t) + (param $path_len $size) + (result $error $errno) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) + (param $iovs $ciovec_array) ;;; The offset within the file at which to write. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Read from a file descriptor. ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_t_array) - (result $error $errno_t) + (param $iovs $iovec_array) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Read directory entries from a directory. @@ -227,15 +227,15 @@ ;;; read buffer size in case it's too small to fit a single large directory ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") - (param $fd $fd_t) + (param $fd $fd) ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) - (param $buf_len $size_t) + (param $buf_len $size) ;;; The location within the directory to start reading - (param $cookie $dircookie_t) - (result $error $errno_t) + (param $cookie $dircookie) + (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -249,104 +249,104 @@ ;;; This function provides a way to atomically renumber file descriptors, which ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") - (param $fd $fd_t) + (param $fd $fd) ;;; The file descriptor to overwrite. - (param $to $fd_t) - (result $error $errno_t) + (param $to $fd) + (result $error $errno) ) ;;; Move the offset of a file descriptor. ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") - (param $fd $fd_t) + (param $fd $fd) ;;; The number of bytes to move. - (param $offset $filedelta_t) + (param $offset $filedelta) ;;; The base from which the offset is relative. - (param $whence $whence_t) - (result $error $errno_t) + (param $whence $whence) + (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize_t) + (result $newoffset $filesize) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize_t) + (result $offset $filesize) ) ;;; Write to a file descriptor. ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) - (result $error $errno_t) + (param $iovs $ciovec_array) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Create a directory. ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Return the attributes of a file or directory. ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno_t) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the timestamps of a file or directory. ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to operate on. (param $path string) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Create a hard link. ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $old_fd $fd_t) + (param $old_fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags_t) + (param $old_flags $lookupflags) ;;; The source path from which to link. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Open a file or directory. @@ -359,14 +359,14 @@ ;; ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags_t) + (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the ;;; `dirfd` directory. (param $path string) ;;; The method by which to open the file. - (param $o_flags $oflags_t) + (param $oflags $oflags) ;;; The initial rights of the newly created file descriptor. The ;;; implementation is allowed to return a file descriptor with fewer rights ;;; than specified, if and only if those rights do not apply to the type of @@ -375,49 +375,49 @@ ;;; The *base* rights are rights that will apply to operations using the file ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. - (param $fs_rights_base $rights_t) - (param $fs_rights_inherting $rights_t) - (param $flags $fdflags_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inherting $rights) + (param $fdflags $fdflags) + (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd_t) + (result $opened_fd $fd) ) ;;; Read the contents of a symbolic link. ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") - (param $fd $fd_t) + (param $fd $fd) ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Remove a directory. ;;; Return `ENOTEMPTY` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Rename a file or directory. ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") - (param $fd $fd_t) + (param $fd $fd) ;;; The source path of the file or directory to rename. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Create a symbolic link. @@ -425,10 +425,10 @@ (@interface func (export "path_symlink") ;;; The contents of the symbolic link. (param $old_path string) - (param $fd $fd_t) + (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) @@ -436,23 +436,23 @@ ;;; Return `EISDIR` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription_t)) + (param $in (@witx const_pointer $subscription)) ;;; The events that have occurred. - (param $out (@witx pointer $event_t)) + (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size_t) - (result $error $errno_t) + (param $nsubscriptions $size) + (result $error $errno) ;;; The number of events stored. - (result $nevents $size_t) + (result $nevents $size) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -460,21 +460,21 @@ ;;; the environment. (@interface func (export "proc_exit") ;;; The exit code returned by the process. - (param $rval $exitcode_t) + (param $rval $exitcode) ) ;;; Send a signal to the process of the calling thread. ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") ;;; The signal condition to trigger. - (param $sig $signal_t) - (result $error $errno_t) + (param $sig $signal) + (result $error $errno) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno_t) + (result $error $errno) ) ;;; Write high-quality random data into a buffer. @@ -486,46 +486,46 @@ (@interface func (export "random_get") ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ) ;;; Receive a message from a socket. ;;; Note: This is similar to `recv` in POSIX, though it also supports reading ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_t_array) + (param $ri_data $iovec_array) ;;; Message flags. - (param $ri_flags $riflags_t) - (result $error $errno_t) + (param $ri_flags $riflags) + (result $error $errno) ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size_t) + (result $ro_datalen $size) ;;; Message flags. - (result $ro_flags $roflags_t) + (result $ro_flags $roflags) ) ;;; Send a message on a socket. ;;; Note: This is similar to `send` in POSIX, though it also supports writing ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_t_array) + (param $si_data $ciovec_array) ;;; Message flags. - (param $si_flags $siflags_t) - (result $error $errno_t) + (param $si_flags $siflags) + (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size_t) + (result $so_datalen $size) ) ;;; Shut down socket send and receive channels. ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") - (param $fd $fd_t) + (param $fd $fd) ;;; Which channels on the socket to shut down. - (param $how $sdflags_t) - (result $error $errno_t) + (param $how $sdflags) + (result $error $errno) ) ) diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx index cf39a2deb..9a7fc0bb2 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx @@ -5,29 +5,29 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(typename $size_t u32) +(typename $size u32) ;;; Non-negative file size or length of a region within a file. -(typename $filesize_t u64) +(typename $filesize u64) ;;; Timestamp in nanoseconds. -(typename $timestamp_t u64) +(typename $timestamp u64) ;;; Identifiers for clocks. -(typename $clockid_t +(typename $clockid (enum u32 ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME + $realtime ;;; The store-wide monotonic clock, which is defined as a clock measuring ;;; real time, whose value cannot be adjusted and which cannot have negative ;;; clock jumps. The epoch of this clock is undefined. The absolute time ;;; value of this clock therefore has no meaning. - $CLOCK_MONOTONIC + $monotonic ;;; The CPU-time clock associated with the current process. - $CLOCK_PROCESS_CPUTIME_ID + $process_cputime_id ;;; The CPU-time clock associated with the current thread. - $CLOCK_THREAD_CPUTIME_ID + $thread_cputime_id ) ) @@ -35,720 +35,720 @@ ;;; Not all of these error codes are returned by the functions provided by this ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. -(typename $errno_t +(typename $errno (enum u16 ;;; No error occurred. System call completed successfully. - $ESUCCESS + $success ;;; Argument list too long. - $E2BIG + $2big ;;; Permission denied. - $EACCES + $acces ;;; Address in use. - $EADDRINUSE + $addrinuse ;;; Address not available. - $EADDRNOTAVAIL + $addrnotavail ;;; Address family not supported. - $EAFNOSUPPORT + $afnosupport ;;; Resource unavailable, or operation would block. - $EAGAIN + $again ;;; Connection already in progress. - $EALREADY + $already ;;; Bad file descriptor. - $EBADF + $badf ;;; Bad message. - $EBADMSG + $badmsg ;;; Device or resource busy. - $EBUSY + $busy ;;; Operation canceled. - $ECANCELED + $canceled ;;; No child processes. - $ECHILD + $child ;;; Connection aborted. - $ECONNABORTED + $connaborted ;;; Connection refused. - $ECONNREFUSED + $connrefused ;;; Connection reset. - $ECONNRESET + $connreset ;;; Resource deadlock would occur. - $EDEADLK + $deadlk ;;; Destination address required. - $EDESTADDRREQ + $destaddrreq ;;; Mathematics argument out of domain of function. - $EDOM + $dom ;;; Reserved. - $EDQUOT + $dquot ;;; File exists. - $EEXIST + $exist ;;; Bad address. - $EFAULT + $fault ;;; File too large. - $EFBIG + $fbig ;;; Host is unreachable. - $EHOSTUNREACH + $hostunreach ;;; Identifier removed. - $EIDRM + $idrm ;;; Illegal byte sequence. - $EILSEQ + $ilseq ;;; Operation in progress. - $EINPROGRESS + $inprogress ;;; Interrupted function. - $EINTR + $intr ;;; Invalid argument. - $EINVAL + $inval ;;; I/O error. - $EIO + $io ;;; Socket is connected. - $EISCONN + $isconn ;;; Is a directory. - $EISDIR + $isdir ;;; Too many levels of symbolic links. - $ELOOP + $loop ;;; File descriptor value too large. - $EMFILE + $mfile ;;; Too many links. - $EMLINK + $mlink ;;; Message too large. - $EMSGSIZE + $msgsize ;;; Reserved. - $EMULTIHOP + $multihop ;;; Filename too long. - $ENAMETOOLONG + $nametoolong ;;; Network is down. - $ENETDOWN + $netdown ;;; Connection aborted by network. - $ENETRESET + $netreset ;;; Network unreachable. - $ENETUNREACH + $netunreach ;;; Too many files open in system. - $ENFILE + $nfile ;;; No buffer space available. - $ENOBUFS + $nobufs ;;; No such device. - $ENODEV + $nodev ;;; No such file or directory. - $ENOENT + $noent ;;; Executable file format error. - $ENOEXEC + $noexec ;;; No locks available. - $ENOLCK + $nolck ;;; Reserved. - $ENOLINK + $nolink ;;; Not enough space. - $ENOMEM + $nomem ;;; No message of the desired type. - $ENOMSG + $nomsg ;;; Protocol not available. - $ENOPROTOOPT + $noprotoopt ;;; No space left on device. - $ENOSPC + $nospc ;;; Function not supported. - $ENOSYS + $nosys ;;; The socket is not connected. - $ENOTCONN + $notconn ;;; Not a directory or a symbolic link to a directory. - $ENOTDIR + $notdir ;;; Directory not empty. - $ENOTEMPTY + $notempty ;;; State not recoverable. - $ENOTRECOVERABLE + $notrecoverable ;;; Not a socket. - $ENOTSOCK + $notsock ;;; Not supported, or operation not supported on socket. - $ENOTSUP + $notsup ;;; Inappropriate I/O control operation. - $ENOTTY + $notty ;;; No such device or address. - $ENXIO + $nxio ;;; Value too large to be stored in data type. - $EOVERFLOW + $overflow ;;; Previous owner died. - $EOWNERDEAD + $ownerdead ;;; Operation not permitted. - $EPERM + $perm ;;; Broken pipe. - $EPIPE + $pipe ;;; Protocol error. - $EPROTO + $proto ;;; Protocol not supported. - $EPROTONOSUPPORT + $protonosupport ;;; Protocol wrong type for socket. - $EPROTOTYPE + $prototype ;;; Result too large. - $ERANGE + $range ;;; Read-only file system. - $EROFS + $rofs ;;; Invalid seek. - $ESPIPE + $spipe ;;; No such process. - $ESRCH + $srch ;;; Reserved. - $ESTALE + $stale ;;; Connection timed out. - $ETIMEDOUT + $timedout ;;; Text file busy. - $ETXTBSY + $txtbsy ;;; Cross-device link. - $EXDEV + $xdev ;;; Extension: Capabilities insufficient. - $ENOTCAPABLE + $notcapable ) ) ;;; File descriptor rights, determining which actions may be performed. -(typename $rights_t +(typename $rights (flags u64 ;;; The right to invoke `fd_datasync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; If `rights::path_open` is set, includes the right to invoke ;;; `path_open` with `FDFLAG_DSYNC`. - $RIGHT_FD_DATASYNC + $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - $RIGHT_FD_READ - ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - $RIGHT_FD_SEEK + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. + $fd_read + ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. + $fd_seek ;;; The right to invoke `fd_fdstat_set_flags`. - $RIGHT_FD_FDSTAT_SET_FLAGS + $fd_fdstat_set_flags ;;; The right to invoke `fd_sync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; If `rights::path_open` is set, includes the right to invoke ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - $RIGHT_FD_SYNC + $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;;; invoke `fd_tell`. - $RIGHT_FD_TELL + $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - $RIGHT_FD_WRITE + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. + $fd_write ;;; The right to invoke `fd_advise`. - $RIGHT_FD_ADVISE + $fd_advise ;;; The right to invoke `fd_allocate`. - $RIGHT_FD_ALLOCATE + $fd_allocate ;;; The right to invoke `path_create_directory`. - $RIGHT_PATH_CREATE_DIRECTORY - ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - $RIGHT_PATH_CREATE_FILE + $path_create_directory + ;;; If `rights::path_open` is set, the right to invoke `path_open` with `O_CREAT`. + $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. - $RIGHT_PATH_LINK_SOURCE + $path_link_source ;;; The right to invoke `path_link` with the file descriptor as the ;;; target directory. - $RIGHT_PATH_LINK_TARGET + $path_link_target ;;; The right to invoke `path_open`. - $RIGHT_PATH_OPEN + $path_open ;;; The right to invoke `fd_readdir`. - $RIGHT_FD_READDIR + $fd_readdir ;;; The right to invoke `path_readlink`. - $RIGHT_PATH_READLINK + $path_readlink ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $RIGHT_PATH_RENAME_SOURCE + $path_rename_source ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $RIGHT_PATH_RENAME_TARGET + $path_rename_target ;;; The right to invoke `path_filestat_get`. - $RIGHT_PATH_FILESTAT_GET + $path_filestat_get ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - $RIGHT_PATH_FILESTAT_SET_SIZE + ;;; If `rights::path_open` is set, includes the right to invoke `path_open` with `O_TRUNC`. + $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. - $RIGHT_PATH_FILESTAT_SET_TIMES + $path_filestat_set_times ;;; The right to invoke `fd_filestat_get`. - $RIGHT_FD_FILESTAT_GET + $fd_filestat_get ;;; The right to invoke `fd_filestat_set_size`. - $RIGHT_FD_FILESTAT_SET_SIZE + $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. - $RIGHT_FD_FILESTAT_SET_TIMES + $fd_filestat_set_times ;;; The right to invoke `path_symlink`. - $RIGHT_PATH_SYMLINK + $path_symlink ;;; The right to invoke `path_remove_directory`. - $RIGHT_PATH_REMOVE_DIRECTORY + $path_remove_directory ;;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE - ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - $RIGHT_POLL_FD_READWRITE + $path_unlink_file + ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. + ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. + $poll_fd_readwrite ;;; The right to invoke `sock_shutdown`. - $RIGHT_SOCK_SHUTDOWN + $sock_shutdown ) ) ;;; A file descriptor index. -(typename $fd_t u32) +(typename $fd u32) ;;; A region of memory for scatter/gather reads. -(typename $iovec_t +(typename $iovec (struct ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. - (field $buf_len $size_t) + (field $buf_len $size) ) ) ;;; A region of memory for scatter/gather writes. -(typename $ciovec_t +(typename $ciovec (struct ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. - (field $buf_len $size_t) + (field $buf_len $size) ) ) -(typename $iovec_t_array (array $iovec_t)) -(typename $ciovec_t_array (array $ciovec_t)) +(typename $iovec_array (array $iovec)) +(typename $ciovec_array (array $ciovec)) ;;; Relative offset within a file. -(typename $filedelta_t s64) +(typename $filedelta s64) ;;; The position relative to which to set the offset of the file descriptor. -(typename $whence_t +(typename $whence (enum u8 ;;; Seek relative to current position. - $WHENCE_CUR + $cur ;;; Seek relative to end-of-file. - $WHENCE_END + $end ;;; Seek relative to start-of-file. - $WHENCE_SET + $set ) ) ;;; A reference to the offset of a directory entry. -(typename $dircookie_t u64) +(typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent_t. -(typename $dirnamlen_t u32) +;;; The type for the $d_namlen field of $dirent. +(typename $dirnamlen u32) ;;; File serial number that is unique within its file system. -(typename $inode_t u64) +(typename $inode u64) ;;; The type of a file descriptor or file. -(typename $filetype_t +(typename $filetype (enum u8 ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $FILETYPE_UNKNOWN + $unknown ;;; The file descriptor or file refers to a block device inode. - $FILETYPE_BLOCK_DEVICE + $block_device ;;; The file descriptor or file refers to a character device inode. - $FILETYPE_CHARACTER_DEVICE + $character_device ;;; The file descriptor or file refers to a directory inode. - $FILETYPE_DIRECTORY + $directory ;;; The file descriptor or file refers to a regular file inode. - $FILETYPE_REGULAR_FILE + $regular_file ;;; The file descriptor or file refers to a datagram socket. - $FILETYPE_SOCKET_DGRAM + $socket_dgram ;;; The file descriptor or file refers to a byte-stream socket. - $FILETYPE_SOCKET_STREAM + $socket_stream ;;; The file refers to a symbolic link inode. - $FILETYPE_SYMBOLIC_LINK + $symbolic_link ) ) ;;; A directory entry. -(typename $dirent_t +(typename $dirent (struct ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie_t) + (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode_t) + (field $d_ino $inode) ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen_t) + (field $d_namlen $dirnamlen) ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype_t) + (field $d_type $filetype) ) ) ;;; File or memory access pattern advisory information. -(typename $advice_t +(typename $advice (enum u8 ;;; The application has no advice to give on its behavior with respect to the specified data. - $ADVICE_NORMAL + $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $ADVICE_SEQUENTIAL + $sequential ;;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM + $random ;;; The application expects to access the specified data in the near future. - $ADVICE_WILLNEED + $willneed ;;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED + $dontneed ;;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE + $noreuse ) ) ;;; File descriptor flags. -(typename $fdflags_t +(typename $fdflags (flags u16 ;;; Append mode: Data written to the file is always appended to the file's end. - $FDFLAG_APPEND + $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $FDFLAG_DSYNC + $dsync ;;; Non-blocking mode. - $FDFLAG_NONBLOCK + $nonblock ;;; Synchronized read I/O operations. - $FDFLAG_RSYNC + $rsync ;;; Write according to synchronized I/O file integrity completion. In ;;; addition to synchronizing the data stored in the file, the implementation ;;; may also synchronously update the file's metadata. - $FDFLAG_SYNC + $sync ) ) ;;; File descriptor attributes. -(typename $fdstat_t +(typename $fdstat (struct ;;; File type. - (field $fs_filetype $filetype_t) + (field $fs_filetype $filetype) ;;; File descriptor flags. - (field $fs_flags $fdflags_t) + (field $fs_flags $fdflags) ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights_t) + (field $fs_rights_base $rights) ;;; Maximum set of rights that may be installed on new file descriptors that ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights_t) + (field $fs_rights_inheriting $rights) ) ) ;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode_t` to uniquely identify a file or directory in the filesystem. -(typename $device_t u64) +;;; with `inode` to uniquely identify a file or directory in the filesystem. +(typename $device u64) ;;; Which file time attributes to adjust. -(typename $fstflags_t +(typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - $FILESTAT_SET_ATIM - ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_ATIM_NOW - ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - $FILESTAT_SET_MTIM - ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_MTIM_NOW + ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + $atim + ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + $atim_now + ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + $mtim + ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + $mtim_now ) ) ;;; Flags determining the method of how paths are resolved. -(typename $lookupflags_t +(typename $lookupflags (flags u32 ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $LOOKUP_SYMLINK_FOLLOW + $symlink_follow ) ) ;;; Open flags used by `path_open`. -(typename $oflags_t +(typename $oflags (flags u16 ;;; Create file if it does not exist. - $O_CREAT + $creat ;;; Fail if not a directory. - $O_DIRECTORY + $directory ;;; Fail if file already exists. - $O_EXCL + $excl ;;; Truncate file to size 0. - $O_TRUNC + $trunc ) ) ;;; Number of hard links to an inode. -(typename $linkcount_t u32) +(typename $linkcount u32) ;;; File attributes. -(typename $filestat_t +(typename $filestat (struct ;;; Device ID of device containing the file. - (field $st_dev $device_t) + (field $dev $device) ;;; File serial number. - (field $st_ino $inode_t) + (field $ino $inode) ;;; File type. - (field $st_filetype $filetype_t) + (field $filetype $filetype) ;;; Number of hard links to the file. - (field $st_nlink $linkcount_t) + (field $nlink $linkcount) ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $st_size $filesize_t) + (field $size $filesize) ;;; Last data access timestamp. - (field $st_atim $timestamp_t) + (field $atim $timestamp) ;;; Last data modification timestamp. - (field $st_mtim $timestamp_t) + (field $mtim $timestamp) ;;; Last file status change timestamp. - (field $st_ctim $timestamp_t) + (field $ctim $timestamp) ) ) ;;; User-provided value that may be attached to objects that is retained when ;;; extracted from the implementation. -(typename $userdata_t u64) +(typename $userdata u64) ;;; Type of a subscription to an event or its occurrence. -(typename $eventtype_t +(typename $eventtype (enum u8 - ;;; The time value of clock `subscription_t::u.clock.clock_id` has - ;;; reached timestamp `subscription_t::u.clock.timeout`. - $EVENTTYPE_CLOCK - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; The time value of clock `subscription::u.clock.clock_id` has + ;;; reached timestamp `subscription::u.clock.timeout`. + $clock + ;;; File descriptor `subscription::u.fd_readwrite.fd` has data ;;; available for reading. This event always triggers for regular files. - $EVENTTYPE_FD_READ - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + $fd_read + ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity ;;; available for writing. This event always triggers for regular files. - $EVENTTYPE_FD_WRITE + $fd_write ) ) ;;; The state of the file descriptor subscribed to with -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $eventrwflags_t +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $eventrwflags (flags u16 ;;; The peer of this socket has closed or disconnected. - $EVENT_FD_READWRITE_HANGUP + $fd_readwrite_hangup ) ) -;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;;; `EVENTTYPE_FD_WRITE`. -(typename $event_fd_readwrite_t +;;; The contents of an $event when type is `eventtype::fd_read` or +;;; `eventtype::fd_write`. +(typename $event_fd_readwrite (struct ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) + (field $nbytes $filesize) ;;; The state of the file descriptor. - (field $flags $eventrwflags_t) + (field $flags $eventrwflags) ) ) -;;; The contents of an $event_t. +;;; The contents of an $event. (typename $event_u (union - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $event_fd_readwrite_t) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $event_fd_readwrite) ) ) ;;; An event that occurred. -(typename $event_t +(typename $event (struct - ;;; User-provided value that got attached to `subscription_t::userdata`. - (field $userdata $userdata_t) + ;;; User-provided value that got attached to `subscription::userdata`. + (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno_t) + (field $error $errno) ;;; The type of the event that occurred. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the event. (field $u $event_u) ) ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_t::u.clock.timeout.` -(typename $subclockflags_t +;;; `subscription::u.clock.timeout.` +(typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription_t::u.clock.timeout` relative to the - ;;; current time value of clock `subscription_t::u.clock.clock_id.` - $SUBSCRIPTION_CLOCK_ABSTIME + ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription::u.clock.timeout` relative to the + ;;; current time value of clock `subscription::u.clock.clock_id.` + $subscription_clock_abstime ) ) -;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. -(typename $subscription_clock_t +;;; The contents of a $subscription when type is `eventtype::clock`. +(typename $subscription_clock (struct ;;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) + (field $identifier $userdata) ;;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) + (field $id $clockid) ;;; The absolute or relative timestamp. - (field $timeout $timestamp_t) + (field $timeout $timestamp) ;;; The amount of time that the implementation may wait additionally ;;; to coalesce with other events. - (field $precision $timestamp_t) + (field $precision $timestamp) ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags_t) + (field $flags $subclockflags) ) ) -;;; The contents of a $subscription_t when type is type is -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $subscription_fd_readwrite_t +;;; The contents of a $subscription when type is type is +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $subscription_fd_readwrite (struct ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) + (field $file_descriptor $fd) ) ) -;;; The contents of a $subscription_t. +;;; The contents of a $subscription. (typename $subscription_u (union - ;;; When type is `EVENTTYPE_CLOCK`: - (field $clock $subscription_clock_t) - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $subscription_fd_readwrite_t) + ;;; When type is `eventtype::clock`: + (field $clock $subscription_clock) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $subscription_fd_readwrite) ) ) ;;; Subscription to an event. -(typename $subscription_t +(typename $subscription (struct ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event_t::userdata`. - (field $userdata $userdata_t) + ;;; implementation and returned through `event::userdata`. + (field $userdata $userdata) ;;; The type of the event to which to subscribe. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the subscription. (field $u $subscription_u) ) ) ;;; Exit code generated by a process when exiting. -(typename $exitcode_t u32) +(typename $exitcode u32) ;;; Signal condition. -(typename $signal_t +(typename $signal (enum u8 ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. - $SIGNONE + $none ;;; Hangup. ;;; Action: Terminates the process. - $SIGHUP + $hup ;;; Terminate interrupt signal. ;;; Action: Terminates the process. - $SIGINT + $int ;;; Terminal quit signal. ;;; Action: Terminates the process. - $SIGQUIT + $quit ;;; Illegal instruction. ;;; Action: Terminates the process. - $SIGILL + $ill ;;; Trace/breakpoint trap. ;;; Action: Terminates the process. - $SIGTRAP + $trap ;;; Process abort signal. ;;; Action: Terminates the process. - $SIGABRT + $abrt ;;; Access to an undefined portion of a memory object. ;;; Action: Terminates the process. - $SIGBUS + $bus ;;; Erroneous arithmetic operation. ;;; Action: Terminates the process. - $SIGFPE + $fpe ;;; Kill. ;;; Action: Terminates the process. - $SIGKILL + $kill ;;; User-defined signal 1. ;;; Action: Terminates the process. - $SIGUSR1 + $usr1 ;;; Invalid memory reference. ;;; Action: Terminates the process. - $SIGSEGV + $segv ;;; User-defined signal 2. ;;; Action: Terminates the process. - $SIGUSR2 + $usr2 ;;; Write on a pipe with no one to read it. ;;; Action: Ignored. - $SIGPIPE + $pipe ;;; Alarm clock. ;;; Action: Terminates the process. - $SIGALRM + $alrm ;;; Termination signal. ;;; Action: Terminates the process. - $SIGTERM + $term ;;; Child process terminated, stopped, or continued. ;;; Action: Ignored. - $SIGCHLD + $chld ;;; Continue executing, if stopped. ;;; Action: Continues executing, if stopped. - $SIGCONT + $cont ;;; Stop executing. ;;; Action: Stops executing. - $SIGSTOP + $stop ;;; Terminal stop signal. ;;; Action: Stops executing. - $SIGTSTP + $tstp ;;; Background process attempting read. ;;; Action: Stops executing. - $SIGTTIN + $ttin ;;; Background process attempting write. ;;; Action: Stops executing. - $SIGTTOU + $ttou ;;; High bandwidth data is available at a socket. ;;; Action: Ignored. - $SIGURG + $urg ;;; CPU time limit exceeded. ;;; Action: Terminates the process. - $SIGXCPU + $xcpu ;;; File size limit exceeded. ;;; Action: Terminates the process. - $SIGXFSZ + $xfsz ;;; Virtual timer expired. ;;; Action: Terminates the process. - $SIGVTALRM + $vtalrm ;;; Profiling timer expired. ;;; Action: Terminates the process. - $SIGPROF + $prof ;;; Window changed. ;;; Action: Ignored. - $SIGWINCH + $winch ;;; I/O possible. ;;; Action: Terminates the process. - $SIGPOLL + $poll ;;; Power failure. ;;; Action: Terminates the process. - $SIGPWR + $pwr ;;; Bad system call. ;;; Action: Terminates the process. - $SIGSYS + $sys ) ) ;;; Flags provided to `sock_recv`. -(typename $riflags_t +(typename $riflags (flags u16 ;;; Returns the message without removing it from the socket's receive queue. - $SOCK_RECV_PEEK + $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. - $SOCK_RECV_WAITALL + $recv_waitall ) ) ;;; Flags returned by `sock_recv`. -(typename $roflags_t +(typename $roflags (flags u16 ;;; Returned by `sock_recv`: Message data has been truncated. - $SOCK_RECV_DATA_TRUNCATED + $recv_data_truncated ) ) ;;; Flags provided to `sock_send`. As there are currently no flags ;;; defined, it must be set to zero. -(typename $siflags_t u16) +(typename $siflags u16) ;;; Which channels on a socket to shut down. -(typename $sdflags_t +(typename $sdflags (flags u8 ;;; Disables further receive operations. - $SHUT_RD + $rd ;;; Disables further send operations. - $SHUT_WR + $wr ) ) ;;; Identifiers for preopened capabilities. -(typename $preopentype_t +(typename $preopentype (enum u8 ;;; A pre-opened directory. - $PREOPENTYPE_DIR + $dir ) ) -;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat when type is `PREOPENTYPE_DIR`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size_t) + (field $pr_name_len $size) ) ) -;;; The contents of an $prestat_t. +;;; The contents of an $prestat. (typename $prestat_u (union ;;; When type is `PREOPENTYPE_DIR`: @@ -757,10 +757,10 @@ ) ;;; Information about a pre-opened capability. -(typename $prestat_t +(typename $prestat (struct ;;; The type of the pre-opened capability. - (field $pr_type $preopentype_t) + (field $pr_type $preopentype) ;;; The contents of the information. (field $u $prestat_u) ) diff --git a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx index 4cf5f4ffa..5e125caf2 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -20,15 +20,15 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Read environment variable data. @@ -36,187 +36,187 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Return the resolution of a clock. ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno_t) + (result $error $errno) ;;; The clock for which to return the resolution. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The resolution of the clock. - (result $resolution $timestamp_t) + (result $resolution $timestamp) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") ;;; The clock for which to return the time. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp_t) - (result $error $errno_t) + (param $precision $timestamp) + (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp_t) + (result $time $timestamp) ) ;;; Provide file advisory information on a file descriptor. ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset within the file to which the advisory applies. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the region to which the advisory applies. - (param $len $filesize_t) + (param $len $filesize) ;;; The advice. - (param $advice $advice_t) - (result $error $errno_t) + (param $advice $advice) + (result $error $errno) ) ;;; Force the allocation of space in a file. ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset at which to start the allocation. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the area that is allocated. - (param $len $filesize_t) - (result $error $errno_t) + (param $len $filesize) + (result $error $errno) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat_t) + (result $stat $fdstat) ) ;;; Adjust the flags associated with a file descriptor. ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the file descriptor flags. - (param $flags $fdflags_t) - (result $error $errno_t) + (param $flags $fdflags) + (result $error $errno) ) ;;; Adjust the rights associated with a file descriptor. ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights_t) - (param $fs_rights_inheriting $rights_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inheriting $rights) + (result $error $errno) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired file size. - (param $st_size $filesize_t) - (result $error $errno_t) + (param $size $filesize) + (result $error $errno) ) ;;; Adjust the timestamps of an open file or directory. ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_t_array) + (param $iovs $iovec_array) ;;; The offset within the file at which to read. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat_t) + (result $buf $prestat) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") - (param $fd $fd_t) + (param $fd $fd) ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) - (param $path_len $size_t) - (result $error $errno_t) + (param $path_len $size) + (result $error $errno) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) + (param $iovs $ciovec_array) ;;; The offset within the file at which to write. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Read from a file descriptor. ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_t_array) - (result $error $errno_t) + (param $iovs $iovec_array) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Read directory entries from a directory. @@ -230,15 +230,15 @@ ;;; read buffer size in case it's too small to fit a single large directory ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") - (param $fd $fd_t) + (param $fd $fd) ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) - (param $buf_len $size_t) + (param $buf_len $size) ;;; The location within the directory to start reading - (param $cookie $dircookie_t) - (result $error $errno_t) + (param $cookie $dircookie) + (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -252,104 +252,104 @@ ;;; This function provides a way to atomically renumber file descriptors, which ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") - (param $fd $fd_t) + (param $fd $fd) ;;; The file descriptor to overwrite. - (param $to $fd_t) - (result $error $errno_t) + (param $to $fd) + (result $error $errno) ) ;;; Move the offset of a file descriptor. ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") - (param $fd $fd_t) + (param $fd $fd) ;;; The number of bytes to move. - (param $offset $filedelta_t) + (param $offset $filedelta) ;;; The base from which the offset is relative. - (param $whence $whence_t) - (result $error $errno_t) + (param $whence $whence) + (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize_t) + (result $newoffset $filesize) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize_t) + (result $offset $filesize) ) ;;; Write to a file descriptor. ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) - (result $error $errno_t) + (param $iovs $ciovec_array) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Create a directory. ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Return the attributes of a file or directory. ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno_t) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the timestamps of a file or directory. ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to operate on. (param $path string) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Create a hard link. ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $old_fd $fd_t) + (param $old_fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags_t) + (param $old_flags $lookupflags) ;;; The source path from which to link. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Open a file or directory. @@ -362,14 +362,14 @@ ;; ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags_t) + (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the ;;; `dirfd` directory. (param $path string) ;;; The method by which to open the file. - (param $o_flags $oflags_t) + (param $oflags $oflags) ;;; The initial rights of the newly created file descriptor. The ;;; implementation is allowed to return a file descriptor with fewer rights ;;; than specified, if and only if those rights do not apply to the type of @@ -378,49 +378,49 @@ ;;; The *base* rights are rights that will apply to operations using the file ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. - (param $fs_rights_base $rights_t) - (param $fs_rights_inherting $rights_t) - (param $flags $fdflags_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inherting $rights) + (param $fdflags $fdflags) + (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd_t) + (result $opened_fd $fd) ) ;;; Read the contents of a symbolic link. ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") - (param $fd $fd_t) + (param $fd $fd) ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Remove a directory. ;;; Return `ENOTEMPTY` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Rename a file or directory. ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") - (param $fd $fd_t) + (param $fd $fd) ;;; The source path of the file or directory to rename. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Create a symbolic link. @@ -428,10 +428,10 @@ (@interface func (export "path_symlink") ;;; The contents of the symbolic link. (param $old_path string) - (param $fd $fd_t) + (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) @@ -439,23 +439,23 @@ ;;; Return `EISDIR` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription_t)) + (param $in (@witx const_pointer $subscription)) ;;; The events that have occurred. - (param $out (@witx pointer $event_t)) + (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size_t) - (result $error $errno_t) + (param $nsubscriptions $size) + (result $error $errno) ;;; The number of events stored. - (result $nevents $size_t) + (result $nevents $size) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -463,21 +463,21 @@ ;;; the environment. (@interface func (export "proc_exit") ;;; The exit code returned by the process. - (param $rval $exitcode_t) + (param $rval $exitcode) ) ;;; Send a signal to the process of the calling thread. ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") ;;; The signal condition to trigger. - (param $sig $signal_t) - (result $error $errno_t) + (param $sig $signal) + (result $error $errno) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno_t) + (result $error $errno) ) ;;; Write high-quality random data into a buffer. @@ -489,46 +489,46 @@ (@interface func (export "random_get") ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ) ;;; Receive a message from a socket. ;;; Note: This is similar to `recv` in POSIX, though it also supports reading ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_t_array) + (param $ri_data $iovec_array) ;;; Message flags. - (param $ri_flags $riflags_t) - (result $error $errno_t) + (param $ri_flags $riflags) + (result $error $errno) ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size_t) + (result $ro_datalen $size) ;;; Message flags. - (result $ro_flags $roflags_t) + (result $ro_flags $roflags) ) ;;; Send a message on a socket. ;;; Note: This is similar to `send` in POSIX, though it also supports writing ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_t_array) + (param $si_data $ciovec_array) ;;; Message flags. - (param $si_flags $siflags_t) - (result $error $errno_t) + (param $si_flags $siflags) + (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size_t) + (result $so_datalen $size) ) ;;; Shut down socket send and receive channels. ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") - (param $fd $fd_t) + (param $fd $fd) ;;; Which channels on the socket to shut down. - (param $how $sdflags_t) - (result $error $errno_t) + (param $how $sdflags) + (result $error $errno) ) ) diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx index 68f6fac4a..d8ce215d7 100644 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -5,29 +5,29 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(typename $size_t u32) +(typename $size u32) ;;; Non-negative file size or length of a region within a file. -(typename $filesize_t u64) +(typename $filesize u64) ;;; Timestamp in nanoseconds. -(typename $timestamp_t u64) +(typename $timestamp u64) ;;; Identifiers for clocks. -(typename $clockid_t +(typename $clockid (enum u32 ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME + $realtime ;;; The store-wide monotonic clock, which is defined as a clock measuring ;;; real time, whose value cannot be adjusted and which cannot have negative ;;; clock jumps. The epoch of this clock is undefined. The absolute time ;;; value of this clock therefore has no meaning. - $CLOCK_MONOTONIC + $monotonic ;;; The CPU-time clock associated with the current process. - $CLOCK_PROCESS_CPUTIME_ID + $process_cputime_id ;;; The CPU-time clock associated with the current thread. - $CLOCK_THREAD_CPUTIME_ID + $thread_cputime_id ) ) @@ -35,732 +35,732 @@ ;;; Not all of these error codes are returned by the functions provided by this ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. -(typename $errno_t +(typename $errno (enum u16 ;;; No error occurred. System call completed successfully. - $ESUCCESS + $success ;;; Argument list too long. - $E2BIG + $2big ;;; Permission denied. - $EACCES + $acces ;;; Address in use. - $EADDRINUSE + $addrinuse ;;; Address not available. - $EADDRNOTAVAIL + $addrnotavail ;;; Address family not supported. - $EAFNOSUPPORT + $afnosupport ;;; Resource unavailable, or operation would block. - $EAGAIN + $again ;;; Connection already in progress. - $EALREADY + $already ;;; Bad file descriptor. - $EBADF + $badf ;;; Bad message. - $EBADMSG + $badmsg ;;; Device or resource busy. - $EBUSY + $busy ;;; Operation canceled. - $ECANCELED + $canceled ;;; No child processes. - $ECHILD + $child ;;; Connection aborted. - $ECONNABORTED + $connaborted ;;; Connection refused. - $ECONNREFUSED + $connrefused ;;; Connection reset. - $ECONNRESET + $connreset ;;; Resource deadlock would occur. - $EDEADLK + $deadlk ;;; Destination address required. - $EDESTADDRREQ + $destaddrreq ;;; Mathematics argument out of domain of function. - $EDOM + $dom ;;; Reserved. - $EDQUOT + $dquot ;;; File exists. - $EEXIST + $exist ;;; Bad address. - $EFAULT + $fault ;;; File too large. - $EFBIG + $fbig ;;; Host is unreachable. - $EHOSTUNREACH + $hostunreach ;;; Identifier removed. - $EIDRM + $idrm ;;; Illegal byte sequence. - $EILSEQ + $ilseq ;;; Operation in progress. - $EINPROGRESS + $inprogress ;;; Interrupted function. - $EINTR + $intr ;;; Invalid argument. - $EINVAL + $inval ;;; I/O error. - $EIO + $io ;;; Socket is connected. - $EISCONN + $isconn ;;; Is a directory. - $EISDIR + $isdir ;;; Too many levels of symbolic links. - $ELOOP + $loop ;;; File descriptor value too large. - $EMFILE + $mfile ;;; Too many links. - $EMLINK + $mlink ;;; Message too large. - $EMSGSIZE + $msgsize ;;; Reserved. - $EMULTIHOP + $multihop ;;; Filename too long. - $ENAMETOOLONG + $nametoolong ;;; Network is down. - $ENETDOWN + $netdown ;;; Connection aborted by network. - $ENETRESET + $netreset ;;; Network unreachable. - $ENETUNREACH + $netunreach ;;; Too many files open in system. - $ENFILE + $nfile ;;; No buffer space available. - $ENOBUFS + $nobufs ;;; No such device. - $ENODEV + $nodev ;;; No such file or directory. - $ENOENT + $noent ;;; Executable file format error. - $ENOEXEC + $noexec ;;; No locks available. - $ENOLCK + $nolck ;;; Reserved. - $ENOLINK + $nolink ;;; Not enough space. - $ENOMEM + $nomem ;;; No message of the desired type. - $ENOMSG + $nomsg ;;; Protocol not available. - $ENOPROTOOPT + $noprotoopt ;;; No space left on device. - $ENOSPC + $nospc ;;; Function not supported. - $ENOSYS + $nosys ;;; The socket is not connected. - $ENOTCONN + $notconn ;;; Not a directory or a symbolic link to a directory. - $ENOTDIR + $notdir ;;; Directory not empty. - $ENOTEMPTY + $notempty ;;; State not recoverable. - $ENOTRECOVERABLE + $notrecoverable ;;; Not a socket. - $ENOTSOCK + $notsock ;;; Not supported, or operation not supported on socket. - $ENOTSUP + $notsup ;;; Inappropriate I/O control operation. - $ENOTTY + $notty ;;; No such device or address. - $ENXIO + $nxio ;;; Value too large to be stored in data type. - $EOVERFLOW + $overflow ;;; Previous owner died. - $EOWNERDEAD + $ownerdead ;;; Operation not permitted. - $EPERM + $perm ;;; Broken pipe. - $EPIPE + $pipe ;;; Protocol error. - $EPROTO + $proto ;;; Protocol not supported. - $EPROTONOSUPPORT + $protonosupport ;;; Protocol wrong type for socket. - $EPROTOTYPE + $prototype ;;; Result too large. - $ERANGE + $range ;;; Read-only file system. - $EROFS + $rofs ;;; Invalid seek. - $ESPIPE + $spipe ;;; No such process. - $ESRCH + $srch ;;; Reserved. - $ESTALE + $stale ;;; Connection timed out. - $ETIMEDOUT + $timedout ;;; Text file busy. - $ETXTBSY + $txtbsy ;;; Cross-device link. - $EXDEV + $xdev ;;; Extension: Capabilities insufficient. - $ENOTCAPABLE + $notcapable ) ) ;;; File descriptor rights, determining which actions may be performed. -(typename $rights_t +(typename $rights (flags u64 ;;; The right to invoke `fd_datasync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_DSYNC`. - $RIGHT_FD_DATASYNC + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflag::dsync`. + $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - $RIGHT_FD_READ - ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - $RIGHT_FD_SEEK + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. + $fd_read + ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. + $fd_seek ;;; The right to invoke `fd_fdstat_set_flags`. - $RIGHT_FD_FDSTAT_SET_FLAGS + $fd_fdstat_set_flags ;;; The right to invoke `fd_sync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - $RIGHT_FD_SYNC + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflag::rsync` and `fdflag::dsync`. + $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;;; invoke `fd_tell`. - $RIGHT_FD_TELL + $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - $RIGHT_FD_WRITE + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. + $fd_write ;;; The right to invoke `fd_advise`. - $RIGHT_FD_ADVISE + $fd_advise ;;; The right to invoke `fd_allocate`. - $RIGHT_FD_ALLOCATE + $fd_allocate ;;; The right to invoke `path_create_directory`. - $RIGHT_PATH_CREATE_DIRECTORY - ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - $RIGHT_PATH_CREATE_FILE + $path_create_directory + ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::creat`. + $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. - $RIGHT_PATH_LINK_SOURCE + $path_link_source ;;; The right to invoke `path_link` with the file descriptor as the ;;; target directory. - $RIGHT_PATH_LINK_TARGET + $path_link_target ;;; The right to invoke `path_open`. - $RIGHT_PATH_OPEN + $path_open ;;; The right to invoke `fd_readdir`. - $RIGHT_FD_READDIR + $fd_readdir ;;; The right to invoke `path_readlink`. - $RIGHT_PATH_READLINK + $path_readlink ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $RIGHT_PATH_RENAME_SOURCE + $path_rename_source ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $RIGHT_PATH_RENAME_TARGET + $path_rename_target ;;; The right to invoke `path_filestat_get`. - $RIGHT_PATH_FILESTAT_GET + $path_filestat_get ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - $RIGHT_PATH_FILESTAT_SET_SIZE + ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. + $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. - $RIGHT_PATH_FILESTAT_SET_TIMES + $path_filestat_set_times ;;; The right to invoke `fd_filestat_get`. - $RIGHT_FD_FILESTAT_GET + $fd_filestat_get ;;; The right to invoke `fd_filestat_set_size`. - $RIGHT_FD_FILESTAT_SET_SIZE + $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. - $RIGHT_FD_FILESTAT_SET_TIMES + $fd_filestat_set_times ;;; The right to invoke `path_symlink`. - $RIGHT_PATH_SYMLINK + $path_symlink ;;; The right to invoke `path_remove_directory`. - $RIGHT_PATH_REMOVE_DIRECTORY + $path_remove_directory ;;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE - ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - $RIGHT_POLL_FD_READWRITE + $path_unlink_file + ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. + ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. + $poll_fd_readwrite ;;; The right to invoke `sock_shutdown`. - $RIGHT_SOCK_SHUTDOWN + $sock_shutdown ) ) ;;; A file descriptor index. -(typename $fd_t u32) +(typename $fd u32) ;;; A region of memory for scatter/gather reads. -(typename $iovec_t +(typename $iovec (struct ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. - (field $buf_len $size_t) + (field $buf_len $size) ) ) ;;; A region of memory for scatter/gather writes. -(typename $ciovec_t +(typename $ciovec (struct ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. - (field $buf_len $size_t) + (field $buf_len $size) ) ) -(typename $iovec_t_array (array $iovec_t)) -(typename $ciovec_t_array (array $ciovec_t)) +(typename $iovec_array (array $iovec)) +(typename $ciovec_array (array $ciovec)) ;;; Relative offset within a file. -(typename $filedelta_t s64) +(typename $filedelta s64) ;;; The position relative to which to set the offset of the file descriptor. -(typename $whence_t +(typename $whence (enum u8 ;;; Seek relative to start-of-file. - $WHENCE_SET + $set ;;; Seek relative to current position. - $WHENCE_CUR + $cur ;;; Seek relative to end-of-file. - $WHENCE_END + $end ) ) ;;; A reference to the offset of a directory entry. ;;; ;;; The value 0 signifies the start of the directory. -(typename $dircookie_t u64) +(typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent_t. -(typename $dirnamlen_t u32) +;;; The type for the $d_namlen field of $dirent. +(typename $dirnamlen u32) ;;; File serial number that is unique within its file system. -(typename $inode_t u64) +(typename $inode u64) ;;; The type of a file descriptor or file. -(typename $filetype_t +(typename $filetype (enum u8 ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $FILETYPE_UNKNOWN + $unknown ;;; The file descriptor or file refers to a block device inode. - $FILETYPE_BLOCK_DEVICE + $block_device ;;; The file descriptor or file refers to a character device inode. - $FILETYPE_CHARACTER_DEVICE + $character_device ;;; The file descriptor or file refers to a directory inode. - $FILETYPE_DIRECTORY + $directory ;;; The file descriptor or file refers to a regular file inode. - $FILETYPE_REGULAR_FILE + $regular_file ;;; The file descriptor or file refers to a datagram socket. - $FILETYPE_SOCKET_DGRAM + $socket_dgram ;;; The file descriptor or file refers to a byte-stream socket. - $FILETYPE_SOCKET_STREAM + $socket_stream ;;; The file refers to a symbolic link inode. - $FILETYPE_SYMBOLIC_LINK + $symbolic_link ) ) ;;; A directory entry. -(typename $dirent_t +(typename $dirent (struct ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie_t) + (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode_t) + (field $d_ino $inode) ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen_t) + (field $d_namlen $dirnamlen) ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype_t) + (field $d_type $filetype) ) ) ;;; File or memory access pattern advisory information. -(typename $advice_t +(typename $advice (enum u8 ;;; The application has no advice to give on its behavior with respect to the specified data. - $ADVICE_NORMAL + $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $ADVICE_SEQUENTIAL + $sequential ;;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM + $random ;;; The application expects to access the specified data in the near future. - $ADVICE_WILLNEED + $willneed ;;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED + $dontneed ;;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE + $noreuse ) ) ;;; File descriptor flags. -(typename $fdflags_t +(typename $fdflags (flags u16 ;;; Append mode: Data written to the file is always appended to the file's end. - $FDFLAG_APPEND + $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $FDFLAG_DSYNC + $dsync ;;; Non-blocking mode. - $FDFLAG_NONBLOCK + $nonblock ;;; Synchronized read I/O operations. - $FDFLAG_RSYNC + $rsync ;;; Write according to synchronized I/O file integrity completion. In ;;; addition to synchronizing the data stored in the file, the implementation ;;; may also synchronously update the file's metadata. - $FDFLAG_SYNC + $sync ) ) ;;; File descriptor attributes. -(typename $fdstat_t +(typename $fdstat (struct ;;; File type. - (field $fs_filetype $filetype_t) + (field $fs_filetype $filetype) ;;; File descriptor flags. - (field $fs_flags $fdflags_t) + (field $fs_flags $fdflags) ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights_t) + (field $fs_rights_base $rights) ;;; Maximum set of rights that may be installed on new file descriptors that ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights_t) + (field $fs_rights_inheriting $rights) ) ) ;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode_t` to uniquely identify a file or directory in the filesystem. -(typename $device_t u64) +;;; with `inode` to uniquely identify a file or directory in the filesystem. +(typename $device u64) ;;; Which file time attributes to adjust. -(typename $fstflags_t +(typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - $FILESTAT_SET_ATIM - ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_ATIM_NOW - ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - $FILESTAT_SET_MTIM - ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_MTIM_NOW + ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + $atim + ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + $atim_now + ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + $mtim + ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + $mtim_now ) ) ;;; Flags determining the method of how paths are resolved. -(typename $lookupflags_t +(typename $lookupflags (flags u32 ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $LOOKUP_SYMLINK_FOLLOW + $symlink_follow ) ) ;;; Open flags used by `path_open`. -(typename $oflags_t +(typename $oflags (flags u16 ;;; Create file if it does not exist. - $O_CREAT + $creat ;;; Fail if not a directory. - $O_DIRECTORY + $directory ;;; Fail if file already exists. - $O_EXCL + $excl ;;; Truncate file to size 0. - $O_TRUNC + $trunc ) ) ;;; Number of hard links to an inode. -(typename $linkcount_t u64) +(typename $linkcount u64) ;;; File attributes. -(typename $filestat_t +(typename $filestat (struct ;;; Device ID of device containing the file. - (field $st_dev $device_t) + (field $dev $device) ;;; File serial number. - (field $st_ino $inode_t) + (field $ino $inode) ;;; File type. - (field $st_filetype $filetype_t) + (field $filetype $filetype) ;;; Number of hard links to the file. - (field $st_nlink $linkcount_t) + (field $nlink $linkcount) ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $st_size $filesize_t) + (field $size $filesize) ;;; Last data access timestamp. - (field $st_atim $timestamp_t) + (field $atim $timestamp) ;;; Last data modification timestamp. - (field $st_mtim $timestamp_t) + (field $mtim $timestamp) ;;; Last file status change timestamp. - (field $st_ctim $timestamp_t) + (field $ctim $timestamp) ) ) ;;; User-provided value that may be attached to objects that is retained when ;;; extracted from the implementation. -(typename $userdata_t u64) +(typename $userdata u64) ;;; Type of a subscription to an event or its occurrence. -(typename $eventtype_t +(typename $eventtype (enum u8 - ;;; The time value of clock `subscription_t::u.clock.clock_id` has - ;;; reached timestamp `subscription_t::u.clock.timeout`. - $EVENTTYPE_CLOCK - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; The time value of clock `subscription::u.clock.clock_id` has + ;;; reached timestamp `subscription::u.clock.timeout`. + $clock + ;;; File descriptor `subscription::u.fd_readwrite.fd` has data ;;; available for reading. This event always triggers for regular files. - $EVENTTYPE_FD_READ - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + $fd_read + ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity ;;; available for writing. This event always triggers for regular files. - $EVENTTYPE_FD_WRITE + $fd_write ) ) ;;; The state of the file descriptor subscribed to with -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $eventrwflags_t +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $eventrwflags (flags u16 ;;; The peer of this socket has closed or disconnected. - $EVENT_FD_READWRITE_HANGUP + $fd_readwrite_hangup ) ) -;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;;; `EVENTTYPE_FD_WRITE`. -(typename $event_fd_readwrite_t +;;; The contents of an $event when type is `eventtype::fd_read` or +;;; `eventtype::fd_write`. +(typename $event_fd_readwrite (struct ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) + (field $nbytes $filesize) ;;; The state of the file descriptor. - (field $flags $eventrwflags_t) + (field $flags $eventrwflags) ) ) -;;; The contents of an $event_t. +;;; The contents of an $event. (typename $event_u (union - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $event_fd_readwrite_t) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $event_fd_readwrite) ) ) ;;; An event that occurred. -(typename $event_t +(typename $event (struct - ;;; User-provided value that got attached to `subscription_t::userdata`. - (field $userdata $userdata_t) + ;;; User-provided value that got attached to `subscription::userdata`. + (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno_t) + (field $error $errno) ;;; The type of the event that occurred. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the event. (field $u $event_u) ) ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_t::u.clock.timeout.` -(typename $subclockflags_t +;;; `subscription::u.clock.timeout.` +(typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription_t::u.clock.timeout` relative to the - ;;; current time value of clock `subscription_t::u.clock.clock_id.` - $SUBSCRIPTION_CLOCK_ABSTIME + ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription::u.clock.timeout` relative to the + ;;; current time value of clock `subscription::u.clock.clock_id.` + $subscription_clock_abstime ) ) -;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. -(typename $subscription_clock_t +;;; The contents of a $subscription when type is `eventtype::clock`. +(typename $subscription_clock (struct ;;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) + (field $id $clockid) ;;; The absolute or relative timestamp. - (field $timeout $timestamp_t) + (field $timeout $timestamp) ;;; The amount of time that the implementation may wait additionally ;;; to coalesce with other events. - (field $precision $timestamp_t) + (field $precision $timestamp) ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags_t) + (field $flags $subclockflags) ) ) -;;; The contents of a $subscription_t when type is type is -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $subscription_fd_readwrite_t +;;; The contents of a $subscription when type is type is +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $subscription_fd_readwrite (struct ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) + (field $file_descriptor $fd) ) ) -;;; The contents of a $subscription_t. +;;; The contents of a $subscription. (typename $subscription_u (union - ;;; When type is `EVENTTYPE_CLOCK`: - (field $clock $subscription_clock_t) - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $subscription_fd_readwrite_t) + ;;; When type is `eventtype::clock`: + (field $clock $subscription_clock) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $subscription_fd_readwrite) ) ) ;;; Subscription to an event. -(typename $subscription_t +(typename $subscription (struct ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event_t::userdata`. - (field $userdata $userdata_t) + ;;; implementation and returned through `event::userdata`. + (field $userdata $userdata) ;;; The type of the event to which to subscribe. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the subscription. (field $u $subscription_u) ) ) ;;; Exit code generated by a process when exiting. -(typename $exitcode_t u32) +(typename $exitcode u32) ;;; Signal condition. -(typename $signal_t +(typename $signal (enum u8 ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. - $SIGNONE + $none ;;; Hangup. ;;; Action: Terminates the process. - $SIGHUP + $hup ;;; Terminate interrupt signal. ;;; Action: Terminates the process. - $SIGINT + $int ;;; Terminal quit signal. ;;; Action: Terminates the process. - $SIGQUIT + $quit ;;; Illegal instruction. ;;; Action: Terminates the process. - $SIGILL + $ill ;;; Trace/breakpoint trap. ;;; Action: Terminates the process. - $SIGTRAP + $trap ;;; Process abort signal. ;;; Action: Terminates the process. - $SIGABRT + $abrt ;;; Access to an undefined portion of a memory object. ;;; Action: Terminates the process. - $SIGBUS + $bus ;;; Erroneous arithmetic operation. ;;; Action: Terminates the process. - $SIGFPE + $fpe ;;; Kill. ;;; Action: Terminates the process. - $SIGKILL + $kill ;;; User-defined signal 1. ;;; Action: Terminates the process. - $SIGUSR1 + $usr1 ;;; Invalid memory reference. ;;; Action: Terminates the process. - $SIGSEGV + $segv ;;; User-defined signal 2. ;;; Action: Terminates the process. - $SIGUSR2 + $usr2 ;;; Write on a pipe with no one to read it. ;;; Action: Ignored. - $SIGPIPE + $pipe ;;; Alarm clock. ;;; Action: Terminates the process. - $SIGALRM + $alrm ;;; Termination signal. ;;; Action: Terminates the process. - $SIGTERM + $term ;;; Child process terminated, stopped, or continued. ;;; Action: Ignored. - $SIGCHLD + $chld ;;; Continue executing, if stopped. ;;; Action: Continues executing, if stopped. - $SIGCONT + $cont ;;; Stop executing. ;;; Action: Stops executing. - $SIGSTOP + $stop ;;; Terminal stop signal. ;;; Action: Stops executing. - $SIGTSTP + $tstp ;;; Background process attempting read. ;;; Action: Stops executing. - $SIGTTIN + $ttin ;;; Background process attempting write. ;;; Action: Stops executing. - $SIGTTOU + $ttou ;;; High bandwidth data is available at a socket. ;;; Action: Ignored. - $SIGURG + $urg ;;; CPU time limit exceeded. ;;; Action: Terminates the process. - $SIGXCPU + $xcpu ;;; File size limit exceeded. ;;; Action: Terminates the process. - $SIGXFSZ + $xfsz ;;; Virtual timer expired. ;;; Action: Terminates the process. - $SIGVTALRM + $vtalrm ;;; Profiling timer expired. ;;; Action: Terminates the process. - $SIGPROF + $prof ;;; Window changed. ;;; Action: Ignored. - $SIGWINCH + $winch ;;; I/O possible. ;;; Action: Terminates the process. - $SIGPOLL + $poll ;;; Power failure. ;;; Action: Terminates the process. - $SIGPWR + $pwr ;;; Bad system call. ;;; Action: Terminates the process. - $SIGSYS + $sys ) ) ;;; Flags provided to `sock_recv`. -(typename $riflags_t +(typename $riflags (flags u16 ;;; Returns the message without removing it from the socket's receive queue. - $SOCK_RECV_PEEK + $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. - $SOCK_RECV_WAITALL + $recv_waitall ) ) ;;; Flags returned by `sock_recv`. -(typename $roflags_t +(typename $roflags (flags u16 ;;; Returned by `sock_recv`: Message data has been truncated. - $SOCK_RECV_DATA_TRUNCATED + $recv_data_truncated ) ) ;;; Flags provided to `sock_send`. As there are currently no flags ;;; defined, it must be set to zero. -(typename $siflags_t u16) +(typename $siflags u16) ;;; Which channels on a socket to shut down. -(typename $sdflags_t +(typename $sdflags (flags u8 ;;; Disables further receive operations. - $SHUT_RD + $rd ;;; Disables further send operations. - $SHUT_WR + $wr ) ) ;;; Identifiers for preopened capabilities. -(typename $preopentype_t +(typename $preopentype (enum u8 ;;; A pre-opened directory. - $PREOPENTYPE_DIR + $dir ) ) -;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size_t) + (field $pr_name_len $size) ) ) -;;; The contents of an $prestat_t. +;;; The contents of an $prestat. (typename $prestat_u (union - ;;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `preopentype::dir`: (field $dir $prestat_dir) ) ) ;;; Information about a pre-opened capability. -(typename $prestat_t +(typename $prestat (struct ;;; The type of the pre-opened capability. - (field $pr_type $preopentype_t) + (field $pr_type $preopentype) ;;; The contents of the information. (field $u $prestat_u) ) diff --git a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx index e69b788dc..44a297b8c 100644 --- a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -17,15 +17,15 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Read environment variable data. @@ -33,187 +33,187 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Return the resolution of a clock. ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno_t) + (result $error $errno) ;;; The clock for which to return the resolution. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The resolution of the clock. - (result $resolution $timestamp_t) + (result $resolution $timestamp) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") ;;; The clock for which to return the time. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp_t) - (result $error $errno_t) + (param $precision $timestamp) + (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp_t) + (result $time $timestamp) ) ;;; Provide file advisory information on a file descriptor. ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset within the file to which the advisory applies. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the region to which the advisory applies. - (param $len $filesize_t) + (param $len $filesize) ;;; The advice. - (param $advice $advice_t) - (result $error $errno_t) + (param $advice $advice) + (result $error $errno) ) ;;; Force the allocation of space in a file. ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset at which to start the allocation. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the area that is allocated. - (param $len $filesize_t) - (result $error $errno_t) + (param $len $filesize) + (result $error $errno) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat_t) + (result $stat $fdstat) ) ;;; Adjust the flags associated with a file descriptor. ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the file descriptor flags. - (param $flags $fdflags_t) - (result $error $errno_t) + (param $flags $fdflags) + (result $error $errno) ) ;;; Adjust the rights associated with a file descriptor. ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights_t) - (param $fs_rights_inheriting $rights_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inheriting $rights) + (result $error $errno) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired file size. - (param $st_size $filesize_t) - (result $error $errno_t) + (param $size $filesize) + (result $error $errno) ) ;;; Adjust the timestamps of an open file or directory. ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_t_array) + (param $iovs $iovec_array) ;;; The offset within the file at which to read. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat_t) + (result $buf $prestat) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") - (param $fd $fd_t) + (param $fd $fd) ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) - (param $path_len $size_t) - (result $error $errno_t) + (param $path_len $size) + (result $error $errno) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) + (param $iovs $ciovec_array) ;;; The offset within the file at which to write. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Read from a file descriptor. ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_t_array) - (result $error $errno_t) + (param $iovs $iovec_array) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Read directory entries from a directory. @@ -227,15 +227,15 @@ ;;; read buffer size in case it's too small to fit a single large directory ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") - (param $fd $fd_t) + (param $fd $fd) ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) - (param $buf_len $size_t) + (param $buf_len $size) ;;; The location within the directory to start reading - (param $cookie $dircookie_t) - (result $error $errno_t) + (param $cookie $dircookie) + (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -249,104 +249,104 @@ ;;; This function provides a way to atomically renumber file descriptors, which ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") - (param $fd $fd_t) + (param $fd $fd) ;;; The file descriptor to overwrite. - (param $to $fd_t) - (result $error $errno_t) + (param $to $fd) + (result $error $errno) ) ;;; Move the offset of a file descriptor. ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") - (param $fd $fd_t) + (param $fd $fd) ;;; The number of bytes to move. - (param $offset $filedelta_t) + (param $offset $filedelta) ;;; The base from which the offset is relative. - (param $whence $whence_t) - (result $error $errno_t) + (param $whence $whence) + (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize_t) + (result $newoffset $filesize) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize_t) + (result $offset $filesize) ) ;;; Write to a file descriptor. ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) - (result $error $errno_t) + (param $iovs $ciovec_array) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Create a directory. ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Return the attributes of a file or directory. ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno_t) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the timestamps of a file or directory. ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to operate on. (param $path string) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Create a hard link. ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $old_fd $fd_t) + (param $old_fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags_t) + (param $old_flags $lookupflags) ;;; The source path from which to link. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Open a file or directory. @@ -359,14 +359,14 @@ ;; ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags_t) + (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the ;;; `dirfd` directory. (param $path string) ;;; The method by which to open the file. - (param $o_flags $oflags_t) + (param $oflags $oflags) ;;; The initial rights of the newly created file descriptor. The ;;; implementation is allowed to return a file descriptor with fewer rights ;;; than specified, if and only if those rights do not apply to the type of @@ -375,49 +375,49 @@ ;;; The *base* rights are rights that will apply to operations using the file ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. - (param $fs_rights_base $rights_t) - (param $fs_rights_inherting $rights_t) - (param $flags $fdflags_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inherting $rights) + (param $fdflags $fdflags) + (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd_t) + (result $opened_fd $fd) ) ;;; Read the contents of a symbolic link. ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") - (param $fd $fd_t) + (param $fd $fd) ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Remove a directory. ;;; Return `ENOTEMPTY` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Rename a file or directory. ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") - (param $fd $fd_t) + (param $fd $fd) ;;; The source path of the file or directory to rename. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Create a symbolic link. @@ -425,10 +425,10 @@ (@interface func (export "path_symlink") ;;; The contents of the symbolic link. (param $old_path string) - (param $fd $fd_t) + (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) @@ -436,23 +436,23 @@ ;;; Return `EISDIR` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription_t)) + (param $in (@witx const_pointer $subscription)) ;;; The events that have occurred. - (param $out (@witx pointer $event_t)) + (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size_t) - (result $error $errno_t) + (param $nsubscriptions $size) + (result $error $errno) ;;; The number of events stored. - (result $nevents $size_t) + (result $nevents $size) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -460,21 +460,21 @@ ;;; the environment. (@interface func (export "proc_exit") ;;; The exit code returned by the process. - (param $rval $exitcode_t) + (param $rval $exitcode) ) ;;; Send a signal to the process of the calling thread. ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") ;;; The signal condition to trigger. - (param $sig $signal_t) - (result $error $errno_t) + (param $sig $signal) + (result $error $errno) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno_t) + (result $error $errno) ) ;;; Write high-quality random data into a buffer. @@ -486,46 +486,46 @@ (@interface func (export "random_get") ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ) ;;; Receive a message from a socket. ;;; Note: This is similar to `recv` in POSIX, though it also supports reading ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_t_array) + (param $ri_data $iovec_array) ;;; Message flags. - (param $ri_flags $riflags_t) - (result $error $errno_t) + (param $ri_flags $riflags) + (result $error $errno) ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size_t) + (result $ro_datalen $size) ;;; Message flags. - (result $ro_flags $roflags_t) + (result $ro_flags $roflags) ) ;;; Send a message on a socket. ;;; Note: This is similar to `send` in POSIX, though it also supports writing ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_t_array) + (param $si_data $ciovec_array) ;;; Message flags. - (param $si_flags $siflags_t) - (result $error $errno_t) + (param $si_flags $siflags) + (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size_t) + (result $so_datalen $size) ) ;;; Shut down socket send and receive channels. ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") - (param $fd $fd_t) + (param $fd $fd) ;;; Which channels on the socket to shut down. - (param $how $sdflags_t) - (result $error $errno_t) + (param $how $sdflags) + (result $error $errno) ) ) diff --git a/proposals/clocks/tools/witx/tests/wasi.rs b/proposals/clocks/tools/witx/tests/wasi.rs index aef954236..938c78067 100644 --- a/proposals/clocks/tools/witx/tests/wasi.rs +++ b/proposals/clocks/tools/witx/tests/wasi.rs @@ -25,11 +25,6 @@ fn render_roundtrip() { let back_to_sexprs = format!("{}", doc); println!("{}", back_to_sexprs); - let doc2 = witx::parse(&back_to_sexprs) - .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) - .unwrap(); - - let back_to_sexprs = format!("{}", doc); let doc2 = witx::parse(&back_to_sexprs) .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) From 96d51eba58eadecb4323858910d6f20c78347c4b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 17:15:57 -0800 Subject: [PATCH 0296/1772] Mechanical witx naming convention changes (#137) * witx: drop trailing `_t` from all typenames this suffix is not appropriate for all languages that may need to generate code from witx, so this change removes it from all witx files and leaves the code generator in charge of putting the appropriate suffix onto any type names it produces. sed -i -E 's/\$([a-z_]+)_t([)\n\r ])?/\$\1\2/g' **/*.witx * witx: change identifiers to snake case Change all $SHOUTY_SNAKE_CASE identifers to $snake_case. It is the responsibility of a code generator backend to select the right case and style of these identifiers for the target language. In witx, we should standardize on snake case (lowercase with a single underscore as a word separator) sed -i -E 's/\$([A-Z0-9_]+)([)\n\r ])?/\$\L\1\2/g' **/*.witx * witx: mechanically remove repeated prefixes from flags, enums once again, the code translation tool is responsible for putting the right prefix in the generated code. languages with proper namespacing facilities don't need the identifiers themselves to be namespaced. otherwise, you can derive the namespacing prefix from the type name. sed -i -E 's/\$(clock_|right_|whence_|filetype_|advice_|fdflag_|filestat_set_|lookup_|o_|st_|sock_|shut_|preopentype_)/\$/g' **/*.witx * restore fields named pr_type and d_type * remove $event_ prefix from eventrwflags member doing so by regexp would delete various other valid event_ prefixes * remove eventtype_ prefix from enum fields this one could have been mechanical, but i left it out of the regexp * restore oflags, fdflags argument names in path_open * witx: delete leading `sig` from each $signal enum variant * witx: delete leading `e` from each $errno enum variant * fixup test * witx: fix up old style names in comments --- .../phases/ephemeral/witx/typenames.witx | 608 +++++++++--------- .../witx/wasi_ephemeral_preview.witx | 306 ++++----- .../phases/old/snapshot_0/witx/typenames.witx | 604 ++++++++--------- .../old/snapshot_0/witx/wasi_unstable.witx | 306 ++++----- .../phases/snapshot/witx/typenames.witx | 608 +++++++++--------- .../snapshot/witx/wasi_snapshot_preview1.witx | 306 ++++----- proposals/random/tools/witx/tests/wasi.rs | 5 - 7 files changed, 1369 insertions(+), 1374 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index a614d8528..00ae3d15e 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -5,29 +5,29 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(typename $size_t u32) +(typename $size u32) ;;; Non-negative file size or length of a region within a file. -(typename $filesize_t u64) +(typename $filesize u64) ;;; Timestamp in nanoseconds. -(typename $timestamp_t u64) +(typename $timestamp u64) ;;; Identifiers for clocks. -(typename $clockid_t +(typename $clockid (enum u32 ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME + $realtime ;;; The store-wide monotonic clock, which is defined as a clock measuring ;;; real time, whose value cannot be adjusted and which cannot have negative ;;; clock jumps. The epoch of this clock is undefined. The absolute time ;;; value of this clock therefore has no meaning. - $CLOCK_MONOTONIC + $monotonic ;;; The CPU-time clock associated with the current process. - $CLOCK_PROCESS_CPUTIME_ID + $process_cputime_id ;;; The CPU-time clock associated with the current thread. - $CLOCK_THREAD_CPUTIME_ID + $thread_cputime_id ) ) @@ -35,732 +35,732 @@ ;;; Not all of these error codes are returned by the functions provided by this ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. -(typename $errno_t +(typename $errno (enum u16 ;;; No error occurred. System call completed successfully. - $ESUCCESS + $success ;;; Argument list too long. - $E2BIG + $2big ;;; Permission denied. - $EACCES + $acces ;;; Address in use. - $EADDRINUSE + $addrinuse ;;; Address not available. - $EADDRNOTAVAIL + $addrnotavail ;;; Address family not supported. - $EAFNOSUPPORT + $afnosupport ;;; Resource unavailable, or operation would block. - $EAGAIN + $again ;;; Connection already in progress. - $EALREADY + $already ;;; Bad file descriptor. - $EBADF + $badf ;;; Bad message. - $EBADMSG + $badmsg ;;; Device or resource busy. - $EBUSY + $busy ;;; Operation canceled. - $ECANCELED + $canceled ;;; No child processes. - $ECHILD + $child ;;; Connection aborted. - $ECONNABORTED + $connaborted ;;; Connection refused. - $ECONNREFUSED + $connrefused ;;; Connection reset. - $ECONNRESET + $connreset ;;; Resource deadlock would occur. - $EDEADLK + $deadlk ;;; Destination address required. - $EDESTADDRREQ + $destaddrreq ;;; Mathematics argument out of domain of function. - $EDOM + $dom ;;; Reserved. - $EDQUOT + $dquot ;;; File exists. - $EEXIST + $exist ;;; Bad address. - $EFAULT + $fault ;;; File too large. - $EFBIG + $fbig ;;; Host is unreachable. - $EHOSTUNREACH + $hostunreach ;;; Identifier removed. - $EIDRM + $idrm ;;; Illegal byte sequence. - $EILSEQ + $ilseq ;;; Operation in progress. - $EINPROGRESS + $inprogress ;;; Interrupted function. - $EINTR + $intr ;;; Invalid argument. - $EINVAL + $inval ;;; I/O error. - $EIO + $io ;;; Socket is connected. - $EISCONN + $isconn ;;; Is a directory. - $EISDIR + $isdir ;;; Too many levels of symbolic links. - $ELOOP + $loop ;;; File descriptor value too large. - $EMFILE + $mfile ;;; Too many links. - $EMLINK + $mlink ;;; Message too large. - $EMSGSIZE + $msgsize ;;; Reserved. - $EMULTIHOP + $multihop ;;; Filename too long. - $ENAMETOOLONG + $nametoolong ;;; Network is down. - $ENETDOWN + $netdown ;;; Connection aborted by network. - $ENETRESET + $netreset ;;; Network unreachable. - $ENETUNREACH + $netunreach ;;; Too many files open in system. - $ENFILE + $nfile ;;; No buffer space available. - $ENOBUFS + $nobufs ;;; No such device. - $ENODEV + $nodev ;;; No such file or directory. - $ENOENT + $noent ;;; Executable file format error. - $ENOEXEC + $noexec ;;; No locks available. - $ENOLCK + $nolck ;;; Reserved. - $ENOLINK + $nolink ;;; Not enough space. - $ENOMEM + $nomem ;;; No message of the desired type. - $ENOMSG + $nomsg ;;; Protocol not available. - $ENOPROTOOPT + $noprotoopt ;;; No space left on device. - $ENOSPC + $nospc ;;; Function not supported. - $ENOSYS + $nosys ;;; The socket is not connected. - $ENOTCONN + $notconn ;;; Not a directory or a symbolic link to a directory. - $ENOTDIR + $notdir ;;; Directory not empty. - $ENOTEMPTY + $notempty ;;; State not recoverable. - $ENOTRECOVERABLE + $notrecoverable ;;; Not a socket. - $ENOTSOCK + $notsock ;;; Not supported, or operation not supported on socket. - $ENOTSUP + $notsup ;;; Inappropriate I/O control operation. - $ENOTTY + $notty ;;; No such device or address. - $ENXIO + $nxio ;;; Value too large to be stored in data type. - $EOVERFLOW + $overflow ;;; Previous owner died. - $EOWNERDEAD + $ownerdead ;;; Operation not permitted. - $EPERM + $perm ;;; Broken pipe. - $EPIPE + $pipe ;;; Protocol error. - $EPROTO + $proto ;;; Protocol not supported. - $EPROTONOSUPPORT + $protonosupport ;;; Protocol wrong type for socket. - $EPROTOTYPE + $prototype ;;; Result too large. - $ERANGE + $range ;;; Read-only file system. - $EROFS + $rofs ;;; Invalid seek. - $ESPIPE + $spipe ;;; No such process. - $ESRCH + $srch ;;; Reserved. - $ESTALE + $stale ;;; Connection timed out. - $ETIMEDOUT + $timedout ;;; Text file busy. - $ETXTBSY + $txtbsy ;;; Cross-device link. - $EXDEV + $xdev ;;; Extension: Capabilities insufficient. - $ENOTCAPABLE + $notcapable ) ) ;;; File descriptor rights, determining which actions may be performed. -(typename $rights_t +(typename $rights (flags u64 ;;; The right to invoke `fd_datasync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_DSYNC`. - $RIGHT_FD_DATASYNC + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflag::dsync`. + $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - $RIGHT_FD_READ - ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - $RIGHT_FD_SEEK + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. + $fd_read + ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. + $fd_seek ;;; The right to invoke `fd_fdstat_set_flags`. - $RIGHT_FD_FDSTAT_SET_FLAGS + $fd_fdstat_set_flags ;;; The right to invoke `fd_sync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - $RIGHT_FD_SYNC + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflag::rsync` and `fdflag::dsync`. + $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;;; invoke `fd_tell`. - $RIGHT_FD_TELL + $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - $RIGHT_FD_WRITE + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. + $fd_write ;;; The right to invoke `fd_advise`. - $RIGHT_FD_ADVISE + $fd_advise ;;; The right to invoke `fd_allocate`. - $RIGHT_FD_ALLOCATE + $fd_allocate ;;; The right to invoke `path_create_directory`. - $RIGHT_PATH_CREATE_DIRECTORY - ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - $RIGHT_PATH_CREATE_FILE + $path_create_directory + ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::creat`. + $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. - $RIGHT_PATH_LINK_SOURCE + $path_link_source ;;; The right to invoke `path_link` with the file descriptor as the ;;; target directory. - $RIGHT_PATH_LINK_TARGET + $path_link_target ;;; The right to invoke `path_open`. - $RIGHT_PATH_OPEN + $path_open ;;; The right to invoke `fd_readdir`. - $RIGHT_FD_READDIR + $fd_readdir ;;; The right to invoke `path_readlink`. - $RIGHT_PATH_READLINK + $path_readlink ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $RIGHT_PATH_RENAME_SOURCE + $path_rename_source ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $RIGHT_PATH_RENAME_TARGET + $path_rename_target ;;; The right to invoke `path_filestat_get`. - $RIGHT_PATH_FILESTAT_GET + $path_filestat_get ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - $RIGHT_PATH_FILESTAT_SET_SIZE + ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. + $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. - $RIGHT_PATH_FILESTAT_SET_TIMES + $path_filestat_set_times ;;; The right to invoke `fd_filestat_get`. - $RIGHT_FD_FILESTAT_GET + $fd_filestat_get ;;; The right to invoke `fd_filestat_set_size`. - $RIGHT_FD_FILESTAT_SET_SIZE + $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. - $RIGHT_FD_FILESTAT_SET_TIMES + $fd_filestat_set_times ;;; The right to invoke `path_symlink`. - $RIGHT_PATH_SYMLINK + $path_symlink ;;; The right to invoke `path_remove_directory`. - $RIGHT_PATH_REMOVE_DIRECTORY + $path_remove_directory ;;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE - ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - $RIGHT_POLL_FD_READWRITE + $path_unlink_file + ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. + ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. + $poll_fd_readwrite ;;; The right to invoke `sock_shutdown`. - $RIGHT_SOCK_SHUTDOWN + $sock_shutdown ) ) ;;; A file descriptor index. -(typename $fd_t u32) +(typename $fd u32) ;;; A region of memory for scatter/gather reads. -(typename $iovec_t +(typename $iovec (struct ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. - (field $buf_len $size_t) + (field $buf_len $size) ) ) ;;; A region of memory for scatter/gather writes. -(typename $ciovec_t +(typename $ciovec (struct ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. - (field $buf_len $size_t) + (field $buf_len $size) ) ) -(typename $iovec_t_array (array $iovec_t)) -(typename $ciovec_t_array (array $ciovec_t)) +(typename $iovec_array (array $iovec)) +(typename $ciovec_array (array $ciovec)) ;;; Relative offset within a file. -(typename $filedelta_t s64) +(typename $filedelta s64) ;;; The position relative to which to set the offset of the file descriptor. -(typename $whence_t +(typename $whence (enum u8 ;;; Seek relative to start-of-file. - $WHENCE_SET + $set ;;; Seek relative to current position. - $WHENCE_CUR + $cur ;;; Seek relative to end-of-file. - $WHENCE_END + $end ) ) ;;; A reference to the offset of a directory entry. ;; ;;; The value 0 signifies the start of the directory. -(typename $dircookie_t u64) +(typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent_t. -(typename $dirnamlen_t u32) +;;; The type for the $d_namlen field of $dirent. +(typename $dirnamlen u32) ;;; File serial number that is unique within its file system. -(typename $inode_t u64) +(typename $inode u64) ;;; The type of a file descriptor or file. -(typename $filetype_t +(typename $filetype (enum u8 ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $FILETYPE_UNKNOWN + $unknown ;;; The file descriptor or file refers to a block device inode. - $FILETYPE_BLOCK_DEVICE + $block_device ;;; The file descriptor or file refers to a character device inode. - $FILETYPE_CHARACTER_DEVICE + $character_device ;;; The file descriptor or file refers to a directory inode. - $FILETYPE_DIRECTORY + $directory ;;; The file descriptor or file refers to a regular file inode. - $FILETYPE_REGULAR_FILE + $regular_file ;;; The file descriptor or file refers to a datagram socket. - $FILETYPE_SOCKET_DGRAM + $socket_dgram ;;; The file descriptor or file refers to a byte-stream socket. - $FILETYPE_SOCKET_STREAM + $socket_stream ;;; The file refers to a symbolic link inode. - $FILETYPE_SYMBOLIC_LINK + $symbolic_link ) ) ;;; A directory entry. -(typename $dirent_t +(typename $dirent (struct ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie_t) + (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode_t) + (field $d_ino $inode) ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen_t) + (field $d_namlen $dirnamlen) ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype_t) + (field $d_type $filetype) ) ) ;;; File or memory access pattern advisory information. -(typename $advice_t +(typename $advice (enum u8 ;;; The application has no advice to give on its behavior with respect to the specified data. - $ADVICE_NORMAL + $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $ADVICE_SEQUENTIAL + $sequential ;;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM + $random ;;; The application expects to access the specified data in the near future. - $ADVICE_WILLNEED + $willneed ;;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED + $dontneed ;;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE + $noreuse ) ) ;;; File descriptor flags. -(typename $fdflags_t +(typename $fdflags (flags u16 ;;; Append mode: Data written to the file is always appended to the file's end. - $FDFLAG_APPEND + $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $FDFLAG_DSYNC + $dsync ;;; Non-blocking mode. - $FDFLAG_NONBLOCK + $nonblock ;;; Synchronized read I/O operations. - $FDFLAG_RSYNC + $rsync ;;; Write according to synchronized I/O file integrity completion. In ;;; addition to synchronizing the data stored in the file, the implementation ;;; may also synchronously update the file's metadata. - $FDFLAG_SYNC + $sync ) ) ;;; File descriptor attributes. -(typename $fdstat_t +(typename $fdstat (struct ;;; File type. - (field $fs_filetype $filetype_t) + (field $fs_filetype $filetype) ;;; File descriptor flags. - (field $fs_flags $fdflags_t) + (field $fs_flags $fdflags) ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights_t) + (field $fs_rights_base $rights) ;;; Maximum set of rights that may be installed on new file descriptors that ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights_t) + (field $fs_rights_inheriting $rights) ) ) ;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode_t` to uniquely identify a file or directory in the filesystem. -(typename $device_t u64) +;;; with `inode` to uniquely identify a file or directory in the filesystem. +(typename $device u64) ;;; Which file time attributes to adjust. -(typename $fstflags_t +(typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - $FILESTAT_SET_ATIM - ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_ATIM_NOW - ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - $FILESTAT_SET_MTIM - ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_MTIM_NOW + ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + $atim + ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + $atim_now + ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + $mtim + ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + $mtim_now ) ) ;;; Flags determining the method of how paths are resolved. -(typename $lookupflags_t +(typename $lookupflags (flags u32 ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $LOOKUP_SYMLINK_FOLLOW + $symlink_follow ) ) ;;; Open flags used by `path_open`. -(typename $oflags_t +(typename $oflags (flags u16 ;;; Create file if it does not exist. - $O_CREAT + $creat ;;; Fail if not a directory. - $O_DIRECTORY + $directory ;;; Fail if file already exists. - $O_EXCL + $excl ;;; Truncate file to size 0. - $O_TRUNC + $trunc ) ) ;;; Number of hard links to an inode. -(typename $linkcount_t u64) +(typename $linkcount u64) ;;; File attributes. -(typename $filestat_t +(typename $filestat (struct ;;; Device ID of device containing the file. - (field $st_dev $device_t) + (field $dev $device) ;;; File serial number. - (field $st_ino $inode_t) + (field $ino $inode) ;;; File type. - (field $st_filetype $filetype_t) + (field $filetype $filetype) ;;; Number of hard links to the file. - (field $st_nlink $linkcount_t) + (field $nlink $linkcount) ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $st_size $filesize_t) + (field $size $filesize) ;;; Last data access timestamp. - (field $st_atim $timestamp_t) + (field $atim $timestamp) ;;; Last data modification timestamp. - (field $st_mtim $timestamp_t) + (field $mtim $timestamp) ;;; Last file status change timestamp. - (field $st_ctim $timestamp_t) + (field $ctim $timestamp) ) ) ;;; User-provided value that may be attached to objects that is retained when ;;; extracted from the implementation. -(typename $userdata_t u64) +(typename $userdata u64) ;;; Type of a subscription to an event or its occurrence. -(typename $eventtype_t +(typename $eventtype (enum u8 - ;;; The time value of clock `subscription_t::u.clock.clock_id` has - ;;; reached timestamp `subscription_t::u.clock.timeout`. - $EVENTTYPE_CLOCK - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; The time value of clock `subscription::u.clock.clock_id` has + ;;; reached timestamp `subscription::u.clock.timeout`. + $clock + ;;; File descriptor `subscription::u.fd_readwrite.fd` has data ;;; available for reading. This event always triggers for regular files. - $EVENTTYPE_FD_READ - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + $fd_read + ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity ;;; available for writing. This event always triggers for regular files. - $EVENTTYPE_FD_WRITE + $fd_write ) ) ;;; The state of the file descriptor subscribed to with -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $eventrwflags_t +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $eventrwflags (flags u16 ;;; The peer of this socket has closed or disconnected. - $EVENT_FD_READWRITE_HANGUP + $fd_readwrite_hangup ) ) -;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;;; `EVENTTYPE_FD_WRITE`. -(typename $event_fd_readwrite_t +;;; The contents of an $event when type is `eventtype::fd_read` or +;;; `eventtype::fd_write`. +(typename $event_fd_readwrite (struct ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) + (field $nbytes $filesize) ;;; The state of the file descriptor. - (field $flags $eventrwflags_t) + (field $flags $eventrwflags) ) ) -;;; The contents of an $event_t. +;;; The contents of an $event. (typename $event_u (union - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $event_fd_readwrite_t) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $event_fd_readwrite) ) ) ;;; An event that occurred. -(typename $event_t +(typename $event (struct - ;;; User-provided value that got attached to `subscription_t::userdata`. - (field $userdata $userdata_t) + ;;; User-provided value that got attached to `subscription::userdata`. + (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno_t) + (field $error $errno) ;;; The type of the event that occurred. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the event. (field $u $event_u) ) ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_t::u.clock.timeout.` -(typename $subclockflags_t +;;; `subscription::u.clock.timeout.` +(typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription_t::u.clock.timeout` relative to the - ;;; current time value of clock `subscription_t::u.clock.clock_id.` - $SUBSCRIPTION_CLOCK_ABSTIME + ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription::u.clock.timeout` relative to the + ;;; current time value of clock `subscription::u.clock.clock_id.` + $subscription_clock_abstime ) ) -;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. -(typename $subscription_clock_t +;;; The contents of a $subscription when type is `eventtype::clock`. +(typename $subscription_clock (struct ;;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) + (field $id $clockid) ;;; The absolute or relative timestamp. - (field $timeout $timestamp_t) + (field $timeout $timestamp) ;;; The amount of time that the implementation may wait additionally ;;; to coalesce with other events. - (field $precision $timestamp_t) + (field $precision $timestamp) ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags_t) + (field $flags $subclockflags) ) ) -;;; The contents of a $subscription_t when type is type is -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $subscription_fd_readwrite_t +;;; The contents of a $subscription when type is type is +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $subscription_fd_readwrite (struct ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) + (field $file_descriptor $fd) ) ) -;;; The contents of a $subscription_t. +;;; The contents of a $subscription. (typename $subscription_u (union - ;;; When type is `EVENTTYPE_CLOCK`: - (field $clock $subscription_clock_t) - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $subscription_fd_readwrite_t) + ;;; When type is `eventtype::clock`: + (field $clock $subscription_clock) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $subscription_fd_readwrite) ) ) ;;; Subscription to an event. -(typename $subscription_t +(typename $subscription (struct ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event_t::userdata`. - (field $userdata $userdata_t) + ;;; implementation and returned through `event::userdata`. + (field $userdata $userdata) ;;; The type of the event to which to subscribe. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the subscription. (field $u $subscription_u) ) ) ;;; Exit code generated by a process when exiting. -(typename $exitcode_t u32) +(typename $exitcode u32) ;;; Signal condition. -(typename $signal_t +(typename $signal (enum u8 ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. - $SIGNONE + $none ;;; Hangup. ;;; Action: Terminates the process. - $SIGHUP + $hup ;;; Terminate interrupt signal. ;;; Action: Terminates the process. - $SIGINT + $int ;;; Terminal quit signal. ;;; Action: Terminates the process. - $SIGQUIT + $quit ;;; Illegal instruction. ;;; Action: Terminates the process. - $SIGILL + $ill ;;; Trace/breakpoint trap. ;;; Action: Terminates the process. - $SIGTRAP + $trap ;;; Process abort signal. ;;; Action: Terminates the process. - $SIGABRT + $abrt ;;; Access to an undefined portion of a memory object. ;;; Action: Terminates the process. - $SIGBUS + $bus ;;; Erroneous arithmetic operation. ;;; Action: Terminates the process. - $SIGFPE + $fpe ;;; Kill. ;;; Action: Terminates the process. - $SIGKILL + $kill ;;; User-defined signal 1. ;;; Action: Terminates the process. - $SIGUSR1 + $usr1 ;;; Invalid memory reference. ;;; Action: Terminates the process. - $SIGSEGV + $segv ;;; User-defined signal 2. ;;; Action: Terminates the process. - $SIGUSR2 + $usr2 ;;; Write on a pipe with no one to read it. ;;; Action: Ignored. - $SIGPIPE + $pipe ;;; Alarm clock. ;;; Action: Terminates the process. - $SIGALRM + $alrm ;;; Termination signal. ;;; Action: Terminates the process. - $SIGTERM + $term ;;; Child process terminated, stopped, or continued. ;;; Action: Ignored. - $SIGCHLD + $chld ;;; Continue executing, if stopped. ;;; Action: Continues executing, if stopped. - $SIGCONT + $cont ;;; Stop executing. ;;; Action: Stops executing. - $SIGSTOP + $stop ;;; Terminal stop signal. ;;; Action: Stops executing. - $SIGTSTP + $tstp ;;; Background process attempting read. ;;; Action: Stops executing. - $SIGTTIN + $ttin ;;; Background process attempting write. ;;; Action: Stops executing. - $SIGTTOU + $ttou ;;; High bandwidth data is available at a socket. ;;; Action: Ignored. - $SIGURG + $urg ;;; CPU time limit exceeded. ;;; Action: Terminates the process. - $SIGXCPU + $xcpu ;;; File size limit exceeded. ;;; Action: Terminates the process. - $SIGXFSZ + $xfsz ;;; Virtual timer expired. ;;; Action: Terminates the process. - $SIGVTALRM + $vtalrm ;;; Profiling timer expired. ;;; Action: Terminates the process. - $SIGPROF + $prof ;;; Window changed. ;;; Action: Ignored. - $SIGWINCH + $winch ;;; I/O possible. ;;; Action: Terminates the process. - $SIGPOLL + $poll ;;; Power failure. ;;; Action: Terminates the process. - $SIGPWR + $pwr ;;; Bad system call. ;;; Action: Terminates the process. - $SIGSYS + $sys ) ) ;;; Flags provided to `sock_recv`. -(typename $riflags_t +(typename $riflags (flags u16 ;;; Returns the message without removing it from the socket's receive queue. - $SOCK_RECV_PEEK + $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. - $SOCK_RECV_WAITALL + $recv_waitall ) ) ;;; Flags returned by `sock_recv`. -(typename $roflags_t +(typename $roflags (flags u16 ;;; Returned by `sock_recv`: Message data has been truncated. - $SOCK_RECV_DATA_TRUNCATED + $recv_data_truncated ) ) ;;; Flags provided to `sock_send`. As there are currently no flags ;;; defined, it must be set to zero. -(typename $siflags_t u16) +(typename $siflags u16) ;;; Which channels on a socket to shut down. -(typename $sdflags_t +(typename $sdflags (flags u8 ;;; Disables further receive operations. - $SHUT_RD + $rd ;;; Disables further send operations. - $SHUT_WR + $wr ) ) ;;; Identifiers for preopened capabilities. -(typename $preopentype_t +(typename $preopentype (enum u8 ;;; A pre-opened directory. - $PREOPENTYPE_DIR + $dir ) ) -;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size_t) + (field $pr_name_len $size) ) ) -;;; The contents of an $prestat_t. +;;; The contents of an $prestat. (typename $prestat_u (union - ;;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `preopentype::dir`: (field $dir $prestat_dir) ) ) ;;; Information about a pre-opened capability. -(typename $prestat_t +(typename $prestat (struct ;;; The type of the pre-opened capability. - (field $pr_type $preopentype_t) + (field $pr_type $preopentype) ;;; The contents of the information. (field $u $prestat_u) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx index d15b8c514..43bd57e4b 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -17,15 +17,15 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Read environment variable data. @@ -33,187 +33,187 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Return the resolution of a clock. ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno_t) + (result $error $errno) ;;; The clock for which to return the resolution. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The resolution of the clock. - (result $resolution $timestamp_t) + (result $resolution $timestamp) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") ;;; The clock for which to return the time. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp_t) - (result $error $errno_t) + (param $precision $timestamp) + (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp_t) + (result $time $timestamp) ) ;;; Provide file advisory information on a file descriptor. ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset within the file to which the advisory applies. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the region to which the advisory applies. - (param $len $filesize_t) + (param $len $filesize) ;;; The advice. - (param $advice $advice_t) - (result $error $errno_t) + (param $advice $advice) + (result $error $errno) ) ;;; Force the allocation of space in a file. ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset at which to start the allocation. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the area that is allocated. - (param $len $filesize_t) - (result $error $errno_t) + (param $len $filesize) + (result $error $errno) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat_t) + (result $stat $fdstat) ) ;;; Adjust the flags associated with a file descriptor. ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the file descriptor flags. - (param $flags $fdflags_t) - (result $error $errno_t) + (param $flags $fdflags) + (result $error $errno) ) ;;; Adjust the rights associated with a file descriptor. ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights_t) - (param $fs_rights_inheriting $rights_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inheriting $rights) + (result $error $errno) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired file size. - (param $st_size $filesize_t) - (result $error $errno_t) + (param $size $filesize) + (result $error $errno) ) ;;; Adjust the timestamps of an open file or directory. ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_t_array) + (param $iovs $iovec_array) ;;; The offset within the file at which to read. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat_t) + (result $buf $prestat) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") - (param $fd $fd_t) + (param $fd $fd) ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) - (param $path_len $size_t) - (result $error $errno_t) + (param $path_len $size) + (result $error $errno) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) + (param $iovs $ciovec_array) ;;; The offset within the file at which to write. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Read from a file descriptor. ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_t_array) - (result $error $errno_t) + (param $iovs $iovec_array) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Read directory entries from a directory. @@ -227,15 +227,15 @@ ;;; read buffer size in case it's too small to fit a single large directory ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") - (param $fd $fd_t) + (param $fd $fd) ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) - (param $buf_len $size_t) + (param $buf_len $size) ;;; The location within the directory to start reading - (param $cookie $dircookie_t) - (result $error $errno_t) + (param $cookie $dircookie) + (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -249,104 +249,104 @@ ;;; This function provides a way to atomically renumber file descriptors, which ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") - (param $fd $fd_t) + (param $fd $fd) ;;; The file descriptor to overwrite. - (param $to $fd_t) - (result $error $errno_t) + (param $to $fd) + (result $error $errno) ) ;;; Move the offset of a file descriptor. ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") - (param $fd $fd_t) + (param $fd $fd) ;;; The number of bytes to move. - (param $offset $filedelta_t) + (param $offset $filedelta) ;;; The base from which the offset is relative. - (param $whence $whence_t) - (result $error $errno_t) + (param $whence $whence) + (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize_t) + (result $newoffset $filesize) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize_t) + (result $offset $filesize) ) ;;; Write to a file descriptor. ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) - (result $error $errno_t) + (param $iovs $ciovec_array) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Create a directory. ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Return the attributes of a file or directory. ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno_t) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the timestamps of a file or directory. ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to operate on. (param $path string) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Create a hard link. ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $old_fd $fd_t) + (param $old_fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags_t) + (param $old_flags $lookupflags) ;;; The source path from which to link. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Open a file or directory. @@ -359,14 +359,14 @@ ;; ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags_t) + (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the ;;; `dirfd` directory. (param $path string) ;;; The method by which to open the file. - (param $o_flags $oflags_t) + (param $oflags $oflags) ;;; The initial rights of the newly created file descriptor. The ;;; implementation is allowed to return a file descriptor with fewer rights ;;; than specified, if and only if those rights do not apply to the type of @@ -375,49 +375,49 @@ ;;; The *base* rights are rights that will apply to operations using the file ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. - (param $fs_rights_base $rights_t) - (param $fs_rights_inherting $rights_t) - (param $flags $fdflags_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inherting $rights) + (param $fdflags $fdflags) + (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd_t) + (result $opened_fd $fd) ) ;;; Read the contents of a symbolic link. ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") - (param $fd $fd_t) + (param $fd $fd) ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Remove a directory. ;;; Return `ENOTEMPTY` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Rename a file or directory. ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") - (param $fd $fd_t) + (param $fd $fd) ;;; The source path of the file or directory to rename. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Create a symbolic link. @@ -425,10 +425,10 @@ (@interface func (export "path_symlink") ;;; The contents of the symbolic link. (param $old_path string) - (param $fd $fd_t) + (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) @@ -436,23 +436,23 @@ ;;; Return `EISDIR` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription_t)) + (param $in (@witx const_pointer $subscription)) ;;; The events that have occurred. - (param $out (@witx pointer $event_t)) + (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size_t) - (result $error $errno_t) + (param $nsubscriptions $size) + (result $error $errno) ;;; The number of events stored. - (result $nevents $size_t) + (result $nevents $size) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -460,21 +460,21 @@ ;;; the environment. (@interface func (export "proc_exit") ;;; The exit code returned by the process. - (param $rval $exitcode_t) + (param $rval $exitcode) ) ;;; Send a signal to the process of the calling thread. ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") ;;; The signal condition to trigger. - (param $sig $signal_t) - (result $error $errno_t) + (param $sig $signal) + (result $error $errno) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno_t) + (result $error $errno) ) ;;; Write high-quality random data into a buffer. @@ -486,46 +486,46 @@ (@interface func (export "random_get") ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ) ;;; Receive a message from a socket. ;;; Note: This is similar to `recv` in POSIX, though it also supports reading ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_t_array) + (param $ri_data $iovec_array) ;;; Message flags. - (param $ri_flags $riflags_t) - (result $error $errno_t) + (param $ri_flags $riflags) + (result $error $errno) ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size_t) + (result $ro_datalen $size) ;;; Message flags. - (result $ro_flags $roflags_t) + (result $ro_flags $roflags) ) ;;; Send a message on a socket. ;;; Note: This is similar to `send` in POSIX, though it also supports writing ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_t_array) + (param $si_data $ciovec_array) ;;; Message flags. - (param $si_flags $siflags_t) - (result $error $errno_t) + (param $si_flags $siflags) + (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size_t) + (result $so_datalen $size) ) ;;; Shut down socket send and receive channels. ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") - (param $fd $fd_t) + (param $fd $fd) ;;; Which channels on the socket to shut down. - (param $how $sdflags_t) - (result $error $errno_t) + (param $how $sdflags) + (result $error $errno) ) ) diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx index cf39a2deb..9a7fc0bb2 100644 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/random/phases/old/snapshot_0/witx/typenames.witx @@ -5,29 +5,29 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(typename $size_t u32) +(typename $size u32) ;;; Non-negative file size or length of a region within a file. -(typename $filesize_t u64) +(typename $filesize u64) ;;; Timestamp in nanoseconds. -(typename $timestamp_t u64) +(typename $timestamp u64) ;;; Identifiers for clocks. -(typename $clockid_t +(typename $clockid (enum u32 ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME + $realtime ;;; The store-wide monotonic clock, which is defined as a clock measuring ;;; real time, whose value cannot be adjusted and which cannot have negative ;;; clock jumps. The epoch of this clock is undefined. The absolute time ;;; value of this clock therefore has no meaning. - $CLOCK_MONOTONIC + $monotonic ;;; The CPU-time clock associated with the current process. - $CLOCK_PROCESS_CPUTIME_ID + $process_cputime_id ;;; The CPU-time clock associated with the current thread. - $CLOCK_THREAD_CPUTIME_ID + $thread_cputime_id ) ) @@ -35,720 +35,720 @@ ;;; Not all of these error codes are returned by the functions provided by this ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. -(typename $errno_t +(typename $errno (enum u16 ;;; No error occurred. System call completed successfully. - $ESUCCESS + $success ;;; Argument list too long. - $E2BIG + $2big ;;; Permission denied. - $EACCES + $acces ;;; Address in use. - $EADDRINUSE + $addrinuse ;;; Address not available. - $EADDRNOTAVAIL + $addrnotavail ;;; Address family not supported. - $EAFNOSUPPORT + $afnosupport ;;; Resource unavailable, or operation would block. - $EAGAIN + $again ;;; Connection already in progress. - $EALREADY + $already ;;; Bad file descriptor. - $EBADF + $badf ;;; Bad message. - $EBADMSG + $badmsg ;;; Device or resource busy. - $EBUSY + $busy ;;; Operation canceled. - $ECANCELED + $canceled ;;; No child processes. - $ECHILD + $child ;;; Connection aborted. - $ECONNABORTED + $connaborted ;;; Connection refused. - $ECONNREFUSED + $connrefused ;;; Connection reset. - $ECONNRESET + $connreset ;;; Resource deadlock would occur. - $EDEADLK + $deadlk ;;; Destination address required. - $EDESTADDRREQ + $destaddrreq ;;; Mathematics argument out of domain of function. - $EDOM + $dom ;;; Reserved. - $EDQUOT + $dquot ;;; File exists. - $EEXIST + $exist ;;; Bad address. - $EFAULT + $fault ;;; File too large. - $EFBIG + $fbig ;;; Host is unreachable. - $EHOSTUNREACH + $hostunreach ;;; Identifier removed. - $EIDRM + $idrm ;;; Illegal byte sequence. - $EILSEQ + $ilseq ;;; Operation in progress. - $EINPROGRESS + $inprogress ;;; Interrupted function. - $EINTR + $intr ;;; Invalid argument. - $EINVAL + $inval ;;; I/O error. - $EIO + $io ;;; Socket is connected. - $EISCONN + $isconn ;;; Is a directory. - $EISDIR + $isdir ;;; Too many levels of symbolic links. - $ELOOP + $loop ;;; File descriptor value too large. - $EMFILE + $mfile ;;; Too many links. - $EMLINK + $mlink ;;; Message too large. - $EMSGSIZE + $msgsize ;;; Reserved. - $EMULTIHOP + $multihop ;;; Filename too long. - $ENAMETOOLONG + $nametoolong ;;; Network is down. - $ENETDOWN + $netdown ;;; Connection aborted by network. - $ENETRESET + $netreset ;;; Network unreachable. - $ENETUNREACH + $netunreach ;;; Too many files open in system. - $ENFILE + $nfile ;;; No buffer space available. - $ENOBUFS + $nobufs ;;; No such device. - $ENODEV + $nodev ;;; No such file or directory. - $ENOENT + $noent ;;; Executable file format error. - $ENOEXEC + $noexec ;;; No locks available. - $ENOLCK + $nolck ;;; Reserved. - $ENOLINK + $nolink ;;; Not enough space. - $ENOMEM + $nomem ;;; No message of the desired type. - $ENOMSG + $nomsg ;;; Protocol not available. - $ENOPROTOOPT + $noprotoopt ;;; No space left on device. - $ENOSPC + $nospc ;;; Function not supported. - $ENOSYS + $nosys ;;; The socket is not connected. - $ENOTCONN + $notconn ;;; Not a directory or a symbolic link to a directory. - $ENOTDIR + $notdir ;;; Directory not empty. - $ENOTEMPTY + $notempty ;;; State not recoverable. - $ENOTRECOVERABLE + $notrecoverable ;;; Not a socket. - $ENOTSOCK + $notsock ;;; Not supported, or operation not supported on socket. - $ENOTSUP + $notsup ;;; Inappropriate I/O control operation. - $ENOTTY + $notty ;;; No such device or address. - $ENXIO + $nxio ;;; Value too large to be stored in data type. - $EOVERFLOW + $overflow ;;; Previous owner died. - $EOWNERDEAD + $ownerdead ;;; Operation not permitted. - $EPERM + $perm ;;; Broken pipe. - $EPIPE + $pipe ;;; Protocol error. - $EPROTO + $proto ;;; Protocol not supported. - $EPROTONOSUPPORT + $protonosupport ;;; Protocol wrong type for socket. - $EPROTOTYPE + $prototype ;;; Result too large. - $ERANGE + $range ;;; Read-only file system. - $EROFS + $rofs ;;; Invalid seek. - $ESPIPE + $spipe ;;; No such process. - $ESRCH + $srch ;;; Reserved. - $ESTALE + $stale ;;; Connection timed out. - $ETIMEDOUT + $timedout ;;; Text file busy. - $ETXTBSY + $txtbsy ;;; Cross-device link. - $EXDEV + $xdev ;;; Extension: Capabilities insufficient. - $ENOTCAPABLE + $notcapable ) ) ;;; File descriptor rights, determining which actions may be performed. -(typename $rights_t +(typename $rights (flags u64 ;;; The right to invoke `fd_datasync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; If `rights::path_open` is set, includes the right to invoke ;;; `path_open` with `FDFLAG_DSYNC`. - $RIGHT_FD_DATASYNC + $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - $RIGHT_FD_READ - ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - $RIGHT_FD_SEEK + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. + $fd_read + ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. + $fd_seek ;;; The right to invoke `fd_fdstat_set_flags`. - $RIGHT_FD_FDSTAT_SET_FLAGS + $fd_fdstat_set_flags ;;; The right to invoke `fd_sync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; If `rights::path_open` is set, includes the right to invoke ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - $RIGHT_FD_SYNC + $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;;; invoke `fd_tell`. - $RIGHT_FD_TELL + $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - $RIGHT_FD_WRITE + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. + $fd_write ;;; The right to invoke `fd_advise`. - $RIGHT_FD_ADVISE + $fd_advise ;;; The right to invoke `fd_allocate`. - $RIGHT_FD_ALLOCATE + $fd_allocate ;;; The right to invoke `path_create_directory`. - $RIGHT_PATH_CREATE_DIRECTORY - ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - $RIGHT_PATH_CREATE_FILE + $path_create_directory + ;;; If `rights::path_open` is set, the right to invoke `path_open` with `O_CREAT`. + $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. - $RIGHT_PATH_LINK_SOURCE + $path_link_source ;;; The right to invoke `path_link` with the file descriptor as the ;;; target directory. - $RIGHT_PATH_LINK_TARGET + $path_link_target ;;; The right to invoke `path_open`. - $RIGHT_PATH_OPEN + $path_open ;;; The right to invoke `fd_readdir`. - $RIGHT_FD_READDIR + $fd_readdir ;;; The right to invoke `path_readlink`. - $RIGHT_PATH_READLINK + $path_readlink ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $RIGHT_PATH_RENAME_SOURCE + $path_rename_source ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $RIGHT_PATH_RENAME_TARGET + $path_rename_target ;;; The right to invoke `path_filestat_get`. - $RIGHT_PATH_FILESTAT_GET + $path_filestat_get ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - $RIGHT_PATH_FILESTAT_SET_SIZE + ;;; If `rights::path_open` is set, includes the right to invoke `path_open` with `O_TRUNC`. + $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. - $RIGHT_PATH_FILESTAT_SET_TIMES + $path_filestat_set_times ;;; The right to invoke `fd_filestat_get`. - $RIGHT_FD_FILESTAT_GET + $fd_filestat_get ;;; The right to invoke `fd_filestat_set_size`. - $RIGHT_FD_FILESTAT_SET_SIZE + $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. - $RIGHT_FD_FILESTAT_SET_TIMES + $fd_filestat_set_times ;;; The right to invoke `path_symlink`. - $RIGHT_PATH_SYMLINK + $path_symlink ;;; The right to invoke `path_remove_directory`. - $RIGHT_PATH_REMOVE_DIRECTORY + $path_remove_directory ;;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE - ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - $RIGHT_POLL_FD_READWRITE + $path_unlink_file + ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. + ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. + $poll_fd_readwrite ;;; The right to invoke `sock_shutdown`. - $RIGHT_SOCK_SHUTDOWN + $sock_shutdown ) ) ;;; A file descriptor index. -(typename $fd_t u32) +(typename $fd u32) ;;; A region of memory for scatter/gather reads. -(typename $iovec_t +(typename $iovec (struct ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. - (field $buf_len $size_t) + (field $buf_len $size) ) ) ;;; A region of memory for scatter/gather writes. -(typename $ciovec_t +(typename $ciovec (struct ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. - (field $buf_len $size_t) + (field $buf_len $size) ) ) -(typename $iovec_t_array (array $iovec_t)) -(typename $ciovec_t_array (array $ciovec_t)) +(typename $iovec_array (array $iovec)) +(typename $ciovec_array (array $ciovec)) ;;; Relative offset within a file. -(typename $filedelta_t s64) +(typename $filedelta s64) ;;; The position relative to which to set the offset of the file descriptor. -(typename $whence_t +(typename $whence (enum u8 ;;; Seek relative to current position. - $WHENCE_CUR + $cur ;;; Seek relative to end-of-file. - $WHENCE_END + $end ;;; Seek relative to start-of-file. - $WHENCE_SET + $set ) ) ;;; A reference to the offset of a directory entry. -(typename $dircookie_t u64) +(typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent_t. -(typename $dirnamlen_t u32) +;;; The type for the $d_namlen field of $dirent. +(typename $dirnamlen u32) ;;; File serial number that is unique within its file system. -(typename $inode_t u64) +(typename $inode u64) ;;; The type of a file descriptor or file. -(typename $filetype_t +(typename $filetype (enum u8 ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $FILETYPE_UNKNOWN + $unknown ;;; The file descriptor or file refers to a block device inode. - $FILETYPE_BLOCK_DEVICE + $block_device ;;; The file descriptor or file refers to a character device inode. - $FILETYPE_CHARACTER_DEVICE + $character_device ;;; The file descriptor or file refers to a directory inode. - $FILETYPE_DIRECTORY + $directory ;;; The file descriptor or file refers to a regular file inode. - $FILETYPE_REGULAR_FILE + $regular_file ;;; The file descriptor or file refers to a datagram socket. - $FILETYPE_SOCKET_DGRAM + $socket_dgram ;;; The file descriptor or file refers to a byte-stream socket. - $FILETYPE_SOCKET_STREAM + $socket_stream ;;; The file refers to a symbolic link inode. - $FILETYPE_SYMBOLIC_LINK + $symbolic_link ) ) ;;; A directory entry. -(typename $dirent_t +(typename $dirent (struct ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie_t) + (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode_t) + (field $d_ino $inode) ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen_t) + (field $d_namlen $dirnamlen) ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype_t) + (field $d_type $filetype) ) ) ;;; File or memory access pattern advisory information. -(typename $advice_t +(typename $advice (enum u8 ;;; The application has no advice to give on its behavior with respect to the specified data. - $ADVICE_NORMAL + $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $ADVICE_SEQUENTIAL + $sequential ;;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM + $random ;;; The application expects to access the specified data in the near future. - $ADVICE_WILLNEED + $willneed ;;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED + $dontneed ;;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE + $noreuse ) ) ;;; File descriptor flags. -(typename $fdflags_t +(typename $fdflags (flags u16 ;;; Append mode: Data written to the file is always appended to the file's end. - $FDFLAG_APPEND + $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $FDFLAG_DSYNC + $dsync ;;; Non-blocking mode. - $FDFLAG_NONBLOCK + $nonblock ;;; Synchronized read I/O operations. - $FDFLAG_RSYNC + $rsync ;;; Write according to synchronized I/O file integrity completion. In ;;; addition to synchronizing the data stored in the file, the implementation ;;; may also synchronously update the file's metadata. - $FDFLAG_SYNC + $sync ) ) ;;; File descriptor attributes. -(typename $fdstat_t +(typename $fdstat (struct ;;; File type. - (field $fs_filetype $filetype_t) + (field $fs_filetype $filetype) ;;; File descriptor flags. - (field $fs_flags $fdflags_t) + (field $fs_flags $fdflags) ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights_t) + (field $fs_rights_base $rights) ;;; Maximum set of rights that may be installed on new file descriptors that ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights_t) + (field $fs_rights_inheriting $rights) ) ) ;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode_t` to uniquely identify a file or directory in the filesystem. -(typename $device_t u64) +;;; with `inode` to uniquely identify a file or directory in the filesystem. +(typename $device u64) ;;; Which file time attributes to adjust. -(typename $fstflags_t +(typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - $FILESTAT_SET_ATIM - ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_ATIM_NOW - ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - $FILESTAT_SET_MTIM - ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_MTIM_NOW + ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + $atim + ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + $atim_now + ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + $mtim + ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + $mtim_now ) ) ;;; Flags determining the method of how paths are resolved. -(typename $lookupflags_t +(typename $lookupflags (flags u32 ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $LOOKUP_SYMLINK_FOLLOW + $symlink_follow ) ) ;;; Open flags used by `path_open`. -(typename $oflags_t +(typename $oflags (flags u16 ;;; Create file if it does not exist. - $O_CREAT + $creat ;;; Fail if not a directory. - $O_DIRECTORY + $directory ;;; Fail if file already exists. - $O_EXCL + $excl ;;; Truncate file to size 0. - $O_TRUNC + $trunc ) ) ;;; Number of hard links to an inode. -(typename $linkcount_t u32) +(typename $linkcount u32) ;;; File attributes. -(typename $filestat_t +(typename $filestat (struct ;;; Device ID of device containing the file. - (field $st_dev $device_t) + (field $dev $device) ;;; File serial number. - (field $st_ino $inode_t) + (field $ino $inode) ;;; File type. - (field $st_filetype $filetype_t) + (field $filetype $filetype) ;;; Number of hard links to the file. - (field $st_nlink $linkcount_t) + (field $nlink $linkcount) ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $st_size $filesize_t) + (field $size $filesize) ;;; Last data access timestamp. - (field $st_atim $timestamp_t) + (field $atim $timestamp) ;;; Last data modification timestamp. - (field $st_mtim $timestamp_t) + (field $mtim $timestamp) ;;; Last file status change timestamp. - (field $st_ctim $timestamp_t) + (field $ctim $timestamp) ) ) ;;; User-provided value that may be attached to objects that is retained when ;;; extracted from the implementation. -(typename $userdata_t u64) +(typename $userdata u64) ;;; Type of a subscription to an event or its occurrence. -(typename $eventtype_t +(typename $eventtype (enum u8 - ;;; The time value of clock `subscription_t::u.clock.clock_id` has - ;;; reached timestamp `subscription_t::u.clock.timeout`. - $EVENTTYPE_CLOCK - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; The time value of clock `subscription::u.clock.clock_id` has + ;;; reached timestamp `subscription::u.clock.timeout`. + $clock + ;;; File descriptor `subscription::u.fd_readwrite.fd` has data ;;; available for reading. This event always triggers for regular files. - $EVENTTYPE_FD_READ - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + $fd_read + ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity ;;; available for writing. This event always triggers for regular files. - $EVENTTYPE_FD_WRITE + $fd_write ) ) ;;; The state of the file descriptor subscribed to with -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $eventrwflags_t +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $eventrwflags (flags u16 ;;; The peer of this socket has closed or disconnected. - $EVENT_FD_READWRITE_HANGUP + $fd_readwrite_hangup ) ) -;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;;; `EVENTTYPE_FD_WRITE`. -(typename $event_fd_readwrite_t +;;; The contents of an $event when type is `eventtype::fd_read` or +;;; `eventtype::fd_write`. +(typename $event_fd_readwrite (struct ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) + (field $nbytes $filesize) ;;; The state of the file descriptor. - (field $flags $eventrwflags_t) + (field $flags $eventrwflags) ) ) -;;; The contents of an $event_t. +;;; The contents of an $event. (typename $event_u (union - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $event_fd_readwrite_t) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $event_fd_readwrite) ) ) ;;; An event that occurred. -(typename $event_t +(typename $event (struct - ;;; User-provided value that got attached to `subscription_t::userdata`. - (field $userdata $userdata_t) + ;;; User-provided value that got attached to `subscription::userdata`. + (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno_t) + (field $error $errno) ;;; The type of the event that occurred. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the event. (field $u $event_u) ) ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_t::u.clock.timeout.` -(typename $subclockflags_t +;;; `subscription::u.clock.timeout.` +(typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription_t::u.clock.timeout` relative to the - ;;; current time value of clock `subscription_t::u.clock.clock_id.` - $SUBSCRIPTION_CLOCK_ABSTIME + ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription::u.clock.timeout` relative to the + ;;; current time value of clock `subscription::u.clock.clock_id.` + $subscription_clock_abstime ) ) -;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. -(typename $subscription_clock_t +;;; The contents of a $subscription when type is `eventtype::clock`. +(typename $subscription_clock (struct ;;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) + (field $identifier $userdata) ;;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) + (field $id $clockid) ;;; The absolute or relative timestamp. - (field $timeout $timestamp_t) + (field $timeout $timestamp) ;;; The amount of time that the implementation may wait additionally ;;; to coalesce with other events. - (field $precision $timestamp_t) + (field $precision $timestamp) ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags_t) + (field $flags $subclockflags) ) ) -;;; The contents of a $subscription_t when type is type is -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $subscription_fd_readwrite_t +;;; The contents of a $subscription when type is type is +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $subscription_fd_readwrite (struct ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) + (field $file_descriptor $fd) ) ) -;;; The contents of a $subscription_t. +;;; The contents of a $subscription. (typename $subscription_u (union - ;;; When type is `EVENTTYPE_CLOCK`: - (field $clock $subscription_clock_t) - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $subscription_fd_readwrite_t) + ;;; When type is `eventtype::clock`: + (field $clock $subscription_clock) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $subscription_fd_readwrite) ) ) ;;; Subscription to an event. -(typename $subscription_t +(typename $subscription (struct ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event_t::userdata`. - (field $userdata $userdata_t) + ;;; implementation and returned through `event::userdata`. + (field $userdata $userdata) ;;; The type of the event to which to subscribe. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the subscription. (field $u $subscription_u) ) ) ;;; Exit code generated by a process when exiting. -(typename $exitcode_t u32) +(typename $exitcode u32) ;;; Signal condition. -(typename $signal_t +(typename $signal (enum u8 ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. - $SIGNONE + $none ;;; Hangup. ;;; Action: Terminates the process. - $SIGHUP + $hup ;;; Terminate interrupt signal. ;;; Action: Terminates the process. - $SIGINT + $int ;;; Terminal quit signal. ;;; Action: Terminates the process. - $SIGQUIT + $quit ;;; Illegal instruction. ;;; Action: Terminates the process. - $SIGILL + $ill ;;; Trace/breakpoint trap. ;;; Action: Terminates the process. - $SIGTRAP + $trap ;;; Process abort signal. ;;; Action: Terminates the process. - $SIGABRT + $abrt ;;; Access to an undefined portion of a memory object. ;;; Action: Terminates the process. - $SIGBUS + $bus ;;; Erroneous arithmetic operation. ;;; Action: Terminates the process. - $SIGFPE + $fpe ;;; Kill. ;;; Action: Terminates the process. - $SIGKILL + $kill ;;; User-defined signal 1. ;;; Action: Terminates the process. - $SIGUSR1 + $usr1 ;;; Invalid memory reference. ;;; Action: Terminates the process. - $SIGSEGV + $segv ;;; User-defined signal 2. ;;; Action: Terminates the process. - $SIGUSR2 + $usr2 ;;; Write on a pipe with no one to read it. ;;; Action: Ignored. - $SIGPIPE + $pipe ;;; Alarm clock. ;;; Action: Terminates the process. - $SIGALRM + $alrm ;;; Termination signal. ;;; Action: Terminates the process. - $SIGTERM + $term ;;; Child process terminated, stopped, or continued. ;;; Action: Ignored. - $SIGCHLD + $chld ;;; Continue executing, if stopped. ;;; Action: Continues executing, if stopped. - $SIGCONT + $cont ;;; Stop executing. ;;; Action: Stops executing. - $SIGSTOP + $stop ;;; Terminal stop signal. ;;; Action: Stops executing. - $SIGTSTP + $tstp ;;; Background process attempting read. ;;; Action: Stops executing. - $SIGTTIN + $ttin ;;; Background process attempting write. ;;; Action: Stops executing. - $SIGTTOU + $ttou ;;; High bandwidth data is available at a socket. ;;; Action: Ignored. - $SIGURG + $urg ;;; CPU time limit exceeded. ;;; Action: Terminates the process. - $SIGXCPU + $xcpu ;;; File size limit exceeded. ;;; Action: Terminates the process. - $SIGXFSZ + $xfsz ;;; Virtual timer expired. ;;; Action: Terminates the process. - $SIGVTALRM + $vtalrm ;;; Profiling timer expired. ;;; Action: Terminates the process. - $SIGPROF + $prof ;;; Window changed. ;;; Action: Ignored. - $SIGWINCH + $winch ;;; I/O possible. ;;; Action: Terminates the process. - $SIGPOLL + $poll ;;; Power failure. ;;; Action: Terminates the process. - $SIGPWR + $pwr ;;; Bad system call. ;;; Action: Terminates the process. - $SIGSYS + $sys ) ) ;;; Flags provided to `sock_recv`. -(typename $riflags_t +(typename $riflags (flags u16 ;;; Returns the message without removing it from the socket's receive queue. - $SOCK_RECV_PEEK + $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. - $SOCK_RECV_WAITALL + $recv_waitall ) ) ;;; Flags returned by `sock_recv`. -(typename $roflags_t +(typename $roflags (flags u16 ;;; Returned by `sock_recv`: Message data has been truncated. - $SOCK_RECV_DATA_TRUNCATED + $recv_data_truncated ) ) ;;; Flags provided to `sock_send`. As there are currently no flags ;;; defined, it must be set to zero. -(typename $siflags_t u16) +(typename $siflags u16) ;;; Which channels on a socket to shut down. -(typename $sdflags_t +(typename $sdflags (flags u8 ;;; Disables further receive operations. - $SHUT_RD + $rd ;;; Disables further send operations. - $SHUT_WR + $wr ) ) ;;; Identifiers for preopened capabilities. -(typename $preopentype_t +(typename $preopentype (enum u8 ;;; A pre-opened directory. - $PREOPENTYPE_DIR + $dir ) ) -;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat when type is `PREOPENTYPE_DIR`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size_t) + (field $pr_name_len $size) ) ) -;;; The contents of an $prestat_t. +;;; The contents of an $prestat. (typename $prestat_u (union ;;; When type is `PREOPENTYPE_DIR`: @@ -757,10 +757,10 @@ ) ;;; Information about a pre-opened capability. -(typename $prestat_t +(typename $prestat (struct ;;; The type of the pre-opened capability. - (field $pr_type $preopentype_t) + (field $pr_type $preopentype) ;;; The contents of the information. (field $u $prestat_u) ) diff --git a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx index 4cf5f4ffa..5e125caf2 100644 --- a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -20,15 +20,15 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Read environment variable data. @@ -36,187 +36,187 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Return the resolution of a clock. ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno_t) + (result $error $errno) ;;; The clock for which to return the resolution. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The resolution of the clock. - (result $resolution $timestamp_t) + (result $resolution $timestamp) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") ;;; The clock for which to return the time. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp_t) - (result $error $errno_t) + (param $precision $timestamp) + (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp_t) + (result $time $timestamp) ) ;;; Provide file advisory information on a file descriptor. ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset within the file to which the advisory applies. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the region to which the advisory applies. - (param $len $filesize_t) + (param $len $filesize) ;;; The advice. - (param $advice $advice_t) - (result $error $errno_t) + (param $advice $advice) + (result $error $errno) ) ;;; Force the allocation of space in a file. ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset at which to start the allocation. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the area that is allocated. - (param $len $filesize_t) - (result $error $errno_t) + (param $len $filesize) + (result $error $errno) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat_t) + (result $stat $fdstat) ) ;;; Adjust the flags associated with a file descriptor. ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the file descriptor flags. - (param $flags $fdflags_t) - (result $error $errno_t) + (param $flags $fdflags) + (result $error $errno) ) ;;; Adjust the rights associated with a file descriptor. ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights_t) - (param $fs_rights_inheriting $rights_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inheriting $rights) + (result $error $errno) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired file size. - (param $st_size $filesize_t) - (result $error $errno_t) + (param $size $filesize) + (result $error $errno) ) ;;; Adjust the timestamps of an open file or directory. ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_t_array) + (param $iovs $iovec_array) ;;; The offset within the file at which to read. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat_t) + (result $buf $prestat) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") - (param $fd $fd_t) + (param $fd $fd) ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) - (param $path_len $size_t) - (result $error $errno_t) + (param $path_len $size) + (result $error $errno) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) + (param $iovs $ciovec_array) ;;; The offset within the file at which to write. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Read from a file descriptor. ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_t_array) - (result $error $errno_t) + (param $iovs $iovec_array) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Read directory entries from a directory. @@ -230,15 +230,15 @@ ;;; read buffer size in case it's too small to fit a single large directory ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") - (param $fd $fd_t) + (param $fd $fd) ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) - (param $buf_len $size_t) + (param $buf_len $size) ;;; The location within the directory to start reading - (param $cookie $dircookie_t) - (result $error $errno_t) + (param $cookie $dircookie) + (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -252,104 +252,104 @@ ;;; This function provides a way to atomically renumber file descriptors, which ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") - (param $fd $fd_t) + (param $fd $fd) ;;; The file descriptor to overwrite. - (param $to $fd_t) - (result $error $errno_t) + (param $to $fd) + (result $error $errno) ) ;;; Move the offset of a file descriptor. ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") - (param $fd $fd_t) + (param $fd $fd) ;;; The number of bytes to move. - (param $offset $filedelta_t) + (param $offset $filedelta) ;;; The base from which the offset is relative. - (param $whence $whence_t) - (result $error $errno_t) + (param $whence $whence) + (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize_t) + (result $newoffset $filesize) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize_t) + (result $offset $filesize) ) ;;; Write to a file descriptor. ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) - (result $error $errno_t) + (param $iovs $ciovec_array) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Create a directory. ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Return the attributes of a file or directory. ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno_t) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the timestamps of a file or directory. ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to operate on. (param $path string) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Create a hard link. ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $old_fd $fd_t) + (param $old_fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags_t) + (param $old_flags $lookupflags) ;;; The source path from which to link. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Open a file or directory. @@ -362,14 +362,14 @@ ;; ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags_t) + (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the ;;; `dirfd` directory. (param $path string) ;;; The method by which to open the file. - (param $o_flags $oflags_t) + (param $oflags $oflags) ;;; The initial rights of the newly created file descriptor. The ;;; implementation is allowed to return a file descriptor with fewer rights ;;; than specified, if and only if those rights do not apply to the type of @@ -378,49 +378,49 @@ ;;; The *base* rights are rights that will apply to operations using the file ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. - (param $fs_rights_base $rights_t) - (param $fs_rights_inherting $rights_t) - (param $flags $fdflags_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inherting $rights) + (param $fdflags $fdflags) + (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd_t) + (result $opened_fd $fd) ) ;;; Read the contents of a symbolic link. ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") - (param $fd $fd_t) + (param $fd $fd) ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Remove a directory. ;;; Return `ENOTEMPTY` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Rename a file or directory. ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") - (param $fd $fd_t) + (param $fd $fd) ;;; The source path of the file or directory to rename. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Create a symbolic link. @@ -428,10 +428,10 @@ (@interface func (export "path_symlink") ;;; The contents of the symbolic link. (param $old_path string) - (param $fd $fd_t) + (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) @@ -439,23 +439,23 @@ ;;; Return `EISDIR` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription_t)) + (param $in (@witx const_pointer $subscription)) ;;; The events that have occurred. - (param $out (@witx pointer $event_t)) + (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size_t) - (result $error $errno_t) + (param $nsubscriptions $size) + (result $error $errno) ;;; The number of events stored. - (result $nevents $size_t) + (result $nevents $size) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -463,21 +463,21 @@ ;;; the environment. (@interface func (export "proc_exit") ;;; The exit code returned by the process. - (param $rval $exitcode_t) + (param $rval $exitcode) ) ;;; Send a signal to the process of the calling thread. ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") ;;; The signal condition to trigger. - (param $sig $signal_t) - (result $error $errno_t) + (param $sig $signal) + (result $error $errno) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno_t) + (result $error $errno) ) ;;; Write high-quality random data into a buffer. @@ -489,46 +489,46 @@ (@interface func (export "random_get") ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ) ;;; Receive a message from a socket. ;;; Note: This is similar to `recv` in POSIX, though it also supports reading ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_t_array) + (param $ri_data $iovec_array) ;;; Message flags. - (param $ri_flags $riflags_t) - (result $error $errno_t) + (param $ri_flags $riflags) + (result $error $errno) ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size_t) + (result $ro_datalen $size) ;;; Message flags. - (result $ro_flags $roflags_t) + (result $ro_flags $roflags) ) ;;; Send a message on a socket. ;;; Note: This is similar to `send` in POSIX, though it also supports writing ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_t_array) + (param $si_data $ciovec_array) ;;; Message flags. - (param $si_flags $siflags_t) - (result $error $errno_t) + (param $si_flags $siflags) + (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size_t) + (result $so_datalen $size) ) ;;; Shut down socket send and receive channels. ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") - (param $fd $fd_t) + (param $fd $fd) ;;; Which channels on the socket to shut down. - (param $how $sdflags_t) - (result $error $errno_t) + (param $how $sdflags) + (result $error $errno) ) ) diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx index 68f6fac4a..d8ce215d7 100644 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -5,29 +5,29 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(typename $size_t u32) +(typename $size u32) ;;; Non-negative file size or length of a region within a file. -(typename $filesize_t u64) +(typename $filesize u64) ;;; Timestamp in nanoseconds. -(typename $timestamp_t u64) +(typename $timestamp u64) ;;; Identifiers for clocks. -(typename $clockid_t +(typename $clockid (enum u32 ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME + $realtime ;;; The store-wide monotonic clock, which is defined as a clock measuring ;;; real time, whose value cannot be adjusted and which cannot have negative ;;; clock jumps. The epoch of this clock is undefined. The absolute time ;;; value of this clock therefore has no meaning. - $CLOCK_MONOTONIC + $monotonic ;;; The CPU-time clock associated with the current process. - $CLOCK_PROCESS_CPUTIME_ID + $process_cputime_id ;;; The CPU-time clock associated with the current thread. - $CLOCK_THREAD_CPUTIME_ID + $thread_cputime_id ) ) @@ -35,732 +35,732 @@ ;;; Not all of these error codes are returned by the functions provided by this ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. -(typename $errno_t +(typename $errno (enum u16 ;;; No error occurred. System call completed successfully. - $ESUCCESS + $success ;;; Argument list too long. - $E2BIG + $2big ;;; Permission denied. - $EACCES + $acces ;;; Address in use. - $EADDRINUSE + $addrinuse ;;; Address not available. - $EADDRNOTAVAIL + $addrnotavail ;;; Address family not supported. - $EAFNOSUPPORT + $afnosupport ;;; Resource unavailable, or operation would block. - $EAGAIN + $again ;;; Connection already in progress. - $EALREADY + $already ;;; Bad file descriptor. - $EBADF + $badf ;;; Bad message. - $EBADMSG + $badmsg ;;; Device or resource busy. - $EBUSY + $busy ;;; Operation canceled. - $ECANCELED + $canceled ;;; No child processes. - $ECHILD + $child ;;; Connection aborted. - $ECONNABORTED + $connaborted ;;; Connection refused. - $ECONNREFUSED + $connrefused ;;; Connection reset. - $ECONNRESET + $connreset ;;; Resource deadlock would occur. - $EDEADLK + $deadlk ;;; Destination address required. - $EDESTADDRREQ + $destaddrreq ;;; Mathematics argument out of domain of function. - $EDOM + $dom ;;; Reserved. - $EDQUOT + $dquot ;;; File exists. - $EEXIST + $exist ;;; Bad address. - $EFAULT + $fault ;;; File too large. - $EFBIG + $fbig ;;; Host is unreachable. - $EHOSTUNREACH + $hostunreach ;;; Identifier removed. - $EIDRM + $idrm ;;; Illegal byte sequence. - $EILSEQ + $ilseq ;;; Operation in progress. - $EINPROGRESS + $inprogress ;;; Interrupted function. - $EINTR + $intr ;;; Invalid argument. - $EINVAL + $inval ;;; I/O error. - $EIO + $io ;;; Socket is connected. - $EISCONN + $isconn ;;; Is a directory. - $EISDIR + $isdir ;;; Too many levels of symbolic links. - $ELOOP + $loop ;;; File descriptor value too large. - $EMFILE + $mfile ;;; Too many links. - $EMLINK + $mlink ;;; Message too large. - $EMSGSIZE + $msgsize ;;; Reserved. - $EMULTIHOP + $multihop ;;; Filename too long. - $ENAMETOOLONG + $nametoolong ;;; Network is down. - $ENETDOWN + $netdown ;;; Connection aborted by network. - $ENETRESET + $netreset ;;; Network unreachable. - $ENETUNREACH + $netunreach ;;; Too many files open in system. - $ENFILE + $nfile ;;; No buffer space available. - $ENOBUFS + $nobufs ;;; No such device. - $ENODEV + $nodev ;;; No such file or directory. - $ENOENT + $noent ;;; Executable file format error. - $ENOEXEC + $noexec ;;; No locks available. - $ENOLCK + $nolck ;;; Reserved. - $ENOLINK + $nolink ;;; Not enough space. - $ENOMEM + $nomem ;;; No message of the desired type. - $ENOMSG + $nomsg ;;; Protocol not available. - $ENOPROTOOPT + $noprotoopt ;;; No space left on device. - $ENOSPC + $nospc ;;; Function not supported. - $ENOSYS + $nosys ;;; The socket is not connected. - $ENOTCONN + $notconn ;;; Not a directory or a symbolic link to a directory. - $ENOTDIR + $notdir ;;; Directory not empty. - $ENOTEMPTY + $notempty ;;; State not recoverable. - $ENOTRECOVERABLE + $notrecoverable ;;; Not a socket. - $ENOTSOCK + $notsock ;;; Not supported, or operation not supported on socket. - $ENOTSUP + $notsup ;;; Inappropriate I/O control operation. - $ENOTTY + $notty ;;; No such device or address. - $ENXIO + $nxio ;;; Value too large to be stored in data type. - $EOVERFLOW + $overflow ;;; Previous owner died. - $EOWNERDEAD + $ownerdead ;;; Operation not permitted. - $EPERM + $perm ;;; Broken pipe. - $EPIPE + $pipe ;;; Protocol error. - $EPROTO + $proto ;;; Protocol not supported. - $EPROTONOSUPPORT + $protonosupport ;;; Protocol wrong type for socket. - $EPROTOTYPE + $prototype ;;; Result too large. - $ERANGE + $range ;;; Read-only file system. - $EROFS + $rofs ;;; Invalid seek. - $ESPIPE + $spipe ;;; No such process. - $ESRCH + $srch ;;; Reserved. - $ESTALE + $stale ;;; Connection timed out. - $ETIMEDOUT + $timedout ;;; Text file busy. - $ETXTBSY + $txtbsy ;;; Cross-device link. - $EXDEV + $xdev ;;; Extension: Capabilities insufficient. - $ENOTCAPABLE + $notcapable ) ) ;;; File descriptor rights, determining which actions may be performed. -(typename $rights_t +(typename $rights (flags u64 ;;; The right to invoke `fd_datasync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_DSYNC`. - $RIGHT_FD_DATASYNC + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflag::dsync`. + $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - $RIGHT_FD_READ - ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - $RIGHT_FD_SEEK + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. + $fd_read + ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. + $fd_seek ;;; The right to invoke `fd_fdstat_set_flags`. - $RIGHT_FD_FDSTAT_SET_FLAGS + $fd_fdstat_set_flags ;;; The right to invoke `fd_sync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - $RIGHT_FD_SYNC + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflag::rsync` and `fdflag::dsync`. + $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;;; invoke `fd_tell`. - $RIGHT_FD_TELL + $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - $RIGHT_FD_WRITE + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. + $fd_write ;;; The right to invoke `fd_advise`. - $RIGHT_FD_ADVISE + $fd_advise ;;; The right to invoke `fd_allocate`. - $RIGHT_FD_ALLOCATE + $fd_allocate ;;; The right to invoke `path_create_directory`. - $RIGHT_PATH_CREATE_DIRECTORY - ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - $RIGHT_PATH_CREATE_FILE + $path_create_directory + ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::creat`. + $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. - $RIGHT_PATH_LINK_SOURCE + $path_link_source ;;; The right to invoke `path_link` with the file descriptor as the ;;; target directory. - $RIGHT_PATH_LINK_TARGET + $path_link_target ;;; The right to invoke `path_open`. - $RIGHT_PATH_OPEN + $path_open ;;; The right to invoke `fd_readdir`. - $RIGHT_FD_READDIR + $fd_readdir ;;; The right to invoke `path_readlink`. - $RIGHT_PATH_READLINK + $path_readlink ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $RIGHT_PATH_RENAME_SOURCE + $path_rename_source ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $RIGHT_PATH_RENAME_TARGET + $path_rename_target ;;; The right to invoke `path_filestat_get`. - $RIGHT_PATH_FILESTAT_GET + $path_filestat_get ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - $RIGHT_PATH_FILESTAT_SET_SIZE + ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. + $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. - $RIGHT_PATH_FILESTAT_SET_TIMES + $path_filestat_set_times ;;; The right to invoke `fd_filestat_get`. - $RIGHT_FD_FILESTAT_GET + $fd_filestat_get ;;; The right to invoke `fd_filestat_set_size`. - $RIGHT_FD_FILESTAT_SET_SIZE + $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. - $RIGHT_FD_FILESTAT_SET_TIMES + $fd_filestat_set_times ;;; The right to invoke `path_symlink`. - $RIGHT_PATH_SYMLINK + $path_symlink ;;; The right to invoke `path_remove_directory`. - $RIGHT_PATH_REMOVE_DIRECTORY + $path_remove_directory ;;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE - ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - $RIGHT_POLL_FD_READWRITE + $path_unlink_file + ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. + ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. + $poll_fd_readwrite ;;; The right to invoke `sock_shutdown`. - $RIGHT_SOCK_SHUTDOWN + $sock_shutdown ) ) ;;; A file descriptor index. -(typename $fd_t u32) +(typename $fd u32) ;;; A region of memory for scatter/gather reads. -(typename $iovec_t +(typename $iovec (struct ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. - (field $buf_len $size_t) + (field $buf_len $size) ) ) ;;; A region of memory for scatter/gather writes. -(typename $ciovec_t +(typename $ciovec (struct ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. - (field $buf_len $size_t) + (field $buf_len $size) ) ) -(typename $iovec_t_array (array $iovec_t)) -(typename $ciovec_t_array (array $ciovec_t)) +(typename $iovec_array (array $iovec)) +(typename $ciovec_array (array $ciovec)) ;;; Relative offset within a file. -(typename $filedelta_t s64) +(typename $filedelta s64) ;;; The position relative to which to set the offset of the file descriptor. -(typename $whence_t +(typename $whence (enum u8 ;;; Seek relative to start-of-file. - $WHENCE_SET + $set ;;; Seek relative to current position. - $WHENCE_CUR + $cur ;;; Seek relative to end-of-file. - $WHENCE_END + $end ) ) ;;; A reference to the offset of a directory entry. ;;; ;;; The value 0 signifies the start of the directory. -(typename $dircookie_t u64) +(typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent_t. -(typename $dirnamlen_t u32) +;;; The type for the $d_namlen field of $dirent. +(typename $dirnamlen u32) ;;; File serial number that is unique within its file system. -(typename $inode_t u64) +(typename $inode u64) ;;; The type of a file descriptor or file. -(typename $filetype_t +(typename $filetype (enum u8 ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $FILETYPE_UNKNOWN + $unknown ;;; The file descriptor or file refers to a block device inode. - $FILETYPE_BLOCK_DEVICE + $block_device ;;; The file descriptor or file refers to a character device inode. - $FILETYPE_CHARACTER_DEVICE + $character_device ;;; The file descriptor or file refers to a directory inode. - $FILETYPE_DIRECTORY + $directory ;;; The file descriptor or file refers to a regular file inode. - $FILETYPE_REGULAR_FILE + $regular_file ;;; The file descriptor or file refers to a datagram socket. - $FILETYPE_SOCKET_DGRAM + $socket_dgram ;;; The file descriptor or file refers to a byte-stream socket. - $FILETYPE_SOCKET_STREAM + $socket_stream ;;; The file refers to a symbolic link inode. - $FILETYPE_SYMBOLIC_LINK + $symbolic_link ) ) ;;; A directory entry. -(typename $dirent_t +(typename $dirent (struct ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie_t) + (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode_t) + (field $d_ino $inode) ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen_t) + (field $d_namlen $dirnamlen) ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype_t) + (field $d_type $filetype) ) ) ;;; File or memory access pattern advisory information. -(typename $advice_t +(typename $advice (enum u8 ;;; The application has no advice to give on its behavior with respect to the specified data. - $ADVICE_NORMAL + $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $ADVICE_SEQUENTIAL + $sequential ;;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM + $random ;;; The application expects to access the specified data in the near future. - $ADVICE_WILLNEED + $willneed ;;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED + $dontneed ;;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE + $noreuse ) ) ;;; File descriptor flags. -(typename $fdflags_t +(typename $fdflags (flags u16 ;;; Append mode: Data written to the file is always appended to the file's end. - $FDFLAG_APPEND + $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $FDFLAG_DSYNC + $dsync ;;; Non-blocking mode. - $FDFLAG_NONBLOCK + $nonblock ;;; Synchronized read I/O operations. - $FDFLAG_RSYNC + $rsync ;;; Write according to synchronized I/O file integrity completion. In ;;; addition to synchronizing the data stored in the file, the implementation ;;; may also synchronously update the file's metadata. - $FDFLAG_SYNC + $sync ) ) ;;; File descriptor attributes. -(typename $fdstat_t +(typename $fdstat (struct ;;; File type. - (field $fs_filetype $filetype_t) + (field $fs_filetype $filetype) ;;; File descriptor flags. - (field $fs_flags $fdflags_t) + (field $fs_flags $fdflags) ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights_t) + (field $fs_rights_base $rights) ;;; Maximum set of rights that may be installed on new file descriptors that ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights_t) + (field $fs_rights_inheriting $rights) ) ) ;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode_t` to uniquely identify a file or directory in the filesystem. -(typename $device_t u64) +;;; with `inode` to uniquely identify a file or directory in the filesystem. +(typename $device u64) ;;; Which file time attributes to adjust. -(typename $fstflags_t +(typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - $FILESTAT_SET_ATIM - ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_ATIM_NOW - ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - $FILESTAT_SET_MTIM - ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_MTIM_NOW + ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + $atim + ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + $atim_now + ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + $mtim + ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + $mtim_now ) ) ;;; Flags determining the method of how paths are resolved. -(typename $lookupflags_t +(typename $lookupflags (flags u32 ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $LOOKUP_SYMLINK_FOLLOW + $symlink_follow ) ) ;;; Open flags used by `path_open`. -(typename $oflags_t +(typename $oflags (flags u16 ;;; Create file if it does not exist. - $O_CREAT + $creat ;;; Fail if not a directory. - $O_DIRECTORY + $directory ;;; Fail if file already exists. - $O_EXCL + $excl ;;; Truncate file to size 0. - $O_TRUNC + $trunc ) ) ;;; Number of hard links to an inode. -(typename $linkcount_t u64) +(typename $linkcount u64) ;;; File attributes. -(typename $filestat_t +(typename $filestat (struct ;;; Device ID of device containing the file. - (field $st_dev $device_t) + (field $dev $device) ;;; File serial number. - (field $st_ino $inode_t) + (field $ino $inode) ;;; File type. - (field $st_filetype $filetype_t) + (field $filetype $filetype) ;;; Number of hard links to the file. - (field $st_nlink $linkcount_t) + (field $nlink $linkcount) ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $st_size $filesize_t) + (field $size $filesize) ;;; Last data access timestamp. - (field $st_atim $timestamp_t) + (field $atim $timestamp) ;;; Last data modification timestamp. - (field $st_mtim $timestamp_t) + (field $mtim $timestamp) ;;; Last file status change timestamp. - (field $st_ctim $timestamp_t) + (field $ctim $timestamp) ) ) ;;; User-provided value that may be attached to objects that is retained when ;;; extracted from the implementation. -(typename $userdata_t u64) +(typename $userdata u64) ;;; Type of a subscription to an event or its occurrence. -(typename $eventtype_t +(typename $eventtype (enum u8 - ;;; The time value of clock `subscription_t::u.clock.clock_id` has - ;;; reached timestamp `subscription_t::u.clock.timeout`. - $EVENTTYPE_CLOCK - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; The time value of clock `subscription::u.clock.clock_id` has + ;;; reached timestamp `subscription::u.clock.timeout`. + $clock + ;;; File descriptor `subscription::u.fd_readwrite.fd` has data ;;; available for reading. This event always triggers for regular files. - $EVENTTYPE_FD_READ - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + $fd_read + ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity ;;; available for writing. This event always triggers for regular files. - $EVENTTYPE_FD_WRITE + $fd_write ) ) ;;; The state of the file descriptor subscribed to with -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $eventrwflags_t +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $eventrwflags (flags u16 ;;; The peer of this socket has closed or disconnected. - $EVENT_FD_READWRITE_HANGUP + $fd_readwrite_hangup ) ) -;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;;; `EVENTTYPE_FD_WRITE`. -(typename $event_fd_readwrite_t +;;; The contents of an $event when type is `eventtype::fd_read` or +;;; `eventtype::fd_write`. +(typename $event_fd_readwrite (struct ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) + (field $nbytes $filesize) ;;; The state of the file descriptor. - (field $flags $eventrwflags_t) + (field $flags $eventrwflags) ) ) -;;; The contents of an $event_t. +;;; The contents of an $event. (typename $event_u (union - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $event_fd_readwrite_t) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $event_fd_readwrite) ) ) ;;; An event that occurred. -(typename $event_t +(typename $event (struct - ;;; User-provided value that got attached to `subscription_t::userdata`. - (field $userdata $userdata_t) + ;;; User-provided value that got attached to `subscription::userdata`. + (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno_t) + (field $error $errno) ;;; The type of the event that occurred. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the event. (field $u $event_u) ) ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_t::u.clock.timeout.` -(typename $subclockflags_t +;;; `subscription::u.clock.timeout.` +(typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription_t::u.clock.timeout` relative to the - ;;; current time value of clock `subscription_t::u.clock.clock_id.` - $SUBSCRIPTION_CLOCK_ABSTIME + ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription::u.clock.timeout` relative to the + ;;; current time value of clock `subscription::u.clock.clock_id.` + $subscription_clock_abstime ) ) -;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. -(typename $subscription_clock_t +;;; The contents of a $subscription when type is `eventtype::clock`. +(typename $subscription_clock (struct ;;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) + (field $id $clockid) ;;; The absolute or relative timestamp. - (field $timeout $timestamp_t) + (field $timeout $timestamp) ;;; The amount of time that the implementation may wait additionally ;;; to coalesce with other events. - (field $precision $timestamp_t) + (field $precision $timestamp) ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags_t) + (field $flags $subclockflags) ) ) -;;; The contents of a $subscription_t when type is type is -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $subscription_fd_readwrite_t +;;; The contents of a $subscription when type is type is +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $subscription_fd_readwrite (struct ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) + (field $file_descriptor $fd) ) ) -;;; The contents of a $subscription_t. +;;; The contents of a $subscription. (typename $subscription_u (union - ;;; When type is `EVENTTYPE_CLOCK`: - (field $clock $subscription_clock_t) - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $subscription_fd_readwrite_t) + ;;; When type is `eventtype::clock`: + (field $clock $subscription_clock) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $subscription_fd_readwrite) ) ) ;;; Subscription to an event. -(typename $subscription_t +(typename $subscription (struct ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event_t::userdata`. - (field $userdata $userdata_t) + ;;; implementation and returned through `event::userdata`. + (field $userdata $userdata) ;;; The type of the event to which to subscribe. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the subscription. (field $u $subscription_u) ) ) ;;; Exit code generated by a process when exiting. -(typename $exitcode_t u32) +(typename $exitcode u32) ;;; Signal condition. -(typename $signal_t +(typename $signal (enum u8 ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. - $SIGNONE + $none ;;; Hangup. ;;; Action: Terminates the process. - $SIGHUP + $hup ;;; Terminate interrupt signal. ;;; Action: Terminates the process. - $SIGINT + $int ;;; Terminal quit signal. ;;; Action: Terminates the process. - $SIGQUIT + $quit ;;; Illegal instruction. ;;; Action: Terminates the process. - $SIGILL + $ill ;;; Trace/breakpoint trap. ;;; Action: Terminates the process. - $SIGTRAP + $trap ;;; Process abort signal. ;;; Action: Terminates the process. - $SIGABRT + $abrt ;;; Access to an undefined portion of a memory object. ;;; Action: Terminates the process. - $SIGBUS + $bus ;;; Erroneous arithmetic operation. ;;; Action: Terminates the process. - $SIGFPE + $fpe ;;; Kill. ;;; Action: Terminates the process. - $SIGKILL + $kill ;;; User-defined signal 1. ;;; Action: Terminates the process. - $SIGUSR1 + $usr1 ;;; Invalid memory reference. ;;; Action: Terminates the process. - $SIGSEGV + $segv ;;; User-defined signal 2. ;;; Action: Terminates the process. - $SIGUSR2 + $usr2 ;;; Write on a pipe with no one to read it. ;;; Action: Ignored. - $SIGPIPE + $pipe ;;; Alarm clock. ;;; Action: Terminates the process. - $SIGALRM + $alrm ;;; Termination signal. ;;; Action: Terminates the process. - $SIGTERM + $term ;;; Child process terminated, stopped, or continued. ;;; Action: Ignored. - $SIGCHLD + $chld ;;; Continue executing, if stopped. ;;; Action: Continues executing, if stopped. - $SIGCONT + $cont ;;; Stop executing. ;;; Action: Stops executing. - $SIGSTOP + $stop ;;; Terminal stop signal. ;;; Action: Stops executing. - $SIGTSTP + $tstp ;;; Background process attempting read. ;;; Action: Stops executing. - $SIGTTIN + $ttin ;;; Background process attempting write. ;;; Action: Stops executing. - $SIGTTOU + $ttou ;;; High bandwidth data is available at a socket. ;;; Action: Ignored. - $SIGURG + $urg ;;; CPU time limit exceeded. ;;; Action: Terminates the process. - $SIGXCPU + $xcpu ;;; File size limit exceeded. ;;; Action: Terminates the process. - $SIGXFSZ + $xfsz ;;; Virtual timer expired. ;;; Action: Terminates the process. - $SIGVTALRM + $vtalrm ;;; Profiling timer expired. ;;; Action: Terminates the process. - $SIGPROF + $prof ;;; Window changed. ;;; Action: Ignored. - $SIGWINCH + $winch ;;; I/O possible. ;;; Action: Terminates the process. - $SIGPOLL + $poll ;;; Power failure. ;;; Action: Terminates the process. - $SIGPWR + $pwr ;;; Bad system call. ;;; Action: Terminates the process. - $SIGSYS + $sys ) ) ;;; Flags provided to `sock_recv`. -(typename $riflags_t +(typename $riflags (flags u16 ;;; Returns the message without removing it from the socket's receive queue. - $SOCK_RECV_PEEK + $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. - $SOCK_RECV_WAITALL + $recv_waitall ) ) ;;; Flags returned by `sock_recv`. -(typename $roflags_t +(typename $roflags (flags u16 ;;; Returned by `sock_recv`: Message data has been truncated. - $SOCK_RECV_DATA_TRUNCATED + $recv_data_truncated ) ) ;;; Flags provided to `sock_send`. As there are currently no flags ;;; defined, it must be set to zero. -(typename $siflags_t u16) +(typename $siflags u16) ;;; Which channels on a socket to shut down. -(typename $sdflags_t +(typename $sdflags (flags u8 ;;; Disables further receive operations. - $SHUT_RD + $rd ;;; Disables further send operations. - $SHUT_WR + $wr ) ) ;;; Identifiers for preopened capabilities. -(typename $preopentype_t +(typename $preopentype (enum u8 ;;; A pre-opened directory. - $PREOPENTYPE_DIR + $dir ) ) -;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size_t) + (field $pr_name_len $size) ) ) -;;; The contents of an $prestat_t. +;;; The contents of an $prestat. (typename $prestat_u (union - ;;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `preopentype::dir`: (field $dir $prestat_dir) ) ) ;;; Information about a pre-opened capability. -(typename $prestat_t +(typename $prestat (struct ;;; The type of the pre-opened capability. - (field $pr_type $preopentype_t) + (field $pr_type $preopentype) ;;; The contents of the information. (field $u $prestat_u) ) diff --git a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx index e69b788dc..44a297b8c 100644 --- a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -17,15 +17,15 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Read environment variable data. @@ -33,187 +33,187 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Return the resolution of a clock. ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno_t) + (result $error $errno) ;;; The clock for which to return the resolution. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The resolution of the clock. - (result $resolution $timestamp_t) + (result $resolution $timestamp) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") ;;; The clock for which to return the time. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp_t) - (result $error $errno_t) + (param $precision $timestamp) + (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp_t) + (result $time $timestamp) ) ;;; Provide file advisory information on a file descriptor. ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset within the file to which the advisory applies. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the region to which the advisory applies. - (param $len $filesize_t) + (param $len $filesize) ;;; The advice. - (param $advice $advice_t) - (result $error $errno_t) + (param $advice $advice) + (result $error $errno) ) ;;; Force the allocation of space in a file. ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset at which to start the allocation. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the area that is allocated. - (param $len $filesize_t) - (result $error $errno_t) + (param $len $filesize) + (result $error $errno) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat_t) + (result $stat $fdstat) ) ;;; Adjust the flags associated with a file descriptor. ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the file descriptor flags. - (param $flags $fdflags_t) - (result $error $errno_t) + (param $flags $fdflags) + (result $error $errno) ) ;;; Adjust the rights associated with a file descriptor. ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights_t) - (param $fs_rights_inheriting $rights_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inheriting $rights) + (result $error $errno) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired file size. - (param $st_size $filesize_t) - (result $error $errno_t) + (param $size $filesize) + (result $error $errno) ) ;;; Adjust the timestamps of an open file or directory. ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_t_array) + (param $iovs $iovec_array) ;;; The offset within the file at which to read. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat_t) + (result $buf $prestat) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") - (param $fd $fd_t) + (param $fd $fd) ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) - (param $path_len $size_t) - (result $error $errno_t) + (param $path_len $size) + (result $error $errno) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) + (param $iovs $ciovec_array) ;;; The offset within the file at which to write. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Read from a file descriptor. ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_t_array) - (result $error $errno_t) + (param $iovs $iovec_array) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Read directory entries from a directory. @@ -227,15 +227,15 @@ ;;; read buffer size in case it's too small to fit a single large directory ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") - (param $fd $fd_t) + (param $fd $fd) ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) - (param $buf_len $size_t) + (param $buf_len $size) ;;; The location within the directory to start reading - (param $cookie $dircookie_t) - (result $error $errno_t) + (param $cookie $dircookie) + (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -249,104 +249,104 @@ ;;; This function provides a way to atomically renumber file descriptors, which ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") - (param $fd $fd_t) + (param $fd $fd) ;;; The file descriptor to overwrite. - (param $to $fd_t) - (result $error $errno_t) + (param $to $fd) + (result $error $errno) ) ;;; Move the offset of a file descriptor. ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") - (param $fd $fd_t) + (param $fd $fd) ;;; The number of bytes to move. - (param $offset $filedelta_t) + (param $offset $filedelta) ;;; The base from which the offset is relative. - (param $whence $whence_t) - (result $error $errno_t) + (param $whence $whence) + (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize_t) + (result $newoffset $filesize) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize_t) + (result $offset $filesize) ) ;;; Write to a file descriptor. ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) - (result $error $errno_t) + (param $iovs $ciovec_array) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Create a directory. ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Return the attributes of a file or directory. ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno_t) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the timestamps of a file or directory. ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to operate on. (param $path string) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Create a hard link. ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $old_fd $fd_t) + (param $old_fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags_t) + (param $old_flags $lookupflags) ;;; The source path from which to link. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Open a file or directory. @@ -359,14 +359,14 @@ ;; ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags_t) + (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the ;;; `dirfd` directory. (param $path string) ;;; The method by which to open the file. - (param $o_flags $oflags_t) + (param $oflags $oflags) ;;; The initial rights of the newly created file descriptor. The ;;; implementation is allowed to return a file descriptor with fewer rights ;;; than specified, if and only if those rights do not apply to the type of @@ -375,49 +375,49 @@ ;;; The *base* rights are rights that will apply to operations using the file ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. - (param $fs_rights_base $rights_t) - (param $fs_rights_inherting $rights_t) - (param $flags $fdflags_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inherting $rights) + (param $fdflags $fdflags) + (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd_t) + (result $opened_fd $fd) ) ;;; Read the contents of a symbolic link. ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") - (param $fd $fd_t) + (param $fd $fd) ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Remove a directory. ;;; Return `ENOTEMPTY` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Rename a file or directory. ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") - (param $fd $fd_t) + (param $fd $fd) ;;; The source path of the file or directory to rename. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Create a symbolic link. @@ -425,10 +425,10 @@ (@interface func (export "path_symlink") ;;; The contents of the symbolic link. (param $old_path string) - (param $fd $fd_t) + (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) @@ -436,23 +436,23 @@ ;;; Return `EISDIR` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription_t)) + (param $in (@witx const_pointer $subscription)) ;;; The events that have occurred. - (param $out (@witx pointer $event_t)) + (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size_t) - (result $error $errno_t) + (param $nsubscriptions $size) + (result $error $errno) ;;; The number of events stored. - (result $nevents $size_t) + (result $nevents $size) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -460,21 +460,21 @@ ;;; the environment. (@interface func (export "proc_exit") ;;; The exit code returned by the process. - (param $rval $exitcode_t) + (param $rval $exitcode) ) ;;; Send a signal to the process of the calling thread. ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") ;;; The signal condition to trigger. - (param $sig $signal_t) - (result $error $errno_t) + (param $sig $signal) + (result $error $errno) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno_t) + (result $error $errno) ) ;;; Write high-quality random data into a buffer. @@ -486,46 +486,46 @@ (@interface func (export "random_get") ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ) ;;; Receive a message from a socket. ;;; Note: This is similar to `recv` in POSIX, though it also supports reading ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_t_array) + (param $ri_data $iovec_array) ;;; Message flags. - (param $ri_flags $riflags_t) - (result $error $errno_t) + (param $ri_flags $riflags) + (result $error $errno) ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size_t) + (result $ro_datalen $size) ;;; Message flags. - (result $ro_flags $roflags_t) + (result $ro_flags $roflags) ) ;;; Send a message on a socket. ;;; Note: This is similar to `send` in POSIX, though it also supports writing ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_t_array) + (param $si_data $ciovec_array) ;;; Message flags. - (param $si_flags $siflags_t) - (result $error $errno_t) + (param $si_flags $siflags) + (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size_t) + (result $so_datalen $size) ) ;;; Shut down socket send and receive channels. ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") - (param $fd $fd_t) + (param $fd $fd) ;;; Which channels on the socket to shut down. - (param $how $sdflags_t) - (result $error $errno_t) + (param $how $sdflags) + (result $error $errno) ) ) diff --git a/proposals/random/tools/witx/tests/wasi.rs b/proposals/random/tools/witx/tests/wasi.rs index aef954236..938c78067 100644 --- a/proposals/random/tools/witx/tests/wasi.rs +++ b/proposals/random/tools/witx/tests/wasi.rs @@ -25,11 +25,6 @@ fn render_roundtrip() { let back_to_sexprs = format!("{}", doc); println!("{}", back_to_sexprs); - let doc2 = witx::parse(&back_to_sexprs) - .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) - .unwrap(); - - let back_to_sexprs = format!("{}", doc); let doc2 = witx::parse(&back_to_sexprs) .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) From 229982c48c3b7f8d6c0bf0d92c959df59fcb5521 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 17:15:57 -0800 Subject: [PATCH 0297/1772] Mechanical witx naming convention changes (#137) * witx: drop trailing `_t` from all typenames this suffix is not appropriate for all languages that may need to generate code from witx, so this change removes it from all witx files and leaves the code generator in charge of putting the appropriate suffix onto any type names it produces. sed -i -E 's/\$([a-z_]+)_t([)\n\r ])?/\$\1\2/g' **/*.witx * witx: change identifiers to snake case Change all $SHOUTY_SNAKE_CASE identifers to $snake_case. It is the responsibility of a code generator backend to select the right case and style of these identifiers for the target language. In witx, we should standardize on snake case (lowercase with a single underscore as a word separator) sed -i -E 's/\$([A-Z0-9_]+)([)\n\r ])?/\$\L\1\2/g' **/*.witx * witx: mechanically remove repeated prefixes from flags, enums once again, the code translation tool is responsible for putting the right prefix in the generated code. languages with proper namespacing facilities don't need the identifiers themselves to be namespaced. otherwise, you can derive the namespacing prefix from the type name. sed -i -E 's/\$(clock_|right_|whence_|filetype_|advice_|fdflag_|filestat_set_|lookup_|o_|st_|sock_|shut_|preopentype_)/\$/g' **/*.witx * restore fields named pr_type and d_type * remove $event_ prefix from eventrwflags member doing so by regexp would delete various other valid event_ prefixes * remove eventtype_ prefix from enum fields this one could have been mechanical, but i left it out of the regexp * restore oflags, fdflags argument names in path_open * witx: delete leading `sig` from each $signal enum variant * witx: delete leading `e` from each $errno enum variant * fixup test * witx: fix up old style names in comments --- .../phases/ephemeral/witx/typenames.witx | 608 +++++++++--------- .../witx/wasi_ephemeral_preview.witx | 306 ++++----- .../phases/old/snapshot_0/witx/typenames.witx | 604 ++++++++--------- .../old/snapshot_0/witx/wasi_unstable.witx | 306 ++++----- .../phases/snapshot/witx/typenames.witx | 608 +++++++++--------- .../snapshot/witx/wasi_snapshot_preview1.witx | 306 ++++----- proposals/filesystem/tools/witx/tests/wasi.rs | 5 - 7 files changed, 1369 insertions(+), 1374 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index a614d8528..00ae3d15e 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -5,29 +5,29 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(typename $size_t u32) +(typename $size u32) ;;; Non-negative file size or length of a region within a file. -(typename $filesize_t u64) +(typename $filesize u64) ;;; Timestamp in nanoseconds. -(typename $timestamp_t u64) +(typename $timestamp u64) ;;; Identifiers for clocks. -(typename $clockid_t +(typename $clockid (enum u32 ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME + $realtime ;;; The store-wide monotonic clock, which is defined as a clock measuring ;;; real time, whose value cannot be adjusted and which cannot have negative ;;; clock jumps. The epoch of this clock is undefined. The absolute time ;;; value of this clock therefore has no meaning. - $CLOCK_MONOTONIC + $monotonic ;;; The CPU-time clock associated with the current process. - $CLOCK_PROCESS_CPUTIME_ID + $process_cputime_id ;;; The CPU-time clock associated with the current thread. - $CLOCK_THREAD_CPUTIME_ID + $thread_cputime_id ) ) @@ -35,732 +35,732 @@ ;;; Not all of these error codes are returned by the functions provided by this ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. -(typename $errno_t +(typename $errno (enum u16 ;;; No error occurred. System call completed successfully. - $ESUCCESS + $success ;;; Argument list too long. - $E2BIG + $2big ;;; Permission denied. - $EACCES + $acces ;;; Address in use. - $EADDRINUSE + $addrinuse ;;; Address not available. - $EADDRNOTAVAIL + $addrnotavail ;;; Address family not supported. - $EAFNOSUPPORT + $afnosupport ;;; Resource unavailable, or operation would block. - $EAGAIN + $again ;;; Connection already in progress. - $EALREADY + $already ;;; Bad file descriptor. - $EBADF + $badf ;;; Bad message. - $EBADMSG + $badmsg ;;; Device or resource busy. - $EBUSY + $busy ;;; Operation canceled. - $ECANCELED + $canceled ;;; No child processes. - $ECHILD + $child ;;; Connection aborted. - $ECONNABORTED + $connaborted ;;; Connection refused. - $ECONNREFUSED + $connrefused ;;; Connection reset. - $ECONNRESET + $connreset ;;; Resource deadlock would occur. - $EDEADLK + $deadlk ;;; Destination address required. - $EDESTADDRREQ + $destaddrreq ;;; Mathematics argument out of domain of function. - $EDOM + $dom ;;; Reserved. - $EDQUOT + $dquot ;;; File exists. - $EEXIST + $exist ;;; Bad address. - $EFAULT + $fault ;;; File too large. - $EFBIG + $fbig ;;; Host is unreachable. - $EHOSTUNREACH + $hostunreach ;;; Identifier removed. - $EIDRM + $idrm ;;; Illegal byte sequence. - $EILSEQ + $ilseq ;;; Operation in progress. - $EINPROGRESS + $inprogress ;;; Interrupted function. - $EINTR + $intr ;;; Invalid argument. - $EINVAL + $inval ;;; I/O error. - $EIO + $io ;;; Socket is connected. - $EISCONN + $isconn ;;; Is a directory. - $EISDIR + $isdir ;;; Too many levels of symbolic links. - $ELOOP + $loop ;;; File descriptor value too large. - $EMFILE + $mfile ;;; Too many links. - $EMLINK + $mlink ;;; Message too large. - $EMSGSIZE + $msgsize ;;; Reserved. - $EMULTIHOP + $multihop ;;; Filename too long. - $ENAMETOOLONG + $nametoolong ;;; Network is down. - $ENETDOWN + $netdown ;;; Connection aborted by network. - $ENETRESET + $netreset ;;; Network unreachable. - $ENETUNREACH + $netunreach ;;; Too many files open in system. - $ENFILE + $nfile ;;; No buffer space available. - $ENOBUFS + $nobufs ;;; No such device. - $ENODEV + $nodev ;;; No such file or directory. - $ENOENT + $noent ;;; Executable file format error. - $ENOEXEC + $noexec ;;; No locks available. - $ENOLCK + $nolck ;;; Reserved. - $ENOLINK + $nolink ;;; Not enough space. - $ENOMEM + $nomem ;;; No message of the desired type. - $ENOMSG + $nomsg ;;; Protocol not available. - $ENOPROTOOPT + $noprotoopt ;;; No space left on device. - $ENOSPC + $nospc ;;; Function not supported. - $ENOSYS + $nosys ;;; The socket is not connected. - $ENOTCONN + $notconn ;;; Not a directory or a symbolic link to a directory. - $ENOTDIR + $notdir ;;; Directory not empty. - $ENOTEMPTY + $notempty ;;; State not recoverable. - $ENOTRECOVERABLE + $notrecoverable ;;; Not a socket. - $ENOTSOCK + $notsock ;;; Not supported, or operation not supported on socket. - $ENOTSUP + $notsup ;;; Inappropriate I/O control operation. - $ENOTTY + $notty ;;; No such device or address. - $ENXIO + $nxio ;;; Value too large to be stored in data type. - $EOVERFLOW + $overflow ;;; Previous owner died. - $EOWNERDEAD + $ownerdead ;;; Operation not permitted. - $EPERM + $perm ;;; Broken pipe. - $EPIPE + $pipe ;;; Protocol error. - $EPROTO + $proto ;;; Protocol not supported. - $EPROTONOSUPPORT + $protonosupport ;;; Protocol wrong type for socket. - $EPROTOTYPE + $prototype ;;; Result too large. - $ERANGE + $range ;;; Read-only file system. - $EROFS + $rofs ;;; Invalid seek. - $ESPIPE + $spipe ;;; No such process. - $ESRCH + $srch ;;; Reserved. - $ESTALE + $stale ;;; Connection timed out. - $ETIMEDOUT + $timedout ;;; Text file busy. - $ETXTBSY + $txtbsy ;;; Cross-device link. - $EXDEV + $xdev ;;; Extension: Capabilities insufficient. - $ENOTCAPABLE + $notcapable ) ) ;;; File descriptor rights, determining which actions may be performed. -(typename $rights_t +(typename $rights (flags u64 ;;; The right to invoke `fd_datasync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_DSYNC`. - $RIGHT_FD_DATASYNC + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflag::dsync`. + $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - $RIGHT_FD_READ - ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - $RIGHT_FD_SEEK + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. + $fd_read + ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. + $fd_seek ;;; The right to invoke `fd_fdstat_set_flags`. - $RIGHT_FD_FDSTAT_SET_FLAGS + $fd_fdstat_set_flags ;;; The right to invoke `fd_sync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - $RIGHT_FD_SYNC + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflag::rsync` and `fdflag::dsync`. + $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;;; invoke `fd_tell`. - $RIGHT_FD_TELL + $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - $RIGHT_FD_WRITE + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. + $fd_write ;;; The right to invoke `fd_advise`. - $RIGHT_FD_ADVISE + $fd_advise ;;; The right to invoke `fd_allocate`. - $RIGHT_FD_ALLOCATE + $fd_allocate ;;; The right to invoke `path_create_directory`. - $RIGHT_PATH_CREATE_DIRECTORY - ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - $RIGHT_PATH_CREATE_FILE + $path_create_directory + ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::creat`. + $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. - $RIGHT_PATH_LINK_SOURCE + $path_link_source ;;; The right to invoke `path_link` with the file descriptor as the ;;; target directory. - $RIGHT_PATH_LINK_TARGET + $path_link_target ;;; The right to invoke `path_open`. - $RIGHT_PATH_OPEN + $path_open ;;; The right to invoke `fd_readdir`. - $RIGHT_FD_READDIR + $fd_readdir ;;; The right to invoke `path_readlink`. - $RIGHT_PATH_READLINK + $path_readlink ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $RIGHT_PATH_RENAME_SOURCE + $path_rename_source ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $RIGHT_PATH_RENAME_TARGET + $path_rename_target ;;; The right to invoke `path_filestat_get`. - $RIGHT_PATH_FILESTAT_GET + $path_filestat_get ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - $RIGHT_PATH_FILESTAT_SET_SIZE + ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. + $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. - $RIGHT_PATH_FILESTAT_SET_TIMES + $path_filestat_set_times ;;; The right to invoke `fd_filestat_get`. - $RIGHT_FD_FILESTAT_GET + $fd_filestat_get ;;; The right to invoke `fd_filestat_set_size`. - $RIGHT_FD_FILESTAT_SET_SIZE + $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. - $RIGHT_FD_FILESTAT_SET_TIMES + $fd_filestat_set_times ;;; The right to invoke `path_symlink`. - $RIGHT_PATH_SYMLINK + $path_symlink ;;; The right to invoke `path_remove_directory`. - $RIGHT_PATH_REMOVE_DIRECTORY + $path_remove_directory ;;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE - ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - $RIGHT_POLL_FD_READWRITE + $path_unlink_file + ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. + ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. + $poll_fd_readwrite ;;; The right to invoke `sock_shutdown`. - $RIGHT_SOCK_SHUTDOWN + $sock_shutdown ) ) ;;; A file descriptor index. -(typename $fd_t u32) +(typename $fd u32) ;;; A region of memory for scatter/gather reads. -(typename $iovec_t +(typename $iovec (struct ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. - (field $buf_len $size_t) + (field $buf_len $size) ) ) ;;; A region of memory for scatter/gather writes. -(typename $ciovec_t +(typename $ciovec (struct ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. - (field $buf_len $size_t) + (field $buf_len $size) ) ) -(typename $iovec_t_array (array $iovec_t)) -(typename $ciovec_t_array (array $ciovec_t)) +(typename $iovec_array (array $iovec)) +(typename $ciovec_array (array $ciovec)) ;;; Relative offset within a file. -(typename $filedelta_t s64) +(typename $filedelta s64) ;;; The position relative to which to set the offset of the file descriptor. -(typename $whence_t +(typename $whence (enum u8 ;;; Seek relative to start-of-file. - $WHENCE_SET + $set ;;; Seek relative to current position. - $WHENCE_CUR + $cur ;;; Seek relative to end-of-file. - $WHENCE_END + $end ) ) ;;; A reference to the offset of a directory entry. ;; ;;; The value 0 signifies the start of the directory. -(typename $dircookie_t u64) +(typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent_t. -(typename $dirnamlen_t u32) +;;; The type for the $d_namlen field of $dirent. +(typename $dirnamlen u32) ;;; File serial number that is unique within its file system. -(typename $inode_t u64) +(typename $inode u64) ;;; The type of a file descriptor or file. -(typename $filetype_t +(typename $filetype (enum u8 ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $FILETYPE_UNKNOWN + $unknown ;;; The file descriptor or file refers to a block device inode. - $FILETYPE_BLOCK_DEVICE + $block_device ;;; The file descriptor or file refers to a character device inode. - $FILETYPE_CHARACTER_DEVICE + $character_device ;;; The file descriptor or file refers to a directory inode. - $FILETYPE_DIRECTORY + $directory ;;; The file descriptor or file refers to a regular file inode. - $FILETYPE_REGULAR_FILE + $regular_file ;;; The file descriptor or file refers to a datagram socket. - $FILETYPE_SOCKET_DGRAM + $socket_dgram ;;; The file descriptor or file refers to a byte-stream socket. - $FILETYPE_SOCKET_STREAM + $socket_stream ;;; The file refers to a symbolic link inode. - $FILETYPE_SYMBOLIC_LINK + $symbolic_link ) ) ;;; A directory entry. -(typename $dirent_t +(typename $dirent (struct ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie_t) + (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode_t) + (field $d_ino $inode) ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen_t) + (field $d_namlen $dirnamlen) ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype_t) + (field $d_type $filetype) ) ) ;;; File or memory access pattern advisory information. -(typename $advice_t +(typename $advice (enum u8 ;;; The application has no advice to give on its behavior with respect to the specified data. - $ADVICE_NORMAL + $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $ADVICE_SEQUENTIAL + $sequential ;;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM + $random ;;; The application expects to access the specified data in the near future. - $ADVICE_WILLNEED + $willneed ;;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED + $dontneed ;;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE + $noreuse ) ) ;;; File descriptor flags. -(typename $fdflags_t +(typename $fdflags (flags u16 ;;; Append mode: Data written to the file is always appended to the file's end. - $FDFLAG_APPEND + $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $FDFLAG_DSYNC + $dsync ;;; Non-blocking mode. - $FDFLAG_NONBLOCK + $nonblock ;;; Synchronized read I/O operations. - $FDFLAG_RSYNC + $rsync ;;; Write according to synchronized I/O file integrity completion. In ;;; addition to synchronizing the data stored in the file, the implementation ;;; may also synchronously update the file's metadata. - $FDFLAG_SYNC + $sync ) ) ;;; File descriptor attributes. -(typename $fdstat_t +(typename $fdstat (struct ;;; File type. - (field $fs_filetype $filetype_t) + (field $fs_filetype $filetype) ;;; File descriptor flags. - (field $fs_flags $fdflags_t) + (field $fs_flags $fdflags) ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights_t) + (field $fs_rights_base $rights) ;;; Maximum set of rights that may be installed on new file descriptors that ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights_t) + (field $fs_rights_inheriting $rights) ) ) ;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode_t` to uniquely identify a file or directory in the filesystem. -(typename $device_t u64) +;;; with `inode` to uniquely identify a file or directory in the filesystem. +(typename $device u64) ;;; Which file time attributes to adjust. -(typename $fstflags_t +(typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - $FILESTAT_SET_ATIM - ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_ATIM_NOW - ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - $FILESTAT_SET_MTIM - ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_MTIM_NOW + ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + $atim + ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + $atim_now + ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + $mtim + ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + $mtim_now ) ) ;;; Flags determining the method of how paths are resolved. -(typename $lookupflags_t +(typename $lookupflags (flags u32 ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $LOOKUP_SYMLINK_FOLLOW + $symlink_follow ) ) ;;; Open flags used by `path_open`. -(typename $oflags_t +(typename $oflags (flags u16 ;;; Create file if it does not exist. - $O_CREAT + $creat ;;; Fail if not a directory. - $O_DIRECTORY + $directory ;;; Fail if file already exists. - $O_EXCL + $excl ;;; Truncate file to size 0. - $O_TRUNC + $trunc ) ) ;;; Number of hard links to an inode. -(typename $linkcount_t u64) +(typename $linkcount u64) ;;; File attributes. -(typename $filestat_t +(typename $filestat (struct ;;; Device ID of device containing the file. - (field $st_dev $device_t) + (field $dev $device) ;;; File serial number. - (field $st_ino $inode_t) + (field $ino $inode) ;;; File type. - (field $st_filetype $filetype_t) + (field $filetype $filetype) ;;; Number of hard links to the file. - (field $st_nlink $linkcount_t) + (field $nlink $linkcount) ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $st_size $filesize_t) + (field $size $filesize) ;;; Last data access timestamp. - (field $st_atim $timestamp_t) + (field $atim $timestamp) ;;; Last data modification timestamp. - (field $st_mtim $timestamp_t) + (field $mtim $timestamp) ;;; Last file status change timestamp. - (field $st_ctim $timestamp_t) + (field $ctim $timestamp) ) ) ;;; User-provided value that may be attached to objects that is retained when ;;; extracted from the implementation. -(typename $userdata_t u64) +(typename $userdata u64) ;;; Type of a subscription to an event or its occurrence. -(typename $eventtype_t +(typename $eventtype (enum u8 - ;;; The time value of clock `subscription_t::u.clock.clock_id` has - ;;; reached timestamp `subscription_t::u.clock.timeout`. - $EVENTTYPE_CLOCK - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; The time value of clock `subscription::u.clock.clock_id` has + ;;; reached timestamp `subscription::u.clock.timeout`. + $clock + ;;; File descriptor `subscription::u.fd_readwrite.fd` has data ;;; available for reading. This event always triggers for regular files. - $EVENTTYPE_FD_READ - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + $fd_read + ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity ;;; available for writing. This event always triggers for regular files. - $EVENTTYPE_FD_WRITE + $fd_write ) ) ;;; The state of the file descriptor subscribed to with -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $eventrwflags_t +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $eventrwflags (flags u16 ;;; The peer of this socket has closed or disconnected. - $EVENT_FD_READWRITE_HANGUP + $fd_readwrite_hangup ) ) -;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;;; `EVENTTYPE_FD_WRITE`. -(typename $event_fd_readwrite_t +;;; The contents of an $event when type is `eventtype::fd_read` or +;;; `eventtype::fd_write`. +(typename $event_fd_readwrite (struct ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) + (field $nbytes $filesize) ;;; The state of the file descriptor. - (field $flags $eventrwflags_t) + (field $flags $eventrwflags) ) ) -;;; The contents of an $event_t. +;;; The contents of an $event. (typename $event_u (union - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $event_fd_readwrite_t) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $event_fd_readwrite) ) ) ;;; An event that occurred. -(typename $event_t +(typename $event (struct - ;;; User-provided value that got attached to `subscription_t::userdata`. - (field $userdata $userdata_t) + ;;; User-provided value that got attached to `subscription::userdata`. + (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno_t) + (field $error $errno) ;;; The type of the event that occurred. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the event. (field $u $event_u) ) ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_t::u.clock.timeout.` -(typename $subclockflags_t +;;; `subscription::u.clock.timeout.` +(typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription_t::u.clock.timeout` relative to the - ;;; current time value of clock `subscription_t::u.clock.clock_id.` - $SUBSCRIPTION_CLOCK_ABSTIME + ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription::u.clock.timeout` relative to the + ;;; current time value of clock `subscription::u.clock.clock_id.` + $subscription_clock_abstime ) ) -;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. -(typename $subscription_clock_t +;;; The contents of a $subscription when type is `eventtype::clock`. +(typename $subscription_clock (struct ;;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) + (field $id $clockid) ;;; The absolute or relative timestamp. - (field $timeout $timestamp_t) + (field $timeout $timestamp) ;;; The amount of time that the implementation may wait additionally ;;; to coalesce with other events. - (field $precision $timestamp_t) + (field $precision $timestamp) ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags_t) + (field $flags $subclockflags) ) ) -;;; The contents of a $subscription_t when type is type is -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $subscription_fd_readwrite_t +;;; The contents of a $subscription when type is type is +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $subscription_fd_readwrite (struct ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) + (field $file_descriptor $fd) ) ) -;;; The contents of a $subscription_t. +;;; The contents of a $subscription. (typename $subscription_u (union - ;;; When type is `EVENTTYPE_CLOCK`: - (field $clock $subscription_clock_t) - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $subscription_fd_readwrite_t) + ;;; When type is `eventtype::clock`: + (field $clock $subscription_clock) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $subscription_fd_readwrite) ) ) ;;; Subscription to an event. -(typename $subscription_t +(typename $subscription (struct ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event_t::userdata`. - (field $userdata $userdata_t) + ;;; implementation and returned through `event::userdata`. + (field $userdata $userdata) ;;; The type of the event to which to subscribe. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the subscription. (field $u $subscription_u) ) ) ;;; Exit code generated by a process when exiting. -(typename $exitcode_t u32) +(typename $exitcode u32) ;;; Signal condition. -(typename $signal_t +(typename $signal (enum u8 ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. - $SIGNONE + $none ;;; Hangup. ;;; Action: Terminates the process. - $SIGHUP + $hup ;;; Terminate interrupt signal. ;;; Action: Terminates the process. - $SIGINT + $int ;;; Terminal quit signal. ;;; Action: Terminates the process. - $SIGQUIT + $quit ;;; Illegal instruction. ;;; Action: Terminates the process. - $SIGILL + $ill ;;; Trace/breakpoint trap. ;;; Action: Terminates the process. - $SIGTRAP + $trap ;;; Process abort signal. ;;; Action: Terminates the process. - $SIGABRT + $abrt ;;; Access to an undefined portion of a memory object. ;;; Action: Terminates the process. - $SIGBUS + $bus ;;; Erroneous arithmetic operation. ;;; Action: Terminates the process. - $SIGFPE + $fpe ;;; Kill. ;;; Action: Terminates the process. - $SIGKILL + $kill ;;; User-defined signal 1. ;;; Action: Terminates the process. - $SIGUSR1 + $usr1 ;;; Invalid memory reference. ;;; Action: Terminates the process. - $SIGSEGV + $segv ;;; User-defined signal 2. ;;; Action: Terminates the process. - $SIGUSR2 + $usr2 ;;; Write on a pipe with no one to read it. ;;; Action: Ignored. - $SIGPIPE + $pipe ;;; Alarm clock. ;;; Action: Terminates the process. - $SIGALRM + $alrm ;;; Termination signal. ;;; Action: Terminates the process. - $SIGTERM + $term ;;; Child process terminated, stopped, or continued. ;;; Action: Ignored. - $SIGCHLD + $chld ;;; Continue executing, if stopped. ;;; Action: Continues executing, if stopped. - $SIGCONT + $cont ;;; Stop executing. ;;; Action: Stops executing. - $SIGSTOP + $stop ;;; Terminal stop signal. ;;; Action: Stops executing. - $SIGTSTP + $tstp ;;; Background process attempting read. ;;; Action: Stops executing. - $SIGTTIN + $ttin ;;; Background process attempting write. ;;; Action: Stops executing. - $SIGTTOU + $ttou ;;; High bandwidth data is available at a socket. ;;; Action: Ignored. - $SIGURG + $urg ;;; CPU time limit exceeded. ;;; Action: Terminates the process. - $SIGXCPU + $xcpu ;;; File size limit exceeded. ;;; Action: Terminates the process. - $SIGXFSZ + $xfsz ;;; Virtual timer expired. ;;; Action: Terminates the process. - $SIGVTALRM + $vtalrm ;;; Profiling timer expired. ;;; Action: Terminates the process. - $SIGPROF + $prof ;;; Window changed. ;;; Action: Ignored. - $SIGWINCH + $winch ;;; I/O possible. ;;; Action: Terminates the process. - $SIGPOLL + $poll ;;; Power failure. ;;; Action: Terminates the process. - $SIGPWR + $pwr ;;; Bad system call. ;;; Action: Terminates the process. - $SIGSYS + $sys ) ) ;;; Flags provided to `sock_recv`. -(typename $riflags_t +(typename $riflags (flags u16 ;;; Returns the message without removing it from the socket's receive queue. - $SOCK_RECV_PEEK + $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. - $SOCK_RECV_WAITALL + $recv_waitall ) ) ;;; Flags returned by `sock_recv`. -(typename $roflags_t +(typename $roflags (flags u16 ;;; Returned by `sock_recv`: Message data has been truncated. - $SOCK_RECV_DATA_TRUNCATED + $recv_data_truncated ) ) ;;; Flags provided to `sock_send`. As there are currently no flags ;;; defined, it must be set to zero. -(typename $siflags_t u16) +(typename $siflags u16) ;;; Which channels on a socket to shut down. -(typename $sdflags_t +(typename $sdflags (flags u8 ;;; Disables further receive operations. - $SHUT_RD + $rd ;;; Disables further send operations. - $SHUT_WR + $wr ) ) ;;; Identifiers for preopened capabilities. -(typename $preopentype_t +(typename $preopentype (enum u8 ;;; A pre-opened directory. - $PREOPENTYPE_DIR + $dir ) ) -;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size_t) + (field $pr_name_len $size) ) ) -;;; The contents of an $prestat_t. +;;; The contents of an $prestat. (typename $prestat_u (union - ;;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `preopentype::dir`: (field $dir $prestat_dir) ) ) ;;; Information about a pre-opened capability. -(typename $prestat_t +(typename $prestat (struct ;;; The type of the pre-opened capability. - (field $pr_type $preopentype_t) + (field $pr_type $preopentype) ;;; The contents of the information. (field $u $prestat_u) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx index d15b8c514..43bd57e4b 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -17,15 +17,15 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Read environment variable data. @@ -33,187 +33,187 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Return the resolution of a clock. ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno_t) + (result $error $errno) ;;; The clock for which to return the resolution. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The resolution of the clock. - (result $resolution $timestamp_t) + (result $resolution $timestamp) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") ;;; The clock for which to return the time. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp_t) - (result $error $errno_t) + (param $precision $timestamp) + (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp_t) + (result $time $timestamp) ) ;;; Provide file advisory information on a file descriptor. ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset within the file to which the advisory applies. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the region to which the advisory applies. - (param $len $filesize_t) + (param $len $filesize) ;;; The advice. - (param $advice $advice_t) - (result $error $errno_t) + (param $advice $advice) + (result $error $errno) ) ;;; Force the allocation of space in a file. ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset at which to start the allocation. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the area that is allocated. - (param $len $filesize_t) - (result $error $errno_t) + (param $len $filesize) + (result $error $errno) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat_t) + (result $stat $fdstat) ) ;;; Adjust the flags associated with a file descriptor. ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the file descriptor flags. - (param $flags $fdflags_t) - (result $error $errno_t) + (param $flags $fdflags) + (result $error $errno) ) ;;; Adjust the rights associated with a file descriptor. ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights_t) - (param $fs_rights_inheriting $rights_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inheriting $rights) + (result $error $errno) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired file size. - (param $st_size $filesize_t) - (result $error $errno_t) + (param $size $filesize) + (result $error $errno) ) ;;; Adjust the timestamps of an open file or directory. ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_t_array) + (param $iovs $iovec_array) ;;; The offset within the file at which to read. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat_t) + (result $buf $prestat) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") - (param $fd $fd_t) + (param $fd $fd) ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) - (param $path_len $size_t) - (result $error $errno_t) + (param $path_len $size) + (result $error $errno) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) + (param $iovs $ciovec_array) ;;; The offset within the file at which to write. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Read from a file descriptor. ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_t_array) - (result $error $errno_t) + (param $iovs $iovec_array) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Read directory entries from a directory. @@ -227,15 +227,15 @@ ;;; read buffer size in case it's too small to fit a single large directory ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") - (param $fd $fd_t) + (param $fd $fd) ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) - (param $buf_len $size_t) + (param $buf_len $size) ;;; The location within the directory to start reading - (param $cookie $dircookie_t) - (result $error $errno_t) + (param $cookie $dircookie) + (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -249,104 +249,104 @@ ;;; This function provides a way to atomically renumber file descriptors, which ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") - (param $fd $fd_t) + (param $fd $fd) ;;; The file descriptor to overwrite. - (param $to $fd_t) - (result $error $errno_t) + (param $to $fd) + (result $error $errno) ) ;;; Move the offset of a file descriptor. ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") - (param $fd $fd_t) + (param $fd $fd) ;;; The number of bytes to move. - (param $offset $filedelta_t) + (param $offset $filedelta) ;;; The base from which the offset is relative. - (param $whence $whence_t) - (result $error $errno_t) + (param $whence $whence) + (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize_t) + (result $newoffset $filesize) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize_t) + (result $offset $filesize) ) ;;; Write to a file descriptor. ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) - (result $error $errno_t) + (param $iovs $ciovec_array) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Create a directory. ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Return the attributes of a file or directory. ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno_t) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the timestamps of a file or directory. ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to operate on. (param $path string) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Create a hard link. ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $old_fd $fd_t) + (param $old_fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags_t) + (param $old_flags $lookupflags) ;;; The source path from which to link. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Open a file or directory. @@ -359,14 +359,14 @@ ;; ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags_t) + (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the ;;; `dirfd` directory. (param $path string) ;;; The method by which to open the file. - (param $o_flags $oflags_t) + (param $oflags $oflags) ;;; The initial rights of the newly created file descriptor. The ;;; implementation is allowed to return a file descriptor with fewer rights ;;; than specified, if and only if those rights do not apply to the type of @@ -375,49 +375,49 @@ ;;; The *base* rights are rights that will apply to operations using the file ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. - (param $fs_rights_base $rights_t) - (param $fs_rights_inherting $rights_t) - (param $flags $fdflags_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inherting $rights) + (param $fdflags $fdflags) + (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd_t) + (result $opened_fd $fd) ) ;;; Read the contents of a symbolic link. ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") - (param $fd $fd_t) + (param $fd $fd) ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Remove a directory. ;;; Return `ENOTEMPTY` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Rename a file or directory. ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") - (param $fd $fd_t) + (param $fd $fd) ;;; The source path of the file or directory to rename. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Create a symbolic link. @@ -425,10 +425,10 @@ (@interface func (export "path_symlink") ;;; The contents of the symbolic link. (param $old_path string) - (param $fd $fd_t) + (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) @@ -436,23 +436,23 @@ ;;; Return `EISDIR` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription_t)) + (param $in (@witx const_pointer $subscription)) ;;; The events that have occurred. - (param $out (@witx pointer $event_t)) + (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size_t) - (result $error $errno_t) + (param $nsubscriptions $size) + (result $error $errno) ;;; The number of events stored. - (result $nevents $size_t) + (result $nevents $size) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -460,21 +460,21 @@ ;;; the environment. (@interface func (export "proc_exit") ;;; The exit code returned by the process. - (param $rval $exitcode_t) + (param $rval $exitcode) ) ;;; Send a signal to the process of the calling thread. ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") ;;; The signal condition to trigger. - (param $sig $signal_t) - (result $error $errno_t) + (param $sig $signal) + (result $error $errno) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno_t) + (result $error $errno) ) ;;; Write high-quality random data into a buffer. @@ -486,46 +486,46 @@ (@interface func (export "random_get") ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ) ;;; Receive a message from a socket. ;;; Note: This is similar to `recv` in POSIX, though it also supports reading ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_t_array) + (param $ri_data $iovec_array) ;;; Message flags. - (param $ri_flags $riflags_t) - (result $error $errno_t) + (param $ri_flags $riflags) + (result $error $errno) ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size_t) + (result $ro_datalen $size) ;;; Message flags. - (result $ro_flags $roflags_t) + (result $ro_flags $roflags) ) ;;; Send a message on a socket. ;;; Note: This is similar to `send` in POSIX, though it also supports writing ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_t_array) + (param $si_data $ciovec_array) ;;; Message flags. - (param $si_flags $siflags_t) - (result $error $errno_t) + (param $si_flags $siflags) + (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size_t) + (result $so_datalen $size) ) ;;; Shut down socket send and receive channels. ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") - (param $fd $fd_t) + (param $fd $fd) ;;; Which channels on the socket to shut down. - (param $how $sdflags_t) - (result $error $errno_t) + (param $how $sdflags) + (result $error $errno) ) ) diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx index cf39a2deb..9a7fc0bb2 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx @@ -5,29 +5,29 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(typename $size_t u32) +(typename $size u32) ;;; Non-negative file size or length of a region within a file. -(typename $filesize_t u64) +(typename $filesize u64) ;;; Timestamp in nanoseconds. -(typename $timestamp_t u64) +(typename $timestamp u64) ;;; Identifiers for clocks. -(typename $clockid_t +(typename $clockid (enum u32 ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME + $realtime ;;; The store-wide monotonic clock, which is defined as a clock measuring ;;; real time, whose value cannot be adjusted and which cannot have negative ;;; clock jumps. The epoch of this clock is undefined. The absolute time ;;; value of this clock therefore has no meaning. - $CLOCK_MONOTONIC + $monotonic ;;; The CPU-time clock associated with the current process. - $CLOCK_PROCESS_CPUTIME_ID + $process_cputime_id ;;; The CPU-time clock associated with the current thread. - $CLOCK_THREAD_CPUTIME_ID + $thread_cputime_id ) ) @@ -35,720 +35,720 @@ ;;; Not all of these error codes are returned by the functions provided by this ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. -(typename $errno_t +(typename $errno (enum u16 ;;; No error occurred. System call completed successfully. - $ESUCCESS + $success ;;; Argument list too long. - $E2BIG + $2big ;;; Permission denied. - $EACCES + $acces ;;; Address in use. - $EADDRINUSE + $addrinuse ;;; Address not available. - $EADDRNOTAVAIL + $addrnotavail ;;; Address family not supported. - $EAFNOSUPPORT + $afnosupport ;;; Resource unavailable, or operation would block. - $EAGAIN + $again ;;; Connection already in progress. - $EALREADY + $already ;;; Bad file descriptor. - $EBADF + $badf ;;; Bad message. - $EBADMSG + $badmsg ;;; Device or resource busy. - $EBUSY + $busy ;;; Operation canceled. - $ECANCELED + $canceled ;;; No child processes. - $ECHILD + $child ;;; Connection aborted. - $ECONNABORTED + $connaborted ;;; Connection refused. - $ECONNREFUSED + $connrefused ;;; Connection reset. - $ECONNRESET + $connreset ;;; Resource deadlock would occur. - $EDEADLK + $deadlk ;;; Destination address required. - $EDESTADDRREQ + $destaddrreq ;;; Mathematics argument out of domain of function. - $EDOM + $dom ;;; Reserved. - $EDQUOT + $dquot ;;; File exists. - $EEXIST + $exist ;;; Bad address. - $EFAULT + $fault ;;; File too large. - $EFBIG + $fbig ;;; Host is unreachable. - $EHOSTUNREACH + $hostunreach ;;; Identifier removed. - $EIDRM + $idrm ;;; Illegal byte sequence. - $EILSEQ + $ilseq ;;; Operation in progress. - $EINPROGRESS + $inprogress ;;; Interrupted function. - $EINTR + $intr ;;; Invalid argument. - $EINVAL + $inval ;;; I/O error. - $EIO + $io ;;; Socket is connected. - $EISCONN + $isconn ;;; Is a directory. - $EISDIR + $isdir ;;; Too many levels of symbolic links. - $ELOOP + $loop ;;; File descriptor value too large. - $EMFILE + $mfile ;;; Too many links. - $EMLINK + $mlink ;;; Message too large. - $EMSGSIZE + $msgsize ;;; Reserved. - $EMULTIHOP + $multihop ;;; Filename too long. - $ENAMETOOLONG + $nametoolong ;;; Network is down. - $ENETDOWN + $netdown ;;; Connection aborted by network. - $ENETRESET + $netreset ;;; Network unreachable. - $ENETUNREACH + $netunreach ;;; Too many files open in system. - $ENFILE + $nfile ;;; No buffer space available. - $ENOBUFS + $nobufs ;;; No such device. - $ENODEV + $nodev ;;; No such file or directory. - $ENOENT + $noent ;;; Executable file format error. - $ENOEXEC + $noexec ;;; No locks available. - $ENOLCK + $nolck ;;; Reserved. - $ENOLINK + $nolink ;;; Not enough space. - $ENOMEM + $nomem ;;; No message of the desired type. - $ENOMSG + $nomsg ;;; Protocol not available. - $ENOPROTOOPT + $noprotoopt ;;; No space left on device. - $ENOSPC + $nospc ;;; Function not supported. - $ENOSYS + $nosys ;;; The socket is not connected. - $ENOTCONN + $notconn ;;; Not a directory or a symbolic link to a directory. - $ENOTDIR + $notdir ;;; Directory not empty. - $ENOTEMPTY + $notempty ;;; State not recoverable. - $ENOTRECOVERABLE + $notrecoverable ;;; Not a socket. - $ENOTSOCK + $notsock ;;; Not supported, or operation not supported on socket. - $ENOTSUP + $notsup ;;; Inappropriate I/O control operation. - $ENOTTY + $notty ;;; No such device or address. - $ENXIO + $nxio ;;; Value too large to be stored in data type. - $EOVERFLOW + $overflow ;;; Previous owner died. - $EOWNERDEAD + $ownerdead ;;; Operation not permitted. - $EPERM + $perm ;;; Broken pipe. - $EPIPE + $pipe ;;; Protocol error. - $EPROTO + $proto ;;; Protocol not supported. - $EPROTONOSUPPORT + $protonosupport ;;; Protocol wrong type for socket. - $EPROTOTYPE + $prototype ;;; Result too large. - $ERANGE + $range ;;; Read-only file system. - $EROFS + $rofs ;;; Invalid seek. - $ESPIPE + $spipe ;;; No such process. - $ESRCH + $srch ;;; Reserved. - $ESTALE + $stale ;;; Connection timed out. - $ETIMEDOUT + $timedout ;;; Text file busy. - $ETXTBSY + $txtbsy ;;; Cross-device link. - $EXDEV + $xdev ;;; Extension: Capabilities insufficient. - $ENOTCAPABLE + $notcapable ) ) ;;; File descriptor rights, determining which actions may be performed. -(typename $rights_t +(typename $rights (flags u64 ;;; The right to invoke `fd_datasync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; If `rights::path_open` is set, includes the right to invoke ;;; `path_open` with `FDFLAG_DSYNC`. - $RIGHT_FD_DATASYNC + $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - $RIGHT_FD_READ - ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - $RIGHT_FD_SEEK + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. + $fd_read + ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. + $fd_seek ;;; The right to invoke `fd_fdstat_set_flags`. - $RIGHT_FD_FDSTAT_SET_FLAGS + $fd_fdstat_set_flags ;;; The right to invoke `fd_sync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke + ;;; If `rights::path_open` is set, includes the right to invoke ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - $RIGHT_FD_SYNC + $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;;; invoke `fd_tell`. - $RIGHT_FD_TELL + $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - $RIGHT_FD_WRITE + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. + $fd_write ;;; The right to invoke `fd_advise`. - $RIGHT_FD_ADVISE + $fd_advise ;;; The right to invoke `fd_allocate`. - $RIGHT_FD_ALLOCATE + $fd_allocate ;;; The right to invoke `path_create_directory`. - $RIGHT_PATH_CREATE_DIRECTORY - ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - $RIGHT_PATH_CREATE_FILE + $path_create_directory + ;;; If `rights::path_open` is set, the right to invoke `path_open` with `O_CREAT`. + $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. - $RIGHT_PATH_LINK_SOURCE + $path_link_source ;;; The right to invoke `path_link` with the file descriptor as the ;;; target directory. - $RIGHT_PATH_LINK_TARGET + $path_link_target ;;; The right to invoke `path_open`. - $RIGHT_PATH_OPEN + $path_open ;;; The right to invoke `fd_readdir`. - $RIGHT_FD_READDIR + $fd_readdir ;;; The right to invoke `path_readlink`. - $RIGHT_PATH_READLINK + $path_readlink ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $RIGHT_PATH_RENAME_SOURCE + $path_rename_source ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $RIGHT_PATH_RENAME_TARGET + $path_rename_target ;;; The right to invoke `path_filestat_get`. - $RIGHT_PATH_FILESTAT_GET + $path_filestat_get ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - $RIGHT_PATH_FILESTAT_SET_SIZE + ;;; If `rights::path_open` is set, includes the right to invoke `path_open` with `O_TRUNC`. + $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. - $RIGHT_PATH_FILESTAT_SET_TIMES + $path_filestat_set_times ;;; The right to invoke `fd_filestat_get`. - $RIGHT_FD_FILESTAT_GET + $fd_filestat_get ;;; The right to invoke `fd_filestat_set_size`. - $RIGHT_FD_FILESTAT_SET_SIZE + $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. - $RIGHT_FD_FILESTAT_SET_TIMES + $fd_filestat_set_times ;;; The right to invoke `path_symlink`. - $RIGHT_PATH_SYMLINK + $path_symlink ;;; The right to invoke `path_remove_directory`. - $RIGHT_PATH_REMOVE_DIRECTORY + $path_remove_directory ;;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE - ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - $RIGHT_POLL_FD_READWRITE + $path_unlink_file + ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. + ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. + $poll_fd_readwrite ;;; The right to invoke `sock_shutdown`. - $RIGHT_SOCK_SHUTDOWN + $sock_shutdown ) ) ;;; A file descriptor index. -(typename $fd_t u32) +(typename $fd u32) ;;; A region of memory for scatter/gather reads. -(typename $iovec_t +(typename $iovec (struct ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. - (field $buf_len $size_t) + (field $buf_len $size) ) ) ;;; A region of memory for scatter/gather writes. -(typename $ciovec_t +(typename $ciovec (struct ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. - (field $buf_len $size_t) + (field $buf_len $size) ) ) -(typename $iovec_t_array (array $iovec_t)) -(typename $ciovec_t_array (array $ciovec_t)) +(typename $iovec_array (array $iovec)) +(typename $ciovec_array (array $ciovec)) ;;; Relative offset within a file. -(typename $filedelta_t s64) +(typename $filedelta s64) ;;; The position relative to which to set the offset of the file descriptor. -(typename $whence_t +(typename $whence (enum u8 ;;; Seek relative to current position. - $WHENCE_CUR + $cur ;;; Seek relative to end-of-file. - $WHENCE_END + $end ;;; Seek relative to start-of-file. - $WHENCE_SET + $set ) ) ;;; A reference to the offset of a directory entry. -(typename $dircookie_t u64) +(typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent_t. -(typename $dirnamlen_t u32) +;;; The type for the $d_namlen field of $dirent. +(typename $dirnamlen u32) ;;; File serial number that is unique within its file system. -(typename $inode_t u64) +(typename $inode u64) ;;; The type of a file descriptor or file. -(typename $filetype_t +(typename $filetype (enum u8 ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $FILETYPE_UNKNOWN + $unknown ;;; The file descriptor or file refers to a block device inode. - $FILETYPE_BLOCK_DEVICE + $block_device ;;; The file descriptor or file refers to a character device inode. - $FILETYPE_CHARACTER_DEVICE + $character_device ;;; The file descriptor or file refers to a directory inode. - $FILETYPE_DIRECTORY + $directory ;;; The file descriptor or file refers to a regular file inode. - $FILETYPE_REGULAR_FILE + $regular_file ;;; The file descriptor or file refers to a datagram socket. - $FILETYPE_SOCKET_DGRAM + $socket_dgram ;;; The file descriptor or file refers to a byte-stream socket. - $FILETYPE_SOCKET_STREAM + $socket_stream ;;; The file refers to a symbolic link inode. - $FILETYPE_SYMBOLIC_LINK + $symbolic_link ) ) ;;; A directory entry. -(typename $dirent_t +(typename $dirent (struct ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie_t) + (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode_t) + (field $d_ino $inode) ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen_t) + (field $d_namlen $dirnamlen) ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype_t) + (field $d_type $filetype) ) ) ;;; File or memory access pattern advisory information. -(typename $advice_t +(typename $advice (enum u8 ;;; The application has no advice to give on its behavior with respect to the specified data. - $ADVICE_NORMAL + $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $ADVICE_SEQUENTIAL + $sequential ;;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM + $random ;;; The application expects to access the specified data in the near future. - $ADVICE_WILLNEED + $willneed ;;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED + $dontneed ;;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE + $noreuse ) ) ;;; File descriptor flags. -(typename $fdflags_t +(typename $fdflags (flags u16 ;;; Append mode: Data written to the file is always appended to the file's end. - $FDFLAG_APPEND + $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $FDFLAG_DSYNC + $dsync ;;; Non-blocking mode. - $FDFLAG_NONBLOCK + $nonblock ;;; Synchronized read I/O operations. - $FDFLAG_RSYNC + $rsync ;;; Write according to synchronized I/O file integrity completion. In ;;; addition to synchronizing the data stored in the file, the implementation ;;; may also synchronously update the file's metadata. - $FDFLAG_SYNC + $sync ) ) ;;; File descriptor attributes. -(typename $fdstat_t +(typename $fdstat (struct ;;; File type. - (field $fs_filetype $filetype_t) + (field $fs_filetype $filetype) ;;; File descriptor flags. - (field $fs_flags $fdflags_t) + (field $fs_flags $fdflags) ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights_t) + (field $fs_rights_base $rights) ;;; Maximum set of rights that may be installed on new file descriptors that ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights_t) + (field $fs_rights_inheriting $rights) ) ) ;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode_t` to uniquely identify a file or directory in the filesystem. -(typename $device_t u64) +;;; with `inode` to uniquely identify a file or directory in the filesystem. +(typename $device u64) ;;; Which file time attributes to adjust. -(typename $fstflags_t +(typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - $FILESTAT_SET_ATIM - ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_ATIM_NOW - ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - $FILESTAT_SET_MTIM - ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_MTIM_NOW + ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + $atim + ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + $atim_now + ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + $mtim + ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + $mtim_now ) ) ;;; Flags determining the method of how paths are resolved. -(typename $lookupflags_t +(typename $lookupflags (flags u32 ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $LOOKUP_SYMLINK_FOLLOW + $symlink_follow ) ) ;;; Open flags used by `path_open`. -(typename $oflags_t +(typename $oflags (flags u16 ;;; Create file if it does not exist. - $O_CREAT + $creat ;;; Fail if not a directory. - $O_DIRECTORY + $directory ;;; Fail if file already exists. - $O_EXCL + $excl ;;; Truncate file to size 0. - $O_TRUNC + $trunc ) ) ;;; Number of hard links to an inode. -(typename $linkcount_t u32) +(typename $linkcount u32) ;;; File attributes. -(typename $filestat_t +(typename $filestat (struct ;;; Device ID of device containing the file. - (field $st_dev $device_t) + (field $dev $device) ;;; File serial number. - (field $st_ino $inode_t) + (field $ino $inode) ;;; File type. - (field $st_filetype $filetype_t) + (field $filetype $filetype) ;;; Number of hard links to the file. - (field $st_nlink $linkcount_t) + (field $nlink $linkcount) ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $st_size $filesize_t) + (field $size $filesize) ;;; Last data access timestamp. - (field $st_atim $timestamp_t) + (field $atim $timestamp) ;;; Last data modification timestamp. - (field $st_mtim $timestamp_t) + (field $mtim $timestamp) ;;; Last file status change timestamp. - (field $st_ctim $timestamp_t) + (field $ctim $timestamp) ) ) ;;; User-provided value that may be attached to objects that is retained when ;;; extracted from the implementation. -(typename $userdata_t u64) +(typename $userdata u64) ;;; Type of a subscription to an event or its occurrence. -(typename $eventtype_t +(typename $eventtype (enum u8 - ;;; The time value of clock `subscription_t::u.clock.clock_id` has - ;;; reached timestamp `subscription_t::u.clock.timeout`. - $EVENTTYPE_CLOCK - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; The time value of clock `subscription::u.clock.clock_id` has + ;;; reached timestamp `subscription::u.clock.timeout`. + $clock + ;;; File descriptor `subscription::u.fd_readwrite.fd` has data ;;; available for reading. This event always triggers for regular files. - $EVENTTYPE_FD_READ - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + $fd_read + ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity ;;; available for writing. This event always triggers for regular files. - $EVENTTYPE_FD_WRITE + $fd_write ) ) ;;; The state of the file descriptor subscribed to with -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $eventrwflags_t +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $eventrwflags (flags u16 ;;; The peer of this socket has closed or disconnected. - $EVENT_FD_READWRITE_HANGUP + $fd_readwrite_hangup ) ) -;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;;; `EVENTTYPE_FD_WRITE`. -(typename $event_fd_readwrite_t +;;; The contents of an $event when type is `eventtype::fd_read` or +;;; `eventtype::fd_write`. +(typename $event_fd_readwrite (struct ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) + (field $nbytes $filesize) ;;; The state of the file descriptor. - (field $flags $eventrwflags_t) + (field $flags $eventrwflags) ) ) -;;; The contents of an $event_t. +;;; The contents of an $event. (typename $event_u (union - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $event_fd_readwrite_t) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $event_fd_readwrite) ) ) ;;; An event that occurred. -(typename $event_t +(typename $event (struct - ;;; User-provided value that got attached to `subscription_t::userdata`. - (field $userdata $userdata_t) + ;;; User-provided value that got attached to `subscription::userdata`. + (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno_t) + (field $error $errno) ;;; The type of the event that occurred. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the event. (field $u $event_u) ) ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_t::u.clock.timeout.` -(typename $subclockflags_t +;;; `subscription::u.clock.timeout.` +(typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription_t::u.clock.timeout` relative to the - ;;; current time value of clock `subscription_t::u.clock.clock_id.` - $SUBSCRIPTION_CLOCK_ABSTIME + ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription::u.clock.timeout` relative to the + ;;; current time value of clock `subscription::u.clock.clock_id.` + $subscription_clock_abstime ) ) -;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. -(typename $subscription_clock_t +;;; The contents of a $subscription when type is `eventtype::clock`. +(typename $subscription_clock (struct ;;; The user-defined unique identifier of the clock. - (field $identifier $userdata_t) + (field $identifier $userdata) ;;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) + (field $id $clockid) ;;; The absolute or relative timestamp. - (field $timeout $timestamp_t) + (field $timeout $timestamp) ;;; The amount of time that the implementation may wait additionally ;;; to coalesce with other events. - (field $precision $timestamp_t) + (field $precision $timestamp) ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags_t) + (field $flags $subclockflags) ) ) -;;; The contents of a $subscription_t when type is type is -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $subscription_fd_readwrite_t +;;; The contents of a $subscription when type is type is +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $subscription_fd_readwrite (struct ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) + (field $file_descriptor $fd) ) ) -;;; The contents of a $subscription_t. +;;; The contents of a $subscription. (typename $subscription_u (union - ;;; When type is `EVENTTYPE_CLOCK`: - (field $clock $subscription_clock_t) - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $subscription_fd_readwrite_t) + ;;; When type is `eventtype::clock`: + (field $clock $subscription_clock) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $subscription_fd_readwrite) ) ) ;;; Subscription to an event. -(typename $subscription_t +(typename $subscription (struct ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event_t::userdata`. - (field $userdata $userdata_t) + ;;; implementation and returned through `event::userdata`. + (field $userdata $userdata) ;;; The type of the event to which to subscribe. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the subscription. (field $u $subscription_u) ) ) ;;; Exit code generated by a process when exiting. -(typename $exitcode_t u32) +(typename $exitcode u32) ;;; Signal condition. -(typename $signal_t +(typename $signal (enum u8 ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. - $SIGNONE + $none ;;; Hangup. ;;; Action: Terminates the process. - $SIGHUP + $hup ;;; Terminate interrupt signal. ;;; Action: Terminates the process. - $SIGINT + $int ;;; Terminal quit signal. ;;; Action: Terminates the process. - $SIGQUIT + $quit ;;; Illegal instruction. ;;; Action: Terminates the process. - $SIGILL + $ill ;;; Trace/breakpoint trap. ;;; Action: Terminates the process. - $SIGTRAP + $trap ;;; Process abort signal. ;;; Action: Terminates the process. - $SIGABRT + $abrt ;;; Access to an undefined portion of a memory object. ;;; Action: Terminates the process. - $SIGBUS + $bus ;;; Erroneous arithmetic operation. ;;; Action: Terminates the process. - $SIGFPE + $fpe ;;; Kill. ;;; Action: Terminates the process. - $SIGKILL + $kill ;;; User-defined signal 1. ;;; Action: Terminates the process. - $SIGUSR1 + $usr1 ;;; Invalid memory reference. ;;; Action: Terminates the process. - $SIGSEGV + $segv ;;; User-defined signal 2. ;;; Action: Terminates the process. - $SIGUSR2 + $usr2 ;;; Write on a pipe with no one to read it. ;;; Action: Ignored. - $SIGPIPE + $pipe ;;; Alarm clock. ;;; Action: Terminates the process. - $SIGALRM + $alrm ;;; Termination signal. ;;; Action: Terminates the process. - $SIGTERM + $term ;;; Child process terminated, stopped, or continued. ;;; Action: Ignored. - $SIGCHLD + $chld ;;; Continue executing, if stopped. ;;; Action: Continues executing, if stopped. - $SIGCONT + $cont ;;; Stop executing. ;;; Action: Stops executing. - $SIGSTOP + $stop ;;; Terminal stop signal. ;;; Action: Stops executing. - $SIGTSTP + $tstp ;;; Background process attempting read. ;;; Action: Stops executing. - $SIGTTIN + $ttin ;;; Background process attempting write. ;;; Action: Stops executing. - $SIGTTOU + $ttou ;;; High bandwidth data is available at a socket. ;;; Action: Ignored. - $SIGURG + $urg ;;; CPU time limit exceeded. ;;; Action: Terminates the process. - $SIGXCPU + $xcpu ;;; File size limit exceeded. ;;; Action: Terminates the process. - $SIGXFSZ + $xfsz ;;; Virtual timer expired. ;;; Action: Terminates the process. - $SIGVTALRM + $vtalrm ;;; Profiling timer expired. ;;; Action: Terminates the process. - $SIGPROF + $prof ;;; Window changed. ;;; Action: Ignored. - $SIGWINCH + $winch ;;; I/O possible. ;;; Action: Terminates the process. - $SIGPOLL + $poll ;;; Power failure. ;;; Action: Terminates the process. - $SIGPWR + $pwr ;;; Bad system call. ;;; Action: Terminates the process. - $SIGSYS + $sys ) ) ;;; Flags provided to `sock_recv`. -(typename $riflags_t +(typename $riflags (flags u16 ;;; Returns the message without removing it from the socket's receive queue. - $SOCK_RECV_PEEK + $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. - $SOCK_RECV_WAITALL + $recv_waitall ) ) ;;; Flags returned by `sock_recv`. -(typename $roflags_t +(typename $roflags (flags u16 ;;; Returned by `sock_recv`: Message data has been truncated. - $SOCK_RECV_DATA_TRUNCATED + $recv_data_truncated ) ) ;;; Flags provided to `sock_send`. As there are currently no flags ;;; defined, it must be set to zero. -(typename $siflags_t u16) +(typename $siflags u16) ;;; Which channels on a socket to shut down. -(typename $sdflags_t +(typename $sdflags (flags u8 ;;; Disables further receive operations. - $SHUT_RD + $rd ;;; Disables further send operations. - $SHUT_WR + $wr ) ) ;;; Identifiers for preopened capabilities. -(typename $preopentype_t +(typename $preopentype (enum u8 ;;; A pre-opened directory. - $PREOPENTYPE_DIR + $dir ) ) -;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat when type is `PREOPENTYPE_DIR`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size_t) + (field $pr_name_len $size) ) ) -;;; The contents of an $prestat_t. +;;; The contents of an $prestat. (typename $prestat_u (union ;;; When type is `PREOPENTYPE_DIR`: @@ -757,10 +757,10 @@ ) ;;; Information about a pre-opened capability. -(typename $prestat_t +(typename $prestat (struct ;;; The type of the pre-opened capability. - (field $pr_type $preopentype_t) + (field $pr_type $preopentype) ;;; The contents of the information. (field $u $prestat_u) ) diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx index 4cf5f4ffa..5e125caf2 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -20,15 +20,15 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Read environment variable data. @@ -36,187 +36,187 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Return the resolution of a clock. ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno_t) + (result $error $errno) ;;; The clock for which to return the resolution. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The resolution of the clock. - (result $resolution $timestamp_t) + (result $resolution $timestamp) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") ;;; The clock for which to return the time. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp_t) - (result $error $errno_t) + (param $precision $timestamp) + (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp_t) + (result $time $timestamp) ) ;;; Provide file advisory information on a file descriptor. ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset within the file to which the advisory applies. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the region to which the advisory applies. - (param $len $filesize_t) + (param $len $filesize) ;;; The advice. - (param $advice $advice_t) - (result $error $errno_t) + (param $advice $advice) + (result $error $errno) ) ;;; Force the allocation of space in a file. ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset at which to start the allocation. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the area that is allocated. - (param $len $filesize_t) - (result $error $errno_t) + (param $len $filesize) + (result $error $errno) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat_t) + (result $stat $fdstat) ) ;;; Adjust the flags associated with a file descriptor. ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the file descriptor flags. - (param $flags $fdflags_t) - (result $error $errno_t) + (param $flags $fdflags) + (result $error $errno) ) ;;; Adjust the rights associated with a file descriptor. ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights_t) - (param $fs_rights_inheriting $rights_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inheriting $rights) + (result $error $errno) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired file size. - (param $st_size $filesize_t) - (result $error $errno_t) + (param $size $filesize) + (result $error $errno) ) ;;; Adjust the timestamps of an open file or directory. ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_t_array) + (param $iovs $iovec_array) ;;; The offset within the file at which to read. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat_t) + (result $buf $prestat) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") - (param $fd $fd_t) + (param $fd $fd) ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) - (param $path_len $size_t) - (result $error $errno_t) + (param $path_len $size) + (result $error $errno) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) + (param $iovs $ciovec_array) ;;; The offset within the file at which to write. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Read from a file descriptor. ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_t_array) - (result $error $errno_t) + (param $iovs $iovec_array) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Read directory entries from a directory. @@ -230,15 +230,15 @@ ;;; read buffer size in case it's too small to fit a single large directory ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") - (param $fd $fd_t) + (param $fd $fd) ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) - (param $buf_len $size_t) + (param $buf_len $size) ;;; The location within the directory to start reading - (param $cookie $dircookie_t) - (result $error $errno_t) + (param $cookie $dircookie) + (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -252,104 +252,104 @@ ;;; This function provides a way to atomically renumber file descriptors, which ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") - (param $fd $fd_t) + (param $fd $fd) ;;; The file descriptor to overwrite. - (param $to $fd_t) - (result $error $errno_t) + (param $to $fd) + (result $error $errno) ) ;;; Move the offset of a file descriptor. ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") - (param $fd $fd_t) + (param $fd $fd) ;;; The number of bytes to move. - (param $offset $filedelta_t) + (param $offset $filedelta) ;;; The base from which the offset is relative. - (param $whence $whence_t) - (result $error $errno_t) + (param $whence $whence) + (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize_t) + (result $newoffset $filesize) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize_t) + (result $offset $filesize) ) ;;; Write to a file descriptor. ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) - (result $error $errno_t) + (param $iovs $ciovec_array) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Create a directory. ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Return the attributes of a file or directory. ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno_t) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the timestamps of a file or directory. ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to operate on. (param $path string) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Create a hard link. ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $old_fd $fd_t) + (param $old_fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags_t) + (param $old_flags $lookupflags) ;;; The source path from which to link. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Open a file or directory. @@ -362,14 +362,14 @@ ;; ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags_t) + (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the ;;; `dirfd` directory. (param $path string) ;;; The method by which to open the file. - (param $o_flags $oflags_t) + (param $oflags $oflags) ;;; The initial rights of the newly created file descriptor. The ;;; implementation is allowed to return a file descriptor with fewer rights ;;; than specified, if and only if those rights do not apply to the type of @@ -378,49 +378,49 @@ ;;; The *base* rights are rights that will apply to operations using the file ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. - (param $fs_rights_base $rights_t) - (param $fs_rights_inherting $rights_t) - (param $flags $fdflags_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inherting $rights) + (param $fdflags $fdflags) + (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd_t) + (result $opened_fd $fd) ) ;;; Read the contents of a symbolic link. ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") - (param $fd $fd_t) + (param $fd $fd) ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Remove a directory. ;;; Return `ENOTEMPTY` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Rename a file or directory. ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") - (param $fd $fd_t) + (param $fd $fd) ;;; The source path of the file or directory to rename. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Create a symbolic link. @@ -428,10 +428,10 @@ (@interface func (export "path_symlink") ;;; The contents of the symbolic link. (param $old_path string) - (param $fd $fd_t) + (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) @@ -439,23 +439,23 @@ ;;; Return `EISDIR` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription_t)) + (param $in (@witx const_pointer $subscription)) ;;; The events that have occurred. - (param $out (@witx pointer $event_t)) + (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size_t) - (result $error $errno_t) + (param $nsubscriptions $size) + (result $error $errno) ;;; The number of events stored. - (result $nevents $size_t) + (result $nevents $size) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -463,21 +463,21 @@ ;;; the environment. (@interface func (export "proc_exit") ;;; The exit code returned by the process. - (param $rval $exitcode_t) + (param $rval $exitcode) ) ;;; Send a signal to the process of the calling thread. ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") ;;; The signal condition to trigger. - (param $sig $signal_t) - (result $error $errno_t) + (param $sig $signal) + (result $error $errno) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno_t) + (result $error $errno) ) ;;; Write high-quality random data into a buffer. @@ -489,46 +489,46 @@ (@interface func (export "random_get") ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ) ;;; Receive a message from a socket. ;;; Note: This is similar to `recv` in POSIX, though it also supports reading ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_t_array) + (param $ri_data $iovec_array) ;;; Message flags. - (param $ri_flags $riflags_t) - (result $error $errno_t) + (param $ri_flags $riflags) + (result $error $errno) ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size_t) + (result $ro_datalen $size) ;;; Message flags. - (result $ro_flags $roflags_t) + (result $ro_flags $roflags) ) ;;; Send a message on a socket. ;;; Note: This is similar to `send` in POSIX, though it also supports writing ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_t_array) + (param $si_data $ciovec_array) ;;; Message flags. - (param $si_flags $siflags_t) - (result $error $errno_t) + (param $si_flags $siflags) + (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size_t) + (result $so_datalen $size) ) ;;; Shut down socket send and receive channels. ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") - (param $fd $fd_t) + (param $fd $fd) ;;; Which channels on the socket to shut down. - (param $how $sdflags_t) - (result $error $errno_t) + (param $how $sdflags) + (result $error $errno) ) ) diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx index 68f6fac4a..d8ce215d7 100644 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -5,29 +5,29 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(typename $size_t u32) +(typename $size u32) ;;; Non-negative file size or length of a region within a file. -(typename $filesize_t u64) +(typename $filesize u64) ;;; Timestamp in nanoseconds. -(typename $timestamp_t u64) +(typename $timestamp u64) ;;; Identifiers for clocks. -(typename $clockid_t +(typename $clockid (enum u32 ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. - $CLOCK_REALTIME + $realtime ;;; The store-wide monotonic clock, which is defined as a clock measuring ;;; real time, whose value cannot be adjusted and which cannot have negative ;;; clock jumps. The epoch of this clock is undefined. The absolute time ;;; value of this clock therefore has no meaning. - $CLOCK_MONOTONIC + $monotonic ;;; The CPU-time clock associated with the current process. - $CLOCK_PROCESS_CPUTIME_ID + $process_cputime_id ;;; The CPU-time clock associated with the current thread. - $CLOCK_THREAD_CPUTIME_ID + $thread_cputime_id ) ) @@ -35,732 +35,732 @@ ;;; Not all of these error codes are returned by the functions provided by this ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. -(typename $errno_t +(typename $errno (enum u16 ;;; No error occurred. System call completed successfully. - $ESUCCESS + $success ;;; Argument list too long. - $E2BIG + $2big ;;; Permission denied. - $EACCES + $acces ;;; Address in use. - $EADDRINUSE + $addrinuse ;;; Address not available. - $EADDRNOTAVAIL + $addrnotavail ;;; Address family not supported. - $EAFNOSUPPORT + $afnosupport ;;; Resource unavailable, or operation would block. - $EAGAIN + $again ;;; Connection already in progress. - $EALREADY + $already ;;; Bad file descriptor. - $EBADF + $badf ;;; Bad message. - $EBADMSG + $badmsg ;;; Device or resource busy. - $EBUSY + $busy ;;; Operation canceled. - $ECANCELED + $canceled ;;; No child processes. - $ECHILD + $child ;;; Connection aborted. - $ECONNABORTED + $connaborted ;;; Connection refused. - $ECONNREFUSED + $connrefused ;;; Connection reset. - $ECONNRESET + $connreset ;;; Resource deadlock would occur. - $EDEADLK + $deadlk ;;; Destination address required. - $EDESTADDRREQ + $destaddrreq ;;; Mathematics argument out of domain of function. - $EDOM + $dom ;;; Reserved. - $EDQUOT + $dquot ;;; File exists. - $EEXIST + $exist ;;; Bad address. - $EFAULT + $fault ;;; File too large. - $EFBIG + $fbig ;;; Host is unreachable. - $EHOSTUNREACH + $hostunreach ;;; Identifier removed. - $EIDRM + $idrm ;;; Illegal byte sequence. - $EILSEQ + $ilseq ;;; Operation in progress. - $EINPROGRESS + $inprogress ;;; Interrupted function. - $EINTR + $intr ;;; Invalid argument. - $EINVAL + $inval ;;; I/O error. - $EIO + $io ;;; Socket is connected. - $EISCONN + $isconn ;;; Is a directory. - $EISDIR + $isdir ;;; Too many levels of symbolic links. - $ELOOP + $loop ;;; File descriptor value too large. - $EMFILE + $mfile ;;; Too many links. - $EMLINK + $mlink ;;; Message too large. - $EMSGSIZE + $msgsize ;;; Reserved. - $EMULTIHOP + $multihop ;;; Filename too long. - $ENAMETOOLONG + $nametoolong ;;; Network is down. - $ENETDOWN + $netdown ;;; Connection aborted by network. - $ENETRESET + $netreset ;;; Network unreachable. - $ENETUNREACH + $netunreach ;;; Too many files open in system. - $ENFILE + $nfile ;;; No buffer space available. - $ENOBUFS + $nobufs ;;; No such device. - $ENODEV + $nodev ;;; No such file or directory. - $ENOENT + $noent ;;; Executable file format error. - $ENOEXEC + $noexec ;;; No locks available. - $ENOLCK + $nolck ;;; Reserved. - $ENOLINK + $nolink ;;; Not enough space. - $ENOMEM + $nomem ;;; No message of the desired type. - $ENOMSG + $nomsg ;;; Protocol not available. - $ENOPROTOOPT + $noprotoopt ;;; No space left on device. - $ENOSPC + $nospc ;;; Function not supported. - $ENOSYS + $nosys ;;; The socket is not connected. - $ENOTCONN + $notconn ;;; Not a directory or a symbolic link to a directory. - $ENOTDIR + $notdir ;;; Directory not empty. - $ENOTEMPTY + $notempty ;;; State not recoverable. - $ENOTRECOVERABLE + $notrecoverable ;;; Not a socket. - $ENOTSOCK + $notsock ;;; Not supported, or operation not supported on socket. - $ENOTSUP + $notsup ;;; Inappropriate I/O control operation. - $ENOTTY + $notty ;;; No such device or address. - $ENXIO + $nxio ;;; Value too large to be stored in data type. - $EOVERFLOW + $overflow ;;; Previous owner died. - $EOWNERDEAD + $ownerdead ;;; Operation not permitted. - $EPERM + $perm ;;; Broken pipe. - $EPIPE + $pipe ;;; Protocol error. - $EPROTO + $proto ;;; Protocol not supported. - $EPROTONOSUPPORT + $protonosupport ;;; Protocol wrong type for socket. - $EPROTOTYPE + $prototype ;;; Result too large. - $ERANGE + $range ;;; Read-only file system. - $EROFS + $rofs ;;; Invalid seek. - $ESPIPE + $spipe ;;; No such process. - $ESRCH + $srch ;;; Reserved. - $ESTALE + $stale ;;; Connection timed out. - $ETIMEDOUT + $timedout ;;; Text file busy. - $ETXTBSY + $txtbsy ;;; Cross-device link. - $EXDEV + $xdev ;;; Extension: Capabilities insufficient. - $ENOTCAPABLE + $notcapable ) ) ;;; File descriptor rights, determining which actions may be performed. -(typename $rights_t +(typename $rights (flags u64 ;;; The right to invoke `fd_datasync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_DSYNC`. - $RIGHT_FD_DATASYNC + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflag::dsync`. + $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pread`. - $RIGHT_FD_READ - ;;; The right to invoke `fd_seek`. This flag implies `RIGHT_FD_TELL`. - $RIGHT_FD_SEEK + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. + $fd_read + ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. + $fd_seek ;;; The right to invoke `fd_fdstat_set_flags`. - $RIGHT_FD_FDSTAT_SET_FLAGS + $fd_fdstat_set_flags ;;; The right to invoke `fd_sync`. ;; - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. - $RIGHT_FD_SYNC + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflag::rsync` and `fdflag::dsync`. + $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to ;;; invoke `fd_tell`. - $RIGHT_FD_TELL + $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `RIGHT_FD_SEEK` is set, includes the right to invoke `fd_pwrite`. - $RIGHT_FD_WRITE + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. + $fd_write ;;; The right to invoke `fd_advise`. - $RIGHT_FD_ADVISE + $fd_advise ;;; The right to invoke `fd_allocate`. - $RIGHT_FD_ALLOCATE + $fd_allocate ;;; The right to invoke `path_create_directory`. - $RIGHT_PATH_CREATE_DIRECTORY - ;;; If `RIGHT_PATH_OPEN` is set, the right to invoke `path_open` with `O_CREAT`. - $RIGHT_PATH_CREATE_FILE + $path_create_directory + ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::creat`. + $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. - $RIGHT_PATH_LINK_SOURCE + $path_link_source ;;; The right to invoke `path_link` with the file descriptor as the ;;; target directory. - $RIGHT_PATH_LINK_TARGET + $path_link_target ;;; The right to invoke `path_open`. - $RIGHT_PATH_OPEN + $path_open ;;; The right to invoke `fd_readdir`. - $RIGHT_FD_READDIR + $fd_readdir ;;; The right to invoke `path_readlink`. - $RIGHT_PATH_READLINK + $path_readlink ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $RIGHT_PATH_RENAME_SOURCE + $path_rename_source ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $RIGHT_PATH_RENAME_TARGET + $path_rename_target ;;; The right to invoke `path_filestat_get`. - $RIGHT_PATH_FILESTAT_GET + $path_filestat_get ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `RIGHT_PATH_OPEN` is set, includes the right to invoke `path_open` with `O_TRUNC`. - $RIGHT_PATH_FILESTAT_SET_SIZE + ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. + $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. - $RIGHT_PATH_FILESTAT_SET_TIMES + $path_filestat_set_times ;;; The right to invoke `fd_filestat_get`. - $RIGHT_FD_FILESTAT_GET + $fd_filestat_get ;;; The right to invoke `fd_filestat_set_size`. - $RIGHT_FD_FILESTAT_SET_SIZE + $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. - $RIGHT_FD_FILESTAT_SET_TIMES + $fd_filestat_set_times ;;; The right to invoke `path_symlink`. - $RIGHT_PATH_SYMLINK + $path_symlink ;;; The right to invoke `path_remove_directory`. - $RIGHT_PATH_REMOVE_DIRECTORY + $path_remove_directory ;;; The right to invoke `path_unlink_file`. - $RIGHT_PATH_UNLINK_FILE - ;;; If `RIGHT_FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_READ`. - ;;; If `RIGHT_FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `EVENTTYPE_FD_WRITE`. - $RIGHT_POLL_FD_READWRITE + $path_unlink_file + ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. + ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. + $poll_fd_readwrite ;;; The right to invoke `sock_shutdown`. - $RIGHT_SOCK_SHUTDOWN + $sock_shutdown ) ) ;;; A file descriptor index. -(typename $fd_t u32) +(typename $fd u32) ;;; A region of memory for scatter/gather reads. -(typename $iovec_t +(typename $iovec (struct ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. - (field $buf_len $size_t) + (field $buf_len $size) ) ) ;;; A region of memory for scatter/gather writes. -(typename $ciovec_t +(typename $ciovec (struct ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. - (field $buf_len $size_t) + (field $buf_len $size) ) ) -(typename $iovec_t_array (array $iovec_t)) -(typename $ciovec_t_array (array $ciovec_t)) +(typename $iovec_array (array $iovec)) +(typename $ciovec_array (array $ciovec)) ;;; Relative offset within a file. -(typename $filedelta_t s64) +(typename $filedelta s64) ;;; The position relative to which to set the offset of the file descriptor. -(typename $whence_t +(typename $whence (enum u8 ;;; Seek relative to start-of-file. - $WHENCE_SET + $set ;;; Seek relative to current position. - $WHENCE_CUR + $cur ;;; Seek relative to end-of-file. - $WHENCE_END + $end ) ) ;;; A reference to the offset of a directory entry. ;;; ;;; The value 0 signifies the start of the directory. -(typename $dircookie_t u64) +(typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent_t. -(typename $dirnamlen_t u32) +;;; The type for the $d_namlen field of $dirent. +(typename $dirnamlen u32) ;;; File serial number that is unique within its file system. -(typename $inode_t u64) +(typename $inode u64) ;;; The type of a file descriptor or file. -(typename $filetype_t +(typename $filetype (enum u8 ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $FILETYPE_UNKNOWN + $unknown ;;; The file descriptor or file refers to a block device inode. - $FILETYPE_BLOCK_DEVICE + $block_device ;;; The file descriptor or file refers to a character device inode. - $FILETYPE_CHARACTER_DEVICE + $character_device ;;; The file descriptor or file refers to a directory inode. - $FILETYPE_DIRECTORY + $directory ;;; The file descriptor or file refers to a regular file inode. - $FILETYPE_REGULAR_FILE + $regular_file ;;; The file descriptor or file refers to a datagram socket. - $FILETYPE_SOCKET_DGRAM + $socket_dgram ;;; The file descriptor or file refers to a byte-stream socket. - $FILETYPE_SOCKET_STREAM + $socket_stream ;;; The file refers to a symbolic link inode. - $FILETYPE_SYMBOLIC_LINK + $symbolic_link ) ) ;;; A directory entry. -(typename $dirent_t +(typename $dirent (struct ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie_t) + (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode_t) + (field $d_ino $inode) ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen_t) + (field $d_namlen $dirnamlen) ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype_t) + (field $d_type $filetype) ) ) ;;; File or memory access pattern advisory information. -(typename $advice_t +(typename $advice (enum u8 ;;; The application has no advice to give on its behavior with respect to the specified data. - $ADVICE_NORMAL + $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $ADVICE_SEQUENTIAL + $sequential ;;; The application expects to access the specified data in a random order. - $ADVICE_RANDOM + $random ;;; The application expects to access the specified data in the near future. - $ADVICE_WILLNEED + $willneed ;;; The application expects that it will not access the specified data in the near future. - $ADVICE_DONTNEED + $dontneed ;;; The application expects to access the specified data once and then not reuse it thereafter. - $ADVICE_NOREUSE + $noreuse ) ) ;;; File descriptor flags. -(typename $fdflags_t +(typename $fdflags (flags u16 ;;; Append mode: Data written to the file is always appended to the file's end. - $FDFLAG_APPEND + $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $FDFLAG_DSYNC + $dsync ;;; Non-blocking mode. - $FDFLAG_NONBLOCK + $nonblock ;;; Synchronized read I/O operations. - $FDFLAG_RSYNC + $rsync ;;; Write according to synchronized I/O file integrity completion. In ;;; addition to synchronizing the data stored in the file, the implementation ;;; may also synchronously update the file's metadata. - $FDFLAG_SYNC + $sync ) ) ;;; File descriptor attributes. -(typename $fdstat_t +(typename $fdstat (struct ;;; File type. - (field $fs_filetype $filetype_t) + (field $fs_filetype $filetype) ;;; File descriptor flags. - (field $fs_flags $fdflags_t) + (field $fs_flags $fdflags) ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights_t) + (field $fs_rights_base $rights) ;;; Maximum set of rights that may be installed on new file descriptors that ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights_t) + (field $fs_rights_inheriting $rights) ) ) ;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode_t` to uniquely identify a file or directory in the filesystem. -(typename $device_t u64) +;;; with `inode` to uniquely identify a file or directory in the filesystem. +(typename $device u64) ;;; Which file time attributes to adjust. -(typename $fstflags_t +(typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat_t::st_atim`. - $FILESTAT_SET_ATIM - ;;; Adjust the last data access timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_ATIM_NOW - ;;; Adjust the last data modification timestamp to the value stored in `filestat_t::st_mtim`. - $FILESTAT_SET_MTIM - ;;; Adjust the last data modification timestamp to the time of clock `CLOCK_REALTIME`. - $FILESTAT_SET_MTIM_NOW + ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + $atim + ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + $atim_now + ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + $mtim + ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + $mtim_now ) ) ;;; Flags determining the method of how paths are resolved. -(typename $lookupflags_t +(typename $lookupflags (flags u32 ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $LOOKUP_SYMLINK_FOLLOW + $symlink_follow ) ) ;;; Open flags used by `path_open`. -(typename $oflags_t +(typename $oflags (flags u16 ;;; Create file if it does not exist. - $O_CREAT + $creat ;;; Fail if not a directory. - $O_DIRECTORY + $directory ;;; Fail if file already exists. - $O_EXCL + $excl ;;; Truncate file to size 0. - $O_TRUNC + $trunc ) ) ;;; Number of hard links to an inode. -(typename $linkcount_t u64) +(typename $linkcount u64) ;;; File attributes. -(typename $filestat_t +(typename $filestat (struct ;;; Device ID of device containing the file. - (field $st_dev $device_t) + (field $dev $device) ;;; File serial number. - (field $st_ino $inode_t) + (field $ino $inode) ;;; File type. - (field $st_filetype $filetype_t) + (field $filetype $filetype) ;;; Number of hard links to the file. - (field $st_nlink $linkcount_t) + (field $nlink $linkcount) ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $st_size $filesize_t) + (field $size $filesize) ;;; Last data access timestamp. - (field $st_atim $timestamp_t) + (field $atim $timestamp) ;;; Last data modification timestamp. - (field $st_mtim $timestamp_t) + (field $mtim $timestamp) ;;; Last file status change timestamp. - (field $st_ctim $timestamp_t) + (field $ctim $timestamp) ) ) ;;; User-provided value that may be attached to objects that is retained when ;;; extracted from the implementation. -(typename $userdata_t u64) +(typename $userdata u64) ;;; Type of a subscription to an event or its occurrence. -(typename $eventtype_t +(typename $eventtype (enum u8 - ;;; The time value of clock `subscription_t::u.clock.clock_id` has - ;;; reached timestamp `subscription_t::u.clock.timeout`. - $EVENTTYPE_CLOCK - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has data + ;;; The time value of clock `subscription::u.clock.clock_id` has + ;;; reached timestamp `subscription::u.clock.timeout`. + $clock + ;;; File descriptor `subscription::u.fd_readwrite.fd` has data ;;; available for reading. This event always triggers for regular files. - $EVENTTYPE_FD_READ - ;;; File descriptor `subscription_t::u.fd_readwrite.fd` has capacity + $fd_read + ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity ;;; available for writing. This event always triggers for regular files. - $EVENTTYPE_FD_WRITE + $fd_write ) ) ;;; The state of the file descriptor subscribed to with -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $eventrwflags_t +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $eventrwflags (flags u16 ;;; The peer of this socket has closed or disconnected. - $EVENT_FD_READWRITE_HANGUP + $fd_readwrite_hangup ) ) -;;; The contents of an $event_t when type is `EVENTTYPE_FD_READ` or -;;; `EVENTTYPE_FD_WRITE`. -(typename $event_fd_readwrite_t +;;; The contents of an $event when type is `eventtype::fd_read` or +;;; `eventtype::fd_write`. +(typename $event_fd_readwrite (struct ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize_t) + (field $nbytes $filesize) ;;; The state of the file descriptor. - (field $flags $eventrwflags_t) + (field $flags $eventrwflags) ) ) -;;; The contents of an $event_t. +;;; The contents of an $event. (typename $event_u (union - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $event_fd_readwrite_t) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $event_fd_readwrite) ) ) ;;; An event that occurred. -(typename $event_t +(typename $event (struct - ;;; User-provided value that got attached to `subscription_t::userdata`. - (field $userdata $userdata_t) + ;;; User-provided value that got attached to `subscription::userdata`. + (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno_t) + (field $error $errno) ;;; The type of the event that occurred. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the event. (field $u $event_u) ) ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_t::u.clock.timeout.` -(typename $subclockflags_t +;;; `subscription::u.clock.timeout.` +(typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription_t::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription_t::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription_t::u.clock.timeout` relative to the - ;;; current time value of clock `subscription_t::u.clock.clock_id.` - $SUBSCRIPTION_CLOCK_ABSTIME + ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock + ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp + ;;; provided in `subscription::u.clock.timeout` relative to the + ;;; current time value of clock `subscription::u.clock.clock_id.` + $subscription_clock_abstime ) ) -;;; The contents of a $subscription_t when type is `EVENTTYPE_CLOCK`. -(typename $subscription_clock_t +;;; The contents of a $subscription when type is `eventtype::clock`. +(typename $subscription_clock (struct ;;; The clock against which to compare the timestamp. - (field $clock_id $clockid_t) + (field $id $clockid) ;;; The absolute or relative timestamp. - (field $timeout $timestamp_t) + (field $timeout $timestamp) ;;; The amount of time that the implementation may wait additionally ;;; to coalesce with other events. - (field $precision $timestamp_t) + (field $precision $timestamp) ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags_t) + (field $flags $subclockflags) ) ) -;;; The contents of a $subscription_t when type is type is -;;; `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`. -(typename $subscription_fd_readwrite_t +;;; The contents of a $subscription when type is type is +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $subscription_fd_readwrite (struct ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd_t) + (field $file_descriptor $fd) ) ) -;;; The contents of a $subscription_t. +;;; The contents of a $subscription. (typename $subscription_u (union - ;;; When type is `EVENTTYPE_CLOCK`: - (field $clock $subscription_clock_t) - ;;; When type is `EVENTTYPE_FD_READ` or `EVENTTYPE_FD_WRITE`: - (field $fd_readwrite $subscription_fd_readwrite_t) + ;;; When type is `eventtype::clock`: + (field $clock $subscription_clock) + ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: + (field $fd_readwrite $subscription_fd_readwrite) ) ) ;;; Subscription to an event. -(typename $subscription_t +(typename $subscription (struct ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event_t::userdata`. - (field $userdata $userdata_t) + ;;; implementation and returned through `event::userdata`. + (field $userdata $userdata) ;;; The type of the event to which to subscribe. - (field $type $eventtype_t) + (field $type $eventtype) ;;; The contents of the subscription. (field $u $subscription_u) ) ) ;;; Exit code generated by a process when exiting. -(typename $exitcode_t u32) +(typename $exitcode u32) ;;; Signal condition. -(typename $signal_t +(typename $signal (enum u8 ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. - $SIGNONE + $none ;;; Hangup. ;;; Action: Terminates the process. - $SIGHUP + $hup ;;; Terminate interrupt signal. ;;; Action: Terminates the process. - $SIGINT + $int ;;; Terminal quit signal. ;;; Action: Terminates the process. - $SIGQUIT + $quit ;;; Illegal instruction. ;;; Action: Terminates the process. - $SIGILL + $ill ;;; Trace/breakpoint trap. ;;; Action: Terminates the process. - $SIGTRAP + $trap ;;; Process abort signal. ;;; Action: Terminates the process. - $SIGABRT + $abrt ;;; Access to an undefined portion of a memory object. ;;; Action: Terminates the process. - $SIGBUS + $bus ;;; Erroneous arithmetic operation. ;;; Action: Terminates the process. - $SIGFPE + $fpe ;;; Kill. ;;; Action: Terminates the process. - $SIGKILL + $kill ;;; User-defined signal 1. ;;; Action: Terminates the process. - $SIGUSR1 + $usr1 ;;; Invalid memory reference. ;;; Action: Terminates the process. - $SIGSEGV + $segv ;;; User-defined signal 2. ;;; Action: Terminates the process. - $SIGUSR2 + $usr2 ;;; Write on a pipe with no one to read it. ;;; Action: Ignored. - $SIGPIPE + $pipe ;;; Alarm clock. ;;; Action: Terminates the process. - $SIGALRM + $alrm ;;; Termination signal. ;;; Action: Terminates the process. - $SIGTERM + $term ;;; Child process terminated, stopped, or continued. ;;; Action: Ignored. - $SIGCHLD + $chld ;;; Continue executing, if stopped. ;;; Action: Continues executing, if stopped. - $SIGCONT + $cont ;;; Stop executing. ;;; Action: Stops executing. - $SIGSTOP + $stop ;;; Terminal stop signal. ;;; Action: Stops executing. - $SIGTSTP + $tstp ;;; Background process attempting read. ;;; Action: Stops executing. - $SIGTTIN + $ttin ;;; Background process attempting write. ;;; Action: Stops executing. - $SIGTTOU + $ttou ;;; High bandwidth data is available at a socket. ;;; Action: Ignored. - $SIGURG + $urg ;;; CPU time limit exceeded. ;;; Action: Terminates the process. - $SIGXCPU + $xcpu ;;; File size limit exceeded. ;;; Action: Terminates the process. - $SIGXFSZ + $xfsz ;;; Virtual timer expired. ;;; Action: Terminates the process. - $SIGVTALRM + $vtalrm ;;; Profiling timer expired. ;;; Action: Terminates the process. - $SIGPROF + $prof ;;; Window changed. ;;; Action: Ignored. - $SIGWINCH + $winch ;;; I/O possible. ;;; Action: Terminates the process. - $SIGPOLL + $poll ;;; Power failure. ;;; Action: Terminates the process. - $SIGPWR + $pwr ;;; Bad system call. ;;; Action: Terminates the process. - $SIGSYS + $sys ) ) ;;; Flags provided to `sock_recv`. -(typename $riflags_t +(typename $riflags (flags u16 ;;; Returns the message without removing it from the socket's receive queue. - $SOCK_RECV_PEEK + $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. - $SOCK_RECV_WAITALL + $recv_waitall ) ) ;;; Flags returned by `sock_recv`. -(typename $roflags_t +(typename $roflags (flags u16 ;;; Returned by `sock_recv`: Message data has been truncated. - $SOCK_RECV_DATA_TRUNCATED + $recv_data_truncated ) ) ;;; Flags provided to `sock_send`. As there are currently no flags ;;; defined, it must be set to zero. -(typename $siflags_t u16) +(typename $siflags u16) ;;; Which channels on a socket to shut down. -(typename $sdflags_t +(typename $sdflags (flags u8 ;;; Disables further receive operations. - $SHUT_RD + $rd ;;; Disables further send operations. - $SHUT_WR + $wr ) ) ;;; Identifiers for preopened capabilities. -(typename $preopentype_t +(typename $preopentype (enum u8 ;;; A pre-opened directory. - $PREOPENTYPE_DIR + $dir ) ) -;;; The contents of a $prestat_t when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size_t) + (field $pr_name_len $size) ) ) -;;; The contents of an $prestat_t. +;;; The contents of an $prestat. (typename $prestat_u (union - ;;; When type is `PREOPENTYPE_DIR`: + ;;; When type is `preopentype::dir`: (field $dir $prestat_dir) ) ) ;;; Information about a pre-opened capability. -(typename $prestat_t +(typename $prestat (struct ;;; The type of the pre-opened capability. - (field $pr_type $preopentype_t) + (field $pr_type $preopentype) ;;; The contents of the information. (field $u $prestat_u) ) diff --git a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx index e69b788dc..44a297b8c 100644 --- a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -17,15 +17,15 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Read environment variable data. @@ -33,187 +33,187 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno_t) + (result $error $errno) ) ;;; Return command-line argument data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno_t) + (result $error $errno) ;;; The number of arguments. - (result $argc $size_t) + (result $argc $size) ;;; The size of the argument string data. - (result $argv_buf_size $size_t) + (result $argv_buf_size $size) ) ;;; Return the resolution of a clock. ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno_t) + (result $error $errno) ;;; The clock for which to return the resolution. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The resolution of the clock. - (result $resolution $timestamp_t) + (result $resolution $timestamp) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. (@interface func (export "clock_time_get") ;;; The clock for which to return the time. - (param $clock_id $clockid_t) + (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp_t) - (result $error $errno_t) + (param $precision $timestamp) + (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp_t) + (result $time $timestamp) ) ;;; Provide file advisory information on a file descriptor. ;;; Note: This is similar to `posix_fadvise` in POSIX. (@interface func (export "fd_advise") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset within the file to which the advisory applies. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the region to which the advisory applies. - (param $len $filesize_t) + (param $len $filesize) ;;; The advice. - (param $advice $advice_t) - (result $error $errno_t) + (param $advice $advice) + (result $error $errno) ) ;;; Force the allocation of space in a file. ;;; Note: This is similar to `posix_fallocate` in POSIX. (@interface func (export "fd_allocate") - (param $fd $fd_t) + (param $fd $fd) ;;; The offset at which to start the allocation. - (param $offset $filesize_t) + (param $offset $filesize) ;;; The length of the area that is allocated. - (param $len $filesize_t) - (result $error $errno_t) + (param $len $filesize) + (result $error $errno) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat_t) + (result $stat $fdstat) ) ;;; Adjust the flags associated with a file descriptor. ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the file descriptor flags. - (param $flags $fdflags_t) - (result $error $errno_t) + (param $flags $fdflags) + (result $error $errno) ) ;;; Adjust the rights associated with a file descriptor. ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights_t) - (param $fs_rights_inheriting $rights_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inheriting $rights) + (result $error $errno) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. ;;; Note: This is similar to `ftruncate` in POSIX. (@interface func (export "fd_filestat_set_size") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired file size. - (param $st_size $filesize_t) - (result $error $errno_t) + (param $size $filesize) + (result $error $errno) ) ;;; Adjust the timestamps of an open file or directory. ;;; Note: This is similar to `futimens` in POSIX. (@interface func (export "fd_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "fd_pread") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_t_array) + (param $iovs $iovec_array) ;;; The offset within the file at which to read. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat_t) + (result $buf $prestat) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_dir_name") - (param $fd $fd_t) + (param $fd $fd) ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) - (param $path_len $size_t) - (result $error $errno_t) + (param $path_len $size) + (result $error $errno) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `pwritev` in POSIX. (@interface func (export "fd_pwrite") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) + (param $iovs $ciovec_array) ;;; The offset within the file at which to write. - (param $offset $filesize_t) - (result $error $errno_t) + (param $offset $filesize) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Read from a file descriptor. ;;; Note: This is similar to `readv` in POSIX. (@interface func (export "fd_read") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_t_array) - (result $error $errno_t) + (param $iovs $iovec_array) + (result $error $errno) ;;; The number of bytes read. - (result $nread $size_t) + (result $nread $size) ) ;;; Read directory entries from a directory. @@ -227,15 +227,15 @@ ;;; read buffer size in case it's too small to fit a single large directory ;;; entry, or skip the oversized directory entry. (@interface func (export "fd_readdir") - (param $fd $fd_t) + (param $fd $fd) ;;; The buffer where directory entries are stored (param $buf (@witx pointer u8)) - (param $buf_len $size_t) + (param $buf_len $size) ;;; The location within the directory to start reading - (param $cookie $dircookie_t) - (result $error $errno_t) + (param $cookie $dircookie) + (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -249,104 +249,104 @@ ;;; This function provides a way to atomically renumber file descriptors, which ;;; would disappear if `dup2()` were to be removed entirely. (@interface func (export "fd_renumber") - (param $fd $fd_t) + (param $fd $fd) ;;; The file descriptor to overwrite. - (param $to $fd_t) - (result $error $errno_t) + (param $to $fd) + (result $error $errno) ) ;;; Move the offset of a file descriptor. ;;; Note: This is similar to `lseek` in POSIX. (@interface func (export "fd_seek") - (param $fd $fd_t) + (param $fd $fd) ;;; The number of bytes to move. - (param $offset $filedelta_t) + (param $offset $filedelta) ;;; The base from which the offset is relative. - (param $whence $whence_t) - (result $error $errno_t) + (param $whence $whence) + (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize_t) + (result $newoffset $filesize) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") - (param $fd $fd_t) - (result $error $errno_t) + (param $fd $fd) + (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize_t) + (result $offset $filesize) ) ;;; Write to a file descriptor. ;;; Note: This is similar to `writev` in POSIX. (@interface func (export "fd_write") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_t_array) - (result $error $errno_t) + (param $iovs $ciovec_array) + (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size_t) + (result $nwritten $size) ) ;;; Create a directory. ;;; Note: This is similar to `mkdirat` in POSIX. (@interface func (export "path_create_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Return the attributes of a file or directory. ;;; Note: This is similar to `stat` in POSIX. (@interface func (export "path_filestat_get") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno_t) + (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat_t) + (result $buf $filestat) ) ;;; Adjust the timestamps of a file or directory. ;;; Note: This is similar to `utimensat` in POSIX. (@interface func (export "path_filestat_set_times") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags_t) + (param $flags $lookupflags) ;;; The path of the file or directory to operate on. (param $path string) ;;; The desired values of the data access timestamp. - (param $st_atim $timestamp_t) + (param $atim $timestamp) ;;; The desired values of the data modification timestamp. - (param $st_mtim $timestamp_t) + (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags_t) - (result $error $errno_t) + (param $fst_flags $fstflags) + (result $error $errno) ) ;;; Create a hard link. ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "path_link") - (param $old_fd $fd_t) + (param $old_fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags_t) + (param $old_flags $lookupflags) ;;; The source path from which to link. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Open a file or directory. @@ -359,14 +359,14 @@ ;; ;;; Note: This is similar to `openat` in POSIX. (@interface func (export "path_open") - (param $fd $fd_t) + (param $fd $fd) ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags_t) + (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the ;;; `dirfd` directory. (param $path string) ;;; The method by which to open the file. - (param $o_flags $oflags_t) + (param $oflags $oflags) ;;; The initial rights of the newly created file descriptor. The ;;; implementation is allowed to return a file descriptor with fewer rights ;;; than specified, if and only if those rights do not apply to the type of @@ -375,49 +375,49 @@ ;;; The *base* rights are rights that will apply to operations using the file ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. - (param $fs_rights_base $rights_t) - (param $fs_rights_inherting $rights_t) - (param $flags $fdflags_t) - (result $error $errno_t) + (param $fs_rights_base $rights) + (param $fs_rights_inherting $rights) + (param $fdflags $fdflags) + (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd_t) + (result $opened_fd $fd) ) ;;; Read the contents of a symbolic link. ;;; Note: This is similar to `readlinkat` in POSIX. (@interface func (export "path_readlink") - (param $fd $fd_t) + (param $fd $fd) ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size_t) + (result $bufused $size) ) ;;; Remove a directory. ;;; Return `ENOTEMPTY` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Rename a file or directory. ;;; Note: This is similar to `renameat` in POSIX. (@interface func (export "path_rename") - (param $fd $fd_t) + (param $fd $fd) ;;; The source path of the file or directory to rename. (param $old_path string) ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd_t) + (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Create a symbolic link. @@ -425,10 +425,10 @@ (@interface func (export "path_symlink") ;;; The contents of the symbolic link. (param $old_path string) - (param $fd $fd_t) + (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno_t) + (result $error $errno) ) @@ -436,23 +436,23 @@ ;;; Return `EISDIR` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") - (param $fd $fd_t) + (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno_t) + (result $error $errno) ) ;;; Concurrently poll for the occurrence of a set of events. (@interface func (export "poll_oneoff") ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription_t)) + (param $in (@witx const_pointer $subscription)) ;;; The events that have occurred. - (param $out (@witx pointer $event_t)) + (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size_t) - (result $error $errno_t) + (param $nsubscriptions $size) + (result $error $errno) ;;; The number of events stored. - (result $nevents $size_t) + (result $nevents $size) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -460,21 +460,21 @@ ;;; the environment. (@interface func (export "proc_exit") ;;; The exit code returned by the process. - (param $rval $exitcode_t) + (param $rval $exitcode) ) ;;; Send a signal to the process of the calling thread. ;;; Note: This is similar to `raise` in POSIX. (@interface func (export "proc_raise") ;;; The signal condition to trigger. - (param $sig $signal_t) - (result $error $errno_t) + (param $sig $signal) + (result $error $errno) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno_t) + (result $error $errno) ) ;;; Write high-quality random data into a buffer. @@ -486,46 +486,46 @@ (@interface func (export "random_get") ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) - (param $buf_len $size_t) - (result $error $errno_t) + (param $buf_len $size) + (result $error $errno) ) ;;; Receive a message from a socket. ;;; Note: This is similar to `recv` in POSIX, though it also supports reading ;;; the data into multiple buffers in the manner of `readv`. (@interface func (export "sock_recv") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_t_array) + (param $ri_data $iovec_array) ;;; Message flags. - (param $ri_flags $riflags_t) - (result $error $errno_t) + (param $ri_flags $riflags) + (result $error $errno) ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size_t) + (result $ro_datalen $size) ;;; Message flags. - (result $ro_flags $roflags_t) + (result $ro_flags $roflags) ) ;;; Send a message on a socket. ;;; Note: This is similar to `send` in POSIX, though it also supports writing ;;; the data from multiple buffers in the manner of `writev`. (@interface func (export "sock_send") - (param $fd $fd_t) + (param $fd $fd) ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_t_array) + (param $si_data $ciovec_array) ;;; Message flags. - (param $si_flags $siflags_t) - (result $error $errno_t) + (param $si_flags $siflags) + (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size_t) + (result $so_datalen $size) ) ;;; Shut down socket send and receive channels. ;;; Note: This is similar to `shutdown` in POSIX. (@interface func (export "sock_shutdown") - (param $fd $fd_t) + (param $fd $fd) ;;; Which channels on the socket to shut down. - (param $how $sdflags_t) - (result $error $errno_t) + (param $how $sdflags) + (result $error $errno) ) ) diff --git a/proposals/filesystem/tools/witx/tests/wasi.rs b/proposals/filesystem/tools/witx/tests/wasi.rs index aef954236..938c78067 100644 --- a/proposals/filesystem/tools/witx/tests/wasi.rs +++ b/proposals/filesystem/tools/witx/tests/wasi.rs @@ -25,11 +25,6 @@ fn render_roundtrip() { let back_to_sexprs = format!("{}", doc); println!("{}", back_to_sexprs); - let doc2 = witx::parse(&back_to_sexprs) - .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) - .unwrap(); - - let back_to_sexprs = format!("{}", doc); let doc2 = witx::parse(&back_to_sexprs) .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) From ca0c42f64d0a1eefd94e95c9bedae6cf89880c95 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 17:28:53 -0800 Subject: [PATCH 0298/1772] witx: add handles kind (#117) * witx: Add `handle` datatype variant to language * ephemeral: change $fd type definition from a u32 to a handle --- .../phases/ephemeral/witx/typenames.witx | 4 +- proposals/clocks/tools/witx/src/ast.rs | 21 ++++++++ proposals/clocks/tools/witx/src/coretypes.rs | 1 + proposals/clocks/tools/witx/src/docs.rs | 12 +++++ proposals/clocks/tools/witx/src/lib.rs | 7 +-- proposals/clocks/tools/witx/src/parser.rs | 20 +++++++ proposals/clocks/tools/witx/src/render.rs | 12 +++++ proposals/clocks/tools/witx/src/validate.rs | 53 +++++++++++++++++-- 8 files changed, 122 insertions(+), 8 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 00ae3d15e..5802048be 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -273,8 +273,8 @@ ) ) -;;; A file descriptor index. -(typename $fd u32) +;;; A file descriptor handle. +(typename $fd (handle)) ;;; A region of memory for scatter/gather reads. (typename $iovec diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 48c776ba9..341186820 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -130,6 +130,21 @@ pub enum DatatypeVariant { Flags(FlagsDatatype), Struct(StructDatatype), Union(UnionDatatype), + Handle(HandleDatatype), +} + +impl DatatypeVariant { + pub fn kind(&self) -> &'static str { + use DatatypeVariant::*; + match self { + Alias(_) => "alias", + Enum(_) => "enum", + Flags(_) => "flags", + Struct(_) => "struct", + Union(_) => "union", + Handle(_) => "handle", + } + } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -198,6 +213,12 @@ pub struct UnionVariant { pub docs: String, } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct HandleDatatype { + pub name: Id, + pub supertypes: Vec, +} + #[derive(Debug, Clone)] pub struct Module { pub name: Id, diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index 5b3c89d8d..f9919bc55 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -59,6 +59,7 @@ impl DatatypeIdent { DatatypeVariant::Struct { .. } | DatatypeVariant::Union { .. } => { DatatypePassedBy::Pointer } + DatatypeVariant::Handle { .. } => DatatypePassedBy::Value(AtomType::I32), }, } } diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs index 532b3d902..0e75c1e95 100644 --- a/proposals/clocks/tools/witx/src/docs.rs +++ b/proposals/clocks/tools/witx/src/docs.rs @@ -68,6 +68,7 @@ impl Documentation for DatatypeVariant { DatatypeVariant::Flags(a) => a.to_md(), DatatypeVariant::Struct(a) => a.to_md(), DatatypeVariant::Union(a) => a.to_md(), + DatatypeVariant::Handle(a) => a.to_md(), } } } @@ -148,6 +149,17 @@ impl Documentation for UnionDatatype { } } +impl Documentation for HandleDatatype { + fn to_md(&self) -> String { + let supertypes = self + .supertypes + .iter() + .map(|s| format!("* {}", s.name())) + .collect::>() + .join("\n"); + format!("### Handle supertypes:\n{}\n", supertypes) + } +} impl IntRepr { fn name(&self) -> &'static str { match self { diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 60b0e0663..a781aa09b 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -17,9 +17,10 @@ mod validate; pub use ast::{ AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, Id, IntRepr, InterfaceFunc, - InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, - ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, + Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntRepr, + InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, + ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, + UnionVariant, }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; pub use docs::Documentation; diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 77a1c0b03..5c4e75f1d 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -23,6 +23,7 @@ mod kw { wast::custom_keyword!(f64); wast::custom_keyword!(field); wast::custom_keyword!(flags); + wast::custom_keyword!(handle); wast::custom_keyword!(pointer); wast::custom_keyword!(r#enum = "enum"); wast::custom_keyword!(r#struct = "struct"); @@ -333,6 +334,7 @@ pub enum TypedefSyntax<'a> { Flags(FlagsSyntax<'a>), Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), + Handle(HandleSyntax<'a>), } impl<'a> Parse<'a> for TypedefSyntax<'a> { @@ -351,6 +353,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Struct(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Union(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Handle(parser.parse()?)) } else { Err(l.error()) } @@ -446,6 +450,22 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct HandleSyntax<'a> { + pub supertypes: Vec>, +} + +impl<'a> Parse<'a> for HandleSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let mut supertypes = Vec::new(); + while !parser.is_empty() { + supertypes.push(parser.parse()?); + } + Ok(HandleSyntax { supertypes }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct ModuleSyntax<'a> { pub name: wast::Id<'a>, diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 4bb7df729..2f2f8526f 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -135,6 +135,7 @@ impl Render for DatatypeVariant { DatatypeVariant::Flags(a) => a.to_sexpr(), DatatypeVariant::Struct(a) => a.to_sexpr(), DatatypeVariant::Union(a) => a.to_sexpr(), + DatatypeVariant::Handle(a) => a.to_sexpr(), } } } @@ -211,6 +212,17 @@ impl Render for UnionDatatype { } } +impl Render for HandleDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("handle")]; + let supertypes = self + .supertypes + .iter() + .map(|s| s.to_sexpr()) + .collect::>(); + SExpr::Vec([header, supertypes].concat()) + } +} impl Render for IntRepr { fn to_sexpr(&self) -> SExpr { match self { diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index eba087e8c..5781ebd06 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -2,11 +2,11 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ CommentSyntax, DatatypeIdentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, - ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + HandleSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, - Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, Id, IntRepr, - InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, + Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, + IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; @@ -188,6 +188,9 @@ impl DocValidationScope<'_> { TypedefSyntax::Union(syntax) => DatatypeVariant::Union( self.validate_union(&name, &syntax, decl.ident.span())?, ), + TypedefSyntax::Handle(syntax) => DatatypeVariant::Handle( + self.validate_handle(&name, syntax, decl.ident.span())?, + ), }; let rc_datatype = Rc::new(Datatype { name: name.clone(), @@ -358,6 +361,50 @@ impl DocValidationScope<'_> { }) } + fn validate_handle( + &self, + name: &Id, + syntax: &HandleSyntax, + _span: wast::Span, + ) -> Result { + let supertypes = syntax + .supertypes + .iter() + .map(|id_syntax| { + let id = self.get(&id_syntax)?; + match self.doc.entries.get(&id) { + Some(Entry::Datatype(weak_d)) => { + let d = weak_d.upgrade().expect("weak backref to defined type"); + match &d.variant { + DatatypeVariant::Handle { .. } => Ok(DatatypeIdent::Ident(d)), + _ => Err(ValidationError::WrongKindName { + name: id_syntax.name().to_string(), + location: self.location(id_syntax.span()), + expected: "handle", + got: d.variant.kind(), + }), + } + } + Some(entry) => Err(ValidationError::WrongKindName { + name: id_syntax.name().to_string(), + location: self.location(id_syntax.span()), + expected: "handle", + got: entry.kind(), + }), + None => Err(ValidationError::Recursive { + name: id_syntax.name().to_string(), + location: self.location(id_syntax.span()), + }), + } + }) + .collect::, _>>()?; + + Ok(HandleDatatype { + name: name.clone(), + supertypes, + }) + } + fn validate_int_repr( &self, type_: &BuiltinType, From e7067921be6ebf399e01c591e19e9cc7b9a2f00b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 17:28:53 -0800 Subject: [PATCH 0299/1772] witx: add handles kind (#117) * witx: Add `handle` datatype variant to language * ephemeral: change $fd type definition from a u32 to a handle --- .../phases/ephemeral/witx/typenames.witx | 4 +- proposals/random/tools/witx/src/ast.rs | 21 ++++++++ proposals/random/tools/witx/src/coretypes.rs | 1 + proposals/random/tools/witx/src/docs.rs | 12 +++++ proposals/random/tools/witx/src/lib.rs | 7 +-- proposals/random/tools/witx/src/parser.rs | 20 +++++++ proposals/random/tools/witx/src/render.rs | 12 +++++ proposals/random/tools/witx/src/validate.rs | 53 +++++++++++++++++-- 8 files changed, 122 insertions(+), 8 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 00ae3d15e..5802048be 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -273,8 +273,8 @@ ) ) -;;; A file descriptor index. -(typename $fd u32) +;;; A file descriptor handle. +(typename $fd (handle)) ;;; A region of memory for scatter/gather reads. (typename $iovec diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 48c776ba9..341186820 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -130,6 +130,21 @@ pub enum DatatypeVariant { Flags(FlagsDatatype), Struct(StructDatatype), Union(UnionDatatype), + Handle(HandleDatatype), +} + +impl DatatypeVariant { + pub fn kind(&self) -> &'static str { + use DatatypeVariant::*; + match self { + Alias(_) => "alias", + Enum(_) => "enum", + Flags(_) => "flags", + Struct(_) => "struct", + Union(_) => "union", + Handle(_) => "handle", + } + } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -198,6 +213,12 @@ pub struct UnionVariant { pub docs: String, } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct HandleDatatype { + pub name: Id, + pub supertypes: Vec, +} + #[derive(Debug, Clone)] pub struct Module { pub name: Id, diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index 5b3c89d8d..f9919bc55 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -59,6 +59,7 @@ impl DatatypeIdent { DatatypeVariant::Struct { .. } | DatatypeVariant::Union { .. } => { DatatypePassedBy::Pointer } + DatatypeVariant::Handle { .. } => DatatypePassedBy::Value(AtomType::I32), }, } } diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs index 532b3d902..0e75c1e95 100644 --- a/proposals/random/tools/witx/src/docs.rs +++ b/proposals/random/tools/witx/src/docs.rs @@ -68,6 +68,7 @@ impl Documentation for DatatypeVariant { DatatypeVariant::Flags(a) => a.to_md(), DatatypeVariant::Struct(a) => a.to_md(), DatatypeVariant::Union(a) => a.to_md(), + DatatypeVariant::Handle(a) => a.to_md(), } } } @@ -148,6 +149,17 @@ impl Documentation for UnionDatatype { } } +impl Documentation for HandleDatatype { + fn to_md(&self) -> String { + let supertypes = self + .supertypes + .iter() + .map(|s| format!("* {}", s.name())) + .collect::>() + .join("\n"); + format!("### Handle supertypes:\n{}\n", supertypes) + } +} impl IntRepr { fn name(&self) -> &'static str { match self { diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 60b0e0663..a781aa09b 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -17,9 +17,10 @@ mod validate; pub use ast::{ AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, Id, IntRepr, InterfaceFunc, - InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, - ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, + Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntRepr, + InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, + ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, + UnionVariant, }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; pub use docs::Documentation; diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 77a1c0b03..5c4e75f1d 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -23,6 +23,7 @@ mod kw { wast::custom_keyword!(f64); wast::custom_keyword!(field); wast::custom_keyword!(flags); + wast::custom_keyword!(handle); wast::custom_keyword!(pointer); wast::custom_keyword!(r#enum = "enum"); wast::custom_keyword!(r#struct = "struct"); @@ -333,6 +334,7 @@ pub enum TypedefSyntax<'a> { Flags(FlagsSyntax<'a>), Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), + Handle(HandleSyntax<'a>), } impl<'a> Parse<'a> for TypedefSyntax<'a> { @@ -351,6 +353,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Struct(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Union(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Handle(parser.parse()?)) } else { Err(l.error()) } @@ -446,6 +450,22 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct HandleSyntax<'a> { + pub supertypes: Vec>, +} + +impl<'a> Parse<'a> for HandleSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let mut supertypes = Vec::new(); + while !parser.is_empty() { + supertypes.push(parser.parse()?); + } + Ok(HandleSyntax { supertypes }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct ModuleSyntax<'a> { pub name: wast::Id<'a>, diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 4bb7df729..2f2f8526f 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -135,6 +135,7 @@ impl Render for DatatypeVariant { DatatypeVariant::Flags(a) => a.to_sexpr(), DatatypeVariant::Struct(a) => a.to_sexpr(), DatatypeVariant::Union(a) => a.to_sexpr(), + DatatypeVariant::Handle(a) => a.to_sexpr(), } } } @@ -211,6 +212,17 @@ impl Render for UnionDatatype { } } +impl Render for HandleDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("handle")]; + let supertypes = self + .supertypes + .iter() + .map(|s| s.to_sexpr()) + .collect::>(); + SExpr::Vec([header, supertypes].concat()) + } +} impl Render for IntRepr { fn to_sexpr(&self) -> SExpr { match self { diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index eba087e8c..5781ebd06 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -2,11 +2,11 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ CommentSyntax, DatatypeIdentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, - ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + HandleSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, - Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, Id, IntRepr, - InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, + Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, + IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; @@ -188,6 +188,9 @@ impl DocValidationScope<'_> { TypedefSyntax::Union(syntax) => DatatypeVariant::Union( self.validate_union(&name, &syntax, decl.ident.span())?, ), + TypedefSyntax::Handle(syntax) => DatatypeVariant::Handle( + self.validate_handle(&name, syntax, decl.ident.span())?, + ), }; let rc_datatype = Rc::new(Datatype { name: name.clone(), @@ -358,6 +361,50 @@ impl DocValidationScope<'_> { }) } + fn validate_handle( + &self, + name: &Id, + syntax: &HandleSyntax, + _span: wast::Span, + ) -> Result { + let supertypes = syntax + .supertypes + .iter() + .map(|id_syntax| { + let id = self.get(&id_syntax)?; + match self.doc.entries.get(&id) { + Some(Entry::Datatype(weak_d)) => { + let d = weak_d.upgrade().expect("weak backref to defined type"); + match &d.variant { + DatatypeVariant::Handle { .. } => Ok(DatatypeIdent::Ident(d)), + _ => Err(ValidationError::WrongKindName { + name: id_syntax.name().to_string(), + location: self.location(id_syntax.span()), + expected: "handle", + got: d.variant.kind(), + }), + } + } + Some(entry) => Err(ValidationError::WrongKindName { + name: id_syntax.name().to_string(), + location: self.location(id_syntax.span()), + expected: "handle", + got: entry.kind(), + }), + None => Err(ValidationError::Recursive { + name: id_syntax.name().to_string(), + location: self.location(id_syntax.span()), + }), + } + }) + .collect::, _>>()?; + + Ok(HandleDatatype { + name: name.clone(), + supertypes, + }) + } + fn validate_int_repr( &self, type_: &BuiltinType, From adefad788847c6963c45961fc76cbcda89834fce Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 17:28:53 -0800 Subject: [PATCH 0300/1772] witx: add handles kind (#117) * witx: Add `handle` datatype variant to language * ephemeral: change $fd type definition from a u32 to a handle --- .../phases/ephemeral/witx/typenames.witx | 4 +- proposals/filesystem/tools/witx/src/ast.rs | 21 ++++++++ .../filesystem/tools/witx/src/coretypes.rs | 1 + proposals/filesystem/tools/witx/src/docs.rs | 12 +++++ proposals/filesystem/tools/witx/src/lib.rs | 7 +-- proposals/filesystem/tools/witx/src/parser.rs | 20 +++++++ proposals/filesystem/tools/witx/src/render.rs | 12 +++++ .../filesystem/tools/witx/src/validate.rs | 53 +++++++++++++++++-- 8 files changed, 122 insertions(+), 8 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 00ae3d15e..5802048be 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -273,8 +273,8 @@ ) ) -;;; A file descriptor index. -(typename $fd u32) +;;; A file descriptor handle. +(typename $fd (handle)) ;;; A region of memory for scatter/gather reads. (typename $iovec diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 48c776ba9..341186820 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -130,6 +130,21 @@ pub enum DatatypeVariant { Flags(FlagsDatatype), Struct(StructDatatype), Union(UnionDatatype), + Handle(HandleDatatype), +} + +impl DatatypeVariant { + pub fn kind(&self) -> &'static str { + use DatatypeVariant::*; + match self { + Alias(_) => "alias", + Enum(_) => "enum", + Flags(_) => "flags", + Struct(_) => "struct", + Union(_) => "union", + Handle(_) => "handle", + } + } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -198,6 +213,12 @@ pub struct UnionVariant { pub docs: String, } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct HandleDatatype { + pub name: Id, + pub supertypes: Vec, +} + #[derive(Debug, Clone)] pub struct Module { pub name: Id, diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index 5b3c89d8d..f9919bc55 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -59,6 +59,7 @@ impl DatatypeIdent { DatatypeVariant::Struct { .. } | DatatypeVariant::Union { .. } => { DatatypePassedBy::Pointer } + DatatypeVariant::Handle { .. } => DatatypePassedBy::Value(AtomType::I32), }, } } diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs index 532b3d902..0e75c1e95 100644 --- a/proposals/filesystem/tools/witx/src/docs.rs +++ b/proposals/filesystem/tools/witx/src/docs.rs @@ -68,6 +68,7 @@ impl Documentation for DatatypeVariant { DatatypeVariant::Flags(a) => a.to_md(), DatatypeVariant::Struct(a) => a.to_md(), DatatypeVariant::Union(a) => a.to_md(), + DatatypeVariant::Handle(a) => a.to_md(), } } } @@ -148,6 +149,17 @@ impl Documentation for UnionDatatype { } } +impl Documentation for HandleDatatype { + fn to_md(&self) -> String { + let supertypes = self + .supertypes + .iter() + .map(|s| format!("* {}", s.name())) + .collect::>() + .join("\n"); + format!("### Handle supertypes:\n{}\n", supertypes) + } +} impl IntRepr { fn name(&self) -> &'static str { match self { diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 60b0e0663..a781aa09b 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -17,9 +17,10 @@ mod validate; pub use ast::{ AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, Id, IntRepr, InterfaceFunc, - InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, - ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, + Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntRepr, + InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, + ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, + UnionVariant, }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; pub use docs::Documentation; diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 77a1c0b03..5c4e75f1d 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -23,6 +23,7 @@ mod kw { wast::custom_keyword!(f64); wast::custom_keyword!(field); wast::custom_keyword!(flags); + wast::custom_keyword!(handle); wast::custom_keyword!(pointer); wast::custom_keyword!(r#enum = "enum"); wast::custom_keyword!(r#struct = "struct"); @@ -333,6 +334,7 @@ pub enum TypedefSyntax<'a> { Flags(FlagsSyntax<'a>), Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), + Handle(HandleSyntax<'a>), } impl<'a> Parse<'a> for TypedefSyntax<'a> { @@ -351,6 +353,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Struct(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Union(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Handle(parser.parse()?)) } else { Err(l.error()) } @@ -446,6 +450,22 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct HandleSyntax<'a> { + pub supertypes: Vec>, +} + +impl<'a> Parse<'a> for HandleSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let mut supertypes = Vec::new(); + while !parser.is_empty() { + supertypes.push(parser.parse()?); + } + Ok(HandleSyntax { supertypes }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct ModuleSyntax<'a> { pub name: wast::Id<'a>, diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 4bb7df729..2f2f8526f 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -135,6 +135,7 @@ impl Render for DatatypeVariant { DatatypeVariant::Flags(a) => a.to_sexpr(), DatatypeVariant::Struct(a) => a.to_sexpr(), DatatypeVariant::Union(a) => a.to_sexpr(), + DatatypeVariant::Handle(a) => a.to_sexpr(), } } } @@ -211,6 +212,17 @@ impl Render for UnionDatatype { } } +impl Render for HandleDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("handle")]; + let supertypes = self + .supertypes + .iter() + .map(|s| s.to_sexpr()) + .collect::>(); + SExpr::Vec([header, supertypes].concat()) + } +} impl Render for IntRepr { fn to_sexpr(&self) -> SExpr { match self { diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index eba087e8c..5781ebd06 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -2,11 +2,11 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ CommentSyntax, DatatypeIdentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, - ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + HandleSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, - Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, Id, IntRepr, - InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, + Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, + IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, UnionVariant, }; @@ -188,6 +188,9 @@ impl DocValidationScope<'_> { TypedefSyntax::Union(syntax) => DatatypeVariant::Union( self.validate_union(&name, &syntax, decl.ident.span())?, ), + TypedefSyntax::Handle(syntax) => DatatypeVariant::Handle( + self.validate_handle(&name, syntax, decl.ident.span())?, + ), }; let rc_datatype = Rc::new(Datatype { name: name.clone(), @@ -358,6 +361,50 @@ impl DocValidationScope<'_> { }) } + fn validate_handle( + &self, + name: &Id, + syntax: &HandleSyntax, + _span: wast::Span, + ) -> Result { + let supertypes = syntax + .supertypes + .iter() + .map(|id_syntax| { + let id = self.get(&id_syntax)?; + match self.doc.entries.get(&id) { + Some(Entry::Datatype(weak_d)) => { + let d = weak_d.upgrade().expect("weak backref to defined type"); + match &d.variant { + DatatypeVariant::Handle { .. } => Ok(DatatypeIdent::Ident(d)), + _ => Err(ValidationError::WrongKindName { + name: id_syntax.name().to_string(), + location: self.location(id_syntax.span()), + expected: "handle", + got: d.variant.kind(), + }), + } + } + Some(entry) => Err(ValidationError::WrongKindName { + name: id_syntax.name().to_string(), + location: self.location(id_syntax.span()), + expected: "handle", + got: entry.kind(), + }), + None => Err(ValidationError::Recursive { + name: id_syntax.name().to_string(), + location: self.location(id_syntax.span()), + }), + } + }) + .collect::, _>>()?; + + Ok(HandleDatatype { + name: name.clone(), + supertypes, + }) + } + fn validate_int_repr( &self, type_: &BuiltinType, From 6530c73d42cd492681934b4290f5a697f52e71c3 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 17:31:09 -0800 Subject: [PATCH 0301/1772] witx: bump version to 0.5.0 --- proposals/clocks/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index f25555c0f..ead450c7c 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.4.0" +version = "0.5.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 43b72bb87f190f6796f7aa34e463832b5dfbb0f9 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 17:31:09 -0800 Subject: [PATCH 0302/1772] witx: bump version to 0.5.0 --- proposals/random/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index f25555c0f..ead450c7c 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.4.0" +version = "0.5.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From e8f577b9acdf6720d5fe3dd947d16750a1b97573 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Nov 2019 17:31:09 -0800 Subject: [PATCH 0303/1772] witx: bump version to 0.5.0 --- proposals/filesystem/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index f25555c0f..ead450c7c 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.4.0" +version = "0.5.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From ef507ed1f740164d3722d2413dae4e68dac23e8b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 18 Nov 2019 17:34:43 -0800 Subject: [PATCH 0304/1772] Announce the 11-21 meeting. Also, post the notes for the 11-07 meeting. --- proposals/clocks/meetings/2019/WASI-11-07.md | 61 +++++++++++++++++++- proposals/clocks/meetings/2019/WASI-11-21.md | 41 +++++++++++++ proposals/clocks/meetings/README.md | 1 + 3 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 proposals/clocks/meetings/2019/WASI-11-21.md diff --git a/proposals/clocks/meetings/2019/WASI-11-07.md b/proposals/clocks/meetings/2019/WASI-11-07.md index b23bb73c7..bda872b71 100644 --- a/proposals/clocks/meetings/2019/WASI-11-07.md +++ b/proposals/clocks/meetings/2019/WASI-11-07.md @@ -1,9 +1,9 @@ ![WASI logo](/WASI.png) -## Agenda for the November 24 video call of WASI Subgroup +## Agenda for the November 07 video call of WASI Subgroup - **Where**: zoom.us -- **When**: November 24, 17:00-18:00 UTC +- **When**: November 07, 17:00-18:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Dan Gohman @@ -43,3 +43,60 @@ Installation is required, see the calendar invite. 1. Closure ## Meeting Notes + +Attendees: + +Dan Gohman +Stefan Junker +Mark Bestavros +Nathaniel McCallum +Johnnie Birch Jr. +Mark S. Miller +Alon Zakai +Yury Delendik +Alex Chrichton +Luke Wagner +Mark McCaskey +Pat Hickey +Sam Clegg +Peter Huene +Alon Zakai + + +Meeting notes: + +## Making a first snapshot - call it “snapshot” + +AI: Dan to add a note to the phases document about how we make syntax changes to old versions while keeping the ABI compatible + +## Make clocks/random into capabilities + +DG: Currently clocks/random are ambient authority in WASI. Can keep compatibility with (C-style) programs out there which expect this to be the case? If so, how? +LW: Would this step mean that the program will always ask for clocks/random with the future option of allowing to not ask for it? +DG: What troubles me about that is that we’d still have to think about the mechanism for asking for it + +(discussion about clocks/random as stream vs. datagram) + +## Increase the timestamp range + +DG: this would be a good opportunity for someone who just wants to do this for the sake of learning how to change the API. happy to talk about this offline + +## Remove remaining "process" dependencies + +(discussion about exception handling in JS when interacting with WASM) + +DG: proc_raise is going away, proc_exit should ideally be implemented in terms of unwinding, though there are some details to figure out there. Can we remove the process-oriented clock identifiers? + +(Discussion, concluding in general approval) + +(Discussion of whether a “gas” clock could be defined; see also + +https://medium.com/@erights/a-pack-of-watchdogs-is-cheaper-than-gas-7e118edfb4cc + +Answer: there are some potentially subtle issues — programs could use this to determine how much time other parts of the program take, which may be undesirable. In any case, WASI itself would have no trouble defining new kinds of clocks in the future.) + +NM: Our implementation is able to implement the process-oriented clocks efficiently. If we remove them today, could they be reintroduced in the future if we want them? +DG: Yes, once we have modularity established and optional imports, it would be straightforward to add new features like this. + +NM: Is working on a proposal for a high level crypto API +MM: A request would be to not have the keys and algorithms in the same address space.. diff --git a/proposals/clocks/meetings/2019/WASI-11-21.md b/proposals/clocks/meetings/2019/WASI-11-21.md new file mode 100644 index 000000000..6b818553a --- /dev/null +++ b/proposals/clocks/meetings/2019/WASI-11-21.md @@ -0,0 +1,41 @@ +![WASI logo](/WASI.png) + +## Agenda for the November 21 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: November 21, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. `wasi_snapshot_preview1` update: now live! + 1. wasi-libc update here: https://github.com/CraneStation/wasi-libc/pull/136 + 1. Other toolchains should start moving to it as well. + 1. `wasi-sdk` and `wasi-libc` will be moving into the `WebAssembly org + 1. Discussed here: https://github.com/WebAssembly/meetings/blob/master/2019/CG-11-12.md + 1. Modularization update. + 1. Link to be posted soon. + 1. Calling for volunteers. + +1. Closure + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 2988c76ac..f1d790942 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -20,3 +20,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI October 15th in-person meeting](2019/WASI-10-15.md) * [WASI October 24th video call](2019/WASI-10-24.md) * [WASI November 7th video call](2019/WASI-11-07.md) + * [WASI November 21st video call](2019/WASI-11-21.md) From d0f637269606866cea4aeef4e8036474fd552670 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 18 Nov 2019 17:34:43 -0800 Subject: [PATCH 0305/1772] Announce the 11-21 meeting. Also, post the notes for the 11-07 meeting. --- proposals/random/meetings/2019/WASI-11-07.md | 61 +++++++++++++++++++- proposals/random/meetings/2019/WASI-11-21.md | 41 +++++++++++++ proposals/random/meetings/README.md | 1 + 3 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 proposals/random/meetings/2019/WASI-11-21.md diff --git a/proposals/random/meetings/2019/WASI-11-07.md b/proposals/random/meetings/2019/WASI-11-07.md index b23bb73c7..bda872b71 100644 --- a/proposals/random/meetings/2019/WASI-11-07.md +++ b/proposals/random/meetings/2019/WASI-11-07.md @@ -1,9 +1,9 @@ ![WASI logo](/WASI.png) -## Agenda for the November 24 video call of WASI Subgroup +## Agenda for the November 07 video call of WASI Subgroup - **Where**: zoom.us -- **When**: November 24, 17:00-18:00 UTC +- **When**: November 07, 17:00-18:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Dan Gohman @@ -43,3 +43,60 @@ Installation is required, see the calendar invite. 1. Closure ## Meeting Notes + +Attendees: + +Dan Gohman +Stefan Junker +Mark Bestavros +Nathaniel McCallum +Johnnie Birch Jr. +Mark S. Miller +Alon Zakai +Yury Delendik +Alex Chrichton +Luke Wagner +Mark McCaskey +Pat Hickey +Sam Clegg +Peter Huene +Alon Zakai + + +Meeting notes: + +## Making a first snapshot - call it “snapshot” + +AI: Dan to add a note to the phases document about how we make syntax changes to old versions while keeping the ABI compatible + +## Make clocks/random into capabilities + +DG: Currently clocks/random are ambient authority in WASI. Can keep compatibility with (C-style) programs out there which expect this to be the case? If so, how? +LW: Would this step mean that the program will always ask for clocks/random with the future option of allowing to not ask for it? +DG: What troubles me about that is that we’d still have to think about the mechanism for asking for it + +(discussion about clocks/random as stream vs. datagram) + +## Increase the timestamp range + +DG: this would be a good opportunity for someone who just wants to do this for the sake of learning how to change the API. happy to talk about this offline + +## Remove remaining "process" dependencies + +(discussion about exception handling in JS when interacting with WASM) + +DG: proc_raise is going away, proc_exit should ideally be implemented in terms of unwinding, though there are some details to figure out there. Can we remove the process-oriented clock identifiers? + +(Discussion, concluding in general approval) + +(Discussion of whether a “gas” clock could be defined; see also + +https://medium.com/@erights/a-pack-of-watchdogs-is-cheaper-than-gas-7e118edfb4cc + +Answer: there are some potentially subtle issues — programs could use this to determine how much time other parts of the program take, which may be undesirable. In any case, WASI itself would have no trouble defining new kinds of clocks in the future.) + +NM: Our implementation is able to implement the process-oriented clocks efficiently. If we remove them today, could they be reintroduced in the future if we want them? +DG: Yes, once we have modularity established and optional imports, it would be straightforward to add new features like this. + +NM: Is working on a proposal for a high level crypto API +MM: A request would be to not have the keys and algorithms in the same address space.. diff --git a/proposals/random/meetings/2019/WASI-11-21.md b/proposals/random/meetings/2019/WASI-11-21.md new file mode 100644 index 000000000..6b818553a --- /dev/null +++ b/proposals/random/meetings/2019/WASI-11-21.md @@ -0,0 +1,41 @@ +![WASI logo](/WASI.png) + +## Agenda for the November 21 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: November 21, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. `wasi_snapshot_preview1` update: now live! + 1. wasi-libc update here: https://github.com/CraneStation/wasi-libc/pull/136 + 1. Other toolchains should start moving to it as well. + 1. `wasi-sdk` and `wasi-libc` will be moving into the `WebAssembly org + 1. Discussed here: https://github.com/WebAssembly/meetings/blob/master/2019/CG-11-12.md + 1. Modularization update. + 1. Link to be posted soon. + 1. Calling for volunteers. + +1. Closure + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 2988c76ac..f1d790942 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -20,3 +20,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI October 15th in-person meeting](2019/WASI-10-15.md) * [WASI October 24th video call](2019/WASI-10-24.md) * [WASI November 7th video call](2019/WASI-11-07.md) + * [WASI November 21st video call](2019/WASI-11-21.md) From d7d92954194683effd9f0a330d89a76ddd22dca7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 18 Nov 2019 17:34:43 -0800 Subject: [PATCH 0306/1772] Announce the 11-21 meeting. Also, post the notes for the 11-07 meeting. --- .../filesystem/meetings/2019/WASI-11-07.md | 61 ++++++++++++++++++- .../filesystem/meetings/2019/WASI-11-21.md | 41 +++++++++++++ proposals/filesystem/meetings/README.md | 1 + 3 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 proposals/filesystem/meetings/2019/WASI-11-21.md diff --git a/proposals/filesystem/meetings/2019/WASI-11-07.md b/proposals/filesystem/meetings/2019/WASI-11-07.md index b23bb73c7..bda872b71 100644 --- a/proposals/filesystem/meetings/2019/WASI-11-07.md +++ b/proposals/filesystem/meetings/2019/WASI-11-07.md @@ -1,9 +1,9 @@ ![WASI logo](/WASI.png) -## Agenda for the November 24 video call of WASI Subgroup +## Agenda for the November 07 video call of WASI Subgroup - **Where**: zoom.us -- **When**: November 24, 17:00-18:00 UTC +- **When**: November 07, 17:00-18:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Dan Gohman @@ -43,3 +43,60 @@ Installation is required, see the calendar invite. 1. Closure ## Meeting Notes + +Attendees: + +Dan Gohman +Stefan Junker +Mark Bestavros +Nathaniel McCallum +Johnnie Birch Jr. +Mark S. Miller +Alon Zakai +Yury Delendik +Alex Chrichton +Luke Wagner +Mark McCaskey +Pat Hickey +Sam Clegg +Peter Huene +Alon Zakai + + +Meeting notes: + +## Making a first snapshot - call it “snapshot” + +AI: Dan to add a note to the phases document about how we make syntax changes to old versions while keeping the ABI compatible + +## Make clocks/random into capabilities + +DG: Currently clocks/random are ambient authority in WASI. Can keep compatibility with (C-style) programs out there which expect this to be the case? If so, how? +LW: Would this step mean that the program will always ask for clocks/random with the future option of allowing to not ask for it? +DG: What troubles me about that is that we’d still have to think about the mechanism for asking for it + +(discussion about clocks/random as stream vs. datagram) + +## Increase the timestamp range + +DG: this would be a good opportunity for someone who just wants to do this for the sake of learning how to change the API. happy to talk about this offline + +## Remove remaining "process" dependencies + +(discussion about exception handling in JS when interacting with WASM) + +DG: proc_raise is going away, proc_exit should ideally be implemented in terms of unwinding, though there are some details to figure out there. Can we remove the process-oriented clock identifiers? + +(Discussion, concluding in general approval) + +(Discussion of whether a “gas” clock could be defined; see also + +https://medium.com/@erights/a-pack-of-watchdogs-is-cheaper-than-gas-7e118edfb4cc + +Answer: there are some potentially subtle issues — programs could use this to determine how much time other parts of the program take, which may be undesirable. In any case, WASI itself would have no trouble defining new kinds of clocks in the future.) + +NM: Our implementation is able to implement the process-oriented clocks efficiently. If we remove them today, could they be reintroduced in the future if we want them? +DG: Yes, once we have modularity established and optional imports, it would be straightforward to add new features like this. + +NM: Is working on a proposal for a high level crypto API +MM: A request would be to not have the keys and algorithms in the same address space.. diff --git a/proposals/filesystem/meetings/2019/WASI-11-21.md b/proposals/filesystem/meetings/2019/WASI-11-21.md new file mode 100644 index 000000000..6b818553a --- /dev/null +++ b/proposals/filesystem/meetings/2019/WASI-11-21.md @@ -0,0 +1,41 @@ +![WASI logo](/WASI.png) + +## Agenda for the November 21 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: November 21, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. `wasi_snapshot_preview1` update: now live! + 1. wasi-libc update here: https://github.com/CraneStation/wasi-libc/pull/136 + 1. Other toolchains should start moving to it as well. + 1. `wasi-sdk` and `wasi-libc` will be moving into the `WebAssembly org + 1. Discussed here: https://github.com/WebAssembly/meetings/blob/master/2019/CG-11-12.md + 1. Modularization update. + 1. Link to be posted soon. + 1. Calling for volunteers. + +1. Closure + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 2988c76ac..f1d790942 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -20,3 +20,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI October 15th in-person meeting](2019/WASI-10-15.md) * [WASI October 24th video call](2019/WASI-10-24.md) * [WASI November 7th video call](2019/WASI-11-07.md) + * [WASI November 21st video call](2019/WASI-11-21.md) From e8b88e6efbc3d1a6fe4648295d8f244cd13cf685 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 19 Nov 2019 11:30:32 -0800 Subject: [PATCH 0307/1772] witx: Depend on wast 3.0.4 to fix build failure with 3.0.1 witx depends on wast 3.0.1, but it uses the comment() method of the Cursor type, which doesn't exist in version 3.0.1. This results in a build failure if attempting to build witx against wast 3.0.1. That method exists in the current 3.0.4, so update the wast dependency to 3.0.4. --- proposals/clocks/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index ead450c7c..11b0e4ba0 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -19,5 +19,5 @@ path = "src/main.rs" [dependencies] clap = "2" -wast = "3.0.1" +wast = "3.0.4" failure = "0.1" From d12b7820763460fcaad3e8e3b4d686d7f11f8493 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 19 Nov 2019 11:30:32 -0800 Subject: [PATCH 0308/1772] witx: Depend on wast 3.0.4 to fix build failure with 3.0.1 witx depends on wast 3.0.1, but it uses the comment() method of the Cursor type, which doesn't exist in version 3.0.1. This results in a build failure if attempting to build witx against wast 3.0.1. That method exists in the current 3.0.4, so update the wast dependency to 3.0.4. --- proposals/random/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index ead450c7c..11b0e4ba0 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -19,5 +19,5 @@ path = "src/main.rs" [dependencies] clap = "2" -wast = "3.0.1" +wast = "3.0.4" failure = "0.1" From 4133e48101bee33ccd47be6d6d5b7a240826d400 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 19 Nov 2019 11:30:32 -0800 Subject: [PATCH 0309/1772] witx: Depend on wast 3.0.4 to fix build failure with 3.0.1 witx depends on wast 3.0.1, but it uses the comment() method of the Cursor type, which doesn't exist in version 3.0.1. This results in a build failure if attempting to build witx against wast 3.0.1. That method exists in the current 3.0.4, so update the wast dependency to 3.0.4. --- proposals/filesystem/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index ead450c7c..11b0e4ba0 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -19,5 +19,5 @@ path = "src/main.rs" [dependencies] clap = "2" -wast = "3.0.1" +wast = "3.0.4" failure = "0.1" From 110d28ee01e934ce2d2c1090e616deb698370a10 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 22 Nov 2019 12:52:12 -0500 Subject: [PATCH 0310/1772] Re-organize witx AST (#154) The witx::ast types had some confusing choices that I blame on building the first draft of the tool in a hurry. This redesigns the AST a bit: I used Datatype/datatype in a number of places where witx syntax and wasm just call things types. The data-prefix has been dropped in many places. StructDatatype, UnionDatatype and friends still retain the "data" part of the name, but that seems less problematic. instead of two enumerations (DatatypeIdent and DatatypeVariant) holding different variations (arrays and pointers and builtins falling under Ident, everything else in variant) there is now just one enum Type that has each possible variation in a datatype Types can either be anonymous (e.g. an (array u8) in a function argument) or named (by (typename ...). An enum TypeRef gives a type either by Value(Type) or Name(NamedType). Only NamedTypes have docs. Instead of considering Aliases as a variation of a datatype, they are now encoded using TypeRef: (typename $a u32) is a NamedType { name: "a", dt: TypeRef::Value(Type::Builtin(BuiltinType::U32)) }. * witx: reorganize the AST this has highlighted some issues with the grammar, unfortunately * wip * continued work on tests * witx: all tests pass!! * rename Datatype to Type, so ast is closer to syntax * fix docs output --- proposals/clocks/tools/witx/src/ast.rs | 87 ++++----- proposals/clocks/tools/witx/src/coretypes.rs | 55 +++--- proposals/clocks/tools/witx/src/docs.rs | 85 +++++---- proposals/clocks/tools/witx/src/lib.rs | 12 +- proposals/clocks/tools/witx/src/parser.rs | 119 +++++++------ proposals/clocks/tools/witx/src/render.rs | 99 +++++------ proposals/clocks/tools/witx/src/toplevel.rs | 27 +-- proposals/clocks/tools/witx/src/validate.rs | 166 +++++++----------- .../clocks/tools/witx/tests/multimodule.rs | 47 ++--- proposals/clocks/tools/witx/tests/wasi.rs | 15 +- 10 files changed, 329 insertions(+), 383 deletions(-) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 341186820..2295cc94c 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -29,27 +29,27 @@ impl Document { entries, } } - pub fn datatype(&self, name: &Id) -> Option> { + pub fn typename(&self, name: &Id) -> Option> { self.entries.get(name).and_then(|e| match e { - Entry::Datatype(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + Entry::Typename(nt) => Some(nt.upgrade().expect("always possible to upgrade entry")), _ => None, }) } - pub fn datatypes<'a>(&'a self) -> impl Iterator> + 'a { + pub fn typenames<'a>(&'a self) -> impl Iterator> + 'a { self.definitions.iter().filter_map(|d| match d { - Definition::Datatype(d) => Some(d.clone()), + Definition::Typename(nt) => Some(nt.clone()), _ => None, }) } pub fn module(&self, name: &Id) -> Option> { self.entries.get(&name).and_then(|e| match e { - Entry::Module(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + Entry::Module(m) => Some(m.upgrade().expect("always possible to upgrade entry")), _ => None, }) } pub fn modules<'a>(&'a self) -> impl Iterator> + 'a { self.definitions.iter().filter_map(|d| match d { - Definition::Module(d) => Some(d.clone()), + Definition::Module(m) => Some(m.clone()), _ => None, }) } @@ -66,20 +66,20 @@ impl Eq for Document {} #[derive(Debug, Clone)] pub enum Definition { - Datatype(Rc), + Typename(Rc), Module(Rc), } #[derive(Debug, Clone)] pub enum Entry { - Datatype(Weak), + Typename(Weak), Module(Weak), } impl Entry { pub fn kind(&self) -> &'static str { match self { - Entry::Datatype { .. } => "datatype", + Entry::Typename { .. } => "typename", Entry::Module { .. } => "module", } } @@ -88,10 +88,10 @@ impl Entry { impl PartialEq for Entry { fn eq(&self, rhs: &Entry) -> bool { match (self, rhs) { - (Entry::Datatype(d), Entry::Datatype(d_rhs)) => { - d.upgrade() + (Entry::Typename(t), Entry::Typename(t_rhs)) => { + t.upgrade() .expect("possible to upgrade entry when part of document") - == d_rhs + == t_rhs .upgrade() .expect("possible to upgrade entry when part of document") } @@ -108,51 +108,63 @@ impl PartialEq for Entry { } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum DatatypeIdent { - Builtin(BuiltinType), - Array(Box), - Pointer(Box), - ConstPointer(Box), - Ident(Rc), +pub enum TypeRef { + Name(Rc), + Value(Rc), +} + +impl TypeRef { + pub fn type_(&self) -> Rc { + match self { + TypeRef::Name(named) => named.type_(), + TypeRef::Value(ref v) => v.clone(), + } + } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct Datatype { +pub struct NamedType { pub name: Id, - pub variant: DatatypeVariant, + pub dt: TypeRef, pub docs: String, } +impl NamedType { + pub fn type_(&self) -> Rc { + self.dt.type_() + } +} + #[derive(Debug, Clone, PartialEq, Eq)] -pub enum DatatypeVariant { - Alias(AliasDatatype), +pub enum Type { Enum(EnumDatatype), Flags(FlagsDatatype), Struct(StructDatatype), Union(UnionDatatype), Handle(HandleDatatype), + Array(TypeRef), + Pointer(TypeRef), + ConstPointer(TypeRef), + Builtin(BuiltinType), } -impl DatatypeVariant { +impl Type { pub fn kind(&self) -> &'static str { - use DatatypeVariant::*; + use Type::*; match self { - Alias(_) => "alias", Enum(_) => "enum", Flags(_) => "flags", Struct(_) => "struct", Union(_) => "union", Handle(_) => "handle", + Array(_) => "array", + Pointer(_) => "pointer", + ConstPointer(_) => "constpointer", + Builtin(_) => "builtin", } } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct AliasDatatype { - pub name: Id, - pub to: DatatypeIdent, -} - #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum IntRepr { U8, @@ -163,7 +175,6 @@ pub enum IntRepr { #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumDatatype { - pub name: Id, pub repr: IntRepr, pub variants: Vec, } @@ -176,7 +187,6 @@ pub struct EnumVariant { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsDatatype { - pub name: Id, pub repr: IntRepr, pub flags: Vec, } @@ -189,34 +199,31 @@ pub struct FlagsMember { #[derive(Debug, Clone, PartialEq, Eq)] pub struct StructDatatype { - pub name: Id, pub members: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct StructMember { pub name: Id, - pub type_: DatatypeIdent, + pub tref: TypeRef, pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionDatatype { - pub name: Id, pub variants: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionVariant { pub name: Id, - pub type_: DatatypeIdent, + pub tref: TypeRef, pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct HandleDatatype { - pub name: Id, - pub supertypes: Vec, + pub supertypes: Vec, } #[derive(Debug, Clone)] @@ -333,7 +340,7 @@ pub struct InterfaceFunc { #[derive(Debug, Clone, PartialEq, Eq)] pub struct InterfaceFuncParam { pub name: Id, - pub type_: DatatypeIdent, + pub tref: TypeRef, pub position: InterfaceFuncParamPosition, pub docs: String, } diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index f9919bc55..d772b3f54 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -1,6 +1,4 @@ -use crate::{ - BuiltinType, DatatypeIdent, DatatypeVariant, IntRepr, InterfaceFunc, InterfaceFuncParam, -}; +use crate::{BuiltinType, IntRepr, InterfaceFunc, InterfaceFuncParam, Type}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] /// Enumerates the types permitted for function arguments in the WebAssembly spec @@ -22,7 +20,7 @@ impl From for AtomType { #[derive(Debug, Copy, Clone, PartialEq, Eq)] /// Enumerates the strategies which may be used to pass a datatype as an argument -pub enum DatatypePassedBy { +pub enum TypePassedBy { /// Pass by value specifies the AtomType used to represent that value Value(AtomType), /// Pass by a pointer into linear memory @@ -31,36 +29,29 @@ pub enum DatatypePassedBy { PointerLengthPair, } -impl DatatypeIdent { +impl Type { /// Determine the simplest strategy by which a type may be passed. Value always preferred over /// Pointer. - pub fn passed_by(&self) -> DatatypePassedBy { - match &self { - DatatypeIdent::Builtin(b) => match b { - BuiltinType::String => DatatypePassedBy::PointerLengthPair, + pub fn passed_by(&self) -> TypePassedBy { + match self { + Type::Builtin(b) => match b { + BuiltinType::String => TypePassedBy::PointerLengthPair, BuiltinType::U8 | BuiltinType::U16 | BuiltinType::U32 | BuiltinType::S8 | BuiltinType::S16 - | BuiltinType::S32 => DatatypePassedBy::Value(AtomType::I32), - BuiltinType::U64 | BuiltinType::S64 => DatatypePassedBy::Value(AtomType::I64), - BuiltinType::F32 => DatatypePassedBy::Value(AtomType::F32), - BuiltinType::F64 => DatatypePassedBy::Value(AtomType::F64), - }, - DatatypeIdent::Array { .. } => DatatypePassedBy::PointerLengthPair, - DatatypeIdent::Pointer { .. } | DatatypeIdent::ConstPointer { .. } => { - DatatypePassedBy::Value(AtomType::I32) - } - DatatypeIdent::Ident(i) => match &i.variant { - DatatypeVariant::Alias(a) => a.to.passed_by(), - DatatypeVariant::Enum(e) => DatatypePassedBy::Value(e.repr.into()), - DatatypeVariant::Flags(f) => DatatypePassedBy::Value(f.repr.into()), - DatatypeVariant::Struct { .. } | DatatypeVariant::Union { .. } => { - DatatypePassedBy::Pointer - } - DatatypeVariant::Handle { .. } => DatatypePassedBy::Value(AtomType::I32), + | BuiltinType::S32 => TypePassedBy::Value(AtomType::I32), + BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), + BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), + BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), }, + Type::Array { .. } => TypePassedBy::PointerLengthPair, + Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), + Type::Enum(e) => TypePassedBy::Value(e.repr.into()), + Type::Flags(f) => TypePassedBy::Value(f.repr.into()), + Type::Struct { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), } } } @@ -108,12 +99,12 @@ impl InterfaceFuncParam { /// Gives the WebAssembly type that corresponds to passing this interface func parameter by value. /// Not all types can be passed by value: those which cannot return None pub fn pass_by_value(&self) -> Option { - match self.type_.passed_by() { - DatatypePassedBy::Value(atom) => Some(CoreParamType { + match self.tref.type_().passed_by() { + TypePassedBy::Value(atom) => Some(CoreParamType { signifies: CoreParamSignifies::Value(atom), param: self.clone(), }), - DatatypePassedBy::Pointer | DatatypePassedBy::PointerLengthPair => None, + TypePassedBy::Pointer | TypePassedBy::PointerLengthPair => None, } } @@ -121,12 +112,12 @@ impl InterfaceFuncParam { /// by reference. Some types are passed by reference using a single pointer, others /// require both a pointer and length. pub fn pass_by_reference(&self) -> Vec { - match self.type_.passed_by() { - DatatypePassedBy::Value(_) | DatatypePassedBy::Pointer => vec![CoreParamType { + match self.tref.type_().passed_by() { + TypePassedBy::Value(_) | TypePassedBy::Pointer => vec![CoreParamType { signifies: CoreParamSignifies::PointerTo, param: self.clone(), }], - DatatypePassedBy::PointerLengthPair => vec![ + TypePassedBy::PointerLengthPair => vec![ CoreParamType { signifies: CoreParamSignifies::PointerTo, param: self.clone(), diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs index 0e75c1e95..511186a47 100644 --- a/proposals/clocks/tools/witx/src/docs.rs +++ b/proposals/clocks/tools/witx/src/docs.rs @@ -7,7 +7,7 @@ pub trait Documentation { impl Documentation for Document { fn to_md(&self) -> String { let mut ret = "# Types\n".to_string(); - for d in self.datatypes() { + for d in self.typenames() { ret += &d.to_md(); } @@ -20,7 +20,7 @@ impl Documentation for Document { } impl BuiltinType { - fn name(&self) -> &'static str { + fn type_name(&self) -> &'static str { match self { BuiltinType::String => "string", BuiltinType::U8 => "u8", @@ -37,48 +37,47 @@ impl BuiltinType { } } -impl DatatypeIdent { - fn name(&self) -> String { - match self { - DatatypeIdent::Builtin(b) => b.name().to_string(), - DatatypeIdent::Array(a) => format!("Array<{}>", a.name()), - DatatypeIdent::Pointer(p) => format!("Pointer<{}>", p.name()), - DatatypeIdent::ConstPointer(p) => format!("ConstPointer<{}>", p.name()), - DatatypeIdent::Ident(i) => i.name.as_str().to_string(), - } - } -} - -impl Documentation for Datatype { +impl Documentation for NamedType { fn to_md(&self) -> String { - format!( - "## `{}`\n{}\n{}\n", - self.name.as_str(), - self.docs, - self.variant.to_md() - ) + let body = match &self.dt { + TypeRef::Value(v) => match &**v { + Type::Enum(a) => a.to_md(), + Type::Flags(a) => a.to_md(), + Type::Struct(a) => a.to_md(), + Type::Union(a) => a.to_md(), + Type::Handle(a) => a.to_md(), + Type::Array(a) => format!("Array of {}", a.type_name()), + Type::Pointer(a) => format!("Pointer to {}", a.type_name()), + Type::ConstPointer(a) => format!("Constant Pointer to {}", a.type_name()), + Type::Builtin(a) => format!("Builtin type {}", a.type_name()), + }, + TypeRef::Name(n) => format!("Alias to {}", n.name.as_str()), + }; + format!("## `{}`\n{}\n{}\n", self.name.as_str(), self.docs, body,) } } -impl Documentation for DatatypeVariant { - fn to_md(&self) -> String { +impl TypeRef { + fn type_name(&self) -> String { match self { - DatatypeVariant::Alias(a) => a.to_md(), - DatatypeVariant::Enum(a) => a.to_md(), - DatatypeVariant::Flags(a) => a.to_md(), - DatatypeVariant::Struct(a) => a.to_md(), - DatatypeVariant::Union(a) => a.to_md(), - DatatypeVariant::Handle(a) => a.to_md(), + TypeRef::Name(n) => n.name.as_str().to_string(), + TypeRef::Value(ref v) => match &**v { + Type::Array(a) => format!("Array<{}>", a.type_name()), + Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), + Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), + Type::Builtin(b) => b.type_name().to_string(), + Type::Enum { .. } + | Type::Flags { .. } + | Type::Struct { .. } + | Type::Union { .. } + | Type::Handle { .. } => { + unimplemented!("type_name of anonymous compound datatypes") + } + }, } } } -impl Documentation for AliasDatatype { - fn to_md(&self) -> String { - format!("Alias to `{}`", self.to.name()) - } -} - impl Documentation for EnumDatatype { fn to_md(&self) -> String { let variants = self @@ -89,7 +88,7 @@ impl Documentation for EnumDatatype { .join("\n"); format!( "Enum represented by `{}`\n\n### Variants:\n{}\n", - self.repr.name(), + self.repr.type_name(), variants ) } @@ -105,7 +104,7 @@ impl Documentation for FlagsDatatype { .join("\n"); format!( "Flags represented by `{}`\n\n### Flags:\n{}", - self.repr.name(), + self.repr.type_name(), flags ) } @@ -120,7 +119,7 @@ impl Documentation for StructDatatype { format!( "#### `{}`\nMember type: `{}`\n{}", m.name.as_str(), - m.type_.name(), + m.tref.type_name(), m.docs, ) }) @@ -139,7 +138,7 @@ impl Documentation for UnionDatatype { format!( "#### `{}`\nVariant type: `{}`\n{}", v.name.as_str(), - v.type_.name(), + v.tref.type_name(), v.docs, ) }) @@ -154,14 +153,14 @@ impl Documentation for HandleDatatype { let supertypes = self .supertypes .iter() - .map(|s| format!("* {}", s.name())) + .map(|s| format!("* {}", s.type_name())) .collect::>() .join("\n"); format!("### Handle supertypes:\n{}\n", supertypes) } } impl IntRepr { - fn name(&self) -> &'static str { + fn type_name(&self) -> &'static str { match self { IntRepr::U8 => "u8", IntRepr::U16 => "u16", @@ -209,7 +208,7 @@ impl Documentation for InterfaceFunc { format!( "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", name = f.name.as_str(), - type_ = f.type_.name(), + type_ = f.tref.type_name(), docs = f.docs ) }) @@ -222,7 +221,7 @@ impl Documentation for InterfaceFunc { format!( "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", name = f.name.as_str(), - type_ = f.type_.name(), + type_ = f.tref.type_name(), docs = f.docs ) }) diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index a781aa09b..1c538d9da 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -16,17 +16,17 @@ mod toplevel; mod validate; pub use ast::{ - AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntRepr, - InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, - ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, + BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, + FlagsMember, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, + InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, ModuleImport, + ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypeRef, UnionDatatype, UnionVariant, }; -pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; +pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; -pub use render::{Render, SExpr as RenderSExpr}; +pub use render::SExpr; pub use validate::ValidationError; use failure::Fail; diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 5c4e75f1d..d8088cd61 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -98,6 +98,24 @@ impl Parse<'_> for BuiltinType { } } +impl wast::parser::Peek for BuiltinType { + fn peek(cursor: wast::parser::Cursor<'_>) -> bool { + ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + } + fn display() -> &'static str { + "builtin type" + } +} #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct CommentSyntax<'a> { pub comments: Vec<&'a str>, @@ -178,41 +196,6 @@ impl<'a, T: Parse<'a>> Parse<'a> for Documented<'a, T> { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum DatatypeIdentSyntax<'a> { - Builtin(BuiltinType), - Array(Box>), - Pointer(Box>), - ConstPointer(Box>), - Ident(wast::Id<'a>), -} - -impl<'a> Parse<'a> for DatatypeIdentSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - if parser.peek::() { - Ok(DatatypeIdentSyntax::Ident(parser.parse()?)) - } else if parser.peek2::() { - Ok(DatatypeIdentSyntax::Array(parser.parens(|p| { - p.parse::()?; - Ok(Box::new(parser.parse()?)) - })?)) - } else if parser.peek::() { - parser.parens(|p| { - p.parse::()?; - if p.peek::() { - p.parse::()?; - Ok(DatatypeIdentSyntax::ConstPointer(Box::new(p.parse()?))) - } else { - p.parse::()?; - Ok(DatatypeIdentSyntax::Pointer(Box::new(p.parse()?))) - } - }) - } else { - Ok(DatatypeIdentSyntax::Builtin(parser.parse()?)) - } - } -} - struct AtWitx; impl Parse<'_> for AtWitx { @@ -329,36 +312,60 @@ impl<'a> Parse<'a> for TypenameSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub enum TypedefSyntax<'a> { - Ident(DatatypeIdentSyntax<'a>), Enum(EnumSyntax<'a>), Flags(FlagsSyntax<'a>), Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), Handle(HandleSyntax<'a>), + Array(Box>), + Pointer(Box>), + ConstPointer(Box>), + Builtin(BuiltinType), + Ident(wast::Id<'a>), } impl<'a> Parse<'a> for TypedefSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - if !parser.peek::() || parser.peek2::() || parser.peek2::() - { - return Ok(TypedefSyntax::Ident(parser.parse()?)); + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(TypedefSyntax::Ident(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Builtin(parser.parse()?)) + } else if l.peek::() { + parser.parens(|parser| { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(TypedefSyntax::Enum(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Flags(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Struct(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Union(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Handle(parser.parse()?)) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::Array(Box::new(parser.parse()?))) + } else if l.peek::() { + parser.parse::()?; + let mut l = parser.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::ConstPointer(Box::new(parser.parse()?))) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) + } else { + Err(l.error()) + } + } else { + Err(l.error()) + } + }) + } else { + Err(l.error()) } - parser.parens(|parser| { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(TypedefSyntax::Enum(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Flags(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Struct(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Union(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Handle(parser.parse()?)) - } else { - Err(l.error()) - } - }) } } @@ -419,7 +426,7 @@ impl<'a> Parse<'a> for StructSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FieldSyntax<'a> { pub name: wast::Id<'a>, - pub type_: DatatypeIdentSyntax<'a>, + pub type_: TypedefSyntax<'a>, } impl<'a> Parse<'a> for FieldSyntax<'a> { diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 2f2f8526f..c9ec34b1f 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -3,8 +3,8 @@ use std::fmt; impl fmt::Display for Document { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for d in self.datatypes() { - write!(f, "{}\n", d.to_sexpr())?; + for d in self.typenames() { + write!(f, "{}\n", d.definition_sexpr())?; } for m in self.modules() { write!(f, "{}\n", m.to_sexpr())?; @@ -68,17 +68,13 @@ impl SExpr { } } -pub trait Render { - fn to_sexpr(&self) -> SExpr; -} - -impl Render for Id { +impl Id { fn to_sexpr(&self) -> SExpr { SExpr::ident(self.as_str()) } } -impl Render for BuiltinType { +impl BuiltinType { fn to_sexpr(&self) -> SExpr { match self { BuiltinType::String => SExpr::word("string"), @@ -96,57 +92,50 @@ impl Render for BuiltinType { } } -impl Render for DatatypeIdent { - fn to_sexpr(&self) -> SExpr { - match self { - DatatypeIdent::Builtin(b) => b.to_sexpr(), - DatatypeIdent::Array(a) => SExpr::Vec(vec![SExpr::word("array"), a.to_sexpr()]), - DatatypeIdent::Pointer(p) => SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("pointer"), - p.to_sexpr(), - ]), - DatatypeIdent::ConstPointer(p) => SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("const_pointer"), - p.to_sexpr(), - ]), - DatatypeIdent::Ident(i) => i.name.to_sexpr(), - } - } -} - -impl Render for Datatype { - fn to_sexpr(&self) -> SExpr { - let name = self.name.to_sexpr(); - let body = self.variant.to_sexpr(); +impl NamedType { + fn definition_sexpr(&self) -> SExpr { + let body = self.dt.to_sexpr(); SExpr::docs( &self.docs, - SExpr::Vec(vec![SExpr::word("typename"), name, body]), + SExpr::Vec(vec![SExpr::word("typename"), self.name.to_sexpr(), body]), ) } } -impl Render for DatatypeVariant { +impl TypeRef { fn to_sexpr(&self) -> SExpr { match self { - DatatypeVariant::Alias(a) => a.to_sexpr(), - DatatypeVariant::Enum(a) => a.to_sexpr(), - DatatypeVariant::Flags(a) => a.to_sexpr(), - DatatypeVariant::Struct(a) => a.to_sexpr(), - DatatypeVariant::Union(a) => a.to_sexpr(), - DatatypeVariant::Handle(a) => a.to_sexpr(), + TypeRef::Name(n) => n.name.to_sexpr(), + TypeRef::Value(v) => v.to_sexpr(), } } } -impl Render for AliasDatatype { +impl Type { fn to_sexpr(&self) -> SExpr { - self.to.to_sexpr() + match self { + Type::Enum(a) => a.to_sexpr(), + Type::Flags(a) => a.to_sexpr(), + Type::Struct(a) => a.to_sexpr(), + Type::Union(a) => a.to_sexpr(), + Type::Handle(a) => a.to_sexpr(), + Type::Array(a) => SExpr::Vec(vec![SExpr::word("array"), a.to_sexpr()]), + Type::Pointer(p) => SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("pointer"), + p.to_sexpr(), + ]), + Type::ConstPointer(p) => SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("const_pointer"), + p.to_sexpr(), + ]), + Type::Builtin(b) => b.to_sexpr(), + } } } -impl Render for EnumDatatype { +impl EnumDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("enum"), self.repr.to_sexpr()]; let variants = self @@ -158,7 +147,7 @@ impl Render for EnumDatatype { } } -impl Render for FlagsDatatype { +impl FlagsDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; let flags = self @@ -170,7 +159,7 @@ impl Render for FlagsDatatype { } } -impl Render for StructDatatype { +impl StructDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("struct")]; let members = self @@ -182,7 +171,7 @@ impl Render for StructDatatype { SExpr::Vec(vec![ SExpr::word("field"), m.name.to_sexpr(), - m.type_.to_sexpr(), + m.tref.to_sexpr(), ]), ) }) @@ -191,7 +180,7 @@ impl Render for StructDatatype { } } -impl Render for UnionDatatype { +impl UnionDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("union")]; let variants = self @@ -203,7 +192,7 @@ impl Render for UnionDatatype { SExpr::Vec(vec![ SExpr::word("field"), v.name.to_sexpr(), - v.type_.to_sexpr(), + v.tref.to_sexpr(), ]), ) }) @@ -212,7 +201,7 @@ impl Render for UnionDatatype { } } -impl Render for HandleDatatype { +impl HandleDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("handle")]; let supertypes = self @@ -223,7 +212,7 @@ impl Render for HandleDatatype { SExpr::Vec([header, supertypes].concat()) } } -impl Render for IntRepr { +impl IntRepr { fn to_sexpr(&self) -> SExpr { match self { IntRepr::U8 => SExpr::word("u8"), @@ -234,7 +223,7 @@ impl Render for IntRepr { } } -impl Render for Module { +impl Module { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("module"), self.name.to_sexpr()]; let definitions = self @@ -246,7 +235,7 @@ impl Render for Module { } } -impl Render for ModuleImport { +impl ModuleImport { fn to_sexpr(&self) -> SExpr { let variant = match self.variant { ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), @@ -262,7 +251,7 @@ impl Render for ModuleImport { } } -impl Render for InterfaceFunc { +impl InterfaceFunc { fn to_sexpr(&self) -> SExpr { let header = vec![ SExpr::annot("interface"), @@ -281,7 +270,7 @@ impl Render for InterfaceFunc { SExpr::Vec(vec![ SExpr::word("param"), f.name.to_sexpr(), - f.type_.to_sexpr(), + f.tref.to_sexpr(), ]), ) }) @@ -295,7 +284,7 @@ impl Render for InterfaceFunc { SExpr::Vec(vec![ SExpr::word("result"), f.name.to_sexpr(), - f.type_.to_sexpr(), + f.tref.to_sexpr(), ]), ) }) diff --git a/proposals/clocks/tools/witx/src/toplevel.rs b/proposals/clocks/tools/witx/src/toplevel.rs index 2e0738a6b..4fb13b8d7 100644 --- a/proposals/clocks/tools/witx/src/toplevel.rs +++ b/proposals/clocks/tools/witx/src/toplevel.rs @@ -107,21 +107,11 @@ mod test { ) .expect("parse"); - match &doc.datatype(&Id::new("b_float")).unwrap().variant { - DatatypeVariant::Alias(a) => { - assert_eq!(a.name.as_str(), "b_float"); - assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::F64)); - } - other => panic!("expected alias, got {:?}", other), - } + let b_float = doc.typename(&Id::new("b_float")).unwrap(); + assert_eq!(*b_float.type_(), Type::Builtin(BuiltinType::F64)); - match &doc.datatype(&Id::new("c_int")).unwrap().variant { - DatatypeVariant::Alias(a) => { - assert_eq!(a.name.as_str(), "c_int"); - assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::U32)); - } - other => panic!("expected alias, got {:?}", other), - } + let c_int = doc.typename(&Id::new("c_int")).unwrap(); + assert_eq!(*c_int.type_(), Type::Builtin(BuiltinType::U32)); } #[test] @@ -137,13 +127,8 @@ mod test { ) .expect("parse"); - match &doc.datatype(&Id::new("d_char")).unwrap().variant { - DatatypeVariant::Alias(a) => { - assert_eq!(a.name.as_str(), "d_char"); - assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::U8)); - } - other => panic!("expected alias, got {:?}", other), - } + let d_char = doc.typename(&Id::new("d_char")).unwrap(); + assert_eq!(*d_char.type_(), Type::Builtin(BuiltinType::U8)); } #[test] diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 5781ebd06..f9cc2a169 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -1,14 +1,13 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ - CommentSyntax, DatatypeIdentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, - HandleSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, + ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, - AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, - Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, - IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, - ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, - UnionDatatype, UnionVariant, + BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, + HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, + Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, + StructDatatype, StructMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, }; use failure::Fail; use std::collections::HashMap; @@ -168,39 +167,17 @@ impl DocValidationScope<'_> { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; let docs = comments.docs(); - let variant = - match &decl.def { - TypedefSyntax::Ident(syntax) => DatatypeVariant::Alias(AliasDatatype { - name: name.clone(), - to: self.validate_datatype_ident(&syntax)?, - }), - TypedefSyntax::Enum(syntax) => DatatypeVariant::Enum(self.validate_enum( - &name, - &syntax, - decl.ident.span(), - )?), - TypedefSyntax::Flags(syntax) => DatatypeVariant::Flags( - self.validate_flags(&name, &syntax, decl.ident.span())?, - ), - TypedefSyntax::Struct(syntax) => DatatypeVariant::Struct( - self.validate_struct(&name, &syntax, decl.ident.span())?, - ), - TypedefSyntax::Union(syntax) => DatatypeVariant::Union( - self.validate_union(&name, &syntax, decl.ident.span())?, - ), - TypedefSyntax::Handle(syntax) => DatatypeVariant::Handle( - self.validate_handle(&name, syntax, decl.ident.span())?, - ), - }; - let rc_datatype = Rc::new(Datatype { + let dt = self.validate_datatype(&decl.def, decl.ident.span())?; + + let rc_datatype = Rc::new(NamedType { name: name.clone(), - variant, + dt, docs, }); self.doc .entries - .insert(name, Entry::Datatype(Rc::downgrade(&rc_datatype))); - Ok(Definition::Datatype(rc_datatype)) + .insert(name, Entry::Typename(Rc::downgrade(&rc_datatype))); + Ok(Definition::Typename(rc_datatype)) } DeclSyntax::Module(syntax) => { let name = self.introduce(&syntax.name)?; @@ -225,45 +202,51 @@ impl DocValidationScope<'_> { } } - fn validate_datatype_ident( + fn validate_datatype( &self, - syntax: &DatatypeIdentSyntax, - ) -> Result { + syntax: &TypedefSyntax, + span: wast::Span, + ) -> Result { match syntax { - DatatypeIdentSyntax::Builtin(b) => Ok(DatatypeIdent::Builtin(*b)), - DatatypeIdentSyntax::Array(a) => Ok(DatatypeIdent::Array(Box::new( - self.validate_datatype_ident(&a)?, - ))), - DatatypeIdentSyntax::Pointer(a) => Ok(DatatypeIdent::Pointer(Box::new( - self.validate_datatype_ident(&a)?, - ))), - DatatypeIdentSyntax::ConstPointer(a) => Ok(DatatypeIdent::ConstPointer(Box::new( - self.validate_datatype_ident(&a)?, - ))), - DatatypeIdentSyntax::Ident(i) => { - let id = self.get(i)?; - match self.doc.entries.get(&id) { - Some(Entry::Datatype(weak_d)) => Ok(DatatypeIdent::Ident( - weak_d.upgrade().expect("weak backref to defined type"), + TypedefSyntax::Ident(syntax) => { + let i = self.get(syntax)?; + match self.doc.entries.get(&i) { + Some(Entry::Typename(weak_ref)) => Ok(TypeRef::Name( + weak_ref.upgrade().expect("weak backref to defined type"), )), Some(e) => Err(ValidationError::WrongKindName { - name: i.name().to_string(), - location: self.location(i.span()), + name: i.as_str().to_string(), + location: self.location(syntax.span()), expected: "datatype", got: e.kind(), }), None => Err(ValidationError::Recursive { - name: i.name().to_string(), - location: self.location(i.span()), + name: i.as_str().to_string(), + location: self.location(syntax.span()), }), } } + other => Ok(TypeRef::Value(Rc::new(match other { + TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), + TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), + TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), + TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), + TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), + TypedefSyntax::Array(syntax) => Type::Array(self.validate_datatype(syntax, span)?), + TypedefSyntax::Pointer(syntax) => { + Type::Pointer(self.validate_datatype(syntax, span)?) + } + TypedefSyntax::ConstPointer(syntax) => { + Type::ConstPointer(self.validate_datatype(syntax, span)?) + } + TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), + TypedefSyntax::Ident { .. } => unreachable!(), + }))), } } fn validate_enum( &self, - name: &Id, syntax: &EnumSyntax, span: wast::Span, ) -> Result { @@ -279,16 +262,11 @@ impl DocValidationScope<'_> { }) .collect::, _>>()?; - Ok(EnumDatatype { - name: name.clone(), - repr, - variants, - }) + Ok(EnumDatatype { repr, variants }) } fn validate_flags( &self, - name: &Id, syntax: &FlagsSyntax, span: wast::Span, ) -> Result { @@ -304,16 +282,11 @@ impl DocValidationScope<'_> { }) .collect::, _>>()?; - Ok(FlagsDatatype { - name: name.clone(), - repr, - flags, - }) + Ok(FlagsDatatype { repr, flags }) } fn validate_struct( &self, - name: &Id, syntax: &StructSyntax, _span: wast::Span, ) -> Result { @@ -324,21 +297,17 @@ impl DocValidationScope<'_> { .map(|f| { let name = member_scope .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let type_ = self.validate_datatype_ident(&f.item.type_)?; + let tref = self.validate_datatype(&f.item.type_, f.item.name.span())?; let docs = f.comments.docs(); - Ok(StructMember { name, type_, docs }) + Ok(StructMember { name, tref, docs }) }) .collect::, _>>()?; - Ok(StructDatatype { - name: name.clone(), - members, - }) + Ok(StructDatatype { members }) } fn validate_union( &self, - name: &Id, syntax: &UnionSyntax, _span: wast::Span, ) -> Result { @@ -349,21 +318,17 @@ impl DocValidationScope<'_> { .map(|f| { let name = variant_scope .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let type_ = self.validate_datatype_ident(&f.item.type_)?; + let tref = self.validate_datatype(&f.item.type_, f.item.name.span())?; let docs = f.comments.docs(); - Ok(UnionVariant { name, type_, docs }) + Ok(UnionVariant { name, tref, docs }) }) .collect::, _>>()?; - Ok(UnionDatatype { - name: name.clone(), - variants, - }) + Ok(UnionDatatype { variants }) } fn validate_handle( &self, - name: &Id, syntax: &HandleSyntax, _span: wast::Span, ) -> Result { @@ -373,15 +338,15 @@ impl DocValidationScope<'_> { .map(|id_syntax| { let id = self.get(&id_syntax)?; match self.doc.entries.get(&id) { - Some(Entry::Datatype(weak_d)) => { - let d = weak_d.upgrade().expect("weak backref to defined type"); - match &d.variant { - DatatypeVariant::Handle { .. } => Ok(DatatypeIdent::Ident(d)), - _ => Err(ValidationError::WrongKindName { + Some(Entry::Typename(weak_ref)) => { + let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); + match &*named_dt.type_() { + Type::Handle { .. } => Ok(TypeRef::Name(named_dt)), + other => Err(ValidationError::WrongKindName { name: id_syntax.name().to_string(), location: self.location(id_syntax.span()), expected: "handle", - got: d.variant.kind(), + got: other.kind(), }), } } @@ -397,12 +362,9 @@ impl DocValidationScope<'_> { }), } }) - .collect::, _>>()?; + .collect::, _>>()?; - Ok(HandleDatatype { - name: name.clone(), - supertypes, - }) + Ok(HandleDatatype { supertypes }) } fn validate_int_repr( @@ -472,7 +434,9 @@ impl<'a> ModuleValidation<'a> { f.item.name.name(), self.doc.location(f.item.name.span()), )?, - type_: self.doc.validate_datatype_ident(&f.item.type_)?, + tref: self + .doc + .validate_datatype(&f.item.type_, f.item.name.span())?, position: InterfaceFuncParamPosition::Param(ix), docs: f.comments.docs(), }) @@ -483,10 +447,12 @@ impl<'a> ModuleValidation<'a> { .iter() .enumerate() .map(|(ix, f)| { - let type_ = self.doc.validate_datatype_ident(&f.item.type_)?; + let tref = self + .doc + .validate_datatype(&f.item.type_, f.item.name.span())?; if ix == 0 { - match type_.passed_by() { - DatatypePassedBy::Value(_) => {} + match tref.type_().passed_by() { + TypePassedBy::Value(_) => {} _ => Err(ValidationError::InvalidFirstResultType { location: self.doc.location(f.item.name.span()), })?, @@ -497,7 +463,7 @@ impl<'a> ModuleValidation<'a> { f.item.name.name(), self.doc.location(f.item.name.span()), )?, - type_, + tref, position: InterfaceFuncParamPosition::Result(ix), docs: f.comments.docs(), }) diff --git a/proposals/clocks/tools/witx/tests/multimodule.rs b/proposals/clocks/tools/witx/tests/multimodule.rs index e9cc5ecb9..47fb34755 100644 --- a/proposals/clocks/tools/witx/tests/multimodule.rs +++ b/proposals/clocks/tools/witx/tests/multimodule.rs @@ -1,4 +1,4 @@ -use witx::{load, BuiltinType, DatatypeIdent, DatatypeVariant, Id}; +use witx::{load, BuiltinType, Id, Type, TypeRef}; #[test] fn validate_multimodule() { @@ -9,44 +9,35 @@ fn validate_multimodule() { ]) .unwrap_or_else(|e| panic!("failed to validate: {}", e)); - println!("{}", doc); + //println!("{}", doc); // Check that the `a` both modules use is what we expect: - let type_a = doc.datatype(&Id::new("a")).expect("type a exists"); - match &type_a.variant { - DatatypeVariant::Alias(alias) => match alias.to { - DatatypeIdent::Builtin(b) => assert_eq!(b, BuiltinType::U32), - _ => panic!("a is an alias u32"), - }, - _ => panic!("a is an alias to u32"), - } + let type_a = doc.typename(&Id::new("a")).expect("type a exists"); + assert_eq!(*type_a.type_(), Type::Builtin(BuiltinType::U32)); // `b` is a struct with a single member of type `a` - let type_b = doc.datatype(&Id::new("b")).expect("type b exists"); - match &type_b.variant { - DatatypeVariant::Struct(struct_) => { + let type_b = doc.typename(&Id::new("b")).expect("type b exists"); + match &*type_b.type_() { + Type::Struct(struct_) => { assert_eq!(struct_.members.len(), 1); - match &struct_.members.get(0).unwrap().type_ { - DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), - _ => panic!("b.0 has type a"), - } + assert_eq!( + struct_.members.get(0).unwrap().tref, + TypeRef::Name(type_a.clone()) + ); } _ => panic!("b is a struct"), } // `c` is a struct with a two members of type `a` - let type_c = doc.datatype(&Id::new("c")).expect("type c exists"); - match &type_c.variant { - DatatypeVariant::Struct(struct_) => { + let type_c = doc.typename(&Id::new("c")).expect("type c exists"); + match &*type_c.type_() { + Type::Struct(struct_) => { assert_eq!(struct_.members.len(), 2); - match &struct_.members.get(0).unwrap().type_ { - DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), - _ => panic!("c.0 has type a"), - } - match &struct_.members.get(1).unwrap().type_ { - DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), - _ => panic!("c.1 has type a"), - } + assert_eq!( + struct_.members.get(0).unwrap().tref, + TypeRef::Name(type_a.clone()) + ); + assert_eq!(struct_.members.get(1).unwrap().tref, TypeRef::Name(type_a)); } _ => panic!("c is a struct"), } diff --git a/proposals/clocks/tools/witx/tests/wasi.rs b/proposals/clocks/tools/witx/tests/wasi.rs index 938c78067..6d6ebc120 100644 --- a/proposals/clocks/tools/witx/tests/wasi.rs +++ b/proposals/clocks/tools/witx/tests/wasi.rs @@ -33,8 +33,8 @@ fn render_roundtrip() { // I'd just assert_eq, but when it fails the debug print is thousands of lines long and impossible // to figure out where they are unequal. if doc != doc2 { - for type_ in doc.datatypes() { - let type2 = doc2.datatype(&type_.name).expect("doc2 missing datatype"); + for type_ in doc.typenames() { + let type2 = doc2.typename(&type_.name).expect("doc2 missing datatype"); assert_eq!(type_, type2); } for mod_ in doc.modules() { @@ -52,3 +52,14 @@ fn render_roundtrip() { // This should be equivelant to the above, but just in case some code changes where it isnt: assert_eq!(doc, doc2); } + +#[test] +fn document_wasi_snapshot() { + use witx::Documentation; + println!( + "{}", + witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)) + .to_md() + ); +} From 30d5983db7085c5f47ea9d71b392bcb41bb33b4b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 22 Nov 2019 12:52:12 -0500 Subject: [PATCH 0311/1772] Re-organize witx AST (#154) The witx::ast types had some confusing choices that I blame on building the first draft of the tool in a hurry. This redesigns the AST a bit: I used Datatype/datatype in a number of places where witx syntax and wasm just call things types. The data-prefix has been dropped in many places. StructDatatype, UnionDatatype and friends still retain the "data" part of the name, but that seems less problematic. instead of two enumerations (DatatypeIdent and DatatypeVariant) holding different variations (arrays and pointers and builtins falling under Ident, everything else in variant) there is now just one enum Type that has each possible variation in a datatype Types can either be anonymous (e.g. an (array u8) in a function argument) or named (by (typename ...). An enum TypeRef gives a type either by Value(Type) or Name(NamedType). Only NamedTypes have docs. Instead of considering Aliases as a variation of a datatype, they are now encoded using TypeRef: (typename $a u32) is a NamedType { name: "a", dt: TypeRef::Value(Type::Builtin(BuiltinType::U32)) }. * witx: reorganize the AST this has highlighted some issues with the grammar, unfortunately * wip * continued work on tests * witx: all tests pass!! * rename Datatype to Type, so ast is closer to syntax * fix docs output --- proposals/random/tools/witx/src/ast.rs | 87 ++++----- proposals/random/tools/witx/src/coretypes.rs | 55 +++--- proposals/random/tools/witx/src/docs.rs | 85 +++++---- proposals/random/tools/witx/src/lib.rs | 12 +- proposals/random/tools/witx/src/parser.rs | 119 +++++++------ proposals/random/tools/witx/src/render.rs | 99 +++++------ proposals/random/tools/witx/src/toplevel.rs | 27 +-- proposals/random/tools/witx/src/validate.rs | 166 +++++++----------- .../random/tools/witx/tests/multimodule.rs | 47 ++--- proposals/random/tools/witx/tests/wasi.rs | 15 +- 10 files changed, 329 insertions(+), 383 deletions(-) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 341186820..2295cc94c 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -29,27 +29,27 @@ impl Document { entries, } } - pub fn datatype(&self, name: &Id) -> Option> { + pub fn typename(&self, name: &Id) -> Option> { self.entries.get(name).and_then(|e| match e { - Entry::Datatype(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + Entry::Typename(nt) => Some(nt.upgrade().expect("always possible to upgrade entry")), _ => None, }) } - pub fn datatypes<'a>(&'a self) -> impl Iterator> + 'a { + pub fn typenames<'a>(&'a self) -> impl Iterator> + 'a { self.definitions.iter().filter_map(|d| match d { - Definition::Datatype(d) => Some(d.clone()), + Definition::Typename(nt) => Some(nt.clone()), _ => None, }) } pub fn module(&self, name: &Id) -> Option> { self.entries.get(&name).and_then(|e| match e { - Entry::Module(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + Entry::Module(m) => Some(m.upgrade().expect("always possible to upgrade entry")), _ => None, }) } pub fn modules<'a>(&'a self) -> impl Iterator> + 'a { self.definitions.iter().filter_map(|d| match d { - Definition::Module(d) => Some(d.clone()), + Definition::Module(m) => Some(m.clone()), _ => None, }) } @@ -66,20 +66,20 @@ impl Eq for Document {} #[derive(Debug, Clone)] pub enum Definition { - Datatype(Rc), + Typename(Rc), Module(Rc), } #[derive(Debug, Clone)] pub enum Entry { - Datatype(Weak), + Typename(Weak), Module(Weak), } impl Entry { pub fn kind(&self) -> &'static str { match self { - Entry::Datatype { .. } => "datatype", + Entry::Typename { .. } => "typename", Entry::Module { .. } => "module", } } @@ -88,10 +88,10 @@ impl Entry { impl PartialEq for Entry { fn eq(&self, rhs: &Entry) -> bool { match (self, rhs) { - (Entry::Datatype(d), Entry::Datatype(d_rhs)) => { - d.upgrade() + (Entry::Typename(t), Entry::Typename(t_rhs)) => { + t.upgrade() .expect("possible to upgrade entry when part of document") - == d_rhs + == t_rhs .upgrade() .expect("possible to upgrade entry when part of document") } @@ -108,51 +108,63 @@ impl PartialEq for Entry { } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum DatatypeIdent { - Builtin(BuiltinType), - Array(Box), - Pointer(Box), - ConstPointer(Box), - Ident(Rc), +pub enum TypeRef { + Name(Rc), + Value(Rc), +} + +impl TypeRef { + pub fn type_(&self) -> Rc { + match self { + TypeRef::Name(named) => named.type_(), + TypeRef::Value(ref v) => v.clone(), + } + } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct Datatype { +pub struct NamedType { pub name: Id, - pub variant: DatatypeVariant, + pub dt: TypeRef, pub docs: String, } +impl NamedType { + pub fn type_(&self) -> Rc { + self.dt.type_() + } +} + #[derive(Debug, Clone, PartialEq, Eq)] -pub enum DatatypeVariant { - Alias(AliasDatatype), +pub enum Type { Enum(EnumDatatype), Flags(FlagsDatatype), Struct(StructDatatype), Union(UnionDatatype), Handle(HandleDatatype), + Array(TypeRef), + Pointer(TypeRef), + ConstPointer(TypeRef), + Builtin(BuiltinType), } -impl DatatypeVariant { +impl Type { pub fn kind(&self) -> &'static str { - use DatatypeVariant::*; + use Type::*; match self { - Alias(_) => "alias", Enum(_) => "enum", Flags(_) => "flags", Struct(_) => "struct", Union(_) => "union", Handle(_) => "handle", + Array(_) => "array", + Pointer(_) => "pointer", + ConstPointer(_) => "constpointer", + Builtin(_) => "builtin", } } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct AliasDatatype { - pub name: Id, - pub to: DatatypeIdent, -} - #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum IntRepr { U8, @@ -163,7 +175,6 @@ pub enum IntRepr { #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumDatatype { - pub name: Id, pub repr: IntRepr, pub variants: Vec, } @@ -176,7 +187,6 @@ pub struct EnumVariant { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsDatatype { - pub name: Id, pub repr: IntRepr, pub flags: Vec, } @@ -189,34 +199,31 @@ pub struct FlagsMember { #[derive(Debug, Clone, PartialEq, Eq)] pub struct StructDatatype { - pub name: Id, pub members: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct StructMember { pub name: Id, - pub type_: DatatypeIdent, + pub tref: TypeRef, pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionDatatype { - pub name: Id, pub variants: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionVariant { pub name: Id, - pub type_: DatatypeIdent, + pub tref: TypeRef, pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct HandleDatatype { - pub name: Id, - pub supertypes: Vec, + pub supertypes: Vec, } #[derive(Debug, Clone)] @@ -333,7 +340,7 @@ pub struct InterfaceFunc { #[derive(Debug, Clone, PartialEq, Eq)] pub struct InterfaceFuncParam { pub name: Id, - pub type_: DatatypeIdent, + pub tref: TypeRef, pub position: InterfaceFuncParamPosition, pub docs: String, } diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index f9919bc55..d772b3f54 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -1,6 +1,4 @@ -use crate::{ - BuiltinType, DatatypeIdent, DatatypeVariant, IntRepr, InterfaceFunc, InterfaceFuncParam, -}; +use crate::{BuiltinType, IntRepr, InterfaceFunc, InterfaceFuncParam, Type}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] /// Enumerates the types permitted for function arguments in the WebAssembly spec @@ -22,7 +20,7 @@ impl From for AtomType { #[derive(Debug, Copy, Clone, PartialEq, Eq)] /// Enumerates the strategies which may be used to pass a datatype as an argument -pub enum DatatypePassedBy { +pub enum TypePassedBy { /// Pass by value specifies the AtomType used to represent that value Value(AtomType), /// Pass by a pointer into linear memory @@ -31,36 +29,29 @@ pub enum DatatypePassedBy { PointerLengthPair, } -impl DatatypeIdent { +impl Type { /// Determine the simplest strategy by which a type may be passed. Value always preferred over /// Pointer. - pub fn passed_by(&self) -> DatatypePassedBy { - match &self { - DatatypeIdent::Builtin(b) => match b { - BuiltinType::String => DatatypePassedBy::PointerLengthPair, + pub fn passed_by(&self) -> TypePassedBy { + match self { + Type::Builtin(b) => match b { + BuiltinType::String => TypePassedBy::PointerLengthPair, BuiltinType::U8 | BuiltinType::U16 | BuiltinType::U32 | BuiltinType::S8 | BuiltinType::S16 - | BuiltinType::S32 => DatatypePassedBy::Value(AtomType::I32), - BuiltinType::U64 | BuiltinType::S64 => DatatypePassedBy::Value(AtomType::I64), - BuiltinType::F32 => DatatypePassedBy::Value(AtomType::F32), - BuiltinType::F64 => DatatypePassedBy::Value(AtomType::F64), - }, - DatatypeIdent::Array { .. } => DatatypePassedBy::PointerLengthPair, - DatatypeIdent::Pointer { .. } | DatatypeIdent::ConstPointer { .. } => { - DatatypePassedBy::Value(AtomType::I32) - } - DatatypeIdent::Ident(i) => match &i.variant { - DatatypeVariant::Alias(a) => a.to.passed_by(), - DatatypeVariant::Enum(e) => DatatypePassedBy::Value(e.repr.into()), - DatatypeVariant::Flags(f) => DatatypePassedBy::Value(f.repr.into()), - DatatypeVariant::Struct { .. } | DatatypeVariant::Union { .. } => { - DatatypePassedBy::Pointer - } - DatatypeVariant::Handle { .. } => DatatypePassedBy::Value(AtomType::I32), + | BuiltinType::S32 => TypePassedBy::Value(AtomType::I32), + BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), + BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), + BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), }, + Type::Array { .. } => TypePassedBy::PointerLengthPair, + Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), + Type::Enum(e) => TypePassedBy::Value(e.repr.into()), + Type::Flags(f) => TypePassedBy::Value(f.repr.into()), + Type::Struct { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), } } } @@ -108,12 +99,12 @@ impl InterfaceFuncParam { /// Gives the WebAssembly type that corresponds to passing this interface func parameter by value. /// Not all types can be passed by value: those which cannot return None pub fn pass_by_value(&self) -> Option { - match self.type_.passed_by() { - DatatypePassedBy::Value(atom) => Some(CoreParamType { + match self.tref.type_().passed_by() { + TypePassedBy::Value(atom) => Some(CoreParamType { signifies: CoreParamSignifies::Value(atom), param: self.clone(), }), - DatatypePassedBy::Pointer | DatatypePassedBy::PointerLengthPair => None, + TypePassedBy::Pointer | TypePassedBy::PointerLengthPair => None, } } @@ -121,12 +112,12 @@ impl InterfaceFuncParam { /// by reference. Some types are passed by reference using a single pointer, others /// require both a pointer and length. pub fn pass_by_reference(&self) -> Vec { - match self.type_.passed_by() { - DatatypePassedBy::Value(_) | DatatypePassedBy::Pointer => vec![CoreParamType { + match self.tref.type_().passed_by() { + TypePassedBy::Value(_) | TypePassedBy::Pointer => vec![CoreParamType { signifies: CoreParamSignifies::PointerTo, param: self.clone(), }], - DatatypePassedBy::PointerLengthPair => vec![ + TypePassedBy::PointerLengthPair => vec![ CoreParamType { signifies: CoreParamSignifies::PointerTo, param: self.clone(), diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs index 0e75c1e95..511186a47 100644 --- a/proposals/random/tools/witx/src/docs.rs +++ b/proposals/random/tools/witx/src/docs.rs @@ -7,7 +7,7 @@ pub trait Documentation { impl Documentation for Document { fn to_md(&self) -> String { let mut ret = "# Types\n".to_string(); - for d in self.datatypes() { + for d in self.typenames() { ret += &d.to_md(); } @@ -20,7 +20,7 @@ impl Documentation for Document { } impl BuiltinType { - fn name(&self) -> &'static str { + fn type_name(&self) -> &'static str { match self { BuiltinType::String => "string", BuiltinType::U8 => "u8", @@ -37,48 +37,47 @@ impl BuiltinType { } } -impl DatatypeIdent { - fn name(&self) -> String { - match self { - DatatypeIdent::Builtin(b) => b.name().to_string(), - DatatypeIdent::Array(a) => format!("Array<{}>", a.name()), - DatatypeIdent::Pointer(p) => format!("Pointer<{}>", p.name()), - DatatypeIdent::ConstPointer(p) => format!("ConstPointer<{}>", p.name()), - DatatypeIdent::Ident(i) => i.name.as_str().to_string(), - } - } -} - -impl Documentation for Datatype { +impl Documentation for NamedType { fn to_md(&self) -> String { - format!( - "## `{}`\n{}\n{}\n", - self.name.as_str(), - self.docs, - self.variant.to_md() - ) + let body = match &self.dt { + TypeRef::Value(v) => match &**v { + Type::Enum(a) => a.to_md(), + Type::Flags(a) => a.to_md(), + Type::Struct(a) => a.to_md(), + Type::Union(a) => a.to_md(), + Type::Handle(a) => a.to_md(), + Type::Array(a) => format!("Array of {}", a.type_name()), + Type::Pointer(a) => format!("Pointer to {}", a.type_name()), + Type::ConstPointer(a) => format!("Constant Pointer to {}", a.type_name()), + Type::Builtin(a) => format!("Builtin type {}", a.type_name()), + }, + TypeRef::Name(n) => format!("Alias to {}", n.name.as_str()), + }; + format!("## `{}`\n{}\n{}\n", self.name.as_str(), self.docs, body,) } } -impl Documentation for DatatypeVariant { - fn to_md(&self) -> String { +impl TypeRef { + fn type_name(&self) -> String { match self { - DatatypeVariant::Alias(a) => a.to_md(), - DatatypeVariant::Enum(a) => a.to_md(), - DatatypeVariant::Flags(a) => a.to_md(), - DatatypeVariant::Struct(a) => a.to_md(), - DatatypeVariant::Union(a) => a.to_md(), - DatatypeVariant::Handle(a) => a.to_md(), + TypeRef::Name(n) => n.name.as_str().to_string(), + TypeRef::Value(ref v) => match &**v { + Type::Array(a) => format!("Array<{}>", a.type_name()), + Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), + Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), + Type::Builtin(b) => b.type_name().to_string(), + Type::Enum { .. } + | Type::Flags { .. } + | Type::Struct { .. } + | Type::Union { .. } + | Type::Handle { .. } => { + unimplemented!("type_name of anonymous compound datatypes") + } + }, } } } -impl Documentation for AliasDatatype { - fn to_md(&self) -> String { - format!("Alias to `{}`", self.to.name()) - } -} - impl Documentation for EnumDatatype { fn to_md(&self) -> String { let variants = self @@ -89,7 +88,7 @@ impl Documentation for EnumDatatype { .join("\n"); format!( "Enum represented by `{}`\n\n### Variants:\n{}\n", - self.repr.name(), + self.repr.type_name(), variants ) } @@ -105,7 +104,7 @@ impl Documentation for FlagsDatatype { .join("\n"); format!( "Flags represented by `{}`\n\n### Flags:\n{}", - self.repr.name(), + self.repr.type_name(), flags ) } @@ -120,7 +119,7 @@ impl Documentation for StructDatatype { format!( "#### `{}`\nMember type: `{}`\n{}", m.name.as_str(), - m.type_.name(), + m.tref.type_name(), m.docs, ) }) @@ -139,7 +138,7 @@ impl Documentation for UnionDatatype { format!( "#### `{}`\nVariant type: `{}`\n{}", v.name.as_str(), - v.type_.name(), + v.tref.type_name(), v.docs, ) }) @@ -154,14 +153,14 @@ impl Documentation for HandleDatatype { let supertypes = self .supertypes .iter() - .map(|s| format!("* {}", s.name())) + .map(|s| format!("* {}", s.type_name())) .collect::>() .join("\n"); format!("### Handle supertypes:\n{}\n", supertypes) } } impl IntRepr { - fn name(&self) -> &'static str { + fn type_name(&self) -> &'static str { match self { IntRepr::U8 => "u8", IntRepr::U16 => "u16", @@ -209,7 +208,7 @@ impl Documentation for InterfaceFunc { format!( "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", name = f.name.as_str(), - type_ = f.type_.name(), + type_ = f.tref.type_name(), docs = f.docs ) }) @@ -222,7 +221,7 @@ impl Documentation for InterfaceFunc { format!( "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", name = f.name.as_str(), - type_ = f.type_.name(), + type_ = f.tref.type_name(), docs = f.docs ) }) diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index a781aa09b..1c538d9da 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -16,17 +16,17 @@ mod toplevel; mod validate; pub use ast::{ - AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntRepr, - InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, - ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, + BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, + FlagsMember, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, + InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, ModuleImport, + ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypeRef, UnionDatatype, UnionVariant, }; -pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; +pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; -pub use render::{Render, SExpr as RenderSExpr}; +pub use render::SExpr; pub use validate::ValidationError; use failure::Fail; diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 5c4e75f1d..d8088cd61 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -98,6 +98,24 @@ impl Parse<'_> for BuiltinType { } } +impl wast::parser::Peek for BuiltinType { + fn peek(cursor: wast::parser::Cursor<'_>) -> bool { + ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + } + fn display() -> &'static str { + "builtin type" + } +} #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct CommentSyntax<'a> { pub comments: Vec<&'a str>, @@ -178,41 +196,6 @@ impl<'a, T: Parse<'a>> Parse<'a> for Documented<'a, T> { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum DatatypeIdentSyntax<'a> { - Builtin(BuiltinType), - Array(Box>), - Pointer(Box>), - ConstPointer(Box>), - Ident(wast::Id<'a>), -} - -impl<'a> Parse<'a> for DatatypeIdentSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - if parser.peek::() { - Ok(DatatypeIdentSyntax::Ident(parser.parse()?)) - } else if parser.peek2::() { - Ok(DatatypeIdentSyntax::Array(parser.parens(|p| { - p.parse::()?; - Ok(Box::new(parser.parse()?)) - })?)) - } else if parser.peek::() { - parser.parens(|p| { - p.parse::()?; - if p.peek::() { - p.parse::()?; - Ok(DatatypeIdentSyntax::ConstPointer(Box::new(p.parse()?))) - } else { - p.parse::()?; - Ok(DatatypeIdentSyntax::Pointer(Box::new(p.parse()?))) - } - }) - } else { - Ok(DatatypeIdentSyntax::Builtin(parser.parse()?)) - } - } -} - struct AtWitx; impl Parse<'_> for AtWitx { @@ -329,36 +312,60 @@ impl<'a> Parse<'a> for TypenameSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub enum TypedefSyntax<'a> { - Ident(DatatypeIdentSyntax<'a>), Enum(EnumSyntax<'a>), Flags(FlagsSyntax<'a>), Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), Handle(HandleSyntax<'a>), + Array(Box>), + Pointer(Box>), + ConstPointer(Box>), + Builtin(BuiltinType), + Ident(wast::Id<'a>), } impl<'a> Parse<'a> for TypedefSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - if !parser.peek::() || parser.peek2::() || parser.peek2::() - { - return Ok(TypedefSyntax::Ident(parser.parse()?)); + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(TypedefSyntax::Ident(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Builtin(parser.parse()?)) + } else if l.peek::() { + parser.parens(|parser| { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(TypedefSyntax::Enum(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Flags(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Struct(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Union(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Handle(parser.parse()?)) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::Array(Box::new(parser.parse()?))) + } else if l.peek::() { + parser.parse::()?; + let mut l = parser.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::ConstPointer(Box::new(parser.parse()?))) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) + } else { + Err(l.error()) + } + } else { + Err(l.error()) + } + }) + } else { + Err(l.error()) } - parser.parens(|parser| { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(TypedefSyntax::Enum(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Flags(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Struct(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Union(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Handle(parser.parse()?)) - } else { - Err(l.error()) - } - }) } } @@ -419,7 +426,7 @@ impl<'a> Parse<'a> for StructSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FieldSyntax<'a> { pub name: wast::Id<'a>, - pub type_: DatatypeIdentSyntax<'a>, + pub type_: TypedefSyntax<'a>, } impl<'a> Parse<'a> for FieldSyntax<'a> { diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 2f2f8526f..c9ec34b1f 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -3,8 +3,8 @@ use std::fmt; impl fmt::Display for Document { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for d in self.datatypes() { - write!(f, "{}\n", d.to_sexpr())?; + for d in self.typenames() { + write!(f, "{}\n", d.definition_sexpr())?; } for m in self.modules() { write!(f, "{}\n", m.to_sexpr())?; @@ -68,17 +68,13 @@ impl SExpr { } } -pub trait Render { - fn to_sexpr(&self) -> SExpr; -} - -impl Render for Id { +impl Id { fn to_sexpr(&self) -> SExpr { SExpr::ident(self.as_str()) } } -impl Render for BuiltinType { +impl BuiltinType { fn to_sexpr(&self) -> SExpr { match self { BuiltinType::String => SExpr::word("string"), @@ -96,57 +92,50 @@ impl Render for BuiltinType { } } -impl Render for DatatypeIdent { - fn to_sexpr(&self) -> SExpr { - match self { - DatatypeIdent::Builtin(b) => b.to_sexpr(), - DatatypeIdent::Array(a) => SExpr::Vec(vec![SExpr::word("array"), a.to_sexpr()]), - DatatypeIdent::Pointer(p) => SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("pointer"), - p.to_sexpr(), - ]), - DatatypeIdent::ConstPointer(p) => SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("const_pointer"), - p.to_sexpr(), - ]), - DatatypeIdent::Ident(i) => i.name.to_sexpr(), - } - } -} - -impl Render for Datatype { - fn to_sexpr(&self) -> SExpr { - let name = self.name.to_sexpr(); - let body = self.variant.to_sexpr(); +impl NamedType { + fn definition_sexpr(&self) -> SExpr { + let body = self.dt.to_sexpr(); SExpr::docs( &self.docs, - SExpr::Vec(vec![SExpr::word("typename"), name, body]), + SExpr::Vec(vec![SExpr::word("typename"), self.name.to_sexpr(), body]), ) } } -impl Render for DatatypeVariant { +impl TypeRef { fn to_sexpr(&self) -> SExpr { match self { - DatatypeVariant::Alias(a) => a.to_sexpr(), - DatatypeVariant::Enum(a) => a.to_sexpr(), - DatatypeVariant::Flags(a) => a.to_sexpr(), - DatatypeVariant::Struct(a) => a.to_sexpr(), - DatatypeVariant::Union(a) => a.to_sexpr(), - DatatypeVariant::Handle(a) => a.to_sexpr(), + TypeRef::Name(n) => n.name.to_sexpr(), + TypeRef::Value(v) => v.to_sexpr(), } } } -impl Render for AliasDatatype { +impl Type { fn to_sexpr(&self) -> SExpr { - self.to.to_sexpr() + match self { + Type::Enum(a) => a.to_sexpr(), + Type::Flags(a) => a.to_sexpr(), + Type::Struct(a) => a.to_sexpr(), + Type::Union(a) => a.to_sexpr(), + Type::Handle(a) => a.to_sexpr(), + Type::Array(a) => SExpr::Vec(vec![SExpr::word("array"), a.to_sexpr()]), + Type::Pointer(p) => SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("pointer"), + p.to_sexpr(), + ]), + Type::ConstPointer(p) => SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("const_pointer"), + p.to_sexpr(), + ]), + Type::Builtin(b) => b.to_sexpr(), + } } } -impl Render for EnumDatatype { +impl EnumDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("enum"), self.repr.to_sexpr()]; let variants = self @@ -158,7 +147,7 @@ impl Render for EnumDatatype { } } -impl Render for FlagsDatatype { +impl FlagsDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; let flags = self @@ -170,7 +159,7 @@ impl Render for FlagsDatatype { } } -impl Render for StructDatatype { +impl StructDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("struct")]; let members = self @@ -182,7 +171,7 @@ impl Render for StructDatatype { SExpr::Vec(vec![ SExpr::word("field"), m.name.to_sexpr(), - m.type_.to_sexpr(), + m.tref.to_sexpr(), ]), ) }) @@ -191,7 +180,7 @@ impl Render for StructDatatype { } } -impl Render for UnionDatatype { +impl UnionDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("union")]; let variants = self @@ -203,7 +192,7 @@ impl Render for UnionDatatype { SExpr::Vec(vec![ SExpr::word("field"), v.name.to_sexpr(), - v.type_.to_sexpr(), + v.tref.to_sexpr(), ]), ) }) @@ -212,7 +201,7 @@ impl Render for UnionDatatype { } } -impl Render for HandleDatatype { +impl HandleDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("handle")]; let supertypes = self @@ -223,7 +212,7 @@ impl Render for HandleDatatype { SExpr::Vec([header, supertypes].concat()) } } -impl Render for IntRepr { +impl IntRepr { fn to_sexpr(&self) -> SExpr { match self { IntRepr::U8 => SExpr::word("u8"), @@ -234,7 +223,7 @@ impl Render for IntRepr { } } -impl Render for Module { +impl Module { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("module"), self.name.to_sexpr()]; let definitions = self @@ -246,7 +235,7 @@ impl Render for Module { } } -impl Render for ModuleImport { +impl ModuleImport { fn to_sexpr(&self) -> SExpr { let variant = match self.variant { ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), @@ -262,7 +251,7 @@ impl Render for ModuleImport { } } -impl Render for InterfaceFunc { +impl InterfaceFunc { fn to_sexpr(&self) -> SExpr { let header = vec![ SExpr::annot("interface"), @@ -281,7 +270,7 @@ impl Render for InterfaceFunc { SExpr::Vec(vec![ SExpr::word("param"), f.name.to_sexpr(), - f.type_.to_sexpr(), + f.tref.to_sexpr(), ]), ) }) @@ -295,7 +284,7 @@ impl Render for InterfaceFunc { SExpr::Vec(vec![ SExpr::word("result"), f.name.to_sexpr(), - f.type_.to_sexpr(), + f.tref.to_sexpr(), ]), ) }) diff --git a/proposals/random/tools/witx/src/toplevel.rs b/proposals/random/tools/witx/src/toplevel.rs index 2e0738a6b..4fb13b8d7 100644 --- a/proposals/random/tools/witx/src/toplevel.rs +++ b/proposals/random/tools/witx/src/toplevel.rs @@ -107,21 +107,11 @@ mod test { ) .expect("parse"); - match &doc.datatype(&Id::new("b_float")).unwrap().variant { - DatatypeVariant::Alias(a) => { - assert_eq!(a.name.as_str(), "b_float"); - assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::F64)); - } - other => panic!("expected alias, got {:?}", other), - } + let b_float = doc.typename(&Id::new("b_float")).unwrap(); + assert_eq!(*b_float.type_(), Type::Builtin(BuiltinType::F64)); - match &doc.datatype(&Id::new("c_int")).unwrap().variant { - DatatypeVariant::Alias(a) => { - assert_eq!(a.name.as_str(), "c_int"); - assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::U32)); - } - other => panic!("expected alias, got {:?}", other), - } + let c_int = doc.typename(&Id::new("c_int")).unwrap(); + assert_eq!(*c_int.type_(), Type::Builtin(BuiltinType::U32)); } #[test] @@ -137,13 +127,8 @@ mod test { ) .expect("parse"); - match &doc.datatype(&Id::new("d_char")).unwrap().variant { - DatatypeVariant::Alias(a) => { - assert_eq!(a.name.as_str(), "d_char"); - assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::U8)); - } - other => panic!("expected alias, got {:?}", other), - } + let d_char = doc.typename(&Id::new("d_char")).unwrap(); + assert_eq!(*d_char.type_(), Type::Builtin(BuiltinType::U8)); } #[test] diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 5781ebd06..f9cc2a169 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -1,14 +1,13 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ - CommentSyntax, DatatypeIdentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, - HandleSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, + ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, - AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, - Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, - IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, - ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, - UnionDatatype, UnionVariant, + BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, + HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, + Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, + StructDatatype, StructMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, }; use failure::Fail; use std::collections::HashMap; @@ -168,39 +167,17 @@ impl DocValidationScope<'_> { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; let docs = comments.docs(); - let variant = - match &decl.def { - TypedefSyntax::Ident(syntax) => DatatypeVariant::Alias(AliasDatatype { - name: name.clone(), - to: self.validate_datatype_ident(&syntax)?, - }), - TypedefSyntax::Enum(syntax) => DatatypeVariant::Enum(self.validate_enum( - &name, - &syntax, - decl.ident.span(), - )?), - TypedefSyntax::Flags(syntax) => DatatypeVariant::Flags( - self.validate_flags(&name, &syntax, decl.ident.span())?, - ), - TypedefSyntax::Struct(syntax) => DatatypeVariant::Struct( - self.validate_struct(&name, &syntax, decl.ident.span())?, - ), - TypedefSyntax::Union(syntax) => DatatypeVariant::Union( - self.validate_union(&name, &syntax, decl.ident.span())?, - ), - TypedefSyntax::Handle(syntax) => DatatypeVariant::Handle( - self.validate_handle(&name, syntax, decl.ident.span())?, - ), - }; - let rc_datatype = Rc::new(Datatype { + let dt = self.validate_datatype(&decl.def, decl.ident.span())?; + + let rc_datatype = Rc::new(NamedType { name: name.clone(), - variant, + dt, docs, }); self.doc .entries - .insert(name, Entry::Datatype(Rc::downgrade(&rc_datatype))); - Ok(Definition::Datatype(rc_datatype)) + .insert(name, Entry::Typename(Rc::downgrade(&rc_datatype))); + Ok(Definition::Typename(rc_datatype)) } DeclSyntax::Module(syntax) => { let name = self.introduce(&syntax.name)?; @@ -225,45 +202,51 @@ impl DocValidationScope<'_> { } } - fn validate_datatype_ident( + fn validate_datatype( &self, - syntax: &DatatypeIdentSyntax, - ) -> Result { + syntax: &TypedefSyntax, + span: wast::Span, + ) -> Result { match syntax { - DatatypeIdentSyntax::Builtin(b) => Ok(DatatypeIdent::Builtin(*b)), - DatatypeIdentSyntax::Array(a) => Ok(DatatypeIdent::Array(Box::new( - self.validate_datatype_ident(&a)?, - ))), - DatatypeIdentSyntax::Pointer(a) => Ok(DatatypeIdent::Pointer(Box::new( - self.validate_datatype_ident(&a)?, - ))), - DatatypeIdentSyntax::ConstPointer(a) => Ok(DatatypeIdent::ConstPointer(Box::new( - self.validate_datatype_ident(&a)?, - ))), - DatatypeIdentSyntax::Ident(i) => { - let id = self.get(i)?; - match self.doc.entries.get(&id) { - Some(Entry::Datatype(weak_d)) => Ok(DatatypeIdent::Ident( - weak_d.upgrade().expect("weak backref to defined type"), + TypedefSyntax::Ident(syntax) => { + let i = self.get(syntax)?; + match self.doc.entries.get(&i) { + Some(Entry::Typename(weak_ref)) => Ok(TypeRef::Name( + weak_ref.upgrade().expect("weak backref to defined type"), )), Some(e) => Err(ValidationError::WrongKindName { - name: i.name().to_string(), - location: self.location(i.span()), + name: i.as_str().to_string(), + location: self.location(syntax.span()), expected: "datatype", got: e.kind(), }), None => Err(ValidationError::Recursive { - name: i.name().to_string(), - location: self.location(i.span()), + name: i.as_str().to_string(), + location: self.location(syntax.span()), }), } } + other => Ok(TypeRef::Value(Rc::new(match other { + TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), + TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), + TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), + TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), + TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), + TypedefSyntax::Array(syntax) => Type::Array(self.validate_datatype(syntax, span)?), + TypedefSyntax::Pointer(syntax) => { + Type::Pointer(self.validate_datatype(syntax, span)?) + } + TypedefSyntax::ConstPointer(syntax) => { + Type::ConstPointer(self.validate_datatype(syntax, span)?) + } + TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), + TypedefSyntax::Ident { .. } => unreachable!(), + }))), } } fn validate_enum( &self, - name: &Id, syntax: &EnumSyntax, span: wast::Span, ) -> Result { @@ -279,16 +262,11 @@ impl DocValidationScope<'_> { }) .collect::, _>>()?; - Ok(EnumDatatype { - name: name.clone(), - repr, - variants, - }) + Ok(EnumDatatype { repr, variants }) } fn validate_flags( &self, - name: &Id, syntax: &FlagsSyntax, span: wast::Span, ) -> Result { @@ -304,16 +282,11 @@ impl DocValidationScope<'_> { }) .collect::, _>>()?; - Ok(FlagsDatatype { - name: name.clone(), - repr, - flags, - }) + Ok(FlagsDatatype { repr, flags }) } fn validate_struct( &self, - name: &Id, syntax: &StructSyntax, _span: wast::Span, ) -> Result { @@ -324,21 +297,17 @@ impl DocValidationScope<'_> { .map(|f| { let name = member_scope .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let type_ = self.validate_datatype_ident(&f.item.type_)?; + let tref = self.validate_datatype(&f.item.type_, f.item.name.span())?; let docs = f.comments.docs(); - Ok(StructMember { name, type_, docs }) + Ok(StructMember { name, tref, docs }) }) .collect::, _>>()?; - Ok(StructDatatype { - name: name.clone(), - members, - }) + Ok(StructDatatype { members }) } fn validate_union( &self, - name: &Id, syntax: &UnionSyntax, _span: wast::Span, ) -> Result { @@ -349,21 +318,17 @@ impl DocValidationScope<'_> { .map(|f| { let name = variant_scope .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let type_ = self.validate_datatype_ident(&f.item.type_)?; + let tref = self.validate_datatype(&f.item.type_, f.item.name.span())?; let docs = f.comments.docs(); - Ok(UnionVariant { name, type_, docs }) + Ok(UnionVariant { name, tref, docs }) }) .collect::, _>>()?; - Ok(UnionDatatype { - name: name.clone(), - variants, - }) + Ok(UnionDatatype { variants }) } fn validate_handle( &self, - name: &Id, syntax: &HandleSyntax, _span: wast::Span, ) -> Result { @@ -373,15 +338,15 @@ impl DocValidationScope<'_> { .map(|id_syntax| { let id = self.get(&id_syntax)?; match self.doc.entries.get(&id) { - Some(Entry::Datatype(weak_d)) => { - let d = weak_d.upgrade().expect("weak backref to defined type"); - match &d.variant { - DatatypeVariant::Handle { .. } => Ok(DatatypeIdent::Ident(d)), - _ => Err(ValidationError::WrongKindName { + Some(Entry::Typename(weak_ref)) => { + let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); + match &*named_dt.type_() { + Type::Handle { .. } => Ok(TypeRef::Name(named_dt)), + other => Err(ValidationError::WrongKindName { name: id_syntax.name().to_string(), location: self.location(id_syntax.span()), expected: "handle", - got: d.variant.kind(), + got: other.kind(), }), } } @@ -397,12 +362,9 @@ impl DocValidationScope<'_> { }), } }) - .collect::, _>>()?; + .collect::, _>>()?; - Ok(HandleDatatype { - name: name.clone(), - supertypes, - }) + Ok(HandleDatatype { supertypes }) } fn validate_int_repr( @@ -472,7 +434,9 @@ impl<'a> ModuleValidation<'a> { f.item.name.name(), self.doc.location(f.item.name.span()), )?, - type_: self.doc.validate_datatype_ident(&f.item.type_)?, + tref: self + .doc + .validate_datatype(&f.item.type_, f.item.name.span())?, position: InterfaceFuncParamPosition::Param(ix), docs: f.comments.docs(), }) @@ -483,10 +447,12 @@ impl<'a> ModuleValidation<'a> { .iter() .enumerate() .map(|(ix, f)| { - let type_ = self.doc.validate_datatype_ident(&f.item.type_)?; + let tref = self + .doc + .validate_datatype(&f.item.type_, f.item.name.span())?; if ix == 0 { - match type_.passed_by() { - DatatypePassedBy::Value(_) => {} + match tref.type_().passed_by() { + TypePassedBy::Value(_) => {} _ => Err(ValidationError::InvalidFirstResultType { location: self.doc.location(f.item.name.span()), })?, @@ -497,7 +463,7 @@ impl<'a> ModuleValidation<'a> { f.item.name.name(), self.doc.location(f.item.name.span()), )?, - type_, + tref, position: InterfaceFuncParamPosition::Result(ix), docs: f.comments.docs(), }) diff --git a/proposals/random/tools/witx/tests/multimodule.rs b/proposals/random/tools/witx/tests/multimodule.rs index e9cc5ecb9..47fb34755 100644 --- a/proposals/random/tools/witx/tests/multimodule.rs +++ b/proposals/random/tools/witx/tests/multimodule.rs @@ -1,4 +1,4 @@ -use witx::{load, BuiltinType, DatatypeIdent, DatatypeVariant, Id}; +use witx::{load, BuiltinType, Id, Type, TypeRef}; #[test] fn validate_multimodule() { @@ -9,44 +9,35 @@ fn validate_multimodule() { ]) .unwrap_or_else(|e| panic!("failed to validate: {}", e)); - println!("{}", doc); + //println!("{}", doc); // Check that the `a` both modules use is what we expect: - let type_a = doc.datatype(&Id::new("a")).expect("type a exists"); - match &type_a.variant { - DatatypeVariant::Alias(alias) => match alias.to { - DatatypeIdent::Builtin(b) => assert_eq!(b, BuiltinType::U32), - _ => panic!("a is an alias u32"), - }, - _ => panic!("a is an alias to u32"), - } + let type_a = doc.typename(&Id::new("a")).expect("type a exists"); + assert_eq!(*type_a.type_(), Type::Builtin(BuiltinType::U32)); // `b` is a struct with a single member of type `a` - let type_b = doc.datatype(&Id::new("b")).expect("type b exists"); - match &type_b.variant { - DatatypeVariant::Struct(struct_) => { + let type_b = doc.typename(&Id::new("b")).expect("type b exists"); + match &*type_b.type_() { + Type::Struct(struct_) => { assert_eq!(struct_.members.len(), 1); - match &struct_.members.get(0).unwrap().type_ { - DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), - _ => panic!("b.0 has type a"), - } + assert_eq!( + struct_.members.get(0).unwrap().tref, + TypeRef::Name(type_a.clone()) + ); } _ => panic!("b is a struct"), } // `c` is a struct with a two members of type `a` - let type_c = doc.datatype(&Id::new("c")).expect("type c exists"); - match &type_c.variant { - DatatypeVariant::Struct(struct_) => { + let type_c = doc.typename(&Id::new("c")).expect("type c exists"); + match &*type_c.type_() { + Type::Struct(struct_) => { assert_eq!(struct_.members.len(), 2); - match &struct_.members.get(0).unwrap().type_ { - DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), - _ => panic!("c.0 has type a"), - } - match &struct_.members.get(1).unwrap().type_ { - DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), - _ => panic!("c.1 has type a"), - } + assert_eq!( + struct_.members.get(0).unwrap().tref, + TypeRef::Name(type_a.clone()) + ); + assert_eq!(struct_.members.get(1).unwrap().tref, TypeRef::Name(type_a)); } _ => panic!("c is a struct"), } diff --git a/proposals/random/tools/witx/tests/wasi.rs b/proposals/random/tools/witx/tests/wasi.rs index 938c78067..6d6ebc120 100644 --- a/proposals/random/tools/witx/tests/wasi.rs +++ b/proposals/random/tools/witx/tests/wasi.rs @@ -33,8 +33,8 @@ fn render_roundtrip() { // I'd just assert_eq, but when it fails the debug print is thousands of lines long and impossible // to figure out where they are unequal. if doc != doc2 { - for type_ in doc.datatypes() { - let type2 = doc2.datatype(&type_.name).expect("doc2 missing datatype"); + for type_ in doc.typenames() { + let type2 = doc2.typename(&type_.name).expect("doc2 missing datatype"); assert_eq!(type_, type2); } for mod_ in doc.modules() { @@ -52,3 +52,14 @@ fn render_roundtrip() { // This should be equivelant to the above, but just in case some code changes where it isnt: assert_eq!(doc, doc2); } + +#[test] +fn document_wasi_snapshot() { + use witx::Documentation; + println!( + "{}", + witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)) + .to_md() + ); +} From 25d583f9d810b30a12ae769f17e1c2f7cf97570c Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 22 Nov 2019 12:52:12 -0500 Subject: [PATCH 0312/1772] Re-organize witx AST (#154) The witx::ast types had some confusing choices that I blame on building the first draft of the tool in a hurry. This redesigns the AST a bit: I used Datatype/datatype in a number of places where witx syntax and wasm just call things types. The data-prefix has been dropped in many places. StructDatatype, UnionDatatype and friends still retain the "data" part of the name, but that seems less problematic. instead of two enumerations (DatatypeIdent and DatatypeVariant) holding different variations (arrays and pointers and builtins falling under Ident, everything else in variant) there is now just one enum Type that has each possible variation in a datatype Types can either be anonymous (e.g. an (array u8) in a function argument) or named (by (typename ...). An enum TypeRef gives a type either by Value(Type) or Name(NamedType). Only NamedTypes have docs. Instead of considering Aliases as a variation of a datatype, they are now encoded using TypeRef: (typename $a u32) is a NamedType { name: "a", dt: TypeRef::Value(Type::Builtin(BuiltinType::U32)) }. * witx: reorganize the AST this has highlighted some issues with the grammar, unfortunately * wip * continued work on tests * witx: all tests pass!! * rename Datatype to Type, so ast is closer to syntax * fix docs output --- proposals/filesystem/tools/witx/src/ast.rs | 87 ++++----- .../filesystem/tools/witx/src/coretypes.rs | 55 +++--- proposals/filesystem/tools/witx/src/docs.rs | 85 +++++---- proposals/filesystem/tools/witx/src/lib.rs | 12 +- proposals/filesystem/tools/witx/src/parser.rs | 119 +++++++------ proposals/filesystem/tools/witx/src/render.rs | 99 +++++------ .../filesystem/tools/witx/src/toplevel.rs | 27 +-- .../filesystem/tools/witx/src/validate.rs | 166 +++++++----------- .../tools/witx/tests/multimodule.rs | 47 ++--- proposals/filesystem/tools/witx/tests/wasi.rs | 15 +- 10 files changed, 329 insertions(+), 383 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 341186820..2295cc94c 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -29,27 +29,27 @@ impl Document { entries, } } - pub fn datatype(&self, name: &Id) -> Option> { + pub fn typename(&self, name: &Id) -> Option> { self.entries.get(name).and_then(|e| match e { - Entry::Datatype(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + Entry::Typename(nt) => Some(nt.upgrade().expect("always possible to upgrade entry")), _ => None, }) } - pub fn datatypes<'a>(&'a self) -> impl Iterator> + 'a { + pub fn typenames<'a>(&'a self) -> impl Iterator> + 'a { self.definitions.iter().filter_map(|d| match d { - Definition::Datatype(d) => Some(d.clone()), + Definition::Typename(nt) => Some(nt.clone()), _ => None, }) } pub fn module(&self, name: &Id) -> Option> { self.entries.get(&name).and_then(|e| match e { - Entry::Module(d) => Some(d.upgrade().expect("always possible to upgrade entry")), + Entry::Module(m) => Some(m.upgrade().expect("always possible to upgrade entry")), _ => None, }) } pub fn modules<'a>(&'a self) -> impl Iterator> + 'a { self.definitions.iter().filter_map(|d| match d { - Definition::Module(d) => Some(d.clone()), + Definition::Module(m) => Some(m.clone()), _ => None, }) } @@ -66,20 +66,20 @@ impl Eq for Document {} #[derive(Debug, Clone)] pub enum Definition { - Datatype(Rc), + Typename(Rc), Module(Rc), } #[derive(Debug, Clone)] pub enum Entry { - Datatype(Weak), + Typename(Weak), Module(Weak), } impl Entry { pub fn kind(&self) -> &'static str { match self { - Entry::Datatype { .. } => "datatype", + Entry::Typename { .. } => "typename", Entry::Module { .. } => "module", } } @@ -88,10 +88,10 @@ impl Entry { impl PartialEq for Entry { fn eq(&self, rhs: &Entry) -> bool { match (self, rhs) { - (Entry::Datatype(d), Entry::Datatype(d_rhs)) => { - d.upgrade() + (Entry::Typename(t), Entry::Typename(t_rhs)) => { + t.upgrade() .expect("possible to upgrade entry when part of document") - == d_rhs + == t_rhs .upgrade() .expect("possible to upgrade entry when part of document") } @@ -108,51 +108,63 @@ impl PartialEq for Entry { } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum DatatypeIdent { - Builtin(BuiltinType), - Array(Box), - Pointer(Box), - ConstPointer(Box), - Ident(Rc), +pub enum TypeRef { + Name(Rc), + Value(Rc), +} + +impl TypeRef { + pub fn type_(&self) -> Rc { + match self { + TypeRef::Name(named) => named.type_(), + TypeRef::Value(ref v) => v.clone(), + } + } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct Datatype { +pub struct NamedType { pub name: Id, - pub variant: DatatypeVariant, + pub dt: TypeRef, pub docs: String, } +impl NamedType { + pub fn type_(&self) -> Rc { + self.dt.type_() + } +} + #[derive(Debug, Clone, PartialEq, Eq)] -pub enum DatatypeVariant { - Alias(AliasDatatype), +pub enum Type { Enum(EnumDatatype), Flags(FlagsDatatype), Struct(StructDatatype), Union(UnionDatatype), Handle(HandleDatatype), + Array(TypeRef), + Pointer(TypeRef), + ConstPointer(TypeRef), + Builtin(BuiltinType), } -impl DatatypeVariant { +impl Type { pub fn kind(&self) -> &'static str { - use DatatypeVariant::*; + use Type::*; match self { - Alias(_) => "alias", Enum(_) => "enum", Flags(_) => "flags", Struct(_) => "struct", Union(_) => "union", Handle(_) => "handle", + Array(_) => "array", + Pointer(_) => "pointer", + ConstPointer(_) => "constpointer", + Builtin(_) => "builtin", } } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct AliasDatatype { - pub name: Id, - pub to: DatatypeIdent, -} - #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum IntRepr { U8, @@ -163,7 +175,6 @@ pub enum IntRepr { #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumDatatype { - pub name: Id, pub repr: IntRepr, pub variants: Vec, } @@ -176,7 +187,6 @@ pub struct EnumVariant { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsDatatype { - pub name: Id, pub repr: IntRepr, pub flags: Vec, } @@ -189,34 +199,31 @@ pub struct FlagsMember { #[derive(Debug, Clone, PartialEq, Eq)] pub struct StructDatatype { - pub name: Id, pub members: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct StructMember { pub name: Id, - pub type_: DatatypeIdent, + pub tref: TypeRef, pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionDatatype { - pub name: Id, pub variants: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionVariant { pub name: Id, - pub type_: DatatypeIdent, + pub tref: TypeRef, pub docs: String, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct HandleDatatype { - pub name: Id, - pub supertypes: Vec, + pub supertypes: Vec, } #[derive(Debug, Clone)] @@ -333,7 +340,7 @@ pub struct InterfaceFunc { #[derive(Debug, Clone, PartialEq, Eq)] pub struct InterfaceFuncParam { pub name: Id, - pub type_: DatatypeIdent, + pub tref: TypeRef, pub position: InterfaceFuncParamPosition, pub docs: String, } diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index f9919bc55..d772b3f54 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -1,6 +1,4 @@ -use crate::{ - BuiltinType, DatatypeIdent, DatatypeVariant, IntRepr, InterfaceFunc, InterfaceFuncParam, -}; +use crate::{BuiltinType, IntRepr, InterfaceFunc, InterfaceFuncParam, Type}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] /// Enumerates the types permitted for function arguments in the WebAssembly spec @@ -22,7 +20,7 @@ impl From for AtomType { #[derive(Debug, Copy, Clone, PartialEq, Eq)] /// Enumerates the strategies which may be used to pass a datatype as an argument -pub enum DatatypePassedBy { +pub enum TypePassedBy { /// Pass by value specifies the AtomType used to represent that value Value(AtomType), /// Pass by a pointer into linear memory @@ -31,36 +29,29 @@ pub enum DatatypePassedBy { PointerLengthPair, } -impl DatatypeIdent { +impl Type { /// Determine the simplest strategy by which a type may be passed. Value always preferred over /// Pointer. - pub fn passed_by(&self) -> DatatypePassedBy { - match &self { - DatatypeIdent::Builtin(b) => match b { - BuiltinType::String => DatatypePassedBy::PointerLengthPair, + pub fn passed_by(&self) -> TypePassedBy { + match self { + Type::Builtin(b) => match b { + BuiltinType::String => TypePassedBy::PointerLengthPair, BuiltinType::U8 | BuiltinType::U16 | BuiltinType::U32 | BuiltinType::S8 | BuiltinType::S16 - | BuiltinType::S32 => DatatypePassedBy::Value(AtomType::I32), - BuiltinType::U64 | BuiltinType::S64 => DatatypePassedBy::Value(AtomType::I64), - BuiltinType::F32 => DatatypePassedBy::Value(AtomType::F32), - BuiltinType::F64 => DatatypePassedBy::Value(AtomType::F64), - }, - DatatypeIdent::Array { .. } => DatatypePassedBy::PointerLengthPair, - DatatypeIdent::Pointer { .. } | DatatypeIdent::ConstPointer { .. } => { - DatatypePassedBy::Value(AtomType::I32) - } - DatatypeIdent::Ident(i) => match &i.variant { - DatatypeVariant::Alias(a) => a.to.passed_by(), - DatatypeVariant::Enum(e) => DatatypePassedBy::Value(e.repr.into()), - DatatypeVariant::Flags(f) => DatatypePassedBy::Value(f.repr.into()), - DatatypeVariant::Struct { .. } | DatatypeVariant::Union { .. } => { - DatatypePassedBy::Pointer - } - DatatypeVariant::Handle { .. } => DatatypePassedBy::Value(AtomType::I32), + | BuiltinType::S32 => TypePassedBy::Value(AtomType::I32), + BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), + BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), + BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), }, + Type::Array { .. } => TypePassedBy::PointerLengthPair, + Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), + Type::Enum(e) => TypePassedBy::Value(e.repr.into()), + Type::Flags(f) => TypePassedBy::Value(f.repr.into()), + Type::Struct { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), } } } @@ -108,12 +99,12 @@ impl InterfaceFuncParam { /// Gives the WebAssembly type that corresponds to passing this interface func parameter by value. /// Not all types can be passed by value: those which cannot return None pub fn pass_by_value(&self) -> Option { - match self.type_.passed_by() { - DatatypePassedBy::Value(atom) => Some(CoreParamType { + match self.tref.type_().passed_by() { + TypePassedBy::Value(atom) => Some(CoreParamType { signifies: CoreParamSignifies::Value(atom), param: self.clone(), }), - DatatypePassedBy::Pointer | DatatypePassedBy::PointerLengthPair => None, + TypePassedBy::Pointer | TypePassedBy::PointerLengthPair => None, } } @@ -121,12 +112,12 @@ impl InterfaceFuncParam { /// by reference. Some types are passed by reference using a single pointer, others /// require both a pointer and length. pub fn pass_by_reference(&self) -> Vec { - match self.type_.passed_by() { - DatatypePassedBy::Value(_) | DatatypePassedBy::Pointer => vec![CoreParamType { + match self.tref.type_().passed_by() { + TypePassedBy::Value(_) | TypePassedBy::Pointer => vec![CoreParamType { signifies: CoreParamSignifies::PointerTo, param: self.clone(), }], - DatatypePassedBy::PointerLengthPair => vec![ + TypePassedBy::PointerLengthPair => vec![ CoreParamType { signifies: CoreParamSignifies::PointerTo, param: self.clone(), diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs index 0e75c1e95..511186a47 100644 --- a/proposals/filesystem/tools/witx/src/docs.rs +++ b/proposals/filesystem/tools/witx/src/docs.rs @@ -7,7 +7,7 @@ pub trait Documentation { impl Documentation for Document { fn to_md(&self) -> String { let mut ret = "# Types\n".to_string(); - for d in self.datatypes() { + for d in self.typenames() { ret += &d.to_md(); } @@ -20,7 +20,7 @@ impl Documentation for Document { } impl BuiltinType { - fn name(&self) -> &'static str { + fn type_name(&self) -> &'static str { match self { BuiltinType::String => "string", BuiltinType::U8 => "u8", @@ -37,48 +37,47 @@ impl BuiltinType { } } -impl DatatypeIdent { - fn name(&self) -> String { - match self { - DatatypeIdent::Builtin(b) => b.name().to_string(), - DatatypeIdent::Array(a) => format!("Array<{}>", a.name()), - DatatypeIdent::Pointer(p) => format!("Pointer<{}>", p.name()), - DatatypeIdent::ConstPointer(p) => format!("ConstPointer<{}>", p.name()), - DatatypeIdent::Ident(i) => i.name.as_str().to_string(), - } - } -} - -impl Documentation for Datatype { +impl Documentation for NamedType { fn to_md(&self) -> String { - format!( - "## `{}`\n{}\n{}\n", - self.name.as_str(), - self.docs, - self.variant.to_md() - ) + let body = match &self.dt { + TypeRef::Value(v) => match &**v { + Type::Enum(a) => a.to_md(), + Type::Flags(a) => a.to_md(), + Type::Struct(a) => a.to_md(), + Type::Union(a) => a.to_md(), + Type::Handle(a) => a.to_md(), + Type::Array(a) => format!("Array of {}", a.type_name()), + Type::Pointer(a) => format!("Pointer to {}", a.type_name()), + Type::ConstPointer(a) => format!("Constant Pointer to {}", a.type_name()), + Type::Builtin(a) => format!("Builtin type {}", a.type_name()), + }, + TypeRef::Name(n) => format!("Alias to {}", n.name.as_str()), + }; + format!("## `{}`\n{}\n{}\n", self.name.as_str(), self.docs, body,) } } -impl Documentation for DatatypeVariant { - fn to_md(&self) -> String { +impl TypeRef { + fn type_name(&self) -> String { match self { - DatatypeVariant::Alias(a) => a.to_md(), - DatatypeVariant::Enum(a) => a.to_md(), - DatatypeVariant::Flags(a) => a.to_md(), - DatatypeVariant::Struct(a) => a.to_md(), - DatatypeVariant::Union(a) => a.to_md(), - DatatypeVariant::Handle(a) => a.to_md(), + TypeRef::Name(n) => n.name.as_str().to_string(), + TypeRef::Value(ref v) => match &**v { + Type::Array(a) => format!("Array<{}>", a.type_name()), + Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), + Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), + Type::Builtin(b) => b.type_name().to_string(), + Type::Enum { .. } + | Type::Flags { .. } + | Type::Struct { .. } + | Type::Union { .. } + | Type::Handle { .. } => { + unimplemented!("type_name of anonymous compound datatypes") + } + }, } } } -impl Documentation for AliasDatatype { - fn to_md(&self) -> String { - format!("Alias to `{}`", self.to.name()) - } -} - impl Documentation for EnumDatatype { fn to_md(&self) -> String { let variants = self @@ -89,7 +88,7 @@ impl Documentation for EnumDatatype { .join("\n"); format!( "Enum represented by `{}`\n\n### Variants:\n{}\n", - self.repr.name(), + self.repr.type_name(), variants ) } @@ -105,7 +104,7 @@ impl Documentation for FlagsDatatype { .join("\n"); format!( "Flags represented by `{}`\n\n### Flags:\n{}", - self.repr.name(), + self.repr.type_name(), flags ) } @@ -120,7 +119,7 @@ impl Documentation for StructDatatype { format!( "#### `{}`\nMember type: `{}`\n{}", m.name.as_str(), - m.type_.name(), + m.tref.type_name(), m.docs, ) }) @@ -139,7 +138,7 @@ impl Documentation for UnionDatatype { format!( "#### `{}`\nVariant type: `{}`\n{}", v.name.as_str(), - v.type_.name(), + v.tref.type_name(), v.docs, ) }) @@ -154,14 +153,14 @@ impl Documentation for HandleDatatype { let supertypes = self .supertypes .iter() - .map(|s| format!("* {}", s.name())) + .map(|s| format!("* {}", s.type_name())) .collect::>() .join("\n"); format!("### Handle supertypes:\n{}\n", supertypes) } } impl IntRepr { - fn name(&self) -> &'static str { + fn type_name(&self) -> &'static str { match self { IntRepr::U8 => "u8", IntRepr::U16 => "u16", @@ -209,7 +208,7 @@ impl Documentation for InterfaceFunc { format!( "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", name = f.name.as_str(), - type_ = f.type_.name(), + type_ = f.tref.type_name(), docs = f.docs ) }) @@ -222,7 +221,7 @@ impl Documentation for InterfaceFunc { format!( "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", name = f.name.as_str(), - type_ = f.type_.name(), + type_ = f.tref.type_name(), docs = f.docs ) }) diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index a781aa09b..1c538d9da 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -16,17 +16,17 @@ mod toplevel; mod validate; pub use ast::{ - AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypeVariant, Definition, Document, - Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntRepr, - InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, - ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, UnionDatatype, + BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, + FlagsMember, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, + InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, ModuleImport, + ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypeRef, UnionDatatype, UnionVariant, }; -pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, DatatypePassedBy}; +pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; -pub use render::{Render, SExpr as RenderSExpr}; +pub use render::SExpr; pub use validate::ValidationError; use failure::Fail; diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 5c4e75f1d..d8088cd61 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -98,6 +98,24 @@ impl Parse<'_> for BuiltinType { } } +impl wast::parser::Peek for BuiltinType { + fn peek(cursor: wast::parser::Cursor<'_>) -> bool { + ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + || ::peek(cursor) + } + fn display() -> &'static str { + "builtin type" + } +} #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct CommentSyntax<'a> { pub comments: Vec<&'a str>, @@ -178,41 +196,6 @@ impl<'a, T: Parse<'a>> Parse<'a> for Documented<'a, T> { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum DatatypeIdentSyntax<'a> { - Builtin(BuiltinType), - Array(Box>), - Pointer(Box>), - ConstPointer(Box>), - Ident(wast::Id<'a>), -} - -impl<'a> Parse<'a> for DatatypeIdentSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - if parser.peek::() { - Ok(DatatypeIdentSyntax::Ident(parser.parse()?)) - } else if parser.peek2::() { - Ok(DatatypeIdentSyntax::Array(parser.parens(|p| { - p.parse::()?; - Ok(Box::new(parser.parse()?)) - })?)) - } else if parser.peek::() { - parser.parens(|p| { - p.parse::()?; - if p.peek::() { - p.parse::()?; - Ok(DatatypeIdentSyntax::ConstPointer(Box::new(p.parse()?))) - } else { - p.parse::()?; - Ok(DatatypeIdentSyntax::Pointer(Box::new(p.parse()?))) - } - }) - } else { - Ok(DatatypeIdentSyntax::Builtin(parser.parse()?)) - } - } -} - struct AtWitx; impl Parse<'_> for AtWitx { @@ -329,36 +312,60 @@ impl<'a> Parse<'a> for TypenameSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub enum TypedefSyntax<'a> { - Ident(DatatypeIdentSyntax<'a>), Enum(EnumSyntax<'a>), Flags(FlagsSyntax<'a>), Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), Handle(HandleSyntax<'a>), + Array(Box>), + Pointer(Box>), + ConstPointer(Box>), + Builtin(BuiltinType), + Ident(wast::Id<'a>), } impl<'a> Parse<'a> for TypedefSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - if !parser.peek::() || parser.peek2::() || parser.peek2::() - { - return Ok(TypedefSyntax::Ident(parser.parse()?)); + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(TypedefSyntax::Ident(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Builtin(parser.parse()?)) + } else if l.peek::() { + parser.parens(|parser| { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(TypedefSyntax::Enum(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Flags(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Struct(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Union(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Handle(parser.parse()?)) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::Array(Box::new(parser.parse()?))) + } else if l.peek::() { + parser.parse::()?; + let mut l = parser.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::ConstPointer(Box::new(parser.parse()?))) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) + } else { + Err(l.error()) + } + } else { + Err(l.error()) + } + }) + } else { + Err(l.error()) } - parser.parens(|parser| { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(TypedefSyntax::Enum(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Flags(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Struct(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Union(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Handle(parser.parse()?)) - } else { - Err(l.error()) - } - }) } } @@ -419,7 +426,7 @@ impl<'a> Parse<'a> for StructSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FieldSyntax<'a> { pub name: wast::Id<'a>, - pub type_: DatatypeIdentSyntax<'a>, + pub type_: TypedefSyntax<'a>, } impl<'a> Parse<'a> for FieldSyntax<'a> { diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 2f2f8526f..c9ec34b1f 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -3,8 +3,8 @@ use std::fmt; impl fmt::Display for Document { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for d in self.datatypes() { - write!(f, "{}\n", d.to_sexpr())?; + for d in self.typenames() { + write!(f, "{}\n", d.definition_sexpr())?; } for m in self.modules() { write!(f, "{}\n", m.to_sexpr())?; @@ -68,17 +68,13 @@ impl SExpr { } } -pub trait Render { - fn to_sexpr(&self) -> SExpr; -} - -impl Render for Id { +impl Id { fn to_sexpr(&self) -> SExpr { SExpr::ident(self.as_str()) } } -impl Render for BuiltinType { +impl BuiltinType { fn to_sexpr(&self) -> SExpr { match self { BuiltinType::String => SExpr::word("string"), @@ -96,57 +92,50 @@ impl Render for BuiltinType { } } -impl Render for DatatypeIdent { - fn to_sexpr(&self) -> SExpr { - match self { - DatatypeIdent::Builtin(b) => b.to_sexpr(), - DatatypeIdent::Array(a) => SExpr::Vec(vec![SExpr::word("array"), a.to_sexpr()]), - DatatypeIdent::Pointer(p) => SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("pointer"), - p.to_sexpr(), - ]), - DatatypeIdent::ConstPointer(p) => SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("const_pointer"), - p.to_sexpr(), - ]), - DatatypeIdent::Ident(i) => i.name.to_sexpr(), - } - } -} - -impl Render for Datatype { - fn to_sexpr(&self) -> SExpr { - let name = self.name.to_sexpr(); - let body = self.variant.to_sexpr(); +impl NamedType { + fn definition_sexpr(&self) -> SExpr { + let body = self.dt.to_sexpr(); SExpr::docs( &self.docs, - SExpr::Vec(vec![SExpr::word("typename"), name, body]), + SExpr::Vec(vec![SExpr::word("typename"), self.name.to_sexpr(), body]), ) } } -impl Render for DatatypeVariant { +impl TypeRef { fn to_sexpr(&self) -> SExpr { match self { - DatatypeVariant::Alias(a) => a.to_sexpr(), - DatatypeVariant::Enum(a) => a.to_sexpr(), - DatatypeVariant::Flags(a) => a.to_sexpr(), - DatatypeVariant::Struct(a) => a.to_sexpr(), - DatatypeVariant::Union(a) => a.to_sexpr(), - DatatypeVariant::Handle(a) => a.to_sexpr(), + TypeRef::Name(n) => n.name.to_sexpr(), + TypeRef::Value(v) => v.to_sexpr(), } } } -impl Render for AliasDatatype { +impl Type { fn to_sexpr(&self) -> SExpr { - self.to.to_sexpr() + match self { + Type::Enum(a) => a.to_sexpr(), + Type::Flags(a) => a.to_sexpr(), + Type::Struct(a) => a.to_sexpr(), + Type::Union(a) => a.to_sexpr(), + Type::Handle(a) => a.to_sexpr(), + Type::Array(a) => SExpr::Vec(vec![SExpr::word("array"), a.to_sexpr()]), + Type::Pointer(p) => SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("pointer"), + p.to_sexpr(), + ]), + Type::ConstPointer(p) => SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("const_pointer"), + p.to_sexpr(), + ]), + Type::Builtin(b) => b.to_sexpr(), + } } } -impl Render for EnumDatatype { +impl EnumDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("enum"), self.repr.to_sexpr()]; let variants = self @@ -158,7 +147,7 @@ impl Render for EnumDatatype { } } -impl Render for FlagsDatatype { +impl FlagsDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; let flags = self @@ -170,7 +159,7 @@ impl Render for FlagsDatatype { } } -impl Render for StructDatatype { +impl StructDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("struct")]; let members = self @@ -182,7 +171,7 @@ impl Render for StructDatatype { SExpr::Vec(vec![ SExpr::word("field"), m.name.to_sexpr(), - m.type_.to_sexpr(), + m.tref.to_sexpr(), ]), ) }) @@ -191,7 +180,7 @@ impl Render for StructDatatype { } } -impl Render for UnionDatatype { +impl UnionDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("union")]; let variants = self @@ -203,7 +192,7 @@ impl Render for UnionDatatype { SExpr::Vec(vec![ SExpr::word("field"), v.name.to_sexpr(), - v.type_.to_sexpr(), + v.tref.to_sexpr(), ]), ) }) @@ -212,7 +201,7 @@ impl Render for UnionDatatype { } } -impl Render for HandleDatatype { +impl HandleDatatype { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("handle")]; let supertypes = self @@ -223,7 +212,7 @@ impl Render for HandleDatatype { SExpr::Vec([header, supertypes].concat()) } } -impl Render for IntRepr { +impl IntRepr { fn to_sexpr(&self) -> SExpr { match self { IntRepr::U8 => SExpr::word("u8"), @@ -234,7 +223,7 @@ impl Render for IntRepr { } } -impl Render for Module { +impl Module { fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("module"), self.name.to_sexpr()]; let definitions = self @@ -246,7 +235,7 @@ impl Render for Module { } } -impl Render for ModuleImport { +impl ModuleImport { fn to_sexpr(&self) -> SExpr { let variant = match self.variant { ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), @@ -262,7 +251,7 @@ impl Render for ModuleImport { } } -impl Render for InterfaceFunc { +impl InterfaceFunc { fn to_sexpr(&self) -> SExpr { let header = vec![ SExpr::annot("interface"), @@ -281,7 +270,7 @@ impl Render for InterfaceFunc { SExpr::Vec(vec![ SExpr::word("param"), f.name.to_sexpr(), - f.type_.to_sexpr(), + f.tref.to_sexpr(), ]), ) }) @@ -295,7 +284,7 @@ impl Render for InterfaceFunc { SExpr::Vec(vec![ SExpr::word("result"), f.name.to_sexpr(), - f.type_.to_sexpr(), + f.tref.to_sexpr(), ]), ) }) diff --git a/proposals/filesystem/tools/witx/src/toplevel.rs b/proposals/filesystem/tools/witx/src/toplevel.rs index 2e0738a6b..4fb13b8d7 100644 --- a/proposals/filesystem/tools/witx/src/toplevel.rs +++ b/proposals/filesystem/tools/witx/src/toplevel.rs @@ -107,21 +107,11 @@ mod test { ) .expect("parse"); - match &doc.datatype(&Id::new("b_float")).unwrap().variant { - DatatypeVariant::Alias(a) => { - assert_eq!(a.name.as_str(), "b_float"); - assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::F64)); - } - other => panic!("expected alias, got {:?}", other), - } + let b_float = doc.typename(&Id::new("b_float")).unwrap(); + assert_eq!(*b_float.type_(), Type::Builtin(BuiltinType::F64)); - match &doc.datatype(&Id::new("c_int")).unwrap().variant { - DatatypeVariant::Alias(a) => { - assert_eq!(a.name.as_str(), "c_int"); - assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::U32)); - } - other => panic!("expected alias, got {:?}", other), - } + let c_int = doc.typename(&Id::new("c_int")).unwrap(); + assert_eq!(*c_int.type_(), Type::Builtin(BuiltinType::U32)); } #[test] @@ -137,13 +127,8 @@ mod test { ) .expect("parse"); - match &doc.datatype(&Id::new("d_char")).unwrap().variant { - DatatypeVariant::Alias(a) => { - assert_eq!(a.name.as_str(), "d_char"); - assert_eq!(a.to, DatatypeIdent::Builtin(BuiltinType::U8)); - } - other => panic!("expected alias, got {:?}", other), - } + let d_char = doc.typename(&Id::new("d_char")).unwrap(); + assert_eq!(*d_char.type_(), Type::Builtin(BuiltinType::U8)); } #[test] diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 5781ebd06..f9cc2a169 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -1,14 +1,13 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ - CommentSyntax, DatatypeIdentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, - HandleSyntax, ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, + ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, - AliasDatatype, BuiltinType, Datatype, DatatypeIdent, DatatypePassedBy, DatatypeVariant, - Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, - IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, - ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, StructDatatype, StructMember, - UnionDatatype, UnionVariant, + BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, + HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, + Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, + StructDatatype, StructMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, }; use failure::Fail; use std::collections::HashMap; @@ -168,39 +167,17 @@ impl DocValidationScope<'_> { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; let docs = comments.docs(); - let variant = - match &decl.def { - TypedefSyntax::Ident(syntax) => DatatypeVariant::Alias(AliasDatatype { - name: name.clone(), - to: self.validate_datatype_ident(&syntax)?, - }), - TypedefSyntax::Enum(syntax) => DatatypeVariant::Enum(self.validate_enum( - &name, - &syntax, - decl.ident.span(), - )?), - TypedefSyntax::Flags(syntax) => DatatypeVariant::Flags( - self.validate_flags(&name, &syntax, decl.ident.span())?, - ), - TypedefSyntax::Struct(syntax) => DatatypeVariant::Struct( - self.validate_struct(&name, &syntax, decl.ident.span())?, - ), - TypedefSyntax::Union(syntax) => DatatypeVariant::Union( - self.validate_union(&name, &syntax, decl.ident.span())?, - ), - TypedefSyntax::Handle(syntax) => DatatypeVariant::Handle( - self.validate_handle(&name, syntax, decl.ident.span())?, - ), - }; - let rc_datatype = Rc::new(Datatype { + let dt = self.validate_datatype(&decl.def, decl.ident.span())?; + + let rc_datatype = Rc::new(NamedType { name: name.clone(), - variant, + dt, docs, }); self.doc .entries - .insert(name, Entry::Datatype(Rc::downgrade(&rc_datatype))); - Ok(Definition::Datatype(rc_datatype)) + .insert(name, Entry::Typename(Rc::downgrade(&rc_datatype))); + Ok(Definition::Typename(rc_datatype)) } DeclSyntax::Module(syntax) => { let name = self.introduce(&syntax.name)?; @@ -225,45 +202,51 @@ impl DocValidationScope<'_> { } } - fn validate_datatype_ident( + fn validate_datatype( &self, - syntax: &DatatypeIdentSyntax, - ) -> Result { + syntax: &TypedefSyntax, + span: wast::Span, + ) -> Result { match syntax { - DatatypeIdentSyntax::Builtin(b) => Ok(DatatypeIdent::Builtin(*b)), - DatatypeIdentSyntax::Array(a) => Ok(DatatypeIdent::Array(Box::new( - self.validate_datatype_ident(&a)?, - ))), - DatatypeIdentSyntax::Pointer(a) => Ok(DatatypeIdent::Pointer(Box::new( - self.validate_datatype_ident(&a)?, - ))), - DatatypeIdentSyntax::ConstPointer(a) => Ok(DatatypeIdent::ConstPointer(Box::new( - self.validate_datatype_ident(&a)?, - ))), - DatatypeIdentSyntax::Ident(i) => { - let id = self.get(i)?; - match self.doc.entries.get(&id) { - Some(Entry::Datatype(weak_d)) => Ok(DatatypeIdent::Ident( - weak_d.upgrade().expect("weak backref to defined type"), + TypedefSyntax::Ident(syntax) => { + let i = self.get(syntax)?; + match self.doc.entries.get(&i) { + Some(Entry::Typename(weak_ref)) => Ok(TypeRef::Name( + weak_ref.upgrade().expect("weak backref to defined type"), )), Some(e) => Err(ValidationError::WrongKindName { - name: i.name().to_string(), - location: self.location(i.span()), + name: i.as_str().to_string(), + location: self.location(syntax.span()), expected: "datatype", got: e.kind(), }), None => Err(ValidationError::Recursive { - name: i.name().to_string(), - location: self.location(i.span()), + name: i.as_str().to_string(), + location: self.location(syntax.span()), }), } } + other => Ok(TypeRef::Value(Rc::new(match other { + TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), + TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), + TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), + TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), + TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), + TypedefSyntax::Array(syntax) => Type::Array(self.validate_datatype(syntax, span)?), + TypedefSyntax::Pointer(syntax) => { + Type::Pointer(self.validate_datatype(syntax, span)?) + } + TypedefSyntax::ConstPointer(syntax) => { + Type::ConstPointer(self.validate_datatype(syntax, span)?) + } + TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), + TypedefSyntax::Ident { .. } => unreachable!(), + }))), } } fn validate_enum( &self, - name: &Id, syntax: &EnumSyntax, span: wast::Span, ) -> Result { @@ -279,16 +262,11 @@ impl DocValidationScope<'_> { }) .collect::, _>>()?; - Ok(EnumDatatype { - name: name.clone(), - repr, - variants, - }) + Ok(EnumDatatype { repr, variants }) } fn validate_flags( &self, - name: &Id, syntax: &FlagsSyntax, span: wast::Span, ) -> Result { @@ -304,16 +282,11 @@ impl DocValidationScope<'_> { }) .collect::, _>>()?; - Ok(FlagsDatatype { - name: name.clone(), - repr, - flags, - }) + Ok(FlagsDatatype { repr, flags }) } fn validate_struct( &self, - name: &Id, syntax: &StructSyntax, _span: wast::Span, ) -> Result { @@ -324,21 +297,17 @@ impl DocValidationScope<'_> { .map(|f| { let name = member_scope .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let type_ = self.validate_datatype_ident(&f.item.type_)?; + let tref = self.validate_datatype(&f.item.type_, f.item.name.span())?; let docs = f.comments.docs(); - Ok(StructMember { name, type_, docs }) + Ok(StructMember { name, tref, docs }) }) .collect::, _>>()?; - Ok(StructDatatype { - name: name.clone(), - members, - }) + Ok(StructDatatype { members }) } fn validate_union( &self, - name: &Id, syntax: &UnionSyntax, _span: wast::Span, ) -> Result { @@ -349,21 +318,17 @@ impl DocValidationScope<'_> { .map(|f| { let name = variant_scope .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let type_ = self.validate_datatype_ident(&f.item.type_)?; + let tref = self.validate_datatype(&f.item.type_, f.item.name.span())?; let docs = f.comments.docs(); - Ok(UnionVariant { name, type_, docs }) + Ok(UnionVariant { name, tref, docs }) }) .collect::, _>>()?; - Ok(UnionDatatype { - name: name.clone(), - variants, - }) + Ok(UnionDatatype { variants }) } fn validate_handle( &self, - name: &Id, syntax: &HandleSyntax, _span: wast::Span, ) -> Result { @@ -373,15 +338,15 @@ impl DocValidationScope<'_> { .map(|id_syntax| { let id = self.get(&id_syntax)?; match self.doc.entries.get(&id) { - Some(Entry::Datatype(weak_d)) => { - let d = weak_d.upgrade().expect("weak backref to defined type"); - match &d.variant { - DatatypeVariant::Handle { .. } => Ok(DatatypeIdent::Ident(d)), - _ => Err(ValidationError::WrongKindName { + Some(Entry::Typename(weak_ref)) => { + let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); + match &*named_dt.type_() { + Type::Handle { .. } => Ok(TypeRef::Name(named_dt)), + other => Err(ValidationError::WrongKindName { name: id_syntax.name().to_string(), location: self.location(id_syntax.span()), expected: "handle", - got: d.variant.kind(), + got: other.kind(), }), } } @@ -397,12 +362,9 @@ impl DocValidationScope<'_> { }), } }) - .collect::, _>>()?; + .collect::, _>>()?; - Ok(HandleDatatype { - name: name.clone(), - supertypes, - }) + Ok(HandleDatatype { supertypes }) } fn validate_int_repr( @@ -472,7 +434,9 @@ impl<'a> ModuleValidation<'a> { f.item.name.name(), self.doc.location(f.item.name.span()), )?, - type_: self.doc.validate_datatype_ident(&f.item.type_)?, + tref: self + .doc + .validate_datatype(&f.item.type_, f.item.name.span())?, position: InterfaceFuncParamPosition::Param(ix), docs: f.comments.docs(), }) @@ -483,10 +447,12 @@ impl<'a> ModuleValidation<'a> { .iter() .enumerate() .map(|(ix, f)| { - let type_ = self.doc.validate_datatype_ident(&f.item.type_)?; + let tref = self + .doc + .validate_datatype(&f.item.type_, f.item.name.span())?; if ix == 0 { - match type_.passed_by() { - DatatypePassedBy::Value(_) => {} + match tref.type_().passed_by() { + TypePassedBy::Value(_) => {} _ => Err(ValidationError::InvalidFirstResultType { location: self.doc.location(f.item.name.span()), })?, @@ -497,7 +463,7 @@ impl<'a> ModuleValidation<'a> { f.item.name.name(), self.doc.location(f.item.name.span()), )?, - type_, + tref, position: InterfaceFuncParamPosition::Result(ix), docs: f.comments.docs(), }) diff --git a/proposals/filesystem/tools/witx/tests/multimodule.rs b/proposals/filesystem/tools/witx/tests/multimodule.rs index e9cc5ecb9..47fb34755 100644 --- a/proposals/filesystem/tools/witx/tests/multimodule.rs +++ b/proposals/filesystem/tools/witx/tests/multimodule.rs @@ -1,4 +1,4 @@ -use witx::{load, BuiltinType, DatatypeIdent, DatatypeVariant, Id}; +use witx::{load, BuiltinType, Id, Type, TypeRef}; #[test] fn validate_multimodule() { @@ -9,44 +9,35 @@ fn validate_multimodule() { ]) .unwrap_or_else(|e| panic!("failed to validate: {}", e)); - println!("{}", doc); + //println!("{}", doc); // Check that the `a` both modules use is what we expect: - let type_a = doc.datatype(&Id::new("a")).expect("type a exists"); - match &type_a.variant { - DatatypeVariant::Alias(alias) => match alias.to { - DatatypeIdent::Builtin(b) => assert_eq!(b, BuiltinType::U32), - _ => panic!("a is an alias u32"), - }, - _ => panic!("a is an alias to u32"), - } + let type_a = doc.typename(&Id::new("a")).expect("type a exists"); + assert_eq!(*type_a.type_(), Type::Builtin(BuiltinType::U32)); // `b` is a struct with a single member of type `a` - let type_b = doc.datatype(&Id::new("b")).expect("type b exists"); - match &type_b.variant { - DatatypeVariant::Struct(struct_) => { + let type_b = doc.typename(&Id::new("b")).expect("type b exists"); + match &*type_b.type_() { + Type::Struct(struct_) => { assert_eq!(struct_.members.len(), 1); - match &struct_.members.get(0).unwrap().type_ { - DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), - _ => panic!("b.0 has type a"), - } + assert_eq!( + struct_.members.get(0).unwrap().tref, + TypeRef::Name(type_a.clone()) + ); } _ => panic!("b is a struct"), } // `c` is a struct with a two members of type `a` - let type_c = doc.datatype(&Id::new("c")).expect("type c exists"); - match &type_c.variant { - DatatypeVariant::Struct(struct_) => { + let type_c = doc.typename(&Id::new("c")).expect("type c exists"); + match &*type_c.type_() { + Type::Struct(struct_) => { assert_eq!(struct_.members.len(), 2); - match &struct_.members.get(0).unwrap().type_ { - DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), - _ => panic!("c.0 has type a"), - } - match &struct_.members.get(1).unwrap().type_ { - DatatypeIdent::Ident(member_a) => assert_eq!(*member_a, type_a), - _ => panic!("c.1 has type a"), - } + assert_eq!( + struct_.members.get(0).unwrap().tref, + TypeRef::Name(type_a.clone()) + ); + assert_eq!(struct_.members.get(1).unwrap().tref, TypeRef::Name(type_a)); } _ => panic!("c is a struct"), } diff --git a/proposals/filesystem/tools/witx/tests/wasi.rs b/proposals/filesystem/tools/witx/tests/wasi.rs index 938c78067..6d6ebc120 100644 --- a/proposals/filesystem/tools/witx/tests/wasi.rs +++ b/proposals/filesystem/tools/witx/tests/wasi.rs @@ -33,8 +33,8 @@ fn render_roundtrip() { // I'd just assert_eq, but when it fails the debug print is thousands of lines long and impossible // to figure out where they are unequal. if doc != doc2 { - for type_ in doc.datatypes() { - let type2 = doc2.datatype(&type_.name).expect("doc2 missing datatype"); + for type_ in doc.typenames() { + let type2 = doc2.typename(&type_.name).expect("doc2 missing datatype"); assert_eq!(type_, type2); } for mod_ in doc.modules() { @@ -52,3 +52,14 @@ fn render_roundtrip() { // This should be equivelant to the above, but just in case some code changes where it isnt: assert_eq!(doc, doc2); } + +#[test] +fn document_wasi_snapshot() { + use witx::Documentation; + println!( + "{}", + witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)) + .to_md() + ); +} From 0f9ea45069060c0289bb87323e995cf43bcc77e4 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 26 Nov 2019 11:38:16 -0800 Subject: [PATCH 0313/1772] Switch witx from `failure` to `thiserror` --- proposals/clocks/tools/witx/Cargo.toml | 2 +- proposals/clocks/tools/witx/src/lib.rs | 16 ++++++++-------- proposals/clocks/tools/witx/src/validate.rs | 19 ++++++++----------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 11b0e4ba0..309800edc 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -20,4 +20,4 @@ path = "src/main.rs" [dependencies] clap = "2" wast = "3.0.4" -failure = "0.1" +thiserror = "1.0" diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 1c538d9da..ef32bf882 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -29,8 +29,8 @@ pub use parser::DeclSyntax; pub use render::SExpr; pub use validate::ValidationError; -use failure::Fail; use std::path::{Path, PathBuf}; +use thiserror::Error; /// Load a witx document from the filesystem pub fn load>(paths: &[P]) -> Result { @@ -51,14 +51,14 @@ pub struct Location { pub column: usize, } -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum WitxError { - #[fail(display = "with file {:?}: {}", _0, _1)] - Io(PathBuf, #[cause] ::std::io::Error), - #[fail(display = "{}", _0)] - Parse(#[cause] wast::Error), - #[fail(display = "{}", _0)] - Validation(#[cause] ValidationError), + #[error("IO error with file {0:?}")] + Io(PathBuf, #[source] ::std::io::Error), + #[error("Parse error")] + Parse(#[from] wast::Error), + #[error("Validation error")] + Validation(#[from] ValidationError), } impl WitxError { diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index f9cc2a169..de9e3e49c 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -9,39 +9,36 @@ use crate::{ Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, }; -use failure::Fail; use std::collections::HashMap; use std::path::Path; use std::rc::Rc; +use thiserror::Error; -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum ValidationError { - #[fail(display = "Unknown name `{}`", name)] + #[error("Unknown name `{name}`")] UnknownName { name: String, location: Location }, - #[fail(display = "Redefinition of name `{}`", name)] + #[error("Redefinition of name `{name}`")] NameAlreadyExists { name: String, at_location: Location, previous_location: Location, }, - #[fail( - display = "Wrong kind of name `{}`: expected {}, got {}", - name, expected, got - )] + #[error("Wrong kind of name `{name}`: expected {expected}, got {got}")] WrongKindName { name: String, location: Location, expected: &'static str, got: &'static str, }, - #[fail(display = "Recursive definition of name `{}`", name)] + #[error("Recursive definition of name `{name}`")] Recursive { name: String, location: Location }, - #[fail(display = "Invalid representation `{:?}`", repr)] + #[error("Invalid representation `{repr:?}`")] InvalidRepr { repr: BuiltinType, location: Location, }, - #[fail(display = "First result type must be pass-by-value")] + #[error("First result type must be pass-by-value")] InvalidFirstResultType { location: Location }, } From b4dc275e9a5897d280b47214a447f63e7e160c94 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 26 Nov 2019 11:38:16 -0800 Subject: [PATCH 0314/1772] Switch witx from `failure` to `thiserror` --- proposals/random/tools/witx/Cargo.toml | 2 +- proposals/random/tools/witx/src/lib.rs | 16 ++++++++-------- proposals/random/tools/witx/src/validate.rs | 19 ++++++++----------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 11b0e4ba0..309800edc 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -20,4 +20,4 @@ path = "src/main.rs" [dependencies] clap = "2" wast = "3.0.4" -failure = "0.1" +thiserror = "1.0" diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 1c538d9da..ef32bf882 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -29,8 +29,8 @@ pub use parser::DeclSyntax; pub use render::SExpr; pub use validate::ValidationError; -use failure::Fail; use std::path::{Path, PathBuf}; +use thiserror::Error; /// Load a witx document from the filesystem pub fn load>(paths: &[P]) -> Result { @@ -51,14 +51,14 @@ pub struct Location { pub column: usize, } -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum WitxError { - #[fail(display = "with file {:?}: {}", _0, _1)] - Io(PathBuf, #[cause] ::std::io::Error), - #[fail(display = "{}", _0)] - Parse(#[cause] wast::Error), - #[fail(display = "{}", _0)] - Validation(#[cause] ValidationError), + #[error("IO error with file {0:?}")] + Io(PathBuf, #[source] ::std::io::Error), + #[error("Parse error")] + Parse(#[from] wast::Error), + #[error("Validation error")] + Validation(#[from] ValidationError), } impl WitxError { diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index f9cc2a169..de9e3e49c 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -9,39 +9,36 @@ use crate::{ Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, }; -use failure::Fail; use std::collections::HashMap; use std::path::Path; use std::rc::Rc; +use thiserror::Error; -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum ValidationError { - #[fail(display = "Unknown name `{}`", name)] + #[error("Unknown name `{name}`")] UnknownName { name: String, location: Location }, - #[fail(display = "Redefinition of name `{}`", name)] + #[error("Redefinition of name `{name}`")] NameAlreadyExists { name: String, at_location: Location, previous_location: Location, }, - #[fail( - display = "Wrong kind of name `{}`: expected {}, got {}", - name, expected, got - )] + #[error("Wrong kind of name `{name}`: expected {expected}, got {got}")] WrongKindName { name: String, location: Location, expected: &'static str, got: &'static str, }, - #[fail(display = "Recursive definition of name `{}`", name)] + #[error("Recursive definition of name `{name}`")] Recursive { name: String, location: Location }, - #[fail(display = "Invalid representation `{:?}`", repr)] + #[error("Invalid representation `{repr:?}`")] InvalidRepr { repr: BuiltinType, location: Location, }, - #[fail(display = "First result type must be pass-by-value")] + #[error("First result type must be pass-by-value")] InvalidFirstResultType { location: Location }, } From ceac1526a3e72f08c1db621a143bed9082c3a3bb Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 26 Nov 2019 11:38:16 -0800 Subject: [PATCH 0315/1772] Switch witx from `failure` to `thiserror` --- proposals/filesystem/tools/witx/Cargo.toml | 2 +- proposals/filesystem/tools/witx/src/lib.rs | 16 ++++++++-------- .../filesystem/tools/witx/src/validate.rs | 19 ++++++++----------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 11b0e4ba0..309800edc 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -20,4 +20,4 @@ path = "src/main.rs" [dependencies] clap = "2" wast = "3.0.4" -failure = "0.1" +thiserror = "1.0" diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 1c538d9da..ef32bf882 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -29,8 +29,8 @@ pub use parser::DeclSyntax; pub use render::SExpr; pub use validate::ValidationError; -use failure::Fail; use std::path::{Path, PathBuf}; +use thiserror::Error; /// Load a witx document from the filesystem pub fn load>(paths: &[P]) -> Result { @@ -51,14 +51,14 @@ pub struct Location { pub column: usize, } -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum WitxError { - #[fail(display = "with file {:?}: {}", _0, _1)] - Io(PathBuf, #[cause] ::std::io::Error), - #[fail(display = "{}", _0)] - Parse(#[cause] wast::Error), - #[fail(display = "{}", _0)] - Validation(#[cause] ValidationError), + #[error("IO error with file {0:?}")] + Io(PathBuf, #[source] ::std::io::Error), + #[error("Parse error")] + Parse(#[from] wast::Error), + #[error("Validation error")] + Validation(#[from] ValidationError), } impl WitxError { diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index f9cc2a169..de9e3e49c 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -9,39 +9,36 @@ use crate::{ Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, }; -use failure::Fail; use std::collections::HashMap; use std::path::Path; use std::rc::Rc; +use thiserror::Error; -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum ValidationError { - #[fail(display = "Unknown name `{}`", name)] + #[error("Unknown name `{name}`")] UnknownName { name: String, location: Location }, - #[fail(display = "Redefinition of name `{}`", name)] + #[error("Redefinition of name `{name}`")] NameAlreadyExists { name: String, at_location: Location, previous_location: Location, }, - #[fail( - display = "Wrong kind of name `{}`: expected {}, got {}", - name, expected, got - )] + #[error("Wrong kind of name `{name}`: expected {expected}, got {got}")] WrongKindName { name: String, location: Location, expected: &'static str, got: &'static str, }, - #[fail(display = "Recursive definition of name `{}`", name)] + #[error("Recursive definition of name `{name}`")] Recursive { name: String, location: Location }, - #[fail(display = "Invalid representation `{:?}`", repr)] + #[error("Invalid representation `{repr:?}`")] InvalidRepr { repr: BuiltinType, location: Location, }, - #[fail(display = "First result type must be pass-by-value")] + #[error("First result type must be pass-by-value")] InvalidFirstResultType { location: Location }, } From c83c47b0be8dd0dc59efa8c1c3757a0074917155 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 26 Nov 2019 11:38:39 -0800 Subject: [PATCH 0316/1772] witx: bump version to 0.6.0 --- proposals/clocks/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 309800edc..2fffc2c12 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.5.0" +version = "0.6.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 111b629e1d00e567cb3f0502d8d787da7090fdda Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 26 Nov 2019 11:38:39 -0800 Subject: [PATCH 0317/1772] witx: bump version to 0.6.0 --- proposals/random/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 309800edc..2fffc2c12 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.5.0" +version = "0.6.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 6bb1d5b53ea4401dfec5c8b1720f51a3ad7891d6 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 26 Nov 2019 11:38:39 -0800 Subject: [PATCH 0318/1772] witx: bump version to 0.6.0 --- proposals/filesystem/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 309800edc..2fffc2c12 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.5.0" +version = "0.6.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 28884e81f7899fcdced97c8e2bbbd4064bfd276c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 10:18:55 -0800 Subject: [PATCH 0319/1772] Remove `proc_raise` and the signal types and constants. WebAssembly doesn't support signal handling, so these weren't useful for their main purpose. The one thing you could do with `proc_raise` was terminate execution with a signal status, however that's not super useful and even wasi-libc didn't make use of it in its abort function. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 201 ------------------ .../phases/ephemeral/witx/typenames.witx | 99 --------- .../witx/wasi_ephemeral_preview.witx | 8 - 3 files changed, 308 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md index 6de15f1d2..087716fa5 100644 --- a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -106,7 +106,6 @@ modules so that embedders need not implement all of it. - [`__wasi_path_unlink_file()`](#path_unlink_file) - [`__wasi_poll_oneoff()`](#poll_oneoff) - [`__wasi_proc_exit()`](#proc_exit) -- [`__wasi_proc_raise()`](#proc_raise) - [`__wasi_random_get()`](#random_get) - [`__wasi_sched_yield()`](#sched_yield) - [`__wasi_sock_recv()`](#sock_recv) @@ -951,18 +950,6 @@ Inputs: Does not return. -### `__wasi_proc_raise()` - -Send a signal to the process of the calling thread. - -Note: This is similar to `raise` in POSIX. - -Inputs: - -- [\_\_wasi\_signal\_t](#signal) sig - - The signal condition to trigger. - ### `__wasi_random_get()` Write high-quality random data into a buffer. @@ -2057,194 +2044,6 @@ defined, it must be set to zero. Used by [`__wasi_sock_send()`](#sock_send). -### `__wasi_signal_t` (`uint8_t`) - -Signal condition. - -Used by [`__wasi_proc_raise()`](#proc_raise). - -Possible values: - -- **`__WASI_SIGHUP`** - - Hangup. - - Action: Terminates the process. - -- **`__WASI_SIGINT`** - - Terminate interrupt signal. - - Action: Terminates the process. - -- **`__WASI_SIGQUIT`** - - Terminal quit signal. - - Action: Terminates the process. - -- **`__WASI_SIGILL`** - - Illegal instruction. - - Action: Terminates the process. - -- **`__WASI_SIGTRAP`** - - Trace/breakpoint trap. - - Action: Terminates the process. - -- **`__WASI_SIGABRT`** - - Process abort signal. - - Action: Terminates the process. - -- **`__WASI_SIGBUS`** - - Access to an undefined portion of a memory object. - - Action: Terminates the process. - -- **`__WASI_SIGFPE`** - - Erroneous arithmetic operation. - - Action: Terminates the process. - -- **`__WASI_SIGKILL`** - - Kill. - - Action: Terminates the process. - -- **`__WASI_SIGUSR1`** - - User-defined signal 1. - - Action: Terminates the process. - -- **`__WASI_SIGSEGV`** - - Invalid memory reference. - - Action: Terminates the process. - -- **`__WASI_SIGUSR2`** - - User-defined signal 2. - - Action: Terminates the process. - -- **`__WASI_SIGPIPE`** - - Write on a pipe with no one to read it. - - Action: Ignored. - -- **`__WASI_SIGALRM`** - - Alarm clock. - - Action: Terminates the process. - -- **`__WASI_SIGTERM`** - - Termination signal. - - Action: Terminates the process. - -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** - - Continue executing, if stopped. - - Action: Continues executing, if stopped. - -- **`__WASI_SIGSTOP`** - - Stop executing. - - Action: Stops executing. - -- **`__WASI_SIGTSTP`** - - Terminal stop signal. - - Action: Stops executing. - -- **`__WASI_SIGTTIN`** - - Background process attempting read. - - Action: Stops executing. - -- **`__WASI_SIGTTOU`** - - Background process attempting write. - - Action: Stops executing. - -- **`__WASI_SIGURG`** - - High bandwidth data is available at a socket. - - Action: Ignored. - -- **`__WASI_SIGXCPU`** - - CPU time limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGXFSZ`** - - File size limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGVTALRM`** - - Virtual timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGPROF`** - - Profiling timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGWINCH`** - - Window changed. - - Action: Ignored. - -- **`__WASI_SIGPOLL`** - - I/O possible. - - Action: Terminates the process. - -- **`__WASI_SIGPWR`** - - Power failure. - - Action: Terminates the process. - -- **`__WASI_SIGSYS`** - - Bad system call. - - Action: Terminates the process. - ### `__wasi_subclockflags_t` (`uint16_t` bitfield) Flags determining how to interpret the timestamp provided in diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 5802048be..904aa1ca9 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -601,105 +601,6 @@ ;;; Exit code generated by a process when exiting. (typename $exitcode u32) -;;; Signal condition. -(typename $signal - (enum u8 - ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;;; so this value is reserved. - $none - ;;; Hangup. - ;;; Action: Terminates the process. - $hup - ;;; Terminate interrupt signal. - ;;; Action: Terminates the process. - $int - ;;; Terminal quit signal. - ;;; Action: Terminates the process. - $quit - ;;; Illegal instruction. - ;;; Action: Terminates the process. - $ill - ;;; Trace/breakpoint trap. - ;;; Action: Terminates the process. - $trap - ;;; Process abort signal. - ;;; Action: Terminates the process. - $abrt - ;;; Access to an undefined portion of a memory object. - ;;; Action: Terminates the process. - $bus - ;;; Erroneous arithmetic operation. - ;;; Action: Terminates the process. - $fpe - ;;; Kill. - ;;; Action: Terminates the process. - $kill - ;;; User-defined signal 1. - ;;; Action: Terminates the process. - $usr1 - ;;; Invalid memory reference. - ;;; Action: Terminates the process. - $segv - ;;; User-defined signal 2. - ;;; Action: Terminates the process. - $usr2 - ;;; Write on a pipe with no one to read it. - ;;; Action: Ignored. - $pipe - ;;; Alarm clock. - ;;; Action: Terminates the process. - $alrm - ;;; Termination signal. - ;;; Action: Terminates the process. - $term - ;;; Child process terminated, stopped, or continued. - ;;; Action: Ignored. - $chld - ;;; Continue executing, if stopped. - ;;; Action: Continues executing, if stopped. - $cont - ;;; Stop executing. - ;;; Action: Stops executing. - $stop - ;;; Terminal stop signal. - ;;; Action: Stops executing. - $tstp - ;;; Background process attempting read. - ;;; Action: Stops executing. - $ttin - ;;; Background process attempting write. - ;;; Action: Stops executing. - $ttou - ;;; High bandwidth data is available at a socket. - ;;; Action: Ignored. - $urg - ;;; CPU time limit exceeded. - ;;; Action: Terminates the process. - $xcpu - ;;; File size limit exceeded. - ;;; Action: Terminates the process. - $xfsz - ;;; Virtual timer expired. - ;;; Action: Terminates the process. - $vtalrm - ;;; Profiling timer expired. - ;;; Action: Terminates the process. - $prof - ;;; Window changed. - ;;; Action: Ignored. - $winch - ;;; I/O possible. - ;;; Action: Terminates the process. - $poll - ;;; Power failure. - ;;; Action: Terminates the process. - $pwr - ;;; Bad system call. - ;;; Action: Terminates the process. - $sys - ) -) - ;;; Flags provided to `sock_recv`. (typename $riflags (flags u16 diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx index 43bd57e4b..50bf519e7 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -463,14 +463,6 @@ (param $rval $exitcode) ) - ;;; Send a signal to the process of the calling thread. - ;;; Note: This is similar to `raise` in POSIX. - (@interface func (export "proc_raise") - ;;; The signal condition to trigger. - (param $sig $signal) - (result $error $errno) - ) - ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") From e9c8cf47e16fec8f1a3c67874246945ffabbe5b2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 10:18:55 -0800 Subject: [PATCH 0320/1772] Remove `proc_raise` and the signal types and constants. WebAssembly doesn't support signal handling, so these weren't useful for their main purpose. The one thing you could do with `proc_raise` was terminate execution with a signal status, however that's not super useful and even wasi-libc didn't make use of it in its abort function. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 201 ------------------ .../phases/ephemeral/witx/typenames.witx | 99 --------- .../witx/wasi_ephemeral_preview.witx | 8 - 3 files changed, 308 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md index 6de15f1d2..087716fa5 100644 --- a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -106,7 +106,6 @@ modules so that embedders need not implement all of it. - [`__wasi_path_unlink_file()`](#path_unlink_file) - [`__wasi_poll_oneoff()`](#poll_oneoff) - [`__wasi_proc_exit()`](#proc_exit) -- [`__wasi_proc_raise()`](#proc_raise) - [`__wasi_random_get()`](#random_get) - [`__wasi_sched_yield()`](#sched_yield) - [`__wasi_sock_recv()`](#sock_recv) @@ -951,18 +950,6 @@ Inputs: Does not return. -### `__wasi_proc_raise()` - -Send a signal to the process of the calling thread. - -Note: This is similar to `raise` in POSIX. - -Inputs: - -- [\_\_wasi\_signal\_t](#signal) sig - - The signal condition to trigger. - ### `__wasi_random_get()` Write high-quality random data into a buffer. @@ -2057,194 +2044,6 @@ defined, it must be set to zero. Used by [`__wasi_sock_send()`](#sock_send). -### `__wasi_signal_t` (`uint8_t`) - -Signal condition. - -Used by [`__wasi_proc_raise()`](#proc_raise). - -Possible values: - -- **`__WASI_SIGHUP`** - - Hangup. - - Action: Terminates the process. - -- **`__WASI_SIGINT`** - - Terminate interrupt signal. - - Action: Terminates the process. - -- **`__WASI_SIGQUIT`** - - Terminal quit signal. - - Action: Terminates the process. - -- **`__WASI_SIGILL`** - - Illegal instruction. - - Action: Terminates the process. - -- **`__WASI_SIGTRAP`** - - Trace/breakpoint trap. - - Action: Terminates the process. - -- **`__WASI_SIGABRT`** - - Process abort signal. - - Action: Terminates the process. - -- **`__WASI_SIGBUS`** - - Access to an undefined portion of a memory object. - - Action: Terminates the process. - -- **`__WASI_SIGFPE`** - - Erroneous arithmetic operation. - - Action: Terminates the process. - -- **`__WASI_SIGKILL`** - - Kill. - - Action: Terminates the process. - -- **`__WASI_SIGUSR1`** - - User-defined signal 1. - - Action: Terminates the process. - -- **`__WASI_SIGSEGV`** - - Invalid memory reference. - - Action: Terminates the process. - -- **`__WASI_SIGUSR2`** - - User-defined signal 2. - - Action: Terminates the process. - -- **`__WASI_SIGPIPE`** - - Write on a pipe with no one to read it. - - Action: Ignored. - -- **`__WASI_SIGALRM`** - - Alarm clock. - - Action: Terminates the process. - -- **`__WASI_SIGTERM`** - - Termination signal. - - Action: Terminates the process. - -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** - - Continue executing, if stopped. - - Action: Continues executing, if stopped. - -- **`__WASI_SIGSTOP`** - - Stop executing. - - Action: Stops executing. - -- **`__WASI_SIGTSTP`** - - Terminal stop signal. - - Action: Stops executing. - -- **`__WASI_SIGTTIN`** - - Background process attempting read. - - Action: Stops executing. - -- **`__WASI_SIGTTOU`** - - Background process attempting write. - - Action: Stops executing. - -- **`__WASI_SIGURG`** - - High bandwidth data is available at a socket. - - Action: Ignored. - -- **`__WASI_SIGXCPU`** - - CPU time limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGXFSZ`** - - File size limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGVTALRM`** - - Virtual timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGPROF`** - - Profiling timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGWINCH`** - - Window changed. - - Action: Ignored. - -- **`__WASI_SIGPOLL`** - - I/O possible. - - Action: Terminates the process. - -- **`__WASI_SIGPWR`** - - Power failure. - - Action: Terminates the process. - -- **`__WASI_SIGSYS`** - - Bad system call. - - Action: Terminates the process. - ### `__wasi_subclockflags_t` (`uint16_t` bitfield) Flags determining how to interpret the timestamp provided in diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 5802048be..904aa1ca9 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -601,105 +601,6 @@ ;;; Exit code generated by a process when exiting. (typename $exitcode u32) -;;; Signal condition. -(typename $signal - (enum u8 - ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;;; so this value is reserved. - $none - ;;; Hangup. - ;;; Action: Terminates the process. - $hup - ;;; Terminate interrupt signal. - ;;; Action: Terminates the process. - $int - ;;; Terminal quit signal. - ;;; Action: Terminates the process. - $quit - ;;; Illegal instruction. - ;;; Action: Terminates the process. - $ill - ;;; Trace/breakpoint trap. - ;;; Action: Terminates the process. - $trap - ;;; Process abort signal. - ;;; Action: Terminates the process. - $abrt - ;;; Access to an undefined portion of a memory object. - ;;; Action: Terminates the process. - $bus - ;;; Erroneous arithmetic operation. - ;;; Action: Terminates the process. - $fpe - ;;; Kill. - ;;; Action: Terminates the process. - $kill - ;;; User-defined signal 1. - ;;; Action: Terminates the process. - $usr1 - ;;; Invalid memory reference. - ;;; Action: Terminates the process. - $segv - ;;; User-defined signal 2. - ;;; Action: Terminates the process. - $usr2 - ;;; Write on a pipe with no one to read it. - ;;; Action: Ignored. - $pipe - ;;; Alarm clock. - ;;; Action: Terminates the process. - $alrm - ;;; Termination signal. - ;;; Action: Terminates the process. - $term - ;;; Child process terminated, stopped, or continued. - ;;; Action: Ignored. - $chld - ;;; Continue executing, if stopped. - ;;; Action: Continues executing, if stopped. - $cont - ;;; Stop executing. - ;;; Action: Stops executing. - $stop - ;;; Terminal stop signal. - ;;; Action: Stops executing. - $tstp - ;;; Background process attempting read. - ;;; Action: Stops executing. - $ttin - ;;; Background process attempting write. - ;;; Action: Stops executing. - $ttou - ;;; High bandwidth data is available at a socket. - ;;; Action: Ignored. - $urg - ;;; CPU time limit exceeded. - ;;; Action: Terminates the process. - $xcpu - ;;; File size limit exceeded. - ;;; Action: Terminates the process. - $xfsz - ;;; Virtual timer expired. - ;;; Action: Terminates the process. - $vtalrm - ;;; Profiling timer expired. - ;;; Action: Terminates the process. - $prof - ;;; Window changed. - ;;; Action: Ignored. - $winch - ;;; I/O possible. - ;;; Action: Terminates the process. - $poll - ;;; Power failure. - ;;; Action: Terminates the process. - $pwr - ;;; Bad system call. - ;;; Action: Terminates the process. - $sys - ) -) - ;;; Flags provided to `sock_recv`. (typename $riflags (flags u16 diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx index 43bd57e4b..50bf519e7 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -463,14 +463,6 @@ (param $rval $exitcode) ) - ;;; Send a signal to the process of the calling thread. - ;;; Note: This is similar to `raise` in POSIX. - (@interface func (export "proc_raise") - ;;; The signal condition to trigger. - (param $sig $signal) - (result $error $errno) - ) - ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") From e157a9f046d7a46b65fce8b26df90d43b280db18 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 Nov 2019 10:18:55 -0800 Subject: [PATCH 0321/1772] Remove `proc_raise` and the signal types and constants. WebAssembly doesn't support signal handling, so these weren't useful for their main purpose. The one thing you could do with `proc_raise` was terminate execution with a signal status, however that's not super useful and even wasi-libc didn't make use of it in its abort function. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 201 ------------------ .../phases/ephemeral/witx/typenames.witx | 99 --------- .../witx/wasi_ephemeral_preview.witx | 8 - 3 files changed, 308 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md index 6de15f1d2..087716fa5 100644 --- a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md @@ -106,7 +106,6 @@ modules so that embedders need not implement all of it. - [`__wasi_path_unlink_file()`](#path_unlink_file) - [`__wasi_poll_oneoff()`](#poll_oneoff) - [`__wasi_proc_exit()`](#proc_exit) -- [`__wasi_proc_raise()`](#proc_raise) - [`__wasi_random_get()`](#random_get) - [`__wasi_sched_yield()`](#sched_yield) - [`__wasi_sock_recv()`](#sock_recv) @@ -951,18 +950,6 @@ Inputs: Does not return. -### `__wasi_proc_raise()` - -Send a signal to the process of the calling thread. - -Note: This is similar to `raise` in POSIX. - -Inputs: - -- [\_\_wasi\_signal\_t](#signal) sig - - The signal condition to trigger. - ### `__wasi_random_get()` Write high-quality random data into a buffer. @@ -2057,194 +2044,6 @@ defined, it must be set to zero. Used by [`__wasi_sock_send()`](#sock_send). -### `__wasi_signal_t` (`uint8_t`) - -Signal condition. - -Used by [`__wasi_proc_raise()`](#proc_raise). - -Possible values: - -- **`__WASI_SIGHUP`** - - Hangup. - - Action: Terminates the process. - -- **`__WASI_SIGINT`** - - Terminate interrupt signal. - - Action: Terminates the process. - -- **`__WASI_SIGQUIT`** - - Terminal quit signal. - - Action: Terminates the process. - -- **`__WASI_SIGILL`** - - Illegal instruction. - - Action: Terminates the process. - -- **`__WASI_SIGTRAP`** - - Trace/breakpoint trap. - - Action: Terminates the process. - -- **`__WASI_SIGABRT`** - - Process abort signal. - - Action: Terminates the process. - -- **`__WASI_SIGBUS`** - - Access to an undefined portion of a memory object. - - Action: Terminates the process. - -- **`__WASI_SIGFPE`** - - Erroneous arithmetic operation. - - Action: Terminates the process. - -- **`__WASI_SIGKILL`** - - Kill. - - Action: Terminates the process. - -- **`__WASI_SIGUSR1`** - - User-defined signal 1. - - Action: Terminates the process. - -- **`__WASI_SIGSEGV`** - - Invalid memory reference. - - Action: Terminates the process. - -- **`__WASI_SIGUSR2`** - - User-defined signal 2. - - Action: Terminates the process. - -- **`__WASI_SIGPIPE`** - - Write on a pipe with no one to read it. - - Action: Ignored. - -- **`__WASI_SIGALRM`** - - Alarm clock. - - Action: Terminates the process. - -- **`__WASI_SIGTERM`** - - Termination signal. - - Action: Terminates the process. - -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** - - Continue executing, if stopped. - - Action: Continues executing, if stopped. - -- **`__WASI_SIGSTOP`** - - Stop executing. - - Action: Stops executing. - -- **`__WASI_SIGTSTP`** - - Terminal stop signal. - - Action: Stops executing. - -- **`__WASI_SIGTTIN`** - - Background process attempting read. - - Action: Stops executing. - -- **`__WASI_SIGTTOU`** - - Background process attempting write. - - Action: Stops executing. - -- **`__WASI_SIGURG`** - - High bandwidth data is available at a socket. - - Action: Ignored. - -- **`__WASI_SIGXCPU`** - - CPU time limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGXFSZ`** - - File size limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGVTALRM`** - - Virtual timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGPROF`** - - Profiling timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGWINCH`** - - Window changed. - - Action: Ignored. - -- **`__WASI_SIGPOLL`** - - I/O possible. - - Action: Terminates the process. - -- **`__WASI_SIGPWR`** - - Power failure. - - Action: Terminates the process. - -- **`__WASI_SIGSYS`** - - Bad system call. - - Action: Terminates the process. - ### `__wasi_subclockflags_t` (`uint16_t` bitfield) Flags determining how to interpret the timestamp provided in diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 5802048be..904aa1ca9 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -601,105 +601,6 @@ ;;; Exit code generated by a process when exiting. (typename $exitcode u32) -;;; Signal condition. -(typename $signal - (enum u8 - ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;;; so this value is reserved. - $none - ;;; Hangup. - ;;; Action: Terminates the process. - $hup - ;;; Terminate interrupt signal. - ;;; Action: Terminates the process. - $int - ;;; Terminal quit signal. - ;;; Action: Terminates the process. - $quit - ;;; Illegal instruction. - ;;; Action: Terminates the process. - $ill - ;;; Trace/breakpoint trap. - ;;; Action: Terminates the process. - $trap - ;;; Process abort signal. - ;;; Action: Terminates the process. - $abrt - ;;; Access to an undefined portion of a memory object. - ;;; Action: Terminates the process. - $bus - ;;; Erroneous arithmetic operation. - ;;; Action: Terminates the process. - $fpe - ;;; Kill. - ;;; Action: Terminates the process. - $kill - ;;; User-defined signal 1. - ;;; Action: Terminates the process. - $usr1 - ;;; Invalid memory reference. - ;;; Action: Terminates the process. - $segv - ;;; User-defined signal 2. - ;;; Action: Terminates the process. - $usr2 - ;;; Write on a pipe with no one to read it. - ;;; Action: Ignored. - $pipe - ;;; Alarm clock. - ;;; Action: Terminates the process. - $alrm - ;;; Termination signal. - ;;; Action: Terminates the process. - $term - ;;; Child process terminated, stopped, or continued. - ;;; Action: Ignored. - $chld - ;;; Continue executing, if stopped. - ;;; Action: Continues executing, if stopped. - $cont - ;;; Stop executing. - ;;; Action: Stops executing. - $stop - ;;; Terminal stop signal. - ;;; Action: Stops executing. - $tstp - ;;; Background process attempting read. - ;;; Action: Stops executing. - $ttin - ;;; Background process attempting write. - ;;; Action: Stops executing. - $ttou - ;;; High bandwidth data is available at a socket. - ;;; Action: Ignored. - $urg - ;;; CPU time limit exceeded. - ;;; Action: Terminates the process. - $xcpu - ;;; File size limit exceeded. - ;;; Action: Terminates the process. - $xfsz - ;;; Virtual timer expired. - ;;; Action: Terminates the process. - $vtalrm - ;;; Profiling timer expired. - ;;; Action: Terminates the process. - $prof - ;;; Window changed. - ;;; Action: Ignored. - $winch - ;;; I/O possible. - ;;; Action: Terminates the process. - $poll - ;;; Power failure. - ;;; Action: Terminates the process. - $pwr - ;;; Bad system call. - ;;; Action: Terminates the process. - $sys - ) -) - ;;; Flags provided to `sock_recv`. (typename $riflags (flags u16 diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx index 43bd57e4b..50bf519e7 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx @@ -463,14 +463,6 @@ (param $rval $exitcode) ) - ;;; Send a signal to the process of the calling thread. - ;;; Note: This is similar to `raise` in POSIX. - (@interface func (export "proc_raise") - ;;; The signal condition to trigger. - (param $sig $signal) - (result $error $errno) - ) - ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") From af36b67dd424ff512899a9bdc381601b6224053e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 25 Sep 2019 23:42:49 -0700 Subject: [PATCH 0322/1772] Modularize the WASI API. This splits what was previously "preview" into separate modules. There's a lot of API evolution still to be done here, and the groupings presented here may change, but this should help get things started. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 2150 ----------------- .../ephemeral/witx/wasi_ephemeral_args.witx | 28 + .../ephemeral/witx/wasi_ephemeral_clock.witx | 36 + .../witx/wasi_ephemeral_environ.witx | 28 + .../ephemeral/witx/wasi_ephemeral_fd.witx | 242 ++ .../ephemeral/witx/wasi_ephemeral_path.witx | 160 ++ .../ephemeral/witx/wasi_ephemeral_poll.witx | 26 + .../witx/wasi_ephemeral_preview.witx | 523 ---- .../ephemeral/witx/wasi_ephemeral_proc.witx | 18 + .../ephemeral/witx/wasi_ephemeral_random.witx | 26 + .../ephemeral/witx/wasi_ephemeral_sched.witx | 16 + .../ephemeral/witx/wasi_ephemeral_sock.witx | 52 + 12 files changed, 632 insertions(+), 2673 deletions(-) delete mode 100644 proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md create mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx create mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx create mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx create mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx create mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx create mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx delete mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx create mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx create mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx create mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sched.witx create mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sock.witx diff --git a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md deleted file mode 100644 index 087716fa5..000000000 --- a/proposals/clocks/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ /dev/null @@ -1,2150 +0,0 @@ - - -# The WASI Preview API - -This is the API-level documentation for WASI Preview. The function names -are prefixed with "\_\_wasi\_" to reflect how they are spelled in -flat-namespace contexts, however at the wasm module level, they are -unprefixed, because they're inside a module namespace. - -Functions that start with `__wasi_fd_` operate on file descriptors, -while functions that start with `__wasi_path_` operate on filesystem -paths, which are relative to directory file descriptors. - -Much inspiration and content here is derived from [CloudABI] and [POSIX], -though there are also several differences from CloudABI and POSIX. For -example, WASI Preview has no concept of processes in the traditional Unix -sense. While wasm linear memories have some of the aspects of processes, -and it's possible to *emulate* the full semantics of processes on top of -them, this can sometimes be unnatural and inefficient. The goal for -WASI Preview is to be a WebAssembly-native API that exposes APIs that fit -well into the underlying WebAssembly platform, rather than to directly -emulate other platforms. - -This is also a work in progress, and the API here is still evolving. - -Historical note: this API was originally named "WASI Core", and used the -API module name "wasi\_unstable". We've since sought to deemphasize the -"Core" name, as the goal is to split this API up into independent -modules so that embedders need not implement all of it. - -[CloudABI]: https://github.com/NuxiNL/cloudabi -[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ - -## System calls - -- [`__wasi_args_get()`](#args_get) -- [`__wasi_args_sizes_get()`](#args_sizes_get) -- [`__wasi_clock_res_get()`](#clock_res_get) -- [`__wasi_clock_time_get()`](#clock_time_get) -- [`__wasi_environ_get()`](#environ_get) -- [`__wasi_environ_sizes_get()`](#environ_sizes_get) -- [`__wasi_fd_advise()`](#fd_advise) -- [`__wasi_fd_allocate()`](#fd_allocate) -- [`__wasi_fd_close()`](#fd_close) -- [`__wasi_fd_datasync()`](#fd_datasync) -- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) -- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) -- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) -- [`__wasi_fd_filestat_get()`](#fd_filestat_get) -- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) -- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) -- [`__wasi_fd_pread()`](#fd_pread) -- [`__wasi_fd_prestat_get()`](#fd_prestat_get) -- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) -- [`__wasi_fd_pwrite()`](#fd_pwrite) -- [`__wasi_fd_read()`](#fd_read) -- [`__wasi_fd_readdir()`](#fd_readdir) -- [`__wasi_fd_renumber()`](#fd_renumber) -- [`__wasi_fd_seek()`](#fd_seek) -- [`__wasi_fd_sync()`](#fd_sync) -- [`__wasi_fd_tell()`](#fd_tell) -- [`__wasi_fd_write()`](#fd_write) -- [`__wasi_path_create_directory()`](#path_create_directory) -- [`__wasi_path_filestat_get()`](#path_filestat_get) -- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) -- [`__wasi_path_link()`](#path_link) -- [`__wasi_path_open()`](#path_open) -- [`__wasi_path_readlink()`](#path_readlink) -- [`__wasi_path_remove_directory()`](#path_remove_directory) -- [`__wasi_path_rename()`](#path_rename) -- [`__wasi_path_symlink()`](#path_symlink) -- [`__wasi_path_unlink_file()`](#path_unlink_file) -- [`__wasi_poll_oneoff()`](#poll_oneoff) -- [`__wasi_proc_exit()`](#proc_exit) -- [`__wasi_random_get()`](#random_get) -- [`__wasi_sched_yield()`](#sched_yield) -- [`__wasi_sock_recv()`](#sock_recv) -- [`__wasi_sock_send()`](#sock_send) -- [`__wasi_sock_shutdown()`](#sock_shutdown) - -### `__wasi_args_get()` - -Read command-line argument data. - -Inputs: - -- char \*\*argv - - A pointer to a buffer to write the argument pointers. - - The count of elements for the buffer should be at least the value of `argc` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - - The caller of `__wasi_args_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. - -- char \*argv\_buf - - A pointer to a buffer to write the argument string data. - - The size of this buffer should be the value of `argv_buf_size` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - -### `__wasi_args_sizes_get()` - -Return command-line argument data sizes. - -Outputs: - -- size\_t \*argc - - The number of arguments. - -- size\_t \*argv\_buf\_size - - The size of the argument string data. - -### `__wasi_clock_res_get()` - -Return the resolution of a clock. - -Implementations are required to provide a non-zero value for supported clocks. -For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). - -Note: This is similar to `clock_getres` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the resolution. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) resolution - - The resolution of the clock. - -### `__wasi_clock_time_get()` - -Return the time value of a clock. - -Note: This is similar to `clock_gettime` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the time. - -- [\_\_wasi\_timestamp\_t](#timestamp) precision - - The maximum lag (exclusive) that the returned - time value may have, compared to its actual - value. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) time - - The time value of the clock. - -### `__wasi_environ_get()` - -Read environment variable data. - -Inputs: - -- char \*\*environ - - A pointer to a buffer to write the environment variable pointers. - - The count of elements for the buffer should be at least the value of `environ_count` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - - The caller of `__wasi_environ_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. - -- char \*environ\_buf - - A pointer to a buffer to write the environment variable string data. - - The size of this buffer should be the value of `environ_buf_size` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - -### `__wasi_environ_sizes_get()` - -Return enviroment variable data sizes. - -Outputs: - -- size\_t \*environ\_count - - The number of environment variables. - -- size\_t \*environ\_buf\_size - - The size of the environment variable string data. - -### `__wasi_fd_advise()` - -Provide file advisory information on a file descriptor. - -Note: This is similar to `posix_fadvise` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file for which to provide file advisory information. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file to which the advisory applies. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the region to which the advisory applies. - -- [\_\_wasi\_advice\_t](#advice) advice - - The advice. - -### `__wasi_fd_allocate()` - -Force the allocation of space in a file. - -Note: This is similar to `posix_fallocate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file in which to allocate space. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset at which to start the allocation. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the area that is allocated. - -### `__wasi_fd_close()` - -Close a file descriptor. - -Note: This is similar to `close` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to close. - -### `__wasi_fd_datasync()` - -Synchronize the data of a file to disk. - -Note: This is similar to `fdatasync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file to synchronize to disk. - -### `__wasi_fd_fdstat_get()` - -Get the attributes of a file descriptor. - -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well -as additional fields. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_fdstat\_t](#fdstat) \*buf - - The buffer where the file descriptor's attributes are stored. - -### `__wasi_fd_fdstat_set_flags()` - -Adjust the flags associated with a file descriptor. - -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_fdflags\_t](#fdflags) flags - - The desired values of the file descriptor - flags. - -### `__wasi_fd_fdstat_set_rights()` - -Adjust the rights associated with a file descriptor. - -This can only be used to remove rights, and returns -[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt -to add rights. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The desired rights of the file descriptor. - -### `__wasi_fd_filestat_get()` - -Return the attributes of an open file. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_fd_filestat_set_size()` - -Adjust the size of an open file. If this increases the file's size, the extra -bytes are filled with zeros. - -Note: This is similar to `ftruncate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - A file descriptor for the file to adjust. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - The desired file size. - -### `__wasi_fd_filestat_set_times()` - -Adjust the timestamps of an open file or directory. - -Note: This is similar to `futimens` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_fd_pread()` - -Read from a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `preadv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors in which to store data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to read. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_prestat_get()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- [\_\_wasi\_prestat\_t](#prestat) \*buf - - The buffer where the description is stored. - -### `__wasi_fd_prestat_dir_name()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- const char \*path and size\_t path\_len - - A buffer into which to write the preopened directory name. - -### `__wasi_fd_pwrite()` - -Write to a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `pwritev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to write. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_fd_read()` - -Read from a file descriptor. - -Note: This is similar to `readv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors to which to store data. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_readdir()` - -Read directory entries from a directory. - -When successful, the contents of the output buffer consist of -a sequence of directory entries. Each directory entry consists -of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes -holding the name of the directory entry. - -This function fills the output buffer as much as possible, -potentially truncating the last directory entry. This allows -the caller to grow its read buffer size in case it's too small -to fit a single large directory entry, or skip the oversized -directory entry. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The directory from which to read the directory - entries. - -- void \*buf and size\_t buf\_len - - The buffer where directory entries are stored. - -- [\_\_wasi\_dircookie\_t](#dircookie) cookie - - The location within the directory to start - reading. - -Outputs: - -- size\_t bufused - - The number of bytes stored in the read buffer. - If less than the size of the read buffer, the - end of the directory has been reached. - -### `__wasi_fd_renumber()` - -Atomically replace a file descriptor by renumbering another -file descriptor. - -Due to the strong focus on thread safety, this environment -does not provide a mechanism to duplicate or renumber a file -descriptor to an arbitrary number, like dup2(). This would be -prone to race conditions, as an actual file descriptor with the -same number could be allocated by a different thread at the same -time. - -This function provides a way to atomically renumber file -descriptors, which would disappear if dup2() were to be -removed entirely. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) from - - The file descriptor to renumber. - -- [\_\_wasi\_fd\_t](#fd) to - - The file descriptor to overwrite. - -### `__wasi_fd_seek()` - -Move the offset of a file descriptor. - -Note: This is similar to `lseek` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_filedelta\_t](#filedelta) offset - - The number of bytes to move. - -- [\_\_wasi\_whence\_t](#whence) whence - - The base from which the offset is relative. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) newoffset - - The new offset of the file descriptor, - relative to the start of the file. - -### `__wasi_fd_sync()` - -Synchronize the data and metadata of a file to disk. - -Note: This is similar to `fsync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file containing the data - and metadata to synchronize to disk. - -### `__wasi_fd_tell()` - -Return the current offset of a file descriptor. - -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The current offset of the file descriptor, relative to the start of the file. - -### `__wasi_fd_write()` - -Write to a file descriptor. - -Note: This is similar to `writev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_path_create_directory()` - -Create a directory. - -Note: This is similar to `mkdirat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path at which to create the directory. - -### `__wasi_path_filestat_get()` - -Return the attributes of a file or directory. - -Note: This is similar to `stat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_path_filestat_set_times()` - -Adjust the timestamps of a file or directory. - -Note: This is similar to `utimensat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_path_link()` - -Create a hard link. - -Note: This is similar to `linkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags - - Flags determining the method of how the path is resolved. - -- const char \*old\_path and size\_t old\_path\_len - - The source path from which to link. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the hard link. - -### `__wasi_path_open()` - -Open a file or directory. - -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since -this is error-prone in multi-threaded contexts. The returned file -descriptor is guaranteed to be less than 231. - -Note: This is similar to `openat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) dirfd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The relative path of the file or directory to open, relative to - the [`dirfd`](#path_open.dirfd) directory. - -- [\_\_wasi\_oflags\_t](#oflags) o_flags - - The method by which to open the file. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The initial rights of the newly created file descriptor. The - implementation is allowed to return a file descriptor with fewer - rights than specified, if and only if those rights do not apply - to the type of file being opened. - - The *base* rights are rights that will apply to operations using - the file descriptor itself, while the *inheriting* rights are - rights that apply to file descriptors derived from it. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - The initial flags of the file descriptor. - -Outputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file that has been - opened. - -### `__wasi_path_readlink()` - -Read the contents of a symbolic link. - -Note: This is similar to `readlinkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path of the symbolic link from which to read. - -- char \*buf and size\_t buf\_len - - The buffer to which to write the contents of the symbolic link. - -Outputs: - -- size\_t bufused - - The number of bytes placed in the buffer. - -### `__wasi_path_remove_directory()` - -Remove a directory. - -Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. - -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a directory to remove. - -### `__wasi_path_rename()` - -Rename a file or directory. - -Note: This is similar to `renameat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- const char \*old\_path and size\_t old\_path\_len - - The source path of the file or directory to rename. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path to which to rename the file or directory. - -### `__wasi_path_symlink()` - -Create a symbolic link. - -Note: This is similar to `symlinkat` in POSIX. - -Inputs: - -- const char \*old\_path and size\_t old_path\_len - - The contents of the symbolic link. - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the symbolic link. - -### `__wasi_path_unlink_file()` - -Unlink a file. - -Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. - -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a file to unlink. - -### `__wasi_poll_oneoff()` - -Concurrently poll for the occurrence of a set of events. - -Inputs: - -- const [\_\_wasi\_subscription\_t](#subscription) \*in - - The events to which to subscribe. - -- [\_\_wasi\_event\_t](#event) \*out - - The events that have occurred. - -- size\_t nsubscriptions - - Both the number of subscriptions and events. - -Outputs: - -- size\_t nevents - - The number of events stored. - -### `__wasi_proc_exit()` - -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -Note: This is similar to `_Exit` in POSIX. - -Inputs: - -- [\_\_wasi\_exitcode\_t](#exitcode) rval - - The exit code returned by the process. - -Does not return. - -### `__wasi_random_get()` - -Write high-quality random data into a buffer. - -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. - -This function may execute slowly, so when large mounts of random -data are required, it's advisable to use this function to seed a -pseudo-random number generator, rather than to provide the -random data directly. - -Inputs: - -- void \*buf and size\_t buf\_len - - The buffer to fill with random data. - -### `__wasi_sched_yield()` - -Temporarily yield execution of the calling thread. - -Note: This is similar to `sched_yield` in POSIX. - -### `__wasi_sock_recv()` - -Receive a message from a socket. - -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to receive data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len - - List of scatter/gather vectors to which to store data. - -- [\_\_wasi\_riflags\_t](#riflags) ri\_flags - - Message flags. - -Outputs: - -- size\_t ro\_datalen - - Number of bytes stored in [`ri_data`](#sock_recv.ri_data). - -- [\_\_wasi\_roflags\_t](#roflags) ro\_flags - - Message flags. - -### `__wasi_sock_send()` - -Send a message on a socket. - -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to send data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len - - List of scatter/gather vectors to which to retrieve data - -- [\_\_wasi\_siflags\_t](#siflags) si\_flags - - Message flags. - -Outputs: - -- size\_t so\_datalen - - Number of bytes transmitted. - -### `__wasi_sock_shutdown()` - -Shut down socket send and receive channels. - -Note: This is similar to `shutdown` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to shutdown channels. - -- [\_\_wasi\_sdflags\_t](#sdflags) how - - Which channels on the socket to shut down. - -## Types - -### `__wasi_advice_t` (`uint8_t`) - -File or memory access pattern advisory information. - -Used by [`__wasi_fd_advise()`](#fd_advise). - -Possible values: - -- **`__WASI_ADVICE_NORMAL`** - - The application has no advice to give on its behavior - with respect to the specified data. - -- **`__WASI_ADVICE_SEQUENTIAL`** - - The application expects to access the specified data - sequentially from lower offsets to higher offsets. - -- **`__WASI_ADVICE_RANDOM`** - - The application expects to access the specified data - in a random order. - -- **`__WASI_ADVICE_WILLNEED`** - - The application expects to access the specified data - in the near future. - -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - -### `__wasi_ciovec_t` (`struct`) - -A region of memory for scatter/gather writes. - -Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). - -Members: - -- const void \*buf and size\_t buf\_len - - The address and length of the buffer to be written. - -### `__wasi_clockid_t` (`uint32_t`) - -Identifiers for clocks. - -Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). - -Possible values: - -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - -- **`__WASI_CLOCK_MONOTONIC`** - - The store-wide monotonic clock, which is defined as a - clock measuring real time, whose value cannot be - adjusted and which cannot have negative clock jumps. - - The epoch of this clock is undefined. The absolute - time value of this clock therefore has no meaning. - -- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** - - The CPU-time clock associated with the current - process. - -- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** - - The CPU-time clock associated with the current thread. - -### `__wasi_device_t` (`uint64_t`) - -Identifier for a device containing a file system. Can be used -in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or -directory in the filesystem. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_dircookie_t` (`uint64_t`) - -A reference to the offset of a directory entry. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). - -Special values: - -- **`__WASI_DIRCOOKIE_START`** - - Permanent reference to the first directory entry - within a directory. - -### `__wasi_dirent_t` (`struct`) - -A directory entry. - -Members: - -- [\_\_wasi\_dircookie\_t](#dircookie) d\_next - - The offset of the next directory entry stored in this - directory. - -- [\_\_wasi\_inode\_t](#inode) d\_ino - - The serial number of the file referred to by this - directory entry. - -- uint32\_t d\_namlen - - The length of the name of the directory entry. - -- [\_\_wasi\_filetype\_t](#filetype) d\_type - - The type of the file referred to by this directory - entry. - -### `__wasi_errno_t` (`uint16_t`) - -Error codes returned by functions. - -Not all of these error codes are returned by the functions -provided by this API; some are used in higher-level library layers, -and others are provided merely for alignment with POSIX. - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_ESUCCESS`** - - No error occurred. System call completed successfully. - -- **`__WASI_E2BIG`** - - Argument list too long. - -- **`__WASI_EACCES`** - - Permission denied. - -- **`__WASI_EADDRINUSE`** - - Address in use. - -- **`__WASI_EADDRNOTAVAIL`** - - Address not available. - -- **`__WASI_EAFNOSUPPORT`** - - Address family not supported. - -- **`__WASI_EAGAIN`** - - Resource unavailable, or operation would block. - -- **`__WASI_EALREADY`** - - Connection already in progress. - -- **`__WASI_EBADF`** - - Bad file descriptor. - -- **`__WASI_EBADMSG`** - - Bad message. - -- **`__WASI_EBUSY`** - - Device or resource busy. - -- **`__WASI_ECANCELED`** - - Operation canceled. - -- **`__WASI_ECHILD`** - - No child processes. - -- **`__WASI_ECONNABORTED`** - - Connection aborted. - -- **`__WASI_ECONNREFUSED`** - - Connection refused. - -- **`__WASI_ECONNRESET`** - - Connection reset. - -- **`__WASI_EDEADLK`** - - Resource deadlock would occur. - -- **`__WASI_EDESTADDRREQ`** - - Destination address required. - -- **`__WASI_EDOM`** - - Mathematics argument out of domain of function. - -- **`__WASI_EDQUOT`** - - Reserved. - -- **`__WASI_EEXIST`** - - File exists. - -- **`__WASI_EFAULT`** - - Bad address. - -- **`__WASI_EFBIG`** - - File too large. - -- **`__WASI_EHOSTUNREACH`** - - Host is unreachable. - -- **`__WASI_EIDRM`** - - Identifier removed. - -- **`__WASI_EILSEQ`** - - Illegal byte sequence. - -- **`__WASI_EINPROGRESS`** - - Operation in progress. - -- **`__WASI_EINTR`** - - Interrupted function. - -- **`__WASI_EINVAL`** - - Invalid argument. - -- **`__WASI_EIO`** - - I/O error. - -- **`__WASI_EISCONN`** - - Socket is connected. - -- **`__WASI_EISDIR`** - - Is a directory. - -- **`__WASI_ELOOP`** - - Too many levels of symbolic links. - -- **`__WASI_EMFILE`** - - File descriptor value too large. - -- **`__WASI_EMLINK`** - - Too many links. - -- **`__WASI_EMSGSIZE`** - - Message too large. - -- **`__WASI_EMULTIHOP`** - - Reserved. - -- **`__WASI_ENAMETOOLONG`** - - Filename too long. - -- **`__WASI_ENETDOWN`** - - Network is down. - -- **`__WASI_ENETRESET`** - - Connection aborted by network. - -- **`__WASI_ENETUNREACH`** - - Network unreachable. - -- **`__WASI_ENFILE`** - - Too many files open in system. - -- **`__WASI_ENOBUFS`** - - No buffer space available. - -- **`__WASI_ENODEV`** - - No such device. - -- **`__WASI_ENOENT`** - - No such file or directory. - -- **`__WASI_ENOEXEC`** - - Executable file format error. - -- **`__WASI_ENOLCK`** - - No locks available. - -- **`__WASI_ENOLINK`** - - Reserved. - -- **`__WASI_ENOMEM`** - - Not enough space. - -- **`__WASI_ENOMSG`** - - No message of the desired type. - -- **`__WASI_ENOPROTOOPT`** - - Protocol not available. - -- **`__WASI_ENOSPC`** - - No space left on device. - -- **`__WASI_ENOSYS`** - - Function not supported. - -- **`__WASI_ENOTCONN`** - - The socket is not connected. - -- **`__WASI_ENOTDIR`** - - Not a directory or a symbolic link to a directory. - -- **`__WASI_ENOTEMPTY`** - - Directory not empty. - -- **`__WASI_ENOTRECOVERABLE`** - - State not recoverable. - -- **`__WASI_ENOTSOCK`** - - Not a socket. - -- **`__WASI_ENOTSUP`** - - Not supported, or operation not supported on socket. - -- **`__WASI_ENOTTY`** - - Inappropriate I/O control operation. - -- **`__WASI_ENXIO`** - - No such device or address. - -- **`__WASI_EOVERFLOW`** - - Value too large to be stored in data type. - -- **`__WASI_EOWNERDEAD`** - - Previous owner died. - -- **`__WASI_EPERM`** - - Operation not permitted. - -- **`__WASI_EPIPE`** - - Broken pipe. - -- **`__WASI_EPROTO`** - - Protocol error. - -- **`__WASI_EPROTONOSUPPORT`** - - Protocol not supported. - -- **`__WASI_EPROTOTYPE`** - - Protocol wrong type for socket. - -- **`__WASI_ERANGE`** - - Result too large. - -- **`__WASI_EROFS`** - - Read-only file system. - -- **`__WASI_ESPIPE`** - - Invalid seek. - -- **`__WASI_ESRCH`** - - No such process. - -- **`__WASI_ESTALE`** - - Reserved. - -- **`__WASI_ETIMEDOUT`** - - Connection timed out. - -- **`__WASI_ETXTBSY`** - - Text file busy. - -- **`__WASI_EXDEV`** - - Cross-device link. - -- **`__WASI_ENOTCAPABLE`** - - Extension: Capabilities insufficient. - -### `__wasi_event_t` (`struct`) - -An event that occurred. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that got attached to - [`__wasi_subscription_t::userdata`](#subscription.userdata). - -- [\_\_wasi\_errno\_t](#errno) error - - If non-zero, an error that occurred while processing - the subscription request. - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event that occurred. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_filesize\_t](#filesize) nbytes - - The number of bytes available for reading or writing. - - - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags - - The state of the file descriptor. - -### `__wasi_eventrwflags_t` (`uint16_t` bitfield) - -The state of the file descriptor subscribed to with -[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_EVENT_FD_READWRITE_HANGUP`** - - The peer of this socket has closed or disconnected. - -### `__wasi_eventtype_t` (`uint8_t`) - -Type of a subscription to an event or its occurrence. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_EVENTTYPE_CLOCK`** - - The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) - has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -- **`__WASI_EVENTTYPE_FD_READ`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - data available for reading. This event always triggers - for regular files. - -- **`__WASI_EVENTTYPE_FD_WRITE`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - capacity available for writing. This event always - triggers for regular files. - -### `__wasi_exitcode_t` (`uint32_t`) - -Exit code generated by a process when exiting. - -Used by [`__wasi_proc_exit()`](#proc_exit). - -### `__wasi_fd_t` (`uint32_t`) - -A file descriptor number. - -Used by many functions in this API. - -As in POSIX, three file descriptor numbers are provided to instances -on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, -and `STDERR_FILENO`). - -Other than these, WASI implementations are not required to allocate -new file descriptors in ascending order. - -### `__wasi_fdflags_t` (`uint16_t` bitfield) - -File descriptor flags. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_FDFLAG_APPEND`** - - Append mode: Data written to the file is always - appended to the file's end. - -- **`__WASI_FDFLAG_DSYNC`** - - Write according to synchronized I/O data integrity - completion. Only the data stored in the file is - synchronized. - -- **`__WASI_FDFLAG_NONBLOCK`** - - Non-blocking mode. - -- **`__WASI_FDFLAG_RSYNC`** - - Synchronized read I/O operations. - -- **`__WASI_FDFLAG_SYNC`** - - Write according to synchronized I/O file integrity completion. - In addition to synchronizing the data stored in the file, the - implementation may also synchronously update the file's metadata. - -### `__wasi_fdstat_t` (`struct`) - -File descriptor attributes. - -Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). - -Members: - -- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype - - File type. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - File descriptor flags. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base - - Rights that apply to this file descriptor. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - Maximum set of rights that may be installed on new - file descriptors that are created through this file - descriptor, e.g., through [`__wasi_path_open()`](#path_open). - -### `__wasi_filedelta_t` (`int64_t`) - -Relative offset within a file. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -### `__wasi_filesize_t` (`uint64_t`) - -Non-negative file size or length of a region within a file. - -Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -### `__wasi_filestat_t` (`struct`) - -File attributes. - -Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). - -Members: - -- [\_\_wasi\_device\_t](#device) st\_dev - - Device ID of device containing the file. - -- [\_\_wasi\_inode\_t](#inode) st\_ino - - File serial number. - -- [\_\_wasi\_filetype\_t](#filetype) st\_filetype - - File type. - -- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink - - Number of hard links to the file. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - For regular files, the file size in bytes. For - symbolic links, the length in bytes of the pathname - contained in the symbolic link. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - Last data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - Last data modification timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim - - Last file status change timestamp. - -### `__wasi_filetype_t` (`uint8_t`) - -The type of a file descriptor or file. - -Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). - -Possible values: - -- **`__WASI_FILETYPE_UNKNOWN`** - - The type of the file descriptor or file is unknown or - is different from any of the other types specified. - -- **`__WASI_FILETYPE_BLOCK_DEVICE`** - - The file descriptor or file refers to a block device - inode. - -- **`__WASI_FILETYPE_CHARACTER_DEVICE`** - - The file descriptor or file refers to a character - device inode. - -- **`__WASI_FILETYPE_DIRECTORY`** - - The file descriptor or file refers to a directory - inode. - -- **`__WASI_FILETYPE_REGULAR_FILE`** - - The file descriptor or file refers to a regular file - inode. - -- **`__WASI_FILETYPE_SOCKET_DGRAM`** - - The file descriptor or file refers to a datagram - socket. - -- **`__WASI_FILETYPE_SOCKET_STREAM`** - - The file descriptor or file refers to a byte-stream - socket. - -- **`__WASI_FILETYPE_SYMBOLIC_LINK`** - - The file refers to a symbolic link inode. - -### `__wasi_fstflags_t` (`uint16_t` bitfield) - -Which file time attributes to adjust. - -Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -Possible values: - -- **`__WASI_FILESTAT_SET_ATIM`** - - Adjust the last data access timestamp to the value - stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). - -- **`__WASI_FILESTAT_SET_ATIM_NOW`** - - Adjust the last data access timestamp to the time - of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -- **`__WASI_FILESTAT_SET_MTIM`** - - Adjust the last data modification timestamp to the - value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). - -- **`__WASI_FILESTAT_SET_MTIM_NOW`** - - Adjust the last data modification timestamp to the - time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -### `__wasi_inode_t` (`uint64_t`) - -File serial number that is unique within its file system. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). - -### `__wasi_iovec_t` (`struct`) - -A region of memory for scatter/gather reads. - -Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). - -Members: - -- void \*buf and size\_t buf\_len - - The address and length of the buffer to be filled. - -### `__wasi_linkcount_t` (`uint64_t`) - -Number of hard links to an inode. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_lookupflags_t` (`uint32_t` bitfield) - -Flags determining the method of how paths are resolved. - -Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** - - As long as the resolved path corresponds to a symbolic - link, it is expanded. - -### `__wasi_oflags_t` (`uint16_t` bitfield) - -Open flags used by [`__wasi_path_open()`](#path_open). - -Used by [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_O_CREAT`** - - Create file if it does not exist. - -- **`__WASI_O_DIRECTORY`** - - Fail if not a directory. - -- **`__WASI_O_EXCL`** - - Fail if file already exists. - -- **`__WASI_O_TRUNC`** - - Truncate file to size 0. - -### `__wasi_riflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_PEEK`** - - Returns the message without removing it from the - socket's receive queue. - -- **`__WASI_SOCK_RECV_WAITALL`** - - On byte-stream sockets, block until the full amount - of data can be returned. - -### `__wasi_rights_t` (`uint64_t` bitfield) - -File descriptor rights, determining which actions may be -performed. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_RIGHT_FD_DATASYNC`** - - The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_READ`** - - The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke - [`__wasi_fd_pread()`](#fd_pread). - -- **`__WASI_RIGHT_FD_SEEK`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies - [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). - -- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** - - The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). - -- **`__WASI_RIGHT_FD_SYNC`** - - The right to invoke [`__wasi_fd_sync()`](#fd_sync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and - [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_TELL`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the - file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with - offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). - -- **`__WASI_RIGHT_FD_WRITE`** - - The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to - invoke [`__wasi_fd_pwrite()`](#fd_pwrite). - -- **`__WASI_RIGHT_FD_ADVISE`** - - The right to invoke [`__wasi_fd_advise()`](#fd_advise). - -- **`__WASI_RIGHT_FD_ALLOCATE`** - - The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). - -- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** - - The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). - -- **`__WASI_RIGHT_PATH_CREATE_FILE`** - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke - [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). - -- **`__WASI_RIGHT_PATH_LINK_SOURCE`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_LINK_TARGET`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_OPEN`** - - The right to invoke [`__wasi_path_open()`](#path_open). - -- **`__WASI_RIGHT_FD_READDIR`** - - The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). - -- **`__WASI_RIGHT_PATH_READLINK`** - - The right to invoke [`__wasi_path_readlink()`](#path_readlink). - -- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_RENAME_TARGET`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_FILESTAT_GET`** - - The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** - - The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -- **`__WASI_RIGHT_FD_FILESTAT_GET`** - - The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** - - The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). - -- **`__WASI_RIGHT_PATH_SYMLINK`** - - The right to invoke [`__wasi_path_symlink()`](#path_symlink). - -- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** - - The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). - -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - -- **`__WASI_RIGHT_POLL_FD_READWRITE`** - - If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). - - If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -- **`__WASI_RIGHT_SOCK_SHUTDOWN`** - - The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). - -### `__wasi_roflags_t` (`uint16_t` bitfield) - -Flags returned by [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** - - Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been - truncated. - -### `__wasi_sdflags_t` (`uint8_t` bitfield) - -Which channels on a socket to shut down. - -Used by [`__wasi_sock_shutdown()`](#sock_shutdown). - -Possible values: - -- **`__WASI_SHUT_RD`** - - Disables further receive operations. - -- **`__WASI_SHUT_WR`** - - Disables further send operations. - -### `__wasi_siflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Used by [`__wasi_sock_send()`](#sock_send). - -### `__wasi_subclockflags_t` (`uint16_t` bitfield) - -Flags determining how to interpret the timestamp provided in -[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -Used by [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** - - If set, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp - of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - - If clear, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current - time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - -### `__wasi_subscription_t` (`struct`) - -Subscription to an event. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that is attached to the subscription in the - implementation and returned through - [`__wasi_event_t::userdata`](#event.userdata). - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event to which to subscribe. - -- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): - - - **`u.clock`** - - - [\_\_wasi\_userdata\_t](#userdata) identifier - - The user-defined unique identifier of the clock. - - - [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock against which to compare the timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) timeout - - The absolute or relative timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) precision - - The amount of time that the implementation may wait additionally - to coalesce with other events. - - - [\_\_wasi\_subclockflags\_t](#subclockflags) flags - - Flags specifying whether the timeout is absolute or relative. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor on which to wait for it to become ready - for reading or writing. - -### `__wasi_timestamp_t` (`uint64_t`) - -Timestamp in nanoseconds. - -Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -### `__wasi_userdata_t` (`uint64_t`) - -User-provided value that may be attached to objects that is -retained when extracted from the implementation. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -### `__wasi_whence_t` (`uint8_t`) - -The position relative to which to set the offset of the file descriptor. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -Possible values: - -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - -- **`__WASI_WHENCE_CUR`** - - Seek relative to current position. - -- **`__WASI_WHENCE_END`** - - Seek relative to end-of-file. - diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx new file mode 100644 index 000000000..2c2d32d67 --- /dev/null +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -0,0 +1,28 @@ +;; WASI Command-line Arguments. +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_args + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Read command-line argument data. + ;;; The size of the array should match that returned by `sizes_get` + (@interface func (export "get") + (param $argv (@witx pointer (@witx pointer u8))) + (param $argv_buf (@witx pointer u8)) + (result $error $errno) + ) + + ;;; Return command-line argument data sizes. + (@interface func (export "sizes_get") + (result $error $errno) + ;;; The number of arguments. + (result $argc $size) + ;;; The size of the argument string data. + (result $argv_buf_size $size) + ) +) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx new file mode 100644 index 000000000..b6d880443 --- /dev/null +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx @@ -0,0 +1,36 @@ +;; WASI Clocks. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_clock + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Return the resolution of a clock. + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Note: This is similar to `clock_getres` in POSIX. + (@interface func (export "res_get") + (result $error $errno) + ;;; The clock for which to return the resolution. + (param $id $clockid) + ;;; The resolution of the clock. + (result $resolution $timestamp) + ) + + ;;; Return the time value of a clock. + ;;; Note: This is similar to `clock_gettime` in POSIX. + (@interface func (export "time_get") + ;;; The clock for which to return the time. + (param $id $clockid) + ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp) + (result $error $errno) + ;;; The time value of the clock. + (result $time $timestamp) + ) +) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx new file mode 100644 index 000000000..5bc9c5a6f --- /dev/null +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -0,0 +1,28 @@ +;; WASI Environment Variables. +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_environ + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Read environment variable data. + ;;; The sizes of the buffers should match that returned by `sizes_get`. + (@interface func (export "get") + (param $environ (@witx pointer (@witx pointer u8))) + (param $environ_buf (@witx pointer u8)) + (result $error $errno) + ) + + ;;; Return command-line argument data sizes. + (@interface func (export "sizes_get") + (result $error $errno) + ;;; The number of arguments. + (result $argc $size) + ;;; The size of the argument string data. + (result $argv_buf_size $size) + ) +) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx new file mode 100644 index 000000000..9fbad9ab7 --- /dev/null +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -0,0 +1,242 @@ +;; WASI I/O. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_fd + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Provide file advisory information on a file descriptor. + ;;; Note: This is similar to `posix_fadvise` in POSIX. + (@interface func (export "advise") + (param $fd $fd) + ;;; The offset within the file to which the advisory applies. + (param $offset $filesize) + ;;; The length of the region to which the advisory applies. + (param $len $filesize) + ;;; The advice. + (param $advice $advice) + (result $error $errno) + ) + + ;;; Force the allocation of space in a file. + ;;; Note: This is similar to `posix_fallocate` in POSIX. + (@interface func (export "allocate") + (param $fd $fd) + ;;; The offset at which to start the allocation. + (param $offset $filesize) + ;;; The length of the area that is allocated. + (param $len $filesize) + (result $error $errno) + ) + + ;;; Close a file descriptor. + ;;; Note: This is similar to `close` in POSIX. + (@interface func (export "close") + (param $fd $fd) + (result $error $errno) + ) + + ;;; Synchronize the data of a file to disk. + ;;; Note: This is similar to `fdatasync` in POSIX. + (@interface func (export "datasync") + (param $fd $fd) + (result $error $errno) + ) + + ;;; Get the attributes of a file descriptor. + ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (@interface func (export "fdstat_get") + (param $fd $fd) + (result $error $errno) + ;;; The buffer where the file descriptor's attributes are stored. + (result $stat $fdstat) + ) + + ;;; Adjust the flags associated with a file descriptor. + ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (@interface func (export "fdstat_set_flags") + (param $fd $fd) + ;;; The desired values of the file descriptor flags. + (param $flags $fdflags) + (result $error $errno) + ) + + ;;; Adjust the rights associated with a file descriptor. + ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (@interface func (export "fdstat_set_rights") + (param $fd $fd) + ;;; The desired rights of the file descriptor. + (param $fs_rights_base $rights) + (param $fs_rights_inheriting $rights) + (result $error $errno) + ) + + ;;; Return the attributes of an open file. + (@interface func (export "filestat_get") + (param $fd $fd) + (result $error $errno) + ;;; The buffer where the file's attributes are stored. + (result $buf $filestat) + ) + + ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;;; Note: This is similar to `ftruncate` in POSIX. + (@interface func (export "filestat_set_size") + (param $fd $fd) + ;;; The desired file size. + (param $size $filesize) + (result $error $errno) + ) + + ;;; Adjust the timestamps of an open file or directory. + ;;; Note: This is similar to `futimens` in POSIX. + (@interface func (export "filestat_set_times") + (param $fd $fd) + ;;; The desired values of the data access timestamp. + (param $atim $timestamp) + ;;; The desired values of the data modification timestamp. + (param $mtim $timestamp) + ;;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags) + (result $error $errno) + ) + + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `preadv` in POSIX. + (@interface func (export "pread") + (param $fd $fd) + ;;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_array) + ;;; The offset within the file at which to read. + (param $offset $filesize) + (result $error $errno) + ;;; The number of bytes read. + (result $nread $size) + ) + + ;;; Return a description of the given preopened file descriptor. + (@interface func (export "prestat_get") + (param $fd $fd) + (result $error $errno) + ;;; The buffer where the description is stored. + (result $buf $prestat) + ) + + ;;; Return a description of the given preopened file descriptor. + (@interface func (export "prestat_dir_name") + (param $fd $fd) + ;;; A buffer into which to write the preopened directory name. + (param $path (@witx pointer u8)) + (param $path_len $size) + (result $error $errno) + ) + + ;;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `pwritev` in POSIX. + (@interface func (export "pwrite") + (param $fd $fd) + ;;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_array) + ;;; The offset within the file at which to write. + (param $offset $filesize) + (result $error $errno) + ;;; The number of bytes written. + (result $nwritten $size) + ) + + ;;; Read from a file descriptor. + ;;; Note: This is similar to `readv` in POSIX. + (@interface func (export "read") + (param $fd $fd) + ;;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_array) + (result $error $errno) + ;;; The number of bytes read. + (result $nread $size) + ) + + ;;; Read directory entries from a directory. + ;;; When successful, the contents of the output buffer consist of a sequence of + ;;; directory entries. Each directory entry consists of a dirent_t object, + ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; entry. + ;; + ;;; This function fills the output buffer as much as possible, potentially + ;;; truncating the last directory entry. This allows the caller to grow its + ;;; read buffer size in case it's too small to fit a single large directory + ;;; entry, or skip the oversized directory entry. + (@interface func (export "readdir") + (param $fd $fd) + ;;; The buffer where directory entries are stored + (param $buf (@witx pointer u8)) + (param $buf_len $size) + ;;; The location within the directory to start reading + (param $cookie $dircookie) + (result $error $errno) + ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size) + ) + + ;;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; + ;;; Due to the strong focus on thread safety, this environment does not provide + ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;;; file descriptor with the same number could be allocated by a different + ;;; thread at the same time. + ;; + ;;; This function provides a way to atomically renumber file descriptors, which + ;;; would disappear if `dup2()` were to be removed entirely. + (@interface func (export "renumber") + (param $fd $fd) + ;;; The file descriptor to overwrite. + (param $to $fd) + (result $error $errno) + ) + + ;;; Move the offset of a file descriptor. + ;;; Note: This is similar to `lseek` in POSIX. + (@interface func (export "seek") + (param $fd $fd) + ;;; The number of bytes to move. + (param $offset $filedelta) + ;;; The base from which the offset is relative. + (param $whence $whence) + (result $error $errno) + ;;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize) + ) + + ;;; Synchronize the data and metadata of a file to disk. + ;;; Note: This is similar to `fsync` in POSIX. + (@interface func (export "sync") + (param $fd $fd) + (result $error $errno) + ) + + ;;; Return the current offset of a file descriptor. + ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (@interface func (export "tell") + (param $fd $fd) + (result $error $errno) + ;;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize) + ) + + ;;; Write to a file descriptor. + ;;; Note: This is similar to `writev` in POSIX. + (@interface func (export "write") + (param $fd $fd) + ;;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_array) + (result $error $errno) + ;;; The number of bytes written. + (result $nwritten $size) + ) +) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx new file mode 100644 index 000000000..16c974692 --- /dev/null +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -0,0 +1,160 @@ +;; WASI Filesystem Path API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_path + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Create a directory. + ;;; Note: This is similar to `mkdirat` in POSIX. + (@interface func (export "create_directory") + (param $fd $fd) + ;;; The path at which to create the directory. + (param $path string) + (result $error $errno) + ) + + ;;; Return the attributes of a file or directory. + ;;; Note: This is similar to `stat` in POSIX. + (@interface func (export "filestat_get") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags) + ;;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno) + ;;; The buffer where the file's attributes are stored. + (result $buf $filestat) + ) + + ;;; Adjust the timestamps of a file or directory. + ;;; Note: This is similar to `utimensat` in POSIX. + (@interface func (export "filestat_set_times") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags) + ;;; The path of the file or directory to operate on. + (param $path string) + ;;; The desired values of the data access timestamp. + (param $atim $timestamp) + ;;; The desired values of the data modification timestamp. + (param $mtim $timestamp) + ;;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags) + (result $error $errno) + ) + + ;;; Create a hard link. + ;;; Note: This is similar to `linkat` in POSIX. + (@interface func (export "link") + (param $old_fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags) + ;;; The source path from which to link. + (param $old_path string) + ;;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd) + ;;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno) + ) + + ;;; Open a file or directory. + ;; + ;;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;;; file descriptor not currently open; it is randomized to prevent + ;;; applications from depending on making assumptions about indexes, since this + ;;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;;; guaranteed to be less than 2**31. + ;; + ;;; Note: This is similar to `openat` in POSIX. + (@interface func (export "open") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags) + ;;; The relative path of the file or directory to open, relative to the + ;;; `dirfd` directory. + (param $path string) + ;;; The method by which to open the file. + (param $oflags $oflags) + ;;; The initial rights of the newly created file descriptor. The + ;;; implementation is allowed to return a file descriptor with fewer rights + ;;; than specified, if and only if those rights do not apply to the type of + ;;; file being opened. + ;; + ;;; The *base* rights are rights that will apply to operations using the file + ;;; descriptor itself, while the *inheriting* rights are rights that apply to + ;;; file descriptors derived from it. + (param $fs_rights_base $rights) + (param $fs_rights_inherting $rights) + (param $fdflags $fdflags) + (result $error $errno) + ;;; The file descriptor of the file that has been opened. + (result $opened_fd $fd) + ) + + ;;; Read the contents of a symbolic link. + ;;; Note: This is similar to `readlinkat` in POSIX. + (@interface func (export "readlink") + (param $fd $fd) + ;;; The path of the symbolic link from which to read. + (param $path string) + ;;; The buffer to which to write the contents of the symbolic link. + (param $buf (@witx pointer u8)) + (param $buf_len $size) + (result $error $errno) + ;;; The number of bytes placed in the buffer. + (result $bufused $size) + ) + + ;;; Remove a directory. + ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (@interface func (export "remove_directory") + (param $fd $fd) + ;;; The path to a directory to remove. + (param $path string) + (result $error $errno) + ) + + ;;; Rename a file or directory. + ;;; Note: This is similar to `renameat` in POSIX. + (@interface func (export "rename") + (param $fd $fd) + ;;; The source path of the file or directory to rename. + (param $old_path string) + ;;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd) + ;;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno) + ) + + ;;; Create a symbolic link. + ;;; Note: This is similar to `symlinkat` in POSIX. + (@interface func (export "symlink") + ;;; The contents of the symbolic link. + (param $old_path string) + (param $fd $fd) + ;;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno) + ) + + + ;;; Unlink a file. + ;;; Return `EISDIR` if the path refers to a directory. + ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (@interface func (export "unlink_file") + (param $fd $fd) + ;;; The path to a file to unlink. + (param $path string) + (result $error $errno) + ) +) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx new file mode 100644 index 000000000..7dcdb53e6 --- /dev/null +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx @@ -0,0 +1,26 @@ +;; WASI Poll API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_poll + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Concurrently poll for the occurrence of a set of events. + (@interface func (export "oneoff") + ;;; The events to which to subscribe. + (param $in (@witx const_pointer $subscription)) + ;;; The events that have occurred. + (param $out (@witx pointer $event)) + ;;; Both the number of subscriptions and events. + (param $nsubscriptions $size) + (result $error $errno) + ;;; The number of events stored. + (result $nevents $size) + ) +) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx deleted file mode 100644 index 50bf519e7..000000000 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ /dev/null @@ -1,523 +0,0 @@ -;; WASI Preview. This is an evolution of the API that WASI initially -;; launched with. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_preview - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `wasi_args_sizes_get()` - (@interface func (export "args_get") - (param $argv (@witx pointer (@witx pointer u8))) - (param $argv_buf (@witx pointer u8)) - (result $error $errno) - ) - ;;; Return command-line argument data sizes. - (@interface func (export "args_sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) - ) - - ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. - (@interface func (export "environ_get") - (param $environ (@witx pointer (@witx pointer u8))) - (param $environ_buf (@witx pointer u8)) - (result $error $errno) - ) - ;;; Return command-line argument data sizes. - (@interface func (export "environ_sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) - ) - - ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;;; Note: This is similar to `clock_getres` in POSIX. - (@interface func (export "clock_res_get") - (result $error $errno) - ;;; The clock for which to return the resolution. - (param $id $clockid) - ;;; The resolution of the clock. - (result $resolution $timestamp) - ) - ;;; Return the time value of a clock. - ;;; Note: This is similar to `clock_gettime` in POSIX. - (@interface func (export "clock_time_get") - ;;; The clock for which to return the time. - (param $id $clockid) - ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp) - (result $error $errno) - ;;; The time value of the clock. - (result $time $timestamp) - ) - - ;;; Provide file advisory information on a file descriptor. - ;;; Note: This is similar to `posix_fadvise` in POSIX. - (@interface func (export "fd_advise") - (param $fd $fd) - ;;; The offset within the file to which the advisory applies. - (param $offset $filesize) - ;;; The length of the region to which the advisory applies. - (param $len $filesize) - ;;; The advice. - (param $advice $advice) - (result $error $errno) - ) - - ;;; Force the allocation of space in a file. - ;;; Note: This is similar to `posix_fallocate` in POSIX. - (@interface func (export "fd_allocate") - (param $fd $fd) - ;;; The offset at which to start the allocation. - (param $offset $filesize) - ;;; The length of the area that is allocated. - (param $len $filesize) - (result $error $errno) - ) - - ;;; Close a file descriptor. - ;;; Note: This is similar to `close` in POSIX. - (@interface func (export "fd_close") - (param $fd $fd) - (result $error $errno) - ) - - ;;; Synchronize the data of a file to disk. - ;;; Note: This is similar to `fdatasync` in POSIX. - (@interface func (export "fd_datasync") - (param $fd $fd) - (result $error $errno) - ) - - ;;; Get the attributes of a file descriptor. - ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (@interface func (export "fd_fdstat_get") - (param $fd $fd) - (result $error $errno) - ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat) - ) - - ;;; Adjust the flags associated with a file descriptor. - ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd) - ;;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error $errno) - ) - - ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights - (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd) - ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (result $error $errno) - ) - - ;;; Return the attributes of an open file. - (@interface func (export "fd_filestat_get") - (param $fd $fd) - (result $error $errno) - ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) - ) - - ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;;; Note: This is similar to `ftruncate` in POSIX. - (@interface func (export "fd_filestat_set_size") - (param $fd $fd) - ;;; The desired file size. - (param $size $filesize) - (result $error $errno) - ) - - ;;; Adjust the timestamps of an open file or directory. - ;;; Note: This is similar to `futimens` in POSIX. - (@interface func (export "fd_filestat_set_times") - (param $fd $fd) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error $errno) - ) - - ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in POSIX. - (@interface func (export "fd_pread") - (param $fd $fd) - ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_array) - ;;; The offset within the file at which to read. - (param $offset $filesize) - (result $error $errno) - ;;; The number of bytes read. - (result $nread $size) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_get") - (param $fd $fd) - (result $error $errno) - ;;; The buffer where the description is stored. - (result $buf $prestat) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_dir_name") - (param $fd $fd) - ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer u8)) - (param $path_len $size) - (result $error $errno) - ) - - ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in POSIX. - (@interface func (export "fd_pwrite") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The offset within the file at which to write. - (param $offset $filesize) - (result $error $errno) - ;;; The number of bytes written. - (result $nwritten $size) - ) - - ;;; Read from a file descriptor. - ;;; Note: This is similar to `readv` in POSIX. - (@interface func (export "fd_read") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_array) - (result $error $errno) - ;;; The number of bytes read. - (result $nread $size) - ) - - ;;; Read directory entries from a directory. - ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a dirent_t object, - ;;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;;; entry. - ;; - ;;; This function fills the output buffer as much as possible, potentially - ;;; truncating the last directory entry. This allows the caller to grow its - ;;; read buffer size in case it's too small to fit a single large directory - ;;; entry, or skip the oversized directory entry. - (@interface func (export "fd_readdir") - (param $fd $fd) - ;;; The buffer where directory entries are stored - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The location within the directory to start reading - (param $cookie $dircookie) - (result $error $errno) - ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size) - ) - - ;;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;;; Due to the strong focus on thread safety, this environment does not provide - ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;;; file descriptor with the same number could be allocated by a different - ;;; thread at the same time. - ;; - ;;; This function provides a way to atomically renumber file descriptors, which - ;;; would disappear if `dup2()` were to be removed entirely. - (@interface func (export "fd_renumber") - (param $fd $fd) - ;;; The file descriptor to overwrite. - (param $to $fd) - (result $error $errno) - ) - - ;;; Move the offset of a file descriptor. - ;;; Note: This is similar to `lseek` in POSIX. - (@interface func (export "fd_seek") - (param $fd $fd) - ;;; The number of bytes to move. - (param $offset $filedelta) - ;;; The base from which the offset is relative. - (param $whence $whence) - (result $error $errno) - ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize) - ) - - ;;; Synchronize the data and metadata of a file to disk. - ;;; Note: This is similar to `fsync` in POSIX. - (@interface func (export "fd_sync") - (param $fd $fd) - (result $error $errno) - ) - - ;;; Return the current offset of a file descriptor. - ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (@interface func (export "fd_tell") - (param $fd $fd) - (result $error $errno) - ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize) - ) - - ;;; Write to a file descriptor. - ;;; Note: This is similar to `writev` in POSIX. - (@interface func (export "fd_write") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - (result $error $errno) - ;;; The number of bytes written. - (result $nwritten $size) - ) - - ;;; Create a directory. - ;;; Note: This is similar to `mkdirat` in POSIX. - (@interface func (export "path_create_directory") - (param $fd $fd) - ;;; The path at which to create the directory. - (param $path string) - (result $error $errno) - ) - - ;;; Return the attributes of a file or directory. - ;;; Note: This is similar to `stat` in POSIX. - (@interface func (export "path_filestat_get") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to inspect. - (param $path string) - (result $error $errno) - ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) - ) - - ;;; Adjust the timestamps of a file or directory. - ;;; Note: This is similar to `utimensat` in POSIX. - (@interface func (export "path_filestat_set_times") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to operate on. - (param $path string) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error $errno) - ) - - ;;; Create a hard link. - ;;; Note: This is similar to `linkat` in POSIX. - (@interface func (export "path_link") - (param $old_fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags) - ;;; The source path from which to link. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path at which to create the hard link. - (param $new_path string) - (result $error $errno) - ) - - ;;; Open a file or directory. - ;; - ;;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;;; file descriptor not currently open; it is randomized to prevent - ;;; applications from depending on making assumptions about indexes, since this - ;;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;;; guaranteed to be less than 2**31. - ;; - ;;; Note: This is similar to `openat` in POSIX. - (@interface func (export "path_open") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags) - ;;; The relative path of the file or directory to open, relative to the - ;;; `dirfd` directory. - (param $path string) - ;;; The method by which to open the file. - (param $oflags $oflags) - ;;; The initial rights of the newly created file descriptor. The - ;;; implementation is allowed to return a file descriptor with fewer rights - ;;; than specified, if and only if those rights do not apply to the type of - ;;; file being opened. - ;; - ;;; The *base* rights are rights that will apply to operations using the file - ;;; descriptor itself, while the *inheriting* rights are rights that apply to - ;;; file descriptors derived from it. - (param $fs_rights_base $rights) - (param $fs_rights_inherting $rights) - (param $fdflags $fdflags) - (result $error $errno) - ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd) - ) - - ;;; Read the contents of a symbolic link. - ;;; Note: This is similar to `readlinkat` in POSIX. - (@interface func (export "path_readlink") - (param $fd $fd) - ;;; The path of the symbolic link from which to read. - (param $path string) - ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error $errno) - ;;; The number of bytes placed in the buffer. - (result $bufused $size) - ) - - ;;; Remove a directory. - ;;; Return `ENOTEMPTY` if the directory is not empty. - ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (@interface func (export "path_remove_directory") - (param $fd $fd) - ;;; The path to a directory to remove. - (param $path string) - (result $error $errno) - ) - - ;;; Rename a file or directory. - ;;; Note: This is similar to `renameat` in POSIX. - (@interface func (export "path_rename") - (param $fd $fd) - ;;; The source path of the file or directory to rename. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error $errno) - ) - - ;;; Create a symbolic link. - ;;; Note: This is similar to `symlinkat` in POSIX. - (@interface func (export "path_symlink") - ;;; The contents of the symbolic link. - (param $old_path string) - (param $fd $fd) - ;;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error $errno) - ) - - - ;;; Unlink a file. - ;;; Return `EISDIR` if the path refers to a directory. - ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (@interface func (export "path_unlink_file") - (param $fd $fd) - ;;; The path to a file to unlink. - (param $path string) - (result $error $errno) - ) - - ;;; Concurrently poll for the occurrence of a set of events. - (@interface func (export "poll_oneoff") - ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription)) - ;;; The events that have occurred. - (param $out (@witx pointer $event)) - ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size) - (result $error $errno) - ;;; The number of events stored. - (result $nevents $size) - ) - - ;;; Terminate the process normally. An exit code of 0 indicates successful - ;;; termination of the program. The meanings of other values is dependent on - ;;; the environment. - (@interface func (export "proc_exit") - ;;; The exit code returned by the process. - (param $rval $exitcode) - ) - - ;;; Temporarily yield execution of the calling thread. - ;;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "sched_yield") - (result $error $errno) - ) - - ;;; Write high-quality random data into a buffer. - ;;; This function blocks when the implementation is unable to immediately - ;;; provide sufficient high-quality random data. - ;;; This function may execute slowly, so when large mounts of random data are - ;;; required, it's advisable to use this function to seed a pseudo-random - ;;; number generator, rather than to provide the random data directly. - (@interface func (export "random_get") - ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error $errno) - ) - - ;;; Receive a message from a socket. - ;;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;;; the data into multiple buffers in the manner of `readv`. - (@interface func (export "sock_recv") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_array) - ;;; Message flags. - (param $ri_flags $riflags) - (result $error $errno) - ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size) - ;;; Message flags. - (result $ro_flags $roflags) - ) - - ;;; Send a message on a socket. - ;;; Note: This is similar to `send` in POSIX, though it also supports writing - ;;; the data from multiple buffers in the manner of `writev`. - (@interface func (export "sock_send") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_array) - ;;; Message flags. - (param $si_flags $siflags) - (result $error $errno) - ;;; Number of bytes transmitted. - (result $so_datalen $size) - ) - - ;;; Shut down socket send and receive channels. - ;;; Note: This is similar to `shutdown` in POSIX. - (@interface func (export "sock_shutdown") - (param $fd $fd) - ;;; Which channels on the socket to shut down. - (param $how $sdflags) - (result $error $errno) - ) -) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx new file mode 100644 index 000000000..5e53a83ec --- /dev/null +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx @@ -0,0 +1,18 @@ +;; WASI Process API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_proc + ;;; Terminate the process normally. An exit code of 0 indicates successful + ;;; termination of the program. The meanings of other values is dependent on + ;;; the environment. + (@interface func (export "exit") + ;;; The exit code returned by the process. + (param $rval $exitcode) + ) +) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx new file mode 100644 index 000000000..55c6df021 --- /dev/null +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx @@ -0,0 +1,26 @@ +;; WASI Random API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_random + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Write high-quality random data into a buffer. + ;;; This function blocks when the implementation is unable to immediately + ;;; provide sufficient high-quality random data. + ;;; This function may execute slowly, so when large mounts of random data are + ;;; required, it's advisable to use this function to seed a pseudo-random + ;;; number generator, rather than to provide the random data directly. + (@interface func (export "get") + ;;; The buffer to fill with random data. + (param $buf (@witx pointer u8)) + (param $buf_len $size) + (result $error $errno) + ) +) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sched.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sched.witx new file mode 100644 index 000000000..799a75fa9 --- /dev/null +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sched.witx @@ -0,0 +1,16 @@ +;; WASI Scheduler API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_sched + ;;; Temporarily yield execution of the calling thread. + ;;; Note: This is similar to `yield` in POSIX. + (@interface func (export "yield") + (result $error $errno) + ) +) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sock.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sock.witx new file mode 100644 index 000000000..becf80ffc --- /dev/null +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sock.witx @@ -0,0 +1,52 @@ +;; WASI Sockets. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_sock + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Receive a message from a socket. + ;;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;;; the data into multiple buffers in the manner of `readv`. + (@interface func (export "recv") + (param $fd $fd) + ;;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_array) + ;;; Message flags. + (param $ri_flags $riflags) + (result $error $errno) + ;;; Number of bytes stored in ri_data. + (result $ro_datalen $size) + ;;; Message flags. + (result $ro_flags $roflags) + ) + + ;;; Send a message on a socket. + ;;; Note: This is similar to `send` in POSIX, though it also supports writing + ;;; the data from multiple buffers in the manner of `writev`. + (@interface func (export "send") + (param $fd $fd) + ;;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_array) + ;;; Message flags. + (param $si_flags $siflags) + (result $error $errno) + ;;; Number of bytes transmitted. + (result $so_datalen $size) + ) + + ;;; Shut down socket send and receive channels. + ;;; Note: This is similar to `shutdown` in POSIX. + (@interface func (export "shutdown") + (param $fd $fd) + ;;; Which channels on the socket to shut down. + (param $how $sdflags) + (result $error $errno) + ) +) From 91fdc5d75c30aaffcdcf086de892f92f08b8988a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 25 Sep 2019 23:42:49 -0700 Subject: [PATCH 0323/1772] Modularize the WASI API. This splits what was previously "preview" into separate modules. There's a lot of API evolution still to be done here, and the groupings presented here may change, but this should help get things started. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 2150 ----------------- .../ephemeral/witx/wasi_ephemeral_args.witx | 28 + .../ephemeral/witx/wasi_ephemeral_clock.witx | 36 + .../witx/wasi_ephemeral_environ.witx | 28 + .../ephemeral/witx/wasi_ephemeral_fd.witx | 242 ++ .../ephemeral/witx/wasi_ephemeral_path.witx | 160 ++ .../ephemeral/witx/wasi_ephemeral_poll.witx | 26 + .../witx/wasi_ephemeral_preview.witx | 523 ---- .../ephemeral/witx/wasi_ephemeral_proc.witx | 18 + .../ephemeral/witx/wasi_ephemeral_random.witx | 26 + .../ephemeral/witx/wasi_ephemeral_sched.witx | 16 + .../ephemeral/witx/wasi_ephemeral_sock.witx | 52 + 12 files changed, 632 insertions(+), 2673 deletions(-) delete mode 100644 proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md create mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx create mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx create mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx create mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx create mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx create mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx delete mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx create mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx create mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx create mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_sched.witx create mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_sock.witx diff --git a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md deleted file mode 100644 index 087716fa5..000000000 --- a/proposals/random/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ /dev/null @@ -1,2150 +0,0 @@ - - -# The WASI Preview API - -This is the API-level documentation for WASI Preview. The function names -are prefixed with "\_\_wasi\_" to reflect how they are spelled in -flat-namespace contexts, however at the wasm module level, they are -unprefixed, because they're inside a module namespace. - -Functions that start with `__wasi_fd_` operate on file descriptors, -while functions that start with `__wasi_path_` operate on filesystem -paths, which are relative to directory file descriptors. - -Much inspiration and content here is derived from [CloudABI] and [POSIX], -though there are also several differences from CloudABI and POSIX. For -example, WASI Preview has no concept of processes in the traditional Unix -sense. While wasm linear memories have some of the aspects of processes, -and it's possible to *emulate* the full semantics of processes on top of -them, this can sometimes be unnatural and inefficient. The goal for -WASI Preview is to be a WebAssembly-native API that exposes APIs that fit -well into the underlying WebAssembly platform, rather than to directly -emulate other platforms. - -This is also a work in progress, and the API here is still evolving. - -Historical note: this API was originally named "WASI Core", and used the -API module name "wasi\_unstable". We've since sought to deemphasize the -"Core" name, as the goal is to split this API up into independent -modules so that embedders need not implement all of it. - -[CloudABI]: https://github.com/NuxiNL/cloudabi -[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ - -## System calls - -- [`__wasi_args_get()`](#args_get) -- [`__wasi_args_sizes_get()`](#args_sizes_get) -- [`__wasi_clock_res_get()`](#clock_res_get) -- [`__wasi_clock_time_get()`](#clock_time_get) -- [`__wasi_environ_get()`](#environ_get) -- [`__wasi_environ_sizes_get()`](#environ_sizes_get) -- [`__wasi_fd_advise()`](#fd_advise) -- [`__wasi_fd_allocate()`](#fd_allocate) -- [`__wasi_fd_close()`](#fd_close) -- [`__wasi_fd_datasync()`](#fd_datasync) -- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) -- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) -- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) -- [`__wasi_fd_filestat_get()`](#fd_filestat_get) -- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) -- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) -- [`__wasi_fd_pread()`](#fd_pread) -- [`__wasi_fd_prestat_get()`](#fd_prestat_get) -- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) -- [`__wasi_fd_pwrite()`](#fd_pwrite) -- [`__wasi_fd_read()`](#fd_read) -- [`__wasi_fd_readdir()`](#fd_readdir) -- [`__wasi_fd_renumber()`](#fd_renumber) -- [`__wasi_fd_seek()`](#fd_seek) -- [`__wasi_fd_sync()`](#fd_sync) -- [`__wasi_fd_tell()`](#fd_tell) -- [`__wasi_fd_write()`](#fd_write) -- [`__wasi_path_create_directory()`](#path_create_directory) -- [`__wasi_path_filestat_get()`](#path_filestat_get) -- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) -- [`__wasi_path_link()`](#path_link) -- [`__wasi_path_open()`](#path_open) -- [`__wasi_path_readlink()`](#path_readlink) -- [`__wasi_path_remove_directory()`](#path_remove_directory) -- [`__wasi_path_rename()`](#path_rename) -- [`__wasi_path_symlink()`](#path_symlink) -- [`__wasi_path_unlink_file()`](#path_unlink_file) -- [`__wasi_poll_oneoff()`](#poll_oneoff) -- [`__wasi_proc_exit()`](#proc_exit) -- [`__wasi_random_get()`](#random_get) -- [`__wasi_sched_yield()`](#sched_yield) -- [`__wasi_sock_recv()`](#sock_recv) -- [`__wasi_sock_send()`](#sock_send) -- [`__wasi_sock_shutdown()`](#sock_shutdown) - -### `__wasi_args_get()` - -Read command-line argument data. - -Inputs: - -- char \*\*argv - - A pointer to a buffer to write the argument pointers. - - The count of elements for the buffer should be at least the value of `argc` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - - The caller of `__wasi_args_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. - -- char \*argv\_buf - - A pointer to a buffer to write the argument string data. - - The size of this buffer should be the value of `argv_buf_size` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - -### `__wasi_args_sizes_get()` - -Return command-line argument data sizes. - -Outputs: - -- size\_t \*argc - - The number of arguments. - -- size\_t \*argv\_buf\_size - - The size of the argument string data. - -### `__wasi_clock_res_get()` - -Return the resolution of a clock. - -Implementations are required to provide a non-zero value for supported clocks. -For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). - -Note: This is similar to `clock_getres` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the resolution. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) resolution - - The resolution of the clock. - -### `__wasi_clock_time_get()` - -Return the time value of a clock. - -Note: This is similar to `clock_gettime` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the time. - -- [\_\_wasi\_timestamp\_t](#timestamp) precision - - The maximum lag (exclusive) that the returned - time value may have, compared to its actual - value. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) time - - The time value of the clock. - -### `__wasi_environ_get()` - -Read environment variable data. - -Inputs: - -- char \*\*environ - - A pointer to a buffer to write the environment variable pointers. - - The count of elements for the buffer should be at least the value of `environ_count` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - - The caller of `__wasi_environ_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. - -- char \*environ\_buf - - A pointer to a buffer to write the environment variable string data. - - The size of this buffer should be the value of `environ_buf_size` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - -### `__wasi_environ_sizes_get()` - -Return enviroment variable data sizes. - -Outputs: - -- size\_t \*environ\_count - - The number of environment variables. - -- size\_t \*environ\_buf\_size - - The size of the environment variable string data. - -### `__wasi_fd_advise()` - -Provide file advisory information on a file descriptor. - -Note: This is similar to `posix_fadvise` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file for which to provide file advisory information. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file to which the advisory applies. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the region to which the advisory applies. - -- [\_\_wasi\_advice\_t](#advice) advice - - The advice. - -### `__wasi_fd_allocate()` - -Force the allocation of space in a file. - -Note: This is similar to `posix_fallocate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file in which to allocate space. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset at which to start the allocation. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the area that is allocated. - -### `__wasi_fd_close()` - -Close a file descriptor. - -Note: This is similar to `close` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to close. - -### `__wasi_fd_datasync()` - -Synchronize the data of a file to disk. - -Note: This is similar to `fdatasync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file to synchronize to disk. - -### `__wasi_fd_fdstat_get()` - -Get the attributes of a file descriptor. - -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well -as additional fields. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_fdstat\_t](#fdstat) \*buf - - The buffer where the file descriptor's attributes are stored. - -### `__wasi_fd_fdstat_set_flags()` - -Adjust the flags associated with a file descriptor. - -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_fdflags\_t](#fdflags) flags - - The desired values of the file descriptor - flags. - -### `__wasi_fd_fdstat_set_rights()` - -Adjust the rights associated with a file descriptor. - -This can only be used to remove rights, and returns -[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt -to add rights. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The desired rights of the file descriptor. - -### `__wasi_fd_filestat_get()` - -Return the attributes of an open file. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_fd_filestat_set_size()` - -Adjust the size of an open file. If this increases the file's size, the extra -bytes are filled with zeros. - -Note: This is similar to `ftruncate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - A file descriptor for the file to adjust. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - The desired file size. - -### `__wasi_fd_filestat_set_times()` - -Adjust the timestamps of an open file or directory. - -Note: This is similar to `futimens` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_fd_pread()` - -Read from a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `preadv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors in which to store data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to read. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_prestat_get()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- [\_\_wasi\_prestat\_t](#prestat) \*buf - - The buffer where the description is stored. - -### `__wasi_fd_prestat_dir_name()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- const char \*path and size\_t path\_len - - A buffer into which to write the preopened directory name. - -### `__wasi_fd_pwrite()` - -Write to a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `pwritev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to write. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_fd_read()` - -Read from a file descriptor. - -Note: This is similar to `readv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors to which to store data. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_readdir()` - -Read directory entries from a directory. - -When successful, the contents of the output buffer consist of -a sequence of directory entries. Each directory entry consists -of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes -holding the name of the directory entry. - -This function fills the output buffer as much as possible, -potentially truncating the last directory entry. This allows -the caller to grow its read buffer size in case it's too small -to fit a single large directory entry, or skip the oversized -directory entry. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The directory from which to read the directory - entries. - -- void \*buf and size\_t buf\_len - - The buffer where directory entries are stored. - -- [\_\_wasi\_dircookie\_t](#dircookie) cookie - - The location within the directory to start - reading. - -Outputs: - -- size\_t bufused - - The number of bytes stored in the read buffer. - If less than the size of the read buffer, the - end of the directory has been reached. - -### `__wasi_fd_renumber()` - -Atomically replace a file descriptor by renumbering another -file descriptor. - -Due to the strong focus on thread safety, this environment -does not provide a mechanism to duplicate or renumber a file -descriptor to an arbitrary number, like dup2(). This would be -prone to race conditions, as an actual file descriptor with the -same number could be allocated by a different thread at the same -time. - -This function provides a way to atomically renumber file -descriptors, which would disappear if dup2() were to be -removed entirely. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) from - - The file descriptor to renumber. - -- [\_\_wasi\_fd\_t](#fd) to - - The file descriptor to overwrite. - -### `__wasi_fd_seek()` - -Move the offset of a file descriptor. - -Note: This is similar to `lseek` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_filedelta\_t](#filedelta) offset - - The number of bytes to move. - -- [\_\_wasi\_whence\_t](#whence) whence - - The base from which the offset is relative. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) newoffset - - The new offset of the file descriptor, - relative to the start of the file. - -### `__wasi_fd_sync()` - -Synchronize the data and metadata of a file to disk. - -Note: This is similar to `fsync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file containing the data - and metadata to synchronize to disk. - -### `__wasi_fd_tell()` - -Return the current offset of a file descriptor. - -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The current offset of the file descriptor, relative to the start of the file. - -### `__wasi_fd_write()` - -Write to a file descriptor. - -Note: This is similar to `writev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_path_create_directory()` - -Create a directory. - -Note: This is similar to `mkdirat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path at which to create the directory. - -### `__wasi_path_filestat_get()` - -Return the attributes of a file or directory. - -Note: This is similar to `stat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_path_filestat_set_times()` - -Adjust the timestamps of a file or directory. - -Note: This is similar to `utimensat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_path_link()` - -Create a hard link. - -Note: This is similar to `linkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags - - Flags determining the method of how the path is resolved. - -- const char \*old\_path and size\_t old\_path\_len - - The source path from which to link. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the hard link. - -### `__wasi_path_open()` - -Open a file or directory. - -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since -this is error-prone in multi-threaded contexts. The returned file -descriptor is guaranteed to be less than 231. - -Note: This is similar to `openat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) dirfd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The relative path of the file or directory to open, relative to - the [`dirfd`](#path_open.dirfd) directory. - -- [\_\_wasi\_oflags\_t](#oflags) o_flags - - The method by which to open the file. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The initial rights of the newly created file descriptor. The - implementation is allowed to return a file descriptor with fewer - rights than specified, if and only if those rights do not apply - to the type of file being opened. - - The *base* rights are rights that will apply to operations using - the file descriptor itself, while the *inheriting* rights are - rights that apply to file descriptors derived from it. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - The initial flags of the file descriptor. - -Outputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file that has been - opened. - -### `__wasi_path_readlink()` - -Read the contents of a symbolic link. - -Note: This is similar to `readlinkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path of the symbolic link from which to read. - -- char \*buf and size\_t buf\_len - - The buffer to which to write the contents of the symbolic link. - -Outputs: - -- size\_t bufused - - The number of bytes placed in the buffer. - -### `__wasi_path_remove_directory()` - -Remove a directory. - -Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. - -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a directory to remove. - -### `__wasi_path_rename()` - -Rename a file or directory. - -Note: This is similar to `renameat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- const char \*old\_path and size\_t old\_path\_len - - The source path of the file or directory to rename. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path to which to rename the file or directory. - -### `__wasi_path_symlink()` - -Create a symbolic link. - -Note: This is similar to `symlinkat` in POSIX. - -Inputs: - -- const char \*old\_path and size\_t old_path\_len - - The contents of the symbolic link. - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the symbolic link. - -### `__wasi_path_unlink_file()` - -Unlink a file. - -Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. - -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a file to unlink. - -### `__wasi_poll_oneoff()` - -Concurrently poll for the occurrence of a set of events. - -Inputs: - -- const [\_\_wasi\_subscription\_t](#subscription) \*in - - The events to which to subscribe. - -- [\_\_wasi\_event\_t](#event) \*out - - The events that have occurred. - -- size\_t nsubscriptions - - Both the number of subscriptions and events. - -Outputs: - -- size\_t nevents - - The number of events stored. - -### `__wasi_proc_exit()` - -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -Note: This is similar to `_Exit` in POSIX. - -Inputs: - -- [\_\_wasi\_exitcode\_t](#exitcode) rval - - The exit code returned by the process. - -Does not return. - -### `__wasi_random_get()` - -Write high-quality random data into a buffer. - -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. - -This function may execute slowly, so when large mounts of random -data are required, it's advisable to use this function to seed a -pseudo-random number generator, rather than to provide the -random data directly. - -Inputs: - -- void \*buf and size\_t buf\_len - - The buffer to fill with random data. - -### `__wasi_sched_yield()` - -Temporarily yield execution of the calling thread. - -Note: This is similar to `sched_yield` in POSIX. - -### `__wasi_sock_recv()` - -Receive a message from a socket. - -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to receive data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len - - List of scatter/gather vectors to which to store data. - -- [\_\_wasi\_riflags\_t](#riflags) ri\_flags - - Message flags. - -Outputs: - -- size\_t ro\_datalen - - Number of bytes stored in [`ri_data`](#sock_recv.ri_data). - -- [\_\_wasi\_roflags\_t](#roflags) ro\_flags - - Message flags. - -### `__wasi_sock_send()` - -Send a message on a socket. - -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to send data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len - - List of scatter/gather vectors to which to retrieve data - -- [\_\_wasi\_siflags\_t](#siflags) si\_flags - - Message flags. - -Outputs: - -- size\_t so\_datalen - - Number of bytes transmitted. - -### `__wasi_sock_shutdown()` - -Shut down socket send and receive channels. - -Note: This is similar to `shutdown` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to shutdown channels. - -- [\_\_wasi\_sdflags\_t](#sdflags) how - - Which channels on the socket to shut down. - -## Types - -### `__wasi_advice_t` (`uint8_t`) - -File or memory access pattern advisory information. - -Used by [`__wasi_fd_advise()`](#fd_advise). - -Possible values: - -- **`__WASI_ADVICE_NORMAL`** - - The application has no advice to give on its behavior - with respect to the specified data. - -- **`__WASI_ADVICE_SEQUENTIAL`** - - The application expects to access the specified data - sequentially from lower offsets to higher offsets. - -- **`__WASI_ADVICE_RANDOM`** - - The application expects to access the specified data - in a random order. - -- **`__WASI_ADVICE_WILLNEED`** - - The application expects to access the specified data - in the near future. - -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - -### `__wasi_ciovec_t` (`struct`) - -A region of memory for scatter/gather writes. - -Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). - -Members: - -- const void \*buf and size\_t buf\_len - - The address and length of the buffer to be written. - -### `__wasi_clockid_t` (`uint32_t`) - -Identifiers for clocks. - -Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). - -Possible values: - -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - -- **`__WASI_CLOCK_MONOTONIC`** - - The store-wide monotonic clock, which is defined as a - clock measuring real time, whose value cannot be - adjusted and which cannot have negative clock jumps. - - The epoch of this clock is undefined. The absolute - time value of this clock therefore has no meaning. - -- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** - - The CPU-time clock associated with the current - process. - -- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** - - The CPU-time clock associated with the current thread. - -### `__wasi_device_t` (`uint64_t`) - -Identifier for a device containing a file system. Can be used -in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or -directory in the filesystem. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_dircookie_t` (`uint64_t`) - -A reference to the offset of a directory entry. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). - -Special values: - -- **`__WASI_DIRCOOKIE_START`** - - Permanent reference to the first directory entry - within a directory. - -### `__wasi_dirent_t` (`struct`) - -A directory entry. - -Members: - -- [\_\_wasi\_dircookie\_t](#dircookie) d\_next - - The offset of the next directory entry stored in this - directory. - -- [\_\_wasi\_inode\_t](#inode) d\_ino - - The serial number of the file referred to by this - directory entry. - -- uint32\_t d\_namlen - - The length of the name of the directory entry. - -- [\_\_wasi\_filetype\_t](#filetype) d\_type - - The type of the file referred to by this directory - entry. - -### `__wasi_errno_t` (`uint16_t`) - -Error codes returned by functions. - -Not all of these error codes are returned by the functions -provided by this API; some are used in higher-level library layers, -and others are provided merely for alignment with POSIX. - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_ESUCCESS`** - - No error occurred. System call completed successfully. - -- **`__WASI_E2BIG`** - - Argument list too long. - -- **`__WASI_EACCES`** - - Permission denied. - -- **`__WASI_EADDRINUSE`** - - Address in use. - -- **`__WASI_EADDRNOTAVAIL`** - - Address not available. - -- **`__WASI_EAFNOSUPPORT`** - - Address family not supported. - -- **`__WASI_EAGAIN`** - - Resource unavailable, or operation would block. - -- **`__WASI_EALREADY`** - - Connection already in progress. - -- **`__WASI_EBADF`** - - Bad file descriptor. - -- **`__WASI_EBADMSG`** - - Bad message. - -- **`__WASI_EBUSY`** - - Device or resource busy. - -- **`__WASI_ECANCELED`** - - Operation canceled. - -- **`__WASI_ECHILD`** - - No child processes. - -- **`__WASI_ECONNABORTED`** - - Connection aborted. - -- **`__WASI_ECONNREFUSED`** - - Connection refused. - -- **`__WASI_ECONNRESET`** - - Connection reset. - -- **`__WASI_EDEADLK`** - - Resource deadlock would occur. - -- **`__WASI_EDESTADDRREQ`** - - Destination address required. - -- **`__WASI_EDOM`** - - Mathematics argument out of domain of function. - -- **`__WASI_EDQUOT`** - - Reserved. - -- **`__WASI_EEXIST`** - - File exists. - -- **`__WASI_EFAULT`** - - Bad address. - -- **`__WASI_EFBIG`** - - File too large. - -- **`__WASI_EHOSTUNREACH`** - - Host is unreachable. - -- **`__WASI_EIDRM`** - - Identifier removed. - -- **`__WASI_EILSEQ`** - - Illegal byte sequence. - -- **`__WASI_EINPROGRESS`** - - Operation in progress. - -- **`__WASI_EINTR`** - - Interrupted function. - -- **`__WASI_EINVAL`** - - Invalid argument. - -- **`__WASI_EIO`** - - I/O error. - -- **`__WASI_EISCONN`** - - Socket is connected. - -- **`__WASI_EISDIR`** - - Is a directory. - -- **`__WASI_ELOOP`** - - Too many levels of symbolic links. - -- **`__WASI_EMFILE`** - - File descriptor value too large. - -- **`__WASI_EMLINK`** - - Too many links. - -- **`__WASI_EMSGSIZE`** - - Message too large. - -- **`__WASI_EMULTIHOP`** - - Reserved. - -- **`__WASI_ENAMETOOLONG`** - - Filename too long. - -- **`__WASI_ENETDOWN`** - - Network is down. - -- **`__WASI_ENETRESET`** - - Connection aborted by network. - -- **`__WASI_ENETUNREACH`** - - Network unreachable. - -- **`__WASI_ENFILE`** - - Too many files open in system. - -- **`__WASI_ENOBUFS`** - - No buffer space available. - -- **`__WASI_ENODEV`** - - No such device. - -- **`__WASI_ENOENT`** - - No such file or directory. - -- **`__WASI_ENOEXEC`** - - Executable file format error. - -- **`__WASI_ENOLCK`** - - No locks available. - -- **`__WASI_ENOLINK`** - - Reserved. - -- **`__WASI_ENOMEM`** - - Not enough space. - -- **`__WASI_ENOMSG`** - - No message of the desired type. - -- **`__WASI_ENOPROTOOPT`** - - Protocol not available. - -- **`__WASI_ENOSPC`** - - No space left on device. - -- **`__WASI_ENOSYS`** - - Function not supported. - -- **`__WASI_ENOTCONN`** - - The socket is not connected. - -- **`__WASI_ENOTDIR`** - - Not a directory or a symbolic link to a directory. - -- **`__WASI_ENOTEMPTY`** - - Directory not empty. - -- **`__WASI_ENOTRECOVERABLE`** - - State not recoverable. - -- **`__WASI_ENOTSOCK`** - - Not a socket. - -- **`__WASI_ENOTSUP`** - - Not supported, or operation not supported on socket. - -- **`__WASI_ENOTTY`** - - Inappropriate I/O control operation. - -- **`__WASI_ENXIO`** - - No such device or address. - -- **`__WASI_EOVERFLOW`** - - Value too large to be stored in data type. - -- **`__WASI_EOWNERDEAD`** - - Previous owner died. - -- **`__WASI_EPERM`** - - Operation not permitted. - -- **`__WASI_EPIPE`** - - Broken pipe. - -- **`__WASI_EPROTO`** - - Protocol error. - -- **`__WASI_EPROTONOSUPPORT`** - - Protocol not supported. - -- **`__WASI_EPROTOTYPE`** - - Protocol wrong type for socket. - -- **`__WASI_ERANGE`** - - Result too large. - -- **`__WASI_EROFS`** - - Read-only file system. - -- **`__WASI_ESPIPE`** - - Invalid seek. - -- **`__WASI_ESRCH`** - - No such process. - -- **`__WASI_ESTALE`** - - Reserved. - -- **`__WASI_ETIMEDOUT`** - - Connection timed out. - -- **`__WASI_ETXTBSY`** - - Text file busy. - -- **`__WASI_EXDEV`** - - Cross-device link. - -- **`__WASI_ENOTCAPABLE`** - - Extension: Capabilities insufficient. - -### `__wasi_event_t` (`struct`) - -An event that occurred. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that got attached to - [`__wasi_subscription_t::userdata`](#subscription.userdata). - -- [\_\_wasi\_errno\_t](#errno) error - - If non-zero, an error that occurred while processing - the subscription request. - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event that occurred. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_filesize\_t](#filesize) nbytes - - The number of bytes available for reading or writing. - - - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags - - The state of the file descriptor. - -### `__wasi_eventrwflags_t` (`uint16_t` bitfield) - -The state of the file descriptor subscribed to with -[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_EVENT_FD_READWRITE_HANGUP`** - - The peer of this socket has closed or disconnected. - -### `__wasi_eventtype_t` (`uint8_t`) - -Type of a subscription to an event or its occurrence. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_EVENTTYPE_CLOCK`** - - The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) - has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -- **`__WASI_EVENTTYPE_FD_READ`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - data available for reading. This event always triggers - for regular files. - -- **`__WASI_EVENTTYPE_FD_WRITE`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - capacity available for writing. This event always - triggers for regular files. - -### `__wasi_exitcode_t` (`uint32_t`) - -Exit code generated by a process when exiting. - -Used by [`__wasi_proc_exit()`](#proc_exit). - -### `__wasi_fd_t` (`uint32_t`) - -A file descriptor number. - -Used by many functions in this API. - -As in POSIX, three file descriptor numbers are provided to instances -on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, -and `STDERR_FILENO`). - -Other than these, WASI implementations are not required to allocate -new file descriptors in ascending order. - -### `__wasi_fdflags_t` (`uint16_t` bitfield) - -File descriptor flags. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_FDFLAG_APPEND`** - - Append mode: Data written to the file is always - appended to the file's end. - -- **`__WASI_FDFLAG_DSYNC`** - - Write according to synchronized I/O data integrity - completion. Only the data stored in the file is - synchronized. - -- **`__WASI_FDFLAG_NONBLOCK`** - - Non-blocking mode. - -- **`__WASI_FDFLAG_RSYNC`** - - Synchronized read I/O operations. - -- **`__WASI_FDFLAG_SYNC`** - - Write according to synchronized I/O file integrity completion. - In addition to synchronizing the data stored in the file, the - implementation may also synchronously update the file's metadata. - -### `__wasi_fdstat_t` (`struct`) - -File descriptor attributes. - -Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). - -Members: - -- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype - - File type. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - File descriptor flags. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base - - Rights that apply to this file descriptor. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - Maximum set of rights that may be installed on new - file descriptors that are created through this file - descriptor, e.g., through [`__wasi_path_open()`](#path_open). - -### `__wasi_filedelta_t` (`int64_t`) - -Relative offset within a file. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -### `__wasi_filesize_t` (`uint64_t`) - -Non-negative file size or length of a region within a file. - -Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -### `__wasi_filestat_t` (`struct`) - -File attributes. - -Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). - -Members: - -- [\_\_wasi\_device\_t](#device) st\_dev - - Device ID of device containing the file. - -- [\_\_wasi\_inode\_t](#inode) st\_ino - - File serial number. - -- [\_\_wasi\_filetype\_t](#filetype) st\_filetype - - File type. - -- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink - - Number of hard links to the file. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - For regular files, the file size in bytes. For - symbolic links, the length in bytes of the pathname - contained in the symbolic link. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - Last data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - Last data modification timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim - - Last file status change timestamp. - -### `__wasi_filetype_t` (`uint8_t`) - -The type of a file descriptor or file. - -Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). - -Possible values: - -- **`__WASI_FILETYPE_UNKNOWN`** - - The type of the file descriptor or file is unknown or - is different from any of the other types specified. - -- **`__WASI_FILETYPE_BLOCK_DEVICE`** - - The file descriptor or file refers to a block device - inode. - -- **`__WASI_FILETYPE_CHARACTER_DEVICE`** - - The file descriptor or file refers to a character - device inode. - -- **`__WASI_FILETYPE_DIRECTORY`** - - The file descriptor or file refers to a directory - inode. - -- **`__WASI_FILETYPE_REGULAR_FILE`** - - The file descriptor or file refers to a regular file - inode. - -- **`__WASI_FILETYPE_SOCKET_DGRAM`** - - The file descriptor or file refers to a datagram - socket. - -- **`__WASI_FILETYPE_SOCKET_STREAM`** - - The file descriptor or file refers to a byte-stream - socket. - -- **`__WASI_FILETYPE_SYMBOLIC_LINK`** - - The file refers to a symbolic link inode. - -### `__wasi_fstflags_t` (`uint16_t` bitfield) - -Which file time attributes to adjust. - -Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -Possible values: - -- **`__WASI_FILESTAT_SET_ATIM`** - - Adjust the last data access timestamp to the value - stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). - -- **`__WASI_FILESTAT_SET_ATIM_NOW`** - - Adjust the last data access timestamp to the time - of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -- **`__WASI_FILESTAT_SET_MTIM`** - - Adjust the last data modification timestamp to the - value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). - -- **`__WASI_FILESTAT_SET_MTIM_NOW`** - - Adjust the last data modification timestamp to the - time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -### `__wasi_inode_t` (`uint64_t`) - -File serial number that is unique within its file system. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). - -### `__wasi_iovec_t` (`struct`) - -A region of memory for scatter/gather reads. - -Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). - -Members: - -- void \*buf and size\_t buf\_len - - The address and length of the buffer to be filled. - -### `__wasi_linkcount_t` (`uint64_t`) - -Number of hard links to an inode. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_lookupflags_t` (`uint32_t` bitfield) - -Flags determining the method of how paths are resolved. - -Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** - - As long as the resolved path corresponds to a symbolic - link, it is expanded. - -### `__wasi_oflags_t` (`uint16_t` bitfield) - -Open flags used by [`__wasi_path_open()`](#path_open). - -Used by [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_O_CREAT`** - - Create file if it does not exist. - -- **`__WASI_O_DIRECTORY`** - - Fail if not a directory. - -- **`__WASI_O_EXCL`** - - Fail if file already exists. - -- **`__WASI_O_TRUNC`** - - Truncate file to size 0. - -### `__wasi_riflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_PEEK`** - - Returns the message without removing it from the - socket's receive queue. - -- **`__WASI_SOCK_RECV_WAITALL`** - - On byte-stream sockets, block until the full amount - of data can be returned. - -### `__wasi_rights_t` (`uint64_t` bitfield) - -File descriptor rights, determining which actions may be -performed. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_RIGHT_FD_DATASYNC`** - - The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_READ`** - - The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke - [`__wasi_fd_pread()`](#fd_pread). - -- **`__WASI_RIGHT_FD_SEEK`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies - [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). - -- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** - - The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). - -- **`__WASI_RIGHT_FD_SYNC`** - - The right to invoke [`__wasi_fd_sync()`](#fd_sync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and - [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_TELL`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the - file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with - offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). - -- **`__WASI_RIGHT_FD_WRITE`** - - The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to - invoke [`__wasi_fd_pwrite()`](#fd_pwrite). - -- **`__WASI_RIGHT_FD_ADVISE`** - - The right to invoke [`__wasi_fd_advise()`](#fd_advise). - -- **`__WASI_RIGHT_FD_ALLOCATE`** - - The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). - -- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** - - The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). - -- **`__WASI_RIGHT_PATH_CREATE_FILE`** - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke - [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). - -- **`__WASI_RIGHT_PATH_LINK_SOURCE`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_LINK_TARGET`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_OPEN`** - - The right to invoke [`__wasi_path_open()`](#path_open). - -- **`__WASI_RIGHT_FD_READDIR`** - - The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). - -- **`__WASI_RIGHT_PATH_READLINK`** - - The right to invoke [`__wasi_path_readlink()`](#path_readlink). - -- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_RENAME_TARGET`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_FILESTAT_GET`** - - The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** - - The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -- **`__WASI_RIGHT_FD_FILESTAT_GET`** - - The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** - - The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). - -- **`__WASI_RIGHT_PATH_SYMLINK`** - - The right to invoke [`__wasi_path_symlink()`](#path_symlink). - -- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** - - The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). - -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - -- **`__WASI_RIGHT_POLL_FD_READWRITE`** - - If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). - - If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -- **`__WASI_RIGHT_SOCK_SHUTDOWN`** - - The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). - -### `__wasi_roflags_t` (`uint16_t` bitfield) - -Flags returned by [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** - - Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been - truncated. - -### `__wasi_sdflags_t` (`uint8_t` bitfield) - -Which channels on a socket to shut down. - -Used by [`__wasi_sock_shutdown()`](#sock_shutdown). - -Possible values: - -- **`__WASI_SHUT_RD`** - - Disables further receive operations. - -- **`__WASI_SHUT_WR`** - - Disables further send operations. - -### `__wasi_siflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Used by [`__wasi_sock_send()`](#sock_send). - -### `__wasi_subclockflags_t` (`uint16_t` bitfield) - -Flags determining how to interpret the timestamp provided in -[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -Used by [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** - - If set, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp - of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - - If clear, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current - time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - -### `__wasi_subscription_t` (`struct`) - -Subscription to an event. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that is attached to the subscription in the - implementation and returned through - [`__wasi_event_t::userdata`](#event.userdata). - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event to which to subscribe. - -- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): - - - **`u.clock`** - - - [\_\_wasi\_userdata\_t](#userdata) identifier - - The user-defined unique identifier of the clock. - - - [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock against which to compare the timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) timeout - - The absolute or relative timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) precision - - The amount of time that the implementation may wait additionally - to coalesce with other events. - - - [\_\_wasi\_subclockflags\_t](#subclockflags) flags - - Flags specifying whether the timeout is absolute or relative. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor on which to wait for it to become ready - for reading or writing. - -### `__wasi_timestamp_t` (`uint64_t`) - -Timestamp in nanoseconds. - -Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -### `__wasi_userdata_t` (`uint64_t`) - -User-provided value that may be attached to objects that is -retained when extracted from the implementation. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -### `__wasi_whence_t` (`uint8_t`) - -The position relative to which to set the offset of the file descriptor. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -Possible values: - -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - -- **`__WASI_WHENCE_CUR`** - - Seek relative to current position. - -- **`__WASI_WHENCE_END`** - - Seek relative to end-of-file. - diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx new file mode 100644 index 000000000..2c2d32d67 --- /dev/null +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -0,0 +1,28 @@ +;; WASI Command-line Arguments. +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_args + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Read command-line argument data. + ;;; The size of the array should match that returned by `sizes_get` + (@interface func (export "get") + (param $argv (@witx pointer (@witx pointer u8))) + (param $argv_buf (@witx pointer u8)) + (result $error $errno) + ) + + ;;; Return command-line argument data sizes. + (@interface func (export "sizes_get") + (result $error $errno) + ;;; The number of arguments. + (result $argc $size) + ;;; The size of the argument string data. + (result $argv_buf_size $size) + ) +) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx new file mode 100644 index 000000000..b6d880443 --- /dev/null +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx @@ -0,0 +1,36 @@ +;; WASI Clocks. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_clock + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Return the resolution of a clock. + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Note: This is similar to `clock_getres` in POSIX. + (@interface func (export "res_get") + (result $error $errno) + ;;; The clock for which to return the resolution. + (param $id $clockid) + ;;; The resolution of the clock. + (result $resolution $timestamp) + ) + + ;;; Return the time value of a clock. + ;;; Note: This is similar to `clock_gettime` in POSIX. + (@interface func (export "time_get") + ;;; The clock for which to return the time. + (param $id $clockid) + ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp) + (result $error $errno) + ;;; The time value of the clock. + (result $time $timestamp) + ) +) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx new file mode 100644 index 000000000..5bc9c5a6f --- /dev/null +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -0,0 +1,28 @@ +;; WASI Environment Variables. +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_environ + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Read environment variable data. + ;;; The sizes of the buffers should match that returned by `sizes_get`. + (@interface func (export "get") + (param $environ (@witx pointer (@witx pointer u8))) + (param $environ_buf (@witx pointer u8)) + (result $error $errno) + ) + + ;;; Return command-line argument data sizes. + (@interface func (export "sizes_get") + (result $error $errno) + ;;; The number of arguments. + (result $argc $size) + ;;; The size of the argument string data. + (result $argv_buf_size $size) + ) +) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx new file mode 100644 index 000000000..9fbad9ab7 --- /dev/null +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -0,0 +1,242 @@ +;; WASI I/O. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_fd + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Provide file advisory information on a file descriptor. + ;;; Note: This is similar to `posix_fadvise` in POSIX. + (@interface func (export "advise") + (param $fd $fd) + ;;; The offset within the file to which the advisory applies. + (param $offset $filesize) + ;;; The length of the region to which the advisory applies. + (param $len $filesize) + ;;; The advice. + (param $advice $advice) + (result $error $errno) + ) + + ;;; Force the allocation of space in a file. + ;;; Note: This is similar to `posix_fallocate` in POSIX. + (@interface func (export "allocate") + (param $fd $fd) + ;;; The offset at which to start the allocation. + (param $offset $filesize) + ;;; The length of the area that is allocated. + (param $len $filesize) + (result $error $errno) + ) + + ;;; Close a file descriptor. + ;;; Note: This is similar to `close` in POSIX. + (@interface func (export "close") + (param $fd $fd) + (result $error $errno) + ) + + ;;; Synchronize the data of a file to disk. + ;;; Note: This is similar to `fdatasync` in POSIX. + (@interface func (export "datasync") + (param $fd $fd) + (result $error $errno) + ) + + ;;; Get the attributes of a file descriptor. + ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (@interface func (export "fdstat_get") + (param $fd $fd) + (result $error $errno) + ;;; The buffer where the file descriptor's attributes are stored. + (result $stat $fdstat) + ) + + ;;; Adjust the flags associated with a file descriptor. + ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (@interface func (export "fdstat_set_flags") + (param $fd $fd) + ;;; The desired values of the file descriptor flags. + (param $flags $fdflags) + (result $error $errno) + ) + + ;;; Adjust the rights associated with a file descriptor. + ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (@interface func (export "fdstat_set_rights") + (param $fd $fd) + ;;; The desired rights of the file descriptor. + (param $fs_rights_base $rights) + (param $fs_rights_inheriting $rights) + (result $error $errno) + ) + + ;;; Return the attributes of an open file. + (@interface func (export "filestat_get") + (param $fd $fd) + (result $error $errno) + ;;; The buffer where the file's attributes are stored. + (result $buf $filestat) + ) + + ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;;; Note: This is similar to `ftruncate` in POSIX. + (@interface func (export "filestat_set_size") + (param $fd $fd) + ;;; The desired file size. + (param $size $filesize) + (result $error $errno) + ) + + ;;; Adjust the timestamps of an open file or directory. + ;;; Note: This is similar to `futimens` in POSIX. + (@interface func (export "filestat_set_times") + (param $fd $fd) + ;;; The desired values of the data access timestamp. + (param $atim $timestamp) + ;;; The desired values of the data modification timestamp. + (param $mtim $timestamp) + ;;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags) + (result $error $errno) + ) + + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `preadv` in POSIX. + (@interface func (export "pread") + (param $fd $fd) + ;;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_array) + ;;; The offset within the file at which to read. + (param $offset $filesize) + (result $error $errno) + ;;; The number of bytes read. + (result $nread $size) + ) + + ;;; Return a description of the given preopened file descriptor. + (@interface func (export "prestat_get") + (param $fd $fd) + (result $error $errno) + ;;; The buffer where the description is stored. + (result $buf $prestat) + ) + + ;;; Return a description of the given preopened file descriptor. + (@interface func (export "prestat_dir_name") + (param $fd $fd) + ;;; A buffer into which to write the preopened directory name. + (param $path (@witx pointer u8)) + (param $path_len $size) + (result $error $errno) + ) + + ;;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `pwritev` in POSIX. + (@interface func (export "pwrite") + (param $fd $fd) + ;;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_array) + ;;; The offset within the file at which to write. + (param $offset $filesize) + (result $error $errno) + ;;; The number of bytes written. + (result $nwritten $size) + ) + + ;;; Read from a file descriptor. + ;;; Note: This is similar to `readv` in POSIX. + (@interface func (export "read") + (param $fd $fd) + ;;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_array) + (result $error $errno) + ;;; The number of bytes read. + (result $nread $size) + ) + + ;;; Read directory entries from a directory. + ;;; When successful, the contents of the output buffer consist of a sequence of + ;;; directory entries. Each directory entry consists of a dirent_t object, + ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; entry. + ;; + ;;; This function fills the output buffer as much as possible, potentially + ;;; truncating the last directory entry. This allows the caller to grow its + ;;; read buffer size in case it's too small to fit a single large directory + ;;; entry, or skip the oversized directory entry. + (@interface func (export "readdir") + (param $fd $fd) + ;;; The buffer where directory entries are stored + (param $buf (@witx pointer u8)) + (param $buf_len $size) + ;;; The location within the directory to start reading + (param $cookie $dircookie) + (result $error $errno) + ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size) + ) + + ;;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; + ;;; Due to the strong focus on thread safety, this environment does not provide + ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;;; file descriptor with the same number could be allocated by a different + ;;; thread at the same time. + ;; + ;;; This function provides a way to atomically renumber file descriptors, which + ;;; would disappear if `dup2()` were to be removed entirely. + (@interface func (export "renumber") + (param $fd $fd) + ;;; The file descriptor to overwrite. + (param $to $fd) + (result $error $errno) + ) + + ;;; Move the offset of a file descriptor. + ;;; Note: This is similar to `lseek` in POSIX. + (@interface func (export "seek") + (param $fd $fd) + ;;; The number of bytes to move. + (param $offset $filedelta) + ;;; The base from which the offset is relative. + (param $whence $whence) + (result $error $errno) + ;;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize) + ) + + ;;; Synchronize the data and metadata of a file to disk. + ;;; Note: This is similar to `fsync` in POSIX. + (@interface func (export "sync") + (param $fd $fd) + (result $error $errno) + ) + + ;;; Return the current offset of a file descriptor. + ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (@interface func (export "tell") + (param $fd $fd) + (result $error $errno) + ;;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize) + ) + + ;;; Write to a file descriptor. + ;;; Note: This is similar to `writev` in POSIX. + (@interface func (export "write") + (param $fd $fd) + ;;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_array) + (result $error $errno) + ;;; The number of bytes written. + (result $nwritten $size) + ) +) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx new file mode 100644 index 000000000..16c974692 --- /dev/null +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -0,0 +1,160 @@ +;; WASI Filesystem Path API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_path + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Create a directory. + ;;; Note: This is similar to `mkdirat` in POSIX. + (@interface func (export "create_directory") + (param $fd $fd) + ;;; The path at which to create the directory. + (param $path string) + (result $error $errno) + ) + + ;;; Return the attributes of a file or directory. + ;;; Note: This is similar to `stat` in POSIX. + (@interface func (export "filestat_get") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags) + ;;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno) + ;;; The buffer where the file's attributes are stored. + (result $buf $filestat) + ) + + ;;; Adjust the timestamps of a file or directory. + ;;; Note: This is similar to `utimensat` in POSIX. + (@interface func (export "filestat_set_times") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags) + ;;; The path of the file or directory to operate on. + (param $path string) + ;;; The desired values of the data access timestamp. + (param $atim $timestamp) + ;;; The desired values of the data modification timestamp. + (param $mtim $timestamp) + ;;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags) + (result $error $errno) + ) + + ;;; Create a hard link. + ;;; Note: This is similar to `linkat` in POSIX. + (@interface func (export "link") + (param $old_fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags) + ;;; The source path from which to link. + (param $old_path string) + ;;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd) + ;;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno) + ) + + ;;; Open a file or directory. + ;; + ;;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;;; file descriptor not currently open; it is randomized to prevent + ;;; applications from depending on making assumptions about indexes, since this + ;;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;;; guaranteed to be less than 2**31. + ;; + ;;; Note: This is similar to `openat` in POSIX. + (@interface func (export "open") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags) + ;;; The relative path of the file or directory to open, relative to the + ;;; `dirfd` directory. + (param $path string) + ;;; The method by which to open the file. + (param $oflags $oflags) + ;;; The initial rights of the newly created file descriptor. The + ;;; implementation is allowed to return a file descriptor with fewer rights + ;;; than specified, if and only if those rights do not apply to the type of + ;;; file being opened. + ;; + ;;; The *base* rights are rights that will apply to operations using the file + ;;; descriptor itself, while the *inheriting* rights are rights that apply to + ;;; file descriptors derived from it. + (param $fs_rights_base $rights) + (param $fs_rights_inherting $rights) + (param $fdflags $fdflags) + (result $error $errno) + ;;; The file descriptor of the file that has been opened. + (result $opened_fd $fd) + ) + + ;;; Read the contents of a symbolic link. + ;;; Note: This is similar to `readlinkat` in POSIX. + (@interface func (export "readlink") + (param $fd $fd) + ;;; The path of the symbolic link from which to read. + (param $path string) + ;;; The buffer to which to write the contents of the symbolic link. + (param $buf (@witx pointer u8)) + (param $buf_len $size) + (result $error $errno) + ;;; The number of bytes placed in the buffer. + (result $bufused $size) + ) + + ;;; Remove a directory. + ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (@interface func (export "remove_directory") + (param $fd $fd) + ;;; The path to a directory to remove. + (param $path string) + (result $error $errno) + ) + + ;;; Rename a file or directory. + ;;; Note: This is similar to `renameat` in POSIX. + (@interface func (export "rename") + (param $fd $fd) + ;;; The source path of the file or directory to rename. + (param $old_path string) + ;;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd) + ;;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno) + ) + + ;;; Create a symbolic link. + ;;; Note: This is similar to `symlinkat` in POSIX. + (@interface func (export "symlink") + ;;; The contents of the symbolic link. + (param $old_path string) + (param $fd $fd) + ;;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno) + ) + + + ;;; Unlink a file. + ;;; Return `EISDIR` if the path refers to a directory. + ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (@interface func (export "unlink_file") + (param $fd $fd) + ;;; The path to a file to unlink. + (param $path string) + (result $error $errno) + ) +) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx new file mode 100644 index 000000000..7dcdb53e6 --- /dev/null +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx @@ -0,0 +1,26 @@ +;; WASI Poll API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_poll + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Concurrently poll for the occurrence of a set of events. + (@interface func (export "oneoff") + ;;; The events to which to subscribe. + (param $in (@witx const_pointer $subscription)) + ;;; The events that have occurred. + (param $out (@witx pointer $event)) + ;;; Both the number of subscriptions and events. + (param $nsubscriptions $size) + (result $error $errno) + ;;; The number of events stored. + (result $nevents $size) + ) +) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx deleted file mode 100644 index 50bf519e7..000000000 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ /dev/null @@ -1,523 +0,0 @@ -;; WASI Preview. This is an evolution of the API that WASI initially -;; launched with. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_preview - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `wasi_args_sizes_get()` - (@interface func (export "args_get") - (param $argv (@witx pointer (@witx pointer u8))) - (param $argv_buf (@witx pointer u8)) - (result $error $errno) - ) - ;;; Return command-line argument data sizes. - (@interface func (export "args_sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) - ) - - ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. - (@interface func (export "environ_get") - (param $environ (@witx pointer (@witx pointer u8))) - (param $environ_buf (@witx pointer u8)) - (result $error $errno) - ) - ;;; Return command-line argument data sizes. - (@interface func (export "environ_sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) - ) - - ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;;; Note: This is similar to `clock_getres` in POSIX. - (@interface func (export "clock_res_get") - (result $error $errno) - ;;; The clock for which to return the resolution. - (param $id $clockid) - ;;; The resolution of the clock. - (result $resolution $timestamp) - ) - ;;; Return the time value of a clock. - ;;; Note: This is similar to `clock_gettime` in POSIX. - (@interface func (export "clock_time_get") - ;;; The clock for which to return the time. - (param $id $clockid) - ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp) - (result $error $errno) - ;;; The time value of the clock. - (result $time $timestamp) - ) - - ;;; Provide file advisory information on a file descriptor. - ;;; Note: This is similar to `posix_fadvise` in POSIX. - (@interface func (export "fd_advise") - (param $fd $fd) - ;;; The offset within the file to which the advisory applies. - (param $offset $filesize) - ;;; The length of the region to which the advisory applies. - (param $len $filesize) - ;;; The advice. - (param $advice $advice) - (result $error $errno) - ) - - ;;; Force the allocation of space in a file. - ;;; Note: This is similar to `posix_fallocate` in POSIX. - (@interface func (export "fd_allocate") - (param $fd $fd) - ;;; The offset at which to start the allocation. - (param $offset $filesize) - ;;; The length of the area that is allocated. - (param $len $filesize) - (result $error $errno) - ) - - ;;; Close a file descriptor. - ;;; Note: This is similar to `close` in POSIX. - (@interface func (export "fd_close") - (param $fd $fd) - (result $error $errno) - ) - - ;;; Synchronize the data of a file to disk. - ;;; Note: This is similar to `fdatasync` in POSIX. - (@interface func (export "fd_datasync") - (param $fd $fd) - (result $error $errno) - ) - - ;;; Get the attributes of a file descriptor. - ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (@interface func (export "fd_fdstat_get") - (param $fd $fd) - (result $error $errno) - ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat) - ) - - ;;; Adjust the flags associated with a file descriptor. - ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd) - ;;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error $errno) - ) - - ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights - (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd) - ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (result $error $errno) - ) - - ;;; Return the attributes of an open file. - (@interface func (export "fd_filestat_get") - (param $fd $fd) - (result $error $errno) - ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) - ) - - ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;;; Note: This is similar to `ftruncate` in POSIX. - (@interface func (export "fd_filestat_set_size") - (param $fd $fd) - ;;; The desired file size. - (param $size $filesize) - (result $error $errno) - ) - - ;;; Adjust the timestamps of an open file or directory. - ;;; Note: This is similar to `futimens` in POSIX. - (@interface func (export "fd_filestat_set_times") - (param $fd $fd) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error $errno) - ) - - ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in POSIX. - (@interface func (export "fd_pread") - (param $fd $fd) - ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_array) - ;;; The offset within the file at which to read. - (param $offset $filesize) - (result $error $errno) - ;;; The number of bytes read. - (result $nread $size) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_get") - (param $fd $fd) - (result $error $errno) - ;;; The buffer where the description is stored. - (result $buf $prestat) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_dir_name") - (param $fd $fd) - ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer u8)) - (param $path_len $size) - (result $error $errno) - ) - - ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in POSIX. - (@interface func (export "fd_pwrite") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The offset within the file at which to write. - (param $offset $filesize) - (result $error $errno) - ;;; The number of bytes written. - (result $nwritten $size) - ) - - ;;; Read from a file descriptor. - ;;; Note: This is similar to `readv` in POSIX. - (@interface func (export "fd_read") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_array) - (result $error $errno) - ;;; The number of bytes read. - (result $nread $size) - ) - - ;;; Read directory entries from a directory. - ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a dirent_t object, - ;;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;;; entry. - ;; - ;;; This function fills the output buffer as much as possible, potentially - ;;; truncating the last directory entry. This allows the caller to grow its - ;;; read buffer size in case it's too small to fit a single large directory - ;;; entry, or skip the oversized directory entry. - (@interface func (export "fd_readdir") - (param $fd $fd) - ;;; The buffer where directory entries are stored - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The location within the directory to start reading - (param $cookie $dircookie) - (result $error $errno) - ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size) - ) - - ;;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;;; Due to the strong focus on thread safety, this environment does not provide - ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;;; file descriptor with the same number could be allocated by a different - ;;; thread at the same time. - ;; - ;;; This function provides a way to atomically renumber file descriptors, which - ;;; would disappear if `dup2()` were to be removed entirely. - (@interface func (export "fd_renumber") - (param $fd $fd) - ;;; The file descriptor to overwrite. - (param $to $fd) - (result $error $errno) - ) - - ;;; Move the offset of a file descriptor. - ;;; Note: This is similar to `lseek` in POSIX. - (@interface func (export "fd_seek") - (param $fd $fd) - ;;; The number of bytes to move. - (param $offset $filedelta) - ;;; The base from which the offset is relative. - (param $whence $whence) - (result $error $errno) - ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize) - ) - - ;;; Synchronize the data and metadata of a file to disk. - ;;; Note: This is similar to `fsync` in POSIX. - (@interface func (export "fd_sync") - (param $fd $fd) - (result $error $errno) - ) - - ;;; Return the current offset of a file descriptor. - ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (@interface func (export "fd_tell") - (param $fd $fd) - (result $error $errno) - ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize) - ) - - ;;; Write to a file descriptor. - ;;; Note: This is similar to `writev` in POSIX. - (@interface func (export "fd_write") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - (result $error $errno) - ;;; The number of bytes written. - (result $nwritten $size) - ) - - ;;; Create a directory. - ;;; Note: This is similar to `mkdirat` in POSIX. - (@interface func (export "path_create_directory") - (param $fd $fd) - ;;; The path at which to create the directory. - (param $path string) - (result $error $errno) - ) - - ;;; Return the attributes of a file or directory. - ;;; Note: This is similar to `stat` in POSIX. - (@interface func (export "path_filestat_get") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to inspect. - (param $path string) - (result $error $errno) - ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) - ) - - ;;; Adjust the timestamps of a file or directory. - ;;; Note: This is similar to `utimensat` in POSIX. - (@interface func (export "path_filestat_set_times") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to operate on. - (param $path string) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error $errno) - ) - - ;;; Create a hard link. - ;;; Note: This is similar to `linkat` in POSIX. - (@interface func (export "path_link") - (param $old_fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags) - ;;; The source path from which to link. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path at which to create the hard link. - (param $new_path string) - (result $error $errno) - ) - - ;;; Open a file or directory. - ;; - ;;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;;; file descriptor not currently open; it is randomized to prevent - ;;; applications from depending on making assumptions about indexes, since this - ;;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;;; guaranteed to be less than 2**31. - ;; - ;;; Note: This is similar to `openat` in POSIX. - (@interface func (export "path_open") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags) - ;;; The relative path of the file or directory to open, relative to the - ;;; `dirfd` directory. - (param $path string) - ;;; The method by which to open the file. - (param $oflags $oflags) - ;;; The initial rights of the newly created file descriptor. The - ;;; implementation is allowed to return a file descriptor with fewer rights - ;;; than specified, if and only if those rights do not apply to the type of - ;;; file being opened. - ;; - ;;; The *base* rights are rights that will apply to operations using the file - ;;; descriptor itself, while the *inheriting* rights are rights that apply to - ;;; file descriptors derived from it. - (param $fs_rights_base $rights) - (param $fs_rights_inherting $rights) - (param $fdflags $fdflags) - (result $error $errno) - ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd) - ) - - ;;; Read the contents of a symbolic link. - ;;; Note: This is similar to `readlinkat` in POSIX. - (@interface func (export "path_readlink") - (param $fd $fd) - ;;; The path of the symbolic link from which to read. - (param $path string) - ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error $errno) - ;;; The number of bytes placed in the buffer. - (result $bufused $size) - ) - - ;;; Remove a directory. - ;;; Return `ENOTEMPTY` if the directory is not empty. - ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (@interface func (export "path_remove_directory") - (param $fd $fd) - ;;; The path to a directory to remove. - (param $path string) - (result $error $errno) - ) - - ;;; Rename a file or directory. - ;;; Note: This is similar to `renameat` in POSIX. - (@interface func (export "path_rename") - (param $fd $fd) - ;;; The source path of the file or directory to rename. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error $errno) - ) - - ;;; Create a symbolic link. - ;;; Note: This is similar to `symlinkat` in POSIX. - (@interface func (export "path_symlink") - ;;; The contents of the symbolic link. - (param $old_path string) - (param $fd $fd) - ;;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error $errno) - ) - - - ;;; Unlink a file. - ;;; Return `EISDIR` if the path refers to a directory. - ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (@interface func (export "path_unlink_file") - (param $fd $fd) - ;;; The path to a file to unlink. - (param $path string) - (result $error $errno) - ) - - ;;; Concurrently poll for the occurrence of a set of events. - (@interface func (export "poll_oneoff") - ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription)) - ;;; The events that have occurred. - (param $out (@witx pointer $event)) - ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size) - (result $error $errno) - ;;; The number of events stored. - (result $nevents $size) - ) - - ;;; Terminate the process normally. An exit code of 0 indicates successful - ;;; termination of the program. The meanings of other values is dependent on - ;;; the environment. - (@interface func (export "proc_exit") - ;;; The exit code returned by the process. - (param $rval $exitcode) - ) - - ;;; Temporarily yield execution of the calling thread. - ;;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "sched_yield") - (result $error $errno) - ) - - ;;; Write high-quality random data into a buffer. - ;;; This function blocks when the implementation is unable to immediately - ;;; provide sufficient high-quality random data. - ;;; This function may execute slowly, so when large mounts of random data are - ;;; required, it's advisable to use this function to seed a pseudo-random - ;;; number generator, rather than to provide the random data directly. - (@interface func (export "random_get") - ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error $errno) - ) - - ;;; Receive a message from a socket. - ;;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;;; the data into multiple buffers in the manner of `readv`. - (@interface func (export "sock_recv") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_array) - ;;; Message flags. - (param $ri_flags $riflags) - (result $error $errno) - ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size) - ;;; Message flags. - (result $ro_flags $roflags) - ) - - ;;; Send a message on a socket. - ;;; Note: This is similar to `send` in POSIX, though it also supports writing - ;;; the data from multiple buffers in the manner of `writev`. - (@interface func (export "sock_send") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_array) - ;;; Message flags. - (param $si_flags $siflags) - (result $error $errno) - ;;; Number of bytes transmitted. - (result $so_datalen $size) - ) - - ;;; Shut down socket send and receive channels. - ;;; Note: This is similar to `shutdown` in POSIX. - (@interface func (export "sock_shutdown") - (param $fd $fd) - ;;; Which channels on the socket to shut down. - (param $how $sdflags) - (result $error $errno) - ) -) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx new file mode 100644 index 000000000..5e53a83ec --- /dev/null +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx @@ -0,0 +1,18 @@ +;; WASI Process API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_proc + ;;; Terminate the process normally. An exit code of 0 indicates successful + ;;; termination of the program. The meanings of other values is dependent on + ;;; the environment. + (@interface func (export "exit") + ;;; The exit code returned by the process. + (param $rval $exitcode) + ) +) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx new file mode 100644 index 000000000..55c6df021 --- /dev/null +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx @@ -0,0 +1,26 @@ +;; WASI Random API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_random + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Write high-quality random data into a buffer. + ;;; This function blocks when the implementation is unable to immediately + ;;; provide sufficient high-quality random data. + ;;; This function may execute slowly, so when large mounts of random data are + ;;; required, it's advisable to use this function to seed a pseudo-random + ;;; number generator, rather than to provide the random data directly. + (@interface func (export "get") + ;;; The buffer to fill with random data. + (param $buf (@witx pointer u8)) + (param $buf_len $size) + (result $error $errno) + ) +) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sched.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sched.witx new file mode 100644 index 000000000..799a75fa9 --- /dev/null +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sched.witx @@ -0,0 +1,16 @@ +;; WASI Scheduler API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_sched + ;;; Temporarily yield execution of the calling thread. + ;;; Note: This is similar to `yield` in POSIX. + (@interface func (export "yield") + (result $error $errno) + ) +) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sock.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sock.witx new file mode 100644 index 000000000..becf80ffc --- /dev/null +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sock.witx @@ -0,0 +1,52 @@ +;; WASI Sockets. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_sock + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Receive a message from a socket. + ;;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;;; the data into multiple buffers in the manner of `readv`. + (@interface func (export "recv") + (param $fd $fd) + ;;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_array) + ;;; Message flags. + (param $ri_flags $riflags) + (result $error $errno) + ;;; Number of bytes stored in ri_data. + (result $ro_datalen $size) + ;;; Message flags. + (result $ro_flags $roflags) + ) + + ;;; Send a message on a socket. + ;;; Note: This is similar to `send` in POSIX, though it also supports writing + ;;; the data from multiple buffers in the manner of `writev`. + (@interface func (export "send") + (param $fd $fd) + ;;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_array) + ;;; Message flags. + (param $si_flags $siflags) + (result $error $errno) + ;;; Number of bytes transmitted. + (result $so_datalen $size) + ) + + ;;; Shut down socket send and receive channels. + ;;; Note: This is similar to `shutdown` in POSIX. + (@interface func (export "shutdown") + (param $fd $fd) + ;;; Which channels on the socket to shut down. + (param $how $sdflags) + (result $error $errno) + ) +) From 436781b02568a0f7d9c372666583c5cc39dc7caf Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 25 Sep 2019 23:42:49 -0700 Subject: [PATCH 0324/1772] Modularize the WASI API. This splits what was previously "preview" into separate modules. There's a lot of API evolution still to be done here, and the groupings presented here may change, but this should help get things started. --- .../ephemeral/docs/wasi_ephemeral_preview.md | 2150 ----------------- .../ephemeral/witx/wasi_ephemeral_args.witx | 28 + .../ephemeral/witx/wasi_ephemeral_clock.witx | 36 + .../witx/wasi_ephemeral_environ.witx | 28 + .../ephemeral/witx/wasi_ephemeral_fd.witx | 242 ++ .../ephemeral/witx/wasi_ephemeral_path.witx | 160 ++ .../ephemeral/witx/wasi_ephemeral_poll.witx | 26 + .../witx/wasi_ephemeral_preview.witx | 523 ---- .../ephemeral/witx/wasi_ephemeral_proc.witx | 18 + .../ephemeral/witx/wasi_ephemeral_random.witx | 26 + .../ephemeral/witx/wasi_ephemeral_sched.witx | 16 + .../ephemeral/witx/wasi_ephemeral_sock.witx | 52 + 12 files changed, 632 insertions(+), 2673 deletions(-) delete mode 100644 proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md create mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx create mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx create mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx create mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx create mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx create mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx delete mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx create mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx create mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx create mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sched.witx create mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sock.witx diff --git a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md b/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md deleted file mode 100644 index 087716fa5..000000000 --- a/proposals/filesystem/phases/ephemeral/docs/wasi_ephemeral_preview.md +++ /dev/null @@ -1,2150 +0,0 @@ - - -# The WASI Preview API - -This is the API-level documentation for WASI Preview. The function names -are prefixed with "\_\_wasi\_" to reflect how they are spelled in -flat-namespace contexts, however at the wasm module level, they are -unprefixed, because they're inside a module namespace. - -Functions that start with `__wasi_fd_` operate on file descriptors, -while functions that start with `__wasi_path_` operate on filesystem -paths, which are relative to directory file descriptors. - -Much inspiration and content here is derived from [CloudABI] and [POSIX], -though there are also several differences from CloudABI and POSIX. For -example, WASI Preview has no concept of processes in the traditional Unix -sense. While wasm linear memories have some of the aspects of processes, -and it's possible to *emulate* the full semantics of processes on top of -them, this can sometimes be unnatural and inefficient. The goal for -WASI Preview is to be a WebAssembly-native API that exposes APIs that fit -well into the underlying WebAssembly platform, rather than to directly -emulate other platforms. - -This is also a work in progress, and the API here is still evolving. - -Historical note: this API was originally named "WASI Core", and used the -API module name "wasi\_unstable". We've since sought to deemphasize the -"Core" name, as the goal is to split this API up into independent -modules so that embedders need not implement all of it. - -[CloudABI]: https://github.com/NuxiNL/cloudabi -[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ - -## System calls - -- [`__wasi_args_get()`](#args_get) -- [`__wasi_args_sizes_get()`](#args_sizes_get) -- [`__wasi_clock_res_get()`](#clock_res_get) -- [`__wasi_clock_time_get()`](#clock_time_get) -- [`__wasi_environ_get()`](#environ_get) -- [`__wasi_environ_sizes_get()`](#environ_sizes_get) -- [`__wasi_fd_advise()`](#fd_advise) -- [`__wasi_fd_allocate()`](#fd_allocate) -- [`__wasi_fd_close()`](#fd_close) -- [`__wasi_fd_datasync()`](#fd_datasync) -- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) -- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) -- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) -- [`__wasi_fd_filestat_get()`](#fd_filestat_get) -- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) -- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) -- [`__wasi_fd_pread()`](#fd_pread) -- [`__wasi_fd_prestat_get()`](#fd_prestat_get) -- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) -- [`__wasi_fd_pwrite()`](#fd_pwrite) -- [`__wasi_fd_read()`](#fd_read) -- [`__wasi_fd_readdir()`](#fd_readdir) -- [`__wasi_fd_renumber()`](#fd_renumber) -- [`__wasi_fd_seek()`](#fd_seek) -- [`__wasi_fd_sync()`](#fd_sync) -- [`__wasi_fd_tell()`](#fd_tell) -- [`__wasi_fd_write()`](#fd_write) -- [`__wasi_path_create_directory()`](#path_create_directory) -- [`__wasi_path_filestat_get()`](#path_filestat_get) -- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) -- [`__wasi_path_link()`](#path_link) -- [`__wasi_path_open()`](#path_open) -- [`__wasi_path_readlink()`](#path_readlink) -- [`__wasi_path_remove_directory()`](#path_remove_directory) -- [`__wasi_path_rename()`](#path_rename) -- [`__wasi_path_symlink()`](#path_symlink) -- [`__wasi_path_unlink_file()`](#path_unlink_file) -- [`__wasi_poll_oneoff()`](#poll_oneoff) -- [`__wasi_proc_exit()`](#proc_exit) -- [`__wasi_random_get()`](#random_get) -- [`__wasi_sched_yield()`](#sched_yield) -- [`__wasi_sock_recv()`](#sock_recv) -- [`__wasi_sock_send()`](#sock_send) -- [`__wasi_sock_shutdown()`](#sock_shutdown) - -### `__wasi_args_get()` - -Read command-line argument data. - -Inputs: - -- char \*\*argv - - A pointer to a buffer to write the argument pointers. - - The count of elements for the buffer should be at least the value of `argc` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - - The caller of `__wasi_args_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. - -- char \*argv\_buf - - A pointer to a buffer to write the argument string data. - - The size of this buffer should be the value of `argv_buf_size` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - -### `__wasi_args_sizes_get()` - -Return command-line argument data sizes. - -Outputs: - -- size\_t \*argc - - The number of arguments. - -- size\_t \*argv\_buf\_size - - The size of the argument string data. - -### `__wasi_clock_res_get()` - -Return the resolution of a clock. - -Implementations are required to provide a non-zero value for supported clocks. -For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). - -Note: This is similar to `clock_getres` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the resolution. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) resolution - - The resolution of the clock. - -### `__wasi_clock_time_get()` - -Return the time value of a clock. - -Note: This is similar to `clock_gettime` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the time. - -- [\_\_wasi\_timestamp\_t](#timestamp) precision - - The maximum lag (exclusive) that the returned - time value may have, compared to its actual - value. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) time - - The time value of the clock. - -### `__wasi_environ_get()` - -Read environment variable data. - -Inputs: - -- char \*\*environ - - A pointer to a buffer to write the environment variable pointers. - - The count of elements for the buffer should be at least the value of `environ_count` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - - The caller of `__wasi_environ_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. - -- char \*environ\_buf - - A pointer to a buffer to write the environment variable string data. - - The size of this buffer should be the value of `environ_buf_size` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - -### `__wasi_environ_sizes_get()` - -Return enviroment variable data sizes. - -Outputs: - -- size\_t \*environ\_count - - The number of environment variables. - -- size\_t \*environ\_buf\_size - - The size of the environment variable string data. - -### `__wasi_fd_advise()` - -Provide file advisory information on a file descriptor. - -Note: This is similar to `posix_fadvise` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file for which to provide file advisory information. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file to which the advisory applies. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the region to which the advisory applies. - -- [\_\_wasi\_advice\_t](#advice) advice - - The advice. - -### `__wasi_fd_allocate()` - -Force the allocation of space in a file. - -Note: This is similar to `posix_fallocate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file in which to allocate space. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset at which to start the allocation. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the area that is allocated. - -### `__wasi_fd_close()` - -Close a file descriptor. - -Note: This is similar to `close` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to close. - -### `__wasi_fd_datasync()` - -Synchronize the data of a file to disk. - -Note: This is similar to `fdatasync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file to synchronize to disk. - -### `__wasi_fd_fdstat_get()` - -Get the attributes of a file descriptor. - -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well -as additional fields. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_fdstat\_t](#fdstat) \*buf - - The buffer where the file descriptor's attributes are stored. - -### `__wasi_fd_fdstat_set_flags()` - -Adjust the flags associated with a file descriptor. - -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_fdflags\_t](#fdflags) flags - - The desired values of the file descriptor - flags. - -### `__wasi_fd_fdstat_set_rights()` - -Adjust the rights associated with a file descriptor. - -This can only be used to remove rights, and returns -[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt -to add rights. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The desired rights of the file descriptor. - -### `__wasi_fd_filestat_get()` - -Return the attributes of an open file. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_fd_filestat_set_size()` - -Adjust the size of an open file. If this increases the file's size, the extra -bytes are filled with zeros. - -Note: This is similar to `ftruncate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - A file descriptor for the file to adjust. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - The desired file size. - -### `__wasi_fd_filestat_set_times()` - -Adjust the timestamps of an open file or directory. - -Note: This is similar to `futimens` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_fd_pread()` - -Read from a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `preadv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors in which to store data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to read. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_prestat_get()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- [\_\_wasi\_prestat\_t](#prestat) \*buf - - The buffer where the description is stored. - -### `__wasi_fd_prestat_dir_name()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- const char \*path and size\_t path\_len - - A buffer into which to write the preopened directory name. - -### `__wasi_fd_pwrite()` - -Write to a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `pwritev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to write. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_fd_read()` - -Read from a file descriptor. - -Note: This is similar to `readv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors to which to store data. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_readdir()` - -Read directory entries from a directory. - -When successful, the contents of the output buffer consist of -a sequence of directory entries. Each directory entry consists -of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes -holding the name of the directory entry. - -This function fills the output buffer as much as possible, -potentially truncating the last directory entry. This allows -the caller to grow its read buffer size in case it's too small -to fit a single large directory entry, or skip the oversized -directory entry. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The directory from which to read the directory - entries. - -- void \*buf and size\_t buf\_len - - The buffer where directory entries are stored. - -- [\_\_wasi\_dircookie\_t](#dircookie) cookie - - The location within the directory to start - reading. - -Outputs: - -- size\_t bufused - - The number of bytes stored in the read buffer. - If less than the size of the read buffer, the - end of the directory has been reached. - -### `__wasi_fd_renumber()` - -Atomically replace a file descriptor by renumbering another -file descriptor. - -Due to the strong focus on thread safety, this environment -does not provide a mechanism to duplicate or renumber a file -descriptor to an arbitrary number, like dup2(). This would be -prone to race conditions, as an actual file descriptor with the -same number could be allocated by a different thread at the same -time. - -This function provides a way to atomically renumber file -descriptors, which would disappear if dup2() were to be -removed entirely. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) from - - The file descriptor to renumber. - -- [\_\_wasi\_fd\_t](#fd) to - - The file descriptor to overwrite. - -### `__wasi_fd_seek()` - -Move the offset of a file descriptor. - -Note: This is similar to `lseek` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_filedelta\_t](#filedelta) offset - - The number of bytes to move. - -- [\_\_wasi\_whence\_t](#whence) whence - - The base from which the offset is relative. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) newoffset - - The new offset of the file descriptor, - relative to the start of the file. - -### `__wasi_fd_sync()` - -Synchronize the data and metadata of a file to disk. - -Note: This is similar to `fsync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file containing the data - and metadata to synchronize to disk. - -### `__wasi_fd_tell()` - -Return the current offset of a file descriptor. - -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The current offset of the file descriptor, relative to the start of the file. - -### `__wasi_fd_write()` - -Write to a file descriptor. - -Note: This is similar to `writev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_path_create_directory()` - -Create a directory. - -Note: This is similar to `mkdirat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path at which to create the directory. - -### `__wasi_path_filestat_get()` - -Return the attributes of a file or directory. - -Note: This is similar to `stat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_path_filestat_set_times()` - -Adjust the timestamps of a file or directory. - -Note: This is similar to `utimensat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_path_link()` - -Create a hard link. - -Note: This is similar to `linkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags - - Flags determining the method of how the path is resolved. - -- const char \*old\_path and size\_t old\_path\_len - - The source path from which to link. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the hard link. - -### `__wasi_path_open()` - -Open a file or directory. - -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since -this is error-prone in multi-threaded contexts. The returned file -descriptor is guaranteed to be less than 231. - -Note: This is similar to `openat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) dirfd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The relative path of the file or directory to open, relative to - the [`dirfd`](#path_open.dirfd) directory. - -- [\_\_wasi\_oflags\_t](#oflags) o_flags - - The method by which to open the file. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The initial rights of the newly created file descriptor. The - implementation is allowed to return a file descriptor with fewer - rights than specified, if and only if those rights do not apply - to the type of file being opened. - - The *base* rights are rights that will apply to operations using - the file descriptor itself, while the *inheriting* rights are - rights that apply to file descriptors derived from it. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - The initial flags of the file descriptor. - -Outputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file that has been - opened. - -### `__wasi_path_readlink()` - -Read the contents of a symbolic link. - -Note: This is similar to `readlinkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path of the symbolic link from which to read. - -- char \*buf and size\_t buf\_len - - The buffer to which to write the contents of the symbolic link. - -Outputs: - -- size\_t bufused - - The number of bytes placed in the buffer. - -### `__wasi_path_remove_directory()` - -Remove a directory. - -Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. - -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a directory to remove. - -### `__wasi_path_rename()` - -Rename a file or directory. - -Note: This is similar to `renameat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- const char \*old\_path and size\_t old\_path\_len - - The source path of the file or directory to rename. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path to which to rename the file or directory. - -### `__wasi_path_symlink()` - -Create a symbolic link. - -Note: This is similar to `symlinkat` in POSIX. - -Inputs: - -- const char \*old\_path and size\_t old_path\_len - - The contents of the symbolic link. - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the symbolic link. - -### `__wasi_path_unlink_file()` - -Unlink a file. - -Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. - -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a file to unlink. - -### `__wasi_poll_oneoff()` - -Concurrently poll for the occurrence of a set of events. - -Inputs: - -- const [\_\_wasi\_subscription\_t](#subscription) \*in - - The events to which to subscribe. - -- [\_\_wasi\_event\_t](#event) \*out - - The events that have occurred. - -- size\_t nsubscriptions - - Both the number of subscriptions and events. - -Outputs: - -- size\_t nevents - - The number of events stored. - -### `__wasi_proc_exit()` - -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -Note: This is similar to `_Exit` in POSIX. - -Inputs: - -- [\_\_wasi\_exitcode\_t](#exitcode) rval - - The exit code returned by the process. - -Does not return. - -### `__wasi_random_get()` - -Write high-quality random data into a buffer. - -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. - -This function may execute slowly, so when large mounts of random -data are required, it's advisable to use this function to seed a -pseudo-random number generator, rather than to provide the -random data directly. - -Inputs: - -- void \*buf and size\_t buf\_len - - The buffer to fill with random data. - -### `__wasi_sched_yield()` - -Temporarily yield execution of the calling thread. - -Note: This is similar to `sched_yield` in POSIX. - -### `__wasi_sock_recv()` - -Receive a message from a socket. - -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to receive data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len - - List of scatter/gather vectors to which to store data. - -- [\_\_wasi\_riflags\_t](#riflags) ri\_flags - - Message flags. - -Outputs: - -- size\_t ro\_datalen - - Number of bytes stored in [`ri_data`](#sock_recv.ri_data). - -- [\_\_wasi\_roflags\_t](#roflags) ro\_flags - - Message flags. - -### `__wasi_sock_send()` - -Send a message on a socket. - -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to send data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len - - List of scatter/gather vectors to which to retrieve data - -- [\_\_wasi\_siflags\_t](#siflags) si\_flags - - Message flags. - -Outputs: - -- size\_t so\_datalen - - Number of bytes transmitted. - -### `__wasi_sock_shutdown()` - -Shut down socket send and receive channels. - -Note: This is similar to `shutdown` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to shutdown channels. - -- [\_\_wasi\_sdflags\_t](#sdflags) how - - Which channels on the socket to shut down. - -## Types - -### `__wasi_advice_t` (`uint8_t`) - -File or memory access pattern advisory information. - -Used by [`__wasi_fd_advise()`](#fd_advise). - -Possible values: - -- **`__WASI_ADVICE_NORMAL`** - - The application has no advice to give on its behavior - with respect to the specified data. - -- **`__WASI_ADVICE_SEQUENTIAL`** - - The application expects to access the specified data - sequentially from lower offsets to higher offsets. - -- **`__WASI_ADVICE_RANDOM`** - - The application expects to access the specified data - in a random order. - -- **`__WASI_ADVICE_WILLNEED`** - - The application expects to access the specified data - in the near future. - -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - -### `__wasi_ciovec_t` (`struct`) - -A region of memory for scatter/gather writes. - -Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). - -Members: - -- const void \*buf and size\_t buf\_len - - The address and length of the buffer to be written. - -### `__wasi_clockid_t` (`uint32_t`) - -Identifiers for clocks. - -Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). - -Possible values: - -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - -- **`__WASI_CLOCK_MONOTONIC`** - - The store-wide monotonic clock, which is defined as a - clock measuring real time, whose value cannot be - adjusted and which cannot have negative clock jumps. - - The epoch of this clock is undefined. The absolute - time value of this clock therefore has no meaning. - -- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** - - The CPU-time clock associated with the current - process. - -- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** - - The CPU-time clock associated with the current thread. - -### `__wasi_device_t` (`uint64_t`) - -Identifier for a device containing a file system. Can be used -in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or -directory in the filesystem. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_dircookie_t` (`uint64_t`) - -A reference to the offset of a directory entry. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). - -Special values: - -- **`__WASI_DIRCOOKIE_START`** - - Permanent reference to the first directory entry - within a directory. - -### `__wasi_dirent_t` (`struct`) - -A directory entry. - -Members: - -- [\_\_wasi\_dircookie\_t](#dircookie) d\_next - - The offset of the next directory entry stored in this - directory. - -- [\_\_wasi\_inode\_t](#inode) d\_ino - - The serial number of the file referred to by this - directory entry. - -- uint32\_t d\_namlen - - The length of the name of the directory entry. - -- [\_\_wasi\_filetype\_t](#filetype) d\_type - - The type of the file referred to by this directory - entry. - -### `__wasi_errno_t` (`uint16_t`) - -Error codes returned by functions. - -Not all of these error codes are returned by the functions -provided by this API; some are used in higher-level library layers, -and others are provided merely for alignment with POSIX. - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_ESUCCESS`** - - No error occurred. System call completed successfully. - -- **`__WASI_E2BIG`** - - Argument list too long. - -- **`__WASI_EACCES`** - - Permission denied. - -- **`__WASI_EADDRINUSE`** - - Address in use. - -- **`__WASI_EADDRNOTAVAIL`** - - Address not available. - -- **`__WASI_EAFNOSUPPORT`** - - Address family not supported. - -- **`__WASI_EAGAIN`** - - Resource unavailable, or operation would block. - -- **`__WASI_EALREADY`** - - Connection already in progress. - -- **`__WASI_EBADF`** - - Bad file descriptor. - -- **`__WASI_EBADMSG`** - - Bad message. - -- **`__WASI_EBUSY`** - - Device or resource busy. - -- **`__WASI_ECANCELED`** - - Operation canceled. - -- **`__WASI_ECHILD`** - - No child processes. - -- **`__WASI_ECONNABORTED`** - - Connection aborted. - -- **`__WASI_ECONNREFUSED`** - - Connection refused. - -- **`__WASI_ECONNRESET`** - - Connection reset. - -- **`__WASI_EDEADLK`** - - Resource deadlock would occur. - -- **`__WASI_EDESTADDRREQ`** - - Destination address required. - -- **`__WASI_EDOM`** - - Mathematics argument out of domain of function. - -- **`__WASI_EDQUOT`** - - Reserved. - -- **`__WASI_EEXIST`** - - File exists. - -- **`__WASI_EFAULT`** - - Bad address. - -- **`__WASI_EFBIG`** - - File too large. - -- **`__WASI_EHOSTUNREACH`** - - Host is unreachable. - -- **`__WASI_EIDRM`** - - Identifier removed. - -- **`__WASI_EILSEQ`** - - Illegal byte sequence. - -- **`__WASI_EINPROGRESS`** - - Operation in progress. - -- **`__WASI_EINTR`** - - Interrupted function. - -- **`__WASI_EINVAL`** - - Invalid argument. - -- **`__WASI_EIO`** - - I/O error. - -- **`__WASI_EISCONN`** - - Socket is connected. - -- **`__WASI_EISDIR`** - - Is a directory. - -- **`__WASI_ELOOP`** - - Too many levels of symbolic links. - -- **`__WASI_EMFILE`** - - File descriptor value too large. - -- **`__WASI_EMLINK`** - - Too many links. - -- **`__WASI_EMSGSIZE`** - - Message too large. - -- **`__WASI_EMULTIHOP`** - - Reserved. - -- **`__WASI_ENAMETOOLONG`** - - Filename too long. - -- **`__WASI_ENETDOWN`** - - Network is down. - -- **`__WASI_ENETRESET`** - - Connection aborted by network. - -- **`__WASI_ENETUNREACH`** - - Network unreachable. - -- **`__WASI_ENFILE`** - - Too many files open in system. - -- **`__WASI_ENOBUFS`** - - No buffer space available. - -- **`__WASI_ENODEV`** - - No such device. - -- **`__WASI_ENOENT`** - - No such file or directory. - -- **`__WASI_ENOEXEC`** - - Executable file format error. - -- **`__WASI_ENOLCK`** - - No locks available. - -- **`__WASI_ENOLINK`** - - Reserved. - -- **`__WASI_ENOMEM`** - - Not enough space. - -- **`__WASI_ENOMSG`** - - No message of the desired type. - -- **`__WASI_ENOPROTOOPT`** - - Protocol not available. - -- **`__WASI_ENOSPC`** - - No space left on device. - -- **`__WASI_ENOSYS`** - - Function not supported. - -- **`__WASI_ENOTCONN`** - - The socket is not connected. - -- **`__WASI_ENOTDIR`** - - Not a directory or a symbolic link to a directory. - -- **`__WASI_ENOTEMPTY`** - - Directory not empty. - -- **`__WASI_ENOTRECOVERABLE`** - - State not recoverable. - -- **`__WASI_ENOTSOCK`** - - Not a socket. - -- **`__WASI_ENOTSUP`** - - Not supported, or operation not supported on socket. - -- **`__WASI_ENOTTY`** - - Inappropriate I/O control operation. - -- **`__WASI_ENXIO`** - - No such device or address. - -- **`__WASI_EOVERFLOW`** - - Value too large to be stored in data type. - -- **`__WASI_EOWNERDEAD`** - - Previous owner died. - -- **`__WASI_EPERM`** - - Operation not permitted. - -- **`__WASI_EPIPE`** - - Broken pipe. - -- **`__WASI_EPROTO`** - - Protocol error. - -- **`__WASI_EPROTONOSUPPORT`** - - Protocol not supported. - -- **`__WASI_EPROTOTYPE`** - - Protocol wrong type for socket. - -- **`__WASI_ERANGE`** - - Result too large. - -- **`__WASI_EROFS`** - - Read-only file system. - -- **`__WASI_ESPIPE`** - - Invalid seek. - -- **`__WASI_ESRCH`** - - No such process. - -- **`__WASI_ESTALE`** - - Reserved. - -- **`__WASI_ETIMEDOUT`** - - Connection timed out. - -- **`__WASI_ETXTBSY`** - - Text file busy. - -- **`__WASI_EXDEV`** - - Cross-device link. - -- **`__WASI_ENOTCAPABLE`** - - Extension: Capabilities insufficient. - -### `__wasi_event_t` (`struct`) - -An event that occurred. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that got attached to - [`__wasi_subscription_t::userdata`](#subscription.userdata). - -- [\_\_wasi\_errno\_t](#errno) error - - If non-zero, an error that occurred while processing - the subscription request. - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event that occurred. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_filesize\_t](#filesize) nbytes - - The number of bytes available for reading or writing. - - - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags - - The state of the file descriptor. - -### `__wasi_eventrwflags_t` (`uint16_t` bitfield) - -The state of the file descriptor subscribed to with -[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_EVENT_FD_READWRITE_HANGUP`** - - The peer of this socket has closed or disconnected. - -### `__wasi_eventtype_t` (`uint8_t`) - -Type of a subscription to an event or its occurrence. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_EVENTTYPE_CLOCK`** - - The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) - has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -- **`__WASI_EVENTTYPE_FD_READ`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - data available for reading. This event always triggers - for regular files. - -- **`__WASI_EVENTTYPE_FD_WRITE`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - capacity available for writing. This event always - triggers for regular files. - -### `__wasi_exitcode_t` (`uint32_t`) - -Exit code generated by a process when exiting. - -Used by [`__wasi_proc_exit()`](#proc_exit). - -### `__wasi_fd_t` (`uint32_t`) - -A file descriptor number. - -Used by many functions in this API. - -As in POSIX, three file descriptor numbers are provided to instances -on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, -and `STDERR_FILENO`). - -Other than these, WASI implementations are not required to allocate -new file descriptors in ascending order. - -### `__wasi_fdflags_t` (`uint16_t` bitfield) - -File descriptor flags. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_FDFLAG_APPEND`** - - Append mode: Data written to the file is always - appended to the file's end. - -- **`__WASI_FDFLAG_DSYNC`** - - Write according to synchronized I/O data integrity - completion. Only the data stored in the file is - synchronized. - -- **`__WASI_FDFLAG_NONBLOCK`** - - Non-blocking mode. - -- **`__WASI_FDFLAG_RSYNC`** - - Synchronized read I/O operations. - -- **`__WASI_FDFLAG_SYNC`** - - Write according to synchronized I/O file integrity completion. - In addition to synchronizing the data stored in the file, the - implementation may also synchronously update the file's metadata. - -### `__wasi_fdstat_t` (`struct`) - -File descriptor attributes. - -Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). - -Members: - -- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype - - File type. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - File descriptor flags. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base - - Rights that apply to this file descriptor. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - Maximum set of rights that may be installed on new - file descriptors that are created through this file - descriptor, e.g., through [`__wasi_path_open()`](#path_open). - -### `__wasi_filedelta_t` (`int64_t`) - -Relative offset within a file. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -### `__wasi_filesize_t` (`uint64_t`) - -Non-negative file size or length of a region within a file. - -Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -### `__wasi_filestat_t` (`struct`) - -File attributes. - -Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). - -Members: - -- [\_\_wasi\_device\_t](#device) st\_dev - - Device ID of device containing the file. - -- [\_\_wasi\_inode\_t](#inode) st\_ino - - File serial number. - -- [\_\_wasi\_filetype\_t](#filetype) st\_filetype - - File type. - -- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink - - Number of hard links to the file. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - For regular files, the file size in bytes. For - symbolic links, the length in bytes of the pathname - contained in the symbolic link. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - Last data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - Last data modification timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim - - Last file status change timestamp. - -### `__wasi_filetype_t` (`uint8_t`) - -The type of a file descriptor or file. - -Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). - -Possible values: - -- **`__WASI_FILETYPE_UNKNOWN`** - - The type of the file descriptor or file is unknown or - is different from any of the other types specified. - -- **`__WASI_FILETYPE_BLOCK_DEVICE`** - - The file descriptor or file refers to a block device - inode. - -- **`__WASI_FILETYPE_CHARACTER_DEVICE`** - - The file descriptor or file refers to a character - device inode. - -- **`__WASI_FILETYPE_DIRECTORY`** - - The file descriptor or file refers to a directory - inode. - -- **`__WASI_FILETYPE_REGULAR_FILE`** - - The file descriptor or file refers to a regular file - inode. - -- **`__WASI_FILETYPE_SOCKET_DGRAM`** - - The file descriptor or file refers to a datagram - socket. - -- **`__WASI_FILETYPE_SOCKET_STREAM`** - - The file descriptor or file refers to a byte-stream - socket. - -- **`__WASI_FILETYPE_SYMBOLIC_LINK`** - - The file refers to a symbolic link inode. - -### `__wasi_fstflags_t` (`uint16_t` bitfield) - -Which file time attributes to adjust. - -Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -Possible values: - -- **`__WASI_FILESTAT_SET_ATIM`** - - Adjust the last data access timestamp to the value - stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). - -- **`__WASI_FILESTAT_SET_ATIM_NOW`** - - Adjust the last data access timestamp to the time - of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -- **`__WASI_FILESTAT_SET_MTIM`** - - Adjust the last data modification timestamp to the - value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). - -- **`__WASI_FILESTAT_SET_MTIM_NOW`** - - Adjust the last data modification timestamp to the - time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -### `__wasi_inode_t` (`uint64_t`) - -File serial number that is unique within its file system. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). - -### `__wasi_iovec_t` (`struct`) - -A region of memory for scatter/gather reads. - -Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). - -Members: - -- void \*buf and size\_t buf\_len - - The address and length of the buffer to be filled. - -### `__wasi_linkcount_t` (`uint64_t`) - -Number of hard links to an inode. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_lookupflags_t` (`uint32_t` bitfield) - -Flags determining the method of how paths are resolved. - -Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** - - As long as the resolved path corresponds to a symbolic - link, it is expanded. - -### `__wasi_oflags_t` (`uint16_t` bitfield) - -Open flags used by [`__wasi_path_open()`](#path_open). - -Used by [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_O_CREAT`** - - Create file if it does not exist. - -- **`__WASI_O_DIRECTORY`** - - Fail if not a directory. - -- **`__WASI_O_EXCL`** - - Fail if file already exists. - -- **`__WASI_O_TRUNC`** - - Truncate file to size 0. - -### `__wasi_riflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_PEEK`** - - Returns the message without removing it from the - socket's receive queue. - -- **`__WASI_SOCK_RECV_WAITALL`** - - On byte-stream sockets, block until the full amount - of data can be returned. - -### `__wasi_rights_t` (`uint64_t` bitfield) - -File descriptor rights, determining which actions may be -performed. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_RIGHT_FD_DATASYNC`** - - The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_READ`** - - The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke - [`__wasi_fd_pread()`](#fd_pread). - -- **`__WASI_RIGHT_FD_SEEK`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies - [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). - -- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** - - The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). - -- **`__WASI_RIGHT_FD_SYNC`** - - The right to invoke [`__wasi_fd_sync()`](#fd_sync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and - [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_TELL`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the - file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with - offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). - -- **`__WASI_RIGHT_FD_WRITE`** - - The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to - invoke [`__wasi_fd_pwrite()`](#fd_pwrite). - -- **`__WASI_RIGHT_FD_ADVISE`** - - The right to invoke [`__wasi_fd_advise()`](#fd_advise). - -- **`__WASI_RIGHT_FD_ALLOCATE`** - - The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). - -- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** - - The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). - -- **`__WASI_RIGHT_PATH_CREATE_FILE`** - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke - [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). - -- **`__WASI_RIGHT_PATH_LINK_SOURCE`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_LINK_TARGET`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_OPEN`** - - The right to invoke [`__wasi_path_open()`](#path_open). - -- **`__WASI_RIGHT_FD_READDIR`** - - The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). - -- **`__WASI_RIGHT_PATH_READLINK`** - - The right to invoke [`__wasi_path_readlink()`](#path_readlink). - -- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_RENAME_TARGET`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_FILESTAT_GET`** - - The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** - - The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -- **`__WASI_RIGHT_FD_FILESTAT_GET`** - - The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** - - The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). - -- **`__WASI_RIGHT_PATH_SYMLINK`** - - The right to invoke [`__wasi_path_symlink()`](#path_symlink). - -- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** - - The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). - -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - -- **`__WASI_RIGHT_POLL_FD_READWRITE`** - - If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). - - If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -- **`__WASI_RIGHT_SOCK_SHUTDOWN`** - - The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). - -### `__wasi_roflags_t` (`uint16_t` bitfield) - -Flags returned by [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** - - Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been - truncated. - -### `__wasi_sdflags_t` (`uint8_t` bitfield) - -Which channels on a socket to shut down. - -Used by [`__wasi_sock_shutdown()`](#sock_shutdown). - -Possible values: - -- **`__WASI_SHUT_RD`** - - Disables further receive operations. - -- **`__WASI_SHUT_WR`** - - Disables further send operations. - -### `__wasi_siflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Used by [`__wasi_sock_send()`](#sock_send). - -### `__wasi_subclockflags_t` (`uint16_t` bitfield) - -Flags determining how to interpret the timestamp provided in -[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -Used by [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** - - If set, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp - of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - - If clear, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current - time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - -### `__wasi_subscription_t` (`struct`) - -Subscription to an event. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that is attached to the subscription in the - implementation and returned through - [`__wasi_event_t::userdata`](#event.userdata). - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event to which to subscribe. - -- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): - - - **`u.clock`** - - - [\_\_wasi\_userdata\_t](#userdata) identifier - - The user-defined unique identifier of the clock. - - - [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock against which to compare the timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) timeout - - The absolute or relative timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) precision - - The amount of time that the implementation may wait additionally - to coalesce with other events. - - - [\_\_wasi\_subclockflags\_t](#subclockflags) flags - - Flags specifying whether the timeout is absolute or relative. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor on which to wait for it to become ready - for reading or writing. - -### `__wasi_timestamp_t` (`uint64_t`) - -Timestamp in nanoseconds. - -Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -### `__wasi_userdata_t` (`uint64_t`) - -User-provided value that may be attached to objects that is -retained when extracted from the implementation. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -### `__wasi_whence_t` (`uint8_t`) - -The position relative to which to set the offset of the file descriptor. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -Possible values: - -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - -- **`__WASI_WHENCE_CUR`** - - Seek relative to current position. - -- **`__WASI_WHENCE_END`** - - Seek relative to end-of-file. - diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx new file mode 100644 index 000000000..2c2d32d67 --- /dev/null +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -0,0 +1,28 @@ +;; WASI Command-line Arguments. +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_args + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Read command-line argument data. + ;;; The size of the array should match that returned by `sizes_get` + (@interface func (export "get") + (param $argv (@witx pointer (@witx pointer u8))) + (param $argv_buf (@witx pointer u8)) + (result $error $errno) + ) + + ;;; Return command-line argument data sizes. + (@interface func (export "sizes_get") + (result $error $errno) + ;;; The number of arguments. + (result $argc $size) + ;;; The size of the argument string data. + (result $argv_buf_size $size) + ) +) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx new file mode 100644 index 000000000..b6d880443 --- /dev/null +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx @@ -0,0 +1,36 @@ +;; WASI Clocks. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_clock + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Return the resolution of a clock. + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Note: This is similar to `clock_getres` in POSIX. + (@interface func (export "res_get") + (result $error $errno) + ;;; The clock for which to return the resolution. + (param $id $clockid) + ;;; The resolution of the clock. + (result $resolution $timestamp) + ) + + ;;; Return the time value of a clock. + ;;; Note: This is similar to `clock_gettime` in POSIX. + (@interface func (export "time_get") + ;;; The clock for which to return the time. + (param $id $clockid) + ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp) + (result $error $errno) + ;;; The time value of the clock. + (result $time $timestamp) + ) +) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx new file mode 100644 index 000000000..5bc9c5a6f --- /dev/null +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -0,0 +1,28 @@ +;; WASI Environment Variables. +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_environ + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Read environment variable data. + ;;; The sizes of the buffers should match that returned by `sizes_get`. + (@interface func (export "get") + (param $environ (@witx pointer (@witx pointer u8))) + (param $environ_buf (@witx pointer u8)) + (result $error $errno) + ) + + ;;; Return command-line argument data sizes. + (@interface func (export "sizes_get") + (result $error $errno) + ;;; The number of arguments. + (result $argc $size) + ;;; The size of the argument string data. + (result $argv_buf_size $size) + ) +) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx new file mode 100644 index 000000000..9fbad9ab7 --- /dev/null +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -0,0 +1,242 @@ +;; WASI I/O. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_fd + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Provide file advisory information on a file descriptor. + ;;; Note: This is similar to `posix_fadvise` in POSIX. + (@interface func (export "advise") + (param $fd $fd) + ;;; The offset within the file to which the advisory applies. + (param $offset $filesize) + ;;; The length of the region to which the advisory applies. + (param $len $filesize) + ;;; The advice. + (param $advice $advice) + (result $error $errno) + ) + + ;;; Force the allocation of space in a file. + ;;; Note: This is similar to `posix_fallocate` in POSIX. + (@interface func (export "allocate") + (param $fd $fd) + ;;; The offset at which to start the allocation. + (param $offset $filesize) + ;;; The length of the area that is allocated. + (param $len $filesize) + (result $error $errno) + ) + + ;;; Close a file descriptor. + ;;; Note: This is similar to `close` in POSIX. + (@interface func (export "close") + (param $fd $fd) + (result $error $errno) + ) + + ;;; Synchronize the data of a file to disk. + ;;; Note: This is similar to `fdatasync` in POSIX. + (@interface func (export "datasync") + (param $fd $fd) + (result $error $errno) + ) + + ;;; Get the attributes of a file descriptor. + ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (@interface func (export "fdstat_get") + (param $fd $fd) + (result $error $errno) + ;;; The buffer where the file descriptor's attributes are stored. + (result $stat $fdstat) + ) + + ;;; Adjust the flags associated with a file descriptor. + ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (@interface func (export "fdstat_set_flags") + (param $fd $fd) + ;;; The desired values of the file descriptor flags. + (param $flags $fdflags) + (result $error $errno) + ) + + ;;; Adjust the rights associated with a file descriptor. + ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + (@interface func (export "fdstat_set_rights") + (param $fd $fd) + ;;; The desired rights of the file descriptor. + (param $fs_rights_base $rights) + (param $fs_rights_inheriting $rights) + (result $error $errno) + ) + + ;;; Return the attributes of an open file. + (@interface func (export "filestat_get") + (param $fd $fd) + (result $error $errno) + ;;; The buffer where the file's attributes are stored. + (result $buf $filestat) + ) + + ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;;; Note: This is similar to `ftruncate` in POSIX. + (@interface func (export "filestat_set_size") + (param $fd $fd) + ;;; The desired file size. + (param $size $filesize) + (result $error $errno) + ) + + ;;; Adjust the timestamps of an open file or directory. + ;;; Note: This is similar to `futimens` in POSIX. + (@interface func (export "filestat_set_times") + (param $fd $fd) + ;;; The desired values of the data access timestamp. + (param $atim $timestamp) + ;;; The desired values of the data modification timestamp. + (param $mtim $timestamp) + ;;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags) + (result $error $errno) + ) + + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `preadv` in POSIX. + (@interface func (export "pread") + (param $fd $fd) + ;;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_array) + ;;; The offset within the file at which to read. + (param $offset $filesize) + (result $error $errno) + ;;; The number of bytes read. + (result $nread $size) + ) + + ;;; Return a description of the given preopened file descriptor. + (@interface func (export "prestat_get") + (param $fd $fd) + (result $error $errno) + ;;; The buffer where the description is stored. + (result $buf $prestat) + ) + + ;;; Return a description of the given preopened file descriptor. + (@interface func (export "prestat_dir_name") + (param $fd $fd) + ;;; A buffer into which to write the preopened directory name. + (param $path (@witx pointer u8)) + (param $path_len $size) + (result $error $errno) + ) + + ;;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `pwritev` in POSIX. + (@interface func (export "pwrite") + (param $fd $fd) + ;;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_array) + ;;; The offset within the file at which to write. + (param $offset $filesize) + (result $error $errno) + ;;; The number of bytes written. + (result $nwritten $size) + ) + + ;;; Read from a file descriptor. + ;;; Note: This is similar to `readv` in POSIX. + (@interface func (export "read") + (param $fd $fd) + ;;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_array) + (result $error $errno) + ;;; The number of bytes read. + (result $nread $size) + ) + + ;;; Read directory entries from a directory. + ;;; When successful, the contents of the output buffer consist of a sequence of + ;;; directory entries. Each directory entry consists of a dirent_t object, + ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; entry. + ;; + ;;; This function fills the output buffer as much as possible, potentially + ;;; truncating the last directory entry. This allows the caller to grow its + ;;; read buffer size in case it's too small to fit a single large directory + ;;; entry, or skip the oversized directory entry. + (@interface func (export "readdir") + (param $fd $fd) + ;;; The buffer where directory entries are stored + (param $buf (@witx pointer u8)) + (param $buf_len $size) + ;;; The location within the directory to start reading + (param $cookie $dircookie) + (result $error $errno) + ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $bufused $size) + ) + + ;;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; + ;;; Due to the strong focus on thread safety, this environment does not provide + ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;;; file descriptor with the same number could be allocated by a different + ;;; thread at the same time. + ;; + ;;; This function provides a way to atomically renumber file descriptors, which + ;;; would disappear if `dup2()` were to be removed entirely. + (@interface func (export "renumber") + (param $fd $fd) + ;;; The file descriptor to overwrite. + (param $to $fd) + (result $error $errno) + ) + + ;;; Move the offset of a file descriptor. + ;;; Note: This is similar to `lseek` in POSIX. + (@interface func (export "seek") + (param $fd $fd) + ;;; The number of bytes to move. + (param $offset $filedelta) + ;;; The base from which the offset is relative. + (param $whence $whence) + (result $error $errno) + ;;; The new offset of the file descriptor, relative to the start of the file. + (result $newoffset $filesize) + ) + + ;;; Synchronize the data and metadata of a file to disk. + ;;; Note: This is similar to `fsync` in POSIX. + (@interface func (export "sync") + (param $fd $fd) + (result $error $errno) + ) + + ;;; Return the current offset of a file descriptor. + ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (@interface func (export "tell") + (param $fd $fd) + (result $error $errno) + ;;; The current offset of the file descriptor, relative to the start of the file. + (result $offset $filesize) + ) + + ;;; Write to a file descriptor. + ;;; Note: This is similar to `writev` in POSIX. + (@interface func (export "write") + (param $fd $fd) + ;;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_array) + (result $error $errno) + ;;; The number of bytes written. + (result $nwritten $size) + ) +) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx new file mode 100644 index 000000000..16c974692 --- /dev/null +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -0,0 +1,160 @@ +;; WASI Filesystem Path API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_path + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Create a directory. + ;;; Note: This is similar to `mkdirat` in POSIX. + (@interface func (export "create_directory") + (param $fd $fd) + ;;; The path at which to create the directory. + (param $path string) + (result $error $errno) + ) + + ;;; Return the attributes of a file or directory. + ;;; Note: This is similar to `stat` in POSIX. + (@interface func (export "filestat_get") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags) + ;;; The path of the file or directory to inspect. + (param $path string) + (result $error $errno) + ;;; The buffer where the file's attributes are stored. + (result $buf $filestat) + ) + + ;;; Adjust the timestamps of a file or directory. + ;;; Note: This is similar to `utimensat` in POSIX. + (@interface func (export "filestat_set_times") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags) + ;;; The path of the file or directory to operate on. + (param $path string) + ;;; The desired values of the data access timestamp. + (param $atim $timestamp) + ;;; The desired values of the data modification timestamp. + (param $mtim $timestamp) + ;;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags) + (result $error $errno) + ) + + ;;; Create a hard link. + ;;; Note: This is similar to `linkat` in POSIX. + (@interface func (export "link") + (param $old_fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags) + ;;; The source path from which to link. + (param $old_path string) + ;;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd) + ;;; The destination path at which to create the hard link. + (param $new_path string) + (result $error $errno) + ) + + ;;; Open a file or directory. + ;; + ;;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;;; file descriptor not currently open; it is randomized to prevent + ;;; applications from depending on making assumptions about indexes, since this + ;;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;;; guaranteed to be less than 2**31. + ;; + ;;; Note: This is similar to `openat` in POSIX. + (@interface func (export "open") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags) + ;;; The relative path of the file or directory to open, relative to the + ;;; `dirfd` directory. + (param $path string) + ;;; The method by which to open the file. + (param $oflags $oflags) + ;;; The initial rights of the newly created file descriptor. The + ;;; implementation is allowed to return a file descriptor with fewer rights + ;;; than specified, if and only if those rights do not apply to the type of + ;;; file being opened. + ;; + ;;; The *base* rights are rights that will apply to operations using the file + ;;; descriptor itself, while the *inheriting* rights are rights that apply to + ;;; file descriptors derived from it. + (param $fs_rights_base $rights) + (param $fs_rights_inherting $rights) + (param $fdflags $fdflags) + (result $error $errno) + ;;; The file descriptor of the file that has been opened. + (result $opened_fd $fd) + ) + + ;;; Read the contents of a symbolic link. + ;;; Note: This is similar to `readlinkat` in POSIX. + (@interface func (export "readlink") + (param $fd $fd) + ;;; The path of the symbolic link from which to read. + (param $path string) + ;;; The buffer to which to write the contents of the symbolic link. + (param $buf (@witx pointer u8)) + (param $buf_len $size) + (result $error $errno) + ;;; The number of bytes placed in the buffer. + (result $bufused $size) + ) + + ;;; Remove a directory. + ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (@interface func (export "remove_directory") + (param $fd $fd) + ;;; The path to a directory to remove. + (param $path string) + (result $error $errno) + ) + + ;;; Rename a file or directory. + ;;; Note: This is similar to `renameat` in POSIX. + (@interface func (export "rename") + (param $fd $fd) + ;;; The source path of the file or directory to rename. + (param $old_path string) + ;;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd) + ;;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error $errno) + ) + + ;;; Create a symbolic link. + ;;; Note: This is similar to `symlinkat` in POSIX. + (@interface func (export "symlink") + ;;; The contents of the symbolic link. + (param $old_path string) + (param $fd $fd) + ;;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error $errno) + ) + + + ;;; Unlink a file. + ;;; Return `EISDIR` if the path refers to a directory. + ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (@interface func (export "unlink_file") + (param $fd $fd) + ;;; The path to a file to unlink. + (param $path string) + (result $error $errno) + ) +) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx new file mode 100644 index 000000000..7dcdb53e6 --- /dev/null +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx @@ -0,0 +1,26 @@ +;; WASI Poll API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_poll + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Concurrently poll for the occurrence of a set of events. + (@interface func (export "oneoff") + ;;; The events to which to subscribe. + (param $in (@witx const_pointer $subscription)) + ;;; The events that have occurred. + (param $out (@witx pointer $event)) + ;;; Both the number of subscriptions and events. + (param $nsubscriptions $size) + (result $error $errno) + ;;; The number of events stored. + (result $nevents $size) + ) +) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx deleted file mode 100644 index 50bf519e7..000000000 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_preview.witx +++ /dev/null @@ -1,523 +0,0 @@ -;; WASI Preview. This is an evolution of the API that WASI initially -;; launched with. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_preview - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `wasi_args_sizes_get()` - (@interface func (export "args_get") - (param $argv (@witx pointer (@witx pointer u8))) - (param $argv_buf (@witx pointer u8)) - (result $error $errno) - ) - ;;; Return command-line argument data sizes. - (@interface func (export "args_sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) - ) - - ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. - (@interface func (export "environ_get") - (param $environ (@witx pointer (@witx pointer u8))) - (param $environ_buf (@witx pointer u8)) - (result $error $errno) - ) - ;;; Return command-line argument data sizes. - (@interface func (export "environ_sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) - ) - - ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` - ;;; Note: This is similar to `clock_getres` in POSIX. - (@interface func (export "clock_res_get") - (result $error $errno) - ;;; The clock for which to return the resolution. - (param $id $clockid) - ;;; The resolution of the clock. - (result $resolution $timestamp) - ) - ;;; Return the time value of a clock. - ;;; Note: This is similar to `clock_gettime` in POSIX. - (@interface func (export "clock_time_get") - ;;; The clock for which to return the time. - (param $id $clockid) - ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp) - (result $error $errno) - ;;; The time value of the clock. - (result $time $timestamp) - ) - - ;;; Provide file advisory information on a file descriptor. - ;;; Note: This is similar to `posix_fadvise` in POSIX. - (@interface func (export "fd_advise") - (param $fd $fd) - ;;; The offset within the file to which the advisory applies. - (param $offset $filesize) - ;;; The length of the region to which the advisory applies. - (param $len $filesize) - ;;; The advice. - (param $advice $advice) - (result $error $errno) - ) - - ;;; Force the allocation of space in a file. - ;;; Note: This is similar to `posix_fallocate` in POSIX. - (@interface func (export "fd_allocate") - (param $fd $fd) - ;;; The offset at which to start the allocation. - (param $offset $filesize) - ;;; The length of the area that is allocated. - (param $len $filesize) - (result $error $errno) - ) - - ;;; Close a file descriptor. - ;;; Note: This is similar to `close` in POSIX. - (@interface func (export "fd_close") - (param $fd $fd) - (result $error $errno) - ) - - ;;; Synchronize the data of a file to disk. - ;;; Note: This is similar to `fdatasync` in POSIX. - (@interface func (export "fd_datasync") - (param $fd $fd) - (result $error $errno) - ) - - ;;; Get the attributes of a file descriptor. - ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (@interface func (export "fd_fdstat_get") - (param $fd $fd) - (result $error $errno) - ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat) - ) - - ;;; Adjust the flags associated with a file descriptor. - ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd) - ;;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error $errno) - ) - - ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights - (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd) - ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (result $error $errno) - ) - - ;;; Return the attributes of an open file. - (@interface func (export "fd_filestat_get") - (param $fd $fd) - (result $error $errno) - ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) - ) - - ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;;; Note: This is similar to `ftruncate` in POSIX. - (@interface func (export "fd_filestat_set_size") - (param $fd $fd) - ;;; The desired file size. - (param $size $filesize) - (result $error $errno) - ) - - ;;; Adjust the timestamps of an open file or directory. - ;;; Note: This is similar to `futimens` in POSIX. - (@interface func (export "fd_filestat_set_times") - (param $fd $fd) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error $errno) - ) - - ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in POSIX. - (@interface func (export "fd_pread") - (param $fd $fd) - ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_array) - ;;; The offset within the file at which to read. - (param $offset $filesize) - (result $error $errno) - ;;; The number of bytes read. - (result $nread $size) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_get") - (param $fd $fd) - (result $error $errno) - ;;; The buffer where the description is stored. - (result $buf $prestat) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_dir_name") - (param $fd $fd) - ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer u8)) - (param $path_len $size) - (result $error $errno) - ) - - ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in POSIX. - (@interface func (export "fd_pwrite") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The offset within the file at which to write. - (param $offset $filesize) - (result $error $errno) - ;;; The number of bytes written. - (result $nwritten $size) - ) - - ;;; Read from a file descriptor. - ;;; Note: This is similar to `readv` in POSIX. - (@interface func (export "fd_read") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_array) - (result $error $errno) - ;;; The number of bytes read. - (result $nread $size) - ) - - ;;; Read directory entries from a directory. - ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a dirent_t object, - ;;; followed by dirent_t::d_namlen bytes holding the name of the directory - ;;; entry. - ;; - ;;; This function fills the output buffer as much as possible, potentially - ;;; truncating the last directory entry. This allows the caller to grow its - ;;; read buffer size in case it's too small to fit a single large directory - ;;; entry, or skip the oversized directory entry. - (@interface func (export "fd_readdir") - (param $fd $fd) - ;;; The buffer where directory entries are stored - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The location within the directory to start reading - (param $cookie $dircookie) - (result $error $errno) - ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size) - ) - - ;;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;;; Due to the strong focus on thread safety, this environment does not provide - ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;;; file descriptor with the same number could be allocated by a different - ;;; thread at the same time. - ;; - ;;; This function provides a way to atomically renumber file descriptors, which - ;;; would disappear if `dup2()` were to be removed entirely. - (@interface func (export "fd_renumber") - (param $fd $fd) - ;;; The file descriptor to overwrite. - (param $to $fd) - (result $error $errno) - ) - - ;;; Move the offset of a file descriptor. - ;;; Note: This is similar to `lseek` in POSIX. - (@interface func (export "fd_seek") - (param $fd $fd) - ;;; The number of bytes to move. - (param $offset $filedelta) - ;;; The base from which the offset is relative. - (param $whence $whence) - (result $error $errno) - ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize) - ) - - ;;; Synchronize the data and metadata of a file to disk. - ;;; Note: This is similar to `fsync` in POSIX. - (@interface func (export "fd_sync") - (param $fd $fd) - (result $error $errno) - ) - - ;;; Return the current offset of a file descriptor. - ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (@interface func (export "fd_tell") - (param $fd $fd) - (result $error $errno) - ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize) - ) - - ;;; Write to a file descriptor. - ;;; Note: This is similar to `writev` in POSIX. - (@interface func (export "fd_write") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - (result $error $errno) - ;;; The number of bytes written. - (result $nwritten $size) - ) - - ;;; Create a directory. - ;;; Note: This is similar to `mkdirat` in POSIX. - (@interface func (export "path_create_directory") - (param $fd $fd) - ;;; The path at which to create the directory. - (param $path string) - (result $error $errno) - ) - - ;;; Return the attributes of a file or directory. - ;;; Note: This is similar to `stat` in POSIX. - (@interface func (export "path_filestat_get") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to inspect. - (param $path string) - (result $error $errno) - ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) - ) - - ;;; Adjust the timestamps of a file or directory. - ;;; Note: This is similar to `utimensat` in POSIX. - (@interface func (export "path_filestat_set_times") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to operate on. - (param $path string) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error $errno) - ) - - ;;; Create a hard link. - ;;; Note: This is similar to `linkat` in POSIX. - (@interface func (export "path_link") - (param $old_fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags) - ;;; The source path from which to link. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path at which to create the hard link. - (param $new_path string) - (result $error $errno) - ) - - ;;; Open a file or directory. - ;; - ;;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;;; file descriptor not currently open; it is randomized to prevent - ;;; applications from depending on making assumptions about indexes, since this - ;;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;;; guaranteed to be less than 2**31. - ;; - ;;; Note: This is similar to `openat` in POSIX. - (@interface func (export "path_open") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags) - ;;; The relative path of the file or directory to open, relative to the - ;;; `dirfd` directory. - (param $path string) - ;;; The method by which to open the file. - (param $oflags $oflags) - ;;; The initial rights of the newly created file descriptor. The - ;;; implementation is allowed to return a file descriptor with fewer rights - ;;; than specified, if and only if those rights do not apply to the type of - ;;; file being opened. - ;; - ;;; The *base* rights are rights that will apply to operations using the file - ;;; descriptor itself, while the *inheriting* rights are rights that apply to - ;;; file descriptors derived from it. - (param $fs_rights_base $rights) - (param $fs_rights_inherting $rights) - (param $fdflags $fdflags) - (result $error $errno) - ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd) - ) - - ;;; Read the contents of a symbolic link. - ;;; Note: This is similar to `readlinkat` in POSIX. - (@interface func (export "path_readlink") - (param $fd $fd) - ;;; The path of the symbolic link from which to read. - (param $path string) - ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error $errno) - ;;; The number of bytes placed in the buffer. - (result $bufused $size) - ) - - ;;; Remove a directory. - ;;; Return `ENOTEMPTY` if the directory is not empty. - ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (@interface func (export "path_remove_directory") - (param $fd $fd) - ;;; The path to a directory to remove. - (param $path string) - (result $error $errno) - ) - - ;;; Rename a file or directory. - ;;; Note: This is similar to `renameat` in POSIX. - (@interface func (export "path_rename") - (param $fd $fd) - ;;; The source path of the file or directory to rename. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error $errno) - ) - - ;;; Create a symbolic link. - ;;; Note: This is similar to `symlinkat` in POSIX. - (@interface func (export "path_symlink") - ;;; The contents of the symbolic link. - (param $old_path string) - (param $fd $fd) - ;;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error $errno) - ) - - - ;;; Unlink a file. - ;;; Return `EISDIR` if the path refers to a directory. - ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (@interface func (export "path_unlink_file") - (param $fd $fd) - ;;; The path to a file to unlink. - (param $path string) - (result $error $errno) - ) - - ;;; Concurrently poll for the occurrence of a set of events. - (@interface func (export "poll_oneoff") - ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription)) - ;;; The events that have occurred. - (param $out (@witx pointer $event)) - ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size) - (result $error $errno) - ;;; The number of events stored. - (result $nevents $size) - ) - - ;;; Terminate the process normally. An exit code of 0 indicates successful - ;;; termination of the program. The meanings of other values is dependent on - ;;; the environment. - (@interface func (export "proc_exit") - ;;; The exit code returned by the process. - (param $rval $exitcode) - ) - - ;;; Temporarily yield execution of the calling thread. - ;;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "sched_yield") - (result $error $errno) - ) - - ;;; Write high-quality random data into a buffer. - ;;; This function blocks when the implementation is unable to immediately - ;;; provide sufficient high-quality random data. - ;;; This function may execute slowly, so when large mounts of random data are - ;;; required, it's advisable to use this function to seed a pseudo-random - ;;; number generator, rather than to provide the random data directly. - (@interface func (export "random_get") - ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error $errno) - ) - - ;;; Receive a message from a socket. - ;;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;;; the data into multiple buffers in the manner of `readv`. - (@interface func (export "sock_recv") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_array) - ;;; Message flags. - (param $ri_flags $riflags) - (result $error $errno) - ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size) - ;;; Message flags. - (result $ro_flags $roflags) - ) - - ;;; Send a message on a socket. - ;;; Note: This is similar to `send` in POSIX, though it also supports writing - ;;; the data from multiple buffers in the manner of `writev`. - (@interface func (export "sock_send") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_array) - ;;; Message flags. - (param $si_flags $siflags) - (result $error $errno) - ;;; Number of bytes transmitted. - (result $so_datalen $size) - ) - - ;;; Shut down socket send and receive channels. - ;;; Note: This is similar to `shutdown` in POSIX. - (@interface func (export "sock_shutdown") - (param $fd $fd) - ;;; Which channels on the socket to shut down. - (param $how $sdflags) - (result $error $errno) - ) -) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx new file mode 100644 index 000000000..5e53a83ec --- /dev/null +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx @@ -0,0 +1,18 @@ +;; WASI Process API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_proc + ;;; Terminate the process normally. An exit code of 0 indicates successful + ;;; termination of the program. The meanings of other values is dependent on + ;;; the environment. + (@interface func (export "exit") + ;;; The exit code returned by the process. + (param $rval $exitcode) + ) +) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx new file mode 100644 index 000000000..55c6df021 --- /dev/null +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx @@ -0,0 +1,26 @@ +;; WASI Random API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_random + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Write high-quality random data into a buffer. + ;;; This function blocks when the implementation is unable to immediately + ;;; provide sufficient high-quality random data. + ;;; This function may execute slowly, so when large mounts of random data are + ;;; required, it's advisable to use this function to seed a pseudo-random + ;;; number generator, rather than to provide the random data directly. + (@interface func (export "get") + ;;; The buffer to fill with random data. + (param $buf (@witx pointer u8)) + (param $buf_len $size) + (result $error $errno) + ) +) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sched.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sched.witx new file mode 100644 index 000000000..799a75fa9 --- /dev/null +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sched.witx @@ -0,0 +1,16 @@ +;; WASI Scheduler API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_sched + ;;; Temporarily yield execution of the calling thread. + ;;; Note: This is similar to `yield` in POSIX. + (@interface func (export "yield") + (result $error $errno) + ) +) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sock.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sock.witx new file mode 100644 index 000000000..becf80ffc --- /dev/null +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sock.witx @@ -0,0 +1,52 @@ +;; WASI Sockets. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_sock + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Receive a message from a socket. + ;;; Note: This is similar to `recv` in POSIX, though it also supports reading + ;;; the data into multiple buffers in the manner of `readv`. + (@interface func (export "recv") + (param $fd $fd) + ;;; List of scatter/gather vectors to which to store data. + (param $ri_data $iovec_array) + ;;; Message flags. + (param $ri_flags $riflags) + (result $error $errno) + ;;; Number of bytes stored in ri_data. + (result $ro_datalen $size) + ;;; Message flags. + (result $ro_flags $roflags) + ) + + ;;; Send a message on a socket. + ;;; Note: This is similar to `send` in POSIX, though it also supports writing + ;;; the data from multiple buffers in the manner of `writev`. + (@interface func (export "send") + (param $fd $fd) + ;;; List of scatter/gather vectors to which to retrieve data + (param $si_data $ciovec_array) + ;;; Message flags. + (param $si_flags $siflags) + (result $error $errno) + ;;; Number of bytes transmitted. + (result $so_datalen $size) + ) + + ;;; Shut down socket send and receive channels. + ;;; Note: This is similar to `shutdown` in POSIX. + (@interface func (export "shutdown") + (param $fd $fd) + ;;; Which channels on the socket to shut down. + (param $how $sdflags) + (result $error $errno) + ) +) From 161ffb0d4b027a01bd00787b3e0d52184a36b42e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Nov 2019 16:34:45 -0800 Subject: [PATCH 0325/1772] Update the witx tests for modularization. --- proposals/clocks/tools/witx/tests/wasi.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/tools/witx/tests/wasi.rs b/proposals/clocks/tools/witx/tests/wasi.rs index 6d6ebc120..fe7a101eb 100644 --- a/proposals/clocks/tools/witx/tests/wasi.rs +++ b/proposals/clocks/tools/witx/tests/wasi.rs @@ -8,8 +8,19 @@ fn validate_wasi_snapshot() { #[test] fn validate_wasi_ephemeral() { - witx::load(&["../../phases/ephemeral/witx/wasi_ephemeral_preview.witx"]) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&[ + "../../phases/ephemeral/witx/wasi_ephemeral_args.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_clock.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_environ.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_fd.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_path.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_poll.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_proc.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_random.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_sched.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_sock.witx", + ]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] From be0d698c667e57097a7c5829331e70a1cf069019 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Nov 2019 16:34:45 -0800 Subject: [PATCH 0326/1772] Update the witx tests for modularization. --- proposals/random/tools/witx/tests/wasi.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/proposals/random/tools/witx/tests/wasi.rs b/proposals/random/tools/witx/tests/wasi.rs index 6d6ebc120..fe7a101eb 100644 --- a/proposals/random/tools/witx/tests/wasi.rs +++ b/proposals/random/tools/witx/tests/wasi.rs @@ -8,8 +8,19 @@ fn validate_wasi_snapshot() { #[test] fn validate_wasi_ephemeral() { - witx::load(&["../../phases/ephemeral/witx/wasi_ephemeral_preview.witx"]) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&[ + "../../phases/ephemeral/witx/wasi_ephemeral_args.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_clock.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_environ.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_fd.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_path.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_poll.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_proc.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_random.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_sched.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_sock.witx", + ]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] From 04997b71ceae5267aaf99da4b6eb44e0b050565d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Nov 2019 16:34:45 -0800 Subject: [PATCH 0327/1772] Update the witx tests for modularization. --- proposals/filesystem/tools/witx/tests/wasi.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/tools/witx/tests/wasi.rs b/proposals/filesystem/tools/witx/tests/wasi.rs index 6d6ebc120..fe7a101eb 100644 --- a/proposals/filesystem/tools/witx/tests/wasi.rs +++ b/proposals/filesystem/tools/witx/tests/wasi.rs @@ -8,8 +8,19 @@ fn validate_wasi_snapshot() { #[test] fn validate_wasi_ephemeral() { - witx::load(&["../../phases/ephemeral/witx/wasi_ephemeral_preview.witx"]) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&[ + "../../phases/ephemeral/witx/wasi_ephemeral_args.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_clock.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_environ.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_fd.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_path.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_poll.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_proc.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_random.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_sched.witx", + "../../phases/ephemeral/witx/wasi_ephemeral_sock.witx", + ]) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] From b6be8268831a27b16b3a19bfb20acee4cddd15f1 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 3 Dec 2019 15:02:11 -0600 Subject: [PATCH 0328/1772] github actions: pin version of the checkout action (#169) To avoid effects of changes on their master branch. See https://github.com/CraneStation/wasi-libc/pull/145 --- proposals/clocks/.github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 797e4f1ca..5fc77d880 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -9,7 +9,7 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] steps: - - uses: actions/checkout@master + - uses: actions/checkout@v1 - name: Install Rust (rustup) shell: bash run: rustup update stable --no-self-update && rustup default stable @@ -30,7 +30,7 @@ jobs: name: Rustfmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@master + - uses: actions/checkout@v1 - name: Install Rust run: rustup update stable && rustup default stable && rustup component add rustfmt - run: cargo fmt -- --check From a115693a744bf19eb48e0a618ab9aad0b0c38a02 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 3 Dec 2019 15:02:11 -0600 Subject: [PATCH 0329/1772] github actions: pin version of the checkout action (#169) To avoid effects of changes on their master branch. See https://github.com/CraneStation/wasi-libc/pull/145 --- proposals/random/.github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index 797e4f1ca..5fc77d880 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -9,7 +9,7 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] steps: - - uses: actions/checkout@master + - uses: actions/checkout@v1 - name: Install Rust (rustup) shell: bash run: rustup update stable --no-self-update && rustup default stable @@ -30,7 +30,7 @@ jobs: name: Rustfmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@master + - uses: actions/checkout@v1 - name: Install Rust run: rustup update stable && rustup default stable && rustup component add rustfmt - run: cargo fmt -- --check From e2b9ce94867caf6803de1aa275f862640a9aa7ae Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 3 Dec 2019 15:02:11 -0600 Subject: [PATCH 0330/1772] github actions: pin version of the checkout action (#169) To avoid effects of changes on their master branch. See https://github.com/CraneStation/wasi-libc/pull/145 --- proposals/filesystem/.github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index 797e4f1ca..5fc77d880 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -9,7 +9,7 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] steps: - - uses: actions/checkout@master + - uses: actions/checkout@v1 - name: Install Rust (rustup) shell: bash run: rustup update stable --no-self-update && rustup default stable @@ -30,7 +30,7 @@ jobs: name: Rustfmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@master + - uses: actions/checkout@v1 - name: Install Rust run: rustup update stable && rustup default stable && rustup component add rustfmt - run: cargo fmt -- --check From f8a5f59bad922ff5f3b7b4a4a423f775840b6d00 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Nov 2019 15:54:53 -0800 Subject: [PATCH 0331/1772] Preliminary agenda; more to come! --- proposals/clocks/meetings/2019/WASI-12-05.md | 50 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 51 insertions(+) create mode 100644 proposals/clocks/meetings/2019/WASI-12-05.md diff --git a/proposals/clocks/meetings/2019/WASI-12-05.md b/proposals/clocks/meetings/2019/WASI-12-05.md new file mode 100644 index 000000000..0d2bb9622 --- /dev/null +++ b/proposals/clocks/meetings/2019/WASI-12-05.md @@ -0,0 +1,50 @@ +![WASI logo](/WASI.png) + +## Agenda for the December 5 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: December 5, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Stack trace API + 1. https://github.com/WebAssembly/WASI/issues/159 + 1. Whare are the next steps here? + 1. Character encodings + 1. https://github.com/WebAssembly/WASI/issues/8 + 1. Can we decide on this, or do we need more information? + 1. Case sensitivity + 1. https://github.com/WebAssembly/WASI/issues/72 + 1. Can we decide on this, or do we need more information? + 1. ANSI escape sequences + 1. https://github.com/WebAssembly/WASI/issues/162 + 1. Can we agree on the overall framework proposed here? + 1. Input sequences + 1. https://github.com/WebAssembly/WASI/issues/163 + 1. Fun with Unicode + 1. What standards govern this space? +1. Closure + +## Meeting Notes + +https://github.com/bytecodealliance/wasmtime/pull/235#issuecomment-518897502 diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index f1d790942..d290c87a2 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -21,3 +21,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI October 24th video call](2019/WASI-10-24.md) * [WASI November 7th video call](2019/WASI-11-07.md) * [WASI November 21st video call](2019/WASI-11-21.md) + * [WASI December 5th video call](2019/WASI-12-05.md) From 9179dd891c0811ce0c6c6479db634d5a87c29e04 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Nov 2019 15:54:53 -0800 Subject: [PATCH 0332/1772] Preliminary agenda; more to come! --- proposals/random/meetings/2019/WASI-12-05.md | 50 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 51 insertions(+) create mode 100644 proposals/random/meetings/2019/WASI-12-05.md diff --git a/proposals/random/meetings/2019/WASI-12-05.md b/proposals/random/meetings/2019/WASI-12-05.md new file mode 100644 index 000000000..0d2bb9622 --- /dev/null +++ b/proposals/random/meetings/2019/WASI-12-05.md @@ -0,0 +1,50 @@ +![WASI logo](/WASI.png) + +## Agenda for the December 5 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: December 5, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Stack trace API + 1. https://github.com/WebAssembly/WASI/issues/159 + 1. Whare are the next steps here? + 1. Character encodings + 1. https://github.com/WebAssembly/WASI/issues/8 + 1. Can we decide on this, or do we need more information? + 1. Case sensitivity + 1. https://github.com/WebAssembly/WASI/issues/72 + 1. Can we decide on this, or do we need more information? + 1. ANSI escape sequences + 1. https://github.com/WebAssembly/WASI/issues/162 + 1. Can we agree on the overall framework proposed here? + 1. Input sequences + 1. https://github.com/WebAssembly/WASI/issues/163 + 1. Fun with Unicode + 1. What standards govern this space? +1. Closure + +## Meeting Notes + +https://github.com/bytecodealliance/wasmtime/pull/235#issuecomment-518897502 diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index f1d790942..d290c87a2 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -21,3 +21,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI October 24th video call](2019/WASI-10-24.md) * [WASI November 7th video call](2019/WASI-11-07.md) * [WASI November 21st video call](2019/WASI-11-21.md) + * [WASI December 5th video call](2019/WASI-12-05.md) From b40061e2edb5a6c36da07e0ece4b52b534320c85 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Nov 2019 15:54:53 -0800 Subject: [PATCH 0333/1772] Preliminary agenda; more to come! --- .../filesystem/meetings/2019/WASI-12-05.md | 50 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 51 insertions(+) create mode 100644 proposals/filesystem/meetings/2019/WASI-12-05.md diff --git a/proposals/filesystem/meetings/2019/WASI-12-05.md b/proposals/filesystem/meetings/2019/WASI-12-05.md new file mode 100644 index 000000000..0d2bb9622 --- /dev/null +++ b/proposals/filesystem/meetings/2019/WASI-12-05.md @@ -0,0 +1,50 @@ +![WASI logo](/WASI.png) + +## Agenda for the December 5 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: December 5, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Stack trace API + 1. https://github.com/WebAssembly/WASI/issues/159 + 1. Whare are the next steps here? + 1. Character encodings + 1. https://github.com/WebAssembly/WASI/issues/8 + 1. Can we decide on this, or do we need more information? + 1. Case sensitivity + 1. https://github.com/WebAssembly/WASI/issues/72 + 1. Can we decide on this, or do we need more information? + 1. ANSI escape sequences + 1. https://github.com/WebAssembly/WASI/issues/162 + 1. Can we agree on the overall framework proposed here? + 1. Input sequences + 1. https://github.com/WebAssembly/WASI/issues/163 + 1. Fun with Unicode + 1. What standards govern this space? +1. Closure + +## Meeting Notes + +https://github.com/bytecodealliance/wasmtime/pull/235#issuecomment-518897502 diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index f1d790942..d290c87a2 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -21,3 +21,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI October 24th video call](2019/WASI-10-24.md) * [WASI November 7th video call](2019/WASI-11-07.md) * [WASI November 21st video call](2019/WASI-11-21.md) + * [WASI December 5th video call](2019/WASI-12-05.md) From 6b43896e4243064b9b0edd4a7f76535a4ec31968 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 3 Dec 2019 07:40:11 -0800 Subject: [PATCH 0334/1772] Remove the Unicode idea from the agenda. After further investigation, it doesn't seem viable (see the related issue for discussion). --- proposals/clocks/meetings/2019/WASI-12-05.md | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/clocks/meetings/2019/WASI-12-05.md b/proposals/clocks/meetings/2019/WASI-12-05.md index 0d2bb9622..cfc2b6297 100644 --- a/proposals/clocks/meetings/2019/WASI-12-05.md +++ b/proposals/clocks/meetings/2019/WASI-12-05.md @@ -41,7 +41,6 @@ Installation is required, see the calendar invite. 1. Can we agree on the overall framework proposed here? 1. Input sequences 1. https://github.com/WebAssembly/WASI/issues/163 - 1. Fun with Unicode 1. What standards govern this space? 1. Closure From ac3eb4d2edbd377ee1a78f4cfc15dc7bf6584b73 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 3 Dec 2019 07:40:11 -0800 Subject: [PATCH 0335/1772] Remove the Unicode idea from the agenda. After further investigation, it doesn't seem viable (see the related issue for discussion). --- proposals/random/meetings/2019/WASI-12-05.md | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/random/meetings/2019/WASI-12-05.md b/proposals/random/meetings/2019/WASI-12-05.md index 0d2bb9622..cfc2b6297 100644 --- a/proposals/random/meetings/2019/WASI-12-05.md +++ b/proposals/random/meetings/2019/WASI-12-05.md @@ -41,7 +41,6 @@ Installation is required, see the calendar invite. 1. Can we agree on the overall framework proposed here? 1. Input sequences 1. https://github.com/WebAssembly/WASI/issues/163 - 1. Fun with Unicode 1. What standards govern this space? 1. Closure From ad0fdb694ac0fec7ddc9dbf18b374d2aad914d75 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 3 Dec 2019 07:40:11 -0800 Subject: [PATCH 0336/1772] Remove the Unicode idea from the agenda. After further investigation, it doesn't seem viable (see the related issue for discussion). --- proposals/filesystem/meetings/2019/WASI-12-05.md | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/filesystem/meetings/2019/WASI-12-05.md b/proposals/filesystem/meetings/2019/WASI-12-05.md index 0d2bb9622..cfc2b6297 100644 --- a/proposals/filesystem/meetings/2019/WASI-12-05.md +++ b/proposals/filesystem/meetings/2019/WASI-12-05.md @@ -41,7 +41,6 @@ Installation is required, see the calendar invite. 1. Can we agree on the overall framework proposed here? 1. Input sequences 1. https://github.com/WebAssembly/WASI/issues/163 - 1. Fun with Unicode 1. What standards govern this space? 1. Closure From 0a15c8ef4216c5969cae4724148fb7852c5a7deb Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 16 Dec 2019 23:28:31 -0800 Subject: [PATCH 0337/1772] Announce the 12-19 meeting. --- proposals/clocks/meetings/2019/WASI-12-19.md | 39 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 40 insertions(+) create mode 100644 proposals/clocks/meetings/2019/WASI-12-19.md diff --git a/proposals/clocks/meetings/2019/WASI-12-19.md b/proposals/clocks/meetings/2019/WASI-12-19.md new file mode 100644 index 000000000..8f477ed78 --- /dev/null +++ b/proposals/clocks/meetings/2019/WASI-12-19.md @@ -0,0 +1,39 @@ +![WASI logo](/WASI.png) + +## Agenda for the December 19 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: December 19, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Stack trace API + 1. https://github.com/WebAssembly/WASI/issues/159 + 1. Whare are the next steps here? + 1. Windowing and Framebuffer APIs + 1. https://github.com/WebAssembly/WASI/issues/171 + 1. https://github.com/WebAssembly/WASI/issues/174 + 1. What guidance can we give to folks interested in working on these? +1. Closure + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index d290c87a2..08acc5d84 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -22,3 +22,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI November 7th video call](2019/WASI-11-07.md) * [WASI November 21st video call](2019/WASI-11-21.md) * [WASI December 5th video call](2019/WASI-12-05.md) + * [WASI December 19th video call](2019/WASI-12-19.md) From 1cdf5413693826747717bcadfe77d8a5e6bc026c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 16 Dec 2019 23:28:31 -0800 Subject: [PATCH 0338/1772] Announce the 12-19 meeting. --- proposals/random/meetings/2019/WASI-12-19.md | 39 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 40 insertions(+) create mode 100644 proposals/random/meetings/2019/WASI-12-19.md diff --git a/proposals/random/meetings/2019/WASI-12-19.md b/proposals/random/meetings/2019/WASI-12-19.md new file mode 100644 index 000000000..8f477ed78 --- /dev/null +++ b/proposals/random/meetings/2019/WASI-12-19.md @@ -0,0 +1,39 @@ +![WASI logo](/WASI.png) + +## Agenda for the December 19 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: December 19, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Stack trace API + 1. https://github.com/WebAssembly/WASI/issues/159 + 1. Whare are the next steps here? + 1. Windowing and Framebuffer APIs + 1. https://github.com/WebAssembly/WASI/issues/171 + 1. https://github.com/WebAssembly/WASI/issues/174 + 1. What guidance can we give to folks interested in working on these? +1. Closure + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index d290c87a2..08acc5d84 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -22,3 +22,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI November 7th video call](2019/WASI-11-07.md) * [WASI November 21st video call](2019/WASI-11-21.md) * [WASI December 5th video call](2019/WASI-12-05.md) + * [WASI December 19th video call](2019/WASI-12-19.md) From 029261a66496d3a1a4342682f1a9c76b8a31f11a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 16 Dec 2019 23:28:31 -0800 Subject: [PATCH 0339/1772] Announce the 12-19 meeting. --- .../filesystem/meetings/2019/WASI-12-19.md | 39 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 40 insertions(+) create mode 100644 proposals/filesystem/meetings/2019/WASI-12-19.md diff --git a/proposals/filesystem/meetings/2019/WASI-12-19.md b/proposals/filesystem/meetings/2019/WASI-12-19.md new file mode 100644 index 000000000..8f477ed78 --- /dev/null +++ b/proposals/filesystem/meetings/2019/WASI-12-19.md @@ -0,0 +1,39 @@ +![WASI logo](/WASI.png) + +## Agenda for the December 19 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: December 19, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Opening of the meeting + 1. Introduction of attendees +1. Find volunteers for note taking (acting chair to volunteer) +1. Adoption of the agenda +1. Proposals and discussions + 1. Stack trace API + 1. https://github.com/WebAssembly/WASI/issues/159 + 1. Whare are the next steps here? + 1. Windowing and Framebuffer APIs + 1. https://github.com/WebAssembly/WASI/issues/171 + 1. https://github.com/WebAssembly/WASI/issues/174 + 1. What guidance can we give to folks interested in working on these? +1. Closure + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index d290c87a2..08acc5d84 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -22,3 +22,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI November 7th video call](2019/WASI-11-07.md) * [WASI November 21st video call](2019/WASI-11-21.md) * [WASI December 5th video call](2019/WASI-12-05.md) + * [WASI December 19th video call](2019/WASI-12-19.md) From 720d15a0e8099348aa1f11b26212f9855899ef9d Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 27 Nov 2019 17:44:07 -0800 Subject: [PATCH 0340/1772] wip: some attempt at reasoning about what interfaces can be polyfilled --- proposals/clocks/tools/witx/src/ast.rs | 17 +- proposals/clocks/tools/witx/src/lib.rs | 2 + proposals/clocks/tools/witx/src/main.rs | 189 +++++++++++++++++++--- proposals/clocks/tools/witx/src/parser.rs | 15 +- 4 files changed, 186 insertions(+), 37 deletions(-) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 2295cc94c..49fd56b1d 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -2,8 +2,6 @@ use std::collections::HashMap; use std::rc::{Rc, Weak}; -pub use crate::parser::BuiltinType; - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Id(String); @@ -165,6 +163,21 @@ impl Type { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum BuiltinType { + String, + U8, + U16, + U32, + U64, + S8, + S16, + S32, + S64, + F32, + F64, +} + #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum IntRepr { U8, diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index ef32bf882..560bdcb71 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -14,6 +14,7 @@ mod render; mod toplevel; /// Validate declarations into ast mod validate; +mod representation; pub use ast::{ BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, @@ -28,6 +29,7 @@ pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; pub use render::SExpr; pub use validate::ValidationError; +pub use representation::Representable; use std::path::{Path, PathBuf}; use thiserror::Error; diff --git a/proposals/clocks/tools/witx/src/main.rs b/proposals/clocks/tools/witx/src/main.rs index 6251c3efa..359f2df1d 100644 --- a/proposals/clocks/tools/witx/src/main.rs +++ b/proposals/clocks/tools/witx/src/main.rs @@ -1,7 +1,7 @@ use clap::{App, Arg, SubCommand}; +use std::collections::HashMap; use std::fs::File; use std::io::Write; -use std::path::PathBuf; use std::process; use witx::{load, Documentation}; @@ -33,37 +33,184 @@ pub fn main() { .required(false), ), ) + .subcommand( + SubCommand::with_name("polyfill") + .about("Examine differences between interfaces") + .arg( + Arg::with_name("older_interface") + .required(true) + .multiple(true) + .help("path to root of witx document describing interface to polyfill"), + ) + .arg( + Arg::with_name("module_mapping") + .short("m") + .long("module_mapping") + .required(false) + .takes_value(true) + .multiple(true) + .help("module to examine. Use newname=oldname syntax if name is different between new and old interfaces"), + ), + ) .get_matches(); let inputs = app .values_of("input") .expect("at least one input required") - .into_iter() - .map(|i| PathBuf::from(i)) - .collect::>(); + .collect::>(); - match load(&inputs) { - Ok(doc) => { - if app.is_present("verbose") { - println!("{:?}", doc) + let load_docs = { + |inputs: &[&str]| match load(inputs) { + Ok(doc) => doc, + Err(e) => { + println!("{}", e.report()); + if app.is_present("verbose") { + println!("{:?}", e); + } + process::exit(1) } + } + }; + + let doc = load_docs(&inputs); + if app.is_present("verbose") { + println!("{:?}", doc) + } + + if let Some(docs_command) = app.subcommand_matches("docs") { + let md = doc.to_md(); + if let Some(output) = docs_command.value_of("output") { + let mut file = File::create(output).expect("create output file"); + file.write_all(md.as_bytes()).expect("write output file"); + } else { + println!("{}", md) + } + } else if let Some(polyfill_command) = app.subcommand_matches("polyfill") { + let older_inputs = polyfill_command + .values_of("older_interface") + .expect("at least one older_interface argument required") + .collect::>(); + let older_doc = load_docs(&older_inputs); + + let module_mapping_args = polyfill_command + .values_of("module_mapping") + .expect("at least one module_mapping argument required") + .collect::>(); + let module_mapping = parse_module_mapping(&module_mapping_args); - if let Some(subcommand) = app.subcommand_matches("docs") { - let md = doc.to_md(); - if let Some(output) = subcommand.value_of("output") { - let mut file = File::create(output).expect("create output file"); - file.write_all(md.as_bytes()).expect("write output file"); + polyfill(&doc, &older_doc, &module_mapping); + } +} + +fn parse_module_mapping(ms: &[&str]) -> HashMap { + let mut o = HashMap::new(); + for m in ms { + let s = m.split('=').collect::>(); + if s.len() == 0 { + let mname = s.get(0).unwrap(); + o.insert(mname.to_string(), mname.to_string()); + } else if s.len() == 1 { + let newname = s.get(0).unwrap(); + let oldname = s.get(0).unwrap(); + o.insert(newname.to_string(), oldname.to_string()); + } else { + panic!("invalid module mapping: '{}'", m) + } + } + o +} + +fn polyfill(new: &witx::Document, old: &witx::Document, module_mapping: &HashMap) { + use witx::Representable; + for (newmodulename, oldmodulename) in module_mapping { + let newmodule = new + .module(&witx::Id::new(newmodulename)) + .expect("module exists in new"); + let oldmodule = old + .module(&witx::Id::new(oldmodulename)) + .expect("module exists in old"); + + for oldfunc in oldmodule.funcs() { + if let Some(newfunc) = newmodule.func(&oldfunc.name) { + if newfunc.params.len() != oldfunc.params.len() { + println!( + "{}:{} has different number of params than {}:{}", + newmodulename, + newfunc.name.as_str(), + oldmodulename, + oldfunc.name.as_str() + ) } else { - println!("{}", md) + for (newparam, oldparam) in newfunc.params.iter().zip(oldfunc.params.iter()) { + if newparam.name != oldparam.name { + println!( + "{}:{} param {} doesnt match {}:{} param {}", + newmodulename, + newfunc.name.as_str(), + newparam.name.as_str(), + oldmodulename, + oldfunc.name.as_str(), + oldparam.name.as_str(), + ); + } else if !newparam.tref.representable(&oldparam.tref) { + println!( + "{}:{} param {}:{:?} has incompatible representation with {}:{} param {}:{:?}", + newmodulename, + newfunc.name.as_str(), + newparam.name.as_str(), + newparam.tref, + oldmodulename, + oldfunc.name.as_str(), + oldparam.name.as_str(), + newparam.tref, + ); + } + } } + if newfunc.results.len() != oldfunc.results.len() { + println!( + "{}:{} has different number of results than {}:{}", + newmodulename, + newfunc.name.as_str(), + oldmodulename, + oldfunc.name.as_str() + ) + } else { + for (newresult, oldresult) in newfunc.results.iter().zip(oldfunc.results.iter()) + { + if newresult.name != oldresult.name { + println!( + "{}:{} result {} doesnt match {}:{} result {}", + newmodulename, + newfunc.name.as_str(), + newresult.name.as_str(), + oldmodulename, + oldfunc.name.as_str(), + oldresult.name.as_str(), + ); + } else if !newresult.tref.representable(&oldresult.tref) { + println!( + "{}:{} result {}:{:?} has incompatible representation with {}:{} result {}:{:?}", + newmodulename, + newfunc.name.as_str(), + newresult.name.as_str(), + newresult.tref, + oldmodulename, + oldfunc.name.as_str(), + oldresult.name.as_str(), + newresult.tref, + ); + } + } + } + } else { + println!( + "{}:{} does not correspond to function in {}", + oldmodulename, + oldfunc.name.as_str(), + newmodulename + ); } } - Err(e) => { - println!("{}", e.report()); - if app.is_present("verbose") { - println!("{:?}", e); - } - process::exit(1) - } } } diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index d8088cd61..8e7e89bb2 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -1,3 +1,4 @@ +use crate::BuiltinType; use wast::lexer::Comment; use wast::parser::{Cursor, Parse, Parser, Peek, Result}; @@ -41,20 +42,6 @@ mod kw { wast::custom_keyword!(u8); } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum BuiltinType { - String, - U8, - U16, - U32, - U64, - S8, - S16, - S32, - S64, - F32, - F64, -} impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { From c09321ab86b2ea325f8dab21285640f2e29ec27d Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 27 Nov 2019 17:44:07 -0800 Subject: [PATCH 0341/1772] wip: some attempt at reasoning about what interfaces can be polyfilled --- proposals/random/tools/witx/src/ast.rs | 17 +- proposals/random/tools/witx/src/lib.rs | 2 + proposals/random/tools/witx/src/main.rs | 189 +++++++++++++++++++--- proposals/random/tools/witx/src/parser.rs | 15 +- 4 files changed, 186 insertions(+), 37 deletions(-) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 2295cc94c..49fd56b1d 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -2,8 +2,6 @@ use std::collections::HashMap; use std::rc::{Rc, Weak}; -pub use crate::parser::BuiltinType; - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Id(String); @@ -165,6 +163,21 @@ impl Type { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum BuiltinType { + String, + U8, + U16, + U32, + U64, + S8, + S16, + S32, + S64, + F32, + F64, +} + #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum IntRepr { U8, diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index ef32bf882..560bdcb71 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -14,6 +14,7 @@ mod render; mod toplevel; /// Validate declarations into ast mod validate; +mod representation; pub use ast::{ BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, @@ -28,6 +29,7 @@ pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; pub use render::SExpr; pub use validate::ValidationError; +pub use representation::Representable; use std::path::{Path, PathBuf}; use thiserror::Error; diff --git a/proposals/random/tools/witx/src/main.rs b/proposals/random/tools/witx/src/main.rs index 6251c3efa..359f2df1d 100644 --- a/proposals/random/tools/witx/src/main.rs +++ b/proposals/random/tools/witx/src/main.rs @@ -1,7 +1,7 @@ use clap::{App, Arg, SubCommand}; +use std::collections::HashMap; use std::fs::File; use std::io::Write; -use std::path::PathBuf; use std::process; use witx::{load, Documentation}; @@ -33,37 +33,184 @@ pub fn main() { .required(false), ), ) + .subcommand( + SubCommand::with_name("polyfill") + .about("Examine differences between interfaces") + .arg( + Arg::with_name("older_interface") + .required(true) + .multiple(true) + .help("path to root of witx document describing interface to polyfill"), + ) + .arg( + Arg::with_name("module_mapping") + .short("m") + .long("module_mapping") + .required(false) + .takes_value(true) + .multiple(true) + .help("module to examine. Use newname=oldname syntax if name is different between new and old interfaces"), + ), + ) .get_matches(); let inputs = app .values_of("input") .expect("at least one input required") - .into_iter() - .map(|i| PathBuf::from(i)) - .collect::>(); + .collect::>(); - match load(&inputs) { - Ok(doc) => { - if app.is_present("verbose") { - println!("{:?}", doc) + let load_docs = { + |inputs: &[&str]| match load(inputs) { + Ok(doc) => doc, + Err(e) => { + println!("{}", e.report()); + if app.is_present("verbose") { + println!("{:?}", e); + } + process::exit(1) } + } + }; + + let doc = load_docs(&inputs); + if app.is_present("verbose") { + println!("{:?}", doc) + } + + if let Some(docs_command) = app.subcommand_matches("docs") { + let md = doc.to_md(); + if let Some(output) = docs_command.value_of("output") { + let mut file = File::create(output).expect("create output file"); + file.write_all(md.as_bytes()).expect("write output file"); + } else { + println!("{}", md) + } + } else if let Some(polyfill_command) = app.subcommand_matches("polyfill") { + let older_inputs = polyfill_command + .values_of("older_interface") + .expect("at least one older_interface argument required") + .collect::>(); + let older_doc = load_docs(&older_inputs); + + let module_mapping_args = polyfill_command + .values_of("module_mapping") + .expect("at least one module_mapping argument required") + .collect::>(); + let module_mapping = parse_module_mapping(&module_mapping_args); - if let Some(subcommand) = app.subcommand_matches("docs") { - let md = doc.to_md(); - if let Some(output) = subcommand.value_of("output") { - let mut file = File::create(output).expect("create output file"); - file.write_all(md.as_bytes()).expect("write output file"); + polyfill(&doc, &older_doc, &module_mapping); + } +} + +fn parse_module_mapping(ms: &[&str]) -> HashMap { + let mut o = HashMap::new(); + for m in ms { + let s = m.split('=').collect::>(); + if s.len() == 0 { + let mname = s.get(0).unwrap(); + o.insert(mname.to_string(), mname.to_string()); + } else if s.len() == 1 { + let newname = s.get(0).unwrap(); + let oldname = s.get(0).unwrap(); + o.insert(newname.to_string(), oldname.to_string()); + } else { + panic!("invalid module mapping: '{}'", m) + } + } + o +} + +fn polyfill(new: &witx::Document, old: &witx::Document, module_mapping: &HashMap) { + use witx::Representable; + for (newmodulename, oldmodulename) in module_mapping { + let newmodule = new + .module(&witx::Id::new(newmodulename)) + .expect("module exists in new"); + let oldmodule = old + .module(&witx::Id::new(oldmodulename)) + .expect("module exists in old"); + + for oldfunc in oldmodule.funcs() { + if let Some(newfunc) = newmodule.func(&oldfunc.name) { + if newfunc.params.len() != oldfunc.params.len() { + println!( + "{}:{} has different number of params than {}:{}", + newmodulename, + newfunc.name.as_str(), + oldmodulename, + oldfunc.name.as_str() + ) } else { - println!("{}", md) + for (newparam, oldparam) in newfunc.params.iter().zip(oldfunc.params.iter()) { + if newparam.name != oldparam.name { + println!( + "{}:{} param {} doesnt match {}:{} param {}", + newmodulename, + newfunc.name.as_str(), + newparam.name.as_str(), + oldmodulename, + oldfunc.name.as_str(), + oldparam.name.as_str(), + ); + } else if !newparam.tref.representable(&oldparam.tref) { + println!( + "{}:{} param {}:{:?} has incompatible representation with {}:{} param {}:{:?}", + newmodulename, + newfunc.name.as_str(), + newparam.name.as_str(), + newparam.tref, + oldmodulename, + oldfunc.name.as_str(), + oldparam.name.as_str(), + newparam.tref, + ); + } + } } + if newfunc.results.len() != oldfunc.results.len() { + println!( + "{}:{} has different number of results than {}:{}", + newmodulename, + newfunc.name.as_str(), + oldmodulename, + oldfunc.name.as_str() + ) + } else { + for (newresult, oldresult) in newfunc.results.iter().zip(oldfunc.results.iter()) + { + if newresult.name != oldresult.name { + println!( + "{}:{} result {} doesnt match {}:{} result {}", + newmodulename, + newfunc.name.as_str(), + newresult.name.as_str(), + oldmodulename, + oldfunc.name.as_str(), + oldresult.name.as_str(), + ); + } else if !newresult.tref.representable(&oldresult.tref) { + println!( + "{}:{} result {}:{:?} has incompatible representation with {}:{} result {}:{:?}", + newmodulename, + newfunc.name.as_str(), + newresult.name.as_str(), + newresult.tref, + oldmodulename, + oldfunc.name.as_str(), + oldresult.name.as_str(), + newresult.tref, + ); + } + } + } + } else { + println!( + "{}:{} does not correspond to function in {}", + oldmodulename, + oldfunc.name.as_str(), + newmodulename + ); } } - Err(e) => { - println!("{}", e.report()); - if app.is_present("verbose") { - println!("{:?}", e); - } - process::exit(1) - } } } diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index d8088cd61..8e7e89bb2 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -1,3 +1,4 @@ +use crate::BuiltinType; use wast::lexer::Comment; use wast::parser::{Cursor, Parse, Parser, Peek, Result}; @@ -41,20 +42,6 @@ mod kw { wast::custom_keyword!(u8); } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum BuiltinType { - String, - U8, - U16, - U32, - U64, - S8, - S16, - S32, - S64, - F32, - F64, -} impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { From 957ae24d560179b090f401abeff226e7a04a3aed Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 27 Nov 2019 17:44:07 -0800 Subject: [PATCH 0342/1772] wip: some attempt at reasoning about what interfaces can be polyfilled --- proposals/filesystem/tools/witx/src/ast.rs | 17 +- proposals/filesystem/tools/witx/src/lib.rs | 2 + proposals/filesystem/tools/witx/src/main.rs | 189 ++++++++++++++++-- proposals/filesystem/tools/witx/src/parser.rs | 15 +- 4 files changed, 186 insertions(+), 37 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 2295cc94c..49fd56b1d 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -2,8 +2,6 @@ use std::collections::HashMap; use std::rc::{Rc, Weak}; -pub use crate::parser::BuiltinType; - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Id(String); @@ -165,6 +163,21 @@ impl Type { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum BuiltinType { + String, + U8, + U16, + U32, + U64, + S8, + S16, + S32, + S64, + F32, + F64, +} + #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum IntRepr { U8, diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index ef32bf882..560bdcb71 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -14,6 +14,7 @@ mod render; mod toplevel; /// Validate declarations into ast mod validate; +mod representation; pub use ast::{ BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, @@ -28,6 +29,7 @@ pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; pub use render::SExpr; pub use validate::ValidationError; +pub use representation::Representable; use std::path::{Path, PathBuf}; use thiserror::Error; diff --git a/proposals/filesystem/tools/witx/src/main.rs b/proposals/filesystem/tools/witx/src/main.rs index 6251c3efa..359f2df1d 100644 --- a/proposals/filesystem/tools/witx/src/main.rs +++ b/proposals/filesystem/tools/witx/src/main.rs @@ -1,7 +1,7 @@ use clap::{App, Arg, SubCommand}; +use std::collections::HashMap; use std::fs::File; use std::io::Write; -use std::path::PathBuf; use std::process; use witx::{load, Documentation}; @@ -33,37 +33,184 @@ pub fn main() { .required(false), ), ) + .subcommand( + SubCommand::with_name("polyfill") + .about("Examine differences between interfaces") + .arg( + Arg::with_name("older_interface") + .required(true) + .multiple(true) + .help("path to root of witx document describing interface to polyfill"), + ) + .arg( + Arg::with_name("module_mapping") + .short("m") + .long("module_mapping") + .required(false) + .takes_value(true) + .multiple(true) + .help("module to examine. Use newname=oldname syntax if name is different between new and old interfaces"), + ), + ) .get_matches(); let inputs = app .values_of("input") .expect("at least one input required") - .into_iter() - .map(|i| PathBuf::from(i)) - .collect::>(); + .collect::>(); - match load(&inputs) { - Ok(doc) => { - if app.is_present("verbose") { - println!("{:?}", doc) + let load_docs = { + |inputs: &[&str]| match load(inputs) { + Ok(doc) => doc, + Err(e) => { + println!("{}", e.report()); + if app.is_present("verbose") { + println!("{:?}", e); + } + process::exit(1) } + } + }; + + let doc = load_docs(&inputs); + if app.is_present("verbose") { + println!("{:?}", doc) + } + + if let Some(docs_command) = app.subcommand_matches("docs") { + let md = doc.to_md(); + if let Some(output) = docs_command.value_of("output") { + let mut file = File::create(output).expect("create output file"); + file.write_all(md.as_bytes()).expect("write output file"); + } else { + println!("{}", md) + } + } else if let Some(polyfill_command) = app.subcommand_matches("polyfill") { + let older_inputs = polyfill_command + .values_of("older_interface") + .expect("at least one older_interface argument required") + .collect::>(); + let older_doc = load_docs(&older_inputs); + + let module_mapping_args = polyfill_command + .values_of("module_mapping") + .expect("at least one module_mapping argument required") + .collect::>(); + let module_mapping = parse_module_mapping(&module_mapping_args); - if let Some(subcommand) = app.subcommand_matches("docs") { - let md = doc.to_md(); - if let Some(output) = subcommand.value_of("output") { - let mut file = File::create(output).expect("create output file"); - file.write_all(md.as_bytes()).expect("write output file"); + polyfill(&doc, &older_doc, &module_mapping); + } +} + +fn parse_module_mapping(ms: &[&str]) -> HashMap { + let mut o = HashMap::new(); + for m in ms { + let s = m.split('=').collect::>(); + if s.len() == 0 { + let mname = s.get(0).unwrap(); + o.insert(mname.to_string(), mname.to_string()); + } else if s.len() == 1 { + let newname = s.get(0).unwrap(); + let oldname = s.get(0).unwrap(); + o.insert(newname.to_string(), oldname.to_string()); + } else { + panic!("invalid module mapping: '{}'", m) + } + } + o +} + +fn polyfill(new: &witx::Document, old: &witx::Document, module_mapping: &HashMap) { + use witx::Representable; + for (newmodulename, oldmodulename) in module_mapping { + let newmodule = new + .module(&witx::Id::new(newmodulename)) + .expect("module exists in new"); + let oldmodule = old + .module(&witx::Id::new(oldmodulename)) + .expect("module exists in old"); + + for oldfunc in oldmodule.funcs() { + if let Some(newfunc) = newmodule.func(&oldfunc.name) { + if newfunc.params.len() != oldfunc.params.len() { + println!( + "{}:{} has different number of params than {}:{}", + newmodulename, + newfunc.name.as_str(), + oldmodulename, + oldfunc.name.as_str() + ) } else { - println!("{}", md) + for (newparam, oldparam) in newfunc.params.iter().zip(oldfunc.params.iter()) { + if newparam.name != oldparam.name { + println!( + "{}:{} param {} doesnt match {}:{} param {}", + newmodulename, + newfunc.name.as_str(), + newparam.name.as_str(), + oldmodulename, + oldfunc.name.as_str(), + oldparam.name.as_str(), + ); + } else if !newparam.tref.representable(&oldparam.tref) { + println!( + "{}:{} param {}:{:?} has incompatible representation with {}:{} param {}:{:?}", + newmodulename, + newfunc.name.as_str(), + newparam.name.as_str(), + newparam.tref, + oldmodulename, + oldfunc.name.as_str(), + oldparam.name.as_str(), + newparam.tref, + ); + } + } } + if newfunc.results.len() != oldfunc.results.len() { + println!( + "{}:{} has different number of results than {}:{}", + newmodulename, + newfunc.name.as_str(), + oldmodulename, + oldfunc.name.as_str() + ) + } else { + for (newresult, oldresult) in newfunc.results.iter().zip(oldfunc.results.iter()) + { + if newresult.name != oldresult.name { + println!( + "{}:{} result {} doesnt match {}:{} result {}", + newmodulename, + newfunc.name.as_str(), + newresult.name.as_str(), + oldmodulename, + oldfunc.name.as_str(), + oldresult.name.as_str(), + ); + } else if !newresult.tref.representable(&oldresult.tref) { + println!( + "{}:{} result {}:{:?} has incompatible representation with {}:{} result {}:{:?}", + newmodulename, + newfunc.name.as_str(), + newresult.name.as_str(), + newresult.tref, + oldmodulename, + oldfunc.name.as_str(), + oldresult.name.as_str(), + newresult.tref, + ); + } + } + } + } else { + println!( + "{}:{} does not correspond to function in {}", + oldmodulename, + oldfunc.name.as_str(), + newmodulename + ); } } - Err(e) => { - println!("{}", e.report()); - if app.is_present("verbose") { - println!("{:?}", e); - } - process::exit(1) - } } } diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index d8088cd61..8e7e89bb2 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -1,3 +1,4 @@ +use crate::BuiltinType; use wast::lexer::Comment; use wast::parser::{Cursor, Parse, Parser, Peek, Result}; @@ -41,20 +42,6 @@ mod kw { wast::custom_keyword!(u8); } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum BuiltinType { - String, - U8, - U16, - U32, - U64, - S8, - S16, - S32, - S64, - F32, - F64, -} impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { From 98fc485c0afb02b938a7af41862fc3ea1a8a2e82 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 27 Nov 2019 17:49:42 -0800 Subject: [PATCH 0343/1772] forgot to git add --- .../clocks/tools/witx/src/representation.rs | 164 ++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 proposals/clocks/tools/witx/src/representation.rs diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs new file mode 100644 index 000000000..95de41fe7 --- /dev/null +++ b/proposals/clocks/tools/witx/src/representation.rs @@ -0,0 +1,164 @@ +use crate::{ + BuiltinType, EnumDatatype, FlagsDatatype, HandleDatatype, IntRepr, StructDatatype, Type, + TypeRef, UnionDatatype, +}; + +pub trait Representable { + fn representable(&self, by: &Self) -> bool; + // XXX its not enough for this to be a bool. we need to give the recipe with which to represent + // it -does it correspond exactly, does it need an upcast, or does it not correspond at all? + // and so on for each member. + // for structs, one might be able to represent each other, but not in the same memory layout. + // this can be arbitrarily deep due to recursion. for ABI compatibility we may need + // structs to correspond exactly, but maybe builtintypes just need to be representable. for + // polyfilling, we may just need everything to be representable. + // so, really this should return an enum describing what sort of equality we found between + // the two types, and then let the caller make that policy decision. TODO: design exactly that + // enum, i guess? + // also what about equality of typeref? +} + +impl Representable for BuiltinType { + fn representable(&self, by: &Self) -> bool { + // An unsigned integer can be used to represent an unsigned integer of smaller width. + // Otherwise, types must be equal. + match self { + BuiltinType::U8 => match by { + BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 | BuiltinType::U8 => true, + _ => false, + }, + BuiltinType::U16 => match by { + BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 => true, + _ => false, + }, + BuiltinType::U32 => match by { + BuiltinType::U64 | BuiltinType::U32 => true, + _ => false, + }, + other => by == other, + } + } +} + +impl Representable for IntRepr { + fn representable(&self, by: &Self) -> bool { + // An unsigned integer can be used to represent an unsigned integer of smaller width. + match self { + IntRepr::U8 => true, + IntRepr::U16 => match by { + IntRepr::U16 | IntRepr::U32 | IntRepr::U64 => true, + _ => false, + }, + IntRepr::U32 => match by { + IntRepr::U32 | IntRepr::U64 => true, + _ => false, + }, + IntRepr::U64 => *by == IntRepr::U64, + } + } +} + +impl Representable for EnumDatatype { + fn representable(&self, by: &Self) -> bool { + // Integer representation must be compatible + if !by.repr.representable(&self.repr) { + return false; + } + // For each variant in self, must have variant of same name and position in by: + for (ix, v) in self.variants.iter().enumerate() { + if let Some(by_v) = by.variants.get(ix) { + if by_v.name != v.name { + return false; + } + } else { + return false; + } + } + true + } +} + +impl Representable for FlagsDatatype { + fn representable(&self, by: &Self) -> bool { + // Integer representation must be compatible + if !by.repr.representable(&self.repr) { + return false; + } + // For each flag in self, must have flag of same name and position in by: + for (ix, f) in self.flags.iter().enumerate() { + if let Some(by_f) = by.flags.get(ix) { + if by_f.name != f.name { + return false; + } + } else { + return false; + } + } + true + } +} + +impl Representable for HandleDatatype { + fn representable(&self, by: &Self) -> bool { + // Handles must have the same set of named supertypes. Anonymous supertypes are never + // equal, and the validator should probably make sure these are not allowed, because + // what would that even mean?? + for supertype_ref in self.supertypes.iter() { + match supertype_ref { + TypeRef::Name(nt) => { + if let Some(by_nt) = by.supertypes.iter().find_map(|tref| match tref { + TypeRef::Name(by_nt) if by_nt.name == nt.name => Some(by_nt), + _ => None, + }) { + if !nt.dt.representable(&by_nt.dt) { + return false; + } + } else { + return false; + } + } + TypeRef::Value(_) => { + return false; + } + } + } + true + } +} + +impl Representable for StructDatatype { + fn representable(&self, _by: &Self) -> bool { + unimplemented!( + "this one is hard - need more than a bool for this return type to really describe it" + ) + } +} + +impl Representable for UnionDatatype { + fn representable(&self, _by: &Self) -> bool { + unimplemented!("this one is hard") + } +} + +impl Representable for TypeRef { + fn representable(&self, _by: &Self) -> bool { + unimplemented!("this one is hard - representable by type_() is appropriate in some cases, some times you may want precise name equality as well") + } +} + +impl Representable for Type { + fn representable(&self, by: &Self) -> bool { + match (&self, &by) { + (Type::Enum(s), Type::Enum(b)) => s.representable(b), + (Type::Flags(s), Type::Flags(b)) => s.representable(b), + (Type::Struct(s), Type::Struct(b)) => s.representable(b), + (Type::Union(s), Type::Union(b)) => s.representable(b), + (Type::Handle(s), Type::Handle(b)) => s.representable(b), + (Type::Array(s), Type::Array(b)) => s.representable(b), + (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), + (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), + (Type::Builtin(s), Type::Builtin(b)) => s.representable(b), + _ => false, + } + } +} From ba6efb254bfd26dbb0be3028a4246ee0682725a4 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 27 Nov 2019 17:49:42 -0800 Subject: [PATCH 0344/1772] forgot to git add --- .../random/tools/witx/src/representation.rs | 164 ++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 proposals/random/tools/witx/src/representation.rs diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs new file mode 100644 index 000000000..95de41fe7 --- /dev/null +++ b/proposals/random/tools/witx/src/representation.rs @@ -0,0 +1,164 @@ +use crate::{ + BuiltinType, EnumDatatype, FlagsDatatype, HandleDatatype, IntRepr, StructDatatype, Type, + TypeRef, UnionDatatype, +}; + +pub trait Representable { + fn representable(&self, by: &Self) -> bool; + // XXX its not enough for this to be a bool. we need to give the recipe with which to represent + // it -does it correspond exactly, does it need an upcast, or does it not correspond at all? + // and so on for each member. + // for structs, one might be able to represent each other, but not in the same memory layout. + // this can be arbitrarily deep due to recursion. for ABI compatibility we may need + // structs to correspond exactly, but maybe builtintypes just need to be representable. for + // polyfilling, we may just need everything to be representable. + // so, really this should return an enum describing what sort of equality we found between + // the two types, and then let the caller make that policy decision. TODO: design exactly that + // enum, i guess? + // also what about equality of typeref? +} + +impl Representable for BuiltinType { + fn representable(&self, by: &Self) -> bool { + // An unsigned integer can be used to represent an unsigned integer of smaller width. + // Otherwise, types must be equal. + match self { + BuiltinType::U8 => match by { + BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 | BuiltinType::U8 => true, + _ => false, + }, + BuiltinType::U16 => match by { + BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 => true, + _ => false, + }, + BuiltinType::U32 => match by { + BuiltinType::U64 | BuiltinType::U32 => true, + _ => false, + }, + other => by == other, + } + } +} + +impl Representable for IntRepr { + fn representable(&self, by: &Self) -> bool { + // An unsigned integer can be used to represent an unsigned integer of smaller width. + match self { + IntRepr::U8 => true, + IntRepr::U16 => match by { + IntRepr::U16 | IntRepr::U32 | IntRepr::U64 => true, + _ => false, + }, + IntRepr::U32 => match by { + IntRepr::U32 | IntRepr::U64 => true, + _ => false, + }, + IntRepr::U64 => *by == IntRepr::U64, + } + } +} + +impl Representable for EnumDatatype { + fn representable(&self, by: &Self) -> bool { + // Integer representation must be compatible + if !by.repr.representable(&self.repr) { + return false; + } + // For each variant in self, must have variant of same name and position in by: + for (ix, v) in self.variants.iter().enumerate() { + if let Some(by_v) = by.variants.get(ix) { + if by_v.name != v.name { + return false; + } + } else { + return false; + } + } + true + } +} + +impl Representable for FlagsDatatype { + fn representable(&self, by: &Self) -> bool { + // Integer representation must be compatible + if !by.repr.representable(&self.repr) { + return false; + } + // For each flag in self, must have flag of same name and position in by: + for (ix, f) in self.flags.iter().enumerate() { + if let Some(by_f) = by.flags.get(ix) { + if by_f.name != f.name { + return false; + } + } else { + return false; + } + } + true + } +} + +impl Representable for HandleDatatype { + fn representable(&self, by: &Self) -> bool { + // Handles must have the same set of named supertypes. Anonymous supertypes are never + // equal, and the validator should probably make sure these are not allowed, because + // what would that even mean?? + for supertype_ref in self.supertypes.iter() { + match supertype_ref { + TypeRef::Name(nt) => { + if let Some(by_nt) = by.supertypes.iter().find_map(|tref| match tref { + TypeRef::Name(by_nt) if by_nt.name == nt.name => Some(by_nt), + _ => None, + }) { + if !nt.dt.representable(&by_nt.dt) { + return false; + } + } else { + return false; + } + } + TypeRef::Value(_) => { + return false; + } + } + } + true + } +} + +impl Representable for StructDatatype { + fn representable(&self, _by: &Self) -> bool { + unimplemented!( + "this one is hard - need more than a bool for this return type to really describe it" + ) + } +} + +impl Representable for UnionDatatype { + fn representable(&self, _by: &Self) -> bool { + unimplemented!("this one is hard") + } +} + +impl Representable for TypeRef { + fn representable(&self, _by: &Self) -> bool { + unimplemented!("this one is hard - representable by type_() is appropriate in some cases, some times you may want precise name equality as well") + } +} + +impl Representable for Type { + fn representable(&self, by: &Self) -> bool { + match (&self, &by) { + (Type::Enum(s), Type::Enum(b)) => s.representable(b), + (Type::Flags(s), Type::Flags(b)) => s.representable(b), + (Type::Struct(s), Type::Struct(b)) => s.representable(b), + (Type::Union(s), Type::Union(b)) => s.representable(b), + (Type::Handle(s), Type::Handle(b)) => s.representable(b), + (Type::Array(s), Type::Array(b)) => s.representable(b), + (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), + (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), + (Type::Builtin(s), Type::Builtin(b)) => s.representable(b), + _ => false, + } + } +} From 5346b8ded38da0df32c6a572b12fd4f3ca88dcc5 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 27 Nov 2019 17:49:42 -0800 Subject: [PATCH 0345/1772] forgot to git add --- .../tools/witx/src/representation.rs | 164 ++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 proposals/filesystem/tools/witx/src/representation.rs diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs new file mode 100644 index 000000000..95de41fe7 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/representation.rs @@ -0,0 +1,164 @@ +use crate::{ + BuiltinType, EnumDatatype, FlagsDatatype, HandleDatatype, IntRepr, StructDatatype, Type, + TypeRef, UnionDatatype, +}; + +pub trait Representable { + fn representable(&self, by: &Self) -> bool; + // XXX its not enough for this to be a bool. we need to give the recipe with which to represent + // it -does it correspond exactly, does it need an upcast, or does it not correspond at all? + // and so on for each member. + // for structs, one might be able to represent each other, but not in the same memory layout. + // this can be arbitrarily deep due to recursion. for ABI compatibility we may need + // structs to correspond exactly, but maybe builtintypes just need to be representable. for + // polyfilling, we may just need everything to be representable. + // so, really this should return an enum describing what sort of equality we found between + // the two types, and then let the caller make that policy decision. TODO: design exactly that + // enum, i guess? + // also what about equality of typeref? +} + +impl Representable for BuiltinType { + fn representable(&self, by: &Self) -> bool { + // An unsigned integer can be used to represent an unsigned integer of smaller width. + // Otherwise, types must be equal. + match self { + BuiltinType::U8 => match by { + BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 | BuiltinType::U8 => true, + _ => false, + }, + BuiltinType::U16 => match by { + BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 => true, + _ => false, + }, + BuiltinType::U32 => match by { + BuiltinType::U64 | BuiltinType::U32 => true, + _ => false, + }, + other => by == other, + } + } +} + +impl Representable for IntRepr { + fn representable(&self, by: &Self) -> bool { + // An unsigned integer can be used to represent an unsigned integer of smaller width. + match self { + IntRepr::U8 => true, + IntRepr::U16 => match by { + IntRepr::U16 | IntRepr::U32 | IntRepr::U64 => true, + _ => false, + }, + IntRepr::U32 => match by { + IntRepr::U32 | IntRepr::U64 => true, + _ => false, + }, + IntRepr::U64 => *by == IntRepr::U64, + } + } +} + +impl Representable for EnumDatatype { + fn representable(&self, by: &Self) -> bool { + // Integer representation must be compatible + if !by.repr.representable(&self.repr) { + return false; + } + // For each variant in self, must have variant of same name and position in by: + for (ix, v) in self.variants.iter().enumerate() { + if let Some(by_v) = by.variants.get(ix) { + if by_v.name != v.name { + return false; + } + } else { + return false; + } + } + true + } +} + +impl Representable for FlagsDatatype { + fn representable(&self, by: &Self) -> bool { + // Integer representation must be compatible + if !by.repr.representable(&self.repr) { + return false; + } + // For each flag in self, must have flag of same name and position in by: + for (ix, f) in self.flags.iter().enumerate() { + if let Some(by_f) = by.flags.get(ix) { + if by_f.name != f.name { + return false; + } + } else { + return false; + } + } + true + } +} + +impl Representable for HandleDatatype { + fn representable(&self, by: &Self) -> bool { + // Handles must have the same set of named supertypes. Anonymous supertypes are never + // equal, and the validator should probably make sure these are not allowed, because + // what would that even mean?? + for supertype_ref in self.supertypes.iter() { + match supertype_ref { + TypeRef::Name(nt) => { + if let Some(by_nt) = by.supertypes.iter().find_map(|tref| match tref { + TypeRef::Name(by_nt) if by_nt.name == nt.name => Some(by_nt), + _ => None, + }) { + if !nt.dt.representable(&by_nt.dt) { + return false; + } + } else { + return false; + } + } + TypeRef::Value(_) => { + return false; + } + } + } + true + } +} + +impl Representable for StructDatatype { + fn representable(&self, _by: &Self) -> bool { + unimplemented!( + "this one is hard - need more than a bool for this return type to really describe it" + ) + } +} + +impl Representable for UnionDatatype { + fn representable(&self, _by: &Self) -> bool { + unimplemented!("this one is hard") + } +} + +impl Representable for TypeRef { + fn representable(&self, _by: &Self) -> bool { + unimplemented!("this one is hard - representable by type_() is appropriate in some cases, some times you may want precise name equality as well") + } +} + +impl Representable for Type { + fn representable(&self, by: &Self) -> bool { + match (&self, &by) { + (Type::Enum(s), Type::Enum(b)) => s.representable(b), + (Type::Flags(s), Type::Flags(b)) => s.representable(b), + (Type::Struct(s), Type::Struct(b)) => s.representable(b), + (Type::Union(s), Type::Union(b)) => s.representable(b), + (Type::Handle(s), Type::Handle(b)) => s.representable(b), + (Type::Array(s), Type::Array(b)) => s.representable(b), + (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), + (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), + (Type::Builtin(s), Type::Builtin(b)) => s.representable(b), + _ => false, + } + } +} From 0abedb9153e568701190d9cde9b5900cc27675d4 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 2 Dec 2019 11:59:06 -0800 Subject: [PATCH 0346/1772] witx polyfill: now outputs something vaguely useful --- proposals/clocks/tools/witx/src/lib.rs | 2 +- proposals/clocks/tools/witx/src/main.rs | 26 +-- proposals/clocks/tools/witx/src/render.rs | 30 ++-- .../clocks/tools/witx/src/representation.rs | 149 +++++++++++------- 4 files changed, 124 insertions(+), 83 deletions(-) diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 560bdcb71..815bccc94 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -29,7 +29,7 @@ pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; pub use render::SExpr; pub use validate::ValidationError; -pub use representation::Representable; +pub use representation::{Representable, RepEquality}; use std::path::{Path, PathBuf}; use thiserror::Error; diff --git a/proposals/clocks/tools/witx/src/main.rs b/proposals/clocks/tools/witx/src/main.rs index 359f2df1d..8a62dcf5f 100644 --- a/proposals/clocks/tools/witx/src/main.rs +++ b/proposals/clocks/tools/witx/src/main.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use std::fs::File; use std::io::Write; use std::process; -use witx::{load, Documentation}; +use witx::{load, Documentation, RepEquality}; pub fn main() { let app = App::new("witx") @@ -106,12 +106,12 @@ fn parse_module_mapping(ms: &[&str]) -> HashMap { let mut o = HashMap::new(); for m in ms { let s = m.split('=').collect::>(); - if s.len() == 0 { + if s.len() == 1 { let mname = s.get(0).unwrap(); o.insert(mname.to_string(), mname.to_string()); - } else if s.len() == 1 { + } else if s.len() == 2 { let newname = s.get(0).unwrap(); - let oldname = s.get(0).unwrap(); + let oldname = s.get(1).unwrap(); o.insert(newname.to_string(), oldname.to_string()); } else { panic!("invalid module mapping: '{}'", m) @@ -152,17 +152,18 @@ fn polyfill(new: &witx::Document, old: &witx::Document, module_mapping: &HashMap oldfunc.name.as_str(), oldparam.name.as_str(), ); - } else if !newparam.tref.representable(&oldparam.tref) { + } else if newparam.tref.representable(&oldparam.tref) != RepEquality::Eq { println!( - "{}:{} param {}:{:?} has incompatible representation with {}:{} param {}:{:?}", + "{}:{} param {}:{} is {:?} of {}:{} param {}:{}", newmodulename, newfunc.name.as_str(), newparam.name.as_str(), - newparam.tref, + newparam.tref.to_sexpr(), + newparam.tref.representable(&oldparam.tref), oldmodulename, oldfunc.name.as_str(), oldparam.name.as_str(), - newparam.tref, + newparam.tref.to_sexpr(), ); } } @@ -188,17 +189,18 @@ fn polyfill(new: &witx::Document, old: &witx::Document, module_mapping: &HashMap oldfunc.name.as_str(), oldresult.name.as_str(), ); - } else if !newresult.tref.representable(&oldresult.tref) { + } else if newresult.tref.representable(&oldresult.tref) != RepEquality::Eq { println!( - "{}:{} result {}:{:?} has incompatible representation with {}:{} result {}:{:?}", + "{}:{} result {}:{} is {:?} of {}:{} result {}:{}", newmodulename, newfunc.name.as_str(), newresult.name.as_str(), - newresult.tref, + newresult.tref.to_sexpr(), + newresult.tref.representable(&oldresult.tref), oldmodulename, oldfunc.name.as_str(), oldresult.name.as_str(), - newresult.tref, + newresult.tref.to_sexpr(), ); } } diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index c9ec34b1f..880f7613b 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -4,7 +4,7 @@ use std::fmt; impl fmt::Display for Document { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for d in self.typenames() { - write!(f, "{}\n", d.definition_sexpr())?; + write!(f, "{}\n", d.to_sexpr())?; } for m in self.modules() { write!(f, "{}\n", m.to_sexpr())?; @@ -69,13 +69,13 @@ impl SExpr { } impl Id { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { SExpr::ident(self.as_str()) } } impl BuiltinType { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { match self { BuiltinType::String => SExpr::word("string"), BuiltinType::U8 => SExpr::word("u8"), @@ -93,7 +93,7 @@ impl BuiltinType { } impl NamedType { - fn definition_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let body = self.dt.to_sexpr(); SExpr::docs( &self.docs, @@ -103,7 +103,7 @@ impl NamedType { } impl TypeRef { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { match self { TypeRef::Name(n) => n.name.to_sexpr(), TypeRef::Value(v) => v.to_sexpr(), @@ -112,7 +112,7 @@ impl TypeRef { } impl Type { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { match self { Type::Enum(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), @@ -136,7 +136,7 @@ impl Type { } impl EnumDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("enum"), self.repr.to_sexpr()]; let variants = self .variants @@ -148,7 +148,7 @@ impl EnumDatatype { } impl FlagsDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; let flags = self .flags @@ -160,7 +160,7 @@ impl FlagsDatatype { } impl StructDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("struct")]; let members = self .members @@ -181,7 +181,7 @@ impl StructDatatype { } impl UnionDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("union")]; let variants = self .variants @@ -202,7 +202,7 @@ impl UnionDatatype { } impl HandleDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("handle")]; let supertypes = self .supertypes @@ -213,7 +213,7 @@ impl HandleDatatype { } } impl IntRepr { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { match self { IntRepr::U8 => SExpr::word("u8"), IntRepr::U16 => SExpr::word("u16"), @@ -224,7 +224,7 @@ impl IntRepr { } impl Module { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("module"), self.name.to_sexpr()]; let definitions = self .imports() @@ -236,7 +236,7 @@ impl Module { } impl ModuleImport { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let variant = match self.variant { ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), }; @@ -252,7 +252,7 @@ impl ModuleImport { } impl InterfaceFunc { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![ SExpr::annot("interface"), SExpr::word("func"), diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs index 95de41fe7..c91813241 100644 --- a/proposals/clocks/tools/witx/src/representation.rs +++ b/proposals/clocks/tools/witx/src/representation.rs @@ -3,103 +3,122 @@ use crate::{ TypeRef, UnionDatatype, }; +// A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum RepEquality { + Eq, + Superset, + NotEq, +} + +impl RepEquality { + pub fn join(&self, rhs: &Self) -> Self { + match (self, rhs) { + (RepEquality::Eq, RepEquality::Eq) => RepEquality::Eq, + _ => RepEquality::NotEq, + } + } +} + pub trait Representable { - fn representable(&self, by: &Self) -> bool; - // XXX its not enough for this to be a bool. we need to give the recipe with which to represent - // it -does it correspond exactly, does it need an upcast, or does it not correspond at all? - // and so on for each member. - // for structs, one might be able to represent each other, but not in the same memory layout. - // this can be arbitrarily deep due to recursion. for ABI compatibility we may need - // structs to correspond exactly, but maybe builtintypes just need to be representable. for - // polyfilling, we may just need everything to be representable. - // so, really this should return an enum describing what sort of equality we found between - // the two types, and then let the caller make that policy decision. TODO: design exactly that - // enum, i guess? - // also what about equality of typeref? + fn representable(&self, by: &Self) -> RepEquality; } impl Representable for BuiltinType { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { // An unsigned integer can be used to represent an unsigned integer of smaller width. // Otherwise, types must be equal. + if self == by { + return RepEquality::Eq; + } match self { BuiltinType::U8 => match by { - BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 | BuiltinType::U8 => true, - _ => false, + BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 => RepEquality::Superset, + _ => RepEquality::NotEq, }, BuiltinType::U16 => match by { - BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 => true, - _ => false, + BuiltinType::U64 | BuiltinType::U32 => RepEquality::Superset, + _ => RepEquality::NotEq, }, BuiltinType::U32 => match by { - BuiltinType::U64 | BuiltinType::U32 => true, - _ => false, + BuiltinType::U64 => RepEquality::Superset, + _ => RepEquality::NotEq, }, - other => by == other, + _ => RepEquality::NotEq, } } } impl Representable for IntRepr { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { + if self == by { + return RepEquality::Eq; + } // An unsigned integer can be used to represent an unsigned integer of smaller width. match self { - IntRepr::U8 => true, IntRepr::U16 => match by { - IntRepr::U16 | IntRepr::U32 | IntRepr::U64 => true, - _ => false, + IntRepr::U32 | IntRepr::U64 => RepEquality::Superset, + _ => RepEquality::NotEq, }, IntRepr::U32 => match by { - IntRepr::U32 | IntRepr::U64 => true, - _ => false, + IntRepr::U64 => RepEquality::Superset, + _ => RepEquality::NotEq, }, - IntRepr::U64 => *by == IntRepr::U64, + _ => RepEquality::NotEq, } } } impl Representable for EnumDatatype { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { // Integer representation must be compatible - if !by.repr.representable(&self.repr) { - return false; + if self.repr.representable(&by.repr) == RepEquality::NotEq { + return RepEquality::NotEq; } // For each variant in self, must have variant of same name and position in by: for (ix, v) in self.variants.iter().enumerate() { if let Some(by_v) = by.variants.get(ix) { if by_v.name != v.name { - return false; + return RepEquality::NotEq; } } else { - return false; + return RepEquality::NotEq; } } - true + if by.variants.len() > self.variants.len() { + RepEquality::Superset + } else { + self.repr.representable(&by.repr) + } } } impl Representable for FlagsDatatype { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { // Integer representation must be compatible - if !by.repr.representable(&self.repr) { - return false; + if self.repr.representable(&by.repr) == RepEquality::NotEq { + return RepEquality::NotEq; } // For each flag in self, must have flag of same name and position in by: for (ix, f) in self.flags.iter().enumerate() { if let Some(by_f) = by.flags.get(ix) { if by_f.name != f.name { - return false; + return RepEquality::NotEq; } } else { - return false; + return RepEquality::NotEq; } } - true + if by.flags.len() > self.flags.len() { + RepEquality::Superset + } else { + self.repr.representable(&by.repr) + } } } impl Representable for HandleDatatype { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { // Handles must have the same set of named supertypes. Anonymous supertypes are never // equal, and the validator should probably make sure these are not allowed, because // what would that even mean?? @@ -110,44 +129,64 @@ impl Representable for HandleDatatype { TypeRef::Name(by_nt) if by_nt.name == nt.name => Some(by_nt), _ => None, }) { - if !nt.dt.representable(&by_nt.dt) { - return false; + if nt.dt.representable(&by_nt.dt) == RepEquality::NotEq { + return RepEquality::NotEq; } } else { - return false; + return RepEquality::NotEq; } } TypeRef::Value(_) => { - return false; + return RepEquality::NotEq; } } } - true + RepEquality::Eq } } impl Representable for StructDatatype { - fn representable(&self, _by: &Self) -> bool { - unimplemented!( - "this one is hard - need more than a bool for this return type to really describe it" - ) + fn representable(&self, by: &Self) -> RepEquality { + if self.members.len() != by.members.len() { + return RepEquality::NotEq; + } + for (m, bym) in self.members.iter().zip(by.members.iter()) { + if m.name != bym.name { + return RepEquality::NotEq; + } + if m.tref.type_().representable(&*bym.tref.type_()) != RepEquality::Eq { + return RepEquality::NotEq; + } + } + RepEquality::Eq } } impl Representable for UnionDatatype { - fn representable(&self, _by: &Self) -> bool { - unimplemented!("this one is hard") + fn representable(&self, by: &Self) -> RepEquality { + if self.variants.len() > by.variants.len() { + return RepEquality::NotEq; + } + for (v, byv) in self.variants.iter().zip(by.variants.iter()) { + if v.name != byv.name { + return RepEquality::NotEq; + } + if v.tref.type_().representable(&*byv.tref.type_()) != RepEquality::Eq { + return RepEquality::NotEq; + } + } + RepEquality::Eq } } impl Representable for TypeRef { - fn representable(&self, _by: &Self) -> bool { - unimplemented!("this one is hard - representable by type_() is appropriate in some cases, some times you may want precise name equality as well") + fn representable(&self, by: &Self) -> RepEquality { + self.type_().representable(&*by.type_()) } } impl Representable for Type { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { match (&self, &by) { (Type::Enum(s), Type::Enum(b)) => s.representable(b), (Type::Flags(s), Type::Flags(b)) => s.representable(b), @@ -158,7 +197,7 @@ impl Representable for Type { (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), (Type::Builtin(s), Type::Builtin(b)) => s.representable(b), - _ => false, + _ => RepEquality::NotEq, } } } From 7b43e2489b756d6d8e523ec6c48e8e06241546c0 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 2 Dec 2019 11:59:06 -0800 Subject: [PATCH 0347/1772] witx polyfill: now outputs something vaguely useful --- proposals/random/tools/witx/src/lib.rs | 2 +- proposals/random/tools/witx/src/main.rs | 26 +-- proposals/random/tools/witx/src/render.rs | 30 ++-- .../random/tools/witx/src/representation.rs | 149 +++++++++++------- 4 files changed, 124 insertions(+), 83 deletions(-) diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 560bdcb71..815bccc94 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -29,7 +29,7 @@ pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; pub use render::SExpr; pub use validate::ValidationError; -pub use representation::Representable; +pub use representation::{Representable, RepEquality}; use std::path::{Path, PathBuf}; use thiserror::Error; diff --git a/proposals/random/tools/witx/src/main.rs b/proposals/random/tools/witx/src/main.rs index 359f2df1d..8a62dcf5f 100644 --- a/proposals/random/tools/witx/src/main.rs +++ b/proposals/random/tools/witx/src/main.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use std::fs::File; use std::io::Write; use std::process; -use witx::{load, Documentation}; +use witx::{load, Documentation, RepEquality}; pub fn main() { let app = App::new("witx") @@ -106,12 +106,12 @@ fn parse_module_mapping(ms: &[&str]) -> HashMap { let mut o = HashMap::new(); for m in ms { let s = m.split('=').collect::>(); - if s.len() == 0 { + if s.len() == 1 { let mname = s.get(0).unwrap(); o.insert(mname.to_string(), mname.to_string()); - } else if s.len() == 1 { + } else if s.len() == 2 { let newname = s.get(0).unwrap(); - let oldname = s.get(0).unwrap(); + let oldname = s.get(1).unwrap(); o.insert(newname.to_string(), oldname.to_string()); } else { panic!("invalid module mapping: '{}'", m) @@ -152,17 +152,18 @@ fn polyfill(new: &witx::Document, old: &witx::Document, module_mapping: &HashMap oldfunc.name.as_str(), oldparam.name.as_str(), ); - } else if !newparam.tref.representable(&oldparam.tref) { + } else if newparam.tref.representable(&oldparam.tref) != RepEquality::Eq { println!( - "{}:{} param {}:{:?} has incompatible representation with {}:{} param {}:{:?}", + "{}:{} param {}:{} is {:?} of {}:{} param {}:{}", newmodulename, newfunc.name.as_str(), newparam.name.as_str(), - newparam.tref, + newparam.tref.to_sexpr(), + newparam.tref.representable(&oldparam.tref), oldmodulename, oldfunc.name.as_str(), oldparam.name.as_str(), - newparam.tref, + newparam.tref.to_sexpr(), ); } } @@ -188,17 +189,18 @@ fn polyfill(new: &witx::Document, old: &witx::Document, module_mapping: &HashMap oldfunc.name.as_str(), oldresult.name.as_str(), ); - } else if !newresult.tref.representable(&oldresult.tref) { + } else if newresult.tref.representable(&oldresult.tref) != RepEquality::Eq { println!( - "{}:{} result {}:{:?} has incompatible representation with {}:{} result {}:{:?}", + "{}:{} result {}:{} is {:?} of {}:{} result {}:{}", newmodulename, newfunc.name.as_str(), newresult.name.as_str(), - newresult.tref, + newresult.tref.to_sexpr(), + newresult.tref.representable(&oldresult.tref), oldmodulename, oldfunc.name.as_str(), oldresult.name.as_str(), - newresult.tref, + newresult.tref.to_sexpr(), ); } } diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index c9ec34b1f..880f7613b 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -4,7 +4,7 @@ use std::fmt; impl fmt::Display for Document { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for d in self.typenames() { - write!(f, "{}\n", d.definition_sexpr())?; + write!(f, "{}\n", d.to_sexpr())?; } for m in self.modules() { write!(f, "{}\n", m.to_sexpr())?; @@ -69,13 +69,13 @@ impl SExpr { } impl Id { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { SExpr::ident(self.as_str()) } } impl BuiltinType { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { match self { BuiltinType::String => SExpr::word("string"), BuiltinType::U8 => SExpr::word("u8"), @@ -93,7 +93,7 @@ impl BuiltinType { } impl NamedType { - fn definition_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let body = self.dt.to_sexpr(); SExpr::docs( &self.docs, @@ -103,7 +103,7 @@ impl NamedType { } impl TypeRef { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { match self { TypeRef::Name(n) => n.name.to_sexpr(), TypeRef::Value(v) => v.to_sexpr(), @@ -112,7 +112,7 @@ impl TypeRef { } impl Type { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { match self { Type::Enum(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), @@ -136,7 +136,7 @@ impl Type { } impl EnumDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("enum"), self.repr.to_sexpr()]; let variants = self .variants @@ -148,7 +148,7 @@ impl EnumDatatype { } impl FlagsDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; let flags = self .flags @@ -160,7 +160,7 @@ impl FlagsDatatype { } impl StructDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("struct")]; let members = self .members @@ -181,7 +181,7 @@ impl StructDatatype { } impl UnionDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("union")]; let variants = self .variants @@ -202,7 +202,7 @@ impl UnionDatatype { } impl HandleDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("handle")]; let supertypes = self .supertypes @@ -213,7 +213,7 @@ impl HandleDatatype { } } impl IntRepr { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { match self { IntRepr::U8 => SExpr::word("u8"), IntRepr::U16 => SExpr::word("u16"), @@ -224,7 +224,7 @@ impl IntRepr { } impl Module { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("module"), self.name.to_sexpr()]; let definitions = self .imports() @@ -236,7 +236,7 @@ impl Module { } impl ModuleImport { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let variant = match self.variant { ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), }; @@ -252,7 +252,7 @@ impl ModuleImport { } impl InterfaceFunc { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![ SExpr::annot("interface"), SExpr::word("func"), diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs index 95de41fe7..c91813241 100644 --- a/proposals/random/tools/witx/src/representation.rs +++ b/proposals/random/tools/witx/src/representation.rs @@ -3,103 +3,122 @@ use crate::{ TypeRef, UnionDatatype, }; +// A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum RepEquality { + Eq, + Superset, + NotEq, +} + +impl RepEquality { + pub fn join(&self, rhs: &Self) -> Self { + match (self, rhs) { + (RepEquality::Eq, RepEquality::Eq) => RepEquality::Eq, + _ => RepEquality::NotEq, + } + } +} + pub trait Representable { - fn representable(&self, by: &Self) -> bool; - // XXX its not enough for this to be a bool. we need to give the recipe with which to represent - // it -does it correspond exactly, does it need an upcast, or does it not correspond at all? - // and so on for each member. - // for structs, one might be able to represent each other, but not in the same memory layout. - // this can be arbitrarily deep due to recursion. for ABI compatibility we may need - // structs to correspond exactly, but maybe builtintypes just need to be representable. for - // polyfilling, we may just need everything to be representable. - // so, really this should return an enum describing what sort of equality we found between - // the two types, and then let the caller make that policy decision. TODO: design exactly that - // enum, i guess? - // also what about equality of typeref? + fn representable(&self, by: &Self) -> RepEquality; } impl Representable for BuiltinType { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { // An unsigned integer can be used to represent an unsigned integer of smaller width. // Otherwise, types must be equal. + if self == by { + return RepEquality::Eq; + } match self { BuiltinType::U8 => match by { - BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 | BuiltinType::U8 => true, - _ => false, + BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 => RepEquality::Superset, + _ => RepEquality::NotEq, }, BuiltinType::U16 => match by { - BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 => true, - _ => false, + BuiltinType::U64 | BuiltinType::U32 => RepEquality::Superset, + _ => RepEquality::NotEq, }, BuiltinType::U32 => match by { - BuiltinType::U64 | BuiltinType::U32 => true, - _ => false, + BuiltinType::U64 => RepEquality::Superset, + _ => RepEquality::NotEq, }, - other => by == other, + _ => RepEquality::NotEq, } } } impl Representable for IntRepr { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { + if self == by { + return RepEquality::Eq; + } // An unsigned integer can be used to represent an unsigned integer of smaller width. match self { - IntRepr::U8 => true, IntRepr::U16 => match by { - IntRepr::U16 | IntRepr::U32 | IntRepr::U64 => true, - _ => false, + IntRepr::U32 | IntRepr::U64 => RepEquality::Superset, + _ => RepEquality::NotEq, }, IntRepr::U32 => match by { - IntRepr::U32 | IntRepr::U64 => true, - _ => false, + IntRepr::U64 => RepEquality::Superset, + _ => RepEquality::NotEq, }, - IntRepr::U64 => *by == IntRepr::U64, + _ => RepEquality::NotEq, } } } impl Representable for EnumDatatype { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { // Integer representation must be compatible - if !by.repr.representable(&self.repr) { - return false; + if self.repr.representable(&by.repr) == RepEquality::NotEq { + return RepEquality::NotEq; } // For each variant in self, must have variant of same name and position in by: for (ix, v) in self.variants.iter().enumerate() { if let Some(by_v) = by.variants.get(ix) { if by_v.name != v.name { - return false; + return RepEquality::NotEq; } } else { - return false; + return RepEquality::NotEq; } } - true + if by.variants.len() > self.variants.len() { + RepEquality::Superset + } else { + self.repr.representable(&by.repr) + } } } impl Representable for FlagsDatatype { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { // Integer representation must be compatible - if !by.repr.representable(&self.repr) { - return false; + if self.repr.representable(&by.repr) == RepEquality::NotEq { + return RepEquality::NotEq; } // For each flag in self, must have flag of same name and position in by: for (ix, f) in self.flags.iter().enumerate() { if let Some(by_f) = by.flags.get(ix) { if by_f.name != f.name { - return false; + return RepEquality::NotEq; } } else { - return false; + return RepEquality::NotEq; } } - true + if by.flags.len() > self.flags.len() { + RepEquality::Superset + } else { + self.repr.representable(&by.repr) + } } } impl Representable for HandleDatatype { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { // Handles must have the same set of named supertypes. Anonymous supertypes are never // equal, and the validator should probably make sure these are not allowed, because // what would that even mean?? @@ -110,44 +129,64 @@ impl Representable for HandleDatatype { TypeRef::Name(by_nt) if by_nt.name == nt.name => Some(by_nt), _ => None, }) { - if !nt.dt.representable(&by_nt.dt) { - return false; + if nt.dt.representable(&by_nt.dt) == RepEquality::NotEq { + return RepEquality::NotEq; } } else { - return false; + return RepEquality::NotEq; } } TypeRef::Value(_) => { - return false; + return RepEquality::NotEq; } } } - true + RepEquality::Eq } } impl Representable for StructDatatype { - fn representable(&self, _by: &Self) -> bool { - unimplemented!( - "this one is hard - need more than a bool for this return type to really describe it" - ) + fn representable(&self, by: &Self) -> RepEquality { + if self.members.len() != by.members.len() { + return RepEquality::NotEq; + } + for (m, bym) in self.members.iter().zip(by.members.iter()) { + if m.name != bym.name { + return RepEquality::NotEq; + } + if m.tref.type_().representable(&*bym.tref.type_()) != RepEquality::Eq { + return RepEquality::NotEq; + } + } + RepEquality::Eq } } impl Representable for UnionDatatype { - fn representable(&self, _by: &Self) -> bool { - unimplemented!("this one is hard") + fn representable(&self, by: &Self) -> RepEquality { + if self.variants.len() > by.variants.len() { + return RepEquality::NotEq; + } + for (v, byv) in self.variants.iter().zip(by.variants.iter()) { + if v.name != byv.name { + return RepEquality::NotEq; + } + if v.tref.type_().representable(&*byv.tref.type_()) != RepEquality::Eq { + return RepEquality::NotEq; + } + } + RepEquality::Eq } } impl Representable for TypeRef { - fn representable(&self, _by: &Self) -> bool { - unimplemented!("this one is hard - representable by type_() is appropriate in some cases, some times you may want precise name equality as well") + fn representable(&self, by: &Self) -> RepEquality { + self.type_().representable(&*by.type_()) } } impl Representable for Type { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { match (&self, &by) { (Type::Enum(s), Type::Enum(b)) => s.representable(b), (Type::Flags(s), Type::Flags(b)) => s.representable(b), @@ -158,7 +197,7 @@ impl Representable for Type { (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), (Type::Builtin(s), Type::Builtin(b)) => s.representable(b), - _ => false, + _ => RepEquality::NotEq, } } } From 5759cfc9d12bfeb6d9d16a2201248967cdd41ee3 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 2 Dec 2019 11:59:06 -0800 Subject: [PATCH 0348/1772] witx polyfill: now outputs something vaguely useful --- proposals/filesystem/tools/witx/src/lib.rs | 2 +- proposals/filesystem/tools/witx/src/main.rs | 26 +-- proposals/filesystem/tools/witx/src/render.rs | 30 ++-- .../tools/witx/src/representation.rs | 149 +++++++++++------- 4 files changed, 124 insertions(+), 83 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 560bdcb71..815bccc94 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -29,7 +29,7 @@ pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; pub use render::SExpr; pub use validate::ValidationError; -pub use representation::Representable; +pub use representation::{Representable, RepEquality}; use std::path::{Path, PathBuf}; use thiserror::Error; diff --git a/proposals/filesystem/tools/witx/src/main.rs b/proposals/filesystem/tools/witx/src/main.rs index 359f2df1d..8a62dcf5f 100644 --- a/proposals/filesystem/tools/witx/src/main.rs +++ b/proposals/filesystem/tools/witx/src/main.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use std::fs::File; use std::io::Write; use std::process; -use witx::{load, Documentation}; +use witx::{load, Documentation, RepEquality}; pub fn main() { let app = App::new("witx") @@ -106,12 +106,12 @@ fn parse_module_mapping(ms: &[&str]) -> HashMap { let mut o = HashMap::new(); for m in ms { let s = m.split('=').collect::>(); - if s.len() == 0 { + if s.len() == 1 { let mname = s.get(0).unwrap(); o.insert(mname.to_string(), mname.to_string()); - } else if s.len() == 1 { + } else if s.len() == 2 { let newname = s.get(0).unwrap(); - let oldname = s.get(0).unwrap(); + let oldname = s.get(1).unwrap(); o.insert(newname.to_string(), oldname.to_string()); } else { panic!("invalid module mapping: '{}'", m) @@ -152,17 +152,18 @@ fn polyfill(new: &witx::Document, old: &witx::Document, module_mapping: &HashMap oldfunc.name.as_str(), oldparam.name.as_str(), ); - } else if !newparam.tref.representable(&oldparam.tref) { + } else if newparam.tref.representable(&oldparam.tref) != RepEquality::Eq { println!( - "{}:{} param {}:{:?} has incompatible representation with {}:{} param {}:{:?}", + "{}:{} param {}:{} is {:?} of {}:{} param {}:{}", newmodulename, newfunc.name.as_str(), newparam.name.as_str(), - newparam.tref, + newparam.tref.to_sexpr(), + newparam.tref.representable(&oldparam.tref), oldmodulename, oldfunc.name.as_str(), oldparam.name.as_str(), - newparam.tref, + newparam.tref.to_sexpr(), ); } } @@ -188,17 +189,18 @@ fn polyfill(new: &witx::Document, old: &witx::Document, module_mapping: &HashMap oldfunc.name.as_str(), oldresult.name.as_str(), ); - } else if !newresult.tref.representable(&oldresult.tref) { + } else if newresult.tref.representable(&oldresult.tref) != RepEquality::Eq { println!( - "{}:{} result {}:{:?} has incompatible representation with {}:{} result {}:{:?}", + "{}:{} result {}:{} is {:?} of {}:{} result {}:{}", newmodulename, newfunc.name.as_str(), newresult.name.as_str(), - newresult.tref, + newresult.tref.to_sexpr(), + newresult.tref.representable(&oldresult.tref), oldmodulename, oldfunc.name.as_str(), oldresult.name.as_str(), - newresult.tref, + newresult.tref.to_sexpr(), ); } } diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index c9ec34b1f..880f7613b 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -4,7 +4,7 @@ use std::fmt; impl fmt::Display for Document { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for d in self.typenames() { - write!(f, "{}\n", d.definition_sexpr())?; + write!(f, "{}\n", d.to_sexpr())?; } for m in self.modules() { write!(f, "{}\n", m.to_sexpr())?; @@ -69,13 +69,13 @@ impl SExpr { } impl Id { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { SExpr::ident(self.as_str()) } } impl BuiltinType { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { match self { BuiltinType::String => SExpr::word("string"), BuiltinType::U8 => SExpr::word("u8"), @@ -93,7 +93,7 @@ impl BuiltinType { } impl NamedType { - fn definition_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let body = self.dt.to_sexpr(); SExpr::docs( &self.docs, @@ -103,7 +103,7 @@ impl NamedType { } impl TypeRef { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { match self { TypeRef::Name(n) => n.name.to_sexpr(), TypeRef::Value(v) => v.to_sexpr(), @@ -112,7 +112,7 @@ impl TypeRef { } impl Type { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { match self { Type::Enum(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), @@ -136,7 +136,7 @@ impl Type { } impl EnumDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("enum"), self.repr.to_sexpr()]; let variants = self .variants @@ -148,7 +148,7 @@ impl EnumDatatype { } impl FlagsDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; let flags = self .flags @@ -160,7 +160,7 @@ impl FlagsDatatype { } impl StructDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("struct")]; let members = self .members @@ -181,7 +181,7 @@ impl StructDatatype { } impl UnionDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("union")]; let variants = self .variants @@ -202,7 +202,7 @@ impl UnionDatatype { } impl HandleDatatype { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("handle")]; let supertypes = self .supertypes @@ -213,7 +213,7 @@ impl HandleDatatype { } } impl IntRepr { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { match self { IntRepr::U8 => SExpr::word("u8"), IntRepr::U16 => SExpr::word("u16"), @@ -224,7 +224,7 @@ impl IntRepr { } impl Module { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("module"), self.name.to_sexpr()]; let definitions = self .imports() @@ -236,7 +236,7 @@ impl Module { } impl ModuleImport { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let variant = match self.variant { ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), }; @@ -252,7 +252,7 @@ impl ModuleImport { } impl InterfaceFunc { - fn to_sexpr(&self) -> SExpr { + pub fn to_sexpr(&self) -> SExpr { let header = vec![ SExpr::annot("interface"), SExpr::word("func"), diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs index 95de41fe7..c91813241 100644 --- a/proposals/filesystem/tools/witx/src/representation.rs +++ b/proposals/filesystem/tools/witx/src/representation.rs @@ -3,103 +3,122 @@ use crate::{ TypeRef, UnionDatatype, }; +// A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum RepEquality { + Eq, + Superset, + NotEq, +} + +impl RepEquality { + pub fn join(&self, rhs: &Self) -> Self { + match (self, rhs) { + (RepEquality::Eq, RepEquality::Eq) => RepEquality::Eq, + _ => RepEquality::NotEq, + } + } +} + pub trait Representable { - fn representable(&self, by: &Self) -> bool; - // XXX its not enough for this to be a bool. we need to give the recipe with which to represent - // it -does it correspond exactly, does it need an upcast, or does it not correspond at all? - // and so on for each member. - // for structs, one might be able to represent each other, but not in the same memory layout. - // this can be arbitrarily deep due to recursion. for ABI compatibility we may need - // structs to correspond exactly, but maybe builtintypes just need to be representable. for - // polyfilling, we may just need everything to be representable. - // so, really this should return an enum describing what sort of equality we found between - // the two types, and then let the caller make that policy decision. TODO: design exactly that - // enum, i guess? - // also what about equality of typeref? + fn representable(&self, by: &Self) -> RepEquality; } impl Representable for BuiltinType { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { // An unsigned integer can be used to represent an unsigned integer of smaller width. // Otherwise, types must be equal. + if self == by { + return RepEquality::Eq; + } match self { BuiltinType::U8 => match by { - BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 | BuiltinType::U8 => true, - _ => false, + BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 => RepEquality::Superset, + _ => RepEquality::NotEq, }, BuiltinType::U16 => match by { - BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 => true, - _ => false, + BuiltinType::U64 | BuiltinType::U32 => RepEquality::Superset, + _ => RepEquality::NotEq, }, BuiltinType::U32 => match by { - BuiltinType::U64 | BuiltinType::U32 => true, - _ => false, + BuiltinType::U64 => RepEquality::Superset, + _ => RepEquality::NotEq, }, - other => by == other, + _ => RepEquality::NotEq, } } } impl Representable for IntRepr { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { + if self == by { + return RepEquality::Eq; + } // An unsigned integer can be used to represent an unsigned integer of smaller width. match self { - IntRepr::U8 => true, IntRepr::U16 => match by { - IntRepr::U16 | IntRepr::U32 | IntRepr::U64 => true, - _ => false, + IntRepr::U32 | IntRepr::U64 => RepEquality::Superset, + _ => RepEquality::NotEq, }, IntRepr::U32 => match by { - IntRepr::U32 | IntRepr::U64 => true, - _ => false, + IntRepr::U64 => RepEquality::Superset, + _ => RepEquality::NotEq, }, - IntRepr::U64 => *by == IntRepr::U64, + _ => RepEquality::NotEq, } } } impl Representable for EnumDatatype { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { // Integer representation must be compatible - if !by.repr.representable(&self.repr) { - return false; + if self.repr.representable(&by.repr) == RepEquality::NotEq { + return RepEquality::NotEq; } // For each variant in self, must have variant of same name and position in by: for (ix, v) in self.variants.iter().enumerate() { if let Some(by_v) = by.variants.get(ix) { if by_v.name != v.name { - return false; + return RepEquality::NotEq; } } else { - return false; + return RepEquality::NotEq; } } - true + if by.variants.len() > self.variants.len() { + RepEquality::Superset + } else { + self.repr.representable(&by.repr) + } } } impl Representable for FlagsDatatype { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { // Integer representation must be compatible - if !by.repr.representable(&self.repr) { - return false; + if self.repr.representable(&by.repr) == RepEquality::NotEq { + return RepEquality::NotEq; } // For each flag in self, must have flag of same name and position in by: for (ix, f) in self.flags.iter().enumerate() { if let Some(by_f) = by.flags.get(ix) { if by_f.name != f.name { - return false; + return RepEquality::NotEq; } } else { - return false; + return RepEquality::NotEq; } } - true + if by.flags.len() > self.flags.len() { + RepEquality::Superset + } else { + self.repr.representable(&by.repr) + } } } impl Representable for HandleDatatype { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { // Handles must have the same set of named supertypes. Anonymous supertypes are never // equal, and the validator should probably make sure these are not allowed, because // what would that even mean?? @@ -110,44 +129,64 @@ impl Representable for HandleDatatype { TypeRef::Name(by_nt) if by_nt.name == nt.name => Some(by_nt), _ => None, }) { - if !nt.dt.representable(&by_nt.dt) { - return false; + if nt.dt.representable(&by_nt.dt) == RepEquality::NotEq { + return RepEquality::NotEq; } } else { - return false; + return RepEquality::NotEq; } } TypeRef::Value(_) => { - return false; + return RepEquality::NotEq; } } } - true + RepEquality::Eq } } impl Representable for StructDatatype { - fn representable(&self, _by: &Self) -> bool { - unimplemented!( - "this one is hard - need more than a bool for this return type to really describe it" - ) + fn representable(&self, by: &Self) -> RepEquality { + if self.members.len() != by.members.len() { + return RepEquality::NotEq; + } + for (m, bym) in self.members.iter().zip(by.members.iter()) { + if m.name != bym.name { + return RepEquality::NotEq; + } + if m.tref.type_().representable(&*bym.tref.type_()) != RepEquality::Eq { + return RepEquality::NotEq; + } + } + RepEquality::Eq } } impl Representable for UnionDatatype { - fn representable(&self, _by: &Self) -> bool { - unimplemented!("this one is hard") + fn representable(&self, by: &Self) -> RepEquality { + if self.variants.len() > by.variants.len() { + return RepEquality::NotEq; + } + for (v, byv) in self.variants.iter().zip(by.variants.iter()) { + if v.name != byv.name { + return RepEquality::NotEq; + } + if v.tref.type_().representable(&*byv.tref.type_()) != RepEquality::Eq { + return RepEquality::NotEq; + } + } + RepEquality::Eq } } impl Representable for TypeRef { - fn representable(&self, _by: &Self) -> bool { - unimplemented!("this one is hard - representable by type_() is appropriate in some cases, some times you may want precise name equality as well") + fn representable(&self, by: &Self) -> RepEquality { + self.type_().representable(&*by.type_()) } } impl Representable for Type { - fn representable(&self, by: &Self) -> bool { + fn representable(&self, by: &Self) -> RepEquality { match (&self, &by) { (Type::Enum(s), Type::Enum(b)) => s.representable(b), (Type::Flags(s), Type::Flags(b)) => s.representable(b), @@ -158,7 +197,7 @@ impl Representable for Type { (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), (Type::Builtin(s), Type::Builtin(b)) => s.representable(b), - _ => false, + _ => RepEquality::NotEq, } } } From 74f755e9294ec78bab92473768e29c8452ab930d Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 2 Dec 2019 16:40:56 -0800 Subject: [PATCH 0349/1772] consistiency: NamedType's TypeRef member should also be called tref --- proposals/clocks/tools/witx/src/ast.rs | 4 ++-- proposals/clocks/tools/witx/src/docs.rs | 2 +- proposals/clocks/tools/witx/src/render.rs | 2 +- proposals/clocks/tools/witx/src/representation.rs | 8 +++++++- proposals/clocks/tools/witx/src/validate.rs | 4 ++-- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 49fd56b1d..c3ce4eb64 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -123,13 +123,13 @@ impl TypeRef { #[derive(Debug, Clone, PartialEq, Eq)] pub struct NamedType { pub name: Id, - pub dt: TypeRef, + pub tref: TypeRef, pub docs: String, } impl NamedType { pub fn type_(&self) -> Rc { - self.dt.type_() + self.tref.type_() } } diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs index 511186a47..a6f79280c 100644 --- a/proposals/clocks/tools/witx/src/docs.rs +++ b/proposals/clocks/tools/witx/src/docs.rs @@ -39,7 +39,7 @@ impl BuiltinType { impl Documentation for NamedType { fn to_md(&self) -> String { - let body = match &self.dt { + let body = match &self.tref { TypeRef::Value(v) => match &**v { Type::Enum(a) => a.to_md(), Type::Flags(a) => a.to_md(), diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 880f7613b..2c08aef40 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -94,7 +94,7 @@ impl BuiltinType { impl NamedType { pub fn to_sexpr(&self) -> SExpr { - let body = self.dt.to_sexpr(); + let body = self.tref.to_sexpr(); SExpr::docs( &self.docs, SExpr::Vec(vec![SExpr::word("typename"), self.name.to_sexpr(), body]), diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs index c91813241..38a599c66 100644 --- a/proposals/clocks/tools/witx/src/representation.rs +++ b/proposals/clocks/tools/witx/src/representation.rs @@ -129,7 +129,7 @@ impl Representable for HandleDatatype { TypeRef::Name(by_nt) if by_nt.name == nt.name => Some(by_nt), _ => None, }) { - if nt.dt.representable(&by_nt.dt) == RepEquality::NotEq { + if nt.tref.representable(&by_nt.tref) == RepEquality::NotEq { return RepEquality::NotEq; } } else { @@ -185,6 +185,12 @@ impl Representable for TypeRef { } } +impl Representable for NamedType { + fn representable(&self, by: &Self) -> RepEquality { + self.tref.representable(&by.tref) + } +} + impl Representable for Type { fn representable(&self, by: &Self) -> RepEquality { match (&self, &by) { diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index de9e3e49c..a8d832056 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -164,11 +164,11 @@ impl DocValidationScope<'_> { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; let docs = comments.docs(); - let dt = self.validate_datatype(&decl.def, decl.ident.span())?; + let tref = self.validate_datatype(&decl.def, decl.ident.span())?; let rc_datatype = Rc::new(NamedType { name: name.clone(), - dt, + tref, docs, }); self.doc From 05f3624d5d4e58bc8530939da55dfd65bc6922ee Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 2 Dec 2019 16:40:56 -0800 Subject: [PATCH 0350/1772] consistiency: NamedType's TypeRef member should also be called tref --- proposals/random/tools/witx/src/ast.rs | 4 ++-- proposals/random/tools/witx/src/docs.rs | 2 +- proposals/random/tools/witx/src/render.rs | 2 +- proposals/random/tools/witx/src/representation.rs | 8 +++++++- proposals/random/tools/witx/src/validate.rs | 4 ++-- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 49fd56b1d..c3ce4eb64 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -123,13 +123,13 @@ impl TypeRef { #[derive(Debug, Clone, PartialEq, Eq)] pub struct NamedType { pub name: Id, - pub dt: TypeRef, + pub tref: TypeRef, pub docs: String, } impl NamedType { pub fn type_(&self) -> Rc { - self.dt.type_() + self.tref.type_() } } diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs index 511186a47..a6f79280c 100644 --- a/proposals/random/tools/witx/src/docs.rs +++ b/proposals/random/tools/witx/src/docs.rs @@ -39,7 +39,7 @@ impl BuiltinType { impl Documentation for NamedType { fn to_md(&self) -> String { - let body = match &self.dt { + let body = match &self.tref { TypeRef::Value(v) => match &**v { Type::Enum(a) => a.to_md(), Type::Flags(a) => a.to_md(), diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 880f7613b..2c08aef40 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -94,7 +94,7 @@ impl BuiltinType { impl NamedType { pub fn to_sexpr(&self) -> SExpr { - let body = self.dt.to_sexpr(); + let body = self.tref.to_sexpr(); SExpr::docs( &self.docs, SExpr::Vec(vec![SExpr::word("typename"), self.name.to_sexpr(), body]), diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs index c91813241..38a599c66 100644 --- a/proposals/random/tools/witx/src/representation.rs +++ b/proposals/random/tools/witx/src/representation.rs @@ -129,7 +129,7 @@ impl Representable for HandleDatatype { TypeRef::Name(by_nt) if by_nt.name == nt.name => Some(by_nt), _ => None, }) { - if nt.dt.representable(&by_nt.dt) == RepEquality::NotEq { + if nt.tref.representable(&by_nt.tref) == RepEquality::NotEq { return RepEquality::NotEq; } } else { @@ -185,6 +185,12 @@ impl Representable for TypeRef { } } +impl Representable for NamedType { + fn representable(&self, by: &Self) -> RepEquality { + self.tref.representable(&by.tref) + } +} + impl Representable for Type { fn representable(&self, by: &Self) -> RepEquality { match (&self, &by) { diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index de9e3e49c..a8d832056 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -164,11 +164,11 @@ impl DocValidationScope<'_> { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; let docs = comments.docs(); - let dt = self.validate_datatype(&decl.def, decl.ident.span())?; + let tref = self.validate_datatype(&decl.def, decl.ident.span())?; let rc_datatype = Rc::new(NamedType { name: name.clone(), - dt, + tref, docs, }); self.doc From 786e099dd813ffd65d62c12d16c14fc809d44e22 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 2 Dec 2019 16:40:56 -0800 Subject: [PATCH 0351/1772] consistiency: NamedType's TypeRef member should also be called tref --- proposals/filesystem/tools/witx/src/ast.rs | 4 ++-- proposals/filesystem/tools/witx/src/docs.rs | 2 +- proposals/filesystem/tools/witx/src/render.rs | 2 +- proposals/filesystem/tools/witx/src/representation.rs | 8 +++++++- proposals/filesystem/tools/witx/src/validate.rs | 4 ++-- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 49fd56b1d..c3ce4eb64 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -123,13 +123,13 @@ impl TypeRef { #[derive(Debug, Clone, PartialEq, Eq)] pub struct NamedType { pub name: Id, - pub dt: TypeRef, + pub tref: TypeRef, pub docs: String, } impl NamedType { pub fn type_(&self) -> Rc { - self.dt.type_() + self.tref.type_() } } diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs index 511186a47..a6f79280c 100644 --- a/proposals/filesystem/tools/witx/src/docs.rs +++ b/proposals/filesystem/tools/witx/src/docs.rs @@ -39,7 +39,7 @@ impl BuiltinType { impl Documentation for NamedType { fn to_md(&self) -> String { - let body = match &self.dt { + let body = match &self.tref { TypeRef::Value(v) => match &**v { Type::Enum(a) => a.to_md(), Type::Flags(a) => a.to_md(), diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 880f7613b..2c08aef40 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -94,7 +94,7 @@ impl BuiltinType { impl NamedType { pub fn to_sexpr(&self) -> SExpr { - let body = self.dt.to_sexpr(); + let body = self.tref.to_sexpr(); SExpr::docs( &self.docs, SExpr::Vec(vec![SExpr::word("typename"), self.name.to_sexpr(), body]), diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs index c91813241..38a599c66 100644 --- a/proposals/filesystem/tools/witx/src/representation.rs +++ b/proposals/filesystem/tools/witx/src/representation.rs @@ -129,7 +129,7 @@ impl Representable for HandleDatatype { TypeRef::Name(by_nt) if by_nt.name == nt.name => Some(by_nt), _ => None, }) { - if nt.dt.representable(&by_nt.dt) == RepEquality::NotEq { + if nt.tref.representable(&by_nt.tref) == RepEquality::NotEq { return RepEquality::NotEq; } } else { @@ -185,6 +185,12 @@ impl Representable for TypeRef { } } +impl Representable for NamedType { + fn representable(&self, by: &Self) -> RepEquality { + self.tref.representable(&by.tref) + } +} + impl Representable for Type { fn representable(&self, by: &Self) -> RepEquality { match (&self, &by) { diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index de9e3e49c..a8d832056 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -164,11 +164,11 @@ impl DocValidationScope<'_> { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; let docs = comments.docs(); - let dt = self.validate_datatype(&decl.def, decl.ident.span())?; + let tref = self.validate_datatype(&decl.def, decl.ident.span())?; let rc_datatype = Rc::new(NamedType { name: name.clone(), - dt, + tref, docs, }); self.doc From 191ee6767ebb909dea7725c07a27c4cd141a0830 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 2 Dec 2019 16:41:14 -0800 Subject: [PATCH 0352/1772] representation: bugfix, add tests --- .../clocks/tools/witx/src/representation.rs | 92 ++++++++++++++++++- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs index 38a599c66..819c0e82f 100644 --- a/proposals/clocks/tools/witx/src/representation.rs +++ b/proposals/clocks/tools/witx/src/representation.rs @@ -1,6 +1,6 @@ use crate::{ - BuiltinType, EnumDatatype, FlagsDatatype, HandleDatatype, IntRepr, StructDatatype, Type, - TypeRef, UnionDatatype, + BuiltinType, EnumDatatype, FlagsDatatype, HandleDatatype, IntRepr, NamedType, StructDatatype, + Type, TypeRef, UnionDatatype, }; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. @@ -175,7 +175,11 @@ impl Representable for UnionDatatype { return RepEquality::NotEq; } } - RepEquality::Eq + if by.variants.len() > self.variants.len() { + RepEquality::Superset + } else { + RepEquality::Eq + } } } @@ -207,3 +211,85 @@ impl Representable for Type { } } } + +#[cfg(test)] +mod test { + use super::*; + use crate::io::MockFs; + use crate::toplevel::parse_witx_with; + use crate::Id; + use std::rc::Rc; + + fn def_type(typename: &str, syntax: &str) -> Rc { + use std::path::Path; + let doc = parse_witx_with(&[Path::new("-")], &MockFs::new(&[("-", syntax)])) + .expect("parse witx doc"); + let t = doc.typename(&Id::new(typename)).expect("defined type"); + // Identity should always be true: + assert_eq!(t.representable(&t), RepEquality::Eq, "identity"); + t + } + + #[test] + fn different_typenames_equal() { + let a = def_type("a", "(typename $a (flags u32 $b $c))"); + let d = def_type("d", "(typename $d (flags u32 $b $c))"); + + assert_eq!(a.representable(&d), RepEquality::Eq); + assert_eq!(d.representable(&a), RepEquality::Eq); + } + + #[test] + fn different_flagnames_not_equal() { + let a = def_type("a", "(typename $a (flags u32 $b $c))"); + let d = def_type("d", "(typename $d (flags u32 $b $e))"); + + assert_eq!(a.representable(&d), RepEquality::NotEq); + assert_eq!(d.representable(&a), RepEquality::NotEq); + } + + #[test] + fn flag_superset() { + let base = def_type("a", "(typename $a (flags u32 $b $c))"); + let extra_flag = def_type("a", "(typename $a (flags u32 $b $c $d))"); + + assert_eq!(base.representable(&extra_flag), RepEquality::Superset); + assert_eq!(extra_flag.representable(&base), RepEquality::NotEq); + + let smaller_size = def_type("a", "(typename $a (flags u16 $b $c))"); + assert_eq!(smaller_size.representable(&base), RepEquality::Superset); + assert_eq!( + smaller_size.representable(&extra_flag), + RepEquality::Superset + ); + assert_eq!(base.representable(&smaller_size), RepEquality::NotEq); + } + + #[test] + fn enum_superset() { + let base = def_type("a", "(typename $a (enum u32 $b $c))"); + let extra_variant = def_type("a", "(typename $a (enum u32 $b $c $d))"); + + assert_eq!(base.representable(&extra_variant), RepEquality::Superset); + assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); + + let smaller_size = def_type("a", "(typename $a (enum u16 $b $c))"); + assert_eq!(smaller_size.representable(&base), RepEquality::Superset); + assert_eq!( + smaller_size.representable(&extra_variant), + RepEquality::Superset + ); + } + + #[test] + fn union_superset() { + let base = def_type("a", "(typename $a (union (field $b u32) (field $c f32)))"); + let extra_variant = def_type( + "a", + "(typename $a (union (field $b u32) (field $c f32) (field $d f64)))", + ); + + assert_eq!(base.representable(&extra_variant), RepEquality::Superset); + assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); + } +} From d16c667c7d1907240e7ab52ffb08aa4b420bd7a0 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 2 Dec 2019 16:41:14 -0800 Subject: [PATCH 0353/1772] representation: bugfix, add tests --- .../random/tools/witx/src/representation.rs | 92 ++++++++++++++++++- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs index 38a599c66..819c0e82f 100644 --- a/proposals/random/tools/witx/src/representation.rs +++ b/proposals/random/tools/witx/src/representation.rs @@ -1,6 +1,6 @@ use crate::{ - BuiltinType, EnumDatatype, FlagsDatatype, HandleDatatype, IntRepr, StructDatatype, Type, - TypeRef, UnionDatatype, + BuiltinType, EnumDatatype, FlagsDatatype, HandleDatatype, IntRepr, NamedType, StructDatatype, + Type, TypeRef, UnionDatatype, }; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. @@ -175,7 +175,11 @@ impl Representable for UnionDatatype { return RepEquality::NotEq; } } - RepEquality::Eq + if by.variants.len() > self.variants.len() { + RepEquality::Superset + } else { + RepEquality::Eq + } } } @@ -207,3 +211,85 @@ impl Representable for Type { } } } + +#[cfg(test)] +mod test { + use super::*; + use crate::io::MockFs; + use crate::toplevel::parse_witx_with; + use crate::Id; + use std::rc::Rc; + + fn def_type(typename: &str, syntax: &str) -> Rc { + use std::path::Path; + let doc = parse_witx_with(&[Path::new("-")], &MockFs::new(&[("-", syntax)])) + .expect("parse witx doc"); + let t = doc.typename(&Id::new(typename)).expect("defined type"); + // Identity should always be true: + assert_eq!(t.representable(&t), RepEquality::Eq, "identity"); + t + } + + #[test] + fn different_typenames_equal() { + let a = def_type("a", "(typename $a (flags u32 $b $c))"); + let d = def_type("d", "(typename $d (flags u32 $b $c))"); + + assert_eq!(a.representable(&d), RepEquality::Eq); + assert_eq!(d.representable(&a), RepEquality::Eq); + } + + #[test] + fn different_flagnames_not_equal() { + let a = def_type("a", "(typename $a (flags u32 $b $c))"); + let d = def_type("d", "(typename $d (flags u32 $b $e))"); + + assert_eq!(a.representable(&d), RepEquality::NotEq); + assert_eq!(d.representable(&a), RepEquality::NotEq); + } + + #[test] + fn flag_superset() { + let base = def_type("a", "(typename $a (flags u32 $b $c))"); + let extra_flag = def_type("a", "(typename $a (flags u32 $b $c $d))"); + + assert_eq!(base.representable(&extra_flag), RepEquality::Superset); + assert_eq!(extra_flag.representable(&base), RepEquality::NotEq); + + let smaller_size = def_type("a", "(typename $a (flags u16 $b $c))"); + assert_eq!(smaller_size.representable(&base), RepEquality::Superset); + assert_eq!( + smaller_size.representable(&extra_flag), + RepEquality::Superset + ); + assert_eq!(base.representable(&smaller_size), RepEquality::NotEq); + } + + #[test] + fn enum_superset() { + let base = def_type("a", "(typename $a (enum u32 $b $c))"); + let extra_variant = def_type("a", "(typename $a (enum u32 $b $c $d))"); + + assert_eq!(base.representable(&extra_variant), RepEquality::Superset); + assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); + + let smaller_size = def_type("a", "(typename $a (enum u16 $b $c))"); + assert_eq!(smaller_size.representable(&base), RepEquality::Superset); + assert_eq!( + smaller_size.representable(&extra_variant), + RepEquality::Superset + ); + } + + #[test] + fn union_superset() { + let base = def_type("a", "(typename $a (union (field $b u32) (field $c f32)))"); + let extra_variant = def_type( + "a", + "(typename $a (union (field $b u32) (field $c f32) (field $d f64)))", + ); + + assert_eq!(base.representable(&extra_variant), RepEquality::Superset); + assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); + } +} From 12af4f3a899bcb55618e3b8424f48f7c48dd5c8e Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 2 Dec 2019 16:41:14 -0800 Subject: [PATCH 0354/1772] representation: bugfix, add tests --- .../tools/witx/src/representation.rs | 92 ++++++++++++++++++- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs index 38a599c66..819c0e82f 100644 --- a/proposals/filesystem/tools/witx/src/representation.rs +++ b/proposals/filesystem/tools/witx/src/representation.rs @@ -1,6 +1,6 @@ use crate::{ - BuiltinType, EnumDatatype, FlagsDatatype, HandleDatatype, IntRepr, StructDatatype, Type, - TypeRef, UnionDatatype, + BuiltinType, EnumDatatype, FlagsDatatype, HandleDatatype, IntRepr, NamedType, StructDatatype, + Type, TypeRef, UnionDatatype, }; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. @@ -175,7 +175,11 @@ impl Representable for UnionDatatype { return RepEquality::NotEq; } } - RepEquality::Eq + if by.variants.len() > self.variants.len() { + RepEquality::Superset + } else { + RepEquality::Eq + } } } @@ -207,3 +211,85 @@ impl Representable for Type { } } } + +#[cfg(test)] +mod test { + use super::*; + use crate::io::MockFs; + use crate::toplevel::parse_witx_with; + use crate::Id; + use std::rc::Rc; + + fn def_type(typename: &str, syntax: &str) -> Rc { + use std::path::Path; + let doc = parse_witx_with(&[Path::new("-")], &MockFs::new(&[("-", syntax)])) + .expect("parse witx doc"); + let t = doc.typename(&Id::new(typename)).expect("defined type"); + // Identity should always be true: + assert_eq!(t.representable(&t), RepEquality::Eq, "identity"); + t + } + + #[test] + fn different_typenames_equal() { + let a = def_type("a", "(typename $a (flags u32 $b $c))"); + let d = def_type("d", "(typename $d (flags u32 $b $c))"); + + assert_eq!(a.representable(&d), RepEquality::Eq); + assert_eq!(d.representable(&a), RepEquality::Eq); + } + + #[test] + fn different_flagnames_not_equal() { + let a = def_type("a", "(typename $a (flags u32 $b $c))"); + let d = def_type("d", "(typename $d (flags u32 $b $e))"); + + assert_eq!(a.representable(&d), RepEquality::NotEq); + assert_eq!(d.representable(&a), RepEquality::NotEq); + } + + #[test] + fn flag_superset() { + let base = def_type("a", "(typename $a (flags u32 $b $c))"); + let extra_flag = def_type("a", "(typename $a (flags u32 $b $c $d))"); + + assert_eq!(base.representable(&extra_flag), RepEquality::Superset); + assert_eq!(extra_flag.representable(&base), RepEquality::NotEq); + + let smaller_size = def_type("a", "(typename $a (flags u16 $b $c))"); + assert_eq!(smaller_size.representable(&base), RepEquality::Superset); + assert_eq!( + smaller_size.representable(&extra_flag), + RepEquality::Superset + ); + assert_eq!(base.representable(&smaller_size), RepEquality::NotEq); + } + + #[test] + fn enum_superset() { + let base = def_type("a", "(typename $a (enum u32 $b $c))"); + let extra_variant = def_type("a", "(typename $a (enum u32 $b $c $d))"); + + assert_eq!(base.representable(&extra_variant), RepEquality::Superset); + assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); + + let smaller_size = def_type("a", "(typename $a (enum u16 $b $c))"); + assert_eq!(smaller_size.representable(&base), RepEquality::Superset); + assert_eq!( + smaller_size.representable(&extra_variant), + RepEquality::Superset + ); + } + + #[test] + fn union_superset() { + let base = def_type("a", "(typename $a (union (field $b u32) (field $c f32)))"); + let extra_variant = def_type( + "a", + "(typename $a (union (field $b u32) (field $c f32) (field $d f64)))", + ); + + assert_eq!(base.representable(&extra_variant), RepEquality::Superset); + assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); + } +} From 1874a6099121137dcaf3d7be527468c835fed03f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 3 Dec 2019 20:35:02 -0800 Subject: [PATCH 0355/1772] polyfill: produce a reasonably nice report --- proposals/clocks/tools/witx/src/docs.rs | 4 +- proposals/clocks/tools/witx/src/lib.rs | 7 +- proposals/clocks/tools/witx/src/main.rs | 106 +------ proposals/clocks/tools/witx/src/polyfill.rs | 268 ++++++++++++++++++ .../clocks/tools/witx/src/representation.rs | 48 ++-- 5 files changed, 312 insertions(+), 121 deletions(-) create mode 100644 proposals/clocks/tools/witx/src/polyfill.rs diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs index a6f79280c..162e36720 100644 --- a/proposals/clocks/tools/witx/src/docs.rs +++ b/proposals/clocks/tools/witx/src/docs.rs @@ -20,7 +20,7 @@ impl Documentation for Document { } impl BuiltinType { - fn type_name(&self) -> &'static str { + pub fn type_name(&self) -> &'static str { match self { BuiltinType::String => "string", BuiltinType::U8 => "u8", @@ -58,7 +58,7 @@ impl Documentation for NamedType { } impl TypeRef { - fn type_name(&self) -> String { + pub fn type_name(&self) -> String { match self { TypeRef::Name(n) => n.name.as_str().to_string(), TypeRef::Value(ref v) => match &**v { diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 815bccc94..018b55133 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -8,13 +8,16 @@ mod docs; mod io; /// Witx syntax parsing from SExprs mod parser; +/// Calculate required polyfill between interfaces +pub mod polyfill; /// Render ast to text mod render; +/// Representational equality of types +mod representation; /// Resolve toplevel `use` declarations across files mod toplevel; /// Validate declarations into ast mod validate; -mod representation; pub use ast::{ BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, @@ -28,8 +31,8 @@ pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; pub use render::SExpr; +pub use representation::{RepEquality, Representable}; pub use validate::ValidationError; -pub use representation::{Representable, RepEquality}; use std::path::{Path, PathBuf}; use thiserror::Error; diff --git a/proposals/clocks/tools/witx/src/main.rs b/proposals/clocks/tools/witx/src/main.rs index 8a62dcf5f..8327ac3fb 100644 --- a/proposals/clocks/tools/witx/src/main.rs +++ b/proposals/clocks/tools/witx/src/main.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use std::fs::File; use std::io::Write; use std::process; -use witx::{load, Documentation, RepEquality}; +use witx::{load, Documentation}; pub fn main() { let app = App::new("witx") @@ -98,7 +98,12 @@ pub fn main() { .collect::>(); let module_mapping = parse_module_mapping(&module_mapping_args); - polyfill(&doc, &older_doc, &module_mapping); + let polyfill = witx::polyfill::Polyfill::new(&doc, &older_doc, &module_mapping) + .expect("calculate polyfill"); + println!("{}", polyfill.report()); + if app.is_present("verbose") { + println!("{:?}", polyfill); + } } } @@ -119,100 +124,3 @@ fn parse_module_mapping(ms: &[&str]) -> HashMap { } o } - -fn polyfill(new: &witx::Document, old: &witx::Document, module_mapping: &HashMap) { - use witx::Representable; - for (newmodulename, oldmodulename) in module_mapping { - let newmodule = new - .module(&witx::Id::new(newmodulename)) - .expect("module exists in new"); - let oldmodule = old - .module(&witx::Id::new(oldmodulename)) - .expect("module exists in old"); - - for oldfunc in oldmodule.funcs() { - if let Some(newfunc) = newmodule.func(&oldfunc.name) { - if newfunc.params.len() != oldfunc.params.len() { - println!( - "{}:{} has different number of params than {}:{}", - newmodulename, - newfunc.name.as_str(), - oldmodulename, - oldfunc.name.as_str() - ) - } else { - for (newparam, oldparam) in newfunc.params.iter().zip(oldfunc.params.iter()) { - if newparam.name != oldparam.name { - println!( - "{}:{} param {} doesnt match {}:{} param {}", - newmodulename, - newfunc.name.as_str(), - newparam.name.as_str(), - oldmodulename, - oldfunc.name.as_str(), - oldparam.name.as_str(), - ); - } else if newparam.tref.representable(&oldparam.tref) != RepEquality::Eq { - println!( - "{}:{} param {}:{} is {:?} of {}:{} param {}:{}", - newmodulename, - newfunc.name.as_str(), - newparam.name.as_str(), - newparam.tref.to_sexpr(), - newparam.tref.representable(&oldparam.tref), - oldmodulename, - oldfunc.name.as_str(), - oldparam.name.as_str(), - newparam.tref.to_sexpr(), - ); - } - } - } - if newfunc.results.len() != oldfunc.results.len() { - println!( - "{}:{} has different number of results than {}:{}", - newmodulename, - newfunc.name.as_str(), - oldmodulename, - oldfunc.name.as_str() - ) - } else { - for (newresult, oldresult) in newfunc.results.iter().zip(oldfunc.results.iter()) - { - if newresult.name != oldresult.name { - println!( - "{}:{} result {} doesnt match {}:{} result {}", - newmodulename, - newfunc.name.as_str(), - newresult.name.as_str(), - oldmodulename, - oldfunc.name.as_str(), - oldresult.name.as_str(), - ); - } else if newresult.tref.representable(&oldresult.tref) != RepEquality::Eq { - println!( - "{}:{} result {}:{} is {:?} of {}:{} result {}:{}", - newmodulename, - newfunc.name.as_str(), - newresult.name.as_str(), - newresult.tref.to_sexpr(), - newresult.tref.representable(&oldresult.tref), - oldmodulename, - oldfunc.name.as_str(), - oldresult.name.as_str(), - newresult.tref.to_sexpr(), - ); - } - } - } - } else { - println!( - "{}:{} does not correspond to function in {}", - oldmodulename, - oldfunc.name.as_str(), - newmodulename - ); - } - } - } -} diff --git a/proposals/clocks/tools/witx/src/polyfill.rs b/proposals/clocks/tools/witx/src/polyfill.rs new file mode 100644 index 000000000..492ee44fa --- /dev/null +++ b/proposals/clocks/tools/witx/src/polyfill.rs @@ -0,0 +1,268 @@ +use crate::{Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable}; +use std::collections::HashMap; +use std::rc::Rc; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum PolyfillError { + #[error("Module not present: {name:?}")] + ModuleNotPresent { name: Id }, + #[error("Function not present: {name:?}")] + FuncNotPresent { name: Id }, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Polyfill { + pub modules: Vec, +} + +impl Polyfill { + pub fn new( + new: &Document, + old: &Document, + module_mapping: &HashMap, // Will need a more sophisticated mapping - what about function names, argument names? + ) -> Result { + let mut modules = Vec::new(); + for (newname, oldname) in module_mapping { + let newname = Id::new(newname); + let oldname = Id::new(oldname); + let newmod = new + .module(&newname) + .ok_or_else(|| PolyfillError::ModuleNotPresent { name: newname })?; + let oldmod = old + .module(&oldname) + .ok_or_else(|| PolyfillError::ModuleNotPresent { name: oldname })?; + modules.push(ModulePolyfill::new(newmod, oldmod)?); + } + Ok(Polyfill { modules }) + } + + pub fn report(&self) -> String { + self.modules + .iter() + .map(|m| m.report()) + .collect::>() + .join("\n") + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ModulePolyfill { + pub new: Rc, + pub old: Rc, + pub funcs: Vec, +} + +impl ModulePolyfill { + pub fn new(new: Rc, old: Rc) -> Result { + let mut funcs = Vec::new(); + for oldfunc in old.funcs() { + let newfunc = new + .func(&oldfunc.name) + .ok_or_else(|| PolyfillError::FuncNotPresent { + name: oldfunc.name.clone(), + })?; + funcs.push(FuncPolyfill::new(newfunc, oldfunc)); + } + Ok(ModulePolyfill { new, old, funcs }) + } + + pub fn report(&self) -> String { + format!( + "Implement module {} in terms of {}:\n\t{}", + self.new.name.as_str(), + self.old.name.as_str(), + self.funcs + .iter() + .map(|f| f.report()) + .collect::>() + .join("\n\t"), + ) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FuncPolyfill { + pub new: Rc, + pub old: Rc, + pub mapped_params: Vec, + pub unknown_params: Vec, + pub mapped_results: Vec, + pub unknown_results: Vec, +} + +impl FuncPolyfill { + pub fn new(new: Rc, old: Rc) -> FuncPolyfill { + let mut mapped_params = Vec::new(); + let mut unknown_params = Vec::new(); + + // Old function is called. Need to map each of its parameters to the new function: + for old_param in old.params.iter() { + if let Some(new_param) = new.params.iter().find(|p| p.name == old_param.name) { + mapped_params.push(ParamPolyfill { + new: new_param.clone(), + old: old_param.clone(), + // Call new param type with old param: + repeq : old_param + .tref + .type_() + .representable(&new_param.tref.type_()), + }) + } else { + unknown_params.push(ParamUnknown::Old(old_param.clone())); + } + } + // Are any new params not covered by the old params? + // This search is O(n^2), but n ought to be small. + for new_param in new.params.iter() { + if mapped_params + .iter() + .find(|m| m.new.name == new_param.name) + .is_none() + { + unknown_params.push(ParamUnknown::New(new_param.clone())); + } + } + + let mut mapped_results = Vec::new(); + let mut unknown_results = Vec::new(); + + // New function has returned. Need to map each of its results to the old function: + for new_result in new.results.iter() { + if let Some(old_result) = old.results.iter().find(|p| p.name == new_result.name) { + mapped_results.push(ParamPolyfill { + new: new_result.clone(), + old: old_result.clone(), + // Return new result type as old result: + repeq : new_result + .tref + .type_() + .representable(&old_result.tref.type_()), + }) + } else { + unknown_results.push(ParamUnknown::New(new_result.clone())); + } + } + + // Are any old results not covered by the new results? + for old_result in old.results.iter() { + if mapped_results + .iter() + .find(|m| m.old.name == old_result.name) + .is_none() + { + unknown_results.push(ParamUnknown::Old(old_result.clone())); + } + } + + FuncPolyfill { + new, + old, + mapped_params, + unknown_params, + mapped_results, + unknown_results, + } + } + + pub fn report(&self) -> String { + if self.full_compat() { + format!("{}: full compatibility", self.new.name.as_str()) + } else { + let name = if self.new.name != self.old.name { + format!("{} => {}", self.old.name.as_str(), self.new.name.as_str()) + } else { + self.new.name.as_str().to_string() + }; + let mut contents = Vec::new(); + for p in self.mapped_params.iter() { + contents.push(if !p.full_compat() { + format!("param {}", p.report()) + } else { + format!("param {}: compatible", p.new.name.as_str()) + }) + } + for u in self.unknown_params.iter() { + contents.push(format!( + "{} param {}: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + for r in self.mapped_results.iter() { + contents.push(if !r.full_compat() { + format!("result {}", r.report()) + } else { + format!("result {}: compatible", r.new.name.as_str()) + }) + } + for u in self.unknown_results.iter() { + contents.push(format!( + "{} result {}: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + let contents = if contents.is_empty() { + String::new() + } else { + format!(":\n\t\t{}", contents.join("\n\t\t")) + }; + format!("{}{}", name, contents) + } + } + pub fn full_compat(&self) -> bool { + self.new.name == self.old.name + && self.mapped_params.iter().all(|p| p.full_compat()) + && self.unknown_params.is_empty() + && self.mapped_results.iter().all(|p| p.full_compat()) + && self.unknown_results.is_empty() + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ParamPolyfill { + pub new: InterfaceFuncParam, + pub old: InterfaceFuncParam, + pub repeq: RepEquality, +} + +impl ParamPolyfill { + pub fn full_compat(&self) -> bool { + self.new.name == self.old.name && self.repeq == RepEquality::Eq + } + pub fn report(&self) -> String { + let name = if self.new.name != self.old.name { + format!("{} => {}", self.old.name.as_str(), self.new.name.as_str()) + } else { + self.new.name.as_str().to_string() + }; + let repr = match self.repeq { + RepEquality::Eq => "compatible types".to_string(), + RepEquality::Superset => format!("{} is superset-compatible with {}", self.old.tref.type_name(), self.new.tref.type_name()), + RepEquality::NotEq => format!("{} is incompatible with new {}", self.old.tref.type_name(), self.new.tref.type_name()) + }; + format!("{}: {}", name, repr) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ParamUnknown { + Old(InterfaceFuncParam), + New(InterfaceFuncParam), +} + +impl ParamUnknown { + pub fn which(&self) -> &'static str { + match self { + ParamUnknown::Old { .. } => "old", + ParamUnknown::New { .. } => "new", + } + } + pub fn param(&self) -> &InterfaceFuncParam { + match self { + ParamUnknown::Old(p) => &p, + ParamUnknown::New(p) => &p, + } + } +} diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs index 819c0e82f..3bdd6a792 100644 --- a/proposals/clocks/tools/witx/src/representation.rs +++ b/proposals/clocks/tools/witx/src/representation.rs @@ -147,6 +147,10 @@ impl Representable for HandleDatatype { impl Representable for StructDatatype { fn representable(&self, by: &Self) -> RepEquality { + // Structs must have exact structural equality - same members, must + // be Eq, in the same order. + // We would require require a more expressive RepEquality enum to describe which members + // might be supersets. if self.members.len() != by.members.len() { return RepEquality::NotEq; } @@ -164,14 +168,19 @@ impl Representable for StructDatatype { impl Representable for UnionDatatype { fn representable(&self, by: &Self) -> RepEquality { + // Unions must have equal variants, by name (independent of order). If `by` has extra + // variants, its a superset. + // We would require require a more expressive RepEquality enum to describe which variants + // might be supersets. if self.variants.len() > by.variants.len() { return RepEquality::NotEq; } - for (v, byv) in self.variants.iter().zip(by.variants.iter()) { - if v.name != byv.name { - return RepEquality::NotEq; - } - if v.tref.type_().representable(&*byv.tref.type_()) != RepEquality::Eq { + for v in self.variants.iter() { + if let Some(byv) = by.variants.iter().find(|byv| byv.name == v.name) { + if v.tref.type_().representable(&*byv.tref.type_()) != RepEquality::Eq { + return RepEquality::NotEq; + } + } else { return RepEquality::NotEq; } } @@ -231,7 +240,7 @@ mod test { } #[test] - fn different_typenames_equal() { + fn different_typenames() { let a = def_type("a", "(typename $a (flags u32 $b $c))"); let d = def_type("d", "(typename $d (flags u32 $b $c))"); @@ -240,22 +249,17 @@ mod test { } #[test] - fn different_flagnames_not_equal() { - let a = def_type("a", "(typename $a (flags u32 $b $c))"); - let d = def_type("d", "(typename $d (flags u32 $b $e))"); - - assert_eq!(a.representable(&d), RepEquality::NotEq); - assert_eq!(d.representable(&a), RepEquality::NotEq); - } - - #[test] - fn flag_superset() { + fn flags() { let base = def_type("a", "(typename $a (flags u32 $b $c))"); let extra_flag = def_type("a", "(typename $a (flags u32 $b $c $d))"); assert_eq!(base.representable(&extra_flag), RepEquality::Superset); assert_eq!(extra_flag.representable(&base), RepEquality::NotEq); + let different_flagnames = def_type("d", "(typename $d (flags u32 $b $e))"); + assert_eq!(base.representable(&different_flagnames), RepEquality::NotEq); + assert_eq!(different_flagnames.representable(&base), RepEquality::NotEq); + let smaller_size = def_type("a", "(typename $a (flags u16 $b $c))"); assert_eq!(smaller_size.representable(&base), RepEquality::Superset); assert_eq!( @@ -266,7 +270,7 @@ mod test { } #[test] - fn enum_superset() { + fn enum_() { let base = def_type("a", "(typename $a (enum u32 $b $c))"); let extra_variant = def_type("a", "(typename $a (enum u32 $b $c $d))"); @@ -282,7 +286,7 @@ mod test { } #[test] - fn union_superset() { + fn union() { let base = def_type("a", "(typename $a (union (field $b u32) (field $c f32)))"); let extra_variant = def_type( "a", @@ -291,5 +295,13 @@ mod test { assert_eq!(base.representable(&extra_variant), RepEquality::Superset); assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); + + let other_ordering = def_type("a", "(typename $a (union (field $c f32) (field $b u32)))"); + assert_eq!(base.representable(&other_ordering), RepEquality::Eq); + assert_eq!(other_ordering.representable(&base), RepEquality::Eq); + assert_eq!( + other_ordering.representable(&extra_variant), + RepEquality::Superset + ); } } From 9a76bc64030f62fc548940e6024f9040e575f8da Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 3 Dec 2019 20:35:02 -0800 Subject: [PATCH 0356/1772] polyfill: produce a reasonably nice report --- proposals/random/tools/witx/src/docs.rs | 4 +- proposals/random/tools/witx/src/lib.rs | 7 +- proposals/random/tools/witx/src/main.rs | 106 +------ proposals/random/tools/witx/src/polyfill.rs | 268 ++++++++++++++++++ .../random/tools/witx/src/representation.rs | 48 ++-- 5 files changed, 312 insertions(+), 121 deletions(-) create mode 100644 proposals/random/tools/witx/src/polyfill.rs diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs index a6f79280c..162e36720 100644 --- a/proposals/random/tools/witx/src/docs.rs +++ b/proposals/random/tools/witx/src/docs.rs @@ -20,7 +20,7 @@ impl Documentation for Document { } impl BuiltinType { - fn type_name(&self) -> &'static str { + pub fn type_name(&self) -> &'static str { match self { BuiltinType::String => "string", BuiltinType::U8 => "u8", @@ -58,7 +58,7 @@ impl Documentation for NamedType { } impl TypeRef { - fn type_name(&self) -> String { + pub fn type_name(&self) -> String { match self { TypeRef::Name(n) => n.name.as_str().to_string(), TypeRef::Value(ref v) => match &**v { diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 815bccc94..018b55133 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -8,13 +8,16 @@ mod docs; mod io; /// Witx syntax parsing from SExprs mod parser; +/// Calculate required polyfill between interfaces +pub mod polyfill; /// Render ast to text mod render; +/// Representational equality of types +mod representation; /// Resolve toplevel `use` declarations across files mod toplevel; /// Validate declarations into ast mod validate; -mod representation; pub use ast::{ BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, @@ -28,8 +31,8 @@ pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; pub use render::SExpr; +pub use representation::{RepEquality, Representable}; pub use validate::ValidationError; -pub use representation::{Representable, RepEquality}; use std::path::{Path, PathBuf}; use thiserror::Error; diff --git a/proposals/random/tools/witx/src/main.rs b/proposals/random/tools/witx/src/main.rs index 8a62dcf5f..8327ac3fb 100644 --- a/proposals/random/tools/witx/src/main.rs +++ b/proposals/random/tools/witx/src/main.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use std::fs::File; use std::io::Write; use std::process; -use witx::{load, Documentation, RepEquality}; +use witx::{load, Documentation}; pub fn main() { let app = App::new("witx") @@ -98,7 +98,12 @@ pub fn main() { .collect::>(); let module_mapping = parse_module_mapping(&module_mapping_args); - polyfill(&doc, &older_doc, &module_mapping); + let polyfill = witx::polyfill::Polyfill::new(&doc, &older_doc, &module_mapping) + .expect("calculate polyfill"); + println!("{}", polyfill.report()); + if app.is_present("verbose") { + println!("{:?}", polyfill); + } } } @@ -119,100 +124,3 @@ fn parse_module_mapping(ms: &[&str]) -> HashMap { } o } - -fn polyfill(new: &witx::Document, old: &witx::Document, module_mapping: &HashMap) { - use witx::Representable; - for (newmodulename, oldmodulename) in module_mapping { - let newmodule = new - .module(&witx::Id::new(newmodulename)) - .expect("module exists in new"); - let oldmodule = old - .module(&witx::Id::new(oldmodulename)) - .expect("module exists in old"); - - for oldfunc in oldmodule.funcs() { - if let Some(newfunc) = newmodule.func(&oldfunc.name) { - if newfunc.params.len() != oldfunc.params.len() { - println!( - "{}:{} has different number of params than {}:{}", - newmodulename, - newfunc.name.as_str(), - oldmodulename, - oldfunc.name.as_str() - ) - } else { - for (newparam, oldparam) in newfunc.params.iter().zip(oldfunc.params.iter()) { - if newparam.name != oldparam.name { - println!( - "{}:{} param {} doesnt match {}:{} param {}", - newmodulename, - newfunc.name.as_str(), - newparam.name.as_str(), - oldmodulename, - oldfunc.name.as_str(), - oldparam.name.as_str(), - ); - } else if newparam.tref.representable(&oldparam.tref) != RepEquality::Eq { - println!( - "{}:{} param {}:{} is {:?} of {}:{} param {}:{}", - newmodulename, - newfunc.name.as_str(), - newparam.name.as_str(), - newparam.tref.to_sexpr(), - newparam.tref.representable(&oldparam.tref), - oldmodulename, - oldfunc.name.as_str(), - oldparam.name.as_str(), - newparam.tref.to_sexpr(), - ); - } - } - } - if newfunc.results.len() != oldfunc.results.len() { - println!( - "{}:{} has different number of results than {}:{}", - newmodulename, - newfunc.name.as_str(), - oldmodulename, - oldfunc.name.as_str() - ) - } else { - for (newresult, oldresult) in newfunc.results.iter().zip(oldfunc.results.iter()) - { - if newresult.name != oldresult.name { - println!( - "{}:{} result {} doesnt match {}:{} result {}", - newmodulename, - newfunc.name.as_str(), - newresult.name.as_str(), - oldmodulename, - oldfunc.name.as_str(), - oldresult.name.as_str(), - ); - } else if newresult.tref.representable(&oldresult.tref) != RepEquality::Eq { - println!( - "{}:{} result {}:{} is {:?} of {}:{} result {}:{}", - newmodulename, - newfunc.name.as_str(), - newresult.name.as_str(), - newresult.tref.to_sexpr(), - newresult.tref.representable(&oldresult.tref), - oldmodulename, - oldfunc.name.as_str(), - oldresult.name.as_str(), - newresult.tref.to_sexpr(), - ); - } - } - } - } else { - println!( - "{}:{} does not correspond to function in {}", - oldmodulename, - oldfunc.name.as_str(), - newmodulename - ); - } - } - } -} diff --git a/proposals/random/tools/witx/src/polyfill.rs b/proposals/random/tools/witx/src/polyfill.rs new file mode 100644 index 000000000..492ee44fa --- /dev/null +++ b/proposals/random/tools/witx/src/polyfill.rs @@ -0,0 +1,268 @@ +use crate::{Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable}; +use std::collections::HashMap; +use std::rc::Rc; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum PolyfillError { + #[error("Module not present: {name:?}")] + ModuleNotPresent { name: Id }, + #[error("Function not present: {name:?}")] + FuncNotPresent { name: Id }, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Polyfill { + pub modules: Vec, +} + +impl Polyfill { + pub fn new( + new: &Document, + old: &Document, + module_mapping: &HashMap, // Will need a more sophisticated mapping - what about function names, argument names? + ) -> Result { + let mut modules = Vec::new(); + for (newname, oldname) in module_mapping { + let newname = Id::new(newname); + let oldname = Id::new(oldname); + let newmod = new + .module(&newname) + .ok_or_else(|| PolyfillError::ModuleNotPresent { name: newname })?; + let oldmod = old + .module(&oldname) + .ok_or_else(|| PolyfillError::ModuleNotPresent { name: oldname })?; + modules.push(ModulePolyfill::new(newmod, oldmod)?); + } + Ok(Polyfill { modules }) + } + + pub fn report(&self) -> String { + self.modules + .iter() + .map(|m| m.report()) + .collect::>() + .join("\n") + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ModulePolyfill { + pub new: Rc, + pub old: Rc, + pub funcs: Vec, +} + +impl ModulePolyfill { + pub fn new(new: Rc, old: Rc) -> Result { + let mut funcs = Vec::new(); + for oldfunc in old.funcs() { + let newfunc = new + .func(&oldfunc.name) + .ok_or_else(|| PolyfillError::FuncNotPresent { + name: oldfunc.name.clone(), + })?; + funcs.push(FuncPolyfill::new(newfunc, oldfunc)); + } + Ok(ModulePolyfill { new, old, funcs }) + } + + pub fn report(&self) -> String { + format!( + "Implement module {} in terms of {}:\n\t{}", + self.new.name.as_str(), + self.old.name.as_str(), + self.funcs + .iter() + .map(|f| f.report()) + .collect::>() + .join("\n\t"), + ) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FuncPolyfill { + pub new: Rc, + pub old: Rc, + pub mapped_params: Vec, + pub unknown_params: Vec, + pub mapped_results: Vec, + pub unknown_results: Vec, +} + +impl FuncPolyfill { + pub fn new(new: Rc, old: Rc) -> FuncPolyfill { + let mut mapped_params = Vec::new(); + let mut unknown_params = Vec::new(); + + // Old function is called. Need to map each of its parameters to the new function: + for old_param in old.params.iter() { + if let Some(new_param) = new.params.iter().find(|p| p.name == old_param.name) { + mapped_params.push(ParamPolyfill { + new: new_param.clone(), + old: old_param.clone(), + // Call new param type with old param: + repeq : old_param + .tref + .type_() + .representable(&new_param.tref.type_()), + }) + } else { + unknown_params.push(ParamUnknown::Old(old_param.clone())); + } + } + // Are any new params not covered by the old params? + // This search is O(n^2), but n ought to be small. + for new_param in new.params.iter() { + if mapped_params + .iter() + .find(|m| m.new.name == new_param.name) + .is_none() + { + unknown_params.push(ParamUnknown::New(new_param.clone())); + } + } + + let mut mapped_results = Vec::new(); + let mut unknown_results = Vec::new(); + + // New function has returned. Need to map each of its results to the old function: + for new_result in new.results.iter() { + if let Some(old_result) = old.results.iter().find(|p| p.name == new_result.name) { + mapped_results.push(ParamPolyfill { + new: new_result.clone(), + old: old_result.clone(), + // Return new result type as old result: + repeq : new_result + .tref + .type_() + .representable(&old_result.tref.type_()), + }) + } else { + unknown_results.push(ParamUnknown::New(new_result.clone())); + } + } + + // Are any old results not covered by the new results? + for old_result in old.results.iter() { + if mapped_results + .iter() + .find(|m| m.old.name == old_result.name) + .is_none() + { + unknown_results.push(ParamUnknown::Old(old_result.clone())); + } + } + + FuncPolyfill { + new, + old, + mapped_params, + unknown_params, + mapped_results, + unknown_results, + } + } + + pub fn report(&self) -> String { + if self.full_compat() { + format!("{}: full compatibility", self.new.name.as_str()) + } else { + let name = if self.new.name != self.old.name { + format!("{} => {}", self.old.name.as_str(), self.new.name.as_str()) + } else { + self.new.name.as_str().to_string() + }; + let mut contents = Vec::new(); + for p in self.mapped_params.iter() { + contents.push(if !p.full_compat() { + format!("param {}", p.report()) + } else { + format!("param {}: compatible", p.new.name.as_str()) + }) + } + for u in self.unknown_params.iter() { + contents.push(format!( + "{} param {}: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + for r in self.mapped_results.iter() { + contents.push(if !r.full_compat() { + format!("result {}", r.report()) + } else { + format!("result {}: compatible", r.new.name.as_str()) + }) + } + for u in self.unknown_results.iter() { + contents.push(format!( + "{} result {}: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + let contents = if contents.is_empty() { + String::new() + } else { + format!(":\n\t\t{}", contents.join("\n\t\t")) + }; + format!("{}{}", name, contents) + } + } + pub fn full_compat(&self) -> bool { + self.new.name == self.old.name + && self.mapped_params.iter().all(|p| p.full_compat()) + && self.unknown_params.is_empty() + && self.mapped_results.iter().all(|p| p.full_compat()) + && self.unknown_results.is_empty() + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ParamPolyfill { + pub new: InterfaceFuncParam, + pub old: InterfaceFuncParam, + pub repeq: RepEquality, +} + +impl ParamPolyfill { + pub fn full_compat(&self) -> bool { + self.new.name == self.old.name && self.repeq == RepEquality::Eq + } + pub fn report(&self) -> String { + let name = if self.new.name != self.old.name { + format!("{} => {}", self.old.name.as_str(), self.new.name.as_str()) + } else { + self.new.name.as_str().to_string() + }; + let repr = match self.repeq { + RepEquality::Eq => "compatible types".to_string(), + RepEquality::Superset => format!("{} is superset-compatible with {}", self.old.tref.type_name(), self.new.tref.type_name()), + RepEquality::NotEq => format!("{} is incompatible with new {}", self.old.tref.type_name(), self.new.tref.type_name()) + }; + format!("{}: {}", name, repr) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ParamUnknown { + Old(InterfaceFuncParam), + New(InterfaceFuncParam), +} + +impl ParamUnknown { + pub fn which(&self) -> &'static str { + match self { + ParamUnknown::Old { .. } => "old", + ParamUnknown::New { .. } => "new", + } + } + pub fn param(&self) -> &InterfaceFuncParam { + match self { + ParamUnknown::Old(p) => &p, + ParamUnknown::New(p) => &p, + } + } +} diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs index 819c0e82f..3bdd6a792 100644 --- a/proposals/random/tools/witx/src/representation.rs +++ b/proposals/random/tools/witx/src/representation.rs @@ -147,6 +147,10 @@ impl Representable for HandleDatatype { impl Representable for StructDatatype { fn representable(&self, by: &Self) -> RepEquality { + // Structs must have exact structural equality - same members, must + // be Eq, in the same order. + // We would require require a more expressive RepEquality enum to describe which members + // might be supersets. if self.members.len() != by.members.len() { return RepEquality::NotEq; } @@ -164,14 +168,19 @@ impl Representable for StructDatatype { impl Representable for UnionDatatype { fn representable(&self, by: &Self) -> RepEquality { + // Unions must have equal variants, by name (independent of order). If `by` has extra + // variants, its a superset. + // We would require require a more expressive RepEquality enum to describe which variants + // might be supersets. if self.variants.len() > by.variants.len() { return RepEquality::NotEq; } - for (v, byv) in self.variants.iter().zip(by.variants.iter()) { - if v.name != byv.name { - return RepEquality::NotEq; - } - if v.tref.type_().representable(&*byv.tref.type_()) != RepEquality::Eq { + for v in self.variants.iter() { + if let Some(byv) = by.variants.iter().find(|byv| byv.name == v.name) { + if v.tref.type_().representable(&*byv.tref.type_()) != RepEquality::Eq { + return RepEquality::NotEq; + } + } else { return RepEquality::NotEq; } } @@ -231,7 +240,7 @@ mod test { } #[test] - fn different_typenames_equal() { + fn different_typenames() { let a = def_type("a", "(typename $a (flags u32 $b $c))"); let d = def_type("d", "(typename $d (flags u32 $b $c))"); @@ -240,22 +249,17 @@ mod test { } #[test] - fn different_flagnames_not_equal() { - let a = def_type("a", "(typename $a (flags u32 $b $c))"); - let d = def_type("d", "(typename $d (flags u32 $b $e))"); - - assert_eq!(a.representable(&d), RepEquality::NotEq); - assert_eq!(d.representable(&a), RepEquality::NotEq); - } - - #[test] - fn flag_superset() { + fn flags() { let base = def_type("a", "(typename $a (flags u32 $b $c))"); let extra_flag = def_type("a", "(typename $a (flags u32 $b $c $d))"); assert_eq!(base.representable(&extra_flag), RepEquality::Superset); assert_eq!(extra_flag.representable(&base), RepEquality::NotEq); + let different_flagnames = def_type("d", "(typename $d (flags u32 $b $e))"); + assert_eq!(base.representable(&different_flagnames), RepEquality::NotEq); + assert_eq!(different_flagnames.representable(&base), RepEquality::NotEq); + let smaller_size = def_type("a", "(typename $a (flags u16 $b $c))"); assert_eq!(smaller_size.representable(&base), RepEquality::Superset); assert_eq!( @@ -266,7 +270,7 @@ mod test { } #[test] - fn enum_superset() { + fn enum_() { let base = def_type("a", "(typename $a (enum u32 $b $c))"); let extra_variant = def_type("a", "(typename $a (enum u32 $b $c $d))"); @@ -282,7 +286,7 @@ mod test { } #[test] - fn union_superset() { + fn union() { let base = def_type("a", "(typename $a (union (field $b u32) (field $c f32)))"); let extra_variant = def_type( "a", @@ -291,5 +295,13 @@ mod test { assert_eq!(base.representable(&extra_variant), RepEquality::Superset); assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); + + let other_ordering = def_type("a", "(typename $a (union (field $c f32) (field $b u32)))"); + assert_eq!(base.representable(&other_ordering), RepEquality::Eq); + assert_eq!(other_ordering.representable(&base), RepEquality::Eq); + assert_eq!( + other_ordering.representable(&extra_variant), + RepEquality::Superset + ); } } From 38e5197f29b239d2e320146cba4f8fe74ae247dc Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 3 Dec 2019 20:35:02 -0800 Subject: [PATCH 0357/1772] polyfill: produce a reasonably nice report --- proposals/filesystem/tools/witx/src/docs.rs | 4 +- proposals/filesystem/tools/witx/src/lib.rs | 7 +- proposals/filesystem/tools/witx/src/main.rs | 106 +------ .../filesystem/tools/witx/src/polyfill.rs | 268 ++++++++++++++++++ .../tools/witx/src/representation.rs | 48 ++-- 5 files changed, 312 insertions(+), 121 deletions(-) create mode 100644 proposals/filesystem/tools/witx/src/polyfill.rs diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs index a6f79280c..162e36720 100644 --- a/proposals/filesystem/tools/witx/src/docs.rs +++ b/proposals/filesystem/tools/witx/src/docs.rs @@ -20,7 +20,7 @@ impl Documentation for Document { } impl BuiltinType { - fn type_name(&self) -> &'static str { + pub fn type_name(&self) -> &'static str { match self { BuiltinType::String => "string", BuiltinType::U8 => "u8", @@ -58,7 +58,7 @@ impl Documentation for NamedType { } impl TypeRef { - fn type_name(&self) -> String { + pub fn type_name(&self) -> String { match self { TypeRef::Name(n) => n.name.as_str().to_string(), TypeRef::Value(ref v) => match &**v { diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 815bccc94..018b55133 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -8,13 +8,16 @@ mod docs; mod io; /// Witx syntax parsing from SExprs mod parser; +/// Calculate required polyfill between interfaces +pub mod polyfill; /// Render ast to text mod render; +/// Representational equality of types +mod representation; /// Resolve toplevel `use` declarations across files mod toplevel; /// Validate declarations into ast mod validate; -mod representation; pub use ast::{ BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, @@ -28,8 +31,8 @@ pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use parser::DeclSyntax; pub use render::SExpr; +pub use representation::{RepEquality, Representable}; pub use validate::ValidationError; -pub use representation::{Representable, RepEquality}; use std::path::{Path, PathBuf}; use thiserror::Error; diff --git a/proposals/filesystem/tools/witx/src/main.rs b/proposals/filesystem/tools/witx/src/main.rs index 8a62dcf5f..8327ac3fb 100644 --- a/proposals/filesystem/tools/witx/src/main.rs +++ b/proposals/filesystem/tools/witx/src/main.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use std::fs::File; use std::io::Write; use std::process; -use witx::{load, Documentation, RepEquality}; +use witx::{load, Documentation}; pub fn main() { let app = App::new("witx") @@ -98,7 +98,12 @@ pub fn main() { .collect::>(); let module_mapping = parse_module_mapping(&module_mapping_args); - polyfill(&doc, &older_doc, &module_mapping); + let polyfill = witx::polyfill::Polyfill::new(&doc, &older_doc, &module_mapping) + .expect("calculate polyfill"); + println!("{}", polyfill.report()); + if app.is_present("verbose") { + println!("{:?}", polyfill); + } } } @@ -119,100 +124,3 @@ fn parse_module_mapping(ms: &[&str]) -> HashMap { } o } - -fn polyfill(new: &witx::Document, old: &witx::Document, module_mapping: &HashMap) { - use witx::Representable; - for (newmodulename, oldmodulename) in module_mapping { - let newmodule = new - .module(&witx::Id::new(newmodulename)) - .expect("module exists in new"); - let oldmodule = old - .module(&witx::Id::new(oldmodulename)) - .expect("module exists in old"); - - for oldfunc in oldmodule.funcs() { - if let Some(newfunc) = newmodule.func(&oldfunc.name) { - if newfunc.params.len() != oldfunc.params.len() { - println!( - "{}:{} has different number of params than {}:{}", - newmodulename, - newfunc.name.as_str(), - oldmodulename, - oldfunc.name.as_str() - ) - } else { - for (newparam, oldparam) in newfunc.params.iter().zip(oldfunc.params.iter()) { - if newparam.name != oldparam.name { - println!( - "{}:{} param {} doesnt match {}:{} param {}", - newmodulename, - newfunc.name.as_str(), - newparam.name.as_str(), - oldmodulename, - oldfunc.name.as_str(), - oldparam.name.as_str(), - ); - } else if newparam.tref.representable(&oldparam.tref) != RepEquality::Eq { - println!( - "{}:{} param {}:{} is {:?} of {}:{} param {}:{}", - newmodulename, - newfunc.name.as_str(), - newparam.name.as_str(), - newparam.tref.to_sexpr(), - newparam.tref.representable(&oldparam.tref), - oldmodulename, - oldfunc.name.as_str(), - oldparam.name.as_str(), - newparam.tref.to_sexpr(), - ); - } - } - } - if newfunc.results.len() != oldfunc.results.len() { - println!( - "{}:{} has different number of results than {}:{}", - newmodulename, - newfunc.name.as_str(), - oldmodulename, - oldfunc.name.as_str() - ) - } else { - for (newresult, oldresult) in newfunc.results.iter().zip(oldfunc.results.iter()) - { - if newresult.name != oldresult.name { - println!( - "{}:{} result {} doesnt match {}:{} result {}", - newmodulename, - newfunc.name.as_str(), - newresult.name.as_str(), - oldmodulename, - oldfunc.name.as_str(), - oldresult.name.as_str(), - ); - } else if newresult.tref.representable(&oldresult.tref) != RepEquality::Eq { - println!( - "{}:{} result {}:{} is {:?} of {}:{} result {}:{}", - newmodulename, - newfunc.name.as_str(), - newresult.name.as_str(), - newresult.tref.to_sexpr(), - newresult.tref.representable(&oldresult.tref), - oldmodulename, - oldfunc.name.as_str(), - oldresult.name.as_str(), - newresult.tref.to_sexpr(), - ); - } - } - } - } else { - println!( - "{}:{} does not correspond to function in {}", - oldmodulename, - oldfunc.name.as_str(), - newmodulename - ); - } - } - } -} diff --git a/proposals/filesystem/tools/witx/src/polyfill.rs b/proposals/filesystem/tools/witx/src/polyfill.rs new file mode 100644 index 000000000..492ee44fa --- /dev/null +++ b/proposals/filesystem/tools/witx/src/polyfill.rs @@ -0,0 +1,268 @@ +use crate::{Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable}; +use std::collections::HashMap; +use std::rc::Rc; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum PolyfillError { + #[error("Module not present: {name:?}")] + ModuleNotPresent { name: Id }, + #[error("Function not present: {name:?}")] + FuncNotPresent { name: Id }, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Polyfill { + pub modules: Vec, +} + +impl Polyfill { + pub fn new( + new: &Document, + old: &Document, + module_mapping: &HashMap, // Will need a more sophisticated mapping - what about function names, argument names? + ) -> Result { + let mut modules = Vec::new(); + for (newname, oldname) in module_mapping { + let newname = Id::new(newname); + let oldname = Id::new(oldname); + let newmod = new + .module(&newname) + .ok_or_else(|| PolyfillError::ModuleNotPresent { name: newname })?; + let oldmod = old + .module(&oldname) + .ok_or_else(|| PolyfillError::ModuleNotPresent { name: oldname })?; + modules.push(ModulePolyfill::new(newmod, oldmod)?); + } + Ok(Polyfill { modules }) + } + + pub fn report(&self) -> String { + self.modules + .iter() + .map(|m| m.report()) + .collect::>() + .join("\n") + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ModulePolyfill { + pub new: Rc, + pub old: Rc, + pub funcs: Vec, +} + +impl ModulePolyfill { + pub fn new(new: Rc, old: Rc) -> Result { + let mut funcs = Vec::new(); + for oldfunc in old.funcs() { + let newfunc = new + .func(&oldfunc.name) + .ok_or_else(|| PolyfillError::FuncNotPresent { + name: oldfunc.name.clone(), + })?; + funcs.push(FuncPolyfill::new(newfunc, oldfunc)); + } + Ok(ModulePolyfill { new, old, funcs }) + } + + pub fn report(&self) -> String { + format!( + "Implement module {} in terms of {}:\n\t{}", + self.new.name.as_str(), + self.old.name.as_str(), + self.funcs + .iter() + .map(|f| f.report()) + .collect::>() + .join("\n\t"), + ) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FuncPolyfill { + pub new: Rc, + pub old: Rc, + pub mapped_params: Vec, + pub unknown_params: Vec, + pub mapped_results: Vec, + pub unknown_results: Vec, +} + +impl FuncPolyfill { + pub fn new(new: Rc, old: Rc) -> FuncPolyfill { + let mut mapped_params = Vec::new(); + let mut unknown_params = Vec::new(); + + // Old function is called. Need to map each of its parameters to the new function: + for old_param in old.params.iter() { + if let Some(new_param) = new.params.iter().find(|p| p.name == old_param.name) { + mapped_params.push(ParamPolyfill { + new: new_param.clone(), + old: old_param.clone(), + // Call new param type with old param: + repeq : old_param + .tref + .type_() + .representable(&new_param.tref.type_()), + }) + } else { + unknown_params.push(ParamUnknown::Old(old_param.clone())); + } + } + // Are any new params not covered by the old params? + // This search is O(n^2), but n ought to be small. + for new_param in new.params.iter() { + if mapped_params + .iter() + .find(|m| m.new.name == new_param.name) + .is_none() + { + unknown_params.push(ParamUnknown::New(new_param.clone())); + } + } + + let mut mapped_results = Vec::new(); + let mut unknown_results = Vec::new(); + + // New function has returned. Need to map each of its results to the old function: + for new_result in new.results.iter() { + if let Some(old_result) = old.results.iter().find(|p| p.name == new_result.name) { + mapped_results.push(ParamPolyfill { + new: new_result.clone(), + old: old_result.clone(), + // Return new result type as old result: + repeq : new_result + .tref + .type_() + .representable(&old_result.tref.type_()), + }) + } else { + unknown_results.push(ParamUnknown::New(new_result.clone())); + } + } + + // Are any old results not covered by the new results? + for old_result in old.results.iter() { + if mapped_results + .iter() + .find(|m| m.old.name == old_result.name) + .is_none() + { + unknown_results.push(ParamUnknown::Old(old_result.clone())); + } + } + + FuncPolyfill { + new, + old, + mapped_params, + unknown_params, + mapped_results, + unknown_results, + } + } + + pub fn report(&self) -> String { + if self.full_compat() { + format!("{}: full compatibility", self.new.name.as_str()) + } else { + let name = if self.new.name != self.old.name { + format!("{} => {}", self.old.name.as_str(), self.new.name.as_str()) + } else { + self.new.name.as_str().to_string() + }; + let mut contents = Vec::new(); + for p in self.mapped_params.iter() { + contents.push(if !p.full_compat() { + format!("param {}", p.report()) + } else { + format!("param {}: compatible", p.new.name.as_str()) + }) + } + for u in self.unknown_params.iter() { + contents.push(format!( + "{} param {}: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + for r in self.mapped_results.iter() { + contents.push(if !r.full_compat() { + format!("result {}", r.report()) + } else { + format!("result {}: compatible", r.new.name.as_str()) + }) + } + for u in self.unknown_results.iter() { + contents.push(format!( + "{} result {}: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + let contents = if contents.is_empty() { + String::new() + } else { + format!(":\n\t\t{}", contents.join("\n\t\t")) + }; + format!("{}{}", name, contents) + } + } + pub fn full_compat(&self) -> bool { + self.new.name == self.old.name + && self.mapped_params.iter().all(|p| p.full_compat()) + && self.unknown_params.is_empty() + && self.mapped_results.iter().all(|p| p.full_compat()) + && self.unknown_results.is_empty() + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ParamPolyfill { + pub new: InterfaceFuncParam, + pub old: InterfaceFuncParam, + pub repeq: RepEquality, +} + +impl ParamPolyfill { + pub fn full_compat(&self) -> bool { + self.new.name == self.old.name && self.repeq == RepEquality::Eq + } + pub fn report(&self) -> String { + let name = if self.new.name != self.old.name { + format!("{} => {}", self.old.name.as_str(), self.new.name.as_str()) + } else { + self.new.name.as_str().to_string() + }; + let repr = match self.repeq { + RepEquality::Eq => "compatible types".to_string(), + RepEquality::Superset => format!("{} is superset-compatible with {}", self.old.tref.type_name(), self.new.tref.type_name()), + RepEquality::NotEq => format!("{} is incompatible with new {}", self.old.tref.type_name(), self.new.tref.type_name()) + }; + format!("{}: {}", name, repr) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ParamUnknown { + Old(InterfaceFuncParam), + New(InterfaceFuncParam), +} + +impl ParamUnknown { + pub fn which(&self) -> &'static str { + match self { + ParamUnknown::Old { .. } => "old", + ParamUnknown::New { .. } => "new", + } + } + pub fn param(&self) -> &InterfaceFuncParam { + match self { + ParamUnknown::Old(p) => &p, + ParamUnknown::New(p) => &p, + } + } +} diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs index 819c0e82f..3bdd6a792 100644 --- a/proposals/filesystem/tools/witx/src/representation.rs +++ b/proposals/filesystem/tools/witx/src/representation.rs @@ -147,6 +147,10 @@ impl Representable for HandleDatatype { impl Representable for StructDatatype { fn representable(&self, by: &Self) -> RepEquality { + // Structs must have exact structural equality - same members, must + // be Eq, in the same order. + // We would require require a more expressive RepEquality enum to describe which members + // might be supersets. if self.members.len() != by.members.len() { return RepEquality::NotEq; } @@ -164,14 +168,19 @@ impl Representable for StructDatatype { impl Representable for UnionDatatype { fn representable(&self, by: &Self) -> RepEquality { + // Unions must have equal variants, by name (independent of order). If `by` has extra + // variants, its a superset. + // We would require require a more expressive RepEquality enum to describe which variants + // might be supersets. if self.variants.len() > by.variants.len() { return RepEquality::NotEq; } - for (v, byv) in self.variants.iter().zip(by.variants.iter()) { - if v.name != byv.name { - return RepEquality::NotEq; - } - if v.tref.type_().representable(&*byv.tref.type_()) != RepEquality::Eq { + for v in self.variants.iter() { + if let Some(byv) = by.variants.iter().find(|byv| byv.name == v.name) { + if v.tref.type_().representable(&*byv.tref.type_()) != RepEquality::Eq { + return RepEquality::NotEq; + } + } else { return RepEquality::NotEq; } } @@ -231,7 +240,7 @@ mod test { } #[test] - fn different_typenames_equal() { + fn different_typenames() { let a = def_type("a", "(typename $a (flags u32 $b $c))"); let d = def_type("d", "(typename $d (flags u32 $b $c))"); @@ -240,22 +249,17 @@ mod test { } #[test] - fn different_flagnames_not_equal() { - let a = def_type("a", "(typename $a (flags u32 $b $c))"); - let d = def_type("d", "(typename $d (flags u32 $b $e))"); - - assert_eq!(a.representable(&d), RepEquality::NotEq); - assert_eq!(d.representable(&a), RepEquality::NotEq); - } - - #[test] - fn flag_superset() { + fn flags() { let base = def_type("a", "(typename $a (flags u32 $b $c))"); let extra_flag = def_type("a", "(typename $a (flags u32 $b $c $d))"); assert_eq!(base.representable(&extra_flag), RepEquality::Superset); assert_eq!(extra_flag.representable(&base), RepEquality::NotEq); + let different_flagnames = def_type("d", "(typename $d (flags u32 $b $e))"); + assert_eq!(base.representable(&different_flagnames), RepEquality::NotEq); + assert_eq!(different_flagnames.representable(&base), RepEquality::NotEq); + let smaller_size = def_type("a", "(typename $a (flags u16 $b $c))"); assert_eq!(smaller_size.representable(&base), RepEquality::Superset); assert_eq!( @@ -266,7 +270,7 @@ mod test { } #[test] - fn enum_superset() { + fn enum_() { let base = def_type("a", "(typename $a (enum u32 $b $c))"); let extra_variant = def_type("a", "(typename $a (enum u32 $b $c $d))"); @@ -282,7 +286,7 @@ mod test { } #[test] - fn union_superset() { + fn union() { let base = def_type("a", "(typename $a (union (field $b u32) (field $c f32)))"); let extra_variant = def_type( "a", @@ -291,5 +295,13 @@ mod test { assert_eq!(base.representable(&extra_variant), RepEquality::Superset); assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); + + let other_ordering = def_type("a", "(typename $a (union (field $c f32) (field $b u32)))"); + assert_eq!(base.representable(&other_ordering), RepEquality::Eq); + assert_eq!(other_ordering.representable(&base), RepEquality::Eq); + assert_eq!( + other_ordering.representable(&extra_variant), + RepEquality::Superset + ); } } From 0eb409cc11f93af21f0332c4689d5533c39a15d2 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 4 Dec 2019 11:03:26 -0800 Subject: [PATCH 0358/1772] polyfill: move document creation to the right module --- proposals/clocks/tools/witx/src/docs.rs | 111 ++++++++++++++++++++ proposals/clocks/tools/witx/src/main.rs | 2 +- proposals/clocks/tools/witx/src/polyfill.rs | 84 +-------------- 3 files changed, 114 insertions(+), 83 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs index 162e36720..b075f03dc 100644 --- a/proposals/clocks/tools/witx/src/docs.rs +++ b/proposals/clocks/tools/witx/src/docs.rs @@ -1,4 +1,6 @@ use crate::ast::*; +use crate::polyfill::*; +use crate::RepEquality; pub trait Documentation { fn to_md(&self) -> String; @@ -236,3 +238,112 @@ impl Documentation for InterfaceFunc { ) } } + +impl Documentation for Polyfill { + fn to_md(&self) -> String { + let module_docs = self + .modules + .iter() + .map(|m| m.to_md()) + .collect::>() + .join("\n"); + let type_docs = format!("TODO"); + format!("# Modules\n{}\n# Types\n{}\n", module_docs, type_docs) + } +} + +impl Documentation for ModulePolyfill { + fn to_md(&self) -> String { + format!( + "## `{}` in terms of `{}`\n{}", + self.new.name.as_str(), + self.old.name.as_str(), + self.funcs + .iter() + .map(|f| f.to_md()) + .collect::>() + .join("\n"), + ) + } +} + +impl Documentation for FuncPolyfill { + fn to_md(&self) -> String { + if self.full_compat() { + format!("* `{}`: full compatibility", self.new.name.as_str()) + } else { + let name = if self.new.name != self.old.name { + format!( + "* `{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("* `{}`", self.new.name.as_str()) + }; + let mut contents = Vec::new(); + for p in self.mapped_params.iter() { + contents.push(if !p.full_compat() { + format!("param {}", p.to_md()) + } else { + format!("param `{}`: compatible", p.new.name.as_str()) + }) + } + for u in self.unknown_params.iter() { + contents.push(format!( + "{} param `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + for r in self.mapped_results.iter() { + contents.push(if !r.full_compat() { + format!("result {}", r.to_md()) + } else { + format!("result `{}`: compatible", r.new.name.as_str()) + }) + } + for u in self.unknown_results.iter() { + contents.push(format!( + "{} result `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + let contents = if contents.is_empty() { + String::new() + } else { + format!(":\n - {}", contents.join("\n - ")) + }; + format!("{}{}", name, contents) + } + } +} + +impl Documentation for ParamPolyfill { + fn to_md(&self) -> String { + let name = if self.new.name != self.old.name { + format!( + "`{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("`{}`", self.new.name.as_str()) + }; + let repr = match self.repeq { + RepEquality::Eq => "compatible types".to_string(), + RepEquality::Superset => format!( + "`{}` is superset-compatible with `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + RepEquality::NotEq => format!( + "`{}` is incompatible with new `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + }; + format!("{}: {}", name, repr) + } +} diff --git a/proposals/clocks/tools/witx/src/main.rs b/proposals/clocks/tools/witx/src/main.rs index 8327ac3fb..d7ff23b55 100644 --- a/proposals/clocks/tools/witx/src/main.rs +++ b/proposals/clocks/tools/witx/src/main.rs @@ -100,7 +100,7 @@ pub fn main() { let polyfill = witx::polyfill::Polyfill::new(&doc, &older_doc, &module_mapping) .expect("calculate polyfill"); - println!("{}", polyfill.report()); + println!("{}", polyfill.to_md()); if app.is_present("verbose") { println!("{:?}", polyfill); } diff --git a/proposals/clocks/tools/witx/src/polyfill.rs b/proposals/clocks/tools/witx/src/polyfill.rs index 492ee44fa..bb5541072 100644 --- a/proposals/clocks/tools/witx/src/polyfill.rs +++ b/proposals/clocks/tools/witx/src/polyfill.rs @@ -36,14 +36,6 @@ impl Polyfill { } Ok(Polyfill { modules }) } - - pub fn report(&self) -> String { - self.modules - .iter() - .map(|m| m.report()) - .collect::>() - .join("\n") - } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -66,19 +58,6 @@ impl ModulePolyfill { } Ok(ModulePolyfill { new, old, funcs }) } - - pub fn report(&self) -> String { - format!( - "Implement module {} in terms of {}:\n\t{}", - self.new.name.as_str(), - self.old.name.as_str(), - self.funcs - .iter() - .map(|f| f.report()) - .collect::>() - .join("\n\t"), - ) - } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -103,7 +82,7 @@ impl FuncPolyfill { new: new_param.clone(), old: old_param.clone(), // Call new param type with old param: - repeq : old_param + repeq: old_param .tref .type_() .representable(&new_param.tref.type_()), @@ -134,7 +113,7 @@ impl FuncPolyfill { new: new_result.clone(), old: old_result.clone(), // Return new result type as old result: - repeq : new_result + repeq: new_result .tref .type_() .representable(&old_result.tref.type_()), @@ -165,52 +144,6 @@ impl FuncPolyfill { } } - pub fn report(&self) -> String { - if self.full_compat() { - format!("{}: full compatibility", self.new.name.as_str()) - } else { - let name = if self.new.name != self.old.name { - format!("{} => {}", self.old.name.as_str(), self.new.name.as_str()) - } else { - self.new.name.as_str().to_string() - }; - let mut contents = Vec::new(); - for p in self.mapped_params.iter() { - contents.push(if !p.full_compat() { - format!("param {}", p.report()) - } else { - format!("param {}: compatible", p.new.name.as_str()) - }) - } - for u in self.unknown_params.iter() { - contents.push(format!( - "{} param {}: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - for r in self.mapped_results.iter() { - contents.push(if !r.full_compat() { - format!("result {}", r.report()) - } else { - format!("result {}: compatible", r.new.name.as_str()) - }) - } - for u in self.unknown_results.iter() { - contents.push(format!( - "{} result {}: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - let contents = if contents.is_empty() { - String::new() - } else { - format!(":\n\t\t{}", contents.join("\n\t\t")) - }; - format!("{}{}", name, contents) - } - } pub fn full_compat(&self) -> bool { self.new.name == self.old.name && self.mapped_params.iter().all(|p| p.full_compat()) @@ -231,19 +164,6 @@ impl ParamPolyfill { pub fn full_compat(&self) -> bool { self.new.name == self.old.name && self.repeq == RepEquality::Eq } - pub fn report(&self) -> String { - let name = if self.new.name != self.old.name { - format!("{} => {}", self.old.name.as_str(), self.new.name.as_str()) - } else { - self.new.name.as_str().to_string() - }; - let repr = match self.repeq { - RepEquality::Eq => "compatible types".to_string(), - RepEquality::Superset => format!("{} is superset-compatible with {}", self.old.tref.type_name(), self.new.tref.type_name()), - RepEquality::NotEq => format!("{} is incompatible with new {}", self.old.tref.type_name(), self.new.tref.type_name()) - }; - format!("{}: {}", name, repr) - } } #[derive(Debug, Clone, PartialEq, Eq)] From f247f8682b316f5e6141974be3405b8c2331b75b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 4 Dec 2019 11:03:26 -0800 Subject: [PATCH 0359/1772] polyfill: move document creation to the right module --- proposals/random/tools/witx/src/docs.rs | 111 ++++++++++++++++++++ proposals/random/tools/witx/src/main.rs | 2 +- proposals/random/tools/witx/src/polyfill.rs | 84 +-------------- 3 files changed, 114 insertions(+), 83 deletions(-) diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs index 162e36720..b075f03dc 100644 --- a/proposals/random/tools/witx/src/docs.rs +++ b/proposals/random/tools/witx/src/docs.rs @@ -1,4 +1,6 @@ use crate::ast::*; +use crate::polyfill::*; +use crate::RepEquality; pub trait Documentation { fn to_md(&self) -> String; @@ -236,3 +238,112 @@ impl Documentation for InterfaceFunc { ) } } + +impl Documentation for Polyfill { + fn to_md(&self) -> String { + let module_docs = self + .modules + .iter() + .map(|m| m.to_md()) + .collect::>() + .join("\n"); + let type_docs = format!("TODO"); + format!("# Modules\n{}\n# Types\n{}\n", module_docs, type_docs) + } +} + +impl Documentation for ModulePolyfill { + fn to_md(&self) -> String { + format!( + "## `{}` in terms of `{}`\n{}", + self.new.name.as_str(), + self.old.name.as_str(), + self.funcs + .iter() + .map(|f| f.to_md()) + .collect::>() + .join("\n"), + ) + } +} + +impl Documentation for FuncPolyfill { + fn to_md(&self) -> String { + if self.full_compat() { + format!("* `{}`: full compatibility", self.new.name.as_str()) + } else { + let name = if self.new.name != self.old.name { + format!( + "* `{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("* `{}`", self.new.name.as_str()) + }; + let mut contents = Vec::new(); + for p in self.mapped_params.iter() { + contents.push(if !p.full_compat() { + format!("param {}", p.to_md()) + } else { + format!("param `{}`: compatible", p.new.name.as_str()) + }) + } + for u in self.unknown_params.iter() { + contents.push(format!( + "{} param `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + for r in self.mapped_results.iter() { + contents.push(if !r.full_compat() { + format!("result {}", r.to_md()) + } else { + format!("result `{}`: compatible", r.new.name.as_str()) + }) + } + for u in self.unknown_results.iter() { + contents.push(format!( + "{} result `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + let contents = if contents.is_empty() { + String::new() + } else { + format!(":\n - {}", contents.join("\n - ")) + }; + format!("{}{}", name, contents) + } + } +} + +impl Documentation for ParamPolyfill { + fn to_md(&self) -> String { + let name = if self.new.name != self.old.name { + format!( + "`{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("`{}`", self.new.name.as_str()) + }; + let repr = match self.repeq { + RepEquality::Eq => "compatible types".to_string(), + RepEquality::Superset => format!( + "`{}` is superset-compatible with `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + RepEquality::NotEq => format!( + "`{}` is incompatible with new `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + }; + format!("{}: {}", name, repr) + } +} diff --git a/proposals/random/tools/witx/src/main.rs b/proposals/random/tools/witx/src/main.rs index 8327ac3fb..d7ff23b55 100644 --- a/proposals/random/tools/witx/src/main.rs +++ b/proposals/random/tools/witx/src/main.rs @@ -100,7 +100,7 @@ pub fn main() { let polyfill = witx::polyfill::Polyfill::new(&doc, &older_doc, &module_mapping) .expect("calculate polyfill"); - println!("{}", polyfill.report()); + println!("{}", polyfill.to_md()); if app.is_present("verbose") { println!("{:?}", polyfill); } diff --git a/proposals/random/tools/witx/src/polyfill.rs b/proposals/random/tools/witx/src/polyfill.rs index 492ee44fa..bb5541072 100644 --- a/proposals/random/tools/witx/src/polyfill.rs +++ b/proposals/random/tools/witx/src/polyfill.rs @@ -36,14 +36,6 @@ impl Polyfill { } Ok(Polyfill { modules }) } - - pub fn report(&self) -> String { - self.modules - .iter() - .map(|m| m.report()) - .collect::>() - .join("\n") - } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -66,19 +58,6 @@ impl ModulePolyfill { } Ok(ModulePolyfill { new, old, funcs }) } - - pub fn report(&self) -> String { - format!( - "Implement module {} in terms of {}:\n\t{}", - self.new.name.as_str(), - self.old.name.as_str(), - self.funcs - .iter() - .map(|f| f.report()) - .collect::>() - .join("\n\t"), - ) - } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -103,7 +82,7 @@ impl FuncPolyfill { new: new_param.clone(), old: old_param.clone(), // Call new param type with old param: - repeq : old_param + repeq: old_param .tref .type_() .representable(&new_param.tref.type_()), @@ -134,7 +113,7 @@ impl FuncPolyfill { new: new_result.clone(), old: old_result.clone(), // Return new result type as old result: - repeq : new_result + repeq: new_result .tref .type_() .representable(&old_result.tref.type_()), @@ -165,52 +144,6 @@ impl FuncPolyfill { } } - pub fn report(&self) -> String { - if self.full_compat() { - format!("{}: full compatibility", self.new.name.as_str()) - } else { - let name = if self.new.name != self.old.name { - format!("{} => {}", self.old.name.as_str(), self.new.name.as_str()) - } else { - self.new.name.as_str().to_string() - }; - let mut contents = Vec::new(); - for p in self.mapped_params.iter() { - contents.push(if !p.full_compat() { - format!("param {}", p.report()) - } else { - format!("param {}: compatible", p.new.name.as_str()) - }) - } - for u in self.unknown_params.iter() { - contents.push(format!( - "{} param {}: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - for r in self.mapped_results.iter() { - contents.push(if !r.full_compat() { - format!("result {}", r.report()) - } else { - format!("result {}: compatible", r.new.name.as_str()) - }) - } - for u in self.unknown_results.iter() { - contents.push(format!( - "{} result {}: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - let contents = if contents.is_empty() { - String::new() - } else { - format!(":\n\t\t{}", contents.join("\n\t\t")) - }; - format!("{}{}", name, contents) - } - } pub fn full_compat(&self) -> bool { self.new.name == self.old.name && self.mapped_params.iter().all(|p| p.full_compat()) @@ -231,19 +164,6 @@ impl ParamPolyfill { pub fn full_compat(&self) -> bool { self.new.name == self.old.name && self.repeq == RepEquality::Eq } - pub fn report(&self) -> String { - let name = if self.new.name != self.old.name { - format!("{} => {}", self.old.name.as_str(), self.new.name.as_str()) - } else { - self.new.name.as_str().to_string() - }; - let repr = match self.repeq { - RepEquality::Eq => "compatible types".to_string(), - RepEquality::Superset => format!("{} is superset-compatible with {}", self.old.tref.type_name(), self.new.tref.type_name()), - RepEquality::NotEq => format!("{} is incompatible with new {}", self.old.tref.type_name(), self.new.tref.type_name()) - }; - format!("{}: {}", name, repr) - } } #[derive(Debug, Clone, PartialEq, Eq)] From 3a23a3a2001693675bc2aafe28c0462016d53013 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 4 Dec 2019 11:03:26 -0800 Subject: [PATCH 0360/1772] polyfill: move document creation to the right module --- proposals/filesystem/tools/witx/src/docs.rs | 111 ++++++++++++++++++ proposals/filesystem/tools/witx/src/main.rs | 2 +- .../filesystem/tools/witx/src/polyfill.rs | 84 +------------ 3 files changed, 114 insertions(+), 83 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs index 162e36720..b075f03dc 100644 --- a/proposals/filesystem/tools/witx/src/docs.rs +++ b/proposals/filesystem/tools/witx/src/docs.rs @@ -1,4 +1,6 @@ use crate::ast::*; +use crate::polyfill::*; +use crate::RepEquality; pub trait Documentation { fn to_md(&self) -> String; @@ -236,3 +238,112 @@ impl Documentation for InterfaceFunc { ) } } + +impl Documentation for Polyfill { + fn to_md(&self) -> String { + let module_docs = self + .modules + .iter() + .map(|m| m.to_md()) + .collect::>() + .join("\n"); + let type_docs = format!("TODO"); + format!("# Modules\n{}\n# Types\n{}\n", module_docs, type_docs) + } +} + +impl Documentation for ModulePolyfill { + fn to_md(&self) -> String { + format!( + "## `{}` in terms of `{}`\n{}", + self.new.name.as_str(), + self.old.name.as_str(), + self.funcs + .iter() + .map(|f| f.to_md()) + .collect::>() + .join("\n"), + ) + } +} + +impl Documentation for FuncPolyfill { + fn to_md(&self) -> String { + if self.full_compat() { + format!("* `{}`: full compatibility", self.new.name.as_str()) + } else { + let name = if self.new.name != self.old.name { + format!( + "* `{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("* `{}`", self.new.name.as_str()) + }; + let mut contents = Vec::new(); + for p in self.mapped_params.iter() { + contents.push(if !p.full_compat() { + format!("param {}", p.to_md()) + } else { + format!("param `{}`: compatible", p.new.name.as_str()) + }) + } + for u in self.unknown_params.iter() { + contents.push(format!( + "{} param `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + for r in self.mapped_results.iter() { + contents.push(if !r.full_compat() { + format!("result {}", r.to_md()) + } else { + format!("result `{}`: compatible", r.new.name.as_str()) + }) + } + for u in self.unknown_results.iter() { + contents.push(format!( + "{} result `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + let contents = if contents.is_empty() { + String::new() + } else { + format!(":\n - {}", contents.join("\n - ")) + }; + format!("{}{}", name, contents) + } + } +} + +impl Documentation for ParamPolyfill { + fn to_md(&self) -> String { + let name = if self.new.name != self.old.name { + format!( + "`{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("`{}`", self.new.name.as_str()) + }; + let repr = match self.repeq { + RepEquality::Eq => "compatible types".to_string(), + RepEquality::Superset => format!( + "`{}` is superset-compatible with `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + RepEquality::NotEq => format!( + "`{}` is incompatible with new `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + }; + format!("{}: {}", name, repr) + } +} diff --git a/proposals/filesystem/tools/witx/src/main.rs b/proposals/filesystem/tools/witx/src/main.rs index 8327ac3fb..d7ff23b55 100644 --- a/proposals/filesystem/tools/witx/src/main.rs +++ b/proposals/filesystem/tools/witx/src/main.rs @@ -100,7 +100,7 @@ pub fn main() { let polyfill = witx::polyfill::Polyfill::new(&doc, &older_doc, &module_mapping) .expect("calculate polyfill"); - println!("{}", polyfill.report()); + println!("{}", polyfill.to_md()); if app.is_present("verbose") { println!("{:?}", polyfill); } diff --git a/proposals/filesystem/tools/witx/src/polyfill.rs b/proposals/filesystem/tools/witx/src/polyfill.rs index 492ee44fa..bb5541072 100644 --- a/proposals/filesystem/tools/witx/src/polyfill.rs +++ b/proposals/filesystem/tools/witx/src/polyfill.rs @@ -36,14 +36,6 @@ impl Polyfill { } Ok(Polyfill { modules }) } - - pub fn report(&self) -> String { - self.modules - .iter() - .map(|m| m.report()) - .collect::>() - .join("\n") - } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -66,19 +58,6 @@ impl ModulePolyfill { } Ok(ModulePolyfill { new, old, funcs }) } - - pub fn report(&self) -> String { - format!( - "Implement module {} in terms of {}:\n\t{}", - self.new.name.as_str(), - self.old.name.as_str(), - self.funcs - .iter() - .map(|f| f.report()) - .collect::>() - .join("\n\t"), - ) - } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -103,7 +82,7 @@ impl FuncPolyfill { new: new_param.clone(), old: old_param.clone(), // Call new param type with old param: - repeq : old_param + repeq: old_param .tref .type_() .representable(&new_param.tref.type_()), @@ -134,7 +113,7 @@ impl FuncPolyfill { new: new_result.clone(), old: old_result.clone(), // Return new result type as old result: - repeq : new_result + repeq: new_result .tref .type_() .representable(&old_result.tref.type_()), @@ -165,52 +144,6 @@ impl FuncPolyfill { } } - pub fn report(&self) -> String { - if self.full_compat() { - format!("{}: full compatibility", self.new.name.as_str()) - } else { - let name = if self.new.name != self.old.name { - format!("{} => {}", self.old.name.as_str(), self.new.name.as_str()) - } else { - self.new.name.as_str().to_string() - }; - let mut contents = Vec::new(); - for p in self.mapped_params.iter() { - contents.push(if !p.full_compat() { - format!("param {}", p.report()) - } else { - format!("param {}: compatible", p.new.name.as_str()) - }) - } - for u in self.unknown_params.iter() { - contents.push(format!( - "{} param {}: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - for r in self.mapped_results.iter() { - contents.push(if !r.full_compat() { - format!("result {}", r.report()) - } else { - format!("result {}: compatible", r.new.name.as_str()) - }) - } - for u in self.unknown_results.iter() { - contents.push(format!( - "{} result {}: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - let contents = if contents.is_empty() { - String::new() - } else { - format!(":\n\t\t{}", contents.join("\n\t\t")) - }; - format!("{}{}", name, contents) - } - } pub fn full_compat(&self) -> bool { self.new.name == self.old.name && self.mapped_params.iter().all(|p| p.full_compat()) @@ -231,19 +164,6 @@ impl ParamPolyfill { pub fn full_compat(&self) -> bool { self.new.name == self.old.name && self.repeq == RepEquality::Eq } - pub fn report(&self) -> String { - let name = if self.new.name != self.old.name { - format!("{} => {}", self.old.name.as_str(), self.new.name.as_str()) - } else { - self.new.name.as_str().to_string() - }; - let repr = match self.repeq { - RepEquality::Eq => "compatible types".to_string(), - RepEquality::Superset => format!("{} is superset-compatible with {}", self.old.tref.type_name(), self.new.tref.type_name()), - RepEquality::NotEq => format!("{} is incompatible with new {}", self.old.tref.type_name(), self.new.tref.type_name()) - }; - format!("{}: {}", name, repr) - } } #[derive(Debug, Clone, PartialEq, Eq)] From 94d49c7be810d3ac893b3aa160eb0115435a32c2 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 4 Dec 2019 11:33:53 -0800 Subject: [PATCH 0361/1772] polyfill: note module when func not found --- proposals/clocks/tools/witx/src/polyfill.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/src/polyfill.rs b/proposals/clocks/tools/witx/src/polyfill.rs index bb5541072..729feac3e 100644 --- a/proposals/clocks/tools/witx/src/polyfill.rs +++ b/proposals/clocks/tools/witx/src/polyfill.rs @@ -8,7 +8,7 @@ pub enum PolyfillError { #[error("Module not present: {name:?}")] ModuleNotPresent { name: Id }, #[error("Function not present: {name:?}")] - FuncNotPresent { name: Id }, + FuncNotPresent { module: Id, name: Id }, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -52,6 +52,7 @@ impl ModulePolyfill { let newfunc = new .func(&oldfunc.name) .ok_or_else(|| PolyfillError::FuncNotPresent { + module: new.name.clone(), name: oldfunc.name.clone(), })?; funcs.push(FuncPolyfill::new(newfunc, oldfunc)); From 971d52a01b6906378523629295e5ec951c8bb124 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 4 Dec 2019 11:33:53 -0800 Subject: [PATCH 0362/1772] polyfill: note module when func not found --- proposals/random/tools/witx/src/polyfill.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/src/polyfill.rs b/proposals/random/tools/witx/src/polyfill.rs index bb5541072..729feac3e 100644 --- a/proposals/random/tools/witx/src/polyfill.rs +++ b/proposals/random/tools/witx/src/polyfill.rs @@ -8,7 +8,7 @@ pub enum PolyfillError { #[error("Module not present: {name:?}")] ModuleNotPresent { name: Id }, #[error("Function not present: {name:?}")] - FuncNotPresent { name: Id }, + FuncNotPresent { module: Id, name: Id }, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -52,6 +52,7 @@ impl ModulePolyfill { let newfunc = new .func(&oldfunc.name) .ok_or_else(|| PolyfillError::FuncNotPresent { + module: new.name.clone(), name: oldfunc.name.clone(), })?; funcs.push(FuncPolyfill::new(newfunc, oldfunc)); From 6b3e7d7d20cb8731f97d071bdb0c5da927dc7914 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 4 Dec 2019 11:33:53 -0800 Subject: [PATCH 0363/1772] polyfill: note module when func not found --- proposals/filesystem/tools/witx/src/polyfill.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/src/polyfill.rs b/proposals/filesystem/tools/witx/src/polyfill.rs index bb5541072..729feac3e 100644 --- a/proposals/filesystem/tools/witx/src/polyfill.rs +++ b/proposals/filesystem/tools/witx/src/polyfill.rs @@ -8,7 +8,7 @@ pub enum PolyfillError { #[error("Module not present: {name:?}")] ModuleNotPresent { name: Id }, #[error("Function not present: {name:?}")] - FuncNotPresent { name: Id }, + FuncNotPresent { module: Id, name: Id }, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -52,6 +52,7 @@ impl ModulePolyfill { let newfunc = new .func(&oldfunc.name) .ok_or_else(|| PolyfillError::FuncNotPresent { + module: new.name.clone(), name: oldfunc.name.clone(), })?; funcs.push(FuncPolyfill::new(newfunc, oldfunc)); From 79eb887cd463c77feb6c70783a09797a28f0b3ce Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 4 Dec 2019 12:09:50 -0800 Subject: [PATCH 0364/1772] docs: delete todo --- proposals/clocks/tools/witx/src/docs.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs index b075f03dc..7f391998f 100644 --- a/proposals/clocks/tools/witx/src/docs.rs +++ b/proposals/clocks/tools/witx/src/docs.rs @@ -247,8 +247,7 @@ impl Documentation for Polyfill { .map(|m| m.to_md()) .collect::>() .join("\n"); - let type_docs = format!("TODO"); - format!("# Modules\n{}\n# Types\n{}\n", module_docs, type_docs) + format!("# Modules\n{}\n", module_docs) } } From 3d6cc39b84216b2426e445618b4c94e78bfcc4ff Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 4 Dec 2019 12:09:50 -0800 Subject: [PATCH 0365/1772] docs: delete todo --- proposals/random/tools/witx/src/docs.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs index b075f03dc..7f391998f 100644 --- a/proposals/random/tools/witx/src/docs.rs +++ b/proposals/random/tools/witx/src/docs.rs @@ -247,8 +247,7 @@ impl Documentation for Polyfill { .map(|m| m.to_md()) .collect::>() .join("\n"); - let type_docs = format!("TODO"); - format!("# Modules\n{}\n# Types\n{}\n", module_docs, type_docs) + format!("# Modules\n{}\n", module_docs) } } From d5d843c82308de50e82f6497f68f0130602d6ea4 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 4 Dec 2019 12:09:50 -0800 Subject: [PATCH 0366/1772] docs: delete todo --- proposals/filesystem/tools/witx/src/docs.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs index b075f03dc..7f391998f 100644 --- a/proposals/filesystem/tools/witx/src/docs.rs +++ b/proposals/filesystem/tools/witx/src/docs.rs @@ -247,8 +247,7 @@ impl Documentation for Polyfill { .map(|m| m.to_md()) .collect::>() .join("\n"); - let type_docs = format!("TODO"); - format!("# Modules\n{}\n# Types\n{}\n", module_docs, type_docs) + format!("# Modules\n{}\n", module_docs) } } From a7a632f3f94eca0234266ea73843bc4ab14d0f9e Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 4 Dec 2019 12:13:17 -0800 Subject: [PATCH 0367/1772] rustfmt --- proposals/clocks/tools/witx/src/parser.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 8e7e89bb2..059a7b6ba 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -42,7 +42,6 @@ mod kw { wast::custom_keyword!(u8); } - impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { let mut l = parser.lookahead1(); From e233e88d5f6c2c9cfc25d0aa0ccec20207aa71ce Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 4 Dec 2019 12:13:17 -0800 Subject: [PATCH 0368/1772] rustfmt --- proposals/random/tools/witx/src/parser.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 8e7e89bb2..059a7b6ba 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -42,7 +42,6 @@ mod kw { wast::custom_keyword!(u8); } - impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { let mut l = parser.lookahead1(); From 5b3efd2da625dc2c4252581a904fdf8637cd91ab Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 4 Dec 2019 12:13:17 -0800 Subject: [PATCH 0369/1772] rustfmt --- proposals/filesystem/tools/witx/src/parser.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 8e7e89bb2..059a7b6ba 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -42,7 +42,6 @@ mod kw { wast::custom_keyword!(u8); } - impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { let mut l = parser.lookahead1(); From 815447aece0acc9f653c7e370de251649c325973 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 10 Dec 2019 16:46:36 -0800 Subject: [PATCH 0370/1772] ast: derive Hash everywhere --- proposals/clocks/tools/witx/src/ast.rs | 59 ++++++++++++++++---------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index c3ce4eb64..0388673e3 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -62,7 +62,14 @@ impl PartialEq for Document { } impl Eq for Document {} -#[derive(Debug, Clone)] +impl std::hash::Hash for Document { + fn hash(&self, state: &mut H) { + std::hash::Hash::hash(&self.definitions, state); + } +} + + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Definition { Typename(Rc), Module(Rc), @@ -105,7 +112,7 @@ impl PartialEq for Entry { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum TypeRef { Name(Rc), Value(Rc), @@ -120,7 +127,7 @@ impl TypeRef { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct NamedType { pub name: Id, pub tref: TypeRef, @@ -133,7 +140,7 @@ impl NamedType { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { Enum(EnumDatatype), Flags(FlagsDatatype), @@ -163,7 +170,7 @@ impl Type { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { String, U8, @@ -178,7 +185,7 @@ pub enum BuiltinType { F64, } -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum IntRepr { U8, U16, @@ -186,55 +193,55 @@ pub enum IntRepr { U64, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct EnumDatatype { pub repr: IntRepr, pub variants: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct EnumVariant { pub name: Id, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsDatatype { pub repr: IntRepr, pub flags: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsMember { pub name: Id, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct StructDatatype { pub members: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct StructMember { pub name: Id, pub tref: TypeRef, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionDatatype { pub variants: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionVariant { pub name: Id, pub tref: TypeRef, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct HandleDatatype { pub supertypes: Vec, } @@ -291,12 +298,20 @@ impl PartialEq for Module { fn eq(&self, rhs: &Module) -> bool { // For equality, we don't care about the ordering of definitions, // so we only need to check that the entries map is equal - self.entries == rhs.entries + self.name == rhs.name && self.entries == rhs.entries && self.docs == rhs.docs } } impl Eq for Module {} -#[derive(Debug, Clone)] +impl std::hash::Hash for Module { + fn hash(&self, state: &mut H) { + std::hash::Hash::hash(&self.name, state); + std::hash::Hash::hash(&self.definitions, state); + std::hash::Hash::hash(&self.docs, state); + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ModuleDefinition { Import(Rc), Func(Rc), @@ -330,19 +345,19 @@ impl PartialEq for ModuleEntry { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ModuleImport { pub name: Id, pub variant: ModuleImportVariant, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ModuleImportVariant { Memory, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct InterfaceFunc { pub name: Id, pub params: Vec, @@ -350,7 +365,7 @@ pub struct InterfaceFunc { pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct InterfaceFuncParam { pub name: Id, pub tref: TypeRef, @@ -358,7 +373,7 @@ pub struct InterfaceFuncParam { pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum InterfaceFuncParamPosition { Param(usize), Result(usize), From 34b6f008b7bb6290dbccff494a580a202c75f259 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 10 Dec 2019 16:46:36 -0800 Subject: [PATCH 0371/1772] ast: derive Hash everywhere --- proposals/random/tools/witx/src/ast.rs | 59 ++++++++++++++++---------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index c3ce4eb64..0388673e3 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -62,7 +62,14 @@ impl PartialEq for Document { } impl Eq for Document {} -#[derive(Debug, Clone)] +impl std::hash::Hash for Document { + fn hash(&self, state: &mut H) { + std::hash::Hash::hash(&self.definitions, state); + } +} + + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Definition { Typename(Rc), Module(Rc), @@ -105,7 +112,7 @@ impl PartialEq for Entry { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum TypeRef { Name(Rc), Value(Rc), @@ -120,7 +127,7 @@ impl TypeRef { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct NamedType { pub name: Id, pub tref: TypeRef, @@ -133,7 +140,7 @@ impl NamedType { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { Enum(EnumDatatype), Flags(FlagsDatatype), @@ -163,7 +170,7 @@ impl Type { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { String, U8, @@ -178,7 +185,7 @@ pub enum BuiltinType { F64, } -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum IntRepr { U8, U16, @@ -186,55 +193,55 @@ pub enum IntRepr { U64, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct EnumDatatype { pub repr: IntRepr, pub variants: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct EnumVariant { pub name: Id, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsDatatype { pub repr: IntRepr, pub flags: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsMember { pub name: Id, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct StructDatatype { pub members: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct StructMember { pub name: Id, pub tref: TypeRef, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionDatatype { pub variants: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionVariant { pub name: Id, pub tref: TypeRef, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct HandleDatatype { pub supertypes: Vec, } @@ -291,12 +298,20 @@ impl PartialEq for Module { fn eq(&self, rhs: &Module) -> bool { // For equality, we don't care about the ordering of definitions, // so we only need to check that the entries map is equal - self.entries == rhs.entries + self.name == rhs.name && self.entries == rhs.entries && self.docs == rhs.docs } } impl Eq for Module {} -#[derive(Debug, Clone)] +impl std::hash::Hash for Module { + fn hash(&self, state: &mut H) { + std::hash::Hash::hash(&self.name, state); + std::hash::Hash::hash(&self.definitions, state); + std::hash::Hash::hash(&self.docs, state); + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ModuleDefinition { Import(Rc), Func(Rc), @@ -330,19 +345,19 @@ impl PartialEq for ModuleEntry { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ModuleImport { pub name: Id, pub variant: ModuleImportVariant, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ModuleImportVariant { Memory, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct InterfaceFunc { pub name: Id, pub params: Vec, @@ -350,7 +365,7 @@ pub struct InterfaceFunc { pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct InterfaceFuncParam { pub name: Id, pub tref: TypeRef, @@ -358,7 +373,7 @@ pub struct InterfaceFuncParam { pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum InterfaceFuncParamPosition { Param(usize), Result(usize), From 62e0b01bd1a8e3f6f527b2c7f04fb426bf037387 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 10 Dec 2019 16:46:36 -0800 Subject: [PATCH 0372/1772] ast: derive Hash everywhere --- proposals/filesystem/tools/witx/src/ast.rs | 59 ++++++++++++++-------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index c3ce4eb64..0388673e3 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -62,7 +62,14 @@ impl PartialEq for Document { } impl Eq for Document {} -#[derive(Debug, Clone)] +impl std::hash::Hash for Document { + fn hash(&self, state: &mut H) { + std::hash::Hash::hash(&self.definitions, state); + } +} + + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Definition { Typename(Rc), Module(Rc), @@ -105,7 +112,7 @@ impl PartialEq for Entry { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum TypeRef { Name(Rc), Value(Rc), @@ -120,7 +127,7 @@ impl TypeRef { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct NamedType { pub name: Id, pub tref: TypeRef, @@ -133,7 +140,7 @@ impl NamedType { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { Enum(EnumDatatype), Flags(FlagsDatatype), @@ -163,7 +170,7 @@ impl Type { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { String, U8, @@ -178,7 +185,7 @@ pub enum BuiltinType { F64, } -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum IntRepr { U8, U16, @@ -186,55 +193,55 @@ pub enum IntRepr { U64, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct EnumDatatype { pub repr: IntRepr, pub variants: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct EnumVariant { pub name: Id, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsDatatype { pub repr: IntRepr, pub flags: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsMember { pub name: Id, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct StructDatatype { pub members: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct StructMember { pub name: Id, pub tref: TypeRef, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionDatatype { pub variants: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionVariant { pub name: Id, pub tref: TypeRef, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct HandleDatatype { pub supertypes: Vec, } @@ -291,12 +298,20 @@ impl PartialEq for Module { fn eq(&self, rhs: &Module) -> bool { // For equality, we don't care about the ordering of definitions, // so we only need to check that the entries map is equal - self.entries == rhs.entries + self.name == rhs.name && self.entries == rhs.entries && self.docs == rhs.docs } } impl Eq for Module {} -#[derive(Debug, Clone)] +impl std::hash::Hash for Module { + fn hash(&self, state: &mut H) { + std::hash::Hash::hash(&self.name, state); + std::hash::Hash::hash(&self.definitions, state); + std::hash::Hash::hash(&self.docs, state); + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ModuleDefinition { Import(Rc), Func(Rc), @@ -330,19 +345,19 @@ impl PartialEq for ModuleEntry { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ModuleImport { pub name: Id, pub variant: ModuleImportVariant, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ModuleImportVariant { Memory, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct InterfaceFunc { pub name: Id, pub params: Vec, @@ -350,7 +365,7 @@ pub struct InterfaceFunc { pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct InterfaceFuncParam { pub name: Id, pub tref: TypeRef, @@ -358,7 +373,7 @@ pub struct InterfaceFuncParam { pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum InterfaceFuncParamPosition { Param(usize), Result(usize), From 52f96e5cbd7575ca2de8bc83f7374e9531a00d17 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 10 Dec 2019 16:58:04 -0800 Subject: [PATCH 0373/1772] polyfills: calculate type polyfills as a set --- proposals/clocks/tools/witx/src/docs.rs | 2 +- proposals/clocks/tools/witx/src/polyfill.rs | 105 +++++++++++++++----- 2 files changed, 79 insertions(+), 28 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs index 7f391998f..715e2cb80 100644 --- a/proposals/clocks/tools/witx/src/docs.rs +++ b/proposals/clocks/tools/witx/src/docs.rs @@ -330,7 +330,7 @@ impl Documentation for ParamPolyfill { } else { format!("`{}`", self.new.name.as_str()) }; - let repr = match self.repeq { + let repr = match self.repeq() { RepEquality::Eq => "compatible types".to_string(), RepEquality::Superset => format!( "`{}` is superset-compatible with `{}`", diff --git a/proposals/clocks/tools/witx/src/polyfill.rs b/proposals/clocks/tools/witx/src/polyfill.rs index 729feac3e..04847508d 100644 --- a/proposals/clocks/tools/witx/src/polyfill.rs +++ b/proposals/clocks/tools/witx/src/polyfill.rs @@ -1,5 +1,7 @@ -use crate::{Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable}; -use std::collections::HashMap; +use crate::{ + Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable, TypeRef, +}; +use std::collections::{HashMap, HashSet}; use std::rc::Rc; use thiserror::Error; @@ -11,7 +13,7 @@ pub enum PolyfillError { FuncNotPresent { module: Id, name: Id }, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Polyfill { pub modules: Vec, } @@ -36,9 +38,17 @@ impl Polyfill { } Ok(Polyfill { modules }) } + + pub fn type_polyfills(&self) -> HashSet { + self.modules + .iter() + .map(|m| m.type_polyfills()) + .flatten() + .collect() + } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ModulePolyfill { pub new: Rc, pub old: Rc, @@ -59,9 +69,16 @@ impl ModulePolyfill { } Ok(ModulePolyfill { new, old, funcs }) } + pub fn type_polyfills(&self) -> HashSet { + self.funcs + .iter() + .map(|f| f.type_polyfills()) + .flatten() + .collect() + } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FuncPolyfill { pub new: Rc, pub old: Rc, @@ -79,15 +96,7 @@ impl FuncPolyfill { // Old function is called. Need to map each of its parameters to the new function: for old_param in old.params.iter() { if let Some(new_param) = new.params.iter().find(|p| p.name == old_param.name) { - mapped_params.push(ParamPolyfill { - new: new_param.clone(), - old: old_param.clone(), - // Call new param type with old param: - repeq: old_param - .tref - .type_() - .representable(&new_param.tref.type_()), - }) + mapped_params.push(ParamPolyfill::param(new_param.clone(), old_param.clone())) } else { unknown_params.push(ParamUnknown::Old(old_param.clone())); } @@ -110,15 +119,10 @@ impl FuncPolyfill { // New function has returned. Need to map each of its results to the old function: for new_result in new.results.iter() { if let Some(old_result) = old.results.iter().find(|p| p.name == new_result.name) { - mapped_results.push(ParamPolyfill { - new: new_result.clone(), - old: old_result.clone(), - // Return new result type as old result: - repeq: new_result - .tref - .type_() - .representable(&old_result.tref.type_()), - }) + mapped_results.push(ParamPolyfill::result( + new_result.clone(), + old_result.clone(), + )) } else { unknown_results.push(ParamUnknown::New(new_result.clone())); } @@ -152,22 +156,54 @@ impl FuncPolyfill { && self.mapped_results.iter().all(|p| p.full_compat()) && self.unknown_results.is_empty() } + + pub fn type_polyfills(&self) -> HashSet { + self.mapped_params + .iter() + .map(|p| p.type_polyfill.clone()) + .chain(self.mapped_results.iter().map(|p| p.type_polyfill.clone())) + .collect() + } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ParamPolyfill { pub new: InterfaceFuncParam, pub old: InterfaceFuncParam, - pub repeq: RepEquality, + pub type_polyfill: TypePolyfill, } impl ParamPolyfill { + pub fn param(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { + // Call new param type with old param: + let type_polyfill = TypePolyfill::OldToNew(old.tref.clone(), new.tref.clone()); + ParamPolyfill { + new, + old, + type_polyfill, + } + } + + pub fn result(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { + // Return old result type from new result: + let type_polyfill = TypePolyfill::NewToOld(new.tref.clone(), old.tref.clone()); + ParamPolyfill { + new, + old, + type_polyfill, + } + } + pub fn full_compat(&self) -> bool { - self.new.name == self.old.name && self.repeq == RepEquality::Eq + self.new.name == self.old.name && self.repeq() == RepEquality::Eq + } + + pub fn repeq(&self) -> RepEquality { + self.type_polyfill.repeq() } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ParamUnknown { Old(InterfaceFuncParam), New(InterfaceFuncParam), @@ -187,3 +223,18 @@ impl ParamUnknown { } } } + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum TypePolyfill { + NewToOld(TypeRef, TypeRef), + OldToNew(TypeRef, TypeRef), +} + +impl TypePolyfill { + pub fn repeq(&self) -> RepEquality { + match self { + TypePolyfill::NewToOld(new, old) => old.type_().representable(&new.type_()), + TypePolyfill::OldToNew(old, new) => new.type_().representable(&old.type_()), + } + } +} From 4788435ddefcd19545e234c9dc2379c38e549709 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 10 Dec 2019 16:58:04 -0800 Subject: [PATCH 0374/1772] polyfills: calculate type polyfills as a set --- proposals/random/tools/witx/src/docs.rs | 2 +- proposals/random/tools/witx/src/polyfill.rs | 105 +++++++++++++++----- 2 files changed, 79 insertions(+), 28 deletions(-) diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs index 7f391998f..715e2cb80 100644 --- a/proposals/random/tools/witx/src/docs.rs +++ b/proposals/random/tools/witx/src/docs.rs @@ -330,7 +330,7 @@ impl Documentation for ParamPolyfill { } else { format!("`{}`", self.new.name.as_str()) }; - let repr = match self.repeq { + let repr = match self.repeq() { RepEquality::Eq => "compatible types".to_string(), RepEquality::Superset => format!( "`{}` is superset-compatible with `{}`", diff --git a/proposals/random/tools/witx/src/polyfill.rs b/proposals/random/tools/witx/src/polyfill.rs index 729feac3e..04847508d 100644 --- a/proposals/random/tools/witx/src/polyfill.rs +++ b/proposals/random/tools/witx/src/polyfill.rs @@ -1,5 +1,7 @@ -use crate::{Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable}; -use std::collections::HashMap; +use crate::{ + Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable, TypeRef, +}; +use std::collections::{HashMap, HashSet}; use std::rc::Rc; use thiserror::Error; @@ -11,7 +13,7 @@ pub enum PolyfillError { FuncNotPresent { module: Id, name: Id }, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Polyfill { pub modules: Vec, } @@ -36,9 +38,17 @@ impl Polyfill { } Ok(Polyfill { modules }) } + + pub fn type_polyfills(&self) -> HashSet { + self.modules + .iter() + .map(|m| m.type_polyfills()) + .flatten() + .collect() + } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ModulePolyfill { pub new: Rc, pub old: Rc, @@ -59,9 +69,16 @@ impl ModulePolyfill { } Ok(ModulePolyfill { new, old, funcs }) } + pub fn type_polyfills(&self) -> HashSet { + self.funcs + .iter() + .map(|f| f.type_polyfills()) + .flatten() + .collect() + } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FuncPolyfill { pub new: Rc, pub old: Rc, @@ -79,15 +96,7 @@ impl FuncPolyfill { // Old function is called. Need to map each of its parameters to the new function: for old_param in old.params.iter() { if let Some(new_param) = new.params.iter().find(|p| p.name == old_param.name) { - mapped_params.push(ParamPolyfill { - new: new_param.clone(), - old: old_param.clone(), - // Call new param type with old param: - repeq: old_param - .tref - .type_() - .representable(&new_param.tref.type_()), - }) + mapped_params.push(ParamPolyfill::param(new_param.clone(), old_param.clone())) } else { unknown_params.push(ParamUnknown::Old(old_param.clone())); } @@ -110,15 +119,10 @@ impl FuncPolyfill { // New function has returned. Need to map each of its results to the old function: for new_result in new.results.iter() { if let Some(old_result) = old.results.iter().find(|p| p.name == new_result.name) { - mapped_results.push(ParamPolyfill { - new: new_result.clone(), - old: old_result.clone(), - // Return new result type as old result: - repeq: new_result - .tref - .type_() - .representable(&old_result.tref.type_()), - }) + mapped_results.push(ParamPolyfill::result( + new_result.clone(), + old_result.clone(), + )) } else { unknown_results.push(ParamUnknown::New(new_result.clone())); } @@ -152,22 +156,54 @@ impl FuncPolyfill { && self.mapped_results.iter().all(|p| p.full_compat()) && self.unknown_results.is_empty() } + + pub fn type_polyfills(&self) -> HashSet { + self.mapped_params + .iter() + .map(|p| p.type_polyfill.clone()) + .chain(self.mapped_results.iter().map(|p| p.type_polyfill.clone())) + .collect() + } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ParamPolyfill { pub new: InterfaceFuncParam, pub old: InterfaceFuncParam, - pub repeq: RepEquality, + pub type_polyfill: TypePolyfill, } impl ParamPolyfill { + pub fn param(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { + // Call new param type with old param: + let type_polyfill = TypePolyfill::OldToNew(old.tref.clone(), new.tref.clone()); + ParamPolyfill { + new, + old, + type_polyfill, + } + } + + pub fn result(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { + // Return old result type from new result: + let type_polyfill = TypePolyfill::NewToOld(new.tref.clone(), old.tref.clone()); + ParamPolyfill { + new, + old, + type_polyfill, + } + } + pub fn full_compat(&self) -> bool { - self.new.name == self.old.name && self.repeq == RepEquality::Eq + self.new.name == self.old.name && self.repeq() == RepEquality::Eq + } + + pub fn repeq(&self) -> RepEquality { + self.type_polyfill.repeq() } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ParamUnknown { Old(InterfaceFuncParam), New(InterfaceFuncParam), @@ -187,3 +223,18 @@ impl ParamUnknown { } } } + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum TypePolyfill { + NewToOld(TypeRef, TypeRef), + OldToNew(TypeRef, TypeRef), +} + +impl TypePolyfill { + pub fn repeq(&self) -> RepEquality { + match self { + TypePolyfill::NewToOld(new, old) => old.type_().representable(&new.type_()), + TypePolyfill::OldToNew(old, new) => new.type_().representable(&old.type_()), + } + } +} From 7784d40101d8ff5d691db32920a138054dc1aa62 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 10 Dec 2019 16:58:04 -0800 Subject: [PATCH 0375/1772] polyfills: calculate type polyfills as a set --- proposals/filesystem/tools/witx/src/docs.rs | 2 +- .../filesystem/tools/witx/src/polyfill.rs | 105 +++++++++++++----- 2 files changed, 79 insertions(+), 28 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs index 7f391998f..715e2cb80 100644 --- a/proposals/filesystem/tools/witx/src/docs.rs +++ b/proposals/filesystem/tools/witx/src/docs.rs @@ -330,7 +330,7 @@ impl Documentation for ParamPolyfill { } else { format!("`{}`", self.new.name.as_str()) }; - let repr = match self.repeq { + let repr = match self.repeq() { RepEquality::Eq => "compatible types".to_string(), RepEquality::Superset => format!( "`{}` is superset-compatible with `{}`", diff --git a/proposals/filesystem/tools/witx/src/polyfill.rs b/proposals/filesystem/tools/witx/src/polyfill.rs index 729feac3e..04847508d 100644 --- a/proposals/filesystem/tools/witx/src/polyfill.rs +++ b/proposals/filesystem/tools/witx/src/polyfill.rs @@ -1,5 +1,7 @@ -use crate::{Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable}; -use std::collections::HashMap; +use crate::{ + Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable, TypeRef, +}; +use std::collections::{HashMap, HashSet}; use std::rc::Rc; use thiserror::Error; @@ -11,7 +13,7 @@ pub enum PolyfillError { FuncNotPresent { module: Id, name: Id }, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Polyfill { pub modules: Vec, } @@ -36,9 +38,17 @@ impl Polyfill { } Ok(Polyfill { modules }) } + + pub fn type_polyfills(&self) -> HashSet { + self.modules + .iter() + .map(|m| m.type_polyfills()) + .flatten() + .collect() + } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ModulePolyfill { pub new: Rc, pub old: Rc, @@ -59,9 +69,16 @@ impl ModulePolyfill { } Ok(ModulePolyfill { new, old, funcs }) } + pub fn type_polyfills(&self) -> HashSet { + self.funcs + .iter() + .map(|f| f.type_polyfills()) + .flatten() + .collect() + } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FuncPolyfill { pub new: Rc, pub old: Rc, @@ -79,15 +96,7 @@ impl FuncPolyfill { // Old function is called. Need to map each of its parameters to the new function: for old_param in old.params.iter() { if let Some(new_param) = new.params.iter().find(|p| p.name == old_param.name) { - mapped_params.push(ParamPolyfill { - new: new_param.clone(), - old: old_param.clone(), - // Call new param type with old param: - repeq: old_param - .tref - .type_() - .representable(&new_param.tref.type_()), - }) + mapped_params.push(ParamPolyfill::param(new_param.clone(), old_param.clone())) } else { unknown_params.push(ParamUnknown::Old(old_param.clone())); } @@ -110,15 +119,10 @@ impl FuncPolyfill { // New function has returned. Need to map each of its results to the old function: for new_result in new.results.iter() { if let Some(old_result) = old.results.iter().find(|p| p.name == new_result.name) { - mapped_results.push(ParamPolyfill { - new: new_result.clone(), - old: old_result.clone(), - // Return new result type as old result: - repeq: new_result - .tref - .type_() - .representable(&old_result.tref.type_()), - }) + mapped_results.push(ParamPolyfill::result( + new_result.clone(), + old_result.clone(), + )) } else { unknown_results.push(ParamUnknown::New(new_result.clone())); } @@ -152,22 +156,54 @@ impl FuncPolyfill { && self.mapped_results.iter().all(|p| p.full_compat()) && self.unknown_results.is_empty() } + + pub fn type_polyfills(&self) -> HashSet { + self.mapped_params + .iter() + .map(|p| p.type_polyfill.clone()) + .chain(self.mapped_results.iter().map(|p| p.type_polyfill.clone())) + .collect() + } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ParamPolyfill { pub new: InterfaceFuncParam, pub old: InterfaceFuncParam, - pub repeq: RepEquality, + pub type_polyfill: TypePolyfill, } impl ParamPolyfill { + pub fn param(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { + // Call new param type with old param: + let type_polyfill = TypePolyfill::OldToNew(old.tref.clone(), new.tref.clone()); + ParamPolyfill { + new, + old, + type_polyfill, + } + } + + pub fn result(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { + // Return old result type from new result: + let type_polyfill = TypePolyfill::NewToOld(new.tref.clone(), old.tref.clone()); + ParamPolyfill { + new, + old, + type_polyfill, + } + } + pub fn full_compat(&self) -> bool { - self.new.name == self.old.name && self.repeq == RepEquality::Eq + self.new.name == self.old.name && self.repeq() == RepEquality::Eq + } + + pub fn repeq(&self) -> RepEquality { + self.type_polyfill.repeq() } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ParamUnknown { Old(InterfaceFuncParam), New(InterfaceFuncParam), @@ -187,3 +223,18 @@ impl ParamUnknown { } } } + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum TypePolyfill { + NewToOld(TypeRef, TypeRef), + OldToNew(TypeRef, TypeRef), +} + +impl TypePolyfill { + pub fn repeq(&self) -> RepEquality { + match self { + TypePolyfill::NewToOld(new, old) => old.type_().representable(&new.type_()), + TypePolyfill::OldToNew(old, new) => new.type_().representable(&old.type_()), + } + } +} From d307644d50d8e6c97eb6406e139c6ddde71df280 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 11 Dec 2019 09:41:23 -0800 Subject: [PATCH 0376/1772] polyfill: a type polyfill can use a common denominator --- proposals/clocks/tools/witx/src/docs.rs | 43 ++++++++++++++++++++- proposals/clocks/tools/witx/src/polyfill.rs | 21 ++++++++-- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs index 715e2cb80..cbae46bfb 100644 --- a/proposals/clocks/tools/witx/src/docs.rs +++ b/proposals/clocks/tools/witx/src/docs.rs @@ -247,7 +247,22 @@ impl Documentation for Polyfill { .map(|m| m.to_md()) .collect::>() .join("\n"); - format!("# Modules\n{}\n", module_docs) + let type_docs = self + .type_polyfills() + .iter() + .filter_map(|t| { + if t.repeq() == RepEquality::Eq { + None + } else { + Some(t.to_md()) + } + }) + .collect::>() + .join("\n"); + format!( + "# Modules\n{}\n# Type Conversions\n{}\n", + module_docs, type_docs + ) } } @@ -346,3 +361,29 @@ impl Documentation for ParamPolyfill { format!("{}: {}", name, repr) } } + +impl Documentation for TypePolyfill { + fn to_md(&self) -> String { + fn repeq_name(r: RepEquality) -> &'static str { + match r { + RepEquality::Eq => ": compatible", + RepEquality::Superset => ": superset", + RepEquality::NotEq => "", + } + } + match self { + TypePolyfill::OldToNew(o, n) => format!( + "* old `{}` => new `{}`{}", + o.type_name(), + n.type_name(), + repeq_name(self.repeq()) + ), + TypePolyfill::NewToOld(n, o) => format!( + "* new `{}` => old `{}`{}", + n.type_name(), + o.type_name(), + repeq_name(self.repeq()) + ), + } + } +} diff --git a/proposals/clocks/tools/witx/src/polyfill.rs b/proposals/clocks/tools/witx/src/polyfill.rs index 04847508d..6181d357c 100644 --- a/proposals/clocks/tools/witx/src/polyfill.rs +++ b/proposals/clocks/tools/witx/src/polyfill.rs @@ -1,5 +1,6 @@ use crate::{ - Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable, TypeRef, + Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable, Type, + TypeRef, }; use std::collections::{HashMap, HashSet}; use std::rc::Rc; @@ -174,9 +175,22 @@ pub struct ParamPolyfill { } impl ParamPolyfill { + fn common_denominator(a: TypeRef, b: TypeRef) -> (TypeRef, TypeRef) { + match (&a, &b) { + (TypeRef::Value(va), TypeRef::Value(vb)) => match (&**va, &**vb) { + (Type::Array(a), Type::Array(b)) => (a.clone(), b.clone()), + (Type::Pointer(a), Type::Pointer(b)) => (a.clone(), b.clone()), + (Type::ConstPointer(a), Type::ConstPointer(b)) => (a.clone(), b.clone()), + _ => (a, b), + }, + _ => (a, b), + } + } + pub fn param(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { + let (told, tnew) = Self::common_denominator(old.tref.clone(), new.tref.clone()); // Call new param type with old param: - let type_polyfill = TypePolyfill::OldToNew(old.tref.clone(), new.tref.clone()); + let type_polyfill = TypePolyfill::OldToNew(told, tnew); ParamPolyfill { new, old, @@ -185,8 +199,9 @@ impl ParamPolyfill { } pub fn result(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { + let (told, tnew) = Self::common_denominator(old.tref.clone(), new.tref.clone()); // Return old result type from new result: - let type_polyfill = TypePolyfill::NewToOld(new.tref.clone(), old.tref.clone()); + let type_polyfill = TypePolyfill::NewToOld(tnew, told); ParamPolyfill { new, old, From ae5d26a37704906e1a4a720aacea44b650ba721e Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 11 Dec 2019 09:41:23 -0800 Subject: [PATCH 0377/1772] polyfill: a type polyfill can use a common denominator --- proposals/random/tools/witx/src/docs.rs | 43 ++++++++++++++++++++- proposals/random/tools/witx/src/polyfill.rs | 21 ++++++++-- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs index 715e2cb80..cbae46bfb 100644 --- a/proposals/random/tools/witx/src/docs.rs +++ b/proposals/random/tools/witx/src/docs.rs @@ -247,7 +247,22 @@ impl Documentation for Polyfill { .map(|m| m.to_md()) .collect::>() .join("\n"); - format!("# Modules\n{}\n", module_docs) + let type_docs = self + .type_polyfills() + .iter() + .filter_map(|t| { + if t.repeq() == RepEquality::Eq { + None + } else { + Some(t.to_md()) + } + }) + .collect::>() + .join("\n"); + format!( + "# Modules\n{}\n# Type Conversions\n{}\n", + module_docs, type_docs + ) } } @@ -346,3 +361,29 @@ impl Documentation for ParamPolyfill { format!("{}: {}", name, repr) } } + +impl Documentation for TypePolyfill { + fn to_md(&self) -> String { + fn repeq_name(r: RepEquality) -> &'static str { + match r { + RepEquality::Eq => ": compatible", + RepEquality::Superset => ": superset", + RepEquality::NotEq => "", + } + } + match self { + TypePolyfill::OldToNew(o, n) => format!( + "* old `{}` => new `{}`{}", + o.type_name(), + n.type_name(), + repeq_name(self.repeq()) + ), + TypePolyfill::NewToOld(n, o) => format!( + "* new `{}` => old `{}`{}", + n.type_name(), + o.type_name(), + repeq_name(self.repeq()) + ), + } + } +} diff --git a/proposals/random/tools/witx/src/polyfill.rs b/proposals/random/tools/witx/src/polyfill.rs index 04847508d..6181d357c 100644 --- a/proposals/random/tools/witx/src/polyfill.rs +++ b/proposals/random/tools/witx/src/polyfill.rs @@ -1,5 +1,6 @@ use crate::{ - Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable, TypeRef, + Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable, Type, + TypeRef, }; use std::collections::{HashMap, HashSet}; use std::rc::Rc; @@ -174,9 +175,22 @@ pub struct ParamPolyfill { } impl ParamPolyfill { + fn common_denominator(a: TypeRef, b: TypeRef) -> (TypeRef, TypeRef) { + match (&a, &b) { + (TypeRef::Value(va), TypeRef::Value(vb)) => match (&**va, &**vb) { + (Type::Array(a), Type::Array(b)) => (a.clone(), b.clone()), + (Type::Pointer(a), Type::Pointer(b)) => (a.clone(), b.clone()), + (Type::ConstPointer(a), Type::ConstPointer(b)) => (a.clone(), b.clone()), + _ => (a, b), + }, + _ => (a, b), + } + } + pub fn param(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { + let (told, tnew) = Self::common_denominator(old.tref.clone(), new.tref.clone()); // Call new param type with old param: - let type_polyfill = TypePolyfill::OldToNew(old.tref.clone(), new.tref.clone()); + let type_polyfill = TypePolyfill::OldToNew(told, tnew); ParamPolyfill { new, old, @@ -185,8 +199,9 @@ impl ParamPolyfill { } pub fn result(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { + let (told, tnew) = Self::common_denominator(old.tref.clone(), new.tref.clone()); // Return old result type from new result: - let type_polyfill = TypePolyfill::NewToOld(new.tref.clone(), old.tref.clone()); + let type_polyfill = TypePolyfill::NewToOld(tnew, told); ParamPolyfill { new, old, From 4d0e49ce6ad3069aaffbe22192684969a0f54091 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 11 Dec 2019 09:41:23 -0800 Subject: [PATCH 0378/1772] polyfill: a type polyfill can use a common denominator --- proposals/filesystem/tools/witx/src/docs.rs | 43 ++++++++++++++++++- .../filesystem/tools/witx/src/polyfill.rs | 21 +++++++-- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs index 715e2cb80..cbae46bfb 100644 --- a/proposals/filesystem/tools/witx/src/docs.rs +++ b/proposals/filesystem/tools/witx/src/docs.rs @@ -247,7 +247,22 @@ impl Documentation for Polyfill { .map(|m| m.to_md()) .collect::>() .join("\n"); - format!("# Modules\n{}\n", module_docs) + let type_docs = self + .type_polyfills() + .iter() + .filter_map(|t| { + if t.repeq() == RepEquality::Eq { + None + } else { + Some(t.to_md()) + } + }) + .collect::>() + .join("\n"); + format!( + "# Modules\n{}\n# Type Conversions\n{}\n", + module_docs, type_docs + ) } } @@ -346,3 +361,29 @@ impl Documentation for ParamPolyfill { format!("{}: {}", name, repr) } } + +impl Documentation for TypePolyfill { + fn to_md(&self) -> String { + fn repeq_name(r: RepEquality) -> &'static str { + match r { + RepEquality::Eq => ": compatible", + RepEquality::Superset => ": superset", + RepEquality::NotEq => "", + } + } + match self { + TypePolyfill::OldToNew(o, n) => format!( + "* old `{}` => new `{}`{}", + o.type_name(), + n.type_name(), + repeq_name(self.repeq()) + ), + TypePolyfill::NewToOld(n, o) => format!( + "* new `{}` => old `{}`{}", + n.type_name(), + o.type_name(), + repeq_name(self.repeq()) + ), + } + } +} diff --git a/proposals/filesystem/tools/witx/src/polyfill.rs b/proposals/filesystem/tools/witx/src/polyfill.rs index 04847508d..6181d357c 100644 --- a/proposals/filesystem/tools/witx/src/polyfill.rs +++ b/proposals/filesystem/tools/witx/src/polyfill.rs @@ -1,5 +1,6 @@ use crate::{ - Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable, TypeRef, + Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable, Type, + TypeRef, }; use std::collections::{HashMap, HashSet}; use std::rc::Rc; @@ -174,9 +175,22 @@ pub struct ParamPolyfill { } impl ParamPolyfill { + fn common_denominator(a: TypeRef, b: TypeRef) -> (TypeRef, TypeRef) { + match (&a, &b) { + (TypeRef::Value(va), TypeRef::Value(vb)) => match (&**va, &**vb) { + (Type::Array(a), Type::Array(b)) => (a.clone(), b.clone()), + (Type::Pointer(a), Type::Pointer(b)) => (a.clone(), b.clone()), + (Type::ConstPointer(a), Type::ConstPointer(b)) => (a.clone(), b.clone()), + _ => (a, b), + }, + _ => (a, b), + } + } + pub fn param(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { + let (told, tnew) = Self::common_denominator(old.tref.clone(), new.tref.clone()); // Call new param type with old param: - let type_polyfill = TypePolyfill::OldToNew(old.tref.clone(), new.tref.clone()); + let type_polyfill = TypePolyfill::OldToNew(told, tnew); ParamPolyfill { new, old, @@ -185,8 +199,9 @@ impl ParamPolyfill { } pub fn result(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { + let (told, tnew) = Self::common_denominator(old.tref.clone(), new.tref.clone()); // Return old result type from new result: - let type_polyfill = TypePolyfill::NewToOld(new.tref.clone(), old.tref.clone()); + let type_polyfill = TypePolyfill::NewToOld(tnew, told); ParamPolyfill { new, old, From c5bb1c3412b858199ea3f10fff3cd6f2c84ec6c0 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Dec 2019 16:41:51 -0800 Subject: [PATCH 0379/1772] add module for calculating C ABI layout of datatypes --- proposals/clocks/tools/witx/src/layout.rs | 146 ++++++++++++++++++++++ proposals/clocks/tools/witx/src/lib.rs | 2 + 2 files changed, 148 insertions(+) create mode 100644 proposals/clocks/tools/witx/src/layout.rs diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs new file mode 100644 index 000000000..626ac67b2 --- /dev/null +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -0,0 +1,146 @@ +use crate::ast::*; +use std::collections::HashMap; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct SizeAlign { + size: usize, + align: usize, +} + +pub trait Layout { + fn mem_size_align(&self) -> SizeAlign; + fn mem_size(&self) -> usize { + self.mem_size_align().size + } + fn mem_align(&self) -> usize { + self.mem_size_align().align + } +} + +impl TypeRef { + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + if let Some(hit) = cache.get(self) { + return *hit; + } + let layout = match &*self.type_() { + Type::Enum(e) => e.repr.layout(), + Type::Flags(f) => f.repr.layout(), + Type::Struct(s) => s.layout(cache), + Type::Union(u) => u.layout(cache), + Type::Handle { .. } => BuiltinType::U32.layout(), + Type::Array { .. } => BuiltinType::String.layout(), + Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.layout(), + Type::Builtin(b) => b.layout(), + }; + cache.insert(self.clone(), layout); + layout + } +} + +impl Layout for TypeRef { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + +impl IntRepr { + pub fn layout(&self) -> SizeAlign { + match self { + IntRepr::U8 => BuiltinType::U8.layout(), + IntRepr::U16 => BuiltinType::U16.layout(), + IntRepr::U32 => BuiltinType::U32.layout(), + IntRepr::U64 => BuiltinType::U64.layout(), + } + } +} + +pub struct StructMemberLayout<'a> { + member: &'a StructMember, + offset: usize, +} + +impl StructDatatype { + pub fn member_layout( + &self, + cache: &mut HashMap, + ) -> Vec { + let mut members = Vec::new(); + let mut offset = 0; + for m in self.members.iter() { + let sa = m.tref.layout(cache); + offset = align_to(offset, sa.align); + members.push(StructMemberLayout { member: m, offset }); + offset += sa.size; + } + members + } + + pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { + let members = self.member_layout(cache); + let align = members + .iter() + .map(|m| m.member.tref.layout(cache).align) + .max() + .expect("nonzero struct members"); + let last_offset = members.last().expect("nonzero struct members").offset; + let size = align_to(last_offset, align); + SizeAlign { size, align } + } +} + +/// If the next free byte in the struct is `offs`, and the next +/// element has alignment `alignment`, determine the offset at +/// which to place that element. +fn align_to(offs: usize, alignment: usize) -> usize { + offs + alignment - 1 - ((offs + alignment - 1) % alignment) +} + +#[cfg(test)] +mod test { + use super::align_to; + #[test] + fn align() { + assert_eq!(0, align_to(0, 1)); + assert_eq!(0, align_to(0, 2)); + assert_eq!(0, align_to(0, 4)); + assert_eq!(0, align_to(0, 8)); + + assert_eq!(1, align_to(1, 1)); + assert_eq!(2, align_to(1, 2)); + assert_eq!(4, align_to(1, 4)); + assert_eq!(8, align_to(1, 8)); + + assert_eq!(2, align_to(2, 1)); + assert_eq!(2, align_to(2, 2)); + assert_eq!(4, align_to(2, 4)); + assert_eq!(8, align_to(2, 8)); + + assert_eq!(5, align_to(5, 1)); + assert_eq!(6, align_to(5, 2)); + assert_eq!(8, align_to(5, 4)); + assert_eq!(8, align_to(5, 8)); + } +} + +impl UnionDatatype { + pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { + unimplemented!() + } +} + +impl BuiltinType { + pub fn layout(&self) -> SizeAlign { + match self { + BuiltinType::String => SizeAlign { size: 8, align: 4 }, // Pointer and Length + BuiltinType::U8 | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, + BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, + BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { + SizeAlign { size: 4, align: 4 } + } + BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { + SizeAlign { size: 8, align: 8 } + } + } + } +} diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 018b55133..0e3ac3d50 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -6,6 +6,8 @@ mod coretypes; mod docs; /// Interface for filesystem or mock IO mod io; +/// Calculate memory layout of types +pub mod layout; /// Witx syntax parsing from SExprs mod parser; /// Calculate required polyfill between interfaces From 754a68cf9860be3b81216a52149c9125b6fabb88 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Dec 2019 16:41:51 -0800 Subject: [PATCH 0380/1772] add module for calculating C ABI layout of datatypes --- proposals/random/tools/witx/src/layout.rs | 146 ++++++++++++++++++++++ proposals/random/tools/witx/src/lib.rs | 2 + 2 files changed, 148 insertions(+) create mode 100644 proposals/random/tools/witx/src/layout.rs diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs new file mode 100644 index 000000000..626ac67b2 --- /dev/null +++ b/proposals/random/tools/witx/src/layout.rs @@ -0,0 +1,146 @@ +use crate::ast::*; +use std::collections::HashMap; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct SizeAlign { + size: usize, + align: usize, +} + +pub trait Layout { + fn mem_size_align(&self) -> SizeAlign; + fn mem_size(&self) -> usize { + self.mem_size_align().size + } + fn mem_align(&self) -> usize { + self.mem_size_align().align + } +} + +impl TypeRef { + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + if let Some(hit) = cache.get(self) { + return *hit; + } + let layout = match &*self.type_() { + Type::Enum(e) => e.repr.layout(), + Type::Flags(f) => f.repr.layout(), + Type::Struct(s) => s.layout(cache), + Type::Union(u) => u.layout(cache), + Type::Handle { .. } => BuiltinType::U32.layout(), + Type::Array { .. } => BuiltinType::String.layout(), + Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.layout(), + Type::Builtin(b) => b.layout(), + }; + cache.insert(self.clone(), layout); + layout + } +} + +impl Layout for TypeRef { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + +impl IntRepr { + pub fn layout(&self) -> SizeAlign { + match self { + IntRepr::U8 => BuiltinType::U8.layout(), + IntRepr::U16 => BuiltinType::U16.layout(), + IntRepr::U32 => BuiltinType::U32.layout(), + IntRepr::U64 => BuiltinType::U64.layout(), + } + } +} + +pub struct StructMemberLayout<'a> { + member: &'a StructMember, + offset: usize, +} + +impl StructDatatype { + pub fn member_layout( + &self, + cache: &mut HashMap, + ) -> Vec { + let mut members = Vec::new(); + let mut offset = 0; + for m in self.members.iter() { + let sa = m.tref.layout(cache); + offset = align_to(offset, sa.align); + members.push(StructMemberLayout { member: m, offset }); + offset += sa.size; + } + members + } + + pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { + let members = self.member_layout(cache); + let align = members + .iter() + .map(|m| m.member.tref.layout(cache).align) + .max() + .expect("nonzero struct members"); + let last_offset = members.last().expect("nonzero struct members").offset; + let size = align_to(last_offset, align); + SizeAlign { size, align } + } +} + +/// If the next free byte in the struct is `offs`, and the next +/// element has alignment `alignment`, determine the offset at +/// which to place that element. +fn align_to(offs: usize, alignment: usize) -> usize { + offs + alignment - 1 - ((offs + alignment - 1) % alignment) +} + +#[cfg(test)] +mod test { + use super::align_to; + #[test] + fn align() { + assert_eq!(0, align_to(0, 1)); + assert_eq!(0, align_to(0, 2)); + assert_eq!(0, align_to(0, 4)); + assert_eq!(0, align_to(0, 8)); + + assert_eq!(1, align_to(1, 1)); + assert_eq!(2, align_to(1, 2)); + assert_eq!(4, align_to(1, 4)); + assert_eq!(8, align_to(1, 8)); + + assert_eq!(2, align_to(2, 1)); + assert_eq!(2, align_to(2, 2)); + assert_eq!(4, align_to(2, 4)); + assert_eq!(8, align_to(2, 8)); + + assert_eq!(5, align_to(5, 1)); + assert_eq!(6, align_to(5, 2)); + assert_eq!(8, align_to(5, 4)); + assert_eq!(8, align_to(5, 8)); + } +} + +impl UnionDatatype { + pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { + unimplemented!() + } +} + +impl BuiltinType { + pub fn layout(&self) -> SizeAlign { + match self { + BuiltinType::String => SizeAlign { size: 8, align: 4 }, // Pointer and Length + BuiltinType::U8 | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, + BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, + BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { + SizeAlign { size: 4, align: 4 } + } + BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { + SizeAlign { size: 8, align: 8 } + } + } + } +} diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 018b55133..0e3ac3d50 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -6,6 +6,8 @@ mod coretypes; mod docs; /// Interface for filesystem or mock IO mod io; +/// Calculate memory layout of types +pub mod layout; /// Witx syntax parsing from SExprs mod parser; /// Calculate required polyfill between interfaces From fbbb742d6732ff8adc52f263cc324f3ff02a3684 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Dec 2019 16:41:51 -0800 Subject: [PATCH 0381/1772] add module for calculating C ABI layout of datatypes --- proposals/filesystem/tools/witx/src/layout.rs | 146 ++++++++++++++++++ proposals/filesystem/tools/witx/src/lib.rs | 2 + 2 files changed, 148 insertions(+) create mode 100644 proposals/filesystem/tools/witx/src/layout.rs diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs new file mode 100644 index 000000000..626ac67b2 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -0,0 +1,146 @@ +use crate::ast::*; +use std::collections::HashMap; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct SizeAlign { + size: usize, + align: usize, +} + +pub trait Layout { + fn mem_size_align(&self) -> SizeAlign; + fn mem_size(&self) -> usize { + self.mem_size_align().size + } + fn mem_align(&self) -> usize { + self.mem_size_align().align + } +} + +impl TypeRef { + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + if let Some(hit) = cache.get(self) { + return *hit; + } + let layout = match &*self.type_() { + Type::Enum(e) => e.repr.layout(), + Type::Flags(f) => f.repr.layout(), + Type::Struct(s) => s.layout(cache), + Type::Union(u) => u.layout(cache), + Type::Handle { .. } => BuiltinType::U32.layout(), + Type::Array { .. } => BuiltinType::String.layout(), + Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.layout(), + Type::Builtin(b) => b.layout(), + }; + cache.insert(self.clone(), layout); + layout + } +} + +impl Layout for TypeRef { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + +impl IntRepr { + pub fn layout(&self) -> SizeAlign { + match self { + IntRepr::U8 => BuiltinType::U8.layout(), + IntRepr::U16 => BuiltinType::U16.layout(), + IntRepr::U32 => BuiltinType::U32.layout(), + IntRepr::U64 => BuiltinType::U64.layout(), + } + } +} + +pub struct StructMemberLayout<'a> { + member: &'a StructMember, + offset: usize, +} + +impl StructDatatype { + pub fn member_layout( + &self, + cache: &mut HashMap, + ) -> Vec { + let mut members = Vec::new(); + let mut offset = 0; + for m in self.members.iter() { + let sa = m.tref.layout(cache); + offset = align_to(offset, sa.align); + members.push(StructMemberLayout { member: m, offset }); + offset += sa.size; + } + members + } + + pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { + let members = self.member_layout(cache); + let align = members + .iter() + .map(|m| m.member.tref.layout(cache).align) + .max() + .expect("nonzero struct members"); + let last_offset = members.last().expect("nonzero struct members").offset; + let size = align_to(last_offset, align); + SizeAlign { size, align } + } +} + +/// If the next free byte in the struct is `offs`, and the next +/// element has alignment `alignment`, determine the offset at +/// which to place that element. +fn align_to(offs: usize, alignment: usize) -> usize { + offs + alignment - 1 - ((offs + alignment - 1) % alignment) +} + +#[cfg(test)] +mod test { + use super::align_to; + #[test] + fn align() { + assert_eq!(0, align_to(0, 1)); + assert_eq!(0, align_to(0, 2)); + assert_eq!(0, align_to(0, 4)); + assert_eq!(0, align_to(0, 8)); + + assert_eq!(1, align_to(1, 1)); + assert_eq!(2, align_to(1, 2)); + assert_eq!(4, align_to(1, 4)); + assert_eq!(8, align_to(1, 8)); + + assert_eq!(2, align_to(2, 1)); + assert_eq!(2, align_to(2, 2)); + assert_eq!(4, align_to(2, 4)); + assert_eq!(8, align_to(2, 8)); + + assert_eq!(5, align_to(5, 1)); + assert_eq!(6, align_to(5, 2)); + assert_eq!(8, align_to(5, 4)); + assert_eq!(8, align_to(5, 8)); + } +} + +impl UnionDatatype { + pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { + unimplemented!() + } +} + +impl BuiltinType { + pub fn layout(&self) -> SizeAlign { + match self { + BuiltinType::String => SizeAlign { size: 8, align: 4 }, // Pointer and Length + BuiltinType::U8 | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, + BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, + BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { + SizeAlign { size: 4, align: 4 } + } + BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { + SizeAlign { size: 8, align: 8 } + } + } + } +} diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 018b55133..0e3ac3d50 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -6,6 +6,8 @@ mod coretypes; mod docs; /// Interface for filesystem or mock IO mod io; +/// Calculate memory layout of types +pub mod layout; /// Witx syntax parsing from SExprs mod parser; /// Calculate required polyfill between interfaces From 258a6901fb7878cfac14e08eafb3f350bc5e80eb Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Dec 2019 16:48:25 -0800 Subject: [PATCH 0382/1772] rustfmt --- proposals/clocks/tools/witx/src/ast.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 0388673e3..224a614c6 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -68,7 +68,6 @@ impl std::hash::Hash for Document { } } - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Definition { Typename(Rc), From 3a4b20fd3d78108466522e8f89f65a2fd117a803 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Dec 2019 16:48:25 -0800 Subject: [PATCH 0383/1772] rustfmt --- proposals/random/tools/witx/src/ast.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 0388673e3..224a614c6 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -68,7 +68,6 @@ impl std::hash::Hash for Document { } } - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Definition { Typename(Rc), From b2bf85d847e6df204f54d3d3b3dc38e5b1d3e24d Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Dec 2019 16:48:25 -0800 Subject: [PATCH 0384/1772] rustfmt --- proposals/filesystem/tools/witx/src/ast.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 0388673e3..224a614c6 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -68,7 +68,6 @@ impl std::hash::Hash for Document { } } - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Definition { Typename(Rc), From b77e2e3690300455c633577d190e33751de81312 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Dec 2019 16:41:51 -0800 Subject: [PATCH 0385/1772] add module for calculating C ABI layout of datatypes --- proposals/clocks/tools/witx/src/layout.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index 626ac67b2..9aa1df682 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -125,7 +125,22 @@ mod test { impl UnionDatatype { pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { - unimplemented!() + let sas = self + .variants + .iter() + .map(|v| v.tref.layout(cache)) + .collect::>(); + let size = sas + .iter() + .map(|sa| sa.size) + .max() + .expect("nonzero variants"); + let align = sas + .iter() + .map(|sa| sa.align) + .max() + .expect("nonzero variants"); + SizeAlign { size, align } } } From 361e24e694b6bed5e5a6d2d42c09da163a9a365f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Dec 2019 16:41:51 -0800 Subject: [PATCH 0386/1772] add module for calculating C ABI layout of datatypes --- proposals/random/tools/witx/src/layout.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index 626ac67b2..9aa1df682 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -125,7 +125,22 @@ mod test { impl UnionDatatype { pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { - unimplemented!() + let sas = self + .variants + .iter() + .map(|v| v.tref.layout(cache)) + .collect::>(); + let size = sas + .iter() + .map(|sa| sa.size) + .max() + .expect("nonzero variants"); + let align = sas + .iter() + .map(|sa| sa.align) + .max() + .expect("nonzero variants"); + SizeAlign { size, align } } } From 6f86b6f1ea758a2418cde8490ab26c79fe6f0c91 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Dec 2019 16:41:51 -0800 Subject: [PATCH 0387/1772] add module for calculating C ABI layout of datatypes --- proposals/filesystem/tools/witx/src/layout.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index 626ac67b2..9aa1df682 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -125,7 +125,22 @@ mod test { impl UnionDatatype { pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { - unimplemented!() + let sas = self + .variants + .iter() + .map(|v| v.tref.layout(cache)) + .collect::>(); + let size = sas + .iter() + .map(|sa| sa.size) + .max() + .expect("nonzero variants"); + let align = sas + .iter() + .map(|sa| sa.align) + .max() + .expect("nonzero variants"); + SizeAlign { size, align } } } From 48a6b75fe9e07990e1aa015e8cad1af758dc0ef7 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Dec 2019 16:51:32 -0800 Subject: [PATCH 0388/1772] expose SizeAlign fields --- proposals/clocks/tools/witx/src/layout.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index 9aa1df682..16c14337e 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -3,8 +3,8 @@ use std::collections::HashMap; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct SizeAlign { - size: usize, - align: usize, + pub size: usize, + pub align: usize, } pub trait Layout { From f336743f4f72d816b38af8f4fe747b212fd99059 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Dec 2019 16:51:32 -0800 Subject: [PATCH 0389/1772] expose SizeAlign fields --- proposals/random/tools/witx/src/layout.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index 9aa1df682..16c14337e 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -3,8 +3,8 @@ use std::collections::HashMap; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct SizeAlign { - size: usize, - align: usize, + pub size: usize, + pub align: usize, } pub trait Layout { From 98a05260b775df604dd6dd0c76bbe268da18619c Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Dec 2019 16:51:32 -0800 Subject: [PATCH 0390/1772] expose SizeAlign fields --- proposals/filesystem/tools/witx/src/layout.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index 9aa1df682..16c14337e 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -3,8 +3,8 @@ use std::collections::HashMap; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct SizeAlign { - size: usize, - align: usize, + pub size: usize, + pub align: usize, } pub trait Layout { From 03a1e6856f518d09ed2cc69c3f874ff437fd7270 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Dec 2019 17:26:38 -0800 Subject: [PATCH 0391/1772] layout: fix bugs, clean up exports --- proposals/clocks/tools/witx/src/layout.rs | 67 ++++++++++++++--------- proposals/clocks/tools/witx/src/lib.rs | 3 +- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index 16c14337e..80a30470b 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -23,14 +23,14 @@ impl TypeRef { return *hit; } let layout = match &*self.type_() { - Type::Enum(e) => e.repr.layout(), - Type::Flags(f) => f.repr.layout(), + Type::Enum(e) => e.repr.mem_size_align(), + Type::Flags(f) => f.repr.mem_size_align(), Type::Struct(s) => s.layout(cache), Type::Union(u) => u.layout(cache), - Type::Handle { .. } => BuiltinType::U32.layout(), - Type::Array { .. } => BuiltinType::String.layout(), - Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.layout(), - Type::Builtin(b) => b.layout(), + Type::Handle { .. } => BuiltinType::U32.mem_size_align(), + Type::Array { .. } => BuiltinType::String.mem_size_align(), + Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), + Type::Builtin(b) => b.mem_size_align(), }; cache.insert(self.clone(), layout); layout @@ -43,28 +43,28 @@ impl Layout for TypeRef { self.layout(&mut cache) } } - -impl IntRepr { - pub fn layout(&self) -> SizeAlign { +impl Layout for IntRepr { + fn mem_size_align(&self) -> SizeAlign { match self { - IntRepr::U8 => BuiltinType::U8.layout(), - IntRepr::U16 => BuiltinType::U16.layout(), - IntRepr::U32 => BuiltinType::U32.layout(), - IntRepr::U64 => BuiltinType::U64.layout(), + IntRepr::U8 => BuiltinType::U8.mem_size_align(), + IntRepr::U16 => BuiltinType::U16.mem_size_align(), + IntRepr::U32 => BuiltinType::U32.mem_size_align(), + IntRepr::U64 => BuiltinType::U64.mem_size_align(), } } } pub struct StructMemberLayout<'a> { - member: &'a StructMember, - offset: usize, + pub member: &'a StructMember, + pub offset: usize, } impl StructDatatype { - pub fn member_layout( - &self, - cache: &mut HashMap, - ) -> Vec { + pub fn member_layout(&self) -> Vec { + self.member_layout_(&mut HashMap::new()) + } + + fn member_layout_(&self, cache: &mut HashMap) -> Vec { let mut members = Vec::new(); let mut offset = 0; for m in self.members.iter() { @@ -76,19 +76,27 @@ impl StructDatatype { members } - pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { - let members = self.member_layout(cache); + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + let members = self.member_layout_(cache); let align = members .iter() .map(|m| m.member.tref.layout(cache).align) .max() .expect("nonzero struct members"); - let last_offset = members.last().expect("nonzero struct members").offset; - let size = align_to(last_offset, align); + let last = members.last().expect("nonzero struct members"); + let size = last.offset + last.member.tref.layout(cache).size; + let size = align_to(size, align); SizeAlign { size, align } } } +impl Layout for StructDatatype { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + /// If the next free byte in the struct is `offs`, and the next /// element has alignment `alignment`, determine the offset at /// which to place that element. @@ -124,7 +132,7 @@ mod test { } impl UnionDatatype { - pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { + fn layout(&self, cache: &mut HashMap) -> SizeAlign { let sas = self .variants .iter() @@ -144,8 +152,15 @@ impl UnionDatatype { } } -impl BuiltinType { - pub fn layout(&self) -> SizeAlign { +impl Layout for UnionDatatype { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + +impl Layout for BuiltinType { + fn mem_size_align(&self) -> SizeAlign { match self { BuiltinType::String => SizeAlign { size: 8, align: 4 }, // Pointer and Length BuiltinType::U8 | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 0e3ac3d50..1ef5d5693 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -7,7 +7,7 @@ mod docs; /// Interface for filesystem or mock IO mod io; /// Calculate memory layout of types -pub mod layout; +mod layout; /// Witx syntax parsing from SExprs mod parser; /// Calculate required polyfill between interfaces @@ -31,6 +31,7 @@ pub use ast::{ pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; +pub use layout::{Layout, SizeAlign, StructMemberLayout}; pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; From 3b69ef56447061bcdc72642d9418e454c45bdfb0 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Dec 2019 17:26:38 -0800 Subject: [PATCH 0392/1772] layout: fix bugs, clean up exports --- proposals/random/tools/witx/src/layout.rs | 67 ++++++++++++++--------- proposals/random/tools/witx/src/lib.rs | 3 +- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index 16c14337e..80a30470b 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -23,14 +23,14 @@ impl TypeRef { return *hit; } let layout = match &*self.type_() { - Type::Enum(e) => e.repr.layout(), - Type::Flags(f) => f.repr.layout(), + Type::Enum(e) => e.repr.mem_size_align(), + Type::Flags(f) => f.repr.mem_size_align(), Type::Struct(s) => s.layout(cache), Type::Union(u) => u.layout(cache), - Type::Handle { .. } => BuiltinType::U32.layout(), - Type::Array { .. } => BuiltinType::String.layout(), - Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.layout(), - Type::Builtin(b) => b.layout(), + Type::Handle { .. } => BuiltinType::U32.mem_size_align(), + Type::Array { .. } => BuiltinType::String.mem_size_align(), + Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), + Type::Builtin(b) => b.mem_size_align(), }; cache.insert(self.clone(), layout); layout @@ -43,28 +43,28 @@ impl Layout for TypeRef { self.layout(&mut cache) } } - -impl IntRepr { - pub fn layout(&self) -> SizeAlign { +impl Layout for IntRepr { + fn mem_size_align(&self) -> SizeAlign { match self { - IntRepr::U8 => BuiltinType::U8.layout(), - IntRepr::U16 => BuiltinType::U16.layout(), - IntRepr::U32 => BuiltinType::U32.layout(), - IntRepr::U64 => BuiltinType::U64.layout(), + IntRepr::U8 => BuiltinType::U8.mem_size_align(), + IntRepr::U16 => BuiltinType::U16.mem_size_align(), + IntRepr::U32 => BuiltinType::U32.mem_size_align(), + IntRepr::U64 => BuiltinType::U64.mem_size_align(), } } } pub struct StructMemberLayout<'a> { - member: &'a StructMember, - offset: usize, + pub member: &'a StructMember, + pub offset: usize, } impl StructDatatype { - pub fn member_layout( - &self, - cache: &mut HashMap, - ) -> Vec { + pub fn member_layout(&self) -> Vec { + self.member_layout_(&mut HashMap::new()) + } + + fn member_layout_(&self, cache: &mut HashMap) -> Vec { let mut members = Vec::new(); let mut offset = 0; for m in self.members.iter() { @@ -76,19 +76,27 @@ impl StructDatatype { members } - pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { - let members = self.member_layout(cache); + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + let members = self.member_layout_(cache); let align = members .iter() .map(|m| m.member.tref.layout(cache).align) .max() .expect("nonzero struct members"); - let last_offset = members.last().expect("nonzero struct members").offset; - let size = align_to(last_offset, align); + let last = members.last().expect("nonzero struct members"); + let size = last.offset + last.member.tref.layout(cache).size; + let size = align_to(size, align); SizeAlign { size, align } } } +impl Layout for StructDatatype { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + /// If the next free byte in the struct is `offs`, and the next /// element has alignment `alignment`, determine the offset at /// which to place that element. @@ -124,7 +132,7 @@ mod test { } impl UnionDatatype { - pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { + fn layout(&self, cache: &mut HashMap) -> SizeAlign { let sas = self .variants .iter() @@ -144,8 +152,15 @@ impl UnionDatatype { } } -impl BuiltinType { - pub fn layout(&self) -> SizeAlign { +impl Layout for UnionDatatype { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + +impl Layout for BuiltinType { + fn mem_size_align(&self) -> SizeAlign { match self { BuiltinType::String => SizeAlign { size: 8, align: 4 }, // Pointer and Length BuiltinType::U8 | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 0e3ac3d50..1ef5d5693 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -7,7 +7,7 @@ mod docs; /// Interface for filesystem or mock IO mod io; /// Calculate memory layout of types -pub mod layout; +mod layout; /// Witx syntax parsing from SExprs mod parser; /// Calculate required polyfill between interfaces @@ -31,6 +31,7 @@ pub use ast::{ pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; +pub use layout::{Layout, SizeAlign, StructMemberLayout}; pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; From 03d96faf5a23d2041642fcd8392d3e16f6cf2ede Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Dec 2019 17:26:38 -0800 Subject: [PATCH 0393/1772] layout: fix bugs, clean up exports --- proposals/filesystem/tools/witx/src/layout.rs | 67 ++++++++++++------- proposals/filesystem/tools/witx/src/lib.rs | 3 +- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index 16c14337e..80a30470b 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -23,14 +23,14 @@ impl TypeRef { return *hit; } let layout = match &*self.type_() { - Type::Enum(e) => e.repr.layout(), - Type::Flags(f) => f.repr.layout(), + Type::Enum(e) => e.repr.mem_size_align(), + Type::Flags(f) => f.repr.mem_size_align(), Type::Struct(s) => s.layout(cache), Type::Union(u) => u.layout(cache), - Type::Handle { .. } => BuiltinType::U32.layout(), - Type::Array { .. } => BuiltinType::String.layout(), - Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.layout(), - Type::Builtin(b) => b.layout(), + Type::Handle { .. } => BuiltinType::U32.mem_size_align(), + Type::Array { .. } => BuiltinType::String.mem_size_align(), + Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), + Type::Builtin(b) => b.mem_size_align(), }; cache.insert(self.clone(), layout); layout @@ -43,28 +43,28 @@ impl Layout for TypeRef { self.layout(&mut cache) } } - -impl IntRepr { - pub fn layout(&self) -> SizeAlign { +impl Layout for IntRepr { + fn mem_size_align(&self) -> SizeAlign { match self { - IntRepr::U8 => BuiltinType::U8.layout(), - IntRepr::U16 => BuiltinType::U16.layout(), - IntRepr::U32 => BuiltinType::U32.layout(), - IntRepr::U64 => BuiltinType::U64.layout(), + IntRepr::U8 => BuiltinType::U8.mem_size_align(), + IntRepr::U16 => BuiltinType::U16.mem_size_align(), + IntRepr::U32 => BuiltinType::U32.mem_size_align(), + IntRepr::U64 => BuiltinType::U64.mem_size_align(), } } } pub struct StructMemberLayout<'a> { - member: &'a StructMember, - offset: usize, + pub member: &'a StructMember, + pub offset: usize, } impl StructDatatype { - pub fn member_layout( - &self, - cache: &mut HashMap, - ) -> Vec { + pub fn member_layout(&self) -> Vec { + self.member_layout_(&mut HashMap::new()) + } + + fn member_layout_(&self, cache: &mut HashMap) -> Vec { let mut members = Vec::new(); let mut offset = 0; for m in self.members.iter() { @@ -76,19 +76,27 @@ impl StructDatatype { members } - pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { - let members = self.member_layout(cache); + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + let members = self.member_layout_(cache); let align = members .iter() .map(|m| m.member.tref.layout(cache).align) .max() .expect("nonzero struct members"); - let last_offset = members.last().expect("nonzero struct members").offset; - let size = align_to(last_offset, align); + let last = members.last().expect("nonzero struct members"); + let size = last.offset + last.member.tref.layout(cache).size; + let size = align_to(size, align); SizeAlign { size, align } } } +impl Layout for StructDatatype { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + /// If the next free byte in the struct is `offs`, and the next /// element has alignment `alignment`, determine the offset at /// which to place that element. @@ -124,7 +132,7 @@ mod test { } impl UnionDatatype { - pub fn layout(&self, cache: &mut HashMap) -> SizeAlign { + fn layout(&self, cache: &mut HashMap) -> SizeAlign { let sas = self .variants .iter() @@ -144,8 +152,15 @@ impl UnionDatatype { } } -impl BuiltinType { - pub fn layout(&self) -> SizeAlign { +impl Layout for UnionDatatype { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + +impl Layout for BuiltinType { + fn mem_size_align(&self) -> SizeAlign { match self { BuiltinType::String => SizeAlign { size: 8, align: 4 }, // Pointer and Length BuiltinType::U8 | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 0e3ac3d50..1ef5d5693 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -7,7 +7,7 @@ mod docs; /// Interface for filesystem or mock IO mod io; /// Calculate memory layout of types -pub mod layout; +mod layout; /// Witx syntax parsing from SExprs mod parser; /// Calculate required polyfill between interfaces @@ -31,6 +31,7 @@ pub use ast::{ pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; +pub use layout::{Layout, SizeAlign, StructMemberLayout}; pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; From fb2f50bf1b18829488a72345c9691ecb0c003da1 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Dec 2019 17:49:24 -0800 Subject: [PATCH 0394/1772] layout: give HandleDatatype the trait too --- proposals/clocks/tools/witx/src/layout.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index 80a30470b..ca5457ece 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -27,7 +27,7 @@ impl TypeRef { Type::Flags(f) => f.repr.mem_size_align(), Type::Struct(s) => s.layout(cache), Type::Union(u) => u.layout(cache), - Type::Handle { .. } => BuiltinType::U32.mem_size_align(), + Type::Handle(h) => h.mem_size_align(), Type::Array { .. } => BuiltinType::String.mem_size_align(), Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), @@ -159,6 +159,12 @@ impl Layout for UnionDatatype { } } +impl Layout for HandleDatatype { + fn mem_size_align(&self) -> SizeAlign { + BuiltinType::U32.mem_size_align() + } +} + impl Layout for BuiltinType { fn mem_size_align(&self) -> SizeAlign { match self { From 185fec01bd4d28361e34ec049125296158fd91b4 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Dec 2019 17:49:24 -0800 Subject: [PATCH 0395/1772] layout: give HandleDatatype the trait too --- proposals/random/tools/witx/src/layout.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index 80a30470b..ca5457ece 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -27,7 +27,7 @@ impl TypeRef { Type::Flags(f) => f.repr.mem_size_align(), Type::Struct(s) => s.layout(cache), Type::Union(u) => u.layout(cache), - Type::Handle { .. } => BuiltinType::U32.mem_size_align(), + Type::Handle(h) => h.mem_size_align(), Type::Array { .. } => BuiltinType::String.mem_size_align(), Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), @@ -159,6 +159,12 @@ impl Layout for UnionDatatype { } } +impl Layout for HandleDatatype { + fn mem_size_align(&self) -> SizeAlign { + BuiltinType::U32.mem_size_align() + } +} + impl Layout for BuiltinType { fn mem_size_align(&self) -> SizeAlign { match self { From cb0ee56e785ea9eda53cbdc628c62c31157b9be5 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Dec 2019 17:49:24 -0800 Subject: [PATCH 0396/1772] layout: give HandleDatatype the trait too --- proposals/filesystem/tools/witx/src/layout.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index 80a30470b..ca5457ece 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -27,7 +27,7 @@ impl TypeRef { Type::Flags(f) => f.repr.mem_size_align(), Type::Struct(s) => s.layout(cache), Type::Union(u) => u.layout(cache), - Type::Handle { .. } => BuiltinType::U32.mem_size_align(), + Type::Handle(h) => h.mem_size_align(), Type::Array { .. } => BuiltinType::String.mem_size_align(), Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), @@ -159,6 +159,12 @@ impl Layout for UnionDatatype { } } +impl Layout for HandleDatatype { + fn mem_size_align(&self) -> SizeAlign { + BuiltinType::U32.mem_size_align() + } +} + impl Layout for BuiltinType { fn mem_size_align(&self) -> SizeAlign { match self { From b900122fcc5f6b63f65566d64b2c0ab65b18f937 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 19 Dec 2019 15:00:50 -0800 Subject: [PATCH 0397/1772] witx: make some render funcs public, so we can reuse them in witx-test --- proposals/clocks/tools/witx/src/render.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 2c08aef40..fadc70310 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -47,19 +47,19 @@ impl fmt::Display for SExpr { } impl SExpr { - fn word(s: &str) -> SExpr { + pub fn word(s: &str) -> SExpr { SExpr::Word(s.to_string()) } - fn ident(s: &str) -> SExpr { + pub fn ident(s: &str) -> SExpr { SExpr::Ident(s.to_string()) } - fn quote(s: &str) -> SExpr { + pub fn quote(s: &str) -> SExpr { SExpr::Quote(s.to_string()) } - fn annot(s: &str) -> SExpr { + pub fn annot(s: &str) -> SExpr { SExpr::Annot(s.to_string()) } - fn docs(d: &str, s: SExpr) -> SExpr { + pub fn docs(d: &str, s: SExpr) -> SExpr { if d.is_empty() { s } else { From 2e25d2605fff5130680795245cbda18db2ce0379 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 19 Dec 2019 15:00:50 -0800 Subject: [PATCH 0398/1772] witx: make some render funcs public, so we can reuse them in witx-test --- proposals/random/tools/witx/src/render.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 2c08aef40..fadc70310 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -47,19 +47,19 @@ impl fmt::Display for SExpr { } impl SExpr { - fn word(s: &str) -> SExpr { + pub fn word(s: &str) -> SExpr { SExpr::Word(s.to_string()) } - fn ident(s: &str) -> SExpr { + pub fn ident(s: &str) -> SExpr { SExpr::Ident(s.to_string()) } - fn quote(s: &str) -> SExpr { + pub fn quote(s: &str) -> SExpr { SExpr::Quote(s.to_string()) } - fn annot(s: &str) -> SExpr { + pub fn annot(s: &str) -> SExpr { SExpr::Annot(s.to_string()) } - fn docs(d: &str, s: SExpr) -> SExpr { + pub fn docs(d: &str, s: SExpr) -> SExpr { if d.is_empty() { s } else { From 81175672cfca5dc615301e23db4659c75c581a15 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 19 Dec 2019 15:00:50 -0800 Subject: [PATCH 0399/1772] witx: make some render funcs public, so we can reuse them in witx-test --- proposals/filesystem/tools/witx/src/render.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 2c08aef40..fadc70310 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -47,19 +47,19 @@ impl fmt::Display for SExpr { } impl SExpr { - fn word(s: &str) -> SExpr { + pub fn word(s: &str) -> SExpr { SExpr::Word(s.to_string()) } - fn ident(s: &str) -> SExpr { + pub fn ident(s: &str) -> SExpr { SExpr::Ident(s.to_string()) } - fn quote(s: &str) -> SExpr { + pub fn quote(s: &str) -> SExpr { SExpr::Quote(s.to_string()) } - fn annot(s: &str) -> SExpr { + pub fn annot(s: &str) -> SExpr { SExpr::Annot(s.to_string()) } - fn docs(d: &str, s: SExpr) -> SExpr { + pub fn docs(d: &str, s: SExpr) -> SExpr { if d.is_empty() { s } else { From ca8ad9eb322c2fdcdeea3ab9df5310545b5142e1 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 19 Dec 2019 17:04:03 -0800 Subject: [PATCH 0400/1772] witx layout: fix calculation of union size --- proposals/clocks/tools/witx/src/layout.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index ca5457ece..506cec038 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -148,6 +148,7 @@ impl UnionDatatype { .map(|sa| sa.align) .max() .expect("nonzero variants"); + let size = align_to(size, align); SizeAlign { size, align } } } From 89159c0d48006623ffb4d340133060d80b5116e8 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 19 Dec 2019 17:04:03 -0800 Subject: [PATCH 0401/1772] witx layout: fix calculation of union size --- proposals/random/tools/witx/src/layout.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index ca5457ece..506cec038 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -148,6 +148,7 @@ impl UnionDatatype { .map(|sa| sa.align) .max() .expect("nonzero variants"); + let size = align_to(size, align); SizeAlign { size, align } } } From c28c7691450d000a5c4dc61acc9110d488055965 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 19 Dec 2019 17:04:03 -0800 Subject: [PATCH 0402/1772] witx layout: fix calculation of union size --- proposals/filesystem/tools/witx/src/layout.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index ca5457ece..506cec038 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -148,6 +148,7 @@ impl UnionDatatype { .map(|sa| sa.align) .max() .expect("nonzero variants"); + let size = align_to(size, align); SizeAlign { size, align } } } From 417c64ccc92ada5f11d7ab2b0bfe7f867acb553b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 16 Dec 2019 06:11:56 -0800 Subject: [PATCH 0403/1772] Add a char8 type to represent data which is expected to be valid UTF-8. This will allow the generated C header file to use [char8_t]. [char8_t]: https://en.cppreference.com/w/cpp/keyword/char8_t Fixes #6. --- .../clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx | 4 ++-- .../clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx | 4 ++-- .../clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx | 2 +- .../clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx | 2 +- .../clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx | 2 +- proposals/clocks/tools/witx/src/ast.rs | 1 + proposals/clocks/tools/witx/src/coretypes.rs | 3 ++- proposals/clocks/tools/witx/src/docs.rs | 1 + proposals/clocks/tools/witx/src/layout.rs | 4 +++- proposals/clocks/tools/witx/src/parser.rs | 5 +++++ proposals/clocks/tools/witx/src/render.rs | 1 + 11 files changed, 20 insertions(+), 9 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx index 2c2d32d67..485fafd27 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -12,8 +12,8 @@ ;;; Read command-line argument data. ;;; The size of the array should match that returned by `sizes_get` (@interface func (export "get") - (param $argv (@witx pointer (@witx pointer u8))) - (param $argv_buf (@witx pointer u8)) + (param $argv (@witx pointer (@witx pointer char8))) + (param $argv_buf (@witx pointer char8)) (result $error $errno) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx index 5bc9c5a6f..2adcb2874 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -12,8 +12,8 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `sizes_get`. (@interface func (export "get") - (param $environ (@witx pointer (@witx pointer u8))) - (param $environ_buf (@witx pointer u8)) + (param $environ (@witx pointer (@witx pointer char8))) + (param $environ_buf (@witx pointer char8)) (result $error $errno) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx index 9fbad9ab7..d7d88c7b0 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -132,7 +132,7 @@ (@interface func (export "prestat_dir_name") (param $fd $fd) ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer u8)) + (param $path (@witx pointer char8)) (param $path_len $size) (result $error $errno) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx index 16c974692..e700a482b 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -106,7 +106,7 @@ ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer u8)) + (param $buf (@witx pointer char8)) (param $buf_len $size) (result $error $errno) ;;; The number of bytes placed in the buffer. diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx index 55c6df021..e68d50c91 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx @@ -19,7 +19,7 @@ ;;; number generator, rather than to provide the random data directly. (@interface func (export "get") ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) + (param $buf (@witx pointer char8)) (param $buf_len $size) (result $error $errno) ) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 224a614c6..2c9f4c65e 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -172,6 +172,7 @@ impl Type { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { String, + Char8, U8, U16, U32, diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index d772b3f54..47ef6908b 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -41,7 +41,8 @@ impl Type { | BuiltinType::U32 | BuiltinType::S8 | BuiltinType::S16 - | BuiltinType::S32 => TypePassedBy::Value(AtomType::I32), + | BuiltinType::S32 + | BuiltinType::Char8 => TypePassedBy::Value(AtomType::I32), BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs index cbae46bfb..fe9ea9844 100644 --- a/proposals/clocks/tools/witx/src/docs.rs +++ b/proposals/clocks/tools/witx/src/docs.rs @@ -25,6 +25,7 @@ impl BuiltinType { pub fn type_name(&self) -> &'static str { match self { BuiltinType::String => "string", + BuiltinType::Char8 => "char8", BuiltinType::U8 => "u8", BuiltinType::U16 => "u16", BuiltinType::U32 => "u32", diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index 506cec038..1a445a1b1 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -170,7 +170,9 @@ impl Layout for BuiltinType { fn mem_size_align(&self) -> SizeAlign { match self { BuiltinType::String => SizeAlign { size: 8, align: 4 }, // Pointer and Length - BuiltinType::U8 | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, + BuiltinType::U8 | BuiltinType::S8 | BuiltinType::Char8 => { + SizeAlign { size: 1, align: 1 } + } BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { SizeAlign { size: 4, align: 4 } diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 059a7b6ba..e0e4d5bf8 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -19,6 +19,7 @@ mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; wast::custom_keyword!(array); + wast::custom_keyword!(char8); wast::custom_keyword!(const_pointer); wast::custom_keyword!(f32); wast::custom_keyword!(f64); @@ -48,6 +49,9 @@ impl Parse<'_> for BuiltinType { if l.peek::() { parser.parse::()?; Ok(BuiltinType::String) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::Char8) } else if l.peek::() { parser.parse::()?; Ok(BuiltinType::U8) @@ -87,6 +91,7 @@ impl Parse<'_> for BuiltinType { impl wast::parser::Peek for BuiltinType { fn peek(cursor: wast::parser::Cursor<'_>) -> bool { ::peek(cursor) + || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index fadc70310..e7e4bb16c 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -78,6 +78,7 @@ impl BuiltinType { pub fn to_sexpr(&self) -> SExpr { match self { BuiltinType::String => SExpr::word("string"), + BuiltinType::Char8 => SExpr::word("char8"), BuiltinType::U8 => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), BuiltinType::U32 => SExpr::word("u32"), From 2c069c05045e9bfe0f33572ae376eb3018a59e76 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 16 Dec 2019 06:11:56 -0800 Subject: [PATCH 0404/1772] Add a char8 type to represent data which is expected to be valid UTF-8. This will allow the generated C header file to use [char8_t]. [char8_t]: https://en.cppreference.com/w/cpp/keyword/char8_t Fixes #6. --- .../random/phases/ephemeral/witx/wasi_ephemeral_args.witx | 4 ++-- .../random/phases/ephemeral/witx/wasi_ephemeral_environ.witx | 4 ++-- .../random/phases/ephemeral/witx/wasi_ephemeral_fd.witx | 2 +- .../random/phases/ephemeral/witx/wasi_ephemeral_path.witx | 2 +- .../random/phases/ephemeral/witx/wasi_ephemeral_random.witx | 2 +- proposals/random/tools/witx/src/ast.rs | 1 + proposals/random/tools/witx/src/coretypes.rs | 3 ++- proposals/random/tools/witx/src/docs.rs | 1 + proposals/random/tools/witx/src/layout.rs | 4 +++- proposals/random/tools/witx/src/parser.rs | 5 +++++ proposals/random/tools/witx/src/render.rs | 1 + 11 files changed, 20 insertions(+), 9 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx index 2c2d32d67..485fafd27 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -12,8 +12,8 @@ ;;; Read command-line argument data. ;;; The size of the array should match that returned by `sizes_get` (@interface func (export "get") - (param $argv (@witx pointer (@witx pointer u8))) - (param $argv_buf (@witx pointer u8)) + (param $argv (@witx pointer (@witx pointer char8))) + (param $argv_buf (@witx pointer char8)) (result $error $errno) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx index 5bc9c5a6f..2adcb2874 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -12,8 +12,8 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `sizes_get`. (@interface func (export "get") - (param $environ (@witx pointer (@witx pointer u8))) - (param $environ_buf (@witx pointer u8)) + (param $environ (@witx pointer (@witx pointer char8))) + (param $environ_buf (@witx pointer char8)) (result $error $errno) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx index 9fbad9ab7..d7d88c7b0 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -132,7 +132,7 @@ (@interface func (export "prestat_dir_name") (param $fd $fd) ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer u8)) + (param $path (@witx pointer char8)) (param $path_len $size) (result $error $errno) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx index 16c974692..e700a482b 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -106,7 +106,7 @@ ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer u8)) + (param $buf (@witx pointer char8)) (param $buf_len $size) (result $error $errno) ;;; The number of bytes placed in the buffer. diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx index 55c6df021..e68d50c91 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx @@ -19,7 +19,7 @@ ;;; number generator, rather than to provide the random data directly. (@interface func (export "get") ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) + (param $buf (@witx pointer char8)) (param $buf_len $size) (result $error $errno) ) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 224a614c6..2c9f4c65e 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -172,6 +172,7 @@ impl Type { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { String, + Char8, U8, U16, U32, diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index d772b3f54..47ef6908b 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -41,7 +41,8 @@ impl Type { | BuiltinType::U32 | BuiltinType::S8 | BuiltinType::S16 - | BuiltinType::S32 => TypePassedBy::Value(AtomType::I32), + | BuiltinType::S32 + | BuiltinType::Char8 => TypePassedBy::Value(AtomType::I32), BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs index cbae46bfb..fe9ea9844 100644 --- a/proposals/random/tools/witx/src/docs.rs +++ b/proposals/random/tools/witx/src/docs.rs @@ -25,6 +25,7 @@ impl BuiltinType { pub fn type_name(&self) -> &'static str { match self { BuiltinType::String => "string", + BuiltinType::Char8 => "char8", BuiltinType::U8 => "u8", BuiltinType::U16 => "u16", BuiltinType::U32 => "u32", diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index 506cec038..1a445a1b1 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -170,7 +170,9 @@ impl Layout for BuiltinType { fn mem_size_align(&self) -> SizeAlign { match self { BuiltinType::String => SizeAlign { size: 8, align: 4 }, // Pointer and Length - BuiltinType::U8 | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, + BuiltinType::U8 | BuiltinType::S8 | BuiltinType::Char8 => { + SizeAlign { size: 1, align: 1 } + } BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { SizeAlign { size: 4, align: 4 } diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 059a7b6ba..e0e4d5bf8 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -19,6 +19,7 @@ mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; wast::custom_keyword!(array); + wast::custom_keyword!(char8); wast::custom_keyword!(const_pointer); wast::custom_keyword!(f32); wast::custom_keyword!(f64); @@ -48,6 +49,9 @@ impl Parse<'_> for BuiltinType { if l.peek::() { parser.parse::()?; Ok(BuiltinType::String) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::Char8) } else if l.peek::() { parser.parse::()?; Ok(BuiltinType::U8) @@ -87,6 +91,7 @@ impl Parse<'_> for BuiltinType { impl wast::parser::Peek for BuiltinType { fn peek(cursor: wast::parser::Cursor<'_>) -> bool { ::peek(cursor) + || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index fadc70310..e7e4bb16c 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -78,6 +78,7 @@ impl BuiltinType { pub fn to_sexpr(&self) -> SExpr { match self { BuiltinType::String => SExpr::word("string"), + BuiltinType::Char8 => SExpr::word("char8"), BuiltinType::U8 => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), BuiltinType::U32 => SExpr::word("u32"), From 13f1917bcb39289b47a11cc96209cd920a6e140f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 16 Dec 2019 06:11:56 -0800 Subject: [PATCH 0405/1772] Add a char8 type to represent data which is expected to be valid UTF-8. This will allow the generated C header file to use [char8_t]. [char8_t]: https://en.cppreference.com/w/cpp/keyword/char8_t Fixes #6. --- .../phases/ephemeral/witx/wasi_ephemeral_args.witx | 4 ++-- .../phases/ephemeral/witx/wasi_ephemeral_environ.witx | 4 ++-- .../filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx | 2 +- .../phases/ephemeral/witx/wasi_ephemeral_path.witx | 2 +- .../phases/ephemeral/witx/wasi_ephemeral_random.witx | 2 +- proposals/filesystem/tools/witx/src/ast.rs | 1 + proposals/filesystem/tools/witx/src/coretypes.rs | 3 ++- proposals/filesystem/tools/witx/src/docs.rs | 1 + proposals/filesystem/tools/witx/src/layout.rs | 4 +++- proposals/filesystem/tools/witx/src/parser.rs | 5 +++++ proposals/filesystem/tools/witx/src/render.rs | 1 + 11 files changed, 20 insertions(+), 9 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx index 2c2d32d67..485fafd27 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -12,8 +12,8 @@ ;;; Read command-line argument data. ;;; The size of the array should match that returned by `sizes_get` (@interface func (export "get") - (param $argv (@witx pointer (@witx pointer u8))) - (param $argv_buf (@witx pointer u8)) + (param $argv (@witx pointer (@witx pointer char8))) + (param $argv_buf (@witx pointer char8)) (result $error $errno) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx index 5bc9c5a6f..2adcb2874 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -12,8 +12,8 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `sizes_get`. (@interface func (export "get") - (param $environ (@witx pointer (@witx pointer u8))) - (param $environ_buf (@witx pointer u8)) + (param $environ (@witx pointer (@witx pointer char8))) + (param $environ_buf (@witx pointer char8)) (result $error $errno) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx index 9fbad9ab7..d7d88c7b0 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -132,7 +132,7 @@ (@interface func (export "prestat_dir_name") (param $fd $fd) ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer u8)) + (param $path (@witx pointer char8)) (param $path_len $size) (result $error $errno) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx index 16c974692..e700a482b 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -106,7 +106,7 @@ ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer u8)) + (param $buf (@witx pointer char8)) (param $buf_len $size) (result $error $errno) ;;; The number of bytes placed in the buffer. diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx index 55c6df021..e68d50c91 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx @@ -19,7 +19,7 @@ ;;; number generator, rather than to provide the random data directly. (@interface func (export "get") ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) + (param $buf (@witx pointer char8)) (param $buf_len $size) (result $error $errno) ) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 224a614c6..2c9f4c65e 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -172,6 +172,7 @@ impl Type { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { String, + Char8, U8, U16, U32, diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index d772b3f54..47ef6908b 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -41,7 +41,8 @@ impl Type { | BuiltinType::U32 | BuiltinType::S8 | BuiltinType::S16 - | BuiltinType::S32 => TypePassedBy::Value(AtomType::I32), + | BuiltinType::S32 + | BuiltinType::Char8 => TypePassedBy::Value(AtomType::I32), BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs index cbae46bfb..fe9ea9844 100644 --- a/proposals/filesystem/tools/witx/src/docs.rs +++ b/proposals/filesystem/tools/witx/src/docs.rs @@ -25,6 +25,7 @@ impl BuiltinType { pub fn type_name(&self) -> &'static str { match self { BuiltinType::String => "string", + BuiltinType::Char8 => "char8", BuiltinType::U8 => "u8", BuiltinType::U16 => "u16", BuiltinType::U32 => "u32", diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index 506cec038..1a445a1b1 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -170,7 +170,9 @@ impl Layout for BuiltinType { fn mem_size_align(&self) -> SizeAlign { match self { BuiltinType::String => SizeAlign { size: 8, align: 4 }, // Pointer and Length - BuiltinType::U8 | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, + BuiltinType::U8 | BuiltinType::S8 | BuiltinType::Char8 => { + SizeAlign { size: 1, align: 1 } + } BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { SizeAlign { size: 4, align: 4 } diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 059a7b6ba..e0e4d5bf8 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -19,6 +19,7 @@ mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; wast::custom_keyword!(array); + wast::custom_keyword!(char8); wast::custom_keyword!(const_pointer); wast::custom_keyword!(f32); wast::custom_keyword!(f64); @@ -48,6 +49,9 @@ impl Parse<'_> for BuiltinType { if l.peek::() { parser.parse::()?; Ok(BuiltinType::String) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::Char8) } else if l.peek::() { parser.parse::()?; Ok(BuiltinType::U8) @@ -87,6 +91,7 @@ impl Parse<'_> for BuiltinType { impl wast::parser::Peek for BuiltinType { fn peek(cursor: wast::parser::Cursor<'_>) -> bool { ::peek(cursor) + || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index fadc70310..e7e4bb16c 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -78,6 +78,7 @@ impl BuiltinType { pub fn to_sexpr(&self) -> SExpr { match self { BuiltinType::String => SExpr::word("string"), + BuiltinType::Char8 => SExpr::word("char8"), BuiltinType::U8 => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), BuiltinType::U32 => SExpr::word("u32"), From 8e3c8e38d2a6cf326387e61c5bc00fb5c8addbe6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 16 Dec 2019 06:12:11 -0800 Subject: [PATCH 0406/1772] Add a noreturn keyword to annotate functions expected to not return. This will allow us to automatically add `_Noreturn` to `proc_exit` in C, and `-> !` in Rust, rather than special-casing it. --- .../ephemeral/witx/wasi_ephemeral_proc.witx | 1 + proposals/clocks/tools/witx/src/ast.rs | 1 + proposals/clocks/tools/witx/src/parser.rs | 22 ++++++++++++++++++- proposals/clocks/tools/witx/src/render.rs | 10 ++++++++- proposals/clocks/tools/witx/src/validate.rs | 2 ++ 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx index 5e53a83ec..0507d4ff7 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx @@ -14,5 +14,6 @@ (@interface func (export "exit") ;;; The exit code returned by the process. (param $rval $exitcode) + (@witx noreturn) ) ) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 2c9f4c65e..a3844a3d6 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -362,6 +362,7 @@ pub struct InterfaceFunc { pub name: Id, pub params: Vec, pub results: Vec, + pub noreturn: bool, pub docs: String, } diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index e0e4d5bf8..1cfcba79d 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -26,6 +26,7 @@ mod kw { wast::custom_keyword!(field); wast::custom_keyword!(flags); wast::custom_keyword!(handle); + wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); wast::custom_keyword!(r#enum = "enum"); wast::custom_keyword!(r#struct = "struct"); @@ -549,6 +550,7 @@ pub struct InterfaceFuncSyntax<'a> { pub export_loc: wast::Span, pub params: Vec>>, pub results: Vec>>, + pub noreturn: bool, } impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { @@ -563,6 +565,7 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { let mut params = Vec::new(); let mut results = Vec::new(); + let mut noreturn = false; while !parser.is_empty() { let func_field = parser.parse::>()?; @@ -579,6 +582,9 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { item, }); } + InterfaceFuncField::Noreturn => { + noreturn = true; + } } } @@ -587,6 +593,7 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { export_loc, params, results, + noreturn, }) } } @@ -594,6 +601,7 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { enum InterfaceFuncField<'a> { Param(FieldSyntax<'a>), Result(FieldSyntax<'a>), + Noreturn, } impl<'a> Parse<'a> for InterfaceFuncField<'a> { fn parse(parser: Parser<'a>) -> Result { @@ -611,6 +619,15 @@ impl<'a> Parse<'a> for InterfaceFuncField<'a> { name: parser.parse()?, type_: parser.parse()?, })) + } else if l.peek::() { + parser.parse::()?; + let mut l = parser.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(InterfaceFuncField::Noreturn) + } else { + Err(l.error()) + } } else { Err(l.error()) } @@ -621,7 +638,10 @@ impl<'a> Parse<'a> for InterfaceFuncField<'a> { impl PartialEq for InterfaceFuncSyntax<'_> { fn eq(&self, other: &InterfaceFuncSyntax<'_>) -> bool { // skip the `export_loc` field - self.export == other.export && self.params == other.params && self.results == other.results + self.export == other.export + && self.params == other.params + && self.results == other.results + && self.noreturn == other.noreturn } } diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index e7e4bb16c..9e715eef1 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -290,6 +290,14 @@ impl InterfaceFunc { ) }) .collect(); - SExpr::docs(&self.docs, SExpr::Vec([header, params, results].concat())) + let attrs = if self.noreturn { + vec![SExpr::annot("witx"), SExpr::word("noreturn")] + } else { + vec![] + }; + SExpr::docs( + &self.docs, + SExpr::Vec([header, params, results, attrs].concat()), + ) } } diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index a8d832056..2c246bca2 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -466,11 +466,13 @@ impl<'a> ModuleValidation<'a> { }) }) .collect::, _>>()?; + let noreturn = syntax.noreturn; let rc_func = Rc::new(InterfaceFunc { name: name.clone(), params, results, + noreturn, docs: decl.comments.docs(), }); self.entries From ecbbdaf15d4825c6775da66385a32b8d513ec478 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 16 Dec 2019 06:12:11 -0800 Subject: [PATCH 0407/1772] Add a noreturn keyword to annotate functions expected to not return. This will allow us to automatically add `_Noreturn` to `proc_exit` in C, and `-> !` in Rust, rather than special-casing it. --- .../ephemeral/witx/wasi_ephemeral_proc.witx | 1 + proposals/random/tools/witx/src/ast.rs | 1 + proposals/random/tools/witx/src/parser.rs | 22 ++++++++++++++++++- proposals/random/tools/witx/src/render.rs | 10 ++++++++- proposals/random/tools/witx/src/validate.rs | 2 ++ 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx index 5e53a83ec..0507d4ff7 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx @@ -14,5 +14,6 @@ (@interface func (export "exit") ;;; The exit code returned by the process. (param $rval $exitcode) + (@witx noreturn) ) ) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 2c9f4c65e..a3844a3d6 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -362,6 +362,7 @@ pub struct InterfaceFunc { pub name: Id, pub params: Vec, pub results: Vec, + pub noreturn: bool, pub docs: String, } diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index e0e4d5bf8..1cfcba79d 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -26,6 +26,7 @@ mod kw { wast::custom_keyword!(field); wast::custom_keyword!(flags); wast::custom_keyword!(handle); + wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); wast::custom_keyword!(r#enum = "enum"); wast::custom_keyword!(r#struct = "struct"); @@ -549,6 +550,7 @@ pub struct InterfaceFuncSyntax<'a> { pub export_loc: wast::Span, pub params: Vec>>, pub results: Vec>>, + pub noreturn: bool, } impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { @@ -563,6 +565,7 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { let mut params = Vec::new(); let mut results = Vec::new(); + let mut noreturn = false; while !parser.is_empty() { let func_field = parser.parse::>()?; @@ -579,6 +582,9 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { item, }); } + InterfaceFuncField::Noreturn => { + noreturn = true; + } } } @@ -587,6 +593,7 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { export_loc, params, results, + noreturn, }) } } @@ -594,6 +601,7 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { enum InterfaceFuncField<'a> { Param(FieldSyntax<'a>), Result(FieldSyntax<'a>), + Noreturn, } impl<'a> Parse<'a> for InterfaceFuncField<'a> { fn parse(parser: Parser<'a>) -> Result { @@ -611,6 +619,15 @@ impl<'a> Parse<'a> for InterfaceFuncField<'a> { name: parser.parse()?, type_: parser.parse()?, })) + } else if l.peek::() { + parser.parse::()?; + let mut l = parser.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(InterfaceFuncField::Noreturn) + } else { + Err(l.error()) + } } else { Err(l.error()) } @@ -621,7 +638,10 @@ impl<'a> Parse<'a> for InterfaceFuncField<'a> { impl PartialEq for InterfaceFuncSyntax<'_> { fn eq(&self, other: &InterfaceFuncSyntax<'_>) -> bool { // skip the `export_loc` field - self.export == other.export && self.params == other.params && self.results == other.results + self.export == other.export + && self.params == other.params + && self.results == other.results + && self.noreturn == other.noreturn } } diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index e7e4bb16c..9e715eef1 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -290,6 +290,14 @@ impl InterfaceFunc { ) }) .collect(); - SExpr::docs(&self.docs, SExpr::Vec([header, params, results].concat())) + let attrs = if self.noreturn { + vec![SExpr::annot("witx"), SExpr::word("noreturn")] + } else { + vec![] + }; + SExpr::docs( + &self.docs, + SExpr::Vec([header, params, results, attrs].concat()), + ) } } diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index a8d832056..2c246bca2 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -466,11 +466,13 @@ impl<'a> ModuleValidation<'a> { }) }) .collect::, _>>()?; + let noreturn = syntax.noreturn; let rc_func = Rc::new(InterfaceFunc { name: name.clone(), params, results, + noreturn, docs: decl.comments.docs(), }); self.entries From bbcd01d644aade16fdd28259530dab53681e393b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 16 Dec 2019 06:12:11 -0800 Subject: [PATCH 0408/1772] Add a noreturn keyword to annotate functions expected to not return. This will allow us to automatically add `_Noreturn` to `proc_exit` in C, and `-> !` in Rust, rather than special-casing it. --- .../ephemeral/witx/wasi_ephemeral_proc.witx | 1 + proposals/filesystem/tools/witx/src/ast.rs | 1 + proposals/filesystem/tools/witx/src/parser.rs | 22 ++++++++++++++++++- proposals/filesystem/tools/witx/src/render.rs | 10 ++++++++- .../filesystem/tools/witx/src/validate.rs | 2 ++ 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx index 5e53a83ec..0507d4ff7 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx @@ -14,5 +14,6 @@ (@interface func (export "exit") ;;; The exit code returned by the process. (param $rval $exitcode) + (@witx noreturn) ) ) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 2c9f4c65e..a3844a3d6 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -362,6 +362,7 @@ pub struct InterfaceFunc { pub name: Id, pub params: Vec, pub results: Vec, + pub noreturn: bool, pub docs: String, } diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index e0e4d5bf8..1cfcba79d 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -26,6 +26,7 @@ mod kw { wast::custom_keyword!(field); wast::custom_keyword!(flags); wast::custom_keyword!(handle); + wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); wast::custom_keyword!(r#enum = "enum"); wast::custom_keyword!(r#struct = "struct"); @@ -549,6 +550,7 @@ pub struct InterfaceFuncSyntax<'a> { pub export_loc: wast::Span, pub params: Vec>>, pub results: Vec>>, + pub noreturn: bool, } impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { @@ -563,6 +565,7 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { let mut params = Vec::new(); let mut results = Vec::new(); + let mut noreturn = false; while !parser.is_empty() { let func_field = parser.parse::>()?; @@ -579,6 +582,9 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { item, }); } + InterfaceFuncField::Noreturn => { + noreturn = true; + } } } @@ -587,6 +593,7 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { export_loc, params, results, + noreturn, }) } } @@ -594,6 +601,7 @@ impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { enum InterfaceFuncField<'a> { Param(FieldSyntax<'a>), Result(FieldSyntax<'a>), + Noreturn, } impl<'a> Parse<'a> for InterfaceFuncField<'a> { fn parse(parser: Parser<'a>) -> Result { @@ -611,6 +619,15 @@ impl<'a> Parse<'a> for InterfaceFuncField<'a> { name: parser.parse()?, type_: parser.parse()?, })) + } else if l.peek::() { + parser.parse::()?; + let mut l = parser.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(InterfaceFuncField::Noreturn) + } else { + Err(l.error()) + } } else { Err(l.error()) } @@ -621,7 +638,10 @@ impl<'a> Parse<'a> for InterfaceFuncField<'a> { impl PartialEq for InterfaceFuncSyntax<'_> { fn eq(&self, other: &InterfaceFuncSyntax<'_>) -> bool { // skip the `export_loc` field - self.export == other.export && self.params == other.params && self.results == other.results + self.export == other.export + && self.params == other.params + && self.results == other.results + && self.noreturn == other.noreturn } } diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index e7e4bb16c..9e715eef1 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -290,6 +290,14 @@ impl InterfaceFunc { ) }) .collect(); - SExpr::docs(&self.docs, SExpr::Vec([header, params, results].concat())) + let attrs = if self.noreturn { + vec![SExpr::annot("witx"), SExpr::word("noreturn")] + } else { + vec![] + }; + SExpr::docs( + &self.docs, + SExpr::Vec([header, params, results, attrs].concat()), + ) } } diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index a8d832056..2c246bca2 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -466,11 +466,13 @@ impl<'a> ModuleValidation<'a> { }) }) .collect::, _>>()?; + let noreturn = syntax.noreturn; let rc_func = Rc::new(InterfaceFunc { name: name.clone(), params, results, + noreturn, docs: decl.comments.docs(), }); self.entries From db8236c2408ad306872016b23eb79b75023bed37 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 16 Dec 2019 06:11:07 -0800 Subject: [PATCH 0409/1772] Add a `usize` type to indicate types which will change size on wasm64. This will allow code generators to know which types are sensitive to wasm32 vs wasm64 without special-casing the `size` type. --- proposals/clocks/phases/ephemeral/witx/typenames.witx | 2 +- proposals/clocks/tools/witx/src/ast.rs | 2 ++ proposals/clocks/tools/witx/src/coretypes.rs | 4 +++- proposals/clocks/tools/witx/src/docs.rs | 2 ++ proposals/clocks/tools/witx/src/layout.rs | 4 +++- proposals/clocks/tools/witx/src/parser.rs | 5 +++++ proposals/clocks/tools/witx/src/render.rs | 1 + proposals/clocks/tools/witx/src/validate.rs | 1 + 8 files changed, 18 insertions(+), 3 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 904aa1ca9..048c4b2e1 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -5,7 +5,7 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(typename $size u32) +(typename $size (@witx usize)) ;;; Non-negative file size or length of a region within a file. (typename $filesize u64) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index a3844a3d6..56a550dff 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -149,6 +149,7 @@ pub enum Type { Array(TypeRef), Pointer(TypeRef), ConstPointer(TypeRef), + USize, Builtin(BuiltinType), } @@ -164,6 +165,7 @@ impl Type { Array(_) => "array", Pointer(_) => "pointer", ConstPointer(_) => "constpointer", + USize => "usize", Builtin(_) => "builtin", } } diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index 47ef6908b..cedf652fa 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -48,7 +48,9 @@ impl Type { BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), }, Type::Array { .. } => TypePassedBy::PointerLengthPair, - Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), + Type::Pointer { .. } | Type::ConstPointer { .. } | Type::USize => { + TypePassedBy::Value(AtomType::I32) + } Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), Type::Struct { .. } | Type::Union { .. } => TypePassedBy::Pointer, diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs index fe9ea9844..b795a4f0c 100644 --- a/proposals/clocks/tools/witx/src/docs.rs +++ b/proposals/clocks/tools/witx/src/docs.rs @@ -52,6 +52,7 @@ impl Documentation for NamedType { Type::Array(a) => format!("Array of {}", a.type_name()), Type::Pointer(a) => format!("Pointer to {}", a.type_name()), Type::ConstPointer(a) => format!("Constant Pointer to {}", a.type_name()), + Type::USize => format!("USize"), Type::Builtin(a) => format!("Builtin type {}", a.type_name()), }, TypeRef::Name(n) => format!("Alias to {}", n.name.as_str()), @@ -68,6 +69,7 @@ impl TypeRef { Type::Array(a) => format!("Array<{}>", a.type_name()), Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), + Type::USize => format!("USize"), Type::Builtin(b) => b.type_name().to_string(), Type::Enum { .. } | Type::Flags { .. } diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index 1a445a1b1..2460ddde7 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -29,7 +29,9 @@ impl TypeRef { Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::Array { .. } => BuiltinType::String.mem_size_align(), - Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), + Type::Pointer { .. } | Type::ConstPointer { .. } | Type::USize => { + BuiltinType::U32.mem_size_align() + } Type::Builtin(b) => b.mem_size_align(), }; cache.insert(self.clone(), layout); diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 1cfcba79d..7a15f469d 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -42,6 +42,7 @@ mod kw { wast::custom_keyword!(u32); wast::custom_keyword!(u64); wast::custom_keyword!(u8); + wast::custom_keyword!(usize); } impl Parse<'_> for BuiltinType { @@ -312,6 +313,7 @@ pub enum TypedefSyntax<'a> { Array(Box>), Pointer(Box>), ConstPointer(Box>), + USize, Builtin(BuiltinType), Ident(wast::Id<'a>), } @@ -348,6 +350,9 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { } else if l.peek::() { parser.parse::()?; Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::USize) } else { Err(l.error()) } diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 9e715eef1..e35f563f2 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -131,6 +131,7 @@ impl Type { SExpr::word("const_pointer"), p.to_sexpr(), ]), + Type::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), Type::Builtin(b) => b.to_sexpr(), } } diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 2c246bca2..340ed058f 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -236,6 +236,7 @@ impl DocValidationScope<'_> { TypedefSyntax::ConstPointer(syntax) => { Type::ConstPointer(self.validate_datatype(syntax, span)?) } + TypedefSyntax::USize => Type::USize, TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), TypedefSyntax::Ident { .. } => unreachable!(), }))), From e3f7b55a78ab599e597e29b191e3ad072092226a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 16 Dec 2019 06:11:07 -0800 Subject: [PATCH 0410/1772] Add a `usize` type to indicate types which will change size on wasm64. This will allow code generators to know which types are sensitive to wasm32 vs wasm64 without special-casing the `size` type. --- proposals/random/phases/ephemeral/witx/typenames.witx | 2 +- proposals/random/tools/witx/src/ast.rs | 2 ++ proposals/random/tools/witx/src/coretypes.rs | 4 +++- proposals/random/tools/witx/src/docs.rs | 2 ++ proposals/random/tools/witx/src/layout.rs | 4 +++- proposals/random/tools/witx/src/parser.rs | 5 +++++ proposals/random/tools/witx/src/render.rs | 1 + proposals/random/tools/witx/src/validate.rs | 1 + 8 files changed, 18 insertions(+), 3 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 904aa1ca9..048c4b2e1 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -5,7 +5,7 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(typename $size u32) +(typename $size (@witx usize)) ;;; Non-negative file size or length of a region within a file. (typename $filesize u64) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index a3844a3d6..56a550dff 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -149,6 +149,7 @@ pub enum Type { Array(TypeRef), Pointer(TypeRef), ConstPointer(TypeRef), + USize, Builtin(BuiltinType), } @@ -164,6 +165,7 @@ impl Type { Array(_) => "array", Pointer(_) => "pointer", ConstPointer(_) => "constpointer", + USize => "usize", Builtin(_) => "builtin", } } diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index 47ef6908b..cedf652fa 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -48,7 +48,9 @@ impl Type { BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), }, Type::Array { .. } => TypePassedBy::PointerLengthPair, - Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), + Type::Pointer { .. } | Type::ConstPointer { .. } | Type::USize => { + TypePassedBy::Value(AtomType::I32) + } Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), Type::Struct { .. } | Type::Union { .. } => TypePassedBy::Pointer, diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs index fe9ea9844..b795a4f0c 100644 --- a/proposals/random/tools/witx/src/docs.rs +++ b/proposals/random/tools/witx/src/docs.rs @@ -52,6 +52,7 @@ impl Documentation for NamedType { Type::Array(a) => format!("Array of {}", a.type_name()), Type::Pointer(a) => format!("Pointer to {}", a.type_name()), Type::ConstPointer(a) => format!("Constant Pointer to {}", a.type_name()), + Type::USize => format!("USize"), Type::Builtin(a) => format!("Builtin type {}", a.type_name()), }, TypeRef::Name(n) => format!("Alias to {}", n.name.as_str()), @@ -68,6 +69,7 @@ impl TypeRef { Type::Array(a) => format!("Array<{}>", a.type_name()), Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), + Type::USize => format!("USize"), Type::Builtin(b) => b.type_name().to_string(), Type::Enum { .. } | Type::Flags { .. } diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index 1a445a1b1..2460ddde7 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -29,7 +29,9 @@ impl TypeRef { Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::Array { .. } => BuiltinType::String.mem_size_align(), - Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), + Type::Pointer { .. } | Type::ConstPointer { .. } | Type::USize => { + BuiltinType::U32.mem_size_align() + } Type::Builtin(b) => b.mem_size_align(), }; cache.insert(self.clone(), layout); diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 1cfcba79d..7a15f469d 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -42,6 +42,7 @@ mod kw { wast::custom_keyword!(u32); wast::custom_keyword!(u64); wast::custom_keyword!(u8); + wast::custom_keyword!(usize); } impl Parse<'_> for BuiltinType { @@ -312,6 +313,7 @@ pub enum TypedefSyntax<'a> { Array(Box>), Pointer(Box>), ConstPointer(Box>), + USize, Builtin(BuiltinType), Ident(wast::Id<'a>), } @@ -348,6 +350,9 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { } else if l.peek::() { parser.parse::()?; Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::USize) } else { Err(l.error()) } diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 9e715eef1..e35f563f2 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -131,6 +131,7 @@ impl Type { SExpr::word("const_pointer"), p.to_sexpr(), ]), + Type::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), Type::Builtin(b) => b.to_sexpr(), } } diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 2c246bca2..340ed058f 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -236,6 +236,7 @@ impl DocValidationScope<'_> { TypedefSyntax::ConstPointer(syntax) => { Type::ConstPointer(self.validate_datatype(syntax, span)?) } + TypedefSyntax::USize => Type::USize, TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), TypedefSyntax::Ident { .. } => unreachable!(), }))), From 6ae48ea8debe52d4f1c131c066621b7df311657b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 16 Dec 2019 06:11:07 -0800 Subject: [PATCH 0411/1772] Add a `usize` type to indicate types which will change size on wasm64. This will allow code generators to know which types are sensitive to wasm32 vs wasm64 without special-casing the `size` type. --- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 2 +- proposals/filesystem/tools/witx/src/ast.rs | 2 ++ proposals/filesystem/tools/witx/src/coretypes.rs | 4 +++- proposals/filesystem/tools/witx/src/docs.rs | 2 ++ proposals/filesystem/tools/witx/src/layout.rs | 4 +++- proposals/filesystem/tools/witx/src/parser.rs | 5 +++++ proposals/filesystem/tools/witx/src/render.rs | 1 + proposals/filesystem/tools/witx/src/validate.rs | 1 + 8 files changed, 18 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 904aa1ca9..048c4b2e1 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -5,7 +5,7 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. -(typename $size u32) +(typename $size (@witx usize)) ;;; Non-negative file size or length of a region within a file. (typename $filesize u64) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index a3844a3d6..56a550dff 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -149,6 +149,7 @@ pub enum Type { Array(TypeRef), Pointer(TypeRef), ConstPointer(TypeRef), + USize, Builtin(BuiltinType), } @@ -164,6 +165,7 @@ impl Type { Array(_) => "array", Pointer(_) => "pointer", ConstPointer(_) => "constpointer", + USize => "usize", Builtin(_) => "builtin", } } diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index 47ef6908b..cedf652fa 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -48,7 +48,9 @@ impl Type { BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), }, Type::Array { .. } => TypePassedBy::PointerLengthPair, - Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), + Type::Pointer { .. } | Type::ConstPointer { .. } | Type::USize => { + TypePassedBy::Value(AtomType::I32) + } Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), Type::Struct { .. } | Type::Union { .. } => TypePassedBy::Pointer, diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs index fe9ea9844..b795a4f0c 100644 --- a/proposals/filesystem/tools/witx/src/docs.rs +++ b/proposals/filesystem/tools/witx/src/docs.rs @@ -52,6 +52,7 @@ impl Documentation for NamedType { Type::Array(a) => format!("Array of {}", a.type_name()), Type::Pointer(a) => format!("Pointer to {}", a.type_name()), Type::ConstPointer(a) => format!("Constant Pointer to {}", a.type_name()), + Type::USize => format!("USize"), Type::Builtin(a) => format!("Builtin type {}", a.type_name()), }, TypeRef::Name(n) => format!("Alias to {}", n.name.as_str()), @@ -68,6 +69,7 @@ impl TypeRef { Type::Array(a) => format!("Array<{}>", a.type_name()), Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), + Type::USize => format!("USize"), Type::Builtin(b) => b.type_name().to_string(), Type::Enum { .. } | Type::Flags { .. } diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index 1a445a1b1..2460ddde7 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -29,7 +29,9 @@ impl TypeRef { Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::Array { .. } => BuiltinType::String.mem_size_align(), - Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), + Type::Pointer { .. } | Type::ConstPointer { .. } | Type::USize => { + BuiltinType::U32.mem_size_align() + } Type::Builtin(b) => b.mem_size_align(), }; cache.insert(self.clone(), layout); diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 1cfcba79d..7a15f469d 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -42,6 +42,7 @@ mod kw { wast::custom_keyword!(u32); wast::custom_keyword!(u64); wast::custom_keyword!(u8); + wast::custom_keyword!(usize); } impl Parse<'_> for BuiltinType { @@ -312,6 +313,7 @@ pub enum TypedefSyntax<'a> { Array(Box>), Pointer(Box>), ConstPointer(Box>), + USize, Builtin(BuiltinType), Ident(wast::Id<'a>), } @@ -348,6 +350,9 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { } else if l.peek::() { parser.parse::()?; Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::USize) } else { Err(l.error()) } diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 9e715eef1..e35f563f2 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -131,6 +131,7 @@ impl Type { SExpr::word("const_pointer"), p.to_sexpr(), ]), + Type::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), Type::Builtin(b) => b.to_sexpr(), } } diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 2c246bca2..340ed058f 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -236,6 +236,7 @@ impl DocValidationScope<'_> { TypedefSyntax::ConstPointer(syntax) => { Type::ConstPointer(self.validate_datatype(syntax, span)?) } + TypedefSyntax::USize => Type::USize, TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), TypedefSyntax::Ident { .. } => unreachable!(), }))), From 0a743ea90b564db13dae7de779d1313ae59f08d8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 20 Dec 2019 20:46:56 -0800 Subject: [PATCH 0412/1772] Add functions for working with file permissions. (#170) * Add functions for working with file permissions. Add functions and types to query and set the filesystem permissions of a file: read, write, execute (for files), and search (for directories). These permissions aren't the only thing which determines whether a given file or directory can be accessed; hosts may impose additional arbitrary security restrictions not reflected here. WASI itself does not currently have the ability to execute files, so the meaning of "execute" here is entirely up to the host filesystem. These are similar to fchmod/fchmodat/fstat/fstatat in POSIX, though there are some differences: - This doesn't surface POSIX's setuid, setgid, or sticky bits. These can be added in the future if needed, though they'll require additional security and portability considerations. - This uses separate flags for "execute" on files vs "search" on directories. WASI libc can provide a POSIX-compatible C API. - This doesn't expose POSIX's user/group/other concepts. These can be added in the future if needed, though they'll require additional security and portability considerations. Implementations in POSIX environments should follow the umask when setting permissions flags. * Make $permissions a flags. * Put a permissions field in `filestat`. This is instead of dedicated `permissions_get` functions. * Fold the $search permission for directories into the $read permission. * Add a $private permission flag. --- .../phases/ephemeral/witx/typenames.witx | 37 +++++++++++++++++++ .../ephemeral/witx/wasi_ephemeral_fd.witx | 19 ++++++++++ .../ephemeral/witx/wasi_ephemeral_path.witx | 26 ++++++++++++- 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 048c4b2e1..b3e998228 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -253,12 +253,16 @@ $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. $path_filestat_set_times + ;;; The right to invoke `path_filestat_set_permissions`. + $path_permissions_set ;;; The right to invoke `fd_filestat_get`. $fd_filestat_get ;;; The right to invoke `fd_filestat_set_size`. $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. $fd_filestat_set_times + ;;; The right to invoke `fd_filestat_set_permissions`. + $fd_permissions_set ;;; The right to invoke `path_symlink`. $path_symlink ;;; The right to invoke `path_remove_directory`. @@ -455,6 +459,37 @@ ;;; Number of hard links to an inode. (typename $linkcount u64) +;;; File permissions. This represents the permissions associated with a +;;; file in a filesystem, and don't fully reflect all the conditions +;;; which determine whether a given WASI program can access the file. +(typename $permissions + (flags u8 + ;;; For files, permission to read the file. + ;;; For directories, permission to do `readdir` and access files + ;;; within the directory. + ;;; + ;;; Note: This is similar to the read bit being set on files, and the + ;;; read *and* execute bits being set on directories, in POSIX. + $read + + ;;; For files, permission to mutate the file. + ;;; For directories, permission to create, remove, and rename items + ;;; within the directory. + $write + + ;;; For files, permission to "execute" the file, using whatever + ;;; concept of "executing" the host filesystem has. + ;;; This flag is not valid for directories. + $execute + + ;;; For filesystems which have a concept of multiple "users", this flag + ;;; indicates that the file is only accessible by the effective "user" + ;;; that the WASI store uses to access the filesystem, and inaccessible + ;;; to other "users". + $private + ) +) + ;;; File attributes. (typename $filestat (struct @@ -464,6 +499,8 @@ (field $ino $inode) ;;; File type. (field $filetype $filetype) + ;;; File permissions. + (field $permissions $permissions) ;;; Number of hard links to the file. (field $nlink $linkcount) ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx index d7d88c7b0..abd5cf610 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -107,6 +107,25 @@ (result $error $errno) ) + ;;; Set the permissions of a file or directory. + ;;; + ;;; This sets the permissions associated with a file or directory in + ;;; a filesystem at the time it is called. The ability to actually access + ;;; a file or directory may depend on additional permissions not reflected + ;;; here. + ;;; + ;;; Note: This is similar `fchmod` in POSIX. + ;;; + ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; + ;;; implementations in POSIX environments are suggested to consult the + ;;; umask to determine which of the user/group/other flags to modify. + (@interface func (export "permissions_set") + (param $fd $fd) + ;;; The permissions associated with the file. + (result $permissions $permissions) + (result $error $errno) + ) + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "pread") diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx index e700a482b..dbd02dc1a 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -50,6 +50,29 @@ (result $error $errno) ) + ;;; Set the permissions of a file or directory. + ;;; + ;;; This sets the permissions associated with a file or directory in + ;;; a filesystem at the time it is called. The ability to actually access + ;;; a file or directory may depend on additional permissions not reflected + ;;; here. + ;;; + ;;; Note: This is similar to `fchmodat` in POSIX. + ;;; + ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; + ;;; implementations in POSIX environments are suggested to consult the + ;;; umask to determine which of the user/group/other flags to modify. + (@interface func (export "permissions_set") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags) + ;;; The path to a file to query. + (param $path string) + ;;; The permissions to associate with the file. + (param $permissions $permissions) + (result $error $errno) + ) + ;;; Create a hard link. ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "link") @@ -94,6 +117,8 @@ (param $fs_rights_base $rights) (param $fs_rights_inherting $rights) (param $fdflags $fdflags) + ;;; If a file is created, the filesystem permissions to associate with it. + (param $permissions $permissions) (result $error $errno) ;;; The file descriptor of the file that has been opened. (result $opened_fd $fd) @@ -147,7 +172,6 @@ (result $error $errno) ) - ;;; Unlink a file. ;;; Return `EISDIR` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. From 2c8f305e06161f5514a6c757b66cadc6137b301f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 20 Dec 2019 20:46:56 -0800 Subject: [PATCH 0413/1772] Add functions for working with file permissions. (#170) * Add functions for working with file permissions. Add functions and types to query and set the filesystem permissions of a file: read, write, execute (for files), and search (for directories). These permissions aren't the only thing which determines whether a given file or directory can be accessed; hosts may impose additional arbitrary security restrictions not reflected here. WASI itself does not currently have the ability to execute files, so the meaning of "execute" here is entirely up to the host filesystem. These are similar to fchmod/fchmodat/fstat/fstatat in POSIX, though there are some differences: - This doesn't surface POSIX's setuid, setgid, or sticky bits. These can be added in the future if needed, though they'll require additional security and portability considerations. - This uses separate flags for "execute" on files vs "search" on directories. WASI libc can provide a POSIX-compatible C API. - This doesn't expose POSIX's user/group/other concepts. These can be added in the future if needed, though they'll require additional security and portability considerations. Implementations in POSIX environments should follow the umask when setting permissions flags. * Make $permissions a flags. * Put a permissions field in `filestat`. This is instead of dedicated `permissions_get` functions. * Fold the $search permission for directories into the $read permission. * Add a $private permission flag. --- .../phases/ephemeral/witx/typenames.witx | 37 +++++++++++++++++++ .../ephemeral/witx/wasi_ephemeral_fd.witx | 19 ++++++++++ .../ephemeral/witx/wasi_ephemeral_path.witx | 26 ++++++++++++- 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 048c4b2e1..b3e998228 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -253,12 +253,16 @@ $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. $path_filestat_set_times + ;;; The right to invoke `path_filestat_set_permissions`. + $path_permissions_set ;;; The right to invoke `fd_filestat_get`. $fd_filestat_get ;;; The right to invoke `fd_filestat_set_size`. $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. $fd_filestat_set_times + ;;; The right to invoke `fd_filestat_set_permissions`. + $fd_permissions_set ;;; The right to invoke `path_symlink`. $path_symlink ;;; The right to invoke `path_remove_directory`. @@ -455,6 +459,37 @@ ;;; Number of hard links to an inode. (typename $linkcount u64) +;;; File permissions. This represents the permissions associated with a +;;; file in a filesystem, and don't fully reflect all the conditions +;;; which determine whether a given WASI program can access the file. +(typename $permissions + (flags u8 + ;;; For files, permission to read the file. + ;;; For directories, permission to do `readdir` and access files + ;;; within the directory. + ;;; + ;;; Note: This is similar to the read bit being set on files, and the + ;;; read *and* execute bits being set on directories, in POSIX. + $read + + ;;; For files, permission to mutate the file. + ;;; For directories, permission to create, remove, and rename items + ;;; within the directory. + $write + + ;;; For files, permission to "execute" the file, using whatever + ;;; concept of "executing" the host filesystem has. + ;;; This flag is not valid for directories. + $execute + + ;;; For filesystems which have a concept of multiple "users", this flag + ;;; indicates that the file is only accessible by the effective "user" + ;;; that the WASI store uses to access the filesystem, and inaccessible + ;;; to other "users". + $private + ) +) + ;;; File attributes. (typename $filestat (struct @@ -464,6 +499,8 @@ (field $ino $inode) ;;; File type. (field $filetype $filetype) + ;;; File permissions. + (field $permissions $permissions) ;;; Number of hard links to the file. (field $nlink $linkcount) ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx index d7d88c7b0..abd5cf610 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -107,6 +107,25 @@ (result $error $errno) ) + ;;; Set the permissions of a file or directory. + ;;; + ;;; This sets the permissions associated with a file or directory in + ;;; a filesystem at the time it is called. The ability to actually access + ;;; a file or directory may depend on additional permissions not reflected + ;;; here. + ;;; + ;;; Note: This is similar `fchmod` in POSIX. + ;;; + ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; + ;;; implementations in POSIX environments are suggested to consult the + ;;; umask to determine which of the user/group/other flags to modify. + (@interface func (export "permissions_set") + (param $fd $fd) + ;;; The permissions associated with the file. + (result $permissions $permissions) + (result $error $errno) + ) + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "pread") diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx index e700a482b..dbd02dc1a 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -50,6 +50,29 @@ (result $error $errno) ) + ;;; Set the permissions of a file or directory. + ;;; + ;;; This sets the permissions associated with a file or directory in + ;;; a filesystem at the time it is called. The ability to actually access + ;;; a file or directory may depend on additional permissions not reflected + ;;; here. + ;;; + ;;; Note: This is similar to `fchmodat` in POSIX. + ;;; + ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; + ;;; implementations in POSIX environments are suggested to consult the + ;;; umask to determine which of the user/group/other flags to modify. + (@interface func (export "permissions_set") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags) + ;;; The path to a file to query. + (param $path string) + ;;; The permissions to associate with the file. + (param $permissions $permissions) + (result $error $errno) + ) + ;;; Create a hard link. ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "link") @@ -94,6 +117,8 @@ (param $fs_rights_base $rights) (param $fs_rights_inherting $rights) (param $fdflags $fdflags) + ;;; If a file is created, the filesystem permissions to associate with it. + (param $permissions $permissions) (result $error $errno) ;;; The file descriptor of the file that has been opened. (result $opened_fd $fd) @@ -147,7 +172,6 @@ (result $error $errno) ) - ;;; Unlink a file. ;;; Return `EISDIR` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. From 846e333f3b3b600dc046f5eff0eab3f01801d099 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 20 Dec 2019 20:46:56 -0800 Subject: [PATCH 0414/1772] Add functions for working with file permissions. (#170) * Add functions for working with file permissions. Add functions and types to query and set the filesystem permissions of a file: read, write, execute (for files), and search (for directories). These permissions aren't the only thing which determines whether a given file or directory can be accessed; hosts may impose additional arbitrary security restrictions not reflected here. WASI itself does not currently have the ability to execute files, so the meaning of "execute" here is entirely up to the host filesystem. These are similar to fchmod/fchmodat/fstat/fstatat in POSIX, though there are some differences: - This doesn't surface POSIX's setuid, setgid, or sticky bits. These can be added in the future if needed, though they'll require additional security and portability considerations. - This uses separate flags for "execute" on files vs "search" on directories. WASI libc can provide a POSIX-compatible C API. - This doesn't expose POSIX's user/group/other concepts. These can be added in the future if needed, though they'll require additional security and portability considerations. Implementations in POSIX environments should follow the umask when setting permissions flags. * Make $permissions a flags. * Put a permissions field in `filestat`. This is instead of dedicated `permissions_get` functions. * Fold the $search permission for directories into the $read permission. * Add a $private permission flag. --- .../phases/ephemeral/witx/typenames.witx | 37 +++++++++++++++++++ .../ephemeral/witx/wasi_ephemeral_fd.witx | 19 ++++++++++ .../ephemeral/witx/wasi_ephemeral_path.witx | 26 ++++++++++++- 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 048c4b2e1..b3e998228 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -253,12 +253,16 @@ $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. $path_filestat_set_times + ;;; The right to invoke `path_filestat_set_permissions`. + $path_permissions_set ;;; The right to invoke `fd_filestat_get`. $fd_filestat_get ;;; The right to invoke `fd_filestat_set_size`. $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. $fd_filestat_set_times + ;;; The right to invoke `fd_filestat_set_permissions`. + $fd_permissions_set ;;; The right to invoke `path_symlink`. $path_symlink ;;; The right to invoke `path_remove_directory`. @@ -455,6 +459,37 @@ ;;; Number of hard links to an inode. (typename $linkcount u64) +;;; File permissions. This represents the permissions associated with a +;;; file in a filesystem, and don't fully reflect all the conditions +;;; which determine whether a given WASI program can access the file. +(typename $permissions + (flags u8 + ;;; For files, permission to read the file. + ;;; For directories, permission to do `readdir` and access files + ;;; within the directory. + ;;; + ;;; Note: This is similar to the read bit being set on files, and the + ;;; read *and* execute bits being set on directories, in POSIX. + $read + + ;;; For files, permission to mutate the file. + ;;; For directories, permission to create, remove, and rename items + ;;; within the directory. + $write + + ;;; For files, permission to "execute" the file, using whatever + ;;; concept of "executing" the host filesystem has. + ;;; This flag is not valid for directories. + $execute + + ;;; For filesystems which have a concept of multiple "users", this flag + ;;; indicates that the file is only accessible by the effective "user" + ;;; that the WASI store uses to access the filesystem, and inaccessible + ;;; to other "users". + $private + ) +) + ;;; File attributes. (typename $filestat (struct @@ -464,6 +499,8 @@ (field $ino $inode) ;;; File type. (field $filetype $filetype) + ;;; File permissions. + (field $permissions $permissions) ;;; Number of hard links to the file. (field $nlink $linkcount) ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx index d7d88c7b0..abd5cf610 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -107,6 +107,25 @@ (result $error $errno) ) + ;;; Set the permissions of a file or directory. + ;;; + ;;; This sets the permissions associated with a file or directory in + ;;; a filesystem at the time it is called. The ability to actually access + ;;; a file or directory may depend on additional permissions not reflected + ;;; here. + ;;; + ;;; Note: This is similar `fchmod` in POSIX. + ;;; + ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; + ;;; implementations in POSIX environments are suggested to consult the + ;;; umask to determine which of the user/group/other flags to modify. + (@interface func (export "permissions_set") + (param $fd $fd) + ;;; The permissions associated with the file. + (result $permissions $permissions) + (result $error $errno) + ) + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. ;;; Note: This is similar to `preadv` in POSIX. (@interface func (export "pread") diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx index e700a482b..dbd02dc1a 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -50,6 +50,29 @@ (result $error $errno) ) + ;;; Set the permissions of a file or directory. + ;;; + ;;; This sets the permissions associated with a file or directory in + ;;; a filesystem at the time it is called. The ability to actually access + ;;; a file or directory may depend on additional permissions not reflected + ;;; here. + ;;; + ;;; Note: This is similar to `fchmodat` in POSIX. + ;;; + ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; + ;;; implementations in POSIX environments are suggested to consult the + ;;; umask to determine which of the user/group/other flags to modify. + (@interface func (export "permissions_set") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags) + ;;; The path to a file to query. + (param $path string) + ;;; The permissions to associate with the file. + (param $permissions $permissions) + (result $error $errno) + ) + ;;; Create a hard link. ;;; Note: This is similar to `linkat` in POSIX. (@interface func (export "link") @@ -94,6 +117,8 @@ (param $fs_rights_base $rights) (param $fs_rights_inherting $rights) (param $fdflags $fdflags) + ;;; If a file is created, the filesystem permissions to associate with it. + (param $permissions $permissions) (result $error $errno) ;;; The file descriptor of the file that has been opened. (result $opened_fd $fd) @@ -147,7 +172,6 @@ (result $error $errno) ) - ;;; Unlink a file. ;;; Return `EISDIR` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. From df39e70e68dd897884425506357b05f564d4254e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 20 Dec 2019 20:47:17 -0800 Subject: [PATCH 0415/1772] Add an int typedef kind, which is like enum but not expected to be exhaustive. (#177) This will allow us to auto-generate the `DIRCOOKIE_START` constant. --- .../phases/ephemeral/witx/typenames.witx | 9 ++-- proposals/clocks/tools/witx/src/ast.rs | 15 +++++++ proposals/clocks/tools/witx/src/coretypes.rs | 1 + proposals/clocks/tools/witx/src/docs.rs | 18 ++++++++ proposals/clocks/tools/witx/src/layout.rs | 1 + proposals/clocks/tools/witx/src/lib.rs | 8 ++-- proposals/clocks/tools/witx/src/parser.rs | 41 +++++++++++++++++++ proposals/clocks/tools/witx/src/render.rs | 22 ++++++++++ proposals/clocks/tools/witx/src/validate.rs | 32 +++++++++++++-- 9 files changed, 136 insertions(+), 11 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index b3e998228..8b2165eb6 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -319,9 +319,12 @@ ) ;;; A reference to the offset of a directory entry. -;; -;;; The value 0 signifies the start of the directory. -(typename $dircookie u64) +(typename $dircookie + (int u64 + ;; In an `fd_readdir` call, this value signifies the start of the directory. + (const $start 0) + ) +) ;;; The type for the $d_namlen field of $dirent. (typename $dirnamlen u32) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 56a550dff..cf9e2845d 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -142,6 +142,7 @@ impl NamedType { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { Enum(EnumDatatype), + Int(IntDatatype), Flags(FlagsDatatype), Struct(StructDatatype), Union(UnionDatatype), @@ -158,6 +159,7 @@ impl Type { use Type::*; match self { Enum(_) => "enum", + Int(_) => "int", Flags(_) => "flags", Struct(_) => "struct", Union(_) => "union", @@ -207,6 +209,19 @@ pub struct EnumVariant { pub docs: String, } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct IntDatatype { + pub repr: IntRepr, + pub consts: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct IntConst { + pub name: Id, + pub value: u64, + pub docs: String, +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsDatatype { pub repr: IntRepr, diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index cedf652fa..49d4292cf 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -52,6 +52,7 @@ impl Type { TypePassedBy::Value(AtomType::I32) } Type::Enum(e) => TypePassedBy::Value(e.repr.into()), + Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), Type::Struct { .. } | Type::Union { .. } => TypePassedBy::Pointer, Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs index b795a4f0c..f6d4566e3 100644 --- a/proposals/clocks/tools/witx/src/docs.rs +++ b/proposals/clocks/tools/witx/src/docs.rs @@ -45,6 +45,7 @@ impl Documentation for NamedType { let body = match &self.tref { TypeRef::Value(v) => match &**v { Type::Enum(a) => a.to_md(), + Type::Int(a) => a.to_md(), Type::Flags(a) => a.to_md(), Type::Struct(a) => a.to_md(), Type::Union(a) => a.to_md(), @@ -72,6 +73,7 @@ impl TypeRef { Type::USize => format!("USize"), Type::Builtin(b) => b.type_name().to_string(), Type::Enum { .. } + | Type::Int { .. } | Type::Flags { .. } | Type::Struct { .. } | Type::Union { .. } @@ -99,6 +101,22 @@ impl Documentation for EnumDatatype { } } +impl Documentation for IntDatatype { + fn to_md(&self) -> String { + let consts = self + .consts + .iter() + .map(|v| format!("#### `{}`: {}\n{}", v.name.as_str(), v.value, v.docs)) + .collect::>() + .join("\n"); + format!( + "Int represented by `{}`\n\n### Consts:\n{}\n", + self.repr.type_name(), + consts + ) + } +} + impl Documentation for FlagsDatatype { fn to_md(&self) -> String { let flags = self diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index 2460ddde7..3d265639f 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -24,6 +24,7 @@ impl TypeRef { } let layout = match &*self.type_() { Type::Enum(e) => e.repr.mem_size_align(), + Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), Type::Struct(s) => s.layout(cache), Type::Union(u) => u.layout(cache), diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 1ef5d5693..05586ec96 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -23,10 +23,10 @@ mod validate; pub use ast::{ BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, - FlagsMember, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, - InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypeRef, UnionDatatype, - UnionVariant, + FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, + InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, + ModuleImport, ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypeRef, + UnionDatatype, UnionVariant, }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 7a15f469d..fadd43578 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -26,8 +26,10 @@ mod kw { wast::custom_keyword!(field); wast::custom_keyword!(flags); wast::custom_keyword!(handle); + wast::custom_keyword!(int); wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); + wast::custom_keyword!(r#const = "const"); wast::custom_keyword!(r#enum = "enum"); wast::custom_keyword!(r#struct = "struct"); wast::custom_keyword!(r#union = "union"); @@ -306,6 +308,7 @@ impl<'a> Parse<'a> for TypenameSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub enum TypedefSyntax<'a> { Enum(EnumSyntax<'a>), + Int(IntSyntax<'a>), Flags(FlagsSyntax<'a>), Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), @@ -330,6 +333,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { let mut l = parser.lookahead1(); if l.peek::() { Ok(TypedefSyntax::Enum(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Int(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Flags(parser.parse()?)) } else if l.peek::() { @@ -385,6 +390,42 @@ impl<'a> Parse<'a> for EnumSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct IntSyntax<'a> { + pub repr: BuiltinType, + pub consts: Vec>>, +} + +impl<'a> Parse<'a> for IntSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let repr = parser.parse()?; + let mut consts = Vec::new(); + consts.push(parser.parse()?); + while !parser.is_empty() { + consts.push(parser.parse()?); + } + Ok(IntSyntax { repr, consts }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ConstSyntax<'a> { + pub name: wast::Id<'a>, + pub value: u64, +} + +impl<'a> Parse<'a> for ConstSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parens(|p| { + p.parse::()?; + let name = p.parse()?; + let value = p.parse()?; + Ok(ConstSyntax { name, value }) + }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsSyntax<'a> { pub repr: BuiltinType, diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index e35f563f2..a8f3ddf2d 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -116,6 +116,7 @@ impl Type { pub fn to_sexpr(&self) -> SExpr { match self { Type::Enum(a) => a.to_sexpr(), + Type::Int(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), Type::Struct(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), @@ -149,6 +150,27 @@ impl EnumDatatype { } } +impl IntDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("int"), self.repr.to_sexpr()]; + let consts = self + .consts + .iter() + .map(|v| { + SExpr::docs( + &v.docs, + SExpr::Vec(vec![ + SExpr::word("const"), + v.name.to_sexpr(), + SExpr::word(&format!("{}", v.value)), + ]), + ) + }) + .collect::>(); + SExpr::Vec([header, consts].concat()) + } +} + impl FlagsDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 340ed058f..02c3ab3bb 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -2,12 +2,13 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, - ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, - HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, - Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, - StructDatatype, StructMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, + HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, + InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, + ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypePassedBy, TypeRef, + UnionDatatype, UnionVariant, }; use std::collections::HashMap; use std::path::Path; @@ -225,6 +226,7 @@ impl DocValidationScope<'_> { } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), + TypedefSyntax::Int(syntax) => Type::Int(self.validate_int(&syntax, span)?), TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), @@ -263,6 +265,28 @@ impl DocValidationScope<'_> { Ok(EnumDatatype { repr, variants }) } + fn validate_int( + &self, + syntax: &IntSyntax, + span: wast::Span, + ) -> Result { + let mut int_scope = IdentValidation::new(); + let repr = self.validate_int_repr(&syntax.repr, span)?; + let consts = syntax + .consts + .iter() + .map(|i| { + let name = + int_scope.introduce(i.item.name.name(), self.location(i.item.name.span()))?; + let value = i.item.value; + let docs = i.comments.docs(); + Ok(IntConst { name, value, docs }) + }) + .collect::, _>>()?; + + Ok(IntDatatype { repr, consts }) + } + fn validate_flags( &self, syntax: &FlagsSyntax, From 4d1fb872a0d062fb1307df9392bdfdcccc0aaf12 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 20 Dec 2019 20:47:17 -0800 Subject: [PATCH 0416/1772] Add an int typedef kind, which is like enum but not expected to be exhaustive. (#177) This will allow us to auto-generate the `DIRCOOKIE_START` constant. --- .../phases/ephemeral/witx/typenames.witx | 9 ++-- proposals/random/tools/witx/src/ast.rs | 15 +++++++ proposals/random/tools/witx/src/coretypes.rs | 1 + proposals/random/tools/witx/src/docs.rs | 18 ++++++++ proposals/random/tools/witx/src/layout.rs | 1 + proposals/random/tools/witx/src/lib.rs | 8 ++-- proposals/random/tools/witx/src/parser.rs | 41 +++++++++++++++++++ proposals/random/tools/witx/src/render.rs | 22 ++++++++++ proposals/random/tools/witx/src/validate.rs | 32 +++++++++++++-- 9 files changed, 136 insertions(+), 11 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index b3e998228..8b2165eb6 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -319,9 +319,12 @@ ) ;;; A reference to the offset of a directory entry. -;; -;;; The value 0 signifies the start of the directory. -(typename $dircookie u64) +(typename $dircookie + (int u64 + ;; In an `fd_readdir` call, this value signifies the start of the directory. + (const $start 0) + ) +) ;;; The type for the $d_namlen field of $dirent. (typename $dirnamlen u32) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 56a550dff..cf9e2845d 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -142,6 +142,7 @@ impl NamedType { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { Enum(EnumDatatype), + Int(IntDatatype), Flags(FlagsDatatype), Struct(StructDatatype), Union(UnionDatatype), @@ -158,6 +159,7 @@ impl Type { use Type::*; match self { Enum(_) => "enum", + Int(_) => "int", Flags(_) => "flags", Struct(_) => "struct", Union(_) => "union", @@ -207,6 +209,19 @@ pub struct EnumVariant { pub docs: String, } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct IntDatatype { + pub repr: IntRepr, + pub consts: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct IntConst { + pub name: Id, + pub value: u64, + pub docs: String, +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsDatatype { pub repr: IntRepr, diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index cedf652fa..49d4292cf 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -52,6 +52,7 @@ impl Type { TypePassedBy::Value(AtomType::I32) } Type::Enum(e) => TypePassedBy::Value(e.repr.into()), + Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), Type::Struct { .. } | Type::Union { .. } => TypePassedBy::Pointer, Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs index b795a4f0c..f6d4566e3 100644 --- a/proposals/random/tools/witx/src/docs.rs +++ b/proposals/random/tools/witx/src/docs.rs @@ -45,6 +45,7 @@ impl Documentation for NamedType { let body = match &self.tref { TypeRef::Value(v) => match &**v { Type::Enum(a) => a.to_md(), + Type::Int(a) => a.to_md(), Type::Flags(a) => a.to_md(), Type::Struct(a) => a.to_md(), Type::Union(a) => a.to_md(), @@ -72,6 +73,7 @@ impl TypeRef { Type::USize => format!("USize"), Type::Builtin(b) => b.type_name().to_string(), Type::Enum { .. } + | Type::Int { .. } | Type::Flags { .. } | Type::Struct { .. } | Type::Union { .. } @@ -99,6 +101,22 @@ impl Documentation for EnumDatatype { } } +impl Documentation for IntDatatype { + fn to_md(&self) -> String { + let consts = self + .consts + .iter() + .map(|v| format!("#### `{}`: {}\n{}", v.name.as_str(), v.value, v.docs)) + .collect::>() + .join("\n"); + format!( + "Int represented by `{}`\n\n### Consts:\n{}\n", + self.repr.type_name(), + consts + ) + } +} + impl Documentation for FlagsDatatype { fn to_md(&self) -> String { let flags = self diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index 2460ddde7..3d265639f 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -24,6 +24,7 @@ impl TypeRef { } let layout = match &*self.type_() { Type::Enum(e) => e.repr.mem_size_align(), + Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), Type::Struct(s) => s.layout(cache), Type::Union(u) => u.layout(cache), diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 1ef5d5693..05586ec96 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -23,10 +23,10 @@ mod validate; pub use ast::{ BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, - FlagsMember, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, - InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypeRef, UnionDatatype, - UnionVariant, + FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, + InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, + ModuleImport, ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypeRef, + UnionDatatype, UnionVariant, }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 7a15f469d..fadd43578 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -26,8 +26,10 @@ mod kw { wast::custom_keyword!(field); wast::custom_keyword!(flags); wast::custom_keyword!(handle); + wast::custom_keyword!(int); wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); + wast::custom_keyword!(r#const = "const"); wast::custom_keyword!(r#enum = "enum"); wast::custom_keyword!(r#struct = "struct"); wast::custom_keyword!(r#union = "union"); @@ -306,6 +308,7 @@ impl<'a> Parse<'a> for TypenameSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub enum TypedefSyntax<'a> { Enum(EnumSyntax<'a>), + Int(IntSyntax<'a>), Flags(FlagsSyntax<'a>), Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), @@ -330,6 +333,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { let mut l = parser.lookahead1(); if l.peek::() { Ok(TypedefSyntax::Enum(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Int(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Flags(parser.parse()?)) } else if l.peek::() { @@ -385,6 +390,42 @@ impl<'a> Parse<'a> for EnumSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct IntSyntax<'a> { + pub repr: BuiltinType, + pub consts: Vec>>, +} + +impl<'a> Parse<'a> for IntSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let repr = parser.parse()?; + let mut consts = Vec::new(); + consts.push(parser.parse()?); + while !parser.is_empty() { + consts.push(parser.parse()?); + } + Ok(IntSyntax { repr, consts }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ConstSyntax<'a> { + pub name: wast::Id<'a>, + pub value: u64, +} + +impl<'a> Parse<'a> for ConstSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parens(|p| { + p.parse::()?; + let name = p.parse()?; + let value = p.parse()?; + Ok(ConstSyntax { name, value }) + }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsSyntax<'a> { pub repr: BuiltinType, diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index e35f563f2..a8f3ddf2d 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -116,6 +116,7 @@ impl Type { pub fn to_sexpr(&self) -> SExpr { match self { Type::Enum(a) => a.to_sexpr(), + Type::Int(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), Type::Struct(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), @@ -149,6 +150,27 @@ impl EnumDatatype { } } +impl IntDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("int"), self.repr.to_sexpr()]; + let consts = self + .consts + .iter() + .map(|v| { + SExpr::docs( + &v.docs, + SExpr::Vec(vec![ + SExpr::word("const"), + v.name.to_sexpr(), + SExpr::word(&format!("{}", v.value)), + ]), + ) + }) + .collect::>(); + SExpr::Vec([header, consts].concat()) + } +} + impl FlagsDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 340ed058f..02c3ab3bb 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -2,12 +2,13 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, - ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, - HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, - Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, - StructDatatype, StructMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, + HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, + InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, + ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypePassedBy, TypeRef, + UnionDatatype, UnionVariant, }; use std::collections::HashMap; use std::path::Path; @@ -225,6 +226,7 @@ impl DocValidationScope<'_> { } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), + TypedefSyntax::Int(syntax) => Type::Int(self.validate_int(&syntax, span)?), TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), @@ -263,6 +265,28 @@ impl DocValidationScope<'_> { Ok(EnumDatatype { repr, variants }) } + fn validate_int( + &self, + syntax: &IntSyntax, + span: wast::Span, + ) -> Result { + let mut int_scope = IdentValidation::new(); + let repr = self.validate_int_repr(&syntax.repr, span)?; + let consts = syntax + .consts + .iter() + .map(|i| { + let name = + int_scope.introduce(i.item.name.name(), self.location(i.item.name.span()))?; + let value = i.item.value; + let docs = i.comments.docs(); + Ok(IntConst { name, value, docs }) + }) + .collect::, _>>()?; + + Ok(IntDatatype { repr, consts }) + } + fn validate_flags( &self, syntax: &FlagsSyntax, From 92cbd481a8fee534787b13b8ae14140c719986a9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 20 Dec 2019 20:47:17 -0800 Subject: [PATCH 0417/1772] Add an int typedef kind, which is like enum but not expected to be exhaustive. (#177) This will allow us to auto-generate the `DIRCOOKIE_START` constant. --- .../phases/ephemeral/witx/typenames.witx | 9 ++-- proposals/filesystem/tools/witx/src/ast.rs | 15 +++++++ .../filesystem/tools/witx/src/coretypes.rs | 1 + proposals/filesystem/tools/witx/src/docs.rs | 18 ++++++++ proposals/filesystem/tools/witx/src/layout.rs | 1 + proposals/filesystem/tools/witx/src/lib.rs | 8 ++-- proposals/filesystem/tools/witx/src/parser.rs | 41 +++++++++++++++++++ proposals/filesystem/tools/witx/src/render.rs | 22 ++++++++++ .../filesystem/tools/witx/src/validate.rs | 32 +++++++++++++-- 9 files changed, 136 insertions(+), 11 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index b3e998228..8b2165eb6 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -319,9 +319,12 @@ ) ;;; A reference to the offset of a directory entry. -;; -;;; The value 0 signifies the start of the directory. -(typename $dircookie u64) +(typename $dircookie + (int u64 + ;; In an `fd_readdir` call, this value signifies the start of the directory. + (const $start 0) + ) +) ;;; The type for the $d_namlen field of $dirent. (typename $dirnamlen u32) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 56a550dff..cf9e2845d 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -142,6 +142,7 @@ impl NamedType { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { Enum(EnumDatatype), + Int(IntDatatype), Flags(FlagsDatatype), Struct(StructDatatype), Union(UnionDatatype), @@ -158,6 +159,7 @@ impl Type { use Type::*; match self { Enum(_) => "enum", + Int(_) => "int", Flags(_) => "flags", Struct(_) => "struct", Union(_) => "union", @@ -207,6 +209,19 @@ pub struct EnumVariant { pub docs: String, } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct IntDatatype { + pub repr: IntRepr, + pub consts: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct IntConst { + pub name: Id, + pub value: u64, + pub docs: String, +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsDatatype { pub repr: IntRepr, diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index cedf652fa..49d4292cf 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -52,6 +52,7 @@ impl Type { TypePassedBy::Value(AtomType::I32) } Type::Enum(e) => TypePassedBy::Value(e.repr.into()), + Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), Type::Struct { .. } | Type::Union { .. } => TypePassedBy::Pointer, Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs index b795a4f0c..f6d4566e3 100644 --- a/proposals/filesystem/tools/witx/src/docs.rs +++ b/proposals/filesystem/tools/witx/src/docs.rs @@ -45,6 +45,7 @@ impl Documentation for NamedType { let body = match &self.tref { TypeRef::Value(v) => match &**v { Type::Enum(a) => a.to_md(), + Type::Int(a) => a.to_md(), Type::Flags(a) => a.to_md(), Type::Struct(a) => a.to_md(), Type::Union(a) => a.to_md(), @@ -72,6 +73,7 @@ impl TypeRef { Type::USize => format!("USize"), Type::Builtin(b) => b.type_name().to_string(), Type::Enum { .. } + | Type::Int { .. } | Type::Flags { .. } | Type::Struct { .. } | Type::Union { .. } @@ -99,6 +101,22 @@ impl Documentation for EnumDatatype { } } +impl Documentation for IntDatatype { + fn to_md(&self) -> String { + let consts = self + .consts + .iter() + .map(|v| format!("#### `{}`: {}\n{}", v.name.as_str(), v.value, v.docs)) + .collect::>() + .join("\n"); + format!( + "Int represented by `{}`\n\n### Consts:\n{}\n", + self.repr.type_name(), + consts + ) + } +} + impl Documentation for FlagsDatatype { fn to_md(&self) -> String { let flags = self diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index 2460ddde7..3d265639f 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -24,6 +24,7 @@ impl TypeRef { } let layout = match &*self.type_() { Type::Enum(e) => e.repr.mem_size_align(), + Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), Type::Struct(s) => s.layout(cache), Type::Union(u) => u.layout(cache), diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 1ef5d5693..05586ec96 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -23,10 +23,10 @@ mod validate; pub use ast::{ BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, - FlagsMember, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, - InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypeRef, UnionDatatype, - UnionVariant, + FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, + InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, + ModuleImport, ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypeRef, + UnionDatatype, UnionVariant, }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 7a15f469d..fadd43578 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -26,8 +26,10 @@ mod kw { wast::custom_keyword!(field); wast::custom_keyword!(flags); wast::custom_keyword!(handle); + wast::custom_keyword!(int); wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); + wast::custom_keyword!(r#const = "const"); wast::custom_keyword!(r#enum = "enum"); wast::custom_keyword!(r#struct = "struct"); wast::custom_keyword!(r#union = "union"); @@ -306,6 +308,7 @@ impl<'a> Parse<'a> for TypenameSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub enum TypedefSyntax<'a> { Enum(EnumSyntax<'a>), + Int(IntSyntax<'a>), Flags(FlagsSyntax<'a>), Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), @@ -330,6 +333,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { let mut l = parser.lookahead1(); if l.peek::() { Ok(TypedefSyntax::Enum(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Int(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Flags(parser.parse()?)) } else if l.peek::() { @@ -385,6 +390,42 @@ impl<'a> Parse<'a> for EnumSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct IntSyntax<'a> { + pub repr: BuiltinType, + pub consts: Vec>>, +} + +impl<'a> Parse<'a> for IntSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let repr = parser.parse()?; + let mut consts = Vec::new(); + consts.push(parser.parse()?); + while !parser.is_empty() { + consts.push(parser.parse()?); + } + Ok(IntSyntax { repr, consts }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ConstSyntax<'a> { + pub name: wast::Id<'a>, + pub value: u64, +} + +impl<'a> Parse<'a> for ConstSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parens(|p| { + p.parse::()?; + let name = p.parse()?; + let value = p.parse()?; + Ok(ConstSyntax { name, value }) + }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsSyntax<'a> { pub repr: BuiltinType, diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index e35f563f2..a8f3ddf2d 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -116,6 +116,7 @@ impl Type { pub fn to_sexpr(&self) -> SExpr { match self { Type::Enum(a) => a.to_sexpr(), + Type::Int(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), Type::Struct(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), @@ -149,6 +150,27 @@ impl EnumDatatype { } } +impl IntDatatype { + fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("int"), self.repr.to_sexpr()]; + let consts = self + .consts + .iter() + .map(|v| { + SExpr::docs( + &v.docs, + SExpr::Vec(vec![ + SExpr::word("const"), + v.name.to_sexpr(), + SExpr::word(&format!("{}", v.value)), + ]), + ) + }) + .collect::>(); + SExpr::Vec([header, consts].concat()) + } +} + impl FlagsDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 340ed058f..02c3ab3bb 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -2,12 +2,13 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, - ImportTypeSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, }, BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, - HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, - Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, - StructDatatype, StructMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, + HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, + InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, + ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypePassedBy, TypeRef, + UnionDatatype, UnionVariant, }; use std::collections::HashMap; use std::path::Path; @@ -225,6 +226,7 @@ impl DocValidationScope<'_> { } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), + TypedefSyntax::Int(syntax) => Type::Int(self.validate_int(&syntax, span)?), TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), @@ -263,6 +265,28 @@ impl DocValidationScope<'_> { Ok(EnumDatatype { repr, variants }) } + fn validate_int( + &self, + syntax: &IntSyntax, + span: wast::Span, + ) -> Result { + let mut int_scope = IdentValidation::new(); + let repr = self.validate_int_repr(&syntax.repr, span)?; + let consts = syntax + .consts + .iter() + .map(|i| { + let name = + int_scope.introduce(i.item.name.name(), self.location(i.item.name.span()))?; + let value = i.item.value; + let docs = i.comments.docs(); + Ok(IntConst { name, value, docs }) + }) + .collect::, _>>()?; + + Ok(IntDatatype { repr, consts }) + } + fn validate_flags( &self, syntax: &FlagsSyntax, From 1b67f92ec7742419673511b8e082a60aa51eee77 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Sat, 21 Dec 2019 00:06:28 -0800 Subject: [PATCH 0418/1772] witx: exclude structs, unions, enums, flags, and handles from being declared anonymously (#183) --- proposals/clocks/tools/witx/src/validate.rs | 45 +++++++++++++------ .../clocks/tools/witx/tests/anonymous.rs | 41 +++++++++++++++++ 2 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 proposals/clocks/tools/witx/tests/anonymous.rs diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 02c3ab3bb..518564371 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -41,6 +41,8 @@ pub enum ValidationError { }, #[error("First result type must be pass-by-value")] InvalidFirstResultType { location: Location }, + #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] + AnonymousStructure { location: Location }, } impl ValidationError { @@ -51,7 +53,8 @@ impl ValidationError { | WrongKindName { location, .. } | Recursive { location, .. } | InvalidRepr { location, .. } - | InvalidFirstResultType { location, .. } => { + | InvalidFirstResultType { location, .. } + | AnonymousStructure { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } NameAlreadyExists { @@ -165,7 +168,7 @@ impl DocValidationScope<'_> { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; let docs = comments.docs(); - let tref = self.validate_datatype(&decl.def, decl.ident.span())?; + let tref = self.validate_datatype(&decl.def, true, decl.ident.span())?; let rc_datatype = Rc::new(NamedType { name: name.clone(), @@ -203,6 +206,7 @@ impl DocValidationScope<'_> { fn validate_datatype( &self, syntax: &TypedefSyntax, + named: bool, span: wast::Span, ) -> Result { match syntax { @@ -224,6 +228,17 @@ impl DocValidationScope<'_> { }), } } + TypedefSyntax::Enum { .. } + | TypedefSyntax::Flags { .. } + | TypedefSyntax::Struct { .. } + | TypedefSyntax::Union { .. } + | TypedefSyntax::Handle { .. } + if !named => + { + Err(ValidationError::AnonymousStructure { + location: self.location(span), + }) + } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), TypedefSyntax::Int(syntax) => Type::Int(self.validate_int(&syntax, span)?), @@ -231,12 +246,14 @@ impl DocValidationScope<'_> { TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), - TypedefSyntax::Array(syntax) => Type::Array(self.validate_datatype(syntax, span)?), + TypedefSyntax::Array(syntax) => { + Type::Array(self.validate_datatype(syntax, false, span)?) + } TypedefSyntax::Pointer(syntax) => { - Type::Pointer(self.validate_datatype(syntax, span)?) + Type::Pointer(self.validate_datatype(syntax, false, span)?) } TypedefSyntax::ConstPointer(syntax) => { - Type::ConstPointer(self.validate_datatype(syntax, span)?) + Type::ConstPointer(self.validate_datatype(syntax, false, span)?) } TypedefSyntax::USize => Type::USize, TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), @@ -319,7 +336,7 @@ impl DocValidationScope<'_> { .map(|f| { let name = member_scope .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let tref = self.validate_datatype(&f.item.type_, f.item.name.span())?; + let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; let docs = f.comments.docs(); Ok(StructMember { name, tref, docs }) }) @@ -340,7 +357,7 @@ impl DocValidationScope<'_> { .map(|f| { let name = variant_scope .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let tref = self.validate_datatype(&f.item.type_, f.item.name.span())?; + let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; let docs = f.comments.docs(); Ok(UnionVariant { name, tref, docs }) }) @@ -456,9 +473,11 @@ impl<'a> ModuleValidation<'a> { f.item.name.name(), self.doc.location(f.item.name.span()), )?, - tref: self - .doc - .validate_datatype(&f.item.type_, f.item.name.span())?, + tref: self.doc.validate_datatype( + &f.item.type_, + false, + f.item.name.span(), + )?, position: InterfaceFuncParamPosition::Param(ix), docs: f.comments.docs(), }) @@ -469,9 +488,9 @@ impl<'a> ModuleValidation<'a> { .iter() .enumerate() .map(|(ix, f)| { - let tref = self - .doc - .validate_datatype(&f.item.type_, f.item.name.span())?; + let tref = + self.doc + .validate_datatype(&f.item.type_, false, f.item.name.span())?; if ix == 0 { match tref.type_().passed_by() { TypePassedBy::Value(_) => {} diff --git a/proposals/clocks/tools/witx/tests/anonymous.rs b/proposals/clocks/tools/witx/tests/anonymous.rs new file mode 100644 index 000000000..e1976a261 --- /dev/null +++ b/proposals/clocks/tools/witx/tests/anonymous.rs @@ -0,0 +1,41 @@ +use witx; + +fn is_anonymous_struct_err(r: Result) -> bool { + match r { + Err(witx::WitxError::Validation(witx::ValidationError::AnonymousStructure { .. })) => true, + _ => false, + } +} + +#[test] +fn anonymous_types() { + let pointer_to_struct = witx::parse("(typename $a (@witx pointer (struct (field $b u8))))"); + assert!(is_anonymous_struct_err(pointer_to_struct)); + + let pointer_to_union = witx::parse("(typename $a (@witx pointer (union (field $b u8))))"); + assert!(is_anonymous_struct_err(pointer_to_union)); + + let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum u32 $b)))"); + assert!(is_anonymous_struct_err(pointer_to_enum)); + + let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags u32 $b)))"); + assert!(is_anonymous_struct_err(pointer_to_flags)); + + let pointer_to_handle = witx::parse("(typename $a (@witx pointer (handle)))"); + assert!(is_anonymous_struct_err(pointer_to_handle)); + + let pointer_to_builtin = witx::parse("(typename $a (@witx pointer u8))"); + assert!(pointer_to_builtin.is_ok()); + + let pointer_to_pointer = witx::parse("(typename $a (@witx pointer (@witx const_pointer u8)))"); + assert!(pointer_to_pointer.is_ok()); + + let struct_in_struct = witx::parse("(typename $a (struct (field $b (struct (field $c u8)))))"); + assert!(is_anonymous_struct_err(struct_in_struct)); + + let union_in_struct = witx::parse("(typename $a (struct (field $b (union (field $c u8)))))"); + assert!(is_anonymous_struct_err(union_in_struct)); + + let pointer_in_struct = witx::parse("(typename $a (struct (field $b (@witx pointer u8))))"); + assert!(pointer_in_struct.is_ok()) +} From 75363d74e7c376a8372356cb353c5efe0b0b867b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Sat, 21 Dec 2019 00:06:28 -0800 Subject: [PATCH 0419/1772] witx: exclude structs, unions, enums, flags, and handles from being declared anonymously (#183) --- proposals/random/tools/witx/src/validate.rs | 45 +++++++++++++------ .../random/tools/witx/tests/anonymous.rs | 41 +++++++++++++++++ 2 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 proposals/random/tools/witx/tests/anonymous.rs diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 02c3ab3bb..518564371 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -41,6 +41,8 @@ pub enum ValidationError { }, #[error("First result type must be pass-by-value")] InvalidFirstResultType { location: Location }, + #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] + AnonymousStructure { location: Location }, } impl ValidationError { @@ -51,7 +53,8 @@ impl ValidationError { | WrongKindName { location, .. } | Recursive { location, .. } | InvalidRepr { location, .. } - | InvalidFirstResultType { location, .. } => { + | InvalidFirstResultType { location, .. } + | AnonymousStructure { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } NameAlreadyExists { @@ -165,7 +168,7 @@ impl DocValidationScope<'_> { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; let docs = comments.docs(); - let tref = self.validate_datatype(&decl.def, decl.ident.span())?; + let tref = self.validate_datatype(&decl.def, true, decl.ident.span())?; let rc_datatype = Rc::new(NamedType { name: name.clone(), @@ -203,6 +206,7 @@ impl DocValidationScope<'_> { fn validate_datatype( &self, syntax: &TypedefSyntax, + named: bool, span: wast::Span, ) -> Result { match syntax { @@ -224,6 +228,17 @@ impl DocValidationScope<'_> { }), } } + TypedefSyntax::Enum { .. } + | TypedefSyntax::Flags { .. } + | TypedefSyntax::Struct { .. } + | TypedefSyntax::Union { .. } + | TypedefSyntax::Handle { .. } + if !named => + { + Err(ValidationError::AnonymousStructure { + location: self.location(span), + }) + } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), TypedefSyntax::Int(syntax) => Type::Int(self.validate_int(&syntax, span)?), @@ -231,12 +246,14 @@ impl DocValidationScope<'_> { TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), - TypedefSyntax::Array(syntax) => Type::Array(self.validate_datatype(syntax, span)?), + TypedefSyntax::Array(syntax) => { + Type::Array(self.validate_datatype(syntax, false, span)?) + } TypedefSyntax::Pointer(syntax) => { - Type::Pointer(self.validate_datatype(syntax, span)?) + Type::Pointer(self.validate_datatype(syntax, false, span)?) } TypedefSyntax::ConstPointer(syntax) => { - Type::ConstPointer(self.validate_datatype(syntax, span)?) + Type::ConstPointer(self.validate_datatype(syntax, false, span)?) } TypedefSyntax::USize => Type::USize, TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), @@ -319,7 +336,7 @@ impl DocValidationScope<'_> { .map(|f| { let name = member_scope .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let tref = self.validate_datatype(&f.item.type_, f.item.name.span())?; + let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; let docs = f.comments.docs(); Ok(StructMember { name, tref, docs }) }) @@ -340,7 +357,7 @@ impl DocValidationScope<'_> { .map(|f| { let name = variant_scope .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let tref = self.validate_datatype(&f.item.type_, f.item.name.span())?; + let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; let docs = f.comments.docs(); Ok(UnionVariant { name, tref, docs }) }) @@ -456,9 +473,11 @@ impl<'a> ModuleValidation<'a> { f.item.name.name(), self.doc.location(f.item.name.span()), )?, - tref: self - .doc - .validate_datatype(&f.item.type_, f.item.name.span())?, + tref: self.doc.validate_datatype( + &f.item.type_, + false, + f.item.name.span(), + )?, position: InterfaceFuncParamPosition::Param(ix), docs: f.comments.docs(), }) @@ -469,9 +488,9 @@ impl<'a> ModuleValidation<'a> { .iter() .enumerate() .map(|(ix, f)| { - let tref = self - .doc - .validate_datatype(&f.item.type_, f.item.name.span())?; + let tref = + self.doc + .validate_datatype(&f.item.type_, false, f.item.name.span())?; if ix == 0 { match tref.type_().passed_by() { TypePassedBy::Value(_) => {} diff --git a/proposals/random/tools/witx/tests/anonymous.rs b/proposals/random/tools/witx/tests/anonymous.rs new file mode 100644 index 000000000..e1976a261 --- /dev/null +++ b/proposals/random/tools/witx/tests/anonymous.rs @@ -0,0 +1,41 @@ +use witx; + +fn is_anonymous_struct_err(r: Result) -> bool { + match r { + Err(witx::WitxError::Validation(witx::ValidationError::AnonymousStructure { .. })) => true, + _ => false, + } +} + +#[test] +fn anonymous_types() { + let pointer_to_struct = witx::parse("(typename $a (@witx pointer (struct (field $b u8))))"); + assert!(is_anonymous_struct_err(pointer_to_struct)); + + let pointer_to_union = witx::parse("(typename $a (@witx pointer (union (field $b u8))))"); + assert!(is_anonymous_struct_err(pointer_to_union)); + + let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum u32 $b)))"); + assert!(is_anonymous_struct_err(pointer_to_enum)); + + let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags u32 $b)))"); + assert!(is_anonymous_struct_err(pointer_to_flags)); + + let pointer_to_handle = witx::parse("(typename $a (@witx pointer (handle)))"); + assert!(is_anonymous_struct_err(pointer_to_handle)); + + let pointer_to_builtin = witx::parse("(typename $a (@witx pointer u8))"); + assert!(pointer_to_builtin.is_ok()); + + let pointer_to_pointer = witx::parse("(typename $a (@witx pointer (@witx const_pointer u8)))"); + assert!(pointer_to_pointer.is_ok()); + + let struct_in_struct = witx::parse("(typename $a (struct (field $b (struct (field $c u8)))))"); + assert!(is_anonymous_struct_err(struct_in_struct)); + + let union_in_struct = witx::parse("(typename $a (struct (field $b (union (field $c u8)))))"); + assert!(is_anonymous_struct_err(union_in_struct)); + + let pointer_in_struct = witx::parse("(typename $a (struct (field $b (@witx pointer u8))))"); + assert!(pointer_in_struct.is_ok()) +} From dbc6fcd1a45eaac3f11a656e9a5af38661506ff9 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Sat, 21 Dec 2019 00:06:28 -0800 Subject: [PATCH 0420/1772] witx: exclude structs, unions, enums, flags, and handles from being declared anonymously (#183) --- .../filesystem/tools/witx/src/validate.rs | 45 +++++++++++++------ .../filesystem/tools/witx/tests/anonymous.rs | 41 +++++++++++++++++ 2 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 proposals/filesystem/tools/witx/tests/anonymous.rs diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 02c3ab3bb..518564371 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -41,6 +41,8 @@ pub enum ValidationError { }, #[error("First result type must be pass-by-value")] InvalidFirstResultType { location: Location }, + #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] + AnonymousStructure { location: Location }, } impl ValidationError { @@ -51,7 +53,8 @@ impl ValidationError { | WrongKindName { location, .. } | Recursive { location, .. } | InvalidRepr { location, .. } - | InvalidFirstResultType { location, .. } => { + | InvalidFirstResultType { location, .. } + | AnonymousStructure { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } NameAlreadyExists { @@ -165,7 +168,7 @@ impl DocValidationScope<'_> { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; let docs = comments.docs(); - let tref = self.validate_datatype(&decl.def, decl.ident.span())?; + let tref = self.validate_datatype(&decl.def, true, decl.ident.span())?; let rc_datatype = Rc::new(NamedType { name: name.clone(), @@ -203,6 +206,7 @@ impl DocValidationScope<'_> { fn validate_datatype( &self, syntax: &TypedefSyntax, + named: bool, span: wast::Span, ) -> Result { match syntax { @@ -224,6 +228,17 @@ impl DocValidationScope<'_> { }), } } + TypedefSyntax::Enum { .. } + | TypedefSyntax::Flags { .. } + | TypedefSyntax::Struct { .. } + | TypedefSyntax::Union { .. } + | TypedefSyntax::Handle { .. } + if !named => + { + Err(ValidationError::AnonymousStructure { + location: self.location(span), + }) + } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), TypedefSyntax::Int(syntax) => Type::Int(self.validate_int(&syntax, span)?), @@ -231,12 +246,14 @@ impl DocValidationScope<'_> { TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), - TypedefSyntax::Array(syntax) => Type::Array(self.validate_datatype(syntax, span)?), + TypedefSyntax::Array(syntax) => { + Type::Array(self.validate_datatype(syntax, false, span)?) + } TypedefSyntax::Pointer(syntax) => { - Type::Pointer(self.validate_datatype(syntax, span)?) + Type::Pointer(self.validate_datatype(syntax, false, span)?) } TypedefSyntax::ConstPointer(syntax) => { - Type::ConstPointer(self.validate_datatype(syntax, span)?) + Type::ConstPointer(self.validate_datatype(syntax, false, span)?) } TypedefSyntax::USize => Type::USize, TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), @@ -319,7 +336,7 @@ impl DocValidationScope<'_> { .map(|f| { let name = member_scope .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let tref = self.validate_datatype(&f.item.type_, f.item.name.span())?; + let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; let docs = f.comments.docs(); Ok(StructMember { name, tref, docs }) }) @@ -340,7 +357,7 @@ impl DocValidationScope<'_> { .map(|f| { let name = variant_scope .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let tref = self.validate_datatype(&f.item.type_, f.item.name.span())?; + let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; let docs = f.comments.docs(); Ok(UnionVariant { name, tref, docs }) }) @@ -456,9 +473,11 @@ impl<'a> ModuleValidation<'a> { f.item.name.name(), self.doc.location(f.item.name.span()), )?, - tref: self - .doc - .validate_datatype(&f.item.type_, f.item.name.span())?, + tref: self.doc.validate_datatype( + &f.item.type_, + false, + f.item.name.span(), + )?, position: InterfaceFuncParamPosition::Param(ix), docs: f.comments.docs(), }) @@ -469,9 +488,9 @@ impl<'a> ModuleValidation<'a> { .iter() .enumerate() .map(|(ix, f)| { - let tref = self - .doc - .validate_datatype(&f.item.type_, f.item.name.span())?; + let tref = + self.doc + .validate_datatype(&f.item.type_, false, f.item.name.span())?; if ix == 0 { match tref.type_().passed_by() { TypePassedBy::Value(_) => {} diff --git a/proposals/filesystem/tools/witx/tests/anonymous.rs b/proposals/filesystem/tools/witx/tests/anonymous.rs new file mode 100644 index 000000000..e1976a261 --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/anonymous.rs @@ -0,0 +1,41 @@ +use witx; + +fn is_anonymous_struct_err(r: Result) -> bool { + match r { + Err(witx::WitxError::Validation(witx::ValidationError::AnonymousStructure { .. })) => true, + _ => false, + } +} + +#[test] +fn anonymous_types() { + let pointer_to_struct = witx::parse("(typename $a (@witx pointer (struct (field $b u8))))"); + assert!(is_anonymous_struct_err(pointer_to_struct)); + + let pointer_to_union = witx::parse("(typename $a (@witx pointer (union (field $b u8))))"); + assert!(is_anonymous_struct_err(pointer_to_union)); + + let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum u32 $b)))"); + assert!(is_anonymous_struct_err(pointer_to_enum)); + + let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags u32 $b)))"); + assert!(is_anonymous_struct_err(pointer_to_flags)); + + let pointer_to_handle = witx::parse("(typename $a (@witx pointer (handle)))"); + assert!(is_anonymous_struct_err(pointer_to_handle)); + + let pointer_to_builtin = witx::parse("(typename $a (@witx pointer u8))"); + assert!(pointer_to_builtin.is_ok()); + + let pointer_to_pointer = witx::parse("(typename $a (@witx pointer (@witx const_pointer u8)))"); + assert!(pointer_to_pointer.is_ok()); + + let struct_in_struct = witx::parse("(typename $a (struct (field $b (struct (field $c u8)))))"); + assert!(is_anonymous_struct_err(struct_in_struct)); + + let union_in_struct = witx::parse("(typename $a (struct (field $b (union (field $c u8)))))"); + assert!(is_anonymous_struct_err(union_in_struct)); + + let pointer_in_struct = witx::parse("(typename $a (struct (field $b (@witx pointer u8))))"); + assert!(pointer_in_struct.is_ok()) +} From 97e7be75222afc2f711e548bfb2b7a95b9d8d16b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Sat, 28 Dec 2019 09:56:18 -0800 Subject: [PATCH 0421/1772] witx: make USize a BuiltinType --- proposals/clocks/tools/witx/src/ast.rs | 3 +-- proposals/clocks/tools/witx/src/coretypes.rs | 7 +++---- proposals/clocks/tools/witx/src/docs.rs | 3 +-- proposals/clocks/tools/witx/src/layout.rs | 6 ++---- proposals/clocks/tools/witx/src/parser.rs | 3 +-- proposals/clocks/tools/witx/src/render.rs | 2 +- proposals/clocks/tools/witx/src/validate.rs | 1 - 7 files changed, 9 insertions(+), 16 deletions(-) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index cf9e2845d..fcb33ad44 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -150,7 +150,6 @@ pub enum Type { Array(TypeRef), Pointer(TypeRef), ConstPointer(TypeRef), - USize, Builtin(BuiltinType), } @@ -167,7 +166,6 @@ impl Type { Array(_) => "array", Pointer(_) => "pointer", ConstPointer(_) => "constpointer", - USize => "usize", Builtin(_) => "builtin", } } @@ -177,6 +175,7 @@ impl Type { pub enum BuiltinType { String, Char8, + USize, U8, U16, U32, diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index 49d4292cf..84756209d 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -42,15 +42,14 @@ impl Type { | BuiltinType::S8 | BuiltinType::S16 | BuiltinType::S32 - | BuiltinType::Char8 => TypePassedBy::Value(AtomType::I32), + | BuiltinType::Char8 + | BuiltinType::USize => TypePassedBy::Value(AtomType::I32), BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), }, Type::Array { .. } => TypePassedBy::PointerLengthPair, - Type::Pointer { .. } | Type::ConstPointer { .. } | Type::USize => { - TypePassedBy::Value(AtomType::I32) - } + Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs index f6d4566e3..1d7572949 100644 --- a/proposals/clocks/tools/witx/src/docs.rs +++ b/proposals/clocks/tools/witx/src/docs.rs @@ -26,6 +26,7 @@ impl BuiltinType { match self { BuiltinType::String => "string", BuiltinType::Char8 => "char8", + BuiltinType::USize => "usize", BuiltinType::U8 => "u8", BuiltinType::U16 => "u16", BuiltinType::U32 => "u32", @@ -53,7 +54,6 @@ impl Documentation for NamedType { Type::Array(a) => format!("Array of {}", a.type_name()), Type::Pointer(a) => format!("Pointer to {}", a.type_name()), Type::ConstPointer(a) => format!("Constant Pointer to {}", a.type_name()), - Type::USize => format!("USize"), Type::Builtin(a) => format!("Builtin type {}", a.type_name()), }, TypeRef::Name(n) => format!("Alias to {}", n.name.as_str()), @@ -70,7 +70,6 @@ impl TypeRef { Type::Array(a) => format!("Array<{}>", a.type_name()), Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), - Type::USize => format!("USize"), Type::Builtin(b) => b.type_name().to_string(), Type::Enum { .. } | Type::Int { .. } diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index 3d265639f..cd3bd7da9 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -30,9 +30,7 @@ impl TypeRef { Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::Array { .. } => BuiltinType::String.mem_size_align(), - Type::Pointer { .. } | Type::ConstPointer { .. } | Type::USize => { - BuiltinType::U32.mem_size_align() - } + Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), }; cache.insert(self.clone(), layout); @@ -177,7 +175,7 @@ impl Layout for BuiltinType { SizeAlign { size: 1, align: 1 } } BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, - BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { + BuiltinType::USize | BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { SizeAlign { size: 4, align: 4 } } BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index fadd43578..08bc9af5b 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -316,7 +316,6 @@ pub enum TypedefSyntax<'a> { Array(Box>), Pointer(Box>), ConstPointer(Box>), - USize, Builtin(BuiltinType), Ident(wast::Id<'a>), } @@ -357,7 +356,7 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) } else if l.peek::() { parser.parse::()?; - Ok(TypedefSyntax::USize) + Ok(TypedefSyntax::Builtin(BuiltinType::USize)) } else { Err(l.error()) } diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index a8f3ddf2d..a1a6ff58a 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -79,6 +79,7 @@ impl BuiltinType { match self { BuiltinType::String => SExpr::word("string"), BuiltinType::Char8 => SExpr::word("char8"), + BuiltinType::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), BuiltinType::U8 => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), BuiltinType::U32 => SExpr::word("u32"), @@ -132,7 +133,6 @@ impl Type { SExpr::word("const_pointer"), p.to_sexpr(), ]), - Type::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), Type::Builtin(b) => b.to_sexpr(), } } diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 518564371..b640ba99d 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -255,7 +255,6 @@ impl DocValidationScope<'_> { TypedefSyntax::ConstPointer(syntax) => { Type::ConstPointer(self.validate_datatype(syntax, false, span)?) } - TypedefSyntax::USize => Type::USize, TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), TypedefSyntax::Ident { .. } => unreachable!(), }))), From 17e4c57b603306d258414ecc5feceecc3aaa60e1 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Sat, 28 Dec 2019 09:56:18 -0800 Subject: [PATCH 0422/1772] witx: make USize a BuiltinType --- proposals/random/tools/witx/src/ast.rs | 3 +-- proposals/random/tools/witx/src/coretypes.rs | 7 +++---- proposals/random/tools/witx/src/docs.rs | 3 +-- proposals/random/tools/witx/src/layout.rs | 6 ++---- proposals/random/tools/witx/src/parser.rs | 3 +-- proposals/random/tools/witx/src/render.rs | 2 +- proposals/random/tools/witx/src/validate.rs | 1 - 7 files changed, 9 insertions(+), 16 deletions(-) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index cf9e2845d..fcb33ad44 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -150,7 +150,6 @@ pub enum Type { Array(TypeRef), Pointer(TypeRef), ConstPointer(TypeRef), - USize, Builtin(BuiltinType), } @@ -167,7 +166,6 @@ impl Type { Array(_) => "array", Pointer(_) => "pointer", ConstPointer(_) => "constpointer", - USize => "usize", Builtin(_) => "builtin", } } @@ -177,6 +175,7 @@ impl Type { pub enum BuiltinType { String, Char8, + USize, U8, U16, U32, diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index 49d4292cf..84756209d 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -42,15 +42,14 @@ impl Type { | BuiltinType::S8 | BuiltinType::S16 | BuiltinType::S32 - | BuiltinType::Char8 => TypePassedBy::Value(AtomType::I32), + | BuiltinType::Char8 + | BuiltinType::USize => TypePassedBy::Value(AtomType::I32), BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), }, Type::Array { .. } => TypePassedBy::PointerLengthPair, - Type::Pointer { .. } | Type::ConstPointer { .. } | Type::USize => { - TypePassedBy::Value(AtomType::I32) - } + Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs index f6d4566e3..1d7572949 100644 --- a/proposals/random/tools/witx/src/docs.rs +++ b/proposals/random/tools/witx/src/docs.rs @@ -26,6 +26,7 @@ impl BuiltinType { match self { BuiltinType::String => "string", BuiltinType::Char8 => "char8", + BuiltinType::USize => "usize", BuiltinType::U8 => "u8", BuiltinType::U16 => "u16", BuiltinType::U32 => "u32", @@ -53,7 +54,6 @@ impl Documentation for NamedType { Type::Array(a) => format!("Array of {}", a.type_name()), Type::Pointer(a) => format!("Pointer to {}", a.type_name()), Type::ConstPointer(a) => format!("Constant Pointer to {}", a.type_name()), - Type::USize => format!("USize"), Type::Builtin(a) => format!("Builtin type {}", a.type_name()), }, TypeRef::Name(n) => format!("Alias to {}", n.name.as_str()), @@ -70,7 +70,6 @@ impl TypeRef { Type::Array(a) => format!("Array<{}>", a.type_name()), Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), - Type::USize => format!("USize"), Type::Builtin(b) => b.type_name().to_string(), Type::Enum { .. } | Type::Int { .. } diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index 3d265639f..cd3bd7da9 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -30,9 +30,7 @@ impl TypeRef { Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::Array { .. } => BuiltinType::String.mem_size_align(), - Type::Pointer { .. } | Type::ConstPointer { .. } | Type::USize => { - BuiltinType::U32.mem_size_align() - } + Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), }; cache.insert(self.clone(), layout); @@ -177,7 +175,7 @@ impl Layout for BuiltinType { SizeAlign { size: 1, align: 1 } } BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, - BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { + BuiltinType::USize | BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { SizeAlign { size: 4, align: 4 } } BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index fadd43578..08bc9af5b 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -316,7 +316,6 @@ pub enum TypedefSyntax<'a> { Array(Box>), Pointer(Box>), ConstPointer(Box>), - USize, Builtin(BuiltinType), Ident(wast::Id<'a>), } @@ -357,7 +356,7 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) } else if l.peek::() { parser.parse::()?; - Ok(TypedefSyntax::USize) + Ok(TypedefSyntax::Builtin(BuiltinType::USize)) } else { Err(l.error()) } diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index a8f3ddf2d..a1a6ff58a 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -79,6 +79,7 @@ impl BuiltinType { match self { BuiltinType::String => SExpr::word("string"), BuiltinType::Char8 => SExpr::word("char8"), + BuiltinType::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), BuiltinType::U8 => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), BuiltinType::U32 => SExpr::word("u32"), @@ -132,7 +133,6 @@ impl Type { SExpr::word("const_pointer"), p.to_sexpr(), ]), - Type::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), Type::Builtin(b) => b.to_sexpr(), } } diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 518564371..b640ba99d 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -255,7 +255,6 @@ impl DocValidationScope<'_> { TypedefSyntax::ConstPointer(syntax) => { Type::ConstPointer(self.validate_datatype(syntax, false, span)?) } - TypedefSyntax::USize => Type::USize, TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), TypedefSyntax::Ident { .. } => unreachable!(), }))), From 7d741f8e88cb97b7925dd60bc5ab6cd5112ee4a5 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Sat, 28 Dec 2019 09:56:18 -0800 Subject: [PATCH 0423/1772] witx: make USize a BuiltinType --- proposals/filesystem/tools/witx/src/ast.rs | 3 +-- proposals/filesystem/tools/witx/src/coretypes.rs | 7 +++---- proposals/filesystem/tools/witx/src/docs.rs | 3 +-- proposals/filesystem/tools/witx/src/layout.rs | 6 ++---- proposals/filesystem/tools/witx/src/parser.rs | 3 +-- proposals/filesystem/tools/witx/src/render.rs | 2 +- proposals/filesystem/tools/witx/src/validate.rs | 1 - 7 files changed, 9 insertions(+), 16 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index cf9e2845d..fcb33ad44 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -150,7 +150,6 @@ pub enum Type { Array(TypeRef), Pointer(TypeRef), ConstPointer(TypeRef), - USize, Builtin(BuiltinType), } @@ -167,7 +166,6 @@ impl Type { Array(_) => "array", Pointer(_) => "pointer", ConstPointer(_) => "constpointer", - USize => "usize", Builtin(_) => "builtin", } } @@ -177,6 +175,7 @@ impl Type { pub enum BuiltinType { String, Char8, + USize, U8, U16, U32, diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index 49d4292cf..84756209d 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -42,15 +42,14 @@ impl Type { | BuiltinType::S8 | BuiltinType::S16 | BuiltinType::S32 - | BuiltinType::Char8 => TypePassedBy::Value(AtomType::I32), + | BuiltinType::Char8 + | BuiltinType::USize => TypePassedBy::Value(AtomType::I32), BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), }, Type::Array { .. } => TypePassedBy::PointerLengthPair, - Type::Pointer { .. } | Type::ConstPointer { .. } | Type::USize => { - TypePassedBy::Value(AtomType::I32) - } + Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs index f6d4566e3..1d7572949 100644 --- a/proposals/filesystem/tools/witx/src/docs.rs +++ b/proposals/filesystem/tools/witx/src/docs.rs @@ -26,6 +26,7 @@ impl BuiltinType { match self { BuiltinType::String => "string", BuiltinType::Char8 => "char8", + BuiltinType::USize => "usize", BuiltinType::U8 => "u8", BuiltinType::U16 => "u16", BuiltinType::U32 => "u32", @@ -53,7 +54,6 @@ impl Documentation for NamedType { Type::Array(a) => format!("Array of {}", a.type_name()), Type::Pointer(a) => format!("Pointer to {}", a.type_name()), Type::ConstPointer(a) => format!("Constant Pointer to {}", a.type_name()), - Type::USize => format!("USize"), Type::Builtin(a) => format!("Builtin type {}", a.type_name()), }, TypeRef::Name(n) => format!("Alias to {}", n.name.as_str()), @@ -70,7 +70,6 @@ impl TypeRef { Type::Array(a) => format!("Array<{}>", a.type_name()), Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), - Type::USize => format!("USize"), Type::Builtin(b) => b.type_name().to_string(), Type::Enum { .. } | Type::Int { .. } diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index 3d265639f..cd3bd7da9 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -30,9 +30,7 @@ impl TypeRef { Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::Array { .. } => BuiltinType::String.mem_size_align(), - Type::Pointer { .. } | Type::ConstPointer { .. } | Type::USize => { - BuiltinType::U32.mem_size_align() - } + Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), }; cache.insert(self.clone(), layout); @@ -177,7 +175,7 @@ impl Layout for BuiltinType { SizeAlign { size: 1, align: 1 } } BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, - BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { + BuiltinType::USize | BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { SizeAlign { size: 4, align: 4 } } BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index fadd43578..08bc9af5b 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -316,7 +316,6 @@ pub enum TypedefSyntax<'a> { Array(Box>), Pointer(Box>), ConstPointer(Box>), - USize, Builtin(BuiltinType), Ident(wast::Id<'a>), } @@ -357,7 +356,7 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) } else if l.peek::() { parser.parse::()?; - Ok(TypedefSyntax::USize) + Ok(TypedefSyntax::Builtin(BuiltinType::USize)) } else { Err(l.error()) } diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index a8f3ddf2d..a1a6ff58a 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -79,6 +79,7 @@ impl BuiltinType { match self { BuiltinType::String => SExpr::word("string"), BuiltinType::Char8 => SExpr::word("char8"), + BuiltinType::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), BuiltinType::U8 => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), BuiltinType::U32 => SExpr::word("u32"), @@ -132,7 +133,6 @@ impl Type { SExpr::word("const_pointer"), p.to_sexpr(), ]), - Type::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), Type::Builtin(b) => b.to_sexpr(), } } diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 518564371..b640ba99d 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -255,7 +255,6 @@ impl DocValidationScope<'_> { TypedefSyntax::ConstPointer(syntax) => { Type::ConstPointer(self.validate_datatype(syntax, false, span)?) } - TypedefSyntax::USize => Type::USize, TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), TypedefSyntax::Ident { .. } => unreachable!(), }))), From 847ff885e0a171e054203bc2f6e6457d93bf7afc Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Sun, 5 Jan 2020 22:00:05 -0800 Subject: [PATCH 0424/1772] wasi_unstable_preview1.md: fix deleted field, reported in #188 --- .../clocks/phases/snapshot/docs/wasi_unstable_preview1.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md b/proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md index 6de15f1d2..47e1df0a0 100644 --- a/proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md +++ b/proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md @@ -2286,10 +2286,6 @@ Members: - **`u.clock`** - - [\_\_wasi\_userdata\_t](#userdata) identifier - - The user-defined unique identifier of the clock. - - [\_\_wasi\_clockid\_t](#clockid) clock\_id The clock against which to compare the timestamp. From f88442c34666ad56fad8fb697205e0b0c46f8257 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Sun, 5 Jan 2020 22:00:05 -0800 Subject: [PATCH 0425/1772] wasi_unstable_preview1.md: fix deleted field, reported in #188 --- .../random/phases/snapshot/docs/wasi_unstable_preview1.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md b/proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md index 6de15f1d2..47e1df0a0 100644 --- a/proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md +++ b/proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md @@ -2286,10 +2286,6 @@ Members: - **`u.clock`** - - [\_\_wasi\_userdata\_t](#userdata) identifier - - The user-defined unique identifier of the clock. - - [\_\_wasi\_clockid\_t](#clockid) clock\_id The clock against which to compare the timestamp. From 0bfbc735ca45eca4cdda98a25b0289873bf02528 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Sun, 5 Jan 2020 22:00:05 -0800 Subject: [PATCH 0426/1772] wasi_unstable_preview1.md: fix deleted field, reported in #188 --- .../filesystem/phases/snapshot/docs/wasi_unstable_preview1.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md b/proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md index 6de15f1d2..47e1df0a0 100644 --- a/proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md +++ b/proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md @@ -2286,10 +2286,6 @@ Members: - **`u.clock`** - - [\_\_wasi\_userdata\_t](#userdata) identifier - - The user-defined unique identifier of the clock. - - [\_\_wasi\_clockid\_t](#clockid) clock\_id The clock against which to compare the timestamp. From 1712a6819cdb6f26dde96c29b5a19144dfd5c42b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 7 Jan 2020 14:19:54 -0800 Subject: [PATCH 0427/1772] Update phases/snapshot/docs/wasi_unstable_preview1.md Co-Authored-By: Jakub Konka --- .../clocks/phases/snapshot/docs/wasi_unstable_preview1.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md b/proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md index 47e1df0a0..7aa5816af 100644 --- a/proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md +++ b/proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md @@ -2286,7 +2286,7 @@ Members: - **`u.clock`** - - [\_\_wasi\_clockid\_t](#clockid) clock\_id + - [\_\_wasi\_clockid\_t](#clockid) id The clock against which to compare the timestamp. @@ -2344,4 +2344,3 @@ Possible values: - **`__WASI_WHENCE_END`** Seek relative to end-of-file. - From 22fe578e30dc0836281cd0b19d2709d330be2c25 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 7 Jan 2020 14:19:54 -0800 Subject: [PATCH 0428/1772] Update phases/snapshot/docs/wasi_unstable_preview1.md Co-Authored-By: Jakub Konka --- .../random/phases/snapshot/docs/wasi_unstable_preview1.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md b/proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md index 47e1df0a0..7aa5816af 100644 --- a/proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md +++ b/proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md @@ -2286,7 +2286,7 @@ Members: - **`u.clock`** - - [\_\_wasi\_clockid\_t](#clockid) clock\_id + - [\_\_wasi\_clockid\_t](#clockid) id The clock against which to compare the timestamp. @@ -2344,4 +2344,3 @@ Possible values: - **`__WASI_WHENCE_END`** Seek relative to end-of-file. - From 453108bf1937e04165dceaeefe1a3b32950db664 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 7 Jan 2020 14:19:54 -0800 Subject: [PATCH 0429/1772] Update phases/snapshot/docs/wasi_unstable_preview1.md Co-Authored-By: Jakub Konka --- .../filesystem/phases/snapshot/docs/wasi_unstable_preview1.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md b/proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md index 47e1df0a0..7aa5816af 100644 --- a/proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md +++ b/proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md @@ -2286,7 +2286,7 @@ Members: - **`u.clock`** - - [\_\_wasi\_clockid\_t](#clockid) clock\_id + - [\_\_wasi\_clockid\_t](#clockid) id The clock against which to compare the timestamp. @@ -2344,4 +2344,3 @@ Possible values: - **`__WASI_WHENCE_END`** Seek relative to end-of-file. - From 125974b4b033b757d5f5df42c30b838e92a9e3d5 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 9 Jan 2020 05:45:14 +0545 Subject: [PATCH 0430/1772] Add FIFO filetype to match POSIX (#189) Every other filetype defined by POSIX for stat is in here, so add FIFO to round things out. --- proposals/clocks/phases/ephemeral/witx/typenames.witx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 8b2165eb6..f3b7c83e5 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -351,6 +351,8 @@ $socket_stream ;;; The file refers to a symbolic link inode. $symbolic_link + ;;; The file descriptor or file refers to a FIFO. + $fifo ) ) From 8a68af8f68b9be73057f655cfe081285762fc9b4 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 9 Jan 2020 05:45:14 +0545 Subject: [PATCH 0431/1772] Add FIFO filetype to match POSIX (#189) Every other filetype defined by POSIX for stat is in here, so add FIFO to round things out. --- proposals/random/phases/ephemeral/witx/typenames.witx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 8b2165eb6..f3b7c83e5 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -351,6 +351,8 @@ $socket_stream ;;; The file refers to a symbolic link inode. $symbolic_link + ;;; The file descriptor or file refers to a FIFO. + $fifo ) ) From 817e41d85c9aa7da3400b1104806672328bfa4fe Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 9 Jan 2020 05:45:14 +0545 Subject: [PATCH 0432/1772] Add FIFO filetype to match POSIX (#189) Every other filetype defined by POSIX for stat is in here, so add FIFO to round things out. --- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 8b2165eb6..f3b7c83e5 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -351,6 +351,8 @@ $socket_stream ;;; The file refers to a symbolic link inode. $symbolic_link + ;;; The file descriptor or file refers to a FIFO. + $fifo ) ) From 7298ed154f2c6435d3f1e0bc0c0c09d63f388659 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 9 Jan 2020 17:05:35 -0800 Subject: [PATCH 0433/1772] Add an agenda for the 01-16 meeting. (#195) --- proposals/clocks/meetings/2020/WASI-01-16.md | 34 ++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-01-16.md diff --git a/proposals/clocks/meetings/2020/WASI-01-16.md b/proposals/clocks/meetings/2020/WASI-01-16.md new file mode 100644 index 000000000..801786c56 --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-01-16.md @@ -0,0 +1,34 @@ +![WASI logo](/WASI.png) + +## Agenda for the January 16 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: January 16, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. WASI design principles PR: + 1. https://github.com/WebAssembly/WASI/pull/192 + 1. What should `poll` for no events do? + 1. https://github.com/WebAssembly/WASI/pull/193 + +## Meeting Notes From e4929fc4f1ac8e34b7d7fd71df9bb9c1cdd68a49 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 9 Jan 2020 17:05:35 -0800 Subject: [PATCH 0434/1772] Add an agenda for the 01-16 meeting. (#195) --- proposals/random/meetings/2020/WASI-01-16.md | 34 ++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-01-16.md diff --git a/proposals/random/meetings/2020/WASI-01-16.md b/proposals/random/meetings/2020/WASI-01-16.md new file mode 100644 index 000000000..801786c56 --- /dev/null +++ b/proposals/random/meetings/2020/WASI-01-16.md @@ -0,0 +1,34 @@ +![WASI logo](/WASI.png) + +## Agenda for the January 16 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: January 16, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. WASI design principles PR: + 1. https://github.com/WebAssembly/WASI/pull/192 + 1. What should `poll` for no events do? + 1. https://github.com/WebAssembly/WASI/pull/193 + +## Meeting Notes From 7578ce8df950eee18c3f669be3ab9dce5164173d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 9 Jan 2020 17:05:35 -0800 Subject: [PATCH 0435/1772] Add an agenda for the 01-16 meeting. (#195) --- .../filesystem/meetings/2020/WASI-01-16.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-01-16.md diff --git a/proposals/filesystem/meetings/2020/WASI-01-16.md b/proposals/filesystem/meetings/2020/WASI-01-16.md new file mode 100644 index 000000000..801786c56 --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-01-16.md @@ -0,0 +1,34 @@ +![WASI logo](/WASI.png) + +## Agenda for the January 16 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: January 16, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. WASI design principles PR: + 1. https://github.com/WebAssembly/WASI/pull/192 + 1. What should `poll` for no events do? + 1. https://github.com/WebAssembly/WASI/pull/193 + +## Meeting Notes From eaa6357531bba098a1d0c7b0ef6187bf0835451f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 9 Jan 2020 17:06:12 -0800 Subject: [PATCH 0436/1772] Add the 01-16 meeting to the meeting index too. --- proposals/clocks/meetings/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 08acc5d84..d0461d30e 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -23,3 +23,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI November 21st video call](2019/WASI-11-21.md) * [WASI December 5th video call](2019/WASI-12-05.md) * [WASI December 19th video call](2019/WASI-12-19.md) + * [WASI January 16th video call](2020/WASI-01-16.md) From 95f104aba7a8443461d1faa3445df01086f1f645 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 9 Jan 2020 17:06:12 -0800 Subject: [PATCH 0437/1772] Add the 01-16 meeting to the meeting index too. --- proposals/random/meetings/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 08acc5d84..d0461d30e 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -23,3 +23,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI November 21st video call](2019/WASI-11-21.md) * [WASI December 5th video call](2019/WASI-12-05.md) * [WASI December 19th video call](2019/WASI-12-19.md) + * [WASI January 16th video call](2020/WASI-01-16.md) From 7ef88cc203b1b5f1de9e0470e1bc8db54074012f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 9 Jan 2020 17:06:12 -0800 Subject: [PATCH 0438/1772] Add the 01-16 meeting to the meeting index too. --- proposals/filesystem/meetings/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 08acc5d84..d0461d30e 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -23,3 +23,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI November 21st video call](2019/WASI-11-21.md) * [WASI December 5th video call](2019/WASI-12-05.md) * [WASI December 19th video call](2019/WASI-12-19.md) + * [WASI January 16th video call](2020/WASI-01-16.md) From 115837d58046cac0a0f73f2a4317fc68077716dc Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 8 Jan 2020 23:01:25 +0100 Subject: [PATCH 0439/1772] Clean up Markdown generation from witx This commit tweaks `docs.rs` module of the `witx` tool facilitating generation of Markdown documentation from `*.witx` files which * is formatted in a more readable way * inserts HTML links for each header but also a list entry (in the latter case, the link is scoped; i.e., it includes the link id of the enclosing Markdown section) --- proposals/clocks/tools/witx/src/docs.rs | 661 +++++++++++++++++------- 1 file changed, 481 insertions(+), 180 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs index 1d7572949..2e358b15e 100644 --- a/proposals/clocks/tools/witx/src/docs.rs +++ b/proposals/clocks/tools/witx/src/docs.rs @@ -1,23 +1,349 @@ use crate::ast::*; use crate::polyfill::*; use crate::RepEquality; +use std::fmt; + +#[derive(Debug)] +pub enum MdBlockElement { + Section(MdSection), + TypeListing(MdTypeListing), + InterfaceFunc(MdInterfaceFunc), + Root(MdRoot), +} + +impl fmt::Display for MdBlockElement { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Section(sec) => sec.fmt(f), + Self::TypeListing(listing) => listing.fmt(f), + Self::InterfaceFunc(func) => func.fmt(f), + Self::Root(root) => root.fmt(f), + } + } +} + +#[derive(Debug, Default)] +pub struct MdRoot { + blocks: Vec, +} + +impl fmt::Display for MdRoot { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for block in &self.blocks { + block.fmt(f)?; + } + Ok(()) + } +} + +#[derive(Debug, Clone)] +struct MdParagraph { + para: String, +} + +impl MdParagraph { + fn new>(para: S) -> Self { + Self { + para: para.as_ref().to_owned(), + } + } + + fn with_links_parsed>(para: S) -> Self { + let to_parse = para.as_ref(); + let mut parsed = String::with_capacity(to_parse.len()); + let mut temp = String::with_capacity(to_parse.len()); + let mut is_link = false; + let mut eaten = None; + for ch in to_parse.chars() { + match (ch, is_link) { + ('`', false) => { + // found the beginning of a link + is_link = true; + } + ('`', true) => { + // reached the end, expand into a link! + let expanded = format!("[`{}`](#{})", temp, temp); + parsed.push_str(&expanded); + temp.drain(..); + is_link = false; + } + (':', true) => { + if let Some(_) = eaten { + // swap for '.' + temp.push('.'); + eaten = None; + } else { + eaten = Some(':'); + } + } + (ch, false) => parsed.push(ch), + (ch, true) => temp.push(ch), + } + } + Self::new(parsed) + } +} + +impl fmt::Display for MdParagraph { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_fmt(format_args!("{}\n", &self.para)) + } +} + +#[allow(dead_code)] +#[derive(Debug, Clone)] +enum MdHeading { + Header { + id: String, + title: String, + doc_level: usize, + }, + Bullet { + id: String, + title: String, + }, +} + +impl MdHeading { + fn new_header>(title: S, doc_level: usize) -> Self { + let id = title.as_ref().replace(" ", "_"); + let title = title.as_ref().to_owned(); + Self::Header { + id, + title, + doc_level, + } + } + + fn new_bullet>(title: S) -> Self { + let id = title.as_ref().replace(" ", "_"); + let title = title.as_ref().to_owned(); + Self::Bullet { id, title } + } + + fn id(&self) -> &str { + match self { + Self::Header { ref id, .. } => id, + Self::Bullet { ref id, .. } => id, + } + } + + fn set_id>(&mut self, id: S) { + let s_id = match self { + Self::Header { ref mut id, .. } => id, + Self::Bullet { ref mut id, .. } => id, + }; + *s_id = id.as_ref().to_owned(); + } +} + +impl fmt::Display for MdHeading { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let (id, title, heading) = match self { + Self::Header { + id, + title, + doc_level, + } => (id, title, "#".repeat(*doc_level)), + Self::Bullet { id, title } => (id, title, "-".to_owned()), + }; + f.write_fmt(format_args!( + "{heading} {title}\n", + heading = heading, + id = id, + title = title + )) + } +} + +#[derive(Debug)] +pub struct MdSection { + heading: MdHeading, + description: Vec, + blocks: Vec, +} + +impl MdSection { + fn new(heading: MdHeading) -> Self { + Self { + heading, + description: vec![], + blocks: vec![], + } + } +} + +impl fmt::Display for MdSection { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.heading.fmt(f)?; + for para in &self.description { + para.fmt(f)?; + } + for el in &self.blocks { + el.fmt(f)?; + } + Ok(()) + } +} + +#[allow(dead_code)] +#[derive(Debug)] +enum MdType { + Enum { repr: String }, + Int { repr: String }, + Flags { repr: String }, + Struct, + Union, + Handle, + Array { r#type: String }, + Pointer { to: String }, + ConstPointer { to: String }, + Builtin { r#type: String }, +} + +impl fmt::Display for MdType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let type_specific = match self { + MdType::Enum { repr } => format!("Enum represented by `{}`\n\n**Variants:**", repr), + MdType::Int { repr } => format!("Int represented by `{}`\n\n**Const:**", repr), + MdType::Flags { repr } => format!("Flags represented by `{}`\n\n**Flags:**", repr), + MdType::Struct => "\n**Struct members:**".to_owned(), + MdType::Union => "\n**Union variants:**".to_owned(), + MdType::Handle => "\n**Supertypes:**".to_owned(), + MdType::Array { r#type } => format!("Array of `{}`", r#type), + MdType::Pointer { to } => format!("Pointer to `{}`", to), + MdType::ConstPointer { to } => format!("Const pointer to `{}`", to), + MdType::Builtin { r#type } => format!("Builtin type `{}`", r#type), + }; + f.write_fmt(format_args!("{}\n", type_specific)) + } +} + +#[derive(Debug, Clone)] +struct MdListingEntry { + heading: MdHeading, + description: Vec, +} + +impl fmt::Display for MdListingEntry { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.heading.fmt(f)?; + for para in &self.description { + f.write_fmt(format_args!("\n\t{}\n", para))?; + } + Ok(()) + } +} + +#[derive(Debug)] +pub struct MdTypeListing { + heading: MdHeading, + r#type: MdType, + description: Vec, + entries: Vec, +} + +impl MdTypeListing { + fn new(heading: MdHeading, r#type: MdType) -> Self { + Self { + heading, + r#type, + description: vec![], + entries: vec![], + } + } +} + +impl fmt::Display for MdTypeListing { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.heading.fmt(f)?; + for para in &self.description { + para.fmt(f)?; + } + self.r#type.fmt(f)?; + for el in &self.entries { + // prepend id of this MdTypeListing in order to generate scoped + // references of list entries + let id = format!("{}.{}", self.heading.id(), el.heading.id()); + let mut new_el = el.clone(); + new_el.heading.set_id(id); + new_el.fmt(f)?; + } + Ok(()) + } +} + +#[derive(Debug)] +pub struct MdInterfaceFunc { + heading: MdHeading, + description: Vec, + parameters: Vec, + results: Vec, +} + +impl MdInterfaceFunc { + fn new(heading: MdHeading) -> Self { + Self { + heading, + description: vec![], + parameters: vec![], + results: vec![], + } + } +} + +impl fmt::Display for MdInterfaceFunc { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.heading.fmt(f)?; + for desc in &self.description { + desc.fmt(f)?; + } + f.write_str("\n**Parameters:**\n\n")?; + for el in &self.parameters { + // prepend id of this MdTypeListing in order to generate scoped + // references of list entries + let id = format!("{}.{}", self.heading.id(), el.heading.id()); + let mut new_el = el.clone(); + new_el.heading.set_id(id); + new_el.fmt(f)?; + } + f.write_str("\n**Results:**\n\n")?; + for el in &self.results { + // prepend id of this MdTypeListing in order to generate scoped + // references of list entries + let id = format!("{}.{}", self.heading.id(), el.heading.id()); + let mut new_el = el.clone(); + new_el.heading.set_id(id); + new_el.fmt(f)?; + } + Ok(()) + } +} pub trait Documentation { - fn to_md(&self) -> String; + fn to_md(&self) -> String { + format!("{}", self.gen(0)) + } + + fn gen(&self, _level: usize) -> MdBlockElement { + MdBlockElement::Root(MdRoot::default()) + } } impl Documentation for Document { - fn to_md(&self) -> String { - let mut ret = "# Types\n".to_string(); - for d in self.typenames() { - ret += &d.to_md(); + fn gen(&self, level: usize) -> MdBlockElement { + let mut doc = MdRoot::default(); + let mut types = MdSection::new(MdHeading::new_header("Types", level + 1)); + for typename in self.typenames() { + types.blocks.push(typename.gen(level + 2)); } - - ret += "\n# Modules\n"; - for m in self.modules() { - ret += &m.to_md(); + doc.blocks.push(MdBlockElement::Section(types)); + let mut modules = MdSection::new(MdHeading::new_header("Modules", level + 1)); + for module in self.modules() { + modules.blocks.push(module.gen(level + 2)); } - ret + doc.blocks.push(MdBlockElement::Section(modules)); + MdBlockElement::Root(doc) } } @@ -42,23 +368,104 @@ impl BuiltinType { } impl Documentation for NamedType { - fn to_md(&self) -> String { - let body = match &self.tref { - TypeRef::Value(v) => match &**v { - Type::Enum(a) => a.to_md(), - Type::Int(a) => a.to_md(), - Type::Flags(a) => a.to_md(), - Type::Struct(a) => a.to_md(), - Type::Union(a) => a.to_md(), - Type::Handle(a) => a.to_md(), - Type::Array(a) => format!("Array of {}", a.type_name()), - Type::Pointer(a) => format!("Pointer to {}", a.type_name()), - Type::ConstPointer(a) => format!("Constant Pointer to {}", a.type_name()), - Type::Builtin(a) => format!("Builtin type {}", a.type_name()), + fn gen(&self, level: usize) -> MdBlockElement { + match &self.tref { + TypeRef::Value(v) => { + let md_type = MdType::from(&**v); + let mut entries: Vec<_> = match &**v { + Type::Enum(a) => a.variants.iter().map(MdListingEntry::from).collect(), + Type::Int(a) => a.consts.iter().map(MdListingEntry::from).collect(), + Type::Flags(a) => a.flags.iter().map(MdListingEntry::from).collect(), + Type::Struct(a) => a.members.iter().map(MdListingEntry::from).collect(), + Type::Union(a) => a.variants.iter().map(MdListingEntry::from).collect(), + Type::Handle(a) => a.supertypes.iter().map(MdListingEntry::from).collect(), + _ => vec![], + }; + let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); + heading.set_id(self.name.as_str()); + let mut listing = MdTypeListing::new(heading, md_type); + listing + .description + .push(MdParagraph::with_links_parsed(&self.docs)); + listing.entries.append(&mut entries); + MdBlockElement::TypeListing(listing) + } + TypeRef::Name(n) => { + let mut heading = MdHeading::new_header(self.name.as_str(), level); + heading.set_id(self.name.as_str()); + let mut sec = MdSection::new(heading); + sec.description + .push(MdParagraph::with_links_parsed(&self.docs)); + sec.description.push(MdParagraph::with_links_parsed(format!( + "Alias to {}", + n.name.as_str() + ))); + MdBlockElement::Section(sec) + } + } + } +} + +impl From<&Type> for MdType { + fn from(r#type: &Type) -> Self { + match r#type { + Type::Enum(a) => Self::Enum { + repr: a.repr.type_name().to_owned(), }, - TypeRef::Name(n) => format!("Alias to {}", n.name.as_str()), - }; - format!("## `{}`\n{}\n{}\n", self.name.as_str(), self.docs, body,) + Type::Int(a) => Self::Int { + repr: a.repr.type_name().to_owned(), + }, + Type::Flags(a) => Self::Flags { + repr: a.repr.type_name().to_owned(), + }, + Type::Struct(_) => Self::Struct, + Type::Union(_) => Self::Union, + Type::Handle(_) => Self::Handle, + Type::Array(a) => Self::Array { + r#type: a.type_name().to_owned(), + }, + Type::Pointer(a) => Self::Pointer { + to: a.type_name().to_owned(), + }, + Type::ConstPointer(a) => Self::ConstPointer { + to: a.type_name().to_owned(), + }, + Type::Builtin(a) => Self::Builtin { + r#type: a.type_name().to_owned(), + }, + } + } +} + +macro_rules! impl_mdlistingentry { + ($from:ty) => { + impl From<$from> for MdListingEntry { + fn from(f: $from) -> Self { + let mut heading = MdHeading::new_bullet(format!("`{}`", f.name.as_str())); + heading.set_id(f.name.as_str()); + Self { + heading, + description: vec![MdParagraph::with_links_parsed(&f.docs)], + } + } + } + }; +} + +impl_mdlistingentry!(&EnumVariant); +impl_mdlistingentry!(&IntConst); +impl_mdlistingentry!(&FlagsMember); +impl_mdlistingentry!(&StructMember); +impl_mdlistingentry!(&UnionVariant); + +impl From<&TypeRef> for MdListingEntry { + fn from(t: &TypeRef) -> Self { + let mut heading = MdHeading::new_bullet(format!("`{}`", t.type_name())); + heading.set_id(t.type_name()); + Self { + heading, + description: vec![], + } } } @@ -84,103 +491,6 @@ impl TypeRef { } } -impl Documentation for EnumDatatype { - fn to_md(&self) -> String { - let variants = self - .variants - .iter() - .map(|v| format!("#### `{}`\n{}", v.name.as_str(), v.docs)) - .collect::>() - .join("\n"); - format!( - "Enum represented by `{}`\n\n### Variants:\n{}\n", - self.repr.type_name(), - variants - ) - } -} - -impl Documentation for IntDatatype { - fn to_md(&self) -> String { - let consts = self - .consts - .iter() - .map(|v| format!("#### `{}`: {}\n{}", v.name.as_str(), v.value, v.docs)) - .collect::>() - .join("\n"); - format!( - "Int represented by `{}`\n\n### Consts:\n{}\n", - self.repr.type_name(), - consts - ) - } -} - -impl Documentation for FlagsDatatype { - fn to_md(&self) -> String { - let flags = self - .flags - .iter() - .map(|f| format!("#### `{}`\n{}\n", f.name.as_str(), f.docs)) - .collect::>() - .join("\n"); - format!( - "Flags represented by `{}`\n\n### Flags:\n{}", - self.repr.type_name(), - flags - ) - } -} - -impl Documentation for StructDatatype { - fn to_md(&self) -> String { - let members = self - .members - .iter() - .map(|m| { - format!( - "#### `{}`\nMember type: `{}`\n{}", - m.name.as_str(), - m.tref.type_name(), - m.docs, - ) - }) - .collect::>() - .join("\n"); - format!("### Struct members:\n{}", members) - } -} - -impl Documentation for UnionDatatype { - fn to_md(&self) -> String { - let variants = self - .variants - .iter() - .map(|v| { - format!( - "#### `{}`\nVariant type: `{}`\n{}", - v.name.as_str(), - v.tref.type_name(), - v.docs, - ) - }) - .collect::>() - .join("\n"); - format!("### Union variants:\n{}\n", variants) - } -} - -impl Documentation for HandleDatatype { - fn to_md(&self) -> String { - let supertypes = self - .supertypes - .iter() - .map(|s| format!("* {}", s.type_name())) - .collect::>() - .join("\n"); - format!("### Handle supertypes:\n{}\n", supertypes) - } -} impl IntRepr { fn type_name(&self) -> &'static str { match self { @@ -193,72 +503,63 @@ impl IntRepr { } impl Documentation for Module { - fn to_md(&self) -> String { - let imports = self - .imports() - .map(|i| i.to_md()) - .collect::>() - .join("\n"); - let funcs = self - .funcs() - .map(|i| i.to_md()) - .collect::>() - .join("\n"); - format!( - "## `{}`\n### Imports\n{}\n### Functions\n{}", - self.name.as_str(), - imports, - funcs, - ) + fn gen(&self, level: usize) -> MdBlockElement { + let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); + heading.set_id(self.name.as_str()); + let mut sec = MdSection::new(heading); + let mut imports = MdSection::new(MdHeading::new_header("Imports", level + 1)); + // FIXME + for import in self.imports() { + let desc = match import.variant { + ModuleImportVariant::Memory => { + MdParagraph::with_links_parsed(format!("* {}: Memory", import.name.as_str())) + } + }; + imports.description.push(desc); + } + sec.blocks.push(MdBlockElement::Section(imports)); + let mut funcs = MdSection::new(MdHeading::new_header("Functions", level + 1)); + funcs.blocks.extend(self.funcs().map(|f| f.gen(level + 2))); + sec.blocks.push(MdBlockElement::Section(funcs)); + MdBlockElement::Section(sec) } } -impl Documentation for ModuleImport { - fn to_md(&self) -> String { - match self.variant { - ModuleImportVariant::Memory => format!("* {}: Memory", self.name.as_str()), - } +impl Documentation for InterfaceFunc { + fn gen(&self, level: usize) -> MdBlockElement { + let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); + heading.set_id(self.name.as_str()); + let mut func = MdInterfaceFunc::new(heading); + func.description + .push(MdParagraph::with_links_parsed(&self.docs)); + func.parameters + .extend(self.params.iter().map(MdListingEntry::from)); + func.results + .extend(self.results.iter().map(MdListingEntry::from)); + MdBlockElement::InterfaceFunc(func) } } -impl Documentation for InterfaceFunc { - fn to_md(&self) -> String { - let params = self - .params - .iter() - .map(|f| { - format!( - "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", - name = f.name.as_str(), - type_ = f.tref.type_name(), - docs = f.docs - ) - }) - .collect::>() - .join("\n"); - let results = self - .results - .iter() - .map(|f| { - format!( - "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", - name = f.name.as_str(), - type_ = f.tref.type_name(), - docs = f.docs - ) - }) - .collect::>() - .join("\n"); - format!( - "### {}\n{}\n#### Parameters:\n{}#### Results:\n{}", - self.name.as_str(), - self.docs, - params, - results, - ) +impl From<&InterfaceFuncParam> for MdListingEntry { + fn from(param: &InterfaceFuncParam) -> Self { + let mut heading = MdHeading::new_bullet(format!("`{}`", param.name.as_str())); + heading.set_id(param.name.as_str()); + let mut description = vec![]; + description.push(MdParagraph::with_links_parsed(format!( + "`{}` has type `{}`.", + param.name.as_str(), + param.tref.type_name() + ))); + description.push(MdParagraph::with_links_parsed(¶m.docs)); + Self { + heading, + description, + } } } +// TODO +// Generate nicely-formatted docs for polyfill impl Documentation for Polyfill { fn to_md(&self) -> String { let module_docs = self From 7f11908488a6889b1e03d2be33ef6612b38cf7bd Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 8 Jan 2020 23:01:25 +0100 Subject: [PATCH 0440/1772] Clean up Markdown generation from witx This commit tweaks `docs.rs` module of the `witx` tool facilitating generation of Markdown documentation from `*.witx` files which * is formatted in a more readable way * inserts HTML links for each header but also a list entry (in the latter case, the link is scoped; i.e., it includes the link id of the enclosing Markdown section) --- proposals/random/tools/witx/src/docs.rs | 661 +++++++++++++++++------- 1 file changed, 481 insertions(+), 180 deletions(-) diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs index 1d7572949..2e358b15e 100644 --- a/proposals/random/tools/witx/src/docs.rs +++ b/proposals/random/tools/witx/src/docs.rs @@ -1,23 +1,349 @@ use crate::ast::*; use crate::polyfill::*; use crate::RepEquality; +use std::fmt; + +#[derive(Debug)] +pub enum MdBlockElement { + Section(MdSection), + TypeListing(MdTypeListing), + InterfaceFunc(MdInterfaceFunc), + Root(MdRoot), +} + +impl fmt::Display for MdBlockElement { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Section(sec) => sec.fmt(f), + Self::TypeListing(listing) => listing.fmt(f), + Self::InterfaceFunc(func) => func.fmt(f), + Self::Root(root) => root.fmt(f), + } + } +} + +#[derive(Debug, Default)] +pub struct MdRoot { + blocks: Vec, +} + +impl fmt::Display for MdRoot { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for block in &self.blocks { + block.fmt(f)?; + } + Ok(()) + } +} + +#[derive(Debug, Clone)] +struct MdParagraph { + para: String, +} + +impl MdParagraph { + fn new>(para: S) -> Self { + Self { + para: para.as_ref().to_owned(), + } + } + + fn with_links_parsed>(para: S) -> Self { + let to_parse = para.as_ref(); + let mut parsed = String::with_capacity(to_parse.len()); + let mut temp = String::with_capacity(to_parse.len()); + let mut is_link = false; + let mut eaten = None; + for ch in to_parse.chars() { + match (ch, is_link) { + ('`', false) => { + // found the beginning of a link + is_link = true; + } + ('`', true) => { + // reached the end, expand into a link! + let expanded = format!("[`{}`](#{})", temp, temp); + parsed.push_str(&expanded); + temp.drain(..); + is_link = false; + } + (':', true) => { + if let Some(_) = eaten { + // swap for '.' + temp.push('.'); + eaten = None; + } else { + eaten = Some(':'); + } + } + (ch, false) => parsed.push(ch), + (ch, true) => temp.push(ch), + } + } + Self::new(parsed) + } +} + +impl fmt::Display for MdParagraph { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_fmt(format_args!("{}\n", &self.para)) + } +} + +#[allow(dead_code)] +#[derive(Debug, Clone)] +enum MdHeading { + Header { + id: String, + title: String, + doc_level: usize, + }, + Bullet { + id: String, + title: String, + }, +} + +impl MdHeading { + fn new_header>(title: S, doc_level: usize) -> Self { + let id = title.as_ref().replace(" ", "_"); + let title = title.as_ref().to_owned(); + Self::Header { + id, + title, + doc_level, + } + } + + fn new_bullet>(title: S) -> Self { + let id = title.as_ref().replace(" ", "_"); + let title = title.as_ref().to_owned(); + Self::Bullet { id, title } + } + + fn id(&self) -> &str { + match self { + Self::Header { ref id, .. } => id, + Self::Bullet { ref id, .. } => id, + } + } + + fn set_id>(&mut self, id: S) { + let s_id = match self { + Self::Header { ref mut id, .. } => id, + Self::Bullet { ref mut id, .. } => id, + }; + *s_id = id.as_ref().to_owned(); + } +} + +impl fmt::Display for MdHeading { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let (id, title, heading) = match self { + Self::Header { + id, + title, + doc_level, + } => (id, title, "#".repeat(*doc_level)), + Self::Bullet { id, title } => (id, title, "-".to_owned()), + }; + f.write_fmt(format_args!( + "{heading} {title}\n", + heading = heading, + id = id, + title = title + )) + } +} + +#[derive(Debug)] +pub struct MdSection { + heading: MdHeading, + description: Vec, + blocks: Vec, +} + +impl MdSection { + fn new(heading: MdHeading) -> Self { + Self { + heading, + description: vec![], + blocks: vec![], + } + } +} + +impl fmt::Display for MdSection { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.heading.fmt(f)?; + for para in &self.description { + para.fmt(f)?; + } + for el in &self.blocks { + el.fmt(f)?; + } + Ok(()) + } +} + +#[allow(dead_code)] +#[derive(Debug)] +enum MdType { + Enum { repr: String }, + Int { repr: String }, + Flags { repr: String }, + Struct, + Union, + Handle, + Array { r#type: String }, + Pointer { to: String }, + ConstPointer { to: String }, + Builtin { r#type: String }, +} + +impl fmt::Display for MdType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let type_specific = match self { + MdType::Enum { repr } => format!("Enum represented by `{}`\n\n**Variants:**", repr), + MdType::Int { repr } => format!("Int represented by `{}`\n\n**Const:**", repr), + MdType::Flags { repr } => format!("Flags represented by `{}`\n\n**Flags:**", repr), + MdType::Struct => "\n**Struct members:**".to_owned(), + MdType::Union => "\n**Union variants:**".to_owned(), + MdType::Handle => "\n**Supertypes:**".to_owned(), + MdType::Array { r#type } => format!("Array of `{}`", r#type), + MdType::Pointer { to } => format!("Pointer to `{}`", to), + MdType::ConstPointer { to } => format!("Const pointer to `{}`", to), + MdType::Builtin { r#type } => format!("Builtin type `{}`", r#type), + }; + f.write_fmt(format_args!("{}\n", type_specific)) + } +} + +#[derive(Debug, Clone)] +struct MdListingEntry { + heading: MdHeading, + description: Vec, +} + +impl fmt::Display for MdListingEntry { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.heading.fmt(f)?; + for para in &self.description { + f.write_fmt(format_args!("\n\t{}\n", para))?; + } + Ok(()) + } +} + +#[derive(Debug)] +pub struct MdTypeListing { + heading: MdHeading, + r#type: MdType, + description: Vec, + entries: Vec, +} + +impl MdTypeListing { + fn new(heading: MdHeading, r#type: MdType) -> Self { + Self { + heading, + r#type, + description: vec![], + entries: vec![], + } + } +} + +impl fmt::Display for MdTypeListing { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.heading.fmt(f)?; + for para in &self.description { + para.fmt(f)?; + } + self.r#type.fmt(f)?; + for el in &self.entries { + // prepend id of this MdTypeListing in order to generate scoped + // references of list entries + let id = format!("{}.{}", self.heading.id(), el.heading.id()); + let mut new_el = el.clone(); + new_el.heading.set_id(id); + new_el.fmt(f)?; + } + Ok(()) + } +} + +#[derive(Debug)] +pub struct MdInterfaceFunc { + heading: MdHeading, + description: Vec, + parameters: Vec, + results: Vec, +} + +impl MdInterfaceFunc { + fn new(heading: MdHeading) -> Self { + Self { + heading, + description: vec![], + parameters: vec![], + results: vec![], + } + } +} + +impl fmt::Display for MdInterfaceFunc { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.heading.fmt(f)?; + for desc in &self.description { + desc.fmt(f)?; + } + f.write_str("\n**Parameters:**\n\n")?; + for el in &self.parameters { + // prepend id of this MdTypeListing in order to generate scoped + // references of list entries + let id = format!("{}.{}", self.heading.id(), el.heading.id()); + let mut new_el = el.clone(); + new_el.heading.set_id(id); + new_el.fmt(f)?; + } + f.write_str("\n**Results:**\n\n")?; + for el in &self.results { + // prepend id of this MdTypeListing in order to generate scoped + // references of list entries + let id = format!("{}.{}", self.heading.id(), el.heading.id()); + let mut new_el = el.clone(); + new_el.heading.set_id(id); + new_el.fmt(f)?; + } + Ok(()) + } +} pub trait Documentation { - fn to_md(&self) -> String; + fn to_md(&self) -> String { + format!("{}", self.gen(0)) + } + + fn gen(&self, _level: usize) -> MdBlockElement { + MdBlockElement::Root(MdRoot::default()) + } } impl Documentation for Document { - fn to_md(&self) -> String { - let mut ret = "# Types\n".to_string(); - for d in self.typenames() { - ret += &d.to_md(); + fn gen(&self, level: usize) -> MdBlockElement { + let mut doc = MdRoot::default(); + let mut types = MdSection::new(MdHeading::new_header("Types", level + 1)); + for typename in self.typenames() { + types.blocks.push(typename.gen(level + 2)); } - - ret += "\n# Modules\n"; - for m in self.modules() { - ret += &m.to_md(); + doc.blocks.push(MdBlockElement::Section(types)); + let mut modules = MdSection::new(MdHeading::new_header("Modules", level + 1)); + for module in self.modules() { + modules.blocks.push(module.gen(level + 2)); } - ret + doc.blocks.push(MdBlockElement::Section(modules)); + MdBlockElement::Root(doc) } } @@ -42,23 +368,104 @@ impl BuiltinType { } impl Documentation for NamedType { - fn to_md(&self) -> String { - let body = match &self.tref { - TypeRef::Value(v) => match &**v { - Type::Enum(a) => a.to_md(), - Type::Int(a) => a.to_md(), - Type::Flags(a) => a.to_md(), - Type::Struct(a) => a.to_md(), - Type::Union(a) => a.to_md(), - Type::Handle(a) => a.to_md(), - Type::Array(a) => format!("Array of {}", a.type_name()), - Type::Pointer(a) => format!("Pointer to {}", a.type_name()), - Type::ConstPointer(a) => format!("Constant Pointer to {}", a.type_name()), - Type::Builtin(a) => format!("Builtin type {}", a.type_name()), + fn gen(&self, level: usize) -> MdBlockElement { + match &self.tref { + TypeRef::Value(v) => { + let md_type = MdType::from(&**v); + let mut entries: Vec<_> = match &**v { + Type::Enum(a) => a.variants.iter().map(MdListingEntry::from).collect(), + Type::Int(a) => a.consts.iter().map(MdListingEntry::from).collect(), + Type::Flags(a) => a.flags.iter().map(MdListingEntry::from).collect(), + Type::Struct(a) => a.members.iter().map(MdListingEntry::from).collect(), + Type::Union(a) => a.variants.iter().map(MdListingEntry::from).collect(), + Type::Handle(a) => a.supertypes.iter().map(MdListingEntry::from).collect(), + _ => vec![], + }; + let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); + heading.set_id(self.name.as_str()); + let mut listing = MdTypeListing::new(heading, md_type); + listing + .description + .push(MdParagraph::with_links_parsed(&self.docs)); + listing.entries.append(&mut entries); + MdBlockElement::TypeListing(listing) + } + TypeRef::Name(n) => { + let mut heading = MdHeading::new_header(self.name.as_str(), level); + heading.set_id(self.name.as_str()); + let mut sec = MdSection::new(heading); + sec.description + .push(MdParagraph::with_links_parsed(&self.docs)); + sec.description.push(MdParagraph::with_links_parsed(format!( + "Alias to {}", + n.name.as_str() + ))); + MdBlockElement::Section(sec) + } + } + } +} + +impl From<&Type> for MdType { + fn from(r#type: &Type) -> Self { + match r#type { + Type::Enum(a) => Self::Enum { + repr: a.repr.type_name().to_owned(), }, - TypeRef::Name(n) => format!("Alias to {}", n.name.as_str()), - }; - format!("## `{}`\n{}\n{}\n", self.name.as_str(), self.docs, body,) + Type::Int(a) => Self::Int { + repr: a.repr.type_name().to_owned(), + }, + Type::Flags(a) => Self::Flags { + repr: a.repr.type_name().to_owned(), + }, + Type::Struct(_) => Self::Struct, + Type::Union(_) => Self::Union, + Type::Handle(_) => Self::Handle, + Type::Array(a) => Self::Array { + r#type: a.type_name().to_owned(), + }, + Type::Pointer(a) => Self::Pointer { + to: a.type_name().to_owned(), + }, + Type::ConstPointer(a) => Self::ConstPointer { + to: a.type_name().to_owned(), + }, + Type::Builtin(a) => Self::Builtin { + r#type: a.type_name().to_owned(), + }, + } + } +} + +macro_rules! impl_mdlistingentry { + ($from:ty) => { + impl From<$from> for MdListingEntry { + fn from(f: $from) -> Self { + let mut heading = MdHeading::new_bullet(format!("`{}`", f.name.as_str())); + heading.set_id(f.name.as_str()); + Self { + heading, + description: vec![MdParagraph::with_links_parsed(&f.docs)], + } + } + } + }; +} + +impl_mdlistingentry!(&EnumVariant); +impl_mdlistingentry!(&IntConst); +impl_mdlistingentry!(&FlagsMember); +impl_mdlistingentry!(&StructMember); +impl_mdlistingentry!(&UnionVariant); + +impl From<&TypeRef> for MdListingEntry { + fn from(t: &TypeRef) -> Self { + let mut heading = MdHeading::new_bullet(format!("`{}`", t.type_name())); + heading.set_id(t.type_name()); + Self { + heading, + description: vec![], + } } } @@ -84,103 +491,6 @@ impl TypeRef { } } -impl Documentation for EnumDatatype { - fn to_md(&self) -> String { - let variants = self - .variants - .iter() - .map(|v| format!("#### `{}`\n{}", v.name.as_str(), v.docs)) - .collect::>() - .join("\n"); - format!( - "Enum represented by `{}`\n\n### Variants:\n{}\n", - self.repr.type_name(), - variants - ) - } -} - -impl Documentation for IntDatatype { - fn to_md(&self) -> String { - let consts = self - .consts - .iter() - .map(|v| format!("#### `{}`: {}\n{}", v.name.as_str(), v.value, v.docs)) - .collect::>() - .join("\n"); - format!( - "Int represented by `{}`\n\n### Consts:\n{}\n", - self.repr.type_name(), - consts - ) - } -} - -impl Documentation for FlagsDatatype { - fn to_md(&self) -> String { - let flags = self - .flags - .iter() - .map(|f| format!("#### `{}`\n{}\n", f.name.as_str(), f.docs)) - .collect::>() - .join("\n"); - format!( - "Flags represented by `{}`\n\n### Flags:\n{}", - self.repr.type_name(), - flags - ) - } -} - -impl Documentation for StructDatatype { - fn to_md(&self) -> String { - let members = self - .members - .iter() - .map(|m| { - format!( - "#### `{}`\nMember type: `{}`\n{}", - m.name.as_str(), - m.tref.type_name(), - m.docs, - ) - }) - .collect::>() - .join("\n"); - format!("### Struct members:\n{}", members) - } -} - -impl Documentation for UnionDatatype { - fn to_md(&self) -> String { - let variants = self - .variants - .iter() - .map(|v| { - format!( - "#### `{}`\nVariant type: `{}`\n{}", - v.name.as_str(), - v.tref.type_name(), - v.docs, - ) - }) - .collect::>() - .join("\n"); - format!("### Union variants:\n{}\n", variants) - } -} - -impl Documentation for HandleDatatype { - fn to_md(&self) -> String { - let supertypes = self - .supertypes - .iter() - .map(|s| format!("* {}", s.type_name())) - .collect::>() - .join("\n"); - format!("### Handle supertypes:\n{}\n", supertypes) - } -} impl IntRepr { fn type_name(&self) -> &'static str { match self { @@ -193,72 +503,63 @@ impl IntRepr { } impl Documentation for Module { - fn to_md(&self) -> String { - let imports = self - .imports() - .map(|i| i.to_md()) - .collect::>() - .join("\n"); - let funcs = self - .funcs() - .map(|i| i.to_md()) - .collect::>() - .join("\n"); - format!( - "## `{}`\n### Imports\n{}\n### Functions\n{}", - self.name.as_str(), - imports, - funcs, - ) + fn gen(&self, level: usize) -> MdBlockElement { + let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); + heading.set_id(self.name.as_str()); + let mut sec = MdSection::new(heading); + let mut imports = MdSection::new(MdHeading::new_header("Imports", level + 1)); + // FIXME + for import in self.imports() { + let desc = match import.variant { + ModuleImportVariant::Memory => { + MdParagraph::with_links_parsed(format!("* {}: Memory", import.name.as_str())) + } + }; + imports.description.push(desc); + } + sec.blocks.push(MdBlockElement::Section(imports)); + let mut funcs = MdSection::new(MdHeading::new_header("Functions", level + 1)); + funcs.blocks.extend(self.funcs().map(|f| f.gen(level + 2))); + sec.blocks.push(MdBlockElement::Section(funcs)); + MdBlockElement::Section(sec) } } -impl Documentation for ModuleImport { - fn to_md(&self) -> String { - match self.variant { - ModuleImportVariant::Memory => format!("* {}: Memory", self.name.as_str()), - } +impl Documentation for InterfaceFunc { + fn gen(&self, level: usize) -> MdBlockElement { + let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); + heading.set_id(self.name.as_str()); + let mut func = MdInterfaceFunc::new(heading); + func.description + .push(MdParagraph::with_links_parsed(&self.docs)); + func.parameters + .extend(self.params.iter().map(MdListingEntry::from)); + func.results + .extend(self.results.iter().map(MdListingEntry::from)); + MdBlockElement::InterfaceFunc(func) } } -impl Documentation for InterfaceFunc { - fn to_md(&self) -> String { - let params = self - .params - .iter() - .map(|f| { - format!( - "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", - name = f.name.as_str(), - type_ = f.tref.type_name(), - docs = f.docs - ) - }) - .collect::>() - .join("\n"); - let results = self - .results - .iter() - .map(|f| { - format!( - "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", - name = f.name.as_str(), - type_ = f.tref.type_name(), - docs = f.docs - ) - }) - .collect::>() - .join("\n"); - format!( - "### {}\n{}\n#### Parameters:\n{}#### Results:\n{}", - self.name.as_str(), - self.docs, - params, - results, - ) +impl From<&InterfaceFuncParam> for MdListingEntry { + fn from(param: &InterfaceFuncParam) -> Self { + let mut heading = MdHeading::new_bullet(format!("`{}`", param.name.as_str())); + heading.set_id(param.name.as_str()); + let mut description = vec![]; + description.push(MdParagraph::with_links_parsed(format!( + "`{}` has type `{}`.", + param.name.as_str(), + param.tref.type_name() + ))); + description.push(MdParagraph::with_links_parsed(¶m.docs)); + Self { + heading, + description, + } } } +// TODO +// Generate nicely-formatted docs for polyfill impl Documentation for Polyfill { fn to_md(&self) -> String { let module_docs = self From 5b0ccd24e4920934735230598109d13c84af6f9c Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 8 Jan 2020 23:01:25 +0100 Subject: [PATCH 0441/1772] Clean up Markdown generation from witx This commit tweaks `docs.rs` module of the `witx` tool facilitating generation of Markdown documentation from `*.witx` files which * is formatted in a more readable way * inserts HTML links for each header but also a list entry (in the latter case, the link is scoped; i.e., it includes the link id of the enclosing Markdown section) --- proposals/filesystem/tools/witx/src/docs.rs | 661 ++++++++++++++------ 1 file changed, 481 insertions(+), 180 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs index 1d7572949..2e358b15e 100644 --- a/proposals/filesystem/tools/witx/src/docs.rs +++ b/proposals/filesystem/tools/witx/src/docs.rs @@ -1,23 +1,349 @@ use crate::ast::*; use crate::polyfill::*; use crate::RepEquality; +use std::fmt; + +#[derive(Debug)] +pub enum MdBlockElement { + Section(MdSection), + TypeListing(MdTypeListing), + InterfaceFunc(MdInterfaceFunc), + Root(MdRoot), +} + +impl fmt::Display for MdBlockElement { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Section(sec) => sec.fmt(f), + Self::TypeListing(listing) => listing.fmt(f), + Self::InterfaceFunc(func) => func.fmt(f), + Self::Root(root) => root.fmt(f), + } + } +} + +#[derive(Debug, Default)] +pub struct MdRoot { + blocks: Vec, +} + +impl fmt::Display for MdRoot { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for block in &self.blocks { + block.fmt(f)?; + } + Ok(()) + } +} + +#[derive(Debug, Clone)] +struct MdParagraph { + para: String, +} + +impl MdParagraph { + fn new>(para: S) -> Self { + Self { + para: para.as_ref().to_owned(), + } + } + + fn with_links_parsed>(para: S) -> Self { + let to_parse = para.as_ref(); + let mut parsed = String::with_capacity(to_parse.len()); + let mut temp = String::with_capacity(to_parse.len()); + let mut is_link = false; + let mut eaten = None; + for ch in to_parse.chars() { + match (ch, is_link) { + ('`', false) => { + // found the beginning of a link + is_link = true; + } + ('`', true) => { + // reached the end, expand into a link! + let expanded = format!("[`{}`](#{})", temp, temp); + parsed.push_str(&expanded); + temp.drain(..); + is_link = false; + } + (':', true) => { + if let Some(_) = eaten { + // swap for '.' + temp.push('.'); + eaten = None; + } else { + eaten = Some(':'); + } + } + (ch, false) => parsed.push(ch), + (ch, true) => temp.push(ch), + } + } + Self::new(parsed) + } +} + +impl fmt::Display for MdParagraph { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_fmt(format_args!("{}\n", &self.para)) + } +} + +#[allow(dead_code)] +#[derive(Debug, Clone)] +enum MdHeading { + Header { + id: String, + title: String, + doc_level: usize, + }, + Bullet { + id: String, + title: String, + }, +} + +impl MdHeading { + fn new_header>(title: S, doc_level: usize) -> Self { + let id = title.as_ref().replace(" ", "_"); + let title = title.as_ref().to_owned(); + Self::Header { + id, + title, + doc_level, + } + } + + fn new_bullet>(title: S) -> Self { + let id = title.as_ref().replace(" ", "_"); + let title = title.as_ref().to_owned(); + Self::Bullet { id, title } + } + + fn id(&self) -> &str { + match self { + Self::Header { ref id, .. } => id, + Self::Bullet { ref id, .. } => id, + } + } + + fn set_id>(&mut self, id: S) { + let s_id = match self { + Self::Header { ref mut id, .. } => id, + Self::Bullet { ref mut id, .. } => id, + }; + *s_id = id.as_ref().to_owned(); + } +} + +impl fmt::Display for MdHeading { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let (id, title, heading) = match self { + Self::Header { + id, + title, + doc_level, + } => (id, title, "#".repeat(*doc_level)), + Self::Bullet { id, title } => (id, title, "-".to_owned()), + }; + f.write_fmt(format_args!( + "{heading} {title}\n", + heading = heading, + id = id, + title = title + )) + } +} + +#[derive(Debug)] +pub struct MdSection { + heading: MdHeading, + description: Vec, + blocks: Vec, +} + +impl MdSection { + fn new(heading: MdHeading) -> Self { + Self { + heading, + description: vec![], + blocks: vec![], + } + } +} + +impl fmt::Display for MdSection { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.heading.fmt(f)?; + for para in &self.description { + para.fmt(f)?; + } + for el in &self.blocks { + el.fmt(f)?; + } + Ok(()) + } +} + +#[allow(dead_code)] +#[derive(Debug)] +enum MdType { + Enum { repr: String }, + Int { repr: String }, + Flags { repr: String }, + Struct, + Union, + Handle, + Array { r#type: String }, + Pointer { to: String }, + ConstPointer { to: String }, + Builtin { r#type: String }, +} + +impl fmt::Display for MdType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let type_specific = match self { + MdType::Enum { repr } => format!("Enum represented by `{}`\n\n**Variants:**", repr), + MdType::Int { repr } => format!("Int represented by `{}`\n\n**Const:**", repr), + MdType::Flags { repr } => format!("Flags represented by `{}`\n\n**Flags:**", repr), + MdType::Struct => "\n**Struct members:**".to_owned(), + MdType::Union => "\n**Union variants:**".to_owned(), + MdType::Handle => "\n**Supertypes:**".to_owned(), + MdType::Array { r#type } => format!("Array of `{}`", r#type), + MdType::Pointer { to } => format!("Pointer to `{}`", to), + MdType::ConstPointer { to } => format!("Const pointer to `{}`", to), + MdType::Builtin { r#type } => format!("Builtin type `{}`", r#type), + }; + f.write_fmt(format_args!("{}\n", type_specific)) + } +} + +#[derive(Debug, Clone)] +struct MdListingEntry { + heading: MdHeading, + description: Vec, +} + +impl fmt::Display for MdListingEntry { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.heading.fmt(f)?; + for para in &self.description { + f.write_fmt(format_args!("\n\t{}\n", para))?; + } + Ok(()) + } +} + +#[derive(Debug)] +pub struct MdTypeListing { + heading: MdHeading, + r#type: MdType, + description: Vec, + entries: Vec, +} + +impl MdTypeListing { + fn new(heading: MdHeading, r#type: MdType) -> Self { + Self { + heading, + r#type, + description: vec![], + entries: vec![], + } + } +} + +impl fmt::Display for MdTypeListing { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.heading.fmt(f)?; + for para in &self.description { + para.fmt(f)?; + } + self.r#type.fmt(f)?; + for el in &self.entries { + // prepend id of this MdTypeListing in order to generate scoped + // references of list entries + let id = format!("{}.{}", self.heading.id(), el.heading.id()); + let mut new_el = el.clone(); + new_el.heading.set_id(id); + new_el.fmt(f)?; + } + Ok(()) + } +} + +#[derive(Debug)] +pub struct MdInterfaceFunc { + heading: MdHeading, + description: Vec, + parameters: Vec, + results: Vec, +} + +impl MdInterfaceFunc { + fn new(heading: MdHeading) -> Self { + Self { + heading, + description: vec![], + parameters: vec![], + results: vec![], + } + } +} + +impl fmt::Display for MdInterfaceFunc { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.heading.fmt(f)?; + for desc in &self.description { + desc.fmt(f)?; + } + f.write_str("\n**Parameters:**\n\n")?; + for el in &self.parameters { + // prepend id of this MdTypeListing in order to generate scoped + // references of list entries + let id = format!("{}.{}", self.heading.id(), el.heading.id()); + let mut new_el = el.clone(); + new_el.heading.set_id(id); + new_el.fmt(f)?; + } + f.write_str("\n**Results:**\n\n")?; + for el in &self.results { + // prepend id of this MdTypeListing in order to generate scoped + // references of list entries + let id = format!("{}.{}", self.heading.id(), el.heading.id()); + let mut new_el = el.clone(); + new_el.heading.set_id(id); + new_el.fmt(f)?; + } + Ok(()) + } +} pub trait Documentation { - fn to_md(&self) -> String; + fn to_md(&self) -> String { + format!("{}", self.gen(0)) + } + + fn gen(&self, _level: usize) -> MdBlockElement { + MdBlockElement::Root(MdRoot::default()) + } } impl Documentation for Document { - fn to_md(&self) -> String { - let mut ret = "# Types\n".to_string(); - for d in self.typenames() { - ret += &d.to_md(); + fn gen(&self, level: usize) -> MdBlockElement { + let mut doc = MdRoot::default(); + let mut types = MdSection::new(MdHeading::new_header("Types", level + 1)); + for typename in self.typenames() { + types.blocks.push(typename.gen(level + 2)); } - - ret += "\n# Modules\n"; - for m in self.modules() { - ret += &m.to_md(); + doc.blocks.push(MdBlockElement::Section(types)); + let mut modules = MdSection::new(MdHeading::new_header("Modules", level + 1)); + for module in self.modules() { + modules.blocks.push(module.gen(level + 2)); } - ret + doc.blocks.push(MdBlockElement::Section(modules)); + MdBlockElement::Root(doc) } } @@ -42,23 +368,104 @@ impl BuiltinType { } impl Documentation for NamedType { - fn to_md(&self) -> String { - let body = match &self.tref { - TypeRef::Value(v) => match &**v { - Type::Enum(a) => a.to_md(), - Type::Int(a) => a.to_md(), - Type::Flags(a) => a.to_md(), - Type::Struct(a) => a.to_md(), - Type::Union(a) => a.to_md(), - Type::Handle(a) => a.to_md(), - Type::Array(a) => format!("Array of {}", a.type_name()), - Type::Pointer(a) => format!("Pointer to {}", a.type_name()), - Type::ConstPointer(a) => format!("Constant Pointer to {}", a.type_name()), - Type::Builtin(a) => format!("Builtin type {}", a.type_name()), + fn gen(&self, level: usize) -> MdBlockElement { + match &self.tref { + TypeRef::Value(v) => { + let md_type = MdType::from(&**v); + let mut entries: Vec<_> = match &**v { + Type::Enum(a) => a.variants.iter().map(MdListingEntry::from).collect(), + Type::Int(a) => a.consts.iter().map(MdListingEntry::from).collect(), + Type::Flags(a) => a.flags.iter().map(MdListingEntry::from).collect(), + Type::Struct(a) => a.members.iter().map(MdListingEntry::from).collect(), + Type::Union(a) => a.variants.iter().map(MdListingEntry::from).collect(), + Type::Handle(a) => a.supertypes.iter().map(MdListingEntry::from).collect(), + _ => vec![], + }; + let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); + heading.set_id(self.name.as_str()); + let mut listing = MdTypeListing::new(heading, md_type); + listing + .description + .push(MdParagraph::with_links_parsed(&self.docs)); + listing.entries.append(&mut entries); + MdBlockElement::TypeListing(listing) + } + TypeRef::Name(n) => { + let mut heading = MdHeading::new_header(self.name.as_str(), level); + heading.set_id(self.name.as_str()); + let mut sec = MdSection::new(heading); + sec.description + .push(MdParagraph::with_links_parsed(&self.docs)); + sec.description.push(MdParagraph::with_links_parsed(format!( + "Alias to {}", + n.name.as_str() + ))); + MdBlockElement::Section(sec) + } + } + } +} + +impl From<&Type> for MdType { + fn from(r#type: &Type) -> Self { + match r#type { + Type::Enum(a) => Self::Enum { + repr: a.repr.type_name().to_owned(), }, - TypeRef::Name(n) => format!("Alias to {}", n.name.as_str()), - }; - format!("## `{}`\n{}\n{}\n", self.name.as_str(), self.docs, body,) + Type::Int(a) => Self::Int { + repr: a.repr.type_name().to_owned(), + }, + Type::Flags(a) => Self::Flags { + repr: a.repr.type_name().to_owned(), + }, + Type::Struct(_) => Self::Struct, + Type::Union(_) => Self::Union, + Type::Handle(_) => Self::Handle, + Type::Array(a) => Self::Array { + r#type: a.type_name().to_owned(), + }, + Type::Pointer(a) => Self::Pointer { + to: a.type_name().to_owned(), + }, + Type::ConstPointer(a) => Self::ConstPointer { + to: a.type_name().to_owned(), + }, + Type::Builtin(a) => Self::Builtin { + r#type: a.type_name().to_owned(), + }, + } + } +} + +macro_rules! impl_mdlistingentry { + ($from:ty) => { + impl From<$from> for MdListingEntry { + fn from(f: $from) -> Self { + let mut heading = MdHeading::new_bullet(format!("`{}`", f.name.as_str())); + heading.set_id(f.name.as_str()); + Self { + heading, + description: vec![MdParagraph::with_links_parsed(&f.docs)], + } + } + } + }; +} + +impl_mdlistingentry!(&EnumVariant); +impl_mdlistingentry!(&IntConst); +impl_mdlistingentry!(&FlagsMember); +impl_mdlistingentry!(&StructMember); +impl_mdlistingentry!(&UnionVariant); + +impl From<&TypeRef> for MdListingEntry { + fn from(t: &TypeRef) -> Self { + let mut heading = MdHeading::new_bullet(format!("`{}`", t.type_name())); + heading.set_id(t.type_name()); + Self { + heading, + description: vec![], + } } } @@ -84,103 +491,6 @@ impl TypeRef { } } -impl Documentation for EnumDatatype { - fn to_md(&self) -> String { - let variants = self - .variants - .iter() - .map(|v| format!("#### `{}`\n{}", v.name.as_str(), v.docs)) - .collect::>() - .join("\n"); - format!( - "Enum represented by `{}`\n\n### Variants:\n{}\n", - self.repr.type_name(), - variants - ) - } -} - -impl Documentation for IntDatatype { - fn to_md(&self) -> String { - let consts = self - .consts - .iter() - .map(|v| format!("#### `{}`: {}\n{}", v.name.as_str(), v.value, v.docs)) - .collect::>() - .join("\n"); - format!( - "Int represented by `{}`\n\n### Consts:\n{}\n", - self.repr.type_name(), - consts - ) - } -} - -impl Documentation for FlagsDatatype { - fn to_md(&self) -> String { - let flags = self - .flags - .iter() - .map(|f| format!("#### `{}`\n{}\n", f.name.as_str(), f.docs)) - .collect::>() - .join("\n"); - format!( - "Flags represented by `{}`\n\n### Flags:\n{}", - self.repr.type_name(), - flags - ) - } -} - -impl Documentation for StructDatatype { - fn to_md(&self) -> String { - let members = self - .members - .iter() - .map(|m| { - format!( - "#### `{}`\nMember type: `{}`\n{}", - m.name.as_str(), - m.tref.type_name(), - m.docs, - ) - }) - .collect::>() - .join("\n"); - format!("### Struct members:\n{}", members) - } -} - -impl Documentation for UnionDatatype { - fn to_md(&self) -> String { - let variants = self - .variants - .iter() - .map(|v| { - format!( - "#### `{}`\nVariant type: `{}`\n{}", - v.name.as_str(), - v.tref.type_name(), - v.docs, - ) - }) - .collect::>() - .join("\n"); - format!("### Union variants:\n{}\n", variants) - } -} - -impl Documentation for HandleDatatype { - fn to_md(&self) -> String { - let supertypes = self - .supertypes - .iter() - .map(|s| format!("* {}", s.type_name())) - .collect::>() - .join("\n"); - format!("### Handle supertypes:\n{}\n", supertypes) - } -} impl IntRepr { fn type_name(&self) -> &'static str { match self { @@ -193,72 +503,63 @@ impl IntRepr { } impl Documentation for Module { - fn to_md(&self) -> String { - let imports = self - .imports() - .map(|i| i.to_md()) - .collect::>() - .join("\n"); - let funcs = self - .funcs() - .map(|i| i.to_md()) - .collect::>() - .join("\n"); - format!( - "## `{}`\n### Imports\n{}\n### Functions\n{}", - self.name.as_str(), - imports, - funcs, - ) + fn gen(&self, level: usize) -> MdBlockElement { + let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); + heading.set_id(self.name.as_str()); + let mut sec = MdSection::new(heading); + let mut imports = MdSection::new(MdHeading::new_header("Imports", level + 1)); + // FIXME + for import in self.imports() { + let desc = match import.variant { + ModuleImportVariant::Memory => { + MdParagraph::with_links_parsed(format!("* {}: Memory", import.name.as_str())) + } + }; + imports.description.push(desc); + } + sec.blocks.push(MdBlockElement::Section(imports)); + let mut funcs = MdSection::new(MdHeading::new_header("Functions", level + 1)); + funcs.blocks.extend(self.funcs().map(|f| f.gen(level + 2))); + sec.blocks.push(MdBlockElement::Section(funcs)); + MdBlockElement::Section(sec) } } -impl Documentation for ModuleImport { - fn to_md(&self) -> String { - match self.variant { - ModuleImportVariant::Memory => format!("* {}: Memory", self.name.as_str()), - } +impl Documentation for InterfaceFunc { + fn gen(&self, level: usize) -> MdBlockElement { + let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); + heading.set_id(self.name.as_str()); + let mut func = MdInterfaceFunc::new(heading); + func.description + .push(MdParagraph::with_links_parsed(&self.docs)); + func.parameters + .extend(self.params.iter().map(MdListingEntry::from)); + func.results + .extend(self.results.iter().map(MdListingEntry::from)); + MdBlockElement::InterfaceFunc(func) } } -impl Documentation for InterfaceFunc { - fn to_md(&self) -> String { - let params = self - .params - .iter() - .map(|f| { - format!( - "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", - name = f.name.as_str(), - type_ = f.tref.type_name(), - docs = f.docs - ) - }) - .collect::>() - .join("\n"); - let results = self - .results - .iter() - .map(|f| { - format!( - "##### `{name}`\n`{name}` has type `{type_}`\n{docs}", - name = f.name.as_str(), - type_ = f.tref.type_name(), - docs = f.docs - ) - }) - .collect::>() - .join("\n"); - format!( - "### {}\n{}\n#### Parameters:\n{}#### Results:\n{}", - self.name.as_str(), - self.docs, - params, - results, - ) +impl From<&InterfaceFuncParam> for MdListingEntry { + fn from(param: &InterfaceFuncParam) -> Self { + let mut heading = MdHeading::new_bullet(format!("`{}`", param.name.as_str())); + heading.set_id(param.name.as_str()); + let mut description = vec![]; + description.push(MdParagraph::with_links_parsed(format!( + "`{}` has type `{}`.", + param.name.as_str(), + param.tref.type_name() + ))); + description.push(MdParagraph::with_links_parsed(¶m.docs)); + Self { + heading, + description, + } } } +// TODO +// Generate nicely-formatted docs for polyfill impl Documentation for Polyfill { fn to_md(&self) -> String { let module_docs = self From 4029de3b012b111efe7617c2a6b1fc79bf626266 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 9 Jan 2020 22:41:43 +0100 Subject: [PATCH 0442/1772] Reorganise and refactor handling on header nesting This commit reorganises the `docs` module into a couple of submodules for easier navigation. It also replaces manual specifying of nesting level upon Markdown element creation for automatic header generation. I should note here that I've decided to simplify the code over the previous commit, as the previous seemed unnecessary bloated and really subtle in places which IMHO would very likely cause some maintenance hell in the future. --- proposals/clocks/tools/witx/src/docs.rs | 710 -------------------- proposals/clocks/tools/witx/src/docs/md.rs | 288 ++++++++ proposals/clocks/tools/witx/src/docs/mod.rs | 411 +++++++++++ 3 files changed, 699 insertions(+), 710 deletions(-) delete mode 100644 proposals/clocks/tools/witx/src/docs.rs create mode 100644 proposals/clocks/tools/witx/src/docs/md.rs create mode 100644 proposals/clocks/tools/witx/src/docs/mod.rs diff --git a/proposals/clocks/tools/witx/src/docs.rs b/proposals/clocks/tools/witx/src/docs.rs deleted file mode 100644 index 2e358b15e..000000000 --- a/proposals/clocks/tools/witx/src/docs.rs +++ /dev/null @@ -1,710 +0,0 @@ -use crate::ast::*; -use crate::polyfill::*; -use crate::RepEquality; -use std::fmt; - -#[derive(Debug)] -pub enum MdBlockElement { - Section(MdSection), - TypeListing(MdTypeListing), - InterfaceFunc(MdInterfaceFunc), - Root(MdRoot), -} - -impl fmt::Display for MdBlockElement { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Section(sec) => sec.fmt(f), - Self::TypeListing(listing) => listing.fmt(f), - Self::InterfaceFunc(func) => func.fmt(f), - Self::Root(root) => root.fmt(f), - } - } -} - -#[derive(Debug, Default)] -pub struct MdRoot { - blocks: Vec, -} - -impl fmt::Display for MdRoot { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for block in &self.blocks { - block.fmt(f)?; - } - Ok(()) - } -} - -#[derive(Debug, Clone)] -struct MdParagraph { - para: String, -} - -impl MdParagraph { - fn new>(para: S) -> Self { - Self { - para: para.as_ref().to_owned(), - } - } - - fn with_links_parsed>(para: S) -> Self { - let to_parse = para.as_ref(); - let mut parsed = String::with_capacity(to_parse.len()); - let mut temp = String::with_capacity(to_parse.len()); - let mut is_link = false; - let mut eaten = None; - for ch in to_parse.chars() { - match (ch, is_link) { - ('`', false) => { - // found the beginning of a link - is_link = true; - } - ('`', true) => { - // reached the end, expand into a link! - let expanded = format!("[`{}`](#{})", temp, temp); - parsed.push_str(&expanded); - temp.drain(..); - is_link = false; - } - (':', true) => { - if let Some(_) = eaten { - // swap for '.' - temp.push('.'); - eaten = None; - } else { - eaten = Some(':'); - } - } - (ch, false) => parsed.push(ch), - (ch, true) => temp.push(ch), - } - } - Self::new(parsed) - } -} - -impl fmt::Display for MdParagraph { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_fmt(format_args!("{}\n", &self.para)) - } -} - -#[allow(dead_code)] -#[derive(Debug, Clone)] -enum MdHeading { - Header { - id: String, - title: String, - doc_level: usize, - }, - Bullet { - id: String, - title: String, - }, -} - -impl MdHeading { - fn new_header>(title: S, doc_level: usize) -> Self { - let id = title.as_ref().replace(" ", "_"); - let title = title.as_ref().to_owned(); - Self::Header { - id, - title, - doc_level, - } - } - - fn new_bullet>(title: S) -> Self { - let id = title.as_ref().replace(" ", "_"); - let title = title.as_ref().to_owned(); - Self::Bullet { id, title } - } - - fn id(&self) -> &str { - match self { - Self::Header { ref id, .. } => id, - Self::Bullet { ref id, .. } => id, - } - } - - fn set_id>(&mut self, id: S) { - let s_id = match self { - Self::Header { ref mut id, .. } => id, - Self::Bullet { ref mut id, .. } => id, - }; - *s_id = id.as_ref().to_owned(); - } -} - -impl fmt::Display for MdHeading { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let (id, title, heading) = match self { - Self::Header { - id, - title, - doc_level, - } => (id, title, "#".repeat(*doc_level)), - Self::Bullet { id, title } => (id, title, "-".to_owned()), - }; - f.write_fmt(format_args!( - "{heading} {title}\n", - heading = heading, - id = id, - title = title - )) - } -} - -#[derive(Debug)] -pub struct MdSection { - heading: MdHeading, - description: Vec, - blocks: Vec, -} - -impl MdSection { - fn new(heading: MdHeading) -> Self { - Self { - heading, - description: vec![], - blocks: vec![], - } - } -} - -impl fmt::Display for MdSection { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.heading.fmt(f)?; - for para in &self.description { - para.fmt(f)?; - } - for el in &self.blocks { - el.fmt(f)?; - } - Ok(()) - } -} - -#[allow(dead_code)] -#[derive(Debug)] -enum MdType { - Enum { repr: String }, - Int { repr: String }, - Flags { repr: String }, - Struct, - Union, - Handle, - Array { r#type: String }, - Pointer { to: String }, - ConstPointer { to: String }, - Builtin { r#type: String }, -} - -impl fmt::Display for MdType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let type_specific = match self { - MdType::Enum { repr } => format!("Enum represented by `{}`\n\n**Variants:**", repr), - MdType::Int { repr } => format!("Int represented by `{}`\n\n**Const:**", repr), - MdType::Flags { repr } => format!("Flags represented by `{}`\n\n**Flags:**", repr), - MdType::Struct => "\n**Struct members:**".to_owned(), - MdType::Union => "\n**Union variants:**".to_owned(), - MdType::Handle => "\n**Supertypes:**".to_owned(), - MdType::Array { r#type } => format!("Array of `{}`", r#type), - MdType::Pointer { to } => format!("Pointer to `{}`", to), - MdType::ConstPointer { to } => format!("Const pointer to `{}`", to), - MdType::Builtin { r#type } => format!("Builtin type `{}`", r#type), - }; - f.write_fmt(format_args!("{}\n", type_specific)) - } -} - -#[derive(Debug, Clone)] -struct MdListingEntry { - heading: MdHeading, - description: Vec, -} - -impl fmt::Display for MdListingEntry { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.heading.fmt(f)?; - for para in &self.description { - f.write_fmt(format_args!("\n\t{}\n", para))?; - } - Ok(()) - } -} - -#[derive(Debug)] -pub struct MdTypeListing { - heading: MdHeading, - r#type: MdType, - description: Vec, - entries: Vec, -} - -impl MdTypeListing { - fn new(heading: MdHeading, r#type: MdType) -> Self { - Self { - heading, - r#type, - description: vec![], - entries: vec![], - } - } -} - -impl fmt::Display for MdTypeListing { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.heading.fmt(f)?; - for para in &self.description { - para.fmt(f)?; - } - self.r#type.fmt(f)?; - for el in &self.entries { - // prepend id of this MdTypeListing in order to generate scoped - // references of list entries - let id = format!("{}.{}", self.heading.id(), el.heading.id()); - let mut new_el = el.clone(); - new_el.heading.set_id(id); - new_el.fmt(f)?; - } - Ok(()) - } -} - -#[derive(Debug)] -pub struct MdInterfaceFunc { - heading: MdHeading, - description: Vec, - parameters: Vec, - results: Vec, -} - -impl MdInterfaceFunc { - fn new(heading: MdHeading) -> Self { - Self { - heading, - description: vec![], - parameters: vec![], - results: vec![], - } - } -} - -impl fmt::Display for MdInterfaceFunc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.heading.fmt(f)?; - for desc in &self.description { - desc.fmt(f)?; - } - f.write_str("\n**Parameters:**\n\n")?; - for el in &self.parameters { - // prepend id of this MdTypeListing in order to generate scoped - // references of list entries - let id = format!("{}.{}", self.heading.id(), el.heading.id()); - let mut new_el = el.clone(); - new_el.heading.set_id(id); - new_el.fmt(f)?; - } - f.write_str("\n**Results:**\n\n")?; - for el in &self.results { - // prepend id of this MdTypeListing in order to generate scoped - // references of list entries - let id = format!("{}.{}", self.heading.id(), el.heading.id()); - let mut new_el = el.clone(); - new_el.heading.set_id(id); - new_el.fmt(f)?; - } - Ok(()) - } -} - -pub trait Documentation { - fn to_md(&self) -> String { - format!("{}", self.gen(0)) - } - - fn gen(&self, _level: usize) -> MdBlockElement { - MdBlockElement::Root(MdRoot::default()) - } -} - -impl Documentation for Document { - fn gen(&self, level: usize) -> MdBlockElement { - let mut doc = MdRoot::default(); - let mut types = MdSection::new(MdHeading::new_header("Types", level + 1)); - for typename in self.typenames() { - types.blocks.push(typename.gen(level + 2)); - } - doc.blocks.push(MdBlockElement::Section(types)); - let mut modules = MdSection::new(MdHeading::new_header("Modules", level + 1)); - for module in self.modules() { - modules.blocks.push(module.gen(level + 2)); - } - doc.blocks.push(MdBlockElement::Section(modules)); - MdBlockElement::Root(doc) - } -} - -impl BuiltinType { - pub fn type_name(&self) -> &'static str { - match self { - BuiltinType::String => "string", - BuiltinType::Char8 => "char8", - BuiltinType::USize => "usize", - BuiltinType::U8 => "u8", - BuiltinType::U16 => "u16", - BuiltinType::U32 => "u32", - BuiltinType::U64 => "u64", - BuiltinType::S8 => "s8", - BuiltinType::S16 => "s16", - BuiltinType::S32 => "s32", - BuiltinType::S64 => "s64", - BuiltinType::F32 => "f32", - BuiltinType::F64 => "f64", - } - } -} - -impl Documentation for NamedType { - fn gen(&self, level: usize) -> MdBlockElement { - match &self.tref { - TypeRef::Value(v) => { - let md_type = MdType::from(&**v); - let mut entries: Vec<_> = match &**v { - Type::Enum(a) => a.variants.iter().map(MdListingEntry::from).collect(), - Type::Int(a) => a.consts.iter().map(MdListingEntry::from).collect(), - Type::Flags(a) => a.flags.iter().map(MdListingEntry::from).collect(), - Type::Struct(a) => a.members.iter().map(MdListingEntry::from).collect(), - Type::Union(a) => a.variants.iter().map(MdListingEntry::from).collect(), - Type::Handle(a) => a.supertypes.iter().map(MdListingEntry::from).collect(), - _ => vec![], - }; - let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); - heading.set_id(self.name.as_str()); - let mut listing = MdTypeListing::new(heading, md_type); - listing - .description - .push(MdParagraph::with_links_parsed(&self.docs)); - listing.entries.append(&mut entries); - MdBlockElement::TypeListing(listing) - } - TypeRef::Name(n) => { - let mut heading = MdHeading::new_header(self.name.as_str(), level); - heading.set_id(self.name.as_str()); - let mut sec = MdSection::new(heading); - sec.description - .push(MdParagraph::with_links_parsed(&self.docs)); - sec.description.push(MdParagraph::with_links_parsed(format!( - "Alias to {}", - n.name.as_str() - ))); - MdBlockElement::Section(sec) - } - } - } -} - -impl From<&Type> for MdType { - fn from(r#type: &Type) -> Self { - match r#type { - Type::Enum(a) => Self::Enum { - repr: a.repr.type_name().to_owned(), - }, - Type::Int(a) => Self::Int { - repr: a.repr.type_name().to_owned(), - }, - Type::Flags(a) => Self::Flags { - repr: a.repr.type_name().to_owned(), - }, - Type::Struct(_) => Self::Struct, - Type::Union(_) => Self::Union, - Type::Handle(_) => Self::Handle, - Type::Array(a) => Self::Array { - r#type: a.type_name().to_owned(), - }, - Type::Pointer(a) => Self::Pointer { - to: a.type_name().to_owned(), - }, - Type::ConstPointer(a) => Self::ConstPointer { - to: a.type_name().to_owned(), - }, - Type::Builtin(a) => Self::Builtin { - r#type: a.type_name().to_owned(), - }, - } - } -} - -macro_rules! impl_mdlistingentry { - ($from:ty) => { - impl From<$from> for MdListingEntry { - fn from(f: $from) -> Self { - let mut heading = MdHeading::new_bullet(format!("`{}`", f.name.as_str())); - heading.set_id(f.name.as_str()); - Self { - heading, - description: vec![MdParagraph::with_links_parsed(&f.docs)], - } - } - } - }; -} - -impl_mdlistingentry!(&EnumVariant); -impl_mdlistingentry!(&IntConst); -impl_mdlistingentry!(&FlagsMember); -impl_mdlistingentry!(&StructMember); -impl_mdlistingentry!(&UnionVariant); - -impl From<&TypeRef> for MdListingEntry { - fn from(t: &TypeRef) -> Self { - let mut heading = MdHeading::new_bullet(format!("`{}`", t.type_name())); - heading.set_id(t.type_name()); - Self { - heading, - description: vec![], - } - } -} - -impl TypeRef { - pub fn type_name(&self) -> String { - match self { - TypeRef::Name(n) => n.name.as_str().to_string(), - TypeRef::Value(ref v) => match &**v { - Type::Array(a) => format!("Array<{}>", a.type_name()), - Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), - Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), - Type::Builtin(b) => b.type_name().to_string(), - Type::Enum { .. } - | Type::Int { .. } - | Type::Flags { .. } - | Type::Struct { .. } - | Type::Union { .. } - | Type::Handle { .. } => { - unimplemented!("type_name of anonymous compound datatypes") - } - }, - } - } -} - -impl IntRepr { - fn type_name(&self) -> &'static str { - match self { - IntRepr::U8 => "u8", - IntRepr::U16 => "u16", - IntRepr::U32 => "u32", - IntRepr::U64 => "u64", - } - } -} - -impl Documentation for Module { - fn gen(&self, level: usize) -> MdBlockElement { - let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); - heading.set_id(self.name.as_str()); - let mut sec = MdSection::new(heading); - let mut imports = MdSection::new(MdHeading::new_header("Imports", level + 1)); - // FIXME - for import in self.imports() { - let desc = match import.variant { - ModuleImportVariant::Memory => { - MdParagraph::with_links_parsed(format!("* {}: Memory", import.name.as_str())) - } - }; - imports.description.push(desc); - } - sec.blocks.push(MdBlockElement::Section(imports)); - let mut funcs = MdSection::new(MdHeading::new_header("Functions", level + 1)); - funcs.blocks.extend(self.funcs().map(|f| f.gen(level + 2))); - sec.blocks.push(MdBlockElement::Section(funcs)); - MdBlockElement::Section(sec) - } -} - -impl Documentation for InterfaceFunc { - fn gen(&self, level: usize) -> MdBlockElement { - let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); - heading.set_id(self.name.as_str()); - let mut func = MdInterfaceFunc::new(heading); - func.description - .push(MdParagraph::with_links_parsed(&self.docs)); - func.parameters - .extend(self.params.iter().map(MdListingEntry::from)); - func.results - .extend(self.results.iter().map(MdListingEntry::from)); - MdBlockElement::InterfaceFunc(func) - } -} - -impl From<&InterfaceFuncParam> for MdListingEntry { - fn from(param: &InterfaceFuncParam) -> Self { - let mut heading = MdHeading::new_bullet(format!("`{}`", param.name.as_str())); - heading.set_id(param.name.as_str()); - let mut description = vec![]; - description.push(MdParagraph::with_links_parsed(format!( - "`{}` has type `{}`.", - param.name.as_str(), - param.tref.type_name() - ))); - description.push(MdParagraph::with_links_parsed(¶m.docs)); - Self { - heading, - description, - } - } -} - -// TODO -// Generate nicely-formatted docs for polyfill -impl Documentation for Polyfill { - fn to_md(&self) -> String { - let module_docs = self - .modules - .iter() - .map(|m| m.to_md()) - .collect::>() - .join("\n"); - let type_docs = self - .type_polyfills() - .iter() - .filter_map(|t| { - if t.repeq() == RepEquality::Eq { - None - } else { - Some(t.to_md()) - } - }) - .collect::>() - .join("\n"); - format!( - "# Modules\n{}\n# Type Conversions\n{}\n", - module_docs, type_docs - ) - } -} - -impl Documentation for ModulePolyfill { - fn to_md(&self) -> String { - format!( - "## `{}` in terms of `{}`\n{}", - self.new.name.as_str(), - self.old.name.as_str(), - self.funcs - .iter() - .map(|f| f.to_md()) - .collect::>() - .join("\n"), - ) - } -} - -impl Documentation for FuncPolyfill { - fn to_md(&self) -> String { - if self.full_compat() { - format!("* `{}`: full compatibility", self.new.name.as_str()) - } else { - let name = if self.new.name != self.old.name { - format!( - "* `{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("* `{}`", self.new.name.as_str()) - }; - let mut contents = Vec::new(); - for p in self.mapped_params.iter() { - contents.push(if !p.full_compat() { - format!("param {}", p.to_md()) - } else { - format!("param `{}`: compatible", p.new.name.as_str()) - }) - } - for u in self.unknown_params.iter() { - contents.push(format!( - "{} param `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - for r in self.mapped_results.iter() { - contents.push(if !r.full_compat() { - format!("result {}", r.to_md()) - } else { - format!("result `{}`: compatible", r.new.name.as_str()) - }) - } - for u in self.unknown_results.iter() { - contents.push(format!( - "{} result `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - let contents = if contents.is_empty() { - String::new() - } else { - format!(":\n - {}", contents.join("\n - ")) - }; - format!("{}{}", name, contents) - } - } -} - -impl Documentation for ParamPolyfill { - fn to_md(&self) -> String { - let name = if self.new.name != self.old.name { - format!( - "`{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("`{}`", self.new.name.as_str()) - }; - let repr = match self.repeq() { - RepEquality::Eq => "compatible types".to_string(), - RepEquality::Superset => format!( - "`{}` is superset-compatible with `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - RepEquality::NotEq => format!( - "`{}` is incompatible with new `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - }; - format!("{}: {}", name, repr) - } -} - -impl Documentation for TypePolyfill { - fn to_md(&self) -> String { - fn repeq_name(r: RepEquality) -> &'static str { - match r { - RepEquality::Eq => ": compatible", - RepEquality::Superset => ": superset", - RepEquality::NotEq => "", - } - } - match self { - TypePolyfill::OldToNew(o, n) => format!( - "* old `{}` => new `{}`{}", - o.type_name(), - n.type_name(), - repeq_name(self.repeq()) - ), - TypePolyfill::NewToOld(n, o) => format!( - "* new `{}` => old `{}`{}", - n.type_name(), - o.type_name(), - repeq_name(self.repeq()) - ), - } - } -} diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs new file mode 100644 index 000000000..3ba383a92 --- /dev/null +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -0,0 +1,288 @@ +use std::{ + cell::{Ref, RefCell, RefMut}, + fmt, + rc::{Rc, Weak}, +}; + +#[derive(Debug)] +pub enum MdElement { + Section(RefCell), + TypeListing(RefCell), + InterfaceFunc(RefCell), +} + +impl MdElement { + pub fn as_section(&self) -> Ref { + match self { + Self::Section(t) => t.borrow(), + _ => panic!("not a MdSection"), + } + } + + pub fn as_section_mut(&self) -> RefMut { + match self { + Self::Section(t) => t.borrow_mut(), + _ => panic!("not a MdSection"), + } + } + + pub fn as_type_listing(&self) -> Ref { + match self { + Self::TypeListing(t) => t.borrow(), + _ => panic!("not a MdTypeListing"), + } + } + + pub fn as_type_listing_mut(&self) -> RefMut { + match self { + Self::TypeListing(t) => t.borrow_mut(), + _ => panic!("not a MdTypeListing"), + } + } + + pub fn as_interface_func(&self) -> Ref { + match self { + Self::InterfaceFunc(t) => t.borrow(), + _ => panic!("not a MdInterfaceFunc"), + } + } + + pub fn as_interface_func_mut(&self) -> RefMut { + match self { + Self::InterfaceFunc(t) => t.borrow_mut(), + _ => panic!("not a MdInterfaceFunc"), + } + } + + pub fn parent(&self) -> Option> { + match self { + Self::Section(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), + Self::TypeListing(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), + Self::InterfaceFunc(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), + } + } +} + +impl fmt::Display for MdElement { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Section(t) => t.borrow().fmt(f), + Self::TypeListing(t) => t.borrow().fmt(f), + Self::InterfaceFunc(t) => t.borrow().fmt(f), + } + } +} + +fn walk_parents(start: &Weak, cb: &mut impl FnMut(Rc)) { + let mut parent = if let Some(parent) = start.upgrade() { + cb(parent.clone()); + parent + } else { + return; + }; + + while let Some(p) = parent.parent() { + cb(p.clone()); + parent = p; + } +} + +#[derive(Debug)] +pub struct MdSection { + pub id: String, + pub title: String, + pub description: Vec, + pub elements: Vec>, + pub parent: Option>, +} + +impl MdSection { + pub fn new(id: &str, title: &str, parent: Option>) -> MdElement { + MdElement::Section(RefCell::new(Self { + id: id.to_owned(), + title: title.to_owned(), + description: vec![], + elements: vec![], + parent, + })) + } +} + +impl fmt::Display for MdSection { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut heading = "#".to_owned(); + if let Some(parent) = self.parent.as_ref() { + walk_parents(parent, &mut |_| { + heading += "#"; + }); + } + f.write_fmt(format_args!( + "{heading} {title}\n", + heading = heading, + id = self.id, + title = self.title + ))?; + for para in &self.description { + f.write_fmt(format_args!("{}\n", para))?; + } + for el in &self.elements { + f.write_fmt(format_args!("{}\n", el))?; + } + Ok(()) + } +} + +#[derive(Debug)] +pub struct MdTypeListing { + pub id: String, + pub r#type: MdType, + pub description: Vec, + pub elements: Vec, + pub parent: Option>, +} + +#[derive(Debug)] +pub enum MdType { + Enum { repr: String }, + Int { repr: String }, + Flags { repr: String }, + Struct, + Union, + Handle, + Array { r#type: String }, + Pointer { to: String }, + ConstPointer { to: String }, + Builtin { r#type: String }, +} + +#[derive(Debug)] +pub struct MdBullet { + pub id: String, + pub description: String, +} + +impl MdTypeListing { + pub fn new(id: &str, r#type: MdType, parent: Option>) -> MdElement { + MdElement::TypeListing(RefCell::new(Self { + id: id.to_owned(), + r#type, + description: vec![], + elements: vec![], + parent, + })) + } +} + +impl fmt::Display for MdTypeListing { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut heading = "#".to_owned(); + if let Some(parent) = self.parent.as_ref() { + walk_parents(parent, &mut |_| { + heading += "#"; + }); + } + // ### `errno` + f.write_fmt(format_args!( + "{heading} `{id}`\n", + heading = heading, + id = self.id + ))?; + // Error codes returned by function... + for para in &self.description { + f.write_fmt(format_args!("{}\n", para))?; + } + // Enum represented by `u16` + // Variants: + let type_specific = match &self.r#type { + MdType::Enum { repr } => format!("Enum represented by `{}`\n\n**Variants:**\n", repr), + MdType::Int { repr } => format!("Int represented by `{}`\n\n**Const:**\n", repr), + MdType::Flags { repr } => format!("Flags represented by `{}`\n\n**Flags:**\n", repr), + MdType::Struct => "\n**Struct members:**\n".to_owned(), + MdType::Union => "\n**Union variants:**\n".to_owned(), + MdType::Handle => "\n**Supertypes:**\n".to_owned(), + MdType::Array { r#type } => format!("Array of `{}`", r#type), + MdType::Pointer { to } => format!("Pointer to `{}`", to), + MdType::ConstPointer { to } => format!("Const pointer to `{}`", to), + MdType::Builtin { r#type } => format!("Builtin type `{}`", r#type), + }; + f.write_str(&type_specific)?; + // - `success` + // No error occurred. System call completed successfully. + for el in &self.elements { + f.write_fmt(format_args!( + "- `{id}`\n\n", + this_id = self.id, + id = el.id + ))?; + f.write_fmt(format_args!("\t{}\n", &el.description))?; + } + Ok(()) + } +} + +#[derive(Debug)] +pub struct MdInterfaceFunc { + pub id: String, + pub description: Vec, + pub parameters: Vec, + pub results: Vec, + pub parent: Option>, +} + +impl MdInterfaceFunc { + pub fn new(id: &str, parent: Option>) -> MdElement { + MdElement::InterfaceFunc(RefCell::new(Self { + id: id.to_owned(), + description: vec![], + parameters: vec![], + results: vec![], + parent, + })) + } +} + +impl fmt::Display for MdInterfaceFunc { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut heading = "#".to_owned(); + if let Some(parent) = self.parent.as_ref() { + walk_parents(parent, &mut |_| { + heading += "#"; + }); + } + // ### `args_get` + f.write_fmt(format_args!( + "{heading} `{id}`\n\n", + heading = heading, + id = self.id + ))?; + // Read command-line argument data... + for desc in &self.description { + f.write_fmt(format_args!("{}\n", desc))?; + } + // Parameters: + // * `argv` + // `argv` has type... + f.write_str("\n**Parameters:**\n\n")?; + for param in &self.parameters { + f.write_fmt(format_args!( + "- `{param_id}`\n\n", + id = self.id, + param_id = param.id + ))?; + f.write_fmt(format_args!("\t{}\n", ¶m.description))?; + } + // Results: + // * `error` + // `error` has type `errno` + f.write_str("\n**Results:**\n\n")?; + for result in &self.results { + f.write_fmt(format_args!( + "- `{res_id}`\n\n", + id = self.id, + res_id = result.id + ))?; + f.write_fmt(format_args!("\t{}\n", &result.description))?; + } + Ok(()) + } +} diff --git a/proposals/clocks/tools/witx/src/docs/mod.rs b/proposals/clocks/tools/witx/src/docs/mod.rs new file mode 100644 index 000000000..219c7d716 --- /dev/null +++ b/proposals/clocks/tools/witx/src/docs/mod.rs @@ -0,0 +1,411 @@ +mod md; + +pub use self::md::*; +use crate::ast::*; +use crate::polyfill::*; +use crate::RepEquality; +use std::rc::{Rc, Weak}; + +pub trait Documentation { + fn to_md(&self) -> String; +} +pub trait ToMarkdown { + fn gen(&self, _parent: Option>) -> Rc; +} + +impl Documentation for Document { + fn to_md(&self) -> String { + format!("{}", self.gen(None)) + } +} + +impl ToMarkdown for Document { + fn gen(&self, parent: Option>) -> Rc { + let doc = Rc::new(MdSection::new("root", "Root", parent)); + let types = Rc::new(MdSection::new("types", "Types", Some(Rc::downgrade(&doc)))); + for typename in self.typenames() { + types + .as_section_mut() + .elements + .push(typename.gen(Some(Rc::downgrade(&types)))); + } + doc.as_section_mut().elements.push(types); + let modules = Rc::new(MdSection::new( + "modules", + "Modules", + Some(Rc::downgrade(&doc)), + )); + for module in self.modules() { + modules + .as_section_mut() + .elements + .push(module.gen(Some(Rc::downgrade(&modules)))); + } + doc.as_section_mut().elements.push(modules); + doc + } +} + +impl BuiltinType { + pub fn type_name(&self) -> &'static str { + match self { + BuiltinType::String => "string", + BuiltinType::Char8 => "char8", + BuiltinType::USize => "usize", + BuiltinType::U8 => "u8", + BuiltinType::U16 => "u16", + BuiltinType::U32 => "u32", + BuiltinType::U64 => "u64", + BuiltinType::S8 => "s8", + BuiltinType::S16 => "s16", + BuiltinType::S32 => "s32", + BuiltinType::S64 => "s64", + BuiltinType::F32 => "f32", + BuiltinType::F64 => "f64", + } + } +} + +impl ToMarkdown for NamedType { + fn gen(&self, parent: Option>) -> Rc { + match &self.tref { + TypeRef::Value(v) => { + let md_type = MdType::from(&**v); + let mut elements: Vec<_> = match &**v { + Type::Enum(a) => a.variants.iter().map(MdBullet::from).collect(), + Type::Int(a) => a.consts.iter().map(MdBullet::from).collect(), + Type::Flags(a) => a.flags.iter().map(MdBullet::from).collect(), + Type::Struct(a) => a.members.iter().map(MdBullet::from).collect(), + Type::Union(a) => a.variants.iter().map(MdBullet::from).collect(), + Type::Handle(a) => a.supertypes.iter().map(MdBullet::from).collect(), + _ => vec![], + }; + let listing = Rc::new(MdTypeListing::new(self.name.as_str(), md_type, parent)); + listing + .as_type_listing_mut() + .description + .push(self.docs.clone()); + listing.as_type_listing_mut().elements.append(&mut elements); + listing + } + TypeRef::Name(n) => { + let sec = Rc::new(MdSection::new( + self.name.as_str(), + self.name.as_str(), + parent, + )); + sec.as_section_mut().description.push(self.docs.clone()); + sec.as_section_mut() + .description + .push(format!("Alias to {}", n.name.as_str())); + sec + } + } + } +} + +impl From<&Type> for MdType { + fn from(r#type: &Type) -> Self { + match r#type { + Type::Enum(a) => Self::Enum { + repr: a.repr.type_name().to_owned(), + }, + Type::Int(a) => Self::Int { + repr: a.repr.type_name().to_owned(), + }, + Type::Flags(a) => Self::Flags { + repr: a.repr.type_name().to_owned(), + }, + Type::Struct(_) => Self::Struct, + Type::Union(_) => Self::Union, + Type::Handle(_) => Self::Handle, + Type::Array(a) => Self::Array { + r#type: a.type_name().to_owned(), + }, + Type::Pointer(a) => Self::Pointer { + to: a.type_name().to_owned(), + }, + Type::ConstPointer(a) => Self::ConstPointer { + to: a.type_name().to_owned(), + }, + Type::Builtin(a) => Self::Builtin { + r#type: a.type_name().to_owned(), + }, + } + } +} + +macro_rules! impl_mdbullet { + ($from:ty) => { + impl From<$from> for MdBullet { + fn from(f: $from) -> Self { + Self { + id: f.name.as_str().to_owned(), + description: f.docs.clone(), + } + } + } + }; +} + +impl_mdbullet!(&EnumVariant); +impl_mdbullet!(&IntConst); +impl_mdbullet!(&FlagsMember); +impl_mdbullet!(&StructMember); +impl_mdbullet!(&UnionVariant); + +impl From<&TypeRef> for MdBullet { + fn from(t: &TypeRef) -> Self { + Self { + id: t.type_name().to_owned(), + description: "".to_owned(), // FIXME + } + } +} + +impl TypeRef { + pub fn type_name(&self) -> String { + match self { + TypeRef::Name(n) => n.name.as_str().to_string(), + TypeRef::Value(ref v) => match &**v { + Type::Array(a) => format!("Array<{}>", a.type_name()), + Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), + Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), + Type::Builtin(b) => b.type_name().to_string(), + Type::Enum { .. } + | Type::Int { .. } + | Type::Flags { .. } + | Type::Struct { .. } + | Type::Union { .. } + | Type::Handle { .. } => { + unimplemented!("type_name of anonymous compound datatypes") + } + }, + } + } +} + +impl IntRepr { + fn type_name(&self) -> &'static str { + match self { + IntRepr::U8 => "u8", + IntRepr::U16 => "u16", + IntRepr::U32 => "u32", + IntRepr::U64 => "u64", + } + } +} + +impl ToMarkdown for Module { + fn gen(&self, parent: Option>) -> Rc { + let sec = Rc::new(MdSection::new( + self.name.as_str(), + &format!("`{}`", self.name.as_str()), + parent, + )); + let imports = Rc::new(MdSection::new( + "imports", + "Imports", + Some(Rc::downgrade(&sec)), + )); + // FIXME + for import in self.imports() { + let desc = match import.variant { + ModuleImportVariant::Memory => format!("* {}: Memory", import.name.as_str()), + }; + imports.as_section_mut().description.push(desc); + } + sec.as_section_mut().elements.push(imports); + let funcs = Rc::new(MdSection::new( + "functions", + "Functions", + Some(Rc::downgrade(&sec)), + )); + funcs + .as_section_mut() + .elements + .extend(self.funcs().map(|f| f.gen(Some(Rc::downgrade(&funcs))))); + sec.as_section_mut().elements.push(funcs); + sec + } +} + +impl ToMarkdown for InterfaceFunc { + fn gen(&self, parent: Option>) -> Rc { + let func = Rc::new(MdInterfaceFunc::new(self.name.as_str(), parent)); + func.as_interface_func_mut() + .description + .push(self.docs.clone()); + func.as_interface_func_mut() + .parameters + .extend(self.params.iter().map(MdBullet::from)); + func.as_interface_func_mut() + .results + .extend(self.results.iter().map(MdBullet::from)); + func + } +} + +impl From<&InterfaceFuncParam> for MdBullet { + fn from(param: &InterfaceFuncParam) -> Self { + Self { + id: param.name.as_str().to_owned(), + description: format!( + "`{}` has type `{}`\n{}\n\n", + param.name.as_str(), + param.tref.type_name(), + param.docs + ), + } + } +} + +// TODO polyfill +impl Documentation for Polyfill { + fn to_md(&self) -> String { + let module_docs = self + .modules + .iter() + .map(|m| m.to_md()) + .collect::>() + .join("\n"); + let type_docs = self + .type_polyfills() + .iter() + .filter_map(|t| { + if t.repeq() == RepEquality::Eq { + None + } else { + Some(t.to_md()) + } + }) + .collect::>() + .join("\n"); + format!( + "# Modules\n{}\n# Type Conversions\n{}\n", + module_docs, type_docs + ) + } +} + +impl Documentation for ModulePolyfill { + fn to_md(&self) -> String { + format!( + "## `{}` in terms of `{}`\n{}", + self.new.name.as_str(), + self.old.name.as_str(), + self.funcs + .iter() + .map(|f| f.to_md()) + .collect::>() + .join("\n"), + ) + } +} + +impl Documentation for FuncPolyfill { + fn to_md(&self) -> String { + if self.full_compat() { + format!("* `{}`: full compatibility", self.new.name.as_str()) + } else { + let name = if self.new.name != self.old.name { + format!( + "* `{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("* `{}`", self.new.name.as_str()) + }; + let mut contents = Vec::new(); + for p in self.mapped_params.iter() { + contents.push(if !p.full_compat() { + format!("param {}", p.to_md()) + } else { + format!("param `{}`: compatible", p.new.name.as_str()) + }) + } + for u in self.unknown_params.iter() { + contents.push(format!( + "{} param `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + for r in self.mapped_results.iter() { + contents.push(if !r.full_compat() { + format!("result {}", r.to_md()) + } else { + format!("result `{}`: compatible", r.new.name.as_str()) + }) + } + for u in self.unknown_results.iter() { + contents.push(format!( + "{} result `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + let contents = if contents.is_empty() { + String::new() + } else { + format!(":\n - {}", contents.join("\n - ")) + }; + format!("{}{}", name, contents) + } + } +} + +impl Documentation for ParamPolyfill { + fn to_md(&self) -> String { + let name = if self.new.name != self.old.name { + format!( + "`{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("`{}`", self.new.name.as_str()) + }; + let repr = match self.repeq() { + RepEquality::Eq => "compatible types".to_string(), + RepEquality::Superset => format!( + "`{}` is superset-compatible with `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + RepEquality::NotEq => format!( + "`{}` is incompatible with new `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + }; + format!("{}: {}", name, repr) + } +} + +impl Documentation for TypePolyfill { + fn to_md(&self) -> String { + fn repeq_name(r: RepEquality) -> &'static str { + match r { + RepEquality::Eq => ": compatible", + RepEquality::Superset => ": superset", + RepEquality::NotEq => "", + } + } + match self { + TypePolyfill::OldToNew(o, n) => format!( + "* old `{}` => new `{}`{}", + o.type_name(), + n.type_name(), + repeq_name(self.repeq()) + ), + TypePolyfill::NewToOld(n, o) => format!( + "* new `{}` => old `{}`{}", + n.type_name(), + o.type_name(), + repeq_name(self.repeq()) + ), + } + } +} From 874aff4b9696393a19773cfc62692092388587d2 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 9 Jan 2020 22:41:43 +0100 Subject: [PATCH 0443/1772] Reorganise and refactor handling on header nesting This commit reorganises the `docs` module into a couple of submodules for easier navigation. It also replaces manual specifying of nesting level upon Markdown element creation for automatic header generation. I should note here that I've decided to simplify the code over the previous commit, as the previous seemed unnecessary bloated and really subtle in places which IMHO would very likely cause some maintenance hell in the future. --- proposals/random/tools/witx/src/docs.rs | 710 -------------------- proposals/random/tools/witx/src/docs/md.rs | 288 ++++++++ proposals/random/tools/witx/src/docs/mod.rs | 411 +++++++++++ 3 files changed, 699 insertions(+), 710 deletions(-) delete mode 100644 proposals/random/tools/witx/src/docs.rs create mode 100644 proposals/random/tools/witx/src/docs/md.rs create mode 100644 proposals/random/tools/witx/src/docs/mod.rs diff --git a/proposals/random/tools/witx/src/docs.rs b/proposals/random/tools/witx/src/docs.rs deleted file mode 100644 index 2e358b15e..000000000 --- a/proposals/random/tools/witx/src/docs.rs +++ /dev/null @@ -1,710 +0,0 @@ -use crate::ast::*; -use crate::polyfill::*; -use crate::RepEquality; -use std::fmt; - -#[derive(Debug)] -pub enum MdBlockElement { - Section(MdSection), - TypeListing(MdTypeListing), - InterfaceFunc(MdInterfaceFunc), - Root(MdRoot), -} - -impl fmt::Display for MdBlockElement { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Section(sec) => sec.fmt(f), - Self::TypeListing(listing) => listing.fmt(f), - Self::InterfaceFunc(func) => func.fmt(f), - Self::Root(root) => root.fmt(f), - } - } -} - -#[derive(Debug, Default)] -pub struct MdRoot { - blocks: Vec, -} - -impl fmt::Display for MdRoot { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for block in &self.blocks { - block.fmt(f)?; - } - Ok(()) - } -} - -#[derive(Debug, Clone)] -struct MdParagraph { - para: String, -} - -impl MdParagraph { - fn new>(para: S) -> Self { - Self { - para: para.as_ref().to_owned(), - } - } - - fn with_links_parsed>(para: S) -> Self { - let to_parse = para.as_ref(); - let mut parsed = String::with_capacity(to_parse.len()); - let mut temp = String::with_capacity(to_parse.len()); - let mut is_link = false; - let mut eaten = None; - for ch in to_parse.chars() { - match (ch, is_link) { - ('`', false) => { - // found the beginning of a link - is_link = true; - } - ('`', true) => { - // reached the end, expand into a link! - let expanded = format!("[`{}`](#{})", temp, temp); - parsed.push_str(&expanded); - temp.drain(..); - is_link = false; - } - (':', true) => { - if let Some(_) = eaten { - // swap for '.' - temp.push('.'); - eaten = None; - } else { - eaten = Some(':'); - } - } - (ch, false) => parsed.push(ch), - (ch, true) => temp.push(ch), - } - } - Self::new(parsed) - } -} - -impl fmt::Display for MdParagraph { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_fmt(format_args!("{}\n", &self.para)) - } -} - -#[allow(dead_code)] -#[derive(Debug, Clone)] -enum MdHeading { - Header { - id: String, - title: String, - doc_level: usize, - }, - Bullet { - id: String, - title: String, - }, -} - -impl MdHeading { - fn new_header>(title: S, doc_level: usize) -> Self { - let id = title.as_ref().replace(" ", "_"); - let title = title.as_ref().to_owned(); - Self::Header { - id, - title, - doc_level, - } - } - - fn new_bullet>(title: S) -> Self { - let id = title.as_ref().replace(" ", "_"); - let title = title.as_ref().to_owned(); - Self::Bullet { id, title } - } - - fn id(&self) -> &str { - match self { - Self::Header { ref id, .. } => id, - Self::Bullet { ref id, .. } => id, - } - } - - fn set_id>(&mut self, id: S) { - let s_id = match self { - Self::Header { ref mut id, .. } => id, - Self::Bullet { ref mut id, .. } => id, - }; - *s_id = id.as_ref().to_owned(); - } -} - -impl fmt::Display for MdHeading { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let (id, title, heading) = match self { - Self::Header { - id, - title, - doc_level, - } => (id, title, "#".repeat(*doc_level)), - Self::Bullet { id, title } => (id, title, "-".to_owned()), - }; - f.write_fmt(format_args!( - "{heading} {title}\n", - heading = heading, - id = id, - title = title - )) - } -} - -#[derive(Debug)] -pub struct MdSection { - heading: MdHeading, - description: Vec, - blocks: Vec, -} - -impl MdSection { - fn new(heading: MdHeading) -> Self { - Self { - heading, - description: vec![], - blocks: vec![], - } - } -} - -impl fmt::Display for MdSection { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.heading.fmt(f)?; - for para in &self.description { - para.fmt(f)?; - } - for el in &self.blocks { - el.fmt(f)?; - } - Ok(()) - } -} - -#[allow(dead_code)] -#[derive(Debug)] -enum MdType { - Enum { repr: String }, - Int { repr: String }, - Flags { repr: String }, - Struct, - Union, - Handle, - Array { r#type: String }, - Pointer { to: String }, - ConstPointer { to: String }, - Builtin { r#type: String }, -} - -impl fmt::Display for MdType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let type_specific = match self { - MdType::Enum { repr } => format!("Enum represented by `{}`\n\n**Variants:**", repr), - MdType::Int { repr } => format!("Int represented by `{}`\n\n**Const:**", repr), - MdType::Flags { repr } => format!("Flags represented by `{}`\n\n**Flags:**", repr), - MdType::Struct => "\n**Struct members:**".to_owned(), - MdType::Union => "\n**Union variants:**".to_owned(), - MdType::Handle => "\n**Supertypes:**".to_owned(), - MdType::Array { r#type } => format!("Array of `{}`", r#type), - MdType::Pointer { to } => format!("Pointer to `{}`", to), - MdType::ConstPointer { to } => format!("Const pointer to `{}`", to), - MdType::Builtin { r#type } => format!("Builtin type `{}`", r#type), - }; - f.write_fmt(format_args!("{}\n", type_specific)) - } -} - -#[derive(Debug, Clone)] -struct MdListingEntry { - heading: MdHeading, - description: Vec, -} - -impl fmt::Display for MdListingEntry { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.heading.fmt(f)?; - for para in &self.description { - f.write_fmt(format_args!("\n\t{}\n", para))?; - } - Ok(()) - } -} - -#[derive(Debug)] -pub struct MdTypeListing { - heading: MdHeading, - r#type: MdType, - description: Vec, - entries: Vec, -} - -impl MdTypeListing { - fn new(heading: MdHeading, r#type: MdType) -> Self { - Self { - heading, - r#type, - description: vec![], - entries: vec![], - } - } -} - -impl fmt::Display for MdTypeListing { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.heading.fmt(f)?; - for para in &self.description { - para.fmt(f)?; - } - self.r#type.fmt(f)?; - for el in &self.entries { - // prepend id of this MdTypeListing in order to generate scoped - // references of list entries - let id = format!("{}.{}", self.heading.id(), el.heading.id()); - let mut new_el = el.clone(); - new_el.heading.set_id(id); - new_el.fmt(f)?; - } - Ok(()) - } -} - -#[derive(Debug)] -pub struct MdInterfaceFunc { - heading: MdHeading, - description: Vec, - parameters: Vec, - results: Vec, -} - -impl MdInterfaceFunc { - fn new(heading: MdHeading) -> Self { - Self { - heading, - description: vec![], - parameters: vec![], - results: vec![], - } - } -} - -impl fmt::Display for MdInterfaceFunc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.heading.fmt(f)?; - for desc in &self.description { - desc.fmt(f)?; - } - f.write_str("\n**Parameters:**\n\n")?; - for el in &self.parameters { - // prepend id of this MdTypeListing in order to generate scoped - // references of list entries - let id = format!("{}.{}", self.heading.id(), el.heading.id()); - let mut new_el = el.clone(); - new_el.heading.set_id(id); - new_el.fmt(f)?; - } - f.write_str("\n**Results:**\n\n")?; - for el in &self.results { - // prepend id of this MdTypeListing in order to generate scoped - // references of list entries - let id = format!("{}.{}", self.heading.id(), el.heading.id()); - let mut new_el = el.clone(); - new_el.heading.set_id(id); - new_el.fmt(f)?; - } - Ok(()) - } -} - -pub trait Documentation { - fn to_md(&self) -> String { - format!("{}", self.gen(0)) - } - - fn gen(&self, _level: usize) -> MdBlockElement { - MdBlockElement::Root(MdRoot::default()) - } -} - -impl Documentation for Document { - fn gen(&self, level: usize) -> MdBlockElement { - let mut doc = MdRoot::default(); - let mut types = MdSection::new(MdHeading::new_header("Types", level + 1)); - for typename in self.typenames() { - types.blocks.push(typename.gen(level + 2)); - } - doc.blocks.push(MdBlockElement::Section(types)); - let mut modules = MdSection::new(MdHeading::new_header("Modules", level + 1)); - for module in self.modules() { - modules.blocks.push(module.gen(level + 2)); - } - doc.blocks.push(MdBlockElement::Section(modules)); - MdBlockElement::Root(doc) - } -} - -impl BuiltinType { - pub fn type_name(&self) -> &'static str { - match self { - BuiltinType::String => "string", - BuiltinType::Char8 => "char8", - BuiltinType::USize => "usize", - BuiltinType::U8 => "u8", - BuiltinType::U16 => "u16", - BuiltinType::U32 => "u32", - BuiltinType::U64 => "u64", - BuiltinType::S8 => "s8", - BuiltinType::S16 => "s16", - BuiltinType::S32 => "s32", - BuiltinType::S64 => "s64", - BuiltinType::F32 => "f32", - BuiltinType::F64 => "f64", - } - } -} - -impl Documentation for NamedType { - fn gen(&self, level: usize) -> MdBlockElement { - match &self.tref { - TypeRef::Value(v) => { - let md_type = MdType::from(&**v); - let mut entries: Vec<_> = match &**v { - Type::Enum(a) => a.variants.iter().map(MdListingEntry::from).collect(), - Type::Int(a) => a.consts.iter().map(MdListingEntry::from).collect(), - Type::Flags(a) => a.flags.iter().map(MdListingEntry::from).collect(), - Type::Struct(a) => a.members.iter().map(MdListingEntry::from).collect(), - Type::Union(a) => a.variants.iter().map(MdListingEntry::from).collect(), - Type::Handle(a) => a.supertypes.iter().map(MdListingEntry::from).collect(), - _ => vec![], - }; - let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); - heading.set_id(self.name.as_str()); - let mut listing = MdTypeListing::new(heading, md_type); - listing - .description - .push(MdParagraph::with_links_parsed(&self.docs)); - listing.entries.append(&mut entries); - MdBlockElement::TypeListing(listing) - } - TypeRef::Name(n) => { - let mut heading = MdHeading::new_header(self.name.as_str(), level); - heading.set_id(self.name.as_str()); - let mut sec = MdSection::new(heading); - sec.description - .push(MdParagraph::with_links_parsed(&self.docs)); - sec.description.push(MdParagraph::with_links_parsed(format!( - "Alias to {}", - n.name.as_str() - ))); - MdBlockElement::Section(sec) - } - } - } -} - -impl From<&Type> for MdType { - fn from(r#type: &Type) -> Self { - match r#type { - Type::Enum(a) => Self::Enum { - repr: a.repr.type_name().to_owned(), - }, - Type::Int(a) => Self::Int { - repr: a.repr.type_name().to_owned(), - }, - Type::Flags(a) => Self::Flags { - repr: a.repr.type_name().to_owned(), - }, - Type::Struct(_) => Self::Struct, - Type::Union(_) => Self::Union, - Type::Handle(_) => Self::Handle, - Type::Array(a) => Self::Array { - r#type: a.type_name().to_owned(), - }, - Type::Pointer(a) => Self::Pointer { - to: a.type_name().to_owned(), - }, - Type::ConstPointer(a) => Self::ConstPointer { - to: a.type_name().to_owned(), - }, - Type::Builtin(a) => Self::Builtin { - r#type: a.type_name().to_owned(), - }, - } - } -} - -macro_rules! impl_mdlistingentry { - ($from:ty) => { - impl From<$from> for MdListingEntry { - fn from(f: $from) -> Self { - let mut heading = MdHeading::new_bullet(format!("`{}`", f.name.as_str())); - heading.set_id(f.name.as_str()); - Self { - heading, - description: vec![MdParagraph::with_links_parsed(&f.docs)], - } - } - } - }; -} - -impl_mdlistingentry!(&EnumVariant); -impl_mdlistingentry!(&IntConst); -impl_mdlistingentry!(&FlagsMember); -impl_mdlistingentry!(&StructMember); -impl_mdlistingentry!(&UnionVariant); - -impl From<&TypeRef> for MdListingEntry { - fn from(t: &TypeRef) -> Self { - let mut heading = MdHeading::new_bullet(format!("`{}`", t.type_name())); - heading.set_id(t.type_name()); - Self { - heading, - description: vec![], - } - } -} - -impl TypeRef { - pub fn type_name(&self) -> String { - match self { - TypeRef::Name(n) => n.name.as_str().to_string(), - TypeRef::Value(ref v) => match &**v { - Type::Array(a) => format!("Array<{}>", a.type_name()), - Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), - Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), - Type::Builtin(b) => b.type_name().to_string(), - Type::Enum { .. } - | Type::Int { .. } - | Type::Flags { .. } - | Type::Struct { .. } - | Type::Union { .. } - | Type::Handle { .. } => { - unimplemented!("type_name of anonymous compound datatypes") - } - }, - } - } -} - -impl IntRepr { - fn type_name(&self) -> &'static str { - match self { - IntRepr::U8 => "u8", - IntRepr::U16 => "u16", - IntRepr::U32 => "u32", - IntRepr::U64 => "u64", - } - } -} - -impl Documentation for Module { - fn gen(&self, level: usize) -> MdBlockElement { - let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); - heading.set_id(self.name.as_str()); - let mut sec = MdSection::new(heading); - let mut imports = MdSection::new(MdHeading::new_header("Imports", level + 1)); - // FIXME - for import in self.imports() { - let desc = match import.variant { - ModuleImportVariant::Memory => { - MdParagraph::with_links_parsed(format!("* {}: Memory", import.name.as_str())) - } - }; - imports.description.push(desc); - } - sec.blocks.push(MdBlockElement::Section(imports)); - let mut funcs = MdSection::new(MdHeading::new_header("Functions", level + 1)); - funcs.blocks.extend(self.funcs().map(|f| f.gen(level + 2))); - sec.blocks.push(MdBlockElement::Section(funcs)); - MdBlockElement::Section(sec) - } -} - -impl Documentation for InterfaceFunc { - fn gen(&self, level: usize) -> MdBlockElement { - let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); - heading.set_id(self.name.as_str()); - let mut func = MdInterfaceFunc::new(heading); - func.description - .push(MdParagraph::with_links_parsed(&self.docs)); - func.parameters - .extend(self.params.iter().map(MdListingEntry::from)); - func.results - .extend(self.results.iter().map(MdListingEntry::from)); - MdBlockElement::InterfaceFunc(func) - } -} - -impl From<&InterfaceFuncParam> for MdListingEntry { - fn from(param: &InterfaceFuncParam) -> Self { - let mut heading = MdHeading::new_bullet(format!("`{}`", param.name.as_str())); - heading.set_id(param.name.as_str()); - let mut description = vec![]; - description.push(MdParagraph::with_links_parsed(format!( - "`{}` has type `{}`.", - param.name.as_str(), - param.tref.type_name() - ))); - description.push(MdParagraph::with_links_parsed(¶m.docs)); - Self { - heading, - description, - } - } -} - -// TODO -// Generate nicely-formatted docs for polyfill -impl Documentation for Polyfill { - fn to_md(&self) -> String { - let module_docs = self - .modules - .iter() - .map(|m| m.to_md()) - .collect::>() - .join("\n"); - let type_docs = self - .type_polyfills() - .iter() - .filter_map(|t| { - if t.repeq() == RepEquality::Eq { - None - } else { - Some(t.to_md()) - } - }) - .collect::>() - .join("\n"); - format!( - "# Modules\n{}\n# Type Conversions\n{}\n", - module_docs, type_docs - ) - } -} - -impl Documentation for ModulePolyfill { - fn to_md(&self) -> String { - format!( - "## `{}` in terms of `{}`\n{}", - self.new.name.as_str(), - self.old.name.as_str(), - self.funcs - .iter() - .map(|f| f.to_md()) - .collect::>() - .join("\n"), - ) - } -} - -impl Documentation for FuncPolyfill { - fn to_md(&self) -> String { - if self.full_compat() { - format!("* `{}`: full compatibility", self.new.name.as_str()) - } else { - let name = if self.new.name != self.old.name { - format!( - "* `{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("* `{}`", self.new.name.as_str()) - }; - let mut contents = Vec::new(); - for p in self.mapped_params.iter() { - contents.push(if !p.full_compat() { - format!("param {}", p.to_md()) - } else { - format!("param `{}`: compatible", p.new.name.as_str()) - }) - } - for u in self.unknown_params.iter() { - contents.push(format!( - "{} param `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - for r in self.mapped_results.iter() { - contents.push(if !r.full_compat() { - format!("result {}", r.to_md()) - } else { - format!("result `{}`: compatible", r.new.name.as_str()) - }) - } - for u in self.unknown_results.iter() { - contents.push(format!( - "{} result `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - let contents = if contents.is_empty() { - String::new() - } else { - format!(":\n - {}", contents.join("\n - ")) - }; - format!("{}{}", name, contents) - } - } -} - -impl Documentation for ParamPolyfill { - fn to_md(&self) -> String { - let name = if self.new.name != self.old.name { - format!( - "`{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("`{}`", self.new.name.as_str()) - }; - let repr = match self.repeq() { - RepEquality::Eq => "compatible types".to_string(), - RepEquality::Superset => format!( - "`{}` is superset-compatible with `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - RepEquality::NotEq => format!( - "`{}` is incompatible with new `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - }; - format!("{}: {}", name, repr) - } -} - -impl Documentation for TypePolyfill { - fn to_md(&self) -> String { - fn repeq_name(r: RepEquality) -> &'static str { - match r { - RepEquality::Eq => ": compatible", - RepEquality::Superset => ": superset", - RepEquality::NotEq => "", - } - } - match self { - TypePolyfill::OldToNew(o, n) => format!( - "* old `{}` => new `{}`{}", - o.type_name(), - n.type_name(), - repeq_name(self.repeq()) - ), - TypePolyfill::NewToOld(n, o) => format!( - "* new `{}` => old `{}`{}", - n.type_name(), - o.type_name(), - repeq_name(self.repeq()) - ), - } - } -} diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs new file mode 100644 index 000000000..3ba383a92 --- /dev/null +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -0,0 +1,288 @@ +use std::{ + cell::{Ref, RefCell, RefMut}, + fmt, + rc::{Rc, Weak}, +}; + +#[derive(Debug)] +pub enum MdElement { + Section(RefCell), + TypeListing(RefCell), + InterfaceFunc(RefCell), +} + +impl MdElement { + pub fn as_section(&self) -> Ref { + match self { + Self::Section(t) => t.borrow(), + _ => panic!("not a MdSection"), + } + } + + pub fn as_section_mut(&self) -> RefMut { + match self { + Self::Section(t) => t.borrow_mut(), + _ => panic!("not a MdSection"), + } + } + + pub fn as_type_listing(&self) -> Ref { + match self { + Self::TypeListing(t) => t.borrow(), + _ => panic!("not a MdTypeListing"), + } + } + + pub fn as_type_listing_mut(&self) -> RefMut { + match self { + Self::TypeListing(t) => t.borrow_mut(), + _ => panic!("not a MdTypeListing"), + } + } + + pub fn as_interface_func(&self) -> Ref { + match self { + Self::InterfaceFunc(t) => t.borrow(), + _ => panic!("not a MdInterfaceFunc"), + } + } + + pub fn as_interface_func_mut(&self) -> RefMut { + match self { + Self::InterfaceFunc(t) => t.borrow_mut(), + _ => panic!("not a MdInterfaceFunc"), + } + } + + pub fn parent(&self) -> Option> { + match self { + Self::Section(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), + Self::TypeListing(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), + Self::InterfaceFunc(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), + } + } +} + +impl fmt::Display for MdElement { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Section(t) => t.borrow().fmt(f), + Self::TypeListing(t) => t.borrow().fmt(f), + Self::InterfaceFunc(t) => t.borrow().fmt(f), + } + } +} + +fn walk_parents(start: &Weak, cb: &mut impl FnMut(Rc)) { + let mut parent = if let Some(parent) = start.upgrade() { + cb(parent.clone()); + parent + } else { + return; + }; + + while let Some(p) = parent.parent() { + cb(p.clone()); + parent = p; + } +} + +#[derive(Debug)] +pub struct MdSection { + pub id: String, + pub title: String, + pub description: Vec, + pub elements: Vec>, + pub parent: Option>, +} + +impl MdSection { + pub fn new(id: &str, title: &str, parent: Option>) -> MdElement { + MdElement::Section(RefCell::new(Self { + id: id.to_owned(), + title: title.to_owned(), + description: vec![], + elements: vec![], + parent, + })) + } +} + +impl fmt::Display for MdSection { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut heading = "#".to_owned(); + if let Some(parent) = self.parent.as_ref() { + walk_parents(parent, &mut |_| { + heading += "#"; + }); + } + f.write_fmt(format_args!( + "{heading} {title}\n", + heading = heading, + id = self.id, + title = self.title + ))?; + for para in &self.description { + f.write_fmt(format_args!("{}\n", para))?; + } + for el in &self.elements { + f.write_fmt(format_args!("{}\n", el))?; + } + Ok(()) + } +} + +#[derive(Debug)] +pub struct MdTypeListing { + pub id: String, + pub r#type: MdType, + pub description: Vec, + pub elements: Vec, + pub parent: Option>, +} + +#[derive(Debug)] +pub enum MdType { + Enum { repr: String }, + Int { repr: String }, + Flags { repr: String }, + Struct, + Union, + Handle, + Array { r#type: String }, + Pointer { to: String }, + ConstPointer { to: String }, + Builtin { r#type: String }, +} + +#[derive(Debug)] +pub struct MdBullet { + pub id: String, + pub description: String, +} + +impl MdTypeListing { + pub fn new(id: &str, r#type: MdType, parent: Option>) -> MdElement { + MdElement::TypeListing(RefCell::new(Self { + id: id.to_owned(), + r#type, + description: vec![], + elements: vec![], + parent, + })) + } +} + +impl fmt::Display for MdTypeListing { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut heading = "#".to_owned(); + if let Some(parent) = self.parent.as_ref() { + walk_parents(parent, &mut |_| { + heading += "#"; + }); + } + // ### `errno` + f.write_fmt(format_args!( + "{heading} `{id}`\n", + heading = heading, + id = self.id + ))?; + // Error codes returned by function... + for para in &self.description { + f.write_fmt(format_args!("{}\n", para))?; + } + // Enum represented by `u16` + // Variants: + let type_specific = match &self.r#type { + MdType::Enum { repr } => format!("Enum represented by `{}`\n\n**Variants:**\n", repr), + MdType::Int { repr } => format!("Int represented by `{}`\n\n**Const:**\n", repr), + MdType::Flags { repr } => format!("Flags represented by `{}`\n\n**Flags:**\n", repr), + MdType::Struct => "\n**Struct members:**\n".to_owned(), + MdType::Union => "\n**Union variants:**\n".to_owned(), + MdType::Handle => "\n**Supertypes:**\n".to_owned(), + MdType::Array { r#type } => format!("Array of `{}`", r#type), + MdType::Pointer { to } => format!("Pointer to `{}`", to), + MdType::ConstPointer { to } => format!("Const pointer to `{}`", to), + MdType::Builtin { r#type } => format!("Builtin type `{}`", r#type), + }; + f.write_str(&type_specific)?; + // - `success` + // No error occurred. System call completed successfully. + for el in &self.elements { + f.write_fmt(format_args!( + "- `{id}`\n\n", + this_id = self.id, + id = el.id + ))?; + f.write_fmt(format_args!("\t{}\n", &el.description))?; + } + Ok(()) + } +} + +#[derive(Debug)] +pub struct MdInterfaceFunc { + pub id: String, + pub description: Vec, + pub parameters: Vec, + pub results: Vec, + pub parent: Option>, +} + +impl MdInterfaceFunc { + pub fn new(id: &str, parent: Option>) -> MdElement { + MdElement::InterfaceFunc(RefCell::new(Self { + id: id.to_owned(), + description: vec![], + parameters: vec![], + results: vec![], + parent, + })) + } +} + +impl fmt::Display for MdInterfaceFunc { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut heading = "#".to_owned(); + if let Some(parent) = self.parent.as_ref() { + walk_parents(parent, &mut |_| { + heading += "#"; + }); + } + // ### `args_get` + f.write_fmt(format_args!( + "{heading} `{id}`\n\n", + heading = heading, + id = self.id + ))?; + // Read command-line argument data... + for desc in &self.description { + f.write_fmt(format_args!("{}\n", desc))?; + } + // Parameters: + // * `argv` + // `argv` has type... + f.write_str("\n**Parameters:**\n\n")?; + for param in &self.parameters { + f.write_fmt(format_args!( + "- `{param_id}`\n\n", + id = self.id, + param_id = param.id + ))?; + f.write_fmt(format_args!("\t{}\n", ¶m.description))?; + } + // Results: + // * `error` + // `error` has type `errno` + f.write_str("\n**Results:**\n\n")?; + for result in &self.results { + f.write_fmt(format_args!( + "- `{res_id}`\n\n", + id = self.id, + res_id = result.id + ))?; + f.write_fmt(format_args!("\t{}\n", &result.description))?; + } + Ok(()) + } +} diff --git a/proposals/random/tools/witx/src/docs/mod.rs b/proposals/random/tools/witx/src/docs/mod.rs new file mode 100644 index 000000000..219c7d716 --- /dev/null +++ b/proposals/random/tools/witx/src/docs/mod.rs @@ -0,0 +1,411 @@ +mod md; + +pub use self::md::*; +use crate::ast::*; +use crate::polyfill::*; +use crate::RepEquality; +use std::rc::{Rc, Weak}; + +pub trait Documentation { + fn to_md(&self) -> String; +} +pub trait ToMarkdown { + fn gen(&self, _parent: Option>) -> Rc; +} + +impl Documentation for Document { + fn to_md(&self) -> String { + format!("{}", self.gen(None)) + } +} + +impl ToMarkdown for Document { + fn gen(&self, parent: Option>) -> Rc { + let doc = Rc::new(MdSection::new("root", "Root", parent)); + let types = Rc::new(MdSection::new("types", "Types", Some(Rc::downgrade(&doc)))); + for typename in self.typenames() { + types + .as_section_mut() + .elements + .push(typename.gen(Some(Rc::downgrade(&types)))); + } + doc.as_section_mut().elements.push(types); + let modules = Rc::new(MdSection::new( + "modules", + "Modules", + Some(Rc::downgrade(&doc)), + )); + for module in self.modules() { + modules + .as_section_mut() + .elements + .push(module.gen(Some(Rc::downgrade(&modules)))); + } + doc.as_section_mut().elements.push(modules); + doc + } +} + +impl BuiltinType { + pub fn type_name(&self) -> &'static str { + match self { + BuiltinType::String => "string", + BuiltinType::Char8 => "char8", + BuiltinType::USize => "usize", + BuiltinType::U8 => "u8", + BuiltinType::U16 => "u16", + BuiltinType::U32 => "u32", + BuiltinType::U64 => "u64", + BuiltinType::S8 => "s8", + BuiltinType::S16 => "s16", + BuiltinType::S32 => "s32", + BuiltinType::S64 => "s64", + BuiltinType::F32 => "f32", + BuiltinType::F64 => "f64", + } + } +} + +impl ToMarkdown for NamedType { + fn gen(&self, parent: Option>) -> Rc { + match &self.tref { + TypeRef::Value(v) => { + let md_type = MdType::from(&**v); + let mut elements: Vec<_> = match &**v { + Type::Enum(a) => a.variants.iter().map(MdBullet::from).collect(), + Type::Int(a) => a.consts.iter().map(MdBullet::from).collect(), + Type::Flags(a) => a.flags.iter().map(MdBullet::from).collect(), + Type::Struct(a) => a.members.iter().map(MdBullet::from).collect(), + Type::Union(a) => a.variants.iter().map(MdBullet::from).collect(), + Type::Handle(a) => a.supertypes.iter().map(MdBullet::from).collect(), + _ => vec![], + }; + let listing = Rc::new(MdTypeListing::new(self.name.as_str(), md_type, parent)); + listing + .as_type_listing_mut() + .description + .push(self.docs.clone()); + listing.as_type_listing_mut().elements.append(&mut elements); + listing + } + TypeRef::Name(n) => { + let sec = Rc::new(MdSection::new( + self.name.as_str(), + self.name.as_str(), + parent, + )); + sec.as_section_mut().description.push(self.docs.clone()); + sec.as_section_mut() + .description + .push(format!("Alias to {}", n.name.as_str())); + sec + } + } + } +} + +impl From<&Type> for MdType { + fn from(r#type: &Type) -> Self { + match r#type { + Type::Enum(a) => Self::Enum { + repr: a.repr.type_name().to_owned(), + }, + Type::Int(a) => Self::Int { + repr: a.repr.type_name().to_owned(), + }, + Type::Flags(a) => Self::Flags { + repr: a.repr.type_name().to_owned(), + }, + Type::Struct(_) => Self::Struct, + Type::Union(_) => Self::Union, + Type::Handle(_) => Self::Handle, + Type::Array(a) => Self::Array { + r#type: a.type_name().to_owned(), + }, + Type::Pointer(a) => Self::Pointer { + to: a.type_name().to_owned(), + }, + Type::ConstPointer(a) => Self::ConstPointer { + to: a.type_name().to_owned(), + }, + Type::Builtin(a) => Self::Builtin { + r#type: a.type_name().to_owned(), + }, + } + } +} + +macro_rules! impl_mdbullet { + ($from:ty) => { + impl From<$from> for MdBullet { + fn from(f: $from) -> Self { + Self { + id: f.name.as_str().to_owned(), + description: f.docs.clone(), + } + } + } + }; +} + +impl_mdbullet!(&EnumVariant); +impl_mdbullet!(&IntConst); +impl_mdbullet!(&FlagsMember); +impl_mdbullet!(&StructMember); +impl_mdbullet!(&UnionVariant); + +impl From<&TypeRef> for MdBullet { + fn from(t: &TypeRef) -> Self { + Self { + id: t.type_name().to_owned(), + description: "".to_owned(), // FIXME + } + } +} + +impl TypeRef { + pub fn type_name(&self) -> String { + match self { + TypeRef::Name(n) => n.name.as_str().to_string(), + TypeRef::Value(ref v) => match &**v { + Type::Array(a) => format!("Array<{}>", a.type_name()), + Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), + Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), + Type::Builtin(b) => b.type_name().to_string(), + Type::Enum { .. } + | Type::Int { .. } + | Type::Flags { .. } + | Type::Struct { .. } + | Type::Union { .. } + | Type::Handle { .. } => { + unimplemented!("type_name of anonymous compound datatypes") + } + }, + } + } +} + +impl IntRepr { + fn type_name(&self) -> &'static str { + match self { + IntRepr::U8 => "u8", + IntRepr::U16 => "u16", + IntRepr::U32 => "u32", + IntRepr::U64 => "u64", + } + } +} + +impl ToMarkdown for Module { + fn gen(&self, parent: Option>) -> Rc { + let sec = Rc::new(MdSection::new( + self.name.as_str(), + &format!("`{}`", self.name.as_str()), + parent, + )); + let imports = Rc::new(MdSection::new( + "imports", + "Imports", + Some(Rc::downgrade(&sec)), + )); + // FIXME + for import in self.imports() { + let desc = match import.variant { + ModuleImportVariant::Memory => format!("* {}: Memory", import.name.as_str()), + }; + imports.as_section_mut().description.push(desc); + } + sec.as_section_mut().elements.push(imports); + let funcs = Rc::new(MdSection::new( + "functions", + "Functions", + Some(Rc::downgrade(&sec)), + )); + funcs + .as_section_mut() + .elements + .extend(self.funcs().map(|f| f.gen(Some(Rc::downgrade(&funcs))))); + sec.as_section_mut().elements.push(funcs); + sec + } +} + +impl ToMarkdown for InterfaceFunc { + fn gen(&self, parent: Option>) -> Rc { + let func = Rc::new(MdInterfaceFunc::new(self.name.as_str(), parent)); + func.as_interface_func_mut() + .description + .push(self.docs.clone()); + func.as_interface_func_mut() + .parameters + .extend(self.params.iter().map(MdBullet::from)); + func.as_interface_func_mut() + .results + .extend(self.results.iter().map(MdBullet::from)); + func + } +} + +impl From<&InterfaceFuncParam> for MdBullet { + fn from(param: &InterfaceFuncParam) -> Self { + Self { + id: param.name.as_str().to_owned(), + description: format!( + "`{}` has type `{}`\n{}\n\n", + param.name.as_str(), + param.tref.type_name(), + param.docs + ), + } + } +} + +// TODO polyfill +impl Documentation for Polyfill { + fn to_md(&self) -> String { + let module_docs = self + .modules + .iter() + .map(|m| m.to_md()) + .collect::>() + .join("\n"); + let type_docs = self + .type_polyfills() + .iter() + .filter_map(|t| { + if t.repeq() == RepEquality::Eq { + None + } else { + Some(t.to_md()) + } + }) + .collect::>() + .join("\n"); + format!( + "# Modules\n{}\n# Type Conversions\n{}\n", + module_docs, type_docs + ) + } +} + +impl Documentation for ModulePolyfill { + fn to_md(&self) -> String { + format!( + "## `{}` in terms of `{}`\n{}", + self.new.name.as_str(), + self.old.name.as_str(), + self.funcs + .iter() + .map(|f| f.to_md()) + .collect::>() + .join("\n"), + ) + } +} + +impl Documentation for FuncPolyfill { + fn to_md(&self) -> String { + if self.full_compat() { + format!("* `{}`: full compatibility", self.new.name.as_str()) + } else { + let name = if self.new.name != self.old.name { + format!( + "* `{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("* `{}`", self.new.name.as_str()) + }; + let mut contents = Vec::new(); + for p in self.mapped_params.iter() { + contents.push(if !p.full_compat() { + format!("param {}", p.to_md()) + } else { + format!("param `{}`: compatible", p.new.name.as_str()) + }) + } + for u in self.unknown_params.iter() { + contents.push(format!( + "{} param `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + for r in self.mapped_results.iter() { + contents.push(if !r.full_compat() { + format!("result {}", r.to_md()) + } else { + format!("result `{}`: compatible", r.new.name.as_str()) + }) + } + for u in self.unknown_results.iter() { + contents.push(format!( + "{} result `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + let contents = if contents.is_empty() { + String::new() + } else { + format!(":\n - {}", contents.join("\n - ")) + }; + format!("{}{}", name, contents) + } + } +} + +impl Documentation for ParamPolyfill { + fn to_md(&self) -> String { + let name = if self.new.name != self.old.name { + format!( + "`{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("`{}`", self.new.name.as_str()) + }; + let repr = match self.repeq() { + RepEquality::Eq => "compatible types".to_string(), + RepEquality::Superset => format!( + "`{}` is superset-compatible with `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + RepEquality::NotEq => format!( + "`{}` is incompatible with new `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + }; + format!("{}: {}", name, repr) + } +} + +impl Documentation for TypePolyfill { + fn to_md(&self) -> String { + fn repeq_name(r: RepEquality) -> &'static str { + match r { + RepEquality::Eq => ": compatible", + RepEquality::Superset => ": superset", + RepEquality::NotEq => "", + } + } + match self { + TypePolyfill::OldToNew(o, n) => format!( + "* old `{}` => new `{}`{}", + o.type_name(), + n.type_name(), + repeq_name(self.repeq()) + ), + TypePolyfill::NewToOld(n, o) => format!( + "* new `{}` => old `{}`{}", + n.type_name(), + o.type_name(), + repeq_name(self.repeq()) + ), + } + } +} From d62a4aef25cfb60bbf1715953448996134801b74 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 9 Jan 2020 22:41:43 +0100 Subject: [PATCH 0444/1772] Reorganise and refactor handling on header nesting This commit reorganises the `docs` module into a couple of submodules for easier navigation. It also replaces manual specifying of nesting level upon Markdown element creation for automatic header generation. I should note here that I've decided to simplify the code over the previous commit, as the previous seemed unnecessary bloated and really subtle in places which IMHO would very likely cause some maintenance hell in the future. --- proposals/filesystem/tools/witx/src/docs.rs | 710 ------------------ .../filesystem/tools/witx/src/docs/md.rs | 288 +++++++ .../filesystem/tools/witx/src/docs/mod.rs | 411 ++++++++++ 3 files changed, 699 insertions(+), 710 deletions(-) delete mode 100644 proposals/filesystem/tools/witx/src/docs.rs create mode 100644 proposals/filesystem/tools/witx/src/docs/md.rs create mode 100644 proposals/filesystem/tools/witx/src/docs/mod.rs diff --git a/proposals/filesystem/tools/witx/src/docs.rs b/proposals/filesystem/tools/witx/src/docs.rs deleted file mode 100644 index 2e358b15e..000000000 --- a/proposals/filesystem/tools/witx/src/docs.rs +++ /dev/null @@ -1,710 +0,0 @@ -use crate::ast::*; -use crate::polyfill::*; -use crate::RepEquality; -use std::fmt; - -#[derive(Debug)] -pub enum MdBlockElement { - Section(MdSection), - TypeListing(MdTypeListing), - InterfaceFunc(MdInterfaceFunc), - Root(MdRoot), -} - -impl fmt::Display for MdBlockElement { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Section(sec) => sec.fmt(f), - Self::TypeListing(listing) => listing.fmt(f), - Self::InterfaceFunc(func) => func.fmt(f), - Self::Root(root) => root.fmt(f), - } - } -} - -#[derive(Debug, Default)] -pub struct MdRoot { - blocks: Vec, -} - -impl fmt::Display for MdRoot { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for block in &self.blocks { - block.fmt(f)?; - } - Ok(()) - } -} - -#[derive(Debug, Clone)] -struct MdParagraph { - para: String, -} - -impl MdParagraph { - fn new>(para: S) -> Self { - Self { - para: para.as_ref().to_owned(), - } - } - - fn with_links_parsed>(para: S) -> Self { - let to_parse = para.as_ref(); - let mut parsed = String::with_capacity(to_parse.len()); - let mut temp = String::with_capacity(to_parse.len()); - let mut is_link = false; - let mut eaten = None; - for ch in to_parse.chars() { - match (ch, is_link) { - ('`', false) => { - // found the beginning of a link - is_link = true; - } - ('`', true) => { - // reached the end, expand into a link! - let expanded = format!("[`{}`](#{})", temp, temp); - parsed.push_str(&expanded); - temp.drain(..); - is_link = false; - } - (':', true) => { - if let Some(_) = eaten { - // swap for '.' - temp.push('.'); - eaten = None; - } else { - eaten = Some(':'); - } - } - (ch, false) => parsed.push(ch), - (ch, true) => temp.push(ch), - } - } - Self::new(parsed) - } -} - -impl fmt::Display for MdParagraph { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_fmt(format_args!("{}\n", &self.para)) - } -} - -#[allow(dead_code)] -#[derive(Debug, Clone)] -enum MdHeading { - Header { - id: String, - title: String, - doc_level: usize, - }, - Bullet { - id: String, - title: String, - }, -} - -impl MdHeading { - fn new_header>(title: S, doc_level: usize) -> Self { - let id = title.as_ref().replace(" ", "_"); - let title = title.as_ref().to_owned(); - Self::Header { - id, - title, - doc_level, - } - } - - fn new_bullet>(title: S) -> Self { - let id = title.as_ref().replace(" ", "_"); - let title = title.as_ref().to_owned(); - Self::Bullet { id, title } - } - - fn id(&self) -> &str { - match self { - Self::Header { ref id, .. } => id, - Self::Bullet { ref id, .. } => id, - } - } - - fn set_id>(&mut self, id: S) { - let s_id = match self { - Self::Header { ref mut id, .. } => id, - Self::Bullet { ref mut id, .. } => id, - }; - *s_id = id.as_ref().to_owned(); - } -} - -impl fmt::Display for MdHeading { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let (id, title, heading) = match self { - Self::Header { - id, - title, - doc_level, - } => (id, title, "#".repeat(*doc_level)), - Self::Bullet { id, title } => (id, title, "-".to_owned()), - }; - f.write_fmt(format_args!( - "{heading} {title}\n", - heading = heading, - id = id, - title = title - )) - } -} - -#[derive(Debug)] -pub struct MdSection { - heading: MdHeading, - description: Vec, - blocks: Vec, -} - -impl MdSection { - fn new(heading: MdHeading) -> Self { - Self { - heading, - description: vec![], - blocks: vec![], - } - } -} - -impl fmt::Display for MdSection { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.heading.fmt(f)?; - for para in &self.description { - para.fmt(f)?; - } - for el in &self.blocks { - el.fmt(f)?; - } - Ok(()) - } -} - -#[allow(dead_code)] -#[derive(Debug)] -enum MdType { - Enum { repr: String }, - Int { repr: String }, - Flags { repr: String }, - Struct, - Union, - Handle, - Array { r#type: String }, - Pointer { to: String }, - ConstPointer { to: String }, - Builtin { r#type: String }, -} - -impl fmt::Display for MdType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let type_specific = match self { - MdType::Enum { repr } => format!("Enum represented by `{}`\n\n**Variants:**", repr), - MdType::Int { repr } => format!("Int represented by `{}`\n\n**Const:**", repr), - MdType::Flags { repr } => format!("Flags represented by `{}`\n\n**Flags:**", repr), - MdType::Struct => "\n**Struct members:**".to_owned(), - MdType::Union => "\n**Union variants:**".to_owned(), - MdType::Handle => "\n**Supertypes:**".to_owned(), - MdType::Array { r#type } => format!("Array of `{}`", r#type), - MdType::Pointer { to } => format!("Pointer to `{}`", to), - MdType::ConstPointer { to } => format!("Const pointer to `{}`", to), - MdType::Builtin { r#type } => format!("Builtin type `{}`", r#type), - }; - f.write_fmt(format_args!("{}\n", type_specific)) - } -} - -#[derive(Debug, Clone)] -struct MdListingEntry { - heading: MdHeading, - description: Vec, -} - -impl fmt::Display for MdListingEntry { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.heading.fmt(f)?; - for para in &self.description { - f.write_fmt(format_args!("\n\t{}\n", para))?; - } - Ok(()) - } -} - -#[derive(Debug)] -pub struct MdTypeListing { - heading: MdHeading, - r#type: MdType, - description: Vec, - entries: Vec, -} - -impl MdTypeListing { - fn new(heading: MdHeading, r#type: MdType) -> Self { - Self { - heading, - r#type, - description: vec![], - entries: vec![], - } - } -} - -impl fmt::Display for MdTypeListing { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.heading.fmt(f)?; - for para in &self.description { - para.fmt(f)?; - } - self.r#type.fmt(f)?; - for el in &self.entries { - // prepend id of this MdTypeListing in order to generate scoped - // references of list entries - let id = format!("{}.{}", self.heading.id(), el.heading.id()); - let mut new_el = el.clone(); - new_el.heading.set_id(id); - new_el.fmt(f)?; - } - Ok(()) - } -} - -#[derive(Debug)] -pub struct MdInterfaceFunc { - heading: MdHeading, - description: Vec, - parameters: Vec, - results: Vec, -} - -impl MdInterfaceFunc { - fn new(heading: MdHeading) -> Self { - Self { - heading, - description: vec![], - parameters: vec![], - results: vec![], - } - } -} - -impl fmt::Display for MdInterfaceFunc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.heading.fmt(f)?; - for desc in &self.description { - desc.fmt(f)?; - } - f.write_str("\n**Parameters:**\n\n")?; - for el in &self.parameters { - // prepend id of this MdTypeListing in order to generate scoped - // references of list entries - let id = format!("{}.{}", self.heading.id(), el.heading.id()); - let mut new_el = el.clone(); - new_el.heading.set_id(id); - new_el.fmt(f)?; - } - f.write_str("\n**Results:**\n\n")?; - for el in &self.results { - // prepend id of this MdTypeListing in order to generate scoped - // references of list entries - let id = format!("{}.{}", self.heading.id(), el.heading.id()); - let mut new_el = el.clone(); - new_el.heading.set_id(id); - new_el.fmt(f)?; - } - Ok(()) - } -} - -pub trait Documentation { - fn to_md(&self) -> String { - format!("{}", self.gen(0)) - } - - fn gen(&self, _level: usize) -> MdBlockElement { - MdBlockElement::Root(MdRoot::default()) - } -} - -impl Documentation for Document { - fn gen(&self, level: usize) -> MdBlockElement { - let mut doc = MdRoot::default(); - let mut types = MdSection::new(MdHeading::new_header("Types", level + 1)); - for typename in self.typenames() { - types.blocks.push(typename.gen(level + 2)); - } - doc.blocks.push(MdBlockElement::Section(types)); - let mut modules = MdSection::new(MdHeading::new_header("Modules", level + 1)); - for module in self.modules() { - modules.blocks.push(module.gen(level + 2)); - } - doc.blocks.push(MdBlockElement::Section(modules)); - MdBlockElement::Root(doc) - } -} - -impl BuiltinType { - pub fn type_name(&self) -> &'static str { - match self { - BuiltinType::String => "string", - BuiltinType::Char8 => "char8", - BuiltinType::USize => "usize", - BuiltinType::U8 => "u8", - BuiltinType::U16 => "u16", - BuiltinType::U32 => "u32", - BuiltinType::U64 => "u64", - BuiltinType::S8 => "s8", - BuiltinType::S16 => "s16", - BuiltinType::S32 => "s32", - BuiltinType::S64 => "s64", - BuiltinType::F32 => "f32", - BuiltinType::F64 => "f64", - } - } -} - -impl Documentation for NamedType { - fn gen(&self, level: usize) -> MdBlockElement { - match &self.tref { - TypeRef::Value(v) => { - let md_type = MdType::from(&**v); - let mut entries: Vec<_> = match &**v { - Type::Enum(a) => a.variants.iter().map(MdListingEntry::from).collect(), - Type::Int(a) => a.consts.iter().map(MdListingEntry::from).collect(), - Type::Flags(a) => a.flags.iter().map(MdListingEntry::from).collect(), - Type::Struct(a) => a.members.iter().map(MdListingEntry::from).collect(), - Type::Union(a) => a.variants.iter().map(MdListingEntry::from).collect(), - Type::Handle(a) => a.supertypes.iter().map(MdListingEntry::from).collect(), - _ => vec![], - }; - let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); - heading.set_id(self.name.as_str()); - let mut listing = MdTypeListing::new(heading, md_type); - listing - .description - .push(MdParagraph::with_links_parsed(&self.docs)); - listing.entries.append(&mut entries); - MdBlockElement::TypeListing(listing) - } - TypeRef::Name(n) => { - let mut heading = MdHeading::new_header(self.name.as_str(), level); - heading.set_id(self.name.as_str()); - let mut sec = MdSection::new(heading); - sec.description - .push(MdParagraph::with_links_parsed(&self.docs)); - sec.description.push(MdParagraph::with_links_parsed(format!( - "Alias to {}", - n.name.as_str() - ))); - MdBlockElement::Section(sec) - } - } - } -} - -impl From<&Type> for MdType { - fn from(r#type: &Type) -> Self { - match r#type { - Type::Enum(a) => Self::Enum { - repr: a.repr.type_name().to_owned(), - }, - Type::Int(a) => Self::Int { - repr: a.repr.type_name().to_owned(), - }, - Type::Flags(a) => Self::Flags { - repr: a.repr.type_name().to_owned(), - }, - Type::Struct(_) => Self::Struct, - Type::Union(_) => Self::Union, - Type::Handle(_) => Self::Handle, - Type::Array(a) => Self::Array { - r#type: a.type_name().to_owned(), - }, - Type::Pointer(a) => Self::Pointer { - to: a.type_name().to_owned(), - }, - Type::ConstPointer(a) => Self::ConstPointer { - to: a.type_name().to_owned(), - }, - Type::Builtin(a) => Self::Builtin { - r#type: a.type_name().to_owned(), - }, - } - } -} - -macro_rules! impl_mdlistingentry { - ($from:ty) => { - impl From<$from> for MdListingEntry { - fn from(f: $from) -> Self { - let mut heading = MdHeading::new_bullet(format!("`{}`", f.name.as_str())); - heading.set_id(f.name.as_str()); - Self { - heading, - description: vec![MdParagraph::with_links_parsed(&f.docs)], - } - } - } - }; -} - -impl_mdlistingentry!(&EnumVariant); -impl_mdlistingentry!(&IntConst); -impl_mdlistingentry!(&FlagsMember); -impl_mdlistingentry!(&StructMember); -impl_mdlistingentry!(&UnionVariant); - -impl From<&TypeRef> for MdListingEntry { - fn from(t: &TypeRef) -> Self { - let mut heading = MdHeading::new_bullet(format!("`{}`", t.type_name())); - heading.set_id(t.type_name()); - Self { - heading, - description: vec![], - } - } -} - -impl TypeRef { - pub fn type_name(&self) -> String { - match self { - TypeRef::Name(n) => n.name.as_str().to_string(), - TypeRef::Value(ref v) => match &**v { - Type::Array(a) => format!("Array<{}>", a.type_name()), - Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), - Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), - Type::Builtin(b) => b.type_name().to_string(), - Type::Enum { .. } - | Type::Int { .. } - | Type::Flags { .. } - | Type::Struct { .. } - | Type::Union { .. } - | Type::Handle { .. } => { - unimplemented!("type_name of anonymous compound datatypes") - } - }, - } - } -} - -impl IntRepr { - fn type_name(&self) -> &'static str { - match self { - IntRepr::U8 => "u8", - IntRepr::U16 => "u16", - IntRepr::U32 => "u32", - IntRepr::U64 => "u64", - } - } -} - -impl Documentation for Module { - fn gen(&self, level: usize) -> MdBlockElement { - let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); - heading.set_id(self.name.as_str()); - let mut sec = MdSection::new(heading); - let mut imports = MdSection::new(MdHeading::new_header("Imports", level + 1)); - // FIXME - for import in self.imports() { - let desc = match import.variant { - ModuleImportVariant::Memory => { - MdParagraph::with_links_parsed(format!("* {}: Memory", import.name.as_str())) - } - }; - imports.description.push(desc); - } - sec.blocks.push(MdBlockElement::Section(imports)); - let mut funcs = MdSection::new(MdHeading::new_header("Functions", level + 1)); - funcs.blocks.extend(self.funcs().map(|f| f.gen(level + 2))); - sec.blocks.push(MdBlockElement::Section(funcs)); - MdBlockElement::Section(sec) - } -} - -impl Documentation for InterfaceFunc { - fn gen(&self, level: usize) -> MdBlockElement { - let mut heading = MdHeading::new_header(format!("`{}`", self.name.as_str()), level); - heading.set_id(self.name.as_str()); - let mut func = MdInterfaceFunc::new(heading); - func.description - .push(MdParagraph::with_links_parsed(&self.docs)); - func.parameters - .extend(self.params.iter().map(MdListingEntry::from)); - func.results - .extend(self.results.iter().map(MdListingEntry::from)); - MdBlockElement::InterfaceFunc(func) - } -} - -impl From<&InterfaceFuncParam> for MdListingEntry { - fn from(param: &InterfaceFuncParam) -> Self { - let mut heading = MdHeading::new_bullet(format!("`{}`", param.name.as_str())); - heading.set_id(param.name.as_str()); - let mut description = vec![]; - description.push(MdParagraph::with_links_parsed(format!( - "`{}` has type `{}`.", - param.name.as_str(), - param.tref.type_name() - ))); - description.push(MdParagraph::with_links_parsed(¶m.docs)); - Self { - heading, - description, - } - } -} - -// TODO -// Generate nicely-formatted docs for polyfill -impl Documentation for Polyfill { - fn to_md(&self) -> String { - let module_docs = self - .modules - .iter() - .map(|m| m.to_md()) - .collect::>() - .join("\n"); - let type_docs = self - .type_polyfills() - .iter() - .filter_map(|t| { - if t.repeq() == RepEquality::Eq { - None - } else { - Some(t.to_md()) - } - }) - .collect::>() - .join("\n"); - format!( - "# Modules\n{}\n# Type Conversions\n{}\n", - module_docs, type_docs - ) - } -} - -impl Documentation for ModulePolyfill { - fn to_md(&self) -> String { - format!( - "## `{}` in terms of `{}`\n{}", - self.new.name.as_str(), - self.old.name.as_str(), - self.funcs - .iter() - .map(|f| f.to_md()) - .collect::>() - .join("\n"), - ) - } -} - -impl Documentation for FuncPolyfill { - fn to_md(&self) -> String { - if self.full_compat() { - format!("* `{}`: full compatibility", self.new.name.as_str()) - } else { - let name = if self.new.name != self.old.name { - format!( - "* `{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("* `{}`", self.new.name.as_str()) - }; - let mut contents = Vec::new(); - for p in self.mapped_params.iter() { - contents.push(if !p.full_compat() { - format!("param {}", p.to_md()) - } else { - format!("param `{}`: compatible", p.new.name.as_str()) - }) - } - for u in self.unknown_params.iter() { - contents.push(format!( - "{} param `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - for r in self.mapped_results.iter() { - contents.push(if !r.full_compat() { - format!("result {}", r.to_md()) - } else { - format!("result `{}`: compatible", r.new.name.as_str()) - }) - } - for u in self.unknown_results.iter() { - contents.push(format!( - "{} result `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - let contents = if contents.is_empty() { - String::new() - } else { - format!(":\n - {}", contents.join("\n - ")) - }; - format!("{}{}", name, contents) - } - } -} - -impl Documentation for ParamPolyfill { - fn to_md(&self) -> String { - let name = if self.new.name != self.old.name { - format!( - "`{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("`{}`", self.new.name.as_str()) - }; - let repr = match self.repeq() { - RepEquality::Eq => "compatible types".to_string(), - RepEquality::Superset => format!( - "`{}` is superset-compatible with `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - RepEquality::NotEq => format!( - "`{}` is incompatible with new `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - }; - format!("{}: {}", name, repr) - } -} - -impl Documentation for TypePolyfill { - fn to_md(&self) -> String { - fn repeq_name(r: RepEquality) -> &'static str { - match r { - RepEquality::Eq => ": compatible", - RepEquality::Superset => ": superset", - RepEquality::NotEq => "", - } - } - match self { - TypePolyfill::OldToNew(o, n) => format!( - "* old `{}` => new `{}`{}", - o.type_name(), - n.type_name(), - repeq_name(self.repeq()) - ), - TypePolyfill::NewToOld(n, o) => format!( - "* new `{}` => old `{}`{}", - n.type_name(), - o.type_name(), - repeq_name(self.repeq()) - ), - } - } -} diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs new file mode 100644 index 000000000..3ba383a92 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -0,0 +1,288 @@ +use std::{ + cell::{Ref, RefCell, RefMut}, + fmt, + rc::{Rc, Weak}, +}; + +#[derive(Debug)] +pub enum MdElement { + Section(RefCell), + TypeListing(RefCell), + InterfaceFunc(RefCell), +} + +impl MdElement { + pub fn as_section(&self) -> Ref { + match self { + Self::Section(t) => t.borrow(), + _ => panic!("not a MdSection"), + } + } + + pub fn as_section_mut(&self) -> RefMut { + match self { + Self::Section(t) => t.borrow_mut(), + _ => panic!("not a MdSection"), + } + } + + pub fn as_type_listing(&self) -> Ref { + match self { + Self::TypeListing(t) => t.borrow(), + _ => panic!("not a MdTypeListing"), + } + } + + pub fn as_type_listing_mut(&self) -> RefMut { + match self { + Self::TypeListing(t) => t.borrow_mut(), + _ => panic!("not a MdTypeListing"), + } + } + + pub fn as_interface_func(&self) -> Ref { + match self { + Self::InterfaceFunc(t) => t.borrow(), + _ => panic!("not a MdInterfaceFunc"), + } + } + + pub fn as_interface_func_mut(&self) -> RefMut { + match self { + Self::InterfaceFunc(t) => t.borrow_mut(), + _ => panic!("not a MdInterfaceFunc"), + } + } + + pub fn parent(&self) -> Option> { + match self { + Self::Section(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), + Self::TypeListing(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), + Self::InterfaceFunc(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), + } + } +} + +impl fmt::Display for MdElement { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Section(t) => t.borrow().fmt(f), + Self::TypeListing(t) => t.borrow().fmt(f), + Self::InterfaceFunc(t) => t.borrow().fmt(f), + } + } +} + +fn walk_parents(start: &Weak, cb: &mut impl FnMut(Rc)) { + let mut parent = if let Some(parent) = start.upgrade() { + cb(parent.clone()); + parent + } else { + return; + }; + + while let Some(p) = parent.parent() { + cb(p.clone()); + parent = p; + } +} + +#[derive(Debug)] +pub struct MdSection { + pub id: String, + pub title: String, + pub description: Vec, + pub elements: Vec>, + pub parent: Option>, +} + +impl MdSection { + pub fn new(id: &str, title: &str, parent: Option>) -> MdElement { + MdElement::Section(RefCell::new(Self { + id: id.to_owned(), + title: title.to_owned(), + description: vec![], + elements: vec![], + parent, + })) + } +} + +impl fmt::Display for MdSection { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut heading = "#".to_owned(); + if let Some(parent) = self.parent.as_ref() { + walk_parents(parent, &mut |_| { + heading += "#"; + }); + } + f.write_fmt(format_args!( + "{heading} {title}\n", + heading = heading, + id = self.id, + title = self.title + ))?; + for para in &self.description { + f.write_fmt(format_args!("{}\n", para))?; + } + for el in &self.elements { + f.write_fmt(format_args!("{}\n", el))?; + } + Ok(()) + } +} + +#[derive(Debug)] +pub struct MdTypeListing { + pub id: String, + pub r#type: MdType, + pub description: Vec, + pub elements: Vec, + pub parent: Option>, +} + +#[derive(Debug)] +pub enum MdType { + Enum { repr: String }, + Int { repr: String }, + Flags { repr: String }, + Struct, + Union, + Handle, + Array { r#type: String }, + Pointer { to: String }, + ConstPointer { to: String }, + Builtin { r#type: String }, +} + +#[derive(Debug)] +pub struct MdBullet { + pub id: String, + pub description: String, +} + +impl MdTypeListing { + pub fn new(id: &str, r#type: MdType, parent: Option>) -> MdElement { + MdElement::TypeListing(RefCell::new(Self { + id: id.to_owned(), + r#type, + description: vec![], + elements: vec![], + parent, + })) + } +} + +impl fmt::Display for MdTypeListing { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut heading = "#".to_owned(); + if let Some(parent) = self.parent.as_ref() { + walk_parents(parent, &mut |_| { + heading += "#"; + }); + } + // ### `errno` + f.write_fmt(format_args!( + "{heading} `{id}`\n", + heading = heading, + id = self.id + ))?; + // Error codes returned by function... + for para in &self.description { + f.write_fmt(format_args!("{}\n", para))?; + } + // Enum represented by `u16` + // Variants: + let type_specific = match &self.r#type { + MdType::Enum { repr } => format!("Enum represented by `{}`\n\n**Variants:**\n", repr), + MdType::Int { repr } => format!("Int represented by `{}`\n\n**Const:**\n", repr), + MdType::Flags { repr } => format!("Flags represented by `{}`\n\n**Flags:**\n", repr), + MdType::Struct => "\n**Struct members:**\n".to_owned(), + MdType::Union => "\n**Union variants:**\n".to_owned(), + MdType::Handle => "\n**Supertypes:**\n".to_owned(), + MdType::Array { r#type } => format!("Array of `{}`", r#type), + MdType::Pointer { to } => format!("Pointer to `{}`", to), + MdType::ConstPointer { to } => format!("Const pointer to `{}`", to), + MdType::Builtin { r#type } => format!("Builtin type `{}`", r#type), + }; + f.write_str(&type_specific)?; + // - `success` + // No error occurred. System call completed successfully. + for el in &self.elements { + f.write_fmt(format_args!( + "- `{id}`\n\n", + this_id = self.id, + id = el.id + ))?; + f.write_fmt(format_args!("\t{}\n", &el.description))?; + } + Ok(()) + } +} + +#[derive(Debug)] +pub struct MdInterfaceFunc { + pub id: String, + pub description: Vec, + pub parameters: Vec, + pub results: Vec, + pub parent: Option>, +} + +impl MdInterfaceFunc { + pub fn new(id: &str, parent: Option>) -> MdElement { + MdElement::InterfaceFunc(RefCell::new(Self { + id: id.to_owned(), + description: vec![], + parameters: vec![], + results: vec![], + parent, + })) + } +} + +impl fmt::Display for MdInterfaceFunc { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut heading = "#".to_owned(); + if let Some(parent) = self.parent.as_ref() { + walk_parents(parent, &mut |_| { + heading += "#"; + }); + } + // ### `args_get` + f.write_fmt(format_args!( + "{heading} `{id}`\n\n", + heading = heading, + id = self.id + ))?; + // Read command-line argument data... + for desc in &self.description { + f.write_fmt(format_args!("{}\n", desc))?; + } + // Parameters: + // * `argv` + // `argv` has type... + f.write_str("\n**Parameters:**\n\n")?; + for param in &self.parameters { + f.write_fmt(format_args!( + "- `{param_id}`\n\n", + id = self.id, + param_id = param.id + ))?; + f.write_fmt(format_args!("\t{}\n", ¶m.description))?; + } + // Results: + // * `error` + // `error` has type `errno` + f.write_str("\n**Results:**\n\n")?; + for result in &self.results { + f.write_fmt(format_args!( + "- `{res_id}`\n\n", + id = self.id, + res_id = result.id + ))?; + f.write_fmt(format_args!("\t{}\n", &result.description))?; + } + Ok(()) + } +} diff --git a/proposals/filesystem/tools/witx/src/docs/mod.rs b/proposals/filesystem/tools/witx/src/docs/mod.rs new file mode 100644 index 000000000..219c7d716 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/docs/mod.rs @@ -0,0 +1,411 @@ +mod md; + +pub use self::md::*; +use crate::ast::*; +use crate::polyfill::*; +use crate::RepEquality; +use std::rc::{Rc, Weak}; + +pub trait Documentation { + fn to_md(&self) -> String; +} +pub trait ToMarkdown { + fn gen(&self, _parent: Option>) -> Rc; +} + +impl Documentation for Document { + fn to_md(&self) -> String { + format!("{}", self.gen(None)) + } +} + +impl ToMarkdown for Document { + fn gen(&self, parent: Option>) -> Rc { + let doc = Rc::new(MdSection::new("root", "Root", parent)); + let types = Rc::new(MdSection::new("types", "Types", Some(Rc::downgrade(&doc)))); + for typename in self.typenames() { + types + .as_section_mut() + .elements + .push(typename.gen(Some(Rc::downgrade(&types)))); + } + doc.as_section_mut().elements.push(types); + let modules = Rc::new(MdSection::new( + "modules", + "Modules", + Some(Rc::downgrade(&doc)), + )); + for module in self.modules() { + modules + .as_section_mut() + .elements + .push(module.gen(Some(Rc::downgrade(&modules)))); + } + doc.as_section_mut().elements.push(modules); + doc + } +} + +impl BuiltinType { + pub fn type_name(&self) -> &'static str { + match self { + BuiltinType::String => "string", + BuiltinType::Char8 => "char8", + BuiltinType::USize => "usize", + BuiltinType::U8 => "u8", + BuiltinType::U16 => "u16", + BuiltinType::U32 => "u32", + BuiltinType::U64 => "u64", + BuiltinType::S8 => "s8", + BuiltinType::S16 => "s16", + BuiltinType::S32 => "s32", + BuiltinType::S64 => "s64", + BuiltinType::F32 => "f32", + BuiltinType::F64 => "f64", + } + } +} + +impl ToMarkdown for NamedType { + fn gen(&self, parent: Option>) -> Rc { + match &self.tref { + TypeRef::Value(v) => { + let md_type = MdType::from(&**v); + let mut elements: Vec<_> = match &**v { + Type::Enum(a) => a.variants.iter().map(MdBullet::from).collect(), + Type::Int(a) => a.consts.iter().map(MdBullet::from).collect(), + Type::Flags(a) => a.flags.iter().map(MdBullet::from).collect(), + Type::Struct(a) => a.members.iter().map(MdBullet::from).collect(), + Type::Union(a) => a.variants.iter().map(MdBullet::from).collect(), + Type::Handle(a) => a.supertypes.iter().map(MdBullet::from).collect(), + _ => vec![], + }; + let listing = Rc::new(MdTypeListing::new(self.name.as_str(), md_type, parent)); + listing + .as_type_listing_mut() + .description + .push(self.docs.clone()); + listing.as_type_listing_mut().elements.append(&mut elements); + listing + } + TypeRef::Name(n) => { + let sec = Rc::new(MdSection::new( + self.name.as_str(), + self.name.as_str(), + parent, + )); + sec.as_section_mut().description.push(self.docs.clone()); + sec.as_section_mut() + .description + .push(format!("Alias to {}", n.name.as_str())); + sec + } + } + } +} + +impl From<&Type> for MdType { + fn from(r#type: &Type) -> Self { + match r#type { + Type::Enum(a) => Self::Enum { + repr: a.repr.type_name().to_owned(), + }, + Type::Int(a) => Self::Int { + repr: a.repr.type_name().to_owned(), + }, + Type::Flags(a) => Self::Flags { + repr: a.repr.type_name().to_owned(), + }, + Type::Struct(_) => Self::Struct, + Type::Union(_) => Self::Union, + Type::Handle(_) => Self::Handle, + Type::Array(a) => Self::Array { + r#type: a.type_name().to_owned(), + }, + Type::Pointer(a) => Self::Pointer { + to: a.type_name().to_owned(), + }, + Type::ConstPointer(a) => Self::ConstPointer { + to: a.type_name().to_owned(), + }, + Type::Builtin(a) => Self::Builtin { + r#type: a.type_name().to_owned(), + }, + } + } +} + +macro_rules! impl_mdbullet { + ($from:ty) => { + impl From<$from> for MdBullet { + fn from(f: $from) -> Self { + Self { + id: f.name.as_str().to_owned(), + description: f.docs.clone(), + } + } + } + }; +} + +impl_mdbullet!(&EnumVariant); +impl_mdbullet!(&IntConst); +impl_mdbullet!(&FlagsMember); +impl_mdbullet!(&StructMember); +impl_mdbullet!(&UnionVariant); + +impl From<&TypeRef> for MdBullet { + fn from(t: &TypeRef) -> Self { + Self { + id: t.type_name().to_owned(), + description: "".to_owned(), // FIXME + } + } +} + +impl TypeRef { + pub fn type_name(&self) -> String { + match self { + TypeRef::Name(n) => n.name.as_str().to_string(), + TypeRef::Value(ref v) => match &**v { + Type::Array(a) => format!("Array<{}>", a.type_name()), + Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), + Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), + Type::Builtin(b) => b.type_name().to_string(), + Type::Enum { .. } + | Type::Int { .. } + | Type::Flags { .. } + | Type::Struct { .. } + | Type::Union { .. } + | Type::Handle { .. } => { + unimplemented!("type_name of anonymous compound datatypes") + } + }, + } + } +} + +impl IntRepr { + fn type_name(&self) -> &'static str { + match self { + IntRepr::U8 => "u8", + IntRepr::U16 => "u16", + IntRepr::U32 => "u32", + IntRepr::U64 => "u64", + } + } +} + +impl ToMarkdown for Module { + fn gen(&self, parent: Option>) -> Rc { + let sec = Rc::new(MdSection::new( + self.name.as_str(), + &format!("`{}`", self.name.as_str()), + parent, + )); + let imports = Rc::new(MdSection::new( + "imports", + "Imports", + Some(Rc::downgrade(&sec)), + )); + // FIXME + for import in self.imports() { + let desc = match import.variant { + ModuleImportVariant::Memory => format!("* {}: Memory", import.name.as_str()), + }; + imports.as_section_mut().description.push(desc); + } + sec.as_section_mut().elements.push(imports); + let funcs = Rc::new(MdSection::new( + "functions", + "Functions", + Some(Rc::downgrade(&sec)), + )); + funcs + .as_section_mut() + .elements + .extend(self.funcs().map(|f| f.gen(Some(Rc::downgrade(&funcs))))); + sec.as_section_mut().elements.push(funcs); + sec + } +} + +impl ToMarkdown for InterfaceFunc { + fn gen(&self, parent: Option>) -> Rc { + let func = Rc::new(MdInterfaceFunc::new(self.name.as_str(), parent)); + func.as_interface_func_mut() + .description + .push(self.docs.clone()); + func.as_interface_func_mut() + .parameters + .extend(self.params.iter().map(MdBullet::from)); + func.as_interface_func_mut() + .results + .extend(self.results.iter().map(MdBullet::from)); + func + } +} + +impl From<&InterfaceFuncParam> for MdBullet { + fn from(param: &InterfaceFuncParam) -> Self { + Self { + id: param.name.as_str().to_owned(), + description: format!( + "`{}` has type `{}`\n{}\n\n", + param.name.as_str(), + param.tref.type_name(), + param.docs + ), + } + } +} + +// TODO polyfill +impl Documentation for Polyfill { + fn to_md(&self) -> String { + let module_docs = self + .modules + .iter() + .map(|m| m.to_md()) + .collect::>() + .join("\n"); + let type_docs = self + .type_polyfills() + .iter() + .filter_map(|t| { + if t.repeq() == RepEquality::Eq { + None + } else { + Some(t.to_md()) + } + }) + .collect::>() + .join("\n"); + format!( + "# Modules\n{}\n# Type Conversions\n{}\n", + module_docs, type_docs + ) + } +} + +impl Documentation for ModulePolyfill { + fn to_md(&self) -> String { + format!( + "## `{}` in terms of `{}`\n{}", + self.new.name.as_str(), + self.old.name.as_str(), + self.funcs + .iter() + .map(|f| f.to_md()) + .collect::>() + .join("\n"), + ) + } +} + +impl Documentation for FuncPolyfill { + fn to_md(&self) -> String { + if self.full_compat() { + format!("* `{}`: full compatibility", self.new.name.as_str()) + } else { + let name = if self.new.name != self.old.name { + format!( + "* `{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("* `{}`", self.new.name.as_str()) + }; + let mut contents = Vec::new(); + for p in self.mapped_params.iter() { + contents.push(if !p.full_compat() { + format!("param {}", p.to_md()) + } else { + format!("param `{}`: compatible", p.new.name.as_str()) + }) + } + for u in self.unknown_params.iter() { + contents.push(format!( + "{} param `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + for r in self.mapped_results.iter() { + contents.push(if !r.full_compat() { + format!("result {}", r.to_md()) + } else { + format!("result `{}`: compatible", r.new.name.as_str()) + }) + } + for u in self.unknown_results.iter() { + contents.push(format!( + "{} result `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + let contents = if contents.is_empty() { + String::new() + } else { + format!(":\n - {}", contents.join("\n - ")) + }; + format!("{}{}", name, contents) + } + } +} + +impl Documentation for ParamPolyfill { + fn to_md(&self) -> String { + let name = if self.new.name != self.old.name { + format!( + "`{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("`{}`", self.new.name.as_str()) + }; + let repr = match self.repeq() { + RepEquality::Eq => "compatible types".to_string(), + RepEquality::Superset => format!( + "`{}` is superset-compatible with `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + RepEquality::NotEq => format!( + "`{}` is incompatible with new `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + }; + format!("{}: {}", name, repr) + } +} + +impl Documentation for TypePolyfill { + fn to_md(&self) -> String { + fn repeq_name(r: RepEquality) -> &'static str { + match r { + RepEquality::Eq => ": compatible", + RepEquality::Superset => ": superset", + RepEquality::NotEq => "", + } + } + match self { + TypePolyfill::OldToNew(o, n) => format!( + "* old `{}` => new `{}`{}", + o.type_name(), + n.type_name(), + repeq_name(self.repeq()) + ), + TypePolyfill::NewToOld(n, o) => format!( + "* new `{}` => old `{}`{}", + n.type_name(), + o.type_name(), + repeq_name(self.repeq()) + ), + } + } +} From 18996254248a18d0e78c081927e77be18b094110 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 9 Jan 2020 23:12:28 +0100 Subject: [PATCH 0445/1772] Clean up generation of bullets in a Markdown list Fix spurious warnings. --- proposals/clocks/tools/witx/src/docs/md.rs | 40 +++++++++++++-------- proposals/clocks/tools/witx/src/docs/mod.rs | 38 +++++++++++--------- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index 3ba383a92..01a93025a 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -12,6 +12,7 @@ pub enum MdElement { } impl MdElement { + #[allow(dead_code)] pub fn as_section(&self) -> Ref { match self { Self::Section(t) => t.borrow(), @@ -26,6 +27,7 @@ impl MdElement { } } + #[allow(dead_code)] pub fn as_type_listing(&self) -> Ref { match self { Self::TypeListing(t) => t.borrow(), @@ -40,6 +42,7 @@ impl MdElement { } } + #[allow(dead_code)] pub fn as_interface_func(&self) -> Ref { match self { Self::InterfaceFunc(t) => t.borrow(), @@ -97,10 +100,10 @@ pub struct MdSection { } impl MdSection { - pub fn new(id: &str, title: &str, parent: Option>) -> MdElement { + pub fn new>(id: S, title: S, parent: Option>) -> MdElement { MdElement::Section(RefCell::new(Self { - id: id.to_owned(), - title: title.to_owned(), + id: id.as_ref().to_owned(), + title: title.as_ref().to_owned(), description: vec![], elements: vec![], parent, @@ -141,6 +144,7 @@ pub struct MdTypeListing { pub parent: Option>, } +#[allow(dead_code)] #[derive(Debug)] pub enum MdType { Enum { repr: String }, @@ -158,7 +162,7 @@ pub enum MdType { #[derive(Debug)] pub struct MdBullet { pub id: String, - pub description: String, + pub description: Vec, } impl MdTypeListing { @@ -214,7 +218,9 @@ impl fmt::Display for MdTypeListing { this_id = self.id, id = el.id ))?; - f.write_fmt(format_args!("\t{}\n", &el.description))?; + for desc in &el.description { + f.write_fmt(format_args!("\t{}\n", desc))?; + } } Ok(()) } @@ -262,14 +268,18 @@ impl fmt::Display for MdInterfaceFunc { // Parameters: // * `argv` // `argv` has type... - f.write_str("\n**Parameters:**\n\n")?; - for param in &self.parameters { - f.write_fmt(format_args!( - "- `{param_id}`\n\n", - id = self.id, - param_id = param.id - ))?; - f.write_fmt(format_args!("\t{}\n", ¶m.description))?; + if !self.parameters.is_empty() { + f.write_str("\n**Parameters:**\n\n")?; + for param in &self.parameters { + f.write_fmt(format_args!( + "- `{param_id}`\n\n", + id = self.id, + param_id = param.id + ))?; + for desc in ¶m.description { + f.write_fmt(format_args!("\t{}\n", desc))?; + } + } } // Results: // * `error` @@ -281,7 +291,9 @@ impl fmt::Display for MdInterfaceFunc { id = self.id, res_id = result.id ))?; - f.write_fmt(format_args!("\t{}\n", &result.description))?; + for desc in &result.description { + f.write_fmt(format_args!("\t{}\n", desc))?; + } } Ok(()) } diff --git a/proposals/clocks/tools/witx/src/docs/mod.rs b/proposals/clocks/tools/witx/src/docs/mod.rs index 219c7d716..ae86872f8 100644 --- a/proposals/clocks/tools/witx/src/docs/mod.rs +++ b/proposals/clocks/tools/witx/src/docs/mod.rs @@ -29,7 +29,6 @@ impl ToMarkdown for Document { .elements .push(typename.gen(Some(Rc::downgrade(&types)))); } - doc.as_section_mut().elements.push(types); let modules = Rc::new(MdSection::new( "modules", "Modules", @@ -41,7 +40,9 @@ impl ToMarkdown for Document { .elements .push(module.gen(Some(Rc::downgrade(&modules)))); } - doc.as_section_mut().elements.push(modules); + doc.as_section_mut() + .elements + .extend_from_slice(&[types, modules]); doc } } @@ -94,10 +95,10 @@ impl ToMarkdown for NamedType { self.name.as_str(), parent, )); - sec.as_section_mut().description.push(self.docs.clone()); - sec.as_section_mut() - .description - .push(format!("Alias to {}", n.name.as_str())); + sec.as_section_mut().description.extend_from_slice(&[ + self.docs.clone(), + format!("Alias to {}", n.name.as_str()), + ]); sec } } @@ -141,7 +142,7 @@ macro_rules! impl_mdbullet { fn from(f: $from) -> Self { Self { id: f.name.as_str().to_owned(), - description: f.docs.clone(), + description: vec![f.docs.clone()], } } } @@ -158,7 +159,7 @@ impl From<&TypeRef> for MdBullet { fn from(t: &TypeRef) -> Self { Self { id: t.type_name().to_owned(), - description: "".to_owned(), // FIXME + description: vec![], } } } @@ -208,7 +209,9 @@ impl ToMarkdown for Module { "Imports", Some(Rc::downgrade(&sec)), )); - // FIXME + // TODO + // This should probably be done using something more specific + // than a generic MdSection for import in self.imports() { let desc = match import.variant { ModuleImportVariant::Memory => format!("* {}: Memory", import.name.as_str()), @@ -250,17 +253,20 @@ impl From<&InterfaceFuncParam> for MdBullet { fn from(param: &InterfaceFuncParam) -> Self { Self { id: param.name.as_str().to_owned(), - description: format!( - "`{}` has type `{}`\n{}\n\n", - param.name.as_str(), - param.tref.type_name(), - param.docs - ), + description: vec![ + format!( + "`{}` has type `{}`", + param.name.as_str(), + param.tref.type_name(), + ), + format!("{}", param.docs), + ], } } } -// TODO polyfill +// TODO +// Implement ToMarkdown for Polyfill impl Documentation for Polyfill { fn to_md(&self) -> String { let module_docs = self From 24977d0758fe24606818e2681956def6cd458804 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 9 Jan 2020 23:12:28 +0100 Subject: [PATCH 0446/1772] Clean up generation of bullets in a Markdown list Fix spurious warnings. --- proposals/random/tools/witx/src/docs/md.rs | 40 +++++++++++++-------- proposals/random/tools/witx/src/docs/mod.rs | 38 +++++++++++--------- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index 3ba383a92..01a93025a 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -12,6 +12,7 @@ pub enum MdElement { } impl MdElement { + #[allow(dead_code)] pub fn as_section(&self) -> Ref { match self { Self::Section(t) => t.borrow(), @@ -26,6 +27,7 @@ impl MdElement { } } + #[allow(dead_code)] pub fn as_type_listing(&self) -> Ref { match self { Self::TypeListing(t) => t.borrow(), @@ -40,6 +42,7 @@ impl MdElement { } } + #[allow(dead_code)] pub fn as_interface_func(&self) -> Ref { match self { Self::InterfaceFunc(t) => t.borrow(), @@ -97,10 +100,10 @@ pub struct MdSection { } impl MdSection { - pub fn new(id: &str, title: &str, parent: Option>) -> MdElement { + pub fn new>(id: S, title: S, parent: Option>) -> MdElement { MdElement::Section(RefCell::new(Self { - id: id.to_owned(), - title: title.to_owned(), + id: id.as_ref().to_owned(), + title: title.as_ref().to_owned(), description: vec![], elements: vec![], parent, @@ -141,6 +144,7 @@ pub struct MdTypeListing { pub parent: Option>, } +#[allow(dead_code)] #[derive(Debug)] pub enum MdType { Enum { repr: String }, @@ -158,7 +162,7 @@ pub enum MdType { #[derive(Debug)] pub struct MdBullet { pub id: String, - pub description: String, + pub description: Vec, } impl MdTypeListing { @@ -214,7 +218,9 @@ impl fmt::Display for MdTypeListing { this_id = self.id, id = el.id ))?; - f.write_fmt(format_args!("\t{}\n", &el.description))?; + for desc in &el.description { + f.write_fmt(format_args!("\t{}\n", desc))?; + } } Ok(()) } @@ -262,14 +268,18 @@ impl fmt::Display for MdInterfaceFunc { // Parameters: // * `argv` // `argv` has type... - f.write_str("\n**Parameters:**\n\n")?; - for param in &self.parameters { - f.write_fmt(format_args!( - "- `{param_id}`\n\n", - id = self.id, - param_id = param.id - ))?; - f.write_fmt(format_args!("\t{}\n", ¶m.description))?; + if !self.parameters.is_empty() { + f.write_str("\n**Parameters:**\n\n")?; + for param in &self.parameters { + f.write_fmt(format_args!( + "- `{param_id}`\n\n", + id = self.id, + param_id = param.id + ))?; + for desc in ¶m.description { + f.write_fmt(format_args!("\t{}\n", desc))?; + } + } } // Results: // * `error` @@ -281,7 +291,9 @@ impl fmt::Display for MdInterfaceFunc { id = self.id, res_id = result.id ))?; - f.write_fmt(format_args!("\t{}\n", &result.description))?; + for desc in &result.description { + f.write_fmt(format_args!("\t{}\n", desc))?; + } } Ok(()) } diff --git a/proposals/random/tools/witx/src/docs/mod.rs b/proposals/random/tools/witx/src/docs/mod.rs index 219c7d716..ae86872f8 100644 --- a/proposals/random/tools/witx/src/docs/mod.rs +++ b/proposals/random/tools/witx/src/docs/mod.rs @@ -29,7 +29,6 @@ impl ToMarkdown for Document { .elements .push(typename.gen(Some(Rc::downgrade(&types)))); } - doc.as_section_mut().elements.push(types); let modules = Rc::new(MdSection::new( "modules", "Modules", @@ -41,7 +40,9 @@ impl ToMarkdown for Document { .elements .push(module.gen(Some(Rc::downgrade(&modules)))); } - doc.as_section_mut().elements.push(modules); + doc.as_section_mut() + .elements + .extend_from_slice(&[types, modules]); doc } } @@ -94,10 +95,10 @@ impl ToMarkdown for NamedType { self.name.as_str(), parent, )); - sec.as_section_mut().description.push(self.docs.clone()); - sec.as_section_mut() - .description - .push(format!("Alias to {}", n.name.as_str())); + sec.as_section_mut().description.extend_from_slice(&[ + self.docs.clone(), + format!("Alias to {}", n.name.as_str()), + ]); sec } } @@ -141,7 +142,7 @@ macro_rules! impl_mdbullet { fn from(f: $from) -> Self { Self { id: f.name.as_str().to_owned(), - description: f.docs.clone(), + description: vec![f.docs.clone()], } } } @@ -158,7 +159,7 @@ impl From<&TypeRef> for MdBullet { fn from(t: &TypeRef) -> Self { Self { id: t.type_name().to_owned(), - description: "".to_owned(), // FIXME + description: vec![], } } } @@ -208,7 +209,9 @@ impl ToMarkdown for Module { "Imports", Some(Rc::downgrade(&sec)), )); - // FIXME + // TODO + // This should probably be done using something more specific + // than a generic MdSection for import in self.imports() { let desc = match import.variant { ModuleImportVariant::Memory => format!("* {}: Memory", import.name.as_str()), @@ -250,17 +253,20 @@ impl From<&InterfaceFuncParam> for MdBullet { fn from(param: &InterfaceFuncParam) -> Self { Self { id: param.name.as_str().to_owned(), - description: format!( - "`{}` has type `{}`\n{}\n\n", - param.name.as_str(), - param.tref.type_name(), - param.docs - ), + description: vec![ + format!( + "`{}` has type `{}`", + param.name.as_str(), + param.tref.type_name(), + ), + format!("{}", param.docs), + ], } } } -// TODO polyfill +// TODO +// Implement ToMarkdown for Polyfill impl Documentation for Polyfill { fn to_md(&self) -> String { let module_docs = self From 021fbff4175ca70648c1ac9452e93793247f91d5 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 9 Jan 2020 23:12:28 +0100 Subject: [PATCH 0447/1772] Clean up generation of bullets in a Markdown list Fix spurious warnings. --- .../filesystem/tools/witx/src/docs/md.rs | 40 ++++++++++++------- .../filesystem/tools/witx/src/docs/mod.rs | 38 ++++++++++-------- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index 3ba383a92..01a93025a 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -12,6 +12,7 @@ pub enum MdElement { } impl MdElement { + #[allow(dead_code)] pub fn as_section(&self) -> Ref { match self { Self::Section(t) => t.borrow(), @@ -26,6 +27,7 @@ impl MdElement { } } + #[allow(dead_code)] pub fn as_type_listing(&self) -> Ref { match self { Self::TypeListing(t) => t.borrow(), @@ -40,6 +42,7 @@ impl MdElement { } } + #[allow(dead_code)] pub fn as_interface_func(&self) -> Ref { match self { Self::InterfaceFunc(t) => t.borrow(), @@ -97,10 +100,10 @@ pub struct MdSection { } impl MdSection { - pub fn new(id: &str, title: &str, parent: Option>) -> MdElement { + pub fn new>(id: S, title: S, parent: Option>) -> MdElement { MdElement::Section(RefCell::new(Self { - id: id.to_owned(), - title: title.to_owned(), + id: id.as_ref().to_owned(), + title: title.as_ref().to_owned(), description: vec![], elements: vec![], parent, @@ -141,6 +144,7 @@ pub struct MdTypeListing { pub parent: Option>, } +#[allow(dead_code)] #[derive(Debug)] pub enum MdType { Enum { repr: String }, @@ -158,7 +162,7 @@ pub enum MdType { #[derive(Debug)] pub struct MdBullet { pub id: String, - pub description: String, + pub description: Vec, } impl MdTypeListing { @@ -214,7 +218,9 @@ impl fmt::Display for MdTypeListing { this_id = self.id, id = el.id ))?; - f.write_fmt(format_args!("\t{}\n", &el.description))?; + for desc in &el.description { + f.write_fmt(format_args!("\t{}\n", desc))?; + } } Ok(()) } @@ -262,14 +268,18 @@ impl fmt::Display for MdInterfaceFunc { // Parameters: // * `argv` // `argv` has type... - f.write_str("\n**Parameters:**\n\n")?; - for param in &self.parameters { - f.write_fmt(format_args!( - "- `{param_id}`\n\n", - id = self.id, - param_id = param.id - ))?; - f.write_fmt(format_args!("\t{}\n", ¶m.description))?; + if !self.parameters.is_empty() { + f.write_str("\n**Parameters:**\n\n")?; + for param in &self.parameters { + f.write_fmt(format_args!( + "- `{param_id}`\n\n", + id = self.id, + param_id = param.id + ))?; + for desc in ¶m.description { + f.write_fmt(format_args!("\t{}\n", desc))?; + } + } } // Results: // * `error` @@ -281,7 +291,9 @@ impl fmt::Display for MdInterfaceFunc { id = self.id, res_id = result.id ))?; - f.write_fmt(format_args!("\t{}\n", &result.description))?; + for desc in &result.description { + f.write_fmt(format_args!("\t{}\n", desc))?; + } } Ok(()) } diff --git a/proposals/filesystem/tools/witx/src/docs/mod.rs b/proposals/filesystem/tools/witx/src/docs/mod.rs index 219c7d716..ae86872f8 100644 --- a/proposals/filesystem/tools/witx/src/docs/mod.rs +++ b/proposals/filesystem/tools/witx/src/docs/mod.rs @@ -29,7 +29,6 @@ impl ToMarkdown for Document { .elements .push(typename.gen(Some(Rc::downgrade(&types)))); } - doc.as_section_mut().elements.push(types); let modules = Rc::new(MdSection::new( "modules", "Modules", @@ -41,7 +40,9 @@ impl ToMarkdown for Document { .elements .push(module.gen(Some(Rc::downgrade(&modules)))); } - doc.as_section_mut().elements.push(modules); + doc.as_section_mut() + .elements + .extend_from_slice(&[types, modules]); doc } } @@ -94,10 +95,10 @@ impl ToMarkdown for NamedType { self.name.as_str(), parent, )); - sec.as_section_mut().description.push(self.docs.clone()); - sec.as_section_mut() - .description - .push(format!("Alias to {}", n.name.as_str())); + sec.as_section_mut().description.extend_from_slice(&[ + self.docs.clone(), + format!("Alias to {}", n.name.as_str()), + ]); sec } } @@ -141,7 +142,7 @@ macro_rules! impl_mdbullet { fn from(f: $from) -> Self { Self { id: f.name.as_str().to_owned(), - description: f.docs.clone(), + description: vec![f.docs.clone()], } } } @@ -158,7 +159,7 @@ impl From<&TypeRef> for MdBullet { fn from(t: &TypeRef) -> Self { Self { id: t.type_name().to_owned(), - description: "".to_owned(), // FIXME + description: vec![], } } } @@ -208,7 +209,9 @@ impl ToMarkdown for Module { "Imports", Some(Rc::downgrade(&sec)), )); - // FIXME + // TODO + // This should probably be done using something more specific + // than a generic MdSection for import in self.imports() { let desc = match import.variant { ModuleImportVariant::Memory => format!("* {}: Memory", import.name.as_str()), @@ -250,17 +253,20 @@ impl From<&InterfaceFuncParam> for MdBullet { fn from(param: &InterfaceFuncParam) -> Self { Self { id: param.name.as_str().to_owned(), - description: format!( - "`{}` has type `{}`\n{}\n\n", - param.name.as_str(), - param.tref.type_name(), - param.docs - ), + description: vec![ + format!( + "`{}` has type `{}`", + param.name.as_str(), + param.tref.type_name(), + ), + format!("{}", param.docs), + ], } } } -// TODO polyfill +// TODO +// Implement ToMarkdown for Polyfill impl Documentation for Polyfill { fn to_md(&self) -> String { let module_docs = self From afa4f86d9b1e149388275c97b692cc049b62db54 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 9 Jan 2020 23:22:29 +0100 Subject: [PATCH 0448/1772] Clean up link generation for headers and bullets --- proposals/clocks/tools/witx/src/docs/md.rs | 57 ++++++++++++---------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index 01a93025a..b59af542f 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -4,6 +4,24 @@ use std::{ rc::{Rc, Weak}, }; +fn walk_parents(start: &Weak, cb: &mut impl FnMut(Rc)) { + let mut parent = if let Some(parent) = start.upgrade() { + cb(parent.clone()); + parent + } else { + return; + }; + + while let Some(p) = parent.parent() { + cb(p.clone()); + parent = p; + } +} + +fn gen_link>(id: S) -> String { + format!("", id = id.as_ref()) +} + #[derive(Debug)] pub enum MdElement { Section(RefCell), @@ -76,20 +94,6 @@ impl fmt::Display for MdElement { } } -fn walk_parents(start: &Weak, cb: &mut impl FnMut(Rc)) { - let mut parent = if let Some(parent) = start.upgrade() { - cb(parent.clone()); - parent - } else { - return; - }; - - while let Some(p) = parent.parent() { - cb(p.clone()); - parent = p; - } -} - #[derive(Debug)] pub struct MdSection { pub id: String, @@ -120,10 +124,10 @@ impl fmt::Display for MdSection { }); } f.write_fmt(format_args!( - "{heading} {title}\n", + "{heading} {link} {title}\n", heading = heading, - id = self.id, - title = self.title + link = gen_link(&self.id), + title = &self.title ))?; for para in &self.description { f.write_fmt(format_args!("{}\n", para))?; @@ -187,9 +191,10 @@ impl fmt::Display for MdTypeListing { } // ### `errno` f.write_fmt(format_args!( - "{heading} `{id}`\n", + "{heading} {link} `{id}`\n", heading = heading, - id = self.id + link = gen_link(&self.id), + id = &self.id ))?; // Error codes returned by function... for para in &self.description { @@ -214,9 +219,9 @@ impl fmt::Display for MdTypeListing { // No error occurred. System call completed successfully. for el in &self.elements { f.write_fmt(format_args!( - "- `{id}`\n\n", - this_id = self.id, - id = el.id + "- {link} `{el_id}`\n\n", + link = gen_link(format!("{}.{}", self.id, el.id)), + el_id = el.id ))?; for desc in &el.description { f.write_fmt(format_args!("\t{}\n", desc))?; @@ -272,8 +277,8 @@ impl fmt::Display for MdInterfaceFunc { f.write_str("\n**Parameters:**\n\n")?; for param in &self.parameters { f.write_fmt(format_args!( - "- `{param_id}`\n\n", - id = self.id, + "- {link} `{param_id}`\n\n", + link = gen_link(format!("{}.{}", self.id, param.id)), param_id = param.id ))?; for desc in ¶m.description { @@ -287,8 +292,8 @@ impl fmt::Display for MdInterfaceFunc { f.write_str("\n**Results:**\n\n")?; for result in &self.results { f.write_fmt(format_args!( - "- `{res_id}`\n\n", - id = self.id, + "- {link} `{res_id}`\n\n", + link = gen_link(format!("{}.{}", self.id, result.id)), res_id = result.id ))?; for desc in &result.description { From 4e19f148d6af8dd076634ec3695232df5fc143dd Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 9 Jan 2020 23:22:29 +0100 Subject: [PATCH 0449/1772] Clean up link generation for headers and bullets --- proposals/random/tools/witx/src/docs/md.rs | 57 ++++++++++++---------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index 01a93025a..b59af542f 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -4,6 +4,24 @@ use std::{ rc::{Rc, Weak}, }; +fn walk_parents(start: &Weak, cb: &mut impl FnMut(Rc)) { + let mut parent = if let Some(parent) = start.upgrade() { + cb(parent.clone()); + parent + } else { + return; + }; + + while let Some(p) = parent.parent() { + cb(p.clone()); + parent = p; + } +} + +fn gen_link>(id: S) -> String { + format!("", id = id.as_ref()) +} + #[derive(Debug)] pub enum MdElement { Section(RefCell), @@ -76,20 +94,6 @@ impl fmt::Display for MdElement { } } -fn walk_parents(start: &Weak, cb: &mut impl FnMut(Rc)) { - let mut parent = if let Some(parent) = start.upgrade() { - cb(parent.clone()); - parent - } else { - return; - }; - - while let Some(p) = parent.parent() { - cb(p.clone()); - parent = p; - } -} - #[derive(Debug)] pub struct MdSection { pub id: String, @@ -120,10 +124,10 @@ impl fmt::Display for MdSection { }); } f.write_fmt(format_args!( - "{heading} {title}\n", + "{heading} {link} {title}\n", heading = heading, - id = self.id, - title = self.title + link = gen_link(&self.id), + title = &self.title ))?; for para in &self.description { f.write_fmt(format_args!("{}\n", para))?; @@ -187,9 +191,10 @@ impl fmt::Display for MdTypeListing { } // ### `errno` f.write_fmt(format_args!( - "{heading} `{id}`\n", + "{heading} {link} `{id}`\n", heading = heading, - id = self.id + link = gen_link(&self.id), + id = &self.id ))?; // Error codes returned by function... for para in &self.description { @@ -214,9 +219,9 @@ impl fmt::Display for MdTypeListing { // No error occurred. System call completed successfully. for el in &self.elements { f.write_fmt(format_args!( - "- `{id}`\n\n", - this_id = self.id, - id = el.id + "- {link} `{el_id}`\n\n", + link = gen_link(format!("{}.{}", self.id, el.id)), + el_id = el.id ))?; for desc in &el.description { f.write_fmt(format_args!("\t{}\n", desc))?; @@ -272,8 +277,8 @@ impl fmt::Display for MdInterfaceFunc { f.write_str("\n**Parameters:**\n\n")?; for param in &self.parameters { f.write_fmt(format_args!( - "- `{param_id}`\n\n", - id = self.id, + "- {link} `{param_id}`\n\n", + link = gen_link(format!("{}.{}", self.id, param.id)), param_id = param.id ))?; for desc in ¶m.description { @@ -287,8 +292,8 @@ impl fmt::Display for MdInterfaceFunc { f.write_str("\n**Results:**\n\n")?; for result in &self.results { f.write_fmt(format_args!( - "- `{res_id}`\n\n", - id = self.id, + "- {link} `{res_id}`\n\n", + link = gen_link(format!("{}.{}", self.id, result.id)), res_id = result.id ))?; for desc in &result.description { From 0bf3856e6924e58c7779143687107ebb8e7dc92d Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 9 Jan 2020 23:22:29 +0100 Subject: [PATCH 0450/1772] Clean up link generation for headers and bullets --- .../filesystem/tools/witx/src/docs/md.rs | 57 ++++++++++--------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index 01a93025a..b59af542f 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -4,6 +4,24 @@ use std::{ rc::{Rc, Weak}, }; +fn walk_parents(start: &Weak, cb: &mut impl FnMut(Rc)) { + let mut parent = if let Some(parent) = start.upgrade() { + cb(parent.clone()); + parent + } else { + return; + }; + + while let Some(p) = parent.parent() { + cb(p.clone()); + parent = p; + } +} + +fn gen_link>(id: S) -> String { + format!("", id = id.as_ref()) +} + #[derive(Debug)] pub enum MdElement { Section(RefCell), @@ -76,20 +94,6 @@ impl fmt::Display for MdElement { } } -fn walk_parents(start: &Weak, cb: &mut impl FnMut(Rc)) { - let mut parent = if let Some(parent) = start.upgrade() { - cb(parent.clone()); - parent - } else { - return; - }; - - while let Some(p) = parent.parent() { - cb(p.clone()); - parent = p; - } -} - #[derive(Debug)] pub struct MdSection { pub id: String, @@ -120,10 +124,10 @@ impl fmt::Display for MdSection { }); } f.write_fmt(format_args!( - "{heading} {title}\n", + "{heading} {link} {title}\n", heading = heading, - id = self.id, - title = self.title + link = gen_link(&self.id), + title = &self.title ))?; for para in &self.description { f.write_fmt(format_args!("{}\n", para))?; @@ -187,9 +191,10 @@ impl fmt::Display for MdTypeListing { } // ### `errno` f.write_fmt(format_args!( - "{heading} `{id}`\n", + "{heading} {link} `{id}`\n", heading = heading, - id = self.id + link = gen_link(&self.id), + id = &self.id ))?; // Error codes returned by function... for para in &self.description { @@ -214,9 +219,9 @@ impl fmt::Display for MdTypeListing { // No error occurred. System call completed successfully. for el in &self.elements { f.write_fmt(format_args!( - "- `{id}`\n\n", - this_id = self.id, - id = el.id + "- {link} `{el_id}`\n\n", + link = gen_link(format!("{}.{}", self.id, el.id)), + el_id = el.id ))?; for desc in &el.description { f.write_fmt(format_args!("\t{}\n", desc))?; @@ -272,8 +277,8 @@ impl fmt::Display for MdInterfaceFunc { f.write_str("\n**Parameters:**\n\n")?; for param in &self.parameters { f.write_fmt(format_args!( - "- `{param_id}`\n\n", - id = self.id, + "- {link} `{param_id}`\n\n", + link = gen_link(format!("{}.{}", self.id, param.id)), param_id = param.id ))?; for desc in ¶m.description { @@ -287,8 +292,8 @@ impl fmt::Display for MdInterfaceFunc { f.write_str("\n**Results:**\n\n")?; for result in &self.results { f.write_fmt(format_args!( - "- `{res_id}`\n\n", - id = self.id, + "- {link} `{res_id}`\n\n", + link = gen_link(format!("{}.{}", self.id, result.id)), res_id = result.id ))?; for desc in &result.description { From 61ab5cbf8441eb3ffb0b88c2f51081d34b464dae Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 9 Jan 2020 23:31:39 +0100 Subject: [PATCH 0451/1772] Fix scoping of types --- proposals/clocks/tools/witx/src/docs/md.rs | 26 ++++++++++----------- proposals/clocks/tools/witx/src/docs/mod.rs | 5 ++-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index b59af542f..60cd009eb 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -23,7 +23,7 @@ fn gen_link>(id: S) -> String { } #[derive(Debug)] -pub enum MdElement { +pub(super) enum MdElement { Section(RefCell), TypeListing(RefCell), InterfaceFunc(RefCell), @@ -31,14 +31,14 @@ pub enum MdElement { impl MdElement { #[allow(dead_code)] - pub fn as_section(&self) -> Ref { + pub(super) fn as_section(&self) -> Ref { match self { Self::Section(t) => t.borrow(), _ => panic!("not a MdSection"), } } - pub fn as_section_mut(&self) -> RefMut { + pub(super) fn as_section_mut(&self) -> RefMut { match self { Self::Section(t) => t.borrow_mut(), _ => panic!("not a MdSection"), @@ -46,14 +46,14 @@ impl MdElement { } #[allow(dead_code)] - pub fn as_type_listing(&self) -> Ref { + pub(super) fn as_type_listing(&self) -> Ref { match self { Self::TypeListing(t) => t.borrow(), _ => panic!("not a MdTypeListing"), } } - pub fn as_type_listing_mut(&self) -> RefMut { + pub(super) fn as_type_listing_mut(&self) -> RefMut { match self { Self::TypeListing(t) => t.borrow_mut(), _ => panic!("not a MdTypeListing"), @@ -61,21 +61,21 @@ impl MdElement { } #[allow(dead_code)] - pub fn as_interface_func(&self) -> Ref { + pub(super) fn as_interface_func(&self) -> Ref { match self { Self::InterfaceFunc(t) => t.borrow(), _ => panic!("not a MdInterfaceFunc"), } } - pub fn as_interface_func_mut(&self) -> RefMut { + pub(super) fn as_interface_func_mut(&self) -> RefMut { match self { Self::InterfaceFunc(t) => t.borrow_mut(), _ => panic!("not a MdInterfaceFunc"), } } - pub fn parent(&self) -> Option> { + pub(super) fn parent(&self) -> Option> { match self { Self::Section(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), Self::TypeListing(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), @@ -95,7 +95,7 @@ impl fmt::Display for MdElement { } #[derive(Debug)] -pub struct MdSection { +pub(super) struct MdSection { pub id: String, pub title: String, pub description: Vec, @@ -140,7 +140,7 @@ impl fmt::Display for MdSection { } #[derive(Debug)] -pub struct MdTypeListing { +pub(super) struct MdTypeListing { pub id: String, pub r#type: MdType, pub description: Vec, @@ -150,7 +150,7 @@ pub struct MdTypeListing { #[allow(dead_code)] #[derive(Debug)] -pub enum MdType { +pub(super) enum MdType { Enum { repr: String }, Int { repr: String }, Flags { repr: String }, @@ -164,7 +164,7 @@ pub enum MdType { } #[derive(Debug)] -pub struct MdBullet { +pub(super) struct MdBullet { pub id: String, pub description: Vec, } @@ -232,7 +232,7 @@ impl fmt::Display for MdTypeListing { } #[derive(Debug)] -pub struct MdInterfaceFunc { +pub(super) struct MdInterfaceFunc { pub id: String, pub description: Vec, pub parameters: Vec, diff --git a/proposals/clocks/tools/witx/src/docs/mod.rs b/proposals/clocks/tools/witx/src/docs/mod.rs index ae86872f8..e2b9eab5e 100644 --- a/proposals/clocks/tools/witx/src/docs/mod.rs +++ b/proposals/clocks/tools/witx/src/docs/mod.rs @@ -1,15 +1,16 @@ mod md; -pub use self::md::*; use crate::ast::*; use crate::polyfill::*; use crate::RepEquality; +use md::*; use std::rc::{Rc, Weak}; pub trait Documentation { fn to_md(&self) -> String; } -pub trait ToMarkdown { + +trait ToMarkdown { fn gen(&self, _parent: Option>) -> Rc; } From 8a71634b12d965cd457d77a01e41531d26def878 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 9 Jan 2020 23:31:39 +0100 Subject: [PATCH 0452/1772] Fix scoping of types --- proposals/random/tools/witx/src/docs/md.rs | 26 ++++++++++----------- proposals/random/tools/witx/src/docs/mod.rs | 5 ++-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index b59af542f..60cd009eb 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -23,7 +23,7 @@ fn gen_link>(id: S) -> String { } #[derive(Debug)] -pub enum MdElement { +pub(super) enum MdElement { Section(RefCell), TypeListing(RefCell), InterfaceFunc(RefCell), @@ -31,14 +31,14 @@ pub enum MdElement { impl MdElement { #[allow(dead_code)] - pub fn as_section(&self) -> Ref { + pub(super) fn as_section(&self) -> Ref { match self { Self::Section(t) => t.borrow(), _ => panic!("not a MdSection"), } } - pub fn as_section_mut(&self) -> RefMut { + pub(super) fn as_section_mut(&self) -> RefMut { match self { Self::Section(t) => t.borrow_mut(), _ => panic!("not a MdSection"), @@ -46,14 +46,14 @@ impl MdElement { } #[allow(dead_code)] - pub fn as_type_listing(&self) -> Ref { + pub(super) fn as_type_listing(&self) -> Ref { match self { Self::TypeListing(t) => t.borrow(), _ => panic!("not a MdTypeListing"), } } - pub fn as_type_listing_mut(&self) -> RefMut { + pub(super) fn as_type_listing_mut(&self) -> RefMut { match self { Self::TypeListing(t) => t.borrow_mut(), _ => panic!("not a MdTypeListing"), @@ -61,21 +61,21 @@ impl MdElement { } #[allow(dead_code)] - pub fn as_interface_func(&self) -> Ref { + pub(super) fn as_interface_func(&self) -> Ref { match self { Self::InterfaceFunc(t) => t.borrow(), _ => panic!("not a MdInterfaceFunc"), } } - pub fn as_interface_func_mut(&self) -> RefMut { + pub(super) fn as_interface_func_mut(&self) -> RefMut { match self { Self::InterfaceFunc(t) => t.borrow_mut(), _ => panic!("not a MdInterfaceFunc"), } } - pub fn parent(&self) -> Option> { + pub(super) fn parent(&self) -> Option> { match self { Self::Section(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), Self::TypeListing(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), @@ -95,7 +95,7 @@ impl fmt::Display for MdElement { } #[derive(Debug)] -pub struct MdSection { +pub(super) struct MdSection { pub id: String, pub title: String, pub description: Vec, @@ -140,7 +140,7 @@ impl fmt::Display for MdSection { } #[derive(Debug)] -pub struct MdTypeListing { +pub(super) struct MdTypeListing { pub id: String, pub r#type: MdType, pub description: Vec, @@ -150,7 +150,7 @@ pub struct MdTypeListing { #[allow(dead_code)] #[derive(Debug)] -pub enum MdType { +pub(super) enum MdType { Enum { repr: String }, Int { repr: String }, Flags { repr: String }, @@ -164,7 +164,7 @@ pub enum MdType { } #[derive(Debug)] -pub struct MdBullet { +pub(super) struct MdBullet { pub id: String, pub description: Vec, } @@ -232,7 +232,7 @@ impl fmt::Display for MdTypeListing { } #[derive(Debug)] -pub struct MdInterfaceFunc { +pub(super) struct MdInterfaceFunc { pub id: String, pub description: Vec, pub parameters: Vec, diff --git a/proposals/random/tools/witx/src/docs/mod.rs b/proposals/random/tools/witx/src/docs/mod.rs index ae86872f8..e2b9eab5e 100644 --- a/proposals/random/tools/witx/src/docs/mod.rs +++ b/proposals/random/tools/witx/src/docs/mod.rs @@ -1,15 +1,16 @@ mod md; -pub use self::md::*; use crate::ast::*; use crate::polyfill::*; use crate::RepEquality; +use md::*; use std::rc::{Rc, Weak}; pub trait Documentation { fn to_md(&self) -> String; } -pub trait ToMarkdown { + +trait ToMarkdown { fn gen(&self, _parent: Option>) -> Rc; } From a708720132079753f31f17ac4902099769ac8052 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 9 Jan 2020 23:31:39 +0100 Subject: [PATCH 0453/1772] Fix scoping of types --- .../filesystem/tools/witx/src/docs/md.rs | 26 +++++++++---------- .../filesystem/tools/witx/src/docs/mod.rs | 5 ++-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index b59af542f..60cd009eb 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -23,7 +23,7 @@ fn gen_link>(id: S) -> String { } #[derive(Debug)] -pub enum MdElement { +pub(super) enum MdElement { Section(RefCell), TypeListing(RefCell), InterfaceFunc(RefCell), @@ -31,14 +31,14 @@ pub enum MdElement { impl MdElement { #[allow(dead_code)] - pub fn as_section(&self) -> Ref { + pub(super) fn as_section(&self) -> Ref { match self { Self::Section(t) => t.borrow(), _ => panic!("not a MdSection"), } } - pub fn as_section_mut(&self) -> RefMut { + pub(super) fn as_section_mut(&self) -> RefMut { match self { Self::Section(t) => t.borrow_mut(), _ => panic!("not a MdSection"), @@ -46,14 +46,14 @@ impl MdElement { } #[allow(dead_code)] - pub fn as_type_listing(&self) -> Ref { + pub(super) fn as_type_listing(&self) -> Ref { match self { Self::TypeListing(t) => t.borrow(), _ => panic!("not a MdTypeListing"), } } - pub fn as_type_listing_mut(&self) -> RefMut { + pub(super) fn as_type_listing_mut(&self) -> RefMut { match self { Self::TypeListing(t) => t.borrow_mut(), _ => panic!("not a MdTypeListing"), @@ -61,21 +61,21 @@ impl MdElement { } #[allow(dead_code)] - pub fn as_interface_func(&self) -> Ref { + pub(super) fn as_interface_func(&self) -> Ref { match self { Self::InterfaceFunc(t) => t.borrow(), _ => panic!("not a MdInterfaceFunc"), } } - pub fn as_interface_func_mut(&self) -> RefMut { + pub(super) fn as_interface_func_mut(&self) -> RefMut { match self { Self::InterfaceFunc(t) => t.borrow_mut(), _ => panic!("not a MdInterfaceFunc"), } } - pub fn parent(&self) -> Option> { + pub(super) fn parent(&self) -> Option> { match self { Self::Section(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), Self::TypeListing(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), @@ -95,7 +95,7 @@ impl fmt::Display for MdElement { } #[derive(Debug)] -pub struct MdSection { +pub(super) struct MdSection { pub id: String, pub title: String, pub description: Vec, @@ -140,7 +140,7 @@ impl fmt::Display for MdSection { } #[derive(Debug)] -pub struct MdTypeListing { +pub(super) struct MdTypeListing { pub id: String, pub r#type: MdType, pub description: Vec, @@ -150,7 +150,7 @@ pub struct MdTypeListing { #[allow(dead_code)] #[derive(Debug)] -pub enum MdType { +pub(super) enum MdType { Enum { repr: String }, Int { repr: String }, Flags { repr: String }, @@ -164,7 +164,7 @@ pub enum MdType { } #[derive(Debug)] -pub struct MdBullet { +pub(super) struct MdBullet { pub id: String, pub description: Vec, } @@ -232,7 +232,7 @@ impl fmt::Display for MdTypeListing { } #[derive(Debug)] -pub struct MdInterfaceFunc { +pub(super) struct MdInterfaceFunc { pub id: String, pub description: Vec, pub parameters: Vec, diff --git a/proposals/filesystem/tools/witx/src/docs/mod.rs b/proposals/filesystem/tools/witx/src/docs/mod.rs index ae86872f8..e2b9eab5e 100644 --- a/proposals/filesystem/tools/witx/src/docs/mod.rs +++ b/proposals/filesystem/tools/witx/src/docs/mod.rs @@ -1,15 +1,16 @@ mod md; -pub use self::md::*; use crate::ast::*; use crate::polyfill::*; use crate::RepEquality; +use md::*; use std::rc::{Rc, Weak}; pub trait Documentation { fn to_md(&self) -> String; } -pub trait ToMarkdown { + +trait ToMarkdown { fn gen(&self, _parent: Option>) -> Rc; } From a55d8a22e2b6df8a89969f597e6ecd185459c4cb Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 10 Jan 2020 00:10:42 +0100 Subject: [PATCH 0454/1772] Add parse_links in again --- proposals/clocks/tools/witx/src/docs/md.rs | 65 +++++++++++++++++++-- proposals/clocks/tools/witx/src/docs/mod.rs | 23 ++++---- 2 files changed, 72 insertions(+), 16 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index 60cd009eb..52ea968a8 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -22,6 +22,44 @@ fn gen_link>(id: S) -> String { format!("", id = id.as_ref()) } +fn parse_links>(s: S) -> String { + let to_parse = s.as_ref(); + let mut parsed = String::with_capacity(to_parse.len()); + let mut temp = String::with_capacity(to_parse.len()); + let mut is_link = false; + let mut eaten = None; + for ch in to_parse.chars() { + match (ch, is_link) { + ('`', false) => { + // Found the beginning of a link! + is_link = true; + } + ('`', true) => { + // Reached the end, expand into a link! + // TODO + // Before committing to pasting the link in, + // first verify that it actually exists. + let expanded = format!("[`{}`](#{})", temp, temp); + parsed.push_str(&expanded); + temp.drain(..); + is_link = false; + } + (':', true) => { + if let Some(_) = eaten { + // Swap for '.' + temp.push('.'); + eaten = None; + } else { + eaten = Some(':'); + } + } + (ch, false) => parsed.push(ch), + (ch, true) => temp.push(ch), + } + } + parsed +} + #[derive(Debug)] pub(super) enum MdElement { Section(RefCell), @@ -98,11 +136,26 @@ impl fmt::Display for MdElement { pub(super) struct MdSection { pub id: String, pub title: String, - pub description: Vec, + pub description: Vec, pub elements: Vec>, pub parent: Option>, } +#[derive(Debug)] +pub(super) struct MdParagraph(String); + +impl MdParagraph { + pub fn new>(s: S) -> Self { + Self(s.as_ref().to_owned()) + } +} + +impl fmt::Display for MdParagraph { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + writeln!(f, "{}", parse_links(&self.0)) + } +} + impl MdSection { pub fn new>(id: S, title: S, parent: Option>) -> MdElement { MdElement::Section(RefCell::new(Self { @@ -143,7 +196,7 @@ impl fmt::Display for MdSection { pub(super) struct MdTypeListing { pub id: String, pub r#type: MdType, - pub description: Vec, + pub description: Vec, pub elements: Vec, pub parent: Option>, } @@ -166,7 +219,7 @@ pub(super) enum MdType { #[derive(Debug)] pub(super) struct MdBullet { pub id: String, - pub description: Vec, + pub description: Vec, } impl MdTypeListing { @@ -234,7 +287,7 @@ impl fmt::Display for MdTypeListing { #[derive(Debug)] pub(super) struct MdInterfaceFunc { pub id: String, - pub description: Vec, + pub description: Vec, pub parameters: Vec, pub results: Vec, pub parent: Option>, @@ -274,7 +327,7 @@ impl fmt::Display for MdInterfaceFunc { // * `argv` // `argv` has type... if !self.parameters.is_empty() { - f.write_str("\n**Parameters:**\n\n")?; + f.write_str("**Parameters:**\n\n")?; for param in &self.parameters { f.write_fmt(format_args!( "- {link} `{param_id}`\n\n", @@ -289,7 +342,7 @@ impl fmt::Display for MdInterfaceFunc { // Results: // * `error` // `error` has type `errno` - f.write_str("\n**Results:**\n\n")?; + f.write_str("**Results:**\n\n")?; for result in &self.results { f.write_fmt(format_args!( "- {link} `{res_id}`\n\n", diff --git a/proposals/clocks/tools/witx/src/docs/mod.rs b/proposals/clocks/tools/witx/src/docs/mod.rs index e2b9eab5e..ebf720416 100644 --- a/proposals/clocks/tools/witx/src/docs/mod.rs +++ b/proposals/clocks/tools/witx/src/docs/mod.rs @@ -86,7 +86,7 @@ impl ToMarkdown for NamedType { listing .as_type_listing_mut() .description - .push(self.docs.clone()); + .push(MdParagraph::new(&self.docs)); listing.as_type_listing_mut().elements.append(&mut elements); listing } @@ -96,9 +96,9 @@ impl ToMarkdown for NamedType { self.name.as_str(), parent, )); - sec.as_section_mut().description.extend_from_slice(&[ - self.docs.clone(), - format!("Alias to {}", n.name.as_str()), + sec.as_section_mut().description.append(&mut vec![ + MdParagraph::new(&self.docs), + MdParagraph::new(format!("Alias to {}", n.name.as_str())), ]); sec } @@ -143,7 +143,7 @@ macro_rules! impl_mdbullet { fn from(f: $from) -> Self { Self { id: f.name.as_str().to_owned(), - description: vec![f.docs.clone()], + description: vec![MdParagraph::new(&f.docs)], } } } @@ -217,7 +217,10 @@ impl ToMarkdown for Module { let desc = match import.variant { ModuleImportVariant::Memory => format!("* {}: Memory", import.name.as_str()), }; - imports.as_section_mut().description.push(desc); + imports + .as_section_mut() + .description + .push(MdParagraph::new(desc)); } sec.as_section_mut().elements.push(imports); let funcs = Rc::new(MdSection::new( @@ -239,7 +242,7 @@ impl ToMarkdown for InterfaceFunc { let func = Rc::new(MdInterfaceFunc::new(self.name.as_str(), parent)); func.as_interface_func_mut() .description - .push(self.docs.clone()); + .push(MdParagraph::new(&self.docs)); func.as_interface_func_mut() .parameters .extend(self.params.iter().map(MdBullet::from)); @@ -255,12 +258,12 @@ impl From<&InterfaceFuncParam> for MdBullet { Self { id: param.name.as_str().to_owned(), description: vec![ - format!( + MdParagraph::new(format!( "`{}` has type `{}`", param.name.as_str(), param.tref.type_name(), - ), - format!("{}", param.docs), + )), + MdParagraph::new(format!("{}", param.docs)), ], } } From 8f0bb56fb8c381967a3926c72a981cb66a07056c Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 10 Jan 2020 00:10:42 +0100 Subject: [PATCH 0455/1772] Add parse_links in again --- proposals/random/tools/witx/src/docs/md.rs | 65 +++++++++++++++++++-- proposals/random/tools/witx/src/docs/mod.rs | 23 ++++---- 2 files changed, 72 insertions(+), 16 deletions(-) diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index 60cd009eb..52ea968a8 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -22,6 +22,44 @@ fn gen_link>(id: S) -> String { format!("", id = id.as_ref()) } +fn parse_links>(s: S) -> String { + let to_parse = s.as_ref(); + let mut parsed = String::with_capacity(to_parse.len()); + let mut temp = String::with_capacity(to_parse.len()); + let mut is_link = false; + let mut eaten = None; + for ch in to_parse.chars() { + match (ch, is_link) { + ('`', false) => { + // Found the beginning of a link! + is_link = true; + } + ('`', true) => { + // Reached the end, expand into a link! + // TODO + // Before committing to pasting the link in, + // first verify that it actually exists. + let expanded = format!("[`{}`](#{})", temp, temp); + parsed.push_str(&expanded); + temp.drain(..); + is_link = false; + } + (':', true) => { + if let Some(_) = eaten { + // Swap for '.' + temp.push('.'); + eaten = None; + } else { + eaten = Some(':'); + } + } + (ch, false) => parsed.push(ch), + (ch, true) => temp.push(ch), + } + } + parsed +} + #[derive(Debug)] pub(super) enum MdElement { Section(RefCell), @@ -98,11 +136,26 @@ impl fmt::Display for MdElement { pub(super) struct MdSection { pub id: String, pub title: String, - pub description: Vec, + pub description: Vec, pub elements: Vec>, pub parent: Option>, } +#[derive(Debug)] +pub(super) struct MdParagraph(String); + +impl MdParagraph { + pub fn new>(s: S) -> Self { + Self(s.as_ref().to_owned()) + } +} + +impl fmt::Display for MdParagraph { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + writeln!(f, "{}", parse_links(&self.0)) + } +} + impl MdSection { pub fn new>(id: S, title: S, parent: Option>) -> MdElement { MdElement::Section(RefCell::new(Self { @@ -143,7 +196,7 @@ impl fmt::Display for MdSection { pub(super) struct MdTypeListing { pub id: String, pub r#type: MdType, - pub description: Vec, + pub description: Vec, pub elements: Vec, pub parent: Option>, } @@ -166,7 +219,7 @@ pub(super) enum MdType { #[derive(Debug)] pub(super) struct MdBullet { pub id: String, - pub description: Vec, + pub description: Vec, } impl MdTypeListing { @@ -234,7 +287,7 @@ impl fmt::Display for MdTypeListing { #[derive(Debug)] pub(super) struct MdInterfaceFunc { pub id: String, - pub description: Vec, + pub description: Vec, pub parameters: Vec, pub results: Vec, pub parent: Option>, @@ -274,7 +327,7 @@ impl fmt::Display for MdInterfaceFunc { // * `argv` // `argv` has type... if !self.parameters.is_empty() { - f.write_str("\n**Parameters:**\n\n")?; + f.write_str("**Parameters:**\n\n")?; for param in &self.parameters { f.write_fmt(format_args!( "- {link} `{param_id}`\n\n", @@ -289,7 +342,7 @@ impl fmt::Display for MdInterfaceFunc { // Results: // * `error` // `error` has type `errno` - f.write_str("\n**Results:**\n\n")?; + f.write_str("**Results:**\n\n")?; for result in &self.results { f.write_fmt(format_args!( "- {link} `{res_id}`\n\n", diff --git a/proposals/random/tools/witx/src/docs/mod.rs b/proposals/random/tools/witx/src/docs/mod.rs index e2b9eab5e..ebf720416 100644 --- a/proposals/random/tools/witx/src/docs/mod.rs +++ b/proposals/random/tools/witx/src/docs/mod.rs @@ -86,7 +86,7 @@ impl ToMarkdown for NamedType { listing .as_type_listing_mut() .description - .push(self.docs.clone()); + .push(MdParagraph::new(&self.docs)); listing.as_type_listing_mut().elements.append(&mut elements); listing } @@ -96,9 +96,9 @@ impl ToMarkdown for NamedType { self.name.as_str(), parent, )); - sec.as_section_mut().description.extend_from_slice(&[ - self.docs.clone(), - format!("Alias to {}", n.name.as_str()), + sec.as_section_mut().description.append(&mut vec![ + MdParagraph::new(&self.docs), + MdParagraph::new(format!("Alias to {}", n.name.as_str())), ]); sec } @@ -143,7 +143,7 @@ macro_rules! impl_mdbullet { fn from(f: $from) -> Self { Self { id: f.name.as_str().to_owned(), - description: vec![f.docs.clone()], + description: vec![MdParagraph::new(&f.docs)], } } } @@ -217,7 +217,10 @@ impl ToMarkdown for Module { let desc = match import.variant { ModuleImportVariant::Memory => format!("* {}: Memory", import.name.as_str()), }; - imports.as_section_mut().description.push(desc); + imports + .as_section_mut() + .description + .push(MdParagraph::new(desc)); } sec.as_section_mut().elements.push(imports); let funcs = Rc::new(MdSection::new( @@ -239,7 +242,7 @@ impl ToMarkdown for InterfaceFunc { let func = Rc::new(MdInterfaceFunc::new(self.name.as_str(), parent)); func.as_interface_func_mut() .description - .push(self.docs.clone()); + .push(MdParagraph::new(&self.docs)); func.as_interface_func_mut() .parameters .extend(self.params.iter().map(MdBullet::from)); @@ -255,12 +258,12 @@ impl From<&InterfaceFuncParam> for MdBullet { Self { id: param.name.as_str().to_owned(), description: vec![ - format!( + MdParagraph::new(format!( "`{}` has type `{}`", param.name.as_str(), param.tref.type_name(), - ), - format!("{}", param.docs), + )), + MdParagraph::new(format!("{}", param.docs)), ], } } From 16f6914f54bf61775870541db303212e3a6fa1c4 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 10 Jan 2020 00:10:42 +0100 Subject: [PATCH 0456/1772] Add parse_links in again --- .../filesystem/tools/witx/src/docs/md.rs | 65 +++++++++++++++++-- .../filesystem/tools/witx/src/docs/mod.rs | 23 ++++--- 2 files changed, 72 insertions(+), 16 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index 60cd009eb..52ea968a8 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -22,6 +22,44 @@ fn gen_link>(id: S) -> String { format!("", id = id.as_ref()) } +fn parse_links>(s: S) -> String { + let to_parse = s.as_ref(); + let mut parsed = String::with_capacity(to_parse.len()); + let mut temp = String::with_capacity(to_parse.len()); + let mut is_link = false; + let mut eaten = None; + for ch in to_parse.chars() { + match (ch, is_link) { + ('`', false) => { + // Found the beginning of a link! + is_link = true; + } + ('`', true) => { + // Reached the end, expand into a link! + // TODO + // Before committing to pasting the link in, + // first verify that it actually exists. + let expanded = format!("[`{}`](#{})", temp, temp); + parsed.push_str(&expanded); + temp.drain(..); + is_link = false; + } + (':', true) => { + if let Some(_) = eaten { + // Swap for '.' + temp.push('.'); + eaten = None; + } else { + eaten = Some(':'); + } + } + (ch, false) => parsed.push(ch), + (ch, true) => temp.push(ch), + } + } + parsed +} + #[derive(Debug)] pub(super) enum MdElement { Section(RefCell), @@ -98,11 +136,26 @@ impl fmt::Display for MdElement { pub(super) struct MdSection { pub id: String, pub title: String, - pub description: Vec, + pub description: Vec, pub elements: Vec>, pub parent: Option>, } +#[derive(Debug)] +pub(super) struct MdParagraph(String); + +impl MdParagraph { + pub fn new>(s: S) -> Self { + Self(s.as_ref().to_owned()) + } +} + +impl fmt::Display for MdParagraph { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + writeln!(f, "{}", parse_links(&self.0)) + } +} + impl MdSection { pub fn new>(id: S, title: S, parent: Option>) -> MdElement { MdElement::Section(RefCell::new(Self { @@ -143,7 +196,7 @@ impl fmt::Display for MdSection { pub(super) struct MdTypeListing { pub id: String, pub r#type: MdType, - pub description: Vec, + pub description: Vec, pub elements: Vec, pub parent: Option>, } @@ -166,7 +219,7 @@ pub(super) enum MdType { #[derive(Debug)] pub(super) struct MdBullet { pub id: String, - pub description: Vec, + pub description: Vec, } impl MdTypeListing { @@ -234,7 +287,7 @@ impl fmt::Display for MdTypeListing { #[derive(Debug)] pub(super) struct MdInterfaceFunc { pub id: String, - pub description: Vec, + pub description: Vec, pub parameters: Vec, pub results: Vec, pub parent: Option>, @@ -274,7 +327,7 @@ impl fmt::Display for MdInterfaceFunc { // * `argv` // `argv` has type... if !self.parameters.is_empty() { - f.write_str("\n**Parameters:**\n\n")?; + f.write_str("**Parameters:**\n\n")?; for param in &self.parameters { f.write_fmt(format_args!( "- {link} `{param_id}`\n\n", @@ -289,7 +342,7 @@ impl fmt::Display for MdInterfaceFunc { // Results: // * `error` // `error` has type `errno` - f.write_str("\n**Results:**\n\n")?; + f.write_str("**Results:**\n\n")?; for result in &self.results { f.write_fmt(format_args!( "- {link} `{res_id}`\n\n", diff --git a/proposals/filesystem/tools/witx/src/docs/mod.rs b/proposals/filesystem/tools/witx/src/docs/mod.rs index e2b9eab5e..ebf720416 100644 --- a/proposals/filesystem/tools/witx/src/docs/mod.rs +++ b/proposals/filesystem/tools/witx/src/docs/mod.rs @@ -86,7 +86,7 @@ impl ToMarkdown for NamedType { listing .as_type_listing_mut() .description - .push(self.docs.clone()); + .push(MdParagraph::new(&self.docs)); listing.as_type_listing_mut().elements.append(&mut elements); listing } @@ -96,9 +96,9 @@ impl ToMarkdown for NamedType { self.name.as_str(), parent, )); - sec.as_section_mut().description.extend_from_slice(&[ - self.docs.clone(), - format!("Alias to {}", n.name.as_str()), + sec.as_section_mut().description.append(&mut vec![ + MdParagraph::new(&self.docs), + MdParagraph::new(format!("Alias to {}", n.name.as_str())), ]); sec } @@ -143,7 +143,7 @@ macro_rules! impl_mdbullet { fn from(f: $from) -> Self { Self { id: f.name.as_str().to_owned(), - description: vec![f.docs.clone()], + description: vec![MdParagraph::new(&f.docs)], } } } @@ -217,7 +217,10 @@ impl ToMarkdown for Module { let desc = match import.variant { ModuleImportVariant::Memory => format!("* {}: Memory", import.name.as_str()), }; - imports.as_section_mut().description.push(desc); + imports + .as_section_mut() + .description + .push(MdParagraph::new(desc)); } sec.as_section_mut().elements.push(imports); let funcs = Rc::new(MdSection::new( @@ -239,7 +242,7 @@ impl ToMarkdown for InterfaceFunc { let func = Rc::new(MdInterfaceFunc::new(self.name.as_str(), parent)); func.as_interface_func_mut() .description - .push(self.docs.clone()); + .push(MdParagraph::new(&self.docs)); func.as_interface_func_mut() .parameters .extend(self.params.iter().map(MdBullet::from)); @@ -255,12 +258,12 @@ impl From<&InterfaceFuncParam> for MdBullet { Self { id: param.name.as_str().to_owned(), description: vec![ - format!( + MdParagraph::new(format!( "`{}` has type `{}`", param.name.as_str(), param.tref.type_name(), - ), - format!("{}", param.docs), + )), + MdParagraph::new(format!("{}", param.docs)), ], } } From 67a8288bedd1df2bc2956a2ad913e699a06a380f Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 00:05:23 +0100 Subject: [PATCH 0457/1772] Final iteration of the approach (hopefully) This approach is heavily inspired by `HostRef` and related present in `wasmtime` (see [wasmtime/crates/api/ref.rs]). In this new approach, instead of holding all possible type variants inside a statically-typed `enum`, I've decided to have a tiered structure where (from bottom/inner-most element to the top/outer-most element): * `Box` is any "content-box" holding for instance a Markdown element representing a section, `NamedType`, etc. * `MdNode` struct wrapping the "content-box" plus storing all children `MdNodes` (representing subsections, etc.), and a weak link to the parent `MdNode` (if any) * `MdNodeRef` struct wrapping `MdNode` inside an `Rc>`, and offering convenience methods to extract `dyn MdElement` directly from `MdNodeRef`, etc. Finally, `trait MdElement` represents the minimum interface required for any "content-box" to have in order to be able to interface with other generated Markdown nodes. [wasmtime/crates/api/ref.rs]: https://github.com/bytecodealliance/wasmtime/blob/master/crates/api/src/ref.rs --- proposals/clocks/tools/witx/src/docs/ast.rs | 415 +++++++++++++++ proposals/clocks/tools/witx/src/docs/md.rs | 544 ++++++++++---------- proposals/clocks/tools/witx/src/docs/mod.rs | 415 +-------------- 3 files changed, 694 insertions(+), 680 deletions(-) create mode 100644 proposals/clocks/tools/witx/src/docs/ast.rs diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs new file mode 100644 index 000000000..641673775 --- /dev/null +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -0,0 +1,415 @@ +use super::md::*; +use super::Documentation; +use crate::ast::*; +use crate::polyfill::*; +use crate::RepEquality; + +impl ToMarkdown for Document { + fn generate(&self, node: MdNodeRef) { + let types = node.new_child(MdSection::new("Types")); + for d in self.typenames() { + let child = types.new_child(MdNamedType::new(d.name.as_str(), &d.docs)); + d.generate(child.clone()); + } + + let modules = node.new_child(MdSection::new("Modules")); + for d in self.modules() { + let mut content = MdSection::new(d.name.as_str()); + content.id = Some(d.name.as_str().to_owned()); + let child = modules.new_child(content); + d.generate(child.clone()); + } + } +} + +impl ToMarkdown for TypeRef { + fn generate(&self, node: MdNodeRef) { + match self { + TypeRef::Value(v) => v.generate(node.clone()), + TypeRef::Name(n) => { + node.content_mut::().r#type = Some(MdType::Alias { + r#type: n.name.as_str().to_owned(), + }) + } + } + } +} + +impl ToMarkdown for NamedType { + fn generate(&self, node: MdNodeRef) { + self.tref.generate(node.clone()); + } +} + +impl ToMarkdown for Type { + fn generate(&self, node: MdNodeRef) { + match self { + Self::Enum(a) => a.generate(node.clone()), + Self::Int(a) => a.generate(node.clone()), + Self::Flags(a) => a.generate(node.clone()), + Self::Struct(a) => a.generate(node.clone()), + Self::Union(a) => a.generate(node.clone()), + Self::Handle(a) => a.generate(node.clone()), + Self::Array(a) => { + node.content_mut::().r#type = Some(MdType::Array { + r#type: a.type_name().to_owned(), + }) + } + Self::Pointer(a) => { + node.content_mut::().r#type = Some(MdType::Pointer { + r#type: a.type_name().to_owned(), + }) + } + Self::ConstPointer(a) => { + node.content_mut::().r#type = Some(MdType::ConstPointer { + r#type: a.type_name().to_owned(), + }) + } + Self::Builtin(a) => { + node.content_mut::().r#type = Some(MdType::Builtin { + repr: a.type_name().to_owned(), + }) + } + } + } +} + +impl ToMarkdown for EnumDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Variants")); + + for variant in &self.variants { + node.new_child(MdNamedType::new(variant.name.as_str(), &variant.docs)); + } + + node.content_mut::().r#type = Some(MdType::Enum { + repr: self.repr.type_name().to_owned(), + }); + } +} + +impl ToMarkdown for IntDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Consts")); + + for r#const in &self.consts { + let tt = MdNamedType::new(r#const.name.as_str(), &r#const.docs); + // TODO handle r#const.value + node.new_child(tt); + } + + node.content_mut::().r#type = Some(MdType::Int { + repr: self.repr.type_name().to_owned(), + }); + } +} + +impl ToMarkdown for FlagsDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Flags")); + + for flag in &self.flags { + node.new_child(MdNamedType::new(flag.name.as_str(), &flag.docs)); + } + + node.content_mut::().r#type = Some(MdType::Flags { + repr: self.repr.type_name().to_owned(), + }); + } +} + +impl ToMarkdown for StructDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Struct members")); + + for member in &self.members { + let n = node.new_child(MdNamedType::new(member.name.as_str(), &member.docs)); + member.tref.generate(n.clone()); + } + + node.content_mut::().r#type = Some(MdType::Struct); + } +} + +impl ToMarkdown for UnionDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Union variants")); + + for variant in &self.variants { + let n = node.new_child(MdNamedType::new(variant.name.as_str(), &variant.docs)); + variant.tref.generate(n.clone()); + } + + node.content_mut::().r#type = Some(MdType::Union); + } +} + +impl ToMarkdown for HandleDatatype { + fn generate(&self, node: MdNodeRef) { + // TODO this needs more work + node.new_child(MdSection::new("Supertypes")); + node.content_mut::().r#type = Some(MdType::Handle); + } +} + +impl ToMarkdown for Module { + fn generate(&self, node: MdNodeRef) { + let imports = node.new_child(MdSection::new("Imports")); + for import in self.imports() { + let child = imports.new_child(MdSection::default()); + import.generate(child.clone()); + } + + let funcs = node.new_child(MdSection::new("Functions")); + for func in self.funcs() { + let child = funcs.new_child(MdFunc::new(func.name.as_str(), &func.docs)); + func.generate(child.clone()); + } + } +} + +impl ToMarkdown for ModuleImport { + fn generate(&self, node: MdNodeRef) { + match self.variant { + ModuleImportVariant::Memory => { + node.content_mut::().title = "Memory".to_owned(); + } + } + } +} + +impl ToMarkdown for InterfaceFunc { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Params")); + for param in &self.params { + let child = node.new_child(MdNamedType::new(param.name.as_str(), param.name.as_str())); + param.generate(child.clone()); + // TODO should this be expanded recursively instead of using flattened type names? + node.content_mut::() + .inputs + .push((param.name.as_str().to_owned(), param.tref.type_name())); + } + + node.new_child(MdSection::new("Results")); + for result in &self.results { + let child = + node.new_child(MdNamedType::new(result.name.as_str(), result.name.as_str())); + result.generate(child.clone()); + // TODO should this be expanded recursively instead of using flattened type names? + node.content_mut::() + .outputs + .push(result.tref.type_name()); + } + } +} + +impl ToMarkdown for InterfaceFuncParam { + fn generate(&self, node: MdNodeRef) { + self.tref.generate(node.clone()); + node.content_mut::().docs = self.docs.clone(); + } +} + +impl BuiltinType { + pub fn type_name(&self) -> &'static str { + match self { + BuiltinType::String => "string", + BuiltinType::Char8 => "char8", + BuiltinType::USize => "usize", + BuiltinType::U8 => "u8", + BuiltinType::U16 => "u16", + BuiltinType::U32 => "u32", + BuiltinType::U64 => "u64", + BuiltinType::S8 => "s8", + BuiltinType::S16 => "s16", + BuiltinType::S32 => "s32", + BuiltinType::S64 => "s64", + BuiltinType::F32 => "f32", + BuiltinType::F64 => "f64", + } + } +} + +impl TypeRef { + pub fn type_name(&self) -> String { + match self { + TypeRef::Name(n) => n.name.as_str().to_string(), + TypeRef::Value(ref v) => match &**v { + Type::Array(a) => format!("Array<{}>", a.type_name()), + Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), + Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), + Type::Builtin(b) => b.type_name().to_string(), + Type::Enum { .. } + | Type::Int { .. } + | Type::Flags { .. } + | Type::Struct { .. } + | Type::Union { .. } + | Type::Handle { .. } => { + unimplemented!("type_name of anonymous compound datatypes") + } + }, + } + } +} + +impl IntRepr { + fn type_name(&self) -> &'static str { + match self { + IntRepr::U8 => "u8", + IntRepr::U16 => "u16", + IntRepr::U32 => "u32", + IntRepr::U64 => "u64", + } + } +} + +// TODO +// Generate Markdown tree for the polyfill +impl Documentation for Polyfill { + fn to_md(&self) -> String { + let module_docs = self + .modules + .iter() + .map(|m| m.to_md()) + .collect::>() + .join("\n"); + let type_docs = self + .type_polyfills() + .iter() + .filter_map(|t| { + if t.repeq() == RepEquality::Eq { + None + } else { + Some(t.to_md()) + } + }) + .collect::>() + .join("\n"); + format!( + "# Modules\n{}\n# Type Conversions\n{}\n", + module_docs, type_docs + ) + } +} + +impl Documentation for ModulePolyfill { + fn to_md(&self) -> String { + format!( + "## `{}` in terms of `{}`\n{}", + self.new.name.as_str(), + self.old.name.as_str(), + self.funcs + .iter() + .map(|f| f.to_md()) + .collect::>() + .join("\n"), + ) + } +} + +impl Documentation for FuncPolyfill { + fn to_md(&self) -> String { + if self.full_compat() { + format!("* `{}`: full compatibility", self.new.name.as_str()) + } else { + let name = if self.new.name != self.old.name { + format!( + "* `{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("* `{}`", self.new.name.as_str()) + }; + let mut contents = Vec::new(); + for p in self.mapped_params.iter() { + contents.push(if !p.full_compat() { + format!("param {}", p.to_md()) + } else { + format!("param `{}`: compatible", p.new.name.as_str()) + }) + } + for u in self.unknown_params.iter() { + contents.push(format!( + "{} param `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + for r in self.mapped_results.iter() { + contents.push(if !r.full_compat() { + format!("result {}", r.to_md()) + } else { + format!("result `{}`: compatible", r.new.name.as_str()) + }) + } + for u in self.unknown_results.iter() { + contents.push(format!( + "{} result `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + let contents = if contents.is_empty() { + String::new() + } else { + format!(":\n - {}", contents.join("\n - ")) + }; + format!("{}{}", name, contents) + } + } +} + +impl Documentation for ParamPolyfill { + fn to_md(&self) -> String { + let name = if self.new.name != self.old.name { + format!( + "`{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("`{}`", self.new.name.as_str()) + }; + let repr = match self.repeq() { + RepEquality::Eq => "compatible types".to_string(), + RepEquality::Superset => format!( + "`{}` is superset-compatible with `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + RepEquality::NotEq => format!( + "`{}` is incompatible with new `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + }; + format!("{}: {}", name, repr) + } +} + +impl Documentation for TypePolyfill { + fn to_md(&self) -> String { + fn repeq_name(r: RepEquality) -> &'static str { + match r { + RepEquality::Eq => ": compatible", + RepEquality::Superset => ": superset", + RepEquality::NotEq => "", + } + } + match self { + TypePolyfill::OldToNew(o, n) => format!( + "* old `{}` => new `{}`{}", + o.type_name(), + n.type_name(), + repeq_name(self.repeq()) + ), + TypePolyfill::NewToOld(n, o) => format!( + "* new `{}` => old `{}`{}", + n.type_name(), + o.type_name(), + repeq_name(self.repeq()) + ), + } + } +} diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index 52ea968a8..58fbbb16a 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -1,207 +1,217 @@ use std::{ - cell::{Ref, RefCell, RefMut}, + any::Any, + cell::{self, RefCell}, fmt, rc::{Rc, Weak}, }; -fn walk_parents(start: &Weak, cb: &mut impl FnMut(Rc)) { - let mut parent = if let Some(parent) = start.upgrade() { - cb(parent.clone()); - parent - } else { - return; - }; +pub(super) trait ToMarkdown { + fn generate(&self, node: MdNodeRef); +} - while let Some(p) = parent.parent() { - cb(p.clone()); - parent = p; - } +pub(super) trait MdElement: fmt::Debug + 'static { + fn id(&self) -> Option<&str>; + fn as_any(&self) -> &dyn Any; + fn as_any_mut(&mut self) -> &mut dyn Any; + fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result; } -fn gen_link>(id: S) -> String { - format!("", id = id.as_ref()) +#[derive(Debug)] +struct MdNode { + content: Box, + parent: Option>>, + children: Vec, } -fn parse_links>(s: S) -> String { - let to_parse = s.as_ref(); - let mut parsed = String::with_capacity(to_parse.len()); - let mut temp = String::with_capacity(to_parse.len()); - let mut is_link = false; - let mut eaten = None; - for ch in to_parse.chars() { - match (ch, is_link) { - ('`', false) => { - // Found the beginning of a link! - is_link = true; - } - ('`', true) => { - // Reached the end, expand into a link! - // TODO - // Before committing to pasting the link in, - // first verify that it actually exists. - let expanded = format!("[`{}`](#{})", temp, temp); - parsed.push_str(&expanded); - temp.drain(..); - is_link = false; - } - (':', true) => { - if let Some(_) = eaten { - // Swap for '.' - temp.push('.'); - eaten = None; - } else { - eaten = Some(':'); - } - } - (ch, false) => parsed.push(ch), - (ch, true) => temp.push(ch), +impl MdNode { + fn new(item: T) -> Self { + Self { + content: Box::new(item), + parent: None, + children: vec![], } } - parsed } -#[derive(Debug)] -pub(super) enum MdElement { - Section(RefCell), - TypeListing(RefCell), - InterfaceFunc(RefCell), +fn walk_parents(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { + if let Some(parent) = parent.and_then(|x| x.upgrade()) { + cb(parent.clone().into()); + walk_parents(parent.borrow().parent.as_ref(), cb) + } } -impl MdElement { - #[allow(dead_code)] - pub(super) fn as_section(&self) -> Ref { - match self { - Self::Section(t) => t.borrow(), - _ => panic!("not a MdSection"), +impl fmt::Display for MdNode { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut parents = Vec::new(); + walk_parents(self.parent.as_ref(), &mut |parent| { + parents.push(parent); + }); + + MdElement::fmt(&*self.content, f, parents)?; + + for child in &self.children { + child.fmt(f)?; } + + Ok(()) } +} - pub(super) fn as_section_mut(&self) -> RefMut { - match self { - Self::Section(t) => t.borrow_mut(), - _ => panic!("not a MdSection"), - } +#[derive(Debug)] +pub(super) struct MdNodeRef(Rc>); + +impl MdNodeRef { + pub fn new(item: T) -> Self { + Self(Rc::new(RefCell::new(MdNode::new(item)))) } - #[allow(dead_code)] - pub(super) fn as_type_listing(&self) -> Ref { - match self { - Self::TypeListing(t) => t.borrow(), - _ => panic!("not a MdTypeListing"), - } + pub fn new_child(&self, item: T) -> Self { + let mut child_node = MdNode::new(item); + child_node.parent = Some(Rc::downgrade(&self.0)); + let child_ref = Self(Rc::new(RefCell::new(child_node))); + self.0.borrow_mut().children.push(child_ref.clone()); + child_ref } - pub(super) fn as_type_listing_mut(&self) -> RefMut { - match self { - Self::TypeListing(t) => t.borrow_mut(), - _ => panic!("not a MdTypeListing"), - } + fn borrow(&self) -> cell::Ref { + self.0.borrow() } - #[allow(dead_code)] - pub(super) fn as_interface_func(&self) -> Ref { - match self { - Self::InterfaceFunc(t) => t.borrow(), - _ => panic!("not a MdInterfaceFunc"), - } + fn borrow_mut(&self) -> cell::RefMut { + self.0.borrow_mut() } - pub(super) fn as_interface_func_mut(&self) -> RefMut { - match self { - Self::InterfaceFunc(t) => t.borrow_mut(), - _ => panic!("not a MdInterfaceFunc"), - } + pub fn content_ref(&self) -> cell::Ref { + cell::Ref::map(self.borrow(), |b| { + let r = b.content.as_any(); + r.downcast_ref::().expect("reference is not T type") + }) } - pub(super) fn parent(&self) -> Option> { - match self { - Self::Section(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), - Self::TypeListing(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), - Self::InterfaceFunc(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), + pub fn content_mut(&self) -> cell::RefMut { + cell::RefMut::map(self.borrow_mut(), |b| { + let r = b.content.as_any_mut(); + r.downcast_mut::().expect("reference is not T type") + }) + } + + pub fn get_content(&self) -> Option> { + if self.borrow().content.as_any().is::() { + Some(self.content_ref::()) + } else { + None } } -} -impl fmt::Display for MdElement { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Section(t) => t.borrow().fmt(f), - Self::TypeListing(t) => t.borrow().fmt(f), - Self::InterfaceFunc(t) => t.borrow().fmt(f), + #[allow(unused)] + pub fn get_content_mut(&self) -> Option> { + if self.borrow_mut().content.as_any().is::() { + Some(self.content_mut::()) + } else { + None } } } -#[derive(Debug)] -pub(super) struct MdSection { - pub id: String, - pub title: String, - pub description: Vec, - pub elements: Vec>, - pub parent: Option>, +impl Clone for MdNodeRef { + fn clone(&self) -> Self { + Self(self.0.clone()) + } } -#[derive(Debug)] -pub(super) struct MdParagraph(String); - -impl MdParagraph { - pub fn new>(s: S) -> Self { - Self(s.as_ref().to_owned()) +impl From>> for MdNodeRef { + fn from(node: Rc>) -> Self { + Self(node) } } -impl fmt::Display for MdParagraph { +impl fmt::Display for MdNodeRef { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - writeln!(f, "{}", parse_links(&self.0)) + self.borrow().fmt(f) + } +} + +#[derive(Debug, Default)] +pub(super) struct MdRoot; + +impl MdElement for MdRoot { + fn id(&self) -> Option<&str> { + None + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn fmt(&self, _f: &mut fmt::Formatter, _parents: Vec) -> fmt::Result { + Ok(()) } } +#[derive(Debug, Default)] +pub(super) struct MdSection { + pub id: Option, + pub title: String, +} + impl MdSection { - pub fn new>(id: S, title: S, parent: Option>) -> MdElement { - MdElement::Section(RefCell::new(Self { - id: id.as_ref().to_owned(), + pub fn new>(title: S) -> Self { + Self { + id: None, title: title.as_ref().to_owned(), - description: vec![], - elements: vec![], - parent, - })) + } } } -impl fmt::Display for MdSection { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut heading = "#".to_owned(); - if let Some(parent) = self.parent.as_ref() { - walk_parents(parent, &mut |_| { - heading += "#"; - }); - } - f.write_fmt(format_args!( - "{heading} {link} {title}\n", - heading = heading, - link = gen_link(&self.id), - title = &self.title - ))?; - for para in &self.description { - f.write_fmt(format_args!("{}\n", para))?; - } - for el in &self.elements { - f.write_fmt(format_args!("{}\n", el))?; +impl MdElement for MdSection { + fn id(&self) -> Option<&str> { + self.id.as_ref().map(|s| s.as_str()) + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { + let header = "#".repeat(parents.len()); + f.write_fmt(format_args!("{} ", header))?; + + if let Some(id) = &self.id { + f.write_fmt(format_args!( + " ", + id = id + ))?; } - Ok(()) + + writeln!(f, "{}", self.title) } } #[derive(Debug)] -pub(super) struct MdTypeListing { - pub id: String, - pub r#type: MdType, - pub description: Vec, - pub elements: Vec, - pub parent: Option>, +pub(super) struct MdNamedType { + pub name: String, + pub docs: String, + pub r#type: Option, +} + +impl MdNamedType { + pub fn new, S2: AsRef>(name: S1, docs: S2) -> Self { + Self { + name: name.as_ref().to_owned(), + docs: docs.as_ref().to_owned(), + r#type: None, + } + } } -#[allow(dead_code)] #[derive(Debug)] pub(super) enum MdType { Enum { repr: String }, @@ -209,150 +219,142 @@ pub(super) enum MdType { Flags { repr: String }, Struct, Union, - Handle, Array { r#type: String }, - Pointer { to: String }, - ConstPointer { to: String }, - Builtin { r#type: String }, + Pointer { r#type: String }, + ConstPointer { r#type: String }, + Builtin { repr: String }, + Handle, + Alias { r#type: String }, } -#[derive(Debug)] -pub(super) struct MdBullet { - pub id: String, - pub description: Vec, -} +impl fmt::Display for MdType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Enum { repr } => f.write_fmt(format_args!(": Enum(`{}`)", repr))?, + Self::Int { repr } => f.write_fmt(format_args!(": Int(`{}`)", repr))?, + Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, + Self::Struct => f.write_fmt(format_args!(": Struct"))?, + Self::Union => f.write_fmt(format_args!(": Union"))?, + Self::Array { r#type } => f.write_fmt(format_args!(": `Array<{}>`", r#type))?, + Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, + Self::ConstPointer { r#type } => { + f.write_fmt(format_args!(": `ConstPointer<{}>`", r#type))? + } + Self::Builtin { repr } => f.write_fmt(format_args!(": `{}`", repr))?, + Self::Handle => {} + Self::Alias { r#type } => f.write_fmt(format_args!(": `{}`", r#type))?, + }; -impl MdTypeListing { - pub fn new(id: &str, r#type: MdType, parent: Option>) -> MdElement { - MdElement::TypeListing(RefCell::new(Self { - id: id.to_owned(), - r#type, - description: vec![], - elements: vec![], - parent, - })) + Ok(()) } } -impl fmt::Display for MdTypeListing { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut heading = "#".to_owned(); - if let Some(parent) = self.parent.as_ref() { - walk_parents(parent, &mut |_| { - heading += "#"; - }); - } - // ### `errno` +impl MdElement for MdNamedType { + fn id(&self) -> Option<&str> { + Some(&self.name) + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { + // Firstly, check if our parent is an MdSection or another MdNamedType in which + // case, we're already nesting and should be represented as bullets + let (header, link) = if let Some(p) = parents.first() { + if let Some(_sec) = p.get_content::() { + ("#".repeat(parents.len()), self.name.clone()) + } else if let Some(tt) = p.get_content::() { + ("-".to_owned(), format!("{}.{}", tt.name, self.name)) + } else if let Some(f) = p.get_content::() { + ("-".to_owned(), format!("{}.{}", f.name, self.name)) + } else { + ("#".to_owned(), self.name.clone()) + } + } else { + ("#".to_owned(), self.name.clone()) + }; + f.write_fmt(format_args!( - "{heading} {link} `{id}`\n", - heading = heading, - link = gen_link(&self.id), - id = &self.id + "{header} `{name}`", + header = header, + link = link, + name = self.name, ))?; - // Error codes returned by function... - for para in &self.description { - f.write_fmt(format_args!("{}\n", para))?; - } - // Enum represented by `u16` - // Variants: - let type_specific = match &self.r#type { - MdType::Enum { repr } => format!("Enum represented by `{}`\n\n**Variants:**\n", repr), - MdType::Int { repr } => format!("Int represented by `{}`\n\n**Const:**\n", repr), - MdType::Flags { repr } => format!("Flags represented by `{}`\n\n**Flags:**\n", repr), - MdType::Struct => "\n**Struct members:**\n".to_owned(), - MdType::Union => "\n**Union variants:**\n".to_owned(), - MdType::Handle => "\n**Supertypes:**\n".to_owned(), - MdType::Array { r#type } => format!("Array of `{}`", r#type), - MdType::Pointer { to } => format!("Pointer to `{}`", to), - MdType::ConstPointer { to } => format!("Const pointer to `{}`", to), - MdType::Builtin { r#type } => format!("Builtin type `{}`", r#type), - }; - f.write_str(&type_specific)?; - // - `success` - // No error occurred. System call completed successfully. - for el in &self.elements { - f.write_fmt(format_args!( - "- {link} `{el_id}`\n\n", - link = gen_link(format!("{}.{}", self.id, el.id)), - el_id = el.id - ))?; - for desc in &el.description { - f.write_fmt(format_args!("\t{}\n", desc))?; - } + + if let Some(tt) = &self.r#type { + f.write_fmt(format_args!("{}", tt))?; } - Ok(()) + + writeln!(f, "\n{}", self.docs) } } #[derive(Debug)] -pub(super) struct MdInterfaceFunc { - pub id: String, - pub description: Vec, - pub parameters: Vec, - pub results: Vec, - pub parent: Option>, +pub(super) struct MdFunc { + pub name: String, + pub inputs: Vec<(String, String)>, + pub outputs: Vec, + pub docs: String, } -impl MdInterfaceFunc { - pub fn new(id: &str, parent: Option>) -> MdElement { - MdElement::InterfaceFunc(RefCell::new(Self { - id: id.to_owned(), - description: vec![], - parameters: vec![], - results: vec![], - parent, - })) +impl MdFunc { + pub fn new, S2: AsRef>(name: S1, docs: S2) -> Self { + Self { + name: name.as_ref().to_owned(), + inputs: vec![], + outputs: vec![], + docs: docs.as_ref().to_owned(), + } } } -impl fmt::Display for MdInterfaceFunc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut heading = "#".to_owned(); - if let Some(parent) = self.parent.as_ref() { - walk_parents(parent, &mut |_| { - heading += "#"; - }); - } - // ### `args_get` +impl MdElement for MdFunc { + fn id(&self) -> Option<&str> { + Some(&self.name) + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { + // Expand header + let header = "#".repeat(parents.len()); + // Expand inputs + let inputs = self + .inputs + .iter() + .map(|(name, r#type)| format!("{}: `{}`", name, r#type)) + .collect::>() + .join(", "); + // Expand outputs + let outputs: Vec<_> = self + .outputs + .iter() + .map(|r#type| format!("`{}`", r#type)) + .collect(); + let outputs = match outputs.len() { + 0 => "".to_owned(), + 1 => format!(" -> {}", outputs[0]), + _ => format!(" -> ({})", outputs.join(", ")), + }; f.write_fmt(format_args!( - "{heading} `{id}`\n\n", - heading = heading, - id = self.id + "{header} Fn {name}({inputs}){outputs}", + header = header, + name = self.name, + inputs = inputs, + outputs = outputs, ))?; - // Read command-line argument data... - for desc in &self.description { - f.write_fmt(format_args!("{}\n", desc))?; - } - // Parameters: - // * `argv` - // `argv` has type... - if !self.parameters.is_empty() { - f.write_str("**Parameters:**\n\n")?; - for param in &self.parameters { - f.write_fmt(format_args!( - "- {link} `{param_id}`\n\n", - link = gen_link(format!("{}.{}", self.id, param.id)), - param_id = param.id - ))?; - for desc in ¶m.description { - f.write_fmt(format_args!("\t{}\n", desc))?; - } - } - } - // Results: - // * `error` - // `error` has type `errno` - f.write_str("**Results:**\n\n")?; - for result in &self.results { - f.write_fmt(format_args!( - "- {link} `{res_id}`\n\n", - link = gen_link(format!("{}.{}", self.id, result.id)), - res_id = result.id - ))?; - for desc in &result.description { - f.write_fmt(format_args!("\t{}\n", desc))?; - } - } - Ok(()) + + writeln!(f, "\n{}", self.docs) } } diff --git a/proposals/clocks/tools/witx/src/docs/mod.rs b/proposals/clocks/tools/witx/src/docs/mod.rs index ebf720416..e0b962ce2 100644 --- a/proposals/clocks/tools/witx/src/docs/mod.rs +++ b/proposals/clocks/tools/witx/src/docs/mod.rs @@ -1,421 +1,18 @@ +mod ast; mod md; -use crate::ast::*; -use crate::polyfill::*; -use crate::RepEquality; -use md::*; -use std::rc::{Rc, Weak}; +use crate::ast::Document; +use md::{MdNodeRef, MdRoot, ToMarkdown}; pub trait Documentation { fn to_md(&self) -> String; } -trait ToMarkdown { - fn gen(&self, _parent: Option>) -> Rc; -} - impl Documentation for Document { fn to_md(&self) -> String { - format!("{}", self.gen(None)) - } -} - -impl ToMarkdown for Document { - fn gen(&self, parent: Option>) -> Rc { - let doc = Rc::new(MdSection::new("root", "Root", parent)); - let types = Rc::new(MdSection::new("types", "Types", Some(Rc::downgrade(&doc)))); - for typename in self.typenames() { - types - .as_section_mut() - .elements - .push(typename.gen(Some(Rc::downgrade(&types)))); - } - let modules = Rc::new(MdSection::new( - "modules", - "Modules", - Some(Rc::downgrade(&doc)), - )); - for module in self.modules() { - modules - .as_section_mut() - .elements - .push(module.gen(Some(Rc::downgrade(&modules)))); - } - doc.as_section_mut() - .elements - .extend_from_slice(&[types, modules]); - doc - } -} - -impl BuiltinType { - pub fn type_name(&self) -> &'static str { - match self { - BuiltinType::String => "string", - BuiltinType::Char8 => "char8", - BuiltinType::USize => "usize", - BuiltinType::U8 => "u8", - BuiltinType::U16 => "u16", - BuiltinType::U32 => "u32", - BuiltinType::U64 => "u64", - BuiltinType::S8 => "s8", - BuiltinType::S16 => "s16", - BuiltinType::S32 => "s32", - BuiltinType::S64 => "s64", - BuiltinType::F32 => "f32", - BuiltinType::F64 => "f64", - } - } -} - -impl ToMarkdown for NamedType { - fn gen(&self, parent: Option>) -> Rc { - match &self.tref { - TypeRef::Value(v) => { - let md_type = MdType::from(&**v); - let mut elements: Vec<_> = match &**v { - Type::Enum(a) => a.variants.iter().map(MdBullet::from).collect(), - Type::Int(a) => a.consts.iter().map(MdBullet::from).collect(), - Type::Flags(a) => a.flags.iter().map(MdBullet::from).collect(), - Type::Struct(a) => a.members.iter().map(MdBullet::from).collect(), - Type::Union(a) => a.variants.iter().map(MdBullet::from).collect(), - Type::Handle(a) => a.supertypes.iter().map(MdBullet::from).collect(), - _ => vec![], - }; - let listing = Rc::new(MdTypeListing::new(self.name.as_str(), md_type, parent)); - listing - .as_type_listing_mut() - .description - .push(MdParagraph::new(&self.docs)); - listing.as_type_listing_mut().elements.append(&mut elements); - listing - } - TypeRef::Name(n) => { - let sec = Rc::new(MdSection::new( - self.name.as_str(), - self.name.as_str(), - parent, - )); - sec.as_section_mut().description.append(&mut vec![ - MdParagraph::new(&self.docs), - MdParagraph::new(format!("Alias to {}", n.name.as_str())), - ]); - sec - } - } - } -} - -impl From<&Type> for MdType { - fn from(r#type: &Type) -> Self { - match r#type { - Type::Enum(a) => Self::Enum { - repr: a.repr.type_name().to_owned(), - }, - Type::Int(a) => Self::Int { - repr: a.repr.type_name().to_owned(), - }, - Type::Flags(a) => Self::Flags { - repr: a.repr.type_name().to_owned(), - }, - Type::Struct(_) => Self::Struct, - Type::Union(_) => Self::Union, - Type::Handle(_) => Self::Handle, - Type::Array(a) => Self::Array { - r#type: a.type_name().to_owned(), - }, - Type::Pointer(a) => Self::Pointer { - to: a.type_name().to_owned(), - }, - Type::ConstPointer(a) => Self::ConstPointer { - to: a.type_name().to_owned(), - }, - Type::Builtin(a) => Self::Builtin { - r#type: a.type_name().to_owned(), - }, - } - } -} - -macro_rules! impl_mdbullet { - ($from:ty) => { - impl From<$from> for MdBullet { - fn from(f: $from) -> Self { - Self { - id: f.name.as_str().to_owned(), - description: vec![MdParagraph::new(&f.docs)], - } - } - } - }; -} - -impl_mdbullet!(&EnumVariant); -impl_mdbullet!(&IntConst); -impl_mdbullet!(&FlagsMember); -impl_mdbullet!(&StructMember); -impl_mdbullet!(&UnionVariant); - -impl From<&TypeRef> for MdBullet { - fn from(t: &TypeRef) -> Self { - Self { - id: t.type_name().to_owned(), - description: vec![], - } - } -} - -impl TypeRef { - pub fn type_name(&self) -> String { - match self { - TypeRef::Name(n) => n.name.as_str().to_string(), - TypeRef::Value(ref v) => match &**v { - Type::Array(a) => format!("Array<{}>", a.type_name()), - Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), - Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), - Type::Builtin(b) => b.type_name().to_string(), - Type::Enum { .. } - | Type::Int { .. } - | Type::Flags { .. } - | Type::Struct { .. } - | Type::Union { .. } - | Type::Handle { .. } => { - unimplemented!("type_name of anonymous compound datatypes") - } - }, - } - } -} - -impl IntRepr { - fn type_name(&self) -> &'static str { - match self { - IntRepr::U8 => "u8", - IntRepr::U16 => "u16", - IntRepr::U32 => "u32", - IntRepr::U64 => "u64", - } - } -} - -impl ToMarkdown for Module { - fn gen(&self, parent: Option>) -> Rc { - let sec = Rc::new(MdSection::new( - self.name.as_str(), - &format!("`{}`", self.name.as_str()), - parent, - )); - let imports = Rc::new(MdSection::new( - "imports", - "Imports", - Some(Rc::downgrade(&sec)), - )); - // TODO - // This should probably be done using something more specific - // than a generic MdSection - for import in self.imports() { - let desc = match import.variant { - ModuleImportVariant::Memory => format!("* {}: Memory", import.name.as_str()), - }; - imports - .as_section_mut() - .description - .push(MdParagraph::new(desc)); - } - sec.as_section_mut().elements.push(imports); - let funcs = Rc::new(MdSection::new( - "functions", - "Functions", - Some(Rc::downgrade(&sec)), - )); - funcs - .as_section_mut() - .elements - .extend(self.funcs().map(|f| f.gen(Some(Rc::downgrade(&funcs))))); - sec.as_section_mut().elements.push(funcs); - sec - } -} - -impl ToMarkdown for InterfaceFunc { - fn gen(&self, parent: Option>) -> Rc { - let func = Rc::new(MdInterfaceFunc::new(self.name.as_str(), parent)); - func.as_interface_func_mut() - .description - .push(MdParagraph::new(&self.docs)); - func.as_interface_func_mut() - .parameters - .extend(self.params.iter().map(MdBullet::from)); - func.as_interface_func_mut() - .results - .extend(self.results.iter().map(MdBullet::from)); - func - } -} - -impl From<&InterfaceFuncParam> for MdBullet { - fn from(param: &InterfaceFuncParam) -> Self { - Self { - id: param.name.as_str().to_owned(), - description: vec![ - MdParagraph::new(format!( - "`{}` has type `{}`", - param.name.as_str(), - param.tref.type_name(), - )), - MdParagraph::new(format!("{}", param.docs)), - ], - } - } -} - -// TODO -// Implement ToMarkdown for Polyfill -impl Documentation for Polyfill { - fn to_md(&self) -> String { - let module_docs = self - .modules - .iter() - .map(|m| m.to_md()) - .collect::>() - .join("\n"); - let type_docs = self - .type_polyfills() - .iter() - .filter_map(|t| { - if t.repeq() == RepEquality::Eq { - None - } else { - Some(t.to_md()) - } - }) - .collect::>() - .join("\n"); - format!( - "# Modules\n{}\n# Type Conversions\n{}\n", - module_docs, type_docs - ) + let root = MdNodeRef::new(MdRoot::default()); + self.generate(root.clone()); + format!("{}", root) } } -impl Documentation for ModulePolyfill { - fn to_md(&self) -> String { - format!( - "## `{}` in terms of `{}`\n{}", - self.new.name.as_str(), - self.old.name.as_str(), - self.funcs - .iter() - .map(|f| f.to_md()) - .collect::>() - .join("\n"), - ) - } -} - -impl Documentation for FuncPolyfill { - fn to_md(&self) -> String { - if self.full_compat() { - format!("* `{}`: full compatibility", self.new.name.as_str()) - } else { - let name = if self.new.name != self.old.name { - format!( - "* `{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("* `{}`", self.new.name.as_str()) - }; - let mut contents = Vec::new(); - for p in self.mapped_params.iter() { - contents.push(if !p.full_compat() { - format!("param {}", p.to_md()) - } else { - format!("param `{}`: compatible", p.new.name.as_str()) - }) - } - for u in self.unknown_params.iter() { - contents.push(format!( - "{} param `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - for r in self.mapped_results.iter() { - contents.push(if !r.full_compat() { - format!("result {}", r.to_md()) - } else { - format!("result `{}`: compatible", r.new.name.as_str()) - }) - } - for u in self.unknown_results.iter() { - contents.push(format!( - "{} result `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - let contents = if contents.is_empty() { - String::new() - } else { - format!(":\n - {}", contents.join("\n - ")) - }; - format!("{}{}", name, contents) - } - } -} - -impl Documentation for ParamPolyfill { - fn to_md(&self) -> String { - let name = if self.new.name != self.old.name { - format!( - "`{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("`{}`", self.new.name.as_str()) - }; - let repr = match self.repeq() { - RepEquality::Eq => "compatible types".to_string(), - RepEquality::Superset => format!( - "`{}` is superset-compatible with `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - RepEquality::NotEq => format!( - "`{}` is incompatible with new `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - }; - format!("{}: {}", name, repr) - } -} - -impl Documentation for TypePolyfill { - fn to_md(&self) -> String { - fn repeq_name(r: RepEquality) -> &'static str { - match r { - RepEquality::Eq => ": compatible", - RepEquality::Superset => ": superset", - RepEquality::NotEq => "", - } - } - match self { - TypePolyfill::OldToNew(o, n) => format!( - "* old `{}` => new `{}`{}", - o.type_name(), - n.type_name(), - repeq_name(self.repeq()) - ), - TypePolyfill::NewToOld(n, o) => format!( - "* new `{}` => old `{}`{}", - n.type_name(), - o.type_name(), - repeq_name(self.repeq()) - ), - } - } -} From 413f6bbdb1b42bb02256c6db191ce121e901aa4e Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 00:05:23 +0100 Subject: [PATCH 0458/1772] Final iteration of the approach (hopefully) This approach is heavily inspired by `HostRef` and related present in `wasmtime` (see [wasmtime/crates/api/ref.rs]). In this new approach, instead of holding all possible type variants inside a statically-typed `enum`, I've decided to have a tiered structure where (from bottom/inner-most element to the top/outer-most element): * `Box` is any "content-box" holding for instance a Markdown element representing a section, `NamedType`, etc. * `MdNode` struct wrapping the "content-box" plus storing all children `MdNodes` (representing subsections, etc.), and a weak link to the parent `MdNode` (if any) * `MdNodeRef` struct wrapping `MdNode` inside an `Rc>`, and offering convenience methods to extract `dyn MdElement` directly from `MdNodeRef`, etc. Finally, `trait MdElement` represents the minimum interface required for any "content-box" to have in order to be able to interface with other generated Markdown nodes. [wasmtime/crates/api/ref.rs]: https://github.com/bytecodealliance/wasmtime/blob/master/crates/api/src/ref.rs --- proposals/random/tools/witx/src/docs/ast.rs | 415 +++++++++++++++ proposals/random/tools/witx/src/docs/md.rs | 544 ++++++++++---------- proposals/random/tools/witx/src/docs/mod.rs | 415 +-------------- 3 files changed, 694 insertions(+), 680 deletions(-) create mode 100644 proposals/random/tools/witx/src/docs/ast.rs diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs new file mode 100644 index 000000000..641673775 --- /dev/null +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -0,0 +1,415 @@ +use super::md::*; +use super::Documentation; +use crate::ast::*; +use crate::polyfill::*; +use crate::RepEquality; + +impl ToMarkdown for Document { + fn generate(&self, node: MdNodeRef) { + let types = node.new_child(MdSection::new("Types")); + for d in self.typenames() { + let child = types.new_child(MdNamedType::new(d.name.as_str(), &d.docs)); + d.generate(child.clone()); + } + + let modules = node.new_child(MdSection::new("Modules")); + for d in self.modules() { + let mut content = MdSection::new(d.name.as_str()); + content.id = Some(d.name.as_str().to_owned()); + let child = modules.new_child(content); + d.generate(child.clone()); + } + } +} + +impl ToMarkdown for TypeRef { + fn generate(&self, node: MdNodeRef) { + match self { + TypeRef::Value(v) => v.generate(node.clone()), + TypeRef::Name(n) => { + node.content_mut::().r#type = Some(MdType::Alias { + r#type: n.name.as_str().to_owned(), + }) + } + } + } +} + +impl ToMarkdown for NamedType { + fn generate(&self, node: MdNodeRef) { + self.tref.generate(node.clone()); + } +} + +impl ToMarkdown for Type { + fn generate(&self, node: MdNodeRef) { + match self { + Self::Enum(a) => a.generate(node.clone()), + Self::Int(a) => a.generate(node.clone()), + Self::Flags(a) => a.generate(node.clone()), + Self::Struct(a) => a.generate(node.clone()), + Self::Union(a) => a.generate(node.clone()), + Self::Handle(a) => a.generate(node.clone()), + Self::Array(a) => { + node.content_mut::().r#type = Some(MdType::Array { + r#type: a.type_name().to_owned(), + }) + } + Self::Pointer(a) => { + node.content_mut::().r#type = Some(MdType::Pointer { + r#type: a.type_name().to_owned(), + }) + } + Self::ConstPointer(a) => { + node.content_mut::().r#type = Some(MdType::ConstPointer { + r#type: a.type_name().to_owned(), + }) + } + Self::Builtin(a) => { + node.content_mut::().r#type = Some(MdType::Builtin { + repr: a.type_name().to_owned(), + }) + } + } + } +} + +impl ToMarkdown for EnumDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Variants")); + + for variant in &self.variants { + node.new_child(MdNamedType::new(variant.name.as_str(), &variant.docs)); + } + + node.content_mut::().r#type = Some(MdType::Enum { + repr: self.repr.type_name().to_owned(), + }); + } +} + +impl ToMarkdown for IntDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Consts")); + + for r#const in &self.consts { + let tt = MdNamedType::new(r#const.name.as_str(), &r#const.docs); + // TODO handle r#const.value + node.new_child(tt); + } + + node.content_mut::().r#type = Some(MdType::Int { + repr: self.repr.type_name().to_owned(), + }); + } +} + +impl ToMarkdown for FlagsDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Flags")); + + for flag in &self.flags { + node.new_child(MdNamedType::new(flag.name.as_str(), &flag.docs)); + } + + node.content_mut::().r#type = Some(MdType::Flags { + repr: self.repr.type_name().to_owned(), + }); + } +} + +impl ToMarkdown for StructDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Struct members")); + + for member in &self.members { + let n = node.new_child(MdNamedType::new(member.name.as_str(), &member.docs)); + member.tref.generate(n.clone()); + } + + node.content_mut::().r#type = Some(MdType::Struct); + } +} + +impl ToMarkdown for UnionDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Union variants")); + + for variant in &self.variants { + let n = node.new_child(MdNamedType::new(variant.name.as_str(), &variant.docs)); + variant.tref.generate(n.clone()); + } + + node.content_mut::().r#type = Some(MdType::Union); + } +} + +impl ToMarkdown for HandleDatatype { + fn generate(&self, node: MdNodeRef) { + // TODO this needs more work + node.new_child(MdSection::new("Supertypes")); + node.content_mut::().r#type = Some(MdType::Handle); + } +} + +impl ToMarkdown for Module { + fn generate(&self, node: MdNodeRef) { + let imports = node.new_child(MdSection::new("Imports")); + for import in self.imports() { + let child = imports.new_child(MdSection::default()); + import.generate(child.clone()); + } + + let funcs = node.new_child(MdSection::new("Functions")); + for func in self.funcs() { + let child = funcs.new_child(MdFunc::new(func.name.as_str(), &func.docs)); + func.generate(child.clone()); + } + } +} + +impl ToMarkdown for ModuleImport { + fn generate(&self, node: MdNodeRef) { + match self.variant { + ModuleImportVariant::Memory => { + node.content_mut::().title = "Memory".to_owned(); + } + } + } +} + +impl ToMarkdown for InterfaceFunc { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Params")); + for param in &self.params { + let child = node.new_child(MdNamedType::new(param.name.as_str(), param.name.as_str())); + param.generate(child.clone()); + // TODO should this be expanded recursively instead of using flattened type names? + node.content_mut::() + .inputs + .push((param.name.as_str().to_owned(), param.tref.type_name())); + } + + node.new_child(MdSection::new("Results")); + for result in &self.results { + let child = + node.new_child(MdNamedType::new(result.name.as_str(), result.name.as_str())); + result.generate(child.clone()); + // TODO should this be expanded recursively instead of using flattened type names? + node.content_mut::() + .outputs + .push(result.tref.type_name()); + } + } +} + +impl ToMarkdown for InterfaceFuncParam { + fn generate(&self, node: MdNodeRef) { + self.tref.generate(node.clone()); + node.content_mut::().docs = self.docs.clone(); + } +} + +impl BuiltinType { + pub fn type_name(&self) -> &'static str { + match self { + BuiltinType::String => "string", + BuiltinType::Char8 => "char8", + BuiltinType::USize => "usize", + BuiltinType::U8 => "u8", + BuiltinType::U16 => "u16", + BuiltinType::U32 => "u32", + BuiltinType::U64 => "u64", + BuiltinType::S8 => "s8", + BuiltinType::S16 => "s16", + BuiltinType::S32 => "s32", + BuiltinType::S64 => "s64", + BuiltinType::F32 => "f32", + BuiltinType::F64 => "f64", + } + } +} + +impl TypeRef { + pub fn type_name(&self) -> String { + match self { + TypeRef::Name(n) => n.name.as_str().to_string(), + TypeRef::Value(ref v) => match &**v { + Type::Array(a) => format!("Array<{}>", a.type_name()), + Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), + Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), + Type::Builtin(b) => b.type_name().to_string(), + Type::Enum { .. } + | Type::Int { .. } + | Type::Flags { .. } + | Type::Struct { .. } + | Type::Union { .. } + | Type::Handle { .. } => { + unimplemented!("type_name of anonymous compound datatypes") + } + }, + } + } +} + +impl IntRepr { + fn type_name(&self) -> &'static str { + match self { + IntRepr::U8 => "u8", + IntRepr::U16 => "u16", + IntRepr::U32 => "u32", + IntRepr::U64 => "u64", + } + } +} + +// TODO +// Generate Markdown tree for the polyfill +impl Documentation for Polyfill { + fn to_md(&self) -> String { + let module_docs = self + .modules + .iter() + .map(|m| m.to_md()) + .collect::>() + .join("\n"); + let type_docs = self + .type_polyfills() + .iter() + .filter_map(|t| { + if t.repeq() == RepEquality::Eq { + None + } else { + Some(t.to_md()) + } + }) + .collect::>() + .join("\n"); + format!( + "# Modules\n{}\n# Type Conversions\n{}\n", + module_docs, type_docs + ) + } +} + +impl Documentation for ModulePolyfill { + fn to_md(&self) -> String { + format!( + "## `{}` in terms of `{}`\n{}", + self.new.name.as_str(), + self.old.name.as_str(), + self.funcs + .iter() + .map(|f| f.to_md()) + .collect::>() + .join("\n"), + ) + } +} + +impl Documentation for FuncPolyfill { + fn to_md(&self) -> String { + if self.full_compat() { + format!("* `{}`: full compatibility", self.new.name.as_str()) + } else { + let name = if self.new.name != self.old.name { + format!( + "* `{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("* `{}`", self.new.name.as_str()) + }; + let mut contents = Vec::new(); + for p in self.mapped_params.iter() { + contents.push(if !p.full_compat() { + format!("param {}", p.to_md()) + } else { + format!("param `{}`: compatible", p.new.name.as_str()) + }) + } + for u in self.unknown_params.iter() { + contents.push(format!( + "{} param `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + for r in self.mapped_results.iter() { + contents.push(if !r.full_compat() { + format!("result {}", r.to_md()) + } else { + format!("result `{}`: compatible", r.new.name.as_str()) + }) + } + for u in self.unknown_results.iter() { + contents.push(format!( + "{} result `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + let contents = if contents.is_empty() { + String::new() + } else { + format!(":\n - {}", contents.join("\n - ")) + }; + format!("{}{}", name, contents) + } + } +} + +impl Documentation for ParamPolyfill { + fn to_md(&self) -> String { + let name = if self.new.name != self.old.name { + format!( + "`{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("`{}`", self.new.name.as_str()) + }; + let repr = match self.repeq() { + RepEquality::Eq => "compatible types".to_string(), + RepEquality::Superset => format!( + "`{}` is superset-compatible with `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + RepEquality::NotEq => format!( + "`{}` is incompatible with new `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + }; + format!("{}: {}", name, repr) + } +} + +impl Documentation for TypePolyfill { + fn to_md(&self) -> String { + fn repeq_name(r: RepEquality) -> &'static str { + match r { + RepEquality::Eq => ": compatible", + RepEquality::Superset => ": superset", + RepEquality::NotEq => "", + } + } + match self { + TypePolyfill::OldToNew(o, n) => format!( + "* old `{}` => new `{}`{}", + o.type_name(), + n.type_name(), + repeq_name(self.repeq()) + ), + TypePolyfill::NewToOld(n, o) => format!( + "* new `{}` => old `{}`{}", + n.type_name(), + o.type_name(), + repeq_name(self.repeq()) + ), + } + } +} diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index 52ea968a8..58fbbb16a 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -1,207 +1,217 @@ use std::{ - cell::{Ref, RefCell, RefMut}, + any::Any, + cell::{self, RefCell}, fmt, rc::{Rc, Weak}, }; -fn walk_parents(start: &Weak, cb: &mut impl FnMut(Rc)) { - let mut parent = if let Some(parent) = start.upgrade() { - cb(parent.clone()); - parent - } else { - return; - }; +pub(super) trait ToMarkdown { + fn generate(&self, node: MdNodeRef); +} - while let Some(p) = parent.parent() { - cb(p.clone()); - parent = p; - } +pub(super) trait MdElement: fmt::Debug + 'static { + fn id(&self) -> Option<&str>; + fn as_any(&self) -> &dyn Any; + fn as_any_mut(&mut self) -> &mut dyn Any; + fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result; } -fn gen_link>(id: S) -> String { - format!("", id = id.as_ref()) +#[derive(Debug)] +struct MdNode { + content: Box, + parent: Option>>, + children: Vec, } -fn parse_links>(s: S) -> String { - let to_parse = s.as_ref(); - let mut parsed = String::with_capacity(to_parse.len()); - let mut temp = String::with_capacity(to_parse.len()); - let mut is_link = false; - let mut eaten = None; - for ch in to_parse.chars() { - match (ch, is_link) { - ('`', false) => { - // Found the beginning of a link! - is_link = true; - } - ('`', true) => { - // Reached the end, expand into a link! - // TODO - // Before committing to pasting the link in, - // first verify that it actually exists. - let expanded = format!("[`{}`](#{})", temp, temp); - parsed.push_str(&expanded); - temp.drain(..); - is_link = false; - } - (':', true) => { - if let Some(_) = eaten { - // Swap for '.' - temp.push('.'); - eaten = None; - } else { - eaten = Some(':'); - } - } - (ch, false) => parsed.push(ch), - (ch, true) => temp.push(ch), +impl MdNode { + fn new(item: T) -> Self { + Self { + content: Box::new(item), + parent: None, + children: vec![], } } - parsed } -#[derive(Debug)] -pub(super) enum MdElement { - Section(RefCell), - TypeListing(RefCell), - InterfaceFunc(RefCell), +fn walk_parents(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { + if let Some(parent) = parent.and_then(|x| x.upgrade()) { + cb(parent.clone().into()); + walk_parents(parent.borrow().parent.as_ref(), cb) + } } -impl MdElement { - #[allow(dead_code)] - pub(super) fn as_section(&self) -> Ref { - match self { - Self::Section(t) => t.borrow(), - _ => panic!("not a MdSection"), +impl fmt::Display for MdNode { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut parents = Vec::new(); + walk_parents(self.parent.as_ref(), &mut |parent| { + parents.push(parent); + }); + + MdElement::fmt(&*self.content, f, parents)?; + + for child in &self.children { + child.fmt(f)?; } + + Ok(()) } +} - pub(super) fn as_section_mut(&self) -> RefMut { - match self { - Self::Section(t) => t.borrow_mut(), - _ => panic!("not a MdSection"), - } +#[derive(Debug)] +pub(super) struct MdNodeRef(Rc>); + +impl MdNodeRef { + pub fn new(item: T) -> Self { + Self(Rc::new(RefCell::new(MdNode::new(item)))) } - #[allow(dead_code)] - pub(super) fn as_type_listing(&self) -> Ref { - match self { - Self::TypeListing(t) => t.borrow(), - _ => panic!("not a MdTypeListing"), - } + pub fn new_child(&self, item: T) -> Self { + let mut child_node = MdNode::new(item); + child_node.parent = Some(Rc::downgrade(&self.0)); + let child_ref = Self(Rc::new(RefCell::new(child_node))); + self.0.borrow_mut().children.push(child_ref.clone()); + child_ref } - pub(super) fn as_type_listing_mut(&self) -> RefMut { - match self { - Self::TypeListing(t) => t.borrow_mut(), - _ => panic!("not a MdTypeListing"), - } + fn borrow(&self) -> cell::Ref { + self.0.borrow() } - #[allow(dead_code)] - pub(super) fn as_interface_func(&self) -> Ref { - match self { - Self::InterfaceFunc(t) => t.borrow(), - _ => panic!("not a MdInterfaceFunc"), - } + fn borrow_mut(&self) -> cell::RefMut { + self.0.borrow_mut() } - pub(super) fn as_interface_func_mut(&self) -> RefMut { - match self { - Self::InterfaceFunc(t) => t.borrow_mut(), - _ => panic!("not a MdInterfaceFunc"), - } + pub fn content_ref(&self) -> cell::Ref { + cell::Ref::map(self.borrow(), |b| { + let r = b.content.as_any(); + r.downcast_ref::().expect("reference is not T type") + }) } - pub(super) fn parent(&self) -> Option> { - match self { - Self::Section(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), - Self::TypeListing(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), - Self::InterfaceFunc(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), + pub fn content_mut(&self) -> cell::RefMut { + cell::RefMut::map(self.borrow_mut(), |b| { + let r = b.content.as_any_mut(); + r.downcast_mut::().expect("reference is not T type") + }) + } + + pub fn get_content(&self) -> Option> { + if self.borrow().content.as_any().is::() { + Some(self.content_ref::()) + } else { + None } } -} -impl fmt::Display for MdElement { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Section(t) => t.borrow().fmt(f), - Self::TypeListing(t) => t.borrow().fmt(f), - Self::InterfaceFunc(t) => t.borrow().fmt(f), + #[allow(unused)] + pub fn get_content_mut(&self) -> Option> { + if self.borrow_mut().content.as_any().is::() { + Some(self.content_mut::()) + } else { + None } } } -#[derive(Debug)] -pub(super) struct MdSection { - pub id: String, - pub title: String, - pub description: Vec, - pub elements: Vec>, - pub parent: Option>, +impl Clone for MdNodeRef { + fn clone(&self) -> Self { + Self(self.0.clone()) + } } -#[derive(Debug)] -pub(super) struct MdParagraph(String); - -impl MdParagraph { - pub fn new>(s: S) -> Self { - Self(s.as_ref().to_owned()) +impl From>> for MdNodeRef { + fn from(node: Rc>) -> Self { + Self(node) } } -impl fmt::Display for MdParagraph { +impl fmt::Display for MdNodeRef { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - writeln!(f, "{}", parse_links(&self.0)) + self.borrow().fmt(f) + } +} + +#[derive(Debug, Default)] +pub(super) struct MdRoot; + +impl MdElement for MdRoot { + fn id(&self) -> Option<&str> { + None + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn fmt(&self, _f: &mut fmt::Formatter, _parents: Vec) -> fmt::Result { + Ok(()) } } +#[derive(Debug, Default)] +pub(super) struct MdSection { + pub id: Option, + pub title: String, +} + impl MdSection { - pub fn new>(id: S, title: S, parent: Option>) -> MdElement { - MdElement::Section(RefCell::new(Self { - id: id.as_ref().to_owned(), + pub fn new>(title: S) -> Self { + Self { + id: None, title: title.as_ref().to_owned(), - description: vec![], - elements: vec![], - parent, - })) + } } } -impl fmt::Display for MdSection { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut heading = "#".to_owned(); - if let Some(parent) = self.parent.as_ref() { - walk_parents(parent, &mut |_| { - heading += "#"; - }); - } - f.write_fmt(format_args!( - "{heading} {link} {title}\n", - heading = heading, - link = gen_link(&self.id), - title = &self.title - ))?; - for para in &self.description { - f.write_fmt(format_args!("{}\n", para))?; - } - for el in &self.elements { - f.write_fmt(format_args!("{}\n", el))?; +impl MdElement for MdSection { + fn id(&self) -> Option<&str> { + self.id.as_ref().map(|s| s.as_str()) + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { + let header = "#".repeat(parents.len()); + f.write_fmt(format_args!("{} ", header))?; + + if let Some(id) = &self.id { + f.write_fmt(format_args!( + " ", + id = id + ))?; } - Ok(()) + + writeln!(f, "{}", self.title) } } #[derive(Debug)] -pub(super) struct MdTypeListing { - pub id: String, - pub r#type: MdType, - pub description: Vec, - pub elements: Vec, - pub parent: Option>, +pub(super) struct MdNamedType { + pub name: String, + pub docs: String, + pub r#type: Option, +} + +impl MdNamedType { + pub fn new, S2: AsRef>(name: S1, docs: S2) -> Self { + Self { + name: name.as_ref().to_owned(), + docs: docs.as_ref().to_owned(), + r#type: None, + } + } } -#[allow(dead_code)] #[derive(Debug)] pub(super) enum MdType { Enum { repr: String }, @@ -209,150 +219,142 @@ pub(super) enum MdType { Flags { repr: String }, Struct, Union, - Handle, Array { r#type: String }, - Pointer { to: String }, - ConstPointer { to: String }, - Builtin { r#type: String }, + Pointer { r#type: String }, + ConstPointer { r#type: String }, + Builtin { repr: String }, + Handle, + Alias { r#type: String }, } -#[derive(Debug)] -pub(super) struct MdBullet { - pub id: String, - pub description: Vec, -} +impl fmt::Display for MdType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Enum { repr } => f.write_fmt(format_args!(": Enum(`{}`)", repr))?, + Self::Int { repr } => f.write_fmt(format_args!(": Int(`{}`)", repr))?, + Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, + Self::Struct => f.write_fmt(format_args!(": Struct"))?, + Self::Union => f.write_fmt(format_args!(": Union"))?, + Self::Array { r#type } => f.write_fmt(format_args!(": `Array<{}>`", r#type))?, + Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, + Self::ConstPointer { r#type } => { + f.write_fmt(format_args!(": `ConstPointer<{}>`", r#type))? + } + Self::Builtin { repr } => f.write_fmt(format_args!(": `{}`", repr))?, + Self::Handle => {} + Self::Alias { r#type } => f.write_fmt(format_args!(": `{}`", r#type))?, + }; -impl MdTypeListing { - pub fn new(id: &str, r#type: MdType, parent: Option>) -> MdElement { - MdElement::TypeListing(RefCell::new(Self { - id: id.to_owned(), - r#type, - description: vec![], - elements: vec![], - parent, - })) + Ok(()) } } -impl fmt::Display for MdTypeListing { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut heading = "#".to_owned(); - if let Some(parent) = self.parent.as_ref() { - walk_parents(parent, &mut |_| { - heading += "#"; - }); - } - // ### `errno` +impl MdElement for MdNamedType { + fn id(&self) -> Option<&str> { + Some(&self.name) + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { + // Firstly, check if our parent is an MdSection or another MdNamedType in which + // case, we're already nesting and should be represented as bullets + let (header, link) = if let Some(p) = parents.first() { + if let Some(_sec) = p.get_content::() { + ("#".repeat(parents.len()), self.name.clone()) + } else if let Some(tt) = p.get_content::() { + ("-".to_owned(), format!("{}.{}", tt.name, self.name)) + } else if let Some(f) = p.get_content::() { + ("-".to_owned(), format!("{}.{}", f.name, self.name)) + } else { + ("#".to_owned(), self.name.clone()) + } + } else { + ("#".to_owned(), self.name.clone()) + }; + f.write_fmt(format_args!( - "{heading} {link} `{id}`\n", - heading = heading, - link = gen_link(&self.id), - id = &self.id + "{header} `{name}`", + header = header, + link = link, + name = self.name, ))?; - // Error codes returned by function... - for para in &self.description { - f.write_fmt(format_args!("{}\n", para))?; - } - // Enum represented by `u16` - // Variants: - let type_specific = match &self.r#type { - MdType::Enum { repr } => format!("Enum represented by `{}`\n\n**Variants:**\n", repr), - MdType::Int { repr } => format!("Int represented by `{}`\n\n**Const:**\n", repr), - MdType::Flags { repr } => format!("Flags represented by `{}`\n\n**Flags:**\n", repr), - MdType::Struct => "\n**Struct members:**\n".to_owned(), - MdType::Union => "\n**Union variants:**\n".to_owned(), - MdType::Handle => "\n**Supertypes:**\n".to_owned(), - MdType::Array { r#type } => format!("Array of `{}`", r#type), - MdType::Pointer { to } => format!("Pointer to `{}`", to), - MdType::ConstPointer { to } => format!("Const pointer to `{}`", to), - MdType::Builtin { r#type } => format!("Builtin type `{}`", r#type), - }; - f.write_str(&type_specific)?; - // - `success` - // No error occurred. System call completed successfully. - for el in &self.elements { - f.write_fmt(format_args!( - "- {link} `{el_id}`\n\n", - link = gen_link(format!("{}.{}", self.id, el.id)), - el_id = el.id - ))?; - for desc in &el.description { - f.write_fmt(format_args!("\t{}\n", desc))?; - } + + if let Some(tt) = &self.r#type { + f.write_fmt(format_args!("{}", tt))?; } - Ok(()) + + writeln!(f, "\n{}", self.docs) } } #[derive(Debug)] -pub(super) struct MdInterfaceFunc { - pub id: String, - pub description: Vec, - pub parameters: Vec, - pub results: Vec, - pub parent: Option>, +pub(super) struct MdFunc { + pub name: String, + pub inputs: Vec<(String, String)>, + pub outputs: Vec, + pub docs: String, } -impl MdInterfaceFunc { - pub fn new(id: &str, parent: Option>) -> MdElement { - MdElement::InterfaceFunc(RefCell::new(Self { - id: id.to_owned(), - description: vec![], - parameters: vec![], - results: vec![], - parent, - })) +impl MdFunc { + pub fn new, S2: AsRef>(name: S1, docs: S2) -> Self { + Self { + name: name.as_ref().to_owned(), + inputs: vec![], + outputs: vec![], + docs: docs.as_ref().to_owned(), + } } } -impl fmt::Display for MdInterfaceFunc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut heading = "#".to_owned(); - if let Some(parent) = self.parent.as_ref() { - walk_parents(parent, &mut |_| { - heading += "#"; - }); - } - // ### `args_get` +impl MdElement for MdFunc { + fn id(&self) -> Option<&str> { + Some(&self.name) + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { + // Expand header + let header = "#".repeat(parents.len()); + // Expand inputs + let inputs = self + .inputs + .iter() + .map(|(name, r#type)| format!("{}: `{}`", name, r#type)) + .collect::>() + .join(", "); + // Expand outputs + let outputs: Vec<_> = self + .outputs + .iter() + .map(|r#type| format!("`{}`", r#type)) + .collect(); + let outputs = match outputs.len() { + 0 => "".to_owned(), + 1 => format!(" -> {}", outputs[0]), + _ => format!(" -> ({})", outputs.join(", ")), + }; f.write_fmt(format_args!( - "{heading} `{id}`\n\n", - heading = heading, - id = self.id + "{header} Fn {name}({inputs}){outputs}", + header = header, + name = self.name, + inputs = inputs, + outputs = outputs, ))?; - // Read command-line argument data... - for desc in &self.description { - f.write_fmt(format_args!("{}\n", desc))?; - } - // Parameters: - // * `argv` - // `argv` has type... - if !self.parameters.is_empty() { - f.write_str("**Parameters:**\n\n")?; - for param in &self.parameters { - f.write_fmt(format_args!( - "- {link} `{param_id}`\n\n", - link = gen_link(format!("{}.{}", self.id, param.id)), - param_id = param.id - ))?; - for desc in ¶m.description { - f.write_fmt(format_args!("\t{}\n", desc))?; - } - } - } - // Results: - // * `error` - // `error` has type `errno` - f.write_str("**Results:**\n\n")?; - for result in &self.results { - f.write_fmt(format_args!( - "- {link} `{res_id}`\n\n", - link = gen_link(format!("{}.{}", self.id, result.id)), - res_id = result.id - ))?; - for desc in &result.description { - f.write_fmt(format_args!("\t{}\n", desc))?; - } - } - Ok(()) + + writeln!(f, "\n{}", self.docs) } } diff --git a/proposals/random/tools/witx/src/docs/mod.rs b/proposals/random/tools/witx/src/docs/mod.rs index ebf720416..e0b962ce2 100644 --- a/proposals/random/tools/witx/src/docs/mod.rs +++ b/proposals/random/tools/witx/src/docs/mod.rs @@ -1,421 +1,18 @@ +mod ast; mod md; -use crate::ast::*; -use crate::polyfill::*; -use crate::RepEquality; -use md::*; -use std::rc::{Rc, Weak}; +use crate::ast::Document; +use md::{MdNodeRef, MdRoot, ToMarkdown}; pub trait Documentation { fn to_md(&self) -> String; } -trait ToMarkdown { - fn gen(&self, _parent: Option>) -> Rc; -} - impl Documentation for Document { fn to_md(&self) -> String { - format!("{}", self.gen(None)) - } -} - -impl ToMarkdown for Document { - fn gen(&self, parent: Option>) -> Rc { - let doc = Rc::new(MdSection::new("root", "Root", parent)); - let types = Rc::new(MdSection::new("types", "Types", Some(Rc::downgrade(&doc)))); - for typename in self.typenames() { - types - .as_section_mut() - .elements - .push(typename.gen(Some(Rc::downgrade(&types)))); - } - let modules = Rc::new(MdSection::new( - "modules", - "Modules", - Some(Rc::downgrade(&doc)), - )); - for module in self.modules() { - modules - .as_section_mut() - .elements - .push(module.gen(Some(Rc::downgrade(&modules)))); - } - doc.as_section_mut() - .elements - .extend_from_slice(&[types, modules]); - doc - } -} - -impl BuiltinType { - pub fn type_name(&self) -> &'static str { - match self { - BuiltinType::String => "string", - BuiltinType::Char8 => "char8", - BuiltinType::USize => "usize", - BuiltinType::U8 => "u8", - BuiltinType::U16 => "u16", - BuiltinType::U32 => "u32", - BuiltinType::U64 => "u64", - BuiltinType::S8 => "s8", - BuiltinType::S16 => "s16", - BuiltinType::S32 => "s32", - BuiltinType::S64 => "s64", - BuiltinType::F32 => "f32", - BuiltinType::F64 => "f64", - } - } -} - -impl ToMarkdown for NamedType { - fn gen(&self, parent: Option>) -> Rc { - match &self.tref { - TypeRef::Value(v) => { - let md_type = MdType::from(&**v); - let mut elements: Vec<_> = match &**v { - Type::Enum(a) => a.variants.iter().map(MdBullet::from).collect(), - Type::Int(a) => a.consts.iter().map(MdBullet::from).collect(), - Type::Flags(a) => a.flags.iter().map(MdBullet::from).collect(), - Type::Struct(a) => a.members.iter().map(MdBullet::from).collect(), - Type::Union(a) => a.variants.iter().map(MdBullet::from).collect(), - Type::Handle(a) => a.supertypes.iter().map(MdBullet::from).collect(), - _ => vec![], - }; - let listing = Rc::new(MdTypeListing::new(self.name.as_str(), md_type, parent)); - listing - .as_type_listing_mut() - .description - .push(MdParagraph::new(&self.docs)); - listing.as_type_listing_mut().elements.append(&mut elements); - listing - } - TypeRef::Name(n) => { - let sec = Rc::new(MdSection::new( - self.name.as_str(), - self.name.as_str(), - parent, - )); - sec.as_section_mut().description.append(&mut vec![ - MdParagraph::new(&self.docs), - MdParagraph::new(format!("Alias to {}", n.name.as_str())), - ]); - sec - } - } - } -} - -impl From<&Type> for MdType { - fn from(r#type: &Type) -> Self { - match r#type { - Type::Enum(a) => Self::Enum { - repr: a.repr.type_name().to_owned(), - }, - Type::Int(a) => Self::Int { - repr: a.repr.type_name().to_owned(), - }, - Type::Flags(a) => Self::Flags { - repr: a.repr.type_name().to_owned(), - }, - Type::Struct(_) => Self::Struct, - Type::Union(_) => Self::Union, - Type::Handle(_) => Self::Handle, - Type::Array(a) => Self::Array { - r#type: a.type_name().to_owned(), - }, - Type::Pointer(a) => Self::Pointer { - to: a.type_name().to_owned(), - }, - Type::ConstPointer(a) => Self::ConstPointer { - to: a.type_name().to_owned(), - }, - Type::Builtin(a) => Self::Builtin { - r#type: a.type_name().to_owned(), - }, - } - } -} - -macro_rules! impl_mdbullet { - ($from:ty) => { - impl From<$from> for MdBullet { - fn from(f: $from) -> Self { - Self { - id: f.name.as_str().to_owned(), - description: vec![MdParagraph::new(&f.docs)], - } - } - } - }; -} - -impl_mdbullet!(&EnumVariant); -impl_mdbullet!(&IntConst); -impl_mdbullet!(&FlagsMember); -impl_mdbullet!(&StructMember); -impl_mdbullet!(&UnionVariant); - -impl From<&TypeRef> for MdBullet { - fn from(t: &TypeRef) -> Self { - Self { - id: t.type_name().to_owned(), - description: vec![], - } - } -} - -impl TypeRef { - pub fn type_name(&self) -> String { - match self { - TypeRef::Name(n) => n.name.as_str().to_string(), - TypeRef::Value(ref v) => match &**v { - Type::Array(a) => format!("Array<{}>", a.type_name()), - Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), - Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), - Type::Builtin(b) => b.type_name().to_string(), - Type::Enum { .. } - | Type::Int { .. } - | Type::Flags { .. } - | Type::Struct { .. } - | Type::Union { .. } - | Type::Handle { .. } => { - unimplemented!("type_name of anonymous compound datatypes") - } - }, - } - } -} - -impl IntRepr { - fn type_name(&self) -> &'static str { - match self { - IntRepr::U8 => "u8", - IntRepr::U16 => "u16", - IntRepr::U32 => "u32", - IntRepr::U64 => "u64", - } - } -} - -impl ToMarkdown for Module { - fn gen(&self, parent: Option>) -> Rc { - let sec = Rc::new(MdSection::new( - self.name.as_str(), - &format!("`{}`", self.name.as_str()), - parent, - )); - let imports = Rc::new(MdSection::new( - "imports", - "Imports", - Some(Rc::downgrade(&sec)), - )); - // TODO - // This should probably be done using something more specific - // than a generic MdSection - for import in self.imports() { - let desc = match import.variant { - ModuleImportVariant::Memory => format!("* {}: Memory", import.name.as_str()), - }; - imports - .as_section_mut() - .description - .push(MdParagraph::new(desc)); - } - sec.as_section_mut().elements.push(imports); - let funcs = Rc::new(MdSection::new( - "functions", - "Functions", - Some(Rc::downgrade(&sec)), - )); - funcs - .as_section_mut() - .elements - .extend(self.funcs().map(|f| f.gen(Some(Rc::downgrade(&funcs))))); - sec.as_section_mut().elements.push(funcs); - sec - } -} - -impl ToMarkdown for InterfaceFunc { - fn gen(&self, parent: Option>) -> Rc { - let func = Rc::new(MdInterfaceFunc::new(self.name.as_str(), parent)); - func.as_interface_func_mut() - .description - .push(MdParagraph::new(&self.docs)); - func.as_interface_func_mut() - .parameters - .extend(self.params.iter().map(MdBullet::from)); - func.as_interface_func_mut() - .results - .extend(self.results.iter().map(MdBullet::from)); - func - } -} - -impl From<&InterfaceFuncParam> for MdBullet { - fn from(param: &InterfaceFuncParam) -> Self { - Self { - id: param.name.as_str().to_owned(), - description: vec![ - MdParagraph::new(format!( - "`{}` has type `{}`", - param.name.as_str(), - param.tref.type_name(), - )), - MdParagraph::new(format!("{}", param.docs)), - ], - } - } -} - -// TODO -// Implement ToMarkdown for Polyfill -impl Documentation for Polyfill { - fn to_md(&self) -> String { - let module_docs = self - .modules - .iter() - .map(|m| m.to_md()) - .collect::>() - .join("\n"); - let type_docs = self - .type_polyfills() - .iter() - .filter_map(|t| { - if t.repeq() == RepEquality::Eq { - None - } else { - Some(t.to_md()) - } - }) - .collect::>() - .join("\n"); - format!( - "# Modules\n{}\n# Type Conversions\n{}\n", - module_docs, type_docs - ) + let root = MdNodeRef::new(MdRoot::default()); + self.generate(root.clone()); + format!("{}", root) } } -impl Documentation for ModulePolyfill { - fn to_md(&self) -> String { - format!( - "## `{}` in terms of `{}`\n{}", - self.new.name.as_str(), - self.old.name.as_str(), - self.funcs - .iter() - .map(|f| f.to_md()) - .collect::>() - .join("\n"), - ) - } -} - -impl Documentation for FuncPolyfill { - fn to_md(&self) -> String { - if self.full_compat() { - format!("* `{}`: full compatibility", self.new.name.as_str()) - } else { - let name = if self.new.name != self.old.name { - format!( - "* `{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("* `{}`", self.new.name.as_str()) - }; - let mut contents = Vec::new(); - for p in self.mapped_params.iter() { - contents.push(if !p.full_compat() { - format!("param {}", p.to_md()) - } else { - format!("param `{}`: compatible", p.new.name.as_str()) - }) - } - for u in self.unknown_params.iter() { - contents.push(format!( - "{} param `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - for r in self.mapped_results.iter() { - contents.push(if !r.full_compat() { - format!("result {}", r.to_md()) - } else { - format!("result `{}`: compatible", r.new.name.as_str()) - }) - } - for u in self.unknown_results.iter() { - contents.push(format!( - "{} result `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - let contents = if contents.is_empty() { - String::new() - } else { - format!(":\n - {}", contents.join("\n - ")) - }; - format!("{}{}", name, contents) - } - } -} - -impl Documentation for ParamPolyfill { - fn to_md(&self) -> String { - let name = if self.new.name != self.old.name { - format!( - "`{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("`{}`", self.new.name.as_str()) - }; - let repr = match self.repeq() { - RepEquality::Eq => "compatible types".to_string(), - RepEquality::Superset => format!( - "`{}` is superset-compatible with `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - RepEquality::NotEq => format!( - "`{}` is incompatible with new `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - }; - format!("{}: {}", name, repr) - } -} - -impl Documentation for TypePolyfill { - fn to_md(&self) -> String { - fn repeq_name(r: RepEquality) -> &'static str { - match r { - RepEquality::Eq => ": compatible", - RepEquality::Superset => ": superset", - RepEquality::NotEq => "", - } - } - match self { - TypePolyfill::OldToNew(o, n) => format!( - "* old `{}` => new `{}`{}", - o.type_name(), - n.type_name(), - repeq_name(self.repeq()) - ), - TypePolyfill::NewToOld(n, o) => format!( - "* new `{}` => old `{}`{}", - n.type_name(), - o.type_name(), - repeq_name(self.repeq()) - ), - } - } -} From 903d32f9619a737aabaee922b7d0ccb10082c7a0 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 00:05:23 +0100 Subject: [PATCH 0459/1772] Final iteration of the approach (hopefully) This approach is heavily inspired by `HostRef` and related present in `wasmtime` (see [wasmtime/crates/api/ref.rs]). In this new approach, instead of holding all possible type variants inside a statically-typed `enum`, I've decided to have a tiered structure where (from bottom/inner-most element to the top/outer-most element): * `Box` is any "content-box" holding for instance a Markdown element representing a section, `NamedType`, etc. * `MdNode` struct wrapping the "content-box" plus storing all children `MdNodes` (representing subsections, etc.), and a weak link to the parent `MdNode` (if any) * `MdNodeRef` struct wrapping `MdNode` inside an `Rc>`, and offering convenience methods to extract `dyn MdElement` directly from `MdNodeRef`, etc. Finally, `trait MdElement` represents the minimum interface required for any "content-box" to have in order to be able to interface with other generated Markdown nodes. [wasmtime/crates/api/ref.rs]: https://github.com/bytecodealliance/wasmtime/blob/master/crates/api/src/ref.rs --- .../filesystem/tools/witx/src/docs/ast.rs | 415 +++++++++++++ .../filesystem/tools/witx/src/docs/md.rs | 544 +++++++++--------- .../filesystem/tools/witx/src/docs/mod.rs | 415 +------------ 3 files changed, 694 insertions(+), 680 deletions(-) create mode 100644 proposals/filesystem/tools/witx/src/docs/ast.rs diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs new file mode 100644 index 000000000..641673775 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -0,0 +1,415 @@ +use super::md::*; +use super::Documentation; +use crate::ast::*; +use crate::polyfill::*; +use crate::RepEquality; + +impl ToMarkdown for Document { + fn generate(&self, node: MdNodeRef) { + let types = node.new_child(MdSection::new("Types")); + for d in self.typenames() { + let child = types.new_child(MdNamedType::new(d.name.as_str(), &d.docs)); + d.generate(child.clone()); + } + + let modules = node.new_child(MdSection::new("Modules")); + for d in self.modules() { + let mut content = MdSection::new(d.name.as_str()); + content.id = Some(d.name.as_str().to_owned()); + let child = modules.new_child(content); + d.generate(child.clone()); + } + } +} + +impl ToMarkdown for TypeRef { + fn generate(&self, node: MdNodeRef) { + match self { + TypeRef::Value(v) => v.generate(node.clone()), + TypeRef::Name(n) => { + node.content_mut::().r#type = Some(MdType::Alias { + r#type: n.name.as_str().to_owned(), + }) + } + } + } +} + +impl ToMarkdown for NamedType { + fn generate(&self, node: MdNodeRef) { + self.tref.generate(node.clone()); + } +} + +impl ToMarkdown for Type { + fn generate(&self, node: MdNodeRef) { + match self { + Self::Enum(a) => a.generate(node.clone()), + Self::Int(a) => a.generate(node.clone()), + Self::Flags(a) => a.generate(node.clone()), + Self::Struct(a) => a.generate(node.clone()), + Self::Union(a) => a.generate(node.clone()), + Self::Handle(a) => a.generate(node.clone()), + Self::Array(a) => { + node.content_mut::().r#type = Some(MdType::Array { + r#type: a.type_name().to_owned(), + }) + } + Self::Pointer(a) => { + node.content_mut::().r#type = Some(MdType::Pointer { + r#type: a.type_name().to_owned(), + }) + } + Self::ConstPointer(a) => { + node.content_mut::().r#type = Some(MdType::ConstPointer { + r#type: a.type_name().to_owned(), + }) + } + Self::Builtin(a) => { + node.content_mut::().r#type = Some(MdType::Builtin { + repr: a.type_name().to_owned(), + }) + } + } + } +} + +impl ToMarkdown for EnumDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Variants")); + + for variant in &self.variants { + node.new_child(MdNamedType::new(variant.name.as_str(), &variant.docs)); + } + + node.content_mut::().r#type = Some(MdType::Enum { + repr: self.repr.type_name().to_owned(), + }); + } +} + +impl ToMarkdown for IntDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Consts")); + + for r#const in &self.consts { + let tt = MdNamedType::new(r#const.name.as_str(), &r#const.docs); + // TODO handle r#const.value + node.new_child(tt); + } + + node.content_mut::().r#type = Some(MdType::Int { + repr: self.repr.type_name().to_owned(), + }); + } +} + +impl ToMarkdown for FlagsDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Flags")); + + for flag in &self.flags { + node.new_child(MdNamedType::new(flag.name.as_str(), &flag.docs)); + } + + node.content_mut::().r#type = Some(MdType::Flags { + repr: self.repr.type_name().to_owned(), + }); + } +} + +impl ToMarkdown for StructDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Struct members")); + + for member in &self.members { + let n = node.new_child(MdNamedType::new(member.name.as_str(), &member.docs)); + member.tref.generate(n.clone()); + } + + node.content_mut::().r#type = Some(MdType::Struct); + } +} + +impl ToMarkdown for UnionDatatype { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Union variants")); + + for variant in &self.variants { + let n = node.new_child(MdNamedType::new(variant.name.as_str(), &variant.docs)); + variant.tref.generate(n.clone()); + } + + node.content_mut::().r#type = Some(MdType::Union); + } +} + +impl ToMarkdown for HandleDatatype { + fn generate(&self, node: MdNodeRef) { + // TODO this needs more work + node.new_child(MdSection::new("Supertypes")); + node.content_mut::().r#type = Some(MdType::Handle); + } +} + +impl ToMarkdown for Module { + fn generate(&self, node: MdNodeRef) { + let imports = node.new_child(MdSection::new("Imports")); + for import in self.imports() { + let child = imports.new_child(MdSection::default()); + import.generate(child.clone()); + } + + let funcs = node.new_child(MdSection::new("Functions")); + for func in self.funcs() { + let child = funcs.new_child(MdFunc::new(func.name.as_str(), &func.docs)); + func.generate(child.clone()); + } + } +} + +impl ToMarkdown for ModuleImport { + fn generate(&self, node: MdNodeRef) { + match self.variant { + ModuleImportVariant::Memory => { + node.content_mut::().title = "Memory".to_owned(); + } + } + } +} + +impl ToMarkdown for InterfaceFunc { + fn generate(&self, node: MdNodeRef) { + node.new_child(MdSection::new("Params")); + for param in &self.params { + let child = node.new_child(MdNamedType::new(param.name.as_str(), param.name.as_str())); + param.generate(child.clone()); + // TODO should this be expanded recursively instead of using flattened type names? + node.content_mut::() + .inputs + .push((param.name.as_str().to_owned(), param.tref.type_name())); + } + + node.new_child(MdSection::new("Results")); + for result in &self.results { + let child = + node.new_child(MdNamedType::new(result.name.as_str(), result.name.as_str())); + result.generate(child.clone()); + // TODO should this be expanded recursively instead of using flattened type names? + node.content_mut::() + .outputs + .push(result.tref.type_name()); + } + } +} + +impl ToMarkdown for InterfaceFuncParam { + fn generate(&self, node: MdNodeRef) { + self.tref.generate(node.clone()); + node.content_mut::().docs = self.docs.clone(); + } +} + +impl BuiltinType { + pub fn type_name(&self) -> &'static str { + match self { + BuiltinType::String => "string", + BuiltinType::Char8 => "char8", + BuiltinType::USize => "usize", + BuiltinType::U8 => "u8", + BuiltinType::U16 => "u16", + BuiltinType::U32 => "u32", + BuiltinType::U64 => "u64", + BuiltinType::S8 => "s8", + BuiltinType::S16 => "s16", + BuiltinType::S32 => "s32", + BuiltinType::S64 => "s64", + BuiltinType::F32 => "f32", + BuiltinType::F64 => "f64", + } + } +} + +impl TypeRef { + pub fn type_name(&self) -> String { + match self { + TypeRef::Name(n) => n.name.as_str().to_string(), + TypeRef::Value(ref v) => match &**v { + Type::Array(a) => format!("Array<{}>", a.type_name()), + Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), + Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), + Type::Builtin(b) => b.type_name().to_string(), + Type::Enum { .. } + | Type::Int { .. } + | Type::Flags { .. } + | Type::Struct { .. } + | Type::Union { .. } + | Type::Handle { .. } => { + unimplemented!("type_name of anonymous compound datatypes") + } + }, + } + } +} + +impl IntRepr { + fn type_name(&self) -> &'static str { + match self { + IntRepr::U8 => "u8", + IntRepr::U16 => "u16", + IntRepr::U32 => "u32", + IntRepr::U64 => "u64", + } + } +} + +// TODO +// Generate Markdown tree for the polyfill +impl Documentation for Polyfill { + fn to_md(&self) -> String { + let module_docs = self + .modules + .iter() + .map(|m| m.to_md()) + .collect::>() + .join("\n"); + let type_docs = self + .type_polyfills() + .iter() + .filter_map(|t| { + if t.repeq() == RepEquality::Eq { + None + } else { + Some(t.to_md()) + } + }) + .collect::>() + .join("\n"); + format!( + "# Modules\n{}\n# Type Conversions\n{}\n", + module_docs, type_docs + ) + } +} + +impl Documentation for ModulePolyfill { + fn to_md(&self) -> String { + format!( + "## `{}` in terms of `{}`\n{}", + self.new.name.as_str(), + self.old.name.as_str(), + self.funcs + .iter() + .map(|f| f.to_md()) + .collect::>() + .join("\n"), + ) + } +} + +impl Documentation for FuncPolyfill { + fn to_md(&self) -> String { + if self.full_compat() { + format!("* `{}`: full compatibility", self.new.name.as_str()) + } else { + let name = if self.new.name != self.old.name { + format!( + "* `{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("* `{}`", self.new.name.as_str()) + }; + let mut contents = Vec::new(); + for p in self.mapped_params.iter() { + contents.push(if !p.full_compat() { + format!("param {}", p.to_md()) + } else { + format!("param `{}`: compatible", p.new.name.as_str()) + }) + } + for u in self.unknown_params.iter() { + contents.push(format!( + "{} param `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + for r in self.mapped_results.iter() { + contents.push(if !r.full_compat() { + format!("result {}", r.to_md()) + } else { + format!("result `{}`: compatible", r.new.name.as_str()) + }) + } + for u in self.unknown_results.iter() { + contents.push(format!( + "{} result `{}`: no corresponding result!", + u.which(), + u.param().name.as_str() + )) + } + let contents = if contents.is_empty() { + String::new() + } else { + format!(":\n - {}", contents.join("\n - ")) + }; + format!("{}{}", name, contents) + } + } +} + +impl Documentation for ParamPolyfill { + fn to_md(&self) -> String { + let name = if self.new.name != self.old.name { + format!( + "`{}` => `{}`", + self.old.name.as_str(), + self.new.name.as_str() + ) + } else { + format!("`{}`", self.new.name.as_str()) + }; + let repr = match self.repeq() { + RepEquality::Eq => "compatible types".to_string(), + RepEquality::Superset => format!( + "`{}` is superset-compatible with `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + RepEquality::NotEq => format!( + "`{}` is incompatible with new `{}`", + self.old.tref.type_name(), + self.new.tref.type_name() + ), + }; + format!("{}: {}", name, repr) + } +} + +impl Documentation for TypePolyfill { + fn to_md(&self) -> String { + fn repeq_name(r: RepEquality) -> &'static str { + match r { + RepEquality::Eq => ": compatible", + RepEquality::Superset => ": superset", + RepEquality::NotEq => "", + } + } + match self { + TypePolyfill::OldToNew(o, n) => format!( + "* old `{}` => new `{}`{}", + o.type_name(), + n.type_name(), + repeq_name(self.repeq()) + ), + TypePolyfill::NewToOld(n, o) => format!( + "* new `{}` => old `{}`{}", + n.type_name(), + o.type_name(), + repeq_name(self.repeq()) + ), + } + } +} diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index 52ea968a8..58fbbb16a 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -1,207 +1,217 @@ use std::{ - cell::{Ref, RefCell, RefMut}, + any::Any, + cell::{self, RefCell}, fmt, rc::{Rc, Weak}, }; -fn walk_parents(start: &Weak, cb: &mut impl FnMut(Rc)) { - let mut parent = if let Some(parent) = start.upgrade() { - cb(parent.clone()); - parent - } else { - return; - }; +pub(super) trait ToMarkdown { + fn generate(&self, node: MdNodeRef); +} - while let Some(p) = parent.parent() { - cb(p.clone()); - parent = p; - } +pub(super) trait MdElement: fmt::Debug + 'static { + fn id(&self) -> Option<&str>; + fn as_any(&self) -> &dyn Any; + fn as_any_mut(&mut self) -> &mut dyn Any; + fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result; } -fn gen_link>(id: S) -> String { - format!("", id = id.as_ref()) +#[derive(Debug)] +struct MdNode { + content: Box, + parent: Option>>, + children: Vec, } -fn parse_links>(s: S) -> String { - let to_parse = s.as_ref(); - let mut parsed = String::with_capacity(to_parse.len()); - let mut temp = String::with_capacity(to_parse.len()); - let mut is_link = false; - let mut eaten = None; - for ch in to_parse.chars() { - match (ch, is_link) { - ('`', false) => { - // Found the beginning of a link! - is_link = true; - } - ('`', true) => { - // Reached the end, expand into a link! - // TODO - // Before committing to pasting the link in, - // first verify that it actually exists. - let expanded = format!("[`{}`](#{})", temp, temp); - parsed.push_str(&expanded); - temp.drain(..); - is_link = false; - } - (':', true) => { - if let Some(_) = eaten { - // Swap for '.' - temp.push('.'); - eaten = None; - } else { - eaten = Some(':'); - } - } - (ch, false) => parsed.push(ch), - (ch, true) => temp.push(ch), +impl MdNode { + fn new(item: T) -> Self { + Self { + content: Box::new(item), + parent: None, + children: vec![], } } - parsed } -#[derive(Debug)] -pub(super) enum MdElement { - Section(RefCell), - TypeListing(RefCell), - InterfaceFunc(RefCell), +fn walk_parents(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { + if let Some(parent) = parent.and_then(|x| x.upgrade()) { + cb(parent.clone().into()); + walk_parents(parent.borrow().parent.as_ref(), cb) + } } -impl MdElement { - #[allow(dead_code)] - pub(super) fn as_section(&self) -> Ref { - match self { - Self::Section(t) => t.borrow(), - _ => panic!("not a MdSection"), +impl fmt::Display for MdNode { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut parents = Vec::new(); + walk_parents(self.parent.as_ref(), &mut |parent| { + parents.push(parent); + }); + + MdElement::fmt(&*self.content, f, parents)?; + + for child in &self.children { + child.fmt(f)?; } + + Ok(()) } +} - pub(super) fn as_section_mut(&self) -> RefMut { - match self { - Self::Section(t) => t.borrow_mut(), - _ => panic!("not a MdSection"), - } +#[derive(Debug)] +pub(super) struct MdNodeRef(Rc>); + +impl MdNodeRef { + pub fn new(item: T) -> Self { + Self(Rc::new(RefCell::new(MdNode::new(item)))) } - #[allow(dead_code)] - pub(super) fn as_type_listing(&self) -> Ref { - match self { - Self::TypeListing(t) => t.borrow(), - _ => panic!("not a MdTypeListing"), - } + pub fn new_child(&self, item: T) -> Self { + let mut child_node = MdNode::new(item); + child_node.parent = Some(Rc::downgrade(&self.0)); + let child_ref = Self(Rc::new(RefCell::new(child_node))); + self.0.borrow_mut().children.push(child_ref.clone()); + child_ref } - pub(super) fn as_type_listing_mut(&self) -> RefMut { - match self { - Self::TypeListing(t) => t.borrow_mut(), - _ => panic!("not a MdTypeListing"), - } + fn borrow(&self) -> cell::Ref { + self.0.borrow() } - #[allow(dead_code)] - pub(super) fn as_interface_func(&self) -> Ref { - match self { - Self::InterfaceFunc(t) => t.borrow(), - _ => panic!("not a MdInterfaceFunc"), - } + fn borrow_mut(&self) -> cell::RefMut { + self.0.borrow_mut() } - pub(super) fn as_interface_func_mut(&self) -> RefMut { - match self { - Self::InterfaceFunc(t) => t.borrow_mut(), - _ => panic!("not a MdInterfaceFunc"), - } + pub fn content_ref(&self) -> cell::Ref { + cell::Ref::map(self.borrow(), |b| { + let r = b.content.as_any(); + r.downcast_ref::().expect("reference is not T type") + }) } - pub(super) fn parent(&self) -> Option> { - match self { - Self::Section(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), - Self::TypeListing(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), - Self::InterfaceFunc(t) => t.borrow().parent.as_ref().and_then(|x| x.upgrade()), + pub fn content_mut(&self) -> cell::RefMut { + cell::RefMut::map(self.borrow_mut(), |b| { + let r = b.content.as_any_mut(); + r.downcast_mut::().expect("reference is not T type") + }) + } + + pub fn get_content(&self) -> Option> { + if self.borrow().content.as_any().is::() { + Some(self.content_ref::()) + } else { + None } } -} -impl fmt::Display for MdElement { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Section(t) => t.borrow().fmt(f), - Self::TypeListing(t) => t.borrow().fmt(f), - Self::InterfaceFunc(t) => t.borrow().fmt(f), + #[allow(unused)] + pub fn get_content_mut(&self) -> Option> { + if self.borrow_mut().content.as_any().is::() { + Some(self.content_mut::()) + } else { + None } } } -#[derive(Debug)] -pub(super) struct MdSection { - pub id: String, - pub title: String, - pub description: Vec, - pub elements: Vec>, - pub parent: Option>, +impl Clone for MdNodeRef { + fn clone(&self) -> Self { + Self(self.0.clone()) + } } -#[derive(Debug)] -pub(super) struct MdParagraph(String); - -impl MdParagraph { - pub fn new>(s: S) -> Self { - Self(s.as_ref().to_owned()) +impl From>> for MdNodeRef { + fn from(node: Rc>) -> Self { + Self(node) } } -impl fmt::Display for MdParagraph { +impl fmt::Display for MdNodeRef { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - writeln!(f, "{}", parse_links(&self.0)) + self.borrow().fmt(f) + } +} + +#[derive(Debug, Default)] +pub(super) struct MdRoot; + +impl MdElement for MdRoot { + fn id(&self) -> Option<&str> { + None + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn fmt(&self, _f: &mut fmt::Formatter, _parents: Vec) -> fmt::Result { + Ok(()) } } +#[derive(Debug, Default)] +pub(super) struct MdSection { + pub id: Option, + pub title: String, +} + impl MdSection { - pub fn new>(id: S, title: S, parent: Option>) -> MdElement { - MdElement::Section(RefCell::new(Self { - id: id.as_ref().to_owned(), + pub fn new>(title: S) -> Self { + Self { + id: None, title: title.as_ref().to_owned(), - description: vec![], - elements: vec![], - parent, - })) + } } } -impl fmt::Display for MdSection { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut heading = "#".to_owned(); - if let Some(parent) = self.parent.as_ref() { - walk_parents(parent, &mut |_| { - heading += "#"; - }); - } - f.write_fmt(format_args!( - "{heading} {link} {title}\n", - heading = heading, - link = gen_link(&self.id), - title = &self.title - ))?; - for para in &self.description { - f.write_fmt(format_args!("{}\n", para))?; - } - for el in &self.elements { - f.write_fmt(format_args!("{}\n", el))?; +impl MdElement for MdSection { + fn id(&self) -> Option<&str> { + self.id.as_ref().map(|s| s.as_str()) + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { + let header = "#".repeat(parents.len()); + f.write_fmt(format_args!("{} ", header))?; + + if let Some(id) = &self.id { + f.write_fmt(format_args!( + " ", + id = id + ))?; } - Ok(()) + + writeln!(f, "{}", self.title) } } #[derive(Debug)] -pub(super) struct MdTypeListing { - pub id: String, - pub r#type: MdType, - pub description: Vec, - pub elements: Vec, - pub parent: Option>, +pub(super) struct MdNamedType { + pub name: String, + pub docs: String, + pub r#type: Option, +} + +impl MdNamedType { + pub fn new, S2: AsRef>(name: S1, docs: S2) -> Self { + Self { + name: name.as_ref().to_owned(), + docs: docs.as_ref().to_owned(), + r#type: None, + } + } } -#[allow(dead_code)] #[derive(Debug)] pub(super) enum MdType { Enum { repr: String }, @@ -209,150 +219,142 @@ pub(super) enum MdType { Flags { repr: String }, Struct, Union, - Handle, Array { r#type: String }, - Pointer { to: String }, - ConstPointer { to: String }, - Builtin { r#type: String }, + Pointer { r#type: String }, + ConstPointer { r#type: String }, + Builtin { repr: String }, + Handle, + Alias { r#type: String }, } -#[derive(Debug)] -pub(super) struct MdBullet { - pub id: String, - pub description: Vec, -} +impl fmt::Display for MdType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Enum { repr } => f.write_fmt(format_args!(": Enum(`{}`)", repr))?, + Self::Int { repr } => f.write_fmt(format_args!(": Int(`{}`)", repr))?, + Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, + Self::Struct => f.write_fmt(format_args!(": Struct"))?, + Self::Union => f.write_fmt(format_args!(": Union"))?, + Self::Array { r#type } => f.write_fmt(format_args!(": `Array<{}>`", r#type))?, + Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, + Self::ConstPointer { r#type } => { + f.write_fmt(format_args!(": `ConstPointer<{}>`", r#type))? + } + Self::Builtin { repr } => f.write_fmt(format_args!(": `{}`", repr))?, + Self::Handle => {} + Self::Alias { r#type } => f.write_fmt(format_args!(": `{}`", r#type))?, + }; -impl MdTypeListing { - pub fn new(id: &str, r#type: MdType, parent: Option>) -> MdElement { - MdElement::TypeListing(RefCell::new(Self { - id: id.to_owned(), - r#type, - description: vec![], - elements: vec![], - parent, - })) + Ok(()) } } -impl fmt::Display for MdTypeListing { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut heading = "#".to_owned(); - if let Some(parent) = self.parent.as_ref() { - walk_parents(parent, &mut |_| { - heading += "#"; - }); - } - // ### `errno` +impl MdElement for MdNamedType { + fn id(&self) -> Option<&str> { + Some(&self.name) + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { + // Firstly, check if our parent is an MdSection or another MdNamedType in which + // case, we're already nesting and should be represented as bullets + let (header, link) = if let Some(p) = parents.first() { + if let Some(_sec) = p.get_content::() { + ("#".repeat(parents.len()), self.name.clone()) + } else if let Some(tt) = p.get_content::() { + ("-".to_owned(), format!("{}.{}", tt.name, self.name)) + } else if let Some(f) = p.get_content::() { + ("-".to_owned(), format!("{}.{}", f.name, self.name)) + } else { + ("#".to_owned(), self.name.clone()) + } + } else { + ("#".to_owned(), self.name.clone()) + }; + f.write_fmt(format_args!( - "{heading} {link} `{id}`\n", - heading = heading, - link = gen_link(&self.id), - id = &self.id + "{header} `{name}`", + header = header, + link = link, + name = self.name, ))?; - // Error codes returned by function... - for para in &self.description { - f.write_fmt(format_args!("{}\n", para))?; - } - // Enum represented by `u16` - // Variants: - let type_specific = match &self.r#type { - MdType::Enum { repr } => format!("Enum represented by `{}`\n\n**Variants:**\n", repr), - MdType::Int { repr } => format!("Int represented by `{}`\n\n**Const:**\n", repr), - MdType::Flags { repr } => format!("Flags represented by `{}`\n\n**Flags:**\n", repr), - MdType::Struct => "\n**Struct members:**\n".to_owned(), - MdType::Union => "\n**Union variants:**\n".to_owned(), - MdType::Handle => "\n**Supertypes:**\n".to_owned(), - MdType::Array { r#type } => format!("Array of `{}`", r#type), - MdType::Pointer { to } => format!("Pointer to `{}`", to), - MdType::ConstPointer { to } => format!("Const pointer to `{}`", to), - MdType::Builtin { r#type } => format!("Builtin type `{}`", r#type), - }; - f.write_str(&type_specific)?; - // - `success` - // No error occurred. System call completed successfully. - for el in &self.elements { - f.write_fmt(format_args!( - "- {link} `{el_id}`\n\n", - link = gen_link(format!("{}.{}", self.id, el.id)), - el_id = el.id - ))?; - for desc in &el.description { - f.write_fmt(format_args!("\t{}\n", desc))?; - } + + if let Some(tt) = &self.r#type { + f.write_fmt(format_args!("{}", tt))?; } - Ok(()) + + writeln!(f, "\n{}", self.docs) } } #[derive(Debug)] -pub(super) struct MdInterfaceFunc { - pub id: String, - pub description: Vec, - pub parameters: Vec, - pub results: Vec, - pub parent: Option>, +pub(super) struct MdFunc { + pub name: String, + pub inputs: Vec<(String, String)>, + pub outputs: Vec, + pub docs: String, } -impl MdInterfaceFunc { - pub fn new(id: &str, parent: Option>) -> MdElement { - MdElement::InterfaceFunc(RefCell::new(Self { - id: id.to_owned(), - description: vec![], - parameters: vec![], - results: vec![], - parent, - })) +impl MdFunc { + pub fn new, S2: AsRef>(name: S1, docs: S2) -> Self { + Self { + name: name.as_ref().to_owned(), + inputs: vec![], + outputs: vec![], + docs: docs.as_ref().to_owned(), + } } } -impl fmt::Display for MdInterfaceFunc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut heading = "#".to_owned(); - if let Some(parent) = self.parent.as_ref() { - walk_parents(parent, &mut |_| { - heading += "#"; - }); - } - // ### `args_get` +impl MdElement for MdFunc { + fn id(&self) -> Option<&str> { + Some(&self.name) + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { + // Expand header + let header = "#".repeat(parents.len()); + // Expand inputs + let inputs = self + .inputs + .iter() + .map(|(name, r#type)| format!("{}: `{}`", name, r#type)) + .collect::>() + .join(", "); + // Expand outputs + let outputs: Vec<_> = self + .outputs + .iter() + .map(|r#type| format!("`{}`", r#type)) + .collect(); + let outputs = match outputs.len() { + 0 => "".to_owned(), + 1 => format!(" -> {}", outputs[0]), + _ => format!(" -> ({})", outputs.join(", ")), + }; f.write_fmt(format_args!( - "{heading} `{id}`\n\n", - heading = heading, - id = self.id + "{header} Fn {name}({inputs}){outputs}", + header = header, + name = self.name, + inputs = inputs, + outputs = outputs, ))?; - // Read command-line argument data... - for desc in &self.description { - f.write_fmt(format_args!("{}\n", desc))?; - } - // Parameters: - // * `argv` - // `argv` has type... - if !self.parameters.is_empty() { - f.write_str("**Parameters:**\n\n")?; - for param in &self.parameters { - f.write_fmt(format_args!( - "- {link} `{param_id}`\n\n", - link = gen_link(format!("{}.{}", self.id, param.id)), - param_id = param.id - ))?; - for desc in ¶m.description { - f.write_fmt(format_args!("\t{}\n", desc))?; - } - } - } - // Results: - // * `error` - // `error` has type `errno` - f.write_str("**Results:**\n\n")?; - for result in &self.results { - f.write_fmt(format_args!( - "- {link} `{res_id}`\n\n", - link = gen_link(format!("{}.{}", self.id, result.id)), - res_id = result.id - ))?; - for desc in &result.description { - f.write_fmt(format_args!("\t{}\n", desc))?; - } - } - Ok(()) + + writeln!(f, "\n{}", self.docs) } } diff --git a/proposals/filesystem/tools/witx/src/docs/mod.rs b/proposals/filesystem/tools/witx/src/docs/mod.rs index ebf720416..e0b962ce2 100644 --- a/proposals/filesystem/tools/witx/src/docs/mod.rs +++ b/proposals/filesystem/tools/witx/src/docs/mod.rs @@ -1,421 +1,18 @@ +mod ast; mod md; -use crate::ast::*; -use crate::polyfill::*; -use crate::RepEquality; -use md::*; -use std::rc::{Rc, Weak}; +use crate::ast::Document; +use md::{MdNodeRef, MdRoot, ToMarkdown}; pub trait Documentation { fn to_md(&self) -> String; } -trait ToMarkdown { - fn gen(&self, _parent: Option>) -> Rc; -} - impl Documentation for Document { fn to_md(&self) -> String { - format!("{}", self.gen(None)) - } -} - -impl ToMarkdown for Document { - fn gen(&self, parent: Option>) -> Rc { - let doc = Rc::new(MdSection::new("root", "Root", parent)); - let types = Rc::new(MdSection::new("types", "Types", Some(Rc::downgrade(&doc)))); - for typename in self.typenames() { - types - .as_section_mut() - .elements - .push(typename.gen(Some(Rc::downgrade(&types)))); - } - let modules = Rc::new(MdSection::new( - "modules", - "Modules", - Some(Rc::downgrade(&doc)), - )); - for module in self.modules() { - modules - .as_section_mut() - .elements - .push(module.gen(Some(Rc::downgrade(&modules)))); - } - doc.as_section_mut() - .elements - .extend_from_slice(&[types, modules]); - doc - } -} - -impl BuiltinType { - pub fn type_name(&self) -> &'static str { - match self { - BuiltinType::String => "string", - BuiltinType::Char8 => "char8", - BuiltinType::USize => "usize", - BuiltinType::U8 => "u8", - BuiltinType::U16 => "u16", - BuiltinType::U32 => "u32", - BuiltinType::U64 => "u64", - BuiltinType::S8 => "s8", - BuiltinType::S16 => "s16", - BuiltinType::S32 => "s32", - BuiltinType::S64 => "s64", - BuiltinType::F32 => "f32", - BuiltinType::F64 => "f64", - } - } -} - -impl ToMarkdown for NamedType { - fn gen(&self, parent: Option>) -> Rc { - match &self.tref { - TypeRef::Value(v) => { - let md_type = MdType::from(&**v); - let mut elements: Vec<_> = match &**v { - Type::Enum(a) => a.variants.iter().map(MdBullet::from).collect(), - Type::Int(a) => a.consts.iter().map(MdBullet::from).collect(), - Type::Flags(a) => a.flags.iter().map(MdBullet::from).collect(), - Type::Struct(a) => a.members.iter().map(MdBullet::from).collect(), - Type::Union(a) => a.variants.iter().map(MdBullet::from).collect(), - Type::Handle(a) => a.supertypes.iter().map(MdBullet::from).collect(), - _ => vec![], - }; - let listing = Rc::new(MdTypeListing::new(self.name.as_str(), md_type, parent)); - listing - .as_type_listing_mut() - .description - .push(MdParagraph::new(&self.docs)); - listing.as_type_listing_mut().elements.append(&mut elements); - listing - } - TypeRef::Name(n) => { - let sec = Rc::new(MdSection::new( - self.name.as_str(), - self.name.as_str(), - parent, - )); - sec.as_section_mut().description.append(&mut vec![ - MdParagraph::new(&self.docs), - MdParagraph::new(format!("Alias to {}", n.name.as_str())), - ]); - sec - } - } - } -} - -impl From<&Type> for MdType { - fn from(r#type: &Type) -> Self { - match r#type { - Type::Enum(a) => Self::Enum { - repr: a.repr.type_name().to_owned(), - }, - Type::Int(a) => Self::Int { - repr: a.repr.type_name().to_owned(), - }, - Type::Flags(a) => Self::Flags { - repr: a.repr.type_name().to_owned(), - }, - Type::Struct(_) => Self::Struct, - Type::Union(_) => Self::Union, - Type::Handle(_) => Self::Handle, - Type::Array(a) => Self::Array { - r#type: a.type_name().to_owned(), - }, - Type::Pointer(a) => Self::Pointer { - to: a.type_name().to_owned(), - }, - Type::ConstPointer(a) => Self::ConstPointer { - to: a.type_name().to_owned(), - }, - Type::Builtin(a) => Self::Builtin { - r#type: a.type_name().to_owned(), - }, - } - } -} - -macro_rules! impl_mdbullet { - ($from:ty) => { - impl From<$from> for MdBullet { - fn from(f: $from) -> Self { - Self { - id: f.name.as_str().to_owned(), - description: vec![MdParagraph::new(&f.docs)], - } - } - } - }; -} - -impl_mdbullet!(&EnumVariant); -impl_mdbullet!(&IntConst); -impl_mdbullet!(&FlagsMember); -impl_mdbullet!(&StructMember); -impl_mdbullet!(&UnionVariant); - -impl From<&TypeRef> for MdBullet { - fn from(t: &TypeRef) -> Self { - Self { - id: t.type_name().to_owned(), - description: vec![], - } - } -} - -impl TypeRef { - pub fn type_name(&self) -> String { - match self { - TypeRef::Name(n) => n.name.as_str().to_string(), - TypeRef::Value(ref v) => match &**v { - Type::Array(a) => format!("Array<{}>", a.type_name()), - Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), - Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), - Type::Builtin(b) => b.type_name().to_string(), - Type::Enum { .. } - | Type::Int { .. } - | Type::Flags { .. } - | Type::Struct { .. } - | Type::Union { .. } - | Type::Handle { .. } => { - unimplemented!("type_name of anonymous compound datatypes") - } - }, - } - } -} - -impl IntRepr { - fn type_name(&self) -> &'static str { - match self { - IntRepr::U8 => "u8", - IntRepr::U16 => "u16", - IntRepr::U32 => "u32", - IntRepr::U64 => "u64", - } - } -} - -impl ToMarkdown for Module { - fn gen(&self, parent: Option>) -> Rc { - let sec = Rc::new(MdSection::new( - self.name.as_str(), - &format!("`{}`", self.name.as_str()), - parent, - )); - let imports = Rc::new(MdSection::new( - "imports", - "Imports", - Some(Rc::downgrade(&sec)), - )); - // TODO - // This should probably be done using something more specific - // than a generic MdSection - for import in self.imports() { - let desc = match import.variant { - ModuleImportVariant::Memory => format!("* {}: Memory", import.name.as_str()), - }; - imports - .as_section_mut() - .description - .push(MdParagraph::new(desc)); - } - sec.as_section_mut().elements.push(imports); - let funcs = Rc::new(MdSection::new( - "functions", - "Functions", - Some(Rc::downgrade(&sec)), - )); - funcs - .as_section_mut() - .elements - .extend(self.funcs().map(|f| f.gen(Some(Rc::downgrade(&funcs))))); - sec.as_section_mut().elements.push(funcs); - sec - } -} - -impl ToMarkdown for InterfaceFunc { - fn gen(&self, parent: Option>) -> Rc { - let func = Rc::new(MdInterfaceFunc::new(self.name.as_str(), parent)); - func.as_interface_func_mut() - .description - .push(MdParagraph::new(&self.docs)); - func.as_interface_func_mut() - .parameters - .extend(self.params.iter().map(MdBullet::from)); - func.as_interface_func_mut() - .results - .extend(self.results.iter().map(MdBullet::from)); - func - } -} - -impl From<&InterfaceFuncParam> for MdBullet { - fn from(param: &InterfaceFuncParam) -> Self { - Self { - id: param.name.as_str().to_owned(), - description: vec![ - MdParagraph::new(format!( - "`{}` has type `{}`", - param.name.as_str(), - param.tref.type_name(), - )), - MdParagraph::new(format!("{}", param.docs)), - ], - } - } -} - -// TODO -// Implement ToMarkdown for Polyfill -impl Documentation for Polyfill { - fn to_md(&self) -> String { - let module_docs = self - .modules - .iter() - .map(|m| m.to_md()) - .collect::>() - .join("\n"); - let type_docs = self - .type_polyfills() - .iter() - .filter_map(|t| { - if t.repeq() == RepEquality::Eq { - None - } else { - Some(t.to_md()) - } - }) - .collect::>() - .join("\n"); - format!( - "# Modules\n{}\n# Type Conversions\n{}\n", - module_docs, type_docs - ) + let root = MdNodeRef::new(MdRoot::default()); + self.generate(root.clone()); + format!("{}", root) } } -impl Documentation for ModulePolyfill { - fn to_md(&self) -> String { - format!( - "## `{}` in terms of `{}`\n{}", - self.new.name.as_str(), - self.old.name.as_str(), - self.funcs - .iter() - .map(|f| f.to_md()) - .collect::>() - .join("\n"), - ) - } -} - -impl Documentation for FuncPolyfill { - fn to_md(&self) -> String { - if self.full_compat() { - format!("* `{}`: full compatibility", self.new.name.as_str()) - } else { - let name = if self.new.name != self.old.name { - format!( - "* `{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("* `{}`", self.new.name.as_str()) - }; - let mut contents = Vec::new(); - for p in self.mapped_params.iter() { - contents.push(if !p.full_compat() { - format!("param {}", p.to_md()) - } else { - format!("param `{}`: compatible", p.new.name.as_str()) - }) - } - for u in self.unknown_params.iter() { - contents.push(format!( - "{} param `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - for r in self.mapped_results.iter() { - contents.push(if !r.full_compat() { - format!("result {}", r.to_md()) - } else { - format!("result `{}`: compatible", r.new.name.as_str()) - }) - } - for u in self.unknown_results.iter() { - contents.push(format!( - "{} result `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - let contents = if contents.is_empty() { - String::new() - } else { - format!(":\n - {}", contents.join("\n - ")) - }; - format!("{}{}", name, contents) - } - } -} - -impl Documentation for ParamPolyfill { - fn to_md(&self) -> String { - let name = if self.new.name != self.old.name { - format!( - "`{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("`{}`", self.new.name.as_str()) - }; - let repr = match self.repeq() { - RepEquality::Eq => "compatible types".to_string(), - RepEquality::Superset => format!( - "`{}` is superset-compatible with `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - RepEquality::NotEq => format!( - "`{}` is incompatible with new `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - }; - format!("{}: {}", name, repr) - } -} - -impl Documentation for TypePolyfill { - fn to_md(&self) -> String { - fn repeq_name(r: RepEquality) -> &'static str { - match r { - RepEquality::Eq => ": compatible", - RepEquality::Superset => ": superset", - RepEquality::NotEq => "", - } - } - match self { - TypePolyfill::OldToNew(o, n) => format!( - "* old `{}` => new `{}`{}", - o.type_name(), - n.type_name(), - repeq_name(self.repeq()) - ), - TypePolyfill::NewToOld(n, o) => format!( - "* new `{}` => old `{}`{}", - n.type_name(), - o.type_name(), - repeq_name(self.repeq()) - ), - } - } -} From ad56deb33ed63bfbffcaaaf962ab2b5dbdcecee0 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 00:15:02 +0100 Subject: [PATCH 0460/1772] Fix formatting --- proposals/clocks/tools/witx/src/docs/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/clocks/tools/witx/src/docs/mod.rs b/proposals/clocks/tools/witx/src/docs/mod.rs index e0b962ce2..f1ddc7c74 100644 --- a/proposals/clocks/tools/witx/src/docs/mod.rs +++ b/proposals/clocks/tools/witx/src/docs/mod.rs @@ -15,4 +15,3 @@ impl Documentation for Document { format!("{}", root) } } - From 32db69117498e72d3910ce31409d6fa744be62b6 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 00:15:02 +0100 Subject: [PATCH 0461/1772] Fix formatting --- proposals/random/tools/witx/src/docs/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/random/tools/witx/src/docs/mod.rs b/proposals/random/tools/witx/src/docs/mod.rs index e0b962ce2..f1ddc7c74 100644 --- a/proposals/random/tools/witx/src/docs/mod.rs +++ b/proposals/random/tools/witx/src/docs/mod.rs @@ -15,4 +15,3 @@ impl Documentation for Document { format!("{}", root) } } - From 19a506dc9447b49b0fdb1d74456295c09f40fceb Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 00:15:02 +0100 Subject: [PATCH 0462/1772] Fix formatting --- proposals/filesystem/tools/witx/src/docs/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/src/docs/mod.rs b/proposals/filesystem/tools/witx/src/docs/mod.rs index e0b962ce2..f1ddc7c74 100644 --- a/proposals/filesystem/tools/witx/src/docs/mod.rs +++ b/proposals/filesystem/tools/witx/src/docs/mod.rs @@ -15,4 +15,3 @@ impl Documentation for Document { format!("{}", root) } } - From b6acb876ed11980c19e608a28ea51f5b64a8d01f Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 00:52:26 +0100 Subject: [PATCH 0463/1772] A couple minor nitpicks * cleanup `MdNodeRef` impls * prettify formatting of `InterfaceFunc` by adding a line separator * auto-generate links for type aliases --- proposals/clocks/tools/witx/src/docs/md.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index 58fbbb16a..51db1b47a 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -69,7 +69,7 @@ impl MdNodeRef { let mut child_node = MdNode::new(item); child_node.parent = Some(Rc::downgrade(&self.0)); let child_ref = Self(Rc::new(RefCell::new(child_node))); - self.0.borrow_mut().children.push(child_ref.clone()); + self.borrow_mut().children.push(child_ref.clone()); child_ref } @@ -242,7 +242,9 @@ impl fmt::Display for MdType { } Self::Builtin { repr } => f.write_fmt(format_args!(": `{}`", repr))?, Self::Handle => {} - Self::Alias { r#type } => f.write_fmt(format_args!(": `{}`", r#type))?, + Self::Alias { r#type } => { + f.write_fmt(format_args!(": [`{tt}`](#{tt})", tt = r#type))? + } }; Ok(()) @@ -347,6 +349,9 @@ impl MdElement for MdFunc { 1 => format!(" -> {}", outputs[0]), _ => format!(" -> ({})", outputs.join(", ")), }; + // Format + writeln!(f, "\n---\n")?; + f.write_fmt(format_args!( "{header} Fn {name}({inputs}){outputs}", header = header, From 0a2238b8bef46dddb9abf193f147b08b6ce2280a Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 00:52:26 +0100 Subject: [PATCH 0464/1772] A couple minor nitpicks * cleanup `MdNodeRef` impls * prettify formatting of `InterfaceFunc` by adding a line separator * auto-generate links for type aliases --- proposals/random/tools/witx/src/docs/md.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index 58fbbb16a..51db1b47a 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -69,7 +69,7 @@ impl MdNodeRef { let mut child_node = MdNode::new(item); child_node.parent = Some(Rc::downgrade(&self.0)); let child_ref = Self(Rc::new(RefCell::new(child_node))); - self.0.borrow_mut().children.push(child_ref.clone()); + self.borrow_mut().children.push(child_ref.clone()); child_ref } @@ -242,7 +242,9 @@ impl fmt::Display for MdType { } Self::Builtin { repr } => f.write_fmt(format_args!(": `{}`", repr))?, Self::Handle => {} - Self::Alias { r#type } => f.write_fmt(format_args!(": `{}`", r#type))?, + Self::Alias { r#type } => { + f.write_fmt(format_args!(": [`{tt}`](#{tt})", tt = r#type))? + } }; Ok(()) @@ -347,6 +349,9 @@ impl MdElement for MdFunc { 1 => format!(" -> {}", outputs[0]), _ => format!(" -> ({})", outputs.join(", ")), }; + // Format + writeln!(f, "\n---\n")?; + f.write_fmt(format_args!( "{header} Fn {name}({inputs}){outputs}", header = header, From 4ce16545d6fac14f5e38da06e635f266a4ce0422 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 00:52:26 +0100 Subject: [PATCH 0465/1772] A couple minor nitpicks * cleanup `MdNodeRef` impls * prettify formatting of `InterfaceFunc` by adding a line separator * auto-generate links for type aliases --- proposals/filesystem/tools/witx/src/docs/md.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index 58fbbb16a..51db1b47a 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -69,7 +69,7 @@ impl MdNodeRef { let mut child_node = MdNode::new(item); child_node.parent = Some(Rc::downgrade(&self.0)); let child_ref = Self(Rc::new(RefCell::new(child_node))); - self.0.borrow_mut().children.push(child_ref.clone()); + self.borrow_mut().children.push(child_ref.clone()); child_ref } @@ -242,7 +242,9 @@ impl fmt::Display for MdType { } Self::Builtin { repr } => f.write_fmt(format_args!(": `{}`", repr))?, Self::Handle => {} - Self::Alias { r#type } => f.write_fmt(format_args!(": `{}`", r#type))?, + Self::Alias { r#type } => { + f.write_fmt(format_args!(": [`{tt}`](#{tt})", tt = r#type))? + } }; Ok(()) @@ -347,6 +349,9 @@ impl MdElement for MdFunc { 1 => format!(" -> {}", outputs[0]), _ => format!(" -> ({})", outputs.join(", ")), }; + // Format + writeln!(f, "\n---\n")?; + f.write_fmt(format_args!( "{header} Fn {name}({inputs}){outputs}", header = header, From ee582f8596475f5069f0a1a8adee8fad7f8ccd8e Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 19:32:33 +0100 Subject: [PATCH 0466/1772] Remove `fmt` from `MdElement` trait This commit shuffles a few things around, and at the expense of compactness, yet now more explicitly, makes each type adhering to `MdElement` trait define their own `id` and `header` at construction rather than rendering to Markdown. This way, even though there is more code repetition, we get also more control over what each traversed item in the AST gets. Furthermore, rendering to Markdown gets drastically simplified as it is no longer necessary to match all possible types held my `MdNode` when formatting each element, and thus, `MdElement::fmt` can be and is removed in favour of using the `fmt::Display` trait for all elements (where applicable that is). --- proposals/clocks/tools/witx/src/docs/ast.rs | 120 ++++++++++++---- proposals/clocks/tools/witx/src/docs/md.rs | 146 ++++++++++---------- 2 files changed, 169 insertions(+), 97 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index 641673775..cce4a8ed6 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -6,15 +6,22 @@ use crate::RepEquality; impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { - let types = node.new_child(MdSection::new("Types")); + let header = "#".repeat(node.borrow().parents().len() + 1); + let types = node.new_child(MdSection::new(header.as_str(), "Types")); for d in self.typenames() { - let child = types.new_child(MdNamedType::new(d.name.as_str(), &d.docs)); + let name = d.name.as_str(); + let child = types.new_child(MdNamedType::new( + (header.clone() + "#").as_str(), + name, + name, + &d.docs, + )); d.generate(child.clone()); } - let modules = node.new_child(MdSection::new("Modules")); + let modules = node.new_child(MdSection::new(header.as_str(), "Modules")); for d in self.modules() { - let mut content = MdSection::new(d.name.as_str()); + let mut content = MdSection::new((header.clone() + "#").as_str(), d.name.as_str()); content.id = Some(d.name.as_str().to_owned()); let child = modules.new_child(content); d.generate(child.clone()); @@ -76,10 +83,17 @@ impl ToMarkdown for Type { impl ToMarkdown for EnumDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Variants")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Variants")); for variant in &self.variants { - node.new_child(MdNamedType::new(variant.name.as_str(), &variant.docs)); + let name = variant.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); } node.content_mut::().r#type = Some(MdType::Enum { @@ -90,10 +104,17 @@ impl ToMarkdown for EnumDatatype { impl ToMarkdown for IntDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Consts")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Consts")); for r#const in &self.consts { - let tt = MdNamedType::new(r#const.name.as_str(), &r#const.docs); + let name = r#const.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let tt = MdNamedType::new("-", id.as_str(), name, &r#const.docs); // TODO handle r#const.value node.new_child(tt); } @@ -106,10 +127,17 @@ impl ToMarkdown for IntDatatype { impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Flags")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Flags")); for flag in &self.flags { - node.new_child(MdNamedType::new(flag.name.as_str(), &flag.docs)); + let name = flag.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + node.new_child(MdNamedType::new("-", id.as_str(), name, &flag.docs)); } node.content_mut::().r#type = Some(MdType::Flags { @@ -120,10 +148,17 @@ impl ToMarkdown for FlagsDatatype { impl ToMarkdown for StructDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Struct members")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Struct members")); for member in &self.members { - let n = node.new_child(MdNamedType::new(member.name.as_str(), &member.docs)); + let name = member.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let n = node.new_child(MdNamedType::new("-", id.as_str(), name, &member.docs)); member.tref.generate(n.clone()); } @@ -133,10 +168,17 @@ impl ToMarkdown for StructDatatype { impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Union variants")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Union variants")); for variant in &self.variants { - let n = node.new_child(MdNamedType::new(variant.name.as_str(), &variant.docs)); + let name = variant.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let n = node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); variant.tref.generate(n.clone()); } @@ -147,22 +189,30 @@ impl ToMarkdown for UnionDatatype { impl ToMarkdown for HandleDatatype { fn generate(&self, node: MdNodeRef) { // TODO this needs more work - node.new_child(MdSection::new("Supertypes")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Supertypes")); node.content_mut::().r#type = Some(MdType::Handle); } } impl ToMarkdown for Module { fn generate(&self, node: MdNodeRef) { - let imports = node.new_child(MdSection::new("Imports")); + let header = "#".repeat(node.borrow().parents().len() + 1); + let imports = node.new_child(MdSection::new(header.as_str(), "Imports")); for import in self.imports() { - let child = imports.new_child(MdSection::default()); + let child = imports.new_child(MdSection::new((header.clone() + "#").as_str(), "")); import.generate(child.clone()); } - let funcs = node.new_child(MdSection::new("Functions")); + let funcs = node.new_child(MdSection::new(header.as_str(), "Functions")); for func in self.funcs() { - let child = funcs.new_child(MdFunc::new(func.name.as_str(), &func.docs)); + let name = func.name.as_str(); + let child = funcs.new_child(MdFunc::new( + (header.clone() + "#").as_str(), + name, + name, + &func.docs, + )); func.generate(child.clone()); } } @@ -180,9 +230,21 @@ impl ToMarkdown for ModuleImport { impl ToMarkdown for InterfaceFunc { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Params")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Params")); for param in &self.params { - let child = node.new_child(MdNamedType::new(param.name.as_str(), param.name.as_str())); + let name = param.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let child = node.new_child(MdNamedType::new( + "-", + id.as_str(), + name, + param.name.as_str(), + )); param.generate(child.clone()); // TODO should this be expanded recursively instead of using flattened type names? node.content_mut::() @@ -190,10 +252,20 @@ impl ToMarkdown for InterfaceFunc { .push((param.name.as_str().to_owned(), param.tref.type_name())); } - node.new_child(MdSection::new("Results")); + node.new_child(MdSection::new(header.as_str(), "Results")); for result in &self.results { - let child = - node.new_child(MdNamedType::new(result.name.as_str(), result.name.as_str())); + let name = result.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let child = node.new_child(MdNamedType::new( + "-", + id.as_str(), + name, + result.name.as_str(), + )); result.generate(child.clone()); // TODO should this be expanded recursively instead of using flattened type names? node.content_mut::() diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index 51db1b47a..adcb0f412 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -9,20 +9,27 @@ pub(super) trait ToMarkdown { fn generate(&self, node: MdNodeRef); } -pub(super) trait MdElement: fmt::Debug + 'static { +pub(super) trait MdElement: fmt::Display + fmt::Debug + 'static { fn id(&self) -> Option<&str>; + fn docs(&self) -> Option<&str>; fn as_any(&self) -> &dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any; - fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result; } #[derive(Debug)] -struct MdNode { +pub(super) struct MdNode { content: Box, parent: Option>>, children: Vec, } +fn walk_parents(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { + if let Some(parent) = parent.and_then(|x| x.upgrade()) { + cb(parent.clone().into()); + walk_parents(parent.borrow().parent.as_ref(), cb) + } +} + impl MdNode { fn new(item: T) -> Self { Self { @@ -31,23 +38,17 @@ impl MdNode { children: vec![], } } -} -fn walk_parents(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { - if let Some(parent) = parent.and_then(|x| x.upgrade()) { - cb(parent.clone().into()); - walk_parents(parent.borrow().parent.as_ref(), cb) + pub fn parents(&self) -> Vec { + let mut parents = Vec::new(); + walk_parents(self.parent.as_ref(), &mut |parent| parents.push(parent)); + parents } } impl fmt::Display for MdNode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut parents = Vec::new(); - walk_parents(self.parent.as_ref(), &mut |parent| { - parents.push(parent); - }); - - MdElement::fmt(&*self.content, f, parents)?; + self.content.fmt(f)?; for child in &self.children { child.fmt(f)?; @@ -73,19 +74,16 @@ impl MdNodeRef { child_ref } - fn borrow(&self) -> cell::Ref { + pub fn borrow(&self) -> cell::Ref { self.0.borrow() } - fn borrow_mut(&self) -> cell::RefMut { + pub fn borrow_mut(&self) -> cell::RefMut { self.0.borrow_mut() } - pub fn content_ref(&self) -> cell::Ref { - cell::Ref::map(self.borrow(), |b| { - let r = b.content.as_any(); - r.downcast_ref::().expect("reference is not T type") - }) + pub fn any_ref(&self) -> cell::Ref> { + cell::Ref::map(self.borrow(), |b| &b.content) } pub fn content_mut(&self) -> cell::RefMut { @@ -94,23 +92,6 @@ impl MdNodeRef { r.downcast_mut::().expect("reference is not T type") }) } - - pub fn get_content(&self) -> Option> { - if self.borrow().content.as_any().is::() { - Some(self.content_ref::()) - } else { - None - } - } - - #[allow(unused)] - pub fn get_content_mut(&self) -> Option> { - if self.borrow_mut().content.as_any().is::() { - Some(self.content_mut::()) - } else { - None - } - } } impl Clone for MdNodeRef { @@ -139,6 +120,10 @@ impl MdElement for MdRoot { None } + fn docs(&self) -> Option<&str> { + None + } + fn as_any(&self) -> &dyn Any { self } @@ -146,21 +131,25 @@ impl MdElement for MdRoot { fn as_any_mut(&mut self) -> &mut dyn Any { self } +} - fn fmt(&self, _f: &mut fmt::Formatter, _parents: Vec) -> fmt::Result { +impl fmt::Display for MdRoot { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { Ok(()) } } -#[derive(Debug, Default)] +#[derive(Debug)] pub(super) struct MdSection { + pub header: String, pub id: Option, pub title: String, } impl MdSection { - pub fn new>(title: S) -> Self { + pub fn new>(header: S, title: S) -> Self { Self { + header: header.as_ref().to_owned(), id: None, title: title.as_ref().to_owned(), } @@ -172,6 +161,10 @@ impl MdElement for MdSection { self.id.as_ref().map(|s| s.as_str()) } + fn docs(&self) -> Option<&str> { + None + } + fn as_any(&self) -> &dyn Any { self } @@ -179,10 +172,11 @@ impl MdElement for MdSection { fn as_any_mut(&mut self) -> &mut dyn Any { self } +} - fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { - let header = "#".repeat(parents.len()); - f.write_fmt(format_args!("{} ", header))?; +impl fmt::Display for MdSection { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_fmt(format_args!("{} ", self.header))?; if let Some(id) = &self.id { f.write_fmt(format_args!( @@ -197,14 +191,18 @@ impl MdElement for MdSection { #[derive(Debug)] pub(super) struct MdNamedType { + pub header: String, + pub id: String, pub name: String, pub docs: String, pub r#type: Option, } impl MdNamedType { - pub fn new, S2: AsRef>(name: S1, docs: S2) -> Self { + pub fn new>(header: S, id: S, name: S, docs: S) -> Self { Self { + header: header.as_ref().to_owned(), + id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), docs: docs.as_ref().to_owned(), r#type: None, @@ -212,6 +210,9 @@ impl MdNamedType { } } +// TODO `MdType` should probably store `TypeRef` and recursively +// unwind itself into final `String` representation rather than +// being outright flattened. #[derive(Debug)] pub(super) enum MdType { Enum { repr: String }, @@ -253,7 +254,11 @@ impl fmt::Display for MdType { impl MdElement for MdNamedType { fn id(&self) -> Option<&str> { - Some(&self.name) + Some(&self.id) + } + + fn docs(&self) -> Option<&str> { + Some(&self.docs) } fn as_any(&self) -> &dyn Any { @@ -263,28 +268,14 @@ impl MdElement for MdNamedType { fn as_any_mut(&mut self) -> &mut dyn Any { self } +} - fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { - // Firstly, check if our parent is an MdSection or another MdNamedType in which - // case, we're already nesting and should be represented as bullets - let (header, link) = if let Some(p) = parents.first() { - if let Some(_sec) = p.get_content::() { - ("#".repeat(parents.len()), self.name.clone()) - } else if let Some(tt) = p.get_content::() { - ("-".to_owned(), format!("{}.{}", tt.name, self.name)) - } else if let Some(f) = p.get_content::() { - ("-".to_owned(), format!("{}.{}", f.name, self.name)) - } else { - ("#".to_owned(), self.name.clone()) - } - } else { - ("#".to_owned(), self.name.clone()) - }; - +impl fmt::Display for MdNamedType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_fmt(format_args!( - "{header} `{name}`", - header = header, - link = link, + "{header} `{name}`", + header = self.header, + id = self.id, name = self.name, ))?; @@ -298,6 +289,8 @@ impl MdElement for MdNamedType { #[derive(Debug)] pub(super) struct MdFunc { + pub header: String, + pub id: String, pub name: String, pub inputs: Vec<(String, String)>, pub outputs: Vec, @@ -305,8 +298,10 @@ pub(super) struct MdFunc { } impl MdFunc { - pub fn new, S2: AsRef>(name: S1, docs: S2) -> Self { + pub fn new>(header: S, id: S, name: S, docs: S) -> Self { Self { + header: header.as_ref().to_owned(), + id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), inputs: vec![], outputs: vec![], @@ -317,7 +312,11 @@ impl MdFunc { impl MdElement for MdFunc { fn id(&self) -> Option<&str> { - Some(&self.name) + Some(&self.id) + } + + fn docs(&self) -> Option<&str> { + Some(&self.docs) } fn as_any(&self) -> &dyn Any { @@ -327,10 +326,10 @@ impl MdElement for MdFunc { fn as_any_mut(&mut self) -> &mut dyn Any { self } +} - fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { - // Expand header - let header = "#".repeat(parents.len()); +impl fmt::Display for MdFunc { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // Expand inputs let inputs = self .inputs @@ -353,8 +352,9 @@ impl MdElement for MdFunc { writeln!(f, "\n---\n")?; f.write_fmt(format_args!( - "{header} Fn {name}({inputs}){outputs}", - header = header, + "{header} Fn {name}({inputs}){outputs}", + header = self.header, + id = self.id, name = self.name, inputs = inputs, outputs = outputs, From 0f5fe9c3cd21b9bd362fbc399d4d1cc0c1f0ed77 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 19:32:33 +0100 Subject: [PATCH 0467/1772] Remove `fmt` from `MdElement` trait This commit shuffles a few things around, and at the expense of compactness, yet now more explicitly, makes each type adhering to `MdElement` trait define their own `id` and `header` at construction rather than rendering to Markdown. This way, even though there is more code repetition, we get also more control over what each traversed item in the AST gets. Furthermore, rendering to Markdown gets drastically simplified as it is no longer necessary to match all possible types held my `MdNode` when formatting each element, and thus, `MdElement::fmt` can be and is removed in favour of using the `fmt::Display` trait for all elements (where applicable that is). --- proposals/random/tools/witx/src/docs/ast.rs | 120 ++++++++++++---- proposals/random/tools/witx/src/docs/md.rs | 146 ++++++++++---------- 2 files changed, 169 insertions(+), 97 deletions(-) diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index 641673775..cce4a8ed6 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -6,15 +6,22 @@ use crate::RepEquality; impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { - let types = node.new_child(MdSection::new("Types")); + let header = "#".repeat(node.borrow().parents().len() + 1); + let types = node.new_child(MdSection::new(header.as_str(), "Types")); for d in self.typenames() { - let child = types.new_child(MdNamedType::new(d.name.as_str(), &d.docs)); + let name = d.name.as_str(); + let child = types.new_child(MdNamedType::new( + (header.clone() + "#").as_str(), + name, + name, + &d.docs, + )); d.generate(child.clone()); } - let modules = node.new_child(MdSection::new("Modules")); + let modules = node.new_child(MdSection::new(header.as_str(), "Modules")); for d in self.modules() { - let mut content = MdSection::new(d.name.as_str()); + let mut content = MdSection::new((header.clone() + "#").as_str(), d.name.as_str()); content.id = Some(d.name.as_str().to_owned()); let child = modules.new_child(content); d.generate(child.clone()); @@ -76,10 +83,17 @@ impl ToMarkdown for Type { impl ToMarkdown for EnumDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Variants")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Variants")); for variant in &self.variants { - node.new_child(MdNamedType::new(variant.name.as_str(), &variant.docs)); + let name = variant.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); } node.content_mut::().r#type = Some(MdType::Enum { @@ -90,10 +104,17 @@ impl ToMarkdown for EnumDatatype { impl ToMarkdown for IntDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Consts")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Consts")); for r#const in &self.consts { - let tt = MdNamedType::new(r#const.name.as_str(), &r#const.docs); + let name = r#const.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let tt = MdNamedType::new("-", id.as_str(), name, &r#const.docs); // TODO handle r#const.value node.new_child(tt); } @@ -106,10 +127,17 @@ impl ToMarkdown for IntDatatype { impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Flags")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Flags")); for flag in &self.flags { - node.new_child(MdNamedType::new(flag.name.as_str(), &flag.docs)); + let name = flag.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + node.new_child(MdNamedType::new("-", id.as_str(), name, &flag.docs)); } node.content_mut::().r#type = Some(MdType::Flags { @@ -120,10 +148,17 @@ impl ToMarkdown for FlagsDatatype { impl ToMarkdown for StructDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Struct members")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Struct members")); for member in &self.members { - let n = node.new_child(MdNamedType::new(member.name.as_str(), &member.docs)); + let name = member.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let n = node.new_child(MdNamedType::new("-", id.as_str(), name, &member.docs)); member.tref.generate(n.clone()); } @@ -133,10 +168,17 @@ impl ToMarkdown for StructDatatype { impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Union variants")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Union variants")); for variant in &self.variants { - let n = node.new_child(MdNamedType::new(variant.name.as_str(), &variant.docs)); + let name = variant.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let n = node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); variant.tref.generate(n.clone()); } @@ -147,22 +189,30 @@ impl ToMarkdown for UnionDatatype { impl ToMarkdown for HandleDatatype { fn generate(&self, node: MdNodeRef) { // TODO this needs more work - node.new_child(MdSection::new("Supertypes")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Supertypes")); node.content_mut::().r#type = Some(MdType::Handle); } } impl ToMarkdown for Module { fn generate(&self, node: MdNodeRef) { - let imports = node.new_child(MdSection::new("Imports")); + let header = "#".repeat(node.borrow().parents().len() + 1); + let imports = node.new_child(MdSection::new(header.as_str(), "Imports")); for import in self.imports() { - let child = imports.new_child(MdSection::default()); + let child = imports.new_child(MdSection::new((header.clone() + "#").as_str(), "")); import.generate(child.clone()); } - let funcs = node.new_child(MdSection::new("Functions")); + let funcs = node.new_child(MdSection::new(header.as_str(), "Functions")); for func in self.funcs() { - let child = funcs.new_child(MdFunc::new(func.name.as_str(), &func.docs)); + let name = func.name.as_str(); + let child = funcs.new_child(MdFunc::new( + (header.clone() + "#").as_str(), + name, + name, + &func.docs, + )); func.generate(child.clone()); } } @@ -180,9 +230,21 @@ impl ToMarkdown for ModuleImport { impl ToMarkdown for InterfaceFunc { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Params")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Params")); for param in &self.params { - let child = node.new_child(MdNamedType::new(param.name.as_str(), param.name.as_str())); + let name = param.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let child = node.new_child(MdNamedType::new( + "-", + id.as_str(), + name, + param.name.as_str(), + )); param.generate(child.clone()); // TODO should this be expanded recursively instead of using flattened type names? node.content_mut::() @@ -190,10 +252,20 @@ impl ToMarkdown for InterfaceFunc { .push((param.name.as_str().to_owned(), param.tref.type_name())); } - node.new_child(MdSection::new("Results")); + node.new_child(MdSection::new(header.as_str(), "Results")); for result in &self.results { - let child = - node.new_child(MdNamedType::new(result.name.as_str(), result.name.as_str())); + let name = result.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let child = node.new_child(MdNamedType::new( + "-", + id.as_str(), + name, + result.name.as_str(), + )); result.generate(child.clone()); // TODO should this be expanded recursively instead of using flattened type names? node.content_mut::() diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index 51db1b47a..adcb0f412 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -9,20 +9,27 @@ pub(super) trait ToMarkdown { fn generate(&self, node: MdNodeRef); } -pub(super) trait MdElement: fmt::Debug + 'static { +pub(super) trait MdElement: fmt::Display + fmt::Debug + 'static { fn id(&self) -> Option<&str>; + fn docs(&self) -> Option<&str>; fn as_any(&self) -> &dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any; - fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result; } #[derive(Debug)] -struct MdNode { +pub(super) struct MdNode { content: Box, parent: Option>>, children: Vec, } +fn walk_parents(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { + if let Some(parent) = parent.and_then(|x| x.upgrade()) { + cb(parent.clone().into()); + walk_parents(parent.borrow().parent.as_ref(), cb) + } +} + impl MdNode { fn new(item: T) -> Self { Self { @@ -31,23 +38,17 @@ impl MdNode { children: vec![], } } -} -fn walk_parents(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { - if let Some(parent) = parent.and_then(|x| x.upgrade()) { - cb(parent.clone().into()); - walk_parents(parent.borrow().parent.as_ref(), cb) + pub fn parents(&self) -> Vec { + let mut parents = Vec::new(); + walk_parents(self.parent.as_ref(), &mut |parent| parents.push(parent)); + parents } } impl fmt::Display for MdNode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut parents = Vec::new(); - walk_parents(self.parent.as_ref(), &mut |parent| { - parents.push(parent); - }); - - MdElement::fmt(&*self.content, f, parents)?; + self.content.fmt(f)?; for child in &self.children { child.fmt(f)?; @@ -73,19 +74,16 @@ impl MdNodeRef { child_ref } - fn borrow(&self) -> cell::Ref { + pub fn borrow(&self) -> cell::Ref { self.0.borrow() } - fn borrow_mut(&self) -> cell::RefMut { + pub fn borrow_mut(&self) -> cell::RefMut { self.0.borrow_mut() } - pub fn content_ref(&self) -> cell::Ref { - cell::Ref::map(self.borrow(), |b| { - let r = b.content.as_any(); - r.downcast_ref::().expect("reference is not T type") - }) + pub fn any_ref(&self) -> cell::Ref> { + cell::Ref::map(self.borrow(), |b| &b.content) } pub fn content_mut(&self) -> cell::RefMut { @@ -94,23 +92,6 @@ impl MdNodeRef { r.downcast_mut::().expect("reference is not T type") }) } - - pub fn get_content(&self) -> Option> { - if self.borrow().content.as_any().is::() { - Some(self.content_ref::()) - } else { - None - } - } - - #[allow(unused)] - pub fn get_content_mut(&self) -> Option> { - if self.borrow_mut().content.as_any().is::() { - Some(self.content_mut::()) - } else { - None - } - } } impl Clone for MdNodeRef { @@ -139,6 +120,10 @@ impl MdElement for MdRoot { None } + fn docs(&self) -> Option<&str> { + None + } + fn as_any(&self) -> &dyn Any { self } @@ -146,21 +131,25 @@ impl MdElement for MdRoot { fn as_any_mut(&mut self) -> &mut dyn Any { self } +} - fn fmt(&self, _f: &mut fmt::Formatter, _parents: Vec) -> fmt::Result { +impl fmt::Display for MdRoot { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { Ok(()) } } -#[derive(Debug, Default)] +#[derive(Debug)] pub(super) struct MdSection { + pub header: String, pub id: Option, pub title: String, } impl MdSection { - pub fn new>(title: S) -> Self { + pub fn new>(header: S, title: S) -> Self { Self { + header: header.as_ref().to_owned(), id: None, title: title.as_ref().to_owned(), } @@ -172,6 +161,10 @@ impl MdElement for MdSection { self.id.as_ref().map(|s| s.as_str()) } + fn docs(&self) -> Option<&str> { + None + } + fn as_any(&self) -> &dyn Any { self } @@ -179,10 +172,11 @@ impl MdElement for MdSection { fn as_any_mut(&mut self) -> &mut dyn Any { self } +} - fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { - let header = "#".repeat(parents.len()); - f.write_fmt(format_args!("{} ", header))?; +impl fmt::Display for MdSection { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_fmt(format_args!("{} ", self.header))?; if let Some(id) = &self.id { f.write_fmt(format_args!( @@ -197,14 +191,18 @@ impl MdElement for MdSection { #[derive(Debug)] pub(super) struct MdNamedType { + pub header: String, + pub id: String, pub name: String, pub docs: String, pub r#type: Option, } impl MdNamedType { - pub fn new, S2: AsRef>(name: S1, docs: S2) -> Self { + pub fn new>(header: S, id: S, name: S, docs: S) -> Self { Self { + header: header.as_ref().to_owned(), + id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), docs: docs.as_ref().to_owned(), r#type: None, @@ -212,6 +210,9 @@ impl MdNamedType { } } +// TODO `MdType` should probably store `TypeRef` and recursively +// unwind itself into final `String` representation rather than +// being outright flattened. #[derive(Debug)] pub(super) enum MdType { Enum { repr: String }, @@ -253,7 +254,11 @@ impl fmt::Display for MdType { impl MdElement for MdNamedType { fn id(&self) -> Option<&str> { - Some(&self.name) + Some(&self.id) + } + + fn docs(&self) -> Option<&str> { + Some(&self.docs) } fn as_any(&self) -> &dyn Any { @@ -263,28 +268,14 @@ impl MdElement for MdNamedType { fn as_any_mut(&mut self) -> &mut dyn Any { self } +} - fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { - // Firstly, check if our parent is an MdSection or another MdNamedType in which - // case, we're already nesting and should be represented as bullets - let (header, link) = if let Some(p) = parents.first() { - if let Some(_sec) = p.get_content::() { - ("#".repeat(parents.len()), self.name.clone()) - } else if let Some(tt) = p.get_content::() { - ("-".to_owned(), format!("{}.{}", tt.name, self.name)) - } else if let Some(f) = p.get_content::() { - ("-".to_owned(), format!("{}.{}", f.name, self.name)) - } else { - ("#".to_owned(), self.name.clone()) - } - } else { - ("#".to_owned(), self.name.clone()) - }; - +impl fmt::Display for MdNamedType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_fmt(format_args!( - "{header} `{name}`", - header = header, - link = link, + "{header} `{name}`", + header = self.header, + id = self.id, name = self.name, ))?; @@ -298,6 +289,8 @@ impl MdElement for MdNamedType { #[derive(Debug)] pub(super) struct MdFunc { + pub header: String, + pub id: String, pub name: String, pub inputs: Vec<(String, String)>, pub outputs: Vec, @@ -305,8 +298,10 @@ pub(super) struct MdFunc { } impl MdFunc { - pub fn new, S2: AsRef>(name: S1, docs: S2) -> Self { + pub fn new>(header: S, id: S, name: S, docs: S) -> Self { Self { + header: header.as_ref().to_owned(), + id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), inputs: vec![], outputs: vec![], @@ -317,7 +312,11 @@ impl MdFunc { impl MdElement for MdFunc { fn id(&self) -> Option<&str> { - Some(&self.name) + Some(&self.id) + } + + fn docs(&self) -> Option<&str> { + Some(&self.docs) } fn as_any(&self) -> &dyn Any { @@ -327,10 +326,10 @@ impl MdElement for MdFunc { fn as_any_mut(&mut self) -> &mut dyn Any { self } +} - fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { - // Expand header - let header = "#".repeat(parents.len()); +impl fmt::Display for MdFunc { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // Expand inputs let inputs = self .inputs @@ -353,8 +352,9 @@ impl MdElement for MdFunc { writeln!(f, "\n---\n")?; f.write_fmt(format_args!( - "{header} Fn {name}({inputs}){outputs}", - header = header, + "{header} Fn {name}({inputs}){outputs}", + header = self.header, + id = self.id, name = self.name, inputs = inputs, outputs = outputs, From 80551dfc32e24ecc0530d4b4b462d6cbc5761204 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 19:32:33 +0100 Subject: [PATCH 0468/1772] Remove `fmt` from `MdElement` trait This commit shuffles a few things around, and at the expense of compactness, yet now more explicitly, makes each type adhering to `MdElement` trait define their own `id` and `header` at construction rather than rendering to Markdown. This way, even though there is more code repetition, we get also more control over what each traversed item in the AST gets. Furthermore, rendering to Markdown gets drastically simplified as it is no longer necessary to match all possible types held my `MdNode` when formatting each element, and thus, `MdElement::fmt` can be and is removed in favour of using the `fmt::Display` trait for all elements (where applicable that is). --- .../filesystem/tools/witx/src/docs/ast.rs | 120 +++++++++++--- .../filesystem/tools/witx/src/docs/md.rs | 146 +++++++++--------- 2 files changed, 169 insertions(+), 97 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index 641673775..cce4a8ed6 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -6,15 +6,22 @@ use crate::RepEquality; impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { - let types = node.new_child(MdSection::new("Types")); + let header = "#".repeat(node.borrow().parents().len() + 1); + let types = node.new_child(MdSection::new(header.as_str(), "Types")); for d in self.typenames() { - let child = types.new_child(MdNamedType::new(d.name.as_str(), &d.docs)); + let name = d.name.as_str(); + let child = types.new_child(MdNamedType::new( + (header.clone() + "#").as_str(), + name, + name, + &d.docs, + )); d.generate(child.clone()); } - let modules = node.new_child(MdSection::new("Modules")); + let modules = node.new_child(MdSection::new(header.as_str(), "Modules")); for d in self.modules() { - let mut content = MdSection::new(d.name.as_str()); + let mut content = MdSection::new((header.clone() + "#").as_str(), d.name.as_str()); content.id = Some(d.name.as_str().to_owned()); let child = modules.new_child(content); d.generate(child.clone()); @@ -76,10 +83,17 @@ impl ToMarkdown for Type { impl ToMarkdown for EnumDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Variants")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Variants")); for variant in &self.variants { - node.new_child(MdNamedType::new(variant.name.as_str(), &variant.docs)); + let name = variant.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); } node.content_mut::().r#type = Some(MdType::Enum { @@ -90,10 +104,17 @@ impl ToMarkdown for EnumDatatype { impl ToMarkdown for IntDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Consts")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Consts")); for r#const in &self.consts { - let tt = MdNamedType::new(r#const.name.as_str(), &r#const.docs); + let name = r#const.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let tt = MdNamedType::new("-", id.as_str(), name, &r#const.docs); // TODO handle r#const.value node.new_child(tt); } @@ -106,10 +127,17 @@ impl ToMarkdown for IntDatatype { impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Flags")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Flags")); for flag in &self.flags { - node.new_child(MdNamedType::new(flag.name.as_str(), &flag.docs)); + let name = flag.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + node.new_child(MdNamedType::new("-", id.as_str(), name, &flag.docs)); } node.content_mut::().r#type = Some(MdType::Flags { @@ -120,10 +148,17 @@ impl ToMarkdown for FlagsDatatype { impl ToMarkdown for StructDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Struct members")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Struct members")); for member in &self.members { - let n = node.new_child(MdNamedType::new(member.name.as_str(), &member.docs)); + let name = member.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let n = node.new_child(MdNamedType::new("-", id.as_str(), name, &member.docs)); member.tref.generate(n.clone()); } @@ -133,10 +168,17 @@ impl ToMarkdown for StructDatatype { impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Union variants")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Union variants")); for variant in &self.variants { - let n = node.new_child(MdNamedType::new(variant.name.as_str(), &variant.docs)); + let name = variant.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let n = node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); variant.tref.generate(n.clone()); } @@ -147,22 +189,30 @@ impl ToMarkdown for UnionDatatype { impl ToMarkdown for HandleDatatype { fn generate(&self, node: MdNodeRef) { // TODO this needs more work - node.new_child(MdSection::new("Supertypes")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Supertypes")); node.content_mut::().r#type = Some(MdType::Handle); } } impl ToMarkdown for Module { fn generate(&self, node: MdNodeRef) { - let imports = node.new_child(MdSection::new("Imports")); + let header = "#".repeat(node.borrow().parents().len() + 1); + let imports = node.new_child(MdSection::new(header.as_str(), "Imports")); for import in self.imports() { - let child = imports.new_child(MdSection::default()); + let child = imports.new_child(MdSection::new((header.clone() + "#").as_str(), "")); import.generate(child.clone()); } - let funcs = node.new_child(MdSection::new("Functions")); + let funcs = node.new_child(MdSection::new(header.as_str(), "Functions")); for func in self.funcs() { - let child = funcs.new_child(MdFunc::new(func.name.as_str(), &func.docs)); + let name = func.name.as_str(); + let child = funcs.new_child(MdFunc::new( + (header.clone() + "#").as_str(), + name, + name, + &func.docs, + )); func.generate(child.clone()); } } @@ -180,9 +230,21 @@ impl ToMarkdown for ModuleImport { impl ToMarkdown for InterfaceFunc { fn generate(&self, node: MdNodeRef) { - node.new_child(MdSection::new("Params")); + let header = "#".repeat(node.borrow().parents().len() + 1); + node.new_child(MdSection::new(header.as_str(), "Params")); for param in &self.params { - let child = node.new_child(MdNamedType::new(param.name.as_str(), param.name.as_str())); + let name = param.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let child = node.new_child(MdNamedType::new( + "-", + id.as_str(), + name, + param.name.as_str(), + )); param.generate(child.clone()); // TODO should this be expanded recursively instead of using flattened type names? node.content_mut::() @@ -190,10 +252,20 @@ impl ToMarkdown for InterfaceFunc { .push((param.name.as_str().to_owned(), param.tref.type_name())); } - node.new_child(MdSection::new("Results")); + node.new_child(MdSection::new(header.as_str(), "Results")); for result in &self.results { - let child = - node.new_child(MdNamedType::new(result.name.as_str(), result.name.as_str())); + let name = result.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let child = node.new_child(MdNamedType::new( + "-", + id.as_str(), + name, + result.name.as_str(), + )); result.generate(child.clone()); // TODO should this be expanded recursively instead of using flattened type names? node.content_mut::() diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index 51db1b47a..adcb0f412 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -9,20 +9,27 @@ pub(super) trait ToMarkdown { fn generate(&self, node: MdNodeRef); } -pub(super) trait MdElement: fmt::Debug + 'static { +pub(super) trait MdElement: fmt::Display + fmt::Debug + 'static { fn id(&self) -> Option<&str>; + fn docs(&self) -> Option<&str>; fn as_any(&self) -> &dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any; - fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result; } #[derive(Debug)] -struct MdNode { +pub(super) struct MdNode { content: Box, parent: Option>>, children: Vec, } +fn walk_parents(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { + if let Some(parent) = parent.and_then(|x| x.upgrade()) { + cb(parent.clone().into()); + walk_parents(parent.borrow().parent.as_ref(), cb) + } +} + impl MdNode { fn new(item: T) -> Self { Self { @@ -31,23 +38,17 @@ impl MdNode { children: vec![], } } -} -fn walk_parents(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { - if let Some(parent) = parent.and_then(|x| x.upgrade()) { - cb(parent.clone().into()); - walk_parents(parent.borrow().parent.as_ref(), cb) + pub fn parents(&self) -> Vec { + let mut parents = Vec::new(); + walk_parents(self.parent.as_ref(), &mut |parent| parents.push(parent)); + parents } } impl fmt::Display for MdNode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut parents = Vec::new(); - walk_parents(self.parent.as_ref(), &mut |parent| { - parents.push(parent); - }); - - MdElement::fmt(&*self.content, f, parents)?; + self.content.fmt(f)?; for child in &self.children { child.fmt(f)?; @@ -73,19 +74,16 @@ impl MdNodeRef { child_ref } - fn borrow(&self) -> cell::Ref { + pub fn borrow(&self) -> cell::Ref { self.0.borrow() } - fn borrow_mut(&self) -> cell::RefMut { + pub fn borrow_mut(&self) -> cell::RefMut { self.0.borrow_mut() } - pub fn content_ref(&self) -> cell::Ref { - cell::Ref::map(self.borrow(), |b| { - let r = b.content.as_any(); - r.downcast_ref::().expect("reference is not T type") - }) + pub fn any_ref(&self) -> cell::Ref> { + cell::Ref::map(self.borrow(), |b| &b.content) } pub fn content_mut(&self) -> cell::RefMut { @@ -94,23 +92,6 @@ impl MdNodeRef { r.downcast_mut::().expect("reference is not T type") }) } - - pub fn get_content(&self) -> Option> { - if self.borrow().content.as_any().is::() { - Some(self.content_ref::()) - } else { - None - } - } - - #[allow(unused)] - pub fn get_content_mut(&self) -> Option> { - if self.borrow_mut().content.as_any().is::() { - Some(self.content_mut::()) - } else { - None - } - } } impl Clone for MdNodeRef { @@ -139,6 +120,10 @@ impl MdElement for MdRoot { None } + fn docs(&self) -> Option<&str> { + None + } + fn as_any(&self) -> &dyn Any { self } @@ -146,21 +131,25 @@ impl MdElement for MdRoot { fn as_any_mut(&mut self) -> &mut dyn Any { self } +} - fn fmt(&self, _f: &mut fmt::Formatter, _parents: Vec) -> fmt::Result { +impl fmt::Display for MdRoot { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { Ok(()) } } -#[derive(Debug, Default)] +#[derive(Debug)] pub(super) struct MdSection { + pub header: String, pub id: Option, pub title: String, } impl MdSection { - pub fn new>(title: S) -> Self { + pub fn new>(header: S, title: S) -> Self { Self { + header: header.as_ref().to_owned(), id: None, title: title.as_ref().to_owned(), } @@ -172,6 +161,10 @@ impl MdElement for MdSection { self.id.as_ref().map(|s| s.as_str()) } + fn docs(&self) -> Option<&str> { + None + } + fn as_any(&self) -> &dyn Any { self } @@ -179,10 +172,11 @@ impl MdElement for MdSection { fn as_any_mut(&mut self) -> &mut dyn Any { self } +} - fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { - let header = "#".repeat(parents.len()); - f.write_fmt(format_args!("{} ", header))?; +impl fmt::Display for MdSection { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_fmt(format_args!("{} ", self.header))?; if let Some(id) = &self.id { f.write_fmt(format_args!( @@ -197,14 +191,18 @@ impl MdElement for MdSection { #[derive(Debug)] pub(super) struct MdNamedType { + pub header: String, + pub id: String, pub name: String, pub docs: String, pub r#type: Option, } impl MdNamedType { - pub fn new, S2: AsRef>(name: S1, docs: S2) -> Self { + pub fn new>(header: S, id: S, name: S, docs: S) -> Self { Self { + header: header.as_ref().to_owned(), + id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), docs: docs.as_ref().to_owned(), r#type: None, @@ -212,6 +210,9 @@ impl MdNamedType { } } +// TODO `MdType` should probably store `TypeRef` and recursively +// unwind itself into final `String` representation rather than +// being outright flattened. #[derive(Debug)] pub(super) enum MdType { Enum { repr: String }, @@ -253,7 +254,11 @@ impl fmt::Display for MdType { impl MdElement for MdNamedType { fn id(&self) -> Option<&str> { - Some(&self.name) + Some(&self.id) + } + + fn docs(&self) -> Option<&str> { + Some(&self.docs) } fn as_any(&self) -> &dyn Any { @@ -263,28 +268,14 @@ impl MdElement for MdNamedType { fn as_any_mut(&mut self) -> &mut dyn Any { self } +} - fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { - // Firstly, check if our parent is an MdSection or another MdNamedType in which - // case, we're already nesting and should be represented as bullets - let (header, link) = if let Some(p) = parents.first() { - if let Some(_sec) = p.get_content::() { - ("#".repeat(parents.len()), self.name.clone()) - } else if let Some(tt) = p.get_content::() { - ("-".to_owned(), format!("{}.{}", tt.name, self.name)) - } else if let Some(f) = p.get_content::() { - ("-".to_owned(), format!("{}.{}", f.name, self.name)) - } else { - ("#".to_owned(), self.name.clone()) - } - } else { - ("#".to_owned(), self.name.clone()) - }; - +impl fmt::Display for MdNamedType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_fmt(format_args!( - "{header} `{name}`", - header = header, - link = link, + "{header} `{name}`", + header = self.header, + id = self.id, name = self.name, ))?; @@ -298,6 +289,8 @@ impl MdElement for MdNamedType { #[derive(Debug)] pub(super) struct MdFunc { + pub header: String, + pub id: String, pub name: String, pub inputs: Vec<(String, String)>, pub outputs: Vec, @@ -305,8 +298,10 @@ pub(super) struct MdFunc { } impl MdFunc { - pub fn new, S2: AsRef>(name: S1, docs: S2) -> Self { + pub fn new>(header: S, id: S, name: S, docs: S) -> Self { Self { + header: header.as_ref().to_owned(), + id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), inputs: vec![], outputs: vec![], @@ -317,7 +312,11 @@ impl MdFunc { impl MdElement for MdFunc { fn id(&self) -> Option<&str> { - Some(&self.name) + Some(&self.id) + } + + fn docs(&self) -> Option<&str> { + Some(&self.docs) } fn as_any(&self) -> &dyn Any { @@ -327,10 +326,10 @@ impl MdElement for MdFunc { fn as_any_mut(&mut self) -> &mut dyn Any { self } +} - fn fmt(&self, f: &mut fmt::Formatter, parents: Vec) -> fmt::Result { - // Expand header - let header = "#".repeat(parents.len()); +impl fmt::Display for MdFunc { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // Expand inputs let inputs = self .inputs @@ -353,8 +352,9 @@ impl MdElement for MdFunc { writeln!(f, "\n---\n")?; f.write_fmt(format_args!( - "{header} Fn {name}({inputs}){outputs}", - header = header, + "{header} Fn {name}({inputs}){outputs}", + header = self.header, + id = self.id, name = self.name, inputs = inputs, outputs = outputs, From f6190554b78074bbe2725b8bdb0bb7b008fc606a Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 21:45:43 +0100 Subject: [PATCH 0469/1772] Factor out HTML link generation into a helper --- proposals/clocks/tools/witx/src/docs/md.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index adcb0f412..e5647f804 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -174,15 +174,16 @@ impl MdElement for MdSection { } } +fn gen_link>(id: S) -> String { + format!("", id = id.as_ref()) +} + impl fmt::Display for MdSection { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_fmt(format_args!("{} ", self.header))?; if let Some(id) = &self.id { - f.write_fmt(format_args!( - " ", - id = id - ))?; + f.write_fmt(format_args!("{} ", gen_link(id)))?; } writeln!(f, "{}", self.title) @@ -273,9 +274,9 @@ impl MdElement for MdNamedType { impl fmt::Display for MdNamedType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_fmt(format_args!( - "{header} `{name}`", + "{header} {link} `{name}`", header = self.header, - id = self.id, + link = gen_link(&self.id), name = self.name, ))?; @@ -352,9 +353,9 @@ impl fmt::Display for MdFunc { writeln!(f, "\n---\n")?; f.write_fmt(format_args!( - "{header} Fn {name}({inputs}){outputs}", + "{header} {link} Fn {name}({inputs}){outputs}", header = self.header, - id = self.id, + link = gen_link(&self.id), name = self.name, inputs = inputs, outputs = outputs, From 13eaebedcfe6cb2110553869edd85b9c724f6bfd Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 21:45:43 +0100 Subject: [PATCH 0470/1772] Factor out HTML link generation into a helper --- proposals/random/tools/witx/src/docs/md.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index adcb0f412..e5647f804 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -174,15 +174,16 @@ impl MdElement for MdSection { } } +fn gen_link>(id: S) -> String { + format!("", id = id.as_ref()) +} + impl fmt::Display for MdSection { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_fmt(format_args!("{} ", self.header))?; if let Some(id) = &self.id { - f.write_fmt(format_args!( - " ", - id = id - ))?; + f.write_fmt(format_args!("{} ", gen_link(id)))?; } writeln!(f, "{}", self.title) @@ -273,9 +274,9 @@ impl MdElement for MdNamedType { impl fmt::Display for MdNamedType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_fmt(format_args!( - "{header} `{name}`", + "{header} {link} `{name}`", header = self.header, - id = self.id, + link = gen_link(&self.id), name = self.name, ))?; @@ -352,9 +353,9 @@ impl fmt::Display for MdFunc { writeln!(f, "\n---\n")?; f.write_fmt(format_args!( - "{header} Fn {name}({inputs}){outputs}", + "{header} {link} Fn {name}({inputs}){outputs}", header = self.header, - id = self.id, + link = gen_link(&self.id), name = self.name, inputs = inputs, outputs = outputs, From 487ae3226ac903e31826f68a5477b84db832ded2 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 21:45:43 +0100 Subject: [PATCH 0471/1772] Factor out HTML link generation into a helper --- proposals/filesystem/tools/witx/src/docs/md.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index adcb0f412..e5647f804 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -174,15 +174,16 @@ impl MdElement for MdSection { } } +fn gen_link>(id: S) -> String { + format!("", id = id.as_ref()) +} + impl fmt::Display for MdSection { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_fmt(format_args!("{} ", self.header))?; if let Some(id) = &self.id { - f.write_fmt(format_args!( - " ", - id = id - ))?; + f.write_fmt(format_args!("{} ", gen_link(id)))?; } writeln!(f, "{}", self.title) @@ -273,9 +274,9 @@ impl MdElement for MdNamedType { impl fmt::Display for MdNamedType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_fmt(format_args!( - "{header} `{name}`", + "{header} {link} `{name}`", header = self.header, - id = self.id, + link = gen_link(&self.id), name = self.name, ))?; @@ -352,9 +353,9 @@ impl fmt::Display for MdFunc { writeln!(f, "\n---\n")?; f.write_fmt(format_args!( - "{header} Fn {name}({inputs}){outputs}", + "{header} {link} Fn {name}({inputs}){outputs}", header = self.header, - id = self.id, + link = gen_link(&self.id), name = self.name, inputs = inputs, outputs = outputs, From 0e2f53da9c3d9815ed0ea130540619c7c0770973 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 23:27:24 +0100 Subject: [PATCH 0472/1772] Add simple way of generating Markdown links in docs This commit adds a simple way for generating Markdown links in docs sections of relevant AST nodes. Any slice of the form '`...`' is treated as a potential link. If the expanded Markdown form (with "::" replaced with '.') doesn't exist, log a warning message, and leave the link untouched in its original form. --- proposals/clocks/tools/witx/Cargo.toml | 2 + proposals/clocks/tools/witx/src/docs/md.rs | 25 ++++++++ proposals/clocks/tools/witx/src/docs/mod.rs | 63 +++++++++++++++++++++ proposals/clocks/tools/witx/src/main.rs | 2 + 4 files changed, 92 insertions(+) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 2fffc2c12..950137af0 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -21,3 +21,5 @@ path = "src/main.rs" clap = "2" wast = "3.0.4" thiserror = "1.0" +log = "0.4" +pretty_env_logger = "0.3" diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index e5647f804..91d0f6fad 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -12,6 +12,7 @@ pub(super) trait ToMarkdown { pub(super) trait MdElement: fmt::Display + fmt::Debug + 'static { fn id(&self) -> Option<&str>; fn docs(&self) -> Option<&str>; + fn set_docs(&mut self, docs: &str); fn as_any(&self) -> &dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any; } @@ -44,6 +45,14 @@ impl MdNode { walk_parents(self.parent.as_ref(), &mut |parent| parents.push(parent)); parents } + + pub fn children(&self) -> Vec { + let mut children = self.children.clone(); + for child in &self.children { + children.append(&mut child.borrow().children()); + } + children + } } impl fmt::Display for MdNode { @@ -86,6 +95,10 @@ impl MdNodeRef { cell::Ref::map(self.borrow(), |b| &b.content) } + pub fn any_ref_mut(&self) -> cell::RefMut> { + cell::RefMut::map(self.borrow_mut(), |b| &mut b.content) + } + pub fn content_mut(&self) -> cell::RefMut { cell::RefMut::map(self.borrow_mut(), |b| { let r = b.content.as_any_mut(); @@ -124,6 +137,8 @@ impl MdElement for MdRoot { None } + fn set_docs(&mut self, _: &str) {} + fn as_any(&self) -> &dyn Any { self } @@ -165,6 +180,8 @@ impl MdElement for MdSection { None } + fn set_docs(&mut self, _: &str) {} + fn as_any(&self) -> &dyn Any { self } @@ -262,6 +279,10 @@ impl MdElement for MdNamedType { Some(&self.docs) } + fn set_docs(&mut self, docs: &str) { + self.docs = docs.to_owned(); + } + fn as_any(&self) -> &dyn Any { self } @@ -320,6 +341,10 @@ impl MdElement for MdFunc { Some(&self.docs) } + fn set_docs(&mut self, docs: &str) { + self.docs = docs.to_owned(); + } + fn as_any(&self) -> &dyn Any { self } diff --git a/proposals/clocks/tools/witx/src/docs/mod.rs b/proposals/clocks/tools/witx/src/docs/mod.rs index f1ddc7c74..e36e7499f 100644 --- a/proposals/clocks/tools/witx/src/docs/mod.rs +++ b/proposals/clocks/tools/witx/src/docs/mod.rs @@ -3,15 +3,78 @@ mod md; use crate::ast::Document; use md::{MdNodeRef, MdRoot, ToMarkdown}; +use std::{ + collections::{hash_map, HashSet}, + iter::FromIterator, +}; pub trait Documentation { fn to_md(&self) -> String; } +fn parse_links>(text: S, existing_links: &HashSet) -> String { + let text = text.as_ref(); + let mut parsed_text = String::with_capacity(text.len()); + let mut link = String::with_capacity(text.len()); + let mut is_link = false; + + for ch in text.chars() { + match (ch, is_link) { + // Found the beginning of a link! + ('`', false) => { + is_link = true; + } + // Reached the end, expand into a link! + ('`', true) => { + // Sanitise scoping by replacing "::" with '.' + let md_link = link.replace("::", "."); + // Before committing to pasting the link in, + // first verify that it actually exists. + let expanded = if let Some(_) = existing_links.get(&md_link) { + format!("[`{}`](#{})", link, md_link) + } else { + log::warn!( + "Link [`{}`](#{}) could not be found in the document!", + link, + md_link + ); + format!("`{}`", link) + }; + parsed_text.push_str(&expanded); + link.drain(..); + is_link = false; + } + (ch, false) => parsed_text.push(ch), + (ch, true) => link.push(ch), + } + } + + parsed_text +} + impl Documentation for Document { fn to_md(&self) -> String { let root = MdNodeRef::new(MdRoot::default()); self.generate(root.clone()); + // Get all children of the `root` element + let children = root.borrow().children(); + // Gather all existing links in the document into a set + let existing_links: HashSet = HashSet::from_iter( + children + .iter() + .filter_map(|x| x.any_ref().id().map(String::from)), + ); + // Traverse each docs section of each child, and parse links + // logging a warning in case the generated is invalid + for child in children { + let docs_with_links = child + .any_ref() + .docs() + .map(|docs| parse_links(docs, &existing_links)); + if let Some(docs) = docs_with_links { + child.any_ref_mut().set_docs(&docs); + } + } format!("{}", root) } } diff --git a/proposals/clocks/tools/witx/src/main.rs b/proposals/clocks/tools/witx/src/main.rs index d7ff23b55..f89822d7f 100644 --- a/proposals/clocks/tools/witx/src/main.rs +++ b/proposals/clocks/tools/witx/src/main.rs @@ -72,6 +72,8 @@ pub fn main() { } }; + pretty_env_logger::init(); + let doc = load_docs(&inputs); if app.is_present("verbose") { println!("{:?}", doc) From c6bfe1d30c91649ee1364a526da05598c2224760 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 23:27:24 +0100 Subject: [PATCH 0473/1772] Add simple way of generating Markdown links in docs This commit adds a simple way for generating Markdown links in docs sections of relevant AST nodes. Any slice of the form '`...`' is treated as a potential link. If the expanded Markdown form (with "::" replaced with '.') doesn't exist, log a warning message, and leave the link untouched in its original form. --- proposals/random/tools/witx/Cargo.toml | 2 + proposals/random/tools/witx/src/docs/md.rs | 25 ++++++++ proposals/random/tools/witx/src/docs/mod.rs | 63 +++++++++++++++++++++ proposals/random/tools/witx/src/main.rs | 2 + 4 files changed, 92 insertions(+) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 2fffc2c12..950137af0 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -21,3 +21,5 @@ path = "src/main.rs" clap = "2" wast = "3.0.4" thiserror = "1.0" +log = "0.4" +pretty_env_logger = "0.3" diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index e5647f804..91d0f6fad 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -12,6 +12,7 @@ pub(super) trait ToMarkdown { pub(super) trait MdElement: fmt::Display + fmt::Debug + 'static { fn id(&self) -> Option<&str>; fn docs(&self) -> Option<&str>; + fn set_docs(&mut self, docs: &str); fn as_any(&self) -> &dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any; } @@ -44,6 +45,14 @@ impl MdNode { walk_parents(self.parent.as_ref(), &mut |parent| parents.push(parent)); parents } + + pub fn children(&self) -> Vec { + let mut children = self.children.clone(); + for child in &self.children { + children.append(&mut child.borrow().children()); + } + children + } } impl fmt::Display for MdNode { @@ -86,6 +95,10 @@ impl MdNodeRef { cell::Ref::map(self.borrow(), |b| &b.content) } + pub fn any_ref_mut(&self) -> cell::RefMut> { + cell::RefMut::map(self.borrow_mut(), |b| &mut b.content) + } + pub fn content_mut(&self) -> cell::RefMut { cell::RefMut::map(self.borrow_mut(), |b| { let r = b.content.as_any_mut(); @@ -124,6 +137,8 @@ impl MdElement for MdRoot { None } + fn set_docs(&mut self, _: &str) {} + fn as_any(&self) -> &dyn Any { self } @@ -165,6 +180,8 @@ impl MdElement for MdSection { None } + fn set_docs(&mut self, _: &str) {} + fn as_any(&self) -> &dyn Any { self } @@ -262,6 +279,10 @@ impl MdElement for MdNamedType { Some(&self.docs) } + fn set_docs(&mut self, docs: &str) { + self.docs = docs.to_owned(); + } + fn as_any(&self) -> &dyn Any { self } @@ -320,6 +341,10 @@ impl MdElement for MdFunc { Some(&self.docs) } + fn set_docs(&mut self, docs: &str) { + self.docs = docs.to_owned(); + } + fn as_any(&self) -> &dyn Any { self } diff --git a/proposals/random/tools/witx/src/docs/mod.rs b/proposals/random/tools/witx/src/docs/mod.rs index f1ddc7c74..e36e7499f 100644 --- a/proposals/random/tools/witx/src/docs/mod.rs +++ b/proposals/random/tools/witx/src/docs/mod.rs @@ -3,15 +3,78 @@ mod md; use crate::ast::Document; use md::{MdNodeRef, MdRoot, ToMarkdown}; +use std::{ + collections::{hash_map, HashSet}, + iter::FromIterator, +}; pub trait Documentation { fn to_md(&self) -> String; } +fn parse_links>(text: S, existing_links: &HashSet) -> String { + let text = text.as_ref(); + let mut parsed_text = String::with_capacity(text.len()); + let mut link = String::with_capacity(text.len()); + let mut is_link = false; + + for ch in text.chars() { + match (ch, is_link) { + // Found the beginning of a link! + ('`', false) => { + is_link = true; + } + // Reached the end, expand into a link! + ('`', true) => { + // Sanitise scoping by replacing "::" with '.' + let md_link = link.replace("::", "."); + // Before committing to pasting the link in, + // first verify that it actually exists. + let expanded = if let Some(_) = existing_links.get(&md_link) { + format!("[`{}`](#{})", link, md_link) + } else { + log::warn!( + "Link [`{}`](#{}) could not be found in the document!", + link, + md_link + ); + format!("`{}`", link) + }; + parsed_text.push_str(&expanded); + link.drain(..); + is_link = false; + } + (ch, false) => parsed_text.push(ch), + (ch, true) => link.push(ch), + } + } + + parsed_text +} + impl Documentation for Document { fn to_md(&self) -> String { let root = MdNodeRef::new(MdRoot::default()); self.generate(root.clone()); + // Get all children of the `root` element + let children = root.borrow().children(); + // Gather all existing links in the document into a set + let existing_links: HashSet = HashSet::from_iter( + children + .iter() + .filter_map(|x| x.any_ref().id().map(String::from)), + ); + // Traverse each docs section of each child, and parse links + // logging a warning in case the generated is invalid + for child in children { + let docs_with_links = child + .any_ref() + .docs() + .map(|docs| parse_links(docs, &existing_links)); + if let Some(docs) = docs_with_links { + child.any_ref_mut().set_docs(&docs); + } + } format!("{}", root) } } diff --git a/proposals/random/tools/witx/src/main.rs b/proposals/random/tools/witx/src/main.rs index d7ff23b55..f89822d7f 100644 --- a/proposals/random/tools/witx/src/main.rs +++ b/proposals/random/tools/witx/src/main.rs @@ -72,6 +72,8 @@ pub fn main() { } }; + pretty_env_logger::init(); + let doc = load_docs(&inputs); if app.is_present("verbose") { println!("{:?}", doc) From 5d72b260ba8e0c03a77d82b7dc976d9935bbb9fa Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 14 Jan 2020 23:27:24 +0100 Subject: [PATCH 0474/1772] Add simple way of generating Markdown links in docs This commit adds a simple way for generating Markdown links in docs sections of relevant AST nodes. Any slice of the form '`...`' is treated as a potential link. If the expanded Markdown form (with "::" replaced with '.') doesn't exist, log a warning message, and leave the link untouched in its original form. --- proposals/filesystem/tools/witx/Cargo.toml | 2 + .../filesystem/tools/witx/src/docs/md.rs | 25 ++++++++ .../filesystem/tools/witx/src/docs/mod.rs | 63 +++++++++++++++++++ proposals/filesystem/tools/witx/src/main.rs | 2 + 4 files changed, 92 insertions(+) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 2fffc2c12..950137af0 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -21,3 +21,5 @@ path = "src/main.rs" clap = "2" wast = "3.0.4" thiserror = "1.0" +log = "0.4" +pretty_env_logger = "0.3" diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index e5647f804..91d0f6fad 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -12,6 +12,7 @@ pub(super) trait ToMarkdown { pub(super) trait MdElement: fmt::Display + fmt::Debug + 'static { fn id(&self) -> Option<&str>; fn docs(&self) -> Option<&str>; + fn set_docs(&mut self, docs: &str); fn as_any(&self) -> &dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any; } @@ -44,6 +45,14 @@ impl MdNode { walk_parents(self.parent.as_ref(), &mut |parent| parents.push(parent)); parents } + + pub fn children(&self) -> Vec { + let mut children = self.children.clone(); + for child in &self.children { + children.append(&mut child.borrow().children()); + } + children + } } impl fmt::Display for MdNode { @@ -86,6 +95,10 @@ impl MdNodeRef { cell::Ref::map(self.borrow(), |b| &b.content) } + pub fn any_ref_mut(&self) -> cell::RefMut> { + cell::RefMut::map(self.borrow_mut(), |b| &mut b.content) + } + pub fn content_mut(&self) -> cell::RefMut { cell::RefMut::map(self.borrow_mut(), |b| { let r = b.content.as_any_mut(); @@ -124,6 +137,8 @@ impl MdElement for MdRoot { None } + fn set_docs(&mut self, _: &str) {} + fn as_any(&self) -> &dyn Any { self } @@ -165,6 +180,8 @@ impl MdElement for MdSection { None } + fn set_docs(&mut self, _: &str) {} + fn as_any(&self) -> &dyn Any { self } @@ -262,6 +279,10 @@ impl MdElement for MdNamedType { Some(&self.docs) } + fn set_docs(&mut self, docs: &str) { + self.docs = docs.to_owned(); + } + fn as_any(&self) -> &dyn Any { self } @@ -320,6 +341,10 @@ impl MdElement for MdFunc { Some(&self.docs) } + fn set_docs(&mut self, docs: &str) { + self.docs = docs.to_owned(); + } + fn as_any(&self) -> &dyn Any { self } diff --git a/proposals/filesystem/tools/witx/src/docs/mod.rs b/proposals/filesystem/tools/witx/src/docs/mod.rs index f1ddc7c74..e36e7499f 100644 --- a/proposals/filesystem/tools/witx/src/docs/mod.rs +++ b/proposals/filesystem/tools/witx/src/docs/mod.rs @@ -3,15 +3,78 @@ mod md; use crate::ast::Document; use md::{MdNodeRef, MdRoot, ToMarkdown}; +use std::{ + collections::{hash_map, HashSet}, + iter::FromIterator, +}; pub trait Documentation { fn to_md(&self) -> String; } +fn parse_links>(text: S, existing_links: &HashSet) -> String { + let text = text.as_ref(); + let mut parsed_text = String::with_capacity(text.len()); + let mut link = String::with_capacity(text.len()); + let mut is_link = false; + + for ch in text.chars() { + match (ch, is_link) { + // Found the beginning of a link! + ('`', false) => { + is_link = true; + } + // Reached the end, expand into a link! + ('`', true) => { + // Sanitise scoping by replacing "::" with '.' + let md_link = link.replace("::", "."); + // Before committing to pasting the link in, + // first verify that it actually exists. + let expanded = if let Some(_) = existing_links.get(&md_link) { + format!("[`{}`](#{})", link, md_link) + } else { + log::warn!( + "Link [`{}`](#{}) could not be found in the document!", + link, + md_link + ); + format!("`{}`", link) + }; + parsed_text.push_str(&expanded); + link.drain(..); + is_link = false; + } + (ch, false) => parsed_text.push(ch), + (ch, true) => link.push(ch), + } + } + + parsed_text +} + impl Documentation for Document { fn to_md(&self) -> String { let root = MdNodeRef::new(MdRoot::default()); self.generate(root.clone()); + // Get all children of the `root` element + let children = root.borrow().children(); + // Gather all existing links in the document into a set + let existing_links: HashSet = HashSet::from_iter( + children + .iter() + .filter_map(|x| x.any_ref().id().map(String::from)), + ); + // Traverse each docs section of each child, and parse links + // logging a warning in case the generated is invalid + for child in children { + let docs_with_links = child + .any_ref() + .docs() + .map(|docs| parse_links(docs, &existing_links)); + if let Some(docs) = docs_with_links { + child.any_ref_mut().set_docs(&docs); + } + } format!("{}", root) } } diff --git a/proposals/filesystem/tools/witx/src/main.rs b/proposals/filesystem/tools/witx/src/main.rs index d7ff23b55..f89822d7f 100644 --- a/proposals/filesystem/tools/witx/src/main.rs +++ b/proposals/filesystem/tools/witx/src/main.rs @@ -72,6 +72,8 @@ pub fn main() { } }; + pretty_env_logger::init(); + let doc = load_docs(&inputs); if app.is_present("verbose") { println!("{:?}", doc) From d24164c8116c1a6b6c48c9966a1847fdba154a75 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 15 Jan 2020 00:14:13 +0100 Subject: [PATCH 0475/1772] Add docs and refactor --- proposals/clocks/tools/witx/src/docs/ast.rs | 48 ++++----- proposals/clocks/tools/witx/src/docs/md.rs | 110 ++++++++++++++++++-- proposals/clocks/tools/witx/src/docs/mod.rs | 13 ++- 3 files changed, 134 insertions(+), 37 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index cce4a8ed6..a570012dd 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -6,7 +6,7 @@ use crate::RepEquality; impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); let types = node.new_child(MdSection::new(header.as_str(), "Types")); for d in self.typenames() { let name = d.name.as_str(); @@ -34,7 +34,7 @@ impl ToMarkdown for TypeRef { match self { TypeRef::Value(v) => v.generate(node.clone()), TypeRef::Name(n) => { - node.content_mut::().r#type = Some(MdType::Alias { + node.content_ref_mut::().r#type = Some(MdType::Alias { r#type: n.name.as_str().to_owned(), }) } @@ -58,22 +58,22 @@ impl ToMarkdown for Type { Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), Self::Array(a) => { - node.content_mut::().r#type = Some(MdType::Array { + node.content_ref_mut::().r#type = Some(MdType::Array { r#type: a.type_name().to_owned(), }) } Self::Pointer(a) => { - node.content_mut::().r#type = Some(MdType::Pointer { + node.content_ref_mut::().r#type = Some(MdType::Pointer { r#type: a.type_name().to_owned(), }) } Self::ConstPointer(a) => { - node.content_mut::().r#type = Some(MdType::ConstPointer { + node.content_ref_mut::().r#type = Some(MdType::ConstPointer { r#type: a.type_name().to_owned(), }) } Self::Builtin(a) => { - node.content_mut::().r#type = Some(MdType::Builtin { + node.content_ref_mut::().r#type = Some(MdType::Builtin { repr: a.type_name().to_owned(), }) } @@ -83,7 +83,7 @@ impl ToMarkdown for Type { impl ToMarkdown for EnumDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Variants")); for variant in &self.variants { @@ -96,7 +96,7 @@ impl ToMarkdown for EnumDatatype { node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); } - node.content_mut::().r#type = Some(MdType::Enum { + node.content_ref_mut::().r#type = Some(MdType::Enum { repr: self.repr.type_name().to_owned(), }); } @@ -104,7 +104,7 @@ impl ToMarkdown for EnumDatatype { impl ToMarkdown for IntDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Consts")); for r#const in &self.consts { @@ -119,7 +119,7 @@ impl ToMarkdown for IntDatatype { node.new_child(tt); } - node.content_mut::().r#type = Some(MdType::Int { + node.content_ref_mut::().r#type = Some(MdType::Int { repr: self.repr.type_name().to_owned(), }); } @@ -127,7 +127,7 @@ impl ToMarkdown for IntDatatype { impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Flags")); for flag in &self.flags { @@ -140,7 +140,7 @@ impl ToMarkdown for FlagsDatatype { node.new_child(MdNamedType::new("-", id.as_str(), name, &flag.docs)); } - node.content_mut::().r#type = Some(MdType::Flags { + node.content_ref_mut::().r#type = Some(MdType::Flags { repr: self.repr.type_name().to_owned(), }); } @@ -148,7 +148,7 @@ impl ToMarkdown for FlagsDatatype { impl ToMarkdown for StructDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Struct members")); for member in &self.members { @@ -162,13 +162,13 @@ impl ToMarkdown for StructDatatype { member.tref.generate(n.clone()); } - node.content_mut::().r#type = Some(MdType::Struct); + node.content_ref_mut::().r#type = Some(MdType::Struct); } } impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Union variants")); for variant in &self.variants { @@ -182,22 +182,22 @@ impl ToMarkdown for UnionDatatype { variant.tref.generate(n.clone()); } - node.content_mut::().r#type = Some(MdType::Union); + node.content_ref_mut::().r#type = Some(MdType::Union); } } impl ToMarkdown for HandleDatatype { fn generate(&self, node: MdNodeRef) { // TODO this needs more work - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Supertypes")); - node.content_mut::().r#type = Some(MdType::Handle); + node.content_ref_mut::().r#type = Some(MdType::Handle); } } impl ToMarkdown for Module { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); let imports = node.new_child(MdSection::new(header.as_str(), "Imports")); for import in self.imports() { let child = imports.new_child(MdSection::new((header.clone() + "#").as_str(), "")); @@ -222,7 +222,7 @@ impl ToMarkdown for ModuleImport { fn generate(&self, node: MdNodeRef) { match self.variant { ModuleImportVariant::Memory => { - node.content_mut::().title = "Memory".to_owned(); + node.content_ref_mut::().title = "Memory".to_owned(); } } } @@ -230,7 +230,7 @@ impl ToMarkdown for ModuleImport { impl ToMarkdown for InterfaceFunc { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Params")); for param in &self.params { let name = param.name.as_str(); @@ -247,7 +247,7 @@ impl ToMarkdown for InterfaceFunc { )); param.generate(child.clone()); // TODO should this be expanded recursively instead of using flattened type names? - node.content_mut::() + node.content_ref_mut::() .inputs .push((param.name.as_str().to_owned(), param.tref.type_name())); } @@ -268,7 +268,7 @@ impl ToMarkdown for InterfaceFunc { )); result.generate(child.clone()); // TODO should this be expanded recursively instead of using flattened type names? - node.content_mut::() + node.content_ref_mut::() .outputs .push(result.tref.type_name()); } @@ -278,7 +278,7 @@ impl ToMarkdown for InterfaceFunc { impl ToMarkdown for InterfaceFuncParam { fn generate(&self, node: MdNodeRef) { self.tref.generate(node.clone()); - node.content_mut::().docs = self.docs.clone(); + node.content_ref_mut::().docs = self.docs.clone(); } } diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index 91d0f6fad..d4f5f8d95 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -5,18 +5,41 @@ use std::{ rc::{Rc, Weak}, }; +/// Helper trait which simplifies generation of the Markdown document represented +/// as a tree of `MdNodeRef`s. pub(super) trait ToMarkdown { + /// Drives the generation of the `MdNodeRef` tree by either mutating + /// the outer (parent) `MdNodeRef`, shared reference to the `MdNode` `node`, + /// or spawning new child `MdNodeRef` references to nodes. fn generate(&self, node: MdNodeRef); } +/// Interface required for any "content" that is expected to be generated into a +/// Markdown valid format, hence the constraint of `fmt::Display`. +/// +/// In essence, any AST element that is meant to be rendered into Markdown, should +/// define a type implementing this trait. pub(super) trait MdElement: fmt::Display + fmt::Debug + 'static { + /// Returns `Some(id)` of this `MdElement`. Here `id` is synonym for a Markdown actionable + /// link. fn id(&self) -> Option<&str>; + + /// Returns `Some(docs)`, the "docs" of this `MdElement`. fn docs(&self) -> Option<&str>; + + /// Sets `docs`, the "docs" of this `MdElement`. fn set_docs(&mut self, docs: &str); + fn as_any(&self) -> &dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any; } +/// A Markdown node containing: +/// * the Markdown renderable `content`, +/// * a weak reference to the `parent` `MdNode` (if any), and +/// * children `MdNodeRef`s +/// +/// `content` is expected to implement the `MdElement` trait. #[derive(Debug)] pub(super) struct MdNode { content: Box, @@ -24,10 +47,12 @@ pub(super) struct MdNode { children: Vec, } -fn walk_parents(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { +/// Helper function for walking the tree up from some starting `MdNode`, all the way up +/// to the root of the tree. +fn walk_ancestors(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { if let Some(parent) = parent.and_then(|x| x.upgrade()) { cb(parent.clone().into()); - walk_parents(parent.borrow().parent.as_ref(), cb) + walk_ancestors(parent.borrow().parent.as_ref(), cb) } } @@ -40,12 +65,14 @@ impl MdNode { } } - pub fn parents(&self) -> Vec { - let mut parents = Vec::new(); - walk_parents(self.parent.as_ref(), &mut |parent| parents.push(parent)); - parents + /// Returns all ancestors of this `MdNode` all the way to the tree's root. + pub fn ancestors(&self) -> Vec { + let mut ancestors = Vec::new(); + walk_ancestors(self.parent.as_ref(), &mut |parent| ancestors.push(parent)); + ancestors } + /// Returns all children of this `MdNode` in a BFS order. pub fn children(&self) -> Vec { let mut children = self.children.clone(); for child in &self.children { @@ -67,6 +94,7 @@ impl fmt::Display for MdNode { } } +/// Helper struct for storing a shared mutable reference to `MdNode`. #[derive(Debug)] pub(super) struct MdNodeRef(Rc>); @@ -75,6 +103,8 @@ impl MdNodeRef { Self(Rc::new(RefCell::new(MdNode::new(item)))) } + /// Spawns new `MdNode` child node, automatically wrapping it in a + /// `MdNodeRef` and creating a weak link from child to itself. pub fn new_child(&self, item: T) -> Self { let mut child_node = MdNode::new(item); child_node.parent = Some(Rc::downgrade(&self.0)); @@ -91,15 +121,23 @@ impl MdNodeRef { self.0.borrow_mut() } + /// Returns an immutable reference to `MdNode`'s `content` as-is, that + /// is as some type implementing the `MdElement` trait. pub fn any_ref(&self) -> cell::Ref> { cell::Ref::map(self.borrow(), |b| &b.content) } + /// Returns a mutable reference to `MdNode`'s `content` as-is, that + /// is as some type implementing the `MdElement` trait. pub fn any_ref_mut(&self) -> cell::RefMut> { cell::RefMut::map(self.borrow_mut(), |b| &mut b.content) } - pub fn content_mut(&self) -> cell::RefMut { + /// Returns a mutable reference to `MdNode`'s `content` cast to some type + /// `T` which implements `MdElement` trait. + /// + /// Panics if `content` cannot be downcast to `T`. + pub fn content_ref_mut(&self) -> cell::RefMut { cell::RefMut::map(self.borrow_mut(), |b| { let r = b.content.as_any_mut(); r.downcast_mut::().expect("reference is not T type") @@ -125,6 +163,9 @@ impl fmt::Display for MdNodeRef { } } +/// Struct representing the Markdown tree's root. +/// +/// Doesn't render to anything. #[derive(Debug, Default)] pub(super) struct MdRoot; @@ -154,6 +195,14 @@ impl fmt::Display for MdRoot { } } +/// Struct representing a Markdown section without any `docs`, consisting +/// of only a `header` (e.g., "###"), maybe some referencable `id` (i.e., +/// a Markdown link), and some `title`. +/// +/// Example rendering: +/// +/// ### Typenames +/// #[derive(Debug)] pub(super) struct MdSection { pub header: String, @@ -207,6 +256,24 @@ impl fmt::Display for MdSection { } } +/// Struct representing a Markdown section representing any `NamedType` element +/// of the AST. +/// Consists of: +/// * `header`, e.g., "###", or "-" for Enum variants, etc., +/// * referencable `id`, +/// * some `name`, e.g., `errno`, +/// * `docs` paragraph, and +/// * maybe `MdType`. +/// +/// Example rendering (recursive): +/// +/// ### `errno`: Enum(`u16`) +/// Error codes returned by... +/// +/// #### Variants +/// - `success` No error occurred... +/// - `2big` Argument list too long... +/// #[derive(Debug)] pub(super) struct MdNamedType { pub header: String, @@ -228,6 +295,7 @@ impl MdNamedType { } } +/// Helper struct encapsulating the `TypeRef` value. // TODO `MdType` should probably store `TypeRef` and recursively // unwind itself into final `String` representation rather than // being outright flattened. @@ -309,6 +377,28 @@ impl fmt::Display for MdNamedType { } } +/// Struct representing a Markdown section representing any `InterfaceFunc` element +/// of the AST. +/// Consists of: +/// * `header`, e.g., "###", +/// * referencable `id`, +/// * some `name`, e.g., `path_open`, +/// * function `inputs`, i.e., arguments, +/// * function `outputs`, i.e., results, and +/// * `docs` paragraph. +/// +/// Example rendering: +/// +/// ### Fn args_get(argv: `Pointer>`, ...) -> `errno` +/// Read command-line... +/// +/// #### Params +/// - `argv`: `Pointer>` Some docs... +/// - ... +/// +/// #### Results +/// - `error`: `errno` Error code... +/// #[derive(Debug)] pub(super) struct MdFunc { pub header: String, @@ -360,14 +450,14 @@ impl fmt::Display for MdFunc { let inputs = self .inputs .iter() - .map(|(name, r#type)| format!("{}: `{}`", name, r#type)) + .map(|(name, r#type)| format!("{}: {}", name, r#type)) .collect::>() .join(", "); // Expand outputs let outputs: Vec<_> = self .outputs .iter() - .map(|r#type| format!("`{}`", r#type)) + .map(|r#type| format!("{}", r#type)) .collect(); let outputs = match outputs.len() { 0 => "".to_owned(), @@ -378,7 +468,7 @@ impl fmt::Display for MdFunc { writeln!(f, "\n---\n")?; f.write_fmt(format_args!( - "{header} {link} Fn {name}({inputs}){outputs}", + "{header} {link} `{name}({inputs}){outputs}`", header = self.header, link = gen_link(&self.id), name = self.name, diff --git a/proposals/clocks/tools/witx/src/docs/mod.rs b/proposals/clocks/tools/witx/src/docs/mod.rs index e36e7499f..8f082cba5 100644 --- a/proposals/clocks/tools/witx/src/docs/mod.rs +++ b/proposals/clocks/tools/witx/src/docs/mod.rs @@ -8,10 +8,17 @@ use std::{ iter::FromIterator, }; +/// Enables generating Markdown formatted content. pub trait Documentation { fn to_md(&self) -> String; } +/// Helper function which given input `text` and a `HashSet` of existing links converts +/// any slice of the form '`{link}`' into either +/// 1. "[`{link}`](#{md_link})" where `md_link` is `link` with "::" replaced with "." +/// (in Markdown, scoping should be done with ".") if `md_link` exists in the `HashSet` +/// 2. "`{link}`" otherwise. That is, if `md_link` could not be found in the `HashSet`, we +/// just leave what we've consumed. fn parse_links>(text: S, existing_links: &HashSet) -> String { let text = text.as_ref(); let mut parsed_text = String::with_capacity(text.len()); @@ -56,16 +63,16 @@ impl Documentation for Document { fn to_md(&self) -> String { let root = MdNodeRef::new(MdRoot::default()); self.generate(root.clone()); - // Get all children of the `root` element + // Get all children of the `root` element. let children = root.borrow().children(); - // Gather all existing links in the document into a set + // Gather all existing links in the document into a set. let existing_links: HashSet = HashSet::from_iter( children .iter() .filter_map(|x| x.any_ref().id().map(String::from)), ); // Traverse each docs section of each child, and parse links - // logging a warning in case the generated is invalid + // logging a warning in case the generated is invalid. for child in children { let docs_with_links = child .any_ref() From 88ad0be2525a54f8b12c98598e176b01af34597a Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 15 Jan 2020 00:14:13 +0100 Subject: [PATCH 0476/1772] Add docs and refactor --- proposals/random/tools/witx/src/docs/ast.rs | 48 ++++----- proposals/random/tools/witx/src/docs/md.rs | 110 ++++++++++++++++++-- proposals/random/tools/witx/src/docs/mod.rs | 13 ++- 3 files changed, 134 insertions(+), 37 deletions(-) diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index cce4a8ed6..a570012dd 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -6,7 +6,7 @@ use crate::RepEquality; impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); let types = node.new_child(MdSection::new(header.as_str(), "Types")); for d in self.typenames() { let name = d.name.as_str(); @@ -34,7 +34,7 @@ impl ToMarkdown for TypeRef { match self { TypeRef::Value(v) => v.generate(node.clone()), TypeRef::Name(n) => { - node.content_mut::().r#type = Some(MdType::Alias { + node.content_ref_mut::().r#type = Some(MdType::Alias { r#type: n.name.as_str().to_owned(), }) } @@ -58,22 +58,22 @@ impl ToMarkdown for Type { Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), Self::Array(a) => { - node.content_mut::().r#type = Some(MdType::Array { + node.content_ref_mut::().r#type = Some(MdType::Array { r#type: a.type_name().to_owned(), }) } Self::Pointer(a) => { - node.content_mut::().r#type = Some(MdType::Pointer { + node.content_ref_mut::().r#type = Some(MdType::Pointer { r#type: a.type_name().to_owned(), }) } Self::ConstPointer(a) => { - node.content_mut::().r#type = Some(MdType::ConstPointer { + node.content_ref_mut::().r#type = Some(MdType::ConstPointer { r#type: a.type_name().to_owned(), }) } Self::Builtin(a) => { - node.content_mut::().r#type = Some(MdType::Builtin { + node.content_ref_mut::().r#type = Some(MdType::Builtin { repr: a.type_name().to_owned(), }) } @@ -83,7 +83,7 @@ impl ToMarkdown for Type { impl ToMarkdown for EnumDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Variants")); for variant in &self.variants { @@ -96,7 +96,7 @@ impl ToMarkdown for EnumDatatype { node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); } - node.content_mut::().r#type = Some(MdType::Enum { + node.content_ref_mut::().r#type = Some(MdType::Enum { repr: self.repr.type_name().to_owned(), }); } @@ -104,7 +104,7 @@ impl ToMarkdown for EnumDatatype { impl ToMarkdown for IntDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Consts")); for r#const in &self.consts { @@ -119,7 +119,7 @@ impl ToMarkdown for IntDatatype { node.new_child(tt); } - node.content_mut::().r#type = Some(MdType::Int { + node.content_ref_mut::().r#type = Some(MdType::Int { repr: self.repr.type_name().to_owned(), }); } @@ -127,7 +127,7 @@ impl ToMarkdown for IntDatatype { impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Flags")); for flag in &self.flags { @@ -140,7 +140,7 @@ impl ToMarkdown for FlagsDatatype { node.new_child(MdNamedType::new("-", id.as_str(), name, &flag.docs)); } - node.content_mut::().r#type = Some(MdType::Flags { + node.content_ref_mut::().r#type = Some(MdType::Flags { repr: self.repr.type_name().to_owned(), }); } @@ -148,7 +148,7 @@ impl ToMarkdown for FlagsDatatype { impl ToMarkdown for StructDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Struct members")); for member in &self.members { @@ -162,13 +162,13 @@ impl ToMarkdown for StructDatatype { member.tref.generate(n.clone()); } - node.content_mut::().r#type = Some(MdType::Struct); + node.content_ref_mut::().r#type = Some(MdType::Struct); } } impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Union variants")); for variant in &self.variants { @@ -182,22 +182,22 @@ impl ToMarkdown for UnionDatatype { variant.tref.generate(n.clone()); } - node.content_mut::().r#type = Some(MdType::Union); + node.content_ref_mut::().r#type = Some(MdType::Union); } } impl ToMarkdown for HandleDatatype { fn generate(&self, node: MdNodeRef) { // TODO this needs more work - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Supertypes")); - node.content_mut::().r#type = Some(MdType::Handle); + node.content_ref_mut::().r#type = Some(MdType::Handle); } } impl ToMarkdown for Module { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); let imports = node.new_child(MdSection::new(header.as_str(), "Imports")); for import in self.imports() { let child = imports.new_child(MdSection::new((header.clone() + "#").as_str(), "")); @@ -222,7 +222,7 @@ impl ToMarkdown for ModuleImport { fn generate(&self, node: MdNodeRef) { match self.variant { ModuleImportVariant::Memory => { - node.content_mut::().title = "Memory".to_owned(); + node.content_ref_mut::().title = "Memory".to_owned(); } } } @@ -230,7 +230,7 @@ impl ToMarkdown for ModuleImport { impl ToMarkdown for InterfaceFunc { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Params")); for param in &self.params { let name = param.name.as_str(); @@ -247,7 +247,7 @@ impl ToMarkdown for InterfaceFunc { )); param.generate(child.clone()); // TODO should this be expanded recursively instead of using flattened type names? - node.content_mut::() + node.content_ref_mut::() .inputs .push((param.name.as_str().to_owned(), param.tref.type_name())); } @@ -268,7 +268,7 @@ impl ToMarkdown for InterfaceFunc { )); result.generate(child.clone()); // TODO should this be expanded recursively instead of using flattened type names? - node.content_mut::() + node.content_ref_mut::() .outputs .push(result.tref.type_name()); } @@ -278,7 +278,7 @@ impl ToMarkdown for InterfaceFunc { impl ToMarkdown for InterfaceFuncParam { fn generate(&self, node: MdNodeRef) { self.tref.generate(node.clone()); - node.content_mut::().docs = self.docs.clone(); + node.content_ref_mut::().docs = self.docs.clone(); } } diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index 91d0f6fad..d4f5f8d95 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -5,18 +5,41 @@ use std::{ rc::{Rc, Weak}, }; +/// Helper trait which simplifies generation of the Markdown document represented +/// as a tree of `MdNodeRef`s. pub(super) trait ToMarkdown { + /// Drives the generation of the `MdNodeRef` tree by either mutating + /// the outer (parent) `MdNodeRef`, shared reference to the `MdNode` `node`, + /// or spawning new child `MdNodeRef` references to nodes. fn generate(&self, node: MdNodeRef); } +/// Interface required for any "content" that is expected to be generated into a +/// Markdown valid format, hence the constraint of `fmt::Display`. +/// +/// In essence, any AST element that is meant to be rendered into Markdown, should +/// define a type implementing this trait. pub(super) trait MdElement: fmt::Display + fmt::Debug + 'static { + /// Returns `Some(id)` of this `MdElement`. Here `id` is synonym for a Markdown actionable + /// link. fn id(&self) -> Option<&str>; + + /// Returns `Some(docs)`, the "docs" of this `MdElement`. fn docs(&self) -> Option<&str>; + + /// Sets `docs`, the "docs" of this `MdElement`. fn set_docs(&mut self, docs: &str); + fn as_any(&self) -> &dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any; } +/// A Markdown node containing: +/// * the Markdown renderable `content`, +/// * a weak reference to the `parent` `MdNode` (if any), and +/// * children `MdNodeRef`s +/// +/// `content` is expected to implement the `MdElement` trait. #[derive(Debug)] pub(super) struct MdNode { content: Box, @@ -24,10 +47,12 @@ pub(super) struct MdNode { children: Vec, } -fn walk_parents(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { +/// Helper function for walking the tree up from some starting `MdNode`, all the way up +/// to the root of the tree. +fn walk_ancestors(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { if let Some(parent) = parent.and_then(|x| x.upgrade()) { cb(parent.clone().into()); - walk_parents(parent.borrow().parent.as_ref(), cb) + walk_ancestors(parent.borrow().parent.as_ref(), cb) } } @@ -40,12 +65,14 @@ impl MdNode { } } - pub fn parents(&self) -> Vec { - let mut parents = Vec::new(); - walk_parents(self.parent.as_ref(), &mut |parent| parents.push(parent)); - parents + /// Returns all ancestors of this `MdNode` all the way to the tree's root. + pub fn ancestors(&self) -> Vec { + let mut ancestors = Vec::new(); + walk_ancestors(self.parent.as_ref(), &mut |parent| ancestors.push(parent)); + ancestors } + /// Returns all children of this `MdNode` in a BFS order. pub fn children(&self) -> Vec { let mut children = self.children.clone(); for child in &self.children { @@ -67,6 +94,7 @@ impl fmt::Display for MdNode { } } +/// Helper struct for storing a shared mutable reference to `MdNode`. #[derive(Debug)] pub(super) struct MdNodeRef(Rc>); @@ -75,6 +103,8 @@ impl MdNodeRef { Self(Rc::new(RefCell::new(MdNode::new(item)))) } + /// Spawns new `MdNode` child node, automatically wrapping it in a + /// `MdNodeRef` and creating a weak link from child to itself. pub fn new_child(&self, item: T) -> Self { let mut child_node = MdNode::new(item); child_node.parent = Some(Rc::downgrade(&self.0)); @@ -91,15 +121,23 @@ impl MdNodeRef { self.0.borrow_mut() } + /// Returns an immutable reference to `MdNode`'s `content` as-is, that + /// is as some type implementing the `MdElement` trait. pub fn any_ref(&self) -> cell::Ref> { cell::Ref::map(self.borrow(), |b| &b.content) } + /// Returns a mutable reference to `MdNode`'s `content` as-is, that + /// is as some type implementing the `MdElement` trait. pub fn any_ref_mut(&self) -> cell::RefMut> { cell::RefMut::map(self.borrow_mut(), |b| &mut b.content) } - pub fn content_mut(&self) -> cell::RefMut { + /// Returns a mutable reference to `MdNode`'s `content` cast to some type + /// `T` which implements `MdElement` trait. + /// + /// Panics if `content` cannot be downcast to `T`. + pub fn content_ref_mut(&self) -> cell::RefMut { cell::RefMut::map(self.borrow_mut(), |b| { let r = b.content.as_any_mut(); r.downcast_mut::().expect("reference is not T type") @@ -125,6 +163,9 @@ impl fmt::Display for MdNodeRef { } } +/// Struct representing the Markdown tree's root. +/// +/// Doesn't render to anything. #[derive(Debug, Default)] pub(super) struct MdRoot; @@ -154,6 +195,14 @@ impl fmt::Display for MdRoot { } } +/// Struct representing a Markdown section without any `docs`, consisting +/// of only a `header` (e.g., "###"), maybe some referencable `id` (i.e., +/// a Markdown link), and some `title`. +/// +/// Example rendering: +/// +/// ### Typenames +/// #[derive(Debug)] pub(super) struct MdSection { pub header: String, @@ -207,6 +256,24 @@ impl fmt::Display for MdSection { } } +/// Struct representing a Markdown section representing any `NamedType` element +/// of the AST. +/// Consists of: +/// * `header`, e.g., "###", or "-" for Enum variants, etc., +/// * referencable `id`, +/// * some `name`, e.g., `errno`, +/// * `docs` paragraph, and +/// * maybe `MdType`. +/// +/// Example rendering (recursive): +/// +/// ### `errno`: Enum(`u16`) +/// Error codes returned by... +/// +/// #### Variants +/// - `success` No error occurred... +/// - `2big` Argument list too long... +/// #[derive(Debug)] pub(super) struct MdNamedType { pub header: String, @@ -228,6 +295,7 @@ impl MdNamedType { } } +/// Helper struct encapsulating the `TypeRef` value. // TODO `MdType` should probably store `TypeRef` and recursively // unwind itself into final `String` representation rather than // being outright flattened. @@ -309,6 +377,28 @@ impl fmt::Display for MdNamedType { } } +/// Struct representing a Markdown section representing any `InterfaceFunc` element +/// of the AST. +/// Consists of: +/// * `header`, e.g., "###", +/// * referencable `id`, +/// * some `name`, e.g., `path_open`, +/// * function `inputs`, i.e., arguments, +/// * function `outputs`, i.e., results, and +/// * `docs` paragraph. +/// +/// Example rendering: +/// +/// ### Fn args_get(argv: `Pointer>`, ...) -> `errno` +/// Read command-line... +/// +/// #### Params +/// - `argv`: `Pointer>` Some docs... +/// - ... +/// +/// #### Results +/// - `error`: `errno` Error code... +/// #[derive(Debug)] pub(super) struct MdFunc { pub header: String, @@ -360,14 +450,14 @@ impl fmt::Display for MdFunc { let inputs = self .inputs .iter() - .map(|(name, r#type)| format!("{}: `{}`", name, r#type)) + .map(|(name, r#type)| format!("{}: {}", name, r#type)) .collect::>() .join(", "); // Expand outputs let outputs: Vec<_> = self .outputs .iter() - .map(|r#type| format!("`{}`", r#type)) + .map(|r#type| format!("{}", r#type)) .collect(); let outputs = match outputs.len() { 0 => "".to_owned(), @@ -378,7 +468,7 @@ impl fmt::Display for MdFunc { writeln!(f, "\n---\n")?; f.write_fmt(format_args!( - "{header} {link} Fn {name}({inputs}){outputs}", + "{header} {link} `{name}({inputs}){outputs}`", header = self.header, link = gen_link(&self.id), name = self.name, diff --git a/proposals/random/tools/witx/src/docs/mod.rs b/proposals/random/tools/witx/src/docs/mod.rs index e36e7499f..8f082cba5 100644 --- a/proposals/random/tools/witx/src/docs/mod.rs +++ b/proposals/random/tools/witx/src/docs/mod.rs @@ -8,10 +8,17 @@ use std::{ iter::FromIterator, }; +/// Enables generating Markdown formatted content. pub trait Documentation { fn to_md(&self) -> String; } +/// Helper function which given input `text` and a `HashSet` of existing links converts +/// any slice of the form '`{link}`' into either +/// 1. "[`{link}`](#{md_link})" where `md_link` is `link` with "::" replaced with "." +/// (in Markdown, scoping should be done with ".") if `md_link` exists in the `HashSet` +/// 2. "`{link}`" otherwise. That is, if `md_link` could not be found in the `HashSet`, we +/// just leave what we've consumed. fn parse_links>(text: S, existing_links: &HashSet) -> String { let text = text.as_ref(); let mut parsed_text = String::with_capacity(text.len()); @@ -56,16 +63,16 @@ impl Documentation for Document { fn to_md(&self) -> String { let root = MdNodeRef::new(MdRoot::default()); self.generate(root.clone()); - // Get all children of the `root` element + // Get all children of the `root` element. let children = root.borrow().children(); - // Gather all existing links in the document into a set + // Gather all existing links in the document into a set. let existing_links: HashSet = HashSet::from_iter( children .iter() .filter_map(|x| x.any_ref().id().map(String::from)), ); // Traverse each docs section of each child, and parse links - // logging a warning in case the generated is invalid + // logging a warning in case the generated is invalid. for child in children { let docs_with_links = child .any_ref() From 6b353ce2f7d02cde8ae0c4e52e85a0b8a05777c0 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 15 Jan 2020 00:14:13 +0100 Subject: [PATCH 0477/1772] Add docs and refactor --- .../filesystem/tools/witx/src/docs/ast.rs | 48 ++++---- .../filesystem/tools/witx/src/docs/md.rs | 110 ++++++++++++++++-- .../filesystem/tools/witx/src/docs/mod.rs | 13 ++- 3 files changed, 134 insertions(+), 37 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index cce4a8ed6..a570012dd 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -6,7 +6,7 @@ use crate::RepEquality; impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); let types = node.new_child(MdSection::new(header.as_str(), "Types")); for d in self.typenames() { let name = d.name.as_str(); @@ -34,7 +34,7 @@ impl ToMarkdown for TypeRef { match self { TypeRef::Value(v) => v.generate(node.clone()), TypeRef::Name(n) => { - node.content_mut::().r#type = Some(MdType::Alias { + node.content_ref_mut::().r#type = Some(MdType::Alias { r#type: n.name.as_str().to_owned(), }) } @@ -58,22 +58,22 @@ impl ToMarkdown for Type { Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), Self::Array(a) => { - node.content_mut::().r#type = Some(MdType::Array { + node.content_ref_mut::().r#type = Some(MdType::Array { r#type: a.type_name().to_owned(), }) } Self::Pointer(a) => { - node.content_mut::().r#type = Some(MdType::Pointer { + node.content_ref_mut::().r#type = Some(MdType::Pointer { r#type: a.type_name().to_owned(), }) } Self::ConstPointer(a) => { - node.content_mut::().r#type = Some(MdType::ConstPointer { + node.content_ref_mut::().r#type = Some(MdType::ConstPointer { r#type: a.type_name().to_owned(), }) } Self::Builtin(a) => { - node.content_mut::().r#type = Some(MdType::Builtin { + node.content_ref_mut::().r#type = Some(MdType::Builtin { repr: a.type_name().to_owned(), }) } @@ -83,7 +83,7 @@ impl ToMarkdown for Type { impl ToMarkdown for EnumDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Variants")); for variant in &self.variants { @@ -96,7 +96,7 @@ impl ToMarkdown for EnumDatatype { node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); } - node.content_mut::().r#type = Some(MdType::Enum { + node.content_ref_mut::().r#type = Some(MdType::Enum { repr: self.repr.type_name().to_owned(), }); } @@ -104,7 +104,7 @@ impl ToMarkdown for EnumDatatype { impl ToMarkdown for IntDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Consts")); for r#const in &self.consts { @@ -119,7 +119,7 @@ impl ToMarkdown for IntDatatype { node.new_child(tt); } - node.content_mut::().r#type = Some(MdType::Int { + node.content_ref_mut::().r#type = Some(MdType::Int { repr: self.repr.type_name().to_owned(), }); } @@ -127,7 +127,7 @@ impl ToMarkdown for IntDatatype { impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Flags")); for flag in &self.flags { @@ -140,7 +140,7 @@ impl ToMarkdown for FlagsDatatype { node.new_child(MdNamedType::new("-", id.as_str(), name, &flag.docs)); } - node.content_mut::().r#type = Some(MdType::Flags { + node.content_ref_mut::().r#type = Some(MdType::Flags { repr: self.repr.type_name().to_owned(), }); } @@ -148,7 +148,7 @@ impl ToMarkdown for FlagsDatatype { impl ToMarkdown for StructDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Struct members")); for member in &self.members { @@ -162,13 +162,13 @@ impl ToMarkdown for StructDatatype { member.tref.generate(n.clone()); } - node.content_mut::().r#type = Some(MdType::Struct); + node.content_ref_mut::().r#type = Some(MdType::Struct); } } impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Union variants")); for variant in &self.variants { @@ -182,22 +182,22 @@ impl ToMarkdown for UnionDatatype { variant.tref.generate(n.clone()); } - node.content_mut::().r#type = Some(MdType::Union); + node.content_ref_mut::().r#type = Some(MdType::Union); } } impl ToMarkdown for HandleDatatype { fn generate(&self, node: MdNodeRef) { // TODO this needs more work - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Supertypes")); - node.content_mut::().r#type = Some(MdType::Handle); + node.content_ref_mut::().r#type = Some(MdType::Handle); } } impl ToMarkdown for Module { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); let imports = node.new_child(MdSection::new(header.as_str(), "Imports")); for import in self.imports() { let child = imports.new_child(MdSection::new((header.clone() + "#").as_str(), "")); @@ -222,7 +222,7 @@ impl ToMarkdown for ModuleImport { fn generate(&self, node: MdNodeRef) { match self.variant { ModuleImportVariant::Memory => { - node.content_mut::().title = "Memory".to_owned(); + node.content_ref_mut::().title = "Memory".to_owned(); } } } @@ -230,7 +230,7 @@ impl ToMarkdown for ModuleImport { impl ToMarkdown for InterfaceFunc { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().parents().len() + 1); + let header = "#".repeat(node.borrow().ancestors().len() + 1); node.new_child(MdSection::new(header.as_str(), "Params")); for param in &self.params { let name = param.name.as_str(); @@ -247,7 +247,7 @@ impl ToMarkdown for InterfaceFunc { )); param.generate(child.clone()); // TODO should this be expanded recursively instead of using flattened type names? - node.content_mut::() + node.content_ref_mut::() .inputs .push((param.name.as_str().to_owned(), param.tref.type_name())); } @@ -268,7 +268,7 @@ impl ToMarkdown for InterfaceFunc { )); result.generate(child.clone()); // TODO should this be expanded recursively instead of using flattened type names? - node.content_mut::() + node.content_ref_mut::() .outputs .push(result.tref.type_name()); } @@ -278,7 +278,7 @@ impl ToMarkdown for InterfaceFunc { impl ToMarkdown for InterfaceFuncParam { fn generate(&self, node: MdNodeRef) { self.tref.generate(node.clone()); - node.content_mut::().docs = self.docs.clone(); + node.content_ref_mut::().docs = self.docs.clone(); } } diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index 91d0f6fad..d4f5f8d95 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -5,18 +5,41 @@ use std::{ rc::{Rc, Weak}, }; +/// Helper trait which simplifies generation of the Markdown document represented +/// as a tree of `MdNodeRef`s. pub(super) trait ToMarkdown { + /// Drives the generation of the `MdNodeRef` tree by either mutating + /// the outer (parent) `MdNodeRef`, shared reference to the `MdNode` `node`, + /// or spawning new child `MdNodeRef` references to nodes. fn generate(&self, node: MdNodeRef); } +/// Interface required for any "content" that is expected to be generated into a +/// Markdown valid format, hence the constraint of `fmt::Display`. +/// +/// In essence, any AST element that is meant to be rendered into Markdown, should +/// define a type implementing this trait. pub(super) trait MdElement: fmt::Display + fmt::Debug + 'static { + /// Returns `Some(id)` of this `MdElement`. Here `id` is synonym for a Markdown actionable + /// link. fn id(&self) -> Option<&str>; + + /// Returns `Some(docs)`, the "docs" of this `MdElement`. fn docs(&self) -> Option<&str>; + + /// Sets `docs`, the "docs" of this `MdElement`. fn set_docs(&mut self, docs: &str); + fn as_any(&self) -> &dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any; } +/// A Markdown node containing: +/// * the Markdown renderable `content`, +/// * a weak reference to the `parent` `MdNode` (if any), and +/// * children `MdNodeRef`s +/// +/// `content` is expected to implement the `MdElement` trait. #[derive(Debug)] pub(super) struct MdNode { content: Box, @@ -24,10 +47,12 @@ pub(super) struct MdNode { children: Vec, } -fn walk_parents(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { +/// Helper function for walking the tree up from some starting `MdNode`, all the way up +/// to the root of the tree. +fn walk_ancestors(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { if let Some(parent) = parent.and_then(|x| x.upgrade()) { cb(parent.clone().into()); - walk_parents(parent.borrow().parent.as_ref(), cb) + walk_ancestors(parent.borrow().parent.as_ref(), cb) } } @@ -40,12 +65,14 @@ impl MdNode { } } - pub fn parents(&self) -> Vec { - let mut parents = Vec::new(); - walk_parents(self.parent.as_ref(), &mut |parent| parents.push(parent)); - parents + /// Returns all ancestors of this `MdNode` all the way to the tree's root. + pub fn ancestors(&self) -> Vec { + let mut ancestors = Vec::new(); + walk_ancestors(self.parent.as_ref(), &mut |parent| ancestors.push(parent)); + ancestors } + /// Returns all children of this `MdNode` in a BFS order. pub fn children(&self) -> Vec { let mut children = self.children.clone(); for child in &self.children { @@ -67,6 +94,7 @@ impl fmt::Display for MdNode { } } +/// Helper struct for storing a shared mutable reference to `MdNode`. #[derive(Debug)] pub(super) struct MdNodeRef(Rc>); @@ -75,6 +103,8 @@ impl MdNodeRef { Self(Rc::new(RefCell::new(MdNode::new(item)))) } + /// Spawns new `MdNode` child node, automatically wrapping it in a + /// `MdNodeRef` and creating a weak link from child to itself. pub fn new_child(&self, item: T) -> Self { let mut child_node = MdNode::new(item); child_node.parent = Some(Rc::downgrade(&self.0)); @@ -91,15 +121,23 @@ impl MdNodeRef { self.0.borrow_mut() } + /// Returns an immutable reference to `MdNode`'s `content` as-is, that + /// is as some type implementing the `MdElement` trait. pub fn any_ref(&self) -> cell::Ref> { cell::Ref::map(self.borrow(), |b| &b.content) } + /// Returns a mutable reference to `MdNode`'s `content` as-is, that + /// is as some type implementing the `MdElement` trait. pub fn any_ref_mut(&self) -> cell::RefMut> { cell::RefMut::map(self.borrow_mut(), |b| &mut b.content) } - pub fn content_mut(&self) -> cell::RefMut { + /// Returns a mutable reference to `MdNode`'s `content` cast to some type + /// `T` which implements `MdElement` trait. + /// + /// Panics if `content` cannot be downcast to `T`. + pub fn content_ref_mut(&self) -> cell::RefMut { cell::RefMut::map(self.borrow_mut(), |b| { let r = b.content.as_any_mut(); r.downcast_mut::().expect("reference is not T type") @@ -125,6 +163,9 @@ impl fmt::Display for MdNodeRef { } } +/// Struct representing the Markdown tree's root. +/// +/// Doesn't render to anything. #[derive(Debug, Default)] pub(super) struct MdRoot; @@ -154,6 +195,14 @@ impl fmt::Display for MdRoot { } } +/// Struct representing a Markdown section without any `docs`, consisting +/// of only a `header` (e.g., "###"), maybe some referencable `id` (i.e., +/// a Markdown link), and some `title`. +/// +/// Example rendering: +/// +/// ### Typenames +/// #[derive(Debug)] pub(super) struct MdSection { pub header: String, @@ -207,6 +256,24 @@ impl fmt::Display for MdSection { } } +/// Struct representing a Markdown section representing any `NamedType` element +/// of the AST. +/// Consists of: +/// * `header`, e.g., "###", or "-" for Enum variants, etc., +/// * referencable `id`, +/// * some `name`, e.g., `errno`, +/// * `docs` paragraph, and +/// * maybe `MdType`. +/// +/// Example rendering (recursive): +/// +/// ### `errno`: Enum(`u16`) +/// Error codes returned by... +/// +/// #### Variants +/// - `success` No error occurred... +/// - `2big` Argument list too long... +/// #[derive(Debug)] pub(super) struct MdNamedType { pub header: String, @@ -228,6 +295,7 @@ impl MdNamedType { } } +/// Helper struct encapsulating the `TypeRef` value. // TODO `MdType` should probably store `TypeRef` and recursively // unwind itself into final `String` representation rather than // being outright flattened. @@ -309,6 +377,28 @@ impl fmt::Display for MdNamedType { } } +/// Struct representing a Markdown section representing any `InterfaceFunc` element +/// of the AST. +/// Consists of: +/// * `header`, e.g., "###", +/// * referencable `id`, +/// * some `name`, e.g., `path_open`, +/// * function `inputs`, i.e., arguments, +/// * function `outputs`, i.e., results, and +/// * `docs` paragraph. +/// +/// Example rendering: +/// +/// ### Fn args_get(argv: `Pointer>`, ...) -> `errno` +/// Read command-line... +/// +/// #### Params +/// - `argv`: `Pointer>` Some docs... +/// - ... +/// +/// #### Results +/// - `error`: `errno` Error code... +/// #[derive(Debug)] pub(super) struct MdFunc { pub header: String, @@ -360,14 +450,14 @@ impl fmt::Display for MdFunc { let inputs = self .inputs .iter() - .map(|(name, r#type)| format!("{}: `{}`", name, r#type)) + .map(|(name, r#type)| format!("{}: {}", name, r#type)) .collect::>() .join(", "); // Expand outputs let outputs: Vec<_> = self .outputs .iter() - .map(|r#type| format!("`{}`", r#type)) + .map(|r#type| format!("{}", r#type)) .collect(); let outputs = match outputs.len() { 0 => "".to_owned(), @@ -378,7 +468,7 @@ impl fmt::Display for MdFunc { writeln!(f, "\n---\n")?; f.write_fmt(format_args!( - "{header} {link} Fn {name}({inputs}){outputs}", + "{header} {link} `{name}({inputs}){outputs}`", header = self.header, link = gen_link(&self.id), name = self.name, diff --git a/proposals/filesystem/tools/witx/src/docs/mod.rs b/proposals/filesystem/tools/witx/src/docs/mod.rs index e36e7499f..8f082cba5 100644 --- a/proposals/filesystem/tools/witx/src/docs/mod.rs +++ b/proposals/filesystem/tools/witx/src/docs/mod.rs @@ -8,10 +8,17 @@ use std::{ iter::FromIterator, }; +/// Enables generating Markdown formatted content. pub trait Documentation { fn to_md(&self) -> String; } +/// Helper function which given input `text` and a `HashSet` of existing links converts +/// any slice of the form '`{link}`' into either +/// 1. "[`{link}`](#{md_link})" where `md_link` is `link` with "::" replaced with "." +/// (in Markdown, scoping should be done with ".") if `md_link` exists in the `HashSet` +/// 2. "`{link}`" otherwise. That is, if `md_link` could not be found in the `HashSet`, we +/// just leave what we've consumed. fn parse_links>(text: S, existing_links: &HashSet) -> String { let text = text.as_ref(); let mut parsed_text = String::with_capacity(text.len()); @@ -56,16 +63,16 @@ impl Documentation for Document { fn to_md(&self) -> String { let root = MdNodeRef::new(MdRoot::default()); self.generate(root.clone()); - // Get all children of the `root` element + // Get all children of the `root` element. let children = root.borrow().children(); - // Gather all existing links in the document into a set + // Gather all existing links in the document into a set. let existing_links: HashSet = HashSet::from_iter( children .iter() .filter_map(|x| x.any_ref().id().map(String::from)), ); // Traverse each docs section of each child, and parse links - // logging a warning in case the generated is invalid + // logging a warning in case the generated is invalid. for child in children { let docs_with_links = child .any_ref() From 02d85ceaecfa473c0b399b9766f0144552dd8794 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 15 Jan 2020 11:43:47 +0100 Subject: [PATCH 0478/1772] Make imports explicit in docs/ast.rs --- proposals/clocks/tools/witx/src/docs/ast.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index a570012dd..41a6427a3 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -1,8 +1,16 @@ -use super::md::*; -use super::Documentation; -use crate::ast::*; -use crate::polyfill::*; -use crate::RepEquality; +use super::{ + md::{MdFunc, MdNamedType, MdNodeRef, MdSection, MdType, ToMarkdown}, + Documentation, +}; +use crate::{ + ast::{ + BuiltinType, Document, EnumDatatype, FlagsDatatype, HandleDatatype, IntDatatype, IntRepr, + InterfaceFunc, InterfaceFuncParam, Module, ModuleImport, ModuleImportVariant, NamedType, + StructDatatype, Type, TypeRef, UnionDatatype, + }, + polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, + RepEquality, +}; impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { From 918bd2f9fdd94c6a0d026987abab87b1a1b069ce Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 15 Jan 2020 11:43:47 +0100 Subject: [PATCH 0479/1772] Make imports explicit in docs/ast.rs --- proposals/random/tools/witx/src/docs/ast.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index a570012dd..41a6427a3 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -1,8 +1,16 @@ -use super::md::*; -use super::Documentation; -use crate::ast::*; -use crate::polyfill::*; -use crate::RepEquality; +use super::{ + md::{MdFunc, MdNamedType, MdNodeRef, MdSection, MdType, ToMarkdown}, + Documentation, +}; +use crate::{ + ast::{ + BuiltinType, Document, EnumDatatype, FlagsDatatype, HandleDatatype, IntDatatype, IntRepr, + InterfaceFunc, InterfaceFuncParam, Module, ModuleImport, ModuleImportVariant, NamedType, + StructDatatype, Type, TypeRef, UnionDatatype, + }, + polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, + RepEquality, +}; impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { From 4e613c776e54fdb01c1b489076f16a8e80cf910d Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 15 Jan 2020 11:43:47 +0100 Subject: [PATCH 0480/1772] Make imports explicit in docs/ast.rs --- .../filesystem/tools/witx/src/docs/ast.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index a570012dd..41a6427a3 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -1,8 +1,16 @@ -use super::md::*; -use super::Documentation; -use crate::ast::*; -use crate::polyfill::*; -use crate::RepEquality; +use super::{ + md::{MdFunc, MdNamedType, MdNodeRef, MdSection, MdType, ToMarkdown}, + Documentation, +}; +use crate::{ + ast::{ + BuiltinType, Document, EnumDatatype, FlagsDatatype, HandleDatatype, IntDatatype, IntRepr, + InterfaceFunc, InterfaceFuncParam, Module, ModuleImport, ModuleImportVariant, NamedType, + StructDatatype, Type, TypeRef, UnionDatatype, + }, + polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, + RepEquality, +}; impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { From 5022992df20605c3d0e5401410ce1998166154fc Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 15 Jan 2020 12:31:07 +0100 Subject: [PATCH 0481/1772] Add MdHeading type to refactor Markdown heading generation Adds `MdHeading` enum which polymorphs into either: * `MdHeading::Header { level }` representing a standard Markdown header at some `level` of nesting in the tree, or * `MdHeading::Bullet` representing a standard Markdown bullet for use with Markdown lists. --- proposals/clocks/tools/witx/src/docs/ast.rs | 90 +++++++++++++-------- proposals/clocks/tools/witx/src/docs/md.rs | 70 ++++++++++++---- 2 files changed, 113 insertions(+), 47 deletions(-) diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index 41a6427a3..a5f2ca952 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -1,5 +1,5 @@ use super::{ - md::{MdFunc, MdNamedType, MdNodeRef, MdSection, MdType, ToMarkdown}, + md::{MdFunc, MdHeading, MdNamedType, MdNodeRef, MdSection, MdType, ToMarkdown}, Documentation, }; use crate::{ @@ -12,14 +12,18 @@ use crate::{ RepEquality, }; +fn heading_from_node(node: &MdNodeRef, levels_down: usize) -> MdHeading { + MdHeading::new_header(node.borrow().ancestors().len() + levels_down) +} + impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - let types = node.new_child(MdSection::new(header.as_str(), "Types")); + let heading = heading_from_node(&node, 1); + let types = node.new_child(MdSection::new(heading, "Types")); for d in self.typenames() { let name = d.name.as_str(); let child = types.new_child(MdNamedType::new( - (header.clone() + "#").as_str(), + heading.new_level_down(), name, name, &d.docs, @@ -27,9 +31,9 @@ impl ToMarkdown for Document { d.generate(child.clone()); } - let modules = node.new_child(MdSection::new(header.as_str(), "Modules")); + let modules = node.new_child(MdSection::new(heading, "Modules")); for d in self.modules() { - let mut content = MdSection::new((header.clone() + "#").as_str(), d.name.as_str()); + let mut content = MdSection::new(heading.new_level_down(), d.name.as_str()); content.id = Some(d.name.as_str().to_owned()); let child = modules.new_child(content); d.generate(child.clone()); @@ -91,8 +95,8 @@ impl ToMarkdown for Type { impl ToMarkdown for EnumDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Variants")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Variants")); for variant in &self.variants { let name = variant.name.as_str(); @@ -101,7 +105,12 @@ impl ToMarkdown for EnumDatatype { } else { name.to_owned() }; - node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); + node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + &variant.docs, + )); } node.content_ref_mut::().r#type = Some(MdType::Enum { @@ -112,8 +121,8 @@ impl ToMarkdown for EnumDatatype { impl ToMarkdown for IntDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Consts")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Consts")); for r#const in &self.consts { let name = r#const.name.as_str(); @@ -122,7 +131,7 @@ impl ToMarkdown for IntDatatype { } else { name.to_owned() }; - let tt = MdNamedType::new("-", id.as_str(), name, &r#const.docs); + let tt = MdNamedType::new(MdHeading::new_bullet(), id.as_str(), name, &r#const.docs); // TODO handle r#const.value node.new_child(tt); } @@ -135,8 +144,8 @@ impl ToMarkdown for IntDatatype { impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Flags")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Flags")); for flag in &self.flags { let name = flag.name.as_str(); @@ -145,7 +154,12 @@ impl ToMarkdown for FlagsDatatype { } else { name.to_owned() }; - node.new_child(MdNamedType::new("-", id.as_str(), name, &flag.docs)); + node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + &flag.docs, + )); } node.content_ref_mut::().r#type = Some(MdType::Flags { @@ -156,8 +170,8 @@ impl ToMarkdown for FlagsDatatype { impl ToMarkdown for StructDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Struct members")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Struct members")); for member in &self.members { let name = member.name.as_str(); @@ -166,7 +180,12 @@ impl ToMarkdown for StructDatatype { } else { name.to_owned() }; - let n = node.new_child(MdNamedType::new("-", id.as_str(), name, &member.docs)); + let n = node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + &member.docs, + )); member.tref.generate(n.clone()); } @@ -176,8 +195,8 @@ impl ToMarkdown for StructDatatype { impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Union variants")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Union variants")); for variant in &self.variants { let name = variant.name.as_str(); @@ -186,7 +205,12 @@ impl ToMarkdown for UnionDatatype { } else { name.to_owned() }; - let n = node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); + let n = node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + &variant.docs, + )); variant.tref.generate(n.clone()); } @@ -197,26 +221,26 @@ impl ToMarkdown for UnionDatatype { impl ToMarkdown for HandleDatatype { fn generate(&self, node: MdNodeRef) { // TODO this needs more work - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Supertypes")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Supertypes")); node.content_ref_mut::().r#type = Some(MdType::Handle); } } impl ToMarkdown for Module { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - let imports = node.new_child(MdSection::new(header.as_str(), "Imports")); + let heading = heading_from_node(&node, 1); + let imports = node.new_child(MdSection::new(heading, "Imports")); for import in self.imports() { - let child = imports.new_child(MdSection::new((header.clone() + "#").as_str(), "")); + let child = imports.new_child(MdSection::new(heading.new_level_down(), "")); import.generate(child.clone()); } - let funcs = node.new_child(MdSection::new(header.as_str(), "Functions")); + let funcs = node.new_child(MdSection::new(heading, "Functions")); for func in self.funcs() { let name = func.name.as_str(); let child = funcs.new_child(MdFunc::new( - (header.clone() + "#").as_str(), + heading.new_level_down(), name, name, &func.docs, @@ -238,8 +262,8 @@ impl ToMarkdown for ModuleImport { impl ToMarkdown for InterfaceFunc { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Params")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Params")); for param in &self.params { let name = param.name.as_str(); let id = if let Some(id) = node.any_ref().id() { @@ -248,7 +272,7 @@ impl ToMarkdown for InterfaceFunc { name.to_owned() }; let child = node.new_child(MdNamedType::new( - "-", + MdHeading::new_bullet(), id.as_str(), name, param.name.as_str(), @@ -260,7 +284,7 @@ impl ToMarkdown for InterfaceFunc { .push((param.name.as_str().to_owned(), param.tref.type_name())); } - node.new_child(MdSection::new(header.as_str(), "Results")); + node.new_child(MdSection::new(heading, "Results")); for result in &self.results { let name = result.name.as_str(); let id = if let Some(id) = node.any_ref().id() { @@ -269,7 +293,7 @@ impl ToMarkdown for InterfaceFunc { name.to_owned() }; let child = node.new_child(MdNamedType::new( - "-", + MdHeading::new_bullet(), id.as_str(), name, result.name.as_str(), diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index d4f5f8d95..168eb77f4 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -195,6 +195,48 @@ impl fmt::Display for MdRoot { } } +/// Helper enum representing either a Markdown header "#" nested at some +/// `level` down the tree, or a bullet "-" in a list which is idempotent +/// to changing the nesting level. +#[derive(Debug, Clone, Copy)] +pub(super) enum MdHeading { + Header { level: usize }, + Bullet, +} + +impl MdHeading { + /// Creates new instance of `MdHeading::Header` variant nested at some + /// `level` down the Markdown tree. + pub fn new_header(level: usize) -> Self { + MdHeading::Header { level } + } + + /// Creates new instance of `MdHeading::Bullet` variant. + pub fn new_bullet() -> Self { + MdHeading::Bullet + } + + /// Copies `MdHeading` and if `MdHeading::Header`, pushes it down one + /// level in the Markdown tree by incrementing `level`. + pub fn new_level_down(&self) -> Self { + let mut copy = *self; + if let Self::Header { ref mut level } = &mut copy { + *level += 1; + } + copy + } +} + +impl fmt::Display for MdHeading { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let as_string = match self { + Self::Header { level } => "#".repeat(*level), + Self::Bullet => "-".to_owned(), + }; + f.write_str(&as_string) + } +} + /// Struct representing a Markdown section without any `docs`, consisting /// of only a `header` (e.g., "###"), maybe some referencable `id` (i.e., /// a Markdown link), and some `title`. @@ -205,15 +247,15 @@ impl fmt::Display for MdRoot { /// #[derive(Debug)] pub(super) struct MdSection { - pub header: String, + pub heading: MdHeading, pub id: Option, pub title: String, } impl MdSection { - pub fn new>(header: S, title: S) -> Self { + pub fn new>(heading: MdHeading, title: S) -> Self { Self { - header: header.as_ref().to_owned(), + heading, id: None, title: title.as_ref().to_owned(), } @@ -246,7 +288,7 @@ fn gen_link>(id: S) -> String { impl fmt::Display for MdSection { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_fmt(format_args!("{} ", self.header))?; + f.write_fmt(format_args!("{} ", self.heading))?; if let Some(id) = &self.id { f.write_fmt(format_args!("{} ", gen_link(id)))?; @@ -276,7 +318,7 @@ impl fmt::Display for MdSection { /// #[derive(Debug)] pub(super) struct MdNamedType { - pub header: String, + pub heading: MdHeading, pub id: String, pub name: String, pub docs: String, @@ -284,9 +326,9 @@ pub(super) struct MdNamedType { } impl MdNamedType { - pub fn new>(header: S, id: S, name: S, docs: S) -> Self { + pub fn new>(heading: MdHeading, id: S, name: S, docs: S) -> Self { Self { - header: header.as_ref().to_owned(), + heading, id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), docs: docs.as_ref().to_owned(), @@ -363,8 +405,8 @@ impl MdElement for MdNamedType { impl fmt::Display for MdNamedType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_fmt(format_args!( - "{header} {link} `{name}`", - header = self.header, + "{heading} {link} `{name}`", + heading = self.heading, link = gen_link(&self.id), name = self.name, ))?; @@ -401,7 +443,7 @@ impl fmt::Display for MdNamedType { /// #[derive(Debug)] pub(super) struct MdFunc { - pub header: String, + pub heading: MdHeading, pub id: String, pub name: String, pub inputs: Vec<(String, String)>, @@ -410,9 +452,9 @@ pub(super) struct MdFunc { } impl MdFunc { - pub fn new>(header: S, id: S, name: S, docs: S) -> Self { + pub fn new>(heading: MdHeading, id: S, name: S, docs: S) -> Self { Self { - header: header.as_ref().to_owned(), + heading, id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), inputs: vec![], @@ -468,8 +510,8 @@ impl fmt::Display for MdFunc { writeln!(f, "\n---\n")?; f.write_fmt(format_args!( - "{header} {link} `{name}({inputs}){outputs}`", - header = self.header, + "{heading} {link} `{name}({inputs}){outputs}`", + heading = self.heading, link = gen_link(&self.id), name = self.name, inputs = inputs, From 102e6d43d4ea39f6c9973ce2ba77b0aeff48ee83 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 15 Jan 2020 12:31:07 +0100 Subject: [PATCH 0482/1772] Add MdHeading type to refactor Markdown heading generation Adds `MdHeading` enum which polymorphs into either: * `MdHeading::Header { level }` representing a standard Markdown header at some `level` of nesting in the tree, or * `MdHeading::Bullet` representing a standard Markdown bullet for use with Markdown lists. --- proposals/random/tools/witx/src/docs/ast.rs | 90 +++++++++++++-------- proposals/random/tools/witx/src/docs/md.rs | 70 ++++++++++++---- 2 files changed, 113 insertions(+), 47 deletions(-) diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index 41a6427a3..a5f2ca952 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -1,5 +1,5 @@ use super::{ - md::{MdFunc, MdNamedType, MdNodeRef, MdSection, MdType, ToMarkdown}, + md::{MdFunc, MdHeading, MdNamedType, MdNodeRef, MdSection, MdType, ToMarkdown}, Documentation, }; use crate::{ @@ -12,14 +12,18 @@ use crate::{ RepEquality, }; +fn heading_from_node(node: &MdNodeRef, levels_down: usize) -> MdHeading { + MdHeading::new_header(node.borrow().ancestors().len() + levels_down) +} + impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - let types = node.new_child(MdSection::new(header.as_str(), "Types")); + let heading = heading_from_node(&node, 1); + let types = node.new_child(MdSection::new(heading, "Types")); for d in self.typenames() { let name = d.name.as_str(); let child = types.new_child(MdNamedType::new( - (header.clone() + "#").as_str(), + heading.new_level_down(), name, name, &d.docs, @@ -27,9 +31,9 @@ impl ToMarkdown for Document { d.generate(child.clone()); } - let modules = node.new_child(MdSection::new(header.as_str(), "Modules")); + let modules = node.new_child(MdSection::new(heading, "Modules")); for d in self.modules() { - let mut content = MdSection::new((header.clone() + "#").as_str(), d.name.as_str()); + let mut content = MdSection::new(heading.new_level_down(), d.name.as_str()); content.id = Some(d.name.as_str().to_owned()); let child = modules.new_child(content); d.generate(child.clone()); @@ -91,8 +95,8 @@ impl ToMarkdown for Type { impl ToMarkdown for EnumDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Variants")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Variants")); for variant in &self.variants { let name = variant.name.as_str(); @@ -101,7 +105,12 @@ impl ToMarkdown for EnumDatatype { } else { name.to_owned() }; - node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); + node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + &variant.docs, + )); } node.content_ref_mut::().r#type = Some(MdType::Enum { @@ -112,8 +121,8 @@ impl ToMarkdown for EnumDatatype { impl ToMarkdown for IntDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Consts")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Consts")); for r#const in &self.consts { let name = r#const.name.as_str(); @@ -122,7 +131,7 @@ impl ToMarkdown for IntDatatype { } else { name.to_owned() }; - let tt = MdNamedType::new("-", id.as_str(), name, &r#const.docs); + let tt = MdNamedType::new(MdHeading::new_bullet(), id.as_str(), name, &r#const.docs); // TODO handle r#const.value node.new_child(tt); } @@ -135,8 +144,8 @@ impl ToMarkdown for IntDatatype { impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Flags")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Flags")); for flag in &self.flags { let name = flag.name.as_str(); @@ -145,7 +154,12 @@ impl ToMarkdown for FlagsDatatype { } else { name.to_owned() }; - node.new_child(MdNamedType::new("-", id.as_str(), name, &flag.docs)); + node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + &flag.docs, + )); } node.content_ref_mut::().r#type = Some(MdType::Flags { @@ -156,8 +170,8 @@ impl ToMarkdown for FlagsDatatype { impl ToMarkdown for StructDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Struct members")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Struct members")); for member in &self.members { let name = member.name.as_str(); @@ -166,7 +180,12 @@ impl ToMarkdown for StructDatatype { } else { name.to_owned() }; - let n = node.new_child(MdNamedType::new("-", id.as_str(), name, &member.docs)); + let n = node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + &member.docs, + )); member.tref.generate(n.clone()); } @@ -176,8 +195,8 @@ impl ToMarkdown for StructDatatype { impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Union variants")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Union variants")); for variant in &self.variants { let name = variant.name.as_str(); @@ -186,7 +205,12 @@ impl ToMarkdown for UnionDatatype { } else { name.to_owned() }; - let n = node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); + let n = node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + &variant.docs, + )); variant.tref.generate(n.clone()); } @@ -197,26 +221,26 @@ impl ToMarkdown for UnionDatatype { impl ToMarkdown for HandleDatatype { fn generate(&self, node: MdNodeRef) { // TODO this needs more work - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Supertypes")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Supertypes")); node.content_ref_mut::().r#type = Some(MdType::Handle); } } impl ToMarkdown for Module { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - let imports = node.new_child(MdSection::new(header.as_str(), "Imports")); + let heading = heading_from_node(&node, 1); + let imports = node.new_child(MdSection::new(heading, "Imports")); for import in self.imports() { - let child = imports.new_child(MdSection::new((header.clone() + "#").as_str(), "")); + let child = imports.new_child(MdSection::new(heading.new_level_down(), "")); import.generate(child.clone()); } - let funcs = node.new_child(MdSection::new(header.as_str(), "Functions")); + let funcs = node.new_child(MdSection::new(heading, "Functions")); for func in self.funcs() { let name = func.name.as_str(); let child = funcs.new_child(MdFunc::new( - (header.clone() + "#").as_str(), + heading.new_level_down(), name, name, &func.docs, @@ -238,8 +262,8 @@ impl ToMarkdown for ModuleImport { impl ToMarkdown for InterfaceFunc { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Params")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Params")); for param in &self.params { let name = param.name.as_str(); let id = if let Some(id) = node.any_ref().id() { @@ -248,7 +272,7 @@ impl ToMarkdown for InterfaceFunc { name.to_owned() }; let child = node.new_child(MdNamedType::new( - "-", + MdHeading::new_bullet(), id.as_str(), name, param.name.as_str(), @@ -260,7 +284,7 @@ impl ToMarkdown for InterfaceFunc { .push((param.name.as_str().to_owned(), param.tref.type_name())); } - node.new_child(MdSection::new(header.as_str(), "Results")); + node.new_child(MdSection::new(heading, "Results")); for result in &self.results { let name = result.name.as_str(); let id = if let Some(id) = node.any_ref().id() { @@ -269,7 +293,7 @@ impl ToMarkdown for InterfaceFunc { name.to_owned() }; let child = node.new_child(MdNamedType::new( - "-", + MdHeading::new_bullet(), id.as_str(), name, result.name.as_str(), diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index d4f5f8d95..168eb77f4 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -195,6 +195,48 @@ impl fmt::Display for MdRoot { } } +/// Helper enum representing either a Markdown header "#" nested at some +/// `level` down the tree, or a bullet "-" in a list which is idempotent +/// to changing the nesting level. +#[derive(Debug, Clone, Copy)] +pub(super) enum MdHeading { + Header { level: usize }, + Bullet, +} + +impl MdHeading { + /// Creates new instance of `MdHeading::Header` variant nested at some + /// `level` down the Markdown tree. + pub fn new_header(level: usize) -> Self { + MdHeading::Header { level } + } + + /// Creates new instance of `MdHeading::Bullet` variant. + pub fn new_bullet() -> Self { + MdHeading::Bullet + } + + /// Copies `MdHeading` and if `MdHeading::Header`, pushes it down one + /// level in the Markdown tree by incrementing `level`. + pub fn new_level_down(&self) -> Self { + let mut copy = *self; + if let Self::Header { ref mut level } = &mut copy { + *level += 1; + } + copy + } +} + +impl fmt::Display for MdHeading { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let as_string = match self { + Self::Header { level } => "#".repeat(*level), + Self::Bullet => "-".to_owned(), + }; + f.write_str(&as_string) + } +} + /// Struct representing a Markdown section without any `docs`, consisting /// of only a `header` (e.g., "###"), maybe some referencable `id` (i.e., /// a Markdown link), and some `title`. @@ -205,15 +247,15 @@ impl fmt::Display for MdRoot { /// #[derive(Debug)] pub(super) struct MdSection { - pub header: String, + pub heading: MdHeading, pub id: Option, pub title: String, } impl MdSection { - pub fn new>(header: S, title: S) -> Self { + pub fn new>(heading: MdHeading, title: S) -> Self { Self { - header: header.as_ref().to_owned(), + heading, id: None, title: title.as_ref().to_owned(), } @@ -246,7 +288,7 @@ fn gen_link>(id: S) -> String { impl fmt::Display for MdSection { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_fmt(format_args!("{} ", self.header))?; + f.write_fmt(format_args!("{} ", self.heading))?; if let Some(id) = &self.id { f.write_fmt(format_args!("{} ", gen_link(id)))?; @@ -276,7 +318,7 @@ impl fmt::Display for MdSection { /// #[derive(Debug)] pub(super) struct MdNamedType { - pub header: String, + pub heading: MdHeading, pub id: String, pub name: String, pub docs: String, @@ -284,9 +326,9 @@ pub(super) struct MdNamedType { } impl MdNamedType { - pub fn new>(header: S, id: S, name: S, docs: S) -> Self { + pub fn new>(heading: MdHeading, id: S, name: S, docs: S) -> Self { Self { - header: header.as_ref().to_owned(), + heading, id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), docs: docs.as_ref().to_owned(), @@ -363,8 +405,8 @@ impl MdElement for MdNamedType { impl fmt::Display for MdNamedType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_fmt(format_args!( - "{header} {link} `{name}`", - header = self.header, + "{heading} {link} `{name}`", + heading = self.heading, link = gen_link(&self.id), name = self.name, ))?; @@ -401,7 +443,7 @@ impl fmt::Display for MdNamedType { /// #[derive(Debug)] pub(super) struct MdFunc { - pub header: String, + pub heading: MdHeading, pub id: String, pub name: String, pub inputs: Vec<(String, String)>, @@ -410,9 +452,9 @@ pub(super) struct MdFunc { } impl MdFunc { - pub fn new>(header: S, id: S, name: S, docs: S) -> Self { + pub fn new>(heading: MdHeading, id: S, name: S, docs: S) -> Self { Self { - header: header.as_ref().to_owned(), + heading, id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), inputs: vec![], @@ -468,8 +510,8 @@ impl fmt::Display for MdFunc { writeln!(f, "\n---\n")?; f.write_fmt(format_args!( - "{header} {link} `{name}({inputs}){outputs}`", - header = self.header, + "{heading} {link} `{name}({inputs}){outputs}`", + heading = self.heading, link = gen_link(&self.id), name = self.name, inputs = inputs, From 74b499b1d7dff7afabcc20f01480c53f0cf9d251 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 15 Jan 2020 12:31:07 +0100 Subject: [PATCH 0483/1772] Add MdHeading type to refactor Markdown heading generation Adds `MdHeading` enum which polymorphs into either: * `MdHeading::Header { level }` representing a standard Markdown header at some `level` of nesting in the tree, or * `MdHeading::Bullet` representing a standard Markdown bullet for use with Markdown lists. --- .../filesystem/tools/witx/src/docs/ast.rs | 90 ++++++++++++------- .../filesystem/tools/witx/src/docs/md.rs | 70 ++++++++++++--- 2 files changed, 113 insertions(+), 47 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index 41a6427a3..a5f2ca952 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -1,5 +1,5 @@ use super::{ - md::{MdFunc, MdNamedType, MdNodeRef, MdSection, MdType, ToMarkdown}, + md::{MdFunc, MdHeading, MdNamedType, MdNodeRef, MdSection, MdType, ToMarkdown}, Documentation, }; use crate::{ @@ -12,14 +12,18 @@ use crate::{ RepEquality, }; +fn heading_from_node(node: &MdNodeRef, levels_down: usize) -> MdHeading { + MdHeading::new_header(node.borrow().ancestors().len() + levels_down) +} + impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - let types = node.new_child(MdSection::new(header.as_str(), "Types")); + let heading = heading_from_node(&node, 1); + let types = node.new_child(MdSection::new(heading, "Types")); for d in self.typenames() { let name = d.name.as_str(); let child = types.new_child(MdNamedType::new( - (header.clone() + "#").as_str(), + heading.new_level_down(), name, name, &d.docs, @@ -27,9 +31,9 @@ impl ToMarkdown for Document { d.generate(child.clone()); } - let modules = node.new_child(MdSection::new(header.as_str(), "Modules")); + let modules = node.new_child(MdSection::new(heading, "Modules")); for d in self.modules() { - let mut content = MdSection::new((header.clone() + "#").as_str(), d.name.as_str()); + let mut content = MdSection::new(heading.new_level_down(), d.name.as_str()); content.id = Some(d.name.as_str().to_owned()); let child = modules.new_child(content); d.generate(child.clone()); @@ -91,8 +95,8 @@ impl ToMarkdown for Type { impl ToMarkdown for EnumDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Variants")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Variants")); for variant in &self.variants { let name = variant.name.as_str(); @@ -101,7 +105,12 @@ impl ToMarkdown for EnumDatatype { } else { name.to_owned() }; - node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); + node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + &variant.docs, + )); } node.content_ref_mut::().r#type = Some(MdType::Enum { @@ -112,8 +121,8 @@ impl ToMarkdown for EnumDatatype { impl ToMarkdown for IntDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Consts")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Consts")); for r#const in &self.consts { let name = r#const.name.as_str(); @@ -122,7 +131,7 @@ impl ToMarkdown for IntDatatype { } else { name.to_owned() }; - let tt = MdNamedType::new("-", id.as_str(), name, &r#const.docs); + let tt = MdNamedType::new(MdHeading::new_bullet(), id.as_str(), name, &r#const.docs); // TODO handle r#const.value node.new_child(tt); } @@ -135,8 +144,8 @@ impl ToMarkdown for IntDatatype { impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Flags")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Flags")); for flag in &self.flags { let name = flag.name.as_str(); @@ -145,7 +154,12 @@ impl ToMarkdown for FlagsDatatype { } else { name.to_owned() }; - node.new_child(MdNamedType::new("-", id.as_str(), name, &flag.docs)); + node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + &flag.docs, + )); } node.content_ref_mut::().r#type = Some(MdType::Flags { @@ -156,8 +170,8 @@ impl ToMarkdown for FlagsDatatype { impl ToMarkdown for StructDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Struct members")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Struct members")); for member in &self.members { let name = member.name.as_str(); @@ -166,7 +180,12 @@ impl ToMarkdown for StructDatatype { } else { name.to_owned() }; - let n = node.new_child(MdNamedType::new("-", id.as_str(), name, &member.docs)); + let n = node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + &member.docs, + )); member.tref.generate(n.clone()); } @@ -176,8 +195,8 @@ impl ToMarkdown for StructDatatype { impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Union variants")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Union variants")); for variant in &self.variants { let name = variant.name.as_str(); @@ -186,7 +205,12 @@ impl ToMarkdown for UnionDatatype { } else { name.to_owned() }; - let n = node.new_child(MdNamedType::new("-", id.as_str(), name, &variant.docs)); + let n = node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + &variant.docs, + )); variant.tref.generate(n.clone()); } @@ -197,26 +221,26 @@ impl ToMarkdown for UnionDatatype { impl ToMarkdown for HandleDatatype { fn generate(&self, node: MdNodeRef) { // TODO this needs more work - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Supertypes")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Supertypes")); node.content_ref_mut::().r#type = Some(MdType::Handle); } } impl ToMarkdown for Module { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - let imports = node.new_child(MdSection::new(header.as_str(), "Imports")); + let heading = heading_from_node(&node, 1); + let imports = node.new_child(MdSection::new(heading, "Imports")); for import in self.imports() { - let child = imports.new_child(MdSection::new((header.clone() + "#").as_str(), "")); + let child = imports.new_child(MdSection::new(heading.new_level_down(), "")); import.generate(child.clone()); } - let funcs = node.new_child(MdSection::new(header.as_str(), "Functions")); + let funcs = node.new_child(MdSection::new(heading, "Functions")); for func in self.funcs() { let name = func.name.as_str(); let child = funcs.new_child(MdFunc::new( - (header.clone() + "#").as_str(), + heading.new_level_down(), name, name, &func.docs, @@ -238,8 +262,8 @@ impl ToMarkdown for ModuleImport { impl ToMarkdown for InterfaceFunc { fn generate(&self, node: MdNodeRef) { - let header = "#".repeat(node.borrow().ancestors().len() + 1); - node.new_child(MdSection::new(header.as_str(), "Params")); + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Params")); for param in &self.params { let name = param.name.as_str(); let id = if let Some(id) = node.any_ref().id() { @@ -248,7 +272,7 @@ impl ToMarkdown for InterfaceFunc { name.to_owned() }; let child = node.new_child(MdNamedType::new( - "-", + MdHeading::new_bullet(), id.as_str(), name, param.name.as_str(), @@ -260,7 +284,7 @@ impl ToMarkdown for InterfaceFunc { .push((param.name.as_str().to_owned(), param.tref.type_name())); } - node.new_child(MdSection::new(header.as_str(), "Results")); + node.new_child(MdSection::new(heading, "Results")); for result in &self.results { let name = result.name.as_str(); let id = if let Some(id) = node.any_ref().id() { @@ -269,7 +293,7 @@ impl ToMarkdown for InterfaceFunc { name.to_owned() }; let child = node.new_child(MdNamedType::new( - "-", + MdHeading::new_bullet(), id.as_str(), name, result.name.as_str(), diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index d4f5f8d95..168eb77f4 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -195,6 +195,48 @@ impl fmt::Display for MdRoot { } } +/// Helper enum representing either a Markdown header "#" nested at some +/// `level` down the tree, or a bullet "-" in a list which is idempotent +/// to changing the nesting level. +#[derive(Debug, Clone, Copy)] +pub(super) enum MdHeading { + Header { level: usize }, + Bullet, +} + +impl MdHeading { + /// Creates new instance of `MdHeading::Header` variant nested at some + /// `level` down the Markdown tree. + pub fn new_header(level: usize) -> Self { + MdHeading::Header { level } + } + + /// Creates new instance of `MdHeading::Bullet` variant. + pub fn new_bullet() -> Self { + MdHeading::Bullet + } + + /// Copies `MdHeading` and if `MdHeading::Header`, pushes it down one + /// level in the Markdown tree by incrementing `level`. + pub fn new_level_down(&self) -> Self { + let mut copy = *self; + if let Self::Header { ref mut level } = &mut copy { + *level += 1; + } + copy + } +} + +impl fmt::Display for MdHeading { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let as_string = match self { + Self::Header { level } => "#".repeat(*level), + Self::Bullet => "-".to_owned(), + }; + f.write_str(&as_string) + } +} + /// Struct representing a Markdown section without any `docs`, consisting /// of only a `header` (e.g., "###"), maybe some referencable `id` (i.e., /// a Markdown link), and some `title`. @@ -205,15 +247,15 @@ impl fmt::Display for MdRoot { /// #[derive(Debug)] pub(super) struct MdSection { - pub header: String, + pub heading: MdHeading, pub id: Option, pub title: String, } impl MdSection { - pub fn new>(header: S, title: S) -> Self { + pub fn new>(heading: MdHeading, title: S) -> Self { Self { - header: header.as_ref().to_owned(), + heading, id: None, title: title.as_ref().to_owned(), } @@ -246,7 +288,7 @@ fn gen_link>(id: S) -> String { impl fmt::Display for MdSection { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_fmt(format_args!("{} ", self.header))?; + f.write_fmt(format_args!("{} ", self.heading))?; if let Some(id) = &self.id { f.write_fmt(format_args!("{} ", gen_link(id)))?; @@ -276,7 +318,7 @@ impl fmt::Display for MdSection { /// #[derive(Debug)] pub(super) struct MdNamedType { - pub header: String, + pub heading: MdHeading, pub id: String, pub name: String, pub docs: String, @@ -284,9 +326,9 @@ pub(super) struct MdNamedType { } impl MdNamedType { - pub fn new>(header: S, id: S, name: S, docs: S) -> Self { + pub fn new>(heading: MdHeading, id: S, name: S, docs: S) -> Self { Self { - header: header.as_ref().to_owned(), + heading, id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), docs: docs.as_ref().to_owned(), @@ -363,8 +405,8 @@ impl MdElement for MdNamedType { impl fmt::Display for MdNamedType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_fmt(format_args!( - "{header} {link} `{name}`", - header = self.header, + "{heading} {link} `{name}`", + heading = self.heading, link = gen_link(&self.id), name = self.name, ))?; @@ -401,7 +443,7 @@ impl fmt::Display for MdNamedType { /// #[derive(Debug)] pub(super) struct MdFunc { - pub header: String, + pub heading: MdHeading, pub id: String, pub name: String, pub inputs: Vec<(String, String)>, @@ -410,9 +452,9 @@ pub(super) struct MdFunc { } impl MdFunc { - pub fn new>(header: S, id: S, name: S, docs: S) -> Self { + pub fn new>(heading: MdHeading, id: S, name: S, docs: S) -> Self { Self { - header: header.as_ref().to_owned(), + heading, id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), inputs: vec![], @@ -468,8 +510,8 @@ impl fmt::Display for MdFunc { writeln!(f, "\n---\n")?; f.write_fmt(format_args!( - "{header} {link} `{name}({inputs}){outputs}`", - header = self.header, + "{heading} {link} `{name}({inputs}){outputs}`", + heading = self.heading, link = gen_link(&self.id), name = self.name, inputs = inputs, From 305663c90bad0b7ca2596bef76fc9ea1b5a84d37 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 14 Jan 2020 16:20:46 -0800 Subject: [PATCH 0484/1772] witx validator: reject anonymous int type declarations ints are like enums or flags - they only really make sense to have a name --- proposals/clocks/tools/witx/src/validate.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index b640ba99d..4bb92aa89 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -229,6 +229,7 @@ impl DocValidationScope<'_> { } } TypedefSyntax::Enum { .. } + | TypedefSyntax::Int { .. } | TypedefSyntax::Flags { .. } | TypedefSyntax::Struct { .. } | TypedefSyntax::Union { .. } From 6651bb0df1d9ad89e26144beec2acf9063ff2858 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 14 Jan 2020 16:20:46 -0800 Subject: [PATCH 0485/1772] witx validator: reject anonymous int type declarations ints are like enums or flags - they only really make sense to have a name --- proposals/random/tools/witx/src/validate.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index b640ba99d..4bb92aa89 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -229,6 +229,7 @@ impl DocValidationScope<'_> { } } TypedefSyntax::Enum { .. } + | TypedefSyntax::Int { .. } | TypedefSyntax::Flags { .. } | TypedefSyntax::Struct { .. } | TypedefSyntax::Union { .. } From 0af39e2c77471ead36cf0ced3b94b87e9e790dc3 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 14 Jan 2020 16:20:46 -0800 Subject: [PATCH 0486/1772] witx validator: reject anonymous int type declarations ints are like enums or flags - they only really make sense to have a name --- proposals/filesystem/tools/witx/src/validate.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index b640ba99d..4bb92aa89 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -229,6 +229,7 @@ impl DocValidationScope<'_> { } } TypedefSyntax::Enum { .. } + | TypedefSyntax::Int { .. } | TypedefSyntax::Flags { .. } | TypedefSyntax::Struct { .. } | TypedefSyntax::Union { .. } From df23e79c08242567d25277927cb7969f80cfe915 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 14 Jan 2020 14:53:56 -0800 Subject: [PATCH 0487/1772] bump witx version to 0.7.0 --- proposals/clocks/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 950137af0..cb75c1753 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.6.0" +version = "0.7.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 8b9dd26f83b60c36190dbe0b34787d774c37ffab Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 14 Jan 2020 14:53:56 -0800 Subject: [PATCH 0488/1772] bump witx version to 0.7.0 --- proposals/random/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 950137af0..cb75c1753 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.6.0" +version = "0.7.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From a0ae3e62152dbe878766caeb8ab29d035eed5d30 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 14 Jan 2020 14:53:56 -0800 Subject: [PATCH 0489/1772] bump witx version to 0.7.0 --- proposals/filesystem/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 950137af0..cb75c1753 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.6.0" +version = "0.7.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 10c1f06c11699741130e30cdbfd19deef5703d01 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 15 Jan 2020 11:11:42 +0100 Subject: [PATCH 0490/1772] Fix some links in the docs This commit fixes some links in different places in the docs sections in `snapshot1` `*.witx` files so that they are consistent with type naming throughout the document. This will aid correct Markdown link generation by the `witx` tool directly from `*.witx` files. --- .../phases/snapshot/witx/typenames.witx | 32 +++++++++---------- .../snapshot/witx/wasi_snapshot_preview1.witx | 15 +++++---- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx index d8ce215d7..ee8c652ec 100644 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -200,7 +200,7 @@ ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflag::dsync`. + ;;; `path_open` with `fdflags::dsync`. $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; @@ -213,10 +213,10 @@ ;;; The right to invoke `fd_sync`. ;; ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflag::rsync` and `fdflag::dsync`. + ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to ;;; invoke `fd_tell`. $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. @@ -419,13 +419,13 @@ ;;; Which file time attributes to adjust. (typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim - ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. $mtim_now ) ) @@ -484,13 +484,13 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype (enum u8 - ;;; The time value of clock `subscription::u.clock.clock_id` has - ;;; reached timestamp `subscription::u.clock.timeout`. + ;;; The time value of clock `subscription_clock::id` has + ;;; reached timestamp `subscription_clock::timeout`. $clock - ;;; File descriptor `subscription::u.fd_readwrite.fd` has data + ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has data ;;; available for reading. This event always triggers for regular files. $fd_read - ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity + ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has capacity ;;; available for writing. This event always triggers for regular files. $fd_write ) @@ -539,14 +539,14 @@ ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription::u.clock.timeout.` +;;; `subscription_clock::timeout`. (typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription::u.clock.timeout` relative to the - ;;; current time value of clock `subscription::u.clock.clock_id.` + ;;; `subscription_clock::timeout` as an absolute timestamp of clock + ;;; `subscription_clock::id`. If clear, treat the timestamp + ;;; provided in `subscription_clock::timeout` relative to the + ;;; current time value of clock `subscription_clock::id`. $subscription_clock_abstime ) ) diff --git a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx index 44a297b8c..a453faf45 100644 --- a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -13,7 +13,7 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; The size of the array should match that returned by `args_sizes_get` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) @@ -29,7 +29,7 @@ ) ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) @@ -45,7 +45,8 @@ ) ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, + ;;; return `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno) @@ -123,7 +124,7 @@ ) ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd) ;;; The desired rights of the file descriptor. @@ -363,7 +364,7 @@ ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the - ;;; `dirfd` directory. + ;;; `path_open::fd` directory. (param $path string) ;;; The method by which to open the file. (param $oflags $oflags) @@ -398,7 +399,7 @@ ) ;;; Remove a directory. - ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Return `errno::notempty` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd) @@ -433,7 +434,7 @@ ;;; Unlink a file. - ;;; Return `EISDIR` if the path refers to a directory. + ;;; Return `errno::isdir` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd) From 3eb677c5b3eac7b3d407e72dce83222c1f0db609 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 15 Jan 2020 11:11:42 +0100 Subject: [PATCH 0491/1772] Fix some links in the docs This commit fixes some links in different places in the docs sections in `snapshot1` `*.witx` files so that they are consistent with type naming throughout the document. This will aid correct Markdown link generation by the `witx` tool directly from `*.witx` files. --- .../phases/snapshot/witx/typenames.witx | 32 +++++++++---------- .../snapshot/witx/wasi_snapshot_preview1.witx | 15 +++++---- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx index d8ce215d7..ee8c652ec 100644 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -200,7 +200,7 @@ ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflag::dsync`. + ;;; `path_open` with `fdflags::dsync`. $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; @@ -213,10 +213,10 @@ ;;; The right to invoke `fd_sync`. ;; ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflag::rsync` and `fdflag::dsync`. + ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to ;;; invoke `fd_tell`. $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. @@ -419,13 +419,13 @@ ;;; Which file time attributes to adjust. (typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim - ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. $mtim_now ) ) @@ -484,13 +484,13 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype (enum u8 - ;;; The time value of clock `subscription::u.clock.clock_id` has - ;;; reached timestamp `subscription::u.clock.timeout`. + ;;; The time value of clock `subscription_clock::id` has + ;;; reached timestamp `subscription_clock::timeout`. $clock - ;;; File descriptor `subscription::u.fd_readwrite.fd` has data + ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has data ;;; available for reading. This event always triggers for regular files. $fd_read - ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity + ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has capacity ;;; available for writing. This event always triggers for regular files. $fd_write ) @@ -539,14 +539,14 @@ ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription::u.clock.timeout.` +;;; `subscription_clock::timeout`. (typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription::u.clock.timeout` relative to the - ;;; current time value of clock `subscription::u.clock.clock_id.` + ;;; `subscription_clock::timeout` as an absolute timestamp of clock + ;;; `subscription_clock::id`. If clear, treat the timestamp + ;;; provided in `subscription_clock::timeout` relative to the + ;;; current time value of clock `subscription_clock::id`. $subscription_clock_abstime ) ) diff --git a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx index 44a297b8c..a453faf45 100644 --- a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -13,7 +13,7 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; The size of the array should match that returned by `args_sizes_get` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) @@ -29,7 +29,7 @@ ) ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) @@ -45,7 +45,8 @@ ) ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, + ;;; return `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno) @@ -123,7 +124,7 @@ ) ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd) ;;; The desired rights of the file descriptor. @@ -363,7 +364,7 @@ ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the - ;;; `dirfd` directory. + ;;; `path_open::fd` directory. (param $path string) ;;; The method by which to open the file. (param $oflags $oflags) @@ -398,7 +399,7 @@ ) ;;; Remove a directory. - ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Return `errno::notempty` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd) @@ -433,7 +434,7 @@ ;;; Unlink a file. - ;;; Return `EISDIR` if the path refers to a directory. + ;;; Return `errno::isdir` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd) From 0c3ea722b1cb8a75548d9932bfbb6f6b41a5bd96 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 15 Jan 2020 11:11:42 +0100 Subject: [PATCH 0492/1772] Fix some links in the docs This commit fixes some links in different places in the docs sections in `snapshot1` `*.witx` files so that they are consistent with type naming throughout the document. This will aid correct Markdown link generation by the `witx` tool directly from `*.witx` files. --- .../phases/snapshot/witx/typenames.witx | 32 +++++++++---------- .../snapshot/witx/wasi_snapshot_preview1.witx | 15 +++++---- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx index d8ce215d7..ee8c652ec 100644 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -200,7 +200,7 @@ ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflag::dsync`. + ;;; `path_open` with `fdflags::dsync`. $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; @@ -213,10 +213,10 @@ ;;; The right to invoke `fd_sync`. ;; ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflag::rsync` and `fdflag::dsync`. + ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to ;;; invoke `fd_tell`. $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. @@ -419,13 +419,13 @@ ;;; Which file time attributes to adjust. (typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim - ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. $mtim_now ) ) @@ -484,13 +484,13 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype (enum u8 - ;;; The time value of clock `subscription::u.clock.clock_id` has - ;;; reached timestamp `subscription::u.clock.timeout`. + ;;; The time value of clock `subscription_clock::id` has + ;;; reached timestamp `subscription_clock::timeout`. $clock - ;;; File descriptor `subscription::u.fd_readwrite.fd` has data + ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has data ;;; available for reading. This event always triggers for regular files. $fd_read - ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity + ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has capacity ;;; available for writing. This event always triggers for regular files. $fd_write ) @@ -539,14 +539,14 @@ ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription::u.clock.timeout.` +;;; `subscription_clock::timeout`. (typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription::u.clock.timeout` relative to the - ;;; current time value of clock `subscription::u.clock.clock_id.` + ;;; `subscription_clock::timeout` as an absolute timestamp of clock + ;;; `subscription_clock::id`. If clear, treat the timestamp + ;;; provided in `subscription_clock::timeout` relative to the + ;;; current time value of clock `subscription_clock::id`. $subscription_clock_abstime ) ) diff --git a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx index 44a297b8c..a453faf45 100644 --- a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -13,7 +13,7 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; The size of the array should match that returned by `args_sizes_get` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) @@ -29,7 +29,7 @@ ) ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) @@ -45,7 +45,8 @@ ) ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, + ;;; return `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno) @@ -123,7 +124,7 @@ ) ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd) ;;; The desired rights of the file descriptor. @@ -363,7 +364,7 @@ ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the - ;;; `dirfd` directory. + ;;; `path_open::fd` directory. (param $path string) ;;; The method by which to open the file. (param $oflags $oflags) @@ -398,7 +399,7 @@ ) ;;; Remove a directory. - ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Return `errno::notempty` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd) @@ -433,7 +434,7 @@ ;;; Unlink a file. - ;;; Return `EISDIR` if the path refers to a directory. + ;;; Return `errno::isdir` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd) From 841d83dc3fedd613be2810ed0b1f6c700bc0a002 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 13:50:06 -0800 Subject: [PATCH 0493/1772] witx: add executable mode to generate docs for the wasi repo this changes the usage of existing commands :( but to be fair, having an argument before the subcommand was not a common or good idiom. --- proposals/clocks/tools/witx/Cargo.toml | 1 + proposals/clocks/tools/witx/src/lib.rs | 2 + proposals/clocks/tools/witx/src/main.rs | 107 ++++++++++++++-------- proposals/clocks/tools/witx/src/phases.rs | 68 ++++++++++++++ proposals/clocks/tools/witx/tests/wasi.rs | 23 ++--- 5 files changed, 145 insertions(+), 56 deletions(-) create mode 100644 proposals/clocks/tools/witx/src/phases.rs diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index cb75c1753..5f75172a8 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -23,3 +23,4 @@ wast = "3.0.4" thiserror = "1.0" log = "0.4" pretty_env_logger = "0.3" +anyhow = "1" diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 05586ec96..ba4df6889 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -10,6 +10,8 @@ mod io; mod layout; /// Witx syntax parsing from SExprs mod parser; +/// Paths to witx documents for various proposal phases +pub mod phases; /// Calculate required polyfill between interfaces pub mod polyfill; /// Render ast to text diff --git a/proposals/clocks/tools/witx/src/main.rs b/proposals/clocks/tools/witx/src/main.rs index f89822d7f..3fcc6f7f2 100644 --- a/proposals/clocks/tools/witx/src/main.rs +++ b/proposals/clocks/tools/witx/src/main.rs @@ -1,20 +1,15 @@ -use clap::{App, Arg, SubCommand}; +use clap::{App, Arg, ArgMatches, SubCommand}; use std::collections::HashMap; use std::fs::File; use std::io::Write; +use std::path::Path; use std::process; -use witx::{load, Documentation}; +use witx::{load, phases, Document, Documentation}; pub fn main() { let app = App::new("witx") .version(env!("CARGO_PKG_VERSION")) .about("Validate and process witx files") - .arg( - Arg::with_name("input") - .required(true) - .multiple(true) - .help("path to root of witx document"), - ) .arg( Arg::with_name("verbose") .short("v") @@ -25,6 +20,12 @@ pub fn main() { .subcommand( SubCommand::with_name("docs") .about("Output documentation") + .arg( + Arg::with_name("input") + .required(true) + .multiple(true) + .help("path to root of witx document"), + ) .arg( Arg::with_name("output") .short("o") @@ -36,6 +37,12 @@ pub fn main() { .subcommand( SubCommand::with_name("polyfill") .about("Examine differences between interfaces") + .arg( + Arg::with_name("input") + .required(true) + .multiple(true) + .help("path to root of witx document"), + ) .arg( Arg::with_name("older_interface") .required(true) @@ -52,49 +59,50 @@ pub fn main() { .help("module to examine. Use newname=oldname syntax if name is different between new and old interfaces"), ), ) + .subcommand( + SubCommand::with_name("repo-docs") + .about("Update documentation in WASI repository to reflect witx specs") + ) .get_matches(); - let inputs = app - .values_of("input") - .expect("at least one input required") - .collect::>(); - - let load_docs = { - |inputs: &[&str]| match load(inputs) { - Ok(doc) => doc, - Err(e) => { - println!("{}", e.report()); - if app.is_present("verbose") { - println!("{:?}", e); + let load_witx = { + |args: &ArgMatches, field: &str| -> Document { + let inputs = args + .values_of(field) + .expect(&format!("required argument: {}", field)) + .collect::>(); + match load(&inputs) { + Ok(doc) => { + if app.is_present("verbose") { + println!("{}: {:?}", field, doc) + } + doc + } + Err(e) => { + println!("{}", e.report()); + if app.is_present("verbose") { + println!("{:?}", e); + } + process::exit(1) } - process::exit(1) } } }; pretty_env_logger::init(); - let doc = load_docs(&inputs); - if app.is_present("verbose") { - println!("{:?}", doc) - } - - if let Some(docs_command) = app.subcommand_matches("docs") { - let md = doc.to_md(); - if let Some(output) = docs_command.value_of("output") { - let mut file = File::create(output).expect("create output file"); - file.write_all(md.as_bytes()).expect("write output file"); + if let Some(docs_args) = app.subcommand_matches("docs") { + let doc = load_witx(&docs_args, "input"); + if let Some(output) = docs_args.value_of("output") { + write_docs(&doc, output) } else { - println!("{}", md) + println!("{}", doc.to_md()) } - } else if let Some(polyfill_command) = app.subcommand_matches("polyfill") { - let older_inputs = polyfill_command - .values_of("older_interface") - .expect("at least one older_interface argument required") - .collect::>(); - let older_doc = load_docs(&older_inputs); + } else if let Some(polyfill_args) = app.subcommand_matches("polyfill") { + let doc = load_witx(&polyfill_args, "input"); + let older_doc = load_witx(&polyfill_args, "older_interface"); - let module_mapping_args = polyfill_command + let module_mapping_args = polyfill_args .values_of("module_mapping") .expect("at least one module_mapping argument required") .collect::>(); @@ -106,9 +114,30 @@ pub fn main() { if app.is_present("verbose") { println!("{:?}", polyfill); } + } else if app.subcommand_matches("repo-docs").is_some() { + for phase in &[ + phases::snapshot().unwrap(), + phases::ephemeral().unwrap(), + phases::old::snapshot_0().unwrap(), + ] { + let doc = load(&phase).expect("parse phase"); + let path = phase + .get(0) + .expect("at least one path") + .parent() + .expect("drop file") + .join("../docs.md"); + write_docs(&doc, &path); + } } } +fn write_docs>(document: &Document, path: P) { + let mut file = File::create(path.as_ref()).expect("create output file"); + file.write_all(document.to_md().as_bytes()) + .expect("write output file"); +} + fn parse_module_mapping(ms: &[&str]) -> HashMap { let mut o = HashMap::new(); for m in ms { diff --git a/proposals/clocks/tools/witx/src/phases.rs b/proposals/clocks/tools/witx/src/phases.rs new file mode 100644 index 000000000..1bc0c381a --- /dev/null +++ b/proposals/clocks/tools/witx/src/phases.rs @@ -0,0 +1,68 @@ +use anyhow::{anyhow, Result}; +use std::env; +use std::path::PathBuf; + +pub fn snapshot() -> Result> { + let root = repo_root()?; + let snapshot = root.join("phases/snapshot/witx"); + let paths = vec![snapshot.join("wasi_snapshot_preview1.witx")]; + ensure_exists(&paths)?; + Ok(paths) +} + +pub fn ephemeral() -> Result> { + let root = repo_root()?; + let ephemeral = root.join("phases/ephemeral/witx"); + let paths = vec![ + ephemeral.join("wasi_ephemeral_args.witx"), + ephemeral.join("wasi_ephemeral_clock.witx"), + ephemeral.join("wasi_ephemeral_environ.witx"), + ephemeral.join("wasi_ephemeral_fd.witx"), + ephemeral.join("wasi_ephemeral_path.witx"), + ephemeral.join("wasi_ephemeral_poll.witx"), + ephemeral.join("wasi_ephemeral_proc.witx"), + ephemeral.join("wasi_ephemeral_random.witx"), + ephemeral.join("wasi_ephemeral_sched.witx"), + ephemeral.join("wasi_ephemeral_sock.witx"), + ]; + ensure_exists(&paths)?; + Ok(paths) +} + +pub mod old { + use super::*; + pub fn snapshot_0() -> Result> { + let root = repo_root()?; + let snapshot_0 = root.join("phases/old/snapshot_0/witx"); + let paths = vec![snapshot_0.join("wasi_unstable.witx")]; + ensure_exists(&paths)?; + Ok(paths) + } +} + +fn repo_root() -> Result { + let repo_root = if let Ok(e) = env::var("WASI_REPO") { + PathBuf::from(e) + } else { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..") + }; + if repo_root.exists() { + Ok(repo_root) + } else { + Err(anyhow!( + "could not find WASI repo root - try setting WASI_REPO env variable" + )) + } +} + +fn ensure_exists(paths: &[PathBuf]) -> Result<()> { + for p in paths.iter() { + if !p.exists() { + Err(anyhow!( + "{:?} does not exist - is WASI_REPO set to repository root?", + p + ))?; + } + } + Ok(()) +} diff --git a/proposals/clocks/tools/witx/tests/wasi.rs b/proposals/clocks/tools/witx/tests/wasi.rs index fe7a101eb..0d93e68b9 100644 --- a/proposals/clocks/tools/witx/tests/wasi.rs +++ b/proposals/clocks/tools/witx/tests/wasi.rs @@ -2,36 +2,25 @@ use witx; #[test] fn validate_wasi_snapshot() { - witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + witx::load(&witx::phases::snapshot().unwrap()) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_ephemeral() { - witx::load(&[ - "../../phases/ephemeral/witx/wasi_ephemeral_args.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_clock.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_environ.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_fd.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_path.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_poll.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_proc.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_random.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_sched.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_sock.witx", - ]) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&witx::phases::ephemeral().unwrap()) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_old_snapshot_0() { - witx::load(&["../../phases/old/snapshot_0/witx/wasi_unstable.witx"]) + witx::load(&witx::phases::old::snapshot_0().unwrap()) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn render_roundtrip() { - let doc = witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + let doc = witx::load(&witx::phases::snapshot().unwrap()) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); let back_to_sexprs = format!("{}", doc); @@ -69,7 +58,7 @@ fn document_wasi_snapshot() { use witx::Documentation; println!( "{}", - witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + witx::load(&witx::phases::snapshot().unwrap()) .unwrap_or_else(|e| panic!("failed to parse: {}", e)) .to_md() ); From 9a800fe3d841ee513d46cf965ed11916ed8b0ce2 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 13:50:06 -0800 Subject: [PATCH 0494/1772] witx: add executable mode to generate docs for the wasi repo this changes the usage of existing commands :( but to be fair, having an argument before the subcommand was not a common or good idiom. --- proposals/random/tools/witx/Cargo.toml | 1 + proposals/random/tools/witx/src/lib.rs | 2 + proposals/random/tools/witx/src/main.rs | 107 ++++++++++++++-------- proposals/random/tools/witx/src/phases.rs | 68 ++++++++++++++ proposals/random/tools/witx/tests/wasi.rs | 23 ++--- 5 files changed, 145 insertions(+), 56 deletions(-) create mode 100644 proposals/random/tools/witx/src/phases.rs diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index cb75c1753..5f75172a8 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -23,3 +23,4 @@ wast = "3.0.4" thiserror = "1.0" log = "0.4" pretty_env_logger = "0.3" +anyhow = "1" diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 05586ec96..ba4df6889 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -10,6 +10,8 @@ mod io; mod layout; /// Witx syntax parsing from SExprs mod parser; +/// Paths to witx documents for various proposal phases +pub mod phases; /// Calculate required polyfill between interfaces pub mod polyfill; /// Render ast to text diff --git a/proposals/random/tools/witx/src/main.rs b/proposals/random/tools/witx/src/main.rs index f89822d7f..3fcc6f7f2 100644 --- a/proposals/random/tools/witx/src/main.rs +++ b/proposals/random/tools/witx/src/main.rs @@ -1,20 +1,15 @@ -use clap::{App, Arg, SubCommand}; +use clap::{App, Arg, ArgMatches, SubCommand}; use std::collections::HashMap; use std::fs::File; use std::io::Write; +use std::path::Path; use std::process; -use witx::{load, Documentation}; +use witx::{load, phases, Document, Documentation}; pub fn main() { let app = App::new("witx") .version(env!("CARGO_PKG_VERSION")) .about("Validate and process witx files") - .arg( - Arg::with_name("input") - .required(true) - .multiple(true) - .help("path to root of witx document"), - ) .arg( Arg::with_name("verbose") .short("v") @@ -25,6 +20,12 @@ pub fn main() { .subcommand( SubCommand::with_name("docs") .about("Output documentation") + .arg( + Arg::with_name("input") + .required(true) + .multiple(true) + .help("path to root of witx document"), + ) .arg( Arg::with_name("output") .short("o") @@ -36,6 +37,12 @@ pub fn main() { .subcommand( SubCommand::with_name("polyfill") .about("Examine differences between interfaces") + .arg( + Arg::with_name("input") + .required(true) + .multiple(true) + .help("path to root of witx document"), + ) .arg( Arg::with_name("older_interface") .required(true) @@ -52,49 +59,50 @@ pub fn main() { .help("module to examine. Use newname=oldname syntax if name is different between new and old interfaces"), ), ) + .subcommand( + SubCommand::with_name("repo-docs") + .about("Update documentation in WASI repository to reflect witx specs") + ) .get_matches(); - let inputs = app - .values_of("input") - .expect("at least one input required") - .collect::>(); - - let load_docs = { - |inputs: &[&str]| match load(inputs) { - Ok(doc) => doc, - Err(e) => { - println!("{}", e.report()); - if app.is_present("verbose") { - println!("{:?}", e); + let load_witx = { + |args: &ArgMatches, field: &str| -> Document { + let inputs = args + .values_of(field) + .expect(&format!("required argument: {}", field)) + .collect::>(); + match load(&inputs) { + Ok(doc) => { + if app.is_present("verbose") { + println!("{}: {:?}", field, doc) + } + doc + } + Err(e) => { + println!("{}", e.report()); + if app.is_present("verbose") { + println!("{:?}", e); + } + process::exit(1) } - process::exit(1) } } }; pretty_env_logger::init(); - let doc = load_docs(&inputs); - if app.is_present("verbose") { - println!("{:?}", doc) - } - - if let Some(docs_command) = app.subcommand_matches("docs") { - let md = doc.to_md(); - if let Some(output) = docs_command.value_of("output") { - let mut file = File::create(output).expect("create output file"); - file.write_all(md.as_bytes()).expect("write output file"); + if let Some(docs_args) = app.subcommand_matches("docs") { + let doc = load_witx(&docs_args, "input"); + if let Some(output) = docs_args.value_of("output") { + write_docs(&doc, output) } else { - println!("{}", md) + println!("{}", doc.to_md()) } - } else if let Some(polyfill_command) = app.subcommand_matches("polyfill") { - let older_inputs = polyfill_command - .values_of("older_interface") - .expect("at least one older_interface argument required") - .collect::>(); - let older_doc = load_docs(&older_inputs); + } else if let Some(polyfill_args) = app.subcommand_matches("polyfill") { + let doc = load_witx(&polyfill_args, "input"); + let older_doc = load_witx(&polyfill_args, "older_interface"); - let module_mapping_args = polyfill_command + let module_mapping_args = polyfill_args .values_of("module_mapping") .expect("at least one module_mapping argument required") .collect::>(); @@ -106,9 +114,30 @@ pub fn main() { if app.is_present("verbose") { println!("{:?}", polyfill); } + } else if app.subcommand_matches("repo-docs").is_some() { + for phase in &[ + phases::snapshot().unwrap(), + phases::ephemeral().unwrap(), + phases::old::snapshot_0().unwrap(), + ] { + let doc = load(&phase).expect("parse phase"); + let path = phase + .get(0) + .expect("at least one path") + .parent() + .expect("drop file") + .join("../docs.md"); + write_docs(&doc, &path); + } } } +fn write_docs>(document: &Document, path: P) { + let mut file = File::create(path.as_ref()).expect("create output file"); + file.write_all(document.to_md().as_bytes()) + .expect("write output file"); +} + fn parse_module_mapping(ms: &[&str]) -> HashMap { let mut o = HashMap::new(); for m in ms { diff --git a/proposals/random/tools/witx/src/phases.rs b/proposals/random/tools/witx/src/phases.rs new file mode 100644 index 000000000..1bc0c381a --- /dev/null +++ b/proposals/random/tools/witx/src/phases.rs @@ -0,0 +1,68 @@ +use anyhow::{anyhow, Result}; +use std::env; +use std::path::PathBuf; + +pub fn snapshot() -> Result> { + let root = repo_root()?; + let snapshot = root.join("phases/snapshot/witx"); + let paths = vec![snapshot.join("wasi_snapshot_preview1.witx")]; + ensure_exists(&paths)?; + Ok(paths) +} + +pub fn ephemeral() -> Result> { + let root = repo_root()?; + let ephemeral = root.join("phases/ephemeral/witx"); + let paths = vec![ + ephemeral.join("wasi_ephemeral_args.witx"), + ephemeral.join("wasi_ephemeral_clock.witx"), + ephemeral.join("wasi_ephemeral_environ.witx"), + ephemeral.join("wasi_ephemeral_fd.witx"), + ephemeral.join("wasi_ephemeral_path.witx"), + ephemeral.join("wasi_ephemeral_poll.witx"), + ephemeral.join("wasi_ephemeral_proc.witx"), + ephemeral.join("wasi_ephemeral_random.witx"), + ephemeral.join("wasi_ephemeral_sched.witx"), + ephemeral.join("wasi_ephemeral_sock.witx"), + ]; + ensure_exists(&paths)?; + Ok(paths) +} + +pub mod old { + use super::*; + pub fn snapshot_0() -> Result> { + let root = repo_root()?; + let snapshot_0 = root.join("phases/old/snapshot_0/witx"); + let paths = vec![snapshot_0.join("wasi_unstable.witx")]; + ensure_exists(&paths)?; + Ok(paths) + } +} + +fn repo_root() -> Result { + let repo_root = if let Ok(e) = env::var("WASI_REPO") { + PathBuf::from(e) + } else { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..") + }; + if repo_root.exists() { + Ok(repo_root) + } else { + Err(anyhow!( + "could not find WASI repo root - try setting WASI_REPO env variable" + )) + } +} + +fn ensure_exists(paths: &[PathBuf]) -> Result<()> { + for p in paths.iter() { + if !p.exists() { + Err(anyhow!( + "{:?} does not exist - is WASI_REPO set to repository root?", + p + ))?; + } + } + Ok(()) +} diff --git a/proposals/random/tools/witx/tests/wasi.rs b/proposals/random/tools/witx/tests/wasi.rs index fe7a101eb..0d93e68b9 100644 --- a/proposals/random/tools/witx/tests/wasi.rs +++ b/proposals/random/tools/witx/tests/wasi.rs @@ -2,36 +2,25 @@ use witx; #[test] fn validate_wasi_snapshot() { - witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + witx::load(&witx::phases::snapshot().unwrap()) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_ephemeral() { - witx::load(&[ - "../../phases/ephemeral/witx/wasi_ephemeral_args.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_clock.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_environ.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_fd.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_path.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_poll.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_proc.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_random.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_sched.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_sock.witx", - ]) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&witx::phases::ephemeral().unwrap()) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_old_snapshot_0() { - witx::load(&["../../phases/old/snapshot_0/witx/wasi_unstable.witx"]) + witx::load(&witx::phases::old::snapshot_0().unwrap()) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn render_roundtrip() { - let doc = witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + let doc = witx::load(&witx::phases::snapshot().unwrap()) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); let back_to_sexprs = format!("{}", doc); @@ -69,7 +58,7 @@ fn document_wasi_snapshot() { use witx::Documentation; println!( "{}", - witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + witx::load(&witx::phases::snapshot().unwrap()) .unwrap_or_else(|e| panic!("failed to parse: {}", e)) .to_md() ); From 8e1a7e5cc41696b603094b33c9df70eb8ae195c4 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 13:50:06 -0800 Subject: [PATCH 0495/1772] witx: add executable mode to generate docs for the wasi repo this changes the usage of existing commands :( but to be fair, having an argument before the subcommand was not a common or good idiom. --- proposals/filesystem/tools/witx/Cargo.toml | 1 + proposals/filesystem/tools/witx/src/lib.rs | 2 + proposals/filesystem/tools/witx/src/main.rs | 107 +++++++++++------- proposals/filesystem/tools/witx/src/phases.rs | 68 +++++++++++ proposals/filesystem/tools/witx/tests/wasi.rs | 23 +--- 5 files changed, 145 insertions(+), 56 deletions(-) create mode 100644 proposals/filesystem/tools/witx/src/phases.rs diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index cb75c1753..5f75172a8 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -23,3 +23,4 @@ wast = "3.0.4" thiserror = "1.0" log = "0.4" pretty_env_logger = "0.3" +anyhow = "1" diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 05586ec96..ba4df6889 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -10,6 +10,8 @@ mod io; mod layout; /// Witx syntax parsing from SExprs mod parser; +/// Paths to witx documents for various proposal phases +pub mod phases; /// Calculate required polyfill between interfaces pub mod polyfill; /// Render ast to text diff --git a/proposals/filesystem/tools/witx/src/main.rs b/proposals/filesystem/tools/witx/src/main.rs index f89822d7f..3fcc6f7f2 100644 --- a/proposals/filesystem/tools/witx/src/main.rs +++ b/proposals/filesystem/tools/witx/src/main.rs @@ -1,20 +1,15 @@ -use clap::{App, Arg, SubCommand}; +use clap::{App, Arg, ArgMatches, SubCommand}; use std::collections::HashMap; use std::fs::File; use std::io::Write; +use std::path::Path; use std::process; -use witx::{load, Documentation}; +use witx::{load, phases, Document, Documentation}; pub fn main() { let app = App::new("witx") .version(env!("CARGO_PKG_VERSION")) .about("Validate and process witx files") - .arg( - Arg::with_name("input") - .required(true) - .multiple(true) - .help("path to root of witx document"), - ) .arg( Arg::with_name("verbose") .short("v") @@ -25,6 +20,12 @@ pub fn main() { .subcommand( SubCommand::with_name("docs") .about("Output documentation") + .arg( + Arg::with_name("input") + .required(true) + .multiple(true) + .help("path to root of witx document"), + ) .arg( Arg::with_name("output") .short("o") @@ -36,6 +37,12 @@ pub fn main() { .subcommand( SubCommand::with_name("polyfill") .about("Examine differences between interfaces") + .arg( + Arg::with_name("input") + .required(true) + .multiple(true) + .help("path to root of witx document"), + ) .arg( Arg::with_name("older_interface") .required(true) @@ -52,49 +59,50 @@ pub fn main() { .help("module to examine. Use newname=oldname syntax if name is different between new and old interfaces"), ), ) + .subcommand( + SubCommand::with_name("repo-docs") + .about("Update documentation in WASI repository to reflect witx specs") + ) .get_matches(); - let inputs = app - .values_of("input") - .expect("at least one input required") - .collect::>(); - - let load_docs = { - |inputs: &[&str]| match load(inputs) { - Ok(doc) => doc, - Err(e) => { - println!("{}", e.report()); - if app.is_present("verbose") { - println!("{:?}", e); + let load_witx = { + |args: &ArgMatches, field: &str| -> Document { + let inputs = args + .values_of(field) + .expect(&format!("required argument: {}", field)) + .collect::>(); + match load(&inputs) { + Ok(doc) => { + if app.is_present("verbose") { + println!("{}: {:?}", field, doc) + } + doc + } + Err(e) => { + println!("{}", e.report()); + if app.is_present("verbose") { + println!("{:?}", e); + } + process::exit(1) } - process::exit(1) } } }; pretty_env_logger::init(); - let doc = load_docs(&inputs); - if app.is_present("verbose") { - println!("{:?}", doc) - } - - if let Some(docs_command) = app.subcommand_matches("docs") { - let md = doc.to_md(); - if let Some(output) = docs_command.value_of("output") { - let mut file = File::create(output).expect("create output file"); - file.write_all(md.as_bytes()).expect("write output file"); + if let Some(docs_args) = app.subcommand_matches("docs") { + let doc = load_witx(&docs_args, "input"); + if let Some(output) = docs_args.value_of("output") { + write_docs(&doc, output) } else { - println!("{}", md) + println!("{}", doc.to_md()) } - } else if let Some(polyfill_command) = app.subcommand_matches("polyfill") { - let older_inputs = polyfill_command - .values_of("older_interface") - .expect("at least one older_interface argument required") - .collect::>(); - let older_doc = load_docs(&older_inputs); + } else if let Some(polyfill_args) = app.subcommand_matches("polyfill") { + let doc = load_witx(&polyfill_args, "input"); + let older_doc = load_witx(&polyfill_args, "older_interface"); - let module_mapping_args = polyfill_command + let module_mapping_args = polyfill_args .values_of("module_mapping") .expect("at least one module_mapping argument required") .collect::>(); @@ -106,9 +114,30 @@ pub fn main() { if app.is_present("verbose") { println!("{:?}", polyfill); } + } else if app.subcommand_matches("repo-docs").is_some() { + for phase in &[ + phases::snapshot().unwrap(), + phases::ephemeral().unwrap(), + phases::old::snapshot_0().unwrap(), + ] { + let doc = load(&phase).expect("parse phase"); + let path = phase + .get(0) + .expect("at least one path") + .parent() + .expect("drop file") + .join("../docs.md"); + write_docs(&doc, &path); + } } } +fn write_docs>(document: &Document, path: P) { + let mut file = File::create(path.as_ref()).expect("create output file"); + file.write_all(document.to_md().as_bytes()) + .expect("write output file"); +} + fn parse_module_mapping(ms: &[&str]) -> HashMap { let mut o = HashMap::new(); for m in ms { diff --git a/proposals/filesystem/tools/witx/src/phases.rs b/proposals/filesystem/tools/witx/src/phases.rs new file mode 100644 index 000000000..1bc0c381a --- /dev/null +++ b/proposals/filesystem/tools/witx/src/phases.rs @@ -0,0 +1,68 @@ +use anyhow::{anyhow, Result}; +use std::env; +use std::path::PathBuf; + +pub fn snapshot() -> Result> { + let root = repo_root()?; + let snapshot = root.join("phases/snapshot/witx"); + let paths = vec![snapshot.join("wasi_snapshot_preview1.witx")]; + ensure_exists(&paths)?; + Ok(paths) +} + +pub fn ephemeral() -> Result> { + let root = repo_root()?; + let ephemeral = root.join("phases/ephemeral/witx"); + let paths = vec![ + ephemeral.join("wasi_ephemeral_args.witx"), + ephemeral.join("wasi_ephemeral_clock.witx"), + ephemeral.join("wasi_ephemeral_environ.witx"), + ephemeral.join("wasi_ephemeral_fd.witx"), + ephemeral.join("wasi_ephemeral_path.witx"), + ephemeral.join("wasi_ephemeral_poll.witx"), + ephemeral.join("wasi_ephemeral_proc.witx"), + ephemeral.join("wasi_ephemeral_random.witx"), + ephemeral.join("wasi_ephemeral_sched.witx"), + ephemeral.join("wasi_ephemeral_sock.witx"), + ]; + ensure_exists(&paths)?; + Ok(paths) +} + +pub mod old { + use super::*; + pub fn snapshot_0() -> Result> { + let root = repo_root()?; + let snapshot_0 = root.join("phases/old/snapshot_0/witx"); + let paths = vec![snapshot_0.join("wasi_unstable.witx")]; + ensure_exists(&paths)?; + Ok(paths) + } +} + +fn repo_root() -> Result { + let repo_root = if let Ok(e) = env::var("WASI_REPO") { + PathBuf::from(e) + } else { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..") + }; + if repo_root.exists() { + Ok(repo_root) + } else { + Err(anyhow!( + "could not find WASI repo root - try setting WASI_REPO env variable" + )) + } +} + +fn ensure_exists(paths: &[PathBuf]) -> Result<()> { + for p in paths.iter() { + if !p.exists() { + Err(anyhow!( + "{:?} does not exist - is WASI_REPO set to repository root?", + p + ))?; + } + } + Ok(()) +} diff --git a/proposals/filesystem/tools/witx/tests/wasi.rs b/proposals/filesystem/tools/witx/tests/wasi.rs index fe7a101eb..0d93e68b9 100644 --- a/proposals/filesystem/tools/witx/tests/wasi.rs +++ b/proposals/filesystem/tools/witx/tests/wasi.rs @@ -2,36 +2,25 @@ use witx; #[test] fn validate_wasi_snapshot() { - witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + witx::load(&witx::phases::snapshot().unwrap()) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_ephemeral() { - witx::load(&[ - "../../phases/ephemeral/witx/wasi_ephemeral_args.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_clock.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_environ.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_fd.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_path.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_poll.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_proc.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_random.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_sched.witx", - "../../phases/ephemeral/witx/wasi_ephemeral_sock.witx", - ]) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); + witx::load(&witx::phases::ephemeral().unwrap()) + .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn validate_wasi_old_snapshot_0() { - witx::load(&["../../phases/old/snapshot_0/witx/wasi_unstable.witx"]) + witx::load(&witx::phases::old::snapshot_0().unwrap()) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } #[test] fn render_roundtrip() { - let doc = witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + let doc = witx::load(&witx::phases::snapshot().unwrap()) .unwrap_or_else(|e| panic!("failed to parse: {}", e)); let back_to_sexprs = format!("{}", doc); @@ -69,7 +58,7 @@ fn document_wasi_snapshot() { use witx::Documentation; println!( "{}", - witx::load(&["../../phases/snapshot/witx/wasi_snapshot_preview1.witx"]) + witx::load(&witx::phases::snapshot().unwrap()) .unwrap_or_else(|e| panic!("failed to parse: {}", e)) .to_md() ); From 356d7f771242a7397b00047b4d0f2596cea33ef9 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 14:20:27 -0800 Subject: [PATCH 0496/1772] witx: test that docs in tree match generated the body of tests/wasi.rs's `test_against_filesystem` is copied from code Dan wrote in the wasi-libc repo's wasi-headers tool. Same license as this repo, and wasi-libc is destined to land in the WebAssembly github org as well. --- proposals/clocks/tools/witx/Cargo.toml | 3 + proposals/clocks/tools/witx/src/main.rs | 8 +-- proposals/clocks/tools/witx/src/phases.rs | 9 +++ proposals/clocks/tools/witx/tests/wasi.rs | 85 ++++++++++++++++++++++- 4 files changed, 97 insertions(+), 8 deletions(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 5f75172a8..d9ee8d858 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -24,3 +24,6 @@ thiserror = "1.0" log = "0.4" pretty_env_logger = "0.3" anyhow = "1" + +[dev-dependencies] +diff = "0.1.11" diff --git a/proposals/clocks/tools/witx/src/main.rs b/proposals/clocks/tools/witx/src/main.rs index 3fcc6f7f2..16d9d474f 100644 --- a/proposals/clocks/tools/witx/src/main.rs +++ b/proposals/clocks/tools/witx/src/main.rs @@ -121,13 +121,7 @@ pub fn main() { phases::old::snapshot_0().unwrap(), ] { let doc = load(&phase).expect("parse phase"); - let path = phase - .get(0) - .expect("at least one path") - .parent() - .expect("drop file") - .join("../docs.md"); - write_docs(&doc, &path); + write_docs(&doc, phases::docs_path(&phase)); } } } diff --git a/proposals/clocks/tools/witx/src/phases.rs b/proposals/clocks/tools/witx/src/phases.rs index 1bc0c381a..6e0f1776e 100644 --- a/proposals/clocks/tools/witx/src/phases.rs +++ b/proposals/clocks/tools/witx/src/phases.rs @@ -2,6 +2,15 @@ use anyhow::{anyhow, Result}; use std::env; use std::path::PathBuf; +pub fn docs_path(phase_paths: &[PathBuf]) -> PathBuf { + phase_paths + .get(0) + .expect("at least one path") + .parent() + .expect("drop file") + .join("../docs.md") +} + pub fn snapshot() -> Result> { let root = repo_root()?; let snapshot = root.join("phases/snapshot/witx"); diff --git a/proposals/clocks/tools/witx/tests/wasi.rs b/proposals/clocks/tools/witx/tests/wasi.rs index 0d93e68b9..8b03007de 100644 --- a/proposals/clocks/tools/witx/tests/wasi.rs +++ b/proposals/clocks/tools/witx/tests/wasi.rs @@ -1,4 +1,6 @@ -use witx; +use std::fs; +use std::path::Path; +use witx::{self, Documentation}; #[test] fn validate_wasi_snapshot() { @@ -18,6 +20,18 @@ fn validate_wasi_old_snapshot_0() { .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } +#[test] +fn validate_docs() { + for phase in &[ + witx::phases::snapshot().unwrap(), + witx::phases::ephemeral().unwrap(), + witx::phases::old::snapshot_0().unwrap(), + ] { + let doc = witx::load(&phase).unwrap_or_else(|e| panic!("failed to parse: {}", e)); + diff_against_filesystem(&doc.to_md(), &witx::phases::docs_path(&phase)); + } +} + #[test] fn render_roundtrip() { let doc = witx::load(&witx::phases::snapshot().unwrap()) @@ -63,3 +77,72 @@ fn document_wasi_snapshot() { .to_md() ); } + +fn diff_against_filesystem(expected: &str, path: &Path) { + let actual = + fs::read_to_string(path).unwrap_or_else(|e| panic!("couldn't read {:?}: {:?}", path, e)); + if &actual == expected { + return; + } + + eprintln!("The following diff was found between the docs generated from .witx and the"); + eprintln!("source {:?} in the tree:", path); + eprintln!(); + + let mut expected_line = 1; + let mut actual_line = 1; + let mut separated = false; + let mut any_lines = false; + for diff in diff::lines(&expected, &actual) { + match diff { + diff::Result::Left(l) => { + eprintln!("line {}: -{}", expected_line, l); + expected_line += 1; + separated = false; + any_lines = true; + } + diff::Result::Both(_, _) => { + expected_line += 1; + actual_line += 1; + if !separated { + eprintln!("..."); + separated = true; + } + } + diff::Result::Right(r) => { + eprintln!("line {}: +{}", actual_line, r); + actual_line += 1; + separated = false; + any_lines = true; + } + } + } + + if !any_lines { + eprintln!(); + eprintln!( + "Somehow there was a diff with no lines differing. Lengths: {} and {}.", + expected.len(), + actual.len() + ); + for (index, (a, b)) in actual.chars().zip(expected.chars()).enumerate() { + if a != b { + eprintln!("char difference at index {}: '{}' != '{}'", index, a, b); + } + } + for (index, (a, b)) in actual.bytes().zip(expected.bytes()).enumerate() { + if a != b { + eprintln!("byte difference at index {}: b'{}' != b'{}'", index, a, b); + } + } + eprintln!(); + eprintln!("actual: {}", actual); + eprintln!(); + eprintln!("expected: {}", expected); + } + + eprintln!(); + eprintln!("To regenerate the files, run `cd tools/witx && cargo run -- repo-docs`."); + eprintln!(); + panic!(); +} From 049a7b79de80f2e316dff69a8a95706cda74cb5c Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 14:20:27 -0800 Subject: [PATCH 0497/1772] witx: test that docs in tree match generated the body of tests/wasi.rs's `test_against_filesystem` is copied from code Dan wrote in the wasi-libc repo's wasi-headers tool. Same license as this repo, and wasi-libc is destined to land in the WebAssembly github org as well. --- proposals/random/tools/witx/Cargo.toml | 3 + proposals/random/tools/witx/src/main.rs | 8 +-- proposals/random/tools/witx/src/phases.rs | 9 +++ proposals/random/tools/witx/tests/wasi.rs | 85 ++++++++++++++++++++++- 4 files changed, 97 insertions(+), 8 deletions(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 5f75172a8..d9ee8d858 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -24,3 +24,6 @@ thiserror = "1.0" log = "0.4" pretty_env_logger = "0.3" anyhow = "1" + +[dev-dependencies] +diff = "0.1.11" diff --git a/proposals/random/tools/witx/src/main.rs b/proposals/random/tools/witx/src/main.rs index 3fcc6f7f2..16d9d474f 100644 --- a/proposals/random/tools/witx/src/main.rs +++ b/proposals/random/tools/witx/src/main.rs @@ -121,13 +121,7 @@ pub fn main() { phases::old::snapshot_0().unwrap(), ] { let doc = load(&phase).expect("parse phase"); - let path = phase - .get(0) - .expect("at least one path") - .parent() - .expect("drop file") - .join("../docs.md"); - write_docs(&doc, &path); + write_docs(&doc, phases::docs_path(&phase)); } } } diff --git a/proposals/random/tools/witx/src/phases.rs b/proposals/random/tools/witx/src/phases.rs index 1bc0c381a..6e0f1776e 100644 --- a/proposals/random/tools/witx/src/phases.rs +++ b/proposals/random/tools/witx/src/phases.rs @@ -2,6 +2,15 @@ use anyhow::{anyhow, Result}; use std::env; use std::path::PathBuf; +pub fn docs_path(phase_paths: &[PathBuf]) -> PathBuf { + phase_paths + .get(0) + .expect("at least one path") + .parent() + .expect("drop file") + .join("../docs.md") +} + pub fn snapshot() -> Result> { let root = repo_root()?; let snapshot = root.join("phases/snapshot/witx"); diff --git a/proposals/random/tools/witx/tests/wasi.rs b/proposals/random/tools/witx/tests/wasi.rs index 0d93e68b9..8b03007de 100644 --- a/proposals/random/tools/witx/tests/wasi.rs +++ b/proposals/random/tools/witx/tests/wasi.rs @@ -1,4 +1,6 @@ -use witx; +use std::fs; +use std::path::Path; +use witx::{self, Documentation}; #[test] fn validate_wasi_snapshot() { @@ -18,6 +20,18 @@ fn validate_wasi_old_snapshot_0() { .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } +#[test] +fn validate_docs() { + for phase in &[ + witx::phases::snapshot().unwrap(), + witx::phases::ephemeral().unwrap(), + witx::phases::old::snapshot_0().unwrap(), + ] { + let doc = witx::load(&phase).unwrap_or_else(|e| panic!("failed to parse: {}", e)); + diff_against_filesystem(&doc.to_md(), &witx::phases::docs_path(&phase)); + } +} + #[test] fn render_roundtrip() { let doc = witx::load(&witx::phases::snapshot().unwrap()) @@ -63,3 +77,72 @@ fn document_wasi_snapshot() { .to_md() ); } + +fn diff_against_filesystem(expected: &str, path: &Path) { + let actual = + fs::read_to_string(path).unwrap_or_else(|e| panic!("couldn't read {:?}: {:?}", path, e)); + if &actual == expected { + return; + } + + eprintln!("The following diff was found between the docs generated from .witx and the"); + eprintln!("source {:?} in the tree:", path); + eprintln!(); + + let mut expected_line = 1; + let mut actual_line = 1; + let mut separated = false; + let mut any_lines = false; + for diff in diff::lines(&expected, &actual) { + match diff { + diff::Result::Left(l) => { + eprintln!("line {}: -{}", expected_line, l); + expected_line += 1; + separated = false; + any_lines = true; + } + diff::Result::Both(_, _) => { + expected_line += 1; + actual_line += 1; + if !separated { + eprintln!("..."); + separated = true; + } + } + diff::Result::Right(r) => { + eprintln!("line {}: +{}", actual_line, r); + actual_line += 1; + separated = false; + any_lines = true; + } + } + } + + if !any_lines { + eprintln!(); + eprintln!( + "Somehow there was a diff with no lines differing. Lengths: {} and {}.", + expected.len(), + actual.len() + ); + for (index, (a, b)) in actual.chars().zip(expected.chars()).enumerate() { + if a != b { + eprintln!("char difference at index {}: '{}' != '{}'", index, a, b); + } + } + for (index, (a, b)) in actual.bytes().zip(expected.bytes()).enumerate() { + if a != b { + eprintln!("byte difference at index {}: b'{}' != b'{}'", index, a, b); + } + } + eprintln!(); + eprintln!("actual: {}", actual); + eprintln!(); + eprintln!("expected: {}", expected); + } + + eprintln!(); + eprintln!("To regenerate the files, run `cd tools/witx && cargo run -- repo-docs`."); + eprintln!(); + panic!(); +} From a47068fc5bb7abba1cf10f7c1e9fdfb615c99b88 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 14:20:27 -0800 Subject: [PATCH 0498/1772] witx: test that docs in tree match generated the body of tests/wasi.rs's `test_against_filesystem` is copied from code Dan wrote in the wasi-libc repo's wasi-headers tool. Same license as this repo, and wasi-libc is destined to land in the WebAssembly github org as well. --- proposals/filesystem/tools/witx/Cargo.toml | 3 + proposals/filesystem/tools/witx/src/main.rs | 8 +- proposals/filesystem/tools/witx/src/phases.rs | 9 ++ proposals/filesystem/tools/witx/tests/wasi.rs | 85 ++++++++++++++++++- 4 files changed, 97 insertions(+), 8 deletions(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 5f75172a8..d9ee8d858 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -24,3 +24,6 @@ thiserror = "1.0" log = "0.4" pretty_env_logger = "0.3" anyhow = "1" + +[dev-dependencies] +diff = "0.1.11" diff --git a/proposals/filesystem/tools/witx/src/main.rs b/proposals/filesystem/tools/witx/src/main.rs index 3fcc6f7f2..16d9d474f 100644 --- a/proposals/filesystem/tools/witx/src/main.rs +++ b/proposals/filesystem/tools/witx/src/main.rs @@ -121,13 +121,7 @@ pub fn main() { phases::old::snapshot_0().unwrap(), ] { let doc = load(&phase).expect("parse phase"); - let path = phase - .get(0) - .expect("at least one path") - .parent() - .expect("drop file") - .join("../docs.md"); - write_docs(&doc, &path); + write_docs(&doc, phases::docs_path(&phase)); } } } diff --git a/proposals/filesystem/tools/witx/src/phases.rs b/proposals/filesystem/tools/witx/src/phases.rs index 1bc0c381a..6e0f1776e 100644 --- a/proposals/filesystem/tools/witx/src/phases.rs +++ b/proposals/filesystem/tools/witx/src/phases.rs @@ -2,6 +2,15 @@ use anyhow::{anyhow, Result}; use std::env; use std::path::PathBuf; +pub fn docs_path(phase_paths: &[PathBuf]) -> PathBuf { + phase_paths + .get(0) + .expect("at least one path") + .parent() + .expect("drop file") + .join("../docs.md") +} + pub fn snapshot() -> Result> { let root = repo_root()?; let snapshot = root.join("phases/snapshot/witx"); diff --git a/proposals/filesystem/tools/witx/tests/wasi.rs b/proposals/filesystem/tools/witx/tests/wasi.rs index 0d93e68b9..8b03007de 100644 --- a/proposals/filesystem/tools/witx/tests/wasi.rs +++ b/proposals/filesystem/tools/witx/tests/wasi.rs @@ -1,4 +1,6 @@ -use witx; +use std::fs; +use std::path::Path; +use witx::{self, Documentation}; #[test] fn validate_wasi_snapshot() { @@ -18,6 +20,18 @@ fn validate_wasi_old_snapshot_0() { .unwrap_or_else(|e| panic!("failed to parse: {}", e)); } +#[test] +fn validate_docs() { + for phase in &[ + witx::phases::snapshot().unwrap(), + witx::phases::ephemeral().unwrap(), + witx::phases::old::snapshot_0().unwrap(), + ] { + let doc = witx::load(&phase).unwrap_or_else(|e| panic!("failed to parse: {}", e)); + diff_against_filesystem(&doc.to_md(), &witx::phases::docs_path(&phase)); + } +} + #[test] fn render_roundtrip() { let doc = witx::load(&witx::phases::snapshot().unwrap()) @@ -63,3 +77,72 @@ fn document_wasi_snapshot() { .to_md() ); } + +fn diff_against_filesystem(expected: &str, path: &Path) { + let actual = + fs::read_to_string(path).unwrap_or_else(|e| panic!("couldn't read {:?}: {:?}", path, e)); + if &actual == expected { + return; + } + + eprintln!("The following diff was found between the docs generated from .witx and the"); + eprintln!("source {:?} in the tree:", path); + eprintln!(); + + let mut expected_line = 1; + let mut actual_line = 1; + let mut separated = false; + let mut any_lines = false; + for diff in diff::lines(&expected, &actual) { + match diff { + diff::Result::Left(l) => { + eprintln!("line {}: -{}", expected_line, l); + expected_line += 1; + separated = false; + any_lines = true; + } + diff::Result::Both(_, _) => { + expected_line += 1; + actual_line += 1; + if !separated { + eprintln!("..."); + separated = true; + } + } + diff::Result::Right(r) => { + eprintln!("line {}: +{}", actual_line, r); + actual_line += 1; + separated = false; + any_lines = true; + } + } + } + + if !any_lines { + eprintln!(); + eprintln!( + "Somehow there was a diff with no lines differing. Lengths: {} and {}.", + expected.len(), + actual.len() + ); + for (index, (a, b)) in actual.chars().zip(expected.chars()).enumerate() { + if a != b { + eprintln!("char difference at index {}: '{}' != '{}'", index, a, b); + } + } + for (index, (a, b)) in actual.bytes().zip(expected.bytes()).enumerate() { + if a != b { + eprintln!("byte difference at index {}: b'{}' != b'{}'", index, a, b); + } + } + eprintln!(); + eprintln!("actual: {}", actual); + eprintln!(); + eprintln!("expected: {}", expected); + } + + eprintln!(); + eprintln!("To regenerate the files, run `cd tools/witx && cargo run -- repo-docs`."); + eprintln!(); + panic!(); +} From cb2a1f53f471d528ab87596fd58c85d7c1d779e4 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 14:22:28 -0800 Subject: [PATCH 0499/1772] replace legacy docs with new generated docs --- proposals/clocks/phases/ephemeral/docs.md | 1787 +++++++++++++ .../clocks/phases/old/snapshot_0/docs.md | 1791 +++++++++++++ .../old/snapshot_0/docs/wasi_unstable.md | 2343 ---------------- proposals/clocks/phases/snapshot/docs.md | 1790 +++++++++++++ .../snapshot/docs/wasi_unstable_preview1.md | 2346 ----------------- 5 files changed, 5368 insertions(+), 4689 deletions(-) create mode 100644 proposals/clocks/phases/ephemeral/docs.md create mode 100644 proposals/clocks/phases/old/snapshot_0/docs.md delete mode 100644 proposals/clocks/phases/old/snapshot_0/docs/wasi_unstable.md create mode 100644 proposals/clocks/phases/snapshot/docs.md delete mode 100644 proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md new file mode 100644 index 000000000..8465cd8b7 --- /dev/null +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -0,0 +1,1787 @@ +# Types +## `size`: `usize` + +## `filesize`: `u64` +Non-negative file size or length of a region within a file. + +## `timestamp`: `u64` +Timestamp in nanoseconds. + +## `clockid`: Enum(`u32`) +Identifiers for clocks. + +### Variants +- `realtime` +The clock measuring real time. Time value zero corresponds with +1970-01-01T00:00:00Z. + +- `monotonic` +The store-wide monotonic clock, which is defined as a clock measuring +real time, whose value cannot be adjusted and which cannot have negative +clock jumps. The epoch of this clock is undefined. The absolute time +value of this clock therefore has no meaning. + +- `process_cputime_id` +The CPU-time clock associated with the current process. + +- `thread_cputime_id` +The CPU-time clock associated with the current thread. + +## `errno`: Enum(`u16`) +Error codes returned by functions. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX. + +### Variants +- `success` +No error occurred. System call completed successfully. + +- `2big` +Argument list too long. + +- `acces` +Permission denied. + +- `addrinuse` +Address in use. + +- `addrnotavail` +Address not available. + +- `afnosupport` +Address family not supported. + +- `again` +Resource unavailable, or operation would block. + +- `already` +Connection already in progress. + +- `badf` +Bad file descriptor. + +- `badmsg` +Bad message. + +- `busy` +Device or resource busy. + +- `canceled` +Operation canceled. + +- `child` +No child processes. + +- `connaborted` +Connection aborted. + +- `connrefused` +Connection refused. + +- `connreset` +Connection reset. + +- `deadlk` +Resource deadlock would occur. + +- `destaddrreq` +Destination address required. + +- `dom` +Mathematics argument out of domain of function. + +- `dquot` +Reserved. + +- `exist` +File exists. + +- `fault` +Bad address. + +- `fbig` +File too large. + +- `hostunreach` +Host is unreachable. + +- `idrm` +Identifier removed. + +- `ilseq` +Illegal byte sequence. + +- `inprogress` +Operation in progress. + +- `intr` +Interrupted function. + +- `inval` +Invalid argument. + +- `io` +I/O error. + +- `isconn` +Socket is connected. + +- `isdir` +Is a directory. + +- `loop` +Too many levels of symbolic links. + +- `mfile` +File descriptor value too large. + +- `mlink` +Too many links. + +- `msgsize` +Message too large. + +- `multihop` +Reserved. + +- `nametoolong` +Filename too long. + +- `netdown` +Network is down. + +- `netreset` +Connection aborted by network. + +- `netunreach` +Network unreachable. + +- `nfile` +Too many files open in system. + +- `nobufs` +No buffer space available. + +- `nodev` +No such device. + +- `noent` +No such file or directory. + +- `noexec` +Executable file format error. + +- `nolck` +No locks available. + +- `nolink` +Reserved. + +- `nomem` +Not enough space. + +- `nomsg` +No message of the desired type. + +- `noprotoopt` +Protocol not available. + +- `nospc` +No space left on device. + +- `nosys` +Function not supported. + +- `notconn` +The socket is not connected. + +- `notdir` +Not a directory or a symbolic link to a directory. + +- `notempty` +Directory not empty. + +- `notrecoverable` +State not recoverable. + +- `notsock` +Not a socket. + +- `notsup` +Not supported, or operation not supported on socket. + +- `notty` +Inappropriate I/O control operation. + +- `nxio` +No such device or address. + +- `overflow` +Value too large to be stored in data type. + +- `ownerdead` +Previous owner died. + +- `perm` +Operation not permitted. + +- `pipe` +Broken pipe. + +- `proto` +Protocol error. + +- `protonosupport` +Protocol not supported. + +- `prototype` +Protocol wrong type for socket. + +- `range` +Result too large. + +- `rofs` +Read-only file system. + +- `spipe` +Invalid seek. + +- `srch` +No such process. + +- `stale` +Reserved. + +- `timedout` +Connection timed out. + +- `txtbsy` +Text file busy. + +- `xdev` +Cross-device link. + +- `notcapable` +Extension: Capabilities insufficient. + +## `rights`: Flags(`u64`) +File descriptor rights, determining which actions may be performed. + +### Flags +- `fd_datasync` +The right to invoke `fd_datasync`. +If `path_open` is set, includes the right to invoke +`path_open` with `fdflag::dsync`. + +- `fd_read` +The right to invoke `fd_read` and `sock_recv`. +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. + +- `fd_seek` +The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). + +- `fd_fdstat_set_flags` +The right to invoke `fd_fdstat_set_flags`. + +- `fd_sync` +The right to invoke `fd_sync`. +If `path_open` is set, includes the right to invoke +`path_open` with `fdflag::rsync` and `fdflag::dsync`. + +- `fd_tell` +The right to invoke `fd_seek` in such a way that the file offset +remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +invoke `fd_tell`. + +- `fd_write` +The right to invoke `fd_write` and `sock_send`. +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. + +- `fd_advise` +The right to invoke `fd_advise`. + +- `fd_allocate` +The right to invoke `fd_allocate`. + +- `path_create_directory` +The right to invoke `path_create_directory`. + +- `path_create_file` +If `path_open` is set, the right to invoke `path_open` with [`oflags::creat`](#oflags.creat). + +- `path_link_source` +The right to invoke `path_link` with the file descriptor as the +source directory. + +- `path_link_target` +The right to invoke `path_link` with the file descriptor as the +target directory. + +- `path_open` +The right to invoke `path_open`. + +- `fd_readdir` +The right to invoke `fd_readdir`. + +- `path_readlink` +The right to invoke `path_readlink`. + +- `path_rename_source` +The right to invoke `path_rename` with the file descriptor as the source directory. + +- `path_rename_target` +The right to invoke `path_rename` with the file descriptor as the target directory. + +- `path_filestat_get` +The right to invoke `path_filestat_get`. + +- `path_filestat_set_size` +The right to change a file's size (there is no `path_filestat_set_size`). +If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). + +- `path_filestat_set_times` +The right to invoke `path_filestat_set_times`. + +- `path_permissions_set` +The right to invoke `path_filestat_set_permissions`. + +- `fd_filestat_get` +The right to invoke `fd_filestat_get`. + +- `fd_filestat_set_size` +The right to invoke `fd_filestat_set_size`. + +- `fd_filestat_set_times` +The right to invoke `fd_filestat_set_times`. + +- `fd_permissions_set` +The right to invoke `fd_filestat_set_permissions`. + +- `path_symlink` +The right to invoke `path_symlink`. + +- `path_remove_directory` +The right to invoke `path_remove_directory`. + +- `path_unlink_file` +The right to invoke `path_unlink_file`. + +- `poll_fd_readwrite` +If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). +If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). + +- `sock_shutdown` +The right to invoke `sock_shutdown`. + +## `fd` +A file descriptor handle. + +### Supertypes +## `iovec`: Struct +A region of memory for scatter/gather reads. + +### Struct members +- `buf`: `Pointer` +The address of the buffer to be filled. + +- `buf_len`: [`size`](#size) +The length of the buffer to be filled. + +## `ciovec`: Struct +A region of memory for scatter/gather writes. + +### Struct members +- `buf`: `ConstPointer` +The address of the buffer to be written. + +- `buf_len`: [`size`](#size) +The length of the buffer to be written. + +## `iovec_array`: `Array` + +## `ciovec_array`: `Array` + +## `filedelta`: `s64` +Relative offset within a file. + +## `whence`: Enum(`u8`) +The position relative to which to set the offset of the file descriptor. + +### Variants +- `set` +Seek relative to start-of-file. + +- `cur` +Seek relative to current position. + +- `end` +Seek relative to end-of-file. + +## `dircookie`: Int(`u64`) +A reference to the offset of a directory entry. + +### Consts +- `start` + +## `dirnamlen`: `u32` +The type for the $d_namlen field of $dirent. + +## `inode`: `u64` +File serial number that is unique within its file system. + +## `filetype`: Enum(`u8`) +The type of a file descriptor or file. + +### Variants +- `unknown` +The type of the file descriptor or file is unknown or is different from any of the other types specified. + +- `block_device` +The file descriptor or file refers to a block device inode. + +- `character_device` +The file descriptor or file refers to a character device inode. + +- `directory` +The file descriptor or file refers to a directory inode. + +- `regular_file` +The file descriptor or file refers to a regular file inode. + +- `socket_dgram` +The file descriptor or file refers to a datagram socket. + +- `socket_stream` +The file descriptor or file refers to a byte-stream socket. + +- `symbolic_link` +The file refers to a symbolic link inode. + +- `fifo` +The file descriptor or file refers to a FIFO. + +## `dirent`: Struct +A directory entry. + +### Struct members +- `d_next`: [`dircookie`](#dircookie) +The offset of the next directory entry stored in this directory. + +- `d_ino`: [`inode`](#inode) +The serial number of the file referred to by this directory entry. + +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. + +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. + +## `advice`: Enum(`u8`) +File or memory access pattern advisory information. + +### Variants +- `normal` +The application has no advice to give on its behavior with respect to the specified data. + +- `sequential` +The application expects to access the specified data sequentially from lower offsets to higher offsets. + +- `random` +The application expects to access the specified data in a random order. + +- `willneed` +The application expects to access the specified data in the near future. + +- `dontneed` +The application expects that it will not access the specified data in the near future. + +- `noreuse` +The application expects to access the specified data once and then not reuse it thereafter. + +## `fdflags`: Flags(`u16`) +File descriptor flags. + +### Flags +- `append` +Append mode: Data written to the file is always appended to the file's end. + +- `dsync` +Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + +- `nonblock` +Non-blocking mode. + +- `rsync` +Synchronized read I/O operations. + +- `sync` +Write according to synchronized I/O file integrity completion. In +addition to synchronizing the data stored in the file, the implementation +may also synchronously update the file's metadata. + +## `fdstat`: Struct +File descriptor attributes. + +### Struct members +- `fs_filetype`: [`filetype`](#filetype) +File type. + +- `fs_flags`: [`fdflags`](#fdflags) +File descriptor flags. + +- `fs_rights_base`: [`rights`](#rights) +Rights that apply to this file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) +Maximum set of rights that may be installed on new file descriptors that +are created through this file descriptor, e.g., through `path_open`. + +## `device`: `u64` +Identifier for a device containing a file system. Can be used in combination +with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. + +## `fstflags`: Flags(`u16`) +Which file time attributes to adjust. + +### Flags +- `atim` +Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + +- `atim_now` +Adjust the last data access timestamp to the time of clock `clock::realtime`. + +- `mtim` +Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + +- `mtim_now` +Adjust the last data modification timestamp to the time of clock `clock::realtime`. + +## `lookupflags`: Flags(`u32`) +Flags determining the method of how paths are resolved. + +### Flags +- `symlink_follow` +As long as the resolved path corresponds to a symbolic link, it is expanded. + +## `oflags`: Flags(`u16`) +Open flags used by `path_open`. + +### Flags +- `creat` +Create file if it does not exist. + +- `directory` +Fail if not a directory. + +- `excl` +Fail if file already exists. + +- `trunc` +Truncate file to size 0. + +## `linkcount`: `u64` +Number of hard links to an inode. + +## `permissions`: Flags(`u8`) +File permissions. This represents the permissions associated with a +file in a filesystem, and don't fully reflect all the conditions +which determine whether a given WASI program can access the file. + +### Flags +- `read` +For files, permission to read the file. +For directories, permission to do [`readdir`](#readdir) and access files +within the directory. + +Note: This is similar to the read bit being set on files, and the +read *and* execute bits being set on directories, in POSIX. + +- `write` +For files, permission to mutate the file. +For directories, permission to create, remove, and rename items +within the directory. + +- `execute` +For files, permission to "execute" the file, using whatever +concept of "executing" the host filesystem has. +This flag is not valid for directories. + +- `private` +For filesystems which have a concept of multiple "users", this flag +indicates that the file is only accessible by the effective "user" +that the WASI store uses to access the filesystem, and inaccessible +to other "users". + +## `filestat`: Struct +File attributes. + +### Struct members +- `dev`: [`device`](#device) +Device ID of device containing the file. + +- `ino`: [`inode`](#inode) +File serial number. + +- `filetype`: [`filetype`](#filetype) +File type. + +- `permissions`: [`permissions`](#permissions) +File permissions. + +- `nlink`: [`linkcount`](#linkcount) +Number of hard links to the file. + +- `size`: [`filesize`](#filesize) +For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + +- `atim`: [`timestamp`](#timestamp) +Last data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +Last data modification timestamp. + +- `ctim`: [`timestamp`](#timestamp) +Last file status change timestamp. + +## `userdata`: `u64` +User-provided value that may be attached to objects that is retained when +extracted from the implementation. + +## `eventtype`: Enum(`u8`) +Type of a subscription to an event or its occurrence. + +### Variants +- `clock` +The time value of clock `subscription::u.clock.clock_id` has +reached timestamp `subscription::u.clock.timeout`. + +- `fd_read` +File descriptor `subscription::u.fd_readwrite.fd` has data +available for reading. This event always triggers for regular files. + +- `fd_write` +File descriptor `subscription::u.fd_readwrite.fd` has capacity +available for writing. This event always triggers for regular files. + +## `eventrwflags`: Flags(`u16`) +The state of the file descriptor subscribed to with +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Flags +- `fd_readwrite_hangup` +The peer of this socket has closed or disconnected. + +## `event_fd_readwrite`: Struct +The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `nbytes`: [`filesize`](#filesize) +The number of bytes available for reading or writing. + +- `flags`: [`eventrwflags`](#eventrwflags) +The state of the file descriptor. + +## `event_u`: Union +The contents of an $event. + +### Union variants +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `event`: Struct +An event that occurred. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). + +- `error`: [`errno`](#errno) +If non-zero, an error that occurred while processing the subscription request. + +- `type`: [`eventtype`](#eventtype) +The type of the event that occurred. + +- `u`: [`event_u`](#event_u) +The contents of the event. + +## `subclockflags`: Flags(`u16`) +Flags determining how to interpret the timestamp provided in +`subscription::u.clock.timeout.` + +### Flags +- `subscription_clock_abstime` +If set, treat the timestamp provided in +`subscription::u.clock.timeout` as an absolute timestamp of clock +`subscription::u.clock.clock_id.` If clear, treat the timestamp +provided in `subscription::u.clock.timeout` relative to the +current time value of clock `subscription::u.clock.clock_id.` + +## `subscription_clock`: Struct +The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). + +### Struct members +- `id`: [`clockid`](#clockid) +The clock against which to compare the timestamp. + +- `timeout`: [`timestamp`](#timestamp) +The absolute or relative timestamp. + +- `precision`: [`timestamp`](#timestamp) +The amount of time that the implementation may wait additionally +to coalesce with other events. + +- `flags`: [`subclockflags`](#subclockflags) +Flags specifying whether the timeout is absolute or relative + +## `subscription_fd_readwrite`: Struct +The contents of a $subscription when type is type is +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `file_descriptor`: [`fd`](#fd) +The file descriptor on which to wait for it to become ready for reading or writing. + +## `subscription_u`: Union +The contents of a $subscription. + +### Union variants +- `clock`: [`subscription_clock`](#subscription_clock) +When type is [`eventtype::clock`](#eventtype.clock): + +- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `subscription`: Struct +Subscription to an event. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that is attached to the subscription in the +implementation and returned through [`event::userdata`](#event.userdata). + +- `type`: [`eventtype`](#eventtype) +The type of the event to which to subscribe. + +- `u`: [`subscription_u`](#subscription_u) +The contents of the subscription. + +## `exitcode`: `u32` +Exit code generated by a process when exiting. + +## `riflags`: Flags(`u16`) +Flags provided to `sock_recv`. + +### Flags +- `recv_peek` +Returns the message without removing it from the socket's receive queue. + +- `recv_waitall` +On byte-stream sockets, block until the full amount of data can be returned. + +## `roflags`: Flags(`u16`) +Flags returned by `sock_recv`. + +### Flags +- `recv_data_truncated` +Returned by `sock_recv`: Message data has been truncated. + +## `siflags`: `u16` +Flags provided to `sock_send`. As there are currently no flags +defined, it must be set to zero. + +## `sdflags`: Flags(`u8`) +Which channels on a socket to shut down. + +### Flags +- `rd` +Disables further receive operations. + +- `wr` +Disables further send operations. + +## `preopentype`: Enum(`u8`) +Identifiers for preopened capabilities. + +### Variants +- `dir` +A pre-opened directory. + +## `prestat_dir`: Struct +The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). + +### Struct members +- `pr_name_len`: [`size`](#size) +The length of the directory name for use with `fd_prestat_dir_name`. + +## `prestat_u`: Union +The contents of an $prestat. + +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) +When type is [`preopentype::dir`](#preopentype.dir): + +## `prestat`: Struct +Information about a pre-opened capability. + +### Struct members +- `pr_type`: [`preopentype`](#preopentype) +The type of the pre-opened capability. + +- `u`: [`prestat_u`](#prestat_u) +The contents of the information. + +# Modules +## wasi_ephemeral_args +### Imports +#### Memory +### Functions + +--- + +#### `get(argv: Pointer>, argv_buf: Pointer) -> errno` +Read command-line argument data. +The size of the array should match that returned by [`sizes_get`](#sizes_get) + +##### Params +- `argv`: `Pointer>` + +- `argv_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + +## wasi_ephemeral_clock +### Imports +#### Memory +### Functions + +--- + +#### `res_get(id: clockid) -> (errno, timestamp)` +Return the resolution of a clock. +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Note: This is similar to `clock_getres` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the resolution. + +##### Results +- `error`: [`errno`](#errno) + +- `resolution`: [`timestamp`](#timestamp) +The resolution of the clock. + + +--- + +#### `time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +Return the time value of a clock. +Note: This is similar to `clock_gettime` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the time. + +- `precision`: [`timestamp`](#timestamp) +The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + +##### Results +- `error`: [`errno`](#errno) + +- `time`: [`timestamp`](#timestamp) +The time value of the clock. + +## wasi_ephemeral_environ +### Imports +#### Memory +### Functions + +--- + +#### `get(environ: Pointer>, environ_buf: Pointer) -> errno` +Read environment variable data. +The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). + +##### Params +- `environ`: `Pointer>` + +- `environ_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + +## wasi_ephemeral_fd +### Imports +#### Memory +### Functions + +--- + +#### `advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +Provide file advisory information on a file descriptor. +Note: This is similar to `posix_fadvise` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset within the file to which the advisory applies. + +- `len`: [`filesize`](#filesize) +The length of the region to which the advisory applies. + +- `advice`: [`advice`](#advice) +The advice. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `allocate(fd: fd, offset: filesize, len: filesize) -> errno` +Force the allocation of space in a file. +Note: This is similar to `posix_fallocate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset at which to start the allocation. + +- `len`: [`filesize`](#filesize) +The length of the area that is allocated. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `close(fd: fd) -> errno` +Close a file descriptor. +Note: This is similar to [`close`](#close) in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `datasync(fd: fd) -> errno` +Synchronize the data of a file to disk. +Note: This is similar to `fdatasync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fdstat_get(fd: fd) -> (errno, fdstat)` +Get the attributes of a file descriptor. +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `stat`: [`fdstat`](#fdstat) +The buffer where the file descriptor's attributes are stored. + + +--- + +#### `fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +Adjust the flags associated with a file descriptor. +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`fdflags`](#fdflags) +The desired values of the file descriptor flags. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +Adjust the rights associated with a file descriptor. +This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + +##### Params +- `fd`: [`fd`](#fd) + +- `fs_rights_base`: [`rights`](#rights) +The desired rights of the file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `filestat_get(fd: fd) -> (errno, filestat)` +Return the attributes of an open file. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `filestat_set_size(fd: fd, size: filesize) -> errno` +Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. +Note: This is similar to `ftruncate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `size`: [`filesize`](#filesize) +The desired file size. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of an open file or directory. +Note: This is similar to `futimens` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `permissions_set(fd: fd) -> (permissions, errno)` +Set the permissions of a file or directory. + +This sets the permissions associated with a file or directory in +a filesystem at the time it is called. The ability to actually access +a file or directory may depend on additional permissions not reflected +here. + +Note: This is similar `fchmod` in POSIX. + +Unlike POSIX, this doesn't expose a user/group/other distinction; +implementations in POSIX environments are suggested to consult the +umask to determine which of the user/group/other flags to modify. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `permissions`: [`permissions`](#permissions) +The permissions associated with the file. + +- `error`: [`errno`](#errno) + + +--- + +#### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +Read from a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `preadv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors in which to store data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to read. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `prestat_get(fd: fd) -> (errno, prestat)` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`prestat`](#prestat) +The buffer where the description is stored. + + +--- + +#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `Pointer` +A buffer into which to write the preopened directory name. + +- `path_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +Write to a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `pwritev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to write. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `read(fd: fd, iovs: iovec_array) -> (errno, size)` +Read from a file descriptor. +Note: This is similar to `readv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +Read directory entries from a directory. +When successful, the contents of the output buffer consist of a sequence of +directory entries. Each directory entry consists of a dirent_t object, +followed by dirent_t::d_namlen bytes holding the name of the directory +entry. +This function fills the output buffer as much as possible, potentially +truncating the last directory entry. This allows the caller to grow its +read buffer size in case it's too small to fit a single large directory +entry, or skip the oversized directory entry. + +##### Params +- `fd`: [`fd`](#fd) + +- `buf`: `Pointer` +The buffer where directory entries are stored + +- `buf_len`: [`size`](#size) + +- `cookie`: [`dircookie`](#dircookie) +The location within the directory to start reading + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + + +--- + +#### `renumber(fd: fd, to: fd) -> errno` +Atomically replace a file descriptor by renumbering another file descriptor. +Due to the strong focus on thread safety, this environment does not provide +a mechanism to duplicate or renumber a file descriptor to an arbitrary +number, like `dup2()`. This would be prone to race conditions, as an actual +file descriptor with the same number could be allocated by a different +thread at the same time. +This function provides a way to atomically renumber file descriptors, which +would disappear if `dup2()` were to be removed entirely. + +##### Params +- `fd`: [`fd`](#fd) + +- `to`: [`fd`](#fd) +The file descriptor to overwrite. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +Move the offset of a file descriptor. +Note: This is similar to `lseek` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filedelta`](#filedelta) +The number of bytes to move. + +- `whence`: [`whence`](#whence) +The base from which the offset is relative. + +##### Results +- `error`: [`errno`](#errno) + +- `newoffset`: [`filesize`](#filesize) +The new offset of the file descriptor, relative to the start of the file. + + +--- + +#### `sync(fd: fd) -> errno` +Synchronize the data and metadata of a file to disk. +Note: This is similar to `fsync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `tell(fd: fd) -> (errno, filesize)` +Return the current offset of a file descriptor. +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `offset`: [`filesize`](#filesize) +The current offset of the file descriptor, relative to the start of the file. + + +--- + +#### `write(fd: fd, iovs: ciovec_array) -> (errno, size)` +Write to a file descriptor. +Note: This is similar to `writev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + +## wasi_ephemeral_path +### Imports +#### Memory +### Functions + +--- + +#### `create_directory(fd: fd, path: string) -> errno` +Create a directory. +Note: This is similar to `mkdirat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path at which to create the directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +Return the attributes of a file or directory. +Note: This is similar to `stat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to inspect. + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of a file or directory. +Note: This is similar to `utimensat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to operate on. + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `permissions_set(fd: fd, flags: lookupflags, path: string, permissions: permissions) -> errno` +Set the permissions of a file or directory. + +This sets the permissions associated with a file or directory in +a filesystem at the time it is called. The ability to actually access +a file or directory may depend on additional permissions not reflected +here. + +Note: This is similar to `fchmodat` in POSIX. + +Unlike POSIX, this doesn't expose a user/group/other distinction; +implementations in POSIX environments are suggested to consult the +umask to determine which of the user/group/other flags to modify. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path to a file to query. + +- `permissions`: [`permissions`](#permissions) +The permissions to associate with the file. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +Create a hard link. +Note: This is similar to `linkat` in POSIX. + +##### Params +- `old_fd`: [`fd`](#fd) + +- `old_flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `old_path`: `string` +The source path from which to link. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path at which to create the hard link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags, permissions: permissions) -> (errno, fd)` +Open a file or directory. +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since this +is error-prone in multi-threaded contexts. The returned file descriptor is +guaranteed to be less than 2**31. +Note: This is similar to `openat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `dirflags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The relative path of the file or directory to open, relative to the +`dirfd` directory. + +- `oflags`: [`oflags`](#oflags) +The method by which to open the file. + +- `fs_rights_base`: [`rights`](#rights) +The initial rights of the newly created file descriptor. The +implementation is allowed to return a file descriptor with fewer rights +than specified, if and only if those rights do not apply to the type of +file being opened. +The *base* rights are rights that will apply to operations using the file +descriptor itself, while the *inheriting* rights are rights that apply to +file descriptors derived from it. + +- `fs_rights_inherting`: [`rights`](#rights) + +- `fdflags`: [`fdflags`](#fdflags) + +- `permissions`: [`permissions`](#permissions) +If a file is created, the filesystem permissions to associate with it. + +##### Results +- `error`: [`errno`](#errno) + +- `opened_fd`: [`fd`](#fd) +The file descriptor of the file that has been opened. + + +--- + +#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +Read the contents of a symbolic link. +Note: This is similar to `readlinkat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path of the symbolic link from which to read. + +- `buf`: `Pointer` +The buffer to which to write the contents of the symbolic link. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes placed in the buffer. + + +--- + +#### `remove_directory(fd: fd, path: string) -> errno` +Remove a directory. +Return `ENOTEMPTY` if the directory is not empty. +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a directory to remove. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +Rename a file or directory. +Note: This is similar to `renameat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `old_path`: `string` +The source path of the file or directory to rename. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path to which to rename the file or directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `symlink(old_path: string, fd: fd, new_path: string) -> errno` +Create a symbolic link. +Note: This is similar to `symlinkat` in POSIX. + +##### Params +- `old_path`: `string` +The contents of the symbolic link. + +- `fd`: [`fd`](#fd) + +- `new_path`: `string` +The destination path at which to create the symbolic link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `unlink_file(fd: fd, path: string) -> errno` +Unlink a file. +Return `EISDIR` if the path refers to a directory. +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a file to unlink. + +##### Results +- `error`: [`errno`](#errno) + +## wasi_ephemeral_poll +### Imports +#### Memory +### Functions + +--- + +#### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +Concurrently poll for the occurrence of a set of events. + +##### Params +- `in`: `ConstPointer` +The events to which to subscribe. + +- `out`: `Pointer` +The events that have occurred. + +- `nsubscriptions`: [`size`](#size) +Both the number of subscriptions and events. + +##### Results +- `error`: [`errno`](#errno) + +- `nevents`: [`size`](#size) +The number of events stored. + +## wasi_ephemeral_proc +### Imports +### Functions + +--- + +#### `exit(rval: exitcode)` +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +##### Params +- `rval`: [`exitcode`](#exitcode) +The exit code returned by the process. + +##### Results +## wasi_ephemeral_random +### Imports +#### Memory +### Functions + +--- + +#### `get(buf: Pointer, buf_len: size) -> errno` +Write high-quality random data into a buffer. +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. +This function may execute slowly, so when large mounts of random data are +required, it's advisable to use this function to seed a pseudo-random +number generator, rather than to provide the random data directly. + +##### Params +- `buf`: `Pointer` +The buffer to fill with random data. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + +## wasi_ephemeral_sched +### Imports +### Functions + +--- + +#### `yield() -> errno` +Temporarily yield execution of the calling thread. +Note: This is similar to [`yield`](#yield) in POSIX. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +## wasi_ephemeral_sock +### Imports +#### Memory +### Functions + +--- + +#### `recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +Receive a message from a socket. +Note: This is similar to [`recv`](#recv) in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +##### Params +- `fd`: [`fd`](#fd) + +- `ri_data`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +- `ri_flags`: [`riflags`](#riflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `ro_datalen`: [`size`](#size) +Number of bytes stored in ri_data. + +- `ro_flags`: [`roflags`](#roflags) +Message flags. + + +--- + +#### `send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +Send a message on a socket. +Note: This is similar to [`send`](#send) in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +##### Params +- `fd`: [`fd`](#fd) + +- `si_data`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors to which to retrieve data + +- `si_flags`: [`siflags`](#siflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `so_datalen`: [`size`](#size) +Number of bytes transmitted. + + +--- + +#### `shutdown(fd: fd, how: sdflags) -> errno` +Shut down socket send and receive channels. +Note: This is similar to [`shutdown`](#shutdown) in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `how`: [`sdflags`](#sdflags) +Which channels on the socket to shut down. + +##### Results +- `error`: [`errno`](#errno) + diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md new file mode 100644 index 000000000..360cff906 --- /dev/null +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -0,0 +1,1791 @@ +# Types +## `size`: `u32` + +## `filesize`: `u64` +Non-negative file size or length of a region within a file. + +## `timestamp`: `u64` +Timestamp in nanoseconds. + +## `clockid`: Enum(`u32`) +Identifiers for clocks. + +### Variants +- `realtime` +The clock measuring real time. Time value zero corresponds with +1970-01-01T00:00:00Z. + +- `monotonic` +The store-wide monotonic clock, which is defined as a clock measuring +real time, whose value cannot be adjusted and which cannot have negative +clock jumps. The epoch of this clock is undefined. The absolute time +value of this clock therefore has no meaning. + +- `process_cputime_id` +The CPU-time clock associated with the current process. + +- `thread_cputime_id` +The CPU-time clock associated with the current thread. + +## `errno`: Enum(`u16`) +Error codes returned by functions. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX. + +### Variants +- `success` +No error occurred. System call completed successfully. + +- `2big` +Argument list too long. + +- `acces` +Permission denied. + +- `addrinuse` +Address in use. + +- `addrnotavail` +Address not available. + +- `afnosupport` +Address family not supported. + +- `again` +Resource unavailable, or operation would block. + +- `already` +Connection already in progress. + +- `badf` +Bad file descriptor. + +- `badmsg` +Bad message. + +- `busy` +Device or resource busy. + +- `canceled` +Operation canceled. + +- `child` +No child processes. + +- `connaborted` +Connection aborted. + +- `connrefused` +Connection refused. + +- `connreset` +Connection reset. + +- `deadlk` +Resource deadlock would occur. + +- `destaddrreq` +Destination address required. + +- `dom` +Mathematics argument out of domain of function. + +- `dquot` +Reserved. + +- `exist` +File exists. + +- `fault` +Bad address. + +- `fbig` +File too large. + +- `hostunreach` +Host is unreachable. + +- `idrm` +Identifier removed. + +- `ilseq` +Illegal byte sequence. + +- `inprogress` +Operation in progress. + +- `intr` +Interrupted function. + +- `inval` +Invalid argument. + +- `io` +I/O error. + +- `isconn` +Socket is connected. + +- `isdir` +Is a directory. + +- `loop` +Too many levels of symbolic links. + +- `mfile` +File descriptor value too large. + +- `mlink` +Too many links. + +- `msgsize` +Message too large. + +- `multihop` +Reserved. + +- `nametoolong` +Filename too long. + +- `netdown` +Network is down. + +- `netreset` +Connection aborted by network. + +- `netunreach` +Network unreachable. + +- `nfile` +Too many files open in system. + +- `nobufs` +No buffer space available. + +- `nodev` +No such device. + +- `noent` +No such file or directory. + +- `noexec` +Executable file format error. + +- `nolck` +No locks available. + +- `nolink` +Reserved. + +- `nomem` +Not enough space. + +- `nomsg` +No message of the desired type. + +- `noprotoopt` +Protocol not available. + +- `nospc` +No space left on device. + +- `nosys` +Function not supported. + +- `notconn` +The socket is not connected. + +- `notdir` +Not a directory or a symbolic link to a directory. + +- `notempty` +Directory not empty. + +- `notrecoverable` +State not recoverable. + +- `notsock` +Not a socket. + +- `notsup` +Not supported, or operation not supported on socket. + +- `notty` +Inappropriate I/O control operation. + +- `nxio` +No such device or address. + +- `overflow` +Value too large to be stored in data type. + +- `ownerdead` +Previous owner died. + +- `perm` +Operation not permitted. + +- `pipe` +Broken pipe. + +- `proto` +Protocol error. + +- `protonosupport` +Protocol not supported. + +- `prototype` +Protocol wrong type for socket. + +- `range` +Result too large. + +- `rofs` +Read-only file system. + +- `spipe` +Invalid seek. + +- `srch` +No such process. + +- `stale` +Reserved. + +- `timedout` +Connection timed out. + +- `txtbsy` +Text file busy. + +- `xdev` +Cross-device link. + +- `notcapable` +Extension: Capabilities insufficient. + +## `rights`: Flags(`u64`) +File descriptor rights, determining which actions may be performed. + +### Flags +- `fd_datasync` +The right to invoke [`fd_datasync`](#fd_datasync). +If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke +[`path_open`](#path_open) with `FDFLAG_DSYNC`. + +- `fd_read` +The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). + +- `fd_seek` +The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). + +- `fd_fdstat_set_flags` +The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). + +- `fd_sync` +The right to invoke [`fd_sync`](#fd_sync). +If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke +[`path_open`](#path_open) with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + +- `fd_tell` +The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset +remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +invoke [`fd_tell`](#fd_tell). + +- `fd_write` +The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). + +- `fd_advise` +The right to invoke [`fd_advise`](#fd_advise). + +- `fd_allocate` +The right to invoke [`fd_allocate`](#fd_allocate). + +- `path_create_directory` +The right to invoke [`path_create_directory`](#path_create_directory). + +- `path_create_file` +If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with `O_CREAT`. + +- `path_link_source` +The right to invoke [`path_link`](#path_link) with the file descriptor as the +source directory. + +- `path_link_target` +The right to invoke [`path_link`](#path_link) with the file descriptor as the +target directory. + +- `path_open` +The right to invoke [`path_open`](#path_open). + +- `fd_readdir` +The right to invoke [`fd_readdir`](#fd_readdir). + +- `path_readlink` +The right to invoke [`path_readlink`](#path_readlink). + +- `path_rename_source` +The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. + +- `path_rename_target` +The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. + +- `path_filestat_get` +The right to invoke [`path_filestat_get`](#path_filestat_get). + +- `path_filestat_set_size` +The right to change a file's size (there is no `path_filestat_set_size`). +If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with `O_TRUNC`. + +- `path_filestat_set_times` +The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). + +- `fd_filestat_get` +The right to invoke [`fd_filestat_get`](#fd_filestat_get). + +- `fd_filestat_set_size` +The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). + +- `fd_filestat_set_times` +The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). + +- `path_symlink` +The right to invoke [`path_symlink`](#path_symlink). + +- `path_remove_directory` +The right to invoke [`path_remove_directory`](#path_remove_directory). + +- `path_unlink_file` +The right to invoke [`path_unlink_file`](#path_unlink_file). + +- `poll_fd_readwrite` +If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). +If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). + +- `sock_shutdown` +The right to invoke [`sock_shutdown`](#sock_shutdown). + +## `fd`: `u32` +A file descriptor index. + +## `iovec`: Struct +A region of memory for scatter/gather reads. + +### Struct members +- `buf`: `Pointer` +The address of the buffer to be filled. + +- `buf_len`: [`size`](#size) +The length of the buffer to be filled. + +## `ciovec`: Struct +A region of memory for scatter/gather writes. + +### Struct members +- `buf`: `ConstPointer` +The address of the buffer to be written. + +- `buf_len`: [`size`](#size) +The length of the buffer to be written. + +## `iovec_array`: `Array` + +## `ciovec_array`: `Array` + +## `filedelta`: `s64` +Relative offset within a file. + +## `whence`: Enum(`u8`) +The position relative to which to set the offset of the file descriptor. + +### Variants +- `cur` +Seek relative to current position. + +- `end` +Seek relative to end-of-file. + +- `set` +Seek relative to start-of-file. + +## `dircookie`: `u64` +A reference to the offset of a directory entry. + +## `dirnamlen`: `u32` +The type for the $d_namlen field of $dirent. + +## `inode`: `u64` +File serial number that is unique within its file system. + +## `filetype`: Enum(`u8`) +The type of a file descriptor or file. + +### Variants +- `unknown` +The type of the file descriptor or file is unknown or is different from any of the other types specified. + +- `block_device` +The file descriptor or file refers to a block device inode. + +- `character_device` +The file descriptor or file refers to a character device inode. + +- `directory` +The file descriptor or file refers to a directory inode. + +- `regular_file` +The file descriptor or file refers to a regular file inode. + +- `socket_dgram` +The file descriptor or file refers to a datagram socket. + +- `socket_stream` +The file descriptor or file refers to a byte-stream socket. + +- `symbolic_link` +The file refers to a symbolic link inode. + +## `dirent`: Struct +A directory entry. + +### Struct members +- `d_next`: [`dircookie`](#dircookie) +The offset of the next directory entry stored in this directory. + +- `d_ino`: [`inode`](#inode) +The serial number of the file referred to by this directory entry. + +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. + +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. + +## `advice`: Enum(`u8`) +File or memory access pattern advisory information. + +### Variants +- `normal` +The application has no advice to give on its behavior with respect to the specified data. + +- `sequential` +The application expects to access the specified data sequentially from lower offsets to higher offsets. + +- `random` +The application expects to access the specified data in a random order. + +- `willneed` +The application expects to access the specified data in the near future. + +- `dontneed` +The application expects that it will not access the specified data in the near future. + +- `noreuse` +The application expects to access the specified data once and then not reuse it thereafter. + +## `fdflags`: Flags(`u16`) +File descriptor flags. + +### Flags +- `append` +Append mode: Data written to the file is always appended to the file's end. + +- `dsync` +Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + +- `nonblock` +Non-blocking mode. + +- `rsync` +Synchronized read I/O operations. + +- `sync` +Write according to synchronized I/O file integrity completion. In +addition to synchronizing the data stored in the file, the implementation +may also synchronously update the file's metadata. + +## `fdstat`: Struct +File descriptor attributes. + +### Struct members +- `fs_filetype`: [`filetype`](#filetype) +File type. + +- `fs_flags`: [`fdflags`](#fdflags) +File descriptor flags. + +- `fs_rights_base`: [`rights`](#rights) +Rights that apply to this file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) +Maximum set of rights that may be installed on new file descriptors that +are created through this file descriptor, e.g., through [`path_open`](#path_open). + +## `device`: `u64` +Identifier for a device containing a file system. Can be used in combination +with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. + +## `fstflags`: Flags(`u16`) +Which file time attributes to adjust. + +### Flags +- `atim` +Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + +- `atim_now` +Adjust the last data access timestamp to the time of clock `clock::realtime`. + +- `mtim` +Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + +- `mtim_now` +Adjust the last data modification timestamp to the time of clock `clock::realtime`. + +## `lookupflags`: Flags(`u32`) +Flags determining the method of how paths are resolved. + +### Flags +- `symlink_follow` +As long as the resolved path corresponds to a symbolic link, it is expanded. + +## `oflags`: Flags(`u16`) +Open flags used by [`path_open`](#path_open). + +### Flags +- `creat` +Create file if it does not exist. + +- `directory` +Fail if not a directory. + +- `excl` +Fail if file already exists. + +- `trunc` +Truncate file to size 0. + +## `linkcount`: `u32` +Number of hard links to an inode. + +## `filestat`: Struct +File attributes. + +### Struct members +- `dev`: [`device`](#device) +Device ID of device containing the file. + +- `ino`: [`inode`](#inode) +File serial number. + +- `filetype`: [`filetype`](#filetype) +File type. + +- `nlink`: [`linkcount`](#linkcount) +Number of hard links to the file. + +- `size`: [`filesize`](#filesize) +For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + +- `atim`: [`timestamp`](#timestamp) +Last data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +Last data modification timestamp. + +- `ctim`: [`timestamp`](#timestamp) +Last file status change timestamp. + +## `userdata`: `u64` +User-provided value that may be attached to objects that is retained when +extracted from the implementation. + +## `eventtype`: Enum(`u8`) +Type of a subscription to an event or its occurrence. + +### Variants +- `clock` +The time value of clock `subscription::u.clock.clock_id` has +reached timestamp `subscription::u.clock.timeout`. + +- `fd_read` +File descriptor `subscription::u.fd_readwrite.fd` has data +available for reading. This event always triggers for regular files. + +- `fd_write` +File descriptor `subscription::u.fd_readwrite.fd` has capacity +available for writing. This event always triggers for regular files. + +## `eventrwflags`: Flags(`u16`) +The state of the file descriptor subscribed to with +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Flags +- `fd_readwrite_hangup` +The peer of this socket has closed or disconnected. + +## `event_fd_readwrite`: Struct +The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `nbytes`: [`filesize`](#filesize) +The number of bytes available for reading or writing. + +- `flags`: [`eventrwflags`](#eventrwflags) +The state of the file descriptor. + +## `event_u`: Union +The contents of an $event. + +### Union variants +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `event`: Struct +An event that occurred. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). + +- `error`: [`errno`](#errno) +If non-zero, an error that occurred while processing the subscription request. + +- `type`: [`eventtype`](#eventtype) +The type of the event that occurred. + +- `u`: [`event_u`](#event_u) +The contents of the event. + +## `subclockflags`: Flags(`u16`) +Flags determining how to interpret the timestamp provided in +`subscription::u.clock.timeout.` + +### Flags +- `subscription_clock_abstime` +If set, treat the timestamp provided in +`subscription::u.clock.timeout` as an absolute timestamp of clock +`subscription::u.clock.clock_id.` If clear, treat the timestamp +provided in `subscription::u.clock.timeout` relative to the +current time value of clock `subscription::u.clock.clock_id.` + +## `subscription_clock`: Struct +The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). + +### Struct members +- `identifier`: [`userdata`](#userdata) +The user-defined unique identifier of the clock. + +- `id`: [`clockid`](#clockid) +The clock against which to compare the timestamp. + +- `timeout`: [`timestamp`](#timestamp) +The absolute or relative timestamp. + +- `precision`: [`timestamp`](#timestamp) +The amount of time that the implementation may wait additionally +to coalesce with other events. + +- `flags`: [`subclockflags`](#subclockflags) +Flags specifying whether the timeout is absolute or relative + +## `subscription_fd_readwrite`: Struct +The contents of a $subscription when type is type is +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `file_descriptor`: [`fd`](#fd) +The file descriptor on which to wait for it to become ready for reading or writing. + +## `subscription_u`: Union +The contents of a $subscription. + +### Union variants +- `clock`: [`subscription_clock`](#subscription_clock) +When type is [`eventtype::clock`](#eventtype.clock): + +- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `subscription`: Struct +Subscription to an event. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that is attached to the subscription in the +implementation and returned through [`event::userdata`](#event.userdata). + +- `type`: [`eventtype`](#eventtype) +The type of the event to which to subscribe. + +- `u`: [`subscription_u`](#subscription_u) +The contents of the subscription. + +## `exitcode`: `u32` +Exit code generated by a process when exiting. + +## `signal`: Enum(`u8`) +Signal condition. + +### Variants +- `none` +No signal. Note that POSIX has special semantics for `kill(pid, 0)`, +so this value is reserved. + +- `hup` +Hangup. +Action: Terminates the process. + +- `int` +Terminate interrupt signal. +Action: Terminates the process. + +- `quit` +Terminal quit signal. +Action: Terminates the process. + +- `ill` +Illegal instruction. +Action: Terminates the process. + +- `trap` +Trace/breakpoint trap. +Action: Terminates the process. + +- `abrt` +Process abort signal. +Action: Terminates the process. + +- `bus` +Access to an undefined portion of a memory object. +Action: Terminates the process. + +- `fpe` +Erroneous arithmetic operation. +Action: Terminates the process. + +- `kill` +Kill. +Action: Terminates the process. + +- `usr1` +User-defined signal 1. +Action: Terminates the process. + +- `segv` +Invalid memory reference. +Action: Terminates the process. + +- `usr2` +User-defined signal 2. +Action: Terminates the process. + +- `pipe` +Write on a pipe with no one to read it. +Action: Ignored. + +- `alrm` +Alarm clock. +Action: Terminates the process. + +- `term` +Termination signal. +Action: Terminates the process. + +- `chld` +Child process terminated, stopped, or continued. +Action: Ignored. + +- `cont` +Continue executing, if stopped. +Action: Continues executing, if stopped. + +- `stop` +Stop executing. +Action: Stops executing. + +- `tstp` +Terminal stop signal. +Action: Stops executing. + +- `ttin` +Background process attempting read. +Action: Stops executing. + +- `ttou` +Background process attempting write. +Action: Stops executing. + +- `urg` +High bandwidth data is available at a socket. +Action: Ignored. + +- `xcpu` +CPU time limit exceeded. +Action: Terminates the process. + +- `xfsz` +File size limit exceeded. +Action: Terminates the process. + +- `vtalrm` +Virtual timer expired. +Action: Terminates the process. + +- `prof` +Profiling timer expired. +Action: Terminates the process. + +- `winch` +Window changed. +Action: Ignored. + +- `poll` +I/O possible. +Action: Terminates the process. + +- `pwr` +Power failure. +Action: Terminates the process. + +- `sys` +Bad system call. +Action: Terminates the process. + +## `riflags`: Flags(`u16`) +Flags provided to [`sock_recv`](#sock_recv). + +### Flags +- `recv_peek` +Returns the message without removing it from the socket's receive queue. + +- `recv_waitall` +On byte-stream sockets, block until the full amount of data can be returned. + +## `roflags`: Flags(`u16`) +Flags returned by [`sock_recv`](#sock_recv). + +### Flags +- `recv_data_truncated` +Returned by [`sock_recv`](#sock_recv): Message data has been truncated. + +## `siflags`: `u16` +Flags provided to [`sock_send`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +## `sdflags`: Flags(`u8`) +Which channels on a socket to shut down. + +### Flags +- `rd` +Disables further receive operations. + +- `wr` +Disables further send operations. + +## `preopentype`: Enum(`u8`) +Identifiers for preopened capabilities. + +### Variants +- `dir` +A pre-opened directory. + +## `prestat_dir`: Struct +The contents of a $prestat when type is `PREOPENTYPE_DIR`. + +### Struct members +- `pr_name_len`: [`size`](#size) +The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). + +## `prestat_u`: Union +The contents of an $prestat. + +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) +When type is `PREOPENTYPE_DIR`: + +## `prestat`: Struct +Information about a pre-opened capability. + +### Struct members +- `pr_type`: [`preopentype`](#preopentype) +The type of the pre-opened capability. + +- `u`: [`prestat_u`](#prestat_u) +The contents of the information. + +# Modules +## wasi_unstable +### Imports +#### Memory +### Functions + +--- + +#### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` +Read command-line argument data. +The size of the array should match that returned by `wasi_args_sizes_get()` + +##### Params +- `argv`: `Pointer>` + +- `argv_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `args_sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + + +--- + +#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` +Read environment variable data. +The sizes of the buffers should match that returned by `environ.sizes_get()`. + +##### Params +- `environ`: `Pointer>` + +- `environ_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `environ_sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + + +--- + +#### `clock_res_get(id: clockid) -> (errno, timestamp)` +Return the resolution of a clock. +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Note: This is similar to `clock_getres` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the resolution. + +##### Results +- `error`: [`errno`](#errno) + +- `resolution`: [`timestamp`](#timestamp) +The resolution of the clock. + + +--- + +#### `clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +Return the time value of a clock. +Note: This is similar to `clock_gettime` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the time. + +- `precision`: [`timestamp`](#timestamp) +The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + +##### Results +- `error`: [`errno`](#errno) + +- `time`: [`timestamp`](#timestamp) +The time value of the clock. + + +--- + +#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +Provide file advisory information on a file descriptor. +Note: This is similar to `posix_fadvise` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset within the file to which the advisory applies. + +- `len`: [`filesize`](#filesize) +The length of the region to which the advisory applies. + +- `advice`: [`advice`](#advice) +The advice. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno` +Force the allocation of space in a file. +Note: This is similar to `posix_fallocate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset at which to start the allocation. + +- `len`: [`filesize`](#filesize) +The length of the area that is allocated. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_close(fd: fd) -> errno` +Close a file descriptor. +Note: This is similar to `close` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_datasync(fd: fd) -> errno` +Synchronize the data of a file to disk. +Note: This is similar to `fdatasync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_fdstat_get(fd: fd) -> (errno, fdstat)` +Get the attributes of a file descriptor. +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `stat`: [`fdstat`](#fdstat) +The buffer where the file descriptor's attributes are stored. + + +--- + +#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +Adjust the flags associated with a file descriptor. +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`fdflags`](#fdflags) +The desired values of the file descriptor flags. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +Adjust the rights associated with a file descriptor. +This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + +##### Params +- `fd`: [`fd`](#fd) + +- `fs_rights_base`: [`rights`](#rights) +The desired rights of the file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_filestat_get(fd: fd) -> (errno, filestat)` +Return the attributes of an open file. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `fd_filestat_set_size(fd: fd, size: filesize) -> errno` +Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. +Note: This is similar to `ftruncate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `size`: [`filesize`](#filesize) +The desired file size. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of an open file or directory. +Note: This is similar to `futimens` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +Read from a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `preadv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors in which to store data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to read. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `fd_prestat_get(fd: fd) -> (errno, prestat)` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`prestat`](#prestat) +The buffer where the description is stored. + + +--- + +#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `Pointer` +A buffer into which to write the preopened directory name. + +- `path_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +Write to a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `pwritev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to write. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `fd_read(fd: fd, iovs: iovec_array) -> (errno, size)` +Read from a file descriptor. +Note: This is similar to `readv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +Read directory entries from a directory. +When successful, the contents of the output buffer consist of a sequence of +directory entries. Each directory entry consists of a dirent_t object, +followed by dirent_t::d_namlen bytes holding the name of the directory +entry. +This function fills the output buffer as much as possible, potentially +truncating the last directory entry. This allows the caller to grow its +read buffer size in case it's too small to fit a single large directory +entry, or skip the oversized directory entry. + +##### Params +- `fd`: [`fd`](#fd) + +- `buf`: `Pointer` +The buffer where directory entries are stored + +- `buf_len`: [`size`](#size) + +- `cookie`: [`dircookie`](#dircookie) +The location within the directory to start reading + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + + +--- + +#### `fd_renumber(fd: fd, to: fd) -> errno` +Atomically replace a file descriptor by renumbering another file descriptor. +Due to the strong focus on thread safety, this environment does not provide +a mechanism to duplicate or renumber a file descriptor to an arbitrary +number, like `dup2()`. This would be prone to race conditions, as an actual +file descriptor with the same number could be allocated by a different +thread at the same time. +This function provides a way to atomically renumber file descriptors, which +would disappear if `dup2()` were to be removed entirely. + +##### Params +- `fd`: [`fd`](#fd) + +- `to`: [`fd`](#fd) +The file descriptor to overwrite. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +Move the offset of a file descriptor. +Note: This is similar to `lseek` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filedelta`](#filedelta) +The number of bytes to move. + +- `whence`: [`whence`](#whence) +The base from which the offset is relative. + +##### Results +- `error`: [`errno`](#errno) + +- `newoffset`: [`filesize`](#filesize) +The new offset of the file descriptor, relative to the start of the file. + + +--- + +#### `fd_sync(fd: fd) -> errno` +Synchronize the data and metadata of a file to disk. +Note: This is similar to `fsync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_tell(fd: fd) -> (errno, filesize)` +Return the current offset of a file descriptor. +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `offset`: [`filesize`](#filesize) +The current offset of the file descriptor, relative to the start of the file. + + +--- + +#### `fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)` +Write to a file descriptor. +Note: This is similar to `writev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `path_create_directory(fd: fd, path: string) -> errno` +Create a directory. +Note: This is similar to `mkdirat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path at which to create the directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +Return the attributes of a file or directory. +Note: This is similar to `stat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to inspect. + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of a file or directory. +Note: This is similar to `utimensat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to operate on. + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +Create a hard link. +Note: This is similar to `linkat` in POSIX. + +##### Params +- `old_fd`: [`fd`](#fd) + +- `old_flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `old_path`: `string` +The source path from which to link. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path at which to create the hard link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)` +Open a file or directory. +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since this +is error-prone in multi-threaded contexts. The returned file descriptor is +guaranteed to be less than 2**31. +Note: This is similar to `openat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `dirflags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The relative path of the file or directory to open, relative to the +`dirfd` directory. + +- `oflags`: [`oflags`](#oflags) +The method by which to open the file. + +- `fs_rights_base`: [`rights`](#rights) +The initial rights of the newly created file descriptor. The +implementation is allowed to return a file descriptor with fewer rights +than specified, if and only if those rights do not apply to the type of +file being opened. +The *base* rights are rights that will apply to operations using the file +descriptor itself, while the *inheriting* rights are rights that apply to +file descriptors derived from it. + +- `fs_rights_inherting`: [`rights`](#rights) + +- `fdflags`: [`fdflags`](#fdflags) + +##### Results +- `error`: [`errno`](#errno) + +- `opened_fd`: [`fd`](#fd) +The file descriptor of the file that has been opened. + + +--- + +#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +Read the contents of a symbolic link. +Note: This is similar to `readlinkat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path of the symbolic link from which to read. + +- `buf`: `Pointer` +The buffer to which to write the contents of the symbolic link. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes placed in the buffer. + + +--- + +#### `path_remove_directory(fd: fd, path: string) -> errno` +Remove a directory. +Return `ENOTEMPTY` if the directory is not empty. +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a directory to remove. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +Rename a file or directory. +Note: This is similar to `renameat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `old_path`: `string` +The source path of the file or directory to rename. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path to which to rename the file or directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_symlink(old_path: string, fd: fd, new_path: string) -> errno` +Create a symbolic link. +Note: This is similar to `symlinkat` in POSIX. + +##### Params +- `old_path`: `string` +The contents of the symbolic link. + +- `fd`: [`fd`](#fd) + +- `new_path`: `string` +The destination path at which to create the symbolic link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_unlink_file(fd: fd, path: string) -> errno` +Unlink a file. +Return `EISDIR` if the path refers to a directory. +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a file to unlink. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +Concurrently poll for the occurrence of a set of events. + +##### Params +- `in`: `ConstPointer` +The events to which to subscribe. + +- `out`: `Pointer` +The events that have occurred. + +- `nsubscriptions`: [`size`](#size) +Both the number of subscriptions and events. + +##### Results +- `error`: [`errno`](#errno) + +- `nevents`: [`size`](#size) +The number of events stored. + + +--- + +#### `proc_exit(rval: exitcode)` +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +##### Params +- `rval`: [`exitcode`](#exitcode) +The exit code returned by the process. + +##### Results + +--- + +#### `proc_raise(sig: signal) -> errno` +Send a signal to the process of the calling thread. +Note: This is similar to `raise` in POSIX. + +##### Params +- `sig`: [`signal`](#signal) +The signal condition to trigger. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sched_yield() -> errno` +Temporarily yield execution of the calling thread. +Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. + +##### Params +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `random_get(buf: Pointer, buf_len: size) -> errno` +Write high-quality random data into a buffer. +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. +This function may execute slowly, so when large mounts of random data are +required, it's advisable to use this function to seed a pseudo-random +number generator, rather than to provide the random data directly. + +##### Params +- `buf`: `Pointer` +The buffer to fill with random data. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +Receive a message from a socket. +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +##### Params +- `fd`: [`fd`](#fd) + +- `ri_data`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +- `ri_flags`: [`riflags`](#riflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `ro_datalen`: [`size`](#size) +Number of bytes stored in ri_data. + +- `ro_flags`: [`roflags`](#roflags) +Message flags. + + +--- + +#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +Send a message on a socket. +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +##### Params +- `fd`: [`fd`](#fd) + +- `si_data`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors to which to retrieve data + +- `si_flags`: [`siflags`](#siflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `so_datalen`: [`size`](#size) +Number of bytes transmitted. + + +--- + +#### `sock_shutdown(fd: fd, how: sdflags) -> errno` +Shut down socket send and receive channels. +Note: This is similar to `shutdown` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `how`: [`sdflags`](#sdflags) +Which channels on the socket to shut down. + +##### Results +- `error`: [`errno`](#errno) + diff --git a/proposals/clocks/phases/old/snapshot_0/docs/wasi_unstable.md b/proposals/clocks/phases/old/snapshot_0/docs/wasi_unstable.md deleted file mode 100644 index 2464f2342..000000000 --- a/proposals/clocks/phases/old/snapshot_0/docs/wasi_unstable.md +++ /dev/null @@ -1,2343 +0,0 @@ - - -# The WASI Preview API - -This is the API-level documentation for WASI Preview. The function names -are prefixed with "\_\_wasi\_" to reflect how they are spelled in -flat-namespace contexts, however at the wasm module level, they are -unprefixed, because they're inside a module namespace. - -Functions that start with `__wasi_fd_` operate on file descriptors, -while functions that start with `__wasi_path_` operate on filesystem -paths, which are relative to directory file descriptors. - -Much inspiration and content here is derived from [CloudABI] and [POSIX], -though there are also several differences from CloudABI and POSIX. For -example, WASI Preview has no concept of processes in the traditional Unix -sense. While wasm linear memories have some of the aspects of processes, -and it's possible to *emulate* the full semantics of processes on top of -them, this can sometimes be unnatural and inefficient. The goal for -WASI Preview is to be a WebAssembly-native API that exposes APIs that fit -well into the underlying WebAssembly platform, rather than to directly -emulate other platforms. - -This is also a work in progress, and the API here is still evolving. - -Historical note: this API was originally named "WASI Core", and used the -API module name "wasi\_unstable". We've since sought to deemphasize the -"Core" name, as the goal is to split this API up into independent -modules so that embedders need not implement all of it. - -[CloudABI]: https://github.com/NuxiNL/cloudabi -[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ - -## System calls - -- [`__wasi_args_get()`](#args_get) -- [`__wasi_args_sizes_get()`](#args_sizes_get) -- [`__wasi_clock_res_get()`](#clock_res_get) -- [`__wasi_clock_time_get()`](#clock_time_get) -- [`__wasi_environ_get()`](#environ_get) -- [`__wasi_environ_sizes_get()`](#environ_sizes_get) -- [`__wasi_fd_advise()`](#fd_advise) -- [`__wasi_fd_allocate()`](#fd_allocate) -- [`__wasi_fd_close()`](#fd_close) -- [`__wasi_fd_datasync()`](#fd_datasync) -- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) -- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) -- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) -- [`__wasi_fd_filestat_get()`](#fd_filestat_get) -- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) -- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) -- [`__wasi_fd_pread()`](#fd_pread) -- [`__wasi_fd_prestat_get()`](#fd_prestat_get) -- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) -- [`__wasi_fd_pwrite()`](#fd_pwrite) -- [`__wasi_fd_read()`](#fd_read) -- [`__wasi_fd_readdir()`](#fd_readdir) -- [`__wasi_fd_renumber()`](#fd_renumber) -- [`__wasi_fd_seek()`](#fd_seek) -- [`__wasi_fd_sync()`](#fd_sync) -- [`__wasi_fd_tell()`](#fd_tell) -- [`__wasi_fd_write()`](#fd_write) -- [`__wasi_path_create_directory()`](#path_create_directory) -- [`__wasi_path_filestat_get()`](#path_filestat_get) -- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) -- [`__wasi_path_link()`](#path_link) -- [`__wasi_path_open()`](#path_open) -- [`__wasi_path_readlink()`](#path_readlink) -- [`__wasi_path_remove_directory()`](#path_remove_directory) -- [`__wasi_path_rename()`](#path_rename) -- [`__wasi_path_symlink()`](#path_symlink) -- [`__wasi_path_unlink_file()`](#path_unlink_file) -- [`__wasi_poll_oneoff()`](#poll_oneoff) -- [`__wasi_proc_exit()`](#proc_exit) -- [`__wasi_proc_raise()`](#proc_raise) -- [`__wasi_random_get()`](#random_get) -- [`__wasi_sched_yield()`](#sched_yield) -- [`__wasi_sock_recv()`](#sock_recv) -- [`__wasi_sock_send()`](#sock_send) -- [`__wasi_sock_shutdown()`](#sock_shutdown) - -### `__wasi_args_get()` - -Read command-line argument data. - -The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - -Inputs: - -- char \*\*argv - - A pointer to a buffer to write the argument pointers. - -- char \*argv\_buf - - A pointer to a buffer to write the argument string data. - -### `__wasi_args_sizes_get()` - -Return command-line argument data sizes. - -Outputs: - -- size\_t \*argc - - The number of arguments. - -- size\_t \*argv\_buf\_size - - The size of the argument string data. - -### `__wasi_clock_res_get()` - -Return the resolution of a clock. - -Implementations are required to provide a non-zero value for supported clocks. -For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). - -Note: This is similar to `clock_getres` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the resolution. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) resolution - - The resolution of the clock. - -### `__wasi_clock_time_get()` - -Return the time value of a clock. - -Note: This is similar to `clock_gettime` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the time. - -- [\_\_wasi\_timestamp\_t](#timestamp) precision - - The maximum lag (exclusive) that the returned - time value may have, compared to its actual - value. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) time - - The time value of the clock. - -### `__wasi_environ_get()` - -Read environment variable data. - -The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - -Inputs: - -- char \*\*environ - - A pointer to a buffer to write the environment variable pointers. - -- char \*environ\_buf - - A pointer to a buffer to write the environment variable string data. - -### `__wasi_environ_sizes_get()` - -Return command-line argument data sizes. - -Outputs: - -- size\_t \*environ\_count - - The number of environment variables. - -- size\_t \*environ\_buf\_size - - The size of the environment variable string data. - -### `__wasi_fd_advise()` - -Provide file advisory information on a file descriptor. - -Note: This is similar to `posix_fadvise` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file for which to provide file advisory information. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file to which the advisory applies. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the region to which the advisory applies. - -- [\_\_wasi\_advice\_t](#advice) advice - - The advice. - -### `__wasi_fd_allocate()` - -Force the allocation of space in a file. - -Note: This is similar to `posix_fallocate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file in which to allocate space. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset at which to start the allocation. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the area that is allocated. - -### `__wasi_fd_close()` - -Close a file descriptor. - -Note: This is similar to `close` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to close. - -### `__wasi_fd_datasync()` - -Synchronize the data of a file to disk. - -Note: This is similar to `fdatasync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file to synchronize to disk. - -### `__wasi_fd_fdstat_get()` - -Get the attributes of a file descriptor. - -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well -as additional fields. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_fdstat\_t](#fdstat) \*buf - - The buffer where the file descriptor's attributes are stored. - -### `__wasi_fd_fdstat_set_flags()` - -Adjust the flags associated with a file descriptor. - -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_fdflags\_t](#fdflags) flags - - The desired values of the file descriptor - flags. - -### `__wasi_fd_fdstat_set_rights()` - -Adjust the rights associated with a file descriptor. - -This can only be used to remove rights, and returns -[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt -to add rights. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The desired rights of the file descriptor. - -### `__wasi_fd_filestat_get()` - -Return the attributes of an open file. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_fd_filestat_set_size()` - -Adjust the size of an open file. If this increases the file's size, the extra -bytes are filled with zeros. - -Note: This is similar to `ftruncate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - A file descriptor for the file to adjust. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - The desired file size. - -### `__wasi_fd_filestat_set_times()` - -Adjust the timestamps of an open file or directory. - -Note: This is similar to `futimens` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_fd_pread()` - -Read from a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `preadv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors in which to store data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to read. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_prestat_get()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- [\_\_wasi\_prestat\_t](#prestat) \*buf - - The buffer where the description is stored. - -### `__wasi_fd_prestat_dir_name()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- const char \*path and size\_t path\_len - - A buffer into which to write the preopened directory name. - -### `__wasi_fd_pwrite()` - -Write to a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `pwritev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to write. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_fd_read()` - -Read from a file descriptor. - -Note: This is similar to `readv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors to which to store data. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_readdir()` - -Read directory entries from a directory. - -When successful, the contents of the output buffer consist of -a sequence of directory entries. Each directory entry consists -of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes -holding the name of the directory entry. - -This function fills the output buffer as much as possible, -potentially truncating the last directory entry. This allows -the caller to grow its read buffer size in case it's too small -to fit a single large directory entry, or skip the oversized -directory entry. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The directory from which to read the directory - entries. - -- void \*buf and size\_t buf\_len - - The buffer where directory entries are stored. - -- [\_\_wasi\_dircookie\_t](#dircookie) cookie - - The location within the directory to start - reading. - -Outputs: - -- size\_t bufused - - The number of bytes stored in the read buffer. - If less than the size of the read buffer, the - end of the directory has been reached. - -### `__wasi_fd_renumber()` - -Atomically replace a file descriptor by renumbering another -file descriptor. - -Due to the strong focus on thread safety, this environment -does not provide a mechanism to duplicate or renumber a file -descriptor to an arbitrary number, like dup2(). This would be -prone to race conditions, as an actual file descriptor with the -same number could be allocated by a different thread at the same -time. - -This function provides a way to atomically renumber file -descriptors, which would disappear if dup2() were to be -removed entirely. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) from - - The file descriptor to renumber. - -- [\_\_wasi\_fd\_t](#fd) to - - The file descriptor to overwrite. - -### `__wasi_fd_seek()` - -Move the offset of a file descriptor. - -Note: This is similar to `lseek` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_filedelta\_t](#filedelta) offset - - The number of bytes to move. - -- [\_\_wasi\_whence\_t](#whence) whence - - The base from which the offset is relative. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) newoffset - - The new offset of the file descriptor, - relative to the start of the file. - -### `__wasi_fd_sync()` - -Synchronize the data and metadata of a file to disk. - -Note: This is similar to `fsync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file containing the data - and metadata to synchronize to disk. - -### `__wasi_fd_tell()` - -Return the current offset of a file descriptor. - -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The current offset of the file descriptor, relative to the start of the file. - -### `__wasi_fd_write()` - -Write to a file descriptor. - -Note: This is similar to `writev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_path_create_directory()` - -Create a directory. - -Note: This is similar to `mkdirat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path at which to create the directory. - -### `__wasi_path_filestat_get()` - -Return the attributes of a file or directory. - -Note: This is similar to `stat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_path_filestat_set_times()` - -Adjust the timestamps of a file or directory. - -Note: This is similar to `utimensat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_path_link()` - -Create a hard link. - -Note: This is similar to `linkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags - - Flags determining the method of how the path is resolved. - -- const char \*old\_path and size\_t old\_path\_len - - The source path from which to link. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the hard link. - -### `__wasi_path_open()` - -Open a file or directory. - -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since -this is error-prone in multi-threaded contexts. The returned file -descriptor is guaranteed to be less than 231. - -Note: This is similar to `openat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) dirfd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The relative path of the file or directory to open, relative to - the [`dirfd`](#path_open.dirfd) directory. - -- [\_\_wasi\_oflags\_t](#oflags) o_flags - - The method by which to open the file. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The initial rights of the newly created file descriptor. The - implementation is allowed to return a file descriptor with fewer - rights than specified, if and only if those rights do not apply - to the type of file being opened. - - The *base* rights are rights that will apply to operations using - the file descriptor itself, while the *inheriting* rights are - rights that apply to file descriptors derived from it. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - The initial flags of the file descriptor. - -Outputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file that has been - opened. - -### `__wasi_path_readlink()` - -Read the contents of a symbolic link. - -Note: This is similar to `readlinkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path of the symbolic link from which to read. - -- char \*buf and size\_t buf\_len - - The buffer to which to write the contents of the symbolic link. - -Outputs: - -- size\_t bufused - - The number of bytes placed in the buffer. - -### `__wasi_path_remove_directory()` - -Remove a directory. - -Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. - -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a directory to remove. - -### `__wasi_path_rename()` - -Rename a file or directory. - -Note: This is similar to `renameat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- const char \*old\_path and size\_t old\_path\_len - - The source path of the file or directory to rename. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path to which to rename the file or directory. - -### `__wasi_path_symlink()` - -Create a symbolic link. - -Note: This is similar to `symlinkat` in POSIX. - -Inputs: - -- const char \*old\_path and size\_t old_path\_len - - The contents of the symbolic link. - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the symbolic link. - -### `__wasi_path_unlink_file()` - -Unlink a file. - -Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. - -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a file to unlink. - -### `__wasi_poll_oneoff()` - -Concurrently poll for the occurrence of a set of events. - -Inputs: - -- const [\_\_wasi\_subscription\_t](#subscription) \*in - - The events to which to subscribe. - -- [\_\_wasi\_event\_t](#event) \*out - - The events that have occurred. - -- size\_t nsubscriptions - - Both the number of subscriptions and events. - -Outputs: - -- size\_t nevents - - The number of events stored. - -### `__wasi_proc_exit()` - -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -Note: This is similar to `_Exit` in POSIX. - -Inputs: - -- [\_\_wasi\_exitcode\_t](#exitcode) rval - - The exit code returned by the process. - -Does not return. - -### `__wasi_proc_raise()` - -Send a signal to the process of the calling thread. - -Note: This is similar to `raise` in POSIX. - -Inputs: - -- [\_\_wasi\_signal\_t](#signal) sig - - The signal condition to trigger. - -### `__wasi_random_get()` - -Write high-quality random data into a buffer. - -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. - -This function may execute slowly, so when large mounts of random -data are required, it's advisable to use this function to seed a -pseudo-random number generator, rather than to provide the -random data directly. - -Inputs: - -- void \*buf and size\_t buf\_len - - The buffer to fill with random data. - -### `__wasi_sched_yield()` - -Temporarily yield execution of the calling thread. - -Note: This is similar to `sched_yield` in POSIX. - -### `__wasi_sock_recv()` - -Receive a message from a socket. - -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to receive data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len - - List of scatter/gather vectors to which to store data. - -- [\_\_wasi\_riflags\_t](#riflags) ri\_flags - - Message flags. - -Outputs: - -- size\_t ro\_datalen - - Number of bytes stored in [`ri_data`](#sock_recv.ri_data). - -- [\_\_wasi\_roflags\_t](#roflags) ro\_flags - - Message flags. - -### `__wasi_sock_send()` - -Send a message on a socket. - -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to send data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len - - List of scatter/gather vectors to which to retrieve data - -- [\_\_wasi\_siflags\_t](#siflags) si\_flags - - Message flags. - -Outputs: - -- size\_t so\_datalen - - Number of bytes transmitted. - -### `__wasi_sock_shutdown()` - -Shut down socket send and receive channels. - -Note: This is similar to `shutdown` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to shutdown channels. - -- [\_\_wasi\_sdflags\_t](#sdflags) how - - Which channels on the socket to shut down. - -## Types - -### `__wasi_advice_t` (`uint8_t`) - -File or memory access pattern advisory information. - -Used by [`__wasi_fd_advise()`](#fd_advise). - -Possible values: - -- **`__WASI_ADVICE_NORMAL`** - - The application has no advice to give on its behavior - with respect to the specified data. - -- **`__WASI_ADVICE_SEQUENTIAL`** - - The application expects to access the specified data - sequentially from lower offsets to higher offsets. - -- **`__WASI_ADVICE_RANDOM`** - - The application expects to access the specified data - in a random order. - -- **`__WASI_ADVICE_WILLNEED`** - - The application expects to access the specified data - in the near future. - -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - -### `__wasi_ciovec_t` (`struct`) - -A region of memory for scatter/gather writes. - -Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). - -Members: - -- const void \*buf and size\_t buf\_len - - The address and length of the buffer to be written. - -### `__wasi_clockid_t` (`uint32_t`) - -Identifiers for clocks. - -Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). - -Possible values: - -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - -- **`__WASI_CLOCK_MONOTONIC`** - - The store-wide monotonic clock, which is defined as a - clock measuring real time, whose value cannot be - adjusted and which cannot have negative clock jumps. - - The epoch of this clock is undefined. The absolute - time value of this clock therefore has no meaning. - -- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** - - The CPU-time clock associated with the current - process. - -- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** - - The CPU-time clock associated with the current thread. - -### `__wasi_device_t` (`uint64_t`) - -Identifier for a device containing a file system. Can be used -in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or -directory in the filesystem. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_dircookie_t` (`uint64_t`) - -A reference to the offset of a directory entry. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). - -Special values: - -- **`__WASI_DIRCOOKIE_START`** - - Permanent reference to the first directory entry - within a directory. - -### `__wasi_dirent_t` (`struct`) - -A directory entry. - -Members: - -- [\_\_wasi\_dircookie\_t](#dircookie) d\_next - - The offset of the next directory entry stored in this - directory. - -- [\_\_wasi\_inode\_t](#inode) d\_ino - - The serial number of the file referred to by this - directory entry. - -- uint32\_t d\_namlen - - The length of the name of the directory entry. - -- [\_\_wasi\_filetype\_t](#filetype) d\_type - - The type of the file referred to by this directory - entry. - -### `__wasi_errno_t` (`uint16_t`) - -Error codes returned by functions. - -Not all of these error codes are returned by the functions -provided by this API; some are used in higher-level library layers, -and others are provided merely for alignment with POSIX. - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_ESUCCESS`** - - No error occurred. System call completed successfully. - -- **`__WASI_E2BIG`** - - Argument list too long. - -- **`__WASI_EACCES`** - - Permission denied. - -- **`__WASI_EADDRINUSE`** - - Address in use. - -- **`__WASI_EADDRNOTAVAIL`** - - Address not available. - -- **`__WASI_EAFNOSUPPORT`** - - Address family not supported. - -- **`__WASI_EAGAIN`** - - Resource unavailable, or operation would block. - -- **`__WASI_EALREADY`** - - Connection already in progress. - -- **`__WASI_EBADF`** - - Bad file descriptor. - -- **`__WASI_EBADMSG`** - - Bad message. - -- **`__WASI_EBUSY`** - - Device or resource busy. - -- **`__WASI_ECANCELED`** - - Operation canceled. - -- **`__WASI_ECHILD`** - - No child processes. - -- **`__WASI_ECONNABORTED`** - - Connection aborted. - -- **`__WASI_ECONNREFUSED`** - - Connection refused. - -- **`__WASI_ECONNRESET`** - - Connection reset. - -- **`__WASI_EDEADLK`** - - Resource deadlock would occur. - -- **`__WASI_EDESTADDRREQ`** - - Destination address required. - -- **`__WASI_EDOM`** - - Mathematics argument out of domain of function. - -- **`__WASI_EDQUOT`** - - Reserved. - -- **`__WASI_EEXIST`** - - File exists. - -- **`__WASI_EFAULT`** - - Bad address. - -- **`__WASI_EFBIG`** - - File too large. - -- **`__WASI_EHOSTUNREACH`** - - Host is unreachable. - -- **`__WASI_EIDRM`** - - Identifier removed. - -- **`__WASI_EILSEQ`** - - Illegal byte sequence. - -- **`__WASI_EINPROGRESS`** - - Operation in progress. - -- **`__WASI_EINTR`** - - Interrupted function. - -- **`__WASI_EINVAL`** - - Invalid argument. - -- **`__WASI_EIO`** - - I/O error. - -- **`__WASI_EISCONN`** - - Socket is connected. - -- **`__WASI_EISDIR`** - - Is a directory. - -- **`__WASI_ELOOP`** - - Too many levels of symbolic links. - -- **`__WASI_EMFILE`** - - File descriptor value too large. - -- **`__WASI_EMLINK`** - - Too many links. - -- **`__WASI_EMSGSIZE`** - - Message too large. - -- **`__WASI_EMULTIHOP`** - - Reserved. - -- **`__WASI_ENAMETOOLONG`** - - Filename too long. - -- **`__WASI_ENETDOWN`** - - Network is down. - -- **`__WASI_ENETRESET`** - - Connection aborted by network. - -- **`__WASI_ENETUNREACH`** - - Network unreachable. - -- **`__WASI_ENFILE`** - - Too many files open in system. - -- **`__WASI_ENOBUFS`** - - No buffer space available. - -- **`__WASI_ENODEV`** - - No such device. - -- **`__WASI_ENOENT`** - - No such file or directory. - -- **`__WASI_ENOEXEC`** - - Executable file format error. - -- **`__WASI_ENOLCK`** - - No locks available. - -- **`__WASI_ENOLINK`** - - Reserved. - -- **`__WASI_ENOMEM`** - - Not enough space. - -- **`__WASI_ENOMSG`** - - No message of the desired type. - -- **`__WASI_ENOPROTOOPT`** - - Protocol not available. - -- **`__WASI_ENOSPC`** - - No space left on device. - -- **`__WASI_ENOSYS`** - - Function not supported. - -- **`__WASI_ENOTCONN`** - - The socket is not connected. - -- **`__WASI_ENOTDIR`** - - Not a directory or a symbolic link to a directory. - -- **`__WASI_ENOTEMPTY`** - - Directory not empty. - -- **`__WASI_ENOTRECOVERABLE`** - - State not recoverable. - -- **`__WASI_ENOTSOCK`** - - Not a socket. - -- **`__WASI_ENOTSUP`** - - Not supported, or operation not supported on socket. - -- **`__WASI_ENOTTY`** - - Inappropriate I/O control operation. - -- **`__WASI_ENXIO`** - - No such device or address. - -- **`__WASI_EOVERFLOW`** - - Value too large to be stored in data type. - -- **`__WASI_EOWNERDEAD`** - - Previous owner died. - -- **`__WASI_EPERM`** - - Operation not permitted. - -- **`__WASI_EPIPE`** - - Broken pipe. - -- **`__WASI_EPROTO`** - - Protocol error. - -- **`__WASI_EPROTONOSUPPORT`** - - Protocol not supported. - -- **`__WASI_EPROTOTYPE`** - - Protocol wrong type for socket. - -- **`__WASI_ERANGE`** - - Result too large. - -- **`__WASI_EROFS`** - - Read-only file system. - -- **`__WASI_ESPIPE`** - - Invalid seek. - -- **`__WASI_ESRCH`** - - No such process. - -- **`__WASI_ESTALE`** - - Reserved. - -- **`__WASI_ETIMEDOUT`** - - Connection timed out. - -- **`__WASI_ETXTBSY`** - - Text file busy. - -- **`__WASI_EXDEV`** - - Cross-device link. - -- **`__WASI_ENOTCAPABLE`** - - Extension: Capabilities insufficient. - -### `__wasi_event_t` (`struct`) - -An event that occurred. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that got attached to - [`__wasi_subscription_t::userdata`](#subscription.userdata). - -- [\_\_wasi\_errno\_t](#errno) error - - If non-zero, an error that occurred while processing - the subscription request. - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event that occurred. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_filesize\_t](#filesize) nbytes - - The number of bytes available for reading or writing. - - - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags - - The state of the file descriptor. - -### `__wasi_eventrwflags_t` (`uint16_t` bitfield) - -The state of the file descriptor subscribed to with -[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_EVENT_FD_READWRITE_HANGUP`** - - The peer of this socket has closed or disconnected. - -### `__wasi_eventtype_t` (`uint8_t`) - -Type of a subscription to an event or its occurrence. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_EVENTTYPE_CLOCK`** - - The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) - has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -- **`__WASI_EVENTTYPE_FD_READ`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - data available for reading. This event always triggers - for regular files. - -- **`__WASI_EVENTTYPE_FD_WRITE`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - capacity available for writing. This event always - triggers for regular files. - -### `__wasi_exitcode_t` (`uint32_t`) - -Exit code generated by a process when exiting. - -Used by [`__wasi_proc_exit()`](#proc_exit). - -### `__wasi_fd_t` (`uint32_t`) - -A file descriptor number. - -Used by many functions in this API. - -As in POSIX, three file descriptor numbers are provided to instances -on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, -and `STDERR_FILENO`). - -Other than these, WASI implementations are not required to allocate -new file descriptors in ascending order. - -### `__wasi_fdflags_t` (`uint16_t` bitfield) - -File descriptor flags. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_FDFLAG_APPEND`** - - Append mode: Data written to the file is always - appended to the file's end. - -- **`__WASI_FDFLAG_DSYNC`** - - Write according to synchronized I/O data integrity - completion. Only the data stored in the file is - synchronized. - -- **`__WASI_FDFLAG_NONBLOCK`** - - Non-blocking mode. - -- **`__WASI_FDFLAG_RSYNC`** - - Synchronized read I/O operations. - -- **`__WASI_FDFLAG_SYNC`** - - Write according to synchronized I/O file integrity completion. - In addition to synchronizing the data stored in the file, the - implementation may also synchronously update the file's metadata. - -### `__wasi_fdstat_t` (`struct`) - -File descriptor attributes. - -Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). - -Members: - -- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype - - File type. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - File descriptor flags. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base - - Rights that apply to this file descriptor. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - Maximum set of rights that may be installed on new - file descriptors that are created through this file - descriptor, e.g., through [`__wasi_path_open()`](#path_open). - -### `__wasi_filedelta_t` (`int64_t`) - -Relative offset within a file. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -### `__wasi_filesize_t` (`uint64_t`) - -Non-negative file size or length of a region within a file. - -Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -### `__wasi_filestat_t` (`struct`) - -File attributes. - -Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). - -Members: - -- [\_\_wasi\_device\_t](#device) st\_dev - - Device ID of device containing the file. - -- [\_\_wasi\_inode\_t](#inode) st\_ino - - File serial number. - -- [\_\_wasi\_filetype\_t](#filetype) st\_filetype - - File type. - -- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink - - Number of hard links to the file. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - For regular files, the file size in bytes. For - symbolic links, the length in bytes of the pathname - contained in the symbolic link. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - Last data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - Last data modification timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim - - Last file status change timestamp. - -### `__wasi_filetype_t` (`uint8_t`) - -The type of a file descriptor or file. - -Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). - -Possible values: - -- **`__WASI_FILETYPE_UNKNOWN`** - - The type of the file descriptor or file is unknown or - is different from any of the other types specified. - -- **`__WASI_FILETYPE_BLOCK_DEVICE`** - - The file descriptor or file refers to a block device - inode. - -- **`__WASI_FILETYPE_CHARACTER_DEVICE`** - - The file descriptor or file refers to a character - device inode. - -- **`__WASI_FILETYPE_DIRECTORY`** - - The file descriptor or file refers to a directory - inode. - -- **`__WASI_FILETYPE_REGULAR_FILE`** - - The file descriptor or file refers to a regular file - inode. - -- **`__WASI_FILETYPE_SOCKET_DGRAM`** - - The file descriptor or file refers to a datagram - socket. - -- **`__WASI_FILETYPE_SOCKET_STREAM`** - - The file descriptor or file refers to a byte-stream - socket. - -- **`__WASI_FILETYPE_SYMBOLIC_LINK`** - - The file refers to a symbolic link inode. - -### `__wasi_fstflags_t` (`uint16_t` bitfield) - -Which file time attributes to adjust. - -Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -Possible values: - -- **`__WASI_FILESTAT_SET_ATIM`** - - Adjust the last data access timestamp to the value - stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). - -- **`__WASI_FILESTAT_SET_ATIM_NOW`** - - Adjust the last data access timestamp to the time - of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -- **`__WASI_FILESTAT_SET_MTIM`** - - Adjust the last data modification timestamp to the - value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). - -- **`__WASI_FILESTAT_SET_MTIM_NOW`** - - Adjust the last data modification timestamp to the - time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -### `__wasi_inode_t` (`uint64_t`) - -File serial number that is unique within its file system. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). - -### `__wasi_iovec_t` (`struct`) - -A region of memory for scatter/gather reads. - -Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). - -Members: - -- void \*buf and size\_t buf\_len - - The address and length of the buffer to be filled. - -### `__wasi_linkcount_t` (`uint32_t`) - -Number of hard links to an inode. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_lookupflags_t` (`uint32_t` bitfield) - -Flags determining the method of how paths are resolved. - -Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** - - As long as the resolved path corresponds to a symbolic - link, it is expanded. - -### `__wasi_oflags_t` (`uint16_t` bitfield) - -Open flags used by [`__wasi_path_open()`](#path_open). - -Used by [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_O_CREAT`** - - Create file if it does not exist. - -- **`__WASI_O_DIRECTORY`** - - Fail if not a directory. - -- **`__WASI_O_EXCL`** - - Fail if file already exists. - -- **`__WASI_O_TRUNC`** - - Truncate file to size 0. - -### `__wasi_riflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_PEEK`** - - Returns the message without removing it from the - socket's receive queue. - -- **`__WASI_SOCK_RECV_WAITALL`** - - On byte-stream sockets, block until the full amount - of data can be returned. - -### `__wasi_rights_t` (`uint64_t` bitfield) - -File descriptor rights, determining which actions may be -performed. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_RIGHT_FD_DATASYNC`** - - The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_READ`** - - The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke - [`__wasi_fd_pread()`](#fd_pread). - -- **`__WASI_RIGHT_FD_SEEK`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies - [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). - -- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** - - The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). - -- **`__WASI_RIGHT_FD_SYNC`** - - The right to invoke [`__wasi_fd_sync()`](#fd_sync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and - [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_TELL`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the - file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with - offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). - -- **`__WASI_RIGHT_FD_WRITE`** - - The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to - invoke [`__wasi_fd_pwrite()`](#fd_pwrite). - -- **`__WASI_RIGHT_FD_ADVISE`** - - The right to invoke [`__wasi_fd_advise()`](#fd_advise). - -- **`__WASI_RIGHT_FD_ALLOCATE`** - - The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). - -- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** - - The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). - -- **`__WASI_RIGHT_PATH_CREATE_FILE`** - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke - [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). - -- **`__WASI_RIGHT_PATH_LINK_SOURCE`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_LINK_TARGET`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_OPEN`** - - The right to invoke [`__wasi_path_open()`](#path_open). - -- **`__WASI_RIGHT_FD_READDIR`** - - The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). - -- **`__WASI_RIGHT_PATH_READLINK`** - - The right to invoke [`__wasi_path_readlink()`](#path_readlink). - -- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_RENAME_TARGET`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_FILESTAT_GET`** - - The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** - - The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -- **`__WASI_RIGHT_FD_FILESTAT_GET`** - - The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** - - The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). - -- **`__WASI_RIGHT_PATH_SYMLINK`** - - The right to invoke [`__wasi_path_symlink()`](#path_symlink). - -- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** - - The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). - -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - -- **`__WASI_RIGHT_POLL_FD_READWRITE`** - - If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). - - If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -- **`__WASI_RIGHT_SOCK_SHUTDOWN`** - - The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). - -### `__wasi_roflags_t` (`uint16_t` bitfield) - -Flags returned by [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** - - Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been - truncated. - -### `__wasi_sdflags_t` (`uint8_t` bitfield) - -Which channels on a socket to shut down. - -Used by [`__wasi_sock_shutdown()`](#sock_shutdown). - -Possible values: - -- **`__WASI_SHUT_RD`** - - Disables further receive operations. - -- **`__WASI_SHUT_WR`** - - Disables further send operations. - -### `__wasi_siflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Used by [`__wasi_sock_send()`](#sock_send). - -### `__wasi_signal_t` (`uint8_t`) - -Signal condition. - -Used by [`__wasi_proc_raise()`](#proc_raise). - -Possible values: - -- **`__WASI_SIGHUP`** - - Hangup. - - Action: Terminates the process. - -- **`__WASI_SIGINT`** - - Terminate interrupt signal. - - Action: Terminates the process. - -- **`__WASI_SIGQUIT`** - - Terminal quit signal. - - Action: Terminates the process. - -- **`__WASI_SIGILL`** - - Illegal instruction. - - Action: Terminates the process. - -- **`__WASI_SIGTRAP`** - - Trace/breakpoint trap. - - Action: Terminates the process. - -- **`__WASI_SIGABRT`** - - Process abort signal. - - Action: Terminates the process. - -- **`__WASI_SIGBUS`** - - Access to an undefined portion of a memory object. - - Action: Terminates the process. - -- **`__WASI_SIGFPE`** - - Erroneous arithmetic operation. - - Action: Terminates the process. - -- **`__WASI_SIGKILL`** - - Kill. - - Action: Terminates the process. - -- **`__WASI_SIGUSR1`** - - User-defined signal 1. - - Action: Terminates the process. - -- **`__WASI_SIGSEGV`** - - Invalid memory reference. - - Action: Terminates the process. - -- **`__WASI_SIGUSR2`** - - User-defined signal 2. - - Action: Terminates the process. - -- **`__WASI_SIGPIPE`** - - Write on a pipe with no one to read it. - - Action: Ignored. - -- **`__WASI_SIGALRM`** - - Alarm clock. - - Action: Terminates the process. - -- **`__WASI_SIGTERM`** - - Termination signal. - - Action: Terminates the process. - -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** - - Continue executing, if stopped. - - Action: Continues executing, if stopped. - -- **`__WASI_SIGSTOP`** - - Stop executing. - - Action: Stops executing. - -- **`__WASI_SIGTSTP`** - - Terminal stop signal. - - Action: Stops executing. - -- **`__WASI_SIGTTIN`** - - Background process attempting read. - - Action: Stops executing. - -- **`__WASI_SIGTTOU`** - - Background process attempting write. - - Action: Stops executing. - -- **`__WASI_SIGURG`** - - High bandwidth data is available at a socket. - - Action: Ignored. - -- **`__WASI_SIGXCPU`** - - CPU time limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGXFSZ`** - - File size limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGVTALRM`** - - Virtual timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGPROF`** - - Profiling timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGWINCH`** - - Window changed. - - Action: Ignored. - -- **`__WASI_SIGPOLL`** - - I/O possible. - - Action: Terminates the process. - -- **`__WASI_SIGPWR`** - - Power failure. - - Action: Terminates the process. - -- **`__WASI_SIGSYS`** - - Bad system call. - - Action: Terminates the process. - -### `__wasi_subclockflags_t` (`uint16_t` bitfield) - -Flags determining how to interpret the timestamp provided in -[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -Used by [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** - - If set, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp - of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - - If clear, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current - time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - -### `__wasi_subscription_t` (`struct`) - -Subscription to an event. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that is attached to the subscription in the - implementation and returned through - [`__wasi_event_t::userdata`](#event.userdata). - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event to which to subscribe. - -- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): - - - **`u.clock`** - - - [\_\_wasi\_userdata\_t](#userdata) identifier - - The user-defined unique identifier of the clock. - - - [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock against which to compare the timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) timeout - - The absolute or relative timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) precision - - The amount of time that the implementation may wait additionally - to coalesce with other events. - - - [\_\_wasi\_subclockflags\_t](#subclockflags) flags - - Flags specifying whether the timeout is absolute or relative. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor on which to wait for it to become ready - for reading or writing. - -### `__wasi_timestamp_t` (`uint64_t`) - -Timestamp in nanoseconds. - -Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -### `__wasi_userdata_t` (`uint64_t`) - -User-provided value that may be attached to objects that is -retained when extracted from the implementation. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -### `__wasi_whence_t` (`uint8_t`) - -The position relative to which to set the offset of the file descriptor. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -Possible values: - -- **`__WASI_WHENCE_CUR`** - - Seek relative to current position. - -- **`__WASI_WHENCE_END`** - - Seek relative to end-of-file. - -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md new file mode 100644 index 000000000..0688fe7cb --- /dev/null +++ b/proposals/clocks/phases/snapshot/docs.md @@ -0,0 +1,1790 @@ +# Types +## `size`: `u32` + +## `filesize`: `u64` +Non-negative file size or length of a region within a file. + +## `timestamp`: `u64` +Timestamp in nanoseconds. + +## `clockid`: Enum(`u32`) +Identifiers for clocks. + +### Variants +- `realtime` +The clock measuring real time. Time value zero corresponds with +1970-01-01T00:00:00Z. + +- `monotonic` +The store-wide monotonic clock, which is defined as a clock measuring +real time, whose value cannot be adjusted and which cannot have negative +clock jumps. The epoch of this clock is undefined. The absolute time +value of this clock therefore has no meaning. + +- `process_cputime_id` +The CPU-time clock associated with the current process. + +- `thread_cputime_id` +The CPU-time clock associated with the current thread. + +## `errno`: Enum(`u16`) +Error codes returned by functions. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX. + +### Variants +- `success` +No error occurred. System call completed successfully. + +- `2big` +Argument list too long. + +- `acces` +Permission denied. + +- `addrinuse` +Address in use. + +- `addrnotavail` +Address not available. + +- `afnosupport` +Address family not supported. + +- `again` +Resource unavailable, or operation would block. + +- `already` +Connection already in progress. + +- `badf` +Bad file descriptor. + +- `badmsg` +Bad message. + +- `busy` +Device or resource busy. + +- `canceled` +Operation canceled. + +- `child` +No child processes. + +- `connaborted` +Connection aborted. + +- `connrefused` +Connection refused. + +- `connreset` +Connection reset. + +- `deadlk` +Resource deadlock would occur. + +- `destaddrreq` +Destination address required. + +- `dom` +Mathematics argument out of domain of function. + +- `dquot` +Reserved. + +- `exist` +File exists. + +- `fault` +Bad address. + +- `fbig` +File too large. + +- `hostunreach` +Host is unreachable. + +- `idrm` +Identifier removed. + +- `ilseq` +Illegal byte sequence. + +- `inprogress` +Operation in progress. + +- `intr` +Interrupted function. + +- `inval` +Invalid argument. + +- `io` +I/O error. + +- `isconn` +Socket is connected. + +- `isdir` +Is a directory. + +- `loop` +Too many levels of symbolic links. + +- `mfile` +File descriptor value too large. + +- `mlink` +Too many links. + +- `msgsize` +Message too large. + +- `multihop` +Reserved. + +- `nametoolong` +Filename too long. + +- `netdown` +Network is down. + +- `netreset` +Connection aborted by network. + +- `netunreach` +Network unreachable. + +- `nfile` +Too many files open in system. + +- `nobufs` +No buffer space available. + +- `nodev` +No such device. + +- `noent` +No such file or directory. + +- `noexec` +Executable file format error. + +- `nolck` +No locks available. + +- `nolink` +Reserved. + +- `nomem` +Not enough space. + +- `nomsg` +No message of the desired type. + +- `noprotoopt` +Protocol not available. + +- `nospc` +No space left on device. + +- `nosys` +Function not supported. + +- `notconn` +The socket is not connected. + +- `notdir` +Not a directory or a symbolic link to a directory. + +- `notempty` +Directory not empty. + +- `notrecoverable` +State not recoverable. + +- `notsock` +Not a socket. + +- `notsup` +Not supported, or operation not supported on socket. + +- `notty` +Inappropriate I/O control operation. + +- `nxio` +No such device or address. + +- `overflow` +Value too large to be stored in data type. + +- `ownerdead` +Previous owner died. + +- `perm` +Operation not permitted. + +- `pipe` +Broken pipe. + +- `proto` +Protocol error. + +- `protonosupport` +Protocol not supported. + +- `prototype` +Protocol wrong type for socket. + +- `range` +Result too large. + +- `rofs` +Read-only file system. + +- `spipe` +Invalid seek. + +- `srch` +No such process. + +- `stale` +Reserved. + +- `timedout` +Connection timed out. + +- `txtbsy` +Text file busy. + +- `xdev` +Cross-device link. + +- `notcapable` +Extension: Capabilities insufficient. + +## `rights`: Flags(`u64`) +File descriptor rights, determining which actions may be performed. + +### Flags +- `fd_datasync` +The right to invoke [`fd_datasync`](#fd_datasync). +If [`path_open`](#path_open) is set, includes the right to invoke +[`path_open`](#path_open) with `fdflag::dsync`. + +- `fd_read` +The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). + +- `fd_seek` +The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). + +- `fd_fdstat_set_flags` +The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). + +- `fd_sync` +The right to invoke [`fd_sync`](#fd_sync). +If [`path_open`](#path_open) is set, includes the right to invoke +[`path_open`](#path_open) with `fdflag::rsync` and `fdflag::dsync`. + +- `fd_tell` +The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset +remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +invoke [`fd_tell`](#fd_tell). + +- `fd_write` +The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). + +- `fd_advise` +The right to invoke [`fd_advise`](#fd_advise). + +- `fd_allocate` +The right to invoke [`fd_allocate`](#fd_allocate). + +- `path_create_directory` +The right to invoke [`path_create_directory`](#path_create_directory). + +- `path_create_file` +If [`path_open`](#path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). + +- `path_link_source` +The right to invoke [`path_link`](#path_link) with the file descriptor as the +source directory. + +- `path_link_target` +The right to invoke [`path_link`](#path_link) with the file descriptor as the +target directory. + +- `path_open` +The right to invoke [`path_open`](#path_open). + +- `fd_readdir` +The right to invoke [`fd_readdir`](#fd_readdir). + +- `path_readlink` +The right to invoke [`path_readlink`](#path_readlink). + +- `path_rename_source` +The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. + +- `path_rename_target` +The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. + +- `path_filestat_get` +The right to invoke [`path_filestat_get`](#path_filestat_get). + +- `path_filestat_set_size` +The right to change a file's size (there is no `path_filestat_set_size`). +If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). + +- `path_filestat_set_times` +The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). + +- `fd_filestat_get` +The right to invoke [`fd_filestat_get`](#fd_filestat_get). + +- `fd_filestat_set_size` +The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). + +- `fd_filestat_set_times` +The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). + +- `path_symlink` +The right to invoke [`path_symlink`](#path_symlink). + +- `path_remove_directory` +The right to invoke [`path_remove_directory`](#path_remove_directory). + +- `path_unlink_file` +The right to invoke [`path_unlink_file`](#path_unlink_file). + +- `poll_fd_readwrite` +If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). +If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). + +- `sock_shutdown` +The right to invoke [`sock_shutdown`](#sock_shutdown). + +## `fd`: `u32` +A file descriptor index. + +## `iovec`: Struct +A region of memory for scatter/gather reads. + +### Struct members +- `buf`: `Pointer` +The address of the buffer to be filled. + +- `buf_len`: [`size`](#size) +The length of the buffer to be filled. + +## `ciovec`: Struct +A region of memory for scatter/gather writes. + +### Struct members +- `buf`: `ConstPointer` +The address of the buffer to be written. + +- `buf_len`: [`size`](#size) +The length of the buffer to be written. + +## `iovec_array`: `Array` + +## `ciovec_array`: `Array` + +## `filedelta`: `s64` +Relative offset within a file. + +## `whence`: Enum(`u8`) +The position relative to which to set the offset of the file descriptor. + +### Variants +- `set` +Seek relative to start-of-file. + +- `cur` +Seek relative to current position. + +- `end` +Seek relative to end-of-file. + +## `dircookie`: `u64` +A reference to the offset of a directory entry. + +The value 0 signifies the start of the directory. + +## `dirnamlen`: `u32` +The type for the $d_namlen field of $dirent. + +## `inode`: `u64` +File serial number that is unique within its file system. + +## `filetype`: Enum(`u8`) +The type of a file descriptor or file. + +### Variants +- `unknown` +The type of the file descriptor or file is unknown or is different from any of the other types specified. + +- `block_device` +The file descriptor or file refers to a block device inode. + +- `character_device` +The file descriptor or file refers to a character device inode. + +- `directory` +The file descriptor or file refers to a directory inode. + +- `regular_file` +The file descriptor or file refers to a regular file inode. + +- `socket_dgram` +The file descriptor or file refers to a datagram socket. + +- `socket_stream` +The file descriptor or file refers to a byte-stream socket. + +- `symbolic_link` +The file refers to a symbolic link inode. + +## `dirent`: Struct +A directory entry. + +### Struct members +- `d_next`: [`dircookie`](#dircookie) +The offset of the next directory entry stored in this directory. + +- `d_ino`: [`inode`](#inode) +The serial number of the file referred to by this directory entry. + +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. + +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. + +## `advice`: Enum(`u8`) +File or memory access pattern advisory information. + +### Variants +- `normal` +The application has no advice to give on its behavior with respect to the specified data. + +- `sequential` +The application expects to access the specified data sequentially from lower offsets to higher offsets. + +- `random` +The application expects to access the specified data in a random order. + +- `willneed` +The application expects to access the specified data in the near future. + +- `dontneed` +The application expects that it will not access the specified data in the near future. + +- `noreuse` +The application expects to access the specified data once and then not reuse it thereafter. + +## `fdflags`: Flags(`u16`) +File descriptor flags. + +### Flags +- `append` +Append mode: Data written to the file is always appended to the file's end. + +- `dsync` +Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + +- `nonblock` +Non-blocking mode. + +- `rsync` +Synchronized read I/O operations. + +- `sync` +Write according to synchronized I/O file integrity completion. In +addition to synchronizing the data stored in the file, the implementation +may also synchronously update the file's metadata. + +## `fdstat`: Struct +File descriptor attributes. + +### Struct members +- `fs_filetype`: [`filetype`](#filetype) +File type. + +- `fs_flags`: [`fdflags`](#fdflags) +File descriptor flags. + +- `fs_rights_base`: [`rights`](#rights) +Rights that apply to this file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) +Maximum set of rights that may be installed on new file descriptors that +are created through this file descriptor, e.g., through [`path_open`](#path_open). + +## `device`: `u64` +Identifier for a device containing a file system. Can be used in combination +with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. + +## `fstflags`: Flags(`u16`) +Which file time attributes to adjust. + +### Flags +- `atim` +Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + +- `atim_now` +Adjust the last data access timestamp to the time of clock `clock::realtime`. + +- `mtim` +Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + +- `mtim_now` +Adjust the last data modification timestamp to the time of clock `clock::realtime`. + +## `lookupflags`: Flags(`u32`) +Flags determining the method of how paths are resolved. + +### Flags +- `symlink_follow` +As long as the resolved path corresponds to a symbolic link, it is expanded. + +## `oflags`: Flags(`u16`) +Open flags used by [`path_open`](#path_open). + +### Flags +- `creat` +Create file if it does not exist. + +- `directory` +Fail if not a directory. + +- `excl` +Fail if file already exists. + +- `trunc` +Truncate file to size 0. + +## `linkcount`: `u64` +Number of hard links to an inode. + +## `filestat`: Struct +File attributes. + +### Struct members +- `dev`: [`device`](#device) +Device ID of device containing the file. + +- `ino`: [`inode`](#inode) +File serial number. + +- `filetype`: [`filetype`](#filetype) +File type. + +- `nlink`: [`linkcount`](#linkcount) +Number of hard links to the file. + +- `size`: [`filesize`](#filesize) +For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + +- `atim`: [`timestamp`](#timestamp) +Last data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +Last data modification timestamp. + +- `ctim`: [`timestamp`](#timestamp) +Last file status change timestamp. + +## `userdata`: `u64` +User-provided value that may be attached to objects that is retained when +extracted from the implementation. + +## `eventtype`: Enum(`u8`) +Type of a subscription to an event or its occurrence. + +### Variants +- `clock` +The time value of clock `subscription::u.clock.clock_id` has +reached timestamp `subscription::u.clock.timeout`. + +- `fd_read` +File descriptor `subscription::u.fd_readwrite.fd` has data +available for reading. This event always triggers for regular files. + +- `fd_write` +File descriptor `subscription::u.fd_readwrite.fd` has capacity +available for writing. This event always triggers for regular files. + +## `eventrwflags`: Flags(`u16`) +The state of the file descriptor subscribed to with +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Flags +- `fd_readwrite_hangup` +The peer of this socket has closed or disconnected. + +## `event_fd_readwrite`: Struct +The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `nbytes`: [`filesize`](#filesize) +The number of bytes available for reading or writing. + +- `flags`: [`eventrwflags`](#eventrwflags) +The state of the file descriptor. + +## `event_u`: Union +The contents of an $event. + +### Union variants +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `event`: Struct +An event that occurred. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). + +- `error`: [`errno`](#errno) +If non-zero, an error that occurred while processing the subscription request. + +- `type`: [`eventtype`](#eventtype) +The type of the event that occurred. + +- `u`: [`event_u`](#event_u) +The contents of the event. + +## `subclockflags`: Flags(`u16`) +Flags determining how to interpret the timestamp provided in +`subscription::u.clock.timeout.` + +### Flags +- `subscription_clock_abstime` +If set, treat the timestamp provided in +`subscription::u.clock.timeout` as an absolute timestamp of clock +`subscription::u.clock.clock_id.` If clear, treat the timestamp +provided in `subscription::u.clock.timeout` relative to the +current time value of clock `subscription::u.clock.clock_id.` + +## `subscription_clock`: Struct +The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). + +### Struct members +- `id`: [`clockid`](#clockid) +The clock against which to compare the timestamp. + +- `timeout`: [`timestamp`](#timestamp) +The absolute or relative timestamp. + +- `precision`: [`timestamp`](#timestamp) +The amount of time that the implementation may wait additionally +to coalesce with other events. + +- `flags`: [`subclockflags`](#subclockflags) +Flags specifying whether the timeout is absolute or relative + +## `subscription_fd_readwrite`: Struct +The contents of a $subscription when type is type is +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `file_descriptor`: [`fd`](#fd) +The file descriptor on which to wait for it to become ready for reading or writing. + +## `subscription_u`: Union +The contents of a $subscription. + +### Union variants +- `clock`: [`subscription_clock`](#subscription_clock) +When type is [`eventtype::clock`](#eventtype.clock): + +- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `subscription`: Struct +Subscription to an event. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that is attached to the subscription in the +implementation and returned through [`event::userdata`](#event.userdata). + +- `type`: [`eventtype`](#eventtype) +The type of the event to which to subscribe. + +- `u`: [`subscription_u`](#subscription_u) +The contents of the subscription. + +## `exitcode`: `u32` +Exit code generated by a process when exiting. + +## `signal`: Enum(`u8`) +Signal condition. + +### Variants +- `none` +No signal. Note that POSIX has special semantics for `kill(pid, 0)`, +so this value is reserved. + +- `hup` +Hangup. +Action: Terminates the process. + +- `int` +Terminate interrupt signal. +Action: Terminates the process. + +- `quit` +Terminal quit signal. +Action: Terminates the process. + +- `ill` +Illegal instruction. +Action: Terminates the process. + +- `trap` +Trace/breakpoint trap. +Action: Terminates the process. + +- `abrt` +Process abort signal. +Action: Terminates the process. + +- `bus` +Access to an undefined portion of a memory object. +Action: Terminates the process. + +- `fpe` +Erroneous arithmetic operation. +Action: Terminates the process. + +- `kill` +Kill. +Action: Terminates the process. + +- `usr1` +User-defined signal 1. +Action: Terminates the process. + +- `segv` +Invalid memory reference. +Action: Terminates the process. + +- `usr2` +User-defined signal 2. +Action: Terminates the process. + +- `pipe` +Write on a pipe with no one to read it. +Action: Ignored. + +- `alrm` +Alarm clock. +Action: Terminates the process. + +- `term` +Termination signal. +Action: Terminates the process. + +- `chld` +Child process terminated, stopped, or continued. +Action: Ignored. + +- `cont` +Continue executing, if stopped. +Action: Continues executing, if stopped. + +- `stop` +Stop executing. +Action: Stops executing. + +- `tstp` +Terminal stop signal. +Action: Stops executing. + +- `ttin` +Background process attempting read. +Action: Stops executing. + +- `ttou` +Background process attempting write. +Action: Stops executing. + +- `urg` +High bandwidth data is available at a socket. +Action: Ignored. + +- `xcpu` +CPU time limit exceeded. +Action: Terminates the process. + +- `xfsz` +File size limit exceeded. +Action: Terminates the process. + +- `vtalrm` +Virtual timer expired. +Action: Terminates the process. + +- `prof` +Profiling timer expired. +Action: Terminates the process. + +- `winch` +Window changed. +Action: Ignored. + +- `poll` +I/O possible. +Action: Terminates the process. + +- `pwr` +Power failure. +Action: Terminates the process. + +- `sys` +Bad system call. +Action: Terminates the process. + +## `riflags`: Flags(`u16`) +Flags provided to [`sock_recv`](#sock_recv). + +### Flags +- `recv_peek` +Returns the message without removing it from the socket's receive queue. + +- `recv_waitall` +On byte-stream sockets, block until the full amount of data can be returned. + +## `roflags`: Flags(`u16`) +Flags returned by [`sock_recv`](#sock_recv). + +### Flags +- `recv_data_truncated` +Returned by [`sock_recv`](#sock_recv): Message data has been truncated. + +## `siflags`: `u16` +Flags provided to [`sock_send`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +## `sdflags`: Flags(`u8`) +Which channels on a socket to shut down. + +### Flags +- `rd` +Disables further receive operations. + +- `wr` +Disables further send operations. + +## `preopentype`: Enum(`u8`) +Identifiers for preopened capabilities. + +### Variants +- `dir` +A pre-opened directory. + +## `prestat_dir`: Struct +The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). + +### Struct members +- `pr_name_len`: [`size`](#size) +The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). + +## `prestat_u`: Union +The contents of an $prestat. + +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) +When type is [`preopentype::dir`](#preopentype.dir): + +## `prestat`: Struct +Information about a pre-opened capability. + +### Struct members +- `pr_type`: [`preopentype`](#preopentype) +The type of the pre-opened capability. + +- `u`: [`prestat_u`](#prestat_u) +The contents of the information. + +# Modules +## wasi_snapshot_preview1 +### Imports +#### Memory +### Functions + +--- + +#### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` +Read command-line argument data. +The size of the array should match that returned by `wasi_args_sizes_get()` + +##### Params +- `argv`: `Pointer>` + +- `argv_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `args_sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + + +--- + +#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` +Read environment variable data. +The sizes of the buffers should match that returned by `environ.sizes_get()`. + +##### Params +- `environ`: `Pointer>` + +- `environ_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `environ_sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + + +--- + +#### `clock_res_get(id: clockid) -> (errno, timestamp)` +Return the resolution of a clock. +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Note: This is similar to `clock_getres` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the resolution. + +##### Results +- `error`: [`errno`](#errno) + +- `resolution`: [`timestamp`](#timestamp) +The resolution of the clock. + + +--- + +#### `clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +Return the time value of a clock. +Note: This is similar to `clock_gettime` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the time. + +- `precision`: [`timestamp`](#timestamp) +The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + +##### Results +- `error`: [`errno`](#errno) + +- `time`: [`timestamp`](#timestamp) +The time value of the clock. + + +--- + +#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +Provide file advisory information on a file descriptor. +Note: This is similar to `posix_fadvise` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset within the file to which the advisory applies. + +- `len`: [`filesize`](#filesize) +The length of the region to which the advisory applies. + +- `advice`: [`advice`](#advice) +The advice. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno` +Force the allocation of space in a file. +Note: This is similar to `posix_fallocate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset at which to start the allocation. + +- `len`: [`filesize`](#filesize) +The length of the area that is allocated. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_close(fd: fd) -> errno` +Close a file descriptor. +Note: This is similar to `close` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_datasync(fd: fd) -> errno` +Synchronize the data of a file to disk. +Note: This is similar to `fdatasync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_fdstat_get(fd: fd) -> (errno, fdstat)` +Get the attributes of a file descriptor. +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `stat`: [`fdstat`](#fdstat) +The buffer where the file descriptor's attributes are stored. + + +--- + +#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +Adjust the flags associated with a file descriptor. +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`fdflags`](#fdflags) +The desired values of the file descriptor flags. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +Adjust the rights associated with a file descriptor. +This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + +##### Params +- `fd`: [`fd`](#fd) + +- `fs_rights_base`: [`rights`](#rights) +The desired rights of the file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_filestat_get(fd: fd) -> (errno, filestat)` +Return the attributes of an open file. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `fd_filestat_set_size(fd: fd, size: filesize) -> errno` +Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. +Note: This is similar to `ftruncate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `size`: [`filesize`](#filesize) +The desired file size. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of an open file or directory. +Note: This is similar to `futimens` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +Read from a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `preadv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors in which to store data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to read. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `fd_prestat_get(fd: fd) -> (errno, prestat)` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`prestat`](#prestat) +The buffer where the description is stored. + + +--- + +#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `Pointer` +A buffer into which to write the preopened directory name. + +- `path_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +Write to a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `pwritev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to write. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `fd_read(fd: fd, iovs: iovec_array) -> (errno, size)` +Read from a file descriptor. +Note: This is similar to `readv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +Read directory entries from a directory. +When successful, the contents of the output buffer consist of a sequence of +directory entries. Each directory entry consists of a dirent_t object, +followed by dirent_t::d_namlen bytes holding the name of the directory +entry. +This function fills the output buffer as much as possible, potentially +truncating the last directory entry. This allows the caller to grow its +read buffer size in case it's too small to fit a single large directory +entry, or skip the oversized directory entry. + +##### Params +- `fd`: [`fd`](#fd) + +- `buf`: `Pointer` +The buffer where directory entries are stored + +- `buf_len`: [`size`](#size) + +- `cookie`: [`dircookie`](#dircookie) +The location within the directory to start reading + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + + +--- + +#### `fd_renumber(fd: fd, to: fd) -> errno` +Atomically replace a file descriptor by renumbering another file descriptor. +Due to the strong focus on thread safety, this environment does not provide +a mechanism to duplicate or renumber a file descriptor to an arbitrary +number, like `dup2()`. This would be prone to race conditions, as an actual +file descriptor with the same number could be allocated by a different +thread at the same time. +This function provides a way to atomically renumber file descriptors, which +would disappear if `dup2()` were to be removed entirely. + +##### Params +- `fd`: [`fd`](#fd) + +- `to`: [`fd`](#fd) +The file descriptor to overwrite. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +Move the offset of a file descriptor. +Note: This is similar to `lseek` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filedelta`](#filedelta) +The number of bytes to move. + +- `whence`: [`whence`](#whence) +The base from which the offset is relative. + +##### Results +- `error`: [`errno`](#errno) + +- `newoffset`: [`filesize`](#filesize) +The new offset of the file descriptor, relative to the start of the file. + + +--- + +#### `fd_sync(fd: fd) -> errno` +Synchronize the data and metadata of a file to disk. +Note: This is similar to `fsync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_tell(fd: fd) -> (errno, filesize)` +Return the current offset of a file descriptor. +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `offset`: [`filesize`](#filesize) +The current offset of the file descriptor, relative to the start of the file. + + +--- + +#### `fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)` +Write to a file descriptor. +Note: This is similar to `writev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `path_create_directory(fd: fd, path: string) -> errno` +Create a directory. +Note: This is similar to `mkdirat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path at which to create the directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +Return the attributes of a file or directory. +Note: This is similar to `stat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to inspect. + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of a file or directory. +Note: This is similar to `utimensat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to operate on. + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +Create a hard link. +Note: This is similar to `linkat` in POSIX. + +##### Params +- `old_fd`: [`fd`](#fd) + +- `old_flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `old_path`: `string` +The source path from which to link. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path at which to create the hard link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)` +Open a file or directory. +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since this +is error-prone in multi-threaded contexts. The returned file descriptor is +guaranteed to be less than 2**31. +Note: This is similar to `openat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `dirflags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The relative path of the file or directory to open, relative to the +`dirfd` directory. + +- `oflags`: [`oflags`](#oflags) +The method by which to open the file. + +- `fs_rights_base`: [`rights`](#rights) +The initial rights of the newly created file descriptor. The +implementation is allowed to return a file descriptor with fewer rights +than specified, if and only if those rights do not apply to the type of +file being opened. +The *base* rights are rights that will apply to operations using the file +descriptor itself, while the *inheriting* rights are rights that apply to +file descriptors derived from it. + +- `fs_rights_inherting`: [`rights`](#rights) + +- `fdflags`: [`fdflags`](#fdflags) + +##### Results +- `error`: [`errno`](#errno) + +- `opened_fd`: [`fd`](#fd) +The file descriptor of the file that has been opened. + + +--- + +#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +Read the contents of a symbolic link. +Note: This is similar to `readlinkat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path of the symbolic link from which to read. + +- `buf`: `Pointer` +The buffer to which to write the contents of the symbolic link. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes placed in the buffer. + + +--- + +#### `path_remove_directory(fd: fd, path: string) -> errno` +Remove a directory. +Return `ENOTEMPTY` if the directory is not empty. +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a directory to remove. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +Rename a file or directory. +Note: This is similar to `renameat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `old_path`: `string` +The source path of the file or directory to rename. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path to which to rename the file or directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_symlink(old_path: string, fd: fd, new_path: string) -> errno` +Create a symbolic link. +Note: This is similar to `symlinkat` in POSIX. + +##### Params +- `old_path`: `string` +The contents of the symbolic link. + +- `fd`: [`fd`](#fd) + +- `new_path`: `string` +The destination path at which to create the symbolic link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_unlink_file(fd: fd, path: string) -> errno` +Unlink a file. +Return `EISDIR` if the path refers to a directory. +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a file to unlink. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +Concurrently poll for the occurrence of a set of events. + +##### Params +- `in`: `ConstPointer` +The events to which to subscribe. + +- `out`: `Pointer` +The events that have occurred. + +- `nsubscriptions`: [`size`](#size) +Both the number of subscriptions and events. + +##### Results +- `error`: [`errno`](#errno) + +- `nevents`: [`size`](#size) +The number of events stored. + + +--- + +#### `proc_exit(rval: exitcode)` +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +##### Params +- `rval`: [`exitcode`](#exitcode) +The exit code returned by the process. + +##### Results + +--- + +#### `proc_raise(sig: signal) -> errno` +Send a signal to the process of the calling thread. +Note: This is similar to `raise` in POSIX. + +##### Params +- `sig`: [`signal`](#signal) +The signal condition to trigger. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sched_yield() -> errno` +Temporarily yield execution of the calling thread. +Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. + +##### Params +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `random_get(buf: Pointer, buf_len: size) -> errno` +Write high-quality random data into a buffer. +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. +This function may execute slowly, so when large mounts of random data are +required, it's advisable to use this function to seed a pseudo-random +number generator, rather than to provide the random data directly. + +##### Params +- `buf`: `Pointer` +The buffer to fill with random data. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +Receive a message from a socket. +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +##### Params +- `fd`: [`fd`](#fd) + +- `ri_data`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +- `ri_flags`: [`riflags`](#riflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `ro_datalen`: [`size`](#size) +Number of bytes stored in ri_data. + +- `ro_flags`: [`roflags`](#roflags) +Message flags. + + +--- + +#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +Send a message on a socket. +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +##### Params +- `fd`: [`fd`](#fd) + +- `si_data`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors to which to retrieve data + +- `si_flags`: [`siflags`](#siflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `so_datalen`: [`size`](#size) +Number of bytes transmitted. + + +--- + +#### `sock_shutdown(fd: fd, how: sdflags) -> errno` +Shut down socket send and receive channels. +Note: This is similar to `shutdown` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `how`: [`sdflags`](#sdflags) +Which channels on the socket to shut down. + +##### Results +- `error`: [`errno`](#errno) + diff --git a/proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md b/proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md deleted file mode 100644 index 7aa5816af..000000000 --- a/proposals/clocks/phases/snapshot/docs/wasi_unstable_preview1.md +++ /dev/null @@ -1,2346 +0,0 @@ - - -# The WASI Preview API - -This is the API-level documentation for WASI Preview. The function names -are prefixed with "\_\_wasi\_" to reflect how they are spelled in -flat-namespace contexts, however at the wasm module level, they are -unprefixed, because they're inside a module namespace. - -Functions that start with `__wasi_fd_` operate on file descriptors, -while functions that start with `__wasi_path_` operate on filesystem -paths, which are relative to directory file descriptors. - -Much inspiration and content here is derived from [CloudABI] and [POSIX], -though there are also several differences from CloudABI and POSIX. For -example, WASI Preview has no concept of processes in the traditional Unix -sense. While wasm linear memories have some of the aspects of processes, -and it's possible to *emulate* the full semantics of processes on top of -them, this can sometimes be unnatural and inefficient. The goal for -WASI Preview is to be a WebAssembly-native API that exposes APIs that fit -well into the underlying WebAssembly platform, rather than to directly -emulate other platforms. - -This is also a work in progress, and the API here is still evolving. - -Historical note: this API was originally named "WASI Core", and used the -API module name "wasi\_unstable". We've since sought to deemphasize the -"Core" name, as the goal is to split this API up into independent -modules so that embedders need not implement all of it. - -[CloudABI]: https://github.com/NuxiNL/cloudabi -[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ - -## System calls - -- [`__wasi_args_get()`](#args_get) -- [`__wasi_args_sizes_get()`](#args_sizes_get) -- [`__wasi_clock_res_get()`](#clock_res_get) -- [`__wasi_clock_time_get()`](#clock_time_get) -- [`__wasi_environ_get()`](#environ_get) -- [`__wasi_environ_sizes_get()`](#environ_sizes_get) -- [`__wasi_fd_advise()`](#fd_advise) -- [`__wasi_fd_allocate()`](#fd_allocate) -- [`__wasi_fd_close()`](#fd_close) -- [`__wasi_fd_datasync()`](#fd_datasync) -- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) -- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) -- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) -- [`__wasi_fd_filestat_get()`](#fd_filestat_get) -- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) -- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) -- [`__wasi_fd_pread()`](#fd_pread) -- [`__wasi_fd_prestat_get()`](#fd_prestat_get) -- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) -- [`__wasi_fd_pwrite()`](#fd_pwrite) -- [`__wasi_fd_read()`](#fd_read) -- [`__wasi_fd_readdir()`](#fd_readdir) -- [`__wasi_fd_renumber()`](#fd_renumber) -- [`__wasi_fd_seek()`](#fd_seek) -- [`__wasi_fd_sync()`](#fd_sync) -- [`__wasi_fd_tell()`](#fd_tell) -- [`__wasi_fd_write()`](#fd_write) -- [`__wasi_path_create_directory()`](#path_create_directory) -- [`__wasi_path_filestat_get()`](#path_filestat_get) -- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) -- [`__wasi_path_link()`](#path_link) -- [`__wasi_path_open()`](#path_open) -- [`__wasi_path_readlink()`](#path_readlink) -- [`__wasi_path_remove_directory()`](#path_remove_directory) -- [`__wasi_path_rename()`](#path_rename) -- [`__wasi_path_symlink()`](#path_symlink) -- [`__wasi_path_unlink_file()`](#path_unlink_file) -- [`__wasi_poll_oneoff()`](#poll_oneoff) -- [`__wasi_proc_exit()`](#proc_exit) -- [`__wasi_proc_raise()`](#proc_raise) -- [`__wasi_random_get()`](#random_get) -- [`__wasi_sched_yield()`](#sched_yield) -- [`__wasi_sock_recv()`](#sock_recv) -- [`__wasi_sock_send()`](#sock_send) -- [`__wasi_sock_shutdown()`](#sock_shutdown) - -### `__wasi_args_get()` - -Read command-line argument data. - -Inputs: - -- char \*\*argv - - A pointer to a buffer to write the argument pointers. - - The count of elements for the buffer should be at least the value of `argc` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - - The caller of `__wasi_args_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. - -- char \*argv\_buf - - A pointer to a buffer to write the argument string data. - - The size of this buffer should be the value of `argv_buf_size` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - -### `__wasi_args_sizes_get()` - -Return command-line argument data sizes. - -Outputs: - -- size\_t \*argc - - The number of arguments. - -- size\_t \*argv\_buf\_size - - The size of the argument string data. - -### `__wasi_clock_res_get()` - -Return the resolution of a clock. - -Implementations are required to provide a non-zero value for supported clocks. -For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). - -Note: This is similar to `clock_getres` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the resolution. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) resolution - - The resolution of the clock. - -### `__wasi_clock_time_get()` - -Return the time value of a clock. - -Note: This is similar to `clock_gettime` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the time. - -- [\_\_wasi\_timestamp\_t](#timestamp) precision - - The maximum lag (exclusive) that the returned - time value may have, compared to its actual - value. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) time - - The time value of the clock. - -### `__wasi_environ_get()` - -Read environment variable data. - -Inputs: - -- char \*\*environ - - A pointer to a buffer to write the environment variable pointers. - - The count of elements for the buffer should be at least the value of `environ_count` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - - The caller of `__wasi_environ_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. - -- char \*environ\_buf - - A pointer to a buffer to write the environment variable string data. - - The size of this buffer should be the value of `environ_buf_size` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - -### `__wasi_environ_sizes_get()` - -Return enviroment variable data sizes. - -Outputs: - -- size\_t \*environ\_count - - The number of environment variables. - -- size\_t \*environ\_buf\_size - - The size of the environment variable string data. - -### `__wasi_fd_advise()` - -Provide file advisory information on a file descriptor. - -Note: This is similar to `posix_fadvise` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file for which to provide file advisory information. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file to which the advisory applies. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the region to which the advisory applies. - -- [\_\_wasi\_advice\_t](#advice) advice - - The advice. - -### `__wasi_fd_allocate()` - -Force the allocation of space in a file. - -Note: This is similar to `posix_fallocate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file in which to allocate space. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset at which to start the allocation. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the area that is allocated. - -### `__wasi_fd_close()` - -Close a file descriptor. - -Note: This is similar to `close` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to close. - -### `__wasi_fd_datasync()` - -Synchronize the data of a file to disk. - -Note: This is similar to `fdatasync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file to synchronize to disk. - -### `__wasi_fd_fdstat_get()` - -Get the attributes of a file descriptor. - -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well -as additional fields. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_fdstat\_t](#fdstat) \*buf - - The buffer where the file descriptor's attributes are stored. - -### `__wasi_fd_fdstat_set_flags()` - -Adjust the flags associated with a file descriptor. - -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_fdflags\_t](#fdflags) flags - - The desired values of the file descriptor - flags. - -### `__wasi_fd_fdstat_set_rights()` - -Adjust the rights associated with a file descriptor. - -This can only be used to remove rights, and returns -[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt -to add rights. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The desired rights of the file descriptor. - -### `__wasi_fd_filestat_get()` - -Return the attributes of an open file. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_fd_filestat_set_size()` - -Adjust the size of an open file. If this increases the file's size, the extra -bytes are filled with zeros. - -Note: This is similar to `ftruncate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - A file descriptor for the file to adjust. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - The desired file size. - -### `__wasi_fd_filestat_set_times()` - -Adjust the timestamps of an open file or directory. - -Note: This is similar to `futimens` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_fd_pread()` - -Read from a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `preadv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors in which to store data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to read. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_prestat_get()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- [\_\_wasi\_prestat\_t](#prestat) \*buf - - The buffer where the description is stored. - -### `__wasi_fd_prestat_dir_name()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- const char \*path and size\_t path\_len - - A buffer into which to write the preopened directory name. - -### `__wasi_fd_pwrite()` - -Write to a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `pwritev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to write. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_fd_read()` - -Read from a file descriptor. - -Note: This is similar to `readv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors to which to store data. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_readdir()` - -Read directory entries from a directory. - -When successful, the contents of the output buffer consist of -a sequence of directory entries. Each directory entry consists -of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes -holding the name of the directory entry. - -This function fills the output buffer as much as possible, -potentially truncating the last directory entry. This allows -the caller to grow its read buffer size in case it's too small -to fit a single large directory entry, or skip the oversized -directory entry. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The directory from which to read the directory - entries. - -- void \*buf and size\_t buf\_len - - The buffer where directory entries are stored. - -- [\_\_wasi\_dircookie\_t](#dircookie) cookie - - The location within the directory to start - reading. - -Outputs: - -- size\_t bufused - - The number of bytes stored in the read buffer. - If less than the size of the read buffer, the - end of the directory has been reached. - -### `__wasi_fd_renumber()` - -Atomically replace a file descriptor by renumbering another -file descriptor. - -Due to the strong focus on thread safety, this environment -does not provide a mechanism to duplicate or renumber a file -descriptor to an arbitrary number, like dup2(). This would be -prone to race conditions, as an actual file descriptor with the -same number could be allocated by a different thread at the same -time. - -This function provides a way to atomically renumber file -descriptors, which would disappear if dup2() were to be -removed entirely. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) from - - The file descriptor to renumber. - -- [\_\_wasi\_fd\_t](#fd) to - - The file descriptor to overwrite. - -### `__wasi_fd_seek()` - -Move the offset of a file descriptor. - -Note: This is similar to `lseek` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_filedelta\_t](#filedelta) offset - - The number of bytes to move. - -- [\_\_wasi\_whence\_t](#whence) whence - - The base from which the offset is relative. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) newoffset - - The new offset of the file descriptor, - relative to the start of the file. - -### `__wasi_fd_sync()` - -Synchronize the data and metadata of a file to disk. - -Note: This is similar to `fsync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file containing the data - and metadata to synchronize to disk. - -### `__wasi_fd_tell()` - -Return the current offset of a file descriptor. - -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The current offset of the file descriptor, relative to the start of the file. - -### `__wasi_fd_write()` - -Write to a file descriptor. - -Note: This is similar to `writev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_path_create_directory()` - -Create a directory. - -Note: This is similar to `mkdirat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path at which to create the directory. - -### `__wasi_path_filestat_get()` - -Return the attributes of a file or directory. - -Note: This is similar to `stat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_path_filestat_set_times()` - -Adjust the timestamps of a file or directory. - -Note: This is similar to `utimensat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_path_link()` - -Create a hard link. - -Note: This is similar to `linkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags - - Flags determining the method of how the path is resolved. - -- const char \*old\_path and size\_t old\_path\_len - - The source path from which to link. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the hard link. - -### `__wasi_path_open()` - -Open a file or directory. - -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since -this is error-prone in multi-threaded contexts. The returned file -descriptor is guaranteed to be less than 231. - -Note: This is similar to `openat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) dirfd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The relative path of the file or directory to open, relative to - the [`dirfd`](#path_open.dirfd) directory. - -- [\_\_wasi\_oflags\_t](#oflags) o_flags - - The method by which to open the file. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The initial rights of the newly created file descriptor. The - implementation is allowed to return a file descriptor with fewer - rights than specified, if and only if those rights do not apply - to the type of file being opened. - - The *base* rights are rights that will apply to operations using - the file descriptor itself, while the *inheriting* rights are - rights that apply to file descriptors derived from it. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - The initial flags of the file descriptor. - -Outputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file that has been - opened. - -### `__wasi_path_readlink()` - -Read the contents of a symbolic link. - -Note: This is similar to `readlinkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path of the symbolic link from which to read. - -- char \*buf and size\_t buf\_len - - The buffer to which to write the contents of the symbolic link. - -Outputs: - -- size\_t bufused - - The number of bytes placed in the buffer. - -### `__wasi_path_remove_directory()` - -Remove a directory. - -Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. - -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a directory to remove. - -### `__wasi_path_rename()` - -Rename a file or directory. - -Note: This is similar to `renameat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- const char \*old\_path and size\_t old\_path\_len - - The source path of the file or directory to rename. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path to which to rename the file or directory. - -### `__wasi_path_symlink()` - -Create a symbolic link. - -Note: This is similar to `symlinkat` in POSIX. - -Inputs: - -- const char \*old\_path and size\_t old_path\_len - - The contents of the symbolic link. - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the symbolic link. - -### `__wasi_path_unlink_file()` - -Unlink a file. - -Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. - -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a file to unlink. - -### `__wasi_poll_oneoff()` - -Concurrently poll for the occurrence of a set of events. - -Inputs: - -- const [\_\_wasi\_subscription\_t](#subscription) \*in - - The events to which to subscribe. - -- [\_\_wasi\_event\_t](#event) \*out - - The events that have occurred. - -- size\_t nsubscriptions - - Both the number of subscriptions and events. - -Outputs: - -- size\_t nevents - - The number of events stored. - -### `__wasi_proc_exit()` - -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -Note: This is similar to `_Exit` in POSIX. - -Inputs: - -- [\_\_wasi\_exitcode\_t](#exitcode) rval - - The exit code returned by the process. - -Does not return. - -### `__wasi_proc_raise()` - -Send a signal to the process of the calling thread. - -Note: This is similar to `raise` in POSIX. - -Inputs: - -- [\_\_wasi\_signal\_t](#signal) sig - - The signal condition to trigger. - -### `__wasi_random_get()` - -Write high-quality random data into a buffer. - -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. - -This function may execute slowly, so when large mounts of random -data are required, it's advisable to use this function to seed a -pseudo-random number generator, rather than to provide the -random data directly. - -Inputs: - -- void \*buf and size\_t buf\_len - - The buffer to fill with random data. - -### `__wasi_sched_yield()` - -Temporarily yield execution of the calling thread. - -Note: This is similar to `sched_yield` in POSIX. - -### `__wasi_sock_recv()` - -Receive a message from a socket. - -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to receive data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len - - List of scatter/gather vectors to which to store data. - -- [\_\_wasi\_riflags\_t](#riflags) ri\_flags - - Message flags. - -Outputs: - -- size\_t ro\_datalen - - Number of bytes stored in [`ri_data`](#sock_recv.ri_data). - -- [\_\_wasi\_roflags\_t](#roflags) ro\_flags - - Message flags. - -### `__wasi_sock_send()` - -Send a message on a socket. - -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to send data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len - - List of scatter/gather vectors to which to retrieve data - -- [\_\_wasi\_siflags\_t](#siflags) si\_flags - - Message flags. - -Outputs: - -- size\_t so\_datalen - - Number of bytes transmitted. - -### `__wasi_sock_shutdown()` - -Shut down socket send and receive channels. - -Note: This is similar to `shutdown` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to shutdown channels. - -- [\_\_wasi\_sdflags\_t](#sdflags) how - - Which channels on the socket to shut down. - -## Types - -### `__wasi_advice_t` (`uint8_t`) - -File or memory access pattern advisory information. - -Used by [`__wasi_fd_advise()`](#fd_advise). - -Possible values: - -- **`__WASI_ADVICE_NORMAL`** - - The application has no advice to give on its behavior - with respect to the specified data. - -- **`__WASI_ADVICE_SEQUENTIAL`** - - The application expects to access the specified data - sequentially from lower offsets to higher offsets. - -- **`__WASI_ADVICE_RANDOM`** - - The application expects to access the specified data - in a random order. - -- **`__WASI_ADVICE_WILLNEED`** - - The application expects to access the specified data - in the near future. - -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - -### `__wasi_ciovec_t` (`struct`) - -A region of memory for scatter/gather writes. - -Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). - -Members: - -- const void \*buf and size\_t buf\_len - - The address and length of the buffer to be written. - -### `__wasi_clockid_t` (`uint32_t`) - -Identifiers for clocks. - -Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). - -Possible values: - -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - -- **`__WASI_CLOCK_MONOTONIC`** - - The store-wide monotonic clock, which is defined as a - clock measuring real time, whose value cannot be - adjusted and which cannot have negative clock jumps. - - The epoch of this clock is undefined. The absolute - time value of this clock therefore has no meaning. - -- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** - - The CPU-time clock associated with the current - process. - -- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** - - The CPU-time clock associated with the current thread. - -### `__wasi_device_t` (`uint64_t`) - -Identifier for a device containing a file system. Can be used -in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or -directory in the filesystem. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_dircookie_t` (`uint64_t`) - -A reference to the offset of a directory entry. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). - -Special values: - -- **`__WASI_DIRCOOKIE_START`** - - Permanent reference to the first directory entry - within a directory. - -### `__wasi_dirent_t` (`struct`) - -A directory entry. - -Members: - -- [\_\_wasi\_dircookie\_t](#dircookie) d\_next - - The offset of the next directory entry stored in this - directory. - -- [\_\_wasi\_inode\_t](#inode) d\_ino - - The serial number of the file referred to by this - directory entry. - -- uint32\_t d\_namlen - - The length of the name of the directory entry. - -- [\_\_wasi\_filetype\_t](#filetype) d\_type - - The type of the file referred to by this directory - entry. - -### `__wasi_errno_t` (`uint16_t`) - -Error codes returned by functions. - -Not all of these error codes are returned by the functions -provided by this API; some are used in higher-level library layers, -and others are provided merely for alignment with POSIX. - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_ESUCCESS`** - - No error occurred. System call completed successfully. - -- **`__WASI_E2BIG`** - - Argument list too long. - -- **`__WASI_EACCES`** - - Permission denied. - -- **`__WASI_EADDRINUSE`** - - Address in use. - -- **`__WASI_EADDRNOTAVAIL`** - - Address not available. - -- **`__WASI_EAFNOSUPPORT`** - - Address family not supported. - -- **`__WASI_EAGAIN`** - - Resource unavailable, or operation would block. - -- **`__WASI_EALREADY`** - - Connection already in progress. - -- **`__WASI_EBADF`** - - Bad file descriptor. - -- **`__WASI_EBADMSG`** - - Bad message. - -- **`__WASI_EBUSY`** - - Device or resource busy. - -- **`__WASI_ECANCELED`** - - Operation canceled. - -- **`__WASI_ECHILD`** - - No child processes. - -- **`__WASI_ECONNABORTED`** - - Connection aborted. - -- **`__WASI_ECONNREFUSED`** - - Connection refused. - -- **`__WASI_ECONNRESET`** - - Connection reset. - -- **`__WASI_EDEADLK`** - - Resource deadlock would occur. - -- **`__WASI_EDESTADDRREQ`** - - Destination address required. - -- **`__WASI_EDOM`** - - Mathematics argument out of domain of function. - -- **`__WASI_EDQUOT`** - - Reserved. - -- **`__WASI_EEXIST`** - - File exists. - -- **`__WASI_EFAULT`** - - Bad address. - -- **`__WASI_EFBIG`** - - File too large. - -- **`__WASI_EHOSTUNREACH`** - - Host is unreachable. - -- **`__WASI_EIDRM`** - - Identifier removed. - -- **`__WASI_EILSEQ`** - - Illegal byte sequence. - -- **`__WASI_EINPROGRESS`** - - Operation in progress. - -- **`__WASI_EINTR`** - - Interrupted function. - -- **`__WASI_EINVAL`** - - Invalid argument. - -- **`__WASI_EIO`** - - I/O error. - -- **`__WASI_EISCONN`** - - Socket is connected. - -- **`__WASI_EISDIR`** - - Is a directory. - -- **`__WASI_ELOOP`** - - Too many levels of symbolic links. - -- **`__WASI_EMFILE`** - - File descriptor value too large. - -- **`__WASI_EMLINK`** - - Too many links. - -- **`__WASI_EMSGSIZE`** - - Message too large. - -- **`__WASI_EMULTIHOP`** - - Reserved. - -- **`__WASI_ENAMETOOLONG`** - - Filename too long. - -- **`__WASI_ENETDOWN`** - - Network is down. - -- **`__WASI_ENETRESET`** - - Connection aborted by network. - -- **`__WASI_ENETUNREACH`** - - Network unreachable. - -- **`__WASI_ENFILE`** - - Too many files open in system. - -- **`__WASI_ENOBUFS`** - - No buffer space available. - -- **`__WASI_ENODEV`** - - No such device. - -- **`__WASI_ENOENT`** - - No such file or directory. - -- **`__WASI_ENOEXEC`** - - Executable file format error. - -- **`__WASI_ENOLCK`** - - No locks available. - -- **`__WASI_ENOLINK`** - - Reserved. - -- **`__WASI_ENOMEM`** - - Not enough space. - -- **`__WASI_ENOMSG`** - - No message of the desired type. - -- **`__WASI_ENOPROTOOPT`** - - Protocol not available. - -- **`__WASI_ENOSPC`** - - No space left on device. - -- **`__WASI_ENOSYS`** - - Function not supported. - -- **`__WASI_ENOTCONN`** - - The socket is not connected. - -- **`__WASI_ENOTDIR`** - - Not a directory or a symbolic link to a directory. - -- **`__WASI_ENOTEMPTY`** - - Directory not empty. - -- **`__WASI_ENOTRECOVERABLE`** - - State not recoverable. - -- **`__WASI_ENOTSOCK`** - - Not a socket. - -- **`__WASI_ENOTSUP`** - - Not supported, or operation not supported on socket. - -- **`__WASI_ENOTTY`** - - Inappropriate I/O control operation. - -- **`__WASI_ENXIO`** - - No such device or address. - -- **`__WASI_EOVERFLOW`** - - Value too large to be stored in data type. - -- **`__WASI_EOWNERDEAD`** - - Previous owner died. - -- **`__WASI_EPERM`** - - Operation not permitted. - -- **`__WASI_EPIPE`** - - Broken pipe. - -- **`__WASI_EPROTO`** - - Protocol error. - -- **`__WASI_EPROTONOSUPPORT`** - - Protocol not supported. - -- **`__WASI_EPROTOTYPE`** - - Protocol wrong type for socket. - -- **`__WASI_ERANGE`** - - Result too large. - -- **`__WASI_EROFS`** - - Read-only file system. - -- **`__WASI_ESPIPE`** - - Invalid seek. - -- **`__WASI_ESRCH`** - - No such process. - -- **`__WASI_ESTALE`** - - Reserved. - -- **`__WASI_ETIMEDOUT`** - - Connection timed out. - -- **`__WASI_ETXTBSY`** - - Text file busy. - -- **`__WASI_EXDEV`** - - Cross-device link. - -- **`__WASI_ENOTCAPABLE`** - - Extension: Capabilities insufficient. - -### `__wasi_event_t` (`struct`) - -An event that occurred. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that got attached to - [`__wasi_subscription_t::userdata`](#subscription.userdata). - -- [\_\_wasi\_errno\_t](#errno) error - - If non-zero, an error that occurred while processing - the subscription request. - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event that occurred. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_filesize\_t](#filesize) nbytes - - The number of bytes available for reading or writing. - - - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags - - The state of the file descriptor. - -### `__wasi_eventrwflags_t` (`uint16_t` bitfield) - -The state of the file descriptor subscribed to with -[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_EVENT_FD_READWRITE_HANGUP`** - - The peer of this socket has closed or disconnected. - -### `__wasi_eventtype_t` (`uint8_t`) - -Type of a subscription to an event or its occurrence. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_EVENTTYPE_CLOCK`** - - The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) - has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -- **`__WASI_EVENTTYPE_FD_READ`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - data available for reading. This event always triggers - for regular files. - -- **`__WASI_EVENTTYPE_FD_WRITE`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - capacity available for writing. This event always - triggers for regular files. - -### `__wasi_exitcode_t` (`uint32_t`) - -Exit code generated by a process when exiting. - -Used by [`__wasi_proc_exit()`](#proc_exit). - -### `__wasi_fd_t` (`uint32_t`) - -A file descriptor number. - -Used by many functions in this API. - -As in POSIX, three file descriptor numbers are provided to instances -on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, -and `STDERR_FILENO`). - -Other than these, WASI implementations are not required to allocate -new file descriptors in ascending order. - -### `__wasi_fdflags_t` (`uint16_t` bitfield) - -File descriptor flags. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_FDFLAG_APPEND`** - - Append mode: Data written to the file is always - appended to the file's end. - -- **`__WASI_FDFLAG_DSYNC`** - - Write according to synchronized I/O data integrity - completion. Only the data stored in the file is - synchronized. - -- **`__WASI_FDFLAG_NONBLOCK`** - - Non-blocking mode. - -- **`__WASI_FDFLAG_RSYNC`** - - Synchronized read I/O operations. - -- **`__WASI_FDFLAG_SYNC`** - - Write according to synchronized I/O file integrity completion. - In addition to synchronizing the data stored in the file, the - implementation may also synchronously update the file's metadata. - -### `__wasi_fdstat_t` (`struct`) - -File descriptor attributes. - -Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). - -Members: - -- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype - - File type. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - File descriptor flags. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base - - Rights that apply to this file descriptor. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - Maximum set of rights that may be installed on new - file descriptors that are created through this file - descriptor, e.g., through [`__wasi_path_open()`](#path_open). - -### `__wasi_filedelta_t` (`int64_t`) - -Relative offset within a file. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -### `__wasi_filesize_t` (`uint64_t`) - -Non-negative file size or length of a region within a file. - -Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -### `__wasi_filestat_t` (`struct`) - -File attributes. - -Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). - -Members: - -- [\_\_wasi\_device\_t](#device) st\_dev - - Device ID of device containing the file. - -- [\_\_wasi\_inode\_t](#inode) st\_ino - - File serial number. - -- [\_\_wasi\_filetype\_t](#filetype) st\_filetype - - File type. - -- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink - - Number of hard links to the file. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - For regular files, the file size in bytes. For - symbolic links, the length in bytes of the pathname - contained in the symbolic link. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - Last data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - Last data modification timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim - - Last file status change timestamp. - -### `__wasi_filetype_t` (`uint8_t`) - -The type of a file descriptor or file. - -Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). - -Possible values: - -- **`__WASI_FILETYPE_UNKNOWN`** - - The type of the file descriptor or file is unknown or - is different from any of the other types specified. - -- **`__WASI_FILETYPE_BLOCK_DEVICE`** - - The file descriptor or file refers to a block device - inode. - -- **`__WASI_FILETYPE_CHARACTER_DEVICE`** - - The file descriptor or file refers to a character - device inode. - -- **`__WASI_FILETYPE_DIRECTORY`** - - The file descriptor or file refers to a directory - inode. - -- **`__WASI_FILETYPE_REGULAR_FILE`** - - The file descriptor or file refers to a regular file - inode. - -- **`__WASI_FILETYPE_SOCKET_DGRAM`** - - The file descriptor or file refers to a datagram - socket. - -- **`__WASI_FILETYPE_SOCKET_STREAM`** - - The file descriptor or file refers to a byte-stream - socket. - -- **`__WASI_FILETYPE_SYMBOLIC_LINK`** - - The file refers to a symbolic link inode. - -### `__wasi_fstflags_t` (`uint16_t` bitfield) - -Which file time attributes to adjust. - -Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -Possible values: - -- **`__WASI_FILESTAT_SET_ATIM`** - - Adjust the last data access timestamp to the value - stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). - -- **`__WASI_FILESTAT_SET_ATIM_NOW`** - - Adjust the last data access timestamp to the time - of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -- **`__WASI_FILESTAT_SET_MTIM`** - - Adjust the last data modification timestamp to the - value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). - -- **`__WASI_FILESTAT_SET_MTIM_NOW`** - - Adjust the last data modification timestamp to the - time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -### `__wasi_inode_t` (`uint64_t`) - -File serial number that is unique within its file system. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). - -### `__wasi_iovec_t` (`struct`) - -A region of memory for scatter/gather reads. - -Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). - -Members: - -- void \*buf and size\_t buf\_len - - The address and length of the buffer to be filled. - -### `__wasi_linkcount_t` (`uint64_t`) - -Number of hard links to an inode. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_lookupflags_t` (`uint32_t` bitfield) - -Flags determining the method of how paths are resolved. - -Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** - - As long as the resolved path corresponds to a symbolic - link, it is expanded. - -### `__wasi_oflags_t` (`uint16_t` bitfield) - -Open flags used by [`__wasi_path_open()`](#path_open). - -Used by [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_O_CREAT`** - - Create file if it does not exist. - -- **`__WASI_O_DIRECTORY`** - - Fail if not a directory. - -- **`__WASI_O_EXCL`** - - Fail if file already exists. - -- **`__WASI_O_TRUNC`** - - Truncate file to size 0. - -### `__wasi_riflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_PEEK`** - - Returns the message without removing it from the - socket's receive queue. - -- **`__WASI_SOCK_RECV_WAITALL`** - - On byte-stream sockets, block until the full amount - of data can be returned. - -### `__wasi_rights_t` (`uint64_t` bitfield) - -File descriptor rights, determining which actions may be -performed. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_RIGHT_FD_DATASYNC`** - - The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_READ`** - - The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke - [`__wasi_fd_pread()`](#fd_pread). - -- **`__WASI_RIGHT_FD_SEEK`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies - [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). - -- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** - - The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). - -- **`__WASI_RIGHT_FD_SYNC`** - - The right to invoke [`__wasi_fd_sync()`](#fd_sync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and - [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_TELL`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the - file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with - offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). - -- **`__WASI_RIGHT_FD_WRITE`** - - The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to - invoke [`__wasi_fd_pwrite()`](#fd_pwrite). - -- **`__WASI_RIGHT_FD_ADVISE`** - - The right to invoke [`__wasi_fd_advise()`](#fd_advise). - -- **`__WASI_RIGHT_FD_ALLOCATE`** - - The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). - -- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** - - The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). - -- **`__WASI_RIGHT_PATH_CREATE_FILE`** - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke - [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). - -- **`__WASI_RIGHT_PATH_LINK_SOURCE`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_LINK_TARGET`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_OPEN`** - - The right to invoke [`__wasi_path_open()`](#path_open). - -- **`__WASI_RIGHT_FD_READDIR`** - - The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). - -- **`__WASI_RIGHT_PATH_READLINK`** - - The right to invoke [`__wasi_path_readlink()`](#path_readlink). - -- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_RENAME_TARGET`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_FILESTAT_GET`** - - The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** - - The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -- **`__WASI_RIGHT_FD_FILESTAT_GET`** - - The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** - - The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). - -- **`__WASI_RIGHT_PATH_SYMLINK`** - - The right to invoke [`__wasi_path_symlink()`](#path_symlink). - -- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** - - The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). - -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - -- **`__WASI_RIGHT_POLL_FD_READWRITE`** - - If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). - - If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -- **`__WASI_RIGHT_SOCK_SHUTDOWN`** - - The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). - -### `__wasi_roflags_t` (`uint16_t` bitfield) - -Flags returned by [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** - - Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been - truncated. - -### `__wasi_sdflags_t` (`uint8_t` bitfield) - -Which channels on a socket to shut down. - -Used by [`__wasi_sock_shutdown()`](#sock_shutdown). - -Possible values: - -- **`__WASI_SHUT_RD`** - - Disables further receive operations. - -- **`__WASI_SHUT_WR`** - - Disables further send operations. - -### `__wasi_siflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Used by [`__wasi_sock_send()`](#sock_send). - -### `__wasi_signal_t` (`uint8_t`) - -Signal condition. - -Used by [`__wasi_proc_raise()`](#proc_raise). - -Possible values: - -- **`__WASI_SIGHUP`** - - Hangup. - - Action: Terminates the process. - -- **`__WASI_SIGINT`** - - Terminate interrupt signal. - - Action: Terminates the process. - -- **`__WASI_SIGQUIT`** - - Terminal quit signal. - - Action: Terminates the process. - -- **`__WASI_SIGILL`** - - Illegal instruction. - - Action: Terminates the process. - -- **`__WASI_SIGTRAP`** - - Trace/breakpoint trap. - - Action: Terminates the process. - -- **`__WASI_SIGABRT`** - - Process abort signal. - - Action: Terminates the process. - -- **`__WASI_SIGBUS`** - - Access to an undefined portion of a memory object. - - Action: Terminates the process. - -- **`__WASI_SIGFPE`** - - Erroneous arithmetic operation. - - Action: Terminates the process. - -- **`__WASI_SIGKILL`** - - Kill. - - Action: Terminates the process. - -- **`__WASI_SIGUSR1`** - - User-defined signal 1. - - Action: Terminates the process. - -- **`__WASI_SIGSEGV`** - - Invalid memory reference. - - Action: Terminates the process. - -- **`__WASI_SIGUSR2`** - - User-defined signal 2. - - Action: Terminates the process. - -- **`__WASI_SIGPIPE`** - - Write on a pipe with no one to read it. - - Action: Ignored. - -- **`__WASI_SIGALRM`** - - Alarm clock. - - Action: Terminates the process. - -- **`__WASI_SIGTERM`** - - Termination signal. - - Action: Terminates the process. - -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** - - Continue executing, if stopped. - - Action: Continues executing, if stopped. - -- **`__WASI_SIGSTOP`** - - Stop executing. - - Action: Stops executing. - -- **`__WASI_SIGTSTP`** - - Terminal stop signal. - - Action: Stops executing. - -- **`__WASI_SIGTTIN`** - - Background process attempting read. - - Action: Stops executing. - -- **`__WASI_SIGTTOU`** - - Background process attempting write. - - Action: Stops executing. - -- **`__WASI_SIGURG`** - - High bandwidth data is available at a socket. - - Action: Ignored. - -- **`__WASI_SIGXCPU`** - - CPU time limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGXFSZ`** - - File size limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGVTALRM`** - - Virtual timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGPROF`** - - Profiling timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGWINCH`** - - Window changed. - - Action: Ignored. - -- **`__WASI_SIGPOLL`** - - I/O possible. - - Action: Terminates the process. - -- **`__WASI_SIGPWR`** - - Power failure. - - Action: Terminates the process. - -- **`__WASI_SIGSYS`** - - Bad system call. - - Action: Terminates the process. - -### `__wasi_subclockflags_t` (`uint16_t` bitfield) - -Flags determining how to interpret the timestamp provided in -[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -Used by [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** - - If set, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp - of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - - If clear, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current - time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - -### `__wasi_subscription_t` (`struct`) - -Subscription to an event. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that is attached to the subscription in the - implementation and returned through - [`__wasi_event_t::userdata`](#event.userdata). - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event to which to subscribe. - -- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): - - - **`u.clock`** - - - [\_\_wasi\_clockid\_t](#clockid) id - - The clock against which to compare the timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) timeout - - The absolute or relative timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) precision - - The amount of time that the implementation may wait additionally - to coalesce with other events. - - - [\_\_wasi\_subclockflags\_t](#subclockflags) flags - - Flags specifying whether the timeout is absolute or relative. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor on which to wait for it to become ready - for reading or writing. - -### `__wasi_timestamp_t` (`uint64_t`) - -Timestamp in nanoseconds. - -Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -### `__wasi_userdata_t` (`uint64_t`) - -User-provided value that may be attached to objects that is -retained when extracted from the implementation. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -### `__wasi_whence_t` (`uint8_t`) - -The position relative to which to set the offset of the file descriptor. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -Possible values: - -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - -- **`__WASI_WHENCE_CUR`** - - Seek relative to current position. - -- **`__WASI_WHENCE_END`** - - Seek relative to end-of-file. From 8fa56918086fc441550d4a60afb082e14e493f4d Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 14:22:28 -0800 Subject: [PATCH 0500/1772] replace legacy docs with new generated docs --- proposals/random/phases/ephemeral/docs.md | 1787 +++++++++++++ .../random/phases/old/snapshot_0/docs.md | 1791 +++++++++++++ .../old/snapshot_0/docs/wasi_unstable.md | 2343 ---------------- proposals/random/phases/snapshot/docs.md | 1790 +++++++++++++ .../snapshot/docs/wasi_unstable_preview1.md | 2346 ----------------- 5 files changed, 5368 insertions(+), 4689 deletions(-) create mode 100644 proposals/random/phases/ephemeral/docs.md create mode 100644 proposals/random/phases/old/snapshot_0/docs.md delete mode 100644 proposals/random/phases/old/snapshot_0/docs/wasi_unstable.md create mode 100644 proposals/random/phases/snapshot/docs.md delete mode 100644 proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md new file mode 100644 index 000000000..8465cd8b7 --- /dev/null +++ b/proposals/random/phases/ephemeral/docs.md @@ -0,0 +1,1787 @@ +# Types +## `size`: `usize` + +## `filesize`: `u64` +Non-negative file size or length of a region within a file. + +## `timestamp`: `u64` +Timestamp in nanoseconds. + +## `clockid`: Enum(`u32`) +Identifiers for clocks. + +### Variants +- `realtime` +The clock measuring real time. Time value zero corresponds with +1970-01-01T00:00:00Z. + +- `monotonic` +The store-wide monotonic clock, which is defined as a clock measuring +real time, whose value cannot be adjusted and which cannot have negative +clock jumps. The epoch of this clock is undefined. The absolute time +value of this clock therefore has no meaning. + +- `process_cputime_id` +The CPU-time clock associated with the current process. + +- `thread_cputime_id` +The CPU-time clock associated with the current thread. + +## `errno`: Enum(`u16`) +Error codes returned by functions. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX. + +### Variants +- `success` +No error occurred. System call completed successfully. + +- `2big` +Argument list too long. + +- `acces` +Permission denied. + +- `addrinuse` +Address in use. + +- `addrnotavail` +Address not available. + +- `afnosupport` +Address family not supported. + +- `again` +Resource unavailable, or operation would block. + +- `already` +Connection already in progress. + +- `badf` +Bad file descriptor. + +- `badmsg` +Bad message. + +- `busy` +Device or resource busy. + +- `canceled` +Operation canceled. + +- `child` +No child processes. + +- `connaborted` +Connection aborted. + +- `connrefused` +Connection refused. + +- `connreset` +Connection reset. + +- `deadlk` +Resource deadlock would occur. + +- `destaddrreq` +Destination address required. + +- `dom` +Mathematics argument out of domain of function. + +- `dquot` +Reserved. + +- `exist` +File exists. + +- `fault` +Bad address. + +- `fbig` +File too large. + +- `hostunreach` +Host is unreachable. + +- `idrm` +Identifier removed. + +- `ilseq` +Illegal byte sequence. + +- `inprogress` +Operation in progress. + +- `intr` +Interrupted function. + +- `inval` +Invalid argument. + +- `io` +I/O error. + +- `isconn` +Socket is connected. + +- `isdir` +Is a directory. + +- `loop` +Too many levels of symbolic links. + +- `mfile` +File descriptor value too large. + +- `mlink` +Too many links. + +- `msgsize` +Message too large. + +- `multihop` +Reserved. + +- `nametoolong` +Filename too long. + +- `netdown` +Network is down. + +- `netreset` +Connection aborted by network. + +- `netunreach` +Network unreachable. + +- `nfile` +Too many files open in system. + +- `nobufs` +No buffer space available. + +- `nodev` +No such device. + +- `noent` +No such file or directory. + +- `noexec` +Executable file format error. + +- `nolck` +No locks available. + +- `nolink` +Reserved. + +- `nomem` +Not enough space. + +- `nomsg` +No message of the desired type. + +- `noprotoopt` +Protocol not available. + +- `nospc` +No space left on device. + +- `nosys` +Function not supported. + +- `notconn` +The socket is not connected. + +- `notdir` +Not a directory or a symbolic link to a directory. + +- `notempty` +Directory not empty. + +- `notrecoverable` +State not recoverable. + +- `notsock` +Not a socket. + +- `notsup` +Not supported, or operation not supported on socket. + +- `notty` +Inappropriate I/O control operation. + +- `nxio` +No such device or address. + +- `overflow` +Value too large to be stored in data type. + +- `ownerdead` +Previous owner died. + +- `perm` +Operation not permitted. + +- `pipe` +Broken pipe. + +- `proto` +Protocol error. + +- `protonosupport` +Protocol not supported. + +- `prototype` +Protocol wrong type for socket. + +- `range` +Result too large. + +- `rofs` +Read-only file system. + +- `spipe` +Invalid seek. + +- `srch` +No such process. + +- `stale` +Reserved. + +- `timedout` +Connection timed out. + +- `txtbsy` +Text file busy. + +- `xdev` +Cross-device link. + +- `notcapable` +Extension: Capabilities insufficient. + +## `rights`: Flags(`u64`) +File descriptor rights, determining which actions may be performed. + +### Flags +- `fd_datasync` +The right to invoke `fd_datasync`. +If `path_open` is set, includes the right to invoke +`path_open` with `fdflag::dsync`. + +- `fd_read` +The right to invoke `fd_read` and `sock_recv`. +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. + +- `fd_seek` +The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). + +- `fd_fdstat_set_flags` +The right to invoke `fd_fdstat_set_flags`. + +- `fd_sync` +The right to invoke `fd_sync`. +If `path_open` is set, includes the right to invoke +`path_open` with `fdflag::rsync` and `fdflag::dsync`. + +- `fd_tell` +The right to invoke `fd_seek` in such a way that the file offset +remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +invoke `fd_tell`. + +- `fd_write` +The right to invoke `fd_write` and `sock_send`. +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. + +- `fd_advise` +The right to invoke `fd_advise`. + +- `fd_allocate` +The right to invoke `fd_allocate`. + +- `path_create_directory` +The right to invoke `path_create_directory`. + +- `path_create_file` +If `path_open` is set, the right to invoke `path_open` with [`oflags::creat`](#oflags.creat). + +- `path_link_source` +The right to invoke `path_link` with the file descriptor as the +source directory. + +- `path_link_target` +The right to invoke `path_link` with the file descriptor as the +target directory. + +- `path_open` +The right to invoke `path_open`. + +- `fd_readdir` +The right to invoke `fd_readdir`. + +- `path_readlink` +The right to invoke `path_readlink`. + +- `path_rename_source` +The right to invoke `path_rename` with the file descriptor as the source directory. + +- `path_rename_target` +The right to invoke `path_rename` with the file descriptor as the target directory. + +- `path_filestat_get` +The right to invoke `path_filestat_get`. + +- `path_filestat_set_size` +The right to change a file's size (there is no `path_filestat_set_size`). +If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). + +- `path_filestat_set_times` +The right to invoke `path_filestat_set_times`. + +- `path_permissions_set` +The right to invoke `path_filestat_set_permissions`. + +- `fd_filestat_get` +The right to invoke `fd_filestat_get`. + +- `fd_filestat_set_size` +The right to invoke `fd_filestat_set_size`. + +- `fd_filestat_set_times` +The right to invoke `fd_filestat_set_times`. + +- `fd_permissions_set` +The right to invoke `fd_filestat_set_permissions`. + +- `path_symlink` +The right to invoke `path_symlink`. + +- `path_remove_directory` +The right to invoke `path_remove_directory`. + +- `path_unlink_file` +The right to invoke `path_unlink_file`. + +- `poll_fd_readwrite` +If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). +If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). + +- `sock_shutdown` +The right to invoke `sock_shutdown`. + +## `fd` +A file descriptor handle. + +### Supertypes +## `iovec`: Struct +A region of memory for scatter/gather reads. + +### Struct members +- `buf`: `Pointer` +The address of the buffer to be filled. + +- `buf_len`: [`size`](#size) +The length of the buffer to be filled. + +## `ciovec`: Struct +A region of memory for scatter/gather writes. + +### Struct members +- `buf`: `ConstPointer` +The address of the buffer to be written. + +- `buf_len`: [`size`](#size) +The length of the buffer to be written. + +## `iovec_array`: `Array` + +## `ciovec_array`: `Array` + +## `filedelta`: `s64` +Relative offset within a file. + +## `whence`: Enum(`u8`) +The position relative to which to set the offset of the file descriptor. + +### Variants +- `set` +Seek relative to start-of-file. + +- `cur` +Seek relative to current position. + +- `end` +Seek relative to end-of-file. + +## `dircookie`: Int(`u64`) +A reference to the offset of a directory entry. + +### Consts +- `start` + +## `dirnamlen`: `u32` +The type for the $d_namlen field of $dirent. + +## `inode`: `u64` +File serial number that is unique within its file system. + +## `filetype`: Enum(`u8`) +The type of a file descriptor or file. + +### Variants +- `unknown` +The type of the file descriptor or file is unknown or is different from any of the other types specified. + +- `block_device` +The file descriptor or file refers to a block device inode. + +- `character_device` +The file descriptor or file refers to a character device inode. + +- `directory` +The file descriptor or file refers to a directory inode. + +- `regular_file` +The file descriptor or file refers to a regular file inode. + +- `socket_dgram` +The file descriptor or file refers to a datagram socket. + +- `socket_stream` +The file descriptor or file refers to a byte-stream socket. + +- `symbolic_link` +The file refers to a symbolic link inode. + +- `fifo` +The file descriptor or file refers to a FIFO. + +## `dirent`: Struct +A directory entry. + +### Struct members +- `d_next`: [`dircookie`](#dircookie) +The offset of the next directory entry stored in this directory. + +- `d_ino`: [`inode`](#inode) +The serial number of the file referred to by this directory entry. + +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. + +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. + +## `advice`: Enum(`u8`) +File or memory access pattern advisory information. + +### Variants +- `normal` +The application has no advice to give on its behavior with respect to the specified data. + +- `sequential` +The application expects to access the specified data sequentially from lower offsets to higher offsets. + +- `random` +The application expects to access the specified data in a random order. + +- `willneed` +The application expects to access the specified data in the near future. + +- `dontneed` +The application expects that it will not access the specified data in the near future. + +- `noreuse` +The application expects to access the specified data once and then not reuse it thereafter. + +## `fdflags`: Flags(`u16`) +File descriptor flags. + +### Flags +- `append` +Append mode: Data written to the file is always appended to the file's end. + +- `dsync` +Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + +- `nonblock` +Non-blocking mode. + +- `rsync` +Synchronized read I/O operations. + +- `sync` +Write according to synchronized I/O file integrity completion. In +addition to synchronizing the data stored in the file, the implementation +may also synchronously update the file's metadata. + +## `fdstat`: Struct +File descriptor attributes. + +### Struct members +- `fs_filetype`: [`filetype`](#filetype) +File type. + +- `fs_flags`: [`fdflags`](#fdflags) +File descriptor flags. + +- `fs_rights_base`: [`rights`](#rights) +Rights that apply to this file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) +Maximum set of rights that may be installed on new file descriptors that +are created through this file descriptor, e.g., through `path_open`. + +## `device`: `u64` +Identifier for a device containing a file system. Can be used in combination +with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. + +## `fstflags`: Flags(`u16`) +Which file time attributes to adjust. + +### Flags +- `atim` +Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + +- `atim_now` +Adjust the last data access timestamp to the time of clock `clock::realtime`. + +- `mtim` +Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + +- `mtim_now` +Adjust the last data modification timestamp to the time of clock `clock::realtime`. + +## `lookupflags`: Flags(`u32`) +Flags determining the method of how paths are resolved. + +### Flags +- `symlink_follow` +As long as the resolved path corresponds to a symbolic link, it is expanded. + +## `oflags`: Flags(`u16`) +Open flags used by `path_open`. + +### Flags +- `creat` +Create file if it does not exist. + +- `directory` +Fail if not a directory. + +- `excl` +Fail if file already exists. + +- `trunc` +Truncate file to size 0. + +## `linkcount`: `u64` +Number of hard links to an inode. + +## `permissions`: Flags(`u8`) +File permissions. This represents the permissions associated with a +file in a filesystem, and don't fully reflect all the conditions +which determine whether a given WASI program can access the file. + +### Flags +- `read` +For files, permission to read the file. +For directories, permission to do [`readdir`](#readdir) and access files +within the directory. + +Note: This is similar to the read bit being set on files, and the +read *and* execute bits being set on directories, in POSIX. + +- `write` +For files, permission to mutate the file. +For directories, permission to create, remove, and rename items +within the directory. + +- `execute` +For files, permission to "execute" the file, using whatever +concept of "executing" the host filesystem has. +This flag is not valid for directories. + +- `private` +For filesystems which have a concept of multiple "users", this flag +indicates that the file is only accessible by the effective "user" +that the WASI store uses to access the filesystem, and inaccessible +to other "users". + +## `filestat`: Struct +File attributes. + +### Struct members +- `dev`: [`device`](#device) +Device ID of device containing the file. + +- `ino`: [`inode`](#inode) +File serial number. + +- `filetype`: [`filetype`](#filetype) +File type. + +- `permissions`: [`permissions`](#permissions) +File permissions. + +- `nlink`: [`linkcount`](#linkcount) +Number of hard links to the file. + +- `size`: [`filesize`](#filesize) +For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + +- `atim`: [`timestamp`](#timestamp) +Last data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +Last data modification timestamp. + +- `ctim`: [`timestamp`](#timestamp) +Last file status change timestamp. + +## `userdata`: `u64` +User-provided value that may be attached to objects that is retained when +extracted from the implementation. + +## `eventtype`: Enum(`u8`) +Type of a subscription to an event or its occurrence. + +### Variants +- `clock` +The time value of clock `subscription::u.clock.clock_id` has +reached timestamp `subscription::u.clock.timeout`. + +- `fd_read` +File descriptor `subscription::u.fd_readwrite.fd` has data +available for reading. This event always triggers for regular files. + +- `fd_write` +File descriptor `subscription::u.fd_readwrite.fd` has capacity +available for writing. This event always triggers for regular files. + +## `eventrwflags`: Flags(`u16`) +The state of the file descriptor subscribed to with +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Flags +- `fd_readwrite_hangup` +The peer of this socket has closed or disconnected. + +## `event_fd_readwrite`: Struct +The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `nbytes`: [`filesize`](#filesize) +The number of bytes available for reading or writing. + +- `flags`: [`eventrwflags`](#eventrwflags) +The state of the file descriptor. + +## `event_u`: Union +The contents of an $event. + +### Union variants +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `event`: Struct +An event that occurred. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). + +- `error`: [`errno`](#errno) +If non-zero, an error that occurred while processing the subscription request. + +- `type`: [`eventtype`](#eventtype) +The type of the event that occurred. + +- `u`: [`event_u`](#event_u) +The contents of the event. + +## `subclockflags`: Flags(`u16`) +Flags determining how to interpret the timestamp provided in +`subscription::u.clock.timeout.` + +### Flags +- `subscription_clock_abstime` +If set, treat the timestamp provided in +`subscription::u.clock.timeout` as an absolute timestamp of clock +`subscription::u.clock.clock_id.` If clear, treat the timestamp +provided in `subscription::u.clock.timeout` relative to the +current time value of clock `subscription::u.clock.clock_id.` + +## `subscription_clock`: Struct +The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). + +### Struct members +- `id`: [`clockid`](#clockid) +The clock against which to compare the timestamp. + +- `timeout`: [`timestamp`](#timestamp) +The absolute or relative timestamp. + +- `precision`: [`timestamp`](#timestamp) +The amount of time that the implementation may wait additionally +to coalesce with other events. + +- `flags`: [`subclockflags`](#subclockflags) +Flags specifying whether the timeout is absolute or relative + +## `subscription_fd_readwrite`: Struct +The contents of a $subscription when type is type is +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `file_descriptor`: [`fd`](#fd) +The file descriptor on which to wait for it to become ready for reading or writing. + +## `subscription_u`: Union +The contents of a $subscription. + +### Union variants +- `clock`: [`subscription_clock`](#subscription_clock) +When type is [`eventtype::clock`](#eventtype.clock): + +- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `subscription`: Struct +Subscription to an event. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that is attached to the subscription in the +implementation and returned through [`event::userdata`](#event.userdata). + +- `type`: [`eventtype`](#eventtype) +The type of the event to which to subscribe. + +- `u`: [`subscription_u`](#subscription_u) +The contents of the subscription. + +## `exitcode`: `u32` +Exit code generated by a process when exiting. + +## `riflags`: Flags(`u16`) +Flags provided to `sock_recv`. + +### Flags +- `recv_peek` +Returns the message without removing it from the socket's receive queue. + +- `recv_waitall` +On byte-stream sockets, block until the full amount of data can be returned. + +## `roflags`: Flags(`u16`) +Flags returned by `sock_recv`. + +### Flags +- `recv_data_truncated` +Returned by `sock_recv`: Message data has been truncated. + +## `siflags`: `u16` +Flags provided to `sock_send`. As there are currently no flags +defined, it must be set to zero. + +## `sdflags`: Flags(`u8`) +Which channels on a socket to shut down. + +### Flags +- `rd` +Disables further receive operations. + +- `wr` +Disables further send operations. + +## `preopentype`: Enum(`u8`) +Identifiers for preopened capabilities. + +### Variants +- `dir` +A pre-opened directory. + +## `prestat_dir`: Struct +The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). + +### Struct members +- `pr_name_len`: [`size`](#size) +The length of the directory name for use with `fd_prestat_dir_name`. + +## `prestat_u`: Union +The contents of an $prestat. + +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) +When type is [`preopentype::dir`](#preopentype.dir): + +## `prestat`: Struct +Information about a pre-opened capability. + +### Struct members +- `pr_type`: [`preopentype`](#preopentype) +The type of the pre-opened capability. + +- `u`: [`prestat_u`](#prestat_u) +The contents of the information. + +# Modules +## wasi_ephemeral_args +### Imports +#### Memory +### Functions + +--- + +#### `get(argv: Pointer>, argv_buf: Pointer) -> errno` +Read command-line argument data. +The size of the array should match that returned by [`sizes_get`](#sizes_get) + +##### Params +- `argv`: `Pointer>` + +- `argv_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + +## wasi_ephemeral_clock +### Imports +#### Memory +### Functions + +--- + +#### `res_get(id: clockid) -> (errno, timestamp)` +Return the resolution of a clock. +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Note: This is similar to `clock_getres` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the resolution. + +##### Results +- `error`: [`errno`](#errno) + +- `resolution`: [`timestamp`](#timestamp) +The resolution of the clock. + + +--- + +#### `time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +Return the time value of a clock. +Note: This is similar to `clock_gettime` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the time. + +- `precision`: [`timestamp`](#timestamp) +The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + +##### Results +- `error`: [`errno`](#errno) + +- `time`: [`timestamp`](#timestamp) +The time value of the clock. + +## wasi_ephemeral_environ +### Imports +#### Memory +### Functions + +--- + +#### `get(environ: Pointer>, environ_buf: Pointer) -> errno` +Read environment variable data. +The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). + +##### Params +- `environ`: `Pointer>` + +- `environ_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + +## wasi_ephemeral_fd +### Imports +#### Memory +### Functions + +--- + +#### `advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +Provide file advisory information on a file descriptor. +Note: This is similar to `posix_fadvise` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset within the file to which the advisory applies. + +- `len`: [`filesize`](#filesize) +The length of the region to which the advisory applies. + +- `advice`: [`advice`](#advice) +The advice. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `allocate(fd: fd, offset: filesize, len: filesize) -> errno` +Force the allocation of space in a file. +Note: This is similar to `posix_fallocate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset at which to start the allocation. + +- `len`: [`filesize`](#filesize) +The length of the area that is allocated. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `close(fd: fd) -> errno` +Close a file descriptor. +Note: This is similar to [`close`](#close) in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `datasync(fd: fd) -> errno` +Synchronize the data of a file to disk. +Note: This is similar to `fdatasync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fdstat_get(fd: fd) -> (errno, fdstat)` +Get the attributes of a file descriptor. +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `stat`: [`fdstat`](#fdstat) +The buffer where the file descriptor's attributes are stored. + + +--- + +#### `fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +Adjust the flags associated with a file descriptor. +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`fdflags`](#fdflags) +The desired values of the file descriptor flags. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +Adjust the rights associated with a file descriptor. +This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + +##### Params +- `fd`: [`fd`](#fd) + +- `fs_rights_base`: [`rights`](#rights) +The desired rights of the file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `filestat_get(fd: fd) -> (errno, filestat)` +Return the attributes of an open file. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `filestat_set_size(fd: fd, size: filesize) -> errno` +Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. +Note: This is similar to `ftruncate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `size`: [`filesize`](#filesize) +The desired file size. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of an open file or directory. +Note: This is similar to `futimens` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `permissions_set(fd: fd) -> (permissions, errno)` +Set the permissions of a file or directory. + +This sets the permissions associated with a file or directory in +a filesystem at the time it is called. The ability to actually access +a file or directory may depend on additional permissions not reflected +here. + +Note: This is similar `fchmod` in POSIX. + +Unlike POSIX, this doesn't expose a user/group/other distinction; +implementations in POSIX environments are suggested to consult the +umask to determine which of the user/group/other flags to modify. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `permissions`: [`permissions`](#permissions) +The permissions associated with the file. + +- `error`: [`errno`](#errno) + + +--- + +#### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +Read from a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `preadv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors in which to store data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to read. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `prestat_get(fd: fd) -> (errno, prestat)` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`prestat`](#prestat) +The buffer where the description is stored. + + +--- + +#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `Pointer` +A buffer into which to write the preopened directory name. + +- `path_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +Write to a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `pwritev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to write. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `read(fd: fd, iovs: iovec_array) -> (errno, size)` +Read from a file descriptor. +Note: This is similar to `readv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +Read directory entries from a directory. +When successful, the contents of the output buffer consist of a sequence of +directory entries. Each directory entry consists of a dirent_t object, +followed by dirent_t::d_namlen bytes holding the name of the directory +entry. +This function fills the output buffer as much as possible, potentially +truncating the last directory entry. This allows the caller to grow its +read buffer size in case it's too small to fit a single large directory +entry, or skip the oversized directory entry. + +##### Params +- `fd`: [`fd`](#fd) + +- `buf`: `Pointer` +The buffer where directory entries are stored + +- `buf_len`: [`size`](#size) + +- `cookie`: [`dircookie`](#dircookie) +The location within the directory to start reading + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + + +--- + +#### `renumber(fd: fd, to: fd) -> errno` +Atomically replace a file descriptor by renumbering another file descriptor. +Due to the strong focus on thread safety, this environment does not provide +a mechanism to duplicate or renumber a file descriptor to an arbitrary +number, like `dup2()`. This would be prone to race conditions, as an actual +file descriptor with the same number could be allocated by a different +thread at the same time. +This function provides a way to atomically renumber file descriptors, which +would disappear if `dup2()` were to be removed entirely. + +##### Params +- `fd`: [`fd`](#fd) + +- `to`: [`fd`](#fd) +The file descriptor to overwrite. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +Move the offset of a file descriptor. +Note: This is similar to `lseek` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filedelta`](#filedelta) +The number of bytes to move. + +- `whence`: [`whence`](#whence) +The base from which the offset is relative. + +##### Results +- `error`: [`errno`](#errno) + +- `newoffset`: [`filesize`](#filesize) +The new offset of the file descriptor, relative to the start of the file. + + +--- + +#### `sync(fd: fd) -> errno` +Synchronize the data and metadata of a file to disk. +Note: This is similar to `fsync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `tell(fd: fd) -> (errno, filesize)` +Return the current offset of a file descriptor. +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `offset`: [`filesize`](#filesize) +The current offset of the file descriptor, relative to the start of the file. + + +--- + +#### `write(fd: fd, iovs: ciovec_array) -> (errno, size)` +Write to a file descriptor. +Note: This is similar to `writev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + +## wasi_ephemeral_path +### Imports +#### Memory +### Functions + +--- + +#### `create_directory(fd: fd, path: string) -> errno` +Create a directory. +Note: This is similar to `mkdirat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path at which to create the directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +Return the attributes of a file or directory. +Note: This is similar to `stat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to inspect. + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of a file or directory. +Note: This is similar to `utimensat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to operate on. + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `permissions_set(fd: fd, flags: lookupflags, path: string, permissions: permissions) -> errno` +Set the permissions of a file or directory. + +This sets the permissions associated with a file or directory in +a filesystem at the time it is called. The ability to actually access +a file or directory may depend on additional permissions not reflected +here. + +Note: This is similar to `fchmodat` in POSIX. + +Unlike POSIX, this doesn't expose a user/group/other distinction; +implementations in POSIX environments are suggested to consult the +umask to determine which of the user/group/other flags to modify. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path to a file to query. + +- `permissions`: [`permissions`](#permissions) +The permissions to associate with the file. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +Create a hard link. +Note: This is similar to `linkat` in POSIX. + +##### Params +- `old_fd`: [`fd`](#fd) + +- `old_flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `old_path`: `string` +The source path from which to link. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path at which to create the hard link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags, permissions: permissions) -> (errno, fd)` +Open a file or directory. +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since this +is error-prone in multi-threaded contexts. The returned file descriptor is +guaranteed to be less than 2**31. +Note: This is similar to `openat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `dirflags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The relative path of the file or directory to open, relative to the +`dirfd` directory. + +- `oflags`: [`oflags`](#oflags) +The method by which to open the file. + +- `fs_rights_base`: [`rights`](#rights) +The initial rights of the newly created file descriptor. The +implementation is allowed to return a file descriptor with fewer rights +than specified, if and only if those rights do not apply to the type of +file being opened. +The *base* rights are rights that will apply to operations using the file +descriptor itself, while the *inheriting* rights are rights that apply to +file descriptors derived from it. + +- `fs_rights_inherting`: [`rights`](#rights) + +- `fdflags`: [`fdflags`](#fdflags) + +- `permissions`: [`permissions`](#permissions) +If a file is created, the filesystem permissions to associate with it. + +##### Results +- `error`: [`errno`](#errno) + +- `opened_fd`: [`fd`](#fd) +The file descriptor of the file that has been opened. + + +--- + +#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +Read the contents of a symbolic link. +Note: This is similar to `readlinkat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path of the symbolic link from which to read. + +- `buf`: `Pointer` +The buffer to which to write the contents of the symbolic link. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes placed in the buffer. + + +--- + +#### `remove_directory(fd: fd, path: string) -> errno` +Remove a directory. +Return `ENOTEMPTY` if the directory is not empty. +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a directory to remove. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +Rename a file or directory. +Note: This is similar to `renameat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `old_path`: `string` +The source path of the file or directory to rename. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path to which to rename the file or directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `symlink(old_path: string, fd: fd, new_path: string) -> errno` +Create a symbolic link. +Note: This is similar to `symlinkat` in POSIX. + +##### Params +- `old_path`: `string` +The contents of the symbolic link. + +- `fd`: [`fd`](#fd) + +- `new_path`: `string` +The destination path at which to create the symbolic link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `unlink_file(fd: fd, path: string) -> errno` +Unlink a file. +Return `EISDIR` if the path refers to a directory. +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a file to unlink. + +##### Results +- `error`: [`errno`](#errno) + +## wasi_ephemeral_poll +### Imports +#### Memory +### Functions + +--- + +#### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +Concurrently poll for the occurrence of a set of events. + +##### Params +- `in`: `ConstPointer` +The events to which to subscribe. + +- `out`: `Pointer` +The events that have occurred. + +- `nsubscriptions`: [`size`](#size) +Both the number of subscriptions and events. + +##### Results +- `error`: [`errno`](#errno) + +- `nevents`: [`size`](#size) +The number of events stored. + +## wasi_ephemeral_proc +### Imports +### Functions + +--- + +#### `exit(rval: exitcode)` +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +##### Params +- `rval`: [`exitcode`](#exitcode) +The exit code returned by the process. + +##### Results +## wasi_ephemeral_random +### Imports +#### Memory +### Functions + +--- + +#### `get(buf: Pointer, buf_len: size) -> errno` +Write high-quality random data into a buffer. +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. +This function may execute slowly, so when large mounts of random data are +required, it's advisable to use this function to seed a pseudo-random +number generator, rather than to provide the random data directly. + +##### Params +- `buf`: `Pointer` +The buffer to fill with random data. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + +## wasi_ephemeral_sched +### Imports +### Functions + +--- + +#### `yield() -> errno` +Temporarily yield execution of the calling thread. +Note: This is similar to [`yield`](#yield) in POSIX. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +## wasi_ephemeral_sock +### Imports +#### Memory +### Functions + +--- + +#### `recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +Receive a message from a socket. +Note: This is similar to [`recv`](#recv) in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +##### Params +- `fd`: [`fd`](#fd) + +- `ri_data`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +- `ri_flags`: [`riflags`](#riflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `ro_datalen`: [`size`](#size) +Number of bytes stored in ri_data. + +- `ro_flags`: [`roflags`](#roflags) +Message flags. + + +--- + +#### `send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +Send a message on a socket. +Note: This is similar to [`send`](#send) in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +##### Params +- `fd`: [`fd`](#fd) + +- `si_data`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors to which to retrieve data + +- `si_flags`: [`siflags`](#siflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `so_datalen`: [`size`](#size) +Number of bytes transmitted. + + +--- + +#### `shutdown(fd: fd, how: sdflags) -> errno` +Shut down socket send and receive channels. +Note: This is similar to [`shutdown`](#shutdown) in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `how`: [`sdflags`](#sdflags) +Which channels on the socket to shut down. + +##### Results +- `error`: [`errno`](#errno) + diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md new file mode 100644 index 000000000..360cff906 --- /dev/null +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -0,0 +1,1791 @@ +# Types +## `size`: `u32` + +## `filesize`: `u64` +Non-negative file size or length of a region within a file. + +## `timestamp`: `u64` +Timestamp in nanoseconds. + +## `clockid`: Enum(`u32`) +Identifiers for clocks. + +### Variants +- `realtime` +The clock measuring real time. Time value zero corresponds with +1970-01-01T00:00:00Z. + +- `monotonic` +The store-wide monotonic clock, which is defined as a clock measuring +real time, whose value cannot be adjusted and which cannot have negative +clock jumps. The epoch of this clock is undefined. The absolute time +value of this clock therefore has no meaning. + +- `process_cputime_id` +The CPU-time clock associated with the current process. + +- `thread_cputime_id` +The CPU-time clock associated with the current thread. + +## `errno`: Enum(`u16`) +Error codes returned by functions. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX. + +### Variants +- `success` +No error occurred. System call completed successfully. + +- `2big` +Argument list too long. + +- `acces` +Permission denied. + +- `addrinuse` +Address in use. + +- `addrnotavail` +Address not available. + +- `afnosupport` +Address family not supported. + +- `again` +Resource unavailable, or operation would block. + +- `already` +Connection already in progress. + +- `badf` +Bad file descriptor. + +- `badmsg` +Bad message. + +- `busy` +Device or resource busy. + +- `canceled` +Operation canceled. + +- `child` +No child processes. + +- `connaborted` +Connection aborted. + +- `connrefused` +Connection refused. + +- `connreset` +Connection reset. + +- `deadlk` +Resource deadlock would occur. + +- `destaddrreq` +Destination address required. + +- `dom` +Mathematics argument out of domain of function. + +- `dquot` +Reserved. + +- `exist` +File exists. + +- `fault` +Bad address. + +- `fbig` +File too large. + +- `hostunreach` +Host is unreachable. + +- `idrm` +Identifier removed. + +- `ilseq` +Illegal byte sequence. + +- `inprogress` +Operation in progress. + +- `intr` +Interrupted function. + +- `inval` +Invalid argument. + +- `io` +I/O error. + +- `isconn` +Socket is connected. + +- `isdir` +Is a directory. + +- `loop` +Too many levels of symbolic links. + +- `mfile` +File descriptor value too large. + +- `mlink` +Too many links. + +- `msgsize` +Message too large. + +- `multihop` +Reserved. + +- `nametoolong` +Filename too long. + +- `netdown` +Network is down. + +- `netreset` +Connection aborted by network. + +- `netunreach` +Network unreachable. + +- `nfile` +Too many files open in system. + +- `nobufs` +No buffer space available. + +- `nodev` +No such device. + +- `noent` +No such file or directory. + +- `noexec` +Executable file format error. + +- `nolck` +No locks available. + +- `nolink` +Reserved. + +- `nomem` +Not enough space. + +- `nomsg` +No message of the desired type. + +- `noprotoopt` +Protocol not available. + +- `nospc` +No space left on device. + +- `nosys` +Function not supported. + +- `notconn` +The socket is not connected. + +- `notdir` +Not a directory or a symbolic link to a directory. + +- `notempty` +Directory not empty. + +- `notrecoverable` +State not recoverable. + +- `notsock` +Not a socket. + +- `notsup` +Not supported, or operation not supported on socket. + +- `notty` +Inappropriate I/O control operation. + +- `nxio` +No such device or address. + +- `overflow` +Value too large to be stored in data type. + +- `ownerdead` +Previous owner died. + +- `perm` +Operation not permitted. + +- `pipe` +Broken pipe. + +- `proto` +Protocol error. + +- `protonosupport` +Protocol not supported. + +- `prototype` +Protocol wrong type for socket. + +- `range` +Result too large. + +- `rofs` +Read-only file system. + +- `spipe` +Invalid seek. + +- `srch` +No such process. + +- `stale` +Reserved. + +- `timedout` +Connection timed out. + +- `txtbsy` +Text file busy. + +- `xdev` +Cross-device link. + +- `notcapable` +Extension: Capabilities insufficient. + +## `rights`: Flags(`u64`) +File descriptor rights, determining which actions may be performed. + +### Flags +- `fd_datasync` +The right to invoke [`fd_datasync`](#fd_datasync). +If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke +[`path_open`](#path_open) with `FDFLAG_DSYNC`. + +- `fd_read` +The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). + +- `fd_seek` +The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). + +- `fd_fdstat_set_flags` +The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). + +- `fd_sync` +The right to invoke [`fd_sync`](#fd_sync). +If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke +[`path_open`](#path_open) with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + +- `fd_tell` +The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset +remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +invoke [`fd_tell`](#fd_tell). + +- `fd_write` +The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). + +- `fd_advise` +The right to invoke [`fd_advise`](#fd_advise). + +- `fd_allocate` +The right to invoke [`fd_allocate`](#fd_allocate). + +- `path_create_directory` +The right to invoke [`path_create_directory`](#path_create_directory). + +- `path_create_file` +If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with `O_CREAT`. + +- `path_link_source` +The right to invoke [`path_link`](#path_link) with the file descriptor as the +source directory. + +- `path_link_target` +The right to invoke [`path_link`](#path_link) with the file descriptor as the +target directory. + +- `path_open` +The right to invoke [`path_open`](#path_open). + +- `fd_readdir` +The right to invoke [`fd_readdir`](#fd_readdir). + +- `path_readlink` +The right to invoke [`path_readlink`](#path_readlink). + +- `path_rename_source` +The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. + +- `path_rename_target` +The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. + +- `path_filestat_get` +The right to invoke [`path_filestat_get`](#path_filestat_get). + +- `path_filestat_set_size` +The right to change a file's size (there is no `path_filestat_set_size`). +If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with `O_TRUNC`. + +- `path_filestat_set_times` +The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). + +- `fd_filestat_get` +The right to invoke [`fd_filestat_get`](#fd_filestat_get). + +- `fd_filestat_set_size` +The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). + +- `fd_filestat_set_times` +The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). + +- `path_symlink` +The right to invoke [`path_symlink`](#path_symlink). + +- `path_remove_directory` +The right to invoke [`path_remove_directory`](#path_remove_directory). + +- `path_unlink_file` +The right to invoke [`path_unlink_file`](#path_unlink_file). + +- `poll_fd_readwrite` +If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). +If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). + +- `sock_shutdown` +The right to invoke [`sock_shutdown`](#sock_shutdown). + +## `fd`: `u32` +A file descriptor index. + +## `iovec`: Struct +A region of memory for scatter/gather reads. + +### Struct members +- `buf`: `Pointer` +The address of the buffer to be filled. + +- `buf_len`: [`size`](#size) +The length of the buffer to be filled. + +## `ciovec`: Struct +A region of memory for scatter/gather writes. + +### Struct members +- `buf`: `ConstPointer` +The address of the buffer to be written. + +- `buf_len`: [`size`](#size) +The length of the buffer to be written. + +## `iovec_array`: `Array` + +## `ciovec_array`: `Array` + +## `filedelta`: `s64` +Relative offset within a file. + +## `whence`: Enum(`u8`) +The position relative to which to set the offset of the file descriptor. + +### Variants +- `cur` +Seek relative to current position. + +- `end` +Seek relative to end-of-file. + +- `set` +Seek relative to start-of-file. + +## `dircookie`: `u64` +A reference to the offset of a directory entry. + +## `dirnamlen`: `u32` +The type for the $d_namlen field of $dirent. + +## `inode`: `u64` +File serial number that is unique within its file system. + +## `filetype`: Enum(`u8`) +The type of a file descriptor or file. + +### Variants +- `unknown` +The type of the file descriptor or file is unknown or is different from any of the other types specified. + +- `block_device` +The file descriptor or file refers to a block device inode. + +- `character_device` +The file descriptor or file refers to a character device inode. + +- `directory` +The file descriptor or file refers to a directory inode. + +- `regular_file` +The file descriptor or file refers to a regular file inode. + +- `socket_dgram` +The file descriptor or file refers to a datagram socket. + +- `socket_stream` +The file descriptor or file refers to a byte-stream socket. + +- `symbolic_link` +The file refers to a symbolic link inode. + +## `dirent`: Struct +A directory entry. + +### Struct members +- `d_next`: [`dircookie`](#dircookie) +The offset of the next directory entry stored in this directory. + +- `d_ino`: [`inode`](#inode) +The serial number of the file referred to by this directory entry. + +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. + +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. + +## `advice`: Enum(`u8`) +File or memory access pattern advisory information. + +### Variants +- `normal` +The application has no advice to give on its behavior with respect to the specified data. + +- `sequential` +The application expects to access the specified data sequentially from lower offsets to higher offsets. + +- `random` +The application expects to access the specified data in a random order. + +- `willneed` +The application expects to access the specified data in the near future. + +- `dontneed` +The application expects that it will not access the specified data in the near future. + +- `noreuse` +The application expects to access the specified data once and then not reuse it thereafter. + +## `fdflags`: Flags(`u16`) +File descriptor flags. + +### Flags +- `append` +Append mode: Data written to the file is always appended to the file's end. + +- `dsync` +Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + +- `nonblock` +Non-blocking mode. + +- `rsync` +Synchronized read I/O operations. + +- `sync` +Write according to synchronized I/O file integrity completion. In +addition to synchronizing the data stored in the file, the implementation +may also synchronously update the file's metadata. + +## `fdstat`: Struct +File descriptor attributes. + +### Struct members +- `fs_filetype`: [`filetype`](#filetype) +File type. + +- `fs_flags`: [`fdflags`](#fdflags) +File descriptor flags. + +- `fs_rights_base`: [`rights`](#rights) +Rights that apply to this file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) +Maximum set of rights that may be installed on new file descriptors that +are created through this file descriptor, e.g., through [`path_open`](#path_open). + +## `device`: `u64` +Identifier for a device containing a file system. Can be used in combination +with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. + +## `fstflags`: Flags(`u16`) +Which file time attributes to adjust. + +### Flags +- `atim` +Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + +- `atim_now` +Adjust the last data access timestamp to the time of clock `clock::realtime`. + +- `mtim` +Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + +- `mtim_now` +Adjust the last data modification timestamp to the time of clock `clock::realtime`. + +## `lookupflags`: Flags(`u32`) +Flags determining the method of how paths are resolved. + +### Flags +- `symlink_follow` +As long as the resolved path corresponds to a symbolic link, it is expanded. + +## `oflags`: Flags(`u16`) +Open flags used by [`path_open`](#path_open). + +### Flags +- `creat` +Create file if it does not exist. + +- `directory` +Fail if not a directory. + +- `excl` +Fail if file already exists. + +- `trunc` +Truncate file to size 0. + +## `linkcount`: `u32` +Number of hard links to an inode. + +## `filestat`: Struct +File attributes. + +### Struct members +- `dev`: [`device`](#device) +Device ID of device containing the file. + +- `ino`: [`inode`](#inode) +File serial number. + +- `filetype`: [`filetype`](#filetype) +File type. + +- `nlink`: [`linkcount`](#linkcount) +Number of hard links to the file. + +- `size`: [`filesize`](#filesize) +For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + +- `atim`: [`timestamp`](#timestamp) +Last data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +Last data modification timestamp. + +- `ctim`: [`timestamp`](#timestamp) +Last file status change timestamp. + +## `userdata`: `u64` +User-provided value that may be attached to objects that is retained when +extracted from the implementation. + +## `eventtype`: Enum(`u8`) +Type of a subscription to an event or its occurrence. + +### Variants +- `clock` +The time value of clock `subscription::u.clock.clock_id` has +reached timestamp `subscription::u.clock.timeout`. + +- `fd_read` +File descriptor `subscription::u.fd_readwrite.fd` has data +available for reading. This event always triggers for regular files. + +- `fd_write` +File descriptor `subscription::u.fd_readwrite.fd` has capacity +available for writing. This event always triggers for regular files. + +## `eventrwflags`: Flags(`u16`) +The state of the file descriptor subscribed to with +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Flags +- `fd_readwrite_hangup` +The peer of this socket has closed or disconnected. + +## `event_fd_readwrite`: Struct +The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `nbytes`: [`filesize`](#filesize) +The number of bytes available for reading or writing. + +- `flags`: [`eventrwflags`](#eventrwflags) +The state of the file descriptor. + +## `event_u`: Union +The contents of an $event. + +### Union variants +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `event`: Struct +An event that occurred. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). + +- `error`: [`errno`](#errno) +If non-zero, an error that occurred while processing the subscription request. + +- `type`: [`eventtype`](#eventtype) +The type of the event that occurred. + +- `u`: [`event_u`](#event_u) +The contents of the event. + +## `subclockflags`: Flags(`u16`) +Flags determining how to interpret the timestamp provided in +`subscription::u.clock.timeout.` + +### Flags +- `subscription_clock_abstime` +If set, treat the timestamp provided in +`subscription::u.clock.timeout` as an absolute timestamp of clock +`subscription::u.clock.clock_id.` If clear, treat the timestamp +provided in `subscription::u.clock.timeout` relative to the +current time value of clock `subscription::u.clock.clock_id.` + +## `subscription_clock`: Struct +The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). + +### Struct members +- `identifier`: [`userdata`](#userdata) +The user-defined unique identifier of the clock. + +- `id`: [`clockid`](#clockid) +The clock against which to compare the timestamp. + +- `timeout`: [`timestamp`](#timestamp) +The absolute or relative timestamp. + +- `precision`: [`timestamp`](#timestamp) +The amount of time that the implementation may wait additionally +to coalesce with other events. + +- `flags`: [`subclockflags`](#subclockflags) +Flags specifying whether the timeout is absolute or relative + +## `subscription_fd_readwrite`: Struct +The contents of a $subscription when type is type is +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `file_descriptor`: [`fd`](#fd) +The file descriptor on which to wait for it to become ready for reading or writing. + +## `subscription_u`: Union +The contents of a $subscription. + +### Union variants +- `clock`: [`subscription_clock`](#subscription_clock) +When type is [`eventtype::clock`](#eventtype.clock): + +- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `subscription`: Struct +Subscription to an event. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that is attached to the subscription in the +implementation and returned through [`event::userdata`](#event.userdata). + +- `type`: [`eventtype`](#eventtype) +The type of the event to which to subscribe. + +- `u`: [`subscription_u`](#subscription_u) +The contents of the subscription. + +## `exitcode`: `u32` +Exit code generated by a process when exiting. + +## `signal`: Enum(`u8`) +Signal condition. + +### Variants +- `none` +No signal. Note that POSIX has special semantics for `kill(pid, 0)`, +so this value is reserved. + +- `hup` +Hangup. +Action: Terminates the process. + +- `int` +Terminate interrupt signal. +Action: Terminates the process. + +- `quit` +Terminal quit signal. +Action: Terminates the process. + +- `ill` +Illegal instruction. +Action: Terminates the process. + +- `trap` +Trace/breakpoint trap. +Action: Terminates the process. + +- `abrt` +Process abort signal. +Action: Terminates the process. + +- `bus` +Access to an undefined portion of a memory object. +Action: Terminates the process. + +- `fpe` +Erroneous arithmetic operation. +Action: Terminates the process. + +- `kill` +Kill. +Action: Terminates the process. + +- `usr1` +User-defined signal 1. +Action: Terminates the process. + +- `segv` +Invalid memory reference. +Action: Terminates the process. + +- `usr2` +User-defined signal 2. +Action: Terminates the process. + +- `pipe` +Write on a pipe with no one to read it. +Action: Ignored. + +- `alrm` +Alarm clock. +Action: Terminates the process. + +- `term` +Termination signal. +Action: Terminates the process. + +- `chld` +Child process terminated, stopped, or continued. +Action: Ignored. + +- `cont` +Continue executing, if stopped. +Action: Continues executing, if stopped. + +- `stop` +Stop executing. +Action: Stops executing. + +- `tstp` +Terminal stop signal. +Action: Stops executing. + +- `ttin` +Background process attempting read. +Action: Stops executing. + +- `ttou` +Background process attempting write. +Action: Stops executing. + +- `urg` +High bandwidth data is available at a socket. +Action: Ignored. + +- `xcpu` +CPU time limit exceeded. +Action: Terminates the process. + +- `xfsz` +File size limit exceeded. +Action: Terminates the process. + +- `vtalrm` +Virtual timer expired. +Action: Terminates the process. + +- `prof` +Profiling timer expired. +Action: Terminates the process. + +- `winch` +Window changed. +Action: Ignored. + +- `poll` +I/O possible. +Action: Terminates the process. + +- `pwr` +Power failure. +Action: Terminates the process. + +- `sys` +Bad system call. +Action: Terminates the process. + +## `riflags`: Flags(`u16`) +Flags provided to [`sock_recv`](#sock_recv). + +### Flags +- `recv_peek` +Returns the message without removing it from the socket's receive queue. + +- `recv_waitall` +On byte-stream sockets, block until the full amount of data can be returned. + +## `roflags`: Flags(`u16`) +Flags returned by [`sock_recv`](#sock_recv). + +### Flags +- `recv_data_truncated` +Returned by [`sock_recv`](#sock_recv): Message data has been truncated. + +## `siflags`: `u16` +Flags provided to [`sock_send`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +## `sdflags`: Flags(`u8`) +Which channels on a socket to shut down. + +### Flags +- `rd` +Disables further receive operations. + +- `wr` +Disables further send operations. + +## `preopentype`: Enum(`u8`) +Identifiers for preopened capabilities. + +### Variants +- `dir` +A pre-opened directory. + +## `prestat_dir`: Struct +The contents of a $prestat when type is `PREOPENTYPE_DIR`. + +### Struct members +- `pr_name_len`: [`size`](#size) +The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). + +## `prestat_u`: Union +The contents of an $prestat. + +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) +When type is `PREOPENTYPE_DIR`: + +## `prestat`: Struct +Information about a pre-opened capability. + +### Struct members +- `pr_type`: [`preopentype`](#preopentype) +The type of the pre-opened capability. + +- `u`: [`prestat_u`](#prestat_u) +The contents of the information. + +# Modules +## wasi_unstable +### Imports +#### Memory +### Functions + +--- + +#### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` +Read command-line argument data. +The size of the array should match that returned by `wasi_args_sizes_get()` + +##### Params +- `argv`: `Pointer>` + +- `argv_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `args_sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + + +--- + +#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` +Read environment variable data. +The sizes of the buffers should match that returned by `environ.sizes_get()`. + +##### Params +- `environ`: `Pointer>` + +- `environ_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `environ_sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + + +--- + +#### `clock_res_get(id: clockid) -> (errno, timestamp)` +Return the resolution of a clock. +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Note: This is similar to `clock_getres` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the resolution. + +##### Results +- `error`: [`errno`](#errno) + +- `resolution`: [`timestamp`](#timestamp) +The resolution of the clock. + + +--- + +#### `clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +Return the time value of a clock. +Note: This is similar to `clock_gettime` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the time. + +- `precision`: [`timestamp`](#timestamp) +The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + +##### Results +- `error`: [`errno`](#errno) + +- `time`: [`timestamp`](#timestamp) +The time value of the clock. + + +--- + +#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +Provide file advisory information on a file descriptor. +Note: This is similar to `posix_fadvise` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset within the file to which the advisory applies. + +- `len`: [`filesize`](#filesize) +The length of the region to which the advisory applies. + +- `advice`: [`advice`](#advice) +The advice. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno` +Force the allocation of space in a file. +Note: This is similar to `posix_fallocate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset at which to start the allocation. + +- `len`: [`filesize`](#filesize) +The length of the area that is allocated. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_close(fd: fd) -> errno` +Close a file descriptor. +Note: This is similar to `close` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_datasync(fd: fd) -> errno` +Synchronize the data of a file to disk. +Note: This is similar to `fdatasync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_fdstat_get(fd: fd) -> (errno, fdstat)` +Get the attributes of a file descriptor. +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `stat`: [`fdstat`](#fdstat) +The buffer where the file descriptor's attributes are stored. + + +--- + +#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +Adjust the flags associated with a file descriptor. +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`fdflags`](#fdflags) +The desired values of the file descriptor flags. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +Adjust the rights associated with a file descriptor. +This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + +##### Params +- `fd`: [`fd`](#fd) + +- `fs_rights_base`: [`rights`](#rights) +The desired rights of the file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_filestat_get(fd: fd) -> (errno, filestat)` +Return the attributes of an open file. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `fd_filestat_set_size(fd: fd, size: filesize) -> errno` +Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. +Note: This is similar to `ftruncate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `size`: [`filesize`](#filesize) +The desired file size. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of an open file or directory. +Note: This is similar to `futimens` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +Read from a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `preadv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors in which to store data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to read. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `fd_prestat_get(fd: fd) -> (errno, prestat)` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`prestat`](#prestat) +The buffer where the description is stored. + + +--- + +#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `Pointer` +A buffer into which to write the preopened directory name. + +- `path_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +Write to a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `pwritev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to write. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `fd_read(fd: fd, iovs: iovec_array) -> (errno, size)` +Read from a file descriptor. +Note: This is similar to `readv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +Read directory entries from a directory. +When successful, the contents of the output buffer consist of a sequence of +directory entries. Each directory entry consists of a dirent_t object, +followed by dirent_t::d_namlen bytes holding the name of the directory +entry. +This function fills the output buffer as much as possible, potentially +truncating the last directory entry. This allows the caller to grow its +read buffer size in case it's too small to fit a single large directory +entry, or skip the oversized directory entry. + +##### Params +- `fd`: [`fd`](#fd) + +- `buf`: `Pointer` +The buffer where directory entries are stored + +- `buf_len`: [`size`](#size) + +- `cookie`: [`dircookie`](#dircookie) +The location within the directory to start reading + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + + +--- + +#### `fd_renumber(fd: fd, to: fd) -> errno` +Atomically replace a file descriptor by renumbering another file descriptor. +Due to the strong focus on thread safety, this environment does not provide +a mechanism to duplicate or renumber a file descriptor to an arbitrary +number, like `dup2()`. This would be prone to race conditions, as an actual +file descriptor with the same number could be allocated by a different +thread at the same time. +This function provides a way to atomically renumber file descriptors, which +would disappear if `dup2()` were to be removed entirely. + +##### Params +- `fd`: [`fd`](#fd) + +- `to`: [`fd`](#fd) +The file descriptor to overwrite. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +Move the offset of a file descriptor. +Note: This is similar to `lseek` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filedelta`](#filedelta) +The number of bytes to move. + +- `whence`: [`whence`](#whence) +The base from which the offset is relative. + +##### Results +- `error`: [`errno`](#errno) + +- `newoffset`: [`filesize`](#filesize) +The new offset of the file descriptor, relative to the start of the file. + + +--- + +#### `fd_sync(fd: fd) -> errno` +Synchronize the data and metadata of a file to disk. +Note: This is similar to `fsync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_tell(fd: fd) -> (errno, filesize)` +Return the current offset of a file descriptor. +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `offset`: [`filesize`](#filesize) +The current offset of the file descriptor, relative to the start of the file. + + +--- + +#### `fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)` +Write to a file descriptor. +Note: This is similar to `writev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `path_create_directory(fd: fd, path: string) -> errno` +Create a directory. +Note: This is similar to `mkdirat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path at which to create the directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +Return the attributes of a file or directory. +Note: This is similar to `stat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to inspect. + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of a file or directory. +Note: This is similar to `utimensat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to operate on. + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +Create a hard link. +Note: This is similar to `linkat` in POSIX. + +##### Params +- `old_fd`: [`fd`](#fd) + +- `old_flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `old_path`: `string` +The source path from which to link. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path at which to create the hard link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)` +Open a file or directory. +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since this +is error-prone in multi-threaded contexts. The returned file descriptor is +guaranteed to be less than 2**31. +Note: This is similar to `openat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `dirflags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The relative path of the file or directory to open, relative to the +`dirfd` directory. + +- `oflags`: [`oflags`](#oflags) +The method by which to open the file. + +- `fs_rights_base`: [`rights`](#rights) +The initial rights of the newly created file descriptor. The +implementation is allowed to return a file descriptor with fewer rights +than specified, if and only if those rights do not apply to the type of +file being opened. +The *base* rights are rights that will apply to operations using the file +descriptor itself, while the *inheriting* rights are rights that apply to +file descriptors derived from it. + +- `fs_rights_inherting`: [`rights`](#rights) + +- `fdflags`: [`fdflags`](#fdflags) + +##### Results +- `error`: [`errno`](#errno) + +- `opened_fd`: [`fd`](#fd) +The file descriptor of the file that has been opened. + + +--- + +#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +Read the contents of a symbolic link. +Note: This is similar to `readlinkat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path of the symbolic link from which to read. + +- `buf`: `Pointer` +The buffer to which to write the contents of the symbolic link. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes placed in the buffer. + + +--- + +#### `path_remove_directory(fd: fd, path: string) -> errno` +Remove a directory. +Return `ENOTEMPTY` if the directory is not empty. +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a directory to remove. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +Rename a file or directory. +Note: This is similar to `renameat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `old_path`: `string` +The source path of the file or directory to rename. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path to which to rename the file or directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_symlink(old_path: string, fd: fd, new_path: string) -> errno` +Create a symbolic link. +Note: This is similar to `symlinkat` in POSIX. + +##### Params +- `old_path`: `string` +The contents of the symbolic link. + +- `fd`: [`fd`](#fd) + +- `new_path`: `string` +The destination path at which to create the symbolic link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_unlink_file(fd: fd, path: string) -> errno` +Unlink a file. +Return `EISDIR` if the path refers to a directory. +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a file to unlink. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +Concurrently poll for the occurrence of a set of events. + +##### Params +- `in`: `ConstPointer` +The events to which to subscribe. + +- `out`: `Pointer` +The events that have occurred. + +- `nsubscriptions`: [`size`](#size) +Both the number of subscriptions and events. + +##### Results +- `error`: [`errno`](#errno) + +- `nevents`: [`size`](#size) +The number of events stored. + + +--- + +#### `proc_exit(rval: exitcode)` +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +##### Params +- `rval`: [`exitcode`](#exitcode) +The exit code returned by the process. + +##### Results + +--- + +#### `proc_raise(sig: signal) -> errno` +Send a signal to the process of the calling thread. +Note: This is similar to `raise` in POSIX. + +##### Params +- `sig`: [`signal`](#signal) +The signal condition to trigger. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sched_yield() -> errno` +Temporarily yield execution of the calling thread. +Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. + +##### Params +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `random_get(buf: Pointer, buf_len: size) -> errno` +Write high-quality random data into a buffer. +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. +This function may execute slowly, so when large mounts of random data are +required, it's advisable to use this function to seed a pseudo-random +number generator, rather than to provide the random data directly. + +##### Params +- `buf`: `Pointer` +The buffer to fill with random data. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +Receive a message from a socket. +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +##### Params +- `fd`: [`fd`](#fd) + +- `ri_data`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +- `ri_flags`: [`riflags`](#riflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `ro_datalen`: [`size`](#size) +Number of bytes stored in ri_data. + +- `ro_flags`: [`roflags`](#roflags) +Message flags. + + +--- + +#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +Send a message on a socket. +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +##### Params +- `fd`: [`fd`](#fd) + +- `si_data`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors to which to retrieve data + +- `si_flags`: [`siflags`](#siflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `so_datalen`: [`size`](#size) +Number of bytes transmitted. + + +--- + +#### `sock_shutdown(fd: fd, how: sdflags) -> errno` +Shut down socket send and receive channels. +Note: This is similar to `shutdown` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `how`: [`sdflags`](#sdflags) +Which channels on the socket to shut down. + +##### Results +- `error`: [`errno`](#errno) + diff --git a/proposals/random/phases/old/snapshot_0/docs/wasi_unstable.md b/proposals/random/phases/old/snapshot_0/docs/wasi_unstable.md deleted file mode 100644 index 2464f2342..000000000 --- a/proposals/random/phases/old/snapshot_0/docs/wasi_unstable.md +++ /dev/null @@ -1,2343 +0,0 @@ - - -# The WASI Preview API - -This is the API-level documentation for WASI Preview. The function names -are prefixed with "\_\_wasi\_" to reflect how they are spelled in -flat-namespace contexts, however at the wasm module level, they are -unprefixed, because they're inside a module namespace. - -Functions that start with `__wasi_fd_` operate on file descriptors, -while functions that start with `__wasi_path_` operate on filesystem -paths, which are relative to directory file descriptors. - -Much inspiration and content here is derived from [CloudABI] and [POSIX], -though there are also several differences from CloudABI and POSIX. For -example, WASI Preview has no concept of processes in the traditional Unix -sense. While wasm linear memories have some of the aspects of processes, -and it's possible to *emulate* the full semantics of processes on top of -them, this can sometimes be unnatural and inefficient. The goal for -WASI Preview is to be a WebAssembly-native API that exposes APIs that fit -well into the underlying WebAssembly platform, rather than to directly -emulate other platforms. - -This is also a work in progress, and the API here is still evolving. - -Historical note: this API was originally named "WASI Core", and used the -API module name "wasi\_unstable". We've since sought to deemphasize the -"Core" name, as the goal is to split this API up into independent -modules so that embedders need not implement all of it. - -[CloudABI]: https://github.com/NuxiNL/cloudabi -[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ - -## System calls - -- [`__wasi_args_get()`](#args_get) -- [`__wasi_args_sizes_get()`](#args_sizes_get) -- [`__wasi_clock_res_get()`](#clock_res_get) -- [`__wasi_clock_time_get()`](#clock_time_get) -- [`__wasi_environ_get()`](#environ_get) -- [`__wasi_environ_sizes_get()`](#environ_sizes_get) -- [`__wasi_fd_advise()`](#fd_advise) -- [`__wasi_fd_allocate()`](#fd_allocate) -- [`__wasi_fd_close()`](#fd_close) -- [`__wasi_fd_datasync()`](#fd_datasync) -- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) -- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) -- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) -- [`__wasi_fd_filestat_get()`](#fd_filestat_get) -- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) -- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) -- [`__wasi_fd_pread()`](#fd_pread) -- [`__wasi_fd_prestat_get()`](#fd_prestat_get) -- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) -- [`__wasi_fd_pwrite()`](#fd_pwrite) -- [`__wasi_fd_read()`](#fd_read) -- [`__wasi_fd_readdir()`](#fd_readdir) -- [`__wasi_fd_renumber()`](#fd_renumber) -- [`__wasi_fd_seek()`](#fd_seek) -- [`__wasi_fd_sync()`](#fd_sync) -- [`__wasi_fd_tell()`](#fd_tell) -- [`__wasi_fd_write()`](#fd_write) -- [`__wasi_path_create_directory()`](#path_create_directory) -- [`__wasi_path_filestat_get()`](#path_filestat_get) -- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) -- [`__wasi_path_link()`](#path_link) -- [`__wasi_path_open()`](#path_open) -- [`__wasi_path_readlink()`](#path_readlink) -- [`__wasi_path_remove_directory()`](#path_remove_directory) -- [`__wasi_path_rename()`](#path_rename) -- [`__wasi_path_symlink()`](#path_symlink) -- [`__wasi_path_unlink_file()`](#path_unlink_file) -- [`__wasi_poll_oneoff()`](#poll_oneoff) -- [`__wasi_proc_exit()`](#proc_exit) -- [`__wasi_proc_raise()`](#proc_raise) -- [`__wasi_random_get()`](#random_get) -- [`__wasi_sched_yield()`](#sched_yield) -- [`__wasi_sock_recv()`](#sock_recv) -- [`__wasi_sock_send()`](#sock_send) -- [`__wasi_sock_shutdown()`](#sock_shutdown) - -### `__wasi_args_get()` - -Read command-line argument data. - -The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - -Inputs: - -- char \*\*argv - - A pointer to a buffer to write the argument pointers. - -- char \*argv\_buf - - A pointer to a buffer to write the argument string data. - -### `__wasi_args_sizes_get()` - -Return command-line argument data sizes. - -Outputs: - -- size\_t \*argc - - The number of arguments. - -- size\_t \*argv\_buf\_size - - The size of the argument string data. - -### `__wasi_clock_res_get()` - -Return the resolution of a clock. - -Implementations are required to provide a non-zero value for supported clocks. -For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). - -Note: This is similar to `clock_getres` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the resolution. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) resolution - - The resolution of the clock. - -### `__wasi_clock_time_get()` - -Return the time value of a clock. - -Note: This is similar to `clock_gettime` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the time. - -- [\_\_wasi\_timestamp\_t](#timestamp) precision - - The maximum lag (exclusive) that the returned - time value may have, compared to its actual - value. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) time - - The time value of the clock. - -### `__wasi_environ_get()` - -Read environment variable data. - -The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - -Inputs: - -- char \*\*environ - - A pointer to a buffer to write the environment variable pointers. - -- char \*environ\_buf - - A pointer to a buffer to write the environment variable string data. - -### `__wasi_environ_sizes_get()` - -Return command-line argument data sizes. - -Outputs: - -- size\_t \*environ\_count - - The number of environment variables. - -- size\_t \*environ\_buf\_size - - The size of the environment variable string data. - -### `__wasi_fd_advise()` - -Provide file advisory information on a file descriptor. - -Note: This is similar to `posix_fadvise` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file for which to provide file advisory information. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file to which the advisory applies. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the region to which the advisory applies. - -- [\_\_wasi\_advice\_t](#advice) advice - - The advice. - -### `__wasi_fd_allocate()` - -Force the allocation of space in a file. - -Note: This is similar to `posix_fallocate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file in which to allocate space. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset at which to start the allocation. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the area that is allocated. - -### `__wasi_fd_close()` - -Close a file descriptor. - -Note: This is similar to `close` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to close. - -### `__wasi_fd_datasync()` - -Synchronize the data of a file to disk. - -Note: This is similar to `fdatasync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file to synchronize to disk. - -### `__wasi_fd_fdstat_get()` - -Get the attributes of a file descriptor. - -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well -as additional fields. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_fdstat\_t](#fdstat) \*buf - - The buffer where the file descriptor's attributes are stored. - -### `__wasi_fd_fdstat_set_flags()` - -Adjust the flags associated with a file descriptor. - -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_fdflags\_t](#fdflags) flags - - The desired values of the file descriptor - flags. - -### `__wasi_fd_fdstat_set_rights()` - -Adjust the rights associated with a file descriptor. - -This can only be used to remove rights, and returns -[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt -to add rights. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The desired rights of the file descriptor. - -### `__wasi_fd_filestat_get()` - -Return the attributes of an open file. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_fd_filestat_set_size()` - -Adjust the size of an open file. If this increases the file's size, the extra -bytes are filled with zeros. - -Note: This is similar to `ftruncate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - A file descriptor for the file to adjust. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - The desired file size. - -### `__wasi_fd_filestat_set_times()` - -Adjust the timestamps of an open file or directory. - -Note: This is similar to `futimens` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_fd_pread()` - -Read from a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `preadv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors in which to store data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to read. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_prestat_get()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- [\_\_wasi\_prestat\_t](#prestat) \*buf - - The buffer where the description is stored. - -### `__wasi_fd_prestat_dir_name()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- const char \*path and size\_t path\_len - - A buffer into which to write the preopened directory name. - -### `__wasi_fd_pwrite()` - -Write to a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `pwritev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to write. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_fd_read()` - -Read from a file descriptor. - -Note: This is similar to `readv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors to which to store data. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_readdir()` - -Read directory entries from a directory. - -When successful, the contents of the output buffer consist of -a sequence of directory entries. Each directory entry consists -of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes -holding the name of the directory entry. - -This function fills the output buffer as much as possible, -potentially truncating the last directory entry. This allows -the caller to grow its read buffer size in case it's too small -to fit a single large directory entry, or skip the oversized -directory entry. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The directory from which to read the directory - entries. - -- void \*buf and size\_t buf\_len - - The buffer where directory entries are stored. - -- [\_\_wasi\_dircookie\_t](#dircookie) cookie - - The location within the directory to start - reading. - -Outputs: - -- size\_t bufused - - The number of bytes stored in the read buffer. - If less than the size of the read buffer, the - end of the directory has been reached. - -### `__wasi_fd_renumber()` - -Atomically replace a file descriptor by renumbering another -file descriptor. - -Due to the strong focus on thread safety, this environment -does not provide a mechanism to duplicate or renumber a file -descriptor to an arbitrary number, like dup2(). This would be -prone to race conditions, as an actual file descriptor with the -same number could be allocated by a different thread at the same -time. - -This function provides a way to atomically renumber file -descriptors, which would disappear if dup2() were to be -removed entirely. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) from - - The file descriptor to renumber. - -- [\_\_wasi\_fd\_t](#fd) to - - The file descriptor to overwrite. - -### `__wasi_fd_seek()` - -Move the offset of a file descriptor. - -Note: This is similar to `lseek` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_filedelta\_t](#filedelta) offset - - The number of bytes to move. - -- [\_\_wasi\_whence\_t](#whence) whence - - The base from which the offset is relative. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) newoffset - - The new offset of the file descriptor, - relative to the start of the file. - -### `__wasi_fd_sync()` - -Synchronize the data and metadata of a file to disk. - -Note: This is similar to `fsync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file containing the data - and metadata to synchronize to disk. - -### `__wasi_fd_tell()` - -Return the current offset of a file descriptor. - -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The current offset of the file descriptor, relative to the start of the file. - -### `__wasi_fd_write()` - -Write to a file descriptor. - -Note: This is similar to `writev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_path_create_directory()` - -Create a directory. - -Note: This is similar to `mkdirat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path at which to create the directory. - -### `__wasi_path_filestat_get()` - -Return the attributes of a file or directory. - -Note: This is similar to `stat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_path_filestat_set_times()` - -Adjust the timestamps of a file or directory. - -Note: This is similar to `utimensat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_path_link()` - -Create a hard link. - -Note: This is similar to `linkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags - - Flags determining the method of how the path is resolved. - -- const char \*old\_path and size\_t old\_path\_len - - The source path from which to link. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the hard link. - -### `__wasi_path_open()` - -Open a file or directory. - -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since -this is error-prone in multi-threaded contexts. The returned file -descriptor is guaranteed to be less than 231. - -Note: This is similar to `openat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) dirfd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The relative path of the file or directory to open, relative to - the [`dirfd`](#path_open.dirfd) directory. - -- [\_\_wasi\_oflags\_t](#oflags) o_flags - - The method by which to open the file. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The initial rights of the newly created file descriptor. The - implementation is allowed to return a file descriptor with fewer - rights than specified, if and only if those rights do not apply - to the type of file being opened. - - The *base* rights are rights that will apply to operations using - the file descriptor itself, while the *inheriting* rights are - rights that apply to file descriptors derived from it. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - The initial flags of the file descriptor. - -Outputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file that has been - opened. - -### `__wasi_path_readlink()` - -Read the contents of a symbolic link. - -Note: This is similar to `readlinkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path of the symbolic link from which to read. - -- char \*buf and size\_t buf\_len - - The buffer to which to write the contents of the symbolic link. - -Outputs: - -- size\_t bufused - - The number of bytes placed in the buffer. - -### `__wasi_path_remove_directory()` - -Remove a directory. - -Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. - -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a directory to remove. - -### `__wasi_path_rename()` - -Rename a file or directory. - -Note: This is similar to `renameat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- const char \*old\_path and size\_t old\_path\_len - - The source path of the file or directory to rename. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path to which to rename the file or directory. - -### `__wasi_path_symlink()` - -Create a symbolic link. - -Note: This is similar to `symlinkat` in POSIX. - -Inputs: - -- const char \*old\_path and size\_t old_path\_len - - The contents of the symbolic link. - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the symbolic link. - -### `__wasi_path_unlink_file()` - -Unlink a file. - -Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. - -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a file to unlink. - -### `__wasi_poll_oneoff()` - -Concurrently poll for the occurrence of a set of events. - -Inputs: - -- const [\_\_wasi\_subscription\_t](#subscription) \*in - - The events to which to subscribe. - -- [\_\_wasi\_event\_t](#event) \*out - - The events that have occurred. - -- size\_t nsubscriptions - - Both the number of subscriptions and events. - -Outputs: - -- size\_t nevents - - The number of events stored. - -### `__wasi_proc_exit()` - -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -Note: This is similar to `_Exit` in POSIX. - -Inputs: - -- [\_\_wasi\_exitcode\_t](#exitcode) rval - - The exit code returned by the process. - -Does not return. - -### `__wasi_proc_raise()` - -Send a signal to the process of the calling thread. - -Note: This is similar to `raise` in POSIX. - -Inputs: - -- [\_\_wasi\_signal\_t](#signal) sig - - The signal condition to trigger. - -### `__wasi_random_get()` - -Write high-quality random data into a buffer. - -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. - -This function may execute slowly, so when large mounts of random -data are required, it's advisable to use this function to seed a -pseudo-random number generator, rather than to provide the -random data directly. - -Inputs: - -- void \*buf and size\_t buf\_len - - The buffer to fill with random data. - -### `__wasi_sched_yield()` - -Temporarily yield execution of the calling thread. - -Note: This is similar to `sched_yield` in POSIX. - -### `__wasi_sock_recv()` - -Receive a message from a socket. - -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to receive data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len - - List of scatter/gather vectors to which to store data. - -- [\_\_wasi\_riflags\_t](#riflags) ri\_flags - - Message flags. - -Outputs: - -- size\_t ro\_datalen - - Number of bytes stored in [`ri_data`](#sock_recv.ri_data). - -- [\_\_wasi\_roflags\_t](#roflags) ro\_flags - - Message flags. - -### `__wasi_sock_send()` - -Send a message on a socket. - -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to send data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len - - List of scatter/gather vectors to which to retrieve data - -- [\_\_wasi\_siflags\_t](#siflags) si\_flags - - Message flags. - -Outputs: - -- size\_t so\_datalen - - Number of bytes transmitted. - -### `__wasi_sock_shutdown()` - -Shut down socket send and receive channels. - -Note: This is similar to `shutdown` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to shutdown channels. - -- [\_\_wasi\_sdflags\_t](#sdflags) how - - Which channels on the socket to shut down. - -## Types - -### `__wasi_advice_t` (`uint8_t`) - -File or memory access pattern advisory information. - -Used by [`__wasi_fd_advise()`](#fd_advise). - -Possible values: - -- **`__WASI_ADVICE_NORMAL`** - - The application has no advice to give on its behavior - with respect to the specified data. - -- **`__WASI_ADVICE_SEQUENTIAL`** - - The application expects to access the specified data - sequentially from lower offsets to higher offsets. - -- **`__WASI_ADVICE_RANDOM`** - - The application expects to access the specified data - in a random order. - -- **`__WASI_ADVICE_WILLNEED`** - - The application expects to access the specified data - in the near future. - -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - -### `__wasi_ciovec_t` (`struct`) - -A region of memory for scatter/gather writes. - -Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). - -Members: - -- const void \*buf and size\_t buf\_len - - The address and length of the buffer to be written. - -### `__wasi_clockid_t` (`uint32_t`) - -Identifiers for clocks. - -Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). - -Possible values: - -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - -- **`__WASI_CLOCK_MONOTONIC`** - - The store-wide monotonic clock, which is defined as a - clock measuring real time, whose value cannot be - adjusted and which cannot have negative clock jumps. - - The epoch of this clock is undefined. The absolute - time value of this clock therefore has no meaning. - -- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** - - The CPU-time clock associated with the current - process. - -- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** - - The CPU-time clock associated with the current thread. - -### `__wasi_device_t` (`uint64_t`) - -Identifier for a device containing a file system. Can be used -in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or -directory in the filesystem. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_dircookie_t` (`uint64_t`) - -A reference to the offset of a directory entry. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). - -Special values: - -- **`__WASI_DIRCOOKIE_START`** - - Permanent reference to the first directory entry - within a directory. - -### `__wasi_dirent_t` (`struct`) - -A directory entry. - -Members: - -- [\_\_wasi\_dircookie\_t](#dircookie) d\_next - - The offset of the next directory entry stored in this - directory. - -- [\_\_wasi\_inode\_t](#inode) d\_ino - - The serial number of the file referred to by this - directory entry. - -- uint32\_t d\_namlen - - The length of the name of the directory entry. - -- [\_\_wasi\_filetype\_t](#filetype) d\_type - - The type of the file referred to by this directory - entry. - -### `__wasi_errno_t` (`uint16_t`) - -Error codes returned by functions. - -Not all of these error codes are returned by the functions -provided by this API; some are used in higher-level library layers, -and others are provided merely for alignment with POSIX. - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_ESUCCESS`** - - No error occurred. System call completed successfully. - -- **`__WASI_E2BIG`** - - Argument list too long. - -- **`__WASI_EACCES`** - - Permission denied. - -- **`__WASI_EADDRINUSE`** - - Address in use. - -- **`__WASI_EADDRNOTAVAIL`** - - Address not available. - -- **`__WASI_EAFNOSUPPORT`** - - Address family not supported. - -- **`__WASI_EAGAIN`** - - Resource unavailable, or operation would block. - -- **`__WASI_EALREADY`** - - Connection already in progress. - -- **`__WASI_EBADF`** - - Bad file descriptor. - -- **`__WASI_EBADMSG`** - - Bad message. - -- **`__WASI_EBUSY`** - - Device or resource busy. - -- **`__WASI_ECANCELED`** - - Operation canceled. - -- **`__WASI_ECHILD`** - - No child processes. - -- **`__WASI_ECONNABORTED`** - - Connection aborted. - -- **`__WASI_ECONNREFUSED`** - - Connection refused. - -- **`__WASI_ECONNRESET`** - - Connection reset. - -- **`__WASI_EDEADLK`** - - Resource deadlock would occur. - -- **`__WASI_EDESTADDRREQ`** - - Destination address required. - -- **`__WASI_EDOM`** - - Mathematics argument out of domain of function. - -- **`__WASI_EDQUOT`** - - Reserved. - -- **`__WASI_EEXIST`** - - File exists. - -- **`__WASI_EFAULT`** - - Bad address. - -- **`__WASI_EFBIG`** - - File too large. - -- **`__WASI_EHOSTUNREACH`** - - Host is unreachable. - -- **`__WASI_EIDRM`** - - Identifier removed. - -- **`__WASI_EILSEQ`** - - Illegal byte sequence. - -- **`__WASI_EINPROGRESS`** - - Operation in progress. - -- **`__WASI_EINTR`** - - Interrupted function. - -- **`__WASI_EINVAL`** - - Invalid argument. - -- **`__WASI_EIO`** - - I/O error. - -- **`__WASI_EISCONN`** - - Socket is connected. - -- **`__WASI_EISDIR`** - - Is a directory. - -- **`__WASI_ELOOP`** - - Too many levels of symbolic links. - -- **`__WASI_EMFILE`** - - File descriptor value too large. - -- **`__WASI_EMLINK`** - - Too many links. - -- **`__WASI_EMSGSIZE`** - - Message too large. - -- **`__WASI_EMULTIHOP`** - - Reserved. - -- **`__WASI_ENAMETOOLONG`** - - Filename too long. - -- **`__WASI_ENETDOWN`** - - Network is down. - -- **`__WASI_ENETRESET`** - - Connection aborted by network. - -- **`__WASI_ENETUNREACH`** - - Network unreachable. - -- **`__WASI_ENFILE`** - - Too many files open in system. - -- **`__WASI_ENOBUFS`** - - No buffer space available. - -- **`__WASI_ENODEV`** - - No such device. - -- **`__WASI_ENOENT`** - - No such file or directory. - -- **`__WASI_ENOEXEC`** - - Executable file format error. - -- **`__WASI_ENOLCK`** - - No locks available. - -- **`__WASI_ENOLINK`** - - Reserved. - -- **`__WASI_ENOMEM`** - - Not enough space. - -- **`__WASI_ENOMSG`** - - No message of the desired type. - -- **`__WASI_ENOPROTOOPT`** - - Protocol not available. - -- **`__WASI_ENOSPC`** - - No space left on device. - -- **`__WASI_ENOSYS`** - - Function not supported. - -- **`__WASI_ENOTCONN`** - - The socket is not connected. - -- **`__WASI_ENOTDIR`** - - Not a directory or a symbolic link to a directory. - -- **`__WASI_ENOTEMPTY`** - - Directory not empty. - -- **`__WASI_ENOTRECOVERABLE`** - - State not recoverable. - -- **`__WASI_ENOTSOCK`** - - Not a socket. - -- **`__WASI_ENOTSUP`** - - Not supported, or operation not supported on socket. - -- **`__WASI_ENOTTY`** - - Inappropriate I/O control operation. - -- **`__WASI_ENXIO`** - - No such device or address. - -- **`__WASI_EOVERFLOW`** - - Value too large to be stored in data type. - -- **`__WASI_EOWNERDEAD`** - - Previous owner died. - -- **`__WASI_EPERM`** - - Operation not permitted. - -- **`__WASI_EPIPE`** - - Broken pipe. - -- **`__WASI_EPROTO`** - - Protocol error. - -- **`__WASI_EPROTONOSUPPORT`** - - Protocol not supported. - -- **`__WASI_EPROTOTYPE`** - - Protocol wrong type for socket. - -- **`__WASI_ERANGE`** - - Result too large. - -- **`__WASI_EROFS`** - - Read-only file system. - -- **`__WASI_ESPIPE`** - - Invalid seek. - -- **`__WASI_ESRCH`** - - No such process. - -- **`__WASI_ESTALE`** - - Reserved. - -- **`__WASI_ETIMEDOUT`** - - Connection timed out. - -- **`__WASI_ETXTBSY`** - - Text file busy. - -- **`__WASI_EXDEV`** - - Cross-device link. - -- **`__WASI_ENOTCAPABLE`** - - Extension: Capabilities insufficient. - -### `__wasi_event_t` (`struct`) - -An event that occurred. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that got attached to - [`__wasi_subscription_t::userdata`](#subscription.userdata). - -- [\_\_wasi\_errno\_t](#errno) error - - If non-zero, an error that occurred while processing - the subscription request. - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event that occurred. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_filesize\_t](#filesize) nbytes - - The number of bytes available for reading or writing. - - - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags - - The state of the file descriptor. - -### `__wasi_eventrwflags_t` (`uint16_t` bitfield) - -The state of the file descriptor subscribed to with -[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_EVENT_FD_READWRITE_HANGUP`** - - The peer of this socket has closed or disconnected. - -### `__wasi_eventtype_t` (`uint8_t`) - -Type of a subscription to an event or its occurrence. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_EVENTTYPE_CLOCK`** - - The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) - has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -- **`__WASI_EVENTTYPE_FD_READ`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - data available for reading. This event always triggers - for regular files. - -- **`__WASI_EVENTTYPE_FD_WRITE`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - capacity available for writing. This event always - triggers for regular files. - -### `__wasi_exitcode_t` (`uint32_t`) - -Exit code generated by a process when exiting. - -Used by [`__wasi_proc_exit()`](#proc_exit). - -### `__wasi_fd_t` (`uint32_t`) - -A file descriptor number. - -Used by many functions in this API. - -As in POSIX, three file descriptor numbers are provided to instances -on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, -and `STDERR_FILENO`). - -Other than these, WASI implementations are not required to allocate -new file descriptors in ascending order. - -### `__wasi_fdflags_t` (`uint16_t` bitfield) - -File descriptor flags. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_FDFLAG_APPEND`** - - Append mode: Data written to the file is always - appended to the file's end. - -- **`__WASI_FDFLAG_DSYNC`** - - Write according to synchronized I/O data integrity - completion. Only the data stored in the file is - synchronized. - -- **`__WASI_FDFLAG_NONBLOCK`** - - Non-blocking mode. - -- **`__WASI_FDFLAG_RSYNC`** - - Synchronized read I/O operations. - -- **`__WASI_FDFLAG_SYNC`** - - Write according to synchronized I/O file integrity completion. - In addition to synchronizing the data stored in the file, the - implementation may also synchronously update the file's metadata. - -### `__wasi_fdstat_t` (`struct`) - -File descriptor attributes. - -Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). - -Members: - -- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype - - File type. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - File descriptor flags. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base - - Rights that apply to this file descriptor. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - Maximum set of rights that may be installed on new - file descriptors that are created through this file - descriptor, e.g., through [`__wasi_path_open()`](#path_open). - -### `__wasi_filedelta_t` (`int64_t`) - -Relative offset within a file. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -### `__wasi_filesize_t` (`uint64_t`) - -Non-negative file size or length of a region within a file. - -Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -### `__wasi_filestat_t` (`struct`) - -File attributes. - -Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). - -Members: - -- [\_\_wasi\_device\_t](#device) st\_dev - - Device ID of device containing the file. - -- [\_\_wasi\_inode\_t](#inode) st\_ino - - File serial number. - -- [\_\_wasi\_filetype\_t](#filetype) st\_filetype - - File type. - -- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink - - Number of hard links to the file. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - For regular files, the file size in bytes. For - symbolic links, the length in bytes of the pathname - contained in the symbolic link. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - Last data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - Last data modification timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim - - Last file status change timestamp. - -### `__wasi_filetype_t` (`uint8_t`) - -The type of a file descriptor or file. - -Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). - -Possible values: - -- **`__WASI_FILETYPE_UNKNOWN`** - - The type of the file descriptor or file is unknown or - is different from any of the other types specified. - -- **`__WASI_FILETYPE_BLOCK_DEVICE`** - - The file descriptor or file refers to a block device - inode. - -- **`__WASI_FILETYPE_CHARACTER_DEVICE`** - - The file descriptor or file refers to a character - device inode. - -- **`__WASI_FILETYPE_DIRECTORY`** - - The file descriptor or file refers to a directory - inode. - -- **`__WASI_FILETYPE_REGULAR_FILE`** - - The file descriptor or file refers to a regular file - inode. - -- **`__WASI_FILETYPE_SOCKET_DGRAM`** - - The file descriptor or file refers to a datagram - socket. - -- **`__WASI_FILETYPE_SOCKET_STREAM`** - - The file descriptor or file refers to a byte-stream - socket. - -- **`__WASI_FILETYPE_SYMBOLIC_LINK`** - - The file refers to a symbolic link inode. - -### `__wasi_fstflags_t` (`uint16_t` bitfield) - -Which file time attributes to adjust. - -Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -Possible values: - -- **`__WASI_FILESTAT_SET_ATIM`** - - Adjust the last data access timestamp to the value - stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). - -- **`__WASI_FILESTAT_SET_ATIM_NOW`** - - Adjust the last data access timestamp to the time - of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -- **`__WASI_FILESTAT_SET_MTIM`** - - Adjust the last data modification timestamp to the - value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). - -- **`__WASI_FILESTAT_SET_MTIM_NOW`** - - Adjust the last data modification timestamp to the - time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -### `__wasi_inode_t` (`uint64_t`) - -File serial number that is unique within its file system. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). - -### `__wasi_iovec_t` (`struct`) - -A region of memory for scatter/gather reads. - -Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). - -Members: - -- void \*buf and size\_t buf\_len - - The address and length of the buffer to be filled. - -### `__wasi_linkcount_t` (`uint32_t`) - -Number of hard links to an inode. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_lookupflags_t` (`uint32_t` bitfield) - -Flags determining the method of how paths are resolved. - -Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** - - As long as the resolved path corresponds to a symbolic - link, it is expanded. - -### `__wasi_oflags_t` (`uint16_t` bitfield) - -Open flags used by [`__wasi_path_open()`](#path_open). - -Used by [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_O_CREAT`** - - Create file if it does not exist. - -- **`__WASI_O_DIRECTORY`** - - Fail if not a directory. - -- **`__WASI_O_EXCL`** - - Fail if file already exists. - -- **`__WASI_O_TRUNC`** - - Truncate file to size 0. - -### `__wasi_riflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_PEEK`** - - Returns the message without removing it from the - socket's receive queue. - -- **`__WASI_SOCK_RECV_WAITALL`** - - On byte-stream sockets, block until the full amount - of data can be returned. - -### `__wasi_rights_t` (`uint64_t` bitfield) - -File descriptor rights, determining which actions may be -performed. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_RIGHT_FD_DATASYNC`** - - The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_READ`** - - The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke - [`__wasi_fd_pread()`](#fd_pread). - -- **`__WASI_RIGHT_FD_SEEK`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies - [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). - -- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** - - The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). - -- **`__WASI_RIGHT_FD_SYNC`** - - The right to invoke [`__wasi_fd_sync()`](#fd_sync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and - [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_TELL`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the - file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with - offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). - -- **`__WASI_RIGHT_FD_WRITE`** - - The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to - invoke [`__wasi_fd_pwrite()`](#fd_pwrite). - -- **`__WASI_RIGHT_FD_ADVISE`** - - The right to invoke [`__wasi_fd_advise()`](#fd_advise). - -- **`__WASI_RIGHT_FD_ALLOCATE`** - - The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). - -- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** - - The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). - -- **`__WASI_RIGHT_PATH_CREATE_FILE`** - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke - [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). - -- **`__WASI_RIGHT_PATH_LINK_SOURCE`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_LINK_TARGET`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_OPEN`** - - The right to invoke [`__wasi_path_open()`](#path_open). - -- **`__WASI_RIGHT_FD_READDIR`** - - The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). - -- **`__WASI_RIGHT_PATH_READLINK`** - - The right to invoke [`__wasi_path_readlink()`](#path_readlink). - -- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_RENAME_TARGET`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_FILESTAT_GET`** - - The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** - - The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -- **`__WASI_RIGHT_FD_FILESTAT_GET`** - - The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** - - The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). - -- **`__WASI_RIGHT_PATH_SYMLINK`** - - The right to invoke [`__wasi_path_symlink()`](#path_symlink). - -- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** - - The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). - -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - -- **`__WASI_RIGHT_POLL_FD_READWRITE`** - - If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). - - If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -- **`__WASI_RIGHT_SOCK_SHUTDOWN`** - - The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). - -### `__wasi_roflags_t` (`uint16_t` bitfield) - -Flags returned by [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** - - Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been - truncated. - -### `__wasi_sdflags_t` (`uint8_t` bitfield) - -Which channels on a socket to shut down. - -Used by [`__wasi_sock_shutdown()`](#sock_shutdown). - -Possible values: - -- **`__WASI_SHUT_RD`** - - Disables further receive operations. - -- **`__WASI_SHUT_WR`** - - Disables further send operations. - -### `__wasi_siflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Used by [`__wasi_sock_send()`](#sock_send). - -### `__wasi_signal_t` (`uint8_t`) - -Signal condition. - -Used by [`__wasi_proc_raise()`](#proc_raise). - -Possible values: - -- **`__WASI_SIGHUP`** - - Hangup. - - Action: Terminates the process. - -- **`__WASI_SIGINT`** - - Terminate interrupt signal. - - Action: Terminates the process. - -- **`__WASI_SIGQUIT`** - - Terminal quit signal. - - Action: Terminates the process. - -- **`__WASI_SIGILL`** - - Illegal instruction. - - Action: Terminates the process. - -- **`__WASI_SIGTRAP`** - - Trace/breakpoint trap. - - Action: Terminates the process. - -- **`__WASI_SIGABRT`** - - Process abort signal. - - Action: Terminates the process. - -- **`__WASI_SIGBUS`** - - Access to an undefined portion of a memory object. - - Action: Terminates the process. - -- **`__WASI_SIGFPE`** - - Erroneous arithmetic operation. - - Action: Terminates the process. - -- **`__WASI_SIGKILL`** - - Kill. - - Action: Terminates the process. - -- **`__WASI_SIGUSR1`** - - User-defined signal 1. - - Action: Terminates the process. - -- **`__WASI_SIGSEGV`** - - Invalid memory reference. - - Action: Terminates the process. - -- **`__WASI_SIGUSR2`** - - User-defined signal 2. - - Action: Terminates the process. - -- **`__WASI_SIGPIPE`** - - Write on a pipe with no one to read it. - - Action: Ignored. - -- **`__WASI_SIGALRM`** - - Alarm clock. - - Action: Terminates the process. - -- **`__WASI_SIGTERM`** - - Termination signal. - - Action: Terminates the process. - -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** - - Continue executing, if stopped. - - Action: Continues executing, if stopped. - -- **`__WASI_SIGSTOP`** - - Stop executing. - - Action: Stops executing. - -- **`__WASI_SIGTSTP`** - - Terminal stop signal. - - Action: Stops executing. - -- **`__WASI_SIGTTIN`** - - Background process attempting read. - - Action: Stops executing. - -- **`__WASI_SIGTTOU`** - - Background process attempting write. - - Action: Stops executing. - -- **`__WASI_SIGURG`** - - High bandwidth data is available at a socket. - - Action: Ignored. - -- **`__WASI_SIGXCPU`** - - CPU time limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGXFSZ`** - - File size limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGVTALRM`** - - Virtual timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGPROF`** - - Profiling timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGWINCH`** - - Window changed. - - Action: Ignored. - -- **`__WASI_SIGPOLL`** - - I/O possible. - - Action: Terminates the process. - -- **`__WASI_SIGPWR`** - - Power failure. - - Action: Terminates the process. - -- **`__WASI_SIGSYS`** - - Bad system call. - - Action: Terminates the process. - -### `__wasi_subclockflags_t` (`uint16_t` bitfield) - -Flags determining how to interpret the timestamp provided in -[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -Used by [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** - - If set, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp - of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - - If clear, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current - time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - -### `__wasi_subscription_t` (`struct`) - -Subscription to an event. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that is attached to the subscription in the - implementation and returned through - [`__wasi_event_t::userdata`](#event.userdata). - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event to which to subscribe. - -- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): - - - **`u.clock`** - - - [\_\_wasi\_userdata\_t](#userdata) identifier - - The user-defined unique identifier of the clock. - - - [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock against which to compare the timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) timeout - - The absolute or relative timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) precision - - The amount of time that the implementation may wait additionally - to coalesce with other events. - - - [\_\_wasi\_subclockflags\_t](#subclockflags) flags - - Flags specifying whether the timeout is absolute or relative. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor on which to wait for it to become ready - for reading or writing. - -### `__wasi_timestamp_t` (`uint64_t`) - -Timestamp in nanoseconds. - -Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -### `__wasi_userdata_t` (`uint64_t`) - -User-provided value that may be attached to objects that is -retained when extracted from the implementation. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -### `__wasi_whence_t` (`uint8_t`) - -The position relative to which to set the offset of the file descriptor. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -Possible values: - -- **`__WASI_WHENCE_CUR`** - - Seek relative to current position. - -- **`__WASI_WHENCE_END`** - - Seek relative to end-of-file. - -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md new file mode 100644 index 000000000..0688fe7cb --- /dev/null +++ b/proposals/random/phases/snapshot/docs.md @@ -0,0 +1,1790 @@ +# Types +## `size`: `u32` + +## `filesize`: `u64` +Non-negative file size or length of a region within a file. + +## `timestamp`: `u64` +Timestamp in nanoseconds. + +## `clockid`: Enum(`u32`) +Identifiers for clocks. + +### Variants +- `realtime` +The clock measuring real time. Time value zero corresponds with +1970-01-01T00:00:00Z. + +- `monotonic` +The store-wide monotonic clock, which is defined as a clock measuring +real time, whose value cannot be adjusted and which cannot have negative +clock jumps. The epoch of this clock is undefined. The absolute time +value of this clock therefore has no meaning. + +- `process_cputime_id` +The CPU-time clock associated with the current process. + +- `thread_cputime_id` +The CPU-time clock associated with the current thread. + +## `errno`: Enum(`u16`) +Error codes returned by functions. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX. + +### Variants +- `success` +No error occurred. System call completed successfully. + +- `2big` +Argument list too long. + +- `acces` +Permission denied. + +- `addrinuse` +Address in use. + +- `addrnotavail` +Address not available. + +- `afnosupport` +Address family not supported. + +- `again` +Resource unavailable, or operation would block. + +- `already` +Connection already in progress. + +- `badf` +Bad file descriptor. + +- `badmsg` +Bad message. + +- `busy` +Device or resource busy. + +- `canceled` +Operation canceled. + +- `child` +No child processes. + +- `connaborted` +Connection aborted. + +- `connrefused` +Connection refused. + +- `connreset` +Connection reset. + +- `deadlk` +Resource deadlock would occur. + +- `destaddrreq` +Destination address required. + +- `dom` +Mathematics argument out of domain of function. + +- `dquot` +Reserved. + +- `exist` +File exists. + +- `fault` +Bad address. + +- `fbig` +File too large. + +- `hostunreach` +Host is unreachable. + +- `idrm` +Identifier removed. + +- `ilseq` +Illegal byte sequence. + +- `inprogress` +Operation in progress. + +- `intr` +Interrupted function. + +- `inval` +Invalid argument. + +- `io` +I/O error. + +- `isconn` +Socket is connected. + +- `isdir` +Is a directory. + +- `loop` +Too many levels of symbolic links. + +- `mfile` +File descriptor value too large. + +- `mlink` +Too many links. + +- `msgsize` +Message too large. + +- `multihop` +Reserved. + +- `nametoolong` +Filename too long. + +- `netdown` +Network is down. + +- `netreset` +Connection aborted by network. + +- `netunreach` +Network unreachable. + +- `nfile` +Too many files open in system. + +- `nobufs` +No buffer space available. + +- `nodev` +No such device. + +- `noent` +No such file or directory. + +- `noexec` +Executable file format error. + +- `nolck` +No locks available. + +- `nolink` +Reserved. + +- `nomem` +Not enough space. + +- `nomsg` +No message of the desired type. + +- `noprotoopt` +Protocol not available. + +- `nospc` +No space left on device. + +- `nosys` +Function not supported. + +- `notconn` +The socket is not connected. + +- `notdir` +Not a directory or a symbolic link to a directory. + +- `notempty` +Directory not empty. + +- `notrecoverable` +State not recoverable. + +- `notsock` +Not a socket. + +- `notsup` +Not supported, or operation not supported on socket. + +- `notty` +Inappropriate I/O control operation. + +- `nxio` +No such device or address. + +- `overflow` +Value too large to be stored in data type. + +- `ownerdead` +Previous owner died. + +- `perm` +Operation not permitted. + +- `pipe` +Broken pipe. + +- `proto` +Protocol error. + +- `protonosupport` +Protocol not supported. + +- `prototype` +Protocol wrong type for socket. + +- `range` +Result too large. + +- `rofs` +Read-only file system. + +- `spipe` +Invalid seek. + +- `srch` +No such process. + +- `stale` +Reserved. + +- `timedout` +Connection timed out. + +- `txtbsy` +Text file busy. + +- `xdev` +Cross-device link. + +- `notcapable` +Extension: Capabilities insufficient. + +## `rights`: Flags(`u64`) +File descriptor rights, determining which actions may be performed. + +### Flags +- `fd_datasync` +The right to invoke [`fd_datasync`](#fd_datasync). +If [`path_open`](#path_open) is set, includes the right to invoke +[`path_open`](#path_open) with `fdflag::dsync`. + +- `fd_read` +The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). + +- `fd_seek` +The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). + +- `fd_fdstat_set_flags` +The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). + +- `fd_sync` +The right to invoke [`fd_sync`](#fd_sync). +If [`path_open`](#path_open) is set, includes the right to invoke +[`path_open`](#path_open) with `fdflag::rsync` and `fdflag::dsync`. + +- `fd_tell` +The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset +remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +invoke [`fd_tell`](#fd_tell). + +- `fd_write` +The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). + +- `fd_advise` +The right to invoke [`fd_advise`](#fd_advise). + +- `fd_allocate` +The right to invoke [`fd_allocate`](#fd_allocate). + +- `path_create_directory` +The right to invoke [`path_create_directory`](#path_create_directory). + +- `path_create_file` +If [`path_open`](#path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). + +- `path_link_source` +The right to invoke [`path_link`](#path_link) with the file descriptor as the +source directory. + +- `path_link_target` +The right to invoke [`path_link`](#path_link) with the file descriptor as the +target directory. + +- `path_open` +The right to invoke [`path_open`](#path_open). + +- `fd_readdir` +The right to invoke [`fd_readdir`](#fd_readdir). + +- `path_readlink` +The right to invoke [`path_readlink`](#path_readlink). + +- `path_rename_source` +The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. + +- `path_rename_target` +The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. + +- `path_filestat_get` +The right to invoke [`path_filestat_get`](#path_filestat_get). + +- `path_filestat_set_size` +The right to change a file's size (there is no `path_filestat_set_size`). +If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). + +- `path_filestat_set_times` +The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). + +- `fd_filestat_get` +The right to invoke [`fd_filestat_get`](#fd_filestat_get). + +- `fd_filestat_set_size` +The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). + +- `fd_filestat_set_times` +The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). + +- `path_symlink` +The right to invoke [`path_symlink`](#path_symlink). + +- `path_remove_directory` +The right to invoke [`path_remove_directory`](#path_remove_directory). + +- `path_unlink_file` +The right to invoke [`path_unlink_file`](#path_unlink_file). + +- `poll_fd_readwrite` +If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). +If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). + +- `sock_shutdown` +The right to invoke [`sock_shutdown`](#sock_shutdown). + +## `fd`: `u32` +A file descriptor index. + +## `iovec`: Struct +A region of memory for scatter/gather reads. + +### Struct members +- `buf`: `Pointer` +The address of the buffer to be filled. + +- `buf_len`: [`size`](#size) +The length of the buffer to be filled. + +## `ciovec`: Struct +A region of memory for scatter/gather writes. + +### Struct members +- `buf`: `ConstPointer` +The address of the buffer to be written. + +- `buf_len`: [`size`](#size) +The length of the buffer to be written. + +## `iovec_array`: `Array` + +## `ciovec_array`: `Array` + +## `filedelta`: `s64` +Relative offset within a file. + +## `whence`: Enum(`u8`) +The position relative to which to set the offset of the file descriptor. + +### Variants +- `set` +Seek relative to start-of-file. + +- `cur` +Seek relative to current position. + +- `end` +Seek relative to end-of-file. + +## `dircookie`: `u64` +A reference to the offset of a directory entry. + +The value 0 signifies the start of the directory. + +## `dirnamlen`: `u32` +The type for the $d_namlen field of $dirent. + +## `inode`: `u64` +File serial number that is unique within its file system. + +## `filetype`: Enum(`u8`) +The type of a file descriptor or file. + +### Variants +- `unknown` +The type of the file descriptor or file is unknown or is different from any of the other types specified. + +- `block_device` +The file descriptor or file refers to a block device inode. + +- `character_device` +The file descriptor or file refers to a character device inode. + +- `directory` +The file descriptor or file refers to a directory inode. + +- `regular_file` +The file descriptor or file refers to a regular file inode. + +- `socket_dgram` +The file descriptor or file refers to a datagram socket. + +- `socket_stream` +The file descriptor or file refers to a byte-stream socket. + +- `symbolic_link` +The file refers to a symbolic link inode. + +## `dirent`: Struct +A directory entry. + +### Struct members +- `d_next`: [`dircookie`](#dircookie) +The offset of the next directory entry stored in this directory. + +- `d_ino`: [`inode`](#inode) +The serial number of the file referred to by this directory entry. + +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. + +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. + +## `advice`: Enum(`u8`) +File or memory access pattern advisory information. + +### Variants +- `normal` +The application has no advice to give on its behavior with respect to the specified data. + +- `sequential` +The application expects to access the specified data sequentially from lower offsets to higher offsets. + +- `random` +The application expects to access the specified data in a random order. + +- `willneed` +The application expects to access the specified data in the near future. + +- `dontneed` +The application expects that it will not access the specified data in the near future. + +- `noreuse` +The application expects to access the specified data once and then not reuse it thereafter. + +## `fdflags`: Flags(`u16`) +File descriptor flags. + +### Flags +- `append` +Append mode: Data written to the file is always appended to the file's end. + +- `dsync` +Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + +- `nonblock` +Non-blocking mode. + +- `rsync` +Synchronized read I/O operations. + +- `sync` +Write according to synchronized I/O file integrity completion. In +addition to synchronizing the data stored in the file, the implementation +may also synchronously update the file's metadata. + +## `fdstat`: Struct +File descriptor attributes. + +### Struct members +- `fs_filetype`: [`filetype`](#filetype) +File type. + +- `fs_flags`: [`fdflags`](#fdflags) +File descriptor flags. + +- `fs_rights_base`: [`rights`](#rights) +Rights that apply to this file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) +Maximum set of rights that may be installed on new file descriptors that +are created through this file descriptor, e.g., through [`path_open`](#path_open). + +## `device`: `u64` +Identifier for a device containing a file system. Can be used in combination +with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. + +## `fstflags`: Flags(`u16`) +Which file time attributes to adjust. + +### Flags +- `atim` +Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + +- `atim_now` +Adjust the last data access timestamp to the time of clock `clock::realtime`. + +- `mtim` +Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + +- `mtim_now` +Adjust the last data modification timestamp to the time of clock `clock::realtime`. + +## `lookupflags`: Flags(`u32`) +Flags determining the method of how paths are resolved. + +### Flags +- `symlink_follow` +As long as the resolved path corresponds to a symbolic link, it is expanded. + +## `oflags`: Flags(`u16`) +Open flags used by [`path_open`](#path_open). + +### Flags +- `creat` +Create file if it does not exist. + +- `directory` +Fail if not a directory. + +- `excl` +Fail if file already exists. + +- `trunc` +Truncate file to size 0. + +## `linkcount`: `u64` +Number of hard links to an inode. + +## `filestat`: Struct +File attributes. + +### Struct members +- `dev`: [`device`](#device) +Device ID of device containing the file. + +- `ino`: [`inode`](#inode) +File serial number. + +- `filetype`: [`filetype`](#filetype) +File type. + +- `nlink`: [`linkcount`](#linkcount) +Number of hard links to the file. + +- `size`: [`filesize`](#filesize) +For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + +- `atim`: [`timestamp`](#timestamp) +Last data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +Last data modification timestamp. + +- `ctim`: [`timestamp`](#timestamp) +Last file status change timestamp. + +## `userdata`: `u64` +User-provided value that may be attached to objects that is retained when +extracted from the implementation. + +## `eventtype`: Enum(`u8`) +Type of a subscription to an event or its occurrence. + +### Variants +- `clock` +The time value of clock `subscription::u.clock.clock_id` has +reached timestamp `subscription::u.clock.timeout`. + +- `fd_read` +File descriptor `subscription::u.fd_readwrite.fd` has data +available for reading. This event always triggers for regular files. + +- `fd_write` +File descriptor `subscription::u.fd_readwrite.fd` has capacity +available for writing. This event always triggers for regular files. + +## `eventrwflags`: Flags(`u16`) +The state of the file descriptor subscribed to with +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Flags +- `fd_readwrite_hangup` +The peer of this socket has closed or disconnected. + +## `event_fd_readwrite`: Struct +The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `nbytes`: [`filesize`](#filesize) +The number of bytes available for reading or writing. + +- `flags`: [`eventrwflags`](#eventrwflags) +The state of the file descriptor. + +## `event_u`: Union +The contents of an $event. + +### Union variants +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `event`: Struct +An event that occurred. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). + +- `error`: [`errno`](#errno) +If non-zero, an error that occurred while processing the subscription request. + +- `type`: [`eventtype`](#eventtype) +The type of the event that occurred. + +- `u`: [`event_u`](#event_u) +The contents of the event. + +## `subclockflags`: Flags(`u16`) +Flags determining how to interpret the timestamp provided in +`subscription::u.clock.timeout.` + +### Flags +- `subscription_clock_abstime` +If set, treat the timestamp provided in +`subscription::u.clock.timeout` as an absolute timestamp of clock +`subscription::u.clock.clock_id.` If clear, treat the timestamp +provided in `subscription::u.clock.timeout` relative to the +current time value of clock `subscription::u.clock.clock_id.` + +## `subscription_clock`: Struct +The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). + +### Struct members +- `id`: [`clockid`](#clockid) +The clock against which to compare the timestamp. + +- `timeout`: [`timestamp`](#timestamp) +The absolute or relative timestamp. + +- `precision`: [`timestamp`](#timestamp) +The amount of time that the implementation may wait additionally +to coalesce with other events. + +- `flags`: [`subclockflags`](#subclockflags) +Flags specifying whether the timeout is absolute or relative + +## `subscription_fd_readwrite`: Struct +The contents of a $subscription when type is type is +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `file_descriptor`: [`fd`](#fd) +The file descriptor on which to wait for it to become ready for reading or writing. + +## `subscription_u`: Union +The contents of a $subscription. + +### Union variants +- `clock`: [`subscription_clock`](#subscription_clock) +When type is [`eventtype::clock`](#eventtype.clock): + +- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `subscription`: Struct +Subscription to an event. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that is attached to the subscription in the +implementation and returned through [`event::userdata`](#event.userdata). + +- `type`: [`eventtype`](#eventtype) +The type of the event to which to subscribe. + +- `u`: [`subscription_u`](#subscription_u) +The contents of the subscription. + +## `exitcode`: `u32` +Exit code generated by a process when exiting. + +## `signal`: Enum(`u8`) +Signal condition. + +### Variants +- `none` +No signal. Note that POSIX has special semantics for `kill(pid, 0)`, +so this value is reserved. + +- `hup` +Hangup. +Action: Terminates the process. + +- `int` +Terminate interrupt signal. +Action: Terminates the process. + +- `quit` +Terminal quit signal. +Action: Terminates the process. + +- `ill` +Illegal instruction. +Action: Terminates the process. + +- `trap` +Trace/breakpoint trap. +Action: Terminates the process. + +- `abrt` +Process abort signal. +Action: Terminates the process. + +- `bus` +Access to an undefined portion of a memory object. +Action: Terminates the process. + +- `fpe` +Erroneous arithmetic operation. +Action: Terminates the process. + +- `kill` +Kill. +Action: Terminates the process. + +- `usr1` +User-defined signal 1. +Action: Terminates the process. + +- `segv` +Invalid memory reference. +Action: Terminates the process. + +- `usr2` +User-defined signal 2. +Action: Terminates the process. + +- `pipe` +Write on a pipe with no one to read it. +Action: Ignored. + +- `alrm` +Alarm clock. +Action: Terminates the process. + +- `term` +Termination signal. +Action: Terminates the process. + +- `chld` +Child process terminated, stopped, or continued. +Action: Ignored. + +- `cont` +Continue executing, if stopped. +Action: Continues executing, if stopped. + +- `stop` +Stop executing. +Action: Stops executing. + +- `tstp` +Terminal stop signal. +Action: Stops executing. + +- `ttin` +Background process attempting read. +Action: Stops executing. + +- `ttou` +Background process attempting write. +Action: Stops executing. + +- `urg` +High bandwidth data is available at a socket. +Action: Ignored. + +- `xcpu` +CPU time limit exceeded. +Action: Terminates the process. + +- `xfsz` +File size limit exceeded. +Action: Terminates the process. + +- `vtalrm` +Virtual timer expired. +Action: Terminates the process. + +- `prof` +Profiling timer expired. +Action: Terminates the process. + +- `winch` +Window changed. +Action: Ignored. + +- `poll` +I/O possible. +Action: Terminates the process. + +- `pwr` +Power failure. +Action: Terminates the process. + +- `sys` +Bad system call. +Action: Terminates the process. + +## `riflags`: Flags(`u16`) +Flags provided to [`sock_recv`](#sock_recv). + +### Flags +- `recv_peek` +Returns the message without removing it from the socket's receive queue. + +- `recv_waitall` +On byte-stream sockets, block until the full amount of data can be returned. + +## `roflags`: Flags(`u16`) +Flags returned by [`sock_recv`](#sock_recv). + +### Flags +- `recv_data_truncated` +Returned by [`sock_recv`](#sock_recv): Message data has been truncated. + +## `siflags`: `u16` +Flags provided to [`sock_send`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +## `sdflags`: Flags(`u8`) +Which channels on a socket to shut down. + +### Flags +- `rd` +Disables further receive operations. + +- `wr` +Disables further send operations. + +## `preopentype`: Enum(`u8`) +Identifiers for preopened capabilities. + +### Variants +- `dir` +A pre-opened directory. + +## `prestat_dir`: Struct +The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). + +### Struct members +- `pr_name_len`: [`size`](#size) +The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). + +## `prestat_u`: Union +The contents of an $prestat. + +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) +When type is [`preopentype::dir`](#preopentype.dir): + +## `prestat`: Struct +Information about a pre-opened capability. + +### Struct members +- `pr_type`: [`preopentype`](#preopentype) +The type of the pre-opened capability. + +- `u`: [`prestat_u`](#prestat_u) +The contents of the information. + +# Modules +## wasi_snapshot_preview1 +### Imports +#### Memory +### Functions + +--- + +#### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` +Read command-line argument data. +The size of the array should match that returned by `wasi_args_sizes_get()` + +##### Params +- `argv`: `Pointer>` + +- `argv_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `args_sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + + +--- + +#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` +Read environment variable data. +The sizes of the buffers should match that returned by `environ.sizes_get()`. + +##### Params +- `environ`: `Pointer>` + +- `environ_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `environ_sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + + +--- + +#### `clock_res_get(id: clockid) -> (errno, timestamp)` +Return the resolution of a clock. +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Note: This is similar to `clock_getres` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the resolution. + +##### Results +- `error`: [`errno`](#errno) + +- `resolution`: [`timestamp`](#timestamp) +The resolution of the clock. + + +--- + +#### `clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +Return the time value of a clock. +Note: This is similar to `clock_gettime` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the time. + +- `precision`: [`timestamp`](#timestamp) +The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + +##### Results +- `error`: [`errno`](#errno) + +- `time`: [`timestamp`](#timestamp) +The time value of the clock. + + +--- + +#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +Provide file advisory information on a file descriptor. +Note: This is similar to `posix_fadvise` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset within the file to which the advisory applies. + +- `len`: [`filesize`](#filesize) +The length of the region to which the advisory applies. + +- `advice`: [`advice`](#advice) +The advice. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno` +Force the allocation of space in a file. +Note: This is similar to `posix_fallocate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset at which to start the allocation. + +- `len`: [`filesize`](#filesize) +The length of the area that is allocated. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_close(fd: fd) -> errno` +Close a file descriptor. +Note: This is similar to `close` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_datasync(fd: fd) -> errno` +Synchronize the data of a file to disk. +Note: This is similar to `fdatasync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_fdstat_get(fd: fd) -> (errno, fdstat)` +Get the attributes of a file descriptor. +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `stat`: [`fdstat`](#fdstat) +The buffer where the file descriptor's attributes are stored. + + +--- + +#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +Adjust the flags associated with a file descriptor. +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`fdflags`](#fdflags) +The desired values of the file descriptor flags. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +Adjust the rights associated with a file descriptor. +This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + +##### Params +- `fd`: [`fd`](#fd) + +- `fs_rights_base`: [`rights`](#rights) +The desired rights of the file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_filestat_get(fd: fd) -> (errno, filestat)` +Return the attributes of an open file. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `fd_filestat_set_size(fd: fd, size: filesize) -> errno` +Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. +Note: This is similar to `ftruncate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `size`: [`filesize`](#filesize) +The desired file size. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of an open file or directory. +Note: This is similar to `futimens` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +Read from a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `preadv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors in which to store data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to read. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `fd_prestat_get(fd: fd) -> (errno, prestat)` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`prestat`](#prestat) +The buffer where the description is stored. + + +--- + +#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `Pointer` +A buffer into which to write the preopened directory name. + +- `path_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +Write to a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `pwritev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to write. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `fd_read(fd: fd, iovs: iovec_array) -> (errno, size)` +Read from a file descriptor. +Note: This is similar to `readv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +Read directory entries from a directory. +When successful, the contents of the output buffer consist of a sequence of +directory entries. Each directory entry consists of a dirent_t object, +followed by dirent_t::d_namlen bytes holding the name of the directory +entry. +This function fills the output buffer as much as possible, potentially +truncating the last directory entry. This allows the caller to grow its +read buffer size in case it's too small to fit a single large directory +entry, or skip the oversized directory entry. + +##### Params +- `fd`: [`fd`](#fd) + +- `buf`: `Pointer` +The buffer where directory entries are stored + +- `buf_len`: [`size`](#size) + +- `cookie`: [`dircookie`](#dircookie) +The location within the directory to start reading + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + + +--- + +#### `fd_renumber(fd: fd, to: fd) -> errno` +Atomically replace a file descriptor by renumbering another file descriptor. +Due to the strong focus on thread safety, this environment does not provide +a mechanism to duplicate or renumber a file descriptor to an arbitrary +number, like `dup2()`. This would be prone to race conditions, as an actual +file descriptor with the same number could be allocated by a different +thread at the same time. +This function provides a way to atomically renumber file descriptors, which +would disappear if `dup2()` were to be removed entirely. + +##### Params +- `fd`: [`fd`](#fd) + +- `to`: [`fd`](#fd) +The file descriptor to overwrite. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +Move the offset of a file descriptor. +Note: This is similar to `lseek` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filedelta`](#filedelta) +The number of bytes to move. + +- `whence`: [`whence`](#whence) +The base from which the offset is relative. + +##### Results +- `error`: [`errno`](#errno) + +- `newoffset`: [`filesize`](#filesize) +The new offset of the file descriptor, relative to the start of the file. + + +--- + +#### `fd_sync(fd: fd) -> errno` +Synchronize the data and metadata of a file to disk. +Note: This is similar to `fsync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_tell(fd: fd) -> (errno, filesize)` +Return the current offset of a file descriptor. +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `offset`: [`filesize`](#filesize) +The current offset of the file descriptor, relative to the start of the file. + + +--- + +#### `fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)` +Write to a file descriptor. +Note: This is similar to `writev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `path_create_directory(fd: fd, path: string) -> errno` +Create a directory. +Note: This is similar to `mkdirat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path at which to create the directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +Return the attributes of a file or directory. +Note: This is similar to `stat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to inspect. + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of a file or directory. +Note: This is similar to `utimensat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to operate on. + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +Create a hard link. +Note: This is similar to `linkat` in POSIX. + +##### Params +- `old_fd`: [`fd`](#fd) + +- `old_flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `old_path`: `string` +The source path from which to link. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path at which to create the hard link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)` +Open a file or directory. +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since this +is error-prone in multi-threaded contexts. The returned file descriptor is +guaranteed to be less than 2**31. +Note: This is similar to `openat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `dirflags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The relative path of the file or directory to open, relative to the +`dirfd` directory. + +- `oflags`: [`oflags`](#oflags) +The method by which to open the file. + +- `fs_rights_base`: [`rights`](#rights) +The initial rights of the newly created file descriptor. The +implementation is allowed to return a file descriptor with fewer rights +than specified, if and only if those rights do not apply to the type of +file being opened. +The *base* rights are rights that will apply to operations using the file +descriptor itself, while the *inheriting* rights are rights that apply to +file descriptors derived from it. + +- `fs_rights_inherting`: [`rights`](#rights) + +- `fdflags`: [`fdflags`](#fdflags) + +##### Results +- `error`: [`errno`](#errno) + +- `opened_fd`: [`fd`](#fd) +The file descriptor of the file that has been opened. + + +--- + +#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +Read the contents of a symbolic link. +Note: This is similar to `readlinkat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path of the symbolic link from which to read. + +- `buf`: `Pointer` +The buffer to which to write the contents of the symbolic link. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes placed in the buffer. + + +--- + +#### `path_remove_directory(fd: fd, path: string) -> errno` +Remove a directory. +Return `ENOTEMPTY` if the directory is not empty. +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a directory to remove. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +Rename a file or directory. +Note: This is similar to `renameat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `old_path`: `string` +The source path of the file or directory to rename. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path to which to rename the file or directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_symlink(old_path: string, fd: fd, new_path: string) -> errno` +Create a symbolic link. +Note: This is similar to `symlinkat` in POSIX. + +##### Params +- `old_path`: `string` +The contents of the symbolic link. + +- `fd`: [`fd`](#fd) + +- `new_path`: `string` +The destination path at which to create the symbolic link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_unlink_file(fd: fd, path: string) -> errno` +Unlink a file. +Return `EISDIR` if the path refers to a directory. +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a file to unlink. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +Concurrently poll for the occurrence of a set of events. + +##### Params +- `in`: `ConstPointer` +The events to which to subscribe. + +- `out`: `Pointer` +The events that have occurred. + +- `nsubscriptions`: [`size`](#size) +Both the number of subscriptions and events. + +##### Results +- `error`: [`errno`](#errno) + +- `nevents`: [`size`](#size) +The number of events stored. + + +--- + +#### `proc_exit(rval: exitcode)` +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +##### Params +- `rval`: [`exitcode`](#exitcode) +The exit code returned by the process. + +##### Results + +--- + +#### `proc_raise(sig: signal) -> errno` +Send a signal to the process of the calling thread. +Note: This is similar to `raise` in POSIX. + +##### Params +- `sig`: [`signal`](#signal) +The signal condition to trigger. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sched_yield() -> errno` +Temporarily yield execution of the calling thread. +Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. + +##### Params +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `random_get(buf: Pointer, buf_len: size) -> errno` +Write high-quality random data into a buffer. +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. +This function may execute slowly, so when large mounts of random data are +required, it's advisable to use this function to seed a pseudo-random +number generator, rather than to provide the random data directly. + +##### Params +- `buf`: `Pointer` +The buffer to fill with random data. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +Receive a message from a socket. +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +##### Params +- `fd`: [`fd`](#fd) + +- `ri_data`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +- `ri_flags`: [`riflags`](#riflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `ro_datalen`: [`size`](#size) +Number of bytes stored in ri_data. + +- `ro_flags`: [`roflags`](#roflags) +Message flags. + + +--- + +#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +Send a message on a socket. +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +##### Params +- `fd`: [`fd`](#fd) + +- `si_data`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors to which to retrieve data + +- `si_flags`: [`siflags`](#siflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `so_datalen`: [`size`](#size) +Number of bytes transmitted. + + +--- + +#### `sock_shutdown(fd: fd, how: sdflags) -> errno` +Shut down socket send and receive channels. +Note: This is similar to `shutdown` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `how`: [`sdflags`](#sdflags) +Which channels on the socket to shut down. + +##### Results +- `error`: [`errno`](#errno) + diff --git a/proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md b/proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md deleted file mode 100644 index 7aa5816af..000000000 --- a/proposals/random/phases/snapshot/docs/wasi_unstable_preview1.md +++ /dev/null @@ -1,2346 +0,0 @@ - - -# The WASI Preview API - -This is the API-level documentation for WASI Preview. The function names -are prefixed with "\_\_wasi\_" to reflect how they are spelled in -flat-namespace contexts, however at the wasm module level, they are -unprefixed, because they're inside a module namespace. - -Functions that start with `__wasi_fd_` operate on file descriptors, -while functions that start with `__wasi_path_` operate on filesystem -paths, which are relative to directory file descriptors. - -Much inspiration and content here is derived from [CloudABI] and [POSIX], -though there are also several differences from CloudABI and POSIX. For -example, WASI Preview has no concept of processes in the traditional Unix -sense. While wasm linear memories have some of the aspects of processes, -and it's possible to *emulate* the full semantics of processes on top of -them, this can sometimes be unnatural and inefficient. The goal for -WASI Preview is to be a WebAssembly-native API that exposes APIs that fit -well into the underlying WebAssembly platform, rather than to directly -emulate other platforms. - -This is also a work in progress, and the API here is still evolving. - -Historical note: this API was originally named "WASI Core", and used the -API module name "wasi\_unstable". We've since sought to deemphasize the -"Core" name, as the goal is to split this API up into independent -modules so that embedders need not implement all of it. - -[CloudABI]: https://github.com/NuxiNL/cloudabi -[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ - -## System calls - -- [`__wasi_args_get()`](#args_get) -- [`__wasi_args_sizes_get()`](#args_sizes_get) -- [`__wasi_clock_res_get()`](#clock_res_get) -- [`__wasi_clock_time_get()`](#clock_time_get) -- [`__wasi_environ_get()`](#environ_get) -- [`__wasi_environ_sizes_get()`](#environ_sizes_get) -- [`__wasi_fd_advise()`](#fd_advise) -- [`__wasi_fd_allocate()`](#fd_allocate) -- [`__wasi_fd_close()`](#fd_close) -- [`__wasi_fd_datasync()`](#fd_datasync) -- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) -- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) -- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) -- [`__wasi_fd_filestat_get()`](#fd_filestat_get) -- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) -- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) -- [`__wasi_fd_pread()`](#fd_pread) -- [`__wasi_fd_prestat_get()`](#fd_prestat_get) -- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) -- [`__wasi_fd_pwrite()`](#fd_pwrite) -- [`__wasi_fd_read()`](#fd_read) -- [`__wasi_fd_readdir()`](#fd_readdir) -- [`__wasi_fd_renumber()`](#fd_renumber) -- [`__wasi_fd_seek()`](#fd_seek) -- [`__wasi_fd_sync()`](#fd_sync) -- [`__wasi_fd_tell()`](#fd_tell) -- [`__wasi_fd_write()`](#fd_write) -- [`__wasi_path_create_directory()`](#path_create_directory) -- [`__wasi_path_filestat_get()`](#path_filestat_get) -- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) -- [`__wasi_path_link()`](#path_link) -- [`__wasi_path_open()`](#path_open) -- [`__wasi_path_readlink()`](#path_readlink) -- [`__wasi_path_remove_directory()`](#path_remove_directory) -- [`__wasi_path_rename()`](#path_rename) -- [`__wasi_path_symlink()`](#path_symlink) -- [`__wasi_path_unlink_file()`](#path_unlink_file) -- [`__wasi_poll_oneoff()`](#poll_oneoff) -- [`__wasi_proc_exit()`](#proc_exit) -- [`__wasi_proc_raise()`](#proc_raise) -- [`__wasi_random_get()`](#random_get) -- [`__wasi_sched_yield()`](#sched_yield) -- [`__wasi_sock_recv()`](#sock_recv) -- [`__wasi_sock_send()`](#sock_send) -- [`__wasi_sock_shutdown()`](#sock_shutdown) - -### `__wasi_args_get()` - -Read command-line argument data. - -Inputs: - -- char \*\*argv - - A pointer to a buffer to write the argument pointers. - - The count of elements for the buffer should be at least the value of `argc` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - - The caller of `__wasi_args_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. - -- char \*argv\_buf - - A pointer to a buffer to write the argument string data. - - The size of this buffer should be the value of `argv_buf_size` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - -### `__wasi_args_sizes_get()` - -Return command-line argument data sizes. - -Outputs: - -- size\_t \*argc - - The number of arguments. - -- size\_t \*argv\_buf\_size - - The size of the argument string data. - -### `__wasi_clock_res_get()` - -Return the resolution of a clock. - -Implementations are required to provide a non-zero value for supported clocks. -For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). - -Note: This is similar to `clock_getres` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the resolution. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) resolution - - The resolution of the clock. - -### `__wasi_clock_time_get()` - -Return the time value of a clock. - -Note: This is similar to `clock_gettime` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the time. - -- [\_\_wasi\_timestamp\_t](#timestamp) precision - - The maximum lag (exclusive) that the returned - time value may have, compared to its actual - value. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) time - - The time value of the clock. - -### `__wasi_environ_get()` - -Read environment variable data. - -Inputs: - -- char \*\*environ - - A pointer to a buffer to write the environment variable pointers. - - The count of elements for the buffer should be at least the value of `environ_count` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - - The caller of `__wasi_environ_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. - -- char \*environ\_buf - - A pointer to a buffer to write the environment variable string data. - - The size of this buffer should be the value of `environ_buf_size` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - -### `__wasi_environ_sizes_get()` - -Return enviroment variable data sizes. - -Outputs: - -- size\_t \*environ\_count - - The number of environment variables. - -- size\_t \*environ\_buf\_size - - The size of the environment variable string data. - -### `__wasi_fd_advise()` - -Provide file advisory information on a file descriptor. - -Note: This is similar to `posix_fadvise` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file for which to provide file advisory information. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file to which the advisory applies. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the region to which the advisory applies. - -- [\_\_wasi\_advice\_t](#advice) advice - - The advice. - -### `__wasi_fd_allocate()` - -Force the allocation of space in a file. - -Note: This is similar to `posix_fallocate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file in which to allocate space. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset at which to start the allocation. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the area that is allocated. - -### `__wasi_fd_close()` - -Close a file descriptor. - -Note: This is similar to `close` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to close. - -### `__wasi_fd_datasync()` - -Synchronize the data of a file to disk. - -Note: This is similar to `fdatasync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file to synchronize to disk. - -### `__wasi_fd_fdstat_get()` - -Get the attributes of a file descriptor. - -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well -as additional fields. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_fdstat\_t](#fdstat) \*buf - - The buffer where the file descriptor's attributes are stored. - -### `__wasi_fd_fdstat_set_flags()` - -Adjust the flags associated with a file descriptor. - -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_fdflags\_t](#fdflags) flags - - The desired values of the file descriptor - flags. - -### `__wasi_fd_fdstat_set_rights()` - -Adjust the rights associated with a file descriptor. - -This can only be used to remove rights, and returns -[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt -to add rights. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The desired rights of the file descriptor. - -### `__wasi_fd_filestat_get()` - -Return the attributes of an open file. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_fd_filestat_set_size()` - -Adjust the size of an open file. If this increases the file's size, the extra -bytes are filled with zeros. - -Note: This is similar to `ftruncate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - A file descriptor for the file to adjust. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - The desired file size. - -### `__wasi_fd_filestat_set_times()` - -Adjust the timestamps of an open file or directory. - -Note: This is similar to `futimens` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_fd_pread()` - -Read from a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `preadv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors in which to store data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to read. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_prestat_get()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- [\_\_wasi\_prestat\_t](#prestat) \*buf - - The buffer where the description is stored. - -### `__wasi_fd_prestat_dir_name()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- const char \*path and size\_t path\_len - - A buffer into which to write the preopened directory name. - -### `__wasi_fd_pwrite()` - -Write to a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `pwritev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to write. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_fd_read()` - -Read from a file descriptor. - -Note: This is similar to `readv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors to which to store data. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_readdir()` - -Read directory entries from a directory. - -When successful, the contents of the output buffer consist of -a sequence of directory entries. Each directory entry consists -of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes -holding the name of the directory entry. - -This function fills the output buffer as much as possible, -potentially truncating the last directory entry. This allows -the caller to grow its read buffer size in case it's too small -to fit a single large directory entry, or skip the oversized -directory entry. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The directory from which to read the directory - entries. - -- void \*buf and size\_t buf\_len - - The buffer where directory entries are stored. - -- [\_\_wasi\_dircookie\_t](#dircookie) cookie - - The location within the directory to start - reading. - -Outputs: - -- size\_t bufused - - The number of bytes stored in the read buffer. - If less than the size of the read buffer, the - end of the directory has been reached. - -### `__wasi_fd_renumber()` - -Atomically replace a file descriptor by renumbering another -file descriptor. - -Due to the strong focus on thread safety, this environment -does not provide a mechanism to duplicate or renumber a file -descriptor to an arbitrary number, like dup2(). This would be -prone to race conditions, as an actual file descriptor with the -same number could be allocated by a different thread at the same -time. - -This function provides a way to atomically renumber file -descriptors, which would disappear if dup2() were to be -removed entirely. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) from - - The file descriptor to renumber. - -- [\_\_wasi\_fd\_t](#fd) to - - The file descriptor to overwrite. - -### `__wasi_fd_seek()` - -Move the offset of a file descriptor. - -Note: This is similar to `lseek` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_filedelta\_t](#filedelta) offset - - The number of bytes to move. - -- [\_\_wasi\_whence\_t](#whence) whence - - The base from which the offset is relative. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) newoffset - - The new offset of the file descriptor, - relative to the start of the file. - -### `__wasi_fd_sync()` - -Synchronize the data and metadata of a file to disk. - -Note: This is similar to `fsync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file containing the data - and metadata to synchronize to disk. - -### `__wasi_fd_tell()` - -Return the current offset of a file descriptor. - -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The current offset of the file descriptor, relative to the start of the file. - -### `__wasi_fd_write()` - -Write to a file descriptor. - -Note: This is similar to `writev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_path_create_directory()` - -Create a directory. - -Note: This is similar to `mkdirat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path at which to create the directory. - -### `__wasi_path_filestat_get()` - -Return the attributes of a file or directory. - -Note: This is similar to `stat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_path_filestat_set_times()` - -Adjust the timestamps of a file or directory. - -Note: This is similar to `utimensat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_path_link()` - -Create a hard link. - -Note: This is similar to `linkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags - - Flags determining the method of how the path is resolved. - -- const char \*old\_path and size\_t old\_path\_len - - The source path from which to link. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the hard link. - -### `__wasi_path_open()` - -Open a file or directory. - -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since -this is error-prone in multi-threaded contexts. The returned file -descriptor is guaranteed to be less than 231. - -Note: This is similar to `openat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) dirfd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The relative path of the file or directory to open, relative to - the [`dirfd`](#path_open.dirfd) directory. - -- [\_\_wasi\_oflags\_t](#oflags) o_flags - - The method by which to open the file. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The initial rights of the newly created file descriptor. The - implementation is allowed to return a file descriptor with fewer - rights than specified, if and only if those rights do not apply - to the type of file being opened. - - The *base* rights are rights that will apply to operations using - the file descriptor itself, while the *inheriting* rights are - rights that apply to file descriptors derived from it. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - The initial flags of the file descriptor. - -Outputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file that has been - opened. - -### `__wasi_path_readlink()` - -Read the contents of a symbolic link. - -Note: This is similar to `readlinkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path of the symbolic link from which to read. - -- char \*buf and size\_t buf\_len - - The buffer to which to write the contents of the symbolic link. - -Outputs: - -- size\_t bufused - - The number of bytes placed in the buffer. - -### `__wasi_path_remove_directory()` - -Remove a directory. - -Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. - -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a directory to remove. - -### `__wasi_path_rename()` - -Rename a file or directory. - -Note: This is similar to `renameat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- const char \*old\_path and size\_t old\_path\_len - - The source path of the file or directory to rename. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path to which to rename the file or directory. - -### `__wasi_path_symlink()` - -Create a symbolic link. - -Note: This is similar to `symlinkat` in POSIX. - -Inputs: - -- const char \*old\_path and size\_t old_path\_len - - The contents of the symbolic link. - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the symbolic link. - -### `__wasi_path_unlink_file()` - -Unlink a file. - -Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. - -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a file to unlink. - -### `__wasi_poll_oneoff()` - -Concurrently poll for the occurrence of a set of events. - -Inputs: - -- const [\_\_wasi\_subscription\_t](#subscription) \*in - - The events to which to subscribe. - -- [\_\_wasi\_event\_t](#event) \*out - - The events that have occurred. - -- size\_t nsubscriptions - - Both the number of subscriptions and events. - -Outputs: - -- size\_t nevents - - The number of events stored. - -### `__wasi_proc_exit()` - -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -Note: This is similar to `_Exit` in POSIX. - -Inputs: - -- [\_\_wasi\_exitcode\_t](#exitcode) rval - - The exit code returned by the process. - -Does not return. - -### `__wasi_proc_raise()` - -Send a signal to the process of the calling thread. - -Note: This is similar to `raise` in POSIX. - -Inputs: - -- [\_\_wasi\_signal\_t](#signal) sig - - The signal condition to trigger. - -### `__wasi_random_get()` - -Write high-quality random data into a buffer. - -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. - -This function may execute slowly, so when large mounts of random -data are required, it's advisable to use this function to seed a -pseudo-random number generator, rather than to provide the -random data directly. - -Inputs: - -- void \*buf and size\_t buf\_len - - The buffer to fill with random data. - -### `__wasi_sched_yield()` - -Temporarily yield execution of the calling thread. - -Note: This is similar to `sched_yield` in POSIX. - -### `__wasi_sock_recv()` - -Receive a message from a socket. - -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to receive data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len - - List of scatter/gather vectors to which to store data. - -- [\_\_wasi\_riflags\_t](#riflags) ri\_flags - - Message flags. - -Outputs: - -- size\_t ro\_datalen - - Number of bytes stored in [`ri_data`](#sock_recv.ri_data). - -- [\_\_wasi\_roflags\_t](#roflags) ro\_flags - - Message flags. - -### `__wasi_sock_send()` - -Send a message on a socket. - -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to send data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len - - List of scatter/gather vectors to which to retrieve data - -- [\_\_wasi\_siflags\_t](#siflags) si\_flags - - Message flags. - -Outputs: - -- size\_t so\_datalen - - Number of bytes transmitted. - -### `__wasi_sock_shutdown()` - -Shut down socket send and receive channels. - -Note: This is similar to `shutdown` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to shutdown channels. - -- [\_\_wasi\_sdflags\_t](#sdflags) how - - Which channels on the socket to shut down. - -## Types - -### `__wasi_advice_t` (`uint8_t`) - -File or memory access pattern advisory information. - -Used by [`__wasi_fd_advise()`](#fd_advise). - -Possible values: - -- **`__WASI_ADVICE_NORMAL`** - - The application has no advice to give on its behavior - with respect to the specified data. - -- **`__WASI_ADVICE_SEQUENTIAL`** - - The application expects to access the specified data - sequentially from lower offsets to higher offsets. - -- **`__WASI_ADVICE_RANDOM`** - - The application expects to access the specified data - in a random order. - -- **`__WASI_ADVICE_WILLNEED`** - - The application expects to access the specified data - in the near future. - -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - -### `__wasi_ciovec_t` (`struct`) - -A region of memory for scatter/gather writes. - -Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). - -Members: - -- const void \*buf and size\_t buf\_len - - The address and length of the buffer to be written. - -### `__wasi_clockid_t` (`uint32_t`) - -Identifiers for clocks. - -Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). - -Possible values: - -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - -- **`__WASI_CLOCK_MONOTONIC`** - - The store-wide monotonic clock, which is defined as a - clock measuring real time, whose value cannot be - adjusted and which cannot have negative clock jumps. - - The epoch of this clock is undefined. The absolute - time value of this clock therefore has no meaning. - -- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** - - The CPU-time clock associated with the current - process. - -- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** - - The CPU-time clock associated with the current thread. - -### `__wasi_device_t` (`uint64_t`) - -Identifier for a device containing a file system. Can be used -in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or -directory in the filesystem. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_dircookie_t` (`uint64_t`) - -A reference to the offset of a directory entry. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). - -Special values: - -- **`__WASI_DIRCOOKIE_START`** - - Permanent reference to the first directory entry - within a directory. - -### `__wasi_dirent_t` (`struct`) - -A directory entry. - -Members: - -- [\_\_wasi\_dircookie\_t](#dircookie) d\_next - - The offset of the next directory entry stored in this - directory. - -- [\_\_wasi\_inode\_t](#inode) d\_ino - - The serial number of the file referred to by this - directory entry. - -- uint32\_t d\_namlen - - The length of the name of the directory entry. - -- [\_\_wasi\_filetype\_t](#filetype) d\_type - - The type of the file referred to by this directory - entry. - -### `__wasi_errno_t` (`uint16_t`) - -Error codes returned by functions. - -Not all of these error codes are returned by the functions -provided by this API; some are used in higher-level library layers, -and others are provided merely for alignment with POSIX. - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_ESUCCESS`** - - No error occurred. System call completed successfully. - -- **`__WASI_E2BIG`** - - Argument list too long. - -- **`__WASI_EACCES`** - - Permission denied. - -- **`__WASI_EADDRINUSE`** - - Address in use. - -- **`__WASI_EADDRNOTAVAIL`** - - Address not available. - -- **`__WASI_EAFNOSUPPORT`** - - Address family not supported. - -- **`__WASI_EAGAIN`** - - Resource unavailable, or operation would block. - -- **`__WASI_EALREADY`** - - Connection already in progress. - -- **`__WASI_EBADF`** - - Bad file descriptor. - -- **`__WASI_EBADMSG`** - - Bad message. - -- **`__WASI_EBUSY`** - - Device or resource busy. - -- **`__WASI_ECANCELED`** - - Operation canceled. - -- **`__WASI_ECHILD`** - - No child processes. - -- **`__WASI_ECONNABORTED`** - - Connection aborted. - -- **`__WASI_ECONNREFUSED`** - - Connection refused. - -- **`__WASI_ECONNRESET`** - - Connection reset. - -- **`__WASI_EDEADLK`** - - Resource deadlock would occur. - -- **`__WASI_EDESTADDRREQ`** - - Destination address required. - -- **`__WASI_EDOM`** - - Mathematics argument out of domain of function. - -- **`__WASI_EDQUOT`** - - Reserved. - -- **`__WASI_EEXIST`** - - File exists. - -- **`__WASI_EFAULT`** - - Bad address. - -- **`__WASI_EFBIG`** - - File too large. - -- **`__WASI_EHOSTUNREACH`** - - Host is unreachable. - -- **`__WASI_EIDRM`** - - Identifier removed. - -- **`__WASI_EILSEQ`** - - Illegal byte sequence. - -- **`__WASI_EINPROGRESS`** - - Operation in progress. - -- **`__WASI_EINTR`** - - Interrupted function. - -- **`__WASI_EINVAL`** - - Invalid argument. - -- **`__WASI_EIO`** - - I/O error. - -- **`__WASI_EISCONN`** - - Socket is connected. - -- **`__WASI_EISDIR`** - - Is a directory. - -- **`__WASI_ELOOP`** - - Too many levels of symbolic links. - -- **`__WASI_EMFILE`** - - File descriptor value too large. - -- **`__WASI_EMLINK`** - - Too many links. - -- **`__WASI_EMSGSIZE`** - - Message too large. - -- **`__WASI_EMULTIHOP`** - - Reserved. - -- **`__WASI_ENAMETOOLONG`** - - Filename too long. - -- **`__WASI_ENETDOWN`** - - Network is down. - -- **`__WASI_ENETRESET`** - - Connection aborted by network. - -- **`__WASI_ENETUNREACH`** - - Network unreachable. - -- **`__WASI_ENFILE`** - - Too many files open in system. - -- **`__WASI_ENOBUFS`** - - No buffer space available. - -- **`__WASI_ENODEV`** - - No such device. - -- **`__WASI_ENOENT`** - - No such file or directory. - -- **`__WASI_ENOEXEC`** - - Executable file format error. - -- **`__WASI_ENOLCK`** - - No locks available. - -- **`__WASI_ENOLINK`** - - Reserved. - -- **`__WASI_ENOMEM`** - - Not enough space. - -- **`__WASI_ENOMSG`** - - No message of the desired type. - -- **`__WASI_ENOPROTOOPT`** - - Protocol not available. - -- **`__WASI_ENOSPC`** - - No space left on device. - -- **`__WASI_ENOSYS`** - - Function not supported. - -- **`__WASI_ENOTCONN`** - - The socket is not connected. - -- **`__WASI_ENOTDIR`** - - Not a directory or a symbolic link to a directory. - -- **`__WASI_ENOTEMPTY`** - - Directory not empty. - -- **`__WASI_ENOTRECOVERABLE`** - - State not recoverable. - -- **`__WASI_ENOTSOCK`** - - Not a socket. - -- **`__WASI_ENOTSUP`** - - Not supported, or operation not supported on socket. - -- **`__WASI_ENOTTY`** - - Inappropriate I/O control operation. - -- **`__WASI_ENXIO`** - - No such device or address. - -- **`__WASI_EOVERFLOW`** - - Value too large to be stored in data type. - -- **`__WASI_EOWNERDEAD`** - - Previous owner died. - -- **`__WASI_EPERM`** - - Operation not permitted. - -- **`__WASI_EPIPE`** - - Broken pipe. - -- **`__WASI_EPROTO`** - - Protocol error. - -- **`__WASI_EPROTONOSUPPORT`** - - Protocol not supported. - -- **`__WASI_EPROTOTYPE`** - - Protocol wrong type for socket. - -- **`__WASI_ERANGE`** - - Result too large. - -- **`__WASI_EROFS`** - - Read-only file system. - -- **`__WASI_ESPIPE`** - - Invalid seek. - -- **`__WASI_ESRCH`** - - No such process. - -- **`__WASI_ESTALE`** - - Reserved. - -- **`__WASI_ETIMEDOUT`** - - Connection timed out. - -- **`__WASI_ETXTBSY`** - - Text file busy. - -- **`__WASI_EXDEV`** - - Cross-device link. - -- **`__WASI_ENOTCAPABLE`** - - Extension: Capabilities insufficient. - -### `__wasi_event_t` (`struct`) - -An event that occurred. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that got attached to - [`__wasi_subscription_t::userdata`](#subscription.userdata). - -- [\_\_wasi\_errno\_t](#errno) error - - If non-zero, an error that occurred while processing - the subscription request. - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event that occurred. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_filesize\_t](#filesize) nbytes - - The number of bytes available for reading or writing. - - - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags - - The state of the file descriptor. - -### `__wasi_eventrwflags_t` (`uint16_t` bitfield) - -The state of the file descriptor subscribed to with -[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_EVENT_FD_READWRITE_HANGUP`** - - The peer of this socket has closed or disconnected. - -### `__wasi_eventtype_t` (`uint8_t`) - -Type of a subscription to an event or its occurrence. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_EVENTTYPE_CLOCK`** - - The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) - has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -- **`__WASI_EVENTTYPE_FD_READ`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - data available for reading. This event always triggers - for regular files. - -- **`__WASI_EVENTTYPE_FD_WRITE`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - capacity available for writing. This event always - triggers for regular files. - -### `__wasi_exitcode_t` (`uint32_t`) - -Exit code generated by a process when exiting. - -Used by [`__wasi_proc_exit()`](#proc_exit). - -### `__wasi_fd_t` (`uint32_t`) - -A file descriptor number. - -Used by many functions in this API. - -As in POSIX, three file descriptor numbers are provided to instances -on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, -and `STDERR_FILENO`). - -Other than these, WASI implementations are not required to allocate -new file descriptors in ascending order. - -### `__wasi_fdflags_t` (`uint16_t` bitfield) - -File descriptor flags. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_FDFLAG_APPEND`** - - Append mode: Data written to the file is always - appended to the file's end. - -- **`__WASI_FDFLAG_DSYNC`** - - Write according to synchronized I/O data integrity - completion. Only the data stored in the file is - synchronized. - -- **`__WASI_FDFLAG_NONBLOCK`** - - Non-blocking mode. - -- **`__WASI_FDFLAG_RSYNC`** - - Synchronized read I/O operations. - -- **`__WASI_FDFLAG_SYNC`** - - Write according to synchronized I/O file integrity completion. - In addition to synchronizing the data stored in the file, the - implementation may also synchronously update the file's metadata. - -### `__wasi_fdstat_t` (`struct`) - -File descriptor attributes. - -Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). - -Members: - -- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype - - File type. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - File descriptor flags. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base - - Rights that apply to this file descriptor. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - Maximum set of rights that may be installed on new - file descriptors that are created through this file - descriptor, e.g., through [`__wasi_path_open()`](#path_open). - -### `__wasi_filedelta_t` (`int64_t`) - -Relative offset within a file. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -### `__wasi_filesize_t` (`uint64_t`) - -Non-negative file size or length of a region within a file. - -Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -### `__wasi_filestat_t` (`struct`) - -File attributes. - -Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). - -Members: - -- [\_\_wasi\_device\_t](#device) st\_dev - - Device ID of device containing the file. - -- [\_\_wasi\_inode\_t](#inode) st\_ino - - File serial number. - -- [\_\_wasi\_filetype\_t](#filetype) st\_filetype - - File type. - -- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink - - Number of hard links to the file. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - For regular files, the file size in bytes. For - symbolic links, the length in bytes of the pathname - contained in the symbolic link. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - Last data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - Last data modification timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim - - Last file status change timestamp. - -### `__wasi_filetype_t` (`uint8_t`) - -The type of a file descriptor or file. - -Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). - -Possible values: - -- **`__WASI_FILETYPE_UNKNOWN`** - - The type of the file descriptor or file is unknown or - is different from any of the other types specified. - -- **`__WASI_FILETYPE_BLOCK_DEVICE`** - - The file descriptor or file refers to a block device - inode. - -- **`__WASI_FILETYPE_CHARACTER_DEVICE`** - - The file descriptor or file refers to a character - device inode. - -- **`__WASI_FILETYPE_DIRECTORY`** - - The file descriptor or file refers to a directory - inode. - -- **`__WASI_FILETYPE_REGULAR_FILE`** - - The file descriptor or file refers to a regular file - inode. - -- **`__WASI_FILETYPE_SOCKET_DGRAM`** - - The file descriptor or file refers to a datagram - socket. - -- **`__WASI_FILETYPE_SOCKET_STREAM`** - - The file descriptor or file refers to a byte-stream - socket. - -- **`__WASI_FILETYPE_SYMBOLIC_LINK`** - - The file refers to a symbolic link inode. - -### `__wasi_fstflags_t` (`uint16_t` bitfield) - -Which file time attributes to adjust. - -Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -Possible values: - -- **`__WASI_FILESTAT_SET_ATIM`** - - Adjust the last data access timestamp to the value - stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). - -- **`__WASI_FILESTAT_SET_ATIM_NOW`** - - Adjust the last data access timestamp to the time - of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -- **`__WASI_FILESTAT_SET_MTIM`** - - Adjust the last data modification timestamp to the - value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). - -- **`__WASI_FILESTAT_SET_MTIM_NOW`** - - Adjust the last data modification timestamp to the - time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -### `__wasi_inode_t` (`uint64_t`) - -File serial number that is unique within its file system. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). - -### `__wasi_iovec_t` (`struct`) - -A region of memory for scatter/gather reads. - -Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). - -Members: - -- void \*buf and size\_t buf\_len - - The address and length of the buffer to be filled. - -### `__wasi_linkcount_t` (`uint64_t`) - -Number of hard links to an inode. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_lookupflags_t` (`uint32_t` bitfield) - -Flags determining the method of how paths are resolved. - -Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** - - As long as the resolved path corresponds to a symbolic - link, it is expanded. - -### `__wasi_oflags_t` (`uint16_t` bitfield) - -Open flags used by [`__wasi_path_open()`](#path_open). - -Used by [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_O_CREAT`** - - Create file if it does not exist. - -- **`__WASI_O_DIRECTORY`** - - Fail if not a directory. - -- **`__WASI_O_EXCL`** - - Fail if file already exists. - -- **`__WASI_O_TRUNC`** - - Truncate file to size 0. - -### `__wasi_riflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_PEEK`** - - Returns the message without removing it from the - socket's receive queue. - -- **`__WASI_SOCK_RECV_WAITALL`** - - On byte-stream sockets, block until the full amount - of data can be returned. - -### `__wasi_rights_t` (`uint64_t` bitfield) - -File descriptor rights, determining which actions may be -performed. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_RIGHT_FD_DATASYNC`** - - The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_READ`** - - The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke - [`__wasi_fd_pread()`](#fd_pread). - -- **`__WASI_RIGHT_FD_SEEK`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies - [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). - -- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** - - The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). - -- **`__WASI_RIGHT_FD_SYNC`** - - The right to invoke [`__wasi_fd_sync()`](#fd_sync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and - [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_TELL`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the - file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with - offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). - -- **`__WASI_RIGHT_FD_WRITE`** - - The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to - invoke [`__wasi_fd_pwrite()`](#fd_pwrite). - -- **`__WASI_RIGHT_FD_ADVISE`** - - The right to invoke [`__wasi_fd_advise()`](#fd_advise). - -- **`__WASI_RIGHT_FD_ALLOCATE`** - - The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). - -- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** - - The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). - -- **`__WASI_RIGHT_PATH_CREATE_FILE`** - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke - [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). - -- **`__WASI_RIGHT_PATH_LINK_SOURCE`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_LINK_TARGET`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_OPEN`** - - The right to invoke [`__wasi_path_open()`](#path_open). - -- **`__WASI_RIGHT_FD_READDIR`** - - The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). - -- **`__WASI_RIGHT_PATH_READLINK`** - - The right to invoke [`__wasi_path_readlink()`](#path_readlink). - -- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_RENAME_TARGET`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_FILESTAT_GET`** - - The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** - - The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -- **`__WASI_RIGHT_FD_FILESTAT_GET`** - - The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** - - The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). - -- **`__WASI_RIGHT_PATH_SYMLINK`** - - The right to invoke [`__wasi_path_symlink()`](#path_symlink). - -- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** - - The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). - -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - -- **`__WASI_RIGHT_POLL_FD_READWRITE`** - - If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). - - If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -- **`__WASI_RIGHT_SOCK_SHUTDOWN`** - - The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). - -### `__wasi_roflags_t` (`uint16_t` bitfield) - -Flags returned by [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** - - Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been - truncated. - -### `__wasi_sdflags_t` (`uint8_t` bitfield) - -Which channels on a socket to shut down. - -Used by [`__wasi_sock_shutdown()`](#sock_shutdown). - -Possible values: - -- **`__WASI_SHUT_RD`** - - Disables further receive operations. - -- **`__WASI_SHUT_WR`** - - Disables further send operations. - -### `__wasi_siflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Used by [`__wasi_sock_send()`](#sock_send). - -### `__wasi_signal_t` (`uint8_t`) - -Signal condition. - -Used by [`__wasi_proc_raise()`](#proc_raise). - -Possible values: - -- **`__WASI_SIGHUP`** - - Hangup. - - Action: Terminates the process. - -- **`__WASI_SIGINT`** - - Terminate interrupt signal. - - Action: Terminates the process. - -- **`__WASI_SIGQUIT`** - - Terminal quit signal. - - Action: Terminates the process. - -- **`__WASI_SIGILL`** - - Illegal instruction. - - Action: Terminates the process. - -- **`__WASI_SIGTRAP`** - - Trace/breakpoint trap. - - Action: Terminates the process. - -- **`__WASI_SIGABRT`** - - Process abort signal. - - Action: Terminates the process. - -- **`__WASI_SIGBUS`** - - Access to an undefined portion of a memory object. - - Action: Terminates the process. - -- **`__WASI_SIGFPE`** - - Erroneous arithmetic operation. - - Action: Terminates the process. - -- **`__WASI_SIGKILL`** - - Kill. - - Action: Terminates the process. - -- **`__WASI_SIGUSR1`** - - User-defined signal 1. - - Action: Terminates the process. - -- **`__WASI_SIGSEGV`** - - Invalid memory reference. - - Action: Terminates the process. - -- **`__WASI_SIGUSR2`** - - User-defined signal 2. - - Action: Terminates the process. - -- **`__WASI_SIGPIPE`** - - Write on a pipe with no one to read it. - - Action: Ignored. - -- **`__WASI_SIGALRM`** - - Alarm clock. - - Action: Terminates the process. - -- **`__WASI_SIGTERM`** - - Termination signal. - - Action: Terminates the process. - -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** - - Continue executing, if stopped. - - Action: Continues executing, if stopped. - -- **`__WASI_SIGSTOP`** - - Stop executing. - - Action: Stops executing. - -- **`__WASI_SIGTSTP`** - - Terminal stop signal. - - Action: Stops executing. - -- **`__WASI_SIGTTIN`** - - Background process attempting read. - - Action: Stops executing. - -- **`__WASI_SIGTTOU`** - - Background process attempting write. - - Action: Stops executing. - -- **`__WASI_SIGURG`** - - High bandwidth data is available at a socket. - - Action: Ignored. - -- **`__WASI_SIGXCPU`** - - CPU time limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGXFSZ`** - - File size limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGVTALRM`** - - Virtual timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGPROF`** - - Profiling timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGWINCH`** - - Window changed. - - Action: Ignored. - -- **`__WASI_SIGPOLL`** - - I/O possible. - - Action: Terminates the process. - -- **`__WASI_SIGPWR`** - - Power failure. - - Action: Terminates the process. - -- **`__WASI_SIGSYS`** - - Bad system call. - - Action: Terminates the process. - -### `__wasi_subclockflags_t` (`uint16_t` bitfield) - -Flags determining how to interpret the timestamp provided in -[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -Used by [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** - - If set, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp - of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - - If clear, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current - time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - -### `__wasi_subscription_t` (`struct`) - -Subscription to an event. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that is attached to the subscription in the - implementation and returned through - [`__wasi_event_t::userdata`](#event.userdata). - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event to which to subscribe. - -- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): - - - **`u.clock`** - - - [\_\_wasi\_clockid\_t](#clockid) id - - The clock against which to compare the timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) timeout - - The absolute or relative timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) precision - - The amount of time that the implementation may wait additionally - to coalesce with other events. - - - [\_\_wasi\_subclockflags\_t](#subclockflags) flags - - Flags specifying whether the timeout is absolute or relative. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor on which to wait for it to become ready - for reading or writing. - -### `__wasi_timestamp_t` (`uint64_t`) - -Timestamp in nanoseconds. - -Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -### `__wasi_userdata_t` (`uint64_t`) - -User-provided value that may be attached to objects that is -retained when extracted from the implementation. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -### `__wasi_whence_t` (`uint8_t`) - -The position relative to which to set the offset of the file descriptor. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -Possible values: - -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - -- **`__WASI_WHENCE_CUR`** - - Seek relative to current position. - -- **`__WASI_WHENCE_END`** - - Seek relative to end-of-file. From a3eb772ffa46a6183fbd183a49cfa35716134845 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 14:22:28 -0800 Subject: [PATCH 0501/1772] replace legacy docs with new generated docs --- proposals/filesystem/phases/ephemeral/docs.md | 1787 +++++++++++++ .../filesystem/phases/old/snapshot_0/docs.md | 1791 +++++++++++++ .../old/snapshot_0/docs/wasi_unstable.md | 2343 ---------------- proposals/filesystem/phases/snapshot/docs.md | 1790 +++++++++++++ .../snapshot/docs/wasi_unstable_preview1.md | 2346 ----------------- 5 files changed, 5368 insertions(+), 4689 deletions(-) create mode 100644 proposals/filesystem/phases/ephemeral/docs.md create mode 100644 proposals/filesystem/phases/old/snapshot_0/docs.md delete mode 100644 proposals/filesystem/phases/old/snapshot_0/docs/wasi_unstable.md create mode 100644 proposals/filesystem/phases/snapshot/docs.md delete mode 100644 proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md new file mode 100644 index 000000000..8465cd8b7 --- /dev/null +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -0,0 +1,1787 @@ +# Types +## `size`: `usize` + +## `filesize`: `u64` +Non-negative file size or length of a region within a file. + +## `timestamp`: `u64` +Timestamp in nanoseconds. + +## `clockid`: Enum(`u32`) +Identifiers for clocks. + +### Variants +- `realtime` +The clock measuring real time. Time value zero corresponds with +1970-01-01T00:00:00Z. + +- `monotonic` +The store-wide monotonic clock, which is defined as a clock measuring +real time, whose value cannot be adjusted and which cannot have negative +clock jumps. The epoch of this clock is undefined. The absolute time +value of this clock therefore has no meaning. + +- `process_cputime_id` +The CPU-time clock associated with the current process. + +- `thread_cputime_id` +The CPU-time clock associated with the current thread. + +## `errno`: Enum(`u16`) +Error codes returned by functions. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX. + +### Variants +- `success` +No error occurred. System call completed successfully. + +- `2big` +Argument list too long. + +- `acces` +Permission denied. + +- `addrinuse` +Address in use. + +- `addrnotavail` +Address not available. + +- `afnosupport` +Address family not supported. + +- `again` +Resource unavailable, or operation would block. + +- `already` +Connection already in progress. + +- `badf` +Bad file descriptor. + +- `badmsg` +Bad message. + +- `busy` +Device or resource busy. + +- `canceled` +Operation canceled. + +- `child` +No child processes. + +- `connaborted` +Connection aborted. + +- `connrefused` +Connection refused. + +- `connreset` +Connection reset. + +- `deadlk` +Resource deadlock would occur. + +- `destaddrreq` +Destination address required. + +- `dom` +Mathematics argument out of domain of function. + +- `dquot` +Reserved. + +- `exist` +File exists. + +- `fault` +Bad address. + +- `fbig` +File too large. + +- `hostunreach` +Host is unreachable. + +- `idrm` +Identifier removed. + +- `ilseq` +Illegal byte sequence. + +- `inprogress` +Operation in progress. + +- `intr` +Interrupted function. + +- `inval` +Invalid argument. + +- `io` +I/O error. + +- `isconn` +Socket is connected. + +- `isdir` +Is a directory. + +- `loop` +Too many levels of symbolic links. + +- `mfile` +File descriptor value too large. + +- `mlink` +Too many links. + +- `msgsize` +Message too large. + +- `multihop` +Reserved. + +- `nametoolong` +Filename too long. + +- `netdown` +Network is down. + +- `netreset` +Connection aborted by network. + +- `netunreach` +Network unreachable. + +- `nfile` +Too many files open in system. + +- `nobufs` +No buffer space available. + +- `nodev` +No such device. + +- `noent` +No such file or directory. + +- `noexec` +Executable file format error. + +- `nolck` +No locks available. + +- `nolink` +Reserved. + +- `nomem` +Not enough space. + +- `nomsg` +No message of the desired type. + +- `noprotoopt` +Protocol not available. + +- `nospc` +No space left on device. + +- `nosys` +Function not supported. + +- `notconn` +The socket is not connected. + +- `notdir` +Not a directory or a symbolic link to a directory. + +- `notempty` +Directory not empty. + +- `notrecoverable` +State not recoverable. + +- `notsock` +Not a socket. + +- `notsup` +Not supported, or operation not supported on socket. + +- `notty` +Inappropriate I/O control operation. + +- `nxio` +No such device or address. + +- `overflow` +Value too large to be stored in data type. + +- `ownerdead` +Previous owner died. + +- `perm` +Operation not permitted. + +- `pipe` +Broken pipe. + +- `proto` +Protocol error. + +- `protonosupport` +Protocol not supported. + +- `prototype` +Protocol wrong type for socket. + +- `range` +Result too large. + +- `rofs` +Read-only file system. + +- `spipe` +Invalid seek. + +- `srch` +No such process. + +- `stale` +Reserved. + +- `timedout` +Connection timed out. + +- `txtbsy` +Text file busy. + +- `xdev` +Cross-device link. + +- `notcapable` +Extension: Capabilities insufficient. + +## `rights`: Flags(`u64`) +File descriptor rights, determining which actions may be performed. + +### Flags +- `fd_datasync` +The right to invoke `fd_datasync`. +If `path_open` is set, includes the right to invoke +`path_open` with `fdflag::dsync`. + +- `fd_read` +The right to invoke `fd_read` and `sock_recv`. +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. + +- `fd_seek` +The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). + +- `fd_fdstat_set_flags` +The right to invoke `fd_fdstat_set_flags`. + +- `fd_sync` +The right to invoke `fd_sync`. +If `path_open` is set, includes the right to invoke +`path_open` with `fdflag::rsync` and `fdflag::dsync`. + +- `fd_tell` +The right to invoke `fd_seek` in such a way that the file offset +remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +invoke `fd_tell`. + +- `fd_write` +The right to invoke `fd_write` and `sock_send`. +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. + +- `fd_advise` +The right to invoke `fd_advise`. + +- `fd_allocate` +The right to invoke `fd_allocate`. + +- `path_create_directory` +The right to invoke `path_create_directory`. + +- `path_create_file` +If `path_open` is set, the right to invoke `path_open` with [`oflags::creat`](#oflags.creat). + +- `path_link_source` +The right to invoke `path_link` with the file descriptor as the +source directory. + +- `path_link_target` +The right to invoke `path_link` with the file descriptor as the +target directory. + +- `path_open` +The right to invoke `path_open`. + +- `fd_readdir` +The right to invoke `fd_readdir`. + +- `path_readlink` +The right to invoke `path_readlink`. + +- `path_rename_source` +The right to invoke `path_rename` with the file descriptor as the source directory. + +- `path_rename_target` +The right to invoke `path_rename` with the file descriptor as the target directory. + +- `path_filestat_get` +The right to invoke `path_filestat_get`. + +- `path_filestat_set_size` +The right to change a file's size (there is no `path_filestat_set_size`). +If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). + +- `path_filestat_set_times` +The right to invoke `path_filestat_set_times`. + +- `path_permissions_set` +The right to invoke `path_filestat_set_permissions`. + +- `fd_filestat_get` +The right to invoke `fd_filestat_get`. + +- `fd_filestat_set_size` +The right to invoke `fd_filestat_set_size`. + +- `fd_filestat_set_times` +The right to invoke `fd_filestat_set_times`. + +- `fd_permissions_set` +The right to invoke `fd_filestat_set_permissions`. + +- `path_symlink` +The right to invoke `path_symlink`. + +- `path_remove_directory` +The right to invoke `path_remove_directory`. + +- `path_unlink_file` +The right to invoke `path_unlink_file`. + +- `poll_fd_readwrite` +If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). +If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). + +- `sock_shutdown` +The right to invoke `sock_shutdown`. + +## `fd` +A file descriptor handle. + +### Supertypes +## `iovec`: Struct +A region of memory for scatter/gather reads. + +### Struct members +- `buf`: `Pointer` +The address of the buffer to be filled. + +- `buf_len`: [`size`](#size) +The length of the buffer to be filled. + +## `ciovec`: Struct +A region of memory for scatter/gather writes. + +### Struct members +- `buf`: `ConstPointer` +The address of the buffer to be written. + +- `buf_len`: [`size`](#size) +The length of the buffer to be written. + +## `iovec_array`: `Array` + +## `ciovec_array`: `Array` + +## `filedelta`: `s64` +Relative offset within a file. + +## `whence`: Enum(`u8`) +The position relative to which to set the offset of the file descriptor. + +### Variants +- `set` +Seek relative to start-of-file. + +- `cur` +Seek relative to current position. + +- `end` +Seek relative to end-of-file. + +## `dircookie`: Int(`u64`) +A reference to the offset of a directory entry. + +### Consts +- `start` + +## `dirnamlen`: `u32` +The type for the $d_namlen field of $dirent. + +## `inode`: `u64` +File serial number that is unique within its file system. + +## `filetype`: Enum(`u8`) +The type of a file descriptor or file. + +### Variants +- `unknown` +The type of the file descriptor or file is unknown or is different from any of the other types specified. + +- `block_device` +The file descriptor or file refers to a block device inode. + +- `character_device` +The file descriptor or file refers to a character device inode. + +- `directory` +The file descriptor or file refers to a directory inode. + +- `regular_file` +The file descriptor or file refers to a regular file inode. + +- `socket_dgram` +The file descriptor or file refers to a datagram socket. + +- `socket_stream` +The file descriptor or file refers to a byte-stream socket. + +- `symbolic_link` +The file refers to a symbolic link inode. + +- `fifo` +The file descriptor or file refers to a FIFO. + +## `dirent`: Struct +A directory entry. + +### Struct members +- `d_next`: [`dircookie`](#dircookie) +The offset of the next directory entry stored in this directory. + +- `d_ino`: [`inode`](#inode) +The serial number of the file referred to by this directory entry. + +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. + +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. + +## `advice`: Enum(`u8`) +File or memory access pattern advisory information. + +### Variants +- `normal` +The application has no advice to give on its behavior with respect to the specified data. + +- `sequential` +The application expects to access the specified data sequentially from lower offsets to higher offsets. + +- `random` +The application expects to access the specified data in a random order. + +- `willneed` +The application expects to access the specified data in the near future. + +- `dontneed` +The application expects that it will not access the specified data in the near future. + +- `noreuse` +The application expects to access the specified data once and then not reuse it thereafter. + +## `fdflags`: Flags(`u16`) +File descriptor flags. + +### Flags +- `append` +Append mode: Data written to the file is always appended to the file's end. + +- `dsync` +Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + +- `nonblock` +Non-blocking mode. + +- `rsync` +Synchronized read I/O operations. + +- `sync` +Write according to synchronized I/O file integrity completion. In +addition to synchronizing the data stored in the file, the implementation +may also synchronously update the file's metadata. + +## `fdstat`: Struct +File descriptor attributes. + +### Struct members +- `fs_filetype`: [`filetype`](#filetype) +File type. + +- `fs_flags`: [`fdflags`](#fdflags) +File descriptor flags. + +- `fs_rights_base`: [`rights`](#rights) +Rights that apply to this file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) +Maximum set of rights that may be installed on new file descriptors that +are created through this file descriptor, e.g., through `path_open`. + +## `device`: `u64` +Identifier for a device containing a file system. Can be used in combination +with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. + +## `fstflags`: Flags(`u16`) +Which file time attributes to adjust. + +### Flags +- `atim` +Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + +- `atim_now` +Adjust the last data access timestamp to the time of clock `clock::realtime`. + +- `mtim` +Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + +- `mtim_now` +Adjust the last data modification timestamp to the time of clock `clock::realtime`. + +## `lookupflags`: Flags(`u32`) +Flags determining the method of how paths are resolved. + +### Flags +- `symlink_follow` +As long as the resolved path corresponds to a symbolic link, it is expanded. + +## `oflags`: Flags(`u16`) +Open flags used by `path_open`. + +### Flags +- `creat` +Create file if it does not exist. + +- `directory` +Fail if not a directory. + +- `excl` +Fail if file already exists. + +- `trunc` +Truncate file to size 0. + +## `linkcount`: `u64` +Number of hard links to an inode. + +## `permissions`: Flags(`u8`) +File permissions. This represents the permissions associated with a +file in a filesystem, and don't fully reflect all the conditions +which determine whether a given WASI program can access the file. + +### Flags +- `read` +For files, permission to read the file. +For directories, permission to do [`readdir`](#readdir) and access files +within the directory. + +Note: This is similar to the read bit being set on files, and the +read *and* execute bits being set on directories, in POSIX. + +- `write` +For files, permission to mutate the file. +For directories, permission to create, remove, and rename items +within the directory. + +- `execute` +For files, permission to "execute" the file, using whatever +concept of "executing" the host filesystem has. +This flag is not valid for directories. + +- `private` +For filesystems which have a concept of multiple "users", this flag +indicates that the file is only accessible by the effective "user" +that the WASI store uses to access the filesystem, and inaccessible +to other "users". + +## `filestat`: Struct +File attributes. + +### Struct members +- `dev`: [`device`](#device) +Device ID of device containing the file. + +- `ino`: [`inode`](#inode) +File serial number. + +- `filetype`: [`filetype`](#filetype) +File type. + +- `permissions`: [`permissions`](#permissions) +File permissions. + +- `nlink`: [`linkcount`](#linkcount) +Number of hard links to the file. + +- `size`: [`filesize`](#filesize) +For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + +- `atim`: [`timestamp`](#timestamp) +Last data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +Last data modification timestamp. + +- `ctim`: [`timestamp`](#timestamp) +Last file status change timestamp. + +## `userdata`: `u64` +User-provided value that may be attached to objects that is retained when +extracted from the implementation. + +## `eventtype`: Enum(`u8`) +Type of a subscription to an event or its occurrence. + +### Variants +- `clock` +The time value of clock `subscription::u.clock.clock_id` has +reached timestamp `subscription::u.clock.timeout`. + +- `fd_read` +File descriptor `subscription::u.fd_readwrite.fd` has data +available for reading. This event always triggers for regular files. + +- `fd_write` +File descriptor `subscription::u.fd_readwrite.fd` has capacity +available for writing. This event always triggers for regular files. + +## `eventrwflags`: Flags(`u16`) +The state of the file descriptor subscribed to with +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Flags +- `fd_readwrite_hangup` +The peer of this socket has closed or disconnected. + +## `event_fd_readwrite`: Struct +The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `nbytes`: [`filesize`](#filesize) +The number of bytes available for reading or writing. + +- `flags`: [`eventrwflags`](#eventrwflags) +The state of the file descriptor. + +## `event_u`: Union +The contents of an $event. + +### Union variants +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `event`: Struct +An event that occurred. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). + +- `error`: [`errno`](#errno) +If non-zero, an error that occurred while processing the subscription request. + +- `type`: [`eventtype`](#eventtype) +The type of the event that occurred. + +- `u`: [`event_u`](#event_u) +The contents of the event. + +## `subclockflags`: Flags(`u16`) +Flags determining how to interpret the timestamp provided in +`subscription::u.clock.timeout.` + +### Flags +- `subscription_clock_abstime` +If set, treat the timestamp provided in +`subscription::u.clock.timeout` as an absolute timestamp of clock +`subscription::u.clock.clock_id.` If clear, treat the timestamp +provided in `subscription::u.clock.timeout` relative to the +current time value of clock `subscription::u.clock.clock_id.` + +## `subscription_clock`: Struct +The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). + +### Struct members +- `id`: [`clockid`](#clockid) +The clock against which to compare the timestamp. + +- `timeout`: [`timestamp`](#timestamp) +The absolute or relative timestamp. + +- `precision`: [`timestamp`](#timestamp) +The amount of time that the implementation may wait additionally +to coalesce with other events. + +- `flags`: [`subclockflags`](#subclockflags) +Flags specifying whether the timeout is absolute or relative + +## `subscription_fd_readwrite`: Struct +The contents of a $subscription when type is type is +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `file_descriptor`: [`fd`](#fd) +The file descriptor on which to wait for it to become ready for reading or writing. + +## `subscription_u`: Union +The contents of a $subscription. + +### Union variants +- `clock`: [`subscription_clock`](#subscription_clock) +When type is [`eventtype::clock`](#eventtype.clock): + +- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `subscription`: Struct +Subscription to an event. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that is attached to the subscription in the +implementation and returned through [`event::userdata`](#event.userdata). + +- `type`: [`eventtype`](#eventtype) +The type of the event to which to subscribe. + +- `u`: [`subscription_u`](#subscription_u) +The contents of the subscription. + +## `exitcode`: `u32` +Exit code generated by a process when exiting. + +## `riflags`: Flags(`u16`) +Flags provided to `sock_recv`. + +### Flags +- `recv_peek` +Returns the message without removing it from the socket's receive queue. + +- `recv_waitall` +On byte-stream sockets, block until the full amount of data can be returned. + +## `roflags`: Flags(`u16`) +Flags returned by `sock_recv`. + +### Flags +- `recv_data_truncated` +Returned by `sock_recv`: Message data has been truncated. + +## `siflags`: `u16` +Flags provided to `sock_send`. As there are currently no flags +defined, it must be set to zero. + +## `sdflags`: Flags(`u8`) +Which channels on a socket to shut down. + +### Flags +- `rd` +Disables further receive operations. + +- `wr` +Disables further send operations. + +## `preopentype`: Enum(`u8`) +Identifiers for preopened capabilities. + +### Variants +- `dir` +A pre-opened directory. + +## `prestat_dir`: Struct +The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). + +### Struct members +- `pr_name_len`: [`size`](#size) +The length of the directory name for use with `fd_prestat_dir_name`. + +## `prestat_u`: Union +The contents of an $prestat. + +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) +When type is [`preopentype::dir`](#preopentype.dir): + +## `prestat`: Struct +Information about a pre-opened capability. + +### Struct members +- `pr_type`: [`preopentype`](#preopentype) +The type of the pre-opened capability. + +- `u`: [`prestat_u`](#prestat_u) +The contents of the information. + +# Modules +## wasi_ephemeral_args +### Imports +#### Memory +### Functions + +--- + +#### `get(argv: Pointer>, argv_buf: Pointer) -> errno` +Read command-line argument data. +The size of the array should match that returned by [`sizes_get`](#sizes_get) + +##### Params +- `argv`: `Pointer>` + +- `argv_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + +## wasi_ephemeral_clock +### Imports +#### Memory +### Functions + +--- + +#### `res_get(id: clockid) -> (errno, timestamp)` +Return the resolution of a clock. +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Note: This is similar to `clock_getres` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the resolution. + +##### Results +- `error`: [`errno`](#errno) + +- `resolution`: [`timestamp`](#timestamp) +The resolution of the clock. + + +--- + +#### `time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +Return the time value of a clock. +Note: This is similar to `clock_gettime` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the time. + +- `precision`: [`timestamp`](#timestamp) +The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + +##### Results +- `error`: [`errno`](#errno) + +- `time`: [`timestamp`](#timestamp) +The time value of the clock. + +## wasi_ephemeral_environ +### Imports +#### Memory +### Functions + +--- + +#### `get(environ: Pointer>, environ_buf: Pointer) -> errno` +Read environment variable data. +The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). + +##### Params +- `environ`: `Pointer>` + +- `environ_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + +## wasi_ephemeral_fd +### Imports +#### Memory +### Functions + +--- + +#### `advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +Provide file advisory information on a file descriptor. +Note: This is similar to `posix_fadvise` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset within the file to which the advisory applies. + +- `len`: [`filesize`](#filesize) +The length of the region to which the advisory applies. + +- `advice`: [`advice`](#advice) +The advice. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `allocate(fd: fd, offset: filesize, len: filesize) -> errno` +Force the allocation of space in a file. +Note: This is similar to `posix_fallocate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset at which to start the allocation. + +- `len`: [`filesize`](#filesize) +The length of the area that is allocated. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `close(fd: fd) -> errno` +Close a file descriptor. +Note: This is similar to [`close`](#close) in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `datasync(fd: fd) -> errno` +Synchronize the data of a file to disk. +Note: This is similar to `fdatasync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fdstat_get(fd: fd) -> (errno, fdstat)` +Get the attributes of a file descriptor. +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `stat`: [`fdstat`](#fdstat) +The buffer where the file descriptor's attributes are stored. + + +--- + +#### `fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +Adjust the flags associated with a file descriptor. +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`fdflags`](#fdflags) +The desired values of the file descriptor flags. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +Adjust the rights associated with a file descriptor. +This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + +##### Params +- `fd`: [`fd`](#fd) + +- `fs_rights_base`: [`rights`](#rights) +The desired rights of the file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `filestat_get(fd: fd) -> (errno, filestat)` +Return the attributes of an open file. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `filestat_set_size(fd: fd, size: filesize) -> errno` +Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. +Note: This is similar to `ftruncate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `size`: [`filesize`](#filesize) +The desired file size. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of an open file or directory. +Note: This is similar to `futimens` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `permissions_set(fd: fd) -> (permissions, errno)` +Set the permissions of a file or directory. + +This sets the permissions associated with a file or directory in +a filesystem at the time it is called. The ability to actually access +a file or directory may depend on additional permissions not reflected +here. + +Note: This is similar `fchmod` in POSIX. + +Unlike POSIX, this doesn't expose a user/group/other distinction; +implementations in POSIX environments are suggested to consult the +umask to determine which of the user/group/other flags to modify. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `permissions`: [`permissions`](#permissions) +The permissions associated with the file. + +- `error`: [`errno`](#errno) + + +--- + +#### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +Read from a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `preadv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors in which to store data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to read. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `prestat_get(fd: fd) -> (errno, prestat)` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`prestat`](#prestat) +The buffer where the description is stored. + + +--- + +#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `Pointer` +A buffer into which to write the preopened directory name. + +- `path_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +Write to a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `pwritev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to write. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `read(fd: fd, iovs: iovec_array) -> (errno, size)` +Read from a file descriptor. +Note: This is similar to `readv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +Read directory entries from a directory. +When successful, the contents of the output buffer consist of a sequence of +directory entries. Each directory entry consists of a dirent_t object, +followed by dirent_t::d_namlen bytes holding the name of the directory +entry. +This function fills the output buffer as much as possible, potentially +truncating the last directory entry. This allows the caller to grow its +read buffer size in case it's too small to fit a single large directory +entry, or skip the oversized directory entry. + +##### Params +- `fd`: [`fd`](#fd) + +- `buf`: `Pointer` +The buffer where directory entries are stored + +- `buf_len`: [`size`](#size) + +- `cookie`: [`dircookie`](#dircookie) +The location within the directory to start reading + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + + +--- + +#### `renumber(fd: fd, to: fd) -> errno` +Atomically replace a file descriptor by renumbering another file descriptor. +Due to the strong focus on thread safety, this environment does not provide +a mechanism to duplicate or renumber a file descriptor to an arbitrary +number, like `dup2()`. This would be prone to race conditions, as an actual +file descriptor with the same number could be allocated by a different +thread at the same time. +This function provides a way to atomically renumber file descriptors, which +would disappear if `dup2()` were to be removed entirely. + +##### Params +- `fd`: [`fd`](#fd) + +- `to`: [`fd`](#fd) +The file descriptor to overwrite. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +Move the offset of a file descriptor. +Note: This is similar to `lseek` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filedelta`](#filedelta) +The number of bytes to move. + +- `whence`: [`whence`](#whence) +The base from which the offset is relative. + +##### Results +- `error`: [`errno`](#errno) + +- `newoffset`: [`filesize`](#filesize) +The new offset of the file descriptor, relative to the start of the file. + + +--- + +#### `sync(fd: fd) -> errno` +Synchronize the data and metadata of a file to disk. +Note: This is similar to `fsync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `tell(fd: fd) -> (errno, filesize)` +Return the current offset of a file descriptor. +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `offset`: [`filesize`](#filesize) +The current offset of the file descriptor, relative to the start of the file. + + +--- + +#### `write(fd: fd, iovs: ciovec_array) -> (errno, size)` +Write to a file descriptor. +Note: This is similar to `writev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + +## wasi_ephemeral_path +### Imports +#### Memory +### Functions + +--- + +#### `create_directory(fd: fd, path: string) -> errno` +Create a directory. +Note: This is similar to `mkdirat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path at which to create the directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +Return the attributes of a file or directory. +Note: This is similar to `stat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to inspect. + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of a file or directory. +Note: This is similar to `utimensat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to operate on. + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `permissions_set(fd: fd, flags: lookupflags, path: string, permissions: permissions) -> errno` +Set the permissions of a file or directory. + +This sets the permissions associated with a file or directory in +a filesystem at the time it is called. The ability to actually access +a file or directory may depend on additional permissions not reflected +here. + +Note: This is similar to `fchmodat` in POSIX. + +Unlike POSIX, this doesn't expose a user/group/other distinction; +implementations in POSIX environments are suggested to consult the +umask to determine which of the user/group/other flags to modify. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path to a file to query. + +- `permissions`: [`permissions`](#permissions) +The permissions to associate with the file. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +Create a hard link. +Note: This is similar to `linkat` in POSIX. + +##### Params +- `old_fd`: [`fd`](#fd) + +- `old_flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `old_path`: `string` +The source path from which to link. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path at which to create the hard link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags, permissions: permissions) -> (errno, fd)` +Open a file or directory. +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since this +is error-prone in multi-threaded contexts. The returned file descriptor is +guaranteed to be less than 2**31. +Note: This is similar to `openat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `dirflags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The relative path of the file or directory to open, relative to the +`dirfd` directory. + +- `oflags`: [`oflags`](#oflags) +The method by which to open the file. + +- `fs_rights_base`: [`rights`](#rights) +The initial rights of the newly created file descriptor. The +implementation is allowed to return a file descriptor with fewer rights +than specified, if and only if those rights do not apply to the type of +file being opened. +The *base* rights are rights that will apply to operations using the file +descriptor itself, while the *inheriting* rights are rights that apply to +file descriptors derived from it. + +- `fs_rights_inherting`: [`rights`](#rights) + +- `fdflags`: [`fdflags`](#fdflags) + +- `permissions`: [`permissions`](#permissions) +If a file is created, the filesystem permissions to associate with it. + +##### Results +- `error`: [`errno`](#errno) + +- `opened_fd`: [`fd`](#fd) +The file descriptor of the file that has been opened. + + +--- + +#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +Read the contents of a symbolic link. +Note: This is similar to `readlinkat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path of the symbolic link from which to read. + +- `buf`: `Pointer` +The buffer to which to write the contents of the symbolic link. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes placed in the buffer. + + +--- + +#### `remove_directory(fd: fd, path: string) -> errno` +Remove a directory. +Return `ENOTEMPTY` if the directory is not empty. +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a directory to remove. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +Rename a file or directory. +Note: This is similar to `renameat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `old_path`: `string` +The source path of the file or directory to rename. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path to which to rename the file or directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `symlink(old_path: string, fd: fd, new_path: string) -> errno` +Create a symbolic link. +Note: This is similar to `symlinkat` in POSIX. + +##### Params +- `old_path`: `string` +The contents of the symbolic link. + +- `fd`: [`fd`](#fd) + +- `new_path`: `string` +The destination path at which to create the symbolic link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `unlink_file(fd: fd, path: string) -> errno` +Unlink a file. +Return `EISDIR` if the path refers to a directory. +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a file to unlink. + +##### Results +- `error`: [`errno`](#errno) + +## wasi_ephemeral_poll +### Imports +#### Memory +### Functions + +--- + +#### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +Concurrently poll for the occurrence of a set of events. + +##### Params +- `in`: `ConstPointer` +The events to which to subscribe. + +- `out`: `Pointer` +The events that have occurred. + +- `nsubscriptions`: [`size`](#size) +Both the number of subscriptions and events. + +##### Results +- `error`: [`errno`](#errno) + +- `nevents`: [`size`](#size) +The number of events stored. + +## wasi_ephemeral_proc +### Imports +### Functions + +--- + +#### `exit(rval: exitcode)` +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +##### Params +- `rval`: [`exitcode`](#exitcode) +The exit code returned by the process. + +##### Results +## wasi_ephemeral_random +### Imports +#### Memory +### Functions + +--- + +#### `get(buf: Pointer, buf_len: size) -> errno` +Write high-quality random data into a buffer. +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. +This function may execute slowly, so when large mounts of random data are +required, it's advisable to use this function to seed a pseudo-random +number generator, rather than to provide the random data directly. + +##### Params +- `buf`: `Pointer` +The buffer to fill with random data. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + +## wasi_ephemeral_sched +### Imports +### Functions + +--- + +#### `yield() -> errno` +Temporarily yield execution of the calling thread. +Note: This is similar to [`yield`](#yield) in POSIX. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +## wasi_ephemeral_sock +### Imports +#### Memory +### Functions + +--- + +#### `recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +Receive a message from a socket. +Note: This is similar to [`recv`](#recv) in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +##### Params +- `fd`: [`fd`](#fd) + +- `ri_data`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +- `ri_flags`: [`riflags`](#riflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `ro_datalen`: [`size`](#size) +Number of bytes stored in ri_data. + +- `ro_flags`: [`roflags`](#roflags) +Message flags. + + +--- + +#### `send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +Send a message on a socket. +Note: This is similar to [`send`](#send) in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +##### Params +- `fd`: [`fd`](#fd) + +- `si_data`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors to which to retrieve data + +- `si_flags`: [`siflags`](#siflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `so_datalen`: [`size`](#size) +Number of bytes transmitted. + + +--- + +#### `shutdown(fd: fd, how: sdflags) -> errno` +Shut down socket send and receive channels. +Note: This is similar to [`shutdown`](#shutdown) in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `how`: [`sdflags`](#sdflags) +Which channels on the socket to shut down. + +##### Results +- `error`: [`errno`](#errno) + diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md new file mode 100644 index 000000000..360cff906 --- /dev/null +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -0,0 +1,1791 @@ +# Types +## `size`: `u32` + +## `filesize`: `u64` +Non-negative file size or length of a region within a file. + +## `timestamp`: `u64` +Timestamp in nanoseconds. + +## `clockid`: Enum(`u32`) +Identifiers for clocks. + +### Variants +- `realtime` +The clock measuring real time. Time value zero corresponds with +1970-01-01T00:00:00Z. + +- `monotonic` +The store-wide monotonic clock, which is defined as a clock measuring +real time, whose value cannot be adjusted and which cannot have negative +clock jumps. The epoch of this clock is undefined. The absolute time +value of this clock therefore has no meaning. + +- `process_cputime_id` +The CPU-time clock associated with the current process. + +- `thread_cputime_id` +The CPU-time clock associated with the current thread. + +## `errno`: Enum(`u16`) +Error codes returned by functions. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX. + +### Variants +- `success` +No error occurred. System call completed successfully. + +- `2big` +Argument list too long. + +- `acces` +Permission denied. + +- `addrinuse` +Address in use. + +- `addrnotavail` +Address not available. + +- `afnosupport` +Address family not supported. + +- `again` +Resource unavailable, or operation would block. + +- `already` +Connection already in progress. + +- `badf` +Bad file descriptor. + +- `badmsg` +Bad message. + +- `busy` +Device or resource busy. + +- `canceled` +Operation canceled. + +- `child` +No child processes. + +- `connaborted` +Connection aborted. + +- `connrefused` +Connection refused. + +- `connreset` +Connection reset. + +- `deadlk` +Resource deadlock would occur. + +- `destaddrreq` +Destination address required. + +- `dom` +Mathematics argument out of domain of function. + +- `dquot` +Reserved. + +- `exist` +File exists. + +- `fault` +Bad address. + +- `fbig` +File too large. + +- `hostunreach` +Host is unreachable. + +- `idrm` +Identifier removed. + +- `ilseq` +Illegal byte sequence. + +- `inprogress` +Operation in progress. + +- `intr` +Interrupted function. + +- `inval` +Invalid argument. + +- `io` +I/O error. + +- `isconn` +Socket is connected. + +- `isdir` +Is a directory. + +- `loop` +Too many levels of symbolic links. + +- `mfile` +File descriptor value too large. + +- `mlink` +Too many links. + +- `msgsize` +Message too large. + +- `multihop` +Reserved. + +- `nametoolong` +Filename too long. + +- `netdown` +Network is down. + +- `netreset` +Connection aborted by network. + +- `netunreach` +Network unreachable. + +- `nfile` +Too many files open in system. + +- `nobufs` +No buffer space available. + +- `nodev` +No such device. + +- `noent` +No such file or directory. + +- `noexec` +Executable file format error. + +- `nolck` +No locks available. + +- `nolink` +Reserved. + +- `nomem` +Not enough space. + +- `nomsg` +No message of the desired type. + +- `noprotoopt` +Protocol not available. + +- `nospc` +No space left on device. + +- `nosys` +Function not supported. + +- `notconn` +The socket is not connected. + +- `notdir` +Not a directory or a symbolic link to a directory. + +- `notempty` +Directory not empty. + +- `notrecoverable` +State not recoverable. + +- `notsock` +Not a socket. + +- `notsup` +Not supported, or operation not supported on socket. + +- `notty` +Inappropriate I/O control operation. + +- `nxio` +No such device or address. + +- `overflow` +Value too large to be stored in data type. + +- `ownerdead` +Previous owner died. + +- `perm` +Operation not permitted. + +- `pipe` +Broken pipe. + +- `proto` +Protocol error. + +- `protonosupport` +Protocol not supported. + +- `prototype` +Protocol wrong type for socket. + +- `range` +Result too large. + +- `rofs` +Read-only file system. + +- `spipe` +Invalid seek. + +- `srch` +No such process. + +- `stale` +Reserved. + +- `timedout` +Connection timed out. + +- `txtbsy` +Text file busy. + +- `xdev` +Cross-device link. + +- `notcapable` +Extension: Capabilities insufficient. + +## `rights`: Flags(`u64`) +File descriptor rights, determining which actions may be performed. + +### Flags +- `fd_datasync` +The right to invoke [`fd_datasync`](#fd_datasync). +If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke +[`path_open`](#path_open) with `FDFLAG_DSYNC`. + +- `fd_read` +The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). + +- `fd_seek` +The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). + +- `fd_fdstat_set_flags` +The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). + +- `fd_sync` +The right to invoke [`fd_sync`](#fd_sync). +If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke +[`path_open`](#path_open) with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + +- `fd_tell` +The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset +remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +invoke [`fd_tell`](#fd_tell). + +- `fd_write` +The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). + +- `fd_advise` +The right to invoke [`fd_advise`](#fd_advise). + +- `fd_allocate` +The right to invoke [`fd_allocate`](#fd_allocate). + +- `path_create_directory` +The right to invoke [`path_create_directory`](#path_create_directory). + +- `path_create_file` +If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with `O_CREAT`. + +- `path_link_source` +The right to invoke [`path_link`](#path_link) with the file descriptor as the +source directory. + +- `path_link_target` +The right to invoke [`path_link`](#path_link) with the file descriptor as the +target directory. + +- `path_open` +The right to invoke [`path_open`](#path_open). + +- `fd_readdir` +The right to invoke [`fd_readdir`](#fd_readdir). + +- `path_readlink` +The right to invoke [`path_readlink`](#path_readlink). + +- `path_rename_source` +The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. + +- `path_rename_target` +The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. + +- `path_filestat_get` +The right to invoke [`path_filestat_get`](#path_filestat_get). + +- `path_filestat_set_size` +The right to change a file's size (there is no `path_filestat_set_size`). +If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with `O_TRUNC`. + +- `path_filestat_set_times` +The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). + +- `fd_filestat_get` +The right to invoke [`fd_filestat_get`](#fd_filestat_get). + +- `fd_filestat_set_size` +The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). + +- `fd_filestat_set_times` +The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). + +- `path_symlink` +The right to invoke [`path_symlink`](#path_symlink). + +- `path_remove_directory` +The right to invoke [`path_remove_directory`](#path_remove_directory). + +- `path_unlink_file` +The right to invoke [`path_unlink_file`](#path_unlink_file). + +- `poll_fd_readwrite` +If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). +If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). + +- `sock_shutdown` +The right to invoke [`sock_shutdown`](#sock_shutdown). + +## `fd`: `u32` +A file descriptor index. + +## `iovec`: Struct +A region of memory for scatter/gather reads. + +### Struct members +- `buf`: `Pointer` +The address of the buffer to be filled. + +- `buf_len`: [`size`](#size) +The length of the buffer to be filled. + +## `ciovec`: Struct +A region of memory for scatter/gather writes. + +### Struct members +- `buf`: `ConstPointer` +The address of the buffer to be written. + +- `buf_len`: [`size`](#size) +The length of the buffer to be written. + +## `iovec_array`: `Array` + +## `ciovec_array`: `Array` + +## `filedelta`: `s64` +Relative offset within a file. + +## `whence`: Enum(`u8`) +The position relative to which to set the offset of the file descriptor. + +### Variants +- `cur` +Seek relative to current position. + +- `end` +Seek relative to end-of-file. + +- `set` +Seek relative to start-of-file. + +## `dircookie`: `u64` +A reference to the offset of a directory entry. + +## `dirnamlen`: `u32` +The type for the $d_namlen field of $dirent. + +## `inode`: `u64` +File serial number that is unique within its file system. + +## `filetype`: Enum(`u8`) +The type of a file descriptor or file. + +### Variants +- `unknown` +The type of the file descriptor or file is unknown or is different from any of the other types specified. + +- `block_device` +The file descriptor or file refers to a block device inode. + +- `character_device` +The file descriptor or file refers to a character device inode. + +- `directory` +The file descriptor or file refers to a directory inode. + +- `regular_file` +The file descriptor or file refers to a regular file inode. + +- `socket_dgram` +The file descriptor or file refers to a datagram socket. + +- `socket_stream` +The file descriptor or file refers to a byte-stream socket. + +- `symbolic_link` +The file refers to a symbolic link inode. + +## `dirent`: Struct +A directory entry. + +### Struct members +- `d_next`: [`dircookie`](#dircookie) +The offset of the next directory entry stored in this directory. + +- `d_ino`: [`inode`](#inode) +The serial number of the file referred to by this directory entry. + +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. + +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. + +## `advice`: Enum(`u8`) +File or memory access pattern advisory information. + +### Variants +- `normal` +The application has no advice to give on its behavior with respect to the specified data. + +- `sequential` +The application expects to access the specified data sequentially from lower offsets to higher offsets. + +- `random` +The application expects to access the specified data in a random order. + +- `willneed` +The application expects to access the specified data in the near future. + +- `dontneed` +The application expects that it will not access the specified data in the near future. + +- `noreuse` +The application expects to access the specified data once and then not reuse it thereafter. + +## `fdflags`: Flags(`u16`) +File descriptor flags. + +### Flags +- `append` +Append mode: Data written to the file is always appended to the file's end. + +- `dsync` +Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + +- `nonblock` +Non-blocking mode. + +- `rsync` +Synchronized read I/O operations. + +- `sync` +Write according to synchronized I/O file integrity completion. In +addition to synchronizing the data stored in the file, the implementation +may also synchronously update the file's metadata. + +## `fdstat`: Struct +File descriptor attributes. + +### Struct members +- `fs_filetype`: [`filetype`](#filetype) +File type. + +- `fs_flags`: [`fdflags`](#fdflags) +File descriptor flags. + +- `fs_rights_base`: [`rights`](#rights) +Rights that apply to this file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) +Maximum set of rights that may be installed on new file descriptors that +are created through this file descriptor, e.g., through [`path_open`](#path_open). + +## `device`: `u64` +Identifier for a device containing a file system. Can be used in combination +with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. + +## `fstflags`: Flags(`u16`) +Which file time attributes to adjust. + +### Flags +- `atim` +Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + +- `atim_now` +Adjust the last data access timestamp to the time of clock `clock::realtime`. + +- `mtim` +Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + +- `mtim_now` +Adjust the last data modification timestamp to the time of clock `clock::realtime`. + +## `lookupflags`: Flags(`u32`) +Flags determining the method of how paths are resolved. + +### Flags +- `symlink_follow` +As long as the resolved path corresponds to a symbolic link, it is expanded. + +## `oflags`: Flags(`u16`) +Open flags used by [`path_open`](#path_open). + +### Flags +- `creat` +Create file if it does not exist. + +- `directory` +Fail if not a directory. + +- `excl` +Fail if file already exists. + +- `trunc` +Truncate file to size 0. + +## `linkcount`: `u32` +Number of hard links to an inode. + +## `filestat`: Struct +File attributes. + +### Struct members +- `dev`: [`device`](#device) +Device ID of device containing the file. + +- `ino`: [`inode`](#inode) +File serial number. + +- `filetype`: [`filetype`](#filetype) +File type. + +- `nlink`: [`linkcount`](#linkcount) +Number of hard links to the file. + +- `size`: [`filesize`](#filesize) +For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + +- `atim`: [`timestamp`](#timestamp) +Last data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +Last data modification timestamp. + +- `ctim`: [`timestamp`](#timestamp) +Last file status change timestamp. + +## `userdata`: `u64` +User-provided value that may be attached to objects that is retained when +extracted from the implementation. + +## `eventtype`: Enum(`u8`) +Type of a subscription to an event or its occurrence. + +### Variants +- `clock` +The time value of clock `subscription::u.clock.clock_id` has +reached timestamp `subscription::u.clock.timeout`. + +- `fd_read` +File descriptor `subscription::u.fd_readwrite.fd` has data +available for reading. This event always triggers for regular files. + +- `fd_write` +File descriptor `subscription::u.fd_readwrite.fd` has capacity +available for writing. This event always triggers for regular files. + +## `eventrwflags`: Flags(`u16`) +The state of the file descriptor subscribed to with +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Flags +- `fd_readwrite_hangup` +The peer of this socket has closed or disconnected. + +## `event_fd_readwrite`: Struct +The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `nbytes`: [`filesize`](#filesize) +The number of bytes available for reading or writing. + +- `flags`: [`eventrwflags`](#eventrwflags) +The state of the file descriptor. + +## `event_u`: Union +The contents of an $event. + +### Union variants +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `event`: Struct +An event that occurred. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). + +- `error`: [`errno`](#errno) +If non-zero, an error that occurred while processing the subscription request. + +- `type`: [`eventtype`](#eventtype) +The type of the event that occurred. + +- `u`: [`event_u`](#event_u) +The contents of the event. + +## `subclockflags`: Flags(`u16`) +Flags determining how to interpret the timestamp provided in +`subscription::u.clock.timeout.` + +### Flags +- `subscription_clock_abstime` +If set, treat the timestamp provided in +`subscription::u.clock.timeout` as an absolute timestamp of clock +`subscription::u.clock.clock_id.` If clear, treat the timestamp +provided in `subscription::u.clock.timeout` relative to the +current time value of clock `subscription::u.clock.clock_id.` + +## `subscription_clock`: Struct +The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). + +### Struct members +- `identifier`: [`userdata`](#userdata) +The user-defined unique identifier of the clock. + +- `id`: [`clockid`](#clockid) +The clock against which to compare the timestamp. + +- `timeout`: [`timestamp`](#timestamp) +The absolute or relative timestamp. + +- `precision`: [`timestamp`](#timestamp) +The amount of time that the implementation may wait additionally +to coalesce with other events. + +- `flags`: [`subclockflags`](#subclockflags) +Flags specifying whether the timeout is absolute or relative + +## `subscription_fd_readwrite`: Struct +The contents of a $subscription when type is type is +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `file_descriptor`: [`fd`](#fd) +The file descriptor on which to wait for it to become ready for reading or writing. + +## `subscription_u`: Union +The contents of a $subscription. + +### Union variants +- `clock`: [`subscription_clock`](#subscription_clock) +When type is [`eventtype::clock`](#eventtype.clock): + +- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `subscription`: Struct +Subscription to an event. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that is attached to the subscription in the +implementation and returned through [`event::userdata`](#event.userdata). + +- `type`: [`eventtype`](#eventtype) +The type of the event to which to subscribe. + +- `u`: [`subscription_u`](#subscription_u) +The contents of the subscription. + +## `exitcode`: `u32` +Exit code generated by a process when exiting. + +## `signal`: Enum(`u8`) +Signal condition. + +### Variants +- `none` +No signal. Note that POSIX has special semantics for `kill(pid, 0)`, +so this value is reserved. + +- `hup` +Hangup. +Action: Terminates the process. + +- `int` +Terminate interrupt signal. +Action: Terminates the process. + +- `quit` +Terminal quit signal. +Action: Terminates the process. + +- `ill` +Illegal instruction. +Action: Terminates the process. + +- `trap` +Trace/breakpoint trap. +Action: Terminates the process. + +- `abrt` +Process abort signal. +Action: Terminates the process. + +- `bus` +Access to an undefined portion of a memory object. +Action: Terminates the process. + +- `fpe` +Erroneous arithmetic operation. +Action: Terminates the process. + +- `kill` +Kill. +Action: Terminates the process. + +- `usr1` +User-defined signal 1. +Action: Terminates the process. + +- `segv` +Invalid memory reference. +Action: Terminates the process. + +- `usr2` +User-defined signal 2. +Action: Terminates the process. + +- `pipe` +Write on a pipe with no one to read it. +Action: Ignored. + +- `alrm` +Alarm clock. +Action: Terminates the process. + +- `term` +Termination signal. +Action: Terminates the process. + +- `chld` +Child process terminated, stopped, or continued. +Action: Ignored. + +- `cont` +Continue executing, if stopped. +Action: Continues executing, if stopped. + +- `stop` +Stop executing. +Action: Stops executing. + +- `tstp` +Terminal stop signal. +Action: Stops executing. + +- `ttin` +Background process attempting read. +Action: Stops executing. + +- `ttou` +Background process attempting write. +Action: Stops executing. + +- `urg` +High bandwidth data is available at a socket. +Action: Ignored. + +- `xcpu` +CPU time limit exceeded. +Action: Terminates the process. + +- `xfsz` +File size limit exceeded. +Action: Terminates the process. + +- `vtalrm` +Virtual timer expired. +Action: Terminates the process. + +- `prof` +Profiling timer expired. +Action: Terminates the process. + +- `winch` +Window changed. +Action: Ignored. + +- `poll` +I/O possible. +Action: Terminates the process. + +- `pwr` +Power failure. +Action: Terminates the process. + +- `sys` +Bad system call. +Action: Terminates the process. + +## `riflags`: Flags(`u16`) +Flags provided to [`sock_recv`](#sock_recv). + +### Flags +- `recv_peek` +Returns the message without removing it from the socket's receive queue. + +- `recv_waitall` +On byte-stream sockets, block until the full amount of data can be returned. + +## `roflags`: Flags(`u16`) +Flags returned by [`sock_recv`](#sock_recv). + +### Flags +- `recv_data_truncated` +Returned by [`sock_recv`](#sock_recv): Message data has been truncated. + +## `siflags`: `u16` +Flags provided to [`sock_send`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +## `sdflags`: Flags(`u8`) +Which channels on a socket to shut down. + +### Flags +- `rd` +Disables further receive operations. + +- `wr` +Disables further send operations. + +## `preopentype`: Enum(`u8`) +Identifiers for preopened capabilities. + +### Variants +- `dir` +A pre-opened directory. + +## `prestat_dir`: Struct +The contents of a $prestat when type is `PREOPENTYPE_DIR`. + +### Struct members +- `pr_name_len`: [`size`](#size) +The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). + +## `prestat_u`: Union +The contents of an $prestat. + +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) +When type is `PREOPENTYPE_DIR`: + +## `prestat`: Struct +Information about a pre-opened capability. + +### Struct members +- `pr_type`: [`preopentype`](#preopentype) +The type of the pre-opened capability. + +- `u`: [`prestat_u`](#prestat_u) +The contents of the information. + +# Modules +## wasi_unstable +### Imports +#### Memory +### Functions + +--- + +#### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` +Read command-line argument data. +The size of the array should match that returned by `wasi_args_sizes_get()` + +##### Params +- `argv`: `Pointer>` + +- `argv_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `args_sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + + +--- + +#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` +Read environment variable data. +The sizes of the buffers should match that returned by `environ.sizes_get()`. + +##### Params +- `environ`: `Pointer>` + +- `environ_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `environ_sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + + +--- + +#### `clock_res_get(id: clockid) -> (errno, timestamp)` +Return the resolution of a clock. +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Note: This is similar to `clock_getres` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the resolution. + +##### Results +- `error`: [`errno`](#errno) + +- `resolution`: [`timestamp`](#timestamp) +The resolution of the clock. + + +--- + +#### `clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +Return the time value of a clock. +Note: This is similar to `clock_gettime` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the time. + +- `precision`: [`timestamp`](#timestamp) +The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + +##### Results +- `error`: [`errno`](#errno) + +- `time`: [`timestamp`](#timestamp) +The time value of the clock. + + +--- + +#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +Provide file advisory information on a file descriptor. +Note: This is similar to `posix_fadvise` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset within the file to which the advisory applies. + +- `len`: [`filesize`](#filesize) +The length of the region to which the advisory applies. + +- `advice`: [`advice`](#advice) +The advice. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno` +Force the allocation of space in a file. +Note: This is similar to `posix_fallocate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset at which to start the allocation. + +- `len`: [`filesize`](#filesize) +The length of the area that is allocated. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_close(fd: fd) -> errno` +Close a file descriptor. +Note: This is similar to `close` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_datasync(fd: fd) -> errno` +Synchronize the data of a file to disk. +Note: This is similar to `fdatasync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_fdstat_get(fd: fd) -> (errno, fdstat)` +Get the attributes of a file descriptor. +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `stat`: [`fdstat`](#fdstat) +The buffer where the file descriptor's attributes are stored. + + +--- + +#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +Adjust the flags associated with a file descriptor. +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`fdflags`](#fdflags) +The desired values of the file descriptor flags. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +Adjust the rights associated with a file descriptor. +This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + +##### Params +- `fd`: [`fd`](#fd) + +- `fs_rights_base`: [`rights`](#rights) +The desired rights of the file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_filestat_get(fd: fd) -> (errno, filestat)` +Return the attributes of an open file. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `fd_filestat_set_size(fd: fd, size: filesize) -> errno` +Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. +Note: This is similar to `ftruncate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `size`: [`filesize`](#filesize) +The desired file size. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of an open file or directory. +Note: This is similar to `futimens` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +Read from a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `preadv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors in which to store data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to read. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `fd_prestat_get(fd: fd) -> (errno, prestat)` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`prestat`](#prestat) +The buffer where the description is stored. + + +--- + +#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `Pointer` +A buffer into which to write the preopened directory name. + +- `path_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +Write to a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `pwritev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to write. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `fd_read(fd: fd, iovs: iovec_array) -> (errno, size)` +Read from a file descriptor. +Note: This is similar to `readv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +Read directory entries from a directory. +When successful, the contents of the output buffer consist of a sequence of +directory entries. Each directory entry consists of a dirent_t object, +followed by dirent_t::d_namlen bytes holding the name of the directory +entry. +This function fills the output buffer as much as possible, potentially +truncating the last directory entry. This allows the caller to grow its +read buffer size in case it's too small to fit a single large directory +entry, or skip the oversized directory entry. + +##### Params +- `fd`: [`fd`](#fd) + +- `buf`: `Pointer` +The buffer where directory entries are stored + +- `buf_len`: [`size`](#size) + +- `cookie`: [`dircookie`](#dircookie) +The location within the directory to start reading + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + + +--- + +#### `fd_renumber(fd: fd, to: fd) -> errno` +Atomically replace a file descriptor by renumbering another file descriptor. +Due to the strong focus on thread safety, this environment does not provide +a mechanism to duplicate or renumber a file descriptor to an arbitrary +number, like `dup2()`. This would be prone to race conditions, as an actual +file descriptor with the same number could be allocated by a different +thread at the same time. +This function provides a way to atomically renumber file descriptors, which +would disappear if `dup2()` were to be removed entirely. + +##### Params +- `fd`: [`fd`](#fd) + +- `to`: [`fd`](#fd) +The file descriptor to overwrite. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +Move the offset of a file descriptor. +Note: This is similar to `lseek` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filedelta`](#filedelta) +The number of bytes to move. + +- `whence`: [`whence`](#whence) +The base from which the offset is relative. + +##### Results +- `error`: [`errno`](#errno) + +- `newoffset`: [`filesize`](#filesize) +The new offset of the file descriptor, relative to the start of the file. + + +--- + +#### `fd_sync(fd: fd) -> errno` +Synchronize the data and metadata of a file to disk. +Note: This is similar to `fsync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_tell(fd: fd) -> (errno, filesize)` +Return the current offset of a file descriptor. +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `offset`: [`filesize`](#filesize) +The current offset of the file descriptor, relative to the start of the file. + + +--- + +#### `fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)` +Write to a file descriptor. +Note: This is similar to `writev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `path_create_directory(fd: fd, path: string) -> errno` +Create a directory. +Note: This is similar to `mkdirat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path at which to create the directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +Return the attributes of a file or directory. +Note: This is similar to `stat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to inspect. + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of a file or directory. +Note: This is similar to `utimensat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to operate on. + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +Create a hard link. +Note: This is similar to `linkat` in POSIX. + +##### Params +- `old_fd`: [`fd`](#fd) + +- `old_flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `old_path`: `string` +The source path from which to link. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path at which to create the hard link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)` +Open a file or directory. +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since this +is error-prone in multi-threaded contexts. The returned file descriptor is +guaranteed to be less than 2**31. +Note: This is similar to `openat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `dirflags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The relative path of the file or directory to open, relative to the +`dirfd` directory. + +- `oflags`: [`oflags`](#oflags) +The method by which to open the file. + +- `fs_rights_base`: [`rights`](#rights) +The initial rights of the newly created file descriptor. The +implementation is allowed to return a file descriptor with fewer rights +than specified, if and only if those rights do not apply to the type of +file being opened. +The *base* rights are rights that will apply to operations using the file +descriptor itself, while the *inheriting* rights are rights that apply to +file descriptors derived from it. + +- `fs_rights_inherting`: [`rights`](#rights) + +- `fdflags`: [`fdflags`](#fdflags) + +##### Results +- `error`: [`errno`](#errno) + +- `opened_fd`: [`fd`](#fd) +The file descriptor of the file that has been opened. + + +--- + +#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +Read the contents of a symbolic link. +Note: This is similar to `readlinkat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path of the symbolic link from which to read. + +- `buf`: `Pointer` +The buffer to which to write the contents of the symbolic link. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes placed in the buffer. + + +--- + +#### `path_remove_directory(fd: fd, path: string) -> errno` +Remove a directory. +Return `ENOTEMPTY` if the directory is not empty. +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a directory to remove. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +Rename a file or directory. +Note: This is similar to `renameat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `old_path`: `string` +The source path of the file or directory to rename. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path to which to rename the file or directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_symlink(old_path: string, fd: fd, new_path: string) -> errno` +Create a symbolic link. +Note: This is similar to `symlinkat` in POSIX. + +##### Params +- `old_path`: `string` +The contents of the symbolic link. + +- `fd`: [`fd`](#fd) + +- `new_path`: `string` +The destination path at which to create the symbolic link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_unlink_file(fd: fd, path: string) -> errno` +Unlink a file. +Return `EISDIR` if the path refers to a directory. +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a file to unlink. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +Concurrently poll for the occurrence of a set of events. + +##### Params +- `in`: `ConstPointer` +The events to which to subscribe. + +- `out`: `Pointer` +The events that have occurred. + +- `nsubscriptions`: [`size`](#size) +Both the number of subscriptions and events. + +##### Results +- `error`: [`errno`](#errno) + +- `nevents`: [`size`](#size) +The number of events stored. + + +--- + +#### `proc_exit(rval: exitcode)` +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +##### Params +- `rval`: [`exitcode`](#exitcode) +The exit code returned by the process. + +##### Results + +--- + +#### `proc_raise(sig: signal) -> errno` +Send a signal to the process of the calling thread. +Note: This is similar to `raise` in POSIX. + +##### Params +- `sig`: [`signal`](#signal) +The signal condition to trigger. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sched_yield() -> errno` +Temporarily yield execution of the calling thread. +Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. + +##### Params +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `random_get(buf: Pointer, buf_len: size) -> errno` +Write high-quality random data into a buffer. +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. +This function may execute slowly, so when large mounts of random data are +required, it's advisable to use this function to seed a pseudo-random +number generator, rather than to provide the random data directly. + +##### Params +- `buf`: `Pointer` +The buffer to fill with random data. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +Receive a message from a socket. +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +##### Params +- `fd`: [`fd`](#fd) + +- `ri_data`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +- `ri_flags`: [`riflags`](#riflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `ro_datalen`: [`size`](#size) +Number of bytes stored in ri_data. + +- `ro_flags`: [`roflags`](#roflags) +Message flags. + + +--- + +#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +Send a message on a socket. +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +##### Params +- `fd`: [`fd`](#fd) + +- `si_data`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors to which to retrieve data + +- `si_flags`: [`siflags`](#siflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `so_datalen`: [`size`](#size) +Number of bytes transmitted. + + +--- + +#### `sock_shutdown(fd: fd, how: sdflags) -> errno` +Shut down socket send and receive channels. +Note: This is similar to `shutdown` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `how`: [`sdflags`](#sdflags) +Which channels on the socket to shut down. + +##### Results +- `error`: [`errno`](#errno) + diff --git a/proposals/filesystem/phases/old/snapshot_0/docs/wasi_unstable.md b/proposals/filesystem/phases/old/snapshot_0/docs/wasi_unstable.md deleted file mode 100644 index 2464f2342..000000000 --- a/proposals/filesystem/phases/old/snapshot_0/docs/wasi_unstable.md +++ /dev/null @@ -1,2343 +0,0 @@ - - -# The WASI Preview API - -This is the API-level documentation for WASI Preview. The function names -are prefixed with "\_\_wasi\_" to reflect how they are spelled in -flat-namespace contexts, however at the wasm module level, they are -unprefixed, because they're inside a module namespace. - -Functions that start with `__wasi_fd_` operate on file descriptors, -while functions that start with `__wasi_path_` operate on filesystem -paths, which are relative to directory file descriptors. - -Much inspiration and content here is derived from [CloudABI] and [POSIX], -though there are also several differences from CloudABI and POSIX. For -example, WASI Preview has no concept of processes in the traditional Unix -sense. While wasm linear memories have some of the aspects of processes, -and it's possible to *emulate* the full semantics of processes on top of -them, this can sometimes be unnatural and inefficient. The goal for -WASI Preview is to be a WebAssembly-native API that exposes APIs that fit -well into the underlying WebAssembly platform, rather than to directly -emulate other platforms. - -This is also a work in progress, and the API here is still evolving. - -Historical note: this API was originally named "WASI Core", and used the -API module name "wasi\_unstable". We've since sought to deemphasize the -"Core" name, as the goal is to split this API up into independent -modules so that embedders need not implement all of it. - -[CloudABI]: https://github.com/NuxiNL/cloudabi -[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ - -## System calls - -- [`__wasi_args_get()`](#args_get) -- [`__wasi_args_sizes_get()`](#args_sizes_get) -- [`__wasi_clock_res_get()`](#clock_res_get) -- [`__wasi_clock_time_get()`](#clock_time_get) -- [`__wasi_environ_get()`](#environ_get) -- [`__wasi_environ_sizes_get()`](#environ_sizes_get) -- [`__wasi_fd_advise()`](#fd_advise) -- [`__wasi_fd_allocate()`](#fd_allocate) -- [`__wasi_fd_close()`](#fd_close) -- [`__wasi_fd_datasync()`](#fd_datasync) -- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) -- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) -- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) -- [`__wasi_fd_filestat_get()`](#fd_filestat_get) -- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) -- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) -- [`__wasi_fd_pread()`](#fd_pread) -- [`__wasi_fd_prestat_get()`](#fd_prestat_get) -- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) -- [`__wasi_fd_pwrite()`](#fd_pwrite) -- [`__wasi_fd_read()`](#fd_read) -- [`__wasi_fd_readdir()`](#fd_readdir) -- [`__wasi_fd_renumber()`](#fd_renumber) -- [`__wasi_fd_seek()`](#fd_seek) -- [`__wasi_fd_sync()`](#fd_sync) -- [`__wasi_fd_tell()`](#fd_tell) -- [`__wasi_fd_write()`](#fd_write) -- [`__wasi_path_create_directory()`](#path_create_directory) -- [`__wasi_path_filestat_get()`](#path_filestat_get) -- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) -- [`__wasi_path_link()`](#path_link) -- [`__wasi_path_open()`](#path_open) -- [`__wasi_path_readlink()`](#path_readlink) -- [`__wasi_path_remove_directory()`](#path_remove_directory) -- [`__wasi_path_rename()`](#path_rename) -- [`__wasi_path_symlink()`](#path_symlink) -- [`__wasi_path_unlink_file()`](#path_unlink_file) -- [`__wasi_poll_oneoff()`](#poll_oneoff) -- [`__wasi_proc_exit()`](#proc_exit) -- [`__wasi_proc_raise()`](#proc_raise) -- [`__wasi_random_get()`](#random_get) -- [`__wasi_sched_yield()`](#sched_yield) -- [`__wasi_sock_recv()`](#sock_recv) -- [`__wasi_sock_send()`](#sock_send) -- [`__wasi_sock_shutdown()`](#sock_shutdown) - -### `__wasi_args_get()` - -Read command-line argument data. - -The sizes of the buffers should match that returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - -Inputs: - -- char \*\*argv - - A pointer to a buffer to write the argument pointers. - -- char \*argv\_buf - - A pointer to a buffer to write the argument string data. - -### `__wasi_args_sizes_get()` - -Return command-line argument data sizes. - -Outputs: - -- size\_t \*argc - - The number of arguments. - -- size\_t \*argv\_buf\_size - - The size of the argument string data. - -### `__wasi_clock_res_get()` - -Return the resolution of a clock. - -Implementations are required to provide a non-zero value for supported clocks. -For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). - -Note: This is similar to `clock_getres` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the resolution. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) resolution - - The resolution of the clock. - -### `__wasi_clock_time_get()` - -Return the time value of a clock. - -Note: This is similar to `clock_gettime` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the time. - -- [\_\_wasi\_timestamp\_t](#timestamp) precision - - The maximum lag (exclusive) that the returned - time value may have, compared to its actual - value. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) time - - The time value of the clock. - -### `__wasi_environ_get()` - -Read environment variable data. - -The sizes of the buffers should match that returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - -Inputs: - -- char \*\*environ - - A pointer to a buffer to write the environment variable pointers. - -- char \*environ\_buf - - A pointer to a buffer to write the environment variable string data. - -### `__wasi_environ_sizes_get()` - -Return command-line argument data sizes. - -Outputs: - -- size\_t \*environ\_count - - The number of environment variables. - -- size\_t \*environ\_buf\_size - - The size of the environment variable string data. - -### `__wasi_fd_advise()` - -Provide file advisory information on a file descriptor. - -Note: This is similar to `posix_fadvise` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file for which to provide file advisory information. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file to which the advisory applies. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the region to which the advisory applies. - -- [\_\_wasi\_advice\_t](#advice) advice - - The advice. - -### `__wasi_fd_allocate()` - -Force the allocation of space in a file. - -Note: This is similar to `posix_fallocate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file in which to allocate space. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset at which to start the allocation. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the area that is allocated. - -### `__wasi_fd_close()` - -Close a file descriptor. - -Note: This is similar to `close` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to close. - -### `__wasi_fd_datasync()` - -Synchronize the data of a file to disk. - -Note: This is similar to `fdatasync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file to synchronize to disk. - -### `__wasi_fd_fdstat_get()` - -Get the attributes of a file descriptor. - -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well -as additional fields. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_fdstat\_t](#fdstat) \*buf - - The buffer where the file descriptor's attributes are stored. - -### `__wasi_fd_fdstat_set_flags()` - -Adjust the flags associated with a file descriptor. - -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_fdflags\_t](#fdflags) flags - - The desired values of the file descriptor - flags. - -### `__wasi_fd_fdstat_set_rights()` - -Adjust the rights associated with a file descriptor. - -This can only be used to remove rights, and returns -[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt -to add rights. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The desired rights of the file descriptor. - -### `__wasi_fd_filestat_get()` - -Return the attributes of an open file. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_fd_filestat_set_size()` - -Adjust the size of an open file. If this increases the file's size, the extra -bytes are filled with zeros. - -Note: This is similar to `ftruncate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - A file descriptor for the file to adjust. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - The desired file size. - -### `__wasi_fd_filestat_set_times()` - -Adjust the timestamps of an open file or directory. - -Note: This is similar to `futimens` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_fd_pread()` - -Read from a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `preadv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors in which to store data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to read. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_prestat_get()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- [\_\_wasi\_prestat\_t](#prestat) \*buf - - The buffer where the description is stored. - -### `__wasi_fd_prestat_dir_name()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- const char \*path and size\_t path\_len - - A buffer into which to write the preopened directory name. - -### `__wasi_fd_pwrite()` - -Write to a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `pwritev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to write. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_fd_read()` - -Read from a file descriptor. - -Note: This is similar to `readv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors to which to store data. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_readdir()` - -Read directory entries from a directory. - -When successful, the contents of the output buffer consist of -a sequence of directory entries. Each directory entry consists -of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes -holding the name of the directory entry. - -This function fills the output buffer as much as possible, -potentially truncating the last directory entry. This allows -the caller to grow its read buffer size in case it's too small -to fit a single large directory entry, or skip the oversized -directory entry. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The directory from which to read the directory - entries. - -- void \*buf and size\_t buf\_len - - The buffer where directory entries are stored. - -- [\_\_wasi\_dircookie\_t](#dircookie) cookie - - The location within the directory to start - reading. - -Outputs: - -- size\_t bufused - - The number of bytes stored in the read buffer. - If less than the size of the read buffer, the - end of the directory has been reached. - -### `__wasi_fd_renumber()` - -Atomically replace a file descriptor by renumbering another -file descriptor. - -Due to the strong focus on thread safety, this environment -does not provide a mechanism to duplicate or renumber a file -descriptor to an arbitrary number, like dup2(). This would be -prone to race conditions, as an actual file descriptor with the -same number could be allocated by a different thread at the same -time. - -This function provides a way to atomically renumber file -descriptors, which would disappear if dup2() were to be -removed entirely. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) from - - The file descriptor to renumber. - -- [\_\_wasi\_fd\_t](#fd) to - - The file descriptor to overwrite. - -### `__wasi_fd_seek()` - -Move the offset of a file descriptor. - -Note: This is similar to `lseek` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_filedelta\_t](#filedelta) offset - - The number of bytes to move. - -- [\_\_wasi\_whence\_t](#whence) whence - - The base from which the offset is relative. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) newoffset - - The new offset of the file descriptor, - relative to the start of the file. - -### `__wasi_fd_sync()` - -Synchronize the data and metadata of a file to disk. - -Note: This is similar to `fsync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file containing the data - and metadata to synchronize to disk. - -### `__wasi_fd_tell()` - -Return the current offset of a file descriptor. - -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The current offset of the file descriptor, relative to the start of the file. - -### `__wasi_fd_write()` - -Write to a file descriptor. - -Note: This is similar to `writev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_path_create_directory()` - -Create a directory. - -Note: This is similar to `mkdirat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path at which to create the directory. - -### `__wasi_path_filestat_get()` - -Return the attributes of a file or directory. - -Note: This is similar to `stat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_path_filestat_set_times()` - -Adjust the timestamps of a file or directory. - -Note: This is similar to `utimensat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_path_link()` - -Create a hard link. - -Note: This is similar to `linkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags - - Flags determining the method of how the path is resolved. - -- const char \*old\_path and size\_t old\_path\_len - - The source path from which to link. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the hard link. - -### `__wasi_path_open()` - -Open a file or directory. - -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since -this is error-prone in multi-threaded contexts. The returned file -descriptor is guaranteed to be less than 231. - -Note: This is similar to `openat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) dirfd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The relative path of the file or directory to open, relative to - the [`dirfd`](#path_open.dirfd) directory. - -- [\_\_wasi\_oflags\_t](#oflags) o_flags - - The method by which to open the file. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The initial rights of the newly created file descriptor. The - implementation is allowed to return a file descriptor with fewer - rights than specified, if and only if those rights do not apply - to the type of file being opened. - - The *base* rights are rights that will apply to operations using - the file descriptor itself, while the *inheriting* rights are - rights that apply to file descriptors derived from it. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - The initial flags of the file descriptor. - -Outputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file that has been - opened. - -### `__wasi_path_readlink()` - -Read the contents of a symbolic link. - -Note: This is similar to `readlinkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path of the symbolic link from which to read. - -- char \*buf and size\_t buf\_len - - The buffer to which to write the contents of the symbolic link. - -Outputs: - -- size\_t bufused - - The number of bytes placed in the buffer. - -### `__wasi_path_remove_directory()` - -Remove a directory. - -Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. - -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a directory to remove. - -### `__wasi_path_rename()` - -Rename a file or directory. - -Note: This is similar to `renameat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- const char \*old\_path and size\_t old\_path\_len - - The source path of the file or directory to rename. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path to which to rename the file or directory. - -### `__wasi_path_symlink()` - -Create a symbolic link. - -Note: This is similar to `symlinkat` in POSIX. - -Inputs: - -- const char \*old\_path and size\_t old_path\_len - - The contents of the symbolic link. - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the symbolic link. - -### `__wasi_path_unlink_file()` - -Unlink a file. - -Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. - -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a file to unlink. - -### `__wasi_poll_oneoff()` - -Concurrently poll for the occurrence of a set of events. - -Inputs: - -- const [\_\_wasi\_subscription\_t](#subscription) \*in - - The events to which to subscribe. - -- [\_\_wasi\_event\_t](#event) \*out - - The events that have occurred. - -- size\_t nsubscriptions - - Both the number of subscriptions and events. - -Outputs: - -- size\_t nevents - - The number of events stored. - -### `__wasi_proc_exit()` - -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -Note: This is similar to `_Exit` in POSIX. - -Inputs: - -- [\_\_wasi\_exitcode\_t](#exitcode) rval - - The exit code returned by the process. - -Does not return. - -### `__wasi_proc_raise()` - -Send a signal to the process of the calling thread. - -Note: This is similar to `raise` in POSIX. - -Inputs: - -- [\_\_wasi\_signal\_t](#signal) sig - - The signal condition to trigger. - -### `__wasi_random_get()` - -Write high-quality random data into a buffer. - -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. - -This function may execute slowly, so when large mounts of random -data are required, it's advisable to use this function to seed a -pseudo-random number generator, rather than to provide the -random data directly. - -Inputs: - -- void \*buf and size\_t buf\_len - - The buffer to fill with random data. - -### `__wasi_sched_yield()` - -Temporarily yield execution of the calling thread. - -Note: This is similar to `sched_yield` in POSIX. - -### `__wasi_sock_recv()` - -Receive a message from a socket. - -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to receive data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len - - List of scatter/gather vectors to which to store data. - -- [\_\_wasi\_riflags\_t](#riflags) ri\_flags - - Message flags. - -Outputs: - -- size\_t ro\_datalen - - Number of bytes stored in [`ri_data`](#sock_recv.ri_data). - -- [\_\_wasi\_roflags\_t](#roflags) ro\_flags - - Message flags. - -### `__wasi_sock_send()` - -Send a message on a socket. - -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to send data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len - - List of scatter/gather vectors to which to retrieve data - -- [\_\_wasi\_siflags\_t](#siflags) si\_flags - - Message flags. - -Outputs: - -- size\_t so\_datalen - - Number of bytes transmitted. - -### `__wasi_sock_shutdown()` - -Shut down socket send and receive channels. - -Note: This is similar to `shutdown` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to shutdown channels. - -- [\_\_wasi\_sdflags\_t](#sdflags) how - - Which channels on the socket to shut down. - -## Types - -### `__wasi_advice_t` (`uint8_t`) - -File or memory access pattern advisory information. - -Used by [`__wasi_fd_advise()`](#fd_advise). - -Possible values: - -- **`__WASI_ADVICE_NORMAL`** - - The application has no advice to give on its behavior - with respect to the specified data. - -- **`__WASI_ADVICE_SEQUENTIAL`** - - The application expects to access the specified data - sequentially from lower offsets to higher offsets. - -- **`__WASI_ADVICE_RANDOM`** - - The application expects to access the specified data - in a random order. - -- **`__WASI_ADVICE_WILLNEED`** - - The application expects to access the specified data - in the near future. - -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - -### `__wasi_ciovec_t` (`struct`) - -A region of memory for scatter/gather writes. - -Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). - -Members: - -- const void \*buf and size\_t buf\_len - - The address and length of the buffer to be written. - -### `__wasi_clockid_t` (`uint32_t`) - -Identifiers for clocks. - -Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). - -Possible values: - -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - -- **`__WASI_CLOCK_MONOTONIC`** - - The store-wide monotonic clock, which is defined as a - clock measuring real time, whose value cannot be - adjusted and which cannot have negative clock jumps. - - The epoch of this clock is undefined. The absolute - time value of this clock therefore has no meaning. - -- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** - - The CPU-time clock associated with the current - process. - -- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** - - The CPU-time clock associated with the current thread. - -### `__wasi_device_t` (`uint64_t`) - -Identifier for a device containing a file system. Can be used -in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or -directory in the filesystem. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_dircookie_t` (`uint64_t`) - -A reference to the offset of a directory entry. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). - -Special values: - -- **`__WASI_DIRCOOKIE_START`** - - Permanent reference to the first directory entry - within a directory. - -### `__wasi_dirent_t` (`struct`) - -A directory entry. - -Members: - -- [\_\_wasi\_dircookie\_t](#dircookie) d\_next - - The offset of the next directory entry stored in this - directory. - -- [\_\_wasi\_inode\_t](#inode) d\_ino - - The serial number of the file referred to by this - directory entry. - -- uint32\_t d\_namlen - - The length of the name of the directory entry. - -- [\_\_wasi\_filetype\_t](#filetype) d\_type - - The type of the file referred to by this directory - entry. - -### `__wasi_errno_t` (`uint16_t`) - -Error codes returned by functions. - -Not all of these error codes are returned by the functions -provided by this API; some are used in higher-level library layers, -and others are provided merely for alignment with POSIX. - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_ESUCCESS`** - - No error occurred. System call completed successfully. - -- **`__WASI_E2BIG`** - - Argument list too long. - -- **`__WASI_EACCES`** - - Permission denied. - -- **`__WASI_EADDRINUSE`** - - Address in use. - -- **`__WASI_EADDRNOTAVAIL`** - - Address not available. - -- **`__WASI_EAFNOSUPPORT`** - - Address family not supported. - -- **`__WASI_EAGAIN`** - - Resource unavailable, or operation would block. - -- **`__WASI_EALREADY`** - - Connection already in progress. - -- **`__WASI_EBADF`** - - Bad file descriptor. - -- **`__WASI_EBADMSG`** - - Bad message. - -- **`__WASI_EBUSY`** - - Device or resource busy. - -- **`__WASI_ECANCELED`** - - Operation canceled. - -- **`__WASI_ECHILD`** - - No child processes. - -- **`__WASI_ECONNABORTED`** - - Connection aborted. - -- **`__WASI_ECONNREFUSED`** - - Connection refused. - -- **`__WASI_ECONNRESET`** - - Connection reset. - -- **`__WASI_EDEADLK`** - - Resource deadlock would occur. - -- **`__WASI_EDESTADDRREQ`** - - Destination address required. - -- **`__WASI_EDOM`** - - Mathematics argument out of domain of function. - -- **`__WASI_EDQUOT`** - - Reserved. - -- **`__WASI_EEXIST`** - - File exists. - -- **`__WASI_EFAULT`** - - Bad address. - -- **`__WASI_EFBIG`** - - File too large. - -- **`__WASI_EHOSTUNREACH`** - - Host is unreachable. - -- **`__WASI_EIDRM`** - - Identifier removed. - -- **`__WASI_EILSEQ`** - - Illegal byte sequence. - -- **`__WASI_EINPROGRESS`** - - Operation in progress. - -- **`__WASI_EINTR`** - - Interrupted function. - -- **`__WASI_EINVAL`** - - Invalid argument. - -- **`__WASI_EIO`** - - I/O error. - -- **`__WASI_EISCONN`** - - Socket is connected. - -- **`__WASI_EISDIR`** - - Is a directory. - -- **`__WASI_ELOOP`** - - Too many levels of symbolic links. - -- **`__WASI_EMFILE`** - - File descriptor value too large. - -- **`__WASI_EMLINK`** - - Too many links. - -- **`__WASI_EMSGSIZE`** - - Message too large. - -- **`__WASI_EMULTIHOP`** - - Reserved. - -- **`__WASI_ENAMETOOLONG`** - - Filename too long. - -- **`__WASI_ENETDOWN`** - - Network is down. - -- **`__WASI_ENETRESET`** - - Connection aborted by network. - -- **`__WASI_ENETUNREACH`** - - Network unreachable. - -- **`__WASI_ENFILE`** - - Too many files open in system. - -- **`__WASI_ENOBUFS`** - - No buffer space available. - -- **`__WASI_ENODEV`** - - No such device. - -- **`__WASI_ENOENT`** - - No such file or directory. - -- **`__WASI_ENOEXEC`** - - Executable file format error. - -- **`__WASI_ENOLCK`** - - No locks available. - -- **`__WASI_ENOLINK`** - - Reserved. - -- **`__WASI_ENOMEM`** - - Not enough space. - -- **`__WASI_ENOMSG`** - - No message of the desired type. - -- **`__WASI_ENOPROTOOPT`** - - Protocol not available. - -- **`__WASI_ENOSPC`** - - No space left on device. - -- **`__WASI_ENOSYS`** - - Function not supported. - -- **`__WASI_ENOTCONN`** - - The socket is not connected. - -- **`__WASI_ENOTDIR`** - - Not a directory or a symbolic link to a directory. - -- **`__WASI_ENOTEMPTY`** - - Directory not empty. - -- **`__WASI_ENOTRECOVERABLE`** - - State not recoverable. - -- **`__WASI_ENOTSOCK`** - - Not a socket. - -- **`__WASI_ENOTSUP`** - - Not supported, or operation not supported on socket. - -- **`__WASI_ENOTTY`** - - Inappropriate I/O control operation. - -- **`__WASI_ENXIO`** - - No such device or address. - -- **`__WASI_EOVERFLOW`** - - Value too large to be stored in data type. - -- **`__WASI_EOWNERDEAD`** - - Previous owner died. - -- **`__WASI_EPERM`** - - Operation not permitted. - -- **`__WASI_EPIPE`** - - Broken pipe. - -- **`__WASI_EPROTO`** - - Protocol error. - -- **`__WASI_EPROTONOSUPPORT`** - - Protocol not supported. - -- **`__WASI_EPROTOTYPE`** - - Protocol wrong type for socket. - -- **`__WASI_ERANGE`** - - Result too large. - -- **`__WASI_EROFS`** - - Read-only file system. - -- **`__WASI_ESPIPE`** - - Invalid seek. - -- **`__WASI_ESRCH`** - - No such process. - -- **`__WASI_ESTALE`** - - Reserved. - -- **`__WASI_ETIMEDOUT`** - - Connection timed out. - -- **`__WASI_ETXTBSY`** - - Text file busy. - -- **`__WASI_EXDEV`** - - Cross-device link. - -- **`__WASI_ENOTCAPABLE`** - - Extension: Capabilities insufficient. - -### `__wasi_event_t` (`struct`) - -An event that occurred. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that got attached to - [`__wasi_subscription_t::userdata`](#subscription.userdata). - -- [\_\_wasi\_errno\_t](#errno) error - - If non-zero, an error that occurred while processing - the subscription request. - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event that occurred. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_filesize\_t](#filesize) nbytes - - The number of bytes available for reading or writing. - - - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags - - The state of the file descriptor. - -### `__wasi_eventrwflags_t` (`uint16_t` bitfield) - -The state of the file descriptor subscribed to with -[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_EVENT_FD_READWRITE_HANGUP`** - - The peer of this socket has closed or disconnected. - -### `__wasi_eventtype_t` (`uint8_t`) - -Type of a subscription to an event or its occurrence. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_EVENTTYPE_CLOCK`** - - The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) - has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -- **`__WASI_EVENTTYPE_FD_READ`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - data available for reading. This event always triggers - for regular files. - -- **`__WASI_EVENTTYPE_FD_WRITE`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - capacity available for writing. This event always - triggers for regular files. - -### `__wasi_exitcode_t` (`uint32_t`) - -Exit code generated by a process when exiting. - -Used by [`__wasi_proc_exit()`](#proc_exit). - -### `__wasi_fd_t` (`uint32_t`) - -A file descriptor number. - -Used by many functions in this API. - -As in POSIX, three file descriptor numbers are provided to instances -on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, -and `STDERR_FILENO`). - -Other than these, WASI implementations are not required to allocate -new file descriptors in ascending order. - -### `__wasi_fdflags_t` (`uint16_t` bitfield) - -File descriptor flags. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_FDFLAG_APPEND`** - - Append mode: Data written to the file is always - appended to the file's end. - -- **`__WASI_FDFLAG_DSYNC`** - - Write according to synchronized I/O data integrity - completion. Only the data stored in the file is - synchronized. - -- **`__WASI_FDFLAG_NONBLOCK`** - - Non-blocking mode. - -- **`__WASI_FDFLAG_RSYNC`** - - Synchronized read I/O operations. - -- **`__WASI_FDFLAG_SYNC`** - - Write according to synchronized I/O file integrity completion. - In addition to synchronizing the data stored in the file, the - implementation may also synchronously update the file's metadata. - -### `__wasi_fdstat_t` (`struct`) - -File descriptor attributes. - -Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). - -Members: - -- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype - - File type. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - File descriptor flags. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base - - Rights that apply to this file descriptor. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - Maximum set of rights that may be installed on new - file descriptors that are created through this file - descriptor, e.g., through [`__wasi_path_open()`](#path_open). - -### `__wasi_filedelta_t` (`int64_t`) - -Relative offset within a file. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -### `__wasi_filesize_t` (`uint64_t`) - -Non-negative file size or length of a region within a file. - -Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -### `__wasi_filestat_t` (`struct`) - -File attributes. - -Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). - -Members: - -- [\_\_wasi\_device\_t](#device) st\_dev - - Device ID of device containing the file. - -- [\_\_wasi\_inode\_t](#inode) st\_ino - - File serial number. - -- [\_\_wasi\_filetype\_t](#filetype) st\_filetype - - File type. - -- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink - - Number of hard links to the file. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - For regular files, the file size in bytes. For - symbolic links, the length in bytes of the pathname - contained in the symbolic link. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - Last data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - Last data modification timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim - - Last file status change timestamp. - -### `__wasi_filetype_t` (`uint8_t`) - -The type of a file descriptor or file. - -Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). - -Possible values: - -- **`__WASI_FILETYPE_UNKNOWN`** - - The type of the file descriptor or file is unknown or - is different from any of the other types specified. - -- **`__WASI_FILETYPE_BLOCK_DEVICE`** - - The file descriptor or file refers to a block device - inode. - -- **`__WASI_FILETYPE_CHARACTER_DEVICE`** - - The file descriptor or file refers to a character - device inode. - -- **`__WASI_FILETYPE_DIRECTORY`** - - The file descriptor or file refers to a directory - inode. - -- **`__WASI_FILETYPE_REGULAR_FILE`** - - The file descriptor or file refers to a regular file - inode. - -- **`__WASI_FILETYPE_SOCKET_DGRAM`** - - The file descriptor or file refers to a datagram - socket. - -- **`__WASI_FILETYPE_SOCKET_STREAM`** - - The file descriptor or file refers to a byte-stream - socket. - -- **`__WASI_FILETYPE_SYMBOLIC_LINK`** - - The file refers to a symbolic link inode. - -### `__wasi_fstflags_t` (`uint16_t` bitfield) - -Which file time attributes to adjust. - -Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -Possible values: - -- **`__WASI_FILESTAT_SET_ATIM`** - - Adjust the last data access timestamp to the value - stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). - -- **`__WASI_FILESTAT_SET_ATIM_NOW`** - - Adjust the last data access timestamp to the time - of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -- **`__WASI_FILESTAT_SET_MTIM`** - - Adjust the last data modification timestamp to the - value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). - -- **`__WASI_FILESTAT_SET_MTIM_NOW`** - - Adjust the last data modification timestamp to the - time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -### `__wasi_inode_t` (`uint64_t`) - -File serial number that is unique within its file system. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). - -### `__wasi_iovec_t` (`struct`) - -A region of memory for scatter/gather reads. - -Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). - -Members: - -- void \*buf and size\_t buf\_len - - The address and length of the buffer to be filled. - -### `__wasi_linkcount_t` (`uint32_t`) - -Number of hard links to an inode. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_lookupflags_t` (`uint32_t` bitfield) - -Flags determining the method of how paths are resolved. - -Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** - - As long as the resolved path corresponds to a symbolic - link, it is expanded. - -### `__wasi_oflags_t` (`uint16_t` bitfield) - -Open flags used by [`__wasi_path_open()`](#path_open). - -Used by [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_O_CREAT`** - - Create file if it does not exist. - -- **`__WASI_O_DIRECTORY`** - - Fail if not a directory. - -- **`__WASI_O_EXCL`** - - Fail if file already exists. - -- **`__WASI_O_TRUNC`** - - Truncate file to size 0. - -### `__wasi_riflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_PEEK`** - - Returns the message without removing it from the - socket's receive queue. - -- **`__WASI_SOCK_RECV_WAITALL`** - - On byte-stream sockets, block until the full amount - of data can be returned. - -### `__wasi_rights_t` (`uint64_t` bitfield) - -File descriptor rights, determining which actions may be -performed. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_RIGHT_FD_DATASYNC`** - - The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_READ`** - - The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke - [`__wasi_fd_pread()`](#fd_pread). - -- **`__WASI_RIGHT_FD_SEEK`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies - [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). - -- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** - - The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). - -- **`__WASI_RIGHT_FD_SYNC`** - - The right to invoke [`__wasi_fd_sync()`](#fd_sync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and - [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_TELL`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the - file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with - offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). - -- **`__WASI_RIGHT_FD_WRITE`** - - The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to - invoke [`__wasi_fd_pwrite()`](#fd_pwrite). - -- **`__WASI_RIGHT_FD_ADVISE`** - - The right to invoke [`__wasi_fd_advise()`](#fd_advise). - -- **`__WASI_RIGHT_FD_ALLOCATE`** - - The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). - -- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** - - The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). - -- **`__WASI_RIGHT_PATH_CREATE_FILE`** - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke - [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). - -- **`__WASI_RIGHT_PATH_LINK_SOURCE`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_LINK_TARGET`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_OPEN`** - - The right to invoke [`__wasi_path_open()`](#path_open). - -- **`__WASI_RIGHT_FD_READDIR`** - - The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). - -- **`__WASI_RIGHT_PATH_READLINK`** - - The right to invoke [`__wasi_path_readlink()`](#path_readlink). - -- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_RENAME_TARGET`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_FILESTAT_GET`** - - The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** - - The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -- **`__WASI_RIGHT_FD_FILESTAT_GET`** - - The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** - - The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). - -- **`__WASI_RIGHT_PATH_SYMLINK`** - - The right to invoke [`__wasi_path_symlink()`](#path_symlink). - -- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** - - The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). - -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - -- **`__WASI_RIGHT_POLL_FD_READWRITE`** - - If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). - - If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -- **`__WASI_RIGHT_SOCK_SHUTDOWN`** - - The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). - -### `__wasi_roflags_t` (`uint16_t` bitfield) - -Flags returned by [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** - - Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been - truncated. - -### `__wasi_sdflags_t` (`uint8_t` bitfield) - -Which channels on a socket to shut down. - -Used by [`__wasi_sock_shutdown()`](#sock_shutdown). - -Possible values: - -- **`__WASI_SHUT_RD`** - - Disables further receive operations. - -- **`__WASI_SHUT_WR`** - - Disables further send operations. - -### `__wasi_siflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Used by [`__wasi_sock_send()`](#sock_send). - -### `__wasi_signal_t` (`uint8_t`) - -Signal condition. - -Used by [`__wasi_proc_raise()`](#proc_raise). - -Possible values: - -- **`__WASI_SIGHUP`** - - Hangup. - - Action: Terminates the process. - -- **`__WASI_SIGINT`** - - Terminate interrupt signal. - - Action: Terminates the process. - -- **`__WASI_SIGQUIT`** - - Terminal quit signal. - - Action: Terminates the process. - -- **`__WASI_SIGILL`** - - Illegal instruction. - - Action: Terminates the process. - -- **`__WASI_SIGTRAP`** - - Trace/breakpoint trap. - - Action: Terminates the process. - -- **`__WASI_SIGABRT`** - - Process abort signal. - - Action: Terminates the process. - -- **`__WASI_SIGBUS`** - - Access to an undefined portion of a memory object. - - Action: Terminates the process. - -- **`__WASI_SIGFPE`** - - Erroneous arithmetic operation. - - Action: Terminates the process. - -- **`__WASI_SIGKILL`** - - Kill. - - Action: Terminates the process. - -- **`__WASI_SIGUSR1`** - - User-defined signal 1. - - Action: Terminates the process. - -- **`__WASI_SIGSEGV`** - - Invalid memory reference. - - Action: Terminates the process. - -- **`__WASI_SIGUSR2`** - - User-defined signal 2. - - Action: Terminates the process. - -- **`__WASI_SIGPIPE`** - - Write on a pipe with no one to read it. - - Action: Ignored. - -- **`__WASI_SIGALRM`** - - Alarm clock. - - Action: Terminates the process. - -- **`__WASI_SIGTERM`** - - Termination signal. - - Action: Terminates the process. - -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** - - Continue executing, if stopped. - - Action: Continues executing, if stopped. - -- **`__WASI_SIGSTOP`** - - Stop executing. - - Action: Stops executing. - -- **`__WASI_SIGTSTP`** - - Terminal stop signal. - - Action: Stops executing. - -- **`__WASI_SIGTTIN`** - - Background process attempting read. - - Action: Stops executing. - -- **`__WASI_SIGTTOU`** - - Background process attempting write. - - Action: Stops executing. - -- **`__WASI_SIGURG`** - - High bandwidth data is available at a socket. - - Action: Ignored. - -- **`__WASI_SIGXCPU`** - - CPU time limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGXFSZ`** - - File size limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGVTALRM`** - - Virtual timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGPROF`** - - Profiling timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGWINCH`** - - Window changed. - - Action: Ignored. - -- **`__WASI_SIGPOLL`** - - I/O possible. - - Action: Terminates the process. - -- **`__WASI_SIGPWR`** - - Power failure. - - Action: Terminates the process. - -- **`__WASI_SIGSYS`** - - Bad system call. - - Action: Terminates the process. - -### `__wasi_subclockflags_t` (`uint16_t` bitfield) - -Flags determining how to interpret the timestamp provided in -[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -Used by [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** - - If set, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp - of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - - If clear, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current - time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - -### `__wasi_subscription_t` (`struct`) - -Subscription to an event. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that is attached to the subscription in the - implementation and returned through - [`__wasi_event_t::userdata`](#event.userdata). - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event to which to subscribe. - -- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): - - - **`u.clock`** - - - [\_\_wasi\_userdata\_t](#userdata) identifier - - The user-defined unique identifier of the clock. - - - [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock against which to compare the timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) timeout - - The absolute or relative timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) precision - - The amount of time that the implementation may wait additionally - to coalesce with other events. - - - [\_\_wasi\_subclockflags\_t](#subclockflags) flags - - Flags specifying whether the timeout is absolute or relative. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor on which to wait for it to become ready - for reading or writing. - -### `__wasi_timestamp_t` (`uint64_t`) - -Timestamp in nanoseconds. - -Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -### `__wasi_userdata_t` (`uint64_t`) - -User-provided value that may be attached to objects that is -retained when extracted from the implementation. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -### `__wasi_whence_t` (`uint8_t`) - -The position relative to which to set the offset of the file descriptor. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -Possible values: - -- **`__WASI_WHENCE_CUR`** - - Seek relative to current position. - -- **`__WASI_WHENCE_END`** - - Seek relative to end-of-file. - -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md new file mode 100644 index 000000000..0688fe7cb --- /dev/null +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -0,0 +1,1790 @@ +# Types +## `size`: `u32` + +## `filesize`: `u64` +Non-negative file size or length of a region within a file. + +## `timestamp`: `u64` +Timestamp in nanoseconds. + +## `clockid`: Enum(`u32`) +Identifiers for clocks. + +### Variants +- `realtime` +The clock measuring real time. Time value zero corresponds with +1970-01-01T00:00:00Z. + +- `monotonic` +The store-wide monotonic clock, which is defined as a clock measuring +real time, whose value cannot be adjusted and which cannot have negative +clock jumps. The epoch of this clock is undefined. The absolute time +value of this clock therefore has no meaning. + +- `process_cputime_id` +The CPU-time clock associated with the current process. + +- `thread_cputime_id` +The CPU-time clock associated with the current thread. + +## `errno`: Enum(`u16`) +Error codes returned by functions. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX. + +### Variants +- `success` +No error occurred. System call completed successfully. + +- `2big` +Argument list too long. + +- `acces` +Permission denied. + +- `addrinuse` +Address in use. + +- `addrnotavail` +Address not available. + +- `afnosupport` +Address family not supported. + +- `again` +Resource unavailable, or operation would block. + +- `already` +Connection already in progress. + +- `badf` +Bad file descriptor. + +- `badmsg` +Bad message. + +- `busy` +Device or resource busy. + +- `canceled` +Operation canceled. + +- `child` +No child processes. + +- `connaborted` +Connection aborted. + +- `connrefused` +Connection refused. + +- `connreset` +Connection reset. + +- `deadlk` +Resource deadlock would occur. + +- `destaddrreq` +Destination address required. + +- `dom` +Mathematics argument out of domain of function. + +- `dquot` +Reserved. + +- `exist` +File exists. + +- `fault` +Bad address. + +- `fbig` +File too large. + +- `hostunreach` +Host is unreachable. + +- `idrm` +Identifier removed. + +- `ilseq` +Illegal byte sequence. + +- `inprogress` +Operation in progress. + +- `intr` +Interrupted function. + +- `inval` +Invalid argument. + +- `io` +I/O error. + +- `isconn` +Socket is connected. + +- `isdir` +Is a directory. + +- `loop` +Too many levels of symbolic links. + +- `mfile` +File descriptor value too large. + +- `mlink` +Too many links. + +- `msgsize` +Message too large. + +- `multihop` +Reserved. + +- `nametoolong` +Filename too long. + +- `netdown` +Network is down. + +- `netreset` +Connection aborted by network. + +- `netunreach` +Network unreachable. + +- `nfile` +Too many files open in system. + +- `nobufs` +No buffer space available. + +- `nodev` +No such device. + +- `noent` +No such file or directory. + +- `noexec` +Executable file format error. + +- `nolck` +No locks available. + +- `nolink` +Reserved. + +- `nomem` +Not enough space. + +- `nomsg` +No message of the desired type. + +- `noprotoopt` +Protocol not available. + +- `nospc` +No space left on device. + +- `nosys` +Function not supported. + +- `notconn` +The socket is not connected. + +- `notdir` +Not a directory or a symbolic link to a directory. + +- `notempty` +Directory not empty. + +- `notrecoverable` +State not recoverable. + +- `notsock` +Not a socket. + +- `notsup` +Not supported, or operation not supported on socket. + +- `notty` +Inappropriate I/O control operation. + +- `nxio` +No such device or address. + +- `overflow` +Value too large to be stored in data type. + +- `ownerdead` +Previous owner died. + +- `perm` +Operation not permitted. + +- `pipe` +Broken pipe. + +- `proto` +Protocol error. + +- `protonosupport` +Protocol not supported. + +- `prototype` +Protocol wrong type for socket. + +- `range` +Result too large. + +- `rofs` +Read-only file system. + +- `spipe` +Invalid seek. + +- `srch` +No such process. + +- `stale` +Reserved. + +- `timedout` +Connection timed out. + +- `txtbsy` +Text file busy. + +- `xdev` +Cross-device link. + +- `notcapable` +Extension: Capabilities insufficient. + +## `rights`: Flags(`u64`) +File descriptor rights, determining which actions may be performed. + +### Flags +- `fd_datasync` +The right to invoke [`fd_datasync`](#fd_datasync). +If [`path_open`](#path_open) is set, includes the right to invoke +[`path_open`](#path_open) with `fdflag::dsync`. + +- `fd_read` +The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). + +- `fd_seek` +The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). + +- `fd_fdstat_set_flags` +The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). + +- `fd_sync` +The right to invoke [`fd_sync`](#fd_sync). +If [`path_open`](#path_open) is set, includes the right to invoke +[`path_open`](#path_open) with `fdflag::rsync` and `fdflag::dsync`. + +- `fd_tell` +The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset +remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +invoke [`fd_tell`](#fd_tell). + +- `fd_write` +The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). + +- `fd_advise` +The right to invoke [`fd_advise`](#fd_advise). + +- `fd_allocate` +The right to invoke [`fd_allocate`](#fd_allocate). + +- `path_create_directory` +The right to invoke [`path_create_directory`](#path_create_directory). + +- `path_create_file` +If [`path_open`](#path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). + +- `path_link_source` +The right to invoke [`path_link`](#path_link) with the file descriptor as the +source directory. + +- `path_link_target` +The right to invoke [`path_link`](#path_link) with the file descriptor as the +target directory. + +- `path_open` +The right to invoke [`path_open`](#path_open). + +- `fd_readdir` +The right to invoke [`fd_readdir`](#fd_readdir). + +- `path_readlink` +The right to invoke [`path_readlink`](#path_readlink). + +- `path_rename_source` +The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. + +- `path_rename_target` +The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. + +- `path_filestat_get` +The right to invoke [`path_filestat_get`](#path_filestat_get). + +- `path_filestat_set_size` +The right to change a file's size (there is no `path_filestat_set_size`). +If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). + +- `path_filestat_set_times` +The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). + +- `fd_filestat_get` +The right to invoke [`fd_filestat_get`](#fd_filestat_get). + +- `fd_filestat_set_size` +The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). + +- `fd_filestat_set_times` +The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). + +- `path_symlink` +The right to invoke [`path_symlink`](#path_symlink). + +- `path_remove_directory` +The right to invoke [`path_remove_directory`](#path_remove_directory). + +- `path_unlink_file` +The right to invoke [`path_unlink_file`](#path_unlink_file). + +- `poll_fd_readwrite` +If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). +If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). + +- `sock_shutdown` +The right to invoke [`sock_shutdown`](#sock_shutdown). + +## `fd`: `u32` +A file descriptor index. + +## `iovec`: Struct +A region of memory for scatter/gather reads. + +### Struct members +- `buf`: `Pointer` +The address of the buffer to be filled. + +- `buf_len`: [`size`](#size) +The length of the buffer to be filled. + +## `ciovec`: Struct +A region of memory for scatter/gather writes. + +### Struct members +- `buf`: `ConstPointer` +The address of the buffer to be written. + +- `buf_len`: [`size`](#size) +The length of the buffer to be written. + +## `iovec_array`: `Array` + +## `ciovec_array`: `Array` + +## `filedelta`: `s64` +Relative offset within a file. + +## `whence`: Enum(`u8`) +The position relative to which to set the offset of the file descriptor. + +### Variants +- `set` +Seek relative to start-of-file. + +- `cur` +Seek relative to current position. + +- `end` +Seek relative to end-of-file. + +## `dircookie`: `u64` +A reference to the offset of a directory entry. + +The value 0 signifies the start of the directory. + +## `dirnamlen`: `u32` +The type for the $d_namlen field of $dirent. + +## `inode`: `u64` +File serial number that is unique within its file system. + +## `filetype`: Enum(`u8`) +The type of a file descriptor or file. + +### Variants +- `unknown` +The type of the file descriptor or file is unknown or is different from any of the other types specified. + +- `block_device` +The file descriptor or file refers to a block device inode. + +- `character_device` +The file descriptor or file refers to a character device inode. + +- `directory` +The file descriptor or file refers to a directory inode. + +- `regular_file` +The file descriptor or file refers to a regular file inode. + +- `socket_dgram` +The file descriptor or file refers to a datagram socket. + +- `socket_stream` +The file descriptor or file refers to a byte-stream socket. + +- `symbolic_link` +The file refers to a symbolic link inode. + +## `dirent`: Struct +A directory entry. + +### Struct members +- `d_next`: [`dircookie`](#dircookie) +The offset of the next directory entry stored in this directory. + +- `d_ino`: [`inode`](#inode) +The serial number of the file referred to by this directory entry. + +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. + +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. + +## `advice`: Enum(`u8`) +File or memory access pattern advisory information. + +### Variants +- `normal` +The application has no advice to give on its behavior with respect to the specified data. + +- `sequential` +The application expects to access the specified data sequentially from lower offsets to higher offsets. + +- `random` +The application expects to access the specified data in a random order. + +- `willneed` +The application expects to access the specified data in the near future. + +- `dontneed` +The application expects that it will not access the specified data in the near future. + +- `noreuse` +The application expects to access the specified data once and then not reuse it thereafter. + +## `fdflags`: Flags(`u16`) +File descriptor flags. + +### Flags +- `append` +Append mode: Data written to the file is always appended to the file's end. + +- `dsync` +Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + +- `nonblock` +Non-blocking mode. + +- `rsync` +Synchronized read I/O operations. + +- `sync` +Write according to synchronized I/O file integrity completion. In +addition to synchronizing the data stored in the file, the implementation +may also synchronously update the file's metadata. + +## `fdstat`: Struct +File descriptor attributes. + +### Struct members +- `fs_filetype`: [`filetype`](#filetype) +File type. + +- `fs_flags`: [`fdflags`](#fdflags) +File descriptor flags. + +- `fs_rights_base`: [`rights`](#rights) +Rights that apply to this file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) +Maximum set of rights that may be installed on new file descriptors that +are created through this file descriptor, e.g., through [`path_open`](#path_open). + +## `device`: `u64` +Identifier for a device containing a file system. Can be used in combination +with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. + +## `fstflags`: Flags(`u16`) +Which file time attributes to adjust. + +### Flags +- `atim` +Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + +- `atim_now` +Adjust the last data access timestamp to the time of clock `clock::realtime`. + +- `mtim` +Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + +- `mtim_now` +Adjust the last data modification timestamp to the time of clock `clock::realtime`. + +## `lookupflags`: Flags(`u32`) +Flags determining the method of how paths are resolved. + +### Flags +- `symlink_follow` +As long as the resolved path corresponds to a symbolic link, it is expanded. + +## `oflags`: Flags(`u16`) +Open flags used by [`path_open`](#path_open). + +### Flags +- `creat` +Create file if it does not exist. + +- `directory` +Fail if not a directory. + +- `excl` +Fail if file already exists. + +- `trunc` +Truncate file to size 0. + +## `linkcount`: `u64` +Number of hard links to an inode. + +## `filestat`: Struct +File attributes. + +### Struct members +- `dev`: [`device`](#device) +Device ID of device containing the file. + +- `ino`: [`inode`](#inode) +File serial number. + +- `filetype`: [`filetype`](#filetype) +File type. + +- `nlink`: [`linkcount`](#linkcount) +Number of hard links to the file. + +- `size`: [`filesize`](#filesize) +For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + +- `atim`: [`timestamp`](#timestamp) +Last data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +Last data modification timestamp. + +- `ctim`: [`timestamp`](#timestamp) +Last file status change timestamp. + +## `userdata`: `u64` +User-provided value that may be attached to objects that is retained when +extracted from the implementation. + +## `eventtype`: Enum(`u8`) +Type of a subscription to an event or its occurrence. + +### Variants +- `clock` +The time value of clock `subscription::u.clock.clock_id` has +reached timestamp `subscription::u.clock.timeout`. + +- `fd_read` +File descriptor `subscription::u.fd_readwrite.fd` has data +available for reading. This event always triggers for regular files. + +- `fd_write` +File descriptor `subscription::u.fd_readwrite.fd` has capacity +available for writing. This event always triggers for regular files. + +## `eventrwflags`: Flags(`u16`) +The state of the file descriptor subscribed to with +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Flags +- `fd_readwrite_hangup` +The peer of this socket has closed or disconnected. + +## `event_fd_readwrite`: Struct +The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `nbytes`: [`filesize`](#filesize) +The number of bytes available for reading or writing. + +- `flags`: [`eventrwflags`](#eventrwflags) +The state of the file descriptor. + +## `event_u`: Union +The contents of an $event. + +### Union variants +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `event`: Struct +An event that occurred. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). + +- `error`: [`errno`](#errno) +If non-zero, an error that occurred while processing the subscription request. + +- `type`: [`eventtype`](#eventtype) +The type of the event that occurred. + +- `u`: [`event_u`](#event_u) +The contents of the event. + +## `subclockflags`: Flags(`u16`) +Flags determining how to interpret the timestamp provided in +`subscription::u.clock.timeout.` + +### Flags +- `subscription_clock_abstime` +If set, treat the timestamp provided in +`subscription::u.clock.timeout` as an absolute timestamp of clock +`subscription::u.clock.clock_id.` If clear, treat the timestamp +provided in `subscription::u.clock.timeout` relative to the +current time value of clock `subscription::u.clock.clock_id.` + +## `subscription_clock`: Struct +The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). + +### Struct members +- `id`: [`clockid`](#clockid) +The clock against which to compare the timestamp. + +- `timeout`: [`timestamp`](#timestamp) +The absolute or relative timestamp. + +- `precision`: [`timestamp`](#timestamp) +The amount of time that the implementation may wait additionally +to coalesce with other events. + +- `flags`: [`subclockflags`](#subclockflags) +Flags specifying whether the timeout is absolute or relative + +## `subscription_fd_readwrite`: Struct +The contents of a $subscription when type is type is +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +### Struct members +- `file_descriptor`: [`fd`](#fd) +The file descriptor on which to wait for it to become ready for reading or writing. + +## `subscription_u`: Union +The contents of a $subscription. + +### Union variants +- `clock`: [`subscription_clock`](#subscription_clock) +When type is [`eventtype::clock`](#eventtype.clock): + +- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) +When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): + +## `subscription`: Struct +Subscription to an event. + +### Struct members +- `userdata`: [`userdata`](#userdata) +User-provided value that is attached to the subscription in the +implementation and returned through [`event::userdata`](#event.userdata). + +- `type`: [`eventtype`](#eventtype) +The type of the event to which to subscribe. + +- `u`: [`subscription_u`](#subscription_u) +The contents of the subscription. + +## `exitcode`: `u32` +Exit code generated by a process when exiting. + +## `signal`: Enum(`u8`) +Signal condition. + +### Variants +- `none` +No signal. Note that POSIX has special semantics for `kill(pid, 0)`, +so this value is reserved. + +- `hup` +Hangup. +Action: Terminates the process. + +- `int` +Terminate interrupt signal. +Action: Terminates the process. + +- `quit` +Terminal quit signal. +Action: Terminates the process. + +- `ill` +Illegal instruction. +Action: Terminates the process. + +- `trap` +Trace/breakpoint trap. +Action: Terminates the process. + +- `abrt` +Process abort signal. +Action: Terminates the process. + +- `bus` +Access to an undefined portion of a memory object. +Action: Terminates the process. + +- `fpe` +Erroneous arithmetic operation. +Action: Terminates the process. + +- `kill` +Kill. +Action: Terminates the process. + +- `usr1` +User-defined signal 1. +Action: Terminates the process. + +- `segv` +Invalid memory reference. +Action: Terminates the process. + +- `usr2` +User-defined signal 2. +Action: Terminates the process. + +- `pipe` +Write on a pipe with no one to read it. +Action: Ignored. + +- `alrm` +Alarm clock. +Action: Terminates the process. + +- `term` +Termination signal. +Action: Terminates the process. + +- `chld` +Child process terminated, stopped, or continued. +Action: Ignored. + +- `cont` +Continue executing, if stopped. +Action: Continues executing, if stopped. + +- `stop` +Stop executing. +Action: Stops executing. + +- `tstp` +Terminal stop signal. +Action: Stops executing. + +- `ttin` +Background process attempting read. +Action: Stops executing. + +- `ttou` +Background process attempting write. +Action: Stops executing. + +- `urg` +High bandwidth data is available at a socket. +Action: Ignored. + +- `xcpu` +CPU time limit exceeded. +Action: Terminates the process. + +- `xfsz` +File size limit exceeded. +Action: Terminates the process. + +- `vtalrm` +Virtual timer expired. +Action: Terminates the process. + +- `prof` +Profiling timer expired. +Action: Terminates the process. + +- `winch` +Window changed. +Action: Ignored. + +- `poll` +I/O possible. +Action: Terminates the process. + +- `pwr` +Power failure. +Action: Terminates the process. + +- `sys` +Bad system call. +Action: Terminates the process. + +## `riflags`: Flags(`u16`) +Flags provided to [`sock_recv`](#sock_recv). + +### Flags +- `recv_peek` +Returns the message without removing it from the socket's receive queue. + +- `recv_waitall` +On byte-stream sockets, block until the full amount of data can be returned. + +## `roflags`: Flags(`u16`) +Flags returned by [`sock_recv`](#sock_recv). + +### Flags +- `recv_data_truncated` +Returned by [`sock_recv`](#sock_recv): Message data has been truncated. + +## `siflags`: `u16` +Flags provided to [`sock_send`](#sock_send). As there are currently no flags +defined, it must be set to zero. + +## `sdflags`: Flags(`u8`) +Which channels on a socket to shut down. + +### Flags +- `rd` +Disables further receive operations. + +- `wr` +Disables further send operations. + +## `preopentype`: Enum(`u8`) +Identifiers for preopened capabilities. + +### Variants +- `dir` +A pre-opened directory. + +## `prestat_dir`: Struct +The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). + +### Struct members +- `pr_name_len`: [`size`](#size) +The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). + +## `prestat_u`: Union +The contents of an $prestat. + +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) +When type is [`preopentype::dir`](#preopentype.dir): + +## `prestat`: Struct +Information about a pre-opened capability. + +### Struct members +- `pr_type`: [`preopentype`](#preopentype) +The type of the pre-opened capability. + +- `u`: [`prestat_u`](#prestat_u) +The contents of the information. + +# Modules +## wasi_snapshot_preview1 +### Imports +#### Memory +### Functions + +--- + +#### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` +Read command-line argument data. +The size of the array should match that returned by `wasi_args_sizes_get()` + +##### Params +- `argv`: `Pointer>` + +- `argv_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `args_sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + + +--- + +#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` +Read environment variable data. +The sizes of the buffers should match that returned by `environ.sizes_get()`. + +##### Params +- `environ`: `Pointer>` + +- `environ_buf`: `Pointer` + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `environ_sizes_get() -> (errno, size, size)` +Return command-line argument data sizes. + +##### Params +##### Results +- `error`: [`errno`](#errno) + +- `argc`: [`size`](#size) +The number of arguments. + +- `argv_buf_size`: [`size`](#size) +The size of the argument string data. + + +--- + +#### `clock_res_get(id: clockid) -> (errno, timestamp)` +Return the resolution of a clock. +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Note: This is similar to `clock_getres` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the resolution. + +##### Results +- `error`: [`errno`](#errno) + +- `resolution`: [`timestamp`](#timestamp) +The resolution of the clock. + + +--- + +#### `clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +Return the time value of a clock. +Note: This is similar to `clock_gettime` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the time. + +- `precision`: [`timestamp`](#timestamp) +The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + +##### Results +- `error`: [`errno`](#errno) + +- `time`: [`timestamp`](#timestamp) +The time value of the clock. + + +--- + +#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +Provide file advisory information on a file descriptor. +Note: This is similar to `posix_fadvise` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset within the file to which the advisory applies. + +- `len`: [`filesize`](#filesize) +The length of the region to which the advisory applies. + +- `advice`: [`advice`](#advice) +The advice. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno` +Force the allocation of space in a file. +Note: This is similar to `posix_fallocate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset at which to start the allocation. + +- `len`: [`filesize`](#filesize) +The length of the area that is allocated. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_close(fd: fd) -> errno` +Close a file descriptor. +Note: This is similar to `close` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_datasync(fd: fd) -> errno` +Synchronize the data of a file to disk. +Note: This is similar to `fdatasync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_fdstat_get(fd: fd) -> (errno, fdstat)` +Get the attributes of a file descriptor. +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `stat`: [`fdstat`](#fdstat) +The buffer where the file descriptor's attributes are stored. + + +--- + +#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +Adjust the flags associated with a file descriptor. +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`fdflags`](#fdflags) +The desired values of the file descriptor flags. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +Adjust the rights associated with a file descriptor. +This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + +##### Params +- `fd`: [`fd`](#fd) + +- `fs_rights_base`: [`rights`](#rights) +The desired rights of the file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_filestat_get(fd: fd) -> (errno, filestat)` +Return the attributes of an open file. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `fd_filestat_set_size(fd: fd, size: filesize) -> errno` +Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. +Note: This is similar to `ftruncate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `size`: [`filesize`](#filesize) +The desired file size. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of an open file or directory. +Note: This is similar to `futimens` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +Read from a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `preadv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors in which to store data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to read. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `fd_prestat_get(fd: fd) -> (errno, prestat)` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`prestat`](#prestat) +The buffer where the description is stored. + + +--- + +#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +Return a description of the given preopened file descriptor. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `Pointer` +A buffer into which to write the preopened directory name. + +- `path_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +Write to a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `pwritev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to write. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `fd_read(fd: fd, iovs: iovec_array) -> (errno, size)` +Read from a file descriptor. +Note: This is similar to `readv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +##### Results +- `error`: [`errno`](#errno) + +- `nread`: [`size`](#size) +The number of bytes read. + + +--- + +#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +Read directory entries from a directory. +When successful, the contents of the output buffer consist of a sequence of +directory entries. Each directory entry consists of a dirent_t object, +followed by dirent_t::d_namlen bytes holding the name of the directory +entry. +This function fills the output buffer as much as possible, potentially +truncating the last directory entry. This allows the caller to grow its +read buffer size in case it's too small to fit a single large directory +entry, or skip the oversized directory entry. + +##### Params +- `fd`: [`fd`](#fd) + +- `buf`: `Pointer` +The buffer where directory entries are stored + +- `buf_len`: [`size`](#size) + +- `cookie`: [`dircookie`](#dircookie) +The location within the directory to start reading + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + + +--- + +#### `fd_renumber(fd: fd, to: fd) -> errno` +Atomically replace a file descriptor by renumbering another file descriptor. +Due to the strong focus on thread safety, this environment does not provide +a mechanism to duplicate or renumber a file descriptor to an arbitrary +number, like `dup2()`. This would be prone to race conditions, as an actual +file descriptor with the same number could be allocated by a different +thread at the same time. +This function provides a way to atomically renumber file descriptors, which +would disappear if `dup2()` were to be removed entirely. + +##### Params +- `fd`: [`fd`](#fd) + +- `to`: [`fd`](#fd) +The file descriptor to overwrite. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +Move the offset of a file descriptor. +Note: This is similar to `lseek` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filedelta`](#filedelta) +The number of bytes to move. + +- `whence`: [`whence`](#whence) +The base from which the offset is relative. + +##### Results +- `error`: [`errno`](#errno) + +- `newoffset`: [`filesize`](#filesize) +The new offset of the file descriptor, relative to the start of the file. + + +--- + +#### `fd_sync(fd: fd) -> errno` +Synchronize the data and metadata of a file to disk. +Note: This is similar to `fsync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `fd_tell(fd: fd) -> (errno, filesize)` +Return the current offset of a file descriptor. +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: [`errno`](#errno) + +- `offset`: [`filesize`](#filesize) +The current offset of the file descriptor, relative to the start of the file. + + +--- + +#### `fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)` +Write to a file descriptor. +Note: This is similar to `writev` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +##### Results +- `error`: [`errno`](#errno) + +- `nwritten`: [`size`](#size) +The number of bytes written. + + +--- + +#### `path_create_directory(fd: fd, path: string) -> errno` +Create a directory. +Note: This is similar to `mkdirat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path at which to create the directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +Return the attributes of a file or directory. +Note: This is similar to `stat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to inspect. + +##### Results +- `error`: [`errno`](#errno) + +- `buf`: [`filestat`](#filestat) +The buffer where the file's attributes are stored. + + +--- + +#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +Adjust the timestamps of a file or directory. +Note: This is similar to `utimensat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to operate on. + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +Create a hard link. +Note: This is similar to `linkat` in POSIX. + +##### Params +- `old_fd`: [`fd`](#fd) + +- `old_flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `old_path`: `string` +The source path from which to link. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path at which to create the hard link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)` +Open a file or directory. +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since this +is error-prone in multi-threaded contexts. The returned file descriptor is +guaranteed to be less than 2**31. +Note: This is similar to `openat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `dirflags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The relative path of the file or directory to open, relative to the +`dirfd` directory. + +- `oflags`: [`oflags`](#oflags) +The method by which to open the file. + +- `fs_rights_base`: [`rights`](#rights) +The initial rights of the newly created file descriptor. The +implementation is allowed to return a file descriptor with fewer rights +than specified, if and only if those rights do not apply to the type of +file being opened. +The *base* rights are rights that will apply to operations using the file +descriptor itself, while the *inheriting* rights are rights that apply to +file descriptors derived from it. + +- `fs_rights_inherting`: [`rights`](#rights) + +- `fdflags`: [`fdflags`](#fdflags) + +##### Results +- `error`: [`errno`](#errno) + +- `opened_fd`: [`fd`](#fd) +The file descriptor of the file that has been opened. + + +--- + +#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +Read the contents of a symbolic link. +Note: This is similar to `readlinkat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path of the symbolic link from which to read. + +- `buf`: `Pointer` +The buffer to which to write the contents of the symbolic link. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + +- `bufused`: [`size`](#size) +The number of bytes placed in the buffer. + + +--- + +#### `path_remove_directory(fd: fd, path: string) -> errno` +Remove a directory. +Return `ENOTEMPTY` if the directory is not empty. +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a directory to remove. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +Rename a file or directory. +Note: This is similar to `renameat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `old_path`: `string` +The source path of the file or directory to rename. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path to which to rename the file or directory. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_symlink(old_path: string, fd: fd, new_path: string) -> errno` +Create a symbolic link. +Note: This is similar to `symlinkat` in POSIX. + +##### Params +- `old_path`: `string` +The contents of the symbolic link. + +- `fd`: [`fd`](#fd) + +- `new_path`: `string` +The destination path at which to create the symbolic link. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `path_unlink_file(fd: fd, path: string) -> errno` +Unlink a file. +Return `EISDIR` if the path refers to a directory. +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a file to unlink. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +Concurrently poll for the occurrence of a set of events. + +##### Params +- `in`: `ConstPointer` +The events to which to subscribe. + +- `out`: `Pointer` +The events that have occurred. + +- `nsubscriptions`: [`size`](#size) +Both the number of subscriptions and events. + +##### Results +- `error`: [`errno`](#errno) + +- `nevents`: [`size`](#size) +The number of events stored. + + +--- + +#### `proc_exit(rval: exitcode)` +Terminate the process normally. An exit code of 0 indicates successful +termination of the program. The meanings of other values is dependent on +the environment. + +##### Params +- `rval`: [`exitcode`](#exitcode) +The exit code returned by the process. + +##### Results + +--- + +#### `proc_raise(sig: signal) -> errno` +Send a signal to the process of the calling thread. +Note: This is similar to `raise` in POSIX. + +##### Params +- `sig`: [`signal`](#signal) +The signal condition to trigger. + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sched_yield() -> errno` +Temporarily yield execution of the calling thread. +Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. + +##### Params +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `random_get(buf: Pointer, buf_len: size) -> errno` +Write high-quality random data into a buffer. +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. +This function may execute slowly, so when large mounts of random data are +required, it's advisable to use this function to seed a pseudo-random +number generator, rather than to provide the random data directly. + +##### Params +- `buf`: `Pointer` +The buffer to fill with random data. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: [`errno`](#errno) + + +--- + +#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +Receive a message from a socket. +Note: This is similar to `recv` in POSIX, though it also supports reading +the data into multiple buffers in the manner of `readv`. + +##### Params +- `fd`: [`fd`](#fd) + +- `ri_data`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +- `ri_flags`: [`riflags`](#riflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `ro_datalen`: [`size`](#size) +Number of bytes stored in ri_data. + +- `ro_flags`: [`roflags`](#roflags) +Message flags. + + +--- + +#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +Send a message on a socket. +Note: This is similar to `send` in POSIX, though it also supports writing +the data from multiple buffers in the manner of `writev`. + +##### Params +- `fd`: [`fd`](#fd) + +- `si_data`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors to which to retrieve data + +- `si_flags`: [`siflags`](#siflags) +Message flags. + +##### Results +- `error`: [`errno`](#errno) + +- `so_datalen`: [`size`](#size) +Number of bytes transmitted. + + +--- + +#### `sock_shutdown(fd: fd, how: sdflags) -> errno` +Shut down socket send and receive channels. +Note: This is similar to `shutdown` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `how`: [`sdflags`](#sdflags) +Which channels on the socket to shut down. + +##### Results +- `error`: [`errno`](#errno) + diff --git a/proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md b/proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md deleted file mode 100644 index 7aa5816af..000000000 --- a/proposals/filesystem/phases/snapshot/docs/wasi_unstable_preview1.md +++ /dev/null @@ -1,2346 +0,0 @@ - - -# The WASI Preview API - -This is the API-level documentation for WASI Preview. The function names -are prefixed with "\_\_wasi\_" to reflect how they are spelled in -flat-namespace contexts, however at the wasm module level, they are -unprefixed, because they're inside a module namespace. - -Functions that start with `__wasi_fd_` operate on file descriptors, -while functions that start with `__wasi_path_` operate on filesystem -paths, which are relative to directory file descriptors. - -Much inspiration and content here is derived from [CloudABI] and [POSIX], -though there are also several differences from CloudABI and POSIX. For -example, WASI Preview has no concept of processes in the traditional Unix -sense. While wasm linear memories have some of the aspects of processes, -and it's possible to *emulate* the full semantics of processes on top of -them, this can sometimes be unnatural and inefficient. The goal for -WASI Preview is to be a WebAssembly-native API that exposes APIs that fit -well into the underlying WebAssembly platform, rather than to directly -emulate other platforms. - -This is also a work in progress, and the API here is still evolving. - -Historical note: this API was originally named "WASI Core", and used the -API module name "wasi\_unstable". We've since sought to deemphasize the -"Core" name, as the goal is to split this API up into independent -modules so that embedders need not implement all of it. - -[CloudABI]: https://github.com/NuxiNL/cloudabi -[POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/ - -## System calls - -- [`__wasi_args_get()`](#args_get) -- [`__wasi_args_sizes_get()`](#args_sizes_get) -- [`__wasi_clock_res_get()`](#clock_res_get) -- [`__wasi_clock_time_get()`](#clock_time_get) -- [`__wasi_environ_get()`](#environ_get) -- [`__wasi_environ_sizes_get()`](#environ_sizes_get) -- [`__wasi_fd_advise()`](#fd_advise) -- [`__wasi_fd_allocate()`](#fd_allocate) -- [`__wasi_fd_close()`](#fd_close) -- [`__wasi_fd_datasync()`](#fd_datasync) -- [`__wasi_fd_fdstat_get()`](#fd_fdstat_get) -- [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags) -- [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights) -- [`__wasi_fd_filestat_get()`](#fd_filestat_get) -- [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size) -- [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) -- [`__wasi_fd_pread()`](#fd_pread) -- [`__wasi_fd_prestat_get()`](#fd_prestat_get) -- [`__wasi_fd_prestat_dir_name()`](#fd_prestat_dir_name) -- [`__wasi_fd_pwrite()`](#fd_pwrite) -- [`__wasi_fd_read()`](#fd_read) -- [`__wasi_fd_readdir()`](#fd_readdir) -- [`__wasi_fd_renumber()`](#fd_renumber) -- [`__wasi_fd_seek()`](#fd_seek) -- [`__wasi_fd_sync()`](#fd_sync) -- [`__wasi_fd_tell()`](#fd_tell) -- [`__wasi_fd_write()`](#fd_write) -- [`__wasi_path_create_directory()`](#path_create_directory) -- [`__wasi_path_filestat_get()`](#path_filestat_get) -- [`__wasi_path_filestat_set_times()`](#path_filestat_set_times) -- [`__wasi_path_link()`](#path_link) -- [`__wasi_path_open()`](#path_open) -- [`__wasi_path_readlink()`](#path_readlink) -- [`__wasi_path_remove_directory()`](#path_remove_directory) -- [`__wasi_path_rename()`](#path_rename) -- [`__wasi_path_symlink()`](#path_symlink) -- [`__wasi_path_unlink_file()`](#path_unlink_file) -- [`__wasi_poll_oneoff()`](#poll_oneoff) -- [`__wasi_proc_exit()`](#proc_exit) -- [`__wasi_proc_raise()`](#proc_raise) -- [`__wasi_random_get()`](#random_get) -- [`__wasi_sched_yield()`](#sched_yield) -- [`__wasi_sock_recv()`](#sock_recv) -- [`__wasi_sock_send()`](#sock_send) -- [`__wasi_sock_shutdown()`](#sock_shutdown) - -### `__wasi_args_get()` - -Read command-line argument data. - -Inputs: - -- char \*\*argv - - A pointer to a buffer to write the argument pointers. - - The count of elements for the buffer should be at least the value of `argc` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - - The caller of `__wasi_args_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. - -- char \*argv\_buf - - A pointer to a buffer to write the argument string data. - - The size of this buffer should be the value of `argv_buf_size` returned by [`__wasi_args_sizes_get()`](#args_sizes_get). - -### `__wasi_args_sizes_get()` - -Return command-line argument data sizes. - -Outputs: - -- size\_t \*argc - - The number of arguments. - -- size\_t \*argv\_buf\_size - - The size of the argument string data. - -### `__wasi_clock_res_get()` - -Return the resolution of a clock. - -Implementations are required to provide a non-zero value for supported clocks. -For unsupported clocks, return [`__WASI_EINVAL`](#errno.inval). - -Note: This is similar to `clock_getres` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the resolution. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) resolution - - The resolution of the clock. - -### `__wasi_clock_time_get()` - -Return the time value of a clock. - -Note: This is similar to `clock_gettime` in POSIX. - -Inputs: - -- [\_\_wasi\_clockid\_t](#clockid) clock\_id - - The clock for which to return the time. - -- [\_\_wasi\_timestamp\_t](#timestamp) precision - - The maximum lag (exclusive) that the returned - time value may have, compared to its actual - value. - -Outputs: - -- [\_\_wasi\_timestamp\_t](#timestamp) time - - The time value of the clock. - -### `__wasi_environ_get()` - -Read environment variable data. - -Inputs: - -- char \*\*environ - - A pointer to a buffer to write the environment variable pointers. - - The count of elements for the buffer should be at least the value of `environ_count` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - - The caller of `__wasi_environ_get()` is responsible for allocating an additional element for a terminating NULL pointer, if necessary. - -- char \*environ\_buf - - A pointer to a buffer to write the environment variable string data. - - The size of this buffer should be the value of `environ_buf_size` returned by [`__wasi_environ_sizes_get()`](#environ_sizes_get). - -### `__wasi_environ_sizes_get()` - -Return enviroment variable data sizes. - -Outputs: - -- size\_t \*environ\_count - - The number of environment variables. - -- size\_t \*environ\_buf\_size - - The size of the environment variable string data. - -### `__wasi_fd_advise()` - -Provide file advisory information on a file descriptor. - -Note: This is similar to `posix_fadvise` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file for which to provide file advisory information. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file to which the advisory applies. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the region to which the advisory applies. - -- [\_\_wasi\_advice\_t](#advice) advice - - The advice. - -### `__wasi_fd_allocate()` - -Force the allocation of space in a file. - -Note: This is similar to `posix_fallocate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor for the file in which to allocate space. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset at which to start the allocation. - -- [\_\_wasi\_filesize\_t](#filesize) len - - The length of the area that is allocated. - -### `__wasi_fd_close()` - -Close a file descriptor. - -Note: This is similar to `close` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to close. - -### `__wasi_fd_datasync()` - -Synchronize the data of a file to disk. - -Note: This is similar to `fdatasync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file to synchronize to disk. - -### `__wasi_fd_fdstat_get()` - -Get the attributes of a file descriptor. - -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well -as additional fields. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_fdstat\_t](#fdstat) \*buf - - The buffer where the file descriptor's attributes are stored. - -### `__wasi_fd_fdstat_set_flags()` - -Adjust the flags associated with a file descriptor. - -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_fdflags\_t](#fdflags) flags - - The desired values of the file descriptor - flags. - -### `__wasi_fd_fdstat_set_rights()` - -Adjust the rights associated with a file descriptor. - -This can only be used to remove rights, and returns -[`__WASI_ENOTCAPABLE`](#errno.notcapable) if called in a way that would attempt -to add rights. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The desired rights of the file descriptor. - -### `__wasi_fd_filestat_get()` - -Return the attributes of an open file. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_fd_filestat_set_size()` - -Adjust the size of an open file. If this increases the file's size, the extra -bytes are filled with zeros. - -Note: This is similar to `ftruncate` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - A file descriptor for the file to adjust. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - The desired file size. - -### `__wasi_fd_filestat_set_times()` - -Adjust the timestamps of an open file or directory. - -Note: This is similar to `futimens` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_fd_pread()` - -Read from a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `preadv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors in which to store data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to read. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_prestat_get()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- [\_\_wasi\_prestat\_t](#prestat) \*buf - - The buffer where the description is stored. - -### `__wasi_fd_prestat_dir_name()` - -Return a description of the given preopened file descriptor. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor about which to retrieve information. - -- const char \*path and size\_t path\_len - - A buffer into which to write the preopened directory name. - -### `__wasi_fd_pwrite()` - -Write to a file descriptor, without using and updating the -file descriptor's offset. - -Note: This is similar to `pwritev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The offset within the file at which to write. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_fd_read()` - -Read from a file descriptor. - -Note: This is similar to `readv` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor from which to read data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors to which to store data. - -Outputs: - -- size\_t nread - - The number of bytes read. - -### `__wasi_fd_readdir()` - -Read directory entries from a directory. - -When successful, the contents of the output buffer consist of -a sequence of directory entries. Each directory entry consists -of a [`__wasi_dirent_t`](#dirent) object, followed by [`__wasi_dirent_t::d_namlen`](#dirent.d_namlen) bytes -holding the name of the directory entry. - -This function fills the output buffer as much as possible, -potentially truncating the last directory entry. This allows -the caller to grow its read buffer size in case it's too small -to fit a single large directory entry, or skip the oversized -directory entry. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The directory from which to read the directory - entries. - -- void \*buf and size\_t buf\_len - - The buffer where directory entries are stored. - -- [\_\_wasi\_dircookie\_t](#dircookie) cookie - - The location within the directory to start - reading. - -Outputs: - -- size\_t bufused - - The number of bytes stored in the read buffer. - If less than the size of the read buffer, the - end of the directory has been reached. - -### `__wasi_fd_renumber()` - -Atomically replace a file descriptor by renumbering another -file descriptor. - -Due to the strong focus on thread safety, this environment -does not provide a mechanism to duplicate or renumber a file -descriptor to an arbitrary number, like dup2(). This would be -prone to race conditions, as an actual file descriptor with the -same number could be allocated by a different thread at the same -time. - -This function provides a way to atomically renumber file -descriptors, which would disappear if dup2() were to be -removed entirely. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) from - - The file descriptor to renumber. - -- [\_\_wasi\_fd\_t](#fd) to - - The file descriptor to overwrite. - -### `__wasi_fd_seek()` - -Move the offset of a file descriptor. - -Note: This is similar to `lseek` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to operate on. - -- [\_\_wasi\_filedelta\_t](#filedelta) offset - - The number of bytes to move. - -- [\_\_wasi\_whence\_t](#whence) whence - - The base from which the offset is relative. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) newoffset - - The new offset of the file descriptor, - relative to the start of the file. - -### `__wasi_fd_sync()` - -Synchronize the data and metadata of a file to disk. - -Note: This is similar to `fsync` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file containing the data - and metadata to synchronize to disk. - -### `__wasi_fd_tell()` - -Return the current offset of a file descriptor. - -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to inspect. - -Outputs: - -- [\_\_wasi\_filesize\_t](#filesize) offset - - The current offset of the file descriptor, relative to the start of the file. - -### `__wasi_fd_write()` - -Write to a file descriptor. - -Note: This is similar to `writev` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor to which to write data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*iovs and size\_t iovs\_len - - List of scatter/gather vectors from which to retrieve data. - -Outputs: - -- size\_t nwritten - - The number of bytes written. - -### `__wasi_path_create_directory()` - -Create a directory. - -Note: This is similar to `mkdirat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path at which to create the directory. - -### `__wasi_path_filestat_get()` - -Return the attributes of a file or directory. - -Note: This is similar to `stat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to inspect. - -- [\_\_wasi\_filestat\_t](#filestat) \*buf - - The buffer where the file's attributes are - stored. - -### `__wasi_path_filestat_set_times()` - -Adjust the timestamps of a file or directory. - -Note: This is similar to `utimensat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) flags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The path of the file or directory to operate on. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - The desired values of the data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - The desired values of the data modification timestamp. - -- [\_\_wasi\_fstflags\_t](#fstflags) fst\_flags - - A bitmask indicating which timestamps to adjust. - -### `__wasi_path_link()` - -Create a hard link. - -Note: This is similar to `linkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) old\_flags - - Flags determining the method of how the path is resolved. - -- const char \*old\_path and size\_t old\_path\_len - - The source path from which to link. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the hard link. - -### `__wasi_path_open()` - -Open a file or directory. - -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since -this is error-prone in multi-threaded contexts. The returned file -descriptor is guaranteed to be less than 231. - -Note: This is similar to `openat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) dirfd - - The working directory at which the resolution of the path starts. - -- [\_\_wasi\_lookupflags\_t](#lookupflags) dirflags - - Flags determining the method of how the path is resolved. - -- const char \*path and size\_t path\_len - - The relative path of the file or directory to open, relative to - the [`dirfd`](#path_open.dirfd) directory. - -- [\_\_wasi\_oflags\_t](#oflags) o_flags - - The method by which to open the file. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base and [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - The initial rights of the newly created file descriptor. The - implementation is allowed to return a file descriptor with fewer - rights than specified, if and only if those rights do not apply - to the type of file being opened. - - The *base* rights are rights that will apply to operations using - the file descriptor itself, while the *inheriting* rights are - rights that apply to file descriptors derived from it. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - The initial flags of the file descriptor. - -Outputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor of the file that has been - opened. - -### `__wasi_path_readlink()` - -Read the contents of a symbolic link. - -Note: This is similar to `readlinkat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path of the symbolic link from which to read. - -- char \*buf and size\_t buf\_len - - The buffer to which to write the contents of the symbolic link. - -Outputs: - -- size\_t bufused - - The number of bytes placed in the buffer. - -### `__wasi_path_remove_directory()` - -Remove a directory. - -Return [`__WASI_ENOTEMPTY`](#errno.notempty) if the directory is not empty. - -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a directory to remove. - -### `__wasi_path_rename()` - -Rename a file or directory. - -Note: This is similar to `renameat` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) old\_fd - - The working directory at which the resolution of the old path starts. - -- const char \*old\_path and size\_t old\_path\_len - - The source path of the file or directory to rename. - -- [\_\_wasi\_fd\_t](#fd) new\_fd - - The working directory at which the resolution of the new path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path to which to rename the file or directory. - -### `__wasi_path_symlink()` - -Create a symbolic link. - -Note: This is similar to `symlinkat` in POSIX. - -Inputs: - -- const char \*old\_path and size\_t old_path\_len - - The contents of the symbolic link. - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*new\_path and size\_t new\_path\_len - - The destination path at which to create the symbolic link. - -### `__wasi_path_unlink_file()` - -Unlink a file. - -Return [`__WASI_EISDIR`](#errno.isdir) if the path refers to a directory. - -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) fd - - The working directory at which the resolution of the path starts. - -- const char \*path and size\_t path\_len - - The path to a file to unlink. - -### `__wasi_poll_oneoff()` - -Concurrently poll for the occurrence of a set of events. - -Inputs: - -- const [\_\_wasi\_subscription\_t](#subscription) \*in - - The events to which to subscribe. - -- [\_\_wasi\_event\_t](#event) \*out - - The events that have occurred. - -- size\_t nsubscriptions - - Both the number of subscriptions and events. - -Outputs: - -- size\_t nevents - - The number of events stored. - -### `__wasi_proc_exit()` - -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -Note: This is similar to `_Exit` in POSIX. - -Inputs: - -- [\_\_wasi\_exitcode\_t](#exitcode) rval - - The exit code returned by the process. - -Does not return. - -### `__wasi_proc_raise()` - -Send a signal to the process of the calling thread. - -Note: This is similar to `raise` in POSIX. - -Inputs: - -- [\_\_wasi\_signal\_t](#signal) sig - - The signal condition to trigger. - -### `__wasi_random_get()` - -Write high-quality random data into a buffer. - -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. - -This function may execute slowly, so when large mounts of random -data are required, it's advisable to use this function to seed a -pseudo-random number generator, rather than to provide the -random data directly. - -Inputs: - -- void \*buf and size\_t buf\_len - - The buffer to fill with random data. - -### `__wasi_sched_yield()` - -Temporarily yield execution of the calling thread. - -Note: This is similar to `sched_yield` in POSIX. - -### `__wasi_sock_recv()` - -Receive a message from a socket. - -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to receive data. - -- const [\_\_wasi\_iovec\_t](#iovec) \*ri\_data and size\_t ri\_data\_len - - List of scatter/gather vectors to which to store data. - -- [\_\_wasi\_riflags\_t](#riflags) ri\_flags - - Message flags. - -Outputs: - -- size\_t ro\_datalen - - Number of bytes stored in [`ri_data`](#sock_recv.ri_data). - -- [\_\_wasi\_roflags\_t](#roflags) ro\_flags - - Message flags. - -### `__wasi_sock_send()` - -Send a message on a socket. - -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to send data. - -- const [\_\_wasi\_ciovec\_t](#ciovec) \*si\_data and size\_t si\_data\_len - - List of scatter/gather vectors to which to retrieve data - -- [\_\_wasi\_siflags\_t](#siflags) si\_flags - - Message flags. - -Outputs: - -- size\_t so\_datalen - - Number of bytes transmitted. - -### `__wasi_sock_shutdown()` - -Shut down socket send and receive channels. - -Note: This is similar to `shutdown` in POSIX. - -Inputs: - -- [\_\_wasi\_fd\_t](#fd) sock - - The socket on which to shutdown channels. - -- [\_\_wasi\_sdflags\_t](#sdflags) how - - Which channels on the socket to shut down. - -## Types - -### `__wasi_advice_t` (`uint8_t`) - -File or memory access pattern advisory information. - -Used by [`__wasi_fd_advise()`](#fd_advise). - -Possible values: - -- **`__WASI_ADVICE_NORMAL`** - - The application has no advice to give on its behavior - with respect to the specified data. - -- **`__WASI_ADVICE_SEQUENTIAL`** - - The application expects to access the specified data - sequentially from lower offsets to higher offsets. - -- **`__WASI_ADVICE_RANDOM`** - - The application expects to access the specified data - in a random order. - -- **`__WASI_ADVICE_WILLNEED`** - - The application expects to access the specified data - in the near future. - -- **`__WASI_ADVICE_DONTNEED`** - - The application expects that it will not access the - specified data in the near future. - -- **`__WASI_ADVICE_NOREUSE`** - - The application expects to access the specified data - once and then not reuse it thereafter. - -### `__wasi_ciovec_t` (`struct`) - -A region of memory for scatter/gather writes. - -Used by [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_write()`](#fd_write), and [`__wasi_sock_send()`](#sock_send). - -Members: - -- const void \*buf and size\_t buf\_len - - The address and length of the buffer to be written. - -### `__wasi_clockid_t` (`uint32_t`) - -Identifiers for clocks. - -Used by [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), and [`__wasi_clock_time_get()`](#clock_time_get). - -Possible values: - -- **`__WASI_CLOCK_REALTIME`** - - The clock measuring real time. Time value - zero corresponds with 1970-01-01T00:00:00Z. - -- **`__WASI_CLOCK_MONOTONIC`** - - The store-wide monotonic clock, which is defined as a - clock measuring real time, whose value cannot be - adjusted and which cannot have negative clock jumps. - - The epoch of this clock is undefined. The absolute - time value of this clock therefore has no meaning. - -- **`__WASI_CLOCK_PROCESS_CPUTIME_ID`** - - The CPU-time clock associated with the current - process. - -- **`__WASI_CLOCK_THREAD_CPUTIME_ID`** - - The CPU-time clock associated with the current thread. - -### `__wasi_device_t` (`uint64_t`) - -Identifier for a device containing a file system. Can be used -in combination with [`__wasi_inode_t`](#inode) to uniquely identify a file or -directory in the filesystem. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_dircookie_t` (`uint64_t`) - -A reference to the offset of a directory entry. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_fd_readdir()`](#fd_readdir). - -Special values: - -- **`__WASI_DIRCOOKIE_START`** - - Permanent reference to the first directory entry - within a directory. - -### `__wasi_dirent_t` (`struct`) - -A directory entry. - -Members: - -- [\_\_wasi\_dircookie\_t](#dircookie) d\_next - - The offset of the next directory entry stored in this - directory. - -- [\_\_wasi\_inode\_t](#inode) d\_ino - - The serial number of the file referred to by this - directory entry. - -- uint32\_t d\_namlen - - The length of the name of the directory entry. - -- [\_\_wasi\_filetype\_t](#filetype) d\_type - - The type of the file referred to by this directory - entry. - -### `__wasi_errno_t` (`uint16_t`) - -Error codes returned by functions. - -Not all of these error codes are returned by the functions -provided by this API; some are used in higher-level library layers, -and others are provided merely for alignment with POSIX. - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_ESUCCESS`** - - No error occurred. System call completed successfully. - -- **`__WASI_E2BIG`** - - Argument list too long. - -- **`__WASI_EACCES`** - - Permission denied. - -- **`__WASI_EADDRINUSE`** - - Address in use. - -- **`__WASI_EADDRNOTAVAIL`** - - Address not available. - -- **`__WASI_EAFNOSUPPORT`** - - Address family not supported. - -- **`__WASI_EAGAIN`** - - Resource unavailable, or operation would block. - -- **`__WASI_EALREADY`** - - Connection already in progress. - -- **`__WASI_EBADF`** - - Bad file descriptor. - -- **`__WASI_EBADMSG`** - - Bad message. - -- **`__WASI_EBUSY`** - - Device or resource busy. - -- **`__WASI_ECANCELED`** - - Operation canceled. - -- **`__WASI_ECHILD`** - - No child processes. - -- **`__WASI_ECONNABORTED`** - - Connection aborted. - -- **`__WASI_ECONNREFUSED`** - - Connection refused. - -- **`__WASI_ECONNRESET`** - - Connection reset. - -- **`__WASI_EDEADLK`** - - Resource deadlock would occur. - -- **`__WASI_EDESTADDRREQ`** - - Destination address required. - -- **`__WASI_EDOM`** - - Mathematics argument out of domain of function. - -- **`__WASI_EDQUOT`** - - Reserved. - -- **`__WASI_EEXIST`** - - File exists. - -- **`__WASI_EFAULT`** - - Bad address. - -- **`__WASI_EFBIG`** - - File too large. - -- **`__WASI_EHOSTUNREACH`** - - Host is unreachable. - -- **`__WASI_EIDRM`** - - Identifier removed. - -- **`__WASI_EILSEQ`** - - Illegal byte sequence. - -- **`__WASI_EINPROGRESS`** - - Operation in progress. - -- **`__WASI_EINTR`** - - Interrupted function. - -- **`__WASI_EINVAL`** - - Invalid argument. - -- **`__WASI_EIO`** - - I/O error. - -- **`__WASI_EISCONN`** - - Socket is connected. - -- **`__WASI_EISDIR`** - - Is a directory. - -- **`__WASI_ELOOP`** - - Too many levels of symbolic links. - -- **`__WASI_EMFILE`** - - File descriptor value too large. - -- **`__WASI_EMLINK`** - - Too many links. - -- **`__WASI_EMSGSIZE`** - - Message too large. - -- **`__WASI_EMULTIHOP`** - - Reserved. - -- **`__WASI_ENAMETOOLONG`** - - Filename too long. - -- **`__WASI_ENETDOWN`** - - Network is down. - -- **`__WASI_ENETRESET`** - - Connection aborted by network. - -- **`__WASI_ENETUNREACH`** - - Network unreachable. - -- **`__WASI_ENFILE`** - - Too many files open in system. - -- **`__WASI_ENOBUFS`** - - No buffer space available. - -- **`__WASI_ENODEV`** - - No such device. - -- **`__WASI_ENOENT`** - - No such file or directory. - -- **`__WASI_ENOEXEC`** - - Executable file format error. - -- **`__WASI_ENOLCK`** - - No locks available. - -- **`__WASI_ENOLINK`** - - Reserved. - -- **`__WASI_ENOMEM`** - - Not enough space. - -- **`__WASI_ENOMSG`** - - No message of the desired type. - -- **`__WASI_ENOPROTOOPT`** - - Protocol not available. - -- **`__WASI_ENOSPC`** - - No space left on device. - -- **`__WASI_ENOSYS`** - - Function not supported. - -- **`__WASI_ENOTCONN`** - - The socket is not connected. - -- **`__WASI_ENOTDIR`** - - Not a directory or a symbolic link to a directory. - -- **`__WASI_ENOTEMPTY`** - - Directory not empty. - -- **`__WASI_ENOTRECOVERABLE`** - - State not recoverable. - -- **`__WASI_ENOTSOCK`** - - Not a socket. - -- **`__WASI_ENOTSUP`** - - Not supported, or operation not supported on socket. - -- **`__WASI_ENOTTY`** - - Inappropriate I/O control operation. - -- **`__WASI_ENXIO`** - - No such device or address. - -- **`__WASI_EOVERFLOW`** - - Value too large to be stored in data type. - -- **`__WASI_EOWNERDEAD`** - - Previous owner died. - -- **`__WASI_EPERM`** - - Operation not permitted. - -- **`__WASI_EPIPE`** - - Broken pipe. - -- **`__WASI_EPROTO`** - - Protocol error. - -- **`__WASI_EPROTONOSUPPORT`** - - Protocol not supported. - -- **`__WASI_EPROTOTYPE`** - - Protocol wrong type for socket. - -- **`__WASI_ERANGE`** - - Result too large. - -- **`__WASI_EROFS`** - - Read-only file system. - -- **`__WASI_ESPIPE`** - - Invalid seek. - -- **`__WASI_ESRCH`** - - No such process. - -- **`__WASI_ESTALE`** - - Reserved. - -- **`__WASI_ETIMEDOUT`** - - Connection timed out. - -- **`__WASI_ETXTBSY`** - - Text file busy. - -- **`__WASI_EXDEV`** - - Cross-device link. - -- **`__WASI_ENOTCAPABLE`** - - Extension: Capabilities insufficient. - -### `__wasi_event_t` (`struct`) - -An event that occurred. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that got attached to - [`__wasi_subscription_t::userdata`](#subscription.userdata). - -- [\_\_wasi\_errno\_t](#errno) error - - If non-zero, an error that occurred while processing - the subscription request. - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event that occurred. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_filesize\_t](#filesize) nbytes - - The number of bytes available for reading or writing. - - - [\_\_wasi\_eventrwflags\_t](#eventrwflags) flags - - The state of the file descriptor. - -### `__wasi_eventrwflags_t` (`uint16_t` bitfield) - -The state of the file descriptor subscribed to with -[`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -Used by [`__wasi_event_t`](#event). - -Possible values: - -- **`__WASI_EVENT_FD_READWRITE_HANGUP`** - - The peer of this socket has closed or disconnected. - -### `__wasi_eventtype_t` (`uint8_t`) - -Type of a subscription to an event or its occurrence. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_EVENTTYPE_CLOCK`** - - The time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id) - has reached timestamp [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -- **`__WASI_EVENTTYPE_FD_READ`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - data available for reading. This event always triggers - for regular files. - -- **`__WASI_EVENTTYPE_FD_WRITE`** - - File descriptor [`__wasi_subscription_t::u.fd_readwrite.fd`](#subscription.u.fd_readwrite.fd) has - capacity available for writing. This event always - triggers for regular files. - -### `__wasi_exitcode_t` (`uint32_t`) - -Exit code generated by a process when exiting. - -Used by [`__wasi_proc_exit()`](#proc_exit). - -### `__wasi_fd_t` (`uint32_t`) - -A file descriptor number. - -Used by many functions in this API. - -As in POSIX, three file descriptor numbers are provided to instances -on startup -- 0, 1, and 2, (a.k.a. `STDIN_FILENO`, `STDOUT_FILENO`, -and `STDERR_FILENO`). - -Other than these, WASI implementations are not required to allocate -new file descriptors in ascending order. - -### `__wasi_fdflags_t` (`uint16_t` bitfield) - -File descriptor flags. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_FDFLAG_APPEND`** - - Append mode: Data written to the file is always - appended to the file's end. - -- **`__WASI_FDFLAG_DSYNC`** - - Write according to synchronized I/O data integrity - completion. Only the data stored in the file is - synchronized. - -- **`__WASI_FDFLAG_NONBLOCK`** - - Non-blocking mode. - -- **`__WASI_FDFLAG_RSYNC`** - - Synchronized read I/O operations. - -- **`__WASI_FDFLAG_SYNC`** - - Write according to synchronized I/O file integrity completion. - In addition to synchronizing the data stored in the file, the - implementation may also synchronously update the file's metadata. - -### `__wasi_fdstat_t` (`struct`) - -File descriptor attributes. - -Used by [`__wasi_fd_fdstat_get()`](#fd_fdstat_get). - -Members: - -- [\_\_wasi\_filetype\_t](#filetype) fs\_filetype - - File type. - -- [\_\_wasi\_fdflags\_t](#fdflags) fs\_flags - - File descriptor flags. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_base - - Rights that apply to this file descriptor. - -- [\_\_wasi\_rights\_t](#rights) fs\_rights\_inheriting - - Maximum set of rights that may be installed on new - file descriptors that are created through this file - descriptor, e.g., through [`__wasi_path_open()`](#path_open). - -### `__wasi_filedelta_t` (`int64_t`) - -Relative offset within a file. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -### `__wasi_filesize_t` (`uint64_t`) - -Non-negative file size or length of a region within a file. - -Used by [`__wasi_event_t`](#event), [`__wasi_filestat_t`](#filestat), [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_pwrite()`](#fd_pwrite), [`__wasi_fd_seek()`](#fd_seek), [`__wasi_path_tell()`](#path_tell), [`__wasi_fd_advise()`](#fd_advise), [`__wasi_fd_allocate()`](#fd_allocate), and [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -### `__wasi_filestat_t` (`struct`) - -File attributes. - -Used by [`__wasi_fd_filestat_get()`](#fd_filestat_get) and [`__wasi_path_filestat_get()`](#path_filestat_get). - -Members: - -- [\_\_wasi\_device\_t](#device) st\_dev - - Device ID of device containing the file. - -- [\_\_wasi\_inode\_t](#inode) st\_ino - - File serial number. - -- [\_\_wasi\_filetype\_t](#filetype) st\_filetype - - File type. - -- [\_\_wasi\_linkcount\_t](#linkcount) st\_nlink - - Number of hard links to the file. - -- [\_\_wasi\_filesize\_t](#filesize) st\_size - - For regular files, the file size in bytes. For - symbolic links, the length in bytes of the pathname - contained in the symbolic link. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_atim - - Last data access timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_mtim - - Last data modification timestamp. - -- [\_\_wasi\_timestamp\_t](#timestamp) st\_ctim - - Last file status change timestamp. - -### `__wasi_filetype_t` (`uint8_t`) - -The type of a file descriptor or file. - -Used by [`__wasi_dirent_t`](#dirent), [`__wasi_fdstat_t`](#fdstat), and [`__wasi_filestat_t`](#filestat). - -Possible values: - -- **`__WASI_FILETYPE_UNKNOWN`** - - The type of the file descriptor or file is unknown or - is different from any of the other types specified. - -- **`__WASI_FILETYPE_BLOCK_DEVICE`** - - The file descriptor or file refers to a block device - inode. - -- **`__WASI_FILETYPE_CHARACTER_DEVICE`** - - The file descriptor or file refers to a character - device inode. - -- **`__WASI_FILETYPE_DIRECTORY`** - - The file descriptor or file refers to a directory - inode. - -- **`__WASI_FILETYPE_REGULAR_FILE`** - - The file descriptor or file refers to a regular file - inode. - -- **`__WASI_FILETYPE_SOCKET_DGRAM`** - - The file descriptor or file refers to a datagram - socket. - -- **`__WASI_FILETYPE_SOCKET_STREAM`** - - The file descriptor or file refers to a byte-stream - socket. - -- **`__WASI_FILETYPE_SYMBOLIC_LINK`** - - The file refers to a symbolic link inode. - -### `__wasi_fstflags_t` (`uint16_t` bitfield) - -Which file time attributes to adjust. - -Used by [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times) and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -Possible values: - -- **`__WASI_FILESTAT_SET_ATIM`** - - Adjust the last data access timestamp to the value - stored in [`__wasi_filestat_t::st_atim`](#filestat.st_atim). - -- **`__WASI_FILESTAT_SET_ATIM_NOW`** - - Adjust the last data access timestamp to the time - of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -- **`__WASI_FILESTAT_SET_MTIM`** - - Adjust the last data modification timestamp to the - value stored in [`__wasi_filestat_t::st_mtim`](#filestat.st_mtim). - -- **`__WASI_FILESTAT_SET_MTIM_NOW`** - - Adjust the last data modification timestamp to the - time of clock [`__WASI_CLOCK_REALTIME`](#clockid.realtime). - -### `__wasi_inode_t` (`uint64_t`) - -File serial number that is unique within its file system. - -Used by [`__wasi_dirent_t`](#dirent) and [`__wasi_filestat_t`](#filestat). - -### `__wasi_iovec_t` (`struct`) - -A region of memory for scatter/gather reads. - -Used by [`__wasi_fd_pread()`](#fd_pread), [`__wasi_fd_read()`](#fd_read), and [`__wasi_sock_recv()`](#sock_recv). - -Members: - -- void \*buf and size\_t buf\_len - - The address and length of the buffer to be filled. - -### `__wasi_linkcount_t` (`uint64_t`) - -Number of hard links to an inode. - -Used by [`__wasi_filestat_t`](#filestat). - -### `__wasi_lookupflags_t` (`uint32_t` bitfield) - -Flags determining the method of how paths are resolved. - -Used by [`__wasi_path_filestat_get()`](#path_filestat_get), [`__wasi_path_filestat_set_times()`](#path_filestat_set_times), [`__wasi_path_link()`](#path_link), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_LOOKUP_SYMLINK_FOLLOW`** - - As long as the resolved path corresponds to a symbolic - link, it is expanded. - -### `__wasi_oflags_t` (`uint16_t` bitfield) - -Open flags used by [`__wasi_path_open()`](#path_open). - -Used by [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_O_CREAT`** - - Create file if it does not exist. - -- **`__WASI_O_DIRECTORY`** - - Fail if not a directory. - -- **`__WASI_O_EXCL`** - - Fail if file already exists. - -- **`__WASI_O_TRUNC`** - - Truncate file to size 0. - -### `__wasi_riflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_PEEK`** - - Returns the message without removing it from the - socket's receive queue. - -- **`__WASI_SOCK_RECV_WAITALL`** - - On byte-stream sockets, block until the full amount - of data can be returned. - -### `__wasi_rights_t` (`uint64_t` bitfield) - -File descriptor rights, determining which actions may be -performed. - -Used by [`__wasi_fdstat_t`](#fdstat), [`__wasi_fd_fdstat_set_rights()`](#fd_fdstat_set_rights), and [`__wasi_path_open()`](#path_open). - -Possible values: - -- **`__WASI_RIGHT_FD_DATASYNC`** - - The right to invoke [`__wasi_fd_datasync()`](#fd_datasync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_READ`** - - The right to invoke [`__wasi_fd_read()`](#fd_read) and [`__wasi_sock_recv()`](#sock_recv). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to invoke - [`__wasi_fd_pread()`](#fd_pread). - -- **`__WASI_RIGHT_FD_SEEK`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek). This flag implies - [`__WASI_RIGHT_FD_TELL`](#rights.fd_tell). - -- **`__WASI_RIGHT_FD_FDSTAT_SET_FLAGS`** - - The right to invoke [`__wasi_fd_fdstat_set_flags()`](#fd_fdstat_set_flags). - -- **`__WASI_RIGHT_FD_SYNC`** - - The right to invoke [`__wasi_fd_sync()`](#fd_sync). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_FDFLAG_RSYNC`](#fdflags.rsync) and - [`__WASI_FDFLAG_DSYNC`](#fdflags.dsync). - -- **`__WASI_RIGHT_FD_TELL`** - - The right to invoke [`__wasi_fd_seek()`](#fd_seek) in such a way that the - file offset remains unaltered (i.e., [`__WASI_WHENCE_CUR`](#whence.cur) with - offset zero), or to invoke [`__wasi_fd_tell()`](#fd_tell). - -- **`__WASI_RIGHT_FD_WRITE`** - - The right to invoke [`__wasi_fd_write()`](#fd_write) and [`__wasi_sock_send()`](#sock_send). - - If [`__WASI_RIGHT_FD_SEEK`](#rights.fd_seek) is set, includes the right to - invoke [`__wasi_fd_pwrite()`](#fd_pwrite). - -- **`__WASI_RIGHT_FD_ADVISE`** - - The right to invoke [`__wasi_fd_advise()`](#fd_advise). - -- **`__WASI_RIGHT_FD_ALLOCATE`** - - The right to invoke [`__wasi_fd_allocate()`](#fd_allocate). - -- **`__WASI_RIGHT_PATH_CREATE_DIRECTORY`** - - The right to invoke [`__wasi_path_create_directory()`](#path_create_directory). - -- **`__WASI_RIGHT_PATH_CREATE_FILE`** - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, the right to invoke - [`__wasi_path_open()`](#path_open) with [`__WASI_O_CREAT`](#oflags.creat). - -- **`__WASI_RIGHT_PATH_LINK_SOURCE`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_LINK_TARGET`** - - The right to invoke [`__wasi_path_link()`](#path_link) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_OPEN`** - - The right to invoke [`__wasi_path_open()`](#path_open). - -- **`__WASI_RIGHT_FD_READDIR`** - - The right to invoke [`__wasi_fd_readdir()`](#fd_readdir). - -- **`__WASI_RIGHT_PATH_READLINK`** - - The right to invoke [`__wasi_path_readlink()`](#path_readlink). - -- **`__WASI_RIGHT_PATH_RENAME_SOURCE`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the source directory. - -- **`__WASI_RIGHT_PATH_RENAME_TARGET`** - - The right to invoke [`__wasi_path_rename()`](#path_rename) with the file - descriptor as the target directory. - -- **`__WASI_RIGHT_PATH_FILESTAT_GET`** - - The right to invoke [`__wasi_path_filestat_get()`](#path_filestat_get). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_SIZE`** - - The right to change a file's size (there is no `__wasi_path_filestat_set_size()`). - - If [`__WASI_RIGHT_PATH_OPEN`](#rights.path_open) is set, includes the right to - invoke [`__wasi_path_open()`](#path_open) with [`__WASI_O_TRUNC`](#oflags.trunc). - -- **`__WASI_RIGHT_PATH_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -- **`__WASI_RIGHT_FD_FILESTAT_GET`** - - The right to invoke [`__wasi_fd_filestat_get()`](#fd_filestat_get). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_SIZE`** - - The right to invoke [`__wasi_fd_filestat_set_size()`](#fd_filestat_set_size). - -- **`__WASI_RIGHT_FD_FILESTAT_SET_TIMES`** - - The right to invoke [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times). - -- **`__WASI_RIGHT_PATH_SYMLINK`** - - The right to invoke [`__wasi_path_symlink()`](#path_symlink). - -- **`__WASI_RIGHT_PATH_REMOVE_DIRECTORY`** - - The right to invoke [`__wasi_path_remove_directory()`](#path_remove_directory). - -- **`__WASI_RIGHT_PATH_UNLINK_FILE`** - - The right to invoke [`__wasi_path_unlink_file()`](#path_unlink_file). - -- **`__WASI_RIGHT_POLL_FD_READWRITE`** - - If [`__WASI_RIGHT_FD_READ`](#rights.fd_read) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read). - - If [`__WASI_RIGHT_FD_WRITE`](#rights.fd_write) is set, includes the right to - invoke [`__wasi_poll_oneoff()`](#poll_oneoff) to subscribe to [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write). - -- **`__WASI_RIGHT_SOCK_SHUTDOWN`** - - The right to invoke [`__wasi_sock_shutdown()`](#sock_shutdown). - -### `__wasi_roflags_t` (`uint16_t` bitfield) - -Flags returned by [`__wasi_sock_recv()`](#sock_recv). - -Used by [`__wasi_sock_recv()`](#sock_recv). - -Possible values: - -- **`__WASI_SOCK_RECV_DATA_TRUNCATED`** - - Returned by [`__wasi_sock_recv()`](#sock_recv): Message data has been - truncated. - -### `__wasi_sdflags_t` (`uint8_t` bitfield) - -Which channels on a socket to shut down. - -Used by [`__wasi_sock_shutdown()`](#sock_shutdown). - -Possible values: - -- **`__WASI_SHUT_RD`** - - Disables further receive operations. - -- **`__WASI_SHUT_WR`** - - Disables further send operations. - -### `__wasi_siflags_t` (`uint16_t` bitfield) - -Flags provided to [`__wasi_sock_send()`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Used by [`__wasi_sock_send()`](#sock_send). - -### `__wasi_signal_t` (`uint8_t`) - -Signal condition. - -Used by [`__wasi_proc_raise()`](#proc_raise). - -Possible values: - -- **`__WASI_SIGHUP`** - - Hangup. - - Action: Terminates the process. - -- **`__WASI_SIGINT`** - - Terminate interrupt signal. - - Action: Terminates the process. - -- **`__WASI_SIGQUIT`** - - Terminal quit signal. - - Action: Terminates the process. - -- **`__WASI_SIGILL`** - - Illegal instruction. - - Action: Terminates the process. - -- **`__WASI_SIGTRAP`** - - Trace/breakpoint trap. - - Action: Terminates the process. - -- **`__WASI_SIGABRT`** - - Process abort signal. - - Action: Terminates the process. - -- **`__WASI_SIGBUS`** - - Access to an undefined portion of a memory object. - - Action: Terminates the process. - -- **`__WASI_SIGFPE`** - - Erroneous arithmetic operation. - - Action: Terminates the process. - -- **`__WASI_SIGKILL`** - - Kill. - - Action: Terminates the process. - -- **`__WASI_SIGUSR1`** - - User-defined signal 1. - - Action: Terminates the process. - -- **`__WASI_SIGSEGV`** - - Invalid memory reference. - - Action: Terminates the process. - -- **`__WASI_SIGUSR2`** - - User-defined signal 2. - - Action: Terminates the process. - -- **`__WASI_SIGPIPE`** - - Write on a pipe with no one to read it. - - Action: Ignored. - -- **`__WASI_SIGALRM`** - - Alarm clock. - - Action: Terminates the process. - -- **`__WASI_SIGTERM`** - - Termination signal. - - Action: Terminates the process. - -- **`__WASI_SIGCHLD`** - - Child process terminated, stopped, or continued. - - Action: Ignored. - -- **`__WASI_SIGCONT`** - - Continue executing, if stopped. - - Action: Continues executing, if stopped. - -- **`__WASI_SIGSTOP`** - - Stop executing. - - Action: Stops executing. - -- **`__WASI_SIGTSTP`** - - Terminal stop signal. - - Action: Stops executing. - -- **`__WASI_SIGTTIN`** - - Background process attempting read. - - Action: Stops executing. - -- **`__WASI_SIGTTOU`** - - Background process attempting write. - - Action: Stops executing. - -- **`__WASI_SIGURG`** - - High bandwidth data is available at a socket. - - Action: Ignored. - -- **`__WASI_SIGXCPU`** - - CPU time limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGXFSZ`** - - File size limit exceeded. - - Action: Terminates the process. - -- **`__WASI_SIGVTALRM`** - - Virtual timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGPROF`** - - Profiling timer expired. - - Action: Terminates the process. - -- **`__WASI_SIGWINCH`** - - Window changed. - - Action: Ignored. - -- **`__WASI_SIGPOLL`** - - I/O possible. - - Action: Terminates the process. - -- **`__WASI_SIGPWR`** - - Power failure. - - Action: Terminates the process. - -- **`__WASI_SIGSYS`** - - Bad system call. - - Action: Terminates the process. - -### `__wasi_subclockflags_t` (`uint16_t` bitfield) - -Flags determining how to interpret the timestamp provided in -[`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout). - -Used by [`__wasi_subscription_t`](#subscription). - -Possible values: - -- **`__WASI_SUBSCRIPTION_CLOCK_ABSTIME`** - - If set, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) as an absolute timestamp - of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - - If clear, treat the timestamp provided in - [`__wasi_subscription_t::u.clock.timeout`](#subscription.u.clock.timeout) relative to the current - time value of clock [`__wasi_subscription_t::u.clock.clock_id`](#subscription.u.clock.clock_id). - -### `__wasi_subscription_t` (`struct`) - -Subscription to an event. - -Used by [`__wasi_poll_oneoff()`](#poll_oneoff). - -Members: - -- [\_\_wasi\_userdata\_t](#userdata) userdata - - User-provided value that is attached to the subscription in the - implementation and returned through - [`__wasi_event_t::userdata`](#event.userdata). - -- [\_\_wasi\_eventtype\_t](#eventtype) type - - The type of the event to which to subscribe. - -- When `type` is [`__WASI_EVENTTYPE_CLOCK`](#eventtype.u.clock): - - - **`u.clock`** - - - [\_\_wasi\_clockid\_t](#clockid) id - - The clock against which to compare the timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) timeout - - The absolute or relative timestamp. - - - [\_\_wasi\_timestamp\_t](#timestamp) precision - - The amount of time that the implementation may wait additionally - to coalesce with other events. - - - [\_\_wasi\_subclockflags\_t](#subclockflags) flags - - Flags specifying whether the timeout is absolute or relative. - -- When `type` is [`__WASI_EVENTTYPE_FD_READ`](#eventtype.fd_read) or [`__WASI_EVENTTYPE_FD_WRITE`](#eventtype.fd_write): - - - **`u.fd_readwrite`** - - - [\_\_wasi\_fd\_t](#fd) fd - - The file descriptor on which to wait for it to become ready - for reading or writing. - -### `__wasi_timestamp_t` (`uint64_t`) - -Timestamp in nanoseconds. - -Used by [`__wasi_filestat_t`](#filestat), [`__wasi_subscription_t`](#subscription), [`__wasi_clock_res_get()`](#clock_res_get), [`__wasi_clock_time_get()`](#clock_time_get), [`__wasi_fd_filestat_set_times()`](#fd_filestat_set_times), and [`__wasi_path_filestat_set_times()`](#path_filestat_set_times). - -### `__wasi_userdata_t` (`uint64_t`) - -User-provided value that may be attached to objects that is -retained when extracted from the implementation. - -Used by [`__wasi_event_t`](#event) and [`__wasi_subscription_t`](#subscription). - -### `__wasi_whence_t` (`uint8_t`) - -The position relative to which to set the offset of the file descriptor. - -Used by [`__wasi_fd_seek()`](#fd_seek). - -Possible values: - -- **`__WASI_WHENCE_SET`** - - Seek relative to start-of-file. - -- **`__WASI_WHENCE_CUR`** - - Seek relative to current position. - -- **`__WASI_WHENCE_END`** - - Seek relative to end-of-file. From 0cd00f51b5bf1d9e47d597510dfd3120a0e3243d Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 14:39:27 -0800 Subject: [PATCH 0502/1772] witx docs test: convert line endings to unix --- proposals/clocks/tools/witx/tests/wasi.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/proposals/clocks/tools/witx/tests/wasi.rs b/proposals/clocks/tools/witx/tests/wasi.rs index 8b03007de..92c96782b 100644 --- a/proposals/clocks/tools/witx/tests/wasi.rs +++ b/proposals/clocks/tools/witx/tests/wasi.rs @@ -78,9 +78,22 @@ fn document_wasi_snapshot() { ); } +fn dos2unix(s: &str) -> String { + let mut t = String::new(); + t.reserve(s.len()); + for c in s.chars() { + if c != '\r' { + t.push(c) + } + } + t +} + fn diff_against_filesystem(expected: &str, path: &Path) { let actual = fs::read_to_string(path).unwrap_or_else(|e| panic!("couldn't read {:?}: {:?}", path, e)); + // Git may checkout the file with dos line endings on windows. Strip all \r: + let actual = dos2unix(&actual); if &actual == expected { return; } From 7fbf1d9c91e966a187b4b43d49f948780d433325 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 14:39:27 -0800 Subject: [PATCH 0503/1772] witx docs test: convert line endings to unix --- proposals/random/tools/witx/tests/wasi.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/proposals/random/tools/witx/tests/wasi.rs b/proposals/random/tools/witx/tests/wasi.rs index 8b03007de..92c96782b 100644 --- a/proposals/random/tools/witx/tests/wasi.rs +++ b/proposals/random/tools/witx/tests/wasi.rs @@ -78,9 +78,22 @@ fn document_wasi_snapshot() { ); } +fn dos2unix(s: &str) -> String { + let mut t = String::new(); + t.reserve(s.len()); + for c in s.chars() { + if c != '\r' { + t.push(c) + } + } + t +} + fn diff_against_filesystem(expected: &str, path: &Path) { let actual = fs::read_to_string(path).unwrap_or_else(|e| panic!("couldn't read {:?}: {:?}", path, e)); + // Git may checkout the file with dos line endings on windows. Strip all \r: + let actual = dos2unix(&actual); if &actual == expected { return; } From d626a83bf84d9efd17304c19f9195dfab0c61f01 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 14:39:27 -0800 Subject: [PATCH 0504/1772] witx docs test: convert line endings to unix --- proposals/filesystem/tools/witx/tests/wasi.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/proposals/filesystem/tools/witx/tests/wasi.rs b/proposals/filesystem/tools/witx/tests/wasi.rs index 8b03007de..92c96782b 100644 --- a/proposals/filesystem/tools/witx/tests/wasi.rs +++ b/proposals/filesystem/tools/witx/tests/wasi.rs @@ -78,9 +78,22 @@ fn document_wasi_snapshot() { ); } +fn dos2unix(s: &str) -> String { + let mut t = String::new(); + t.reserve(s.len()); + for c in s.chars() { + if c != '\r' { + t.push(c) + } + } + t +} + fn diff_against_filesystem(expected: &str, path: &Path) { let actual = fs::read_to_string(path).unwrap_or_else(|e| panic!("couldn't read {:?}: {:?}", path, e)); + // Git may checkout the file with dos line endings on windows. Strip all \r: + let actual = dos2unix(&actual); if &actual == expected { return; } From 12314f78c6af4f8bd4f13072c8866712b6631df0 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 14:43:26 -0800 Subject: [PATCH 0505/1772] update docs with merge from master --- proposals/clocks/phases/snapshot/docs.md | 47 ++++++++++++------------ 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index 0688fe7cb..09575008e 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -272,7 +272,7 @@ File descriptor rights, determining which actions may be performed. - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). If [`path_open`](#path_open) is set, includes the right to invoke -[`path_open`](#path_open) with `fdflag::dsync`. +[`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). - `fd_read` The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). @@ -287,11 +287,11 @@ The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). - `fd_sync` The right to invoke [`fd_sync`](#fd_sync). If [`path_open`](#path_open) is set, includes the right to invoke -[`path_open`](#path_open) with `fdflag::rsync` and `fdflag::dsync`. +[`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - `fd_tell` The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset -remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke [`fd_tell`](#fd_tell). - `fd_write` @@ -535,16 +535,16 @@ Which file time attributes to adjust. ### Flags - `atim` -Adjust the last data access timestamp to the value stored in `filestat::st_atim`. +Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - `atim_now` -Adjust the last data access timestamp to the time of clock `clock::realtime`. +Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - `mtim` -Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. +Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - `mtim_now` -Adjust the last data modification timestamp to the time of clock `clock::realtime`. +Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. @@ -609,15 +609,15 @@ Type of a subscription to an event or its occurrence. ### Variants - `clock` -The time value of clock `subscription::u.clock.clock_id` has -reached timestamp `subscription::u.clock.timeout`. +The time value of clock [`subscription_clock::id`](#subscription_clock.id) has +reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - `fd_read` -File descriptor `subscription::u.fd_readwrite.fd` has data +File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has data available for reading. This event always triggers for regular files. - `fd_write` -File descriptor `subscription::u.fd_readwrite.fd` has capacity +File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. ## `eventrwflags`: Flags(`u16`) @@ -664,15 +664,15 @@ The contents of the event. ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in -`subscription::u.clock.timeout.` +[`subscription_clock::timeout`](#subscription_clock.timeout). ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in -`subscription::u.clock.timeout` as an absolute timestamp of clock -`subscription::u.clock.clock_id.` If clear, treat the timestamp -provided in `subscription::u.clock.timeout` relative to the -current time value of clock `subscription::u.clock.clock_id.` +[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock +[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp +provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the +current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). @@ -926,7 +926,7 @@ The contents of the information. #### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` Read command-line argument data. -The size of the array should match that returned by `wasi_args_sizes_get()` +The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) ##### Params - `argv`: `Pointer>` @@ -957,7 +957,7 @@ The size of the argument string data. #### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` Read environment variable data. -The sizes of the buffers should match that returned by `environ.sizes_get()`. +The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). ##### Params - `environ`: `Pointer>` @@ -988,7 +988,8 @@ The size of the argument string data. #### `clock_res_get(id: clockid) -> (errno, timestamp)` Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, +return [`errno::inval`](#errno.inval). Note: This is similar to `clock_getres` in POSIX. ##### Params @@ -1125,7 +1126,7 @@ The desired values of the file descriptor flags. #### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights +This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights ##### Params - `fd`: [`fd`](#fd) @@ -1520,7 +1521,7 @@ Flags determining the method of how the path is resolved. - `path`: `string` The relative path of the file or directory to open, relative to the -`dirfd` directory. +[`path_open::fd`](#path_open.fd) directory. - `oflags`: [`oflags`](#oflags) The method by which to open the file. @@ -1573,7 +1574,7 @@ The number of bytes placed in the buffer. #### `path_remove_directory(fd: fd, path: string) -> errno` Remove a directory. -Return `ENOTEMPTY` if the directory is not empty. +Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. ##### Params @@ -1631,7 +1632,7 @@ The destination path at which to create the symbolic link. #### `path_unlink_file(fd: fd, path: string) -> errno` Unlink a file. -Return `EISDIR` if the path refers to a directory. +Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. ##### Params From ca2315dde1035d218191a86f84ef15cc427c93cb Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 14:43:26 -0800 Subject: [PATCH 0506/1772] update docs with merge from master --- proposals/random/phases/snapshot/docs.md | 47 ++++++++++++------------ 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index 0688fe7cb..09575008e 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -272,7 +272,7 @@ File descriptor rights, determining which actions may be performed. - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). If [`path_open`](#path_open) is set, includes the right to invoke -[`path_open`](#path_open) with `fdflag::dsync`. +[`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). - `fd_read` The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). @@ -287,11 +287,11 @@ The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). - `fd_sync` The right to invoke [`fd_sync`](#fd_sync). If [`path_open`](#path_open) is set, includes the right to invoke -[`path_open`](#path_open) with `fdflag::rsync` and `fdflag::dsync`. +[`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - `fd_tell` The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset -remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke [`fd_tell`](#fd_tell). - `fd_write` @@ -535,16 +535,16 @@ Which file time attributes to adjust. ### Flags - `atim` -Adjust the last data access timestamp to the value stored in `filestat::st_atim`. +Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - `atim_now` -Adjust the last data access timestamp to the time of clock `clock::realtime`. +Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - `mtim` -Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. +Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - `mtim_now` -Adjust the last data modification timestamp to the time of clock `clock::realtime`. +Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. @@ -609,15 +609,15 @@ Type of a subscription to an event or its occurrence. ### Variants - `clock` -The time value of clock `subscription::u.clock.clock_id` has -reached timestamp `subscription::u.clock.timeout`. +The time value of clock [`subscription_clock::id`](#subscription_clock.id) has +reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - `fd_read` -File descriptor `subscription::u.fd_readwrite.fd` has data +File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has data available for reading. This event always triggers for regular files. - `fd_write` -File descriptor `subscription::u.fd_readwrite.fd` has capacity +File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. ## `eventrwflags`: Flags(`u16`) @@ -664,15 +664,15 @@ The contents of the event. ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in -`subscription::u.clock.timeout.` +[`subscription_clock::timeout`](#subscription_clock.timeout). ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in -`subscription::u.clock.timeout` as an absolute timestamp of clock -`subscription::u.clock.clock_id.` If clear, treat the timestamp -provided in `subscription::u.clock.timeout` relative to the -current time value of clock `subscription::u.clock.clock_id.` +[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock +[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp +provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the +current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). @@ -926,7 +926,7 @@ The contents of the information. #### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` Read command-line argument data. -The size of the array should match that returned by `wasi_args_sizes_get()` +The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) ##### Params - `argv`: `Pointer>` @@ -957,7 +957,7 @@ The size of the argument string data. #### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` Read environment variable data. -The sizes of the buffers should match that returned by `environ.sizes_get()`. +The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). ##### Params - `environ`: `Pointer>` @@ -988,7 +988,8 @@ The size of the argument string data. #### `clock_res_get(id: clockid) -> (errno, timestamp)` Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, +return [`errno::inval`](#errno.inval). Note: This is similar to `clock_getres` in POSIX. ##### Params @@ -1125,7 +1126,7 @@ The desired values of the file descriptor flags. #### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights +This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights ##### Params - `fd`: [`fd`](#fd) @@ -1520,7 +1521,7 @@ Flags determining the method of how the path is resolved. - `path`: `string` The relative path of the file or directory to open, relative to the -`dirfd` directory. +[`path_open::fd`](#path_open.fd) directory. - `oflags`: [`oflags`](#oflags) The method by which to open the file. @@ -1573,7 +1574,7 @@ The number of bytes placed in the buffer. #### `path_remove_directory(fd: fd, path: string) -> errno` Remove a directory. -Return `ENOTEMPTY` if the directory is not empty. +Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. ##### Params @@ -1631,7 +1632,7 @@ The destination path at which to create the symbolic link. #### `path_unlink_file(fd: fd, path: string) -> errno` Unlink a file. -Return `EISDIR` if the path refers to a directory. +Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. ##### Params From 980c7397e1a87ef7323fabe5606be53b3531d013 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 14:43:26 -0800 Subject: [PATCH 0507/1772] update docs with merge from master --- proposals/filesystem/phases/snapshot/docs.md | 47 ++++++++++---------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index 0688fe7cb..09575008e 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -272,7 +272,7 @@ File descriptor rights, determining which actions may be performed. - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). If [`path_open`](#path_open) is set, includes the right to invoke -[`path_open`](#path_open) with `fdflag::dsync`. +[`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). - `fd_read` The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). @@ -287,11 +287,11 @@ The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). - `fd_sync` The right to invoke [`fd_sync`](#fd_sync). If [`path_open`](#path_open) is set, includes the right to invoke -[`path_open`](#path_open) with `fdflag::rsync` and `fdflag::dsync`. +[`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - `fd_tell` The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset -remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke [`fd_tell`](#fd_tell). - `fd_write` @@ -535,16 +535,16 @@ Which file time attributes to adjust. ### Flags - `atim` -Adjust the last data access timestamp to the value stored in `filestat::st_atim`. +Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - `atim_now` -Adjust the last data access timestamp to the time of clock `clock::realtime`. +Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - `mtim` -Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. +Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - `mtim_now` -Adjust the last data modification timestamp to the time of clock `clock::realtime`. +Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. @@ -609,15 +609,15 @@ Type of a subscription to an event or its occurrence. ### Variants - `clock` -The time value of clock `subscription::u.clock.clock_id` has -reached timestamp `subscription::u.clock.timeout`. +The time value of clock [`subscription_clock::id`](#subscription_clock.id) has +reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - `fd_read` -File descriptor `subscription::u.fd_readwrite.fd` has data +File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has data available for reading. This event always triggers for regular files. - `fd_write` -File descriptor `subscription::u.fd_readwrite.fd` has capacity +File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. ## `eventrwflags`: Flags(`u16`) @@ -664,15 +664,15 @@ The contents of the event. ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in -`subscription::u.clock.timeout.` +[`subscription_clock::timeout`](#subscription_clock.timeout). ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in -`subscription::u.clock.timeout` as an absolute timestamp of clock -`subscription::u.clock.clock_id.` If clear, treat the timestamp -provided in `subscription::u.clock.timeout` relative to the -current time value of clock `subscription::u.clock.clock_id.` +[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock +[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp +provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the +current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). @@ -926,7 +926,7 @@ The contents of the information. #### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` Read command-line argument data. -The size of the array should match that returned by `wasi_args_sizes_get()` +The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) ##### Params - `argv`: `Pointer>` @@ -957,7 +957,7 @@ The size of the argument string data. #### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` Read environment variable data. -The sizes of the buffers should match that returned by `environ.sizes_get()`. +The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). ##### Params - `environ`: `Pointer>` @@ -988,7 +988,8 @@ The size of the argument string data. #### `clock_res_get(id: clockid) -> (errno, timestamp)` Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, +return [`errno::inval`](#errno.inval). Note: This is similar to `clock_getres` in POSIX. ##### Params @@ -1125,7 +1126,7 @@ The desired values of the file descriptor flags. #### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights +This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights ##### Params - `fd`: [`fd`](#fd) @@ -1520,7 +1521,7 @@ Flags determining the method of how the path is resolved. - `path`: `string` The relative path of the file or directory to open, relative to the -`dirfd` directory. +[`path_open::fd`](#path_open.fd) directory. - `oflags`: [`oflags`](#oflags) The method by which to open the file. @@ -1573,7 +1574,7 @@ The number of bytes placed in the buffer. #### `path_remove_directory(fd: fd, path: string) -> errno` Remove a directory. -Return `ENOTEMPTY` if the directory is not empty. +Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. ##### Params @@ -1631,7 +1632,7 @@ The destination path at which to create the symbolic link. #### `path_unlink_file(fd: fd, path: string) -> errno` Unlink a file. -Return `EISDIR` if the path refers to a directory. +Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. ##### Params From bace7b731e5ed7e210846c6dadd868f542458b1d Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 15:18:48 -0800 Subject: [PATCH 0508/1772] review feedback --- proposals/clocks/tools/witx/src/phases.rs | 16 +++++++--------- proposals/clocks/tools/witx/tests/wasi.rs | 4 ++-- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/proposals/clocks/tools/witx/src/phases.rs b/proposals/clocks/tools/witx/src/phases.rs index 6e0f1776e..0bf697e21 100644 --- a/proposals/clocks/tools/witx/src/phases.rs +++ b/proposals/clocks/tools/witx/src/phases.rs @@ -1,6 +1,6 @@ -use anyhow::{anyhow, Result}; +use anyhow::{bail, Result}; use std::env; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; pub fn docs_path(phase_paths: &[PathBuf]) -> PathBuf { phase_paths @@ -58,19 +58,17 @@ fn repo_root() -> Result { if repo_root.exists() { Ok(repo_root) } else { - Err(anyhow!( - "could not find WASI repo root - try setting WASI_REPO env variable" - )) + bail!("could not find WASI repo root - try setting WASI_REPO env variable") } } fn ensure_exists(paths: &[PathBuf]) -> Result<()> { for p in paths.iter() { if !p.exists() { - Err(anyhow!( - "{:?} does not exist - is WASI_REPO set to repository root?", - p - ))?; + bail!( + "{} does not exist - is WASI_REPO set to repository root?", + Path::display(p) + ) } } Ok(()) diff --git a/proposals/clocks/tools/witx/tests/wasi.rs b/proposals/clocks/tools/witx/tests/wasi.rs index 92c96782b..d2fbe807f 100644 --- a/proposals/clocks/tools/witx/tests/wasi.rs +++ b/proposals/clocks/tools/witx/tests/wasi.rs @@ -90,8 +90,8 @@ fn dos2unix(s: &str) -> String { } fn diff_against_filesystem(expected: &str, path: &Path) { - let actual = - fs::read_to_string(path).unwrap_or_else(|e| panic!("couldn't read {:?}: {:?}", path, e)); + let actual = fs::read_to_string(path) + .unwrap_or_else(|e| panic!("couldn't read {}: {:?}", Path::display(path), e)); // Git may checkout the file with dos line endings on windows. Strip all \r: let actual = dos2unix(&actual); if &actual == expected { From 918ac274a9e1e2a07caf9d60ca1efc180af4f8e0 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 15:18:48 -0800 Subject: [PATCH 0509/1772] review feedback --- proposals/random/tools/witx/src/phases.rs | 16 +++++++--------- proposals/random/tools/witx/tests/wasi.rs | 4 ++-- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/proposals/random/tools/witx/src/phases.rs b/proposals/random/tools/witx/src/phases.rs index 6e0f1776e..0bf697e21 100644 --- a/proposals/random/tools/witx/src/phases.rs +++ b/proposals/random/tools/witx/src/phases.rs @@ -1,6 +1,6 @@ -use anyhow::{anyhow, Result}; +use anyhow::{bail, Result}; use std::env; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; pub fn docs_path(phase_paths: &[PathBuf]) -> PathBuf { phase_paths @@ -58,19 +58,17 @@ fn repo_root() -> Result { if repo_root.exists() { Ok(repo_root) } else { - Err(anyhow!( - "could not find WASI repo root - try setting WASI_REPO env variable" - )) + bail!("could not find WASI repo root - try setting WASI_REPO env variable") } } fn ensure_exists(paths: &[PathBuf]) -> Result<()> { for p in paths.iter() { if !p.exists() { - Err(anyhow!( - "{:?} does not exist - is WASI_REPO set to repository root?", - p - ))?; + bail!( + "{} does not exist - is WASI_REPO set to repository root?", + Path::display(p) + ) } } Ok(()) diff --git a/proposals/random/tools/witx/tests/wasi.rs b/proposals/random/tools/witx/tests/wasi.rs index 92c96782b..d2fbe807f 100644 --- a/proposals/random/tools/witx/tests/wasi.rs +++ b/proposals/random/tools/witx/tests/wasi.rs @@ -90,8 +90,8 @@ fn dos2unix(s: &str) -> String { } fn diff_against_filesystem(expected: &str, path: &Path) { - let actual = - fs::read_to_string(path).unwrap_or_else(|e| panic!("couldn't read {:?}: {:?}", path, e)); + let actual = fs::read_to_string(path) + .unwrap_or_else(|e| panic!("couldn't read {}: {:?}", Path::display(path), e)); // Git may checkout the file with dos line endings on windows. Strip all \r: let actual = dos2unix(&actual); if &actual == expected { From 5e171a7e2bdb0fff8193f07e85442c0d93c242ea Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 15 Jan 2020 15:18:48 -0800 Subject: [PATCH 0510/1772] review feedback --- proposals/filesystem/tools/witx/src/phases.rs | 16 +++++++--------- proposals/filesystem/tools/witx/tests/wasi.rs | 4 ++-- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/phases.rs b/proposals/filesystem/tools/witx/src/phases.rs index 6e0f1776e..0bf697e21 100644 --- a/proposals/filesystem/tools/witx/src/phases.rs +++ b/proposals/filesystem/tools/witx/src/phases.rs @@ -1,6 +1,6 @@ -use anyhow::{anyhow, Result}; +use anyhow::{bail, Result}; use std::env; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; pub fn docs_path(phase_paths: &[PathBuf]) -> PathBuf { phase_paths @@ -58,19 +58,17 @@ fn repo_root() -> Result { if repo_root.exists() { Ok(repo_root) } else { - Err(anyhow!( - "could not find WASI repo root - try setting WASI_REPO env variable" - )) + bail!("could not find WASI repo root - try setting WASI_REPO env variable") } } fn ensure_exists(paths: &[PathBuf]) -> Result<()> { for p in paths.iter() { if !p.exists() { - Err(anyhow!( - "{:?} does not exist - is WASI_REPO set to repository root?", - p - ))?; + bail!( + "{} does not exist - is WASI_REPO set to repository root?", + Path::display(p) + ) } } Ok(()) diff --git a/proposals/filesystem/tools/witx/tests/wasi.rs b/proposals/filesystem/tools/witx/tests/wasi.rs index 92c96782b..d2fbe807f 100644 --- a/proposals/filesystem/tools/witx/tests/wasi.rs +++ b/proposals/filesystem/tools/witx/tests/wasi.rs @@ -90,8 +90,8 @@ fn dos2unix(s: &str) -> String { } fn diff_against_filesystem(expected: &str, path: &Path) { - let actual = - fs::read_to_string(path).unwrap_or_else(|e| panic!("couldn't read {:?}: {:?}", path, e)); + let actual = fs::read_to_string(path) + .unwrap_or_else(|e| panic!("couldn't read {}: {:?}", Path::display(path), e)); // Git may checkout the file with dos line endings on windows. Strip all \r: let actual = dos2unix(&actual); if &actual == expected { From ce92ab26bb60c5f5e7633d13319dba63557286dd Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 16 Jan 2020 21:42:50 +0100 Subject: [PATCH 0511/1772] Replace clap with structopt (#205) * Replace clap with structopt IMHO, `structopt` generally makes things somewhat cleaner and is worth moving `witx` to `structopt` from `clap` for added readability and extendability of the tool in the future. * Fix formatting in main.rs --- proposals/clocks/tools/witx/Cargo.toml | 2 +- proposals/clocks/tools/witx/src/main.rs | 272 +++++++++++++----------- 2 files changed, 149 insertions(+), 125 deletions(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index d9ee8d858..959c22143 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -18,7 +18,7 @@ name = "witx" path = "src/main.rs" [dependencies] -clap = "2" +structopt = "0.3" wast = "3.0.4" thiserror = "1.0" log = "0.4" diff --git a/proposals/clocks/tools/witx/src/main.rs b/proposals/clocks/tools/witx/src/main.rs index 16d9d474f..f86140ab8 100644 --- a/proposals/clocks/tools/witx/src/main.rs +++ b/proposals/clocks/tools/witx/src/main.rs @@ -1,127 +1,146 @@ -use clap::{App, Arg, ArgMatches, SubCommand}; -use std::collections::HashMap; +use anyhow::{anyhow, bail, Result}; use std::fs::File; use std::io::Write; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::process; +use structopt::{clap::AppSettings, StructOpt}; use witx::{load, phases, Document, Documentation}; +/// Validate and process witx files +#[derive(StructOpt, Debug)] +#[structopt( + name = "witx", + version = env!("CARGO_PKG_VERSION"), + global_settings = &[ + AppSettings::VersionlessSubcommands, + AppSettings::ColoredHelp + ] +)] +struct Args { + #[structopt(short = "v", long = "verbose")] + verbose: bool, + + #[structopt(subcommand)] + cmd: Command, +} + +#[derive(StructOpt, Debug)] +enum Command { + /// Output documentation + Docs { + /// Path to root of witx document + #[structopt(number_of_values = 1, value_name = "INPUT", parse(from_os_str))] + input: Vec, + /// Path to generated documentation in Markdown format + #[structopt( + short = "o", + long = "output", + value_name = "OUTPUT", + parse(from_os_str) + )] + output: Option, + }, + /// Update documentation in WASI repository to reflect witx specs + RepoDocs, + /// Examine differences between interfaces + Polyfill { + /// Path to root of witx document + #[structopt( + required = true, + number_of_values = 1, + value_name = "INPUT", + parse(from_os_str) + )] + input: Vec, + /// Path to root of witx document describing interface to polyfill + #[structopt( + required = true, + number_of_values = 1, + value_name = "OLDER_INTERFACE", + parse(from_os_str) + )] + older_interface: Vec, + /// Module to examine (use newname=oldname syntax if name is different + /// between new and old interfaces) + #[structopt( + short = "m", + long = "module_mapping", + required = true, + number_of_values = 1, + value_name = "NEWNAME=OLDNAME", + parse(try_from_str = parse_module_mapping) + )] + module_mapping: Vec<(String, String)>, + }, +} + pub fn main() { - let app = App::new("witx") - .version(env!("CARGO_PKG_VERSION")) - .about("Validate and process witx files") - .arg( - Arg::with_name("verbose") - .short("v") - .long("verbose") - .takes_value(false) - .required(false), - ) - .subcommand( - SubCommand::with_name("docs") - .about("Output documentation") - .arg( - Arg::with_name("input") - .required(true) - .multiple(true) - .help("path to root of witx document"), - ) - .arg( - Arg::with_name("output") - .short("o") - .long("output") - .takes_value(true) - .required(false), - ), - ) - .subcommand( - SubCommand::with_name("polyfill") - .about("Examine differences between interfaces") - .arg( - Arg::with_name("input") - .required(true) - .multiple(true) - .help("path to root of witx document"), - ) - .arg( - Arg::with_name("older_interface") - .required(true) - .multiple(true) - .help("path to root of witx document describing interface to polyfill"), - ) - .arg( - Arg::with_name("module_mapping") - .short("m") - .long("module_mapping") - .required(false) - .takes_value(true) - .multiple(true) - .help("module to examine. Use newname=oldname syntax if name is different between new and old interfaces"), - ), - ) - .subcommand( - SubCommand::with_name("repo-docs") - .about("Update documentation in WASI repository to reflect witx specs") - ) - .get_matches(); + let args = Args::from_args(); + pretty_env_logger::init(); + let verbose = args.verbose; - let load_witx = { - |args: &ArgMatches, field: &str| -> Document { - let inputs = args - .values_of(field) - .expect(&format!("required argument: {}", field)) - .collect::>(); - match load(&inputs) { - Ok(doc) => { - if app.is_present("verbose") { - println!("{}: {:?}", field, doc) - } - doc - } + match args.cmd { + Command::Docs { input, output } => { + let doc = load_witx(&input, "input", verbose); + if let Some(output) = output { + write_docs(&doc, output) + } else { + println!("{}", doc.to_md()) + } + } + Command::RepoDocs => { + for phase in &[ + phases::snapshot().unwrap(), + phases::ephemeral().unwrap(), + phases::old::snapshot_0().unwrap(), + ] { + let doc = load(&phase).expect("parse phase"); + write_docs(&doc, phases::docs_path(&phase)); + } + } + Command::Polyfill { + input, + older_interface, + module_mapping, + } => { + use std::{collections::HashMap, iter::FromIterator}; + use witx::polyfill::Polyfill; + + let doc = load_witx(&input, "input", verbose); + let older_doc = load_witx(&older_interface, "older_interface", verbose); + let module_mapping = HashMap::from_iter(module_mapping.into_iter()); + let polyfill = match Polyfill::new(&doc, &older_doc, &module_mapping) { + Ok(polyfill) => polyfill, Err(e) => { - println!("{}", e.report()); - if app.is_present("verbose") { + eprintln!("couldn't calculate polyfill"); + if verbose { println!("{:?}", e); } - process::exit(1) + process::exit(1); } + }; + println!("{}", polyfill.to_md()); + if verbose { + println!("{:?}", polyfill); } } - }; - - pretty_env_logger::init(); - - if let Some(docs_args) = app.subcommand_matches("docs") { - let doc = load_witx(&docs_args, "input"); - if let Some(output) = docs_args.value_of("output") { - write_docs(&doc, output) - } else { - println!("{}", doc.to_md()) - } - } else if let Some(polyfill_args) = app.subcommand_matches("polyfill") { - let doc = load_witx(&polyfill_args, "input"); - let older_doc = load_witx(&polyfill_args, "older_interface"); - - let module_mapping_args = polyfill_args - .values_of("module_mapping") - .expect("at least one module_mapping argument required") - .collect::>(); - let module_mapping = parse_module_mapping(&module_mapping_args); + } +} - let polyfill = witx::polyfill::Polyfill::new(&doc, &older_doc, &module_mapping) - .expect("calculate polyfill"); - println!("{}", polyfill.to_md()); - if app.is_present("verbose") { - println!("{:?}", polyfill); +fn load_witx(input: &[PathBuf], field_name: &str, verbose: bool) -> Document { + match load(input) { + Ok(doc) => { + if verbose { + println!("{}: {:?}", field_name, doc); + } + doc } - } else if app.subcommand_matches("repo-docs").is_some() { - for phase in &[ - phases::snapshot().unwrap(), - phases::ephemeral().unwrap(), - phases::old::snapshot_0().unwrap(), - ] { - let doc = load(&phase).expect("parse phase"); - write_docs(&doc, phases::docs_path(&phase)); + Err(e) => { + eprintln!("{}", e.report()); + if verbose { + println!("{:?}", e); + } + process::exit(1) } } } @@ -132,20 +151,25 @@ fn write_docs>(document: &Document, path: P) { .expect("write output file"); } -fn parse_module_mapping(ms: &[&str]) -> HashMap { - let mut o = HashMap::new(); - for m in ms { - let s = m.split('=').collect::>(); - if s.len() == 1 { - let mname = s.get(0).unwrap(); - o.insert(mname.to_string(), mname.to_string()); - } else if s.len() == 2 { - let newname = s.get(0).unwrap(); - let oldname = s.get(1).unwrap(); - o.insert(newname.to_string(), oldname.to_string()); - } else { - panic!("invalid module mapping: '{}'", m) +fn parse_module_mapping(m: &str) -> Result<(String, String)> { + let s: Vec<_> = m.split('=').collect(); + let (n, o) = match s.len() { + 1 => { + let mname = s + .get(0) + .ok_or(anyhow!("module name cannot be an empty string"))?; + (mname, mname) } - } - o + 2 => { + let newname = s + .get(0) + .ok_or(anyhow!("new module name cannot be an empty string"))?; + let oldname = s + .get(1) + .ok_or(anyhow!("old module name cannot be an empty string"))?; + (newname, oldname) + } + _ => bail!("invalid module mapping: '{}'", m), + }; + Ok((n.to_string(), o.to_string())) } From 4e260048730c6dfa230a349fe7321334a48a5a16 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 16 Jan 2020 21:42:50 +0100 Subject: [PATCH 0512/1772] Replace clap with structopt (#205) * Replace clap with structopt IMHO, `structopt` generally makes things somewhat cleaner and is worth moving `witx` to `structopt` from `clap` for added readability and extendability of the tool in the future. * Fix formatting in main.rs --- proposals/random/tools/witx/Cargo.toml | 2 +- proposals/random/tools/witx/src/main.rs | 272 +++++++++++++----------- 2 files changed, 149 insertions(+), 125 deletions(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index d9ee8d858..959c22143 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -18,7 +18,7 @@ name = "witx" path = "src/main.rs" [dependencies] -clap = "2" +structopt = "0.3" wast = "3.0.4" thiserror = "1.0" log = "0.4" diff --git a/proposals/random/tools/witx/src/main.rs b/proposals/random/tools/witx/src/main.rs index 16d9d474f..f86140ab8 100644 --- a/proposals/random/tools/witx/src/main.rs +++ b/proposals/random/tools/witx/src/main.rs @@ -1,127 +1,146 @@ -use clap::{App, Arg, ArgMatches, SubCommand}; -use std::collections::HashMap; +use anyhow::{anyhow, bail, Result}; use std::fs::File; use std::io::Write; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::process; +use structopt::{clap::AppSettings, StructOpt}; use witx::{load, phases, Document, Documentation}; +/// Validate and process witx files +#[derive(StructOpt, Debug)] +#[structopt( + name = "witx", + version = env!("CARGO_PKG_VERSION"), + global_settings = &[ + AppSettings::VersionlessSubcommands, + AppSettings::ColoredHelp + ] +)] +struct Args { + #[structopt(short = "v", long = "verbose")] + verbose: bool, + + #[structopt(subcommand)] + cmd: Command, +} + +#[derive(StructOpt, Debug)] +enum Command { + /// Output documentation + Docs { + /// Path to root of witx document + #[structopt(number_of_values = 1, value_name = "INPUT", parse(from_os_str))] + input: Vec, + /// Path to generated documentation in Markdown format + #[structopt( + short = "o", + long = "output", + value_name = "OUTPUT", + parse(from_os_str) + )] + output: Option, + }, + /// Update documentation in WASI repository to reflect witx specs + RepoDocs, + /// Examine differences between interfaces + Polyfill { + /// Path to root of witx document + #[structopt( + required = true, + number_of_values = 1, + value_name = "INPUT", + parse(from_os_str) + )] + input: Vec, + /// Path to root of witx document describing interface to polyfill + #[structopt( + required = true, + number_of_values = 1, + value_name = "OLDER_INTERFACE", + parse(from_os_str) + )] + older_interface: Vec, + /// Module to examine (use newname=oldname syntax if name is different + /// between new and old interfaces) + #[structopt( + short = "m", + long = "module_mapping", + required = true, + number_of_values = 1, + value_name = "NEWNAME=OLDNAME", + parse(try_from_str = parse_module_mapping) + )] + module_mapping: Vec<(String, String)>, + }, +} + pub fn main() { - let app = App::new("witx") - .version(env!("CARGO_PKG_VERSION")) - .about("Validate and process witx files") - .arg( - Arg::with_name("verbose") - .short("v") - .long("verbose") - .takes_value(false) - .required(false), - ) - .subcommand( - SubCommand::with_name("docs") - .about("Output documentation") - .arg( - Arg::with_name("input") - .required(true) - .multiple(true) - .help("path to root of witx document"), - ) - .arg( - Arg::with_name("output") - .short("o") - .long("output") - .takes_value(true) - .required(false), - ), - ) - .subcommand( - SubCommand::with_name("polyfill") - .about("Examine differences between interfaces") - .arg( - Arg::with_name("input") - .required(true) - .multiple(true) - .help("path to root of witx document"), - ) - .arg( - Arg::with_name("older_interface") - .required(true) - .multiple(true) - .help("path to root of witx document describing interface to polyfill"), - ) - .arg( - Arg::with_name("module_mapping") - .short("m") - .long("module_mapping") - .required(false) - .takes_value(true) - .multiple(true) - .help("module to examine. Use newname=oldname syntax if name is different between new and old interfaces"), - ), - ) - .subcommand( - SubCommand::with_name("repo-docs") - .about("Update documentation in WASI repository to reflect witx specs") - ) - .get_matches(); + let args = Args::from_args(); + pretty_env_logger::init(); + let verbose = args.verbose; - let load_witx = { - |args: &ArgMatches, field: &str| -> Document { - let inputs = args - .values_of(field) - .expect(&format!("required argument: {}", field)) - .collect::>(); - match load(&inputs) { - Ok(doc) => { - if app.is_present("verbose") { - println!("{}: {:?}", field, doc) - } - doc - } + match args.cmd { + Command::Docs { input, output } => { + let doc = load_witx(&input, "input", verbose); + if let Some(output) = output { + write_docs(&doc, output) + } else { + println!("{}", doc.to_md()) + } + } + Command::RepoDocs => { + for phase in &[ + phases::snapshot().unwrap(), + phases::ephemeral().unwrap(), + phases::old::snapshot_0().unwrap(), + ] { + let doc = load(&phase).expect("parse phase"); + write_docs(&doc, phases::docs_path(&phase)); + } + } + Command::Polyfill { + input, + older_interface, + module_mapping, + } => { + use std::{collections::HashMap, iter::FromIterator}; + use witx::polyfill::Polyfill; + + let doc = load_witx(&input, "input", verbose); + let older_doc = load_witx(&older_interface, "older_interface", verbose); + let module_mapping = HashMap::from_iter(module_mapping.into_iter()); + let polyfill = match Polyfill::new(&doc, &older_doc, &module_mapping) { + Ok(polyfill) => polyfill, Err(e) => { - println!("{}", e.report()); - if app.is_present("verbose") { + eprintln!("couldn't calculate polyfill"); + if verbose { println!("{:?}", e); } - process::exit(1) + process::exit(1); } + }; + println!("{}", polyfill.to_md()); + if verbose { + println!("{:?}", polyfill); } } - }; - - pretty_env_logger::init(); - - if let Some(docs_args) = app.subcommand_matches("docs") { - let doc = load_witx(&docs_args, "input"); - if let Some(output) = docs_args.value_of("output") { - write_docs(&doc, output) - } else { - println!("{}", doc.to_md()) - } - } else if let Some(polyfill_args) = app.subcommand_matches("polyfill") { - let doc = load_witx(&polyfill_args, "input"); - let older_doc = load_witx(&polyfill_args, "older_interface"); - - let module_mapping_args = polyfill_args - .values_of("module_mapping") - .expect("at least one module_mapping argument required") - .collect::>(); - let module_mapping = parse_module_mapping(&module_mapping_args); + } +} - let polyfill = witx::polyfill::Polyfill::new(&doc, &older_doc, &module_mapping) - .expect("calculate polyfill"); - println!("{}", polyfill.to_md()); - if app.is_present("verbose") { - println!("{:?}", polyfill); +fn load_witx(input: &[PathBuf], field_name: &str, verbose: bool) -> Document { + match load(input) { + Ok(doc) => { + if verbose { + println!("{}: {:?}", field_name, doc); + } + doc } - } else if app.subcommand_matches("repo-docs").is_some() { - for phase in &[ - phases::snapshot().unwrap(), - phases::ephemeral().unwrap(), - phases::old::snapshot_0().unwrap(), - ] { - let doc = load(&phase).expect("parse phase"); - write_docs(&doc, phases::docs_path(&phase)); + Err(e) => { + eprintln!("{}", e.report()); + if verbose { + println!("{:?}", e); + } + process::exit(1) } } } @@ -132,20 +151,25 @@ fn write_docs>(document: &Document, path: P) { .expect("write output file"); } -fn parse_module_mapping(ms: &[&str]) -> HashMap { - let mut o = HashMap::new(); - for m in ms { - let s = m.split('=').collect::>(); - if s.len() == 1 { - let mname = s.get(0).unwrap(); - o.insert(mname.to_string(), mname.to_string()); - } else if s.len() == 2 { - let newname = s.get(0).unwrap(); - let oldname = s.get(1).unwrap(); - o.insert(newname.to_string(), oldname.to_string()); - } else { - panic!("invalid module mapping: '{}'", m) +fn parse_module_mapping(m: &str) -> Result<(String, String)> { + let s: Vec<_> = m.split('=').collect(); + let (n, o) = match s.len() { + 1 => { + let mname = s + .get(0) + .ok_or(anyhow!("module name cannot be an empty string"))?; + (mname, mname) } - } - o + 2 => { + let newname = s + .get(0) + .ok_or(anyhow!("new module name cannot be an empty string"))?; + let oldname = s + .get(1) + .ok_or(anyhow!("old module name cannot be an empty string"))?; + (newname, oldname) + } + _ => bail!("invalid module mapping: '{}'", m), + }; + Ok((n.to_string(), o.to_string())) } From 0ffb6719d3cb2e07cd08b054a595aa922bb9fcec Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 16 Jan 2020 21:42:50 +0100 Subject: [PATCH 0513/1772] Replace clap with structopt (#205) * Replace clap with structopt IMHO, `structopt` generally makes things somewhat cleaner and is worth moving `witx` to `structopt` from `clap` for added readability and extendability of the tool in the future. * Fix formatting in main.rs --- proposals/filesystem/tools/witx/Cargo.toml | 2 +- proposals/filesystem/tools/witx/src/main.rs | 272 +++++++++++--------- 2 files changed, 149 insertions(+), 125 deletions(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index d9ee8d858..959c22143 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -18,7 +18,7 @@ name = "witx" path = "src/main.rs" [dependencies] -clap = "2" +structopt = "0.3" wast = "3.0.4" thiserror = "1.0" log = "0.4" diff --git a/proposals/filesystem/tools/witx/src/main.rs b/proposals/filesystem/tools/witx/src/main.rs index 16d9d474f..f86140ab8 100644 --- a/proposals/filesystem/tools/witx/src/main.rs +++ b/proposals/filesystem/tools/witx/src/main.rs @@ -1,127 +1,146 @@ -use clap::{App, Arg, ArgMatches, SubCommand}; -use std::collections::HashMap; +use anyhow::{anyhow, bail, Result}; use std::fs::File; use std::io::Write; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::process; +use structopt::{clap::AppSettings, StructOpt}; use witx::{load, phases, Document, Documentation}; +/// Validate and process witx files +#[derive(StructOpt, Debug)] +#[structopt( + name = "witx", + version = env!("CARGO_PKG_VERSION"), + global_settings = &[ + AppSettings::VersionlessSubcommands, + AppSettings::ColoredHelp + ] +)] +struct Args { + #[structopt(short = "v", long = "verbose")] + verbose: bool, + + #[structopt(subcommand)] + cmd: Command, +} + +#[derive(StructOpt, Debug)] +enum Command { + /// Output documentation + Docs { + /// Path to root of witx document + #[structopt(number_of_values = 1, value_name = "INPUT", parse(from_os_str))] + input: Vec, + /// Path to generated documentation in Markdown format + #[structopt( + short = "o", + long = "output", + value_name = "OUTPUT", + parse(from_os_str) + )] + output: Option, + }, + /// Update documentation in WASI repository to reflect witx specs + RepoDocs, + /// Examine differences between interfaces + Polyfill { + /// Path to root of witx document + #[structopt( + required = true, + number_of_values = 1, + value_name = "INPUT", + parse(from_os_str) + )] + input: Vec, + /// Path to root of witx document describing interface to polyfill + #[structopt( + required = true, + number_of_values = 1, + value_name = "OLDER_INTERFACE", + parse(from_os_str) + )] + older_interface: Vec, + /// Module to examine (use newname=oldname syntax if name is different + /// between new and old interfaces) + #[structopt( + short = "m", + long = "module_mapping", + required = true, + number_of_values = 1, + value_name = "NEWNAME=OLDNAME", + parse(try_from_str = parse_module_mapping) + )] + module_mapping: Vec<(String, String)>, + }, +} + pub fn main() { - let app = App::new("witx") - .version(env!("CARGO_PKG_VERSION")) - .about("Validate and process witx files") - .arg( - Arg::with_name("verbose") - .short("v") - .long("verbose") - .takes_value(false) - .required(false), - ) - .subcommand( - SubCommand::with_name("docs") - .about("Output documentation") - .arg( - Arg::with_name("input") - .required(true) - .multiple(true) - .help("path to root of witx document"), - ) - .arg( - Arg::with_name("output") - .short("o") - .long("output") - .takes_value(true) - .required(false), - ), - ) - .subcommand( - SubCommand::with_name("polyfill") - .about("Examine differences between interfaces") - .arg( - Arg::with_name("input") - .required(true) - .multiple(true) - .help("path to root of witx document"), - ) - .arg( - Arg::with_name("older_interface") - .required(true) - .multiple(true) - .help("path to root of witx document describing interface to polyfill"), - ) - .arg( - Arg::with_name("module_mapping") - .short("m") - .long("module_mapping") - .required(false) - .takes_value(true) - .multiple(true) - .help("module to examine. Use newname=oldname syntax if name is different between new and old interfaces"), - ), - ) - .subcommand( - SubCommand::with_name("repo-docs") - .about("Update documentation in WASI repository to reflect witx specs") - ) - .get_matches(); + let args = Args::from_args(); + pretty_env_logger::init(); + let verbose = args.verbose; - let load_witx = { - |args: &ArgMatches, field: &str| -> Document { - let inputs = args - .values_of(field) - .expect(&format!("required argument: {}", field)) - .collect::>(); - match load(&inputs) { - Ok(doc) => { - if app.is_present("verbose") { - println!("{}: {:?}", field, doc) - } - doc - } + match args.cmd { + Command::Docs { input, output } => { + let doc = load_witx(&input, "input", verbose); + if let Some(output) = output { + write_docs(&doc, output) + } else { + println!("{}", doc.to_md()) + } + } + Command::RepoDocs => { + for phase in &[ + phases::snapshot().unwrap(), + phases::ephemeral().unwrap(), + phases::old::snapshot_0().unwrap(), + ] { + let doc = load(&phase).expect("parse phase"); + write_docs(&doc, phases::docs_path(&phase)); + } + } + Command::Polyfill { + input, + older_interface, + module_mapping, + } => { + use std::{collections::HashMap, iter::FromIterator}; + use witx::polyfill::Polyfill; + + let doc = load_witx(&input, "input", verbose); + let older_doc = load_witx(&older_interface, "older_interface", verbose); + let module_mapping = HashMap::from_iter(module_mapping.into_iter()); + let polyfill = match Polyfill::new(&doc, &older_doc, &module_mapping) { + Ok(polyfill) => polyfill, Err(e) => { - println!("{}", e.report()); - if app.is_present("verbose") { + eprintln!("couldn't calculate polyfill"); + if verbose { println!("{:?}", e); } - process::exit(1) + process::exit(1); } + }; + println!("{}", polyfill.to_md()); + if verbose { + println!("{:?}", polyfill); } } - }; - - pretty_env_logger::init(); - - if let Some(docs_args) = app.subcommand_matches("docs") { - let doc = load_witx(&docs_args, "input"); - if let Some(output) = docs_args.value_of("output") { - write_docs(&doc, output) - } else { - println!("{}", doc.to_md()) - } - } else if let Some(polyfill_args) = app.subcommand_matches("polyfill") { - let doc = load_witx(&polyfill_args, "input"); - let older_doc = load_witx(&polyfill_args, "older_interface"); - - let module_mapping_args = polyfill_args - .values_of("module_mapping") - .expect("at least one module_mapping argument required") - .collect::>(); - let module_mapping = parse_module_mapping(&module_mapping_args); + } +} - let polyfill = witx::polyfill::Polyfill::new(&doc, &older_doc, &module_mapping) - .expect("calculate polyfill"); - println!("{}", polyfill.to_md()); - if app.is_present("verbose") { - println!("{:?}", polyfill); +fn load_witx(input: &[PathBuf], field_name: &str, verbose: bool) -> Document { + match load(input) { + Ok(doc) => { + if verbose { + println!("{}: {:?}", field_name, doc); + } + doc } - } else if app.subcommand_matches("repo-docs").is_some() { - for phase in &[ - phases::snapshot().unwrap(), - phases::ephemeral().unwrap(), - phases::old::snapshot_0().unwrap(), - ] { - let doc = load(&phase).expect("parse phase"); - write_docs(&doc, phases::docs_path(&phase)); + Err(e) => { + eprintln!("{}", e.report()); + if verbose { + println!("{:?}", e); + } + process::exit(1) } } } @@ -132,20 +151,25 @@ fn write_docs>(document: &Document, path: P) { .expect("write output file"); } -fn parse_module_mapping(ms: &[&str]) -> HashMap { - let mut o = HashMap::new(); - for m in ms { - let s = m.split('=').collect::>(); - if s.len() == 1 { - let mname = s.get(0).unwrap(); - o.insert(mname.to_string(), mname.to_string()); - } else if s.len() == 2 { - let newname = s.get(0).unwrap(); - let oldname = s.get(1).unwrap(); - o.insert(newname.to_string(), oldname.to_string()); - } else { - panic!("invalid module mapping: '{}'", m) +fn parse_module_mapping(m: &str) -> Result<(String, String)> { + let s: Vec<_> = m.split('=').collect(); + let (n, o) = match s.len() { + 1 => { + let mname = s + .get(0) + .ok_or(anyhow!("module name cannot be an empty string"))?; + (mname, mname) } - } - o + 2 => { + let newname = s + .get(0) + .ok_or(anyhow!("new module name cannot be an empty string"))?; + let oldname = s + .get(1) + .ok_or(anyhow!("old module name cannot be an empty string"))?; + (newname, oldname) + } + _ => bail!("invalid module mapping: '{}'", m), + }; + Ok((n.to_string(), o.to_string())) } From 9e8b7e4a7429903b3fe1b9b574dbc1c093fdfc3b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 16 Jan 2020 14:42:07 -0800 Subject: [PATCH 0514/1772] Make poll return errno::inval if there are no subscriptions. (#193) `poll` with no subscriptions is effectively an infinite hang. Since wasm has no signals, use cases which involve waking up a libc `pause` call, which is implemented in terms of a poll with no subscriptions, aren't applicable. So all `pause` can do is suspend the program until the host environment terminates it. One situation where that's useful is in debugging, as it's sometimes useful to be able to suspend a process in place so that it can be inspected by a debugger. However, that doesn't require a fully infinite suspend; a suspend with a long timeout is adequate. Making the no-subscriptions case an error can help catch cases where applications unintentionally enter infinite loops. --- proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx index 7dcdb53e6..a30b96afc 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx @@ -12,6 +12,8 @@ (import "memory" (memory)) ;;; Concurrently poll for the occurrence of a set of events. + ;;; + ;;; If `nsubscriptions` is 0, returns `errno::inval`. (@interface func (export "oneoff") ;;; The events to which to subscribe. (param $in (@witx const_pointer $subscription)) From b141744ab8de9086620c49a85acb2f344dc312b3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 16 Jan 2020 14:42:07 -0800 Subject: [PATCH 0515/1772] Make poll return errno::inval if there are no subscriptions. (#193) `poll` with no subscriptions is effectively an infinite hang. Since wasm has no signals, use cases which involve waking up a libc `pause` call, which is implemented in terms of a poll with no subscriptions, aren't applicable. So all `pause` can do is suspend the program until the host environment terminates it. One situation where that's useful is in debugging, as it's sometimes useful to be able to suspend a process in place so that it can be inspected by a debugger. However, that doesn't require a fully infinite suspend; a suspend with a long timeout is adequate. Making the no-subscriptions case an error can help catch cases where applications unintentionally enter infinite loops. --- proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx index 7dcdb53e6..a30b96afc 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx @@ -12,6 +12,8 @@ (import "memory" (memory)) ;;; Concurrently poll for the occurrence of a set of events. + ;;; + ;;; If `nsubscriptions` is 0, returns `errno::inval`. (@interface func (export "oneoff") ;;; The events to which to subscribe. (param $in (@witx const_pointer $subscription)) From 59a43ed43d90088741d2035fda52685e43759eaf Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 16 Jan 2020 14:42:07 -0800 Subject: [PATCH 0516/1772] Make poll return errno::inval if there are no subscriptions. (#193) `poll` with no subscriptions is effectively an infinite hang. Since wasm has no signals, use cases which involve waking up a libc `pause` call, which is implemented in terms of a poll with no subscriptions, aren't applicable. So all `pause` can do is suspend the program until the host environment terminates it. One situation where that's useful is in debugging, as it's sometimes useful to be able to suspend a process in place so that it can be inspected by a debugger. However, that doesn't require a fully infinite suspend; a suspend with a long timeout is adequate. Making the no-subscriptions case an error can help catch cases where applications unintentionally enter infinite loops. --- .../filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx index 7dcdb53e6..a30b96afc 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx @@ -12,6 +12,8 @@ (import "memory" (memory)) ;;; Concurrently poll for the occurrence of a set of events. + ;;; + ;;; If `nsubscriptions` is 0, returns `errno::inval`. (@interface func (export "oneoff") ;;; The events to which to subscribe. (param $in (@witx const_pointer $subscription)) From f335499fe8c7a1b58470676a8e0f0434291a1b6a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 21 Jan 2020 16:22:33 -0800 Subject: [PATCH 0517/1772] regen ephemeral docs --- proposals/clocks/phases/ephemeral/docs.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 8465cd8b7..4fd0305ed 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -1646,6 +1646,8 @@ The path to a file to unlink. #### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` Concurrently poll for the occurrence of a set of events. +If `nsubscriptions` is 0, returns [`errno::inval`](#errno.inval). + ##### Params - `in`: `ConstPointer` The events to which to subscribe. From 032f9eaa59f7e88bb7ada07f30accfab3822b224 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 21 Jan 2020 16:22:33 -0800 Subject: [PATCH 0518/1772] regen ephemeral docs --- proposals/random/phases/ephemeral/docs.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 8465cd8b7..4fd0305ed 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -1646,6 +1646,8 @@ The path to a file to unlink. #### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` Concurrently poll for the occurrence of a set of events. +If `nsubscriptions` is 0, returns [`errno::inval`](#errno.inval). + ##### Params - `in`: `ConstPointer` The events to which to subscribe. From d1d5de649c2153345e5154b9fc63555a9e5b31e0 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 21 Jan 2020 16:22:33 -0800 Subject: [PATCH 0519/1772] regen ephemeral docs --- proposals/filesystem/phases/ephemeral/docs.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 8465cd8b7..4fd0305ed 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -1646,6 +1646,8 @@ The path to a file to unlink. #### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` Concurrently poll for the occurrence of a set of events. +If `nsubscriptions` is 0, returns [`errno::inval`](#errno.inval). + ##### Params - `in`: `ConstPointer` The events to which to subscribe. From 94cb6b47a876d66b3667ecc0cef1951f5d886df6 Mon Sep 17 00:00:00 2001 From: Denis Vasilik Date: Tue, 21 Jan 2020 22:04:49 +0000 Subject: [PATCH 0520/1772] Fix typo in Charter.md --- proposals/clocks/Charter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/Charter.md b/proposals/clocks/Charter.md index b73293475..c7d3a49af 100644 --- a/proposals/clocks/Charter.md +++ b/proposals/clocks/Charter.md @@ -21,7 +21,7 @@ The Subgroup will consider topics related to system interface APIs, including: - APIs for host filesystems, network stacks, and other resources. - APIs for graphics, audio, input devices - APIs for encryption, format conversion, and other transformations - (particularly where hardware accelleration may be available on some plaforms) + (particularly where hardware accelleration may be available on some platforms) ## Deliverables From d7b68f220a39d6883c4153775f8e529ea24ffc40 Mon Sep 17 00:00:00 2001 From: Denis Vasilik Date: Tue, 21 Jan 2020 22:04:49 +0000 Subject: [PATCH 0521/1772] Fix typo in Charter.md --- proposals/random/Charter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/Charter.md b/proposals/random/Charter.md index b73293475..c7d3a49af 100644 --- a/proposals/random/Charter.md +++ b/proposals/random/Charter.md @@ -21,7 +21,7 @@ The Subgroup will consider topics related to system interface APIs, including: - APIs for host filesystems, network stacks, and other resources. - APIs for graphics, audio, input devices - APIs for encryption, format conversion, and other transformations - (particularly where hardware accelleration may be available on some plaforms) + (particularly where hardware accelleration may be available on some platforms) ## Deliverables From 84b4c8e76569c6044d1ad5c7dd2f85a63b099235 Mon Sep 17 00:00:00 2001 From: Denis Vasilik Date: Tue, 21 Jan 2020 22:04:49 +0000 Subject: [PATCH 0522/1772] Fix typo in Charter.md --- proposals/filesystem/Charter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/Charter.md b/proposals/filesystem/Charter.md index b73293475..c7d3a49af 100644 --- a/proposals/filesystem/Charter.md +++ b/proposals/filesystem/Charter.md @@ -21,7 +21,7 @@ The Subgroup will consider topics related to system interface APIs, including: - APIs for host filesystems, network stacks, and other resources. - APIs for graphics, audio, input devices - APIs for encryption, format conversion, and other transformations - (particularly where hardware accelleration may be available on some plaforms) + (particularly where hardware accelleration may be available on some platforms) ## Deliverables From 14a71fab9bf4d5b9e041231d5c30775ff8e93b80 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Jan 2020 14:10:01 -0800 Subject: [PATCH 0523/1772] Rename `creat` to `create`. (#199) Ken Thompson was once asked what he would do differently if he were redesigning the UNIX system. His reply: "I'd spell creat with an e." - https://en.wikiquote.org/wiki/Ken_Thompson#Quotes --- proposals/clocks/phases/ephemeral/witx/typenames.witx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index f3b7c83e5..50b865a58 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -228,7 +228,7 @@ $fd_allocate ;;; The right to invoke `path_create_directory`. $path_create_directory - ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::creat`. + ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::create`. $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. @@ -451,7 +451,7 @@ (typename $oflags (flags u16 ;;; Create file if it does not exist. - $creat + $create ;;; Fail if not a directory. $directory ;;; Fail if file already exists. From 624848d7cc563078e5dd55c4f0ab72bbef75feb6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Jan 2020 14:10:01 -0800 Subject: [PATCH 0524/1772] Rename `creat` to `create`. (#199) Ken Thompson was once asked what he would do differently if he were redesigning the UNIX system. His reply: "I'd spell creat with an e." - https://en.wikiquote.org/wiki/Ken_Thompson#Quotes --- proposals/random/phases/ephemeral/witx/typenames.witx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index f3b7c83e5..50b865a58 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -228,7 +228,7 @@ $fd_allocate ;;; The right to invoke `path_create_directory`. $path_create_directory - ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::creat`. + ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::create`. $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. @@ -451,7 +451,7 @@ (typename $oflags (flags u16 ;;; Create file if it does not exist. - $creat + $create ;;; Fail if not a directory. $directory ;;; Fail if file already exists. From 2119124043b35717062afaf16e6bc042402add8c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Jan 2020 14:10:01 -0800 Subject: [PATCH 0525/1772] Rename `creat` to `create`. (#199) Ken Thompson was once asked what he would do differently if he were redesigning the UNIX system. His reply: "I'd spell creat with an e." - https://en.wikiquote.org/wiki/Ken_Thompson#Quotes --- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index f3b7c83e5..50b865a58 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -228,7 +228,7 @@ $fd_allocate ;;; The right to invoke `path_create_directory`. $path_create_directory - ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::creat`. + ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::create`. $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. @@ -451,7 +451,7 @@ (typename $oflags (flags u16 ;;; Create file if it does not exist. - $creat + $create ;;; Fail if not a directory. $directory ;;; Fail if file already exists. From 33309855a6a0d68a2bedab666c0e7914d6f80f41 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Jan 2020 16:44:02 -0800 Subject: [PATCH 0526/1772] Rename $subscription_fd_readwrite's $fd member to $fd. (#200) This makes it more consistent with naming through the rest of the witx specs. --- proposals/clocks/phases/ephemeral/witx/typenames.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 50b865a58..c04db9476 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -613,7 +613,7 @@ (typename $subscription_fd_readwrite (struct ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd) + (field $fd $fd) ) ) From 876316cceafcca54fce53214ad4896fd2ec61a14 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Jan 2020 16:44:02 -0800 Subject: [PATCH 0527/1772] Rename $subscription_fd_readwrite's $fd member to $fd. (#200) This makes it more consistent with naming through the rest of the witx specs. --- proposals/random/phases/ephemeral/witx/typenames.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 50b865a58..c04db9476 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -613,7 +613,7 @@ (typename $subscription_fd_readwrite (struct ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd) + (field $fd $fd) ) ) From a3ebfd8d700e6ae925b318ed7ebf456574f2fbf9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Jan 2020 16:44:02 -0800 Subject: [PATCH 0528/1772] Rename $subscription_fd_readwrite's $fd member to $fd. (#200) This makes it more consistent with naming through the rest of the witx specs. --- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 50b865a58..c04db9476 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -613,7 +613,7 @@ (typename $subscription_fd_readwrite (struct ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd) + (field $fd $fd) ) ) From 7d169b991886a714565552176abb0e46159dd587 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Jan 2020 16:45:10 -0800 Subject: [PATCH 0529/1772] Change `random`'s buffer back to `u8`. (#198) The buffer contains arbitrary bytes, not UTF-8-encoded bytes, so use `u8` rather than `char8`. Fixes #184. --- .../clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx index e68d50c91..55c6df021 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx @@ -19,7 +19,7 @@ ;;; number generator, rather than to provide the random data directly. (@interface func (export "get") ;;; The buffer to fill with random data. - (param $buf (@witx pointer char8)) + (param $buf (@witx pointer u8)) (param $buf_len $size) (result $error $errno) ) From 65223d2c158df90d567086cf6966c324f31171df Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Jan 2020 16:45:10 -0800 Subject: [PATCH 0530/1772] Change `random`'s buffer back to `u8`. (#198) The buffer contains arbitrary bytes, not UTF-8-encoded bytes, so use `u8` rather than `char8`. Fixes #184. --- .../random/phases/ephemeral/witx/wasi_ephemeral_random.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx index e68d50c91..55c6df021 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx @@ -19,7 +19,7 @@ ;;; number generator, rather than to provide the random data directly. (@interface func (export "get") ;;; The buffer to fill with random data. - (param $buf (@witx pointer char8)) + (param $buf (@witx pointer u8)) (param $buf_len $size) (result $error $errno) ) From 4a08d781aa2baa485cd4fc713e51b8fcf95a87eb Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Jan 2020 16:45:10 -0800 Subject: [PATCH 0531/1772] Change `random`'s buffer back to `u8`. (#198) The buffer contains arbitrary bytes, not UTF-8-encoded bytes, so use `u8` rather than `char8`. Fixes #184. --- .../filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx index e68d50c91..55c6df021 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx @@ -19,7 +19,7 @@ ;;; number generator, rather than to provide the random data directly. (@interface func (export "get") ;;; The buffer to fill with random data. - (param $buf (@witx pointer char8)) + (param $buf (@witx pointer u8)) (param $buf_len $size) (result $error $errno) ) From eaead56d3913676857521145d3d89c679f20b657 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 31 Jan 2020 21:05:26 -0500 Subject: [PATCH 0532/1772] change set_permissions to permissions_set This commit replaces uses of filestat_set_permissions with permissions_set. --- proposals/clocks/phases/ephemeral/witx/typenames.witx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index c04db9476..08a11bb98 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -253,7 +253,7 @@ $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. $path_filestat_set_times - ;;; The right to invoke `path_filestat_set_permissions`. + ;;; The right to invoke `path_permissions_set`. $path_permissions_set ;;; The right to invoke `fd_filestat_get`. $fd_filestat_get @@ -261,7 +261,7 @@ $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. $fd_filestat_set_times - ;;; The right to invoke `fd_filestat_set_permissions`. + ;;; The right to invoke `fd_permissions_set`. $fd_permissions_set ;;; The right to invoke `path_symlink`. $path_symlink From 73f6d74a26779b6ee95b483495045de8d851ce6a Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 31 Jan 2020 21:05:26 -0500 Subject: [PATCH 0533/1772] change set_permissions to permissions_set This commit replaces uses of filestat_set_permissions with permissions_set. --- proposals/random/phases/ephemeral/witx/typenames.witx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index c04db9476..08a11bb98 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -253,7 +253,7 @@ $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. $path_filestat_set_times - ;;; The right to invoke `path_filestat_set_permissions`. + ;;; The right to invoke `path_permissions_set`. $path_permissions_set ;;; The right to invoke `fd_filestat_get`. $fd_filestat_get @@ -261,7 +261,7 @@ $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. $fd_filestat_set_times - ;;; The right to invoke `fd_filestat_set_permissions`. + ;;; The right to invoke `fd_permissions_set`. $fd_permissions_set ;;; The right to invoke `path_symlink`. $path_symlink From 6129e2af7decac7dc27ad6f5fb5d296baa3a7464 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 31 Jan 2020 21:05:26 -0500 Subject: [PATCH 0534/1772] change set_permissions to permissions_set This commit replaces uses of filestat_set_permissions with permissions_set. --- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index c04db9476..08a11bb98 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -253,7 +253,7 @@ $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. $path_filestat_set_times - ;;; The right to invoke `path_filestat_set_permissions`. + ;;; The right to invoke `path_permissions_set`. $path_permissions_set ;;; The right to invoke `fd_filestat_get`. $fd_filestat_get @@ -261,7 +261,7 @@ $fd_filestat_set_size ;;; The right to invoke `fd_filestat_set_times`. $fd_filestat_set_times - ;;; The right to invoke `fd_filestat_set_permissions`. + ;;; The right to invoke `fd_permissions_set`. $fd_permissions_set ;;; The right to invoke `path_symlink`. $path_symlink From 62c6cacdfe4236c960f6fb3d58245dc88dece9da Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 31 Jan 2020 21:07:11 -0500 Subject: [PATCH 0535/1772] regenerate docs --- proposals/clocks/phases/ephemeral/docs.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 4fd0305ed..f8601775d 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -308,7 +308,7 @@ The right to invoke `fd_allocate`. The right to invoke `path_create_directory`. - `path_create_file` -If `path_open` is set, the right to invoke `path_open` with [`oflags::creat`](#oflags.creat). +If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). - `path_link_source` The right to invoke `path_link` with the file descriptor as the @@ -344,7 +344,7 @@ If `path_open` is set, includes the right to invoke `path_open` with [`oflags::t The right to invoke `path_filestat_set_times`. - `path_permissions_set` -The right to invoke `path_filestat_set_permissions`. +The right to invoke `path_permissions_set`. - `fd_filestat_get` The right to invoke `fd_filestat_get`. @@ -356,7 +356,7 @@ The right to invoke `fd_filestat_set_size`. The right to invoke `fd_filestat_set_times`. - `fd_permissions_set` -The right to invoke `fd_filestat_set_permissions`. +The right to invoke `fd_permissions_set`. - `path_symlink` The right to invoke `path_symlink`. @@ -568,7 +568,7 @@ As long as the resolved path corresponds to a symbolic link, it is expanded. Open flags used by `path_open`. ### Flags -- `creat` +- `create` Create file if it does not exist. - `directory` @@ -740,7 +740,7 @@ The contents of a $subscription when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members -- `file_descriptor`: [`fd`](#fd) +- `fd`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. ## `subscription_u`: Union @@ -1687,7 +1687,7 @@ The exit code returned by the process. --- -#### `get(buf: Pointer, buf_len: size) -> errno` +#### `get(buf: Pointer, buf_len: size) -> errno` Write high-quality random data into a buffer. This function blocks when the implementation is unable to immediately provide sufficient high-quality random data. @@ -1696,7 +1696,7 @@ required, it's advisable to use this function to seed a pseudo-random number generator, rather than to provide the random data directly. ##### Params -- `buf`: `Pointer` +- `buf`: `Pointer` The buffer to fill with random data. - `buf_len`: [`size`](#size) From 4841f620289bfdbc273f889e4d612d43c9af21ef Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 31 Jan 2020 21:07:11 -0500 Subject: [PATCH 0536/1772] regenerate docs --- proposals/random/phases/ephemeral/docs.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 4fd0305ed..f8601775d 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -308,7 +308,7 @@ The right to invoke `fd_allocate`. The right to invoke `path_create_directory`. - `path_create_file` -If `path_open` is set, the right to invoke `path_open` with [`oflags::creat`](#oflags.creat). +If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). - `path_link_source` The right to invoke `path_link` with the file descriptor as the @@ -344,7 +344,7 @@ If `path_open` is set, includes the right to invoke `path_open` with [`oflags::t The right to invoke `path_filestat_set_times`. - `path_permissions_set` -The right to invoke `path_filestat_set_permissions`. +The right to invoke `path_permissions_set`. - `fd_filestat_get` The right to invoke `fd_filestat_get`. @@ -356,7 +356,7 @@ The right to invoke `fd_filestat_set_size`. The right to invoke `fd_filestat_set_times`. - `fd_permissions_set` -The right to invoke `fd_filestat_set_permissions`. +The right to invoke `fd_permissions_set`. - `path_symlink` The right to invoke `path_symlink`. @@ -568,7 +568,7 @@ As long as the resolved path corresponds to a symbolic link, it is expanded. Open flags used by `path_open`. ### Flags -- `creat` +- `create` Create file if it does not exist. - `directory` @@ -740,7 +740,7 @@ The contents of a $subscription when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members -- `file_descriptor`: [`fd`](#fd) +- `fd`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. ## `subscription_u`: Union @@ -1687,7 +1687,7 @@ The exit code returned by the process. --- -#### `get(buf: Pointer, buf_len: size) -> errno` +#### `get(buf: Pointer, buf_len: size) -> errno` Write high-quality random data into a buffer. This function blocks when the implementation is unable to immediately provide sufficient high-quality random data. @@ -1696,7 +1696,7 @@ required, it's advisable to use this function to seed a pseudo-random number generator, rather than to provide the random data directly. ##### Params -- `buf`: `Pointer` +- `buf`: `Pointer` The buffer to fill with random data. - `buf_len`: [`size`](#size) From 02cd50e8c5c4ad4d37853f3d5aee0cd4c14e770c Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 31 Jan 2020 21:07:11 -0500 Subject: [PATCH 0537/1772] regenerate docs --- proposals/filesystem/phases/ephemeral/docs.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 4fd0305ed..f8601775d 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -308,7 +308,7 @@ The right to invoke `fd_allocate`. The right to invoke `path_create_directory`. - `path_create_file` -If `path_open` is set, the right to invoke `path_open` with [`oflags::creat`](#oflags.creat). +If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). - `path_link_source` The right to invoke `path_link` with the file descriptor as the @@ -344,7 +344,7 @@ If `path_open` is set, includes the right to invoke `path_open` with [`oflags::t The right to invoke `path_filestat_set_times`. - `path_permissions_set` -The right to invoke `path_filestat_set_permissions`. +The right to invoke `path_permissions_set`. - `fd_filestat_get` The right to invoke `fd_filestat_get`. @@ -356,7 +356,7 @@ The right to invoke `fd_filestat_set_size`. The right to invoke `fd_filestat_set_times`. - `fd_permissions_set` -The right to invoke `fd_filestat_set_permissions`. +The right to invoke `fd_permissions_set`. - `path_symlink` The right to invoke `path_symlink`. @@ -568,7 +568,7 @@ As long as the resolved path corresponds to a symbolic link, it is expanded. Open flags used by `path_open`. ### Flags -- `creat` +- `create` Create file if it does not exist. - `directory` @@ -740,7 +740,7 @@ The contents of a $subscription when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members -- `file_descriptor`: [`fd`](#fd) +- `fd`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. ## `subscription_u`: Union @@ -1687,7 +1687,7 @@ The exit code returned by the process. --- -#### `get(buf: Pointer, buf_len: size) -> errno` +#### `get(buf: Pointer, buf_len: size) -> errno` Write high-quality random data into a buffer. This function blocks when the implementation is unable to immediately provide sufficient high-quality random data. @@ -1696,7 +1696,7 @@ required, it's advisable to use this function to seed a pseudo-random number generator, rather than to provide the random data directly. ##### Params -- `buf`: `Pointer` +- `buf`: `Pointer` The buffer to fill with random data. - `buf_len`: [`size`](#size) From e370c70639a83721a91a0fe2e09714116d7a2c91 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Yuji Date: Fri, 7 Feb 2020 02:41:14 +0900 Subject: [PATCH 0538/1772] Clarify "type" is $pr_type in $prestat_u::dir and $prestat_dir (#222) * Clarify "type" is $pr_type in $prestat_u::dir and $prestat_dir The word "type" in the descriptions of `$prestat_u::dir` and `$prestat_dir` should be clarified as `$pr_type`. We can actually easily infer from the context, but I felt confused a little at first. Fix: https://github.com/WebAssembly/WASI/issues/221 * Fix: avoid test failure underscores in markdown should be escaped, but currently the witx tool doesn't support escaping --- proposals/clocks/phases/ephemeral/docs.md | 4 ++-- proposals/clocks/phases/ephemeral/witx/typenames.witx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index f8601775d..390599af5 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -809,7 +809,7 @@ Identifiers for preopened capabilities. A pre-opened directory. ## `prestat_dir`: Struct -The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). +The contents of a $prestat when its $pr_type is [`preopentype::dir`](#preopentype.dir). ### Struct members - `pr_name_len`: [`size`](#size) @@ -820,7 +820,7 @@ The contents of an $prestat. ### Union variants - `dir`: [`prestat_dir`](#prestat_dir) -When type is [`preopentype::dir`](#preopentype.dir): +When $pr_type of the $prestat is [`preopentype::dir`](#preopentype.dir): ## `prestat`: Struct Information about a pre-opened capability. diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 08a11bb98..38ca67b1c 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -683,7 +683,7 @@ ) ) -;;; The contents of a $prestat when type is `preopentype::dir`. +;;; The contents of a $prestat when its $pr_type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. @@ -694,7 +694,7 @@ ;;; The contents of an $prestat. (typename $prestat_u (union - ;;; When type is `preopentype::dir`: + ;;; When $pr_type of the $prestat is `preopentype::dir`: (field $dir $prestat_dir) ) ) From b45eda9ff1898b743917ff032f75fb759c1a87cf Mon Sep 17 00:00:00 2001 From: YAMAMOTO Yuji Date: Fri, 7 Feb 2020 02:41:14 +0900 Subject: [PATCH 0539/1772] Clarify "type" is $pr_type in $prestat_u::dir and $prestat_dir (#222) * Clarify "type" is $pr_type in $prestat_u::dir and $prestat_dir The word "type" in the descriptions of `$prestat_u::dir` and `$prestat_dir` should be clarified as `$pr_type`. We can actually easily infer from the context, but I felt confused a little at first. Fix: https://github.com/WebAssembly/WASI/issues/221 * Fix: avoid test failure underscores in markdown should be escaped, but currently the witx tool doesn't support escaping --- proposals/random/phases/ephemeral/docs.md | 4 ++-- proposals/random/phases/ephemeral/witx/typenames.witx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index f8601775d..390599af5 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -809,7 +809,7 @@ Identifiers for preopened capabilities. A pre-opened directory. ## `prestat_dir`: Struct -The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). +The contents of a $prestat when its $pr_type is [`preopentype::dir`](#preopentype.dir). ### Struct members - `pr_name_len`: [`size`](#size) @@ -820,7 +820,7 @@ The contents of an $prestat. ### Union variants - `dir`: [`prestat_dir`](#prestat_dir) -When type is [`preopentype::dir`](#preopentype.dir): +When $pr_type of the $prestat is [`preopentype::dir`](#preopentype.dir): ## `prestat`: Struct Information about a pre-opened capability. diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 08a11bb98..38ca67b1c 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -683,7 +683,7 @@ ) ) -;;; The contents of a $prestat when type is `preopentype::dir`. +;;; The contents of a $prestat when its $pr_type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. @@ -694,7 +694,7 @@ ;;; The contents of an $prestat. (typename $prestat_u (union - ;;; When type is `preopentype::dir`: + ;;; When $pr_type of the $prestat is `preopentype::dir`: (field $dir $prestat_dir) ) ) From 0cb9479ba7b9f654dd326a9f1cc79c85837cc872 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Yuji Date: Fri, 7 Feb 2020 02:41:14 +0900 Subject: [PATCH 0540/1772] Clarify "type" is $pr_type in $prestat_u::dir and $prestat_dir (#222) * Clarify "type" is $pr_type in $prestat_u::dir and $prestat_dir The word "type" in the descriptions of `$prestat_u::dir` and `$prestat_dir` should be clarified as `$pr_type`. We can actually easily infer from the context, but I felt confused a little at first. Fix: https://github.com/WebAssembly/WASI/issues/221 * Fix: avoid test failure underscores in markdown should be escaped, but currently the witx tool doesn't support escaping --- proposals/filesystem/phases/ephemeral/docs.md | 4 ++-- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index f8601775d..390599af5 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -809,7 +809,7 @@ Identifiers for preopened capabilities. A pre-opened directory. ## `prestat_dir`: Struct -The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). +The contents of a $prestat when its $pr_type is [`preopentype::dir`](#preopentype.dir). ### Struct members - `pr_name_len`: [`size`](#size) @@ -820,7 +820,7 @@ The contents of an $prestat. ### Union variants - `dir`: [`prestat_dir`](#prestat_dir) -When type is [`preopentype::dir`](#preopentype.dir): +When $pr_type of the $prestat is [`preopentype::dir`](#preopentype.dir): ## `prestat`: Struct Information about a pre-opened capability. diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 08a11bb98..38ca67b1c 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -683,7 +683,7 @@ ) ) -;;; The contents of a $prestat when type is `preopentype::dir`. +;;; The contents of a $prestat when its $pr_type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. @@ -694,7 +694,7 @@ ;;; The contents of an $prestat. (typename $prestat_u (union - ;;; When type is `preopentype::dir`: + ;;; When $pr_type of the $prestat is `preopentype::dir`: (field $dir $prestat_dir) ) ) From 6b73469d060e1edbd885c1cb74fa7d2817a90395 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 31 Jan 2020 20:47:59 -0500 Subject: [PATCH 0541/1772] update fd_permissions_set() signature It appears that the permissions argument to permissions_set() was labeled as an output instead of an input. --- proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx index abd5cf610..e92dd4f91 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -122,7 +122,7 @@ (@interface func (export "permissions_set") (param $fd $fd) ;;; The permissions associated with the file. - (result $permissions $permissions) + (param $permissions $permissions) (result $error $errno) ) From 6e1a2c763da6c220f0faf7efd64fd5427e95f1b1 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 31 Jan 2020 20:47:59 -0500 Subject: [PATCH 0542/1772] update fd_permissions_set() signature It appears that the permissions argument to permissions_set() was labeled as an output instead of an input. --- proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx index abd5cf610..e92dd4f91 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -122,7 +122,7 @@ (@interface func (export "permissions_set") (param $fd $fd) ;;; The permissions associated with the file. - (result $permissions $permissions) + (param $permissions $permissions) (result $error $errno) ) From 3d44b985c4660fe7bc395f1ba54389a2fd1fd893 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 31 Jan 2020 20:47:59 -0500 Subject: [PATCH 0543/1772] update fd_permissions_set() signature It appears that the permissions argument to permissions_set() was labeled as an output instead of an input. --- .../filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx index abd5cf610..e92dd4f91 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -122,7 +122,7 @@ (@interface func (export "permissions_set") (param $fd $fd) ;;; The permissions associated with the file. - (result $permissions $permissions) + (param $permissions $permissions) (result $error $errno) ) From cd48f6f157c76fb52661e717abc69442f7f854d1 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 31 Jan 2020 20:52:43 -0500 Subject: [PATCH 0544/1772] regenerate docs --- proposals/clocks/phases/ephemeral/docs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 390599af5..fed63a44e 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -1122,7 +1122,7 @@ A bitmask indicating which timestamps to adjust. --- -#### `permissions_set(fd: fd) -> (permissions, errno)` +#### `permissions_set(fd: fd, permissions: permissions) -> errno` Set the permissions of a file or directory. This sets the permissions associated with a file or directory in @@ -1139,10 +1139,10 @@ umask to determine which of the user/group/other flags to modify. ##### Params - `fd`: [`fd`](#fd) -##### Results - `permissions`: [`permissions`](#permissions) The permissions associated with the file. +##### Results - `error`: [`errno`](#errno) From b947af8caa614f7d673b0099a9c9e18e37fbd884 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 31 Jan 2020 20:52:43 -0500 Subject: [PATCH 0545/1772] regenerate docs --- proposals/random/phases/ephemeral/docs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 390599af5..fed63a44e 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -1122,7 +1122,7 @@ A bitmask indicating which timestamps to adjust. --- -#### `permissions_set(fd: fd) -> (permissions, errno)` +#### `permissions_set(fd: fd, permissions: permissions) -> errno` Set the permissions of a file or directory. This sets the permissions associated with a file or directory in @@ -1139,10 +1139,10 @@ umask to determine which of the user/group/other flags to modify. ##### Params - `fd`: [`fd`](#fd) -##### Results - `permissions`: [`permissions`](#permissions) The permissions associated with the file. +##### Results - `error`: [`errno`](#errno) From 0e55857774cf138e8dbea0f661c9befd967ceb57 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 31 Jan 2020 20:52:43 -0500 Subject: [PATCH 0546/1772] regenerate docs --- proposals/filesystem/phases/ephemeral/docs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 390599af5..fed63a44e 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -1122,7 +1122,7 @@ A bitmask indicating which timestamps to adjust. --- -#### `permissions_set(fd: fd) -> (permissions, errno)` +#### `permissions_set(fd: fd, permissions: permissions) -> errno` Set the permissions of a file or directory. This sets the permissions associated with a file or directory in @@ -1139,10 +1139,10 @@ umask to determine which of the user/group/other flags to modify. ##### Params - `fd`: [`fd`](#fd) -##### Results - `permissions`: [`permissions`](#permissions) The permissions associated with the file. +##### Results - `error`: [`errno`](#errno) From 9fe831c0dbc2c1cf735af1ccd5789cb031ba5d84 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 18 Feb 2020 20:51:57 +0100 Subject: [PATCH 0547/1772] Fix const description in ephemeral (#224) This commit fixes a `dircookie` comment string of its only const member `start`. Effectively, due to the fact that one semicolon was missing, the docs were not properly generated. --- proposals/clocks/phases/ephemeral/docs.md | 1 + proposals/clocks/phases/ephemeral/witx/typenames.witx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index fed63a44e..42f4f4879 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -423,6 +423,7 @@ A reference to the offset of a directory entry. ### Consts - `start` +In an `fd_readdir` call, this value signifies the start of the directory. ## `dirnamlen`: `u32` The type for the $d_namlen field of $dirent. diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 38ca67b1c..269d203d5 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -321,7 +321,7 @@ ;;; A reference to the offset of a directory entry. (typename $dircookie (int u64 - ;; In an `fd_readdir` call, this value signifies the start of the directory. + ;;; In an `fd_readdir` call, this value signifies the start of the directory. (const $start 0) ) ) From 95f5a701662e214d97ea5ede2874b1c298defd4e Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 18 Feb 2020 20:51:57 +0100 Subject: [PATCH 0548/1772] Fix const description in ephemeral (#224) This commit fixes a `dircookie` comment string of its only const member `start`. Effectively, due to the fact that one semicolon was missing, the docs were not properly generated. --- proposals/random/phases/ephemeral/docs.md | 1 + proposals/random/phases/ephemeral/witx/typenames.witx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index fed63a44e..42f4f4879 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -423,6 +423,7 @@ A reference to the offset of a directory entry. ### Consts - `start` +In an `fd_readdir` call, this value signifies the start of the directory. ## `dirnamlen`: `u32` The type for the $d_namlen field of $dirent. diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 38ca67b1c..269d203d5 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -321,7 +321,7 @@ ;;; A reference to the offset of a directory entry. (typename $dircookie (int u64 - ;; In an `fd_readdir` call, this value signifies the start of the directory. + ;;; In an `fd_readdir` call, this value signifies the start of the directory. (const $start 0) ) ) From 93b004602307e40d4a08e839b12dba5138852f35 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 18 Feb 2020 20:51:57 +0100 Subject: [PATCH 0549/1772] Fix const description in ephemeral (#224) This commit fixes a `dircookie` comment string of its only const member `start`. Effectively, due to the fact that one semicolon was missing, the docs were not properly generated. --- proposals/filesystem/phases/ephemeral/docs.md | 1 + proposals/filesystem/phases/ephemeral/witx/typenames.witx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index fed63a44e..42f4f4879 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -423,6 +423,7 @@ A reference to the offset of a directory entry. ### Consts - `start` +In an `fd_readdir` call, this value signifies the start of the directory. ## `dirnamlen`: `u32` The type for the $d_namlen field of $dirent. diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 38ca67b1c..269d203d5 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -321,7 +321,7 @@ ;;; A reference to the offset of a directory entry. (typename $dircookie (int u64 - ;; In an `fd_readdir` call, this value signifies the start of the directory. + ;;; In an `fd_readdir` call, this value signifies the start of the directory. (const $start 0) ) ) From f6614dfd473c803eb5f3c68feeb839b39e60586b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 18 Feb 2020 12:31:35 -0800 Subject: [PATCH 0550/1772] Change witx unions to be tagged (#220) * unions are now tagged by an enum * union fields may be empty. TODO: write tests * unions: add more tests. compute layout. * snapshot 0: translate untagged union syntax to tagged union syntax * snapshot: update from untagged union to tagged union syntax * snapshot: update docs * snapshot 0: update docs * ephemeral: translate untagged unions to tagged unions * render: fix union output * bump witx to 0.8.0 - this is definitely semver breaking * snapshot: I forgot to delete the tag field `subscription.type` * regen docs * unionlayout: derive the usual suspects * snapshot 1 and 0: put tag back in event struct, flatten event_u prior to this PR, event_u was a union with only one variant fd_readwrite. the change into tagged union ended up changing the memory layout of the event struct. so, rather than use tagged unions in the event struct, we just use a struct that you ignore in the case of the clock event, which has the same ABI as previously. in ephemeral, we use a tagged union for events, because we dont have any ABI stability guarantees to maintain there. * layout: refactor so we have impls for NamedType and Type too * ast: change tag of UnionDatatype to be a NamedType this is much more convenient for consumers, and it reflects the requirement of the syntax to provide an Id * fixup docs --- proposals/clocks/phases/ephemeral/docs.md | 41 ++-- .../phases/ephemeral/witx/typenames.witx | 38 ++-- .../clocks/phases/old/snapshot_0/docs.md | 48 ++--- .../phases/old/snapshot_0/witx/typenames.witx | 45 ++--- proposals/clocks/phases/snapshot/docs.md | 42 ++-- .../phases/snapshot/witx/typenames.witx | 42 ++-- proposals/clocks/tools/witx/Cargo.toml | 2 +- proposals/clocks/tools/witx/src/ast.rs | 3 +- proposals/clocks/tools/witx/src/docs/ast.rs | 6 +- proposals/clocks/tools/witx/src/layout.rs | 95 +++++++-- proposals/clocks/tools/witx/src/parser.rs | 33 +++- proposals/clocks/tools/witx/src/render.rs | 25 ++- .../clocks/tools/witx/src/representation.rs | 45 ++++- proposals/clocks/tools/witx/src/validate.rs | 102 +++++++++- .../clocks/tools/witx/tests/anonymous.rs | 8 +- proposals/clocks/tools/witx/tests/union.rs | 183 ++++++++++++++++++ 16 files changed, 526 insertions(+), 232 deletions(-) create mode 100644 proposals/clocks/tools/witx/tests/union.rs diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 42f4f4879..3834160fc 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -688,8 +688,11 @@ The state of the file descriptor. The contents of an $event. ### Union variants -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): +- `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) + +- `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) + +- `clock` ## `event`: Struct An event that occurred. @@ -701,11 +704,8 @@ User-provided value that got attached to [`subscription::userdata`](#subscriptio - `error`: [`errno`](#errno) If non-zero, an error that occurred while processing the subscription request. -- `type`: [`eventtype`](#eventtype) -The type of the event that occurred. - - `u`: [`event_u`](#event_u) -The contents of the event. +The type of the event that occurred, and the contents of the event ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in @@ -749,10 +749,10 @@ The contents of a $subscription. ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) -When type is [`eventtype::clock`](#eventtype.clock): -- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): +- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) ## `subscription`: Struct Subscription to an event. @@ -762,11 +762,8 @@ Subscription to an event. User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). -- `type`: [`eventtype`](#eventtype) -The type of the event to which to subscribe. - - `u`: [`subscription_u`](#subscription_u) -The contents of the subscription. +The type of the event to which to subscribe, and the contents of the subscription. ## `exitcode`: `u32` Exit code generated by a process when exiting. @@ -816,22 +813,12 @@ The contents of a $prestat when its $pr_type is [`preopentype::dir`](#preopentyp - `pr_name_len`: [`size`](#size) The length of the directory name for use with `fd_prestat_dir_name`. -## `prestat_u`: Union -The contents of an $prestat. - -### Union variants -- `dir`: [`prestat_dir`](#prestat_dir) -When $pr_type of the $prestat is [`preopentype::dir`](#preopentype.dir): - -## `prestat`: Struct +## `prestat`: Union Information about a pre-opened capability. -### Struct members -- `pr_type`: [`preopentype`](#preopentype) -The type of the pre-opened capability. - -- `u`: [`prestat_u`](#prestat_u) -The contents of the information. +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) +When type is [`preopentype::dir`](#preopentype.dir): # Modules ## wasi_ephemeral_args diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 269d203d5..c37ab2e7b 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -560,9 +560,10 @@ ;;; The contents of an $event. (typename $event_u - (union - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $event_fd_readwrite) + (union $eventtype + (field $fd_read $event_fd_readwrite) + (field $fd_write $event_fd_readwrite) + (empty $clock) ) ) @@ -573,9 +574,7 @@ (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno) - ;;; The type of the event that occurred. - (field $type $eventtype) - ;;; The contents of the event. + ;;; The type of the event that occurred, and the contents of the event (field $u $event_u) ) ) @@ -619,11 +618,10 @@ ;;; The contents of a $subscription. (typename $subscription_u - (union - ;;; When type is `eventtype::clock`: + (union $eventtype (field $clock $subscription_clock) - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $subscription_fd_readwrite) + (field $fd_read $subscription_fd_readwrite) + (field $fd_write $subscription_fd_readwrite) ) ) @@ -633,9 +631,7 @@ ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) - ;;; The type of the event to which to subscribe. - (field $type $eventtype) - ;;; The contents of the subscription. + ;;; The type of the event to which to subscribe, and the contents of the subscription. (field $u $subscription_u) ) ) @@ -691,20 +687,10 @@ ) ) -;;; The contents of an $prestat. -(typename $prestat_u - (union - ;;; When $pr_type of the $prestat is `preopentype::dir`: - (field $dir $prestat_dir) - ) -) - ;;; Information about a pre-opened capability. (typename $prestat - (struct - ;;; The type of the pre-opened capability. - (field $pr_type $preopentype) - ;;; The contents of the information. - (field $u $prestat_u) + (union $preopentype + ;;; When type is `preopentype::dir`: + (field $dir $prestat_dir) ) ) diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index 360cff906..3466d13ad 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -627,8 +627,8 @@ The state of the file descriptor subscribed to with The peer of this socket has closed or disconnected. ## `event_fd_readwrite`: Struct -The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). +The contents of an $event for the [`eventtype::fd_read`](#eventtype.fd_read) and +[`eventtype::fd_write`](#eventtype.fd_write) variants ### Struct members - `nbytes`: [`filesize`](#filesize) @@ -637,13 +637,6 @@ The number of bytes available for reading or writing. - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. -## `event_u`: Union -The contents of an $event. - -### Union variants -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): - ## `event`: Struct An event that occurred. @@ -655,10 +648,11 @@ User-provided value that got attached to [`subscription::userdata`](#subscriptio If non-zero, an error that occurred while processing the subscription request. - `type`: [`eventtype`](#eventtype) -The type of the event that occurred. +The type of event that occured -- `u`: [`event_u`](#event_u) -The contents of the event. +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in @@ -693,7 +687,7 @@ to coalesce with other events. Flags specifying whether the timeout is absolute or relative ## `subscription_fd_readwrite`: Struct -The contents of a $subscription when type is type is +The contents of a $subscription when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -705,10 +699,10 @@ The contents of a $subscription. ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) -When type is [`eventtype::clock`](#eventtype.clock): -- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): +- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) ## `subscription`: Struct Subscription to an event. @@ -718,11 +712,8 @@ Subscription to an event. User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). -- `type`: [`eventtype`](#eventtype) -The type of the event to which to subscribe. - - `u`: [`subscription_u`](#subscription_u) -The contents of the subscription. +The type of the event to which to subscribe. ## `exitcode`: `u32` Exit code generated by a process when exiting. @@ -900,22 +891,11 @@ The contents of a $prestat when type is `PREOPENTYPE_DIR`. - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). -## `prestat_u`: Union -The contents of an $prestat. - -### Union variants -- `dir`: [`prestat_dir`](#prestat_dir) -When type is `PREOPENTYPE_DIR`: - -## `prestat`: Struct +## `prestat`: Union Information about a pre-opened capability. -### Struct members -- `pr_type`: [`preopentype`](#preopentype) -The type of the pre-opened capability. - -- `u`: [`prestat_u`](#prestat_u) -The contents of the information. +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) # Modules ## wasi_unstable diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx index 9a7fc0bb2..493bda050 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx @@ -503,8 +503,8 @@ ) ) -;;; The contents of an $event when type is `eventtype::fd_read` or -;;; `eventtype::fd_write`. +;;; The contents of an $event for the `eventtype::fd_read` and +;;; `eventtype::fd_write` variants (typename $event_fd_readwrite (struct ;;; The number of bytes available for reading or writing. @@ -514,14 +514,6 @@ ) ) -;;; The contents of an $event. -(typename $event_u - (union - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $event_fd_readwrite) - ) -) - ;;; An event that occurred. (typename $event (struct @@ -529,10 +521,11 @@ (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno) - ;;; The type of the event that occurred. + ;;; The type of event that occured (field $type $eventtype) - ;;; The contents of the event. - (field $u $event_u) + ;;; The contents of the event, if it is an `eventtype::fd_read` or + ;;; `eventtype::fd_write`. `eventtype::clock` events ignore this field. + (field $fd_readwrite $event_fd_readwrite) ) ) @@ -566,7 +559,7 @@ ) ) -;;; The contents of a $subscription when type is type is +;;; The contents of a $subscription when the variant is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite (struct @@ -577,11 +570,10 @@ ;;; The contents of a $subscription. (typename $subscription_u - (union - ;;; When type is `eventtype::clock`: + (union $eventtype (field $clock $subscription_clock) - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $subscription_fd_readwrite) + (field $fd_read $subscription_fd_readwrite) + (field $fd_write $subscription_fd_readwrite) ) ) @@ -592,8 +584,6 @@ ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) ;;; The type of the event to which to subscribe. - (field $type $eventtype) - ;;; The contents of the subscription. (field $u $subscription_u) ) ) @@ -748,20 +738,9 @@ ) ) -;;; The contents of an $prestat. -(typename $prestat_u - (union - ;;; When type is `PREOPENTYPE_DIR`: - (field $dir $prestat_dir) - ) -) - ;;; Information about a pre-opened capability. (typename $prestat - (struct - ;;; The type of the pre-opened capability. - (field $pr_type $preopentype) - ;;; The contents of the information. - (field $u $prestat_u) + (union $preopentype + (field $dir $prestat_dir) ) ) diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index 09575008e..0b3dec378 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -639,13 +639,6 @@ The number of bytes available for reading or writing. - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. -## `event_u`: Union -The contents of an $event. - -### Union variants -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): - ## `event`: Struct An event that occurred. @@ -657,10 +650,11 @@ User-provided value that got attached to [`subscription::userdata`](#subscriptio If non-zero, an error that occurred while processing the subscription request. - `type`: [`eventtype`](#eventtype) -The type of the event that occurred. +The type of event that occured -- `u`: [`event_u`](#event_u) -The contents of the event. +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in @@ -704,10 +698,10 @@ The contents of a $subscription. ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) -When type is [`eventtype::clock`](#eventtype.clock): -- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): +- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) ## `subscription`: Struct Subscription to an event. @@ -717,11 +711,8 @@ Subscription to an event. User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). -- `type`: [`eventtype`](#eventtype) -The type of the event to which to subscribe. - - `u`: [`subscription_u`](#subscription_u) -The contents of the subscription. +The type of the event to which to subscribe, and its contents ## `exitcode`: `u32` Exit code generated by a process when exiting. @@ -899,22 +890,11 @@ The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). -## `prestat_u`: Union -The contents of an $prestat. - -### Union variants -- `dir`: [`prestat_dir`](#prestat_dir) -When type is [`preopentype::dir`](#preopentype.dir): - -## `prestat`: Struct +## `prestat`: Union Information about a pre-opened capability. -### Struct members -- `pr_type`: [`preopentype`](#preopentype) -The type of the pre-opened capability. - -- `u`: [`prestat_u`](#prestat_u) -The contents of the information. +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) # Modules ## wasi_snapshot_preview1 diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx index ee8c652ec..eb8cb8c64 100644 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -516,14 +516,6 @@ ) ) -;;; The contents of an $event. -(typename $event_u - (union - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $event_fd_readwrite) - ) -) - ;;; An event that occurred. (typename $event (struct @@ -531,10 +523,11 @@ (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno) - ;;; The type of the event that occurred. + ;;; The type of event that occured (field $type $eventtype) - ;;; The contents of the event. - (field $u $event_u) + ;;; The contents of the event, if it is an `eventtype::fd_read` or + ;;; `eventtype::fd_write`. `eventtype::clock` events ignore this field. + (field $fd_readwrite $event_fd_readwrite) ) ) @@ -577,11 +570,10 @@ ;;; The contents of a $subscription. (typename $subscription_u - (union - ;;; When type is `eventtype::clock`: + (union $eventtype (field $clock $subscription_clock) - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $subscription_fd_readwrite) + (field $fd_read $subscription_fd_readwrite) + (field $fd_write $subscription_fd_readwrite) ) ) @@ -591,9 +583,7 @@ ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) - ;;; The type of the event to which to subscribe. - (field $type $eventtype) - ;;; The contents of the subscription. + ;;; The type of the event to which to subscribe, and its contents (field $u $subscription_u) ) ) @@ -748,20 +738,10 @@ ) ) -;;; The contents of an $prestat. -(typename $prestat_u - (union - ;;; When type is `preopentype::dir`: - (field $dir $prestat_dir) - ) -) - ;;; Information about a pre-opened capability. (typename $prestat - (struct - ;;; The type of the pre-opened capability. - (field $pr_type $preopentype) - ;;; The contents of the information. - (field $u $prestat_u) + (union $preopentype + (field $dir $prestat_dir) ) ) + diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 959c22143..32f0cbea9 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.7.0" +version = "0.8.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index fcb33ad44..564d4ea1d 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -247,13 +247,14 @@ pub struct StructMember { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionDatatype { + pub tag: Rc, pub variants: Vec, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionVariant { pub name: Id, - pub tref: TypeRef, + pub tref: Option, pub docs: String, } diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index a5f2ca952..10dc9f7c2 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -211,7 +211,11 @@ impl ToMarkdown for UnionDatatype { name, &variant.docs, )); - variant.tref.generate(n.clone()); + if let Some(ref tref) = variant.tref { + tref.generate(n.clone()); + } else { + n.content_ref_mut::().r#type = None; + } } node.content_ref_mut::().r#type = Some(MdType::Union); diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index cd3bd7da9..3e2f6ee09 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -22,7 +22,37 @@ impl TypeRef { if let Some(hit) = cache.get(self) { return *hit; } - let layout = match &*self.type_() { + let layout = match &self { + TypeRef::Name(nt) => nt.layout(cache), + TypeRef::Value(v) => v.layout(cache), + }; + cache.insert(self.clone(), layout); + layout + } +} + +impl Layout for TypeRef { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + +impl NamedType { + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + self.tref.layout(cache) + } +} +impl Layout for NamedType { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + +impl Type { + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + match &self { Type::Enum(e) => e.repr.mem_size_align(), Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), @@ -32,18 +62,17 @@ impl TypeRef { Type::Array { .. } => BuiltinType::String.mem_size_align(), Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), - }; - cache.insert(self.clone(), layout); - layout + } } } -impl Layout for TypeRef { +impl Layout for Type { fn mem_size_align(&self) -> SizeAlign { let mut cache = HashMap::new(); self.layout(&mut cache) } } + impl Layout for IntRepr { fn mem_size_align(&self) -> SizeAlign { match self { @@ -132,25 +161,51 @@ mod test { } } +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct UnionLayout { + pub tag_size: usize, + pub tag_align: usize, + pub contents_offset: usize, + pub contents_size: usize, + pub contents_align: usize, +} + +impl Layout for UnionLayout { + fn mem_size_align(&self) -> SizeAlign { + let align = std::cmp::max(self.tag_align, self.contents_align); + let size = align_to(self.contents_offset + self.contents_size, align); + SizeAlign { size, align } + } +} + impl UnionDatatype { - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - let sas = self + pub fn union_layout(&self) -> UnionLayout { + let mut cache = HashMap::new(); + self.union_layout_(&mut cache) + } + fn union_layout_(&self, cache: &mut HashMap) -> UnionLayout { + let tag = self.tag.layout(cache); + + let variant_sas = self .variants .iter() - .map(|v| v.tref.layout(cache)) + .filter_map(|v| v.tref.as_ref().map(|t| t.layout(cache))) .collect::>(); - let size = sas - .iter() - .map(|sa| sa.size) - .max() - .expect("nonzero variants"); - let align = sas - .iter() - .map(|sa| sa.align) - .max() - .expect("nonzero variants"); - let size = align_to(size, align); - SizeAlign { size, align } + + let contents_size = variant_sas.iter().map(|sa| sa.size).max().unwrap_or(0); + let contents_align = variant_sas.iter().map(|sa| sa.align).max().unwrap_or(1); + + UnionLayout { + tag_size: tag.size, + tag_align: tag.align, + contents_offset: align_to(tag.size, contents_align), + contents_size, + contents_align, + } + } + + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + self.union_layout_(cache).mem_size_align() } } diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 08bc9af5b..85f8c8d09 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -24,6 +24,7 @@ mod kw { wast::custom_keyword!(f32); wast::custom_keyword!(f64); wast::custom_keyword!(field); + wast::custom_keyword!(empty); wast::custom_keyword!(flags); wast::custom_keyword!(handle); wast::custom_keyword!(int); @@ -477,20 +478,48 @@ impl<'a> Parse<'a> for FieldSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum VariantSyntax<'a> { + Field(FieldSyntax<'a>), + Empty(wast::Id<'a>), +} + +impl<'a> Parse<'a> for VariantSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parens(|p| { + let mut l = p.lookahead1(); + if l.peek::() { + parser.parse::()?; + let name = p.parse()?; + let type_ = p.parse()?; + Ok(VariantSyntax::Field(FieldSyntax { name, type_ })) + } else if l.peek::() { + parser.parse::()?; + let name = p.parse()?; + Ok(VariantSyntax::Empty(name)) + } else { + Err(l.error()) + } + }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionSyntax<'a> { - pub fields: Vec>>, + pub tag: wast::Id<'a>, + pub fields: Vec>>, } impl<'a> Parse<'a> for UnionSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; + let tag = parser.parse()?; let mut fields = Vec::new(); fields.push(parser.parse()?); while !parser.is_empty() { fields.push(parser.parse()?); } - Ok(UnionSyntax { fields }) + Ok(UnionSyntax { tag, fields }) } } diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index a1a6ff58a..64b429f8b 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -206,19 +206,26 @@ impl StructDatatype { impl UnionDatatype { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("union")]; + let header = vec![SExpr::word("union"), self.tag.name.to_sexpr()]; let variants = self .variants .iter() .map(|v| { - SExpr::docs( - &v.docs, - SExpr::Vec(vec![ - SExpr::word("field"), - v.name.to_sexpr(), - v.tref.to_sexpr(), - ]), - ) + if let Some(ref tref) = v.tref { + SExpr::docs( + &v.docs, + SExpr::Vec(vec![ + SExpr::word("field"), + v.name.to_sexpr(), + tref.to_sexpr(), + ]), + ) + } else { + SExpr::docs( + &v.docs, + SExpr::Vec(vec![SExpr::word("empty"), v.name.to_sexpr()]), + ) + } }) .collect::>(); SExpr::Vec([header, variants].concat()) diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs index 3bdd6a792..0f12217af 100644 --- a/proposals/clocks/tools/witx/src/representation.rs +++ b/proposals/clocks/tools/witx/src/representation.rs @@ -177,7 +177,21 @@ impl Representable for UnionDatatype { } for v in self.variants.iter() { if let Some(byv) = by.variants.iter().find(|byv| byv.name == v.name) { - if v.tref.type_().representable(&*byv.tref.type_()) != RepEquality::Eq { + if v.tref.is_none() && byv.tref.is_none() { + // Both empty is OK + } else if v.tref.is_some() && byv.tref.is_some() { + if v.tref + .as_ref() + .unwrap() + .type_() + .representable(&*byv.tref.as_ref().unwrap().type_()) + != RepEquality::Eq + { + // Fields must be Eq + return RepEquality::NotEq; + } + } else { + // Either one empty means not representable return RepEquality::NotEq; } } else { @@ -185,9 +199,19 @@ impl Representable for UnionDatatype { } } if by.variants.len() > self.variants.len() { - RepEquality::Superset + // By is a superset of self only if the tags are as well: + if self.tag.type_().representable(&*by.tag.type_()) == RepEquality::Superset { + RepEquality::Superset + } else { + RepEquality::NotEq + } } else { - RepEquality::Eq + // By and self have matching variants, so they are equal if tags are: + if self.tag.type_().representable(&*by.tag.type_()) == RepEquality::Eq { + RepEquality::Eq + } else { + RepEquality::NotEq + } } } } @@ -287,16 +311,25 @@ mod test { #[test] fn union() { - let base = def_type("a", "(typename $a (union (field $b u32) (field $c f32)))"); + let base = def_type( + "a", + "(typename $tag (enum u8 $b $c)) + (typename $a (union $tag (field $b u32) (field $c f32)))", + ); let extra_variant = def_type( "a", - "(typename $a (union (field $b u32) (field $c f32) (field $d f64)))", + "(typename $tag (enum u8 $b $c $d)) + (typename $a (union $tag (field $b u32) (field $c f32) (field $d f64)))", ); assert_eq!(base.representable(&extra_variant), RepEquality::Superset); assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); - let other_ordering = def_type("a", "(typename $a (union (field $c f32) (field $b u32)))"); + let other_ordering = def_type( + "a", + "(typename $tag (enum u8 $b $c)) + (typename $a (union $tag (field $c f32) (field $b u32)))", + ); assert_eq!(base.representable(&other_ordering), RepEquality::Eq); assert_eq!(other_ordering.representable(&base), RepEquality::Eq); assert_eq!( diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 4bb92aa89..17be21e82 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -3,6 +3,7 @@ use crate::{ parser::{ CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + VariantSyntax, }, BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, @@ -10,7 +11,7 @@ use crate::{ ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, }; -use std::collections::HashMap; +use std::collections::{hash_map, HashMap}; use std::path::Path; use std::rc::Rc; use thiserror::Error; @@ -43,6 +44,12 @@ pub enum ValidationError { InvalidFirstResultType { location: Location }, #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] AnonymousStructure { location: Location }, + #[error("Invalid union field `{name}`: {reason}")] + InvalidUnionField { + name: String, + reason: String, + location: Location, + }, } impl ValidationError { @@ -54,7 +61,8 @@ impl ValidationError { | Recursive { location, .. } | InvalidRepr { location, .. } | InvalidFirstResultType { location, .. } - | AnonymousStructure { location, .. } => { + | AnonymousStructure { location, .. } + | InvalidUnionField { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } NameAlreadyExists { @@ -348,22 +356,100 @@ impl DocValidationScope<'_> { fn validate_union( &self, syntax: &UnionSyntax, - _span: wast::Span, + span: wast::Span, ) -> Result { let mut variant_scope = IdentValidation::new(); + let tag_id = self.get(&syntax.tag)?; + let (tag, mut variant_name_uses) = match self.doc.entries.get(&tag_id) { + Some(Entry::Typename(weak_ref)) => { + let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); + match &*named_dt.type_() { + Type::Enum(e) => { + let uses = e + .variants + .iter() + .map(|v| (v.name.clone(), false)) + .collect::>(); + Ok((named_dt, uses)) + } + other => Err(ValidationError::WrongKindName { + name: syntax.tag.name().to_string(), + location: self.location(syntax.tag.span()), + expected: "enum", + got: other.kind(), + }), + } + } + other => Err(ValidationError::WrongKindName { + name: syntax.tag.name().to_string(), + location: self.location(syntax.tag.span()), + expected: "enum", + got: match other { + Some(e) => e.kind(), + None => "unknown", + }, + }), + }?; + let variants = syntax .fields .iter() - .map(|f| { + .map(|v| { + let variant_name = match v.item { + VariantSyntax::Field(ref f) => &f.name, + VariantSyntax::Empty(ref name) => name, + }; let name = variant_scope - .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; - let docs = f.comments.docs(); + .introduce(variant_name.name(), self.location(variant_name.span()))?; + let tref = match &v.item { + VariantSyntax::Field(f) => { + Some(self.validate_datatype(&f.type_, false, variant_name.span())?) + } + VariantSyntax::Empty { .. } => None, + }; + let docs = v.comments.docs(); + match variant_name_uses.entry(name.clone()) { + hash_map::Entry::Occupied(mut e) => { + if *e.get() { + Err(ValidationError::InvalidUnionField { + name: variant_name.name().to_string(), + reason: "variant already defined".to_owned(), + location: self.location(variant_name.span()), + })?; + } else { + e.insert(true); + } + } + hash_map::Entry::Vacant { .. } => Err(ValidationError::InvalidUnionField { + name: variant_name.name().to_string(), + reason: format!( + "does not correspond to variant in tag `{}`", + tag.name.as_str() + ), + location: self.location(variant_name.span()), + })?, + } Ok(UnionVariant { name, tref, docs }) }) .collect::, _>>()?; - Ok(UnionDatatype { variants }) + let unused_variants = variant_name_uses + .iter() + .filter(|(_k, used)| **used == false) + .map(|(k, _)| k.clone()) + .collect::>(); + if !unused_variants.is_empty() { + Err(ValidationError::InvalidUnionField { + name: unused_variants + .iter() + .map(|i| i.as_str()) + .collect::>() + .join(", "), + reason: format!("missing variants from tag `{}`", tag.name.as_str()), + location: self.location(span), + })?; + } + Ok(UnionDatatype { tag, variants }) } fn validate_handle( diff --git a/proposals/clocks/tools/witx/tests/anonymous.rs b/proposals/clocks/tools/witx/tests/anonymous.rs index e1976a261..6bf11d883 100644 --- a/proposals/clocks/tools/witx/tests/anonymous.rs +++ b/proposals/clocks/tools/witx/tests/anonymous.rs @@ -12,7 +12,9 @@ fn anonymous_types() { let pointer_to_struct = witx::parse("(typename $a (@witx pointer (struct (field $b u8))))"); assert!(is_anonymous_struct_err(pointer_to_struct)); - let pointer_to_union = witx::parse("(typename $a (@witx pointer (union (field $b u8))))"); + let pointer_to_union = witx::parse( + "(typename $tag (enum u8 $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", + ); assert!(is_anonymous_struct_err(pointer_to_union)); let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum u32 $b)))"); @@ -33,7 +35,9 @@ fn anonymous_types() { let struct_in_struct = witx::parse("(typename $a (struct (field $b (struct (field $c u8)))))"); assert!(is_anonymous_struct_err(struct_in_struct)); - let union_in_struct = witx::parse("(typename $a (struct (field $b (union (field $c u8)))))"); + let union_in_struct = witx::parse( + "(typename $tag (enum u8 $c)) (typename $a (struct (field $b (union $tag (field $c u8)))))", + ); assert!(is_anonymous_struct_err(union_in_struct)); let pointer_in_struct = witx::parse("(typename $a (struct (field $b (@witx pointer u8))))"); diff --git a/proposals/clocks/tools/witx/tests/union.rs b/proposals/clocks/tools/witx/tests/union.rs new file mode 100644 index 000000000..732b5c007 --- /dev/null +++ b/proposals/clocks/tools/witx/tests/union.rs @@ -0,0 +1,183 @@ +// Every worker needs a union! Time to organize +use witx::{Id, Representable}; + +#[test] +fn one_variant_union() { + let d = witx::parse( + "(typename $tag (enum u8 $c)) + (typename $u (union $tag (field $c u8)))", + ); + assert!(d.is_ok()); +} + +#[test] +fn two_variant_union() { + let d1 = witx::parse( + "(typename $tag (enum u8 $a $b)) + (typename $u (union $tag (field $a u8) (field $b u16)))", + ); + assert!(d1.is_ok(), "d1 is ok"); + + // Fields can come in whatever order: + let d2 = witx::parse( + "(typename $tag (enum u8 $a $b)) + (typename $u (union $tag (field $b u16) (field $a u8)))", + ); + assert!(d2.is_ok(), "d2 is ok"); + + // These two unions should be represented the same: + let u1 = d1.unwrap().typename(&Id::new("u")).unwrap().type_(); + let u2 = d2.unwrap().typename(&Id::new("u")).unwrap().type_(); + + assert_eq!( + u1.representable(&u2), + witx::RepEquality::Eq, + "u1 can represent u2" + ); + assert_eq!( + u2.representable(&u1), + witx::RepEquality::Eq, + "u2 can represent u1" + ); + + // Tag order doesnt matter for validation, but does for rep equality + let d3 = witx::parse( + "(typename $tag (enum u8 $b $a)) + (typename $u (union $tag (field $b u16) (field $a u8)))", + ); + assert!(d3.is_ok(), "d2 is ok"); + let u3 = d3.unwrap().typename(&Id::new("u")).unwrap().type_(); + assert_eq!( + u3.representable(&u1), + witx::RepEquality::NotEq, + "u3 cannot represent u1" + ); +} + +#[test] +fn empty_variant_unions() { + let d1 = witx::parse( + "(typename $tag (enum u8 $a $b)) + (typename $u (union $tag (empty $a) (field $b u16)))", + ); + assert!(d1.is_ok(), "d1 is ok"); + + let d2 = witx::parse( + "(typename $tag (enum u8 $a $b)) + (typename $u (union $tag (empty $a) (empty $b)))", + ); + assert!(d2.is_ok(), "d2 is ok"); +} + +#[test] +fn many_variant_unions() { + let d1 = witx::parse( + "(typename $tag (enum u32 $a $b $c $d $e $f $g $h $i $j $k $l $m)) + (typename $u + (union $tag + (field $a u8) + (field $b u16) + (field $c u32) + (field $d u64) + (field $e s8) + (field $f s16) + (field $g s32) + (field $h s64) + (field $i f32) + (field $j f64) + (field $k (@witx usize)) + (field $l char8) + (empty $m) + ) + )", + ); + assert!(d1.is_ok(), "d1 is ok"); +} + +#[test] +fn no_tag_union() { + let d = witx::parse("(typename $u (union $tag (field $a u8) (field $b u16)))"); + assert!(d.is_err()); +} + +#[test] +fn wrong_kind_tag_union() { + let d = witx::parse( + "(typename $tag u32) + (typename $u (union $tag (field $a u8) (field $b u16)))", + ); + let (expected, got) = wrong_kind_name_err(d).expect("wrong kind of tag"); + assert_eq!(expected, "enum"); + assert_eq!(got, "builtin"); +} + +#[test] +fn bad_field_unions() { + let d = witx::parse( + "(typename $tag (enum u8 $c)) + (typename $u (union $tag (field $b u8)))", + ); + let (name, reason) = union_field_err(d).expect("bad field union 1"); + assert_eq!(name, "b", "bad field name union 1"); + assert_eq!( + reason, "does not correspond to variant in tag `tag`", + "reason union 1" + ); + + let d = witx::parse( + "(typename $tag (enum u8 $c)) + (typename $u (union $tag (field $c f32) (field $b u8)))", + ); + let (name, reason) = union_field_err(d).expect("bad field union 2"); + assert_eq!(name, "b", "bad field name union 2"); + assert_eq!( + reason, "does not correspond to variant in tag `tag`", + "reason union 2" + ); + + let d = witx::parse( + "(typename $tag (enum u8 $c $d)) + (typename $u (union $tag (field $c f32)))", + ); + let (name, reason) = union_field_err(d).expect("bad field union 3"); + assert_eq!(name, "d", "bad field name union 3"); + assert_eq!(reason, "missing variants from tag `tag`", "reason union 3"); +} + +fn wrong_kind_name_err( + r: Result, +) -> Option<(&'static str, &'static str)> { + match r { + Err(witx::WitxError::Validation(witx::ValidationError::WrongKindName { + expected, + got, + .. + })) => Some((expected, got)), + Err(e) => { + eprintln!("expected WrongKindName ValidationError, got: {:?}", e); + None + } + Ok(_) => { + eprintln!("expected WrongKindName ValidationError: Ok(witx::Document)"); + None + } + } +} + +fn union_field_err(r: Result) -> Option<(String, String)> { + match r { + Err(witx::WitxError::Validation(witx::ValidationError::InvalidUnionField { + name, + reason, + .. + })) => Some((name, reason)), + Err(e) => { + eprintln!("expected InvalidUnionField ValidationError, got: {:?}", e); + None + } + Ok(_) => { + eprintln!("expected InvalidUnionField ValidationError, got: Ok(witx::Document)"); + None + } + } +} From 9f4453ea63f1de0235f0aae6d59f95064d64a7dd Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 18 Feb 2020 12:31:35 -0800 Subject: [PATCH 0551/1772] Change witx unions to be tagged (#220) * unions are now tagged by an enum * union fields may be empty. TODO: write tests * unions: add more tests. compute layout. * snapshot 0: translate untagged union syntax to tagged union syntax * snapshot: update from untagged union to tagged union syntax * snapshot: update docs * snapshot 0: update docs * ephemeral: translate untagged unions to tagged unions * render: fix union output * bump witx to 0.8.0 - this is definitely semver breaking * snapshot: I forgot to delete the tag field `subscription.type` * regen docs * unionlayout: derive the usual suspects * snapshot 1 and 0: put tag back in event struct, flatten event_u prior to this PR, event_u was a union with only one variant fd_readwrite. the change into tagged union ended up changing the memory layout of the event struct. so, rather than use tagged unions in the event struct, we just use a struct that you ignore in the case of the clock event, which has the same ABI as previously. in ephemeral, we use a tagged union for events, because we dont have any ABI stability guarantees to maintain there. * layout: refactor so we have impls for NamedType and Type too * ast: change tag of UnionDatatype to be a NamedType this is much more convenient for consumers, and it reflects the requirement of the syntax to provide an Id * fixup docs --- proposals/random/phases/ephemeral/docs.md | 41 ++-- .../phases/ephemeral/witx/typenames.witx | 38 ++-- .../random/phases/old/snapshot_0/docs.md | 48 ++--- .../phases/old/snapshot_0/witx/typenames.witx | 45 ++--- proposals/random/phases/snapshot/docs.md | 42 ++-- .../phases/snapshot/witx/typenames.witx | 42 ++-- proposals/random/tools/witx/Cargo.toml | 2 +- proposals/random/tools/witx/src/ast.rs | 3 +- proposals/random/tools/witx/src/docs/ast.rs | 6 +- proposals/random/tools/witx/src/layout.rs | 95 +++++++-- proposals/random/tools/witx/src/parser.rs | 33 +++- proposals/random/tools/witx/src/render.rs | 25 ++- .../random/tools/witx/src/representation.rs | 45 ++++- proposals/random/tools/witx/src/validate.rs | 102 +++++++++- .../random/tools/witx/tests/anonymous.rs | 8 +- proposals/random/tools/witx/tests/union.rs | 183 ++++++++++++++++++ 16 files changed, 526 insertions(+), 232 deletions(-) create mode 100644 proposals/random/tools/witx/tests/union.rs diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 42f4f4879..3834160fc 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -688,8 +688,11 @@ The state of the file descriptor. The contents of an $event. ### Union variants -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): +- `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) + +- `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) + +- `clock` ## `event`: Struct An event that occurred. @@ -701,11 +704,8 @@ User-provided value that got attached to [`subscription::userdata`](#subscriptio - `error`: [`errno`](#errno) If non-zero, an error that occurred while processing the subscription request. -- `type`: [`eventtype`](#eventtype) -The type of the event that occurred. - - `u`: [`event_u`](#event_u) -The contents of the event. +The type of the event that occurred, and the contents of the event ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in @@ -749,10 +749,10 @@ The contents of a $subscription. ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) -When type is [`eventtype::clock`](#eventtype.clock): -- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): +- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) ## `subscription`: Struct Subscription to an event. @@ -762,11 +762,8 @@ Subscription to an event. User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). -- `type`: [`eventtype`](#eventtype) -The type of the event to which to subscribe. - - `u`: [`subscription_u`](#subscription_u) -The contents of the subscription. +The type of the event to which to subscribe, and the contents of the subscription. ## `exitcode`: `u32` Exit code generated by a process when exiting. @@ -816,22 +813,12 @@ The contents of a $prestat when its $pr_type is [`preopentype::dir`](#preopentyp - `pr_name_len`: [`size`](#size) The length of the directory name for use with `fd_prestat_dir_name`. -## `prestat_u`: Union -The contents of an $prestat. - -### Union variants -- `dir`: [`prestat_dir`](#prestat_dir) -When $pr_type of the $prestat is [`preopentype::dir`](#preopentype.dir): - -## `prestat`: Struct +## `prestat`: Union Information about a pre-opened capability. -### Struct members -- `pr_type`: [`preopentype`](#preopentype) -The type of the pre-opened capability. - -- `u`: [`prestat_u`](#prestat_u) -The contents of the information. +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) +When type is [`preopentype::dir`](#preopentype.dir): # Modules ## wasi_ephemeral_args diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 269d203d5..c37ab2e7b 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -560,9 +560,10 @@ ;;; The contents of an $event. (typename $event_u - (union - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $event_fd_readwrite) + (union $eventtype + (field $fd_read $event_fd_readwrite) + (field $fd_write $event_fd_readwrite) + (empty $clock) ) ) @@ -573,9 +574,7 @@ (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno) - ;;; The type of the event that occurred. - (field $type $eventtype) - ;;; The contents of the event. + ;;; The type of the event that occurred, and the contents of the event (field $u $event_u) ) ) @@ -619,11 +618,10 @@ ;;; The contents of a $subscription. (typename $subscription_u - (union - ;;; When type is `eventtype::clock`: + (union $eventtype (field $clock $subscription_clock) - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $subscription_fd_readwrite) + (field $fd_read $subscription_fd_readwrite) + (field $fd_write $subscription_fd_readwrite) ) ) @@ -633,9 +631,7 @@ ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) - ;;; The type of the event to which to subscribe. - (field $type $eventtype) - ;;; The contents of the subscription. + ;;; The type of the event to which to subscribe, and the contents of the subscription. (field $u $subscription_u) ) ) @@ -691,20 +687,10 @@ ) ) -;;; The contents of an $prestat. -(typename $prestat_u - (union - ;;; When $pr_type of the $prestat is `preopentype::dir`: - (field $dir $prestat_dir) - ) -) - ;;; Information about a pre-opened capability. (typename $prestat - (struct - ;;; The type of the pre-opened capability. - (field $pr_type $preopentype) - ;;; The contents of the information. - (field $u $prestat_u) + (union $preopentype + ;;; When type is `preopentype::dir`: + (field $dir $prestat_dir) ) ) diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index 360cff906..3466d13ad 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -627,8 +627,8 @@ The state of the file descriptor subscribed to with The peer of this socket has closed or disconnected. ## `event_fd_readwrite`: Struct -The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). +The contents of an $event for the [`eventtype::fd_read`](#eventtype.fd_read) and +[`eventtype::fd_write`](#eventtype.fd_write) variants ### Struct members - `nbytes`: [`filesize`](#filesize) @@ -637,13 +637,6 @@ The number of bytes available for reading or writing. - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. -## `event_u`: Union -The contents of an $event. - -### Union variants -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): - ## `event`: Struct An event that occurred. @@ -655,10 +648,11 @@ User-provided value that got attached to [`subscription::userdata`](#subscriptio If non-zero, an error that occurred while processing the subscription request. - `type`: [`eventtype`](#eventtype) -The type of the event that occurred. +The type of event that occured -- `u`: [`event_u`](#event_u) -The contents of the event. +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in @@ -693,7 +687,7 @@ to coalesce with other events. Flags specifying whether the timeout is absolute or relative ## `subscription_fd_readwrite`: Struct -The contents of a $subscription when type is type is +The contents of a $subscription when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -705,10 +699,10 @@ The contents of a $subscription. ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) -When type is [`eventtype::clock`](#eventtype.clock): -- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): +- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) ## `subscription`: Struct Subscription to an event. @@ -718,11 +712,8 @@ Subscription to an event. User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). -- `type`: [`eventtype`](#eventtype) -The type of the event to which to subscribe. - - `u`: [`subscription_u`](#subscription_u) -The contents of the subscription. +The type of the event to which to subscribe. ## `exitcode`: `u32` Exit code generated by a process when exiting. @@ -900,22 +891,11 @@ The contents of a $prestat when type is `PREOPENTYPE_DIR`. - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). -## `prestat_u`: Union -The contents of an $prestat. - -### Union variants -- `dir`: [`prestat_dir`](#prestat_dir) -When type is `PREOPENTYPE_DIR`: - -## `prestat`: Struct +## `prestat`: Union Information about a pre-opened capability. -### Struct members -- `pr_type`: [`preopentype`](#preopentype) -The type of the pre-opened capability. - -- `u`: [`prestat_u`](#prestat_u) -The contents of the information. +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) # Modules ## wasi_unstable diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx index 9a7fc0bb2..493bda050 100644 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/random/phases/old/snapshot_0/witx/typenames.witx @@ -503,8 +503,8 @@ ) ) -;;; The contents of an $event when type is `eventtype::fd_read` or -;;; `eventtype::fd_write`. +;;; The contents of an $event for the `eventtype::fd_read` and +;;; `eventtype::fd_write` variants (typename $event_fd_readwrite (struct ;;; The number of bytes available for reading or writing. @@ -514,14 +514,6 @@ ) ) -;;; The contents of an $event. -(typename $event_u - (union - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $event_fd_readwrite) - ) -) - ;;; An event that occurred. (typename $event (struct @@ -529,10 +521,11 @@ (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno) - ;;; The type of the event that occurred. + ;;; The type of event that occured (field $type $eventtype) - ;;; The contents of the event. - (field $u $event_u) + ;;; The contents of the event, if it is an `eventtype::fd_read` or + ;;; `eventtype::fd_write`. `eventtype::clock` events ignore this field. + (field $fd_readwrite $event_fd_readwrite) ) ) @@ -566,7 +559,7 @@ ) ) -;;; The contents of a $subscription when type is type is +;;; The contents of a $subscription when the variant is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite (struct @@ -577,11 +570,10 @@ ;;; The contents of a $subscription. (typename $subscription_u - (union - ;;; When type is `eventtype::clock`: + (union $eventtype (field $clock $subscription_clock) - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $subscription_fd_readwrite) + (field $fd_read $subscription_fd_readwrite) + (field $fd_write $subscription_fd_readwrite) ) ) @@ -592,8 +584,6 @@ ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) ;;; The type of the event to which to subscribe. - (field $type $eventtype) - ;;; The contents of the subscription. (field $u $subscription_u) ) ) @@ -748,20 +738,9 @@ ) ) -;;; The contents of an $prestat. -(typename $prestat_u - (union - ;;; When type is `PREOPENTYPE_DIR`: - (field $dir $prestat_dir) - ) -) - ;;; Information about a pre-opened capability. (typename $prestat - (struct - ;;; The type of the pre-opened capability. - (field $pr_type $preopentype) - ;;; The contents of the information. - (field $u $prestat_u) + (union $preopentype + (field $dir $prestat_dir) ) ) diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index 09575008e..0b3dec378 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -639,13 +639,6 @@ The number of bytes available for reading or writing. - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. -## `event_u`: Union -The contents of an $event. - -### Union variants -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): - ## `event`: Struct An event that occurred. @@ -657,10 +650,11 @@ User-provided value that got attached to [`subscription::userdata`](#subscriptio If non-zero, an error that occurred while processing the subscription request. - `type`: [`eventtype`](#eventtype) -The type of the event that occurred. +The type of event that occured -- `u`: [`event_u`](#event_u) -The contents of the event. +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in @@ -704,10 +698,10 @@ The contents of a $subscription. ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) -When type is [`eventtype::clock`](#eventtype.clock): -- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): +- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) ## `subscription`: Struct Subscription to an event. @@ -717,11 +711,8 @@ Subscription to an event. User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). -- `type`: [`eventtype`](#eventtype) -The type of the event to which to subscribe. - - `u`: [`subscription_u`](#subscription_u) -The contents of the subscription. +The type of the event to which to subscribe, and its contents ## `exitcode`: `u32` Exit code generated by a process when exiting. @@ -899,22 +890,11 @@ The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). -## `prestat_u`: Union -The contents of an $prestat. - -### Union variants -- `dir`: [`prestat_dir`](#prestat_dir) -When type is [`preopentype::dir`](#preopentype.dir): - -## `prestat`: Struct +## `prestat`: Union Information about a pre-opened capability. -### Struct members -- `pr_type`: [`preopentype`](#preopentype) -The type of the pre-opened capability. - -- `u`: [`prestat_u`](#prestat_u) -The contents of the information. +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) # Modules ## wasi_snapshot_preview1 diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx index ee8c652ec..eb8cb8c64 100644 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -516,14 +516,6 @@ ) ) -;;; The contents of an $event. -(typename $event_u - (union - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $event_fd_readwrite) - ) -) - ;;; An event that occurred. (typename $event (struct @@ -531,10 +523,11 @@ (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno) - ;;; The type of the event that occurred. + ;;; The type of event that occured (field $type $eventtype) - ;;; The contents of the event. - (field $u $event_u) + ;;; The contents of the event, if it is an `eventtype::fd_read` or + ;;; `eventtype::fd_write`. `eventtype::clock` events ignore this field. + (field $fd_readwrite $event_fd_readwrite) ) ) @@ -577,11 +570,10 @@ ;;; The contents of a $subscription. (typename $subscription_u - (union - ;;; When type is `eventtype::clock`: + (union $eventtype (field $clock $subscription_clock) - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $subscription_fd_readwrite) + (field $fd_read $subscription_fd_readwrite) + (field $fd_write $subscription_fd_readwrite) ) ) @@ -591,9 +583,7 @@ ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) - ;;; The type of the event to which to subscribe. - (field $type $eventtype) - ;;; The contents of the subscription. + ;;; The type of the event to which to subscribe, and its contents (field $u $subscription_u) ) ) @@ -748,20 +738,10 @@ ) ) -;;; The contents of an $prestat. -(typename $prestat_u - (union - ;;; When type is `preopentype::dir`: - (field $dir $prestat_dir) - ) -) - ;;; Information about a pre-opened capability. (typename $prestat - (struct - ;;; The type of the pre-opened capability. - (field $pr_type $preopentype) - ;;; The contents of the information. - (field $u $prestat_u) + (union $preopentype + (field $dir $prestat_dir) ) ) + diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 959c22143..32f0cbea9 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.7.0" +version = "0.8.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index fcb33ad44..564d4ea1d 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -247,13 +247,14 @@ pub struct StructMember { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionDatatype { + pub tag: Rc, pub variants: Vec, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionVariant { pub name: Id, - pub tref: TypeRef, + pub tref: Option, pub docs: String, } diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index a5f2ca952..10dc9f7c2 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -211,7 +211,11 @@ impl ToMarkdown for UnionDatatype { name, &variant.docs, )); - variant.tref.generate(n.clone()); + if let Some(ref tref) = variant.tref { + tref.generate(n.clone()); + } else { + n.content_ref_mut::().r#type = None; + } } node.content_ref_mut::().r#type = Some(MdType::Union); diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index cd3bd7da9..3e2f6ee09 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -22,7 +22,37 @@ impl TypeRef { if let Some(hit) = cache.get(self) { return *hit; } - let layout = match &*self.type_() { + let layout = match &self { + TypeRef::Name(nt) => nt.layout(cache), + TypeRef::Value(v) => v.layout(cache), + }; + cache.insert(self.clone(), layout); + layout + } +} + +impl Layout for TypeRef { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + +impl NamedType { + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + self.tref.layout(cache) + } +} +impl Layout for NamedType { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + +impl Type { + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + match &self { Type::Enum(e) => e.repr.mem_size_align(), Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), @@ -32,18 +62,17 @@ impl TypeRef { Type::Array { .. } => BuiltinType::String.mem_size_align(), Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), - }; - cache.insert(self.clone(), layout); - layout + } } } -impl Layout for TypeRef { +impl Layout for Type { fn mem_size_align(&self) -> SizeAlign { let mut cache = HashMap::new(); self.layout(&mut cache) } } + impl Layout for IntRepr { fn mem_size_align(&self) -> SizeAlign { match self { @@ -132,25 +161,51 @@ mod test { } } +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct UnionLayout { + pub tag_size: usize, + pub tag_align: usize, + pub contents_offset: usize, + pub contents_size: usize, + pub contents_align: usize, +} + +impl Layout for UnionLayout { + fn mem_size_align(&self) -> SizeAlign { + let align = std::cmp::max(self.tag_align, self.contents_align); + let size = align_to(self.contents_offset + self.contents_size, align); + SizeAlign { size, align } + } +} + impl UnionDatatype { - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - let sas = self + pub fn union_layout(&self) -> UnionLayout { + let mut cache = HashMap::new(); + self.union_layout_(&mut cache) + } + fn union_layout_(&self, cache: &mut HashMap) -> UnionLayout { + let tag = self.tag.layout(cache); + + let variant_sas = self .variants .iter() - .map(|v| v.tref.layout(cache)) + .filter_map(|v| v.tref.as_ref().map(|t| t.layout(cache))) .collect::>(); - let size = sas - .iter() - .map(|sa| sa.size) - .max() - .expect("nonzero variants"); - let align = sas - .iter() - .map(|sa| sa.align) - .max() - .expect("nonzero variants"); - let size = align_to(size, align); - SizeAlign { size, align } + + let contents_size = variant_sas.iter().map(|sa| sa.size).max().unwrap_or(0); + let contents_align = variant_sas.iter().map(|sa| sa.align).max().unwrap_or(1); + + UnionLayout { + tag_size: tag.size, + tag_align: tag.align, + contents_offset: align_to(tag.size, contents_align), + contents_size, + contents_align, + } + } + + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + self.union_layout_(cache).mem_size_align() } } diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 08bc9af5b..85f8c8d09 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -24,6 +24,7 @@ mod kw { wast::custom_keyword!(f32); wast::custom_keyword!(f64); wast::custom_keyword!(field); + wast::custom_keyword!(empty); wast::custom_keyword!(flags); wast::custom_keyword!(handle); wast::custom_keyword!(int); @@ -477,20 +478,48 @@ impl<'a> Parse<'a> for FieldSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum VariantSyntax<'a> { + Field(FieldSyntax<'a>), + Empty(wast::Id<'a>), +} + +impl<'a> Parse<'a> for VariantSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parens(|p| { + let mut l = p.lookahead1(); + if l.peek::() { + parser.parse::()?; + let name = p.parse()?; + let type_ = p.parse()?; + Ok(VariantSyntax::Field(FieldSyntax { name, type_ })) + } else if l.peek::() { + parser.parse::()?; + let name = p.parse()?; + Ok(VariantSyntax::Empty(name)) + } else { + Err(l.error()) + } + }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionSyntax<'a> { - pub fields: Vec>>, + pub tag: wast::Id<'a>, + pub fields: Vec>>, } impl<'a> Parse<'a> for UnionSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; + let tag = parser.parse()?; let mut fields = Vec::new(); fields.push(parser.parse()?); while !parser.is_empty() { fields.push(parser.parse()?); } - Ok(UnionSyntax { fields }) + Ok(UnionSyntax { tag, fields }) } } diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index a1a6ff58a..64b429f8b 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -206,19 +206,26 @@ impl StructDatatype { impl UnionDatatype { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("union")]; + let header = vec![SExpr::word("union"), self.tag.name.to_sexpr()]; let variants = self .variants .iter() .map(|v| { - SExpr::docs( - &v.docs, - SExpr::Vec(vec![ - SExpr::word("field"), - v.name.to_sexpr(), - v.tref.to_sexpr(), - ]), - ) + if let Some(ref tref) = v.tref { + SExpr::docs( + &v.docs, + SExpr::Vec(vec![ + SExpr::word("field"), + v.name.to_sexpr(), + tref.to_sexpr(), + ]), + ) + } else { + SExpr::docs( + &v.docs, + SExpr::Vec(vec![SExpr::word("empty"), v.name.to_sexpr()]), + ) + } }) .collect::>(); SExpr::Vec([header, variants].concat()) diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs index 3bdd6a792..0f12217af 100644 --- a/proposals/random/tools/witx/src/representation.rs +++ b/proposals/random/tools/witx/src/representation.rs @@ -177,7 +177,21 @@ impl Representable for UnionDatatype { } for v in self.variants.iter() { if let Some(byv) = by.variants.iter().find(|byv| byv.name == v.name) { - if v.tref.type_().representable(&*byv.tref.type_()) != RepEquality::Eq { + if v.tref.is_none() && byv.tref.is_none() { + // Both empty is OK + } else if v.tref.is_some() && byv.tref.is_some() { + if v.tref + .as_ref() + .unwrap() + .type_() + .representable(&*byv.tref.as_ref().unwrap().type_()) + != RepEquality::Eq + { + // Fields must be Eq + return RepEquality::NotEq; + } + } else { + // Either one empty means not representable return RepEquality::NotEq; } } else { @@ -185,9 +199,19 @@ impl Representable for UnionDatatype { } } if by.variants.len() > self.variants.len() { - RepEquality::Superset + // By is a superset of self only if the tags are as well: + if self.tag.type_().representable(&*by.tag.type_()) == RepEquality::Superset { + RepEquality::Superset + } else { + RepEquality::NotEq + } } else { - RepEquality::Eq + // By and self have matching variants, so they are equal if tags are: + if self.tag.type_().representable(&*by.tag.type_()) == RepEquality::Eq { + RepEquality::Eq + } else { + RepEquality::NotEq + } } } } @@ -287,16 +311,25 @@ mod test { #[test] fn union() { - let base = def_type("a", "(typename $a (union (field $b u32) (field $c f32)))"); + let base = def_type( + "a", + "(typename $tag (enum u8 $b $c)) + (typename $a (union $tag (field $b u32) (field $c f32)))", + ); let extra_variant = def_type( "a", - "(typename $a (union (field $b u32) (field $c f32) (field $d f64)))", + "(typename $tag (enum u8 $b $c $d)) + (typename $a (union $tag (field $b u32) (field $c f32) (field $d f64)))", ); assert_eq!(base.representable(&extra_variant), RepEquality::Superset); assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); - let other_ordering = def_type("a", "(typename $a (union (field $c f32) (field $b u32)))"); + let other_ordering = def_type( + "a", + "(typename $tag (enum u8 $b $c)) + (typename $a (union $tag (field $c f32) (field $b u32)))", + ); assert_eq!(base.representable(&other_ordering), RepEquality::Eq); assert_eq!(other_ordering.representable(&base), RepEquality::Eq); assert_eq!( diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 4bb92aa89..17be21e82 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -3,6 +3,7 @@ use crate::{ parser::{ CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + VariantSyntax, }, BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, @@ -10,7 +11,7 @@ use crate::{ ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, }; -use std::collections::HashMap; +use std::collections::{hash_map, HashMap}; use std::path::Path; use std::rc::Rc; use thiserror::Error; @@ -43,6 +44,12 @@ pub enum ValidationError { InvalidFirstResultType { location: Location }, #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] AnonymousStructure { location: Location }, + #[error("Invalid union field `{name}`: {reason}")] + InvalidUnionField { + name: String, + reason: String, + location: Location, + }, } impl ValidationError { @@ -54,7 +61,8 @@ impl ValidationError { | Recursive { location, .. } | InvalidRepr { location, .. } | InvalidFirstResultType { location, .. } - | AnonymousStructure { location, .. } => { + | AnonymousStructure { location, .. } + | InvalidUnionField { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } NameAlreadyExists { @@ -348,22 +356,100 @@ impl DocValidationScope<'_> { fn validate_union( &self, syntax: &UnionSyntax, - _span: wast::Span, + span: wast::Span, ) -> Result { let mut variant_scope = IdentValidation::new(); + let tag_id = self.get(&syntax.tag)?; + let (tag, mut variant_name_uses) = match self.doc.entries.get(&tag_id) { + Some(Entry::Typename(weak_ref)) => { + let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); + match &*named_dt.type_() { + Type::Enum(e) => { + let uses = e + .variants + .iter() + .map(|v| (v.name.clone(), false)) + .collect::>(); + Ok((named_dt, uses)) + } + other => Err(ValidationError::WrongKindName { + name: syntax.tag.name().to_string(), + location: self.location(syntax.tag.span()), + expected: "enum", + got: other.kind(), + }), + } + } + other => Err(ValidationError::WrongKindName { + name: syntax.tag.name().to_string(), + location: self.location(syntax.tag.span()), + expected: "enum", + got: match other { + Some(e) => e.kind(), + None => "unknown", + }, + }), + }?; + let variants = syntax .fields .iter() - .map(|f| { + .map(|v| { + let variant_name = match v.item { + VariantSyntax::Field(ref f) => &f.name, + VariantSyntax::Empty(ref name) => name, + }; let name = variant_scope - .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; - let docs = f.comments.docs(); + .introduce(variant_name.name(), self.location(variant_name.span()))?; + let tref = match &v.item { + VariantSyntax::Field(f) => { + Some(self.validate_datatype(&f.type_, false, variant_name.span())?) + } + VariantSyntax::Empty { .. } => None, + }; + let docs = v.comments.docs(); + match variant_name_uses.entry(name.clone()) { + hash_map::Entry::Occupied(mut e) => { + if *e.get() { + Err(ValidationError::InvalidUnionField { + name: variant_name.name().to_string(), + reason: "variant already defined".to_owned(), + location: self.location(variant_name.span()), + })?; + } else { + e.insert(true); + } + } + hash_map::Entry::Vacant { .. } => Err(ValidationError::InvalidUnionField { + name: variant_name.name().to_string(), + reason: format!( + "does not correspond to variant in tag `{}`", + tag.name.as_str() + ), + location: self.location(variant_name.span()), + })?, + } Ok(UnionVariant { name, tref, docs }) }) .collect::, _>>()?; - Ok(UnionDatatype { variants }) + let unused_variants = variant_name_uses + .iter() + .filter(|(_k, used)| **used == false) + .map(|(k, _)| k.clone()) + .collect::>(); + if !unused_variants.is_empty() { + Err(ValidationError::InvalidUnionField { + name: unused_variants + .iter() + .map(|i| i.as_str()) + .collect::>() + .join(", "), + reason: format!("missing variants from tag `{}`", tag.name.as_str()), + location: self.location(span), + })?; + } + Ok(UnionDatatype { tag, variants }) } fn validate_handle( diff --git a/proposals/random/tools/witx/tests/anonymous.rs b/proposals/random/tools/witx/tests/anonymous.rs index e1976a261..6bf11d883 100644 --- a/proposals/random/tools/witx/tests/anonymous.rs +++ b/proposals/random/tools/witx/tests/anonymous.rs @@ -12,7 +12,9 @@ fn anonymous_types() { let pointer_to_struct = witx::parse("(typename $a (@witx pointer (struct (field $b u8))))"); assert!(is_anonymous_struct_err(pointer_to_struct)); - let pointer_to_union = witx::parse("(typename $a (@witx pointer (union (field $b u8))))"); + let pointer_to_union = witx::parse( + "(typename $tag (enum u8 $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", + ); assert!(is_anonymous_struct_err(pointer_to_union)); let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum u32 $b)))"); @@ -33,7 +35,9 @@ fn anonymous_types() { let struct_in_struct = witx::parse("(typename $a (struct (field $b (struct (field $c u8)))))"); assert!(is_anonymous_struct_err(struct_in_struct)); - let union_in_struct = witx::parse("(typename $a (struct (field $b (union (field $c u8)))))"); + let union_in_struct = witx::parse( + "(typename $tag (enum u8 $c)) (typename $a (struct (field $b (union $tag (field $c u8)))))", + ); assert!(is_anonymous_struct_err(union_in_struct)); let pointer_in_struct = witx::parse("(typename $a (struct (field $b (@witx pointer u8))))"); diff --git a/proposals/random/tools/witx/tests/union.rs b/proposals/random/tools/witx/tests/union.rs new file mode 100644 index 000000000..732b5c007 --- /dev/null +++ b/proposals/random/tools/witx/tests/union.rs @@ -0,0 +1,183 @@ +// Every worker needs a union! Time to organize +use witx::{Id, Representable}; + +#[test] +fn one_variant_union() { + let d = witx::parse( + "(typename $tag (enum u8 $c)) + (typename $u (union $tag (field $c u8)))", + ); + assert!(d.is_ok()); +} + +#[test] +fn two_variant_union() { + let d1 = witx::parse( + "(typename $tag (enum u8 $a $b)) + (typename $u (union $tag (field $a u8) (field $b u16)))", + ); + assert!(d1.is_ok(), "d1 is ok"); + + // Fields can come in whatever order: + let d2 = witx::parse( + "(typename $tag (enum u8 $a $b)) + (typename $u (union $tag (field $b u16) (field $a u8)))", + ); + assert!(d2.is_ok(), "d2 is ok"); + + // These two unions should be represented the same: + let u1 = d1.unwrap().typename(&Id::new("u")).unwrap().type_(); + let u2 = d2.unwrap().typename(&Id::new("u")).unwrap().type_(); + + assert_eq!( + u1.representable(&u2), + witx::RepEquality::Eq, + "u1 can represent u2" + ); + assert_eq!( + u2.representable(&u1), + witx::RepEquality::Eq, + "u2 can represent u1" + ); + + // Tag order doesnt matter for validation, but does for rep equality + let d3 = witx::parse( + "(typename $tag (enum u8 $b $a)) + (typename $u (union $tag (field $b u16) (field $a u8)))", + ); + assert!(d3.is_ok(), "d2 is ok"); + let u3 = d3.unwrap().typename(&Id::new("u")).unwrap().type_(); + assert_eq!( + u3.representable(&u1), + witx::RepEquality::NotEq, + "u3 cannot represent u1" + ); +} + +#[test] +fn empty_variant_unions() { + let d1 = witx::parse( + "(typename $tag (enum u8 $a $b)) + (typename $u (union $tag (empty $a) (field $b u16)))", + ); + assert!(d1.is_ok(), "d1 is ok"); + + let d2 = witx::parse( + "(typename $tag (enum u8 $a $b)) + (typename $u (union $tag (empty $a) (empty $b)))", + ); + assert!(d2.is_ok(), "d2 is ok"); +} + +#[test] +fn many_variant_unions() { + let d1 = witx::parse( + "(typename $tag (enum u32 $a $b $c $d $e $f $g $h $i $j $k $l $m)) + (typename $u + (union $tag + (field $a u8) + (field $b u16) + (field $c u32) + (field $d u64) + (field $e s8) + (field $f s16) + (field $g s32) + (field $h s64) + (field $i f32) + (field $j f64) + (field $k (@witx usize)) + (field $l char8) + (empty $m) + ) + )", + ); + assert!(d1.is_ok(), "d1 is ok"); +} + +#[test] +fn no_tag_union() { + let d = witx::parse("(typename $u (union $tag (field $a u8) (field $b u16)))"); + assert!(d.is_err()); +} + +#[test] +fn wrong_kind_tag_union() { + let d = witx::parse( + "(typename $tag u32) + (typename $u (union $tag (field $a u8) (field $b u16)))", + ); + let (expected, got) = wrong_kind_name_err(d).expect("wrong kind of tag"); + assert_eq!(expected, "enum"); + assert_eq!(got, "builtin"); +} + +#[test] +fn bad_field_unions() { + let d = witx::parse( + "(typename $tag (enum u8 $c)) + (typename $u (union $tag (field $b u8)))", + ); + let (name, reason) = union_field_err(d).expect("bad field union 1"); + assert_eq!(name, "b", "bad field name union 1"); + assert_eq!( + reason, "does not correspond to variant in tag `tag`", + "reason union 1" + ); + + let d = witx::parse( + "(typename $tag (enum u8 $c)) + (typename $u (union $tag (field $c f32) (field $b u8)))", + ); + let (name, reason) = union_field_err(d).expect("bad field union 2"); + assert_eq!(name, "b", "bad field name union 2"); + assert_eq!( + reason, "does not correspond to variant in tag `tag`", + "reason union 2" + ); + + let d = witx::parse( + "(typename $tag (enum u8 $c $d)) + (typename $u (union $tag (field $c f32)))", + ); + let (name, reason) = union_field_err(d).expect("bad field union 3"); + assert_eq!(name, "d", "bad field name union 3"); + assert_eq!(reason, "missing variants from tag `tag`", "reason union 3"); +} + +fn wrong_kind_name_err( + r: Result, +) -> Option<(&'static str, &'static str)> { + match r { + Err(witx::WitxError::Validation(witx::ValidationError::WrongKindName { + expected, + got, + .. + })) => Some((expected, got)), + Err(e) => { + eprintln!("expected WrongKindName ValidationError, got: {:?}", e); + None + } + Ok(_) => { + eprintln!("expected WrongKindName ValidationError: Ok(witx::Document)"); + None + } + } +} + +fn union_field_err(r: Result) -> Option<(String, String)> { + match r { + Err(witx::WitxError::Validation(witx::ValidationError::InvalidUnionField { + name, + reason, + .. + })) => Some((name, reason)), + Err(e) => { + eprintln!("expected InvalidUnionField ValidationError, got: {:?}", e); + None + } + Ok(_) => { + eprintln!("expected InvalidUnionField ValidationError, got: Ok(witx::Document)"); + None + } + } +} From 23f233b38eeee66e94ead1cabe09bc3c5b0a946b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 18 Feb 2020 12:31:35 -0800 Subject: [PATCH 0552/1772] Change witx unions to be tagged (#220) * unions are now tagged by an enum * union fields may be empty. TODO: write tests * unions: add more tests. compute layout. * snapshot 0: translate untagged union syntax to tagged union syntax * snapshot: update from untagged union to tagged union syntax * snapshot: update docs * snapshot 0: update docs * ephemeral: translate untagged unions to tagged unions * render: fix union output * bump witx to 0.8.0 - this is definitely semver breaking * snapshot: I forgot to delete the tag field `subscription.type` * regen docs * unionlayout: derive the usual suspects * snapshot 1 and 0: put tag back in event struct, flatten event_u prior to this PR, event_u was a union with only one variant fd_readwrite. the change into tagged union ended up changing the memory layout of the event struct. so, rather than use tagged unions in the event struct, we just use a struct that you ignore in the case of the clock event, which has the same ABI as previously. in ephemeral, we use a tagged union for events, because we dont have any ABI stability guarantees to maintain there. * layout: refactor so we have impls for NamedType and Type too * ast: change tag of UnionDatatype to be a NamedType this is much more convenient for consumers, and it reflects the requirement of the syntax to provide an Id * fixup docs --- proposals/filesystem/phases/ephemeral/docs.md | 41 ++-- .../phases/ephemeral/witx/typenames.witx | 38 ++-- .../filesystem/phases/old/snapshot_0/docs.md | 48 ++--- .../phases/old/snapshot_0/witx/typenames.witx | 45 ++--- proposals/filesystem/phases/snapshot/docs.md | 42 ++-- .../phases/snapshot/witx/typenames.witx | 42 ++-- proposals/filesystem/tools/witx/Cargo.toml | 2 +- proposals/filesystem/tools/witx/src/ast.rs | 3 +- .../filesystem/tools/witx/src/docs/ast.rs | 6 +- proposals/filesystem/tools/witx/src/layout.rs | 95 +++++++-- proposals/filesystem/tools/witx/src/parser.rs | 33 +++- proposals/filesystem/tools/witx/src/render.rs | 25 ++- .../tools/witx/src/representation.rs | 45 ++++- .../filesystem/tools/witx/src/validate.rs | 102 +++++++++- .../filesystem/tools/witx/tests/anonymous.rs | 8 +- .../filesystem/tools/witx/tests/union.rs | 183 ++++++++++++++++++ 16 files changed, 526 insertions(+), 232 deletions(-) create mode 100644 proposals/filesystem/tools/witx/tests/union.rs diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 42f4f4879..3834160fc 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -688,8 +688,11 @@ The state of the file descriptor. The contents of an $event. ### Union variants -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): +- `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) + +- `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) + +- `clock` ## `event`: Struct An event that occurred. @@ -701,11 +704,8 @@ User-provided value that got attached to [`subscription::userdata`](#subscriptio - `error`: [`errno`](#errno) If non-zero, an error that occurred while processing the subscription request. -- `type`: [`eventtype`](#eventtype) -The type of the event that occurred. - - `u`: [`event_u`](#event_u) -The contents of the event. +The type of the event that occurred, and the contents of the event ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in @@ -749,10 +749,10 @@ The contents of a $subscription. ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) -When type is [`eventtype::clock`](#eventtype.clock): -- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): +- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) ## `subscription`: Struct Subscription to an event. @@ -762,11 +762,8 @@ Subscription to an event. User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). -- `type`: [`eventtype`](#eventtype) -The type of the event to which to subscribe. - - `u`: [`subscription_u`](#subscription_u) -The contents of the subscription. +The type of the event to which to subscribe, and the contents of the subscription. ## `exitcode`: `u32` Exit code generated by a process when exiting. @@ -816,22 +813,12 @@ The contents of a $prestat when its $pr_type is [`preopentype::dir`](#preopentyp - `pr_name_len`: [`size`](#size) The length of the directory name for use with `fd_prestat_dir_name`. -## `prestat_u`: Union -The contents of an $prestat. - -### Union variants -- `dir`: [`prestat_dir`](#prestat_dir) -When $pr_type of the $prestat is [`preopentype::dir`](#preopentype.dir): - -## `prestat`: Struct +## `prestat`: Union Information about a pre-opened capability. -### Struct members -- `pr_type`: [`preopentype`](#preopentype) -The type of the pre-opened capability. - -- `u`: [`prestat_u`](#prestat_u) -The contents of the information. +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) +When type is [`preopentype::dir`](#preopentype.dir): # Modules ## wasi_ephemeral_args diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 269d203d5..c37ab2e7b 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -560,9 +560,10 @@ ;;; The contents of an $event. (typename $event_u - (union - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $event_fd_readwrite) + (union $eventtype + (field $fd_read $event_fd_readwrite) + (field $fd_write $event_fd_readwrite) + (empty $clock) ) ) @@ -573,9 +574,7 @@ (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno) - ;;; The type of the event that occurred. - (field $type $eventtype) - ;;; The contents of the event. + ;;; The type of the event that occurred, and the contents of the event (field $u $event_u) ) ) @@ -619,11 +618,10 @@ ;;; The contents of a $subscription. (typename $subscription_u - (union - ;;; When type is `eventtype::clock`: + (union $eventtype (field $clock $subscription_clock) - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $subscription_fd_readwrite) + (field $fd_read $subscription_fd_readwrite) + (field $fd_write $subscription_fd_readwrite) ) ) @@ -633,9 +631,7 @@ ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) - ;;; The type of the event to which to subscribe. - (field $type $eventtype) - ;;; The contents of the subscription. + ;;; The type of the event to which to subscribe, and the contents of the subscription. (field $u $subscription_u) ) ) @@ -691,20 +687,10 @@ ) ) -;;; The contents of an $prestat. -(typename $prestat_u - (union - ;;; When $pr_type of the $prestat is `preopentype::dir`: - (field $dir $prestat_dir) - ) -) - ;;; Information about a pre-opened capability. (typename $prestat - (struct - ;;; The type of the pre-opened capability. - (field $pr_type $preopentype) - ;;; The contents of the information. - (field $u $prestat_u) + (union $preopentype + ;;; When type is `preopentype::dir`: + (field $dir $prestat_dir) ) ) diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index 360cff906..3466d13ad 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -627,8 +627,8 @@ The state of the file descriptor subscribed to with The peer of this socket has closed or disconnected. ## `event_fd_readwrite`: Struct -The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). +The contents of an $event for the [`eventtype::fd_read`](#eventtype.fd_read) and +[`eventtype::fd_write`](#eventtype.fd_write) variants ### Struct members - `nbytes`: [`filesize`](#filesize) @@ -637,13 +637,6 @@ The number of bytes available for reading or writing. - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. -## `event_u`: Union -The contents of an $event. - -### Union variants -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): - ## `event`: Struct An event that occurred. @@ -655,10 +648,11 @@ User-provided value that got attached to [`subscription::userdata`](#subscriptio If non-zero, an error that occurred while processing the subscription request. - `type`: [`eventtype`](#eventtype) -The type of the event that occurred. +The type of event that occured -- `u`: [`event_u`](#event_u) -The contents of the event. +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in @@ -693,7 +687,7 @@ to coalesce with other events. Flags specifying whether the timeout is absolute or relative ## `subscription_fd_readwrite`: Struct -The contents of a $subscription when type is type is +The contents of a $subscription when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -705,10 +699,10 @@ The contents of a $subscription. ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) -When type is [`eventtype::clock`](#eventtype.clock): -- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): +- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) ## `subscription`: Struct Subscription to an event. @@ -718,11 +712,8 @@ Subscription to an event. User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). -- `type`: [`eventtype`](#eventtype) -The type of the event to which to subscribe. - - `u`: [`subscription_u`](#subscription_u) -The contents of the subscription. +The type of the event to which to subscribe. ## `exitcode`: `u32` Exit code generated by a process when exiting. @@ -900,22 +891,11 @@ The contents of a $prestat when type is `PREOPENTYPE_DIR`. - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). -## `prestat_u`: Union -The contents of an $prestat. - -### Union variants -- `dir`: [`prestat_dir`](#prestat_dir) -When type is `PREOPENTYPE_DIR`: - -## `prestat`: Struct +## `prestat`: Union Information about a pre-opened capability. -### Struct members -- `pr_type`: [`preopentype`](#preopentype) -The type of the pre-opened capability. - -- `u`: [`prestat_u`](#prestat_u) -The contents of the information. +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) # Modules ## wasi_unstable diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx index 9a7fc0bb2..493bda050 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx @@ -503,8 +503,8 @@ ) ) -;;; The contents of an $event when type is `eventtype::fd_read` or -;;; `eventtype::fd_write`. +;;; The contents of an $event for the `eventtype::fd_read` and +;;; `eventtype::fd_write` variants (typename $event_fd_readwrite (struct ;;; The number of bytes available for reading or writing. @@ -514,14 +514,6 @@ ) ) -;;; The contents of an $event. -(typename $event_u - (union - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $event_fd_readwrite) - ) -) - ;;; An event that occurred. (typename $event (struct @@ -529,10 +521,11 @@ (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno) - ;;; The type of the event that occurred. + ;;; The type of event that occured (field $type $eventtype) - ;;; The contents of the event. - (field $u $event_u) + ;;; The contents of the event, if it is an `eventtype::fd_read` or + ;;; `eventtype::fd_write`. `eventtype::clock` events ignore this field. + (field $fd_readwrite $event_fd_readwrite) ) ) @@ -566,7 +559,7 @@ ) ) -;;; The contents of a $subscription when type is type is +;;; The contents of a $subscription when the variant is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite (struct @@ -577,11 +570,10 @@ ;;; The contents of a $subscription. (typename $subscription_u - (union - ;;; When type is `eventtype::clock`: + (union $eventtype (field $clock $subscription_clock) - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $subscription_fd_readwrite) + (field $fd_read $subscription_fd_readwrite) + (field $fd_write $subscription_fd_readwrite) ) ) @@ -592,8 +584,6 @@ ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) ;;; The type of the event to which to subscribe. - (field $type $eventtype) - ;;; The contents of the subscription. (field $u $subscription_u) ) ) @@ -748,20 +738,9 @@ ) ) -;;; The contents of an $prestat. -(typename $prestat_u - (union - ;;; When type is `PREOPENTYPE_DIR`: - (field $dir $prestat_dir) - ) -) - ;;; Information about a pre-opened capability. (typename $prestat - (struct - ;;; The type of the pre-opened capability. - (field $pr_type $preopentype) - ;;; The contents of the information. - (field $u $prestat_u) + (union $preopentype + (field $dir $prestat_dir) ) ) diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index 09575008e..0b3dec378 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -639,13 +639,6 @@ The number of bytes available for reading or writing. - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. -## `event_u`: Union -The contents of an $event. - -### Union variants -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): - ## `event`: Struct An event that occurred. @@ -657,10 +650,11 @@ User-provided value that got attached to [`subscription::userdata`](#subscriptio If non-zero, an error that occurred while processing the subscription request. - `type`: [`eventtype`](#eventtype) -The type of the event that occurred. +The type of event that occured -- `u`: [`event_u`](#event_u) -The contents of the event. +- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) +The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in @@ -704,10 +698,10 @@ The contents of a $subscription. ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) -When type is [`eventtype::clock`](#eventtype.clock): -- `fd_readwrite`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -When type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write): +- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) ## `subscription`: Struct Subscription to an event. @@ -717,11 +711,8 @@ Subscription to an event. User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). -- `type`: [`eventtype`](#eventtype) -The type of the event to which to subscribe. - - `u`: [`subscription_u`](#subscription_u) -The contents of the subscription. +The type of the event to which to subscribe, and its contents ## `exitcode`: `u32` Exit code generated by a process when exiting. @@ -899,22 +890,11 @@ The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). -## `prestat_u`: Union -The contents of an $prestat. - -### Union variants -- `dir`: [`prestat_dir`](#prestat_dir) -When type is [`preopentype::dir`](#preopentype.dir): - -## `prestat`: Struct +## `prestat`: Union Information about a pre-opened capability. -### Struct members -- `pr_type`: [`preopentype`](#preopentype) -The type of the pre-opened capability. - -- `u`: [`prestat_u`](#prestat_u) -The contents of the information. +### Union variants +- `dir`: [`prestat_dir`](#prestat_dir) # Modules ## wasi_snapshot_preview1 diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx index ee8c652ec..eb8cb8c64 100644 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -516,14 +516,6 @@ ) ) -;;; The contents of an $event. -(typename $event_u - (union - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $event_fd_readwrite) - ) -) - ;;; An event that occurred. (typename $event (struct @@ -531,10 +523,11 @@ (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. (field $error $errno) - ;;; The type of the event that occurred. + ;;; The type of event that occured (field $type $eventtype) - ;;; The contents of the event. - (field $u $event_u) + ;;; The contents of the event, if it is an `eventtype::fd_read` or + ;;; `eventtype::fd_write`. `eventtype::clock` events ignore this field. + (field $fd_readwrite $event_fd_readwrite) ) ) @@ -577,11 +570,10 @@ ;;; The contents of a $subscription. (typename $subscription_u - (union - ;;; When type is `eventtype::clock`: + (union $eventtype (field $clock $subscription_clock) - ;;; When type is `eventtype::fd_read` or `eventtype::fd_write`: - (field $fd_readwrite $subscription_fd_readwrite) + (field $fd_read $subscription_fd_readwrite) + (field $fd_write $subscription_fd_readwrite) ) ) @@ -591,9 +583,7 @@ ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) - ;;; The type of the event to which to subscribe. - (field $type $eventtype) - ;;; The contents of the subscription. + ;;; The type of the event to which to subscribe, and its contents (field $u $subscription_u) ) ) @@ -748,20 +738,10 @@ ) ) -;;; The contents of an $prestat. -(typename $prestat_u - (union - ;;; When type is `preopentype::dir`: - (field $dir $prestat_dir) - ) -) - ;;; Information about a pre-opened capability. (typename $prestat - (struct - ;;; The type of the pre-opened capability. - (field $pr_type $preopentype) - ;;; The contents of the information. - (field $u $prestat_u) + (union $preopentype + (field $dir $prestat_dir) ) ) + diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 959c22143..32f0cbea9 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.7.0" +version = "0.8.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index fcb33ad44..564d4ea1d 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -247,13 +247,14 @@ pub struct StructMember { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionDatatype { + pub tag: Rc, pub variants: Vec, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionVariant { pub name: Id, - pub tref: TypeRef, + pub tref: Option, pub docs: String, } diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index a5f2ca952..10dc9f7c2 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -211,7 +211,11 @@ impl ToMarkdown for UnionDatatype { name, &variant.docs, )); - variant.tref.generate(n.clone()); + if let Some(ref tref) = variant.tref { + tref.generate(n.clone()); + } else { + n.content_ref_mut::().r#type = None; + } } node.content_ref_mut::().r#type = Some(MdType::Union); diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index cd3bd7da9..3e2f6ee09 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -22,7 +22,37 @@ impl TypeRef { if let Some(hit) = cache.get(self) { return *hit; } - let layout = match &*self.type_() { + let layout = match &self { + TypeRef::Name(nt) => nt.layout(cache), + TypeRef::Value(v) => v.layout(cache), + }; + cache.insert(self.clone(), layout); + layout + } +} + +impl Layout for TypeRef { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + +impl NamedType { + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + self.tref.layout(cache) + } +} +impl Layout for NamedType { + fn mem_size_align(&self) -> SizeAlign { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } +} + +impl Type { + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + match &self { Type::Enum(e) => e.repr.mem_size_align(), Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), @@ -32,18 +62,17 @@ impl TypeRef { Type::Array { .. } => BuiltinType::String.mem_size_align(), Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), - }; - cache.insert(self.clone(), layout); - layout + } } } -impl Layout for TypeRef { +impl Layout for Type { fn mem_size_align(&self) -> SizeAlign { let mut cache = HashMap::new(); self.layout(&mut cache) } } + impl Layout for IntRepr { fn mem_size_align(&self) -> SizeAlign { match self { @@ -132,25 +161,51 @@ mod test { } } +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct UnionLayout { + pub tag_size: usize, + pub tag_align: usize, + pub contents_offset: usize, + pub contents_size: usize, + pub contents_align: usize, +} + +impl Layout for UnionLayout { + fn mem_size_align(&self) -> SizeAlign { + let align = std::cmp::max(self.tag_align, self.contents_align); + let size = align_to(self.contents_offset + self.contents_size, align); + SizeAlign { size, align } + } +} + impl UnionDatatype { - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - let sas = self + pub fn union_layout(&self) -> UnionLayout { + let mut cache = HashMap::new(); + self.union_layout_(&mut cache) + } + fn union_layout_(&self, cache: &mut HashMap) -> UnionLayout { + let tag = self.tag.layout(cache); + + let variant_sas = self .variants .iter() - .map(|v| v.tref.layout(cache)) + .filter_map(|v| v.tref.as_ref().map(|t| t.layout(cache))) .collect::>(); - let size = sas - .iter() - .map(|sa| sa.size) - .max() - .expect("nonzero variants"); - let align = sas - .iter() - .map(|sa| sa.align) - .max() - .expect("nonzero variants"); - let size = align_to(size, align); - SizeAlign { size, align } + + let contents_size = variant_sas.iter().map(|sa| sa.size).max().unwrap_or(0); + let contents_align = variant_sas.iter().map(|sa| sa.align).max().unwrap_or(1); + + UnionLayout { + tag_size: tag.size, + tag_align: tag.align, + contents_offset: align_to(tag.size, contents_align), + contents_size, + contents_align, + } + } + + fn layout(&self, cache: &mut HashMap) -> SizeAlign { + self.union_layout_(cache).mem_size_align() } } diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 08bc9af5b..85f8c8d09 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -24,6 +24,7 @@ mod kw { wast::custom_keyword!(f32); wast::custom_keyword!(f64); wast::custom_keyword!(field); + wast::custom_keyword!(empty); wast::custom_keyword!(flags); wast::custom_keyword!(handle); wast::custom_keyword!(int); @@ -477,20 +478,48 @@ impl<'a> Parse<'a> for FieldSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum VariantSyntax<'a> { + Field(FieldSyntax<'a>), + Empty(wast::Id<'a>), +} + +impl<'a> Parse<'a> for VariantSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parens(|p| { + let mut l = p.lookahead1(); + if l.peek::() { + parser.parse::()?; + let name = p.parse()?; + let type_ = p.parse()?; + Ok(VariantSyntax::Field(FieldSyntax { name, type_ })) + } else if l.peek::() { + parser.parse::()?; + let name = p.parse()?; + Ok(VariantSyntax::Empty(name)) + } else { + Err(l.error()) + } + }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionSyntax<'a> { - pub fields: Vec>>, + pub tag: wast::Id<'a>, + pub fields: Vec>>, } impl<'a> Parse<'a> for UnionSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; + let tag = parser.parse()?; let mut fields = Vec::new(); fields.push(parser.parse()?); while !parser.is_empty() { fields.push(parser.parse()?); } - Ok(UnionSyntax { fields }) + Ok(UnionSyntax { tag, fields }) } } diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index a1a6ff58a..64b429f8b 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -206,19 +206,26 @@ impl StructDatatype { impl UnionDatatype { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("union")]; + let header = vec![SExpr::word("union"), self.tag.name.to_sexpr()]; let variants = self .variants .iter() .map(|v| { - SExpr::docs( - &v.docs, - SExpr::Vec(vec![ - SExpr::word("field"), - v.name.to_sexpr(), - v.tref.to_sexpr(), - ]), - ) + if let Some(ref tref) = v.tref { + SExpr::docs( + &v.docs, + SExpr::Vec(vec![ + SExpr::word("field"), + v.name.to_sexpr(), + tref.to_sexpr(), + ]), + ) + } else { + SExpr::docs( + &v.docs, + SExpr::Vec(vec![SExpr::word("empty"), v.name.to_sexpr()]), + ) + } }) .collect::>(); SExpr::Vec([header, variants].concat()) diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs index 3bdd6a792..0f12217af 100644 --- a/proposals/filesystem/tools/witx/src/representation.rs +++ b/proposals/filesystem/tools/witx/src/representation.rs @@ -177,7 +177,21 @@ impl Representable for UnionDatatype { } for v in self.variants.iter() { if let Some(byv) = by.variants.iter().find(|byv| byv.name == v.name) { - if v.tref.type_().representable(&*byv.tref.type_()) != RepEquality::Eq { + if v.tref.is_none() && byv.tref.is_none() { + // Both empty is OK + } else if v.tref.is_some() && byv.tref.is_some() { + if v.tref + .as_ref() + .unwrap() + .type_() + .representable(&*byv.tref.as_ref().unwrap().type_()) + != RepEquality::Eq + { + // Fields must be Eq + return RepEquality::NotEq; + } + } else { + // Either one empty means not representable return RepEquality::NotEq; } } else { @@ -185,9 +199,19 @@ impl Representable for UnionDatatype { } } if by.variants.len() > self.variants.len() { - RepEquality::Superset + // By is a superset of self only if the tags are as well: + if self.tag.type_().representable(&*by.tag.type_()) == RepEquality::Superset { + RepEquality::Superset + } else { + RepEquality::NotEq + } } else { - RepEquality::Eq + // By and self have matching variants, so they are equal if tags are: + if self.tag.type_().representable(&*by.tag.type_()) == RepEquality::Eq { + RepEquality::Eq + } else { + RepEquality::NotEq + } } } } @@ -287,16 +311,25 @@ mod test { #[test] fn union() { - let base = def_type("a", "(typename $a (union (field $b u32) (field $c f32)))"); + let base = def_type( + "a", + "(typename $tag (enum u8 $b $c)) + (typename $a (union $tag (field $b u32) (field $c f32)))", + ); let extra_variant = def_type( "a", - "(typename $a (union (field $b u32) (field $c f32) (field $d f64)))", + "(typename $tag (enum u8 $b $c $d)) + (typename $a (union $tag (field $b u32) (field $c f32) (field $d f64)))", ); assert_eq!(base.representable(&extra_variant), RepEquality::Superset); assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); - let other_ordering = def_type("a", "(typename $a (union (field $c f32) (field $b u32)))"); + let other_ordering = def_type( + "a", + "(typename $tag (enum u8 $b $c)) + (typename $a (union $tag (field $c f32) (field $b u32)))", + ); assert_eq!(base.representable(&other_ordering), RepEquality::Eq); assert_eq!(other_ordering.representable(&base), RepEquality::Eq); assert_eq!( diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 4bb92aa89..17be21e82 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -3,6 +3,7 @@ use crate::{ parser::{ CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + VariantSyntax, }, BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, @@ -10,7 +11,7 @@ use crate::{ ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, }; -use std::collections::HashMap; +use std::collections::{hash_map, HashMap}; use std::path::Path; use std::rc::Rc; use thiserror::Error; @@ -43,6 +44,12 @@ pub enum ValidationError { InvalidFirstResultType { location: Location }, #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] AnonymousStructure { location: Location }, + #[error("Invalid union field `{name}`: {reason}")] + InvalidUnionField { + name: String, + reason: String, + location: Location, + }, } impl ValidationError { @@ -54,7 +61,8 @@ impl ValidationError { | Recursive { location, .. } | InvalidRepr { location, .. } | InvalidFirstResultType { location, .. } - | AnonymousStructure { location, .. } => { + | AnonymousStructure { location, .. } + | InvalidUnionField { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } NameAlreadyExists { @@ -348,22 +356,100 @@ impl DocValidationScope<'_> { fn validate_union( &self, syntax: &UnionSyntax, - _span: wast::Span, + span: wast::Span, ) -> Result { let mut variant_scope = IdentValidation::new(); + let tag_id = self.get(&syntax.tag)?; + let (tag, mut variant_name_uses) = match self.doc.entries.get(&tag_id) { + Some(Entry::Typename(weak_ref)) => { + let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); + match &*named_dt.type_() { + Type::Enum(e) => { + let uses = e + .variants + .iter() + .map(|v| (v.name.clone(), false)) + .collect::>(); + Ok((named_dt, uses)) + } + other => Err(ValidationError::WrongKindName { + name: syntax.tag.name().to_string(), + location: self.location(syntax.tag.span()), + expected: "enum", + got: other.kind(), + }), + } + } + other => Err(ValidationError::WrongKindName { + name: syntax.tag.name().to_string(), + location: self.location(syntax.tag.span()), + expected: "enum", + got: match other { + Some(e) => e.kind(), + None => "unknown", + }, + }), + }?; + let variants = syntax .fields .iter() - .map(|f| { + .map(|v| { + let variant_name = match v.item { + VariantSyntax::Field(ref f) => &f.name, + VariantSyntax::Empty(ref name) => name, + }; let name = variant_scope - .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; - let docs = f.comments.docs(); + .introduce(variant_name.name(), self.location(variant_name.span()))?; + let tref = match &v.item { + VariantSyntax::Field(f) => { + Some(self.validate_datatype(&f.type_, false, variant_name.span())?) + } + VariantSyntax::Empty { .. } => None, + }; + let docs = v.comments.docs(); + match variant_name_uses.entry(name.clone()) { + hash_map::Entry::Occupied(mut e) => { + if *e.get() { + Err(ValidationError::InvalidUnionField { + name: variant_name.name().to_string(), + reason: "variant already defined".to_owned(), + location: self.location(variant_name.span()), + })?; + } else { + e.insert(true); + } + } + hash_map::Entry::Vacant { .. } => Err(ValidationError::InvalidUnionField { + name: variant_name.name().to_string(), + reason: format!( + "does not correspond to variant in tag `{}`", + tag.name.as_str() + ), + location: self.location(variant_name.span()), + })?, + } Ok(UnionVariant { name, tref, docs }) }) .collect::, _>>()?; - Ok(UnionDatatype { variants }) + let unused_variants = variant_name_uses + .iter() + .filter(|(_k, used)| **used == false) + .map(|(k, _)| k.clone()) + .collect::>(); + if !unused_variants.is_empty() { + Err(ValidationError::InvalidUnionField { + name: unused_variants + .iter() + .map(|i| i.as_str()) + .collect::>() + .join(", "), + reason: format!("missing variants from tag `{}`", tag.name.as_str()), + location: self.location(span), + })?; + } + Ok(UnionDatatype { tag, variants }) } fn validate_handle( diff --git a/proposals/filesystem/tools/witx/tests/anonymous.rs b/proposals/filesystem/tools/witx/tests/anonymous.rs index e1976a261..6bf11d883 100644 --- a/proposals/filesystem/tools/witx/tests/anonymous.rs +++ b/proposals/filesystem/tools/witx/tests/anonymous.rs @@ -12,7 +12,9 @@ fn anonymous_types() { let pointer_to_struct = witx::parse("(typename $a (@witx pointer (struct (field $b u8))))"); assert!(is_anonymous_struct_err(pointer_to_struct)); - let pointer_to_union = witx::parse("(typename $a (@witx pointer (union (field $b u8))))"); + let pointer_to_union = witx::parse( + "(typename $tag (enum u8 $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", + ); assert!(is_anonymous_struct_err(pointer_to_union)); let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum u32 $b)))"); @@ -33,7 +35,9 @@ fn anonymous_types() { let struct_in_struct = witx::parse("(typename $a (struct (field $b (struct (field $c u8)))))"); assert!(is_anonymous_struct_err(struct_in_struct)); - let union_in_struct = witx::parse("(typename $a (struct (field $b (union (field $c u8)))))"); + let union_in_struct = witx::parse( + "(typename $tag (enum u8 $c)) (typename $a (struct (field $b (union $tag (field $c u8)))))", + ); assert!(is_anonymous_struct_err(union_in_struct)); let pointer_in_struct = witx::parse("(typename $a (struct (field $b (@witx pointer u8))))"); diff --git a/proposals/filesystem/tools/witx/tests/union.rs b/proposals/filesystem/tools/witx/tests/union.rs new file mode 100644 index 000000000..732b5c007 --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/union.rs @@ -0,0 +1,183 @@ +// Every worker needs a union! Time to organize +use witx::{Id, Representable}; + +#[test] +fn one_variant_union() { + let d = witx::parse( + "(typename $tag (enum u8 $c)) + (typename $u (union $tag (field $c u8)))", + ); + assert!(d.is_ok()); +} + +#[test] +fn two_variant_union() { + let d1 = witx::parse( + "(typename $tag (enum u8 $a $b)) + (typename $u (union $tag (field $a u8) (field $b u16)))", + ); + assert!(d1.is_ok(), "d1 is ok"); + + // Fields can come in whatever order: + let d2 = witx::parse( + "(typename $tag (enum u8 $a $b)) + (typename $u (union $tag (field $b u16) (field $a u8)))", + ); + assert!(d2.is_ok(), "d2 is ok"); + + // These two unions should be represented the same: + let u1 = d1.unwrap().typename(&Id::new("u")).unwrap().type_(); + let u2 = d2.unwrap().typename(&Id::new("u")).unwrap().type_(); + + assert_eq!( + u1.representable(&u2), + witx::RepEquality::Eq, + "u1 can represent u2" + ); + assert_eq!( + u2.representable(&u1), + witx::RepEquality::Eq, + "u2 can represent u1" + ); + + // Tag order doesnt matter for validation, but does for rep equality + let d3 = witx::parse( + "(typename $tag (enum u8 $b $a)) + (typename $u (union $tag (field $b u16) (field $a u8)))", + ); + assert!(d3.is_ok(), "d2 is ok"); + let u3 = d3.unwrap().typename(&Id::new("u")).unwrap().type_(); + assert_eq!( + u3.representable(&u1), + witx::RepEquality::NotEq, + "u3 cannot represent u1" + ); +} + +#[test] +fn empty_variant_unions() { + let d1 = witx::parse( + "(typename $tag (enum u8 $a $b)) + (typename $u (union $tag (empty $a) (field $b u16)))", + ); + assert!(d1.is_ok(), "d1 is ok"); + + let d2 = witx::parse( + "(typename $tag (enum u8 $a $b)) + (typename $u (union $tag (empty $a) (empty $b)))", + ); + assert!(d2.is_ok(), "d2 is ok"); +} + +#[test] +fn many_variant_unions() { + let d1 = witx::parse( + "(typename $tag (enum u32 $a $b $c $d $e $f $g $h $i $j $k $l $m)) + (typename $u + (union $tag + (field $a u8) + (field $b u16) + (field $c u32) + (field $d u64) + (field $e s8) + (field $f s16) + (field $g s32) + (field $h s64) + (field $i f32) + (field $j f64) + (field $k (@witx usize)) + (field $l char8) + (empty $m) + ) + )", + ); + assert!(d1.is_ok(), "d1 is ok"); +} + +#[test] +fn no_tag_union() { + let d = witx::parse("(typename $u (union $tag (field $a u8) (field $b u16)))"); + assert!(d.is_err()); +} + +#[test] +fn wrong_kind_tag_union() { + let d = witx::parse( + "(typename $tag u32) + (typename $u (union $tag (field $a u8) (field $b u16)))", + ); + let (expected, got) = wrong_kind_name_err(d).expect("wrong kind of tag"); + assert_eq!(expected, "enum"); + assert_eq!(got, "builtin"); +} + +#[test] +fn bad_field_unions() { + let d = witx::parse( + "(typename $tag (enum u8 $c)) + (typename $u (union $tag (field $b u8)))", + ); + let (name, reason) = union_field_err(d).expect("bad field union 1"); + assert_eq!(name, "b", "bad field name union 1"); + assert_eq!( + reason, "does not correspond to variant in tag `tag`", + "reason union 1" + ); + + let d = witx::parse( + "(typename $tag (enum u8 $c)) + (typename $u (union $tag (field $c f32) (field $b u8)))", + ); + let (name, reason) = union_field_err(d).expect("bad field union 2"); + assert_eq!(name, "b", "bad field name union 2"); + assert_eq!( + reason, "does not correspond to variant in tag `tag`", + "reason union 2" + ); + + let d = witx::parse( + "(typename $tag (enum u8 $c $d)) + (typename $u (union $tag (field $c f32)))", + ); + let (name, reason) = union_field_err(d).expect("bad field union 3"); + assert_eq!(name, "d", "bad field name union 3"); + assert_eq!(reason, "missing variants from tag `tag`", "reason union 3"); +} + +fn wrong_kind_name_err( + r: Result, +) -> Option<(&'static str, &'static str)> { + match r { + Err(witx::WitxError::Validation(witx::ValidationError::WrongKindName { + expected, + got, + .. + })) => Some((expected, got)), + Err(e) => { + eprintln!("expected WrongKindName ValidationError, got: {:?}", e); + None + } + Ok(_) => { + eprintln!("expected WrongKindName ValidationError: Ok(witx::Document)"); + None + } + } +} + +fn union_field_err(r: Result) -> Option<(String, String)> { + match r { + Err(witx::WitxError::Validation(witx::ValidationError::InvalidUnionField { + name, + reason, + .. + })) => Some((name, reason)), + Err(e) => { + eprintln!("expected InvalidUnionField ValidationError, got: {:?}", e); + None + } + Ok(_) => { + eprintln!("expected InvalidUnionField ValidationError, got: Ok(witx::Document)"); + None + } + } +} From 0fab70aa80bdb92d87589d416b1de466414b3d48 Mon Sep 17 00:00:00 2001 From: Denis Vasilik Date: Wed, 19 Feb 2020 18:40:22 +0100 Subject: [PATCH 0553/1772] Rename acces to access (#211) --- proposals/clocks/phases/ephemeral/docs.md | 2 +- proposals/clocks/phases/ephemeral/witx/typenames.witx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 3834160fc..3418a7713 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -40,7 +40,7 @@ No error occurred. System call completed successfully. - `2big` Argument list too long. -- `acces` +- `access` Permission denied. - `addrinuse` diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index c37ab2e7b..58888122e 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -42,7 +42,7 @@ ;;; Argument list too long. $2big ;;; Permission denied. - $acces + $access ;;; Address in use. $addrinuse ;;; Address not available. From 7d1291ac806daad00e3e90d85aad75b70d043a8d Mon Sep 17 00:00:00 2001 From: Denis Vasilik Date: Wed, 19 Feb 2020 18:40:22 +0100 Subject: [PATCH 0554/1772] Rename acces to access (#211) --- proposals/random/phases/ephemeral/docs.md | 2 +- proposals/random/phases/ephemeral/witx/typenames.witx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 3834160fc..3418a7713 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -40,7 +40,7 @@ No error occurred. System call completed successfully. - `2big` Argument list too long. -- `acces` +- `access` Permission denied. - `addrinuse` diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index c37ab2e7b..58888122e 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -42,7 +42,7 @@ ;;; Argument list too long. $2big ;;; Permission denied. - $acces + $access ;;; Address in use. $addrinuse ;;; Address not available. From fce0462e7de8fd3b7f90346e0d90400bd00ea0a2 Mon Sep 17 00:00:00 2001 From: Denis Vasilik Date: Wed, 19 Feb 2020 18:40:22 +0100 Subject: [PATCH 0555/1772] Rename acces to access (#211) --- proposals/filesystem/phases/ephemeral/docs.md | 2 +- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 3834160fc..3418a7713 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -40,7 +40,7 @@ No error occurred. System call completed successfully. - `2big` Argument list too long. -- `acces` +- `access` Permission denied. - `addrinuse` diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index c37ab2e7b..58888122e 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -42,7 +42,7 @@ ;;; Argument list too long. $2big ;;; Permission denied. - $acces + $access ;;; Address in use. $addrinuse ;;; Address not available. From 1fbdab9ba79da3c411fe4c30f43ad1e82ba5d28a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 19 Feb 2020 10:40:13 -0800 Subject: [PATCH 0556/1772] Add a WASI design principles document. (#192) * Add a WASI design principles document. This spells out WASI's design principles around capabilities, relationship to POSIX, and other topics. This also includes a section on virtualization, which takes some ideas from #69, but modifies it to focus on using interface types and the linking proposal to implement virtualization. * Fix the links to the type imports proposal. * Fix "wowever" typo. * Elaborate on what WASI does instead of shared filesystem views. * Linkify "weak imports". * Rename WASI-design-principles.md to DesignPrinciples.md * Wrap lines to 72 columns. * Remove a redundant "always". * Say "interposition" instead of "virtualization". * Add some text to clarify that shared-nothing linking will require porting. * Reword the paragraph explaining how forgeable indices doesn't mean forgeable capabilities. * Update docs/DesignPrinciples.md Fix spelling of "trade-off" Co-Authored-By: Ben B. Co-authored-by: Ben B. --- proposals/clocks/docs/DesignPrinciples.md | 291 ++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 proposals/clocks/docs/DesignPrinciples.md diff --git a/proposals/clocks/docs/DesignPrinciples.md b/proposals/clocks/docs/DesignPrinciples.md new file mode 100644 index 000000000..584ba03ae --- /dev/null +++ b/proposals/clocks/docs/DesignPrinciples.md @@ -0,0 +1,291 @@ +# WASI Design Principles + +## Capability-based security + +WASI is built using capability-based security principles. Access to +external resources is always represented by *handles*, which are special +values that are *unforgeable*, meaning there's no way to coerce an +arbitrary integer or other type of value into a handle. WASI is also +aiming to have no *ambient authorities*, meaning that there should +be no way to request a handle purely by providing a string or other +user-controlled identifier providing the name of a resource. With these +two properties, the only ways to obtain access to resources are to be +explicitly given handles, or to perform operations on handles which +return new handles. + +Note that this is a different sense of "capability" than [Linux +capabilities](http://man7.org/linux/man-pages/man7/capabilities.7.html) +or the withdrawn [POSIX +capabilities](https://archive.org/details/posix_1003.1e-990310), which +are per-process rather than per-resource. + +The simplest representation of handles are values of [reference +type](https://github.com/WebAssembly/reference-types). References in +wasm are inherently unforgeable, so they can represent handles directly. + +Some programming languages operate primarily within linear memory, +such as C, C++, and Rust, and there currently is no easy way for +these languages to use references in normal code. And even if it does +become possible, it's likely that source code will still require +annotations to fully opt into references, so it won't always be +feasible to use. For these languages, references are stored in a +[table](https://webassembly.github.io/spec/core/bikeshed/index.html#tables%E2%91%A0) +called a *c-list*. Integer indices into the table then identify +resources, which can be easily passed around or stored in memory. In +some contexts, these indices are called *file descriptors* since they're +similar to what POSIX uses that term for. There are even some tools, +such as wasm-bindgen, which make this fairly easy. (Internally, tools +and engines don't always use actual WebAssembly tables to do this, +however those are implementation details. Conceptually, they work as if +they had tables.) + +Integer indices are themselves forgeable, however a program can only +access handles within the c-list it has access to, so isolation can still +be achieved, even between libraries which internally use integer indices, +by witholding access to each library's c-list to the other libraries. +Instances can be given access to some c-lists and not others, or even +no c-lists at all, so it's still possible to establish isolation between +instances. + +Witx-specified APIs use a special `handle` keyword to mark parameters +and return values which are handles. In the short term, these are +lowered to integer indices, with an implied table, so that the APIs +can be easily used from C and similar languages today. Once [interface +types](https://github.com/WebAssembly/interface-types) and [type +imports](https://github.com/WebAssembly/proposal-type-imports) are +ready, we expect to make use of them to provide APIs which can be used +either from languages using references or from languages using integer +indices, with tables being used and managed automatically. + +## WASI's Scope + +WASI started out with a very POSIX-like API, however WASI will grow to +include many APIs that are outside of the scope of POSIX. WASI is a +forum for cooperatively designing APIs, along with a W3C CG Subgroup for +eventually standardizing them. + +For example, WASI may include high-level network APIs, such as APIs for +HTTP. This is outside the scope of POSIX, and while some WebAssembly +engines are very interested in implementing it natively, others will +find it too complex and high-level. But one of the great things about +WebAssembly is that there's no syscall instruction, so "syscalls" +in WebAssembly are just calls to imported functions, which could be +native functions provided by the runtime, or could be other WebAssembly +modules. We expect to leverage this capability to provide polyfill +implementations of things like high-level network APIs on top of +low-level APIs, such as a raw socket API, so that engines which wish to +keep things simple and just implement the low-level socket APIs can do +so. + +WASI also aims to include domain-specific APIs, such as +database, blockchain, or specialized APIs for embedded +systems. Another key building block for WASI is [optional +imports](https://github.com/WebAssembly/WASI/blob/master/design/optional-imports.md), +which give applications the ability to dynamically test for the +availability of APIs. + +## Relationship to POSIX + +POSIX specifies a C API rather than an actual system call ABI, with +the expectation that implementation details will differ at the system +call level. In the same way, the primary vehicle for WASI's POSIX +compatibility is libraries such as WASI libc, rather than the WASI API +itself. WASI libc provides a wide range of POSIX-compatible APIs. + +In the parts of WASI which do correspond to POSIX functionality, WASI +follows POSIX when it doesn't conflict with WASI's other goals. And, +we consult POSIX even when we aren't strictly following it. POSIX is +valuable for several reasons: POSIX represents a large body of lessons +learned about systems programming, portability, and robustness. POSIX +is available on many existing hosts that we want to port WASI to. And, +there's a large amount of application code that we want to port to WASI +that uses POSIX-style interfaces. + +All this said, maximal POSIX conformance is not WASI's primary goal. +Some reasons include: + + - `fork` -- It's not that we can't make `fork` work -- we can, it's +that `fork` carries with it the assumption of copy-on-write memory +optimizations which won't be feasible in many environments where we +want to run WASI, such as nano-processes. There may eventually be +compatibility layers that provide `fork` to help people port POSIX +code to WASI, however there's a difference between providing `fork` as +an optional compatibility layer and having it as a cornerstone of an +ecosystem as it is in POSIX. + + And when we take `fork` out of the focus, it changes the way we think +about a lot of other things, such as `execve`, `dup`, `fcntl`-style file +locking, and even processes. + + - Users and Groups -- POSIX's Users and Groups subsystem are +notoriously inflexible, to the point where much of the computing world +has moved to using containers and VMs and other forms of single-user +environments because traditional multi-user OS functionality doesn't do +what's needed. + + And, when running untrusted code, it isn't desirable to run it as a +user's normal identity, because it shouldn't inherit all of the rights a +user has, but it also doesn't help to run it as user "nobody", as it's +still useful to grant it some rights and restrict it from others. + + And, we are aiming for portability to OS's which don't have +POSIX-style users and groups, and systems which don't have OS's at all. + + - Asynchronous signals and handlers -- The core WebAssembly semantics +don't support these, which would need to change before WASI could +consider supporting them, and there are currently no proposals for doing +so. In POSIX, some interfaces are designed with the assumption that +signals like `SIGPIPE`, `SIGALRM`, `SIGCHLD`, `SIGIO` and others exist +and can cover certain situations, so in the absence of these signals, +those interfaces won't always make sense. + + - Shared filesystem views - One of the unique capabilities WebAssembly +brings to the table is the possibility of shared-nothing linking between +applications and libraries. Shared-nothing means that all communication +is via explicit calls, and the libraries don't share an address space +or any other implicit shared state. But if we run both sides within +the same filesystem view, that would give them a large body of shared +state. Union mounts, mandatory access control systems, user namespaces, +and other techniques can help, but often require complex configuration, +heavy-weight boundaries, and sometimes even admin privileges to set up. + +This has wide-ranging implications. Much of POSIX is oriented around +passing around strings, whether through command-line arguments, +environment variables, or paths embedded in files, with the assumption +that there's a shared filesystem view between components. As we said +above, we're de-emphasizing strings, which dovetails with de-emphasizing +shared filesystem views. Instead of having shared state and passing +around values which identify things within the shared state, WASI +prefers to share as little as possible, and use handles which represent +the things which need to be shared. + +Compatibility with existing host environments and applications is +important, and we have put a lot of work into WASI libc to provide POSIX +compatibility and support existing applications. There's a lot more work +that can be done, and a lot more we can do to improve compatibility and +user convenience. We're continuing to make progress -- and users are +encouraged to [file bugs](https://github.com/WebAssembly/WASI/issues) +when they find things that don't work or are awkward. This approach +supports existing applications, while also supporting applications and +libraries willing to opt in to enable stronger and more fine-grained +security properties than are possible in regular POSIX. + +For example, a typical POSIX-style API might include a function that +accepts a file name to open. That requires the implementation to +have a filesystem view, and to have appropriate permissions within +that filesystem view. WASI APIs typically prefer to instead have a +function which accepts a handle for an already-open file. That way, the +implementation doesn't need a filesystem view, or permissions within +the filesystem. It doesn't even need to care whether there even is a +filesystem. When needed, compatibility with POSIX-style APIs is then +provided as a thin layer on top implementing a simple name-to-handle +mapping. + +We recognize that this approach has trade-offs. It often does take more +work to design and implement the compatibility layers needed to support +existing applications than if we just made WASI always expose +POSIX-style APIs directly. It will take more work to port existing +libraries to work with shared-nothing linking. And, even when we do have +compatibility mechanisms, they aren't always the most locally optimal +ones. The compatibility layer overhead is usually quite modest, but it +is present. + +However, libraries built to use shared-nothing linking can be used in +more circumstances, because you don't have to have the trust implied by +a shared filesystem view, or the complexity of configuring filesystem +rules for each library. With a better story for libraries and tools to +work together in cooperation with the sandbox, we can build a stronger +ecosystem which makes up for the downsides in the long run. + +## Relationship to the Web + +It is possible to run WASI code on the Web with the help of polyfills, +however WASI isn't limited to APIs which run well or are easy or +efficient to polyfill on the Web. + +That said, where other considerations don't interfere, WASI should use +existing Web standards and work with Web standardization efforts rather +than gratuitously inventing its own versions of them and/or duplicating +efforts. + +When using Web standards, WASI APIs should be careful to avoid depending +on JavaScript in the engine in APIs where it isn't essential. + +## Use WebAssembly standards and proposals + +WASI should align with and build on WebAssembly standards and proposals +where applicable. + +For example, WASI seeks to align with and build on [interface +types](https://github.com/WebAssembly/interface-types), [multiple +return values](https://github.com/WebAssembly/multi-value/), [reference +types](https://github.com/WebAssembly/reference-types), [type +imports](https://github.com/WebAssembly/proposal-type-imports), and +more. As of this writing, some of these are early-stage proposals, so +we're not actually depending on them yet, however we are carefully +aligning with them so that we'll be ready when they are. + +As another example, WASI's +[witx](https://github.com/WebAssembly/WASI/blob/master/docs/witx.md) +file format is designed to be a +straightforward superset of the [module type +proposal](https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md)'s +.wit format and the [annotations +proposal](https://github.com/WebAssembly/annotations/)'s annotation +syntax. + +## Interposition + +Interposition in the context of WASI interfaces is the ability for a +Webassembly instance to implement a given WASI interface, and for a +consumer WebAssembly instance to be able to use this implementation +transparently. This can be used to adapt or attenuate the functionality +of a WASI API without changing the code using it. + +In WASI, we envision interposition will primarily be configured +through the mechanisms in the interface types' [linking +proposal](https://github.com/WebAssembly/interface-types/blob/linking/proposals/interface-types/linking/Explainer.md). +Imports are resolved when a module is instantiated, which may happen +during the runtime of a larger logical application, so we can support +interposition of WASI APIs without defining them in terms of explicit +dynamic dispatch mechanisms. + +Interposition is sometimes referred to as "virtualization", however we +use "interposition" here because the word "virtualization" has several +related meanings. + +## Compatibility + +Compatibility with existing applications and libraries, as well as +existing host platforms, is important, but will sometimes be in conflict +with overall API cleanliness, safety, performance, or portability. +Where practical, WASI seeks to keep the WASI API itself free of +compatibility concerns, and provides compatibility through libraries, +such as WASI libc, and tools. This way, applications which don't require +compatibility for compatibility' sake aren't burdened by it. + +## Portability + +Portability is important to WASI, however the meaning of portability +will be specific to each API. + +WASI's modular nature means that engines don't need to implement every +API in WASI, so we don't need to exclude APIs just because some host +environments can't implement them. We prefer APIs which can run across +a wide variety of engines when feasible, but we'll ultimately decide +whether something is "portable enough" on an API-by-API basis. + +## Strings + +WASI in general de-emphasizes strings in areas where typed interfaces +can be sufficient, and especially when the strings would be serving as +identifiers in a global shared resource pool. + +Where strings are passed through APIs, WASI will use [interface +types](https://github.com/WebAssembly/interface-types) to manage the +strings. + +Where string encodings are exposed, WASI prefers to use UTF-8 +encodings for strings, and to provide explicit length values +rather than NUL-terminated strings, (as [WebAssembly itself +does](https://webassembly.github.io/spec/core/bikeshed/index.html#binary-utf8)). From 2b11f05f3329ff3645e502fb7bd32bfa065fdb99 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 19 Feb 2020 10:40:13 -0800 Subject: [PATCH 0557/1772] Add a WASI design principles document. (#192) * Add a WASI design principles document. This spells out WASI's design principles around capabilities, relationship to POSIX, and other topics. This also includes a section on virtualization, which takes some ideas from #69, but modifies it to focus on using interface types and the linking proposal to implement virtualization. * Fix the links to the type imports proposal. * Fix "wowever" typo. * Elaborate on what WASI does instead of shared filesystem views. * Linkify "weak imports". * Rename WASI-design-principles.md to DesignPrinciples.md * Wrap lines to 72 columns. * Remove a redundant "always". * Say "interposition" instead of "virtualization". * Add some text to clarify that shared-nothing linking will require porting. * Reword the paragraph explaining how forgeable indices doesn't mean forgeable capabilities. * Update docs/DesignPrinciples.md Fix spelling of "trade-off" Co-Authored-By: Ben B. Co-authored-by: Ben B. --- proposals/random/docs/DesignPrinciples.md | 291 ++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 proposals/random/docs/DesignPrinciples.md diff --git a/proposals/random/docs/DesignPrinciples.md b/proposals/random/docs/DesignPrinciples.md new file mode 100644 index 000000000..584ba03ae --- /dev/null +++ b/proposals/random/docs/DesignPrinciples.md @@ -0,0 +1,291 @@ +# WASI Design Principles + +## Capability-based security + +WASI is built using capability-based security principles. Access to +external resources is always represented by *handles*, which are special +values that are *unforgeable*, meaning there's no way to coerce an +arbitrary integer or other type of value into a handle. WASI is also +aiming to have no *ambient authorities*, meaning that there should +be no way to request a handle purely by providing a string or other +user-controlled identifier providing the name of a resource. With these +two properties, the only ways to obtain access to resources are to be +explicitly given handles, or to perform operations on handles which +return new handles. + +Note that this is a different sense of "capability" than [Linux +capabilities](http://man7.org/linux/man-pages/man7/capabilities.7.html) +or the withdrawn [POSIX +capabilities](https://archive.org/details/posix_1003.1e-990310), which +are per-process rather than per-resource. + +The simplest representation of handles are values of [reference +type](https://github.com/WebAssembly/reference-types). References in +wasm are inherently unforgeable, so they can represent handles directly. + +Some programming languages operate primarily within linear memory, +such as C, C++, and Rust, and there currently is no easy way for +these languages to use references in normal code. And even if it does +become possible, it's likely that source code will still require +annotations to fully opt into references, so it won't always be +feasible to use. For these languages, references are stored in a +[table](https://webassembly.github.io/spec/core/bikeshed/index.html#tables%E2%91%A0) +called a *c-list*. Integer indices into the table then identify +resources, which can be easily passed around or stored in memory. In +some contexts, these indices are called *file descriptors* since they're +similar to what POSIX uses that term for. There are even some tools, +such as wasm-bindgen, which make this fairly easy. (Internally, tools +and engines don't always use actual WebAssembly tables to do this, +however those are implementation details. Conceptually, they work as if +they had tables.) + +Integer indices are themselves forgeable, however a program can only +access handles within the c-list it has access to, so isolation can still +be achieved, even between libraries which internally use integer indices, +by witholding access to each library's c-list to the other libraries. +Instances can be given access to some c-lists and not others, or even +no c-lists at all, so it's still possible to establish isolation between +instances. + +Witx-specified APIs use a special `handle` keyword to mark parameters +and return values which are handles. In the short term, these are +lowered to integer indices, with an implied table, so that the APIs +can be easily used from C and similar languages today. Once [interface +types](https://github.com/WebAssembly/interface-types) and [type +imports](https://github.com/WebAssembly/proposal-type-imports) are +ready, we expect to make use of them to provide APIs which can be used +either from languages using references or from languages using integer +indices, with tables being used and managed automatically. + +## WASI's Scope + +WASI started out with a very POSIX-like API, however WASI will grow to +include many APIs that are outside of the scope of POSIX. WASI is a +forum for cooperatively designing APIs, along with a W3C CG Subgroup for +eventually standardizing them. + +For example, WASI may include high-level network APIs, such as APIs for +HTTP. This is outside the scope of POSIX, and while some WebAssembly +engines are very interested in implementing it natively, others will +find it too complex and high-level. But one of the great things about +WebAssembly is that there's no syscall instruction, so "syscalls" +in WebAssembly are just calls to imported functions, which could be +native functions provided by the runtime, or could be other WebAssembly +modules. We expect to leverage this capability to provide polyfill +implementations of things like high-level network APIs on top of +low-level APIs, such as a raw socket API, so that engines which wish to +keep things simple and just implement the low-level socket APIs can do +so. + +WASI also aims to include domain-specific APIs, such as +database, blockchain, or specialized APIs for embedded +systems. Another key building block for WASI is [optional +imports](https://github.com/WebAssembly/WASI/blob/master/design/optional-imports.md), +which give applications the ability to dynamically test for the +availability of APIs. + +## Relationship to POSIX + +POSIX specifies a C API rather than an actual system call ABI, with +the expectation that implementation details will differ at the system +call level. In the same way, the primary vehicle for WASI's POSIX +compatibility is libraries such as WASI libc, rather than the WASI API +itself. WASI libc provides a wide range of POSIX-compatible APIs. + +In the parts of WASI which do correspond to POSIX functionality, WASI +follows POSIX when it doesn't conflict with WASI's other goals. And, +we consult POSIX even when we aren't strictly following it. POSIX is +valuable for several reasons: POSIX represents a large body of lessons +learned about systems programming, portability, and robustness. POSIX +is available on many existing hosts that we want to port WASI to. And, +there's a large amount of application code that we want to port to WASI +that uses POSIX-style interfaces. + +All this said, maximal POSIX conformance is not WASI's primary goal. +Some reasons include: + + - `fork` -- It's not that we can't make `fork` work -- we can, it's +that `fork` carries with it the assumption of copy-on-write memory +optimizations which won't be feasible in many environments where we +want to run WASI, such as nano-processes. There may eventually be +compatibility layers that provide `fork` to help people port POSIX +code to WASI, however there's a difference between providing `fork` as +an optional compatibility layer and having it as a cornerstone of an +ecosystem as it is in POSIX. + + And when we take `fork` out of the focus, it changes the way we think +about a lot of other things, such as `execve`, `dup`, `fcntl`-style file +locking, and even processes. + + - Users and Groups -- POSIX's Users and Groups subsystem are +notoriously inflexible, to the point where much of the computing world +has moved to using containers and VMs and other forms of single-user +environments because traditional multi-user OS functionality doesn't do +what's needed. + + And, when running untrusted code, it isn't desirable to run it as a +user's normal identity, because it shouldn't inherit all of the rights a +user has, but it also doesn't help to run it as user "nobody", as it's +still useful to grant it some rights and restrict it from others. + + And, we are aiming for portability to OS's which don't have +POSIX-style users and groups, and systems which don't have OS's at all. + + - Asynchronous signals and handlers -- The core WebAssembly semantics +don't support these, which would need to change before WASI could +consider supporting them, and there are currently no proposals for doing +so. In POSIX, some interfaces are designed with the assumption that +signals like `SIGPIPE`, `SIGALRM`, `SIGCHLD`, `SIGIO` and others exist +and can cover certain situations, so in the absence of these signals, +those interfaces won't always make sense. + + - Shared filesystem views - One of the unique capabilities WebAssembly +brings to the table is the possibility of shared-nothing linking between +applications and libraries. Shared-nothing means that all communication +is via explicit calls, and the libraries don't share an address space +or any other implicit shared state. But if we run both sides within +the same filesystem view, that would give them a large body of shared +state. Union mounts, mandatory access control systems, user namespaces, +and other techniques can help, but often require complex configuration, +heavy-weight boundaries, and sometimes even admin privileges to set up. + +This has wide-ranging implications. Much of POSIX is oriented around +passing around strings, whether through command-line arguments, +environment variables, or paths embedded in files, with the assumption +that there's a shared filesystem view between components. As we said +above, we're de-emphasizing strings, which dovetails with de-emphasizing +shared filesystem views. Instead of having shared state and passing +around values which identify things within the shared state, WASI +prefers to share as little as possible, and use handles which represent +the things which need to be shared. + +Compatibility with existing host environments and applications is +important, and we have put a lot of work into WASI libc to provide POSIX +compatibility and support existing applications. There's a lot more work +that can be done, and a lot more we can do to improve compatibility and +user convenience. We're continuing to make progress -- and users are +encouraged to [file bugs](https://github.com/WebAssembly/WASI/issues) +when they find things that don't work or are awkward. This approach +supports existing applications, while also supporting applications and +libraries willing to opt in to enable stronger and more fine-grained +security properties than are possible in regular POSIX. + +For example, a typical POSIX-style API might include a function that +accepts a file name to open. That requires the implementation to +have a filesystem view, and to have appropriate permissions within +that filesystem view. WASI APIs typically prefer to instead have a +function which accepts a handle for an already-open file. That way, the +implementation doesn't need a filesystem view, or permissions within +the filesystem. It doesn't even need to care whether there even is a +filesystem. When needed, compatibility with POSIX-style APIs is then +provided as a thin layer on top implementing a simple name-to-handle +mapping. + +We recognize that this approach has trade-offs. It often does take more +work to design and implement the compatibility layers needed to support +existing applications than if we just made WASI always expose +POSIX-style APIs directly. It will take more work to port existing +libraries to work with shared-nothing linking. And, even when we do have +compatibility mechanisms, they aren't always the most locally optimal +ones. The compatibility layer overhead is usually quite modest, but it +is present. + +However, libraries built to use shared-nothing linking can be used in +more circumstances, because you don't have to have the trust implied by +a shared filesystem view, or the complexity of configuring filesystem +rules for each library. With a better story for libraries and tools to +work together in cooperation with the sandbox, we can build a stronger +ecosystem which makes up for the downsides in the long run. + +## Relationship to the Web + +It is possible to run WASI code on the Web with the help of polyfills, +however WASI isn't limited to APIs which run well or are easy or +efficient to polyfill on the Web. + +That said, where other considerations don't interfere, WASI should use +existing Web standards and work with Web standardization efforts rather +than gratuitously inventing its own versions of them and/or duplicating +efforts. + +When using Web standards, WASI APIs should be careful to avoid depending +on JavaScript in the engine in APIs where it isn't essential. + +## Use WebAssembly standards and proposals + +WASI should align with and build on WebAssembly standards and proposals +where applicable. + +For example, WASI seeks to align with and build on [interface +types](https://github.com/WebAssembly/interface-types), [multiple +return values](https://github.com/WebAssembly/multi-value/), [reference +types](https://github.com/WebAssembly/reference-types), [type +imports](https://github.com/WebAssembly/proposal-type-imports), and +more. As of this writing, some of these are early-stage proposals, so +we're not actually depending on them yet, however we are carefully +aligning with them so that we'll be ready when they are. + +As another example, WASI's +[witx](https://github.com/WebAssembly/WASI/blob/master/docs/witx.md) +file format is designed to be a +straightforward superset of the [module type +proposal](https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md)'s +.wit format and the [annotations +proposal](https://github.com/WebAssembly/annotations/)'s annotation +syntax. + +## Interposition + +Interposition in the context of WASI interfaces is the ability for a +Webassembly instance to implement a given WASI interface, and for a +consumer WebAssembly instance to be able to use this implementation +transparently. This can be used to adapt or attenuate the functionality +of a WASI API without changing the code using it. + +In WASI, we envision interposition will primarily be configured +through the mechanisms in the interface types' [linking +proposal](https://github.com/WebAssembly/interface-types/blob/linking/proposals/interface-types/linking/Explainer.md). +Imports are resolved when a module is instantiated, which may happen +during the runtime of a larger logical application, so we can support +interposition of WASI APIs without defining them in terms of explicit +dynamic dispatch mechanisms. + +Interposition is sometimes referred to as "virtualization", however we +use "interposition" here because the word "virtualization" has several +related meanings. + +## Compatibility + +Compatibility with existing applications and libraries, as well as +existing host platforms, is important, but will sometimes be in conflict +with overall API cleanliness, safety, performance, or portability. +Where practical, WASI seeks to keep the WASI API itself free of +compatibility concerns, and provides compatibility through libraries, +such as WASI libc, and tools. This way, applications which don't require +compatibility for compatibility' sake aren't burdened by it. + +## Portability + +Portability is important to WASI, however the meaning of portability +will be specific to each API. + +WASI's modular nature means that engines don't need to implement every +API in WASI, so we don't need to exclude APIs just because some host +environments can't implement them. We prefer APIs which can run across +a wide variety of engines when feasible, but we'll ultimately decide +whether something is "portable enough" on an API-by-API basis. + +## Strings + +WASI in general de-emphasizes strings in areas where typed interfaces +can be sufficient, and especially when the strings would be serving as +identifiers in a global shared resource pool. + +Where strings are passed through APIs, WASI will use [interface +types](https://github.com/WebAssembly/interface-types) to manage the +strings. + +Where string encodings are exposed, WASI prefers to use UTF-8 +encodings for strings, and to provide explicit length values +rather than NUL-terminated strings, (as [WebAssembly itself +does](https://webassembly.github.io/spec/core/bikeshed/index.html#binary-utf8)). From 1709c2f07e066ab799ea697cc311724cb0026e03 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 19 Feb 2020 10:40:13 -0800 Subject: [PATCH 0558/1772] Add a WASI design principles document. (#192) * Add a WASI design principles document. This spells out WASI's design principles around capabilities, relationship to POSIX, and other topics. This also includes a section on virtualization, which takes some ideas from #69, but modifies it to focus on using interface types and the linking proposal to implement virtualization. * Fix the links to the type imports proposal. * Fix "wowever" typo. * Elaborate on what WASI does instead of shared filesystem views. * Linkify "weak imports". * Rename WASI-design-principles.md to DesignPrinciples.md * Wrap lines to 72 columns. * Remove a redundant "always". * Say "interposition" instead of "virtualization". * Add some text to clarify that shared-nothing linking will require porting. * Reword the paragraph explaining how forgeable indices doesn't mean forgeable capabilities. * Update docs/DesignPrinciples.md Fix spelling of "trade-off" Co-Authored-By: Ben B. Co-authored-by: Ben B. --- proposals/filesystem/docs/DesignPrinciples.md | 291 ++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 proposals/filesystem/docs/DesignPrinciples.md diff --git a/proposals/filesystem/docs/DesignPrinciples.md b/proposals/filesystem/docs/DesignPrinciples.md new file mode 100644 index 000000000..584ba03ae --- /dev/null +++ b/proposals/filesystem/docs/DesignPrinciples.md @@ -0,0 +1,291 @@ +# WASI Design Principles + +## Capability-based security + +WASI is built using capability-based security principles. Access to +external resources is always represented by *handles*, which are special +values that are *unforgeable*, meaning there's no way to coerce an +arbitrary integer or other type of value into a handle. WASI is also +aiming to have no *ambient authorities*, meaning that there should +be no way to request a handle purely by providing a string or other +user-controlled identifier providing the name of a resource. With these +two properties, the only ways to obtain access to resources are to be +explicitly given handles, or to perform operations on handles which +return new handles. + +Note that this is a different sense of "capability" than [Linux +capabilities](http://man7.org/linux/man-pages/man7/capabilities.7.html) +or the withdrawn [POSIX +capabilities](https://archive.org/details/posix_1003.1e-990310), which +are per-process rather than per-resource. + +The simplest representation of handles are values of [reference +type](https://github.com/WebAssembly/reference-types). References in +wasm are inherently unforgeable, so they can represent handles directly. + +Some programming languages operate primarily within linear memory, +such as C, C++, and Rust, and there currently is no easy way for +these languages to use references in normal code. And even if it does +become possible, it's likely that source code will still require +annotations to fully opt into references, so it won't always be +feasible to use. For these languages, references are stored in a +[table](https://webassembly.github.io/spec/core/bikeshed/index.html#tables%E2%91%A0) +called a *c-list*. Integer indices into the table then identify +resources, which can be easily passed around or stored in memory. In +some contexts, these indices are called *file descriptors* since they're +similar to what POSIX uses that term for. There are even some tools, +such as wasm-bindgen, which make this fairly easy. (Internally, tools +and engines don't always use actual WebAssembly tables to do this, +however those are implementation details. Conceptually, they work as if +they had tables.) + +Integer indices are themselves forgeable, however a program can only +access handles within the c-list it has access to, so isolation can still +be achieved, even between libraries which internally use integer indices, +by witholding access to each library's c-list to the other libraries. +Instances can be given access to some c-lists and not others, or even +no c-lists at all, so it's still possible to establish isolation between +instances. + +Witx-specified APIs use a special `handle` keyword to mark parameters +and return values which are handles. In the short term, these are +lowered to integer indices, with an implied table, so that the APIs +can be easily used from C and similar languages today. Once [interface +types](https://github.com/WebAssembly/interface-types) and [type +imports](https://github.com/WebAssembly/proposal-type-imports) are +ready, we expect to make use of them to provide APIs which can be used +either from languages using references or from languages using integer +indices, with tables being used and managed automatically. + +## WASI's Scope + +WASI started out with a very POSIX-like API, however WASI will grow to +include many APIs that are outside of the scope of POSIX. WASI is a +forum for cooperatively designing APIs, along with a W3C CG Subgroup for +eventually standardizing them. + +For example, WASI may include high-level network APIs, such as APIs for +HTTP. This is outside the scope of POSIX, and while some WebAssembly +engines are very interested in implementing it natively, others will +find it too complex and high-level. But one of the great things about +WebAssembly is that there's no syscall instruction, so "syscalls" +in WebAssembly are just calls to imported functions, which could be +native functions provided by the runtime, or could be other WebAssembly +modules. We expect to leverage this capability to provide polyfill +implementations of things like high-level network APIs on top of +low-level APIs, such as a raw socket API, so that engines which wish to +keep things simple and just implement the low-level socket APIs can do +so. + +WASI also aims to include domain-specific APIs, such as +database, blockchain, or specialized APIs for embedded +systems. Another key building block for WASI is [optional +imports](https://github.com/WebAssembly/WASI/blob/master/design/optional-imports.md), +which give applications the ability to dynamically test for the +availability of APIs. + +## Relationship to POSIX + +POSIX specifies a C API rather than an actual system call ABI, with +the expectation that implementation details will differ at the system +call level. In the same way, the primary vehicle for WASI's POSIX +compatibility is libraries such as WASI libc, rather than the WASI API +itself. WASI libc provides a wide range of POSIX-compatible APIs. + +In the parts of WASI which do correspond to POSIX functionality, WASI +follows POSIX when it doesn't conflict with WASI's other goals. And, +we consult POSIX even when we aren't strictly following it. POSIX is +valuable for several reasons: POSIX represents a large body of lessons +learned about systems programming, portability, and robustness. POSIX +is available on many existing hosts that we want to port WASI to. And, +there's a large amount of application code that we want to port to WASI +that uses POSIX-style interfaces. + +All this said, maximal POSIX conformance is not WASI's primary goal. +Some reasons include: + + - `fork` -- It's not that we can't make `fork` work -- we can, it's +that `fork` carries with it the assumption of copy-on-write memory +optimizations which won't be feasible in many environments where we +want to run WASI, such as nano-processes. There may eventually be +compatibility layers that provide `fork` to help people port POSIX +code to WASI, however there's a difference between providing `fork` as +an optional compatibility layer and having it as a cornerstone of an +ecosystem as it is in POSIX. + + And when we take `fork` out of the focus, it changes the way we think +about a lot of other things, such as `execve`, `dup`, `fcntl`-style file +locking, and even processes. + + - Users and Groups -- POSIX's Users and Groups subsystem are +notoriously inflexible, to the point where much of the computing world +has moved to using containers and VMs and other forms of single-user +environments because traditional multi-user OS functionality doesn't do +what's needed. + + And, when running untrusted code, it isn't desirable to run it as a +user's normal identity, because it shouldn't inherit all of the rights a +user has, but it also doesn't help to run it as user "nobody", as it's +still useful to grant it some rights and restrict it from others. + + And, we are aiming for portability to OS's which don't have +POSIX-style users and groups, and systems which don't have OS's at all. + + - Asynchronous signals and handlers -- The core WebAssembly semantics +don't support these, which would need to change before WASI could +consider supporting them, and there are currently no proposals for doing +so. In POSIX, some interfaces are designed with the assumption that +signals like `SIGPIPE`, `SIGALRM`, `SIGCHLD`, `SIGIO` and others exist +and can cover certain situations, so in the absence of these signals, +those interfaces won't always make sense. + + - Shared filesystem views - One of the unique capabilities WebAssembly +brings to the table is the possibility of shared-nothing linking between +applications and libraries. Shared-nothing means that all communication +is via explicit calls, and the libraries don't share an address space +or any other implicit shared state. But if we run both sides within +the same filesystem view, that would give them a large body of shared +state. Union mounts, mandatory access control systems, user namespaces, +and other techniques can help, but often require complex configuration, +heavy-weight boundaries, and sometimes even admin privileges to set up. + +This has wide-ranging implications. Much of POSIX is oriented around +passing around strings, whether through command-line arguments, +environment variables, or paths embedded in files, with the assumption +that there's a shared filesystem view between components. As we said +above, we're de-emphasizing strings, which dovetails with de-emphasizing +shared filesystem views. Instead of having shared state and passing +around values which identify things within the shared state, WASI +prefers to share as little as possible, and use handles which represent +the things which need to be shared. + +Compatibility with existing host environments and applications is +important, and we have put a lot of work into WASI libc to provide POSIX +compatibility and support existing applications. There's a lot more work +that can be done, and a lot more we can do to improve compatibility and +user convenience. We're continuing to make progress -- and users are +encouraged to [file bugs](https://github.com/WebAssembly/WASI/issues) +when they find things that don't work or are awkward. This approach +supports existing applications, while also supporting applications and +libraries willing to opt in to enable stronger and more fine-grained +security properties than are possible in regular POSIX. + +For example, a typical POSIX-style API might include a function that +accepts a file name to open. That requires the implementation to +have a filesystem view, and to have appropriate permissions within +that filesystem view. WASI APIs typically prefer to instead have a +function which accepts a handle for an already-open file. That way, the +implementation doesn't need a filesystem view, or permissions within +the filesystem. It doesn't even need to care whether there even is a +filesystem. When needed, compatibility with POSIX-style APIs is then +provided as a thin layer on top implementing a simple name-to-handle +mapping. + +We recognize that this approach has trade-offs. It often does take more +work to design and implement the compatibility layers needed to support +existing applications than if we just made WASI always expose +POSIX-style APIs directly. It will take more work to port existing +libraries to work with shared-nothing linking. And, even when we do have +compatibility mechanisms, they aren't always the most locally optimal +ones. The compatibility layer overhead is usually quite modest, but it +is present. + +However, libraries built to use shared-nothing linking can be used in +more circumstances, because you don't have to have the trust implied by +a shared filesystem view, or the complexity of configuring filesystem +rules for each library. With a better story for libraries and tools to +work together in cooperation with the sandbox, we can build a stronger +ecosystem which makes up for the downsides in the long run. + +## Relationship to the Web + +It is possible to run WASI code on the Web with the help of polyfills, +however WASI isn't limited to APIs which run well or are easy or +efficient to polyfill on the Web. + +That said, where other considerations don't interfere, WASI should use +existing Web standards and work with Web standardization efforts rather +than gratuitously inventing its own versions of them and/or duplicating +efforts. + +When using Web standards, WASI APIs should be careful to avoid depending +on JavaScript in the engine in APIs where it isn't essential. + +## Use WebAssembly standards and proposals + +WASI should align with and build on WebAssembly standards and proposals +where applicable. + +For example, WASI seeks to align with and build on [interface +types](https://github.com/WebAssembly/interface-types), [multiple +return values](https://github.com/WebAssembly/multi-value/), [reference +types](https://github.com/WebAssembly/reference-types), [type +imports](https://github.com/WebAssembly/proposal-type-imports), and +more. As of this writing, some of these are early-stage proposals, so +we're not actually depending on them yet, however we are carefully +aligning with them so that we'll be ready when they are. + +As another example, WASI's +[witx](https://github.com/WebAssembly/WASI/blob/master/docs/witx.md) +file format is designed to be a +straightforward superset of the [module type +proposal](https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md)'s +.wit format and the [annotations +proposal](https://github.com/WebAssembly/annotations/)'s annotation +syntax. + +## Interposition + +Interposition in the context of WASI interfaces is the ability for a +Webassembly instance to implement a given WASI interface, and for a +consumer WebAssembly instance to be able to use this implementation +transparently. This can be used to adapt or attenuate the functionality +of a WASI API without changing the code using it. + +In WASI, we envision interposition will primarily be configured +through the mechanisms in the interface types' [linking +proposal](https://github.com/WebAssembly/interface-types/blob/linking/proposals/interface-types/linking/Explainer.md). +Imports are resolved when a module is instantiated, which may happen +during the runtime of a larger logical application, so we can support +interposition of WASI APIs without defining them in terms of explicit +dynamic dispatch mechanisms. + +Interposition is sometimes referred to as "virtualization", however we +use "interposition" here because the word "virtualization" has several +related meanings. + +## Compatibility + +Compatibility with existing applications and libraries, as well as +existing host platforms, is important, but will sometimes be in conflict +with overall API cleanliness, safety, performance, or portability. +Where practical, WASI seeks to keep the WASI API itself free of +compatibility concerns, and provides compatibility through libraries, +such as WASI libc, and tools. This way, applications which don't require +compatibility for compatibility' sake aren't burdened by it. + +## Portability + +Portability is important to WASI, however the meaning of portability +will be specific to each API. + +WASI's modular nature means that engines don't need to implement every +API in WASI, so we don't need to exclude APIs just because some host +environments can't implement them. We prefer APIs which can run across +a wide variety of engines when feasible, but we'll ultimately decide +whether something is "portable enough" on an API-by-API basis. + +## Strings + +WASI in general de-emphasizes strings in areas where typed interfaces +can be sufficient, and especially when the strings would be serving as +identifiers in a global shared resource pool. + +Where strings are passed through APIs, WASI will use [interface +types](https://github.com/WebAssembly/interface-types) to manage the +strings. + +Where string encodings are exposed, WASI prefers to use UTF-8 +encodings for strings, and to provide explicit length values +rather than NUL-terminated strings, (as [WebAssembly itself +does](https://webassembly.github.io/spec/core/bikeshed/index.html#binary-utf8)). From ec0d9e76488a1b0c9a46fb93b95482a7a7656ddb Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 19 Feb 2020 11:03:14 -0800 Subject: [PATCH 0559/1772] Remove the cputime clocks. (#197) * Remove the cputime clocks. Remove $process_cputime_id and $thread_cputime_id. Some implementations will not have one wasm nanoprocess per OS process, or one wasm thread per OS thread, making it difficult to implement $process_cputime_id meaningfully. Also, the concept of "cputime" available in most host environments isn't easy to directly connect to what we might expect "cputime" to mean for wasm code. These correspond to `CLOCK_PROCESS_CPUTIME_ID` and `CLOCK_THREAD_CPUTIME_ID` in POSIX, which are optional: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html * Auto-generate docs. --- proposals/clocks/phases/ephemeral/docs.md | 6 ------ proposals/clocks/phases/ephemeral/witx/typenames.witx | 4 ---- 2 files changed, 10 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 3418a7713..d69e10f0b 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -21,12 +21,6 @@ real time, whose value cannot be adjusted and which cannot have negative clock jumps. The epoch of this clock is undefined. The absolute time value of this clock therefore has no meaning. -- `process_cputime_id` -The CPU-time clock associated with the current process. - -- `thread_cputime_id` -The CPU-time clock associated with the current thread. - ## `errno`: Enum(`u16`) Error codes returned by functions. Not all of these error codes are returned by the functions provided by this diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 58888122e..b7ee26aa6 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -24,10 +24,6 @@ ;;; clock jumps. The epoch of this clock is undefined. The absolute time ;;; value of this clock therefore has no meaning. $monotonic - ;;; The CPU-time clock associated with the current process. - $process_cputime_id - ;;; The CPU-time clock associated with the current thread. - $thread_cputime_id ) ) From 02ecfb0d1b00fe2cbb1b6783ad6f16426f6c11b1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 19 Feb 2020 11:03:14 -0800 Subject: [PATCH 0560/1772] Remove the cputime clocks. (#197) * Remove the cputime clocks. Remove $process_cputime_id and $thread_cputime_id. Some implementations will not have one wasm nanoprocess per OS process, or one wasm thread per OS thread, making it difficult to implement $process_cputime_id meaningfully. Also, the concept of "cputime" available in most host environments isn't easy to directly connect to what we might expect "cputime" to mean for wasm code. These correspond to `CLOCK_PROCESS_CPUTIME_ID` and `CLOCK_THREAD_CPUTIME_ID` in POSIX, which are optional: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html * Auto-generate docs. --- proposals/random/phases/ephemeral/docs.md | 6 ------ proposals/random/phases/ephemeral/witx/typenames.witx | 4 ---- 2 files changed, 10 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 3418a7713..d69e10f0b 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -21,12 +21,6 @@ real time, whose value cannot be adjusted and which cannot have negative clock jumps. The epoch of this clock is undefined. The absolute time value of this clock therefore has no meaning. -- `process_cputime_id` -The CPU-time clock associated with the current process. - -- `thread_cputime_id` -The CPU-time clock associated with the current thread. - ## `errno`: Enum(`u16`) Error codes returned by functions. Not all of these error codes are returned by the functions provided by this diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 58888122e..b7ee26aa6 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -24,10 +24,6 @@ ;;; clock jumps. The epoch of this clock is undefined. The absolute time ;;; value of this clock therefore has no meaning. $monotonic - ;;; The CPU-time clock associated with the current process. - $process_cputime_id - ;;; The CPU-time clock associated with the current thread. - $thread_cputime_id ) ) From b2eb6ebd44defd62f5c780f6243822ebef579ded Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 19 Feb 2020 11:03:14 -0800 Subject: [PATCH 0561/1772] Remove the cputime clocks. (#197) * Remove the cputime clocks. Remove $process_cputime_id and $thread_cputime_id. Some implementations will not have one wasm nanoprocess per OS process, or one wasm thread per OS thread, making it difficult to implement $process_cputime_id meaningfully. Also, the concept of "cputime" available in most host environments isn't easy to directly connect to what we might expect "cputime" to mean for wasm code. These correspond to `CLOCK_PROCESS_CPUTIME_ID` and `CLOCK_THREAD_CPUTIME_ID` in POSIX, which are optional: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html * Auto-generate docs. --- proposals/filesystem/phases/ephemeral/docs.md | 6 ------ proposals/filesystem/phases/ephemeral/witx/typenames.witx | 4 ---- 2 files changed, 10 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 3418a7713..d69e10f0b 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -21,12 +21,6 @@ real time, whose value cannot be adjusted and which cannot have negative clock jumps. The epoch of this clock is undefined. The absolute time value of this clock therefore has no meaning. -- `process_cputime_id` -The CPU-time clock associated with the current process. - -- `thread_cputime_id` -The CPU-time clock associated with the current thread. - ## `errno`: Enum(`u16`) Error codes returned by functions. Not all of these error codes are returned by the functions provided by this diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 58888122e..b7ee26aa6 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -24,10 +24,6 @@ ;;; clock jumps. The epoch of this clock is undefined. The absolute time ;;; value of this clock therefore has no meaning. $monotonic - ;;; The CPU-time clock associated with the current process. - $process_cputime_id - ;;; The CPU-time clock associated with the current thread. - $thread_cputime_id ) ) From aa6870240caf3bdf6e6ca541abe1737178b07696 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 21 Feb 2020 10:16:47 -0800 Subject: [PATCH 0562/1772] witx: export UnionLayout type (#225) * witx: export UnionLayout type * bump witx version to 0.8.1 --- proposals/clocks/tools/witx/Cargo.toml | 2 +- proposals/clocks/tools/witx/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 32f0cbea9..459ec4602 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.0" +version = "0.8.1" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index ba4df6889..c612e601d 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -33,7 +33,7 @@ pub use ast::{ pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; -pub use layout::{Layout, SizeAlign, StructMemberLayout}; +pub use layout::{Layout, SizeAlign, StructMemberLayout, UnionLayout}; pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; From 529bccf6ee041ee3e790b108411b8c58a165a8ba Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 21 Feb 2020 10:16:47 -0800 Subject: [PATCH 0563/1772] witx: export UnionLayout type (#225) * witx: export UnionLayout type * bump witx version to 0.8.1 --- proposals/random/tools/witx/Cargo.toml | 2 +- proposals/random/tools/witx/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 32f0cbea9..459ec4602 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.0" +version = "0.8.1" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index ba4df6889..c612e601d 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -33,7 +33,7 @@ pub use ast::{ pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; -pub use layout::{Layout, SizeAlign, StructMemberLayout}; +pub use layout::{Layout, SizeAlign, StructMemberLayout, UnionLayout}; pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; From 21802c5f3e222147738b01d97199a8c701f859e8 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 21 Feb 2020 10:16:47 -0800 Subject: [PATCH 0564/1772] witx: export UnionLayout type (#225) * witx: export UnionLayout type * bump witx version to 0.8.1 --- proposals/filesystem/tools/witx/Cargo.toml | 2 +- proposals/filesystem/tools/witx/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 32f0cbea9..459ec4602 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.0" +version = "0.8.1" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index ba4df6889..c612e601d 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -33,7 +33,7 @@ pub use ast::{ pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; -pub use layout::{Layout, SizeAlign, StructMemberLayout}; +pub use layout::{Layout, SizeAlign, StructMemberLayout, UnionLayout}; pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; From 734457bddc5e68db60f4699061a0481a4aea2660 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 21 Feb 2020 19:22:56 +0100 Subject: [PATCH 0565/1772] Fix dead links across all snapshots (#226) This commit fixes dead links (most likely not all of them, but at least a large number) across all snapshots. --- proposals/clocks/phases/ephemeral/docs.md | 61 ++++++++++--------- .../phases/ephemeral/witx/typenames.witx | 46 +++++++------- .../ephemeral/witx/wasi_ephemeral_clock.witx | 3 +- .../ephemeral/witx/wasi_ephemeral_fd.witx | 6 +- .../ephemeral/witx/wasi_ephemeral_path.witx | 6 +- .../clocks/phases/old/snapshot_0/docs.md | 59 +++++++++--------- .../phases/old/snapshot_0/witx/typenames.witx | 44 ++++++------- .../old/snapshot_0/witx/wasi_unstable.witx | 15 ++--- proposals/clocks/phases/snapshot/docs.md | 6 +- .../phases/snapshot/witx/typenames.witx | 6 +- 10 files changed, 128 insertions(+), 124 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index d69e10f0b..8f19cc8c2 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -266,7 +266,7 @@ File descriptor rights, determining which actions may be performed. - `fd_datasync` The right to invoke `fd_datasync`. If `path_open` is set, includes the right to invoke -`path_open` with `fdflag::dsync`. +`path_open` with [`fdflags::dsync`](#fdflags.dsync). - `fd_read` The right to invoke `fd_read` and `sock_recv`. @@ -281,11 +281,11 @@ The right to invoke `fd_fdstat_set_flags`. - `fd_sync` The right to invoke `fd_sync`. If `path_open` is set, includes the right to invoke -`path_open` with `fdflag::rsync` and `fdflag::dsync`. +`path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - `fd_tell` The right to invoke `fd_seek` in such a way that the file offset -remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke `fd_tell`. - `fd_write` @@ -420,7 +420,7 @@ A reference to the offset of a directory entry. In an `fd_readdir` call, this value signifies the start of the directory. ## `dirnamlen`: `u32` -The type for the $d_namlen field of $dirent. +The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). ## `inode`: `u64` File serial number that is unique within its file system. @@ -541,16 +541,16 @@ Which file time attributes to adjust. ### Flags - `atim` -Adjust the last data access timestamp to the value stored in `filestat::st_atim`. +Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - `atim_now` -Adjust the last data access timestamp to the time of clock `clock::realtime`. +Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - `mtim` -Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. +Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - `mtim_now` -Adjust the last data modification timestamp to the time of clock `clock::realtime`. +Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. @@ -648,15 +648,15 @@ Type of a subscription to an event or its occurrence. ### Variants - `clock` -The time value of clock `subscription::u.clock.clock_id` has -reached timestamp `subscription::u.clock.timeout`. +The time value of clock [`subscription_clock::id`](#subscription_clock.id) has +reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - `fd_read` -File descriptor `subscription::u.fd_readwrite.fd` has data +File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has data available for reading. This event always triggers for regular files. - `fd_write` -File descriptor `subscription::u.fd_readwrite.fd` has capacity +File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity available for writing. This event always triggers for regular files. ## `eventrwflags`: Flags(`u16`) @@ -668,7 +668,7 @@ The state of the file descriptor subscribed to with The peer of this socket has closed or disconnected. ## `event_fd_readwrite`: Struct -The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -679,7 +679,7 @@ The number of bytes available for reading or writing. The state of the file descriptor. ## `event_u`: Union -The contents of an $event. +The contents of an [`event`](#event). ### Union variants - `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) @@ -703,18 +703,18 @@ The type of the event that occurred, and the contents of the event ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in -`subscription::u.clock.timeout.` +[`subscription_clock::timeout`](#subscription_clock.timeout). ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in -`subscription::u.clock.timeout` as an absolute timestamp of clock -`subscription::u.clock.clock_id.` If clear, treat the timestamp -provided in `subscription::u.clock.timeout` relative to the -current time value of clock `subscription::u.clock.clock_id.` +[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock +[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp +provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the +current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct -The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). +The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). ### Struct members - `id`: [`clockid`](#clockid) @@ -731,7 +731,7 @@ to coalesce with other events. Flags specifying whether the timeout is absolute or relative ## `subscription_fd_readwrite`: Struct -The contents of a $subscription when type is type is +The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -739,7 +739,7 @@ The contents of a $subscription when type is type is The file descriptor on which to wait for it to become ready for reading or writing. ## `subscription_u`: Union -The contents of a $subscription. +The contents of a [`subscription`](#subscription). ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -801,7 +801,7 @@ Identifiers for preopened capabilities. A pre-opened directory. ## `prestat_dir`: Struct -The contents of a $prestat when its $pr_type is [`preopentype::dir`](#preopentype.dir). +The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). ### Struct members - `pr_name_len`: [`size`](#size) @@ -859,7 +859,8 @@ The size of the argument string data. #### `res_get(id: clockid) -> (errno, timestamp)` Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, +return [`errno::inval`](#errno.inval). Note: This is similar to `clock_getres` in POSIX. ##### Params @@ -1035,7 +1036,7 @@ The desired values of the file descriptor flags. #### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights +This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights ##### Params - `fd`: [`fd`](#fd) @@ -1228,8 +1229,8 @@ The number of bytes read. #### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a dirent_t object, -followed by dirent_t::d_namlen bytes holding the name of the directory +directory entries. Each directory entry consists of a [`dirent`](#dirent) object, +followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory entry. This function fills the output buffer as much as possible, potentially truncating the last directory entry. This allows the caller to grow its @@ -1492,7 +1493,7 @@ Flags determining the method of how the path is resolved. - `path`: `string` The relative path of the file or directory to open, relative to the -`dirfd` directory. +[`fd`](#fd) directory. - `oflags`: [`oflags`](#oflags) The method by which to open the file. @@ -1548,7 +1549,7 @@ The number of bytes placed in the buffer. #### `remove_directory(fd: fd, path: string) -> errno` Remove a directory. -Return `ENOTEMPTY` if the directory is not empty. +Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. ##### Params @@ -1606,7 +1607,7 @@ The destination path at which to create the symbolic link. #### `unlink_file(fd: fd, path: string) -> errno` Unlink a file. -Return `EISDIR` if the path refers to a directory. +Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. ##### Params diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index b7ee26aa6..162c80f2b 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflag::dsync`. + ;;; `path_open` with `fdflags::dsync`. $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; @@ -209,10 +209,10 @@ ;;; The right to invoke `fd_sync`. ;; ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflag::rsync` and `fdflag::dsync`. + ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to ;;; invoke `fd_tell`. $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. @@ -322,7 +322,7 @@ ) ) -;;; The type for the $d_namlen field of $dirent. +;;; The type for the `dirent::d_namlen` field of `dirent`. (typename $dirnamlen u32) ;;; File serial number that is unique within its file system. @@ -424,13 +424,13 @@ ;;; Which file time attributes to adjust. (typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim - ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. $mtim_now ) ) @@ -522,13 +522,13 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype (enum u8 - ;;; The time value of clock `subscription::u.clock.clock_id` has - ;;; reached timestamp `subscription::u.clock.timeout`. + ;;; The time value of clock `subscription_clock::id` has + ;;; reached timestamp `subscription_clock::timeout`. $clock - ;;; File descriptor `subscription::u.fd_readwrite.fd` has data + ;;; File descriptor `subscription_fd_readwrite::fd` has data ;;; available for reading. This event always triggers for regular files. $fd_read - ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity + ;;; File descriptor `subscription_fd_readwrite::fd` has capacity ;;; available for writing. This event always triggers for regular files. $fd_write ) @@ -543,7 +543,7 @@ ) ) -;;; The contents of an $event when type is `eventtype::fd_read` or +;;; The contents of an `event` when type is `eventtype::fd_read` or ;;; `eventtype::fd_write`. (typename $event_fd_readwrite (struct @@ -554,7 +554,7 @@ ) ) -;;; The contents of an $event. +;;; The contents of an `event`. (typename $event_u (union $eventtype (field $fd_read $event_fd_readwrite) @@ -576,19 +576,19 @@ ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription::u.clock.timeout.` +;;; `subscription_clock::timeout`. (typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription::u.clock.timeout` relative to the - ;;; current time value of clock `subscription::u.clock.clock_id.` + ;;; `subscription_clock::timeout` as an absolute timestamp of clock + ;;; `subscription_clock::id`. If clear, treat the timestamp + ;;; provided in `subscription_clock::timeout` relative to the + ;;; current time value of clock `subscription_clock::id`. $subscription_clock_abstime ) ) -;;; The contents of a $subscription when type is `eventtype::clock`. +;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock (struct ;;; The clock against which to compare the timestamp. @@ -603,7 +603,7 @@ ) ) -;;; The contents of a $subscription when type is type is +;;; The contents of a `subscription` when type is type is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite (struct @@ -612,7 +612,7 @@ ) ) -;;; The contents of a $subscription. +;;; The contents of a `subscription`. (typename $subscription_u (union $eventtype (field $clock $subscription_clock) @@ -675,7 +675,7 @@ ) ) -;;; The contents of a $prestat when its $pr_type is `preopentype::dir`. +;;; The contents of a `prestat` when its type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx index b6d880443..65b8d0e15 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx @@ -12,7 +12,8 @@ (import "memory" (memory)) ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, + ;;; return `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "res_get") (result $error $errno) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx index e92dd4f91..2f3c618ff 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -68,7 +68,7 @@ ) ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights (@interface func (export "fdstat_set_rights") (param $fd $fd) ;;; The desired rights of the file descriptor. @@ -182,8 +182,8 @@ ;;; Read directory entries from a directory. ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a dirent_t object, - ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; directory entries. Each directory entry consists of a `dirent` object, + ;;; followed by `dirent::d_namlen` bytes holding the name of the directory ;;; entry. ;; ;;; This function fills the output buffer as much as possible, potentially diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx index dbd02dc1a..086637c96 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -102,7 +102,7 @@ ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the - ;;; `dirfd` directory. + ;;; `fd` directory. (param $path string) ;;; The method by which to open the file. (param $oflags $oflags) @@ -139,7 +139,7 @@ ) ;;; Remove a directory. - ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Return `errno::notempty` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "remove_directory") (param $fd $fd) @@ -173,7 +173,7 @@ ) ;;; Unlink a file. - ;;; Return `EISDIR` if the path refers to a directory. + ;;; Return `errno::isdir` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "unlink_file") (param $fd $fd) diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index 3466d13ad..4094320f8 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -272,7 +272,7 @@ File descriptor rights, determining which actions may be performed. - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke -[`path_open`](#path_open) with `FDFLAG_DSYNC`. +[`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). - `fd_read` The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). @@ -287,11 +287,11 @@ The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). - `fd_sync` The right to invoke [`fd_sync`](#fd_sync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke -[`path_open`](#path_open) with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. +[`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - `fd_tell` The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset -remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke [`fd_tell`](#fd_tell). - `fd_write` @@ -308,7 +308,7 @@ The right to invoke [`fd_allocate`](#fd_allocate). The right to invoke [`path_create_directory`](#path_create_directory). - `path_create_file` -If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with `O_CREAT`. +If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). - `path_link_source` The right to invoke [`path_link`](#path_link) with the file descriptor as the @@ -338,7 +338,7 @@ The right to invoke [`path_filestat_get`](#path_filestat_get). - `path_filestat_set_size` The right to change a file's size (there is no `path_filestat_set_size`). -If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with `O_TRUNC`. +If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). - `path_filestat_set_times` The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). @@ -533,16 +533,16 @@ Which file time attributes to adjust. ### Flags - `atim` -Adjust the last data access timestamp to the value stored in `filestat::st_atim`. +Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - `atim_now` -Adjust the last data access timestamp to the time of clock `clock::realtime`. +Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - `mtim` -Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. +Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - `mtim_now` -Adjust the last data modification timestamp to the time of clock `clock::realtime`. +Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. @@ -607,15 +607,15 @@ Type of a subscription to an event or its occurrence. ### Variants - `clock` -The time value of clock `subscription::u.clock.clock_id` has -reached timestamp `subscription::u.clock.timeout`. +The time value of clock [`subscription_clock::id`](#subscription_clock.id) has +reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - `fd_read` -File descriptor `subscription::u.fd_readwrite.fd` has data +File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has data available for reading. This event always triggers for regular files. - `fd_write` -File descriptor `subscription::u.fd_readwrite.fd` has capacity +File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. ## `eventrwflags`: Flags(`u16`) @@ -656,18 +656,18 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in -`subscription::u.clock.timeout.` +[`subscription_clock::timeout`](#subscription_clock.timeout). ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in -`subscription::u.clock.timeout` as an absolute timestamp of clock -`subscription::u.clock.clock_id.` If clear, treat the timestamp -provided in `subscription::u.clock.timeout` relative to the -current time value of clock `subscription::u.clock.clock_id.` +[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock +[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp +provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the +current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct -The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). +The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). ### Struct members - `identifier`: [`userdata`](#userdata) @@ -687,7 +687,7 @@ to coalesce with other events. Flags specifying whether the timeout is absolute or relative ## `subscription_fd_readwrite`: Struct -The contents of a $subscription when the variant is +The contents of a [`subscription`](#subscription) when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -695,7 +695,7 @@ The contents of a $subscription when the variant is The file descriptor on which to wait for it to become ready for reading or writing. ## `subscription_u`: Union -The contents of a $subscription. +The contents of a [`subscription`](#subscription). ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -885,7 +885,7 @@ Identifiers for preopened capabilities. A pre-opened directory. ## `prestat_dir`: Struct -The contents of a $prestat when type is `PREOPENTYPE_DIR`. +The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). ### Struct members - `pr_name_len`: [`size`](#size) @@ -907,7 +907,7 @@ Information about a pre-opened capability. #### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` Read command-line argument data. -The size of the array should match that returned by `wasi_args_sizes_get()` +The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) ##### Params - `argv`: `Pointer>` @@ -938,7 +938,7 @@ The size of the argument string data. #### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` Read environment variable data. -The sizes of the buffers should match that returned by `environ.sizes_get()`. +The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). ##### Params - `environ`: `Pointer>` @@ -969,7 +969,8 @@ The size of the argument string data. #### `clock_res_get(id: clockid) -> (errno, timestamp)` Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return +[`errno::inval`](#errno.inval). Note: This is similar to `clock_getres` in POSIX. ##### Params @@ -1106,7 +1107,7 @@ The desired values of the file descriptor flags. #### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights +This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights ##### Params - `fd`: [`fd`](#fd) @@ -1501,7 +1502,7 @@ Flags determining the method of how the path is resolved. - `path`: `string` The relative path of the file or directory to open, relative to the -`dirfd` directory. +[`fd`](#fd) directory. - `oflags`: [`oflags`](#oflags) The method by which to open the file. @@ -1554,7 +1555,7 @@ The number of bytes placed in the buffer. #### `path_remove_directory(fd: fd, path: string) -> errno` Remove a directory. -Return `ENOTEMPTY` if the directory is not empty. +Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. ##### Params @@ -1612,7 +1613,7 @@ The destination path at which to create the symbolic link. #### `path_unlink_file(fd: fd, path: string) -> errno` Unlink a file. -Return `EISDIR` if the path refers to a directory. +Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. ##### Params diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx index 493bda050..0efdb27a7 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx @@ -200,7 +200,7 @@ ;;; The right to invoke `fd_datasync`. ;; ;;; If `rights::path_open` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_DSYNC`. + ;;; `path_open` with `fdflags::dsync`. $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; @@ -213,10 +213,10 @@ ;;; The right to invoke `fd_sync`. ;; ;;; If `rights::path_open` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to ;;; invoke `fd_tell`. $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. @@ -228,7 +228,7 @@ $fd_allocate ;;; The right to invoke `path_create_directory`. $path_create_directory - ;;; If `rights::path_open` is set, the right to invoke `path_open` with `O_CREAT`. + ;;; If `rights::path_open` is set, the right to invoke `path_open` with `oflags::creat`. $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. @@ -249,7 +249,7 @@ ;;; The right to invoke `path_filestat_get`. $path_filestat_get ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `rights::path_open` is set, includes the right to invoke `path_open` with `O_TRUNC`. + ;;; If `rights::path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. $path_filestat_set_times @@ -417,13 +417,13 @@ ;;; Which file time attributes to adjust. (typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim - ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. $mtim_now ) ) @@ -482,13 +482,13 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype (enum u8 - ;;; The time value of clock `subscription::u.clock.clock_id` has - ;;; reached timestamp `subscription::u.clock.timeout`. + ;;; The time value of clock `subscription_clock::id` has + ;;; reached timestamp `subscription_clock::timeout`. $clock - ;;; File descriptor `subscription::u.fd_readwrite.fd` has data + ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has data ;;; available for reading. This event always triggers for regular files. $fd_read - ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity + ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has capacity ;;; available for writing. This event always triggers for regular files. $fd_write ) @@ -530,19 +530,19 @@ ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription::u.clock.timeout.` +;;; `subscription_clock::timeout`. (typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription::u.clock.timeout` relative to the - ;;; current time value of clock `subscription::u.clock.clock_id.` + ;;; `subscription_clock::timeout` as an absolute timestamp of clock + ;;; `subscription_clock::id`. If clear, treat the timestamp + ;;; provided in `subscription_clock::timeout` relative to the + ;;; current time value of clock `subscription_clock::id`. $subscription_clock_abstime ) ) -;;; The contents of a $subscription when type is `eventtype::clock`. +;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock (struct ;;; The user-defined unique identifier of the clock. @@ -559,7 +559,7 @@ ) ) -;;; The contents of a $subscription when the variant is +;;; The contents of a `subscription` when the variant is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite (struct @@ -568,7 +568,7 @@ ) ) -;;; The contents of a $subscription. +;;; The contents of a `subscription`. (typename $subscription_u (union $eventtype (field $clock $subscription_clock) @@ -730,7 +730,7 @@ ) ) -;;; The contents of a $prestat when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. diff --git a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx index 5e125caf2..3b7dcb0cf 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -16,7 +16,7 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; The size of the array should match that returned by `args_sizes_get` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) @@ -32,7 +32,7 @@ ) ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) @@ -48,7 +48,8 @@ ) ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return + ;;; `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno) @@ -126,7 +127,7 @@ ) ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd) ;;; The desired rights of the file descriptor. @@ -366,7 +367,7 @@ ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the - ;;; `dirfd` directory. + ;;; `fd` directory. (param $path string) ;;; The method by which to open the file. (param $oflags $oflags) @@ -401,7 +402,7 @@ ) ;;; Remove a directory. - ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Return `errno::notempty` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd) @@ -436,7 +437,7 @@ ;;; Unlink a file. - ;;; Return `EISDIR` if the path refers to a directory. + ;;; Return `errno::isdir` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd) diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index 0b3dec378..0578d3f50 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -669,7 +669,7 @@ provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relativ current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct -The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). +The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). ### Struct members - `id`: [`clockid`](#clockid) @@ -686,7 +686,7 @@ to coalesce with other events. Flags specifying whether the timeout is absolute or relative ## `subscription_fd_readwrite`: Struct -The contents of a $subscription when type is type is +The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -694,7 +694,7 @@ The contents of a $subscription when type is type is The file descriptor on which to wait for it to become ready for reading or writing. ## `subscription_u`: Union -The contents of a $subscription. +The contents of a [`subscription`](#subscription). ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx index eb8cb8c64..27d84cd5f 100644 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -544,7 +544,7 @@ ) ) -;;; The contents of a $subscription when type is `eventtype::clock`. +;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock (struct ;;; The clock against which to compare the timestamp. @@ -559,7 +559,7 @@ ) ) -;;; The contents of a $subscription when type is type is +;;; The contents of a `subscription` when type is type is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite (struct @@ -568,7 +568,7 @@ ) ) -;;; The contents of a $subscription. +;;; The contents of a `subscription`. (typename $subscription_u (union $eventtype (field $clock $subscription_clock) From 7cb07f448e2ee6d1b4bb0993b9fd75cc153c44f4 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 21 Feb 2020 19:22:56 +0100 Subject: [PATCH 0566/1772] Fix dead links across all snapshots (#226) This commit fixes dead links (most likely not all of them, but at least a large number) across all snapshots. --- proposals/random/phases/ephemeral/docs.md | 61 ++++++++++--------- .../phases/ephemeral/witx/typenames.witx | 46 +++++++------- .../ephemeral/witx/wasi_ephemeral_clock.witx | 3 +- .../ephemeral/witx/wasi_ephemeral_fd.witx | 6 +- .../ephemeral/witx/wasi_ephemeral_path.witx | 6 +- .../random/phases/old/snapshot_0/docs.md | 59 +++++++++--------- .../phases/old/snapshot_0/witx/typenames.witx | 44 ++++++------- .../old/snapshot_0/witx/wasi_unstable.witx | 15 ++--- proposals/random/phases/snapshot/docs.md | 6 +- .../phases/snapshot/witx/typenames.witx | 6 +- 10 files changed, 128 insertions(+), 124 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index d69e10f0b..8f19cc8c2 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -266,7 +266,7 @@ File descriptor rights, determining which actions may be performed. - `fd_datasync` The right to invoke `fd_datasync`. If `path_open` is set, includes the right to invoke -`path_open` with `fdflag::dsync`. +`path_open` with [`fdflags::dsync`](#fdflags.dsync). - `fd_read` The right to invoke `fd_read` and `sock_recv`. @@ -281,11 +281,11 @@ The right to invoke `fd_fdstat_set_flags`. - `fd_sync` The right to invoke `fd_sync`. If `path_open` is set, includes the right to invoke -`path_open` with `fdflag::rsync` and `fdflag::dsync`. +`path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - `fd_tell` The right to invoke `fd_seek` in such a way that the file offset -remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke `fd_tell`. - `fd_write` @@ -420,7 +420,7 @@ A reference to the offset of a directory entry. In an `fd_readdir` call, this value signifies the start of the directory. ## `dirnamlen`: `u32` -The type for the $d_namlen field of $dirent. +The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). ## `inode`: `u64` File serial number that is unique within its file system. @@ -541,16 +541,16 @@ Which file time attributes to adjust. ### Flags - `atim` -Adjust the last data access timestamp to the value stored in `filestat::st_atim`. +Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - `atim_now` -Adjust the last data access timestamp to the time of clock `clock::realtime`. +Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - `mtim` -Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. +Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - `mtim_now` -Adjust the last data modification timestamp to the time of clock `clock::realtime`. +Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. @@ -648,15 +648,15 @@ Type of a subscription to an event or its occurrence. ### Variants - `clock` -The time value of clock `subscription::u.clock.clock_id` has -reached timestamp `subscription::u.clock.timeout`. +The time value of clock [`subscription_clock::id`](#subscription_clock.id) has +reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - `fd_read` -File descriptor `subscription::u.fd_readwrite.fd` has data +File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has data available for reading. This event always triggers for regular files. - `fd_write` -File descriptor `subscription::u.fd_readwrite.fd` has capacity +File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity available for writing. This event always triggers for regular files. ## `eventrwflags`: Flags(`u16`) @@ -668,7 +668,7 @@ The state of the file descriptor subscribed to with The peer of this socket has closed or disconnected. ## `event_fd_readwrite`: Struct -The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -679,7 +679,7 @@ The number of bytes available for reading or writing. The state of the file descriptor. ## `event_u`: Union -The contents of an $event. +The contents of an [`event`](#event). ### Union variants - `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) @@ -703,18 +703,18 @@ The type of the event that occurred, and the contents of the event ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in -`subscription::u.clock.timeout.` +[`subscription_clock::timeout`](#subscription_clock.timeout). ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in -`subscription::u.clock.timeout` as an absolute timestamp of clock -`subscription::u.clock.clock_id.` If clear, treat the timestamp -provided in `subscription::u.clock.timeout` relative to the -current time value of clock `subscription::u.clock.clock_id.` +[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock +[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp +provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the +current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct -The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). +The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). ### Struct members - `id`: [`clockid`](#clockid) @@ -731,7 +731,7 @@ to coalesce with other events. Flags specifying whether the timeout is absolute or relative ## `subscription_fd_readwrite`: Struct -The contents of a $subscription when type is type is +The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -739,7 +739,7 @@ The contents of a $subscription when type is type is The file descriptor on which to wait for it to become ready for reading or writing. ## `subscription_u`: Union -The contents of a $subscription. +The contents of a [`subscription`](#subscription). ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -801,7 +801,7 @@ Identifiers for preopened capabilities. A pre-opened directory. ## `prestat_dir`: Struct -The contents of a $prestat when its $pr_type is [`preopentype::dir`](#preopentype.dir). +The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). ### Struct members - `pr_name_len`: [`size`](#size) @@ -859,7 +859,8 @@ The size of the argument string data. #### `res_get(id: clockid) -> (errno, timestamp)` Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, +return [`errno::inval`](#errno.inval). Note: This is similar to `clock_getres` in POSIX. ##### Params @@ -1035,7 +1036,7 @@ The desired values of the file descriptor flags. #### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights +This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights ##### Params - `fd`: [`fd`](#fd) @@ -1228,8 +1229,8 @@ The number of bytes read. #### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a dirent_t object, -followed by dirent_t::d_namlen bytes holding the name of the directory +directory entries. Each directory entry consists of a [`dirent`](#dirent) object, +followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory entry. This function fills the output buffer as much as possible, potentially truncating the last directory entry. This allows the caller to grow its @@ -1492,7 +1493,7 @@ Flags determining the method of how the path is resolved. - `path`: `string` The relative path of the file or directory to open, relative to the -`dirfd` directory. +[`fd`](#fd) directory. - `oflags`: [`oflags`](#oflags) The method by which to open the file. @@ -1548,7 +1549,7 @@ The number of bytes placed in the buffer. #### `remove_directory(fd: fd, path: string) -> errno` Remove a directory. -Return `ENOTEMPTY` if the directory is not empty. +Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. ##### Params @@ -1606,7 +1607,7 @@ The destination path at which to create the symbolic link. #### `unlink_file(fd: fd, path: string) -> errno` Unlink a file. -Return `EISDIR` if the path refers to a directory. +Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. ##### Params diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index b7ee26aa6..162c80f2b 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflag::dsync`. + ;;; `path_open` with `fdflags::dsync`. $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; @@ -209,10 +209,10 @@ ;;; The right to invoke `fd_sync`. ;; ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflag::rsync` and `fdflag::dsync`. + ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to ;;; invoke `fd_tell`. $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. @@ -322,7 +322,7 @@ ) ) -;;; The type for the $d_namlen field of $dirent. +;;; The type for the `dirent::d_namlen` field of `dirent`. (typename $dirnamlen u32) ;;; File serial number that is unique within its file system. @@ -424,13 +424,13 @@ ;;; Which file time attributes to adjust. (typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim - ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. $mtim_now ) ) @@ -522,13 +522,13 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype (enum u8 - ;;; The time value of clock `subscription::u.clock.clock_id` has - ;;; reached timestamp `subscription::u.clock.timeout`. + ;;; The time value of clock `subscription_clock::id` has + ;;; reached timestamp `subscription_clock::timeout`. $clock - ;;; File descriptor `subscription::u.fd_readwrite.fd` has data + ;;; File descriptor `subscription_fd_readwrite::fd` has data ;;; available for reading. This event always triggers for regular files. $fd_read - ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity + ;;; File descriptor `subscription_fd_readwrite::fd` has capacity ;;; available for writing. This event always triggers for regular files. $fd_write ) @@ -543,7 +543,7 @@ ) ) -;;; The contents of an $event when type is `eventtype::fd_read` or +;;; The contents of an `event` when type is `eventtype::fd_read` or ;;; `eventtype::fd_write`. (typename $event_fd_readwrite (struct @@ -554,7 +554,7 @@ ) ) -;;; The contents of an $event. +;;; The contents of an `event`. (typename $event_u (union $eventtype (field $fd_read $event_fd_readwrite) @@ -576,19 +576,19 @@ ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription::u.clock.timeout.` +;;; `subscription_clock::timeout`. (typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription::u.clock.timeout` relative to the - ;;; current time value of clock `subscription::u.clock.clock_id.` + ;;; `subscription_clock::timeout` as an absolute timestamp of clock + ;;; `subscription_clock::id`. If clear, treat the timestamp + ;;; provided in `subscription_clock::timeout` relative to the + ;;; current time value of clock `subscription_clock::id`. $subscription_clock_abstime ) ) -;;; The contents of a $subscription when type is `eventtype::clock`. +;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock (struct ;;; The clock against which to compare the timestamp. @@ -603,7 +603,7 @@ ) ) -;;; The contents of a $subscription when type is type is +;;; The contents of a `subscription` when type is type is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite (struct @@ -612,7 +612,7 @@ ) ) -;;; The contents of a $subscription. +;;; The contents of a `subscription`. (typename $subscription_u (union $eventtype (field $clock $subscription_clock) @@ -675,7 +675,7 @@ ) ) -;;; The contents of a $prestat when its $pr_type is `preopentype::dir`. +;;; The contents of a `prestat` when its type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx index b6d880443..65b8d0e15 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx @@ -12,7 +12,8 @@ (import "memory" (memory)) ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, + ;;; return `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "res_get") (result $error $errno) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx index e92dd4f91..2f3c618ff 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -68,7 +68,7 @@ ) ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights (@interface func (export "fdstat_set_rights") (param $fd $fd) ;;; The desired rights of the file descriptor. @@ -182,8 +182,8 @@ ;;; Read directory entries from a directory. ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a dirent_t object, - ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; directory entries. Each directory entry consists of a `dirent` object, + ;;; followed by `dirent::d_namlen` bytes holding the name of the directory ;;; entry. ;; ;;; This function fills the output buffer as much as possible, potentially diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx index dbd02dc1a..086637c96 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -102,7 +102,7 @@ ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the - ;;; `dirfd` directory. + ;;; `fd` directory. (param $path string) ;;; The method by which to open the file. (param $oflags $oflags) @@ -139,7 +139,7 @@ ) ;;; Remove a directory. - ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Return `errno::notempty` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "remove_directory") (param $fd $fd) @@ -173,7 +173,7 @@ ) ;;; Unlink a file. - ;;; Return `EISDIR` if the path refers to a directory. + ;;; Return `errno::isdir` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "unlink_file") (param $fd $fd) diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index 3466d13ad..4094320f8 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -272,7 +272,7 @@ File descriptor rights, determining which actions may be performed. - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke -[`path_open`](#path_open) with `FDFLAG_DSYNC`. +[`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). - `fd_read` The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). @@ -287,11 +287,11 @@ The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). - `fd_sync` The right to invoke [`fd_sync`](#fd_sync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke -[`path_open`](#path_open) with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. +[`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - `fd_tell` The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset -remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke [`fd_tell`](#fd_tell). - `fd_write` @@ -308,7 +308,7 @@ The right to invoke [`fd_allocate`](#fd_allocate). The right to invoke [`path_create_directory`](#path_create_directory). - `path_create_file` -If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with `O_CREAT`. +If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). - `path_link_source` The right to invoke [`path_link`](#path_link) with the file descriptor as the @@ -338,7 +338,7 @@ The right to invoke [`path_filestat_get`](#path_filestat_get). - `path_filestat_set_size` The right to change a file's size (there is no `path_filestat_set_size`). -If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with `O_TRUNC`. +If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). - `path_filestat_set_times` The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). @@ -533,16 +533,16 @@ Which file time attributes to adjust. ### Flags - `atim` -Adjust the last data access timestamp to the value stored in `filestat::st_atim`. +Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - `atim_now` -Adjust the last data access timestamp to the time of clock `clock::realtime`. +Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - `mtim` -Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. +Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - `mtim_now` -Adjust the last data modification timestamp to the time of clock `clock::realtime`. +Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. @@ -607,15 +607,15 @@ Type of a subscription to an event or its occurrence. ### Variants - `clock` -The time value of clock `subscription::u.clock.clock_id` has -reached timestamp `subscription::u.clock.timeout`. +The time value of clock [`subscription_clock::id`](#subscription_clock.id) has +reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - `fd_read` -File descriptor `subscription::u.fd_readwrite.fd` has data +File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has data available for reading. This event always triggers for regular files. - `fd_write` -File descriptor `subscription::u.fd_readwrite.fd` has capacity +File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. ## `eventrwflags`: Flags(`u16`) @@ -656,18 +656,18 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in -`subscription::u.clock.timeout.` +[`subscription_clock::timeout`](#subscription_clock.timeout). ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in -`subscription::u.clock.timeout` as an absolute timestamp of clock -`subscription::u.clock.clock_id.` If clear, treat the timestamp -provided in `subscription::u.clock.timeout` relative to the -current time value of clock `subscription::u.clock.clock_id.` +[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock +[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp +provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the +current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct -The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). +The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). ### Struct members - `identifier`: [`userdata`](#userdata) @@ -687,7 +687,7 @@ to coalesce with other events. Flags specifying whether the timeout is absolute or relative ## `subscription_fd_readwrite`: Struct -The contents of a $subscription when the variant is +The contents of a [`subscription`](#subscription) when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -695,7 +695,7 @@ The contents of a $subscription when the variant is The file descriptor on which to wait for it to become ready for reading or writing. ## `subscription_u`: Union -The contents of a $subscription. +The contents of a [`subscription`](#subscription). ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -885,7 +885,7 @@ Identifiers for preopened capabilities. A pre-opened directory. ## `prestat_dir`: Struct -The contents of a $prestat when type is `PREOPENTYPE_DIR`. +The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). ### Struct members - `pr_name_len`: [`size`](#size) @@ -907,7 +907,7 @@ Information about a pre-opened capability. #### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` Read command-line argument data. -The size of the array should match that returned by `wasi_args_sizes_get()` +The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) ##### Params - `argv`: `Pointer>` @@ -938,7 +938,7 @@ The size of the argument string data. #### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` Read environment variable data. -The sizes of the buffers should match that returned by `environ.sizes_get()`. +The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). ##### Params - `environ`: `Pointer>` @@ -969,7 +969,8 @@ The size of the argument string data. #### `clock_res_get(id: clockid) -> (errno, timestamp)` Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return +[`errno::inval`](#errno.inval). Note: This is similar to `clock_getres` in POSIX. ##### Params @@ -1106,7 +1107,7 @@ The desired values of the file descriptor flags. #### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights +This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights ##### Params - `fd`: [`fd`](#fd) @@ -1501,7 +1502,7 @@ Flags determining the method of how the path is resolved. - `path`: `string` The relative path of the file or directory to open, relative to the -`dirfd` directory. +[`fd`](#fd) directory. - `oflags`: [`oflags`](#oflags) The method by which to open the file. @@ -1554,7 +1555,7 @@ The number of bytes placed in the buffer. #### `path_remove_directory(fd: fd, path: string) -> errno` Remove a directory. -Return `ENOTEMPTY` if the directory is not empty. +Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. ##### Params @@ -1612,7 +1613,7 @@ The destination path at which to create the symbolic link. #### `path_unlink_file(fd: fd, path: string) -> errno` Unlink a file. -Return `EISDIR` if the path refers to a directory. +Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. ##### Params diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx index 493bda050..0efdb27a7 100644 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/random/phases/old/snapshot_0/witx/typenames.witx @@ -200,7 +200,7 @@ ;;; The right to invoke `fd_datasync`. ;; ;;; If `rights::path_open` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_DSYNC`. + ;;; `path_open` with `fdflags::dsync`. $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; @@ -213,10 +213,10 @@ ;;; The right to invoke `fd_sync`. ;; ;;; If `rights::path_open` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to ;;; invoke `fd_tell`. $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. @@ -228,7 +228,7 @@ $fd_allocate ;;; The right to invoke `path_create_directory`. $path_create_directory - ;;; If `rights::path_open` is set, the right to invoke `path_open` with `O_CREAT`. + ;;; If `rights::path_open` is set, the right to invoke `path_open` with `oflags::creat`. $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. @@ -249,7 +249,7 @@ ;;; The right to invoke `path_filestat_get`. $path_filestat_get ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `rights::path_open` is set, includes the right to invoke `path_open` with `O_TRUNC`. + ;;; If `rights::path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. $path_filestat_set_times @@ -417,13 +417,13 @@ ;;; Which file time attributes to adjust. (typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim - ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. $mtim_now ) ) @@ -482,13 +482,13 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype (enum u8 - ;;; The time value of clock `subscription::u.clock.clock_id` has - ;;; reached timestamp `subscription::u.clock.timeout`. + ;;; The time value of clock `subscription_clock::id` has + ;;; reached timestamp `subscription_clock::timeout`. $clock - ;;; File descriptor `subscription::u.fd_readwrite.fd` has data + ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has data ;;; available for reading. This event always triggers for regular files. $fd_read - ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity + ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has capacity ;;; available for writing. This event always triggers for regular files. $fd_write ) @@ -530,19 +530,19 @@ ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription::u.clock.timeout.` +;;; `subscription_clock::timeout`. (typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription::u.clock.timeout` relative to the - ;;; current time value of clock `subscription::u.clock.clock_id.` + ;;; `subscription_clock::timeout` as an absolute timestamp of clock + ;;; `subscription_clock::id`. If clear, treat the timestamp + ;;; provided in `subscription_clock::timeout` relative to the + ;;; current time value of clock `subscription_clock::id`. $subscription_clock_abstime ) ) -;;; The contents of a $subscription when type is `eventtype::clock`. +;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock (struct ;;; The user-defined unique identifier of the clock. @@ -559,7 +559,7 @@ ) ) -;;; The contents of a $subscription when the variant is +;;; The contents of a `subscription` when the variant is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite (struct @@ -568,7 +568,7 @@ ) ) -;;; The contents of a $subscription. +;;; The contents of a `subscription`. (typename $subscription_u (union $eventtype (field $clock $subscription_clock) @@ -730,7 +730,7 @@ ) ) -;;; The contents of a $prestat when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. diff --git a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx index 5e125caf2..3b7dcb0cf 100644 --- a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -16,7 +16,7 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; The size of the array should match that returned by `args_sizes_get` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) @@ -32,7 +32,7 @@ ) ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) @@ -48,7 +48,8 @@ ) ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return + ;;; `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno) @@ -126,7 +127,7 @@ ) ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd) ;;; The desired rights of the file descriptor. @@ -366,7 +367,7 @@ ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the - ;;; `dirfd` directory. + ;;; `fd` directory. (param $path string) ;;; The method by which to open the file. (param $oflags $oflags) @@ -401,7 +402,7 @@ ) ;;; Remove a directory. - ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Return `errno::notempty` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd) @@ -436,7 +437,7 @@ ;;; Unlink a file. - ;;; Return `EISDIR` if the path refers to a directory. + ;;; Return `errno::isdir` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd) diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index 0b3dec378..0578d3f50 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -669,7 +669,7 @@ provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relativ current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct -The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). +The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). ### Struct members - `id`: [`clockid`](#clockid) @@ -686,7 +686,7 @@ to coalesce with other events. Flags specifying whether the timeout is absolute or relative ## `subscription_fd_readwrite`: Struct -The contents of a $subscription when type is type is +The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -694,7 +694,7 @@ The contents of a $subscription when type is type is The file descriptor on which to wait for it to become ready for reading or writing. ## `subscription_u`: Union -The contents of a $subscription. +The contents of a [`subscription`](#subscription). ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx index eb8cb8c64..27d84cd5f 100644 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -544,7 +544,7 @@ ) ) -;;; The contents of a $subscription when type is `eventtype::clock`. +;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock (struct ;;; The clock against which to compare the timestamp. @@ -559,7 +559,7 @@ ) ) -;;; The contents of a $subscription when type is type is +;;; The contents of a `subscription` when type is type is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite (struct @@ -568,7 +568,7 @@ ) ) -;;; The contents of a $subscription. +;;; The contents of a `subscription`. (typename $subscription_u (union $eventtype (field $clock $subscription_clock) From 06f2e6516c82e7af698aec9c5a2ff20006089b5a Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 21 Feb 2020 19:22:56 +0100 Subject: [PATCH 0567/1772] Fix dead links across all snapshots (#226) This commit fixes dead links (most likely not all of them, but at least a large number) across all snapshots. --- proposals/filesystem/phases/ephemeral/docs.md | 61 ++++++++++--------- .../phases/ephemeral/witx/typenames.witx | 46 +++++++------- .../ephemeral/witx/wasi_ephemeral_clock.witx | 3 +- .../ephemeral/witx/wasi_ephemeral_fd.witx | 6 +- .../ephemeral/witx/wasi_ephemeral_path.witx | 6 +- .../filesystem/phases/old/snapshot_0/docs.md | 59 +++++++++--------- .../phases/old/snapshot_0/witx/typenames.witx | 44 ++++++------- .../old/snapshot_0/witx/wasi_unstable.witx | 15 ++--- proposals/filesystem/phases/snapshot/docs.md | 6 +- .../phases/snapshot/witx/typenames.witx | 6 +- 10 files changed, 128 insertions(+), 124 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index d69e10f0b..8f19cc8c2 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -266,7 +266,7 @@ File descriptor rights, determining which actions may be performed. - `fd_datasync` The right to invoke `fd_datasync`. If `path_open` is set, includes the right to invoke -`path_open` with `fdflag::dsync`. +`path_open` with [`fdflags::dsync`](#fdflags.dsync). - `fd_read` The right to invoke `fd_read` and `sock_recv`. @@ -281,11 +281,11 @@ The right to invoke `fd_fdstat_set_flags`. - `fd_sync` The right to invoke `fd_sync`. If `path_open` is set, includes the right to invoke -`path_open` with `fdflag::rsync` and `fdflag::dsync`. +`path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - `fd_tell` The right to invoke `fd_seek` in such a way that the file offset -remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke `fd_tell`. - `fd_write` @@ -420,7 +420,7 @@ A reference to the offset of a directory entry. In an `fd_readdir` call, this value signifies the start of the directory. ## `dirnamlen`: `u32` -The type for the $d_namlen field of $dirent. +The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). ## `inode`: `u64` File serial number that is unique within its file system. @@ -541,16 +541,16 @@ Which file time attributes to adjust. ### Flags - `atim` -Adjust the last data access timestamp to the value stored in `filestat::st_atim`. +Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - `atim_now` -Adjust the last data access timestamp to the time of clock `clock::realtime`. +Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - `mtim` -Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. +Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - `mtim_now` -Adjust the last data modification timestamp to the time of clock `clock::realtime`. +Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. @@ -648,15 +648,15 @@ Type of a subscription to an event or its occurrence. ### Variants - `clock` -The time value of clock `subscription::u.clock.clock_id` has -reached timestamp `subscription::u.clock.timeout`. +The time value of clock [`subscription_clock::id`](#subscription_clock.id) has +reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - `fd_read` -File descriptor `subscription::u.fd_readwrite.fd` has data +File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has data available for reading. This event always triggers for regular files. - `fd_write` -File descriptor `subscription::u.fd_readwrite.fd` has capacity +File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity available for writing. This event always triggers for regular files. ## `eventrwflags`: Flags(`u16`) @@ -668,7 +668,7 @@ The state of the file descriptor subscribed to with The peer of this socket has closed or disconnected. ## `event_fd_readwrite`: Struct -The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -679,7 +679,7 @@ The number of bytes available for reading or writing. The state of the file descriptor. ## `event_u`: Union -The contents of an $event. +The contents of an [`event`](#event). ### Union variants - `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) @@ -703,18 +703,18 @@ The type of the event that occurred, and the contents of the event ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in -`subscription::u.clock.timeout.` +[`subscription_clock::timeout`](#subscription_clock.timeout). ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in -`subscription::u.clock.timeout` as an absolute timestamp of clock -`subscription::u.clock.clock_id.` If clear, treat the timestamp -provided in `subscription::u.clock.timeout` relative to the -current time value of clock `subscription::u.clock.clock_id.` +[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock +[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp +provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the +current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct -The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). +The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). ### Struct members - `id`: [`clockid`](#clockid) @@ -731,7 +731,7 @@ to coalesce with other events. Flags specifying whether the timeout is absolute or relative ## `subscription_fd_readwrite`: Struct -The contents of a $subscription when type is type is +The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -739,7 +739,7 @@ The contents of a $subscription when type is type is The file descriptor on which to wait for it to become ready for reading or writing. ## `subscription_u`: Union -The contents of a $subscription. +The contents of a [`subscription`](#subscription). ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -801,7 +801,7 @@ Identifiers for preopened capabilities. A pre-opened directory. ## `prestat_dir`: Struct -The contents of a $prestat when its $pr_type is [`preopentype::dir`](#preopentype.dir). +The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). ### Struct members - `pr_name_len`: [`size`](#size) @@ -859,7 +859,8 @@ The size of the argument string data. #### `res_get(id: clockid) -> (errno, timestamp)` Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, +return [`errno::inval`](#errno.inval). Note: This is similar to `clock_getres` in POSIX. ##### Params @@ -1035,7 +1036,7 @@ The desired values of the file descriptor flags. #### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights +This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights ##### Params - `fd`: [`fd`](#fd) @@ -1228,8 +1229,8 @@ The number of bytes read. #### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a dirent_t object, -followed by dirent_t::d_namlen bytes holding the name of the directory +directory entries. Each directory entry consists of a [`dirent`](#dirent) object, +followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory entry. This function fills the output buffer as much as possible, potentially truncating the last directory entry. This allows the caller to grow its @@ -1492,7 +1493,7 @@ Flags determining the method of how the path is resolved. - `path`: `string` The relative path of the file or directory to open, relative to the -`dirfd` directory. +[`fd`](#fd) directory. - `oflags`: [`oflags`](#oflags) The method by which to open the file. @@ -1548,7 +1549,7 @@ The number of bytes placed in the buffer. #### `remove_directory(fd: fd, path: string) -> errno` Remove a directory. -Return `ENOTEMPTY` if the directory is not empty. +Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. ##### Params @@ -1606,7 +1607,7 @@ The destination path at which to create the symbolic link. #### `unlink_file(fd: fd, path: string) -> errno` Unlink a file. -Return `EISDIR` if the path refers to a directory. +Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. ##### Params diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index b7ee26aa6..162c80f2b 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflag::dsync`. + ;;; `path_open` with `fdflags::dsync`. $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; @@ -209,10 +209,10 @@ ;;; The right to invoke `fd_sync`. ;; ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflag::rsync` and `fdflag::dsync`. + ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to ;;; invoke `fd_tell`. $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. @@ -322,7 +322,7 @@ ) ) -;;; The type for the $d_namlen field of $dirent. +;;; The type for the `dirent::d_namlen` field of `dirent`. (typename $dirnamlen u32) ;;; File serial number that is unique within its file system. @@ -424,13 +424,13 @@ ;;; Which file time attributes to adjust. (typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim - ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. $mtim_now ) ) @@ -522,13 +522,13 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype (enum u8 - ;;; The time value of clock `subscription::u.clock.clock_id` has - ;;; reached timestamp `subscription::u.clock.timeout`. + ;;; The time value of clock `subscription_clock::id` has + ;;; reached timestamp `subscription_clock::timeout`. $clock - ;;; File descriptor `subscription::u.fd_readwrite.fd` has data + ;;; File descriptor `subscription_fd_readwrite::fd` has data ;;; available for reading. This event always triggers for regular files. $fd_read - ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity + ;;; File descriptor `subscription_fd_readwrite::fd` has capacity ;;; available for writing. This event always triggers for regular files. $fd_write ) @@ -543,7 +543,7 @@ ) ) -;;; The contents of an $event when type is `eventtype::fd_read` or +;;; The contents of an `event` when type is `eventtype::fd_read` or ;;; `eventtype::fd_write`. (typename $event_fd_readwrite (struct @@ -554,7 +554,7 @@ ) ) -;;; The contents of an $event. +;;; The contents of an `event`. (typename $event_u (union $eventtype (field $fd_read $event_fd_readwrite) @@ -576,19 +576,19 @@ ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription::u.clock.timeout.` +;;; `subscription_clock::timeout`. (typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription::u.clock.timeout` relative to the - ;;; current time value of clock `subscription::u.clock.clock_id.` + ;;; `subscription_clock::timeout` as an absolute timestamp of clock + ;;; `subscription_clock::id`. If clear, treat the timestamp + ;;; provided in `subscription_clock::timeout` relative to the + ;;; current time value of clock `subscription_clock::id`. $subscription_clock_abstime ) ) -;;; The contents of a $subscription when type is `eventtype::clock`. +;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock (struct ;;; The clock against which to compare the timestamp. @@ -603,7 +603,7 @@ ) ) -;;; The contents of a $subscription when type is type is +;;; The contents of a `subscription` when type is type is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite (struct @@ -612,7 +612,7 @@ ) ) -;;; The contents of a $subscription. +;;; The contents of a `subscription`. (typename $subscription_u (union $eventtype (field $clock $subscription_clock) @@ -675,7 +675,7 @@ ) ) -;;; The contents of a $prestat when its $pr_type is `preopentype::dir`. +;;; The contents of a `prestat` when its type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx index b6d880443..65b8d0e15 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx @@ -12,7 +12,8 @@ (import "memory" (memory)) ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, + ;;; return `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "res_get") (result $error $errno) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx index e92dd4f91..2f3c618ff 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -68,7 +68,7 @@ ) ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights (@interface func (export "fdstat_set_rights") (param $fd $fd) ;;; The desired rights of the file descriptor. @@ -182,8 +182,8 @@ ;;; Read directory entries from a directory. ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a dirent_t object, - ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; directory entries. Each directory entry consists of a `dirent` object, + ;;; followed by `dirent::d_namlen` bytes holding the name of the directory ;;; entry. ;; ;;; This function fills the output buffer as much as possible, potentially diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx index dbd02dc1a..086637c96 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -102,7 +102,7 @@ ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the - ;;; `dirfd` directory. + ;;; `fd` directory. (param $path string) ;;; The method by which to open the file. (param $oflags $oflags) @@ -139,7 +139,7 @@ ) ;;; Remove a directory. - ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Return `errno::notempty` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "remove_directory") (param $fd $fd) @@ -173,7 +173,7 @@ ) ;;; Unlink a file. - ;;; Return `EISDIR` if the path refers to a directory. + ;;; Return `errno::isdir` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "unlink_file") (param $fd $fd) diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index 3466d13ad..4094320f8 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -272,7 +272,7 @@ File descriptor rights, determining which actions may be performed. - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke -[`path_open`](#path_open) with `FDFLAG_DSYNC`. +[`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). - `fd_read` The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). @@ -287,11 +287,11 @@ The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). - `fd_sync` The right to invoke [`fd_sync`](#fd_sync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke -[`path_open`](#path_open) with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. +[`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - `fd_tell` The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset -remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to +remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke [`fd_tell`](#fd_tell). - `fd_write` @@ -308,7 +308,7 @@ The right to invoke [`fd_allocate`](#fd_allocate). The right to invoke [`path_create_directory`](#path_create_directory). - `path_create_file` -If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with `O_CREAT`. +If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). - `path_link_source` The right to invoke [`path_link`](#path_link) with the file descriptor as the @@ -338,7 +338,7 @@ The right to invoke [`path_filestat_get`](#path_filestat_get). - `path_filestat_set_size` The right to change a file's size (there is no `path_filestat_set_size`). -If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with `O_TRUNC`. +If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). - `path_filestat_set_times` The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). @@ -533,16 +533,16 @@ Which file time attributes to adjust. ### Flags - `atim` -Adjust the last data access timestamp to the value stored in `filestat::st_atim`. +Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - `atim_now` -Adjust the last data access timestamp to the time of clock `clock::realtime`. +Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - `mtim` -Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. +Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - `mtim_now` -Adjust the last data modification timestamp to the time of clock `clock::realtime`. +Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. @@ -607,15 +607,15 @@ Type of a subscription to an event or its occurrence. ### Variants - `clock` -The time value of clock `subscription::u.clock.clock_id` has -reached timestamp `subscription::u.clock.timeout`. +The time value of clock [`subscription_clock::id`](#subscription_clock.id) has +reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - `fd_read` -File descriptor `subscription::u.fd_readwrite.fd` has data +File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has data available for reading. This event always triggers for regular files. - `fd_write` -File descriptor `subscription::u.fd_readwrite.fd` has capacity +File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. ## `eventrwflags`: Flags(`u16`) @@ -656,18 +656,18 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in -`subscription::u.clock.timeout.` +[`subscription_clock::timeout`](#subscription_clock.timeout). ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in -`subscription::u.clock.timeout` as an absolute timestamp of clock -`subscription::u.clock.clock_id.` If clear, treat the timestamp -provided in `subscription::u.clock.timeout` relative to the -current time value of clock `subscription::u.clock.clock_id.` +[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock +[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp +provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the +current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct -The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). +The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). ### Struct members - `identifier`: [`userdata`](#userdata) @@ -687,7 +687,7 @@ to coalesce with other events. Flags specifying whether the timeout is absolute or relative ## `subscription_fd_readwrite`: Struct -The contents of a $subscription when the variant is +The contents of a [`subscription`](#subscription) when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -695,7 +695,7 @@ The contents of a $subscription when the variant is The file descriptor on which to wait for it to become ready for reading or writing. ## `subscription_u`: Union -The contents of a $subscription. +The contents of a [`subscription`](#subscription). ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -885,7 +885,7 @@ Identifiers for preopened capabilities. A pre-opened directory. ## `prestat_dir`: Struct -The contents of a $prestat when type is `PREOPENTYPE_DIR`. +The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). ### Struct members - `pr_name_len`: [`size`](#size) @@ -907,7 +907,7 @@ Information about a pre-opened capability. #### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` Read command-line argument data. -The size of the array should match that returned by `wasi_args_sizes_get()` +The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) ##### Params - `argv`: `Pointer>` @@ -938,7 +938,7 @@ The size of the argument string data. #### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` Read environment variable data. -The sizes of the buffers should match that returned by `environ.sizes_get()`. +The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). ##### Params - `environ`: `Pointer>` @@ -969,7 +969,8 @@ The size of the argument string data. #### `clock_res_get(id: clockid) -> (errno, timestamp)` Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return +[`errno::inval`](#errno.inval). Note: This is similar to `clock_getres` in POSIX. ##### Params @@ -1106,7 +1107,7 @@ The desired values of the file descriptor flags. #### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights +This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights ##### Params - `fd`: [`fd`](#fd) @@ -1501,7 +1502,7 @@ Flags determining the method of how the path is resolved. - `path`: `string` The relative path of the file or directory to open, relative to the -`dirfd` directory. +[`fd`](#fd) directory. - `oflags`: [`oflags`](#oflags) The method by which to open the file. @@ -1554,7 +1555,7 @@ The number of bytes placed in the buffer. #### `path_remove_directory(fd: fd, path: string) -> errno` Remove a directory. -Return `ENOTEMPTY` if the directory is not empty. +Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. ##### Params @@ -1612,7 +1613,7 @@ The destination path at which to create the symbolic link. #### `path_unlink_file(fd: fd, path: string) -> errno` Unlink a file. -Return `EISDIR` if the path refers to a directory. +Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. ##### Params diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx index 493bda050..0efdb27a7 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx @@ -200,7 +200,7 @@ ;;; The right to invoke `fd_datasync`. ;; ;;; If `rights::path_open` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_DSYNC`. + ;;; `path_open` with `fdflags::dsync`. $fd_datasync ;;; The right to invoke `fd_read` and `sock_recv`. ;; @@ -213,10 +213,10 @@ ;;; The right to invoke `fd_sync`. ;; ;;; If `rights::path_open` is set, includes the right to invoke - ;;; `path_open` with `FDFLAG_RSYNC` and `FDFLAG_DSYNC`. + ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. $fd_sync ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to + ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to ;;; invoke `fd_tell`. $fd_tell ;;; The right to invoke `fd_write` and `sock_send`. @@ -228,7 +228,7 @@ $fd_allocate ;;; The right to invoke `path_create_directory`. $path_create_directory - ;;; If `rights::path_open` is set, the right to invoke `path_open` with `O_CREAT`. + ;;; If `rights::path_open` is set, the right to invoke `path_open` with `oflags::creat`. $path_create_file ;;; The right to invoke `path_link` with the file descriptor as the ;;; source directory. @@ -249,7 +249,7 @@ ;;; The right to invoke `path_filestat_get`. $path_filestat_get ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `rights::path_open` is set, includes the right to invoke `path_open` with `O_TRUNC`. + ;;; If `rights::path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. $path_filestat_set_times @@ -417,13 +417,13 @@ ;;; Which file time attributes to adjust. (typename $fstflags (flags u16 - ;;; Adjust the last data access timestamp to the value stored in `filestat::st_atim`. + ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim - ;;; Adjust the last data access timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`. + ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clock::realtime`. + ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. $mtim_now ) ) @@ -482,13 +482,13 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype (enum u8 - ;;; The time value of clock `subscription::u.clock.clock_id` has - ;;; reached timestamp `subscription::u.clock.timeout`. + ;;; The time value of clock `subscription_clock::id` has + ;;; reached timestamp `subscription_clock::timeout`. $clock - ;;; File descriptor `subscription::u.fd_readwrite.fd` has data + ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has data ;;; available for reading. This event always triggers for regular files. $fd_read - ;;; File descriptor `subscription::u.fd_readwrite.fd` has capacity + ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has capacity ;;; available for writing. This event always triggers for regular files. $fd_write ) @@ -530,19 +530,19 @@ ) ;;; Flags determining how to interpret the timestamp provided in -;;; `subscription::u.clock.timeout.` +;;; `subscription_clock::timeout`. (typename $subclockflags (flags u16 ;;; If set, treat the timestamp provided in - ;;; `subscription::u.clock.timeout` as an absolute timestamp of clock - ;;; `subscription::u.clock.clock_id.` If clear, treat the timestamp - ;;; provided in `subscription::u.clock.timeout` relative to the - ;;; current time value of clock `subscription::u.clock.clock_id.` + ;;; `subscription_clock::timeout` as an absolute timestamp of clock + ;;; `subscription_clock::id`. If clear, treat the timestamp + ;;; provided in `subscription_clock::timeout` relative to the + ;;; current time value of clock `subscription_clock::id`. $subscription_clock_abstime ) ) -;;; The contents of a $subscription when type is `eventtype::clock`. +;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock (struct ;;; The user-defined unique identifier of the clock. @@ -559,7 +559,7 @@ ) ) -;;; The contents of a $subscription when the variant is +;;; The contents of a `subscription` when the variant is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite (struct @@ -568,7 +568,7 @@ ) ) -;;; The contents of a $subscription. +;;; The contents of a `subscription`. (typename $subscription_u (union $eventtype (field $clock $subscription_clock) @@ -730,7 +730,7 @@ ) ) -;;; The contents of a $prestat when type is `PREOPENTYPE_DIR`. +;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir (struct ;;; The length of the directory name for use with `fd_prestat_dir_name`. diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx index 5e125caf2..3b7dcb0cf 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -16,7 +16,7 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `wasi_args_sizes_get()` + ;;; The size of the array should match that returned by `args_sizes_get` (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) @@ -32,7 +32,7 @@ ) ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ.sizes_get()`. + ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) @@ -48,7 +48,8 @@ ) ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL` + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return + ;;; `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") (result $error $errno) @@ -126,7 +127,7 @@ ) ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights + ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights (@interface func (export "fd_fdstat_set_rights") (param $fd $fd) ;;; The desired rights of the file descriptor. @@ -366,7 +367,7 @@ ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the - ;;; `dirfd` directory. + ;;; `fd` directory. (param $path string) ;;; The method by which to open the file. (param $oflags $oflags) @@ -401,7 +402,7 @@ ) ;;; Remove a directory. - ;;; Return `ENOTEMPTY` if the directory is not empty. + ;;; Return `errno::notempty` if the directory is not empty. ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. (@interface func (export "path_remove_directory") (param $fd $fd) @@ -436,7 +437,7 @@ ;;; Unlink a file. - ;;; Return `EISDIR` if the path refers to a directory. + ;;; Return `errno::isdir` if the path refers to a directory. ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. (@interface func (export "path_unlink_file") (param $fd $fd) diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index 0b3dec378..0578d3f50 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -669,7 +669,7 @@ provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relativ current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct -The contents of a $subscription when type is [`eventtype::clock`](#eventtype.clock). +The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). ### Struct members - `id`: [`clockid`](#clockid) @@ -686,7 +686,7 @@ to coalesce with other events. Flags specifying whether the timeout is absolute or relative ## `subscription_fd_readwrite`: Struct -The contents of a $subscription when type is type is +The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). ### Struct members @@ -694,7 +694,7 @@ The contents of a $subscription when type is type is The file descriptor on which to wait for it to become ready for reading or writing. ## `subscription_u`: Union -The contents of a $subscription. +The contents of a [`subscription`](#subscription). ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx index eb8cb8c64..27d84cd5f 100644 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -544,7 +544,7 @@ ) ) -;;; The contents of a $subscription when type is `eventtype::clock`. +;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock (struct ;;; The clock against which to compare the timestamp. @@ -559,7 +559,7 @@ ) ) -;;; The contents of a $subscription when type is type is +;;; The contents of a `subscription` when type is type is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite (struct @@ -568,7 +568,7 @@ ) ) -;;; The contents of a $subscription. +;;; The contents of a `subscription`. (typename $subscription_u (union $eventtype (field $clock $subscription_clock) From 772069765bd43c4533c99250b937ed24d163dc7f Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 22 Feb 2020 20:32:34 +0100 Subject: [PATCH 0568/1772] Fix wording and return args in environ_sizes_get syscall (#227) This commit fixes wording and return args naming in `environ_sizes_get` syscalls across all snapshots. It seems that the wording for `args_sizes_get` was copied over to `environ_sizes_get` but without adjusting the wording and naming. --- proposals/clocks/phases/ephemeral/docs.md | 10 +++++----- .../phases/ephemeral/witx/wasi_ephemeral_environ.witx | 10 +++++----- proposals/clocks/phases/old/snapshot_0/docs.md | 10 +++++----- .../phases/old/snapshot_0/witx/wasi_unstable.witx | 10 +++++----- proposals/clocks/phases/snapshot/docs.md | 10 +++++----- .../phases/snapshot/witx/wasi_snapshot_preview1.witx | 10 +++++----- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 8f19cc8c2..a05ec6e8c 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -916,17 +916,17 @@ The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get) --- #### `sizes_get() -> (errno, size, size)` -Return command-line argument data sizes. +Return environment variable data sizes. ##### Params ##### Results - `error`: [`errno`](#errno) -- `argc`: [`size`](#size) -The number of arguments. +- `environc`: [`size`](#size) +The number of environment variable arguments. -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `environ_buf_size`: [`size`](#size) +The size of the environment variable data. ## wasi_ephemeral_fd ### Imports diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx index 2adcb2874..ab564076d 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -17,12 +17,12 @@ (result $error $errno) ) - ;;; Return command-line argument data sizes. + ;;; Return environment variable data sizes. (@interface func (export "sizes_get") (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; The number of environment variable arguments. + (result $environc $size) + ;;; The size of the environment variable data. + (result $environ_buf_size $size) ) ) diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index 4094320f8..6bfe03198 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -952,17 +952,17 @@ The sizes of the buffers should match that returned by [`environ_sizes_get`](#en --- #### `environ_sizes_get() -> (errno, size, size)` -Return command-line argument data sizes. +Return environment variable data sizes. ##### Params ##### Results - `error`: [`errno`](#errno) -- `argc`: [`size`](#size) -The number of arguments. +- `environc`: [`size`](#size) +The number of environment variable arguments. -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `environ_buf_size`: [`size`](#size) +The size of the environment variable data. --- diff --git a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx index 3b7dcb0cf..c3aabbbfc 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -38,13 +38,13 @@ (param $environ_buf (@witx pointer u8)) (result $error $errno) ) - ;;; Return command-line argument data sizes. + ;;; Return environment variable data sizes. (@interface func (export "environ_sizes_get") (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; The number of environment variable arguments. + (result $environc $size) + ;;; The size of the environment variable data. + (result $environ_buf_size $size) ) ;;; Return the resolution of a clock. diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index 0578d3f50..274e5335c 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -951,17 +951,17 @@ The sizes of the buffers should match that returned by [`environ_sizes_get`](#en --- #### `environ_sizes_get() -> (errno, size, size)` -Return command-line argument data sizes. +Return environment variable data sizes. ##### Params ##### Results - `error`: [`errno`](#errno) -- `argc`: [`size`](#size) -The number of arguments. +- `environc`: [`size`](#size) +The number of environment variable arguments. -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `environ_buf_size`: [`size`](#size) +The size of the environment variable data. --- diff --git a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx index a453faf45..c2a746730 100644 --- a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -35,13 +35,13 @@ (param $environ_buf (@witx pointer u8)) (result $error $errno) ) - ;;; Return command-line argument data sizes. + ;;; Return environment variable data sizes. (@interface func (export "environ_sizes_get") (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; The number of environment variable arguments. + (result $environc $size) + ;;; The size of the environment variable data. + (result $environ_buf_size $size) ) ;;; Return the resolution of a clock. From cc53df026738688d2bfee5f3b214c451f7e8509e Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 22 Feb 2020 20:32:34 +0100 Subject: [PATCH 0569/1772] Fix wording and return args in environ_sizes_get syscall (#227) This commit fixes wording and return args naming in `environ_sizes_get` syscalls across all snapshots. It seems that the wording for `args_sizes_get` was copied over to `environ_sizes_get` but without adjusting the wording and naming. --- proposals/random/phases/ephemeral/docs.md | 10 +++++----- .../phases/ephemeral/witx/wasi_ephemeral_environ.witx | 10 +++++----- proposals/random/phases/old/snapshot_0/docs.md | 10 +++++----- .../phases/old/snapshot_0/witx/wasi_unstable.witx | 10 +++++----- proposals/random/phases/snapshot/docs.md | 10 +++++----- .../phases/snapshot/witx/wasi_snapshot_preview1.witx | 10 +++++----- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 8f19cc8c2..a05ec6e8c 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -916,17 +916,17 @@ The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get) --- #### `sizes_get() -> (errno, size, size)` -Return command-line argument data sizes. +Return environment variable data sizes. ##### Params ##### Results - `error`: [`errno`](#errno) -- `argc`: [`size`](#size) -The number of arguments. +- `environc`: [`size`](#size) +The number of environment variable arguments. -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `environ_buf_size`: [`size`](#size) +The size of the environment variable data. ## wasi_ephemeral_fd ### Imports diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx index 2adcb2874..ab564076d 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -17,12 +17,12 @@ (result $error $errno) ) - ;;; Return command-line argument data sizes. + ;;; Return environment variable data sizes. (@interface func (export "sizes_get") (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; The number of environment variable arguments. + (result $environc $size) + ;;; The size of the environment variable data. + (result $environ_buf_size $size) ) ) diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index 4094320f8..6bfe03198 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -952,17 +952,17 @@ The sizes of the buffers should match that returned by [`environ_sizes_get`](#en --- #### `environ_sizes_get() -> (errno, size, size)` -Return command-line argument data sizes. +Return environment variable data sizes. ##### Params ##### Results - `error`: [`errno`](#errno) -- `argc`: [`size`](#size) -The number of arguments. +- `environc`: [`size`](#size) +The number of environment variable arguments. -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `environ_buf_size`: [`size`](#size) +The size of the environment variable data. --- diff --git a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx index 3b7dcb0cf..c3aabbbfc 100644 --- a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -38,13 +38,13 @@ (param $environ_buf (@witx pointer u8)) (result $error $errno) ) - ;;; Return command-line argument data sizes. + ;;; Return environment variable data sizes. (@interface func (export "environ_sizes_get") (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; The number of environment variable arguments. + (result $environc $size) + ;;; The size of the environment variable data. + (result $environ_buf_size $size) ) ;;; Return the resolution of a clock. diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index 0578d3f50..274e5335c 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -951,17 +951,17 @@ The sizes of the buffers should match that returned by [`environ_sizes_get`](#en --- #### `environ_sizes_get() -> (errno, size, size)` -Return command-line argument data sizes. +Return environment variable data sizes. ##### Params ##### Results - `error`: [`errno`](#errno) -- `argc`: [`size`](#size) -The number of arguments. +- `environc`: [`size`](#size) +The number of environment variable arguments. -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `environ_buf_size`: [`size`](#size) +The size of the environment variable data. --- diff --git a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx index a453faf45..c2a746730 100644 --- a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -35,13 +35,13 @@ (param $environ_buf (@witx pointer u8)) (result $error $errno) ) - ;;; Return command-line argument data sizes. + ;;; Return environment variable data sizes. (@interface func (export "environ_sizes_get") (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; The number of environment variable arguments. + (result $environc $size) + ;;; The size of the environment variable data. + (result $environ_buf_size $size) ) ;;; Return the resolution of a clock. From 57f9c423ff333764519d0cc5dc49558ff2738f7b Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 22 Feb 2020 20:32:34 +0100 Subject: [PATCH 0570/1772] Fix wording and return args in environ_sizes_get syscall (#227) This commit fixes wording and return args naming in `environ_sizes_get` syscalls across all snapshots. It seems that the wording for `args_sizes_get` was copied over to `environ_sizes_get` but without adjusting the wording and naming. --- proposals/filesystem/phases/ephemeral/docs.md | 10 +++++----- .../phases/ephemeral/witx/wasi_ephemeral_environ.witx | 10 +++++----- proposals/filesystem/phases/old/snapshot_0/docs.md | 10 +++++----- .../phases/old/snapshot_0/witx/wasi_unstable.witx | 10 +++++----- proposals/filesystem/phases/snapshot/docs.md | 10 +++++----- .../phases/snapshot/witx/wasi_snapshot_preview1.witx | 10 +++++----- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 8f19cc8c2..a05ec6e8c 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -916,17 +916,17 @@ The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get) --- #### `sizes_get() -> (errno, size, size)` -Return command-line argument data sizes. +Return environment variable data sizes. ##### Params ##### Results - `error`: [`errno`](#errno) -- `argc`: [`size`](#size) -The number of arguments. +- `environc`: [`size`](#size) +The number of environment variable arguments. -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `environ_buf_size`: [`size`](#size) +The size of the environment variable data. ## wasi_ephemeral_fd ### Imports diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx index 2adcb2874..ab564076d 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -17,12 +17,12 @@ (result $error $errno) ) - ;;; Return command-line argument data sizes. + ;;; Return environment variable data sizes. (@interface func (export "sizes_get") (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; The number of environment variable arguments. + (result $environc $size) + ;;; The size of the environment variable data. + (result $environ_buf_size $size) ) ) diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index 4094320f8..6bfe03198 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -952,17 +952,17 @@ The sizes of the buffers should match that returned by [`environ_sizes_get`](#en --- #### `environ_sizes_get() -> (errno, size, size)` -Return command-line argument data sizes. +Return environment variable data sizes. ##### Params ##### Results - `error`: [`errno`](#errno) -- `argc`: [`size`](#size) -The number of arguments. +- `environc`: [`size`](#size) +The number of environment variable arguments. -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `environ_buf_size`: [`size`](#size) +The size of the environment variable data. --- diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx index 3b7dcb0cf..c3aabbbfc 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -38,13 +38,13 @@ (param $environ_buf (@witx pointer u8)) (result $error $errno) ) - ;;; Return command-line argument data sizes. + ;;; Return environment variable data sizes. (@interface func (export "environ_sizes_get") (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; The number of environment variable arguments. + (result $environc $size) + ;;; The size of the environment variable data. + (result $environ_buf_size $size) ) ;;; Return the resolution of a clock. diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index 0578d3f50..274e5335c 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -951,17 +951,17 @@ The sizes of the buffers should match that returned by [`environ_sizes_get`](#en --- #### `environ_sizes_get() -> (errno, size, size)` -Return command-line argument data sizes. +Return environment variable data sizes. ##### Params ##### Results - `error`: [`errno`](#errno) -- `argc`: [`size`](#size) -The number of arguments. +- `environc`: [`size`](#size) +The number of environment variable arguments. -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `environ_buf_size`: [`size`](#size) +The size of the environment variable data. --- diff --git a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx index a453faf45..c2a746730 100644 --- a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -35,13 +35,13 @@ (param $environ_buf (@witx pointer u8)) (result $error $errno) ) - ;;; Return command-line argument data sizes. + ;;; Return environment variable data sizes. (@interface func (export "environ_sizes_get") (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; The number of environment variable arguments. + (result $environc $size) + ;;; The size of the environment variable data. + (result $environ_buf_size $size) ) ;;; Return the resolution of a clock. From 920f2c93de3d693b02a2545ce9d4fe00ef4b29e9 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 24 Feb 2020 12:13:26 -0800 Subject: [PATCH 0571/1772] witx: Update to current wast 8.0.0 (#228) Bump witx version to 0.8.2. --- proposals/clocks/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 459ec4602..b46252119 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.1" +version = "0.8.2" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" @@ -19,7 +19,7 @@ path = "src/main.rs" [dependencies] structopt = "0.3" -wast = "3.0.4" +wast = "8.0.0" thiserror = "1.0" log = "0.4" pretty_env_logger = "0.3" From 5ee0610e5085b4e8871bb93d23bc6ba7e2be6d50 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 24 Feb 2020 12:13:26 -0800 Subject: [PATCH 0572/1772] witx: Update to current wast 8.0.0 (#228) Bump witx version to 0.8.2. --- proposals/random/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 459ec4602..b46252119 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.1" +version = "0.8.2" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" @@ -19,7 +19,7 @@ path = "src/main.rs" [dependencies] structopt = "0.3" -wast = "3.0.4" +wast = "8.0.0" thiserror = "1.0" log = "0.4" pretty_env_logger = "0.3" From b494d407e54bd94eb4303d1b6793972febf03824 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 24 Feb 2020 12:13:26 -0800 Subject: [PATCH 0573/1772] witx: Update to current wast 8.0.0 (#228) Bump witx version to 0.8.2. --- proposals/filesystem/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 459ec4602..b46252119 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.1" +version = "0.8.2" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" @@ -19,7 +19,7 @@ path = "src/main.rs" [dependencies] structopt = "0.3" -wast = "3.0.4" +wast = "8.0.0" thiserror = "1.0" log = "0.4" pretty_env_logger = "0.3" From 6848cafe64fc841e30fbcf84570c6c1603a5cdf2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 24 Feb 2020 13:28:10 -0800 Subject: [PATCH 0574/1772] Add an agenda for the 02-27 meeting. (#230) --- proposals/clocks/meetings/2020/WASI-02-27.md | 37 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 38 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-02-27.md diff --git a/proposals/clocks/meetings/2020/WASI-02-27.md b/proposals/clocks/meetings/2020/WASI-02-27.md new file mode 100644 index 000000000..b7862ba1e --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-02-27.md @@ -0,0 +1,37 @@ +![WASI logo](/WASI.png) + +## Agenda for the February 27 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: February 27, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Whole-program LTO coming: + - https://github.com/WebAssembly/tool-conventions/pull/134 + 1. Frame-buffer API: + - https://github.com/WebAssembly/WASI/pull/229 + - The process for designing and submitting new API proposals is still being + figured out, so in addition to the proposal, let's also talk about what we can + do to make the process easier. + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index d0461d30e..b9324d4e3 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -24,3 +24,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI December 5th video call](2019/WASI-12-05.md) * [WASI December 19th video call](2019/WASI-12-19.md) * [WASI January 16th video call](2020/WASI-01-16.md) + * [WASI February 27th video call](2020/WASI-02-27.md) From 0b371b0ceac935752272d9833596a6db209ae59f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 24 Feb 2020 13:28:10 -0800 Subject: [PATCH 0575/1772] Add an agenda for the 02-27 meeting. (#230) --- proposals/random/meetings/2020/WASI-02-27.md | 37 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 38 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-02-27.md diff --git a/proposals/random/meetings/2020/WASI-02-27.md b/proposals/random/meetings/2020/WASI-02-27.md new file mode 100644 index 000000000..b7862ba1e --- /dev/null +++ b/proposals/random/meetings/2020/WASI-02-27.md @@ -0,0 +1,37 @@ +![WASI logo](/WASI.png) + +## Agenda for the February 27 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: February 27, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Whole-program LTO coming: + - https://github.com/WebAssembly/tool-conventions/pull/134 + 1. Frame-buffer API: + - https://github.com/WebAssembly/WASI/pull/229 + - The process for designing and submitting new API proposals is still being + figured out, so in addition to the proposal, let's also talk about what we can + do to make the process easier. + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index d0461d30e..b9324d4e3 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -24,3 +24,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI December 5th video call](2019/WASI-12-05.md) * [WASI December 19th video call](2019/WASI-12-19.md) * [WASI January 16th video call](2020/WASI-01-16.md) + * [WASI February 27th video call](2020/WASI-02-27.md) From 41828f16adc006f3131e4b1fe7bfc3ba48131308 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 24 Feb 2020 13:28:10 -0800 Subject: [PATCH 0576/1772] Add an agenda for the 02-27 meeting. (#230) --- .../filesystem/meetings/2020/WASI-02-27.md | 37 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 38 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-02-27.md diff --git a/proposals/filesystem/meetings/2020/WASI-02-27.md b/proposals/filesystem/meetings/2020/WASI-02-27.md new file mode 100644 index 000000000..b7862ba1e --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-02-27.md @@ -0,0 +1,37 @@ +![WASI logo](/WASI.png) + +## Agenda for the February 27 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: February 27, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Whole-program LTO coming: + - https://github.com/WebAssembly/tool-conventions/pull/134 + 1. Frame-buffer API: + - https://github.com/WebAssembly/WASI/pull/229 + - The process for designing and submitting new API proposals is still being + figured out, so in addition to the proposal, let's also talk about what we can + do to make the process easier. + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index d0461d30e..b9324d4e3 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -24,3 +24,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI December 5th video call](2019/WASI-12-05.md) * [WASI December 19th video call](2019/WASI-12-19.md) * [WASI January 16th video call](2020/WASI-01-16.md) + * [WASI February 27th video call](2020/WASI-02-27.md) From 02b76801d829bd4207acfb9ada6ecc18eb108779 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 26 Feb 2020 09:58:03 -0800 Subject: [PATCH 0577/1772] Update the wast crate in the witx tool This updates the necessary glue to parse annotations, since the `wast` crate now has more official support for annotations. --- proposals/clocks/tools/witx/Cargo.toml | 2 +- proposals/clocks/tools/witx/src/parser.rs | 67 +++++------------------ 2 files changed, 15 insertions(+), 54 deletions(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index b46252119..80fd59e3c 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -19,7 +19,7 @@ path = "src/main.rs" [dependencies] structopt = "0.3" -wast = "8.0.0" +wast = { version = "9.0.0", default-features = false } thiserror = "1.0" log = "0.4" pretty_env_logger = "0.3" diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 85f8c8d09..be0cb31e1 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -1,6 +1,6 @@ use crate::BuiltinType; use wast::lexer::Comment; -use wast::parser::{Cursor, Parse, Parser, Peek, Result}; +use wast::parser::{Parse, Parser, Peek, Result}; ///! Parser turns s-expressions into unvalidated syntax constructs. ///! conventions: @@ -48,6 +48,11 @@ mod kw { wast::custom_keyword!(usize); } +mod annotation { + wast::annotation!(interface); + wast::annotation!(witx); +} + impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { let mut l = parser.lookahead1(); @@ -186,58 +191,14 @@ pub struct Documented<'a, T> { impl<'a, T: Parse<'a>> Parse<'a> for Documented<'a, T> { fn parse(parser: Parser<'a>) -> Result { + let _r1 = parser.register_annotation("witx"); + let _r1 = parser.register_annotation("interface"); let comments = parser.parse()?; let item = parser.parse()?; Ok(Documented { comments, item }) } } -struct AtWitx; - -impl Parse<'_> for AtWitx { - fn parse(parser: Parser<'_>) -> Result { - parser.step(|c| { - if let Some(("@witx", rest)) = c.reserved() { - return Ok((AtWitx, rest)); - } - Err(c.error("expected `@witx`")) - }) - } -} - -impl Peek for AtWitx { - fn peek(cursor: Cursor<'_>) -> bool { - cursor.reserved().map(|s| s.0) == Some("@witx") - } - - fn display() -> &'static str { - "`@witx`" - } -} - -struct AtInterface; - -impl Parse<'_> for AtInterface { - fn parse(parser: Parser<'_>) -> Result { - parser.step(|c| { - if let Some(("@interface", rest)) = c.reserved() { - return Ok((AtInterface, rest)); - } - Err(c.error("expected `@interface`")) - }) - } -} - -impl Peek for AtInterface { - fn peek(cursor: Cursor<'_>) -> bool { - cursor.reserved().map(|s| s.0) == Some("@interface") - } - - fn display() -> &'static str { - "`@interface`" - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub struct TopLevelDocument<'a> { pub items: Vec>>, @@ -346,8 +307,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { } else if l.peek::() { parser.parse::()?; Ok(TypedefSyntax::Array(Box::new(parser.parse()?))) - } else if l.peek::() { - parser.parse::()?; + } else if l.peek::() { + parser.parse::()?; let mut l = parser.lookahead1(); if l.peek::() { parser.parse::()?; @@ -569,7 +530,7 @@ impl<'a> Parse<'a> for ModuleDeclSyntax<'a> { let mut l = p.lookahead1(); if l.peek::() { Ok(ModuleDeclSyntax::Import(p.parse()?)) - } else if l.peek::() { + } else if l.peek::() { Ok(ModuleDeclSyntax::Func(p.parse()?)) } else { Err(l.error()) @@ -629,7 +590,7 @@ pub struct InterfaceFuncSyntax<'a> { impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; + parser.parse::()?; parser.parse::()?; let (export_loc, export) = parser.parens(|p| { @@ -693,8 +654,8 @@ impl<'a> Parse<'a> for InterfaceFuncField<'a> { name: parser.parse()?, type_: parser.parse()?, })) - } else if l.peek::() { - parser.parse::()?; + } else if l.peek::() { + parser.parse::()?; let mut l = parser.lookahead1(); if l.peek::() { parser.parse::()?; From 06e9a2f1fd03a86fb2e0a0093ce65ebf33380590 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 26 Feb 2020 09:58:03 -0800 Subject: [PATCH 0578/1772] Update the wast crate in the witx tool This updates the necessary glue to parse annotations, since the `wast` crate now has more official support for annotations. --- proposals/random/tools/witx/Cargo.toml | 2 +- proposals/random/tools/witx/src/parser.rs | 67 +++++------------------ 2 files changed, 15 insertions(+), 54 deletions(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index b46252119..80fd59e3c 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -19,7 +19,7 @@ path = "src/main.rs" [dependencies] structopt = "0.3" -wast = "8.0.0" +wast = { version = "9.0.0", default-features = false } thiserror = "1.0" log = "0.4" pretty_env_logger = "0.3" diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 85f8c8d09..be0cb31e1 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -1,6 +1,6 @@ use crate::BuiltinType; use wast::lexer::Comment; -use wast::parser::{Cursor, Parse, Parser, Peek, Result}; +use wast::parser::{Parse, Parser, Peek, Result}; ///! Parser turns s-expressions into unvalidated syntax constructs. ///! conventions: @@ -48,6 +48,11 @@ mod kw { wast::custom_keyword!(usize); } +mod annotation { + wast::annotation!(interface); + wast::annotation!(witx); +} + impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { let mut l = parser.lookahead1(); @@ -186,58 +191,14 @@ pub struct Documented<'a, T> { impl<'a, T: Parse<'a>> Parse<'a> for Documented<'a, T> { fn parse(parser: Parser<'a>) -> Result { + let _r1 = parser.register_annotation("witx"); + let _r1 = parser.register_annotation("interface"); let comments = parser.parse()?; let item = parser.parse()?; Ok(Documented { comments, item }) } } -struct AtWitx; - -impl Parse<'_> for AtWitx { - fn parse(parser: Parser<'_>) -> Result { - parser.step(|c| { - if let Some(("@witx", rest)) = c.reserved() { - return Ok((AtWitx, rest)); - } - Err(c.error("expected `@witx`")) - }) - } -} - -impl Peek for AtWitx { - fn peek(cursor: Cursor<'_>) -> bool { - cursor.reserved().map(|s| s.0) == Some("@witx") - } - - fn display() -> &'static str { - "`@witx`" - } -} - -struct AtInterface; - -impl Parse<'_> for AtInterface { - fn parse(parser: Parser<'_>) -> Result { - parser.step(|c| { - if let Some(("@interface", rest)) = c.reserved() { - return Ok((AtInterface, rest)); - } - Err(c.error("expected `@interface`")) - }) - } -} - -impl Peek for AtInterface { - fn peek(cursor: Cursor<'_>) -> bool { - cursor.reserved().map(|s| s.0) == Some("@interface") - } - - fn display() -> &'static str { - "`@interface`" - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub struct TopLevelDocument<'a> { pub items: Vec>>, @@ -346,8 +307,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { } else if l.peek::() { parser.parse::()?; Ok(TypedefSyntax::Array(Box::new(parser.parse()?))) - } else if l.peek::() { - parser.parse::()?; + } else if l.peek::() { + parser.parse::()?; let mut l = parser.lookahead1(); if l.peek::() { parser.parse::()?; @@ -569,7 +530,7 @@ impl<'a> Parse<'a> for ModuleDeclSyntax<'a> { let mut l = p.lookahead1(); if l.peek::() { Ok(ModuleDeclSyntax::Import(p.parse()?)) - } else if l.peek::() { + } else if l.peek::() { Ok(ModuleDeclSyntax::Func(p.parse()?)) } else { Err(l.error()) @@ -629,7 +590,7 @@ pub struct InterfaceFuncSyntax<'a> { impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; + parser.parse::()?; parser.parse::()?; let (export_loc, export) = parser.parens(|p| { @@ -693,8 +654,8 @@ impl<'a> Parse<'a> for InterfaceFuncField<'a> { name: parser.parse()?, type_: parser.parse()?, })) - } else if l.peek::() { - parser.parse::()?; + } else if l.peek::() { + parser.parse::()?; let mut l = parser.lookahead1(); if l.peek::() { parser.parse::()?; From b4d44d5de6a962909f388c9ad5ac38f94b5f1164 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 26 Feb 2020 09:58:03 -0800 Subject: [PATCH 0579/1772] Update the wast crate in the witx tool This updates the necessary glue to parse annotations, since the `wast` crate now has more official support for annotations. --- proposals/filesystem/tools/witx/Cargo.toml | 2 +- proposals/filesystem/tools/witx/src/parser.rs | 67 ++++--------------- 2 files changed, 15 insertions(+), 54 deletions(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index b46252119..80fd59e3c 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -19,7 +19,7 @@ path = "src/main.rs" [dependencies] structopt = "0.3" -wast = "8.0.0" +wast = { version = "9.0.0", default-features = false } thiserror = "1.0" log = "0.4" pretty_env_logger = "0.3" diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 85f8c8d09..be0cb31e1 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -1,6 +1,6 @@ use crate::BuiltinType; use wast::lexer::Comment; -use wast::parser::{Cursor, Parse, Parser, Peek, Result}; +use wast::parser::{Parse, Parser, Peek, Result}; ///! Parser turns s-expressions into unvalidated syntax constructs. ///! conventions: @@ -48,6 +48,11 @@ mod kw { wast::custom_keyword!(usize); } +mod annotation { + wast::annotation!(interface); + wast::annotation!(witx); +} + impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { let mut l = parser.lookahead1(); @@ -186,58 +191,14 @@ pub struct Documented<'a, T> { impl<'a, T: Parse<'a>> Parse<'a> for Documented<'a, T> { fn parse(parser: Parser<'a>) -> Result { + let _r1 = parser.register_annotation("witx"); + let _r1 = parser.register_annotation("interface"); let comments = parser.parse()?; let item = parser.parse()?; Ok(Documented { comments, item }) } } -struct AtWitx; - -impl Parse<'_> for AtWitx { - fn parse(parser: Parser<'_>) -> Result { - parser.step(|c| { - if let Some(("@witx", rest)) = c.reserved() { - return Ok((AtWitx, rest)); - } - Err(c.error("expected `@witx`")) - }) - } -} - -impl Peek for AtWitx { - fn peek(cursor: Cursor<'_>) -> bool { - cursor.reserved().map(|s| s.0) == Some("@witx") - } - - fn display() -> &'static str { - "`@witx`" - } -} - -struct AtInterface; - -impl Parse<'_> for AtInterface { - fn parse(parser: Parser<'_>) -> Result { - parser.step(|c| { - if let Some(("@interface", rest)) = c.reserved() { - return Ok((AtInterface, rest)); - } - Err(c.error("expected `@interface`")) - }) - } -} - -impl Peek for AtInterface { - fn peek(cursor: Cursor<'_>) -> bool { - cursor.reserved().map(|s| s.0) == Some("@interface") - } - - fn display() -> &'static str { - "`@interface`" - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub struct TopLevelDocument<'a> { pub items: Vec>>, @@ -346,8 +307,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { } else if l.peek::() { parser.parse::()?; Ok(TypedefSyntax::Array(Box::new(parser.parse()?))) - } else if l.peek::() { - parser.parse::()?; + } else if l.peek::() { + parser.parse::()?; let mut l = parser.lookahead1(); if l.peek::() { parser.parse::()?; @@ -569,7 +530,7 @@ impl<'a> Parse<'a> for ModuleDeclSyntax<'a> { let mut l = p.lookahead1(); if l.peek::() { Ok(ModuleDeclSyntax::Import(p.parse()?)) - } else if l.peek::() { + } else if l.peek::() { Ok(ModuleDeclSyntax::Func(p.parse()?)) } else { Err(l.error()) @@ -629,7 +590,7 @@ pub struct InterfaceFuncSyntax<'a> { impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; + parser.parse::()?; parser.parse::()?; let (export_loc, export) = parser.parens(|p| { @@ -693,8 +654,8 @@ impl<'a> Parse<'a> for InterfaceFuncField<'a> { name: parser.parse()?, type_: parser.parse()?, })) - } else if l.peek::() { - parser.parse::()?; + } else if l.peek::() { + parser.parse::()?; let mut l = parser.lookahead1(); if l.peek::() { parser.parse::()?; From c1a1fd6925d87b8ae008503206b95a60250f3576 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 26 Feb 2020 19:40:35 +0100 Subject: [PATCH 0580/1772] Reorder params/results in clock_res_get syscall (#234) This is merely a stylistic nit which strives to maintain consistency across all WASI syscalls in that `param`s *always* precede `result`s in `*.witx` specs. --- .../clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx | 2 +- proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx | 2 +- .../clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx index 65b8d0e15..3b00e0ac4 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx @@ -16,9 +16,9 @@ ;;; return `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "res_get") - (result $error $errno) ;;; The clock for which to return the resolution. (param $id $clockid) + (result $error $errno) ;;; The resolution of the clock. (result $resolution $timestamp) ) diff --git a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx index c3aabbbfc..fb098d7b5 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -52,9 +52,9 @@ ;;; `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno) ;;; The clock for which to return the resolution. (param $id $clockid) + (result $error $errno) ;;; The resolution of the clock. (result $resolution $timestamp) ) diff --git a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx index c2a746730..98cd94787 100644 --- a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -49,9 +49,9 @@ ;;; return `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno) ;;; The clock for which to return the resolution. (param $id $clockid) + (result $error $errno) ;;; The resolution of the clock. (result $resolution $timestamp) ) From f8b52ef75c3573f31a15e3af9e600577bc730bbd Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 26 Feb 2020 19:40:35 +0100 Subject: [PATCH 0581/1772] Reorder params/results in clock_res_get syscall (#234) This is merely a stylistic nit which strives to maintain consistency across all WASI syscalls in that `param`s *always* precede `result`s in `*.witx` specs. --- .../random/phases/ephemeral/witx/wasi_ephemeral_clock.witx | 2 +- proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx | 2 +- .../random/phases/snapshot/witx/wasi_snapshot_preview1.witx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx index 65b8d0e15..3b00e0ac4 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx @@ -16,9 +16,9 @@ ;;; return `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "res_get") - (result $error $errno) ;;; The clock for which to return the resolution. (param $id $clockid) + (result $error $errno) ;;; The resolution of the clock. (result $resolution $timestamp) ) diff --git a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx index c3aabbbfc..fb098d7b5 100644 --- a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -52,9 +52,9 @@ ;;; `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno) ;;; The clock for which to return the resolution. (param $id $clockid) + (result $error $errno) ;;; The resolution of the clock. (result $resolution $timestamp) ) diff --git a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx index c2a746730..98cd94787 100644 --- a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -49,9 +49,9 @@ ;;; return `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno) ;;; The clock for which to return the resolution. (param $id $clockid) + (result $error $errno) ;;; The resolution of the clock. (result $resolution $timestamp) ) From 5c68aabf5fac3fedd36abd8e55f7507bb9b54dee Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 26 Feb 2020 19:40:35 +0100 Subject: [PATCH 0582/1772] Reorder params/results in clock_res_get syscall (#234) This is merely a stylistic nit which strives to maintain consistency across all WASI syscalls in that `param`s *always* precede `result`s in `*.witx` specs. --- .../filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx | 2 +- .../filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx | 2 +- .../filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx index 65b8d0e15..3b00e0ac4 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx @@ -16,9 +16,9 @@ ;;; return `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "res_get") - (result $error $errno) ;;; The clock for which to return the resolution. (param $id $clockid) + (result $error $errno) ;;; The resolution of the clock. (result $resolution $timestamp) ) diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx index c3aabbbfc..fb098d7b5 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -52,9 +52,9 @@ ;;; `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno) ;;; The clock for which to return the resolution. (param $id $clockid) + (result $error $errno) ;;; The resolution of the clock. (result $resolution $timestamp) ) diff --git a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx index c2a746730..98cd94787 100644 --- a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -49,9 +49,9 @@ ;;; return `errno::inval`. ;;; Note: This is similar to `clock_getres` in POSIX. (@interface func (export "clock_res_get") - (result $error $errno) ;;; The clock for which to return the resolution. (param $id $clockid) + (result $error $errno) ;;; The resolution of the clock. (result $resolution $timestamp) ) From 4d00a0aa215fafe1999a1a6cb097b0d0b93e99ee Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 26 Feb 2020 12:14:53 -0800 Subject: [PATCH 0583/1772] bump witx to 0.8.3 --- proposals/clocks/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 80fd59e3c..ef8efab1c 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.2" +version = "0.8.3" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 5599515c178a5c734ebae2742c385085159c0dbe Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 26 Feb 2020 12:14:53 -0800 Subject: [PATCH 0584/1772] bump witx to 0.8.3 --- proposals/random/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 80fd59e3c..ef8efab1c 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.2" +version = "0.8.3" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 995488e05f33811a44e62e8077f8b41a0243ffc6 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 26 Feb 2020 12:14:53 -0800 Subject: [PATCH 0585/1772] bump witx to 0.8.3 --- proposals/filesystem/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 80fd59e3c..ef8efab1c 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.2" +version = "0.8.3" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 831a15a47bf5088a7dcbc4ee2a42449e55e9b3c9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 27 Feb 2020 07:29:46 -0800 Subject: [PATCH 0586/1772] Add an agenda item for the Crypto API proposal. (#237) --- proposals/clocks/meetings/2020/WASI-02-27.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/clocks/meetings/2020/WASI-02-27.md b/proposals/clocks/meetings/2020/WASI-02-27.md index b7862ba1e..5648a7741 100644 --- a/proposals/clocks/meetings/2020/WASI-02-27.md +++ b/proposals/clocks/meetings/2020/WASI-02-27.md @@ -33,5 +33,9 @@ Installation is required, see the calendar invite. - The process for designing and submitting new API proposals is still being figured out, so in addition to the proposal, let's also talk about what we can do to make the process easier. + 1. Crypto API! + - https://github.com/WebAssembly/WASI/pull/231 + - What criteria should we apply? + - We can also talk about process. ## Meeting Notes From 2393045ee923d232525e83d6955e74b70b93c7a9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 27 Feb 2020 07:29:46 -0800 Subject: [PATCH 0587/1772] Add an agenda item for the Crypto API proposal. (#237) --- proposals/random/meetings/2020/WASI-02-27.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/random/meetings/2020/WASI-02-27.md b/proposals/random/meetings/2020/WASI-02-27.md index b7862ba1e..5648a7741 100644 --- a/proposals/random/meetings/2020/WASI-02-27.md +++ b/proposals/random/meetings/2020/WASI-02-27.md @@ -33,5 +33,9 @@ Installation is required, see the calendar invite. - The process for designing and submitting new API proposals is still being figured out, so in addition to the proposal, let's also talk about what we can do to make the process easier. + 1. Crypto API! + - https://github.com/WebAssembly/WASI/pull/231 + - What criteria should we apply? + - We can also talk about process. ## Meeting Notes From 4321bbc8689197f5a97b79164e404c3105a67c30 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 27 Feb 2020 07:29:46 -0800 Subject: [PATCH 0588/1772] Add an agenda item for the Crypto API proposal. (#237) --- proposals/filesystem/meetings/2020/WASI-02-27.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/filesystem/meetings/2020/WASI-02-27.md b/proposals/filesystem/meetings/2020/WASI-02-27.md index b7862ba1e..5648a7741 100644 --- a/proposals/filesystem/meetings/2020/WASI-02-27.md +++ b/proposals/filesystem/meetings/2020/WASI-02-27.md @@ -33,5 +33,9 @@ Installation is required, see the calendar invite. - The process for designing and submitting new API proposals is still being figured out, so in addition to the proposal, let's also talk about what we can do to make the process easier. + 1. Crypto API! + - https://github.com/WebAssembly/WASI/pull/231 + - What criteria should we apply? + - We can also talk about process. ## Meeting Notes From cce1fbfc53f1a328e7e170b7416b77b3b6d80f05 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 27 Feb 2020 07:56:42 -0800 Subject: [PATCH 0589/1772] Add a documentation comment for the `$size` type. (#236) --- proposals/clocks/phases/ephemeral/docs.md | 3 +++ proposals/clocks/phases/ephemeral/witx/typenames.witx | 3 +++ 2 files changed, 6 insertions(+) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index a05ec6e8c..c645a7452 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -1,5 +1,8 @@ # Types ## `size`: `usize` +An array size. + +Note: This is similar to `size_t` in POSIX. ## `filesize`: `u64` Non-negative file size or length of a region within a file. diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 162c80f2b..772b8be82 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -5,6 +5,9 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. +;;; An array size. +;;; +;;; Note: This is similar to `size_t` in POSIX. (typename $size (@witx usize)) ;;; Non-negative file size or length of a region within a file. From 25bfbaef6217a7551041317fd0bd87be2e1e51af Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 27 Feb 2020 07:56:42 -0800 Subject: [PATCH 0590/1772] Add a documentation comment for the `$size` type. (#236) --- proposals/random/phases/ephemeral/docs.md | 3 +++ proposals/random/phases/ephemeral/witx/typenames.witx | 3 +++ 2 files changed, 6 insertions(+) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index a05ec6e8c..c645a7452 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -1,5 +1,8 @@ # Types ## `size`: `usize` +An array size. + +Note: This is similar to `size_t` in POSIX. ## `filesize`: `u64` Non-negative file size or length of a region within a file. diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 162c80f2b..772b8be82 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -5,6 +5,9 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. +;;; An array size. +;;; +;;; Note: This is similar to `size_t` in POSIX. (typename $size (@witx usize)) ;;; Non-negative file size or length of a region within a file. From c165fa01916cc29eb906e62cb36ce87dc780d41d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 27 Feb 2020 07:56:42 -0800 Subject: [PATCH 0591/1772] Add a documentation comment for the `$size` type. (#236) --- proposals/filesystem/phases/ephemeral/docs.md | 3 +++ proposals/filesystem/phases/ephemeral/witx/typenames.witx | 3 +++ 2 files changed, 6 insertions(+) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index a05ec6e8c..c645a7452 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -1,5 +1,8 @@ # Types ## `size`: `usize` +An array size. + +Note: This is similar to `size_t` in POSIX. ## `filesize`: `u64` Non-negative file size or length of a region within a file. diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 162c80f2b..772b8be82 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -5,6 +5,9 @@ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) ;; for an explanation of what that means. +;;; An array size. +;;; +;;; Note: This is similar to `size_t` in POSIX. (typename $size (@witx usize)) ;;; Non-negative file size or length of a region within a file. From b7e03ce41007432ef0312e872ac679ea14baa1ff Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 29 Feb 2020 01:19:27 +0100 Subject: [PATCH 0592/1772] Backport fd as handle to past and current snapshots (#238) This commit backports fd as handle to past and current snapshots. I'm hoping this could prove useful in situations where currently in the implementor's code, any syscall that deals with `fd`s has to be marked as potentially "unsafe", whereas with `fd` as a handle this would be shifted to the fact that `fd` *is* a handle rather than an alias to an int type. --- proposals/clocks/phases/old/snapshot_0/docs.md | 5 +++-- proposals/clocks/phases/old/snapshot_0/witx/typenames.witx | 4 ++-- proposals/clocks/phases/snapshot/docs.md | 5 +++-- proposals/clocks/phases/snapshot/witx/typenames.witx | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index 6bfe03198..f5b8ff314 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -368,9 +368,10 @@ If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [ - `sock_shutdown` The right to invoke [`sock_shutdown`](#sock_shutdown). -## `fd`: `u32` -A file descriptor index. +## `fd` +A file descriptor handle. +### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx index 0efdb27a7..f59f9ea15 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx @@ -273,8 +273,8 @@ ) ) -;;; A file descriptor index. -(typename $fd u32) +;;; A file descriptor handle. +(typename $fd (handle)) ;;; A region of memory for scatter/gather reads. (typename $iovec diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index 274e5335c..e2da39278 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -368,9 +368,10 @@ If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [ - `sock_shutdown` The right to invoke [`sock_shutdown`](#sock_shutdown). -## `fd`: `u32` -A file descriptor index. +## `fd` +A file descriptor handle. +### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx index 27d84cd5f..2bccd79a6 100644 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -273,8 +273,8 @@ ) ) -;;; A file descriptor index. -(typename $fd u32) +;;; A file descriptor handle. +(typename $fd (handle)) ;;; A region of memory for scatter/gather reads. (typename $iovec From 35d643518febb4ec8909418cd56e8f3b9f4534e9 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 29 Feb 2020 01:19:27 +0100 Subject: [PATCH 0593/1772] Backport fd as handle to past and current snapshots (#238) This commit backports fd as handle to past and current snapshots. I'm hoping this could prove useful in situations where currently in the implementor's code, any syscall that deals with `fd`s has to be marked as potentially "unsafe", whereas with `fd` as a handle this would be shifted to the fact that `fd` *is* a handle rather than an alias to an int type. --- proposals/random/phases/old/snapshot_0/docs.md | 5 +++-- proposals/random/phases/old/snapshot_0/witx/typenames.witx | 4 ++-- proposals/random/phases/snapshot/docs.md | 5 +++-- proposals/random/phases/snapshot/witx/typenames.witx | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index 6bfe03198..f5b8ff314 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -368,9 +368,10 @@ If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [ - `sock_shutdown` The right to invoke [`sock_shutdown`](#sock_shutdown). -## `fd`: `u32` -A file descriptor index. +## `fd` +A file descriptor handle. +### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx index 0efdb27a7..f59f9ea15 100644 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/random/phases/old/snapshot_0/witx/typenames.witx @@ -273,8 +273,8 @@ ) ) -;;; A file descriptor index. -(typename $fd u32) +;;; A file descriptor handle. +(typename $fd (handle)) ;;; A region of memory for scatter/gather reads. (typename $iovec diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index 274e5335c..e2da39278 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -368,9 +368,10 @@ If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [ - `sock_shutdown` The right to invoke [`sock_shutdown`](#sock_shutdown). -## `fd`: `u32` -A file descriptor index. +## `fd` +A file descriptor handle. +### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx index 27d84cd5f..2bccd79a6 100644 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -273,8 +273,8 @@ ) ) -;;; A file descriptor index. -(typename $fd u32) +;;; A file descriptor handle. +(typename $fd (handle)) ;;; A region of memory for scatter/gather reads. (typename $iovec From f6c6e5cef480c2b0900f03edf856e97aa008dcf2 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 29 Feb 2020 01:19:27 +0100 Subject: [PATCH 0594/1772] Backport fd as handle to past and current snapshots (#238) This commit backports fd as handle to past and current snapshots. I'm hoping this could prove useful in situations where currently in the implementor's code, any syscall that deals with `fd`s has to be marked as potentially "unsafe", whereas with `fd` as a handle this would be shifted to the fact that `fd` *is* a handle rather than an alias to an int type. --- proposals/filesystem/phases/old/snapshot_0/docs.md | 5 +++-- .../filesystem/phases/old/snapshot_0/witx/typenames.witx | 4 ++-- proposals/filesystem/phases/snapshot/docs.md | 5 +++-- proposals/filesystem/phases/snapshot/witx/typenames.witx | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index 6bfe03198..f5b8ff314 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -368,9 +368,10 @@ If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [ - `sock_shutdown` The right to invoke [`sock_shutdown`](#sock_shutdown). -## `fd`: `u32` -A file descriptor index. +## `fd` +A file descriptor handle. +### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx index 0efdb27a7..f59f9ea15 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx @@ -273,8 +273,8 @@ ) ) -;;; A file descriptor index. -(typename $fd u32) +;;; A file descriptor handle. +(typename $fd (handle)) ;;; A region of memory for scatter/gather reads. (typename $iovec diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index 274e5335c..e2da39278 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -368,9 +368,10 @@ If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [ - `sock_shutdown` The right to invoke [`sock_shutdown`](#sock_shutdown). -## `fd`: `u32` -A file descriptor index. +## `fd` +A file descriptor handle. +### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx index 27d84cd5f..2bccd79a6 100644 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -273,8 +273,8 @@ ) ) -;;; A file descriptor index. -(typename $fd u32) +;;; A file descriptor handle. +(typename $fd (handle)) ;;; A region of memory for scatter/gather reads. (typename $iovec From 5e1cb9ae1ce4cc18eaf56946b98589fd5e6082c7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 6 Mar 2020 07:29:36 -0800 Subject: [PATCH 0595/1772] Add an agenda for the 03-12 meeting, and add notes for prior meetings (#241) * Add meeting notes for the past several meetings. * Add an agenda for the upcoming meeting. --- proposals/clocks/meetings/2019/WASI-11-21.md | 22 +++++ proposals/clocks/meetings/2019/WASI-12-05.md | 75 +++++++++++++++++ proposals/clocks/meetings/2019/WASI-12-19.md | 5 ++ proposals/clocks/meetings/2020/WASI-01-16.md | 89 ++++++++++++++++++++ proposals/clocks/meetings/2020/WASI-02-27.md | 51 +++++++++++ proposals/clocks/meetings/2020/WASI-03-12.md | 37 ++++++++ proposals/clocks/meetings/README.md | 1 + 7 files changed, 280 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-03-12.md diff --git a/proposals/clocks/meetings/2019/WASI-11-21.md b/proposals/clocks/meetings/2019/WASI-11-21.md index 6b818553a..005585876 100644 --- a/proposals/clocks/meetings/2019/WASI-11-21.md +++ b/proposals/clocks/meetings/2019/WASI-11-21.md @@ -39,3 +39,25 @@ Installation is required, see the calendar invite. 1. Closure ## Meeting Notes + +Attendees: + +Pat Hickey +Jan Falkin +Alex crichton +Jay Phelps +Andrew brown +Luke Wagner +Alon Zakai +Dan Gohman +Mark McCaskey + +Meeting notes: + +DG: WASI Snapshot 1 is out. + +DG: WASI-SDK and WASI-libc. Currently in Cranestation orginization. They will move under the WebAssembly orginization, that was approved at the last CG meeting. We just have to work out some minor licensing issues for that to move forward. + +DG: Modularization update. I don’t have an update, haven’t had enough time. The current PR shows the shape of it, but it needs to be updated to the current set of APIs and witx. + +DG: Call for volunteers. I want to emphasize that WASI is a big opportunity, and now is the time to make changes. Please make PRs against the ephemeral directory diff --git a/proposals/clocks/meetings/2019/WASI-12-05.md b/proposals/clocks/meetings/2019/WASI-12-05.md index cfc2b6297..0dc54deb4 100644 --- a/proposals/clocks/meetings/2019/WASI-12-05.md +++ b/proposals/clocks/meetings/2019/WASI-12-05.md @@ -46,4 +46,79 @@ Installation is required, see the calendar invite. ## Meeting Notes +Attendees: + +Dan Gohman +Pat Hickey +Stefan Junker +Wouter van Oortmerssen +Jan Falkin +Andrew Brown +Mark McCaskey +Peter Huene + +Meeting notes: + https://github.com/bytecodealliance/wasmtime/pull/235#issuecomment-518897502 + +DG: If people have comments on the process we’re following with these meetings, please give feedback. + +PH: I’ll second the agenda + +DG: First item, stack trace API. Thomas Lively proposed this, but he’s not in the meeting at this time. Let’s table this until he’s here. + +DG: Character encodings. This issue has been open for a while and there’s no easy answer. There’s a shape of a proposal in the issue that most engines are following - we say that everything is UTF-8. Is there any disagreement with that consensus here? + +(none) + +DG: For things like environment variables, it would simplify things a lot if we could guarantee those are UTF-8 strings. + +DG: What about filesystems with file names that are unencodable? Can we find a way to tunnel that through? We currently use pointer+length to pass all filenames. No filesystem permits null in a filename, so we can encode a non-UTF8 string by putting extra information after the null. The trouble comes when you have to manipulate the path. + +PH: What about interface types interaction? + +DG: The stuff after the null will still be valid UTF-8 which encodes the non-UTF-8 part of the filename. So any library code that expects UTF-8 will still work. +DG: We’ll take this as consensus, and go forward with this design for now. We can change it if problems happen or we have objections during implementations. + +AB: Can you clarify what is being encoded after the null? + +DG: Two things: in the part before the null we want a normal-looking string, so any bytes that cant be translated get the unencodable-character (uffd). Then, after the null, we put the information that was lost. Something like, index of the string, then the missing bytes. We want something that is reversible. I agree it is goofy. Does anyone know how to encode an arbitrary integer in a utf-8 byte pattern? Obviously we could invent something, like using ascii digits. If theres an existing way to encode it, we’d want to follow that. + +AB: So we can’t just say we support all unicode strings? + +DG: The problem is that there are names out there that can’t be expressed in unicode. And from people I’ve talked to, its rare in practice. So the goal here is that if you get a path from one wasi api, and treat it as a utf-8 string without manipulating it, and then pass it to another wasi api, it works exactly as is. + +AB: I misstated my question - is there no unicode format where this reconstruction wouldn't be necessary? Or will there always be some way for there to be an unencodable string? + +DG: My understanding is there’s no way out of this. + +Peter H: This would be for bytes which are not valid unicode codepoints. + +DG: I’m looking for enough agreement that we can keep designing this for now. + +Peter H: is there currently a part of the spec that allows non-utf8? + +DG: Witx String type is always UTF-8. We don’t have a byte vector type right now, but there are byte pointer-length pairs. For any string passed to WASI we’ll require it to be UTF-8, and any string coming from WASI would be guaranteed to be UTF-8. + +DG: Next topic, case sensitivity in filesystems. If you look at issue 72, the big picture strategy is that WASI doesn’t dictate case sensitivity or insensitivity, or what variation of sensitivity it has (because different filesystems have different rules, whether they case map ascii or different versions of unicode). I think the point of the API is to interact with existing filesystems, and we can’t control those, so this is going to be a portability hazard for WASI. We can make tools that help you detect these pitfalls. Does anyone have ideas of how we can make this better? + +DG: Ok, so to use the wasm scary word, it is nondeterministic to use different cases to access the same file in the WASI api. +DG: Alright, so the next two issues are about virtual terminal handling. Its a space largely defined by compatibility with existing systems like xterm, unix consoles, and windows consoles. It makes sense to have something simple here. You could imagine unifying terminals with GUIs, modernizing terminals, lots of blue sky stuff here. My sense is that the value here is to find a simple thing that will interoperate with lots of different existing systems. + +Sbc: Not just to interoperate with existing systems but to allow existing programs to run on many different systems? + +DG: Yes my goal is something like vi on wasi just works. It looks like lots of people don’t use terminfo to figure out colors and just hard-code them. And windows support is tricky because it doesn’t have exactly the same features as unix. In cases where the terminals differ, should we expose WASI programs to the differences between them? + +DG: The direction I’m going is we don’t try to do terminfo, the WASI implementation will be responsible for remapping escape sequences and all that. You could imagine having an environment variable TERM=WASI. It would look a lot like xterm, which in turn looks a lot like windows. + +DG: On that topic, input sequences are a subfield of escape sequences. Input varies way more than output, across platforms. This made me think we could do a cool radical thing like use unicode symbols. But maybe the simplest thing is, just do what xterm does, and if it needs to be remapped by a WASI implementation to fit another console, thats up to them. But there are interesting questions to still ask here like what set of input sequences to support + +DG: Its tempting to say, we can go and design a modern system that doesn’t have all the legacy baggage. But my instinct now is to pull back from that and pick a reasonable set of defaults based on some of the successful modern implementations. If someone wants to design a whole new system, I won’t stand in their way. + +SJ: Can you clarify about how vim would work on this? + +DG: Vim itself wouldnt have to change. Terminfo is a library that gets linked in, but hopefully we could provide a radically simplified version that works on wasi. Inside the wasi implementation, anything like a TTY would have to filter the output coming from WASI program to neutralize all escape sequences, and then encode in terms of whatever its client expects. + +SJ: I would have assumed that stdin/out/err just map to whatever the host of the WASI implementation expects + +DG: We’re worried about security, because the terminal interface wasn’t designed to deal with untrusted code running on the terminal. So one example is that you could run a program and you think that it exited, but really its just showing you something that looks like your shell. We want to not allow applications to do things like that, by default. So if you wanted to run vim, you’d have to give it permission to rewrite your entire screen, versus just print ordinary text to stdout, which would be the default. So, controlling cursor position and colors and that would be exposed to wasi as a capability. diff --git a/proposals/clocks/meetings/2019/WASI-12-19.md b/proposals/clocks/meetings/2019/WASI-12-19.md index 8f477ed78..0621c97b1 100644 --- a/proposals/clocks/meetings/2019/WASI-12-19.md +++ b/proposals/clocks/meetings/2019/WASI-12-19.md @@ -37,3 +37,8 @@ Installation is required, see the calendar invite. 1. Closure ## Meeting Notes + +Windowing and Framebuffer APIs: + +There's an early demo out, and it's gotten some feedback. Aarron Turner is +working on incorporating the feedback and putting together a proposal. diff --git a/proposals/clocks/meetings/2020/WASI-01-16.md b/proposals/clocks/meetings/2020/WASI-01-16.md index 801786c56..687446a21 100644 --- a/proposals/clocks/meetings/2020/WASI-01-16.md +++ b/proposals/clocks/meetings/2020/WASI-01-16.md @@ -32,3 +32,92 @@ Installation is required, see the calendar invite. 1. https://github.com/WebAssembly/WASI/pull/193 ## Meeting Notes + +Attendees: + +Dan Gohman +Jan Falkin +Johnnie Birch +Sam Clegg +Wouter van Oortmerssen +Mingqiu Sun +Andrew Brown +Alex Crichton +Peter Huene +Stefan Junker +Aaron Turner +Radu Matei +Brian Hardock +Ralph Squillace + +Meeting notes: + +##Pull 192: https://github.com/WebAssembly/WASI/pull/192 +(...) +Note SJ: not sure about a conclusion on this one + +## Link-time virtualization: https://github.com/WebAssembly/WASI/pull/69 + +DG: A way to override imports with alternative implementations of the same API + +Sbc: How about using the term “interposition” vs “virtualization”? +(...) +Sbc: I’m okay with “virtualization” as long as we know we don’t mean dynamic dispatch +DG: let’s discuss dynamic dispatch. +Sbc: I like the idea of keeping system interfaces simple and not bring in object orientation +DG: okay, can revisit this later. It’s also tricky cause it depends on features which aren’t done yet, namely interface types and (...) +Sbc: embedder decides linking, so they could have interposition or not, so the module isn’t in the position to dictate that +DG: How linking is being done today is not final + +Existing virtualization doc: https://github.com/WebAssembly/WASI/pull/69 + +Close this PR for now, citing the fact that the spec mechanisms we need to do this aren’t well defined yet, so we’ll focus on the simple thing for now. + +## POSIX compatibility +DG: people are surprised that WASI does not align with POSIX. We see justified reasons for this, but it means that applications will have to port to WASI and can’t just recompile for a different target. For compatibility we can have an emulation layer, but for more performance usage to the native syscalls will be beneficial. +Sbc: agree that we need a compatibility layer for easier transition to WASI +DG: once we have a better solution for accessing files, a lot of concerns will go away + + +## What should poll for no events do? https://github.com/WebAssembly/WASI/pull/193 +DG: As WASM doesn’t have signal handlers and might never have, does it make sense to poll indefinitely with no subscribers? +PH: Personally I think it should return `EINVAL` see (https://github.com/WebAssembly/WASI/pull/193#issuecomment-572737431) +AB: what happens to existing programs if we change this? +PH: if we start returning EINVAL from this, probably no one’s checking for it +DG: we could expose the change through a link failure with helpful documentation references. We could also put the feature back in once we have signals + +## Framebuffer API https://github.com/WebAssembly/WASI/issues/174 +AT: +Sbc: Is this using an mmap’ed file? +DG: I don’t know the API, but could we mmap the file into the runtime +Sbc: it probably needs an extra copy for copying between WASI and host memory +AT: Is this a good idea or do we need WebGL, and only that? +DG: we don’t have to wait for use cases which require WebGL, and we can implement the simple thing (framebuffer) now +AT: are there documents on how to get started with new syscalls? +DG: A C header file would be enough to get started. +AT: Cool, so I’ll get started on that +DG: are we going to have an audio API too? +AT: probably +DG: we’ll have to be careful about synchronizing the data flow +Sbc: Will consumers call these functions directly as opposed to using a libc wrapper +DG/Sbc: (...) probably? +DG: It’ll be great to have this so other API functions can follow this trail, like bulk copy, clearing the screen. So we can figure out questions like if we should pull those APIs in the WASI SDK, etc. + +## Presence on the upcoming in-person meeting? +Sbc to file an issue. + + + + +PE: Will be presenting on an embedder api for wasi at the cg meeting. +Sbc: maybe we should open an issue to collect items and see if it justifies an in-person meeting + +## Status on networking syscalls +DG: fastly and DG had an in-person meeting to discuss HTTP proxy API. Lots of pressure on network API due to asynchronous requirements, which depends on mechanisms which we don’t have (standardized) yet, e.g. coroutines, expressing synchronicity in interface types, etc. +PH: where’s this work tracked? +DG: there aren’t specific issues +SBC: Isn’t libevent which is synchronous the defacto standard? +DG: async depends on which level in the stack you’re looking at. Something which looks async to the application using callbacks, might be using a poll loop a layer below. +DG: we could have a single event loop for various events which is great for API builders, but not for application builders which might want their own event loop +SJ: what next steps are required to progress here? +DG: figuring out async, and then we need a proposal. We want to avoid a system which has either all networking or no networking. Ideally we’d like to have handles. Please reach out to me so we can discuss ideas. diff --git a/proposals/clocks/meetings/2020/WASI-02-27.md b/proposals/clocks/meetings/2020/WASI-02-27.md index 5648a7741..9a813723e 100644 --- a/proposals/clocks/meetings/2020/WASI-02-27.md +++ b/proposals/clocks/meetings/2020/WASI-02-27.md @@ -39,3 +39,54 @@ Installation is required, see the calendar invite. - We can also talk about process. ## Meeting Notes + +Attendees: + +Dan Gohman +Mark McCaskey +Eric Rosenberg +Mark S. Miller +Peter Huene +Yury Delendik +Luke Wagner +Daiki Ueno +Johnnie Birch +Lee Campbell +Benjamin Brittain +Aaron Turner +Pat Hickey +Ralph Squillace +Sam Clegg + + +Meeting notes: + +Whole-program LTO coming: +https://github.com/WebAssembly/tool-conventions/pull/134 +Smaller binary size, optimization of combining libraries with Wasm binary (for example libc) +Frame-buffer API: +https://github.com/WebAssembly/WASI/pull/229 +The process for designing and submitting new API proposals is still being figured out, so in addition to the proposal, let's also talk about what we can do to make the process easier. +Aaron: Idea: add a short and sweet markdown document laying out the steps for a proposal +Aaron: I wouldn’t mind writing this up. It’s already pretty much already in my PR. So it’s just cleaning that up and we would be good to go :) +Josh Triplett’s talk at Wasm SF was helpful, but a bit outdated even though it was only given a few months ago. + + + +Crypto API! +https://github.com/WebAssembly/WASI/pull/231 +What criteria should we apply? +We can also talk about process. +Being developed to support running wasm within a trusted execution environment, but intending this crypto API to have broader use cases. +Enarx: https://github.com/enarx/enarx/wiki +Prerequisite for sockets support +Lots of interest in sockets support. +Sockets dependency on merging read/write with send/recv? +Don’t over-rotate on POSIX. +How much appetite should we have for prototyping? +Feature flags are a great way to support this +Declare ahead of time what the process is. +Maybe it’s ok to use alternate names, as long as we document what’s going to happen. And maybe use polyfills to ease transitions. +Action item: Dan to write up a brief README for how to prototype a new feature. Also add things to watch out for. +Separate experimental repo? Directory? Maybe just put features in ephemeral/snapshot +Back on read/write - we don’t want to over-rotate on POSIX, but we do want a general read/write? We are heavily influenced by POSIX here. diff --git a/proposals/clocks/meetings/2020/WASI-03-12.md b/proposals/clocks/meetings/2020/WASI-03-12.md new file mode 100644 index 000000000..b8ad84d73 --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-03-12.md @@ -0,0 +1,37 @@ +![WASI logo](/WASI.png) + +## Agenda for the March 12 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: March 12, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Crypto API now has its own repository: + - https://github.com/WebAssembly/WASI-crypto + - Let's talk about process and expectations. + 1. Merging send/recv into write/read: + - https://github.com/WebAssembly/WASI/pull/240 + - This is a complex proposal, but the intention is to simplify + the I/O story as we contemplate new kinds of streams and messages. + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index b9324d4e3..454198c09 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -25,3 +25,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI December 19th video call](2019/WASI-12-19.md) * [WASI January 16th video call](2020/WASI-01-16.md) * [WASI February 27th video call](2020/WASI-02-27.md) + * [WASI March 12th video call](2020/WASI-03-12.md) From ab718c9d5bb348d701558b62475c4cd969458d25 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 6 Mar 2020 07:29:36 -0800 Subject: [PATCH 0596/1772] Add an agenda for the 03-12 meeting, and add notes for prior meetings (#241) * Add meeting notes for the past several meetings. * Add an agenda for the upcoming meeting. --- proposals/random/meetings/2019/WASI-11-21.md | 22 +++++ proposals/random/meetings/2019/WASI-12-05.md | 75 +++++++++++++++++ proposals/random/meetings/2019/WASI-12-19.md | 5 ++ proposals/random/meetings/2020/WASI-01-16.md | 89 ++++++++++++++++++++ proposals/random/meetings/2020/WASI-02-27.md | 51 +++++++++++ proposals/random/meetings/2020/WASI-03-12.md | 37 ++++++++ proposals/random/meetings/README.md | 1 + 7 files changed, 280 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-03-12.md diff --git a/proposals/random/meetings/2019/WASI-11-21.md b/proposals/random/meetings/2019/WASI-11-21.md index 6b818553a..005585876 100644 --- a/proposals/random/meetings/2019/WASI-11-21.md +++ b/proposals/random/meetings/2019/WASI-11-21.md @@ -39,3 +39,25 @@ Installation is required, see the calendar invite. 1. Closure ## Meeting Notes + +Attendees: + +Pat Hickey +Jan Falkin +Alex crichton +Jay Phelps +Andrew brown +Luke Wagner +Alon Zakai +Dan Gohman +Mark McCaskey + +Meeting notes: + +DG: WASI Snapshot 1 is out. + +DG: WASI-SDK and WASI-libc. Currently in Cranestation orginization. They will move under the WebAssembly orginization, that was approved at the last CG meeting. We just have to work out some minor licensing issues for that to move forward. + +DG: Modularization update. I don’t have an update, haven’t had enough time. The current PR shows the shape of it, but it needs to be updated to the current set of APIs and witx. + +DG: Call for volunteers. I want to emphasize that WASI is a big opportunity, and now is the time to make changes. Please make PRs against the ephemeral directory diff --git a/proposals/random/meetings/2019/WASI-12-05.md b/proposals/random/meetings/2019/WASI-12-05.md index cfc2b6297..0dc54deb4 100644 --- a/proposals/random/meetings/2019/WASI-12-05.md +++ b/proposals/random/meetings/2019/WASI-12-05.md @@ -46,4 +46,79 @@ Installation is required, see the calendar invite. ## Meeting Notes +Attendees: + +Dan Gohman +Pat Hickey +Stefan Junker +Wouter van Oortmerssen +Jan Falkin +Andrew Brown +Mark McCaskey +Peter Huene + +Meeting notes: + https://github.com/bytecodealliance/wasmtime/pull/235#issuecomment-518897502 + +DG: If people have comments on the process we’re following with these meetings, please give feedback. + +PH: I’ll second the agenda + +DG: First item, stack trace API. Thomas Lively proposed this, but he’s not in the meeting at this time. Let’s table this until he’s here. + +DG: Character encodings. This issue has been open for a while and there’s no easy answer. There’s a shape of a proposal in the issue that most engines are following - we say that everything is UTF-8. Is there any disagreement with that consensus here? + +(none) + +DG: For things like environment variables, it would simplify things a lot if we could guarantee those are UTF-8 strings. + +DG: What about filesystems with file names that are unencodable? Can we find a way to tunnel that through? We currently use pointer+length to pass all filenames. No filesystem permits null in a filename, so we can encode a non-UTF8 string by putting extra information after the null. The trouble comes when you have to manipulate the path. + +PH: What about interface types interaction? + +DG: The stuff after the null will still be valid UTF-8 which encodes the non-UTF-8 part of the filename. So any library code that expects UTF-8 will still work. +DG: We’ll take this as consensus, and go forward with this design for now. We can change it if problems happen or we have objections during implementations. + +AB: Can you clarify what is being encoded after the null? + +DG: Two things: in the part before the null we want a normal-looking string, so any bytes that cant be translated get the unencodable-character (uffd). Then, after the null, we put the information that was lost. Something like, index of the string, then the missing bytes. We want something that is reversible. I agree it is goofy. Does anyone know how to encode an arbitrary integer in a utf-8 byte pattern? Obviously we could invent something, like using ascii digits. If theres an existing way to encode it, we’d want to follow that. + +AB: So we can’t just say we support all unicode strings? + +DG: The problem is that there are names out there that can’t be expressed in unicode. And from people I’ve talked to, its rare in practice. So the goal here is that if you get a path from one wasi api, and treat it as a utf-8 string without manipulating it, and then pass it to another wasi api, it works exactly as is. + +AB: I misstated my question - is there no unicode format where this reconstruction wouldn't be necessary? Or will there always be some way for there to be an unencodable string? + +DG: My understanding is there’s no way out of this. + +Peter H: This would be for bytes which are not valid unicode codepoints. + +DG: I’m looking for enough agreement that we can keep designing this for now. + +Peter H: is there currently a part of the spec that allows non-utf8? + +DG: Witx String type is always UTF-8. We don’t have a byte vector type right now, but there are byte pointer-length pairs. For any string passed to WASI we’ll require it to be UTF-8, and any string coming from WASI would be guaranteed to be UTF-8. + +DG: Next topic, case sensitivity in filesystems. If you look at issue 72, the big picture strategy is that WASI doesn’t dictate case sensitivity or insensitivity, or what variation of sensitivity it has (because different filesystems have different rules, whether they case map ascii or different versions of unicode). I think the point of the API is to interact with existing filesystems, and we can’t control those, so this is going to be a portability hazard for WASI. We can make tools that help you detect these pitfalls. Does anyone have ideas of how we can make this better? + +DG: Ok, so to use the wasm scary word, it is nondeterministic to use different cases to access the same file in the WASI api. +DG: Alright, so the next two issues are about virtual terminal handling. Its a space largely defined by compatibility with existing systems like xterm, unix consoles, and windows consoles. It makes sense to have something simple here. You could imagine unifying terminals with GUIs, modernizing terminals, lots of blue sky stuff here. My sense is that the value here is to find a simple thing that will interoperate with lots of different existing systems. + +Sbc: Not just to interoperate with existing systems but to allow existing programs to run on many different systems? + +DG: Yes my goal is something like vi on wasi just works. It looks like lots of people don’t use terminfo to figure out colors and just hard-code them. And windows support is tricky because it doesn’t have exactly the same features as unix. In cases where the terminals differ, should we expose WASI programs to the differences between them? + +DG: The direction I’m going is we don’t try to do terminfo, the WASI implementation will be responsible for remapping escape sequences and all that. You could imagine having an environment variable TERM=WASI. It would look a lot like xterm, which in turn looks a lot like windows. + +DG: On that topic, input sequences are a subfield of escape sequences. Input varies way more than output, across platforms. This made me think we could do a cool radical thing like use unicode symbols. But maybe the simplest thing is, just do what xterm does, and if it needs to be remapped by a WASI implementation to fit another console, thats up to them. But there are interesting questions to still ask here like what set of input sequences to support + +DG: Its tempting to say, we can go and design a modern system that doesn’t have all the legacy baggage. But my instinct now is to pull back from that and pick a reasonable set of defaults based on some of the successful modern implementations. If someone wants to design a whole new system, I won’t stand in their way. + +SJ: Can you clarify about how vim would work on this? + +DG: Vim itself wouldnt have to change. Terminfo is a library that gets linked in, but hopefully we could provide a radically simplified version that works on wasi. Inside the wasi implementation, anything like a TTY would have to filter the output coming from WASI program to neutralize all escape sequences, and then encode in terms of whatever its client expects. + +SJ: I would have assumed that stdin/out/err just map to whatever the host of the WASI implementation expects + +DG: We’re worried about security, because the terminal interface wasn’t designed to deal with untrusted code running on the terminal. So one example is that you could run a program and you think that it exited, but really its just showing you something that looks like your shell. We want to not allow applications to do things like that, by default. So if you wanted to run vim, you’d have to give it permission to rewrite your entire screen, versus just print ordinary text to stdout, which would be the default. So, controlling cursor position and colors and that would be exposed to wasi as a capability. diff --git a/proposals/random/meetings/2019/WASI-12-19.md b/proposals/random/meetings/2019/WASI-12-19.md index 8f477ed78..0621c97b1 100644 --- a/proposals/random/meetings/2019/WASI-12-19.md +++ b/proposals/random/meetings/2019/WASI-12-19.md @@ -37,3 +37,8 @@ Installation is required, see the calendar invite. 1. Closure ## Meeting Notes + +Windowing and Framebuffer APIs: + +There's an early demo out, and it's gotten some feedback. Aarron Turner is +working on incorporating the feedback and putting together a proposal. diff --git a/proposals/random/meetings/2020/WASI-01-16.md b/proposals/random/meetings/2020/WASI-01-16.md index 801786c56..687446a21 100644 --- a/proposals/random/meetings/2020/WASI-01-16.md +++ b/proposals/random/meetings/2020/WASI-01-16.md @@ -32,3 +32,92 @@ Installation is required, see the calendar invite. 1. https://github.com/WebAssembly/WASI/pull/193 ## Meeting Notes + +Attendees: + +Dan Gohman +Jan Falkin +Johnnie Birch +Sam Clegg +Wouter van Oortmerssen +Mingqiu Sun +Andrew Brown +Alex Crichton +Peter Huene +Stefan Junker +Aaron Turner +Radu Matei +Brian Hardock +Ralph Squillace + +Meeting notes: + +##Pull 192: https://github.com/WebAssembly/WASI/pull/192 +(...) +Note SJ: not sure about a conclusion on this one + +## Link-time virtualization: https://github.com/WebAssembly/WASI/pull/69 + +DG: A way to override imports with alternative implementations of the same API + +Sbc: How about using the term “interposition” vs “virtualization”? +(...) +Sbc: I’m okay with “virtualization” as long as we know we don’t mean dynamic dispatch +DG: let’s discuss dynamic dispatch. +Sbc: I like the idea of keeping system interfaces simple and not bring in object orientation +DG: okay, can revisit this later. It’s also tricky cause it depends on features which aren’t done yet, namely interface types and (...) +Sbc: embedder decides linking, so they could have interposition or not, so the module isn’t in the position to dictate that +DG: How linking is being done today is not final + +Existing virtualization doc: https://github.com/WebAssembly/WASI/pull/69 + +Close this PR for now, citing the fact that the spec mechanisms we need to do this aren’t well defined yet, so we’ll focus on the simple thing for now. + +## POSIX compatibility +DG: people are surprised that WASI does not align with POSIX. We see justified reasons for this, but it means that applications will have to port to WASI and can’t just recompile for a different target. For compatibility we can have an emulation layer, but for more performance usage to the native syscalls will be beneficial. +Sbc: agree that we need a compatibility layer for easier transition to WASI +DG: once we have a better solution for accessing files, a lot of concerns will go away + + +## What should poll for no events do? https://github.com/WebAssembly/WASI/pull/193 +DG: As WASM doesn’t have signal handlers and might never have, does it make sense to poll indefinitely with no subscribers? +PH: Personally I think it should return `EINVAL` see (https://github.com/WebAssembly/WASI/pull/193#issuecomment-572737431) +AB: what happens to existing programs if we change this? +PH: if we start returning EINVAL from this, probably no one’s checking for it +DG: we could expose the change through a link failure with helpful documentation references. We could also put the feature back in once we have signals + +## Framebuffer API https://github.com/WebAssembly/WASI/issues/174 +AT: +Sbc: Is this using an mmap’ed file? +DG: I don’t know the API, but could we mmap the file into the runtime +Sbc: it probably needs an extra copy for copying between WASI and host memory +AT: Is this a good idea or do we need WebGL, and only that? +DG: we don’t have to wait for use cases which require WebGL, and we can implement the simple thing (framebuffer) now +AT: are there documents on how to get started with new syscalls? +DG: A C header file would be enough to get started. +AT: Cool, so I’ll get started on that +DG: are we going to have an audio API too? +AT: probably +DG: we’ll have to be careful about synchronizing the data flow +Sbc: Will consumers call these functions directly as opposed to using a libc wrapper +DG/Sbc: (...) probably? +DG: It’ll be great to have this so other API functions can follow this trail, like bulk copy, clearing the screen. So we can figure out questions like if we should pull those APIs in the WASI SDK, etc. + +## Presence on the upcoming in-person meeting? +Sbc to file an issue. + + + + +PE: Will be presenting on an embedder api for wasi at the cg meeting. +Sbc: maybe we should open an issue to collect items and see if it justifies an in-person meeting + +## Status on networking syscalls +DG: fastly and DG had an in-person meeting to discuss HTTP proxy API. Lots of pressure on network API due to asynchronous requirements, which depends on mechanisms which we don’t have (standardized) yet, e.g. coroutines, expressing synchronicity in interface types, etc. +PH: where’s this work tracked? +DG: there aren’t specific issues +SBC: Isn’t libevent which is synchronous the defacto standard? +DG: async depends on which level in the stack you’re looking at. Something which looks async to the application using callbacks, might be using a poll loop a layer below. +DG: we could have a single event loop for various events which is great for API builders, but not for application builders which might want their own event loop +SJ: what next steps are required to progress here? +DG: figuring out async, and then we need a proposal. We want to avoid a system which has either all networking or no networking. Ideally we’d like to have handles. Please reach out to me so we can discuss ideas. diff --git a/proposals/random/meetings/2020/WASI-02-27.md b/proposals/random/meetings/2020/WASI-02-27.md index 5648a7741..9a813723e 100644 --- a/proposals/random/meetings/2020/WASI-02-27.md +++ b/proposals/random/meetings/2020/WASI-02-27.md @@ -39,3 +39,54 @@ Installation is required, see the calendar invite. - We can also talk about process. ## Meeting Notes + +Attendees: + +Dan Gohman +Mark McCaskey +Eric Rosenberg +Mark S. Miller +Peter Huene +Yury Delendik +Luke Wagner +Daiki Ueno +Johnnie Birch +Lee Campbell +Benjamin Brittain +Aaron Turner +Pat Hickey +Ralph Squillace +Sam Clegg + + +Meeting notes: + +Whole-program LTO coming: +https://github.com/WebAssembly/tool-conventions/pull/134 +Smaller binary size, optimization of combining libraries with Wasm binary (for example libc) +Frame-buffer API: +https://github.com/WebAssembly/WASI/pull/229 +The process for designing and submitting new API proposals is still being figured out, so in addition to the proposal, let's also talk about what we can do to make the process easier. +Aaron: Idea: add a short and sweet markdown document laying out the steps for a proposal +Aaron: I wouldn’t mind writing this up. It’s already pretty much already in my PR. So it’s just cleaning that up and we would be good to go :) +Josh Triplett’s talk at Wasm SF was helpful, but a bit outdated even though it was only given a few months ago. + + + +Crypto API! +https://github.com/WebAssembly/WASI/pull/231 +What criteria should we apply? +We can also talk about process. +Being developed to support running wasm within a trusted execution environment, but intending this crypto API to have broader use cases. +Enarx: https://github.com/enarx/enarx/wiki +Prerequisite for sockets support +Lots of interest in sockets support. +Sockets dependency on merging read/write with send/recv? +Don’t over-rotate on POSIX. +How much appetite should we have for prototyping? +Feature flags are a great way to support this +Declare ahead of time what the process is. +Maybe it’s ok to use alternate names, as long as we document what’s going to happen. And maybe use polyfills to ease transitions. +Action item: Dan to write up a brief README for how to prototype a new feature. Also add things to watch out for. +Separate experimental repo? Directory? Maybe just put features in ephemeral/snapshot +Back on read/write - we don’t want to over-rotate on POSIX, but we do want a general read/write? We are heavily influenced by POSIX here. diff --git a/proposals/random/meetings/2020/WASI-03-12.md b/proposals/random/meetings/2020/WASI-03-12.md new file mode 100644 index 000000000..b8ad84d73 --- /dev/null +++ b/proposals/random/meetings/2020/WASI-03-12.md @@ -0,0 +1,37 @@ +![WASI logo](/WASI.png) + +## Agenda for the March 12 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: March 12, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Crypto API now has its own repository: + - https://github.com/WebAssembly/WASI-crypto + - Let's talk about process and expectations. + 1. Merging send/recv into write/read: + - https://github.com/WebAssembly/WASI/pull/240 + - This is a complex proposal, but the intention is to simplify + the I/O story as we contemplate new kinds of streams and messages. + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index b9324d4e3..454198c09 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -25,3 +25,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI December 19th video call](2019/WASI-12-19.md) * [WASI January 16th video call](2020/WASI-01-16.md) * [WASI February 27th video call](2020/WASI-02-27.md) + * [WASI March 12th video call](2020/WASI-03-12.md) From e4f1f1951fe289e54b9968cf27133f5ff52997b6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 6 Mar 2020 07:29:36 -0800 Subject: [PATCH 0597/1772] Add an agenda for the 03-12 meeting, and add notes for prior meetings (#241) * Add meeting notes for the past several meetings. * Add an agenda for the upcoming meeting. --- .../filesystem/meetings/2019/WASI-11-21.md | 22 +++++ .../filesystem/meetings/2019/WASI-12-05.md | 75 ++++++++++++++++ .../filesystem/meetings/2019/WASI-12-19.md | 5 ++ .../filesystem/meetings/2020/WASI-01-16.md | 89 +++++++++++++++++++ .../filesystem/meetings/2020/WASI-02-27.md | 51 +++++++++++ .../filesystem/meetings/2020/WASI-03-12.md | 37 ++++++++ proposals/filesystem/meetings/README.md | 1 + 7 files changed, 280 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-03-12.md diff --git a/proposals/filesystem/meetings/2019/WASI-11-21.md b/proposals/filesystem/meetings/2019/WASI-11-21.md index 6b818553a..005585876 100644 --- a/proposals/filesystem/meetings/2019/WASI-11-21.md +++ b/proposals/filesystem/meetings/2019/WASI-11-21.md @@ -39,3 +39,25 @@ Installation is required, see the calendar invite. 1. Closure ## Meeting Notes + +Attendees: + +Pat Hickey +Jan Falkin +Alex crichton +Jay Phelps +Andrew brown +Luke Wagner +Alon Zakai +Dan Gohman +Mark McCaskey + +Meeting notes: + +DG: WASI Snapshot 1 is out. + +DG: WASI-SDK and WASI-libc. Currently in Cranestation orginization. They will move under the WebAssembly orginization, that was approved at the last CG meeting. We just have to work out some minor licensing issues for that to move forward. + +DG: Modularization update. I don’t have an update, haven’t had enough time. The current PR shows the shape of it, but it needs to be updated to the current set of APIs and witx. + +DG: Call for volunteers. I want to emphasize that WASI is a big opportunity, and now is the time to make changes. Please make PRs against the ephemeral directory diff --git a/proposals/filesystem/meetings/2019/WASI-12-05.md b/proposals/filesystem/meetings/2019/WASI-12-05.md index cfc2b6297..0dc54deb4 100644 --- a/proposals/filesystem/meetings/2019/WASI-12-05.md +++ b/proposals/filesystem/meetings/2019/WASI-12-05.md @@ -46,4 +46,79 @@ Installation is required, see the calendar invite. ## Meeting Notes +Attendees: + +Dan Gohman +Pat Hickey +Stefan Junker +Wouter van Oortmerssen +Jan Falkin +Andrew Brown +Mark McCaskey +Peter Huene + +Meeting notes: + https://github.com/bytecodealliance/wasmtime/pull/235#issuecomment-518897502 + +DG: If people have comments on the process we’re following with these meetings, please give feedback. + +PH: I’ll second the agenda + +DG: First item, stack trace API. Thomas Lively proposed this, but he’s not in the meeting at this time. Let’s table this until he’s here. + +DG: Character encodings. This issue has been open for a while and there’s no easy answer. There’s a shape of a proposal in the issue that most engines are following - we say that everything is UTF-8. Is there any disagreement with that consensus here? + +(none) + +DG: For things like environment variables, it would simplify things a lot if we could guarantee those are UTF-8 strings. + +DG: What about filesystems with file names that are unencodable? Can we find a way to tunnel that through? We currently use pointer+length to pass all filenames. No filesystem permits null in a filename, so we can encode a non-UTF8 string by putting extra information after the null. The trouble comes when you have to manipulate the path. + +PH: What about interface types interaction? + +DG: The stuff after the null will still be valid UTF-8 which encodes the non-UTF-8 part of the filename. So any library code that expects UTF-8 will still work. +DG: We’ll take this as consensus, and go forward with this design for now. We can change it if problems happen or we have objections during implementations. + +AB: Can you clarify what is being encoded after the null? + +DG: Two things: in the part before the null we want a normal-looking string, so any bytes that cant be translated get the unencodable-character (uffd). Then, after the null, we put the information that was lost. Something like, index of the string, then the missing bytes. We want something that is reversible. I agree it is goofy. Does anyone know how to encode an arbitrary integer in a utf-8 byte pattern? Obviously we could invent something, like using ascii digits. If theres an existing way to encode it, we’d want to follow that. + +AB: So we can’t just say we support all unicode strings? + +DG: The problem is that there are names out there that can’t be expressed in unicode. And from people I’ve talked to, its rare in practice. So the goal here is that if you get a path from one wasi api, and treat it as a utf-8 string without manipulating it, and then pass it to another wasi api, it works exactly as is. + +AB: I misstated my question - is there no unicode format where this reconstruction wouldn't be necessary? Or will there always be some way for there to be an unencodable string? + +DG: My understanding is there’s no way out of this. + +Peter H: This would be for bytes which are not valid unicode codepoints. + +DG: I’m looking for enough agreement that we can keep designing this for now. + +Peter H: is there currently a part of the spec that allows non-utf8? + +DG: Witx String type is always UTF-8. We don’t have a byte vector type right now, but there are byte pointer-length pairs. For any string passed to WASI we’ll require it to be UTF-8, and any string coming from WASI would be guaranteed to be UTF-8. + +DG: Next topic, case sensitivity in filesystems. If you look at issue 72, the big picture strategy is that WASI doesn’t dictate case sensitivity or insensitivity, or what variation of sensitivity it has (because different filesystems have different rules, whether they case map ascii or different versions of unicode). I think the point of the API is to interact with existing filesystems, and we can’t control those, so this is going to be a portability hazard for WASI. We can make tools that help you detect these pitfalls. Does anyone have ideas of how we can make this better? + +DG: Ok, so to use the wasm scary word, it is nondeterministic to use different cases to access the same file in the WASI api. +DG: Alright, so the next two issues are about virtual terminal handling. Its a space largely defined by compatibility with existing systems like xterm, unix consoles, and windows consoles. It makes sense to have something simple here. You could imagine unifying terminals with GUIs, modernizing terminals, lots of blue sky stuff here. My sense is that the value here is to find a simple thing that will interoperate with lots of different existing systems. + +Sbc: Not just to interoperate with existing systems but to allow existing programs to run on many different systems? + +DG: Yes my goal is something like vi on wasi just works. It looks like lots of people don’t use terminfo to figure out colors and just hard-code them. And windows support is tricky because it doesn’t have exactly the same features as unix. In cases where the terminals differ, should we expose WASI programs to the differences between them? + +DG: The direction I’m going is we don’t try to do terminfo, the WASI implementation will be responsible for remapping escape sequences and all that. You could imagine having an environment variable TERM=WASI. It would look a lot like xterm, which in turn looks a lot like windows. + +DG: On that topic, input sequences are a subfield of escape sequences. Input varies way more than output, across platforms. This made me think we could do a cool radical thing like use unicode symbols. But maybe the simplest thing is, just do what xterm does, and if it needs to be remapped by a WASI implementation to fit another console, thats up to them. But there are interesting questions to still ask here like what set of input sequences to support + +DG: Its tempting to say, we can go and design a modern system that doesn’t have all the legacy baggage. But my instinct now is to pull back from that and pick a reasonable set of defaults based on some of the successful modern implementations. If someone wants to design a whole new system, I won’t stand in their way. + +SJ: Can you clarify about how vim would work on this? + +DG: Vim itself wouldnt have to change. Terminfo is a library that gets linked in, but hopefully we could provide a radically simplified version that works on wasi. Inside the wasi implementation, anything like a TTY would have to filter the output coming from WASI program to neutralize all escape sequences, and then encode in terms of whatever its client expects. + +SJ: I would have assumed that stdin/out/err just map to whatever the host of the WASI implementation expects + +DG: We’re worried about security, because the terminal interface wasn’t designed to deal with untrusted code running on the terminal. So one example is that you could run a program and you think that it exited, but really its just showing you something that looks like your shell. We want to not allow applications to do things like that, by default. So if you wanted to run vim, you’d have to give it permission to rewrite your entire screen, versus just print ordinary text to stdout, which would be the default. So, controlling cursor position and colors and that would be exposed to wasi as a capability. diff --git a/proposals/filesystem/meetings/2019/WASI-12-19.md b/proposals/filesystem/meetings/2019/WASI-12-19.md index 8f477ed78..0621c97b1 100644 --- a/proposals/filesystem/meetings/2019/WASI-12-19.md +++ b/proposals/filesystem/meetings/2019/WASI-12-19.md @@ -37,3 +37,8 @@ Installation is required, see the calendar invite. 1. Closure ## Meeting Notes + +Windowing and Framebuffer APIs: + +There's an early demo out, and it's gotten some feedback. Aarron Turner is +working on incorporating the feedback and putting together a proposal. diff --git a/proposals/filesystem/meetings/2020/WASI-01-16.md b/proposals/filesystem/meetings/2020/WASI-01-16.md index 801786c56..687446a21 100644 --- a/proposals/filesystem/meetings/2020/WASI-01-16.md +++ b/proposals/filesystem/meetings/2020/WASI-01-16.md @@ -32,3 +32,92 @@ Installation is required, see the calendar invite. 1. https://github.com/WebAssembly/WASI/pull/193 ## Meeting Notes + +Attendees: + +Dan Gohman +Jan Falkin +Johnnie Birch +Sam Clegg +Wouter van Oortmerssen +Mingqiu Sun +Andrew Brown +Alex Crichton +Peter Huene +Stefan Junker +Aaron Turner +Radu Matei +Brian Hardock +Ralph Squillace + +Meeting notes: + +##Pull 192: https://github.com/WebAssembly/WASI/pull/192 +(...) +Note SJ: not sure about a conclusion on this one + +## Link-time virtualization: https://github.com/WebAssembly/WASI/pull/69 + +DG: A way to override imports with alternative implementations of the same API + +Sbc: How about using the term “interposition” vs “virtualization”? +(...) +Sbc: I’m okay with “virtualization” as long as we know we don’t mean dynamic dispatch +DG: let’s discuss dynamic dispatch. +Sbc: I like the idea of keeping system interfaces simple and not bring in object orientation +DG: okay, can revisit this later. It’s also tricky cause it depends on features which aren’t done yet, namely interface types and (...) +Sbc: embedder decides linking, so they could have interposition or not, so the module isn’t in the position to dictate that +DG: How linking is being done today is not final + +Existing virtualization doc: https://github.com/WebAssembly/WASI/pull/69 + +Close this PR for now, citing the fact that the spec mechanisms we need to do this aren’t well defined yet, so we’ll focus on the simple thing for now. + +## POSIX compatibility +DG: people are surprised that WASI does not align with POSIX. We see justified reasons for this, but it means that applications will have to port to WASI and can’t just recompile for a different target. For compatibility we can have an emulation layer, but for more performance usage to the native syscalls will be beneficial. +Sbc: agree that we need a compatibility layer for easier transition to WASI +DG: once we have a better solution for accessing files, a lot of concerns will go away + + +## What should poll for no events do? https://github.com/WebAssembly/WASI/pull/193 +DG: As WASM doesn’t have signal handlers and might never have, does it make sense to poll indefinitely with no subscribers? +PH: Personally I think it should return `EINVAL` see (https://github.com/WebAssembly/WASI/pull/193#issuecomment-572737431) +AB: what happens to existing programs if we change this? +PH: if we start returning EINVAL from this, probably no one’s checking for it +DG: we could expose the change through a link failure with helpful documentation references. We could also put the feature back in once we have signals + +## Framebuffer API https://github.com/WebAssembly/WASI/issues/174 +AT: +Sbc: Is this using an mmap’ed file? +DG: I don’t know the API, but could we mmap the file into the runtime +Sbc: it probably needs an extra copy for copying between WASI and host memory +AT: Is this a good idea or do we need WebGL, and only that? +DG: we don’t have to wait for use cases which require WebGL, and we can implement the simple thing (framebuffer) now +AT: are there documents on how to get started with new syscalls? +DG: A C header file would be enough to get started. +AT: Cool, so I’ll get started on that +DG: are we going to have an audio API too? +AT: probably +DG: we’ll have to be careful about synchronizing the data flow +Sbc: Will consumers call these functions directly as opposed to using a libc wrapper +DG/Sbc: (...) probably? +DG: It’ll be great to have this so other API functions can follow this trail, like bulk copy, clearing the screen. So we can figure out questions like if we should pull those APIs in the WASI SDK, etc. + +## Presence on the upcoming in-person meeting? +Sbc to file an issue. + + + + +PE: Will be presenting on an embedder api for wasi at the cg meeting. +Sbc: maybe we should open an issue to collect items and see if it justifies an in-person meeting + +## Status on networking syscalls +DG: fastly and DG had an in-person meeting to discuss HTTP proxy API. Lots of pressure on network API due to asynchronous requirements, which depends on mechanisms which we don’t have (standardized) yet, e.g. coroutines, expressing synchronicity in interface types, etc. +PH: where’s this work tracked? +DG: there aren’t specific issues +SBC: Isn’t libevent which is synchronous the defacto standard? +DG: async depends on which level in the stack you’re looking at. Something which looks async to the application using callbacks, might be using a poll loop a layer below. +DG: we could have a single event loop for various events which is great for API builders, but not for application builders which might want their own event loop +SJ: what next steps are required to progress here? +DG: figuring out async, and then we need a proposal. We want to avoid a system which has either all networking or no networking. Ideally we’d like to have handles. Please reach out to me so we can discuss ideas. diff --git a/proposals/filesystem/meetings/2020/WASI-02-27.md b/proposals/filesystem/meetings/2020/WASI-02-27.md index 5648a7741..9a813723e 100644 --- a/proposals/filesystem/meetings/2020/WASI-02-27.md +++ b/proposals/filesystem/meetings/2020/WASI-02-27.md @@ -39,3 +39,54 @@ Installation is required, see the calendar invite. - We can also talk about process. ## Meeting Notes + +Attendees: + +Dan Gohman +Mark McCaskey +Eric Rosenberg +Mark S. Miller +Peter Huene +Yury Delendik +Luke Wagner +Daiki Ueno +Johnnie Birch +Lee Campbell +Benjamin Brittain +Aaron Turner +Pat Hickey +Ralph Squillace +Sam Clegg + + +Meeting notes: + +Whole-program LTO coming: +https://github.com/WebAssembly/tool-conventions/pull/134 +Smaller binary size, optimization of combining libraries with Wasm binary (for example libc) +Frame-buffer API: +https://github.com/WebAssembly/WASI/pull/229 +The process for designing and submitting new API proposals is still being figured out, so in addition to the proposal, let's also talk about what we can do to make the process easier. +Aaron: Idea: add a short and sweet markdown document laying out the steps for a proposal +Aaron: I wouldn’t mind writing this up. It’s already pretty much already in my PR. So it’s just cleaning that up and we would be good to go :) +Josh Triplett’s talk at Wasm SF was helpful, but a bit outdated even though it was only given a few months ago. + + + +Crypto API! +https://github.com/WebAssembly/WASI/pull/231 +What criteria should we apply? +We can also talk about process. +Being developed to support running wasm within a trusted execution environment, but intending this crypto API to have broader use cases. +Enarx: https://github.com/enarx/enarx/wiki +Prerequisite for sockets support +Lots of interest in sockets support. +Sockets dependency on merging read/write with send/recv? +Don’t over-rotate on POSIX. +How much appetite should we have for prototyping? +Feature flags are a great way to support this +Declare ahead of time what the process is. +Maybe it’s ok to use alternate names, as long as we document what’s going to happen. And maybe use polyfills to ease transitions. +Action item: Dan to write up a brief README for how to prototype a new feature. Also add things to watch out for. +Separate experimental repo? Directory? Maybe just put features in ephemeral/snapshot +Back on read/write - we don’t want to over-rotate on POSIX, but we do want a general read/write? We are heavily influenced by POSIX here. diff --git a/proposals/filesystem/meetings/2020/WASI-03-12.md b/proposals/filesystem/meetings/2020/WASI-03-12.md new file mode 100644 index 000000000..b8ad84d73 --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-03-12.md @@ -0,0 +1,37 @@ +![WASI logo](/WASI.png) + +## Agenda for the March 12 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: March 12, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Crypto API now has its own repository: + - https://github.com/WebAssembly/WASI-crypto + - Let's talk about process and expectations. + 1. Merging send/recv into write/read: + - https://github.com/WebAssembly/WASI/pull/240 + - This is a complex proposal, but the intention is to simplify + the I/O story as we contemplate new kinds of streams and messages. + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index b9324d4e3..454198c09 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -25,3 +25,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI December 19th video call](2019/WASI-12-19.md) * [WASI January 16th video call](2020/WASI-01-16.md) * [WASI February 27th video call](2020/WASI-02-27.md) + * [WASI March 12th video call](2020/WASI-03-12.md) From 75a79d01b2827c06b35002f179c5f44470ced001 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 13 Mar 2020 17:48:01 -0500 Subject: [PATCH 0598/1772] Move `witx` program to an example (#243) This allows crates which depend on `witx` for library support to avoid pulling in `pretty_env_logger` and `structopt` since those are only used by the binary program instead of the library itself. --- proposals/clocks/tools/witx/Cargo.toml | 14 +++++--------- .../tools/witx/{src/main.rs => examples/witx.rs} | 0 2 files changed, 5 insertions(+), 9 deletions(-) rename proposals/clocks/tools/witx/{src/main.rs => examples/witx.rs} (100%) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index ef8efab1c..941c147aa 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -13,17 +13,13 @@ edition = "2018" [lib] crate-type=["rlib"] -[[bin]] -name = "witx" -path = "src/main.rs" - [dependencies] -structopt = "0.3" -wast = { version = "9.0.0", default-features = false } -thiserror = "1.0" -log = "0.4" -pretty_env_logger = "0.3" anyhow = "1" +log = "0.4" +thiserror = "1.0" +wast = { version = "9.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" +pretty_env_logger = "0.3" +structopt = "0.3" diff --git a/proposals/clocks/tools/witx/src/main.rs b/proposals/clocks/tools/witx/examples/witx.rs similarity index 100% rename from proposals/clocks/tools/witx/src/main.rs rename to proposals/clocks/tools/witx/examples/witx.rs From fc003befabf35e1cd7f78f6d9fea4cffbfad9489 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 13 Mar 2020 17:48:01 -0500 Subject: [PATCH 0599/1772] Move `witx` program to an example (#243) This allows crates which depend on `witx` for library support to avoid pulling in `pretty_env_logger` and `structopt` since those are only used by the binary program instead of the library itself. --- proposals/random/tools/witx/Cargo.toml | 14 +++++--------- .../tools/witx/{src/main.rs => examples/witx.rs} | 0 2 files changed, 5 insertions(+), 9 deletions(-) rename proposals/random/tools/witx/{src/main.rs => examples/witx.rs} (100%) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index ef8efab1c..941c147aa 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -13,17 +13,13 @@ edition = "2018" [lib] crate-type=["rlib"] -[[bin]] -name = "witx" -path = "src/main.rs" - [dependencies] -structopt = "0.3" -wast = { version = "9.0.0", default-features = false } -thiserror = "1.0" -log = "0.4" -pretty_env_logger = "0.3" anyhow = "1" +log = "0.4" +thiserror = "1.0" +wast = { version = "9.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" +pretty_env_logger = "0.3" +structopt = "0.3" diff --git a/proposals/random/tools/witx/src/main.rs b/proposals/random/tools/witx/examples/witx.rs similarity index 100% rename from proposals/random/tools/witx/src/main.rs rename to proposals/random/tools/witx/examples/witx.rs From 3530fbb0539bd499ecc513b75109edebf66dda77 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 13 Mar 2020 17:48:01 -0500 Subject: [PATCH 0600/1772] Move `witx` program to an example (#243) This allows crates which depend on `witx` for library support to avoid pulling in `pretty_env_logger` and `structopt` since those are only used by the binary program instead of the library itself. --- proposals/filesystem/tools/witx/Cargo.toml | 14 +++++--------- .../tools/witx/{src/main.rs => examples/witx.rs} | 0 2 files changed, 5 insertions(+), 9 deletions(-) rename proposals/filesystem/tools/witx/{src/main.rs => examples/witx.rs} (100%) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index ef8efab1c..941c147aa 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -13,17 +13,13 @@ edition = "2018" [lib] crate-type=["rlib"] -[[bin]] -name = "witx" -path = "src/main.rs" - [dependencies] -structopt = "0.3" -wast = { version = "9.0.0", default-features = false } -thiserror = "1.0" -log = "0.4" -pretty_env_logger = "0.3" anyhow = "1" +log = "0.4" +thiserror = "1.0" +wast = { version = "9.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" +pretty_env_logger = "0.3" +structopt = "0.3" diff --git a/proposals/filesystem/tools/witx/src/main.rs b/proposals/filesystem/tools/witx/examples/witx.rs similarity index 100% rename from proposals/filesystem/tools/witx/src/main.rs rename to proposals/filesystem/tools/witx/examples/witx.rs From c0b95b76beff6fb4925ae4aef1bdd009412b9bb9 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 13 Mar 2020 15:57:38 -0700 Subject: [PATCH 0601/1772] fix error message when docs out of date (#244) --- proposals/clocks/tools/witx/tests/wasi.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/tests/wasi.rs b/proposals/clocks/tools/witx/tests/wasi.rs index d2fbe807f..17f79341d 100644 --- a/proposals/clocks/tools/witx/tests/wasi.rs +++ b/proposals/clocks/tools/witx/tests/wasi.rs @@ -155,7 +155,9 @@ fn diff_against_filesystem(expected: &str, path: &Path) { } eprintln!(); - eprintln!("To regenerate the files, run `cd tools/witx && cargo run -- repo-docs`."); + eprintln!( + "To regenerate the files, run `cd tools/witx && cargo run --example witx repo-docs`." + ); eprintln!(); panic!(); } From 780a2cdbf7870abf196dad2fb36d3446e809099a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 13 Mar 2020 15:57:38 -0700 Subject: [PATCH 0602/1772] fix error message when docs out of date (#244) --- proposals/random/tools/witx/tests/wasi.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/tests/wasi.rs b/proposals/random/tools/witx/tests/wasi.rs index d2fbe807f..17f79341d 100644 --- a/proposals/random/tools/witx/tests/wasi.rs +++ b/proposals/random/tools/witx/tests/wasi.rs @@ -155,7 +155,9 @@ fn diff_against_filesystem(expected: &str, path: &Path) { } eprintln!(); - eprintln!("To regenerate the files, run `cd tools/witx && cargo run -- repo-docs`."); + eprintln!( + "To regenerate the files, run `cd tools/witx && cargo run --example witx repo-docs`." + ); eprintln!(); panic!(); } From 26c3dc3b8065a938165f69b64e00bed51ae9afbc Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 13 Mar 2020 15:57:38 -0700 Subject: [PATCH 0603/1772] fix error message when docs out of date (#244) --- proposals/filesystem/tools/witx/tests/wasi.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/tests/wasi.rs b/proposals/filesystem/tools/witx/tests/wasi.rs index d2fbe807f..17f79341d 100644 --- a/proposals/filesystem/tools/witx/tests/wasi.rs +++ b/proposals/filesystem/tools/witx/tests/wasi.rs @@ -155,7 +155,9 @@ fn diff_against_filesystem(expected: &str, path: &Path) { } eprintln!(); - eprintln!("To regenerate the files, run `cd tools/witx && cargo run -- repo-docs`."); + eprintln!( + "To regenerate the files, run `cd tools/witx && cargo run --example witx repo-docs`." + ); eprintln!(); panic!(); } From 9823d5a25a692d5c197c778bd68a1925881e8c3b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Mar 2020 13:23:59 -0700 Subject: [PATCH 0604/1772] bump witx to 0.8.4 (#245) --- proposals/clocks/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 941c147aa..158a36bdb 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.3" +version = "0.8.4" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From b919ba12baf6cb3e45ffe07e145b4ea36af4988a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Mar 2020 13:23:59 -0700 Subject: [PATCH 0605/1772] bump witx to 0.8.4 (#245) --- proposals/random/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 941c147aa..158a36bdb 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.3" +version = "0.8.4" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 3220e53ce9910ee4833640393530f374129f891c Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Mar 2020 13:23:59 -0700 Subject: [PATCH 0606/1772] bump witx to 0.8.4 (#245) --- proposals/filesystem/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 941c147aa..158a36bdb 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.3" +version = "0.8.4" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 63cdd2a92da590696ba53d82b90f8d61054384d2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 18 Mar 2020 12:58:52 -0500 Subject: [PATCH 0607/1772] Update some witx Rust dependencies (#246) Minor updates! --- proposals/clocks/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 158a36bdb..b4513ce59 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -17,9 +17,9 @@ crate-type=["rlib"] anyhow = "1" log = "0.4" thiserror = "1.0" -wast = { version = "9.0.0", default-features = false } +wast = { version = "11.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" -pretty_env_logger = "0.3" +pretty_env_logger = "0.4" structopt = "0.3" From f6577c124375ceeeb605bf4fe503c6ef7cf23b52 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 18 Mar 2020 12:58:52 -0500 Subject: [PATCH 0608/1772] Update some witx Rust dependencies (#246) Minor updates! --- proposals/random/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 158a36bdb..b4513ce59 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -17,9 +17,9 @@ crate-type=["rlib"] anyhow = "1" log = "0.4" thiserror = "1.0" -wast = { version = "9.0.0", default-features = false } +wast = { version = "11.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" -pretty_env_logger = "0.3" +pretty_env_logger = "0.4" structopt = "0.3" From 9e6ee63f6ed12085a7683d19c7890beb9fe06e36 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 18 Mar 2020 12:58:52 -0500 Subject: [PATCH 0609/1772] Update some witx Rust dependencies (#246) Minor updates! --- proposals/filesystem/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 158a36bdb..b4513ce59 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -17,9 +17,9 @@ crate-type=["rlib"] anyhow = "1" log = "0.4" thiserror = "1.0" -wast = { version = "9.0.0", default-features = false } +wast = { version = "11.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" -pretty_env_logger = "0.3" +pretty_env_logger = "0.4" structopt = "0.3" From b1ea4cb0dea7d4ed4ea3bdf23b3af58603794bfa Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 24 Mar 2020 10:09:32 -0700 Subject: [PATCH 0610/1772] Add an agenda for the 03-26 meeting. (#248) And add the notes for the 03-12 meeting. --- proposals/clocks/meetings/2020/WASI-03-12.md | 48 ++++++++++++++++++ proposals/clocks/meetings/2020/WASI-03-26.md | 51 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 3 files changed, 100 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-03-26.md diff --git a/proposals/clocks/meetings/2020/WASI-03-12.md b/proposals/clocks/meetings/2020/WASI-03-12.md index b8ad84d73..6efd47d9a 100644 --- a/proposals/clocks/meetings/2020/WASI-03-12.md +++ b/proposals/clocks/meetings/2020/WASI-03-12.md @@ -35,3 +35,51 @@ Installation is required, see the calendar invite. the I/O story as we contemplate new kinds of streams and messages. ## Meeting Notes + +Attendees: + +Dan Gohman +Jan Falkin +Mike Trinkala +Lee Campbell +Andrew Brown +Ralph Squillace +Johnnie Birch +Benjamin Brittain +Mark McCaskey + +Meeting notes: + +Crypto API now has its own repository: +https://github.com/WebAssembly/WASI-crypto +Let's talk about process and expectations. + +Merging send/recv into write/read: +https://github.com/WebAssembly/WASI/pull/240 +This is a complex proposal, but the intention is to simplify the I/O story as we contemplate new kinds of streams and messages. +It’s difficult to comment because it’s a big and fairly abstract PR +Prototype implementation would help people see how this works out in practice +Impromptu questions: +Is it ok to have ambient authorities for debugging facilities such as logging? +BB, Lee: Yes, handles are good +Making it ambient is a decrease in potential power of the system + +Impromptu agenda item: + +DG: Is it ok if we have ambient authorities producing handles if the handles themselves can’t be used to do any I/O? +Sealed capabilities are a useful concept. +Lee: Avoid ambient authorities. +BB: Capabilities aren’t just security, they also allow compositional design patterns. +Lee: eg. logging. Where does the log output go? If you make it a handle, now you can send different handles that represent different sinks. +Logging for debugging vs logging for production, perhaps are not so different use cases. +Lee: A really powerful feature would be to have move-only semantics for handles, so you can send an instance a handle and it can be sure it’s the only instance with access to it. +DG: Reference types proposal doesn’t have move-only semantics, but it’s something to think about +Lee: Reference-counting can lead to awkward edge cases where references are kept live, or have aliases, in surprising ways. +In Fuchsia, fd’s are 64-bit numbers and not reused. +WebAssembly/interface-types +BB: Move semantics changes how I’d design WASI APIs +Eg. capabilities for memory regions. What does it look like to transfer a handle for one of these to another instance? +Lee: Let’s have a discussion on rights, what rights look like, do we have a handle hierarchy? +WASI doesn’t predefine __unix__. +RS: GIve people a new engine, and it’s an easier step for people to take to port to. Guide them to doing the thing they want to do. Think of this as a new target. Don’t roll in old metaphors. +Lee: If something doesn’t build, then you know what you have to fix. If it builds but doesn’t work, now you have to debug it. diff --git a/proposals/clocks/meetings/2020/WASI-03-26.md b/proposals/clocks/meetings/2020/WASI-03-26.md new file mode 100644 index 000000000..b65c085c1 --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-03-26.md @@ -0,0 +1,51 @@ +![WASI logo](/WASI.png) + +## Agenda for the March 26 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: March 26, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. WASI currently uses a POSIX-like `errno` enum, but that seems + not well suited for less POSIX-like APIs: + https://github.com/WebAssembly/WASI-crypto/pull/13#issuecomment-599324384 + Many systems have evolved to having a single error enum shared + across the whole system. Is it ok if we don't aim for that? + 1. POSIX tries hard not to let syscalls cause segfaults, returning + things like `EFAULT` instead. There may be some value in this for + POSIX compatibility, but how valuable is this otherwise? Should + other WASI APIs be allowed to trap? + 1. Evolving idea: wasi-sdk API for extra emulation: + 1. `-D_WASILIBC_EMULATED_MMAN` + 1. `-D_WASILIBC_EMULATED_PAUSE` + 1. `-D_WASILIBC_EMULATED_RAISE` + 1. ... + 1. `-D_WASILIBC_EMULATED_ALL` ? + and + 1. `-lwasi-emulated-mman` + 1. `-lwasi-emulated-pause` + 1. `-lwasi-emulated-raise` + 1. ... + 1. `-lwasi-emulated-all` ? + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 454198c09..6bbf6c6c6 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -26,3 +26,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI January 16th video call](2020/WASI-01-16.md) * [WASI February 27th video call](2020/WASI-02-27.md) * [WASI March 12th video call](2020/WASI-03-12.md) + * [WASI March 26th video call](2020/WASI-03-26.md) From 0668d0e6c1b6bec2fb55ce84593317ce586548c3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 24 Mar 2020 10:09:32 -0700 Subject: [PATCH 0611/1772] Add an agenda for the 03-26 meeting. (#248) And add the notes for the 03-12 meeting. --- proposals/random/meetings/2020/WASI-03-12.md | 48 ++++++++++++++++++ proposals/random/meetings/2020/WASI-03-26.md | 51 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 3 files changed, 100 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-03-26.md diff --git a/proposals/random/meetings/2020/WASI-03-12.md b/proposals/random/meetings/2020/WASI-03-12.md index b8ad84d73..6efd47d9a 100644 --- a/proposals/random/meetings/2020/WASI-03-12.md +++ b/proposals/random/meetings/2020/WASI-03-12.md @@ -35,3 +35,51 @@ Installation is required, see the calendar invite. the I/O story as we contemplate new kinds of streams and messages. ## Meeting Notes + +Attendees: + +Dan Gohman +Jan Falkin +Mike Trinkala +Lee Campbell +Andrew Brown +Ralph Squillace +Johnnie Birch +Benjamin Brittain +Mark McCaskey + +Meeting notes: + +Crypto API now has its own repository: +https://github.com/WebAssembly/WASI-crypto +Let's talk about process and expectations. + +Merging send/recv into write/read: +https://github.com/WebAssembly/WASI/pull/240 +This is a complex proposal, but the intention is to simplify the I/O story as we contemplate new kinds of streams and messages. +It’s difficult to comment because it’s a big and fairly abstract PR +Prototype implementation would help people see how this works out in practice +Impromptu questions: +Is it ok to have ambient authorities for debugging facilities such as logging? +BB, Lee: Yes, handles are good +Making it ambient is a decrease in potential power of the system + +Impromptu agenda item: + +DG: Is it ok if we have ambient authorities producing handles if the handles themselves can’t be used to do any I/O? +Sealed capabilities are a useful concept. +Lee: Avoid ambient authorities. +BB: Capabilities aren’t just security, they also allow compositional design patterns. +Lee: eg. logging. Where does the log output go? If you make it a handle, now you can send different handles that represent different sinks. +Logging for debugging vs logging for production, perhaps are not so different use cases. +Lee: A really powerful feature would be to have move-only semantics for handles, so you can send an instance a handle and it can be sure it’s the only instance with access to it. +DG: Reference types proposal doesn’t have move-only semantics, but it’s something to think about +Lee: Reference-counting can lead to awkward edge cases where references are kept live, or have aliases, in surprising ways. +In Fuchsia, fd’s are 64-bit numbers and not reused. +WebAssembly/interface-types +BB: Move semantics changes how I’d design WASI APIs +Eg. capabilities for memory regions. What does it look like to transfer a handle for one of these to another instance? +Lee: Let’s have a discussion on rights, what rights look like, do we have a handle hierarchy? +WASI doesn’t predefine __unix__. +RS: GIve people a new engine, and it’s an easier step for people to take to port to. Guide them to doing the thing they want to do. Think of this as a new target. Don’t roll in old metaphors. +Lee: If something doesn’t build, then you know what you have to fix. If it builds but doesn’t work, now you have to debug it. diff --git a/proposals/random/meetings/2020/WASI-03-26.md b/proposals/random/meetings/2020/WASI-03-26.md new file mode 100644 index 000000000..b65c085c1 --- /dev/null +++ b/proposals/random/meetings/2020/WASI-03-26.md @@ -0,0 +1,51 @@ +![WASI logo](/WASI.png) + +## Agenda for the March 26 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: March 26, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. WASI currently uses a POSIX-like `errno` enum, but that seems + not well suited for less POSIX-like APIs: + https://github.com/WebAssembly/WASI-crypto/pull/13#issuecomment-599324384 + Many systems have evolved to having a single error enum shared + across the whole system. Is it ok if we don't aim for that? + 1. POSIX tries hard not to let syscalls cause segfaults, returning + things like `EFAULT` instead. There may be some value in this for + POSIX compatibility, but how valuable is this otherwise? Should + other WASI APIs be allowed to trap? + 1. Evolving idea: wasi-sdk API for extra emulation: + 1. `-D_WASILIBC_EMULATED_MMAN` + 1. `-D_WASILIBC_EMULATED_PAUSE` + 1. `-D_WASILIBC_EMULATED_RAISE` + 1. ... + 1. `-D_WASILIBC_EMULATED_ALL` ? + and + 1. `-lwasi-emulated-mman` + 1. `-lwasi-emulated-pause` + 1. `-lwasi-emulated-raise` + 1. ... + 1. `-lwasi-emulated-all` ? + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 454198c09..6bbf6c6c6 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -26,3 +26,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI January 16th video call](2020/WASI-01-16.md) * [WASI February 27th video call](2020/WASI-02-27.md) * [WASI March 12th video call](2020/WASI-03-12.md) + * [WASI March 26th video call](2020/WASI-03-26.md) From 8ad690d0602d3e2b12a3b1d1157475d1c6ccac3a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 24 Mar 2020 10:09:32 -0700 Subject: [PATCH 0612/1772] Add an agenda for the 03-26 meeting. (#248) And add the notes for the 03-12 meeting. --- .../filesystem/meetings/2020/WASI-03-12.md | 48 +++++++++++++++++ .../filesystem/meetings/2020/WASI-03-26.md | 51 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 3 files changed, 100 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-03-26.md diff --git a/proposals/filesystem/meetings/2020/WASI-03-12.md b/proposals/filesystem/meetings/2020/WASI-03-12.md index b8ad84d73..6efd47d9a 100644 --- a/proposals/filesystem/meetings/2020/WASI-03-12.md +++ b/proposals/filesystem/meetings/2020/WASI-03-12.md @@ -35,3 +35,51 @@ Installation is required, see the calendar invite. the I/O story as we contemplate new kinds of streams and messages. ## Meeting Notes + +Attendees: + +Dan Gohman +Jan Falkin +Mike Trinkala +Lee Campbell +Andrew Brown +Ralph Squillace +Johnnie Birch +Benjamin Brittain +Mark McCaskey + +Meeting notes: + +Crypto API now has its own repository: +https://github.com/WebAssembly/WASI-crypto +Let's talk about process and expectations. + +Merging send/recv into write/read: +https://github.com/WebAssembly/WASI/pull/240 +This is a complex proposal, but the intention is to simplify the I/O story as we contemplate new kinds of streams and messages. +It’s difficult to comment because it’s a big and fairly abstract PR +Prototype implementation would help people see how this works out in practice +Impromptu questions: +Is it ok to have ambient authorities for debugging facilities such as logging? +BB, Lee: Yes, handles are good +Making it ambient is a decrease in potential power of the system + +Impromptu agenda item: + +DG: Is it ok if we have ambient authorities producing handles if the handles themselves can’t be used to do any I/O? +Sealed capabilities are a useful concept. +Lee: Avoid ambient authorities. +BB: Capabilities aren’t just security, they also allow compositional design patterns. +Lee: eg. logging. Where does the log output go? If you make it a handle, now you can send different handles that represent different sinks. +Logging for debugging vs logging for production, perhaps are not so different use cases. +Lee: A really powerful feature would be to have move-only semantics for handles, so you can send an instance a handle and it can be sure it’s the only instance with access to it. +DG: Reference types proposal doesn’t have move-only semantics, but it’s something to think about +Lee: Reference-counting can lead to awkward edge cases where references are kept live, or have aliases, in surprising ways. +In Fuchsia, fd’s are 64-bit numbers and not reused. +WebAssembly/interface-types +BB: Move semantics changes how I’d design WASI APIs +Eg. capabilities for memory regions. What does it look like to transfer a handle for one of these to another instance? +Lee: Let’s have a discussion on rights, what rights look like, do we have a handle hierarchy? +WASI doesn’t predefine __unix__. +RS: GIve people a new engine, and it’s an easier step for people to take to port to. Guide them to doing the thing they want to do. Think of this as a new target. Don’t roll in old metaphors. +Lee: If something doesn’t build, then you know what you have to fix. If it builds but doesn’t work, now you have to debug it. diff --git a/proposals/filesystem/meetings/2020/WASI-03-26.md b/proposals/filesystem/meetings/2020/WASI-03-26.md new file mode 100644 index 000000000..b65c085c1 --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-03-26.md @@ -0,0 +1,51 @@ +![WASI logo](/WASI.png) + +## Agenda for the March 26 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: March 26, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. WASI currently uses a POSIX-like `errno` enum, but that seems + not well suited for less POSIX-like APIs: + https://github.com/WebAssembly/WASI-crypto/pull/13#issuecomment-599324384 + Many systems have evolved to having a single error enum shared + across the whole system. Is it ok if we don't aim for that? + 1. POSIX tries hard not to let syscalls cause segfaults, returning + things like `EFAULT` instead. There may be some value in this for + POSIX compatibility, but how valuable is this otherwise? Should + other WASI APIs be allowed to trap? + 1. Evolving idea: wasi-sdk API for extra emulation: + 1. `-D_WASILIBC_EMULATED_MMAN` + 1. `-D_WASILIBC_EMULATED_PAUSE` + 1. `-D_WASILIBC_EMULATED_RAISE` + 1. ... + 1. `-D_WASILIBC_EMULATED_ALL` ? + and + 1. `-lwasi-emulated-mman` + 1. `-lwasi-emulated-pause` + 1. `-lwasi-emulated-raise` + 1. ... + 1. `-lwasi-emulated-all` ? + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 454198c09..6bbf6c6c6 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -26,3 +26,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI January 16th video call](2020/WASI-01-16.md) * [WASI February 27th video call](2020/WASI-02-27.md) * [WASI March 12th video call](2020/WASI-03-12.md) + * [WASI March 26th video call](2020/WASI-03-26.md) From 15f76d025b77fc7d75f6d8057dc65413dc461241 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Thu, 26 Mar 2020 08:46:44 -0700 Subject: [PATCH 0613/1772] Add Proxy-Wasm update to 3/26 agenda. (#249) --- proposals/clocks/meetings/2020/WASI-03-26.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/clocks/meetings/2020/WASI-03-26.md b/proposals/clocks/meetings/2020/WASI-03-26.md index b65c085c1..bdb02ee28 100644 --- a/proposals/clocks/meetings/2020/WASI-03-26.md +++ b/proposals/clocks/meetings/2020/WASI-03-26.md @@ -47,5 +47,6 @@ Installation is required, see the calendar invite. 1. `-lwasi-emulated-raise` 1. ... 1. `-lwasi-emulated-all` ? + 1. [Proxy-Wasm](https://github.com/proxy-wasm) update. ## Meeting Notes From 6808000449e7fd5dae764c283802eced24e3f601 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Thu, 26 Mar 2020 08:46:44 -0700 Subject: [PATCH 0614/1772] Add Proxy-Wasm update to 3/26 agenda. (#249) --- proposals/random/meetings/2020/WASI-03-26.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/random/meetings/2020/WASI-03-26.md b/proposals/random/meetings/2020/WASI-03-26.md index b65c085c1..bdb02ee28 100644 --- a/proposals/random/meetings/2020/WASI-03-26.md +++ b/proposals/random/meetings/2020/WASI-03-26.md @@ -47,5 +47,6 @@ Installation is required, see the calendar invite. 1. `-lwasi-emulated-raise` 1. ... 1. `-lwasi-emulated-all` ? + 1. [Proxy-Wasm](https://github.com/proxy-wasm) update. ## Meeting Notes From e29e5926e972444d9fcc92dd830ba1c7ed2dc462 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Thu, 26 Mar 2020 08:46:44 -0700 Subject: [PATCH 0615/1772] Add Proxy-Wasm update to 3/26 agenda. (#249) --- proposals/filesystem/meetings/2020/WASI-03-26.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/filesystem/meetings/2020/WASI-03-26.md b/proposals/filesystem/meetings/2020/WASI-03-26.md index b65c085c1..bdb02ee28 100644 --- a/proposals/filesystem/meetings/2020/WASI-03-26.md +++ b/proposals/filesystem/meetings/2020/WASI-03-26.md @@ -47,5 +47,6 @@ Installation is required, see the calendar invite. 1. `-lwasi-emulated-raise` 1. ... 1. `-lwasi-emulated-all` ? + 1. [Proxy-Wasm](https://github.com/proxy-wasm) update. ## Meeting Notes From e86e510339d3a4f7e52e7f5989be6eb654a6af9e Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 30 Mar 2020 13:33:46 -0700 Subject: [PATCH 0616/1772] witx: expose iterator of all error types (#250) --- proposals/clocks/tools/witx/src/ast.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 564d4ea1d..661e91475 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -1,5 +1,5 @@ #![allow(dead_code)] -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::rc::{Rc, Weak}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -39,6 +39,18 @@ impl Document { _ => None, }) } + /// All of the (unique) types used as the first result value of a function. + pub fn error_types<'a>(&'a self) -> impl Iterator + 'a { + let errors: HashSet = self + .modules() + .flat_map(|m| { + m.funcs() + .filter_map(|f| f.results.get(0).as_ref().map(|r| r.tref.clone())) + .collect::>() + }) + .collect(); + errors.into_iter() + } pub fn module(&self, name: &Id) -> Option> { self.entries.get(&name).and_then(|e| match e { Entry::Module(m) => Some(m.upgrade().expect("always possible to upgrade entry")), From 97014d51f9fff5ef7c15f14735e8ec75883f5c37 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 30 Mar 2020 13:33:46 -0700 Subject: [PATCH 0617/1772] witx: expose iterator of all error types (#250) --- proposals/random/tools/witx/src/ast.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 564d4ea1d..661e91475 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -1,5 +1,5 @@ #![allow(dead_code)] -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::rc::{Rc, Weak}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -39,6 +39,18 @@ impl Document { _ => None, }) } + /// All of the (unique) types used as the first result value of a function. + pub fn error_types<'a>(&'a self) -> impl Iterator + 'a { + let errors: HashSet = self + .modules() + .flat_map(|m| { + m.funcs() + .filter_map(|f| f.results.get(0).as_ref().map(|r| r.tref.clone())) + .collect::>() + }) + .collect(); + errors.into_iter() + } pub fn module(&self, name: &Id) -> Option> { self.entries.get(&name).and_then(|e| match e { Entry::Module(m) => Some(m.upgrade().expect("always possible to upgrade entry")), From 7cfb94339911bedbbe8f6eb132339a3bb28d68bb Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 30 Mar 2020 13:33:46 -0700 Subject: [PATCH 0618/1772] witx: expose iterator of all error types (#250) --- proposals/filesystem/tools/witx/src/ast.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 564d4ea1d..661e91475 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -1,5 +1,5 @@ #![allow(dead_code)] -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::rc::{Rc, Weak}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -39,6 +39,18 @@ impl Document { _ => None, }) } + /// All of the (unique) types used as the first result value of a function. + pub fn error_types<'a>(&'a self) -> impl Iterator + 'a { + let errors: HashSet = self + .modules() + .flat_map(|m| { + m.funcs() + .filter_map(|f| f.results.get(0).as_ref().map(|r| r.tref.clone())) + .collect::>() + }) + .collect(); + errors.into_iter() + } pub fn module(&self, name: &Id) -> Option> { self.entries.get(&name).and_then(|e| match e { Entry::Module(m) => Some(m.upgrade().expect("always possible to upgrade entry")), From 43030de0b95d46d518fafaea8784193c0734a917 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 30 Mar 2020 13:35:49 -0700 Subject: [PATCH 0619/1772] bump witx to 0.8.5 --- proposals/clocks/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index b4513ce59..e5edffad2 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.4" +version = "0.8.5" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 4b9c02e57ac4eb913cf7ca000cdf51001707fd53 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 30 Mar 2020 13:35:49 -0700 Subject: [PATCH 0620/1772] bump witx to 0.8.5 --- proposals/random/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index b4513ce59..e5edffad2 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.4" +version = "0.8.5" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 0e8d31502024c25ba395780312c328e598aaefa5 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 30 Mar 2020 13:35:49 -0700 Subject: [PATCH 0621/1772] bump witx to 0.8.5 --- proposals/filesystem/tools/witx/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index b4513ce59..e5edffad2 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.4" +version = "0.8.5" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" From 0efcea04c8d821cb4197dc41f01236edabd95de2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 2 Apr 2020 17:42:45 -0700 Subject: [PATCH 0622/1772] Add an agenda for the 04-09 meeting and the notes for 03-26. (#253) --- proposals/clocks/meetings/2020/WASI-03-26.md | 74 ++++++++++++++++++++ proposals/clocks/meetings/2020/WASI-04-09.md | 32 +++++++++ proposals/clocks/meetings/README.md | 4 ++ 3 files changed, 110 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-04-09.md diff --git a/proposals/clocks/meetings/2020/WASI-03-26.md b/proposals/clocks/meetings/2020/WASI-03-26.md index bdb02ee28..47aa470da 100644 --- a/proposals/clocks/meetings/2020/WASI-03-26.md +++ b/proposals/clocks/meetings/2020/WASI-03-26.md @@ -50,3 +50,77 @@ Installation is required, see the calendar invite. 1. [Proxy-Wasm](https://github.com/proxy-wasm) update. ## Meeting Notes + +Attendees: + +Dan Gohman +Jan Falkin +Lee Campbell +Till Schneidereit +Alex Crichton +Andrew Brown +Mingqiu Sun +Olaf Tomalka +Piotr Sikora +Pat Hickey +Peter Huene +Sam Clegg +Johnnie Birch +Wouter van Oortmerssen +Luke Wagner +Aaron Turner +Benjamin Brittain +Taylor Thomas +John Plevyak +Ralph Squillace +Brian Hardock + +Meeting notes: + +WASI currently uses a POSIX-like errno enum, but that seems not well suited for less POSIX-like APIs: https://github.com/WebAssembly/WASI-crypto/pull/13#issuecomment-599324384 Many systems have evolved to having a single error enum shared across the whole system. Is it ok if we don't aim for that? +Lee: we need standardized ways to propagate errors throughout the system which is generic over all kinds of APIs +PH: Design a way to structure and compose errors. We should do this with types, rather than integer ranges. +SBC: Capability system is one of the unifying parts of WASI, there will be errors common to all capability operations. +PCH: Compositional errors might be something like a sum type of different errors. +Bwb: Strings as errors have lots of awkward problems, including internationalization. +PCH: Being able to use any type gives us the power to describe errors. +Jplev: Have a generic error codes, with ways to map to them. +Sbc: Don’t redeclare the same errors as POSIX +Pat: APIs define the things they need now, and we’ll work on factoring things out and composition as we go forward. +Lee: POSIX is a C API and we can map WASI errors to POSIX errno as needed. + + +POSIX tries hard not to let syscalls cause segfaults, returning things like EFAULT instead. There may be some value in this for POSIX compatibility, but how valuable is this otherwise? Should other WASI APIs be allowed to trap? +Sbc: one of our objectives is to be able to implement WASI as wasm modules. +Lee, sbc: We seem to need core language support for catching traps to really figure this out. +Evolving idea: wasi-sdk API for extra emulation: +``` +-D_WASILIBC_EMULATED_MMAN +-D_WASILIBC_EMULATED_PAUSE +-D_WASILIBC_EMULATED_RAISE +... +-D_WASILIBC_EMULATED_ALL ? and +-lwasi-emulated-mman +-lwasi-emulated-pause +-lwasi-emulated-raise +... +-lwasi-emulated-all ? +``` +Lee: Do we need the `-l`s? We can just put everythgin in libc.a and it’ll only get linked in +Proxy-Wasm update. +This is an update from the previous presentation in October. +Consolidated many callbacks from the previous presentationtation. + +Sbc: Have you looked at creating a witx description? +Piotr: Not yet; we’re still iterating on the API. +Sbc: Do proxy implementations need to implement all callbacks, or are some of the m optional? +Piotr: Some are optional. If you’re only implementing HTTP, you only need to impelment HTTP callbacks. +PH: This proposal is great, and also very big, can we factor out pieces that can be used in other contexts? + +Adapting the core CG Phases for WASI. +https://github.com/WebAssembly/proposals/ +“Two or more Web VMs” + +Reference interpreter, formal semantics + +Fitting the existing phases into the process diff --git a/proposals/clocks/meetings/2020/WASI-04-09.md b/proposals/clocks/meetings/2020/WASI-04-09.md new file mode 100644 index 000000000..f5de8a90f --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-04-09.md @@ -0,0 +1,32 @@ +![WASI logo](/WASI.png) + +## Agenda for the April 9 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: April 9, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Moving to a CG-style phases process: + https://github.com/WebAssembly/WASI/pull/252 + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 6bbf6c6c6..380496f38 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -23,7 +23,11 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI November 21st video call](2019/WASI-11-21.md) * [WASI December 5th video call](2019/WASI-12-05.md) * [WASI December 19th video call](2019/WASI-12-19.md) + +### 2020 + * [WASI January 16th video call](2020/WASI-01-16.md) * [WASI February 27th video call](2020/WASI-02-27.md) * [WASI March 12th video call](2020/WASI-03-12.md) * [WASI March 26th video call](2020/WASI-03-26.md) + * [WASI April 9th video call](2020/WASI-04-09.md) From 3c39a9cd193a00975418bea63850fee1f7384bc9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 2 Apr 2020 17:42:45 -0700 Subject: [PATCH 0623/1772] Add an agenda for the 04-09 meeting and the notes for 03-26. (#253) --- proposals/random/meetings/2020/WASI-03-26.md | 74 ++++++++++++++++++++ proposals/random/meetings/2020/WASI-04-09.md | 32 +++++++++ proposals/random/meetings/README.md | 4 ++ 3 files changed, 110 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-04-09.md diff --git a/proposals/random/meetings/2020/WASI-03-26.md b/proposals/random/meetings/2020/WASI-03-26.md index bdb02ee28..47aa470da 100644 --- a/proposals/random/meetings/2020/WASI-03-26.md +++ b/proposals/random/meetings/2020/WASI-03-26.md @@ -50,3 +50,77 @@ Installation is required, see the calendar invite. 1. [Proxy-Wasm](https://github.com/proxy-wasm) update. ## Meeting Notes + +Attendees: + +Dan Gohman +Jan Falkin +Lee Campbell +Till Schneidereit +Alex Crichton +Andrew Brown +Mingqiu Sun +Olaf Tomalka +Piotr Sikora +Pat Hickey +Peter Huene +Sam Clegg +Johnnie Birch +Wouter van Oortmerssen +Luke Wagner +Aaron Turner +Benjamin Brittain +Taylor Thomas +John Plevyak +Ralph Squillace +Brian Hardock + +Meeting notes: + +WASI currently uses a POSIX-like errno enum, but that seems not well suited for less POSIX-like APIs: https://github.com/WebAssembly/WASI-crypto/pull/13#issuecomment-599324384 Many systems have evolved to having a single error enum shared across the whole system. Is it ok if we don't aim for that? +Lee: we need standardized ways to propagate errors throughout the system which is generic over all kinds of APIs +PH: Design a way to structure and compose errors. We should do this with types, rather than integer ranges. +SBC: Capability system is one of the unifying parts of WASI, there will be errors common to all capability operations. +PCH: Compositional errors might be something like a sum type of different errors. +Bwb: Strings as errors have lots of awkward problems, including internationalization. +PCH: Being able to use any type gives us the power to describe errors. +Jplev: Have a generic error codes, with ways to map to them. +Sbc: Don’t redeclare the same errors as POSIX +Pat: APIs define the things they need now, and we’ll work on factoring things out and composition as we go forward. +Lee: POSIX is a C API and we can map WASI errors to POSIX errno as needed. + + +POSIX tries hard not to let syscalls cause segfaults, returning things like EFAULT instead. There may be some value in this for POSIX compatibility, but how valuable is this otherwise? Should other WASI APIs be allowed to trap? +Sbc: one of our objectives is to be able to implement WASI as wasm modules. +Lee, sbc: We seem to need core language support for catching traps to really figure this out. +Evolving idea: wasi-sdk API for extra emulation: +``` +-D_WASILIBC_EMULATED_MMAN +-D_WASILIBC_EMULATED_PAUSE +-D_WASILIBC_EMULATED_RAISE +... +-D_WASILIBC_EMULATED_ALL ? and +-lwasi-emulated-mman +-lwasi-emulated-pause +-lwasi-emulated-raise +... +-lwasi-emulated-all ? +``` +Lee: Do we need the `-l`s? We can just put everythgin in libc.a and it’ll only get linked in +Proxy-Wasm update. +This is an update from the previous presentation in October. +Consolidated many callbacks from the previous presentationtation. + +Sbc: Have you looked at creating a witx description? +Piotr: Not yet; we’re still iterating on the API. +Sbc: Do proxy implementations need to implement all callbacks, or are some of the m optional? +Piotr: Some are optional. If you’re only implementing HTTP, you only need to impelment HTTP callbacks. +PH: This proposal is great, and also very big, can we factor out pieces that can be used in other contexts? + +Adapting the core CG Phases for WASI. +https://github.com/WebAssembly/proposals/ +“Two or more Web VMs” + +Reference interpreter, formal semantics + +Fitting the existing phases into the process diff --git a/proposals/random/meetings/2020/WASI-04-09.md b/proposals/random/meetings/2020/WASI-04-09.md new file mode 100644 index 000000000..f5de8a90f --- /dev/null +++ b/proposals/random/meetings/2020/WASI-04-09.md @@ -0,0 +1,32 @@ +![WASI logo](/WASI.png) + +## Agenda for the April 9 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: April 9, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Moving to a CG-style phases process: + https://github.com/WebAssembly/WASI/pull/252 + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 6bbf6c6c6..380496f38 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -23,7 +23,11 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI November 21st video call](2019/WASI-11-21.md) * [WASI December 5th video call](2019/WASI-12-05.md) * [WASI December 19th video call](2019/WASI-12-19.md) + +### 2020 + * [WASI January 16th video call](2020/WASI-01-16.md) * [WASI February 27th video call](2020/WASI-02-27.md) * [WASI March 12th video call](2020/WASI-03-12.md) * [WASI March 26th video call](2020/WASI-03-26.md) + * [WASI April 9th video call](2020/WASI-04-09.md) From a24ecf0d9e0ff01a7ede57c14e5ced45b0ebbf11 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 2 Apr 2020 17:42:45 -0700 Subject: [PATCH 0624/1772] Add an agenda for the 04-09 meeting and the notes for 03-26. (#253) --- .../filesystem/meetings/2020/WASI-03-26.md | 74 +++++++++++++++++++ .../filesystem/meetings/2020/WASI-04-09.md | 32 ++++++++ proposals/filesystem/meetings/README.md | 4 + 3 files changed, 110 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-04-09.md diff --git a/proposals/filesystem/meetings/2020/WASI-03-26.md b/proposals/filesystem/meetings/2020/WASI-03-26.md index bdb02ee28..47aa470da 100644 --- a/proposals/filesystem/meetings/2020/WASI-03-26.md +++ b/proposals/filesystem/meetings/2020/WASI-03-26.md @@ -50,3 +50,77 @@ Installation is required, see the calendar invite. 1. [Proxy-Wasm](https://github.com/proxy-wasm) update. ## Meeting Notes + +Attendees: + +Dan Gohman +Jan Falkin +Lee Campbell +Till Schneidereit +Alex Crichton +Andrew Brown +Mingqiu Sun +Olaf Tomalka +Piotr Sikora +Pat Hickey +Peter Huene +Sam Clegg +Johnnie Birch +Wouter van Oortmerssen +Luke Wagner +Aaron Turner +Benjamin Brittain +Taylor Thomas +John Plevyak +Ralph Squillace +Brian Hardock + +Meeting notes: + +WASI currently uses a POSIX-like errno enum, but that seems not well suited for less POSIX-like APIs: https://github.com/WebAssembly/WASI-crypto/pull/13#issuecomment-599324384 Many systems have evolved to having a single error enum shared across the whole system. Is it ok if we don't aim for that? +Lee: we need standardized ways to propagate errors throughout the system which is generic over all kinds of APIs +PH: Design a way to structure and compose errors. We should do this with types, rather than integer ranges. +SBC: Capability system is one of the unifying parts of WASI, there will be errors common to all capability operations. +PCH: Compositional errors might be something like a sum type of different errors. +Bwb: Strings as errors have lots of awkward problems, including internationalization. +PCH: Being able to use any type gives us the power to describe errors. +Jplev: Have a generic error codes, with ways to map to them. +Sbc: Don’t redeclare the same errors as POSIX +Pat: APIs define the things they need now, and we’ll work on factoring things out and composition as we go forward. +Lee: POSIX is a C API and we can map WASI errors to POSIX errno as needed. + + +POSIX tries hard not to let syscalls cause segfaults, returning things like EFAULT instead. There may be some value in this for POSIX compatibility, but how valuable is this otherwise? Should other WASI APIs be allowed to trap? +Sbc: one of our objectives is to be able to implement WASI as wasm modules. +Lee, sbc: We seem to need core language support for catching traps to really figure this out. +Evolving idea: wasi-sdk API for extra emulation: +``` +-D_WASILIBC_EMULATED_MMAN +-D_WASILIBC_EMULATED_PAUSE +-D_WASILIBC_EMULATED_RAISE +... +-D_WASILIBC_EMULATED_ALL ? and +-lwasi-emulated-mman +-lwasi-emulated-pause +-lwasi-emulated-raise +... +-lwasi-emulated-all ? +``` +Lee: Do we need the `-l`s? We can just put everythgin in libc.a and it’ll only get linked in +Proxy-Wasm update. +This is an update from the previous presentation in October. +Consolidated many callbacks from the previous presentationtation. + +Sbc: Have you looked at creating a witx description? +Piotr: Not yet; we’re still iterating on the API. +Sbc: Do proxy implementations need to implement all callbacks, or are some of the m optional? +Piotr: Some are optional. If you’re only implementing HTTP, you only need to impelment HTTP callbacks. +PH: This proposal is great, and also very big, can we factor out pieces that can be used in other contexts? + +Adapting the core CG Phases for WASI. +https://github.com/WebAssembly/proposals/ +“Two or more Web VMs” + +Reference interpreter, formal semantics + +Fitting the existing phases into the process diff --git a/proposals/filesystem/meetings/2020/WASI-04-09.md b/proposals/filesystem/meetings/2020/WASI-04-09.md new file mode 100644 index 000000000..f5de8a90f --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-04-09.md @@ -0,0 +1,32 @@ +![WASI logo](/WASI.png) + +## Agenda for the April 9 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: April 9, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Moving to a CG-style phases process: + https://github.com/WebAssembly/WASI/pull/252 + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 6bbf6c6c6..380496f38 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -23,7 +23,11 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI November 21st video call](2019/WASI-11-21.md) * [WASI December 5th video call](2019/WASI-12-05.md) * [WASI December 19th video call](2019/WASI-12-19.md) + +### 2020 + * [WASI January 16th video call](2020/WASI-01-16.md) * [WASI February 27th video call](2020/WASI-02-27.md) * [WASI March 12th video call](2020/WASI-03-12.md) * [WASI March 26th video call](2020/WASI-03-26.md) + * [WASI April 9th video call](2020/WASI-04-09.md) From c13345b7253ccbda02e39c7362975a5830c99771 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 Apr 2020 16:59:00 -0700 Subject: [PATCH 0625/1772] Add an agenda item to discuss the proxy-wasm proposal. (#254) --- proposals/clocks/meetings/2020/WASI-04-09.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/clocks/meetings/2020/WASI-04-09.md b/proposals/clocks/meetings/2020/WASI-04-09.md index f5de8a90f..0be796fe0 100644 --- a/proposals/clocks/meetings/2020/WASI-04-09.md +++ b/proposals/clocks/meetings/2020/WASI-04-09.md @@ -28,5 +28,8 @@ Installation is required, see the calendar invite. 1. Proposals and discussions 1. Moving to a CG-style phases process: https://github.com/WebAssembly/WASI/pull/252 + 1. Proxy-wasm + 1. Vote: approve for Phase 1 (see previous item)? + 1. Discussion: Next steps. ## Meeting Notes From 6d6918d574f1302f0561a8df3f82a727e00f7154 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 Apr 2020 16:59:00 -0700 Subject: [PATCH 0626/1772] Add an agenda item to discuss the proxy-wasm proposal. (#254) --- proposals/random/meetings/2020/WASI-04-09.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/random/meetings/2020/WASI-04-09.md b/proposals/random/meetings/2020/WASI-04-09.md index f5de8a90f..0be796fe0 100644 --- a/proposals/random/meetings/2020/WASI-04-09.md +++ b/proposals/random/meetings/2020/WASI-04-09.md @@ -28,5 +28,8 @@ Installation is required, see the calendar invite. 1. Proposals and discussions 1. Moving to a CG-style phases process: https://github.com/WebAssembly/WASI/pull/252 + 1. Proxy-wasm + 1. Vote: approve for Phase 1 (see previous item)? + 1. Discussion: Next steps. ## Meeting Notes From 757bcf437019ee264b487d9dc6a8168eef950e07 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 Apr 2020 16:59:00 -0700 Subject: [PATCH 0627/1772] Add an agenda item to discuss the proxy-wasm proposal. (#254) --- proposals/filesystem/meetings/2020/WASI-04-09.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/filesystem/meetings/2020/WASI-04-09.md b/proposals/filesystem/meetings/2020/WASI-04-09.md index f5de8a90f..0be796fe0 100644 --- a/proposals/filesystem/meetings/2020/WASI-04-09.md +++ b/proposals/filesystem/meetings/2020/WASI-04-09.md @@ -28,5 +28,8 @@ Installation is required, see the calendar invite. 1. Proposals and discussions 1. Moving to a CG-style phases process: https://github.com/WebAssembly/WASI/pull/252 + 1. Proxy-wasm + 1. Vote: approve for Phase 1 (see previous item)? + 1. Discussion: Next steps. ## Meeting Notes From 0092120b72ca205ee54816fb04894d0731b82bd0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Apr 2020 07:56:34 -0700 Subject: [PATCH 0628/1772] Start moving WASI to a CG-style phases process. (#252) Adapt the WebAssembly CG's phases process for WASI, and make an initial mapping of current WASI proposals to phases within this process. This is quite rough at this time, and not everything fits in quite yet, and we can adjust things. This is a first step, and we'll work for greater harmonization as we proceed. --- proposals/clocks/docs/Process.md | 37 +++++++++++++++++++ proposals/clocks/docs/Proposals.md | 59 ++++++++++++++++++++++++++++++ proposals/clocks/phases/README.md | 37 +++++++------------ 3 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 proposals/clocks/docs/Process.md create mode 100644 proposals/clocks/docs/Proposals.md diff --git a/proposals/clocks/docs/Process.md b/proposals/clocks/docs/Process.md new file mode 100644 index 000000000..3b4affc3c --- /dev/null +++ b/proposals/clocks/docs/Process.md @@ -0,0 +1,37 @@ +# WASI Standardization Process + +WASI follows the [WebAssembly CG Phases process], with the following adaptations: + + - Entry into Stage 2 requires [witx] specifications. + + - Starting in Stage 2, proposals may follow WASI's [ephemeral/snapshot/old] process + to provide a balance between the need for stability so that toolchains and engines + can sync up, and the need for evolution. + + - The Phase 4's entry requirements for "Two or more Web VMs implement the feature", + "At least one toolchain implements the feature", and "The formalization and the + reference interpreter are usually updated (though these two can be done as part + of step 3 at the Working Group chair's discretion)." are waived. + + In their place, as an additional entry requirement into Phase 2, champion(s) must + include a set of entry criteria into Phase 4 in their proposal, which the Subgroup + will vote on as part of Phase 2 approval. + + Phase 4 criteria will vary depending on the API and its expected use cases, + but may include things like multiple independent production implementations, + implementations on multiple host platforms, polyfill implementations, and + bindings in toolchains and libraries. Note that, portability requirements may + vary between proposals, as not all features will necessarily make sense in all + host environments. + + - The specific process in Phases 4 and 5 will be determined when we have a + proposal ready for them. + + - Requirements around the reference interpreter don't apply. + + - WASI proposals don't require formal notation. Formal notation may be used in the + documentation of a feature, but it isn't expected to be practical for all APIs. + +[WebAssembly CG Phases process]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md +[witx]: https://github.com/WebAssembly/WASI/blob/master/docs/witx.md +[ephemeral/snapshot/old process]: https://github.com/WebAssembly/WASI/blob/master/phases/README.md diff --git a/proposals/clocks/docs/Proposals.md b/proposals/clocks/docs/Proposals.md new file mode 100644 index 000000000..5ba7fefd3 --- /dev/null +++ b/proposals/clocks/docs/Proposals.md @@ -0,0 +1,59 @@ +# WASI proposals + +This page is under construction. The intent is to follow the CG's +[proposals page], but adapted for [WASI]. Some of the proposals predate our +adoption of this process and so don't fit exactly into the defined phases, +however our intention is to align them going forward. + +[WASI]: https://github.com/WebAssembly/WASI +[proposals page]: https://github.com/WebAssembly/proposals/blob/master/README.md + +## Active proposals + +Proposals follow [this process document](https://github.com/WebAssembly/WASI/blob/master/docs/Process.md). + +### Phase 4 - Standardize the Feature (WG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | + +### Phase 3 - Implementation Phase (CG + WG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | + +### Phase 2 - Proposed Spec Text Available (CG + WG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | +| [I/O][wasi-io] | Dan Gohman | +| [Filesystem][wasi-filesystem] | Dan Gohman | +| [Command-Line][wasi-command-line] | Dan Gohman | +| [Clocks][wasi-clocks] | Dan Gohman | +| [Random][wasi-random] | Dan Gohman | +| [Misc][wasi-misc] | Dan Gohman | + +### Phase 1 - Feature Proposal (CG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | +| [Crypto][wasi-crypto] | Frank Denis and Daiki Ueno | + +### Phase 0 - Pre-Proposal (CG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | +| [proxy-wasm][wasi-proxy-wasm] | Piotr Sikora | + +### Contributing new proposals + +Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. + +[wasi-io]: https://github.com/WebAssembly/WASI/phases +[filesystem]: https://github.com/WebAssembly/WASI/phases +[wasi-command-line]: https://github.com/WebAssembly/WASI/phases +[clocks]: https://github.com/WebAssembly/WASI/phases +[random]: https://github.com/WebAssembly/WASI/phases +[misc]: https://github.com/WebAssembly/WASI/phases +[wasi-crypto]: https://github.com/WebAssembly/WASI-crypto +[wasi-proxy-wasm]: https://github.com/WebAssembly/WASI diff --git a/proposals/clocks/phases/README.md b/proposals/clocks/phases/README.md index 86f5fb4ba..06a515526 100644 --- a/proposals/clocks/phases/README.md +++ b/proposals/clocks/phases/README.md @@ -1,6 +1,17 @@ -# WASI development process +# WASI's ephemeral/snapshot/old Process -## WASI uses a 3-phase process: +For the standardization process, WASI overall uses a [process] +modeled after the WebAssembly CG's phased process. + +For development of features in Phase 2 and later of that process, WASI +has a ephemeral/snapshot/old process, which is designed to allow +for a balance between the need for stability to allow people to build +compatible implementations, libraries, and tools and gain implementation +experience, and the need for proposals to evolve. + +[phases process]: https://github.com/WebAssembly/WASI/blob/master/phases/README.md + +## The ephemeral/snapshot/old Phases - [`ephemeral`](ephemeral): The development staging area. New API proposals API-changing fixes to existing APIs should be submitted @@ -37,25 +48,3 @@ versions, the old API modules are moved to the `old` directory. When possible, `old` APIs may be accompanied by polyfill modules which implement their API in terms of newer versions of the API. - -## Rationale - -### Relationship to the CG's phases - -When WASI becomes more mature, such that we have an established base -and we're adding incremental functionality to it, we may want to adopt -a process like [the CG's phases]. However, right now, everything in -WASI is undergoing changes, so we have a greater need to iterate with -flexibility. - -### Relationship to standards - -WASI should eventually become a standard at the level of WebAssembly -itself. Right now, it needs a lot of work before it's ready. The -`snapshot` tree is meant to serve a practical purpose for people who -want to work with APIs today, with the understanding that everything -is still evolving. It's not meant as a replacement for proper -standardization, which will happen once the overall API is more -mature. - -[the CG's phases]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md From 957598ebbed603cdf6a5900a45a1423224ace9c9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Apr 2020 07:56:34 -0700 Subject: [PATCH 0629/1772] Start moving WASI to a CG-style phases process. (#252) Adapt the WebAssembly CG's phases process for WASI, and make an initial mapping of current WASI proposals to phases within this process. This is quite rough at this time, and not everything fits in quite yet, and we can adjust things. This is a first step, and we'll work for greater harmonization as we proceed. --- proposals/random/docs/Process.md | 37 +++++++++++++++++++ proposals/random/docs/Proposals.md | 59 ++++++++++++++++++++++++++++++ proposals/random/phases/README.md | 37 +++++++------------ 3 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 proposals/random/docs/Process.md create mode 100644 proposals/random/docs/Proposals.md diff --git a/proposals/random/docs/Process.md b/proposals/random/docs/Process.md new file mode 100644 index 000000000..3b4affc3c --- /dev/null +++ b/proposals/random/docs/Process.md @@ -0,0 +1,37 @@ +# WASI Standardization Process + +WASI follows the [WebAssembly CG Phases process], with the following adaptations: + + - Entry into Stage 2 requires [witx] specifications. + + - Starting in Stage 2, proposals may follow WASI's [ephemeral/snapshot/old] process + to provide a balance between the need for stability so that toolchains and engines + can sync up, and the need for evolution. + + - The Phase 4's entry requirements for "Two or more Web VMs implement the feature", + "At least one toolchain implements the feature", and "The formalization and the + reference interpreter are usually updated (though these two can be done as part + of step 3 at the Working Group chair's discretion)." are waived. + + In their place, as an additional entry requirement into Phase 2, champion(s) must + include a set of entry criteria into Phase 4 in their proposal, which the Subgroup + will vote on as part of Phase 2 approval. + + Phase 4 criteria will vary depending on the API and its expected use cases, + but may include things like multiple independent production implementations, + implementations on multiple host platforms, polyfill implementations, and + bindings in toolchains and libraries. Note that, portability requirements may + vary between proposals, as not all features will necessarily make sense in all + host environments. + + - The specific process in Phases 4 and 5 will be determined when we have a + proposal ready for them. + + - Requirements around the reference interpreter don't apply. + + - WASI proposals don't require formal notation. Formal notation may be used in the + documentation of a feature, but it isn't expected to be practical for all APIs. + +[WebAssembly CG Phases process]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md +[witx]: https://github.com/WebAssembly/WASI/blob/master/docs/witx.md +[ephemeral/snapshot/old process]: https://github.com/WebAssembly/WASI/blob/master/phases/README.md diff --git a/proposals/random/docs/Proposals.md b/proposals/random/docs/Proposals.md new file mode 100644 index 000000000..5ba7fefd3 --- /dev/null +++ b/proposals/random/docs/Proposals.md @@ -0,0 +1,59 @@ +# WASI proposals + +This page is under construction. The intent is to follow the CG's +[proposals page], but adapted for [WASI]. Some of the proposals predate our +adoption of this process and so don't fit exactly into the defined phases, +however our intention is to align them going forward. + +[WASI]: https://github.com/WebAssembly/WASI +[proposals page]: https://github.com/WebAssembly/proposals/blob/master/README.md + +## Active proposals + +Proposals follow [this process document](https://github.com/WebAssembly/WASI/blob/master/docs/Process.md). + +### Phase 4 - Standardize the Feature (WG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | + +### Phase 3 - Implementation Phase (CG + WG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | + +### Phase 2 - Proposed Spec Text Available (CG + WG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | +| [I/O][wasi-io] | Dan Gohman | +| [Filesystem][wasi-filesystem] | Dan Gohman | +| [Command-Line][wasi-command-line] | Dan Gohman | +| [Clocks][wasi-clocks] | Dan Gohman | +| [Random][wasi-random] | Dan Gohman | +| [Misc][wasi-misc] | Dan Gohman | + +### Phase 1 - Feature Proposal (CG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | +| [Crypto][wasi-crypto] | Frank Denis and Daiki Ueno | + +### Phase 0 - Pre-Proposal (CG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | +| [proxy-wasm][wasi-proxy-wasm] | Piotr Sikora | + +### Contributing new proposals + +Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. + +[wasi-io]: https://github.com/WebAssembly/WASI/phases +[filesystem]: https://github.com/WebAssembly/WASI/phases +[wasi-command-line]: https://github.com/WebAssembly/WASI/phases +[clocks]: https://github.com/WebAssembly/WASI/phases +[random]: https://github.com/WebAssembly/WASI/phases +[misc]: https://github.com/WebAssembly/WASI/phases +[wasi-crypto]: https://github.com/WebAssembly/WASI-crypto +[wasi-proxy-wasm]: https://github.com/WebAssembly/WASI diff --git a/proposals/random/phases/README.md b/proposals/random/phases/README.md index 86f5fb4ba..06a515526 100644 --- a/proposals/random/phases/README.md +++ b/proposals/random/phases/README.md @@ -1,6 +1,17 @@ -# WASI development process +# WASI's ephemeral/snapshot/old Process -## WASI uses a 3-phase process: +For the standardization process, WASI overall uses a [process] +modeled after the WebAssembly CG's phased process. + +For development of features in Phase 2 and later of that process, WASI +has a ephemeral/snapshot/old process, which is designed to allow +for a balance between the need for stability to allow people to build +compatible implementations, libraries, and tools and gain implementation +experience, and the need for proposals to evolve. + +[phases process]: https://github.com/WebAssembly/WASI/blob/master/phases/README.md + +## The ephemeral/snapshot/old Phases - [`ephemeral`](ephemeral): The development staging area. New API proposals API-changing fixes to existing APIs should be submitted @@ -37,25 +48,3 @@ versions, the old API modules are moved to the `old` directory. When possible, `old` APIs may be accompanied by polyfill modules which implement their API in terms of newer versions of the API. - -## Rationale - -### Relationship to the CG's phases - -When WASI becomes more mature, such that we have an established base -and we're adding incremental functionality to it, we may want to adopt -a process like [the CG's phases]. However, right now, everything in -WASI is undergoing changes, so we have a greater need to iterate with -flexibility. - -### Relationship to standards - -WASI should eventually become a standard at the level of WebAssembly -itself. Right now, it needs a lot of work before it's ready. The -`snapshot` tree is meant to serve a practical purpose for people who -want to work with APIs today, with the understanding that everything -is still evolving. It's not meant as a replacement for proper -standardization, which will happen once the overall API is more -mature. - -[the CG's phases]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md From 4caed962fc3356691632aa733211f8277a836042 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Apr 2020 07:56:34 -0700 Subject: [PATCH 0630/1772] Start moving WASI to a CG-style phases process. (#252) Adapt the WebAssembly CG's phases process for WASI, and make an initial mapping of current WASI proposals to phases within this process. This is quite rough at this time, and not everything fits in quite yet, and we can adjust things. This is a first step, and we'll work for greater harmonization as we proceed. --- proposals/filesystem/docs/Process.md | 37 ++++++++++++++++ proposals/filesystem/docs/Proposals.md | 59 ++++++++++++++++++++++++++ proposals/filesystem/phases/README.md | 37 ++++++---------- 3 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 proposals/filesystem/docs/Process.md create mode 100644 proposals/filesystem/docs/Proposals.md diff --git a/proposals/filesystem/docs/Process.md b/proposals/filesystem/docs/Process.md new file mode 100644 index 000000000..3b4affc3c --- /dev/null +++ b/proposals/filesystem/docs/Process.md @@ -0,0 +1,37 @@ +# WASI Standardization Process + +WASI follows the [WebAssembly CG Phases process], with the following adaptations: + + - Entry into Stage 2 requires [witx] specifications. + + - Starting in Stage 2, proposals may follow WASI's [ephemeral/snapshot/old] process + to provide a balance between the need for stability so that toolchains and engines + can sync up, and the need for evolution. + + - The Phase 4's entry requirements for "Two or more Web VMs implement the feature", + "At least one toolchain implements the feature", and "The formalization and the + reference interpreter are usually updated (though these two can be done as part + of step 3 at the Working Group chair's discretion)." are waived. + + In their place, as an additional entry requirement into Phase 2, champion(s) must + include a set of entry criteria into Phase 4 in their proposal, which the Subgroup + will vote on as part of Phase 2 approval. + + Phase 4 criteria will vary depending on the API and its expected use cases, + but may include things like multiple independent production implementations, + implementations on multiple host platforms, polyfill implementations, and + bindings in toolchains and libraries. Note that, portability requirements may + vary between proposals, as not all features will necessarily make sense in all + host environments. + + - The specific process in Phases 4 and 5 will be determined when we have a + proposal ready for them. + + - Requirements around the reference interpreter don't apply. + + - WASI proposals don't require formal notation. Formal notation may be used in the + documentation of a feature, but it isn't expected to be practical for all APIs. + +[WebAssembly CG Phases process]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md +[witx]: https://github.com/WebAssembly/WASI/blob/master/docs/witx.md +[ephemeral/snapshot/old process]: https://github.com/WebAssembly/WASI/blob/master/phases/README.md diff --git a/proposals/filesystem/docs/Proposals.md b/proposals/filesystem/docs/Proposals.md new file mode 100644 index 000000000..5ba7fefd3 --- /dev/null +++ b/proposals/filesystem/docs/Proposals.md @@ -0,0 +1,59 @@ +# WASI proposals + +This page is under construction. The intent is to follow the CG's +[proposals page], but adapted for [WASI]. Some of the proposals predate our +adoption of this process and so don't fit exactly into the defined phases, +however our intention is to align them going forward. + +[WASI]: https://github.com/WebAssembly/WASI +[proposals page]: https://github.com/WebAssembly/proposals/blob/master/README.md + +## Active proposals + +Proposals follow [this process document](https://github.com/WebAssembly/WASI/blob/master/docs/Process.md). + +### Phase 4 - Standardize the Feature (WG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | + +### Phase 3 - Implementation Phase (CG + WG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | + +### Phase 2 - Proposed Spec Text Available (CG + WG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | +| [I/O][wasi-io] | Dan Gohman | +| [Filesystem][wasi-filesystem] | Dan Gohman | +| [Command-Line][wasi-command-line] | Dan Gohman | +| [Clocks][wasi-clocks] | Dan Gohman | +| [Random][wasi-random] | Dan Gohman | +| [Misc][wasi-misc] | Dan Gohman | + +### Phase 1 - Feature Proposal (CG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | +| [Crypto][wasi-crypto] | Frank Denis and Daiki Ueno | + +### Phase 0 - Pre-Proposal (CG) + +| Proposal | Champion | +| ------------------------------------------------------------------------------ | -------------------------------------- | +| [proxy-wasm][wasi-proxy-wasm] | Piotr Sikora | + +### Contributing new proposals + +Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. + +[wasi-io]: https://github.com/WebAssembly/WASI/phases +[filesystem]: https://github.com/WebAssembly/WASI/phases +[wasi-command-line]: https://github.com/WebAssembly/WASI/phases +[clocks]: https://github.com/WebAssembly/WASI/phases +[random]: https://github.com/WebAssembly/WASI/phases +[misc]: https://github.com/WebAssembly/WASI/phases +[wasi-crypto]: https://github.com/WebAssembly/WASI-crypto +[wasi-proxy-wasm]: https://github.com/WebAssembly/WASI diff --git a/proposals/filesystem/phases/README.md b/proposals/filesystem/phases/README.md index 86f5fb4ba..06a515526 100644 --- a/proposals/filesystem/phases/README.md +++ b/proposals/filesystem/phases/README.md @@ -1,6 +1,17 @@ -# WASI development process +# WASI's ephemeral/snapshot/old Process -## WASI uses a 3-phase process: +For the standardization process, WASI overall uses a [process] +modeled after the WebAssembly CG's phased process. + +For development of features in Phase 2 and later of that process, WASI +has a ephemeral/snapshot/old process, which is designed to allow +for a balance between the need for stability to allow people to build +compatible implementations, libraries, and tools and gain implementation +experience, and the need for proposals to evolve. + +[phases process]: https://github.com/WebAssembly/WASI/blob/master/phases/README.md + +## The ephemeral/snapshot/old Phases - [`ephemeral`](ephemeral): The development staging area. New API proposals API-changing fixes to existing APIs should be submitted @@ -37,25 +48,3 @@ versions, the old API modules are moved to the `old` directory. When possible, `old` APIs may be accompanied by polyfill modules which implement their API in terms of newer versions of the API. - -## Rationale - -### Relationship to the CG's phases - -When WASI becomes more mature, such that we have an established base -and we're adding incremental functionality to it, we may want to adopt -a process like [the CG's phases]. However, right now, everything in -WASI is undergoing changes, so we have a greater need to iterate with -flexibility. - -### Relationship to standards - -WASI should eventually become a standard at the level of WebAssembly -itself. Right now, it needs a lot of work before it's ready. The -`snapshot` tree is meant to serve a practical purpose for people who -want to work with APIs today, with the understanding that everything -is still evolving. It's not meant as a replacement for proper -standardization, which will happen once the overall API is more -mature. - -[the CG's phases]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md From 5a677b3db9ab6ea0ba3daf30766a18dbcf89da10 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 20 Apr 2020 15:51:57 -0700 Subject: [PATCH 0631/1772] Describe a primitive reactor ABI. (#256) * Describe a primitive reactor ABI. This adds a new reactor ABI, indicated by exporting the function "_activate". For now, a reactor is just a module which doesn't have a lifetime scoped by a "_start" or "main" function, though it may evolve to include other semantics in the future. * Mention that command and reactor kinds are mutually exclusive. * Rename `_activate` to `_initialize`. --- proposals/clocks/design/application-abi.md | 31 ++++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/proposals/clocks/design/application-abi.md b/proposals/clocks/design/application-abi.md index b3156081d..1b3f82b31 100644 --- a/proposals/clocks/design/application-abi.md +++ b/proposals/clocks/design/application-abi.md @@ -12,20 +12,29 @@ include. Current Unstable ABI -------------------- -The current WASI unstable ABI specifies only two exports from a WASI -application: +There are two kinds of modules: -- `_start` - the program entry point -- `memory` - linear memory used by the program + - A *command* exports a function named `_start`, with no arguments and no return + values. Environments shall call this function once, after instantiating the + module and all of its dependencies. After this function exits, the instance + is considered terminated and no further use of any of its exports should be + permitted. -The `_start` export must be WebAssembly function and will be used as the program -entry point. This is the default name used by `lld` when linking WebAssembly -modules. The embedder is expected to call this function once the module is -instantiated. + - A *reactor* exports a function named `_initialize`, with no arguments and no + return values. Environments shall call this function once, after instantiating + the module and all of its dependencies. After this function exits, the instance + remains live, and its exports may be accessed. -Many of the current WASI unstable APIs require sharing of linear memory between -the application and the embedder. In order to use any such APIs the WASI module -is expected to export its linear memory under the name `memory`. +These kinds are mutually exclusive; implementations should report an error if +asked to instantiate a module containing exports which declare it to be of +multiple kinds. + +Regardless of the kind, all programs accessing WASI APIs also export a linear +memory with the name `memory`. Pointers in WASI API calls are relative to this +memory's index space. + +In the future, as the underlying WebAssembly platform offers more features, we +we hope to eliminate the requirement to export all of linear memory. Planned Stable ABI ------------------ From d5ed51bc8cfd70157d2920a5e69c697b44df8059 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 20 Apr 2020 15:51:57 -0700 Subject: [PATCH 0632/1772] Describe a primitive reactor ABI. (#256) * Describe a primitive reactor ABI. This adds a new reactor ABI, indicated by exporting the function "_activate". For now, a reactor is just a module which doesn't have a lifetime scoped by a "_start" or "main" function, though it may evolve to include other semantics in the future. * Mention that command and reactor kinds are mutually exclusive. * Rename `_activate` to `_initialize`. --- proposals/random/design/application-abi.md | 31 ++++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/proposals/random/design/application-abi.md b/proposals/random/design/application-abi.md index b3156081d..1b3f82b31 100644 --- a/proposals/random/design/application-abi.md +++ b/proposals/random/design/application-abi.md @@ -12,20 +12,29 @@ include. Current Unstable ABI -------------------- -The current WASI unstable ABI specifies only two exports from a WASI -application: +There are two kinds of modules: -- `_start` - the program entry point -- `memory` - linear memory used by the program + - A *command* exports a function named `_start`, with no arguments and no return + values. Environments shall call this function once, after instantiating the + module and all of its dependencies. After this function exits, the instance + is considered terminated and no further use of any of its exports should be + permitted. -The `_start` export must be WebAssembly function and will be used as the program -entry point. This is the default name used by `lld` when linking WebAssembly -modules. The embedder is expected to call this function once the module is -instantiated. + - A *reactor* exports a function named `_initialize`, with no arguments and no + return values. Environments shall call this function once, after instantiating + the module and all of its dependencies. After this function exits, the instance + remains live, and its exports may be accessed. -Many of the current WASI unstable APIs require sharing of linear memory between -the application and the embedder. In order to use any such APIs the WASI module -is expected to export its linear memory under the name `memory`. +These kinds are mutually exclusive; implementations should report an error if +asked to instantiate a module containing exports which declare it to be of +multiple kinds. + +Regardless of the kind, all programs accessing WASI APIs also export a linear +memory with the name `memory`. Pointers in WASI API calls are relative to this +memory's index space. + +In the future, as the underlying WebAssembly platform offers more features, we +we hope to eliminate the requirement to export all of linear memory. Planned Stable ABI ------------------ From 8f6b06187b4ca39888947d71337261ff891141e3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 20 Apr 2020 15:51:57 -0700 Subject: [PATCH 0633/1772] Describe a primitive reactor ABI. (#256) * Describe a primitive reactor ABI. This adds a new reactor ABI, indicated by exporting the function "_activate". For now, a reactor is just a module which doesn't have a lifetime scoped by a "_start" or "main" function, though it may evolve to include other semantics in the future. * Mention that command and reactor kinds are mutually exclusive. * Rename `_activate` to `_initialize`. --- .../filesystem/design/application-abi.md | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/proposals/filesystem/design/application-abi.md b/proposals/filesystem/design/application-abi.md index b3156081d..1b3f82b31 100644 --- a/proposals/filesystem/design/application-abi.md +++ b/proposals/filesystem/design/application-abi.md @@ -12,20 +12,29 @@ include. Current Unstable ABI -------------------- -The current WASI unstable ABI specifies only two exports from a WASI -application: +There are two kinds of modules: -- `_start` - the program entry point -- `memory` - linear memory used by the program + - A *command* exports a function named `_start`, with no arguments and no return + values. Environments shall call this function once, after instantiating the + module and all of its dependencies. After this function exits, the instance + is considered terminated and no further use of any of its exports should be + permitted. -The `_start` export must be WebAssembly function and will be used as the program -entry point. This is the default name used by `lld` when linking WebAssembly -modules. The embedder is expected to call this function once the module is -instantiated. + - A *reactor* exports a function named `_initialize`, with no arguments and no + return values. Environments shall call this function once, after instantiating + the module and all of its dependencies. After this function exits, the instance + remains live, and its exports may be accessed. -Many of the current WASI unstable APIs require sharing of linear memory between -the application and the embedder. In order to use any such APIs the WASI module -is expected to export its linear memory under the name `memory`. +These kinds are mutually exclusive; implementations should report an error if +asked to instantiate a module containing exports which declare it to be of +multiple kinds. + +Regardless of the kind, all programs accessing WASI APIs also export a linear +memory with the name `memory`. Pointers in WASI API calls are relative to this +memory's index space. + +In the future, as the underlying WebAssembly platform offers more features, we +we hope to eliminate the requirement to export all of linear memory. Planned Stable ABI ------------------ From 1701c4a478e461fe69b5389a7286c6b288969ded Mon Sep 17 00:00:00 2001 From: Benjamin Brittain Date: Fri, 24 Apr 2020 17:19:31 -0700 Subject: [PATCH 0634/1772] Update witx.md (#263) clarify .witx is not going away --- proposals/clocks/docs/witx.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/clocks/docs/witx.md b/proposals/clocks/docs/witx.md index db267992f..db5b5a400 100644 --- a/proposals/clocks/docs/witx.md +++ b/proposals/clocks/docs/witx.md @@ -17,10 +17,10 @@ full interface types specification, or the use of the interface types custom sections. We expect that eventually we will transition to using the full interface -types specification. Until then, the goals here are to remain aligned with -interface types and other relevant WebAssembly standards and proposals -wherever practical, and to be an input into the design process of interface -types. +types specification, with `witx` having minimal additional features. Until then, +the goals here are to remain aligned with interface types and other relevant +WebAssembly standards and proposals wherever practical, and to be an input +into the design process of interface types. [module types]: https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md [interface types]: https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md From 6ac4a1816f78969826043ab81c53aa31d3c91503 Mon Sep 17 00:00:00 2001 From: Benjamin Brittain Date: Fri, 24 Apr 2020 17:19:31 -0700 Subject: [PATCH 0635/1772] Update witx.md (#263) clarify .witx is not going away --- proposals/random/docs/witx.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/random/docs/witx.md b/proposals/random/docs/witx.md index db267992f..db5b5a400 100644 --- a/proposals/random/docs/witx.md +++ b/proposals/random/docs/witx.md @@ -17,10 +17,10 @@ full interface types specification, or the use of the interface types custom sections. We expect that eventually we will transition to using the full interface -types specification. Until then, the goals here are to remain aligned with -interface types and other relevant WebAssembly standards and proposals -wherever practical, and to be an input into the design process of interface -types. +types specification, with `witx` having minimal additional features. Until then, +the goals here are to remain aligned with interface types and other relevant +WebAssembly standards and proposals wherever practical, and to be an input +into the design process of interface types. [module types]: https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md [interface types]: https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md From 1a6b5f8d6cfb0893a739adf8062dcc7d5b82e21e Mon Sep 17 00:00:00 2001 From: Benjamin Brittain Date: Fri, 24 Apr 2020 17:19:31 -0700 Subject: [PATCH 0636/1772] Update witx.md (#263) clarify .witx is not going away --- proposals/filesystem/docs/witx.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/filesystem/docs/witx.md b/proposals/filesystem/docs/witx.md index db267992f..db5b5a400 100644 --- a/proposals/filesystem/docs/witx.md +++ b/proposals/filesystem/docs/witx.md @@ -17,10 +17,10 @@ full interface types specification, or the use of the interface types custom sections. We expect that eventually we will transition to using the full interface -types specification. Until then, the goals here are to remain aligned with -interface types and other relevant WebAssembly standards and proposals -wherever practical, and to be an input into the design process of interface -types. +types specification, with `witx` having minimal additional features. Until then, +the goals here are to remain aligned with interface types and other relevant +WebAssembly standards and proposals wherever practical, and to be an input +into the design process of interface types. [module types]: https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md [interface types]: https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md From e94487929f602381d17ef88126875be2ce41f42c Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Sat, 2 May 2020 00:01:48 -0700 Subject: [PATCH 0637/1772] Added sizes and alignments to WASI docs (#268) * Added sizes and alignments to WASI docs * Fixed formatting * Made requested changes * Fixed whitespace issues * Fixed up whitespace one last time --- proposals/clocks/phases/ephemeral/docs.md | 274 ++++ .../clocks/phases/old/snapshot_0/docs.md | 266 ++++ proposals/clocks/phases/snapshot/docs.html | 1279 +++++++++++++++++ proposals/clocks/phases/snapshot/docs.md | 264 ++++ proposals/clocks/tools/witx/src/docs/ast.rs | 45 +- 5 files changed, 2123 insertions(+), 5 deletions(-) create mode 100644 proposals/clocks/phases/snapshot/docs.html diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index c645a7452..3ddc5ad79 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -4,15 +4,31 @@ An array size. Note: This is similar to `size_t` in POSIX. +Size: 4 + +Alignment: 4 + ## `filesize`: `u64` Non-negative file size or length of a region within a file. +Size: 8 + +Alignment: 8 + ## `timestamp`: `u64` Timestamp in nanoseconds. +Size: 8 + +Alignment: 8 + ## `clockid`: Enum(`u32`) Identifiers for clocks. +Size: 4 + +Alignment: 4 + ### Variants - `realtime` The clock measuring real time. Time value zero corresponds with @@ -30,6 +46,10 @@ Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided merely for alignment with POSIX. +Size: 2 + +Alignment: 2 + ### Variants - `success` No error occurred. System call completed successfully. @@ -265,6 +285,10 @@ Extension: Capabilities insufficient. ## `rights`: Flags(`u64`) File descriptor rights, determining which actions may be performed. +Size: 8 + +Alignment: 8 + ### Flags - `fd_datasync` The right to invoke `fd_datasync`. @@ -374,37 +398,73 @@ The right to invoke `sock_shutdown`. ## `fd` A file descriptor handle. +Size: 4 + +Alignment: 4 + ### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `Pointer` The address of the buffer to be filled. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be filled. +Offset: 4 + ## `ciovec`: Struct A region of memory for scatter/gather writes. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `ConstPointer` The address of the buffer to be written. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be written. +Offset: 4 + ## `iovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `ciovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `filedelta`: `s64` Relative offset within a file. +Size: 8 + +Alignment: 8 + ## `whence`: Enum(`u8`) The position relative to which to set the offset of the file descriptor. +Size: 1 + +Alignment: 1 + ### Variants - `set` Seek relative to start-of-file. @@ -418,6 +478,10 @@ Seek relative to end-of-file. ## `dircookie`: Int(`u64`) A reference to the offset of a directory entry. +Size: 8 + +Alignment: 8 + ### Consts - `start` In an `fd_readdir` call, this value signifies the start of the directory. @@ -425,12 +489,24 @@ In an `fd_readdir` call, this value signifies the start of the directory. ## `dirnamlen`: `u32` The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). +Size: 4 + +Alignment: 4 + ## `inode`: `u64` File serial number that is unique within its file system. +Size: 8 + +Alignment: 8 + ## `filetype`: Enum(`u8`) The type of a file descriptor or file. +Size: 1 + +Alignment: 1 + ### Variants - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -462,22 +538,38 @@ The file descriptor or file refers to a FIFO. ## `dirent`: Struct A directory entry. +Size: 24 + +Alignment: 8 + ### Struct members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. +Offset: 0 + - `d_ino`: [`inode`](#inode) The serial number of the file referred to by this directory entry. +Offset: 8 + - `d_namlen`: [`dirnamlen`](#dirnamlen) The length of the name of the directory entry. +Offset: 16 + - `d_type`: [`filetype`](#filetype) The type of the file referred to by this directory entry. +Offset: 20 + ## `advice`: Enum(`u8`) File or memory access pattern advisory information. +Size: 1 + +Alignment: 1 + ### Variants - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -500,6 +592,10 @@ The application expects to access the specified data once and then not reuse it ## `fdflags`: Flags(`u16`) File descriptor flags. +Size: 2 + +Alignment: 2 + ### Flags - `append` Append mode: Data written to the file is always appended to the file's end. @@ -521,27 +617,47 @@ may also synchronously update the file's metadata. ## `fdstat`: Struct File descriptor attributes. +Size: 24 + +Alignment: 8 + ### Struct members - `fs_filetype`: [`filetype`](#filetype) File type. +Offset: 0 + - `fs_flags`: [`fdflags`](#fdflags) File descriptor flags. +Offset: 2 + - `fs_rights_base`: [`rights`](#rights) Rights that apply to this file descriptor. +Offset: 8 + - `fs_rights_inheriting`: [`rights`](#rights) Maximum set of rights that may be installed on new file descriptors that are created through this file descriptor, e.g., through `path_open`. +Offset: 16 + ## `device`: `u64` Identifier for a device containing a file system. Can be used in combination with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. +Size: 8 + +Alignment: 8 + ## `fstflags`: Flags(`u16`) Which file time attributes to adjust. +Size: 2 + +Alignment: 2 + ### Flags - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -558,6 +674,10 @@ Adjust the last data modification timestamp to the time of clock [`clockid::real ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. +Size: 4 + +Alignment: 4 + ### Flags - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. @@ -565,6 +685,10 @@ As long as the resolved path corresponds to a symbolic link, it is expanded. ## `oflags`: Flags(`u16`) Open flags used by `path_open`. +Size: 2 + +Alignment: 2 + ### Flags - `create` Create file if it does not exist. @@ -581,11 +705,19 @@ Truncate file to size 0. ## `linkcount`: `u64` Number of hard links to an inode. +Size: 8 + +Alignment: 8 + ## `permissions`: Flags(`u8`) File permissions. This represents the permissions associated with a file in a filesystem, and don't fully reflect all the conditions which determine whether a given WASI program can access the file. +Size: 1 + +Alignment: 1 + ### Flags - `read` For files, permission to read the file. @@ -614,41 +746,71 @@ to other "users". ## `filestat`: Struct File attributes. +Size: 64 + +Alignment: 8 + ### Struct members - `dev`: [`device`](#device) Device ID of device containing the file. +Offset: 0 + - `ino`: [`inode`](#inode) File serial number. +Offset: 8 + - `filetype`: [`filetype`](#filetype) File type. +Offset: 16 + - `permissions`: [`permissions`](#permissions) File permissions. +Offset: 17 + - `nlink`: [`linkcount`](#linkcount) Number of hard links to the file. +Offset: 24 + - `size`: [`filesize`](#filesize) For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. +Offset: 32 + - `atim`: [`timestamp`](#timestamp) Last data access timestamp. +Offset: 40 + - `mtim`: [`timestamp`](#timestamp) Last data modification timestamp. +Offset: 48 + - `ctim`: [`timestamp`](#timestamp) Last file status change timestamp. +Offset: 56 + ## `userdata`: `u64` User-provided value that may be attached to objects that is retained when extracted from the implementation. +Size: 8 + +Alignment: 8 + ## `eventtype`: Enum(`u8`) Type of a subscription to an event or its occurrence. +Size: 1 + +Alignment: 1 + ### Variants - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has @@ -666,6 +828,10 @@ available for writing. This event always triggers for regular files. The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 2 + +Alignment: 2 + ### Flags - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -674,16 +840,34 @@ The peer of this socket has closed or disconnected. The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 16 + +Alignment: 8 + ### Struct members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. +Offset: 0 + - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. +Offset: 8 + ## `event_u`: Union The contents of an [`event`](#event). +Size: 24 + +Alignment: 8 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 8 +- contents_size: 16 +- contents_align: 8 ### Union variants - `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) @@ -694,20 +878,34 @@ The contents of an [`event`](#event). ## `event`: Struct An event that occurred. +Size: 40 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). +Offset: 0 + - `error`: [`errno`](#errno) If non-zero, an error that occurred while processing the subscription request. +Offset: 8 + - `u`: [`event_u`](#event_u) The type of the event that occurred, and the contents of the event +Offset: 16 + ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). +Size: 2 + +Alignment: 2 + ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in @@ -719,31 +917,59 @@ current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). +Size: 32 + +Alignment: 8 + ### Struct members - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. +Offset: 0 + - `timeout`: [`timestamp`](#timestamp) The absolute or relative timestamp. +Offset: 8 + - `precision`: [`timestamp`](#timestamp) The amount of time that the implementation may wait additionally to coalesce with other events. +Offset: 16 + - `flags`: [`subclockflags`](#subclockflags) Flags specifying whether the timeout is absolute or relative +Offset: 24 + ## `subscription_fd_readwrite`: Struct The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 4 + +Alignment: 4 + ### Struct members - `fd`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. +Offset: 0 + ## `subscription_u`: Union The contents of a [`subscription`](#subscription). +Size: 40 + +Alignment: 8 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 8 +- contents_size: 32 +- contents_align: 8 ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -754,20 +980,36 @@ The contents of a [`subscription`](#subscription). ## `subscription`: Struct Subscription to an event. +Size: 48 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). +Offset: 0 + - `u`: [`subscription_u`](#subscription_u) The type of the event to which to subscribe, and the contents of the subscription. +Offset: 8 + ## `exitcode`: `u32` Exit code generated by a process when exiting. +Size: 4 + +Alignment: 4 + ## `riflags`: Flags(`u16`) Flags provided to `sock_recv`. +Size: 2 + +Alignment: 2 + ### Flags - `recv_peek` Returns the message without removing it from the socket's receive queue. @@ -778,6 +1020,10 @@ On byte-stream sockets, block until the full amount of data can be returned. ## `roflags`: Flags(`u16`) Flags returned by `sock_recv`. +Size: 2 + +Alignment: 2 + ### Flags - `recv_data_truncated` Returned by `sock_recv`: Message data has been truncated. @@ -786,9 +1032,17 @@ Returned by `sock_recv`: Message data has been truncated. Flags provided to `sock_send`. As there are currently no flags defined, it must be set to zero. +Size: 2 + +Alignment: 2 + ## `sdflags`: Flags(`u8`) Which channels on a socket to shut down. +Size: 1 + +Alignment: 1 + ### Flags - `rd` Disables further receive operations. @@ -799,6 +1053,10 @@ Disables further send operations. ## `preopentype`: Enum(`u8`) Identifiers for preopened capabilities. +Size: 1 + +Alignment: 1 + ### Variants - `dir` A pre-opened directory. @@ -806,13 +1064,29 @@ A pre-opened directory. ## `prestat_dir`: Struct The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). +Size: 4 + +Alignment: 4 + ### Struct members - `pr_name_len`: [`size`](#size) The length of the directory name for use with `fd_prestat_dir_name`. +Offset: 0 + ## `prestat`: Union Information about a pre-opened capability. +Size: 8 + +Alignment: 4 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 4 +- contents_size: 4 +- contents_align: 4 ### Union variants - `dir`: [`prestat_dir`](#prestat_dir) When type is [`preopentype::dir`](#preopentype.dir): diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index f5b8ff314..eda85fbc0 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -1,15 +1,31 @@ # Types ## `size`: `u32` +Size: 4 + +Alignment: 4 + ## `filesize`: `u64` Non-negative file size or length of a region within a file. +Size: 8 + +Alignment: 8 + ## `timestamp`: `u64` Timestamp in nanoseconds. +Size: 8 + +Alignment: 8 + ## `clockid`: Enum(`u32`) Identifiers for clocks. +Size: 4 + +Alignment: 4 + ### Variants - `realtime` The clock measuring real time. Time value zero corresponds with @@ -33,6 +49,10 @@ Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided merely for alignment with POSIX. +Size: 2 + +Alignment: 2 + ### Variants - `success` No error occurred. System call completed successfully. @@ -268,6 +288,10 @@ Extension: Capabilities insufficient. ## `rights`: Flags(`u64`) File descriptor rights, determining which actions may be performed. +Size: 8 + +Alignment: 8 + ### Flags - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). @@ -371,37 +395,73 @@ The right to invoke [`sock_shutdown`](#sock_shutdown). ## `fd` A file descriptor handle. +Size: 4 + +Alignment: 4 + ### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `Pointer` The address of the buffer to be filled. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be filled. +Offset: 4 + ## `ciovec`: Struct A region of memory for scatter/gather writes. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `ConstPointer` The address of the buffer to be written. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be written. +Offset: 4 + ## `iovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `ciovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `filedelta`: `s64` Relative offset within a file. +Size: 8 + +Alignment: 8 + ## `whence`: Enum(`u8`) The position relative to which to set the offset of the file descriptor. +Size: 1 + +Alignment: 1 + ### Variants - `cur` Seek relative to current position. @@ -415,15 +475,31 @@ Seek relative to start-of-file. ## `dircookie`: `u64` A reference to the offset of a directory entry. +Size: 8 + +Alignment: 8 + ## `dirnamlen`: `u32` The type for the $d_namlen field of $dirent. +Size: 4 + +Alignment: 4 + ## `inode`: `u64` File serial number that is unique within its file system. +Size: 8 + +Alignment: 8 + ## `filetype`: Enum(`u8`) The type of a file descriptor or file. +Size: 1 + +Alignment: 1 + ### Variants - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -452,22 +528,38 @@ The file refers to a symbolic link inode. ## `dirent`: Struct A directory entry. +Size: 24 + +Alignment: 8 + ### Struct members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. +Offset: 0 + - `d_ino`: [`inode`](#inode) The serial number of the file referred to by this directory entry. +Offset: 8 + - `d_namlen`: [`dirnamlen`](#dirnamlen) The length of the name of the directory entry. +Offset: 16 + - `d_type`: [`filetype`](#filetype) The type of the file referred to by this directory entry. +Offset: 20 + ## `advice`: Enum(`u8`) File or memory access pattern advisory information. +Size: 1 + +Alignment: 1 + ### Variants - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -490,6 +582,10 @@ The application expects to access the specified data once and then not reuse it ## `fdflags`: Flags(`u16`) File descriptor flags. +Size: 2 + +Alignment: 2 + ### Flags - `append` Append mode: Data written to the file is always appended to the file's end. @@ -511,27 +607,47 @@ may also synchronously update the file's metadata. ## `fdstat`: Struct File descriptor attributes. +Size: 24 + +Alignment: 8 + ### Struct members - `fs_filetype`: [`filetype`](#filetype) File type. +Offset: 0 + - `fs_flags`: [`fdflags`](#fdflags) File descriptor flags. +Offset: 2 + - `fs_rights_base`: [`rights`](#rights) Rights that apply to this file descriptor. +Offset: 8 + - `fs_rights_inheriting`: [`rights`](#rights) Maximum set of rights that may be installed on new file descriptors that are created through this file descriptor, e.g., through [`path_open`](#path_open). +Offset: 16 + ## `device`: `u64` Identifier for a device containing a file system. Can be used in combination with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. +Size: 8 + +Alignment: 8 + ## `fstflags`: Flags(`u16`) Which file time attributes to adjust. +Size: 2 + +Alignment: 2 + ### Flags - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -548,6 +664,10 @@ Adjust the last data modification timestamp to the time of clock [`clockid::real ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. +Size: 4 + +Alignment: 4 + ### Flags - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. @@ -555,6 +675,10 @@ As long as the resolved path corresponds to a symbolic link, it is expanded. ## `oflags`: Flags(`u16`) Open flags used by [`path_open`](#path_open). +Size: 2 + +Alignment: 2 + ### Flags - `creat` Create file if it does not exist. @@ -571,41 +695,73 @@ Truncate file to size 0. ## `linkcount`: `u32` Number of hard links to an inode. +Size: 4 + +Alignment: 4 + ## `filestat`: Struct File attributes. +Size: 56 + +Alignment: 8 + ### Struct members - `dev`: [`device`](#device) Device ID of device containing the file. +Offset: 0 + - `ino`: [`inode`](#inode) File serial number. +Offset: 8 + - `filetype`: [`filetype`](#filetype) File type. +Offset: 16 + - `nlink`: [`linkcount`](#linkcount) Number of hard links to the file. +Offset: 20 + - `size`: [`filesize`](#filesize) For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. +Offset: 24 + - `atim`: [`timestamp`](#timestamp) Last data access timestamp. +Offset: 32 + - `mtim`: [`timestamp`](#timestamp) Last data modification timestamp. +Offset: 40 + - `ctim`: [`timestamp`](#timestamp) Last file status change timestamp. +Offset: 48 + ## `userdata`: `u64` User-provided value that may be attached to objects that is retained when extracted from the implementation. +Size: 8 + +Alignment: 8 + ## `eventtype`: Enum(`u8`) Type of a subscription to an event or its occurrence. +Size: 1 + +Alignment: 1 + ### Variants - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has @@ -623,6 +779,10 @@ available for writing. This event always triggers for regular files. The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 2 + +Alignment: 2 + ### Flags - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -631,34 +791,58 @@ The peer of this socket has closed or disconnected. The contents of an $event for the [`eventtype::fd_read`](#eventtype.fd_read) and [`eventtype::fd_write`](#eventtype.fd_write) variants +Size: 16 + +Alignment: 8 + ### Struct members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. +Offset: 0 + - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. +Offset: 8 + ## `event`: Struct An event that occurred. +Size: 32 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). +Offset: 0 + - `error`: [`errno`](#errno) If non-zero, an error that occurred while processing the subscription request. +Offset: 8 + - `type`: [`eventtype`](#eventtype) The type of event that occured +Offset: 10 + - `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. +Offset: 16 + ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). +Size: 2 + +Alignment: 2 + ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in @@ -670,34 +854,64 @@ current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). +Size: 40 + +Alignment: 8 + ### Struct members - `identifier`: [`userdata`](#userdata) The user-defined unique identifier of the clock. +Offset: 0 + - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. +Offset: 8 + - `timeout`: [`timestamp`](#timestamp) The absolute or relative timestamp. +Offset: 16 + - `precision`: [`timestamp`](#timestamp) The amount of time that the implementation may wait additionally to coalesce with other events. +Offset: 24 + - `flags`: [`subclockflags`](#subclockflags) Flags specifying whether the timeout is absolute or relative +Offset: 32 + ## `subscription_fd_readwrite`: Struct The contents of a [`subscription`](#subscription) when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 4 + +Alignment: 4 + ### Struct members - `file_descriptor`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. +Offset: 0 + ## `subscription_u`: Union The contents of a [`subscription`](#subscription). +Size: 48 + +Alignment: 8 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 8 +- contents_size: 40 +- contents_align: 8 ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -708,20 +922,36 @@ The contents of a [`subscription`](#subscription). ## `subscription`: Struct Subscription to an event. +Size: 56 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). +Offset: 0 + - `u`: [`subscription_u`](#subscription_u) The type of the event to which to subscribe. +Offset: 8 + ## `exitcode`: `u32` Exit code generated by a process when exiting. +Size: 4 + +Alignment: 4 + ## `signal`: Enum(`u8`) Signal condition. +Size: 1 + +Alignment: 1 + ### Variants - `none` No signal. Note that POSIX has special semantics for `kill(pid, 0)`, @@ -850,6 +1080,10 @@ Action: Terminates the process. ## `riflags`: Flags(`u16`) Flags provided to [`sock_recv`](#sock_recv). +Size: 2 + +Alignment: 2 + ### Flags - `recv_peek` Returns the message without removing it from the socket's receive queue. @@ -860,6 +1094,10 @@ On byte-stream sockets, block until the full amount of data can be returned. ## `roflags`: Flags(`u16`) Flags returned by [`sock_recv`](#sock_recv). +Size: 2 + +Alignment: 2 + ### Flags - `recv_data_truncated` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. @@ -868,9 +1106,17 @@ Returned by [`sock_recv`](#sock_recv): Message data has been truncated. Flags provided to [`sock_send`](#sock_send). As there are currently no flags defined, it must be set to zero. +Size: 2 + +Alignment: 2 + ## `sdflags`: Flags(`u8`) Which channels on a socket to shut down. +Size: 1 + +Alignment: 1 + ### Flags - `rd` Disables further receive operations. @@ -881,6 +1127,10 @@ Disables further send operations. ## `preopentype`: Enum(`u8`) Identifiers for preopened capabilities. +Size: 1 + +Alignment: 1 + ### Variants - `dir` A pre-opened directory. @@ -888,13 +1138,29 @@ A pre-opened directory. ## `prestat_dir`: Struct The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). +Size: 4 + +Alignment: 4 + ### Struct members - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). +Offset: 0 + ## `prestat`: Union Information about a pre-opened capability. +Size: 8 + +Alignment: 4 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 4 +- contents_size: 4 +- contents_align: 4 ### Union variants - `dir`: [`prestat_dir`](#prestat_dir) diff --git a/proposals/clocks/phases/snapshot/docs.html b/proposals/clocks/phases/snapshot/docs.html new file mode 100644 index 000000000..83ea3c7d2 --- /dev/null +++ b/proposals/clocks/phases/snapshot/docs.html @@ -0,0 +1,1279 @@ +

Types

+

<a href="#size" name="size"></a> size: u32

+

Size: 4
Alignment: 4

+

<a href="#filesize" name="filesize"></a> filesize: u64

+

Non-negative file size or length of a region within a file.
Size: 8
Alignment: 8

+

<a href="#timestamp" name="timestamp"></a> timestamp: u64

+

Timestamp in nanoseconds.
Size: 8
Alignment: 8

+

<a href="#clockid" name="clockid"></a> clockid: Enum(u32)

+

Identifiers for clocks.
Size: 4
Alignment: 4

+

Variants

+
    +
  • <a href="#clockid.realtime" name="clockid.realtime"></a> realtime
    The clock measuring real time. Time value zero corresponds with
    1970-01-01T00:00:00Z.

    +
  • +
  • <a href="#clockid.monotonic" name="clockid.monotonic"></a> monotonic
    The store-wide monotonic clock, which is defined as a clock measuring
    real time, whose value cannot be adjusted and which cannot have negative
    clock jumps. The epoch of this clock is undefined. The absolute time
    value of this clock therefore has no meaning.

    +
  • +
  • <a href="#clockid.process_cputime_id" name="clockid.process_cputime_id"></a> process_cputime_id
    The CPU-time clock associated with the current process.

    +
  • +
  • <a href="#clockid.thread_cputime_id" name="clockid.thread_cputime_id"></a> thread_cputime_id
    The CPU-time clock associated with the current thread.

    +
  • +
+

<a href="#errno" name="errno"></a> errno: Enum(u16)

+

Error codes returned by functions.
Not all of these error codes are returned by the functions provided by this
API; some are used in higher-level library layers, and others are provided
merely for alignment with POSIX.
Size: 2
Alignment: 2

+

Variants

+
    +
  • <a href="#errno.success" name="errno.success"></a> success
    No error occurred. System call completed successfully.

    +
  • +
  • <a href="#errno.2big" name="errno.2big"></a> 2big
    Argument list too long.

    +
  • +
  • <a href="#errno.acces" name="errno.acces"></a> acces
    Permission denied.

    +
  • +
  • <a href="#errno.addrinuse" name="errno.addrinuse"></a> addrinuse
    Address in use.

    +
  • +
  • <a href="#errno.addrnotavail" name="errno.addrnotavail"></a> addrnotavail
    Address not available.

    +
  • +
  • <a href="#errno.afnosupport" name="errno.afnosupport"></a> afnosupport
    Address family not supported.

    +
  • +
  • <a href="#errno.again" name="errno.again"></a> again
    Resource unavailable, or operation would block.

    +
  • +
  • <a href="#errno.already" name="errno.already"></a> already
    Connection already in progress.

    +
  • +
  • <a href="#errno.badf" name="errno.badf"></a> badf
    Bad file descriptor.

    +
  • +
  • <a href="#errno.badmsg" name="errno.badmsg"></a> badmsg
    Bad message.

    +
  • +
  • <a href="#errno.busy" name="errno.busy"></a> busy
    Device or resource busy.

    +
  • +
  • <a href="#errno.canceled" name="errno.canceled"></a> canceled
    Operation canceled.

    +
  • +
  • <a href="#errno.child" name="errno.child"></a> child
    No child processes.

    +
  • +
  • <a href="#errno.connaborted" name="errno.connaborted"></a> connaborted
    Connection aborted.

    +
  • +
  • <a href="#errno.connrefused" name="errno.connrefused"></a> connrefused
    Connection refused.

    +
  • +
  • <a href="#errno.connreset" name="errno.connreset"></a> connreset
    Connection reset.

    +
  • +
  • <a href="#errno.deadlk" name="errno.deadlk"></a> deadlk
    Resource deadlock would occur.

    +
  • +
  • <a href="#errno.destaddrreq" name="errno.destaddrreq"></a> destaddrreq
    Destination address required.

    +
  • +
  • <a href="#errno.dom" name="errno.dom"></a> dom
    Mathematics argument out of domain of function.

    +
  • +
  • <a href="#errno.dquot" name="errno.dquot"></a> dquot
    Reserved.

    +
  • +
  • <a href="#errno.exist" name="errno.exist"></a> exist
    File exists.

    +
  • +
  • <a href="#errno.fault" name="errno.fault"></a> fault
    Bad address.

    +
  • +
  • <a href="#errno.fbig" name="errno.fbig"></a> fbig
    File too large.

    +
  • +
  • <a href="#errno.hostunreach" name="errno.hostunreach"></a> hostunreach
    Host is unreachable.

    +
  • +
  • <a href="#errno.idrm" name="errno.idrm"></a> idrm
    Identifier removed.

    +
  • +
  • <a href="#errno.ilseq" name="errno.ilseq"></a> ilseq
    Illegal byte sequence.

    +
  • +
  • <a href="#errno.inprogress" name="errno.inprogress"></a> inprogress
    Operation in progress.

    +
  • +
  • <a href="#errno.intr" name="errno.intr"></a> intr
    Interrupted function.

    +
  • +
  • <a href="#errno.inval" name="errno.inval"></a> inval
    Invalid argument.

    +
  • +
  • <a href="#errno.io" name="errno.io"></a> io
    I/O error.

    +
  • +
  • <a href="#errno.isconn" name="errno.isconn"></a> isconn
    Socket is connected.

    +
  • +
  • <a href="#errno.isdir" name="errno.isdir"></a> isdir
    Is a directory.

    +
  • +
  • <a href="#errno.loop" name="errno.loop"></a> loop
    Too many levels of symbolic links.

    +
  • +
  • <a href="#errno.mfile" name="errno.mfile"></a> mfile
    File descriptor value too large.

    +
  • +
  • <a href="#errno.mlink" name="errno.mlink"></a> mlink
    Too many links.

    +
  • +
  • <a href="#errno.msgsize" name="errno.msgsize"></a> msgsize
    Message too large.

    +
  • +
  • <a href="#errno.multihop" name="errno.multihop"></a> multihop
    Reserved.

    +
  • +
  • <a href="#errno.nametoolong" name="errno.nametoolong"></a> nametoolong
    Filename too long.

    +
  • +
  • <a href="#errno.netdown" name="errno.netdown"></a> netdown
    Network is down.

    +
  • +
  • <a href="#errno.netreset" name="errno.netreset"></a> netreset
    Connection aborted by network.

    +
  • +
  • <a href="#errno.netunreach" name="errno.netunreach"></a> netunreach
    Network unreachable.

    +
  • +
  • <a href="#errno.nfile" name="errno.nfile"></a> nfile
    Too many files open in system.

    +
  • +
  • <a href="#errno.nobufs" name="errno.nobufs"></a> nobufs
    No buffer space available.

    +
  • +
  • <a href="#errno.nodev" name="errno.nodev"></a> nodev
    No such device.

    +
  • +
  • <a href="#errno.noent" name="errno.noent"></a> noent
    No such file or directory.

    +
  • +
  • <a href="#errno.noexec" name="errno.noexec"></a> noexec
    Executable file format error.

    +
  • +
  • <a href="#errno.nolck" name="errno.nolck"></a> nolck
    No locks available.

    +
  • +
  • <a href="#errno.nolink" name="errno.nolink"></a> nolink
    Reserved.

    +
  • +
  • <a href="#errno.nomem" name="errno.nomem"></a> nomem
    Not enough space.

    +
  • +
  • <a href="#errno.nomsg" name="errno.nomsg"></a> nomsg
    No message of the desired type.

    +
  • +
  • <a href="#errno.noprotoopt" name="errno.noprotoopt"></a> noprotoopt
    Protocol not available.

    +
  • +
  • <a href="#errno.nospc" name="errno.nospc"></a> nospc
    No space left on device.

    +
  • +
  • <a href="#errno.nosys" name="errno.nosys"></a> nosys
    Function not supported.

    +
  • +
  • <a href="#errno.notconn" name="errno.notconn"></a> notconn
    The socket is not connected.

    +
  • +
  • <a href="#errno.notdir" name="errno.notdir"></a> notdir
    Not a directory or a symbolic link to a directory.

    +
  • +
  • <a href="#errno.notempty" name="errno.notempty"></a> notempty
    Directory not empty.

    +
  • +
  • <a href="#errno.notrecoverable" name="errno.notrecoverable"></a> notrecoverable
    State not recoverable.

    +
  • +
  • <a href="#errno.notsock" name="errno.notsock"></a> notsock
    Not a socket.

    +
  • +
  • <a href="#errno.notsup" name="errno.notsup"></a> notsup
    Not supported, or operation not supported on socket.

    +
  • +
  • <a href="#errno.notty" name="errno.notty"></a> notty
    Inappropriate I/O control operation.

    +
  • +
  • <a href="#errno.nxio" name="errno.nxio"></a> nxio
    No such device or address.

    +
  • +
  • <a href="#errno.overflow" name="errno.overflow"></a> overflow
    Value too large to be stored in data type.

    +
  • +
  • <a href="#errno.ownerdead" name="errno.ownerdead"></a> ownerdead
    Previous owner died.

    +
  • +
  • <a href="#errno.perm" name="errno.perm"></a> perm
    Operation not permitted.

    +
  • +
  • <a href="#errno.pipe" name="errno.pipe"></a> pipe
    Broken pipe.

    +
  • +
  • <a href="#errno.proto" name="errno.proto"></a> proto
    Protocol error.

    +
  • +
  • <a href="#errno.protonosupport" name="errno.protonosupport"></a> protonosupport
    Protocol not supported.

    +
  • +
  • <a href="#errno.prototype" name="errno.prototype"></a> prototype
    Protocol wrong type for socket.

    +
  • +
  • <a href="#errno.range" name="errno.range"></a> range
    Result too large.

    +
  • +
  • <a href="#errno.rofs" name="errno.rofs"></a> rofs
    Read-only file system.

    +
  • +
  • <a href="#errno.spipe" name="errno.spipe"></a> spipe
    Invalid seek.

    +
  • +
  • <a href="#errno.srch" name="errno.srch"></a> srch
    No such process.

    +
  • +
  • <a href="#errno.stale" name="errno.stale"></a> stale
    Reserved.

    +
  • +
  • <a href="#errno.timedout" name="errno.timedout"></a> timedout
    Connection timed out.

    +
  • +
  • <a href="#errno.txtbsy" name="errno.txtbsy"></a> txtbsy
    Text file busy.

    +
  • +
  • <a href="#errno.xdev" name="errno.xdev"></a> xdev
    Cross-device link.

    +
  • +
  • <a href="#errno.notcapable" name="errno.notcapable"></a> notcapable
    Extension: Capabilities insufficient.

    +
  • +
+

<a href="#rights" name="rights"></a> rights: Flags(u64)

+

File descriptor rights, determining which actions may be performed.
Size: 8
Alignment: 8

+

Flags

+
    +
  • <a href="#rights.fd_datasync" name="rights.fd_datasync"></a> fd_datasync
    The right to invoke fd_datasync.
    If path_open is set, includes the right to invoke
    path_open with fdflags::dsync.

    +
  • +
  • <a href="#rights.fd_read" name="rights.fd_read"></a> fd_read
    The right to invoke fd_read and sock_recv.
    If rights::fd_seek is set, includes the right to invoke fd_pread.

    +
  • +
  • <a href="#rights.fd_seek" name="rights.fd_seek"></a> fd_seek
    The right to invoke fd_seek. This flag implies rights::fd_tell.

    +
  • +
  • <a href="#rights.fd_fdstat_set_flags" name="rights.fd_fdstat_set_flags"></a> fd_fdstat_set_flags
    The right to invoke fd_fdstat_set_flags.

    +
  • +
  • <a href="#rights.fd_sync" name="rights.fd_sync"></a> fd_sync
    The right to invoke fd_sync.
    If path_open is set, includes the right to invoke
    path_open with fdflags::rsync and fdflags::dsync.

    +
  • +
  • <a href="#rights.fd_tell" name="rights.fd_tell"></a> fd_tell
    The right to invoke fd_seek in such a way that the file offset
    remains unaltered (i.e., whence::cur with offset zero), or to
    invoke fd_tell.

    +
  • +
  • <a href="#rights.fd_write" name="rights.fd_write"></a> fd_write
    The right to invoke fd_write and sock_send.
    If rights::fd_seek is set, includes the right to invoke fd_pwrite.

    +
  • +
  • <a href="#rights.fd_advise" name="rights.fd_advise"></a> fd_advise
    The right to invoke fd_advise.

    +
  • +
  • <a href="#rights.fd_allocate" name="rights.fd_allocate"></a> fd_allocate
    The right to invoke fd_allocate.

    +
  • +
  • <a href="#rights.path_create_directory" name="rights.path_create_directory"></a> path_create_directory
    The right to invoke path_create_directory.

    +
  • +
  • <a href="#rights.path_create_file" name="rights.path_create_file"></a> path_create_file
    If path_open is set, the right to invoke path_open with oflags::creat.

    +
  • +
  • <a href="#rights.path_link_source" name="rights.path_link_source"></a> path_link_source
    The right to invoke path_link with the file descriptor as the
    source directory.

    +
  • +
  • <a href="#rights.path_link_target" name="rights.path_link_target"></a> path_link_target
    The right to invoke path_link with the file descriptor as the
    target directory.

    +
  • +
  • <a href="#rights.path_open" name="rights.path_open"></a> path_open
    The right to invoke path_open.

    +
  • +
  • <a href="#rights.fd_readdir" name="rights.fd_readdir"></a> fd_readdir
    The right to invoke fd_readdir.

    +
  • +
  • <a href="#rights.path_readlink" name="rights.path_readlink"></a> path_readlink
    The right to invoke path_readlink.

    +
  • +
  • <a href="#rights.path_rename_source" name="rights.path_rename_source"></a> path_rename_source
    The right to invoke path_rename with the file descriptor as the source directory.

    +
  • +
  • <a href="#rights.path_rename_target" name="rights.path_rename_target"></a> path_rename_target
    The right to invoke path_rename with the file descriptor as the target directory.

    +
  • +
  • <a href="#rights.path_filestat_get" name="rights.path_filestat_get"></a> path_filestat_get
    The right to invoke path_filestat_get.

    +
  • +
  • <a href="#rights.path_filestat_set_size" name="rights.path_filestat_set_size"></a> path_filestat_set_size
    The right to change a file's size (there is no path_filestat_set_size).
    If path_open is set, includes the right to invoke path_open with oflags::trunc.

    +
  • +
  • <a href="#rights.path_filestat_set_times" name="rights.path_filestat_set_times"></a> path_filestat_set_times
    The right to invoke path_filestat_set_times.

    +
  • +
  • <a href="#rights.fd_filestat_get" name="rights.fd_filestat_get"></a> fd_filestat_get
    The right to invoke fd_filestat_get.

    +
  • +
  • <a href="#rights.fd_filestat_set_size" name="rights.fd_filestat_set_size"></a> fd_filestat_set_size
    The right to invoke fd_filestat_set_size.

    +
  • +
  • <a href="#rights.fd_filestat_set_times" name="rights.fd_filestat_set_times"></a> fd_filestat_set_times
    The right to invoke fd_filestat_set_times.

    +
  • +
  • <a href="#rights.path_symlink" name="rights.path_symlink"></a> path_symlink
    The right to invoke path_symlink.

    +
  • +
  • <a href="#rights.path_remove_directory" name="rights.path_remove_directory"></a> path_remove_directory
    The right to invoke path_remove_directory.

    +
  • +
  • <a href="#rights.path_unlink_file" name="rights.path_unlink_file"></a> path_unlink_file
    The right to invoke path_unlink_file.

    +
  • +
  • <a href="#rights.poll_fd_readwrite" name="rights.poll_fd_readwrite"></a> poll_fd_readwrite
    If rights::fd_read is set, includes the right to invoke poll_oneoff to subscribe to eventtype::fd_read.
    If rights::fd_write is set, includes the right to invoke poll_oneoff to subscribe to eventtype::fd_write.

    +
  • +
  • <a href="#rights.sock_shutdown" name="rights.sock_shutdown"></a> sock_shutdown
    The right to invoke sock_shutdown.

    +
  • +
+

<a href="#fd" name="fd"></a> fd

+

A file descriptor handle.
Size: 4
Alignment: 4

+

Supertypes

+

<a href="#iovec" name="iovec"></a> iovec: Struct

+

A region of memory for scatter/gather reads.
Size: 8
Alignment: 4

+

Struct members

+
    +
  • <a href="#iovec.buf" name="iovec.buf"></a> buf: Pointer<u8>
    The address of the buffer to be filled.
    Offset: 0
  • +
  • <a href="#iovec.buf_len" name="iovec.buf_len"></a> buf_len: size
    The length of the buffer to be filled.
    Offset: 4

    <a href="#ciovec" name="ciovec"></a> ciovec: Struct

    +A region of memory for scatter/gather writes.
    Size: 8
    Alignment: 4

    Struct members

    +
  • +
  • <a href="#ciovec.buf" name="ciovec.buf"></a> buf: ConstPointer<u8>
    The address of the buffer to be written.
    Offset: 0
  • +
  • <a href="#ciovec.buf_len" name="ciovec.buf_len"></a> buf_len: size
    The length of the buffer to be written.
    Offset: 4

    <a href="#iovec_array" name="iovec_array"></a> iovec_array: Array<iovec>

    +Size: 8
    Alignment: 4

    <a href="#ciovec_array" name="ciovec_array"></a> ciovec_array: Array<ciovec>

    +Size: 8
    Alignment: 4

    <a href="#filedelta" name="filedelta"></a> filedelta: s64

    +Relative offset within a file.
    Size: 8
    Alignment: 8

    <a href="#whence" name="whence"></a> whence: Enum(u8)

    +The position relative to which to set the offset of the file descriptor.
    Size: 1
    Alignment: 1

    Variants

    +
  • +
  • <a href="#whence.set" name="whence.set"></a> set
    Seek relative to start-of-file.

    +
  • +
  • <a href="#whence.cur" name="whence.cur"></a> cur
    Seek relative to current position.

    +
  • +
  • <a href="#whence.end" name="whence.end"></a> end
    Seek relative to end-of-file.

    +
  • +
+

<a href="#dircookie" name="dircookie"></a> dircookie: u64

+

A reference to the offset of a directory entry.

+

The value 0 signifies the start of the directory.
Size: 8
Alignment: 8

+

<a href="#dirnamlen" name="dirnamlen"></a> dirnamlen: u32

+

The type for the $d_namlen field of $dirent.
Size: 4
Alignment: 4

+

<a href="#inode" name="inode"></a> inode: u64

+

File serial number that is unique within its file system.
Size: 8
Alignment: 8

+

<a href="#filetype" name="filetype"></a> filetype: Enum(u8)

+

The type of a file descriptor or file.
Size: 1
Alignment: 1

+

Variants

+
    +
  • <a href="#filetype.unknown" name="filetype.unknown"></a> unknown
    The type of the file descriptor or file is unknown or is different from any of the other types specified.

    +
  • +
  • <a href="#filetype.block_device" name="filetype.block_device"></a> block_device
    The file descriptor or file refers to a block device inode.

    +
  • +
  • <a href="#filetype.character_device" name="filetype.character_device"></a> character_device
    The file descriptor or file refers to a character device inode.

    +
  • +
  • <a href="#filetype.directory" name="filetype.directory"></a> directory
    The file descriptor or file refers to a directory inode.

    +
  • +
  • <a href="#filetype.regular_file" name="filetype.regular_file"></a> regular_file
    The file descriptor or file refers to a regular file inode.

    +
  • +
  • <a href="#filetype.socket_dgram" name="filetype.socket_dgram"></a> socket_dgram
    The file descriptor or file refers to a datagram socket.

    +
  • +
  • <a href="#filetype.socket_stream" name="filetype.socket_stream"></a> socket_stream
    The file descriptor or file refers to a byte-stream socket.

    +
  • +
  • <a href="#filetype.symbolic_link" name="filetype.symbolic_link"></a> symbolic_link
    The file refers to a symbolic link inode.

    +
  • +
+

<a href="#dirent" name="dirent"></a> dirent: Struct

+

A directory entry.
Size: 24
Alignment: 8

+

Struct members

+
    +
  • <a href="#dirent.d_next" name="dirent.d_next"></a> d_next: dircookie
    The offset of the next directory entry stored in this directory.
    Offset: 0
  • +
  • <a href="#dirent.d_ino" name="dirent.d_ino"></a> d_ino: inode
    The serial number of the file referred to by this directory entry.
    Offset: 8
  • +
  • <a href="#dirent.d_namlen" name="dirent.d_namlen"></a> d_namlen: dirnamlen
    The length of the name of the directory entry.
    Offset: 16
  • +
  • <a href="#dirent.d_type" name="dirent.d_type"></a> d_type: filetype
    The type of the file referred to by this directory entry.
    Offset: 20

    <a href="#advice" name="advice"></a> advice: Enum(u8)

    +File or memory access pattern advisory information.
    Size: 1
    Alignment: 1

    Variants

    +
  • +
  • <a href="#advice.normal" name="advice.normal"></a> normal
    The application has no advice to give on its behavior with respect to the specified data.

    +
  • +
  • <a href="#advice.sequential" name="advice.sequential"></a> sequential
    The application expects to access the specified data sequentially from lower offsets to higher offsets.

    +
  • +
  • <a href="#advice.random" name="advice.random"></a> random
    The application expects to access the specified data in a random order.

    +
  • +
  • <a href="#advice.willneed" name="advice.willneed"></a> willneed
    The application expects to access the specified data in the near future.

    +
  • +
  • <a href="#advice.dontneed" name="advice.dontneed"></a> dontneed
    The application expects that it will not access the specified data in the near future.

    +
  • +
  • <a href="#advice.noreuse" name="advice.noreuse"></a> noreuse
    The application expects to access the specified data once and then not reuse it thereafter.

    +
  • +
+

<a href="#fdflags" name="fdflags"></a> fdflags: Flags(u16)

+

File descriptor flags.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#fdflags.append" name="fdflags.append"></a> append
    Append mode: Data written to the file is always appended to the file's end.

    +
  • +
  • <a href="#fdflags.dsync" name="fdflags.dsync"></a> dsync
    Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized.

    +
  • +
  • <a href="#fdflags.nonblock" name="fdflags.nonblock"></a> nonblock
    Non-blocking mode.

    +
  • +
  • <a href="#fdflags.rsync" name="fdflags.rsync"></a> rsync
    Synchronized read I/O operations.

    +
  • +
  • <a href="#fdflags.sync" name="fdflags.sync"></a> sync
    Write according to synchronized I/O file integrity completion. In
    addition to synchronizing the data stored in the file, the implementation
    may also synchronously update the file's metadata.

    +
  • +
+

<a href="#fdstat" name="fdstat"></a> fdstat: Struct

+

File descriptor attributes.
Size: 24
Alignment: 8

+

Struct members

+
    +
  • <a href="#fdstat.fs_filetype" name="fdstat.fs_filetype"></a> fs_filetype: filetype
    File type.
    Offset: 0
  • +
  • <a href="#fdstat.fs_flags" name="fdstat.fs_flags"></a> fs_flags: fdflags
    File descriptor flags.
    Offset: 2
  • +
  • <a href="#fdstat.fs_rights_base" name="fdstat.fs_rights_base"></a> fs_rights_base: rights
    Rights that apply to this file descriptor.
    Offset: 8
  • +
  • <a href="#fdstat.fs_rights_inheriting" name="fdstat.fs_rights_inheriting"></a> fs_rights_inheriting: rights
    Maximum set of rights that may be installed on new file descriptors that
    are created through this file descriptor, e.g., through path_open.
    Offset: 16

    <a href="#device" name="device"></a> device: u64

    +Identifier for a device containing a file system. Can be used in combination
    with inode to uniquely identify a file or directory in the filesystem.
    Size: 8
    Alignment: 8

    <a href="#fstflags" name="fstflags"></a> fstflags: Flags(u16)

    +Which file time attributes to adjust.
    Size: 2
    Alignment: 2

    Flags

    +
  • +
  • <a href="#fstflags.atim" name="fstflags.atim"></a> atim
    Adjust the last data access timestamp to the value stored in filestat::atim.

    +
  • +
  • <a href="#fstflags.atim_now" name="fstflags.atim_now"></a> atim_now
    Adjust the last data access timestamp to the time of clock clockid::realtime.

    +
  • +
  • <a href="#fstflags.mtim" name="fstflags.mtim"></a> mtim
    Adjust the last data modification timestamp to the value stored in filestat::mtim.

    +
  • +
  • <a href="#fstflags.mtim_now" name="fstflags.mtim_now"></a> mtim_now
    Adjust the last data modification timestamp to the time of clock clockid::realtime.

    +
  • +
+

<a href="#lookupflags" name="lookupflags"></a> lookupflags: Flags(u32)

+

Flags determining the method of how paths are resolved.
Size: 4
Alignment: 4

+

Flags

+
    +
  • <a href="#lookupflags.symlink_follow" name="lookupflags.symlink_follow"></a> symlink_follow
    As long as the resolved path corresponds to a symbolic link, it is expanded.
  • +
+

<a href="#oflags" name="oflags"></a> oflags: Flags(u16)

+

Open flags used by path_open.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#oflags.creat" name="oflags.creat"></a> creat
    Create file if it does not exist.

    +
  • +
  • <a href="#oflags.directory" name="oflags.directory"></a> directory
    Fail if not a directory.

    +
  • +
  • <a href="#oflags.excl" name="oflags.excl"></a> excl
    Fail if file already exists.

    +
  • +
  • <a href="#oflags.trunc" name="oflags.trunc"></a> trunc
    Truncate file to size 0.

    +
  • +
+

<a href="#linkcount" name="linkcount"></a> linkcount: u64

+

Number of hard links to an inode.
Size: 8
Alignment: 8

+

<a href="#filestat" name="filestat"></a> filestat: Struct

+

File attributes.
Size: 64
Alignment: 8

+

Struct members

+
    +
  • <a href="#filestat.dev" name="filestat.dev"></a> dev: device
    Device ID of device containing the file.
    Offset: 0
  • +
  • <a href="#filestat.ino" name="filestat.ino"></a> ino: inode
    File serial number.
    Offset: 8
  • +
  • <a href="#filestat.filetype" name="filestat.filetype"></a> filetype: filetype
    File type.
    Offset: 16
  • +
  • <a href="#filestat.nlink" name="filestat.nlink"></a> nlink: linkcount
    Number of hard links to the file.
    Offset: 24
  • +
  • <a href="#filestat.size" name="filestat.size"></a> size: filesize
    For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link.
    Offset: 32
  • +
  • <a href="#filestat.atim" name="filestat.atim"></a> atim: timestamp
    Last data access timestamp.
    Offset: 40
  • +
  • <a href="#filestat.mtim" name="filestat.mtim"></a> mtim: timestamp
    Last data modification timestamp.
    Offset: 48
  • +
  • <a href="#filestat.ctim" name="filestat.ctim"></a> ctim: timestamp
    Last file status change timestamp.
    Offset: 56

    <a href="#userdata" name="userdata"></a> userdata: u64

    +User-provided value that may be attached to objects that is retained when
    extracted from the implementation.
    Size: 8
    Alignment: 8

    <a href="#eventtype" name="eventtype"></a> eventtype: Enum(u8)

    +Type of a subscription to an event or its occurrence.
    Size: 1
    Alignment: 1

    Variants

    +
  • +
  • <a href="#eventtype.clock" name="eventtype.clock"></a> clock
    The time value of clock subscription_clock::id has
    reached timestamp subscription_clock::timeout.

    +
  • +
  • <a href="#eventtype.fd_read" name="eventtype.fd_read"></a> fd_read
    File descriptor subscription_fd_readwrite::file_descriptor has data
    available for reading. This event always triggers for regular files.

    +
  • +
  • <a href="#eventtype.fd_write" name="eventtype.fd_write"></a> fd_write
    File descriptor subscription_fd_readwrite::file_descriptor has capacity
    available for writing. This event always triggers for regular files.

    +
  • +
+

<a href="#eventrwflags" name="eventrwflags"></a> eventrwflags: Flags(u16)

+

The state of the file descriptor subscribed to with
eventtype::fd_read or eventtype::fd_write.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#eventrwflags.fd_readwrite_hangup" name="eventrwflags.fd_readwrite_hangup"></a> fd_readwrite_hangup
    The peer of this socket has closed or disconnected.
  • +
+

<a href="#event_fd_readwrite" name="event_fd_readwrite"></a> event_fd_readwrite: Struct

+

The contents of an $event when type is eventtype::fd_read or
eventtype::fd_write.
Size: 16
Alignment: 8

+

Struct members

+
    +
  • <a href="#event_fd_readwrite.nbytes" name="event_fd_readwrite.nbytes"></a> nbytes: filesize
    The number of bytes available for reading or writing.
    Offset: 0
  • +
  • <a href="#event_fd_readwrite.flags" name="event_fd_readwrite.flags"></a> flags: eventrwflags
    The state of the file descriptor.
    Offset: 8

    <a href="#event" name="event"></a> event: Struct

    +An event that occurred.
    Size: 32
    Alignment: 8

    Struct members

    +
  • +
  • <a href="#event.userdata" name="event.userdata"></a> userdata: userdata
    User-provided value that got attached to subscription::userdata.
    Offset: 0
  • +
  • <a href="#event.error" name="event.error"></a> error: errno
    If non-zero, an error that occurred while processing the subscription request.
    Offset: 8
  • +
  • <a href="#event.type" name="event.type"></a> type: eventtype
    The type of event that occured
    Offset: 10
  • +
  • <a href="#event.fd_readwrite" name="event.fd_readwrite"></a> fd_readwrite: event_fd_readwrite
    The contents of the event, if it is an eventtype::fd_read or
    eventtype::fd_write. eventtype::clock events ignore this field.
    Offset: 16

    <a href="#subclockflags" name="subclockflags"></a> subclockflags: Flags(u16)

    +Flags determining how to interpret the timestamp provided in
    subscription_clock::timeout.
    Size: 2
    Alignment: 2

    Flags

    +
  • +
  • <a href="#subclockflags.subscription_clock_abstime" name="subclockflags.subscription_clock_abstime"></a> subscription_clock_abstime
    If set, treat the timestamp provided in
    subscription_clock::timeout as an absolute timestamp of clock
    subscription_clock::id. If clear, treat the timestamp
    provided in subscription_clock::timeout relative to the
    current time value of clock subscription_clock::id.
  • +
+

<a href="#subscription_clock" name="subscription_clock"></a> subscription_clock: Struct

+

The contents of a subscription when type is eventtype::clock.
Size: 32
Alignment: 8

+

Struct members

+
    +
  • <a href="#subscription_clock.id" name="subscription_clock.id"></a> id: clockid
    The clock against which to compare the timestamp.
    Offset: 0
  • +
  • <a href="#subscription_clock.timeout" name="subscription_clock.timeout"></a> timeout: timestamp
    The absolute or relative timestamp.
    Offset: 8
  • +
  • <a href="#subscription_clock.precision" name="subscription_clock.precision"></a> precision: timestamp
    The amount of time that the implementation may wait additionally
    to coalesce with other events.
    Offset: 16
  • +
  • <a href="#subscription_clock.flags" name="subscription_clock.flags"></a> flags: subclockflags
    Flags specifying whether the timeout is absolute or relative
    Offset: 24

    <a href="#subscription_fd_readwrite" name="subscription_fd_readwrite"></a> subscription_fd_readwrite: Struct

    +The contents of a subscription when type is type is
    eventtype::fd_read or eventtype::fd_write.
    Size: 4
    Alignment: 4

    Struct members

    +
  • +
  • <a href="#subscription_fd_readwrite.file_descriptor" name="subscription_fd_readwrite.file_descriptor"></a> file_descriptor: fd
    The file descriptor on which to wait for it to become ready for reading or writing.
    Offset: 0

    <a href="#subscription_u" name="subscription_u"></a> subscription_u: Union

    +The contents of a subscription.
    Size: 40
    Alignment: 8

    Union Layout

    +
  • +
  • tag_size: 1
  • +
  • tag_align: 1
  • +
  • contents_offset: 8
  • +
  • contents_size: 32
  • +
  • contents_align: 8

    Union variants

    +
  • +
  • <a href="#subscription_u.clock" name="subscription_u.clock"></a> clock: subscription_clock

    +
  • +
  • <a href="#subscription_u.fd_read" name="subscription_u.fd_read"></a> fd_read: subscription_fd_readwrite

    +
  • +
  • <a href="#subscription_u.fd_write" name="subscription_u.fd_write"></a> fd_write: subscription_fd_readwrite

    +
  • +
+

<a href="#subscription" name="subscription"></a> subscription: Struct

+

Subscription to an event.
Size: 48
Alignment: 8

+

Struct members

+
    +
  • <a href="#subscription.userdata" name="subscription.userdata"></a> userdata: userdata
    User-provided value that is attached to the subscription in the
    implementation and returned through event::userdata.
    Offset: 0
  • +
  • <a href="#subscription.u" name="subscription.u"></a> u: subscription_u
    The type of the event to which to subscribe, and its contents
    Offset: 8

    <a href="#exitcode" name="exitcode"></a> exitcode: u32

    +Exit code generated by a process when exiting.
    Size: 4
    Alignment: 4

    <a href="#signal" name="signal"></a> signal: Enum(u8)

    +Signal condition.
    Size: 1
    Alignment: 1

    Variants

    +
  • +
  • <a href="#signal.none" name="signal.none"></a> none
    No signal. Note that POSIX has special semantics for kill(pid, 0),
    so this value is reserved.

    +
  • +
  • <a href="#signal.hup" name="signal.hup"></a> hup
    Hangup.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.int" name="signal.int"></a> int
    Terminate interrupt signal.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.quit" name="signal.quit"></a> quit
    Terminal quit signal.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.ill" name="signal.ill"></a> ill
    Illegal instruction.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.trap" name="signal.trap"></a> trap
    Trace/breakpoint trap.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.abrt" name="signal.abrt"></a> abrt
    Process abort signal.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.bus" name="signal.bus"></a> bus
    Access to an undefined portion of a memory object.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.fpe" name="signal.fpe"></a> fpe
    Erroneous arithmetic operation.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.kill" name="signal.kill"></a> kill
    Kill.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.usr1" name="signal.usr1"></a> usr1
    User-defined signal 1.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.segv" name="signal.segv"></a> segv
    Invalid memory reference.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.usr2" name="signal.usr2"></a> usr2
    User-defined signal 2.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.pipe" name="signal.pipe"></a> pipe
    Write on a pipe with no one to read it.
    Action: Ignored.

    +
  • +
  • <a href="#signal.alrm" name="signal.alrm"></a> alrm
    Alarm clock.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.term" name="signal.term"></a> term
    Termination signal.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.chld" name="signal.chld"></a> chld
    Child process terminated, stopped, or continued.
    Action: Ignored.

    +
  • +
  • <a href="#signal.cont" name="signal.cont"></a> cont
    Continue executing, if stopped.
    Action: Continues executing, if stopped.

    +
  • +
  • <a href="#signal.stop" name="signal.stop"></a> stop
    Stop executing.
    Action: Stops executing.

    +
  • +
  • <a href="#signal.tstp" name="signal.tstp"></a> tstp
    Terminal stop signal.
    Action: Stops executing.

    +
  • +
  • <a href="#signal.ttin" name="signal.ttin"></a> ttin
    Background process attempting read.
    Action: Stops executing.

    +
  • +
  • <a href="#signal.ttou" name="signal.ttou"></a> ttou
    Background process attempting write.
    Action: Stops executing.

    +
  • +
  • <a href="#signal.urg" name="signal.urg"></a> urg
    High bandwidth data is available at a socket.
    Action: Ignored.

    +
  • +
  • <a href="#signal.xcpu" name="signal.xcpu"></a> xcpu
    CPU time limit exceeded.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.xfsz" name="signal.xfsz"></a> xfsz
    File size limit exceeded.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.vtalrm" name="signal.vtalrm"></a> vtalrm
    Virtual timer expired.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.prof" name="signal.prof"></a> prof
    Profiling timer expired.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.winch" name="signal.winch"></a> winch
    Window changed.
    Action: Ignored.

    +
  • +
  • <a href="#signal.poll" name="signal.poll"></a> poll
    I/O possible.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.pwr" name="signal.pwr"></a> pwr
    Power failure.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.sys" name="signal.sys"></a> sys
    Bad system call.
    Action: Terminates the process.

    +
  • +
+

<a href="#riflags" name="riflags"></a> riflags: Flags(u16)

+

Flags provided to sock_recv.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#riflags.recv_peek" name="riflags.recv_peek"></a> recv_peek
    Returns the message without removing it from the socket's receive queue.

    +
  • +
  • <a href="#riflags.recv_waitall" name="riflags.recv_waitall"></a> recv_waitall
    On byte-stream sockets, block until the full amount of data can be returned.

    +
  • +
+

<a href="#roflags" name="roflags"></a> roflags: Flags(u16)

+

Flags returned by sock_recv.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#roflags.recv_data_truncated" name="roflags.recv_data_truncated"></a> recv_data_truncated
    Returned by sock_recv: Message data has been truncated.
  • +
+

<a href="#siflags" name="siflags"></a> siflags: u16

+

Flags provided to sock_send. As there are currently no flags
defined, it must be set to zero.
Size: 2
Alignment: 2

+

<a href="#sdflags" name="sdflags"></a> sdflags: Flags(u8)

+

Which channels on a socket to shut down.
Size: 1
Alignment: 1

+

Flags

+
    +
  • <a href="#sdflags.rd" name="sdflags.rd"></a> rd
    Disables further receive operations.

    +
  • +
  • <a href="#sdflags.wr" name="sdflags.wr"></a> wr
    Disables further send operations.

    +
  • +
+

<a href="#preopentype" name="preopentype"></a> preopentype: Enum(u8)

+

Identifiers for preopened capabilities.
Size: 1
Alignment: 1

+

Variants

+
    +
  • <a href="#preopentype.dir" name="preopentype.dir"></a> dir
    A pre-opened directory.
  • +
+

<a href="#prestat_dir" name="prestat_dir"></a> prestat_dir: Struct

+

The contents of a $prestat when type is preopentype::dir.
Size: 4
Alignment: 4

+

Struct members

+
    +
  • <a href="#prestat_dir.pr_name_len" name="prestat_dir.pr_name_len"></a> pr_name_len: size
    The length of the directory name for use with fd_prestat_dir_name.
    Offset: 0

    <a href="#prestat" name="prestat"></a> prestat: Union

    +Information about a pre-opened capability.
    Size: 8
    Alignment: 4

    Union Layout

    +
  • +
  • tag_size: 1
  • +
  • tag_align: 1
  • +
  • contents_offset: 4
  • +
  • contents_size: 4
  • +
  • contents_align: 4

    Union variants

    +
  • +
  • <a href="#prestat.dir" name="prestat.dir"></a> dir: prestat_dir
  • +
+

Modules

+

<a href="#wasi_snapshot_preview1" name="wasi_snapshot_preview1"></a> wasi_snapshot_preview1

+

Imports

+

Memory

+

Functions

+
+

<a href="#args_get" name="args_get"></a> args_get(argv: Pointer<Pointer<u8>>, argv_buf: Pointer<u8>) -> errno

+

Read command-line argument data.
The size of the array should match that returned by args_sizes_get

+
Params
+
    +
  • <a href="#args_get.argv" name="args_get.argv"></a> argv: Pointer<Pointer<u8>>

    +
  • +
  • <a href="#args_get.argv_buf" name="args_get.argv_buf"></a> argv_buf: Pointer<u8>

    +
  • +
+
Results
+
    +
  • <a href="#args_get.error" name="args_get.error"></a> error: errno
  • +
+
+

<a href="#args_sizes_get" name="args_sizes_get"></a> args_sizes_get() -> (errno, size, size)

+

Return command-line argument data sizes.

+
Params
+
Results
+
    +
  • <a href="#args_sizes_get.error" name="args_sizes_get.error"></a> error: errno

    +
  • +
  • <a href="#args_sizes_get.argc" name="args_sizes_get.argc"></a> argc: size
    The number of arguments.

    +
  • +
  • <a href="#args_sizes_get.argv_buf_size" name="args_sizes_get.argv_buf_size"></a> argv_buf_size: size
    The size of the argument string data.

    +
  • +
+
+

<a href="#environ_get" name="environ_get"></a> environ_get(environ: Pointer<Pointer<u8>>, environ_buf: Pointer<u8>) -> errno

+

Read environment variable data.
The sizes of the buffers should match that returned by environ_sizes_get.

+
Params
+
    +
  • <a href="#environ_get.environ" name="environ_get.environ"></a> environ: Pointer<Pointer<u8>>

    +
  • +
  • <a href="#environ_get.environ_buf" name="environ_get.environ_buf"></a> environ_buf: Pointer<u8>

    +
  • +
+
Results
+
    +
  • <a href="#environ_get.error" name="environ_get.error"></a> error: errno
  • +
+
+

<a href="#environ_sizes_get" name="environ_sizes_get"></a> environ_sizes_get() -> (errno, size, size)

+

Return environment variable data sizes.

+
Params
+
Results
+
    +
  • <a href="#environ_sizes_get.error" name="environ_sizes_get.error"></a> error: errno

    +
  • +
  • <a href="#environ_sizes_get.environc" name="environ_sizes_get.environc"></a> environc: size
    The number of environment variable arguments.

    +
  • +
  • <a href="#environ_sizes_get.environ_buf_size" name="environ_sizes_get.environ_buf_size"></a> environ_buf_size: size
    The size of the environment variable data.

    +
  • +
+
+

<a href="#clock_res_get" name="clock_res_get"></a> clock_res_get(id: clockid) -> (errno, timestamp)

+

Return the resolution of a clock.
Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks,
return errno::inval.
Note: This is similar to clock_getres in POSIX.

+
Params
+
    +
  • <a href="#clock_res_get.id" name="clock_res_get.id"></a> id: clockid
    The clock for which to return the resolution.
  • +
+
Results
+
    +
  • <a href="#clock_res_get.error" name="clock_res_get.error"></a> error: errno

    +
  • +
  • <a href="#clock_res_get.resolution" name="clock_res_get.resolution"></a> resolution: timestamp
    The resolution of the clock.

    +
  • +
+
+

<a href="#clock_time_get" name="clock_time_get"></a> clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)

+

Return the time value of a clock.
Note: This is similar to clock_gettime in POSIX.

+
Params
+
    +
  • <a href="#clock_time_get.id" name="clock_time_get.id"></a> id: clockid
    The clock for which to return the time.

    +
  • +
  • <a href="#clock_time_get.precision" name="clock_time_get.precision"></a> precision: timestamp
    The maximum lag (exclusive) that the returned time value may have, compared to its actual value.

    +
  • +
+
Results
+
    +
  • <a href="#clock_time_get.error" name="clock_time_get.error"></a> error: errno

    +
  • +
  • <a href="#clock_time_get.time" name="clock_time_get.time"></a> time: timestamp
    The time value of the clock.

    +
  • +
+
+

<a href="#fd_advise" name="fd_advise"></a> fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno

+

Provide file advisory information on a file descriptor.
Note: This is similar to posix_fadvise in POSIX.

+
Params
+
    +
  • <a href="#fd_advise.fd" name="fd_advise.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_advise.offset" name="fd_advise.offset"></a> offset: filesize
    The offset within the file to which the advisory applies.

    +
  • +
  • <a href="#fd_advise.len" name="fd_advise.len"></a> len: filesize
    The length of the region to which the advisory applies.

    +
  • +
  • <a href="#fd_advise.advice" name="fd_advise.advice"></a> advice: advice
    The advice.

    +
  • +
+
Results
+
    +
  • <a href="#fd_advise.error" name="fd_advise.error"></a> error: errno
  • +
+
+

<a href="#fd_allocate" name="fd_allocate"></a> fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno

+

Force the allocation of space in a file.
Note: This is similar to posix_fallocate in POSIX.

+
Params
+
    +
  • <a href="#fd_allocate.fd" name="fd_allocate.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_allocate.offset" name="fd_allocate.offset"></a> offset: filesize
    The offset at which to start the allocation.

    +
  • +
  • <a href="#fd_allocate.len" name="fd_allocate.len"></a> len: filesize
    The length of the area that is allocated.

    +
  • +
+
Results
+
    +
  • <a href="#fd_allocate.error" name="fd_allocate.error"></a> error: errno
  • +
+
+

<a href="#fd_close" name="fd_close"></a> fd_close(fd: fd) -> errno

+

Close a file descriptor.
Note: This is similar to close in POSIX.

+
Params
+
    +
  • <a href="#fd_close.fd" name="fd_close.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_close.error" name="fd_close.error"></a> error: errno
  • +
+
+

<a href="#fd_datasync" name="fd_datasync"></a> fd_datasync(fd: fd) -> errno

+

Synchronize the data of a file to disk.
Note: This is similar to fdatasync in POSIX.

+
Params
+
    +
  • <a href="#fd_datasync.fd" name="fd_datasync.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_datasync.error" name="fd_datasync.error"></a> error: errno
  • +
+
+

<a href="#fd_fdstat_get" name="fd_fdstat_get"></a> fd_fdstat_get(fd: fd) -> (errno, fdstat)

+

Get the attributes of a file descriptor.
Note: This returns similar flags to fsync(fd, F_GETFL) in POSIX, as well as additional fields.

+
Params
+
    +
  • <a href="#fd_fdstat_get.fd" name="fd_fdstat_get.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_fdstat_get.error" name="fd_fdstat_get.error"></a> error: errno

    +
  • +
  • <a href="#fd_fdstat_get.stat" name="fd_fdstat_get.stat"></a> stat: fdstat
    The buffer where the file descriptor's attributes are stored.

    +
  • +
+
+

<a href="#fd_fdstat_set_flags" name="fd_fdstat_set_flags"></a> fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno

+

Adjust the flags associated with a file descriptor.
Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

+
Params
+
    +
  • <a href="#fd_fdstat_set_flags.fd" name="fd_fdstat_set_flags.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_fdstat_set_flags.flags" name="fd_fdstat_set_flags.flags"></a> flags: fdflags
    The desired values of the file descriptor flags.

    +
  • +
+
Results
+
    +
  • <a href="#fd_fdstat_set_flags.error" name="fd_fdstat_set_flags.error"></a> error: errno
  • +
+
+

<a href="#fd_fdstat_set_rights" name="fd_fdstat_set_rights"></a> fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno

+

Adjust the rights associated with a file descriptor.
This can only be used to remove rights, and returns errno::notcapable if called in a way that would attempt to add rights

+
Params
+
    +
  • <a href="#fd_fdstat_set_rights.fd" name="fd_fdstat_set_rights.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_fdstat_set_rights.fs_rights_base" name="fd_fdstat_set_rights.fs_rights_base"></a> fs_rights_base: rights
    The desired rights of the file descriptor.

    +
  • +
  • <a href="#fd_fdstat_set_rights.fs_rights_inheriting" name="fd_fdstat_set_rights.fs_rights_inheriting"></a> fs_rights_inheriting: rights

    +
  • +
+
Results
+
    +
  • <a href="#fd_fdstat_set_rights.error" name="fd_fdstat_set_rights.error"></a> error: errno
  • +
+
+

<a href="#fd_filestat_get" name="fd_filestat_get"></a> fd_filestat_get(fd: fd) -> (errno, filestat)

+

Return the attributes of an open file.

+
Params
+
    +
  • <a href="#fd_filestat_get.fd" name="fd_filestat_get.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_filestat_get.error" name="fd_filestat_get.error"></a> error: errno

    +
  • +
  • <a href="#fd_filestat_get.buf" name="fd_filestat_get.buf"></a> buf: filestat
    The buffer where the file's attributes are stored.

    +
  • +
+
+

<a href="#fd_filestat_set_size" name="fd_filestat_set_size"></a> fd_filestat_set_size(fd: fd, size: filesize) -> errno

+

Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.
Note: This is similar to ftruncate in POSIX.

+
Params
+
    +
  • <a href="#fd_filestat_set_size.fd" name="fd_filestat_set_size.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_filestat_set_size.size" name="fd_filestat_set_size.size"></a> size: filesize
    The desired file size.

    +
  • +
+
Results
+
    +
  • <a href="#fd_filestat_set_size.error" name="fd_filestat_set_size.error"></a> error: errno
  • +
+
+

<a href="#fd_filestat_set_times" name="fd_filestat_set_times"></a> fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno

+

Adjust the timestamps of an open file or directory.
Note: This is similar to futimens in POSIX.

+
Params
+
    +
  • <a href="#fd_filestat_set_times.fd" name="fd_filestat_set_times.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_filestat_set_times.atim" name="fd_filestat_set_times.atim"></a> atim: timestamp
    The desired values of the data access timestamp.

    +
  • +
  • <a href="#fd_filestat_set_times.mtim" name="fd_filestat_set_times.mtim"></a> mtim: timestamp
    The desired values of the data modification timestamp.

    +
  • +
  • <a href="#fd_filestat_set_times.fst_flags" name="fd_filestat_set_times.fst_flags"></a> fst_flags: fstflags
    A bitmask indicating which timestamps to adjust.

    +
  • +
+
Results
+
    +
  • <a href="#fd_filestat_set_times.error" name="fd_filestat_set_times.error"></a> error: errno
  • +
+
+

<a href="#fd_pread" name="fd_pread"></a> fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)

+

Read from a file descriptor, without using and updating the file descriptor's offset.
Note: This is similar to preadv in POSIX.

+
Params
+
    +
  • <a href="#fd_pread.fd" name="fd_pread.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_pread.iovs" name="fd_pread.iovs"></a> iovs: iovec_array
    List of scatter/gather vectors in which to store data.

    +
  • +
  • <a href="#fd_pread.offset" name="fd_pread.offset"></a> offset: filesize
    The offset within the file at which to read.

    +
  • +
+
Results
+
    +
  • <a href="#fd_pread.error" name="fd_pread.error"></a> error: errno

    +
  • +
  • <a href="#fd_pread.nread" name="fd_pread.nread"></a> nread: size
    The number of bytes read.

    +
  • +
+
+

<a href="#fd_prestat_get" name="fd_prestat_get"></a> fd_prestat_get(fd: fd) -> (errno, prestat)

+

Return a description of the given preopened file descriptor.

+
Params
+
    +
  • <a href="#fd_prestat_get.fd" name="fd_prestat_get.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_prestat_get.error" name="fd_prestat_get.error"></a> error: errno

    +
  • +
  • <a href="#fd_prestat_get.buf" name="fd_prestat_get.buf"></a> buf: prestat
    The buffer where the description is stored.

    +
  • +
+
+

<a href="#fd_prestat_dir_name" name="fd_prestat_dir_name"></a> fd_prestat_dir_name(fd: fd, path: Pointer<u8>, path_len: size) -> errno

+

Return a description of the given preopened file descriptor.

+
Params
+
    +
  • <a href="#fd_prestat_dir_name.fd" name="fd_prestat_dir_name.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_prestat_dir_name.path" name="fd_prestat_dir_name.path"></a> path: Pointer<u8>
    A buffer into which to write the preopened directory name.

    +
  • +
  • <a href="#fd_prestat_dir_name.path_len" name="fd_prestat_dir_name.path_len"></a> path_len: size

    +
  • +
+
Results
+
    +
  • <a href="#fd_prestat_dir_name.error" name="fd_prestat_dir_name.error"></a> error: errno
  • +
+
+

<a href="#fd_pwrite" name="fd_pwrite"></a> fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)

+

Write to a file descriptor, without using and updating the file descriptor's offset.
Note: This is similar to pwritev in POSIX.

+
Params
+
    +
  • <a href="#fd_pwrite.fd" name="fd_pwrite.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_pwrite.iovs" name="fd_pwrite.iovs"></a> iovs: ciovec_array
    List of scatter/gather vectors from which to retrieve data.

    +
  • +
  • <a href="#fd_pwrite.offset" name="fd_pwrite.offset"></a> offset: filesize
    The offset within the file at which to write.

    +
  • +
+
Results
+
    +
  • <a href="#fd_pwrite.error" name="fd_pwrite.error"></a> error: errno

    +
  • +
  • <a href="#fd_pwrite.nwritten" name="fd_pwrite.nwritten"></a> nwritten: size
    The number of bytes written.

    +
  • +
+
+

<a href="#fd_read" name="fd_read"></a> fd_read(fd: fd, iovs: iovec_array) -> (errno, size)

+

Read from a file descriptor.
Note: This is similar to readv in POSIX.

+
Params
+
    +
  • <a href="#fd_read.fd" name="fd_read.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_read.iovs" name="fd_read.iovs"></a> iovs: iovec_array
    List of scatter/gather vectors to which to store data.

    +
  • +
+
Results
+
    +
  • <a href="#fd_read.error" name="fd_read.error"></a> error: errno

    +
  • +
  • <a href="#fd_read.nread" name="fd_read.nread"></a> nread: size
    The number of bytes read.

    +
  • +
+
+ +

Read directory entries from a directory.
When successful, the contents of the output buffer consist of a sequence of
directory entries. Each directory entry consists of a dirent_t object,
followed by dirent_t::d_namlen bytes holding the name of the directory
entry.
This function fills the output buffer as much as possible, potentially
truncating the last directory entry. This allows the caller to grow its
read buffer size in case it's too small to fit a single large directory
entry, or skip the oversized directory entry.

+
Params
+
    +
  • <a href="#fd_readdir.fd" name="fd_readdir.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_readdir.buf" name="fd_readdir.buf"></a> buf: Pointer<u8>
    The buffer where directory entries are stored

    +
  • +
  • <a href="#fd_readdir.buf_len" name="fd_readdir.buf_len"></a> buf_len: size

    +
  • +
  • <a href="#fd_readdir.cookie" name="fd_readdir.cookie"></a> cookie: dircookie
    The location within the directory to start reading

    +
  • +
+
Results
+
    +
  • <a href="#fd_readdir.error" name="fd_readdir.error"></a> error: errno

    +
  • +
  • <a href="#fd_readdir.bufused" name="fd_readdir.bufused"></a> bufused: size
    The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached.

    +
  • +
+
+

<a href="#fd_renumber" name="fd_renumber"></a> fd_renumber(fd: fd, to: fd) -> errno

+

Atomically replace a file descriptor by renumbering another file descriptor.
Due to the strong focus on thread safety, this environment does not provide
a mechanism to duplicate or renumber a file descriptor to an arbitrary
number, like dup2(). This would be prone to race conditions, as an actual
file descriptor with the same number could be allocated by a different
thread at the same time.
This function provides a way to atomically renumber file descriptors, which
would disappear if dup2() were to be removed entirely.

+
Params
+
    +
  • <a href="#fd_renumber.fd" name="fd_renumber.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_renumber.to" name="fd_renumber.to"></a> to: fd
    The file descriptor to overwrite.

    +
  • +
+
Results
+
    +
  • <a href="#fd_renumber.error" name="fd_renumber.error"></a> error: errno
  • +
+
+

<a href="#fd_seek" name="fd_seek"></a> fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)

+

Move the offset of a file descriptor.
Note: This is similar to lseek in POSIX.

+
Params
+
    +
  • <a href="#fd_seek.fd" name="fd_seek.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_seek.offset" name="fd_seek.offset"></a> offset: filedelta
    The number of bytes to move.

    +
  • +
  • <a href="#fd_seek.whence" name="fd_seek.whence"></a> whence: whence
    The base from which the offset is relative.

    +
  • +
+
Results
+
    +
  • <a href="#fd_seek.error" name="fd_seek.error"></a> error: errno

    +
  • +
  • <a href="#fd_seek.newoffset" name="fd_seek.newoffset"></a> newoffset: filesize
    The new offset of the file descriptor, relative to the start of the file.

    +
  • +
+
+

<a href="#fd_sync" name="fd_sync"></a> fd_sync(fd: fd) -> errno

+

Synchronize the data and metadata of a file to disk.
Note: This is similar to fsync in POSIX.

+
Params
+
    +
  • <a href="#fd_sync.fd" name="fd_sync.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_sync.error" name="fd_sync.error"></a> error: errno
  • +
+
+

<a href="#fd_tell" name="fd_tell"></a> fd_tell(fd: fd) -> (errno, filesize)

+

Return the current offset of a file descriptor.
Note: This is similar to lseek(fd, 0, SEEK_CUR) in POSIX.

+
Params
+
    +
  • <a href="#fd_tell.fd" name="fd_tell.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_tell.error" name="fd_tell.error"></a> error: errno

    +
  • +
  • <a href="#fd_tell.offset" name="fd_tell.offset"></a> offset: filesize
    The current offset of the file descriptor, relative to the start of the file.

    +
  • +
+
+

<a href="#fd_write" name="fd_write"></a> fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)

+

Write to a file descriptor.
Note: This is similar to writev in POSIX.

+
Params
+
    +
  • <a href="#fd_write.fd" name="fd_write.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_write.iovs" name="fd_write.iovs"></a> iovs: ciovec_array
    List of scatter/gather vectors from which to retrieve data.

    +
  • +
+
Results
+
    +
  • <a href="#fd_write.error" name="fd_write.error"></a> error: errno

    +
  • +
  • <a href="#fd_write.nwritten" name="fd_write.nwritten"></a> nwritten: size
    The number of bytes written.

    +
  • +
+
+

<a href="#path_create_directory" name="path_create_directory"></a> path_create_directory(fd: fd, path: string) -> errno

+

Create a directory.
Note: This is similar to mkdirat in POSIX.

+
Params
+
    +
  • <a href="#path_create_directory.fd" name="path_create_directory.fd"></a> fd: fd

    +
  • +
  • <a href="#path_create_directory.path" name="path_create_directory.path"></a> path: string
    The path at which to create the directory.

    +
  • +
+
Results
+
    +
  • <a href="#path_create_directory.error" name="path_create_directory.error"></a> error: errno
  • +
+
+

<a href="#path_filestat_get" name="path_filestat_get"></a> path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)

+

Return the attributes of a file or directory.
Note: This is similar to stat in POSIX.

+
Params
+
    +
  • <a href="#path_filestat_get.fd" name="path_filestat_get.fd"></a> fd: fd

    +
  • +
  • <a href="#path_filestat_get.flags" name="path_filestat_get.flags"></a> flags: lookupflags
    Flags determining the method of how the path is resolved.

    +
  • +
  • <a href="#path_filestat_get.path" name="path_filestat_get.path"></a> path: string
    The path of the file or directory to inspect.

    +
  • +
+
Results
+
    +
  • <a href="#path_filestat_get.error" name="path_filestat_get.error"></a> error: errno

    +
  • +
  • <a href="#path_filestat_get.buf" name="path_filestat_get.buf"></a> buf: filestat
    The buffer where the file's attributes are stored.

    +
  • +
+
+

<a href="#path_filestat_set_times" name="path_filestat_set_times"></a> path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno

+

Adjust the timestamps of a file or directory.
Note: This is similar to utimensat in POSIX.

+
Params
+
    +
  • <a href="#path_filestat_set_times.fd" name="path_filestat_set_times.fd"></a> fd: fd

    +
  • +
  • <a href="#path_filestat_set_times.flags" name="path_filestat_set_times.flags"></a> flags: lookupflags
    Flags determining the method of how the path is resolved.

    +
  • +
  • <a href="#path_filestat_set_times.path" name="path_filestat_set_times.path"></a> path: string
    The path of the file or directory to operate on.

    +
  • +
  • <a href="#path_filestat_set_times.atim" name="path_filestat_set_times.atim"></a> atim: timestamp
    The desired values of the data access timestamp.

    +
  • +
  • <a href="#path_filestat_set_times.mtim" name="path_filestat_set_times.mtim"></a> mtim: timestamp
    The desired values of the data modification timestamp.

    +
  • +
  • <a href="#path_filestat_set_times.fst_flags" name="path_filestat_set_times.fst_flags"></a> fst_flags: fstflags
    A bitmask indicating which timestamps to adjust.

    +
  • +
+
Results
+
    +
  • <a href="#path_filestat_set_times.error" name="path_filestat_set_times.error"></a> error: errno
  • +
+
+ +

Create a hard link.
Note: This is similar to linkat in POSIX.

+
Params
+
    +
  • <a href="#path_link.old_fd" name="path_link.old_fd"></a> old_fd: fd

    +
  • +
  • <a href="#path_link.old_flags" name="path_link.old_flags"></a> old_flags: lookupflags
    Flags determining the method of how the path is resolved.

    +
  • +
  • <a href="#path_link.old_path" name="path_link.old_path"></a> old_path: string
    The source path from which to link.

    +
  • +
  • <a href="#path_link.new_fd" name="path_link.new_fd"></a> new_fd: fd
    The working directory at which the resolution of the new path starts.

    +
  • +
  • <a href="#path_link.new_path" name="path_link.new_path"></a> new_path: string
    The destination path at which to create the hard link.

    +
  • +
+
Results
+
    +
  • <a href="#path_link.error" name="path_link.error"></a> error: errno
  • +
+
+

<a href="#path_open" name="path_open"></a> path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)

+

Open a file or directory.
The returned file descriptor is not guaranteed to be the lowest-numbered
file descriptor not currently open; it is randomized to prevent
applications from depending on making assumptions about indexes, since this
is error-prone in multi-threaded contexts. The returned file descriptor is
guaranteed to be less than 2**31.
Note: This is similar to openat in POSIX.

+
Params
+
    +
  • <a href="#path_open.fd" name="path_open.fd"></a> fd: fd

    +
  • +
  • <a href="#path_open.dirflags" name="path_open.dirflags"></a> dirflags: lookupflags
    Flags determining the method of how the path is resolved.

    +
  • +
  • <a href="#path_open.path" name="path_open.path"></a> path: string
    The relative path of the file or directory to open, relative to the
    path_open::fd directory.

    +
  • +
  • <a href="#path_open.oflags" name="path_open.oflags"></a> oflags: oflags
    The method by which to open the file.

    +
  • +
  • <a href="#path_open.fs_rights_base" name="path_open.fs_rights_base"></a> fs_rights_base: rights
    The initial rights of the newly created file descriptor. The
    implementation is allowed to return a file descriptor with fewer rights
    than specified, if and only if those rights do not apply to the type of
    file being opened.
    The base rights are rights that will apply to operations using the file
    descriptor itself, while the inheriting rights are rights that apply to
    file descriptors derived from it.

    +
  • +
  • <a href="#path_open.fs_rights_inherting" name="path_open.fs_rights_inherting"></a> fs_rights_inherting: rights

    +
  • +
  • <a href="#path_open.fdflags" name="path_open.fdflags"></a> fdflags: fdflags

    +
  • +
+
Results
+
    +
  • <a href="#path_open.error" name="path_open.error"></a> error: errno

    +
  • +
  • <a href="#path_open.opened_fd" name="path_open.opened_fd"></a> opened_fd: fd
    The file descriptor of the file that has been opened.

    +
  • +
+
+ +

Read the contents of a symbolic link.
Note: This is similar to readlinkat in POSIX.

+
Params
+
    +
  • <a href="#path_readlink.fd" name="path_readlink.fd"></a> fd: fd

    +
  • +
  • <a href="#path_readlink.path" name="path_readlink.path"></a> path: string
    The path of the symbolic link from which to read.

    +
  • +
  • <a href="#path_readlink.buf" name="path_readlink.buf"></a> buf: Pointer<u8>
    The buffer to which to write the contents of the symbolic link.

    +
  • +
  • <a href="#path_readlink.buf_len" name="path_readlink.buf_len"></a> buf_len: size

    +
  • +
+
Results
+
    +
  • <a href="#path_readlink.error" name="path_readlink.error"></a> error: errno

    +
  • +
  • <a href="#path_readlink.bufused" name="path_readlink.bufused"></a> bufused: size
    The number of bytes placed in the buffer.

    +
  • +
+
+

<a href="#path_remove_directory" name="path_remove_directory"></a> path_remove_directory(fd: fd, path: string) -> errno

+

Remove a directory.
Return errno::notempty if the directory is not empty.
Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

+
Params
+
    +
  • <a href="#path_remove_directory.fd" name="path_remove_directory.fd"></a> fd: fd

    +
  • +
  • <a href="#path_remove_directory.path" name="path_remove_directory.path"></a> path: string
    The path to a directory to remove.

    +
  • +
+
Results
+
    +
  • <a href="#path_remove_directory.error" name="path_remove_directory.error"></a> error: errno
  • +
+
+

<a href="#path_rename" name="path_rename"></a> path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno

+

Rename a file or directory.
Note: This is similar to renameat in POSIX.

+
Params
+
    +
  • <a href="#path_rename.fd" name="path_rename.fd"></a> fd: fd

    +
  • +
  • <a href="#path_rename.old_path" name="path_rename.old_path"></a> old_path: string
    The source path of the file or directory to rename.

    +
  • +
  • <a href="#path_rename.new_fd" name="path_rename.new_fd"></a> new_fd: fd
    The working directory at which the resolution of the new path starts.

    +
  • +
  • <a href="#path_rename.new_path" name="path_rename.new_path"></a> new_path: string
    The destination path to which to rename the file or directory.

    +
  • +
+
Results
+
    +
  • <a href="#path_rename.error" name="path_rename.error"></a> error: errno
  • +
+
+ +

Create a symbolic link.
Note: This is similar to symlinkat in POSIX.

+
Params
+
    +
  • <a href="#path_symlink.old_path" name="path_symlink.old_path"></a> old_path: string
    The contents of the symbolic link.

    +
  • +
  • <a href="#path_symlink.fd" name="path_symlink.fd"></a> fd: fd

    +
  • +
  • <a href="#path_symlink.new_path" name="path_symlink.new_path"></a> new_path: string
    The destination path at which to create the symbolic link.

    +
  • +
+
Results
+
    +
  • <a href="#path_symlink.error" name="path_symlink.error"></a> error: errno
  • +
+
+ +

Unlink a file.
Return errno::isdir if the path refers to a directory.
Note: This is similar to unlinkat(fd, path, 0) in POSIX.

+
Params
+
    +
  • <a href="#path_unlink_file.fd" name="path_unlink_file.fd"></a> fd: fd

    +
  • +
  • <a href="#path_unlink_file.path" name="path_unlink_file.path"></a> path: string
    The path to a file to unlink.

    +
  • +
+
Results
+
    +
  • <a href="#path_unlink_file.error" name="path_unlink_file.error"></a> error: errno
  • +
+
+

<a href="#poll_oneoff" name="poll_oneoff"></a> poll_oneoff(in: ConstPointer<subscription>, out: Pointer<event>, nsubscriptions: size) -> (errno, size)

+

Concurrently poll for the occurrence of a set of events.

+
Params
+
    +
  • <a href="#poll_oneoff.in" name="poll_oneoff.in"></a> in: ConstPointer<subscription>
    The events to which to subscribe.

    +
  • +
  • <a href="#poll_oneoff.out" name="poll_oneoff.out"></a> out: Pointer<event>
    The events that have occurred.

    +
  • +
  • <a href="#poll_oneoff.nsubscriptions" name="poll_oneoff.nsubscriptions"></a> nsubscriptions: size
    Both the number of subscriptions and events.

    +
  • +
+
Results
+
    +
  • <a href="#poll_oneoff.error" name="poll_oneoff.error"></a> error: errno

    +
  • +
  • <a href="#poll_oneoff.nevents" name="poll_oneoff.nevents"></a> nevents: size
    The number of events stored.

    +
  • +
+
+

<a href="#proc_exit" name="proc_exit"></a> proc_exit(rval: exitcode)

+

Terminate the process normally. An exit code of 0 indicates successful
termination of the program. The meanings of other values is dependent on
the environment.

+
Params
+
    +
  • <a href="#proc_exit.rval" name="proc_exit.rval"></a> rval: exitcode
    The exit code returned by the process.
  • +
+
Results
+
+

<a href="#proc_raise" name="proc_raise"></a> proc_raise(sig: signal) -> errno

+

Send a signal to the process of the calling thread.
Note: This is similar to raise in POSIX.

+
Params
+
    +
  • <a href="#proc_raise.sig" name="proc_raise.sig"></a> sig: signal
    The signal condition to trigger.
  • +
+
Results
+
    +
  • <a href="#proc_raise.error" name="proc_raise.error"></a> error: errno
  • +
+
+

<a href="#sched_yield" name="sched_yield"></a> sched_yield() -> errno

+

Temporarily yield execution of the calling thread.
Note: This is similar to sched_yield in POSIX.

+
Params
+
Results
+
    +
  • <a href="#sched_yield.error" name="sched_yield.error"></a> error: errno
  • +
+
+

<a href="#random_get" name="random_get"></a> random_get(buf: Pointer<u8>, buf_len: size) -> errno

+

Write high-quality random data into a buffer.
This function blocks when the implementation is unable to immediately
provide sufficient high-quality random data.
This function may execute slowly, so when large mounts of random data are
required, it's advisable to use this function to seed a pseudo-random
number generator, rather than to provide the random data directly.

+
Params
+
    +
  • <a href="#random_get.buf" name="random_get.buf"></a> buf: Pointer<u8>
    The buffer to fill with random data.

    +
  • +
  • <a href="#random_get.buf_len" name="random_get.buf_len"></a> buf_len: size

    +
  • +
+
Results
+
    +
  • <a href="#random_get.error" name="random_get.error"></a> error: errno
  • +
+
+

<a href="#sock_recv" name="sock_recv"></a> sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)

+

Receive a message from a socket.
Note: This is similar to recv in POSIX, though it also supports reading
the data into multiple buffers in the manner of readv.

+
Params
+
    +
  • <a href="#sock_recv.fd" name="sock_recv.fd"></a> fd: fd

    +
  • +
  • <a href="#sock_recv.ri_data" name="sock_recv.ri_data"></a> ri_data: iovec_array
    List of scatter/gather vectors to which to store data.

    +
  • +
  • <a href="#sock_recv.ri_flags" name="sock_recv.ri_flags"></a> ri_flags: riflags
    Message flags.

    +
  • +
+
Results
+
    +
  • <a href="#sock_recv.error" name="sock_recv.error"></a> error: errno

    +
  • +
  • <a href="#sock_recv.ro_datalen" name="sock_recv.ro_datalen"></a> ro_datalen: size
    Number of bytes stored in ri_data.

    +
  • +
  • <a href="#sock_recv.ro_flags" name="sock_recv.ro_flags"></a> ro_flags: roflags
    Message flags.

    +
  • +
+
+

<a href="#sock_send" name="sock_send"></a> sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)

+

Send a message on a socket.
Note: This is similar to send in POSIX, though it also supports writing
the data from multiple buffers in the manner of writev.

+
Params
+
    +
  • <a href="#sock_send.fd" name="sock_send.fd"></a> fd: fd

    +
  • +
  • <a href="#sock_send.si_data" name="sock_send.si_data"></a> si_data: ciovec_array
    List of scatter/gather vectors to which to retrieve data

    +
  • +
  • <a href="#sock_send.si_flags" name="sock_send.si_flags"></a> si_flags: siflags
    Message flags.

    +
  • +
+
Results
+
    +
  • <a href="#sock_send.error" name="sock_send.error"></a> error: errno

    +
  • +
  • <a href="#sock_send.so_datalen" name="sock_send.so_datalen"></a> so_datalen: size
    Number of bytes transmitted.

    +
  • +
+
+

<a href="#sock_shutdown" name="sock_shutdown"></a> sock_shutdown(fd: fd, how: sdflags) -> errno

+

Shut down socket send and receive channels.
Note: This is similar to shutdown in POSIX.

+
Params
+
    +
  • <a href="#sock_shutdown.fd" name="sock_shutdown.fd"></a> fd: fd

    +
  • +
  • <a href="#sock_shutdown.how" name="sock_shutdown.how"></a> how: sdflags
    Which channels on the socket to shut down.

    +
  • +
+
Results
+
    +
  • <a href="#sock_shutdown.error" name="sock_shutdown.error"></a> error: errno
  • +
diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index e2da39278..a50afa96a 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -1,15 +1,31 @@ # Types ## `size`: `u32` +Size: 4 + +Alignment: 4 + ## `filesize`: `u64` Non-negative file size or length of a region within a file. +Size: 8 + +Alignment: 8 + ## `timestamp`: `u64` Timestamp in nanoseconds. +Size: 8 + +Alignment: 8 + ## `clockid`: Enum(`u32`) Identifiers for clocks. +Size: 4 + +Alignment: 4 + ### Variants - `realtime` The clock measuring real time. Time value zero corresponds with @@ -33,6 +49,10 @@ Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided merely for alignment with POSIX. +Size: 2 + +Alignment: 2 + ### Variants - `success` No error occurred. System call completed successfully. @@ -268,6 +288,10 @@ Extension: Capabilities insufficient. ## `rights`: Flags(`u64`) File descriptor rights, determining which actions may be performed. +Size: 8 + +Alignment: 8 + ### Flags - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). @@ -371,37 +395,73 @@ The right to invoke [`sock_shutdown`](#sock_shutdown). ## `fd` A file descriptor handle. +Size: 4 + +Alignment: 4 + ### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `Pointer` The address of the buffer to be filled. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be filled. +Offset: 4 + ## `ciovec`: Struct A region of memory for scatter/gather writes. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `ConstPointer` The address of the buffer to be written. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be written. +Offset: 4 + ## `iovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `ciovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `filedelta`: `s64` Relative offset within a file. +Size: 8 + +Alignment: 8 + ## `whence`: Enum(`u8`) The position relative to which to set the offset of the file descriptor. +Size: 1 + +Alignment: 1 + ### Variants - `set` Seek relative to start-of-file. @@ -417,15 +477,31 @@ A reference to the offset of a directory entry. The value 0 signifies the start of the directory. +Size: 8 + +Alignment: 8 + ## `dirnamlen`: `u32` The type for the $d_namlen field of $dirent. +Size: 4 + +Alignment: 4 + ## `inode`: `u64` File serial number that is unique within its file system. +Size: 8 + +Alignment: 8 + ## `filetype`: Enum(`u8`) The type of a file descriptor or file. +Size: 1 + +Alignment: 1 + ### Variants - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -454,22 +530,38 @@ The file refers to a symbolic link inode. ## `dirent`: Struct A directory entry. +Size: 24 + +Alignment: 8 + ### Struct members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. +Offset: 0 + - `d_ino`: [`inode`](#inode) The serial number of the file referred to by this directory entry. +Offset: 8 + - `d_namlen`: [`dirnamlen`](#dirnamlen) The length of the name of the directory entry. +Offset: 16 + - `d_type`: [`filetype`](#filetype) The type of the file referred to by this directory entry. +Offset: 20 + ## `advice`: Enum(`u8`) File or memory access pattern advisory information. +Size: 1 + +Alignment: 1 + ### Variants - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -492,6 +584,10 @@ The application expects to access the specified data once and then not reuse it ## `fdflags`: Flags(`u16`) File descriptor flags. +Size: 2 + +Alignment: 2 + ### Flags - `append` Append mode: Data written to the file is always appended to the file's end. @@ -513,27 +609,47 @@ may also synchronously update the file's metadata. ## `fdstat`: Struct File descriptor attributes. +Size: 24 + +Alignment: 8 + ### Struct members - `fs_filetype`: [`filetype`](#filetype) File type. +Offset: 0 + - `fs_flags`: [`fdflags`](#fdflags) File descriptor flags. +Offset: 2 + - `fs_rights_base`: [`rights`](#rights) Rights that apply to this file descriptor. +Offset: 8 + - `fs_rights_inheriting`: [`rights`](#rights) Maximum set of rights that may be installed on new file descriptors that are created through this file descriptor, e.g., through [`path_open`](#path_open). +Offset: 16 + ## `device`: `u64` Identifier for a device containing a file system. Can be used in combination with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. +Size: 8 + +Alignment: 8 + ## `fstflags`: Flags(`u16`) Which file time attributes to adjust. +Size: 2 + +Alignment: 2 + ### Flags - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -550,6 +666,10 @@ Adjust the last data modification timestamp to the time of clock [`clockid::real ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. +Size: 4 + +Alignment: 4 + ### Flags - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. @@ -557,6 +677,10 @@ As long as the resolved path corresponds to a symbolic link, it is expanded. ## `oflags`: Flags(`u16`) Open flags used by [`path_open`](#path_open). +Size: 2 + +Alignment: 2 + ### Flags - `creat` Create file if it does not exist. @@ -573,41 +697,73 @@ Truncate file to size 0. ## `linkcount`: `u64` Number of hard links to an inode. +Size: 8 + +Alignment: 8 + ## `filestat`: Struct File attributes. +Size: 64 + +Alignment: 8 + ### Struct members - `dev`: [`device`](#device) Device ID of device containing the file. +Offset: 0 + - `ino`: [`inode`](#inode) File serial number. +Offset: 8 + - `filetype`: [`filetype`](#filetype) File type. +Offset: 16 + - `nlink`: [`linkcount`](#linkcount) Number of hard links to the file. +Offset: 24 + - `size`: [`filesize`](#filesize) For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. +Offset: 32 + - `atim`: [`timestamp`](#timestamp) Last data access timestamp. +Offset: 40 + - `mtim`: [`timestamp`](#timestamp) Last data modification timestamp. +Offset: 48 + - `ctim`: [`timestamp`](#timestamp) Last file status change timestamp. +Offset: 56 + ## `userdata`: `u64` User-provided value that may be attached to objects that is retained when extracted from the implementation. +Size: 8 + +Alignment: 8 + ## `eventtype`: Enum(`u8`) Type of a subscription to an event or its occurrence. +Size: 1 + +Alignment: 1 + ### Variants - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has @@ -625,6 +781,10 @@ available for writing. This event always triggers for regular files. The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 2 + +Alignment: 2 + ### Flags - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -633,34 +793,58 @@ The peer of this socket has closed or disconnected. The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 16 + +Alignment: 8 + ### Struct members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. +Offset: 0 + - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. +Offset: 8 + ## `event`: Struct An event that occurred. +Size: 32 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). +Offset: 0 + - `error`: [`errno`](#errno) If non-zero, an error that occurred while processing the subscription request. +Offset: 8 + - `type`: [`eventtype`](#eventtype) The type of event that occured +Offset: 10 + - `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. +Offset: 16 + ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). +Size: 2 + +Alignment: 2 + ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in @@ -672,31 +856,59 @@ current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). +Size: 32 + +Alignment: 8 + ### Struct members - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. +Offset: 0 + - `timeout`: [`timestamp`](#timestamp) The absolute or relative timestamp. +Offset: 8 + - `precision`: [`timestamp`](#timestamp) The amount of time that the implementation may wait additionally to coalesce with other events. +Offset: 16 + - `flags`: [`subclockflags`](#subclockflags) Flags specifying whether the timeout is absolute or relative +Offset: 24 + ## `subscription_fd_readwrite`: Struct The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 4 + +Alignment: 4 + ### Struct members - `file_descriptor`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. +Offset: 0 + ## `subscription_u`: Union The contents of a [`subscription`](#subscription). +Size: 40 + +Alignment: 8 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 8 +- contents_size: 32 +- contents_align: 8 ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -707,20 +919,36 @@ The contents of a [`subscription`](#subscription). ## `subscription`: Struct Subscription to an event. +Size: 48 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). +Offset: 0 + - `u`: [`subscription_u`](#subscription_u) The type of the event to which to subscribe, and its contents +Offset: 8 + ## `exitcode`: `u32` Exit code generated by a process when exiting. +Size: 4 + +Alignment: 4 + ## `signal`: Enum(`u8`) Signal condition. +Size: 1 + +Alignment: 1 + ### Variants - `none` No signal. Note that POSIX has special semantics for `kill(pid, 0)`, @@ -849,6 +1077,10 @@ Action: Terminates the process. ## `riflags`: Flags(`u16`) Flags provided to [`sock_recv`](#sock_recv). +Size: 2 + +Alignment: 2 + ### Flags - `recv_peek` Returns the message without removing it from the socket's receive queue. @@ -859,6 +1091,10 @@ On byte-stream sockets, block until the full amount of data can be returned. ## `roflags`: Flags(`u16`) Flags returned by [`sock_recv`](#sock_recv). +Size: 2 + +Alignment: 2 + ### Flags - `recv_data_truncated` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. @@ -867,9 +1103,17 @@ Returned by [`sock_recv`](#sock_recv): Message data has been truncated. Flags provided to [`sock_send`](#sock_send). As there are currently no flags defined, it must be set to zero. +Size: 2 + +Alignment: 2 + ## `sdflags`: Flags(`u8`) Which channels on a socket to shut down. +Size: 1 + +Alignment: 1 + ### Flags - `rd` Disables further receive operations. @@ -880,6 +1124,10 @@ Disables further send operations. ## `preopentype`: Enum(`u8`) Identifiers for preopened capabilities. +Size: 1 + +Alignment: 1 + ### Variants - `dir` A pre-opened directory. @@ -887,13 +1135,29 @@ A pre-opened directory. ## `prestat_dir`: Struct The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). +Size: 4 + +Alignment: 4 + ### Struct members - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). +Offset: 0 + ## `prestat`: Union Information about a pre-opened capability. +Size: 8 + +Alignment: 4 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 4 +- contents_size: 4 +- contents_align: 4 ### Union variants - `dir`: [`prestat_dir`](#prestat_dir) diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index 10dc9f7c2..02ef9ec22 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -8,6 +8,7 @@ use crate::{ InterfaceFunc, InterfaceFuncParam, Module, ModuleImport, ModuleImportVariant, NamedType, StructDatatype, Type, TypeRef, UnionDatatype, }, + layout::Layout, polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, RepEquality, }; @@ -26,7 +27,13 @@ impl ToMarkdown for Document { heading.new_level_down(), name, name, - &d.docs, + format!( + "{}\nSize: {}\n\nAlignment: {}\n", + &d.docs, + &d.mem_size(), + &d.mem_align() + ) + .as_str(), )); d.generate(child.clone()); } @@ -173,7 +180,9 @@ impl ToMarkdown for StructDatatype { let heading = heading_from_node(&node, 1); node.new_child(MdSection::new(heading, "Struct members")); - for member in &self.members { + for member_layout in &self.member_layout() { + let member = member_layout.member; + let offset = member_layout.offset; let name = member.name.as_str(); let id = if let Some(id) = node.any_ref().id() { format!("{}.{}", id, name) @@ -184,7 +193,7 @@ impl ToMarkdown for StructDatatype { MdHeading::new_bullet(), id.as_str(), name, - &member.docs, + format!("{}\nOffset: {}\n", &member.docs, &offset).as_str(), )); member.tref.generate(n.clone()); } @@ -195,8 +204,34 @@ impl ToMarkdown for StructDatatype { impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Union variants")); + // Sizes & Alignments + let sizes_heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(sizes_heading, "Union Layout")); + let union_layout = &self.union_layout(); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("tag_size: {}", union_layout.tag_size).as_str(), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("tag_align: {}", union_layout.tag_align).as_str(), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("contents_offset: {}", union_layout.contents_offset).as_str(), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("contents_size: {}", union_layout.contents_size).as_str(), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("contents_align: {}", union_layout.contents_align).as_str(), + )); + + // Variants + let variants_heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(variants_heading, "Union variants")); for variant in &self.variants { let name = variant.name.as_str(); From 5ac3ff265a50890410da54fb6975eac5d88f459e Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Sat, 2 May 2020 00:01:48 -0700 Subject: [PATCH 0638/1772] Added sizes and alignments to WASI docs (#268) * Added sizes and alignments to WASI docs * Fixed formatting * Made requested changes * Fixed whitespace issues * Fixed up whitespace one last time --- proposals/random/phases/ephemeral/docs.md | 274 ++++ .../random/phases/old/snapshot_0/docs.md | 266 ++++ proposals/random/phases/snapshot/docs.html | 1279 +++++++++++++++++ proposals/random/phases/snapshot/docs.md | 264 ++++ proposals/random/tools/witx/src/docs/ast.rs | 45 +- 5 files changed, 2123 insertions(+), 5 deletions(-) create mode 100644 proposals/random/phases/snapshot/docs.html diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index c645a7452..3ddc5ad79 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -4,15 +4,31 @@ An array size. Note: This is similar to `size_t` in POSIX. +Size: 4 + +Alignment: 4 + ## `filesize`: `u64` Non-negative file size or length of a region within a file. +Size: 8 + +Alignment: 8 + ## `timestamp`: `u64` Timestamp in nanoseconds. +Size: 8 + +Alignment: 8 + ## `clockid`: Enum(`u32`) Identifiers for clocks. +Size: 4 + +Alignment: 4 + ### Variants - `realtime` The clock measuring real time. Time value zero corresponds with @@ -30,6 +46,10 @@ Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided merely for alignment with POSIX. +Size: 2 + +Alignment: 2 + ### Variants - `success` No error occurred. System call completed successfully. @@ -265,6 +285,10 @@ Extension: Capabilities insufficient. ## `rights`: Flags(`u64`) File descriptor rights, determining which actions may be performed. +Size: 8 + +Alignment: 8 + ### Flags - `fd_datasync` The right to invoke `fd_datasync`. @@ -374,37 +398,73 @@ The right to invoke `sock_shutdown`. ## `fd` A file descriptor handle. +Size: 4 + +Alignment: 4 + ### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `Pointer` The address of the buffer to be filled. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be filled. +Offset: 4 + ## `ciovec`: Struct A region of memory for scatter/gather writes. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `ConstPointer` The address of the buffer to be written. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be written. +Offset: 4 + ## `iovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `ciovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `filedelta`: `s64` Relative offset within a file. +Size: 8 + +Alignment: 8 + ## `whence`: Enum(`u8`) The position relative to which to set the offset of the file descriptor. +Size: 1 + +Alignment: 1 + ### Variants - `set` Seek relative to start-of-file. @@ -418,6 +478,10 @@ Seek relative to end-of-file. ## `dircookie`: Int(`u64`) A reference to the offset of a directory entry. +Size: 8 + +Alignment: 8 + ### Consts - `start` In an `fd_readdir` call, this value signifies the start of the directory. @@ -425,12 +489,24 @@ In an `fd_readdir` call, this value signifies the start of the directory. ## `dirnamlen`: `u32` The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). +Size: 4 + +Alignment: 4 + ## `inode`: `u64` File serial number that is unique within its file system. +Size: 8 + +Alignment: 8 + ## `filetype`: Enum(`u8`) The type of a file descriptor or file. +Size: 1 + +Alignment: 1 + ### Variants - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -462,22 +538,38 @@ The file descriptor or file refers to a FIFO. ## `dirent`: Struct A directory entry. +Size: 24 + +Alignment: 8 + ### Struct members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. +Offset: 0 + - `d_ino`: [`inode`](#inode) The serial number of the file referred to by this directory entry. +Offset: 8 + - `d_namlen`: [`dirnamlen`](#dirnamlen) The length of the name of the directory entry. +Offset: 16 + - `d_type`: [`filetype`](#filetype) The type of the file referred to by this directory entry. +Offset: 20 + ## `advice`: Enum(`u8`) File or memory access pattern advisory information. +Size: 1 + +Alignment: 1 + ### Variants - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -500,6 +592,10 @@ The application expects to access the specified data once and then not reuse it ## `fdflags`: Flags(`u16`) File descriptor flags. +Size: 2 + +Alignment: 2 + ### Flags - `append` Append mode: Data written to the file is always appended to the file's end. @@ -521,27 +617,47 @@ may also synchronously update the file's metadata. ## `fdstat`: Struct File descriptor attributes. +Size: 24 + +Alignment: 8 + ### Struct members - `fs_filetype`: [`filetype`](#filetype) File type. +Offset: 0 + - `fs_flags`: [`fdflags`](#fdflags) File descriptor flags. +Offset: 2 + - `fs_rights_base`: [`rights`](#rights) Rights that apply to this file descriptor. +Offset: 8 + - `fs_rights_inheriting`: [`rights`](#rights) Maximum set of rights that may be installed on new file descriptors that are created through this file descriptor, e.g., through `path_open`. +Offset: 16 + ## `device`: `u64` Identifier for a device containing a file system. Can be used in combination with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. +Size: 8 + +Alignment: 8 + ## `fstflags`: Flags(`u16`) Which file time attributes to adjust. +Size: 2 + +Alignment: 2 + ### Flags - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -558,6 +674,10 @@ Adjust the last data modification timestamp to the time of clock [`clockid::real ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. +Size: 4 + +Alignment: 4 + ### Flags - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. @@ -565,6 +685,10 @@ As long as the resolved path corresponds to a symbolic link, it is expanded. ## `oflags`: Flags(`u16`) Open flags used by `path_open`. +Size: 2 + +Alignment: 2 + ### Flags - `create` Create file if it does not exist. @@ -581,11 +705,19 @@ Truncate file to size 0. ## `linkcount`: `u64` Number of hard links to an inode. +Size: 8 + +Alignment: 8 + ## `permissions`: Flags(`u8`) File permissions. This represents the permissions associated with a file in a filesystem, and don't fully reflect all the conditions which determine whether a given WASI program can access the file. +Size: 1 + +Alignment: 1 + ### Flags - `read` For files, permission to read the file. @@ -614,41 +746,71 @@ to other "users". ## `filestat`: Struct File attributes. +Size: 64 + +Alignment: 8 + ### Struct members - `dev`: [`device`](#device) Device ID of device containing the file. +Offset: 0 + - `ino`: [`inode`](#inode) File serial number. +Offset: 8 + - `filetype`: [`filetype`](#filetype) File type. +Offset: 16 + - `permissions`: [`permissions`](#permissions) File permissions. +Offset: 17 + - `nlink`: [`linkcount`](#linkcount) Number of hard links to the file. +Offset: 24 + - `size`: [`filesize`](#filesize) For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. +Offset: 32 + - `atim`: [`timestamp`](#timestamp) Last data access timestamp. +Offset: 40 + - `mtim`: [`timestamp`](#timestamp) Last data modification timestamp. +Offset: 48 + - `ctim`: [`timestamp`](#timestamp) Last file status change timestamp. +Offset: 56 + ## `userdata`: `u64` User-provided value that may be attached to objects that is retained when extracted from the implementation. +Size: 8 + +Alignment: 8 + ## `eventtype`: Enum(`u8`) Type of a subscription to an event or its occurrence. +Size: 1 + +Alignment: 1 + ### Variants - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has @@ -666,6 +828,10 @@ available for writing. This event always triggers for regular files. The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 2 + +Alignment: 2 + ### Flags - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -674,16 +840,34 @@ The peer of this socket has closed or disconnected. The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 16 + +Alignment: 8 + ### Struct members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. +Offset: 0 + - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. +Offset: 8 + ## `event_u`: Union The contents of an [`event`](#event). +Size: 24 + +Alignment: 8 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 8 +- contents_size: 16 +- contents_align: 8 ### Union variants - `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) @@ -694,20 +878,34 @@ The contents of an [`event`](#event). ## `event`: Struct An event that occurred. +Size: 40 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). +Offset: 0 + - `error`: [`errno`](#errno) If non-zero, an error that occurred while processing the subscription request. +Offset: 8 + - `u`: [`event_u`](#event_u) The type of the event that occurred, and the contents of the event +Offset: 16 + ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). +Size: 2 + +Alignment: 2 + ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in @@ -719,31 +917,59 @@ current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). +Size: 32 + +Alignment: 8 + ### Struct members - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. +Offset: 0 + - `timeout`: [`timestamp`](#timestamp) The absolute or relative timestamp. +Offset: 8 + - `precision`: [`timestamp`](#timestamp) The amount of time that the implementation may wait additionally to coalesce with other events. +Offset: 16 + - `flags`: [`subclockflags`](#subclockflags) Flags specifying whether the timeout is absolute or relative +Offset: 24 + ## `subscription_fd_readwrite`: Struct The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 4 + +Alignment: 4 + ### Struct members - `fd`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. +Offset: 0 + ## `subscription_u`: Union The contents of a [`subscription`](#subscription). +Size: 40 + +Alignment: 8 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 8 +- contents_size: 32 +- contents_align: 8 ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -754,20 +980,36 @@ The contents of a [`subscription`](#subscription). ## `subscription`: Struct Subscription to an event. +Size: 48 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). +Offset: 0 + - `u`: [`subscription_u`](#subscription_u) The type of the event to which to subscribe, and the contents of the subscription. +Offset: 8 + ## `exitcode`: `u32` Exit code generated by a process when exiting. +Size: 4 + +Alignment: 4 + ## `riflags`: Flags(`u16`) Flags provided to `sock_recv`. +Size: 2 + +Alignment: 2 + ### Flags - `recv_peek` Returns the message without removing it from the socket's receive queue. @@ -778,6 +1020,10 @@ On byte-stream sockets, block until the full amount of data can be returned. ## `roflags`: Flags(`u16`) Flags returned by `sock_recv`. +Size: 2 + +Alignment: 2 + ### Flags - `recv_data_truncated` Returned by `sock_recv`: Message data has been truncated. @@ -786,9 +1032,17 @@ Returned by `sock_recv`: Message data has been truncated. Flags provided to `sock_send`. As there are currently no flags defined, it must be set to zero. +Size: 2 + +Alignment: 2 + ## `sdflags`: Flags(`u8`) Which channels on a socket to shut down. +Size: 1 + +Alignment: 1 + ### Flags - `rd` Disables further receive operations. @@ -799,6 +1053,10 @@ Disables further send operations. ## `preopentype`: Enum(`u8`) Identifiers for preopened capabilities. +Size: 1 + +Alignment: 1 + ### Variants - `dir` A pre-opened directory. @@ -806,13 +1064,29 @@ A pre-opened directory. ## `prestat_dir`: Struct The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). +Size: 4 + +Alignment: 4 + ### Struct members - `pr_name_len`: [`size`](#size) The length of the directory name for use with `fd_prestat_dir_name`. +Offset: 0 + ## `prestat`: Union Information about a pre-opened capability. +Size: 8 + +Alignment: 4 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 4 +- contents_size: 4 +- contents_align: 4 ### Union variants - `dir`: [`prestat_dir`](#prestat_dir) When type is [`preopentype::dir`](#preopentype.dir): diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index f5b8ff314..eda85fbc0 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -1,15 +1,31 @@ # Types ## `size`: `u32` +Size: 4 + +Alignment: 4 + ## `filesize`: `u64` Non-negative file size or length of a region within a file. +Size: 8 + +Alignment: 8 + ## `timestamp`: `u64` Timestamp in nanoseconds. +Size: 8 + +Alignment: 8 + ## `clockid`: Enum(`u32`) Identifiers for clocks. +Size: 4 + +Alignment: 4 + ### Variants - `realtime` The clock measuring real time. Time value zero corresponds with @@ -33,6 +49,10 @@ Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided merely for alignment with POSIX. +Size: 2 + +Alignment: 2 + ### Variants - `success` No error occurred. System call completed successfully. @@ -268,6 +288,10 @@ Extension: Capabilities insufficient. ## `rights`: Flags(`u64`) File descriptor rights, determining which actions may be performed. +Size: 8 + +Alignment: 8 + ### Flags - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). @@ -371,37 +395,73 @@ The right to invoke [`sock_shutdown`](#sock_shutdown). ## `fd` A file descriptor handle. +Size: 4 + +Alignment: 4 + ### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `Pointer` The address of the buffer to be filled. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be filled. +Offset: 4 + ## `ciovec`: Struct A region of memory for scatter/gather writes. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `ConstPointer` The address of the buffer to be written. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be written. +Offset: 4 + ## `iovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `ciovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `filedelta`: `s64` Relative offset within a file. +Size: 8 + +Alignment: 8 + ## `whence`: Enum(`u8`) The position relative to which to set the offset of the file descriptor. +Size: 1 + +Alignment: 1 + ### Variants - `cur` Seek relative to current position. @@ -415,15 +475,31 @@ Seek relative to start-of-file. ## `dircookie`: `u64` A reference to the offset of a directory entry. +Size: 8 + +Alignment: 8 + ## `dirnamlen`: `u32` The type for the $d_namlen field of $dirent. +Size: 4 + +Alignment: 4 + ## `inode`: `u64` File serial number that is unique within its file system. +Size: 8 + +Alignment: 8 + ## `filetype`: Enum(`u8`) The type of a file descriptor or file. +Size: 1 + +Alignment: 1 + ### Variants - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -452,22 +528,38 @@ The file refers to a symbolic link inode. ## `dirent`: Struct A directory entry. +Size: 24 + +Alignment: 8 + ### Struct members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. +Offset: 0 + - `d_ino`: [`inode`](#inode) The serial number of the file referred to by this directory entry. +Offset: 8 + - `d_namlen`: [`dirnamlen`](#dirnamlen) The length of the name of the directory entry. +Offset: 16 + - `d_type`: [`filetype`](#filetype) The type of the file referred to by this directory entry. +Offset: 20 + ## `advice`: Enum(`u8`) File or memory access pattern advisory information. +Size: 1 + +Alignment: 1 + ### Variants - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -490,6 +582,10 @@ The application expects to access the specified data once and then not reuse it ## `fdflags`: Flags(`u16`) File descriptor flags. +Size: 2 + +Alignment: 2 + ### Flags - `append` Append mode: Data written to the file is always appended to the file's end. @@ -511,27 +607,47 @@ may also synchronously update the file's metadata. ## `fdstat`: Struct File descriptor attributes. +Size: 24 + +Alignment: 8 + ### Struct members - `fs_filetype`: [`filetype`](#filetype) File type. +Offset: 0 + - `fs_flags`: [`fdflags`](#fdflags) File descriptor flags. +Offset: 2 + - `fs_rights_base`: [`rights`](#rights) Rights that apply to this file descriptor. +Offset: 8 + - `fs_rights_inheriting`: [`rights`](#rights) Maximum set of rights that may be installed on new file descriptors that are created through this file descriptor, e.g., through [`path_open`](#path_open). +Offset: 16 + ## `device`: `u64` Identifier for a device containing a file system. Can be used in combination with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. +Size: 8 + +Alignment: 8 + ## `fstflags`: Flags(`u16`) Which file time attributes to adjust. +Size: 2 + +Alignment: 2 + ### Flags - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -548,6 +664,10 @@ Adjust the last data modification timestamp to the time of clock [`clockid::real ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. +Size: 4 + +Alignment: 4 + ### Flags - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. @@ -555,6 +675,10 @@ As long as the resolved path corresponds to a symbolic link, it is expanded. ## `oflags`: Flags(`u16`) Open flags used by [`path_open`](#path_open). +Size: 2 + +Alignment: 2 + ### Flags - `creat` Create file if it does not exist. @@ -571,41 +695,73 @@ Truncate file to size 0. ## `linkcount`: `u32` Number of hard links to an inode. +Size: 4 + +Alignment: 4 + ## `filestat`: Struct File attributes. +Size: 56 + +Alignment: 8 + ### Struct members - `dev`: [`device`](#device) Device ID of device containing the file. +Offset: 0 + - `ino`: [`inode`](#inode) File serial number. +Offset: 8 + - `filetype`: [`filetype`](#filetype) File type. +Offset: 16 + - `nlink`: [`linkcount`](#linkcount) Number of hard links to the file. +Offset: 20 + - `size`: [`filesize`](#filesize) For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. +Offset: 24 + - `atim`: [`timestamp`](#timestamp) Last data access timestamp. +Offset: 32 + - `mtim`: [`timestamp`](#timestamp) Last data modification timestamp. +Offset: 40 + - `ctim`: [`timestamp`](#timestamp) Last file status change timestamp. +Offset: 48 + ## `userdata`: `u64` User-provided value that may be attached to objects that is retained when extracted from the implementation. +Size: 8 + +Alignment: 8 + ## `eventtype`: Enum(`u8`) Type of a subscription to an event or its occurrence. +Size: 1 + +Alignment: 1 + ### Variants - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has @@ -623,6 +779,10 @@ available for writing. This event always triggers for regular files. The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 2 + +Alignment: 2 + ### Flags - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -631,34 +791,58 @@ The peer of this socket has closed or disconnected. The contents of an $event for the [`eventtype::fd_read`](#eventtype.fd_read) and [`eventtype::fd_write`](#eventtype.fd_write) variants +Size: 16 + +Alignment: 8 + ### Struct members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. +Offset: 0 + - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. +Offset: 8 + ## `event`: Struct An event that occurred. +Size: 32 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). +Offset: 0 + - `error`: [`errno`](#errno) If non-zero, an error that occurred while processing the subscription request. +Offset: 8 + - `type`: [`eventtype`](#eventtype) The type of event that occured +Offset: 10 + - `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. +Offset: 16 + ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). +Size: 2 + +Alignment: 2 + ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in @@ -670,34 +854,64 @@ current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). +Size: 40 + +Alignment: 8 + ### Struct members - `identifier`: [`userdata`](#userdata) The user-defined unique identifier of the clock. +Offset: 0 + - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. +Offset: 8 + - `timeout`: [`timestamp`](#timestamp) The absolute or relative timestamp. +Offset: 16 + - `precision`: [`timestamp`](#timestamp) The amount of time that the implementation may wait additionally to coalesce with other events. +Offset: 24 + - `flags`: [`subclockflags`](#subclockflags) Flags specifying whether the timeout is absolute or relative +Offset: 32 + ## `subscription_fd_readwrite`: Struct The contents of a [`subscription`](#subscription) when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 4 + +Alignment: 4 + ### Struct members - `file_descriptor`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. +Offset: 0 + ## `subscription_u`: Union The contents of a [`subscription`](#subscription). +Size: 48 + +Alignment: 8 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 8 +- contents_size: 40 +- contents_align: 8 ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -708,20 +922,36 @@ The contents of a [`subscription`](#subscription). ## `subscription`: Struct Subscription to an event. +Size: 56 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). +Offset: 0 + - `u`: [`subscription_u`](#subscription_u) The type of the event to which to subscribe. +Offset: 8 + ## `exitcode`: `u32` Exit code generated by a process when exiting. +Size: 4 + +Alignment: 4 + ## `signal`: Enum(`u8`) Signal condition. +Size: 1 + +Alignment: 1 + ### Variants - `none` No signal. Note that POSIX has special semantics for `kill(pid, 0)`, @@ -850,6 +1080,10 @@ Action: Terminates the process. ## `riflags`: Flags(`u16`) Flags provided to [`sock_recv`](#sock_recv). +Size: 2 + +Alignment: 2 + ### Flags - `recv_peek` Returns the message without removing it from the socket's receive queue. @@ -860,6 +1094,10 @@ On byte-stream sockets, block until the full amount of data can be returned. ## `roflags`: Flags(`u16`) Flags returned by [`sock_recv`](#sock_recv). +Size: 2 + +Alignment: 2 + ### Flags - `recv_data_truncated` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. @@ -868,9 +1106,17 @@ Returned by [`sock_recv`](#sock_recv): Message data has been truncated. Flags provided to [`sock_send`](#sock_send). As there are currently no flags defined, it must be set to zero. +Size: 2 + +Alignment: 2 + ## `sdflags`: Flags(`u8`) Which channels on a socket to shut down. +Size: 1 + +Alignment: 1 + ### Flags - `rd` Disables further receive operations. @@ -881,6 +1127,10 @@ Disables further send operations. ## `preopentype`: Enum(`u8`) Identifiers for preopened capabilities. +Size: 1 + +Alignment: 1 + ### Variants - `dir` A pre-opened directory. @@ -888,13 +1138,29 @@ A pre-opened directory. ## `prestat_dir`: Struct The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). +Size: 4 + +Alignment: 4 + ### Struct members - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). +Offset: 0 + ## `prestat`: Union Information about a pre-opened capability. +Size: 8 + +Alignment: 4 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 4 +- contents_size: 4 +- contents_align: 4 ### Union variants - `dir`: [`prestat_dir`](#prestat_dir) diff --git a/proposals/random/phases/snapshot/docs.html b/proposals/random/phases/snapshot/docs.html new file mode 100644 index 000000000..83ea3c7d2 --- /dev/null +++ b/proposals/random/phases/snapshot/docs.html @@ -0,0 +1,1279 @@ +

Types

+

<a href="#size" name="size"></a> size: u32

+

Size: 4
Alignment: 4

+

<a href="#filesize" name="filesize"></a> filesize: u64

+

Non-negative file size or length of a region within a file.
Size: 8
Alignment: 8

+

<a href="#timestamp" name="timestamp"></a> timestamp: u64

+

Timestamp in nanoseconds.
Size: 8
Alignment: 8

+

<a href="#clockid" name="clockid"></a> clockid: Enum(u32)

+

Identifiers for clocks.
Size: 4
Alignment: 4

+

Variants

+
    +
  • <a href="#clockid.realtime" name="clockid.realtime"></a> realtime
    The clock measuring real time. Time value zero corresponds with
    1970-01-01T00:00:00Z.

    +
  • +
  • <a href="#clockid.monotonic" name="clockid.monotonic"></a> monotonic
    The store-wide monotonic clock, which is defined as a clock measuring
    real time, whose value cannot be adjusted and which cannot have negative
    clock jumps. The epoch of this clock is undefined. The absolute time
    value of this clock therefore has no meaning.

    +
  • +
  • <a href="#clockid.process_cputime_id" name="clockid.process_cputime_id"></a> process_cputime_id
    The CPU-time clock associated with the current process.

    +
  • +
  • <a href="#clockid.thread_cputime_id" name="clockid.thread_cputime_id"></a> thread_cputime_id
    The CPU-time clock associated with the current thread.

    +
  • +
+

<a href="#errno" name="errno"></a> errno: Enum(u16)

+

Error codes returned by functions.
Not all of these error codes are returned by the functions provided by this
API; some are used in higher-level library layers, and others are provided
merely for alignment with POSIX.
Size: 2
Alignment: 2

+

Variants

+
    +
  • <a href="#errno.success" name="errno.success"></a> success
    No error occurred. System call completed successfully.

    +
  • +
  • <a href="#errno.2big" name="errno.2big"></a> 2big
    Argument list too long.

    +
  • +
  • <a href="#errno.acces" name="errno.acces"></a> acces
    Permission denied.

    +
  • +
  • <a href="#errno.addrinuse" name="errno.addrinuse"></a> addrinuse
    Address in use.

    +
  • +
  • <a href="#errno.addrnotavail" name="errno.addrnotavail"></a> addrnotavail
    Address not available.

    +
  • +
  • <a href="#errno.afnosupport" name="errno.afnosupport"></a> afnosupport
    Address family not supported.

    +
  • +
  • <a href="#errno.again" name="errno.again"></a> again
    Resource unavailable, or operation would block.

    +
  • +
  • <a href="#errno.already" name="errno.already"></a> already
    Connection already in progress.

    +
  • +
  • <a href="#errno.badf" name="errno.badf"></a> badf
    Bad file descriptor.

    +
  • +
  • <a href="#errno.badmsg" name="errno.badmsg"></a> badmsg
    Bad message.

    +
  • +
  • <a href="#errno.busy" name="errno.busy"></a> busy
    Device or resource busy.

    +
  • +
  • <a href="#errno.canceled" name="errno.canceled"></a> canceled
    Operation canceled.

    +
  • +
  • <a href="#errno.child" name="errno.child"></a> child
    No child processes.

    +
  • +
  • <a href="#errno.connaborted" name="errno.connaborted"></a> connaborted
    Connection aborted.

    +
  • +
  • <a href="#errno.connrefused" name="errno.connrefused"></a> connrefused
    Connection refused.

    +
  • +
  • <a href="#errno.connreset" name="errno.connreset"></a> connreset
    Connection reset.

    +
  • +
  • <a href="#errno.deadlk" name="errno.deadlk"></a> deadlk
    Resource deadlock would occur.

    +
  • +
  • <a href="#errno.destaddrreq" name="errno.destaddrreq"></a> destaddrreq
    Destination address required.

    +
  • +
  • <a href="#errno.dom" name="errno.dom"></a> dom
    Mathematics argument out of domain of function.

    +
  • +
  • <a href="#errno.dquot" name="errno.dquot"></a> dquot
    Reserved.

    +
  • +
  • <a href="#errno.exist" name="errno.exist"></a> exist
    File exists.

    +
  • +
  • <a href="#errno.fault" name="errno.fault"></a> fault
    Bad address.

    +
  • +
  • <a href="#errno.fbig" name="errno.fbig"></a> fbig
    File too large.

    +
  • +
  • <a href="#errno.hostunreach" name="errno.hostunreach"></a> hostunreach
    Host is unreachable.

    +
  • +
  • <a href="#errno.idrm" name="errno.idrm"></a> idrm
    Identifier removed.

    +
  • +
  • <a href="#errno.ilseq" name="errno.ilseq"></a> ilseq
    Illegal byte sequence.

    +
  • +
  • <a href="#errno.inprogress" name="errno.inprogress"></a> inprogress
    Operation in progress.

    +
  • +
  • <a href="#errno.intr" name="errno.intr"></a> intr
    Interrupted function.

    +
  • +
  • <a href="#errno.inval" name="errno.inval"></a> inval
    Invalid argument.

    +
  • +
  • <a href="#errno.io" name="errno.io"></a> io
    I/O error.

    +
  • +
  • <a href="#errno.isconn" name="errno.isconn"></a> isconn
    Socket is connected.

    +
  • +
  • <a href="#errno.isdir" name="errno.isdir"></a> isdir
    Is a directory.

    +
  • +
  • <a href="#errno.loop" name="errno.loop"></a> loop
    Too many levels of symbolic links.

    +
  • +
  • <a href="#errno.mfile" name="errno.mfile"></a> mfile
    File descriptor value too large.

    +
  • +
  • <a href="#errno.mlink" name="errno.mlink"></a> mlink
    Too many links.

    +
  • +
  • <a href="#errno.msgsize" name="errno.msgsize"></a> msgsize
    Message too large.

    +
  • +
  • <a href="#errno.multihop" name="errno.multihop"></a> multihop
    Reserved.

    +
  • +
  • <a href="#errno.nametoolong" name="errno.nametoolong"></a> nametoolong
    Filename too long.

    +
  • +
  • <a href="#errno.netdown" name="errno.netdown"></a> netdown
    Network is down.

    +
  • +
  • <a href="#errno.netreset" name="errno.netreset"></a> netreset
    Connection aborted by network.

    +
  • +
  • <a href="#errno.netunreach" name="errno.netunreach"></a> netunreach
    Network unreachable.

    +
  • +
  • <a href="#errno.nfile" name="errno.nfile"></a> nfile
    Too many files open in system.

    +
  • +
  • <a href="#errno.nobufs" name="errno.nobufs"></a> nobufs
    No buffer space available.

    +
  • +
  • <a href="#errno.nodev" name="errno.nodev"></a> nodev
    No such device.

    +
  • +
  • <a href="#errno.noent" name="errno.noent"></a> noent
    No such file or directory.

    +
  • +
  • <a href="#errno.noexec" name="errno.noexec"></a> noexec
    Executable file format error.

    +
  • +
  • <a href="#errno.nolck" name="errno.nolck"></a> nolck
    No locks available.

    +
  • +
  • <a href="#errno.nolink" name="errno.nolink"></a> nolink
    Reserved.

    +
  • +
  • <a href="#errno.nomem" name="errno.nomem"></a> nomem
    Not enough space.

    +
  • +
  • <a href="#errno.nomsg" name="errno.nomsg"></a> nomsg
    No message of the desired type.

    +
  • +
  • <a href="#errno.noprotoopt" name="errno.noprotoopt"></a> noprotoopt
    Protocol not available.

    +
  • +
  • <a href="#errno.nospc" name="errno.nospc"></a> nospc
    No space left on device.

    +
  • +
  • <a href="#errno.nosys" name="errno.nosys"></a> nosys
    Function not supported.

    +
  • +
  • <a href="#errno.notconn" name="errno.notconn"></a> notconn
    The socket is not connected.

    +
  • +
  • <a href="#errno.notdir" name="errno.notdir"></a> notdir
    Not a directory or a symbolic link to a directory.

    +
  • +
  • <a href="#errno.notempty" name="errno.notempty"></a> notempty
    Directory not empty.

    +
  • +
  • <a href="#errno.notrecoverable" name="errno.notrecoverable"></a> notrecoverable
    State not recoverable.

    +
  • +
  • <a href="#errno.notsock" name="errno.notsock"></a> notsock
    Not a socket.

    +
  • +
  • <a href="#errno.notsup" name="errno.notsup"></a> notsup
    Not supported, or operation not supported on socket.

    +
  • +
  • <a href="#errno.notty" name="errno.notty"></a> notty
    Inappropriate I/O control operation.

    +
  • +
  • <a href="#errno.nxio" name="errno.nxio"></a> nxio
    No such device or address.

    +
  • +
  • <a href="#errno.overflow" name="errno.overflow"></a> overflow
    Value too large to be stored in data type.

    +
  • +
  • <a href="#errno.ownerdead" name="errno.ownerdead"></a> ownerdead
    Previous owner died.

    +
  • +
  • <a href="#errno.perm" name="errno.perm"></a> perm
    Operation not permitted.

    +
  • +
  • <a href="#errno.pipe" name="errno.pipe"></a> pipe
    Broken pipe.

    +
  • +
  • <a href="#errno.proto" name="errno.proto"></a> proto
    Protocol error.

    +
  • +
  • <a href="#errno.protonosupport" name="errno.protonosupport"></a> protonosupport
    Protocol not supported.

    +
  • +
  • <a href="#errno.prototype" name="errno.prototype"></a> prototype
    Protocol wrong type for socket.

    +
  • +
  • <a href="#errno.range" name="errno.range"></a> range
    Result too large.

    +
  • +
  • <a href="#errno.rofs" name="errno.rofs"></a> rofs
    Read-only file system.

    +
  • +
  • <a href="#errno.spipe" name="errno.spipe"></a> spipe
    Invalid seek.

    +
  • +
  • <a href="#errno.srch" name="errno.srch"></a> srch
    No such process.

    +
  • +
  • <a href="#errno.stale" name="errno.stale"></a> stale
    Reserved.

    +
  • +
  • <a href="#errno.timedout" name="errno.timedout"></a> timedout
    Connection timed out.

    +
  • +
  • <a href="#errno.txtbsy" name="errno.txtbsy"></a> txtbsy
    Text file busy.

    +
  • +
  • <a href="#errno.xdev" name="errno.xdev"></a> xdev
    Cross-device link.

    +
  • +
  • <a href="#errno.notcapable" name="errno.notcapable"></a> notcapable
    Extension: Capabilities insufficient.

    +
  • +
+

<a href="#rights" name="rights"></a> rights: Flags(u64)

+

File descriptor rights, determining which actions may be performed.
Size: 8
Alignment: 8

+

Flags

+
    +
  • <a href="#rights.fd_datasync" name="rights.fd_datasync"></a> fd_datasync
    The right to invoke fd_datasync.
    If path_open is set, includes the right to invoke
    path_open with fdflags::dsync.

    +
  • +
  • <a href="#rights.fd_read" name="rights.fd_read"></a> fd_read
    The right to invoke fd_read and sock_recv.
    If rights::fd_seek is set, includes the right to invoke fd_pread.

    +
  • +
  • <a href="#rights.fd_seek" name="rights.fd_seek"></a> fd_seek
    The right to invoke fd_seek. This flag implies rights::fd_tell.

    +
  • +
  • <a href="#rights.fd_fdstat_set_flags" name="rights.fd_fdstat_set_flags"></a> fd_fdstat_set_flags
    The right to invoke fd_fdstat_set_flags.

    +
  • +
  • <a href="#rights.fd_sync" name="rights.fd_sync"></a> fd_sync
    The right to invoke fd_sync.
    If path_open is set, includes the right to invoke
    path_open with fdflags::rsync and fdflags::dsync.

    +
  • +
  • <a href="#rights.fd_tell" name="rights.fd_tell"></a> fd_tell
    The right to invoke fd_seek in such a way that the file offset
    remains unaltered (i.e., whence::cur with offset zero), or to
    invoke fd_tell.

    +
  • +
  • <a href="#rights.fd_write" name="rights.fd_write"></a> fd_write
    The right to invoke fd_write and sock_send.
    If rights::fd_seek is set, includes the right to invoke fd_pwrite.

    +
  • +
  • <a href="#rights.fd_advise" name="rights.fd_advise"></a> fd_advise
    The right to invoke fd_advise.

    +
  • +
  • <a href="#rights.fd_allocate" name="rights.fd_allocate"></a> fd_allocate
    The right to invoke fd_allocate.

    +
  • +
  • <a href="#rights.path_create_directory" name="rights.path_create_directory"></a> path_create_directory
    The right to invoke path_create_directory.

    +
  • +
  • <a href="#rights.path_create_file" name="rights.path_create_file"></a> path_create_file
    If path_open is set, the right to invoke path_open with oflags::creat.

    +
  • +
  • <a href="#rights.path_link_source" name="rights.path_link_source"></a> path_link_source
    The right to invoke path_link with the file descriptor as the
    source directory.

    +
  • +
  • <a href="#rights.path_link_target" name="rights.path_link_target"></a> path_link_target
    The right to invoke path_link with the file descriptor as the
    target directory.

    +
  • +
  • <a href="#rights.path_open" name="rights.path_open"></a> path_open
    The right to invoke path_open.

    +
  • +
  • <a href="#rights.fd_readdir" name="rights.fd_readdir"></a> fd_readdir
    The right to invoke fd_readdir.

    +
  • +
  • <a href="#rights.path_readlink" name="rights.path_readlink"></a> path_readlink
    The right to invoke path_readlink.

    +
  • +
  • <a href="#rights.path_rename_source" name="rights.path_rename_source"></a> path_rename_source
    The right to invoke path_rename with the file descriptor as the source directory.

    +
  • +
  • <a href="#rights.path_rename_target" name="rights.path_rename_target"></a> path_rename_target
    The right to invoke path_rename with the file descriptor as the target directory.

    +
  • +
  • <a href="#rights.path_filestat_get" name="rights.path_filestat_get"></a> path_filestat_get
    The right to invoke path_filestat_get.

    +
  • +
  • <a href="#rights.path_filestat_set_size" name="rights.path_filestat_set_size"></a> path_filestat_set_size
    The right to change a file's size (there is no path_filestat_set_size).
    If path_open is set, includes the right to invoke path_open with oflags::trunc.

    +
  • +
  • <a href="#rights.path_filestat_set_times" name="rights.path_filestat_set_times"></a> path_filestat_set_times
    The right to invoke path_filestat_set_times.

    +
  • +
  • <a href="#rights.fd_filestat_get" name="rights.fd_filestat_get"></a> fd_filestat_get
    The right to invoke fd_filestat_get.

    +
  • +
  • <a href="#rights.fd_filestat_set_size" name="rights.fd_filestat_set_size"></a> fd_filestat_set_size
    The right to invoke fd_filestat_set_size.

    +
  • +
  • <a href="#rights.fd_filestat_set_times" name="rights.fd_filestat_set_times"></a> fd_filestat_set_times
    The right to invoke fd_filestat_set_times.

    +
  • +
  • <a href="#rights.path_symlink" name="rights.path_symlink"></a> path_symlink
    The right to invoke path_symlink.

    +
  • +
  • <a href="#rights.path_remove_directory" name="rights.path_remove_directory"></a> path_remove_directory
    The right to invoke path_remove_directory.

    +
  • +
  • <a href="#rights.path_unlink_file" name="rights.path_unlink_file"></a> path_unlink_file
    The right to invoke path_unlink_file.

    +
  • +
  • <a href="#rights.poll_fd_readwrite" name="rights.poll_fd_readwrite"></a> poll_fd_readwrite
    If rights::fd_read is set, includes the right to invoke poll_oneoff to subscribe to eventtype::fd_read.
    If rights::fd_write is set, includes the right to invoke poll_oneoff to subscribe to eventtype::fd_write.

    +
  • +
  • <a href="#rights.sock_shutdown" name="rights.sock_shutdown"></a> sock_shutdown
    The right to invoke sock_shutdown.

    +
  • +
+

<a href="#fd" name="fd"></a> fd

+

A file descriptor handle.
Size: 4
Alignment: 4

+

Supertypes

+

<a href="#iovec" name="iovec"></a> iovec: Struct

+

A region of memory for scatter/gather reads.
Size: 8
Alignment: 4

+

Struct members

+
    +
  • <a href="#iovec.buf" name="iovec.buf"></a> buf: Pointer<u8>
    The address of the buffer to be filled.
    Offset: 0
  • +
  • <a href="#iovec.buf_len" name="iovec.buf_len"></a> buf_len: size
    The length of the buffer to be filled.
    Offset: 4

    <a href="#ciovec" name="ciovec"></a> ciovec: Struct

    +A region of memory for scatter/gather writes.
    Size: 8
    Alignment: 4

    Struct members

    +
  • +
  • <a href="#ciovec.buf" name="ciovec.buf"></a> buf: ConstPointer<u8>
    The address of the buffer to be written.
    Offset: 0
  • +
  • <a href="#ciovec.buf_len" name="ciovec.buf_len"></a> buf_len: size
    The length of the buffer to be written.
    Offset: 4

    <a href="#iovec_array" name="iovec_array"></a> iovec_array: Array<iovec>

    +Size: 8
    Alignment: 4

    <a href="#ciovec_array" name="ciovec_array"></a> ciovec_array: Array<ciovec>

    +Size: 8
    Alignment: 4

    <a href="#filedelta" name="filedelta"></a> filedelta: s64

    +Relative offset within a file.
    Size: 8
    Alignment: 8

    <a href="#whence" name="whence"></a> whence: Enum(u8)

    +The position relative to which to set the offset of the file descriptor.
    Size: 1
    Alignment: 1

    Variants

    +
  • +
  • <a href="#whence.set" name="whence.set"></a> set
    Seek relative to start-of-file.

    +
  • +
  • <a href="#whence.cur" name="whence.cur"></a> cur
    Seek relative to current position.

    +
  • +
  • <a href="#whence.end" name="whence.end"></a> end
    Seek relative to end-of-file.

    +
  • +
+

<a href="#dircookie" name="dircookie"></a> dircookie: u64

+

A reference to the offset of a directory entry.

+

The value 0 signifies the start of the directory.
Size: 8
Alignment: 8

+

<a href="#dirnamlen" name="dirnamlen"></a> dirnamlen: u32

+

The type for the $d_namlen field of $dirent.
Size: 4
Alignment: 4

+

<a href="#inode" name="inode"></a> inode: u64

+

File serial number that is unique within its file system.
Size: 8
Alignment: 8

+

<a href="#filetype" name="filetype"></a> filetype: Enum(u8)

+

The type of a file descriptor or file.
Size: 1
Alignment: 1

+

Variants

+
    +
  • <a href="#filetype.unknown" name="filetype.unknown"></a> unknown
    The type of the file descriptor or file is unknown or is different from any of the other types specified.

    +
  • +
  • <a href="#filetype.block_device" name="filetype.block_device"></a> block_device
    The file descriptor or file refers to a block device inode.

    +
  • +
  • <a href="#filetype.character_device" name="filetype.character_device"></a> character_device
    The file descriptor or file refers to a character device inode.

    +
  • +
  • <a href="#filetype.directory" name="filetype.directory"></a> directory
    The file descriptor or file refers to a directory inode.

    +
  • +
  • <a href="#filetype.regular_file" name="filetype.regular_file"></a> regular_file
    The file descriptor or file refers to a regular file inode.

    +
  • +
  • <a href="#filetype.socket_dgram" name="filetype.socket_dgram"></a> socket_dgram
    The file descriptor or file refers to a datagram socket.

    +
  • +
  • <a href="#filetype.socket_stream" name="filetype.socket_stream"></a> socket_stream
    The file descriptor or file refers to a byte-stream socket.

    +
  • +
  • <a href="#filetype.symbolic_link" name="filetype.symbolic_link"></a> symbolic_link
    The file refers to a symbolic link inode.

    +
  • +
+

<a href="#dirent" name="dirent"></a> dirent: Struct

+

A directory entry.
Size: 24
Alignment: 8

+

Struct members

+
    +
  • <a href="#dirent.d_next" name="dirent.d_next"></a> d_next: dircookie
    The offset of the next directory entry stored in this directory.
    Offset: 0
  • +
  • <a href="#dirent.d_ino" name="dirent.d_ino"></a> d_ino: inode
    The serial number of the file referred to by this directory entry.
    Offset: 8
  • +
  • <a href="#dirent.d_namlen" name="dirent.d_namlen"></a> d_namlen: dirnamlen
    The length of the name of the directory entry.
    Offset: 16
  • +
  • <a href="#dirent.d_type" name="dirent.d_type"></a> d_type: filetype
    The type of the file referred to by this directory entry.
    Offset: 20

    <a href="#advice" name="advice"></a> advice: Enum(u8)

    +File or memory access pattern advisory information.
    Size: 1
    Alignment: 1

    Variants

    +
  • +
  • <a href="#advice.normal" name="advice.normal"></a> normal
    The application has no advice to give on its behavior with respect to the specified data.

    +
  • +
  • <a href="#advice.sequential" name="advice.sequential"></a> sequential
    The application expects to access the specified data sequentially from lower offsets to higher offsets.

    +
  • +
  • <a href="#advice.random" name="advice.random"></a> random
    The application expects to access the specified data in a random order.

    +
  • +
  • <a href="#advice.willneed" name="advice.willneed"></a> willneed
    The application expects to access the specified data in the near future.

    +
  • +
  • <a href="#advice.dontneed" name="advice.dontneed"></a> dontneed
    The application expects that it will not access the specified data in the near future.

    +
  • +
  • <a href="#advice.noreuse" name="advice.noreuse"></a> noreuse
    The application expects to access the specified data once and then not reuse it thereafter.

    +
  • +
+

<a href="#fdflags" name="fdflags"></a> fdflags: Flags(u16)

+

File descriptor flags.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#fdflags.append" name="fdflags.append"></a> append
    Append mode: Data written to the file is always appended to the file's end.

    +
  • +
  • <a href="#fdflags.dsync" name="fdflags.dsync"></a> dsync
    Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized.

    +
  • +
  • <a href="#fdflags.nonblock" name="fdflags.nonblock"></a> nonblock
    Non-blocking mode.

    +
  • +
  • <a href="#fdflags.rsync" name="fdflags.rsync"></a> rsync
    Synchronized read I/O operations.

    +
  • +
  • <a href="#fdflags.sync" name="fdflags.sync"></a> sync
    Write according to synchronized I/O file integrity completion. In
    addition to synchronizing the data stored in the file, the implementation
    may also synchronously update the file's metadata.

    +
  • +
+

<a href="#fdstat" name="fdstat"></a> fdstat: Struct

+

File descriptor attributes.
Size: 24
Alignment: 8

+

Struct members

+
    +
  • <a href="#fdstat.fs_filetype" name="fdstat.fs_filetype"></a> fs_filetype: filetype
    File type.
    Offset: 0
  • +
  • <a href="#fdstat.fs_flags" name="fdstat.fs_flags"></a> fs_flags: fdflags
    File descriptor flags.
    Offset: 2
  • +
  • <a href="#fdstat.fs_rights_base" name="fdstat.fs_rights_base"></a> fs_rights_base: rights
    Rights that apply to this file descriptor.
    Offset: 8
  • +
  • <a href="#fdstat.fs_rights_inheriting" name="fdstat.fs_rights_inheriting"></a> fs_rights_inheriting: rights
    Maximum set of rights that may be installed on new file descriptors that
    are created through this file descriptor, e.g., through path_open.
    Offset: 16

    <a href="#device" name="device"></a> device: u64

    +Identifier for a device containing a file system. Can be used in combination
    with inode to uniquely identify a file or directory in the filesystem.
    Size: 8
    Alignment: 8

    <a href="#fstflags" name="fstflags"></a> fstflags: Flags(u16)

    +Which file time attributes to adjust.
    Size: 2
    Alignment: 2

    Flags

    +
  • +
  • <a href="#fstflags.atim" name="fstflags.atim"></a> atim
    Adjust the last data access timestamp to the value stored in filestat::atim.

    +
  • +
  • <a href="#fstflags.atim_now" name="fstflags.atim_now"></a> atim_now
    Adjust the last data access timestamp to the time of clock clockid::realtime.

    +
  • +
  • <a href="#fstflags.mtim" name="fstflags.mtim"></a> mtim
    Adjust the last data modification timestamp to the value stored in filestat::mtim.

    +
  • +
  • <a href="#fstflags.mtim_now" name="fstflags.mtim_now"></a> mtim_now
    Adjust the last data modification timestamp to the time of clock clockid::realtime.

    +
  • +
+

<a href="#lookupflags" name="lookupflags"></a> lookupflags: Flags(u32)

+

Flags determining the method of how paths are resolved.
Size: 4
Alignment: 4

+

Flags

+
    +
  • <a href="#lookupflags.symlink_follow" name="lookupflags.symlink_follow"></a> symlink_follow
    As long as the resolved path corresponds to a symbolic link, it is expanded.
  • +
+

<a href="#oflags" name="oflags"></a> oflags: Flags(u16)

+

Open flags used by path_open.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#oflags.creat" name="oflags.creat"></a> creat
    Create file if it does not exist.

    +
  • +
  • <a href="#oflags.directory" name="oflags.directory"></a> directory
    Fail if not a directory.

    +
  • +
  • <a href="#oflags.excl" name="oflags.excl"></a> excl
    Fail if file already exists.

    +
  • +
  • <a href="#oflags.trunc" name="oflags.trunc"></a> trunc
    Truncate file to size 0.

    +
  • +
+

<a href="#linkcount" name="linkcount"></a> linkcount: u64

+

Number of hard links to an inode.
Size: 8
Alignment: 8

+

<a href="#filestat" name="filestat"></a> filestat: Struct

+

File attributes.
Size: 64
Alignment: 8

+

Struct members

+
    +
  • <a href="#filestat.dev" name="filestat.dev"></a> dev: device
    Device ID of device containing the file.
    Offset: 0
  • +
  • <a href="#filestat.ino" name="filestat.ino"></a> ino: inode
    File serial number.
    Offset: 8
  • +
  • <a href="#filestat.filetype" name="filestat.filetype"></a> filetype: filetype
    File type.
    Offset: 16
  • +
  • <a href="#filestat.nlink" name="filestat.nlink"></a> nlink: linkcount
    Number of hard links to the file.
    Offset: 24
  • +
  • <a href="#filestat.size" name="filestat.size"></a> size: filesize
    For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link.
    Offset: 32
  • +
  • <a href="#filestat.atim" name="filestat.atim"></a> atim: timestamp
    Last data access timestamp.
    Offset: 40
  • +
  • <a href="#filestat.mtim" name="filestat.mtim"></a> mtim: timestamp
    Last data modification timestamp.
    Offset: 48
  • +
  • <a href="#filestat.ctim" name="filestat.ctim"></a> ctim: timestamp
    Last file status change timestamp.
    Offset: 56

    <a href="#userdata" name="userdata"></a> userdata: u64

    +User-provided value that may be attached to objects that is retained when
    extracted from the implementation.
    Size: 8
    Alignment: 8

    <a href="#eventtype" name="eventtype"></a> eventtype: Enum(u8)

    +Type of a subscription to an event or its occurrence.
    Size: 1
    Alignment: 1

    Variants

    +
  • +
  • <a href="#eventtype.clock" name="eventtype.clock"></a> clock
    The time value of clock subscription_clock::id has
    reached timestamp subscription_clock::timeout.

    +
  • +
  • <a href="#eventtype.fd_read" name="eventtype.fd_read"></a> fd_read
    File descriptor subscription_fd_readwrite::file_descriptor has data
    available for reading. This event always triggers for regular files.

    +
  • +
  • <a href="#eventtype.fd_write" name="eventtype.fd_write"></a> fd_write
    File descriptor subscription_fd_readwrite::file_descriptor has capacity
    available for writing. This event always triggers for regular files.

    +
  • +
+

<a href="#eventrwflags" name="eventrwflags"></a> eventrwflags: Flags(u16)

+

The state of the file descriptor subscribed to with
eventtype::fd_read or eventtype::fd_write.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#eventrwflags.fd_readwrite_hangup" name="eventrwflags.fd_readwrite_hangup"></a> fd_readwrite_hangup
    The peer of this socket has closed or disconnected.
  • +
+

<a href="#event_fd_readwrite" name="event_fd_readwrite"></a> event_fd_readwrite: Struct

+

The contents of an $event when type is eventtype::fd_read or
eventtype::fd_write.
Size: 16
Alignment: 8

+

Struct members

+
    +
  • <a href="#event_fd_readwrite.nbytes" name="event_fd_readwrite.nbytes"></a> nbytes: filesize
    The number of bytes available for reading or writing.
    Offset: 0
  • +
  • <a href="#event_fd_readwrite.flags" name="event_fd_readwrite.flags"></a> flags: eventrwflags
    The state of the file descriptor.
    Offset: 8

    <a href="#event" name="event"></a> event: Struct

    +An event that occurred.
    Size: 32
    Alignment: 8

    Struct members

    +
  • +
  • <a href="#event.userdata" name="event.userdata"></a> userdata: userdata
    User-provided value that got attached to subscription::userdata.
    Offset: 0
  • +
  • <a href="#event.error" name="event.error"></a> error: errno
    If non-zero, an error that occurred while processing the subscription request.
    Offset: 8
  • +
  • <a href="#event.type" name="event.type"></a> type: eventtype
    The type of event that occured
    Offset: 10
  • +
  • <a href="#event.fd_readwrite" name="event.fd_readwrite"></a> fd_readwrite: event_fd_readwrite
    The contents of the event, if it is an eventtype::fd_read or
    eventtype::fd_write. eventtype::clock events ignore this field.
    Offset: 16

    <a href="#subclockflags" name="subclockflags"></a> subclockflags: Flags(u16)

    +Flags determining how to interpret the timestamp provided in
    subscription_clock::timeout.
    Size: 2
    Alignment: 2

    Flags

    +
  • +
  • <a href="#subclockflags.subscription_clock_abstime" name="subclockflags.subscription_clock_abstime"></a> subscription_clock_abstime
    If set, treat the timestamp provided in
    subscription_clock::timeout as an absolute timestamp of clock
    subscription_clock::id. If clear, treat the timestamp
    provided in subscription_clock::timeout relative to the
    current time value of clock subscription_clock::id.
  • +
+

<a href="#subscription_clock" name="subscription_clock"></a> subscription_clock: Struct

+

The contents of a subscription when type is eventtype::clock.
Size: 32
Alignment: 8

+

Struct members

+
    +
  • <a href="#subscription_clock.id" name="subscription_clock.id"></a> id: clockid
    The clock against which to compare the timestamp.
    Offset: 0
  • +
  • <a href="#subscription_clock.timeout" name="subscription_clock.timeout"></a> timeout: timestamp
    The absolute or relative timestamp.
    Offset: 8
  • +
  • <a href="#subscription_clock.precision" name="subscription_clock.precision"></a> precision: timestamp
    The amount of time that the implementation may wait additionally
    to coalesce with other events.
    Offset: 16
  • +
  • <a href="#subscription_clock.flags" name="subscription_clock.flags"></a> flags: subclockflags
    Flags specifying whether the timeout is absolute or relative
    Offset: 24

    <a href="#subscription_fd_readwrite" name="subscription_fd_readwrite"></a> subscription_fd_readwrite: Struct

    +The contents of a subscription when type is type is
    eventtype::fd_read or eventtype::fd_write.
    Size: 4
    Alignment: 4

    Struct members

    +
  • +
  • <a href="#subscription_fd_readwrite.file_descriptor" name="subscription_fd_readwrite.file_descriptor"></a> file_descriptor: fd
    The file descriptor on which to wait for it to become ready for reading or writing.
    Offset: 0

    <a href="#subscription_u" name="subscription_u"></a> subscription_u: Union

    +The contents of a subscription.
    Size: 40
    Alignment: 8

    Union Layout

    +
  • +
  • tag_size: 1
  • +
  • tag_align: 1
  • +
  • contents_offset: 8
  • +
  • contents_size: 32
  • +
  • contents_align: 8

    Union variants

    +
  • +
  • <a href="#subscription_u.clock" name="subscription_u.clock"></a> clock: subscription_clock

    +
  • +
  • <a href="#subscription_u.fd_read" name="subscription_u.fd_read"></a> fd_read: subscription_fd_readwrite

    +
  • +
  • <a href="#subscription_u.fd_write" name="subscription_u.fd_write"></a> fd_write: subscription_fd_readwrite

    +
  • +
+

<a href="#subscription" name="subscription"></a> subscription: Struct

+

Subscription to an event.
Size: 48
Alignment: 8

+

Struct members

+
    +
  • <a href="#subscription.userdata" name="subscription.userdata"></a> userdata: userdata
    User-provided value that is attached to the subscription in the
    implementation and returned through event::userdata.
    Offset: 0
  • +
  • <a href="#subscription.u" name="subscription.u"></a> u: subscription_u
    The type of the event to which to subscribe, and its contents
    Offset: 8

    <a href="#exitcode" name="exitcode"></a> exitcode: u32

    +Exit code generated by a process when exiting.
    Size: 4
    Alignment: 4

    <a href="#signal" name="signal"></a> signal: Enum(u8)

    +Signal condition.
    Size: 1
    Alignment: 1

    Variants

    +
  • +
  • <a href="#signal.none" name="signal.none"></a> none
    No signal. Note that POSIX has special semantics for kill(pid, 0),
    so this value is reserved.

    +
  • +
  • <a href="#signal.hup" name="signal.hup"></a> hup
    Hangup.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.int" name="signal.int"></a> int
    Terminate interrupt signal.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.quit" name="signal.quit"></a> quit
    Terminal quit signal.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.ill" name="signal.ill"></a> ill
    Illegal instruction.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.trap" name="signal.trap"></a> trap
    Trace/breakpoint trap.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.abrt" name="signal.abrt"></a> abrt
    Process abort signal.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.bus" name="signal.bus"></a> bus
    Access to an undefined portion of a memory object.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.fpe" name="signal.fpe"></a> fpe
    Erroneous arithmetic operation.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.kill" name="signal.kill"></a> kill
    Kill.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.usr1" name="signal.usr1"></a> usr1
    User-defined signal 1.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.segv" name="signal.segv"></a> segv
    Invalid memory reference.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.usr2" name="signal.usr2"></a> usr2
    User-defined signal 2.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.pipe" name="signal.pipe"></a> pipe
    Write on a pipe with no one to read it.
    Action: Ignored.

    +
  • +
  • <a href="#signal.alrm" name="signal.alrm"></a> alrm
    Alarm clock.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.term" name="signal.term"></a> term
    Termination signal.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.chld" name="signal.chld"></a> chld
    Child process terminated, stopped, or continued.
    Action: Ignored.

    +
  • +
  • <a href="#signal.cont" name="signal.cont"></a> cont
    Continue executing, if stopped.
    Action: Continues executing, if stopped.

    +
  • +
  • <a href="#signal.stop" name="signal.stop"></a> stop
    Stop executing.
    Action: Stops executing.

    +
  • +
  • <a href="#signal.tstp" name="signal.tstp"></a> tstp
    Terminal stop signal.
    Action: Stops executing.

    +
  • +
  • <a href="#signal.ttin" name="signal.ttin"></a> ttin
    Background process attempting read.
    Action: Stops executing.

    +
  • +
  • <a href="#signal.ttou" name="signal.ttou"></a> ttou
    Background process attempting write.
    Action: Stops executing.

    +
  • +
  • <a href="#signal.urg" name="signal.urg"></a> urg
    High bandwidth data is available at a socket.
    Action: Ignored.

    +
  • +
  • <a href="#signal.xcpu" name="signal.xcpu"></a> xcpu
    CPU time limit exceeded.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.xfsz" name="signal.xfsz"></a> xfsz
    File size limit exceeded.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.vtalrm" name="signal.vtalrm"></a> vtalrm
    Virtual timer expired.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.prof" name="signal.prof"></a> prof
    Profiling timer expired.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.winch" name="signal.winch"></a> winch
    Window changed.
    Action: Ignored.

    +
  • +
  • <a href="#signal.poll" name="signal.poll"></a> poll
    I/O possible.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.pwr" name="signal.pwr"></a> pwr
    Power failure.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.sys" name="signal.sys"></a> sys
    Bad system call.
    Action: Terminates the process.

    +
  • +
+

<a href="#riflags" name="riflags"></a> riflags: Flags(u16)

+

Flags provided to sock_recv.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#riflags.recv_peek" name="riflags.recv_peek"></a> recv_peek
    Returns the message without removing it from the socket's receive queue.

    +
  • +
  • <a href="#riflags.recv_waitall" name="riflags.recv_waitall"></a> recv_waitall
    On byte-stream sockets, block until the full amount of data can be returned.

    +
  • +
+

<a href="#roflags" name="roflags"></a> roflags: Flags(u16)

+

Flags returned by sock_recv.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#roflags.recv_data_truncated" name="roflags.recv_data_truncated"></a> recv_data_truncated
    Returned by sock_recv: Message data has been truncated.
  • +
+

<a href="#siflags" name="siflags"></a> siflags: u16

+

Flags provided to sock_send. As there are currently no flags
defined, it must be set to zero.
Size: 2
Alignment: 2

+

<a href="#sdflags" name="sdflags"></a> sdflags: Flags(u8)

+

Which channels on a socket to shut down.
Size: 1
Alignment: 1

+

Flags

+
    +
  • <a href="#sdflags.rd" name="sdflags.rd"></a> rd
    Disables further receive operations.

    +
  • +
  • <a href="#sdflags.wr" name="sdflags.wr"></a> wr
    Disables further send operations.

    +
  • +
+

<a href="#preopentype" name="preopentype"></a> preopentype: Enum(u8)

+

Identifiers for preopened capabilities.
Size: 1
Alignment: 1

+

Variants

+
    +
  • <a href="#preopentype.dir" name="preopentype.dir"></a> dir
    A pre-opened directory.
  • +
+

<a href="#prestat_dir" name="prestat_dir"></a> prestat_dir: Struct

+

The contents of a $prestat when type is preopentype::dir.
Size: 4
Alignment: 4

+

Struct members

+
    +
  • <a href="#prestat_dir.pr_name_len" name="prestat_dir.pr_name_len"></a> pr_name_len: size
    The length of the directory name for use with fd_prestat_dir_name.
    Offset: 0

    <a href="#prestat" name="prestat"></a> prestat: Union

    +Information about a pre-opened capability.
    Size: 8
    Alignment: 4

    Union Layout

    +
  • +
  • tag_size: 1
  • +
  • tag_align: 1
  • +
  • contents_offset: 4
  • +
  • contents_size: 4
  • +
  • contents_align: 4

    Union variants

    +
  • +
  • <a href="#prestat.dir" name="prestat.dir"></a> dir: prestat_dir
  • +
+

Modules

+

<a href="#wasi_snapshot_preview1" name="wasi_snapshot_preview1"></a> wasi_snapshot_preview1

+

Imports

+

Memory

+

Functions

+
+

<a href="#args_get" name="args_get"></a> args_get(argv: Pointer<Pointer<u8>>, argv_buf: Pointer<u8>) -> errno

+

Read command-line argument data.
The size of the array should match that returned by args_sizes_get

+
Params
+
    +
  • <a href="#args_get.argv" name="args_get.argv"></a> argv: Pointer<Pointer<u8>>

    +
  • +
  • <a href="#args_get.argv_buf" name="args_get.argv_buf"></a> argv_buf: Pointer<u8>

    +
  • +
+
Results
+
    +
  • <a href="#args_get.error" name="args_get.error"></a> error: errno
  • +
+
+

<a href="#args_sizes_get" name="args_sizes_get"></a> args_sizes_get() -> (errno, size, size)

+

Return command-line argument data sizes.

+
Params
+
Results
+
    +
  • <a href="#args_sizes_get.error" name="args_sizes_get.error"></a> error: errno

    +
  • +
  • <a href="#args_sizes_get.argc" name="args_sizes_get.argc"></a> argc: size
    The number of arguments.

    +
  • +
  • <a href="#args_sizes_get.argv_buf_size" name="args_sizes_get.argv_buf_size"></a> argv_buf_size: size
    The size of the argument string data.

    +
  • +
+
+

<a href="#environ_get" name="environ_get"></a> environ_get(environ: Pointer<Pointer<u8>>, environ_buf: Pointer<u8>) -> errno

+

Read environment variable data.
The sizes of the buffers should match that returned by environ_sizes_get.

+
Params
+
    +
  • <a href="#environ_get.environ" name="environ_get.environ"></a> environ: Pointer<Pointer<u8>>

    +
  • +
  • <a href="#environ_get.environ_buf" name="environ_get.environ_buf"></a> environ_buf: Pointer<u8>

    +
  • +
+
Results
+
    +
  • <a href="#environ_get.error" name="environ_get.error"></a> error: errno
  • +
+
+

<a href="#environ_sizes_get" name="environ_sizes_get"></a> environ_sizes_get() -> (errno, size, size)

+

Return environment variable data sizes.

+
Params
+
Results
+
    +
  • <a href="#environ_sizes_get.error" name="environ_sizes_get.error"></a> error: errno

    +
  • +
  • <a href="#environ_sizes_get.environc" name="environ_sizes_get.environc"></a> environc: size
    The number of environment variable arguments.

    +
  • +
  • <a href="#environ_sizes_get.environ_buf_size" name="environ_sizes_get.environ_buf_size"></a> environ_buf_size: size
    The size of the environment variable data.

    +
  • +
+
+

<a href="#clock_res_get" name="clock_res_get"></a> clock_res_get(id: clockid) -> (errno, timestamp)

+

Return the resolution of a clock.
Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks,
return errno::inval.
Note: This is similar to clock_getres in POSIX.

+
Params
+
    +
  • <a href="#clock_res_get.id" name="clock_res_get.id"></a> id: clockid
    The clock for which to return the resolution.
  • +
+
Results
+
    +
  • <a href="#clock_res_get.error" name="clock_res_get.error"></a> error: errno

    +
  • +
  • <a href="#clock_res_get.resolution" name="clock_res_get.resolution"></a> resolution: timestamp
    The resolution of the clock.

    +
  • +
+
+

<a href="#clock_time_get" name="clock_time_get"></a> clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)

+

Return the time value of a clock.
Note: This is similar to clock_gettime in POSIX.

+
Params
+
    +
  • <a href="#clock_time_get.id" name="clock_time_get.id"></a> id: clockid
    The clock for which to return the time.

    +
  • +
  • <a href="#clock_time_get.precision" name="clock_time_get.precision"></a> precision: timestamp
    The maximum lag (exclusive) that the returned time value may have, compared to its actual value.

    +
  • +
+
Results
+
    +
  • <a href="#clock_time_get.error" name="clock_time_get.error"></a> error: errno

    +
  • +
  • <a href="#clock_time_get.time" name="clock_time_get.time"></a> time: timestamp
    The time value of the clock.

    +
  • +
+
+

<a href="#fd_advise" name="fd_advise"></a> fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno

+

Provide file advisory information on a file descriptor.
Note: This is similar to posix_fadvise in POSIX.

+
Params
+
    +
  • <a href="#fd_advise.fd" name="fd_advise.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_advise.offset" name="fd_advise.offset"></a> offset: filesize
    The offset within the file to which the advisory applies.

    +
  • +
  • <a href="#fd_advise.len" name="fd_advise.len"></a> len: filesize
    The length of the region to which the advisory applies.

    +
  • +
  • <a href="#fd_advise.advice" name="fd_advise.advice"></a> advice: advice
    The advice.

    +
  • +
+
Results
+
    +
  • <a href="#fd_advise.error" name="fd_advise.error"></a> error: errno
  • +
+
+

<a href="#fd_allocate" name="fd_allocate"></a> fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno

+

Force the allocation of space in a file.
Note: This is similar to posix_fallocate in POSIX.

+
Params
+
    +
  • <a href="#fd_allocate.fd" name="fd_allocate.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_allocate.offset" name="fd_allocate.offset"></a> offset: filesize
    The offset at which to start the allocation.

    +
  • +
  • <a href="#fd_allocate.len" name="fd_allocate.len"></a> len: filesize
    The length of the area that is allocated.

    +
  • +
+
Results
+
    +
  • <a href="#fd_allocate.error" name="fd_allocate.error"></a> error: errno
  • +
+
+

<a href="#fd_close" name="fd_close"></a> fd_close(fd: fd) -> errno

+

Close a file descriptor.
Note: This is similar to close in POSIX.

+
Params
+
    +
  • <a href="#fd_close.fd" name="fd_close.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_close.error" name="fd_close.error"></a> error: errno
  • +
+
+

<a href="#fd_datasync" name="fd_datasync"></a> fd_datasync(fd: fd) -> errno

+

Synchronize the data of a file to disk.
Note: This is similar to fdatasync in POSIX.

+
Params
+
    +
  • <a href="#fd_datasync.fd" name="fd_datasync.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_datasync.error" name="fd_datasync.error"></a> error: errno
  • +
+
+

<a href="#fd_fdstat_get" name="fd_fdstat_get"></a> fd_fdstat_get(fd: fd) -> (errno, fdstat)

+

Get the attributes of a file descriptor.
Note: This returns similar flags to fsync(fd, F_GETFL) in POSIX, as well as additional fields.

+
Params
+
    +
  • <a href="#fd_fdstat_get.fd" name="fd_fdstat_get.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_fdstat_get.error" name="fd_fdstat_get.error"></a> error: errno

    +
  • +
  • <a href="#fd_fdstat_get.stat" name="fd_fdstat_get.stat"></a> stat: fdstat
    The buffer where the file descriptor's attributes are stored.

    +
  • +
+
+

<a href="#fd_fdstat_set_flags" name="fd_fdstat_set_flags"></a> fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno

+

Adjust the flags associated with a file descriptor.
Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

+
Params
+
    +
  • <a href="#fd_fdstat_set_flags.fd" name="fd_fdstat_set_flags.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_fdstat_set_flags.flags" name="fd_fdstat_set_flags.flags"></a> flags: fdflags
    The desired values of the file descriptor flags.

    +
  • +
+
Results
+
    +
  • <a href="#fd_fdstat_set_flags.error" name="fd_fdstat_set_flags.error"></a> error: errno
  • +
+
+

<a href="#fd_fdstat_set_rights" name="fd_fdstat_set_rights"></a> fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno

+

Adjust the rights associated with a file descriptor.
This can only be used to remove rights, and returns errno::notcapable if called in a way that would attempt to add rights

+
Params
+
    +
  • <a href="#fd_fdstat_set_rights.fd" name="fd_fdstat_set_rights.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_fdstat_set_rights.fs_rights_base" name="fd_fdstat_set_rights.fs_rights_base"></a> fs_rights_base: rights
    The desired rights of the file descriptor.

    +
  • +
  • <a href="#fd_fdstat_set_rights.fs_rights_inheriting" name="fd_fdstat_set_rights.fs_rights_inheriting"></a> fs_rights_inheriting: rights

    +
  • +
+
Results
+
    +
  • <a href="#fd_fdstat_set_rights.error" name="fd_fdstat_set_rights.error"></a> error: errno
  • +
+
+

<a href="#fd_filestat_get" name="fd_filestat_get"></a> fd_filestat_get(fd: fd) -> (errno, filestat)

+

Return the attributes of an open file.

+
Params
+
    +
  • <a href="#fd_filestat_get.fd" name="fd_filestat_get.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_filestat_get.error" name="fd_filestat_get.error"></a> error: errno

    +
  • +
  • <a href="#fd_filestat_get.buf" name="fd_filestat_get.buf"></a> buf: filestat
    The buffer where the file's attributes are stored.

    +
  • +
+
+

<a href="#fd_filestat_set_size" name="fd_filestat_set_size"></a> fd_filestat_set_size(fd: fd, size: filesize) -> errno

+

Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.
Note: This is similar to ftruncate in POSIX.

+
Params
+
    +
  • <a href="#fd_filestat_set_size.fd" name="fd_filestat_set_size.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_filestat_set_size.size" name="fd_filestat_set_size.size"></a> size: filesize
    The desired file size.

    +
  • +
+
Results
+
    +
  • <a href="#fd_filestat_set_size.error" name="fd_filestat_set_size.error"></a> error: errno
  • +
+
+

<a href="#fd_filestat_set_times" name="fd_filestat_set_times"></a> fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno

+

Adjust the timestamps of an open file or directory.
Note: This is similar to futimens in POSIX.

+
Params
+
    +
  • <a href="#fd_filestat_set_times.fd" name="fd_filestat_set_times.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_filestat_set_times.atim" name="fd_filestat_set_times.atim"></a> atim: timestamp
    The desired values of the data access timestamp.

    +
  • +
  • <a href="#fd_filestat_set_times.mtim" name="fd_filestat_set_times.mtim"></a> mtim: timestamp
    The desired values of the data modification timestamp.

    +
  • +
  • <a href="#fd_filestat_set_times.fst_flags" name="fd_filestat_set_times.fst_flags"></a> fst_flags: fstflags
    A bitmask indicating which timestamps to adjust.

    +
  • +
+
Results
+
    +
  • <a href="#fd_filestat_set_times.error" name="fd_filestat_set_times.error"></a> error: errno
  • +
+
+

<a href="#fd_pread" name="fd_pread"></a> fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)

+

Read from a file descriptor, without using and updating the file descriptor's offset.
Note: This is similar to preadv in POSIX.

+
Params
+
    +
  • <a href="#fd_pread.fd" name="fd_pread.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_pread.iovs" name="fd_pread.iovs"></a> iovs: iovec_array
    List of scatter/gather vectors in which to store data.

    +
  • +
  • <a href="#fd_pread.offset" name="fd_pread.offset"></a> offset: filesize
    The offset within the file at which to read.

    +
  • +
+
Results
+
    +
  • <a href="#fd_pread.error" name="fd_pread.error"></a> error: errno

    +
  • +
  • <a href="#fd_pread.nread" name="fd_pread.nread"></a> nread: size
    The number of bytes read.

    +
  • +
+
+

<a href="#fd_prestat_get" name="fd_prestat_get"></a> fd_prestat_get(fd: fd) -> (errno, prestat)

+

Return a description of the given preopened file descriptor.

+
Params
+
    +
  • <a href="#fd_prestat_get.fd" name="fd_prestat_get.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_prestat_get.error" name="fd_prestat_get.error"></a> error: errno

    +
  • +
  • <a href="#fd_prestat_get.buf" name="fd_prestat_get.buf"></a> buf: prestat
    The buffer where the description is stored.

    +
  • +
+
+

<a href="#fd_prestat_dir_name" name="fd_prestat_dir_name"></a> fd_prestat_dir_name(fd: fd, path: Pointer<u8>, path_len: size) -> errno

+

Return a description of the given preopened file descriptor.

+
Params
+
    +
  • <a href="#fd_prestat_dir_name.fd" name="fd_prestat_dir_name.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_prestat_dir_name.path" name="fd_prestat_dir_name.path"></a> path: Pointer<u8>
    A buffer into which to write the preopened directory name.

    +
  • +
  • <a href="#fd_prestat_dir_name.path_len" name="fd_prestat_dir_name.path_len"></a> path_len: size

    +
  • +
+
Results
+
    +
  • <a href="#fd_prestat_dir_name.error" name="fd_prestat_dir_name.error"></a> error: errno
  • +
+
+

<a href="#fd_pwrite" name="fd_pwrite"></a> fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)

+

Write to a file descriptor, without using and updating the file descriptor's offset.
Note: This is similar to pwritev in POSIX.

+
Params
+
    +
  • <a href="#fd_pwrite.fd" name="fd_pwrite.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_pwrite.iovs" name="fd_pwrite.iovs"></a> iovs: ciovec_array
    List of scatter/gather vectors from which to retrieve data.

    +
  • +
  • <a href="#fd_pwrite.offset" name="fd_pwrite.offset"></a> offset: filesize
    The offset within the file at which to write.

    +
  • +
+
Results
+
    +
  • <a href="#fd_pwrite.error" name="fd_pwrite.error"></a> error: errno

    +
  • +
  • <a href="#fd_pwrite.nwritten" name="fd_pwrite.nwritten"></a> nwritten: size
    The number of bytes written.

    +
  • +
+
+

<a href="#fd_read" name="fd_read"></a> fd_read(fd: fd, iovs: iovec_array) -> (errno, size)

+

Read from a file descriptor.
Note: This is similar to readv in POSIX.

+
Params
+
    +
  • <a href="#fd_read.fd" name="fd_read.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_read.iovs" name="fd_read.iovs"></a> iovs: iovec_array
    List of scatter/gather vectors to which to store data.

    +
  • +
+
Results
+
    +
  • <a href="#fd_read.error" name="fd_read.error"></a> error: errno

    +
  • +
  • <a href="#fd_read.nread" name="fd_read.nread"></a> nread: size
    The number of bytes read.

    +
  • +
+
+ +

Read directory entries from a directory.
When successful, the contents of the output buffer consist of a sequence of
directory entries. Each directory entry consists of a dirent_t object,
followed by dirent_t::d_namlen bytes holding the name of the directory
entry.
This function fills the output buffer as much as possible, potentially
truncating the last directory entry. This allows the caller to grow its
read buffer size in case it's too small to fit a single large directory
entry, or skip the oversized directory entry.

+
Params
+
    +
  • <a href="#fd_readdir.fd" name="fd_readdir.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_readdir.buf" name="fd_readdir.buf"></a> buf: Pointer<u8>
    The buffer where directory entries are stored

    +
  • +
  • <a href="#fd_readdir.buf_len" name="fd_readdir.buf_len"></a> buf_len: size

    +
  • +
  • <a href="#fd_readdir.cookie" name="fd_readdir.cookie"></a> cookie: dircookie
    The location within the directory to start reading

    +
  • +
+
Results
+
    +
  • <a href="#fd_readdir.error" name="fd_readdir.error"></a> error: errno

    +
  • +
  • <a href="#fd_readdir.bufused" name="fd_readdir.bufused"></a> bufused: size
    The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached.

    +
  • +
+
+

<a href="#fd_renumber" name="fd_renumber"></a> fd_renumber(fd: fd, to: fd) -> errno

+

Atomically replace a file descriptor by renumbering another file descriptor.
Due to the strong focus on thread safety, this environment does not provide
a mechanism to duplicate or renumber a file descriptor to an arbitrary
number, like dup2(). This would be prone to race conditions, as an actual
file descriptor with the same number could be allocated by a different
thread at the same time.
This function provides a way to atomically renumber file descriptors, which
would disappear if dup2() were to be removed entirely.

+
Params
+
    +
  • <a href="#fd_renumber.fd" name="fd_renumber.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_renumber.to" name="fd_renumber.to"></a> to: fd
    The file descriptor to overwrite.

    +
  • +
+
Results
+
    +
  • <a href="#fd_renumber.error" name="fd_renumber.error"></a> error: errno
  • +
+
+

<a href="#fd_seek" name="fd_seek"></a> fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)

+

Move the offset of a file descriptor.
Note: This is similar to lseek in POSIX.

+
Params
+
    +
  • <a href="#fd_seek.fd" name="fd_seek.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_seek.offset" name="fd_seek.offset"></a> offset: filedelta
    The number of bytes to move.

    +
  • +
  • <a href="#fd_seek.whence" name="fd_seek.whence"></a> whence: whence
    The base from which the offset is relative.

    +
  • +
+
Results
+
    +
  • <a href="#fd_seek.error" name="fd_seek.error"></a> error: errno

    +
  • +
  • <a href="#fd_seek.newoffset" name="fd_seek.newoffset"></a> newoffset: filesize
    The new offset of the file descriptor, relative to the start of the file.

    +
  • +
+
+

<a href="#fd_sync" name="fd_sync"></a> fd_sync(fd: fd) -> errno

+

Synchronize the data and metadata of a file to disk.
Note: This is similar to fsync in POSIX.

+
Params
+
    +
  • <a href="#fd_sync.fd" name="fd_sync.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_sync.error" name="fd_sync.error"></a> error: errno
  • +
+
+

<a href="#fd_tell" name="fd_tell"></a> fd_tell(fd: fd) -> (errno, filesize)

+

Return the current offset of a file descriptor.
Note: This is similar to lseek(fd, 0, SEEK_CUR) in POSIX.

+
Params
+
    +
  • <a href="#fd_tell.fd" name="fd_tell.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_tell.error" name="fd_tell.error"></a> error: errno

    +
  • +
  • <a href="#fd_tell.offset" name="fd_tell.offset"></a> offset: filesize
    The current offset of the file descriptor, relative to the start of the file.

    +
  • +
+
+

<a href="#fd_write" name="fd_write"></a> fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)

+

Write to a file descriptor.
Note: This is similar to writev in POSIX.

+
Params
+
    +
  • <a href="#fd_write.fd" name="fd_write.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_write.iovs" name="fd_write.iovs"></a> iovs: ciovec_array
    List of scatter/gather vectors from which to retrieve data.

    +
  • +
+
Results
+
    +
  • <a href="#fd_write.error" name="fd_write.error"></a> error: errno

    +
  • +
  • <a href="#fd_write.nwritten" name="fd_write.nwritten"></a> nwritten: size
    The number of bytes written.

    +
  • +
+
+

<a href="#path_create_directory" name="path_create_directory"></a> path_create_directory(fd: fd, path: string) -> errno

+

Create a directory.
Note: This is similar to mkdirat in POSIX.

+
Params
+
    +
  • <a href="#path_create_directory.fd" name="path_create_directory.fd"></a> fd: fd

    +
  • +
  • <a href="#path_create_directory.path" name="path_create_directory.path"></a> path: string
    The path at which to create the directory.

    +
  • +
+
Results
+
    +
  • <a href="#path_create_directory.error" name="path_create_directory.error"></a> error: errno
  • +
+
+

<a href="#path_filestat_get" name="path_filestat_get"></a> path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)

+

Return the attributes of a file or directory.
Note: This is similar to stat in POSIX.

+
Params
+
    +
  • <a href="#path_filestat_get.fd" name="path_filestat_get.fd"></a> fd: fd

    +
  • +
  • <a href="#path_filestat_get.flags" name="path_filestat_get.flags"></a> flags: lookupflags
    Flags determining the method of how the path is resolved.

    +
  • +
  • <a href="#path_filestat_get.path" name="path_filestat_get.path"></a> path: string
    The path of the file or directory to inspect.

    +
  • +
+
Results
+
    +
  • <a href="#path_filestat_get.error" name="path_filestat_get.error"></a> error: errno

    +
  • +
  • <a href="#path_filestat_get.buf" name="path_filestat_get.buf"></a> buf: filestat
    The buffer where the file's attributes are stored.

    +
  • +
+
+

<a href="#path_filestat_set_times" name="path_filestat_set_times"></a> path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno

+

Adjust the timestamps of a file or directory.
Note: This is similar to utimensat in POSIX.

+
Params
+
    +
  • <a href="#path_filestat_set_times.fd" name="path_filestat_set_times.fd"></a> fd: fd

    +
  • +
  • <a href="#path_filestat_set_times.flags" name="path_filestat_set_times.flags"></a> flags: lookupflags
    Flags determining the method of how the path is resolved.

    +
  • +
  • <a href="#path_filestat_set_times.path" name="path_filestat_set_times.path"></a> path: string
    The path of the file or directory to operate on.

    +
  • +
  • <a href="#path_filestat_set_times.atim" name="path_filestat_set_times.atim"></a> atim: timestamp
    The desired values of the data access timestamp.

    +
  • +
  • <a href="#path_filestat_set_times.mtim" name="path_filestat_set_times.mtim"></a> mtim: timestamp
    The desired values of the data modification timestamp.

    +
  • +
  • <a href="#path_filestat_set_times.fst_flags" name="path_filestat_set_times.fst_flags"></a> fst_flags: fstflags
    A bitmask indicating which timestamps to adjust.

    +
  • +
+
Results
+
    +
  • <a href="#path_filestat_set_times.error" name="path_filestat_set_times.error"></a> error: errno
  • +
+
+ +

Create a hard link.
Note: This is similar to linkat in POSIX.

+
Params
+
    +
  • <a href="#path_link.old_fd" name="path_link.old_fd"></a> old_fd: fd

    +
  • +
  • <a href="#path_link.old_flags" name="path_link.old_flags"></a> old_flags: lookupflags
    Flags determining the method of how the path is resolved.

    +
  • +
  • <a href="#path_link.old_path" name="path_link.old_path"></a> old_path: string
    The source path from which to link.

    +
  • +
  • <a href="#path_link.new_fd" name="path_link.new_fd"></a> new_fd: fd
    The working directory at which the resolution of the new path starts.

    +
  • +
  • <a href="#path_link.new_path" name="path_link.new_path"></a> new_path: string
    The destination path at which to create the hard link.

    +
  • +
+
Results
+
    +
  • <a href="#path_link.error" name="path_link.error"></a> error: errno
  • +
+
+

<a href="#path_open" name="path_open"></a> path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)

+

Open a file or directory.
The returned file descriptor is not guaranteed to be the lowest-numbered
file descriptor not currently open; it is randomized to prevent
applications from depending on making assumptions about indexes, since this
is error-prone in multi-threaded contexts. The returned file descriptor is
guaranteed to be less than 2**31.
Note: This is similar to openat in POSIX.

+
Params
+
    +
  • <a href="#path_open.fd" name="path_open.fd"></a> fd: fd

    +
  • +
  • <a href="#path_open.dirflags" name="path_open.dirflags"></a> dirflags: lookupflags
    Flags determining the method of how the path is resolved.

    +
  • +
  • <a href="#path_open.path" name="path_open.path"></a> path: string
    The relative path of the file or directory to open, relative to the
    path_open::fd directory.

    +
  • +
  • <a href="#path_open.oflags" name="path_open.oflags"></a> oflags: oflags
    The method by which to open the file.

    +
  • +
  • <a href="#path_open.fs_rights_base" name="path_open.fs_rights_base"></a> fs_rights_base: rights
    The initial rights of the newly created file descriptor. The
    implementation is allowed to return a file descriptor with fewer rights
    than specified, if and only if those rights do not apply to the type of
    file being opened.
    The base rights are rights that will apply to operations using the file
    descriptor itself, while the inheriting rights are rights that apply to
    file descriptors derived from it.

    +
  • +
  • <a href="#path_open.fs_rights_inherting" name="path_open.fs_rights_inherting"></a> fs_rights_inherting: rights

    +
  • +
  • <a href="#path_open.fdflags" name="path_open.fdflags"></a> fdflags: fdflags

    +
  • +
+
Results
+
    +
  • <a href="#path_open.error" name="path_open.error"></a> error: errno

    +
  • +
  • <a href="#path_open.opened_fd" name="path_open.opened_fd"></a> opened_fd: fd
    The file descriptor of the file that has been opened.

    +
  • +
+
+ +

Read the contents of a symbolic link.
Note: This is similar to readlinkat in POSIX.

+
Params
+
    +
  • <a href="#path_readlink.fd" name="path_readlink.fd"></a> fd: fd

    +
  • +
  • <a href="#path_readlink.path" name="path_readlink.path"></a> path: string
    The path of the symbolic link from which to read.

    +
  • +
  • <a href="#path_readlink.buf" name="path_readlink.buf"></a> buf: Pointer<u8>
    The buffer to which to write the contents of the symbolic link.

    +
  • +
  • <a href="#path_readlink.buf_len" name="path_readlink.buf_len"></a> buf_len: size

    +
  • +
+
Results
+
    +
  • <a href="#path_readlink.error" name="path_readlink.error"></a> error: errno

    +
  • +
  • <a href="#path_readlink.bufused" name="path_readlink.bufused"></a> bufused: size
    The number of bytes placed in the buffer.

    +
  • +
+
+

<a href="#path_remove_directory" name="path_remove_directory"></a> path_remove_directory(fd: fd, path: string) -> errno

+

Remove a directory.
Return errno::notempty if the directory is not empty.
Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

+
Params
+
    +
  • <a href="#path_remove_directory.fd" name="path_remove_directory.fd"></a> fd: fd

    +
  • +
  • <a href="#path_remove_directory.path" name="path_remove_directory.path"></a> path: string
    The path to a directory to remove.

    +
  • +
+
Results
+
    +
  • <a href="#path_remove_directory.error" name="path_remove_directory.error"></a> error: errno
  • +
+
+

<a href="#path_rename" name="path_rename"></a> path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno

+

Rename a file or directory.
Note: This is similar to renameat in POSIX.

+
Params
+
    +
  • <a href="#path_rename.fd" name="path_rename.fd"></a> fd: fd

    +
  • +
  • <a href="#path_rename.old_path" name="path_rename.old_path"></a> old_path: string
    The source path of the file or directory to rename.

    +
  • +
  • <a href="#path_rename.new_fd" name="path_rename.new_fd"></a> new_fd: fd
    The working directory at which the resolution of the new path starts.

    +
  • +
  • <a href="#path_rename.new_path" name="path_rename.new_path"></a> new_path: string
    The destination path to which to rename the file or directory.

    +
  • +
+
Results
+
    +
  • <a href="#path_rename.error" name="path_rename.error"></a> error: errno
  • +
+
+ +

Create a symbolic link.
Note: This is similar to symlinkat in POSIX.

+
Params
+
    +
  • <a href="#path_symlink.old_path" name="path_symlink.old_path"></a> old_path: string
    The contents of the symbolic link.

    +
  • +
  • <a href="#path_symlink.fd" name="path_symlink.fd"></a> fd: fd

    +
  • +
  • <a href="#path_symlink.new_path" name="path_symlink.new_path"></a> new_path: string
    The destination path at which to create the symbolic link.

    +
  • +
+
Results
+
    +
  • <a href="#path_symlink.error" name="path_symlink.error"></a> error: errno
  • +
+
+ +

Unlink a file.
Return errno::isdir if the path refers to a directory.
Note: This is similar to unlinkat(fd, path, 0) in POSIX.

+
Params
+
    +
  • <a href="#path_unlink_file.fd" name="path_unlink_file.fd"></a> fd: fd

    +
  • +
  • <a href="#path_unlink_file.path" name="path_unlink_file.path"></a> path: string
    The path to a file to unlink.

    +
  • +
+
Results
+
    +
  • <a href="#path_unlink_file.error" name="path_unlink_file.error"></a> error: errno
  • +
+
+

<a href="#poll_oneoff" name="poll_oneoff"></a> poll_oneoff(in: ConstPointer<subscription>, out: Pointer<event>, nsubscriptions: size) -> (errno, size)

+

Concurrently poll for the occurrence of a set of events.

+
Params
+
    +
  • <a href="#poll_oneoff.in" name="poll_oneoff.in"></a> in: ConstPointer<subscription>
    The events to which to subscribe.

    +
  • +
  • <a href="#poll_oneoff.out" name="poll_oneoff.out"></a> out: Pointer<event>
    The events that have occurred.

    +
  • +
  • <a href="#poll_oneoff.nsubscriptions" name="poll_oneoff.nsubscriptions"></a> nsubscriptions: size
    Both the number of subscriptions and events.

    +
  • +
+
Results
+
    +
  • <a href="#poll_oneoff.error" name="poll_oneoff.error"></a> error: errno

    +
  • +
  • <a href="#poll_oneoff.nevents" name="poll_oneoff.nevents"></a> nevents: size
    The number of events stored.

    +
  • +
+
+

<a href="#proc_exit" name="proc_exit"></a> proc_exit(rval: exitcode)

+

Terminate the process normally. An exit code of 0 indicates successful
termination of the program. The meanings of other values is dependent on
the environment.

+
Params
+
    +
  • <a href="#proc_exit.rval" name="proc_exit.rval"></a> rval: exitcode
    The exit code returned by the process.
  • +
+
Results
+
+

<a href="#proc_raise" name="proc_raise"></a> proc_raise(sig: signal) -> errno

+

Send a signal to the process of the calling thread.
Note: This is similar to raise in POSIX.

+
Params
+
    +
  • <a href="#proc_raise.sig" name="proc_raise.sig"></a> sig: signal
    The signal condition to trigger.
  • +
+
Results
+
    +
  • <a href="#proc_raise.error" name="proc_raise.error"></a> error: errno
  • +
+
+

<a href="#sched_yield" name="sched_yield"></a> sched_yield() -> errno

+

Temporarily yield execution of the calling thread.
Note: This is similar to sched_yield in POSIX.

+
Params
+
Results
+
    +
  • <a href="#sched_yield.error" name="sched_yield.error"></a> error: errno
  • +
+
+

<a href="#random_get" name="random_get"></a> random_get(buf: Pointer<u8>, buf_len: size) -> errno

+

Write high-quality random data into a buffer.
This function blocks when the implementation is unable to immediately
provide sufficient high-quality random data.
This function may execute slowly, so when large mounts of random data are
required, it's advisable to use this function to seed a pseudo-random
number generator, rather than to provide the random data directly.

+
Params
+
    +
  • <a href="#random_get.buf" name="random_get.buf"></a> buf: Pointer<u8>
    The buffer to fill with random data.

    +
  • +
  • <a href="#random_get.buf_len" name="random_get.buf_len"></a> buf_len: size

    +
  • +
+
Results
+
    +
  • <a href="#random_get.error" name="random_get.error"></a> error: errno
  • +
+
+

<a href="#sock_recv" name="sock_recv"></a> sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)

+

Receive a message from a socket.
Note: This is similar to recv in POSIX, though it also supports reading
the data into multiple buffers in the manner of readv.

+
Params
+
    +
  • <a href="#sock_recv.fd" name="sock_recv.fd"></a> fd: fd

    +
  • +
  • <a href="#sock_recv.ri_data" name="sock_recv.ri_data"></a> ri_data: iovec_array
    List of scatter/gather vectors to which to store data.

    +
  • +
  • <a href="#sock_recv.ri_flags" name="sock_recv.ri_flags"></a> ri_flags: riflags
    Message flags.

    +
  • +
+
Results
+
    +
  • <a href="#sock_recv.error" name="sock_recv.error"></a> error: errno

    +
  • +
  • <a href="#sock_recv.ro_datalen" name="sock_recv.ro_datalen"></a> ro_datalen: size
    Number of bytes stored in ri_data.

    +
  • +
  • <a href="#sock_recv.ro_flags" name="sock_recv.ro_flags"></a> ro_flags: roflags
    Message flags.

    +
  • +
+
+

<a href="#sock_send" name="sock_send"></a> sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)

+

Send a message on a socket.
Note: This is similar to send in POSIX, though it also supports writing
the data from multiple buffers in the manner of writev.

+
Params
+
    +
  • <a href="#sock_send.fd" name="sock_send.fd"></a> fd: fd

    +
  • +
  • <a href="#sock_send.si_data" name="sock_send.si_data"></a> si_data: ciovec_array
    List of scatter/gather vectors to which to retrieve data

    +
  • +
  • <a href="#sock_send.si_flags" name="sock_send.si_flags"></a> si_flags: siflags
    Message flags.

    +
  • +
+
Results
+
    +
  • <a href="#sock_send.error" name="sock_send.error"></a> error: errno

    +
  • +
  • <a href="#sock_send.so_datalen" name="sock_send.so_datalen"></a> so_datalen: size
    Number of bytes transmitted.

    +
  • +
+
+

<a href="#sock_shutdown" name="sock_shutdown"></a> sock_shutdown(fd: fd, how: sdflags) -> errno

+

Shut down socket send and receive channels.
Note: This is similar to shutdown in POSIX.

+
Params
+
    +
  • <a href="#sock_shutdown.fd" name="sock_shutdown.fd"></a> fd: fd

    +
  • +
  • <a href="#sock_shutdown.how" name="sock_shutdown.how"></a> how: sdflags
    Which channels on the socket to shut down.

    +
  • +
+
Results
+
    +
  • <a href="#sock_shutdown.error" name="sock_shutdown.error"></a> error: errno
  • +
diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index e2da39278..a50afa96a 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -1,15 +1,31 @@ # Types ## `size`: `u32` +Size: 4 + +Alignment: 4 + ## `filesize`: `u64` Non-negative file size or length of a region within a file. +Size: 8 + +Alignment: 8 + ## `timestamp`: `u64` Timestamp in nanoseconds. +Size: 8 + +Alignment: 8 + ## `clockid`: Enum(`u32`) Identifiers for clocks. +Size: 4 + +Alignment: 4 + ### Variants - `realtime` The clock measuring real time. Time value zero corresponds with @@ -33,6 +49,10 @@ Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided merely for alignment with POSIX. +Size: 2 + +Alignment: 2 + ### Variants - `success` No error occurred. System call completed successfully. @@ -268,6 +288,10 @@ Extension: Capabilities insufficient. ## `rights`: Flags(`u64`) File descriptor rights, determining which actions may be performed. +Size: 8 + +Alignment: 8 + ### Flags - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). @@ -371,37 +395,73 @@ The right to invoke [`sock_shutdown`](#sock_shutdown). ## `fd` A file descriptor handle. +Size: 4 + +Alignment: 4 + ### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `Pointer` The address of the buffer to be filled. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be filled. +Offset: 4 + ## `ciovec`: Struct A region of memory for scatter/gather writes. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `ConstPointer` The address of the buffer to be written. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be written. +Offset: 4 + ## `iovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `ciovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `filedelta`: `s64` Relative offset within a file. +Size: 8 + +Alignment: 8 + ## `whence`: Enum(`u8`) The position relative to which to set the offset of the file descriptor. +Size: 1 + +Alignment: 1 + ### Variants - `set` Seek relative to start-of-file. @@ -417,15 +477,31 @@ A reference to the offset of a directory entry. The value 0 signifies the start of the directory. +Size: 8 + +Alignment: 8 + ## `dirnamlen`: `u32` The type for the $d_namlen field of $dirent. +Size: 4 + +Alignment: 4 + ## `inode`: `u64` File serial number that is unique within its file system. +Size: 8 + +Alignment: 8 + ## `filetype`: Enum(`u8`) The type of a file descriptor or file. +Size: 1 + +Alignment: 1 + ### Variants - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -454,22 +530,38 @@ The file refers to a symbolic link inode. ## `dirent`: Struct A directory entry. +Size: 24 + +Alignment: 8 + ### Struct members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. +Offset: 0 + - `d_ino`: [`inode`](#inode) The serial number of the file referred to by this directory entry. +Offset: 8 + - `d_namlen`: [`dirnamlen`](#dirnamlen) The length of the name of the directory entry. +Offset: 16 + - `d_type`: [`filetype`](#filetype) The type of the file referred to by this directory entry. +Offset: 20 + ## `advice`: Enum(`u8`) File or memory access pattern advisory information. +Size: 1 + +Alignment: 1 + ### Variants - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -492,6 +584,10 @@ The application expects to access the specified data once and then not reuse it ## `fdflags`: Flags(`u16`) File descriptor flags. +Size: 2 + +Alignment: 2 + ### Flags - `append` Append mode: Data written to the file is always appended to the file's end. @@ -513,27 +609,47 @@ may also synchronously update the file's metadata. ## `fdstat`: Struct File descriptor attributes. +Size: 24 + +Alignment: 8 + ### Struct members - `fs_filetype`: [`filetype`](#filetype) File type. +Offset: 0 + - `fs_flags`: [`fdflags`](#fdflags) File descriptor flags. +Offset: 2 + - `fs_rights_base`: [`rights`](#rights) Rights that apply to this file descriptor. +Offset: 8 + - `fs_rights_inheriting`: [`rights`](#rights) Maximum set of rights that may be installed on new file descriptors that are created through this file descriptor, e.g., through [`path_open`](#path_open). +Offset: 16 + ## `device`: `u64` Identifier for a device containing a file system. Can be used in combination with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. +Size: 8 + +Alignment: 8 + ## `fstflags`: Flags(`u16`) Which file time attributes to adjust. +Size: 2 + +Alignment: 2 + ### Flags - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -550,6 +666,10 @@ Adjust the last data modification timestamp to the time of clock [`clockid::real ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. +Size: 4 + +Alignment: 4 + ### Flags - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. @@ -557,6 +677,10 @@ As long as the resolved path corresponds to a symbolic link, it is expanded. ## `oflags`: Flags(`u16`) Open flags used by [`path_open`](#path_open). +Size: 2 + +Alignment: 2 + ### Flags - `creat` Create file if it does not exist. @@ -573,41 +697,73 @@ Truncate file to size 0. ## `linkcount`: `u64` Number of hard links to an inode. +Size: 8 + +Alignment: 8 + ## `filestat`: Struct File attributes. +Size: 64 + +Alignment: 8 + ### Struct members - `dev`: [`device`](#device) Device ID of device containing the file. +Offset: 0 + - `ino`: [`inode`](#inode) File serial number. +Offset: 8 + - `filetype`: [`filetype`](#filetype) File type. +Offset: 16 + - `nlink`: [`linkcount`](#linkcount) Number of hard links to the file. +Offset: 24 + - `size`: [`filesize`](#filesize) For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. +Offset: 32 + - `atim`: [`timestamp`](#timestamp) Last data access timestamp. +Offset: 40 + - `mtim`: [`timestamp`](#timestamp) Last data modification timestamp. +Offset: 48 + - `ctim`: [`timestamp`](#timestamp) Last file status change timestamp. +Offset: 56 + ## `userdata`: `u64` User-provided value that may be attached to objects that is retained when extracted from the implementation. +Size: 8 + +Alignment: 8 + ## `eventtype`: Enum(`u8`) Type of a subscription to an event or its occurrence. +Size: 1 + +Alignment: 1 + ### Variants - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has @@ -625,6 +781,10 @@ available for writing. This event always triggers for regular files. The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 2 + +Alignment: 2 + ### Flags - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -633,34 +793,58 @@ The peer of this socket has closed or disconnected. The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 16 + +Alignment: 8 + ### Struct members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. +Offset: 0 + - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. +Offset: 8 + ## `event`: Struct An event that occurred. +Size: 32 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). +Offset: 0 + - `error`: [`errno`](#errno) If non-zero, an error that occurred while processing the subscription request. +Offset: 8 + - `type`: [`eventtype`](#eventtype) The type of event that occured +Offset: 10 + - `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. +Offset: 16 + ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). +Size: 2 + +Alignment: 2 + ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in @@ -672,31 +856,59 @@ current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). +Size: 32 + +Alignment: 8 + ### Struct members - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. +Offset: 0 + - `timeout`: [`timestamp`](#timestamp) The absolute or relative timestamp. +Offset: 8 + - `precision`: [`timestamp`](#timestamp) The amount of time that the implementation may wait additionally to coalesce with other events. +Offset: 16 + - `flags`: [`subclockflags`](#subclockflags) Flags specifying whether the timeout is absolute or relative +Offset: 24 + ## `subscription_fd_readwrite`: Struct The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 4 + +Alignment: 4 + ### Struct members - `file_descriptor`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. +Offset: 0 + ## `subscription_u`: Union The contents of a [`subscription`](#subscription). +Size: 40 + +Alignment: 8 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 8 +- contents_size: 32 +- contents_align: 8 ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -707,20 +919,36 @@ The contents of a [`subscription`](#subscription). ## `subscription`: Struct Subscription to an event. +Size: 48 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). +Offset: 0 + - `u`: [`subscription_u`](#subscription_u) The type of the event to which to subscribe, and its contents +Offset: 8 + ## `exitcode`: `u32` Exit code generated by a process when exiting. +Size: 4 + +Alignment: 4 + ## `signal`: Enum(`u8`) Signal condition. +Size: 1 + +Alignment: 1 + ### Variants - `none` No signal. Note that POSIX has special semantics for `kill(pid, 0)`, @@ -849,6 +1077,10 @@ Action: Terminates the process. ## `riflags`: Flags(`u16`) Flags provided to [`sock_recv`](#sock_recv). +Size: 2 + +Alignment: 2 + ### Flags - `recv_peek` Returns the message without removing it from the socket's receive queue. @@ -859,6 +1091,10 @@ On byte-stream sockets, block until the full amount of data can be returned. ## `roflags`: Flags(`u16`) Flags returned by [`sock_recv`](#sock_recv). +Size: 2 + +Alignment: 2 + ### Flags - `recv_data_truncated` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. @@ -867,9 +1103,17 @@ Returned by [`sock_recv`](#sock_recv): Message data has been truncated. Flags provided to [`sock_send`](#sock_send). As there are currently no flags defined, it must be set to zero. +Size: 2 + +Alignment: 2 + ## `sdflags`: Flags(`u8`) Which channels on a socket to shut down. +Size: 1 + +Alignment: 1 + ### Flags - `rd` Disables further receive operations. @@ -880,6 +1124,10 @@ Disables further send operations. ## `preopentype`: Enum(`u8`) Identifiers for preopened capabilities. +Size: 1 + +Alignment: 1 + ### Variants - `dir` A pre-opened directory. @@ -887,13 +1135,29 @@ A pre-opened directory. ## `prestat_dir`: Struct The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). +Size: 4 + +Alignment: 4 + ### Struct members - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). +Offset: 0 + ## `prestat`: Union Information about a pre-opened capability. +Size: 8 + +Alignment: 4 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 4 +- contents_size: 4 +- contents_align: 4 ### Union variants - `dir`: [`prestat_dir`](#prestat_dir) diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index 10dc9f7c2..02ef9ec22 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -8,6 +8,7 @@ use crate::{ InterfaceFunc, InterfaceFuncParam, Module, ModuleImport, ModuleImportVariant, NamedType, StructDatatype, Type, TypeRef, UnionDatatype, }, + layout::Layout, polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, RepEquality, }; @@ -26,7 +27,13 @@ impl ToMarkdown for Document { heading.new_level_down(), name, name, - &d.docs, + format!( + "{}\nSize: {}\n\nAlignment: {}\n", + &d.docs, + &d.mem_size(), + &d.mem_align() + ) + .as_str(), )); d.generate(child.clone()); } @@ -173,7 +180,9 @@ impl ToMarkdown for StructDatatype { let heading = heading_from_node(&node, 1); node.new_child(MdSection::new(heading, "Struct members")); - for member in &self.members { + for member_layout in &self.member_layout() { + let member = member_layout.member; + let offset = member_layout.offset; let name = member.name.as_str(); let id = if let Some(id) = node.any_ref().id() { format!("{}.{}", id, name) @@ -184,7 +193,7 @@ impl ToMarkdown for StructDatatype { MdHeading::new_bullet(), id.as_str(), name, - &member.docs, + format!("{}\nOffset: {}\n", &member.docs, &offset).as_str(), )); member.tref.generate(n.clone()); } @@ -195,8 +204,34 @@ impl ToMarkdown for StructDatatype { impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Union variants")); + // Sizes & Alignments + let sizes_heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(sizes_heading, "Union Layout")); + let union_layout = &self.union_layout(); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("tag_size: {}", union_layout.tag_size).as_str(), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("tag_align: {}", union_layout.tag_align).as_str(), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("contents_offset: {}", union_layout.contents_offset).as_str(), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("contents_size: {}", union_layout.contents_size).as_str(), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("contents_align: {}", union_layout.contents_align).as_str(), + )); + + // Variants + let variants_heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(variants_heading, "Union variants")); for variant in &self.variants { let name = variant.name.as_str(); From d7ff3b44ba5319340b583bc0b18db75f3c684a11 Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Sat, 2 May 2020 00:01:48 -0700 Subject: [PATCH 0639/1772] Added sizes and alignments to WASI docs (#268) * Added sizes and alignments to WASI docs * Fixed formatting * Made requested changes * Fixed whitespace issues * Fixed up whitespace one last time --- proposals/filesystem/phases/ephemeral/docs.md | 274 ++++ .../filesystem/phases/old/snapshot_0/docs.md | 266 ++++ .../filesystem/phases/snapshot/docs.html | 1279 +++++++++++++++++ proposals/filesystem/phases/snapshot/docs.md | 264 ++++ .../filesystem/tools/witx/src/docs/ast.rs | 45 +- 5 files changed, 2123 insertions(+), 5 deletions(-) create mode 100644 proposals/filesystem/phases/snapshot/docs.html diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index c645a7452..3ddc5ad79 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -4,15 +4,31 @@ An array size. Note: This is similar to `size_t` in POSIX. +Size: 4 + +Alignment: 4 + ## `filesize`: `u64` Non-negative file size or length of a region within a file. +Size: 8 + +Alignment: 8 + ## `timestamp`: `u64` Timestamp in nanoseconds. +Size: 8 + +Alignment: 8 + ## `clockid`: Enum(`u32`) Identifiers for clocks. +Size: 4 + +Alignment: 4 + ### Variants - `realtime` The clock measuring real time. Time value zero corresponds with @@ -30,6 +46,10 @@ Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided merely for alignment with POSIX. +Size: 2 + +Alignment: 2 + ### Variants - `success` No error occurred. System call completed successfully. @@ -265,6 +285,10 @@ Extension: Capabilities insufficient. ## `rights`: Flags(`u64`) File descriptor rights, determining which actions may be performed. +Size: 8 + +Alignment: 8 + ### Flags - `fd_datasync` The right to invoke `fd_datasync`. @@ -374,37 +398,73 @@ The right to invoke `sock_shutdown`. ## `fd` A file descriptor handle. +Size: 4 + +Alignment: 4 + ### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `Pointer` The address of the buffer to be filled. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be filled. +Offset: 4 + ## `ciovec`: Struct A region of memory for scatter/gather writes. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `ConstPointer` The address of the buffer to be written. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be written. +Offset: 4 + ## `iovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `ciovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `filedelta`: `s64` Relative offset within a file. +Size: 8 + +Alignment: 8 + ## `whence`: Enum(`u8`) The position relative to which to set the offset of the file descriptor. +Size: 1 + +Alignment: 1 + ### Variants - `set` Seek relative to start-of-file. @@ -418,6 +478,10 @@ Seek relative to end-of-file. ## `dircookie`: Int(`u64`) A reference to the offset of a directory entry. +Size: 8 + +Alignment: 8 + ### Consts - `start` In an `fd_readdir` call, this value signifies the start of the directory. @@ -425,12 +489,24 @@ In an `fd_readdir` call, this value signifies the start of the directory. ## `dirnamlen`: `u32` The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). +Size: 4 + +Alignment: 4 + ## `inode`: `u64` File serial number that is unique within its file system. +Size: 8 + +Alignment: 8 + ## `filetype`: Enum(`u8`) The type of a file descriptor or file. +Size: 1 + +Alignment: 1 + ### Variants - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -462,22 +538,38 @@ The file descriptor or file refers to a FIFO. ## `dirent`: Struct A directory entry. +Size: 24 + +Alignment: 8 + ### Struct members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. +Offset: 0 + - `d_ino`: [`inode`](#inode) The serial number of the file referred to by this directory entry. +Offset: 8 + - `d_namlen`: [`dirnamlen`](#dirnamlen) The length of the name of the directory entry. +Offset: 16 + - `d_type`: [`filetype`](#filetype) The type of the file referred to by this directory entry. +Offset: 20 + ## `advice`: Enum(`u8`) File or memory access pattern advisory information. +Size: 1 + +Alignment: 1 + ### Variants - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -500,6 +592,10 @@ The application expects to access the specified data once and then not reuse it ## `fdflags`: Flags(`u16`) File descriptor flags. +Size: 2 + +Alignment: 2 + ### Flags - `append` Append mode: Data written to the file is always appended to the file's end. @@ -521,27 +617,47 @@ may also synchronously update the file's metadata. ## `fdstat`: Struct File descriptor attributes. +Size: 24 + +Alignment: 8 + ### Struct members - `fs_filetype`: [`filetype`](#filetype) File type. +Offset: 0 + - `fs_flags`: [`fdflags`](#fdflags) File descriptor flags. +Offset: 2 + - `fs_rights_base`: [`rights`](#rights) Rights that apply to this file descriptor. +Offset: 8 + - `fs_rights_inheriting`: [`rights`](#rights) Maximum set of rights that may be installed on new file descriptors that are created through this file descriptor, e.g., through `path_open`. +Offset: 16 + ## `device`: `u64` Identifier for a device containing a file system. Can be used in combination with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. +Size: 8 + +Alignment: 8 + ## `fstflags`: Flags(`u16`) Which file time attributes to adjust. +Size: 2 + +Alignment: 2 + ### Flags - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -558,6 +674,10 @@ Adjust the last data modification timestamp to the time of clock [`clockid::real ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. +Size: 4 + +Alignment: 4 + ### Flags - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. @@ -565,6 +685,10 @@ As long as the resolved path corresponds to a symbolic link, it is expanded. ## `oflags`: Flags(`u16`) Open flags used by `path_open`. +Size: 2 + +Alignment: 2 + ### Flags - `create` Create file if it does not exist. @@ -581,11 +705,19 @@ Truncate file to size 0. ## `linkcount`: `u64` Number of hard links to an inode. +Size: 8 + +Alignment: 8 + ## `permissions`: Flags(`u8`) File permissions. This represents the permissions associated with a file in a filesystem, and don't fully reflect all the conditions which determine whether a given WASI program can access the file. +Size: 1 + +Alignment: 1 + ### Flags - `read` For files, permission to read the file. @@ -614,41 +746,71 @@ to other "users". ## `filestat`: Struct File attributes. +Size: 64 + +Alignment: 8 + ### Struct members - `dev`: [`device`](#device) Device ID of device containing the file. +Offset: 0 + - `ino`: [`inode`](#inode) File serial number. +Offset: 8 + - `filetype`: [`filetype`](#filetype) File type. +Offset: 16 + - `permissions`: [`permissions`](#permissions) File permissions. +Offset: 17 + - `nlink`: [`linkcount`](#linkcount) Number of hard links to the file. +Offset: 24 + - `size`: [`filesize`](#filesize) For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. +Offset: 32 + - `atim`: [`timestamp`](#timestamp) Last data access timestamp. +Offset: 40 + - `mtim`: [`timestamp`](#timestamp) Last data modification timestamp. +Offset: 48 + - `ctim`: [`timestamp`](#timestamp) Last file status change timestamp. +Offset: 56 + ## `userdata`: `u64` User-provided value that may be attached to objects that is retained when extracted from the implementation. +Size: 8 + +Alignment: 8 + ## `eventtype`: Enum(`u8`) Type of a subscription to an event or its occurrence. +Size: 1 + +Alignment: 1 + ### Variants - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has @@ -666,6 +828,10 @@ available for writing. This event always triggers for regular files. The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 2 + +Alignment: 2 + ### Flags - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -674,16 +840,34 @@ The peer of this socket has closed or disconnected. The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 16 + +Alignment: 8 + ### Struct members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. +Offset: 0 + - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. +Offset: 8 + ## `event_u`: Union The contents of an [`event`](#event). +Size: 24 + +Alignment: 8 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 8 +- contents_size: 16 +- contents_align: 8 ### Union variants - `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) @@ -694,20 +878,34 @@ The contents of an [`event`](#event). ## `event`: Struct An event that occurred. +Size: 40 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). +Offset: 0 + - `error`: [`errno`](#errno) If non-zero, an error that occurred while processing the subscription request. +Offset: 8 + - `u`: [`event_u`](#event_u) The type of the event that occurred, and the contents of the event +Offset: 16 + ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). +Size: 2 + +Alignment: 2 + ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in @@ -719,31 +917,59 @@ current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). +Size: 32 + +Alignment: 8 + ### Struct members - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. +Offset: 0 + - `timeout`: [`timestamp`](#timestamp) The absolute or relative timestamp. +Offset: 8 + - `precision`: [`timestamp`](#timestamp) The amount of time that the implementation may wait additionally to coalesce with other events. +Offset: 16 + - `flags`: [`subclockflags`](#subclockflags) Flags specifying whether the timeout is absolute or relative +Offset: 24 + ## `subscription_fd_readwrite`: Struct The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 4 + +Alignment: 4 + ### Struct members - `fd`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. +Offset: 0 + ## `subscription_u`: Union The contents of a [`subscription`](#subscription). +Size: 40 + +Alignment: 8 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 8 +- contents_size: 32 +- contents_align: 8 ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -754,20 +980,36 @@ The contents of a [`subscription`](#subscription). ## `subscription`: Struct Subscription to an event. +Size: 48 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). +Offset: 0 + - `u`: [`subscription_u`](#subscription_u) The type of the event to which to subscribe, and the contents of the subscription. +Offset: 8 + ## `exitcode`: `u32` Exit code generated by a process when exiting. +Size: 4 + +Alignment: 4 + ## `riflags`: Flags(`u16`) Flags provided to `sock_recv`. +Size: 2 + +Alignment: 2 + ### Flags - `recv_peek` Returns the message without removing it from the socket's receive queue. @@ -778,6 +1020,10 @@ On byte-stream sockets, block until the full amount of data can be returned. ## `roflags`: Flags(`u16`) Flags returned by `sock_recv`. +Size: 2 + +Alignment: 2 + ### Flags - `recv_data_truncated` Returned by `sock_recv`: Message data has been truncated. @@ -786,9 +1032,17 @@ Returned by `sock_recv`: Message data has been truncated. Flags provided to `sock_send`. As there are currently no flags defined, it must be set to zero. +Size: 2 + +Alignment: 2 + ## `sdflags`: Flags(`u8`) Which channels on a socket to shut down. +Size: 1 + +Alignment: 1 + ### Flags - `rd` Disables further receive operations. @@ -799,6 +1053,10 @@ Disables further send operations. ## `preopentype`: Enum(`u8`) Identifiers for preopened capabilities. +Size: 1 + +Alignment: 1 + ### Variants - `dir` A pre-opened directory. @@ -806,13 +1064,29 @@ A pre-opened directory. ## `prestat_dir`: Struct The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). +Size: 4 + +Alignment: 4 + ### Struct members - `pr_name_len`: [`size`](#size) The length of the directory name for use with `fd_prestat_dir_name`. +Offset: 0 + ## `prestat`: Union Information about a pre-opened capability. +Size: 8 + +Alignment: 4 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 4 +- contents_size: 4 +- contents_align: 4 ### Union variants - `dir`: [`prestat_dir`](#prestat_dir) When type is [`preopentype::dir`](#preopentype.dir): diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index f5b8ff314..eda85fbc0 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -1,15 +1,31 @@ # Types ## `size`: `u32` +Size: 4 + +Alignment: 4 + ## `filesize`: `u64` Non-negative file size or length of a region within a file. +Size: 8 + +Alignment: 8 + ## `timestamp`: `u64` Timestamp in nanoseconds. +Size: 8 + +Alignment: 8 + ## `clockid`: Enum(`u32`) Identifiers for clocks. +Size: 4 + +Alignment: 4 + ### Variants - `realtime` The clock measuring real time. Time value zero corresponds with @@ -33,6 +49,10 @@ Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided merely for alignment with POSIX. +Size: 2 + +Alignment: 2 + ### Variants - `success` No error occurred. System call completed successfully. @@ -268,6 +288,10 @@ Extension: Capabilities insufficient. ## `rights`: Flags(`u64`) File descriptor rights, determining which actions may be performed. +Size: 8 + +Alignment: 8 + ### Flags - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). @@ -371,37 +395,73 @@ The right to invoke [`sock_shutdown`](#sock_shutdown). ## `fd` A file descriptor handle. +Size: 4 + +Alignment: 4 + ### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `Pointer` The address of the buffer to be filled. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be filled. +Offset: 4 + ## `ciovec`: Struct A region of memory for scatter/gather writes. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `ConstPointer` The address of the buffer to be written. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be written. +Offset: 4 + ## `iovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `ciovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `filedelta`: `s64` Relative offset within a file. +Size: 8 + +Alignment: 8 + ## `whence`: Enum(`u8`) The position relative to which to set the offset of the file descriptor. +Size: 1 + +Alignment: 1 + ### Variants - `cur` Seek relative to current position. @@ -415,15 +475,31 @@ Seek relative to start-of-file. ## `dircookie`: `u64` A reference to the offset of a directory entry. +Size: 8 + +Alignment: 8 + ## `dirnamlen`: `u32` The type for the $d_namlen field of $dirent. +Size: 4 + +Alignment: 4 + ## `inode`: `u64` File serial number that is unique within its file system. +Size: 8 + +Alignment: 8 + ## `filetype`: Enum(`u8`) The type of a file descriptor or file. +Size: 1 + +Alignment: 1 + ### Variants - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -452,22 +528,38 @@ The file refers to a symbolic link inode. ## `dirent`: Struct A directory entry. +Size: 24 + +Alignment: 8 + ### Struct members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. +Offset: 0 + - `d_ino`: [`inode`](#inode) The serial number of the file referred to by this directory entry. +Offset: 8 + - `d_namlen`: [`dirnamlen`](#dirnamlen) The length of the name of the directory entry. +Offset: 16 + - `d_type`: [`filetype`](#filetype) The type of the file referred to by this directory entry. +Offset: 20 + ## `advice`: Enum(`u8`) File or memory access pattern advisory information. +Size: 1 + +Alignment: 1 + ### Variants - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -490,6 +582,10 @@ The application expects to access the specified data once and then not reuse it ## `fdflags`: Flags(`u16`) File descriptor flags. +Size: 2 + +Alignment: 2 + ### Flags - `append` Append mode: Data written to the file is always appended to the file's end. @@ -511,27 +607,47 @@ may also synchronously update the file's metadata. ## `fdstat`: Struct File descriptor attributes. +Size: 24 + +Alignment: 8 + ### Struct members - `fs_filetype`: [`filetype`](#filetype) File type. +Offset: 0 + - `fs_flags`: [`fdflags`](#fdflags) File descriptor flags. +Offset: 2 + - `fs_rights_base`: [`rights`](#rights) Rights that apply to this file descriptor. +Offset: 8 + - `fs_rights_inheriting`: [`rights`](#rights) Maximum set of rights that may be installed on new file descriptors that are created through this file descriptor, e.g., through [`path_open`](#path_open). +Offset: 16 + ## `device`: `u64` Identifier for a device containing a file system. Can be used in combination with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. +Size: 8 + +Alignment: 8 + ## `fstflags`: Flags(`u16`) Which file time attributes to adjust. +Size: 2 + +Alignment: 2 + ### Flags - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -548,6 +664,10 @@ Adjust the last data modification timestamp to the time of clock [`clockid::real ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. +Size: 4 + +Alignment: 4 + ### Flags - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. @@ -555,6 +675,10 @@ As long as the resolved path corresponds to a symbolic link, it is expanded. ## `oflags`: Flags(`u16`) Open flags used by [`path_open`](#path_open). +Size: 2 + +Alignment: 2 + ### Flags - `creat` Create file if it does not exist. @@ -571,41 +695,73 @@ Truncate file to size 0. ## `linkcount`: `u32` Number of hard links to an inode. +Size: 4 + +Alignment: 4 + ## `filestat`: Struct File attributes. +Size: 56 + +Alignment: 8 + ### Struct members - `dev`: [`device`](#device) Device ID of device containing the file. +Offset: 0 + - `ino`: [`inode`](#inode) File serial number. +Offset: 8 + - `filetype`: [`filetype`](#filetype) File type. +Offset: 16 + - `nlink`: [`linkcount`](#linkcount) Number of hard links to the file. +Offset: 20 + - `size`: [`filesize`](#filesize) For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. +Offset: 24 + - `atim`: [`timestamp`](#timestamp) Last data access timestamp. +Offset: 32 + - `mtim`: [`timestamp`](#timestamp) Last data modification timestamp. +Offset: 40 + - `ctim`: [`timestamp`](#timestamp) Last file status change timestamp. +Offset: 48 + ## `userdata`: `u64` User-provided value that may be attached to objects that is retained when extracted from the implementation. +Size: 8 + +Alignment: 8 + ## `eventtype`: Enum(`u8`) Type of a subscription to an event or its occurrence. +Size: 1 + +Alignment: 1 + ### Variants - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has @@ -623,6 +779,10 @@ available for writing. This event always triggers for regular files. The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 2 + +Alignment: 2 + ### Flags - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -631,34 +791,58 @@ The peer of this socket has closed or disconnected. The contents of an $event for the [`eventtype::fd_read`](#eventtype.fd_read) and [`eventtype::fd_write`](#eventtype.fd_write) variants +Size: 16 + +Alignment: 8 + ### Struct members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. +Offset: 0 + - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. +Offset: 8 + ## `event`: Struct An event that occurred. +Size: 32 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). +Offset: 0 + - `error`: [`errno`](#errno) If non-zero, an error that occurred while processing the subscription request. +Offset: 8 + - `type`: [`eventtype`](#eventtype) The type of event that occured +Offset: 10 + - `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. +Offset: 16 + ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). +Size: 2 + +Alignment: 2 + ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in @@ -670,34 +854,64 @@ current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). +Size: 40 + +Alignment: 8 + ### Struct members - `identifier`: [`userdata`](#userdata) The user-defined unique identifier of the clock. +Offset: 0 + - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. +Offset: 8 + - `timeout`: [`timestamp`](#timestamp) The absolute or relative timestamp. +Offset: 16 + - `precision`: [`timestamp`](#timestamp) The amount of time that the implementation may wait additionally to coalesce with other events. +Offset: 24 + - `flags`: [`subclockflags`](#subclockflags) Flags specifying whether the timeout is absolute or relative +Offset: 32 + ## `subscription_fd_readwrite`: Struct The contents of a [`subscription`](#subscription) when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 4 + +Alignment: 4 + ### Struct members - `file_descriptor`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. +Offset: 0 + ## `subscription_u`: Union The contents of a [`subscription`](#subscription). +Size: 48 + +Alignment: 8 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 8 +- contents_size: 40 +- contents_align: 8 ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -708,20 +922,36 @@ The contents of a [`subscription`](#subscription). ## `subscription`: Struct Subscription to an event. +Size: 56 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). +Offset: 0 + - `u`: [`subscription_u`](#subscription_u) The type of the event to which to subscribe. +Offset: 8 + ## `exitcode`: `u32` Exit code generated by a process when exiting. +Size: 4 + +Alignment: 4 + ## `signal`: Enum(`u8`) Signal condition. +Size: 1 + +Alignment: 1 + ### Variants - `none` No signal. Note that POSIX has special semantics for `kill(pid, 0)`, @@ -850,6 +1080,10 @@ Action: Terminates the process. ## `riflags`: Flags(`u16`) Flags provided to [`sock_recv`](#sock_recv). +Size: 2 + +Alignment: 2 + ### Flags - `recv_peek` Returns the message without removing it from the socket's receive queue. @@ -860,6 +1094,10 @@ On byte-stream sockets, block until the full amount of data can be returned. ## `roflags`: Flags(`u16`) Flags returned by [`sock_recv`](#sock_recv). +Size: 2 + +Alignment: 2 + ### Flags - `recv_data_truncated` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. @@ -868,9 +1106,17 @@ Returned by [`sock_recv`](#sock_recv): Message data has been truncated. Flags provided to [`sock_send`](#sock_send). As there are currently no flags defined, it must be set to zero. +Size: 2 + +Alignment: 2 + ## `sdflags`: Flags(`u8`) Which channels on a socket to shut down. +Size: 1 + +Alignment: 1 + ### Flags - `rd` Disables further receive operations. @@ -881,6 +1127,10 @@ Disables further send operations. ## `preopentype`: Enum(`u8`) Identifiers for preopened capabilities. +Size: 1 + +Alignment: 1 + ### Variants - `dir` A pre-opened directory. @@ -888,13 +1138,29 @@ A pre-opened directory. ## `prestat_dir`: Struct The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). +Size: 4 + +Alignment: 4 + ### Struct members - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). +Offset: 0 + ## `prestat`: Union Information about a pre-opened capability. +Size: 8 + +Alignment: 4 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 4 +- contents_size: 4 +- contents_align: 4 ### Union variants - `dir`: [`prestat_dir`](#prestat_dir) diff --git a/proposals/filesystem/phases/snapshot/docs.html b/proposals/filesystem/phases/snapshot/docs.html new file mode 100644 index 000000000..83ea3c7d2 --- /dev/null +++ b/proposals/filesystem/phases/snapshot/docs.html @@ -0,0 +1,1279 @@ +

Types

+

<a href="#size" name="size"></a> size: u32

+

Size: 4
Alignment: 4

+

<a href="#filesize" name="filesize"></a> filesize: u64

+

Non-negative file size or length of a region within a file.
Size: 8
Alignment: 8

+

<a href="#timestamp" name="timestamp"></a> timestamp: u64

+

Timestamp in nanoseconds.
Size: 8
Alignment: 8

+

<a href="#clockid" name="clockid"></a> clockid: Enum(u32)

+

Identifiers for clocks.
Size: 4
Alignment: 4

+

Variants

+
    +
  • <a href="#clockid.realtime" name="clockid.realtime"></a> realtime
    The clock measuring real time. Time value zero corresponds with
    1970-01-01T00:00:00Z.

    +
  • +
  • <a href="#clockid.monotonic" name="clockid.monotonic"></a> monotonic
    The store-wide monotonic clock, which is defined as a clock measuring
    real time, whose value cannot be adjusted and which cannot have negative
    clock jumps. The epoch of this clock is undefined. The absolute time
    value of this clock therefore has no meaning.

    +
  • +
  • <a href="#clockid.process_cputime_id" name="clockid.process_cputime_id"></a> process_cputime_id
    The CPU-time clock associated with the current process.

    +
  • +
  • <a href="#clockid.thread_cputime_id" name="clockid.thread_cputime_id"></a> thread_cputime_id
    The CPU-time clock associated with the current thread.

    +
  • +
+

<a href="#errno" name="errno"></a> errno: Enum(u16)

+

Error codes returned by functions.
Not all of these error codes are returned by the functions provided by this
API; some are used in higher-level library layers, and others are provided
merely for alignment with POSIX.
Size: 2
Alignment: 2

+

Variants

+
    +
  • <a href="#errno.success" name="errno.success"></a> success
    No error occurred. System call completed successfully.

    +
  • +
  • <a href="#errno.2big" name="errno.2big"></a> 2big
    Argument list too long.

    +
  • +
  • <a href="#errno.acces" name="errno.acces"></a> acces
    Permission denied.

    +
  • +
  • <a href="#errno.addrinuse" name="errno.addrinuse"></a> addrinuse
    Address in use.

    +
  • +
  • <a href="#errno.addrnotavail" name="errno.addrnotavail"></a> addrnotavail
    Address not available.

    +
  • +
  • <a href="#errno.afnosupport" name="errno.afnosupport"></a> afnosupport
    Address family not supported.

    +
  • +
  • <a href="#errno.again" name="errno.again"></a> again
    Resource unavailable, or operation would block.

    +
  • +
  • <a href="#errno.already" name="errno.already"></a> already
    Connection already in progress.

    +
  • +
  • <a href="#errno.badf" name="errno.badf"></a> badf
    Bad file descriptor.

    +
  • +
  • <a href="#errno.badmsg" name="errno.badmsg"></a> badmsg
    Bad message.

    +
  • +
  • <a href="#errno.busy" name="errno.busy"></a> busy
    Device or resource busy.

    +
  • +
  • <a href="#errno.canceled" name="errno.canceled"></a> canceled
    Operation canceled.

    +
  • +
  • <a href="#errno.child" name="errno.child"></a> child
    No child processes.

    +
  • +
  • <a href="#errno.connaborted" name="errno.connaborted"></a> connaborted
    Connection aborted.

    +
  • +
  • <a href="#errno.connrefused" name="errno.connrefused"></a> connrefused
    Connection refused.

    +
  • +
  • <a href="#errno.connreset" name="errno.connreset"></a> connreset
    Connection reset.

    +
  • +
  • <a href="#errno.deadlk" name="errno.deadlk"></a> deadlk
    Resource deadlock would occur.

    +
  • +
  • <a href="#errno.destaddrreq" name="errno.destaddrreq"></a> destaddrreq
    Destination address required.

    +
  • +
  • <a href="#errno.dom" name="errno.dom"></a> dom
    Mathematics argument out of domain of function.

    +
  • +
  • <a href="#errno.dquot" name="errno.dquot"></a> dquot
    Reserved.

    +
  • +
  • <a href="#errno.exist" name="errno.exist"></a> exist
    File exists.

    +
  • +
  • <a href="#errno.fault" name="errno.fault"></a> fault
    Bad address.

    +
  • +
  • <a href="#errno.fbig" name="errno.fbig"></a> fbig
    File too large.

    +
  • +
  • <a href="#errno.hostunreach" name="errno.hostunreach"></a> hostunreach
    Host is unreachable.

    +
  • +
  • <a href="#errno.idrm" name="errno.idrm"></a> idrm
    Identifier removed.

    +
  • +
  • <a href="#errno.ilseq" name="errno.ilseq"></a> ilseq
    Illegal byte sequence.

    +
  • +
  • <a href="#errno.inprogress" name="errno.inprogress"></a> inprogress
    Operation in progress.

    +
  • +
  • <a href="#errno.intr" name="errno.intr"></a> intr
    Interrupted function.

    +
  • +
  • <a href="#errno.inval" name="errno.inval"></a> inval
    Invalid argument.

    +
  • +
  • <a href="#errno.io" name="errno.io"></a> io
    I/O error.

    +
  • +
  • <a href="#errno.isconn" name="errno.isconn"></a> isconn
    Socket is connected.

    +
  • +
  • <a href="#errno.isdir" name="errno.isdir"></a> isdir
    Is a directory.

    +
  • +
  • <a href="#errno.loop" name="errno.loop"></a> loop
    Too many levels of symbolic links.

    +
  • +
  • <a href="#errno.mfile" name="errno.mfile"></a> mfile
    File descriptor value too large.

    +
  • +
  • <a href="#errno.mlink" name="errno.mlink"></a> mlink
    Too many links.

    +
  • +
  • <a href="#errno.msgsize" name="errno.msgsize"></a> msgsize
    Message too large.

    +
  • +
  • <a href="#errno.multihop" name="errno.multihop"></a> multihop
    Reserved.

    +
  • +
  • <a href="#errno.nametoolong" name="errno.nametoolong"></a> nametoolong
    Filename too long.

    +
  • +
  • <a href="#errno.netdown" name="errno.netdown"></a> netdown
    Network is down.

    +
  • +
  • <a href="#errno.netreset" name="errno.netreset"></a> netreset
    Connection aborted by network.

    +
  • +
  • <a href="#errno.netunreach" name="errno.netunreach"></a> netunreach
    Network unreachable.

    +
  • +
  • <a href="#errno.nfile" name="errno.nfile"></a> nfile
    Too many files open in system.

    +
  • +
  • <a href="#errno.nobufs" name="errno.nobufs"></a> nobufs
    No buffer space available.

    +
  • +
  • <a href="#errno.nodev" name="errno.nodev"></a> nodev
    No such device.

    +
  • +
  • <a href="#errno.noent" name="errno.noent"></a> noent
    No such file or directory.

    +
  • +
  • <a href="#errno.noexec" name="errno.noexec"></a> noexec
    Executable file format error.

    +
  • +
  • <a href="#errno.nolck" name="errno.nolck"></a> nolck
    No locks available.

    +
  • +
  • <a href="#errno.nolink" name="errno.nolink"></a> nolink
    Reserved.

    +
  • +
  • <a href="#errno.nomem" name="errno.nomem"></a> nomem
    Not enough space.

    +
  • +
  • <a href="#errno.nomsg" name="errno.nomsg"></a> nomsg
    No message of the desired type.

    +
  • +
  • <a href="#errno.noprotoopt" name="errno.noprotoopt"></a> noprotoopt
    Protocol not available.

    +
  • +
  • <a href="#errno.nospc" name="errno.nospc"></a> nospc
    No space left on device.

    +
  • +
  • <a href="#errno.nosys" name="errno.nosys"></a> nosys
    Function not supported.

    +
  • +
  • <a href="#errno.notconn" name="errno.notconn"></a> notconn
    The socket is not connected.

    +
  • +
  • <a href="#errno.notdir" name="errno.notdir"></a> notdir
    Not a directory or a symbolic link to a directory.

    +
  • +
  • <a href="#errno.notempty" name="errno.notempty"></a> notempty
    Directory not empty.

    +
  • +
  • <a href="#errno.notrecoverable" name="errno.notrecoverable"></a> notrecoverable
    State not recoverable.

    +
  • +
  • <a href="#errno.notsock" name="errno.notsock"></a> notsock
    Not a socket.

    +
  • +
  • <a href="#errno.notsup" name="errno.notsup"></a> notsup
    Not supported, or operation not supported on socket.

    +
  • +
  • <a href="#errno.notty" name="errno.notty"></a> notty
    Inappropriate I/O control operation.

    +
  • +
  • <a href="#errno.nxio" name="errno.nxio"></a> nxio
    No such device or address.

    +
  • +
  • <a href="#errno.overflow" name="errno.overflow"></a> overflow
    Value too large to be stored in data type.

    +
  • +
  • <a href="#errno.ownerdead" name="errno.ownerdead"></a> ownerdead
    Previous owner died.

    +
  • +
  • <a href="#errno.perm" name="errno.perm"></a> perm
    Operation not permitted.

    +
  • +
  • <a href="#errno.pipe" name="errno.pipe"></a> pipe
    Broken pipe.

    +
  • +
  • <a href="#errno.proto" name="errno.proto"></a> proto
    Protocol error.

    +
  • +
  • <a href="#errno.protonosupport" name="errno.protonosupport"></a> protonosupport
    Protocol not supported.

    +
  • +
  • <a href="#errno.prototype" name="errno.prototype"></a> prototype
    Protocol wrong type for socket.

    +
  • +
  • <a href="#errno.range" name="errno.range"></a> range
    Result too large.

    +
  • +
  • <a href="#errno.rofs" name="errno.rofs"></a> rofs
    Read-only file system.

    +
  • +
  • <a href="#errno.spipe" name="errno.spipe"></a> spipe
    Invalid seek.

    +
  • +
  • <a href="#errno.srch" name="errno.srch"></a> srch
    No such process.

    +
  • +
  • <a href="#errno.stale" name="errno.stale"></a> stale
    Reserved.

    +
  • +
  • <a href="#errno.timedout" name="errno.timedout"></a> timedout
    Connection timed out.

    +
  • +
  • <a href="#errno.txtbsy" name="errno.txtbsy"></a> txtbsy
    Text file busy.

    +
  • +
  • <a href="#errno.xdev" name="errno.xdev"></a> xdev
    Cross-device link.

    +
  • +
  • <a href="#errno.notcapable" name="errno.notcapable"></a> notcapable
    Extension: Capabilities insufficient.

    +
  • +
+

<a href="#rights" name="rights"></a> rights: Flags(u64)

+

File descriptor rights, determining which actions may be performed.
Size: 8
Alignment: 8

+

Flags

+
    +
  • <a href="#rights.fd_datasync" name="rights.fd_datasync"></a> fd_datasync
    The right to invoke fd_datasync.
    If path_open is set, includes the right to invoke
    path_open with fdflags::dsync.

    +
  • +
  • <a href="#rights.fd_read" name="rights.fd_read"></a> fd_read
    The right to invoke fd_read and sock_recv.
    If rights::fd_seek is set, includes the right to invoke fd_pread.

    +
  • +
  • <a href="#rights.fd_seek" name="rights.fd_seek"></a> fd_seek
    The right to invoke fd_seek. This flag implies rights::fd_tell.

    +
  • +
  • <a href="#rights.fd_fdstat_set_flags" name="rights.fd_fdstat_set_flags"></a> fd_fdstat_set_flags
    The right to invoke fd_fdstat_set_flags.

    +
  • +
  • <a href="#rights.fd_sync" name="rights.fd_sync"></a> fd_sync
    The right to invoke fd_sync.
    If path_open is set, includes the right to invoke
    path_open with fdflags::rsync and fdflags::dsync.

    +
  • +
  • <a href="#rights.fd_tell" name="rights.fd_tell"></a> fd_tell
    The right to invoke fd_seek in such a way that the file offset
    remains unaltered (i.e., whence::cur with offset zero), or to
    invoke fd_tell.

    +
  • +
  • <a href="#rights.fd_write" name="rights.fd_write"></a> fd_write
    The right to invoke fd_write and sock_send.
    If rights::fd_seek is set, includes the right to invoke fd_pwrite.

    +
  • +
  • <a href="#rights.fd_advise" name="rights.fd_advise"></a> fd_advise
    The right to invoke fd_advise.

    +
  • +
  • <a href="#rights.fd_allocate" name="rights.fd_allocate"></a> fd_allocate
    The right to invoke fd_allocate.

    +
  • +
  • <a href="#rights.path_create_directory" name="rights.path_create_directory"></a> path_create_directory
    The right to invoke path_create_directory.

    +
  • +
  • <a href="#rights.path_create_file" name="rights.path_create_file"></a> path_create_file
    If path_open is set, the right to invoke path_open with oflags::creat.

    +
  • +
  • <a href="#rights.path_link_source" name="rights.path_link_source"></a> path_link_source
    The right to invoke path_link with the file descriptor as the
    source directory.

    +
  • +
  • <a href="#rights.path_link_target" name="rights.path_link_target"></a> path_link_target
    The right to invoke path_link with the file descriptor as the
    target directory.

    +
  • +
  • <a href="#rights.path_open" name="rights.path_open"></a> path_open
    The right to invoke path_open.

    +
  • +
  • <a href="#rights.fd_readdir" name="rights.fd_readdir"></a> fd_readdir
    The right to invoke fd_readdir.

    +
  • +
  • <a href="#rights.path_readlink" name="rights.path_readlink"></a> path_readlink
    The right to invoke path_readlink.

    +
  • +
  • <a href="#rights.path_rename_source" name="rights.path_rename_source"></a> path_rename_source
    The right to invoke path_rename with the file descriptor as the source directory.

    +
  • +
  • <a href="#rights.path_rename_target" name="rights.path_rename_target"></a> path_rename_target
    The right to invoke path_rename with the file descriptor as the target directory.

    +
  • +
  • <a href="#rights.path_filestat_get" name="rights.path_filestat_get"></a> path_filestat_get
    The right to invoke path_filestat_get.

    +
  • +
  • <a href="#rights.path_filestat_set_size" name="rights.path_filestat_set_size"></a> path_filestat_set_size
    The right to change a file's size (there is no path_filestat_set_size).
    If path_open is set, includes the right to invoke path_open with oflags::trunc.

    +
  • +
  • <a href="#rights.path_filestat_set_times" name="rights.path_filestat_set_times"></a> path_filestat_set_times
    The right to invoke path_filestat_set_times.

    +
  • +
  • <a href="#rights.fd_filestat_get" name="rights.fd_filestat_get"></a> fd_filestat_get
    The right to invoke fd_filestat_get.

    +
  • +
  • <a href="#rights.fd_filestat_set_size" name="rights.fd_filestat_set_size"></a> fd_filestat_set_size
    The right to invoke fd_filestat_set_size.

    +
  • +
  • <a href="#rights.fd_filestat_set_times" name="rights.fd_filestat_set_times"></a> fd_filestat_set_times
    The right to invoke fd_filestat_set_times.

    +
  • +
  • <a href="#rights.path_symlink" name="rights.path_symlink"></a> path_symlink
    The right to invoke path_symlink.

    +
  • +
  • <a href="#rights.path_remove_directory" name="rights.path_remove_directory"></a> path_remove_directory
    The right to invoke path_remove_directory.

    +
  • +
  • <a href="#rights.path_unlink_file" name="rights.path_unlink_file"></a> path_unlink_file
    The right to invoke path_unlink_file.

    +
  • +
  • <a href="#rights.poll_fd_readwrite" name="rights.poll_fd_readwrite"></a> poll_fd_readwrite
    If rights::fd_read is set, includes the right to invoke poll_oneoff to subscribe to eventtype::fd_read.
    If rights::fd_write is set, includes the right to invoke poll_oneoff to subscribe to eventtype::fd_write.

    +
  • +
  • <a href="#rights.sock_shutdown" name="rights.sock_shutdown"></a> sock_shutdown
    The right to invoke sock_shutdown.

    +
  • +
+

<a href="#fd" name="fd"></a> fd

+

A file descriptor handle.
Size: 4
Alignment: 4

+

Supertypes

+

<a href="#iovec" name="iovec"></a> iovec: Struct

+

A region of memory for scatter/gather reads.
Size: 8
Alignment: 4

+

Struct members

+
    +
  • <a href="#iovec.buf" name="iovec.buf"></a> buf: Pointer<u8>
    The address of the buffer to be filled.
    Offset: 0
  • +
  • <a href="#iovec.buf_len" name="iovec.buf_len"></a> buf_len: size
    The length of the buffer to be filled.
    Offset: 4

    <a href="#ciovec" name="ciovec"></a> ciovec: Struct

    +A region of memory for scatter/gather writes.
    Size: 8
    Alignment: 4

    Struct members

    +
  • +
  • <a href="#ciovec.buf" name="ciovec.buf"></a> buf: ConstPointer<u8>
    The address of the buffer to be written.
    Offset: 0
  • +
  • <a href="#ciovec.buf_len" name="ciovec.buf_len"></a> buf_len: size
    The length of the buffer to be written.
    Offset: 4

    <a href="#iovec_array" name="iovec_array"></a> iovec_array: Array<iovec>

    +Size: 8
    Alignment: 4

    <a href="#ciovec_array" name="ciovec_array"></a> ciovec_array: Array<ciovec>

    +Size: 8
    Alignment: 4

    <a href="#filedelta" name="filedelta"></a> filedelta: s64

    +Relative offset within a file.
    Size: 8
    Alignment: 8

    <a href="#whence" name="whence"></a> whence: Enum(u8)

    +The position relative to which to set the offset of the file descriptor.
    Size: 1
    Alignment: 1

    Variants

    +
  • +
  • <a href="#whence.set" name="whence.set"></a> set
    Seek relative to start-of-file.

    +
  • +
  • <a href="#whence.cur" name="whence.cur"></a> cur
    Seek relative to current position.

    +
  • +
  • <a href="#whence.end" name="whence.end"></a> end
    Seek relative to end-of-file.

    +
  • +
+

<a href="#dircookie" name="dircookie"></a> dircookie: u64

+

A reference to the offset of a directory entry.

+

The value 0 signifies the start of the directory.
Size: 8
Alignment: 8

+

<a href="#dirnamlen" name="dirnamlen"></a> dirnamlen: u32

+

The type for the $d_namlen field of $dirent.
Size: 4
Alignment: 4

+

<a href="#inode" name="inode"></a> inode: u64

+

File serial number that is unique within its file system.
Size: 8
Alignment: 8

+

<a href="#filetype" name="filetype"></a> filetype: Enum(u8)

+

The type of a file descriptor or file.
Size: 1
Alignment: 1

+

Variants

+
    +
  • <a href="#filetype.unknown" name="filetype.unknown"></a> unknown
    The type of the file descriptor or file is unknown or is different from any of the other types specified.

    +
  • +
  • <a href="#filetype.block_device" name="filetype.block_device"></a> block_device
    The file descriptor or file refers to a block device inode.

    +
  • +
  • <a href="#filetype.character_device" name="filetype.character_device"></a> character_device
    The file descriptor or file refers to a character device inode.

    +
  • +
  • <a href="#filetype.directory" name="filetype.directory"></a> directory
    The file descriptor or file refers to a directory inode.

    +
  • +
  • <a href="#filetype.regular_file" name="filetype.regular_file"></a> regular_file
    The file descriptor or file refers to a regular file inode.

    +
  • +
  • <a href="#filetype.socket_dgram" name="filetype.socket_dgram"></a> socket_dgram
    The file descriptor or file refers to a datagram socket.

    +
  • +
  • <a href="#filetype.socket_stream" name="filetype.socket_stream"></a> socket_stream
    The file descriptor or file refers to a byte-stream socket.

    +
  • +
  • <a href="#filetype.symbolic_link" name="filetype.symbolic_link"></a> symbolic_link
    The file refers to a symbolic link inode.

    +
  • +
+

<a href="#dirent" name="dirent"></a> dirent: Struct

+

A directory entry.
Size: 24
Alignment: 8

+

Struct members

+
    +
  • <a href="#dirent.d_next" name="dirent.d_next"></a> d_next: dircookie
    The offset of the next directory entry stored in this directory.
    Offset: 0
  • +
  • <a href="#dirent.d_ino" name="dirent.d_ino"></a> d_ino: inode
    The serial number of the file referred to by this directory entry.
    Offset: 8
  • +
  • <a href="#dirent.d_namlen" name="dirent.d_namlen"></a> d_namlen: dirnamlen
    The length of the name of the directory entry.
    Offset: 16
  • +
  • <a href="#dirent.d_type" name="dirent.d_type"></a> d_type: filetype
    The type of the file referred to by this directory entry.
    Offset: 20

    <a href="#advice" name="advice"></a> advice: Enum(u8)

    +File or memory access pattern advisory information.
    Size: 1
    Alignment: 1

    Variants

    +
  • +
  • <a href="#advice.normal" name="advice.normal"></a> normal
    The application has no advice to give on its behavior with respect to the specified data.

    +
  • +
  • <a href="#advice.sequential" name="advice.sequential"></a> sequential
    The application expects to access the specified data sequentially from lower offsets to higher offsets.

    +
  • +
  • <a href="#advice.random" name="advice.random"></a> random
    The application expects to access the specified data in a random order.

    +
  • +
  • <a href="#advice.willneed" name="advice.willneed"></a> willneed
    The application expects to access the specified data in the near future.

    +
  • +
  • <a href="#advice.dontneed" name="advice.dontneed"></a> dontneed
    The application expects that it will not access the specified data in the near future.

    +
  • +
  • <a href="#advice.noreuse" name="advice.noreuse"></a> noreuse
    The application expects to access the specified data once and then not reuse it thereafter.

    +
  • +
+

<a href="#fdflags" name="fdflags"></a> fdflags: Flags(u16)

+

File descriptor flags.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#fdflags.append" name="fdflags.append"></a> append
    Append mode: Data written to the file is always appended to the file's end.

    +
  • +
  • <a href="#fdflags.dsync" name="fdflags.dsync"></a> dsync
    Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized.

    +
  • +
  • <a href="#fdflags.nonblock" name="fdflags.nonblock"></a> nonblock
    Non-blocking mode.

    +
  • +
  • <a href="#fdflags.rsync" name="fdflags.rsync"></a> rsync
    Synchronized read I/O operations.

    +
  • +
  • <a href="#fdflags.sync" name="fdflags.sync"></a> sync
    Write according to synchronized I/O file integrity completion. In
    addition to synchronizing the data stored in the file, the implementation
    may also synchronously update the file's metadata.

    +
  • +
+

<a href="#fdstat" name="fdstat"></a> fdstat: Struct

+

File descriptor attributes.
Size: 24
Alignment: 8

+

Struct members

+
    +
  • <a href="#fdstat.fs_filetype" name="fdstat.fs_filetype"></a> fs_filetype: filetype
    File type.
    Offset: 0
  • +
  • <a href="#fdstat.fs_flags" name="fdstat.fs_flags"></a> fs_flags: fdflags
    File descriptor flags.
    Offset: 2
  • +
  • <a href="#fdstat.fs_rights_base" name="fdstat.fs_rights_base"></a> fs_rights_base: rights
    Rights that apply to this file descriptor.
    Offset: 8
  • +
  • <a href="#fdstat.fs_rights_inheriting" name="fdstat.fs_rights_inheriting"></a> fs_rights_inheriting: rights
    Maximum set of rights that may be installed on new file descriptors that
    are created through this file descriptor, e.g., through path_open.
    Offset: 16

    <a href="#device" name="device"></a> device: u64

    +Identifier for a device containing a file system. Can be used in combination
    with inode to uniquely identify a file or directory in the filesystem.
    Size: 8
    Alignment: 8

    <a href="#fstflags" name="fstflags"></a> fstflags: Flags(u16)

    +Which file time attributes to adjust.
    Size: 2
    Alignment: 2

    Flags

    +
  • +
  • <a href="#fstflags.atim" name="fstflags.atim"></a> atim
    Adjust the last data access timestamp to the value stored in filestat::atim.

    +
  • +
  • <a href="#fstflags.atim_now" name="fstflags.atim_now"></a> atim_now
    Adjust the last data access timestamp to the time of clock clockid::realtime.

    +
  • +
  • <a href="#fstflags.mtim" name="fstflags.mtim"></a> mtim
    Adjust the last data modification timestamp to the value stored in filestat::mtim.

    +
  • +
  • <a href="#fstflags.mtim_now" name="fstflags.mtim_now"></a> mtim_now
    Adjust the last data modification timestamp to the time of clock clockid::realtime.

    +
  • +
+

<a href="#lookupflags" name="lookupflags"></a> lookupflags: Flags(u32)

+

Flags determining the method of how paths are resolved.
Size: 4
Alignment: 4

+

Flags

+
    +
  • <a href="#lookupflags.symlink_follow" name="lookupflags.symlink_follow"></a> symlink_follow
    As long as the resolved path corresponds to a symbolic link, it is expanded.
  • +
+

<a href="#oflags" name="oflags"></a> oflags: Flags(u16)

+

Open flags used by path_open.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#oflags.creat" name="oflags.creat"></a> creat
    Create file if it does not exist.

    +
  • +
  • <a href="#oflags.directory" name="oflags.directory"></a> directory
    Fail if not a directory.

    +
  • +
  • <a href="#oflags.excl" name="oflags.excl"></a> excl
    Fail if file already exists.

    +
  • +
  • <a href="#oflags.trunc" name="oflags.trunc"></a> trunc
    Truncate file to size 0.

    +
  • +
+

<a href="#linkcount" name="linkcount"></a> linkcount: u64

+

Number of hard links to an inode.
Size: 8
Alignment: 8

+

<a href="#filestat" name="filestat"></a> filestat: Struct

+

File attributes.
Size: 64
Alignment: 8

+

Struct members

+
    +
  • <a href="#filestat.dev" name="filestat.dev"></a> dev: device
    Device ID of device containing the file.
    Offset: 0
  • +
  • <a href="#filestat.ino" name="filestat.ino"></a> ino: inode
    File serial number.
    Offset: 8
  • +
  • <a href="#filestat.filetype" name="filestat.filetype"></a> filetype: filetype
    File type.
    Offset: 16
  • +
  • <a href="#filestat.nlink" name="filestat.nlink"></a> nlink: linkcount
    Number of hard links to the file.
    Offset: 24
  • +
  • <a href="#filestat.size" name="filestat.size"></a> size: filesize
    For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link.
    Offset: 32
  • +
  • <a href="#filestat.atim" name="filestat.atim"></a> atim: timestamp
    Last data access timestamp.
    Offset: 40
  • +
  • <a href="#filestat.mtim" name="filestat.mtim"></a> mtim: timestamp
    Last data modification timestamp.
    Offset: 48
  • +
  • <a href="#filestat.ctim" name="filestat.ctim"></a> ctim: timestamp
    Last file status change timestamp.
    Offset: 56

    <a href="#userdata" name="userdata"></a> userdata: u64

    +User-provided value that may be attached to objects that is retained when
    extracted from the implementation.
    Size: 8
    Alignment: 8

    <a href="#eventtype" name="eventtype"></a> eventtype: Enum(u8)

    +Type of a subscription to an event or its occurrence.
    Size: 1
    Alignment: 1

    Variants

    +
  • +
  • <a href="#eventtype.clock" name="eventtype.clock"></a> clock
    The time value of clock subscription_clock::id has
    reached timestamp subscription_clock::timeout.

    +
  • +
  • <a href="#eventtype.fd_read" name="eventtype.fd_read"></a> fd_read
    File descriptor subscription_fd_readwrite::file_descriptor has data
    available for reading. This event always triggers for regular files.

    +
  • +
  • <a href="#eventtype.fd_write" name="eventtype.fd_write"></a> fd_write
    File descriptor subscription_fd_readwrite::file_descriptor has capacity
    available for writing. This event always triggers for regular files.

    +
  • +
+

<a href="#eventrwflags" name="eventrwflags"></a> eventrwflags: Flags(u16)

+

The state of the file descriptor subscribed to with
eventtype::fd_read or eventtype::fd_write.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#eventrwflags.fd_readwrite_hangup" name="eventrwflags.fd_readwrite_hangup"></a> fd_readwrite_hangup
    The peer of this socket has closed or disconnected.
  • +
+

<a href="#event_fd_readwrite" name="event_fd_readwrite"></a> event_fd_readwrite: Struct

+

The contents of an $event when type is eventtype::fd_read or
eventtype::fd_write.
Size: 16
Alignment: 8

+

Struct members

+
    +
  • <a href="#event_fd_readwrite.nbytes" name="event_fd_readwrite.nbytes"></a> nbytes: filesize
    The number of bytes available for reading or writing.
    Offset: 0
  • +
  • <a href="#event_fd_readwrite.flags" name="event_fd_readwrite.flags"></a> flags: eventrwflags
    The state of the file descriptor.
    Offset: 8

    <a href="#event" name="event"></a> event: Struct

    +An event that occurred.
    Size: 32
    Alignment: 8

    Struct members

    +
  • +
  • <a href="#event.userdata" name="event.userdata"></a> userdata: userdata
    User-provided value that got attached to subscription::userdata.
    Offset: 0
  • +
  • <a href="#event.error" name="event.error"></a> error: errno
    If non-zero, an error that occurred while processing the subscription request.
    Offset: 8
  • +
  • <a href="#event.type" name="event.type"></a> type: eventtype
    The type of event that occured
    Offset: 10
  • +
  • <a href="#event.fd_readwrite" name="event.fd_readwrite"></a> fd_readwrite: event_fd_readwrite
    The contents of the event, if it is an eventtype::fd_read or
    eventtype::fd_write. eventtype::clock events ignore this field.
    Offset: 16

    <a href="#subclockflags" name="subclockflags"></a> subclockflags: Flags(u16)

    +Flags determining how to interpret the timestamp provided in
    subscription_clock::timeout.
    Size: 2
    Alignment: 2

    Flags

    +
  • +
  • <a href="#subclockflags.subscription_clock_abstime" name="subclockflags.subscription_clock_abstime"></a> subscription_clock_abstime
    If set, treat the timestamp provided in
    subscription_clock::timeout as an absolute timestamp of clock
    subscription_clock::id. If clear, treat the timestamp
    provided in subscription_clock::timeout relative to the
    current time value of clock subscription_clock::id.
  • +
+

<a href="#subscription_clock" name="subscription_clock"></a> subscription_clock: Struct

+

The contents of a subscription when type is eventtype::clock.
Size: 32
Alignment: 8

+

Struct members

+
    +
  • <a href="#subscription_clock.id" name="subscription_clock.id"></a> id: clockid
    The clock against which to compare the timestamp.
    Offset: 0
  • +
  • <a href="#subscription_clock.timeout" name="subscription_clock.timeout"></a> timeout: timestamp
    The absolute or relative timestamp.
    Offset: 8
  • +
  • <a href="#subscription_clock.precision" name="subscription_clock.precision"></a> precision: timestamp
    The amount of time that the implementation may wait additionally
    to coalesce with other events.
    Offset: 16
  • +
  • <a href="#subscription_clock.flags" name="subscription_clock.flags"></a> flags: subclockflags
    Flags specifying whether the timeout is absolute or relative
    Offset: 24

    <a href="#subscription_fd_readwrite" name="subscription_fd_readwrite"></a> subscription_fd_readwrite: Struct

    +The contents of a subscription when type is type is
    eventtype::fd_read or eventtype::fd_write.
    Size: 4
    Alignment: 4

    Struct members

    +
  • +
  • <a href="#subscription_fd_readwrite.file_descriptor" name="subscription_fd_readwrite.file_descriptor"></a> file_descriptor: fd
    The file descriptor on which to wait for it to become ready for reading or writing.
    Offset: 0

    <a href="#subscription_u" name="subscription_u"></a> subscription_u: Union

    +The contents of a subscription.
    Size: 40
    Alignment: 8

    Union Layout

    +
  • +
  • tag_size: 1
  • +
  • tag_align: 1
  • +
  • contents_offset: 8
  • +
  • contents_size: 32
  • +
  • contents_align: 8

    Union variants

    +
  • +
  • <a href="#subscription_u.clock" name="subscription_u.clock"></a> clock: subscription_clock

    +
  • +
  • <a href="#subscription_u.fd_read" name="subscription_u.fd_read"></a> fd_read: subscription_fd_readwrite

    +
  • +
  • <a href="#subscription_u.fd_write" name="subscription_u.fd_write"></a> fd_write: subscription_fd_readwrite

    +
  • +
+

<a href="#subscription" name="subscription"></a> subscription: Struct

+

Subscription to an event.
Size: 48
Alignment: 8

+

Struct members

+
    +
  • <a href="#subscription.userdata" name="subscription.userdata"></a> userdata: userdata
    User-provided value that is attached to the subscription in the
    implementation and returned through event::userdata.
    Offset: 0
  • +
  • <a href="#subscription.u" name="subscription.u"></a> u: subscription_u
    The type of the event to which to subscribe, and its contents
    Offset: 8

    <a href="#exitcode" name="exitcode"></a> exitcode: u32

    +Exit code generated by a process when exiting.
    Size: 4
    Alignment: 4

    <a href="#signal" name="signal"></a> signal: Enum(u8)

    +Signal condition.
    Size: 1
    Alignment: 1

    Variants

    +
  • +
  • <a href="#signal.none" name="signal.none"></a> none
    No signal. Note that POSIX has special semantics for kill(pid, 0),
    so this value is reserved.

    +
  • +
  • <a href="#signal.hup" name="signal.hup"></a> hup
    Hangup.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.int" name="signal.int"></a> int
    Terminate interrupt signal.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.quit" name="signal.quit"></a> quit
    Terminal quit signal.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.ill" name="signal.ill"></a> ill
    Illegal instruction.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.trap" name="signal.trap"></a> trap
    Trace/breakpoint trap.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.abrt" name="signal.abrt"></a> abrt
    Process abort signal.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.bus" name="signal.bus"></a> bus
    Access to an undefined portion of a memory object.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.fpe" name="signal.fpe"></a> fpe
    Erroneous arithmetic operation.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.kill" name="signal.kill"></a> kill
    Kill.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.usr1" name="signal.usr1"></a> usr1
    User-defined signal 1.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.segv" name="signal.segv"></a> segv
    Invalid memory reference.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.usr2" name="signal.usr2"></a> usr2
    User-defined signal 2.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.pipe" name="signal.pipe"></a> pipe
    Write on a pipe with no one to read it.
    Action: Ignored.

    +
  • +
  • <a href="#signal.alrm" name="signal.alrm"></a> alrm
    Alarm clock.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.term" name="signal.term"></a> term
    Termination signal.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.chld" name="signal.chld"></a> chld
    Child process terminated, stopped, or continued.
    Action: Ignored.

    +
  • +
  • <a href="#signal.cont" name="signal.cont"></a> cont
    Continue executing, if stopped.
    Action: Continues executing, if stopped.

    +
  • +
  • <a href="#signal.stop" name="signal.stop"></a> stop
    Stop executing.
    Action: Stops executing.

    +
  • +
  • <a href="#signal.tstp" name="signal.tstp"></a> tstp
    Terminal stop signal.
    Action: Stops executing.

    +
  • +
  • <a href="#signal.ttin" name="signal.ttin"></a> ttin
    Background process attempting read.
    Action: Stops executing.

    +
  • +
  • <a href="#signal.ttou" name="signal.ttou"></a> ttou
    Background process attempting write.
    Action: Stops executing.

    +
  • +
  • <a href="#signal.urg" name="signal.urg"></a> urg
    High bandwidth data is available at a socket.
    Action: Ignored.

    +
  • +
  • <a href="#signal.xcpu" name="signal.xcpu"></a> xcpu
    CPU time limit exceeded.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.xfsz" name="signal.xfsz"></a> xfsz
    File size limit exceeded.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.vtalrm" name="signal.vtalrm"></a> vtalrm
    Virtual timer expired.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.prof" name="signal.prof"></a> prof
    Profiling timer expired.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.winch" name="signal.winch"></a> winch
    Window changed.
    Action: Ignored.

    +
  • +
  • <a href="#signal.poll" name="signal.poll"></a> poll
    I/O possible.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.pwr" name="signal.pwr"></a> pwr
    Power failure.
    Action: Terminates the process.

    +
  • +
  • <a href="#signal.sys" name="signal.sys"></a> sys
    Bad system call.
    Action: Terminates the process.

    +
  • +
+

<a href="#riflags" name="riflags"></a> riflags: Flags(u16)

+

Flags provided to sock_recv.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#riflags.recv_peek" name="riflags.recv_peek"></a> recv_peek
    Returns the message without removing it from the socket's receive queue.

    +
  • +
  • <a href="#riflags.recv_waitall" name="riflags.recv_waitall"></a> recv_waitall
    On byte-stream sockets, block until the full amount of data can be returned.

    +
  • +
+

<a href="#roflags" name="roflags"></a> roflags: Flags(u16)

+

Flags returned by sock_recv.
Size: 2
Alignment: 2

+

Flags

+
    +
  • <a href="#roflags.recv_data_truncated" name="roflags.recv_data_truncated"></a> recv_data_truncated
    Returned by sock_recv: Message data has been truncated.
  • +
+

<a href="#siflags" name="siflags"></a> siflags: u16

+

Flags provided to sock_send. As there are currently no flags
defined, it must be set to zero.
Size: 2
Alignment: 2

+

<a href="#sdflags" name="sdflags"></a> sdflags: Flags(u8)

+

Which channels on a socket to shut down.
Size: 1
Alignment: 1

+

Flags

+
    +
  • <a href="#sdflags.rd" name="sdflags.rd"></a> rd
    Disables further receive operations.

    +
  • +
  • <a href="#sdflags.wr" name="sdflags.wr"></a> wr
    Disables further send operations.

    +
  • +
+

<a href="#preopentype" name="preopentype"></a> preopentype: Enum(u8)

+

Identifiers for preopened capabilities.
Size: 1
Alignment: 1

+

Variants

+
    +
  • <a href="#preopentype.dir" name="preopentype.dir"></a> dir
    A pre-opened directory.
  • +
+

<a href="#prestat_dir" name="prestat_dir"></a> prestat_dir: Struct

+

The contents of a $prestat when type is preopentype::dir.
Size: 4
Alignment: 4

+

Struct members

+
    +
  • <a href="#prestat_dir.pr_name_len" name="prestat_dir.pr_name_len"></a> pr_name_len: size
    The length of the directory name for use with fd_prestat_dir_name.
    Offset: 0

    <a href="#prestat" name="prestat"></a> prestat: Union

    +Information about a pre-opened capability.
    Size: 8
    Alignment: 4

    Union Layout

    +
  • +
  • tag_size: 1
  • +
  • tag_align: 1
  • +
  • contents_offset: 4
  • +
  • contents_size: 4
  • +
  • contents_align: 4

    Union variants

    +
  • +
  • <a href="#prestat.dir" name="prestat.dir"></a> dir: prestat_dir
  • +
+

Modules

+

<a href="#wasi_snapshot_preview1" name="wasi_snapshot_preview1"></a> wasi_snapshot_preview1

+

Imports

+

Memory

+

Functions

+
+

<a href="#args_get" name="args_get"></a> args_get(argv: Pointer<Pointer<u8>>, argv_buf: Pointer<u8>) -> errno

+

Read command-line argument data.
The size of the array should match that returned by args_sizes_get

+
Params
+
    +
  • <a href="#args_get.argv" name="args_get.argv"></a> argv: Pointer<Pointer<u8>>

    +
  • +
  • <a href="#args_get.argv_buf" name="args_get.argv_buf"></a> argv_buf: Pointer<u8>

    +
  • +
+
Results
+
    +
  • <a href="#args_get.error" name="args_get.error"></a> error: errno
  • +
+
+

<a href="#args_sizes_get" name="args_sizes_get"></a> args_sizes_get() -> (errno, size, size)

+

Return command-line argument data sizes.

+
Params
+
Results
+
    +
  • <a href="#args_sizes_get.error" name="args_sizes_get.error"></a> error: errno

    +
  • +
  • <a href="#args_sizes_get.argc" name="args_sizes_get.argc"></a> argc: size
    The number of arguments.

    +
  • +
  • <a href="#args_sizes_get.argv_buf_size" name="args_sizes_get.argv_buf_size"></a> argv_buf_size: size
    The size of the argument string data.

    +
  • +
+
+

<a href="#environ_get" name="environ_get"></a> environ_get(environ: Pointer<Pointer<u8>>, environ_buf: Pointer<u8>) -> errno

+

Read environment variable data.
The sizes of the buffers should match that returned by environ_sizes_get.

+
Params
+
    +
  • <a href="#environ_get.environ" name="environ_get.environ"></a> environ: Pointer<Pointer<u8>>

    +
  • +
  • <a href="#environ_get.environ_buf" name="environ_get.environ_buf"></a> environ_buf: Pointer<u8>

    +
  • +
+
Results
+
    +
  • <a href="#environ_get.error" name="environ_get.error"></a> error: errno
  • +
+
+

<a href="#environ_sizes_get" name="environ_sizes_get"></a> environ_sizes_get() -> (errno, size, size)

+

Return environment variable data sizes.

+
Params
+
Results
+
    +
  • <a href="#environ_sizes_get.error" name="environ_sizes_get.error"></a> error: errno

    +
  • +
  • <a href="#environ_sizes_get.environc" name="environ_sizes_get.environc"></a> environc: size
    The number of environment variable arguments.

    +
  • +
  • <a href="#environ_sizes_get.environ_buf_size" name="environ_sizes_get.environ_buf_size"></a> environ_buf_size: size
    The size of the environment variable data.

    +
  • +
+
+

<a href="#clock_res_get" name="clock_res_get"></a> clock_res_get(id: clockid) -> (errno, timestamp)

+

Return the resolution of a clock.
Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks,
return errno::inval.
Note: This is similar to clock_getres in POSIX.

+
Params
+
    +
  • <a href="#clock_res_get.id" name="clock_res_get.id"></a> id: clockid
    The clock for which to return the resolution.
  • +
+
Results
+
    +
  • <a href="#clock_res_get.error" name="clock_res_get.error"></a> error: errno

    +
  • +
  • <a href="#clock_res_get.resolution" name="clock_res_get.resolution"></a> resolution: timestamp
    The resolution of the clock.

    +
  • +
+
+

<a href="#clock_time_get" name="clock_time_get"></a> clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)

+

Return the time value of a clock.
Note: This is similar to clock_gettime in POSIX.

+
Params
+
    +
  • <a href="#clock_time_get.id" name="clock_time_get.id"></a> id: clockid
    The clock for which to return the time.

    +
  • +
  • <a href="#clock_time_get.precision" name="clock_time_get.precision"></a> precision: timestamp
    The maximum lag (exclusive) that the returned time value may have, compared to its actual value.

    +
  • +
+
Results
+
    +
  • <a href="#clock_time_get.error" name="clock_time_get.error"></a> error: errno

    +
  • +
  • <a href="#clock_time_get.time" name="clock_time_get.time"></a> time: timestamp
    The time value of the clock.

    +
  • +
+
+

<a href="#fd_advise" name="fd_advise"></a> fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno

+

Provide file advisory information on a file descriptor.
Note: This is similar to posix_fadvise in POSIX.

+
Params
+
    +
  • <a href="#fd_advise.fd" name="fd_advise.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_advise.offset" name="fd_advise.offset"></a> offset: filesize
    The offset within the file to which the advisory applies.

    +
  • +
  • <a href="#fd_advise.len" name="fd_advise.len"></a> len: filesize
    The length of the region to which the advisory applies.

    +
  • +
  • <a href="#fd_advise.advice" name="fd_advise.advice"></a> advice: advice
    The advice.

    +
  • +
+
Results
+
    +
  • <a href="#fd_advise.error" name="fd_advise.error"></a> error: errno
  • +
+
+

<a href="#fd_allocate" name="fd_allocate"></a> fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno

+

Force the allocation of space in a file.
Note: This is similar to posix_fallocate in POSIX.

+
Params
+
    +
  • <a href="#fd_allocate.fd" name="fd_allocate.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_allocate.offset" name="fd_allocate.offset"></a> offset: filesize
    The offset at which to start the allocation.

    +
  • +
  • <a href="#fd_allocate.len" name="fd_allocate.len"></a> len: filesize
    The length of the area that is allocated.

    +
  • +
+
Results
+
    +
  • <a href="#fd_allocate.error" name="fd_allocate.error"></a> error: errno
  • +
+
+

<a href="#fd_close" name="fd_close"></a> fd_close(fd: fd) -> errno

+

Close a file descriptor.
Note: This is similar to close in POSIX.

+
Params
+
    +
  • <a href="#fd_close.fd" name="fd_close.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_close.error" name="fd_close.error"></a> error: errno
  • +
+
+

<a href="#fd_datasync" name="fd_datasync"></a> fd_datasync(fd: fd) -> errno

+

Synchronize the data of a file to disk.
Note: This is similar to fdatasync in POSIX.

+
Params
+
    +
  • <a href="#fd_datasync.fd" name="fd_datasync.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_datasync.error" name="fd_datasync.error"></a> error: errno
  • +
+
+

<a href="#fd_fdstat_get" name="fd_fdstat_get"></a> fd_fdstat_get(fd: fd) -> (errno, fdstat)

+

Get the attributes of a file descriptor.
Note: This returns similar flags to fsync(fd, F_GETFL) in POSIX, as well as additional fields.

+
Params
+
    +
  • <a href="#fd_fdstat_get.fd" name="fd_fdstat_get.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_fdstat_get.error" name="fd_fdstat_get.error"></a> error: errno

    +
  • +
  • <a href="#fd_fdstat_get.stat" name="fd_fdstat_get.stat"></a> stat: fdstat
    The buffer where the file descriptor's attributes are stored.

    +
  • +
+
+

<a href="#fd_fdstat_set_flags" name="fd_fdstat_set_flags"></a> fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno

+

Adjust the flags associated with a file descriptor.
Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

+
Params
+
    +
  • <a href="#fd_fdstat_set_flags.fd" name="fd_fdstat_set_flags.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_fdstat_set_flags.flags" name="fd_fdstat_set_flags.flags"></a> flags: fdflags
    The desired values of the file descriptor flags.

    +
  • +
+
Results
+
    +
  • <a href="#fd_fdstat_set_flags.error" name="fd_fdstat_set_flags.error"></a> error: errno
  • +
+
+

<a href="#fd_fdstat_set_rights" name="fd_fdstat_set_rights"></a> fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno

+

Adjust the rights associated with a file descriptor.
This can only be used to remove rights, and returns errno::notcapable if called in a way that would attempt to add rights

+
Params
+
    +
  • <a href="#fd_fdstat_set_rights.fd" name="fd_fdstat_set_rights.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_fdstat_set_rights.fs_rights_base" name="fd_fdstat_set_rights.fs_rights_base"></a> fs_rights_base: rights
    The desired rights of the file descriptor.

    +
  • +
  • <a href="#fd_fdstat_set_rights.fs_rights_inheriting" name="fd_fdstat_set_rights.fs_rights_inheriting"></a> fs_rights_inheriting: rights

    +
  • +
+
Results
+
    +
  • <a href="#fd_fdstat_set_rights.error" name="fd_fdstat_set_rights.error"></a> error: errno
  • +
+
+

<a href="#fd_filestat_get" name="fd_filestat_get"></a> fd_filestat_get(fd: fd) -> (errno, filestat)

+

Return the attributes of an open file.

+
Params
+
    +
  • <a href="#fd_filestat_get.fd" name="fd_filestat_get.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_filestat_get.error" name="fd_filestat_get.error"></a> error: errno

    +
  • +
  • <a href="#fd_filestat_get.buf" name="fd_filestat_get.buf"></a> buf: filestat
    The buffer where the file's attributes are stored.

    +
  • +
+
+

<a href="#fd_filestat_set_size" name="fd_filestat_set_size"></a> fd_filestat_set_size(fd: fd, size: filesize) -> errno

+

Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.
Note: This is similar to ftruncate in POSIX.

+
Params
+
    +
  • <a href="#fd_filestat_set_size.fd" name="fd_filestat_set_size.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_filestat_set_size.size" name="fd_filestat_set_size.size"></a> size: filesize
    The desired file size.

    +
  • +
+
Results
+
    +
  • <a href="#fd_filestat_set_size.error" name="fd_filestat_set_size.error"></a> error: errno
  • +
+
+

<a href="#fd_filestat_set_times" name="fd_filestat_set_times"></a> fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno

+

Adjust the timestamps of an open file or directory.
Note: This is similar to futimens in POSIX.

+
Params
+
    +
  • <a href="#fd_filestat_set_times.fd" name="fd_filestat_set_times.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_filestat_set_times.atim" name="fd_filestat_set_times.atim"></a> atim: timestamp
    The desired values of the data access timestamp.

    +
  • +
  • <a href="#fd_filestat_set_times.mtim" name="fd_filestat_set_times.mtim"></a> mtim: timestamp
    The desired values of the data modification timestamp.

    +
  • +
  • <a href="#fd_filestat_set_times.fst_flags" name="fd_filestat_set_times.fst_flags"></a> fst_flags: fstflags
    A bitmask indicating which timestamps to adjust.

    +
  • +
+
Results
+
    +
  • <a href="#fd_filestat_set_times.error" name="fd_filestat_set_times.error"></a> error: errno
  • +
+
+

<a href="#fd_pread" name="fd_pread"></a> fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)

+

Read from a file descriptor, without using and updating the file descriptor's offset.
Note: This is similar to preadv in POSIX.

+
Params
+
    +
  • <a href="#fd_pread.fd" name="fd_pread.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_pread.iovs" name="fd_pread.iovs"></a> iovs: iovec_array
    List of scatter/gather vectors in which to store data.

    +
  • +
  • <a href="#fd_pread.offset" name="fd_pread.offset"></a> offset: filesize
    The offset within the file at which to read.

    +
  • +
+
Results
+
    +
  • <a href="#fd_pread.error" name="fd_pread.error"></a> error: errno

    +
  • +
  • <a href="#fd_pread.nread" name="fd_pread.nread"></a> nread: size
    The number of bytes read.

    +
  • +
+
+

<a href="#fd_prestat_get" name="fd_prestat_get"></a> fd_prestat_get(fd: fd) -> (errno, prestat)

+

Return a description of the given preopened file descriptor.

+
Params
+
    +
  • <a href="#fd_prestat_get.fd" name="fd_prestat_get.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_prestat_get.error" name="fd_prestat_get.error"></a> error: errno

    +
  • +
  • <a href="#fd_prestat_get.buf" name="fd_prestat_get.buf"></a> buf: prestat
    The buffer where the description is stored.

    +
  • +
+
+

<a href="#fd_prestat_dir_name" name="fd_prestat_dir_name"></a> fd_prestat_dir_name(fd: fd, path: Pointer<u8>, path_len: size) -> errno

+

Return a description of the given preopened file descriptor.

+
Params
+
    +
  • <a href="#fd_prestat_dir_name.fd" name="fd_prestat_dir_name.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_prestat_dir_name.path" name="fd_prestat_dir_name.path"></a> path: Pointer<u8>
    A buffer into which to write the preopened directory name.

    +
  • +
  • <a href="#fd_prestat_dir_name.path_len" name="fd_prestat_dir_name.path_len"></a> path_len: size

    +
  • +
+
Results
+
    +
  • <a href="#fd_prestat_dir_name.error" name="fd_prestat_dir_name.error"></a> error: errno
  • +
+
+

<a href="#fd_pwrite" name="fd_pwrite"></a> fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)

+

Write to a file descriptor, without using and updating the file descriptor's offset.
Note: This is similar to pwritev in POSIX.

+
Params
+
    +
  • <a href="#fd_pwrite.fd" name="fd_pwrite.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_pwrite.iovs" name="fd_pwrite.iovs"></a> iovs: ciovec_array
    List of scatter/gather vectors from which to retrieve data.

    +
  • +
  • <a href="#fd_pwrite.offset" name="fd_pwrite.offset"></a> offset: filesize
    The offset within the file at which to write.

    +
  • +
+
Results
+
    +
  • <a href="#fd_pwrite.error" name="fd_pwrite.error"></a> error: errno

    +
  • +
  • <a href="#fd_pwrite.nwritten" name="fd_pwrite.nwritten"></a> nwritten: size
    The number of bytes written.

    +
  • +
+
+

<a href="#fd_read" name="fd_read"></a> fd_read(fd: fd, iovs: iovec_array) -> (errno, size)

+

Read from a file descriptor.
Note: This is similar to readv in POSIX.

+
Params
+
    +
  • <a href="#fd_read.fd" name="fd_read.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_read.iovs" name="fd_read.iovs"></a> iovs: iovec_array
    List of scatter/gather vectors to which to store data.

    +
  • +
+
Results
+
    +
  • <a href="#fd_read.error" name="fd_read.error"></a> error: errno

    +
  • +
  • <a href="#fd_read.nread" name="fd_read.nread"></a> nread: size
    The number of bytes read.

    +
  • +
+
+ +

Read directory entries from a directory.
When successful, the contents of the output buffer consist of a sequence of
directory entries. Each directory entry consists of a dirent_t object,
followed by dirent_t::d_namlen bytes holding the name of the directory
entry.
This function fills the output buffer as much as possible, potentially
truncating the last directory entry. This allows the caller to grow its
read buffer size in case it's too small to fit a single large directory
entry, or skip the oversized directory entry.

+
Params
+
    +
  • <a href="#fd_readdir.fd" name="fd_readdir.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_readdir.buf" name="fd_readdir.buf"></a> buf: Pointer<u8>
    The buffer where directory entries are stored

    +
  • +
  • <a href="#fd_readdir.buf_len" name="fd_readdir.buf_len"></a> buf_len: size

    +
  • +
  • <a href="#fd_readdir.cookie" name="fd_readdir.cookie"></a> cookie: dircookie
    The location within the directory to start reading

    +
  • +
+
Results
+
    +
  • <a href="#fd_readdir.error" name="fd_readdir.error"></a> error: errno

    +
  • +
  • <a href="#fd_readdir.bufused" name="fd_readdir.bufused"></a> bufused: size
    The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached.

    +
  • +
+
+

<a href="#fd_renumber" name="fd_renumber"></a> fd_renumber(fd: fd, to: fd) -> errno

+

Atomically replace a file descriptor by renumbering another file descriptor.
Due to the strong focus on thread safety, this environment does not provide
a mechanism to duplicate or renumber a file descriptor to an arbitrary
number, like dup2(). This would be prone to race conditions, as an actual
file descriptor with the same number could be allocated by a different
thread at the same time.
This function provides a way to atomically renumber file descriptors, which
would disappear if dup2() were to be removed entirely.

+
Params
+
    +
  • <a href="#fd_renumber.fd" name="fd_renumber.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_renumber.to" name="fd_renumber.to"></a> to: fd
    The file descriptor to overwrite.

    +
  • +
+
Results
+
    +
  • <a href="#fd_renumber.error" name="fd_renumber.error"></a> error: errno
  • +
+
+

<a href="#fd_seek" name="fd_seek"></a> fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)

+

Move the offset of a file descriptor.
Note: This is similar to lseek in POSIX.

+
Params
+
    +
  • <a href="#fd_seek.fd" name="fd_seek.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_seek.offset" name="fd_seek.offset"></a> offset: filedelta
    The number of bytes to move.

    +
  • +
  • <a href="#fd_seek.whence" name="fd_seek.whence"></a> whence: whence
    The base from which the offset is relative.

    +
  • +
+
Results
+
    +
  • <a href="#fd_seek.error" name="fd_seek.error"></a> error: errno

    +
  • +
  • <a href="#fd_seek.newoffset" name="fd_seek.newoffset"></a> newoffset: filesize
    The new offset of the file descriptor, relative to the start of the file.

    +
  • +
+
+

<a href="#fd_sync" name="fd_sync"></a> fd_sync(fd: fd) -> errno

+

Synchronize the data and metadata of a file to disk.
Note: This is similar to fsync in POSIX.

+
Params
+
    +
  • <a href="#fd_sync.fd" name="fd_sync.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_sync.error" name="fd_sync.error"></a> error: errno
  • +
+
+

<a href="#fd_tell" name="fd_tell"></a> fd_tell(fd: fd) -> (errno, filesize)

+

Return the current offset of a file descriptor.
Note: This is similar to lseek(fd, 0, SEEK_CUR) in POSIX.

+
Params
+
    +
  • <a href="#fd_tell.fd" name="fd_tell.fd"></a> fd: fd
  • +
+
Results
+
    +
  • <a href="#fd_tell.error" name="fd_tell.error"></a> error: errno

    +
  • +
  • <a href="#fd_tell.offset" name="fd_tell.offset"></a> offset: filesize
    The current offset of the file descriptor, relative to the start of the file.

    +
  • +
+
+

<a href="#fd_write" name="fd_write"></a> fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)

+

Write to a file descriptor.
Note: This is similar to writev in POSIX.

+
Params
+
    +
  • <a href="#fd_write.fd" name="fd_write.fd"></a> fd: fd

    +
  • +
  • <a href="#fd_write.iovs" name="fd_write.iovs"></a> iovs: ciovec_array
    List of scatter/gather vectors from which to retrieve data.

    +
  • +
+
Results
+
    +
  • <a href="#fd_write.error" name="fd_write.error"></a> error: errno

    +
  • +
  • <a href="#fd_write.nwritten" name="fd_write.nwritten"></a> nwritten: size
    The number of bytes written.

    +
  • +
+
+

<a href="#path_create_directory" name="path_create_directory"></a> path_create_directory(fd: fd, path: string) -> errno

+

Create a directory.
Note: This is similar to mkdirat in POSIX.

+
Params
+
    +
  • <a href="#path_create_directory.fd" name="path_create_directory.fd"></a> fd: fd

    +
  • +
  • <a href="#path_create_directory.path" name="path_create_directory.path"></a> path: string
    The path at which to create the directory.

    +
  • +
+
Results
+
    +
  • <a href="#path_create_directory.error" name="path_create_directory.error"></a> error: errno
  • +
+
+

<a href="#path_filestat_get" name="path_filestat_get"></a> path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)

+

Return the attributes of a file or directory.
Note: This is similar to stat in POSIX.

+
Params
+
    +
  • <a href="#path_filestat_get.fd" name="path_filestat_get.fd"></a> fd: fd

    +
  • +
  • <a href="#path_filestat_get.flags" name="path_filestat_get.flags"></a> flags: lookupflags
    Flags determining the method of how the path is resolved.

    +
  • +
  • <a href="#path_filestat_get.path" name="path_filestat_get.path"></a> path: string
    The path of the file or directory to inspect.

    +
  • +
+
Results
+
    +
  • <a href="#path_filestat_get.error" name="path_filestat_get.error"></a> error: errno

    +
  • +
  • <a href="#path_filestat_get.buf" name="path_filestat_get.buf"></a> buf: filestat
    The buffer where the file's attributes are stored.

    +
  • +
+
+

<a href="#path_filestat_set_times" name="path_filestat_set_times"></a> path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno

+

Adjust the timestamps of a file or directory.
Note: This is similar to utimensat in POSIX.

+
Params
+
    +
  • <a href="#path_filestat_set_times.fd" name="path_filestat_set_times.fd"></a> fd: fd

    +
  • +
  • <a href="#path_filestat_set_times.flags" name="path_filestat_set_times.flags"></a> flags: lookupflags
    Flags determining the method of how the path is resolved.

    +
  • +
  • <a href="#path_filestat_set_times.path" name="path_filestat_set_times.path"></a> path: string
    The path of the file or directory to operate on.

    +
  • +
  • <a href="#path_filestat_set_times.atim" name="path_filestat_set_times.atim"></a> atim: timestamp
    The desired values of the data access timestamp.

    +
  • +
  • <a href="#path_filestat_set_times.mtim" name="path_filestat_set_times.mtim"></a> mtim: timestamp
    The desired values of the data modification timestamp.

    +
  • +
  • <a href="#path_filestat_set_times.fst_flags" name="path_filestat_set_times.fst_flags"></a> fst_flags: fstflags
    A bitmask indicating which timestamps to adjust.

    +
  • +
+
Results
+
    +
  • <a href="#path_filestat_set_times.error" name="path_filestat_set_times.error"></a> error: errno
  • +
+
+ +

Create a hard link.
Note: This is similar to linkat in POSIX.

+
Params
+
    +
  • <a href="#path_link.old_fd" name="path_link.old_fd"></a> old_fd: fd

    +
  • +
  • <a href="#path_link.old_flags" name="path_link.old_flags"></a> old_flags: lookupflags
    Flags determining the method of how the path is resolved.

    +
  • +
  • <a href="#path_link.old_path" name="path_link.old_path"></a> old_path: string
    The source path from which to link.

    +
  • +
  • <a href="#path_link.new_fd" name="path_link.new_fd"></a> new_fd: fd
    The working directory at which the resolution of the new path starts.

    +
  • +
  • <a href="#path_link.new_path" name="path_link.new_path"></a> new_path: string
    The destination path at which to create the hard link.

    +
  • +
+
Results
+
    +
  • <a href="#path_link.error" name="path_link.error"></a> error: errno
  • +
+
+

<a href="#path_open" name="path_open"></a> path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)

+

Open a file or directory.
The returned file descriptor is not guaranteed to be the lowest-numbered
file descriptor not currently open; it is randomized to prevent
applications from depending on making assumptions about indexes, since this
is error-prone in multi-threaded contexts. The returned file descriptor is
guaranteed to be less than 2**31.
Note: This is similar to openat in POSIX.

+
Params
+
    +
  • <a href="#path_open.fd" name="path_open.fd"></a> fd: fd

    +
  • +
  • <a href="#path_open.dirflags" name="path_open.dirflags"></a> dirflags: lookupflags
    Flags determining the method of how the path is resolved.

    +
  • +
  • <a href="#path_open.path" name="path_open.path"></a> path: string
    The relative path of the file or directory to open, relative to the
    path_open::fd directory.

    +
  • +
  • <a href="#path_open.oflags" name="path_open.oflags"></a> oflags: oflags
    The method by which to open the file.

    +
  • +
  • <a href="#path_open.fs_rights_base" name="path_open.fs_rights_base"></a> fs_rights_base: rights
    The initial rights of the newly created file descriptor. The
    implementation is allowed to return a file descriptor with fewer rights
    than specified, if and only if those rights do not apply to the type of
    file being opened.
    The base rights are rights that will apply to operations using the file
    descriptor itself, while the inheriting rights are rights that apply to
    file descriptors derived from it.

    +
  • +
  • <a href="#path_open.fs_rights_inherting" name="path_open.fs_rights_inherting"></a> fs_rights_inherting: rights

    +
  • +
  • <a href="#path_open.fdflags" name="path_open.fdflags"></a> fdflags: fdflags

    +
  • +
+
Results
+
    +
  • <a href="#path_open.error" name="path_open.error"></a> error: errno

    +
  • +
  • <a href="#path_open.opened_fd" name="path_open.opened_fd"></a> opened_fd: fd
    The file descriptor of the file that has been opened.

    +
  • +
+
+ +

Read the contents of a symbolic link.
Note: This is similar to readlinkat in POSIX.

+
Params
+
    +
  • <a href="#path_readlink.fd" name="path_readlink.fd"></a> fd: fd

    +
  • +
  • <a href="#path_readlink.path" name="path_readlink.path"></a> path: string
    The path of the symbolic link from which to read.

    +
  • +
  • <a href="#path_readlink.buf" name="path_readlink.buf"></a> buf: Pointer<u8>
    The buffer to which to write the contents of the symbolic link.

    +
  • +
  • <a href="#path_readlink.buf_len" name="path_readlink.buf_len"></a> buf_len: size

    +
  • +
+
Results
+
    +
  • <a href="#path_readlink.error" name="path_readlink.error"></a> error: errno

    +
  • +
  • <a href="#path_readlink.bufused" name="path_readlink.bufused"></a> bufused: size
    The number of bytes placed in the buffer.

    +
  • +
+
+

<a href="#path_remove_directory" name="path_remove_directory"></a> path_remove_directory(fd: fd, path: string) -> errno

+

Remove a directory.
Return errno::notempty if the directory is not empty.
Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

+
Params
+
    +
  • <a href="#path_remove_directory.fd" name="path_remove_directory.fd"></a> fd: fd

    +
  • +
  • <a href="#path_remove_directory.path" name="path_remove_directory.path"></a> path: string
    The path to a directory to remove.

    +
  • +
+
Results
+
    +
  • <a href="#path_remove_directory.error" name="path_remove_directory.error"></a> error: errno
  • +
+
+

<a href="#path_rename" name="path_rename"></a> path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno

+

Rename a file or directory.
Note: This is similar to renameat in POSIX.

+
Params
+
    +
  • <a href="#path_rename.fd" name="path_rename.fd"></a> fd: fd

    +
  • +
  • <a href="#path_rename.old_path" name="path_rename.old_path"></a> old_path: string
    The source path of the file or directory to rename.

    +
  • +
  • <a href="#path_rename.new_fd" name="path_rename.new_fd"></a> new_fd: fd
    The working directory at which the resolution of the new path starts.

    +
  • +
  • <a href="#path_rename.new_path" name="path_rename.new_path"></a> new_path: string
    The destination path to which to rename the file or directory.

    +
  • +
+
Results
+
    +
  • <a href="#path_rename.error" name="path_rename.error"></a> error: errno
  • +
+
+ +

Create a symbolic link.
Note: This is similar to symlinkat in POSIX.

+
Params
+
    +
  • <a href="#path_symlink.old_path" name="path_symlink.old_path"></a> old_path: string
    The contents of the symbolic link.

    +
  • +
  • <a href="#path_symlink.fd" name="path_symlink.fd"></a> fd: fd

    +
  • +
  • <a href="#path_symlink.new_path" name="path_symlink.new_path"></a> new_path: string
    The destination path at which to create the symbolic link.

    +
  • +
+
Results
+
    +
  • <a href="#path_symlink.error" name="path_symlink.error"></a> error: errno
  • +
+
+ +

Unlink a file.
Return errno::isdir if the path refers to a directory.
Note: This is similar to unlinkat(fd, path, 0) in POSIX.

+
Params
+
    +
  • <a href="#path_unlink_file.fd" name="path_unlink_file.fd"></a> fd: fd

    +
  • +
  • <a href="#path_unlink_file.path" name="path_unlink_file.path"></a> path: string
    The path to a file to unlink.

    +
  • +
+
Results
+
    +
  • <a href="#path_unlink_file.error" name="path_unlink_file.error"></a> error: errno
  • +
+
+

<a href="#poll_oneoff" name="poll_oneoff"></a> poll_oneoff(in: ConstPointer<subscription>, out: Pointer<event>, nsubscriptions: size) -> (errno, size)

+

Concurrently poll for the occurrence of a set of events.

+
Params
+
    +
  • <a href="#poll_oneoff.in" name="poll_oneoff.in"></a> in: ConstPointer<subscription>
    The events to which to subscribe.

    +
  • +
  • <a href="#poll_oneoff.out" name="poll_oneoff.out"></a> out: Pointer<event>
    The events that have occurred.

    +
  • +
  • <a href="#poll_oneoff.nsubscriptions" name="poll_oneoff.nsubscriptions"></a> nsubscriptions: size
    Both the number of subscriptions and events.

    +
  • +
+
Results
+
    +
  • <a href="#poll_oneoff.error" name="poll_oneoff.error"></a> error: errno

    +
  • +
  • <a href="#poll_oneoff.nevents" name="poll_oneoff.nevents"></a> nevents: size
    The number of events stored.

    +
  • +
+
+

<a href="#proc_exit" name="proc_exit"></a> proc_exit(rval: exitcode)

+

Terminate the process normally. An exit code of 0 indicates successful
termination of the program. The meanings of other values is dependent on
the environment.

+
Params
+
    +
  • <a href="#proc_exit.rval" name="proc_exit.rval"></a> rval: exitcode
    The exit code returned by the process.
  • +
+
Results
+
+

<a href="#proc_raise" name="proc_raise"></a> proc_raise(sig: signal) -> errno

+

Send a signal to the process of the calling thread.
Note: This is similar to raise in POSIX.

+
Params
+
    +
  • <a href="#proc_raise.sig" name="proc_raise.sig"></a> sig: signal
    The signal condition to trigger.
  • +
+
Results
+
    +
  • <a href="#proc_raise.error" name="proc_raise.error"></a> error: errno
  • +
+
+

<a href="#sched_yield" name="sched_yield"></a> sched_yield() -> errno

+

Temporarily yield execution of the calling thread.
Note: This is similar to sched_yield in POSIX.

+
Params
+
Results
+
    +
  • <a href="#sched_yield.error" name="sched_yield.error"></a> error: errno
  • +
+
+

<a href="#random_get" name="random_get"></a> random_get(buf: Pointer<u8>, buf_len: size) -> errno

+

Write high-quality random data into a buffer.
This function blocks when the implementation is unable to immediately
provide sufficient high-quality random data.
This function may execute slowly, so when large mounts of random data are
required, it's advisable to use this function to seed a pseudo-random
number generator, rather than to provide the random data directly.

+
Params
+
    +
  • <a href="#random_get.buf" name="random_get.buf"></a> buf: Pointer<u8>
    The buffer to fill with random data.

    +
  • +
  • <a href="#random_get.buf_len" name="random_get.buf_len"></a> buf_len: size

    +
  • +
+
Results
+
    +
  • <a href="#random_get.error" name="random_get.error"></a> error: errno
  • +
+
+

<a href="#sock_recv" name="sock_recv"></a> sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)

+

Receive a message from a socket.
Note: This is similar to recv in POSIX, though it also supports reading
the data into multiple buffers in the manner of readv.

+
Params
+
    +
  • <a href="#sock_recv.fd" name="sock_recv.fd"></a> fd: fd

    +
  • +
  • <a href="#sock_recv.ri_data" name="sock_recv.ri_data"></a> ri_data: iovec_array
    List of scatter/gather vectors to which to store data.

    +
  • +
  • <a href="#sock_recv.ri_flags" name="sock_recv.ri_flags"></a> ri_flags: riflags
    Message flags.

    +
  • +
+
Results
+
    +
  • <a href="#sock_recv.error" name="sock_recv.error"></a> error: errno

    +
  • +
  • <a href="#sock_recv.ro_datalen" name="sock_recv.ro_datalen"></a> ro_datalen: size
    Number of bytes stored in ri_data.

    +
  • +
  • <a href="#sock_recv.ro_flags" name="sock_recv.ro_flags"></a> ro_flags: roflags
    Message flags.

    +
  • +
+
+

<a href="#sock_send" name="sock_send"></a> sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)

+

Send a message on a socket.
Note: This is similar to send in POSIX, though it also supports writing
the data from multiple buffers in the manner of writev.

+
Params
+
    +
  • <a href="#sock_send.fd" name="sock_send.fd"></a> fd: fd

    +
  • +
  • <a href="#sock_send.si_data" name="sock_send.si_data"></a> si_data: ciovec_array
    List of scatter/gather vectors to which to retrieve data

    +
  • +
  • <a href="#sock_send.si_flags" name="sock_send.si_flags"></a> si_flags: siflags
    Message flags.

    +
  • +
+
Results
+
    +
  • <a href="#sock_send.error" name="sock_send.error"></a> error: errno

    +
  • +
  • <a href="#sock_send.so_datalen" name="sock_send.so_datalen"></a> so_datalen: size
    Number of bytes transmitted.

    +
  • +
+
+

<a href="#sock_shutdown" name="sock_shutdown"></a> sock_shutdown(fd: fd, how: sdflags) -> errno

+

Shut down socket send and receive channels.
Note: This is similar to shutdown in POSIX.

+
Params
+
    +
  • <a href="#sock_shutdown.fd" name="sock_shutdown.fd"></a> fd: fd

    +
  • +
  • <a href="#sock_shutdown.how" name="sock_shutdown.how"></a> how: sdflags
    Which channels on the socket to shut down.

    +
  • +
+
Results
+
    +
  • <a href="#sock_shutdown.error" name="sock_shutdown.error"></a> error: errno
  • +
diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index e2da39278..a50afa96a 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -1,15 +1,31 @@ # Types ## `size`: `u32` +Size: 4 + +Alignment: 4 + ## `filesize`: `u64` Non-negative file size or length of a region within a file. +Size: 8 + +Alignment: 8 + ## `timestamp`: `u64` Timestamp in nanoseconds. +Size: 8 + +Alignment: 8 + ## `clockid`: Enum(`u32`) Identifiers for clocks. +Size: 4 + +Alignment: 4 + ### Variants - `realtime` The clock measuring real time. Time value zero corresponds with @@ -33,6 +49,10 @@ Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided merely for alignment with POSIX. +Size: 2 + +Alignment: 2 + ### Variants - `success` No error occurred. System call completed successfully. @@ -268,6 +288,10 @@ Extension: Capabilities insufficient. ## `rights`: Flags(`u64`) File descriptor rights, determining which actions may be performed. +Size: 8 + +Alignment: 8 + ### Flags - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). @@ -371,37 +395,73 @@ The right to invoke [`sock_shutdown`](#sock_shutdown). ## `fd` A file descriptor handle. +Size: 4 + +Alignment: 4 + ### Supertypes ## `iovec`: Struct A region of memory for scatter/gather reads. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `Pointer` The address of the buffer to be filled. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be filled. +Offset: 4 + ## `ciovec`: Struct A region of memory for scatter/gather writes. +Size: 8 + +Alignment: 4 + ### Struct members - `buf`: `ConstPointer` The address of the buffer to be written. +Offset: 0 + - `buf_len`: [`size`](#size) The length of the buffer to be written. +Offset: 4 + ## `iovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `ciovec_array`: `Array` +Size: 8 + +Alignment: 4 + ## `filedelta`: `s64` Relative offset within a file. +Size: 8 + +Alignment: 8 + ## `whence`: Enum(`u8`) The position relative to which to set the offset of the file descriptor. +Size: 1 + +Alignment: 1 + ### Variants - `set` Seek relative to start-of-file. @@ -417,15 +477,31 @@ A reference to the offset of a directory entry. The value 0 signifies the start of the directory. +Size: 8 + +Alignment: 8 + ## `dirnamlen`: `u32` The type for the $d_namlen field of $dirent. +Size: 4 + +Alignment: 4 + ## `inode`: `u64` File serial number that is unique within its file system. +Size: 8 + +Alignment: 8 + ## `filetype`: Enum(`u8`) The type of a file descriptor or file. +Size: 1 + +Alignment: 1 + ### Variants - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -454,22 +530,38 @@ The file refers to a symbolic link inode. ## `dirent`: Struct A directory entry. +Size: 24 + +Alignment: 8 + ### Struct members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. +Offset: 0 + - `d_ino`: [`inode`](#inode) The serial number of the file referred to by this directory entry. +Offset: 8 + - `d_namlen`: [`dirnamlen`](#dirnamlen) The length of the name of the directory entry. +Offset: 16 + - `d_type`: [`filetype`](#filetype) The type of the file referred to by this directory entry. +Offset: 20 + ## `advice`: Enum(`u8`) File or memory access pattern advisory information. +Size: 1 + +Alignment: 1 + ### Variants - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -492,6 +584,10 @@ The application expects to access the specified data once and then not reuse it ## `fdflags`: Flags(`u16`) File descriptor flags. +Size: 2 + +Alignment: 2 + ### Flags - `append` Append mode: Data written to the file is always appended to the file's end. @@ -513,27 +609,47 @@ may also synchronously update the file's metadata. ## `fdstat`: Struct File descriptor attributes. +Size: 24 + +Alignment: 8 + ### Struct members - `fs_filetype`: [`filetype`](#filetype) File type. +Offset: 0 + - `fs_flags`: [`fdflags`](#fdflags) File descriptor flags. +Offset: 2 + - `fs_rights_base`: [`rights`](#rights) Rights that apply to this file descriptor. +Offset: 8 + - `fs_rights_inheriting`: [`rights`](#rights) Maximum set of rights that may be installed on new file descriptors that are created through this file descriptor, e.g., through [`path_open`](#path_open). +Offset: 16 + ## `device`: `u64` Identifier for a device containing a file system. Can be used in combination with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. +Size: 8 + +Alignment: 8 + ## `fstflags`: Flags(`u16`) Which file time attributes to adjust. +Size: 2 + +Alignment: 2 + ### Flags - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -550,6 +666,10 @@ Adjust the last data modification timestamp to the time of clock [`clockid::real ## `lookupflags`: Flags(`u32`) Flags determining the method of how paths are resolved. +Size: 4 + +Alignment: 4 + ### Flags - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. @@ -557,6 +677,10 @@ As long as the resolved path corresponds to a symbolic link, it is expanded. ## `oflags`: Flags(`u16`) Open flags used by [`path_open`](#path_open). +Size: 2 + +Alignment: 2 + ### Flags - `creat` Create file if it does not exist. @@ -573,41 +697,73 @@ Truncate file to size 0. ## `linkcount`: `u64` Number of hard links to an inode. +Size: 8 + +Alignment: 8 + ## `filestat`: Struct File attributes. +Size: 64 + +Alignment: 8 + ### Struct members - `dev`: [`device`](#device) Device ID of device containing the file. +Offset: 0 + - `ino`: [`inode`](#inode) File serial number. +Offset: 8 + - `filetype`: [`filetype`](#filetype) File type. +Offset: 16 + - `nlink`: [`linkcount`](#linkcount) Number of hard links to the file. +Offset: 24 + - `size`: [`filesize`](#filesize) For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. +Offset: 32 + - `atim`: [`timestamp`](#timestamp) Last data access timestamp. +Offset: 40 + - `mtim`: [`timestamp`](#timestamp) Last data modification timestamp. +Offset: 48 + - `ctim`: [`timestamp`](#timestamp) Last file status change timestamp. +Offset: 56 + ## `userdata`: `u64` User-provided value that may be attached to objects that is retained when extracted from the implementation. +Size: 8 + +Alignment: 8 + ## `eventtype`: Enum(`u8`) Type of a subscription to an event or its occurrence. +Size: 1 + +Alignment: 1 + ### Variants - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has @@ -625,6 +781,10 @@ available for writing. This event always triggers for regular files. The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 2 + +Alignment: 2 + ### Flags - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -633,34 +793,58 @@ The peer of this socket has closed or disconnected. The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 16 + +Alignment: 8 + ### Struct members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. +Offset: 0 + - `flags`: [`eventrwflags`](#eventrwflags) The state of the file descriptor. +Offset: 8 + ## `event`: Struct An event that occurred. +Size: 32 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). +Offset: 0 + - `error`: [`errno`](#errno) If non-zero, an error that occurred while processing the subscription request. +Offset: 8 + - `type`: [`eventtype`](#eventtype) The type of event that occured +Offset: 10 + - `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. +Offset: 16 + ## `subclockflags`: Flags(`u16`) Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). +Size: 2 + +Alignment: 2 + ### Flags - `subscription_clock_abstime` If set, treat the timestamp provided in @@ -672,31 +856,59 @@ current time value of clock [`subscription_clock::id`](#subscription_clock.id). ## `subscription_clock`: Struct The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). +Size: 32 + +Alignment: 8 + ### Struct members - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. +Offset: 0 + - `timeout`: [`timestamp`](#timestamp) The absolute or relative timestamp. +Offset: 8 + - `precision`: [`timestamp`](#timestamp) The amount of time that the implementation may wait additionally to coalesce with other events. +Offset: 16 + - `flags`: [`subclockflags`](#subclockflags) Flags specifying whether the timeout is absolute or relative +Offset: 24 + ## `subscription_fd_readwrite`: Struct The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). +Size: 4 + +Alignment: 4 + ### Struct members - `file_descriptor`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. +Offset: 0 + ## `subscription_u`: Union The contents of a [`subscription`](#subscription). +Size: 40 + +Alignment: 8 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 8 +- contents_size: 32 +- contents_align: 8 ### Union variants - `clock`: [`subscription_clock`](#subscription_clock) @@ -707,20 +919,36 @@ The contents of a [`subscription`](#subscription). ## `subscription`: Struct Subscription to an event. +Size: 48 + +Alignment: 8 + ### Struct members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). +Offset: 0 + - `u`: [`subscription_u`](#subscription_u) The type of the event to which to subscribe, and its contents +Offset: 8 + ## `exitcode`: `u32` Exit code generated by a process when exiting. +Size: 4 + +Alignment: 4 + ## `signal`: Enum(`u8`) Signal condition. +Size: 1 + +Alignment: 1 + ### Variants - `none` No signal. Note that POSIX has special semantics for `kill(pid, 0)`, @@ -849,6 +1077,10 @@ Action: Terminates the process. ## `riflags`: Flags(`u16`) Flags provided to [`sock_recv`](#sock_recv). +Size: 2 + +Alignment: 2 + ### Flags - `recv_peek` Returns the message without removing it from the socket's receive queue. @@ -859,6 +1091,10 @@ On byte-stream sockets, block until the full amount of data can be returned. ## `roflags`: Flags(`u16`) Flags returned by [`sock_recv`](#sock_recv). +Size: 2 + +Alignment: 2 + ### Flags - `recv_data_truncated` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. @@ -867,9 +1103,17 @@ Returned by [`sock_recv`](#sock_recv): Message data has been truncated. Flags provided to [`sock_send`](#sock_send). As there are currently no flags defined, it must be set to zero. +Size: 2 + +Alignment: 2 + ## `sdflags`: Flags(`u8`) Which channels on a socket to shut down. +Size: 1 + +Alignment: 1 + ### Flags - `rd` Disables further receive operations. @@ -880,6 +1124,10 @@ Disables further send operations. ## `preopentype`: Enum(`u8`) Identifiers for preopened capabilities. +Size: 1 + +Alignment: 1 + ### Variants - `dir` A pre-opened directory. @@ -887,13 +1135,29 @@ A pre-opened directory. ## `prestat_dir`: Struct The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). +Size: 4 + +Alignment: 4 + ### Struct members - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). +Offset: 0 + ## `prestat`: Union Information about a pre-opened capability. +Size: 8 + +Alignment: 4 + +### Union Layout +- tag_size: 1 +- tag_align: 1 +- contents_offset: 4 +- contents_size: 4 +- contents_align: 4 ### Union variants - `dir`: [`prestat_dir`](#prestat_dir) diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index 10dc9f7c2..02ef9ec22 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -8,6 +8,7 @@ use crate::{ InterfaceFunc, InterfaceFuncParam, Module, ModuleImport, ModuleImportVariant, NamedType, StructDatatype, Type, TypeRef, UnionDatatype, }, + layout::Layout, polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, RepEquality, }; @@ -26,7 +27,13 @@ impl ToMarkdown for Document { heading.new_level_down(), name, name, - &d.docs, + format!( + "{}\nSize: {}\n\nAlignment: {}\n", + &d.docs, + &d.mem_size(), + &d.mem_align() + ) + .as_str(), )); d.generate(child.clone()); } @@ -173,7 +180,9 @@ impl ToMarkdown for StructDatatype { let heading = heading_from_node(&node, 1); node.new_child(MdSection::new(heading, "Struct members")); - for member in &self.members { + for member_layout in &self.member_layout() { + let member = member_layout.member; + let offset = member_layout.offset; let name = member.name.as_str(); let id = if let Some(id) = node.any_ref().id() { format!("{}.{}", id, name) @@ -184,7 +193,7 @@ impl ToMarkdown for StructDatatype { MdHeading::new_bullet(), id.as_str(), name, - &member.docs, + format!("{}\nOffset: {}\n", &member.docs, &offset).as_str(), )); member.tref.generate(n.clone()); } @@ -195,8 +204,34 @@ impl ToMarkdown for StructDatatype { impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Union variants")); + // Sizes & Alignments + let sizes_heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(sizes_heading, "Union Layout")); + let union_layout = &self.union_layout(); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("tag_size: {}", union_layout.tag_size).as_str(), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("tag_align: {}", union_layout.tag_align).as_str(), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("contents_offset: {}", union_layout.contents_offset).as_str(), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("contents_size: {}", union_layout.contents_size).as_str(), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("contents_align: {}", union_layout.contents_align).as_str(), + )); + + // Variants + let variants_heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(variants_heading, "Union variants")); for variant in &self.variants { let name = variant.name.as_str(); From 16cb7f8e4701977ce15a3c669d5086b73bc8b790 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 May 2020 17:25:03 -0700 Subject: [PATCH 0640/1772] Add a meeting page for the 05-07 meeting. (#270) --- proposals/clocks/meetings/2020/WASI-05-07.md | 30 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 31 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-05-07.md diff --git a/proposals/clocks/meetings/2020/WASI-05-07.md b/proposals/clocks/meetings/2020/WASI-05-07.md new file mode 100644 index 000000000..6945a05de --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-05-07.md @@ -0,0 +1,30 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 7 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 07, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 380496f38..fcdd2e258 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -31,3 +31,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI March 12th video call](2020/WASI-03-12.md) * [WASI March 26th video call](2020/WASI-03-26.md) * [WASI April 9th video call](2020/WASI-04-09.md) + * [WASI May 7th video call](2020/WASI-05-07.md) From 18c15c014b197dd795fdac06c49d62369bfcbe27 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 May 2020 17:25:03 -0700 Subject: [PATCH 0641/1772] Add a meeting page for the 05-07 meeting. (#270) --- proposals/random/meetings/2020/WASI-05-07.md | 30 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 31 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-05-07.md diff --git a/proposals/random/meetings/2020/WASI-05-07.md b/proposals/random/meetings/2020/WASI-05-07.md new file mode 100644 index 000000000..6945a05de --- /dev/null +++ b/proposals/random/meetings/2020/WASI-05-07.md @@ -0,0 +1,30 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 7 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 07, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 380496f38..fcdd2e258 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -31,3 +31,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI March 12th video call](2020/WASI-03-12.md) * [WASI March 26th video call](2020/WASI-03-26.md) * [WASI April 9th video call](2020/WASI-04-09.md) + * [WASI May 7th video call](2020/WASI-05-07.md) From 4ccb24316b42cd4ee9c72318b42da295c6717926 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 4 May 2020 17:25:03 -0700 Subject: [PATCH 0642/1772] Add a meeting page for the 05-07 meeting. (#270) --- .../filesystem/meetings/2020/WASI-05-07.md | 30 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 31 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-05-07.md diff --git a/proposals/filesystem/meetings/2020/WASI-05-07.md b/proposals/filesystem/meetings/2020/WASI-05-07.md new file mode 100644 index 000000000..6945a05de --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-05-07.md @@ -0,0 +1,30 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 7 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 07, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 380496f38..fcdd2e258 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -31,3 +31,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI March 12th video call](2020/WASI-03-12.md) * [WASI March 26th video call](2020/WASI-03-26.md) * [WASI April 9th video call](2020/WASI-04-09.md) + * [WASI May 7th video call](2020/WASI-05-07.md) From 49fed235f63ceb4d927751a65716810bb7e50f6f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 6 May 2020 21:13:05 -0700 Subject: [PATCH 0643/1772] Add some agenda topics. (#271) - New proposal process updates. - witx planning - Update on the module-types linking proposal. --- proposals/clocks/meetings/2020/WASI-05-07.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/proposals/clocks/meetings/2020/WASI-05-07.md b/proposals/clocks/meetings/2020/WASI-05-07.md index 6945a05de..abd24a361 100644 --- a/proposals/clocks/meetings/2020/WASI-05-07.md +++ b/proposals/clocks/meetings/2020/WASI-05-07.md @@ -26,5 +26,21 @@ Installation is required, see the calendar invite. 1. Please help take notes. 1. Thanks! 1. Proposals and discussions + 1. Heads up: Meetings agendas and notes will be moving: + 1. https://github.com/WebAssembly/meetings/issues/549 + 1. Proposal organization + 1. New proposal repositories prototypes: + 1. https://github.com/WebAssembly/WASI-http-proxy/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-classic-command/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-poll/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-handle-index/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-clocks/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-random/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-filesystem/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-streams/tree/master/phases/ephemeral/witx + 1. Goal is to have them be forks of the WASI repo. + 1. How should the witx tooling work? + 1. Update on the module-types linking proposal: + 1. https://github.com/WebAssembly/module-types/pull/3 ## Meeting Notes From 0d8aeff54a9d24f67f27b04c6f63d9029603f3ac Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 6 May 2020 21:13:05 -0700 Subject: [PATCH 0644/1772] Add some agenda topics. (#271) - New proposal process updates. - witx planning - Update on the module-types linking proposal. --- proposals/random/meetings/2020/WASI-05-07.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/proposals/random/meetings/2020/WASI-05-07.md b/proposals/random/meetings/2020/WASI-05-07.md index 6945a05de..abd24a361 100644 --- a/proposals/random/meetings/2020/WASI-05-07.md +++ b/proposals/random/meetings/2020/WASI-05-07.md @@ -26,5 +26,21 @@ Installation is required, see the calendar invite. 1. Please help take notes. 1. Thanks! 1. Proposals and discussions + 1. Heads up: Meetings agendas and notes will be moving: + 1. https://github.com/WebAssembly/meetings/issues/549 + 1. Proposal organization + 1. New proposal repositories prototypes: + 1. https://github.com/WebAssembly/WASI-http-proxy/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-classic-command/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-poll/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-handle-index/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-clocks/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-random/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-filesystem/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-streams/tree/master/phases/ephemeral/witx + 1. Goal is to have them be forks of the WASI repo. + 1. How should the witx tooling work? + 1. Update on the module-types linking proposal: + 1. https://github.com/WebAssembly/module-types/pull/3 ## Meeting Notes From e267c241a0f61ae0250b28b1777fef34fbdc06fb Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 6 May 2020 21:13:05 -0700 Subject: [PATCH 0645/1772] Add some agenda topics. (#271) - New proposal process updates. - witx planning - Update on the module-types linking proposal. --- proposals/filesystem/meetings/2020/WASI-05-07.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/proposals/filesystem/meetings/2020/WASI-05-07.md b/proposals/filesystem/meetings/2020/WASI-05-07.md index 6945a05de..abd24a361 100644 --- a/proposals/filesystem/meetings/2020/WASI-05-07.md +++ b/proposals/filesystem/meetings/2020/WASI-05-07.md @@ -26,5 +26,21 @@ Installation is required, see the calendar invite. 1. Please help take notes. 1. Thanks! 1. Proposals and discussions + 1. Heads up: Meetings agendas and notes will be moving: + 1. https://github.com/WebAssembly/meetings/issues/549 + 1. Proposal organization + 1. New proposal repositories prototypes: + 1. https://github.com/WebAssembly/WASI-http-proxy/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-classic-command/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-poll/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-handle-index/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-clocks/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-random/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-filesystem/tree/master/phases/ephemeral/witx + 1. https://github.com/WebAssembly/WASI-streams/tree/master/phases/ephemeral/witx + 1. Goal is to have them be forks of the WASI repo. + 1. How should the witx tooling work? + 1. Update on the module-types linking proposal: + 1. https://github.com/WebAssembly/module-types/pull/3 ## Meeting Notes From 68bf558c300c5d53925352be18d2328366752e5f Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 11 May 2020 03:08:25 +0200 Subject: [PATCH 0646/1772] Fix links to dirent struct in fd_readdir description (#274) This commit fixes links in `fd_readdir` description/docs which were using an outdated (now invalid) ref syntax when referencing `dirent` struct. The changes apply to docs only and only to `wasi_unstable` and `wasi_snapshot_preview1` snapshots. The `wasi_ephemeral` has properly referenced links. --- proposals/clocks/phases/old/snapshot_0/docs.md | 6 +++--- proposals/clocks/phases/old/snapshot_0/witx/typenames.witx | 2 +- .../clocks/phases/old/snapshot_0/witx/wasi_unstable.witx | 4 ++-- proposals/clocks/phases/snapshot/docs.md | 6 +++--- proposals/clocks/phases/snapshot/witx/typenames.witx | 2 +- .../clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index eda85fbc0..98cccf89a 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -480,7 +480,7 @@ Size: 8 Alignment: 8 ## `dirnamlen`: `u32` -The type for the $d_namlen field of $dirent. +The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent) struct. Size: 4 @@ -1541,8 +1541,8 @@ The number of bytes read. #### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a dirent_t object, -followed by dirent_t::d_namlen bytes holding the name of the directory +directory entries. Each directory entry consists of a [`dirent`](#dirent) object, +followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory entry. This function fills the output buffer as much as possible, potentially truncating the last directory entry. This allows the caller to grow its diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx index f59f9ea15..ea8dc2e5d 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx @@ -317,7 +317,7 @@ ;;; A reference to the offset of a directory entry. (typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent. +;;; The type for the `dirent::d_namlen` field of `dirent` struct. (typename $dirnamlen u32) ;;; File serial number that is unique within its file system. diff --git a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx index fb098d7b5..697e3ba88 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -222,8 +222,8 @@ ;;; Read directory entries from a directory. ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a dirent_t object, - ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; directory entries. Each directory entry consists of a `dirent` object, + ;;; followed by `dirent::d_namlen` bytes holding the name of the directory ;;; entry. ;; ;;; This function fills the output buffer as much as possible, potentially diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index a50afa96a..aec5e8faf 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -482,7 +482,7 @@ Size: 8 Alignment: 8 ## `dirnamlen`: `u32` -The type for the $d_namlen field of $dirent. +The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent) struct. Size: 4 @@ -1538,8 +1538,8 @@ The number of bytes read. #### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a dirent_t object, -followed by dirent_t::d_namlen bytes holding the name of the directory +directory entries. Each directory entry consists of a [`dirent`](#dirent) object, +followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory entry. This function fills the output buffer as much as possible, potentially truncating the last directory entry. This allows the caller to grow its diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx index 2bccd79a6..239978d61 100644 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -319,7 +319,7 @@ ;;; The value 0 signifies the start of the directory. (typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent. +;;; The type for the `dirent::d_namlen` field of `dirent` struct. (typename $dirnamlen u32) ;;; File serial number that is unique within its file system. diff --git a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx index 98cd94787..5604c3e68 100644 --- a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -219,8 +219,8 @@ ;;; Read directory entries from a directory. ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a dirent_t object, - ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; directory entries. Each directory entry consists of a `dirent` object, + ;;; followed by `dirent::d_namlen` bytes holding the name of the directory ;;; entry. ;; ;;; This function fills the output buffer as much as possible, potentially From d409f0a80e64fec35b4a0a322feaf54ff1f4c004 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 11 May 2020 03:08:25 +0200 Subject: [PATCH 0647/1772] Fix links to dirent struct in fd_readdir description (#274) This commit fixes links in `fd_readdir` description/docs which were using an outdated (now invalid) ref syntax when referencing `dirent` struct. The changes apply to docs only and only to `wasi_unstable` and `wasi_snapshot_preview1` snapshots. The `wasi_ephemeral` has properly referenced links. --- proposals/random/phases/old/snapshot_0/docs.md | 6 +++--- proposals/random/phases/old/snapshot_0/witx/typenames.witx | 2 +- .../random/phases/old/snapshot_0/witx/wasi_unstable.witx | 4 ++-- proposals/random/phases/snapshot/docs.md | 6 +++--- proposals/random/phases/snapshot/witx/typenames.witx | 2 +- .../random/phases/snapshot/witx/wasi_snapshot_preview1.witx | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index eda85fbc0..98cccf89a 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -480,7 +480,7 @@ Size: 8 Alignment: 8 ## `dirnamlen`: `u32` -The type for the $d_namlen field of $dirent. +The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent) struct. Size: 4 @@ -1541,8 +1541,8 @@ The number of bytes read. #### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a dirent_t object, -followed by dirent_t::d_namlen bytes holding the name of the directory +directory entries. Each directory entry consists of a [`dirent`](#dirent) object, +followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory entry. This function fills the output buffer as much as possible, potentially truncating the last directory entry. This allows the caller to grow its diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx index f59f9ea15..ea8dc2e5d 100644 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/random/phases/old/snapshot_0/witx/typenames.witx @@ -317,7 +317,7 @@ ;;; A reference to the offset of a directory entry. (typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent. +;;; The type for the `dirent::d_namlen` field of `dirent` struct. (typename $dirnamlen u32) ;;; File serial number that is unique within its file system. diff --git a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx index fb098d7b5..697e3ba88 100644 --- a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -222,8 +222,8 @@ ;;; Read directory entries from a directory. ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a dirent_t object, - ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; directory entries. Each directory entry consists of a `dirent` object, + ;;; followed by `dirent::d_namlen` bytes holding the name of the directory ;;; entry. ;; ;;; This function fills the output buffer as much as possible, potentially diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index a50afa96a..aec5e8faf 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -482,7 +482,7 @@ Size: 8 Alignment: 8 ## `dirnamlen`: `u32` -The type for the $d_namlen field of $dirent. +The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent) struct. Size: 4 @@ -1538,8 +1538,8 @@ The number of bytes read. #### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a dirent_t object, -followed by dirent_t::d_namlen bytes holding the name of the directory +directory entries. Each directory entry consists of a [`dirent`](#dirent) object, +followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory entry. This function fills the output buffer as much as possible, potentially truncating the last directory entry. This allows the caller to grow its diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx index 2bccd79a6..239978d61 100644 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -319,7 +319,7 @@ ;;; The value 0 signifies the start of the directory. (typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent. +;;; The type for the `dirent::d_namlen` field of `dirent` struct. (typename $dirnamlen u32) ;;; File serial number that is unique within its file system. diff --git a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx index 98cd94787..5604c3e68 100644 --- a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -219,8 +219,8 @@ ;;; Read directory entries from a directory. ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a dirent_t object, - ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; directory entries. Each directory entry consists of a `dirent` object, + ;;; followed by `dirent::d_namlen` bytes holding the name of the directory ;;; entry. ;; ;;; This function fills the output buffer as much as possible, potentially From a2f4f72d880a2c82ad466cbbcfe09034b62f47ce Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 11 May 2020 03:08:25 +0200 Subject: [PATCH 0648/1772] Fix links to dirent struct in fd_readdir description (#274) This commit fixes links in `fd_readdir` description/docs which were using an outdated (now invalid) ref syntax when referencing `dirent` struct. The changes apply to docs only and only to `wasi_unstable` and `wasi_snapshot_preview1` snapshots. The `wasi_ephemeral` has properly referenced links. --- proposals/filesystem/phases/old/snapshot_0/docs.md | 6 +++--- .../filesystem/phases/old/snapshot_0/witx/typenames.witx | 2 +- .../phases/old/snapshot_0/witx/wasi_unstable.witx | 4 ++-- proposals/filesystem/phases/snapshot/docs.md | 6 +++--- proposals/filesystem/phases/snapshot/witx/typenames.witx | 2 +- .../phases/snapshot/witx/wasi_snapshot_preview1.witx | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index eda85fbc0..98cccf89a 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -480,7 +480,7 @@ Size: 8 Alignment: 8 ## `dirnamlen`: `u32` -The type for the $d_namlen field of $dirent. +The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent) struct. Size: 4 @@ -1541,8 +1541,8 @@ The number of bytes read. #### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a dirent_t object, -followed by dirent_t::d_namlen bytes holding the name of the directory +directory entries. Each directory entry consists of a [`dirent`](#dirent) object, +followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory entry. This function fills the output buffer as much as possible, potentially truncating the last directory entry. This allows the caller to grow its diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx index f59f9ea15..ea8dc2e5d 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx @@ -317,7 +317,7 @@ ;;; A reference to the offset of a directory entry. (typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent. +;;; The type for the `dirent::d_namlen` field of `dirent` struct. (typename $dirnamlen u32) ;;; File serial number that is unique within its file system. diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx index fb098d7b5..697e3ba88 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -222,8 +222,8 @@ ;;; Read directory entries from a directory. ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a dirent_t object, - ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; directory entries. Each directory entry consists of a `dirent` object, + ;;; followed by `dirent::d_namlen` bytes holding the name of the directory ;;; entry. ;; ;;; This function fills the output buffer as much as possible, potentially diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index a50afa96a..aec5e8faf 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -482,7 +482,7 @@ Size: 8 Alignment: 8 ## `dirnamlen`: `u32` -The type for the $d_namlen field of $dirent. +The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent) struct. Size: 4 @@ -1538,8 +1538,8 @@ The number of bytes read. #### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a dirent_t object, -followed by dirent_t::d_namlen bytes holding the name of the directory +directory entries. Each directory entry consists of a [`dirent`](#dirent) object, +followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory entry. This function fills the output buffer as much as possible, potentially truncating the last directory entry. This allows the caller to grow its diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx index 2bccd79a6..239978d61 100644 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -319,7 +319,7 @@ ;;; The value 0 signifies the start of the directory. (typename $dircookie u64) -;;; The type for the $d_namlen field of $dirent. +;;; The type for the `dirent::d_namlen` field of `dirent` struct. (typename $dirnamlen u32) ;;; File serial number that is unique within its file system. diff --git a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx index 98cd94787..5604c3e68 100644 --- a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -219,8 +219,8 @@ ;;; Read directory entries from a directory. ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a dirent_t object, - ;;; followed by dirent_t::d_namlen bytes holding the name of the directory + ;;; directory entries. Each directory entry consists of a `dirent` object, + ;;; followed by `dirent::d_namlen` bytes holding the name of the directory ;;; entry. ;; ;;; This function fills the output buffer as much as possible, potentially From 5eaa4cb9df3e48526a287ccfe5a4b71646334b33 Mon Sep 17 00:00:00 2001 From: Marcin Mielniczuk Date: Thu, 14 May 2020 00:07:23 +0200 Subject: [PATCH 0649/1772] Document why there is no path_filestat_set_size (#180) * Document why there is no path_filestat_set_size * Address review feedback. * Rephrase the rationale --- proposals/clocks/phases/ephemeral/docs.md | 7 ++++++- proposals/clocks/phases/ephemeral/witx/typenames.witx | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 3ddc5ad79..484d64d98 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -358,8 +358,13 @@ The right to invoke `path_rename` with the file descriptor as the target directo The right to invoke `path_filestat_get`. - `path_filestat_set_size` -The right to change a file's size (there is no `path_filestat_set_size`). +The right to change a file's size. If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). +Note: there is no function named `path_filestat_set_size`. This follows POSIX design, +which only has `ftruncate` and does not provide `ftruncateat`. +While such function would be desirable from the API design perspective, there are virtually +no use cases for it since no code written for POSIX systems would use it. +Moreover, implementing it would require multiple syscalls, leading to inferior performance. - `path_filestat_set_times` The right to invoke `path_filestat_set_times`. diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 772b8be82..9efff7290 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -247,8 +247,13 @@ $path_rename_target ;;; The right to invoke `path_filestat_get`. $path_filestat_get - ;;; The right to change a file's size (there is no `path_filestat_set_size`). + ;;; The right to change a file's size. ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. + ;;; Note: there is no function named `path_filestat_set_size`. This follows POSIX design, + ;;; which only has `ftruncate` and does not provide `ftruncateat`. + ;;; While such function would be desirable from the API design perspective, there are virtually + ;;; no use cases for it since no code written for POSIX systems would use it. + ;;; Moreover, implementing it would require multiple syscalls, leading to inferior performance. $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. $path_filestat_set_times From 2cf97d4a6e91b0d02028f35c3eab76d940f511ac Mon Sep 17 00:00:00 2001 From: Marcin Mielniczuk Date: Thu, 14 May 2020 00:07:23 +0200 Subject: [PATCH 0650/1772] Document why there is no path_filestat_set_size (#180) * Document why there is no path_filestat_set_size * Address review feedback. * Rephrase the rationale --- proposals/random/phases/ephemeral/docs.md | 7 ++++++- proposals/random/phases/ephemeral/witx/typenames.witx | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 3ddc5ad79..484d64d98 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -358,8 +358,13 @@ The right to invoke `path_rename` with the file descriptor as the target directo The right to invoke `path_filestat_get`. - `path_filestat_set_size` -The right to change a file's size (there is no `path_filestat_set_size`). +The right to change a file's size. If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). +Note: there is no function named `path_filestat_set_size`. This follows POSIX design, +which only has `ftruncate` and does not provide `ftruncateat`. +While such function would be desirable from the API design perspective, there are virtually +no use cases for it since no code written for POSIX systems would use it. +Moreover, implementing it would require multiple syscalls, leading to inferior performance. - `path_filestat_set_times` The right to invoke `path_filestat_set_times`. diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 772b8be82..9efff7290 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -247,8 +247,13 @@ $path_rename_target ;;; The right to invoke `path_filestat_get`. $path_filestat_get - ;;; The right to change a file's size (there is no `path_filestat_set_size`). + ;;; The right to change a file's size. ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. + ;;; Note: there is no function named `path_filestat_set_size`. This follows POSIX design, + ;;; which only has `ftruncate` and does not provide `ftruncateat`. + ;;; While such function would be desirable from the API design perspective, there are virtually + ;;; no use cases for it since no code written for POSIX systems would use it. + ;;; Moreover, implementing it would require multiple syscalls, leading to inferior performance. $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. $path_filestat_set_times From ffb6783334751a63d4e3ad928ab4aacc85f57efe Mon Sep 17 00:00:00 2001 From: Marcin Mielniczuk Date: Thu, 14 May 2020 00:07:23 +0200 Subject: [PATCH 0651/1772] Document why there is no path_filestat_set_size (#180) * Document why there is no path_filestat_set_size * Address review feedback. * Rephrase the rationale --- proposals/filesystem/phases/ephemeral/docs.md | 7 ++++++- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 3ddc5ad79..484d64d98 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -358,8 +358,13 @@ The right to invoke `path_rename` with the file descriptor as the target directo The right to invoke `path_filestat_get`. - `path_filestat_set_size` -The right to change a file's size (there is no `path_filestat_set_size`). +The right to change a file's size. If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). +Note: there is no function named `path_filestat_set_size`. This follows POSIX design, +which only has `ftruncate` and does not provide `ftruncateat`. +While such function would be desirable from the API design perspective, there are virtually +no use cases for it since no code written for POSIX systems would use it. +Moreover, implementing it would require multiple syscalls, leading to inferior performance. - `path_filestat_set_times` The right to invoke `path_filestat_set_times`. diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 772b8be82..9efff7290 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -247,8 +247,13 @@ $path_rename_target ;;; The right to invoke `path_filestat_get`. $path_filestat_get - ;;; The right to change a file's size (there is no `path_filestat_set_size`). + ;;; The right to change a file's size. ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. + ;;; Note: there is no function named `path_filestat_set_size`. This follows POSIX design, + ;;; which only has `ftruncate` and does not provide `ftruncateat`. + ;;; While such function would be desirable from the API design perspective, there are virtually + ;;; no use cases for it since no code written for POSIX systems would use it. + ;;; Moreover, implementing it would require multiple syscalls, leading to inferior performance. $path_filestat_set_size ;;; The right to invoke `path_filestat_set_times`. $path_filestat_set_times From 59c1aa9a39cbb6a5a4101dc2450dd4c1f2bb8520 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 14 May 2020 00:28:35 +0200 Subject: [PATCH 0652/1772] Fix link to event struct (#275) This commit fixes an outdated ref syntax when referencing back to `event` struct. --- proposals/clocks/phases/old/snapshot_0/docs.md | 2 +- proposals/clocks/phases/old/snapshot_0/witx/typenames.witx | 2 +- proposals/clocks/phases/snapshot/docs.md | 2 +- proposals/clocks/phases/snapshot/witx/typenames.witx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index 98cccf89a..1b2100580 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -788,7 +788,7 @@ Alignment: 2 The peer of this socket has closed or disconnected. ## `event_fd_readwrite`: Struct -The contents of an $event for the [`eventtype::fd_read`](#eventtype.fd_read) and +The contents of an [`event`](#event) for the [`eventtype::fd_read`](#eventtype.fd_read) and [`eventtype::fd_write`](#eventtype.fd_write) variants Size: 16 diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx index ea8dc2e5d..1a795c13c 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx @@ -503,7 +503,7 @@ ) ) -;;; The contents of an $event for the `eventtype::fd_read` and +;;; The contents of an `event` for the `eventtype::fd_read` and ;;; `eventtype::fd_write` variants (typename $event_fd_readwrite (struct diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index aec5e8faf..640943f84 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -790,7 +790,7 @@ Alignment: 2 The peer of this socket has closed or disconnected. ## `event_fd_readwrite`: Struct -The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). Size: 16 diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx index 239978d61..b77372731 100644 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -505,7 +505,7 @@ ) ) -;;; The contents of an $event when type is `eventtype::fd_read` or +;;; The contents of an `event` when type is `eventtype::fd_read` or ;;; `eventtype::fd_write`. (typename $event_fd_readwrite (struct From a9583aa9c638b08791992bc8a698a5c8bf748b61 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 14 May 2020 00:28:35 +0200 Subject: [PATCH 0653/1772] Fix link to event struct (#275) This commit fixes an outdated ref syntax when referencing back to `event` struct. --- proposals/random/phases/old/snapshot_0/docs.md | 2 +- proposals/random/phases/old/snapshot_0/witx/typenames.witx | 2 +- proposals/random/phases/snapshot/docs.md | 2 +- proposals/random/phases/snapshot/witx/typenames.witx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index 98cccf89a..1b2100580 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -788,7 +788,7 @@ Alignment: 2 The peer of this socket has closed or disconnected. ## `event_fd_readwrite`: Struct -The contents of an $event for the [`eventtype::fd_read`](#eventtype.fd_read) and +The contents of an [`event`](#event) for the [`eventtype::fd_read`](#eventtype.fd_read) and [`eventtype::fd_write`](#eventtype.fd_write) variants Size: 16 diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx index ea8dc2e5d..1a795c13c 100644 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/random/phases/old/snapshot_0/witx/typenames.witx @@ -503,7 +503,7 @@ ) ) -;;; The contents of an $event for the `eventtype::fd_read` and +;;; The contents of an `event` for the `eventtype::fd_read` and ;;; `eventtype::fd_write` variants (typename $event_fd_readwrite (struct diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index aec5e8faf..640943f84 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -790,7 +790,7 @@ Alignment: 2 The peer of this socket has closed or disconnected. ## `event_fd_readwrite`: Struct -The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). Size: 16 diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx index 239978d61..b77372731 100644 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -505,7 +505,7 @@ ) ) -;;; The contents of an $event when type is `eventtype::fd_read` or +;;; The contents of an `event` when type is `eventtype::fd_read` or ;;; `eventtype::fd_write`. (typename $event_fd_readwrite (struct From 2aadaf68c422f584e728dfa140efa35b0429fff4 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 14 May 2020 00:28:35 +0200 Subject: [PATCH 0654/1772] Fix link to event struct (#275) This commit fixes an outdated ref syntax when referencing back to `event` struct. --- proposals/filesystem/phases/old/snapshot_0/docs.md | 2 +- proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx | 2 +- proposals/filesystem/phases/snapshot/docs.md | 2 +- proposals/filesystem/phases/snapshot/witx/typenames.witx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index 98cccf89a..1b2100580 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -788,7 +788,7 @@ Alignment: 2 The peer of this socket has closed or disconnected. ## `event_fd_readwrite`: Struct -The contents of an $event for the [`eventtype::fd_read`](#eventtype.fd_read) and +The contents of an [`event`](#event) for the [`eventtype::fd_read`](#eventtype.fd_read) and [`eventtype::fd_write`](#eventtype.fd_write) variants Size: 16 diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx index ea8dc2e5d..1a795c13c 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx @@ -503,7 +503,7 @@ ) ) -;;; The contents of an $event for the `eventtype::fd_read` and +;;; The contents of an `event` for the `eventtype::fd_read` and ;;; `eventtype::fd_write` variants (typename $event_fd_readwrite (struct diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index aec5e8faf..640943f84 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -790,7 +790,7 @@ Alignment: 2 The peer of this socket has closed or disconnected. ## `event_fd_readwrite`: Struct -The contents of an $event when type is [`eventtype::fd_read`](#eventtype.fd_read) or +The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). Size: 16 diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx index 239978d61..b77372731 100644 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -505,7 +505,7 @@ ) ) -;;; The contents of an $event when type is `eventtype::fd_read` or +;;; The contents of an `event` when type is `eventtype::fd_read` or ;;; `eventtype::fd_write`. (typename $event_fd_readwrite (struct From 901103066978c1c6727c96e427d84d3edc9f03e2 Mon Sep 17 00:00:00 2001 From: Casper Beyer Date: Tue, 19 May 2020 07:19:42 +0800 Subject: [PATCH 0655/1772] Move $d_namlen to the end of $dirent (#264) --- proposals/clocks/phases/ephemeral/docs.md | 8 ++++---- proposals/clocks/phases/ephemeral/witx/typenames.witx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 484d64d98..09c8dac51 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -558,13 +558,13 @@ The serial number of the file referred to by this directory entry. Offset: 8 -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. Offset: 16 -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. Offset: 20 diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 9efff7290..349952a15 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -367,10 +367,10 @@ (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. (field $d_ino $inode) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) ;;; The type of the file referred to by this directory entry. (field $d_type $filetype) + ;;; The length of the name of the directory entry. + (field $d_namlen $dirnamlen) ) ) From 5bc66425922b6d2a524e58afb0940afec7b6b7ec Mon Sep 17 00:00:00 2001 From: Casper Beyer Date: Tue, 19 May 2020 07:19:42 +0800 Subject: [PATCH 0656/1772] Move $d_namlen to the end of $dirent (#264) --- proposals/random/phases/ephemeral/docs.md | 8 ++++---- proposals/random/phases/ephemeral/witx/typenames.witx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 484d64d98..09c8dac51 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -558,13 +558,13 @@ The serial number of the file referred to by this directory entry. Offset: 8 -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. Offset: 16 -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. Offset: 20 diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 9efff7290..349952a15 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -367,10 +367,10 @@ (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. (field $d_ino $inode) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) ;;; The type of the file referred to by this directory entry. (field $d_type $filetype) + ;;; The length of the name of the directory entry. + (field $d_namlen $dirnamlen) ) ) From 61f241ed71f90c2069283fc62521236e5f59f411 Mon Sep 17 00:00:00 2001 From: Casper Beyer Date: Tue, 19 May 2020 07:19:42 +0800 Subject: [PATCH 0657/1772] Move $d_namlen to the end of $dirent (#264) --- proposals/filesystem/phases/ephemeral/docs.md | 8 ++++---- proposals/filesystem/phases/ephemeral/witx/typenames.witx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 484d64d98..09c8dac51 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -558,13 +558,13 @@ The serial number of the file referred to by this directory entry. Offset: 8 -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. Offset: 16 -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. Offset: 20 diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 9efff7290..349952a15 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -367,10 +367,10 @@ (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. (field $d_ino $inode) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) ;;; The type of the file referred to by this directory entry. (field $d_type $filetype) + ;;; The length of the name of the directory entry. + (field $d_namlen $dirnamlen) ) ) From 9271b14fc74e052d4cea5b8ae8d6341b7e7f553a Mon Sep 17 00:00:00 2001 From: YAMAMOTO Yuji Date: Tue, 19 May 2020 08:48:35 +0900 Subject: [PATCH 0658/1772] Document atomicity of `write` and `pwrite`, and technical fix about POSIX (#257) * Techinically speaking, preadv and pwritev are not in POSIX. Ref: https://pubs.opengroup.org/onlinepubs/9699919799/idx/ip.html * Document about atomicity of `write` and `pwrite` Related thread of ZULIP: https://bytecodealliance.zulipchat.com/#narrow/stream/219900-wasi/topic/Why.20is.20.60iovecs.60.20an.20array.20of.20strings.3F The thread refers atomicity of `read`, but I couldn't make a good expression for the atomicity of `read`. So I add document only in `write` and `pwrite`. * Limit the scope of atomicity The related POSIX document refers only to threads. https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_07 So the atomicity is limited in the process * Fix test * Fix after review https://github.com/WebAssembly/WASI/pull/257#issuecomment-617354670 The atomicity is guaranteed only for regular files or symbolic links (only symbolic links for a regular files, right?) Delete expressions indicating 'all or nothing' to reflect the actual behavior of POSIX's`write` etc. * Fix after review https://github.com/WebAssembly/WASI/pull/257#discussion_r421221765 Delete the sentences related to 'all data' completely Don't refer to symlink * Fix after review https://github.com/WebAssembly/WASI/pull/257#pullrequestreview-409467163 --- proposals/clocks/phases/ephemeral/docs.md | 12 ++++++++++-- .../phases/ephemeral/witx/wasi_ephemeral_fd.witx | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 09c8dac51..f17e9aa9f 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -1415,7 +1415,7 @@ The permissions associated with the file. #### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` Read from a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `preadv` in POSIX. +Note: This is similar to `preadv` in Linux (and other Unix-es). ##### Params - `fd`: [`fd`](#fd) @@ -1469,7 +1469,11 @@ A buffer into which to write the preopened directory name. #### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` Write to a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `pwritev` in POSIX. +Note: This is similar to `pwritev` in Linux (and other Unix-es). + +Like Linux (and other Unix-es), any calls of [`pwrite`](#pwrite) (and other +functions to read or write) for a regular file by other threads in the +WASI process should not be interleaved while [`pwrite`](#pwrite) is executed. ##### Params - `fd`: [`fd`](#fd) @@ -1616,6 +1620,10 @@ The current offset of the file descriptor, relative to the start of the file. Write to a file descriptor. Note: This is similar to `writev` in POSIX. +Like POSIX, any calls of [`write`](#write) (and other functions to read or write) +for a regular file by other threads in the WASI process should not be +interleaved while [`write`](#write) is executed. + ##### Params - `fd`: [`fd`](#fd) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx index 2f3c618ff..821d3e707 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -127,7 +127,7 @@ ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in POSIX. + ;;; Note: This is similar to `preadv` in Linux (and other Unix-es). (@interface func (export "pread") (param $fd $fd) ;;; List of scatter/gather vectors in which to store data. @@ -157,7 +157,11 @@ ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in POSIX. + ;;; Note: This is similar to `pwritev` in Linux (and other Unix-es). + ;;; + ;;; Like Linux (and other Unix-es), any calls of `pwrite` (and other + ;;; functions to read or write) for a regular file by other threads in the + ;;; WASI process should not be interleaved while `pwrite` is executed. (@interface func (export "pwrite") (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. @@ -250,6 +254,10 @@ ;;; Write to a file descriptor. ;;; Note: This is similar to `writev` in POSIX. + ;;; + ;;; Like POSIX, any calls of `write` (and other functions to read or write) + ;;; for a regular file by other threads in the WASI process should not be + ;;; interleaved while `write` is executed. (@interface func (export "write") (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. From 2a546326a69b75c83569cf08e20d000734969bf8 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Yuji Date: Tue, 19 May 2020 08:48:35 +0900 Subject: [PATCH 0659/1772] Document atomicity of `write` and `pwrite`, and technical fix about POSIX (#257) * Techinically speaking, preadv and pwritev are not in POSIX. Ref: https://pubs.opengroup.org/onlinepubs/9699919799/idx/ip.html * Document about atomicity of `write` and `pwrite` Related thread of ZULIP: https://bytecodealliance.zulipchat.com/#narrow/stream/219900-wasi/topic/Why.20is.20.60iovecs.60.20an.20array.20of.20strings.3F The thread refers atomicity of `read`, but I couldn't make a good expression for the atomicity of `read`. So I add document only in `write` and `pwrite`. * Limit the scope of atomicity The related POSIX document refers only to threads. https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_07 So the atomicity is limited in the process * Fix test * Fix after review https://github.com/WebAssembly/WASI/pull/257#issuecomment-617354670 The atomicity is guaranteed only for regular files or symbolic links (only symbolic links for a regular files, right?) Delete expressions indicating 'all or nothing' to reflect the actual behavior of POSIX's`write` etc. * Fix after review https://github.com/WebAssembly/WASI/pull/257#discussion_r421221765 Delete the sentences related to 'all data' completely Don't refer to symlink * Fix after review https://github.com/WebAssembly/WASI/pull/257#pullrequestreview-409467163 --- proposals/random/phases/ephemeral/docs.md | 12 ++++++++++-- .../phases/ephemeral/witx/wasi_ephemeral_fd.witx | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 09c8dac51..f17e9aa9f 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -1415,7 +1415,7 @@ The permissions associated with the file. #### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` Read from a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `preadv` in POSIX. +Note: This is similar to `preadv` in Linux (and other Unix-es). ##### Params - `fd`: [`fd`](#fd) @@ -1469,7 +1469,11 @@ A buffer into which to write the preopened directory name. #### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` Write to a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `pwritev` in POSIX. +Note: This is similar to `pwritev` in Linux (and other Unix-es). + +Like Linux (and other Unix-es), any calls of [`pwrite`](#pwrite) (and other +functions to read or write) for a regular file by other threads in the +WASI process should not be interleaved while [`pwrite`](#pwrite) is executed. ##### Params - `fd`: [`fd`](#fd) @@ -1616,6 +1620,10 @@ The current offset of the file descriptor, relative to the start of the file. Write to a file descriptor. Note: This is similar to `writev` in POSIX. +Like POSIX, any calls of [`write`](#write) (and other functions to read or write) +for a regular file by other threads in the WASI process should not be +interleaved while [`write`](#write) is executed. + ##### Params - `fd`: [`fd`](#fd) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx index 2f3c618ff..821d3e707 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -127,7 +127,7 @@ ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in POSIX. + ;;; Note: This is similar to `preadv` in Linux (and other Unix-es). (@interface func (export "pread") (param $fd $fd) ;;; List of scatter/gather vectors in which to store data. @@ -157,7 +157,11 @@ ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in POSIX. + ;;; Note: This is similar to `pwritev` in Linux (and other Unix-es). + ;;; + ;;; Like Linux (and other Unix-es), any calls of `pwrite` (and other + ;;; functions to read or write) for a regular file by other threads in the + ;;; WASI process should not be interleaved while `pwrite` is executed. (@interface func (export "pwrite") (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. @@ -250,6 +254,10 @@ ;;; Write to a file descriptor. ;;; Note: This is similar to `writev` in POSIX. + ;;; + ;;; Like POSIX, any calls of `write` (and other functions to read or write) + ;;; for a regular file by other threads in the WASI process should not be + ;;; interleaved while `write` is executed. (@interface func (export "write") (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. From 3d844d983d7fe7c62b2d4ff680b7b8856602147d Mon Sep 17 00:00:00 2001 From: YAMAMOTO Yuji Date: Tue, 19 May 2020 08:48:35 +0900 Subject: [PATCH 0660/1772] Document atomicity of `write` and `pwrite`, and technical fix about POSIX (#257) * Techinically speaking, preadv and pwritev are not in POSIX. Ref: https://pubs.opengroup.org/onlinepubs/9699919799/idx/ip.html * Document about atomicity of `write` and `pwrite` Related thread of ZULIP: https://bytecodealliance.zulipchat.com/#narrow/stream/219900-wasi/topic/Why.20is.20.60iovecs.60.20an.20array.20of.20strings.3F The thread refers atomicity of `read`, but I couldn't make a good expression for the atomicity of `read`. So I add document only in `write` and `pwrite`. * Limit the scope of atomicity The related POSIX document refers only to threads. https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_07 So the atomicity is limited in the process * Fix test * Fix after review https://github.com/WebAssembly/WASI/pull/257#issuecomment-617354670 The atomicity is guaranteed only for regular files or symbolic links (only symbolic links for a regular files, right?) Delete expressions indicating 'all or nothing' to reflect the actual behavior of POSIX's`write` etc. * Fix after review https://github.com/WebAssembly/WASI/pull/257#discussion_r421221765 Delete the sentences related to 'all data' completely Don't refer to symlink * Fix after review https://github.com/WebAssembly/WASI/pull/257#pullrequestreview-409467163 --- proposals/filesystem/phases/ephemeral/docs.md | 12 ++++++++++-- .../phases/ephemeral/witx/wasi_ephemeral_fd.witx | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 09c8dac51..f17e9aa9f 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -1415,7 +1415,7 @@ The permissions associated with the file. #### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` Read from a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `preadv` in POSIX. +Note: This is similar to `preadv` in Linux (and other Unix-es). ##### Params - `fd`: [`fd`](#fd) @@ -1469,7 +1469,11 @@ A buffer into which to write the preopened directory name. #### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` Write to a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `pwritev` in POSIX. +Note: This is similar to `pwritev` in Linux (and other Unix-es). + +Like Linux (and other Unix-es), any calls of [`pwrite`](#pwrite) (and other +functions to read or write) for a regular file by other threads in the +WASI process should not be interleaved while [`pwrite`](#pwrite) is executed. ##### Params - `fd`: [`fd`](#fd) @@ -1616,6 +1620,10 @@ The current offset of the file descriptor, relative to the start of the file. Write to a file descriptor. Note: This is similar to `writev` in POSIX. +Like POSIX, any calls of [`write`](#write) (and other functions to read or write) +for a regular file by other threads in the WASI process should not be +interleaved while [`write`](#write) is executed. + ##### Params - `fd`: [`fd`](#fd) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx index 2f3c618ff..821d3e707 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -127,7 +127,7 @@ ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in POSIX. + ;;; Note: This is similar to `preadv` in Linux (and other Unix-es). (@interface func (export "pread") (param $fd $fd) ;;; List of scatter/gather vectors in which to store data. @@ -157,7 +157,11 @@ ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in POSIX. + ;;; Note: This is similar to `pwritev` in Linux (and other Unix-es). + ;;; + ;;; Like Linux (and other Unix-es), any calls of `pwrite` (and other + ;;; functions to read or write) for a regular file by other threads in the + ;;; WASI process should not be interleaved while `pwrite` is executed. (@interface func (export "pwrite") (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. @@ -250,6 +254,10 @@ ;;; Write to a file descriptor. ;;; Note: This is similar to `writev` in POSIX. + ;;; + ;;; Like POSIX, any calls of `write` (and other functions to read or write) + ;;; for a regular file by other threads in the WASI process should not be + ;;; interleaved while `write` is executed. (@interface func (export "write") (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. From 7fccc87cfa48bcb0df148ade7fedf1af87514991 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 18 May 2020 17:32:57 -0700 Subject: [PATCH 0661/1772] Add an agenda for the 05-21 meeting. (#277) --- proposals/clocks/meetings/2020/WASI-05-21.md | 36 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 37 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-05-21.md diff --git a/proposals/clocks/meetings/2020/WASI-05-21.md b/proposals/clocks/meetings/2020/WASI-05-21.md new file mode 100644 index 000000000..a6ccded1a --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-05-21.md @@ -0,0 +1,36 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 21 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 21, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Update on WASI repository reorganization and new proposal repositories + 1. New proposal: wasi-nn: Neural Network API + 1. https://github.com/WebAssembly/WASI/issues/272 + 1. https://github.com/WebAssembly/wasi-nn + 1. Any initial feedback? + 1. Vote: Approve for Phase 1? + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index fcdd2e258..1722ae8af 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -32,3 +32,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI March 26th video call](2020/WASI-03-26.md) * [WASI April 9th video call](2020/WASI-04-09.md) * [WASI May 7th video call](2020/WASI-05-07.md) + * [WASI May 21st video call](2020/WASI-05-21.md) From 1dc28dcb94c4d43f64f3718b826e746bf990a934 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 18 May 2020 17:32:57 -0700 Subject: [PATCH 0662/1772] Add an agenda for the 05-21 meeting. (#277) --- proposals/random/meetings/2020/WASI-05-21.md | 36 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 37 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-05-21.md diff --git a/proposals/random/meetings/2020/WASI-05-21.md b/proposals/random/meetings/2020/WASI-05-21.md new file mode 100644 index 000000000..a6ccded1a --- /dev/null +++ b/proposals/random/meetings/2020/WASI-05-21.md @@ -0,0 +1,36 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 21 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 21, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Update on WASI repository reorganization and new proposal repositories + 1. New proposal: wasi-nn: Neural Network API + 1. https://github.com/WebAssembly/WASI/issues/272 + 1. https://github.com/WebAssembly/wasi-nn + 1. Any initial feedback? + 1. Vote: Approve for Phase 1? + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index fcdd2e258..1722ae8af 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -32,3 +32,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI March 26th video call](2020/WASI-03-26.md) * [WASI April 9th video call](2020/WASI-04-09.md) * [WASI May 7th video call](2020/WASI-05-07.md) + * [WASI May 21st video call](2020/WASI-05-21.md) From c69f384e70bdc8e8449231006262dfc6db81f2fc Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 18 May 2020 17:32:57 -0700 Subject: [PATCH 0663/1772] Add an agenda for the 05-21 meeting. (#277) --- .../filesystem/meetings/2020/WASI-05-21.md | 36 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 37 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-05-21.md diff --git a/proposals/filesystem/meetings/2020/WASI-05-21.md b/proposals/filesystem/meetings/2020/WASI-05-21.md new file mode 100644 index 000000000..a6ccded1a --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-05-21.md @@ -0,0 +1,36 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 21 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 21, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Update on WASI repository reorganization and new proposal repositories + 1. New proposal: wasi-nn: Neural Network API + 1. https://github.com/WebAssembly/WASI/issues/272 + 1. https://github.com/WebAssembly/wasi-nn + 1. Any initial feedback? + 1. Vote: Approve for Phase 1? + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index fcdd2e258..1722ae8af 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -32,3 +32,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI March 26th video call](2020/WASI-03-26.md) * [WASI April 9th video call](2020/WASI-04-09.md) * [WASI May 7th video call](2020/WASI-05-07.md) + * [WASI May 21st video call](2020/WASI-05-21.md) From da0d440817b4c65645273c6cc094e847dd8976d5 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Yuji Date: Tue, 19 May 2020 21:43:52 +0900 Subject: [PATCH 0664/1772] Fix: Broken link in DesignPrinciples.md #269 (#278) Perhaps this is a temporary fix. We'll have to update the link again after the design of the module types gets updated. --- proposals/clocks/docs/DesignPrinciples.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/docs/DesignPrinciples.md b/proposals/clocks/docs/DesignPrinciples.md index 584ba03ae..064b4525e 100644 --- a/proposals/clocks/docs/DesignPrinciples.md +++ b/proposals/clocks/docs/DesignPrinciples.md @@ -243,8 +243,8 @@ transparently. This can be used to adapt or attenuate the functionality of a WASI API without changing the code using it. In WASI, we envision interposition will primarily be configured -through the mechanisms in the interface types' [linking -proposal](https://github.com/WebAssembly/interface-types/blob/linking/proposals/interface-types/linking/Explainer.md). +through the mechanisms in the module types' [link-time virtualization +](https://github.com/WebAssembly/module-types/blob/module-imports/proposals/module-types/Explainer.md#link-time-virtualization). Imports are resolved when a module is instantiated, which may happen during the runtime of a larger logical application, so we can support interposition of WASI APIs without defining them in terms of explicit From ba8fe8ab781d594f6d707feda62f200aba9fab75 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Yuji Date: Tue, 19 May 2020 21:43:52 +0900 Subject: [PATCH 0665/1772] Fix: Broken link in DesignPrinciples.md #269 (#278) Perhaps this is a temporary fix. We'll have to update the link again after the design of the module types gets updated. --- proposals/random/docs/DesignPrinciples.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/docs/DesignPrinciples.md b/proposals/random/docs/DesignPrinciples.md index 584ba03ae..064b4525e 100644 --- a/proposals/random/docs/DesignPrinciples.md +++ b/proposals/random/docs/DesignPrinciples.md @@ -243,8 +243,8 @@ transparently. This can be used to adapt or attenuate the functionality of a WASI API without changing the code using it. In WASI, we envision interposition will primarily be configured -through the mechanisms in the interface types' [linking -proposal](https://github.com/WebAssembly/interface-types/blob/linking/proposals/interface-types/linking/Explainer.md). +through the mechanisms in the module types' [link-time virtualization +](https://github.com/WebAssembly/module-types/blob/module-imports/proposals/module-types/Explainer.md#link-time-virtualization). Imports are resolved when a module is instantiated, which may happen during the runtime of a larger logical application, so we can support interposition of WASI APIs without defining them in terms of explicit From fbf9f2aa9ff81bd3063cde2fc80de3fac977d456 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Yuji Date: Tue, 19 May 2020 21:43:52 +0900 Subject: [PATCH 0666/1772] Fix: Broken link in DesignPrinciples.md #269 (#278) Perhaps this is a temporary fix. We'll have to update the link again after the design of the module types gets updated. --- proposals/filesystem/docs/DesignPrinciples.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/docs/DesignPrinciples.md b/proposals/filesystem/docs/DesignPrinciples.md index 584ba03ae..064b4525e 100644 --- a/proposals/filesystem/docs/DesignPrinciples.md +++ b/proposals/filesystem/docs/DesignPrinciples.md @@ -243,8 +243,8 @@ transparently. This can be used to adapt or attenuate the functionality of a WASI API without changing the code using it. In WASI, we envision interposition will primarily be configured -through the mechanisms in the interface types' [linking -proposal](https://github.com/WebAssembly/interface-types/blob/linking/proposals/interface-types/linking/Explainer.md). +through the mechanisms in the module types' [link-time virtualization +](https://github.com/WebAssembly/module-types/blob/module-imports/proposals/module-types/Explainer.md#link-time-virtualization). Imports are resolved when a module is instantiated, which may happen during the runtime of a larger logical application, so we can support interposition of WASI APIs without defining them in terms of explicit From bb1036572d3db7a760bc13759cc77f5022291d7a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 28 May 2020 20:18:10 -0700 Subject: [PATCH 0667/1772] Elaborate on the definitions of commands and reactors. (#282) * Elaborate on the definitions of commands and reactors. This pulls out the parts of #281 which document existing practice. * Simplify the text about __heap_base and __data_end. We no longer need to say "applications may export these", but it's still useful to say that environments shouldn't access them. --- proposals/clocks/design/application-abi.md | 38 +++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/proposals/clocks/design/application-abi.md b/proposals/clocks/design/application-abi.md index 1b3f82b31..8fc85da32 100644 --- a/proposals/clocks/design/application-abi.md +++ b/proposals/clocks/design/application-abi.md @@ -15,26 +15,40 @@ Current Unstable ABI There are two kinds of modules: - A *command* exports a function named `_start`, with no arguments and no return - values. Environments shall call this function once, after instantiating the - module and all of its dependencies. After this function exits, the instance - is considered terminated and no further use of any of its exports should be - permitted. + values. - - A *reactor* exports a function named `_initialize`, with no arguments and no - return values. Environments shall call this function once, after instantiating - the module and all of its dependencies. After this function exits, the instance - remains live, and its exports may be accessed. + Command instances may assume that they will be called from the environment + at most once. Command instances may assume that none of their exports are + accessed outside the duraction of that call. + + - All other modules are *reactors*. A reactor may export a function named + `_initialize`, with no arguments and no return values. + + If an `_initialize` export is present, reactor instances may assume that it + will be called by the environment at most once, and that none of their + other exports are accessed before that call. + + After being instantiated, and after any `_initialize` function is called, + a reactor instance remains live, and its exports may be accessed. These kinds are mutually exclusive; implementations should report an error if asked to instantiate a module containing exports which declare it to be of multiple kinds. -Regardless of the kind, all programs accessing WASI APIs also export a linear -memory with the name `memory`. Pointers in WASI API calls are relative to this -memory's index space. +Regardless of the kind, all modules accessing WASI APIs also export a linear +memory with the name `memory`. Data pointers in WASI API calls are relative to +this memory's index space. + +Regardless of the kind, all modules accessing WASI APIs also export a table +with the name `__indirect_function_table`. Function pointers in WASI API calls +are relative to this table's index space. + +Environments shall not access exports named `__heap_base` or `__data_end`. +Toolchains are encouraged to avoid providing these exports. In the future, as the underlying WebAssembly platform offers more features, we -we hope to eliminate the requirement to export all of linear memory. +we hope to eliminate the requirement to export all of linear memory or all of +the indirect function table. Planned Stable ABI ------------------ From 23d4ff574e16c61fdd1f1f77acec4f66399af4e7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 28 May 2020 20:18:10 -0700 Subject: [PATCH 0668/1772] Elaborate on the definitions of commands and reactors. (#282) * Elaborate on the definitions of commands and reactors. This pulls out the parts of #281 which document existing practice. * Simplify the text about __heap_base and __data_end. We no longer need to say "applications may export these", but it's still useful to say that environments shouldn't access them. --- proposals/random/design/application-abi.md | 38 +++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/proposals/random/design/application-abi.md b/proposals/random/design/application-abi.md index 1b3f82b31..8fc85da32 100644 --- a/proposals/random/design/application-abi.md +++ b/proposals/random/design/application-abi.md @@ -15,26 +15,40 @@ Current Unstable ABI There are two kinds of modules: - A *command* exports a function named `_start`, with no arguments and no return - values. Environments shall call this function once, after instantiating the - module and all of its dependencies. After this function exits, the instance - is considered terminated and no further use of any of its exports should be - permitted. + values. - - A *reactor* exports a function named `_initialize`, with no arguments and no - return values. Environments shall call this function once, after instantiating - the module and all of its dependencies. After this function exits, the instance - remains live, and its exports may be accessed. + Command instances may assume that they will be called from the environment + at most once. Command instances may assume that none of their exports are + accessed outside the duraction of that call. + + - All other modules are *reactors*. A reactor may export a function named + `_initialize`, with no arguments and no return values. + + If an `_initialize` export is present, reactor instances may assume that it + will be called by the environment at most once, and that none of their + other exports are accessed before that call. + + After being instantiated, and after any `_initialize` function is called, + a reactor instance remains live, and its exports may be accessed. These kinds are mutually exclusive; implementations should report an error if asked to instantiate a module containing exports which declare it to be of multiple kinds. -Regardless of the kind, all programs accessing WASI APIs also export a linear -memory with the name `memory`. Pointers in WASI API calls are relative to this -memory's index space. +Regardless of the kind, all modules accessing WASI APIs also export a linear +memory with the name `memory`. Data pointers in WASI API calls are relative to +this memory's index space. + +Regardless of the kind, all modules accessing WASI APIs also export a table +with the name `__indirect_function_table`. Function pointers in WASI API calls +are relative to this table's index space. + +Environments shall not access exports named `__heap_base` or `__data_end`. +Toolchains are encouraged to avoid providing these exports. In the future, as the underlying WebAssembly platform offers more features, we -we hope to eliminate the requirement to export all of linear memory. +we hope to eliminate the requirement to export all of linear memory or all of +the indirect function table. Planned Stable ABI ------------------ From 1f6b2bcf8b86db75839b0eaaa242bd75a7a56d3d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 28 May 2020 20:18:10 -0700 Subject: [PATCH 0669/1772] Elaborate on the definitions of commands and reactors. (#282) * Elaborate on the definitions of commands and reactors. This pulls out the parts of #281 which document existing practice. * Simplify the text about __heap_base and __data_end. We no longer need to say "applications may export these", but it's still useful to say that environments shouldn't access them. --- .../filesystem/design/application-abi.md | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/proposals/filesystem/design/application-abi.md b/proposals/filesystem/design/application-abi.md index 1b3f82b31..8fc85da32 100644 --- a/proposals/filesystem/design/application-abi.md +++ b/proposals/filesystem/design/application-abi.md @@ -15,26 +15,40 @@ Current Unstable ABI There are two kinds of modules: - A *command* exports a function named `_start`, with no arguments and no return - values. Environments shall call this function once, after instantiating the - module and all of its dependencies. After this function exits, the instance - is considered terminated and no further use of any of its exports should be - permitted. + values. - - A *reactor* exports a function named `_initialize`, with no arguments and no - return values. Environments shall call this function once, after instantiating - the module and all of its dependencies. After this function exits, the instance - remains live, and its exports may be accessed. + Command instances may assume that they will be called from the environment + at most once. Command instances may assume that none of their exports are + accessed outside the duraction of that call. + + - All other modules are *reactors*. A reactor may export a function named + `_initialize`, with no arguments and no return values. + + If an `_initialize` export is present, reactor instances may assume that it + will be called by the environment at most once, and that none of their + other exports are accessed before that call. + + After being instantiated, and after any `_initialize` function is called, + a reactor instance remains live, and its exports may be accessed. These kinds are mutually exclusive; implementations should report an error if asked to instantiate a module containing exports which declare it to be of multiple kinds. -Regardless of the kind, all programs accessing WASI APIs also export a linear -memory with the name `memory`. Pointers in WASI API calls are relative to this -memory's index space. +Regardless of the kind, all modules accessing WASI APIs also export a linear +memory with the name `memory`. Data pointers in WASI API calls are relative to +this memory's index space. + +Regardless of the kind, all modules accessing WASI APIs also export a table +with the name `__indirect_function_table`. Function pointers in WASI API calls +are relative to this table's index space. + +Environments shall not access exports named `__heap_base` or `__data_end`. +Toolchains are encouraged to avoid providing these exports. In the future, as the underlying WebAssembly platform offers more features, we -we hope to eliminate the requirement to export all of linear memory. +we hope to eliminate the requirement to export all of linear memory or all of +the indirect function table. Planned Stable ABI ------------------ From 44eaabca34394890ab0fb1be509da9bd510f3a42 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 3 Jun 2020 15:54:58 -0700 Subject: [PATCH 0670/1772] Add an agenda for the 06-04 meeting. (#286) Also add the meeting notes for the last few meetings. --- proposals/clocks/meetings/2020/WASI-04-09.md | 48 +++++++++++++++ proposals/clocks/meetings/2020/WASI-05-07.md | 43 +++++++++++++ proposals/clocks/meetings/2020/WASI-05-21.md | 63 ++++++++++++++++++++ proposals/clocks/meetings/2020/WASI-06-04.md | 43 +++++++++++++ proposals/clocks/meetings/README.md | 1 + 5 files changed, 198 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-06-04.md diff --git a/proposals/clocks/meetings/2020/WASI-04-09.md b/proposals/clocks/meetings/2020/WASI-04-09.md index 0be796fe0..50ed01b17 100644 --- a/proposals/clocks/meetings/2020/WASI-04-09.md +++ b/proposals/clocks/meetings/2020/WASI-04-09.md @@ -33,3 +33,51 @@ Installation is required, see the calendar invite. 1. Discussion: Next steps. ## Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2020/WASI-04-09.md + +Attendees: + +Dan Gohman +Lee Campbell +Yury Delendik +Jacob Mischka +Andrew Brown +Mark McCaskey +Matthew Fisher +Radu Matei +Piotr Sikora +Pat Hickey +Benjamin Brittain +Johnnie Birch + +Meeting notes: +Moving to a CG-style phases process: https://github.com/WebAssembly/WASI/pull/252 +LC: What should be the expectations for wasi-sdk and/or other toolchains when a feature is stabilized? +DG: witx support will help wasi-sdk, Rust, and others adopt to new APIs +PH: witx is written in Rust, we’re happy for people to implement it in other languages as well. Currently it just emits markdown docs. Wasi-libc has a C header generator. +LC: witx becomes the ABI standard, “bytes on the wire”. Clients may have higher-level abstractions. The ABI is where the stability is. Applications may link against different versions of higher-level abstraction layers, but as long as the ABI layer is stable they can run on ABI-conforming implementations. + + +Proxy-wasm +Vote: approve for Phase 1 (see previous item)? +Result - approved, unanimous + +Discussion: Next steps. +Piotr to split out pieces of the spec which can be considered independently. + +Discussion: Threads in APIs +https://github.com/WebAssembly/threads/issues/138 +LC: It’d be nice to start thinking about thread safety and which APIs are thread-safe. +BB: Function signatures are typically not sufficient to know if something is thread-safe. +LW: The “is shared” predicate needs to be propagated through APIs. Everything is unshared by default. We need a shared attribute for tables, etc., and we’d need to have the shared attribute on functions to make them shared. +Without the shared attribute, functions can only be called from one thread. +The shared attribute for functions would need to be added in the core wasm spec, and then witx, being based on core wasm, would inherit it. +LW: Part of adding threading support sufficient for WASI would require adding a thread-local storage mechanism. + +Discussion: mmap +LC: What is the short-term plan for mmap? +DG: On the web, mmap is complicated by web compat. But WASI can pursue this. +LW: FWIW, https://github.com/WebAssembly/design/blob/master/FutureFeatures.md#finer-grained-control-over-memory is a long-standing thing we’ve said we’ve wanted in the wasm CG, but maybe it’s better solved by WASI + +LW: I can put together a proposal for a platform-independent mmap interface. diff --git a/proposals/clocks/meetings/2020/WASI-05-07.md b/proposals/clocks/meetings/2020/WASI-05-07.md index abd24a361..18b130196 100644 --- a/proposals/clocks/meetings/2020/WASI-05-07.md +++ b/proposals/clocks/meetings/2020/WASI-05-07.md @@ -44,3 +44,46 @@ Installation is required, see the calendar invite. 1. https://github.com/WebAssembly/module-types/pull/3 ## Meeting Notes + +Attendees: + +Dan Gohman +Mark S. Miller +Andrew Brown +Benjamin Brittain +Daiki +Johnnie Birch +Jplevyak +Lee Campbell +Luke Wager +Mingqiu Sun +Peter Heune +Yury +Sam Clegg + +Meeting notes: + +Heads up: Meetings agendas and notes will be moving: +https://github.com/WebAssembly/meetings/issues/549 + +Proposal organization +New proposal repositories prototypes: +https://github.com/WebAssembly/WASI-http-proxy/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-classic-command/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-poll/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-handle-index/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-clocks/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-random/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-filesystem/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-streams/tree/master/phases/ephemeral/witx + +Goal is to have them be forks of the WASI repo. + +How should the witx tooling work? +https://github.com/WebAssembly/testsuite +https://github.com/WebAssembly/WASI/blob/master/docs/Proposals.md +SBC: Have the proposals repos repo link to the docs from individual proposal repos. +https://github.com/WebAssembly/WASI/blob/master/docs/Process.md +Update on the module-types linking proposal: +https://github.com/WebAssembly/module-types/pull/3 +LW: This also starts to address link-time virtualization. diff --git a/proposals/clocks/meetings/2020/WASI-05-21.md b/proposals/clocks/meetings/2020/WASI-05-21.md index a6ccded1a..f341aecfd 100644 --- a/proposals/clocks/meetings/2020/WASI-05-21.md +++ b/proposals/clocks/meetings/2020/WASI-05-21.md @@ -34,3 +34,66 @@ Installation is required, see the calendar invite. 1. Vote: Approve for Phase 1? ## Meeting Notes + +Attendees: + +Dan Gohman +Lee Campbell +Johnnie Birch +Andrew Brown +Mingqiu Sun +Piotr Sikora +John Plevyak +Mark Miller +Pat Hickey + +Meeting notes: + +Update on WASI repository reorganization and new proposal repositories + +New proposal: wasi-nn: Neural Network API +https://github.com/WebAssembly/WASI/issues/272 +https://github.com/WebAssembly/wasi-nn +Any initial feedback? +Vote: Approve for Phase 1? +MS: +MM: What is the intellectual property side of neural networks? +MS: The weights and the model constitute the intellectual property. By keeping the model outside of the primary source programming language and outside of the main wasm program state, intellectual property is better protected. +MS: We’re working closely with WebNN proposal +MS: We expect many different hardware architectures will implement backend support. +MS: Initial POC would target a CPU backend but future devices (GPU, FPGA, TPU) could also be supported. +MM: Intellectual property is a legal term; is there any attempt at legal protection of these weights? +MS: It’s hard to protect a model across a development and deployment workflow. Model authors want to ensure that their specific weights are protected. What this proposal says is, the model can be opaque. +MM: So you’re not talking about legal protection, just about hiding the information? +MS: Yes, it’s mainly about confidentiality of the model. +MM: So since the questions that wasm would ask of the model through the API would expose information about the model, has there been any analysis? +MS: If you use a programmatic model to define weights it’s a lot harder to protect. +AB: +AB: Showed the proposal: https://github.com/WebAssembly/WASI/issues/272 +DG: Why explicitly expose the target instead of making it an implementation detail +AB/MS: Current thought is that it gives the developer more options. +MM: Could you refactor this to move the target enum into init_execution_context? +What happens if you ask for a target architecture and it isn’t available? +JB: Would it help to say that the target parameter is a hint? + +AB: I agree; 99% of the time, what you want is just “pick the best one for me” +Open question: Web-nn exposes this target parameter; why do that do it? +AB: I’ll summarize this discussion in an issue. +AB: Let’s look at how we represent tensors next. +AB: Is there a better way to represent multi-dimensional arrays? + +PH: You need a dynamic number of dimensions, and it’s hard to do that, especially with witx in its current form. +DG: Does this definition give everything the implementer need to be efficient .. to change to the format needed? Agree with Pat multi-dimensional support is a hard problem right now. +AB: We’ll learn more about the implementation concerns as we start prototyping this. +AB: How do we specify how to include dependencies? +DG/LC: The concept of optional imports may be useful here. +PH: Also have a PR for profiles that is a way to specify in witx dependencies. +DG: Have met the requirements for phase 1. Can vote. +LC: What happens if there is a fail? +AB: Have a mechanism to return error. +Vote: WASI-nn advance to phase 1 +SF: 7 +F: 5 +N: 2 + +Vote succeeds. diff --git a/proposals/clocks/meetings/2020/WASI-06-04.md b/proposals/clocks/meetings/2020/WASI-06-04.md new file mode 100644 index 000000000..6c7e2d7ee --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-06-04.md @@ -0,0 +1,43 @@ +![WASI logo](/WASI.png) + +## Agenda for the June 4 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: June 4, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. wasi-sdk release 11 + 1. https://github.com/WebAssembly/wasi-sdk/issues/139 + 1. Commands and Reactors: + 1. Heads-up: -mexec-model=reactor on clang trunk, use with wasi-libc trunk + 1. Update on repositories: wasi-nn, wasi-http-proxy, etc. + 1. WASI-http-proxy next steps + 1. https://github.com/WebAssembly/WASI-http-proxy + 1. Feedback given earlier is that it'd be good to look + at splitting out some of the parts. How can we help? + 1. Multi-call commands (Dan) + 1. https://github.com/WebAssembly/WASI/pull/281 + 1. Async + 1. https://github.com/WebAssembly/WASI/issues/276 + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 1722ae8af..e428c9cec 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -33,3 +33,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI April 9th video call](2020/WASI-04-09.md) * [WASI May 7th video call](2020/WASI-05-07.md) * [WASI May 21st video call](2020/WASI-05-21.md) + * [WASI June 4th video call](2020/WASI-06-04.md) From 89a051df4b4249d836e4b351ea3c3d117da2c884 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 3 Jun 2020 15:54:58 -0700 Subject: [PATCH 0671/1772] Add an agenda for the 06-04 meeting. (#286) Also add the meeting notes for the last few meetings. --- proposals/random/meetings/2020/WASI-04-09.md | 48 +++++++++++++++ proposals/random/meetings/2020/WASI-05-07.md | 43 +++++++++++++ proposals/random/meetings/2020/WASI-05-21.md | 63 ++++++++++++++++++++ proposals/random/meetings/2020/WASI-06-04.md | 43 +++++++++++++ proposals/random/meetings/README.md | 1 + 5 files changed, 198 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-06-04.md diff --git a/proposals/random/meetings/2020/WASI-04-09.md b/proposals/random/meetings/2020/WASI-04-09.md index 0be796fe0..50ed01b17 100644 --- a/proposals/random/meetings/2020/WASI-04-09.md +++ b/proposals/random/meetings/2020/WASI-04-09.md @@ -33,3 +33,51 @@ Installation is required, see the calendar invite. 1. Discussion: Next steps. ## Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2020/WASI-04-09.md + +Attendees: + +Dan Gohman +Lee Campbell +Yury Delendik +Jacob Mischka +Andrew Brown +Mark McCaskey +Matthew Fisher +Radu Matei +Piotr Sikora +Pat Hickey +Benjamin Brittain +Johnnie Birch + +Meeting notes: +Moving to a CG-style phases process: https://github.com/WebAssembly/WASI/pull/252 +LC: What should be the expectations for wasi-sdk and/or other toolchains when a feature is stabilized? +DG: witx support will help wasi-sdk, Rust, and others adopt to new APIs +PH: witx is written in Rust, we’re happy for people to implement it in other languages as well. Currently it just emits markdown docs. Wasi-libc has a C header generator. +LC: witx becomes the ABI standard, “bytes on the wire”. Clients may have higher-level abstractions. The ABI is where the stability is. Applications may link against different versions of higher-level abstraction layers, but as long as the ABI layer is stable they can run on ABI-conforming implementations. + + +Proxy-wasm +Vote: approve for Phase 1 (see previous item)? +Result - approved, unanimous + +Discussion: Next steps. +Piotr to split out pieces of the spec which can be considered independently. + +Discussion: Threads in APIs +https://github.com/WebAssembly/threads/issues/138 +LC: It’d be nice to start thinking about thread safety and which APIs are thread-safe. +BB: Function signatures are typically not sufficient to know if something is thread-safe. +LW: The “is shared” predicate needs to be propagated through APIs. Everything is unshared by default. We need a shared attribute for tables, etc., and we’d need to have the shared attribute on functions to make them shared. +Without the shared attribute, functions can only be called from one thread. +The shared attribute for functions would need to be added in the core wasm spec, and then witx, being based on core wasm, would inherit it. +LW: Part of adding threading support sufficient for WASI would require adding a thread-local storage mechanism. + +Discussion: mmap +LC: What is the short-term plan for mmap? +DG: On the web, mmap is complicated by web compat. But WASI can pursue this. +LW: FWIW, https://github.com/WebAssembly/design/blob/master/FutureFeatures.md#finer-grained-control-over-memory is a long-standing thing we’ve said we’ve wanted in the wasm CG, but maybe it’s better solved by WASI + +LW: I can put together a proposal for a platform-independent mmap interface. diff --git a/proposals/random/meetings/2020/WASI-05-07.md b/proposals/random/meetings/2020/WASI-05-07.md index abd24a361..18b130196 100644 --- a/proposals/random/meetings/2020/WASI-05-07.md +++ b/proposals/random/meetings/2020/WASI-05-07.md @@ -44,3 +44,46 @@ Installation is required, see the calendar invite. 1. https://github.com/WebAssembly/module-types/pull/3 ## Meeting Notes + +Attendees: + +Dan Gohman +Mark S. Miller +Andrew Brown +Benjamin Brittain +Daiki +Johnnie Birch +Jplevyak +Lee Campbell +Luke Wager +Mingqiu Sun +Peter Heune +Yury +Sam Clegg + +Meeting notes: + +Heads up: Meetings agendas and notes will be moving: +https://github.com/WebAssembly/meetings/issues/549 + +Proposal organization +New proposal repositories prototypes: +https://github.com/WebAssembly/WASI-http-proxy/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-classic-command/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-poll/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-handle-index/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-clocks/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-random/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-filesystem/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-streams/tree/master/phases/ephemeral/witx + +Goal is to have them be forks of the WASI repo. + +How should the witx tooling work? +https://github.com/WebAssembly/testsuite +https://github.com/WebAssembly/WASI/blob/master/docs/Proposals.md +SBC: Have the proposals repos repo link to the docs from individual proposal repos. +https://github.com/WebAssembly/WASI/blob/master/docs/Process.md +Update on the module-types linking proposal: +https://github.com/WebAssembly/module-types/pull/3 +LW: This also starts to address link-time virtualization. diff --git a/proposals/random/meetings/2020/WASI-05-21.md b/proposals/random/meetings/2020/WASI-05-21.md index a6ccded1a..f341aecfd 100644 --- a/proposals/random/meetings/2020/WASI-05-21.md +++ b/proposals/random/meetings/2020/WASI-05-21.md @@ -34,3 +34,66 @@ Installation is required, see the calendar invite. 1. Vote: Approve for Phase 1? ## Meeting Notes + +Attendees: + +Dan Gohman +Lee Campbell +Johnnie Birch +Andrew Brown +Mingqiu Sun +Piotr Sikora +John Plevyak +Mark Miller +Pat Hickey + +Meeting notes: + +Update on WASI repository reorganization and new proposal repositories + +New proposal: wasi-nn: Neural Network API +https://github.com/WebAssembly/WASI/issues/272 +https://github.com/WebAssembly/wasi-nn +Any initial feedback? +Vote: Approve for Phase 1? +MS: +MM: What is the intellectual property side of neural networks? +MS: The weights and the model constitute the intellectual property. By keeping the model outside of the primary source programming language and outside of the main wasm program state, intellectual property is better protected. +MS: We’re working closely with WebNN proposal +MS: We expect many different hardware architectures will implement backend support. +MS: Initial POC would target a CPU backend but future devices (GPU, FPGA, TPU) could also be supported. +MM: Intellectual property is a legal term; is there any attempt at legal protection of these weights? +MS: It’s hard to protect a model across a development and deployment workflow. Model authors want to ensure that their specific weights are protected. What this proposal says is, the model can be opaque. +MM: So you’re not talking about legal protection, just about hiding the information? +MS: Yes, it’s mainly about confidentiality of the model. +MM: So since the questions that wasm would ask of the model through the API would expose information about the model, has there been any analysis? +MS: If you use a programmatic model to define weights it’s a lot harder to protect. +AB: +AB: Showed the proposal: https://github.com/WebAssembly/WASI/issues/272 +DG: Why explicitly expose the target instead of making it an implementation detail +AB/MS: Current thought is that it gives the developer more options. +MM: Could you refactor this to move the target enum into init_execution_context? +What happens if you ask for a target architecture and it isn’t available? +JB: Would it help to say that the target parameter is a hint? + +AB: I agree; 99% of the time, what you want is just “pick the best one for me” +Open question: Web-nn exposes this target parameter; why do that do it? +AB: I’ll summarize this discussion in an issue. +AB: Let’s look at how we represent tensors next. +AB: Is there a better way to represent multi-dimensional arrays? + +PH: You need a dynamic number of dimensions, and it’s hard to do that, especially with witx in its current form. +DG: Does this definition give everything the implementer need to be efficient .. to change to the format needed? Agree with Pat multi-dimensional support is a hard problem right now. +AB: We’ll learn more about the implementation concerns as we start prototyping this. +AB: How do we specify how to include dependencies? +DG/LC: The concept of optional imports may be useful here. +PH: Also have a PR for profiles that is a way to specify in witx dependencies. +DG: Have met the requirements for phase 1. Can vote. +LC: What happens if there is a fail? +AB: Have a mechanism to return error. +Vote: WASI-nn advance to phase 1 +SF: 7 +F: 5 +N: 2 + +Vote succeeds. diff --git a/proposals/random/meetings/2020/WASI-06-04.md b/proposals/random/meetings/2020/WASI-06-04.md new file mode 100644 index 000000000..6c7e2d7ee --- /dev/null +++ b/proposals/random/meetings/2020/WASI-06-04.md @@ -0,0 +1,43 @@ +![WASI logo](/WASI.png) + +## Agenda for the June 4 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: June 4, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. wasi-sdk release 11 + 1. https://github.com/WebAssembly/wasi-sdk/issues/139 + 1. Commands and Reactors: + 1. Heads-up: -mexec-model=reactor on clang trunk, use with wasi-libc trunk + 1. Update on repositories: wasi-nn, wasi-http-proxy, etc. + 1. WASI-http-proxy next steps + 1. https://github.com/WebAssembly/WASI-http-proxy + 1. Feedback given earlier is that it'd be good to look + at splitting out some of the parts. How can we help? + 1. Multi-call commands (Dan) + 1. https://github.com/WebAssembly/WASI/pull/281 + 1. Async + 1. https://github.com/WebAssembly/WASI/issues/276 + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 1722ae8af..e428c9cec 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -33,3 +33,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI April 9th video call](2020/WASI-04-09.md) * [WASI May 7th video call](2020/WASI-05-07.md) * [WASI May 21st video call](2020/WASI-05-21.md) + * [WASI June 4th video call](2020/WASI-06-04.md) From e154e6cae4183074c7e732b02f4fc6f86d9538e2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 3 Jun 2020 15:54:58 -0700 Subject: [PATCH 0672/1772] Add an agenda for the 06-04 meeting. (#286) Also add the meeting notes for the last few meetings. --- .../filesystem/meetings/2020/WASI-04-09.md | 48 ++++++++++++++ .../filesystem/meetings/2020/WASI-05-07.md | 43 +++++++++++++ .../filesystem/meetings/2020/WASI-05-21.md | 63 +++++++++++++++++++ .../filesystem/meetings/2020/WASI-06-04.md | 43 +++++++++++++ proposals/filesystem/meetings/README.md | 1 + 5 files changed, 198 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-06-04.md diff --git a/proposals/filesystem/meetings/2020/WASI-04-09.md b/proposals/filesystem/meetings/2020/WASI-04-09.md index 0be796fe0..50ed01b17 100644 --- a/proposals/filesystem/meetings/2020/WASI-04-09.md +++ b/proposals/filesystem/meetings/2020/WASI-04-09.md @@ -33,3 +33,51 @@ Installation is required, see the calendar invite. 1. Discussion: Next steps. ## Meeting Notes + +Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2020/WASI-04-09.md + +Attendees: + +Dan Gohman +Lee Campbell +Yury Delendik +Jacob Mischka +Andrew Brown +Mark McCaskey +Matthew Fisher +Radu Matei +Piotr Sikora +Pat Hickey +Benjamin Brittain +Johnnie Birch + +Meeting notes: +Moving to a CG-style phases process: https://github.com/WebAssembly/WASI/pull/252 +LC: What should be the expectations for wasi-sdk and/or other toolchains when a feature is stabilized? +DG: witx support will help wasi-sdk, Rust, and others adopt to new APIs +PH: witx is written in Rust, we’re happy for people to implement it in other languages as well. Currently it just emits markdown docs. Wasi-libc has a C header generator. +LC: witx becomes the ABI standard, “bytes on the wire”. Clients may have higher-level abstractions. The ABI is where the stability is. Applications may link against different versions of higher-level abstraction layers, but as long as the ABI layer is stable they can run on ABI-conforming implementations. + + +Proxy-wasm +Vote: approve for Phase 1 (see previous item)? +Result - approved, unanimous + +Discussion: Next steps. +Piotr to split out pieces of the spec which can be considered independently. + +Discussion: Threads in APIs +https://github.com/WebAssembly/threads/issues/138 +LC: It’d be nice to start thinking about thread safety and which APIs are thread-safe. +BB: Function signatures are typically not sufficient to know if something is thread-safe. +LW: The “is shared” predicate needs to be propagated through APIs. Everything is unshared by default. We need a shared attribute for tables, etc., and we’d need to have the shared attribute on functions to make them shared. +Without the shared attribute, functions can only be called from one thread. +The shared attribute for functions would need to be added in the core wasm spec, and then witx, being based on core wasm, would inherit it. +LW: Part of adding threading support sufficient for WASI would require adding a thread-local storage mechanism. + +Discussion: mmap +LC: What is the short-term plan for mmap? +DG: On the web, mmap is complicated by web compat. But WASI can pursue this. +LW: FWIW, https://github.com/WebAssembly/design/blob/master/FutureFeatures.md#finer-grained-control-over-memory is a long-standing thing we’ve said we’ve wanted in the wasm CG, but maybe it’s better solved by WASI + +LW: I can put together a proposal for a platform-independent mmap interface. diff --git a/proposals/filesystem/meetings/2020/WASI-05-07.md b/proposals/filesystem/meetings/2020/WASI-05-07.md index abd24a361..18b130196 100644 --- a/proposals/filesystem/meetings/2020/WASI-05-07.md +++ b/proposals/filesystem/meetings/2020/WASI-05-07.md @@ -44,3 +44,46 @@ Installation is required, see the calendar invite. 1. https://github.com/WebAssembly/module-types/pull/3 ## Meeting Notes + +Attendees: + +Dan Gohman +Mark S. Miller +Andrew Brown +Benjamin Brittain +Daiki +Johnnie Birch +Jplevyak +Lee Campbell +Luke Wager +Mingqiu Sun +Peter Heune +Yury +Sam Clegg + +Meeting notes: + +Heads up: Meetings agendas and notes will be moving: +https://github.com/WebAssembly/meetings/issues/549 + +Proposal organization +New proposal repositories prototypes: +https://github.com/WebAssembly/WASI-http-proxy/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-classic-command/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-poll/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-handle-index/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-clocks/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-random/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-filesystem/tree/master/phases/ephemeral/witx +https://github.com/WebAssembly/WASI-streams/tree/master/phases/ephemeral/witx + +Goal is to have them be forks of the WASI repo. + +How should the witx tooling work? +https://github.com/WebAssembly/testsuite +https://github.com/WebAssembly/WASI/blob/master/docs/Proposals.md +SBC: Have the proposals repos repo link to the docs from individual proposal repos. +https://github.com/WebAssembly/WASI/blob/master/docs/Process.md +Update on the module-types linking proposal: +https://github.com/WebAssembly/module-types/pull/3 +LW: This also starts to address link-time virtualization. diff --git a/proposals/filesystem/meetings/2020/WASI-05-21.md b/proposals/filesystem/meetings/2020/WASI-05-21.md index a6ccded1a..f341aecfd 100644 --- a/proposals/filesystem/meetings/2020/WASI-05-21.md +++ b/proposals/filesystem/meetings/2020/WASI-05-21.md @@ -34,3 +34,66 @@ Installation is required, see the calendar invite. 1. Vote: Approve for Phase 1? ## Meeting Notes + +Attendees: + +Dan Gohman +Lee Campbell +Johnnie Birch +Andrew Brown +Mingqiu Sun +Piotr Sikora +John Plevyak +Mark Miller +Pat Hickey + +Meeting notes: + +Update on WASI repository reorganization and new proposal repositories + +New proposal: wasi-nn: Neural Network API +https://github.com/WebAssembly/WASI/issues/272 +https://github.com/WebAssembly/wasi-nn +Any initial feedback? +Vote: Approve for Phase 1? +MS: +MM: What is the intellectual property side of neural networks? +MS: The weights and the model constitute the intellectual property. By keeping the model outside of the primary source programming language and outside of the main wasm program state, intellectual property is better protected. +MS: We’re working closely with WebNN proposal +MS: We expect many different hardware architectures will implement backend support. +MS: Initial POC would target a CPU backend but future devices (GPU, FPGA, TPU) could also be supported. +MM: Intellectual property is a legal term; is there any attempt at legal protection of these weights? +MS: It’s hard to protect a model across a development and deployment workflow. Model authors want to ensure that their specific weights are protected. What this proposal says is, the model can be opaque. +MM: So you’re not talking about legal protection, just about hiding the information? +MS: Yes, it’s mainly about confidentiality of the model. +MM: So since the questions that wasm would ask of the model through the API would expose information about the model, has there been any analysis? +MS: If you use a programmatic model to define weights it’s a lot harder to protect. +AB: +AB: Showed the proposal: https://github.com/WebAssembly/WASI/issues/272 +DG: Why explicitly expose the target instead of making it an implementation detail +AB/MS: Current thought is that it gives the developer more options. +MM: Could you refactor this to move the target enum into init_execution_context? +What happens if you ask for a target architecture and it isn’t available? +JB: Would it help to say that the target parameter is a hint? + +AB: I agree; 99% of the time, what you want is just “pick the best one for me” +Open question: Web-nn exposes this target parameter; why do that do it? +AB: I’ll summarize this discussion in an issue. +AB: Let’s look at how we represent tensors next. +AB: Is there a better way to represent multi-dimensional arrays? + +PH: You need a dynamic number of dimensions, and it’s hard to do that, especially with witx in its current form. +DG: Does this definition give everything the implementer need to be efficient .. to change to the format needed? Agree with Pat multi-dimensional support is a hard problem right now. +AB: We’ll learn more about the implementation concerns as we start prototyping this. +AB: How do we specify how to include dependencies? +DG/LC: The concept of optional imports may be useful here. +PH: Also have a PR for profiles that is a way to specify in witx dependencies. +DG: Have met the requirements for phase 1. Can vote. +LC: What happens if there is a fail? +AB: Have a mechanism to return error. +Vote: WASI-nn advance to phase 1 +SF: 7 +F: 5 +N: 2 + +Vote succeeds. diff --git a/proposals/filesystem/meetings/2020/WASI-06-04.md b/proposals/filesystem/meetings/2020/WASI-06-04.md new file mode 100644 index 000000000..6c7e2d7ee --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-06-04.md @@ -0,0 +1,43 @@ +![WASI logo](/WASI.png) + +## Agenda for the June 4 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: June 4, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. wasi-sdk release 11 + 1. https://github.com/WebAssembly/wasi-sdk/issues/139 + 1. Commands and Reactors: + 1. Heads-up: -mexec-model=reactor on clang trunk, use with wasi-libc trunk + 1. Update on repositories: wasi-nn, wasi-http-proxy, etc. + 1. WASI-http-proxy next steps + 1. https://github.com/WebAssembly/WASI-http-proxy + 1. Feedback given earlier is that it'd be good to look + at splitting out some of the parts. How can we help? + 1. Multi-call commands (Dan) + 1. https://github.com/WebAssembly/WASI/pull/281 + 1. Async + 1. https://github.com/WebAssembly/WASI/issues/276 + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 1722ae8af..e428c9cec 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -33,3 +33,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI April 9th video call](2020/WASI-04-09.md) * [WASI May 7th video call](2020/WASI-05-07.md) * [WASI May 21st video call](2020/WASI-05-21.md) + * [WASI June 4th video call](2020/WASI-06-04.md) From 9e42da401de1adad779f385a54c1df17f0d0a0d2 Mon Sep 17 00:00:00 2001 From: "katie.martin" Date: Thu, 4 Jun 2020 11:57:03 -0400 Subject: [PATCH 0673/1772] witx: Add trait implementations to `Id` (#287) * witx: add AsRef implementation to witx::Id * witx: add PartialEq implementations for Id --- proposals/clocks/tools/witx/src/ast.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 661e91475..1e1981f66 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -14,6 +14,30 @@ impl Id { } } +impl AsRef for Id { + fn as_ref(&self) -> &str { + self.0.as_ref() + } +} + +impl PartialEq<&str> for Id { + fn eq(&self, rhs: &&str) -> bool { + PartialEq::eq(self.as_ref(), *rhs) + } +} + +impl PartialEq for &str { + fn eq(&self, rhs: &Id) -> bool { + PartialEq::eq(*self, rhs.as_ref()) + } +} + +impl From<&str> for Id { + fn from(s: &str) -> Self { + Self::new(s) + } +} + #[derive(Debug, Clone)] pub struct Document { definitions: Vec, From bdde3a44366be47a3379fc4d614c7757096f8a94 Mon Sep 17 00:00:00 2001 From: "katie.martin" Date: Thu, 4 Jun 2020 11:57:03 -0400 Subject: [PATCH 0674/1772] witx: Add trait implementations to `Id` (#287) * witx: add AsRef implementation to witx::Id * witx: add PartialEq implementations for Id --- proposals/random/tools/witx/src/ast.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 661e91475..1e1981f66 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -14,6 +14,30 @@ impl Id { } } +impl AsRef for Id { + fn as_ref(&self) -> &str { + self.0.as_ref() + } +} + +impl PartialEq<&str> for Id { + fn eq(&self, rhs: &&str) -> bool { + PartialEq::eq(self.as_ref(), *rhs) + } +} + +impl PartialEq for &str { + fn eq(&self, rhs: &Id) -> bool { + PartialEq::eq(*self, rhs.as_ref()) + } +} + +impl From<&str> for Id { + fn from(s: &str) -> Self { + Self::new(s) + } +} + #[derive(Debug, Clone)] pub struct Document { definitions: Vec, From f48b70f2ab9afde1bb1cc3159b56e872e67d6454 Mon Sep 17 00:00:00 2001 From: "katie.martin" Date: Thu, 4 Jun 2020 11:57:03 -0400 Subject: [PATCH 0675/1772] witx: Add trait implementations to `Id` (#287) * witx: add AsRef implementation to witx::Id * witx: add PartialEq implementations for Id --- proposals/filesystem/tools/witx/src/ast.rs | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 661e91475..1e1981f66 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -14,6 +14,30 @@ impl Id { } } +impl AsRef for Id { + fn as_ref(&self) -> &str { + self.0.as_ref() + } +} + +impl PartialEq<&str> for Id { + fn eq(&self, rhs: &&str) -> bool { + PartialEq::eq(self.as_ref(), *rhs) + } +} + +impl PartialEq for &str { + fn eq(&self, rhs: &Id) -> bool { + PartialEq::eq(*self, rhs.as_ref()) + } +} + +impl From<&str> for Id { + fn from(s: &str) -> Self { + Self::new(s) + } +} + #[derive(Debug, Clone)] pub struct Document { definitions: Vec, From 15515dcac468a633c0c412edca067dcbce2a8cea Mon Sep 17 00:00:00 2001 From: nasso <11479594+nasso@users.noreply.github.com> Date: Mon, 8 Jun 2020 19:55:30 +0200 Subject: [PATCH 0676/1772] Fix link in phases/README.md (#284) * Fix link in phases/README.md * Update link to docs/Process --- proposals/clocks/phases/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/phases/README.md b/proposals/clocks/phases/README.md index 06a515526..62c5f9004 100644 --- a/proposals/clocks/phases/README.md +++ b/proposals/clocks/phases/README.md @@ -9,7 +9,7 @@ for a balance between the need for stability to allow people to build compatible implementations, libraries, and tools and gain implementation experience, and the need for proposals to evolve. -[phases process]: https://github.com/WebAssembly/WASI/blob/master/phases/README.md +[process]: https://github.com/WebAssembly/WASI/blob/master/docs/Process.md ## The ephemeral/snapshot/old Phases From e2ab3e10bf77e70ca1a7dab6e4072504053f5f49 Mon Sep 17 00:00:00 2001 From: nasso <11479594+nasso@users.noreply.github.com> Date: Mon, 8 Jun 2020 19:55:30 +0200 Subject: [PATCH 0677/1772] Fix link in phases/README.md (#284) * Fix link in phases/README.md * Update link to docs/Process --- proposals/random/phases/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/phases/README.md b/proposals/random/phases/README.md index 06a515526..62c5f9004 100644 --- a/proposals/random/phases/README.md +++ b/proposals/random/phases/README.md @@ -9,7 +9,7 @@ for a balance between the need for stability to allow people to build compatible implementations, libraries, and tools and gain implementation experience, and the need for proposals to evolve. -[phases process]: https://github.com/WebAssembly/WASI/blob/master/phases/README.md +[process]: https://github.com/WebAssembly/WASI/blob/master/docs/Process.md ## The ephemeral/snapshot/old Phases From 8954620fab4a58091e22171869a824de0a14d746 Mon Sep 17 00:00:00 2001 From: nasso <11479594+nasso@users.noreply.github.com> Date: Mon, 8 Jun 2020 19:55:30 +0200 Subject: [PATCH 0678/1772] Fix link in phases/README.md (#284) * Fix link in phases/README.md * Update link to docs/Process --- proposals/filesystem/phases/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/phases/README.md b/proposals/filesystem/phases/README.md index 06a515526..62c5f9004 100644 --- a/proposals/filesystem/phases/README.md +++ b/proposals/filesystem/phases/README.md @@ -9,7 +9,7 @@ for a balance between the need for stability to allow people to build compatible implementations, libraries, and tools and gain implementation experience, and the need for proposals to evolve. -[phases process]: https://github.com/WebAssembly/WASI/blob/master/phases/README.md +[process]: https://github.com/WebAssembly/WASI/blob/master/docs/Process.md ## The ephemeral/snapshot/old Phases From 26dc6528c002a4943101c2c4705976b4f6a6d516 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 23 Jun 2020 13:16:28 -0700 Subject: [PATCH 0679/1772] witx crate: bump dep version, crate version (#291) * witx: update wast dependency to 20.0.0 * bump witx crate version to 0.8.6 --- proposals/clocks/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index e5edffad2..475541c4f 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.5" +version = "0.8.6" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" @@ -17,7 +17,7 @@ crate-type=["rlib"] anyhow = "1" log = "0.4" thiserror = "1.0" -wast = { version = "11.0.0", default-features = false } +wast = { version = "20.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" From 458de38bead59b4c8eb981af74a07425c9b8baa9 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 23 Jun 2020 13:16:28 -0700 Subject: [PATCH 0680/1772] witx crate: bump dep version, crate version (#291) * witx: update wast dependency to 20.0.0 * bump witx crate version to 0.8.6 --- proposals/random/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index e5edffad2..475541c4f 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.5" +version = "0.8.6" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" @@ -17,7 +17,7 @@ crate-type=["rlib"] anyhow = "1" log = "0.4" thiserror = "1.0" -wast = { version = "11.0.0", default-features = false } +wast = { version = "20.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" From 24240f43c1093e109af87922f88a86f90667a677 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 23 Jun 2020 13:16:28 -0700 Subject: [PATCH 0681/1772] witx crate: bump dep version, crate version (#291) * witx: update wast dependency to 20.0.0 * bump witx crate version to 0.8.6 --- proposals/filesystem/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index e5edffad2..475541c4f 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.5" +version = "0.8.6" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" @@ -17,7 +17,7 @@ crate-type=["rlib"] anyhow = "1" log = "0.4" thiserror = "1.0" -wast = { version = "11.0.0", default-features = false } +wast = { version = "20.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" From eec5c4c703bc4ac539f39ccefd906400d755a616 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 1 Jul 2020 23:22:04 -0700 Subject: [PATCH 0682/1772] Add an agenda for the 07-02 meeting. (#293) --- proposals/clocks/meetings/2020/WASI-07-02.md | 41 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 42 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-07-02.md diff --git a/proposals/clocks/meetings/2020/WASI-07-02.md b/proposals/clocks/meetings/2020/WASI-07-02.md new file mode 100644 index 000000000..cc9ac5576 --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-07-02.md @@ -0,0 +1,41 @@ +![WASI logo](/WASI.png) + +## Agenda for the July 2 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: July 2, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Update on action items. + 1. proxy-wasm repo + 1. Discussion topic: WASI and POSIX + 1. https://github.com/WebAssembly/WASI/issues/292 + 1. What should we do on `lseek` past the end of a file? + 1. Should POSIX be a normative reference for the filesystem etc. APIs? + 1. Documentation philosophy. + 1. Heads-up: Module-linking-based dynamic linking: + 1. https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Example-SharedEverythingDynamicLinking.md + 1. Tooling for new-style commands: + 1. https://reviews.llvm.org/D81689 + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index e428c9cec..26397a268 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -34,3 +34,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 7th video call](2020/WASI-05-07.md) * [WASI May 21st video call](2020/WASI-05-21.md) * [WASI June 4th video call](2020/WASI-06-04.md) + * [WASI July 2nd video call](2020/WASI-07-02.md) From e25ef321ee505fb04cd3df40208c9682219c851e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 1 Jul 2020 23:22:04 -0700 Subject: [PATCH 0683/1772] Add an agenda for the 07-02 meeting. (#293) --- proposals/random/meetings/2020/WASI-07-02.md | 41 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 42 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-07-02.md diff --git a/proposals/random/meetings/2020/WASI-07-02.md b/proposals/random/meetings/2020/WASI-07-02.md new file mode 100644 index 000000000..cc9ac5576 --- /dev/null +++ b/proposals/random/meetings/2020/WASI-07-02.md @@ -0,0 +1,41 @@ +![WASI logo](/WASI.png) + +## Agenda for the July 2 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: July 2, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Update on action items. + 1. proxy-wasm repo + 1. Discussion topic: WASI and POSIX + 1. https://github.com/WebAssembly/WASI/issues/292 + 1. What should we do on `lseek` past the end of a file? + 1. Should POSIX be a normative reference for the filesystem etc. APIs? + 1. Documentation philosophy. + 1. Heads-up: Module-linking-based dynamic linking: + 1. https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Example-SharedEverythingDynamicLinking.md + 1. Tooling for new-style commands: + 1. https://reviews.llvm.org/D81689 + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index e428c9cec..26397a268 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -34,3 +34,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 7th video call](2020/WASI-05-07.md) * [WASI May 21st video call](2020/WASI-05-21.md) * [WASI June 4th video call](2020/WASI-06-04.md) + * [WASI July 2nd video call](2020/WASI-07-02.md) From a465f80989747df0baeb1792a043aecb281fde19 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 1 Jul 2020 23:22:04 -0700 Subject: [PATCH 0684/1772] Add an agenda for the 07-02 meeting. (#293) --- .../filesystem/meetings/2020/WASI-07-02.md | 41 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 42 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-07-02.md diff --git a/proposals/filesystem/meetings/2020/WASI-07-02.md b/proposals/filesystem/meetings/2020/WASI-07-02.md new file mode 100644 index 000000000..cc9ac5576 --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-07-02.md @@ -0,0 +1,41 @@ +![WASI logo](/WASI.png) + +## Agenda for the July 2 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: July 2, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Update on action items. + 1. proxy-wasm repo + 1. Discussion topic: WASI and POSIX + 1. https://github.com/WebAssembly/WASI/issues/292 + 1. What should we do on `lseek` past the end of a file? + 1. Should POSIX be a normative reference for the filesystem etc. APIs? + 1. Documentation philosophy. + 1. Heads-up: Module-linking-based dynamic linking: + 1. https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Example-SharedEverythingDynamicLinking.md + 1. Tooling for new-style commands: + 1. https://reviews.llvm.org/D81689 + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index e428c9cec..26397a268 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -34,3 +34,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 7th video call](2020/WASI-05-07.md) * [WASI May 21st video call](2020/WASI-05-21.md) * [WASI June 4th video call](2020/WASI-06-04.md) + * [WASI July 2nd video call](2020/WASI-07-02.md) From 39fa6321336d3f61479ac33bf13b92535864d440 Mon Sep 17 00:00:00 2001 From: PTrottier Date: Mon, 6 Jul 2020 11:41:39 -0400 Subject: [PATCH 0685/1772] Improve spelling (#295) --- proposals/clocks/Charter.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/Charter.md b/proposals/clocks/Charter.md index c7d3a49af..c50381166 100644 --- a/proposals/clocks/Charter.md +++ b/proposals/clocks/Charter.md @@ -11,7 +11,7 @@ the sections of the [CG charter](https://webassembly.github.io/cg-charter/) rela ## Goals -The mission of this sugbroup is to provide a forum for pre-standardization +The mission of this subgroup is to provide a forum for pre-standardization collaboration on a system interface API for WebAssembly programs. ## Scope @@ -21,7 +21,7 @@ The Subgroup will consider topics related to system interface APIs, including: - APIs for host filesystems, network stacks, and other resources. - APIs for graphics, audio, input devices - APIs for encryption, format conversion, and other transformations - (particularly where hardware accelleration may be available on some platforms) + (particularly where hardware acceleration may be available on some platforms) ## Deliverables From fb81db740129cd89da7938bd2d9d04b70ddd0c62 Mon Sep 17 00:00:00 2001 From: PTrottier Date: Mon, 6 Jul 2020 11:41:39 -0400 Subject: [PATCH 0686/1772] Improve spelling (#295) --- proposals/random/Charter.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/Charter.md b/proposals/random/Charter.md index c7d3a49af..c50381166 100644 --- a/proposals/random/Charter.md +++ b/proposals/random/Charter.md @@ -11,7 +11,7 @@ the sections of the [CG charter](https://webassembly.github.io/cg-charter/) rela ## Goals -The mission of this sugbroup is to provide a forum for pre-standardization +The mission of this subgroup is to provide a forum for pre-standardization collaboration on a system interface API for WebAssembly programs. ## Scope @@ -21,7 +21,7 @@ The Subgroup will consider topics related to system interface APIs, including: - APIs for host filesystems, network stacks, and other resources. - APIs for graphics, audio, input devices - APIs for encryption, format conversion, and other transformations - (particularly where hardware accelleration may be available on some platforms) + (particularly where hardware acceleration may be available on some platforms) ## Deliverables From 0a637aaaec3328f901283427aa6f72f57b15f598 Mon Sep 17 00:00:00 2001 From: PTrottier Date: Mon, 6 Jul 2020 11:41:39 -0400 Subject: [PATCH 0687/1772] Improve spelling (#295) --- proposals/filesystem/Charter.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/Charter.md b/proposals/filesystem/Charter.md index c7d3a49af..c50381166 100644 --- a/proposals/filesystem/Charter.md +++ b/proposals/filesystem/Charter.md @@ -11,7 +11,7 @@ the sections of the [CG charter](https://webassembly.github.io/cg-charter/) rela ## Goals -The mission of this sugbroup is to provide a forum for pre-standardization +The mission of this subgroup is to provide a forum for pre-standardization collaboration on a system interface API for WebAssembly programs. ## Scope @@ -21,7 +21,7 @@ The Subgroup will consider topics related to system interface APIs, including: - APIs for host filesystems, network stacks, and other resources. - APIs for graphics, audio, input devices - APIs for encryption, format conversion, and other transformations - (particularly where hardware accelleration may be available on some platforms) + (particularly where hardware acceleration may be available on some platforms) ## Deliverables From dfb4f5ff9f7f024dd1106c7c83066b63e95a3431 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 16 Jul 2020 01:00:27 -0700 Subject: [PATCH 0688/1772] Add an agenda for the 07-16 meeting. (#300) --- proposals/clocks/meetings/2020/WASI-07-16.md | 41 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 42 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-07-16.md diff --git a/proposals/clocks/meetings/2020/WASI-07-16.md b/proposals/clocks/meetings/2020/WASI-07-16.md new file mode 100644 index 000000000..2ced1afd3 --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-07-16.md @@ -0,0 +1,41 @@ +![WASI logo](/WASI.png) + +## Agenda for the July 16 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: July 16, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. WASI testsuite activities + 1. https://github.com/WebAssembly/WASI/issues/9 + 1. What kinds of tests should be in an official testsuite? + 1. Where should we collect them? + 1. Discussion topic: Threads + 1. WebAssembly/threads#8 + 1. WebAssembly/threads#95 + 1. WebAssembly/threads#138 + 1. Discussion topic: `fd_seek` past the end of a file on Windows + 1. https://github.com/WebAssembly/WASI/issues/292 + 1. Discussion topic: Symbolic links and Windows + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 26397a268..7c1d8d4bb 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -35,3 +35,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 21st video call](2020/WASI-05-21.md) * [WASI June 4th video call](2020/WASI-06-04.md) * [WASI July 2nd video call](2020/WASI-07-02.md) + * [WASI July 16th video call](2020/WASI-07-16.md) From 939937c5c2bf8a0333da164804b228e0e4e1b5c3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 16 Jul 2020 01:00:27 -0700 Subject: [PATCH 0689/1772] Add an agenda for the 07-16 meeting. (#300) --- proposals/random/meetings/2020/WASI-07-16.md | 41 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 42 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-07-16.md diff --git a/proposals/random/meetings/2020/WASI-07-16.md b/proposals/random/meetings/2020/WASI-07-16.md new file mode 100644 index 000000000..2ced1afd3 --- /dev/null +++ b/proposals/random/meetings/2020/WASI-07-16.md @@ -0,0 +1,41 @@ +![WASI logo](/WASI.png) + +## Agenda for the July 16 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: July 16, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. WASI testsuite activities + 1. https://github.com/WebAssembly/WASI/issues/9 + 1. What kinds of tests should be in an official testsuite? + 1. Where should we collect them? + 1. Discussion topic: Threads + 1. WebAssembly/threads#8 + 1. WebAssembly/threads#95 + 1. WebAssembly/threads#138 + 1. Discussion topic: `fd_seek` past the end of a file on Windows + 1. https://github.com/WebAssembly/WASI/issues/292 + 1. Discussion topic: Symbolic links and Windows + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 26397a268..7c1d8d4bb 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -35,3 +35,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 21st video call](2020/WASI-05-21.md) * [WASI June 4th video call](2020/WASI-06-04.md) * [WASI July 2nd video call](2020/WASI-07-02.md) + * [WASI July 16th video call](2020/WASI-07-16.md) From ea5680a7a37a509ae58461270712bef35dc01244 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 16 Jul 2020 01:00:27 -0700 Subject: [PATCH 0690/1772] Add an agenda for the 07-16 meeting. (#300) --- .../filesystem/meetings/2020/WASI-07-16.md | 41 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 42 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-07-16.md diff --git a/proposals/filesystem/meetings/2020/WASI-07-16.md b/proposals/filesystem/meetings/2020/WASI-07-16.md new file mode 100644 index 000000000..2ced1afd3 --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-07-16.md @@ -0,0 +1,41 @@ +![WASI logo](/WASI.png) + +## Agenda for the July 16 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: July 16, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. WASI testsuite activities + 1. https://github.com/WebAssembly/WASI/issues/9 + 1. What kinds of tests should be in an official testsuite? + 1. Where should we collect them? + 1. Discussion topic: Threads + 1. WebAssembly/threads#8 + 1. WebAssembly/threads#95 + 1. WebAssembly/threads#138 + 1. Discussion topic: `fd_seek` past the end of a file on Windows + 1. https://github.com/WebAssembly/WASI/issues/292 + 1. Discussion topic: Symbolic links and Windows + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 26397a268..7c1d8d4bb 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -35,3 +35,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI May 21st video call](2020/WASI-05-21.md) * [WASI June 4th video call](2020/WASI-06-04.md) * [WASI July 2nd video call](2020/WASI-07-02.md) + * [WASI July 16th video call](2020/WASI-07-16.md) From 58b964f0d12e5164d10969b42defdc2d75eae01d Mon Sep 17 00:00:00 2001 From: David McKay Date: Fri, 17 Jul 2020 00:01:37 +0100 Subject: [PATCH 0691/1772] chore: update links to WebAssembly/threads issues (#301) --- proposals/clocks/meetings/2020/WASI-07-16.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/clocks/meetings/2020/WASI-07-16.md b/proposals/clocks/meetings/2020/WASI-07-16.md index 2ced1afd3..f4ba68088 100644 --- a/proposals/clocks/meetings/2020/WASI-07-16.md +++ b/proposals/clocks/meetings/2020/WASI-07-16.md @@ -31,9 +31,9 @@ Installation is required, see the calendar invite. 1. What kinds of tests should be in an official testsuite? 1. Where should we collect them? 1. Discussion topic: Threads - 1. WebAssembly/threads#8 - 1. WebAssembly/threads#95 - 1. WebAssembly/threads#138 + 1. https://github.com/WebAssembly/threads/issues/8 + 1. https://github.com/WebAssembly/threads/issues/95 + 1. https://github.com/WebAssembly/threads/issues/138 1. Discussion topic: `fd_seek` past the end of a file on Windows 1. https://github.com/WebAssembly/WASI/issues/292 1. Discussion topic: Symbolic links and Windows From a20043da02d5dc14f25ea2fdb7532e167775e4cb Mon Sep 17 00:00:00 2001 From: David McKay Date: Fri, 17 Jul 2020 00:01:37 +0100 Subject: [PATCH 0692/1772] chore: update links to WebAssembly/threads issues (#301) --- proposals/random/meetings/2020/WASI-07-16.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/random/meetings/2020/WASI-07-16.md b/proposals/random/meetings/2020/WASI-07-16.md index 2ced1afd3..f4ba68088 100644 --- a/proposals/random/meetings/2020/WASI-07-16.md +++ b/proposals/random/meetings/2020/WASI-07-16.md @@ -31,9 +31,9 @@ Installation is required, see the calendar invite. 1. What kinds of tests should be in an official testsuite? 1. Where should we collect them? 1. Discussion topic: Threads - 1. WebAssembly/threads#8 - 1. WebAssembly/threads#95 - 1. WebAssembly/threads#138 + 1. https://github.com/WebAssembly/threads/issues/8 + 1. https://github.com/WebAssembly/threads/issues/95 + 1. https://github.com/WebAssembly/threads/issues/138 1. Discussion topic: `fd_seek` past the end of a file on Windows 1. https://github.com/WebAssembly/WASI/issues/292 1. Discussion topic: Symbolic links and Windows From 273870c686e377aadf80cb5207c0fe1d214e0143 Mon Sep 17 00:00:00 2001 From: David McKay Date: Fri, 17 Jul 2020 00:01:37 +0100 Subject: [PATCH 0693/1772] chore: update links to WebAssembly/threads issues (#301) --- proposals/filesystem/meetings/2020/WASI-07-16.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/meetings/2020/WASI-07-16.md b/proposals/filesystem/meetings/2020/WASI-07-16.md index 2ced1afd3..f4ba68088 100644 --- a/proposals/filesystem/meetings/2020/WASI-07-16.md +++ b/proposals/filesystem/meetings/2020/WASI-07-16.md @@ -31,9 +31,9 @@ Installation is required, see the calendar invite. 1. What kinds of tests should be in an official testsuite? 1. Where should we collect them? 1. Discussion topic: Threads - 1. WebAssembly/threads#8 - 1. WebAssembly/threads#95 - 1. WebAssembly/threads#138 + 1. https://github.com/WebAssembly/threads/issues/8 + 1. https://github.com/WebAssembly/threads/issues/95 + 1. https://github.com/WebAssembly/threads/issues/138 1. Discussion topic: `fd_seek` past the end of a file on Windows 1. https://github.com/WebAssembly/WASI/issues/292 1. Discussion topic: Symbolic links and Windows From 6c44d7fe80f5be6c48c2a6aa34785391aeba8ff8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 30 Jul 2020 00:39:45 -0700 Subject: [PATCH 0694/1772] Add an agenda for the 07-30 meeting. (#305) --- proposals/clocks/meetings/2020/WASI-07-30.md | 36 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 37 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-07-30.md diff --git a/proposals/clocks/meetings/2020/WASI-07-30.md b/proposals/clocks/meetings/2020/WASI-07-30.md new file mode 100644 index 000000000..1a164d624 --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-07-30.md @@ -0,0 +1,36 @@ +![WASI logo](/WASI.png) + +## Agenda for the July 30 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: July 30, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Documentation for WASI APIs + 1. https://github.com/WebAssembly/WASI/issues/292 + 1. WASI committee processes + 1. Proposal repos + 1. Further harmonizing the spec process with the core CG + 1. What work needs to be done, and who wants to do it? + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 7c1d8d4bb..6817410ca 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -36,3 +36,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI June 4th video call](2020/WASI-06-04.md) * [WASI July 2nd video call](2020/WASI-07-02.md) * [WASI July 16th video call](2020/WASI-07-16.md) + * [WASI July 30th video call](2020/WASI-07-30.md) From c9ca46b1966f3409438566dd9eb6fac5f4689176 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 30 Jul 2020 00:39:45 -0700 Subject: [PATCH 0695/1772] Add an agenda for the 07-30 meeting. (#305) --- proposals/random/meetings/2020/WASI-07-30.md | 36 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 37 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-07-30.md diff --git a/proposals/random/meetings/2020/WASI-07-30.md b/proposals/random/meetings/2020/WASI-07-30.md new file mode 100644 index 000000000..1a164d624 --- /dev/null +++ b/proposals/random/meetings/2020/WASI-07-30.md @@ -0,0 +1,36 @@ +![WASI logo](/WASI.png) + +## Agenda for the July 30 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: July 30, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Documentation for WASI APIs + 1. https://github.com/WebAssembly/WASI/issues/292 + 1. WASI committee processes + 1. Proposal repos + 1. Further harmonizing the spec process with the core CG + 1. What work needs to be done, and who wants to do it? + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 7c1d8d4bb..6817410ca 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -36,3 +36,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI June 4th video call](2020/WASI-06-04.md) * [WASI July 2nd video call](2020/WASI-07-02.md) * [WASI July 16th video call](2020/WASI-07-16.md) + * [WASI July 30th video call](2020/WASI-07-30.md) From 099ea23ff77bf53348eb06cd0bd5c4bd14143de0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 30 Jul 2020 00:39:45 -0700 Subject: [PATCH 0696/1772] Add an agenda for the 07-30 meeting. (#305) --- .../filesystem/meetings/2020/WASI-07-30.md | 36 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 37 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-07-30.md diff --git a/proposals/filesystem/meetings/2020/WASI-07-30.md b/proposals/filesystem/meetings/2020/WASI-07-30.md new file mode 100644 index 000000000..1a164d624 --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-07-30.md @@ -0,0 +1,36 @@ +![WASI logo](/WASI.png) + +## Agenda for the July 30 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: July 30, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: sunfish@mozilla.com + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Documentation for WASI APIs + 1. https://github.com/WebAssembly/WASI/issues/292 + 1. WASI committee processes + 1. Proposal repos + 1. Further harmonizing the spec process with the core CG + 1. What work needs to be done, and who wants to do it? + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 7c1d8d4bb..6817410ca 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -36,3 +36,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI June 4th video call](2020/WASI-06-04.md) * [WASI July 2nd video call](2020/WASI-07-02.md) * [WASI July 16th video call](2020/WASI-07-16.md) + * [WASI July 30th video call](2020/WASI-07-30.md) From b0a85d59cac45534535c54824d067b5dea160489 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Fri, 7 Aug 2020 10:20:02 -0700 Subject: [PATCH 0697/1772] Fix typo (#308) --- proposals/clocks/tools/witx/tests/wasi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/tools/witx/tests/wasi.rs b/proposals/clocks/tools/witx/tests/wasi.rs index 17f79341d..27300a26e 100644 --- a/proposals/clocks/tools/witx/tests/wasi.rs +++ b/proposals/clocks/tools/witx/tests/wasi.rs @@ -63,7 +63,7 @@ fn render_roundtrip() { } } } - // This should be equivelant to the above, but just in case some code changes where it isnt: + // This should be equivalent to the above, but just in case some code changes where it isnt: assert_eq!(doc, doc2); } From d00cf5d5c0d74ed2f57707d36100ad3f167db2c4 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Fri, 7 Aug 2020 10:20:02 -0700 Subject: [PATCH 0698/1772] Fix typo (#308) --- proposals/random/tools/witx/tests/wasi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/tools/witx/tests/wasi.rs b/proposals/random/tools/witx/tests/wasi.rs index 17f79341d..27300a26e 100644 --- a/proposals/random/tools/witx/tests/wasi.rs +++ b/proposals/random/tools/witx/tests/wasi.rs @@ -63,7 +63,7 @@ fn render_roundtrip() { } } } - // This should be equivelant to the above, but just in case some code changes where it isnt: + // This should be equivalent to the above, but just in case some code changes where it isnt: assert_eq!(doc, doc2); } From 08c946129be5ffe2be6e0be7644b2b6af18a0c87 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Fri, 7 Aug 2020 10:20:02 -0700 Subject: [PATCH 0699/1772] Fix typo (#308) --- proposals/filesystem/tools/witx/tests/wasi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/tools/witx/tests/wasi.rs b/proposals/filesystem/tools/witx/tests/wasi.rs index 17f79341d..27300a26e 100644 --- a/proposals/filesystem/tools/witx/tests/wasi.rs +++ b/proposals/filesystem/tools/witx/tests/wasi.rs @@ -63,7 +63,7 @@ fn render_roundtrip() { } } } - // This should be equivelant to the above, but just in case some code changes where it isnt: + // This should be equivalent to the above, but just in case some code changes where it isnt: assert_eq!(doc, doc2); } From 20cef5d8f91fa27fd8bedbff02f8c63831b82659 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 17 Aug 2020 15:44:10 -0700 Subject: [PATCH 0700/1772] latest wast in witx (#311) * witx: bump wast dependency to 22.0.0 * witx: bump crate version to 0.8.7 --- proposals/clocks/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 475541c4f..18502e901 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.6" +version = "0.8.7" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" @@ -17,7 +17,7 @@ crate-type=["rlib"] anyhow = "1" log = "0.4" thiserror = "1.0" -wast = { version = "20.0.0", default-features = false } +wast = { version = "22.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" From 0a0e283e332e2f8591f326a2b4b1b8c39e23ce33 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 17 Aug 2020 15:44:10 -0700 Subject: [PATCH 0701/1772] latest wast in witx (#311) * witx: bump wast dependency to 22.0.0 * witx: bump crate version to 0.8.7 --- proposals/random/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 475541c4f..18502e901 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.6" +version = "0.8.7" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" @@ -17,7 +17,7 @@ crate-type=["rlib"] anyhow = "1" log = "0.4" thiserror = "1.0" -wast = { version = "20.0.0", default-features = false } +wast = { version = "22.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" From c9afe7cce152d98483fa2d639e9cebc44b5559f9 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 17 Aug 2020 15:44:10 -0700 Subject: [PATCH 0702/1772] latest wast in witx (#311) * witx: bump wast dependency to 22.0.0 * witx: bump crate version to 0.8.7 --- proposals/filesystem/tools/witx/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 475541c4f..18502e901 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.6" +version = "0.8.7" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" @@ -17,7 +17,7 @@ crate-type=["rlib"] anyhow = "1" log = "0.4" thiserror = "1.0" -wast = { version = "20.0.0", default-features = false } +wast = { version = "22.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" From f2834a997c4aa52728eba9e4b7d8696f0d637d32 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 26 Aug 2020 10:14:34 -0700 Subject: [PATCH 0703/1772] Add an agenda for the 2020-08-27 meeting. (#314) --- proposals/clocks/meetings/2020/WASI-08-27.md | 42 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 43 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-08-27.md diff --git a/proposals/clocks/meetings/2020/WASI-08-27.md b/proposals/clocks/meetings/2020/WASI-08-27.md new file mode 100644 index 000000000..e5cbbef58 --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-08-27.md @@ -0,0 +1,42 @@ +![WASI logo](/WASI.png) + +## Agenda for the Aug 27 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: August 27, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. WASI Status + 1. Update from Dan + 1. WASI moving forward + 1. Sockets API + 1. https://github.com/WebAssembly/WASI/pull/312 + 1. API discussion + 1. Process discussion + 1. Testsuite + 1. https://github.com/WebAssembly/WASI/issues/9 + 1. https://github.com/khronosproject/wasi-test/ + 1. Should we work to make this an official testsuite? + 1. Where should it live? + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 6817410ca..6a1cdf09f 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -37,3 +37,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI July 2nd video call](2020/WASI-07-02.md) * [WASI July 16th video call](2020/WASI-07-16.md) * [WASI July 30th video call](2020/WASI-07-30.md) + * [WASI August 27th video call](2020/WASI-08-27.md) From 3e0b6e9835e2014745859809aee97e6b915126f7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 26 Aug 2020 10:14:34 -0700 Subject: [PATCH 0704/1772] Add an agenda for the 2020-08-27 meeting. (#314) --- proposals/random/meetings/2020/WASI-08-27.md | 42 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 43 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-08-27.md diff --git a/proposals/random/meetings/2020/WASI-08-27.md b/proposals/random/meetings/2020/WASI-08-27.md new file mode 100644 index 000000000..e5cbbef58 --- /dev/null +++ b/proposals/random/meetings/2020/WASI-08-27.md @@ -0,0 +1,42 @@ +![WASI logo](/WASI.png) + +## Agenda for the Aug 27 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: August 27, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. WASI Status + 1. Update from Dan + 1. WASI moving forward + 1. Sockets API + 1. https://github.com/WebAssembly/WASI/pull/312 + 1. API discussion + 1. Process discussion + 1. Testsuite + 1. https://github.com/WebAssembly/WASI/issues/9 + 1. https://github.com/khronosproject/wasi-test/ + 1. Should we work to make this an official testsuite? + 1. Where should it live? + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 6817410ca..6a1cdf09f 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -37,3 +37,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI July 2nd video call](2020/WASI-07-02.md) * [WASI July 16th video call](2020/WASI-07-16.md) * [WASI July 30th video call](2020/WASI-07-30.md) + * [WASI August 27th video call](2020/WASI-08-27.md) From b56433b1d13877f18e618239d73236f492373ce0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 26 Aug 2020 10:14:34 -0700 Subject: [PATCH 0705/1772] Add an agenda for the 2020-08-27 meeting. (#314) --- .../filesystem/meetings/2020/WASI-08-27.md | 42 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 43 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-08-27.md diff --git a/proposals/filesystem/meetings/2020/WASI-08-27.md b/proposals/filesystem/meetings/2020/WASI-08-27.md new file mode 100644 index 000000000..e5cbbef58 --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-08-27.md @@ -0,0 +1,42 @@ +![WASI logo](/WASI.png) + +## Agenda for the Aug 27 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: August 27, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. WASI Status + 1. Update from Dan + 1. WASI moving forward + 1. Sockets API + 1. https://github.com/WebAssembly/WASI/pull/312 + 1. API discussion + 1. Process discussion + 1. Testsuite + 1. https://github.com/WebAssembly/WASI/issues/9 + 1. https://github.com/khronosproject/wasi-test/ + 1. Should we work to make this an official testsuite? + 1. Where should it live? + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 6817410ca..6a1cdf09f 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -37,3 +37,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI July 2nd video call](2020/WASI-07-02.md) * [WASI July 16th video call](2020/WASI-07-16.md) * [WASI July 30th video call](2020/WASI-07-30.md) + * [WASI August 27th video call](2020/WASI-08-27.md) From 2a27203ce68866de563eb20e1e80fbd27d9c61c2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 9 Sep 2020 18:33:59 -0700 Subject: [PATCH 0706/1772] Add an agenda for the 2020-09-10 meeting. (#314) (#320) --- proposals/clocks/meetings/2020/WASI-09-10.md | 33 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 34 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-09-10.md diff --git a/proposals/clocks/meetings/2020/WASI-09-10.md b/proposals/clocks/meetings/2020/WASI-09-10.md new file mode 100644 index 000000000..feacffd1e --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-09-10.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the September 10 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: September 10, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Sockets API + 1. https://github.com/WebAssembly/WASI/pull/312 + 1. API discussion + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 6a1cdf09f..70ff24e9e 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -38,3 +38,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI July 16th video call](2020/WASI-07-16.md) * [WASI July 30th video call](2020/WASI-07-30.md) * [WASI August 27th video call](2020/WASI-08-27.md) + * [WASI September 10th video call](2020/WASI-09-10.md) From bb64c26eeb86eb941d075c4f0e415c9740b4f132 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 9 Sep 2020 18:33:59 -0700 Subject: [PATCH 0707/1772] Add an agenda for the 2020-09-10 meeting. (#314) (#320) --- proposals/random/meetings/2020/WASI-09-10.md | 33 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 34 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-09-10.md diff --git a/proposals/random/meetings/2020/WASI-09-10.md b/proposals/random/meetings/2020/WASI-09-10.md new file mode 100644 index 000000000..feacffd1e --- /dev/null +++ b/proposals/random/meetings/2020/WASI-09-10.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the September 10 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: September 10, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Sockets API + 1. https://github.com/WebAssembly/WASI/pull/312 + 1. API discussion + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 6a1cdf09f..70ff24e9e 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -38,3 +38,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI July 16th video call](2020/WASI-07-16.md) * [WASI July 30th video call](2020/WASI-07-30.md) * [WASI August 27th video call](2020/WASI-08-27.md) + * [WASI September 10th video call](2020/WASI-09-10.md) From 821afbf7e67c99cf99d7c26c8d4320f11966f3de Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 9 Sep 2020 18:33:59 -0700 Subject: [PATCH 0708/1772] Add an agenda for the 2020-09-10 meeting. (#314) (#320) --- .../filesystem/meetings/2020/WASI-09-10.md | 33 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 34 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-09-10.md diff --git a/proposals/filesystem/meetings/2020/WASI-09-10.md b/proposals/filesystem/meetings/2020/WASI-09-10.md new file mode 100644 index 000000000..feacffd1e --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-09-10.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the September 10 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: September 10, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Proposals and discussions + 1. Sockets API + 1. https://github.com/WebAssembly/WASI/pull/312 + 1. API discussion + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 6a1cdf09f..70ff24e9e 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -38,3 +38,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI July 16th video call](2020/WASI-07-16.md) * [WASI July 30th video call](2020/WASI-07-30.md) * [WASI August 27th video call](2020/WASI-08-27.md) + * [WASI September 10th video call](2020/WASI-09-10.md) From adf6c6701e94606dba13adf359087dddf2c926a1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 21 Sep 2020 14:16:58 -0700 Subject: [PATCH 0709/1772] Add an agenda for the 09-24 meeting. (#321) --- proposals/clocks/meetings/2020/WASI-09-24.md | 30 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 31 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-09-24.md diff --git a/proposals/clocks/meetings/2020/WASI-09-24.md b/proposals/clocks/meetings/2020/WASI-09-24.md new file mode 100644 index 000000000..dd3127e8f --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-09-24.md @@ -0,0 +1,30 @@ +![WASI logo](/WASI.png) + +## Agenda for the September 24 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: September 24, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Add items here! + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 70ff24e9e..2f2ec893e 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -39,3 +39,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI July 30th video call](2020/WASI-07-30.md) * [WASI August 27th video call](2020/WASI-08-27.md) * [WASI September 10th video call](2020/WASI-09-10.md) + * [WASI September 21st video call](2020/WASI-09-21.md) From 3b74adcab3e1c2dca16710d53fbbbd64b2326a62 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 21 Sep 2020 14:16:58 -0700 Subject: [PATCH 0710/1772] Add an agenda for the 09-24 meeting. (#321) --- proposals/random/meetings/2020/WASI-09-24.md | 30 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 31 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-09-24.md diff --git a/proposals/random/meetings/2020/WASI-09-24.md b/proposals/random/meetings/2020/WASI-09-24.md new file mode 100644 index 000000000..dd3127e8f --- /dev/null +++ b/proposals/random/meetings/2020/WASI-09-24.md @@ -0,0 +1,30 @@ +![WASI logo](/WASI.png) + +## Agenda for the September 24 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: September 24, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Add items here! + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 70ff24e9e..2f2ec893e 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -39,3 +39,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI July 30th video call](2020/WASI-07-30.md) * [WASI August 27th video call](2020/WASI-08-27.md) * [WASI September 10th video call](2020/WASI-09-10.md) + * [WASI September 21st video call](2020/WASI-09-21.md) From 2b9568e09f4f139bac7995ac04ba627afdc2ef0f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 21 Sep 2020 14:16:58 -0700 Subject: [PATCH 0711/1772] Add an agenda for the 09-24 meeting. (#321) --- .../filesystem/meetings/2020/WASI-09-24.md | 30 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 31 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-09-24.md diff --git a/proposals/filesystem/meetings/2020/WASI-09-24.md b/proposals/filesystem/meetings/2020/WASI-09-24.md new file mode 100644 index 000000000..dd3127e8f --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-09-24.md @@ -0,0 +1,30 @@ +![WASI logo](/WASI.png) + +## Agenda for the September 24 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: September 24, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Add items here! + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 70ff24e9e..2f2ec893e 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -39,3 +39,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI July 30th video call](2020/WASI-07-30.md) * [WASI August 27th video call](2020/WASI-08-27.md) * [WASI September 10th video call](2020/WASI-09-10.md) + * [WASI September 21st video call](2020/WASI-09-21.md) From 7a738c8ac555a77080b29df0cf30d5501c53e448 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 5 Oct 2020 10:29:21 -0700 Subject: [PATCH 0712/1772] Add an agenda for the 10-08 meeting. (#324) --- proposals/clocks/meetings/2020/WASI-10-08.md | 30 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 31 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-10-08.md diff --git a/proposals/clocks/meetings/2020/WASI-10-08.md b/proposals/clocks/meetings/2020/WASI-10-08.md new file mode 100644 index 000000000..21691af24 --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-10-08.md @@ -0,0 +1,30 @@ +![WASI logo](/WASI.png) + +## Agenda for the October 8 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: October 8, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Add items here! + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 2f2ec893e..3e326e3a6 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -40,3 +40,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI August 27th video call](2020/WASI-08-27.md) * [WASI September 10th video call](2020/WASI-09-10.md) * [WASI September 21st video call](2020/WASI-09-21.md) + * [WASI October 8th video call](2020/WASI-10-08.md) From 86c3dbd213c2d64fbc0e19d3cecb6f6ccf7eb117 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 5 Oct 2020 10:29:21 -0700 Subject: [PATCH 0713/1772] Add an agenda for the 10-08 meeting. (#324) --- proposals/random/meetings/2020/WASI-10-08.md | 30 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 31 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-10-08.md diff --git a/proposals/random/meetings/2020/WASI-10-08.md b/proposals/random/meetings/2020/WASI-10-08.md new file mode 100644 index 000000000..21691af24 --- /dev/null +++ b/proposals/random/meetings/2020/WASI-10-08.md @@ -0,0 +1,30 @@ +![WASI logo](/WASI.png) + +## Agenda for the October 8 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: October 8, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Add items here! + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 2f2ec893e..3e326e3a6 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -40,3 +40,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI August 27th video call](2020/WASI-08-27.md) * [WASI September 10th video call](2020/WASI-09-10.md) * [WASI September 21st video call](2020/WASI-09-21.md) + * [WASI October 8th video call](2020/WASI-10-08.md) From 89b69adc73939616683daaf1b35ea0a94ef583d3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 5 Oct 2020 10:29:21 -0700 Subject: [PATCH 0714/1772] Add an agenda for the 10-08 meeting. (#324) --- .../filesystem/meetings/2020/WASI-10-08.md | 30 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 31 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-10-08.md diff --git a/proposals/filesystem/meetings/2020/WASI-10-08.md b/proposals/filesystem/meetings/2020/WASI-10-08.md new file mode 100644 index 000000000..21691af24 --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-10-08.md @@ -0,0 +1,30 @@ +![WASI logo](/WASI.png) + +## Agenda for the October 8 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: October 8, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Add items here! + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 2f2ec893e..3e326e3a6 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -40,3 +40,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI August 27th video call](2020/WASI-08-27.md) * [WASI September 10th video call](2020/WASI-09-10.md) * [WASI September 21st video call](2020/WASI-09-21.md) + * [WASI October 8th video call](2020/WASI-10-08.md) From 87b525e4bf1da87816ea5c558953e449338aa4d7 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 5 Oct 2020 13:31:01 -0700 Subject: [PATCH 0715/1772] CI: use $GITHUB_PATH rather than add-path In accordance with this advisory it's recommended we move to a different scheme of setting env vars and updating PATH: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/ --- proposals/clocks/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 5fc77d880..138782c2c 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -17,7 +17,7 @@ jobs: - name: Install Rust (macos) run: | curl https://sh.rustup.rs | sh -s -- -y - echo "##[add-path]$HOME/.cargo/bin" + echo "$HOME/.cargo/bin" >> $GITHUB_PATH if: matrix.os == 'macos-latest' - run: cargo fetch working-directory: tools/witx From 55998aa06f83a891de917ee8f3b25cd45b71f411 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 5 Oct 2020 13:31:01 -0700 Subject: [PATCH 0716/1772] CI: use $GITHUB_PATH rather than add-path In accordance with this advisory it's recommended we move to a different scheme of setting env vars and updating PATH: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/ --- proposals/random/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index 5fc77d880..138782c2c 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -17,7 +17,7 @@ jobs: - name: Install Rust (macos) run: | curl https://sh.rustup.rs | sh -s -- -y - echo "##[add-path]$HOME/.cargo/bin" + echo "$HOME/.cargo/bin" >> $GITHUB_PATH if: matrix.os == 'macos-latest' - run: cargo fetch working-directory: tools/witx From e98c59382ae046e1c3e4c1039270111f74bfe993 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 5 Oct 2020 13:31:01 -0700 Subject: [PATCH 0717/1772] CI: use $GITHUB_PATH rather than add-path In accordance with this advisory it's recommended we move to a different scheme of setting env vars and updating PATH: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/ --- proposals/filesystem/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index 5fc77d880..138782c2c 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -17,7 +17,7 @@ jobs: - name: Install Rust (macos) run: | curl https://sh.rustup.rs | sh -s -- -y - echo "##[add-path]$HOME/.cargo/bin" + echo "$HOME/.cargo/bin" >> $GITHUB_PATH if: matrix.os == 'macos-latest' - run: cargo fetch working-directory: tools/witx From 6ce14c0613bd0292ba0674d7b0075d218c1701e2 Mon Sep 17 00:00:00 2001 From: Andrew Mackenzie Date: Sat, 5 Sep 2020 21:22:55 +0200 Subject: [PATCH 0718/1772] Remove reference to non existent modules.md file --- proposals/clocks/design/application-abi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/design/application-abi.md b/proposals/clocks/design/application-abi.md index 8fc85da32..0ef259a51 100644 --- a/proposals/clocks/design/application-abi.md +++ b/proposals/clocks/design/application-abi.md @@ -1,7 +1,7 @@ WASI Application ABI ==================== -In addition to the APIs defined by the various WASI [modules](modules.md) there +In addition to the APIs defined by the various WASI modules there are also certain expectations that the WASI runtime places on an application that wishes to be portable across WASI implementations. From 320bc0ee8b36ebd2f6df320ffaa315ed8aca4474 Mon Sep 17 00:00:00 2001 From: Andrew Mackenzie Date: Sat, 5 Sep 2020 21:22:55 +0200 Subject: [PATCH 0719/1772] Remove reference to non existent modules.md file --- proposals/random/design/application-abi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/design/application-abi.md b/proposals/random/design/application-abi.md index 8fc85da32..0ef259a51 100644 --- a/proposals/random/design/application-abi.md +++ b/proposals/random/design/application-abi.md @@ -1,7 +1,7 @@ WASI Application ABI ==================== -In addition to the APIs defined by the various WASI [modules](modules.md) there +In addition to the APIs defined by the various WASI modules there are also certain expectations that the WASI runtime places on an application that wishes to be portable across WASI implementations. From 7a77b4697f72c9875abc9d3c1f5575cbf379e875 Mon Sep 17 00:00:00 2001 From: Andrew Mackenzie Date: Sat, 5 Sep 2020 21:22:55 +0200 Subject: [PATCH 0720/1772] Remove reference to non existent modules.md file --- proposals/filesystem/design/application-abi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/design/application-abi.md b/proposals/filesystem/design/application-abi.md index 8fc85da32..0ef259a51 100644 --- a/proposals/filesystem/design/application-abi.md +++ b/proposals/filesystem/design/application-abi.md @@ -1,7 +1,7 @@ WASI Application ABI ==================== -In addition to the APIs defined by the various WASI [modules](modules.md) there +In addition to the APIs defined by the various WASI modules there are also certain expectations that the WASI runtime places on an application that wishes to be portable across WASI implementations. From 4c408a12f0c3f517e20fc0d409c84effa6c7514e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 7 Oct 2020 14:46:50 -0700 Subject: [PATCH 0721/1772] Add several meeting agenda items. --- proposals/clocks/meetings/2020/WASI-10-08.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/proposals/clocks/meetings/2020/WASI-10-08.md b/proposals/clocks/meetings/2020/WASI-10-08.md index 21691af24..78d943918 100644 --- a/proposals/clocks/meetings/2020/WASI-10-08.md +++ b/proposals/clocks/meetings/2020/WASI-10-08.md @@ -26,5 +26,17 @@ Installation is required, see the calendar invite. 1. Please help take notes. 1. Thanks! 1. Add items here! + 1. wasi-sdk update waiting for LLVM 11.0 release + 1. https://llvm.org/ + 1. Interface Types update: + 1. https://github.com/WebAssembly/interface-types/pull/122 + 1. WASI is being mentioned a lot in the GC repo: + 1. eg. https://github.com/WebAssembly/gc/issues/143 + 1. WASI testsuite + 1. https://github.com/WebAssembly/WASI/issues/9 + 1. What do we want to build towards? + 1. WASI sockets + 1. https://github.com/WebAssembly/WASI/pull/312 + 1. Merge soon, and iterate? ## Meeting Notes From b4b80ca944f7b527bddf3fc6dace57356f0e3b5d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 7 Oct 2020 14:46:50 -0700 Subject: [PATCH 0722/1772] Add several meeting agenda items. --- proposals/random/meetings/2020/WASI-10-08.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/proposals/random/meetings/2020/WASI-10-08.md b/proposals/random/meetings/2020/WASI-10-08.md index 21691af24..78d943918 100644 --- a/proposals/random/meetings/2020/WASI-10-08.md +++ b/proposals/random/meetings/2020/WASI-10-08.md @@ -26,5 +26,17 @@ Installation is required, see the calendar invite. 1. Please help take notes. 1. Thanks! 1. Add items here! + 1. wasi-sdk update waiting for LLVM 11.0 release + 1. https://llvm.org/ + 1. Interface Types update: + 1. https://github.com/WebAssembly/interface-types/pull/122 + 1. WASI is being mentioned a lot in the GC repo: + 1. eg. https://github.com/WebAssembly/gc/issues/143 + 1. WASI testsuite + 1. https://github.com/WebAssembly/WASI/issues/9 + 1. What do we want to build towards? + 1. WASI sockets + 1. https://github.com/WebAssembly/WASI/pull/312 + 1. Merge soon, and iterate? ## Meeting Notes From 8b142a11340b62963e9520da2271c4a190bbb932 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 7 Oct 2020 14:46:50 -0700 Subject: [PATCH 0723/1772] Add several meeting agenda items. --- proposals/filesystem/meetings/2020/WASI-10-08.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/proposals/filesystem/meetings/2020/WASI-10-08.md b/proposals/filesystem/meetings/2020/WASI-10-08.md index 21691af24..78d943918 100644 --- a/proposals/filesystem/meetings/2020/WASI-10-08.md +++ b/proposals/filesystem/meetings/2020/WASI-10-08.md @@ -26,5 +26,17 @@ Installation is required, see the calendar invite. 1. Please help take notes. 1. Thanks! 1. Add items here! + 1. wasi-sdk update waiting for LLVM 11.0 release + 1. https://llvm.org/ + 1. Interface Types update: + 1. https://github.com/WebAssembly/interface-types/pull/122 + 1. WASI is being mentioned a lot in the GC repo: + 1. eg. https://github.com/WebAssembly/gc/issues/143 + 1. WASI testsuite + 1. https://github.com/WebAssembly/WASI/issues/9 + 1. What do we want to build towards? + 1. WASI sockets + 1. https://github.com/WebAssembly/WASI/pull/312 + 1. Merge soon, and iterate? ## Meeting Notes From 133fa5c04a7e8fe46495316dcb8e0858ff18a67a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 8 Oct 2020 17:04:33 -0700 Subject: [PATCH 0724/1772] Add an agenda for the 10-22 meeting. --- proposals/clocks/meetings/2020/WASI-10-22.md | 30 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 31 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-10-22.md diff --git a/proposals/clocks/meetings/2020/WASI-10-22.md b/proposals/clocks/meetings/2020/WASI-10-22.md new file mode 100644 index 000000000..e8011f2ee --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-10-22.md @@ -0,0 +1,30 @@ +![WASI logo](/WASI.png) + +## Agenda for the October 22 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: October 22, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Add items here! + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 3e326e3a6..3b4adaabe 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -41,3 +41,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI September 10th video call](2020/WASI-09-10.md) * [WASI September 21st video call](2020/WASI-09-21.md) * [WASI October 8th video call](2020/WASI-10-08.md) + * [WASI October 22nd video call](2020/WASI-10-22.md) From 3c933b2a8579ecd7187c7abf4847983bea298d1c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 8 Oct 2020 17:04:33 -0700 Subject: [PATCH 0725/1772] Add an agenda for the 10-22 meeting. --- proposals/random/meetings/2020/WASI-10-22.md | 30 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 31 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-10-22.md diff --git a/proposals/random/meetings/2020/WASI-10-22.md b/proposals/random/meetings/2020/WASI-10-22.md new file mode 100644 index 000000000..e8011f2ee --- /dev/null +++ b/proposals/random/meetings/2020/WASI-10-22.md @@ -0,0 +1,30 @@ +![WASI logo](/WASI.png) + +## Agenda for the October 22 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: October 22, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Add items here! + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 3e326e3a6..3b4adaabe 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -41,3 +41,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI September 10th video call](2020/WASI-09-10.md) * [WASI September 21st video call](2020/WASI-09-21.md) * [WASI October 8th video call](2020/WASI-10-08.md) + * [WASI October 22nd video call](2020/WASI-10-22.md) From 56b978a85e7f1606410227bf9ce9e03a4a9d5c0b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 8 Oct 2020 17:04:33 -0700 Subject: [PATCH 0726/1772] Add an agenda for the 10-22 meeting. --- .../filesystem/meetings/2020/WASI-10-22.md | 30 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 31 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-10-22.md diff --git a/proposals/filesystem/meetings/2020/WASI-10-22.md b/proposals/filesystem/meetings/2020/WASI-10-22.md new file mode 100644 index 000000000..e8011f2ee --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-10-22.md @@ -0,0 +1,30 @@ +![WASI logo](/WASI.png) + +## Agenda for the October 22 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: October 22, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Add items here! + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 3e326e3a6..3b4adaabe 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -41,3 +41,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI September 10th video call](2020/WASI-09-10.md) * [WASI September 21st video call](2020/WASI-09-21.md) * [WASI October 8th video call](2020/WASI-10-08.md) + * [WASI October 22nd video call](2020/WASI-10-22.md) From d05cc44d05719ccc78f0a8d2eb7f45efc4933738 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Fri, 9 Oct 2020 13:12:32 -0700 Subject: [PATCH 0727/1772] Update WASI-10-22.md --- proposals/clocks/meetings/2020/WASI-10-22.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/meetings/2020/WASI-10-22.md b/proposals/clocks/meetings/2020/WASI-10-22.md index e8011f2ee..60f9b44a8 100644 --- a/proposals/clocks/meetings/2020/WASI-10-22.md +++ b/proposals/clocks/meetings/2020/WASI-10-22.md @@ -25,6 +25,6 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! -1. Add items here! +1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). ## Meeting Notes From 16a53a13284b8e157504794dd5f2f762b1e4894d Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Fri, 9 Oct 2020 13:12:32 -0700 Subject: [PATCH 0728/1772] Update WASI-10-22.md --- proposals/random/meetings/2020/WASI-10-22.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/meetings/2020/WASI-10-22.md b/proposals/random/meetings/2020/WASI-10-22.md index e8011f2ee..60f9b44a8 100644 --- a/proposals/random/meetings/2020/WASI-10-22.md +++ b/proposals/random/meetings/2020/WASI-10-22.md @@ -25,6 +25,6 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! -1. Add items here! +1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). ## Meeting Notes From 33acd631a26d2ac66eb23b97e20bdd9e8fde8de3 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Fri, 9 Oct 2020 13:12:32 -0700 Subject: [PATCH 0729/1772] Update WASI-10-22.md --- proposals/filesystem/meetings/2020/WASI-10-22.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/meetings/2020/WASI-10-22.md b/proposals/filesystem/meetings/2020/WASI-10-22.md index e8011f2ee..60f9b44a8 100644 --- a/proposals/filesystem/meetings/2020/WASI-10-22.md +++ b/proposals/filesystem/meetings/2020/WASI-10-22.md @@ -25,6 +25,6 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! -1. Add items here! +1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). ## Meeting Notes From 6a57c6566fd896f74b3f49c4fdb224d453023324 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 10 Oct 2020 22:50:35 -0400 Subject: [PATCH 0730/1772] Fix typo in open param name --- proposals/clocks/phases/ephemeral/docs.md | 4 ++-- .../clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx | 2 +- proposals/clocks/phases/old/snapshot_0/docs.md | 4 ++-- .../clocks/phases/old/snapshot_0/witx/wasi_unstable.witx | 2 +- proposals/clocks/phases/snapshot/docs.md | 4 ++-- .../clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index f17e9aa9f..93416c8eb 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -1766,7 +1766,7 @@ The destination path at which to create the hard link. --- -#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags, permissions: permissions) -> (errno, fd)` +#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, permissions: permissions) -> (errno, fd)` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1797,7 +1797,7 @@ The *base* rights are rights that will apply to operations using the file descriptor itself, while the *inheriting* rights are rights that apply to file descriptors derived from it. -- `fs_rights_inherting`: [`rights`](#rights) +- `fs_rights_inheriting`: [`rights`](#rights) - `fdflags`: [`fdflags`](#fdflags) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx index 086637c96..971a6fc9f 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -115,7 +115,7 @@ ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. (param $fs_rights_base $rights) - (param $fs_rights_inherting $rights) + (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) ;;; If a file is created, the filesystem permissions to associate with it. (param $permissions $permissions) diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index 1b2100580..34eab3c03 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -1752,7 +1752,7 @@ The destination path at which to create the hard link. --- -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)` +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> (errno, fd)` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1783,7 +1783,7 @@ The *base* rights are rights that will apply to operations using the file descriptor itself, while the *inheriting* rights are rights that apply to file descriptors derived from it. -- `fs_rights_inherting`: [`rights`](#rights) +- `fs_rights_inheriting`: [`rights`](#rights) - `fdflags`: [`fdflags`](#fdflags) diff --git a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx index 697e3ba88..a6d352848 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -380,7 +380,7 @@ ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. (param $fs_rights_base $rights) - (param $fs_rights_inherting $rights) + (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) (result $error $errno) ;;; The file descriptor of the file that has been opened. diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index 640943f84..b56e8c533 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -1749,7 +1749,7 @@ The destination path at which to create the hard link. --- -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)` +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> (errno, fd)` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1780,7 +1780,7 @@ The *base* rights are rights that will apply to operations using the file descriptor itself, while the *inheriting* rights are rights that apply to file descriptors derived from it. -- `fs_rights_inherting`: [`rights`](#rights) +- `fs_rights_inheriting`: [`rights`](#rights) - `fdflags`: [`fdflags`](#fdflags) diff --git a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx index 5604c3e68..47dd44910 100644 --- a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -377,7 +377,7 @@ ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. (param $fs_rights_base $rights) - (param $fs_rights_inherting $rights) + (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) (result $error $errno) ;;; The file descriptor of the file that has been opened. From 83e25ad1d64b6fb03bf8ea64aca559210f8a5276 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 10 Oct 2020 22:50:35 -0400 Subject: [PATCH 0731/1772] Fix typo in open param name --- proposals/random/phases/ephemeral/docs.md | 4 ++-- .../random/phases/ephemeral/witx/wasi_ephemeral_path.witx | 2 +- proposals/random/phases/old/snapshot_0/docs.md | 4 ++-- .../random/phases/old/snapshot_0/witx/wasi_unstable.witx | 2 +- proposals/random/phases/snapshot/docs.md | 4 ++-- .../random/phases/snapshot/witx/wasi_snapshot_preview1.witx | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index f17e9aa9f..93416c8eb 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -1766,7 +1766,7 @@ The destination path at which to create the hard link. --- -#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags, permissions: permissions) -> (errno, fd)` +#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, permissions: permissions) -> (errno, fd)` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1797,7 +1797,7 @@ The *base* rights are rights that will apply to operations using the file descriptor itself, while the *inheriting* rights are rights that apply to file descriptors derived from it. -- `fs_rights_inherting`: [`rights`](#rights) +- `fs_rights_inheriting`: [`rights`](#rights) - `fdflags`: [`fdflags`](#fdflags) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx index 086637c96..971a6fc9f 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -115,7 +115,7 @@ ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. (param $fs_rights_base $rights) - (param $fs_rights_inherting $rights) + (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) ;;; If a file is created, the filesystem permissions to associate with it. (param $permissions $permissions) diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index 1b2100580..34eab3c03 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -1752,7 +1752,7 @@ The destination path at which to create the hard link. --- -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)` +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> (errno, fd)` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1783,7 +1783,7 @@ The *base* rights are rights that will apply to operations using the file descriptor itself, while the *inheriting* rights are rights that apply to file descriptors derived from it. -- `fs_rights_inherting`: [`rights`](#rights) +- `fs_rights_inheriting`: [`rights`](#rights) - `fdflags`: [`fdflags`](#fdflags) diff --git a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx index 697e3ba88..a6d352848 100644 --- a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -380,7 +380,7 @@ ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. (param $fs_rights_base $rights) - (param $fs_rights_inherting $rights) + (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) (result $error $errno) ;;; The file descriptor of the file that has been opened. diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index 640943f84..b56e8c533 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -1749,7 +1749,7 @@ The destination path at which to create the hard link. --- -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)` +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> (errno, fd)` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1780,7 +1780,7 @@ The *base* rights are rights that will apply to operations using the file descriptor itself, while the *inheriting* rights are rights that apply to file descriptors derived from it. -- `fs_rights_inherting`: [`rights`](#rights) +- `fs_rights_inheriting`: [`rights`](#rights) - `fdflags`: [`fdflags`](#fdflags) diff --git a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx index 5604c3e68..47dd44910 100644 --- a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -377,7 +377,7 @@ ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. (param $fs_rights_base $rights) - (param $fs_rights_inherting $rights) + (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) (result $error $errno) ;;; The file descriptor of the file that has been opened. From d7030c861d03f572f0b51d23765ffab11f643340 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 10 Oct 2020 22:50:35 -0400 Subject: [PATCH 0732/1772] Fix typo in open param name --- proposals/filesystem/phases/ephemeral/docs.md | 4 ++-- .../filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx | 2 +- proposals/filesystem/phases/old/snapshot_0/docs.md | 4 ++-- .../filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx | 2 +- proposals/filesystem/phases/snapshot/docs.md | 4 ++-- .../phases/snapshot/witx/wasi_snapshot_preview1.witx | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index f17e9aa9f..93416c8eb 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -1766,7 +1766,7 @@ The destination path at which to create the hard link. --- -#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags, permissions: permissions) -> (errno, fd)` +#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, permissions: permissions) -> (errno, fd)` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1797,7 +1797,7 @@ The *base* rights are rights that will apply to operations using the file descriptor itself, while the *inheriting* rights are rights that apply to file descriptors derived from it. -- `fs_rights_inherting`: [`rights`](#rights) +- `fs_rights_inheriting`: [`rights`](#rights) - `fdflags`: [`fdflags`](#fdflags) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx index 086637c96..971a6fc9f 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -115,7 +115,7 @@ ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. (param $fs_rights_base $rights) - (param $fs_rights_inherting $rights) + (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) ;;; If a file is created, the filesystem permissions to associate with it. (param $permissions $permissions) diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index 1b2100580..34eab3c03 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -1752,7 +1752,7 @@ The destination path at which to create the hard link. --- -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)` +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> (errno, fd)` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1783,7 +1783,7 @@ The *base* rights are rights that will apply to operations using the file descriptor itself, while the *inheriting* rights are rights that apply to file descriptors derived from it. -- `fs_rights_inherting`: [`rights`](#rights) +- `fs_rights_inheriting`: [`rights`](#rights) - `fdflags`: [`fdflags`](#fdflags) diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx index 697e3ba88..a6d352848 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -380,7 +380,7 @@ ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. (param $fs_rights_base $rights) - (param $fs_rights_inherting $rights) + (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) (result $error $errno) ;;; The file descriptor of the file that has been opened. diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index 640943f84..b56e8c533 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -1749,7 +1749,7 @@ The destination path at which to create the hard link. --- -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)` +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> (errno, fd)` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1780,7 +1780,7 @@ The *base* rights are rights that will apply to operations using the file descriptor itself, while the *inheriting* rights are rights that apply to file descriptors derived from it. -- `fs_rights_inherting`: [`rights`](#rights) +- `fs_rights_inheriting`: [`rights`](#rights) - `fdflags`: [`fdflags`](#fdflags) diff --git a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx index 5604c3e68..47dd44910 100644 --- a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -377,7 +377,7 @@ ;;; descriptor itself, while the *inheriting* rights are rights that apply to ;;; file descriptors derived from it. (param $fs_rights_base $rights) - (param $fs_rights_inherting $rights) + (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) (result $error $errno) ;;; The file descriptor of the file that has been opened. From b698b69a44a94feebfdfcdd2a245f00bb5e66aec Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 8 Oct 2020 12:17:23 -0700 Subject: [PATCH 0733/1772] Fix links for existing proposals This fixes the Markdown links so at least they display correctly. However, there are several link issues: - https://github.com/WebAssembly/wasi-misc does not exist - https://github.com/WebAssembly/wasi-io does not exist - https://github.com/WebAssembly/wasi-classic-command may not be the correct link for wasi-command-line - https://github.com/proxy-wasm/spec is the correct link for this project but is not a repo containing WITX --- proposals/clocks/docs/Proposals.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/proposals/clocks/docs/Proposals.md b/proposals/clocks/docs/Proposals.md index 5ba7fefd3..439de08fa 100644 --- a/proposals/clocks/docs/Proposals.md +++ b/proposals/clocks/docs/Proposals.md @@ -49,11 +49,11 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. -[wasi-io]: https://github.com/WebAssembly/WASI/phases -[filesystem]: https://github.com/WebAssembly/WASI/phases -[wasi-command-line]: https://github.com/WebAssembly/WASI/phases -[clocks]: https://github.com/WebAssembly/WASI/phases -[random]: https://github.com/WebAssembly/WASI/phases -[misc]: https://github.com/WebAssembly/WASI/phases -[wasi-crypto]: https://github.com/WebAssembly/WASI-crypto -[wasi-proxy-wasm]: https://github.com/WebAssembly/WASI +[wasi-io]: https://github.com/WebAssembly/wasi-io +[wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem +[wasi-command-line]: https://github.com/WebAssembly/wasi-classic-command +[wasi-clocks]: https://github.com/WebAssembly/wasi-clocks +[wasi-random]: https://github.com/WebAssembly/wasi-random +[wasi-misc]: https://github.com/WebAssembly/wasi-misc +[wasi-crypto]: https://github.com/WebAssembly/wasi-crypto +[wasi-proxy-wasm]: https://github.com/proxy-wasm/spec From 7e8861faf9ed3475f83c90a51aa8aaff74972276 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 8 Oct 2020 12:17:23 -0700 Subject: [PATCH 0734/1772] Fix links for existing proposals This fixes the Markdown links so at least they display correctly. However, there are several link issues: - https://github.com/WebAssembly/wasi-misc does not exist - https://github.com/WebAssembly/wasi-io does not exist - https://github.com/WebAssembly/wasi-classic-command may not be the correct link for wasi-command-line - https://github.com/proxy-wasm/spec is the correct link for this project but is not a repo containing WITX --- proposals/random/docs/Proposals.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/proposals/random/docs/Proposals.md b/proposals/random/docs/Proposals.md index 5ba7fefd3..439de08fa 100644 --- a/proposals/random/docs/Proposals.md +++ b/proposals/random/docs/Proposals.md @@ -49,11 +49,11 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. -[wasi-io]: https://github.com/WebAssembly/WASI/phases -[filesystem]: https://github.com/WebAssembly/WASI/phases -[wasi-command-line]: https://github.com/WebAssembly/WASI/phases -[clocks]: https://github.com/WebAssembly/WASI/phases -[random]: https://github.com/WebAssembly/WASI/phases -[misc]: https://github.com/WebAssembly/WASI/phases -[wasi-crypto]: https://github.com/WebAssembly/WASI-crypto -[wasi-proxy-wasm]: https://github.com/WebAssembly/WASI +[wasi-io]: https://github.com/WebAssembly/wasi-io +[wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem +[wasi-command-line]: https://github.com/WebAssembly/wasi-classic-command +[wasi-clocks]: https://github.com/WebAssembly/wasi-clocks +[wasi-random]: https://github.com/WebAssembly/wasi-random +[wasi-misc]: https://github.com/WebAssembly/wasi-misc +[wasi-crypto]: https://github.com/WebAssembly/wasi-crypto +[wasi-proxy-wasm]: https://github.com/proxy-wasm/spec From 55b700ade9e4135287127f36be3598389df4cfd1 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 8 Oct 2020 12:17:23 -0700 Subject: [PATCH 0735/1772] Fix links for existing proposals This fixes the Markdown links so at least they display correctly. However, there are several link issues: - https://github.com/WebAssembly/wasi-misc does not exist - https://github.com/WebAssembly/wasi-io does not exist - https://github.com/WebAssembly/wasi-classic-command may not be the correct link for wasi-command-line - https://github.com/proxy-wasm/spec is the correct link for this project but is not a repo containing WITX --- proposals/filesystem/docs/Proposals.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/proposals/filesystem/docs/Proposals.md b/proposals/filesystem/docs/Proposals.md index 5ba7fefd3..439de08fa 100644 --- a/proposals/filesystem/docs/Proposals.md +++ b/proposals/filesystem/docs/Proposals.md @@ -49,11 +49,11 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. -[wasi-io]: https://github.com/WebAssembly/WASI/phases -[filesystem]: https://github.com/WebAssembly/WASI/phases -[wasi-command-line]: https://github.com/WebAssembly/WASI/phases -[clocks]: https://github.com/WebAssembly/WASI/phases -[random]: https://github.com/WebAssembly/WASI/phases -[misc]: https://github.com/WebAssembly/WASI/phases -[wasi-crypto]: https://github.com/WebAssembly/WASI-crypto -[wasi-proxy-wasm]: https://github.com/WebAssembly/WASI +[wasi-io]: https://github.com/WebAssembly/wasi-io +[wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem +[wasi-command-line]: https://github.com/WebAssembly/wasi-classic-command +[wasi-clocks]: https://github.com/WebAssembly/wasi-clocks +[wasi-random]: https://github.com/WebAssembly/wasi-random +[wasi-misc]: https://github.com/WebAssembly/wasi-misc +[wasi-crypto]: https://github.com/WebAssembly/wasi-crypto +[wasi-proxy-wasm]: https://github.com/proxy-wasm/spec From e4f1392e22b40ac1d7a3e3d3793294a1c2b4fe1c Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 8 Oct 2020 12:21:06 -0700 Subject: [PATCH 0736/1772] Add wasi-nn proposal --- proposals/clocks/docs/Proposals.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/clocks/docs/Proposals.md b/proposals/clocks/docs/Proposals.md index 439de08fa..011a53eb8 100644 --- a/proposals/clocks/docs/Proposals.md +++ b/proposals/clocks/docs/Proposals.md @@ -38,6 +38,7 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo | Proposal | Champion | | ------------------------------------------------------------------------------ | -------------------------------------- | | [Crypto][wasi-crypto] | Frank Denis and Daiki Ueno | +| [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 0 - Pre-Proposal (CG) @@ -55,5 +56,6 @@ Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blo [wasi-clocks]: https://github.com/WebAssembly/wasi-clocks [wasi-random]: https://github.com/WebAssembly/wasi-random [wasi-misc]: https://github.com/WebAssembly/wasi-misc +[wasi-nn]: https://github.com/WebAssembly/wasi-nn [wasi-crypto]: https://github.com/WebAssembly/wasi-crypto [wasi-proxy-wasm]: https://github.com/proxy-wasm/spec From cc18586f27521d240ac569a527aefe9c5a8e6c8e Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 8 Oct 2020 12:21:06 -0700 Subject: [PATCH 0737/1772] Add wasi-nn proposal --- proposals/random/docs/Proposals.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/random/docs/Proposals.md b/proposals/random/docs/Proposals.md index 439de08fa..011a53eb8 100644 --- a/proposals/random/docs/Proposals.md +++ b/proposals/random/docs/Proposals.md @@ -38,6 +38,7 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo | Proposal | Champion | | ------------------------------------------------------------------------------ | -------------------------------------- | | [Crypto][wasi-crypto] | Frank Denis and Daiki Ueno | +| [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 0 - Pre-Proposal (CG) @@ -55,5 +56,6 @@ Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blo [wasi-clocks]: https://github.com/WebAssembly/wasi-clocks [wasi-random]: https://github.com/WebAssembly/wasi-random [wasi-misc]: https://github.com/WebAssembly/wasi-misc +[wasi-nn]: https://github.com/WebAssembly/wasi-nn [wasi-crypto]: https://github.com/WebAssembly/wasi-crypto [wasi-proxy-wasm]: https://github.com/proxy-wasm/spec From 6a847a72e9beca86690f154e6d550f694651b759 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 8 Oct 2020 12:21:06 -0700 Subject: [PATCH 0738/1772] Add wasi-nn proposal --- proposals/filesystem/docs/Proposals.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/filesystem/docs/Proposals.md b/proposals/filesystem/docs/Proposals.md index 439de08fa..011a53eb8 100644 --- a/proposals/filesystem/docs/Proposals.md +++ b/proposals/filesystem/docs/Proposals.md @@ -38,6 +38,7 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo | Proposal | Champion | | ------------------------------------------------------------------------------ | -------------------------------------- | | [Crypto][wasi-crypto] | Frank Denis and Daiki Ueno | +| [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 0 - Pre-Proposal (CG) @@ -55,5 +56,6 @@ Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blo [wasi-clocks]: https://github.com/WebAssembly/wasi-clocks [wasi-random]: https://github.com/WebAssembly/wasi-random [wasi-misc]: https://github.com/WebAssembly/wasi-misc +[wasi-nn]: https://github.com/WebAssembly/wasi-nn [wasi-crypto]: https://github.com/WebAssembly/wasi-crypto [wasi-proxy-wasm]: https://github.com/proxy-wasm/spec From 0e347307eaf2eda7c8e808935511a7a31e8ab661 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 8 Oct 2020 12:22:42 -0700 Subject: [PATCH 0739/1772] Alphabetize proposal links --- proposals/clocks/docs/Proposals.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/clocks/docs/Proposals.md b/proposals/clocks/docs/Proposals.md index 011a53eb8..5b8b08dc9 100644 --- a/proposals/clocks/docs/Proposals.md +++ b/proposals/clocks/docs/Proposals.md @@ -50,12 +50,12 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. -[wasi-io]: https://github.com/WebAssembly/wasi-io -[wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem -[wasi-command-line]: https://github.com/WebAssembly/wasi-classic-command [wasi-clocks]: https://github.com/WebAssembly/wasi-clocks -[wasi-random]: https://github.com/WebAssembly/wasi-random +[wasi-command-line]: https://github.com/WebAssembly/wasi-classic-command +[wasi-crypto]: https://github.com/WebAssembly/wasi-crypto +[wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem +[wasi-io]: https://github.com/WebAssembly/wasi-io [wasi-misc]: https://github.com/WebAssembly/wasi-misc [wasi-nn]: https://github.com/WebAssembly/wasi-nn -[wasi-crypto]: https://github.com/WebAssembly/wasi-crypto [wasi-proxy-wasm]: https://github.com/proxy-wasm/spec +[wasi-random]: https://github.com/WebAssembly/wasi-random From 000546404cb64138fe88894fd51ec5e0af64ca8e Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 8 Oct 2020 12:22:42 -0700 Subject: [PATCH 0740/1772] Alphabetize proposal links --- proposals/random/docs/Proposals.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/random/docs/Proposals.md b/proposals/random/docs/Proposals.md index 011a53eb8..5b8b08dc9 100644 --- a/proposals/random/docs/Proposals.md +++ b/proposals/random/docs/Proposals.md @@ -50,12 +50,12 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. -[wasi-io]: https://github.com/WebAssembly/wasi-io -[wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem -[wasi-command-line]: https://github.com/WebAssembly/wasi-classic-command [wasi-clocks]: https://github.com/WebAssembly/wasi-clocks -[wasi-random]: https://github.com/WebAssembly/wasi-random +[wasi-command-line]: https://github.com/WebAssembly/wasi-classic-command +[wasi-crypto]: https://github.com/WebAssembly/wasi-crypto +[wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem +[wasi-io]: https://github.com/WebAssembly/wasi-io [wasi-misc]: https://github.com/WebAssembly/wasi-misc [wasi-nn]: https://github.com/WebAssembly/wasi-nn -[wasi-crypto]: https://github.com/WebAssembly/wasi-crypto [wasi-proxy-wasm]: https://github.com/proxy-wasm/spec +[wasi-random]: https://github.com/WebAssembly/wasi-random From 976c1771a96a77d6e5cdcd184936deca1a8f6737 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 8 Oct 2020 12:22:42 -0700 Subject: [PATCH 0741/1772] Alphabetize proposal links --- proposals/filesystem/docs/Proposals.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/filesystem/docs/Proposals.md b/proposals/filesystem/docs/Proposals.md index 011a53eb8..5b8b08dc9 100644 --- a/proposals/filesystem/docs/Proposals.md +++ b/proposals/filesystem/docs/Proposals.md @@ -50,12 +50,12 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. -[wasi-io]: https://github.com/WebAssembly/wasi-io -[wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem -[wasi-command-line]: https://github.com/WebAssembly/wasi-classic-command [wasi-clocks]: https://github.com/WebAssembly/wasi-clocks -[wasi-random]: https://github.com/WebAssembly/wasi-random +[wasi-command-line]: https://github.com/WebAssembly/wasi-classic-command +[wasi-crypto]: https://github.com/WebAssembly/wasi-crypto +[wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem +[wasi-io]: https://github.com/WebAssembly/wasi-io [wasi-misc]: https://github.com/WebAssembly/wasi-misc [wasi-nn]: https://github.com/WebAssembly/wasi-nn -[wasi-crypto]: https://github.com/WebAssembly/wasi-crypto [wasi-proxy-wasm]: https://github.com/proxy-wasm/spec +[wasi-random]: https://github.com/WebAssembly/wasi-random From 3f6a80ecc84c0544aabefe374a02dfacbc299b6a Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 8 Oct 2020 12:36:07 -0700 Subject: [PATCH 0742/1772] Add proposal link to main page; re-organize content --- proposals/clocks/README.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 31bb340e1..d690ccb4b 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -3,24 +3,25 @@ ![WASI](WASI.png) This repository is for the WebAssembly System Interface (WASI) Subgroup of the -[WebAssembly Community Group]. Its [Charter] describes the goals, scope and -deliverables of the group. The repository may contain meeting notes, reports, -documentation, specifications and/or software produced by the group (although -larger projects may also have their own repositories). +[WebAssembly Community Group]. It includes: + - [charter]: describes the goals, scope and deliverables of the group + - [docs]: learn more about WASI + - [meetings]: schedules and agendas for video conference and in-person meetings + - [phases]: the current WASI specifications + - [proposals]: the status of each new specification proposal +[charter]: Charter.md +[docs]: docs +[meetings]: meetings/README.md +[phases]: phases/README.md +[proposals]: docs/Proposals.md [WebAssembly Community Group]: https://www.w3.org/community/webassembly/ -[Charter]: Charter.md We'll be adding more content here before long, but for now, check out these: - https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ - Blog post introducing WASI - - https://wasi.dev/ - Links to more information about WASI, including - how to get started using it. + - https://wasi.dev/ - Links to more information about WASI, including how to get started using it. - https://github.com/WebAssembly/WASI/issues - This repo's issue tracker -The issue tracker is the place to ask questions, make suggestions, and start -discussions. +### Contributing -Schedules and agendas for video conference and in-person meetings are posted -[here](meetings/README.md). - -API specification proposals are [here](phases/README.md). +The issue tracker is the place to ask questions, make suggestions, and start discussions. From cdf9862b515dec031d1c38732a8854751a160373 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 8 Oct 2020 12:36:07 -0700 Subject: [PATCH 0743/1772] Add proposal link to main page; re-organize content --- proposals/random/README.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/proposals/random/README.md b/proposals/random/README.md index 31bb340e1..d690ccb4b 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -3,24 +3,25 @@ ![WASI](WASI.png) This repository is for the WebAssembly System Interface (WASI) Subgroup of the -[WebAssembly Community Group]. Its [Charter] describes the goals, scope and -deliverables of the group. The repository may contain meeting notes, reports, -documentation, specifications and/or software produced by the group (although -larger projects may also have their own repositories). +[WebAssembly Community Group]. It includes: + - [charter]: describes the goals, scope and deliverables of the group + - [docs]: learn more about WASI + - [meetings]: schedules and agendas for video conference and in-person meetings + - [phases]: the current WASI specifications + - [proposals]: the status of each new specification proposal +[charter]: Charter.md +[docs]: docs +[meetings]: meetings/README.md +[phases]: phases/README.md +[proposals]: docs/Proposals.md [WebAssembly Community Group]: https://www.w3.org/community/webassembly/ -[Charter]: Charter.md We'll be adding more content here before long, but for now, check out these: - https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ - Blog post introducing WASI - - https://wasi.dev/ - Links to more information about WASI, including - how to get started using it. + - https://wasi.dev/ - Links to more information about WASI, including how to get started using it. - https://github.com/WebAssembly/WASI/issues - This repo's issue tracker -The issue tracker is the place to ask questions, make suggestions, and start -discussions. +### Contributing -Schedules and agendas for video conference and in-person meetings are posted -[here](meetings/README.md). - -API specification proposals are [here](phases/README.md). +The issue tracker is the place to ask questions, make suggestions, and start discussions. From 34c63ff24bec26cac3b1bbcfcc879e76d3f7022e Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 8 Oct 2020 12:36:07 -0700 Subject: [PATCH 0744/1772] Add proposal link to main page; re-organize content --- proposals/filesystem/README.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index 31bb340e1..d690ccb4b 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -3,24 +3,25 @@ ![WASI](WASI.png) This repository is for the WebAssembly System Interface (WASI) Subgroup of the -[WebAssembly Community Group]. Its [Charter] describes the goals, scope and -deliverables of the group. The repository may contain meeting notes, reports, -documentation, specifications and/or software produced by the group (although -larger projects may also have their own repositories). +[WebAssembly Community Group]. It includes: + - [charter]: describes the goals, scope and deliverables of the group + - [docs]: learn more about WASI + - [meetings]: schedules and agendas for video conference and in-person meetings + - [phases]: the current WASI specifications + - [proposals]: the status of each new specification proposal +[charter]: Charter.md +[docs]: docs +[meetings]: meetings/README.md +[phases]: phases/README.md +[proposals]: docs/Proposals.md [WebAssembly Community Group]: https://www.w3.org/community/webassembly/ -[Charter]: Charter.md We'll be adding more content here before long, but for now, check out these: - https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ - Blog post introducing WASI - - https://wasi.dev/ - Links to more information about WASI, including - how to get started using it. + - https://wasi.dev/ - Links to more information about WASI, including how to get started using it. - https://github.com/WebAssembly/WASI/issues - This repo's issue tracker -The issue tracker is the place to ask questions, make suggestions, and start -discussions. +### Contributing -Schedules and agendas for video conference and in-person meetings are posted -[here](meetings/README.md). - -API specification proposals are [here](phases/README.md). +The issue tracker is the place to ask questions, make suggestions, and start discussions. From 01fce05be6a30189226e3fc60d0cf9df5c7ae0c6 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Wed, 21 Oct 2020 10:53:32 -0700 Subject: [PATCH 0745/1772] Add proposal to cover WASI Logo in next WASI meeting (#337) --- proposals/clocks/meetings/2020/WASI-10-22.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/proposals/clocks/meetings/2020/WASI-10-22.md b/proposals/clocks/meetings/2020/WASI-10-22.md index 60f9b44a8..d7abc02b6 100644 --- a/proposals/clocks/meetings/2020/WASI-10-22.md +++ b/proposals/clocks/meetings/2020/WASI-10-22.md @@ -26,5 +26,13 @@ Installation is required, see the calendar invite. 1. Please help take notes. 1. Thanks! 1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). +1. Discuss about how to move forward with a [WASI Logo](https://github.com/WebAssembly/WASI/issues/3). Proposals: + 1. We would never like to change the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png). + 2. We would like to keep the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png) for now, and change it in the future when WASI is more mature. + TODO: Ask the risks of changing the logo short-term and see if there is any way to address them. + TODO: define what "mature" means (objectively) and how the process will be then + 3. We would like to start researching on a new logo now. + TODO: define how the process will be + 4. Other ideas? ## Meeting Notes From 10f5229fe6bfd33d37fd21121c1c3006d72151fc Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Wed, 21 Oct 2020 10:53:32 -0700 Subject: [PATCH 0746/1772] Add proposal to cover WASI Logo in next WASI meeting (#337) --- proposals/random/meetings/2020/WASI-10-22.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/proposals/random/meetings/2020/WASI-10-22.md b/proposals/random/meetings/2020/WASI-10-22.md index 60f9b44a8..d7abc02b6 100644 --- a/proposals/random/meetings/2020/WASI-10-22.md +++ b/proposals/random/meetings/2020/WASI-10-22.md @@ -26,5 +26,13 @@ Installation is required, see the calendar invite. 1. Please help take notes. 1. Thanks! 1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). +1. Discuss about how to move forward with a [WASI Logo](https://github.com/WebAssembly/WASI/issues/3). Proposals: + 1. We would never like to change the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png). + 2. We would like to keep the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png) for now, and change it in the future when WASI is more mature. + TODO: Ask the risks of changing the logo short-term and see if there is any way to address them. + TODO: define what "mature" means (objectively) and how the process will be then + 3. We would like to start researching on a new logo now. + TODO: define how the process will be + 4. Other ideas? ## Meeting Notes From 6e12fb21e71905a857b99f2cb16301e11d7b9fdb Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Wed, 21 Oct 2020 10:53:32 -0700 Subject: [PATCH 0747/1772] Add proposal to cover WASI Logo in next WASI meeting (#337) --- proposals/filesystem/meetings/2020/WASI-10-22.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/proposals/filesystem/meetings/2020/WASI-10-22.md b/proposals/filesystem/meetings/2020/WASI-10-22.md index 60f9b44a8..d7abc02b6 100644 --- a/proposals/filesystem/meetings/2020/WASI-10-22.md +++ b/proposals/filesystem/meetings/2020/WASI-10-22.md @@ -26,5 +26,13 @@ Installation is required, see the calendar invite. 1. Please help take notes. 1. Thanks! 1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). +1. Discuss about how to move forward with a [WASI Logo](https://github.com/WebAssembly/WASI/issues/3). Proposals: + 1. We would never like to change the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png). + 2. We would like to keep the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png) for now, and change it in the future when WASI is more mature. + TODO: Ask the risks of changing the logo short-term and see if there is any way to address them. + TODO: define what "mature" means (objectively) and how the process will be then + 3. We would like to start researching on a new logo now. + TODO: define how the process will be + 4. Other ideas? ## Meeting Notes From 1bf2d45fc73fc1e083e74f935f8f509e17fb0f38 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Wed, 21 Oct 2020 10:57:17 -0700 Subject: [PATCH 0748/1772] Add note about myself hosting this meeting --- proposals/clocks/meetings/2020/WASI-10-22.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/clocks/meetings/2020/WASI-10-22.md b/proposals/clocks/meetings/2020/WASI-10-22.md index d7abc02b6..b100f5434 100644 --- a/proposals/clocks/meetings/2020/WASI-10-22.md +++ b/proposals/clocks/meetings/2020/WASI-10-22.md @@ -9,6 +9,8 @@ - Name: Dan Gohman - Email: hello@sunfishcode.online +**Note**: This meeting will be hosted by the subgroup co-chair Sam Clegg (@sbc100) + ### Registration None required if you've attended before. Email Dan Gohman to sign up if it's From ee50269d90a93204929dc80d0c8d8f7d447ed343 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Wed, 21 Oct 2020 10:57:17 -0700 Subject: [PATCH 0749/1772] Add note about myself hosting this meeting --- proposals/random/meetings/2020/WASI-10-22.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/random/meetings/2020/WASI-10-22.md b/proposals/random/meetings/2020/WASI-10-22.md index d7abc02b6..b100f5434 100644 --- a/proposals/random/meetings/2020/WASI-10-22.md +++ b/proposals/random/meetings/2020/WASI-10-22.md @@ -9,6 +9,8 @@ - Name: Dan Gohman - Email: hello@sunfishcode.online +**Note**: This meeting will be hosted by the subgroup co-chair Sam Clegg (@sbc100) + ### Registration None required if you've attended before. Email Dan Gohman to sign up if it's From 905cedca2f1a41589ac249e2d7007d2ffdae386b Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Wed, 21 Oct 2020 10:57:17 -0700 Subject: [PATCH 0750/1772] Add note about myself hosting this meeting --- proposals/filesystem/meetings/2020/WASI-10-22.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/filesystem/meetings/2020/WASI-10-22.md b/proposals/filesystem/meetings/2020/WASI-10-22.md index d7abc02b6..b100f5434 100644 --- a/proposals/filesystem/meetings/2020/WASI-10-22.md +++ b/proposals/filesystem/meetings/2020/WASI-10-22.md @@ -9,6 +9,8 @@ - Name: Dan Gohman - Email: hello@sunfishcode.online +**Note**: This meeting will be hosted by the subgroup co-chair Sam Clegg (@sbc100) + ### Registration None required if you've attended before. Email Dan Gohman to sign up if it's From e504626d4ef0ee286565704b27396b2711b9b7c3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 21 Oct 2020 12:54:53 -0700 Subject: [PATCH 0751/1772] Add an agenda item for a presentation on character encodings. (#339) There are several discussions going about character encodings and strings across different forums. This presentation will summarize the current conversations and discuss the high-level pros and cons of various options being discussed. --- proposals/clocks/meetings/2020/WASI-10-22.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proposals/clocks/meetings/2020/WASI-10-22.md b/proposals/clocks/meetings/2020/WASI-10-22.md index b100f5434..f220bd5ec 100644 --- a/proposals/clocks/meetings/2020/WASI-10-22.md +++ b/proposals/clocks/meetings/2020/WASI-10-22.md @@ -28,6 +28,12 @@ Installation is required, see the calendar invite. 1. Please help take notes. 1. Thanks! 1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). +1. Character encodings + 1. A presentation on: Summarizing several current discussions around character encodings + 1. For details, see the individual issues: + 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 "case-sensitivity of filesystem apis" + 1. https://github.com/WebAssembly/WASI/issues/8 "Specify UTF-8 as the character set" + 1. https://github.com/WebAssembly/gc/issues/145 "GC story for strings?" 1. Discuss about how to move forward with a [WASI Logo](https://github.com/WebAssembly/WASI/issues/3). Proposals: 1. We would never like to change the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png). 2. We would like to keep the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png) for now, and change it in the future when WASI is more mature. From a7be413ede23d0e5c534f8dbe843f640c1519f0b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 21 Oct 2020 12:54:53 -0700 Subject: [PATCH 0752/1772] Add an agenda item for a presentation on character encodings. (#339) There are several discussions going about character encodings and strings across different forums. This presentation will summarize the current conversations and discuss the high-level pros and cons of various options being discussed. --- proposals/random/meetings/2020/WASI-10-22.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proposals/random/meetings/2020/WASI-10-22.md b/proposals/random/meetings/2020/WASI-10-22.md index b100f5434..f220bd5ec 100644 --- a/proposals/random/meetings/2020/WASI-10-22.md +++ b/proposals/random/meetings/2020/WASI-10-22.md @@ -28,6 +28,12 @@ Installation is required, see the calendar invite. 1. Please help take notes. 1. Thanks! 1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). +1. Character encodings + 1. A presentation on: Summarizing several current discussions around character encodings + 1. For details, see the individual issues: + 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 "case-sensitivity of filesystem apis" + 1. https://github.com/WebAssembly/WASI/issues/8 "Specify UTF-8 as the character set" + 1. https://github.com/WebAssembly/gc/issues/145 "GC story for strings?" 1. Discuss about how to move forward with a [WASI Logo](https://github.com/WebAssembly/WASI/issues/3). Proposals: 1. We would never like to change the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png). 2. We would like to keep the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png) for now, and change it in the future when WASI is more mature. From 89167d6b3d7ec7b18cc1507d92fa3192672a8f29 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 21 Oct 2020 12:54:53 -0700 Subject: [PATCH 0753/1772] Add an agenda item for a presentation on character encodings. (#339) There are several discussions going about character encodings and strings across different forums. This presentation will summarize the current conversations and discuss the high-level pros and cons of various options being discussed. --- proposals/filesystem/meetings/2020/WASI-10-22.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proposals/filesystem/meetings/2020/WASI-10-22.md b/proposals/filesystem/meetings/2020/WASI-10-22.md index b100f5434..f220bd5ec 100644 --- a/proposals/filesystem/meetings/2020/WASI-10-22.md +++ b/proposals/filesystem/meetings/2020/WASI-10-22.md @@ -28,6 +28,12 @@ Installation is required, see the calendar invite. 1. Please help take notes. 1. Thanks! 1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). +1. Character encodings + 1. A presentation on: Summarizing several current discussions around character encodings + 1. For details, see the individual issues: + 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 "case-sensitivity of filesystem apis" + 1. https://github.com/WebAssembly/WASI/issues/8 "Specify UTF-8 as the character set" + 1. https://github.com/WebAssembly/gc/issues/145 "GC story for strings?" 1. Discuss about how to move forward with a [WASI Logo](https://github.com/WebAssembly/WASI/issues/3). Proposals: 1. We would never like to change the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png). 2. We would like to keep the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png) for now, and change it in the future when WASI is more mature. From f921f2b85164015d6cee0829241aa4e4f27ecf34 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 22 Oct 2020 10:12:18 -0700 Subject: [PATCH 0754/1772] Move wasi-nn to phase 2 (#343) See notes for [2020-10-22 subgroup meeting](https://github.com/WebAssembly/WASI/blob/master/meetings/2020/WASI-10-22.md) --- proposals/clocks/docs/Proposals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/docs/Proposals.md b/proposals/clocks/docs/Proposals.md index 5b8b08dc9..e16a8820e 100644 --- a/proposals/clocks/docs/Proposals.md +++ b/proposals/clocks/docs/Proposals.md @@ -32,13 +32,13 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo | [Clocks][wasi-clocks] | Dan Gohman | | [Random][wasi-random] | Dan Gohman | | [Misc][wasi-misc] | Dan Gohman | +| [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 1 - Feature Proposal (CG) | Proposal | Champion | | ------------------------------------------------------------------------------ | -------------------------------------- | | [Crypto][wasi-crypto] | Frank Denis and Daiki Ueno | -| [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 0 - Pre-Proposal (CG) From af4ef04bdd75603842839089b9fedd16cf524416 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 22 Oct 2020 10:12:18 -0700 Subject: [PATCH 0755/1772] Move wasi-nn to phase 2 (#343) See notes for [2020-10-22 subgroup meeting](https://github.com/WebAssembly/WASI/blob/master/meetings/2020/WASI-10-22.md) --- proposals/random/docs/Proposals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/docs/Proposals.md b/proposals/random/docs/Proposals.md index 5b8b08dc9..e16a8820e 100644 --- a/proposals/random/docs/Proposals.md +++ b/proposals/random/docs/Proposals.md @@ -32,13 +32,13 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo | [Clocks][wasi-clocks] | Dan Gohman | | [Random][wasi-random] | Dan Gohman | | [Misc][wasi-misc] | Dan Gohman | +| [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 1 - Feature Proposal (CG) | Proposal | Champion | | ------------------------------------------------------------------------------ | -------------------------------------- | | [Crypto][wasi-crypto] | Frank Denis and Daiki Ueno | -| [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 0 - Pre-Proposal (CG) From ac556418da7eb18f93179ed0b11a50b9e7c65b68 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 22 Oct 2020 10:12:18 -0700 Subject: [PATCH 0756/1772] Move wasi-nn to phase 2 (#343) See notes for [2020-10-22 subgroup meeting](https://github.com/WebAssembly/WASI/blob/master/meetings/2020/WASI-10-22.md) --- proposals/filesystem/docs/Proposals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/docs/Proposals.md b/proposals/filesystem/docs/Proposals.md index 5b8b08dc9..e16a8820e 100644 --- a/proposals/filesystem/docs/Proposals.md +++ b/proposals/filesystem/docs/Proposals.md @@ -32,13 +32,13 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo | [Clocks][wasi-clocks] | Dan Gohman | | [Random][wasi-random] | Dan Gohman | | [Misc][wasi-misc] | Dan Gohman | +| [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 1 - Feature Proposal (CG) | Proposal | Champion | | ------------------------------------------------------------------------------ | -------------------------------------- | | [Crypto][wasi-crypto] | Frank Denis and Daiki Ueno | -| [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 0 - Pre-Proposal (CG) From 8555f9116385d25107c701bf1459b0f6ea1ea39f Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 22 Oct 2020 10:18:01 -0700 Subject: [PATCH 0757/1772] add action items (#342) --- proposals/clocks/meetings/2020/WASI-10-22.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/clocks/meetings/2020/WASI-10-22.md b/proposals/clocks/meetings/2020/WASI-10-22.md index f220bd5ec..99c2a3209 100644 --- a/proposals/clocks/meetings/2020/WASI-10-22.md +++ b/proposals/clocks/meetings/2020/WASI-10-22.md @@ -27,6 +27,7 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! +1. Review of action items from previous meeting(s). 1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). 1. Character encodings 1. A presentation on: Summarizing several current discussions around character encodings From f22a6169ca11f93eed8ee864a16c28fc6f6e6264 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 22 Oct 2020 10:18:01 -0700 Subject: [PATCH 0758/1772] add action items (#342) --- proposals/random/meetings/2020/WASI-10-22.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/random/meetings/2020/WASI-10-22.md b/proposals/random/meetings/2020/WASI-10-22.md index f220bd5ec..99c2a3209 100644 --- a/proposals/random/meetings/2020/WASI-10-22.md +++ b/proposals/random/meetings/2020/WASI-10-22.md @@ -27,6 +27,7 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! +1. Review of action items from previous meeting(s). 1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). 1. Character encodings 1. A presentation on: Summarizing several current discussions around character encodings From 81519ed0a4f895c785e7196160a38cbb25166470 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 22 Oct 2020 10:18:01 -0700 Subject: [PATCH 0759/1772] add action items (#342) --- proposals/filesystem/meetings/2020/WASI-10-22.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/filesystem/meetings/2020/WASI-10-22.md b/proposals/filesystem/meetings/2020/WASI-10-22.md index f220bd5ec..99c2a3209 100644 --- a/proposals/filesystem/meetings/2020/WASI-10-22.md +++ b/proposals/filesystem/meetings/2020/WASI-10-22.md @@ -27,6 +27,7 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! +1. Review of action items from previous meeting(s). 1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). 1. Character encodings 1. A presentation on: Summarizing several current discussions around character encodings From a95ac2ebc39384db3c0ff583d1ea02426da2d0d8 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Fri, 23 Oct 2020 10:43:11 -0700 Subject: [PATCH 0760/1772] Add 10-22 meeting notes (#344) --- proposals/clocks/meetings/2020/WASI-10-22.md | 160 +++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/proposals/clocks/meetings/2020/WASI-10-22.md b/proposals/clocks/meetings/2020/WASI-10-22.md index 99c2a3209..079c3cb62 100644 --- a/proposals/clocks/meetings/2020/WASI-10-22.md +++ b/proposals/clocks/meetings/2020/WASI-10-22.md @@ -45,3 +45,163 @@ Installation is required, see the calendar invite. 4. Other ideas? ## Meeting Notes + +### Attendees + +- Sam Clegg +- Thomas Lively +- Martin Duke +- Syrus Akbary +- Pat Hickey +- Tanya Crenshaw +- Alon Zakai +- Andrew Brown +- Mingqiu Sun +- Alex Crichton +- Dan Gohman +- Steven Dabell +- David Piepgrass +- Johnnie Birch +- Martin Duke +- Yong +- Sergey Rubanov +- Arun Purushan + +### Find volunteers for note taking + +TL volunteers + +### Adoption of the agenda + +PH seconds + +### Notes + +#### Review of action items from prior meeting + +DG: Next time ??? is in the meeting we will check up on ??? + +#### Vote to move wasi-nn to stage 2 + +- Phases: https://github.com/WebAssembly/WASI/blob/master/docs/Process.md + +AB: We proposed wasi-nn a while back. Have a witx spec. I’ve been creating a POC +to see if this works. When looking at docs, realized we are essentially in stage +2. Moving to phase 2 would reflect reality. Asking for feedback on API. + +SC: English spec text requirement doesn’t apply? + +DG: Right, we only have witx. + +AB: Also generates md, which might count. + +SC: Implementation and test writing starts in stage 2. Probably don’t need a +full vote. Does anyone have any comments or objections? + +PH: I followed it and I’m happy with how it looks. + +SC: Unanimous consent achieved to move to stage 2. + +AB: I will submit a PR updating which table it is in. + +#### Character encodings + +DG: Several threads about encodings going on. Want feedback about direction. + + TODO: Add link to slides + +SC: Won’t the C program truncate on strcpy? + +DG: Yes, but then you’ll get a file not found error. + +SC: Where does this ARF encoding come from? + +DG: I invented this after a lot of tries. + +SA: Is this for filenames only or also for contents? + +DG: File names, env vars, commandline args, but not file contents. + +SC: Anywhere a known string crosses the WASI boundary? + +DG: There might be other places. Where invalid strings should be roundtrippable without trapping. Some APIs trap, others wouldn’t. Some tools will want different things as well. + +TL: wasi seems like it may be the wrong layer to solve encoding problems since it is not related to capability-based security. Can we leave this to an optional userspace virtualization layer? + +DG: That seems reasonable since virtualization is an option. + +PH: When IT describe interfaces, it would be great to use strings for these types, and IT guarantees unicode. ARF lets us use the IT string type. + +AC: In windows, filenames are lists of 16-bit values. How do we go from 16-bit to 8-bit strings? We need an extra layer. + +DG: We can extend ARF to handle Windows character space as well. ARF would be a little different on Windows and Linux. + +SC: But there are filesystem out there with different filename encodings. e.g. Shift-JIS in asia. + +DG: wasi engines can translate host character encodings into unicode. + +AC: What would the users look like? Not raw API users, but e.g. rust stdlib users. Would the entire ARF string be stored in Rust’s Path object? + +DG: Two cases: in do nothing case, use all the standard APIs. In ARF encoding case, get string as ARF encoded OSString or similar. WASI will either detect ARF string and not validate or would get file not found. There is a Rust library that can take an OSString and be ARF-aware to do things. + +SC: But most programs won’t need to do this because these files don’t exist in practice. + +AC: Not sure about this. Rust stdlib would want to do the proper decoding to show better error messages. It seems only extremely low-level C developers would be in the do-nothing case. + +SC: Do-nothing only prints first half, right? + +AC: Only in C. When there is a pointer and length, the second half gets printed too. + +DG: Good point. Don’t have an answer for that. + +SC: Curious about prior art. + +DG: Perl 6 has UTF8-C8. Uses highest private use code point as an escape char. + +AC: Using nul character seems reasonable given that native filesystems already disallow it. + +DG: Python uses lone surrogates. Not great because you end up with invalid unicode. + +SC: To be clear, status quo is passing through raw bytes from OS with no validation? + +DG: Some implementations already have some validation and different behavior. + +#### Discuss about how to move forward with a WASI logo + +SA: I’m the founder and CEO of Wasmer, want to see what the risks are about +moving forward with a different logo and what are the issues with the current +logo. + + TODO: add slides + +SA: Show we replace the logo at some point? + +TL: Agree with identified issues. + +SC: Another options would be to fix the problems in the current logo. + +TS: It’s clear that the current logo is a draft. I actually like this property +because WASI itself is also in a draft stage. For example, the proposed logo +uses an office CLI metaphor, which is not what WASI has shaped up to be about. + +SA: One idea would be to replace the current logo with a short term logo that +fixes some of the issues and is more accessible. Then separately it would be +good to organize a contest for a new WASI logo. Back to slides… + +TS: It would be good to mention reasons on the issue so others can weigh in. + +SA: Will follow up on the issue. + +TL: What if we just fix all issues except for wasted space in the current logo? + +SA: That would be an improvement, but it would be good to fix the wasted space as well. + +SC: Any objections to incremental fix? + +PH: Don’t want to spend any more time on this. + +SA: I can handle this and release the results with a copyleft license to resolve any other issues. + +TS: I think we still need to check what the situation is with IP rights just in case. + +SA: I understand those concerns and want to make this as easy as possible. From fe81509408a98ca7f8e063fdc52813b22ddd9003 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Fri, 23 Oct 2020 10:43:11 -0700 Subject: [PATCH 0761/1772] Add 10-22 meeting notes (#344) --- proposals/random/meetings/2020/WASI-10-22.md | 160 +++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/proposals/random/meetings/2020/WASI-10-22.md b/proposals/random/meetings/2020/WASI-10-22.md index 99c2a3209..079c3cb62 100644 --- a/proposals/random/meetings/2020/WASI-10-22.md +++ b/proposals/random/meetings/2020/WASI-10-22.md @@ -45,3 +45,163 @@ Installation is required, see the calendar invite. 4. Other ideas? ## Meeting Notes + +### Attendees + +- Sam Clegg +- Thomas Lively +- Martin Duke +- Syrus Akbary +- Pat Hickey +- Tanya Crenshaw +- Alon Zakai +- Andrew Brown +- Mingqiu Sun +- Alex Crichton +- Dan Gohman +- Steven Dabell +- David Piepgrass +- Johnnie Birch +- Martin Duke +- Yong +- Sergey Rubanov +- Arun Purushan + +### Find volunteers for note taking + +TL volunteers + +### Adoption of the agenda + +PH seconds + +### Notes + +#### Review of action items from prior meeting + +DG: Next time ??? is in the meeting we will check up on ??? + +#### Vote to move wasi-nn to stage 2 + +- Phases: https://github.com/WebAssembly/WASI/blob/master/docs/Process.md + +AB: We proposed wasi-nn a while back. Have a witx spec. I’ve been creating a POC +to see if this works. When looking at docs, realized we are essentially in stage +2. Moving to phase 2 would reflect reality. Asking for feedback on API. + +SC: English spec text requirement doesn’t apply? + +DG: Right, we only have witx. + +AB: Also generates md, which might count. + +SC: Implementation and test writing starts in stage 2. Probably don’t need a +full vote. Does anyone have any comments or objections? + +PH: I followed it and I’m happy with how it looks. + +SC: Unanimous consent achieved to move to stage 2. + +AB: I will submit a PR updating which table it is in. + +#### Character encodings + +DG: Several threads about encodings going on. Want feedback about direction. + + TODO: Add link to slides + +SC: Won’t the C program truncate on strcpy? + +DG: Yes, but then you’ll get a file not found error. + +SC: Where does this ARF encoding come from? + +DG: I invented this after a lot of tries. + +SA: Is this for filenames only or also for contents? + +DG: File names, env vars, commandline args, but not file contents. + +SC: Anywhere a known string crosses the WASI boundary? + +DG: There might be other places. Where invalid strings should be roundtrippable without trapping. Some APIs trap, others wouldn’t. Some tools will want different things as well. + +TL: wasi seems like it may be the wrong layer to solve encoding problems since it is not related to capability-based security. Can we leave this to an optional userspace virtualization layer? + +DG: That seems reasonable since virtualization is an option. + +PH: When IT describe interfaces, it would be great to use strings for these types, and IT guarantees unicode. ARF lets us use the IT string type. + +AC: In windows, filenames are lists of 16-bit values. How do we go from 16-bit to 8-bit strings? We need an extra layer. + +DG: We can extend ARF to handle Windows character space as well. ARF would be a little different on Windows and Linux. + +SC: But there are filesystem out there with different filename encodings. e.g. Shift-JIS in asia. + +DG: wasi engines can translate host character encodings into unicode. + +AC: What would the users look like? Not raw API users, but e.g. rust stdlib users. Would the entire ARF string be stored in Rust’s Path object? + +DG: Two cases: in do nothing case, use all the standard APIs. In ARF encoding case, get string as ARF encoded OSString or similar. WASI will either detect ARF string and not validate or would get file not found. There is a Rust library that can take an OSString and be ARF-aware to do things. + +SC: But most programs won’t need to do this because these files don’t exist in practice. + +AC: Not sure about this. Rust stdlib would want to do the proper decoding to show better error messages. It seems only extremely low-level C developers would be in the do-nothing case. + +SC: Do-nothing only prints first half, right? + +AC: Only in C. When there is a pointer and length, the second half gets printed too. + +DG: Good point. Don’t have an answer for that. + +SC: Curious about prior art. + +DG: Perl 6 has UTF8-C8. Uses highest private use code point as an escape char. + +AC: Using nul character seems reasonable given that native filesystems already disallow it. + +DG: Python uses lone surrogates. Not great because you end up with invalid unicode. + +SC: To be clear, status quo is passing through raw bytes from OS with no validation? + +DG: Some implementations already have some validation and different behavior. + +#### Discuss about how to move forward with a WASI logo + +SA: I’m the founder and CEO of Wasmer, want to see what the risks are about +moving forward with a different logo and what are the issues with the current +logo. + + TODO: add slides + +SA: Show we replace the logo at some point? + +TL: Agree with identified issues. + +SC: Another options would be to fix the problems in the current logo. + +TS: It’s clear that the current logo is a draft. I actually like this property +because WASI itself is also in a draft stage. For example, the proposed logo +uses an office CLI metaphor, which is not what WASI has shaped up to be about. + +SA: One idea would be to replace the current logo with a short term logo that +fixes some of the issues and is more accessible. Then separately it would be +good to organize a contest for a new WASI logo. Back to slides… + +TS: It would be good to mention reasons on the issue so others can weigh in. + +SA: Will follow up on the issue. + +TL: What if we just fix all issues except for wasted space in the current logo? + +SA: That would be an improvement, but it would be good to fix the wasted space as well. + +SC: Any objections to incremental fix? + +PH: Don’t want to spend any more time on this. + +SA: I can handle this and release the results with a copyleft license to resolve any other issues. + +TS: I think we still need to check what the situation is with IP rights just in case. + +SA: I understand those concerns and want to make this as easy as possible. From 04ed1f68f0fdfec4d07b00ae3a3c31d486eecc4f Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Fri, 23 Oct 2020 10:43:11 -0700 Subject: [PATCH 0762/1772] Add 10-22 meeting notes (#344) --- .../filesystem/meetings/2020/WASI-10-22.md | 160 ++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/proposals/filesystem/meetings/2020/WASI-10-22.md b/proposals/filesystem/meetings/2020/WASI-10-22.md index 99c2a3209..079c3cb62 100644 --- a/proposals/filesystem/meetings/2020/WASI-10-22.md +++ b/proposals/filesystem/meetings/2020/WASI-10-22.md @@ -45,3 +45,163 @@ Installation is required, see the calendar invite. 4. Other ideas? ## Meeting Notes + +### Attendees + +- Sam Clegg +- Thomas Lively +- Martin Duke +- Syrus Akbary +- Pat Hickey +- Tanya Crenshaw +- Alon Zakai +- Andrew Brown +- Mingqiu Sun +- Alex Crichton +- Dan Gohman +- Steven Dabell +- David Piepgrass +- Johnnie Birch +- Martin Duke +- Yong +- Sergey Rubanov +- Arun Purushan + +### Find volunteers for note taking + +TL volunteers + +### Adoption of the agenda + +PH seconds + +### Notes + +#### Review of action items from prior meeting + +DG: Next time ??? is in the meeting we will check up on ??? + +#### Vote to move wasi-nn to stage 2 + +- Phases: https://github.com/WebAssembly/WASI/blob/master/docs/Process.md + +AB: We proposed wasi-nn a while back. Have a witx spec. I’ve been creating a POC +to see if this works. When looking at docs, realized we are essentially in stage +2. Moving to phase 2 would reflect reality. Asking for feedback on API. + +SC: English spec text requirement doesn’t apply? + +DG: Right, we only have witx. + +AB: Also generates md, which might count. + +SC: Implementation and test writing starts in stage 2. Probably don’t need a +full vote. Does anyone have any comments or objections? + +PH: I followed it and I’m happy with how it looks. + +SC: Unanimous consent achieved to move to stage 2. + +AB: I will submit a PR updating which table it is in. + +#### Character encodings + +DG: Several threads about encodings going on. Want feedback about direction. + + TODO: Add link to slides + +SC: Won’t the C program truncate on strcpy? + +DG: Yes, but then you’ll get a file not found error. + +SC: Where does this ARF encoding come from? + +DG: I invented this after a lot of tries. + +SA: Is this for filenames only or also for contents? + +DG: File names, env vars, commandline args, but not file contents. + +SC: Anywhere a known string crosses the WASI boundary? + +DG: There might be other places. Where invalid strings should be roundtrippable without trapping. Some APIs trap, others wouldn’t. Some tools will want different things as well. + +TL: wasi seems like it may be the wrong layer to solve encoding problems since it is not related to capability-based security. Can we leave this to an optional userspace virtualization layer? + +DG: That seems reasonable since virtualization is an option. + +PH: When IT describe interfaces, it would be great to use strings for these types, and IT guarantees unicode. ARF lets us use the IT string type. + +AC: In windows, filenames are lists of 16-bit values. How do we go from 16-bit to 8-bit strings? We need an extra layer. + +DG: We can extend ARF to handle Windows character space as well. ARF would be a little different on Windows and Linux. + +SC: But there are filesystem out there with different filename encodings. e.g. Shift-JIS in asia. + +DG: wasi engines can translate host character encodings into unicode. + +AC: What would the users look like? Not raw API users, but e.g. rust stdlib users. Would the entire ARF string be stored in Rust’s Path object? + +DG: Two cases: in do nothing case, use all the standard APIs. In ARF encoding case, get string as ARF encoded OSString or similar. WASI will either detect ARF string and not validate or would get file not found. There is a Rust library that can take an OSString and be ARF-aware to do things. + +SC: But most programs won’t need to do this because these files don’t exist in practice. + +AC: Not sure about this. Rust stdlib would want to do the proper decoding to show better error messages. It seems only extremely low-level C developers would be in the do-nothing case. + +SC: Do-nothing only prints first half, right? + +AC: Only in C. When there is a pointer and length, the second half gets printed too. + +DG: Good point. Don’t have an answer for that. + +SC: Curious about prior art. + +DG: Perl 6 has UTF8-C8. Uses highest private use code point as an escape char. + +AC: Using nul character seems reasonable given that native filesystems already disallow it. + +DG: Python uses lone surrogates. Not great because you end up with invalid unicode. + +SC: To be clear, status quo is passing through raw bytes from OS with no validation? + +DG: Some implementations already have some validation and different behavior. + +#### Discuss about how to move forward with a WASI logo + +SA: I’m the founder and CEO of Wasmer, want to see what the risks are about +moving forward with a different logo and what are the issues with the current +logo. + + TODO: add slides + +SA: Show we replace the logo at some point? + +TL: Agree with identified issues. + +SC: Another options would be to fix the problems in the current logo. + +TS: It’s clear that the current logo is a draft. I actually like this property +because WASI itself is also in a draft stage. For example, the proposed logo +uses an office CLI metaphor, which is not what WASI has shaped up to be about. + +SA: One idea would be to replace the current logo with a short term logo that +fixes some of the issues and is more accessible. Then separately it would be +good to organize a contest for a new WASI logo. Back to slides… + +TS: It would be good to mention reasons on the issue so others can weigh in. + +SA: Will follow up on the issue. + +TL: What if we just fix all issues except for wasted space in the current logo? + +SA: That would be an improvement, but it would be good to fix the wasted space as well. + +SC: Any objections to incremental fix? + +PH: Don’t want to spend any more time on this. + +SA: I can handle this and release the results with a copyleft license to resolve any other issues. + +TS: I think we still need to check what the situation is with IP rights just in case. + +SA: I understand those concerns and want to make this as easy as possible. From 9a99d85baeed5bf63e4407f7743f715ada6131f2 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Fri, 23 Oct 2020 16:06:56 -0700 Subject: [PATCH 0763/1772] Update WASI-10-22.md (#345) --- proposals/clocks/meetings/2020/WASI-10-22.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/meetings/2020/WASI-10-22.md b/proposals/clocks/meetings/2020/WASI-10-22.md index 079c3cb62..eb7d737de 100644 --- a/proposals/clocks/meetings/2020/WASI-10-22.md +++ b/proposals/clocks/meetings/2020/WASI-10-22.md @@ -168,12 +168,16 @@ DG: Some implementations already have some validation and different behavior. #### Discuss about how to move forward with a WASI logo +Slides: +https://speakerdeck.com/syrusakbary/wasi-logo-proposal + +WASI issue: +https://github.com/WebAssembly/WASI/issues/3#issuecomment-714740192 + SA: I’m the founder and CEO of Wasmer, want to see what the risks are about moving forward with a different logo and what are the issues with the current logo. - TODO: add slides - SA: Show we replace the logo at some point? TL: Agree with identified issues. From 6d0118e2853e41d2d08d91fd1d0c21036634976e Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Fri, 23 Oct 2020 16:06:56 -0700 Subject: [PATCH 0764/1772] Update WASI-10-22.md (#345) --- proposals/random/meetings/2020/WASI-10-22.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/proposals/random/meetings/2020/WASI-10-22.md b/proposals/random/meetings/2020/WASI-10-22.md index 079c3cb62..eb7d737de 100644 --- a/proposals/random/meetings/2020/WASI-10-22.md +++ b/proposals/random/meetings/2020/WASI-10-22.md @@ -168,12 +168,16 @@ DG: Some implementations already have some validation and different behavior. #### Discuss about how to move forward with a WASI logo +Slides: +https://speakerdeck.com/syrusakbary/wasi-logo-proposal + +WASI issue: +https://github.com/WebAssembly/WASI/issues/3#issuecomment-714740192 + SA: I’m the founder and CEO of Wasmer, want to see what the risks are about moving forward with a different logo and what are the issues with the current logo. - TODO: add slides - SA: Show we replace the logo at some point? TL: Agree with identified issues. From 36cc12c65e2602f878f1de2469dfca440fbf8012 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Fri, 23 Oct 2020 16:06:56 -0700 Subject: [PATCH 0765/1772] Update WASI-10-22.md (#345) --- proposals/filesystem/meetings/2020/WASI-10-22.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/meetings/2020/WASI-10-22.md b/proposals/filesystem/meetings/2020/WASI-10-22.md index 079c3cb62..eb7d737de 100644 --- a/proposals/filesystem/meetings/2020/WASI-10-22.md +++ b/proposals/filesystem/meetings/2020/WASI-10-22.md @@ -168,12 +168,16 @@ DG: Some implementations already have some validation and different behavior. #### Discuss about how to move forward with a WASI logo +Slides: +https://speakerdeck.com/syrusakbary/wasi-logo-proposal + +WASI issue: +https://github.com/WebAssembly/WASI/issues/3#issuecomment-714740192 + SA: I’m the founder and CEO of Wasmer, want to see what the risks are about moving forward with a different logo and what are the issues with the current logo. - TODO: add slides - SA: Show we replace the logo at some point? TL: Agree with identified issues. From ee2dd3d3862176e5cbbeb9bbeca5ed64eebd9474 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Mon, 26 Oct 2020 10:58:11 -0700 Subject: [PATCH 0766/1772] Create documentation landing page As discussed in https://github.com/WebAssembly/WASI/pull/329#discussion_r505020459, this change creates a landing page explaining roughly what you get in each of the documentation pages and moves the helpful links from the main README to this page. --- proposals/clocks/README.md | 11 ++++------- proposals/clocks/docs/README.md | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 proposals/clocks/docs/README.md diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index d690ccb4b..8d3c56a90 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -11,17 +11,14 @@ This repository is for the WebAssembly System Interface (WASI) Subgroup of the - [proposals]: the status of each new specification proposal [charter]: Charter.md -[docs]: docs +[docs]: docs/README.md [meetings]: meetings/README.md [phases]: phases/README.md [proposals]: docs/Proposals.md [WebAssembly Community Group]: https://www.w3.org/community/webassembly/ -We'll be adding more content here before long, but for now, check out these: - - https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ - Blog post introducing WASI - - https://wasi.dev/ - Links to more information about WASI, including how to get started using it. - - https://github.com/WebAssembly/WASI/issues - This repo's issue tracker - ### Contributing -The issue tracker is the place to ask questions, make suggestions, and start discussions. +The [issue tracker] is the place to ask questions, make suggestions, and start discussions. + +[issue tracker]: https://github.com/WebAssembly/WASI/issues \ No newline at end of file diff --git a/proposals/clocks/docs/README.md b/proposals/clocks/docs/README.md new file mode 100644 index 000000000..bb6d81b25 --- /dev/null +++ b/proposals/clocks/docs/README.md @@ -0,0 +1,15 @@ +# Documentation + +WASI documentation includes: + - [Overview](WASI-overview.md): provides an introduction to WASI and its history + - [Goals](HighLevelGoals.md): a succinct list of WASI's design goals + - [Design Principles](DesignPrinciples.md): discusses details on the principles of capability-based security, scope, + POSIX/Web, etc. + - [WITX](witx.md): an introduction to the WITX specification language + - [Process](Process.md): describes how to move a WASI proposal in to the specification + - [Proposals](Proposals.md): lists the current WASI proposals by phase + +Additionally, here are some links that may be helpful in understanding WASI: + - The blog post introducing WASI: [Standardizing WASI: A system interface to run WebAssembly outside the web](https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/) + - The [wasi.dev](https://wasi.dev) web site includes links to more information about WASI, including how to get started using it + - This repository's [issue tracker](https://github.com/WebAssembly/WASI/issues) \ No newline at end of file From 47f1459b9681292fe1aa88f101c0844acad9b9c7 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Mon, 26 Oct 2020 10:58:11 -0700 Subject: [PATCH 0767/1772] Create documentation landing page As discussed in https://github.com/WebAssembly/WASI/pull/329#discussion_r505020459, this change creates a landing page explaining roughly what you get in each of the documentation pages and moves the helpful links from the main README to this page. --- proposals/random/README.md | 11 ++++------- proposals/random/docs/README.md | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 proposals/random/docs/README.md diff --git a/proposals/random/README.md b/proposals/random/README.md index d690ccb4b..8d3c56a90 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -11,17 +11,14 @@ This repository is for the WebAssembly System Interface (WASI) Subgroup of the - [proposals]: the status of each new specification proposal [charter]: Charter.md -[docs]: docs +[docs]: docs/README.md [meetings]: meetings/README.md [phases]: phases/README.md [proposals]: docs/Proposals.md [WebAssembly Community Group]: https://www.w3.org/community/webassembly/ -We'll be adding more content here before long, but for now, check out these: - - https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ - Blog post introducing WASI - - https://wasi.dev/ - Links to more information about WASI, including how to get started using it. - - https://github.com/WebAssembly/WASI/issues - This repo's issue tracker - ### Contributing -The issue tracker is the place to ask questions, make suggestions, and start discussions. +The [issue tracker] is the place to ask questions, make suggestions, and start discussions. + +[issue tracker]: https://github.com/WebAssembly/WASI/issues \ No newline at end of file diff --git a/proposals/random/docs/README.md b/proposals/random/docs/README.md new file mode 100644 index 000000000..bb6d81b25 --- /dev/null +++ b/proposals/random/docs/README.md @@ -0,0 +1,15 @@ +# Documentation + +WASI documentation includes: + - [Overview](WASI-overview.md): provides an introduction to WASI and its history + - [Goals](HighLevelGoals.md): a succinct list of WASI's design goals + - [Design Principles](DesignPrinciples.md): discusses details on the principles of capability-based security, scope, + POSIX/Web, etc. + - [WITX](witx.md): an introduction to the WITX specification language + - [Process](Process.md): describes how to move a WASI proposal in to the specification + - [Proposals](Proposals.md): lists the current WASI proposals by phase + +Additionally, here are some links that may be helpful in understanding WASI: + - The blog post introducing WASI: [Standardizing WASI: A system interface to run WebAssembly outside the web](https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/) + - The [wasi.dev](https://wasi.dev) web site includes links to more information about WASI, including how to get started using it + - This repository's [issue tracker](https://github.com/WebAssembly/WASI/issues) \ No newline at end of file From 8b1ae9cd04e4299e32e45ee5a9b9a7fc3c78856e Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Mon, 26 Oct 2020 10:58:11 -0700 Subject: [PATCH 0768/1772] Create documentation landing page As discussed in https://github.com/WebAssembly/WASI/pull/329#discussion_r505020459, this change creates a landing page explaining roughly what you get in each of the documentation pages and moves the helpful links from the main README to this page. --- proposals/filesystem/README.md | 11 ++++------- proposals/filesystem/docs/README.md | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 proposals/filesystem/docs/README.md diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index d690ccb4b..8d3c56a90 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -11,17 +11,14 @@ This repository is for the WebAssembly System Interface (WASI) Subgroup of the - [proposals]: the status of each new specification proposal [charter]: Charter.md -[docs]: docs +[docs]: docs/README.md [meetings]: meetings/README.md [phases]: phases/README.md [proposals]: docs/Proposals.md [WebAssembly Community Group]: https://www.w3.org/community/webassembly/ -We'll be adding more content here before long, but for now, check out these: - - https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ - Blog post introducing WASI - - https://wasi.dev/ - Links to more information about WASI, including how to get started using it. - - https://github.com/WebAssembly/WASI/issues - This repo's issue tracker - ### Contributing -The issue tracker is the place to ask questions, make suggestions, and start discussions. +The [issue tracker] is the place to ask questions, make suggestions, and start discussions. + +[issue tracker]: https://github.com/WebAssembly/WASI/issues \ No newline at end of file diff --git a/proposals/filesystem/docs/README.md b/proposals/filesystem/docs/README.md new file mode 100644 index 000000000..bb6d81b25 --- /dev/null +++ b/proposals/filesystem/docs/README.md @@ -0,0 +1,15 @@ +# Documentation + +WASI documentation includes: + - [Overview](WASI-overview.md): provides an introduction to WASI and its history + - [Goals](HighLevelGoals.md): a succinct list of WASI's design goals + - [Design Principles](DesignPrinciples.md): discusses details on the principles of capability-based security, scope, + POSIX/Web, etc. + - [WITX](witx.md): an introduction to the WITX specification language + - [Process](Process.md): describes how to move a WASI proposal in to the specification + - [Proposals](Proposals.md): lists the current WASI proposals by phase + +Additionally, here are some links that may be helpful in understanding WASI: + - The blog post introducing WASI: [Standardizing WASI: A system interface to run WebAssembly outside the web](https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/) + - The [wasi.dev](https://wasi.dev) web site includes links to more information about WASI, including how to get started using it + - This repository's [issue tracker](https://github.com/WebAssembly/WASI/issues) \ No newline at end of file From 7c53c1516d8c5b5177bf88bf58627eb26783272b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 30 Oct 2020 14:24:09 -0700 Subject: [PATCH 0769/1772] Add an agenda for the 11-05 meeting. --- proposals/clocks/meetings/2020/WASI-11-05.md | 37 ++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-11-05.md diff --git a/proposals/clocks/meetings/2020/WASI-11-05.md b/proposals/clocks/meetings/2020/WASI-11-05.md new file mode 100644 index 000000000..9f22ce26e --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-11-05.md @@ -0,0 +1,37 @@ +![WASI logo](/WASI.png) + +## Agenda for the November 5 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: November 5, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Update from Dan +1. Review of action items from previous meeting(s). + 1. Ralph Squillance to write up a draft on "WASI experimental" or + versioning for WASI API experimentation. +1. Removing support for `seekdir`/`telldir` from wasi-filesystem + 1. https://github.com/WebAssembly/wasi-filesystem/issues/7 +1. Filesystem Case Insensitivity + 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 + +## Meeting Notes From 57ae4741261c15ddd7b8f92cc72df332fe2a94d8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 30 Oct 2020 14:24:09 -0700 Subject: [PATCH 0770/1772] Add an agenda for the 11-05 meeting. --- proposals/random/meetings/2020/WASI-11-05.md | 37 ++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-11-05.md diff --git a/proposals/random/meetings/2020/WASI-11-05.md b/proposals/random/meetings/2020/WASI-11-05.md new file mode 100644 index 000000000..9f22ce26e --- /dev/null +++ b/proposals/random/meetings/2020/WASI-11-05.md @@ -0,0 +1,37 @@ +![WASI logo](/WASI.png) + +## Agenda for the November 5 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: November 5, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Update from Dan +1. Review of action items from previous meeting(s). + 1. Ralph Squillance to write up a draft on "WASI experimental" or + versioning for WASI API experimentation. +1. Removing support for `seekdir`/`telldir` from wasi-filesystem + 1. https://github.com/WebAssembly/wasi-filesystem/issues/7 +1. Filesystem Case Insensitivity + 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 + +## Meeting Notes From 6b84bc4d8e698ec25dcdccca93ede258367a41ac Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 30 Oct 2020 14:24:09 -0700 Subject: [PATCH 0771/1772] Add an agenda for the 11-05 meeting. --- .../filesystem/meetings/2020/WASI-11-05.md | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-11-05.md diff --git a/proposals/filesystem/meetings/2020/WASI-11-05.md b/proposals/filesystem/meetings/2020/WASI-11-05.md new file mode 100644 index 000000000..9f22ce26e --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-11-05.md @@ -0,0 +1,37 @@ +![WASI logo](/WASI.png) + +## Agenda for the November 5 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: November 5, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Dan Gohman + - Email: hello@sunfishcode.online + +### Registration + +None required if you've attended before. Email Dan Gohman to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Update from Dan +1. Review of action items from previous meeting(s). + 1. Ralph Squillance to write up a draft on "WASI experimental" or + versioning for WASI API experimentation. +1. Removing support for `seekdir`/`telldir` from wasi-filesystem + 1. https://github.com/WebAssembly/wasi-filesystem/issues/7 +1. Filesystem Case Insensitivity + 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 + +## Meeting Notes From 8aa714b86cc2a5362efa33539f3c79a4c9156788 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 18 Nov 2020 11:09:31 -0800 Subject: [PATCH 0772/1772] Add an agenda for the 11-19 meeting. This updates the agenda from 11-05 which didn't happen due to meeting logistics, and adds another link for the case insensitivity discussion. --- .../clocks/meetings/2020/{WASI-11-05.md => WASI-11-19.md} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename proposals/clocks/meetings/2020/{WASI-11-05.md => WASI-11-19.md} (86%) diff --git a/proposals/clocks/meetings/2020/WASI-11-05.md b/proposals/clocks/meetings/2020/WASI-11-19.md similarity index 86% rename from proposals/clocks/meetings/2020/WASI-11-05.md rename to proposals/clocks/meetings/2020/WASI-11-19.md index 9f22ce26e..00e407bff 100644 --- a/proposals/clocks/meetings/2020/WASI-11-05.md +++ b/proposals/clocks/meetings/2020/WASI-11-19.md @@ -1,9 +1,9 @@ ![WASI logo](/WASI.png) -## Agenda for the November 5 video call of WASI Subgroup +## Agenda for the November 19 video call of WASI Subgroup - **Where**: zoom.us -- **When**: November 5, 16:00-17:00 UTC +- **When**: November 19, 16:00-17:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Dan Gohman @@ -25,7 +25,6 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! -1. Update from Dan 1. Review of action items from previous meeting(s). 1. Ralph Squillance to write up a draft on "WASI experimental" or versioning for WASI API experimentation. @@ -33,5 +32,6 @@ Installation is required, see the calendar invite. 1. https://github.com/WebAssembly/wasi-filesystem/issues/7 1. Filesystem Case Insensitivity 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 + 1. https://github.com/nicowilliams/ietf-fs-i18n ## Meeting Notes From d8945aedfe8875c3639938f6172a84d9c756a24d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 18 Nov 2020 11:09:31 -0800 Subject: [PATCH 0773/1772] Add an agenda for the 11-19 meeting. This updates the agenda from 11-05 which didn't happen due to meeting logistics, and adds another link for the case insensitivity discussion. --- .../random/meetings/2020/{WASI-11-05.md => WASI-11-19.md} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename proposals/random/meetings/2020/{WASI-11-05.md => WASI-11-19.md} (86%) diff --git a/proposals/random/meetings/2020/WASI-11-05.md b/proposals/random/meetings/2020/WASI-11-19.md similarity index 86% rename from proposals/random/meetings/2020/WASI-11-05.md rename to proposals/random/meetings/2020/WASI-11-19.md index 9f22ce26e..00e407bff 100644 --- a/proposals/random/meetings/2020/WASI-11-05.md +++ b/proposals/random/meetings/2020/WASI-11-19.md @@ -1,9 +1,9 @@ ![WASI logo](/WASI.png) -## Agenda for the November 5 video call of WASI Subgroup +## Agenda for the November 19 video call of WASI Subgroup - **Where**: zoom.us -- **When**: November 5, 16:00-17:00 UTC +- **When**: November 19, 16:00-17:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Dan Gohman @@ -25,7 +25,6 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! -1. Update from Dan 1. Review of action items from previous meeting(s). 1. Ralph Squillance to write up a draft on "WASI experimental" or versioning for WASI API experimentation. @@ -33,5 +32,6 @@ Installation is required, see the calendar invite. 1. https://github.com/WebAssembly/wasi-filesystem/issues/7 1. Filesystem Case Insensitivity 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 + 1. https://github.com/nicowilliams/ietf-fs-i18n ## Meeting Notes From 8e79120794f28747fcfab01cb6062e30344b48a4 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 18 Nov 2020 11:09:31 -0800 Subject: [PATCH 0774/1772] Add an agenda for the 11-19 meeting. This updates the agenda from 11-05 which didn't happen due to meeting logistics, and adds another link for the case insensitivity discussion. --- .../meetings/2020/{WASI-11-05.md => WASI-11-19.md} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename proposals/filesystem/meetings/2020/{WASI-11-05.md => WASI-11-19.md} (86%) diff --git a/proposals/filesystem/meetings/2020/WASI-11-05.md b/proposals/filesystem/meetings/2020/WASI-11-19.md similarity index 86% rename from proposals/filesystem/meetings/2020/WASI-11-05.md rename to proposals/filesystem/meetings/2020/WASI-11-19.md index 9f22ce26e..00e407bff 100644 --- a/proposals/filesystem/meetings/2020/WASI-11-05.md +++ b/proposals/filesystem/meetings/2020/WASI-11-19.md @@ -1,9 +1,9 @@ ![WASI logo](/WASI.png) -## Agenda for the November 5 video call of WASI Subgroup +## Agenda for the November 19 video call of WASI Subgroup - **Where**: zoom.us -- **When**: November 5, 16:00-17:00 UTC +- **When**: November 19, 16:00-17:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Dan Gohman @@ -25,7 +25,6 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! -1. Update from Dan 1. Review of action items from previous meeting(s). 1. Ralph Squillance to write up a draft on "WASI experimental" or versioning for WASI API experimentation. @@ -33,5 +32,6 @@ Installation is required, see the calendar invite. 1. https://github.com/WebAssembly/wasi-filesystem/issues/7 1. Filesystem Case Insensitivity 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 + 1. https://github.com/nicowilliams/ietf-fs-i18n ## Meeting Notes From f6a98016d452132e42c53e44606f3014eef8f637 Mon Sep 17 00:00:00 2001 From: Mendy Berger <12537668+MendyBerger@users.noreply.github.com> Date: Sun, 22 Nov 2020 10:53:39 -0500 Subject: [PATCH 0775/1772] Updated module-types links to module-linking links (#330) --- proposals/clocks/docs/DesignPrinciples.md | 8 ++++---- proposals/clocks/docs/witx.md | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/clocks/docs/DesignPrinciples.md b/proposals/clocks/docs/DesignPrinciples.md index 064b4525e..9d0bfcedb 100644 --- a/proposals/clocks/docs/DesignPrinciples.md +++ b/proposals/clocks/docs/DesignPrinciples.md @@ -228,8 +228,8 @@ aligning with them so that we'll be ready when they are. As another example, WASI's [witx](https://github.com/WebAssembly/WASI/blob/master/docs/witx.md) file format is designed to be a -straightforward superset of the [module type -proposal](https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md)'s +straightforward superset of the [module linking +proposal](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md)'s .wit format and the [annotations proposal](https://github.com/WebAssembly/annotations/)'s annotation syntax. @@ -243,8 +243,8 @@ transparently. This can be used to adapt or attenuate the functionality of a WASI API without changing the code using it. In WASI, we envision interposition will primarily be configured -through the mechanisms in the module types' [link-time virtualization -](https://github.com/WebAssembly/module-types/blob/module-imports/proposals/module-types/Explainer.md#link-time-virtualization). +through the mechanisms in the module linking' [link-time virtualization +](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md#link-time-virtualization). Imports are resolved when a module is instantiated, which may happen during the runtime of a larger logical application, so we can support interposition of WASI APIs without defining them in terms of explicit diff --git a/proposals/clocks/docs/witx.md b/proposals/clocks/docs/witx.md index db5b5a400..9423c3f16 100644 --- a/proposals/clocks/docs/witx.md +++ b/proposals/clocks/docs/witx.md @@ -1,7 +1,7 @@ # Know your `witx` The `witx` file format is an experimental format which is based on the -[module types] text format (`wit`), (which is in turn based on the +[module linking] text format (`wit`), (which is in turn based on the [wat format], which is based on [S-expressions]). It adds some features using the same syntax as [interface types], some features with syntax similar to [gc types], as well as a few special features of its own. @@ -22,7 +22,7 @@ the goals here are to remain aligned with interface types and other relevant WebAssembly standards and proposals wherever practical, and to be an input into the design process of interface types. -[module types]: https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md +[module linking]: https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md [interface types]: https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md [gc types]: https://github.com/WebAssembly/gc [wat format]: https://webassembly.github.io/spec/core/bikeshed/index.html#text-format%E2%91%A0 From 2bf34d8423d8e1b810c3c6ee5793f27b1ce35bd3 Mon Sep 17 00:00:00 2001 From: Mendy Berger <12537668+MendyBerger@users.noreply.github.com> Date: Sun, 22 Nov 2020 10:53:39 -0500 Subject: [PATCH 0776/1772] Updated module-types links to module-linking links (#330) --- proposals/random/docs/DesignPrinciples.md | 8 ++++---- proposals/random/docs/witx.md | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/random/docs/DesignPrinciples.md b/proposals/random/docs/DesignPrinciples.md index 064b4525e..9d0bfcedb 100644 --- a/proposals/random/docs/DesignPrinciples.md +++ b/proposals/random/docs/DesignPrinciples.md @@ -228,8 +228,8 @@ aligning with them so that we'll be ready when they are. As another example, WASI's [witx](https://github.com/WebAssembly/WASI/blob/master/docs/witx.md) file format is designed to be a -straightforward superset of the [module type -proposal](https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md)'s +straightforward superset of the [module linking +proposal](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md)'s .wit format and the [annotations proposal](https://github.com/WebAssembly/annotations/)'s annotation syntax. @@ -243,8 +243,8 @@ transparently. This can be used to adapt or attenuate the functionality of a WASI API without changing the code using it. In WASI, we envision interposition will primarily be configured -through the mechanisms in the module types' [link-time virtualization -](https://github.com/WebAssembly/module-types/blob/module-imports/proposals/module-types/Explainer.md#link-time-virtualization). +through the mechanisms in the module linking' [link-time virtualization +](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md#link-time-virtualization). Imports are resolved when a module is instantiated, which may happen during the runtime of a larger logical application, so we can support interposition of WASI APIs without defining them in terms of explicit diff --git a/proposals/random/docs/witx.md b/proposals/random/docs/witx.md index db5b5a400..9423c3f16 100644 --- a/proposals/random/docs/witx.md +++ b/proposals/random/docs/witx.md @@ -1,7 +1,7 @@ # Know your `witx` The `witx` file format is an experimental format which is based on the -[module types] text format (`wit`), (which is in turn based on the +[module linking] text format (`wit`), (which is in turn based on the [wat format], which is based on [S-expressions]). It adds some features using the same syntax as [interface types], some features with syntax similar to [gc types], as well as a few special features of its own. @@ -22,7 +22,7 @@ the goals here are to remain aligned with interface types and other relevant WebAssembly standards and proposals wherever practical, and to be an input into the design process of interface types. -[module types]: https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md +[module linking]: https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md [interface types]: https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md [gc types]: https://github.com/WebAssembly/gc [wat format]: https://webassembly.github.io/spec/core/bikeshed/index.html#text-format%E2%91%A0 From 8a27c57896d039469c44322cb5479c2ecb31fddf Mon Sep 17 00:00:00 2001 From: Mendy Berger <12537668+MendyBerger@users.noreply.github.com> Date: Sun, 22 Nov 2020 10:53:39 -0500 Subject: [PATCH 0777/1772] Updated module-types links to module-linking links (#330) --- proposals/filesystem/docs/DesignPrinciples.md | 8 ++++---- proposals/filesystem/docs/witx.md | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/filesystem/docs/DesignPrinciples.md b/proposals/filesystem/docs/DesignPrinciples.md index 064b4525e..9d0bfcedb 100644 --- a/proposals/filesystem/docs/DesignPrinciples.md +++ b/proposals/filesystem/docs/DesignPrinciples.md @@ -228,8 +228,8 @@ aligning with them so that we'll be ready when they are. As another example, WASI's [witx](https://github.com/WebAssembly/WASI/blob/master/docs/witx.md) file format is designed to be a -straightforward superset of the [module type -proposal](https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md)'s +straightforward superset of the [module linking +proposal](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md)'s .wit format and the [annotations proposal](https://github.com/WebAssembly/annotations/)'s annotation syntax. @@ -243,8 +243,8 @@ transparently. This can be used to adapt or attenuate the functionality of a WASI API without changing the code using it. In WASI, we envision interposition will primarily be configured -through the mechanisms in the module types' [link-time virtualization -](https://github.com/WebAssembly/module-types/blob/module-imports/proposals/module-types/Explainer.md#link-time-virtualization). +through the mechanisms in the module linking' [link-time virtualization +](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md#link-time-virtualization). Imports are resolved when a module is instantiated, which may happen during the runtime of a larger logical application, so we can support interposition of WASI APIs without defining them in terms of explicit diff --git a/proposals/filesystem/docs/witx.md b/proposals/filesystem/docs/witx.md index db5b5a400..9423c3f16 100644 --- a/proposals/filesystem/docs/witx.md +++ b/proposals/filesystem/docs/witx.md @@ -1,7 +1,7 @@ # Know your `witx` The `witx` file format is an experimental format which is based on the -[module types] text format (`wit`), (which is in turn based on the +[module linking] text format (`wit`), (which is in turn based on the [wat format], which is based on [S-expressions]). It adds some features using the same syntax as [interface types], some features with syntax similar to [gc types], as well as a few special features of its own. @@ -22,7 +22,7 @@ the goals here are to remain aligned with interface types and other relevant WebAssembly standards and proposals wherever practical, and to be an input into the design process of interface types. -[module types]: https://github.com/WebAssembly/module-types/blob/master/proposals/module-types/Overview.md +[module linking]: https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md [interface types]: https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md [gc types]: https://github.com/WebAssembly/gc [wat format]: https://webassembly.github.io/spec/core/bikeshed/index.html#text-format%E2%91%A0 From ac8b432e1ac0c8cc9ac9895a1ecd1d632fc599d9 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 23 Nov 2020 19:25:40 -0500 Subject: [PATCH 0778/1772] Add 11-19 meeting notes (#354) --- proposals/clocks/meetings/2020/WASI-11-19.md | 116 +++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/proposals/clocks/meetings/2020/WASI-11-19.md b/proposals/clocks/meetings/2020/WASI-11-19.md index 00e407bff..c9d6a819b 100644 --- a/proposals/clocks/meetings/2020/WASI-11-19.md +++ b/proposals/clocks/meetings/2020/WASI-11-19.md @@ -35,3 +35,119 @@ Installation is required, see the calendar invite. 1. https://github.com/nicowilliams/ietf-fs-i18n ## Meeting Notes + +### Attendees +- Peter Huene +- Sam Clegg (SC) +- Lin Clark (LC) +- Andrew Brown +- Dan Gohman (DG) +- Sergey Rubanov +- Syrus Akbary (SA) +- Matt Fisher +- Eric Rosenberg +- Ralph Squillace (RS) +- Till Schneidereit (TS) +- Harun Oz +- Pat Hickey (PH) + +### Action Items from Last Week +RS: had conversation with Pat and Dan about how people are testing out experimental proposals. Pretty obv that we wanted to use these experiments for inputs. At same time, second issue was wanting to be very clear that none of the experiments were destined to the spec + +Wanted people to be able to play with sockets in Krustlet. Dan proposed creating an experimental namespace. Ralph will now begin tackling the doc. Will talk with Fastly about how they are handling exp. + +DG: need standard convention for naming + +SC: Are you talking about system level imports? + +DG: We have wasi_ naming convention. Should be a naming convention for things not in snapshot yet + +RS: That makes sense. Explicitly not destined to be migrated. Signal that these are things to be used as ways of stimulating thought. Kind of a firewall between these and what’s going into the spec. + +DG: One additional thing—some prior art wrt web standards e.g. vendor prefixes. We can probably avoid + +SC: How would we avoid. By not shipping prod VMs with them enabled? + +DG: Yes, or behind flags + +TS: Situation might become slightly different once module linking and ability to virtualize comes in. Then you could say you don’t need to ship as long as you provide a shim implemented in user space + +SC: presumably not the module name + +PH: unfortunate that there’s only one name + +DG: Module linking has concept of nested modules. Might be useful + +PH: That’s used for definitions but not for imports. + +SC: You can chain imports + +TS: IIRC you have to re-export + +DG: typically you do, but … if we don’t have this, then mangling + +PH: we need this before module linking lands in any toolchain. + +From chat: +wasi_experimental_tests? +wasi_experimental_temp? +From Pat Hickey to Everyone: 12:16 PM +wasi_experimental_ for a mangling scheme + +**ACTION ITEM: Ralph will compile doc** + +### Removing support for seekdir/telldir from wasi-filesystem + +DG: from days when OSs used flat lists. Now they are BTrees. These have become awkward abstractions. + +DG: want to remove from WASI altogether. Can’t do a 64 bit seekdir. In order to satisfy POSIX, we’d need to do some complicated indirection. Theoretically possible, but think better to remove altogether. + +SC: Proposal is just to remove, not emulate in user space? + +DG: I don’t think it’s worth it unless use case + +SA: Don’t have context, but what do you think wouldn’t be possible? + +DG: ls will work. This is why I’m asking whether anyone has heard of someone using this. Scan through, then restart from beginning, and then keep going is pretty rare. This originated when it was hard to keep file in memory at same time + +RS: What’s request? Could potentially search GitHub. There are tools + +DG: Found a million hits in code, a lot are libc code + +SC: Yeah, we’ll need to skip headers and impls + +TS: Have experience from TC39. People have tried to use as code search, but there’s quite a lot more dark matter that’s not in public repos, and also test suites are copied all over place and not ways to exclude. Perhaps possible to do regex to exclude + +RS: Both MS and GitHub have internal tools for this. GH is strongly motivated to make this work. If we can write a user story that’s in the sweet spot, I will see what can be done as a feature, either privately or as a preview test, or ultimately as a public feature + +DG: That feature would be really useful for other questions too + +RS: I do need a user story to pursue in an aggressive way, but I think they actively want user stories. + +DG: WASI libc is already trying to guess what you’ll need. + +RS: Side issue—feature set is that we want to know what the community is using. + +DG: Roughly the plan for removal is to remove from libc. Second step is to remove from WASI itself, removing parameter and introducing rewind call + +**ACTION ITEM: Ralph will use internal tool to search for use** +**(possible) ACTION ITEM: Put together user story for feature that would allow WASI SG to search for usage of other APIs** + +### Filesystem Case Insensitivity + +DG: GitHub repos and offline chatting. ONe question, what is the goal of the ___ API Fully deterministic? Will behave same way across all platforms. + +DG: People want to access existing files that already have their own restrictions. Hard to abstract away. If we can assume WASI runtime owns filesystem, could do a lot, but if we assume you have your own files, we have to pass it on to applications. Somewhat unfortunate, but after a lot of discussion think we’re going non-deterministic. Best we can do is good debugging tools. Those wouldn’t be part of the spec, just side debugging tools. Disappointing from the Wasm perspective, where we try to be deterministic. Not within our power at the WASI level to choose one side + +DG: Also want to mention, link in meeting notes that will hopefully turn into an IETF proposal that will define portable semantics + +### Additional Questions + +SA: One quick question. What do you want me to do with the logo + +DG: Researching IP rules + +LC: I can help with this and serve as point of contact + +SA: Lmk if you need changes to the PR + From b147562b2940094a4d5558a9f05e1b8faf7273f0 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 23 Nov 2020 19:25:40 -0500 Subject: [PATCH 0779/1772] Add 11-19 meeting notes (#354) --- proposals/random/meetings/2020/WASI-11-19.md | 116 +++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/proposals/random/meetings/2020/WASI-11-19.md b/proposals/random/meetings/2020/WASI-11-19.md index 00e407bff..c9d6a819b 100644 --- a/proposals/random/meetings/2020/WASI-11-19.md +++ b/proposals/random/meetings/2020/WASI-11-19.md @@ -35,3 +35,119 @@ Installation is required, see the calendar invite. 1. https://github.com/nicowilliams/ietf-fs-i18n ## Meeting Notes + +### Attendees +- Peter Huene +- Sam Clegg (SC) +- Lin Clark (LC) +- Andrew Brown +- Dan Gohman (DG) +- Sergey Rubanov +- Syrus Akbary (SA) +- Matt Fisher +- Eric Rosenberg +- Ralph Squillace (RS) +- Till Schneidereit (TS) +- Harun Oz +- Pat Hickey (PH) + +### Action Items from Last Week +RS: had conversation with Pat and Dan about how people are testing out experimental proposals. Pretty obv that we wanted to use these experiments for inputs. At same time, second issue was wanting to be very clear that none of the experiments were destined to the spec + +Wanted people to be able to play with sockets in Krustlet. Dan proposed creating an experimental namespace. Ralph will now begin tackling the doc. Will talk with Fastly about how they are handling exp. + +DG: need standard convention for naming + +SC: Are you talking about system level imports? + +DG: We have wasi_ naming convention. Should be a naming convention for things not in snapshot yet + +RS: That makes sense. Explicitly not destined to be migrated. Signal that these are things to be used as ways of stimulating thought. Kind of a firewall between these and what’s going into the spec. + +DG: One additional thing—some prior art wrt web standards e.g. vendor prefixes. We can probably avoid + +SC: How would we avoid. By not shipping prod VMs with them enabled? + +DG: Yes, or behind flags + +TS: Situation might become slightly different once module linking and ability to virtualize comes in. Then you could say you don’t need to ship as long as you provide a shim implemented in user space + +SC: presumably not the module name + +PH: unfortunate that there’s only one name + +DG: Module linking has concept of nested modules. Might be useful + +PH: That’s used for definitions but not for imports. + +SC: You can chain imports + +TS: IIRC you have to re-export + +DG: typically you do, but … if we don’t have this, then mangling + +PH: we need this before module linking lands in any toolchain. + +From chat: +wasi_experimental_tests? +wasi_experimental_temp? +From Pat Hickey to Everyone: 12:16 PM +wasi_experimental_ for a mangling scheme + +**ACTION ITEM: Ralph will compile doc** + +### Removing support for seekdir/telldir from wasi-filesystem + +DG: from days when OSs used flat lists. Now they are BTrees. These have become awkward abstractions. + +DG: want to remove from WASI altogether. Can’t do a 64 bit seekdir. In order to satisfy POSIX, we’d need to do some complicated indirection. Theoretically possible, but think better to remove altogether. + +SC: Proposal is just to remove, not emulate in user space? + +DG: I don’t think it’s worth it unless use case + +SA: Don’t have context, but what do you think wouldn’t be possible? + +DG: ls will work. This is why I’m asking whether anyone has heard of someone using this. Scan through, then restart from beginning, and then keep going is pretty rare. This originated when it was hard to keep file in memory at same time + +RS: What’s request? Could potentially search GitHub. There are tools + +DG: Found a million hits in code, a lot are libc code + +SC: Yeah, we’ll need to skip headers and impls + +TS: Have experience from TC39. People have tried to use as code search, but there’s quite a lot more dark matter that’s not in public repos, and also test suites are copied all over place and not ways to exclude. Perhaps possible to do regex to exclude + +RS: Both MS and GitHub have internal tools for this. GH is strongly motivated to make this work. If we can write a user story that’s in the sweet spot, I will see what can be done as a feature, either privately or as a preview test, or ultimately as a public feature + +DG: That feature would be really useful for other questions too + +RS: I do need a user story to pursue in an aggressive way, but I think they actively want user stories. + +DG: WASI libc is already trying to guess what you’ll need. + +RS: Side issue—feature set is that we want to know what the community is using. + +DG: Roughly the plan for removal is to remove from libc. Second step is to remove from WASI itself, removing parameter and introducing rewind call + +**ACTION ITEM: Ralph will use internal tool to search for use** +**(possible) ACTION ITEM: Put together user story for feature that would allow WASI SG to search for usage of other APIs** + +### Filesystem Case Insensitivity + +DG: GitHub repos and offline chatting. ONe question, what is the goal of the ___ API Fully deterministic? Will behave same way across all platforms. + +DG: People want to access existing files that already have their own restrictions. Hard to abstract away. If we can assume WASI runtime owns filesystem, could do a lot, but if we assume you have your own files, we have to pass it on to applications. Somewhat unfortunate, but after a lot of discussion think we’re going non-deterministic. Best we can do is good debugging tools. Those wouldn’t be part of the spec, just side debugging tools. Disappointing from the Wasm perspective, where we try to be deterministic. Not within our power at the WASI level to choose one side + +DG: Also want to mention, link in meeting notes that will hopefully turn into an IETF proposal that will define portable semantics + +### Additional Questions + +SA: One quick question. What do you want me to do with the logo + +DG: Researching IP rules + +LC: I can help with this and serve as point of contact + +SA: Lmk if you need changes to the PR + From 48830682e81f4cb9d52db6aa51ea876d2324fa41 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 23 Nov 2020 19:25:40 -0500 Subject: [PATCH 0780/1772] Add 11-19 meeting notes (#354) --- .../filesystem/meetings/2020/WASI-11-19.md | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/proposals/filesystem/meetings/2020/WASI-11-19.md b/proposals/filesystem/meetings/2020/WASI-11-19.md index 00e407bff..c9d6a819b 100644 --- a/proposals/filesystem/meetings/2020/WASI-11-19.md +++ b/proposals/filesystem/meetings/2020/WASI-11-19.md @@ -35,3 +35,119 @@ Installation is required, see the calendar invite. 1. https://github.com/nicowilliams/ietf-fs-i18n ## Meeting Notes + +### Attendees +- Peter Huene +- Sam Clegg (SC) +- Lin Clark (LC) +- Andrew Brown +- Dan Gohman (DG) +- Sergey Rubanov +- Syrus Akbary (SA) +- Matt Fisher +- Eric Rosenberg +- Ralph Squillace (RS) +- Till Schneidereit (TS) +- Harun Oz +- Pat Hickey (PH) + +### Action Items from Last Week +RS: had conversation with Pat and Dan about how people are testing out experimental proposals. Pretty obv that we wanted to use these experiments for inputs. At same time, second issue was wanting to be very clear that none of the experiments were destined to the spec + +Wanted people to be able to play with sockets in Krustlet. Dan proposed creating an experimental namespace. Ralph will now begin tackling the doc. Will talk with Fastly about how they are handling exp. + +DG: need standard convention for naming + +SC: Are you talking about system level imports? + +DG: We have wasi_ naming convention. Should be a naming convention for things not in snapshot yet + +RS: That makes sense. Explicitly not destined to be migrated. Signal that these are things to be used as ways of stimulating thought. Kind of a firewall between these and what’s going into the spec. + +DG: One additional thing—some prior art wrt web standards e.g. vendor prefixes. We can probably avoid + +SC: How would we avoid. By not shipping prod VMs with them enabled? + +DG: Yes, or behind flags + +TS: Situation might become slightly different once module linking and ability to virtualize comes in. Then you could say you don’t need to ship as long as you provide a shim implemented in user space + +SC: presumably not the module name + +PH: unfortunate that there’s only one name + +DG: Module linking has concept of nested modules. Might be useful + +PH: That’s used for definitions but not for imports. + +SC: You can chain imports + +TS: IIRC you have to re-export + +DG: typically you do, but … if we don’t have this, then mangling + +PH: we need this before module linking lands in any toolchain. + +From chat: +wasi_experimental_tests? +wasi_experimental_temp? +From Pat Hickey to Everyone: 12:16 PM +wasi_experimental_ for a mangling scheme + +**ACTION ITEM: Ralph will compile doc** + +### Removing support for seekdir/telldir from wasi-filesystem + +DG: from days when OSs used flat lists. Now they are BTrees. These have become awkward abstractions. + +DG: want to remove from WASI altogether. Can’t do a 64 bit seekdir. In order to satisfy POSIX, we’d need to do some complicated indirection. Theoretically possible, but think better to remove altogether. + +SC: Proposal is just to remove, not emulate in user space? + +DG: I don’t think it’s worth it unless use case + +SA: Don’t have context, but what do you think wouldn’t be possible? + +DG: ls will work. This is why I’m asking whether anyone has heard of someone using this. Scan through, then restart from beginning, and then keep going is pretty rare. This originated when it was hard to keep file in memory at same time + +RS: What’s request? Could potentially search GitHub. There are tools + +DG: Found a million hits in code, a lot are libc code + +SC: Yeah, we’ll need to skip headers and impls + +TS: Have experience from TC39. People have tried to use as code search, but there’s quite a lot more dark matter that’s not in public repos, and also test suites are copied all over place and not ways to exclude. Perhaps possible to do regex to exclude + +RS: Both MS and GitHub have internal tools for this. GH is strongly motivated to make this work. If we can write a user story that’s in the sweet spot, I will see what can be done as a feature, either privately or as a preview test, or ultimately as a public feature + +DG: That feature would be really useful for other questions too + +RS: I do need a user story to pursue in an aggressive way, but I think they actively want user stories. + +DG: WASI libc is already trying to guess what you’ll need. + +RS: Side issue—feature set is that we want to know what the community is using. + +DG: Roughly the plan for removal is to remove from libc. Second step is to remove from WASI itself, removing parameter and introducing rewind call + +**ACTION ITEM: Ralph will use internal tool to search for use** +**(possible) ACTION ITEM: Put together user story for feature that would allow WASI SG to search for usage of other APIs** + +### Filesystem Case Insensitivity + +DG: GitHub repos and offline chatting. ONe question, what is the goal of the ___ API Fully deterministic? Will behave same way across all platforms. + +DG: People want to access existing files that already have their own restrictions. Hard to abstract away. If we can assume WASI runtime owns filesystem, could do a lot, but if we assume you have your own files, we have to pass it on to applications. Somewhat unfortunate, but after a lot of discussion think we’re going non-deterministic. Best we can do is good debugging tools. Those wouldn’t be part of the spec, just side debugging tools. Disappointing from the Wasm perspective, where we try to be deterministic. Not within our power at the WASI level to choose one side + +DG: Also want to mention, link in meeting notes that will hopefully turn into an IETF proposal that will define portable semantics + +### Additional Questions + +SA: One quick question. What do you want me to do with the logo + +DG: Researching IP rules + +LC: I can help with this and serve as point of contact + +SA: Lmk if you need changes to the PR + From 75bd25497202b7c7b4b6e56c04a50f33eb41432f Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 23 Nov 2020 19:26:12 -0500 Subject: [PATCH 0781/1772] Add an agenda for the 12-03 meeting. (#355) --- proposals/clocks/meetings/2020/WASI-12-03.md | 33 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 2 ++ 2 files changed, 35 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-12-03.md diff --git a/proposals/clocks/meetings/2020/WASI-12-03.md b/proposals/clocks/meetings/2020/WASI-12-03.md new file mode 100644 index 000000000..21f9acb89 --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-12-03.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the December 3 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: December 3, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Review of action items from previous meeting(s). + 1. Ralph Squillace to write up a draft on "WASI experimental" or versioning for WASI API experimentation. + 1. Ralph Squillace report on search for seekdir/telldir across GitHub codebases. +1. *Submit a PR to add your item here* + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 3b4adaabe..1475d27b2 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -42,3 +42,5 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI September 21st video call](2020/WASI-09-21.md) * [WASI October 8th video call](2020/WASI-10-08.md) * [WASI October 22nd video call](2020/WASI-10-22.md) + * [WASI November 19th video call](2020/WASI-11-19.md) + * [WASI December 3rd video call](2020/WASI-12-03.md) From 916b8939c82968d005c3775e6091c1008c85c060 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 23 Nov 2020 19:26:12 -0500 Subject: [PATCH 0782/1772] Add an agenda for the 12-03 meeting. (#355) --- proposals/random/meetings/2020/WASI-12-03.md | 33 ++++++++++++++++++++ proposals/random/meetings/README.md | 2 ++ 2 files changed, 35 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-12-03.md diff --git a/proposals/random/meetings/2020/WASI-12-03.md b/proposals/random/meetings/2020/WASI-12-03.md new file mode 100644 index 000000000..21f9acb89 --- /dev/null +++ b/proposals/random/meetings/2020/WASI-12-03.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the December 3 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: December 3, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Review of action items from previous meeting(s). + 1. Ralph Squillace to write up a draft on "WASI experimental" or versioning for WASI API experimentation. + 1. Ralph Squillace report on search for seekdir/telldir across GitHub codebases. +1. *Submit a PR to add your item here* + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 3b4adaabe..1475d27b2 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -42,3 +42,5 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI September 21st video call](2020/WASI-09-21.md) * [WASI October 8th video call](2020/WASI-10-08.md) * [WASI October 22nd video call](2020/WASI-10-22.md) + * [WASI November 19th video call](2020/WASI-11-19.md) + * [WASI December 3rd video call](2020/WASI-12-03.md) From 087582a175fba8222834ae0daac178b615cc851a Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 23 Nov 2020 19:26:12 -0500 Subject: [PATCH 0783/1772] Add an agenda for the 12-03 meeting. (#355) --- .../filesystem/meetings/2020/WASI-12-03.md | 33 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 2 ++ 2 files changed, 35 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-12-03.md diff --git a/proposals/filesystem/meetings/2020/WASI-12-03.md b/proposals/filesystem/meetings/2020/WASI-12-03.md new file mode 100644 index 000000000..21f9acb89 --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-12-03.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the December 3 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: December 3, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Review of action items from previous meeting(s). + 1. Ralph Squillace to write up a draft on "WASI experimental" or versioning for WASI API experimentation. + 1. Ralph Squillace report on search for seekdir/telldir across GitHub codebases. +1. *Submit a PR to add your item here* + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 3b4adaabe..1475d27b2 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -42,3 +42,5 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI September 21st video call](2020/WASI-09-21.md) * [WASI October 8th video call](2020/WASI-10-08.md) * [WASI October 22nd video call](2020/WASI-10-22.md) + * [WASI November 19th video call](2020/WASI-11-19.md) + * [WASI December 3rd video call](2020/WASI-12-03.md) From 4941bf3ea9672dd916b7483d8c6788da5393426d Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 30 Nov 2020 11:08:57 -0800 Subject: [PATCH 0784/1772] witx: remove supertypes from the handle type (#358) the idea here was to enable handles to have a subtyping hierarchy, but this isnt compatible with wasm extern refs and we never used it anywhere, so its safe to delete all this code. --- proposals/clocks/tools/witx/src/ast.rs | 4 +-- proposals/clocks/tools/witx/src/parser.rs | 14 +++----- proposals/clocks/tools/witx/src/render.rs | 8 +---- .../clocks/tools/witx/src/representation.rs | 34 ++---------------- proposals/clocks/tools/witx/src/validate.rs | 36 ++----------------- 5 files changed, 11 insertions(+), 85 deletions(-) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 1e1981f66..2e30836b1 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -295,9 +295,7 @@ pub struct UnionVariant { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct HandleDatatype { - pub supertypes: Vec, -} +pub struct HandleDatatype {} #[derive(Debug, Clone)] pub struct Module { diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index be0cb31e1..5ff66828e 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -274,7 +274,7 @@ pub enum TypedefSyntax<'a> { Flags(FlagsSyntax<'a>), Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), - Handle(HandleSyntax<'a>), + Handle(HandleSyntax), Array(Box>), Pointer(Box>), ConstPointer(Box>), @@ -485,18 +485,12 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct HandleSyntax<'a> { - pub supertypes: Vec>, -} +pub struct HandleSyntax {} -impl<'a> Parse<'a> for HandleSyntax<'a> { +impl<'a> Parse<'a> for HandleSyntax { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let mut supertypes = Vec::new(); - while !parser.is_empty() { - supertypes.push(parser.parse()?); - } - Ok(HandleSyntax { supertypes }) + Ok(HandleSyntax {}) } } diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 64b429f8b..f83e561b7 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -234,13 +234,7 @@ impl UnionDatatype { impl HandleDatatype { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("handle")]; - let supertypes = self - .supertypes - .iter() - .map(|s| s.to_sexpr()) - .collect::>(); - SExpr::Vec([header, supertypes].concat()) + SExpr::Vec(vec![SExpr::word("handle")]) } } impl IntRepr { diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs index 0f12217af..2a52fc69b 100644 --- a/proposals/clocks/tools/witx/src/representation.rs +++ b/proposals/clocks/tools/witx/src/representation.rs @@ -1,6 +1,6 @@ use crate::{ - BuiltinType, EnumDatatype, FlagsDatatype, HandleDatatype, IntRepr, NamedType, StructDatatype, - Type, TypeRef, UnionDatatype, + BuiltinType, EnumDatatype, FlagsDatatype, IntRepr, NamedType, StructDatatype, Type, TypeRef, + UnionDatatype, }; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. @@ -117,34 +117,6 @@ impl Representable for FlagsDatatype { } } -impl Representable for HandleDatatype { - fn representable(&self, by: &Self) -> RepEquality { - // Handles must have the same set of named supertypes. Anonymous supertypes are never - // equal, and the validator should probably make sure these are not allowed, because - // what would that even mean?? - for supertype_ref in self.supertypes.iter() { - match supertype_ref { - TypeRef::Name(nt) => { - if let Some(by_nt) = by.supertypes.iter().find_map(|tref| match tref { - TypeRef::Name(by_nt) if by_nt.name == nt.name => Some(by_nt), - _ => None, - }) { - if nt.tref.representable(&by_nt.tref) == RepEquality::NotEq { - return RepEquality::NotEq; - } - } else { - return RepEquality::NotEq; - } - } - TypeRef::Value(_) => { - return RepEquality::NotEq; - } - } - } - RepEquality::Eq - } -} - impl Representable for StructDatatype { fn representable(&self, by: &Self) -> RepEquality { // Structs must have exact structural equality - same members, must @@ -235,7 +207,7 @@ impl Representable for Type { (Type::Flags(s), Type::Flags(b)) => s.representable(b), (Type::Struct(s), Type::Struct(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), - (Type::Handle(s), Type::Handle(b)) => s.representable(b), + (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural (Type::Array(s), Type::Array(b)) => s.representable(b), (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 17be21e82..c4c5589e4 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -454,42 +454,10 @@ impl DocValidationScope<'_> { fn validate_handle( &self, - syntax: &HandleSyntax, + _syntax: &HandleSyntax, _span: wast::Span, ) -> Result { - let supertypes = syntax - .supertypes - .iter() - .map(|id_syntax| { - let id = self.get(&id_syntax)?; - match self.doc.entries.get(&id) { - Some(Entry::Typename(weak_ref)) => { - let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); - match &*named_dt.type_() { - Type::Handle { .. } => Ok(TypeRef::Name(named_dt)), - other => Err(ValidationError::WrongKindName { - name: id_syntax.name().to_string(), - location: self.location(id_syntax.span()), - expected: "handle", - got: other.kind(), - }), - } - } - Some(entry) => Err(ValidationError::WrongKindName { - name: id_syntax.name().to_string(), - location: self.location(id_syntax.span()), - expected: "handle", - got: entry.kind(), - }), - None => Err(ValidationError::Recursive { - name: id_syntax.name().to_string(), - location: self.location(id_syntax.span()), - }), - } - }) - .collect::, _>>()?; - - Ok(HandleDatatype { supertypes }) + Ok(HandleDatatype {}) } fn validate_int_repr( From b726e3f4d172c4f9a6baa9838c825b6d071e8ae5 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 30 Nov 2020 11:08:57 -0800 Subject: [PATCH 0785/1772] witx: remove supertypes from the handle type (#358) the idea here was to enable handles to have a subtyping hierarchy, but this isnt compatible with wasm extern refs and we never used it anywhere, so its safe to delete all this code. --- proposals/random/tools/witx/src/ast.rs | 4 +-- proposals/random/tools/witx/src/parser.rs | 14 +++----- proposals/random/tools/witx/src/render.rs | 8 +---- .../random/tools/witx/src/representation.rs | 34 ++---------------- proposals/random/tools/witx/src/validate.rs | 36 ++----------------- 5 files changed, 11 insertions(+), 85 deletions(-) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 1e1981f66..2e30836b1 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -295,9 +295,7 @@ pub struct UnionVariant { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct HandleDatatype { - pub supertypes: Vec, -} +pub struct HandleDatatype {} #[derive(Debug, Clone)] pub struct Module { diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index be0cb31e1..5ff66828e 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -274,7 +274,7 @@ pub enum TypedefSyntax<'a> { Flags(FlagsSyntax<'a>), Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), - Handle(HandleSyntax<'a>), + Handle(HandleSyntax), Array(Box>), Pointer(Box>), ConstPointer(Box>), @@ -485,18 +485,12 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct HandleSyntax<'a> { - pub supertypes: Vec>, -} +pub struct HandleSyntax {} -impl<'a> Parse<'a> for HandleSyntax<'a> { +impl<'a> Parse<'a> for HandleSyntax { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let mut supertypes = Vec::new(); - while !parser.is_empty() { - supertypes.push(parser.parse()?); - } - Ok(HandleSyntax { supertypes }) + Ok(HandleSyntax {}) } } diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 64b429f8b..f83e561b7 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -234,13 +234,7 @@ impl UnionDatatype { impl HandleDatatype { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("handle")]; - let supertypes = self - .supertypes - .iter() - .map(|s| s.to_sexpr()) - .collect::>(); - SExpr::Vec([header, supertypes].concat()) + SExpr::Vec(vec![SExpr::word("handle")]) } } impl IntRepr { diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs index 0f12217af..2a52fc69b 100644 --- a/proposals/random/tools/witx/src/representation.rs +++ b/proposals/random/tools/witx/src/representation.rs @@ -1,6 +1,6 @@ use crate::{ - BuiltinType, EnumDatatype, FlagsDatatype, HandleDatatype, IntRepr, NamedType, StructDatatype, - Type, TypeRef, UnionDatatype, + BuiltinType, EnumDatatype, FlagsDatatype, IntRepr, NamedType, StructDatatype, Type, TypeRef, + UnionDatatype, }; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. @@ -117,34 +117,6 @@ impl Representable for FlagsDatatype { } } -impl Representable for HandleDatatype { - fn representable(&self, by: &Self) -> RepEquality { - // Handles must have the same set of named supertypes. Anonymous supertypes are never - // equal, and the validator should probably make sure these are not allowed, because - // what would that even mean?? - for supertype_ref in self.supertypes.iter() { - match supertype_ref { - TypeRef::Name(nt) => { - if let Some(by_nt) = by.supertypes.iter().find_map(|tref| match tref { - TypeRef::Name(by_nt) if by_nt.name == nt.name => Some(by_nt), - _ => None, - }) { - if nt.tref.representable(&by_nt.tref) == RepEquality::NotEq { - return RepEquality::NotEq; - } - } else { - return RepEquality::NotEq; - } - } - TypeRef::Value(_) => { - return RepEquality::NotEq; - } - } - } - RepEquality::Eq - } -} - impl Representable for StructDatatype { fn representable(&self, by: &Self) -> RepEquality { // Structs must have exact structural equality - same members, must @@ -235,7 +207,7 @@ impl Representable for Type { (Type::Flags(s), Type::Flags(b)) => s.representable(b), (Type::Struct(s), Type::Struct(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), - (Type::Handle(s), Type::Handle(b)) => s.representable(b), + (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural (Type::Array(s), Type::Array(b)) => s.representable(b), (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 17be21e82..c4c5589e4 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -454,42 +454,10 @@ impl DocValidationScope<'_> { fn validate_handle( &self, - syntax: &HandleSyntax, + _syntax: &HandleSyntax, _span: wast::Span, ) -> Result { - let supertypes = syntax - .supertypes - .iter() - .map(|id_syntax| { - let id = self.get(&id_syntax)?; - match self.doc.entries.get(&id) { - Some(Entry::Typename(weak_ref)) => { - let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); - match &*named_dt.type_() { - Type::Handle { .. } => Ok(TypeRef::Name(named_dt)), - other => Err(ValidationError::WrongKindName { - name: id_syntax.name().to_string(), - location: self.location(id_syntax.span()), - expected: "handle", - got: other.kind(), - }), - } - } - Some(entry) => Err(ValidationError::WrongKindName { - name: id_syntax.name().to_string(), - location: self.location(id_syntax.span()), - expected: "handle", - got: entry.kind(), - }), - None => Err(ValidationError::Recursive { - name: id_syntax.name().to_string(), - location: self.location(id_syntax.span()), - }), - } - }) - .collect::, _>>()?; - - Ok(HandleDatatype { supertypes }) + Ok(HandleDatatype {}) } fn validate_int_repr( From 370715bc8e52fe4e4c9c7c48522591f8be89407a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 30 Nov 2020 11:08:57 -0800 Subject: [PATCH 0786/1772] witx: remove supertypes from the handle type (#358) the idea here was to enable handles to have a subtyping hierarchy, but this isnt compatible with wasm extern refs and we never used it anywhere, so its safe to delete all this code. --- proposals/filesystem/tools/witx/src/ast.rs | 4 +-- proposals/filesystem/tools/witx/src/parser.rs | 14 +++----- proposals/filesystem/tools/witx/src/render.rs | 8 +---- .../tools/witx/src/representation.rs | 34 ++---------------- .../filesystem/tools/witx/src/validate.rs | 36 ++----------------- 5 files changed, 11 insertions(+), 85 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 1e1981f66..2e30836b1 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -295,9 +295,7 @@ pub struct UnionVariant { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct HandleDatatype { - pub supertypes: Vec, -} +pub struct HandleDatatype {} #[derive(Debug, Clone)] pub struct Module { diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index be0cb31e1..5ff66828e 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -274,7 +274,7 @@ pub enum TypedefSyntax<'a> { Flags(FlagsSyntax<'a>), Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), - Handle(HandleSyntax<'a>), + Handle(HandleSyntax), Array(Box>), Pointer(Box>), ConstPointer(Box>), @@ -485,18 +485,12 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct HandleSyntax<'a> { - pub supertypes: Vec>, -} +pub struct HandleSyntax {} -impl<'a> Parse<'a> for HandleSyntax<'a> { +impl<'a> Parse<'a> for HandleSyntax { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let mut supertypes = Vec::new(); - while !parser.is_empty() { - supertypes.push(parser.parse()?); - } - Ok(HandleSyntax { supertypes }) + Ok(HandleSyntax {}) } } diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 64b429f8b..f83e561b7 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -234,13 +234,7 @@ impl UnionDatatype { impl HandleDatatype { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("handle")]; - let supertypes = self - .supertypes - .iter() - .map(|s| s.to_sexpr()) - .collect::>(); - SExpr::Vec([header, supertypes].concat()) + SExpr::Vec(vec![SExpr::word("handle")]) } } impl IntRepr { diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs index 0f12217af..2a52fc69b 100644 --- a/proposals/filesystem/tools/witx/src/representation.rs +++ b/proposals/filesystem/tools/witx/src/representation.rs @@ -1,6 +1,6 @@ use crate::{ - BuiltinType, EnumDatatype, FlagsDatatype, HandleDatatype, IntRepr, NamedType, StructDatatype, - Type, TypeRef, UnionDatatype, + BuiltinType, EnumDatatype, FlagsDatatype, IntRepr, NamedType, StructDatatype, Type, TypeRef, + UnionDatatype, }; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. @@ -117,34 +117,6 @@ impl Representable for FlagsDatatype { } } -impl Representable for HandleDatatype { - fn representable(&self, by: &Self) -> RepEquality { - // Handles must have the same set of named supertypes. Anonymous supertypes are never - // equal, and the validator should probably make sure these are not allowed, because - // what would that even mean?? - for supertype_ref in self.supertypes.iter() { - match supertype_ref { - TypeRef::Name(nt) => { - if let Some(by_nt) = by.supertypes.iter().find_map(|tref| match tref { - TypeRef::Name(by_nt) if by_nt.name == nt.name => Some(by_nt), - _ => None, - }) { - if nt.tref.representable(&by_nt.tref) == RepEquality::NotEq { - return RepEquality::NotEq; - } - } else { - return RepEquality::NotEq; - } - } - TypeRef::Value(_) => { - return RepEquality::NotEq; - } - } - } - RepEquality::Eq - } -} - impl Representable for StructDatatype { fn representable(&self, by: &Self) -> RepEquality { // Structs must have exact structural equality - same members, must @@ -235,7 +207,7 @@ impl Representable for Type { (Type::Flags(s), Type::Flags(b)) => s.representable(b), (Type::Struct(s), Type::Struct(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), - (Type::Handle(s), Type::Handle(b)) => s.representable(b), + (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural (Type::Array(s), Type::Array(b)) => s.representable(b), (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 17be21e82..c4c5589e4 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -454,42 +454,10 @@ impl DocValidationScope<'_> { fn validate_handle( &self, - syntax: &HandleSyntax, + _syntax: &HandleSyntax, _span: wast::Span, ) -> Result { - let supertypes = syntax - .supertypes - .iter() - .map(|id_syntax| { - let id = self.get(&id_syntax)?; - match self.doc.entries.get(&id) { - Some(Entry::Typename(weak_ref)) => { - let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); - match &*named_dt.type_() { - Type::Handle { .. } => Ok(TypeRef::Name(named_dt)), - other => Err(ValidationError::WrongKindName { - name: id_syntax.name().to_string(), - location: self.location(id_syntax.span()), - expected: "handle", - got: other.kind(), - }), - } - } - Some(entry) => Err(ValidationError::WrongKindName { - name: id_syntax.name().to_string(), - location: self.location(id_syntax.span()), - expected: "handle", - got: entry.kind(), - }), - None => Err(ValidationError::Recursive { - name: id_syntax.name().to_string(), - location: self.location(id_syntax.span()), - }), - } - }) - .collect::, _>>()?; - - Ok(HandleDatatype { supertypes }) + Ok(HandleDatatype {}) } fn validate_int_repr( From 0f8f0ac008428abef3abf37b293389defe979bbb Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Wed, 2 Dec 2020 19:04:26 -0500 Subject: [PATCH 0787/1772] Add agenda items for 12-03 meeting (#361) --- proposals/clocks/meetings/2020/WASI-12-03.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/meetings/2020/WASI-12-03.md b/proposals/clocks/meetings/2020/WASI-12-03.md index 21f9acb89..cc6261428 100644 --- a/proposals/clocks/meetings/2020/WASI-12-03.md +++ b/proposals/clocks/meetings/2020/WASI-12-03.md @@ -27,7 +27,8 @@ Installation is required, see the calendar invite. 1. Thanks! 1. Review of action items from previous meeting(s). 1. Ralph Squillace to write up a draft on "WASI experimental" or versioning for WASI API experimentation. - 1. Ralph Squillace report on search for seekdir/telldir across GitHub codebases. -1. *Submit a PR to add your item here* +1. Proposals and discussions + 1. Discussion topic: Repository organization to enable independent proposal repos ([#360](https://github.com/WebAssembly/WASI/issues/360)) + 1. Discussion topic: Using releases to make the repo citable ([#356](https://github.com/WebAssembly/WASI/issues/356)) ## Meeting Notes From b9872b534fd4ac71e1ff67d0fdd05ed47e284442 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Wed, 2 Dec 2020 19:04:26 -0500 Subject: [PATCH 0788/1772] Add agenda items for 12-03 meeting (#361) --- proposals/random/meetings/2020/WASI-12-03.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/random/meetings/2020/WASI-12-03.md b/proposals/random/meetings/2020/WASI-12-03.md index 21f9acb89..cc6261428 100644 --- a/proposals/random/meetings/2020/WASI-12-03.md +++ b/proposals/random/meetings/2020/WASI-12-03.md @@ -27,7 +27,8 @@ Installation is required, see the calendar invite. 1. Thanks! 1. Review of action items from previous meeting(s). 1. Ralph Squillace to write up a draft on "WASI experimental" or versioning for WASI API experimentation. - 1. Ralph Squillace report on search for seekdir/telldir across GitHub codebases. -1. *Submit a PR to add your item here* +1. Proposals and discussions + 1. Discussion topic: Repository organization to enable independent proposal repos ([#360](https://github.com/WebAssembly/WASI/issues/360)) + 1. Discussion topic: Using releases to make the repo citable ([#356](https://github.com/WebAssembly/WASI/issues/356)) ## Meeting Notes From 4e3a846d38c3d9999c496b7c0b239fdf562dedd8 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Wed, 2 Dec 2020 19:04:26 -0500 Subject: [PATCH 0789/1772] Add agenda items for 12-03 meeting (#361) --- proposals/filesystem/meetings/2020/WASI-12-03.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/meetings/2020/WASI-12-03.md b/proposals/filesystem/meetings/2020/WASI-12-03.md index 21f9acb89..cc6261428 100644 --- a/proposals/filesystem/meetings/2020/WASI-12-03.md +++ b/proposals/filesystem/meetings/2020/WASI-12-03.md @@ -27,7 +27,8 @@ Installation is required, see the calendar invite. 1. Thanks! 1. Review of action items from previous meeting(s). 1. Ralph Squillace to write up a draft on "WASI experimental" or versioning for WASI API experimentation. - 1. Ralph Squillace report on search for seekdir/telldir across GitHub codebases. -1. *Submit a PR to add your item here* +1. Proposals and discussions + 1. Discussion topic: Repository organization to enable independent proposal repos ([#360](https://github.com/WebAssembly/WASI/issues/360)) + 1. Discussion topic: Using releases to make the repo citable ([#356](https://github.com/WebAssembly/WASI/issues/356)) ## Meeting Notes From b17ac0906fbb6dc2354279db280324be4115ccee Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 3 Dec 2020 19:09:54 -0500 Subject: [PATCH 0790/1772] Add 12-03 meeting notes (#362) --- proposals/clocks/meetings/2020/WASI-12-03.md | 96 ++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/proposals/clocks/meetings/2020/WASI-12-03.md b/proposals/clocks/meetings/2020/WASI-12-03.md index cc6261428..7d9b521b5 100644 --- a/proposals/clocks/meetings/2020/WASI-12-03.md +++ b/proposals/clocks/meetings/2020/WASI-12-03.md @@ -32,3 +32,99 @@ Installation is required, see the calendar invite. 1. Discussion topic: Using releases to make the repo citable ([#356](https://github.com/WebAssembly/WASI/issues/356)) ## Meeting Notes + +### Attendees +Lin Clark (LC) +Pat Hickey (PAH) +Martin Duke (MD) +Andrew Brown (AB) +Dan Gohman (DG) +Till Schneidereit (TS) +Matt Fisher (MF) +Mingqiu Sun (MS) +Mark McCaskey (MM) +Johnnie Birch (JB) +Ralph Squillace (RS) +Peter Huene (PEH) +Sam Clegg (SBC) + +LC: Action items from last meeting - Ralph is not on the call, so we’ll skip over follow ups with him + +LC: Dan put up a PR yesterday about repo organization to enable independent proposal repos + +DG: In a CG there's the core spec repo, and proposals that add new features are fork repos of the spec. When a proposal gets to stage 5 (spec), the proposal gets merged into the central repository. We want WASI to have a parallel structure to this. + +DG: One thing we want to move away from is a single snapshot path. So when we make a snapshot its url remains stable (we don't put it into old). What this enables is one snapshot referring to another. We want documentation to describe the differences between snapshots and eventually tools will too. Stable URLs are a good first step towards that + +DG: Another feature is moving away from ephemeral. That was envisioned as the place where we do development, where PRs target, but we want to move all development into proposal repositories. The main proposal repo will no longer have an ephemeral directory. +DG: A final piece of this is a place in the repo for a script, similar to core CG’s test suite repository, that pulls in the proposals from all the places they live, and creates the snapshot. All of the proposals will be separate modules in the snapshot. + +AB: When do proposal repos get added to the script so they land in the snapshot? + +DG: As soon as you create them you can create a PR to the script. One rule we could have is that if there's a merge conflict or other obvious errors we just skip over merging a proposal for now. But we want a snapshot to contain all proposals. + +DG: In the root spec repo, there will be a `standards/` directory, it's empty for now because we aren't at stage 5 yet. But out in the proposals they can put whatever they want to land in the spec repo snapshot in their `standards/` directory. This convention is that we don't have to wait for everyone to sync up + +TS: Will it make sense to say “only show me sections for proposals for stage of my choice in the rendered output”. + +DG: We don't have that information yet but that's a good idea. Maybe a magic doc comment in the witx files. Or we can iterate + +TS: There has to be some index about pulling in the proposals, and that can contain the metadata about what stage various proposals are at. + +AB: This is a better system than we have today + +DG: We are learning from our mistakes + +TS: We need to iterate on the infrastructure of the spec in a central place, and make use of it without copying code over, are you envisioning the proposals will pull in the (upstream) spec repo? And we iterate on that outside of the snapshot mechanism? + +DG: Some proposals need to make change to witx. They all have a witx crate in them to make changes to how witx works. You can experiment there and make a non-snapshot PR into the spec repo to merge bigger changes in. You can keep + +PAH: For some changes to WITX, it would make sense to do in the core spec repo and then proposals merge or rebase + +DG: That is something that becomes more awkward with this setup. The question is would you also modify existing snapshots to use the new syntax? Because if not, then snapshots don’t work with new tooling. + + +PAH: let’s set that discussion aside. We have been updating to keep semantics but use new syntax. The hard part of this is that if we have to make a breaking change to WITX that could affect our ability to merge in proposals that haven’t taken in the breaking changes yet. Is it the responsibility of WITX maintainer to un-break all the proposals? + +DG: Initial way that falls out is that the script that merges will run the new version of the tool over that. If it doesn’t run, we leave out of the snapshot + +PAH: That sounds fine to me. What I’m thinking now is the CGs waterfall, continuous integration of tip of tree which makes it possible to find before releases. Could run it on a cron job and does red/green for various proposals + +DG: If someone wants to set up a waterfall, that would be good. Might be more than we need right now. + +PAH: If you have to update both your WITX files and ref implementation on downstream tooling, might not be able you + +DG: You can do it on your local as a champion + +PAH: This also makes me think about the value of the snapshot version being date based. You could have an id and a date. E.g. nightly-YYYY-MM-DD. That could give people ability to find breakages before time for snapshot. I think the biggest thing I’ve messed up in WASI and WITX is not having tooling that makes ephemeral work. Want the new process to be tip of tree always working. I could be wrong on that, but that’s my personal feeling. + +DG: Ephemeral in main repo goes away. If they want to dev in standards dir, they can. If they have their own ephemeral, then it’s on them to keep it working. + +TS: It seems to me that there’s value in cross-proposal CI so that you don’t find out when cutting a snapshot more work to do. I could see value in /standards and /in-progress, where we maybe have GitHub action that tries to do an integration build + +PAH: I think I agree. I would love it if the CI action could be run in any of the fork repos so that they could alert on their own breakage. + +DG: If we put that in the main repo, then they’ll all have a fork of it + +PAH: They’d be able to id if any contrib to main repo is breaking. That’s an implementation detail. + +TS: I feel like it would also be kind of nice to have a snapshot that’s always up to date for what it looks like today with all proposals combined. + +LC: Are there more questions? (no). Dan what are the next steps? +DG: I can make a PR into the spec repo and proposal repos to adopt the new organization. The first step is to reorganize the spec repo and get the scripts setup, then reach out to the proposal champions to integrate up there. + +LC: You can put that list of work into the issue and we can distribute that work out. + +LC: Ralph has joined, do you want to talk about experimental stuff at all or next time? + +RS: I need more time before I present that. + +LC: Next thing on the agenda, we need to talk about releases. Someone is asking us to make citation easier using a tool called zenodo. For that to work we need to cut (GitHub) releases. Should we do this and when should we do them? It seems like we should do them when we do a snapshot. Does anyone have opinions on this? + +JB: Question about zenodo: what does that tool do? + +LC: It (??) DOI’s. I don’t know exactly why a DOI is important for a bibliography but its recommended over a URL when possible by the (APA?). The tool archives the data associated with the DOI, I believe. + +LC: Then we’ll start cutting releases with snapshots. We can do one release now to capture the current snapshot. I’ll work with the wasm cg chair to get zenodo configured for the repo. + +LC: Any other topics? (None) From b1b1bbbb47d2c241c1764bfb12712c31508a6001 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 3 Dec 2020 19:09:54 -0500 Subject: [PATCH 0791/1772] Add 12-03 meeting notes (#362) --- proposals/random/meetings/2020/WASI-12-03.md | 96 ++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/proposals/random/meetings/2020/WASI-12-03.md b/proposals/random/meetings/2020/WASI-12-03.md index cc6261428..7d9b521b5 100644 --- a/proposals/random/meetings/2020/WASI-12-03.md +++ b/proposals/random/meetings/2020/WASI-12-03.md @@ -32,3 +32,99 @@ Installation is required, see the calendar invite. 1. Discussion topic: Using releases to make the repo citable ([#356](https://github.com/WebAssembly/WASI/issues/356)) ## Meeting Notes + +### Attendees +Lin Clark (LC) +Pat Hickey (PAH) +Martin Duke (MD) +Andrew Brown (AB) +Dan Gohman (DG) +Till Schneidereit (TS) +Matt Fisher (MF) +Mingqiu Sun (MS) +Mark McCaskey (MM) +Johnnie Birch (JB) +Ralph Squillace (RS) +Peter Huene (PEH) +Sam Clegg (SBC) + +LC: Action items from last meeting - Ralph is not on the call, so we’ll skip over follow ups with him + +LC: Dan put up a PR yesterday about repo organization to enable independent proposal repos + +DG: In a CG there's the core spec repo, and proposals that add new features are fork repos of the spec. When a proposal gets to stage 5 (spec), the proposal gets merged into the central repository. We want WASI to have a parallel structure to this. + +DG: One thing we want to move away from is a single snapshot path. So when we make a snapshot its url remains stable (we don't put it into old). What this enables is one snapshot referring to another. We want documentation to describe the differences between snapshots and eventually tools will too. Stable URLs are a good first step towards that + +DG: Another feature is moving away from ephemeral. That was envisioned as the place where we do development, where PRs target, but we want to move all development into proposal repositories. The main proposal repo will no longer have an ephemeral directory. +DG: A final piece of this is a place in the repo for a script, similar to core CG’s test suite repository, that pulls in the proposals from all the places they live, and creates the snapshot. All of the proposals will be separate modules in the snapshot. + +AB: When do proposal repos get added to the script so they land in the snapshot? + +DG: As soon as you create them you can create a PR to the script. One rule we could have is that if there's a merge conflict or other obvious errors we just skip over merging a proposal for now. But we want a snapshot to contain all proposals. + +DG: In the root spec repo, there will be a `standards/` directory, it's empty for now because we aren't at stage 5 yet. But out in the proposals they can put whatever they want to land in the spec repo snapshot in their `standards/` directory. This convention is that we don't have to wait for everyone to sync up + +TS: Will it make sense to say “only show me sections for proposals for stage of my choice in the rendered output”. + +DG: We don't have that information yet but that's a good idea. Maybe a magic doc comment in the witx files. Or we can iterate + +TS: There has to be some index about pulling in the proposals, and that can contain the metadata about what stage various proposals are at. + +AB: This is a better system than we have today + +DG: We are learning from our mistakes + +TS: We need to iterate on the infrastructure of the spec in a central place, and make use of it without copying code over, are you envisioning the proposals will pull in the (upstream) spec repo? And we iterate on that outside of the snapshot mechanism? + +DG: Some proposals need to make change to witx. They all have a witx crate in them to make changes to how witx works. You can experiment there and make a non-snapshot PR into the spec repo to merge bigger changes in. You can keep + +PAH: For some changes to WITX, it would make sense to do in the core spec repo and then proposals merge or rebase + +DG: That is something that becomes more awkward with this setup. The question is would you also modify existing snapshots to use the new syntax? Because if not, then snapshots don’t work with new tooling. + + +PAH: let’s set that discussion aside. We have been updating to keep semantics but use new syntax. The hard part of this is that if we have to make a breaking change to WITX that could affect our ability to merge in proposals that haven’t taken in the breaking changes yet. Is it the responsibility of WITX maintainer to un-break all the proposals? + +DG: Initial way that falls out is that the script that merges will run the new version of the tool over that. If it doesn’t run, we leave out of the snapshot + +PAH: That sounds fine to me. What I’m thinking now is the CGs waterfall, continuous integration of tip of tree which makes it possible to find before releases. Could run it on a cron job and does red/green for various proposals + +DG: If someone wants to set up a waterfall, that would be good. Might be more than we need right now. + +PAH: If you have to update both your WITX files and ref implementation on downstream tooling, might not be able you + +DG: You can do it on your local as a champion + +PAH: This also makes me think about the value of the snapshot version being date based. You could have an id and a date. E.g. nightly-YYYY-MM-DD. That could give people ability to find breakages before time for snapshot. I think the biggest thing I’ve messed up in WASI and WITX is not having tooling that makes ephemeral work. Want the new process to be tip of tree always working. I could be wrong on that, but that’s my personal feeling. + +DG: Ephemeral in main repo goes away. If they want to dev in standards dir, they can. If they have their own ephemeral, then it’s on them to keep it working. + +TS: It seems to me that there’s value in cross-proposal CI so that you don’t find out when cutting a snapshot more work to do. I could see value in /standards and /in-progress, where we maybe have GitHub action that tries to do an integration build + +PAH: I think I agree. I would love it if the CI action could be run in any of the fork repos so that they could alert on their own breakage. + +DG: If we put that in the main repo, then they’ll all have a fork of it + +PAH: They’d be able to id if any contrib to main repo is breaking. That’s an implementation detail. + +TS: I feel like it would also be kind of nice to have a snapshot that’s always up to date for what it looks like today with all proposals combined. + +LC: Are there more questions? (no). Dan what are the next steps? +DG: I can make a PR into the spec repo and proposal repos to adopt the new organization. The first step is to reorganize the spec repo and get the scripts setup, then reach out to the proposal champions to integrate up there. + +LC: You can put that list of work into the issue and we can distribute that work out. + +LC: Ralph has joined, do you want to talk about experimental stuff at all or next time? + +RS: I need more time before I present that. + +LC: Next thing on the agenda, we need to talk about releases. Someone is asking us to make citation easier using a tool called zenodo. For that to work we need to cut (GitHub) releases. Should we do this and when should we do them? It seems like we should do them when we do a snapshot. Does anyone have opinions on this? + +JB: Question about zenodo: what does that tool do? + +LC: It (??) DOI’s. I don’t know exactly why a DOI is important for a bibliography but its recommended over a URL when possible by the (APA?). The tool archives the data associated with the DOI, I believe. + +LC: Then we’ll start cutting releases with snapshots. We can do one release now to capture the current snapshot. I’ll work with the wasm cg chair to get zenodo configured for the repo. + +LC: Any other topics? (None) From 4500be86eca90fc0f531e14ea0ded45f21c9837b Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 3 Dec 2020 19:09:54 -0500 Subject: [PATCH 0792/1772] Add 12-03 meeting notes (#362) --- .../filesystem/meetings/2020/WASI-12-03.md | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/proposals/filesystem/meetings/2020/WASI-12-03.md b/proposals/filesystem/meetings/2020/WASI-12-03.md index cc6261428..7d9b521b5 100644 --- a/proposals/filesystem/meetings/2020/WASI-12-03.md +++ b/proposals/filesystem/meetings/2020/WASI-12-03.md @@ -32,3 +32,99 @@ Installation is required, see the calendar invite. 1. Discussion topic: Using releases to make the repo citable ([#356](https://github.com/WebAssembly/WASI/issues/356)) ## Meeting Notes + +### Attendees +Lin Clark (LC) +Pat Hickey (PAH) +Martin Duke (MD) +Andrew Brown (AB) +Dan Gohman (DG) +Till Schneidereit (TS) +Matt Fisher (MF) +Mingqiu Sun (MS) +Mark McCaskey (MM) +Johnnie Birch (JB) +Ralph Squillace (RS) +Peter Huene (PEH) +Sam Clegg (SBC) + +LC: Action items from last meeting - Ralph is not on the call, so we’ll skip over follow ups with him + +LC: Dan put up a PR yesterday about repo organization to enable independent proposal repos + +DG: In a CG there's the core spec repo, and proposals that add new features are fork repos of the spec. When a proposal gets to stage 5 (spec), the proposal gets merged into the central repository. We want WASI to have a parallel structure to this. + +DG: One thing we want to move away from is a single snapshot path. So when we make a snapshot its url remains stable (we don't put it into old). What this enables is one snapshot referring to another. We want documentation to describe the differences between snapshots and eventually tools will too. Stable URLs are a good first step towards that + +DG: Another feature is moving away from ephemeral. That was envisioned as the place where we do development, where PRs target, but we want to move all development into proposal repositories. The main proposal repo will no longer have an ephemeral directory. +DG: A final piece of this is a place in the repo for a script, similar to core CG’s test suite repository, that pulls in the proposals from all the places they live, and creates the snapshot. All of the proposals will be separate modules in the snapshot. + +AB: When do proposal repos get added to the script so they land in the snapshot? + +DG: As soon as you create them you can create a PR to the script. One rule we could have is that if there's a merge conflict or other obvious errors we just skip over merging a proposal for now. But we want a snapshot to contain all proposals. + +DG: In the root spec repo, there will be a `standards/` directory, it's empty for now because we aren't at stage 5 yet. But out in the proposals they can put whatever they want to land in the spec repo snapshot in their `standards/` directory. This convention is that we don't have to wait for everyone to sync up + +TS: Will it make sense to say “only show me sections for proposals for stage of my choice in the rendered output”. + +DG: We don't have that information yet but that's a good idea. Maybe a magic doc comment in the witx files. Or we can iterate + +TS: There has to be some index about pulling in the proposals, and that can contain the metadata about what stage various proposals are at. + +AB: This is a better system than we have today + +DG: We are learning from our mistakes + +TS: We need to iterate on the infrastructure of the spec in a central place, and make use of it without copying code over, are you envisioning the proposals will pull in the (upstream) spec repo? And we iterate on that outside of the snapshot mechanism? + +DG: Some proposals need to make change to witx. They all have a witx crate in them to make changes to how witx works. You can experiment there and make a non-snapshot PR into the spec repo to merge bigger changes in. You can keep + +PAH: For some changes to WITX, it would make sense to do in the core spec repo and then proposals merge or rebase + +DG: That is something that becomes more awkward with this setup. The question is would you also modify existing snapshots to use the new syntax? Because if not, then snapshots don’t work with new tooling. + + +PAH: let’s set that discussion aside. We have been updating to keep semantics but use new syntax. The hard part of this is that if we have to make a breaking change to WITX that could affect our ability to merge in proposals that haven’t taken in the breaking changes yet. Is it the responsibility of WITX maintainer to un-break all the proposals? + +DG: Initial way that falls out is that the script that merges will run the new version of the tool over that. If it doesn’t run, we leave out of the snapshot + +PAH: That sounds fine to me. What I’m thinking now is the CGs waterfall, continuous integration of tip of tree which makes it possible to find before releases. Could run it on a cron job and does red/green for various proposals + +DG: If someone wants to set up a waterfall, that would be good. Might be more than we need right now. + +PAH: If you have to update both your WITX files and ref implementation on downstream tooling, might not be able you + +DG: You can do it on your local as a champion + +PAH: This also makes me think about the value of the snapshot version being date based. You could have an id and a date. E.g. nightly-YYYY-MM-DD. That could give people ability to find breakages before time for snapshot. I think the biggest thing I’ve messed up in WASI and WITX is not having tooling that makes ephemeral work. Want the new process to be tip of tree always working. I could be wrong on that, but that’s my personal feeling. + +DG: Ephemeral in main repo goes away. If they want to dev in standards dir, they can. If they have their own ephemeral, then it’s on them to keep it working. + +TS: It seems to me that there’s value in cross-proposal CI so that you don’t find out when cutting a snapshot more work to do. I could see value in /standards and /in-progress, where we maybe have GitHub action that tries to do an integration build + +PAH: I think I agree. I would love it if the CI action could be run in any of the fork repos so that they could alert on their own breakage. + +DG: If we put that in the main repo, then they’ll all have a fork of it + +PAH: They’d be able to id if any contrib to main repo is breaking. That’s an implementation detail. + +TS: I feel like it would also be kind of nice to have a snapshot that’s always up to date for what it looks like today with all proposals combined. + +LC: Are there more questions? (no). Dan what are the next steps? +DG: I can make a PR into the spec repo and proposal repos to adopt the new organization. The first step is to reorganize the spec repo and get the scripts setup, then reach out to the proposal champions to integrate up there. + +LC: You can put that list of work into the issue and we can distribute that work out. + +LC: Ralph has joined, do you want to talk about experimental stuff at all or next time? + +RS: I need more time before I present that. + +LC: Next thing on the agenda, we need to talk about releases. Someone is asking us to make citation easier using a tool called zenodo. For that to work we need to cut (GitHub) releases. Should we do this and when should we do them? It seems like we should do them when we do a snapshot. Does anyone have opinions on this? + +JB: Question about zenodo: what does that tool do? + +LC: It (??) DOI’s. I don’t know exactly why a DOI is important for a bibliography but its recommended over a URL when possible by the (APA?). The tool archives the data associated with the DOI, I believe. + +LC: Then we’ll start cutting releases with snapshots. We can do one release now to capture the current snapshot. I’ll work with the wasm cg chair to get zenodo configured for the repo. + +LC: Any other topics? (None) From ac6c7251a51f29f07394724eb94e92c18779e2d2 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 3 Dec 2020 22:03:35 -0500 Subject: [PATCH 0793/1772] Add 12-17 meeting agenda (#363) --- proposals/clocks/meetings/2020/WASI-12-17.md | 33 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 1 + 2 files changed, 34 insertions(+) create mode 100644 proposals/clocks/meetings/2020/WASI-12-17.md diff --git a/proposals/clocks/meetings/2020/WASI-12-17.md b/proposals/clocks/meetings/2020/WASI-12-17.md new file mode 100644 index 000000000..4ece98f42 --- /dev/null +++ b/proposals/clocks/meetings/2020/WASI-12-17.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the December 3 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: December 3, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Review of action items from previous meeting(s). + 1. Dan report on repository organization progress +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 1475d27b2..b38bbd9f6 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -44,3 +44,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI October 22nd video call](2020/WASI-10-22.md) * [WASI November 19th video call](2020/WASI-11-19.md) * [WASI December 3rd video call](2020/WASI-12-03.md) + * [WASI December 17th video call](2020/WASI-12-17.md) From 6318472ec22796ec6c84edfdc6f4bf362e037cf9 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 3 Dec 2020 22:03:35 -0500 Subject: [PATCH 0794/1772] Add 12-17 meeting agenda (#363) --- proposals/random/meetings/2020/WASI-12-17.md | 33 ++++++++++++++++++++ proposals/random/meetings/README.md | 1 + 2 files changed, 34 insertions(+) create mode 100644 proposals/random/meetings/2020/WASI-12-17.md diff --git a/proposals/random/meetings/2020/WASI-12-17.md b/proposals/random/meetings/2020/WASI-12-17.md new file mode 100644 index 000000000..4ece98f42 --- /dev/null +++ b/proposals/random/meetings/2020/WASI-12-17.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the December 3 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: December 3, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Review of action items from previous meeting(s). + 1. Dan report on repository organization progress +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 1475d27b2..b38bbd9f6 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -44,3 +44,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI October 22nd video call](2020/WASI-10-22.md) * [WASI November 19th video call](2020/WASI-11-19.md) * [WASI December 3rd video call](2020/WASI-12-03.md) + * [WASI December 17th video call](2020/WASI-12-17.md) From d1787545ecb19ab5729731e1d2a8d9b955066e5f Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 3 Dec 2020 22:03:35 -0500 Subject: [PATCH 0795/1772] Add 12-17 meeting agenda (#363) --- .../filesystem/meetings/2020/WASI-12-17.md | 33 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 1 + 2 files changed, 34 insertions(+) create mode 100644 proposals/filesystem/meetings/2020/WASI-12-17.md diff --git a/proposals/filesystem/meetings/2020/WASI-12-17.md b/proposals/filesystem/meetings/2020/WASI-12-17.md new file mode 100644 index 000000000..4ece98f42 --- /dev/null +++ b/proposals/filesystem/meetings/2020/WASI-12-17.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the December 3 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: December 3, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Review of action items from previous meeting(s). + 1. Dan report on repository organization progress +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 1475d27b2..b38bbd9f6 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -44,3 +44,4 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI October 22nd video call](2020/WASI-10-22.md) * [WASI November 19th video call](2020/WASI-11-19.md) * [WASI December 3rd video call](2020/WASI-12-03.md) + * [WASI December 17th video call](2020/WASI-12-17.md) From 2ad60fd46a7f30a7f5949b18e2140b60fcd4c78c Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 7 Dec 2020 21:21:50 -0500 Subject: [PATCH 0796/1772] Fix time typos in 12-17 meeting agenda --- proposals/clocks/meetings/2020/WASI-12-17.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/meetings/2020/WASI-12-17.md b/proposals/clocks/meetings/2020/WASI-12-17.md index 4ece98f42..de39e37c7 100644 --- a/proposals/clocks/meetings/2020/WASI-12-17.md +++ b/proposals/clocks/meetings/2020/WASI-12-17.md @@ -1,9 +1,9 @@ ![WASI logo](/WASI.png) -## Agenda for the December 3 video call of WASI Subgroup +## Agenda for the December 17 video call of WASI Subgroup - **Where**: zoom.us -- **When**: December 3, 16:00-17:00 UTC +- **When**: December 17, 17:00-18:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Lin Clark From a99548f839465bfeab54e38c925765353996617f Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 7 Dec 2020 21:21:50 -0500 Subject: [PATCH 0797/1772] Fix time typos in 12-17 meeting agenda --- proposals/random/meetings/2020/WASI-12-17.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/meetings/2020/WASI-12-17.md b/proposals/random/meetings/2020/WASI-12-17.md index 4ece98f42..de39e37c7 100644 --- a/proposals/random/meetings/2020/WASI-12-17.md +++ b/proposals/random/meetings/2020/WASI-12-17.md @@ -1,9 +1,9 @@ ![WASI logo](/WASI.png) -## Agenda for the December 3 video call of WASI Subgroup +## Agenda for the December 17 video call of WASI Subgroup - **Where**: zoom.us -- **When**: December 3, 16:00-17:00 UTC +- **When**: December 17, 17:00-18:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Lin Clark From 5af78bdb206ee6ba9c1098ad5716c54571de42f9 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 7 Dec 2020 21:21:50 -0500 Subject: [PATCH 0798/1772] Fix time typos in 12-17 meeting agenda --- proposals/filesystem/meetings/2020/WASI-12-17.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/meetings/2020/WASI-12-17.md b/proposals/filesystem/meetings/2020/WASI-12-17.md index 4ece98f42..de39e37c7 100644 --- a/proposals/filesystem/meetings/2020/WASI-12-17.md +++ b/proposals/filesystem/meetings/2020/WASI-12-17.md @@ -1,9 +1,9 @@ ![WASI logo](/WASI.png) -## Agenda for the December 3 video call of WASI Subgroup +## Agenda for the December 17 video call of WASI Subgroup - **Where**: zoom.us -- **When**: December 3, 16:00-17:00 UTC +- **When**: December 17, 17:00-18:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Lin Clark From a62006a9f361f667544d918922b4f17c3e8b8b9b Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Tue, 15 Dec 2020 15:18:55 -0500 Subject: [PATCH 0799/1772] Add DOI link to README Fixes #356 --- proposals/clocks/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 8d3c56a90..22449e08b 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -1,3 +1,5 @@ +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4323447.svg)](https://doi.org/10.5281/zenodo.4323447) + # WebAssembly System Interface ![WASI](WASI.png) @@ -21,4 +23,4 @@ This repository is for the WebAssembly System Interface (WASI) Subgroup of the The [issue tracker] is the place to ask questions, make suggestions, and start discussions. -[issue tracker]: https://github.com/WebAssembly/WASI/issues \ No newline at end of file +[issue tracker]: https://github.com/WebAssembly/WASI/issues From 7f90f4ca114bd1ed1fe3a9cb6f1daeef9d96e94d Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Tue, 15 Dec 2020 15:18:55 -0500 Subject: [PATCH 0800/1772] Add DOI link to README Fixes #356 --- proposals/random/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/random/README.md b/proposals/random/README.md index 8d3c56a90..22449e08b 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -1,3 +1,5 @@ +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4323447.svg)](https://doi.org/10.5281/zenodo.4323447) + # WebAssembly System Interface ![WASI](WASI.png) @@ -21,4 +23,4 @@ This repository is for the WebAssembly System Interface (WASI) Subgroup of the The [issue tracker] is the place to ask questions, make suggestions, and start discussions. -[issue tracker]: https://github.com/WebAssembly/WASI/issues \ No newline at end of file +[issue tracker]: https://github.com/WebAssembly/WASI/issues From 4d908d5b20d08ece171e5334afb90620894adf96 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Tue, 15 Dec 2020 15:18:55 -0500 Subject: [PATCH 0801/1772] Add DOI link to README Fixes #356 --- proposals/filesystem/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index 8d3c56a90..22449e08b 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -1,3 +1,5 @@ +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4323447.svg)](https://doi.org/10.5281/zenodo.4323447) + # WebAssembly System Interface ![WASI](WASI.png) @@ -21,4 +23,4 @@ This repository is for the WebAssembly System Interface (WASI) Subgroup of the The [issue tracker] is the place to ask questions, make suggestions, and start discussions. -[issue tracker]: https://github.com/WebAssembly/WASI/issues \ No newline at end of file +[issue tracker]: https://github.com/WebAssembly/WASI/issues From 05194bed26001f51a6a5cfe79563b5c128fa8b15 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Tue, 15 Dec 2020 21:07:41 -0500 Subject: [PATCH 0802/1772] Cancel 12-17 meeting and add agendas for 01-14 and 01-28. (#367) --- .../WASI-12-17.md => 2021/WASI-01-14.md} | 5 +-- proposals/clocks/meetings/2021/WASI-01-28.md | 35 +++++++++++++++++++ proposals/clocks/meetings/README.md | 5 ++- 3 files changed, 42 insertions(+), 3 deletions(-) rename proposals/clocks/meetings/{2020/WASI-12-17.md => 2021/WASI-01-14.md} (83%) create mode 100644 proposals/clocks/meetings/2021/WASI-01-28.md diff --git a/proposals/clocks/meetings/2020/WASI-12-17.md b/proposals/clocks/meetings/2021/WASI-01-14.md similarity index 83% rename from proposals/clocks/meetings/2020/WASI-12-17.md rename to proposals/clocks/meetings/2021/WASI-01-14.md index de39e37c7..801201508 100644 --- a/proposals/clocks/meetings/2020/WASI-12-17.md +++ b/proposals/clocks/meetings/2021/WASI-01-14.md @@ -1,9 +1,9 @@ ![WASI logo](/WASI.png) -## Agenda for the December 17 video call of WASI Subgroup +## Agenda for the January 14 video call of WASI Subgroup - **Where**: zoom.us -- **When**: December 17, 17:00-18:00 UTC +- **When**: January 14, 17:00-18:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Lin Clark @@ -28,6 +28,7 @@ Installation is required, see the calendar invite. 1. Review of action items from previous meeting(s). 1. Dan report on repository organization progress 1. Proposals and discussions + 1. Discussion: Testing guidelines for proposals 1. _Sumbit a PR to add your agenda item here_ ## Meeting Notes diff --git a/proposals/clocks/meetings/2021/WASI-01-28.md b/proposals/clocks/meetings/2021/WASI-01-28.md new file mode 100644 index 000000000..757ab4d4e --- /dev/null +++ b/proposals/clocks/meetings/2021/WASI-01-28.md @@ -0,0 +1,35 @@ +![WASI logo](/WASI.png) + +## Agenda for the January 28 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: January 28, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Review of action items from previous meeting(s). + 1. Dan report on repository organization progress +1. Proposals and discussions + 1. Presentation: Update from Luke Wagner on handles and resources in interface types + 1. Discussion: Transitioning WASI APIs to use IT handles + 1. _Sumbit a PR to add your agenda item here_ + +## Meeting Notes diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index b38bbd9f6..3436863ab 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -44,4 +44,7 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI October 22nd video call](2020/WASI-10-22.md) * [WASI November 19th video call](2020/WASI-11-19.md) * [WASI December 3rd video call](2020/WASI-12-03.md) - * [WASI December 17th video call](2020/WASI-12-17.md) + + ### 2021 + * [WASI January 14th video call](2021/WASI-01-14.md) + * [WASI January 28th video call](2021/WASI-01-28.md) From f65d7f64d91f75d93b49cd4f400d235c84bd6312 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Tue, 15 Dec 2020 21:07:41 -0500 Subject: [PATCH 0803/1772] Cancel 12-17 meeting and add agendas for 01-14 and 01-28. (#367) --- .../WASI-12-17.md => 2021/WASI-01-14.md} | 5 +-- proposals/random/meetings/2021/WASI-01-28.md | 35 +++++++++++++++++++ proposals/random/meetings/README.md | 5 ++- 3 files changed, 42 insertions(+), 3 deletions(-) rename proposals/random/meetings/{2020/WASI-12-17.md => 2021/WASI-01-14.md} (83%) create mode 100644 proposals/random/meetings/2021/WASI-01-28.md diff --git a/proposals/random/meetings/2020/WASI-12-17.md b/proposals/random/meetings/2021/WASI-01-14.md similarity index 83% rename from proposals/random/meetings/2020/WASI-12-17.md rename to proposals/random/meetings/2021/WASI-01-14.md index de39e37c7..801201508 100644 --- a/proposals/random/meetings/2020/WASI-12-17.md +++ b/proposals/random/meetings/2021/WASI-01-14.md @@ -1,9 +1,9 @@ ![WASI logo](/WASI.png) -## Agenda for the December 17 video call of WASI Subgroup +## Agenda for the January 14 video call of WASI Subgroup - **Where**: zoom.us -- **When**: December 17, 17:00-18:00 UTC +- **When**: January 14, 17:00-18:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Lin Clark @@ -28,6 +28,7 @@ Installation is required, see the calendar invite. 1. Review of action items from previous meeting(s). 1. Dan report on repository organization progress 1. Proposals and discussions + 1. Discussion: Testing guidelines for proposals 1. _Sumbit a PR to add your agenda item here_ ## Meeting Notes diff --git a/proposals/random/meetings/2021/WASI-01-28.md b/proposals/random/meetings/2021/WASI-01-28.md new file mode 100644 index 000000000..757ab4d4e --- /dev/null +++ b/proposals/random/meetings/2021/WASI-01-28.md @@ -0,0 +1,35 @@ +![WASI logo](/WASI.png) + +## Agenda for the January 28 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: January 28, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Review of action items from previous meeting(s). + 1. Dan report on repository organization progress +1. Proposals and discussions + 1. Presentation: Update from Luke Wagner on handles and resources in interface types + 1. Discussion: Transitioning WASI APIs to use IT handles + 1. _Sumbit a PR to add your agenda item here_ + +## Meeting Notes diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index b38bbd9f6..3436863ab 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -44,4 +44,7 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI October 22nd video call](2020/WASI-10-22.md) * [WASI November 19th video call](2020/WASI-11-19.md) * [WASI December 3rd video call](2020/WASI-12-03.md) - * [WASI December 17th video call](2020/WASI-12-17.md) + + ### 2021 + * [WASI January 14th video call](2021/WASI-01-14.md) + * [WASI January 28th video call](2021/WASI-01-28.md) From 4ab43117b4973182a59b9e62b6a2165ceb39fdd0 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Tue, 15 Dec 2020 21:07:41 -0500 Subject: [PATCH 0804/1772] Cancel 12-17 meeting and add agendas for 01-14 and 01-28. (#367) --- .../WASI-12-17.md => 2021/WASI-01-14.md} | 5 +-- .../filesystem/meetings/2021/WASI-01-28.md | 35 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 5 ++- 3 files changed, 42 insertions(+), 3 deletions(-) rename proposals/filesystem/meetings/{2020/WASI-12-17.md => 2021/WASI-01-14.md} (83%) create mode 100644 proposals/filesystem/meetings/2021/WASI-01-28.md diff --git a/proposals/filesystem/meetings/2020/WASI-12-17.md b/proposals/filesystem/meetings/2021/WASI-01-14.md similarity index 83% rename from proposals/filesystem/meetings/2020/WASI-12-17.md rename to proposals/filesystem/meetings/2021/WASI-01-14.md index de39e37c7..801201508 100644 --- a/proposals/filesystem/meetings/2020/WASI-12-17.md +++ b/proposals/filesystem/meetings/2021/WASI-01-14.md @@ -1,9 +1,9 @@ ![WASI logo](/WASI.png) -## Agenda for the December 17 video call of WASI Subgroup +## Agenda for the January 14 video call of WASI Subgroup - **Where**: zoom.us -- **When**: December 17, 17:00-18:00 UTC +- **When**: January 14, 17:00-18:00 UTC - **Location**: *link on calendar invite* - **Contact**: - Name: Lin Clark @@ -28,6 +28,7 @@ Installation is required, see the calendar invite. 1. Review of action items from previous meeting(s). 1. Dan report on repository organization progress 1. Proposals and discussions + 1. Discussion: Testing guidelines for proposals 1. _Sumbit a PR to add your agenda item here_ ## Meeting Notes diff --git a/proposals/filesystem/meetings/2021/WASI-01-28.md b/proposals/filesystem/meetings/2021/WASI-01-28.md new file mode 100644 index 000000000..757ab4d4e --- /dev/null +++ b/proposals/filesystem/meetings/2021/WASI-01-28.md @@ -0,0 +1,35 @@ +![WASI logo](/WASI.png) + +## Agenda for the January 28 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: January 28, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's +your first time. The meeting is open to CG members only. + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Review of action items from previous meeting(s). + 1. Dan report on repository organization progress +1. Proposals and discussions + 1. Presentation: Update from Luke Wagner on handles and resources in interface types + 1. Discussion: Transitioning WASI APIs to use IT handles + 1. _Sumbit a PR to add your agenda item here_ + +## Meeting Notes diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index b38bbd9f6..3436863ab 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -44,4 +44,7 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI October 22nd video call](2020/WASI-10-22.md) * [WASI November 19th video call](2020/WASI-11-19.md) * [WASI December 3rd video call](2020/WASI-12-03.md) - * [WASI December 17th video call](2020/WASI-12-17.md) + + ### 2021 + * [WASI January 14th video call](2021/WASI-01-14.md) + * [WASI January 28th video call](2021/WASI-01-28.md) From 12f197ec19fc84e74d97df77054f51c6a9bd1c3c Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 6 Jan 2021 13:06:32 -0800 Subject: [PATCH 0805/1772] Add the `(@witx noreturn)` annotation to proc_exit (#371) * Add the `(@witx noreturn)` annotation to proc_exit The noreturn annotation was invented solely for the sake of proc_exit, but we never actually used it in the spec documents. This annotation sets the `noreturn` bit in the `InterfaceFunc` struct. Downstream tools are free to do with that bit what they will. * bugfix: witx rendering * bnump witx version to 0.8.8 --- .../clocks/phases/old/snapshot_0/witx/wasi_unstable.witx | 1 + .../clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx | 1 + proposals/clocks/tools/witx/Cargo.toml | 2 +- proposals/clocks/tools/witx/src/render.rs | 5 ++++- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx index a6d352848..0d16f1b18 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -465,6 +465,7 @@ (@interface func (export "proc_exit") ;;; The exit code returned by the process. (param $rval $exitcode) + (@witx noreturn) ) ;;; Send a signal to the process of the calling thread. diff --git a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx index 47dd44910..eacfab268 100644 --- a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -462,6 +462,7 @@ (@interface func (export "proc_exit") ;;; The exit code returned by the process. (param $rval $exitcode) + (@witx noreturn) ) ;;; Send a signal to the process of the calling thread. diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 18502e901..34c074d68 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.7" +version = "0.8.8" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index f83e561b7..4cf6c531f 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -315,7 +315,10 @@ impl InterfaceFunc { }) .collect(); let attrs = if self.noreturn { - vec![SExpr::annot("witx"), SExpr::word("noreturn")] + vec![SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("noreturn"), + ])] } else { vec![] }; From 38aa151bf7eed9b0f46025ccfaeb9fd70846b086 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 6 Jan 2021 13:06:32 -0800 Subject: [PATCH 0806/1772] Add the `(@witx noreturn)` annotation to proc_exit (#371) * Add the `(@witx noreturn)` annotation to proc_exit The noreturn annotation was invented solely for the sake of proc_exit, but we never actually used it in the spec documents. This annotation sets the `noreturn` bit in the `InterfaceFunc` struct. Downstream tools are free to do with that bit what they will. * bugfix: witx rendering * bnump witx version to 0.8.8 --- .../random/phases/old/snapshot_0/witx/wasi_unstable.witx | 1 + .../random/phases/snapshot/witx/wasi_snapshot_preview1.witx | 1 + proposals/random/tools/witx/Cargo.toml | 2 +- proposals/random/tools/witx/src/render.rs | 5 ++++- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx index a6d352848..0d16f1b18 100644 --- a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -465,6 +465,7 @@ (@interface func (export "proc_exit") ;;; The exit code returned by the process. (param $rval $exitcode) + (@witx noreturn) ) ;;; Send a signal to the process of the calling thread. diff --git a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx index 47dd44910..eacfab268 100644 --- a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -462,6 +462,7 @@ (@interface func (export "proc_exit") ;;; The exit code returned by the process. (param $rval $exitcode) + (@witx noreturn) ) ;;; Send a signal to the process of the calling thread. diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 18502e901..34c074d68 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.7" +version = "0.8.8" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index f83e561b7..4cf6c531f 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -315,7 +315,10 @@ impl InterfaceFunc { }) .collect(); let attrs = if self.noreturn { - vec![SExpr::annot("witx"), SExpr::word("noreturn")] + vec![SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("noreturn"), + ])] } else { vec![] }; From 082968ef7f2e57a217a94d414f4f2ce3d4fa3eca Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 6 Jan 2021 13:06:32 -0800 Subject: [PATCH 0807/1772] Add the `(@witx noreturn)` annotation to proc_exit (#371) * Add the `(@witx noreturn)` annotation to proc_exit The noreturn annotation was invented solely for the sake of proc_exit, but we never actually used it in the spec documents. This annotation sets the `noreturn` bit in the `InterfaceFunc` struct. Downstream tools are free to do with that bit what they will. * bugfix: witx rendering * bnump witx version to 0.8.8 --- .../filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx | 1 + .../phases/snapshot/witx/wasi_snapshot_preview1.witx | 1 + proposals/filesystem/tools/witx/Cargo.toml | 2 +- proposals/filesystem/tools/witx/src/render.rs | 5 ++++- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx index a6d352848..0d16f1b18 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -465,6 +465,7 @@ (@interface func (export "proc_exit") ;;; The exit code returned by the process. (param $rval $exitcode) + (@witx noreturn) ) ;;; Send a signal to the process of the calling thread. diff --git a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx index 47dd44910..eacfab268 100644 --- a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -462,6 +462,7 @@ (@interface func (export "proc_exit") ;;; The exit code returned by the process. (param $rval $exitcode) + (@witx noreturn) ) ;;; Send a signal to the process of the calling thread. diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 18502e901..34c074d68 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.7" +version = "0.8.8" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index f83e561b7..4cf6c531f 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -315,7 +315,10 @@ impl InterfaceFunc { }) .collect(); let attrs = if self.noreturn { - vec![SExpr::annot("witx"), SExpr::word("noreturn")] + vec![SExpr::Vec(vec![ + SExpr::annot("witx"), + SExpr::word("noreturn"), + ])] } else { vec![] }; From f7832b8027ca84246a7dbf5b11364ca0448c9ad2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 10 Dec 2020 12:59:21 -0800 Subject: [PATCH 0808/1772] Reorganize the directory structure to better support proposals. Following the organization sketched out here: https://github.com/WebAssembly/WASI/issues/360 This PR adds several new directories and starts a work-in-progress make-snapshot.sh script for creating snapshots. The `phases` directory is not yet removed; that can happen once we've transitioned everything to the new organization. --- proposals/clocks/proposal-template/README.md | 4 + proposals/clocks/proposals/README.md | 8 + proposals/clocks/repos/README.md | 7 + proposals/clocks/snapshots/README.md | 5 + proposals/clocks/snapshots/make-snapshot.sh | 159 +++++++++++++++++++ proposals/clocks/standard/README.md | 12 ++ 6 files changed, 195 insertions(+) create mode 100644 proposals/clocks/proposal-template/README.md create mode 100644 proposals/clocks/proposals/README.md create mode 100644 proposals/clocks/repos/README.md create mode 100644 proposals/clocks/snapshots/README.md create mode 100755 proposals/clocks/snapshots/make-snapshot.sh create mode 100644 proposals/clocks/standard/README.md diff --git a/proposals/clocks/proposal-template/README.md b/proposals/clocks/proposal-template/README.md new file mode 100644 index 000000000..b97035935 --- /dev/null +++ b/proposals/clocks/proposal-template/README.md @@ -0,0 +1,4 @@ +# Proposal template + +This directory will hold a template for creating new proposals, to help people +get started. diff --git a/proposals/clocks/proposals/README.md b/proposals/clocks/proposals/README.md new file mode 100644 index 000000000..45c2c2852 --- /dev/null +++ b/proposals/clocks/proposals/README.md @@ -0,0 +1,8 @@ +# Proposals + +This directory contains overviews for proposals that are included in this +repository. + +This is analogous to [the correpsonding directory in the spec repository]. + +[the correpsonding directory in the spec repository]: https://github.com/WebAssembly/spec/tree/master/proposals diff --git a/proposals/clocks/repos/README.md b/proposals/clocks/repos/README.md new file mode 100644 index 000000000..c628b3f0d --- /dev/null +++ b/proposals/clocks/repos/README.md @@ -0,0 +1,7 @@ +The spec and proposal repositories will be cloned in this directory by the +make-testsuite.sh script. Don't apply local changes to these repositories, as +the script may destroy them. + +This is analogous to [the coresponding wasm testsuite directory]. + +[the coresponding wasm testsuite directory]: https://github.com/WebAssembly/testsuite/tree/master/repos diff --git a/proposals/clocks/snapshots/README.md b/proposals/clocks/snapshots/README.md new file mode 100644 index 000000000..af94dbdef --- /dev/null +++ b/proposals/clocks/snapshots/README.md @@ -0,0 +1,5 @@ +# WASI Snapshots + +To balance between the needs of development and stability, snapshots +represent the state of all active proposals at a moment in time. Individual +Snapshots are stable, but WASI as a whole is evolving. diff --git a/proposals/clocks/snapshots/make-snapshot.sh b/proposals/clocks/snapshots/make-snapshot.sh new file mode 100755 index 000000000..b7c177f2f --- /dev/null +++ b/proposals/clocks/snapshots/make-snapshot.sh @@ -0,0 +1,159 @@ +#!/bin/bash +# Creates a snapshot based on upstream proposal repositories. +# Derived from update-testsuite.sh in https://github.com/WebAssembly/testsuite +set -e +set -u +set -o pipefail + +ignore_dirs='' + +# TODO: Add the rest. +repos=' + WASI + wasi-filesystem + wasi-clocks + wasi-random +' + +log_and_run() { + echo ">>" $* + if ! $*; then + echo "sub-command failed: $*" + exit + fi +} + +try_log_and_run() { + echo ">>" $* + $* +} + +pushdir() { + pushd $1 >/dev/null || exit +} + +popdir() { + popd >/dev/null || exit +} + +update_repo() { + local repo=$1 + pushdir repos + if [ -d ${repo} ]; then + log_and_run git -C ${repo} fetch origin + log_and_run git -C ${repo} reset origin/master --hard + else + log_and_run git clone https://github.com/WebAssembly/${repo} + fi + + # Add upstream WASI as "WASI" remote. + if [ "${repo}" != "WASI" ]; then + pushdir ${repo} + if ! git remote | grep WASI >/dev/null; then + log_and_run git remote add WASI https://github.com/WebAssembly/WASI + fi + + log_and_run git fetch WASI + popdir + fi + popdir +} + +merge_with_WASI() { + local repo=$1 + + [ "${repo}" == "WASI" ] && return + + pushdir repos/${repo} + # Create and checkout "try-merge" branch. + if ! git branch | grep try-merge >/dev/null; then + log_and_run git branch try-merge origin/master + fi + log_and_run git checkout try-merge + + # Attempt to merge with WASI/master. + log_and_run git reset origin/master --hard + try_log_and_run git merge -q WASI/master -m "merged" + if [ $? -ne 0 ]; then + # Ignore merge conflicts in non-test directories. + # We don't care about those changes. + try_log_and_run git checkout --ours ${ignore_dirs} + try_log_and_run git add ${ignore_dirs} + try_log_and_run git -c core.editor=true merge --continue + if [ $? -ne 0 ]; then + git merge --abort + popdir + return 1 + fi + fi + popdir + return 0 +} + +snapshot_name=$(date --iso-8601) +snapshot_dir=snapshots/$snapshot_name +mkdir -p $snapshot_dir + +commit_message_file=$PWD/commit_message +echo -e "Update repos\n" > $commit_message_file + +failed_repos= + +for repo in ${repos}; do + echo "++ updating ${repo}" + update_repo ${repo} + + if ! merge_with_WASI ${repo}; then + echo -e "!! error merging ${repo}, skipping\n" + failed_repos="${failed_repos} ${repo}" + continue + fi + + if [ "${repo}" = "WASI" ]; then + dest_dir=$snapshot_dir + log_and_run cp -r repos/${repo}/standard ${dest_dir} + else + dest_dir=$snapshot_dir/proposals/${repo} + mkdir -p ${dest_dir} + + # Don't add tests from proposal that are the same as WASI. + pushdir repos/${repo} + for new in $(find standard -type f); do + old=../../repos/WASI/${new} + if [[ ! -f ${old} ]] || ! diff ${old} ${new} >/dev/null; then + log_and_run cp ${new} ../../${dest_dir} + fi + done + popdir + fi + + # Check whether any files were removed. + for old in $(find ${dest_dir} -type f); do + new=$(find repos/${repo}/standard -name ${old##*/}) + if [[ ! -f ${new} ]]; then + log_and_run git rm ${old} + fi + done + + # Check whether any files were updated. + if [ $(git status -s ${dest_dir} | wc -l) -ne 0 ]; then + log_and_run git add ${dest_dir}/* + + repo_sha=$(git -C repos/${repo} log --max-count=1 --oneline origin/master| sed -e 's/ .*//') + echo " ${repo}:" >> $commit_message_file + echo " https://github.com/WebAssembly/${repo}/commit/${repo_sha}" >> $commit_message_file + fi + + echo -e "-- ${repo}\n" +done + +echo "" >> $commit_message_file +echo "This change was automatically generated by \`make-snapshot.sh\`" >> $commit_message_file +git commit -a -F $commit_message_file +# git push + +echo "done" + +if [ -n "${failed_repos}" ]; then + echo "!! failed to update repos: ${failed_repos}" +fi diff --git a/proposals/clocks/standard/README.md b/proposals/clocks/standard/README.md new file mode 100644 index 000000000..ad6f93c7c --- /dev/null +++ b/proposals/clocks/standard/README.md @@ -0,0 +1,12 @@ +# WASI Standard + +In the [main WASI repository], this directory holds proposals which have +[completed the standardization process]. + +In a proposal repository, which is a fork of the main WASI repository, +this directory holds the current proposal, including witx specifications, +tests, and documentation. When the proposal is standardized, the fork is +merged into the main repository. + +[main WASI repository]: https://github.com/WebAssembly/WASI/issues/360 +[completed the standardization process]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md#5-the-feature-is-standardized-working-group From 9d2bf33bd0b86246338651b0a5cf3f75d204fcbd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 10 Dec 2020 12:59:21 -0800 Subject: [PATCH 0809/1772] Reorganize the directory structure to better support proposals. Following the organization sketched out here: https://github.com/WebAssembly/WASI/issues/360 This PR adds several new directories and starts a work-in-progress make-snapshot.sh script for creating snapshots. The `phases` directory is not yet removed; that can happen once we've transitioned everything to the new organization. --- proposals/random/proposal-template/README.md | 4 + proposals/random/proposals/README.md | 8 + proposals/random/repos/README.md | 7 + proposals/random/snapshots/README.md | 5 + proposals/random/snapshots/make-snapshot.sh | 159 +++++++++++++++++++ proposals/random/standard/README.md | 12 ++ 6 files changed, 195 insertions(+) create mode 100644 proposals/random/proposal-template/README.md create mode 100644 proposals/random/proposals/README.md create mode 100644 proposals/random/repos/README.md create mode 100644 proposals/random/snapshots/README.md create mode 100755 proposals/random/snapshots/make-snapshot.sh create mode 100644 proposals/random/standard/README.md diff --git a/proposals/random/proposal-template/README.md b/proposals/random/proposal-template/README.md new file mode 100644 index 000000000..b97035935 --- /dev/null +++ b/proposals/random/proposal-template/README.md @@ -0,0 +1,4 @@ +# Proposal template + +This directory will hold a template for creating new proposals, to help people +get started. diff --git a/proposals/random/proposals/README.md b/proposals/random/proposals/README.md new file mode 100644 index 000000000..45c2c2852 --- /dev/null +++ b/proposals/random/proposals/README.md @@ -0,0 +1,8 @@ +# Proposals + +This directory contains overviews for proposals that are included in this +repository. + +This is analogous to [the correpsonding directory in the spec repository]. + +[the correpsonding directory in the spec repository]: https://github.com/WebAssembly/spec/tree/master/proposals diff --git a/proposals/random/repos/README.md b/proposals/random/repos/README.md new file mode 100644 index 000000000..c628b3f0d --- /dev/null +++ b/proposals/random/repos/README.md @@ -0,0 +1,7 @@ +The spec and proposal repositories will be cloned in this directory by the +make-testsuite.sh script. Don't apply local changes to these repositories, as +the script may destroy them. + +This is analogous to [the coresponding wasm testsuite directory]. + +[the coresponding wasm testsuite directory]: https://github.com/WebAssembly/testsuite/tree/master/repos diff --git a/proposals/random/snapshots/README.md b/proposals/random/snapshots/README.md new file mode 100644 index 000000000..af94dbdef --- /dev/null +++ b/proposals/random/snapshots/README.md @@ -0,0 +1,5 @@ +# WASI Snapshots + +To balance between the needs of development and stability, snapshots +represent the state of all active proposals at a moment in time. Individual +Snapshots are stable, but WASI as a whole is evolving. diff --git a/proposals/random/snapshots/make-snapshot.sh b/proposals/random/snapshots/make-snapshot.sh new file mode 100755 index 000000000..b7c177f2f --- /dev/null +++ b/proposals/random/snapshots/make-snapshot.sh @@ -0,0 +1,159 @@ +#!/bin/bash +# Creates a snapshot based on upstream proposal repositories. +# Derived from update-testsuite.sh in https://github.com/WebAssembly/testsuite +set -e +set -u +set -o pipefail + +ignore_dirs='' + +# TODO: Add the rest. +repos=' + WASI + wasi-filesystem + wasi-clocks + wasi-random +' + +log_and_run() { + echo ">>" $* + if ! $*; then + echo "sub-command failed: $*" + exit + fi +} + +try_log_and_run() { + echo ">>" $* + $* +} + +pushdir() { + pushd $1 >/dev/null || exit +} + +popdir() { + popd >/dev/null || exit +} + +update_repo() { + local repo=$1 + pushdir repos + if [ -d ${repo} ]; then + log_and_run git -C ${repo} fetch origin + log_and_run git -C ${repo} reset origin/master --hard + else + log_and_run git clone https://github.com/WebAssembly/${repo} + fi + + # Add upstream WASI as "WASI" remote. + if [ "${repo}" != "WASI" ]; then + pushdir ${repo} + if ! git remote | grep WASI >/dev/null; then + log_and_run git remote add WASI https://github.com/WebAssembly/WASI + fi + + log_and_run git fetch WASI + popdir + fi + popdir +} + +merge_with_WASI() { + local repo=$1 + + [ "${repo}" == "WASI" ] && return + + pushdir repos/${repo} + # Create and checkout "try-merge" branch. + if ! git branch | grep try-merge >/dev/null; then + log_and_run git branch try-merge origin/master + fi + log_and_run git checkout try-merge + + # Attempt to merge with WASI/master. + log_and_run git reset origin/master --hard + try_log_and_run git merge -q WASI/master -m "merged" + if [ $? -ne 0 ]; then + # Ignore merge conflicts in non-test directories. + # We don't care about those changes. + try_log_and_run git checkout --ours ${ignore_dirs} + try_log_and_run git add ${ignore_dirs} + try_log_and_run git -c core.editor=true merge --continue + if [ $? -ne 0 ]; then + git merge --abort + popdir + return 1 + fi + fi + popdir + return 0 +} + +snapshot_name=$(date --iso-8601) +snapshot_dir=snapshots/$snapshot_name +mkdir -p $snapshot_dir + +commit_message_file=$PWD/commit_message +echo -e "Update repos\n" > $commit_message_file + +failed_repos= + +for repo in ${repos}; do + echo "++ updating ${repo}" + update_repo ${repo} + + if ! merge_with_WASI ${repo}; then + echo -e "!! error merging ${repo}, skipping\n" + failed_repos="${failed_repos} ${repo}" + continue + fi + + if [ "${repo}" = "WASI" ]; then + dest_dir=$snapshot_dir + log_and_run cp -r repos/${repo}/standard ${dest_dir} + else + dest_dir=$snapshot_dir/proposals/${repo} + mkdir -p ${dest_dir} + + # Don't add tests from proposal that are the same as WASI. + pushdir repos/${repo} + for new in $(find standard -type f); do + old=../../repos/WASI/${new} + if [[ ! -f ${old} ]] || ! diff ${old} ${new} >/dev/null; then + log_and_run cp ${new} ../../${dest_dir} + fi + done + popdir + fi + + # Check whether any files were removed. + for old in $(find ${dest_dir} -type f); do + new=$(find repos/${repo}/standard -name ${old##*/}) + if [[ ! -f ${new} ]]; then + log_and_run git rm ${old} + fi + done + + # Check whether any files were updated. + if [ $(git status -s ${dest_dir} | wc -l) -ne 0 ]; then + log_and_run git add ${dest_dir}/* + + repo_sha=$(git -C repos/${repo} log --max-count=1 --oneline origin/master| sed -e 's/ .*//') + echo " ${repo}:" >> $commit_message_file + echo " https://github.com/WebAssembly/${repo}/commit/${repo_sha}" >> $commit_message_file + fi + + echo -e "-- ${repo}\n" +done + +echo "" >> $commit_message_file +echo "This change was automatically generated by \`make-snapshot.sh\`" >> $commit_message_file +git commit -a -F $commit_message_file +# git push + +echo "done" + +if [ -n "${failed_repos}" ]; then + echo "!! failed to update repos: ${failed_repos}" +fi diff --git a/proposals/random/standard/README.md b/proposals/random/standard/README.md new file mode 100644 index 000000000..ad6f93c7c --- /dev/null +++ b/proposals/random/standard/README.md @@ -0,0 +1,12 @@ +# WASI Standard + +In the [main WASI repository], this directory holds proposals which have +[completed the standardization process]. + +In a proposal repository, which is a fork of the main WASI repository, +this directory holds the current proposal, including witx specifications, +tests, and documentation. When the proposal is standardized, the fork is +merged into the main repository. + +[main WASI repository]: https://github.com/WebAssembly/WASI/issues/360 +[completed the standardization process]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md#5-the-feature-is-standardized-working-group From 8c7c2e2be6746d1a68d2e6a054e0a35178cc9f9e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 10 Dec 2020 12:59:21 -0800 Subject: [PATCH 0810/1772] Reorganize the directory structure to better support proposals. Following the organization sketched out here: https://github.com/WebAssembly/WASI/issues/360 This PR adds several new directories and starts a work-in-progress make-snapshot.sh script for creating snapshots. The `phases` directory is not yet removed; that can happen once we've transitioned everything to the new organization. --- .../filesystem/proposal-template/README.md | 4 + proposals/filesystem/proposals/README.md | 8 + proposals/filesystem/repos/README.md | 7 + proposals/filesystem/snapshots/README.md | 5 + .../filesystem/snapshots/make-snapshot.sh | 159 ++++++++++++++++++ proposals/filesystem/standard/README.md | 12 ++ 6 files changed, 195 insertions(+) create mode 100644 proposals/filesystem/proposal-template/README.md create mode 100644 proposals/filesystem/proposals/README.md create mode 100644 proposals/filesystem/repos/README.md create mode 100644 proposals/filesystem/snapshots/README.md create mode 100755 proposals/filesystem/snapshots/make-snapshot.sh create mode 100644 proposals/filesystem/standard/README.md diff --git a/proposals/filesystem/proposal-template/README.md b/proposals/filesystem/proposal-template/README.md new file mode 100644 index 000000000..b97035935 --- /dev/null +++ b/proposals/filesystem/proposal-template/README.md @@ -0,0 +1,4 @@ +# Proposal template + +This directory will hold a template for creating new proposals, to help people +get started. diff --git a/proposals/filesystem/proposals/README.md b/proposals/filesystem/proposals/README.md new file mode 100644 index 000000000..45c2c2852 --- /dev/null +++ b/proposals/filesystem/proposals/README.md @@ -0,0 +1,8 @@ +# Proposals + +This directory contains overviews for proposals that are included in this +repository. + +This is analogous to [the correpsonding directory in the spec repository]. + +[the correpsonding directory in the spec repository]: https://github.com/WebAssembly/spec/tree/master/proposals diff --git a/proposals/filesystem/repos/README.md b/proposals/filesystem/repos/README.md new file mode 100644 index 000000000..c628b3f0d --- /dev/null +++ b/proposals/filesystem/repos/README.md @@ -0,0 +1,7 @@ +The spec and proposal repositories will be cloned in this directory by the +make-testsuite.sh script. Don't apply local changes to these repositories, as +the script may destroy them. + +This is analogous to [the coresponding wasm testsuite directory]. + +[the coresponding wasm testsuite directory]: https://github.com/WebAssembly/testsuite/tree/master/repos diff --git a/proposals/filesystem/snapshots/README.md b/proposals/filesystem/snapshots/README.md new file mode 100644 index 000000000..af94dbdef --- /dev/null +++ b/proposals/filesystem/snapshots/README.md @@ -0,0 +1,5 @@ +# WASI Snapshots + +To balance between the needs of development and stability, snapshots +represent the state of all active proposals at a moment in time. Individual +Snapshots are stable, but WASI as a whole is evolving. diff --git a/proposals/filesystem/snapshots/make-snapshot.sh b/proposals/filesystem/snapshots/make-snapshot.sh new file mode 100755 index 000000000..b7c177f2f --- /dev/null +++ b/proposals/filesystem/snapshots/make-snapshot.sh @@ -0,0 +1,159 @@ +#!/bin/bash +# Creates a snapshot based on upstream proposal repositories. +# Derived from update-testsuite.sh in https://github.com/WebAssembly/testsuite +set -e +set -u +set -o pipefail + +ignore_dirs='' + +# TODO: Add the rest. +repos=' + WASI + wasi-filesystem + wasi-clocks + wasi-random +' + +log_and_run() { + echo ">>" $* + if ! $*; then + echo "sub-command failed: $*" + exit + fi +} + +try_log_and_run() { + echo ">>" $* + $* +} + +pushdir() { + pushd $1 >/dev/null || exit +} + +popdir() { + popd >/dev/null || exit +} + +update_repo() { + local repo=$1 + pushdir repos + if [ -d ${repo} ]; then + log_and_run git -C ${repo} fetch origin + log_and_run git -C ${repo} reset origin/master --hard + else + log_and_run git clone https://github.com/WebAssembly/${repo} + fi + + # Add upstream WASI as "WASI" remote. + if [ "${repo}" != "WASI" ]; then + pushdir ${repo} + if ! git remote | grep WASI >/dev/null; then + log_and_run git remote add WASI https://github.com/WebAssembly/WASI + fi + + log_and_run git fetch WASI + popdir + fi + popdir +} + +merge_with_WASI() { + local repo=$1 + + [ "${repo}" == "WASI" ] && return + + pushdir repos/${repo} + # Create and checkout "try-merge" branch. + if ! git branch | grep try-merge >/dev/null; then + log_and_run git branch try-merge origin/master + fi + log_and_run git checkout try-merge + + # Attempt to merge with WASI/master. + log_and_run git reset origin/master --hard + try_log_and_run git merge -q WASI/master -m "merged" + if [ $? -ne 0 ]; then + # Ignore merge conflicts in non-test directories. + # We don't care about those changes. + try_log_and_run git checkout --ours ${ignore_dirs} + try_log_and_run git add ${ignore_dirs} + try_log_and_run git -c core.editor=true merge --continue + if [ $? -ne 0 ]; then + git merge --abort + popdir + return 1 + fi + fi + popdir + return 0 +} + +snapshot_name=$(date --iso-8601) +snapshot_dir=snapshots/$snapshot_name +mkdir -p $snapshot_dir + +commit_message_file=$PWD/commit_message +echo -e "Update repos\n" > $commit_message_file + +failed_repos= + +for repo in ${repos}; do + echo "++ updating ${repo}" + update_repo ${repo} + + if ! merge_with_WASI ${repo}; then + echo -e "!! error merging ${repo}, skipping\n" + failed_repos="${failed_repos} ${repo}" + continue + fi + + if [ "${repo}" = "WASI" ]; then + dest_dir=$snapshot_dir + log_and_run cp -r repos/${repo}/standard ${dest_dir} + else + dest_dir=$snapshot_dir/proposals/${repo} + mkdir -p ${dest_dir} + + # Don't add tests from proposal that are the same as WASI. + pushdir repos/${repo} + for new in $(find standard -type f); do + old=../../repos/WASI/${new} + if [[ ! -f ${old} ]] || ! diff ${old} ${new} >/dev/null; then + log_and_run cp ${new} ../../${dest_dir} + fi + done + popdir + fi + + # Check whether any files were removed. + for old in $(find ${dest_dir} -type f); do + new=$(find repos/${repo}/standard -name ${old##*/}) + if [[ ! -f ${new} ]]; then + log_and_run git rm ${old} + fi + done + + # Check whether any files were updated. + if [ $(git status -s ${dest_dir} | wc -l) -ne 0 ]; then + log_and_run git add ${dest_dir}/* + + repo_sha=$(git -C repos/${repo} log --max-count=1 --oneline origin/master| sed -e 's/ .*//') + echo " ${repo}:" >> $commit_message_file + echo " https://github.com/WebAssembly/${repo}/commit/${repo_sha}" >> $commit_message_file + fi + + echo -e "-- ${repo}\n" +done + +echo "" >> $commit_message_file +echo "This change was automatically generated by \`make-snapshot.sh\`" >> $commit_message_file +git commit -a -F $commit_message_file +# git push + +echo "done" + +if [ -n "${failed_repos}" ]; then + echo "!! failed to update repos: ${failed_repos}" +fi diff --git a/proposals/filesystem/standard/README.md b/proposals/filesystem/standard/README.md new file mode 100644 index 000000000..ad6f93c7c --- /dev/null +++ b/proposals/filesystem/standard/README.md @@ -0,0 +1,12 @@ +# WASI Standard + +In the [main WASI repository], this directory holds proposals which have +[completed the standardization process]. + +In a proposal repository, which is a fork of the main WASI repository, +this directory holds the current proposal, including witx specifications, +tests, and documentation. When the proposal is standardized, the fork is +merged into the main repository. + +[main WASI repository]: https://github.com/WebAssembly/WASI/issues/360 +[completed the standardization process]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md#5-the-feature-is-standardized-working-group From d7153bd8ccc59aaaac0884be2be010d8a162333e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 13 Jan 2021 12:00:41 -0800 Subject: [PATCH 0811/1772] Remove `repos`. --- proposals/clocks/repos/README.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 proposals/clocks/repos/README.md diff --git a/proposals/clocks/repos/README.md b/proposals/clocks/repos/README.md deleted file mode 100644 index c628b3f0d..000000000 --- a/proposals/clocks/repos/README.md +++ /dev/null @@ -1,7 +0,0 @@ -The spec and proposal repositories will be cloned in this directory by the -make-testsuite.sh script. Don't apply local changes to these repositories, as -the script may destroy them. - -This is analogous to [the coresponding wasm testsuite directory]. - -[the coresponding wasm testsuite directory]: https://github.com/WebAssembly/testsuite/tree/master/repos From fbe8884f0a1975ce41a85223083fc7233f9358ae Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 13 Jan 2021 12:00:41 -0800 Subject: [PATCH 0812/1772] Remove `repos`. --- proposals/random/repos/README.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 proposals/random/repos/README.md diff --git a/proposals/random/repos/README.md b/proposals/random/repos/README.md deleted file mode 100644 index c628b3f0d..000000000 --- a/proposals/random/repos/README.md +++ /dev/null @@ -1,7 +0,0 @@ -The spec and proposal repositories will be cloned in this directory by the -make-testsuite.sh script. Don't apply local changes to these repositories, as -the script may destroy them. - -This is analogous to [the coresponding wasm testsuite directory]. - -[the coresponding wasm testsuite directory]: https://github.com/WebAssembly/testsuite/tree/master/repos From 3ccddfed4c1b9edb8138324eccd49b51f9575e5e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 13 Jan 2021 12:00:41 -0800 Subject: [PATCH 0813/1772] Remove `repos`. --- proposals/filesystem/repos/README.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 proposals/filesystem/repos/README.md diff --git a/proposals/filesystem/repos/README.md b/proposals/filesystem/repos/README.md deleted file mode 100644 index c628b3f0d..000000000 --- a/proposals/filesystem/repos/README.md +++ /dev/null @@ -1,7 +0,0 @@ -The spec and proposal repositories will be cloned in this directory by the -make-testsuite.sh script. Don't apply local changes to these repositories, as -the script may destroy them. - -This is analogous to [the coresponding wasm testsuite directory]. - -[the coresponding wasm testsuite directory]: https://github.com/WebAssembly/testsuite/tree/master/repos From 4d08c7fd1440b5aeb52d45d2c1739bb54d7aed42 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 19 Jan 2021 16:21:39 -0800 Subject: [PATCH 0814/1772] correct WASI branch name references from `master` to `main` (#376) * correct WASI branch name references from `master` to `main` * snapshotting script: update `master` branch to `main` --- proposals/clocks/docs/DesignPrinciples.md | 4 ++-- proposals/clocks/docs/Proposals.md | 4 ++-- proposals/clocks/meetings/2019/WASI-05-02.md | 2 +- proposals/clocks/meetings/2019/WASI-05-16.md | 2 +- proposals/clocks/meetings/2019/WASI-05-30.md | 2 +- proposals/clocks/meetings/2019/WASI-06-27.md | 2 +- proposals/clocks/meetings/2019/WASI-07-18.md | 2 +- proposals/clocks/meetings/2019/WASI-10-15.md | 4 ++-- proposals/clocks/phases/README.md | 2 +- .../clocks/phases/old/snapshot_0/witx/typenames.witx | 2 +- proposals/clocks/snapshots/make-snapshot.sh | 12 ++++++------ 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/proposals/clocks/docs/DesignPrinciples.md b/proposals/clocks/docs/DesignPrinciples.md index 9d0bfcedb..df82c8692 100644 --- a/proposals/clocks/docs/DesignPrinciples.md +++ b/proposals/clocks/docs/DesignPrinciples.md @@ -80,7 +80,7 @@ so. WASI also aims to include domain-specific APIs, such as database, blockchain, or specialized APIs for embedded systems. Another key building block for WASI is [optional -imports](https://github.com/WebAssembly/WASI/blob/master/design/optional-imports.md), +imports](https://github.com/WebAssembly/WASI/blob/main/design/optional-imports.md), which give applications the ability to dynamically test for the availability of APIs. @@ -226,7 +226,7 @@ we're not actually depending on them yet, however we are carefully aligning with them so that we'll be ready when they are. As another example, WASI's -[witx](https://github.com/WebAssembly/WASI/blob/master/docs/witx.md) +[witx](https://github.com/WebAssembly/WASI/blob/main/docs/witx.md) file format is designed to be a straightforward superset of the [module linking proposal](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md)'s diff --git a/proposals/clocks/docs/Proposals.md b/proposals/clocks/docs/Proposals.md index e16a8820e..8bff83eb4 100644 --- a/proposals/clocks/docs/Proposals.md +++ b/proposals/clocks/docs/Proposals.md @@ -6,11 +6,11 @@ adoption of this process and so don't fit exactly into the defined phases, however our intention is to align them going forward. [WASI]: https://github.com/WebAssembly/WASI -[proposals page]: https://github.com/WebAssembly/proposals/blob/master/README.md +[proposals page]: https://github.com/WebAssembly/proposals/blob/main/README.md ## Active proposals -Proposals follow [this process document](https://github.com/WebAssembly/WASI/blob/master/docs/Process.md). +Proposals follow [this process document](https://github.com/WebAssembly/WASI/blob/main/docs/Process.md). ### Phase 4 - Standardize the Feature (WG) diff --git a/proposals/clocks/meetings/2019/WASI-05-02.md b/proposals/clocks/meetings/2019/WASI-05-02.md index f23ec4f50..68fbb58de 100644 --- a/proposals/clocks/meetings/2019/WASI-05-02.md +++ b/proposals/clocks/meetings/2019/WASI-05-02.md @@ -63,7 +63,7 @@ Installation is required, see the calendar invite. 2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-02.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-05-02.md Attendees: diff --git a/proposals/clocks/meetings/2019/WASI-05-16.md b/proposals/clocks/meetings/2019/WASI-05-16.md index d0101162b..65eeb45b7 100644 --- a/proposals/clocks/meetings/2019/WASI-05-16.md +++ b/proposals/clocks/meetings/2019/WASI-05-16.md @@ -64,7 +64,7 @@ Installation is required, see the calendar invite. 2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-16.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-05-16.md Attendees: diff --git a/proposals/clocks/meetings/2019/WASI-05-30.md b/proposals/clocks/meetings/2019/WASI-05-30.md index a48231332..d6c773aa7 100644 --- a/proposals/clocks/meetings/2019/WASI-05-30.md +++ b/proposals/clocks/meetings/2019/WASI-05-30.md @@ -54,7 +54,7 @@ Installation is required, see the calendar invite. 2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-30.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-05-30.md Attendees: diff --git a/proposals/clocks/meetings/2019/WASI-06-27.md b/proposals/clocks/meetings/2019/WASI-06-27.md index af55fe748..d988ee47b 100644 --- a/proposals/clocks/meetings/2019/WASI-06-27.md +++ b/proposals/clocks/meetings/2019/WASI-06-27.md @@ -57,7 +57,7 @@ Installation is required, see the calendar invite. 2019-06-27 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-06-27.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-06-27.md Attendees: diff --git a/proposals/clocks/meetings/2019/WASI-07-18.md b/proposals/clocks/meetings/2019/WASI-07-18.md index 6d275e700..670da9f4d 100644 --- a/proposals/clocks/meetings/2019/WASI-07-18.md +++ b/proposals/clocks/meetings/2019/WASI-07-18.md @@ -53,7 +53,7 @@ Installation is required, see the calendar invite. 2019-07-18 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-07-18.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-07-18.md Attendees: diff --git a/proposals/clocks/meetings/2019/WASI-10-15.md b/proposals/clocks/meetings/2019/WASI-10-15.md index 96df21e3f..4a9566f3d 100644 --- a/proposals/clocks/meetings/2019/WASI-10-15.md +++ b/proposals/clocks/meetings/2019/WASI-10-15.md @@ -73,7 +73,7 @@ Jorge: Version management? Pat: optional imports may alleviate some of the versioning problems too -Presentation: [“What HTTP Needs from WebAssembly”](https://github.com/WebAssembly/WASI/blob/master/meetings/2019/What%20HTTP%20Needs%20from%20WebAssembly.pdf), Mark Nottingham +Presentation: [“What HTTP Needs from WebAssembly”](https://github.com/WebAssembly/WASI/blob/main/meetings/2019/What%20HTTP%20Needs%20from%20WebAssembly.pdf), Mark Nottingham Roberto: What about multiple headers with one name? Mark: [paraphrase] we probably need to talk about that @@ -82,7 +82,7 @@ Dan: Does this include DNS? Mark: Yes, the API accepts names, and they are translated implicitly Discussion of optional imports, which will be important as different use cases will need different parts of these APIs. -Spec: https://github.com/WebAssembly/WASI/blob/master/design/optional-imports.md +Spec: https://github.com/WebAssembly/WASI/blob/main/design/optional-imports.md (general presentation of the people in the meeting) diff --git a/proposals/clocks/phases/README.md b/proposals/clocks/phases/README.md index 62c5f9004..9f66686bd 100644 --- a/proposals/clocks/phases/README.md +++ b/proposals/clocks/phases/README.md @@ -9,7 +9,7 @@ for a balance between the need for stability to allow people to build compatible implementations, libraries, and tools and gain implementation experience, and the need for proposals to evolve. -[process]: https://github.com/WebAssembly/WASI/blob/master/docs/Process.md +[process]: https://github.com/WebAssembly/WASI/blob/main/docs/Process.md ## The ephemeral/snapshot/old Phases diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx index 1a795c13c..74ff0835a 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx @@ -2,7 +2,7 @@ ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). ;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/main/docs/witx.md) ;; for an explanation of what that means. (typename $size u32) diff --git a/proposals/clocks/snapshots/make-snapshot.sh b/proposals/clocks/snapshots/make-snapshot.sh index b7c177f2f..b30dfa2e5 100755 --- a/proposals/clocks/snapshots/make-snapshot.sh +++ b/proposals/clocks/snapshots/make-snapshot.sh @@ -41,7 +41,7 @@ update_repo() { pushdir repos if [ -d ${repo} ]; then log_and_run git -C ${repo} fetch origin - log_and_run git -C ${repo} reset origin/master --hard + log_and_run git -C ${repo} reset origin/main --hard else log_and_run git clone https://github.com/WebAssembly/${repo} fi @@ -67,13 +67,13 @@ merge_with_WASI() { pushdir repos/${repo} # Create and checkout "try-merge" branch. if ! git branch | grep try-merge >/dev/null; then - log_and_run git branch try-merge origin/master + log_and_run git branch try-merge origin/main fi log_and_run git checkout try-merge - # Attempt to merge with WASI/master. - log_and_run git reset origin/master --hard - try_log_and_run git merge -q WASI/master -m "merged" + # Attempt to merge with WASI/main. + log_and_run git reset origin/main --hard + try_log_and_run git merge -q WASI/main -m "merged" if [ $? -ne 0 ]; then # Ignore merge conflicts in non-test directories. # We don't care about those changes. @@ -139,7 +139,7 @@ for repo in ${repos}; do if [ $(git status -s ${dest_dir} | wc -l) -ne 0 ]; then log_and_run git add ${dest_dir}/* - repo_sha=$(git -C repos/${repo} log --max-count=1 --oneline origin/master| sed -e 's/ .*//') + repo_sha=$(git -C repos/${repo} log --max-count=1 --oneline origin/main| sed -e 's/ .*//') echo " ${repo}:" >> $commit_message_file echo " https://github.com/WebAssembly/${repo}/commit/${repo_sha}" >> $commit_message_file fi From fdcae483bb56f560f53cf573258bbd5c021c8f8a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 19 Jan 2021 16:21:39 -0800 Subject: [PATCH 0815/1772] correct WASI branch name references from `master` to `main` (#376) * correct WASI branch name references from `master` to `main` * snapshotting script: update `master` branch to `main` --- proposals/random/docs/DesignPrinciples.md | 4 ++-- proposals/random/docs/Proposals.md | 4 ++-- proposals/random/meetings/2019/WASI-05-02.md | 2 +- proposals/random/meetings/2019/WASI-05-16.md | 2 +- proposals/random/meetings/2019/WASI-05-30.md | 2 +- proposals/random/meetings/2019/WASI-06-27.md | 2 +- proposals/random/meetings/2019/WASI-07-18.md | 2 +- proposals/random/meetings/2019/WASI-10-15.md | 4 ++-- proposals/random/phases/README.md | 2 +- .../random/phases/old/snapshot_0/witx/typenames.witx | 2 +- proposals/random/snapshots/make-snapshot.sh | 12 ++++++------ 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/proposals/random/docs/DesignPrinciples.md b/proposals/random/docs/DesignPrinciples.md index 9d0bfcedb..df82c8692 100644 --- a/proposals/random/docs/DesignPrinciples.md +++ b/proposals/random/docs/DesignPrinciples.md @@ -80,7 +80,7 @@ so. WASI also aims to include domain-specific APIs, such as database, blockchain, or specialized APIs for embedded systems. Another key building block for WASI is [optional -imports](https://github.com/WebAssembly/WASI/blob/master/design/optional-imports.md), +imports](https://github.com/WebAssembly/WASI/blob/main/design/optional-imports.md), which give applications the ability to dynamically test for the availability of APIs. @@ -226,7 +226,7 @@ we're not actually depending on them yet, however we are carefully aligning with them so that we'll be ready when they are. As another example, WASI's -[witx](https://github.com/WebAssembly/WASI/blob/master/docs/witx.md) +[witx](https://github.com/WebAssembly/WASI/blob/main/docs/witx.md) file format is designed to be a straightforward superset of the [module linking proposal](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md)'s diff --git a/proposals/random/docs/Proposals.md b/proposals/random/docs/Proposals.md index e16a8820e..8bff83eb4 100644 --- a/proposals/random/docs/Proposals.md +++ b/proposals/random/docs/Proposals.md @@ -6,11 +6,11 @@ adoption of this process and so don't fit exactly into the defined phases, however our intention is to align them going forward. [WASI]: https://github.com/WebAssembly/WASI -[proposals page]: https://github.com/WebAssembly/proposals/blob/master/README.md +[proposals page]: https://github.com/WebAssembly/proposals/blob/main/README.md ## Active proposals -Proposals follow [this process document](https://github.com/WebAssembly/WASI/blob/master/docs/Process.md). +Proposals follow [this process document](https://github.com/WebAssembly/WASI/blob/main/docs/Process.md). ### Phase 4 - Standardize the Feature (WG) diff --git a/proposals/random/meetings/2019/WASI-05-02.md b/proposals/random/meetings/2019/WASI-05-02.md index f23ec4f50..68fbb58de 100644 --- a/proposals/random/meetings/2019/WASI-05-02.md +++ b/proposals/random/meetings/2019/WASI-05-02.md @@ -63,7 +63,7 @@ Installation is required, see the calendar invite. 2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-02.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-05-02.md Attendees: diff --git a/proposals/random/meetings/2019/WASI-05-16.md b/proposals/random/meetings/2019/WASI-05-16.md index d0101162b..65eeb45b7 100644 --- a/proposals/random/meetings/2019/WASI-05-16.md +++ b/proposals/random/meetings/2019/WASI-05-16.md @@ -64,7 +64,7 @@ Installation is required, see the calendar invite. 2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-16.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-05-16.md Attendees: diff --git a/proposals/random/meetings/2019/WASI-05-30.md b/proposals/random/meetings/2019/WASI-05-30.md index a48231332..d6c773aa7 100644 --- a/proposals/random/meetings/2019/WASI-05-30.md +++ b/proposals/random/meetings/2019/WASI-05-30.md @@ -54,7 +54,7 @@ Installation is required, see the calendar invite. 2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-30.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-05-30.md Attendees: diff --git a/proposals/random/meetings/2019/WASI-06-27.md b/proposals/random/meetings/2019/WASI-06-27.md index af55fe748..d988ee47b 100644 --- a/proposals/random/meetings/2019/WASI-06-27.md +++ b/proposals/random/meetings/2019/WASI-06-27.md @@ -57,7 +57,7 @@ Installation is required, see the calendar invite. 2019-06-27 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-06-27.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-06-27.md Attendees: diff --git a/proposals/random/meetings/2019/WASI-07-18.md b/proposals/random/meetings/2019/WASI-07-18.md index 6d275e700..670da9f4d 100644 --- a/proposals/random/meetings/2019/WASI-07-18.md +++ b/proposals/random/meetings/2019/WASI-07-18.md @@ -53,7 +53,7 @@ Installation is required, see the calendar invite. 2019-07-18 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-07-18.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-07-18.md Attendees: diff --git a/proposals/random/meetings/2019/WASI-10-15.md b/proposals/random/meetings/2019/WASI-10-15.md index 96df21e3f..4a9566f3d 100644 --- a/proposals/random/meetings/2019/WASI-10-15.md +++ b/proposals/random/meetings/2019/WASI-10-15.md @@ -73,7 +73,7 @@ Jorge: Version management? Pat: optional imports may alleviate some of the versioning problems too -Presentation: [“What HTTP Needs from WebAssembly”](https://github.com/WebAssembly/WASI/blob/master/meetings/2019/What%20HTTP%20Needs%20from%20WebAssembly.pdf), Mark Nottingham +Presentation: [“What HTTP Needs from WebAssembly”](https://github.com/WebAssembly/WASI/blob/main/meetings/2019/What%20HTTP%20Needs%20from%20WebAssembly.pdf), Mark Nottingham Roberto: What about multiple headers with one name? Mark: [paraphrase] we probably need to talk about that @@ -82,7 +82,7 @@ Dan: Does this include DNS? Mark: Yes, the API accepts names, and they are translated implicitly Discussion of optional imports, which will be important as different use cases will need different parts of these APIs. -Spec: https://github.com/WebAssembly/WASI/blob/master/design/optional-imports.md +Spec: https://github.com/WebAssembly/WASI/blob/main/design/optional-imports.md (general presentation of the people in the meeting) diff --git a/proposals/random/phases/README.md b/proposals/random/phases/README.md index 62c5f9004..9f66686bd 100644 --- a/proposals/random/phases/README.md +++ b/proposals/random/phases/README.md @@ -9,7 +9,7 @@ for a balance between the need for stability to allow people to build compatible implementations, libraries, and tools and gain implementation experience, and the need for proposals to evolve. -[process]: https://github.com/WebAssembly/WASI/blob/master/docs/Process.md +[process]: https://github.com/WebAssembly/WASI/blob/main/docs/Process.md ## The ephemeral/snapshot/old Phases diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx index 1a795c13c..74ff0835a 100644 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/random/phases/old/snapshot_0/witx/typenames.witx @@ -2,7 +2,7 @@ ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). ;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/main/docs/witx.md) ;; for an explanation of what that means. (typename $size u32) diff --git a/proposals/random/snapshots/make-snapshot.sh b/proposals/random/snapshots/make-snapshot.sh index b7c177f2f..b30dfa2e5 100755 --- a/proposals/random/snapshots/make-snapshot.sh +++ b/proposals/random/snapshots/make-snapshot.sh @@ -41,7 +41,7 @@ update_repo() { pushdir repos if [ -d ${repo} ]; then log_and_run git -C ${repo} fetch origin - log_and_run git -C ${repo} reset origin/master --hard + log_and_run git -C ${repo} reset origin/main --hard else log_and_run git clone https://github.com/WebAssembly/${repo} fi @@ -67,13 +67,13 @@ merge_with_WASI() { pushdir repos/${repo} # Create and checkout "try-merge" branch. if ! git branch | grep try-merge >/dev/null; then - log_and_run git branch try-merge origin/master + log_and_run git branch try-merge origin/main fi log_and_run git checkout try-merge - # Attempt to merge with WASI/master. - log_and_run git reset origin/master --hard - try_log_and_run git merge -q WASI/master -m "merged" + # Attempt to merge with WASI/main. + log_and_run git reset origin/main --hard + try_log_and_run git merge -q WASI/main -m "merged" if [ $? -ne 0 ]; then # Ignore merge conflicts in non-test directories. # We don't care about those changes. @@ -139,7 +139,7 @@ for repo in ${repos}; do if [ $(git status -s ${dest_dir} | wc -l) -ne 0 ]; then log_and_run git add ${dest_dir}/* - repo_sha=$(git -C repos/${repo} log --max-count=1 --oneline origin/master| sed -e 's/ .*//') + repo_sha=$(git -C repos/${repo} log --max-count=1 --oneline origin/main| sed -e 's/ .*//') echo " ${repo}:" >> $commit_message_file echo " https://github.com/WebAssembly/${repo}/commit/${repo_sha}" >> $commit_message_file fi From 4efd0508046f631876858beebf2d664bdf9f36da Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 19 Jan 2021 16:21:39 -0800 Subject: [PATCH 0816/1772] correct WASI branch name references from `master` to `main` (#376) * correct WASI branch name references from `master` to `main` * snapshotting script: update `master` branch to `main` --- proposals/filesystem/docs/DesignPrinciples.md | 4 ++-- proposals/filesystem/docs/Proposals.md | 4 ++-- proposals/filesystem/meetings/2019/WASI-05-02.md | 2 +- proposals/filesystem/meetings/2019/WASI-05-16.md | 2 +- proposals/filesystem/meetings/2019/WASI-05-30.md | 2 +- proposals/filesystem/meetings/2019/WASI-06-27.md | 2 +- proposals/filesystem/meetings/2019/WASI-07-18.md | 2 +- proposals/filesystem/meetings/2019/WASI-10-15.md | 4 ++-- proposals/filesystem/phases/README.md | 2 +- .../phases/old/snapshot_0/witx/typenames.witx | 2 +- proposals/filesystem/snapshots/make-snapshot.sh | 12 ++++++------ 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/proposals/filesystem/docs/DesignPrinciples.md b/proposals/filesystem/docs/DesignPrinciples.md index 9d0bfcedb..df82c8692 100644 --- a/proposals/filesystem/docs/DesignPrinciples.md +++ b/proposals/filesystem/docs/DesignPrinciples.md @@ -80,7 +80,7 @@ so. WASI also aims to include domain-specific APIs, such as database, blockchain, or specialized APIs for embedded systems. Another key building block for WASI is [optional -imports](https://github.com/WebAssembly/WASI/blob/master/design/optional-imports.md), +imports](https://github.com/WebAssembly/WASI/blob/main/design/optional-imports.md), which give applications the ability to dynamically test for the availability of APIs. @@ -226,7 +226,7 @@ we're not actually depending on them yet, however we are carefully aligning with them so that we'll be ready when they are. As another example, WASI's -[witx](https://github.com/WebAssembly/WASI/blob/master/docs/witx.md) +[witx](https://github.com/WebAssembly/WASI/blob/main/docs/witx.md) file format is designed to be a straightforward superset of the [module linking proposal](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md)'s diff --git a/proposals/filesystem/docs/Proposals.md b/proposals/filesystem/docs/Proposals.md index e16a8820e..8bff83eb4 100644 --- a/proposals/filesystem/docs/Proposals.md +++ b/proposals/filesystem/docs/Proposals.md @@ -6,11 +6,11 @@ adoption of this process and so don't fit exactly into the defined phases, however our intention is to align them going forward. [WASI]: https://github.com/WebAssembly/WASI -[proposals page]: https://github.com/WebAssembly/proposals/blob/master/README.md +[proposals page]: https://github.com/WebAssembly/proposals/blob/main/README.md ## Active proposals -Proposals follow [this process document](https://github.com/WebAssembly/WASI/blob/master/docs/Process.md). +Proposals follow [this process document](https://github.com/WebAssembly/WASI/blob/main/docs/Process.md). ### Phase 4 - Standardize the Feature (WG) diff --git a/proposals/filesystem/meetings/2019/WASI-05-02.md b/proposals/filesystem/meetings/2019/WASI-05-02.md index f23ec4f50..68fbb58de 100644 --- a/proposals/filesystem/meetings/2019/WASI-05-02.md +++ b/proposals/filesystem/meetings/2019/WASI-05-02.md @@ -63,7 +63,7 @@ Installation is required, see the calendar invite. 2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-02.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-05-02.md Attendees: diff --git a/proposals/filesystem/meetings/2019/WASI-05-16.md b/proposals/filesystem/meetings/2019/WASI-05-16.md index d0101162b..65eeb45b7 100644 --- a/proposals/filesystem/meetings/2019/WASI-05-16.md +++ b/proposals/filesystem/meetings/2019/WASI-05-16.md @@ -64,7 +64,7 @@ Installation is required, see the calendar invite. 2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-16.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-05-16.md Attendees: diff --git a/proposals/filesystem/meetings/2019/WASI-05-30.md b/proposals/filesystem/meetings/2019/WASI-05-30.md index a48231332..d6c773aa7 100644 --- a/proposals/filesystem/meetings/2019/WASI-05-30.md +++ b/proposals/filesystem/meetings/2019/WASI-05-30.md @@ -54,7 +54,7 @@ Installation is required, see the calendar invite. 2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-05-30.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-05-30.md Attendees: diff --git a/proposals/filesystem/meetings/2019/WASI-06-27.md b/proposals/filesystem/meetings/2019/WASI-06-27.md index af55fe748..d988ee47b 100644 --- a/proposals/filesystem/meetings/2019/WASI-06-27.md +++ b/proposals/filesystem/meetings/2019/WASI-06-27.md @@ -57,7 +57,7 @@ Installation is required, see the calendar invite. 2019-06-27 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-06-27.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-06-27.md Attendees: diff --git a/proposals/filesystem/meetings/2019/WASI-07-18.md b/proposals/filesystem/meetings/2019/WASI-07-18.md index 6d275e700..670da9f4d 100644 --- a/proposals/filesystem/meetings/2019/WASI-07-18.md +++ b/proposals/filesystem/meetings/2019/WASI-07-18.md @@ -53,7 +53,7 @@ Installation is required, see the calendar invite. 2019-07-18 WebAssembly CG WASI Subgroup Video Meeting Notes -Agenda: https://github.com/WebAssembly/WASI/blob/master/meetings/2019/WASI-07-18.md +Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-07-18.md Attendees: diff --git a/proposals/filesystem/meetings/2019/WASI-10-15.md b/proposals/filesystem/meetings/2019/WASI-10-15.md index 96df21e3f..4a9566f3d 100644 --- a/proposals/filesystem/meetings/2019/WASI-10-15.md +++ b/proposals/filesystem/meetings/2019/WASI-10-15.md @@ -73,7 +73,7 @@ Jorge: Version management? Pat: optional imports may alleviate some of the versioning problems too -Presentation: [“What HTTP Needs from WebAssembly”](https://github.com/WebAssembly/WASI/blob/master/meetings/2019/What%20HTTP%20Needs%20from%20WebAssembly.pdf), Mark Nottingham +Presentation: [“What HTTP Needs from WebAssembly”](https://github.com/WebAssembly/WASI/blob/main/meetings/2019/What%20HTTP%20Needs%20from%20WebAssembly.pdf), Mark Nottingham Roberto: What about multiple headers with one name? Mark: [paraphrase] we probably need to talk about that @@ -82,7 +82,7 @@ Dan: Does this include DNS? Mark: Yes, the API accepts names, and they are translated implicitly Discussion of optional imports, which will be important as different use cases will need different parts of these APIs. -Spec: https://github.com/WebAssembly/WASI/blob/master/design/optional-imports.md +Spec: https://github.com/WebAssembly/WASI/blob/main/design/optional-imports.md (general presentation of the people in the meeting) diff --git a/proposals/filesystem/phases/README.md b/proposals/filesystem/phases/README.md index 62c5f9004..9f66686bd 100644 --- a/proposals/filesystem/phases/README.md +++ b/proposals/filesystem/phases/README.md @@ -9,7 +9,7 @@ for a balance between the need for stability to allow people to build compatible implementations, libraries, and tools and gain implementation experience, and the need for proposals to evolve. -[process]: https://github.com/WebAssembly/WASI/blob/master/docs/Process.md +[process]: https://github.com/WebAssembly/WASI/blob/main/docs/Process.md ## The ephemeral/snapshot/old Phases diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx index 1a795c13c..74ff0835a 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx @@ -2,7 +2,7 @@ ;; ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). ;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/main/docs/witx.md) ;; for an explanation of what that means. (typename $size u32) diff --git a/proposals/filesystem/snapshots/make-snapshot.sh b/proposals/filesystem/snapshots/make-snapshot.sh index b7c177f2f..b30dfa2e5 100755 --- a/proposals/filesystem/snapshots/make-snapshot.sh +++ b/proposals/filesystem/snapshots/make-snapshot.sh @@ -41,7 +41,7 @@ update_repo() { pushdir repos if [ -d ${repo} ]; then log_and_run git -C ${repo} fetch origin - log_and_run git -C ${repo} reset origin/master --hard + log_and_run git -C ${repo} reset origin/main --hard else log_and_run git clone https://github.com/WebAssembly/${repo} fi @@ -67,13 +67,13 @@ merge_with_WASI() { pushdir repos/${repo} # Create and checkout "try-merge" branch. if ! git branch | grep try-merge >/dev/null; then - log_and_run git branch try-merge origin/master + log_and_run git branch try-merge origin/main fi log_and_run git checkout try-merge - # Attempt to merge with WASI/master. - log_and_run git reset origin/master --hard - try_log_and_run git merge -q WASI/master -m "merged" + # Attempt to merge with WASI/main. + log_and_run git reset origin/main --hard + try_log_and_run git merge -q WASI/main -m "merged" if [ $? -ne 0 ]; then # Ignore merge conflicts in non-test directories. # We don't care about those changes. @@ -139,7 +139,7 @@ for repo in ${repos}; do if [ $(git status -s ${dest_dir} | wc -l) -ne 0 ]; then log_and_run git add ${dest_dir}/* - repo_sha=$(git -C repos/${repo} log --max-count=1 --oneline origin/master| sed -e 's/ .*//') + repo_sha=$(git -C repos/${repo} log --max-count=1 --oneline origin/main| sed -e 's/ .*//') echo " ${repo}:" >> $commit_message_file echo " https://github.com/WebAssembly/${repo}/commit/${repo_sha}" >> $commit_message_file fi From b59b1e0177e0afb92d40875dcc6fa0aba8f768c3 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 25 Jan 2021 11:30:39 -0500 Subject: [PATCH 0817/1772] Add 01-14 meeting notes --- proposals/clocks/meetings/2021/WASI-01-14.md | 43 +++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/proposals/clocks/meetings/2021/WASI-01-14.md b/proposals/clocks/meetings/2021/WASI-01-14.md index 801201508..9ee3e0be7 100644 --- a/proposals/clocks/meetings/2021/WASI-01-14.md +++ b/proposals/clocks/meetings/2021/WASI-01-14.md @@ -25,10 +25,51 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! +1. Announcement + 1. Pat will be changing branch name from `master` to `main` 1. Review of action items from previous meeting(s). - 1. Dan report on repository organization progress + 1. Lin update on repository organization progress 1. Proposals and discussions 1. Discussion: Testing guidelines for proposals 1. _Sumbit a PR to add your agenda item here_ ## Meeting Notes +### Attendees +Lin Clark +Josh Dolitsky +Dan Gohman +Pat Hickey +Sam Clegg +Casper Beyer +Mark McCaskey +Johnnie Birch +Andrew Brown +Yong He +Peter Engelbert +Peter Huene +Martin Duke +Till Schneidereit +Bogus Wolf + +For people taking notes, just type names; we’ll replace them with abbreviations before posting them publicly. + +**Pat Hickey:** Github is now rolling out features to allow for renaming git branches from “master” to “main”, including blob url redirection. It’s mostly automatic, but it does require people to do some changes locally to update. We’ll put the steps in the WASI github issue tracking this. + +Main topic: Testing. + +**Lin Clark:** + +The context here is WASI modularization -- breaking up the core WASI module into separate modules. + +Pat and Dan are working on a new witx mechanism for expressing dependencies between witx files, allowing modules to depend on each other. + +The main WASI repo will be the source of truth for stage-5 (standardized) proposals. + +Tests should include both the source, in high-level languages, and compiled wasm binaries. + +Things we still need to build: +A test runner +Tests. We’ll start with some tests from Wasmtime, and everyone can add tests. + + + From b1c386086c16cf9b83ccbcd8a596b6a1e95319c3 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 25 Jan 2021 11:30:39 -0500 Subject: [PATCH 0818/1772] Add 01-14 meeting notes --- proposals/random/meetings/2021/WASI-01-14.md | 43 +++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/proposals/random/meetings/2021/WASI-01-14.md b/proposals/random/meetings/2021/WASI-01-14.md index 801201508..9ee3e0be7 100644 --- a/proposals/random/meetings/2021/WASI-01-14.md +++ b/proposals/random/meetings/2021/WASI-01-14.md @@ -25,10 +25,51 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! +1. Announcement + 1. Pat will be changing branch name from `master` to `main` 1. Review of action items from previous meeting(s). - 1. Dan report on repository organization progress + 1. Lin update on repository organization progress 1. Proposals and discussions 1. Discussion: Testing guidelines for proposals 1. _Sumbit a PR to add your agenda item here_ ## Meeting Notes +### Attendees +Lin Clark +Josh Dolitsky +Dan Gohman +Pat Hickey +Sam Clegg +Casper Beyer +Mark McCaskey +Johnnie Birch +Andrew Brown +Yong He +Peter Engelbert +Peter Huene +Martin Duke +Till Schneidereit +Bogus Wolf + +For people taking notes, just type names; we’ll replace them with abbreviations before posting them publicly. + +**Pat Hickey:** Github is now rolling out features to allow for renaming git branches from “master” to “main”, including blob url redirection. It’s mostly automatic, but it does require people to do some changes locally to update. We’ll put the steps in the WASI github issue tracking this. + +Main topic: Testing. + +**Lin Clark:** + +The context here is WASI modularization -- breaking up the core WASI module into separate modules. + +Pat and Dan are working on a new witx mechanism for expressing dependencies between witx files, allowing modules to depend on each other. + +The main WASI repo will be the source of truth for stage-5 (standardized) proposals. + +Tests should include both the source, in high-level languages, and compiled wasm binaries. + +Things we still need to build: +A test runner +Tests. We’ll start with some tests from Wasmtime, and everyone can add tests. + + + From 05dabcf8a829a61608c40f683f877fccbdee314b Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 25 Jan 2021 11:30:39 -0500 Subject: [PATCH 0819/1772] Add 01-14 meeting notes --- .../filesystem/meetings/2021/WASI-01-14.md | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/proposals/filesystem/meetings/2021/WASI-01-14.md b/proposals/filesystem/meetings/2021/WASI-01-14.md index 801201508..9ee3e0be7 100644 --- a/proposals/filesystem/meetings/2021/WASI-01-14.md +++ b/proposals/filesystem/meetings/2021/WASI-01-14.md @@ -25,10 +25,51 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! +1. Announcement + 1. Pat will be changing branch name from `master` to `main` 1. Review of action items from previous meeting(s). - 1. Dan report on repository organization progress + 1. Lin update on repository organization progress 1. Proposals and discussions 1. Discussion: Testing guidelines for proposals 1. _Sumbit a PR to add your agenda item here_ ## Meeting Notes +### Attendees +Lin Clark +Josh Dolitsky +Dan Gohman +Pat Hickey +Sam Clegg +Casper Beyer +Mark McCaskey +Johnnie Birch +Andrew Brown +Yong He +Peter Engelbert +Peter Huene +Martin Duke +Till Schneidereit +Bogus Wolf + +For people taking notes, just type names; we’ll replace them with abbreviations before posting them publicly. + +**Pat Hickey:** Github is now rolling out features to allow for renaming git branches from “master” to “main”, including blob url redirection. It’s mostly automatic, but it does require people to do some changes locally to update. We’ll put the steps in the WASI github issue tracking this. + +Main topic: Testing. + +**Lin Clark:** + +The context here is WASI modularization -- breaking up the core WASI module into separate modules. + +Pat and Dan are working on a new witx mechanism for expressing dependencies between witx files, allowing modules to depend on each other. + +The main WASI repo will be the source of truth for stage-5 (standardized) proposals. + +Tests should include both the source, in high-level languages, and compiled wasm binaries. + +Things we still need to build: +A test runner +Tests. We’ll start with some tests from Wasmtime, and everyone can add tests. + + + From 95b7de4ea3af26a6fb74bcd12105cb8d2360a11c Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 28 Jan 2021 18:15:58 -0500 Subject: [PATCH 0820/1772] Add 01-28 meeting notes --- proposals/clocks/meetings/2021/WASI-01-28.md | 177 ++++++++++++++++++- 1 file changed, 174 insertions(+), 3 deletions(-) diff --git a/proposals/clocks/meetings/2021/WASI-01-28.md b/proposals/clocks/meetings/2021/WASI-01-28.md index 757ab4d4e..cab4dbd21 100644 --- a/proposals/clocks/meetings/2021/WASI-01-28.md +++ b/proposals/clocks/meetings/2021/WASI-01-28.md @@ -25,11 +25,182 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! -1. Review of action items from previous meeting(s). - 1. Dan report on repository organization progress +1. Announcements + 1. Lin Clark on WASI modularization milestone 1. Proposals and discussions 1. Presentation: Update from Luke Wagner on handles and resources in interface types - 1. Discussion: Transitioning WASI APIs to use IT handles 1. _Sumbit a PR to add your agenda item here_ ## Meeting Notes +### Attendees +- Martin Duke, F5 +- Sam Clegg +- Dan Gohman +- Luke Wagner +- Mark McCaskey +- Lin Clark +- Dave Protasowski +- Alex Crichton +- Andrew Brown +- Mingqiu Sun +- Till Schneidereit +- Pat Hickey +- Josh Dolitsky +- Matt Butcher +- Ralph Squillace + +### Announcements +**Lin Clark:** We now have a [milestone for WASI modularization](https://github.com/WebAssembly/WASI/milestone/1). Will be using milestones more in the future. + +### Proposals and discussions +#### Presentation: Update from Luke Wagner on handles and resources in interface types [(Slides)](https://docs.google.com/presentation/d/1ikwS2Ps-KLXFofuS5VAs6Bn14q4LBEaxMjPfLj61UZE) + +**Luke Wagner:** Handles and resources. Have been working on this for a while with a number of y’all +Give background, motivating problems, and proposed solution +Not at all final, still working on a PR. Your feedback is most welcome + +IT gives WASI a bunch of value types +In addition to core basic types, a bunch of abbreviations +Don’t want to have to add core types +This lets us take a WASI function and use a bunch of high level types + +Plan of record for a while has been abstract types for file descriptors +Type imports builds on reference types +Reference types are unforgeable, better than ints + +How does this get virtualized? +Virtualization is a core value of WASI. You can implement with another WASI module +For this, we use module linking proposal + +What does it look like to write that virtualized WASI? (walk through) +Packed the file index into the reference, that’s efficient + +Type imports and exports are transparent by default +This is forgeable. That’s why that was take one + +Type imports has a private type definition +I would take abstract type and make it a private type definition +Private.get and private.new only works inside module that defined the type definition +These private types have to be boxed. +Actually no worse than the native implementation to have one level of indirection + +Two remaining problem areas: resource lifetimes and dynamic casting + +Resource lifetimes +How do resources get released? +Could reference count. +Problematic for a variety of reasons. +Not virtualizable. +Because of downsides, WASI resources have explicit destructor + +Virt WASI then looks like…. +What happens on double close or use-after-close? +Spectrum of options, none of them good +How do I efficiently support cross-instance resource sharing? +Not great options either +How can a WASI impl robustly clean up after clients are destroyed? +Could leak. +Want FDs to be closed when the instance goes away, just like OS process +A native WASI impl could do this, but not a virtualized one +How do instances even get different lifetimes? This is a next step, to add ability to dynamically create and destroy instances +Also problems around dynamic casting +E.g. when store n distinct DOM node types in a single table +Not supporting would be a kind of regression + +Dynamic casting breaks otherwise-static invariants +If there’s a run function and I pass a RO, is it possible for X to somehow do a write? +It would be nice to have that answer based only on the static type +Fix is to treat different imports as different things for purpose of dynamic cast +To fix this, you need a wrapping at some membrane/boundary +OK for core wasm, because that’s just a compiler target +But not ok for ecosystem + +When we’re virtualizingWASI we want: … +Is all of this just for virtualization? +Resources are not a uniquely WASI concern +We should treat WASI as an unprivileged set of library interfaces + +Proposal +Add a new interface type called handle +Handle is a value that can be copied +Refers to a resource +A resource is some entity with a lifetime. It can not be copied +So resource types are like abstract type, but only private option +Additionally resource type definitions can have an optional destructor +Resource creation and use is symmetric to private.new/get +Handles are semantically ref-counted and call the destructor when they get to 0 +That’s what gives virt WASI same privileges as native +Also possible to explicitly destroy handles, and references trap + +**Sam Clegg:** would need to be at WASI core? +**Luke Wagner:** So far everything in Interface Types + +**Pat Hickey:** Attenuation +**Luke Wagner:** I’ve gone back and forth. Have an idea in open questions + +**Luke Wagner:** High level summary of IT +They’re lazy copy operations +Need a way to box all interface types +Generally valuable because it solves interesting performance use cases +For handle values, creates a root that creates the stack +That makes it so handles can outlive stack frame + +Once I have a reference, it can be cast +Will always trap if cast to differently privileged + +IT gives us the boundary/membrane where to wrap + +Proposal summary +Additions +New types +New definition +New instructions +Extend rtt.canon + +Problems: +Robust and efficient handling of double-free/use-after-free +…. + +Open Questions +Add abstract subtyping? +Should we have specialized versions of handle (e.g. a strong handle, unique handle) + +Next steps +Need to give lifetimes to instances +Can instances just be resources? +Could implement WASI command pattern in the toolchain rather than host magic + +**Sam Clegg:** What happens if you destroy a resource and another module still has a copy + +**Luke Wagner:** It will have a handle. That handle is then in a null state. When you try to use the handle, it would trap probably at resource.get + +**Sam Clegg:** So the trap would happen in the callee + +**Luke Wagner:** That’s where we might want to have a strong handle where no one could pass you an invalid handle. It’s an open question + +**Ralph Squillace:** For what it’s worth, I’ve been spinning around Pat’s question and going back to DCE-RPC. Believe that you should make or signal a strong decision about shared resources. + +**Luke Wagner:** That’s one of the reasons I like unique, because then when I give you a handle I’m explicitly saying I dont’ still have it. I guess that’s an argument for both unique and strong + +**Ralph Squillace:** Having the ability to make those choices is what comes to mind. If I choose a convention, I can signal it to others. Previous technologies tried to let people do it without signaling capabilities + +**Luke Wagner:** Would a summary be that you’re in favor of those two types of handles + +**Ralph Squillace:** I would say those two handles express two slices of the problem space. I wouldn’t say that I’ve thought through other possible types. + +**Luke Wagner:** Your’e right, I was trying to survey the literature and there are like 20 types + +**Ralph Squillace:** Even if you don’t have strong type, at least you can trap. Maybe that’s the first step. + +**Luke Wagner:** Hierarchy, undefined is worst, trap is better, statically preventing is best + +**Sam Clegg:** These handles are at IT types and at core go to reference. So references can be copied + +**Luke Wagner:** Once you exclusively use IT, there’s no back door + +**Sam Clegg:** Any incremental steps? + +**Luke Wagner:** In some sense, witx already has handle + +**Lin Clark** proposes that we make that the main topic for next meeting + From 89cbb9eb371d37ad84f741d76553a6376b0afccc Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 28 Jan 2021 18:15:58 -0500 Subject: [PATCH 0821/1772] Add 01-28 meeting notes --- proposals/random/meetings/2021/WASI-01-28.md | 177 ++++++++++++++++++- 1 file changed, 174 insertions(+), 3 deletions(-) diff --git a/proposals/random/meetings/2021/WASI-01-28.md b/proposals/random/meetings/2021/WASI-01-28.md index 757ab4d4e..cab4dbd21 100644 --- a/proposals/random/meetings/2021/WASI-01-28.md +++ b/proposals/random/meetings/2021/WASI-01-28.md @@ -25,11 +25,182 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! -1. Review of action items from previous meeting(s). - 1. Dan report on repository organization progress +1. Announcements + 1. Lin Clark on WASI modularization milestone 1. Proposals and discussions 1. Presentation: Update from Luke Wagner on handles and resources in interface types - 1. Discussion: Transitioning WASI APIs to use IT handles 1. _Sumbit a PR to add your agenda item here_ ## Meeting Notes +### Attendees +- Martin Duke, F5 +- Sam Clegg +- Dan Gohman +- Luke Wagner +- Mark McCaskey +- Lin Clark +- Dave Protasowski +- Alex Crichton +- Andrew Brown +- Mingqiu Sun +- Till Schneidereit +- Pat Hickey +- Josh Dolitsky +- Matt Butcher +- Ralph Squillace + +### Announcements +**Lin Clark:** We now have a [milestone for WASI modularization](https://github.com/WebAssembly/WASI/milestone/1). Will be using milestones more in the future. + +### Proposals and discussions +#### Presentation: Update from Luke Wagner on handles and resources in interface types [(Slides)](https://docs.google.com/presentation/d/1ikwS2Ps-KLXFofuS5VAs6Bn14q4LBEaxMjPfLj61UZE) + +**Luke Wagner:** Handles and resources. Have been working on this for a while with a number of y’all +Give background, motivating problems, and proposed solution +Not at all final, still working on a PR. Your feedback is most welcome + +IT gives WASI a bunch of value types +In addition to core basic types, a bunch of abbreviations +Don’t want to have to add core types +This lets us take a WASI function and use a bunch of high level types + +Plan of record for a while has been abstract types for file descriptors +Type imports builds on reference types +Reference types are unforgeable, better than ints + +How does this get virtualized? +Virtualization is a core value of WASI. You can implement with another WASI module +For this, we use module linking proposal + +What does it look like to write that virtualized WASI? (walk through) +Packed the file index into the reference, that’s efficient + +Type imports and exports are transparent by default +This is forgeable. That’s why that was take one + +Type imports has a private type definition +I would take abstract type and make it a private type definition +Private.get and private.new only works inside module that defined the type definition +These private types have to be boxed. +Actually no worse than the native implementation to have one level of indirection + +Two remaining problem areas: resource lifetimes and dynamic casting + +Resource lifetimes +How do resources get released? +Could reference count. +Problematic for a variety of reasons. +Not virtualizable. +Because of downsides, WASI resources have explicit destructor + +Virt WASI then looks like…. +What happens on double close or use-after-close? +Spectrum of options, none of them good +How do I efficiently support cross-instance resource sharing? +Not great options either +How can a WASI impl robustly clean up after clients are destroyed? +Could leak. +Want FDs to be closed when the instance goes away, just like OS process +A native WASI impl could do this, but not a virtualized one +How do instances even get different lifetimes? This is a next step, to add ability to dynamically create and destroy instances +Also problems around dynamic casting +E.g. when store n distinct DOM node types in a single table +Not supporting would be a kind of regression + +Dynamic casting breaks otherwise-static invariants +If there’s a run function and I pass a RO, is it possible for X to somehow do a write? +It would be nice to have that answer based only on the static type +Fix is to treat different imports as different things for purpose of dynamic cast +To fix this, you need a wrapping at some membrane/boundary +OK for core wasm, because that’s just a compiler target +But not ok for ecosystem + +When we’re virtualizingWASI we want: … +Is all of this just for virtualization? +Resources are not a uniquely WASI concern +We should treat WASI as an unprivileged set of library interfaces + +Proposal +Add a new interface type called handle +Handle is a value that can be copied +Refers to a resource +A resource is some entity with a lifetime. It can not be copied +So resource types are like abstract type, but only private option +Additionally resource type definitions can have an optional destructor +Resource creation and use is symmetric to private.new/get +Handles are semantically ref-counted and call the destructor when they get to 0 +That’s what gives virt WASI same privileges as native +Also possible to explicitly destroy handles, and references trap + +**Sam Clegg:** would need to be at WASI core? +**Luke Wagner:** So far everything in Interface Types + +**Pat Hickey:** Attenuation +**Luke Wagner:** I’ve gone back and forth. Have an idea in open questions + +**Luke Wagner:** High level summary of IT +They’re lazy copy operations +Need a way to box all interface types +Generally valuable because it solves interesting performance use cases +For handle values, creates a root that creates the stack +That makes it so handles can outlive stack frame + +Once I have a reference, it can be cast +Will always trap if cast to differently privileged + +IT gives us the boundary/membrane where to wrap + +Proposal summary +Additions +New types +New definition +New instructions +Extend rtt.canon + +Problems: +Robust and efficient handling of double-free/use-after-free +…. + +Open Questions +Add abstract subtyping? +Should we have specialized versions of handle (e.g. a strong handle, unique handle) + +Next steps +Need to give lifetimes to instances +Can instances just be resources? +Could implement WASI command pattern in the toolchain rather than host magic + +**Sam Clegg:** What happens if you destroy a resource and another module still has a copy + +**Luke Wagner:** It will have a handle. That handle is then in a null state. When you try to use the handle, it would trap probably at resource.get + +**Sam Clegg:** So the trap would happen in the callee + +**Luke Wagner:** That’s where we might want to have a strong handle where no one could pass you an invalid handle. It’s an open question + +**Ralph Squillace:** For what it’s worth, I’ve been spinning around Pat’s question and going back to DCE-RPC. Believe that you should make or signal a strong decision about shared resources. + +**Luke Wagner:** That’s one of the reasons I like unique, because then when I give you a handle I’m explicitly saying I dont’ still have it. I guess that’s an argument for both unique and strong + +**Ralph Squillace:** Having the ability to make those choices is what comes to mind. If I choose a convention, I can signal it to others. Previous technologies tried to let people do it without signaling capabilities + +**Luke Wagner:** Would a summary be that you’re in favor of those two types of handles + +**Ralph Squillace:** I would say those two handles express two slices of the problem space. I wouldn’t say that I’ve thought through other possible types. + +**Luke Wagner:** Your’e right, I was trying to survey the literature and there are like 20 types + +**Ralph Squillace:** Even if you don’t have strong type, at least you can trap. Maybe that’s the first step. + +**Luke Wagner:** Hierarchy, undefined is worst, trap is better, statically preventing is best + +**Sam Clegg:** These handles are at IT types and at core go to reference. So references can be copied + +**Luke Wagner:** Once you exclusively use IT, there’s no back door + +**Sam Clegg:** Any incremental steps? + +**Luke Wagner:** In some sense, witx already has handle + +**Lin Clark** proposes that we make that the main topic for next meeting + From 4770952b67f4d3376d38f9814f33b527e6cf7fa6 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 28 Jan 2021 18:15:58 -0500 Subject: [PATCH 0822/1772] Add 01-28 meeting notes --- .../filesystem/meetings/2021/WASI-01-28.md | 177 +++++++++++++++++- 1 file changed, 174 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/meetings/2021/WASI-01-28.md b/proposals/filesystem/meetings/2021/WASI-01-28.md index 757ab4d4e..cab4dbd21 100644 --- a/proposals/filesystem/meetings/2021/WASI-01-28.md +++ b/proposals/filesystem/meetings/2021/WASI-01-28.md @@ -25,11 +25,182 @@ Installation is required, see the calendar invite. 1. Please help add your name to the meeting notes. 1. Please help take notes. 1. Thanks! -1. Review of action items from previous meeting(s). - 1. Dan report on repository organization progress +1. Announcements + 1. Lin Clark on WASI modularization milestone 1. Proposals and discussions 1. Presentation: Update from Luke Wagner on handles and resources in interface types - 1. Discussion: Transitioning WASI APIs to use IT handles 1. _Sumbit a PR to add your agenda item here_ ## Meeting Notes +### Attendees +- Martin Duke, F5 +- Sam Clegg +- Dan Gohman +- Luke Wagner +- Mark McCaskey +- Lin Clark +- Dave Protasowski +- Alex Crichton +- Andrew Brown +- Mingqiu Sun +- Till Schneidereit +- Pat Hickey +- Josh Dolitsky +- Matt Butcher +- Ralph Squillace + +### Announcements +**Lin Clark:** We now have a [milestone for WASI modularization](https://github.com/WebAssembly/WASI/milestone/1). Will be using milestones more in the future. + +### Proposals and discussions +#### Presentation: Update from Luke Wagner on handles and resources in interface types [(Slides)](https://docs.google.com/presentation/d/1ikwS2Ps-KLXFofuS5VAs6Bn14q4LBEaxMjPfLj61UZE) + +**Luke Wagner:** Handles and resources. Have been working on this for a while with a number of y’all +Give background, motivating problems, and proposed solution +Not at all final, still working on a PR. Your feedback is most welcome + +IT gives WASI a bunch of value types +In addition to core basic types, a bunch of abbreviations +Don’t want to have to add core types +This lets us take a WASI function and use a bunch of high level types + +Plan of record for a while has been abstract types for file descriptors +Type imports builds on reference types +Reference types are unforgeable, better than ints + +How does this get virtualized? +Virtualization is a core value of WASI. You can implement with another WASI module +For this, we use module linking proposal + +What does it look like to write that virtualized WASI? (walk through) +Packed the file index into the reference, that’s efficient + +Type imports and exports are transparent by default +This is forgeable. That’s why that was take one + +Type imports has a private type definition +I would take abstract type and make it a private type definition +Private.get and private.new only works inside module that defined the type definition +These private types have to be boxed. +Actually no worse than the native implementation to have one level of indirection + +Two remaining problem areas: resource lifetimes and dynamic casting + +Resource lifetimes +How do resources get released? +Could reference count. +Problematic for a variety of reasons. +Not virtualizable. +Because of downsides, WASI resources have explicit destructor + +Virt WASI then looks like…. +What happens on double close or use-after-close? +Spectrum of options, none of them good +How do I efficiently support cross-instance resource sharing? +Not great options either +How can a WASI impl robustly clean up after clients are destroyed? +Could leak. +Want FDs to be closed when the instance goes away, just like OS process +A native WASI impl could do this, but not a virtualized one +How do instances even get different lifetimes? This is a next step, to add ability to dynamically create and destroy instances +Also problems around dynamic casting +E.g. when store n distinct DOM node types in a single table +Not supporting would be a kind of regression + +Dynamic casting breaks otherwise-static invariants +If there’s a run function and I pass a RO, is it possible for X to somehow do a write? +It would be nice to have that answer based only on the static type +Fix is to treat different imports as different things for purpose of dynamic cast +To fix this, you need a wrapping at some membrane/boundary +OK for core wasm, because that’s just a compiler target +But not ok for ecosystem + +When we’re virtualizingWASI we want: … +Is all of this just for virtualization? +Resources are not a uniquely WASI concern +We should treat WASI as an unprivileged set of library interfaces + +Proposal +Add a new interface type called handle +Handle is a value that can be copied +Refers to a resource +A resource is some entity with a lifetime. It can not be copied +So resource types are like abstract type, but only private option +Additionally resource type definitions can have an optional destructor +Resource creation and use is symmetric to private.new/get +Handles are semantically ref-counted and call the destructor when they get to 0 +That’s what gives virt WASI same privileges as native +Also possible to explicitly destroy handles, and references trap + +**Sam Clegg:** would need to be at WASI core? +**Luke Wagner:** So far everything in Interface Types + +**Pat Hickey:** Attenuation +**Luke Wagner:** I’ve gone back and forth. Have an idea in open questions + +**Luke Wagner:** High level summary of IT +They’re lazy copy operations +Need a way to box all interface types +Generally valuable because it solves interesting performance use cases +For handle values, creates a root that creates the stack +That makes it so handles can outlive stack frame + +Once I have a reference, it can be cast +Will always trap if cast to differently privileged + +IT gives us the boundary/membrane where to wrap + +Proposal summary +Additions +New types +New definition +New instructions +Extend rtt.canon + +Problems: +Robust and efficient handling of double-free/use-after-free +…. + +Open Questions +Add abstract subtyping? +Should we have specialized versions of handle (e.g. a strong handle, unique handle) + +Next steps +Need to give lifetimes to instances +Can instances just be resources? +Could implement WASI command pattern in the toolchain rather than host magic + +**Sam Clegg:** What happens if you destroy a resource and another module still has a copy + +**Luke Wagner:** It will have a handle. That handle is then in a null state. When you try to use the handle, it would trap probably at resource.get + +**Sam Clegg:** So the trap would happen in the callee + +**Luke Wagner:** That’s where we might want to have a strong handle where no one could pass you an invalid handle. It’s an open question + +**Ralph Squillace:** For what it’s worth, I’ve been spinning around Pat’s question and going back to DCE-RPC. Believe that you should make or signal a strong decision about shared resources. + +**Luke Wagner:** That’s one of the reasons I like unique, because then when I give you a handle I’m explicitly saying I dont’ still have it. I guess that’s an argument for both unique and strong + +**Ralph Squillace:** Having the ability to make those choices is what comes to mind. If I choose a convention, I can signal it to others. Previous technologies tried to let people do it without signaling capabilities + +**Luke Wagner:** Would a summary be that you’re in favor of those two types of handles + +**Ralph Squillace:** I would say those two handles express two slices of the problem space. I wouldn’t say that I’ve thought through other possible types. + +**Luke Wagner:** Your’e right, I was trying to survey the literature and there are like 20 types + +**Ralph Squillace:** Even if you don’t have strong type, at least you can trap. Maybe that’s the first step. + +**Luke Wagner:** Hierarchy, undefined is worst, trap is better, statically preventing is best + +**Sam Clegg:** These handles are at IT types and at core go to reference. So references can be copied + +**Luke Wagner:** Once you exclusively use IT, there’s no back door + +**Sam Clegg:** Any incremental steps? + +**Luke Wagner:** In some sense, witx already has handle + +**Lin Clark** proposes that we make that the main topic for next meeting + From b80c910547345f6d67fd6a75ef583cc1f2f368a8 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 4 Feb 2021 10:27:33 -0500 Subject: [PATCH 0823/1772] Add agendas for 02-11 and 02-25 (#389) --- proposals/clocks/meetings/2021/WASI-02-11.md | 33 ++++++++++++++++++++ proposals/clocks/meetings/2021/WASI-02-25.md | 33 ++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 proposals/clocks/meetings/2021/WASI-02-11.md create mode 100644 proposals/clocks/meetings/2021/WASI-02-25.md diff --git a/proposals/clocks/meetings/2021/WASI-02-11.md b/proposals/clocks/meetings/2021/WASI-02-11.md new file mode 100644 index 000000000..f56b6c537 --- /dev/null +++ b/proposals/clocks/meetings/2021/WASI-02-11.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the February 11 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: February 11, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. Discussion: What are the next steps in adapting WASI to use Interface Types handles and resources? + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/2021/WASI-02-25.md b/proposals/clocks/meetings/2021/WASI-02-25.md new file mode 100644 index 000000000..dd4892efc --- /dev/null +++ b/proposals/clocks/meetings/2021/WASI-02-25.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the February 25 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: February 25, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. Discussion: Better error handling in WASI + 1. _Sumbit a PR to add your agenda item here_ From f0d379a48a65bd4ebad2fe89c5473414c7d5229d Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 4 Feb 2021 10:27:33 -0500 Subject: [PATCH 0824/1772] Add agendas for 02-11 and 02-25 (#389) --- proposals/random/meetings/2021/WASI-02-11.md | 33 ++++++++++++++++++++ proposals/random/meetings/2021/WASI-02-25.md | 33 ++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 proposals/random/meetings/2021/WASI-02-11.md create mode 100644 proposals/random/meetings/2021/WASI-02-25.md diff --git a/proposals/random/meetings/2021/WASI-02-11.md b/proposals/random/meetings/2021/WASI-02-11.md new file mode 100644 index 000000000..f56b6c537 --- /dev/null +++ b/proposals/random/meetings/2021/WASI-02-11.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the February 11 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: February 11, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. Discussion: What are the next steps in adapting WASI to use Interface Types handles and resources? + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/2021/WASI-02-25.md b/proposals/random/meetings/2021/WASI-02-25.md new file mode 100644 index 000000000..dd4892efc --- /dev/null +++ b/proposals/random/meetings/2021/WASI-02-25.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the February 25 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: February 25, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. Discussion: Better error handling in WASI + 1. _Sumbit a PR to add your agenda item here_ From a69b8fd78405e8893a343118597df388045d4b68 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 4 Feb 2021 10:27:33 -0500 Subject: [PATCH 0825/1772] Add agendas for 02-11 and 02-25 (#389) --- .../filesystem/meetings/2021/WASI-02-11.md | 33 +++++++++++++++++++ .../filesystem/meetings/2021/WASI-02-25.md | 33 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 proposals/filesystem/meetings/2021/WASI-02-11.md create mode 100644 proposals/filesystem/meetings/2021/WASI-02-25.md diff --git a/proposals/filesystem/meetings/2021/WASI-02-11.md b/proposals/filesystem/meetings/2021/WASI-02-11.md new file mode 100644 index 000000000..f56b6c537 --- /dev/null +++ b/proposals/filesystem/meetings/2021/WASI-02-11.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the February 11 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: February 11, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. Discussion: What are the next steps in adapting WASI to use Interface Types handles and resources? + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/2021/WASI-02-25.md b/proposals/filesystem/meetings/2021/WASI-02-25.md new file mode 100644 index 000000000..dd4892efc --- /dev/null +++ b/proposals/filesystem/meetings/2021/WASI-02-25.md @@ -0,0 +1,33 @@ +![WASI logo](/WASI.png) + +## Agenda for the February 25 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: February 25, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. +Installation is required, see the calendar invite. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. Discussion: Better error handling in WASI + 1. _Sumbit a PR to add your agenda item here_ From 5fd87d527764a6babf020ad075ab54906fc1699b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 07:15:44 -0800 Subject: [PATCH 0826/1772] Rename `Array` to `List` --- proposals/clocks/phases/ephemeral/docs.md | 4 ++-- proposals/clocks/phases/ephemeral/witx/typenames.witx | 4 ++-- proposals/clocks/phases/old/snapshot_0/docs.md | 4 ++-- .../clocks/phases/old/snapshot_0/witx/typenames.witx | 4 ++-- proposals/clocks/phases/snapshot/docs.md | 4 ++-- proposals/clocks/phases/snapshot/witx/typenames.witx | 4 ++-- proposals/clocks/tools/witx/src/ast.rs | 4 ++-- proposals/clocks/tools/witx/src/coretypes.rs | 2 +- proposals/clocks/tools/witx/src/docs/ast.rs | 6 +++--- proposals/clocks/tools/witx/src/docs/md.rs | 4 ++-- proposals/clocks/tools/witx/src/layout.rs | 2 +- proposals/clocks/tools/witx/src/parser.rs | 10 +++++----- proposals/clocks/tools/witx/src/polyfill.rs | 2 +- proposals/clocks/tools/witx/src/render.rs | 2 +- proposals/clocks/tools/witx/src/representation.rs | 2 +- proposals/clocks/tools/witx/src/validate.rs | 4 ++-- 16 files changed, 31 insertions(+), 31 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 93416c8eb..3f17fdacf 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -444,13 +444,13 @@ The length of the buffer to be written. Offset: 4 -## `iovec_array`: `Array` +## `iovec_array`: `List` Size: 8 Alignment: 4 -## `ciovec_array`: `Array` +## `ciovec_array`: `List` Size: 8 diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 349952a15..723d43cb7 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -304,8 +304,8 @@ ) ) -(typename $iovec_array (array $iovec)) -(typename $ciovec_array (array $ciovec)) +(typename $iovec_array (list $iovec)) +(typename $ciovec_array (list $ciovec)) ;;; Relative offset within a file. (typename $filedelta s64) diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index 34eab3c03..9307d9754 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -436,13 +436,13 @@ The length of the buffer to be written. Offset: 4 -## `iovec_array`: `Array` +## `iovec_array`: `List` Size: 8 Alignment: 4 -## `ciovec_array`: `Array` +## `ciovec_array`: `List` Size: 8 diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx index 74ff0835a..b6f672c3a 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx @@ -296,8 +296,8 @@ ) ) -(typename $iovec_array (array $iovec)) -(typename $ciovec_array (array $ciovec)) +(typename $iovec_array (list $iovec)) +(typename $ciovec_array (list $ciovec)) ;;; Relative offset within a file. (typename $filedelta s64) diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index b56e8c533..1a223448f 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -436,13 +436,13 @@ The length of the buffer to be written. Offset: 4 -## `iovec_array`: `Array` +## `iovec_array`: `List` Size: 8 Alignment: 4 -## `ciovec_array`: `Array` +## `ciovec_array`: `List` Size: 8 diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx index b77372731..5e1049553 100644 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -296,8 +296,8 @@ ) ) -(typename $iovec_array (array $iovec)) -(typename $ciovec_array (array $ciovec)) +(typename $iovec_array (list $iovec)) +(typename $ciovec_array (list $ciovec)) ;;; Relative offset within a file. (typename $filedelta s64) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 2e30836b1..fcf6a2e94 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -183,7 +183,7 @@ pub enum Type { Struct(StructDatatype), Union(UnionDatatype), Handle(HandleDatatype), - Array(TypeRef), + List(TypeRef), Pointer(TypeRef), ConstPointer(TypeRef), Builtin(BuiltinType), @@ -199,7 +199,7 @@ impl Type { Struct(_) => "struct", Union(_) => "union", Handle(_) => "handle", - Array(_) => "array", + List(_) => "list", Pointer(_) => "pointer", ConstPointer(_) => "constpointer", Builtin(_) => "builtin", diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index 84756209d..7865bd8fb 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -48,7 +48,7 @@ impl Type { BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), }, - Type::Array { .. } => TypePassedBy::PointerLengthPair, + Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Int(i) => TypePassedBy::Value(i.repr.into()), diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index 02ef9ec22..0eb2933fe 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -76,8 +76,8 @@ impl ToMarkdown for Type { Self::Struct(a) => a.generate(node.clone()), Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), - Self::Array(a) => { - node.content_ref_mut::().r#type = Some(MdType::Array { + Self::List(a) => { + node.content_ref_mut::().r#type = Some(MdType::List { r#type: a.type_name().to_owned(), }) } @@ -378,7 +378,7 @@ impl TypeRef { match self { TypeRef::Name(n) => n.name.as_str().to_string(), TypeRef::Value(ref v) => match &**v { - Type::Array(a) => format!("Array<{}>", a.type_name()), + Type::List(a) => format!("List<{}>", a.type_name()), Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index 168eb77f4..2373f1ed5 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -348,7 +348,7 @@ pub(super) enum MdType { Flags { repr: String }, Struct, Union, - Array { r#type: String }, + List { r#type: String }, Pointer { r#type: String }, ConstPointer { r#type: String }, Builtin { repr: String }, @@ -364,7 +364,7 @@ impl fmt::Display for MdType { Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Struct => f.write_fmt(format_args!(": Struct"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, - Self::Array { r#type } => f.write_fmt(format_args!(": `Array<{}>`", r#type))?, + Self::List { r#type } => f.write_fmt(format_args!(": `List<{}>`", r#type))?, Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, Self::ConstPointer { r#type } => { f.write_fmt(format_args!(": `ConstPointer<{}>`", r#type))? diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index 3e2f6ee09..6012d38d8 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -59,7 +59,7 @@ impl Type { Type::Struct(s) => s.layout(cache), Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), - Type::Array { .. } => BuiltinType::String.mem_size_align(), + Type::List { .. } => BuiltinType::String.mem_size_align(), Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), } diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 5ff66828e..964a5ba48 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -18,7 +18,6 @@ use wast::parser::{Parse, Parser, Peek, Result}; mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; - wast::custom_keyword!(array); wast::custom_keyword!(char8); wast::custom_keyword!(const_pointer); wast::custom_keyword!(f32); @@ -28,6 +27,7 @@ mod kw { wast::custom_keyword!(flags); wast::custom_keyword!(handle); wast::custom_keyword!(int); + wast::custom_keyword!(list); wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); wast::custom_keyword!(r#const = "const"); @@ -275,7 +275,7 @@ pub enum TypedefSyntax<'a> { Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), Handle(HandleSyntax), - Array(Box>), + List(Box>), Pointer(Box>), ConstPointer(Box>), Builtin(BuiltinType), @@ -304,9 +304,9 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Union(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Handle(parser.parse()?)) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Array(Box::new(parser.parse()?))) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::List(Box::new(parser.parse()?))) } else if l.peek::() { parser.parse::()?; let mut l = parser.lookahead1(); diff --git a/proposals/clocks/tools/witx/src/polyfill.rs b/proposals/clocks/tools/witx/src/polyfill.rs index 6181d357c..c779cfa4e 100644 --- a/proposals/clocks/tools/witx/src/polyfill.rs +++ b/proposals/clocks/tools/witx/src/polyfill.rs @@ -178,7 +178,7 @@ impl ParamPolyfill { fn common_denominator(a: TypeRef, b: TypeRef) -> (TypeRef, TypeRef) { match (&a, &b) { (TypeRef::Value(va), TypeRef::Value(vb)) => match (&**va, &**vb) { - (Type::Array(a), Type::Array(b)) => (a.clone(), b.clone()), + (Type::List(a), Type::List(b)) => (a.clone(), b.clone()), (Type::Pointer(a), Type::Pointer(b)) => (a.clone(), b.clone()), (Type::ConstPointer(a), Type::ConstPointer(b)) => (a.clone(), b.clone()), _ => (a, b), diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 4cf6c531f..11778fa15 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -122,7 +122,7 @@ impl Type { Type::Struct(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), Type::Handle(a) => a.to_sexpr(), - Type::Array(a) => SExpr::Vec(vec![SExpr::word("array"), a.to_sexpr()]), + Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), Type::Pointer(p) => SExpr::Vec(vec![ SExpr::annot("witx"), SExpr::word("pointer"), diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs index 2a52fc69b..f541e9fc1 100644 --- a/proposals/clocks/tools/witx/src/representation.rs +++ b/proposals/clocks/tools/witx/src/representation.rs @@ -208,7 +208,7 @@ impl Representable for Type { (Type::Struct(s), Type::Struct(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural - (Type::Array(s), Type::Array(b)) => s.representable(b), + (Type::List(s), Type::List(b)) => s.representable(b), (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), (Type::Builtin(s), Type::Builtin(b)) => s.representable(b), diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index c4c5589e4..211438819 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -255,8 +255,8 @@ impl DocValidationScope<'_> { TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), - TypedefSyntax::Array(syntax) => { - Type::Array(self.validate_datatype(syntax, false, span)?) + TypedefSyntax::List(syntax) => { + Type::List(self.validate_datatype(syntax, false, span)?) } TypedefSyntax::Pointer(syntax) => { Type::Pointer(self.validate_datatype(syntax, false, span)?) From 3d80f612b5aa8d811653ff44221380d9a40f1c9d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 07:15:44 -0800 Subject: [PATCH 0827/1772] Rename `Array` to `List` --- proposals/random/phases/ephemeral/docs.md | 4 ++-- proposals/random/phases/ephemeral/witx/typenames.witx | 4 ++-- proposals/random/phases/old/snapshot_0/docs.md | 4 ++-- .../random/phases/old/snapshot_0/witx/typenames.witx | 4 ++-- proposals/random/phases/snapshot/docs.md | 4 ++-- proposals/random/phases/snapshot/witx/typenames.witx | 4 ++-- proposals/random/tools/witx/src/ast.rs | 4 ++-- proposals/random/tools/witx/src/coretypes.rs | 2 +- proposals/random/tools/witx/src/docs/ast.rs | 6 +++--- proposals/random/tools/witx/src/docs/md.rs | 4 ++-- proposals/random/tools/witx/src/layout.rs | 2 +- proposals/random/tools/witx/src/parser.rs | 10 +++++----- proposals/random/tools/witx/src/polyfill.rs | 2 +- proposals/random/tools/witx/src/render.rs | 2 +- proposals/random/tools/witx/src/representation.rs | 2 +- proposals/random/tools/witx/src/validate.rs | 4 ++-- 16 files changed, 31 insertions(+), 31 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 93416c8eb..3f17fdacf 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -444,13 +444,13 @@ The length of the buffer to be written. Offset: 4 -## `iovec_array`: `Array` +## `iovec_array`: `List` Size: 8 Alignment: 4 -## `ciovec_array`: `Array` +## `ciovec_array`: `List` Size: 8 diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 349952a15..723d43cb7 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -304,8 +304,8 @@ ) ) -(typename $iovec_array (array $iovec)) -(typename $ciovec_array (array $ciovec)) +(typename $iovec_array (list $iovec)) +(typename $ciovec_array (list $ciovec)) ;;; Relative offset within a file. (typename $filedelta s64) diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index 34eab3c03..9307d9754 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -436,13 +436,13 @@ The length of the buffer to be written. Offset: 4 -## `iovec_array`: `Array` +## `iovec_array`: `List` Size: 8 Alignment: 4 -## `ciovec_array`: `Array` +## `ciovec_array`: `List` Size: 8 diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx index 74ff0835a..b6f672c3a 100644 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/random/phases/old/snapshot_0/witx/typenames.witx @@ -296,8 +296,8 @@ ) ) -(typename $iovec_array (array $iovec)) -(typename $ciovec_array (array $ciovec)) +(typename $iovec_array (list $iovec)) +(typename $ciovec_array (list $ciovec)) ;;; Relative offset within a file. (typename $filedelta s64) diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index b56e8c533..1a223448f 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -436,13 +436,13 @@ The length of the buffer to be written. Offset: 4 -## `iovec_array`: `Array` +## `iovec_array`: `List` Size: 8 Alignment: 4 -## `ciovec_array`: `Array` +## `ciovec_array`: `List` Size: 8 diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx index b77372731..5e1049553 100644 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -296,8 +296,8 @@ ) ) -(typename $iovec_array (array $iovec)) -(typename $ciovec_array (array $ciovec)) +(typename $iovec_array (list $iovec)) +(typename $ciovec_array (list $ciovec)) ;;; Relative offset within a file. (typename $filedelta s64) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 2e30836b1..fcf6a2e94 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -183,7 +183,7 @@ pub enum Type { Struct(StructDatatype), Union(UnionDatatype), Handle(HandleDatatype), - Array(TypeRef), + List(TypeRef), Pointer(TypeRef), ConstPointer(TypeRef), Builtin(BuiltinType), @@ -199,7 +199,7 @@ impl Type { Struct(_) => "struct", Union(_) => "union", Handle(_) => "handle", - Array(_) => "array", + List(_) => "list", Pointer(_) => "pointer", ConstPointer(_) => "constpointer", Builtin(_) => "builtin", diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index 84756209d..7865bd8fb 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -48,7 +48,7 @@ impl Type { BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), }, - Type::Array { .. } => TypePassedBy::PointerLengthPair, + Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Int(i) => TypePassedBy::Value(i.repr.into()), diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index 02ef9ec22..0eb2933fe 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -76,8 +76,8 @@ impl ToMarkdown for Type { Self::Struct(a) => a.generate(node.clone()), Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), - Self::Array(a) => { - node.content_ref_mut::().r#type = Some(MdType::Array { + Self::List(a) => { + node.content_ref_mut::().r#type = Some(MdType::List { r#type: a.type_name().to_owned(), }) } @@ -378,7 +378,7 @@ impl TypeRef { match self { TypeRef::Name(n) => n.name.as_str().to_string(), TypeRef::Value(ref v) => match &**v { - Type::Array(a) => format!("Array<{}>", a.type_name()), + Type::List(a) => format!("List<{}>", a.type_name()), Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index 168eb77f4..2373f1ed5 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -348,7 +348,7 @@ pub(super) enum MdType { Flags { repr: String }, Struct, Union, - Array { r#type: String }, + List { r#type: String }, Pointer { r#type: String }, ConstPointer { r#type: String }, Builtin { repr: String }, @@ -364,7 +364,7 @@ impl fmt::Display for MdType { Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Struct => f.write_fmt(format_args!(": Struct"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, - Self::Array { r#type } => f.write_fmt(format_args!(": `Array<{}>`", r#type))?, + Self::List { r#type } => f.write_fmt(format_args!(": `List<{}>`", r#type))?, Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, Self::ConstPointer { r#type } => { f.write_fmt(format_args!(": `ConstPointer<{}>`", r#type))? diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index 3e2f6ee09..6012d38d8 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -59,7 +59,7 @@ impl Type { Type::Struct(s) => s.layout(cache), Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), - Type::Array { .. } => BuiltinType::String.mem_size_align(), + Type::List { .. } => BuiltinType::String.mem_size_align(), Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), } diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 5ff66828e..964a5ba48 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -18,7 +18,6 @@ use wast::parser::{Parse, Parser, Peek, Result}; mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; - wast::custom_keyword!(array); wast::custom_keyword!(char8); wast::custom_keyword!(const_pointer); wast::custom_keyword!(f32); @@ -28,6 +27,7 @@ mod kw { wast::custom_keyword!(flags); wast::custom_keyword!(handle); wast::custom_keyword!(int); + wast::custom_keyword!(list); wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); wast::custom_keyword!(r#const = "const"); @@ -275,7 +275,7 @@ pub enum TypedefSyntax<'a> { Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), Handle(HandleSyntax), - Array(Box>), + List(Box>), Pointer(Box>), ConstPointer(Box>), Builtin(BuiltinType), @@ -304,9 +304,9 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Union(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Handle(parser.parse()?)) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Array(Box::new(parser.parse()?))) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::List(Box::new(parser.parse()?))) } else if l.peek::() { parser.parse::()?; let mut l = parser.lookahead1(); diff --git a/proposals/random/tools/witx/src/polyfill.rs b/proposals/random/tools/witx/src/polyfill.rs index 6181d357c..c779cfa4e 100644 --- a/proposals/random/tools/witx/src/polyfill.rs +++ b/proposals/random/tools/witx/src/polyfill.rs @@ -178,7 +178,7 @@ impl ParamPolyfill { fn common_denominator(a: TypeRef, b: TypeRef) -> (TypeRef, TypeRef) { match (&a, &b) { (TypeRef::Value(va), TypeRef::Value(vb)) => match (&**va, &**vb) { - (Type::Array(a), Type::Array(b)) => (a.clone(), b.clone()), + (Type::List(a), Type::List(b)) => (a.clone(), b.clone()), (Type::Pointer(a), Type::Pointer(b)) => (a.clone(), b.clone()), (Type::ConstPointer(a), Type::ConstPointer(b)) => (a.clone(), b.clone()), _ => (a, b), diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 4cf6c531f..11778fa15 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -122,7 +122,7 @@ impl Type { Type::Struct(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), Type::Handle(a) => a.to_sexpr(), - Type::Array(a) => SExpr::Vec(vec![SExpr::word("array"), a.to_sexpr()]), + Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), Type::Pointer(p) => SExpr::Vec(vec![ SExpr::annot("witx"), SExpr::word("pointer"), diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs index 2a52fc69b..f541e9fc1 100644 --- a/proposals/random/tools/witx/src/representation.rs +++ b/proposals/random/tools/witx/src/representation.rs @@ -208,7 +208,7 @@ impl Representable for Type { (Type::Struct(s), Type::Struct(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural - (Type::Array(s), Type::Array(b)) => s.representable(b), + (Type::List(s), Type::List(b)) => s.representable(b), (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), (Type::Builtin(s), Type::Builtin(b)) => s.representable(b), diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index c4c5589e4..211438819 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -255,8 +255,8 @@ impl DocValidationScope<'_> { TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), - TypedefSyntax::Array(syntax) => { - Type::Array(self.validate_datatype(syntax, false, span)?) + TypedefSyntax::List(syntax) => { + Type::List(self.validate_datatype(syntax, false, span)?) } TypedefSyntax::Pointer(syntax) => { Type::Pointer(self.validate_datatype(syntax, false, span)?) From d15d6a3313c0b606ff0f503cb695c15cec19e7a9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 07:15:44 -0800 Subject: [PATCH 0828/1772] Rename `Array` to `List` --- proposals/filesystem/phases/ephemeral/docs.md | 4 ++-- .../filesystem/phases/ephemeral/witx/typenames.witx | 4 ++-- proposals/filesystem/phases/old/snapshot_0/docs.md | 4 ++-- .../phases/old/snapshot_0/witx/typenames.witx | 4 ++-- proposals/filesystem/phases/snapshot/docs.md | 4 ++-- .../filesystem/phases/snapshot/witx/typenames.witx | 4 ++-- proposals/filesystem/tools/witx/src/ast.rs | 4 ++-- proposals/filesystem/tools/witx/src/coretypes.rs | 2 +- proposals/filesystem/tools/witx/src/docs/ast.rs | 6 +++--- proposals/filesystem/tools/witx/src/docs/md.rs | 4 ++-- proposals/filesystem/tools/witx/src/layout.rs | 2 +- proposals/filesystem/tools/witx/src/parser.rs | 10 +++++----- proposals/filesystem/tools/witx/src/polyfill.rs | 2 +- proposals/filesystem/tools/witx/src/render.rs | 2 +- proposals/filesystem/tools/witx/src/representation.rs | 2 +- proposals/filesystem/tools/witx/src/validate.rs | 4 ++-- 16 files changed, 31 insertions(+), 31 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 93416c8eb..3f17fdacf 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -444,13 +444,13 @@ The length of the buffer to be written. Offset: 4 -## `iovec_array`: `Array` +## `iovec_array`: `List` Size: 8 Alignment: 4 -## `ciovec_array`: `Array` +## `ciovec_array`: `List` Size: 8 diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 349952a15..723d43cb7 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -304,8 +304,8 @@ ) ) -(typename $iovec_array (array $iovec)) -(typename $ciovec_array (array $ciovec)) +(typename $iovec_array (list $iovec)) +(typename $ciovec_array (list $ciovec)) ;;; Relative offset within a file. (typename $filedelta s64) diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index 34eab3c03..9307d9754 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -436,13 +436,13 @@ The length of the buffer to be written. Offset: 4 -## `iovec_array`: `Array` +## `iovec_array`: `List` Size: 8 Alignment: 4 -## `ciovec_array`: `Array` +## `ciovec_array`: `List` Size: 8 diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx index 74ff0835a..b6f672c3a 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx @@ -296,8 +296,8 @@ ) ) -(typename $iovec_array (array $iovec)) -(typename $ciovec_array (array $ciovec)) +(typename $iovec_array (list $iovec)) +(typename $ciovec_array (list $ciovec)) ;;; Relative offset within a file. (typename $filedelta s64) diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index b56e8c533..1a223448f 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -436,13 +436,13 @@ The length of the buffer to be written. Offset: 4 -## `iovec_array`: `Array` +## `iovec_array`: `List` Size: 8 Alignment: 4 -## `ciovec_array`: `Array` +## `ciovec_array`: `List` Size: 8 diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx index b77372731..5e1049553 100644 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -296,8 +296,8 @@ ) ) -(typename $iovec_array (array $iovec)) -(typename $ciovec_array (array $ciovec)) +(typename $iovec_array (list $iovec)) +(typename $ciovec_array (list $ciovec)) ;;; Relative offset within a file. (typename $filedelta s64) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 2e30836b1..fcf6a2e94 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -183,7 +183,7 @@ pub enum Type { Struct(StructDatatype), Union(UnionDatatype), Handle(HandleDatatype), - Array(TypeRef), + List(TypeRef), Pointer(TypeRef), ConstPointer(TypeRef), Builtin(BuiltinType), @@ -199,7 +199,7 @@ impl Type { Struct(_) => "struct", Union(_) => "union", Handle(_) => "handle", - Array(_) => "array", + List(_) => "list", Pointer(_) => "pointer", ConstPointer(_) => "constpointer", Builtin(_) => "builtin", diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index 84756209d..7865bd8fb 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -48,7 +48,7 @@ impl Type { BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), }, - Type::Array { .. } => TypePassedBy::PointerLengthPair, + Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Int(i) => TypePassedBy::Value(i.repr.into()), diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index 02ef9ec22..0eb2933fe 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -76,8 +76,8 @@ impl ToMarkdown for Type { Self::Struct(a) => a.generate(node.clone()), Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), - Self::Array(a) => { - node.content_ref_mut::().r#type = Some(MdType::Array { + Self::List(a) => { + node.content_ref_mut::().r#type = Some(MdType::List { r#type: a.type_name().to_owned(), }) } @@ -378,7 +378,7 @@ impl TypeRef { match self { TypeRef::Name(n) => n.name.as_str().to_string(), TypeRef::Value(ref v) => match &**v { - Type::Array(a) => format!("Array<{}>", a.type_name()), + Type::List(a) => format!("List<{}>", a.type_name()), Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index 168eb77f4..2373f1ed5 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -348,7 +348,7 @@ pub(super) enum MdType { Flags { repr: String }, Struct, Union, - Array { r#type: String }, + List { r#type: String }, Pointer { r#type: String }, ConstPointer { r#type: String }, Builtin { repr: String }, @@ -364,7 +364,7 @@ impl fmt::Display for MdType { Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Struct => f.write_fmt(format_args!(": Struct"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, - Self::Array { r#type } => f.write_fmt(format_args!(": `Array<{}>`", r#type))?, + Self::List { r#type } => f.write_fmt(format_args!(": `List<{}>`", r#type))?, Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, Self::ConstPointer { r#type } => { f.write_fmt(format_args!(": `ConstPointer<{}>`", r#type))? diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index 3e2f6ee09..6012d38d8 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -59,7 +59,7 @@ impl Type { Type::Struct(s) => s.layout(cache), Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), - Type::Array { .. } => BuiltinType::String.mem_size_align(), + Type::List { .. } => BuiltinType::String.mem_size_align(), Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), } diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 5ff66828e..964a5ba48 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -18,7 +18,6 @@ use wast::parser::{Parse, Parser, Peek, Result}; mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; - wast::custom_keyword!(array); wast::custom_keyword!(char8); wast::custom_keyword!(const_pointer); wast::custom_keyword!(f32); @@ -28,6 +27,7 @@ mod kw { wast::custom_keyword!(flags); wast::custom_keyword!(handle); wast::custom_keyword!(int); + wast::custom_keyword!(list); wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); wast::custom_keyword!(r#const = "const"); @@ -275,7 +275,7 @@ pub enum TypedefSyntax<'a> { Struct(StructSyntax<'a>), Union(UnionSyntax<'a>), Handle(HandleSyntax), - Array(Box>), + List(Box>), Pointer(Box>), ConstPointer(Box>), Builtin(BuiltinType), @@ -304,9 +304,9 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Union(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Handle(parser.parse()?)) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Array(Box::new(parser.parse()?))) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::List(Box::new(parser.parse()?))) } else if l.peek::() { parser.parse::()?; let mut l = parser.lookahead1(); diff --git a/proposals/filesystem/tools/witx/src/polyfill.rs b/proposals/filesystem/tools/witx/src/polyfill.rs index 6181d357c..c779cfa4e 100644 --- a/proposals/filesystem/tools/witx/src/polyfill.rs +++ b/proposals/filesystem/tools/witx/src/polyfill.rs @@ -178,7 +178,7 @@ impl ParamPolyfill { fn common_denominator(a: TypeRef, b: TypeRef) -> (TypeRef, TypeRef) { match (&a, &b) { (TypeRef::Value(va), TypeRef::Value(vb)) => match (&**va, &**vb) { - (Type::Array(a), Type::Array(b)) => (a.clone(), b.clone()), + (Type::List(a), Type::List(b)) => (a.clone(), b.clone()), (Type::Pointer(a), Type::Pointer(b)) => (a.clone(), b.clone()), (Type::ConstPointer(a), Type::ConstPointer(b)) => (a.clone(), b.clone()), _ => (a, b), diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 4cf6c531f..11778fa15 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -122,7 +122,7 @@ impl Type { Type::Struct(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), Type::Handle(a) => a.to_sexpr(), - Type::Array(a) => SExpr::Vec(vec![SExpr::word("array"), a.to_sexpr()]), + Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), Type::Pointer(p) => SExpr::Vec(vec![ SExpr::annot("witx"), SExpr::word("pointer"), diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs index 2a52fc69b..f541e9fc1 100644 --- a/proposals/filesystem/tools/witx/src/representation.rs +++ b/proposals/filesystem/tools/witx/src/representation.rs @@ -208,7 +208,7 @@ impl Representable for Type { (Type::Struct(s), Type::Struct(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural - (Type::Array(s), Type::Array(b)) => s.representable(b), + (Type::List(s), Type::List(b)) => s.representable(b), (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), (Type::Builtin(s), Type::Builtin(b)) => s.representable(b), diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index c4c5589e4..211438819 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -255,8 +255,8 @@ impl DocValidationScope<'_> { TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), - TypedefSyntax::Array(syntax) => { - Type::Array(self.validate_datatype(syntax, false, span)?) + TypedefSyntax::List(syntax) => { + Type::List(self.validate_datatype(syntax, false, span)?) } TypedefSyntax::Pointer(syntax) => { Type::Pointer(self.validate_datatype(syntax, false, span)?) From 31d2177f2c3147ac0cd5e1479baf3b1485f4890d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 07:24:15 -0800 Subject: [PATCH 0829/1772] Rename structs to records --- proposals/clocks/phases/ephemeral/docs.md | 44 +++++++++---------- .../phases/ephemeral/witx/typenames.witx | 22 +++++----- .../clocks/phases/old/snapshot_0/docs.md | 44 +++++++++---------- .../phases/old/snapshot_0/witx/typenames.witx | 22 +++++----- proposals/clocks/phases/snapshot/docs.md | 44 +++++++++---------- .../phases/snapshot/witx/typenames.witx | 22 +++++----- proposals/clocks/tools/witx/src/ast.rs | 10 ++--- proposals/clocks/tools/witx/src/coretypes.rs | 2 +- proposals/clocks/tools/witx/src/docs/ast.rs | 12 ++--- proposals/clocks/tools/witx/src/docs/md.rs | 12 ++--- proposals/clocks/tools/witx/src/layout.rs | 16 +++---- proposals/clocks/tools/witx/src/lib.rs | 4 +- proposals/clocks/tools/witx/src/parser.rs | 16 +++---- proposals/clocks/tools/witx/src/render.rs | 6 +-- .../clocks/tools/witx/src/representation.rs | 8 ++-- proposals/clocks/tools/witx/src/validate.rs | 26 +++++------ .../clocks/tools/witx/tests/anonymous.rs | 30 ++++++------- .../clocks/tools/witx/tests/multimodule.rs | 14 +++--- .../tools/witx/tests/multimodule/type_b.witx | 2 +- .../tools/witx/tests/multimodule/type_c.witx | 2 +- 20 files changed, 179 insertions(+), 179 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 3f17fdacf..3bd147b43 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -408,14 +408,14 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Struct +## `iovec`: Record A region of memory for scatter/gather reads. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `Pointer` The address of the buffer to be filled. @@ -426,14 +426,14 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Struct +## `ciovec`: Record A region of memory for scatter/gather writes. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `ConstPointer` The address of the buffer to be written. @@ -540,14 +540,14 @@ The file refers to a symbolic link inode. - `fifo` The file descriptor or file refers to a FIFO. -## `dirent`: Struct +## `dirent`: Record A directory entry. Size: 24 Alignment: 8 -### Struct members +### Record members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. @@ -619,14 +619,14 @@ Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Struct +## `fdstat`: Record File descriptor attributes. Size: 24 Alignment: 8 -### Struct members +### Record members - `fs_filetype`: [`filetype`](#filetype) File type. @@ -748,14 +748,14 @@ indicates that the file is only accessible by the effective "user" that the WASI store uses to access the filesystem, and inaccessible to other "users". -## `filestat`: Struct +## `filestat`: Record File attributes. Size: 64 Alignment: 8 -### Struct members +### Record members - `dev`: [`device`](#device) Device ID of device containing the file. @@ -841,7 +841,7 @@ Alignment: 2 - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Struct +## `event_fd_readwrite`: Record The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -849,7 +849,7 @@ Size: 16 Alignment: 8 -### Struct members +### Record members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. @@ -880,14 +880,14 @@ Alignment: 8 - `clock` -## `event`: Struct +## `event`: Record An event that occurred. Size: 40 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). @@ -919,14 +919,14 @@ If set, treat the timestamp provided in provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Struct +## `subscription_clock`: Record The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 32 Alignment: 8 -### Struct members +### Record members - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. @@ -948,7 +948,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 24 -## `subscription_fd_readwrite`: Struct +## `subscription_fd_readwrite`: Record The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -956,7 +956,7 @@ Size: 4 Alignment: 4 -### Struct members +### Record members - `fd`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. @@ -982,14 +982,14 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Struct +## `subscription`: Record Subscription to an event. Size: 48 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). @@ -1066,14 +1066,14 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Struct +## `prestat_dir`: Record The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). Size: 4 Alignment: 4 -### Struct members +### Record members - `pr_name_len`: [`size`](#size) The length of the directory name for use with `fd_prestat_dir_name`. diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 723d43cb7..d4cc6274c 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -286,7 +286,7 @@ ;;; A region of memory for scatter/gather reads. (typename $iovec - (struct + (record ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. @@ -296,7 +296,7 @@ ;;; A region of memory for scatter/gather writes. (typename $ciovec - (struct + (record ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. @@ -362,7 +362,7 @@ ;;; A directory entry. (typename $dirent - (struct + (record ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. @@ -412,7 +412,7 @@ ;;; File descriptor attributes. (typename $fdstat - (struct + (record ;;; File type. (field $fs_filetype $filetype) ;;; File descriptor flags. @@ -501,7 +501,7 @@ ;;; File attributes. (typename $filestat - (struct + (record ;;; Device ID of device containing the file. (field $dev $device) ;;; File serial number. @@ -554,7 +554,7 @@ ;;; The contents of an `event` when type is `eventtype::fd_read` or ;;; `eventtype::fd_write`. (typename $event_fd_readwrite - (struct + (record ;;; The number of bytes available for reading or writing. (field $nbytes $filesize) ;;; The state of the file descriptor. @@ -573,7 +573,7 @@ ;;; An event that occurred. (typename $event - (struct + (record ;;; User-provided value that got attached to `subscription::userdata`. (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. @@ -598,7 +598,7 @@ ;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock - (struct + (record ;;; The clock against which to compare the timestamp. (field $id $clockid) ;;; The absolute or relative timestamp. @@ -614,7 +614,7 @@ ;;; The contents of a `subscription` when type is type is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite - (struct + (record ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $fd $fd) ) @@ -631,7 +631,7 @@ ;;; Subscription to an event. (typename $subscription - (struct + (record ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) @@ -685,7 +685,7 @@ ;;; The contents of a `prestat` when its type is `preopentype::dir`. (typename $prestat_dir - (struct + (record ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size) ) diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index 9307d9754..b56aa1f5e 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -400,14 +400,14 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Struct +## `iovec`: Record A region of memory for scatter/gather reads. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `Pointer` The address of the buffer to be filled. @@ -418,14 +418,14 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Struct +## `ciovec`: Record A region of memory for scatter/gather writes. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `ConstPointer` The address of the buffer to be written. @@ -525,14 +525,14 @@ The file descriptor or file refers to a byte-stream socket. - `symbolic_link` The file refers to a symbolic link inode. -## `dirent`: Struct +## `dirent`: Record A directory entry. Size: 24 Alignment: 8 -### Struct members +### Record members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. @@ -604,14 +604,14 @@ Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Struct +## `fdstat`: Record File descriptor attributes. Size: 24 Alignment: 8 -### Struct members +### Record members - `fs_filetype`: [`filetype`](#filetype) File type. @@ -699,14 +699,14 @@ Size: 4 Alignment: 4 -## `filestat`: Struct +## `filestat`: Record File attributes. Size: 56 Alignment: 8 -### Struct members +### Record members - `dev`: [`device`](#device) Device ID of device containing the file. @@ -787,7 +787,7 @@ Alignment: 2 - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Struct +## `event_fd_readwrite`: Record The contents of an [`event`](#event) for the [`eventtype::fd_read`](#eventtype.fd_read) and [`eventtype::fd_write`](#eventtype.fd_write) variants @@ -795,7 +795,7 @@ Size: 16 Alignment: 8 -### Struct members +### Record members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. @@ -806,14 +806,14 @@ The state of the file descriptor. Offset: 8 -## `event`: Struct +## `event`: Record An event that occurred. Size: 32 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). @@ -851,14 +851,14 @@ If set, treat the timestamp provided in provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Struct +## `subscription_clock`: Record The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 40 Alignment: 8 -### Struct members +### Record members - `identifier`: [`userdata`](#userdata) The user-defined unique identifier of the clock. @@ -885,7 +885,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 32 -## `subscription_fd_readwrite`: Struct +## `subscription_fd_readwrite`: Record The contents of a [`subscription`](#subscription) when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -893,7 +893,7 @@ Size: 4 Alignment: 4 -### Struct members +### Record members - `file_descriptor`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. @@ -919,14 +919,14 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Struct +## `subscription`: Record Subscription to an event. Size: 56 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). @@ -1135,14 +1135,14 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Struct +## `prestat_dir`: Record The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). Size: 4 Alignment: 4 -### Struct members +### Record members - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx index b6f672c3a..37a49f083 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx @@ -278,7 +278,7 @@ ;;; A region of memory for scatter/gather reads. (typename $iovec - (struct + (record ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. @@ -288,7 +288,7 @@ ;;; A region of memory for scatter/gather writes. (typename $ciovec - (struct + (record ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. @@ -347,7 +347,7 @@ ;;; A directory entry. (typename $dirent - (struct + (record ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. @@ -397,7 +397,7 @@ ;;; File descriptor attributes. (typename $fdstat - (struct + (record ;;; File type. (field $fs_filetype $filetype) ;;; File descriptor flags. @@ -455,7 +455,7 @@ ;;; File attributes. (typename $filestat - (struct + (record ;;; Device ID of device containing the file. (field $dev $device) ;;; File serial number. @@ -506,7 +506,7 @@ ;;; The contents of an `event` for the `eventtype::fd_read` and ;;; `eventtype::fd_write` variants (typename $event_fd_readwrite - (struct + (record ;;; The number of bytes available for reading or writing. (field $nbytes $filesize) ;;; The state of the file descriptor. @@ -516,7 +516,7 @@ ;;; An event that occurred. (typename $event - (struct + (record ;;; User-provided value that got attached to `subscription::userdata`. (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. @@ -544,7 +544,7 @@ ;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock - (struct + (record ;;; The user-defined unique identifier of the clock. (field $identifier $userdata) ;;; The clock against which to compare the timestamp. @@ -562,7 +562,7 @@ ;;; The contents of a `subscription` when the variant is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite - (struct + (record ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd) ) @@ -579,7 +579,7 @@ ;;; Subscription to an event. (typename $subscription - (struct + (record ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) @@ -732,7 +732,7 @@ ;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir - (struct + (record ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size) ) diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index 1a223448f..1cb642abe 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -400,14 +400,14 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Struct +## `iovec`: Record A region of memory for scatter/gather reads. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `Pointer` The address of the buffer to be filled. @@ -418,14 +418,14 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Struct +## `ciovec`: Record A region of memory for scatter/gather writes. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `ConstPointer` The address of the buffer to be written. @@ -527,14 +527,14 @@ The file descriptor or file refers to a byte-stream socket. - `symbolic_link` The file refers to a symbolic link inode. -## `dirent`: Struct +## `dirent`: Record A directory entry. Size: 24 Alignment: 8 -### Struct members +### Record members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. @@ -606,14 +606,14 @@ Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Struct +## `fdstat`: Record File descriptor attributes. Size: 24 Alignment: 8 -### Struct members +### Record members - `fs_filetype`: [`filetype`](#filetype) File type. @@ -701,14 +701,14 @@ Size: 8 Alignment: 8 -## `filestat`: Struct +## `filestat`: Record File attributes. Size: 64 Alignment: 8 -### Struct members +### Record members - `dev`: [`device`](#device) Device ID of device containing the file. @@ -789,7 +789,7 @@ Alignment: 2 - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Struct +## `event_fd_readwrite`: Record The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -797,7 +797,7 @@ Size: 16 Alignment: 8 -### Struct members +### Record members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. @@ -808,14 +808,14 @@ The state of the file descriptor. Offset: 8 -## `event`: Struct +## `event`: Record An event that occurred. Size: 32 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). @@ -853,14 +853,14 @@ If set, treat the timestamp provided in provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Struct +## `subscription_clock`: Record The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 32 Alignment: 8 -### Struct members +### Record members - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. @@ -882,7 +882,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 24 -## `subscription_fd_readwrite`: Struct +## `subscription_fd_readwrite`: Record The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -890,7 +890,7 @@ Size: 4 Alignment: 4 -### Struct members +### Record members - `file_descriptor`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. @@ -916,14 +916,14 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Struct +## `subscription`: Record Subscription to an event. Size: 48 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). @@ -1132,14 +1132,14 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Struct +## `prestat_dir`: Record The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). Size: 4 Alignment: 4 -### Struct members +### Record members - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx index 5e1049553..b0ccece64 100644 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -278,7 +278,7 @@ ;;; A region of memory for scatter/gather reads. (typename $iovec - (struct + (record ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. @@ -288,7 +288,7 @@ ;;; A region of memory for scatter/gather writes. (typename $ciovec - (struct + (record ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. @@ -349,7 +349,7 @@ ;;; A directory entry. (typename $dirent - (struct + (record ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. @@ -399,7 +399,7 @@ ;;; File descriptor attributes. (typename $fdstat - (struct + (record ;;; File type. (field $fs_filetype $filetype) ;;; File descriptor flags. @@ -457,7 +457,7 @@ ;;; File attributes. (typename $filestat - (struct + (record ;;; Device ID of device containing the file. (field $dev $device) ;;; File serial number. @@ -508,7 +508,7 @@ ;;; The contents of an `event` when type is `eventtype::fd_read` or ;;; `eventtype::fd_write`. (typename $event_fd_readwrite - (struct + (record ;;; The number of bytes available for reading or writing. (field $nbytes $filesize) ;;; The state of the file descriptor. @@ -518,7 +518,7 @@ ;;; An event that occurred. (typename $event - (struct + (record ;;; User-provided value that got attached to `subscription::userdata`. (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. @@ -546,7 +546,7 @@ ;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock - (struct + (record ;;; The clock against which to compare the timestamp. (field $id $clockid) ;;; The absolute or relative timestamp. @@ -562,7 +562,7 @@ ;;; The contents of a `subscription` when type is type is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite - (struct + (record ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd) ) @@ -579,7 +579,7 @@ ;;; Subscription to an event. (typename $subscription - (struct + (record ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) @@ -732,7 +732,7 @@ ;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir - (struct + (record ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size) ) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index fcf6a2e94..65f354c7e 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -180,7 +180,7 @@ pub enum Type { Enum(EnumDatatype), Int(IntDatatype), Flags(FlagsDatatype), - Struct(StructDatatype), + Record(RecordDatatype), Union(UnionDatatype), Handle(HandleDatatype), List(TypeRef), @@ -196,7 +196,7 @@ impl Type { Enum(_) => "enum", Int(_) => "int", Flags(_) => "flags", - Struct(_) => "struct", + Record(_) => "record", Union(_) => "union", Handle(_) => "handle", List(_) => "list", @@ -270,12 +270,12 @@ pub struct FlagsMember { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct StructDatatype { - pub members: Vec, +pub struct RecordDatatype { + pub members: Vec, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct StructMember { +pub struct RecordMember { pub name: Id, pub tref: TypeRef, pub docs: String, diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index 7865bd8fb..733535318 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -53,7 +53,7 @@ impl Type { Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), - Type::Struct { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), } } diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index 0eb2933fe..59c246d23 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -6,7 +6,7 @@ use crate::{ ast::{ BuiltinType, Document, EnumDatatype, FlagsDatatype, HandleDatatype, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, Module, ModuleImport, ModuleImportVariant, NamedType, - StructDatatype, Type, TypeRef, UnionDatatype, + RecordDatatype, Type, TypeRef, UnionDatatype, }, layout::Layout, polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, @@ -73,7 +73,7 @@ impl ToMarkdown for Type { Self::Enum(a) => a.generate(node.clone()), Self::Int(a) => a.generate(node.clone()), Self::Flags(a) => a.generate(node.clone()), - Self::Struct(a) => a.generate(node.clone()), + Self::Record(a) => a.generate(node.clone()), Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), Self::List(a) => { @@ -175,10 +175,10 @@ impl ToMarkdown for FlagsDatatype { } } -impl ToMarkdown for StructDatatype { +impl ToMarkdown for RecordDatatype { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Struct members")); + node.new_child(MdSection::new(heading, "Record members")); for member_layout in &self.member_layout() { let member = member_layout.member; @@ -198,7 +198,7 @@ impl ToMarkdown for StructDatatype { member.tref.generate(n.clone()); } - node.content_ref_mut::().r#type = Some(MdType::Struct); + node.content_ref_mut::().r#type = Some(MdType::Record); } } @@ -385,7 +385,7 @@ impl TypeRef { Type::Enum { .. } | Type::Int { .. } | Type::Flags { .. } - | Type::Struct { .. } + | Type::Record { .. } | Type::Union { .. } | Type::Handle { .. } => { unimplemented!("type_name of anonymous compound datatypes") diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index 2373f1ed5..65969b8d2 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -163,7 +163,7 @@ impl fmt::Display for MdNodeRef { } } -/// Struct representing the Markdown tree's root. +/// Record representing the Markdown tree's root. /// /// Doesn't render to anything. #[derive(Debug, Default)] @@ -237,7 +237,7 @@ impl fmt::Display for MdHeading { } } -/// Struct representing a Markdown section without any `docs`, consisting +/// Record representing a Markdown section without any `docs`, consisting /// of only a `header` (e.g., "###"), maybe some referencable `id` (i.e., /// a Markdown link), and some `title`. /// @@ -298,7 +298,7 @@ impl fmt::Display for MdSection { } } -/// Struct representing a Markdown section representing any `NamedType` element +/// Record representing a Markdown section representing any `NamedType` element /// of the AST. /// Consists of: /// * `header`, e.g., "###", or "-" for Enum variants, etc., @@ -346,7 +346,7 @@ pub(super) enum MdType { Enum { repr: String }, Int { repr: String }, Flags { repr: String }, - Struct, + Record, Union, List { r#type: String }, Pointer { r#type: String }, @@ -362,7 +362,7 @@ impl fmt::Display for MdType { Self::Enum { repr } => f.write_fmt(format_args!(": Enum(`{}`)", repr))?, Self::Int { repr } => f.write_fmt(format_args!(": Int(`{}`)", repr))?, Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, - Self::Struct => f.write_fmt(format_args!(": Struct"))?, + Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, Self::List { r#type } => f.write_fmt(format_args!(": `List<{}>`", r#type))?, Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, @@ -419,7 +419,7 @@ impl fmt::Display for MdNamedType { } } -/// Struct representing a Markdown section representing any `InterfaceFunc` element +/// Record representing a Markdown section representing any `InterfaceFunc` element /// of the AST. /// Consists of: /// * `header`, e.g., "###", diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index 6012d38d8..d29f192b8 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -56,7 +56,7 @@ impl Type { Type::Enum(e) => e.repr.mem_size_align(), Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), - Type::Struct(s) => s.layout(cache), + Type::Record(s) => s.layout(cache), Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => BuiltinType::String.mem_size_align(), @@ -84,23 +84,23 @@ impl Layout for IntRepr { } } -pub struct StructMemberLayout<'a> { - pub member: &'a StructMember, +pub struct RecordMemberLayout<'a> { + pub member: &'a RecordMember, pub offset: usize, } -impl StructDatatype { - pub fn member_layout(&self) -> Vec { +impl RecordDatatype { + pub fn member_layout(&self) -> Vec { self.member_layout_(&mut HashMap::new()) } - fn member_layout_(&self, cache: &mut HashMap) -> Vec { + fn member_layout_(&self, cache: &mut HashMap) -> Vec { let mut members = Vec::new(); let mut offset = 0; for m in self.members.iter() { let sa = m.tref.layout(cache); offset = align_to(offset, sa.align); - members.push(StructMemberLayout { member: m, offset }); + members.push(RecordMemberLayout { member: m, offset }); offset += sa.size; } members @@ -120,7 +120,7 @@ impl StructDatatype { } } -impl Layout for StructDatatype { +impl Layout for RecordDatatype { fn mem_size_align(&self) -> SizeAlign { let mut cache = HashMap::new(); self.layout(&mut cache) diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index c612e601d..d320e15d6 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -27,13 +27,13 @@ pub use ast::{ BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, - ModuleImport, ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypeRef, + ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypeRef, UnionDatatype, UnionVariant, }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; -pub use layout::{Layout, SizeAlign, StructMemberLayout, UnionLayout}; +pub use layout::{Layout, RecordMemberLayout, SizeAlign, UnionLayout}; pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 964a5ba48..aedee808f 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -30,9 +30,9 @@ mod kw { wast::custom_keyword!(list); wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); + wast::custom_keyword!(record); wast::custom_keyword!(r#const = "const"); wast::custom_keyword!(r#enum = "enum"); - wast::custom_keyword!(r#struct = "struct"); wast::custom_keyword!(r#union = "union"); wast::custom_keyword!(r#use = "use"); wast::custom_keyword!(s16); @@ -272,7 +272,7 @@ pub enum TypedefSyntax<'a> { Enum(EnumSyntax<'a>), Int(IntSyntax<'a>), Flags(FlagsSyntax<'a>), - Struct(StructSyntax<'a>), + Record(RecordSyntax<'a>), Union(UnionSyntax<'a>), Handle(HandleSyntax), List(Box>), @@ -298,8 +298,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Int(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Flags(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Struct(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Record(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Union(parser.parse()?)) } else if l.peek::() { @@ -406,19 +406,19 @@ impl<'a> Parse<'a> for FlagsSyntax<'a> { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct StructSyntax<'a> { +pub struct RecordSyntax<'a> { pub fields: Vec>>, } -impl<'a> Parse<'a> for StructSyntax<'a> { +impl<'a> Parse<'a> for RecordSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; + parser.parse::()?; let mut fields = Vec::new(); fields.push(parser.parse()?); while !parser.is_empty() { fields.push(parser.parse()?); } - Ok(StructSyntax { fields }) + Ok(RecordSyntax { fields }) } } diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 11778fa15..88d7d5dce 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -119,7 +119,7 @@ impl Type { Type::Enum(a) => a.to_sexpr(), Type::Int(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), - Type::Struct(a) => a.to_sexpr(), + Type::Record(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), Type::Handle(a) => a.to_sexpr(), Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), @@ -183,9 +183,9 @@ impl FlagsDatatype { } } -impl StructDatatype { +impl RecordDatatype { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("struct")]; + let header = vec![SExpr::word("record")]; let members = self .members .iter() diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs index f541e9fc1..2d03797be 100644 --- a/proposals/clocks/tools/witx/src/representation.rs +++ b/proposals/clocks/tools/witx/src/representation.rs @@ -1,5 +1,5 @@ use crate::{ - BuiltinType, EnumDatatype, FlagsDatatype, IntRepr, NamedType, StructDatatype, Type, TypeRef, + BuiltinType, EnumDatatype, FlagsDatatype, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, }; @@ -117,9 +117,9 @@ impl Representable for FlagsDatatype { } } -impl Representable for StructDatatype { +impl Representable for RecordDatatype { fn representable(&self, by: &Self) -> RepEquality { - // Structs must have exact structural equality - same members, must + // Records must have exact structural equality - same members, must // be Eq, in the same order. // We would require require a more expressive RepEquality enum to describe which members // might be supersets. @@ -205,7 +205,7 @@ impl Representable for Type { match (&self, &by) { (Type::Enum(s), Type::Enum(b)) => s.representable(b), (Type::Flags(s), Type::Flags(b)) => s.representable(b), - (Type::Struct(s), Type::Struct(b)) => s.representable(b), + (Type::Record(s), Type::Record(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural (Type::List(s), Type::List(b)) => s.representable(b), diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 211438819..adfcb757e 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -2,13 +2,13 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, - ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, VariantSyntax, }, BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypePassedBy, TypeRef, + ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, }; use std::collections::{hash_map, HashMap}; @@ -43,7 +43,7 @@ pub enum ValidationError { #[error("First result type must be pass-by-value")] InvalidFirstResultType { location: Location }, #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] - AnonymousStructure { location: Location }, + AnonymousRecord { location: Location }, #[error("Invalid union field `{name}`: {reason}")] InvalidUnionField { name: String, @@ -61,7 +61,7 @@ impl ValidationError { | Recursive { location, .. } | InvalidRepr { location, .. } | InvalidFirstResultType { location, .. } - | AnonymousStructure { location, .. } + | AnonymousRecord { location, .. } | InvalidUnionField { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } @@ -239,12 +239,12 @@ impl DocValidationScope<'_> { TypedefSyntax::Enum { .. } | TypedefSyntax::Int { .. } | TypedefSyntax::Flags { .. } - | TypedefSyntax::Struct { .. } + | TypedefSyntax::Record { .. } | TypedefSyntax::Union { .. } | TypedefSyntax::Handle { .. } if !named => { - Err(ValidationError::AnonymousStructure { + Err(ValidationError::AnonymousRecord { location: self.location(span), }) } @@ -252,7 +252,7 @@ impl DocValidationScope<'_> { TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), TypedefSyntax::Int(syntax) => Type::Int(self.validate_int(&syntax, span)?), TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), - TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), + TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), TypedefSyntax::List(syntax) => { @@ -332,11 +332,11 @@ impl DocValidationScope<'_> { Ok(FlagsDatatype { repr, flags }) } - fn validate_struct( + fn validate_record( &self, - syntax: &StructSyntax, + syntax: &RecordSyntax, _span: wast::Span, - ) -> Result { + ) -> Result { let mut member_scope = IdentValidation::new(); let members = syntax .fields @@ -346,11 +346,11 @@ impl DocValidationScope<'_> { .introduce(f.item.name.name(), self.location(f.item.name.span()))?; let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; let docs = f.comments.docs(); - Ok(StructMember { name, tref, docs }) + Ok(RecordMember { name, tref, docs }) }) - .collect::, _>>()?; + .collect::, _>>()?; - Ok(StructDatatype { members }) + Ok(RecordDatatype { members }) } fn validate_union( diff --git a/proposals/clocks/tools/witx/tests/anonymous.rs b/proposals/clocks/tools/witx/tests/anonymous.rs index 6bf11d883..2bff69960 100644 --- a/proposals/clocks/tools/witx/tests/anonymous.rs +++ b/proposals/clocks/tools/witx/tests/anonymous.rs @@ -1,30 +1,30 @@ use witx; -fn is_anonymous_struct_err(r: Result) -> bool { +fn is_anonymous_record_err(r: Result) -> bool { match r { - Err(witx::WitxError::Validation(witx::ValidationError::AnonymousStructure { .. })) => true, + Err(witx::WitxError::Validation(witx::ValidationError::AnonymousRecord { .. })) => true, _ => false, } } #[test] fn anonymous_types() { - let pointer_to_struct = witx::parse("(typename $a (@witx pointer (struct (field $b u8))))"); - assert!(is_anonymous_struct_err(pointer_to_struct)); + let pointer_to_record = witx::parse("(typename $a (@witx pointer (record (field $b u8))))"); + assert!(is_anonymous_record_err(pointer_to_record)); let pointer_to_union = witx::parse( "(typename $tag (enum u8 $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", ); - assert!(is_anonymous_struct_err(pointer_to_union)); + assert!(is_anonymous_record_err(pointer_to_union)); let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum u32 $b)))"); - assert!(is_anonymous_struct_err(pointer_to_enum)); + assert!(is_anonymous_record_err(pointer_to_enum)); let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags u32 $b)))"); - assert!(is_anonymous_struct_err(pointer_to_flags)); + assert!(is_anonymous_record_err(pointer_to_flags)); let pointer_to_handle = witx::parse("(typename $a (@witx pointer (handle)))"); - assert!(is_anonymous_struct_err(pointer_to_handle)); + assert!(is_anonymous_record_err(pointer_to_handle)); let pointer_to_builtin = witx::parse("(typename $a (@witx pointer u8))"); assert!(pointer_to_builtin.is_ok()); @@ -32,14 +32,14 @@ fn anonymous_types() { let pointer_to_pointer = witx::parse("(typename $a (@witx pointer (@witx const_pointer u8)))"); assert!(pointer_to_pointer.is_ok()); - let struct_in_struct = witx::parse("(typename $a (struct (field $b (struct (field $c u8)))))"); - assert!(is_anonymous_struct_err(struct_in_struct)); + let record_in_record = witx::parse("(typename $a (record (field $b (record (field $c u8)))))"); + assert!(is_anonymous_record_err(record_in_record)); - let union_in_struct = witx::parse( - "(typename $tag (enum u8 $c)) (typename $a (struct (field $b (union $tag (field $c u8)))))", + let union_in_record = witx::parse( + "(typename $tag (enum u8 $c)) (typename $a (record (field $b (union $tag (field $c u8)))))", ); - assert!(is_anonymous_struct_err(union_in_struct)); + assert!(is_anonymous_record_err(union_in_record)); - let pointer_in_struct = witx::parse("(typename $a (struct (field $b (@witx pointer u8))))"); - assert!(pointer_in_struct.is_ok()) + let pointer_in_record = witx::parse("(typename $a (record (field $b (@witx pointer u8))))"); + assert!(pointer_in_record.is_ok()) } diff --git a/proposals/clocks/tools/witx/tests/multimodule.rs b/proposals/clocks/tools/witx/tests/multimodule.rs index 47fb34755..a8e35609f 100644 --- a/proposals/clocks/tools/witx/tests/multimodule.rs +++ b/proposals/clocks/tools/witx/tests/multimodule.rs @@ -18,10 +18,10 @@ fn validate_multimodule() { // `b` is a struct with a single member of type `a` let type_b = doc.typename(&Id::new("b")).expect("type b exists"); match &*type_b.type_() { - Type::Struct(struct_) => { - assert_eq!(struct_.members.len(), 1); + Type::Record(record) => { + assert_eq!(record.members.len(), 1); assert_eq!( - struct_.members.get(0).unwrap().tref, + record.members.get(0).unwrap().tref, TypeRef::Name(type_a.clone()) ); } @@ -31,13 +31,13 @@ fn validate_multimodule() { // `c` is a struct with a two members of type `a` let type_c = doc.typename(&Id::new("c")).expect("type c exists"); match &*type_c.type_() { - Type::Struct(struct_) => { - assert_eq!(struct_.members.len(), 2); + Type::Record(record) => { + assert_eq!(record.members.len(), 2); assert_eq!( - struct_.members.get(0).unwrap().tref, + record.members.get(0).unwrap().tref, TypeRef::Name(type_a.clone()) ); - assert_eq!(struct_.members.get(1).unwrap().tref, TypeRef::Name(type_a)); + assert_eq!(record.members.get(1).unwrap().tref, TypeRef::Name(type_a)); } _ => panic!("c is a struct"), } diff --git a/proposals/clocks/tools/witx/tests/multimodule/type_b.witx b/proposals/clocks/tools/witx/tests/multimodule/type_b.witx index fe8315da9..fe169d3ec 100644 --- a/proposals/clocks/tools/witx/tests/multimodule/type_b.witx +++ b/proposals/clocks/tools/witx/tests/multimodule/type_b.witx @@ -1,2 +1,2 @@ (use "type_a.witx") -(typename $b (struct (field $member_a $a))) +(typename $b (record (field $member_a $a))) diff --git a/proposals/clocks/tools/witx/tests/multimodule/type_c.witx b/proposals/clocks/tools/witx/tests/multimodule/type_c.witx index 9f8819162..f42aac2d0 100644 --- a/proposals/clocks/tools/witx/tests/multimodule/type_c.witx +++ b/proposals/clocks/tools/witx/tests/multimodule/type_c.witx @@ -1,2 +1,2 @@ (use "type_a.witx") -(typename $c (struct (field $first_a $a) (field $second_a $a))) +(typename $c (record (field $first_a $a) (field $second_a $a))) From 5c90de2dfb4afd3a16ef30406c3c2d8501c41ddf Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 07:24:15 -0800 Subject: [PATCH 0830/1772] Rename structs to records --- proposals/random/phases/ephemeral/docs.md | 44 +++++++++---------- .../phases/ephemeral/witx/typenames.witx | 22 +++++----- .../random/phases/old/snapshot_0/docs.md | 44 +++++++++---------- .../phases/old/snapshot_0/witx/typenames.witx | 22 +++++----- proposals/random/phases/snapshot/docs.md | 44 +++++++++---------- .../phases/snapshot/witx/typenames.witx | 22 +++++----- proposals/random/tools/witx/src/ast.rs | 10 ++--- proposals/random/tools/witx/src/coretypes.rs | 2 +- proposals/random/tools/witx/src/docs/ast.rs | 12 ++--- proposals/random/tools/witx/src/docs/md.rs | 12 ++--- proposals/random/tools/witx/src/layout.rs | 16 +++---- proposals/random/tools/witx/src/lib.rs | 4 +- proposals/random/tools/witx/src/parser.rs | 16 +++---- proposals/random/tools/witx/src/render.rs | 6 +-- .../random/tools/witx/src/representation.rs | 8 ++-- proposals/random/tools/witx/src/validate.rs | 26 +++++------ .../random/tools/witx/tests/anonymous.rs | 30 ++++++------- .../random/tools/witx/tests/multimodule.rs | 14 +++--- .../tools/witx/tests/multimodule/type_b.witx | 2 +- .../tools/witx/tests/multimodule/type_c.witx | 2 +- 20 files changed, 179 insertions(+), 179 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 3f17fdacf..3bd147b43 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -408,14 +408,14 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Struct +## `iovec`: Record A region of memory for scatter/gather reads. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `Pointer` The address of the buffer to be filled. @@ -426,14 +426,14 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Struct +## `ciovec`: Record A region of memory for scatter/gather writes. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `ConstPointer` The address of the buffer to be written. @@ -540,14 +540,14 @@ The file refers to a symbolic link inode. - `fifo` The file descriptor or file refers to a FIFO. -## `dirent`: Struct +## `dirent`: Record A directory entry. Size: 24 Alignment: 8 -### Struct members +### Record members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. @@ -619,14 +619,14 @@ Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Struct +## `fdstat`: Record File descriptor attributes. Size: 24 Alignment: 8 -### Struct members +### Record members - `fs_filetype`: [`filetype`](#filetype) File type. @@ -748,14 +748,14 @@ indicates that the file is only accessible by the effective "user" that the WASI store uses to access the filesystem, and inaccessible to other "users". -## `filestat`: Struct +## `filestat`: Record File attributes. Size: 64 Alignment: 8 -### Struct members +### Record members - `dev`: [`device`](#device) Device ID of device containing the file. @@ -841,7 +841,7 @@ Alignment: 2 - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Struct +## `event_fd_readwrite`: Record The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -849,7 +849,7 @@ Size: 16 Alignment: 8 -### Struct members +### Record members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. @@ -880,14 +880,14 @@ Alignment: 8 - `clock` -## `event`: Struct +## `event`: Record An event that occurred. Size: 40 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). @@ -919,14 +919,14 @@ If set, treat the timestamp provided in provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Struct +## `subscription_clock`: Record The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 32 Alignment: 8 -### Struct members +### Record members - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. @@ -948,7 +948,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 24 -## `subscription_fd_readwrite`: Struct +## `subscription_fd_readwrite`: Record The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -956,7 +956,7 @@ Size: 4 Alignment: 4 -### Struct members +### Record members - `fd`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. @@ -982,14 +982,14 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Struct +## `subscription`: Record Subscription to an event. Size: 48 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). @@ -1066,14 +1066,14 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Struct +## `prestat_dir`: Record The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). Size: 4 Alignment: 4 -### Struct members +### Record members - `pr_name_len`: [`size`](#size) The length of the directory name for use with `fd_prestat_dir_name`. diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 723d43cb7..d4cc6274c 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -286,7 +286,7 @@ ;;; A region of memory for scatter/gather reads. (typename $iovec - (struct + (record ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. @@ -296,7 +296,7 @@ ;;; A region of memory for scatter/gather writes. (typename $ciovec - (struct + (record ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. @@ -362,7 +362,7 @@ ;;; A directory entry. (typename $dirent - (struct + (record ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. @@ -412,7 +412,7 @@ ;;; File descriptor attributes. (typename $fdstat - (struct + (record ;;; File type. (field $fs_filetype $filetype) ;;; File descriptor flags. @@ -501,7 +501,7 @@ ;;; File attributes. (typename $filestat - (struct + (record ;;; Device ID of device containing the file. (field $dev $device) ;;; File serial number. @@ -554,7 +554,7 @@ ;;; The contents of an `event` when type is `eventtype::fd_read` or ;;; `eventtype::fd_write`. (typename $event_fd_readwrite - (struct + (record ;;; The number of bytes available for reading or writing. (field $nbytes $filesize) ;;; The state of the file descriptor. @@ -573,7 +573,7 @@ ;;; An event that occurred. (typename $event - (struct + (record ;;; User-provided value that got attached to `subscription::userdata`. (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. @@ -598,7 +598,7 @@ ;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock - (struct + (record ;;; The clock against which to compare the timestamp. (field $id $clockid) ;;; The absolute or relative timestamp. @@ -614,7 +614,7 @@ ;;; The contents of a `subscription` when type is type is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite - (struct + (record ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $fd $fd) ) @@ -631,7 +631,7 @@ ;;; Subscription to an event. (typename $subscription - (struct + (record ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) @@ -685,7 +685,7 @@ ;;; The contents of a `prestat` when its type is `preopentype::dir`. (typename $prestat_dir - (struct + (record ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size) ) diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index 9307d9754..b56aa1f5e 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -400,14 +400,14 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Struct +## `iovec`: Record A region of memory for scatter/gather reads. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `Pointer` The address of the buffer to be filled. @@ -418,14 +418,14 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Struct +## `ciovec`: Record A region of memory for scatter/gather writes. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `ConstPointer` The address of the buffer to be written. @@ -525,14 +525,14 @@ The file descriptor or file refers to a byte-stream socket. - `symbolic_link` The file refers to a symbolic link inode. -## `dirent`: Struct +## `dirent`: Record A directory entry. Size: 24 Alignment: 8 -### Struct members +### Record members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. @@ -604,14 +604,14 @@ Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Struct +## `fdstat`: Record File descriptor attributes. Size: 24 Alignment: 8 -### Struct members +### Record members - `fs_filetype`: [`filetype`](#filetype) File type. @@ -699,14 +699,14 @@ Size: 4 Alignment: 4 -## `filestat`: Struct +## `filestat`: Record File attributes. Size: 56 Alignment: 8 -### Struct members +### Record members - `dev`: [`device`](#device) Device ID of device containing the file. @@ -787,7 +787,7 @@ Alignment: 2 - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Struct +## `event_fd_readwrite`: Record The contents of an [`event`](#event) for the [`eventtype::fd_read`](#eventtype.fd_read) and [`eventtype::fd_write`](#eventtype.fd_write) variants @@ -795,7 +795,7 @@ Size: 16 Alignment: 8 -### Struct members +### Record members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. @@ -806,14 +806,14 @@ The state of the file descriptor. Offset: 8 -## `event`: Struct +## `event`: Record An event that occurred. Size: 32 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). @@ -851,14 +851,14 @@ If set, treat the timestamp provided in provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Struct +## `subscription_clock`: Record The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 40 Alignment: 8 -### Struct members +### Record members - `identifier`: [`userdata`](#userdata) The user-defined unique identifier of the clock. @@ -885,7 +885,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 32 -## `subscription_fd_readwrite`: Struct +## `subscription_fd_readwrite`: Record The contents of a [`subscription`](#subscription) when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -893,7 +893,7 @@ Size: 4 Alignment: 4 -### Struct members +### Record members - `file_descriptor`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. @@ -919,14 +919,14 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Struct +## `subscription`: Record Subscription to an event. Size: 56 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). @@ -1135,14 +1135,14 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Struct +## `prestat_dir`: Record The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). Size: 4 Alignment: 4 -### Struct members +### Record members - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx index b6f672c3a..37a49f083 100644 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/random/phases/old/snapshot_0/witx/typenames.witx @@ -278,7 +278,7 @@ ;;; A region of memory for scatter/gather reads. (typename $iovec - (struct + (record ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. @@ -288,7 +288,7 @@ ;;; A region of memory for scatter/gather writes. (typename $ciovec - (struct + (record ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. @@ -347,7 +347,7 @@ ;;; A directory entry. (typename $dirent - (struct + (record ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. @@ -397,7 +397,7 @@ ;;; File descriptor attributes. (typename $fdstat - (struct + (record ;;; File type. (field $fs_filetype $filetype) ;;; File descriptor flags. @@ -455,7 +455,7 @@ ;;; File attributes. (typename $filestat - (struct + (record ;;; Device ID of device containing the file. (field $dev $device) ;;; File serial number. @@ -506,7 +506,7 @@ ;;; The contents of an `event` for the `eventtype::fd_read` and ;;; `eventtype::fd_write` variants (typename $event_fd_readwrite - (struct + (record ;;; The number of bytes available for reading or writing. (field $nbytes $filesize) ;;; The state of the file descriptor. @@ -516,7 +516,7 @@ ;;; An event that occurred. (typename $event - (struct + (record ;;; User-provided value that got attached to `subscription::userdata`. (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. @@ -544,7 +544,7 @@ ;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock - (struct + (record ;;; The user-defined unique identifier of the clock. (field $identifier $userdata) ;;; The clock against which to compare the timestamp. @@ -562,7 +562,7 @@ ;;; The contents of a `subscription` when the variant is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite - (struct + (record ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd) ) @@ -579,7 +579,7 @@ ;;; Subscription to an event. (typename $subscription - (struct + (record ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) @@ -732,7 +732,7 @@ ;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir - (struct + (record ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size) ) diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index 1a223448f..1cb642abe 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -400,14 +400,14 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Struct +## `iovec`: Record A region of memory for scatter/gather reads. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `Pointer` The address of the buffer to be filled. @@ -418,14 +418,14 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Struct +## `ciovec`: Record A region of memory for scatter/gather writes. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `ConstPointer` The address of the buffer to be written. @@ -527,14 +527,14 @@ The file descriptor or file refers to a byte-stream socket. - `symbolic_link` The file refers to a symbolic link inode. -## `dirent`: Struct +## `dirent`: Record A directory entry. Size: 24 Alignment: 8 -### Struct members +### Record members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. @@ -606,14 +606,14 @@ Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Struct +## `fdstat`: Record File descriptor attributes. Size: 24 Alignment: 8 -### Struct members +### Record members - `fs_filetype`: [`filetype`](#filetype) File type. @@ -701,14 +701,14 @@ Size: 8 Alignment: 8 -## `filestat`: Struct +## `filestat`: Record File attributes. Size: 64 Alignment: 8 -### Struct members +### Record members - `dev`: [`device`](#device) Device ID of device containing the file. @@ -789,7 +789,7 @@ Alignment: 2 - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Struct +## `event_fd_readwrite`: Record The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -797,7 +797,7 @@ Size: 16 Alignment: 8 -### Struct members +### Record members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. @@ -808,14 +808,14 @@ The state of the file descriptor. Offset: 8 -## `event`: Struct +## `event`: Record An event that occurred. Size: 32 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). @@ -853,14 +853,14 @@ If set, treat the timestamp provided in provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Struct +## `subscription_clock`: Record The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 32 Alignment: 8 -### Struct members +### Record members - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. @@ -882,7 +882,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 24 -## `subscription_fd_readwrite`: Struct +## `subscription_fd_readwrite`: Record The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -890,7 +890,7 @@ Size: 4 Alignment: 4 -### Struct members +### Record members - `file_descriptor`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. @@ -916,14 +916,14 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Struct +## `subscription`: Record Subscription to an event. Size: 48 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). @@ -1132,14 +1132,14 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Struct +## `prestat_dir`: Record The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). Size: 4 Alignment: 4 -### Struct members +### Record members - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx index 5e1049553..b0ccece64 100644 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -278,7 +278,7 @@ ;;; A region of memory for scatter/gather reads. (typename $iovec - (struct + (record ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. @@ -288,7 +288,7 @@ ;;; A region of memory for scatter/gather writes. (typename $ciovec - (struct + (record ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. @@ -349,7 +349,7 @@ ;;; A directory entry. (typename $dirent - (struct + (record ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. @@ -399,7 +399,7 @@ ;;; File descriptor attributes. (typename $fdstat - (struct + (record ;;; File type. (field $fs_filetype $filetype) ;;; File descriptor flags. @@ -457,7 +457,7 @@ ;;; File attributes. (typename $filestat - (struct + (record ;;; Device ID of device containing the file. (field $dev $device) ;;; File serial number. @@ -508,7 +508,7 @@ ;;; The contents of an `event` when type is `eventtype::fd_read` or ;;; `eventtype::fd_write`. (typename $event_fd_readwrite - (struct + (record ;;; The number of bytes available for reading or writing. (field $nbytes $filesize) ;;; The state of the file descriptor. @@ -518,7 +518,7 @@ ;;; An event that occurred. (typename $event - (struct + (record ;;; User-provided value that got attached to `subscription::userdata`. (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. @@ -546,7 +546,7 @@ ;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock - (struct + (record ;;; The clock against which to compare the timestamp. (field $id $clockid) ;;; The absolute or relative timestamp. @@ -562,7 +562,7 @@ ;;; The contents of a `subscription` when type is type is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite - (struct + (record ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd) ) @@ -579,7 +579,7 @@ ;;; Subscription to an event. (typename $subscription - (struct + (record ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) @@ -732,7 +732,7 @@ ;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir - (struct + (record ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size) ) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index fcf6a2e94..65f354c7e 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -180,7 +180,7 @@ pub enum Type { Enum(EnumDatatype), Int(IntDatatype), Flags(FlagsDatatype), - Struct(StructDatatype), + Record(RecordDatatype), Union(UnionDatatype), Handle(HandleDatatype), List(TypeRef), @@ -196,7 +196,7 @@ impl Type { Enum(_) => "enum", Int(_) => "int", Flags(_) => "flags", - Struct(_) => "struct", + Record(_) => "record", Union(_) => "union", Handle(_) => "handle", List(_) => "list", @@ -270,12 +270,12 @@ pub struct FlagsMember { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct StructDatatype { - pub members: Vec, +pub struct RecordDatatype { + pub members: Vec, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct StructMember { +pub struct RecordMember { pub name: Id, pub tref: TypeRef, pub docs: String, diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index 7865bd8fb..733535318 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -53,7 +53,7 @@ impl Type { Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), - Type::Struct { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), } } diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index 0eb2933fe..59c246d23 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -6,7 +6,7 @@ use crate::{ ast::{ BuiltinType, Document, EnumDatatype, FlagsDatatype, HandleDatatype, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, Module, ModuleImport, ModuleImportVariant, NamedType, - StructDatatype, Type, TypeRef, UnionDatatype, + RecordDatatype, Type, TypeRef, UnionDatatype, }, layout::Layout, polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, @@ -73,7 +73,7 @@ impl ToMarkdown for Type { Self::Enum(a) => a.generate(node.clone()), Self::Int(a) => a.generate(node.clone()), Self::Flags(a) => a.generate(node.clone()), - Self::Struct(a) => a.generate(node.clone()), + Self::Record(a) => a.generate(node.clone()), Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), Self::List(a) => { @@ -175,10 +175,10 @@ impl ToMarkdown for FlagsDatatype { } } -impl ToMarkdown for StructDatatype { +impl ToMarkdown for RecordDatatype { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Struct members")); + node.new_child(MdSection::new(heading, "Record members")); for member_layout in &self.member_layout() { let member = member_layout.member; @@ -198,7 +198,7 @@ impl ToMarkdown for StructDatatype { member.tref.generate(n.clone()); } - node.content_ref_mut::().r#type = Some(MdType::Struct); + node.content_ref_mut::().r#type = Some(MdType::Record); } } @@ -385,7 +385,7 @@ impl TypeRef { Type::Enum { .. } | Type::Int { .. } | Type::Flags { .. } - | Type::Struct { .. } + | Type::Record { .. } | Type::Union { .. } | Type::Handle { .. } => { unimplemented!("type_name of anonymous compound datatypes") diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index 2373f1ed5..65969b8d2 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -163,7 +163,7 @@ impl fmt::Display for MdNodeRef { } } -/// Struct representing the Markdown tree's root. +/// Record representing the Markdown tree's root. /// /// Doesn't render to anything. #[derive(Debug, Default)] @@ -237,7 +237,7 @@ impl fmt::Display for MdHeading { } } -/// Struct representing a Markdown section without any `docs`, consisting +/// Record representing a Markdown section without any `docs`, consisting /// of only a `header` (e.g., "###"), maybe some referencable `id` (i.e., /// a Markdown link), and some `title`. /// @@ -298,7 +298,7 @@ impl fmt::Display for MdSection { } } -/// Struct representing a Markdown section representing any `NamedType` element +/// Record representing a Markdown section representing any `NamedType` element /// of the AST. /// Consists of: /// * `header`, e.g., "###", or "-" for Enum variants, etc., @@ -346,7 +346,7 @@ pub(super) enum MdType { Enum { repr: String }, Int { repr: String }, Flags { repr: String }, - Struct, + Record, Union, List { r#type: String }, Pointer { r#type: String }, @@ -362,7 +362,7 @@ impl fmt::Display for MdType { Self::Enum { repr } => f.write_fmt(format_args!(": Enum(`{}`)", repr))?, Self::Int { repr } => f.write_fmt(format_args!(": Int(`{}`)", repr))?, Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, - Self::Struct => f.write_fmt(format_args!(": Struct"))?, + Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, Self::List { r#type } => f.write_fmt(format_args!(": `List<{}>`", r#type))?, Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, @@ -419,7 +419,7 @@ impl fmt::Display for MdNamedType { } } -/// Struct representing a Markdown section representing any `InterfaceFunc` element +/// Record representing a Markdown section representing any `InterfaceFunc` element /// of the AST. /// Consists of: /// * `header`, e.g., "###", diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index 6012d38d8..d29f192b8 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -56,7 +56,7 @@ impl Type { Type::Enum(e) => e.repr.mem_size_align(), Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), - Type::Struct(s) => s.layout(cache), + Type::Record(s) => s.layout(cache), Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => BuiltinType::String.mem_size_align(), @@ -84,23 +84,23 @@ impl Layout for IntRepr { } } -pub struct StructMemberLayout<'a> { - pub member: &'a StructMember, +pub struct RecordMemberLayout<'a> { + pub member: &'a RecordMember, pub offset: usize, } -impl StructDatatype { - pub fn member_layout(&self) -> Vec { +impl RecordDatatype { + pub fn member_layout(&self) -> Vec { self.member_layout_(&mut HashMap::new()) } - fn member_layout_(&self, cache: &mut HashMap) -> Vec { + fn member_layout_(&self, cache: &mut HashMap) -> Vec { let mut members = Vec::new(); let mut offset = 0; for m in self.members.iter() { let sa = m.tref.layout(cache); offset = align_to(offset, sa.align); - members.push(StructMemberLayout { member: m, offset }); + members.push(RecordMemberLayout { member: m, offset }); offset += sa.size; } members @@ -120,7 +120,7 @@ impl StructDatatype { } } -impl Layout for StructDatatype { +impl Layout for RecordDatatype { fn mem_size_align(&self) -> SizeAlign { let mut cache = HashMap::new(); self.layout(&mut cache) diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index c612e601d..d320e15d6 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -27,13 +27,13 @@ pub use ast::{ BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, - ModuleImport, ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypeRef, + ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypeRef, UnionDatatype, UnionVariant, }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; -pub use layout::{Layout, SizeAlign, StructMemberLayout, UnionLayout}; +pub use layout::{Layout, RecordMemberLayout, SizeAlign, UnionLayout}; pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 964a5ba48..aedee808f 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -30,9 +30,9 @@ mod kw { wast::custom_keyword!(list); wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); + wast::custom_keyword!(record); wast::custom_keyword!(r#const = "const"); wast::custom_keyword!(r#enum = "enum"); - wast::custom_keyword!(r#struct = "struct"); wast::custom_keyword!(r#union = "union"); wast::custom_keyword!(r#use = "use"); wast::custom_keyword!(s16); @@ -272,7 +272,7 @@ pub enum TypedefSyntax<'a> { Enum(EnumSyntax<'a>), Int(IntSyntax<'a>), Flags(FlagsSyntax<'a>), - Struct(StructSyntax<'a>), + Record(RecordSyntax<'a>), Union(UnionSyntax<'a>), Handle(HandleSyntax), List(Box>), @@ -298,8 +298,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Int(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Flags(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Struct(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Record(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Union(parser.parse()?)) } else if l.peek::() { @@ -406,19 +406,19 @@ impl<'a> Parse<'a> for FlagsSyntax<'a> { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct StructSyntax<'a> { +pub struct RecordSyntax<'a> { pub fields: Vec>>, } -impl<'a> Parse<'a> for StructSyntax<'a> { +impl<'a> Parse<'a> for RecordSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; + parser.parse::()?; let mut fields = Vec::new(); fields.push(parser.parse()?); while !parser.is_empty() { fields.push(parser.parse()?); } - Ok(StructSyntax { fields }) + Ok(RecordSyntax { fields }) } } diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 11778fa15..88d7d5dce 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -119,7 +119,7 @@ impl Type { Type::Enum(a) => a.to_sexpr(), Type::Int(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), - Type::Struct(a) => a.to_sexpr(), + Type::Record(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), Type::Handle(a) => a.to_sexpr(), Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), @@ -183,9 +183,9 @@ impl FlagsDatatype { } } -impl StructDatatype { +impl RecordDatatype { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("struct")]; + let header = vec![SExpr::word("record")]; let members = self .members .iter() diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs index f541e9fc1..2d03797be 100644 --- a/proposals/random/tools/witx/src/representation.rs +++ b/proposals/random/tools/witx/src/representation.rs @@ -1,5 +1,5 @@ use crate::{ - BuiltinType, EnumDatatype, FlagsDatatype, IntRepr, NamedType, StructDatatype, Type, TypeRef, + BuiltinType, EnumDatatype, FlagsDatatype, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, }; @@ -117,9 +117,9 @@ impl Representable for FlagsDatatype { } } -impl Representable for StructDatatype { +impl Representable for RecordDatatype { fn representable(&self, by: &Self) -> RepEquality { - // Structs must have exact structural equality - same members, must + // Records must have exact structural equality - same members, must // be Eq, in the same order. // We would require require a more expressive RepEquality enum to describe which members // might be supersets. @@ -205,7 +205,7 @@ impl Representable for Type { match (&self, &by) { (Type::Enum(s), Type::Enum(b)) => s.representable(b), (Type::Flags(s), Type::Flags(b)) => s.representable(b), - (Type::Struct(s), Type::Struct(b)) => s.representable(b), + (Type::Record(s), Type::Record(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural (Type::List(s), Type::List(b)) => s.representable(b), diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 211438819..adfcb757e 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -2,13 +2,13 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, - ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, VariantSyntax, }, BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypePassedBy, TypeRef, + ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, }; use std::collections::{hash_map, HashMap}; @@ -43,7 +43,7 @@ pub enum ValidationError { #[error("First result type must be pass-by-value")] InvalidFirstResultType { location: Location }, #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] - AnonymousStructure { location: Location }, + AnonymousRecord { location: Location }, #[error("Invalid union field `{name}`: {reason}")] InvalidUnionField { name: String, @@ -61,7 +61,7 @@ impl ValidationError { | Recursive { location, .. } | InvalidRepr { location, .. } | InvalidFirstResultType { location, .. } - | AnonymousStructure { location, .. } + | AnonymousRecord { location, .. } | InvalidUnionField { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } @@ -239,12 +239,12 @@ impl DocValidationScope<'_> { TypedefSyntax::Enum { .. } | TypedefSyntax::Int { .. } | TypedefSyntax::Flags { .. } - | TypedefSyntax::Struct { .. } + | TypedefSyntax::Record { .. } | TypedefSyntax::Union { .. } | TypedefSyntax::Handle { .. } if !named => { - Err(ValidationError::AnonymousStructure { + Err(ValidationError::AnonymousRecord { location: self.location(span), }) } @@ -252,7 +252,7 @@ impl DocValidationScope<'_> { TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), TypedefSyntax::Int(syntax) => Type::Int(self.validate_int(&syntax, span)?), TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), - TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), + TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), TypedefSyntax::List(syntax) => { @@ -332,11 +332,11 @@ impl DocValidationScope<'_> { Ok(FlagsDatatype { repr, flags }) } - fn validate_struct( + fn validate_record( &self, - syntax: &StructSyntax, + syntax: &RecordSyntax, _span: wast::Span, - ) -> Result { + ) -> Result { let mut member_scope = IdentValidation::new(); let members = syntax .fields @@ -346,11 +346,11 @@ impl DocValidationScope<'_> { .introduce(f.item.name.name(), self.location(f.item.name.span()))?; let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; let docs = f.comments.docs(); - Ok(StructMember { name, tref, docs }) + Ok(RecordMember { name, tref, docs }) }) - .collect::, _>>()?; + .collect::, _>>()?; - Ok(StructDatatype { members }) + Ok(RecordDatatype { members }) } fn validate_union( diff --git a/proposals/random/tools/witx/tests/anonymous.rs b/proposals/random/tools/witx/tests/anonymous.rs index 6bf11d883..2bff69960 100644 --- a/proposals/random/tools/witx/tests/anonymous.rs +++ b/proposals/random/tools/witx/tests/anonymous.rs @@ -1,30 +1,30 @@ use witx; -fn is_anonymous_struct_err(r: Result) -> bool { +fn is_anonymous_record_err(r: Result) -> bool { match r { - Err(witx::WitxError::Validation(witx::ValidationError::AnonymousStructure { .. })) => true, + Err(witx::WitxError::Validation(witx::ValidationError::AnonymousRecord { .. })) => true, _ => false, } } #[test] fn anonymous_types() { - let pointer_to_struct = witx::parse("(typename $a (@witx pointer (struct (field $b u8))))"); - assert!(is_anonymous_struct_err(pointer_to_struct)); + let pointer_to_record = witx::parse("(typename $a (@witx pointer (record (field $b u8))))"); + assert!(is_anonymous_record_err(pointer_to_record)); let pointer_to_union = witx::parse( "(typename $tag (enum u8 $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", ); - assert!(is_anonymous_struct_err(pointer_to_union)); + assert!(is_anonymous_record_err(pointer_to_union)); let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum u32 $b)))"); - assert!(is_anonymous_struct_err(pointer_to_enum)); + assert!(is_anonymous_record_err(pointer_to_enum)); let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags u32 $b)))"); - assert!(is_anonymous_struct_err(pointer_to_flags)); + assert!(is_anonymous_record_err(pointer_to_flags)); let pointer_to_handle = witx::parse("(typename $a (@witx pointer (handle)))"); - assert!(is_anonymous_struct_err(pointer_to_handle)); + assert!(is_anonymous_record_err(pointer_to_handle)); let pointer_to_builtin = witx::parse("(typename $a (@witx pointer u8))"); assert!(pointer_to_builtin.is_ok()); @@ -32,14 +32,14 @@ fn anonymous_types() { let pointer_to_pointer = witx::parse("(typename $a (@witx pointer (@witx const_pointer u8)))"); assert!(pointer_to_pointer.is_ok()); - let struct_in_struct = witx::parse("(typename $a (struct (field $b (struct (field $c u8)))))"); - assert!(is_anonymous_struct_err(struct_in_struct)); + let record_in_record = witx::parse("(typename $a (record (field $b (record (field $c u8)))))"); + assert!(is_anonymous_record_err(record_in_record)); - let union_in_struct = witx::parse( - "(typename $tag (enum u8 $c)) (typename $a (struct (field $b (union $tag (field $c u8)))))", + let union_in_record = witx::parse( + "(typename $tag (enum u8 $c)) (typename $a (record (field $b (union $tag (field $c u8)))))", ); - assert!(is_anonymous_struct_err(union_in_struct)); + assert!(is_anonymous_record_err(union_in_record)); - let pointer_in_struct = witx::parse("(typename $a (struct (field $b (@witx pointer u8))))"); - assert!(pointer_in_struct.is_ok()) + let pointer_in_record = witx::parse("(typename $a (record (field $b (@witx pointer u8))))"); + assert!(pointer_in_record.is_ok()) } diff --git a/proposals/random/tools/witx/tests/multimodule.rs b/proposals/random/tools/witx/tests/multimodule.rs index 47fb34755..a8e35609f 100644 --- a/proposals/random/tools/witx/tests/multimodule.rs +++ b/proposals/random/tools/witx/tests/multimodule.rs @@ -18,10 +18,10 @@ fn validate_multimodule() { // `b` is a struct with a single member of type `a` let type_b = doc.typename(&Id::new("b")).expect("type b exists"); match &*type_b.type_() { - Type::Struct(struct_) => { - assert_eq!(struct_.members.len(), 1); + Type::Record(record) => { + assert_eq!(record.members.len(), 1); assert_eq!( - struct_.members.get(0).unwrap().tref, + record.members.get(0).unwrap().tref, TypeRef::Name(type_a.clone()) ); } @@ -31,13 +31,13 @@ fn validate_multimodule() { // `c` is a struct with a two members of type `a` let type_c = doc.typename(&Id::new("c")).expect("type c exists"); match &*type_c.type_() { - Type::Struct(struct_) => { - assert_eq!(struct_.members.len(), 2); + Type::Record(record) => { + assert_eq!(record.members.len(), 2); assert_eq!( - struct_.members.get(0).unwrap().tref, + record.members.get(0).unwrap().tref, TypeRef::Name(type_a.clone()) ); - assert_eq!(struct_.members.get(1).unwrap().tref, TypeRef::Name(type_a)); + assert_eq!(record.members.get(1).unwrap().tref, TypeRef::Name(type_a)); } _ => panic!("c is a struct"), } diff --git a/proposals/random/tools/witx/tests/multimodule/type_b.witx b/proposals/random/tools/witx/tests/multimodule/type_b.witx index fe8315da9..fe169d3ec 100644 --- a/proposals/random/tools/witx/tests/multimodule/type_b.witx +++ b/proposals/random/tools/witx/tests/multimodule/type_b.witx @@ -1,2 +1,2 @@ (use "type_a.witx") -(typename $b (struct (field $member_a $a))) +(typename $b (record (field $member_a $a))) diff --git a/proposals/random/tools/witx/tests/multimodule/type_c.witx b/proposals/random/tools/witx/tests/multimodule/type_c.witx index 9f8819162..f42aac2d0 100644 --- a/proposals/random/tools/witx/tests/multimodule/type_c.witx +++ b/proposals/random/tools/witx/tests/multimodule/type_c.witx @@ -1,2 +1,2 @@ (use "type_a.witx") -(typename $c (struct (field $first_a $a) (field $second_a $a))) +(typename $c (record (field $first_a $a) (field $second_a $a))) From 1551a2454a3b1122cf01af7762ffac807b004957 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 07:24:15 -0800 Subject: [PATCH 0831/1772] Rename structs to records --- proposals/filesystem/phases/ephemeral/docs.md | 44 +++++++++---------- .../phases/ephemeral/witx/typenames.witx | 22 +++++----- .../filesystem/phases/old/snapshot_0/docs.md | 44 +++++++++---------- .../phases/old/snapshot_0/witx/typenames.witx | 22 +++++----- proposals/filesystem/phases/snapshot/docs.md | 44 +++++++++---------- .../phases/snapshot/witx/typenames.witx | 22 +++++----- proposals/filesystem/tools/witx/src/ast.rs | 10 ++--- .../filesystem/tools/witx/src/coretypes.rs | 2 +- .../filesystem/tools/witx/src/docs/ast.rs | 12 ++--- .../filesystem/tools/witx/src/docs/md.rs | 12 ++--- proposals/filesystem/tools/witx/src/layout.rs | 16 +++---- proposals/filesystem/tools/witx/src/lib.rs | 4 +- proposals/filesystem/tools/witx/src/parser.rs | 16 +++---- proposals/filesystem/tools/witx/src/render.rs | 6 +-- .../tools/witx/src/representation.rs | 8 ++-- .../filesystem/tools/witx/src/validate.rs | 26 +++++------ .../filesystem/tools/witx/tests/anonymous.rs | 30 ++++++------- .../tools/witx/tests/multimodule.rs | 14 +++--- .../tools/witx/tests/multimodule/type_b.witx | 2 +- .../tools/witx/tests/multimodule/type_c.witx | 2 +- 20 files changed, 179 insertions(+), 179 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 3f17fdacf..3bd147b43 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -408,14 +408,14 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Struct +## `iovec`: Record A region of memory for scatter/gather reads. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `Pointer` The address of the buffer to be filled. @@ -426,14 +426,14 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Struct +## `ciovec`: Record A region of memory for scatter/gather writes. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `ConstPointer` The address of the buffer to be written. @@ -540,14 +540,14 @@ The file refers to a symbolic link inode. - `fifo` The file descriptor or file refers to a FIFO. -## `dirent`: Struct +## `dirent`: Record A directory entry. Size: 24 Alignment: 8 -### Struct members +### Record members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. @@ -619,14 +619,14 @@ Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Struct +## `fdstat`: Record File descriptor attributes. Size: 24 Alignment: 8 -### Struct members +### Record members - `fs_filetype`: [`filetype`](#filetype) File type. @@ -748,14 +748,14 @@ indicates that the file is only accessible by the effective "user" that the WASI store uses to access the filesystem, and inaccessible to other "users". -## `filestat`: Struct +## `filestat`: Record File attributes. Size: 64 Alignment: 8 -### Struct members +### Record members - `dev`: [`device`](#device) Device ID of device containing the file. @@ -841,7 +841,7 @@ Alignment: 2 - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Struct +## `event_fd_readwrite`: Record The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -849,7 +849,7 @@ Size: 16 Alignment: 8 -### Struct members +### Record members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. @@ -880,14 +880,14 @@ Alignment: 8 - `clock` -## `event`: Struct +## `event`: Record An event that occurred. Size: 40 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). @@ -919,14 +919,14 @@ If set, treat the timestamp provided in provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Struct +## `subscription_clock`: Record The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 32 Alignment: 8 -### Struct members +### Record members - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. @@ -948,7 +948,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 24 -## `subscription_fd_readwrite`: Struct +## `subscription_fd_readwrite`: Record The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -956,7 +956,7 @@ Size: 4 Alignment: 4 -### Struct members +### Record members - `fd`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. @@ -982,14 +982,14 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Struct +## `subscription`: Record Subscription to an event. Size: 48 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). @@ -1066,14 +1066,14 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Struct +## `prestat_dir`: Record The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). Size: 4 Alignment: 4 -### Struct members +### Record members - `pr_name_len`: [`size`](#size) The length of the directory name for use with `fd_prestat_dir_name`. diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 723d43cb7..d4cc6274c 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -286,7 +286,7 @@ ;;; A region of memory for scatter/gather reads. (typename $iovec - (struct + (record ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. @@ -296,7 +296,7 @@ ;;; A region of memory for scatter/gather writes. (typename $ciovec - (struct + (record ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. @@ -362,7 +362,7 @@ ;;; A directory entry. (typename $dirent - (struct + (record ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. @@ -412,7 +412,7 @@ ;;; File descriptor attributes. (typename $fdstat - (struct + (record ;;; File type. (field $fs_filetype $filetype) ;;; File descriptor flags. @@ -501,7 +501,7 @@ ;;; File attributes. (typename $filestat - (struct + (record ;;; Device ID of device containing the file. (field $dev $device) ;;; File serial number. @@ -554,7 +554,7 @@ ;;; The contents of an `event` when type is `eventtype::fd_read` or ;;; `eventtype::fd_write`. (typename $event_fd_readwrite - (struct + (record ;;; The number of bytes available for reading or writing. (field $nbytes $filesize) ;;; The state of the file descriptor. @@ -573,7 +573,7 @@ ;;; An event that occurred. (typename $event - (struct + (record ;;; User-provided value that got attached to `subscription::userdata`. (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. @@ -598,7 +598,7 @@ ;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock - (struct + (record ;;; The clock against which to compare the timestamp. (field $id $clockid) ;;; The absolute or relative timestamp. @@ -614,7 +614,7 @@ ;;; The contents of a `subscription` when type is type is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite - (struct + (record ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $fd $fd) ) @@ -631,7 +631,7 @@ ;;; Subscription to an event. (typename $subscription - (struct + (record ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) @@ -685,7 +685,7 @@ ;;; The contents of a `prestat` when its type is `preopentype::dir`. (typename $prestat_dir - (struct + (record ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size) ) diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index 9307d9754..b56aa1f5e 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -400,14 +400,14 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Struct +## `iovec`: Record A region of memory for scatter/gather reads. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `Pointer` The address of the buffer to be filled. @@ -418,14 +418,14 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Struct +## `ciovec`: Record A region of memory for scatter/gather writes. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `ConstPointer` The address of the buffer to be written. @@ -525,14 +525,14 @@ The file descriptor or file refers to a byte-stream socket. - `symbolic_link` The file refers to a symbolic link inode. -## `dirent`: Struct +## `dirent`: Record A directory entry. Size: 24 Alignment: 8 -### Struct members +### Record members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. @@ -604,14 +604,14 @@ Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Struct +## `fdstat`: Record File descriptor attributes. Size: 24 Alignment: 8 -### Struct members +### Record members - `fs_filetype`: [`filetype`](#filetype) File type. @@ -699,14 +699,14 @@ Size: 4 Alignment: 4 -## `filestat`: Struct +## `filestat`: Record File attributes. Size: 56 Alignment: 8 -### Struct members +### Record members - `dev`: [`device`](#device) Device ID of device containing the file. @@ -787,7 +787,7 @@ Alignment: 2 - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Struct +## `event_fd_readwrite`: Record The contents of an [`event`](#event) for the [`eventtype::fd_read`](#eventtype.fd_read) and [`eventtype::fd_write`](#eventtype.fd_write) variants @@ -795,7 +795,7 @@ Size: 16 Alignment: 8 -### Struct members +### Record members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. @@ -806,14 +806,14 @@ The state of the file descriptor. Offset: 8 -## `event`: Struct +## `event`: Record An event that occurred. Size: 32 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). @@ -851,14 +851,14 @@ If set, treat the timestamp provided in provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Struct +## `subscription_clock`: Record The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 40 Alignment: 8 -### Struct members +### Record members - `identifier`: [`userdata`](#userdata) The user-defined unique identifier of the clock. @@ -885,7 +885,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 32 -## `subscription_fd_readwrite`: Struct +## `subscription_fd_readwrite`: Record The contents of a [`subscription`](#subscription) when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -893,7 +893,7 @@ Size: 4 Alignment: 4 -### Struct members +### Record members - `file_descriptor`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. @@ -919,14 +919,14 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Struct +## `subscription`: Record Subscription to an event. Size: 56 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). @@ -1135,14 +1135,14 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Struct +## `prestat_dir`: Record The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). Size: 4 Alignment: 4 -### Struct members +### Record members - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx index b6f672c3a..37a49f083 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx @@ -278,7 +278,7 @@ ;;; A region of memory for scatter/gather reads. (typename $iovec - (struct + (record ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. @@ -288,7 +288,7 @@ ;;; A region of memory for scatter/gather writes. (typename $ciovec - (struct + (record ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. @@ -347,7 +347,7 @@ ;;; A directory entry. (typename $dirent - (struct + (record ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. @@ -397,7 +397,7 @@ ;;; File descriptor attributes. (typename $fdstat - (struct + (record ;;; File type. (field $fs_filetype $filetype) ;;; File descriptor flags. @@ -455,7 +455,7 @@ ;;; File attributes. (typename $filestat - (struct + (record ;;; Device ID of device containing the file. (field $dev $device) ;;; File serial number. @@ -506,7 +506,7 @@ ;;; The contents of an `event` for the `eventtype::fd_read` and ;;; `eventtype::fd_write` variants (typename $event_fd_readwrite - (struct + (record ;;; The number of bytes available for reading or writing. (field $nbytes $filesize) ;;; The state of the file descriptor. @@ -516,7 +516,7 @@ ;;; An event that occurred. (typename $event - (struct + (record ;;; User-provided value that got attached to `subscription::userdata`. (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. @@ -544,7 +544,7 @@ ;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock - (struct + (record ;;; The user-defined unique identifier of the clock. (field $identifier $userdata) ;;; The clock against which to compare the timestamp. @@ -562,7 +562,7 @@ ;;; The contents of a `subscription` when the variant is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite - (struct + (record ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd) ) @@ -579,7 +579,7 @@ ;;; Subscription to an event. (typename $subscription - (struct + (record ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) @@ -732,7 +732,7 @@ ;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir - (struct + (record ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size) ) diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index 1a223448f..1cb642abe 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -400,14 +400,14 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Struct +## `iovec`: Record A region of memory for scatter/gather reads. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `Pointer` The address of the buffer to be filled. @@ -418,14 +418,14 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Struct +## `ciovec`: Record A region of memory for scatter/gather writes. Size: 8 Alignment: 4 -### Struct members +### Record members - `buf`: `ConstPointer` The address of the buffer to be written. @@ -527,14 +527,14 @@ The file descriptor or file refers to a byte-stream socket. - `symbolic_link` The file refers to a symbolic link inode. -## `dirent`: Struct +## `dirent`: Record A directory entry. Size: 24 Alignment: 8 -### Struct members +### Record members - `d_next`: [`dircookie`](#dircookie) The offset of the next directory entry stored in this directory. @@ -606,14 +606,14 @@ Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Struct +## `fdstat`: Record File descriptor attributes. Size: 24 Alignment: 8 -### Struct members +### Record members - `fs_filetype`: [`filetype`](#filetype) File type. @@ -701,14 +701,14 @@ Size: 8 Alignment: 8 -## `filestat`: Struct +## `filestat`: Record File attributes. Size: 64 Alignment: 8 -### Struct members +### Record members - `dev`: [`device`](#device) Device ID of device containing the file. @@ -789,7 +789,7 @@ Alignment: 2 - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Struct +## `event_fd_readwrite`: Record The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -797,7 +797,7 @@ Size: 16 Alignment: 8 -### Struct members +### Record members - `nbytes`: [`filesize`](#filesize) The number of bytes available for reading or writing. @@ -808,14 +808,14 @@ The state of the file descriptor. Offset: 8 -## `event`: Struct +## `event`: Record An event that occurred. Size: 32 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). @@ -853,14 +853,14 @@ If set, treat the timestamp provided in provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Struct +## `subscription_clock`: Record The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 32 Alignment: 8 -### Struct members +### Record members - `id`: [`clockid`](#clockid) The clock against which to compare the timestamp. @@ -882,7 +882,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 24 -## `subscription_fd_readwrite`: Struct +## `subscription_fd_readwrite`: Record The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -890,7 +890,7 @@ Size: 4 Alignment: 4 -### Struct members +### Record members - `file_descriptor`: [`fd`](#fd) The file descriptor on which to wait for it to become ready for reading or writing. @@ -916,14 +916,14 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Struct +## `subscription`: Record Subscription to an event. Size: 48 Alignment: 8 -### Struct members +### Record members - `userdata`: [`userdata`](#userdata) User-provided value that is attached to the subscription in the implementation and returned through [`event::userdata`](#event.userdata). @@ -1132,14 +1132,14 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Struct +## `prestat_dir`: Record The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). Size: 4 Alignment: 4 -### Struct members +### Record members - `pr_name_len`: [`size`](#size) The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx index 5e1049553..b0ccece64 100644 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -278,7 +278,7 @@ ;;; A region of memory for scatter/gather reads. (typename $iovec - (struct + (record ;;; The address of the buffer to be filled. (field $buf (@witx pointer u8)) ;;; The length of the buffer to be filled. @@ -288,7 +288,7 @@ ;;; A region of memory for scatter/gather writes. (typename $ciovec - (struct + (record ;;; The address of the buffer to be written. (field $buf (@witx const_pointer u8)) ;;; The length of the buffer to be written. @@ -349,7 +349,7 @@ ;;; A directory entry. (typename $dirent - (struct + (record ;;; The offset of the next directory entry stored in this directory. (field $d_next $dircookie) ;;; The serial number of the file referred to by this directory entry. @@ -399,7 +399,7 @@ ;;; File descriptor attributes. (typename $fdstat - (struct + (record ;;; File type. (field $fs_filetype $filetype) ;;; File descriptor flags. @@ -457,7 +457,7 @@ ;;; File attributes. (typename $filestat - (struct + (record ;;; Device ID of device containing the file. (field $dev $device) ;;; File serial number. @@ -508,7 +508,7 @@ ;;; The contents of an `event` when type is `eventtype::fd_read` or ;;; `eventtype::fd_write`. (typename $event_fd_readwrite - (struct + (record ;;; The number of bytes available for reading or writing. (field $nbytes $filesize) ;;; The state of the file descriptor. @@ -518,7 +518,7 @@ ;;; An event that occurred. (typename $event - (struct + (record ;;; User-provided value that got attached to `subscription::userdata`. (field $userdata $userdata) ;;; If non-zero, an error that occurred while processing the subscription request. @@ -546,7 +546,7 @@ ;;; The contents of a `subscription` when type is `eventtype::clock`. (typename $subscription_clock - (struct + (record ;;; The clock against which to compare the timestamp. (field $id $clockid) ;;; The absolute or relative timestamp. @@ -562,7 +562,7 @@ ;;; The contents of a `subscription` when type is type is ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $subscription_fd_readwrite - (struct + (record ;;; The file descriptor on which to wait for it to become ready for reading or writing. (field $file_descriptor $fd) ) @@ -579,7 +579,7 @@ ;;; Subscription to an event. (typename $subscription - (struct + (record ;;; User-provided value that is attached to the subscription in the ;;; implementation and returned through `event::userdata`. (field $userdata $userdata) @@ -732,7 +732,7 @@ ;;; The contents of a $prestat when type is `preopentype::dir`. (typename $prestat_dir - (struct + (record ;;; The length of the directory name for use with `fd_prestat_dir_name`. (field $pr_name_len $size) ) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index fcf6a2e94..65f354c7e 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -180,7 +180,7 @@ pub enum Type { Enum(EnumDatatype), Int(IntDatatype), Flags(FlagsDatatype), - Struct(StructDatatype), + Record(RecordDatatype), Union(UnionDatatype), Handle(HandleDatatype), List(TypeRef), @@ -196,7 +196,7 @@ impl Type { Enum(_) => "enum", Int(_) => "int", Flags(_) => "flags", - Struct(_) => "struct", + Record(_) => "record", Union(_) => "union", Handle(_) => "handle", List(_) => "list", @@ -270,12 +270,12 @@ pub struct FlagsMember { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct StructDatatype { - pub members: Vec, +pub struct RecordDatatype { + pub members: Vec, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct StructMember { +pub struct RecordMember { pub name: Id, pub tref: TypeRef, pub docs: String, diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index 7865bd8fb..733535318 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -53,7 +53,7 @@ impl Type { Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), - Type::Struct { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), } } diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index 0eb2933fe..59c246d23 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -6,7 +6,7 @@ use crate::{ ast::{ BuiltinType, Document, EnumDatatype, FlagsDatatype, HandleDatatype, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, Module, ModuleImport, ModuleImportVariant, NamedType, - StructDatatype, Type, TypeRef, UnionDatatype, + RecordDatatype, Type, TypeRef, UnionDatatype, }, layout::Layout, polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, @@ -73,7 +73,7 @@ impl ToMarkdown for Type { Self::Enum(a) => a.generate(node.clone()), Self::Int(a) => a.generate(node.clone()), Self::Flags(a) => a.generate(node.clone()), - Self::Struct(a) => a.generate(node.clone()), + Self::Record(a) => a.generate(node.clone()), Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), Self::List(a) => { @@ -175,10 +175,10 @@ impl ToMarkdown for FlagsDatatype { } } -impl ToMarkdown for StructDatatype { +impl ToMarkdown for RecordDatatype { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Struct members")); + node.new_child(MdSection::new(heading, "Record members")); for member_layout in &self.member_layout() { let member = member_layout.member; @@ -198,7 +198,7 @@ impl ToMarkdown for StructDatatype { member.tref.generate(n.clone()); } - node.content_ref_mut::().r#type = Some(MdType::Struct); + node.content_ref_mut::().r#type = Some(MdType::Record); } } @@ -385,7 +385,7 @@ impl TypeRef { Type::Enum { .. } | Type::Int { .. } | Type::Flags { .. } - | Type::Struct { .. } + | Type::Record { .. } | Type::Union { .. } | Type::Handle { .. } => { unimplemented!("type_name of anonymous compound datatypes") diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index 2373f1ed5..65969b8d2 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -163,7 +163,7 @@ impl fmt::Display for MdNodeRef { } } -/// Struct representing the Markdown tree's root. +/// Record representing the Markdown tree's root. /// /// Doesn't render to anything. #[derive(Debug, Default)] @@ -237,7 +237,7 @@ impl fmt::Display for MdHeading { } } -/// Struct representing a Markdown section without any `docs`, consisting +/// Record representing a Markdown section without any `docs`, consisting /// of only a `header` (e.g., "###"), maybe some referencable `id` (i.e., /// a Markdown link), and some `title`. /// @@ -298,7 +298,7 @@ impl fmt::Display for MdSection { } } -/// Struct representing a Markdown section representing any `NamedType` element +/// Record representing a Markdown section representing any `NamedType` element /// of the AST. /// Consists of: /// * `header`, e.g., "###", or "-" for Enum variants, etc., @@ -346,7 +346,7 @@ pub(super) enum MdType { Enum { repr: String }, Int { repr: String }, Flags { repr: String }, - Struct, + Record, Union, List { r#type: String }, Pointer { r#type: String }, @@ -362,7 +362,7 @@ impl fmt::Display for MdType { Self::Enum { repr } => f.write_fmt(format_args!(": Enum(`{}`)", repr))?, Self::Int { repr } => f.write_fmt(format_args!(": Int(`{}`)", repr))?, Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, - Self::Struct => f.write_fmt(format_args!(": Struct"))?, + Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, Self::List { r#type } => f.write_fmt(format_args!(": `List<{}>`", r#type))?, Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, @@ -419,7 +419,7 @@ impl fmt::Display for MdNamedType { } } -/// Struct representing a Markdown section representing any `InterfaceFunc` element +/// Record representing a Markdown section representing any `InterfaceFunc` element /// of the AST. /// Consists of: /// * `header`, e.g., "###", diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index 6012d38d8..d29f192b8 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -56,7 +56,7 @@ impl Type { Type::Enum(e) => e.repr.mem_size_align(), Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), - Type::Struct(s) => s.layout(cache), + Type::Record(s) => s.layout(cache), Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => BuiltinType::String.mem_size_align(), @@ -84,23 +84,23 @@ impl Layout for IntRepr { } } -pub struct StructMemberLayout<'a> { - pub member: &'a StructMember, +pub struct RecordMemberLayout<'a> { + pub member: &'a RecordMember, pub offset: usize, } -impl StructDatatype { - pub fn member_layout(&self) -> Vec { +impl RecordDatatype { + pub fn member_layout(&self) -> Vec { self.member_layout_(&mut HashMap::new()) } - fn member_layout_(&self, cache: &mut HashMap) -> Vec { + fn member_layout_(&self, cache: &mut HashMap) -> Vec { let mut members = Vec::new(); let mut offset = 0; for m in self.members.iter() { let sa = m.tref.layout(cache); offset = align_to(offset, sa.align); - members.push(StructMemberLayout { member: m, offset }); + members.push(RecordMemberLayout { member: m, offset }); offset += sa.size; } members @@ -120,7 +120,7 @@ impl StructDatatype { } } -impl Layout for StructDatatype { +impl Layout for RecordDatatype { fn mem_size_align(&self) -> SizeAlign { let mut cache = HashMap::new(); self.layout(&mut cache) diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index c612e601d..d320e15d6 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -27,13 +27,13 @@ pub use ast::{ BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, - ModuleImport, ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypeRef, + ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypeRef, UnionDatatype, UnionVariant, }; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; -pub use layout::{Layout, SizeAlign, StructMemberLayout, UnionLayout}; +pub use layout::{Layout, RecordMemberLayout, SizeAlign, UnionLayout}; pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 964a5ba48..aedee808f 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -30,9 +30,9 @@ mod kw { wast::custom_keyword!(list); wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); + wast::custom_keyword!(record); wast::custom_keyword!(r#const = "const"); wast::custom_keyword!(r#enum = "enum"); - wast::custom_keyword!(r#struct = "struct"); wast::custom_keyword!(r#union = "union"); wast::custom_keyword!(r#use = "use"); wast::custom_keyword!(s16); @@ -272,7 +272,7 @@ pub enum TypedefSyntax<'a> { Enum(EnumSyntax<'a>), Int(IntSyntax<'a>), Flags(FlagsSyntax<'a>), - Struct(StructSyntax<'a>), + Record(RecordSyntax<'a>), Union(UnionSyntax<'a>), Handle(HandleSyntax), List(Box>), @@ -298,8 +298,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Int(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Flags(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Struct(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Record(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Union(parser.parse()?)) } else if l.peek::() { @@ -406,19 +406,19 @@ impl<'a> Parse<'a> for FlagsSyntax<'a> { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct StructSyntax<'a> { +pub struct RecordSyntax<'a> { pub fields: Vec>>, } -impl<'a> Parse<'a> for StructSyntax<'a> { +impl<'a> Parse<'a> for RecordSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; + parser.parse::()?; let mut fields = Vec::new(); fields.push(parser.parse()?); while !parser.is_empty() { fields.push(parser.parse()?); } - Ok(StructSyntax { fields }) + Ok(RecordSyntax { fields }) } } diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 11778fa15..88d7d5dce 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -119,7 +119,7 @@ impl Type { Type::Enum(a) => a.to_sexpr(), Type::Int(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), - Type::Struct(a) => a.to_sexpr(), + Type::Record(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), Type::Handle(a) => a.to_sexpr(), Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), @@ -183,9 +183,9 @@ impl FlagsDatatype { } } -impl StructDatatype { +impl RecordDatatype { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("struct")]; + let header = vec![SExpr::word("record")]; let members = self .members .iter() diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs index f541e9fc1..2d03797be 100644 --- a/proposals/filesystem/tools/witx/src/representation.rs +++ b/proposals/filesystem/tools/witx/src/representation.rs @@ -1,5 +1,5 @@ use crate::{ - BuiltinType, EnumDatatype, FlagsDatatype, IntRepr, NamedType, StructDatatype, Type, TypeRef, + BuiltinType, EnumDatatype, FlagsDatatype, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, }; @@ -117,9 +117,9 @@ impl Representable for FlagsDatatype { } } -impl Representable for StructDatatype { +impl Representable for RecordDatatype { fn representable(&self, by: &Self) -> RepEquality { - // Structs must have exact structural equality - same members, must + // Records must have exact structural equality - same members, must // be Eq, in the same order. // We would require require a more expressive RepEquality enum to describe which members // might be supersets. @@ -205,7 +205,7 @@ impl Representable for Type { match (&self, &by) { (Type::Enum(s), Type::Enum(b)) => s.representable(b), (Type::Flags(s), Type::Flags(b)) => s.representable(b), - (Type::Struct(s), Type::Struct(b)) => s.representable(b), + (Type::Record(s), Type::Record(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural (Type::List(s), Type::List(b)) => s.representable(b), diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 211438819..adfcb757e 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -2,13 +2,13 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, - ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, StructSyntax, TypedefSyntax, UnionSyntax, + ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, VariantSyntax, }, BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, NamedType, StructDatatype, StructMember, Type, TypePassedBy, TypeRef, + ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, }; use std::collections::{hash_map, HashMap}; @@ -43,7 +43,7 @@ pub enum ValidationError { #[error("First result type must be pass-by-value")] InvalidFirstResultType { location: Location }, #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] - AnonymousStructure { location: Location }, + AnonymousRecord { location: Location }, #[error("Invalid union field `{name}`: {reason}")] InvalidUnionField { name: String, @@ -61,7 +61,7 @@ impl ValidationError { | Recursive { location, .. } | InvalidRepr { location, .. } | InvalidFirstResultType { location, .. } - | AnonymousStructure { location, .. } + | AnonymousRecord { location, .. } | InvalidUnionField { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } @@ -239,12 +239,12 @@ impl DocValidationScope<'_> { TypedefSyntax::Enum { .. } | TypedefSyntax::Int { .. } | TypedefSyntax::Flags { .. } - | TypedefSyntax::Struct { .. } + | TypedefSyntax::Record { .. } | TypedefSyntax::Union { .. } | TypedefSyntax::Handle { .. } if !named => { - Err(ValidationError::AnonymousStructure { + Err(ValidationError::AnonymousRecord { location: self.location(span), }) } @@ -252,7 +252,7 @@ impl DocValidationScope<'_> { TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), TypedefSyntax::Int(syntax) => Type::Int(self.validate_int(&syntax, span)?), TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), - TypedefSyntax::Struct(syntax) => Type::Struct(self.validate_struct(&syntax, span)?), + TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), TypedefSyntax::List(syntax) => { @@ -332,11 +332,11 @@ impl DocValidationScope<'_> { Ok(FlagsDatatype { repr, flags }) } - fn validate_struct( + fn validate_record( &self, - syntax: &StructSyntax, + syntax: &RecordSyntax, _span: wast::Span, - ) -> Result { + ) -> Result { let mut member_scope = IdentValidation::new(); let members = syntax .fields @@ -346,11 +346,11 @@ impl DocValidationScope<'_> { .introduce(f.item.name.name(), self.location(f.item.name.span()))?; let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; let docs = f.comments.docs(); - Ok(StructMember { name, tref, docs }) + Ok(RecordMember { name, tref, docs }) }) - .collect::, _>>()?; + .collect::, _>>()?; - Ok(StructDatatype { members }) + Ok(RecordDatatype { members }) } fn validate_union( diff --git a/proposals/filesystem/tools/witx/tests/anonymous.rs b/proposals/filesystem/tools/witx/tests/anonymous.rs index 6bf11d883..2bff69960 100644 --- a/proposals/filesystem/tools/witx/tests/anonymous.rs +++ b/proposals/filesystem/tools/witx/tests/anonymous.rs @@ -1,30 +1,30 @@ use witx; -fn is_anonymous_struct_err(r: Result) -> bool { +fn is_anonymous_record_err(r: Result) -> bool { match r { - Err(witx::WitxError::Validation(witx::ValidationError::AnonymousStructure { .. })) => true, + Err(witx::WitxError::Validation(witx::ValidationError::AnonymousRecord { .. })) => true, _ => false, } } #[test] fn anonymous_types() { - let pointer_to_struct = witx::parse("(typename $a (@witx pointer (struct (field $b u8))))"); - assert!(is_anonymous_struct_err(pointer_to_struct)); + let pointer_to_record = witx::parse("(typename $a (@witx pointer (record (field $b u8))))"); + assert!(is_anonymous_record_err(pointer_to_record)); let pointer_to_union = witx::parse( "(typename $tag (enum u8 $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", ); - assert!(is_anonymous_struct_err(pointer_to_union)); + assert!(is_anonymous_record_err(pointer_to_union)); let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum u32 $b)))"); - assert!(is_anonymous_struct_err(pointer_to_enum)); + assert!(is_anonymous_record_err(pointer_to_enum)); let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags u32 $b)))"); - assert!(is_anonymous_struct_err(pointer_to_flags)); + assert!(is_anonymous_record_err(pointer_to_flags)); let pointer_to_handle = witx::parse("(typename $a (@witx pointer (handle)))"); - assert!(is_anonymous_struct_err(pointer_to_handle)); + assert!(is_anonymous_record_err(pointer_to_handle)); let pointer_to_builtin = witx::parse("(typename $a (@witx pointer u8))"); assert!(pointer_to_builtin.is_ok()); @@ -32,14 +32,14 @@ fn anonymous_types() { let pointer_to_pointer = witx::parse("(typename $a (@witx pointer (@witx const_pointer u8)))"); assert!(pointer_to_pointer.is_ok()); - let struct_in_struct = witx::parse("(typename $a (struct (field $b (struct (field $c u8)))))"); - assert!(is_anonymous_struct_err(struct_in_struct)); + let record_in_record = witx::parse("(typename $a (record (field $b (record (field $c u8)))))"); + assert!(is_anonymous_record_err(record_in_record)); - let union_in_struct = witx::parse( - "(typename $tag (enum u8 $c)) (typename $a (struct (field $b (union $tag (field $c u8)))))", + let union_in_record = witx::parse( + "(typename $tag (enum u8 $c)) (typename $a (record (field $b (union $tag (field $c u8)))))", ); - assert!(is_anonymous_struct_err(union_in_struct)); + assert!(is_anonymous_record_err(union_in_record)); - let pointer_in_struct = witx::parse("(typename $a (struct (field $b (@witx pointer u8))))"); - assert!(pointer_in_struct.is_ok()) + let pointer_in_record = witx::parse("(typename $a (record (field $b (@witx pointer u8))))"); + assert!(pointer_in_record.is_ok()) } diff --git a/proposals/filesystem/tools/witx/tests/multimodule.rs b/proposals/filesystem/tools/witx/tests/multimodule.rs index 47fb34755..a8e35609f 100644 --- a/proposals/filesystem/tools/witx/tests/multimodule.rs +++ b/proposals/filesystem/tools/witx/tests/multimodule.rs @@ -18,10 +18,10 @@ fn validate_multimodule() { // `b` is a struct with a single member of type `a` let type_b = doc.typename(&Id::new("b")).expect("type b exists"); match &*type_b.type_() { - Type::Struct(struct_) => { - assert_eq!(struct_.members.len(), 1); + Type::Record(record) => { + assert_eq!(record.members.len(), 1); assert_eq!( - struct_.members.get(0).unwrap().tref, + record.members.get(0).unwrap().tref, TypeRef::Name(type_a.clone()) ); } @@ -31,13 +31,13 @@ fn validate_multimodule() { // `c` is a struct with a two members of type `a` let type_c = doc.typename(&Id::new("c")).expect("type c exists"); match &*type_c.type_() { - Type::Struct(struct_) => { - assert_eq!(struct_.members.len(), 2); + Type::Record(record) => { + assert_eq!(record.members.len(), 2); assert_eq!( - struct_.members.get(0).unwrap().tref, + record.members.get(0).unwrap().tref, TypeRef::Name(type_a.clone()) ); - assert_eq!(struct_.members.get(1).unwrap().tref, TypeRef::Name(type_a)); + assert_eq!(record.members.get(1).unwrap().tref, TypeRef::Name(type_a)); } _ => panic!("c is a struct"), } diff --git a/proposals/filesystem/tools/witx/tests/multimodule/type_b.witx b/proposals/filesystem/tools/witx/tests/multimodule/type_b.witx index fe8315da9..fe169d3ec 100644 --- a/proposals/filesystem/tools/witx/tests/multimodule/type_b.witx +++ b/proposals/filesystem/tools/witx/tests/multimodule/type_b.witx @@ -1,2 +1,2 @@ (use "type_a.witx") -(typename $b (struct (field $member_a $a))) +(typename $b (record (field $member_a $a))) diff --git a/proposals/filesystem/tools/witx/tests/multimodule/type_c.witx b/proposals/filesystem/tools/witx/tests/multimodule/type_c.witx index 9f8819162..f42aac2d0 100644 --- a/proposals/filesystem/tools/witx/tests/multimodule/type_c.witx +++ b/proposals/filesystem/tools/witx/tests/multimodule/type_c.witx @@ -1,2 +1,2 @@ (use "type_a.witx") -(typename $c (struct (field $first_a $a) (field $second_a $a))) +(typename $c (record (field $first_a $a) (field $second_a $a))) From 67196d240f4fb7b53065324795e5b698b6445a76 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 07:41:30 -0800 Subject: [PATCH 0832/1772] Add initial support for `variant` type --- proposals/clocks/tools/witx/src/ast.rs | 14 +++++ proposals/clocks/tools/witx/src/coretypes.rs | 4 +- proposals/clocks/tools/witx/src/docs/ast.rs | 35 ++++++++++-- proposals/clocks/tools/witx/src/docs/md.rs | 2 + proposals/clocks/tools/witx/src/layout.rs | 60 ++++++++++++++------ proposals/clocks/tools/witx/src/lib.rs | 8 +-- proposals/clocks/tools/witx/src/render.rs | 19 +++++++ 7 files changed, 111 insertions(+), 31 deletions(-) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 65f354c7e..602db8219 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -181,6 +181,7 @@ pub enum Type { Int(IntDatatype), Flags(FlagsDatatype), Record(RecordDatatype), + Variant(Variant), Union(UnionDatatype), Handle(HandleDatatype), List(TypeRef), @@ -197,6 +198,7 @@ impl Type { Int(_) => "int", Flags(_) => "flags", Record(_) => "record", + Variant(_) => "variant", Union(_) => "union", Handle(_) => "handle", List(_) => "list", @@ -281,6 +283,18 @@ pub struct RecordMember { pub docs: String, } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Variant { + pub cases: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Case { + pub name: Id, + pub tref: Option, + pub docs: String, +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionDatatype { pub tag: Rc, diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index 733535318..d226ad691 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -53,7 +53,9 @@ impl Type { Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), - Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } => { + TypePassedBy::Pointer + } Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), } } diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index 59c246d23..fbf92080b 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -3,11 +3,7 @@ use super::{ Documentation, }; use crate::{ - ast::{ - BuiltinType, Document, EnumDatatype, FlagsDatatype, HandleDatatype, IntDatatype, IntRepr, - InterfaceFunc, InterfaceFuncParam, Module, ModuleImport, ModuleImportVariant, NamedType, - RecordDatatype, Type, TypeRef, UnionDatatype, - }, + ast::*, layout::Layout, polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, RepEquality, @@ -74,6 +70,7 @@ impl ToMarkdown for Type { Self::Int(a) => a.generate(node.clone()), Self::Flags(a) => a.generate(node.clone()), Self::Record(a) => a.generate(node.clone()), + Self::Variant(a) => a.generate(node.clone()), Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), Self::List(a) => { @@ -202,6 +199,33 @@ impl ToMarkdown for RecordDatatype { } } +impl ToMarkdown for Variant { + fn generate(&self, node: MdNodeRef) { + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Variant cases")); + + for case in self.cases.iter() { + let name = case.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let n = node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + format!("{}\n", &case.docs).as_str(), + )); + if let Some(ty) = &case.tref { + ty.generate(n.clone()); + } + } + + node.content_ref_mut::().r#type = Some(MdType::Variant); + } +} + impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { // Sizes & Alignments @@ -386,6 +410,7 @@ impl TypeRef { | Type::Int { .. } | Type::Flags { .. } | Type::Record { .. } + | Type::Variant { .. } | Type::Union { .. } | Type::Handle { .. } => { unimplemented!("type_name of anonymous compound datatypes") diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index 65969b8d2..f40200e8a 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -347,6 +347,7 @@ pub(super) enum MdType { Int { repr: String }, Flags { repr: String }, Record, + Variant, Union, List { r#type: String }, Pointer { r#type: String }, @@ -363,6 +364,7 @@ impl fmt::Display for MdType { Self::Int { repr } => f.write_fmt(format_args!(": Int(`{}`)", repr))?, Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Record => f.write_fmt(format_args!(": Record"))?, + Self::Variant => f.write_fmt(format_args!(": Variant"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, Self::List { r#type } => f.write_fmt(format_args!(": `List<{}>`", r#type))?, Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index d29f192b8..b918e0d6b 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -7,6 +7,17 @@ pub struct SizeAlign { pub align: usize, } +impl SizeAlign { + fn zero() -> SizeAlign { + SizeAlign { size: 0, align: 0 } + } + fn append_field(&mut self, other: &SizeAlign) { + self.align = self.align.max(other.align); + self.size = align_to(self.size, other.align); + self.size += other.size; + } +} + pub trait Layout { fn mem_size_align(&self) -> SizeAlign; fn mem_size(&self) -> usize { @@ -57,6 +68,7 @@ impl Type { Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), Type::Record(s) => s.layout(cache), + Type::Variant(s) => s.mem_size_align(), Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => BuiltinType::String.mem_size_align(), @@ -91,32 +103,29 @@ pub struct RecordMemberLayout<'a> { impl RecordDatatype { pub fn member_layout(&self) -> Vec { - self.member_layout_(&mut HashMap::new()) + self.member_layout_(&mut HashMap::new()).1 } - fn member_layout_(&self, cache: &mut HashMap) -> Vec { + fn member_layout_( + &self, + cache: &mut HashMap, + ) -> (SizeAlign, Vec) { let mut members = Vec::new(); - let mut offset = 0; + let mut sa = SizeAlign::zero(); for m in self.members.iter() { - let sa = m.tref.layout(cache); - offset = align_to(offset, sa.align); - members.push(RecordMemberLayout { member: m, offset }); - offset += sa.size; + let member = m.tref.layout(cache); + sa.append_field(&member); + members.push(RecordMemberLayout { + member: m, + offset: sa.size - member.size, + }); } - members + sa.size = align_to(sa.size, sa.align); + (sa, members) } fn layout(&self, cache: &mut HashMap) -> SizeAlign { - let members = self.member_layout_(cache); - let align = members - .iter() - .map(|m| m.member.tref.layout(cache).align) - .max() - .expect("nonzero struct members"); - let last = members.last().expect("nonzero struct members"); - let size = last.offset + last.member.tref.layout(cache).size; - let size = align_to(size, align); - SizeAlign { size, align } + self.member_layout_(cache).0 } } @@ -127,6 +136,21 @@ impl Layout for RecordDatatype { } } +impl Layout for Variant { + fn mem_size_align(&self) -> SizeAlign { + let mut max = SizeAlign { size: 0, align: 0 }; + for case in self.cases.iter() { + let mut size = BuiltinType::S32.mem_size_align(); + if let Some(payload) = &case.tref { + size.append_field(&payload.mem_size_align()); + } + max.size = max.size.max(size.size); + max.align = max.align.max(size.align); + } + max + } +} + /// If the next free byte in the struct is `offs`, and the next /// element has alignment `alignment`, determine the offset at /// which to place that element. diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index d320e15d6..72774c16c 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -23,13 +23,7 @@ mod toplevel; /// Validate declarations into ast mod validate; -pub use ast::{ - BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, - FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, - InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, - ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypeRef, - UnionDatatype, UnionVariant, -}; +pub use ast::*; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 88d7d5dce..412aaf73b 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -120,6 +120,7 @@ impl Type { Type::Int(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), Type::Record(a) => a.to_sexpr(), + Type::Variant(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), Type::Handle(a) => a.to_sexpr(), Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), @@ -204,6 +205,24 @@ impl RecordDatatype { } } +impl Variant { + pub fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("variant")]; + let cases = self + .cases + .iter() + .map(|m| { + let mut list = vec![SExpr::word("case"), m.name.to_sexpr()]; + if let Some(ty) = &m.tref { + list.push(ty.to_sexpr()); + } + SExpr::docs(&m.docs, SExpr::Vec(list)) + }) + .collect::>(); + SExpr::Vec([header, cases].concat()) + } +} + impl UnionDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("union"), self.tag.name.to_sexpr()]; From 01faebba9b6f17b7fcbef5f566c9c40b4ac8fb79 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 07:41:30 -0800 Subject: [PATCH 0833/1772] Add initial support for `variant` type --- proposals/random/tools/witx/src/ast.rs | 14 +++++ proposals/random/tools/witx/src/coretypes.rs | 4 +- proposals/random/tools/witx/src/docs/ast.rs | 35 ++++++++++-- proposals/random/tools/witx/src/docs/md.rs | 2 + proposals/random/tools/witx/src/layout.rs | 60 ++++++++++++++------ proposals/random/tools/witx/src/lib.rs | 8 +-- proposals/random/tools/witx/src/render.rs | 19 +++++++ 7 files changed, 111 insertions(+), 31 deletions(-) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 65f354c7e..602db8219 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -181,6 +181,7 @@ pub enum Type { Int(IntDatatype), Flags(FlagsDatatype), Record(RecordDatatype), + Variant(Variant), Union(UnionDatatype), Handle(HandleDatatype), List(TypeRef), @@ -197,6 +198,7 @@ impl Type { Int(_) => "int", Flags(_) => "flags", Record(_) => "record", + Variant(_) => "variant", Union(_) => "union", Handle(_) => "handle", List(_) => "list", @@ -281,6 +283,18 @@ pub struct RecordMember { pub docs: String, } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Variant { + pub cases: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Case { + pub name: Id, + pub tref: Option, + pub docs: String, +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionDatatype { pub tag: Rc, diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index 733535318..d226ad691 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -53,7 +53,9 @@ impl Type { Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), - Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } => { + TypePassedBy::Pointer + } Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), } } diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index 59c246d23..fbf92080b 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -3,11 +3,7 @@ use super::{ Documentation, }; use crate::{ - ast::{ - BuiltinType, Document, EnumDatatype, FlagsDatatype, HandleDatatype, IntDatatype, IntRepr, - InterfaceFunc, InterfaceFuncParam, Module, ModuleImport, ModuleImportVariant, NamedType, - RecordDatatype, Type, TypeRef, UnionDatatype, - }, + ast::*, layout::Layout, polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, RepEquality, @@ -74,6 +70,7 @@ impl ToMarkdown for Type { Self::Int(a) => a.generate(node.clone()), Self::Flags(a) => a.generate(node.clone()), Self::Record(a) => a.generate(node.clone()), + Self::Variant(a) => a.generate(node.clone()), Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), Self::List(a) => { @@ -202,6 +199,33 @@ impl ToMarkdown for RecordDatatype { } } +impl ToMarkdown for Variant { + fn generate(&self, node: MdNodeRef) { + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Variant cases")); + + for case in self.cases.iter() { + let name = case.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let n = node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + format!("{}\n", &case.docs).as_str(), + )); + if let Some(ty) = &case.tref { + ty.generate(n.clone()); + } + } + + node.content_ref_mut::().r#type = Some(MdType::Variant); + } +} + impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { // Sizes & Alignments @@ -386,6 +410,7 @@ impl TypeRef { | Type::Int { .. } | Type::Flags { .. } | Type::Record { .. } + | Type::Variant { .. } | Type::Union { .. } | Type::Handle { .. } => { unimplemented!("type_name of anonymous compound datatypes") diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index 65969b8d2..f40200e8a 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -347,6 +347,7 @@ pub(super) enum MdType { Int { repr: String }, Flags { repr: String }, Record, + Variant, Union, List { r#type: String }, Pointer { r#type: String }, @@ -363,6 +364,7 @@ impl fmt::Display for MdType { Self::Int { repr } => f.write_fmt(format_args!(": Int(`{}`)", repr))?, Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Record => f.write_fmt(format_args!(": Record"))?, + Self::Variant => f.write_fmt(format_args!(": Variant"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, Self::List { r#type } => f.write_fmt(format_args!(": `List<{}>`", r#type))?, Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index d29f192b8..b918e0d6b 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -7,6 +7,17 @@ pub struct SizeAlign { pub align: usize, } +impl SizeAlign { + fn zero() -> SizeAlign { + SizeAlign { size: 0, align: 0 } + } + fn append_field(&mut self, other: &SizeAlign) { + self.align = self.align.max(other.align); + self.size = align_to(self.size, other.align); + self.size += other.size; + } +} + pub trait Layout { fn mem_size_align(&self) -> SizeAlign; fn mem_size(&self) -> usize { @@ -57,6 +68,7 @@ impl Type { Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), Type::Record(s) => s.layout(cache), + Type::Variant(s) => s.mem_size_align(), Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => BuiltinType::String.mem_size_align(), @@ -91,32 +103,29 @@ pub struct RecordMemberLayout<'a> { impl RecordDatatype { pub fn member_layout(&self) -> Vec { - self.member_layout_(&mut HashMap::new()) + self.member_layout_(&mut HashMap::new()).1 } - fn member_layout_(&self, cache: &mut HashMap) -> Vec { + fn member_layout_( + &self, + cache: &mut HashMap, + ) -> (SizeAlign, Vec) { let mut members = Vec::new(); - let mut offset = 0; + let mut sa = SizeAlign::zero(); for m in self.members.iter() { - let sa = m.tref.layout(cache); - offset = align_to(offset, sa.align); - members.push(RecordMemberLayout { member: m, offset }); - offset += sa.size; + let member = m.tref.layout(cache); + sa.append_field(&member); + members.push(RecordMemberLayout { + member: m, + offset: sa.size - member.size, + }); } - members + sa.size = align_to(sa.size, sa.align); + (sa, members) } fn layout(&self, cache: &mut HashMap) -> SizeAlign { - let members = self.member_layout_(cache); - let align = members - .iter() - .map(|m| m.member.tref.layout(cache).align) - .max() - .expect("nonzero struct members"); - let last = members.last().expect("nonzero struct members"); - let size = last.offset + last.member.tref.layout(cache).size; - let size = align_to(size, align); - SizeAlign { size, align } + self.member_layout_(cache).0 } } @@ -127,6 +136,21 @@ impl Layout for RecordDatatype { } } +impl Layout for Variant { + fn mem_size_align(&self) -> SizeAlign { + let mut max = SizeAlign { size: 0, align: 0 }; + for case in self.cases.iter() { + let mut size = BuiltinType::S32.mem_size_align(); + if let Some(payload) = &case.tref { + size.append_field(&payload.mem_size_align()); + } + max.size = max.size.max(size.size); + max.align = max.align.max(size.align); + } + max + } +} + /// If the next free byte in the struct is `offs`, and the next /// element has alignment `alignment`, determine the offset at /// which to place that element. diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index d320e15d6..72774c16c 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -23,13 +23,7 @@ mod toplevel; /// Validate declarations into ast mod validate; -pub use ast::{ - BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, - FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, - InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, - ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypeRef, - UnionDatatype, UnionVariant, -}; +pub use ast::*; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 88d7d5dce..412aaf73b 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -120,6 +120,7 @@ impl Type { Type::Int(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), Type::Record(a) => a.to_sexpr(), + Type::Variant(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), Type::Handle(a) => a.to_sexpr(), Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), @@ -204,6 +205,24 @@ impl RecordDatatype { } } +impl Variant { + pub fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("variant")]; + let cases = self + .cases + .iter() + .map(|m| { + let mut list = vec![SExpr::word("case"), m.name.to_sexpr()]; + if let Some(ty) = &m.tref { + list.push(ty.to_sexpr()); + } + SExpr::docs(&m.docs, SExpr::Vec(list)) + }) + .collect::>(); + SExpr::Vec([header, cases].concat()) + } +} + impl UnionDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("union"), self.tag.name.to_sexpr()]; From a5298b663220ffcd523ff6496e6be4719b2da217 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 07:41:30 -0800 Subject: [PATCH 0834/1772] Add initial support for `variant` type --- proposals/filesystem/tools/witx/src/ast.rs | 14 +++++ .../filesystem/tools/witx/src/coretypes.rs | 4 +- .../filesystem/tools/witx/src/docs/ast.rs | 35 +++++++++-- .../filesystem/tools/witx/src/docs/md.rs | 2 + proposals/filesystem/tools/witx/src/layout.rs | 60 +++++++++++++------ proposals/filesystem/tools/witx/src/lib.rs | 8 +-- proposals/filesystem/tools/witx/src/render.rs | 19 ++++++ 7 files changed, 111 insertions(+), 31 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 65f354c7e..602db8219 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -181,6 +181,7 @@ pub enum Type { Int(IntDatatype), Flags(FlagsDatatype), Record(RecordDatatype), + Variant(Variant), Union(UnionDatatype), Handle(HandleDatatype), List(TypeRef), @@ -197,6 +198,7 @@ impl Type { Int(_) => "int", Flags(_) => "flags", Record(_) => "record", + Variant(_) => "variant", Union(_) => "union", Handle(_) => "handle", List(_) => "list", @@ -281,6 +283,18 @@ pub struct RecordMember { pub docs: String, } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Variant { + pub cases: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Case { + pub name: Id, + pub tref: Option, + pub docs: String, +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionDatatype { pub tag: Rc, diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index 733535318..d226ad691 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -53,7 +53,9 @@ impl Type { Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), - Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } => { + TypePassedBy::Pointer + } Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), } } diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index 59c246d23..fbf92080b 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -3,11 +3,7 @@ use super::{ Documentation, }; use crate::{ - ast::{ - BuiltinType, Document, EnumDatatype, FlagsDatatype, HandleDatatype, IntDatatype, IntRepr, - InterfaceFunc, InterfaceFuncParam, Module, ModuleImport, ModuleImportVariant, NamedType, - RecordDatatype, Type, TypeRef, UnionDatatype, - }, + ast::*, layout::Layout, polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, RepEquality, @@ -74,6 +70,7 @@ impl ToMarkdown for Type { Self::Int(a) => a.generate(node.clone()), Self::Flags(a) => a.generate(node.clone()), Self::Record(a) => a.generate(node.clone()), + Self::Variant(a) => a.generate(node.clone()), Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), Self::List(a) => { @@ -202,6 +199,33 @@ impl ToMarkdown for RecordDatatype { } } +impl ToMarkdown for Variant { + fn generate(&self, node: MdNodeRef) { + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Variant cases")); + + for case in self.cases.iter() { + let name = case.name.as_str(); + let id = if let Some(id) = node.any_ref().id() { + format!("{}.{}", id, name) + } else { + name.to_owned() + }; + let n = node.new_child(MdNamedType::new( + MdHeading::new_bullet(), + id.as_str(), + name, + format!("{}\n", &case.docs).as_str(), + )); + if let Some(ty) = &case.tref { + ty.generate(n.clone()); + } + } + + node.content_ref_mut::().r#type = Some(MdType::Variant); + } +} + impl ToMarkdown for UnionDatatype { fn generate(&self, node: MdNodeRef) { // Sizes & Alignments @@ -386,6 +410,7 @@ impl TypeRef { | Type::Int { .. } | Type::Flags { .. } | Type::Record { .. } + | Type::Variant { .. } | Type::Union { .. } | Type::Handle { .. } => { unimplemented!("type_name of anonymous compound datatypes") diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index 65969b8d2..f40200e8a 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -347,6 +347,7 @@ pub(super) enum MdType { Int { repr: String }, Flags { repr: String }, Record, + Variant, Union, List { r#type: String }, Pointer { r#type: String }, @@ -363,6 +364,7 @@ impl fmt::Display for MdType { Self::Int { repr } => f.write_fmt(format_args!(": Int(`{}`)", repr))?, Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Record => f.write_fmt(format_args!(": Record"))?, + Self::Variant => f.write_fmt(format_args!(": Variant"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, Self::List { r#type } => f.write_fmt(format_args!(": `List<{}>`", r#type))?, Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index d29f192b8..b918e0d6b 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -7,6 +7,17 @@ pub struct SizeAlign { pub align: usize, } +impl SizeAlign { + fn zero() -> SizeAlign { + SizeAlign { size: 0, align: 0 } + } + fn append_field(&mut self, other: &SizeAlign) { + self.align = self.align.max(other.align); + self.size = align_to(self.size, other.align); + self.size += other.size; + } +} + pub trait Layout { fn mem_size_align(&self) -> SizeAlign; fn mem_size(&self) -> usize { @@ -57,6 +68,7 @@ impl Type { Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), Type::Record(s) => s.layout(cache), + Type::Variant(s) => s.mem_size_align(), Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => BuiltinType::String.mem_size_align(), @@ -91,32 +103,29 @@ pub struct RecordMemberLayout<'a> { impl RecordDatatype { pub fn member_layout(&self) -> Vec { - self.member_layout_(&mut HashMap::new()) + self.member_layout_(&mut HashMap::new()).1 } - fn member_layout_(&self, cache: &mut HashMap) -> Vec { + fn member_layout_( + &self, + cache: &mut HashMap, + ) -> (SizeAlign, Vec) { let mut members = Vec::new(); - let mut offset = 0; + let mut sa = SizeAlign::zero(); for m in self.members.iter() { - let sa = m.tref.layout(cache); - offset = align_to(offset, sa.align); - members.push(RecordMemberLayout { member: m, offset }); - offset += sa.size; + let member = m.tref.layout(cache); + sa.append_field(&member); + members.push(RecordMemberLayout { + member: m, + offset: sa.size - member.size, + }); } - members + sa.size = align_to(sa.size, sa.align); + (sa, members) } fn layout(&self, cache: &mut HashMap) -> SizeAlign { - let members = self.member_layout_(cache); - let align = members - .iter() - .map(|m| m.member.tref.layout(cache).align) - .max() - .expect("nonzero struct members"); - let last = members.last().expect("nonzero struct members"); - let size = last.offset + last.member.tref.layout(cache).size; - let size = align_to(size, align); - SizeAlign { size, align } + self.member_layout_(cache).0 } } @@ -127,6 +136,21 @@ impl Layout for RecordDatatype { } } +impl Layout for Variant { + fn mem_size_align(&self) -> SizeAlign { + let mut max = SizeAlign { size: 0, align: 0 }; + for case in self.cases.iter() { + let mut size = BuiltinType::S32.mem_size_align(); + if let Some(payload) = &case.tref { + size.append_field(&payload.mem_size_align()); + } + max.size = max.size.max(size.size); + max.align = max.align.max(size.align); + } + max + } +} + /// If the next free byte in the struct is `offs`, and the next /// element has alignment `alignment`, determine the offset at /// which to place that element. diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index d320e15d6..72774c16c 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -23,13 +23,7 @@ mod toplevel; /// Validate declarations into ast mod validate; -pub use ast::{ - BuiltinType, Definition, Document, Entry, EnumDatatype, EnumVariant, FlagsDatatype, - FlagsMember, HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, - InterfaceFuncParam, InterfaceFuncParamPosition, Module, ModuleDefinition, ModuleEntry, - ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypeRef, - UnionDatatype, UnionVariant, -}; +pub use ast::*; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 88d7d5dce..412aaf73b 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -120,6 +120,7 @@ impl Type { Type::Int(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), Type::Record(a) => a.to_sexpr(), + Type::Variant(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), Type::Handle(a) => a.to_sexpr(), Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), @@ -204,6 +205,24 @@ impl RecordDatatype { } } +impl Variant { + pub fn to_sexpr(&self) -> SExpr { + let header = vec![SExpr::word("variant")]; + let cases = self + .cases + .iter() + .map(|m| { + let mut list = vec![SExpr::word("case"), m.name.to_sexpr()]; + if let Some(ty) = &m.tref { + list.push(ty.to_sexpr()); + } + SExpr::docs(&m.docs, SExpr::Vec(list)) + }) + .collect::>(); + SExpr::Vec([header, cases].concat()) + } +} + impl UnionDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("union"), self.tag.name.to_sexpr()]; From 6e0089c73739822d6138412ac9f672aabf2d17e4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 09:44:08 -0800 Subject: [PATCH 0835/1772] Remove `IntDatatype` Move constants to a separate list in `Document` --- proposals/clocks/phases/ephemeral/docs.md | 6 +-- .../phases/ephemeral/witx/typenames.witx | 10 ++-- proposals/clocks/tools/witx/src/ast.rs | 31 +++++------ proposals/clocks/tools/witx/src/coretypes.rs | 1 - proposals/clocks/tools/witx/src/docs/ast.rs | 27 +--------- proposals/clocks/tools/witx/src/docs/md.rs | 2 - proposals/clocks/tools/witx/src/layout.rs | 1 - proposals/clocks/tools/witx/src/parser.rs | 39 ++++---------- proposals/clocks/tools/witx/src/render.rs | 22 -------- proposals/clocks/tools/witx/src/validate.rs | 51 +++++++++---------- 10 files changed, 57 insertions(+), 133 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 3bd147b43..3d317dae7 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -480,17 +480,13 @@ Seek relative to current position. - `end` Seek relative to end-of-file. -## `dircookie`: Int(`u64`) +## `dircookie`: `u64` A reference to the offset of a directory entry. Size: 8 Alignment: 8 -### Consts -- `start` -In an `fd_readdir` call, this value signifies the start of the directory. - ## `dirnamlen`: `u32` The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index d4cc6274c..c456a99a7 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -323,12 +323,10 @@ ) ;;; A reference to the offset of a directory entry. -(typename $dircookie - (int u64 - ;;; In an `fd_readdir` call, this value signifies the start of the directory. - (const $start 0) - ) -) +(typename $dircookie u64) + +;;; In an `fd_readdir` call, this value signifies the start of the directory. +(@witx const $dircookie $start 0) ;;; The type for the `dirent::d_namlen` field of `dirent`. (typename $dirnamlen u32) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 602db8219..242fcce1c 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -87,6 +87,13 @@ impl Document { _ => None, }) } + + pub fn constants<'a>(&'a self) -> impl Iterator + 'a { + self.definitions.iter().filter_map(|d| match d { + Definition::Constant(c) => Some(c), + _ => None, + }) + } } impl PartialEq for Document { @@ -108,6 +115,7 @@ impl std::hash::Hash for Document { pub enum Definition { Typename(Rc), Module(Rc), + Constant(Constant), } #[derive(Debug, Clone)] @@ -178,7 +186,6 @@ impl NamedType { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { Enum(EnumDatatype), - Int(IntDatatype), Flags(FlagsDatatype), Record(RecordDatatype), Variant(Variant), @@ -195,7 +202,6 @@ impl Type { use Type::*; match self { Enum(_) => "enum", - Int(_) => "int", Flags(_) => "flags", Record(_) => "record", Variant(_) => "variant", @@ -246,19 +252,6 @@ pub struct EnumVariant { pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct IntDatatype { - pub repr: IntRepr, - pub consts: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct IntConst { - pub name: Id, - pub value: u64, - pub docs: String, -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsDatatype { pub repr: IntRepr, @@ -444,3 +437,11 @@ pub enum InterfaceFuncParamPosition { Param(usize), Result(usize), } + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Constant { + pub ty: Id, + pub name: Id, + pub value: u64, + pub docs: String, +} diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index d226ad691..c11529f9e 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -51,7 +51,6 @@ impl Type { Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), Type::Enum(e) => TypePassedBy::Value(e.repr.into()), - Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } => { TypePassedBy::Pointer diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index fbf92080b..454cac010 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -41,6 +41,8 @@ impl ToMarkdown for Document { let child = modules.new_child(content); d.generate(child.clone()); } + + // TODO: document constants } } @@ -67,7 +69,6 @@ impl ToMarkdown for Type { fn generate(&self, node: MdNodeRef) { match self { Self::Enum(a) => a.generate(node.clone()), - Self::Int(a) => a.generate(node.clone()), Self::Flags(a) => a.generate(node.clone()), Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), @@ -123,29 +124,6 @@ impl ToMarkdown for EnumDatatype { } } -impl ToMarkdown for IntDatatype { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Consts")); - - for r#const in &self.consts { - let name = r#const.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let tt = MdNamedType::new(MdHeading::new_bullet(), id.as_str(), name, &r#const.docs); - // TODO handle r#const.value - node.new_child(tt); - } - - node.content_ref_mut::().r#type = Some(MdType::Int { - repr: self.repr.type_name().to_owned(), - }); - } -} - impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); @@ -407,7 +385,6 @@ impl TypeRef { Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), Type::Enum { .. } - | Type::Int { .. } | Type::Flags { .. } | Type::Record { .. } | Type::Variant { .. } diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index f40200e8a..1ca3a8794 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -344,7 +344,6 @@ impl MdNamedType { #[derive(Debug)] pub(super) enum MdType { Enum { repr: String }, - Int { repr: String }, Flags { repr: String }, Record, Variant, @@ -361,7 +360,6 @@ impl fmt::Display for MdType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::Enum { repr } => f.write_fmt(format_args!(": Enum(`{}`)", repr))?, - Self::Int { repr } => f.write_fmt(format_args!(": Int(`{}`)", repr))?, Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index b918e0d6b..cc4fd0add 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -65,7 +65,6 @@ impl Type { fn layout(&self, cache: &mut HashMap) -> SizeAlign { match &self { Type::Enum(e) => e.repr.mem_size_align(), - Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), Type::Record(s) => s.layout(cache), Type::Variant(s) => s.mem_size_align(), diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index aedee808f..ad9100481 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -26,7 +26,6 @@ mod kw { wast::custom_keyword!(empty); wast::custom_keyword!(flags); wast::custom_keyword!(handle); - wast::custom_keyword!(int); wast::custom_keyword!(list); wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); @@ -237,6 +236,7 @@ impl<'a> Parse<'a> for TopLevelSyntax<'a> { pub enum DeclSyntax<'a> { Typename(TypenameSyntax<'a>), Module(ModuleSyntax<'a>), + Const(Documented<'a, ConstSyntax<'a>>), } impl<'a> Parse<'a> for DeclSyntax<'a> { @@ -246,6 +246,8 @@ impl<'a> Parse<'a> for DeclSyntax<'a> { Ok(DeclSyntax::Module(parser.parse()?)) } else if l.peek::() { Ok(DeclSyntax::Typename(parser.parse()?)) + } else if l.peek::() { + Ok(DeclSyntax::Const(parser.parse()?)) } else { Err(l.error()) } @@ -270,7 +272,6 @@ impl<'a> Parse<'a> for TypenameSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub enum TypedefSyntax<'a> { Enum(EnumSyntax<'a>), - Int(IntSyntax<'a>), Flags(FlagsSyntax<'a>), Record(RecordSyntax<'a>), Union(UnionSyntax<'a>), @@ -294,8 +295,6 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { let mut l = parser.lookahead1(); if l.peek::() { Ok(TypedefSyntax::Enum(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Int(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Flags(parser.parse()?)) } else if l.peek::() { @@ -351,39 +350,21 @@ impl<'a> Parse<'a> for EnumSyntax<'a> { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct IntSyntax<'a> { - pub repr: BuiltinType, - pub consts: Vec>>, -} - -impl<'a> Parse<'a> for IntSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let repr = parser.parse()?; - let mut consts = Vec::new(); - consts.push(parser.parse()?); - while !parser.is_empty() { - consts.push(parser.parse()?); - } - Ok(IntSyntax { repr, consts }) - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConstSyntax<'a> { + pub ty: wast::Id<'a>, pub name: wast::Id<'a>, pub value: u64, } impl<'a> Parse<'a> for ConstSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - p.parse::()?; - let name = p.parse()?; - let value = p.parse()?; - Ok(ConstSyntax { name, value }) - }) + parser.parse::()?; + parser.parse::()?; + let ty = parser.parse()?; + let name = parser.parse()?; + let value = parser.parse()?; + Ok(ConstSyntax { ty, name, value }) } } diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 412aaf73b..44ccb54df 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -117,7 +117,6 @@ impl Type { pub fn to_sexpr(&self) -> SExpr { match self { Type::Enum(a) => a.to_sexpr(), - Type::Int(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), Type::Record(a) => a.to_sexpr(), Type::Variant(a) => a.to_sexpr(), @@ -151,27 +150,6 @@ impl EnumDatatype { } } -impl IntDatatype { - fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("int"), self.repr.to_sexpr()]; - let consts = self - .consts - .iter() - .map(|v| { - SExpr::docs( - &v.docs, - SExpr::Vec(vec![ - SExpr::word("const"), - v.name.to_sexpr(), - SExpr::word(&format!("{}", v.value)), - ]), - ) - }) - .collect::>(); - SExpr::Vec([header, consts].concat()) - } -} - impl FlagsDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index adfcb757e..b51596fe3 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -2,11 +2,11 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, - ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, + ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, VariantSyntax, }, - BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, - HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, + BuiltinType, Constant, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, + FlagsMember, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, @@ -121,6 +121,7 @@ impl IdentValidation { pub struct DocValidation { scope: IdentValidation, pub entries: HashMap, + constant_scopes: HashMap, } pub struct DocValidationScope<'a> { @@ -134,6 +135,7 @@ impl DocValidation { Self { scope: IdentValidation::new(), entries: HashMap::new(), + constant_scopes: HashMap::new(), } } @@ -208,6 +210,25 @@ impl DocValidationScope<'_> { .insert(name, Entry::Module(Rc::downgrade(&rc_module))); Ok(Definition::Module(rc_module)) } + + DeclSyntax::Const(syntax) => { + let ty = Id::new(syntax.item.ty.name()); + let loc = self.location(syntax.item.name.span()); + let scope = self + .doc + .constant_scopes + .entry(ty.clone()) + .or_insert_with(IdentValidation::new); + let name = scope.introduce(syntax.item.name.name(), loc)?; + // TODO: validate `ty` is a integer datatype that `syntax.value` + // fits within. + Ok(Definition::Constant(Constant { + ty, + name, + value: syntax.item.value, + docs: syntax.comments.docs(), + })) + } } } @@ -237,7 +258,6 @@ impl DocValidationScope<'_> { } } TypedefSyntax::Enum { .. } - | TypedefSyntax::Int { .. } | TypedefSyntax::Flags { .. } | TypedefSyntax::Record { .. } | TypedefSyntax::Union { .. } @@ -250,7 +270,6 @@ impl DocValidationScope<'_> { } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), - TypedefSyntax::Int(syntax) => Type::Int(self.validate_int(&syntax, span)?), TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), @@ -290,28 +309,6 @@ impl DocValidationScope<'_> { Ok(EnumDatatype { repr, variants }) } - fn validate_int( - &self, - syntax: &IntSyntax, - span: wast::Span, - ) -> Result { - let mut int_scope = IdentValidation::new(); - let repr = self.validate_int_repr(&syntax.repr, span)?; - let consts = syntax - .consts - .iter() - .map(|i| { - let name = - int_scope.introduce(i.item.name.name(), self.location(i.item.name.span()))?; - let value = i.item.value; - let docs = i.comments.docs(); - Ok(IntConst { name, value, docs }) - }) - .collect::, _>>()?; - - Ok(IntDatatype { repr, consts }) - } - fn validate_flags( &self, syntax: &FlagsSyntax, From b150540f29beb9e27e105ac75f61be4814e76ef3 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 09:44:08 -0800 Subject: [PATCH 0836/1772] Remove `IntDatatype` Move constants to a separate list in `Document` --- proposals/random/phases/ephemeral/docs.md | 6 +-- .../phases/ephemeral/witx/typenames.witx | 10 ++-- proposals/random/tools/witx/src/ast.rs | 31 +++++------ proposals/random/tools/witx/src/coretypes.rs | 1 - proposals/random/tools/witx/src/docs/ast.rs | 27 +--------- proposals/random/tools/witx/src/docs/md.rs | 2 - proposals/random/tools/witx/src/layout.rs | 1 - proposals/random/tools/witx/src/parser.rs | 39 ++++---------- proposals/random/tools/witx/src/render.rs | 22 -------- proposals/random/tools/witx/src/validate.rs | 51 +++++++++---------- 10 files changed, 57 insertions(+), 133 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 3bd147b43..3d317dae7 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -480,17 +480,13 @@ Seek relative to current position. - `end` Seek relative to end-of-file. -## `dircookie`: Int(`u64`) +## `dircookie`: `u64` A reference to the offset of a directory entry. Size: 8 Alignment: 8 -### Consts -- `start` -In an `fd_readdir` call, this value signifies the start of the directory. - ## `dirnamlen`: `u32` The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index d4cc6274c..c456a99a7 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -323,12 +323,10 @@ ) ;;; A reference to the offset of a directory entry. -(typename $dircookie - (int u64 - ;;; In an `fd_readdir` call, this value signifies the start of the directory. - (const $start 0) - ) -) +(typename $dircookie u64) + +;;; In an `fd_readdir` call, this value signifies the start of the directory. +(@witx const $dircookie $start 0) ;;; The type for the `dirent::d_namlen` field of `dirent`. (typename $dirnamlen u32) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 602db8219..242fcce1c 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -87,6 +87,13 @@ impl Document { _ => None, }) } + + pub fn constants<'a>(&'a self) -> impl Iterator + 'a { + self.definitions.iter().filter_map(|d| match d { + Definition::Constant(c) => Some(c), + _ => None, + }) + } } impl PartialEq for Document { @@ -108,6 +115,7 @@ impl std::hash::Hash for Document { pub enum Definition { Typename(Rc), Module(Rc), + Constant(Constant), } #[derive(Debug, Clone)] @@ -178,7 +186,6 @@ impl NamedType { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { Enum(EnumDatatype), - Int(IntDatatype), Flags(FlagsDatatype), Record(RecordDatatype), Variant(Variant), @@ -195,7 +202,6 @@ impl Type { use Type::*; match self { Enum(_) => "enum", - Int(_) => "int", Flags(_) => "flags", Record(_) => "record", Variant(_) => "variant", @@ -246,19 +252,6 @@ pub struct EnumVariant { pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct IntDatatype { - pub repr: IntRepr, - pub consts: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct IntConst { - pub name: Id, - pub value: u64, - pub docs: String, -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsDatatype { pub repr: IntRepr, @@ -444,3 +437,11 @@ pub enum InterfaceFuncParamPosition { Param(usize), Result(usize), } + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Constant { + pub ty: Id, + pub name: Id, + pub value: u64, + pub docs: String, +} diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index d226ad691..c11529f9e 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -51,7 +51,6 @@ impl Type { Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), Type::Enum(e) => TypePassedBy::Value(e.repr.into()), - Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } => { TypePassedBy::Pointer diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index fbf92080b..454cac010 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -41,6 +41,8 @@ impl ToMarkdown for Document { let child = modules.new_child(content); d.generate(child.clone()); } + + // TODO: document constants } } @@ -67,7 +69,6 @@ impl ToMarkdown for Type { fn generate(&self, node: MdNodeRef) { match self { Self::Enum(a) => a.generate(node.clone()), - Self::Int(a) => a.generate(node.clone()), Self::Flags(a) => a.generate(node.clone()), Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), @@ -123,29 +124,6 @@ impl ToMarkdown for EnumDatatype { } } -impl ToMarkdown for IntDatatype { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Consts")); - - for r#const in &self.consts { - let name = r#const.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let tt = MdNamedType::new(MdHeading::new_bullet(), id.as_str(), name, &r#const.docs); - // TODO handle r#const.value - node.new_child(tt); - } - - node.content_ref_mut::().r#type = Some(MdType::Int { - repr: self.repr.type_name().to_owned(), - }); - } -} - impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); @@ -407,7 +385,6 @@ impl TypeRef { Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), Type::Enum { .. } - | Type::Int { .. } | Type::Flags { .. } | Type::Record { .. } | Type::Variant { .. } diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index f40200e8a..1ca3a8794 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -344,7 +344,6 @@ impl MdNamedType { #[derive(Debug)] pub(super) enum MdType { Enum { repr: String }, - Int { repr: String }, Flags { repr: String }, Record, Variant, @@ -361,7 +360,6 @@ impl fmt::Display for MdType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::Enum { repr } => f.write_fmt(format_args!(": Enum(`{}`)", repr))?, - Self::Int { repr } => f.write_fmt(format_args!(": Int(`{}`)", repr))?, Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index b918e0d6b..cc4fd0add 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -65,7 +65,6 @@ impl Type { fn layout(&self, cache: &mut HashMap) -> SizeAlign { match &self { Type::Enum(e) => e.repr.mem_size_align(), - Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), Type::Record(s) => s.layout(cache), Type::Variant(s) => s.mem_size_align(), diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index aedee808f..ad9100481 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -26,7 +26,6 @@ mod kw { wast::custom_keyword!(empty); wast::custom_keyword!(flags); wast::custom_keyword!(handle); - wast::custom_keyword!(int); wast::custom_keyword!(list); wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); @@ -237,6 +236,7 @@ impl<'a> Parse<'a> for TopLevelSyntax<'a> { pub enum DeclSyntax<'a> { Typename(TypenameSyntax<'a>), Module(ModuleSyntax<'a>), + Const(Documented<'a, ConstSyntax<'a>>), } impl<'a> Parse<'a> for DeclSyntax<'a> { @@ -246,6 +246,8 @@ impl<'a> Parse<'a> for DeclSyntax<'a> { Ok(DeclSyntax::Module(parser.parse()?)) } else if l.peek::() { Ok(DeclSyntax::Typename(parser.parse()?)) + } else if l.peek::() { + Ok(DeclSyntax::Const(parser.parse()?)) } else { Err(l.error()) } @@ -270,7 +272,6 @@ impl<'a> Parse<'a> for TypenameSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub enum TypedefSyntax<'a> { Enum(EnumSyntax<'a>), - Int(IntSyntax<'a>), Flags(FlagsSyntax<'a>), Record(RecordSyntax<'a>), Union(UnionSyntax<'a>), @@ -294,8 +295,6 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { let mut l = parser.lookahead1(); if l.peek::() { Ok(TypedefSyntax::Enum(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Int(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Flags(parser.parse()?)) } else if l.peek::() { @@ -351,39 +350,21 @@ impl<'a> Parse<'a> for EnumSyntax<'a> { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct IntSyntax<'a> { - pub repr: BuiltinType, - pub consts: Vec>>, -} - -impl<'a> Parse<'a> for IntSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let repr = parser.parse()?; - let mut consts = Vec::new(); - consts.push(parser.parse()?); - while !parser.is_empty() { - consts.push(parser.parse()?); - } - Ok(IntSyntax { repr, consts }) - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConstSyntax<'a> { + pub ty: wast::Id<'a>, pub name: wast::Id<'a>, pub value: u64, } impl<'a> Parse<'a> for ConstSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - p.parse::()?; - let name = p.parse()?; - let value = p.parse()?; - Ok(ConstSyntax { name, value }) - }) + parser.parse::()?; + parser.parse::()?; + let ty = parser.parse()?; + let name = parser.parse()?; + let value = parser.parse()?; + Ok(ConstSyntax { ty, name, value }) } } diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 412aaf73b..44ccb54df 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -117,7 +117,6 @@ impl Type { pub fn to_sexpr(&self) -> SExpr { match self { Type::Enum(a) => a.to_sexpr(), - Type::Int(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), Type::Record(a) => a.to_sexpr(), Type::Variant(a) => a.to_sexpr(), @@ -151,27 +150,6 @@ impl EnumDatatype { } } -impl IntDatatype { - fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("int"), self.repr.to_sexpr()]; - let consts = self - .consts - .iter() - .map(|v| { - SExpr::docs( - &v.docs, - SExpr::Vec(vec![ - SExpr::word("const"), - v.name.to_sexpr(), - SExpr::word(&format!("{}", v.value)), - ]), - ) - }) - .collect::>(); - SExpr::Vec([header, consts].concat()) - } -} - impl FlagsDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index adfcb757e..b51596fe3 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -2,11 +2,11 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, - ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, + ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, VariantSyntax, }, - BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, - HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, + BuiltinType, Constant, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, + FlagsMember, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, @@ -121,6 +121,7 @@ impl IdentValidation { pub struct DocValidation { scope: IdentValidation, pub entries: HashMap, + constant_scopes: HashMap, } pub struct DocValidationScope<'a> { @@ -134,6 +135,7 @@ impl DocValidation { Self { scope: IdentValidation::new(), entries: HashMap::new(), + constant_scopes: HashMap::new(), } } @@ -208,6 +210,25 @@ impl DocValidationScope<'_> { .insert(name, Entry::Module(Rc::downgrade(&rc_module))); Ok(Definition::Module(rc_module)) } + + DeclSyntax::Const(syntax) => { + let ty = Id::new(syntax.item.ty.name()); + let loc = self.location(syntax.item.name.span()); + let scope = self + .doc + .constant_scopes + .entry(ty.clone()) + .or_insert_with(IdentValidation::new); + let name = scope.introduce(syntax.item.name.name(), loc)?; + // TODO: validate `ty` is a integer datatype that `syntax.value` + // fits within. + Ok(Definition::Constant(Constant { + ty, + name, + value: syntax.item.value, + docs: syntax.comments.docs(), + })) + } } } @@ -237,7 +258,6 @@ impl DocValidationScope<'_> { } } TypedefSyntax::Enum { .. } - | TypedefSyntax::Int { .. } | TypedefSyntax::Flags { .. } | TypedefSyntax::Record { .. } | TypedefSyntax::Union { .. } @@ -250,7 +270,6 @@ impl DocValidationScope<'_> { } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), - TypedefSyntax::Int(syntax) => Type::Int(self.validate_int(&syntax, span)?), TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), @@ -290,28 +309,6 @@ impl DocValidationScope<'_> { Ok(EnumDatatype { repr, variants }) } - fn validate_int( - &self, - syntax: &IntSyntax, - span: wast::Span, - ) -> Result { - let mut int_scope = IdentValidation::new(); - let repr = self.validate_int_repr(&syntax.repr, span)?; - let consts = syntax - .consts - .iter() - .map(|i| { - let name = - int_scope.introduce(i.item.name.name(), self.location(i.item.name.span()))?; - let value = i.item.value; - let docs = i.comments.docs(); - Ok(IntConst { name, value, docs }) - }) - .collect::, _>>()?; - - Ok(IntDatatype { repr, consts }) - } - fn validate_flags( &self, syntax: &FlagsSyntax, From 9b636d3b98c132fbdb8e8cdee4af4ba381fa09d2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 09:44:08 -0800 Subject: [PATCH 0837/1772] Remove `IntDatatype` Move constants to a separate list in `Document` --- proposals/filesystem/phases/ephemeral/docs.md | 6 +-- .../phases/ephemeral/witx/typenames.witx | 10 ++-- proposals/filesystem/tools/witx/src/ast.rs | 31 +++++------ .../filesystem/tools/witx/src/coretypes.rs | 1 - .../filesystem/tools/witx/src/docs/ast.rs | 27 +--------- .../filesystem/tools/witx/src/docs/md.rs | 2 - proposals/filesystem/tools/witx/src/layout.rs | 1 - proposals/filesystem/tools/witx/src/parser.rs | 39 ++++---------- proposals/filesystem/tools/witx/src/render.rs | 22 -------- .../filesystem/tools/witx/src/validate.rs | 51 +++++++++---------- 10 files changed, 57 insertions(+), 133 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 3bd147b43..3d317dae7 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -480,17 +480,13 @@ Seek relative to current position. - `end` Seek relative to end-of-file. -## `dircookie`: Int(`u64`) +## `dircookie`: `u64` A reference to the offset of a directory entry. Size: 8 Alignment: 8 -### Consts -- `start` -In an `fd_readdir` call, this value signifies the start of the directory. - ## `dirnamlen`: `u32` The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index d4cc6274c..c456a99a7 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -323,12 +323,10 @@ ) ;;; A reference to the offset of a directory entry. -(typename $dircookie - (int u64 - ;;; In an `fd_readdir` call, this value signifies the start of the directory. - (const $start 0) - ) -) +(typename $dircookie u64) + +;;; In an `fd_readdir` call, this value signifies the start of the directory. +(@witx const $dircookie $start 0) ;;; The type for the `dirent::d_namlen` field of `dirent`. (typename $dirnamlen u32) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 602db8219..242fcce1c 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -87,6 +87,13 @@ impl Document { _ => None, }) } + + pub fn constants<'a>(&'a self) -> impl Iterator + 'a { + self.definitions.iter().filter_map(|d| match d { + Definition::Constant(c) => Some(c), + _ => None, + }) + } } impl PartialEq for Document { @@ -108,6 +115,7 @@ impl std::hash::Hash for Document { pub enum Definition { Typename(Rc), Module(Rc), + Constant(Constant), } #[derive(Debug, Clone)] @@ -178,7 +186,6 @@ impl NamedType { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { Enum(EnumDatatype), - Int(IntDatatype), Flags(FlagsDatatype), Record(RecordDatatype), Variant(Variant), @@ -195,7 +202,6 @@ impl Type { use Type::*; match self { Enum(_) => "enum", - Int(_) => "int", Flags(_) => "flags", Record(_) => "record", Variant(_) => "variant", @@ -246,19 +252,6 @@ pub struct EnumVariant { pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct IntDatatype { - pub repr: IntRepr, - pub consts: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct IntConst { - pub name: Id, - pub value: u64, - pub docs: String, -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsDatatype { pub repr: IntRepr, @@ -444,3 +437,11 @@ pub enum InterfaceFuncParamPosition { Param(usize), Result(usize), } + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Constant { + pub ty: Id, + pub name: Id, + pub value: u64, + pub docs: String, +} diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index d226ad691..c11529f9e 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -51,7 +51,6 @@ impl Type { Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), Type::Enum(e) => TypePassedBy::Value(e.repr.into()), - Type::Int(i) => TypePassedBy::Value(i.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } => { TypePassedBy::Pointer diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index fbf92080b..454cac010 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -41,6 +41,8 @@ impl ToMarkdown for Document { let child = modules.new_child(content); d.generate(child.clone()); } + + // TODO: document constants } } @@ -67,7 +69,6 @@ impl ToMarkdown for Type { fn generate(&self, node: MdNodeRef) { match self { Self::Enum(a) => a.generate(node.clone()), - Self::Int(a) => a.generate(node.clone()), Self::Flags(a) => a.generate(node.clone()), Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), @@ -123,29 +124,6 @@ impl ToMarkdown for EnumDatatype { } } -impl ToMarkdown for IntDatatype { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Consts")); - - for r#const in &self.consts { - let name = r#const.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let tt = MdNamedType::new(MdHeading::new_bullet(), id.as_str(), name, &r#const.docs); - // TODO handle r#const.value - node.new_child(tt); - } - - node.content_ref_mut::().r#type = Some(MdType::Int { - repr: self.repr.type_name().to_owned(), - }); - } -} - impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); @@ -407,7 +385,6 @@ impl TypeRef { Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), Type::Enum { .. } - | Type::Int { .. } | Type::Flags { .. } | Type::Record { .. } | Type::Variant { .. } diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index f40200e8a..1ca3a8794 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -344,7 +344,6 @@ impl MdNamedType { #[derive(Debug)] pub(super) enum MdType { Enum { repr: String }, - Int { repr: String }, Flags { repr: String }, Record, Variant, @@ -361,7 +360,6 @@ impl fmt::Display for MdType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::Enum { repr } => f.write_fmt(format_args!(": Enum(`{}`)", repr))?, - Self::Int { repr } => f.write_fmt(format_args!(": Int(`{}`)", repr))?, Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index b918e0d6b..cc4fd0add 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -65,7 +65,6 @@ impl Type { fn layout(&self, cache: &mut HashMap) -> SizeAlign { match &self { Type::Enum(e) => e.repr.mem_size_align(), - Type::Int(i) => i.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), Type::Record(s) => s.layout(cache), Type::Variant(s) => s.mem_size_align(), diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index aedee808f..ad9100481 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -26,7 +26,6 @@ mod kw { wast::custom_keyword!(empty); wast::custom_keyword!(flags); wast::custom_keyword!(handle); - wast::custom_keyword!(int); wast::custom_keyword!(list); wast::custom_keyword!(noreturn); wast::custom_keyword!(pointer); @@ -237,6 +236,7 @@ impl<'a> Parse<'a> for TopLevelSyntax<'a> { pub enum DeclSyntax<'a> { Typename(TypenameSyntax<'a>), Module(ModuleSyntax<'a>), + Const(Documented<'a, ConstSyntax<'a>>), } impl<'a> Parse<'a> for DeclSyntax<'a> { @@ -246,6 +246,8 @@ impl<'a> Parse<'a> for DeclSyntax<'a> { Ok(DeclSyntax::Module(parser.parse()?)) } else if l.peek::() { Ok(DeclSyntax::Typename(parser.parse()?)) + } else if l.peek::() { + Ok(DeclSyntax::Const(parser.parse()?)) } else { Err(l.error()) } @@ -270,7 +272,6 @@ impl<'a> Parse<'a> for TypenameSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub enum TypedefSyntax<'a> { Enum(EnumSyntax<'a>), - Int(IntSyntax<'a>), Flags(FlagsSyntax<'a>), Record(RecordSyntax<'a>), Union(UnionSyntax<'a>), @@ -294,8 +295,6 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { let mut l = parser.lookahead1(); if l.peek::() { Ok(TypedefSyntax::Enum(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Int(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Flags(parser.parse()?)) } else if l.peek::() { @@ -351,39 +350,21 @@ impl<'a> Parse<'a> for EnumSyntax<'a> { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct IntSyntax<'a> { - pub repr: BuiltinType, - pub consts: Vec>>, -} - -impl<'a> Parse<'a> for IntSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let repr = parser.parse()?; - let mut consts = Vec::new(); - consts.push(parser.parse()?); - while !parser.is_empty() { - consts.push(parser.parse()?); - } - Ok(IntSyntax { repr, consts }) - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConstSyntax<'a> { + pub ty: wast::Id<'a>, pub name: wast::Id<'a>, pub value: u64, } impl<'a> Parse<'a> for ConstSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - p.parse::()?; - let name = p.parse()?; - let value = p.parse()?; - Ok(ConstSyntax { name, value }) - }) + parser.parse::()?; + parser.parse::()?; + let ty = parser.parse()?; + let name = parser.parse()?; + let value = parser.parse()?; + Ok(ConstSyntax { ty, name, value }) } } diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 412aaf73b..44ccb54df 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -117,7 +117,6 @@ impl Type { pub fn to_sexpr(&self) -> SExpr { match self { Type::Enum(a) => a.to_sexpr(), - Type::Int(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), Type::Record(a) => a.to_sexpr(), Type::Variant(a) => a.to_sexpr(), @@ -151,27 +150,6 @@ impl EnumDatatype { } } -impl IntDatatype { - fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("int"), self.repr.to_sexpr()]; - let consts = self - .consts - .iter() - .map(|v| { - SExpr::docs( - &v.docs, - SExpr::Vec(vec![ - SExpr::word("const"), - v.name.to_sexpr(), - SExpr::word(&format!("{}", v.value)), - ]), - ) - }) - .collect::>(); - SExpr::Vec([header, consts].concat()) - } -} - impl FlagsDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index adfcb757e..b51596fe3 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -2,11 +2,11 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, - ImportTypeSyntax, IntSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, + ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, VariantSyntax, }, - BuiltinType, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, FlagsMember, - HandleDatatype, Id, IntConst, IntDatatype, IntRepr, InterfaceFunc, InterfaceFuncParam, + BuiltinType, Constant, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, + FlagsMember, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, @@ -121,6 +121,7 @@ impl IdentValidation { pub struct DocValidation { scope: IdentValidation, pub entries: HashMap, + constant_scopes: HashMap, } pub struct DocValidationScope<'a> { @@ -134,6 +135,7 @@ impl DocValidation { Self { scope: IdentValidation::new(), entries: HashMap::new(), + constant_scopes: HashMap::new(), } } @@ -208,6 +210,25 @@ impl DocValidationScope<'_> { .insert(name, Entry::Module(Rc::downgrade(&rc_module))); Ok(Definition::Module(rc_module)) } + + DeclSyntax::Const(syntax) => { + let ty = Id::new(syntax.item.ty.name()); + let loc = self.location(syntax.item.name.span()); + let scope = self + .doc + .constant_scopes + .entry(ty.clone()) + .or_insert_with(IdentValidation::new); + let name = scope.introduce(syntax.item.name.name(), loc)?; + // TODO: validate `ty` is a integer datatype that `syntax.value` + // fits within. + Ok(Definition::Constant(Constant { + ty, + name, + value: syntax.item.value, + docs: syntax.comments.docs(), + })) + } } } @@ -237,7 +258,6 @@ impl DocValidationScope<'_> { } } TypedefSyntax::Enum { .. } - | TypedefSyntax::Int { .. } | TypedefSyntax::Flags { .. } | TypedefSyntax::Record { .. } | TypedefSyntax::Union { .. } @@ -250,7 +270,6 @@ impl DocValidationScope<'_> { } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), - TypedefSyntax::Int(syntax) => Type::Int(self.validate_int(&syntax, span)?), TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), @@ -290,28 +309,6 @@ impl DocValidationScope<'_> { Ok(EnumDatatype { repr, variants }) } - fn validate_int( - &self, - syntax: &IntSyntax, - span: wast::Span, - ) -> Result { - let mut int_scope = IdentValidation::new(); - let repr = self.validate_int_repr(&syntax.repr, span)?; - let consts = syntax - .consts - .iter() - .map(|i| { - let name = - int_scope.introduce(i.item.name.name(), self.location(i.item.name.span()))?; - let value = i.item.value; - let docs = i.comments.docs(); - Ok(IntConst { name, value, docs }) - }) - .collect::, _>>()?; - - Ok(IntDatatype { repr, consts }) - } - fn validate_flags( &self, syntax: &FlagsSyntax, From d5d1049a1423593dbdc778990c1778b4bbbe4543 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 10:43:05 -0800 Subject: [PATCH 0838/1772] Implement enums in terms of `Variant` --- proposals/clocks/phases/ephemeral/docs.md | 28 ++++----- .../phases/ephemeral/witx/typenames.witx | 14 ++--- .../clocks/phases/old/snapshot_0/docs.md | 32 +++++------ .../phases/old/snapshot_0/witx/typenames.witx | 16 +++--- proposals/clocks/phases/snapshot/docs.md | 32 +++++------ .../phases/snapshot/witx/typenames.witx | 16 +++--- proposals/clocks/tools/witx/src/ast.rs | 15 +---- proposals/clocks/tools/witx/src/coretypes.rs | 10 +++- proposals/clocks/tools/witx/src/docs/ast.rs | 32 +---------- proposals/clocks/tools/witx/src/docs/md.rs | 2 - proposals/clocks/tools/witx/src/layout.rs | 4 +- proposals/clocks/tools/witx/src/parser.rs | 13 ++++- proposals/clocks/tools/witx/src/render.rs | 46 +++++++-------- .../clocks/tools/witx/src/representation.rs | 30 +++++----- proposals/clocks/tools/witx/src/validate.rs | 57 ++++++++++++------- .../clocks/tools/witx/tests/anonymous.rs | 6 +- proposals/clocks/tools/witx/tests/union.rs | 20 +++---- 17 files changed, 179 insertions(+), 194 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 3d317dae7..3c9b13531 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -22,14 +22,14 @@ Size: 8 Alignment: 8 -## `clockid`: Enum(`u32`) +## `clockid`: Variant Identifiers for clocks. Size: 4 Alignment: 4 -### Variants +### Variant cases - `realtime` The clock measuring real time. Time value zero corresponds with 1970-01-01T00:00:00Z. @@ -40,7 +40,7 @@ real time, whose value cannot be adjusted and which cannot have negative clock jumps. The epoch of this clock is undefined. The absolute time value of this clock therefore has no meaning. -## `errno`: Enum(`u16`) +## `errno`: Variant Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -50,7 +50,7 @@ Size: 2 Alignment: 2 -### Variants +### Variant cases - `success` No error occurred. System call completed successfully. @@ -463,14 +463,14 @@ Size: 8 Alignment: 8 -## `whence`: Enum(`u8`) +## `whence`: Variant The position relative to which to set the offset of the file descriptor. Size: 1 Alignment: 1 -### Variants +### Variant cases - `set` Seek relative to start-of-file. @@ -501,14 +501,14 @@ Size: 8 Alignment: 8 -## `filetype`: Enum(`u8`) +## `filetype`: Variant The type of a file descriptor or file. Size: 1 Alignment: 1 -### Variants +### Variant cases - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -564,14 +564,14 @@ The length of the name of the directory entry. Offset: 20 -## `advice`: Enum(`u8`) +## `advice`: Variant File or memory access pattern advisory information. Size: 1 Alignment: 1 -### Variants +### Variant cases - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -805,14 +805,14 @@ Size: 8 Alignment: 8 -## `eventtype`: Enum(`u8`) +## `eventtype`: Variant Type of a subscription to an event or its occurrence. Size: 1 Alignment: 1 -### Variants +### Variant cases - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -1051,14 +1051,14 @@ Disables further receive operations. - `wr` Disables further send operations. -## `preopentype`: Enum(`u8`) +## `preopentype`: Variant Identifiers for preopened capabilities. Size: 1 Alignment: 1 -### Variants +### Variant cases - `dir` A pre-opened directory. diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index c456a99a7..f2cde8272 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -18,7 +18,7 @@ ;;; Identifiers for clocks. (typename $clockid - (enum u32 + (enum (@witx tag u32) ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. $realtime @@ -35,7 +35,7 @@ ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. (typename $errno - (enum u16 + (enum (@witx tag u16) ;;; No error occurred. System call completed successfully. $success ;;; Argument list too long. @@ -312,7 +312,7 @@ ;;; The position relative to which to set the offset of the file descriptor. (typename $whence - (enum u8 + (enum (@witx tag u8) ;;; Seek relative to start-of-file. $set ;;; Seek relative to current position. @@ -336,7 +336,7 @@ ;;; The type of a file descriptor or file. (typename $filetype - (enum u8 + (enum (@witx tag u8) ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $unknown ;;; The file descriptor or file refers to a block device inode. @@ -374,7 +374,7 @@ ;;; File or memory access pattern advisory information. (typename $advice - (enum u8 + (enum (@witx tag u8) ;;; The application has no advice to give on its behavior with respect to the specified data. $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. @@ -527,7 +527,7 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype - (enum u8 + (enum (@witx tag u8) ;;; The time value of clock `subscription_clock::id` has ;;; reached timestamp `subscription_clock::timeout`. $clock @@ -675,7 +675,7 @@ ;;; Identifiers for preopened capabilities. (typename $preopentype - (enum u8 + (enum (@witx tag u8) ;;; A pre-opened directory. $dir ) diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index b56aa1f5e..5c9543331 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -19,14 +19,14 @@ Size: 8 Alignment: 8 -## `clockid`: Enum(`u32`) +## `clockid`: Variant Identifiers for clocks. Size: 4 Alignment: 4 -### Variants +### Variant cases - `realtime` The clock measuring real time. Time value zero corresponds with 1970-01-01T00:00:00Z. @@ -43,7 +43,7 @@ The CPU-time clock associated with the current process. - `thread_cputime_id` The CPU-time clock associated with the current thread. -## `errno`: Enum(`u16`) +## `errno`: Variant Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -53,7 +53,7 @@ Size: 2 Alignment: 2 -### Variants +### Variant cases - `success` No error occurred. System call completed successfully. @@ -455,14 +455,14 @@ Size: 8 Alignment: 8 -## `whence`: Enum(`u8`) +## `whence`: Variant The position relative to which to set the offset of the file descriptor. Size: 1 Alignment: 1 -### Variants +### Variant cases - `cur` Seek relative to current position. @@ -493,14 +493,14 @@ Size: 8 Alignment: 8 -## `filetype`: Enum(`u8`) +## `filetype`: Variant The type of a file descriptor or file. Size: 1 Alignment: 1 -### Variants +### Variant cases - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -553,14 +553,14 @@ The type of the file referred to by this directory entry. Offset: 20 -## `advice`: Enum(`u8`) +## `advice`: Variant File or memory access pattern advisory information. Size: 1 Alignment: 1 -### Variants +### Variant cases - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -755,14 +755,14 @@ Size: 8 Alignment: 8 -## `eventtype`: Enum(`u8`) +## `eventtype`: Variant Type of a subscription to an event or its occurrence. Size: 1 Alignment: 1 -### Variants +### Variant cases - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -945,14 +945,14 @@ Size: 4 Alignment: 4 -## `signal`: Enum(`u8`) +## `signal`: Variant Signal condition. Size: 1 Alignment: 1 -### Variants +### Variant cases - `none` No signal. Note that POSIX has special semantics for `kill(pid, 0)`, so this value is reserved. @@ -1124,14 +1124,14 @@ Disables further receive operations. - `wr` Disables further send operations. -## `preopentype`: Enum(`u8`) +## `preopentype`: Variant Identifiers for preopened capabilities. Size: 1 Alignment: 1 -### Variants +### Variant cases - `dir` A pre-opened directory. diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx index 37a49f083..4bf485ba8 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx @@ -15,7 +15,7 @@ ;;; Identifiers for clocks. (typename $clockid - (enum u32 + (enum (@witx tag u32) ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. $realtime @@ -36,7 +36,7 @@ ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. (typename $errno - (enum u16 + (enum (@witx tag u16) ;;; No error occurred. System call completed successfully. $success ;;; Argument list too long. @@ -304,7 +304,7 @@ ;;; The position relative to which to set the offset of the file descriptor. (typename $whence - (enum u8 + (enum (@witx tag u8) ;;; Seek relative to current position. $cur ;;; Seek relative to end-of-file. @@ -325,7 +325,7 @@ ;;; The type of a file descriptor or file. (typename $filetype - (enum u8 + (enum (@witx tag u8) ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $unknown ;;; The file descriptor or file refers to a block device inode. @@ -361,7 +361,7 @@ ;;; File or memory access pattern advisory information. (typename $advice - (enum u8 + (enum (@witx tag u8) ;;; The application has no advice to give on its behavior with respect to the specified data. $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. @@ -481,7 +481,7 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype - (enum u8 + (enum (@witx tag u8) ;;; The time value of clock `subscription_clock::id` has ;;; reached timestamp `subscription_clock::timeout`. $clock @@ -593,7 +593,7 @@ ;;; Signal condition. (typename $signal - (enum u8 + (enum (@witx tag u8) ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. $none @@ -724,7 +724,7 @@ ;;; Identifiers for preopened capabilities. (typename $preopentype - (enum u8 + (enum (@witx tag u8) ;;; A pre-opened directory. $dir ) diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index 1cb642abe..827250111 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -19,14 +19,14 @@ Size: 8 Alignment: 8 -## `clockid`: Enum(`u32`) +## `clockid`: Variant Identifiers for clocks. Size: 4 Alignment: 4 -### Variants +### Variant cases - `realtime` The clock measuring real time. Time value zero corresponds with 1970-01-01T00:00:00Z. @@ -43,7 +43,7 @@ The CPU-time clock associated with the current process. - `thread_cputime_id` The CPU-time clock associated with the current thread. -## `errno`: Enum(`u16`) +## `errno`: Variant Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -53,7 +53,7 @@ Size: 2 Alignment: 2 -### Variants +### Variant cases - `success` No error occurred. System call completed successfully. @@ -455,14 +455,14 @@ Size: 8 Alignment: 8 -## `whence`: Enum(`u8`) +## `whence`: Variant The position relative to which to set the offset of the file descriptor. Size: 1 Alignment: 1 -### Variants +### Variant cases - `set` Seek relative to start-of-file. @@ -495,14 +495,14 @@ Size: 8 Alignment: 8 -## `filetype`: Enum(`u8`) +## `filetype`: Variant The type of a file descriptor or file. Size: 1 Alignment: 1 -### Variants +### Variant cases - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -555,14 +555,14 @@ The type of the file referred to by this directory entry. Offset: 20 -## `advice`: Enum(`u8`) +## `advice`: Variant File or memory access pattern advisory information. Size: 1 Alignment: 1 -### Variants +### Variant cases - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -757,14 +757,14 @@ Size: 8 Alignment: 8 -## `eventtype`: Enum(`u8`) +## `eventtype`: Variant Type of a subscription to an event or its occurrence. Size: 1 Alignment: 1 -### Variants +### Variant cases - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -942,14 +942,14 @@ Size: 4 Alignment: 4 -## `signal`: Enum(`u8`) +## `signal`: Variant Signal condition. Size: 1 Alignment: 1 -### Variants +### Variant cases - `none` No signal. Note that POSIX has special semantics for `kill(pid, 0)`, so this value is reserved. @@ -1121,14 +1121,14 @@ Disables further receive operations. - `wr` Disables further send operations. -## `preopentype`: Enum(`u8`) +## `preopentype`: Variant Identifiers for preopened capabilities. Size: 1 Alignment: 1 -### Variants +### Variant cases - `dir` A pre-opened directory. diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx index b0ccece64..a2da265c2 100644 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -15,7 +15,7 @@ ;;; Identifiers for clocks. (typename $clockid - (enum u32 + (enum (@witx tag u32) ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. $realtime @@ -36,7 +36,7 @@ ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. (typename $errno - (enum u16 + (enum (@witx tag u16) ;;; No error occurred. System call completed successfully. $success ;;; Argument list too long. @@ -304,7 +304,7 @@ ;;; The position relative to which to set the offset of the file descriptor. (typename $whence - (enum u8 + (enum (@witx tag u8) ;;; Seek relative to start-of-file. $set ;;; Seek relative to current position. @@ -327,7 +327,7 @@ ;;; The type of a file descriptor or file. (typename $filetype - (enum u8 + (enum (@witx tag u8) ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $unknown ;;; The file descriptor or file refers to a block device inode. @@ -363,7 +363,7 @@ ;;; File or memory access pattern advisory information. (typename $advice - (enum u8 + (enum (@witx tag u8) ;;; The application has no advice to give on its behavior with respect to the specified data. $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. @@ -483,7 +483,7 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype - (enum u8 + (enum (@witx tag u8) ;;; The time value of clock `subscription_clock::id` has ;;; reached timestamp `subscription_clock::timeout`. $clock @@ -593,7 +593,7 @@ ;;; Signal condition. (typename $signal - (enum u8 + (enum (@witx tag u8) ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. $none @@ -724,7 +724,7 @@ ;;; Identifiers for preopened capabilities. (typename $preopentype - (enum u8 + (enum (@witx tag u8) ;;; A pre-opened directory. $dir ) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 242fcce1c..2e5980ff1 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -185,7 +185,6 @@ impl NamedType { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { - Enum(EnumDatatype), Flags(FlagsDatatype), Record(RecordDatatype), Variant(Variant), @@ -201,7 +200,6 @@ impl Type { pub fn kind(&self) -> &'static str { use Type::*; match self { - Enum(_) => "enum", Flags(_) => "flags", Record(_) => "record", Variant(_) => "variant", @@ -240,18 +238,6 @@ pub enum IntRepr { U64, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct EnumDatatype { - pub repr: IntRepr, - pub variants: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct EnumVariant { - pub name: Id, - pub docs: String, -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsDatatype { pub repr: IntRepr, @@ -278,6 +264,7 @@ pub struct RecordMember { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Variant { + pub tag_repr: IntRepr, pub cases: Vec, } diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index c11529f9e..1ffe718f4 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -50,10 +50,14 @@ impl Type { }, Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), - Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), - Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } => { - TypePassedBy::Pointer + Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Variant(v) => { + if v.cases.iter().all(|c| c.tref.is_none()) { + TypePassedBy::Value(v.tag_repr.into()) + } else { + TypePassedBy::Pointer + } } Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), } diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index 454cac010..fea7202cf 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -68,7 +68,6 @@ impl ToMarkdown for NamedType { impl ToMarkdown for Type { fn generate(&self, node: MdNodeRef) { match self { - Self::Enum(a) => a.generate(node.clone()), Self::Flags(a) => a.generate(node.clone()), Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), @@ -98,32 +97,6 @@ impl ToMarkdown for Type { } } -impl ToMarkdown for EnumDatatype { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Variants")); - - for variant in &self.variants { - let name = variant.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - &variant.docs, - )); - } - - node.content_ref_mut::().r#type = Some(MdType::Enum { - repr: self.repr.type_name().to_owned(), - }); - } -} - impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); @@ -193,7 +166,7 @@ impl ToMarkdown for Variant { MdHeading::new_bullet(), id.as_str(), name, - format!("{}\n", &case.docs).as_str(), + &case.docs, )); if let Some(ty) = &case.tref { ty.generate(n.clone()); @@ -384,8 +357,7 @@ impl TypeRef { Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), - Type::Enum { .. } - | Type::Flags { .. } + Type::Flags { .. } | Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index 1ca3a8794..4c32f9179 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -343,7 +343,6 @@ impl MdNamedType { // being outright flattened. #[derive(Debug)] pub(super) enum MdType { - Enum { repr: String }, Flags { repr: String }, Record, Variant, @@ -359,7 +358,6 @@ pub(super) enum MdType { impl fmt::Display for MdType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Self::Enum { repr } => f.write_fmt(format_args!(": Enum(`{}`)", repr))?, Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index cc4fd0add..ea23fd31a 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -64,7 +64,6 @@ impl Layout for NamedType { impl Type { fn layout(&self, cache: &mut HashMap) -> SizeAlign { match &self { - Type::Enum(e) => e.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), Type::Record(s) => s.layout(cache), Type::Variant(s) => s.mem_size_align(), @@ -139,10 +138,11 @@ impl Layout for Variant { fn mem_size_align(&self) -> SizeAlign { let mut max = SizeAlign { size: 0, align: 0 }; for case in self.cases.iter() { - let mut size = BuiltinType::S32.mem_size_align(); + let mut size = self.tag_repr.mem_size_align(); if let Some(payload) = &case.tref { size.append_field(&payload.mem_size_align()); } + size.size = align_to(size.size, size.align); max.size = max.size.max(size.size); max.align = max.align.max(size.align); } diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index ad9100481..d5ce8c3dd 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -39,6 +39,7 @@ mod kw { wast::custom_keyword!(s64); wast::custom_keyword!(s8); wast::custom_keyword!(string); + wast::custom_keyword!(tag); wast::custom_keyword!(typename); wast::custom_keyword!(u16); wast::custom_keyword!(u32); @@ -333,14 +334,22 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumSyntax<'a> { - pub repr: BuiltinType, + pub repr: Option, pub members: Vec>>, } impl<'a> Parse<'a> for EnumSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let repr = parser.parse()?; + let repr = if parser.peek2::() { + Some(parser.parens(|p| { + p.parse::()?; + p.parse::()?; + p.parse() + })?) + } else { + None + }; let mut members = Vec::new(); members.push(parser.parse()?); while !parser.is_empty() { diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 44ccb54df..d61c9b04e 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -116,7 +116,6 @@ impl TypeRef { impl Type { pub fn to_sexpr(&self) -> SExpr { match self { - Type::Enum(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), Type::Record(a) => a.to_sexpr(), Type::Variant(a) => a.to_sexpr(), @@ -138,18 +137,6 @@ impl Type { } } -impl EnumDatatype { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("enum"), self.repr.to_sexpr()]; - let variants = self - .variants - .iter() - .map(|v| SExpr::docs(&v.docs, v.name.to_sexpr())) - .collect::>(); - SExpr::Vec([header, variants].concat()) - } -} - impl FlagsDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; @@ -185,19 +172,28 @@ impl RecordDatatype { impl Variant { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("variant")]; - let cases = self - .cases - .iter() - .map(|m| { - let mut list = vec![SExpr::word("case"), m.name.to_sexpr()]; - if let Some(ty) = &m.tref { - list.push(ty.to_sexpr()); + let mut list = Vec::new(); + if self.cases.iter().all(|c| c.tref.is_none()) { + list.push(SExpr::word("enum")); + list.push(SExpr::Vec(vec![ + SExpr::word("@witx"), + SExpr::word("tag"), + self.tag_repr.to_sexpr(), + ])); + for case in self.cases.iter() { + list.push(SExpr::docs(&case.docs, case.name.to_sexpr())); + } + } else { + list.push(SExpr::word("variant")); + for case in self.cases.iter() { + let mut case_expr = vec![SExpr::word("case"), case.name.to_sexpr()]; + if let Some(ty) = &case.tref { + case_expr.push(ty.to_sexpr()); } - SExpr::docs(&m.docs, SExpr::Vec(list)) - }) - .collect::>(); - SExpr::Vec([header, cases].concat()) + list.push(SExpr::docs(&case.docs, SExpr::Vec(case_expr))); + } + } + SExpr::Vec(list) } } diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs index 2d03797be..5b88c0c02 100644 --- a/proposals/clocks/tools/witx/src/representation.rs +++ b/proposals/clocks/tools/witx/src/representation.rs @@ -1,6 +1,6 @@ use crate::{ - BuiltinType, EnumDatatype, FlagsDatatype, IntRepr, NamedType, RecordDatatype, Type, TypeRef, - UnionDatatype, + BuiltinType, FlagsDatatype, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, + Variant, }; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. @@ -69,15 +69,15 @@ impl Representable for IntRepr { } } -impl Representable for EnumDatatype { +impl Representable for Variant { fn representable(&self, by: &Self) -> RepEquality { // Integer representation must be compatible - if self.repr.representable(&by.repr) == RepEquality::NotEq { + if self.tag_repr.representable(&by.tag_repr) == RepEquality::NotEq { return RepEquality::NotEq; } // For each variant in self, must have variant of same name and position in by: - for (ix, v) in self.variants.iter().enumerate() { - if let Some(by_v) = by.variants.get(ix) { + for (ix, v) in self.cases.iter().enumerate() { + if let Some(by_v) = by.cases.get(ix) { if by_v.name != v.name { return RepEquality::NotEq; } @@ -85,10 +85,10 @@ impl Representable for EnumDatatype { return RepEquality::NotEq; } } - if by.variants.len() > self.variants.len() { + if by.cases.len() > self.cases.len() { RepEquality::Superset } else { - self.repr.representable(&by.repr) + self.tag_repr.representable(&by.tag_repr) } } } @@ -203,7 +203,7 @@ impl Representable for NamedType { impl Representable for Type { fn representable(&self, by: &Self) -> RepEquality { match (&self, &by) { - (Type::Enum(s), Type::Enum(b)) => s.representable(b), + (Type::Variant(s), Type::Variant(b)) => s.representable(b), (Type::Flags(s), Type::Flags(b)) => s.representable(b), (Type::Record(s), Type::Record(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), @@ -267,13 +267,13 @@ mod test { #[test] fn enum_() { - let base = def_type("a", "(typename $a (enum u32 $b $c))"); - let extra_variant = def_type("a", "(typename $a (enum u32 $b $c $d))"); + let base = def_type("a", "(typename $a (enum $b $c))"); + let extra_variant = def_type("a", "(typename $a (enum $b $c $d))"); assert_eq!(base.representable(&extra_variant), RepEquality::Superset); assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); - let smaller_size = def_type("a", "(typename $a (enum u16 $b $c))"); + let smaller_size = def_type("a", "(typename $a (enum (@witx tag u16) $b $c))"); assert_eq!(smaller_size.representable(&base), RepEquality::Superset); assert_eq!( smaller_size.representable(&extra_variant), @@ -285,12 +285,12 @@ mod test { fn union() { let base = def_type( "a", - "(typename $tag (enum u8 $b $c)) + "(typename $tag (enum (@witx tag u8) $b $c)) (typename $a (union $tag (field $b u32) (field $c f32)))", ); let extra_variant = def_type( "a", - "(typename $tag (enum u8 $b $c $d)) + "(typename $tag (enum (@witx tag u8) $b $c $d)) (typename $a (union $tag (field $b u32) (field $c f32) (field $d f64)))", ); @@ -299,7 +299,7 @@ mod test { let other_ordering = def_type( "a", - "(typename $tag (enum u8 $b $c)) + "(typename $tag (enum (@witx tag u8) $b $c)) (typename $a (union $tag (field $c f32) (field $b u32)))", ); assert_eq!(base.representable(&other_ordering), RepEquality::Eq); diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index b51596fe3..279cf594c 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -5,11 +5,10 @@ use crate::{ ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, VariantSyntax, }, - BuiltinType, Constant, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, - FlagsMember, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, - InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypePassedBy, TypeRef, - UnionDatatype, UnionVariant, + BuiltinType, Case, Constant, Definition, Entry, FlagsDatatype, FlagsMember, HandleDatatype, Id, + IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, + ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, + RecordMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, Variant, }; use std::collections::{hash_map, HashMap}; use std::path::Path; @@ -50,6 +49,12 @@ pub enum ValidationError { reason: String, location: Location, }, + #[error("Invalid union tag `{name}`: {reason}")] + InvalidUnionTag { + name: String, + reason: String, + location: Location, + }, } impl ValidationError { @@ -62,7 +67,8 @@ impl ValidationError { | InvalidRepr { location, .. } | InvalidFirstResultType { location, .. } | AnonymousRecord { location, .. } - | InvalidUnionField { location, .. } => { + | InvalidUnionField { location, .. } + | InvalidUnionTag { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } NameAlreadyExists { @@ -269,7 +275,7 @@ impl DocValidationScope<'_> { }) } other => Ok(TypeRef::Value(Rc::new(match other { - TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), + TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), @@ -293,20 +299,27 @@ impl DocValidationScope<'_> { &self, syntax: &EnumSyntax, span: wast::Span, - ) -> Result { + ) -> Result { let mut enum_scope = IdentValidation::new(); - let repr = self.validate_int_repr(&syntax.repr, span)?; - let variants = syntax + let tag_repr = match &syntax.repr { + Some(repr) => self.validate_int_repr(repr, span)?, + None => IntRepr::U32, + }; + let cases = syntax .members .iter() .map(|i| { let name = enum_scope.introduce(i.item.name(), self.location(i.item.span()))?; let docs = i.comments.docs(); - Ok(EnumVariant { name, docs }) + Ok(Case { + name, + tref: None, + docs, + }) }) - .collect::, _>>()?; + .collect::, _>>()?; - Ok(EnumDatatype { repr, variants }) + Ok(Variant { tag_repr, cases }) } fn validate_flags( @@ -361,12 +374,18 @@ impl DocValidationScope<'_> { Some(Entry::Typename(weak_ref)) => { let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); match &*named_dt.type_() { - Type::Enum(e) => { - let uses = e - .variants - .iter() - .map(|v| (v.name.clone(), false)) - .collect::>(); + Type::Variant(e) => { + let mut uses = HashMap::new(); + for c in e.cases.iter() { + if c.tref.is_some() { + return Err(ValidationError::InvalidUnionTag { + name: syntax.tag.name().to_string(), + location: self.location(syntax.tag.span()), + reason: format!("all variant cases should have empty payloads"), + }); + } + uses.insert(c.name.clone(), false); + } Ok((named_dt, uses)) } other => Err(ValidationError::WrongKindName { diff --git a/proposals/clocks/tools/witx/tests/anonymous.rs b/proposals/clocks/tools/witx/tests/anonymous.rs index 2bff69960..723a36030 100644 --- a/proposals/clocks/tools/witx/tests/anonymous.rs +++ b/proposals/clocks/tools/witx/tests/anonymous.rs @@ -13,11 +13,11 @@ fn anonymous_types() { assert!(is_anonymous_record_err(pointer_to_record)); let pointer_to_union = witx::parse( - "(typename $tag (enum u8 $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", + "(typename $tag (enum $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", ); assert!(is_anonymous_record_err(pointer_to_union)); - let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum u32 $b)))"); + let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum $b)))"); assert!(is_anonymous_record_err(pointer_to_enum)); let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags u32 $b)))"); @@ -36,7 +36,7 @@ fn anonymous_types() { assert!(is_anonymous_record_err(record_in_record)); let union_in_record = witx::parse( - "(typename $tag (enum u8 $c)) (typename $a (record (field $b (union $tag (field $c u8)))))", + "(typename $tag (enum $c)) (typename $a (record (field $b (union $tag (field $c u8)))))", ); assert!(is_anonymous_record_err(union_in_record)); diff --git a/proposals/clocks/tools/witx/tests/union.rs b/proposals/clocks/tools/witx/tests/union.rs index 732b5c007..30fb4dfdf 100644 --- a/proposals/clocks/tools/witx/tests/union.rs +++ b/proposals/clocks/tools/witx/tests/union.rs @@ -4,7 +4,7 @@ use witx::{Id, Representable}; #[test] fn one_variant_union() { let d = witx::parse( - "(typename $tag (enum u8 $c)) + "(typename $tag (enum $c)) (typename $u (union $tag (field $c u8)))", ); assert!(d.is_ok()); @@ -13,14 +13,14 @@ fn one_variant_union() { #[test] fn two_variant_union() { let d1 = witx::parse( - "(typename $tag (enum u8 $a $b)) + "(typename $tag (enum $a $b)) (typename $u (union $tag (field $a u8) (field $b u16)))", ); assert!(d1.is_ok(), "d1 is ok"); // Fields can come in whatever order: let d2 = witx::parse( - "(typename $tag (enum u8 $a $b)) + "(typename $tag (enum $a $b)) (typename $u (union $tag (field $b u16) (field $a u8)))", ); assert!(d2.is_ok(), "d2 is ok"); @@ -42,7 +42,7 @@ fn two_variant_union() { // Tag order doesnt matter for validation, but does for rep equality let d3 = witx::parse( - "(typename $tag (enum u8 $b $a)) + "(typename $tag (enum $b $a)) (typename $u (union $tag (field $b u16) (field $a u8)))", ); assert!(d3.is_ok(), "d2 is ok"); @@ -57,13 +57,13 @@ fn two_variant_union() { #[test] fn empty_variant_unions() { let d1 = witx::parse( - "(typename $tag (enum u8 $a $b)) + "(typename $tag (enum $a $b)) (typename $u (union $tag (empty $a) (field $b u16)))", ); assert!(d1.is_ok(), "d1 is ok"); let d2 = witx::parse( - "(typename $tag (enum u8 $a $b)) + "(typename $tag (enum $a $b)) (typename $u (union $tag (empty $a) (empty $b)))", ); assert!(d2.is_ok(), "d2 is ok"); @@ -72,7 +72,7 @@ fn empty_variant_unions() { #[test] fn many_variant_unions() { let d1 = witx::parse( - "(typename $tag (enum u32 $a $b $c $d $e $f $g $h $i $j $k $l $m)) + "(typename $tag (enum $a $b $c $d $e $f $g $h $i $j $k $l $m)) (typename $u (union $tag (field $a u8) @@ -114,7 +114,7 @@ fn wrong_kind_tag_union() { #[test] fn bad_field_unions() { let d = witx::parse( - "(typename $tag (enum u8 $c)) + "(typename $tag (enum $c)) (typename $u (union $tag (field $b u8)))", ); let (name, reason) = union_field_err(d).expect("bad field union 1"); @@ -125,7 +125,7 @@ fn bad_field_unions() { ); let d = witx::parse( - "(typename $tag (enum u8 $c)) + "(typename $tag (enum $c)) (typename $u (union $tag (field $c f32) (field $b u8)))", ); let (name, reason) = union_field_err(d).expect("bad field union 2"); @@ -136,7 +136,7 @@ fn bad_field_unions() { ); let d = witx::parse( - "(typename $tag (enum u8 $c $d)) + "(typename $tag (enum $c $d)) (typename $u (union $tag (field $c f32)))", ); let (name, reason) = union_field_err(d).expect("bad field union 3"); From b0a9a20b294fd02497b760018a588733b5d8d962 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 10:43:05 -0800 Subject: [PATCH 0839/1772] Implement enums in terms of `Variant` --- proposals/random/phases/ephemeral/docs.md | 28 ++++----- .../phases/ephemeral/witx/typenames.witx | 14 ++--- .../random/phases/old/snapshot_0/docs.md | 32 +++++------ .../phases/old/snapshot_0/witx/typenames.witx | 16 +++--- proposals/random/phases/snapshot/docs.md | 32 +++++------ .../phases/snapshot/witx/typenames.witx | 16 +++--- proposals/random/tools/witx/src/ast.rs | 15 +---- proposals/random/tools/witx/src/coretypes.rs | 10 +++- proposals/random/tools/witx/src/docs/ast.rs | 32 +---------- proposals/random/tools/witx/src/docs/md.rs | 2 - proposals/random/tools/witx/src/layout.rs | 4 +- proposals/random/tools/witx/src/parser.rs | 13 ++++- proposals/random/tools/witx/src/render.rs | 46 +++++++-------- .../random/tools/witx/src/representation.rs | 30 +++++----- proposals/random/tools/witx/src/validate.rs | 57 ++++++++++++------- .../random/tools/witx/tests/anonymous.rs | 6 +- proposals/random/tools/witx/tests/union.rs | 20 +++---- 17 files changed, 179 insertions(+), 194 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 3d317dae7..3c9b13531 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -22,14 +22,14 @@ Size: 8 Alignment: 8 -## `clockid`: Enum(`u32`) +## `clockid`: Variant Identifiers for clocks. Size: 4 Alignment: 4 -### Variants +### Variant cases - `realtime` The clock measuring real time. Time value zero corresponds with 1970-01-01T00:00:00Z. @@ -40,7 +40,7 @@ real time, whose value cannot be adjusted and which cannot have negative clock jumps. The epoch of this clock is undefined. The absolute time value of this clock therefore has no meaning. -## `errno`: Enum(`u16`) +## `errno`: Variant Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -50,7 +50,7 @@ Size: 2 Alignment: 2 -### Variants +### Variant cases - `success` No error occurred. System call completed successfully. @@ -463,14 +463,14 @@ Size: 8 Alignment: 8 -## `whence`: Enum(`u8`) +## `whence`: Variant The position relative to which to set the offset of the file descriptor. Size: 1 Alignment: 1 -### Variants +### Variant cases - `set` Seek relative to start-of-file. @@ -501,14 +501,14 @@ Size: 8 Alignment: 8 -## `filetype`: Enum(`u8`) +## `filetype`: Variant The type of a file descriptor or file. Size: 1 Alignment: 1 -### Variants +### Variant cases - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -564,14 +564,14 @@ The length of the name of the directory entry. Offset: 20 -## `advice`: Enum(`u8`) +## `advice`: Variant File or memory access pattern advisory information. Size: 1 Alignment: 1 -### Variants +### Variant cases - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -805,14 +805,14 @@ Size: 8 Alignment: 8 -## `eventtype`: Enum(`u8`) +## `eventtype`: Variant Type of a subscription to an event or its occurrence. Size: 1 Alignment: 1 -### Variants +### Variant cases - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -1051,14 +1051,14 @@ Disables further receive operations. - `wr` Disables further send operations. -## `preopentype`: Enum(`u8`) +## `preopentype`: Variant Identifiers for preopened capabilities. Size: 1 Alignment: 1 -### Variants +### Variant cases - `dir` A pre-opened directory. diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index c456a99a7..f2cde8272 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -18,7 +18,7 @@ ;;; Identifiers for clocks. (typename $clockid - (enum u32 + (enum (@witx tag u32) ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. $realtime @@ -35,7 +35,7 @@ ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. (typename $errno - (enum u16 + (enum (@witx tag u16) ;;; No error occurred. System call completed successfully. $success ;;; Argument list too long. @@ -312,7 +312,7 @@ ;;; The position relative to which to set the offset of the file descriptor. (typename $whence - (enum u8 + (enum (@witx tag u8) ;;; Seek relative to start-of-file. $set ;;; Seek relative to current position. @@ -336,7 +336,7 @@ ;;; The type of a file descriptor or file. (typename $filetype - (enum u8 + (enum (@witx tag u8) ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $unknown ;;; The file descriptor or file refers to a block device inode. @@ -374,7 +374,7 @@ ;;; File or memory access pattern advisory information. (typename $advice - (enum u8 + (enum (@witx tag u8) ;;; The application has no advice to give on its behavior with respect to the specified data. $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. @@ -527,7 +527,7 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype - (enum u8 + (enum (@witx tag u8) ;;; The time value of clock `subscription_clock::id` has ;;; reached timestamp `subscription_clock::timeout`. $clock @@ -675,7 +675,7 @@ ;;; Identifiers for preopened capabilities. (typename $preopentype - (enum u8 + (enum (@witx tag u8) ;;; A pre-opened directory. $dir ) diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index b56aa1f5e..5c9543331 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -19,14 +19,14 @@ Size: 8 Alignment: 8 -## `clockid`: Enum(`u32`) +## `clockid`: Variant Identifiers for clocks. Size: 4 Alignment: 4 -### Variants +### Variant cases - `realtime` The clock measuring real time. Time value zero corresponds with 1970-01-01T00:00:00Z. @@ -43,7 +43,7 @@ The CPU-time clock associated with the current process. - `thread_cputime_id` The CPU-time clock associated with the current thread. -## `errno`: Enum(`u16`) +## `errno`: Variant Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -53,7 +53,7 @@ Size: 2 Alignment: 2 -### Variants +### Variant cases - `success` No error occurred. System call completed successfully. @@ -455,14 +455,14 @@ Size: 8 Alignment: 8 -## `whence`: Enum(`u8`) +## `whence`: Variant The position relative to which to set the offset of the file descriptor. Size: 1 Alignment: 1 -### Variants +### Variant cases - `cur` Seek relative to current position. @@ -493,14 +493,14 @@ Size: 8 Alignment: 8 -## `filetype`: Enum(`u8`) +## `filetype`: Variant The type of a file descriptor or file. Size: 1 Alignment: 1 -### Variants +### Variant cases - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -553,14 +553,14 @@ The type of the file referred to by this directory entry. Offset: 20 -## `advice`: Enum(`u8`) +## `advice`: Variant File or memory access pattern advisory information. Size: 1 Alignment: 1 -### Variants +### Variant cases - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -755,14 +755,14 @@ Size: 8 Alignment: 8 -## `eventtype`: Enum(`u8`) +## `eventtype`: Variant Type of a subscription to an event or its occurrence. Size: 1 Alignment: 1 -### Variants +### Variant cases - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -945,14 +945,14 @@ Size: 4 Alignment: 4 -## `signal`: Enum(`u8`) +## `signal`: Variant Signal condition. Size: 1 Alignment: 1 -### Variants +### Variant cases - `none` No signal. Note that POSIX has special semantics for `kill(pid, 0)`, so this value is reserved. @@ -1124,14 +1124,14 @@ Disables further receive operations. - `wr` Disables further send operations. -## `preopentype`: Enum(`u8`) +## `preopentype`: Variant Identifiers for preopened capabilities. Size: 1 Alignment: 1 -### Variants +### Variant cases - `dir` A pre-opened directory. diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx index 37a49f083..4bf485ba8 100644 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/random/phases/old/snapshot_0/witx/typenames.witx @@ -15,7 +15,7 @@ ;;; Identifiers for clocks. (typename $clockid - (enum u32 + (enum (@witx tag u32) ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. $realtime @@ -36,7 +36,7 @@ ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. (typename $errno - (enum u16 + (enum (@witx tag u16) ;;; No error occurred. System call completed successfully. $success ;;; Argument list too long. @@ -304,7 +304,7 @@ ;;; The position relative to which to set the offset of the file descriptor. (typename $whence - (enum u8 + (enum (@witx tag u8) ;;; Seek relative to current position. $cur ;;; Seek relative to end-of-file. @@ -325,7 +325,7 @@ ;;; The type of a file descriptor or file. (typename $filetype - (enum u8 + (enum (@witx tag u8) ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $unknown ;;; The file descriptor or file refers to a block device inode. @@ -361,7 +361,7 @@ ;;; File or memory access pattern advisory information. (typename $advice - (enum u8 + (enum (@witx tag u8) ;;; The application has no advice to give on its behavior with respect to the specified data. $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. @@ -481,7 +481,7 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype - (enum u8 + (enum (@witx tag u8) ;;; The time value of clock `subscription_clock::id` has ;;; reached timestamp `subscription_clock::timeout`. $clock @@ -593,7 +593,7 @@ ;;; Signal condition. (typename $signal - (enum u8 + (enum (@witx tag u8) ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. $none @@ -724,7 +724,7 @@ ;;; Identifiers for preopened capabilities. (typename $preopentype - (enum u8 + (enum (@witx tag u8) ;;; A pre-opened directory. $dir ) diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index 1cb642abe..827250111 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -19,14 +19,14 @@ Size: 8 Alignment: 8 -## `clockid`: Enum(`u32`) +## `clockid`: Variant Identifiers for clocks. Size: 4 Alignment: 4 -### Variants +### Variant cases - `realtime` The clock measuring real time. Time value zero corresponds with 1970-01-01T00:00:00Z. @@ -43,7 +43,7 @@ The CPU-time clock associated with the current process. - `thread_cputime_id` The CPU-time clock associated with the current thread. -## `errno`: Enum(`u16`) +## `errno`: Variant Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -53,7 +53,7 @@ Size: 2 Alignment: 2 -### Variants +### Variant cases - `success` No error occurred. System call completed successfully. @@ -455,14 +455,14 @@ Size: 8 Alignment: 8 -## `whence`: Enum(`u8`) +## `whence`: Variant The position relative to which to set the offset of the file descriptor. Size: 1 Alignment: 1 -### Variants +### Variant cases - `set` Seek relative to start-of-file. @@ -495,14 +495,14 @@ Size: 8 Alignment: 8 -## `filetype`: Enum(`u8`) +## `filetype`: Variant The type of a file descriptor or file. Size: 1 Alignment: 1 -### Variants +### Variant cases - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -555,14 +555,14 @@ The type of the file referred to by this directory entry. Offset: 20 -## `advice`: Enum(`u8`) +## `advice`: Variant File or memory access pattern advisory information. Size: 1 Alignment: 1 -### Variants +### Variant cases - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -757,14 +757,14 @@ Size: 8 Alignment: 8 -## `eventtype`: Enum(`u8`) +## `eventtype`: Variant Type of a subscription to an event or its occurrence. Size: 1 Alignment: 1 -### Variants +### Variant cases - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -942,14 +942,14 @@ Size: 4 Alignment: 4 -## `signal`: Enum(`u8`) +## `signal`: Variant Signal condition. Size: 1 Alignment: 1 -### Variants +### Variant cases - `none` No signal. Note that POSIX has special semantics for `kill(pid, 0)`, so this value is reserved. @@ -1121,14 +1121,14 @@ Disables further receive operations. - `wr` Disables further send operations. -## `preopentype`: Enum(`u8`) +## `preopentype`: Variant Identifiers for preopened capabilities. Size: 1 Alignment: 1 -### Variants +### Variant cases - `dir` A pre-opened directory. diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx index b0ccece64..a2da265c2 100644 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -15,7 +15,7 @@ ;;; Identifiers for clocks. (typename $clockid - (enum u32 + (enum (@witx tag u32) ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. $realtime @@ -36,7 +36,7 @@ ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. (typename $errno - (enum u16 + (enum (@witx tag u16) ;;; No error occurred. System call completed successfully. $success ;;; Argument list too long. @@ -304,7 +304,7 @@ ;;; The position relative to which to set the offset of the file descriptor. (typename $whence - (enum u8 + (enum (@witx tag u8) ;;; Seek relative to start-of-file. $set ;;; Seek relative to current position. @@ -327,7 +327,7 @@ ;;; The type of a file descriptor or file. (typename $filetype - (enum u8 + (enum (@witx tag u8) ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $unknown ;;; The file descriptor or file refers to a block device inode. @@ -363,7 +363,7 @@ ;;; File or memory access pattern advisory information. (typename $advice - (enum u8 + (enum (@witx tag u8) ;;; The application has no advice to give on its behavior with respect to the specified data. $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. @@ -483,7 +483,7 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype - (enum u8 + (enum (@witx tag u8) ;;; The time value of clock `subscription_clock::id` has ;;; reached timestamp `subscription_clock::timeout`. $clock @@ -593,7 +593,7 @@ ;;; Signal condition. (typename $signal - (enum u8 + (enum (@witx tag u8) ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. $none @@ -724,7 +724,7 @@ ;;; Identifiers for preopened capabilities. (typename $preopentype - (enum u8 + (enum (@witx tag u8) ;;; A pre-opened directory. $dir ) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 242fcce1c..2e5980ff1 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -185,7 +185,6 @@ impl NamedType { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { - Enum(EnumDatatype), Flags(FlagsDatatype), Record(RecordDatatype), Variant(Variant), @@ -201,7 +200,6 @@ impl Type { pub fn kind(&self) -> &'static str { use Type::*; match self { - Enum(_) => "enum", Flags(_) => "flags", Record(_) => "record", Variant(_) => "variant", @@ -240,18 +238,6 @@ pub enum IntRepr { U64, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct EnumDatatype { - pub repr: IntRepr, - pub variants: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct EnumVariant { - pub name: Id, - pub docs: String, -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsDatatype { pub repr: IntRepr, @@ -278,6 +264,7 @@ pub struct RecordMember { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Variant { + pub tag_repr: IntRepr, pub cases: Vec, } diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index c11529f9e..1ffe718f4 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -50,10 +50,14 @@ impl Type { }, Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), - Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), - Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } => { - TypePassedBy::Pointer + Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Variant(v) => { + if v.cases.iter().all(|c| c.tref.is_none()) { + TypePassedBy::Value(v.tag_repr.into()) + } else { + TypePassedBy::Pointer + } } Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), } diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index 454cac010..fea7202cf 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -68,7 +68,6 @@ impl ToMarkdown for NamedType { impl ToMarkdown for Type { fn generate(&self, node: MdNodeRef) { match self { - Self::Enum(a) => a.generate(node.clone()), Self::Flags(a) => a.generate(node.clone()), Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), @@ -98,32 +97,6 @@ impl ToMarkdown for Type { } } -impl ToMarkdown for EnumDatatype { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Variants")); - - for variant in &self.variants { - let name = variant.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - &variant.docs, - )); - } - - node.content_ref_mut::().r#type = Some(MdType::Enum { - repr: self.repr.type_name().to_owned(), - }); - } -} - impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); @@ -193,7 +166,7 @@ impl ToMarkdown for Variant { MdHeading::new_bullet(), id.as_str(), name, - format!("{}\n", &case.docs).as_str(), + &case.docs, )); if let Some(ty) = &case.tref { ty.generate(n.clone()); @@ -384,8 +357,7 @@ impl TypeRef { Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), - Type::Enum { .. } - | Type::Flags { .. } + Type::Flags { .. } | Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index 1ca3a8794..4c32f9179 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -343,7 +343,6 @@ impl MdNamedType { // being outright flattened. #[derive(Debug)] pub(super) enum MdType { - Enum { repr: String }, Flags { repr: String }, Record, Variant, @@ -359,7 +358,6 @@ pub(super) enum MdType { impl fmt::Display for MdType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Self::Enum { repr } => f.write_fmt(format_args!(": Enum(`{}`)", repr))?, Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index cc4fd0add..ea23fd31a 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -64,7 +64,6 @@ impl Layout for NamedType { impl Type { fn layout(&self, cache: &mut HashMap) -> SizeAlign { match &self { - Type::Enum(e) => e.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), Type::Record(s) => s.layout(cache), Type::Variant(s) => s.mem_size_align(), @@ -139,10 +138,11 @@ impl Layout for Variant { fn mem_size_align(&self) -> SizeAlign { let mut max = SizeAlign { size: 0, align: 0 }; for case in self.cases.iter() { - let mut size = BuiltinType::S32.mem_size_align(); + let mut size = self.tag_repr.mem_size_align(); if let Some(payload) = &case.tref { size.append_field(&payload.mem_size_align()); } + size.size = align_to(size.size, size.align); max.size = max.size.max(size.size); max.align = max.align.max(size.align); } diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index ad9100481..d5ce8c3dd 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -39,6 +39,7 @@ mod kw { wast::custom_keyword!(s64); wast::custom_keyword!(s8); wast::custom_keyword!(string); + wast::custom_keyword!(tag); wast::custom_keyword!(typename); wast::custom_keyword!(u16); wast::custom_keyword!(u32); @@ -333,14 +334,22 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumSyntax<'a> { - pub repr: BuiltinType, + pub repr: Option, pub members: Vec>>, } impl<'a> Parse<'a> for EnumSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let repr = parser.parse()?; + let repr = if parser.peek2::() { + Some(parser.parens(|p| { + p.parse::()?; + p.parse::()?; + p.parse() + })?) + } else { + None + }; let mut members = Vec::new(); members.push(parser.parse()?); while !parser.is_empty() { diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 44ccb54df..d61c9b04e 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -116,7 +116,6 @@ impl TypeRef { impl Type { pub fn to_sexpr(&self) -> SExpr { match self { - Type::Enum(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), Type::Record(a) => a.to_sexpr(), Type::Variant(a) => a.to_sexpr(), @@ -138,18 +137,6 @@ impl Type { } } -impl EnumDatatype { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("enum"), self.repr.to_sexpr()]; - let variants = self - .variants - .iter() - .map(|v| SExpr::docs(&v.docs, v.name.to_sexpr())) - .collect::>(); - SExpr::Vec([header, variants].concat()) - } -} - impl FlagsDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; @@ -185,19 +172,28 @@ impl RecordDatatype { impl Variant { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("variant")]; - let cases = self - .cases - .iter() - .map(|m| { - let mut list = vec![SExpr::word("case"), m.name.to_sexpr()]; - if let Some(ty) = &m.tref { - list.push(ty.to_sexpr()); + let mut list = Vec::new(); + if self.cases.iter().all(|c| c.tref.is_none()) { + list.push(SExpr::word("enum")); + list.push(SExpr::Vec(vec![ + SExpr::word("@witx"), + SExpr::word("tag"), + self.tag_repr.to_sexpr(), + ])); + for case in self.cases.iter() { + list.push(SExpr::docs(&case.docs, case.name.to_sexpr())); + } + } else { + list.push(SExpr::word("variant")); + for case in self.cases.iter() { + let mut case_expr = vec![SExpr::word("case"), case.name.to_sexpr()]; + if let Some(ty) = &case.tref { + case_expr.push(ty.to_sexpr()); } - SExpr::docs(&m.docs, SExpr::Vec(list)) - }) - .collect::>(); - SExpr::Vec([header, cases].concat()) + list.push(SExpr::docs(&case.docs, SExpr::Vec(case_expr))); + } + } + SExpr::Vec(list) } } diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs index 2d03797be..5b88c0c02 100644 --- a/proposals/random/tools/witx/src/representation.rs +++ b/proposals/random/tools/witx/src/representation.rs @@ -1,6 +1,6 @@ use crate::{ - BuiltinType, EnumDatatype, FlagsDatatype, IntRepr, NamedType, RecordDatatype, Type, TypeRef, - UnionDatatype, + BuiltinType, FlagsDatatype, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, + Variant, }; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. @@ -69,15 +69,15 @@ impl Representable for IntRepr { } } -impl Representable for EnumDatatype { +impl Representable for Variant { fn representable(&self, by: &Self) -> RepEquality { // Integer representation must be compatible - if self.repr.representable(&by.repr) == RepEquality::NotEq { + if self.tag_repr.representable(&by.tag_repr) == RepEquality::NotEq { return RepEquality::NotEq; } // For each variant in self, must have variant of same name and position in by: - for (ix, v) in self.variants.iter().enumerate() { - if let Some(by_v) = by.variants.get(ix) { + for (ix, v) in self.cases.iter().enumerate() { + if let Some(by_v) = by.cases.get(ix) { if by_v.name != v.name { return RepEquality::NotEq; } @@ -85,10 +85,10 @@ impl Representable for EnumDatatype { return RepEquality::NotEq; } } - if by.variants.len() > self.variants.len() { + if by.cases.len() > self.cases.len() { RepEquality::Superset } else { - self.repr.representable(&by.repr) + self.tag_repr.representable(&by.tag_repr) } } } @@ -203,7 +203,7 @@ impl Representable for NamedType { impl Representable for Type { fn representable(&self, by: &Self) -> RepEquality { match (&self, &by) { - (Type::Enum(s), Type::Enum(b)) => s.representable(b), + (Type::Variant(s), Type::Variant(b)) => s.representable(b), (Type::Flags(s), Type::Flags(b)) => s.representable(b), (Type::Record(s), Type::Record(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), @@ -267,13 +267,13 @@ mod test { #[test] fn enum_() { - let base = def_type("a", "(typename $a (enum u32 $b $c))"); - let extra_variant = def_type("a", "(typename $a (enum u32 $b $c $d))"); + let base = def_type("a", "(typename $a (enum $b $c))"); + let extra_variant = def_type("a", "(typename $a (enum $b $c $d))"); assert_eq!(base.representable(&extra_variant), RepEquality::Superset); assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); - let smaller_size = def_type("a", "(typename $a (enum u16 $b $c))"); + let smaller_size = def_type("a", "(typename $a (enum (@witx tag u16) $b $c))"); assert_eq!(smaller_size.representable(&base), RepEquality::Superset); assert_eq!( smaller_size.representable(&extra_variant), @@ -285,12 +285,12 @@ mod test { fn union() { let base = def_type( "a", - "(typename $tag (enum u8 $b $c)) + "(typename $tag (enum (@witx tag u8) $b $c)) (typename $a (union $tag (field $b u32) (field $c f32)))", ); let extra_variant = def_type( "a", - "(typename $tag (enum u8 $b $c $d)) + "(typename $tag (enum (@witx tag u8) $b $c $d)) (typename $a (union $tag (field $b u32) (field $c f32) (field $d f64)))", ); @@ -299,7 +299,7 @@ mod test { let other_ordering = def_type( "a", - "(typename $tag (enum u8 $b $c)) + "(typename $tag (enum (@witx tag u8) $b $c)) (typename $a (union $tag (field $c f32) (field $b u32)))", ); assert_eq!(base.representable(&other_ordering), RepEquality::Eq); diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index b51596fe3..279cf594c 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -5,11 +5,10 @@ use crate::{ ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, VariantSyntax, }, - BuiltinType, Constant, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, - FlagsMember, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, - InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypePassedBy, TypeRef, - UnionDatatype, UnionVariant, + BuiltinType, Case, Constant, Definition, Entry, FlagsDatatype, FlagsMember, HandleDatatype, Id, + IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, + ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, + RecordMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, Variant, }; use std::collections::{hash_map, HashMap}; use std::path::Path; @@ -50,6 +49,12 @@ pub enum ValidationError { reason: String, location: Location, }, + #[error("Invalid union tag `{name}`: {reason}")] + InvalidUnionTag { + name: String, + reason: String, + location: Location, + }, } impl ValidationError { @@ -62,7 +67,8 @@ impl ValidationError { | InvalidRepr { location, .. } | InvalidFirstResultType { location, .. } | AnonymousRecord { location, .. } - | InvalidUnionField { location, .. } => { + | InvalidUnionField { location, .. } + | InvalidUnionTag { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } NameAlreadyExists { @@ -269,7 +275,7 @@ impl DocValidationScope<'_> { }) } other => Ok(TypeRef::Value(Rc::new(match other { - TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), + TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), @@ -293,20 +299,27 @@ impl DocValidationScope<'_> { &self, syntax: &EnumSyntax, span: wast::Span, - ) -> Result { + ) -> Result { let mut enum_scope = IdentValidation::new(); - let repr = self.validate_int_repr(&syntax.repr, span)?; - let variants = syntax + let tag_repr = match &syntax.repr { + Some(repr) => self.validate_int_repr(repr, span)?, + None => IntRepr::U32, + }; + let cases = syntax .members .iter() .map(|i| { let name = enum_scope.introduce(i.item.name(), self.location(i.item.span()))?; let docs = i.comments.docs(); - Ok(EnumVariant { name, docs }) + Ok(Case { + name, + tref: None, + docs, + }) }) - .collect::, _>>()?; + .collect::, _>>()?; - Ok(EnumDatatype { repr, variants }) + Ok(Variant { tag_repr, cases }) } fn validate_flags( @@ -361,12 +374,18 @@ impl DocValidationScope<'_> { Some(Entry::Typename(weak_ref)) => { let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); match &*named_dt.type_() { - Type::Enum(e) => { - let uses = e - .variants - .iter() - .map(|v| (v.name.clone(), false)) - .collect::>(); + Type::Variant(e) => { + let mut uses = HashMap::new(); + for c in e.cases.iter() { + if c.tref.is_some() { + return Err(ValidationError::InvalidUnionTag { + name: syntax.tag.name().to_string(), + location: self.location(syntax.tag.span()), + reason: format!("all variant cases should have empty payloads"), + }); + } + uses.insert(c.name.clone(), false); + } Ok((named_dt, uses)) } other => Err(ValidationError::WrongKindName { diff --git a/proposals/random/tools/witx/tests/anonymous.rs b/proposals/random/tools/witx/tests/anonymous.rs index 2bff69960..723a36030 100644 --- a/proposals/random/tools/witx/tests/anonymous.rs +++ b/proposals/random/tools/witx/tests/anonymous.rs @@ -13,11 +13,11 @@ fn anonymous_types() { assert!(is_anonymous_record_err(pointer_to_record)); let pointer_to_union = witx::parse( - "(typename $tag (enum u8 $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", + "(typename $tag (enum $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", ); assert!(is_anonymous_record_err(pointer_to_union)); - let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum u32 $b)))"); + let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum $b)))"); assert!(is_anonymous_record_err(pointer_to_enum)); let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags u32 $b)))"); @@ -36,7 +36,7 @@ fn anonymous_types() { assert!(is_anonymous_record_err(record_in_record)); let union_in_record = witx::parse( - "(typename $tag (enum u8 $c)) (typename $a (record (field $b (union $tag (field $c u8)))))", + "(typename $tag (enum $c)) (typename $a (record (field $b (union $tag (field $c u8)))))", ); assert!(is_anonymous_record_err(union_in_record)); diff --git a/proposals/random/tools/witx/tests/union.rs b/proposals/random/tools/witx/tests/union.rs index 732b5c007..30fb4dfdf 100644 --- a/proposals/random/tools/witx/tests/union.rs +++ b/proposals/random/tools/witx/tests/union.rs @@ -4,7 +4,7 @@ use witx::{Id, Representable}; #[test] fn one_variant_union() { let d = witx::parse( - "(typename $tag (enum u8 $c)) + "(typename $tag (enum $c)) (typename $u (union $tag (field $c u8)))", ); assert!(d.is_ok()); @@ -13,14 +13,14 @@ fn one_variant_union() { #[test] fn two_variant_union() { let d1 = witx::parse( - "(typename $tag (enum u8 $a $b)) + "(typename $tag (enum $a $b)) (typename $u (union $tag (field $a u8) (field $b u16)))", ); assert!(d1.is_ok(), "d1 is ok"); // Fields can come in whatever order: let d2 = witx::parse( - "(typename $tag (enum u8 $a $b)) + "(typename $tag (enum $a $b)) (typename $u (union $tag (field $b u16) (field $a u8)))", ); assert!(d2.is_ok(), "d2 is ok"); @@ -42,7 +42,7 @@ fn two_variant_union() { // Tag order doesnt matter for validation, but does for rep equality let d3 = witx::parse( - "(typename $tag (enum u8 $b $a)) + "(typename $tag (enum $b $a)) (typename $u (union $tag (field $b u16) (field $a u8)))", ); assert!(d3.is_ok(), "d2 is ok"); @@ -57,13 +57,13 @@ fn two_variant_union() { #[test] fn empty_variant_unions() { let d1 = witx::parse( - "(typename $tag (enum u8 $a $b)) + "(typename $tag (enum $a $b)) (typename $u (union $tag (empty $a) (field $b u16)))", ); assert!(d1.is_ok(), "d1 is ok"); let d2 = witx::parse( - "(typename $tag (enum u8 $a $b)) + "(typename $tag (enum $a $b)) (typename $u (union $tag (empty $a) (empty $b)))", ); assert!(d2.is_ok(), "d2 is ok"); @@ -72,7 +72,7 @@ fn empty_variant_unions() { #[test] fn many_variant_unions() { let d1 = witx::parse( - "(typename $tag (enum u32 $a $b $c $d $e $f $g $h $i $j $k $l $m)) + "(typename $tag (enum $a $b $c $d $e $f $g $h $i $j $k $l $m)) (typename $u (union $tag (field $a u8) @@ -114,7 +114,7 @@ fn wrong_kind_tag_union() { #[test] fn bad_field_unions() { let d = witx::parse( - "(typename $tag (enum u8 $c)) + "(typename $tag (enum $c)) (typename $u (union $tag (field $b u8)))", ); let (name, reason) = union_field_err(d).expect("bad field union 1"); @@ -125,7 +125,7 @@ fn bad_field_unions() { ); let d = witx::parse( - "(typename $tag (enum u8 $c)) + "(typename $tag (enum $c)) (typename $u (union $tag (field $c f32) (field $b u8)))", ); let (name, reason) = union_field_err(d).expect("bad field union 2"); @@ -136,7 +136,7 @@ fn bad_field_unions() { ); let d = witx::parse( - "(typename $tag (enum u8 $c $d)) + "(typename $tag (enum $c $d)) (typename $u (union $tag (field $c f32)))", ); let (name, reason) = union_field_err(d).expect("bad field union 3"); From 7b9f8d3fc8f2cedc409b7c9cfc02b3d36dd081a5 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 10:43:05 -0800 Subject: [PATCH 0840/1772] Implement enums in terms of `Variant` --- proposals/filesystem/phases/ephemeral/docs.md | 28 ++++----- .../phases/ephemeral/witx/typenames.witx | 14 ++--- .../filesystem/phases/old/snapshot_0/docs.md | 32 +++++------ .../phases/old/snapshot_0/witx/typenames.witx | 16 +++--- proposals/filesystem/phases/snapshot/docs.md | 32 +++++------ .../phases/snapshot/witx/typenames.witx | 16 +++--- proposals/filesystem/tools/witx/src/ast.rs | 15 +---- .../filesystem/tools/witx/src/coretypes.rs | 10 +++- .../filesystem/tools/witx/src/docs/ast.rs | 32 +---------- .../filesystem/tools/witx/src/docs/md.rs | 2 - proposals/filesystem/tools/witx/src/layout.rs | 4 +- proposals/filesystem/tools/witx/src/parser.rs | 13 ++++- proposals/filesystem/tools/witx/src/render.rs | 46 +++++++-------- .../tools/witx/src/representation.rs | 30 +++++----- .../filesystem/tools/witx/src/validate.rs | 57 ++++++++++++------- .../filesystem/tools/witx/tests/anonymous.rs | 6 +- .../filesystem/tools/witx/tests/union.rs | 20 +++---- 17 files changed, 179 insertions(+), 194 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 3d317dae7..3c9b13531 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -22,14 +22,14 @@ Size: 8 Alignment: 8 -## `clockid`: Enum(`u32`) +## `clockid`: Variant Identifiers for clocks. Size: 4 Alignment: 4 -### Variants +### Variant cases - `realtime` The clock measuring real time. Time value zero corresponds with 1970-01-01T00:00:00Z. @@ -40,7 +40,7 @@ real time, whose value cannot be adjusted and which cannot have negative clock jumps. The epoch of this clock is undefined. The absolute time value of this clock therefore has no meaning. -## `errno`: Enum(`u16`) +## `errno`: Variant Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -50,7 +50,7 @@ Size: 2 Alignment: 2 -### Variants +### Variant cases - `success` No error occurred. System call completed successfully. @@ -463,14 +463,14 @@ Size: 8 Alignment: 8 -## `whence`: Enum(`u8`) +## `whence`: Variant The position relative to which to set the offset of the file descriptor. Size: 1 Alignment: 1 -### Variants +### Variant cases - `set` Seek relative to start-of-file. @@ -501,14 +501,14 @@ Size: 8 Alignment: 8 -## `filetype`: Enum(`u8`) +## `filetype`: Variant The type of a file descriptor or file. Size: 1 Alignment: 1 -### Variants +### Variant cases - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -564,14 +564,14 @@ The length of the name of the directory entry. Offset: 20 -## `advice`: Enum(`u8`) +## `advice`: Variant File or memory access pattern advisory information. Size: 1 Alignment: 1 -### Variants +### Variant cases - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -805,14 +805,14 @@ Size: 8 Alignment: 8 -## `eventtype`: Enum(`u8`) +## `eventtype`: Variant Type of a subscription to an event or its occurrence. Size: 1 Alignment: 1 -### Variants +### Variant cases - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -1051,14 +1051,14 @@ Disables further receive operations. - `wr` Disables further send operations. -## `preopentype`: Enum(`u8`) +## `preopentype`: Variant Identifiers for preopened capabilities. Size: 1 Alignment: 1 -### Variants +### Variant cases - `dir` A pre-opened directory. diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index c456a99a7..f2cde8272 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -18,7 +18,7 @@ ;;; Identifiers for clocks. (typename $clockid - (enum u32 + (enum (@witx tag u32) ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. $realtime @@ -35,7 +35,7 @@ ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. (typename $errno - (enum u16 + (enum (@witx tag u16) ;;; No error occurred. System call completed successfully. $success ;;; Argument list too long. @@ -312,7 +312,7 @@ ;;; The position relative to which to set the offset of the file descriptor. (typename $whence - (enum u8 + (enum (@witx tag u8) ;;; Seek relative to start-of-file. $set ;;; Seek relative to current position. @@ -336,7 +336,7 @@ ;;; The type of a file descriptor or file. (typename $filetype - (enum u8 + (enum (@witx tag u8) ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $unknown ;;; The file descriptor or file refers to a block device inode. @@ -374,7 +374,7 @@ ;;; File or memory access pattern advisory information. (typename $advice - (enum u8 + (enum (@witx tag u8) ;;; The application has no advice to give on its behavior with respect to the specified data. $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. @@ -527,7 +527,7 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype - (enum u8 + (enum (@witx tag u8) ;;; The time value of clock `subscription_clock::id` has ;;; reached timestamp `subscription_clock::timeout`. $clock @@ -675,7 +675,7 @@ ;;; Identifiers for preopened capabilities. (typename $preopentype - (enum u8 + (enum (@witx tag u8) ;;; A pre-opened directory. $dir ) diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index b56aa1f5e..5c9543331 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -19,14 +19,14 @@ Size: 8 Alignment: 8 -## `clockid`: Enum(`u32`) +## `clockid`: Variant Identifiers for clocks. Size: 4 Alignment: 4 -### Variants +### Variant cases - `realtime` The clock measuring real time. Time value zero corresponds with 1970-01-01T00:00:00Z. @@ -43,7 +43,7 @@ The CPU-time clock associated with the current process. - `thread_cputime_id` The CPU-time clock associated with the current thread. -## `errno`: Enum(`u16`) +## `errno`: Variant Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -53,7 +53,7 @@ Size: 2 Alignment: 2 -### Variants +### Variant cases - `success` No error occurred. System call completed successfully. @@ -455,14 +455,14 @@ Size: 8 Alignment: 8 -## `whence`: Enum(`u8`) +## `whence`: Variant The position relative to which to set the offset of the file descriptor. Size: 1 Alignment: 1 -### Variants +### Variant cases - `cur` Seek relative to current position. @@ -493,14 +493,14 @@ Size: 8 Alignment: 8 -## `filetype`: Enum(`u8`) +## `filetype`: Variant The type of a file descriptor or file. Size: 1 Alignment: 1 -### Variants +### Variant cases - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -553,14 +553,14 @@ The type of the file referred to by this directory entry. Offset: 20 -## `advice`: Enum(`u8`) +## `advice`: Variant File or memory access pattern advisory information. Size: 1 Alignment: 1 -### Variants +### Variant cases - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -755,14 +755,14 @@ Size: 8 Alignment: 8 -## `eventtype`: Enum(`u8`) +## `eventtype`: Variant Type of a subscription to an event or its occurrence. Size: 1 Alignment: 1 -### Variants +### Variant cases - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -945,14 +945,14 @@ Size: 4 Alignment: 4 -## `signal`: Enum(`u8`) +## `signal`: Variant Signal condition. Size: 1 Alignment: 1 -### Variants +### Variant cases - `none` No signal. Note that POSIX has special semantics for `kill(pid, 0)`, so this value is reserved. @@ -1124,14 +1124,14 @@ Disables further receive operations. - `wr` Disables further send operations. -## `preopentype`: Enum(`u8`) +## `preopentype`: Variant Identifiers for preopened capabilities. Size: 1 Alignment: 1 -### Variants +### Variant cases - `dir` A pre-opened directory. diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx index 37a49f083..4bf485ba8 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx @@ -15,7 +15,7 @@ ;;; Identifiers for clocks. (typename $clockid - (enum u32 + (enum (@witx tag u32) ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. $realtime @@ -36,7 +36,7 @@ ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. (typename $errno - (enum u16 + (enum (@witx tag u16) ;;; No error occurred. System call completed successfully. $success ;;; Argument list too long. @@ -304,7 +304,7 @@ ;;; The position relative to which to set the offset of the file descriptor. (typename $whence - (enum u8 + (enum (@witx tag u8) ;;; Seek relative to current position. $cur ;;; Seek relative to end-of-file. @@ -325,7 +325,7 @@ ;;; The type of a file descriptor or file. (typename $filetype - (enum u8 + (enum (@witx tag u8) ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $unknown ;;; The file descriptor or file refers to a block device inode. @@ -361,7 +361,7 @@ ;;; File or memory access pattern advisory information. (typename $advice - (enum u8 + (enum (@witx tag u8) ;;; The application has no advice to give on its behavior with respect to the specified data. $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. @@ -481,7 +481,7 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype - (enum u8 + (enum (@witx tag u8) ;;; The time value of clock `subscription_clock::id` has ;;; reached timestamp `subscription_clock::timeout`. $clock @@ -593,7 +593,7 @@ ;;; Signal condition. (typename $signal - (enum u8 + (enum (@witx tag u8) ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. $none @@ -724,7 +724,7 @@ ;;; Identifiers for preopened capabilities. (typename $preopentype - (enum u8 + (enum (@witx tag u8) ;;; A pre-opened directory. $dir ) diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index 1cb642abe..827250111 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -19,14 +19,14 @@ Size: 8 Alignment: 8 -## `clockid`: Enum(`u32`) +## `clockid`: Variant Identifiers for clocks. Size: 4 Alignment: 4 -### Variants +### Variant cases - `realtime` The clock measuring real time. Time value zero corresponds with 1970-01-01T00:00:00Z. @@ -43,7 +43,7 @@ The CPU-time clock associated with the current process. - `thread_cputime_id` The CPU-time clock associated with the current thread. -## `errno`: Enum(`u16`) +## `errno`: Variant Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -53,7 +53,7 @@ Size: 2 Alignment: 2 -### Variants +### Variant cases - `success` No error occurred. System call completed successfully. @@ -455,14 +455,14 @@ Size: 8 Alignment: 8 -## `whence`: Enum(`u8`) +## `whence`: Variant The position relative to which to set the offset of the file descriptor. Size: 1 Alignment: 1 -### Variants +### Variant cases - `set` Seek relative to start-of-file. @@ -495,14 +495,14 @@ Size: 8 Alignment: 8 -## `filetype`: Enum(`u8`) +## `filetype`: Variant The type of a file descriptor or file. Size: 1 Alignment: 1 -### Variants +### Variant cases - `unknown` The type of the file descriptor or file is unknown or is different from any of the other types specified. @@ -555,14 +555,14 @@ The type of the file referred to by this directory entry. Offset: 20 -## `advice`: Enum(`u8`) +## `advice`: Variant File or memory access pattern advisory information. Size: 1 Alignment: 1 -### Variants +### Variant cases - `normal` The application has no advice to give on its behavior with respect to the specified data. @@ -757,14 +757,14 @@ Size: 8 Alignment: 8 -## `eventtype`: Enum(`u8`) +## `eventtype`: Variant Type of a subscription to an event or its occurrence. Size: 1 Alignment: 1 -### Variants +### Variant cases - `clock` The time value of clock [`subscription_clock::id`](#subscription_clock.id) has reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -942,14 +942,14 @@ Size: 4 Alignment: 4 -## `signal`: Enum(`u8`) +## `signal`: Variant Signal condition. Size: 1 Alignment: 1 -### Variants +### Variant cases - `none` No signal. Note that POSIX has special semantics for `kill(pid, 0)`, so this value is reserved. @@ -1121,14 +1121,14 @@ Disables further receive operations. - `wr` Disables further send operations. -## `preopentype`: Enum(`u8`) +## `preopentype`: Variant Identifiers for preopened capabilities. Size: 1 Alignment: 1 -### Variants +### Variant cases - `dir` A pre-opened directory. diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx index b0ccece64..a2da265c2 100644 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -15,7 +15,7 @@ ;;; Identifiers for clocks. (typename $clockid - (enum u32 + (enum (@witx tag u32) ;;; The clock measuring real time. Time value zero corresponds with ;;; 1970-01-01T00:00:00Z. $realtime @@ -36,7 +36,7 @@ ;;; API; some are used in higher-level library layers, and others are provided ;;; merely for alignment with POSIX. (typename $errno - (enum u16 + (enum (@witx tag u16) ;;; No error occurred. System call completed successfully. $success ;;; Argument list too long. @@ -304,7 +304,7 @@ ;;; The position relative to which to set the offset of the file descriptor. (typename $whence - (enum u8 + (enum (@witx tag u8) ;;; Seek relative to start-of-file. $set ;;; Seek relative to current position. @@ -327,7 +327,7 @@ ;;; The type of a file descriptor or file. (typename $filetype - (enum u8 + (enum (@witx tag u8) ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. $unknown ;;; The file descriptor or file refers to a block device inode. @@ -363,7 +363,7 @@ ;;; File or memory access pattern advisory information. (typename $advice - (enum u8 + (enum (@witx tag u8) ;;; The application has no advice to give on its behavior with respect to the specified data. $normal ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. @@ -483,7 +483,7 @@ ;;; Type of a subscription to an event or its occurrence. (typename $eventtype - (enum u8 + (enum (@witx tag u8) ;;; The time value of clock `subscription_clock::id` has ;;; reached timestamp `subscription_clock::timeout`. $clock @@ -593,7 +593,7 @@ ;;; Signal condition. (typename $signal - (enum u8 + (enum (@witx tag u8) ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, ;;; so this value is reserved. $none @@ -724,7 +724,7 @@ ;;; Identifiers for preopened capabilities. (typename $preopentype - (enum u8 + (enum (@witx tag u8) ;;; A pre-opened directory. $dir ) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 242fcce1c..2e5980ff1 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -185,7 +185,6 @@ impl NamedType { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { - Enum(EnumDatatype), Flags(FlagsDatatype), Record(RecordDatatype), Variant(Variant), @@ -201,7 +200,6 @@ impl Type { pub fn kind(&self) -> &'static str { use Type::*; match self { - Enum(_) => "enum", Flags(_) => "flags", Record(_) => "record", Variant(_) => "variant", @@ -240,18 +238,6 @@ pub enum IntRepr { U64, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct EnumDatatype { - pub repr: IntRepr, - pub variants: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct EnumVariant { - pub name: Id, - pub docs: String, -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FlagsDatatype { pub repr: IntRepr, @@ -278,6 +264,7 @@ pub struct RecordMember { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Variant { + pub tag_repr: IntRepr, pub cases: Vec, } diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index c11529f9e..1ffe718f4 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -50,10 +50,14 @@ impl Type { }, Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), - Type::Enum(e) => TypePassedBy::Value(e.repr.into()), Type::Flags(f) => TypePassedBy::Value(f.repr.into()), - Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } => { - TypePassedBy::Pointer + Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Variant(v) => { + if v.cases.iter().all(|c| c.tref.is_none()) { + TypePassedBy::Value(v.tag_repr.into()) + } else { + TypePassedBy::Pointer + } } Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), } diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index 454cac010..fea7202cf 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -68,7 +68,6 @@ impl ToMarkdown for NamedType { impl ToMarkdown for Type { fn generate(&self, node: MdNodeRef) { match self { - Self::Enum(a) => a.generate(node.clone()), Self::Flags(a) => a.generate(node.clone()), Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), @@ -98,32 +97,6 @@ impl ToMarkdown for Type { } } -impl ToMarkdown for EnumDatatype { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Variants")); - - for variant in &self.variants { - let name = variant.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - &variant.docs, - )); - } - - node.content_ref_mut::().r#type = Some(MdType::Enum { - repr: self.repr.type_name().to_owned(), - }); - } -} - impl ToMarkdown for FlagsDatatype { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); @@ -193,7 +166,7 @@ impl ToMarkdown for Variant { MdHeading::new_bullet(), id.as_str(), name, - format!("{}\n", &case.docs).as_str(), + &case.docs, )); if let Some(ty) = &case.tref { ty.generate(n.clone()); @@ -384,8 +357,7 @@ impl TypeRef { Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), - Type::Enum { .. } - | Type::Flags { .. } + Type::Flags { .. } | Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index 1ca3a8794..4c32f9179 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -343,7 +343,6 @@ impl MdNamedType { // being outright flattened. #[derive(Debug)] pub(super) enum MdType { - Enum { repr: String }, Flags { repr: String }, Record, Variant, @@ -359,7 +358,6 @@ pub(super) enum MdType { impl fmt::Display for MdType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Self::Enum { repr } => f.write_fmt(format_args!(": Enum(`{}`)", repr))?, Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index cc4fd0add..ea23fd31a 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -64,7 +64,6 @@ impl Layout for NamedType { impl Type { fn layout(&self, cache: &mut HashMap) -> SizeAlign { match &self { - Type::Enum(e) => e.repr.mem_size_align(), Type::Flags(f) => f.repr.mem_size_align(), Type::Record(s) => s.layout(cache), Type::Variant(s) => s.mem_size_align(), @@ -139,10 +138,11 @@ impl Layout for Variant { fn mem_size_align(&self) -> SizeAlign { let mut max = SizeAlign { size: 0, align: 0 }; for case in self.cases.iter() { - let mut size = BuiltinType::S32.mem_size_align(); + let mut size = self.tag_repr.mem_size_align(); if let Some(payload) = &case.tref { size.append_field(&payload.mem_size_align()); } + size.size = align_to(size.size, size.align); max.size = max.size.max(size.size); max.align = max.align.max(size.align); } diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index ad9100481..d5ce8c3dd 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -39,6 +39,7 @@ mod kw { wast::custom_keyword!(s64); wast::custom_keyword!(s8); wast::custom_keyword!(string); + wast::custom_keyword!(tag); wast::custom_keyword!(typename); wast::custom_keyword!(u16); wast::custom_keyword!(u32); @@ -333,14 +334,22 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumSyntax<'a> { - pub repr: BuiltinType, + pub repr: Option, pub members: Vec>>, } impl<'a> Parse<'a> for EnumSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let repr = parser.parse()?; + let repr = if parser.peek2::() { + Some(parser.parens(|p| { + p.parse::()?; + p.parse::()?; + p.parse() + })?) + } else { + None + }; let mut members = Vec::new(); members.push(parser.parse()?); while !parser.is_empty() { diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 44ccb54df..d61c9b04e 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -116,7 +116,6 @@ impl TypeRef { impl Type { pub fn to_sexpr(&self) -> SExpr { match self { - Type::Enum(a) => a.to_sexpr(), Type::Flags(a) => a.to_sexpr(), Type::Record(a) => a.to_sexpr(), Type::Variant(a) => a.to_sexpr(), @@ -138,18 +137,6 @@ impl Type { } } -impl EnumDatatype { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("enum"), self.repr.to_sexpr()]; - let variants = self - .variants - .iter() - .map(|v| SExpr::docs(&v.docs, v.name.to_sexpr())) - .collect::>(); - SExpr::Vec([header, variants].concat()) - } -} - impl FlagsDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; @@ -185,19 +172,28 @@ impl RecordDatatype { impl Variant { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("variant")]; - let cases = self - .cases - .iter() - .map(|m| { - let mut list = vec![SExpr::word("case"), m.name.to_sexpr()]; - if let Some(ty) = &m.tref { - list.push(ty.to_sexpr()); + let mut list = Vec::new(); + if self.cases.iter().all(|c| c.tref.is_none()) { + list.push(SExpr::word("enum")); + list.push(SExpr::Vec(vec![ + SExpr::word("@witx"), + SExpr::word("tag"), + self.tag_repr.to_sexpr(), + ])); + for case in self.cases.iter() { + list.push(SExpr::docs(&case.docs, case.name.to_sexpr())); + } + } else { + list.push(SExpr::word("variant")); + for case in self.cases.iter() { + let mut case_expr = vec![SExpr::word("case"), case.name.to_sexpr()]; + if let Some(ty) = &case.tref { + case_expr.push(ty.to_sexpr()); } - SExpr::docs(&m.docs, SExpr::Vec(list)) - }) - .collect::>(); - SExpr::Vec([header, cases].concat()) + list.push(SExpr::docs(&case.docs, SExpr::Vec(case_expr))); + } + } + SExpr::Vec(list) } } diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs index 2d03797be..5b88c0c02 100644 --- a/proposals/filesystem/tools/witx/src/representation.rs +++ b/proposals/filesystem/tools/witx/src/representation.rs @@ -1,6 +1,6 @@ use crate::{ - BuiltinType, EnumDatatype, FlagsDatatype, IntRepr, NamedType, RecordDatatype, Type, TypeRef, - UnionDatatype, + BuiltinType, FlagsDatatype, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, + Variant, }; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. @@ -69,15 +69,15 @@ impl Representable for IntRepr { } } -impl Representable for EnumDatatype { +impl Representable for Variant { fn representable(&self, by: &Self) -> RepEquality { // Integer representation must be compatible - if self.repr.representable(&by.repr) == RepEquality::NotEq { + if self.tag_repr.representable(&by.tag_repr) == RepEquality::NotEq { return RepEquality::NotEq; } // For each variant in self, must have variant of same name and position in by: - for (ix, v) in self.variants.iter().enumerate() { - if let Some(by_v) = by.variants.get(ix) { + for (ix, v) in self.cases.iter().enumerate() { + if let Some(by_v) = by.cases.get(ix) { if by_v.name != v.name { return RepEquality::NotEq; } @@ -85,10 +85,10 @@ impl Representable for EnumDatatype { return RepEquality::NotEq; } } - if by.variants.len() > self.variants.len() { + if by.cases.len() > self.cases.len() { RepEquality::Superset } else { - self.repr.representable(&by.repr) + self.tag_repr.representable(&by.tag_repr) } } } @@ -203,7 +203,7 @@ impl Representable for NamedType { impl Representable for Type { fn representable(&self, by: &Self) -> RepEquality { match (&self, &by) { - (Type::Enum(s), Type::Enum(b)) => s.representable(b), + (Type::Variant(s), Type::Variant(b)) => s.representable(b), (Type::Flags(s), Type::Flags(b)) => s.representable(b), (Type::Record(s), Type::Record(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), @@ -267,13 +267,13 @@ mod test { #[test] fn enum_() { - let base = def_type("a", "(typename $a (enum u32 $b $c))"); - let extra_variant = def_type("a", "(typename $a (enum u32 $b $c $d))"); + let base = def_type("a", "(typename $a (enum $b $c))"); + let extra_variant = def_type("a", "(typename $a (enum $b $c $d))"); assert_eq!(base.representable(&extra_variant), RepEquality::Superset); assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); - let smaller_size = def_type("a", "(typename $a (enum u16 $b $c))"); + let smaller_size = def_type("a", "(typename $a (enum (@witx tag u16) $b $c))"); assert_eq!(smaller_size.representable(&base), RepEquality::Superset); assert_eq!( smaller_size.representable(&extra_variant), @@ -285,12 +285,12 @@ mod test { fn union() { let base = def_type( "a", - "(typename $tag (enum u8 $b $c)) + "(typename $tag (enum (@witx tag u8) $b $c)) (typename $a (union $tag (field $b u32) (field $c f32)))", ); let extra_variant = def_type( "a", - "(typename $tag (enum u8 $b $c $d)) + "(typename $tag (enum (@witx tag u8) $b $c $d)) (typename $a (union $tag (field $b u32) (field $c f32) (field $d f64)))", ); @@ -299,7 +299,7 @@ mod test { let other_ordering = def_type( "a", - "(typename $tag (enum u8 $b $c)) + "(typename $tag (enum (@witx tag u8) $b $c)) (typename $a (union $tag (field $c f32) (field $b u32)))", ); assert_eq!(base.representable(&other_ordering), RepEquality::Eq); diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index b51596fe3..279cf594c 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -5,11 +5,10 @@ use crate::{ ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, VariantSyntax, }, - BuiltinType, Constant, Definition, Entry, EnumDatatype, EnumVariant, FlagsDatatype, - FlagsMember, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, - InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, - ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, TypePassedBy, TypeRef, - UnionDatatype, UnionVariant, + BuiltinType, Case, Constant, Definition, Entry, FlagsDatatype, FlagsMember, HandleDatatype, Id, + IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, + ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, + RecordMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, Variant, }; use std::collections::{hash_map, HashMap}; use std::path::Path; @@ -50,6 +49,12 @@ pub enum ValidationError { reason: String, location: Location, }, + #[error("Invalid union tag `{name}`: {reason}")] + InvalidUnionTag { + name: String, + reason: String, + location: Location, + }, } impl ValidationError { @@ -62,7 +67,8 @@ impl ValidationError { | InvalidRepr { location, .. } | InvalidFirstResultType { location, .. } | AnonymousRecord { location, .. } - | InvalidUnionField { location, .. } => { + | InvalidUnionField { location, .. } + | InvalidUnionTag { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) } NameAlreadyExists { @@ -269,7 +275,7 @@ impl DocValidationScope<'_> { }) } other => Ok(TypeRef::Value(Rc::new(match other { - TypedefSyntax::Enum(syntax) => Type::Enum(self.validate_enum(&syntax, span)?), + TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), @@ -293,20 +299,27 @@ impl DocValidationScope<'_> { &self, syntax: &EnumSyntax, span: wast::Span, - ) -> Result { + ) -> Result { let mut enum_scope = IdentValidation::new(); - let repr = self.validate_int_repr(&syntax.repr, span)?; - let variants = syntax + let tag_repr = match &syntax.repr { + Some(repr) => self.validate_int_repr(repr, span)?, + None => IntRepr::U32, + }; + let cases = syntax .members .iter() .map(|i| { let name = enum_scope.introduce(i.item.name(), self.location(i.item.span()))?; let docs = i.comments.docs(); - Ok(EnumVariant { name, docs }) + Ok(Case { + name, + tref: None, + docs, + }) }) - .collect::, _>>()?; + .collect::, _>>()?; - Ok(EnumDatatype { repr, variants }) + Ok(Variant { tag_repr, cases }) } fn validate_flags( @@ -361,12 +374,18 @@ impl DocValidationScope<'_> { Some(Entry::Typename(weak_ref)) => { let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); match &*named_dt.type_() { - Type::Enum(e) => { - let uses = e - .variants - .iter() - .map(|v| (v.name.clone(), false)) - .collect::>(); + Type::Variant(e) => { + let mut uses = HashMap::new(); + for c in e.cases.iter() { + if c.tref.is_some() { + return Err(ValidationError::InvalidUnionTag { + name: syntax.tag.name().to_string(), + location: self.location(syntax.tag.span()), + reason: format!("all variant cases should have empty payloads"), + }); + } + uses.insert(c.name.clone(), false); + } Ok((named_dt, uses)) } other => Err(ValidationError::WrongKindName { diff --git a/proposals/filesystem/tools/witx/tests/anonymous.rs b/proposals/filesystem/tools/witx/tests/anonymous.rs index 2bff69960..723a36030 100644 --- a/proposals/filesystem/tools/witx/tests/anonymous.rs +++ b/proposals/filesystem/tools/witx/tests/anonymous.rs @@ -13,11 +13,11 @@ fn anonymous_types() { assert!(is_anonymous_record_err(pointer_to_record)); let pointer_to_union = witx::parse( - "(typename $tag (enum u8 $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", + "(typename $tag (enum $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", ); assert!(is_anonymous_record_err(pointer_to_union)); - let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum u32 $b)))"); + let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum $b)))"); assert!(is_anonymous_record_err(pointer_to_enum)); let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags u32 $b)))"); @@ -36,7 +36,7 @@ fn anonymous_types() { assert!(is_anonymous_record_err(record_in_record)); let union_in_record = witx::parse( - "(typename $tag (enum u8 $c)) (typename $a (record (field $b (union $tag (field $c u8)))))", + "(typename $tag (enum $c)) (typename $a (record (field $b (union $tag (field $c u8)))))", ); assert!(is_anonymous_record_err(union_in_record)); diff --git a/proposals/filesystem/tools/witx/tests/union.rs b/proposals/filesystem/tools/witx/tests/union.rs index 732b5c007..30fb4dfdf 100644 --- a/proposals/filesystem/tools/witx/tests/union.rs +++ b/proposals/filesystem/tools/witx/tests/union.rs @@ -4,7 +4,7 @@ use witx::{Id, Representable}; #[test] fn one_variant_union() { let d = witx::parse( - "(typename $tag (enum u8 $c)) + "(typename $tag (enum $c)) (typename $u (union $tag (field $c u8)))", ); assert!(d.is_ok()); @@ -13,14 +13,14 @@ fn one_variant_union() { #[test] fn two_variant_union() { let d1 = witx::parse( - "(typename $tag (enum u8 $a $b)) + "(typename $tag (enum $a $b)) (typename $u (union $tag (field $a u8) (field $b u16)))", ); assert!(d1.is_ok(), "d1 is ok"); // Fields can come in whatever order: let d2 = witx::parse( - "(typename $tag (enum u8 $a $b)) + "(typename $tag (enum $a $b)) (typename $u (union $tag (field $b u16) (field $a u8)))", ); assert!(d2.is_ok(), "d2 is ok"); @@ -42,7 +42,7 @@ fn two_variant_union() { // Tag order doesnt matter for validation, but does for rep equality let d3 = witx::parse( - "(typename $tag (enum u8 $b $a)) + "(typename $tag (enum $b $a)) (typename $u (union $tag (field $b u16) (field $a u8)))", ); assert!(d3.is_ok(), "d2 is ok"); @@ -57,13 +57,13 @@ fn two_variant_union() { #[test] fn empty_variant_unions() { let d1 = witx::parse( - "(typename $tag (enum u8 $a $b)) + "(typename $tag (enum $a $b)) (typename $u (union $tag (empty $a) (field $b u16)))", ); assert!(d1.is_ok(), "d1 is ok"); let d2 = witx::parse( - "(typename $tag (enum u8 $a $b)) + "(typename $tag (enum $a $b)) (typename $u (union $tag (empty $a) (empty $b)))", ); assert!(d2.is_ok(), "d2 is ok"); @@ -72,7 +72,7 @@ fn empty_variant_unions() { #[test] fn many_variant_unions() { let d1 = witx::parse( - "(typename $tag (enum u32 $a $b $c $d $e $f $g $h $i $j $k $l $m)) + "(typename $tag (enum $a $b $c $d $e $f $g $h $i $j $k $l $m)) (typename $u (union $tag (field $a u8) @@ -114,7 +114,7 @@ fn wrong_kind_tag_union() { #[test] fn bad_field_unions() { let d = witx::parse( - "(typename $tag (enum u8 $c)) + "(typename $tag (enum $c)) (typename $u (union $tag (field $b u8)))", ); let (name, reason) = union_field_err(d).expect("bad field union 1"); @@ -125,7 +125,7 @@ fn bad_field_unions() { ); let d = witx::parse( - "(typename $tag (enum u8 $c)) + "(typename $tag (enum $c)) (typename $u (union $tag (field $c f32) (field $b u8)))", ); let (name, reason) = union_field_err(d).expect("bad field union 2"); @@ -136,7 +136,7 @@ fn bad_field_unions() { ); let d = witx::parse( - "(typename $tag (enum u8 $c $d)) + "(typename $tag (enum $c $d)) (typename $u (union $tag (field $c f32)))", ); let (name, reason) = union_field_err(d).expect("bad field union 3"); From 457d902000e272556654b5f710f851242ffcf0b2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 11:23:00 -0800 Subject: [PATCH 0841/1772] Define `Flags` in terms of integers Remove the `Type::Flags` variant in favor of a witx-specific way to define a bitflags with a number of constants. --- proposals/clocks/phases/ephemeral/docs.md | 47 +++++++------ .../phases/ephemeral/witx/typenames.witx | 22 +++--- .../clocks/phases/old/snapshot_0/docs.md | 40 +++++------ .../phases/old/snapshot_0/witx/typenames.witx | 20 +++--- proposals/clocks/phases/snapshot/docs.md | 40 +++++------ .../phases/snapshot/witx/typenames.witx | 20 +++--- proposals/clocks/tools/witx/src/ast.rs | 21 +++--- proposals/clocks/tools/witx/src/coretypes.rs | 1 - proposals/clocks/tools/witx/src/docs/ast.rs | 62 ++++++----------- proposals/clocks/tools/witx/src/docs/md.rs | 2 - proposals/clocks/tools/witx/src/layout.rs | 8 +-- proposals/clocks/tools/witx/src/parser.rs | 18 ++++- proposals/clocks/tools/witx/src/render.rs | 13 ---- .../clocks/tools/witx/src/representation.rs | 53 +------------- proposals/clocks/tools/witx/src/toplevel.rs | 5 +- proposals/clocks/tools/witx/src/validate.rs | 69 +++++++++++-------- .../clocks/tools/witx/tests/anonymous.rs | 2 +- 17 files changed, 190 insertions(+), 253 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 3c9b13531..c579e00a3 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -282,14 +282,14 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: Flags(`u64`) +## `rights`: `u64` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Flags +### Constants - `fd_datasync` The right to invoke `fd_datasync`. If `path_open` is set, includes the right to invoke @@ -487,6 +487,9 @@ Size: 8 Alignment: 8 +### Constants +- `start` + ## `dirnamlen`: `u32` The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). @@ -590,14 +593,14 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: Flags(`u16`) +## `fdflags`: `u16` File descriptor flags. Size: 2 Alignment: 2 -### Flags +### Constants - `append` Append mode: Data written to the file is always appended to the file's end. @@ -652,14 +655,14 @@ Size: 8 Alignment: 8 -## `fstflags`: Flags(`u16`) +## `fstflags`: `u16` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Flags +### Constants - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -672,25 +675,25 @@ Adjust the last data modification timestamp to the value stored in [`filestat::m - `mtim_now` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: Flags(`u32`) +## `lookupflags`: `u32` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Flags +### Constants - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: Flags(`u16`) +## `oflags`: `u16` Open flags used by `path_open`. Size: 2 Alignment: 2 -### Flags +### Constants - `create` Create file if it does not exist. @@ -710,7 +713,7 @@ Size: 8 Alignment: 8 -## `permissions`: Flags(`u8`) +## `permissions`: `u8` File permissions. This represents the permissions associated with a file in a filesystem, and don't fully reflect all the conditions which determine whether a given WASI program can access the file. @@ -719,7 +722,7 @@ Size: 1 Alignment: 1 -### Flags +### Constants - `read` For files, permission to read the file. For directories, permission to do [`readdir`](#readdir) and access files @@ -825,7 +828,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: Flags(`u16`) +## `eventrwflags`: `u16` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -833,7 +836,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -899,7 +902,7 @@ The type of the event that occurred, and the contents of the event Offset: 16 -## `subclockflags`: Flags(`u16`) +## `subclockflags`: `u16` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -907,7 +910,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `subscription_clock_abstime` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock @@ -1004,28 +1007,28 @@ Size: 4 Alignment: 4 -## `riflags`: Flags(`u16`) +## `riflags`: `u16` Flags provided to `sock_recv`. Size: 2 Alignment: 2 -### Flags +### Constants - `recv_peek` Returns the message without removing it from the socket's receive queue. - `recv_waitall` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: Flags(`u16`) +## `roflags`: `u16` Flags returned by `sock_recv`. Size: 2 Alignment: 2 -### Flags +### Constants - `recv_data_truncated` Returned by `sock_recv`: Message data has been truncated. @@ -1037,14 +1040,14 @@ Size: 2 Alignment: 2 -## `sdflags`: Flags(`u8`) +## `sdflags`: `u8` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Flags +### Constants - `rd` Disables further receive operations. diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index f2cde8272..e10c4c30d 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -195,7 +195,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags u64 + (flags (@witx bitflags u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke @@ -392,7 +392,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags u16 + (flags (@witx bitflags u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -429,7 +429,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags u16 + (flags (@witx bitflags u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -443,7 +443,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags u32 + (flags (@witx bitflags u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -451,7 +451,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags u16 + (flags (@witx bitflags u16) ;;; Create file if it does not exist. $create ;;; Fail if not a directory. @@ -470,7 +470,7 @@ ;;; file in a filesystem, and don't fully reflect all the conditions ;;; which determine whether a given WASI program can access the file. (typename $permissions - (flags u8 + (flags (@witx bitflags u8) ;;; For files, permission to read the file. ;;; For directories, permission to do `readdir` and access files ;;; within the directory. @@ -543,7 +543,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags u16 + (flags (@witx bitflags u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -584,7 +584,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags u16 + (flags (@witx bitflags u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -643,7 +643,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -653,7 +653,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -665,7 +665,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags u8 + (flags (@witx bitflags u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index 5c9543331..0e2f5bde0 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -285,14 +285,14 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: Flags(`u64`) +## `rights`: `u64` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Flags +### Constants - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke @@ -579,14 +579,14 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: Flags(`u16`) +## `fdflags`: `u16` File descriptor flags. Size: 2 Alignment: 2 -### Flags +### Constants - `append` Append mode: Data written to the file is always appended to the file's end. @@ -641,14 +641,14 @@ Size: 8 Alignment: 8 -## `fstflags`: Flags(`u16`) +## `fstflags`: `u16` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Flags +### Constants - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -661,25 +661,25 @@ Adjust the last data modification timestamp to the value stored in [`filestat::m - `mtim_now` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: Flags(`u32`) +## `lookupflags`: `u32` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Flags +### Constants - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: Flags(`u16`) +## `oflags`: `u16` Open flags used by [`path_open`](#path_open). Size: 2 Alignment: 2 -### Flags +### Constants - `creat` Create file if it does not exist. @@ -775,7 +775,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: Flags(`u16`) +## `eventrwflags`: `u16` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -783,7 +783,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -835,7 +835,7 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read Offset: 16 -## `subclockflags`: Flags(`u16`) +## `subclockflags`: `u16` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -843,7 +843,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `subscription_clock_abstime` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock @@ -1077,28 +1077,28 @@ Action: Terminates the process. Bad system call. Action: Terminates the process. -## `riflags`: Flags(`u16`) +## `riflags`: `u16` Flags provided to [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Flags +### Constants - `recv_peek` Returns the message without removing it from the socket's receive queue. - `recv_waitall` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: Flags(`u16`) +## `roflags`: `u16` Flags returned by [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Flags +### Constants - `recv_data_truncated` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. @@ -1110,14 +1110,14 @@ Size: 2 Alignment: 2 -## `sdflags`: Flags(`u8`) +## `sdflags`: `u8` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Flags +### Constants - `rd` Disables further receive operations. diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx index 4bf485ba8..f24000e00 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags u64 + (flags (@witx bitflags u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `rights::path_open` is set, includes the right to invoke @@ -379,7 +379,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags u16 + (flags (@witx bitflags u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -416,7 +416,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags u16 + (flags (@witx bitflags u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -430,7 +430,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags u32 + (flags (@witx bitflags u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -438,7 +438,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags u16 + (flags (@witx bitflags u16) ;;; Create file if it does not exist. $creat ;;; Fail if not a directory. @@ -497,7 +497,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags u16 + (flags (@witx bitflags u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -532,7 +532,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags u16 + (flags (@witx bitflags u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -692,7 +692,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -702,7 +702,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -714,7 +714,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags u8 + (flags (@witx bitflags u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index 827250111..e13dcc79d 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -285,14 +285,14 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: Flags(`u64`) +## `rights`: `u64` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Flags +### Constants - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). If [`path_open`](#path_open) is set, includes the right to invoke @@ -581,14 +581,14 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: Flags(`u16`) +## `fdflags`: `u16` File descriptor flags. Size: 2 Alignment: 2 -### Flags +### Constants - `append` Append mode: Data written to the file is always appended to the file's end. @@ -643,14 +643,14 @@ Size: 8 Alignment: 8 -## `fstflags`: Flags(`u16`) +## `fstflags`: `u16` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Flags +### Constants - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -663,25 +663,25 @@ Adjust the last data modification timestamp to the value stored in [`filestat::m - `mtim_now` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: Flags(`u32`) +## `lookupflags`: `u32` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Flags +### Constants - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: Flags(`u16`) +## `oflags`: `u16` Open flags used by [`path_open`](#path_open). Size: 2 Alignment: 2 -### Flags +### Constants - `creat` Create file if it does not exist. @@ -777,7 +777,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: Flags(`u16`) +## `eventrwflags`: `u16` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -785,7 +785,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -837,7 +837,7 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read Offset: 16 -## `subclockflags`: Flags(`u16`) +## `subclockflags`: `u16` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -845,7 +845,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `subscription_clock_abstime` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock @@ -1074,28 +1074,28 @@ Action: Terminates the process. Bad system call. Action: Terminates the process. -## `riflags`: Flags(`u16`) +## `riflags`: `u16` Flags provided to [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Flags +### Constants - `recv_peek` Returns the message without removing it from the socket's receive queue. - `recv_waitall` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: Flags(`u16`) +## `roflags`: `u16` Flags returned by [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Flags +### Constants - `recv_data_truncated` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. @@ -1107,14 +1107,14 @@ Size: 2 Alignment: 2 -## `sdflags`: Flags(`u8`) +## `sdflags`: `u8` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Flags +### Constants - `rd` Disables further receive operations. diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx index a2da265c2..13eb1759f 100644 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags u64 + (flags (@witx bitflags u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke @@ -381,7 +381,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags u16 + (flags (@witx bitflags u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -418,7 +418,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags u16 + (flags (@witx bitflags u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -432,7 +432,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags u32 + (flags (@witx bitflags u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -440,7 +440,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags u16 + (flags (@witx bitflags u16) ;;; Create file if it does not exist. $creat ;;; Fail if not a directory. @@ -499,7 +499,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags u16 + (flags (@witx bitflags u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -534,7 +534,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags u16 + (flags (@witx bitflags u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -692,7 +692,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -702,7 +702,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -714,7 +714,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags u8 + (flags (@witx bitflags u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 2e5980ff1..556dadd6a 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -185,7 +185,6 @@ impl NamedType { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { - Flags(FlagsDatatype), Record(RecordDatatype), Variant(Variant), Union(UnionDatatype), @@ -200,7 +199,6 @@ impl Type { pub fn kind(&self) -> &'static str { use Type::*; match self { - Flags(_) => "flags", Record(_) => "record", Variant(_) => "variant", Union(_) => "union", @@ -238,16 +236,15 @@ pub enum IntRepr { U64, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct FlagsDatatype { - pub repr: IntRepr, - pub flags: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct FlagsMember { - pub name: Id, - pub docs: String, +impl IntRepr { + pub fn to_builtin(&self) -> BuiltinType { + match self { + IntRepr::U8 => BuiltinType::U8, + IntRepr::U16 => BuiltinType::U16, + IntRepr::U32 => BuiltinType::U32, + IntRepr::U64 => BuiltinType::U64, + } + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index 1ffe718f4..b2cacf8e8 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -50,7 +50,6 @@ impl Type { }, Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), - Type::Flags(f) => TypePassedBy::Value(f.repr.into()), Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, Type::Variant(v) => { if v.cases.iter().all(|c| c.tref.is_none()) { diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index fea7202cf..c9fce08ce 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -8,6 +8,7 @@ use crate::{ polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, RepEquality, }; +use std::collections::HashMap; fn heading_from_node(node: &MdNodeRef, levels_down: usize) -> MdHeading { MdHeading::new_header(node.borrow().ancestors().len() + levels_down) @@ -17,6 +18,12 @@ impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); let types = node.new_child(MdSection::new(heading, "Types")); + + let mut constants_by_name = HashMap::new(); + for c in self.constants() { + constants_by_name.entry(&c.ty).or_insert(Vec::new()).push(c); + } + for d in self.typenames() { let name = d.name.as_str(); let child = types.new_child(MdNamedType::new( @@ -31,6 +38,18 @@ impl ToMarkdown for Document { ) .as_str(), )); + if let Some(constants) = constants_by_name.remove(&d.name) { + let heading = heading_from_node(&child, 1); + child.new_child(MdSection::new(heading, "Constants")); + for constant in constants { + child.new_child(MdNamedType::new( + MdHeading::new_bullet(), + format!("{}.{}", name, constant.name.as_str()).as_str(), + constant.name.as_str(), + &constant.docs, + )); + } + } d.generate(child.clone()); } @@ -42,7 +61,7 @@ impl ToMarkdown for Document { d.generate(child.clone()); } - // TODO: document constants + assert!(constants_by_name.is_empty()); } } @@ -68,7 +87,6 @@ impl ToMarkdown for NamedType { impl ToMarkdown for Type { fn generate(&self, node: MdNodeRef) { match self { - Self::Flags(a) => a.generate(node.clone()), Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), Self::Union(a) => a.generate(node.clone()), @@ -97,32 +115,6 @@ impl ToMarkdown for Type { } } -impl ToMarkdown for FlagsDatatype { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Flags")); - - for flag in &self.flags { - let name = flag.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - &flag.docs, - )); - } - - node.content_ref_mut::().r#type = Some(MdType::Flags { - repr: self.repr.type_name().to_owned(), - }); - } -} - impl ToMarkdown for RecordDatatype { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); @@ -357,8 +349,7 @@ impl TypeRef { Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), - Type::Flags { .. } - | Type::Record { .. } + Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } | Type::Handle { .. } => { @@ -369,17 +360,6 @@ impl TypeRef { } } -impl IntRepr { - fn type_name(&self) -> &'static str { - match self { - IntRepr::U8 => "u8", - IntRepr::U16 => "u16", - IntRepr::U32 => "u32", - IntRepr::U64 => "u64", - } - } -} - // TODO // Generate Markdown tree for the polyfill impl Documentation for Polyfill { diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index 4c32f9179..22ea16074 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -343,7 +343,6 @@ impl MdNamedType { // being outright flattened. #[derive(Debug)] pub(super) enum MdType { - Flags { repr: String }, Record, Variant, Union, @@ -358,7 +357,6 @@ pub(super) enum MdType { impl fmt::Display for MdType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index ea23fd31a..2154eecfe 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -64,7 +64,6 @@ impl Layout for NamedType { impl Type { fn layout(&self, cache: &mut HashMap) -> SizeAlign { match &self { - Type::Flags(f) => f.repr.mem_size_align(), Type::Record(s) => s.layout(cache), Type::Variant(s) => s.mem_size_align(), Type::Union(u) => u.layout(cache), @@ -85,12 +84,7 @@ impl Layout for Type { impl Layout for IntRepr { fn mem_size_align(&self) -> SizeAlign { - match self { - IntRepr::U8 => BuiltinType::U8.mem_size_align(), - IntRepr::U16 => BuiltinType::U16.mem_size_align(), - IntRepr::U32 => BuiltinType::U32.mem_size_align(), - IntRepr::U64 => BuiltinType::U64.mem_size_align(), - } + self.to_builtin().mem_size_align() } } diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index d5ce8c3dd..fad70619b 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -18,6 +18,7 @@ use wast::parser::{Parse, Parser, Peek, Result}; mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; + wast::custom_keyword!(bitflags); wast::custom_keyword!(char8); wast::custom_keyword!(const_pointer); wast::custom_keyword!(f32); @@ -379,19 +380,30 @@ impl<'a> Parse<'a> for ConstSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsSyntax<'a> { - pub repr: BuiltinType, + pub bitflags_repr: Option, pub flags: Vec>>, } impl<'a> Parse<'a> for FlagsSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let repr = parser.parse()?; + let bitflags_repr = if parser.peek2::() { + Some(parser.parens(|p| { + p.parse::()?; + p.parse::()?; + p.parse() + })?) + } else { + None + }; let mut flags = Vec::new(); while !parser.is_empty() { flags.push(parser.parse()?); } - Ok(FlagsSyntax { repr, flags }) + Ok(FlagsSyntax { + bitflags_repr, + flags, + }) } } diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index d61c9b04e..659f940c8 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -116,7 +116,6 @@ impl TypeRef { impl Type { pub fn to_sexpr(&self) -> SExpr { match self { - Type::Flags(a) => a.to_sexpr(), Type::Record(a) => a.to_sexpr(), Type::Variant(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), @@ -137,18 +136,6 @@ impl Type { } } -impl FlagsDatatype { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; - let flags = self - .flags - .iter() - .map(|f| SExpr::docs(&f.docs, f.name.to_sexpr())) - .collect::>(); - SExpr::Vec([header, flags].concat()) - } -} - impl RecordDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("record")]; diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs index 5b88c0c02..d3f7bf817 100644 --- a/proposals/clocks/tools/witx/src/representation.rs +++ b/proposals/clocks/tools/witx/src/representation.rs @@ -1,6 +1,5 @@ use crate::{ - BuiltinType, FlagsDatatype, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, - Variant, + BuiltinType, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, Variant, }; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. @@ -93,30 +92,6 @@ impl Representable for Variant { } } -impl Representable for FlagsDatatype { - fn representable(&self, by: &Self) -> RepEquality { - // Integer representation must be compatible - if self.repr.representable(&by.repr) == RepEquality::NotEq { - return RepEquality::NotEq; - } - // For each flag in self, must have flag of same name and position in by: - for (ix, f) in self.flags.iter().enumerate() { - if let Some(by_f) = by.flags.get(ix) { - if by_f.name != f.name { - return RepEquality::NotEq; - } - } else { - return RepEquality::NotEq; - } - } - if by.flags.len() > self.flags.len() { - RepEquality::Superset - } else { - self.repr.representable(&by.repr) - } - } -} - impl Representable for RecordDatatype { fn representable(&self, by: &Self) -> RepEquality { // Records must have exact structural equality - same members, must @@ -204,7 +179,6 @@ impl Representable for Type { fn representable(&self, by: &Self) -> RepEquality { match (&self, &by) { (Type::Variant(s), Type::Variant(b)) => s.representable(b), - (Type::Flags(s), Type::Flags(b)) => s.representable(b), (Type::Record(s), Type::Record(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural @@ -237,34 +211,13 @@ mod test { #[test] fn different_typenames() { - let a = def_type("a", "(typename $a (flags u32 $b $c))"); - let d = def_type("d", "(typename $d (flags u32 $b $c))"); + let a = def_type("a", "(typename $a (flags (@witx bitflags u32) $b $c))"); + let d = def_type("d", "(typename $d (flags (@witx bitflags u32) $b $c))"); assert_eq!(a.representable(&d), RepEquality::Eq); assert_eq!(d.representable(&a), RepEquality::Eq); } - #[test] - fn flags() { - let base = def_type("a", "(typename $a (flags u32 $b $c))"); - let extra_flag = def_type("a", "(typename $a (flags u32 $b $c $d))"); - - assert_eq!(base.representable(&extra_flag), RepEquality::Superset); - assert_eq!(extra_flag.representable(&base), RepEquality::NotEq); - - let different_flagnames = def_type("d", "(typename $d (flags u32 $b $e))"); - assert_eq!(base.representable(&different_flagnames), RepEquality::NotEq); - assert_eq!(different_flagnames.representable(&base), RepEquality::NotEq); - - let smaller_size = def_type("a", "(typename $a (flags u16 $b $c))"); - assert_eq!(smaller_size.representable(&base), RepEquality::Superset); - assert_eq!( - smaller_size.representable(&extra_flag), - RepEquality::Superset - ); - assert_eq!(base.representable(&smaller_size), RepEquality::NotEq); - } - #[test] fn enum_() { let base = def_type("a", "(typename $a (enum $b $c))"); diff --git a/proposals/clocks/tools/witx/src/toplevel.rs b/proposals/clocks/tools/witx/src/toplevel.rs index 4fb13b8d7..52ef3daa3 100644 --- a/proposals/clocks/tools/witx/src/toplevel.rs +++ b/proposals/clocks/tools/witx/src/toplevel.rs @@ -60,11 +60,10 @@ fn parse_file( for t in doc.items { match t.item { TopLevelSyntax::Decl(d) => { - let def = validator + validator .scope(&input, &path) - .validate_decl(&d, &t.comments) + .validate_decl(&d, &t.comments, definitions) .map_err(WitxError::Validation)?; - definitions.push(def); } TopLevelSyntax::Use(u) => { parse_file(u.as_ref(), io, root, validator, definitions, parsed)?; diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 279cf594c..88f4a44fb 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -5,10 +5,10 @@ use crate::{ ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, VariantSyntax, }, - BuiltinType, Case, Constant, Definition, Entry, FlagsDatatype, FlagsMember, HandleDatatype, Id, - IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, - ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, - RecordMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, Variant, + BuiltinType, Case, Constant, Definition, Entry, HandleDatatype, Id, IntRepr, InterfaceFunc, + InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, + ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, + TypePassedBy, TypeRef, UnionDatatype, UnionVariant, Variant, }; use std::collections::{hash_map, HashMap}; use std::path::Path; @@ -179,7 +179,8 @@ impl DocValidationScope<'_> { &mut self, decl: &DeclSyntax, comments: &CommentSyntax, - ) -> Result { + definitions: &mut Vec, + ) -> Result<(), ValidationError> { match decl { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; @@ -193,13 +194,32 @@ impl DocValidationScope<'_> { }); self.doc .entries - .insert(name, Entry::Typename(Rc::downgrade(&rc_datatype))); - Ok(Definition::Typename(rc_datatype)) + .insert(name.clone(), Entry::Typename(Rc::downgrade(&rc_datatype))); + definitions.push(Definition::Typename(rc_datatype)); + + if let TypedefSyntax::Flags(syntax) = &decl.def { + if syntax.bitflags_repr.is_some() { + let mut flags_scope = IdentValidation::new(); + let ty = name; + for (i, flag) in syntax.flags.iter().enumerate() { + let name = flags_scope + .introduce(flag.item.name(), self.location(flag.item.span()))?; + let docs = flag.comments.docs(); + definitions.push(Definition::Constant(Constant { + ty: ty.clone(), + name, + value: 1 << i, + docs, + })); + } + } + } } + DeclSyntax::Module(syntax) => { let name = self.introduce(&syntax.name)?; let mut module_validator = ModuleValidation::new(self); - let definitions = syntax + let decls = syntax .decls .iter() .map(|d| module_validator.validate_decl(&d)) @@ -207,14 +227,14 @@ impl DocValidationScope<'_> { let rc_module = Rc::new(Module::new( name.clone(), - definitions, + decls, module_validator.entries, comments.docs(), )); self.doc .entries .insert(name, Entry::Module(Rc::downgrade(&rc_module))); - Ok(Definition::Module(rc_module)) + definitions.push(Definition::Module(rc_module)); } DeclSyntax::Const(syntax) => { @@ -228,14 +248,15 @@ impl DocValidationScope<'_> { let name = scope.introduce(syntax.item.name.name(), loc)?; // TODO: validate `ty` is a integer datatype that `syntax.value` // fits within. - Ok(Definition::Constant(Constant { + definitions.push(Definition::Constant(Constant { ty, name, value: syntax.item.value, docs: syntax.comments.docs(), - })) + })); } } + Ok(()) } fn validate_datatype( @@ -276,7 +297,7 @@ impl DocValidationScope<'_> { } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), - TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), + TypedefSyntax::Flags(syntax) => self.validate_flags(&syntax, span)?, TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), @@ -326,20 +347,14 @@ impl DocValidationScope<'_> { &self, syntax: &FlagsSyntax, span: wast::Span, - ) -> Result { - let mut flags_scope = IdentValidation::new(); - let repr = self.validate_int_repr(&syntax.repr, span)?; - let flags = syntax - .flags - .iter() - .map(|i| { - let name = flags_scope.introduce(i.item.name(), self.location(i.item.span()))?; - let docs = i.comments.docs(); - Ok(FlagsMember { name, docs }) - }) - .collect::, _>>()?; - - Ok(FlagsDatatype { repr, flags }) + ) -> Result { + Ok(match &syntax.bitflags_repr { + Some(repr) => Type::Builtin(self.validate_int_repr(repr, span)?.to_builtin()), + None => { + // TODO: auto-translate to a struct-of-bool-fields + unimplemented!(); + } + }) } fn validate_record( diff --git a/proposals/clocks/tools/witx/tests/anonymous.rs b/proposals/clocks/tools/witx/tests/anonymous.rs index 723a36030..a295a3915 100644 --- a/proposals/clocks/tools/witx/tests/anonymous.rs +++ b/proposals/clocks/tools/witx/tests/anonymous.rs @@ -20,7 +20,7 @@ fn anonymous_types() { let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum $b)))"); assert!(is_anonymous_record_err(pointer_to_enum)); - let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags u32 $b)))"); + let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags $b)))"); assert!(is_anonymous_record_err(pointer_to_flags)); let pointer_to_handle = witx::parse("(typename $a (@witx pointer (handle)))"); From da16dbf2105094de1241883fc8bb8f58ac0eb6d7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 11:23:00 -0800 Subject: [PATCH 0842/1772] Define `Flags` in terms of integers Remove the `Type::Flags` variant in favor of a witx-specific way to define a bitflags with a number of constants. --- proposals/random/phases/ephemeral/docs.md | 47 +++++++------ .../phases/ephemeral/witx/typenames.witx | 22 +++--- .../random/phases/old/snapshot_0/docs.md | 40 +++++------ .../phases/old/snapshot_0/witx/typenames.witx | 20 +++--- proposals/random/phases/snapshot/docs.md | 40 +++++------ .../phases/snapshot/witx/typenames.witx | 20 +++--- proposals/random/tools/witx/src/ast.rs | 21 +++--- proposals/random/tools/witx/src/coretypes.rs | 1 - proposals/random/tools/witx/src/docs/ast.rs | 62 ++++++----------- proposals/random/tools/witx/src/docs/md.rs | 2 - proposals/random/tools/witx/src/layout.rs | 8 +-- proposals/random/tools/witx/src/parser.rs | 18 ++++- proposals/random/tools/witx/src/render.rs | 13 ---- .../random/tools/witx/src/representation.rs | 53 +------------- proposals/random/tools/witx/src/toplevel.rs | 5 +- proposals/random/tools/witx/src/validate.rs | 69 +++++++++++-------- .../random/tools/witx/tests/anonymous.rs | 2 +- 17 files changed, 190 insertions(+), 253 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 3c9b13531..c579e00a3 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -282,14 +282,14 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: Flags(`u64`) +## `rights`: `u64` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Flags +### Constants - `fd_datasync` The right to invoke `fd_datasync`. If `path_open` is set, includes the right to invoke @@ -487,6 +487,9 @@ Size: 8 Alignment: 8 +### Constants +- `start` + ## `dirnamlen`: `u32` The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). @@ -590,14 +593,14 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: Flags(`u16`) +## `fdflags`: `u16` File descriptor flags. Size: 2 Alignment: 2 -### Flags +### Constants - `append` Append mode: Data written to the file is always appended to the file's end. @@ -652,14 +655,14 @@ Size: 8 Alignment: 8 -## `fstflags`: Flags(`u16`) +## `fstflags`: `u16` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Flags +### Constants - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -672,25 +675,25 @@ Adjust the last data modification timestamp to the value stored in [`filestat::m - `mtim_now` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: Flags(`u32`) +## `lookupflags`: `u32` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Flags +### Constants - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: Flags(`u16`) +## `oflags`: `u16` Open flags used by `path_open`. Size: 2 Alignment: 2 -### Flags +### Constants - `create` Create file if it does not exist. @@ -710,7 +713,7 @@ Size: 8 Alignment: 8 -## `permissions`: Flags(`u8`) +## `permissions`: `u8` File permissions. This represents the permissions associated with a file in a filesystem, and don't fully reflect all the conditions which determine whether a given WASI program can access the file. @@ -719,7 +722,7 @@ Size: 1 Alignment: 1 -### Flags +### Constants - `read` For files, permission to read the file. For directories, permission to do [`readdir`](#readdir) and access files @@ -825,7 +828,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: Flags(`u16`) +## `eventrwflags`: `u16` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -833,7 +836,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -899,7 +902,7 @@ The type of the event that occurred, and the contents of the event Offset: 16 -## `subclockflags`: Flags(`u16`) +## `subclockflags`: `u16` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -907,7 +910,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `subscription_clock_abstime` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock @@ -1004,28 +1007,28 @@ Size: 4 Alignment: 4 -## `riflags`: Flags(`u16`) +## `riflags`: `u16` Flags provided to `sock_recv`. Size: 2 Alignment: 2 -### Flags +### Constants - `recv_peek` Returns the message without removing it from the socket's receive queue. - `recv_waitall` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: Flags(`u16`) +## `roflags`: `u16` Flags returned by `sock_recv`. Size: 2 Alignment: 2 -### Flags +### Constants - `recv_data_truncated` Returned by `sock_recv`: Message data has been truncated. @@ -1037,14 +1040,14 @@ Size: 2 Alignment: 2 -## `sdflags`: Flags(`u8`) +## `sdflags`: `u8` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Flags +### Constants - `rd` Disables further receive operations. diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index f2cde8272..e10c4c30d 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -195,7 +195,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags u64 + (flags (@witx bitflags u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke @@ -392,7 +392,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags u16 + (flags (@witx bitflags u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -429,7 +429,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags u16 + (flags (@witx bitflags u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -443,7 +443,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags u32 + (flags (@witx bitflags u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -451,7 +451,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags u16 + (flags (@witx bitflags u16) ;;; Create file if it does not exist. $create ;;; Fail if not a directory. @@ -470,7 +470,7 @@ ;;; file in a filesystem, and don't fully reflect all the conditions ;;; which determine whether a given WASI program can access the file. (typename $permissions - (flags u8 + (flags (@witx bitflags u8) ;;; For files, permission to read the file. ;;; For directories, permission to do `readdir` and access files ;;; within the directory. @@ -543,7 +543,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags u16 + (flags (@witx bitflags u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -584,7 +584,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags u16 + (flags (@witx bitflags u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -643,7 +643,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -653,7 +653,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -665,7 +665,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags u8 + (flags (@witx bitflags u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index 5c9543331..0e2f5bde0 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -285,14 +285,14 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: Flags(`u64`) +## `rights`: `u64` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Flags +### Constants - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke @@ -579,14 +579,14 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: Flags(`u16`) +## `fdflags`: `u16` File descriptor flags. Size: 2 Alignment: 2 -### Flags +### Constants - `append` Append mode: Data written to the file is always appended to the file's end. @@ -641,14 +641,14 @@ Size: 8 Alignment: 8 -## `fstflags`: Flags(`u16`) +## `fstflags`: `u16` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Flags +### Constants - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -661,25 +661,25 @@ Adjust the last data modification timestamp to the value stored in [`filestat::m - `mtim_now` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: Flags(`u32`) +## `lookupflags`: `u32` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Flags +### Constants - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: Flags(`u16`) +## `oflags`: `u16` Open flags used by [`path_open`](#path_open). Size: 2 Alignment: 2 -### Flags +### Constants - `creat` Create file if it does not exist. @@ -775,7 +775,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: Flags(`u16`) +## `eventrwflags`: `u16` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -783,7 +783,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -835,7 +835,7 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read Offset: 16 -## `subclockflags`: Flags(`u16`) +## `subclockflags`: `u16` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -843,7 +843,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `subscription_clock_abstime` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock @@ -1077,28 +1077,28 @@ Action: Terminates the process. Bad system call. Action: Terminates the process. -## `riflags`: Flags(`u16`) +## `riflags`: `u16` Flags provided to [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Flags +### Constants - `recv_peek` Returns the message without removing it from the socket's receive queue. - `recv_waitall` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: Flags(`u16`) +## `roflags`: `u16` Flags returned by [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Flags +### Constants - `recv_data_truncated` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. @@ -1110,14 +1110,14 @@ Size: 2 Alignment: 2 -## `sdflags`: Flags(`u8`) +## `sdflags`: `u8` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Flags +### Constants - `rd` Disables further receive operations. diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx index 4bf485ba8..f24000e00 100644 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/random/phases/old/snapshot_0/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags u64 + (flags (@witx bitflags u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `rights::path_open` is set, includes the right to invoke @@ -379,7 +379,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags u16 + (flags (@witx bitflags u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -416,7 +416,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags u16 + (flags (@witx bitflags u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -430,7 +430,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags u32 + (flags (@witx bitflags u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -438,7 +438,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags u16 + (flags (@witx bitflags u16) ;;; Create file if it does not exist. $creat ;;; Fail if not a directory. @@ -497,7 +497,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags u16 + (flags (@witx bitflags u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -532,7 +532,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags u16 + (flags (@witx bitflags u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -692,7 +692,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -702,7 +702,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -714,7 +714,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags u8 + (flags (@witx bitflags u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index 827250111..e13dcc79d 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -285,14 +285,14 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: Flags(`u64`) +## `rights`: `u64` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Flags +### Constants - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). If [`path_open`](#path_open) is set, includes the right to invoke @@ -581,14 +581,14 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: Flags(`u16`) +## `fdflags`: `u16` File descriptor flags. Size: 2 Alignment: 2 -### Flags +### Constants - `append` Append mode: Data written to the file is always appended to the file's end. @@ -643,14 +643,14 @@ Size: 8 Alignment: 8 -## `fstflags`: Flags(`u16`) +## `fstflags`: `u16` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Flags +### Constants - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -663,25 +663,25 @@ Adjust the last data modification timestamp to the value stored in [`filestat::m - `mtim_now` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: Flags(`u32`) +## `lookupflags`: `u32` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Flags +### Constants - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: Flags(`u16`) +## `oflags`: `u16` Open flags used by [`path_open`](#path_open). Size: 2 Alignment: 2 -### Flags +### Constants - `creat` Create file if it does not exist. @@ -777,7 +777,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: Flags(`u16`) +## `eventrwflags`: `u16` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -785,7 +785,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -837,7 +837,7 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read Offset: 16 -## `subclockflags`: Flags(`u16`) +## `subclockflags`: `u16` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -845,7 +845,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `subscription_clock_abstime` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock @@ -1074,28 +1074,28 @@ Action: Terminates the process. Bad system call. Action: Terminates the process. -## `riflags`: Flags(`u16`) +## `riflags`: `u16` Flags provided to [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Flags +### Constants - `recv_peek` Returns the message without removing it from the socket's receive queue. - `recv_waitall` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: Flags(`u16`) +## `roflags`: `u16` Flags returned by [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Flags +### Constants - `recv_data_truncated` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. @@ -1107,14 +1107,14 @@ Size: 2 Alignment: 2 -## `sdflags`: Flags(`u8`) +## `sdflags`: `u8` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Flags +### Constants - `rd` Disables further receive operations. diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx index a2da265c2..13eb1759f 100644 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags u64 + (flags (@witx bitflags u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke @@ -381,7 +381,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags u16 + (flags (@witx bitflags u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -418,7 +418,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags u16 + (flags (@witx bitflags u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -432,7 +432,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags u32 + (flags (@witx bitflags u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -440,7 +440,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags u16 + (flags (@witx bitflags u16) ;;; Create file if it does not exist. $creat ;;; Fail if not a directory. @@ -499,7 +499,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags u16 + (flags (@witx bitflags u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -534,7 +534,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags u16 + (flags (@witx bitflags u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -692,7 +692,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -702,7 +702,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -714,7 +714,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags u8 + (flags (@witx bitflags u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 2e5980ff1..556dadd6a 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -185,7 +185,6 @@ impl NamedType { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { - Flags(FlagsDatatype), Record(RecordDatatype), Variant(Variant), Union(UnionDatatype), @@ -200,7 +199,6 @@ impl Type { pub fn kind(&self) -> &'static str { use Type::*; match self { - Flags(_) => "flags", Record(_) => "record", Variant(_) => "variant", Union(_) => "union", @@ -238,16 +236,15 @@ pub enum IntRepr { U64, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct FlagsDatatype { - pub repr: IntRepr, - pub flags: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct FlagsMember { - pub name: Id, - pub docs: String, +impl IntRepr { + pub fn to_builtin(&self) -> BuiltinType { + match self { + IntRepr::U8 => BuiltinType::U8, + IntRepr::U16 => BuiltinType::U16, + IntRepr::U32 => BuiltinType::U32, + IntRepr::U64 => BuiltinType::U64, + } + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index 1ffe718f4..b2cacf8e8 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -50,7 +50,6 @@ impl Type { }, Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), - Type::Flags(f) => TypePassedBy::Value(f.repr.into()), Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, Type::Variant(v) => { if v.cases.iter().all(|c| c.tref.is_none()) { diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index fea7202cf..c9fce08ce 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -8,6 +8,7 @@ use crate::{ polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, RepEquality, }; +use std::collections::HashMap; fn heading_from_node(node: &MdNodeRef, levels_down: usize) -> MdHeading { MdHeading::new_header(node.borrow().ancestors().len() + levels_down) @@ -17,6 +18,12 @@ impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); let types = node.new_child(MdSection::new(heading, "Types")); + + let mut constants_by_name = HashMap::new(); + for c in self.constants() { + constants_by_name.entry(&c.ty).or_insert(Vec::new()).push(c); + } + for d in self.typenames() { let name = d.name.as_str(); let child = types.new_child(MdNamedType::new( @@ -31,6 +38,18 @@ impl ToMarkdown for Document { ) .as_str(), )); + if let Some(constants) = constants_by_name.remove(&d.name) { + let heading = heading_from_node(&child, 1); + child.new_child(MdSection::new(heading, "Constants")); + for constant in constants { + child.new_child(MdNamedType::new( + MdHeading::new_bullet(), + format!("{}.{}", name, constant.name.as_str()).as_str(), + constant.name.as_str(), + &constant.docs, + )); + } + } d.generate(child.clone()); } @@ -42,7 +61,7 @@ impl ToMarkdown for Document { d.generate(child.clone()); } - // TODO: document constants + assert!(constants_by_name.is_empty()); } } @@ -68,7 +87,6 @@ impl ToMarkdown for NamedType { impl ToMarkdown for Type { fn generate(&self, node: MdNodeRef) { match self { - Self::Flags(a) => a.generate(node.clone()), Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), Self::Union(a) => a.generate(node.clone()), @@ -97,32 +115,6 @@ impl ToMarkdown for Type { } } -impl ToMarkdown for FlagsDatatype { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Flags")); - - for flag in &self.flags { - let name = flag.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - &flag.docs, - )); - } - - node.content_ref_mut::().r#type = Some(MdType::Flags { - repr: self.repr.type_name().to_owned(), - }); - } -} - impl ToMarkdown for RecordDatatype { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); @@ -357,8 +349,7 @@ impl TypeRef { Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), - Type::Flags { .. } - | Type::Record { .. } + Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } | Type::Handle { .. } => { @@ -369,17 +360,6 @@ impl TypeRef { } } -impl IntRepr { - fn type_name(&self) -> &'static str { - match self { - IntRepr::U8 => "u8", - IntRepr::U16 => "u16", - IntRepr::U32 => "u32", - IntRepr::U64 => "u64", - } - } -} - // TODO // Generate Markdown tree for the polyfill impl Documentation for Polyfill { diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index 4c32f9179..22ea16074 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -343,7 +343,6 @@ impl MdNamedType { // being outright flattened. #[derive(Debug)] pub(super) enum MdType { - Flags { repr: String }, Record, Variant, Union, @@ -358,7 +357,6 @@ pub(super) enum MdType { impl fmt::Display for MdType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index ea23fd31a..2154eecfe 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -64,7 +64,6 @@ impl Layout for NamedType { impl Type { fn layout(&self, cache: &mut HashMap) -> SizeAlign { match &self { - Type::Flags(f) => f.repr.mem_size_align(), Type::Record(s) => s.layout(cache), Type::Variant(s) => s.mem_size_align(), Type::Union(u) => u.layout(cache), @@ -85,12 +84,7 @@ impl Layout for Type { impl Layout for IntRepr { fn mem_size_align(&self) -> SizeAlign { - match self { - IntRepr::U8 => BuiltinType::U8.mem_size_align(), - IntRepr::U16 => BuiltinType::U16.mem_size_align(), - IntRepr::U32 => BuiltinType::U32.mem_size_align(), - IntRepr::U64 => BuiltinType::U64.mem_size_align(), - } + self.to_builtin().mem_size_align() } } diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index d5ce8c3dd..fad70619b 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -18,6 +18,7 @@ use wast::parser::{Parse, Parser, Peek, Result}; mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; + wast::custom_keyword!(bitflags); wast::custom_keyword!(char8); wast::custom_keyword!(const_pointer); wast::custom_keyword!(f32); @@ -379,19 +380,30 @@ impl<'a> Parse<'a> for ConstSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsSyntax<'a> { - pub repr: BuiltinType, + pub bitflags_repr: Option, pub flags: Vec>>, } impl<'a> Parse<'a> for FlagsSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let repr = parser.parse()?; + let bitflags_repr = if parser.peek2::() { + Some(parser.parens(|p| { + p.parse::()?; + p.parse::()?; + p.parse() + })?) + } else { + None + }; let mut flags = Vec::new(); while !parser.is_empty() { flags.push(parser.parse()?); } - Ok(FlagsSyntax { repr, flags }) + Ok(FlagsSyntax { + bitflags_repr, + flags, + }) } } diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index d61c9b04e..659f940c8 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -116,7 +116,6 @@ impl TypeRef { impl Type { pub fn to_sexpr(&self) -> SExpr { match self { - Type::Flags(a) => a.to_sexpr(), Type::Record(a) => a.to_sexpr(), Type::Variant(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), @@ -137,18 +136,6 @@ impl Type { } } -impl FlagsDatatype { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; - let flags = self - .flags - .iter() - .map(|f| SExpr::docs(&f.docs, f.name.to_sexpr())) - .collect::>(); - SExpr::Vec([header, flags].concat()) - } -} - impl RecordDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("record")]; diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs index 5b88c0c02..d3f7bf817 100644 --- a/proposals/random/tools/witx/src/representation.rs +++ b/proposals/random/tools/witx/src/representation.rs @@ -1,6 +1,5 @@ use crate::{ - BuiltinType, FlagsDatatype, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, - Variant, + BuiltinType, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, Variant, }; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. @@ -93,30 +92,6 @@ impl Representable for Variant { } } -impl Representable for FlagsDatatype { - fn representable(&self, by: &Self) -> RepEquality { - // Integer representation must be compatible - if self.repr.representable(&by.repr) == RepEquality::NotEq { - return RepEquality::NotEq; - } - // For each flag in self, must have flag of same name and position in by: - for (ix, f) in self.flags.iter().enumerate() { - if let Some(by_f) = by.flags.get(ix) { - if by_f.name != f.name { - return RepEquality::NotEq; - } - } else { - return RepEquality::NotEq; - } - } - if by.flags.len() > self.flags.len() { - RepEquality::Superset - } else { - self.repr.representable(&by.repr) - } - } -} - impl Representable for RecordDatatype { fn representable(&self, by: &Self) -> RepEquality { // Records must have exact structural equality - same members, must @@ -204,7 +179,6 @@ impl Representable for Type { fn representable(&self, by: &Self) -> RepEquality { match (&self, &by) { (Type::Variant(s), Type::Variant(b)) => s.representable(b), - (Type::Flags(s), Type::Flags(b)) => s.representable(b), (Type::Record(s), Type::Record(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural @@ -237,34 +211,13 @@ mod test { #[test] fn different_typenames() { - let a = def_type("a", "(typename $a (flags u32 $b $c))"); - let d = def_type("d", "(typename $d (flags u32 $b $c))"); + let a = def_type("a", "(typename $a (flags (@witx bitflags u32) $b $c))"); + let d = def_type("d", "(typename $d (flags (@witx bitflags u32) $b $c))"); assert_eq!(a.representable(&d), RepEquality::Eq); assert_eq!(d.representable(&a), RepEquality::Eq); } - #[test] - fn flags() { - let base = def_type("a", "(typename $a (flags u32 $b $c))"); - let extra_flag = def_type("a", "(typename $a (flags u32 $b $c $d))"); - - assert_eq!(base.representable(&extra_flag), RepEquality::Superset); - assert_eq!(extra_flag.representable(&base), RepEquality::NotEq); - - let different_flagnames = def_type("d", "(typename $d (flags u32 $b $e))"); - assert_eq!(base.representable(&different_flagnames), RepEquality::NotEq); - assert_eq!(different_flagnames.representable(&base), RepEquality::NotEq); - - let smaller_size = def_type("a", "(typename $a (flags u16 $b $c))"); - assert_eq!(smaller_size.representable(&base), RepEquality::Superset); - assert_eq!( - smaller_size.representable(&extra_flag), - RepEquality::Superset - ); - assert_eq!(base.representable(&smaller_size), RepEquality::NotEq); - } - #[test] fn enum_() { let base = def_type("a", "(typename $a (enum $b $c))"); diff --git a/proposals/random/tools/witx/src/toplevel.rs b/proposals/random/tools/witx/src/toplevel.rs index 4fb13b8d7..52ef3daa3 100644 --- a/proposals/random/tools/witx/src/toplevel.rs +++ b/proposals/random/tools/witx/src/toplevel.rs @@ -60,11 +60,10 @@ fn parse_file( for t in doc.items { match t.item { TopLevelSyntax::Decl(d) => { - let def = validator + validator .scope(&input, &path) - .validate_decl(&d, &t.comments) + .validate_decl(&d, &t.comments, definitions) .map_err(WitxError::Validation)?; - definitions.push(def); } TopLevelSyntax::Use(u) => { parse_file(u.as_ref(), io, root, validator, definitions, parsed)?; diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 279cf594c..88f4a44fb 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -5,10 +5,10 @@ use crate::{ ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, VariantSyntax, }, - BuiltinType, Case, Constant, Definition, Entry, FlagsDatatype, FlagsMember, HandleDatatype, Id, - IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, - ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, - RecordMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, Variant, + BuiltinType, Case, Constant, Definition, Entry, HandleDatatype, Id, IntRepr, InterfaceFunc, + InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, + ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, + TypePassedBy, TypeRef, UnionDatatype, UnionVariant, Variant, }; use std::collections::{hash_map, HashMap}; use std::path::Path; @@ -179,7 +179,8 @@ impl DocValidationScope<'_> { &mut self, decl: &DeclSyntax, comments: &CommentSyntax, - ) -> Result { + definitions: &mut Vec, + ) -> Result<(), ValidationError> { match decl { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; @@ -193,13 +194,32 @@ impl DocValidationScope<'_> { }); self.doc .entries - .insert(name, Entry::Typename(Rc::downgrade(&rc_datatype))); - Ok(Definition::Typename(rc_datatype)) + .insert(name.clone(), Entry::Typename(Rc::downgrade(&rc_datatype))); + definitions.push(Definition::Typename(rc_datatype)); + + if let TypedefSyntax::Flags(syntax) = &decl.def { + if syntax.bitflags_repr.is_some() { + let mut flags_scope = IdentValidation::new(); + let ty = name; + for (i, flag) in syntax.flags.iter().enumerate() { + let name = flags_scope + .introduce(flag.item.name(), self.location(flag.item.span()))?; + let docs = flag.comments.docs(); + definitions.push(Definition::Constant(Constant { + ty: ty.clone(), + name, + value: 1 << i, + docs, + })); + } + } + } } + DeclSyntax::Module(syntax) => { let name = self.introduce(&syntax.name)?; let mut module_validator = ModuleValidation::new(self); - let definitions = syntax + let decls = syntax .decls .iter() .map(|d| module_validator.validate_decl(&d)) @@ -207,14 +227,14 @@ impl DocValidationScope<'_> { let rc_module = Rc::new(Module::new( name.clone(), - definitions, + decls, module_validator.entries, comments.docs(), )); self.doc .entries .insert(name, Entry::Module(Rc::downgrade(&rc_module))); - Ok(Definition::Module(rc_module)) + definitions.push(Definition::Module(rc_module)); } DeclSyntax::Const(syntax) => { @@ -228,14 +248,15 @@ impl DocValidationScope<'_> { let name = scope.introduce(syntax.item.name.name(), loc)?; // TODO: validate `ty` is a integer datatype that `syntax.value` // fits within. - Ok(Definition::Constant(Constant { + definitions.push(Definition::Constant(Constant { ty, name, value: syntax.item.value, docs: syntax.comments.docs(), - })) + })); } } + Ok(()) } fn validate_datatype( @@ -276,7 +297,7 @@ impl DocValidationScope<'_> { } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), - TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), + TypedefSyntax::Flags(syntax) => self.validate_flags(&syntax, span)?, TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), @@ -326,20 +347,14 @@ impl DocValidationScope<'_> { &self, syntax: &FlagsSyntax, span: wast::Span, - ) -> Result { - let mut flags_scope = IdentValidation::new(); - let repr = self.validate_int_repr(&syntax.repr, span)?; - let flags = syntax - .flags - .iter() - .map(|i| { - let name = flags_scope.introduce(i.item.name(), self.location(i.item.span()))?; - let docs = i.comments.docs(); - Ok(FlagsMember { name, docs }) - }) - .collect::, _>>()?; - - Ok(FlagsDatatype { repr, flags }) + ) -> Result { + Ok(match &syntax.bitflags_repr { + Some(repr) => Type::Builtin(self.validate_int_repr(repr, span)?.to_builtin()), + None => { + // TODO: auto-translate to a struct-of-bool-fields + unimplemented!(); + } + }) } fn validate_record( diff --git a/proposals/random/tools/witx/tests/anonymous.rs b/proposals/random/tools/witx/tests/anonymous.rs index 723a36030..a295a3915 100644 --- a/proposals/random/tools/witx/tests/anonymous.rs +++ b/proposals/random/tools/witx/tests/anonymous.rs @@ -20,7 +20,7 @@ fn anonymous_types() { let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum $b)))"); assert!(is_anonymous_record_err(pointer_to_enum)); - let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags u32 $b)))"); + let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags $b)))"); assert!(is_anonymous_record_err(pointer_to_flags)); let pointer_to_handle = witx::parse("(typename $a (@witx pointer (handle)))"); From e175cf5d43125c18d1f6b6719897d8bf9d5b6553 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 11:23:00 -0800 Subject: [PATCH 0843/1772] Define `Flags` in terms of integers Remove the `Type::Flags` variant in favor of a witx-specific way to define a bitflags with a number of constants. --- proposals/filesystem/phases/ephemeral/docs.md | 47 +++++++------ .../phases/ephemeral/witx/typenames.witx | 22 +++--- .../filesystem/phases/old/snapshot_0/docs.md | 40 +++++------ .../phases/old/snapshot_0/witx/typenames.witx | 20 +++--- proposals/filesystem/phases/snapshot/docs.md | 40 +++++------ .../phases/snapshot/witx/typenames.witx | 20 +++--- proposals/filesystem/tools/witx/src/ast.rs | 21 +++--- .../filesystem/tools/witx/src/coretypes.rs | 1 - .../filesystem/tools/witx/src/docs/ast.rs | 62 ++++++----------- .../filesystem/tools/witx/src/docs/md.rs | 2 - proposals/filesystem/tools/witx/src/layout.rs | 8 +-- proposals/filesystem/tools/witx/src/parser.rs | 18 ++++- proposals/filesystem/tools/witx/src/render.rs | 13 ---- .../tools/witx/src/representation.rs | 53 +------------- .../filesystem/tools/witx/src/toplevel.rs | 5 +- .../filesystem/tools/witx/src/validate.rs | 69 +++++++++++-------- .../filesystem/tools/witx/tests/anonymous.rs | 2 +- 17 files changed, 190 insertions(+), 253 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 3c9b13531..c579e00a3 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -282,14 +282,14 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: Flags(`u64`) +## `rights`: `u64` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Flags +### Constants - `fd_datasync` The right to invoke `fd_datasync`. If `path_open` is set, includes the right to invoke @@ -487,6 +487,9 @@ Size: 8 Alignment: 8 +### Constants +- `start` + ## `dirnamlen`: `u32` The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). @@ -590,14 +593,14 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: Flags(`u16`) +## `fdflags`: `u16` File descriptor flags. Size: 2 Alignment: 2 -### Flags +### Constants - `append` Append mode: Data written to the file is always appended to the file's end. @@ -652,14 +655,14 @@ Size: 8 Alignment: 8 -## `fstflags`: Flags(`u16`) +## `fstflags`: `u16` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Flags +### Constants - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -672,25 +675,25 @@ Adjust the last data modification timestamp to the value stored in [`filestat::m - `mtim_now` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: Flags(`u32`) +## `lookupflags`: `u32` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Flags +### Constants - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: Flags(`u16`) +## `oflags`: `u16` Open flags used by `path_open`. Size: 2 Alignment: 2 -### Flags +### Constants - `create` Create file if it does not exist. @@ -710,7 +713,7 @@ Size: 8 Alignment: 8 -## `permissions`: Flags(`u8`) +## `permissions`: `u8` File permissions. This represents the permissions associated with a file in a filesystem, and don't fully reflect all the conditions which determine whether a given WASI program can access the file. @@ -719,7 +722,7 @@ Size: 1 Alignment: 1 -### Flags +### Constants - `read` For files, permission to read the file. For directories, permission to do [`readdir`](#readdir) and access files @@ -825,7 +828,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: Flags(`u16`) +## `eventrwflags`: `u16` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -833,7 +836,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -899,7 +902,7 @@ The type of the event that occurred, and the contents of the event Offset: 16 -## `subclockflags`: Flags(`u16`) +## `subclockflags`: `u16` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -907,7 +910,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `subscription_clock_abstime` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock @@ -1004,28 +1007,28 @@ Size: 4 Alignment: 4 -## `riflags`: Flags(`u16`) +## `riflags`: `u16` Flags provided to `sock_recv`. Size: 2 Alignment: 2 -### Flags +### Constants - `recv_peek` Returns the message without removing it from the socket's receive queue. - `recv_waitall` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: Flags(`u16`) +## `roflags`: `u16` Flags returned by `sock_recv`. Size: 2 Alignment: 2 -### Flags +### Constants - `recv_data_truncated` Returned by `sock_recv`: Message data has been truncated. @@ -1037,14 +1040,14 @@ Size: 2 Alignment: 2 -## `sdflags`: Flags(`u8`) +## `sdflags`: `u8` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Flags +### Constants - `rd` Disables further receive operations. diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index f2cde8272..e10c4c30d 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -195,7 +195,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags u64 + (flags (@witx bitflags u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke @@ -392,7 +392,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags u16 + (flags (@witx bitflags u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -429,7 +429,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags u16 + (flags (@witx bitflags u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -443,7 +443,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags u32 + (flags (@witx bitflags u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -451,7 +451,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags u16 + (flags (@witx bitflags u16) ;;; Create file if it does not exist. $create ;;; Fail if not a directory. @@ -470,7 +470,7 @@ ;;; file in a filesystem, and don't fully reflect all the conditions ;;; which determine whether a given WASI program can access the file. (typename $permissions - (flags u8 + (flags (@witx bitflags u8) ;;; For files, permission to read the file. ;;; For directories, permission to do `readdir` and access files ;;; within the directory. @@ -543,7 +543,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags u16 + (flags (@witx bitflags u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -584,7 +584,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags u16 + (flags (@witx bitflags u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -643,7 +643,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -653,7 +653,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -665,7 +665,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags u8 + (flags (@witx bitflags u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index 5c9543331..0e2f5bde0 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -285,14 +285,14 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: Flags(`u64`) +## `rights`: `u64` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Flags +### Constants - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke @@ -579,14 +579,14 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: Flags(`u16`) +## `fdflags`: `u16` File descriptor flags. Size: 2 Alignment: 2 -### Flags +### Constants - `append` Append mode: Data written to the file is always appended to the file's end. @@ -641,14 +641,14 @@ Size: 8 Alignment: 8 -## `fstflags`: Flags(`u16`) +## `fstflags`: `u16` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Flags +### Constants - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -661,25 +661,25 @@ Adjust the last data modification timestamp to the value stored in [`filestat::m - `mtim_now` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: Flags(`u32`) +## `lookupflags`: `u32` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Flags +### Constants - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: Flags(`u16`) +## `oflags`: `u16` Open flags used by [`path_open`](#path_open). Size: 2 Alignment: 2 -### Flags +### Constants - `creat` Create file if it does not exist. @@ -775,7 +775,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: Flags(`u16`) +## `eventrwflags`: `u16` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -783,7 +783,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -835,7 +835,7 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read Offset: 16 -## `subclockflags`: Flags(`u16`) +## `subclockflags`: `u16` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -843,7 +843,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `subscription_clock_abstime` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock @@ -1077,28 +1077,28 @@ Action: Terminates the process. Bad system call. Action: Terminates the process. -## `riflags`: Flags(`u16`) +## `riflags`: `u16` Flags provided to [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Flags +### Constants - `recv_peek` Returns the message without removing it from the socket's receive queue. - `recv_waitall` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: Flags(`u16`) +## `roflags`: `u16` Flags returned by [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Flags +### Constants - `recv_data_truncated` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. @@ -1110,14 +1110,14 @@ Size: 2 Alignment: 2 -## `sdflags`: Flags(`u8`) +## `sdflags`: `u8` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Flags +### Constants - `rd` Disables further receive operations. diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx index 4bf485ba8..f24000e00 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags u64 + (flags (@witx bitflags u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `rights::path_open` is set, includes the right to invoke @@ -379,7 +379,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags u16 + (flags (@witx bitflags u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -416,7 +416,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags u16 + (flags (@witx bitflags u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -430,7 +430,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags u32 + (flags (@witx bitflags u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -438,7 +438,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags u16 + (flags (@witx bitflags u16) ;;; Create file if it does not exist. $creat ;;; Fail if not a directory. @@ -497,7 +497,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags u16 + (flags (@witx bitflags u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -532,7 +532,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags u16 + (flags (@witx bitflags u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -692,7 +692,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -702,7 +702,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -714,7 +714,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags u8 + (flags (@witx bitflags u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index 827250111..e13dcc79d 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -285,14 +285,14 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: Flags(`u64`) +## `rights`: `u64` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Flags +### Constants - `fd_datasync` The right to invoke [`fd_datasync`](#fd_datasync). If [`path_open`](#path_open) is set, includes the right to invoke @@ -581,14 +581,14 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: Flags(`u16`) +## `fdflags`: `u16` File descriptor flags. Size: 2 Alignment: 2 -### Flags +### Constants - `append` Append mode: Data written to the file is always appended to the file's end. @@ -643,14 +643,14 @@ Size: 8 Alignment: 8 -## `fstflags`: Flags(`u16`) +## `fstflags`: `u16` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Flags +### Constants - `atim` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). @@ -663,25 +663,25 @@ Adjust the last data modification timestamp to the value stored in [`filestat::m - `mtim_now` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: Flags(`u32`) +## `lookupflags`: `u32` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Flags +### Constants - `symlink_follow` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: Flags(`u16`) +## `oflags`: `u16` Open flags used by [`path_open`](#path_open). Size: 2 Alignment: 2 -### Flags +### Constants - `creat` Create file if it does not exist. @@ -777,7 +777,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: Flags(`u16`) +## `eventrwflags`: `u16` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -785,7 +785,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `fd_readwrite_hangup` The peer of this socket has closed or disconnected. @@ -837,7 +837,7 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read Offset: 16 -## `subclockflags`: Flags(`u16`) +## `subclockflags`: `u16` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -845,7 +845,7 @@ Size: 2 Alignment: 2 -### Flags +### Constants - `subscription_clock_abstime` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock @@ -1074,28 +1074,28 @@ Action: Terminates the process. Bad system call. Action: Terminates the process. -## `riflags`: Flags(`u16`) +## `riflags`: `u16` Flags provided to [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Flags +### Constants - `recv_peek` Returns the message without removing it from the socket's receive queue. - `recv_waitall` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: Flags(`u16`) +## `roflags`: `u16` Flags returned by [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Flags +### Constants - `recv_data_truncated` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. @@ -1107,14 +1107,14 @@ Size: 2 Alignment: 2 -## `sdflags`: Flags(`u8`) +## `sdflags`: `u8` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Flags +### Constants - `rd` Disables further receive operations. diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx index a2da265c2..13eb1759f 100644 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags u64 + (flags (@witx bitflags u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke @@ -381,7 +381,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags u16 + (flags (@witx bitflags u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -418,7 +418,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags u16 + (flags (@witx bitflags u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -432,7 +432,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags u32 + (flags (@witx bitflags u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -440,7 +440,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags u16 + (flags (@witx bitflags u16) ;;; Create file if it does not exist. $creat ;;; Fail if not a directory. @@ -499,7 +499,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags u16 + (flags (@witx bitflags u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -534,7 +534,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags u16 + (flags (@witx bitflags u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -692,7 +692,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -702,7 +702,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags u16 + (flags (@witx bitflags u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -714,7 +714,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags u8 + (flags (@witx bitflags u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 2e5980ff1..556dadd6a 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -185,7 +185,6 @@ impl NamedType { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { - Flags(FlagsDatatype), Record(RecordDatatype), Variant(Variant), Union(UnionDatatype), @@ -200,7 +199,6 @@ impl Type { pub fn kind(&self) -> &'static str { use Type::*; match self { - Flags(_) => "flags", Record(_) => "record", Variant(_) => "variant", Union(_) => "union", @@ -238,16 +236,15 @@ pub enum IntRepr { U64, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct FlagsDatatype { - pub repr: IntRepr, - pub flags: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct FlagsMember { - pub name: Id, - pub docs: String, +impl IntRepr { + pub fn to_builtin(&self) -> BuiltinType { + match self { + IntRepr::U8 => BuiltinType::U8, + IntRepr::U16 => BuiltinType::U16, + IntRepr::U32 => BuiltinType::U32, + IntRepr::U64 => BuiltinType::U64, + } + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index 1ffe718f4..b2cacf8e8 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -50,7 +50,6 @@ impl Type { }, Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), - Type::Flags(f) => TypePassedBy::Value(f.repr.into()), Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, Type::Variant(v) => { if v.cases.iter().all(|c| c.tref.is_none()) { diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index fea7202cf..c9fce08ce 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -8,6 +8,7 @@ use crate::{ polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, RepEquality, }; +use std::collections::HashMap; fn heading_from_node(node: &MdNodeRef, levels_down: usize) -> MdHeading { MdHeading::new_header(node.borrow().ancestors().len() + levels_down) @@ -17,6 +18,12 @@ impl ToMarkdown for Document { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); let types = node.new_child(MdSection::new(heading, "Types")); + + let mut constants_by_name = HashMap::new(); + for c in self.constants() { + constants_by_name.entry(&c.ty).or_insert(Vec::new()).push(c); + } + for d in self.typenames() { let name = d.name.as_str(); let child = types.new_child(MdNamedType::new( @@ -31,6 +38,18 @@ impl ToMarkdown for Document { ) .as_str(), )); + if let Some(constants) = constants_by_name.remove(&d.name) { + let heading = heading_from_node(&child, 1); + child.new_child(MdSection::new(heading, "Constants")); + for constant in constants { + child.new_child(MdNamedType::new( + MdHeading::new_bullet(), + format!("{}.{}", name, constant.name.as_str()).as_str(), + constant.name.as_str(), + &constant.docs, + )); + } + } d.generate(child.clone()); } @@ -42,7 +61,7 @@ impl ToMarkdown for Document { d.generate(child.clone()); } - // TODO: document constants + assert!(constants_by_name.is_empty()); } } @@ -68,7 +87,6 @@ impl ToMarkdown for NamedType { impl ToMarkdown for Type { fn generate(&self, node: MdNodeRef) { match self { - Self::Flags(a) => a.generate(node.clone()), Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), Self::Union(a) => a.generate(node.clone()), @@ -97,32 +115,6 @@ impl ToMarkdown for Type { } } -impl ToMarkdown for FlagsDatatype { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Flags")); - - for flag in &self.flags { - let name = flag.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - &flag.docs, - )); - } - - node.content_ref_mut::().r#type = Some(MdType::Flags { - repr: self.repr.type_name().to_owned(), - }); - } -} - impl ToMarkdown for RecordDatatype { fn generate(&self, node: MdNodeRef) { let heading = heading_from_node(&node, 1); @@ -357,8 +349,7 @@ impl TypeRef { Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), - Type::Flags { .. } - | Type::Record { .. } + Type::Record { .. } | Type::Variant { .. } | Type::Union { .. } | Type::Handle { .. } => { @@ -369,17 +360,6 @@ impl TypeRef { } } -impl IntRepr { - fn type_name(&self) -> &'static str { - match self { - IntRepr::U8 => "u8", - IntRepr::U16 => "u16", - IntRepr::U32 => "u32", - IntRepr::U64 => "u64", - } - } -} - // TODO // Generate Markdown tree for the polyfill impl Documentation for Polyfill { diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index 4c32f9179..22ea16074 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -343,7 +343,6 @@ impl MdNamedType { // being outright flattened. #[derive(Debug)] pub(super) enum MdType { - Flags { repr: String }, Record, Variant, Union, @@ -358,7 +357,6 @@ pub(super) enum MdType { impl fmt::Display for MdType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Self::Flags { repr } => f.write_fmt(format_args!(": Flags(`{}`)", repr))?, Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index ea23fd31a..2154eecfe 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -64,7 +64,6 @@ impl Layout for NamedType { impl Type { fn layout(&self, cache: &mut HashMap) -> SizeAlign { match &self { - Type::Flags(f) => f.repr.mem_size_align(), Type::Record(s) => s.layout(cache), Type::Variant(s) => s.mem_size_align(), Type::Union(u) => u.layout(cache), @@ -85,12 +84,7 @@ impl Layout for Type { impl Layout for IntRepr { fn mem_size_align(&self) -> SizeAlign { - match self { - IntRepr::U8 => BuiltinType::U8.mem_size_align(), - IntRepr::U16 => BuiltinType::U16.mem_size_align(), - IntRepr::U32 => BuiltinType::U32.mem_size_align(), - IntRepr::U64 => BuiltinType::U64.mem_size_align(), - } + self.to_builtin().mem_size_align() } } diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index d5ce8c3dd..fad70619b 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -18,6 +18,7 @@ use wast::parser::{Parse, Parser, Peek, Result}; mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; + wast::custom_keyword!(bitflags); wast::custom_keyword!(char8); wast::custom_keyword!(const_pointer); wast::custom_keyword!(f32); @@ -379,19 +380,30 @@ impl<'a> Parse<'a> for ConstSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsSyntax<'a> { - pub repr: BuiltinType, + pub bitflags_repr: Option, pub flags: Vec>>, } impl<'a> Parse<'a> for FlagsSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let repr = parser.parse()?; + let bitflags_repr = if parser.peek2::() { + Some(parser.parens(|p| { + p.parse::()?; + p.parse::()?; + p.parse() + })?) + } else { + None + }; let mut flags = Vec::new(); while !parser.is_empty() { flags.push(parser.parse()?); } - Ok(FlagsSyntax { repr, flags }) + Ok(FlagsSyntax { + bitflags_repr, + flags, + }) } } diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index d61c9b04e..659f940c8 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -116,7 +116,6 @@ impl TypeRef { impl Type { pub fn to_sexpr(&self) -> SExpr { match self { - Type::Flags(a) => a.to_sexpr(), Type::Record(a) => a.to_sexpr(), Type::Variant(a) => a.to_sexpr(), Type::Union(a) => a.to_sexpr(), @@ -137,18 +136,6 @@ impl Type { } } -impl FlagsDatatype { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("flags"), self.repr.to_sexpr()]; - let flags = self - .flags - .iter() - .map(|f| SExpr::docs(&f.docs, f.name.to_sexpr())) - .collect::>(); - SExpr::Vec([header, flags].concat()) - } -} - impl RecordDatatype { pub fn to_sexpr(&self) -> SExpr { let header = vec![SExpr::word("record")]; diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs index 5b88c0c02..d3f7bf817 100644 --- a/proposals/filesystem/tools/witx/src/representation.rs +++ b/proposals/filesystem/tools/witx/src/representation.rs @@ -1,6 +1,5 @@ use crate::{ - BuiltinType, FlagsDatatype, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, - Variant, + BuiltinType, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, Variant, }; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. @@ -93,30 +92,6 @@ impl Representable for Variant { } } -impl Representable for FlagsDatatype { - fn representable(&self, by: &Self) -> RepEquality { - // Integer representation must be compatible - if self.repr.representable(&by.repr) == RepEquality::NotEq { - return RepEquality::NotEq; - } - // For each flag in self, must have flag of same name and position in by: - for (ix, f) in self.flags.iter().enumerate() { - if let Some(by_f) = by.flags.get(ix) { - if by_f.name != f.name { - return RepEquality::NotEq; - } - } else { - return RepEquality::NotEq; - } - } - if by.flags.len() > self.flags.len() { - RepEquality::Superset - } else { - self.repr.representable(&by.repr) - } - } -} - impl Representable for RecordDatatype { fn representable(&self, by: &Self) -> RepEquality { // Records must have exact structural equality - same members, must @@ -204,7 +179,6 @@ impl Representable for Type { fn representable(&self, by: &Self) -> RepEquality { match (&self, &by) { (Type::Variant(s), Type::Variant(b)) => s.representable(b), - (Type::Flags(s), Type::Flags(b)) => s.representable(b), (Type::Record(s), Type::Record(b)) => s.representable(b), (Type::Union(s), Type::Union(b)) => s.representable(b), (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural @@ -237,34 +211,13 @@ mod test { #[test] fn different_typenames() { - let a = def_type("a", "(typename $a (flags u32 $b $c))"); - let d = def_type("d", "(typename $d (flags u32 $b $c))"); + let a = def_type("a", "(typename $a (flags (@witx bitflags u32) $b $c))"); + let d = def_type("d", "(typename $d (flags (@witx bitflags u32) $b $c))"); assert_eq!(a.representable(&d), RepEquality::Eq); assert_eq!(d.representable(&a), RepEquality::Eq); } - #[test] - fn flags() { - let base = def_type("a", "(typename $a (flags u32 $b $c))"); - let extra_flag = def_type("a", "(typename $a (flags u32 $b $c $d))"); - - assert_eq!(base.representable(&extra_flag), RepEquality::Superset); - assert_eq!(extra_flag.representable(&base), RepEquality::NotEq); - - let different_flagnames = def_type("d", "(typename $d (flags u32 $b $e))"); - assert_eq!(base.representable(&different_flagnames), RepEquality::NotEq); - assert_eq!(different_flagnames.representable(&base), RepEquality::NotEq); - - let smaller_size = def_type("a", "(typename $a (flags u16 $b $c))"); - assert_eq!(smaller_size.representable(&base), RepEquality::Superset); - assert_eq!( - smaller_size.representable(&extra_flag), - RepEquality::Superset - ); - assert_eq!(base.representable(&smaller_size), RepEquality::NotEq); - } - #[test] fn enum_() { let base = def_type("a", "(typename $a (enum $b $c))"); diff --git a/proposals/filesystem/tools/witx/src/toplevel.rs b/proposals/filesystem/tools/witx/src/toplevel.rs index 4fb13b8d7..52ef3daa3 100644 --- a/proposals/filesystem/tools/witx/src/toplevel.rs +++ b/proposals/filesystem/tools/witx/src/toplevel.rs @@ -60,11 +60,10 @@ fn parse_file( for t in doc.items { match t.item { TopLevelSyntax::Decl(d) => { - let def = validator + validator .scope(&input, &path) - .validate_decl(&d, &t.comments) + .validate_decl(&d, &t.comments, definitions) .map_err(WitxError::Validation)?; - definitions.push(def); } TopLevelSyntax::Use(u) => { parse_file(u.as_ref(), io, root, validator, definitions, parsed)?; diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 279cf594c..88f4a44fb 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -5,10 +5,10 @@ use crate::{ ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, VariantSyntax, }, - BuiltinType, Case, Constant, Definition, Entry, FlagsDatatype, FlagsMember, HandleDatatype, Id, - IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, - ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, - RecordMember, Type, TypePassedBy, TypeRef, UnionDatatype, UnionVariant, Variant, + BuiltinType, Case, Constant, Definition, Entry, HandleDatatype, Id, IntRepr, InterfaceFunc, + InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, + ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, + TypePassedBy, TypeRef, UnionDatatype, UnionVariant, Variant, }; use std::collections::{hash_map, HashMap}; use std::path::Path; @@ -179,7 +179,8 @@ impl DocValidationScope<'_> { &mut self, decl: &DeclSyntax, comments: &CommentSyntax, - ) -> Result { + definitions: &mut Vec, + ) -> Result<(), ValidationError> { match decl { DeclSyntax::Typename(decl) => { let name = self.introduce(&decl.ident)?; @@ -193,13 +194,32 @@ impl DocValidationScope<'_> { }); self.doc .entries - .insert(name, Entry::Typename(Rc::downgrade(&rc_datatype))); - Ok(Definition::Typename(rc_datatype)) + .insert(name.clone(), Entry::Typename(Rc::downgrade(&rc_datatype))); + definitions.push(Definition::Typename(rc_datatype)); + + if let TypedefSyntax::Flags(syntax) = &decl.def { + if syntax.bitflags_repr.is_some() { + let mut flags_scope = IdentValidation::new(); + let ty = name; + for (i, flag) in syntax.flags.iter().enumerate() { + let name = flags_scope + .introduce(flag.item.name(), self.location(flag.item.span()))?; + let docs = flag.comments.docs(); + definitions.push(Definition::Constant(Constant { + ty: ty.clone(), + name, + value: 1 << i, + docs, + })); + } + } + } } + DeclSyntax::Module(syntax) => { let name = self.introduce(&syntax.name)?; let mut module_validator = ModuleValidation::new(self); - let definitions = syntax + let decls = syntax .decls .iter() .map(|d| module_validator.validate_decl(&d)) @@ -207,14 +227,14 @@ impl DocValidationScope<'_> { let rc_module = Rc::new(Module::new( name.clone(), - definitions, + decls, module_validator.entries, comments.docs(), )); self.doc .entries .insert(name, Entry::Module(Rc::downgrade(&rc_module))); - Ok(Definition::Module(rc_module)) + definitions.push(Definition::Module(rc_module)); } DeclSyntax::Const(syntax) => { @@ -228,14 +248,15 @@ impl DocValidationScope<'_> { let name = scope.introduce(syntax.item.name.name(), loc)?; // TODO: validate `ty` is a integer datatype that `syntax.value` // fits within. - Ok(Definition::Constant(Constant { + definitions.push(Definition::Constant(Constant { ty, name, value: syntax.item.value, docs: syntax.comments.docs(), - })) + })); } } + Ok(()) } fn validate_datatype( @@ -276,7 +297,7 @@ impl DocValidationScope<'_> { } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), - TypedefSyntax::Flags(syntax) => Type::Flags(self.validate_flags(&syntax, span)?), + TypedefSyntax::Flags(syntax) => self.validate_flags(&syntax, span)?, TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), @@ -326,20 +347,14 @@ impl DocValidationScope<'_> { &self, syntax: &FlagsSyntax, span: wast::Span, - ) -> Result { - let mut flags_scope = IdentValidation::new(); - let repr = self.validate_int_repr(&syntax.repr, span)?; - let flags = syntax - .flags - .iter() - .map(|i| { - let name = flags_scope.introduce(i.item.name(), self.location(i.item.span()))?; - let docs = i.comments.docs(); - Ok(FlagsMember { name, docs }) - }) - .collect::, _>>()?; - - Ok(FlagsDatatype { repr, flags }) + ) -> Result { + Ok(match &syntax.bitflags_repr { + Some(repr) => Type::Builtin(self.validate_int_repr(repr, span)?.to_builtin()), + None => { + // TODO: auto-translate to a struct-of-bool-fields + unimplemented!(); + } + }) } fn validate_record( diff --git a/proposals/filesystem/tools/witx/tests/anonymous.rs b/proposals/filesystem/tools/witx/tests/anonymous.rs index 723a36030..a295a3915 100644 --- a/proposals/filesystem/tools/witx/tests/anonymous.rs +++ b/proposals/filesystem/tools/witx/tests/anonymous.rs @@ -20,7 +20,7 @@ fn anonymous_types() { let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum $b)))"); assert!(is_anonymous_record_err(pointer_to_enum)); - let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags u32 $b)))"); + let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags $b)))"); assert!(is_anonymous_record_err(pointer_to_flags)); let pointer_to_handle = witx::parse("(typename $a (@witx pointer (handle)))"); From f98598adc268299637da97c050f53d6ff4e399a4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 11:38:10 -0800 Subject: [PATCH 0844/1772] Represent strings as lists of `char` internally --- proposals/clocks/tools/witx/src/ast.rs | 2 +- proposals/clocks/tools/witx/src/coretypes.rs | 2 +- proposals/clocks/tools/witx/src/docs/ast.rs | 7 +++++-- proposals/clocks/tools/witx/src/docs/md.rs | 8 +++++++- proposals/clocks/tools/witx/src/layout.rs | 11 ++++++----- proposals/clocks/tools/witx/src/parser.rs | 19 +++++++++++++------ proposals/clocks/tools/witx/src/render.rs | 2 +- proposals/clocks/tools/witx/src/validate.rs | 3 +++ 8 files changed, 37 insertions(+), 17 deletions(-) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 556dadd6a..00c9fac83 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -213,8 +213,8 @@ impl Type { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { - String, Char8, + Char, USize, U8, U16, diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index b2cacf8e8..3a5e41284 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -35,7 +35,6 @@ impl Type { pub fn passed_by(&self) -> TypePassedBy { match self { Type::Builtin(b) => match b { - BuiltinType::String => TypePassedBy::PointerLengthPair, BuiltinType::U8 | BuiltinType::U16 | BuiltinType::U32 @@ -43,6 +42,7 @@ impl Type { | BuiltinType::S16 | BuiltinType::S32 | BuiltinType::Char8 + | BuiltinType::Char | BuiltinType::USize => TypePassedBy::Value(AtomType::I32), BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index c9fce08ce..a776907a3 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -323,8 +323,8 @@ impl ToMarkdown for InterfaceFuncParam { impl BuiltinType { pub fn type_name(&self) -> &'static str { match self { - BuiltinType::String => "string", BuiltinType::Char8 => "char8", + BuiltinType::Char => "char", BuiltinType::USize => "usize", BuiltinType::U8 => "u8", BuiltinType::U16 => "u16", @@ -345,7 +345,10 @@ impl TypeRef { match self { TypeRef::Name(n) => n.name.as_str().to_string(), TypeRef::Value(ref v) => match &**v { - Type::List(a) => format!("List<{}>", a.type_name()), + Type::List(a) => match &*a.type_() { + Type::Builtin(BuiltinType::Char) => "string".to_string(), + _ => format!("List<{}>", a.type_name()), + }, Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index 22ea16074..6519d0745 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -360,7 +360,13 @@ impl fmt::Display for MdType { Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, - Self::List { r#type } => f.write_fmt(format_args!(": `List<{}>`", r#type))?, + Self::List { r#type } => { + if r#type == "char" { + f.write_str(": `string`")? + } else { + f.write_fmt(format_args!(": `List<{}>`", r#type))? + } + } Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, Self::ConstPointer { r#type } => { f.write_fmt(format_args!(": `ConstPointer<{}>`", r#type))? diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index 2154eecfe..1e4b03211 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -68,7 +68,7 @@ impl Type { Type::Variant(s) => s.mem_size_align(), Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), - Type::List { .. } => BuiltinType::String.mem_size_align(), + Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), } @@ -242,14 +242,15 @@ impl Layout for HandleDatatype { impl Layout for BuiltinType { fn mem_size_align(&self) -> SizeAlign { match self { - BuiltinType::String => SizeAlign { size: 8, align: 4 }, // Pointer and Length BuiltinType::U8 | BuiltinType::S8 | BuiltinType::Char8 => { SizeAlign { size: 1, align: 1 } } BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, - BuiltinType::USize | BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { - SizeAlign { size: 4, align: 4 } - } + BuiltinType::Char + | BuiltinType::USize + | BuiltinType::U32 + | BuiltinType::S32 + | BuiltinType::F32 => SizeAlign { size: 4, align: 4 }, BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { SizeAlign { size: 8, align: 8 } } diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index fad70619b..6015cb052 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -20,6 +20,7 @@ mod kw { wast::custom_keyword!(bitflags); wast::custom_keyword!(char8); + wast::custom_keyword!(char); wast::custom_keyword!(const_pointer); wast::custom_keyword!(f32); wast::custom_keyword!(f64); @@ -57,12 +58,12 @@ mod annotation { impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::String) - } else if l.peek::() { + if l.peek::() { parser.parse::()?; Ok(BuiltinType::Char8) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::Char) } else if l.peek::() { parser.parse::()?; Ok(BuiltinType::U8) @@ -101,8 +102,8 @@ impl Parse<'_> for BuiltinType { impl wast::parser::Peek for BuiltinType { fn peek(cursor: wast::parser::Cursor<'_>) -> bool { - ::peek(cursor) - || ::peek(cursor) + ::peek(cursor) + || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) @@ -114,10 +115,12 @@ impl wast::parser::Peek for BuiltinType { || ::peek(cursor) || ::peek(cursor) } + fn display() -> &'static str { "builtin type" } } + #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct CommentSyntax<'a> { pub comments: Vec<&'a str>, @@ -283,6 +286,7 @@ pub enum TypedefSyntax<'a> { ConstPointer(Box>), Builtin(BuiltinType), Ident(wast::Id<'a>), + String, } impl<'a> Parse<'a> for TypedefSyntax<'a> { @@ -292,6 +296,9 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Ident(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Builtin(parser.parse()?)) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::String) } else if l.peek::() { parser.parens(|parser| { let mut l = parser.lookahead1(); diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 659f940c8..16b92d48a 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -77,8 +77,8 @@ impl Id { impl BuiltinType { pub fn to_sexpr(&self) -> SExpr { match self { - BuiltinType::String => SExpr::word("string"), BuiltinType::Char8 => SExpr::word("char8"), + BuiltinType::Char => SExpr::word("char"), BuiltinType::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), BuiltinType::U8 => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 88f4a44fb..8d698c77a 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -311,6 +311,9 @@ impl DocValidationScope<'_> { Type::ConstPointer(self.validate_datatype(syntax, false, span)?) } TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), + TypedefSyntax::String => { + Type::List(TypeRef::Value(Rc::new(Type::Builtin(BuiltinType::Char)))) + } TypedefSyntax::Ident { .. } => unreachable!(), }))), } From c4b46cae128e575e927ec9ffb1456bdb7deead1c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 11:38:10 -0800 Subject: [PATCH 0845/1772] Represent strings as lists of `char` internally --- proposals/random/tools/witx/src/ast.rs | 2 +- proposals/random/tools/witx/src/coretypes.rs | 2 +- proposals/random/tools/witx/src/docs/ast.rs | 7 +++++-- proposals/random/tools/witx/src/docs/md.rs | 8 +++++++- proposals/random/tools/witx/src/layout.rs | 11 ++++++----- proposals/random/tools/witx/src/parser.rs | 19 +++++++++++++------ proposals/random/tools/witx/src/render.rs | 2 +- proposals/random/tools/witx/src/validate.rs | 3 +++ 8 files changed, 37 insertions(+), 17 deletions(-) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 556dadd6a..00c9fac83 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -213,8 +213,8 @@ impl Type { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { - String, Char8, + Char, USize, U8, U16, diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index b2cacf8e8..3a5e41284 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -35,7 +35,6 @@ impl Type { pub fn passed_by(&self) -> TypePassedBy { match self { Type::Builtin(b) => match b { - BuiltinType::String => TypePassedBy::PointerLengthPair, BuiltinType::U8 | BuiltinType::U16 | BuiltinType::U32 @@ -43,6 +42,7 @@ impl Type { | BuiltinType::S16 | BuiltinType::S32 | BuiltinType::Char8 + | BuiltinType::Char | BuiltinType::USize => TypePassedBy::Value(AtomType::I32), BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index c9fce08ce..a776907a3 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -323,8 +323,8 @@ impl ToMarkdown for InterfaceFuncParam { impl BuiltinType { pub fn type_name(&self) -> &'static str { match self { - BuiltinType::String => "string", BuiltinType::Char8 => "char8", + BuiltinType::Char => "char", BuiltinType::USize => "usize", BuiltinType::U8 => "u8", BuiltinType::U16 => "u16", @@ -345,7 +345,10 @@ impl TypeRef { match self { TypeRef::Name(n) => n.name.as_str().to_string(), TypeRef::Value(ref v) => match &**v { - Type::List(a) => format!("List<{}>", a.type_name()), + Type::List(a) => match &*a.type_() { + Type::Builtin(BuiltinType::Char) => "string".to_string(), + _ => format!("List<{}>", a.type_name()), + }, Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index 22ea16074..6519d0745 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -360,7 +360,13 @@ impl fmt::Display for MdType { Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, - Self::List { r#type } => f.write_fmt(format_args!(": `List<{}>`", r#type))?, + Self::List { r#type } => { + if r#type == "char" { + f.write_str(": `string`")? + } else { + f.write_fmt(format_args!(": `List<{}>`", r#type))? + } + } Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, Self::ConstPointer { r#type } => { f.write_fmt(format_args!(": `ConstPointer<{}>`", r#type))? diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index 2154eecfe..1e4b03211 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -68,7 +68,7 @@ impl Type { Type::Variant(s) => s.mem_size_align(), Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), - Type::List { .. } => BuiltinType::String.mem_size_align(), + Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), } @@ -242,14 +242,15 @@ impl Layout for HandleDatatype { impl Layout for BuiltinType { fn mem_size_align(&self) -> SizeAlign { match self { - BuiltinType::String => SizeAlign { size: 8, align: 4 }, // Pointer and Length BuiltinType::U8 | BuiltinType::S8 | BuiltinType::Char8 => { SizeAlign { size: 1, align: 1 } } BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, - BuiltinType::USize | BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { - SizeAlign { size: 4, align: 4 } - } + BuiltinType::Char + | BuiltinType::USize + | BuiltinType::U32 + | BuiltinType::S32 + | BuiltinType::F32 => SizeAlign { size: 4, align: 4 }, BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { SizeAlign { size: 8, align: 8 } } diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index fad70619b..6015cb052 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -20,6 +20,7 @@ mod kw { wast::custom_keyword!(bitflags); wast::custom_keyword!(char8); + wast::custom_keyword!(char); wast::custom_keyword!(const_pointer); wast::custom_keyword!(f32); wast::custom_keyword!(f64); @@ -57,12 +58,12 @@ mod annotation { impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::String) - } else if l.peek::() { + if l.peek::() { parser.parse::()?; Ok(BuiltinType::Char8) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::Char) } else if l.peek::() { parser.parse::()?; Ok(BuiltinType::U8) @@ -101,8 +102,8 @@ impl Parse<'_> for BuiltinType { impl wast::parser::Peek for BuiltinType { fn peek(cursor: wast::parser::Cursor<'_>) -> bool { - ::peek(cursor) - || ::peek(cursor) + ::peek(cursor) + || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) @@ -114,10 +115,12 @@ impl wast::parser::Peek for BuiltinType { || ::peek(cursor) || ::peek(cursor) } + fn display() -> &'static str { "builtin type" } } + #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct CommentSyntax<'a> { pub comments: Vec<&'a str>, @@ -283,6 +286,7 @@ pub enum TypedefSyntax<'a> { ConstPointer(Box>), Builtin(BuiltinType), Ident(wast::Id<'a>), + String, } impl<'a> Parse<'a> for TypedefSyntax<'a> { @@ -292,6 +296,9 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Ident(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Builtin(parser.parse()?)) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::String) } else if l.peek::() { parser.parens(|parser| { let mut l = parser.lookahead1(); diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 659f940c8..16b92d48a 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -77,8 +77,8 @@ impl Id { impl BuiltinType { pub fn to_sexpr(&self) -> SExpr { match self { - BuiltinType::String => SExpr::word("string"), BuiltinType::Char8 => SExpr::word("char8"), + BuiltinType::Char => SExpr::word("char"), BuiltinType::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), BuiltinType::U8 => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 88f4a44fb..8d698c77a 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -311,6 +311,9 @@ impl DocValidationScope<'_> { Type::ConstPointer(self.validate_datatype(syntax, false, span)?) } TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), + TypedefSyntax::String => { + Type::List(TypeRef::Value(Rc::new(Type::Builtin(BuiltinType::Char)))) + } TypedefSyntax::Ident { .. } => unreachable!(), }))), } From 05c2bf7c765566b7fa9ba711db11353489daf812 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 11:38:10 -0800 Subject: [PATCH 0846/1772] Represent strings as lists of `char` internally --- proposals/filesystem/tools/witx/src/ast.rs | 2 +- .../filesystem/tools/witx/src/coretypes.rs | 2 +- .../filesystem/tools/witx/src/docs/ast.rs | 7 +++++-- .../filesystem/tools/witx/src/docs/md.rs | 8 +++++++- proposals/filesystem/tools/witx/src/layout.rs | 11 ++++++----- proposals/filesystem/tools/witx/src/parser.rs | 19 +++++++++++++------ proposals/filesystem/tools/witx/src/render.rs | 2 +- .../filesystem/tools/witx/src/validate.rs | 3 +++ 8 files changed, 37 insertions(+), 17 deletions(-) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 556dadd6a..00c9fac83 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -213,8 +213,8 @@ impl Type { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { - String, Char8, + Char, USize, U8, U16, diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index b2cacf8e8..3a5e41284 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -35,7 +35,6 @@ impl Type { pub fn passed_by(&self) -> TypePassedBy { match self { Type::Builtin(b) => match b { - BuiltinType::String => TypePassedBy::PointerLengthPair, BuiltinType::U8 | BuiltinType::U16 | BuiltinType::U32 @@ -43,6 +42,7 @@ impl Type { | BuiltinType::S16 | BuiltinType::S32 | BuiltinType::Char8 + | BuiltinType::Char | BuiltinType::USize => TypePassedBy::Value(AtomType::I32), BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index c9fce08ce..a776907a3 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -323,8 +323,8 @@ impl ToMarkdown for InterfaceFuncParam { impl BuiltinType { pub fn type_name(&self) -> &'static str { match self { - BuiltinType::String => "string", BuiltinType::Char8 => "char8", + BuiltinType::Char => "char", BuiltinType::USize => "usize", BuiltinType::U8 => "u8", BuiltinType::U16 => "u16", @@ -345,7 +345,10 @@ impl TypeRef { match self { TypeRef::Name(n) => n.name.as_str().to_string(), TypeRef::Value(ref v) => match &**v { - Type::List(a) => format!("List<{}>", a.type_name()), + Type::List(a) => match &*a.type_() { + Type::Builtin(BuiltinType::Char) => "string".to_string(), + _ => format!("List<{}>", a.type_name()), + }, Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index 22ea16074..6519d0745 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -360,7 +360,13 @@ impl fmt::Display for MdType { Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, Self::Union => f.write_fmt(format_args!(": Union"))?, - Self::List { r#type } => f.write_fmt(format_args!(": `List<{}>`", r#type))?, + Self::List { r#type } => { + if r#type == "char" { + f.write_str(": `string`")? + } else { + f.write_fmt(format_args!(": `List<{}>`", r#type))? + } + } Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, Self::ConstPointer { r#type } => { f.write_fmt(format_args!(": `ConstPointer<{}>`", r#type))? diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index 2154eecfe..1e4b03211 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -68,7 +68,7 @@ impl Type { Type::Variant(s) => s.mem_size_align(), Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), - Type::List { .. } => BuiltinType::String.mem_size_align(), + Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), } @@ -242,14 +242,15 @@ impl Layout for HandleDatatype { impl Layout for BuiltinType { fn mem_size_align(&self) -> SizeAlign { match self { - BuiltinType::String => SizeAlign { size: 8, align: 4 }, // Pointer and Length BuiltinType::U8 | BuiltinType::S8 | BuiltinType::Char8 => { SizeAlign { size: 1, align: 1 } } BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, - BuiltinType::USize | BuiltinType::U32 | BuiltinType::S32 | BuiltinType::F32 => { - SizeAlign { size: 4, align: 4 } - } + BuiltinType::Char + | BuiltinType::USize + | BuiltinType::U32 + | BuiltinType::S32 + | BuiltinType::F32 => SizeAlign { size: 4, align: 4 }, BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { SizeAlign { size: 8, align: 8 } } diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index fad70619b..6015cb052 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -20,6 +20,7 @@ mod kw { wast::custom_keyword!(bitflags); wast::custom_keyword!(char8); + wast::custom_keyword!(char); wast::custom_keyword!(const_pointer); wast::custom_keyword!(f32); wast::custom_keyword!(f64); @@ -57,12 +58,12 @@ mod annotation { impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::String) - } else if l.peek::() { + if l.peek::() { parser.parse::()?; Ok(BuiltinType::Char8) + } else if l.peek::() { + parser.parse::()?; + Ok(BuiltinType::Char) } else if l.peek::() { parser.parse::()?; Ok(BuiltinType::U8) @@ -101,8 +102,8 @@ impl Parse<'_> for BuiltinType { impl wast::parser::Peek for BuiltinType { fn peek(cursor: wast::parser::Cursor<'_>) -> bool { - ::peek(cursor) - || ::peek(cursor) + ::peek(cursor) + || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) @@ -114,10 +115,12 @@ impl wast::parser::Peek for BuiltinType { || ::peek(cursor) || ::peek(cursor) } + fn display() -> &'static str { "builtin type" } } + #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct CommentSyntax<'a> { pub comments: Vec<&'a str>, @@ -283,6 +286,7 @@ pub enum TypedefSyntax<'a> { ConstPointer(Box>), Builtin(BuiltinType), Ident(wast::Id<'a>), + String, } impl<'a> Parse<'a> for TypedefSyntax<'a> { @@ -292,6 +296,9 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Ident(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Builtin(parser.parse()?)) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::String) } else if l.peek::() { parser.parens(|parser| { let mut l = parser.lookahead1(); diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 659f940c8..16b92d48a 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -77,8 +77,8 @@ impl Id { impl BuiltinType { pub fn to_sexpr(&self) -> SExpr { match self { - BuiltinType::String => SExpr::word("string"), BuiltinType::Char8 => SExpr::word("char8"), + BuiltinType::Char => SExpr::word("char"), BuiltinType::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), BuiltinType::U8 => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 88f4a44fb..8d698c77a 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -311,6 +311,9 @@ impl DocValidationScope<'_> { Type::ConstPointer(self.validate_datatype(syntax, false, span)?) } TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), + TypedefSyntax::String => { + Type::List(TypeRef::Value(Rc::new(Type::Builtin(BuiltinType::Char)))) + } TypedefSyntax::Ident { .. } => unreachable!(), }))), } From c2f660a48fb24dacd031e8a67b0072965c96b234 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 14:12:49 -0800 Subject: [PATCH 0847/1772] Implement Union in terms of Variant --- proposals/clocks/phases/ephemeral/docs.md | 36 ++- .../phases/ephemeral/witx/typenames.witx | 20 +- .../clocks/phases/old/snapshot_0/docs.md | 24 +- .../phases/old/snapshot_0/witx/typenames.witx | 12 +- proposals/clocks/phases/snapshot/docs.md | 24 +- .../phases/snapshot/witx/typenames.witx | 13 +- proposals/clocks/tools/witx/src/ast.rs | 15 -- proposals/clocks/tools/witx/src/coretypes.rs | 2 +- proposals/clocks/tools/witx/src/docs/ast.rs | 82 ++----- proposals/clocks/tools/witx/src/docs/md.rs | 2 - proposals/clocks/tools/witx/src/layout.rs | 56 ----- proposals/clocks/tools/witx/src/lib.rs | 2 +- proposals/clocks/tools/witx/src/parser.rs | 91 +++++--- proposals/clocks/tools/witx/src/render.rs | 35 +-- .../clocks/tools/witx/src/representation.rs | 103 +++----- proposals/clocks/tools/witx/src/validate.rs | 220 ++++++++++-------- .../clocks/tools/witx/tests/anonymous.rs | 10 +- proposals/clocks/tools/witx/tests/union.rs | 111 ++++----- 18 files changed, 360 insertions(+), 498 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index c579e00a3..7ea6969f8 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -859,20 +859,18 @@ The state of the file descriptor. Offset: 8 -## `event_u`: Union +## `event_u`: Variant The contents of an [`event`](#event). Size: 24 Alignment: 8 -### Union Layout +### Variant Layout +- size: 24 +- align: 8 - tag_size: 1 -- tag_align: 1 -- contents_offset: 8 -- contents_size: 16 -- contents_align: 8 -### Union variants +### Variant cases - `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) - `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) @@ -961,20 +959,18 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Union +## `subscription_u`: Variant The contents of a [`subscription`](#subscription). Size: 40 Alignment: 8 -### Union Layout +### Variant Layout +- size: 40 +- align: 8 - tag_size: 1 -- tag_align: 1 -- contents_offset: 8 -- contents_size: 32 -- contents_align: 8 -### Union variants +### Variant cases - `clock`: [`subscription_clock`](#subscription_clock) - `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) @@ -1078,20 +1074,18 @@ The length of the directory name for use with `fd_prestat_dir_name`. Offset: 0 -## `prestat`: Union +## `prestat`: Variant Information about a pre-opened capability. Size: 8 Alignment: 4 -### Union Layout +### Variant Layout +- size: 8 +- align: 4 - tag_size: 1 -- tag_align: 1 -- contents_offset: 4 -- contents_size: 4 -- contents_align: 4 -### Union variants +### Variant cases - `dir`: [`prestat_dir`](#prestat_dir) When type is [`preopentype::dir`](#preopentype.dir): diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index e10c4c30d..503aa0cf6 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -562,10 +562,10 @@ ;;; The contents of an `event`. (typename $event_u - (union $eventtype - (field $fd_read $event_fd_readwrite) - (field $fd_write $event_fd_readwrite) - (empty $clock) + (variant (@witx tag $eventtype) + (case $fd_read $event_fd_readwrite) + (case $fd_write $event_fd_readwrite) + (case $clock) ) ) @@ -620,10 +620,10 @@ ;;; The contents of a `subscription`. (typename $subscription_u - (union $eventtype - (field $clock $subscription_clock) - (field $fd_read $subscription_fd_readwrite) - (field $fd_write $subscription_fd_readwrite) + (union (@witx tag $eventtype) + $subscription_clock + $subscription_fd_readwrite + $subscription_fd_readwrite ) ) @@ -691,8 +691,8 @@ ;;; Information about a pre-opened capability. (typename $prestat - (union $preopentype + (union (@witx tag $preopentype) ;;; When type is `preopentype::dir`: - (field $dir $prestat_dir) + $prestat_dir ) ) diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index 0e2f5bde0..e77002bc6 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -899,20 +899,18 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Union +## `subscription_u`: Variant The contents of a [`subscription`](#subscription). Size: 48 Alignment: 8 -### Union Layout +### Variant Layout +- size: 48 +- align: 8 - tag_size: 1 -- tag_align: 1 -- contents_offset: 8 -- contents_size: 40 -- contents_align: 8 -### Union variants +### Variant cases - `clock`: [`subscription_clock`](#subscription_clock) - `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) @@ -1148,20 +1146,18 @@ The length of the directory name for use with [`fd_prestat_dir_name`](#fd_presta Offset: 0 -## `prestat`: Union +## `prestat`: Variant Information about a pre-opened capability. Size: 8 Alignment: 4 -### Union Layout +### Variant Layout +- size: 8 +- align: 4 - tag_size: 1 -- tag_align: 1 -- contents_offset: 4 -- contents_size: 4 -- contents_align: 4 -### Union variants +### Variant cases - `dir`: [`prestat_dir`](#prestat_dir) # Modules diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx index f24000e00..eb6f70020 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx @@ -570,10 +570,10 @@ ;;; The contents of a `subscription`. (typename $subscription_u - (union $eventtype - (field $clock $subscription_clock) - (field $fd_read $subscription_fd_readwrite) - (field $fd_write $subscription_fd_readwrite) + (union (@witx tag $eventtype) + $subscription_clock + $subscription_fd_readwrite + $subscription_fd_readwrite ) ) @@ -740,7 +740,7 @@ ;;; Information about a pre-opened capability. (typename $prestat - (union $preopentype - (field $dir $prestat_dir) + (union (@witx tag $preopentype) + $prestat_dir ) ) diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index e13dcc79d..1bbbe59f2 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -896,20 +896,18 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Union +## `subscription_u`: Variant The contents of a [`subscription`](#subscription). Size: 40 Alignment: 8 -### Union Layout +### Variant Layout +- size: 40 +- align: 8 - tag_size: 1 -- tag_align: 1 -- contents_offset: 8 -- contents_size: 32 -- contents_align: 8 -### Union variants +### Variant cases - `clock`: [`subscription_clock`](#subscription_clock) - `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) @@ -1145,20 +1143,18 @@ The length of the directory name for use with [`fd_prestat_dir_name`](#fd_presta Offset: 0 -## `prestat`: Union +## `prestat`: Variant Information about a pre-opened capability. Size: 8 Alignment: 4 -### Union Layout +### Variant Layout +- size: 8 +- align: 4 - tag_size: 1 -- tag_align: 1 -- contents_offset: 4 -- contents_size: 4 -- contents_align: 4 -### Union variants +### Variant cases - `dir`: [`prestat_dir`](#prestat_dir) # Modules diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx index 13eb1759f..70e726553 100644 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -570,10 +570,11 @@ ;;; The contents of a `subscription`. (typename $subscription_u - (union $eventtype - (field $clock $subscription_clock) - (field $fd_read $subscription_fd_readwrite) - (field $fd_write $subscription_fd_readwrite) + (union + (@witx tag $eventtype) + $subscription_clock + $subscription_fd_readwrite + $subscription_fd_readwrite ) ) @@ -740,8 +741,8 @@ ;;; Information about a pre-opened capability. (typename $prestat - (union $preopentype - (field $dir $prestat_dir) + (union (@witx tag $preopentype) + $prestat_dir ) ) diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 00c9fac83..5ba525520 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -187,7 +187,6 @@ impl NamedType { pub enum Type { Record(RecordDatatype), Variant(Variant), - Union(UnionDatatype), Handle(HandleDatatype), List(TypeRef), Pointer(TypeRef), @@ -201,7 +200,6 @@ impl Type { match self { Record(_) => "record", Variant(_) => "variant", - Union(_) => "union", Handle(_) => "handle", List(_) => "list", Pointer(_) => "pointer", @@ -272,19 +270,6 @@ pub struct Case { pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct UnionDatatype { - pub tag: Rc, - pub variants: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct UnionVariant { - pub name: Id, - pub tref: Option, - pub docs: String, -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct HandleDatatype {} diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index 3a5e41284..35fea801e 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -50,7 +50,7 @@ impl Type { }, Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), - Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Record { .. } => TypePassedBy::Pointer, Type::Variant(v) => { if v.cases.iter().all(|c| c.tref.is_none()) { TypePassedBy::Value(v.tag_repr.into()) diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index a776907a3..eb4d3e7cb 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -89,7 +89,6 @@ impl ToMarkdown for Type { match self { Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), - Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), Self::List(a) => { node.content_ref_mut::().r#type = Some(MdType::List { @@ -144,6 +143,27 @@ impl ToMarkdown for RecordDatatype { impl ToMarkdown for Variant { fn generate(&self, node: MdNodeRef) { + if self.cases.iter().any(|c| c.tref.is_some()) { + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Variant Layout")); + + let whole = self.mem_size_align(); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("size: {}", whole.size), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("align: {}", whole.align), + )); + + let tag = self.tag_repr.mem_size_align(); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("tag_size: {}", tag.size), + )); + } + let heading = heading_from_node(&node, 1); node.new_child(MdSection::new(heading, "Variant cases")); @@ -169,61 +189,6 @@ impl ToMarkdown for Variant { } } -impl ToMarkdown for UnionDatatype { - fn generate(&self, node: MdNodeRef) { - // Sizes & Alignments - let sizes_heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(sizes_heading, "Union Layout")); - let union_layout = &self.union_layout(); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("tag_size: {}", union_layout.tag_size).as_str(), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("tag_align: {}", union_layout.tag_align).as_str(), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("contents_offset: {}", union_layout.contents_offset).as_str(), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("contents_size: {}", union_layout.contents_size).as_str(), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("contents_align: {}", union_layout.contents_align).as_str(), - )); - - // Variants - let variants_heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(variants_heading, "Union variants")); - - for variant in &self.variants { - let name = variant.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let n = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - &variant.docs, - )); - if let Some(ref tref) = variant.tref { - tref.generate(n.clone()); - } else { - n.content_ref_mut::().r#type = None; - } - } - - node.content_ref_mut::().r#type = Some(MdType::Union); - } -} - impl ToMarkdown for HandleDatatype { fn generate(&self, node: MdNodeRef) { // TODO this needs more work @@ -352,10 +317,7 @@ impl TypeRef { Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), - Type::Record { .. } - | Type::Variant { .. } - | Type::Union { .. } - | Type::Handle { .. } => { + Type::Record { .. } | Type::Variant { .. } | Type::Handle { .. } => { unimplemented!("type_name of anonymous compound datatypes") } }, diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index 6519d0745..d3d5b756d 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -345,7 +345,6 @@ impl MdNamedType { pub(super) enum MdType { Record, Variant, - Union, List { r#type: String }, Pointer { r#type: String }, ConstPointer { r#type: String }, @@ -359,7 +358,6 @@ impl fmt::Display for MdType { match self { Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, - Self::Union => f.write_fmt(format_args!(": Union"))?, Self::List { r#type } => { if r#type == "char" { f.write_str(": `string`")? diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index 1e4b03211..6b77d8a32 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -66,7 +66,6 @@ impl Type { match &self { Type::Record(s) => s.layout(cache), Type::Variant(s) => s.mem_size_align(), - Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), @@ -178,61 +177,6 @@ mod test { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct UnionLayout { - pub tag_size: usize, - pub tag_align: usize, - pub contents_offset: usize, - pub contents_size: usize, - pub contents_align: usize, -} - -impl Layout for UnionLayout { - fn mem_size_align(&self) -> SizeAlign { - let align = std::cmp::max(self.tag_align, self.contents_align); - let size = align_to(self.contents_offset + self.contents_size, align); - SizeAlign { size, align } - } -} - -impl UnionDatatype { - pub fn union_layout(&self) -> UnionLayout { - let mut cache = HashMap::new(); - self.union_layout_(&mut cache) - } - fn union_layout_(&self, cache: &mut HashMap) -> UnionLayout { - let tag = self.tag.layout(cache); - - let variant_sas = self - .variants - .iter() - .filter_map(|v| v.tref.as_ref().map(|t| t.layout(cache))) - .collect::>(); - - let contents_size = variant_sas.iter().map(|sa| sa.size).max().unwrap_or(0); - let contents_align = variant_sas.iter().map(|sa| sa.align).max().unwrap_or(1); - - UnionLayout { - tag_size: tag.size, - tag_align: tag.align, - contents_offset: align_to(tag.size, contents_align), - contents_size, - contents_align, - } - } - - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - self.union_layout_(cache).mem_size_align() - } -} - -impl Layout for UnionDatatype { - fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } -} - impl Layout for HandleDatatype { fn mem_size_align(&self) -> SizeAlign { BuiltinType::U32.mem_size_align() diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 72774c16c..9c0f53060 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -27,7 +27,7 @@ pub use ast::*; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; -pub use layout::{Layout, RecordMemberLayout, SizeAlign, UnionLayout}; +pub use layout::{Layout, RecordMemberLayout, SizeAlign}; pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 6015cb052..ee8bf081e 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -19,6 +19,7 @@ mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; wast::custom_keyword!(bitflags); + wast::custom_keyword!(case); wast::custom_keyword!(char8); wast::custom_keyword!(char); wast::custom_keyword!(const_pointer); @@ -48,6 +49,7 @@ mod kw { wast::custom_keyword!(u64); wast::custom_keyword!(u8); wast::custom_keyword!(usize); + wast::custom_keyword!(variant); } mod annotation { @@ -280,6 +282,7 @@ pub enum TypedefSyntax<'a> { Flags(FlagsSyntax<'a>), Record(RecordSyntax<'a>), Union(UnionSyntax<'a>), + Variant(VariantSyntax<'a>), Handle(HandleSyntax), List(Box>), Pointer(Box>), @@ -310,6 +313,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Record(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Union(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Variant(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Handle(parser.parse()?)) } else if l.peek::() { @@ -448,42 +453,24 @@ impl<'a> Parse<'a> for FieldSyntax<'a> { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum VariantSyntax<'a> { - Field(FieldSyntax<'a>), - Empty(wast::Id<'a>), -} - -impl<'a> Parse<'a> for VariantSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - let mut l = p.lookahead1(); - if l.peek::() { - parser.parse::()?; - let name = p.parse()?; - let type_ = p.parse()?; - Ok(VariantSyntax::Field(FieldSyntax { name, type_ })) - } else if l.peek::() { - parser.parse::()?; - let name = p.parse()?; - Ok(VariantSyntax::Empty(name)) - } else { - Err(l.error()) - } - }) - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionSyntax<'a> { - pub tag: wast::Id<'a>, - pub fields: Vec>>, + pub tag: Option>>, + pub fields: Vec>>, } impl<'a> Parse<'a> for UnionSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let tag = parser.parse()?; + let tag = if parser.peek2::() { + Some(parser.parens(|p| { + p.parse::()?; + p.parse::()?; + p.parse().map(Box::new) + })?) + } else { + None + }; let mut fields = Vec::new(); fields.push(parser.parse()?); while !parser.is_empty() { @@ -493,6 +480,52 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct VariantSyntax<'a> { + pub tag: Option>>, + pub cases: Vec>>, +} + +impl<'a> Parse<'a> for VariantSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let tag = if parser.peek2::() { + Some(parser.parens(|p| { + p.parse::()?; + p.parse::()?; + p.parse().map(Box::new) + })?) + } else { + None + }; + let mut cases = Vec::new(); + while !parser.is_empty() { + cases.push(parser.parens(|p| p.parse())?); + } + Ok(VariantSyntax { tag, cases }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CaseSyntax<'a> { + pub name: wast::Id<'a>, + pub ty: Option>, +} + +impl<'a> Parse<'a> for CaseSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + Ok(CaseSyntax { + name: parser.parse()?, + ty: if parser.is_empty() { + None + } else { + Some(parser.parse()?) + }, + }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct HandleSyntax {} diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 16b92d48a..60df3d6a2 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -118,7 +118,6 @@ impl Type { match self { Type::Record(a) => a.to_sexpr(), Type::Variant(a) => a.to_sexpr(), - Type::Union(a) => a.to_sexpr(), Type::Handle(a) => a.to_sexpr(), Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), Type::Pointer(p) => SExpr::Vec(vec![ @@ -172,6 +171,11 @@ impl Variant { } } else { list.push(SExpr::word("variant")); + list.push(SExpr::Vec(vec![ + SExpr::word("@witx"), + SExpr::word("tag"), + self.tag_repr.to_sexpr(), + ])); for case in self.cases.iter() { let mut case_expr = vec![SExpr::word("case"), case.name.to_sexpr()]; if let Some(ty) = &case.tref { @@ -184,39 +188,12 @@ impl Variant { } } -impl UnionDatatype { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("union"), self.tag.name.to_sexpr()]; - let variants = self - .variants - .iter() - .map(|v| { - if let Some(ref tref) = v.tref { - SExpr::docs( - &v.docs, - SExpr::Vec(vec![ - SExpr::word("field"), - v.name.to_sexpr(), - tref.to_sexpr(), - ]), - ) - } else { - SExpr::docs( - &v.docs, - SExpr::Vec(vec![SExpr::word("empty"), v.name.to_sexpr()]), - ) - } - }) - .collect::>(); - SExpr::Vec([header, variants].concat()) - } -} - impl HandleDatatype { pub fn to_sexpr(&self) -> SExpr { SExpr::Vec(vec![SExpr::word("handle")]) } } + impl IntRepr { pub fn to_sexpr(&self) -> SExpr { match self { diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs index d3f7bf817..6c36e71e7 100644 --- a/proposals/clocks/tools/witx/src/representation.rs +++ b/proposals/clocks/tools/witx/src/representation.rs @@ -1,6 +1,5 @@ -use crate::{ - BuiltinType, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, Variant, -}; +use crate::{BuiltinType, IntRepr, NamedType, RecordDatatype, Type, TypeRef, Variant}; +use std::collections::HashMap; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -70,24 +69,41 @@ impl Representable for IntRepr { impl Representable for Variant { fn representable(&self, by: &Self) -> RepEquality { + let mut superset = false; // Integer representation must be compatible - if self.tag_repr.representable(&by.tag_repr) == RepEquality::NotEq { - return RepEquality::NotEq; + match self.tag_repr.representable(&by.tag_repr) { + RepEquality::NotEq => return RepEquality::NotEq, + RepEquality::Eq => {} + RepEquality::Superset => superset = true, } - // For each variant in self, must have variant of same name and position in by: - for (ix, v) in self.cases.iter().enumerate() { - if let Some(by_v) = by.cases.get(ix) { - if by_v.name != v.name { - return RepEquality::NotEq; - } - } else { - return RepEquality::NotEq; + let other_by_name = by + .cases + .iter() + .map(|c| (&c.name, c)) + .collect::>(); + // For each variant in self, must have variant of same name in by: + for v in self.cases.iter() { + let other_ty = match other_by_name.get(&v.name) { + Some(other) => &other.tref, + None => return RepEquality::NotEq, + }; + match (&v.tref, other_ty) { + (Some(me), Some(other)) => match me.representable(other) { + RepEquality::NotEq => return RepEquality::NotEq, + RepEquality::Eq => {} + RepEquality::Superset => superset = true, + }, + // We added fields, that's not ok + (Some(_), None) => return RepEquality::NotEq, + // Fields were deleted, that's ok + (None, Some(_)) => superset = true, + (None, None) => {} } } - if by.cases.len() > self.cases.len() { + if superset || self.cases.len() < by.cases.len() { RepEquality::Superset } else { - self.tag_repr.representable(&by.tag_repr) + RepEquality::Eq } } } @@ -113,56 +129,6 @@ impl Representable for RecordDatatype { } } -impl Representable for UnionDatatype { - fn representable(&self, by: &Self) -> RepEquality { - // Unions must have equal variants, by name (independent of order). If `by` has extra - // variants, its a superset. - // We would require require a more expressive RepEquality enum to describe which variants - // might be supersets. - if self.variants.len() > by.variants.len() { - return RepEquality::NotEq; - } - for v in self.variants.iter() { - if let Some(byv) = by.variants.iter().find(|byv| byv.name == v.name) { - if v.tref.is_none() && byv.tref.is_none() { - // Both empty is OK - } else if v.tref.is_some() && byv.tref.is_some() { - if v.tref - .as_ref() - .unwrap() - .type_() - .representable(&*byv.tref.as_ref().unwrap().type_()) - != RepEquality::Eq - { - // Fields must be Eq - return RepEquality::NotEq; - } - } else { - // Either one empty means not representable - return RepEquality::NotEq; - } - } else { - return RepEquality::NotEq; - } - } - if by.variants.len() > self.variants.len() { - // By is a superset of self only if the tags are as well: - if self.tag.type_().representable(&*by.tag.type_()) == RepEquality::Superset { - RepEquality::Superset - } else { - RepEquality::NotEq - } - } else { - // By and self have matching variants, so they are equal if tags are: - if self.tag.type_().representable(&*by.tag.type_()) == RepEquality::Eq { - RepEquality::Eq - } else { - RepEquality::NotEq - } - } - } -} - impl Representable for TypeRef { fn representable(&self, by: &Self) -> RepEquality { self.type_().representable(&*by.type_()) @@ -180,7 +146,6 @@ impl Representable for Type { match (&self, &by) { (Type::Variant(s), Type::Variant(b)) => s.representable(b), (Type::Record(s), Type::Record(b)) => s.representable(b), - (Type::Union(s), Type::Union(b)) => s.representable(b), (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural (Type::List(s), Type::List(b)) => s.representable(b), (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), @@ -239,12 +204,12 @@ mod test { let base = def_type( "a", "(typename $tag (enum (@witx tag u8) $b $c)) - (typename $a (union $tag (field $b u32) (field $c f32)))", + (typename $a (union (@witx tag $tag) u32 f32))", ); let extra_variant = def_type( "a", "(typename $tag (enum (@witx tag u8) $b $c $d)) - (typename $a (union $tag (field $b u32) (field $c f32) (field $d f64)))", + (typename $a (union (@witx tag $tag) u32 f32 f64))", ); assert_eq!(base.representable(&extra_variant), RepEquality::Superset); @@ -253,7 +218,7 @@ mod test { let other_ordering = def_type( "a", "(typename $tag (enum (@witx tag u8) $b $c)) - (typename $a (union $tag (field $c f32) (field $b u32)))", + (typename $a (variant (@witx tag $tag) (case $c f32) (case $b u32)))", ); assert_eq!(base.representable(&other_ordering), RepEquality::Eq); assert_eq!(other_ordering.representable(&base), RepEquality::Eq); diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 8d698c77a..7abeef733 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -8,9 +8,9 @@ use crate::{ BuiltinType, Case, Constant, Definition, Entry, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, - TypePassedBy, TypeRef, UnionDatatype, UnionVariant, Variant, + TypePassedBy, TypeRef, Variant, }; -use std::collections::{hash_map, HashMap}; +use std::collections::{HashMap, HashSet}; use std::path::Path; use std::rc::Rc; use thiserror::Error; @@ -43,14 +43,16 @@ pub enum ValidationError { InvalidFirstResultType { location: Location }, #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] AnonymousRecord { location: Location }, - #[error("Invalid union field `{name}`: {reason}")] - InvalidUnionField { - name: String, - reason: String, + #[error("Union expected {expected} variants, found {found}")] + UnionSizeMismatch { + expected: usize, + found: usize, location: Location, }, - #[error("Invalid union tag `{name}`: {reason}")] - InvalidUnionTag { + #[error("Invalid union tag: {reason}")] + InvalidUnionTag { reason: String, location: Location }, + #[error("Invalid union field `{name}`: {reason}")] + InvalidUnionField { name: String, reason: String, location: Location, @@ -67,6 +69,7 @@ impl ValidationError { | InvalidRepr { location, .. } | InvalidFirstResultType { location, .. } | AnonymousRecord { location, .. } + | UnionSizeMismatch { location, .. } | InvalidUnionField { location, .. } | InvalidUnionTag { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) @@ -299,7 +302,10 @@ impl DocValidationScope<'_> { TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), TypedefSyntax::Flags(syntax) => self.validate_flags(&syntax, span)?, TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), - TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), + TypedefSyntax::Union(syntax) => Type::Variant(self.validate_union(&syntax, span)?), + TypedefSyntax::Variant(syntax) => { + Type::Variant(self.validate_variant(&syntax, span)?) + } TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), TypedefSyntax::List(syntax) => { Type::List(self.validate_datatype(syntax, false, span)?) @@ -385,105 +391,121 @@ impl DocValidationScope<'_> { &self, syntax: &UnionSyntax, span: wast::Span, - ) -> Result { - let mut variant_scope = IdentValidation::new(); - let tag_id = self.get(&syntax.tag)?; - let (tag, mut variant_name_uses) = match self.doc.entries.get(&tag_id) { - Some(Entry::Typename(weak_ref)) => { - let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); - match &*named_dt.type_() { - Type::Variant(e) => { - let mut uses = HashMap::new(); - for c in e.cases.iter() { - if c.tref.is_some() { - return Err(ValidationError::InvalidUnionTag { - name: syntax.tag.name().to_string(), - location: self.location(syntax.tag.span()), - reason: format!("all variant cases should have empty payloads"), - }); - } - uses.insert(c.name.clone(), false); - } - Ok((named_dt, uses)) - } - other => Err(ValidationError::WrongKindName { - name: syntax.tag.name().to_string(), - location: self.location(syntax.tag.span()), - expected: "enum", - got: other.kind(), - }), - } + ) -> Result { + let (tag_repr, names) = self.union_tag_repr(&syntax.tag, span)?; + + if let Some(names) = &names { + if names.len() != syntax.fields.len() { + return Err(ValidationError::UnionSizeMismatch { + expected: names.len(), + found: syntax.fields.len(), + location: self.location(span), + }); } - other => Err(ValidationError::WrongKindName { - name: syntax.tag.name().to_string(), - location: self.location(syntax.tag.span()), - expected: "enum", - got: match other { - Some(e) => e.kind(), - None => "unknown", - }, - }), - }?; + } - let variants = syntax + let cases = syntax .fields .iter() - .map(|v| { - let variant_name = match v.item { - VariantSyntax::Field(ref f) => &f.name, - VariantSyntax::Empty(ref name) => name, - }; - let name = variant_scope - .introduce(variant_name.name(), self.location(variant_name.span()))?; - let tref = match &v.item { - VariantSyntax::Field(f) => { - Some(self.validate_datatype(&f.type_, false, variant_name.span())?) - } - VariantSyntax::Empty { .. } => None, - }; - let docs = v.comments.docs(); - match variant_name_uses.entry(name.clone()) { - hash_map::Entry::Occupied(mut e) => { - if *e.get() { - Err(ValidationError::InvalidUnionField { - name: variant_name.name().to_string(), - reason: "variant already defined".to_owned(), - location: self.location(variant_name.span()), - })?; - } else { - e.insert(true); - } + .enumerate() + .map(|(i, case)| { + Ok(Case { + name: match &names { + Some(names) => names[i].clone(), + None => Id::new(i.to_string()), + }, + tref: Some(self.validate_datatype(&case.item, false, span)?), + docs: case.comments.docs(), + }) + }) + .collect::, _>>()?; + Ok(Variant { tag_repr, cases }) + } + + fn validate_variant( + &self, + syntax: &VariantSyntax, + span: wast::Span, + ) -> Result { + let (tag_repr, names) = self.union_tag_repr(&syntax.tag, span)?; + + if let Some(names) = &names { + if names.len() != syntax.cases.len() { + return Err(ValidationError::UnionSizeMismatch { + expected: names.len(), + found: syntax.cases.len(), + location: self.location(span), + }); + } + } + + let mut names = names.map(|names| names.into_iter().collect::>()); + + let cases = syntax + .cases + .iter() + .map(|case| { + let name = Id::new(case.item.name.name()); + if let Some(names) = &mut names { + if !names.remove(&name) { + return Err(ValidationError::InvalidUnionField { + name: name.as_str().to_string(), + location: self.location(case.item.name.span()), + reason: format!("does not correspond to variant in tag `tag`"), + }); } - hash_map::Entry::Vacant { .. } => Err(ValidationError::InvalidUnionField { - name: variant_name.name().to_string(), - reason: format!( - "does not correspond to variant in tag `{}`", - tag.name.as_str() - ), - location: self.location(variant_name.span()), - })?, } - Ok(UnionVariant { name, tref, docs }) + Ok(Case { + name: Id::new(case.item.name.name()), + tref: match &case.item.ty { + Some(ty) => { + Some(self.validate_datatype(ty, false, case.item.name.span())?) + } + None => None, + }, + docs: case.comments.docs(), + }) }) - .collect::, _>>()?; + .collect::, _>>()?; + Ok(Variant { tag_repr, cases }) + } - let unused_variants = variant_name_uses - .iter() - .filter(|(_k, used)| **used == false) - .map(|(k, _)| k.clone()) - .collect::>(); - if !unused_variants.is_empty() { - Err(ValidationError::InvalidUnionField { - name: unused_variants - .iter() - .map(|i| i.as_str()) - .collect::>() - .join(", "), - reason: format!("missing variants from tag `{}`", tag.name.as_str()), - location: self.location(span), - })?; + fn union_tag_repr( + &self, + tag: &Option>>, + span: wast::Span, + ) -> Result<(IntRepr, Option>), ValidationError> { + let ty = match tag { + Some(tag) => self.validate_datatype(tag, false, span)?, + None => return Ok((IntRepr::U32, None)), + }; + match &*ty.type_() { + Type::Variant(e) => { + let mut names = Vec::new(); + for c in e.cases.iter() { + if c.tref.is_some() { + return Err(ValidationError::InvalidUnionTag { + location: self.location(span), + reason: format!("all variant cases should have empty payloads"), + }); + } + names.push(c.name.clone()); + } + return Ok((e.tag_repr, Some(names))); + } + Type::Builtin(BuiltinType::U8) => return Ok((IntRepr::U8, None)), + Type::Builtin(BuiltinType::U16) => return Ok((IntRepr::U16, None)), + Type::Builtin(BuiltinType::U32) => return Ok((IntRepr::U32, None)), + Type::Builtin(BuiltinType::U64) => return Ok((IntRepr::U64, None)), + _ => {} } - Ok(UnionDatatype { tag, variants }) + + Err(ValidationError::WrongKindName { + name: "tag".to_string(), + location: self.location(span), + expected: "enum or builtin", + got: ty.type_().kind(), + }) } fn validate_handle( diff --git a/proposals/clocks/tools/witx/tests/anonymous.rs b/proposals/clocks/tools/witx/tests/anonymous.rs index a295a3915..6cfb2ea7e 100644 --- a/proposals/clocks/tools/witx/tests/anonymous.rs +++ b/proposals/clocks/tools/witx/tests/anonymous.rs @@ -12,9 +12,8 @@ fn anonymous_types() { let pointer_to_record = witx::parse("(typename $a (@witx pointer (record (field $b u8))))"); assert!(is_anonymous_record_err(pointer_to_record)); - let pointer_to_union = witx::parse( - "(typename $tag (enum $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", - ); + let pointer_to_union = + witx::parse("(typename $tag (enum $b)) (typename $a (@witx pointer (union u8)))"); assert!(is_anonymous_record_err(pointer_to_union)); let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum $b)))"); @@ -35,9 +34,8 @@ fn anonymous_types() { let record_in_record = witx::parse("(typename $a (record (field $b (record (field $c u8)))))"); assert!(is_anonymous_record_err(record_in_record)); - let union_in_record = witx::parse( - "(typename $tag (enum $c)) (typename $a (record (field $b (union $tag (field $c u8)))))", - ); + let union_in_record = + witx::parse("(typename $tag (enum $c)) (typename $a (record (field $b (union u8))))"); assert!(is_anonymous_record_err(union_in_record)); let pointer_in_record = witx::parse("(typename $a (record (field $b (@witx pointer u8))))"); diff --git a/proposals/clocks/tools/witx/tests/union.rs b/proposals/clocks/tools/witx/tests/union.rs index 30fb4dfdf..6cfa43e39 100644 --- a/proposals/clocks/tools/witx/tests/union.rs +++ b/proposals/clocks/tools/witx/tests/union.rs @@ -5,7 +5,7 @@ use witx::{Id, Representable}; fn one_variant_union() { let d = witx::parse( "(typename $tag (enum $c)) - (typename $u (union $tag (field $c u8)))", + (typename $u (union (@witx tag $tag) u8))", ); assert!(d.is_ok()); } @@ -14,14 +14,14 @@ fn one_variant_union() { fn two_variant_union() { let d1 = witx::parse( "(typename $tag (enum $a $b)) - (typename $u (union $tag (field $a u8) (field $b u16)))", + (typename $u (union (@witx tag $tag) u8 u16))", ); assert!(d1.is_ok(), "d1 is ok"); // Fields can come in whatever order: let d2 = witx::parse( "(typename $tag (enum $a $b)) - (typename $u (union $tag (field $b u16) (field $a u8)))", + (typename $u (variant (@witx tag $tag) (case $b u16) (case $a u8)))", ); assert!(d2.is_ok(), "d2 is ok"); @@ -40,31 +40,25 @@ fn two_variant_union() { "u2 can represent u1" ); - // Tag order doesnt matter for validation, but does for rep equality + // Tag order doesnt matter for validation let d3 = witx::parse( "(typename $tag (enum $b $a)) - (typename $u (union $tag (field $b u16) (field $a u8)))", + (typename $u (union (@witx tag $tag) u16 u8))", ); assert!(d3.is_ok(), "d2 is ok"); - let u3 = d3.unwrap().typename(&Id::new("u")).unwrap().type_(); - assert_eq!( - u3.representable(&u1), - witx::RepEquality::NotEq, - "u3 cannot represent u1" - ); } #[test] fn empty_variant_unions() { let d1 = witx::parse( "(typename $tag (enum $a $b)) - (typename $u (union $tag (empty $a) (field $b u16)))", + (typename $u (variant (@witx tag $tag) (case $a) (case $b u16)))", ); assert!(d1.is_ok(), "d1 is ok"); let d2 = witx::parse( "(typename $tag (enum $a $b)) - (typename $u (union $tag (empty $a) (empty $b)))", + (typename $u (variant (@witx tag $tag) (case $a) (case $b)))", ); assert!(d2.is_ok(), "d2 is ok"); } @@ -74,20 +68,20 @@ fn many_variant_unions() { let d1 = witx::parse( "(typename $tag (enum $a $b $c $d $e $f $g $h $i $j $k $l $m)) (typename $u - (union $tag - (field $a u8) - (field $b u16) - (field $c u32) - (field $d u64) - (field $e s8) - (field $f s16) - (field $g s32) - (field $h s64) - (field $i f32) - (field $j f64) - (field $k (@witx usize)) - (field $l char8) - (empty $m) + (variant (@witx tag $tag) + (case $a u8) + (case $b u16) + (case $c u32) + (case $d u64) + (case $e s8) + (case $f s16) + (case $g s32) + (case $h s64) + (case $i f32) + (case $j f64) + (case $k (@witx usize)) + (case $l char8) + (case $m) ) )", ); @@ -103,45 +97,48 @@ fn no_tag_union() { #[test] fn wrong_kind_tag_union() { let d = witx::parse( - "(typename $tag u32) - (typename $u (union $tag (field $a u8) (field $b u16)))", + "(typename $tag string) + (typename $u (union (@witx tag $tag) u8 u16))", ); let (expected, got) = wrong_kind_name_err(d).expect("wrong kind of tag"); - assert_eq!(expected, "enum"); - assert_eq!(got, "builtin"); + assert_eq!(expected, "enum or builtin"); + assert_eq!(got, "list"); } #[test] fn bad_field_unions() { let d = witx::parse( "(typename $tag (enum $c)) - (typename $u (union $tag (field $b u8)))", - ); - let (name, reason) = union_field_err(d).expect("bad field union 1"); - assert_eq!(name, "b", "bad field name union 1"); - assert_eq!( - reason, "does not correspond to variant in tag `tag`", - "reason union 1" - ); + (typename $u (variant (@witx tag $tag) (case $b u8)))", + ); + match validation_err(d) { + witx::ValidationError::InvalidUnionField { name, reason, .. } => { + assert_eq!(name, "b", "bad field name union 1"); + assert_eq!( + reason, "does not correspond to variant in tag `tag`", + "reason union 1" + ); + } + other => panic!("bad error: {}", other), + } let d = witx::parse( "(typename $tag (enum $c)) - (typename $u (union $tag (field $c f32) (field $b u8)))", - ); - let (name, reason) = union_field_err(d).expect("bad field union 2"); - assert_eq!(name, "b", "bad field name union 2"); - assert_eq!( - reason, "does not correspond to variant in tag `tag`", - "reason union 2" + (typename $u (variant (@witx tag $tag) (case $c f32) (case $b u8)))", ); + match validation_err(d) { + witx::ValidationError::UnionSizeMismatch { .. } => {} + other => panic!("bad error: {}", other), + } let d = witx::parse( "(typename $tag (enum $c $d)) - (typename $u (union $tag (field $c f32)))", + (typename $u (variant (@witx tag $tag) (case $c f32)))", ); - let (name, reason) = union_field_err(d).expect("bad field union 3"); - assert_eq!(name, "d", "bad field name union 3"); - assert_eq!(reason, "missing variants from tag `tag`", "reason union 3"); + match validation_err(d) { + witx::ValidationError::UnionSizeMismatch { .. } => {} + other => panic!("bad error: {}", other), + } } fn wrong_kind_name_err( @@ -164,20 +161,14 @@ fn wrong_kind_name_err( } } -fn union_field_err(r: Result) -> Option<(String, String)> { +fn validation_err(r: Result) -> witx::ValidationError { match r { - Err(witx::WitxError::Validation(witx::ValidationError::InvalidUnionField { - name, - reason, - .. - })) => Some((name, reason)), + Err(witx::WitxError::Validation(e)) => e, Err(e) => { - eprintln!("expected InvalidUnionField ValidationError, got: {:?}", e); - None + panic!("expected ValidationError, got: {:?}", e) } Ok(_) => { - eprintln!("expected InvalidUnionField ValidationError, got: Ok(witx::Document)"); - None + panic!("expected ValidationError, got: Ok(witx::Document)") } } } From 182b6f61ab6d58a5f5f41ef1eb7807ad226a2b5b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 14:12:49 -0800 Subject: [PATCH 0848/1772] Implement Union in terms of Variant --- proposals/random/phases/ephemeral/docs.md | 36 ++- .../phases/ephemeral/witx/typenames.witx | 20 +- .../random/phases/old/snapshot_0/docs.md | 24 +- .../phases/old/snapshot_0/witx/typenames.witx | 12 +- proposals/random/phases/snapshot/docs.md | 24 +- .../phases/snapshot/witx/typenames.witx | 13 +- proposals/random/tools/witx/src/ast.rs | 15 -- proposals/random/tools/witx/src/coretypes.rs | 2 +- proposals/random/tools/witx/src/docs/ast.rs | 82 ++----- proposals/random/tools/witx/src/docs/md.rs | 2 - proposals/random/tools/witx/src/layout.rs | 56 ----- proposals/random/tools/witx/src/lib.rs | 2 +- proposals/random/tools/witx/src/parser.rs | 91 +++++--- proposals/random/tools/witx/src/render.rs | 35 +-- .../random/tools/witx/src/representation.rs | 103 +++----- proposals/random/tools/witx/src/validate.rs | 220 ++++++++++-------- .../random/tools/witx/tests/anonymous.rs | 10 +- proposals/random/tools/witx/tests/union.rs | 111 ++++----- 18 files changed, 360 insertions(+), 498 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index c579e00a3..7ea6969f8 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -859,20 +859,18 @@ The state of the file descriptor. Offset: 8 -## `event_u`: Union +## `event_u`: Variant The contents of an [`event`](#event). Size: 24 Alignment: 8 -### Union Layout +### Variant Layout +- size: 24 +- align: 8 - tag_size: 1 -- tag_align: 1 -- contents_offset: 8 -- contents_size: 16 -- contents_align: 8 -### Union variants +### Variant cases - `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) - `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) @@ -961,20 +959,18 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Union +## `subscription_u`: Variant The contents of a [`subscription`](#subscription). Size: 40 Alignment: 8 -### Union Layout +### Variant Layout +- size: 40 +- align: 8 - tag_size: 1 -- tag_align: 1 -- contents_offset: 8 -- contents_size: 32 -- contents_align: 8 -### Union variants +### Variant cases - `clock`: [`subscription_clock`](#subscription_clock) - `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) @@ -1078,20 +1074,18 @@ The length of the directory name for use with `fd_prestat_dir_name`. Offset: 0 -## `prestat`: Union +## `prestat`: Variant Information about a pre-opened capability. Size: 8 Alignment: 4 -### Union Layout +### Variant Layout +- size: 8 +- align: 4 - tag_size: 1 -- tag_align: 1 -- contents_offset: 4 -- contents_size: 4 -- contents_align: 4 -### Union variants +### Variant cases - `dir`: [`prestat_dir`](#prestat_dir) When type is [`preopentype::dir`](#preopentype.dir): diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index e10c4c30d..503aa0cf6 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -562,10 +562,10 @@ ;;; The contents of an `event`. (typename $event_u - (union $eventtype - (field $fd_read $event_fd_readwrite) - (field $fd_write $event_fd_readwrite) - (empty $clock) + (variant (@witx tag $eventtype) + (case $fd_read $event_fd_readwrite) + (case $fd_write $event_fd_readwrite) + (case $clock) ) ) @@ -620,10 +620,10 @@ ;;; The contents of a `subscription`. (typename $subscription_u - (union $eventtype - (field $clock $subscription_clock) - (field $fd_read $subscription_fd_readwrite) - (field $fd_write $subscription_fd_readwrite) + (union (@witx tag $eventtype) + $subscription_clock + $subscription_fd_readwrite + $subscription_fd_readwrite ) ) @@ -691,8 +691,8 @@ ;;; Information about a pre-opened capability. (typename $prestat - (union $preopentype + (union (@witx tag $preopentype) ;;; When type is `preopentype::dir`: - (field $dir $prestat_dir) + $prestat_dir ) ) diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index 0e2f5bde0..e77002bc6 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -899,20 +899,18 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Union +## `subscription_u`: Variant The contents of a [`subscription`](#subscription). Size: 48 Alignment: 8 -### Union Layout +### Variant Layout +- size: 48 +- align: 8 - tag_size: 1 -- tag_align: 1 -- contents_offset: 8 -- contents_size: 40 -- contents_align: 8 -### Union variants +### Variant cases - `clock`: [`subscription_clock`](#subscription_clock) - `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) @@ -1148,20 +1146,18 @@ The length of the directory name for use with [`fd_prestat_dir_name`](#fd_presta Offset: 0 -## `prestat`: Union +## `prestat`: Variant Information about a pre-opened capability. Size: 8 Alignment: 4 -### Union Layout +### Variant Layout +- size: 8 +- align: 4 - tag_size: 1 -- tag_align: 1 -- contents_offset: 4 -- contents_size: 4 -- contents_align: 4 -### Union variants +### Variant cases - `dir`: [`prestat_dir`](#prestat_dir) # Modules diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx index f24000e00..eb6f70020 100644 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/random/phases/old/snapshot_0/witx/typenames.witx @@ -570,10 +570,10 @@ ;;; The contents of a `subscription`. (typename $subscription_u - (union $eventtype - (field $clock $subscription_clock) - (field $fd_read $subscription_fd_readwrite) - (field $fd_write $subscription_fd_readwrite) + (union (@witx tag $eventtype) + $subscription_clock + $subscription_fd_readwrite + $subscription_fd_readwrite ) ) @@ -740,7 +740,7 @@ ;;; Information about a pre-opened capability. (typename $prestat - (union $preopentype - (field $dir $prestat_dir) + (union (@witx tag $preopentype) + $prestat_dir ) ) diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index e13dcc79d..1bbbe59f2 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -896,20 +896,18 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Union +## `subscription_u`: Variant The contents of a [`subscription`](#subscription). Size: 40 Alignment: 8 -### Union Layout +### Variant Layout +- size: 40 +- align: 8 - tag_size: 1 -- tag_align: 1 -- contents_offset: 8 -- contents_size: 32 -- contents_align: 8 -### Union variants +### Variant cases - `clock`: [`subscription_clock`](#subscription_clock) - `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) @@ -1145,20 +1143,18 @@ The length of the directory name for use with [`fd_prestat_dir_name`](#fd_presta Offset: 0 -## `prestat`: Union +## `prestat`: Variant Information about a pre-opened capability. Size: 8 Alignment: 4 -### Union Layout +### Variant Layout +- size: 8 +- align: 4 - tag_size: 1 -- tag_align: 1 -- contents_offset: 4 -- contents_size: 4 -- contents_align: 4 -### Union variants +### Variant cases - `dir`: [`prestat_dir`](#prestat_dir) # Modules diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx index 13eb1759f..70e726553 100644 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -570,10 +570,11 @@ ;;; The contents of a `subscription`. (typename $subscription_u - (union $eventtype - (field $clock $subscription_clock) - (field $fd_read $subscription_fd_readwrite) - (field $fd_write $subscription_fd_readwrite) + (union + (@witx tag $eventtype) + $subscription_clock + $subscription_fd_readwrite + $subscription_fd_readwrite ) ) @@ -740,8 +741,8 @@ ;;; Information about a pre-opened capability. (typename $prestat - (union $preopentype - (field $dir $prestat_dir) + (union (@witx tag $preopentype) + $prestat_dir ) ) diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 00c9fac83..5ba525520 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -187,7 +187,6 @@ impl NamedType { pub enum Type { Record(RecordDatatype), Variant(Variant), - Union(UnionDatatype), Handle(HandleDatatype), List(TypeRef), Pointer(TypeRef), @@ -201,7 +200,6 @@ impl Type { match self { Record(_) => "record", Variant(_) => "variant", - Union(_) => "union", Handle(_) => "handle", List(_) => "list", Pointer(_) => "pointer", @@ -272,19 +270,6 @@ pub struct Case { pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct UnionDatatype { - pub tag: Rc, - pub variants: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct UnionVariant { - pub name: Id, - pub tref: Option, - pub docs: String, -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct HandleDatatype {} diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index 3a5e41284..35fea801e 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -50,7 +50,7 @@ impl Type { }, Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), - Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Record { .. } => TypePassedBy::Pointer, Type::Variant(v) => { if v.cases.iter().all(|c| c.tref.is_none()) { TypePassedBy::Value(v.tag_repr.into()) diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index a776907a3..eb4d3e7cb 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -89,7 +89,6 @@ impl ToMarkdown for Type { match self { Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), - Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), Self::List(a) => { node.content_ref_mut::().r#type = Some(MdType::List { @@ -144,6 +143,27 @@ impl ToMarkdown for RecordDatatype { impl ToMarkdown for Variant { fn generate(&self, node: MdNodeRef) { + if self.cases.iter().any(|c| c.tref.is_some()) { + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Variant Layout")); + + let whole = self.mem_size_align(); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("size: {}", whole.size), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("align: {}", whole.align), + )); + + let tag = self.tag_repr.mem_size_align(); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("tag_size: {}", tag.size), + )); + } + let heading = heading_from_node(&node, 1); node.new_child(MdSection::new(heading, "Variant cases")); @@ -169,61 +189,6 @@ impl ToMarkdown for Variant { } } -impl ToMarkdown for UnionDatatype { - fn generate(&self, node: MdNodeRef) { - // Sizes & Alignments - let sizes_heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(sizes_heading, "Union Layout")); - let union_layout = &self.union_layout(); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("tag_size: {}", union_layout.tag_size).as_str(), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("tag_align: {}", union_layout.tag_align).as_str(), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("contents_offset: {}", union_layout.contents_offset).as_str(), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("contents_size: {}", union_layout.contents_size).as_str(), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("contents_align: {}", union_layout.contents_align).as_str(), - )); - - // Variants - let variants_heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(variants_heading, "Union variants")); - - for variant in &self.variants { - let name = variant.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let n = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - &variant.docs, - )); - if let Some(ref tref) = variant.tref { - tref.generate(n.clone()); - } else { - n.content_ref_mut::().r#type = None; - } - } - - node.content_ref_mut::().r#type = Some(MdType::Union); - } -} - impl ToMarkdown for HandleDatatype { fn generate(&self, node: MdNodeRef) { // TODO this needs more work @@ -352,10 +317,7 @@ impl TypeRef { Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), - Type::Record { .. } - | Type::Variant { .. } - | Type::Union { .. } - | Type::Handle { .. } => { + Type::Record { .. } | Type::Variant { .. } | Type::Handle { .. } => { unimplemented!("type_name of anonymous compound datatypes") } }, diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index 6519d0745..d3d5b756d 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -345,7 +345,6 @@ impl MdNamedType { pub(super) enum MdType { Record, Variant, - Union, List { r#type: String }, Pointer { r#type: String }, ConstPointer { r#type: String }, @@ -359,7 +358,6 @@ impl fmt::Display for MdType { match self { Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, - Self::Union => f.write_fmt(format_args!(": Union"))?, Self::List { r#type } => { if r#type == "char" { f.write_str(": `string`")? diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index 1e4b03211..6b77d8a32 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -66,7 +66,6 @@ impl Type { match &self { Type::Record(s) => s.layout(cache), Type::Variant(s) => s.mem_size_align(), - Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), @@ -178,61 +177,6 @@ mod test { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct UnionLayout { - pub tag_size: usize, - pub tag_align: usize, - pub contents_offset: usize, - pub contents_size: usize, - pub contents_align: usize, -} - -impl Layout for UnionLayout { - fn mem_size_align(&self) -> SizeAlign { - let align = std::cmp::max(self.tag_align, self.contents_align); - let size = align_to(self.contents_offset + self.contents_size, align); - SizeAlign { size, align } - } -} - -impl UnionDatatype { - pub fn union_layout(&self) -> UnionLayout { - let mut cache = HashMap::new(); - self.union_layout_(&mut cache) - } - fn union_layout_(&self, cache: &mut HashMap) -> UnionLayout { - let tag = self.tag.layout(cache); - - let variant_sas = self - .variants - .iter() - .filter_map(|v| v.tref.as_ref().map(|t| t.layout(cache))) - .collect::>(); - - let contents_size = variant_sas.iter().map(|sa| sa.size).max().unwrap_or(0); - let contents_align = variant_sas.iter().map(|sa| sa.align).max().unwrap_or(1); - - UnionLayout { - tag_size: tag.size, - tag_align: tag.align, - contents_offset: align_to(tag.size, contents_align), - contents_size, - contents_align, - } - } - - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - self.union_layout_(cache).mem_size_align() - } -} - -impl Layout for UnionDatatype { - fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } -} - impl Layout for HandleDatatype { fn mem_size_align(&self) -> SizeAlign { BuiltinType::U32.mem_size_align() diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 72774c16c..9c0f53060 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -27,7 +27,7 @@ pub use ast::*; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; -pub use layout::{Layout, RecordMemberLayout, SizeAlign, UnionLayout}; +pub use layout::{Layout, RecordMemberLayout, SizeAlign}; pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 6015cb052..ee8bf081e 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -19,6 +19,7 @@ mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; wast::custom_keyword!(bitflags); + wast::custom_keyword!(case); wast::custom_keyword!(char8); wast::custom_keyword!(char); wast::custom_keyword!(const_pointer); @@ -48,6 +49,7 @@ mod kw { wast::custom_keyword!(u64); wast::custom_keyword!(u8); wast::custom_keyword!(usize); + wast::custom_keyword!(variant); } mod annotation { @@ -280,6 +282,7 @@ pub enum TypedefSyntax<'a> { Flags(FlagsSyntax<'a>), Record(RecordSyntax<'a>), Union(UnionSyntax<'a>), + Variant(VariantSyntax<'a>), Handle(HandleSyntax), List(Box>), Pointer(Box>), @@ -310,6 +313,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Record(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Union(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Variant(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Handle(parser.parse()?)) } else if l.peek::() { @@ -448,42 +453,24 @@ impl<'a> Parse<'a> for FieldSyntax<'a> { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum VariantSyntax<'a> { - Field(FieldSyntax<'a>), - Empty(wast::Id<'a>), -} - -impl<'a> Parse<'a> for VariantSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - let mut l = p.lookahead1(); - if l.peek::() { - parser.parse::()?; - let name = p.parse()?; - let type_ = p.parse()?; - Ok(VariantSyntax::Field(FieldSyntax { name, type_ })) - } else if l.peek::() { - parser.parse::()?; - let name = p.parse()?; - Ok(VariantSyntax::Empty(name)) - } else { - Err(l.error()) - } - }) - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionSyntax<'a> { - pub tag: wast::Id<'a>, - pub fields: Vec>>, + pub tag: Option>>, + pub fields: Vec>>, } impl<'a> Parse<'a> for UnionSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let tag = parser.parse()?; + let tag = if parser.peek2::() { + Some(parser.parens(|p| { + p.parse::()?; + p.parse::()?; + p.parse().map(Box::new) + })?) + } else { + None + }; let mut fields = Vec::new(); fields.push(parser.parse()?); while !parser.is_empty() { @@ -493,6 +480,52 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct VariantSyntax<'a> { + pub tag: Option>>, + pub cases: Vec>>, +} + +impl<'a> Parse<'a> for VariantSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let tag = if parser.peek2::() { + Some(parser.parens(|p| { + p.parse::()?; + p.parse::()?; + p.parse().map(Box::new) + })?) + } else { + None + }; + let mut cases = Vec::new(); + while !parser.is_empty() { + cases.push(parser.parens(|p| p.parse())?); + } + Ok(VariantSyntax { tag, cases }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CaseSyntax<'a> { + pub name: wast::Id<'a>, + pub ty: Option>, +} + +impl<'a> Parse<'a> for CaseSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + Ok(CaseSyntax { + name: parser.parse()?, + ty: if parser.is_empty() { + None + } else { + Some(parser.parse()?) + }, + }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct HandleSyntax {} diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 16b92d48a..60df3d6a2 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -118,7 +118,6 @@ impl Type { match self { Type::Record(a) => a.to_sexpr(), Type::Variant(a) => a.to_sexpr(), - Type::Union(a) => a.to_sexpr(), Type::Handle(a) => a.to_sexpr(), Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), Type::Pointer(p) => SExpr::Vec(vec![ @@ -172,6 +171,11 @@ impl Variant { } } else { list.push(SExpr::word("variant")); + list.push(SExpr::Vec(vec![ + SExpr::word("@witx"), + SExpr::word("tag"), + self.tag_repr.to_sexpr(), + ])); for case in self.cases.iter() { let mut case_expr = vec![SExpr::word("case"), case.name.to_sexpr()]; if let Some(ty) = &case.tref { @@ -184,39 +188,12 @@ impl Variant { } } -impl UnionDatatype { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("union"), self.tag.name.to_sexpr()]; - let variants = self - .variants - .iter() - .map(|v| { - if let Some(ref tref) = v.tref { - SExpr::docs( - &v.docs, - SExpr::Vec(vec![ - SExpr::word("field"), - v.name.to_sexpr(), - tref.to_sexpr(), - ]), - ) - } else { - SExpr::docs( - &v.docs, - SExpr::Vec(vec![SExpr::word("empty"), v.name.to_sexpr()]), - ) - } - }) - .collect::>(); - SExpr::Vec([header, variants].concat()) - } -} - impl HandleDatatype { pub fn to_sexpr(&self) -> SExpr { SExpr::Vec(vec![SExpr::word("handle")]) } } + impl IntRepr { pub fn to_sexpr(&self) -> SExpr { match self { diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs index d3f7bf817..6c36e71e7 100644 --- a/proposals/random/tools/witx/src/representation.rs +++ b/proposals/random/tools/witx/src/representation.rs @@ -1,6 +1,5 @@ -use crate::{ - BuiltinType, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, Variant, -}; +use crate::{BuiltinType, IntRepr, NamedType, RecordDatatype, Type, TypeRef, Variant}; +use std::collections::HashMap; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -70,24 +69,41 @@ impl Representable for IntRepr { impl Representable for Variant { fn representable(&self, by: &Self) -> RepEquality { + let mut superset = false; // Integer representation must be compatible - if self.tag_repr.representable(&by.tag_repr) == RepEquality::NotEq { - return RepEquality::NotEq; + match self.tag_repr.representable(&by.tag_repr) { + RepEquality::NotEq => return RepEquality::NotEq, + RepEquality::Eq => {} + RepEquality::Superset => superset = true, } - // For each variant in self, must have variant of same name and position in by: - for (ix, v) in self.cases.iter().enumerate() { - if let Some(by_v) = by.cases.get(ix) { - if by_v.name != v.name { - return RepEquality::NotEq; - } - } else { - return RepEquality::NotEq; + let other_by_name = by + .cases + .iter() + .map(|c| (&c.name, c)) + .collect::>(); + // For each variant in self, must have variant of same name in by: + for v in self.cases.iter() { + let other_ty = match other_by_name.get(&v.name) { + Some(other) => &other.tref, + None => return RepEquality::NotEq, + }; + match (&v.tref, other_ty) { + (Some(me), Some(other)) => match me.representable(other) { + RepEquality::NotEq => return RepEquality::NotEq, + RepEquality::Eq => {} + RepEquality::Superset => superset = true, + }, + // We added fields, that's not ok + (Some(_), None) => return RepEquality::NotEq, + // Fields were deleted, that's ok + (None, Some(_)) => superset = true, + (None, None) => {} } } - if by.cases.len() > self.cases.len() { + if superset || self.cases.len() < by.cases.len() { RepEquality::Superset } else { - self.tag_repr.representable(&by.tag_repr) + RepEquality::Eq } } } @@ -113,56 +129,6 @@ impl Representable for RecordDatatype { } } -impl Representable for UnionDatatype { - fn representable(&self, by: &Self) -> RepEquality { - // Unions must have equal variants, by name (independent of order). If `by` has extra - // variants, its a superset. - // We would require require a more expressive RepEquality enum to describe which variants - // might be supersets. - if self.variants.len() > by.variants.len() { - return RepEquality::NotEq; - } - for v in self.variants.iter() { - if let Some(byv) = by.variants.iter().find(|byv| byv.name == v.name) { - if v.tref.is_none() && byv.tref.is_none() { - // Both empty is OK - } else if v.tref.is_some() && byv.tref.is_some() { - if v.tref - .as_ref() - .unwrap() - .type_() - .representable(&*byv.tref.as_ref().unwrap().type_()) - != RepEquality::Eq - { - // Fields must be Eq - return RepEquality::NotEq; - } - } else { - // Either one empty means not representable - return RepEquality::NotEq; - } - } else { - return RepEquality::NotEq; - } - } - if by.variants.len() > self.variants.len() { - // By is a superset of self only if the tags are as well: - if self.tag.type_().representable(&*by.tag.type_()) == RepEquality::Superset { - RepEquality::Superset - } else { - RepEquality::NotEq - } - } else { - // By and self have matching variants, so they are equal if tags are: - if self.tag.type_().representable(&*by.tag.type_()) == RepEquality::Eq { - RepEquality::Eq - } else { - RepEquality::NotEq - } - } - } -} - impl Representable for TypeRef { fn representable(&self, by: &Self) -> RepEquality { self.type_().representable(&*by.type_()) @@ -180,7 +146,6 @@ impl Representable for Type { match (&self, &by) { (Type::Variant(s), Type::Variant(b)) => s.representable(b), (Type::Record(s), Type::Record(b)) => s.representable(b), - (Type::Union(s), Type::Union(b)) => s.representable(b), (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural (Type::List(s), Type::List(b)) => s.representable(b), (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), @@ -239,12 +204,12 @@ mod test { let base = def_type( "a", "(typename $tag (enum (@witx tag u8) $b $c)) - (typename $a (union $tag (field $b u32) (field $c f32)))", + (typename $a (union (@witx tag $tag) u32 f32))", ); let extra_variant = def_type( "a", "(typename $tag (enum (@witx tag u8) $b $c $d)) - (typename $a (union $tag (field $b u32) (field $c f32) (field $d f64)))", + (typename $a (union (@witx tag $tag) u32 f32 f64))", ); assert_eq!(base.representable(&extra_variant), RepEquality::Superset); @@ -253,7 +218,7 @@ mod test { let other_ordering = def_type( "a", "(typename $tag (enum (@witx tag u8) $b $c)) - (typename $a (union $tag (field $c f32) (field $b u32)))", + (typename $a (variant (@witx tag $tag) (case $c f32) (case $b u32)))", ); assert_eq!(base.representable(&other_ordering), RepEquality::Eq); assert_eq!(other_ordering.representable(&base), RepEquality::Eq); diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 8d698c77a..7abeef733 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -8,9 +8,9 @@ use crate::{ BuiltinType, Case, Constant, Definition, Entry, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, - TypePassedBy, TypeRef, UnionDatatype, UnionVariant, Variant, + TypePassedBy, TypeRef, Variant, }; -use std::collections::{hash_map, HashMap}; +use std::collections::{HashMap, HashSet}; use std::path::Path; use std::rc::Rc; use thiserror::Error; @@ -43,14 +43,16 @@ pub enum ValidationError { InvalidFirstResultType { location: Location }, #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] AnonymousRecord { location: Location }, - #[error("Invalid union field `{name}`: {reason}")] - InvalidUnionField { - name: String, - reason: String, + #[error("Union expected {expected} variants, found {found}")] + UnionSizeMismatch { + expected: usize, + found: usize, location: Location, }, - #[error("Invalid union tag `{name}`: {reason}")] - InvalidUnionTag { + #[error("Invalid union tag: {reason}")] + InvalidUnionTag { reason: String, location: Location }, + #[error("Invalid union field `{name}`: {reason}")] + InvalidUnionField { name: String, reason: String, location: Location, @@ -67,6 +69,7 @@ impl ValidationError { | InvalidRepr { location, .. } | InvalidFirstResultType { location, .. } | AnonymousRecord { location, .. } + | UnionSizeMismatch { location, .. } | InvalidUnionField { location, .. } | InvalidUnionTag { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) @@ -299,7 +302,10 @@ impl DocValidationScope<'_> { TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), TypedefSyntax::Flags(syntax) => self.validate_flags(&syntax, span)?, TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), - TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), + TypedefSyntax::Union(syntax) => Type::Variant(self.validate_union(&syntax, span)?), + TypedefSyntax::Variant(syntax) => { + Type::Variant(self.validate_variant(&syntax, span)?) + } TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), TypedefSyntax::List(syntax) => { Type::List(self.validate_datatype(syntax, false, span)?) @@ -385,105 +391,121 @@ impl DocValidationScope<'_> { &self, syntax: &UnionSyntax, span: wast::Span, - ) -> Result { - let mut variant_scope = IdentValidation::new(); - let tag_id = self.get(&syntax.tag)?; - let (tag, mut variant_name_uses) = match self.doc.entries.get(&tag_id) { - Some(Entry::Typename(weak_ref)) => { - let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); - match &*named_dt.type_() { - Type::Variant(e) => { - let mut uses = HashMap::new(); - for c in e.cases.iter() { - if c.tref.is_some() { - return Err(ValidationError::InvalidUnionTag { - name: syntax.tag.name().to_string(), - location: self.location(syntax.tag.span()), - reason: format!("all variant cases should have empty payloads"), - }); - } - uses.insert(c.name.clone(), false); - } - Ok((named_dt, uses)) - } - other => Err(ValidationError::WrongKindName { - name: syntax.tag.name().to_string(), - location: self.location(syntax.tag.span()), - expected: "enum", - got: other.kind(), - }), - } + ) -> Result { + let (tag_repr, names) = self.union_tag_repr(&syntax.tag, span)?; + + if let Some(names) = &names { + if names.len() != syntax.fields.len() { + return Err(ValidationError::UnionSizeMismatch { + expected: names.len(), + found: syntax.fields.len(), + location: self.location(span), + }); } - other => Err(ValidationError::WrongKindName { - name: syntax.tag.name().to_string(), - location: self.location(syntax.tag.span()), - expected: "enum", - got: match other { - Some(e) => e.kind(), - None => "unknown", - }, - }), - }?; + } - let variants = syntax + let cases = syntax .fields .iter() - .map(|v| { - let variant_name = match v.item { - VariantSyntax::Field(ref f) => &f.name, - VariantSyntax::Empty(ref name) => name, - }; - let name = variant_scope - .introduce(variant_name.name(), self.location(variant_name.span()))?; - let tref = match &v.item { - VariantSyntax::Field(f) => { - Some(self.validate_datatype(&f.type_, false, variant_name.span())?) - } - VariantSyntax::Empty { .. } => None, - }; - let docs = v.comments.docs(); - match variant_name_uses.entry(name.clone()) { - hash_map::Entry::Occupied(mut e) => { - if *e.get() { - Err(ValidationError::InvalidUnionField { - name: variant_name.name().to_string(), - reason: "variant already defined".to_owned(), - location: self.location(variant_name.span()), - })?; - } else { - e.insert(true); - } + .enumerate() + .map(|(i, case)| { + Ok(Case { + name: match &names { + Some(names) => names[i].clone(), + None => Id::new(i.to_string()), + }, + tref: Some(self.validate_datatype(&case.item, false, span)?), + docs: case.comments.docs(), + }) + }) + .collect::, _>>()?; + Ok(Variant { tag_repr, cases }) + } + + fn validate_variant( + &self, + syntax: &VariantSyntax, + span: wast::Span, + ) -> Result { + let (tag_repr, names) = self.union_tag_repr(&syntax.tag, span)?; + + if let Some(names) = &names { + if names.len() != syntax.cases.len() { + return Err(ValidationError::UnionSizeMismatch { + expected: names.len(), + found: syntax.cases.len(), + location: self.location(span), + }); + } + } + + let mut names = names.map(|names| names.into_iter().collect::>()); + + let cases = syntax + .cases + .iter() + .map(|case| { + let name = Id::new(case.item.name.name()); + if let Some(names) = &mut names { + if !names.remove(&name) { + return Err(ValidationError::InvalidUnionField { + name: name.as_str().to_string(), + location: self.location(case.item.name.span()), + reason: format!("does not correspond to variant in tag `tag`"), + }); } - hash_map::Entry::Vacant { .. } => Err(ValidationError::InvalidUnionField { - name: variant_name.name().to_string(), - reason: format!( - "does not correspond to variant in tag `{}`", - tag.name.as_str() - ), - location: self.location(variant_name.span()), - })?, } - Ok(UnionVariant { name, tref, docs }) + Ok(Case { + name: Id::new(case.item.name.name()), + tref: match &case.item.ty { + Some(ty) => { + Some(self.validate_datatype(ty, false, case.item.name.span())?) + } + None => None, + }, + docs: case.comments.docs(), + }) }) - .collect::, _>>()?; + .collect::, _>>()?; + Ok(Variant { tag_repr, cases }) + } - let unused_variants = variant_name_uses - .iter() - .filter(|(_k, used)| **used == false) - .map(|(k, _)| k.clone()) - .collect::>(); - if !unused_variants.is_empty() { - Err(ValidationError::InvalidUnionField { - name: unused_variants - .iter() - .map(|i| i.as_str()) - .collect::>() - .join(", "), - reason: format!("missing variants from tag `{}`", tag.name.as_str()), - location: self.location(span), - })?; + fn union_tag_repr( + &self, + tag: &Option>>, + span: wast::Span, + ) -> Result<(IntRepr, Option>), ValidationError> { + let ty = match tag { + Some(tag) => self.validate_datatype(tag, false, span)?, + None => return Ok((IntRepr::U32, None)), + }; + match &*ty.type_() { + Type::Variant(e) => { + let mut names = Vec::new(); + for c in e.cases.iter() { + if c.tref.is_some() { + return Err(ValidationError::InvalidUnionTag { + location: self.location(span), + reason: format!("all variant cases should have empty payloads"), + }); + } + names.push(c.name.clone()); + } + return Ok((e.tag_repr, Some(names))); + } + Type::Builtin(BuiltinType::U8) => return Ok((IntRepr::U8, None)), + Type::Builtin(BuiltinType::U16) => return Ok((IntRepr::U16, None)), + Type::Builtin(BuiltinType::U32) => return Ok((IntRepr::U32, None)), + Type::Builtin(BuiltinType::U64) => return Ok((IntRepr::U64, None)), + _ => {} } - Ok(UnionDatatype { tag, variants }) + + Err(ValidationError::WrongKindName { + name: "tag".to_string(), + location: self.location(span), + expected: "enum or builtin", + got: ty.type_().kind(), + }) } fn validate_handle( diff --git a/proposals/random/tools/witx/tests/anonymous.rs b/proposals/random/tools/witx/tests/anonymous.rs index a295a3915..6cfb2ea7e 100644 --- a/proposals/random/tools/witx/tests/anonymous.rs +++ b/proposals/random/tools/witx/tests/anonymous.rs @@ -12,9 +12,8 @@ fn anonymous_types() { let pointer_to_record = witx::parse("(typename $a (@witx pointer (record (field $b u8))))"); assert!(is_anonymous_record_err(pointer_to_record)); - let pointer_to_union = witx::parse( - "(typename $tag (enum $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", - ); + let pointer_to_union = + witx::parse("(typename $tag (enum $b)) (typename $a (@witx pointer (union u8)))"); assert!(is_anonymous_record_err(pointer_to_union)); let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum $b)))"); @@ -35,9 +34,8 @@ fn anonymous_types() { let record_in_record = witx::parse("(typename $a (record (field $b (record (field $c u8)))))"); assert!(is_anonymous_record_err(record_in_record)); - let union_in_record = witx::parse( - "(typename $tag (enum $c)) (typename $a (record (field $b (union $tag (field $c u8)))))", - ); + let union_in_record = + witx::parse("(typename $tag (enum $c)) (typename $a (record (field $b (union u8))))"); assert!(is_anonymous_record_err(union_in_record)); let pointer_in_record = witx::parse("(typename $a (record (field $b (@witx pointer u8))))"); diff --git a/proposals/random/tools/witx/tests/union.rs b/proposals/random/tools/witx/tests/union.rs index 30fb4dfdf..6cfa43e39 100644 --- a/proposals/random/tools/witx/tests/union.rs +++ b/proposals/random/tools/witx/tests/union.rs @@ -5,7 +5,7 @@ use witx::{Id, Representable}; fn one_variant_union() { let d = witx::parse( "(typename $tag (enum $c)) - (typename $u (union $tag (field $c u8)))", + (typename $u (union (@witx tag $tag) u8))", ); assert!(d.is_ok()); } @@ -14,14 +14,14 @@ fn one_variant_union() { fn two_variant_union() { let d1 = witx::parse( "(typename $tag (enum $a $b)) - (typename $u (union $tag (field $a u8) (field $b u16)))", + (typename $u (union (@witx tag $tag) u8 u16))", ); assert!(d1.is_ok(), "d1 is ok"); // Fields can come in whatever order: let d2 = witx::parse( "(typename $tag (enum $a $b)) - (typename $u (union $tag (field $b u16) (field $a u8)))", + (typename $u (variant (@witx tag $tag) (case $b u16) (case $a u8)))", ); assert!(d2.is_ok(), "d2 is ok"); @@ -40,31 +40,25 @@ fn two_variant_union() { "u2 can represent u1" ); - // Tag order doesnt matter for validation, but does for rep equality + // Tag order doesnt matter for validation let d3 = witx::parse( "(typename $tag (enum $b $a)) - (typename $u (union $tag (field $b u16) (field $a u8)))", + (typename $u (union (@witx tag $tag) u16 u8))", ); assert!(d3.is_ok(), "d2 is ok"); - let u3 = d3.unwrap().typename(&Id::new("u")).unwrap().type_(); - assert_eq!( - u3.representable(&u1), - witx::RepEquality::NotEq, - "u3 cannot represent u1" - ); } #[test] fn empty_variant_unions() { let d1 = witx::parse( "(typename $tag (enum $a $b)) - (typename $u (union $tag (empty $a) (field $b u16)))", + (typename $u (variant (@witx tag $tag) (case $a) (case $b u16)))", ); assert!(d1.is_ok(), "d1 is ok"); let d2 = witx::parse( "(typename $tag (enum $a $b)) - (typename $u (union $tag (empty $a) (empty $b)))", + (typename $u (variant (@witx tag $tag) (case $a) (case $b)))", ); assert!(d2.is_ok(), "d2 is ok"); } @@ -74,20 +68,20 @@ fn many_variant_unions() { let d1 = witx::parse( "(typename $tag (enum $a $b $c $d $e $f $g $h $i $j $k $l $m)) (typename $u - (union $tag - (field $a u8) - (field $b u16) - (field $c u32) - (field $d u64) - (field $e s8) - (field $f s16) - (field $g s32) - (field $h s64) - (field $i f32) - (field $j f64) - (field $k (@witx usize)) - (field $l char8) - (empty $m) + (variant (@witx tag $tag) + (case $a u8) + (case $b u16) + (case $c u32) + (case $d u64) + (case $e s8) + (case $f s16) + (case $g s32) + (case $h s64) + (case $i f32) + (case $j f64) + (case $k (@witx usize)) + (case $l char8) + (case $m) ) )", ); @@ -103,45 +97,48 @@ fn no_tag_union() { #[test] fn wrong_kind_tag_union() { let d = witx::parse( - "(typename $tag u32) - (typename $u (union $tag (field $a u8) (field $b u16)))", + "(typename $tag string) + (typename $u (union (@witx tag $tag) u8 u16))", ); let (expected, got) = wrong_kind_name_err(d).expect("wrong kind of tag"); - assert_eq!(expected, "enum"); - assert_eq!(got, "builtin"); + assert_eq!(expected, "enum or builtin"); + assert_eq!(got, "list"); } #[test] fn bad_field_unions() { let d = witx::parse( "(typename $tag (enum $c)) - (typename $u (union $tag (field $b u8)))", - ); - let (name, reason) = union_field_err(d).expect("bad field union 1"); - assert_eq!(name, "b", "bad field name union 1"); - assert_eq!( - reason, "does not correspond to variant in tag `tag`", - "reason union 1" - ); + (typename $u (variant (@witx tag $tag) (case $b u8)))", + ); + match validation_err(d) { + witx::ValidationError::InvalidUnionField { name, reason, .. } => { + assert_eq!(name, "b", "bad field name union 1"); + assert_eq!( + reason, "does not correspond to variant in tag `tag`", + "reason union 1" + ); + } + other => panic!("bad error: {}", other), + } let d = witx::parse( "(typename $tag (enum $c)) - (typename $u (union $tag (field $c f32) (field $b u8)))", - ); - let (name, reason) = union_field_err(d).expect("bad field union 2"); - assert_eq!(name, "b", "bad field name union 2"); - assert_eq!( - reason, "does not correspond to variant in tag `tag`", - "reason union 2" + (typename $u (variant (@witx tag $tag) (case $c f32) (case $b u8)))", ); + match validation_err(d) { + witx::ValidationError::UnionSizeMismatch { .. } => {} + other => panic!("bad error: {}", other), + } let d = witx::parse( "(typename $tag (enum $c $d)) - (typename $u (union $tag (field $c f32)))", + (typename $u (variant (@witx tag $tag) (case $c f32)))", ); - let (name, reason) = union_field_err(d).expect("bad field union 3"); - assert_eq!(name, "d", "bad field name union 3"); - assert_eq!(reason, "missing variants from tag `tag`", "reason union 3"); + match validation_err(d) { + witx::ValidationError::UnionSizeMismatch { .. } => {} + other => panic!("bad error: {}", other), + } } fn wrong_kind_name_err( @@ -164,20 +161,14 @@ fn wrong_kind_name_err( } } -fn union_field_err(r: Result) -> Option<(String, String)> { +fn validation_err(r: Result) -> witx::ValidationError { match r { - Err(witx::WitxError::Validation(witx::ValidationError::InvalidUnionField { - name, - reason, - .. - })) => Some((name, reason)), + Err(witx::WitxError::Validation(e)) => e, Err(e) => { - eprintln!("expected InvalidUnionField ValidationError, got: {:?}", e); - None + panic!("expected ValidationError, got: {:?}", e) } Ok(_) => { - eprintln!("expected InvalidUnionField ValidationError, got: Ok(witx::Document)"); - None + panic!("expected ValidationError, got: Ok(witx::Document)") } } } From f057b2b279ede806a2051b476e57a1b464626067 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 14:12:49 -0800 Subject: [PATCH 0849/1772] Implement Union in terms of Variant --- proposals/filesystem/phases/ephemeral/docs.md | 36 ++- .../phases/ephemeral/witx/typenames.witx | 20 +- .../filesystem/phases/old/snapshot_0/docs.md | 24 +- .../phases/old/snapshot_0/witx/typenames.witx | 12 +- proposals/filesystem/phases/snapshot/docs.md | 24 +- .../phases/snapshot/witx/typenames.witx | 13 +- proposals/filesystem/tools/witx/src/ast.rs | 15 -- .../filesystem/tools/witx/src/coretypes.rs | 2 +- .../filesystem/tools/witx/src/docs/ast.rs | 82 ++----- .../filesystem/tools/witx/src/docs/md.rs | 2 - proposals/filesystem/tools/witx/src/layout.rs | 56 ----- proposals/filesystem/tools/witx/src/lib.rs | 2 +- proposals/filesystem/tools/witx/src/parser.rs | 91 +++++--- proposals/filesystem/tools/witx/src/render.rs | 35 +-- .../tools/witx/src/representation.rs | 103 +++----- .../filesystem/tools/witx/src/validate.rs | 220 ++++++++++-------- .../filesystem/tools/witx/tests/anonymous.rs | 10 +- .../filesystem/tools/witx/tests/union.rs | 111 ++++----- 18 files changed, 360 insertions(+), 498 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index c579e00a3..7ea6969f8 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -859,20 +859,18 @@ The state of the file descriptor. Offset: 8 -## `event_u`: Union +## `event_u`: Variant The contents of an [`event`](#event). Size: 24 Alignment: 8 -### Union Layout +### Variant Layout +- size: 24 +- align: 8 - tag_size: 1 -- tag_align: 1 -- contents_offset: 8 -- contents_size: 16 -- contents_align: 8 -### Union variants +### Variant cases - `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) - `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) @@ -961,20 +959,18 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Union +## `subscription_u`: Variant The contents of a [`subscription`](#subscription). Size: 40 Alignment: 8 -### Union Layout +### Variant Layout +- size: 40 +- align: 8 - tag_size: 1 -- tag_align: 1 -- contents_offset: 8 -- contents_size: 32 -- contents_align: 8 -### Union variants +### Variant cases - `clock`: [`subscription_clock`](#subscription_clock) - `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) @@ -1078,20 +1074,18 @@ The length of the directory name for use with `fd_prestat_dir_name`. Offset: 0 -## `prestat`: Union +## `prestat`: Variant Information about a pre-opened capability. Size: 8 Alignment: 4 -### Union Layout +### Variant Layout +- size: 8 +- align: 4 - tag_size: 1 -- tag_align: 1 -- contents_offset: 4 -- contents_size: 4 -- contents_align: 4 -### Union variants +### Variant cases - `dir`: [`prestat_dir`](#prestat_dir) When type is [`preopentype::dir`](#preopentype.dir): diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index e10c4c30d..503aa0cf6 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -562,10 +562,10 @@ ;;; The contents of an `event`. (typename $event_u - (union $eventtype - (field $fd_read $event_fd_readwrite) - (field $fd_write $event_fd_readwrite) - (empty $clock) + (variant (@witx tag $eventtype) + (case $fd_read $event_fd_readwrite) + (case $fd_write $event_fd_readwrite) + (case $clock) ) ) @@ -620,10 +620,10 @@ ;;; The contents of a `subscription`. (typename $subscription_u - (union $eventtype - (field $clock $subscription_clock) - (field $fd_read $subscription_fd_readwrite) - (field $fd_write $subscription_fd_readwrite) + (union (@witx tag $eventtype) + $subscription_clock + $subscription_fd_readwrite + $subscription_fd_readwrite ) ) @@ -691,8 +691,8 @@ ;;; Information about a pre-opened capability. (typename $prestat - (union $preopentype + (union (@witx tag $preopentype) ;;; When type is `preopentype::dir`: - (field $dir $prestat_dir) + $prestat_dir ) ) diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index 0e2f5bde0..e77002bc6 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -899,20 +899,18 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Union +## `subscription_u`: Variant The contents of a [`subscription`](#subscription). Size: 48 Alignment: 8 -### Union Layout +### Variant Layout +- size: 48 +- align: 8 - tag_size: 1 -- tag_align: 1 -- contents_offset: 8 -- contents_size: 40 -- contents_align: 8 -### Union variants +### Variant cases - `clock`: [`subscription_clock`](#subscription_clock) - `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) @@ -1148,20 +1146,18 @@ The length of the directory name for use with [`fd_prestat_dir_name`](#fd_presta Offset: 0 -## `prestat`: Union +## `prestat`: Variant Information about a pre-opened capability. Size: 8 Alignment: 4 -### Union Layout +### Variant Layout +- size: 8 +- align: 4 - tag_size: 1 -- tag_align: 1 -- contents_offset: 4 -- contents_size: 4 -- contents_align: 4 -### Union variants +### Variant cases - `dir`: [`prestat_dir`](#prestat_dir) # Modules diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx index f24000e00..eb6f70020 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx @@ -570,10 +570,10 @@ ;;; The contents of a `subscription`. (typename $subscription_u - (union $eventtype - (field $clock $subscription_clock) - (field $fd_read $subscription_fd_readwrite) - (field $fd_write $subscription_fd_readwrite) + (union (@witx tag $eventtype) + $subscription_clock + $subscription_fd_readwrite + $subscription_fd_readwrite ) ) @@ -740,7 +740,7 @@ ;;; Information about a pre-opened capability. (typename $prestat - (union $preopentype - (field $dir $prestat_dir) + (union (@witx tag $preopentype) + $prestat_dir ) ) diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index e13dcc79d..1bbbe59f2 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -896,20 +896,18 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Union +## `subscription_u`: Variant The contents of a [`subscription`](#subscription). Size: 40 Alignment: 8 -### Union Layout +### Variant Layout +- size: 40 +- align: 8 - tag_size: 1 -- tag_align: 1 -- contents_offset: 8 -- contents_size: 32 -- contents_align: 8 -### Union variants +### Variant cases - `clock`: [`subscription_clock`](#subscription_clock) - `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) @@ -1145,20 +1143,18 @@ The length of the directory name for use with [`fd_prestat_dir_name`](#fd_presta Offset: 0 -## `prestat`: Union +## `prestat`: Variant Information about a pre-opened capability. Size: 8 Alignment: 4 -### Union Layout +### Variant Layout +- size: 8 +- align: 4 - tag_size: 1 -- tag_align: 1 -- contents_offset: 4 -- contents_size: 4 -- contents_align: 4 -### Union variants +### Variant cases - `dir`: [`prestat_dir`](#prestat_dir) # Modules diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx index 13eb1759f..70e726553 100644 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -570,10 +570,11 @@ ;;; The contents of a `subscription`. (typename $subscription_u - (union $eventtype - (field $clock $subscription_clock) - (field $fd_read $subscription_fd_readwrite) - (field $fd_write $subscription_fd_readwrite) + (union + (@witx tag $eventtype) + $subscription_clock + $subscription_fd_readwrite + $subscription_fd_readwrite ) ) @@ -740,8 +741,8 @@ ;;; Information about a pre-opened capability. (typename $prestat - (union $preopentype - (field $dir $prestat_dir) + (union (@witx tag $preopentype) + $prestat_dir ) ) diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 00c9fac83..5ba525520 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -187,7 +187,6 @@ impl NamedType { pub enum Type { Record(RecordDatatype), Variant(Variant), - Union(UnionDatatype), Handle(HandleDatatype), List(TypeRef), Pointer(TypeRef), @@ -201,7 +200,6 @@ impl Type { match self { Record(_) => "record", Variant(_) => "variant", - Union(_) => "union", Handle(_) => "handle", List(_) => "list", Pointer(_) => "pointer", @@ -272,19 +270,6 @@ pub struct Case { pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct UnionDatatype { - pub tag: Rc, - pub variants: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct UnionVariant { - pub name: Id, - pub tref: Option, - pub docs: String, -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct HandleDatatype {} diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index 3a5e41284..35fea801e 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -50,7 +50,7 @@ impl Type { }, Type::List { .. } => TypePassedBy::PointerLengthPair, Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), - Type::Record { .. } | Type::Union { .. } => TypePassedBy::Pointer, + Type::Record { .. } => TypePassedBy::Pointer, Type::Variant(v) => { if v.cases.iter().all(|c| c.tref.is_none()) { TypePassedBy::Value(v.tag_repr.into()) diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index a776907a3..eb4d3e7cb 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -89,7 +89,6 @@ impl ToMarkdown for Type { match self { Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), - Self::Union(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), Self::List(a) => { node.content_ref_mut::().r#type = Some(MdType::List { @@ -144,6 +143,27 @@ impl ToMarkdown for RecordDatatype { impl ToMarkdown for Variant { fn generate(&self, node: MdNodeRef) { + if self.cases.iter().any(|c| c.tref.is_some()) { + let heading = heading_from_node(&node, 1); + node.new_child(MdSection::new(heading, "Variant Layout")); + + let whole = self.mem_size_align(); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("size: {}", whole.size), + )); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("align: {}", whole.align), + )); + + let tag = self.tag_repr.mem_size_align(); + node.new_child(MdSection::new( + MdHeading::new_bullet(), + format!("tag_size: {}", tag.size), + )); + } + let heading = heading_from_node(&node, 1); node.new_child(MdSection::new(heading, "Variant cases")); @@ -169,61 +189,6 @@ impl ToMarkdown for Variant { } } -impl ToMarkdown for UnionDatatype { - fn generate(&self, node: MdNodeRef) { - // Sizes & Alignments - let sizes_heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(sizes_heading, "Union Layout")); - let union_layout = &self.union_layout(); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("tag_size: {}", union_layout.tag_size).as_str(), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("tag_align: {}", union_layout.tag_align).as_str(), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("contents_offset: {}", union_layout.contents_offset).as_str(), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("contents_size: {}", union_layout.contents_size).as_str(), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("contents_align: {}", union_layout.contents_align).as_str(), - )); - - // Variants - let variants_heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(variants_heading, "Union variants")); - - for variant in &self.variants { - let name = variant.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let n = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - &variant.docs, - )); - if let Some(ref tref) = variant.tref { - tref.generate(n.clone()); - } else { - n.content_ref_mut::().r#type = None; - } - } - - node.content_ref_mut::().r#type = Some(MdType::Union); - } -} - impl ToMarkdown for HandleDatatype { fn generate(&self, node: MdNodeRef) { // TODO this needs more work @@ -352,10 +317,7 @@ impl TypeRef { Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), - Type::Record { .. } - | Type::Variant { .. } - | Type::Union { .. } - | Type::Handle { .. } => { + Type::Record { .. } | Type::Variant { .. } | Type::Handle { .. } => { unimplemented!("type_name of anonymous compound datatypes") } }, diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index 6519d0745..d3d5b756d 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -345,7 +345,6 @@ impl MdNamedType { pub(super) enum MdType { Record, Variant, - Union, List { r#type: String }, Pointer { r#type: String }, ConstPointer { r#type: String }, @@ -359,7 +358,6 @@ impl fmt::Display for MdType { match self { Self::Record => f.write_fmt(format_args!(": Record"))?, Self::Variant => f.write_fmt(format_args!(": Variant"))?, - Self::Union => f.write_fmt(format_args!(": Union"))?, Self::List { r#type } => { if r#type == "char" { f.write_str(": `string`")? diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index 1e4b03211..6b77d8a32 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -66,7 +66,6 @@ impl Type { match &self { Type::Record(s) => s.layout(cache), Type::Variant(s) => s.mem_size_align(), - Type::Union(u) => u.layout(cache), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), @@ -178,61 +177,6 @@ mod test { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct UnionLayout { - pub tag_size: usize, - pub tag_align: usize, - pub contents_offset: usize, - pub contents_size: usize, - pub contents_align: usize, -} - -impl Layout for UnionLayout { - fn mem_size_align(&self) -> SizeAlign { - let align = std::cmp::max(self.tag_align, self.contents_align); - let size = align_to(self.contents_offset + self.contents_size, align); - SizeAlign { size, align } - } -} - -impl UnionDatatype { - pub fn union_layout(&self) -> UnionLayout { - let mut cache = HashMap::new(); - self.union_layout_(&mut cache) - } - fn union_layout_(&self, cache: &mut HashMap) -> UnionLayout { - let tag = self.tag.layout(cache); - - let variant_sas = self - .variants - .iter() - .filter_map(|v| v.tref.as_ref().map(|t| t.layout(cache))) - .collect::>(); - - let contents_size = variant_sas.iter().map(|sa| sa.size).max().unwrap_or(0); - let contents_align = variant_sas.iter().map(|sa| sa.align).max().unwrap_or(1); - - UnionLayout { - tag_size: tag.size, - tag_align: tag.align, - contents_offset: align_to(tag.size, contents_align), - contents_size, - contents_align, - } - } - - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - self.union_layout_(cache).mem_size_align() - } -} - -impl Layout for UnionDatatype { - fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } -} - impl Layout for HandleDatatype { fn mem_size_align(&self) -> SizeAlign { BuiltinType::U32.mem_size_align() diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 72774c16c..9c0f53060 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -27,7 +27,7 @@ pub use ast::*; pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; -pub use layout::{Layout, RecordMemberLayout, SizeAlign, UnionLayout}; +pub use layout::{Layout, RecordMemberLayout, SizeAlign}; pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 6015cb052..ee8bf081e 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -19,6 +19,7 @@ mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; wast::custom_keyword!(bitflags); + wast::custom_keyword!(case); wast::custom_keyword!(char8); wast::custom_keyword!(char); wast::custom_keyword!(const_pointer); @@ -48,6 +49,7 @@ mod kw { wast::custom_keyword!(u64); wast::custom_keyword!(u8); wast::custom_keyword!(usize); + wast::custom_keyword!(variant); } mod annotation { @@ -280,6 +282,7 @@ pub enum TypedefSyntax<'a> { Flags(FlagsSyntax<'a>), Record(RecordSyntax<'a>), Union(UnionSyntax<'a>), + Variant(VariantSyntax<'a>), Handle(HandleSyntax), List(Box>), Pointer(Box>), @@ -310,6 +313,8 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Record(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Union(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Variant(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Handle(parser.parse()?)) } else if l.peek::() { @@ -448,42 +453,24 @@ impl<'a> Parse<'a> for FieldSyntax<'a> { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum VariantSyntax<'a> { - Field(FieldSyntax<'a>), - Empty(wast::Id<'a>), -} - -impl<'a> Parse<'a> for VariantSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - let mut l = p.lookahead1(); - if l.peek::() { - parser.parse::()?; - let name = p.parse()?; - let type_ = p.parse()?; - Ok(VariantSyntax::Field(FieldSyntax { name, type_ })) - } else if l.peek::() { - parser.parse::()?; - let name = p.parse()?; - Ok(VariantSyntax::Empty(name)) - } else { - Err(l.error()) - } - }) - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnionSyntax<'a> { - pub tag: wast::Id<'a>, - pub fields: Vec>>, + pub tag: Option>>, + pub fields: Vec>>, } impl<'a> Parse<'a> for UnionSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let tag = parser.parse()?; + let tag = if parser.peek2::() { + Some(parser.parens(|p| { + p.parse::()?; + p.parse::()?; + p.parse().map(Box::new) + })?) + } else { + None + }; let mut fields = Vec::new(); fields.push(parser.parse()?); while !parser.is_empty() { @@ -493,6 +480,52 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct VariantSyntax<'a> { + pub tag: Option>>, + pub cases: Vec>>, +} + +impl<'a> Parse<'a> for VariantSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let tag = if parser.peek2::() { + Some(parser.parens(|p| { + p.parse::()?; + p.parse::()?; + p.parse().map(Box::new) + })?) + } else { + None + }; + let mut cases = Vec::new(); + while !parser.is_empty() { + cases.push(parser.parens(|p| p.parse())?); + } + Ok(VariantSyntax { tag, cases }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CaseSyntax<'a> { + pub name: wast::Id<'a>, + pub ty: Option>, +} + +impl<'a> Parse<'a> for CaseSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + Ok(CaseSyntax { + name: parser.parse()?, + ty: if parser.is_empty() { + None + } else { + Some(parser.parse()?) + }, + }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct HandleSyntax {} diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 16b92d48a..60df3d6a2 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -118,7 +118,6 @@ impl Type { match self { Type::Record(a) => a.to_sexpr(), Type::Variant(a) => a.to_sexpr(), - Type::Union(a) => a.to_sexpr(), Type::Handle(a) => a.to_sexpr(), Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), Type::Pointer(p) => SExpr::Vec(vec![ @@ -172,6 +171,11 @@ impl Variant { } } else { list.push(SExpr::word("variant")); + list.push(SExpr::Vec(vec![ + SExpr::word("@witx"), + SExpr::word("tag"), + self.tag_repr.to_sexpr(), + ])); for case in self.cases.iter() { let mut case_expr = vec![SExpr::word("case"), case.name.to_sexpr()]; if let Some(ty) = &case.tref { @@ -184,39 +188,12 @@ impl Variant { } } -impl UnionDatatype { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("union"), self.tag.name.to_sexpr()]; - let variants = self - .variants - .iter() - .map(|v| { - if let Some(ref tref) = v.tref { - SExpr::docs( - &v.docs, - SExpr::Vec(vec![ - SExpr::word("field"), - v.name.to_sexpr(), - tref.to_sexpr(), - ]), - ) - } else { - SExpr::docs( - &v.docs, - SExpr::Vec(vec![SExpr::word("empty"), v.name.to_sexpr()]), - ) - } - }) - .collect::>(); - SExpr::Vec([header, variants].concat()) - } -} - impl HandleDatatype { pub fn to_sexpr(&self) -> SExpr { SExpr::Vec(vec![SExpr::word("handle")]) } } + impl IntRepr { pub fn to_sexpr(&self) -> SExpr { match self { diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs index d3f7bf817..6c36e71e7 100644 --- a/proposals/filesystem/tools/witx/src/representation.rs +++ b/proposals/filesystem/tools/witx/src/representation.rs @@ -1,6 +1,5 @@ -use crate::{ - BuiltinType, IntRepr, NamedType, RecordDatatype, Type, TypeRef, UnionDatatype, Variant, -}; +use crate::{BuiltinType, IntRepr, NamedType, RecordDatatype, Type, TypeRef, Variant}; +use std::collections::HashMap; // A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -70,24 +69,41 @@ impl Representable for IntRepr { impl Representable for Variant { fn representable(&self, by: &Self) -> RepEquality { + let mut superset = false; // Integer representation must be compatible - if self.tag_repr.representable(&by.tag_repr) == RepEquality::NotEq { - return RepEquality::NotEq; + match self.tag_repr.representable(&by.tag_repr) { + RepEquality::NotEq => return RepEquality::NotEq, + RepEquality::Eq => {} + RepEquality::Superset => superset = true, } - // For each variant in self, must have variant of same name and position in by: - for (ix, v) in self.cases.iter().enumerate() { - if let Some(by_v) = by.cases.get(ix) { - if by_v.name != v.name { - return RepEquality::NotEq; - } - } else { - return RepEquality::NotEq; + let other_by_name = by + .cases + .iter() + .map(|c| (&c.name, c)) + .collect::>(); + // For each variant in self, must have variant of same name in by: + for v in self.cases.iter() { + let other_ty = match other_by_name.get(&v.name) { + Some(other) => &other.tref, + None => return RepEquality::NotEq, + }; + match (&v.tref, other_ty) { + (Some(me), Some(other)) => match me.representable(other) { + RepEquality::NotEq => return RepEquality::NotEq, + RepEquality::Eq => {} + RepEquality::Superset => superset = true, + }, + // We added fields, that's not ok + (Some(_), None) => return RepEquality::NotEq, + // Fields were deleted, that's ok + (None, Some(_)) => superset = true, + (None, None) => {} } } - if by.cases.len() > self.cases.len() { + if superset || self.cases.len() < by.cases.len() { RepEquality::Superset } else { - self.tag_repr.representable(&by.tag_repr) + RepEquality::Eq } } } @@ -113,56 +129,6 @@ impl Representable for RecordDatatype { } } -impl Representable for UnionDatatype { - fn representable(&self, by: &Self) -> RepEquality { - // Unions must have equal variants, by name (independent of order). If `by` has extra - // variants, its a superset. - // We would require require a more expressive RepEquality enum to describe which variants - // might be supersets. - if self.variants.len() > by.variants.len() { - return RepEquality::NotEq; - } - for v in self.variants.iter() { - if let Some(byv) = by.variants.iter().find(|byv| byv.name == v.name) { - if v.tref.is_none() && byv.tref.is_none() { - // Both empty is OK - } else if v.tref.is_some() && byv.tref.is_some() { - if v.tref - .as_ref() - .unwrap() - .type_() - .representable(&*byv.tref.as_ref().unwrap().type_()) - != RepEquality::Eq - { - // Fields must be Eq - return RepEquality::NotEq; - } - } else { - // Either one empty means not representable - return RepEquality::NotEq; - } - } else { - return RepEquality::NotEq; - } - } - if by.variants.len() > self.variants.len() { - // By is a superset of self only if the tags are as well: - if self.tag.type_().representable(&*by.tag.type_()) == RepEquality::Superset { - RepEquality::Superset - } else { - RepEquality::NotEq - } - } else { - // By and self have matching variants, so they are equal if tags are: - if self.tag.type_().representable(&*by.tag.type_()) == RepEquality::Eq { - RepEquality::Eq - } else { - RepEquality::NotEq - } - } - } -} - impl Representable for TypeRef { fn representable(&self, by: &Self) -> RepEquality { self.type_().representable(&*by.type_()) @@ -180,7 +146,6 @@ impl Representable for Type { match (&self, &by) { (Type::Variant(s), Type::Variant(b)) => s.representable(b), (Type::Record(s), Type::Record(b)) => s.representable(b), - (Type::Union(s), Type::Union(b)) => s.representable(b), (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural (Type::List(s), Type::List(b)) => s.representable(b), (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), @@ -239,12 +204,12 @@ mod test { let base = def_type( "a", "(typename $tag (enum (@witx tag u8) $b $c)) - (typename $a (union $tag (field $b u32) (field $c f32)))", + (typename $a (union (@witx tag $tag) u32 f32))", ); let extra_variant = def_type( "a", "(typename $tag (enum (@witx tag u8) $b $c $d)) - (typename $a (union $tag (field $b u32) (field $c f32) (field $d f64)))", + (typename $a (union (@witx tag $tag) u32 f32 f64))", ); assert_eq!(base.representable(&extra_variant), RepEquality::Superset); @@ -253,7 +218,7 @@ mod test { let other_ordering = def_type( "a", "(typename $tag (enum (@witx tag u8) $b $c)) - (typename $a (union $tag (field $c f32) (field $b u32)))", + (typename $a (variant (@witx tag $tag) (case $c f32) (case $b u32)))", ); assert_eq!(base.representable(&other_ordering), RepEquality::Eq); assert_eq!(other_ordering.representable(&base), RepEquality::Eq); diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 8d698c77a..7abeef733 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -8,9 +8,9 @@ use crate::{ BuiltinType, Case, Constant, Definition, Entry, HandleDatatype, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordMember, Type, - TypePassedBy, TypeRef, UnionDatatype, UnionVariant, Variant, + TypePassedBy, TypeRef, Variant, }; -use std::collections::{hash_map, HashMap}; +use std::collections::{HashMap, HashSet}; use std::path::Path; use std::rc::Rc; use thiserror::Error; @@ -43,14 +43,16 @@ pub enum ValidationError { InvalidFirstResultType { location: Location }, #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] AnonymousRecord { location: Location }, - #[error("Invalid union field `{name}`: {reason}")] - InvalidUnionField { - name: String, - reason: String, + #[error("Union expected {expected} variants, found {found}")] + UnionSizeMismatch { + expected: usize, + found: usize, location: Location, }, - #[error("Invalid union tag `{name}`: {reason}")] - InvalidUnionTag { + #[error("Invalid union tag: {reason}")] + InvalidUnionTag { reason: String, location: Location }, + #[error("Invalid union field `{name}`: {reason}")] + InvalidUnionField { name: String, reason: String, location: Location, @@ -67,6 +69,7 @@ impl ValidationError { | InvalidRepr { location, .. } | InvalidFirstResultType { location, .. } | AnonymousRecord { location, .. } + | UnionSizeMismatch { location, .. } | InvalidUnionField { location, .. } | InvalidUnionTag { location, .. } => { format!("{}\n{}", location.highlight_source_with(witxio), &self) @@ -299,7 +302,10 @@ impl DocValidationScope<'_> { TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), TypedefSyntax::Flags(syntax) => self.validate_flags(&syntax, span)?, TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), - TypedefSyntax::Union(syntax) => Type::Union(self.validate_union(&syntax, span)?), + TypedefSyntax::Union(syntax) => Type::Variant(self.validate_union(&syntax, span)?), + TypedefSyntax::Variant(syntax) => { + Type::Variant(self.validate_variant(&syntax, span)?) + } TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), TypedefSyntax::List(syntax) => { Type::List(self.validate_datatype(syntax, false, span)?) @@ -385,105 +391,121 @@ impl DocValidationScope<'_> { &self, syntax: &UnionSyntax, span: wast::Span, - ) -> Result { - let mut variant_scope = IdentValidation::new(); - let tag_id = self.get(&syntax.tag)?; - let (tag, mut variant_name_uses) = match self.doc.entries.get(&tag_id) { - Some(Entry::Typename(weak_ref)) => { - let named_dt = weak_ref.upgrade().expect("weak backref to defined type"); - match &*named_dt.type_() { - Type::Variant(e) => { - let mut uses = HashMap::new(); - for c in e.cases.iter() { - if c.tref.is_some() { - return Err(ValidationError::InvalidUnionTag { - name: syntax.tag.name().to_string(), - location: self.location(syntax.tag.span()), - reason: format!("all variant cases should have empty payloads"), - }); - } - uses.insert(c.name.clone(), false); - } - Ok((named_dt, uses)) - } - other => Err(ValidationError::WrongKindName { - name: syntax.tag.name().to_string(), - location: self.location(syntax.tag.span()), - expected: "enum", - got: other.kind(), - }), - } + ) -> Result { + let (tag_repr, names) = self.union_tag_repr(&syntax.tag, span)?; + + if let Some(names) = &names { + if names.len() != syntax.fields.len() { + return Err(ValidationError::UnionSizeMismatch { + expected: names.len(), + found: syntax.fields.len(), + location: self.location(span), + }); } - other => Err(ValidationError::WrongKindName { - name: syntax.tag.name().to_string(), - location: self.location(syntax.tag.span()), - expected: "enum", - got: match other { - Some(e) => e.kind(), - None => "unknown", - }, - }), - }?; + } - let variants = syntax + let cases = syntax .fields .iter() - .map(|v| { - let variant_name = match v.item { - VariantSyntax::Field(ref f) => &f.name, - VariantSyntax::Empty(ref name) => name, - }; - let name = variant_scope - .introduce(variant_name.name(), self.location(variant_name.span()))?; - let tref = match &v.item { - VariantSyntax::Field(f) => { - Some(self.validate_datatype(&f.type_, false, variant_name.span())?) - } - VariantSyntax::Empty { .. } => None, - }; - let docs = v.comments.docs(); - match variant_name_uses.entry(name.clone()) { - hash_map::Entry::Occupied(mut e) => { - if *e.get() { - Err(ValidationError::InvalidUnionField { - name: variant_name.name().to_string(), - reason: "variant already defined".to_owned(), - location: self.location(variant_name.span()), - })?; - } else { - e.insert(true); - } + .enumerate() + .map(|(i, case)| { + Ok(Case { + name: match &names { + Some(names) => names[i].clone(), + None => Id::new(i.to_string()), + }, + tref: Some(self.validate_datatype(&case.item, false, span)?), + docs: case.comments.docs(), + }) + }) + .collect::, _>>()?; + Ok(Variant { tag_repr, cases }) + } + + fn validate_variant( + &self, + syntax: &VariantSyntax, + span: wast::Span, + ) -> Result { + let (tag_repr, names) = self.union_tag_repr(&syntax.tag, span)?; + + if let Some(names) = &names { + if names.len() != syntax.cases.len() { + return Err(ValidationError::UnionSizeMismatch { + expected: names.len(), + found: syntax.cases.len(), + location: self.location(span), + }); + } + } + + let mut names = names.map(|names| names.into_iter().collect::>()); + + let cases = syntax + .cases + .iter() + .map(|case| { + let name = Id::new(case.item.name.name()); + if let Some(names) = &mut names { + if !names.remove(&name) { + return Err(ValidationError::InvalidUnionField { + name: name.as_str().to_string(), + location: self.location(case.item.name.span()), + reason: format!("does not correspond to variant in tag `tag`"), + }); } - hash_map::Entry::Vacant { .. } => Err(ValidationError::InvalidUnionField { - name: variant_name.name().to_string(), - reason: format!( - "does not correspond to variant in tag `{}`", - tag.name.as_str() - ), - location: self.location(variant_name.span()), - })?, } - Ok(UnionVariant { name, tref, docs }) + Ok(Case { + name: Id::new(case.item.name.name()), + tref: match &case.item.ty { + Some(ty) => { + Some(self.validate_datatype(ty, false, case.item.name.span())?) + } + None => None, + }, + docs: case.comments.docs(), + }) }) - .collect::, _>>()?; + .collect::, _>>()?; + Ok(Variant { tag_repr, cases }) + } - let unused_variants = variant_name_uses - .iter() - .filter(|(_k, used)| **used == false) - .map(|(k, _)| k.clone()) - .collect::>(); - if !unused_variants.is_empty() { - Err(ValidationError::InvalidUnionField { - name: unused_variants - .iter() - .map(|i| i.as_str()) - .collect::>() - .join(", "), - reason: format!("missing variants from tag `{}`", tag.name.as_str()), - location: self.location(span), - })?; + fn union_tag_repr( + &self, + tag: &Option>>, + span: wast::Span, + ) -> Result<(IntRepr, Option>), ValidationError> { + let ty = match tag { + Some(tag) => self.validate_datatype(tag, false, span)?, + None => return Ok((IntRepr::U32, None)), + }; + match &*ty.type_() { + Type::Variant(e) => { + let mut names = Vec::new(); + for c in e.cases.iter() { + if c.tref.is_some() { + return Err(ValidationError::InvalidUnionTag { + location: self.location(span), + reason: format!("all variant cases should have empty payloads"), + }); + } + names.push(c.name.clone()); + } + return Ok((e.tag_repr, Some(names))); + } + Type::Builtin(BuiltinType::U8) => return Ok((IntRepr::U8, None)), + Type::Builtin(BuiltinType::U16) => return Ok((IntRepr::U16, None)), + Type::Builtin(BuiltinType::U32) => return Ok((IntRepr::U32, None)), + Type::Builtin(BuiltinType::U64) => return Ok((IntRepr::U64, None)), + _ => {} } - Ok(UnionDatatype { tag, variants }) + + Err(ValidationError::WrongKindName { + name: "tag".to_string(), + location: self.location(span), + expected: "enum or builtin", + got: ty.type_().kind(), + }) } fn validate_handle( diff --git a/proposals/filesystem/tools/witx/tests/anonymous.rs b/proposals/filesystem/tools/witx/tests/anonymous.rs index a295a3915..6cfb2ea7e 100644 --- a/proposals/filesystem/tools/witx/tests/anonymous.rs +++ b/proposals/filesystem/tools/witx/tests/anonymous.rs @@ -12,9 +12,8 @@ fn anonymous_types() { let pointer_to_record = witx::parse("(typename $a (@witx pointer (record (field $b u8))))"); assert!(is_anonymous_record_err(pointer_to_record)); - let pointer_to_union = witx::parse( - "(typename $tag (enum $b)) (typename $a (@witx pointer (union $tag (field $b u8))))", - ); + let pointer_to_union = + witx::parse("(typename $tag (enum $b)) (typename $a (@witx pointer (union u8)))"); assert!(is_anonymous_record_err(pointer_to_union)); let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum $b)))"); @@ -35,9 +34,8 @@ fn anonymous_types() { let record_in_record = witx::parse("(typename $a (record (field $b (record (field $c u8)))))"); assert!(is_anonymous_record_err(record_in_record)); - let union_in_record = witx::parse( - "(typename $tag (enum $c)) (typename $a (record (field $b (union $tag (field $c u8)))))", - ); + let union_in_record = + witx::parse("(typename $tag (enum $c)) (typename $a (record (field $b (union u8))))"); assert!(is_anonymous_record_err(union_in_record)); let pointer_in_record = witx::parse("(typename $a (record (field $b (@witx pointer u8))))"); diff --git a/proposals/filesystem/tools/witx/tests/union.rs b/proposals/filesystem/tools/witx/tests/union.rs index 30fb4dfdf..6cfa43e39 100644 --- a/proposals/filesystem/tools/witx/tests/union.rs +++ b/proposals/filesystem/tools/witx/tests/union.rs @@ -5,7 +5,7 @@ use witx::{Id, Representable}; fn one_variant_union() { let d = witx::parse( "(typename $tag (enum $c)) - (typename $u (union $tag (field $c u8)))", + (typename $u (union (@witx tag $tag) u8))", ); assert!(d.is_ok()); } @@ -14,14 +14,14 @@ fn one_variant_union() { fn two_variant_union() { let d1 = witx::parse( "(typename $tag (enum $a $b)) - (typename $u (union $tag (field $a u8) (field $b u16)))", + (typename $u (union (@witx tag $tag) u8 u16))", ); assert!(d1.is_ok(), "d1 is ok"); // Fields can come in whatever order: let d2 = witx::parse( "(typename $tag (enum $a $b)) - (typename $u (union $tag (field $b u16) (field $a u8)))", + (typename $u (variant (@witx tag $tag) (case $b u16) (case $a u8)))", ); assert!(d2.is_ok(), "d2 is ok"); @@ -40,31 +40,25 @@ fn two_variant_union() { "u2 can represent u1" ); - // Tag order doesnt matter for validation, but does for rep equality + // Tag order doesnt matter for validation let d3 = witx::parse( "(typename $tag (enum $b $a)) - (typename $u (union $tag (field $b u16) (field $a u8)))", + (typename $u (union (@witx tag $tag) u16 u8))", ); assert!(d3.is_ok(), "d2 is ok"); - let u3 = d3.unwrap().typename(&Id::new("u")).unwrap().type_(); - assert_eq!( - u3.representable(&u1), - witx::RepEquality::NotEq, - "u3 cannot represent u1" - ); } #[test] fn empty_variant_unions() { let d1 = witx::parse( "(typename $tag (enum $a $b)) - (typename $u (union $tag (empty $a) (field $b u16)))", + (typename $u (variant (@witx tag $tag) (case $a) (case $b u16)))", ); assert!(d1.is_ok(), "d1 is ok"); let d2 = witx::parse( "(typename $tag (enum $a $b)) - (typename $u (union $tag (empty $a) (empty $b)))", + (typename $u (variant (@witx tag $tag) (case $a) (case $b)))", ); assert!(d2.is_ok(), "d2 is ok"); } @@ -74,20 +68,20 @@ fn many_variant_unions() { let d1 = witx::parse( "(typename $tag (enum $a $b $c $d $e $f $g $h $i $j $k $l $m)) (typename $u - (union $tag - (field $a u8) - (field $b u16) - (field $c u32) - (field $d u64) - (field $e s8) - (field $f s16) - (field $g s32) - (field $h s64) - (field $i f32) - (field $j f64) - (field $k (@witx usize)) - (field $l char8) - (empty $m) + (variant (@witx tag $tag) + (case $a u8) + (case $b u16) + (case $c u32) + (case $d u64) + (case $e s8) + (case $f s16) + (case $g s32) + (case $h s64) + (case $i f32) + (case $j f64) + (case $k (@witx usize)) + (case $l char8) + (case $m) ) )", ); @@ -103,45 +97,48 @@ fn no_tag_union() { #[test] fn wrong_kind_tag_union() { let d = witx::parse( - "(typename $tag u32) - (typename $u (union $tag (field $a u8) (field $b u16)))", + "(typename $tag string) + (typename $u (union (@witx tag $tag) u8 u16))", ); let (expected, got) = wrong_kind_name_err(d).expect("wrong kind of tag"); - assert_eq!(expected, "enum"); - assert_eq!(got, "builtin"); + assert_eq!(expected, "enum or builtin"); + assert_eq!(got, "list"); } #[test] fn bad_field_unions() { let d = witx::parse( "(typename $tag (enum $c)) - (typename $u (union $tag (field $b u8)))", - ); - let (name, reason) = union_field_err(d).expect("bad field union 1"); - assert_eq!(name, "b", "bad field name union 1"); - assert_eq!( - reason, "does not correspond to variant in tag `tag`", - "reason union 1" - ); + (typename $u (variant (@witx tag $tag) (case $b u8)))", + ); + match validation_err(d) { + witx::ValidationError::InvalidUnionField { name, reason, .. } => { + assert_eq!(name, "b", "bad field name union 1"); + assert_eq!( + reason, "does not correspond to variant in tag `tag`", + "reason union 1" + ); + } + other => panic!("bad error: {}", other), + } let d = witx::parse( "(typename $tag (enum $c)) - (typename $u (union $tag (field $c f32) (field $b u8)))", - ); - let (name, reason) = union_field_err(d).expect("bad field union 2"); - assert_eq!(name, "b", "bad field name union 2"); - assert_eq!( - reason, "does not correspond to variant in tag `tag`", - "reason union 2" + (typename $u (variant (@witx tag $tag) (case $c f32) (case $b u8)))", ); + match validation_err(d) { + witx::ValidationError::UnionSizeMismatch { .. } => {} + other => panic!("bad error: {}", other), + } let d = witx::parse( "(typename $tag (enum $c $d)) - (typename $u (union $tag (field $c f32)))", + (typename $u (variant (@witx tag $tag) (case $c f32)))", ); - let (name, reason) = union_field_err(d).expect("bad field union 3"); - assert_eq!(name, "d", "bad field name union 3"); - assert_eq!(reason, "missing variants from tag `tag`", "reason union 3"); + match validation_err(d) { + witx::ValidationError::UnionSizeMismatch { .. } => {} + other => panic!("bad error: {}", other), + } } fn wrong_kind_name_err( @@ -164,20 +161,14 @@ fn wrong_kind_name_err( } } -fn union_field_err(r: Result) -> Option<(String, String)> { +fn validation_err(r: Result) -> witx::ValidationError { match r { - Err(witx::WitxError::Validation(witx::ValidationError::InvalidUnionField { - name, - reason, - .. - })) => Some((name, reason)), + Err(witx::WitxError::Validation(e)) => e, Err(e) => { - eprintln!("expected InvalidUnionField ValidationError, got: {:?}", e); - None + panic!("expected ValidationError, got: {:?}", e) } Ok(_) => { - eprintln!("expected InvalidUnionField ValidationError, got: Ok(witx::Document)"); - None + panic!("expected ValidationError, got: Ok(witx::Document)") } } } From da5afb26e8c220f4edaa33bf1bd81ea2f85d3289 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 14:24:38 -0800 Subject: [PATCH 0850/1772] Embed type-hint declarations in AST payloads Instead of having a separate variant for `Char8` and `Usize` instead store boolean flags on `U8` and `U32` whether they're intended for these language-specific purposes. This additionally changes to require `@witx` when parsing `char8` to ensure usage is flagged as witx-specific. --- proposals/clocks/phases/ephemeral/docs.md | 22 +++++++------- .../ephemeral/witx/wasi_ephemeral_args.witx | 4 +-- .../witx/wasi_ephemeral_environ.witx | 4 +-- .../ephemeral/witx/wasi_ephemeral_fd.witx | 2 +- .../ephemeral/witx/wasi_ephemeral_path.witx | 2 +- proposals/clocks/tools/witx/src/ast.rs | 29 +++++++++++++++---- proposals/clocks/tools/witx/src/coretypes.rs | 8 ++--- proposals/clocks/tools/witx/src/docs/ast.rs | 6 ++-- proposals/clocks/tools/witx/src/layout.rs | 16 ++++------ proposals/clocks/tools/witx/src/parser.rs | 23 +++++++++------ proposals/clocks/tools/witx/src/render.rs | 14 ++++++--- .../clocks/tools/witx/src/representation.rs | 10 ++++--- proposals/clocks/tools/witx/src/toplevel.rs | 12 ++++++-- proposals/clocks/tools/witx/src/validate.rs | 8 ++--- .../clocks/tools/witx/tests/multimodule.rs | 7 ++++- proposals/clocks/tools/witx/tests/union.rs | 2 +- 16 files changed, 102 insertions(+), 67 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 7ea6969f8..54568c75d 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -1,5 +1,5 @@ # Types -## `size`: `usize` +## `size`: `u32` An array size. Note: This is similar to `size_t` in POSIX. @@ -1097,14 +1097,14 @@ When type is [`preopentype::dir`](#preopentype.dir): --- -#### `get(argv: Pointer>, argv_buf: Pointer) -> errno` +#### `get(argv: Pointer>, argv_buf: Pointer) -> errno` Read command-line argument data. The size of the array should match that returned by [`sizes_get`](#sizes_get) ##### Params -- `argv`: `Pointer>` +- `argv`: `Pointer>` -- `argv_buf`: `Pointer` +- `argv_buf`: `Pointer` ##### Results - `error`: [`errno`](#errno) @@ -1175,14 +1175,14 @@ The time value of the clock. --- -#### `get(environ: Pointer>, environ_buf: Pointer) -> errno` +#### `get(environ: Pointer>, environ_buf: Pointer) -> errno` Read environment variable data. The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). ##### Params -- `environ`: `Pointer>` +- `environ`: `Pointer>` -- `environ_buf`: `Pointer` +- `environ_buf`: `Pointer` ##### Results - `error`: [`errno`](#errno) @@ -1443,13 +1443,13 @@ The buffer where the description is stored. --- -#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` Return a description of the given preopened file descriptor. ##### Params - `fd`: [`fd`](#fd) -- `path`: `Pointer` +- `path`: `Pointer` A buffer into which to write the preopened directory name. - `path_len`: [`size`](#size) @@ -1806,7 +1806,7 @@ The file descriptor of the file that has been opened. --- -#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` Read the contents of a symbolic link. Note: This is similar to `readlinkat` in POSIX. @@ -1816,7 +1816,7 @@ Note: This is similar to `readlinkat` in POSIX. - `path`: `string` The path of the symbolic link from which to read. -- `buf`: `Pointer` +- `buf`: `Pointer` The buffer to which to write the contents of the symbolic link. - `buf_len`: [`size`](#size) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx index 485fafd27..803605fee 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -12,8 +12,8 @@ ;;; Read command-line argument data. ;;; The size of the array should match that returned by `sizes_get` (@interface func (export "get") - (param $argv (@witx pointer (@witx pointer char8))) - (param $argv_buf (@witx pointer char8)) + (param $argv (@witx pointer (@witx pointer (@witx char8)))) + (param $argv_buf (@witx pointer (@witx char8))) (result $error $errno) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx index ab564076d..6357fe602 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -12,8 +12,8 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `sizes_get`. (@interface func (export "get") - (param $environ (@witx pointer (@witx pointer char8))) - (param $environ_buf (@witx pointer char8)) + (param $environ (@witx pointer (@witx pointer (@witx char8)))) + (param $environ_buf (@witx pointer (@witx char8))) (result $error $errno) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx index 821d3e707..8192c9b7f 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -151,7 +151,7 @@ (@interface func (export "prestat_dir_name") (param $fd $fd) ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer char8)) + (param $path (@witx pointer (@witx char8))) (param $path_len $size) (result $error $errno) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx index 971a6fc9f..5b3e17e88 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -131,7 +131,7 @@ ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer char8)) + (param $buf (@witx pointer (@witx char8))) (param $buf_len $size) (result $error $errno) ;;; The number of bytes placed in the buffer. diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 5ba525520..a92c7895f 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -211,12 +211,27 @@ impl Type { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { - Char8, Char, - USize, - U8, + U8 { + /// Indicates whether this type is intended to represent the `char` + /// type in the C language. The C `char` type is often unsigned, but + /// it's language-specific. At an interface-types level this is an + /// unsigned byte but binding generators may wish to bind this as the + /// language-specific representation for a C character instead. + lang_c_char: bool, + }, U16, - U32, + U32 { + /// Indicates that this 32-bit value should actually be considered a + /// pointer-like value in language bindings. At the interface types + /// layer this is always a 32-bit unsigned value, but binding + /// generators may wish to instead bind this as the equivalent of C's + /// `size_t` for convenience with other APIs. + /// + /// This allows witx authors to communicate the intent that the + /// argument or return-value is pointer-like. + lang_ptr_size: bool, + }, U64, S8, S16, @@ -237,9 +252,11 @@ pub enum IntRepr { impl IntRepr { pub fn to_builtin(&self) -> BuiltinType { match self { - IntRepr::U8 => BuiltinType::U8, + IntRepr::U8 => BuiltinType::U8 { lang_c_char: false }, IntRepr::U16 => BuiltinType::U16, - IntRepr::U32 => BuiltinType::U32, + IntRepr::U32 => BuiltinType::U32 { + lang_ptr_size: false, + }, IntRepr::U64 => BuiltinType::U64, } } diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs index 35fea801e..826990369 100644 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ b/proposals/clocks/tools/witx/src/coretypes.rs @@ -35,15 +35,13 @@ impl Type { pub fn passed_by(&self) -> TypePassedBy { match self { Type::Builtin(b) => match b { - BuiltinType::U8 + BuiltinType::U8 { .. } | BuiltinType::U16 - | BuiltinType::U32 + | BuiltinType::U32 { .. } | BuiltinType::S8 | BuiltinType::S16 | BuiltinType::S32 - | BuiltinType::Char8 - | BuiltinType::Char - | BuiltinType::USize => TypePassedBy::Value(AtomType::I32), + | BuiltinType::Char => TypePassedBy::Value(AtomType::I32), BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index eb4d3e7cb..5e077e588 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -288,12 +288,10 @@ impl ToMarkdown for InterfaceFuncParam { impl BuiltinType { pub fn type_name(&self) -> &'static str { match self { - BuiltinType::Char8 => "char8", BuiltinType::Char => "char", - BuiltinType::USize => "usize", - BuiltinType::U8 => "u8", + BuiltinType::U8 { .. } => "u8", BuiltinType::U16 => "u16", - BuiltinType::U32 => "u32", + BuiltinType::U32 { .. } => "u32", BuiltinType::U64 => "u64", BuiltinType::S8 => "s8", BuiltinType::S16 => "s16", diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index 6b77d8a32..2bcd1042a 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -68,7 +68,7 @@ impl Type { Type::Variant(s) => s.mem_size_align(), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length - Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), + Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::S32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), } } @@ -179,22 +179,18 @@ mod test { impl Layout for HandleDatatype { fn mem_size_align(&self) -> SizeAlign { - BuiltinType::U32.mem_size_align() + BuiltinType::S32.mem_size_align() } } impl Layout for BuiltinType { fn mem_size_align(&self) -> SizeAlign { match self { - BuiltinType::U8 | BuiltinType::S8 | BuiltinType::Char8 => { - SizeAlign { size: 1, align: 1 } - } + BuiltinType::U8 { .. } | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, - BuiltinType::Char - | BuiltinType::USize - | BuiltinType::U32 - | BuiltinType::S32 - | BuiltinType::F32 => SizeAlign { size: 4, align: 4 }, + BuiltinType::Char | BuiltinType::U32 { .. } | BuiltinType::S32 | BuiltinType::F32 => { + SizeAlign { size: 4, align: 4 } + } BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { SizeAlign { size: 8, align: 8 } } diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index ee8bf081e..325eb1d35 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -60,21 +60,20 @@ mod annotation { impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::Char8) - } else if l.peek::() { + if l.peek::() { parser.parse::()?; Ok(BuiltinType::Char) } else if l.peek::() { parser.parse::()?; - Ok(BuiltinType::U8) + Ok(BuiltinType::U8 { lang_c_char: false }) } else if l.peek::() { parser.parse::()?; Ok(BuiltinType::U16) } else if l.peek::() { parser.parse::()?; - Ok(BuiltinType::U32) + Ok(BuiltinType::U32 { + lang_ptr_size: false, + }) } else if l.peek::() { parser.parse::()?; Ok(BuiltinType::U64) @@ -104,8 +103,7 @@ impl Parse<'_> for BuiltinType { impl wast::parser::Peek for BuiltinType { fn peek(cursor: wast::parser::Cursor<'_>) -> bool { - ::peek(cursor) - || ::peek(cursor) + ::peek(cursor) || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) @@ -331,7 +329,14 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) } else if l.peek::() { parser.parse::()?; - Ok(TypedefSyntax::Builtin(BuiltinType::USize)) + Ok(TypedefSyntax::Builtin(BuiltinType::U32 { + lang_ptr_size: true, + })) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::Builtin(BuiltinType::U8 { + lang_c_char: true, + })) } else { Err(l.error()) } diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index 60df3d6a2..ad551ae9b 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -77,12 +77,18 @@ impl Id { impl BuiltinType { pub fn to_sexpr(&self) -> SExpr { match self { - BuiltinType::Char8 => SExpr::word("char8"), BuiltinType::Char => SExpr::word("char"), - BuiltinType::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), - BuiltinType::U8 => SExpr::word("u8"), + BuiltinType::U8 { lang_c_char: true } => { + SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("char8")]) + } + BuiltinType::U8 { lang_c_char: false } => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), - BuiltinType::U32 => SExpr::word("u32"), + BuiltinType::U32 { + lang_ptr_size: false, + } => SExpr::word("u32"), + BuiltinType::U32 { + lang_ptr_size: true, + } => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), BuiltinType::U64 => SExpr::word("u64"), BuiltinType::S8 => SExpr::word("s8"), BuiltinType::S16 => SExpr::word("s16"), diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs index 6c36e71e7..99f73f5b6 100644 --- a/proposals/clocks/tools/witx/src/representation.rs +++ b/proposals/clocks/tools/witx/src/representation.rs @@ -30,15 +30,17 @@ impl Representable for BuiltinType { return RepEquality::Eq; } match self { - BuiltinType::U8 => match by { - BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 => RepEquality::Superset, + BuiltinType::U8 { .. } => match by { + BuiltinType::U64 | BuiltinType::U32 { .. } | BuiltinType::U16 => { + RepEquality::Superset + } _ => RepEquality::NotEq, }, BuiltinType::U16 => match by { - BuiltinType::U64 | BuiltinType::U32 => RepEquality::Superset, + BuiltinType::U64 | BuiltinType::U32 { .. } => RepEquality::Superset, _ => RepEquality::NotEq, }, - BuiltinType::U32 => match by { + BuiltinType::U32 { .. } => match by { BuiltinType::U64 => RepEquality::Superset, _ => RepEquality::NotEq, }, diff --git a/proposals/clocks/tools/witx/src/toplevel.rs b/proposals/clocks/tools/witx/src/toplevel.rs index 52ef3daa3..993fc8cc4 100644 --- a/proposals/clocks/tools/witx/src/toplevel.rs +++ b/proposals/clocks/tools/witx/src/toplevel.rs @@ -110,7 +110,12 @@ mod test { assert_eq!(*b_float.type_(), Type::Builtin(BuiltinType::F64)); let c_int = doc.typename(&Id::new("c_int")).unwrap(); - assert_eq!(*c_int.type_(), Type::Builtin(BuiltinType::U32)); + assert_eq!( + *c_int.type_(), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: false + }) + ); } #[test] @@ -127,7 +132,10 @@ mod test { .expect("parse"); let d_char = doc.typename(&Id::new("d_char")).unwrap(); - assert_eq!(*d_char.type_(), Type::Builtin(BuiltinType::U8)); + assert_eq!( + *d_char.type_(), + Type::Builtin(BuiltinType::U8 { lang_c_char: false }) + ); } #[test] diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index 7abeef733..88ae10147 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -493,9 +493,9 @@ impl DocValidationScope<'_> { } return Ok((e.tag_repr, Some(names))); } - Type::Builtin(BuiltinType::U8) => return Ok((IntRepr::U8, None)), + Type::Builtin(BuiltinType::U8 { .. }) => return Ok((IntRepr::U8, None)), Type::Builtin(BuiltinType::U16) => return Ok((IntRepr::U16, None)), - Type::Builtin(BuiltinType::U32) => return Ok((IntRepr::U32, None)), + Type::Builtin(BuiltinType::U32 { .. }) => return Ok((IntRepr::U32, None)), Type::Builtin(BuiltinType::U64) => return Ok((IntRepr::U64, None)), _ => {} } @@ -522,9 +522,9 @@ impl DocValidationScope<'_> { span: wast::Span, ) -> Result { match type_ { - BuiltinType::U8 => Ok(IntRepr::U8), + BuiltinType::U8 { .. } => Ok(IntRepr::U8), BuiltinType::U16 => Ok(IntRepr::U16), - BuiltinType::U32 => Ok(IntRepr::U32), + BuiltinType::U32 { .. } => Ok(IntRepr::U32), BuiltinType::U64 => Ok(IntRepr::U64), _ => Err(ValidationError::InvalidRepr { repr: type_.clone(), diff --git a/proposals/clocks/tools/witx/tests/multimodule.rs b/proposals/clocks/tools/witx/tests/multimodule.rs index a8e35609f..a6c773363 100644 --- a/proposals/clocks/tools/witx/tests/multimodule.rs +++ b/proposals/clocks/tools/witx/tests/multimodule.rs @@ -13,7 +13,12 @@ fn validate_multimodule() { // Check that the `a` both modules use is what we expect: let type_a = doc.typename(&Id::new("a")).expect("type a exists"); - assert_eq!(*type_a.type_(), Type::Builtin(BuiltinType::U32)); + assert_eq!( + *type_a.type_(), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: false + }) + ); // `b` is a struct with a single member of type `a` let type_b = doc.typename(&Id::new("b")).expect("type b exists"); diff --git a/proposals/clocks/tools/witx/tests/union.rs b/proposals/clocks/tools/witx/tests/union.rs index 6cfa43e39..31ade263a 100644 --- a/proposals/clocks/tools/witx/tests/union.rs +++ b/proposals/clocks/tools/witx/tests/union.rs @@ -80,7 +80,7 @@ fn many_variant_unions() { (case $i f32) (case $j f64) (case $k (@witx usize)) - (case $l char8) + (case $l (@witx char8)) (case $m) ) )", From ba8776336346ada02032a22a2c4790493cb47602 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 14:24:38 -0800 Subject: [PATCH 0851/1772] Embed type-hint declarations in AST payloads Instead of having a separate variant for `Char8` and `Usize` instead store boolean flags on `U8` and `U32` whether they're intended for these language-specific purposes. This additionally changes to require `@witx` when parsing `char8` to ensure usage is flagged as witx-specific. --- proposals/random/phases/ephemeral/docs.md | 22 +++++++------- .../ephemeral/witx/wasi_ephemeral_args.witx | 4 +-- .../witx/wasi_ephemeral_environ.witx | 4 +-- .../ephemeral/witx/wasi_ephemeral_fd.witx | 2 +- .../ephemeral/witx/wasi_ephemeral_path.witx | 2 +- proposals/random/tools/witx/src/ast.rs | 29 +++++++++++++++---- proposals/random/tools/witx/src/coretypes.rs | 8 ++--- proposals/random/tools/witx/src/docs/ast.rs | 6 ++-- proposals/random/tools/witx/src/layout.rs | 16 ++++------ proposals/random/tools/witx/src/parser.rs | 23 +++++++++------ proposals/random/tools/witx/src/render.rs | 14 ++++++--- .../random/tools/witx/src/representation.rs | 10 ++++--- proposals/random/tools/witx/src/toplevel.rs | 12 ++++++-- proposals/random/tools/witx/src/validate.rs | 8 ++--- .../random/tools/witx/tests/multimodule.rs | 7 ++++- proposals/random/tools/witx/tests/union.rs | 2 +- 16 files changed, 102 insertions(+), 67 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 7ea6969f8..54568c75d 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -1,5 +1,5 @@ # Types -## `size`: `usize` +## `size`: `u32` An array size. Note: This is similar to `size_t` in POSIX. @@ -1097,14 +1097,14 @@ When type is [`preopentype::dir`](#preopentype.dir): --- -#### `get(argv: Pointer>, argv_buf: Pointer) -> errno` +#### `get(argv: Pointer>, argv_buf: Pointer) -> errno` Read command-line argument data. The size of the array should match that returned by [`sizes_get`](#sizes_get) ##### Params -- `argv`: `Pointer>` +- `argv`: `Pointer>` -- `argv_buf`: `Pointer` +- `argv_buf`: `Pointer` ##### Results - `error`: [`errno`](#errno) @@ -1175,14 +1175,14 @@ The time value of the clock. --- -#### `get(environ: Pointer>, environ_buf: Pointer) -> errno` +#### `get(environ: Pointer>, environ_buf: Pointer) -> errno` Read environment variable data. The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). ##### Params -- `environ`: `Pointer>` +- `environ`: `Pointer>` -- `environ_buf`: `Pointer` +- `environ_buf`: `Pointer` ##### Results - `error`: [`errno`](#errno) @@ -1443,13 +1443,13 @@ The buffer where the description is stored. --- -#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` Return a description of the given preopened file descriptor. ##### Params - `fd`: [`fd`](#fd) -- `path`: `Pointer` +- `path`: `Pointer` A buffer into which to write the preopened directory name. - `path_len`: [`size`](#size) @@ -1806,7 +1806,7 @@ The file descriptor of the file that has been opened. --- -#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` Read the contents of a symbolic link. Note: This is similar to `readlinkat` in POSIX. @@ -1816,7 +1816,7 @@ Note: This is similar to `readlinkat` in POSIX. - `path`: `string` The path of the symbolic link from which to read. -- `buf`: `Pointer` +- `buf`: `Pointer` The buffer to which to write the contents of the symbolic link. - `buf_len`: [`size`](#size) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx index 485fafd27..803605fee 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -12,8 +12,8 @@ ;;; Read command-line argument data. ;;; The size of the array should match that returned by `sizes_get` (@interface func (export "get") - (param $argv (@witx pointer (@witx pointer char8))) - (param $argv_buf (@witx pointer char8)) + (param $argv (@witx pointer (@witx pointer (@witx char8)))) + (param $argv_buf (@witx pointer (@witx char8))) (result $error $errno) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx index ab564076d..6357fe602 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -12,8 +12,8 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `sizes_get`. (@interface func (export "get") - (param $environ (@witx pointer (@witx pointer char8))) - (param $environ_buf (@witx pointer char8)) + (param $environ (@witx pointer (@witx pointer (@witx char8)))) + (param $environ_buf (@witx pointer (@witx char8))) (result $error $errno) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx index 821d3e707..8192c9b7f 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -151,7 +151,7 @@ (@interface func (export "prestat_dir_name") (param $fd $fd) ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer char8)) + (param $path (@witx pointer (@witx char8))) (param $path_len $size) (result $error $errno) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx index 971a6fc9f..5b3e17e88 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -131,7 +131,7 @@ ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer char8)) + (param $buf (@witx pointer (@witx char8))) (param $buf_len $size) (result $error $errno) ;;; The number of bytes placed in the buffer. diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 5ba525520..a92c7895f 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -211,12 +211,27 @@ impl Type { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { - Char8, Char, - USize, - U8, + U8 { + /// Indicates whether this type is intended to represent the `char` + /// type in the C language. The C `char` type is often unsigned, but + /// it's language-specific. At an interface-types level this is an + /// unsigned byte but binding generators may wish to bind this as the + /// language-specific representation for a C character instead. + lang_c_char: bool, + }, U16, - U32, + U32 { + /// Indicates that this 32-bit value should actually be considered a + /// pointer-like value in language bindings. At the interface types + /// layer this is always a 32-bit unsigned value, but binding + /// generators may wish to instead bind this as the equivalent of C's + /// `size_t` for convenience with other APIs. + /// + /// This allows witx authors to communicate the intent that the + /// argument or return-value is pointer-like. + lang_ptr_size: bool, + }, U64, S8, S16, @@ -237,9 +252,11 @@ pub enum IntRepr { impl IntRepr { pub fn to_builtin(&self) -> BuiltinType { match self { - IntRepr::U8 => BuiltinType::U8, + IntRepr::U8 => BuiltinType::U8 { lang_c_char: false }, IntRepr::U16 => BuiltinType::U16, - IntRepr::U32 => BuiltinType::U32, + IntRepr::U32 => BuiltinType::U32 { + lang_ptr_size: false, + }, IntRepr::U64 => BuiltinType::U64, } } diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs index 35fea801e..826990369 100644 --- a/proposals/random/tools/witx/src/coretypes.rs +++ b/proposals/random/tools/witx/src/coretypes.rs @@ -35,15 +35,13 @@ impl Type { pub fn passed_by(&self) -> TypePassedBy { match self { Type::Builtin(b) => match b { - BuiltinType::U8 + BuiltinType::U8 { .. } | BuiltinType::U16 - | BuiltinType::U32 + | BuiltinType::U32 { .. } | BuiltinType::S8 | BuiltinType::S16 | BuiltinType::S32 - | BuiltinType::Char8 - | BuiltinType::Char - | BuiltinType::USize => TypePassedBy::Value(AtomType::I32), + | BuiltinType::Char => TypePassedBy::Value(AtomType::I32), BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index eb4d3e7cb..5e077e588 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -288,12 +288,10 @@ impl ToMarkdown for InterfaceFuncParam { impl BuiltinType { pub fn type_name(&self) -> &'static str { match self { - BuiltinType::Char8 => "char8", BuiltinType::Char => "char", - BuiltinType::USize => "usize", - BuiltinType::U8 => "u8", + BuiltinType::U8 { .. } => "u8", BuiltinType::U16 => "u16", - BuiltinType::U32 => "u32", + BuiltinType::U32 { .. } => "u32", BuiltinType::U64 => "u64", BuiltinType::S8 => "s8", BuiltinType::S16 => "s16", diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index 6b77d8a32..2bcd1042a 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -68,7 +68,7 @@ impl Type { Type::Variant(s) => s.mem_size_align(), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length - Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), + Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::S32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), } } @@ -179,22 +179,18 @@ mod test { impl Layout for HandleDatatype { fn mem_size_align(&self) -> SizeAlign { - BuiltinType::U32.mem_size_align() + BuiltinType::S32.mem_size_align() } } impl Layout for BuiltinType { fn mem_size_align(&self) -> SizeAlign { match self { - BuiltinType::U8 | BuiltinType::S8 | BuiltinType::Char8 => { - SizeAlign { size: 1, align: 1 } - } + BuiltinType::U8 { .. } | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, - BuiltinType::Char - | BuiltinType::USize - | BuiltinType::U32 - | BuiltinType::S32 - | BuiltinType::F32 => SizeAlign { size: 4, align: 4 }, + BuiltinType::Char | BuiltinType::U32 { .. } | BuiltinType::S32 | BuiltinType::F32 => { + SizeAlign { size: 4, align: 4 } + } BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { SizeAlign { size: 8, align: 8 } } diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index ee8bf081e..325eb1d35 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -60,21 +60,20 @@ mod annotation { impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::Char8) - } else if l.peek::() { + if l.peek::() { parser.parse::()?; Ok(BuiltinType::Char) } else if l.peek::() { parser.parse::()?; - Ok(BuiltinType::U8) + Ok(BuiltinType::U8 { lang_c_char: false }) } else if l.peek::() { parser.parse::()?; Ok(BuiltinType::U16) } else if l.peek::() { parser.parse::()?; - Ok(BuiltinType::U32) + Ok(BuiltinType::U32 { + lang_ptr_size: false, + }) } else if l.peek::() { parser.parse::()?; Ok(BuiltinType::U64) @@ -104,8 +103,7 @@ impl Parse<'_> for BuiltinType { impl wast::parser::Peek for BuiltinType { fn peek(cursor: wast::parser::Cursor<'_>) -> bool { - ::peek(cursor) - || ::peek(cursor) + ::peek(cursor) || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) @@ -331,7 +329,14 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) } else if l.peek::() { parser.parse::()?; - Ok(TypedefSyntax::Builtin(BuiltinType::USize)) + Ok(TypedefSyntax::Builtin(BuiltinType::U32 { + lang_ptr_size: true, + })) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::Builtin(BuiltinType::U8 { + lang_c_char: true, + })) } else { Err(l.error()) } diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index 60df3d6a2..ad551ae9b 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -77,12 +77,18 @@ impl Id { impl BuiltinType { pub fn to_sexpr(&self) -> SExpr { match self { - BuiltinType::Char8 => SExpr::word("char8"), BuiltinType::Char => SExpr::word("char"), - BuiltinType::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), - BuiltinType::U8 => SExpr::word("u8"), + BuiltinType::U8 { lang_c_char: true } => { + SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("char8")]) + } + BuiltinType::U8 { lang_c_char: false } => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), - BuiltinType::U32 => SExpr::word("u32"), + BuiltinType::U32 { + lang_ptr_size: false, + } => SExpr::word("u32"), + BuiltinType::U32 { + lang_ptr_size: true, + } => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), BuiltinType::U64 => SExpr::word("u64"), BuiltinType::S8 => SExpr::word("s8"), BuiltinType::S16 => SExpr::word("s16"), diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs index 6c36e71e7..99f73f5b6 100644 --- a/proposals/random/tools/witx/src/representation.rs +++ b/proposals/random/tools/witx/src/representation.rs @@ -30,15 +30,17 @@ impl Representable for BuiltinType { return RepEquality::Eq; } match self { - BuiltinType::U8 => match by { - BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 => RepEquality::Superset, + BuiltinType::U8 { .. } => match by { + BuiltinType::U64 | BuiltinType::U32 { .. } | BuiltinType::U16 => { + RepEquality::Superset + } _ => RepEquality::NotEq, }, BuiltinType::U16 => match by { - BuiltinType::U64 | BuiltinType::U32 => RepEquality::Superset, + BuiltinType::U64 | BuiltinType::U32 { .. } => RepEquality::Superset, _ => RepEquality::NotEq, }, - BuiltinType::U32 => match by { + BuiltinType::U32 { .. } => match by { BuiltinType::U64 => RepEquality::Superset, _ => RepEquality::NotEq, }, diff --git a/proposals/random/tools/witx/src/toplevel.rs b/proposals/random/tools/witx/src/toplevel.rs index 52ef3daa3..993fc8cc4 100644 --- a/proposals/random/tools/witx/src/toplevel.rs +++ b/proposals/random/tools/witx/src/toplevel.rs @@ -110,7 +110,12 @@ mod test { assert_eq!(*b_float.type_(), Type::Builtin(BuiltinType::F64)); let c_int = doc.typename(&Id::new("c_int")).unwrap(); - assert_eq!(*c_int.type_(), Type::Builtin(BuiltinType::U32)); + assert_eq!( + *c_int.type_(), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: false + }) + ); } #[test] @@ -127,7 +132,10 @@ mod test { .expect("parse"); let d_char = doc.typename(&Id::new("d_char")).unwrap(); - assert_eq!(*d_char.type_(), Type::Builtin(BuiltinType::U8)); + assert_eq!( + *d_char.type_(), + Type::Builtin(BuiltinType::U8 { lang_c_char: false }) + ); } #[test] diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index 7abeef733..88ae10147 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -493,9 +493,9 @@ impl DocValidationScope<'_> { } return Ok((e.tag_repr, Some(names))); } - Type::Builtin(BuiltinType::U8) => return Ok((IntRepr::U8, None)), + Type::Builtin(BuiltinType::U8 { .. }) => return Ok((IntRepr::U8, None)), Type::Builtin(BuiltinType::U16) => return Ok((IntRepr::U16, None)), - Type::Builtin(BuiltinType::U32) => return Ok((IntRepr::U32, None)), + Type::Builtin(BuiltinType::U32 { .. }) => return Ok((IntRepr::U32, None)), Type::Builtin(BuiltinType::U64) => return Ok((IntRepr::U64, None)), _ => {} } @@ -522,9 +522,9 @@ impl DocValidationScope<'_> { span: wast::Span, ) -> Result { match type_ { - BuiltinType::U8 => Ok(IntRepr::U8), + BuiltinType::U8 { .. } => Ok(IntRepr::U8), BuiltinType::U16 => Ok(IntRepr::U16), - BuiltinType::U32 => Ok(IntRepr::U32), + BuiltinType::U32 { .. } => Ok(IntRepr::U32), BuiltinType::U64 => Ok(IntRepr::U64), _ => Err(ValidationError::InvalidRepr { repr: type_.clone(), diff --git a/proposals/random/tools/witx/tests/multimodule.rs b/proposals/random/tools/witx/tests/multimodule.rs index a8e35609f..a6c773363 100644 --- a/proposals/random/tools/witx/tests/multimodule.rs +++ b/proposals/random/tools/witx/tests/multimodule.rs @@ -13,7 +13,12 @@ fn validate_multimodule() { // Check that the `a` both modules use is what we expect: let type_a = doc.typename(&Id::new("a")).expect("type a exists"); - assert_eq!(*type_a.type_(), Type::Builtin(BuiltinType::U32)); + assert_eq!( + *type_a.type_(), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: false + }) + ); // `b` is a struct with a single member of type `a` let type_b = doc.typename(&Id::new("b")).expect("type b exists"); diff --git a/proposals/random/tools/witx/tests/union.rs b/proposals/random/tools/witx/tests/union.rs index 6cfa43e39..31ade263a 100644 --- a/proposals/random/tools/witx/tests/union.rs +++ b/proposals/random/tools/witx/tests/union.rs @@ -80,7 +80,7 @@ fn many_variant_unions() { (case $i f32) (case $j f64) (case $k (@witx usize)) - (case $l char8) + (case $l (@witx char8)) (case $m) ) )", From 5ec7f16e945d30f4bac60f96e97e9173f8f7c560 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Feb 2021 14:24:38 -0800 Subject: [PATCH 0852/1772] Embed type-hint declarations in AST payloads Instead of having a separate variant for `Char8` and `Usize` instead store boolean flags on `U8` and `U32` whether they're intended for these language-specific purposes. This additionally changes to require `@witx` when parsing `char8` to ensure usage is flagged as witx-specific. --- proposals/filesystem/phases/ephemeral/docs.md | 22 +++++++------- .../ephemeral/witx/wasi_ephemeral_args.witx | 4 +-- .../witx/wasi_ephemeral_environ.witx | 4 +-- .../ephemeral/witx/wasi_ephemeral_fd.witx | 2 +- .../ephemeral/witx/wasi_ephemeral_path.witx | 2 +- proposals/filesystem/tools/witx/src/ast.rs | 29 +++++++++++++++---- .../filesystem/tools/witx/src/coretypes.rs | 8 ++--- .../filesystem/tools/witx/src/docs/ast.rs | 6 ++-- proposals/filesystem/tools/witx/src/layout.rs | 16 ++++------ proposals/filesystem/tools/witx/src/parser.rs | 23 +++++++++------ proposals/filesystem/tools/witx/src/render.rs | 14 ++++++--- .../tools/witx/src/representation.rs | 10 ++++--- .../filesystem/tools/witx/src/toplevel.rs | 12 ++++++-- .../filesystem/tools/witx/src/validate.rs | 8 ++--- .../tools/witx/tests/multimodule.rs | 7 ++++- .../filesystem/tools/witx/tests/union.rs | 2 +- 16 files changed, 102 insertions(+), 67 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 7ea6969f8..54568c75d 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -1,5 +1,5 @@ # Types -## `size`: `usize` +## `size`: `u32` An array size. Note: This is similar to `size_t` in POSIX. @@ -1097,14 +1097,14 @@ When type is [`preopentype::dir`](#preopentype.dir): --- -#### `get(argv: Pointer>, argv_buf: Pointer) -> errno` +#### `get(argv: Pointer>, argv_buf: Pointer) -> errno` Read command-line argument data. The size of the array should match that returned by [`sizes_get`](#sizes_get) ##### Params -- `argv`: `Pointer>` +- `argv`: `Pointer>` -- `argv_buf`: `Pointer` +- `argv_buf`: `Pointer` ##### Results - `error`: [`errno`](#errno) @@ -1175,14 +1175,14 @@ The time value of the clock. --- -#### `get(environ: Pointer>, environ_buf: Pointer) -> errno` +#### `get(environ: Pointer>, environ_buf: Pointer) -> errno` Read environment variable data. The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). ##### Params -- `environ`: `Pointer>` +- `environ`: `Pointer>` -- `environ_buf`: `Pointer` +- `environ_buf`: `Pointer` ##### Results - `error`: [`errno`](#errno) @@ -1443,13 +1443,13 @@ The buffer where the description is stored. --- -#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` Return a description of the given preopened file descriptor. ##### Params - `fd`: [`fd`](#fd) -- `path`: `Pointer` +- `path`: `Pointer` A buffer into which to write the preopened directory name. - `path_len`: [`size`](#size) @@ -1806,7 +1806,7 @@ The file descriptor of the file that has been opened. --- -#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` Read the contents of a symbolic link. Note: This is similar to `readlinkat` in POSIX. @@ -1816,7 +1816,7 @@ Note: This is similar to `readlinkat` in POSIX. - `path`: `string` The path of the symbolic link from which to read. -- `buf`: `Pointer` +- `buf`: `Pointer` The buffer to which to write the contents of the symbolic link. - `buf_len`: [`size`](#size) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx index 485fafd27..803605fee 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -12,8 +12,8 @@ ;;; Read command-line argument data. ;;; The size of the array should match that returned by `sizes_get` (@interface func (export "get") - (param $argv (@witx pointer (@witx pointer char8))) - (param $argv_buf (@witx pointer char8)) + (param $argv (@witx pointer (@witx pointer (@witx char8)))) + (param $argv_buf (@witx pointer (@witx char8))) (result $error $errno) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx index ab564076d..6357fe602 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -12,8 +12,8 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `sizes_get`. (@interface func (export "get") - (param $environ (@witx pointer (@witx pointer char8))) - (param $environ_buf (@witx pointer char8)) + (param $environ (@witx pointer (@witx pointer (@witx char8)))) + (param $environ_buf (@witx pointer (@witx char8))) (result $error $errno) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx index 821d3e707..8192c9b7f 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -151,7 +151,7 @@ (@interface func (export "prestat_dir_name") (param $fd $fd) ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer char8)) + (param $path (@witx pointer (@witx char8))) (param $path_len $size) (result $error $errno) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx index 971a6fc9f..5b3e17e88 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -131,7 +131,7 @@ ;;; The path of the symbolic link from which to read. (param $path string) ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer char8)) + (param $buf (@witx pointer (@witx char8))) (param $buf_len $size) (result $error $errno) ;;; The number of bytes placed in the buffer. diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 5ba525520..a92c7895f 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -211,12 +211,27 @@ impl Type { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { - Char8, Char, - USize, - U8, + U8 { + /// Indicates whether this type is intended to represent the `char` + /// type in the C language. The C `char` type is often unsigned, but + /// it's language-specific. At an interface-types level this is an + /// unsigned byte but binding generators may wish to bind this as the + /// language-specific representation for a C character instead. + lang_c_char: bool, + }, U16, - U32, + U32 { + /// Indicates that this 32-bit value should actually be considered a + /// pointer-like value in language bindings. At the interface types + /// layer this is always a 32-bit unsigned value, but binding + /// generators may wish to instead bind this as the equivalent of C's + /// `size_t` for convenience with other APIs. + /// + /// This allows witx authors to communicate the intent that the + /// argument or return-value is pointer-like. + lang_ptr_size: bool, + }, U64, S8, S16, @@ -237,9 +252,11 @@ pub enum IntRepr { impl IntRepr { pub fn to_builtin(&self) -> BuiltinType { match self { - IntRepr::U8 => BuiltinType::U8, + IntRepr::U8 => BuiltinType::U8 { lang_c_char: false }, IntRepr::U16 => BuiltinType::U16, - IntRepr::U32 => BuiltinType::U32, + IntRepr::U32 => BuiltinType::U32 { + lang_ptr_size: false, + }, IntRepr::U64 => BuiltinType::U64, } } diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs index 35fea801e..826990369 100644 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ b/proposals/filesystem/tools/witx/src/coretypes.rs @@ -35,15 +35,13 @@ impl Type { pub fn passed_by(&self) -> TypePassedBy { match self { Type::Builtin(b) => match b { - BuiltinType::U8 + BuiltinType::U8 { .. } | BuiltinType::U16 - | BuiltinType::U32 + | BuiltinType::U32 { .. } | BuiltinType::S8 | BuiltinType::S16 | BuiltinType::S32 - | BuiltinType::Char8 - | BuiltinType::Char - | BuiltinType::USize => TypePassedBy::Value(AtomType::I32), + | BuiltinType::Char => TypePassedBy::Value(AtomType::I32), BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index eb4d3e7cb..5e077e588 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -288,12 +288,10 @@ impl ToMarkdown for InterfaceFuncParam { impl BuiltinType { pub fn type_name(&self) -> &'static str { match self { - BuiltinType::Char8 => "char8", BuiltinType::Char => "char", - BuiltinType::USize => "usize", - BuiltinType::U8 => "u8", + BuiltinType::U8 { .. } => "u8", BuiltinType::U16 => "u16", - BuiltinType::U32 => "u32", + BuiltinType::U32 { .. } => "u32", BuiltinType::U64 => "u64", BuiltinType::S8 => "s8", BuiltinType::S16 => "s16", diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index 6b77d8a32..2bcd1042a 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -68,7 +68,7 @@ impl Type { Type::Variant(s) => s.mem_size_align(), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length - Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::U32.mem_size_align(), + Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::S32.mem_size_align(), Type::Builtin(b) => b.mem_size_align(), } } @@ -179,22 +179,18 @@ mod test { impl Layout for HandleDatatype { fn mem_size_align(&self) -> SizeAlign { - BuiltinType::U32.mem_size_align() + BuiltinType::S32.mem_size_align() } } impl Layout for BuiltinType { fn mem_size_align(&self) -> SizeAlign { match self { - BuiltinType::U8 | BuiltinType::S8 | BuiltinType::Char8 => { - SizeAlign { size: 1, align: 1 } - } + BuiltinType::U8 { .. } | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, - BuiltinType::Char - | BuiltinType::USize - | BuiltinType::U32 - | BuiltinType::S32 - | BuiltinType::F32 => SizeAlign { size: 4, align: 4 }, + BuiltinType::Char | BuiltinType::U32 { .. } | BuiltinType::S32 | BuiltinType::F32 => { + SizeAlign { size: 4, align: 4 } + } BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { SizeAlign { size: 8, align: 8 } } diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index ee8bf081e..325eb1d35 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -60,21 +60,20 @@ mod annotation { impl Parse<'_> for BuiltinType { fn parse(parser: Parser<'_>) -> Result { let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::Char8) - } else if l.peek::() { + if l.peek::() { parser.parse::()?; Ok(BuiltinType::Char) } else if l.peek::() { parser.parse::()?; - Ok(BuiltinType::U8) + Ok(BuiltinType::U8 { lang_c_char: false }) } else if l.peek::() { parser.parse::()?; Ok(BuiltinType::U16) } else if l.peek::() { parser.parse::()?; - Ok(BuiltinType::U32) + Ok(BuiltinType::U32 { + lang_ptr_size: false, + }) } else if l.peek::() { parser.parse::()?; Ok(BuiltinType::U64) @@ -104,8 +103,7 @@ impl Parse<'_> for BuiltinType { impl wast::parser::Peek for BuiltinType { fn peek(cursor: wast::parser::Cursor<'_>) -> bool { - ::peek(cursor) - || ::peek(cursor) + ::peek(cursor) || ::peek(cursor) || ::peek(cursor) || ::peek(cursor) @@ -331,7 +329,14 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) } else if l.peek::() { parser.parse::()?; - Ok(TypedefSyntax::Builtin(BuiltinType::USize)) + Ok(TypedefSyntax::Builtin(BuiltinType::U32 { + lang_ptr_size: true, + })) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::Builtin(BuiltinType::U8 { + lang_c_char: true, + })) } else { Err(l.error()) } diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index 60df3d6a2..ad551ae9b 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -77,12 +77,18 @@ impl Id { impl BuiltinType { pub fn to_sexpr(&self) -> SExpr { match self { - BuiltinType::Char8 => SExpr::word("char8"), BuiltinType::Char => SExpr::word("char"), - BuiltinType::USize => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), - BuiltinType::U8 => SExpr::word("u8"), + BuiltinType::U8 { lang_c_char: true } => { + SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("char8")]) + } + BuiltinType::U8 { lang_c_char: false } => SExpr::word("u8"), BuiltinType::U16 => SExpr::word("u16"), - BuiltinType::U32 => SExpr::word("u32"), + BuiltinType::U32 { + lang_ptr_size: false, + } => SExpr::word("u32"), + BuiltinType::U32 { + lang_ptr_size: true, + } => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), BuiltinType::U64 => SExpr::word("u64"), BuiltinType::S8 => SExpr::word("s8"), BuiltinType::S16 => SExpr::word("s16"), diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs index 6c36e71e7..99f73f5b6 100644 --- a/proposals/filesystem/tools/witx/src/representation.rs +++ b/proposals/filesystem/tools/witx/src/representation.rs @@ -30,15 +30,17 @@ impl Representable for BuiltinType { return RepEquality::Eq; } match self { - BuiltinType::U8 => match by { - BuiltinType::U64 | BuiltinType::U32 | BuiltinType::U16 => RepEquality::Superset, + BuiltinType::U8 { .. } => match by { + BuiltinType::U64 | BuiltinType::U32 { .. } | BuiltinType::U16 => { + RepEquality::Superset + } _ => RepEquality::NotEq, }, BuiltinType::U16 => match by { - BuiltinType::U64 | BuiltinType::U32 => RepEquality::Superset, + BuiltinType::U64 | BuiltinType::U32 { .. } => RepEquality::Superset, _ => RepEquality::NotEq, }, - BuiltinType::U32 => match by { + BuiltinType::U32 { .. } => match by { BuiltinType::U64 => RepEquality::Superset, _ => RepEquality::NotEq, }, diff --git a/proposals/filesystem/tools/witx/src/toplevel.rs b/proposals/filesystem/tools/witx/src/toplevel.rs index 52ef3daa3..993fc8cc4 100644 --- a/proposals/filesystem/tools/witx/src/toplevel.rs +++ b/proposals/filesystem/tools/witx/src/toplevel.rs @@ -110,7 +110,12 @@ mod test { assert_eq!(*b_float.type_(), Type::Builtin(BuiltinType::F64)); let c_int = doc.typename(&Id::new("c_int")).unwrap(); - assert_eq!(*c_int.type_(), Type::Builtin(BuiltinType::U32)); + assert_eq!( + *c_int.type_(), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: false + }) + ); } #[test] @@ -127,7 +132,10 @@ mod test { .expect("parse"); let d_char = doc.typename(&Id::new("d_char")).unwrap(); - assert_eq!(*d_char.type_(), Type::Builtin(BuiltinType::U8)); + assert_eq!( + *d_char.type_(), + Type::Builtin(BuiltinType::U8 { lang_c_char: false }) + ); } #[test] diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index 7abeef733..88ae10147 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -493,9 +493,9 @@ impl DocValidationScope<'_> { } return Ok((e.tag_repr, Some(names))); } - Type::Builtin(BuiltinType::U8) => return Ok((IntRepr::U8, None)), + Type::Builtin(BuiltinType::U8 { .. }) => return Ok((IntRepr::U8, None)), Type::Builtin(BuiltinType::U16) => return Ok((IntRepr::U16, None)), - Type::Builtin(BuiltinType::U32) => return Ok((IntRepr::U32, None)), + Type::Builtin(BuiltinType::U32 { .. }) => return Ok((IntRepr::U32, None)), Type::Builtin(BuiltinType::U64) => return Ok((IntRepr::U64, None)), _ => {} } @@ -522,9 +522,9 @@ impl DocValidationScope<'_> { span: wast::Span, ) -> Result { match type_ { - BuiltinType::U8 => Ok(IntRepr::U8), + BuiltinType::U8 { .. } => Ok(IntRepr::U8), BuiltinType::U16 => Ok(IntRepr::U16), - BuiltinType::U32 => Ok(IntRepr::U32), + BuiltinType::U32 { .. } => Ok(IntRepr::U32), BuiltinType::U64 => Ok(IntRepr::U64), _ => Err(ValidationError::InvalidRepr { repr: type_.clone(), diff --git a/proposals/filesystem/tools/witx/tests/multimodule.rs b/proposals/filesystem/tools/witx/tests/multimodule.rs index a8e35609f..a6c773363 100644 --- a/proposals/filesystem/tools/witx/tests/multimodule.rs +++ b/proposals/filesystem/tools/witx/tests/multimodule.rs @@ -13,7 +13,12 @@ fn validate_multimodule() { // Check that the `a` both modules use is what we expect: let type_a = doc.typename(&Id::new("a")).expect("type a exists"); - assert_eq!(*type_a.type_(), Type::Builtin(BuiltinType::U32)); + assert_eq!( + *type_a.type_(), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: false + }) + ); // `b` is a struct with a single member of type `a` let type_b = doc.typename(&Id::new("b")).expect("type b exists"); diff --git a/proposals/filesystem/tools/witx/tests/union.rs b/proposals/filesystem/tools/witx/tests/union.rs index 6cfa43e39..31ade263a 100644 --- a/proposals/filesystem/tools/witx/tests/union.rs +++ b/proposals/filesystem/tools/witx/tests/union.rs @@ -80,7 +80,7 @@ fn many_variant_unions() { (case $i f32) (case $j f64) (case $k (@witx usize)) - (case $l char8) + (case $l (@witx char8)) (case $m) ) )", From 3d9a983f49839f87cc5cf19e43cceed05087f2f8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 9 Feb 2021 07:33:48 -0800 Subject: [PATCH 0853/1772] Address some review feedback --- proposals/clocks/phases/ephemeral/docs.md | 2 +- proposals/clocks/tools/witx/src/ast.rs | 6 ++++++ proposals/clocks/tools/witx/src/docs/ast.rs | 7 ++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 54568c75d..2cd2d1361 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -1,5 +1,5 @@ # Types -## `size`: `u32` +## `size`: `usize` An array size. Note: This is similar to `size_t` in POSIX. diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index a92c7895f..7d34b5f7f 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -211,6 +211,9 @@ impl Type { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { + /// This is a 32-bit unicode scalar value, not a code point. + /// + /// Same as the Rust language's `char` type. Char, U8 { /// Indicates whether this type is intended to represent the `char` @@ -218,6 +221,9 @@ pub enum BuiltinType { /// it's language-specific. At an interface-types level this is an /// unsigned byte but binding generators may wish to bind this as the /// language-specific representation for a C character instead. + /// + /// This is also currently used exclusively in conjunction with `@witx + /// pointer` to hint that it's pointing to unicode string data as well. lang_c_char: bool, }, U16, diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index 5e077e588..6048f73a1 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -291,7 +291,12 @@ impl BuiltinType { BuiltinType::Char => "char", BuiltinType::U8 { .. } => "u8", BuiltinType::U16 => "u16", - BuiltinType::U32 { .. } => "u32", + BuiltinType::U32 { + lang_ptr_size: false, + } => "u32", + BuiltinType::U32 { + lang_ptr_size: true, + } => "usize", BuiltinType::U64 => "u64", BuiltinType::S8 => "s8", BuiltinType::S16 => "s16", From e18e448203c31a1b416a42e7e021e6b484aabbdf Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 9 Feb 2021 07:33:48 -0800 Subject: [PATCH 0854/1772] Address some review feedback --- proposals/random/phases/ephemeral/docs.md | 2 +- proposals/random/tools/witx/src/ast.rs | 6 ++++++ proposals/random/tools/witx/src/docs/ast.rs | 7 ++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 54568c75d..2cd2d1361 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -1,5 +1,5 @@ # Types -## `size`: `u32` +## `size`: `usize` An array size. Note: This is similar to `size_t` in POSIX. diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index a92c7895f..7d34b5f7f 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -211,6 +211,9 @@ impl Type { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { + /// This is a 32-bit unicode scalar value, not a code point. + /// + /// Same as the Rust language's `char` type. Char, U8 { /// Indicates whether this type is intended to represent the `char` @@ -218,6 +221,9 @@ pub enum BuiltinType { /// it's language-specific. At an interface-types level this is an /// unsigned byte but binding generators may wish to bind this as the /// language-specific representation for a C character instead. + /// + /// This is also currently used exclusively in conjunction with `@witx + /// pointer` to hint that it's pointing to unicode string data as well. lang_c_char: bool, }, U16, diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index 5e077e588..6048f73a1 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -291,7 +291,12 @@ impl BuiltinType { BuiltinType::Char => "char", BuiltinType::U8 { .. } => "u8", BuiltinType::U16 => "u16", - BuiltinType::U32 { .. } => "u32", + BuiltinType::U32 { + lang_ptr_size: false, + } => "u32", + BuiltinType::U32 { + lang_ptr_size: true, + } => "usize", BuiltinType::U64 => "u64", BuiltinType::S8 => "s8", BuiltinType::S16 => "s16", From 7ed041dc5a0ed497ca9804c96eaa00fc9da4e2f4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 9 Feb 2021 07:33:48 -0800 Subject: [PATCH 0855/1772] Address some review feedback --- proposals/filesystem/phases/ephemeral/docs.md | 2 +- proposals/filesystem/tools/witx/src/ast.rs | 6 ++++++ proposals/filesystem/tools/witx/src/docs/ast.rs | 7 ++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 54568c75d..2cd2d1361 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -1,5 +1,5 @@ # Types -## `size`: `u32` +## `size`: `usize` An array size. Note: This is similar to `size_t` in POSIX. diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index a92c7895f..7d34b5f7f 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -211,6 +211,9 @@ impl Type { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinType { + /// This is a 32-bit unicode scalar value, not a code point. + /// + /// Same as the Rust language's `char` type. Char, U8 { /// Indicates whether this type is intended to represent the `char` @@ -218,6 +221,9 @@ pub enum BuiltinType { /// it's language-specific. At an interface-types level this is an /// unsigned byte but binding generators may wish to bind this as the /// language-specific representation for a C character instead. + /// + /// This is also currently used exclusively in conjunction with `@witx + /// pointer` to hint that it's pointing to unicode string data as well. lang_c_char: bool, }, U16, diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index 5e077e588..6048f73a1 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -291,7 +291,12 @@ impl BuiltinType { BuiltinType::Char => "char", BuiltinType::U8 { .. } => "u8", BuiltinType::U16 => "u16", - BuiltinType::U32 { .. } => "u32", + BuiltinType::U32 { + lang_ptr_size: false, + } => "u32", + BuiltinType::U32 { + lang_ptr_size: true, + } => "usize", BuiltinType::U64 => "u64", BuiltinType::S8 => "s8", BuiltinType::S16 => "s16", From fd37bc5412a9ebe7cf725fe87b074bd2523145f1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 8 Feb 2021 13:52:34 -0800 Subject: [PATCH 0856/1772] Update the Proposals.md links to match the proposals repositories. This updates the Proposals.md page, fixing a few broken links, and updating the names of the proposals to match the actual proposal repositories. --- proposals/clocks/docs/Proposals.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/proposals/clocks/docs/Proposals.md b/proposals/clocks/docs/Proposals.md index 8bff83eb4..a7a831d40 100644 --- a/proposals/clocks/docs/Proposals.md +++ b/proposals/clocks/docs/Proposals.md @@ -28,10 +28,11 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo | ------------------------------------------------------------------------------ | -------------------------------------- | | [I/O][wasi-io] | Dan Gohman | | [Filesystem][wasi-filesystem] | Dan Gohman | -| [Command-Line][wasi-command-line] | Dan Gohman | +| ["Classic" Command-Line][wasi-classic-command] | Dan Gohman | | [Clocks][wasi-clocks] | Dan Gohman | | [Random][wasi-random] | Dan Gohman | -| [Misc][wasi-misc] | Dan Gohman | +| [Handle Index][handle-index] | Dan Gohman | +| [Poll][poll] | Dan Gohman | | [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 1 - Feature Proposal (CG) @@ -51,7 +52,7 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. [wasi-clocks]: https://github.com/WebAssembly/wasi-clocks -[wasi-command-line]: https://github.com/WebAssembly/wasi-classic-command +[wasi-classic-command]: https://github.com/WebAssembly/wasi-classic-command [wasi-crypto]: https://github.com/WebAssembly/wasi-crypto [wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem [wasi-io]: https://github.com/WebAssembly/wasi-io @@ -59,3 +60,5 @@ Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blo [wasi-nn]: https://github.com/WebAssembly/wasi-nn [wasi-proxy-wasm]: https://github.com/proxy-wasm/spec [wasi-random]: https://github.com/WebAssembly/wasi-random +[wasi-handle-index]: https://github.com/WebAssembly/wasi-handle-index +[wasi-poll]: https://github.com/WebAssembly/wasi-poll From 30e11f80fde7bd95119370ac573ff2803206fe5b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 8 Feb 2021 13:52:34 -0800 Subject: [PATCH 0857/1772] Update the Proposals.md links to match the proposals repositories. This updates the Proposals.md page, fixing a few broken links, and updating the names of the proposals to match the actual proposal repositories. --- proposals/random/docs/Proposals.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/proposals/random/docs/Proposals.md b/proposals/random/docs/Proposals.md index 8bff83eb4..a7a831d40 100644 --- a/proposals/random/docs/Proposals.md +++ b/proposals/random/docs/Proposals.md @@ -28,10 +28,11 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo | ------------------------------------------------------------------------------ | -------------------------------------- | | [I/O][wasi-io] | Dan Gohman | | [Filesystem][wasi-filesystem] | Dan Gohman | -| [Command-Line][wasi-command-line] | Dan Gohman | +| ["Classic" Command-Line][wasi-classic-command] | Dan Gohman | | [Clocks][wasi-clocks] | Dan Gohman | | [Random][wasi-random] | Dan Gohman | -| [Misc][wasi-misc] | Dan Gohman | +| [Handle Index][handle-index] | Dan Gohman | +| [Poll][poll] | Dan Gohman | | [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 1 - Feature Proposal (CG) @@ -51,7 +52,7 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. [wasi-clocks]: https://github.com/WebAssembly/wasi-clocks -[wasi-command-line]: https://github.com/WebAssembly/wasi-classic-command +[wasi-classic-command]: https://github.com/WebAssembly/wasi-classic-command [wasi-crypto]: https://github.com/WebAssembly/wasi-crypto [wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem [wasi-io]: https://github.com/WebAssembly/wasi-io @@ -59,3 +60,5 @@ Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blo [wasi-nn]: https://github.com/WebAssembly/wasi-nn [wasi-proxy-wasm]: https://github.com/proxy-wasm/spec [wasi-random]: https://github.com/WebAssembly/wasi-random +[wasi-handle-index]: https://github.com/WebAssembly/wasi-handle-index +[wasi-poll]: https://github.com/WebAssembly/wasi-poll From e0d32258c89351e3015696de060875d0d29816a9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 8 Feb 2021 13:52:34 -0800 Subject: [PATCH 0858/1772] Update the Proposals.md links to match the proposals repositories. This updates the Proposals.md page, fixing a few broken links, and updating the names of the proposals to match the actual proposal repositories. --- proposals/filesystem/docs/Proposals.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/docs/Proposals.md b/proposals/filesystem/docs/Proposals.md index 8bff83eb4..a7a831d40 100644 --- a/proposals/filesystem/docs/Proposals.md +++ b/proposals/filesystem/docs/Proposals.md @@ -28,10 +28,11 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo | ------------------------------------------------------------------------------ | -------------------------------------- | | [I/O][wasi-io] | Dan Gohman | | [Filesystem][wasi-filesystem] | Dan Gohman | -| [Command-Line][wasi-command-line] | Dan Gohman | +| ["Classic" Command-Line][wasi-classic-command] | Dan Gohman | | [Clocks][wasi-clocks] | Dan Gohman | | [Random][wasi-random] | Dan Gohman | -| [Misc][wasi-misc] | Dan Gohman | +| [Handle Index][handle-index] | Dan Gohman | +| [Poll][poll] | Dan Gohman | | [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 1 - Feature Proposal (CG) @@ -51,7 +52,7 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. [wasi-clocks]: https://github.com/WebAssembly/wasi-clocks -[wasi-command-line]: https://github.com/WebAssembly/wasi-classic-command +[wasi-classic-command]: https://github.com/WebAssembly/wasi-classic-command [wasi-crypto]: https://github.com/WebAssembly/wasi-crypto [wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem [wasi-io]: https://github.com/WebAssembly/wasi-io @@ -59,3 +60,5 @@ Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blo [wasi-nn]: https://github.com/WebAssembly/wasi-nn [wasi-proxy-wasm]: https://github.com/proxy-wasm/spec [wasi-random]: https://github.com/WebAssembly/wasi-random +[wasi-handle-index]: https://github.com/WebAssembly/wasi-handle-index +[wasi-poll]: https://github.com/WebAssembly/wasi-poll From 432ff457fd88fbe41dd7a334174a4ac9ab504cc1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 11 Feb 2021 11:40:18 -0600 Subject: [PATCH 0859/1772] Add a new style of test suite for the `witx` tooling similar to `*.wast` (#392) * Add a wast-like testsuite for the witx tool As the functionality of `witx` grows this will hopefully make adding tests for new functionality as well as new kinds of tests easier. The goal is to make it very easy to drop a test file with various directives to exercise the functionality of `witx` and its internals. For now the testsuite is quite simple, simply asserting whether documents are either valid or invalid. My hope, though, is that this can be expanded over time with more styles of assertions directives. * Migrate union test to `union.witxt` * Add documentation/roundtrip testing to all documents * Translate multi-module test suite to `*.witxt` * Move wasi tests into `witxt` test suites * Convert representation tests to `*.witxt` * Rebased onto origin/main --- proposals/clocks/phases/ephemeral/docs.md | 4 +- proposals/clocks/tools/witx/Cargo.toml | 5 + proposals/clocks/tools/witx/src/lib.rs | 5 +- proposals/clocks/tools/witx/src/parser.rs | 5 +- .../clocks/tools/witx/src/representation.rs | 81 +--- proposals/clocks/tools/witx/src/toplevel.rs | 2 +- proposals/clocks/tools/witx/src/validate.rs | 34 +- .../clocks/tools/witx/tests/anonymous.rs | 43 -- .../clocks/tools/witx/tests/multimodule.rs | 58 --- proposals/clocks/tools/witx/tests/union.rs | 174 -------- .../witx/tests/{wasi.rs => wasi-docs.rs} | 64 --- proposals/clocks/tools/witx/tests/witxt.rs | 409 ++++++++++++++++++ .../tools/witx/tests/witxt/anonymous.witxt | 56 +++ .../tools/witx/tests/witxt/multimodule.witxt | 22 + .../{ => witxt}/multimodule/redefine_a.witx | 0 .../tests/{ => witxt}/multimodule/type_a.witx | 0 .../tests/{ => witxt}/multimodule/type_b.witx | 0 .../tests/{ => witxt}/multimodule/type_c.witx | 0 .../witx/tests/witxt/representation.witxt | 60 +++ .../tools/witx/tests/witxt/simple.witxt | 12 + .../clocks/tools/witx/tests/witxt/union.witxt | 97 +++++ .../clocks/tools/witx/tests/witxt/wasi.witxt | 26 ++ 22 files changed, 726 insertions(+), 431 deletions(-) delete mode 100644 proposals/clocks/tools/witx/tests/anonymous.rs delete mode 100644 proposals/clocks/tools/witx/tests/multimodule.rs delete mode 100644 proposals/clocks/tools/witx/tests/union.rs rename proposals/clocks/tools/witx/tests/{wasi.rs => wasi-docs.rs} (58%) create mode 100644 proposals/clocks/tools/witx/tests/witxt.rs create mode 100644 proposals/clocks/tools/witx/tests/witxt/anonymous.witxt create mode 100644 proposals/clocks/tools/witx/tests/witxt/multimodule.witxt rename proposals/clocks/tools/witx/tests/{ => witxt}/multimodule/redefine_a.witx (100%) rename proposals/clocks/tools/witx/tests/{ => witxt}/multimodule/type_a.witx (100%) rename proposals/clocks/tools/witx/tests/{ => witxt}/multimodule/type_b.witx (100%) rename proposals/clocks/tools/witx/tests/{ => witxt}/multimodule/type_c.witx (100%) create mode 100644 proposals/clocks/tools/witx/tests/witxt/representation.witxt create mode 100644 proposals/clocks/tools/witx/tests/witxt/simple.witxt create mode 100644 proposals/clocks/tools/witx/tests/witxt/union.witxt create mode 100644 proposals/clocks/tools/witx/tests/witxt/wasi.witxt diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 2cd2d1361..a3c0d0a47 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -871,12 +871,12 @@ Alignment: 8 - align: 8 - tag_size: 1 ### Variant cases +- `clock` + - `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) - `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) -- `clock` - ## `event`: Record An event that occurred. diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index 34c074d68..bf9ce16cd 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -23,3 +23,8 @@ wast = { version = "22.0.0", default-features = false } diff = "0.1.11" pretty_env_logger = "0.4" structopt = "0.3" +rayon = "1.0" + +[[test]] +name = "witxt" +harness = false diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 9c0f53060..2c876aa13 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -9,7 +9,7 @@ mod io; /// Calculate memory layout of types mod layout; /// Witx syntax parsing from SExprs -mod parser; +pub mod parser; /// Paths to witx documents for various proposal phases pub mod phases; /// Calculate required polyfill between interfaces @@ -28,10 +28,9 @@ pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, T pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use layout::{Layout, RecordMemberLayout, SizeAlign}; -pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; -pub use validate::ValidationError; +pub use validate::{DocValidation, ValidationError}; use std::path::{Path, PathBuf}; use thiserror::Error; diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 325eb1d35..19d1a0303 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -477,7 +477,6 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { None }; let mut fields = Vec::new(); - fields.push(parser.parse()?); while !parser.is_empty() { fields.push(parser.parse()?); } @@ -505,7 +504,9 @@ impl<'a> Parse<'a> for VariantSyntax<'a> { }; let mut cases = Vec::new(); while !parser.is_empty() { - cases.push(parser.parens(|p| p.parse())?); + let comments = parser.parse()?; + let item = parser.parens(|p| p.parse())?; + cases.push(Documented { comments, item }); } Ok(VariantSyntax { tag, cases }) } diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs index 99f73f5b6..589b64e39 100644 --- a/proposals/clocks/tools/witx/src/representation.rs +++ b/proposals/clocks/tools/witx/src/representation.rs @@ -81,12 +81,14 @@ impl Representable for Variant { let other_by_name = by .cases .iter() - .map(|c| (&c.name, c)) + .enumerate() + .map(|(i, c)| (&c.name, (c, i))) .collect::>(); // For each variant in self, must have variant of same name in by: - for v in self.cases.iter() { + for (i, v) in self.cases.iter().enumerate() { let other_ty = match other_by_name.get(&v.name) { - Some(other) => &other.tref, + Some((_, j)) if i != *j => return RepEquality::NotEq, + Some((other, _)) => &other.tref, None => return RepEquality::NotEq, }; match (&v.tref, other_ty) { @@ -157,76 +159,3 @@ impl Representable for Type { } } } - -#[cfg(test)] -mod test { - use super::*; - use crate::io::MockFs; - use crate::toplevel::parse_witx_with; - use crate::Id; - use std::rc::Rc; - - fn def_type(typename: &str, syntax: &str) -> Rc { - use std::path::Path; - let doc = parse_witx_with(&[Path::new("-")], &MockFs::new(&[("-", syntax)])) - .expect("parse witx doc"); - let t = doc.typename(&Id::new(typename)).expect("defined type"); - // Identity should always be true: - assert_eq!(t.representable(&t), RepEquality::Eq, "identity"); - t - } - - #[test] - fn different_typenames() { - let a = def_type("a", "(typename $a (flags (@witx bitflags u32) $b $c))"); - let d = def_type("d", "(typename $d (flags (@witx bitflags u32) $b $c))"); - - assert_eq!(a.representable(&d), RepEquality::Eq); - assert_eq!(d.representable(&a), RepEquality::Eq); - } - - #[test] - fn enum_() { - let base = def_type("a", "(typename $a (enum $b $c))"); - let extra_variant = def_type("a", "(typename $a (enum $b $c $d))"); - - assert_eq!(base.representable(&extra_variant), RepEquality::Superset); - assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); - - let smaller_size = def_type("a", "(typename $a (enum (@witx tag u16) $b $c))"); - assert_eq!(smaller_size.representable(&base), RepEquality::Superset); - assert_eq!( - smaller_size.representable(&extra_variant), - RepEquality::Superset - ); - } - - #[test] - fn union() { - let base = def_type( - "a", - "(typename $tag (enum (@witx tag u8) $b $c)) - (typename $a (union (@witx tag $tag) u32 f32))", - ); - let extra_variant = def_type( - "a", - "(typename $tag (enum (@witx tag u8) $b $c $d)) - (typename $a (union (@witx tag $tag) u32 f32 f64))", - ); - - assert_eq!(base.representable(&extra_variant), RepEquality::Superset); - assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); - - let other_ordering = def_type( - "a", - "(typename $tag (enum (@witx tag u8) $b $c)) - (typename $a (variant (@witx tag $tag) (case $c f32) (case $b u32)))", - ); - assert_eq!(base.representable(&other_ordering), RepEquality::Eq); - assert_eq!(other_ordering.representable(&base), RepEquality::Eq); - assert_eq!( - other_ordering.representable(&extra_variant), - RepEquality::Superset - ); - } -} diff --git a/proposals/clocks/tools/witx/src/toplevel.rs b/proposals/clocks/tools/witx/src/toplevel.rs index 993fc8cc4..83e940c7c 100644 --- a/proposals/clocks/tools/witx/src/toplevel.rs +++ b/proposals/clocks/tools/witx/src/toplevel.rs @@ -32,7 +32,7 @@ fn _parse_witx_with(paths: &[&Path], io: &dyn WitxIo) -> Result, + entries: HashMap, constant_scopes: HashMap, } @@ -155,6 +155,10 @@ impl DocValidation { path, } } + + pub fn into_document(self, defs: Vec) -> Document { + Document::new(defs, self.entries) + } } impl DocValidationScope<'_> { @@ -439,14 +443,16 @@ impl DocValidationScope<'_> { } } - let mut names = names.map(|names| names.into_iter().collect::>()); + let mut name_set = names + .as_ref() + .map(|names| names.iter().collect::>()); - let cases = syntax + let mut cases = syntax .cases .iter() .map(|case| { let name = Id::new(case.item.name.name()); - if let Some(names) = &mut names { + if let Some(names) = &mut name_set { if !names.remove(&name) { return Err(ValidationError::InvalidUnionField { name: name.as_str().to_string(), @@ -467,6 +473,18 @@ impl DocValidationScope<'_> { }) }) .collect::, _>>()?; + + // If we have an explicit tag with an enum then that's instructing us to + // reorder cases based on the order of the enum itself, so do that here. + if let Some(names) = names { + let name_pos = names + .iter() + .enumerate() + .map(|(i, name)| (name, i)) + .collect::>(); + cases.sort_by_key(|c| name_pos[&&c.name]); + } + Ok(Variant { tag_repr, cases }) } diff --git a/proposals/clocks/tools/witx/tests/anonymous.rs b/proposals/clocks/tools/witx/tests/anonymous.rs deleted file mode 100644 index 6cfb2ea7e..000000000 --- a/proposals/clocks/tools/witx/tests/anonymous.rs +++ /dev/null @@ -1,43 +0,0 @@ -use witx; - -fn is_anonymous_record_err(r: Result) -> bool { - match r { - Err(witx::WitxError::Validation(witx::ValidationError::AnonymousRecord { .. })) => true, - _ => false, - } -} - -#[test] -fn anonymous_types() { - let pointer_to_record = witx::parse("(typename $a (@witx pointer (record (field $b u8))))"); - assert!(is_anonymous_record_err(pointer_to_record)); - - let pointer_to_union = - witx::parse("(typename $tag (enum $b)) (typename $a (@witx pointer (union u8)))"); - assert!(is_anonymous_record_err(pointer_to_union)); - - let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum $b)))"); - assert!(is_anonymous_record_err(pointer_to_enum)); - - let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags $b)))"); - assert!(is_anonymous_record_err(pointer_to_flags)); - - let pointer_to_handle = witx::parse("(typename $a (@witx pointer (handle)))"); - assert!(is_anonymous_record_err(pointer_to_handle)); - - let pointer_to_builtin = witx::parse("(typename $a (@witx pointer u8))"); - assert!(pointer_to_builtin.is_ok()); - - let pointer_to_pointer = witx::parse("(typename $a (@witx pointer (@witx const_pointer u8)))"); - assert!(pointer_to_pointer.is_ok()); - - let record_in_record = witx::parse("(typename $a (record (field $b (record (field $c u8)))))"); - assert!(is_anonymous_record_err(record_in_record)); - - let union_in_record = - witx::parse("(typename $tag (enum $c)) (typename $a (record (field $b (union u8))))"); - assert!(is_anonymous_record_err(union_in_record)); - - let pointer_in_record = witx::parse("(typename $a (record (field $b (@witx pointer u8))))"); - assert!(pointer_in_record.is_ok()) -} diff --git a/proposals/clocks/tools/witx/tests/multimodule.rs b/proposals/clocks/tools/witx/tests/multimodule.rs deleted file mode 100644 index a6c773363..000000000 --- a/proposals/clocks/tools/witx/tests/multimodule.rs +++ /dev/null @@ -1,58 +0,0 @@ -use witx::{load, BuiltinType, Id, Type, TypeRef}; - -#[test] -fn validate_multimodule() { - // B uses A, and C uses A. - let doc = load(&[ - "tests/multimodule/type_b.witx", - "tests/multimodule/type_c.witx", - ]) - .unwrap_or_else(|e| panic!("failed to validate: {}", e)); - - //println!("{}", doc); - - // Check that the `a` both modules use is what we expect: - let type_a = doc.typename(&Id::new("a")).expect("type a exists"); - assert_eq!( - *type_a.type_(), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: false - }) - ); - - // `b` is a struct with a single member of type `a` - let type_b = doc.typename(&Id::new("b")).expect("type b exists"); - match &*type_b.type_() { - Type::Record(record) => { - assert_eq!(record.members.len(), 1); - assert_eq!( - record.members.get(0).unwrap().tref, - TypeRef::Name(type_a.clone()) - ); - } - _ => panic!("b is a struct"), - } - - // `c` is a struct with a two members of type `a` - let type_c = doc.typename(&Id::new("c")).expect("type c exists"); - match &*type_c.type_() { - Type::Record(record) => { - assert_eq!(record.members.len(), 2); - assert_eq!( - record.members.get(0).unwrap().tref, - TypeRef::Name(type_a.clone()) - ); - assert_eq!(record.members.get(1).unwrap().tref, TypeRef::Name(type_a)); - } - _ => panic!("c is a struct"), - } -} - -#[test] -fn multimodule_reject_redefinition() { - assert!(load(&[ - "tests/multimodule/type_a.witx", - "tests/multimodule/redefine_a.witx", - ]) - .is_err()) -} diff --git a/proposals/clocks/tools/witx/tests/union.rs b/proposals/clocks/tools/witx/tests/union.rs deleted file mode 100644 index 31ade263a..000000000 --- a/proposals/clocks/tools/witx/tests/union.rs +++ /dev/null @@ -1,174 +0,0 @@ -// Every worker needs a union! Time to organize -use witx::{Id, Representable}; - -#[test] -fn one_variant_union() { - let d = witx::parse( - "(typename $tag (enum $c)) - (typename $u (union (@witx tag $tag) u8))", - ); - assert!(d.is_ok()); -} - -#[test] -fn two_variant_union() { - let d1 = witx::parse( - "(typename $tag (enum $a $b)) - (typename $u (union (@witx tag $tag) u8 u16))", - ); - assert!(d1.is_ok(), "d1 is ok"); - - // Fields can come in whatever order: - let d2 = witx::parse( - "(typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $b u16) (case $a u8)))", - ); - assert!(d2.is_ok(), "d2 is ok"); - - // These two unions should be represented the same: - let u1 = d1.unwrap().typename(&Id::new("u")).unwrap().type_(); - let u2 = d2.unwrap().typename(&Id::new("u")).unwrap().type_(); - - assert_eq!( - u1.representable(&u2), - witx::RepEquality::Eq, - "u1 can represent u2" - ); - assert_eq!( - u2.representable(&u1), - witx::RepEquality::Eq, - "u2 can represent u1" - ); - - // Tag order doesnt matter for validation - let d3 = witx::parse( - "(typename $tag (enum $b $a)) - (typename $u (union (@witx tag $tag) u16 u8))", - ); - assert!(d3.is_ok(), "d2 is ok"); -} - -#[test] -fn empty_variant_unions() { - let d1 = witx::parse( - "(typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $a) (case $b u16)))", - ); - assert!(d1.is_ok(), "d1 is ok"); - - let d2 = witx::parse( - "(typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $a) (case $b)))", - ); - assert!(d2.is_ok(), "d2 is ok"); -} - -#[test] -fn many_variant_unions() { - let d1 = witx::parse( - "(typename $tag (enum $a $b $c $d $e $f $g $h $i $j $k $l $m)) - (typename $u - (variant (@witx tag $tag) - (case $a u8) - (case $b u16) - (case $c u32) - (case $d u64) - (case $e s8) - (case $f s16) - (case $g s32) - (case $h s64) - (case $i f32) - (case $j f64) - (case $k (@witx usize)) - (case $l (@witx char8)) - (case $m) - ) - )", - ); - assert!(d1.is_ok(), "d1 is ok"); -} - -#[test] -fn no_tag_union() { - let d = witx::parse("(typename $u (union $tag (field $a u8) (field $b u16)))"); - assert!(d.is_err()); -} - -#[test] -fn wrong_kind_tag_union() { - let d = witx::parse( - "(typename $tag string) - (typename $u (union (@witx tag $tag) u8 u16))", - ); - let (expected, got) = wrong_kind_name_err(d).expect("wrong kind of tag"); - assert_eq!(expected, "enum or builtin"); - assert_eq!(got, "list"); -} - -#[test] -fn bad_field_unions() { - let d = witx::parse( - "(typename $tag (enum $c)) - (typename $u (variant (@witx tag $tag) (case $b u8)))", - ); - match validation_err(d) { - witx::ValidationError::InvalidUnionField { name, reason, .. } => { - assert_eq!(name, "b", "bad field name union 1"); - assert_eq!( - reason, "does not correspond to variant in tag `tag`", - "reason union 1" - ); - } - other => panic!("bad error: {}", other), - } - - let d = witx::parse( - "(typename $tag (enum $c)) - (typename $u (variant (@witx tag $tag) (case $c f32) (case $b u8)))", - ); - match validation_err(d) { - witx::ValidationError::UnionSizeMismatch { .. } => {} - other => panic!("bad error: {}", other), - } - - let d = witx::parse( - "(typename $tag (enum $c $d)) - (typename $u (variant (@witx tag $tag) (case $c f32)))", - ); - match validation_err(d) { - witx::ValidationError::UnionSizeMismatch { .. } => {} - other => panic!("bad error: {}", other), - } -} - -fn wrong_kind_name_err( - r: Result, -) -> Option<(&'static str, &'static str)> { - match r { - Err(witx::WitxError::Validation(witx::ValidationError::WrongKindName { - expected, - got, - .. - })) => Some((expected, got)), - Err(e) => { - eprintln!("expected WrongKindName ValidationError, got: {:?}", e); - None - } - Ok(_) => { - eprintln!("expected WrongKindName ValidationError: Ok(witx::Document)"); - None - } - } -} - -fn validation_err(r: Result) -> witx::ValidationError { - match r { - Err(witx::WitxError::Validation(e)) => e, - Err(e) => { - panic!("expected ValidationError, got: {:?}", e) - } - Ok(_) => { - panic!("expected ValidationError, got: Ok(witx::Document)") - } - } -} diff --git a/proposals/clocks/tools/witx/tests/wasi.rs b/proposals/clocks/tools/witx/tests/wasi-docs.rs similarity index 58% rename from proposals/clocks/tools/witx/tests/wasi.rs rename to proposals/clocks/tools/witx/tests/wasi-docs.rs index 27300a26e..6702edfbd 100644 --- a/proposals/clocks/tools/witx/tests/wasi.rs +++ b/proposals/clocks/tools/witx/tests/wasi-docs.rs @@ -2,24 +2,6 @@ use std::fs; use std::path::Path; use witx::{self, Documentation}; -#[test] -fn validate_wasi_snapshot() { - witx::load(&witx::phases::snapshot().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); -} - -#[test] -fn validate_wasi_ephemeral() { - witx::load(&witx::phases::ephemeral().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); -} - -#[test] -fn validate_wasi_old_snapshot_0() { - witx::load(&witx::phases::old::snapshot_0().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); -} - #[test] fn validate_docs() { for phase in &[ @@ -32,52 +14,6 @@ fn validate_docs() { } } -#[test] -fn render_roundtrip() { - let doc = witx::load(&witx::phases::snapshot().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); - - let back_to_sexprs = format!("{}", doc); - println!("{}", back_to_sexprs); - - let doc2 = witx::parse(&back_to_sexprs) - .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) - .unwrap(); - - // I'd just assert_eq, but when it fails the debug print is thousands of lines long and impossible - // to figure out where they are unequal. - if doc != doc2 { - for type_ in doc.typenames() { - let type2 = doc2.typename(&type_.name).expect("doc2 missing datatype"); - assert_eq!(type_, type2); - } - for mod_ in doc.modules() { - let mod2 = doc2.module(&mod_.name).expect("doc2 missing module"); - for import in mod_.imports() { - let import2 = mod2.import(&import.name).expect("mod2 missing import"); - assert_eq!(import, import2); - } - for func in mod_.funcs() { - let func2 = mod2.func(&func.name).expect("mod2 missing func"); - assert_eq!(func, func2); - } - } - } - // This should be equivalent to the above, but just in case some code changes where it isnt: - assert_eq!(doc, doc2); -} - -#[test] -fn document_wasi_snapshot() { - use witx::Documentation; - println!( - "{}", - witx::load(&witx::phases::snapshot().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)) - .to_md() - ); -} - fn dos2unix(s: &str) -> String { let mut t = String::new(); t.reserve(s.len()); diff --git a/proposals/clocks/tools/witx/tests/witxt.rs b/proposals/clocks/tools/witx/tests/witxt.rs new file mode 100644 index 000000000..1056947a3 --- /dev/null +++ b/proposals/clocks/tools/witx/tests/witxt.rs @@ -0,0 +1,409 @@ +//! You can run this test suite with: +//! +//! cargo test --test witxt +//! +//! An argument can be passed as well to filter, based on filename, which test +//! to run +//! +//! cargo test --test witxt foo.witxt + +use anyhow::{anyhow, bail, Context, Result}; +use rayon::prelude::*; +use std::collections::HashMap; +use std::path::{Path, PathBuf}; +use std::str; +use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; +use wast::parser::{self, Parse, ParseBuffer, Parser}; +use witx::{Documentation, Representable}; + +fn main() { + let tests = find_tests(); + let filter = std::env::args().nth(1); + + let tests = tests + .par_iter() + .filter_map(|test| { + if let Some(filter) = &filter { + if let Some(s) = test.to_str() { + if !s.contains(filter) { + return None; + } + } + } + let contents = std::fs::read(test).unwrap(); + Some((test, contents)) + }) + .collect::>(); + + println!("running {} test files\n", tests.len()); + + let ntests = AtomicUsize::new(0); + let errors = tests + .par_iter() + .filter_map(|(test, contents)| { + WitxtRunner { + ntests: &ntests, + documents: HashMap::new(), + } + .run(test, contents) + .err() + }) + .collect::>(); + + if !errors.is_empty() { + for msg in errors.iter() { + eprintln!("{:?}", msg); + } + + panic!("{} tests failed", errors.len()) + } + + println!( + "test result: ok. {} directives passed\n", + ntests.load(SeqCst) + ); +} + +/// Recursively finds all tests in a whitelisted set of directories which we +/// then load up and test in parallel. +fn find_tests() -> Vec { + let mut tests = Vec::new(); + find_tests("tests/witxt".as_ref(), &mut tests); + tests.sort(); + return tests; + + fn find_tests(path: &Path, tests: &mut Vec) { + for f in path.read_dir().unwrap() { + let f = f.unwrap(); + if f.file_type().unwrap().is_dir() { + find_tests(&f.path(), tests); + continue; + } + + match f.path().extension().and_then(|s| s.to_str()) { + Some("witxt") => {} + _ => continue, + } + tests.push(f.path()); + } + } +} + +struct WitxtRunner<'a> { + ntests: &'a AtomicUsize, + documents: HashMap, +} + +impl WitxtRunner<'_> { + fn run(&mut self, test: &Path, contents: &[u8]) -> Result<()> { + let contents = str::from_utf8(contents)?; + macro_rules! adjust { + ($e:expr) => {{ + let mut e = wast::Error::from($e); + e.set_path(test); + e.set_text(contents); + e + }}; + } + let buf = ParseBuffer::new(contents).map_err(|e| adjust!(e))?; + let witxt = parser::parse::(&buf).map_err(|e| adjust!(e))?; + + let errors = witxt + .directives + .into_iter() + .filter_map(|directive| { + let (line, col) = directive.span().linecol_in(contents); + self.test_directive(contents, test, directive) + .with_context(|| { + format!( + "failed directive on {}:{}:{}", + test.display(), + line + 1, + col + 1 + ) + }) + .err() + }) + .collect::>(); + if errors.is_empty() { + return Ok(()); + } + let mut s = format!("{} test failures in {}:", errors.len(), test.display()); + for mut error in errors { + if let Some(err) = error.downcast_mut::() { + err.set_path(test); + err.set_text(contents); + } + s.push_str("\n\n\t--------------------------------\n\n\t"); + s.push_str(&format!("{:?}", error).replace("\n", "\n\t")); + } + bail!("{}", s) + } + + fn test_directive( + &mut self, + contents: &str, + test: &Path, + directive: WitxtDirective, + ) -> Result<()> { + self.bump_ntests(); + match directive { + WitxtDirective::Witx(witx) => { + let doc = witx.document(contents, test)?; + self.assert_roundtrip(&doc) + .context("failed to round-trip the document")?; + self.assert_md(&doc)?; + if let Some(name) = witx.id { + self.documents.insert(name.name().to_string(), doc); + } + } + WitxtDirective::AssertInvalid { witx, message, .. } => { + let err = match witx.document(contents, test) { + Ok(_) => bail!("witx was valid when it shouldn't be"), + Err(e) => format!("{:?}", anyhow::Error::from(e)), + }; + if !err.contains(message) { + bail!("expected error {:?}\nfound error {}", message, err); + } + } + WitxtDirective::AssertRepresentable { repr, t1, t2, .. } => { + let (t1m, t1t) = t1; + let (t2m, t2t) = t2; + let t1d = self + .documents + .get(t1m.name()) + .ok_or_else(|| anyhow!("no document named {:?}", t1m.name()))?; + let t2d = self + .documents + .get(t2m.name()) + .ok_or_else(|| anyhow!("no document named {:?}", t2m.name()))?; + let t1 = t1d + .typename(&witx::Id::new(t1t)) + .ok_or_else(|| anyhow!("no type named {:?}", t1t))?; + let t2 = t2d + .typename(&witx::Id::new(t2t)) + .ok_or_else(|| anyhow!("no type named {:?}", t2t))?; + match (repr, t1.type_().representable(&t2.type_())) { + (RepEquality::Eq, witx::RepEquality::Eq) + | (RepEquality::Superset, witx::RepEquality::Superset) + | (RepEquality::NotEq, witx::RepEquality::NotEq) => {} + (a, b) => { + bail!("expected {:?} representation, got {:?}", a, b); + } + } + } + } + Ok(()) + } + + fn assert_roundtrip(&self, doc: &witx::Document) -> Result<()> { + self.bump_ntests(); + let back_to_sexprs = format!("{}", doc); + let doc2 = witx::parse(&back_to_sexprs)?; + if *doc == doc2 { + return Ok(()); + } + + // Try to get a more specific error message that isn't thousands of + // lines long of debug representations. + for type_ in doc.typenames() { + let type2 = match doc2.typename(&type_.name) { + Some(t) => t, + None => bail!("doc2 missing datatype"), + }; + if type_ != type2 { + bail!("types are not equal\n{:?}\n !=\n{:?}", type_, type2); + } + } + for mod_ in doc.modules() { + let mod2 = match doc2.module(&mod_.name) { + Some(m) => m, + None => bail!("doc2 missing module"), + }; + for import in mod_.imports() { + let import2 = match mod2.import(&import.name) { + Some(i) => i, + None => bail!("mod2 missing import"), + }; + assert_eq!(import, import2); + } + for func in mod_.funcs() { + let func2 = match mod2.func(&func.name) { + Some(f) => f, + None => bail!("mod2 missing func"), + }; + assert_eq!(func, func2); + } + } + bail!("{:?} != {:?}", doc, doc2) + } + + fn assert_md(&self, doc: &witx::Document) -> Result<()> { + self.bump_ntests(); + doc.to_md(); + Ok(()) + } + + fn bump_ntests(&self) { + self.ntests.fetch_add(1, SeqCst); + } +} + +mod kw { + wast::custom_keyword!(assert_invalid); + wast::custom_keyword!(assert_representable); + wast::custom_keyword!(witx); + wast::custom_keyword!(eq); + wast::custom_keyword!(noteq); + wast::custom_keyword!(load); + wast::custom_keyword!(superset); +} + +struct Witxt<'a> { + directives: Vec>, +} + +impl<'a> Parse<'a> for Witxt<'a> { + fn parse(parser: Parser<'a>) -> parser::Result { + let mut directives = Vec::new(); + while !parser.is_empty() { + directives.push(parser.parens(|p| p.parse())?); + } + Ok(Witxt { directives }) + } +} + +enum WitxtDirective<'a> { + Witx(Witx<'a>), + AssertInvalid { + span: wast::Span, + witx: Witx<'a>, + message: &'a str, + }, + AssertRepresentable { + span: wast::Span, + repr: RepEquality, + t1: (wast::Id<'a>, &'a str), + t2: (wast::Id<'a>, &'a str), + }, +} + +impl WitxtDirective<'_> { + fn span(&self) -> wast::Span { + match self { + WitxtDirective::Witx(w) => w.span, + WitxtDirective::AssertInvalid { span, .. } + | WitxtDirective::AssertRepresentable { span, .. } => *span, + } + } +} + +impl<'a> Parse<'a> for WitxtDirective<'a> { + fn parse(parser: Parser<'a>) -> parser::Result { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(WitxtDirective::Witx(parser.parse()?)) + } else if l.peek::() { + let span = parser.parse::()?.0; + Ok(WitxtDirective::AssertInvalid { + span, + witx: parser.parens(|p| p.parse())?, + message: parser.parse()?, + }) + } else if l.peek::() { + let span = parser.parse::()?.0; + Ok(WitxtDirective::AssertRepresentable { + span, + repr: parser.parse()?, + t1: (parser.parse()?, parser.parse()?), + t2: (parser.parse()?, parser.parse()?), + }) + } else { + Err(l.error()) + } + } +} + +struct Witx<'a> { + span: wast::Span, + id: Option>, + def: WitxDef<'a>, +} + +enum WitxDef<'a> { + Fs(Vec<&'a str>), + Inline(Vec>>), +} + +impl Witx<'_> { + fn document(&self, contents: &str, file: &Path) -> Result { + match &self.def { + WitxDef::Inline(decls) => { + let mut validator = witx::DocValidation::new(); + let mut definitions = Vec::new(); + for decl in decls { + validator + .scope(contents, file) + .validate_decl(&decl.item, &decl.comments, &mut definitions) + .map_err(witx::WitxError::Validation)?; + } + Ok(validator.into_document(definitions)) + } + WitxDef::Fs(paths) => { + let parent = file.parent().unwrap(); + let paths = paths.iter().map(|p| parent.join(p)).collect::>(); + Ok(witx::load(&paths)?) + } + } + } +} + +impl<'a> Parse<'a> for Witx<'a> { + fn parse(parser: Parser<'a>) -> parser::Result { + let span = parser.parse::()?.0; + let id = parser.parse()?; + + let def = if parser.peek2::() { + parser.parens(|p| { + p.parse::()?; + let mut paths = Vec::new(); + while !p.is_empty() { + paths.push(p.parse()?); + } + Ok(WitxDef::Fs(paths)) + })? + } else { + let mut decls = Vec::new(); + while !parser.is_empty() { + decls.push(parser.parens(|p| p.parse())?); + } + WitxDef::Inline(decls) + }; + Ok(Witx { id, span, def }) + } +} + +#[derive(Debug)] +enum RepEquality { + Eq, + NotEq, + Superset, +} + +impl<'a> Parse<'a> for RepEquality { + fn parse(parser: Parser<'a>) -> parser::Result { + let mut l = parser.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(RepEquality::Eq) + } else if l.peek::() { + parser.parse::()?; + Ok(RepEquality::NotEq) + } else if l.peek::() { + parser.parse::()?; + Ok(RepEquality::Superset) + } else { + Err(l.error()) + } + } +} diff --git a/proposals/clocks/tools/witx/tests/witxt/anonymous.witxt b/proposals/clocks/tools/witx/tests/witxt/anonymous.witxt new file mode 100644 index 000000000..0ed3bc0d2 --- /dev/null +++ b/proposals/clocks/tools/witx/tests/witxt/anonymous.witxt @@ -0,0 +1,56 @@ +;; Ensure that anonymous structured types are not allowed in type positions at +;; this time, everything has to be named to assist in binding in languages. + +(assert_invalid + (witx + (typename $a (@witx pointer (record (field $b u8)))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (@witx pointer (union))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (@witx pointer (enum $b))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (@witx pointer (flags $b))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (@witx pointer (handle))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (record (field $b (record (field $c u8))))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $tag (enum $c)) + (typename $a (record (field $b (union)))) + ) + "Anonymous structured types") + + +;; pointers don't count for anonymous indirections +(witx + (typename $a (@witx pointer u8))) + +(witx + (typename $a (@witx pointer (@witx const_pointer u8)))) + +(witx + (typename $a (record (field $b (@witx pointer u8))))) diff --git a/proposals/clocks/tools/witx/tests/witxt/multimodule.witxt b/proposals/clocks/tools/witx/tests/witxt/multimodule.witxt new file mode 100644 index 000000000..d8b6559ac --- /dev/null +++ b/proposals/clocks/tools/witx/tests/witxt/multimodule.witxt @@ -0,0 +1,22 @@ +;; B uses A, and C uses A. +(witx $multi + (load "multimodule/type_b.witx" "multimodule/type_c.witx") +) + +(witx $reference + (typename $a u32) + (typename $b (record (field $member_a $a))) + (typename $c (record (field $first_a $a) (field $second_a $a))) +) + +(assert_representable eq $reference "a" $multi "a") +(assert_representable eq $reference "b" $multi "b") +(assert_representable eq $reference "c" $multi "c") + +(assert_invalid + (witx + (load + "multimodule/type_a.witx" + "multimodule/redefine_a.witx") + ) + "Redefinition of name `a`") diff --git a/proposals/clocks/tools/witx/tests/multimodule/redefine_a.witx b/proposals/clocks/tools/witx/tests/witxt/multimodule/redefine_a.witx similarity index 100% rename from proposals/clocks/tools/witx/tests/multimodule/redefine_a.witx rename to proposals/clocks/tools/witx/tests/witxt/multimodule/redefine_a.witx diff --git a/proposals/clocks/tools/witx/tests/multimodule/type_a.witx b/proposals/clocks/tools/witx/tests/witxt/multimodule/type_a.witx similarity index 100% rename from proposals/clocks/tools/witx/tests/multimodule/type_a.witx rename to proposals/clocks/tools/witx/tests/witxt/multimodule/type_a.witx diff --git a/proposals/clocks/tools/witx/tests/multimodule/type_b.witx b/proposals/clocks/tools/witx/tests/witxt/multimodule/type_b.witx similarity index 100% rename from proposals/clocks/tools/witx/tests/multimodule/type_b.witx rename to proposals/clocks/tools/witx/tests/witxt/multimodule/type_b.witx diff --git a/proposals/clocks/tools/witx/tests/multimodule/type_c.witx b/proposals/clocks/tools/witx/tests/witxt/multimodule/type_c.witx similarity index 100% rename from proposals/clocks/tools/witx/tests/multimodule/type_c.witx rename to proposals/clocks/tools/witx/tests/witxt/multimodule/type_c.witx diff --git a/proposals/clocks/tools/witx/tests/witxt/representation.witxt b/proposals/clocks/tools/witx/tests/witxt/representation.witxt new file mode 100644 index 000000000..37d20a70a --- /dev/null +++ b/proposals/clocks/tools/witx/tests/witxt/representation.witxt @@ -0,0 +1,60 @@ +;; type names don't matter +(witx $a + (typename $a (flags (@witx bitflags u8) $b $c))) +(witx $b + (typename $b (flags (@witx bitflags u8) $b $c))) + +(assert_representable eq $a "a" $b "b") +(assert_representable eq $b "b" $a "a") + +(; TODO: perhaps add assertions eventually for document-level representability? +;; flags +(witx $a + (typename $a (flags (@witx bitflags u8) $b $c))) +(witx $b + (typename $b (flags (@witx bitflags u8) $b $c $d))) + +(assert_representable noteq $b "b" $a "a") +(assert_representable superset $a "a" $b "b") + +(witx $c + (typename $c (flags (@witx bitflags u8) $b $e))) +(assert_representable noteq $a "a" $c "c") +(assert_representable noteq $c "c" $a "a") + +(witx $d + (typename $d (flags (@witx bitflags u16) $b $c))) +(assert_representable noteq $a "a" $d "d") +(assert_representable superset $d "d" $a "a") +(assert_representable superset $d "d" $b "b") +;) + +;; enums +(witx $a + (typename $a (enum $b $c))) +(witx $b + (typename $b (enum $b $c $d))) +(assert_representable superset $a "a" $b "b") +(assert_representable noteq $b "b" $a "a") + +(witx $c + (typename $c (enum (@witx tag u16) $b $c))) +(assert_representable superset $c "c" $a "a") +(assert_representable superset $c "c" $b "b") + +;; unions +(witx $a + (typename $tag (enum $b $c)) + (typename $a (union (@witx tag $tag) u32 f32))) +(witx $b + (typename $tag (enum $b $c $d)) + (typename $b (union (@witx tag $tag) u32 f32 f64))) +(assert_representable superset $a "a" $b "b") +(assert_representable noteq $b "b" $a "a") + +(witx $c + (typename $tag (enum $b $c)) + (typename $c (variant (@witx tag $tag) (case $c f32) (case $b u32)))) +(assert_representable eq $a "a" $c "c") +(assert_representable eq $c "c" $a "a") +(assert_representable superset $c "c" $b "b") diff --git a/proposals/clocks/tools/witx/tests/witxt/simple.witxt b/proposals/clocks/tools/witx/tests/witxt/simple.witxt new file mode 100644 index 000000000..af2403043 --- /dev/null +++ b/proposals/clocks/tools/witx/tests/witxt/simple.witxt @@ -0,0 +1,12 @@ +(witx) + +(witx + (typename $x u32) +) + +(assert_invalid + (witx + (typename $x u32) + (typename $x u32) + ) + "Redefinition of name `x`") diff --git a/proposals/clocks/tools/witx/tests/witxt/union.witxt b/proposals/clocks/tools/witx/tests/witxt/union.witxt new file mode 100644 index 000000000..92be3dcd9 --- /dev/null +++ b/proposals/clocks/tools/witx/tests/witxt/union.witxt @@ -0,0 +1,97 @@ + +(witx + (typename $u (union u8)) +) +(witx + (typename $tag (enum (@witx tag u8) $c)) + (typename $u (union (@witx tag $tag) u8)) +) + +(witx + (typename $tag (enum $a $b)) + (typename $u (variant (@witx tag $tag) (case $a) (case $b u16))) +) + +(witx + (typename $tag (enum $a $b)) + (typename $u (variant (@witx tag $tag) (case $a) (case $b))) +) + + +(witx + (typename $u + (union + u8 + u16 + u32 + u64 + s8 + s16 + s32 + s64 + f32 + f64 + (@witx usize) + (@witx char8) + ) + ) +) + +(assert_invalid + (witx (typename $u (union (@witx tag $tag) u8 u16))) + "Unknown name `tag`" +) + +(assert_invalid + (witx + (typename $tag string) + (typename $u (union (@witx tag $tag) u8 u16)) + ) + "Wrong kind of name `tag`: expected enum or builtin, got list" +) + +(assert_invalid + (witx + (typename $tag (enum $c)) + (typename $u (variant (@witx tag $tag) (case $b u8))) + ) + "Invalid union field `b`: does not correspond to variant in tag `tag`" +) + +(assert_invalid + (witx + (typename $tag (enum $c)) + (typename $u (union (@witx tag $tag) f32 u8)) + ) + "Union expected 1 variants, found 2" +) + +(assert_invalid + (witx + (typename $tag (enum $c $d)) + (typename $u (union (@witx tag $tag) f32)) + ) + "Union expected 2 variants, found 1" +) + +(witx $d1 + (typename $tag (enum $a $b)) + (typename $u (union (@witx tag $tag) u8 u16)) +) + +(witx $d2 + (typename $tag (enum $a $b)) + (typename $u (variant (@witx tag $tag) (case $b u16) (case $a u8))) +) + +;; These two unions should be represented the same: +(assert_representable eq $d1 "u" $d2 "u") +(assert_representable eq $d2 "u" $d1 "u") + +;; Tag order doesnt matter for validation, but does for rep equality +(witx $d3 + (typename $tag (enum $b $a)) + (typename $u (union (@witx tag $tag) u16 u8)) +) + +(assert_representable noteq $d3 "u" $d1 "u") diff --git a/proposals/clocks/tools/witx/tests/witxt/wasi.witxt b/proposals/clocks/tools/witx/tests/witxt/wasi.witxt new file mode 100644 index 000000000..f654a7ee3 --- /dev/null +++ b/proposals/clocks/tools/witx/tests/witxt/wasi.witxt @@ -0,0 +1,26 @@ +;; Ensure that all current witx definitions in this repository load, parse, +;; roundtrip, and are documentable. + +(witx + (load "../../../../phases/old/snapshot_0/witx/wasi_unstable.witx")) +(witx + (load "../../../../phases/snapshot/witx/wasi_snapshot_preview1.witx")) + +(witx + (load + "../../../../phases/ephemeral/witx/wasi_ephemeral_args.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_clock.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_environ.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_fd.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_path.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_poll.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_proc.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_random.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_sched.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_sock.witx" + ) +) +;; should be singularly-loadable as well +(witx + (load + "../../../../phases/ephemeral/witx/wasi_ephemeral_fd.witx")) From 7ab2ac2b66604973853de14620d1a241be03195d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 11 Feb 2021 11:40:18 -0600 Subject: [PATCH 0860/1772] Add a new style of test suite for the `witx` tooling similar to `*.wast` (#392) * Add a wast-like testsuite for the witx tool As the functionality of `witx` grows this will hopefully make adding tests for new functionality as well as new kinds of tests easier. The goal is to make it very easy to drop a test file with various directives to exercise the functionality of `witx` and its internals. For now the testsuite is quite simple, simply asserting whether documents are either valid or invalid. My hope, though, is that this can be expanded over time with more styles of assertions directives. * Migrate union test to `union.witxt` * Add documentation/roundtrip testing to all documents * Translate multi-module test suite to `*.witxt` * Move wasi tests into `witxt` test suites * Convert representation tests to `*.witxt` * Rebased onto origin/main --- proposals/random/phases/ephemeral/docs.md | 4 +- proposals/random/tools/witx/Cargo.toml | 5 + proposals/random/tools/witx/src/lib.rs | 5 +- proposals/random/tools/witx/src/parser.rs | 5 +- .../random/tools/witx/src/representation.rs | 81 +--- proposals/random/tools/witx/src/toplevel.rs | 2 +- proposals/random/tools/witx/src/validate.rs | 34 +- .../random/tools/witx/tests/anonymous.rs | 43 -- .../random/tools/witx/tests/multimodule.rs | 58 --- proposals/random/tools/witx/tests/union.rs | 174 -------- .../witx/tests/{wasi.rs => wasi-docs.rs} | 64 --- proposals/random/tools/witx/tests/witxt.rs | 409 ++++++++++++++++++ .../tools/witx/tests/witxt/anonymous.witxt | 56 +++ .../tools/witx/tests/witxt/multimodule.witxt | 22 + .../{ => witxt}/multimodule/redefine_a.witx | 0 .../tests/{ => witxt}/multimodule/type_a.witx | 0 .../tests/{ => witxt}/multimodule/type_b.witx | 0 .../tests/{ => witxt}/multimodule/type_c.witx | 0 .../witx/tests/witxt/representation.witxt | 60 +++ .../tools/witx/tests/witxt/simple.witxt | 12 + .../random/tools/witx/tests/witxt/union.witxt | 97 +++++ .../random/tools/witx/tests/witxt/wasi.witxt | 26 ++ 22 files changed, 726 insertions(+), 431 deletions(-) delete mode 100644 proposals/random/tools/witx/tests/anonymous.rs delete mode 100644 proposals/random/tools/witx/tests/multimodule.rs delete mode 100644 proposals/random/tools/witx/tests/union.rs rename proposals/random/tools/witx/tests/{wasi.rs => wasi-docs.rs} (58%) create mode 100644 proposals/random/tools/witx/tests/witxt.rs create mode 100644 proposals/random/tools/witx/tests/witxt/anonymous.witxt create mode 100644 proposals/random/tools/witx/tests/witxt/multimodule.witxt rename proposals/random/tools/witx/tests/{ => witxt}/multimodule/redefine_a.witx (100%) rename proposals/random/tools/witx/tests/{ => witxt}/multimodule/type_a.witx (100%) rename proposals/random/tools/witx/tests/{ => witxt}/multimodule/type_b.witx (100%) rename proposals/random/tools/witx/tests/{ => witxt}/multimodule/type_c.witx (100%) create mode 100644 proposals/random/tools/witx/tests/witxt/representation.witxt create mode 100644 proposals/random/tools/witx/tests/witxt/simple.witxt create mode 100644 proposals/random/tools/witx/tests/witxt/union.witxt create mode 100644 proposals/random/tools/witx/tests/witxt/wasi.witxt diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 2cd2d1361..a3c0d0a47 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -871,12 +871,12 @@ Alignment: 8 - align: 8 - tag_size: 1 ### Variant cases +- `clock` + - `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) - `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) -- `clock` - ## `event`: Record An event that occurred. diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index 34c074d68..bf9ce16cd 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -23,3 +23,8 @@ wast = { version = "22.0.0", default-features = false } diff = "0.1.11" pretty_env_logger = "0.4" structopt = "0.3" +rayon = "1.0" + +[[test]] +name = "witxt" +harness = false diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 9c0f53060..2c876aa13 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -9,7 +9,7 @@ mod io; /// Calculate memory layout of types mod layout; /// Witx syntax parsing from SExprs -mod parser; +pub mod parser; /// Paths to witx documents for various proposal phases pub mod phases; /// Calculate required polyfill between interfaces @@ -28,10 +28,9 @@ pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, T pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use layout::{Layout, RecordMemberLayout, SizeAlign}; -pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; -pub use validate::ValidationError; +pub use validate::{DocValidation, ValidationError}; use std::path::{Path, PathBuf}; use thiserror::Error; diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 325eb1d35..19d1a0303 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -477,7 +477,6 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { None }; let mut fields = Vec::new(); - fields.push(parser.parse()?); while !parser.is_empty() { fields.push(parser.parse()?); } @@ -505,7 +504,9 @@ impl<'a> Parse<'a> for VariantSyntax<'a> { }; let mut cases = Vec::new(); while !parser.is_empty() { - cases.push(parser.parens(|p| p.parse())?); + let comments = parser.parse()?; + let item = parser.parens(|p| p.parse())?; + cases.push(Documented { comments, item }); } Ok(VariantSyntax { tag, cases }) } diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs index 99f73f5b6..589b64e39 100644 --- a/proposals/random/tools/witx/src/representation.rs +++ b/proposals/random/tools/witx/src/representation.rs @@ -81,12 +81,14 @@ impl Representable for Variant { let other_by_name = by .cases .iter() - .map(|c| (&c.name, c)) + .enumerate() + .map(|(i, c)| (&c.name, (c, i))) .collect::>(); // For each variant in self, must have variant of same name in by: - for v in self.cases.iter() { + for (i, v) in self.cases.iter().enumerate() { let other_ty = match other_by_name.get(&v.name) { - Some(other) => &other.tref, + Some((_, j)) if i != *j => return RepEquality::NotEq, + Some((other, _)) => &other.tref, None => return RepEquality::NotEq, }; match (&v.tref, other_ty) { @@ -157,76 +159,3 @@ impl Representable for Type { } } } - -#[cfg(test)] -mod test { - use super::*; - use crate::io::MockFs; - use crate::toplevel::parse_witx_with; - use crate::Id; - use std::rc::Rc; - - fn def_type(typename: &str, syntax: &str) -> Rc { - use std::path::Path; - let doc = parse_witx_with(&[Path::new("-")], &MockFs::new(&[("-", syntax)])) - .expect("parse witx doc"); - let t = doc.typename(&Id::new(typename)).expect("defined type"); - // Identity should always be true: - assert_eq!(t.representable(&t), RepEquality::Eq, "identity"); - t - } - - #[test] - fn different_typenames() { - let a = def_type("a", "(typename $a (flags (@witx bitflags u32) $b $c))"); - let d = def_type("d", "(typename $d (flags (@witx bitflags u32) $b $c))"); - - assert_eq!(a.representable(&d), RepEquality::Eq); - assert_eq!(d.representable(&a), RepEquality::Eq); - } - - #[test] - fn enum_() { - let base = def_type("a", "(typename $a (enum $b $c))"); - let extra_variant = def_type("a", "(typename $a (enum $b $c $d))"); - - assert_eq!(base.representable(&extra_variant), RepEquality::Superset); - assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); - - let smaller_size = def_type("a", "(typename $a (enum (@witx tag u16) $b $c))"); - assert_eq!(smaller_size.representable(&base), RepEquality::Superset); - assert_eq!( - smaller_size.representable(&extra_variant), - RepEquality::Superset - ); - } - - #[test] - fn union() { - let base = def_type( - "a", - "(typename $tag (enum (@witx tag u8) $b $c)) - (typename $a (union (@witx tag $tag) u32 f32))", - ); - let extra_variant = def_type( - "a", - "(typename $tag (enum (@witx tag u8) $b $c $d)) - (typename $a (union (@witx tag $tag) u32 f32 f64))", - ); - - assert_eq!(base.representable(&extra_variant), RepEquality::Superset); - assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); - - let other_ordering = def_type( - "a", - "(typename $tag (enum (@witx tag u8) $b $c)) - (typename $a (variant (@witx tag $tag) (case $c f32) (case $b u32)))", - ); - assert_eq!(base.representable(&other_ordering), RepEquality::Eq); - assert_eq!(other_ordering.representable(&base), RepEquality::Eq); - assert_eq!( - other_ordering.representable(&extra_variant), - RepEquality::Superset - ); - } -} diff --git a/proposals/random/tools/witx/src/toplevel.rs b/proposals/random/tools/witx/src/toplevel.rs index 993fc8cc4..83e940c7c 100644 --- a/proposals/random/tools/witx/src/toplevel.rs +++ b/proposals/random/tools/witx/src/toplevel.rs @@ -32,7 +32,7 @@ fn _parse_witx_with(paths: &[&Path], io: &dyn WitxIo) -> Result, + entries: HashMap, constant_scopes: HashMap, } @@ -155,6 +155,10 @@ impl DocValidation { path, } } + + pub fn into_document(self, defs: Vec) -> Document { + Document::new(defs, self.entries) + } } impl DocValidationScope<'_> { @@ -439,14 +443,16 @@ impl DocValidationScope<'_> { } } - let mut names = names.map(|names| names.into_iter().collect::>()); + let mut name_set = names + .as_ref() + .map(|names| names.iter().collect::>()); - let cases = syntax + let mut cases = syntax .cases .iter() .map(|case| { let name = Id::new(case.item.name.name()); - if let Some(names) = &mut names { + if let Some(names) = &mut name_set { if !names.remove(&name) { return Err(ValidationError::InvalidUnionField { name: name.as_str().to_string(), @@ -467,6 +473,18 @@ impl DocValidationScope<'_> { }) }) .collect::, _>>()?; + + // If we have an explicit tag with an enum then that's instructing us to + // reorder cases based on the order of the enum itself, so do that here. + if let Some(names) = names { + let name_pos = names + .iter() + .enumerate() + .map(|(i, name)| (name, i)) + .collect::>(); + cases.sort_by_key(|c| name_pos[&&c.name]); + } + Ok(Variant { tag_repr, cases }) } diff --git a/proposals/random/tools/witx/tests/anonymous.rs b/proposals/random/tools/witx/tests/anonymous.rs deleted file mode 100644 index 6cfb2ea7e..000000000 --- a/proposals/random/tools/witx/tests/anonymous.rs +++ /dev/null @@ -1,43 +0,0 @@ -use witx; - -fn is_anonymous_record_err(r: Result) -> bool { - match r { - Err(witx::WitxError::Validation(witx::ValidationError::AnonymousRecord { .. })) => true, - _ => false, - } -} - -#[test] -fn anonymous_types() { - let pointer_to_record = witx::parse("(typename $a (@witx pointer (record (field $b u8))))"); - assert!(is_anonymous_record_err(pointer_to_record)); - - let pointer_to_union = - witx::parse("(typename $tag (enum $b)) (typename $a (@witx pointer (union u8)))"); - assert!(is_anonymous_record_err(pointer_to_union)); - - let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum $b)))"); - assert!(is_anonymous_record_err(pointer_to_enum)); - - let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags $b)))"); - assert!(is_anonymous_record_err(pointer_to_flags)); - - let pointer_to_handle = witx::parse("(typename $a (@witx pointer (handle)))"); - assert!(is_anonymous_record_err(pointer_to_handle)); - - let pointer_to_builtin = witx::parse("(typename $a (@witx pointer u8))"); - assert!(pointer_to_builtin.is_ok()); - - let pointer_to_pointer = witx::parse("(typename $a (@witx pointer (@witx const_pointer u8)))"); - assert!(pointer_to_pointer.is_ok()); - - let record_in_record = witx::parse("(typename $a (record (field $b (record (field $c u8)))))"); - assert!(is_anonymous_record_err(record_in_record)); - - let union_in_record = - witx::parse("(typename $tag (enum $c)) (typename $a (record (field $b (union u8))))"); - assert!(is_anonymous_record_err(union_in_record)); - - let pointer_in_record = witx::parse("(typename $a (record (field $b (@witx pointer u8))))"); - assert!(pointer_in_record.is_ok()) -} diff --git a/proposals/random/tools/witx/tests/multimodule.rs b/proposals/random/tools/witx/tests/multimodule.rs deleted file mode 100644 index a6c773363..000000000 --- a/proposals/random/tools/witx/tests/multimodule.rs +++ /dev/null @@ -1,58 +0,0 @@ -use witx::{load, BuiltinType, Id, Type, TypeRef}; - -#[test] -fn validate_multimodule() { - // B uses A, and C uses A. - let doc = load(&[ - "tests/multimodule/type_b.witx", - "tests/multimodule/type_c.witx", - ]) - .unwrap_or_else(|e| panic!("failed to validate: {}", e)); - - //println!("{}", doc); - - // Check that the `a` both modules use is what we expect: - let type_a = doc.typename(&Id::new("a")).expect("type a exists"); - assert_eq!( - *type_a.type_(), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: false - }) - ); - - // `b` is a struct with a single member of type `a` - let type_b = doc.typename(&Id::new("b")).expect("type b exists"); - match &*type_b.type_() { - Type::Record(record) => { - assert_eq!(record.members.len(), 1); - assert_eq!( - record.members.get(0).unwrap().tref, - TypeRef::Name(type_a.clone()) - ); - } - _ => panic!("b is a struct"), - } - - // `c` is a struct with a two members of type `a` - let type_c = doc.typename(&Id::new("c")).expect("type c exists"); - match &*type_c.type_() { - Type::Record(record) => { - assert_eq!(record.members.len(), 2); - assert_eq!( - record.members.get(0).unwrap().tref, - TypeRef::Name(type_a.clone()) - ); - assert_eq!(record.members.get(1).unwrap().tref, TypeRef::Name(type_a)); - } - _ => panic!("c is a struct"), - } -} - -#[test] -fn multimodule_reject_redefinition() { - assert!(load(&[ - "tests/multimodule/type_a.witx", - "tests/multimodule/redefine_a.witx", - ]) - .is_err()) -} diff --git a/proposals/random/tools/witx/tests/union.rs b/proposals/random/tools/witx/tests/union.rs deleted file mode 100644 index 31ade263a..000000000 --- a/proposals/random/tools/witx/tests/union.rs +++ /dev/null @@ -1,174 +0,0 @@ -// Every worker needs a union! Time to organize -use witx::{Id, Representable}; - -#[test] -fn one_variant_union() { - let d = witx::parse( - "(typename $tag (enum $c)) - (typename $u (union (@witx tag $tag) u8))", - ); - assert!(d.is_ok()); -} - -#[test] -fn two_variant_union() { - let d1 = witx::parse( - "(typename $tag (enum $a $b)) - (typename $u (union (@witx tag $tag) u8 u16))", - ); - assert!(d1.is_ok(), "d1 is ok"); - - // Fields can come in whatever order: - let d2 = witx::parse( - "(typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $b u16) (case $a u8)))", - ); - assert!(d2.is_ok(), "d2 is ok"); - - // These two unions should be represented the same: - let u1 = d1.unwrap().typename(&Id::new("u")).unwrap().type_(); - let u2 = d2.unwrap().typename(&Id::new("u")).unwrap().type_(); - - assert_eq!( - u1.representable(&u2), - witx::RepEquality::Eq, - "u1 can represent u2" - ); - assert_eq!( - u2.representable(&u1), - witx::RepEquality::Eq, - "u2 can represent u1" - ); - - // Tag order doesnt matter for validation - let d3 = witx::parse( - "(typename $tag (enum $b $a)) - (typename $u (union (@witx tag $tag) u16 u8))", - ); - assert!(d3.is_ok(), "d2 is ok"); -} - -#[test] -fn empty_variant_unions() { - let d1 = witx::parse( - "(typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $a) (case $b u16)))", - ); - assert!(d1.is_ok(), "d1 is ok"); - - let d2 = witx::parse( - "(typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $a) (case $b)))", - ); - assert!(d2.is_ok(), "d2 is ok"); -} - -#[test] -fn many_variant_unions() { - let d1 = witx::parse( - "(typename $tag (enum $a $b $c $d $e $f $g $h $i $j $k $l $m)) - (typename $u - (variant (@witx tag $tag) - (case $a u8) - (case $b u16) - (case $c u32) - (case $d u64) - (case $e s8) - (case $f s16) - (case $g s32) - (case $h s64) - (case $i f32) - (case $j f64) - (case $k (@witx usize)) - (case $l (@witx char8)) - (case $m) - ) - )", - ); - assert!(d1.is_ok(), "d1 is ok"); -} - -#[test] -fn no_tag_union() { - let d = witx::parse("(typename $u (union $tag (field $a u8) (field $b u16)))"); - assert!(d.is_err()); -} - -#[test] -fn wrong_kind_tag_union() { - let d = witx::parse( - "(typename $tag string) - (typename $u (union (@witx tag $tag) u8 u16))", - ); - let (expected, got) = wrong_kind_name_err(d).expect("wrong kind of tag"); - assert_eq!(expected, "enum or builtin"); - assert_eq!(got, "list"); -} - -#[test] -fn bad_field_unions() { - let d = witx::parse( - "(typename $tag (enum $c)) - (typename $u (variant (@witx tag $tag) (case $b u8)))", - ); - match validation_err(d) { - witx::ValidationError::InvalidUnionField { name, reason, .. } => { - assert_eq!(name, "b", "bad field name union 1"); - assert_eq!( - reason, "does not correspond to variant in tag `tag`", - "reason union 1" - ); - } - other => panic!("bad error: {}", other), - } - - let d = witx::parse( - "(typename $tag (enum $c)) - (typename $u (variant (@witx tag $tag) (case $c f32) (case $b u8)))", - ); - match validation_err(d) { - witx::ValidationError::UnionSizeMismatch { .. } => {} - other => panic!("bad error: {}", other), - } - - let d = witx::parse( - "(typename $tag (enum $c $d)) - (typename $u (variant (@witx tag $tag) (case $c f32)))", - ); - match validation_err(d) { - witx::ValidationError::UnionSizeMismatch { .. } => {} - other => panic!("bad error: {}", other), - } -} - -fn wrong_kind_name_err( - r: Result, -) -> Option<(&'static str, &'static str)> { - match r { - Err(witx::WitxError::Validation(witx::ValidationError::WrongKindName { - expected, - got, - .. - })) => Some((expected, got)), - Err(e) => { - eprintln!("expected WrongKindName ValidationError, got: {:?}", e); - None - } - Ok(_) => { - eprintln!("expected WrongKindName ValidationError: Ok(witx::Document)"); - None - } - } -} - -fn validation_err(r: Result) -> witx::ValidationError { - match r { - Err(witx::WitxError::Validation(e)) => e, - Err(e) => { - panic!("expected ValidationError, got: {:?}", e) - } - Ok(_) => { - panic!("expected ValidationError, got: Ok(witx::Document)") - } - } -} diff --git a/proposals/random/tools/witx/tests/wasi.rs b/proposals/random/tools/witx/tests/wasi-docs.rs similarity index 58% rename from proposals/random/tools/witx/tests/wasi.rs rename to proposals/random/tools/witx/tests/wasi-docs.rs index 27300a26e..6702edfbd 100644 --- a/proposals/random/tools/witx/tests/wasi.rs +++ b/proposals/random/tools/witx/tests/wasi-docs.rs @@ -2,24 +2,6 @@ use std::fs; use std::path::Path; use witx::{self, Documentation}; -#[test] -fn validate_wasi_snapshot() { - witx::load(&witx::phases::snapshot().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); -} - -#[test] -fn validate_wasi_ephemeral() { - witx::load(&witx::phases::ephemeral().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); -} - -#[test] -fn validate_wasi_old_snapshot_0() { - witx::load(&witx::phases::old::snapshot_0().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); -} - #[test] fn validate_docs() { for phase in &[ @@ -32,52 +14,6 @@ fn validate_docs() { } } -#[test] -fn render_roundtrip() { - let doc = witx::load(&witx::phases::snapshot().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); - - let back_to_sexprs = format!("{}", doc); - println!("{}", back_to_sexprs); - - let doc2 = witx::parse(&back_to_sexprs) - .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) - .unwrap(); - - // I'd just assert_eq, but when it fails the debug print is thousands of lines long and impossible - // to figure out where they are unequal. - if doc != doc2 { - for type_ in doc.typenames() { - let type2 = doc2.typename(&type_.name).expect("doc2 missing datatype"); - assert_eq!(type_, type2); - } - for mod_ in doc.modules() { - let mod2 = doc2.module(&mod_.name).expect("doc2 missing module"); - for import in mod_.imports() { - let import2 = mod2.import(&import.name).expect("mod2 missing import"); - assert_eq!(import, import2); - } - for func in mod_.funcs() { - let func2 = mod2.func(&func.name).expect("mod2 missing func"); - assert_eq!(func, func2); - } - } - } - // This should be equivalent to the above, but just in case some code changes where it isnt: - assert_eq!(doc, doc2); -} - -#[test] -fn document_wasi_snapshot() { - use witx::Documentation; - println!( - "{}", - witx::load(&witx::phases::snapshot().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)) - .to_md() - ); -} - fn dos2unix(s: &str) -> String { let mut t = String::new(); t.reserve(s.len()); diff --git a/proposals/random/tools/witx/tests/witxt.rs b/proposals/random/tools/witx/tests/witxt.rs new file mode 100644 index 000000000..1056947a3 --- /dev/null +++ b/proposals/random/tools/witx/tests/witxt.rs @@ -0,0 +1,409 @@ +//! You can run this test suite with: +//! +//! cargo test --test witxt +//! +//! An argument can be passed as well to filter, based on filename, which test +//! to run +//! +//! cargo test --test witxt foo.witxt + +use anyhow::{anyhow, bail, Context, Result}; +use rayon::prelude::*; +use std::collections::HashMap; +use std::path::{Path, PathBuf}; +use std::str; +use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; +use wast::parser::{self, Parse, ParseBuffer, Parser}; +use witx::{Documentation, Representable}; + +fn main() { + let tests = find_tests(); + let filter = std::env::args().nth(1); + + let tests = tests + .par_iter() + .filter_map(|test| { + if let Some(filter) = &filter { + if let Some(s) = test.to_str() { + if !s.contains(filter) { + return None; + } + } + } + let contents = std::fs::read(test).unwrap(); + Some((test, contents)) + }) + .collect::>(); + + println!("running {} test files\n", tests.len()); + + let ntests = AtomicUsize::new(0); + let errors = tests + .par_iter() + .filter_map(|(test, contents)| { + WitxtRunner { + ntests: &ntests, + documents: HashMap::new(), + } + .run(test, contents) + .err() + }) + .collect::>(); + + if !errors.is_empty() { + for msg in errors.iter() { + eprintln!("{:?}", msg); + } + + panic!("{} tests failed", errors.len()) + } + + println!( + "test result: ok. {} directives passed\n", + ntests.load(SeqCst) + ); +} + +/// Recursively finds all tests in a whitelisted set of directories which we +/// then load up and test in parallel. +fn find_tests() -> Vec { + let mut tests = Vec::new(); + find_tests("tests/witxt".as_ref(), &mut tests); + tests.sort(); + return tests; + + fn find_tests(path: &Path, tests: &mut Vec) { + for f in path.read_dir().unwrap() { + let f = f.unwrap(); + if f.file_type().unwrap().is_dir() { + find_tests(&f.path(), tests); + continue; + } + + match f.path().extension().and_then(|s| s.to_str()) { + Some("witxt") => {} + _ => continue, + } + tests.push(f.path()); + } + } +} + +struct WitxtRunner<'a> { + ntests: &'a AtomicUsize, + documents: HashMap, +} + +impl WitxtRunner<'_> { + fn run(&mut self, test: &Path, contents: &[u8]) -> Result<()> { + let contents = str::from_utf8(contents)?; + macro_rules! adjust { + ($e:expr) => {{ + let mut e = wast::Error::from($e); + e.set_path(test); + e.set_text(contents); + e + }}; + } + let buf = ParseBuffer::new(contents).map_err(|e| adjust!(e))?; + let witxt = parser::parse::(&buf).map_err(|e| adjust!(e))?; + + let errors = witxt + .directives + .into_iter() + .filter_map(|directive| { + let (line, col) = directive.span().linecol_in(contents); + self.test_directive(contents, test, directive) + .with_context(|| { + format!( + "failed directive on {}:{}:{}", + test.display(), + line + 1, + col + 1 + ) + }) + .err() + }) + .collect::>(); + if errors.is_empty() { + return Ok(()); + } + let mut s = format!("{} test failures in {}:", errors.len(), test.display()); + for mut error in errors { + if let Some(err) = error.downcast_mut::() { + err.set_path(test); + err.set_text(contents); + } + s.push_str("\n\n\t--------------------------------\n\n\t"); + s.push_str(&format!("{:?}", error).replace("\n", "\n\t")); + } + bail!("{}", s) + } + + fn test_directive( + &mut self, + contents: &str, + test: &Path, + directive: WitxtDirective, + ) -> Result<()> { + self.bump_ntests(); + match directive { + WitxtDirective::Witx(witx) => { + let doc = witx.document(contents, test)?; + self.assert_roundtrip(&doc) + .context("failed to round-trip the document")?; + self.assert_md(&doc)?; + if let Some(name) = witx.id { + self.documents.insert(name.name().to_string(), doc); + } + } + WitxtDirective::AssertInvalid { witx, message, .. } => { + let err = match witx.document(contents, test) { + Ok(_) => bail!("witx was valid when it shouldn't be"), + Err(e) => format!("{:?}", anyhow::Error::from(e)), + }; + if !err.contains(message) { + bail!("expected error {:?}\nfound error {}", message, err); + } + } + WitxtDirective::AssertRepresentable { repr, t1, t2, .. } => { + let (t1m, t1t) = t1; + let (t2m, t2t) = t2; + let t1d = self + .documents + .get(t1m.name()) + .ok_or_else(|| anyhow!("no document named {:?}", t1m.name()))?; + let t2d = self + .documents + .get(t2m.name()) + .ok_or_else(|| anyhow!("no document named {:?}", t2m.name()))?; + let t1 = t1d + .typename(&witx::Id::new(t1t)) + .ok_or_else(|| anyhow!("no type named {:?}", t1t))?; + let t2 = t2d + .typename(&witx::Id::new(t2t)) + .ok_or_else(|| anyhow!("no type named {:?}", t2t))?; + match (repr, t1.type_().representable(&t2.type_())) { + (RepEquality::Eq, witx::RepEquality::Eq) + | (RepEquality::Superset, witx::RepEquality::Superset) + | (RepEquality::NotEq, witx::RepEquality::NotEq) => {} + (a, b) => { + bail!("expected {:?} representation, got {:?}", a, b); + } + } + } + } + Ok(()) + } + + fn assert_roundtrip(&self, doc: &witx::Document) -> Result<()> { + self.bump_ntests(); + let back_to_sexprs = format!("{}", doc); + let doc2 = witx::parse(&back_to_sexprs)?; + if *doc == doc2 { + return Ok(()); + } + + // Try to get a more specific error message that isn't thousands of + // lines long of debug representations. + for type_ in doc.typenames() { + let type2 = match doc2.typename(&type_.name) { + Some(t) => t, + None => bail!("doc2 missing datatype"), + }; + if type_ != type2 { + bail!("types are not equal\n{:?}\n !=\n{:?}", type_, type2); + } + } + for mod_ in doc.modules() { + let mod2 = match doc2.module(&mod_.name) { + Some(m) => m, + None => bail!("doc2 missing module"), + }; + for import in mod_.imports() { + let import2 = match mod2.import(&import.name) { + Some(i) => i, + None => bail!("mod2 missing import"), + }; + assert_eq!(import, import2); + } + for func in mod_.funcs() { + let func2 = match mod2.func(&func.name) { + Some(f) => f, + None => bail!("mod2 missing func"), + }; + assert_eq!(func, func2); + } + } + bail!("{:?} != {:?}", doc, doc2) + } + + fn assert_md(&self, doc: &witx::Document) -> Result<()> { + self.bump_ntests(); + doc.to_md(); + Ok(()) + } + + fn bump_ntests(&self) { + self.ntests.fetch_add(1, SeqCst); + } +} + +mod kw { + wast::custom_keyword!(assert_invalid); + wast::custom_keyword!(assert_representable); + wast::custom_keyword!(witx); + wast::custom_keyword!(eq); + wast::custom_keyword!(noteq); + wast::custom_keyword!(load); + wast::custom_keyword!(superset); +} + +struct Witxt<'a> { + directives: Vec>, +} + +impl<'a> Parse<'a> for Witxt<'a> { + fn parse(parser: Parser<'a>) -> parser::Result { + let mut directives = Vec::new(); + while !parser.is_empty() { + directives.push(parser.parens(|p| p.parse())?); + } + Ok(Witxt { directives }) + } +} + +enum WitxtDirective<'a> { + Witx(Witx<'a>), + AssertInvalid { + span: wast::Span, + witx: Witx<'a>, + message: &'a str, + }, + AssertRepresentable { + span: wast::Span, + repr: RepEquality, + t1: (wast::Id<'a>, &'a str), + t2: (wast::Id<'a>, &'a str), + }, +} + +impl WitxtDirective<'_> { + fn span(&self) -> wast::Span { + match self { + WitxtDirective::Witx(w) => w.span, + WitxtDirective::AssertInvalid { span, .. } + | WitxtDirective::AssertRepresentable { span, .. } => *span, + } + } +} + +impl<'a> Parse<'a> for WitxtDirective<'a> { + fn parse(parser: Parser<'a>) -> parser::Result { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(WitxtDirective::Witx(parser.parse()?)) + } else if l.peek::() { + let span = parser.parse::()?.0; + Ok(WitxtDirective::AssertInvalid { + span, + witx: parser.parens(|p| p.parse())?, + message: parser.parse()?, + }) + } else if l.peek::() { + let span = parser.parse::()?.0; + Ok(WitxtDirective::AssertRepresentable { + span, + repr: parser.parse()?, + t1: (parser.parse()?, parser.parse()?), + t2: (parser.parse()?, parser.parse()?), + }) + } else { + Err(l.error()) + } + } +} + +struct Witx<'a> { + span: wast::Span, + id: Option>, + def: WitxDef<'a>, +} + +enum WitxDef<'a> { + Fs(Vec<&'a str>), + Inline(Vec>>), +} + +impl Witx<'_> { + fn document(&self, contents: &str, file: &Path) -> Result { + match &self.def { + WitxDef::Inline(decls) => { + let mut validator = witx::DocValidation::new(); + let mut definitions = Vec::new(); + for decl in decls { + validator + .scope(contents, file) + .validate_decl(&decl.item, &decl.comments, &mut definitions) + .map_err(witx::WitxError::Validation)?; + } + Ok(validator.into_document(definitions)) + } + WitxDef::Fs(paths) => { + let parent = file.parent().unwrap(); + let paths = paths.iter().map(|p| parent.join(p)).collect::>(); + Ok(witx::load(&paths)?) + } + } + } +} + +impl<'a> Parse<'a> for Witx<'a> { + fn parse(parser: Parser<'a>) -> parser::Result { + let span = parser.parse::()?.0; + let id = parser.parse()?; + + let def = if parser.peek2::() { + parser.parens(|p| { + p.parse::()?; + let mut paths = Vec::new(); + while !p.is_empty() { + paths.push(p.parse()?); + } + Ok(WitxDef::Fs(paths)) + })? + } else { + let mut decls = Vec::new(); + while !parser.is_empty() { + decls.push(parser.parens(|p| p.parse())?); + } + WitxDef::Inline(decls) + }; + Ok(Witx { id, span, def }) + } +} + +#[derive(Debug)] +enum RepEquality { + Eq, + NotEq, + Superset, +} + +impl<'a> Parse<'a> for RepEquality { + fn parse(parser: Parser<'a>) -> parser::Result { + let mut l = parser.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(RepEquality::Eq) + } else if l.peek::() { + parser.parse::()?; + Ok(RepEquality::NotEq) + } else if l.peek::() { + parser.parse::()?; + Ok(RepEquality::Superset) + } else { + Err(l.error()) + } + } +} diff --git a/proposals/random/tools/witx/tests/witxt/anonymous.witxt b/proposals/random/tools/witx/tests/witxt/anonymous.witxt new file mode 100644 index 000000000..0ed3bc0d2 --- /dev/null +++ b/proposals/random/tools/witx/tests/witxt/anonymous.witxt @@ -0,0 +1,56 @@ +;; Ensure that anonymous structured types are not allowed in type positions at +;; this time, everything has to be named to assist in binding in languages. + +(assert_invalid + (witx + (typename $a (@witx pointer (record (field $b u8)))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (@witx pointer (union))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (@witx pointer (enum $b))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (@witx pointer (flags $b))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (@witx pointer (handle))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (record (field $b (record (field $c u8))))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $tag (enum $c)) + (typename $a (record (field $b (union)))) + ) + "Anonymous structured types") + + +;; pointers don't count for anonymous indirections +(witx + (typename $a (@witx pointer u8))) + +(witx + (typename $a (@witx pointer (@witx const_pointer u8)))) + +(witx + (typename $a (record (field $b (@witx pointer u8))))) diff --git a/proposals/random/tools/witx/tests/witxt/multimodule.witxt b/proposals/random/tools/witx/tests/witxt/multimodule.witxt new file mode 100644 index 000000000..d8b6559ac --- /dev/null +++ b/proposals/random/tools/witx/tests/witxt/multimodule.witxt @@ -0,0 +1,22 @@ +;; B uses A, and C uses A. +(witx $multi + (load "multimodule/type_b.witx" "multimodule/type_c.witx") +) + +(witx $reference + (typename $a u32) + (typename $b (record (field $member_a $a))) + (typename $c (record (field $first_a $a) (field $second_a $a))) +) + +(assert_representable eq $reference "a" $multi "a") +(assert_representable eq $reference "b" $multi "b") +(assert_representable eq $reference "c" $multi "c") + +(assert_invalid + (witx + (load + "multimodule/type_a.witx" + "multimodule/redefine_a.witx") + ) + "Redefinition of name `a`") diff --git a/proposals/random/tools/witx/tests/multimodule/redefine_a.witx b/proposals/random/tools/witx/tests/witxt/multimodule/redefine_a.witx similarity index 100% rename from proposals/random/tools/witx/tests/multimodule/redefine_a.witx rename to proposals/random/tools/witx/tests/witxt/multimodule/redefine_a.witx diff --git a/proposals/random/tools/witx/tests/multimodule/type_a.witx b/proposals/random/tools/witx/tests/witxt/multimodule/type_a.witx similarity index 100% rename from proposals/random/tools/witx/tests/multimodule/type_a.witx rename to proposals/random/tools/witx/tests/witxt/multimodule/type_a.witx diff --git a/proposals/random/tools/witx/tests/multimodule/type_b.witx b/proposals/random/tools/witx/tests/witxt/multimodule/type_b.witx similarity index 100% rename from proposals/random/tools/witx/tests/multimodule/type_b.witx rename to proposals/random/tools/witx/tests/witxt/multimodule/type_b.witx diff --git a/proposals/random/tools/witx/tests/multimodule/type_c.witx b/proposals/random/tools/witx/tests/witxt/multimodule/type_c.witx similarity index 100% rename from proposals/random/tools/witx/tests/multimodule/type_c.witx rename to proposals/random/tools/witx/tests/witxt/multimodule/type_c.witx diff --git a/proposals/random/tools/witx/tests/witxt/representation.witxt b/proposals/random/tools/witx/tests/witxt/representation.witxt new file mode 100644 index 000000000..37d20a70a --- /dev/null +++ b/proposals/random/tools/witx/tests/witxt/representation.witxt @@ -0,0 +1,60 @@ +;; type names don't matter +(witx $a + (typename $a (flags (@witx bitflags u8) $b $c))) +(witx $b + (typename $b (flags (@witx bitflags u8) $b $c))) + +(assert_representable eq $a "a" $b "b") +(assert_representable eq $b "b" $a "a") + +(; TODO: perhaps add assertions eventually for document-level representability? +;; flags +(witx $a + (typename $a (flags (@witx bitflags u8) $b $c))) +(witx $b + (typename $b (flags (@witx bitflags u8) $b $c $d))) + +(assert_representable noteq $b "b" $a "a") +(assert_representable superset $a "a" $b "b") + +(witx $c + (typename $c (flags (@witx bitflags u8) $b $e))) +(assert_representable noteq $a "a" $c "c") +(assert_representable noteq $c "c" $a "a") + +(witx $d + (typename $d (flags (@witx bitflags u16) $b $c))) +(assert_representable noteq $a "a" $d "d") +(assert_representable superset $d "d" $a "a") +(assert_representable superset $d "d" $b "b") +;) + +;; enums +(witx $a + (typename $a (enum $b $c))) +(witx $b + (typename $b (enum $b $c $d))) +(assert_representable superset $a "a" $b "b") +(assert_representable noteq $b "b" $a "a") + +(witx $c + (typename $c (enum (@witx tag u16) $b $c))) +(assert_representable superset $c "c" $a "a") +(assert_representable superset $c "c" $b "b") + +;; unions +(witx $a + (typename $tag (enum $b $c)) + (typename $a (union (@witx tag $tag) u32 f32))) +(witx $b + (typename $tag (enum $b $c $d)) + (typename $b (union (@witx tag $tag) u32 f32 f64))) +(assert_representable superset $a "a" $b "b") +(assert_representable noteq $b "b" $a "a") + +(witx $c + (typename $tag (enum $b $c)) + (typename $c (variant (@witx tag $tag) (case $c f32) (case $b u32)))) +(assert_representable eq $a "a" $c "c") +(assert_representable eq $c "c" $a "a") +(assert_representable superset $c "c" $b "b") diff --git a/proposals/random/tools/witx/tests/witxt/simple.witxt b/proposals/random/tools/witx/tests/witxt/simple.witxt new file mode 100644 index 000000000..af2403043 --- /dev/null +++ b/proposals/random/tools/witx/tests/witxt/simple.witxt @@ -0,0 +1,12 @@ +(witx) + +(witx + (typename $x u32) +) + +(assert_invalid + (witx + (typename $x u32) + (typename $x u32) + ) + "Redefinition of name `x`") diff --git a/proposals/random/tools/witx/tests/witxt/union.witxt b/proposals/random/tools/witx/tests/witxt/union.witxt new file mode 100644 index 000000000..92be3dcd9 --- /dev/null +++ b/proposals/random/tools/witx/tests/witxt/union.witxt @@ -0,0 +1,97 @@ + +(witx + (typename $u (union u8)) +) +(witx + (typename $tag (enum (@witx tag u8) $c)) + (typename $u (union (@witx tag $tag) u8)) +) + +(witx + (typename $tag (enum $a $b)) + (typename $u (variant (@witx tag $tag) (case $a) (case $b u16))) +) + +(witx + (typename $tag (enum $a $b)) + (typename $u (variant (@witx tag $tag) (case $a) (case $b))) +) + + +(witx + (typename $u + (union + u8 + u16 + u32 + u64 + s8 + s16 + s32 + s64 + f32 + f64 + (@witx usize) + (@witx char8) + ) + ) +) + +(assert_invalid + (witx (typename $u (union (@witx tag $tag) u8 u16))) + "Unknown name `tag`" +) + +(assert_invalid + (witx + (typename $tag string) + (typename $u (union (@witx tag $tag) u8 u16)) + ) + "Wrong kind of name `tag`: expected enum or builtin, got list" +) + +(assert_invalid + (witx + (typename $tag (enum $c)) + (typename $u (variant (@witx tag $tag) (case $b u8))) + ) + "Invalid union field `b`: does not correspond to variant in tag `tag`" +) + +(assert_invalid + (witx + (typename $tag (enum $c)) + (typename $u (union (@witx tag $tag) f32 u8)) + ) + "Union expected 1 variants, found 2" +) + +(assert_invalid + (witx + (typename $tag (enum $c $d)) + (typename $u (union (@witx tag $tag) f32)) + ) + "Union expected 2 variants, found 1" +) + +(witx $d1 + (typename $tag (enum $a $b)) + (typename $u (union (@witx tag $tag) u8 u16)) +) + +(witx $d2 + (typename $tag (enum $a $b)) + (typename $u (variant (@witx tag $tag) (case $b u16) (case $a u8))) +) + +;; These two unions should be represented the same: +(assert_representable eq $d1 "u" $d2 "u") +(assert_representable eq $d2 "u" $d1 "u") + +;; Tag order doesnt matter for validation, but does for rep equality +(witx $d3 + (typename $tag (enum $b $a)) + (typename $u (union (@witx tag $tag) u16 u8)) +) + +(assert_representable noteq $d3 "u" $d1 "u") diff --git a/proposals/random/tools/witx/tests/witxt/wasi.witxt b/proposals/random/tools/witx/tests/witxt/wasi.witxt new file mode 100644 index 000000000..f654a7ee3 --- /dev/null +++ b/proposals/random/tools/witx/tests/witxt/wasi.witxt @@ -0,0 +1,26 @@ +;; Ensure that all current witx definitions in this repository load, parse, +;; roundtrip, and are documentable. + +(witx + (load "../../../../phases/old/snapshot_0/witx/wasi_unstable.witx")) +(witx + (load "../../../../phases/snapshot/witx/wasi_snapshot_preview1.witx")) + +(witx + (load + "../../../../phases/ephemeral/witx/wasi_ephemeral_args.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_clock.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_environ.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_fd.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_path.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_poll.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_proc.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_random.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_sched.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_sock.witx" + ) +) +;; should be singularly-loadable as well +(witx + (load + "../../../../phases/ephemeral/witx/wasi_ephemeral_fd.witx")) From 39c791705cc3d130691cc831b875a0b9339225c7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 11 Feb 2021 11:40:18 -0600 Subject: [PATCH 0861/1772] Add a new style of test suite for the `witx` tooling similar to `*.wast` (#392) * Add a wast-like testsuite for the witx tool As the functionality of `witx` grows this will hopefully make adding tests for new functionality as well as new kinds of tests easier. The goal is to make it very easy to drop a test file with various directives to exercise the functionality of `witx` and its internals. For now the testsuite is quite simple, simply asserting whether documents are either valid or invalid. My hope, though, is that this can be expanded over time with more styles of assertions directives. * Migrate union test to `union.witxt` * Add documentation/roundtrip testing to all documents * Translate multi-module test suite to `*.witxt` * Move wasi tests into `witxt` test suites * Convert representation tests to `*.witxt` * Rebased onto origin/main --- proposals/filesystem/phases/ephemeral/docs.md | 4 +- proposals/filesystem/tools/witx/Cargo.toml | 5 + proposals/filesystem/tools/witx/src/lib.rs | 5 +- proposals/filesystem/tools/witx/src/parser.rs | 5 +- .../tools/witx/src/representation.rs | 81 +--- .../filesystem/tools/witx/src/toplevel.rs | 2 +- .../filesystem/tools/witx/src/validate.rs | 34 +- .../filesystem/tools/witx/tests/anonymous.rs | 43 -- .../tools/witx/tests/multimodule.rs | 58 --- .../filesystem/tools/witx/tests/union.rs | 174 -------- .../witx/tests/{wasi.rs => wasi-docs.rs} | 64 --- .../filesystem/tools/witx/tests/witxt.rs | 409 ++++++++++++++++++ .../tools/witx/tests/witxt/anonymous.witxt | 56 +++ .../tools/witx/tests/witxt/multimodule.witxt | 22 + .../{ => witxt}/multimodule/redefine_a.witx | 0 .../tests/{ => witxt}/multimodule/type_a.witx | 0 .../tests/{ => witxt}/multimodule/type_b.witx | 0 .../tests/{ => witxt}/multimodule/type_c.witx | 0 .../witx/tests/witxt/representation.witxt | 60 +++ .../tools/witx/tests/witxt/simple.witxt | 12 + .../tools/witx/tests/witxt/union.witxt | 97 +++++ .../tools/witx/tests/witxt/wasi.witxt | 26 ++ 22 files changed, 726 insertions(+), 431 deletions(-) delete mode 100644 proposals/filesystem/tools/witx/tests/anonymous.rs delete mode 100644 proposals/filesystem/tools/witx/tests/multimodule.rs delete mode 100644 proposals/filesystem/tools/witx/tests/union.rs rename proposals/filesystem/tools/witx/tests/{wasi.rs => wasi-docs.rs} (58%) create mode 100644 proposals/filesystem/tools/witx/tests/witxt.rs create mode 100644 proposals/filesystem/tools/witx/tests/witxt/anonymous.witxt create mode 100644 proposals/filesystem/tools/witx/tests/witxt/multimodule.witxt rename proposals/filesystem/tools/witx/tests/{ => witxt}/multimodule/redefine_a.witx (100%) rename proposals/filesystem/tools/witx/tests/{ => witxt}/multimodule/type_a.witx (100%) rename proposals/filesystem/tools/witx/tests/{ => witxt}/multimodule/type_b.witx (100%) rename proposals/filesystem/tools/witx/tests/{ => witxt}/multimodule/type_c.witx (100%) create mode 100644 proposals/filesystem/tools/witx/tests/witxt/representation.witxt create mode 100644 proposals/filesystem/tools/witx/tests/witxt/simple.witxt create mode 100644 proposals/filesystem/tools/witx/tests/witxt/union.witxt create mode 100644 proposals/filesystem/tools/witx/tests/witxt/wasi.witxt diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 2cd2d1361..a3c0d0a47 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -871,12 +871,12 @@ Alignment: 8 - align: 8 - tag_size: 1 ### Variant cases +- `clock` + - `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) - `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) -- `clock` - ## `event`: Record An event that occurred. diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index 34c074d68..bf9ce16cd 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -23,3 +23,8 @@ wast = { version = "22.0.0", default-features = false } diff = "0.1.11" pretty_env_logger = "0.4" structopt = "0.3" +rayon = "1.0" + +[[test]] +name = "witxt" +harness = false diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 9c0f53060..2c876aa13 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -9,7 +9,7 @@ mod io; /// Calculate memory layout of types mod layout; /// Witx syntax parsing from SExprs -mod parser; +pub mod parser; /// Paths to witx documents for various proposal phases pub mod phases; /// Calculate required polyfill between interfaces @@ -28,10 +28,9 @@ pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, T pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use layout::{Layout, RecordMemberLayout, SizeAlign}; -pub use parser::DeclSyntax; pub use render::SExpr; pub use representation::{RepEquality, Representable}; -pub use validate::ValidationError; +pub use validate::{DocValidation, ValidationError}; use std::path::{Path, PathBuf}; use thiserror::Error; diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 325eb1d35..19d1a0303 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -477,7 +477,6 @@ impl<'a> Parse<'a> for UnionSyntax<'a> { None }; let mut fields = Vec::new(); - fields.push(parser.parse()?); while !parser.is_empty() { fields.push(parser.parse()?); } @@ -505,7 +504,9 @@ impl<'a> Parse<'a> for VariantSyntax<'a> { }; let mut cases = Vec::new(); while !parser.is_empty() { - cases.push(parser.parens(|p| p.parse())?); + let comments = parser.parse()?; + let item = parser.parens(|p| p.parse())?; + cases.push(Documented { comments, item }); } Ok(VariantSyntax { tag, cases }) } diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs index 99f73f5b6..589b64e39 100644 --- a/proposals/filesystem/tools/witx/src/representation.rs +++ b/proposals/filesystem/tools/witx/src/representation.rs @@ -81,12 +81,14 @@ impl Representable for Variant { let other_by_name = by .cases .iter() - .map(|c| (&c.name, c)) + .enumerate() + .map(|(i, c)| (&c.name, (c, i))) .collect::>(); // For each variant in self, must have variant of same name in by: - for v in self.cases.iter() { + for (i, v) in self.cases.iter().enumerate() { let other_ty = match other_by_name.get(&v.name) { - Some(other) => &other.tref, + Some((_, j)) if i != *j => return RepEquality::NotEq, + Some((other, _)) => &other.tref, None => return RepEquality::NotEq, }; match (&v.tref, other_ty) { @@ -157,76 +159,3 @@ impl Representable for Type { } } } - -#[cfg(test)] -mod test { - use super::*; - use crate::io::MockFs; - use crate::toplevel::parse_witx_with; - use crate::Id; - use std::rc::Rc; - - fn def_type(typename: &str, syntax: &str) -> Rc { - use std::path::Path; - let doc = parse_witx_with(&[Path::new("-")], &MockFs::new(&[("-", syntax)])) - .expect("parse witx doc"); - let t = doc.typename(&Id::new(typename)).expect("defined type"); - // Identity should always be true: - assert_eq!(t.representable(&t), RepEquality::Eq, "identity"); - t - } - - #[test] - fn different_typenames() { - let a = def_type("a", "(typename $a (flags (@witx bitflags u32) $b $c))"); - let d = def_type("d", "(typename $d (flags (@witx bitflags u32) $b $c))"); - - assert_eq!(a.representable(&d), RepEquality::Eq); - assert_eq!(d.representable(&a), RepEquality::Eq); - } - - #[test] - fn enum_() { - let base = def_type("a", "(typename $a (enum $b $c))"); - let extra_variant = def_type("a", "(typename $a (enum $b $c $d))"); - - assert_eq!(base.representable(&extra_variant), RepEquality::Superset); - assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); - - let smaller_size = def_type("a", "(typename $a (enum (@witx tag u16) $b $c))"); - assert_eq!(smaller_size.representable(&base), RepEquality::Superset); - assert_eq!( - smaller_size.representable(&extra_variant), - RepEquality::Superset - ); - } - - #[test] - fn union() { - let base = def_type( - "a", - "(typename $tag (enum (@witx tag u8) $b $c)) - (typename $a (union (@witx tag $tag) u32 f32))", - ); - let extra_variant = def_type( - "a", - "(typename $tag (enum (@witx tag u8) $b $c $d)) - (typename $a (union (@witx tag $tag) u32 f32 f64))", - ); - - assert_eq!(base.representable(&extra_variant), RepEquality::Superset); - assert_eq!(extra_variant.representable(&base), RepEquality::NotEq); - - let other_ordering = def_type( - "a", - "(typename $tag (enum (@witx tag u8) $b $c)) - (typename $a (variant (@witx tag $tag) (case $c f32) (case $b u32)))", - ); - assert_eq!(base.representable(&other_ordering), RepEquality::Eq); - assert_eq!(other_ordering.representable(&base), RepEquality::Eq); - assert_eq!( - other_ordering.representable(&extra_variant), - RepEquality::Superset - ); - } -} diff --git a/proposals/filesystem/tools/witx/src/toplevel.rs b/proposals/filesystem/tools/witx/src/toplevel.rs index 993fc8cc4..83e940c7c 100644 --- a/proposals/filesystem/tools/witx/src/toplevel.rs +++ b/proposals/filesystem/tools/witx/src/toplevel.rs @@ -32,7 +32,7 @@ fn _parse_witx_with(paths: &[&Path], io: &dyn WitxIo) -> Result, + entries: HashMap, constant_scopes: HashMap, } @@ -155,6 +155,10 @@ impl DocValidation { path, } } + + pub fn into_document(self, defs: Vec) -> Document { + Document::new(defs, self.entries) + } } impl DocValidationScope<'_> { @@ -439,14 +443,16 @@ impl DocValidationScope<'_> { } } - let mut names = names.map(|names| names.into_iter().collect::>()); + let mut name_set = names + .as_ref() + .map(|names| names.iter().collect::>()); - let cases = syntax + let mut cases = syntax .cases .iter() .map(|case| { let name = Id::new(case.item.name.name()); - if let Some(names) = &mut names { + if let Some(names) = &mut name_set { if !names.remove(&name) { return Err(ValidationError::InvalidUnionField { name: name.as_str().to_string(), @@ -467,6 +473,18 @@ impl DocValidationScope<'_> { }) }) .collect::, _>>()?; + + // If we have an explicit tag with an enum then that's instructing us to + // reorder cases based on the order of the enum itself, so do that here. + if let Some(names) = names { + let name_pos = names + .iter() + .enumerate() + .map(|(i, name)| (name, i)) + .collect::>(); + cases.sort_by_key(|c| name_pos[&&c.name]); + } + Ok(Variant { tag_repr, cases }) } diff --git a/proposals/filesystem/tools/witx/tests/anonymous.rs b/proposals/filesystem/tools/witx/tests/anonymous.rs deleted file mode 100644 index 6cfb2ea7e..000000000 --- a/proposals/filesystem/tools/witx/tests/anonymous.rs +++ /dev/null @@ -1,43 +0,0 @@ -use witx; - -fn is_anonymous_record_err(r: Result) -> bool { - match r { - Err(witx::WitxError::Validation(witx::ValidationError::AnonymousRecord { .. })) => true, - _ => false, - } -} - -#[test] -fn anonymous_types() { - let pointer_to_record = witx::parse("(typename $a (@witx pointer (record (field $b u8))))"); - assert!(is_anonymous_record_err(pointer_to_record)); - - let pointer_to_union = - witx::parse("(typename $tag (enum $b)) (typename $a (@witx pointer (union u8)))"); - assert!(is_anonymous_record_err(pointer_to_union)); - - let pointer_to_enum = witx::parse("(typename $a (@witx pointer (enum $b)))"); - assert!(is_anonymous_record_err(pointer_to_enum)); - - let pointer_to_flags = witx::parse("(typename $a (@witx pointer (flags $b)))"); - assert!(is_anonymous_record_err(pointer_to_flags)); - - let pointer_to_handle = witx::parse("(typename $a (@witx pointer (handle)))"); - assert!(is_anonymous_record_err(pointer_to_handle)); - - let pointer_to_builtin = witx::parse("(typename $a (@witx pointer u8))"); - assert!(pointer_to_builtin.is_ok()); - - let pointer_to_pointer = witx::parse("(typename $a (@witx pointer (@witx const_pointer u8)))"); - assert!(pointer_to_pointer.is_ok()); - - let record_in_record = witx::parse("(typename $a (record (field $b (record (field $c u8)))))"); - assert!(is_anonymous_record_err(record_in_record)); - - let union_in_record = - witx::parse("(typename $tag (enum $c)) (typename $a (record (field $b (union u8))))"); - assert!(is_anonymous_record_err(union_in_record)); - - let pointer_in_record = witx::parse("(typename $a (record (field $b (@witx pointer u8))))"); - assert!(pointer_in_record.is_ok()) -} diff --git a/proposals/filesystem/tools/witx/tests/multimodule.rs b/proposals/filesystem/tools/witx/tests/multimodule.rs deleted file mode 100644 index a6c773363..000000000 --- a/proposals/filesystem/tools/witx/tests/multimodule.rs +++ /dev/null @@ -1,58 +0,0 @@ -use witx::{load, BuiltinType, Id, Type, TypeRef}; - -#[test] -fn validate_multimodule() { - // B uses A, and C uses A. - let doc = load(&[ - "tests/multimodule/type_b.witx", - "tests/multimodule/type_c.witx", - ]) - .unwrap_or_else(|e| panic!("failed to validate: {}", e)); - - //println!("{}", doc); - - // Check that the `a` both modules use is what we expect: - let type_a = doc.typename(&Id::new("a")).expect("type a exists"); - assert_eq!( - *type_a.type_(), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: false - }) - ); - - // `b` is a struct with a single member of type `a` - let type_b = doc.typename(&Id::new("b")).expect("type b exists"); - match &*type_b.type_() { - Type::Record(record) => { - assert_eq!(record.members.len(), 1); - assert_eq!( - record.members.get(0).unwrap().tref, - TypeRef::Name(type_a.clone()) - ); - } - _ => panic!("b is a struct"), - } - - // `c` is a struct with a two members of type `a` - let type_c = doc.typename(&Id::new("c")).expect("type c exists"); - match &*type_c.type_() { - Type::Record(record) => { - assert_eq!(record.members.len(), 2); - assert_eq!( - record.members.get(0).unwrap().tref, - TypeRef::Name(type_a.clone()) - ); - assert_eq!(record.members.get(1).unwrap().tref, TypeRef::Name(type_a)); - } - _ => panic!("c is a struct"), - } -} - -#[test] -fn multimodule_reject_redefinition() { - assert!(load(&[ - "tests/multimodule/type_a.witx", - "tests/multimodule/redefine_a.witx", - ]) - .is_err()) -} diff --git a/proposals/filesystem/tools/witx/tests/union.rs b/proposals/filesystem/tools/witx/tests/union.rs deleted file mode 100644 index 31ade263a..000000000 --- a/proposals/filesystem/tools/witx/tests/union.rs +++ /dev/null @@ -1,174 +0,0 @@ -// Every worker needs a union! Time to organize -use witx::{Id, Representable}; - -#[test] -fn one_variant_union() { - let d = witx::parse( - "(typename $tag (enum $c)) - (typename $u (union (@witx tag $tag) u8))", - ); - assert!(d.is_ok()); -} - -#[test] -fn two_variant_union() { - let d1 = witx::parse( - "(typename $tag (enum $a $b)) - (typename $u (union (@witx tag $tag) u8 u16))", - ); - assert!(d1.is_ok(), "d1 is ok"); - - // Fields can come in whatever order: - let d2 = witx::parse( - "(typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $b u16) (case $a u8)))", - ); - assert!(d2.is_ok(), "d2 is ok"); - - // These two unions should be represented the same: - let u1 = d1.unwrap().typename(&Id::new("u")).unwrap().type_(); - let u2 = d2.unwrap().typename(&Id::new("u")).unwrap().type_(); - - assert_eq!( - u1.representable(&u2), - witx::RepEquality::Eq, - "u1 can represent u2" - ); - assert_eq!( - u2.representable(&u1), - witx::RepEquality::Eq, - "u2 can represent u1" - ); - - // Tag order doesnt matter for validation - let d3 = witx::parse( - "(typename $tag (enum $b $a)) - (typename $u (union (@witx tag $tag) u16 u8))", - ); - assert!(d3.is_ok(), "d2 is ok"); -} - -#[test] -fn empty_variant_unions() { - let d1 = witx::parse( - "(typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $a) (case $b u16)))", - ); - assert!(d1.is_ok(), "d1 is ok"); - - let d2 = witx::parse( - "(typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $a) (case $b)))", - ); - assert!(d2.is_ok(), "d2 is ok"); -} - -#[test] -fn many_variant_unions() { - let d1 = witx::parse( - "(typename $tag (enum $a $b $c $d $e $f $g $h $i $j $k $l $m)) - (typename $u - (variant (@witx tag $tag) - (case $a u8) - (case $b u16) - (case $c u32) - (case $d u64) - (case $e s8) - (case $f s16) - (case $g s32) - (case $h s64) - (case $i f32) - (case $j f64) - (case $k (@witx usize)) - (case $l (@witx char8)) - (case $m) - ) - )", - ); - assert!(d1.is_ok(), "d1 is ok"); -} - -#[test] -fn no_tag_union() { - let d = witx::parse("(typename $u (union $tag (field $a u8) (field $b u16)))"); - assert!(d.is_err()); -} - -#[test] -fn wrong_kind_tag_union() { - let d = witx::parse( - "(typename $tag string) - (typename $u (union (@witx tag $tag) u8 u16))", - ); - let (expected, got) = wrong_kind_name_err(d).expect("wrong kind of tag"); - assert_eq!(expected, "enum or builtin"); - assert_eq!(got, "list"); -} - -#[test] -fn bad_field_unions() { - let d = witx::parse( - "(typename $tag (enum $c)) - (typename $u (variant (@witx tag $tag) (case $b u8)))", - ); - match validation_err(d) { - witx::ValidationError::InvalidUnionField { name, reason, .. } => { - assert_eq!(name, "b", "bad field name union 1"); - assert_eq!( - reason, "does not correspond to variant in tag `tag`", - "reason union 1" - ); - } - other => panic!("bad error: {}", other), - } - - let d = witx::parse( - "(typename $tag (enum $c)) - (typename $u (variant (@witx tag $tag) (case $c f32) (case $b u8)))", - ); - match validation_err(d) { - witx::ValidationError::UnionSizeMismatch { .. } => {} - other => panic!("bad error: {}", other), - } - - let d = witx::parse( - "(typename $tag (enum $c $d)) - (typename $u (variant (@witx tag $tag) (case $c f32)))", - ); - match validation_err(d) { - witx::ValidationError::UnionSizeMismatch { .. } => {} - other => panic!("bad error: {}", other), - } -} - -fn wrong_kind_name_err( - r: Result, -) -> Option<(&'static str, &'static str)> { - match r { - Err(witx::WitxError::Validation(witx::ValidationError::WrongKindName { - expected, - got, - .. - })) => Some((expected, got)), - Err(e) => { - eprintln!("expected WrongKindName ValidationError, got: {:?}", e); - None - } - Ok(_) => { - eprintln!("expected WrongKindName ValidationError: Ok(witx::Document)"); - None - } - } -} - -fn validation_err(r: Result) -> witx::ValidationError { - match r { - Err(witx::WitxError::Validation(e)) => e, - Err(e) => { - panic!("expected ValidationError, got: {:?}", e) - } - Ok(_) => { - panic!("expected ValidationError, got: Ok(witx::Document)") - } - } -} diff --git a/proposals/filesystem/tools/witx/tests/wasi.rs b/proposals/filesystem/tools/witx/tests/wasi-docs.rs similarity index 58% rename from proposals/filesystem/tools/witx/tests/wasi.rs rename to proposals/filesystem/tools/witx/tests/wasi-docs.rs index 27300a26e..6702edfbd 100644 --- a/proposals/filesystem/tools/witx/tests/wasi.rs +++ b/proposals/filesystem/tools/witx/tests/wasi-docs.rs @@ -2,24 +2,6 @@ use std::fs; use std::path::Path; use witx::{self, Documentation}; -#[test] -fn validate_wasi_snapshot() { - witx::load(&witx::phases::snapshot().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); -} - -#[test] -fn validate_wasi_ephemeral() { - witx::load(&witx::phases::ephemeral().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); -} - -#[test] -fn validate_wasi_old_snapshot_0() { - witx::load(&witx::phases::old::snapshot_0().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); -} - #[test] fn validate_docs() { for phase in &[ @@ -32,52 +14,6 @@ fn validate_docs() { } } -#[test] -fn render_roundtrip() { - let doc = witx::load(&witx::phases::snapshot().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)); - - let back_to_sexprs = format!("{}", doc); - println!("{}", back_to_sexprs); - - let doc2 = witx::parse(&back_to_sexprs) - .map_err(|e| e.report_with(&witx::MockFs::new(&[("-", &back_to_sexprs)]))) - .unwrap(); - - // I'd just assert_eq, but when it fails the debug print is thousands of lines long and impossible - // to figure out where they are unequal. - if doc != doc2 { - for type_ in doc.typenames() { - let type2 = doc2.typename(&type_.name).expect("doc2 missing datatype"); - assert_eq!(type_, type2); - } - for mod_ in doc.modules() { - let mod2 = doc2.module(&mod_.name).expect("doc2 missing module"); - for import in mod_.imports() { - let import2 = mod2.import(&import.name).expect("mod2 missing import"); - assert_eq!(import, import2); - } - for func in mod_.funcs() { - let func2 = mod2.func(&func.name).expect("mod2 missing func"); - assert_eq!(func, func2); - } - } - } - // This should be equivalent to the above, but just in case some code changes where it isnt: - assert_eq!(doc, doc2); -} - -#[test] -fn document_wasi_snapshot() { - use witx::Documentation; - println!( - "{}", - witx::load(&witx::phases::snapshot().unwrap()) - .unwrap_or_else(|e| panic!("failed to parse: {}", e)) - .to_md() - ); -} - fn dos2unix(s: &str) -> String { let mut t = String::new(); t.reserve(s.len()); diff --git a/proposals/filesystem/tools/witx/tests/witxt.rs b/proposals/filesystem/tools/witx/tests/witxt.rs new file mode 100644 index 000000000..1056947a3 --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/witxt.rs @@ -0,0 +1,409 @@ +//! You can run this test suite with: +//! +//! cargo test --test witxt +//! +//! An argument can be passed as well to filter, based on filename, which test +//! to run +//! +//! cargo test --test witxt foo.witxt + +use anyhow::{anyhow, bail, Context, Result}; +use rayon::prelude::*; +use std::collections::HashMap; +use std::path::{Path, PathBuf}; +use std::str; +use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; +use wast::parser::{self, Parse, ParseBuffer, Parser}; +use witx::{Documentation, Representable}; + +fn main() { + let tests = find_tests(); + let filter = std::env::args().nth(1); + + let tests = tests + .par_iter() + .filter_map(|test| { + if let Some(filter) = &filter { + if let Some(s) = test.to_str() { + if !s.contains(filter) { + return None; + } + } + } + let contents = std::fs::read(test).unwrap(); + Some((test, contents)) + }) + .collect::>(); + + println!("running {} test files\n", tests.len()); + + let ntests = AtomicUsize::new(0); + let errors = tests + .par_iter() + .filter_map(|(test, contents)| { + WitxtRunner { + ntests: &ntests, + documents: HashMap::new(), + } + .run(test, contents) + .err() + }) + .collect::>(); + + if !errors.is_empty() { + for msg in errors.iter() { + eprintln!("{:?}", msg); + } + + panic!("{} tests failed", errors.len()) + } + + println!( + "test result: ok. {} directives passed\n", + ntests.load(SeqCst) + ); +} + +/// Recursively finds all tests in a whitelisted set of directories which we +/// then load up and test in parallel. +fn find_tests() -> Vec { + let mut tests = Vec::new(); + find_tests("tests/witxt".as_ref(), &mut tests); + tests.sort(); + return tests; + + fn find_tests(path: &Path, tests: &mut Vec) { + for f in path.read_dir().unwrap() { + let f = f.unwrap(); + if f.file_type().unwrap().is_dir() { + find_tests(&f.path(), tests); + continue; + } + + match f.path().extension().and_then(|s| s.to_str()) { + Some("witxt") => {} + _ => continue, + } + tests.push(f.path()); + } + } +} + +struct WitxtRunner<'a> { + ntests: &'a AtomicUsize, + documents: HashMap, +} + +impl WitxtRunner<'_> { + fn run(&mut self, test: &Path, contents: &[u8]) -> Result<()> { + let contents = str::from_utf8(contents)?; + macro_rules! adjust { + ($e:expr) => {{ + let mut e = wast::Error::from($e); + e.set_path(test); + e.set_text(contents); + e + }}; + } + let buf = ParseBuffer::new(contents).map_err(|e| adjust!(e))?; + let witxt = parser::parse::(&buf).map_err(|e| adjust!(e))?; + + let errors = witxt + .directives + .into_iter() + .filter_map(|directive| { + let (line, col) = directive.span().linecol_in(contents); + self.test_directive(contents, test, directive) + .with_context(|| { + format!( + "failed directive on {}:{}:{}", + test.display(), + line + 1, + col + 1 + ) + }) + .err() + }) + .collect::>(); + if errors.is_empty() { + return Ok(()); + } + let mut s = format!("{} test failures in {}:", errors.len(), test.display()); + for mut error in errors { + if let Some(err) = error.downcast_mut::() { + err.set_path(test); + err.set_text(contents); + } + s.push_str("\n\n\t--------------------------------\n\n\t"); + s.push_str(&format!("{:?}", error).replace("\n", "\n\t")); + } + bail!("{}", s) + } + + fn test_directive( + &mut self, + contents: &str, + test: &Path, + directive: WitxtDirective, + ) -> Result<()> { + self.bump_ntests(); + match directive { + WitxtDirective::Witx(witx) => { + let doc = witx.document(contents, test)?; + self.assert_roundtrip(&doc) + .context("failed to round-trip the document")?; + self.assert_md(&doc)?; + if let Some(name) = witx.id { + self.documents.insert(name.name().to_string(), doc); + } + } + WitxtDirective::AssertInvalid { witx, message, .. } => { + let err = match witx.document(contents, test) { + Ok(_) => bail!("witx was valid when it shouldn't be"), + Err(e) => format!("{:?}", anyhow::Error::from(e)), + }; + if !err.contains(message) { + bail!("expected error {:?}\nfound error {}", message, err); + } + } + WitxtDirective::AssertRepresentable { repr, t1, t2, .. } => { + let (t1m, t1t) = t1; + let (t2m, t2t) = t2; + let t1d = self + .documents + .get(t1m.name()) + .ok_or_else(|| anyhow!("no document named {:?}", t1m.name()))?; + let t2d = self + .documents + .get(t2m.name()) + .ok_or_else(|| anyhow!("no document named {:?}", t2m.name()))?; + let t1 = t1d + .typename(&witx::Id::new(t1t)) + .ok_or_else(|| anyhow!("no type named {:?}", t1t))?; + let t2 = t2d + .typename(&witx::Id::new(t2t)) + .ok_or_else(|| anyhow!("no type named {:?}", t2t))?; + match (repr, t1.type_().representable(&t2.type_())) { + (RepEquality::Eq, witx::RepEquality::Eq) + | (RepEquality::Superset, witx::RepEquality::Superset) + | (RepEquality::NotEq, witx::RepEquality::NotEq) => {} + (a, b) => { + bail!("expected {:?} representation, got {:?}", a, b); + } + } + } + } + Ok(()) + } + + fn assert_roundtrip(&self, doc: &witx::Document) -> Result<()> { + self.bump_ntests(); + let back_to_sexprs = format!("{}", doc); + let doc2 = witx::parse(&back_to_sexprs)?; + if *doc == doc2 { + return Ok(()); + } + + // Try to get a more specific error message that isn't thousands of + // lines long of debug representations. + for type_ in doc.typenames() { + let type2 = match doc2.typename(&type_.name) { + Some(t) => t, + None => bail!("doc2 missing datatype"), + }; + if type_ != type2 { + bail!("types are not equal\n{:?}\n !=\n{:?}", type_, type2); + } + } + for mod_ in doc.modules() { + let mod2 = match doc2.module(&mod_.name) { + Some(m) => m, + None => bail!("doc2 missing module"), + }; + for import in mod_.imports() { + let import2 = match mod2.import(&import.name) { + Some(i) => i, + None => bail!("mod2 missing import"), + }; + assert_eq!(import, import2); + } + for func in mod_.funcs() { + let func2 = match mod2.func(&func.name) { + Some(f) => f, + None => bail!("mod2 missing func"), + }; + assert_eq!(func, func2); + } + } + bail!("{:?} != {:?}", doc, doc2) + } + + fn assert_md(&self, doc: &witx::Document) -> Result<()> { + self.bump_ntests(); + doc.to_md(); + Ok(()) + } + + fn bump_ntests(&self) { + self.ntests.fetch_add(1, SeqCst); + } +} + +mod kw { + wast::custom_keyword!(assert_invalid); + wast::custom_keyword!(assert_representable); + wast::custom_keyword!(witx); + wast::custom_keyword!(eq); + wast::custom_keyword!(noteq); + wast::custom_keyword!(load); + wast::custom_keyword!(superset); +} + +struct Witxt<'a> { + directives: Vec>, +} + +impl<'a> Parse<'a> for Witxt<'a> { + fn parse(parser: Parser<'a>) -> parser::Result { + let mut directives = Vec::new(); + while !parser.is_empty() { + directives.push(parser.parens(|p| p.parse())?); + } + Ok(Witxt { directives }) + } +} + +enum WitxtDirective<'a> { + Witx(Witx<'a>), + AssertInvalid { + span: wast::Span, + witx: Witx<'a>, + message: &'a str, + }, + AssertRepresentable { + span: wast::Span, + repr: RepEquality, + t1: (wast::Id<'a>, &'a str), + t2: (wast::Id<'a>, &'a str), + }, +} + +impl WitxtDirective<'_> { + fn span(&self) -> wast::Span { + match self { + WitxtDirective::Witx(w) => w.span, + WitxtDirective::AssertInvalid { span, .. } + | WitxtDirective::AssertRepresentable { span, .. } => *span, + } + } +} + +impl<'a> Parse<'a> for WitxtDirective<'a> { + fn parse(parser: Parser<'a>) -> parser::Result { + let mut l = parser.lookahead1(); + if l.peek::() { + Ok(WitxtDirective::Witx(parser.parse()?)) + } else if l.peek::() { + let span = parser.parse::()?.0; + Ok(WitxtDirective::AssertInvalid { + span, + witx: parser.parens(|p| p.parse())?, + message: parser.parse()?, + }) + } else if l.peek::() { + let span = parser.parse::()?.0; + Ok(WitxtDirective::AssertRepresentable { + span, + repr: parser.parse()?, + t1: (parser.parse()?, parser.parse()?), + t2: (parser.parse()?, parser.parse()?), + }) + } else { + Err(l.error()) + } + } +} + +struct Witx<'a> { + span: wast::Span, + id: Option>, + def: WitxDef<'a>, +} + +enum WitxDef<'a> { + Fs(Vec<&'a str>), + Inline(Vec>>), +} + +impl Witx<'_> { + fn document(&self, contents: &str, file: &Path) -> Result { + match &self.def { + WitxDef::Inline(decls) => { + let mut validator = witx::DocValidation::new(); + let mut definitions = Vec::new(); + for decl in decls { + validator + .scope(contents, file) + .validate_decl(&decl.item, &decl.comments, &mut definitions) + .map_err(witx::WitxError::Validation)?; + } + Ok(validator.into_document(definitions)) + } + WitxDef::Fs(paths) => { + let parent = file.parent().unwrap(); + let paths = paths.iter().map(|p| parent.join(p)).collect::>(); + Ok(witx::load(&paths)?) + } + } + } +} + +impl<'a> Parse<'a> for Witx<'a> { + fn parse(parser: Parser<'a>) -> parser::Result { + let span = parser.parse::()?.0; + let id = parser.parse()?; + + let def = if parser.peek2::() { + parser.parens(|p| { + p.parse::()?; + let mut paths = Vec::new(); + while !p.is_empty() { + paths.push(p.parse()?); + } + Ok(WitxDef::Fs(paths)) + })? + } else { + let mut decls = Vec::new(); + while !parser.is_empty() { + decls.push(parser.parens(|p| p.parse())?); + } + WitxDef::Inline(decls) + }; + Ok(Witx { id, span, def }) + } +} + +#[derive(Debug)] +enum RepEquality { + Eq, + NotEq, + Superset, +} + +impl<'a> Parse<'a> for RepEquality { + fn parse(parser: Parser<'a>) -> parser::Result { + let mut l = parser.lookahead1(); + if l.peek::() { + parser.parse::()?; + Ok(RepEquality::Eq) + } else if l.peek::() { + parser.parse::()?; + Ok(RepEquality::NotEq) + } else if l.peek::() { + parser.parse::()?; + Ok(RepEquality::Superset) + } else { + Err(l.error()) + } + } +} diff --git a/proposals/filesystem/tools/witx/tests/witxt/anonymous.witxt b/proposals/filesystem/tools/witx/tests/witxt/anonymous.witxt new file mode 100644 index 000000000..0ed3bc0d2 --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/witxt/anonymous.witxt @@ -0,0 +1,56 @@ +;; Ensure that anonymous structured types are not allowed in type positions at +;; this time, everything has to be named to assist in binding in languages. + +(assert_invalid + (witx + (typename $a (@witx pointer (record (field $b u8)))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (@witx pointer (union))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (@witx pointer (enum $b))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (@witx pointer (flags $b))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (@witx pointer (handle))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $a (record (field $b (record (field $c u8))))) + ) + "Anonymous structured types") + +(assert_invalid + (witx + (typename $tag (enum $c)) + (typename $a (record (field $b (union)))) + ) + "Anonymous structured types") + + +;; pointers don't count for anonymous indirections +(witx + (typename $a (@witx pointer u8))) + +(witx + (typename $a (@witx pointer (@witx const_pointer u8)))) + +(witx + (typename $a (record (field $b (@witx pointer u8))))) diff --git a/proposals/filesystem/tools/witx/tests/witxt/multimodule.witxt b/proposals/filesystem/tools/witx/tests/witxt/multimodule.witxt new file mode 100644 index 000000000..d8b6559ac --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/witxt/multimodule.witxt @@ -0,0 +1,22 @@ +;; B uses A, and C uses A. +(witx $multi + (load "multimodule/type_b.witx" "multimodule/type_c.witx") +) + +(witx $reference + (typename $a u32) + (typename $b (record (field $member_a $a))) + (typename $c (record (field $first_a $a) (field $second_a $a))) +) + +(assert_representable eq $reference "a" $multi "a") +(assert_representable eq $reference "b" $multi "b") +(assert_representable eq $reference "c" $multi "c") + +(assert_invalid + (witx + (load + "multimodule/type_a.witx" + "multimodule/redefine_a.witx") + ) + "Redefinition of name `a`") diff --git a/proposals/filesystem/tools/witx/tests/multimodule/redefine_a.witx b/proposals/filesystem/tools/witx/tests/witxt/multimodule/redefine_a.witx similarity index 100% rename from proposals/filesystem/tools/witx/tests/multimodule/redefine_a.witx rename to proposals/filesystem/tools/witx/tests/witxt/multimodule/redefine_a.witx diff --git a/proposals/filesystem/tools/witx/tests/multimodule/type_a.witx b/proposals/filesystem/tools/witx/tests/witxt/multimodule/type_a.witx similarity index 100% rename from proposals/filesystem/tools/witx/tests/multimodule/type_a.witx rename to proposals/filesystem/tools/witx/tests/witxt/multimodule/type_a.witx diff --git a/proposals/filesystem/tools/witx/tests/multimodule/type_b.witx b/proposals/filesystem/tools/witx/tests/witxt/multimodule/type_b.witx similarity index 100% rename from proposals/filesystem/tools/witx/tests/multimodule/type_b.witx rename to proposals/filesystem/tools/witx/tests/witxt/multimodule/type_b.witx diff --git a/proposals/filesystem/tools/witx/tests/multimodule/type_c.witx b/proposals/filesystem/tools/witx/tests/witxt/multimodule/type_c.witx similarity index 100% rename from proposals/filesystem/tools/witx/tests/multimodule/type_c.witx rename to proposals/filesystem/tools/witx/tests/witxt/multimodule/type_c.witx diff --git a/proposals/filesystem/tools/witx/tests/witxt/representation.witxt b/proposals/filesystem/tools/witx/tests/witxt/representation.witxt new file mode 100644 index 000000000..37d20a70a --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/witxt/representation.witxt @@ -0,0 +1,60 @@ +;; type names don't matter +(witx $a + (typename $a (flags (@witx bitflags u8) $b $c))) +(witx $b + (typename $b (flags (@witx bitflags u8) $b $c))) + +(assert_representable eq $a "a" $b "b") +(assert_representable eq $b "b" $a "a") + +(; TODO: perhaps add assertions eventually for document-level representability? +;; flags +(witx $a + (typename $a (flags (@witx bitflags u8) $b $c))) +(witx $b + (typename $b (flags (@witx bitflags u8) $b $c $d))) + +(assert_representable noteq $b "b" $a "a") +(assert_representable superset $a "a" $b "b") + +(witx $c + (typename $c (flags (@witx bitflags u8) $b $e))) +(assert_representable noteq $a "a" $c "c") +(assert_representable noteq $c "c" $a "a") + +(witx $d + (typename $d (flags (@witx bitflags u16) $b $c))) +(assert_representable noteq $a "a" $d "d") +(assert_representable superset $d "d" $a "a") +(assert_representable superset $d "d" $b "b") +;) + +;; enums +(witx $a + (typename $a (enum $b $c))) +(witx $b + (typename $b (enum $b $c $d))) +(assert_representable superset $a "a" $b "b") +(assert_representable noteq $b "b" $a "a") + +(witx $c + (typename $c (enum (@witx tag u16) $b $c))) +(assert_representable superset $c "c" $a "a") +(assert_representable superset $c "c" $b "b") + +;; unions +(witx $a + (typename $tag (enum $b $c)) + (typename $a (union (@witx tag $tag) u32 f32))) +(witx $b + (typename $tag (enum $b $c $d)) + (typename $b (union (@witx tag $tag) u32 f32 f64))) +(assert_representable superset $a "a" $b "b") +(assert_representable noteq $b "b" $a "a") + +(witx $c + (typename $tag (enum $b $c)) + (typename $c (variant (@witx tag $tag) (case $c f32) (case $b u32)))) +(assert_representable eq $a "a" $c "c") +(assert_representable eq $c "c" $a "a") +(assert_representable superset $c "c" $b "b") diff --git a/proposals/filesystem/tools/witx/tests/witxt/simple.witxt b/proposals/filesystem/tools/witx/tests/witxt/simple.witxt new file mode 100644 index 000000000..af2403043 --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/witxt/simple.witxt @@ -0,0 +1,12 @@ +(witx) + +(witx + (typename $x u32) +) + +(assert_invalid + (witx + (typename $x u32) + (typename $x u32) + ) + "Redefinition of name `x`") diff --git a/proposals/filesystem/tools/witx/tests/witxt/union.witxt b/proposals/filesystem/tools/witx/tests/witxt/union.witxt new file mode 100644 index 000000000..92be3dcd9 --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/witxt/union.witxt @@ -0,0 +1,97 @@ + +(witx + (typename $u (union u8)) +) +(witx + (typename $tag (enum (@witx tag u8) $c)) + (typename $u (union (@witx tag $tag) u8)) +) + +(witx + (typename $tag (enum $a $b)) + (typename $u (variant (@witx tag $tag) (case $a) (case $b u16))) +) + +(witx + (typename $tag (enum $a $b)) + (typename $u (variant (@witx tag $tag) (case $a) (case $b))) +) + + +(witx + (typename $u + (union + u8 + u16 + u32 + u64 + s8 + s16 + s32 + s64 + f32 + f64 + (@witx usize) + (@witx char8) + ) + ) +) + +(assert_invalid + (witx (typename $u (union (@witx tag $tag) u8 u16))) + "Unknown name `tag`" +) + +(assert_invalid + (witx + (typename $tag string) + (typename $u (union (@witx tag $tag) u8 u16)) + ) + "Wrong kind of name `tag`: expected enum or builtin, got list" +) + +(assert_invalid + (witx + (typename $tag (enum $c)) + (typename $u (variant (@witx tag $tag) (case $b u8))) + ) + "Invalid union field `b`: does not correspond to variant in tag `tag`" +) + +(assert_invalid + (witx + (typename $tag (enum $c)) + (typename $u (union (@witx tag $tag) f32 u8)) + ) + "Union expected 1 variants, found 2" +) + +(assert_invalid + (witx + (typename $tag (enum $c $d)) + (typename $u (union (@witx tag $tag) f32)) + ) + "Union expected 2 variants, found 1" +) + +(witx $d1 + (typename $tag (enum $a $b)) + (typename $u (union (@witx tag $tag) u8 u16)) +) + +(witx $d2 + (typename $tag (enum $a $b)) + (typename $u (variant (@witx tag $tag) (case $b u16) (case $a u8))) +) + +;; These two unions should be represented the same: +(assert_representable eq $d1 "u" $d2 "u") +(assert_representable eq $d2 "u" $d1 "u") + +;; Tag order doesnt matter for validation, but does for rep equality +(witx $d3 + (typename $tag (enum $b $a)) + (typename $u (union (@witx tag $tag) u16 u8)) +) + +(assert_representable noteq $d3 "u" $d1 "u") diff --git a/proposals/filesystem/tools/witx/tests/witxt/wasi.witxt b/proposals/filesystem/tools/witx/tests/witxt/wasi.witxt new file mode 100644 index 000000000..f654a7ee3 --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/witxt/wasi.witxt @@ -0,0 +1,26 @@ +;; Ensure that all current witx definitions in this repository load, parse, +;; roundtrip, and are documentable. + +(witx + (load "../../../../phases/old/snapshot_0/witx/wasi_unstable.witx")) +(witx + (load "../../../../phases/snapshot/witx/wasi_snapshot_preview1.witx")) + +(witx + (load + "../../../../phases/ephemeral/witx/wasi_ephemeral_args.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_clock.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_environ.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_fd.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_path.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_poll.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_proc.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_random.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_sched.witx" + "../../../../phases/ephemeral/witx/wasi_ephemeral_sock.witx" + ) +) +;; should be singularly-loadable as well +(witx + (load + "../../../../phases/ephemeral/witx/wasi_ephemeral_fd.witx")) From 12aebe6c16e1d688872aa8cd75b9f90a92ca03c3 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 11 Feb 2021 09:45:51 -0800 Subject: [PATCH 0862/1772] Fix proposal links --- proposals/clocks/docs/Proposals.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/docs/Proposals.md b/proposals/clocks/docs/Proposals.md index a7a831d40..854467222 100644 --- a/proposals/clocks/docs/Proposals.md +++ b/proposals/clocks/docs/Proposals.md @@ -31,8 +31,8 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo | ["Classic" Command-Line][wasi-classic-command] | Dan Gohman | | [Clocks][wasi-clocks] | Dan Gohman | | [Random][wasi-random] | Dan Gohman | -| [Handle Index][handle-index] | Dan Gohman | -| [Poll][poll] | Dan Gohman | +| [Handle Index][wasi-handle-index] | Dan Gohman | +| [Poll][wasi-poll] | Dan Gohman | | [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 1 - Feature Proposal (CG) From 028aacb50374a1fbf9deaaa56554aaa4f56d9d5f Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 11 Feb 2021 09:45:51 -0800 Subject: [PATCH 0863/1772] Fix proposal links --- proposals/random/docs/Proposals.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/docs/Proposals.md b/proposals/random/docs/Proposals.md index a7a831d40..854467222 100644 --- a/proposals/random/docs/Proposals.md +++ b/proposals/random/docs/Proposals.md @@ -31,8 +31,8 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo | ["Classic" Command-Line][wasi-classic-command] | Dan Gohman | | [Clocks][wasi-clocks] | Dan Gohman | | [Random][wasi-random] | Dan Gohman | -| [Handle Index][handle-index] | Dan Gohman | -| [Poll][poll] | Dan Gohman | +| [Handle Index][wasi-handle-index] | Dan Gohman | +| [Poll][wasi-poll] | Dan Gohman | | [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 1 - Feature Proposal (CG) From 03a2081c84642c45b945e2631dd95c513e13a585 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Thu, 11 Feb 2021 09:45:51 -0800 Subject: [PATCH 0864/1772] Fix proposal links --- proposals/filesystem/docs/Proposals.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/docs/Proposals.md b/proposals/filesystem/docs/Proposals.md index a7a831d40..854467222 100644 --- a/proposals/filesystem/docs/Proposals.md +++ b/proposals/filesystem/docs/Proposals.md @@ -31,8 +31,8 @@ Proposals follow [this process document](https://github.com/WebAssembly/WASI/blo | ["Classic" Command-Line][wasi-classic-command] | Dan Gohman | | [Clocks][wasi-clocks] | Dan Gohman | | [Random][wasi-random] | Dan Gohman | -| [Handle Index][handle-index] | Dan Gohman | -| [Poll][poll] | Dan Gohman | +| [Handle Index][wasi-handle-index] | Dan Gohman | +| [Poll][wasi-poll] | Dan Gohman | | [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | ### Phase 1 - Feature Proposal (CG) From 31047d4fad28071a622f3f54722a2b736c5ece53 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Tue, 16 Feb 2021 12:54:08 -0500 Subject: [PATCH 0865/1772] Add 02-11 meeting notes --- proposals/clocks/meetings/2021/WASI-02-11.md | 85 ++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/proposals/clocks/meetings/2021/WASI-02-11.md b/proposals/clocks/meetings/2021/WASI-02-11.md index f56b6c537..c18c4b8fa 100644 --- a/proposals/clocks/meetings/2021/WASI-02-11.md +++ b/proposals/clocks/meetings/2021/WASI-02-11.md @@ -31,3 +31,88 @@ Installation is required, see the calendar invite. 1. Proposals and discussions 1. Discussion: What are the next steps in adapting WASI to use Interface Types handles and resources? 1. _Sumbit a PR to add your agenda item here_ + +## Notes +### Attendees +Pat Hickey +Andrew Brown +Sergey Rubanov +Lin Clark +Mark McCaskey +Till Schneidereit +Dan Gohman +Josh Dolitsky +Mingqiu Sun +Ralph Squillace +Nicholas +Radu Matei +Matt Fisher +Johnnie Birch +Luke Wagner + +**Lin Clark:** Are there any announcements? +(none) + +**Lin Clark:** Lets talk about how we’re going to move from this version of WASI to a new version that uses handles + +**Dan Gohman:** Witx has been designed to anticipate interface types. It has String and Handle types. These are pretty close to the ones in interface types - PR 391 takes things to the next level and evolves the rest of the witx types towards the interface types. Going forward we need to get rid of the witx pointer and get buffers to work the way they will in interface types, but we’re still waiting to hear from interface types the final word on how those will work. See Interface Types issue 68. Our job on the witx side is to evolve into the Interface Types buffer types. Without waiting we can add support for strings and return types and lower them into the existing C ABI that WASI programs use. + +**Dan Gohman:** Another piece is WASI modularization. It has been in progress for a while but several pieces are coming together. Issue 378. Describes a more granular include mechanism than witx uses right now - import a symbol from a module, rather than import a file. + +**Dan Gohman:** The next two big pieces, which we can address in detail in the future: How do you pass handles into programs? Currently there is a table with preopens in it, but interface types is going to give us new mechanisms that are better than the preopen concept. + +**Dan Gohman:** The last piece is defining new abstractions. wasi PR 240 describes how to merge the send and recv on sockets with read and write on files. We can generalize part of files and sockets into a concept of I/O streams. In interface types you’ll have the vocabulary to ask for e.g. a stream you can write to, without knowing or caring that its backed by a socket or file or pipe etc. What is the noun that you use in function signatures to describe an I/O Stream? Beyond I/O Streams there’s non-streaming operations on files which don’t work on sockets or pipes - pread/pwrite - there’s a place for an I/O object with non-stream personality as well, an array of bytes or a we can call it a dynamic array because it can be resized. There will be other concepts as well - key-value stores, windowed IO with buffers... At the moment the nascent WASI I/O proposal will evolve to develop these ideas. There will still be files, and then a function that gives you a stream from a file. Files are going to be required to interop with existing systems, but we can push people towards interfaces that don’t tie them to the complications of those existing systems, particularly file semantics are very difficult to compose but streams are. This will help us enable shared-nothing linking of modules - we don’t want modules to have to share a filesystem to talk to each other. Questions? + +**Ralph Squillace:** What kinds of objections to this direction do you anticipate? + +**Dan Gohman:** This is going off the path of POSIX. Existing applications and programming languages will be more work to port to I/O streams than having us port libc and standard libraries to WASI. We have ideas for making the standard io operations work on top of I/O streams - you can treat an i/o stream as a libc FILE if you only ever read and write from it, other operations give an error. + +**Ralph Squillace:** The philosophical discussion is about how you weigh the objectives of different applications moving to WASI - some will have to adapt specific POSIX-isms to WASI, where does the work of porting existing code break down - does the code stay in WASM and not use WASI, have its own custom runtime - or does it move to WASI in the coherent way that resolves the semantic differences. I don’t personally see myself trying to port an existing huge monolithic application to WASI, whereas I do see myself working on libraries to make them work in WASI. + +**Lin Clark:** How much is WASI filesystem still going to allow porting POSIX applications? + +**Dan Gohman:** It will allow it. Its a question of priorities rather than absolutes. WASI today runs plenty of interesting POSIX code that doesnt do things like fork(2), WASI filesystem is going to still be there for these applications to use. But we don’t want that to be part of the default for WASI, we want to encourage applications to use simpler concepts that don’t imply a whole filesystem. I want to build tooling that bridges the gap between the shared-nothing-linking space and making big applications work. + +**Till Schneidereit:** We can look at this in terms of layering - there is a core of WASI that may not apply to every use case but you can virtualize many of the other needs on top of it. You can add a filesystem ion top of the core, in many cases, and let applications that need it use it. + +**Dan Gohman:** In terms of migration from where WASI is today to this ideal system - the WASI I/O abstractions can be worked on now, we have witx where we need it. We can flesh out exactly how streams and dynamic arrays work today. + +**Dan Gohman:** Another aspect is portability. I’ve been working on support for WASI on Windows vs Unix the last few months - there are so many differences between those platforms, the semantics of filesystems is radically different and there’s no portability in many cases (its too expensive to bridge them). The WASI I/O abstractions can be designed to hide all of the non-portable parts of filesystems. We can get away from having to specify “what does windows do here” and instead specify the things an application actually needs. + +**Ralph Squillace:** Layering will require thought. + +**Pat Hickey:** The customers we have writing applications right now aren’t concerned with the differences between the filesystem guarantees on linux vs windows, they care about http requests and responses. If we have I/O abstractions that unify the way http bodies work with the way certain aspects of the filesystem work, that is better for the applications we care about. + +**Till Schneidereit:** There are lots of use cases that work with streaming, which has traditionally been a file or a socket, but with abstractions that are hard to generalize. My interpretation of what you were just saying is that if we had a way to have a cleaner system that didn’t have that incidental platform dependence, it would be much easier to build code that works across these very different environments. We have all these applications that are popping up that are very different. Ideally we have a layer that doesn’t care about host differences, and then the layer that cares about that. What we do is just one specific example of that. Don’t want to optimize for old use cases, but all of the new novel ones that are coming about. + +**Radu Matei:** Is the assumption that wasi-filesystem will be developed in parallel? + +**Dan Gohman:** Yes, WASI-filesystem will continue, and wasi-io will be a peer. + +**Ralph Squillace:** Drawing older threads in, what about BSD sockets PR. + +**Dan Gohman:** The contributor who created that hasn’t been active, but I expect that will fit into the system in the same way as wasi-fs. You could get a stream. Networking is a complex topic and I dont’ want to simplify, but the first step will be to take sockets and say the socket gives you a stream that you can read, a stream you can write, and bi-directional r/w. + +Async is a subtlety that we’re leaving out. We can say that async is an orthogonal concern. We expect the Wasm platform will give us better answers over time. But the fundamental concepts of I/O are independent of whether you block that I/O. + +**Lin Clark:** Any other thoughts/comments + +**Luke Wagner:** I have a hypothesis I want to test. Why are people going to want to use wasm outside of a browser? Some people think it’s great because of ISA. We don’t think that’s a great motivator. We think running guest code in latency sensitive and low trust scenarios is the motivator. Things like routers ____ would be host APIs. The libraries would be wasm. These problematic cases don’t have a high value reason to be ported to Wasm. + +**Ralph Squillace:** I understand where you’re coming from. I don’t see WASI as a monolithic process sandbox. I do think that the idea about the sweet spot is right. I’m not a big believer in the thought that the world’s code is going to all be running on WASI. But I think it’s worth consideration how much of the world’s knowledge can be run as WASI. Shouldn’t wall off for all time, but I think the way that Dan laid out the direction, it lets us start with the sweet spot and either layer the others, or add support to WASI later on. I would hate to frame the boundary ruling out knowledge transfer. + +**Luke Wagner:** I agree with your points, so the layering and virtualization are also motivated by that. + +**Dan Gohman:** I can add one thing. Thinking of lib-c, and lots of languages have lib-c like std lib: under the covers, something that people are using as a file could be represented by streams. We can make that work under the covers. We could talk about how that will exactly work. But this is the framework. We can make porting easier by allowing you to use streams by allowing you to use files, but discourage from using file stat and depending on i node. + +**Andrew Brown:** It feels to me that filesystem should be in phase 3 or 4. How do these changes affect moving those to later stages + +**Dan Gohman:** That’s a great question. Wasi-fs is waiting to figure out it’s place. This conversation moves that forward. Understanding that wasi-fs won’t attempt to be abstracting over all hosts, wasi-io does that, and accepting that’s ok means that wasi-fs can probably move to phase 3 at this point. + +**Till Schneidereit:** I think the better way to put it is that it’s not an either/or, we don’t need to make it completely host specific, but let’s find a balance that’s actually viable. + +**Radu Matei:** do we have a document? + +**Dan Gohman:** Will be writing that up. Wanted to introduce here first. Will write up wasi-io ideas soon + +**Pat Hickey:** One blocker to wasi-fs advancing. The filesystem has cloud ABI system of rights. Need to work out what to do with that. From 18c70648463fb747d74d054345d21b4762ee8692 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Tue, 16 Feb 2021 12:54:08 -0500 Subject: [PATCH 0866/1772] Add 02-11 meeting notes --- proposals/random/meetings/2021/WASI-02-11.md | 85 ++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/proposals/random/meetings/2021/WASI-02-11.md b/proposals/random/meetings/2021/WASI-02-11.md index f56b6c537..c18c4b8fa 100644 --- a/proposals/random/meetings/2021/WASI-02-11.md +++ b/proposals/random/meetings/2021/WASI-02-11.md @@ -31,3 +31,88 @@ Installation is required, see the calendar invite. 1. Proposals and discussions 1. Discussion: What are the next steps in adapting WASI to use Interface Types handles and resources? 1. _Sumbit a PR to add your agenda item here_ + +## Notes +### Attendees +Pat Hickey +Andrew Brown +Sergey Rubanov +Lin Clark +Mark McCaskey +Till Schneidereit +Dan Gohman +Josh Dolitsky +Mingqiu Sun +Ralph Squillace +Nicholas +Radu Matei +Matt Fisher +Johnnie Birch +Luke Wagner + +**Lin Clark:** Are there any announcements? +(none) + +**Lin Clark:** Lets talk about how we’re going to move from this version of WASI to a new version that uses handles + +**Dan Gohman:** Witx has been designed to anticipate interface types. It has String and Handle types. These are pretty close to the ones in interface types - PR 391 takes things to the next level and evolves the rest of the witx types towards the interface types. Going forward we need to get rid of the witx pointer and get buffers to work the way they will in interface types, but we’re still waiting to hear from interface types the final word on how those will work. See Interface Types issue 68. Our job on the witx side is to evolve into the Interface Types buffer types. Without waiting we can add support for strings and return types and lower them into the existing C ABI that WASI programs use. + +**Dan Gohman:** Another piece is WASI modularization. It has been in progress for a while but several pieces are coming together. Issue 378. Describes a more granular include mechanism than witx uses right now - import a symbol from a module, rather than import a file. + +**Dan Gohman:** The next two big pieces, which we can address in detail in the future: How do you pass handles into programs? Currently there is a table with preopens in it, but interface types is going to give us new mechanisms that are better than the preopen concept. + +**Dan Gohman:** The last piece is defining new abstractions. wasi PR 240 describes how to merge the send and recv on sockets with read and write on files. We can generalize part of files and sockets into a concept of I/O streams. In interface types you’ll have the vocabulary to ask for e.g. a stream you can write to, without knowing or caring that its backed by a socket or file or pipe etc. What is the noun that you use in function signatures to describe an I/O Stream? Beyond I/O Streams there’s non-streaming operations on files which don’t work on sockets or pipes - pread/pwrite - there’s a place for an I/O object with non-stream personality as well, an array of bytes or a we can call it a dynamic array because it can be resized. There will be other concepts as well - key-value stores, windowed IO with buffers... At the moment the nascent WASI I/O proposal will evolve to develop these ideas. There will still be files, and then a function that gives you a stream from a file. Files are going to be required to interop with existing systems, but we can push people towards interfaces that don’t tie them to the complications of those existing systems, particularly file semantics are very difficult to compose but streams are. This will help us enable shared-nothing linking of modules - we don’t want modules to have to share a filesystem to talk to each other. Questions? + +**Ralph Squillace:** What kinds of objections to this direction do you anticipate? + +**Dan Gohman:** This is going off the path of POSIX. Existing applications and programming languages will be more work to port to I/O streams than having us port libc and standard libraries to WASI. We have ideas for making the standard io operations work on top of I/O streams - you can treat an i/o stream as a libc FILE if you only ever read and write from it, other operations give an error. + +**Ralph Squillace:** The philosophical discussion is about how you weigh the objectives of different applications moving to WASI - some will have to adapt specific POSIX-isms to WASI, where does the work of porting existing code break down - does the code stay in WASM and not use WASI, have its own custom runtime - or does it move to WASI in the coherent way that resolves the semantic differences. I don’t personally see myself trying to port an existing huge monolithic application to WASI, whereas I do see myself working on libraries to make them work in WASI. + +**Lin Clark:** How much is WASI filesystem still going to allow porting POSIX applications? + +**Dan Gohman:** It will allow it. Its a question of priorities rather than absolutes. WASI today runs plenty of interesting POSIX code that doesnt do things like fork(2), WASI filesystem is going to still be there for these applications to use. But we don’t want that to be part of the default for WASI, we want to encourage applications to use simpler concepts that don’t imply a whole filesystem. I want to build tooling that bridges the gap between the shared-nothing-linking space and making big applications work. + +**Till Schneidereit:** We can look at this in terms of layering - there is a core of WASI that may not apply to every use case but you can virtualize many of the other needs on top of it. You can add a filesystem ion top of the core, in many cases, and let applications that need it use it. + +**Dan Gohman:** In terms of migration from where WASI is today to this ideal system - the WASI I/O abstractions can be worked on now, we have witx where we need it. We can flesh out exactly how streams and dynamic arrays work today. + +**Dan Gohman:** Another aspect is portability. I’ve been working on support for WASI on Windows vs Unix the last few months - there are so many differences between those platforms, the semantics of filesystems is radically different and there’s no portability in many cases (its too expensive to bridge them). The WASI I/O abstractions can be designed to hide all of the non-portable parts of filesystems. We can get away from having to specify “what does windows do here” and instead specify the things an application actually needs. + +**Ralph Squillace:** Layering will require thought. + +**Pat Hickey:** The customers we have writing applications right now aren’t concerned with the differences between the filesystem guarantees on linux vs windows, they care about http requests and responses. If we have I/O abstractions that unify the way http bodies work with the way certain aspects of the filesystem work, that is better for the applications we care about. + +**Till Schneidereit:** There are lots of use cases that work with streaming, which has traditionally been a file or a socket, but with abstractions that are hard to generalize. My interpretation of what you were just saying is that if we had a way to have a cleaner system that didn’t have that incidental platform dependence, it would be much easier to build code that works across these very different environments. We have all these applications that are popping up that are very different. Ideally we have a layer that doesn’t care about host differences, and then the layer that cares about that. What we do is just one specific example of that. Don’t want to optimize for old use cases, but all of the new novel ones that are coming about. + +**Radu Matei:** Is the assumption that wasi-filesystem will be developed in parallel? + +**Dan Gohman:** Yes, WASI-filesystem will continue, and wasi-io will be a peer. + +**Ralph Squillace:** Drawing older threads in, what about BSD sockets PR. + +**Dan Gohman:** The contributor who created that hasn’t been active, but I expect that will fit into the system in the same way as wasi-fs. You could get a stream. Networking is a complex topic and I dont’ want to simplify, but the first step will be to take sockets and say the socket gives you a stream that you can read, a stream you can write, and bi-directional r/w. + +Async is a subtlety that we’re leaving out. We can say that async is an orthogonal concern. We expect the Wasm platform will give us better answers over time. But the fundamental concepts of I/O are independent of whether you block that I/O. + +**Lin Clark:** Any other thoughts/comments + +**Luke Wagner:** I have a hypothesis I want to test. Why are people going to want to use wasm outside of a browser? Some people think it’s great because of ISA. We don’t think that’s a great motivator. We think running guest code in latency sensitive and low trust scenarios is the motivator. Things like routers ____ would be host APIs. The libraries would be wasm. These problematic cases don’t have a high value reason to be ported to Wasm. + +**Ralph Squillace:** I understand where you’re coming from. I don’t see WASI as a monolithic process sandbox. I do think that the idea about the sweet spot is right. I’m not a big believer in the thought that the world’s code is going to all be running on WASI. But I think it’s worth consideration how much of the world’s knowledge can be run as WASI. Shouldn’t wall off for all time, but I think the way that Dan laid out the direction, it lets us start with the sweet spot and either layer the others, or add support to WASI later on. I would hate to frame the boundary ruling out knowledge transfer. + +**Luke Wagner:** I agree with your points, so the layering and virtualization are also motivated by that. + +**Dan Gohman:** I can add one thing. Thinking of lib-c, and lots of languages have lib-c like std lib: under the covers, something that people are using as a file could be represented by streams. We can make that work under the covers. We could talk about how that will exactly work. But this is the framework. We can make porting easier by allowing you to use streams by allowing you to use files, but discourage from using file stat and depending on i node. + +**Andrew Brown:** It feels to me that filesystem should be in phase 3 or 4. How do these changes affect moving those to later stages + +**Dan Gohman:** That’s a great question. Wasi-fs is waiting to figure out it’s place. This conversation moves that forward. Understanding that wasi-fs won’t attempt to be abstracting over all hosts, wasi-io does that, and accepting that’s ok means that wasi-fs can probably move to phase 3 at this point. + +**Till Schneidereit:** I think the better way to put it is that it’s not an either/or, we don’t need to make it completely host specific, but let’s find a balance that’s actually viable. + +**Radu Matei:** do we have a document? + +**Dan Gohman:** Will be writing that up. Wanted to introduce here first. Will write up wasi-io ideas soon + +**Pat Hickey:** One blocker to wasi-fs advancing. The filesystem has cloud ABI system of rights. Need to work out what to do with that. From f91446f6afcd82cf377895f302f9f74046fa5a52 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Tue, 16 Feb 2021 12:54:08 -0500 Subject: [PATCH 0867/1772] Add 02-11 meeting notes --- .../filesystem/meetings/2021/WASI-02-11.md | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/proposals/filesystem/meetings/2021/WASI-02-11.md b/proposals/filesystem/meetings/2021/WASI-02-11.md index f56b6c537..c18c4b8fa 100644 --- a/proposals/filesystem/meetings/2021/WASI-02-11.md +++ b/proposals/filesystem/meetings/2021/WASI-02-11.md @@ -31,3 +31,88 @@ Installation is required, see the calendar invite. 1. Proposals and discussions 1. Discussion: What are the next steps in adapting WASI to use Interface Types handles and resources? 1. _Sumbit a PR to add your agenda item here_ + +## Notes +### Attendees +Pat Hickey +Andrew Brown +Sergey Rubanov +Lin Clark +Mark McCaskey +Till Schneidereit +Dan Gohman +Josh Dolitsky +Mingqiu Sun +Ralph Squillace +Nicholas +Radu Matei +Matt Fisher +Johnnie Birch +Luke Wagner + +**Lin Clark:** Are there any announcements? +(none) + +**Lin Clark:** Lets talk about how we’re going to move from this version of WASI to a new version that uses handles + +**Dan Gohman:** Witx has been designed to anticipate interface types. It has String and Handle types. These are pretty close to the ones in interface types - PR 391 takes things to the next level and evolves the rest of the witx types towards the interface types. Going forward we need to get rid of the witx pointer and get buffers to work the way they will in interface types, but we’re still waiting to hear from interface types the final word on how those will work. See Interface Types issue 68. Our job on the witx side is to evolve into the Interface Types buffer types. Without waiting we can add support for strings and return types and lower them into the existing C ABI that WASI programs use. + +**Dan Gohman:** Another piece is WASI modularization. It has been in progress for a while but several pieces are coming together. Issue 378. Describes a more granular include mechanism than witx uses right now - import a symbol from a module, rather than import a file. + +**Dan Gohman:** The next two big pieces, which we can address in detail in the future: How do you pass handles into programs? Currently there is a table with preopens in it, but interface types is going to give us new mechanisms that are better than the preopen concept. + +**Dan Gohman:** The last piece is defining new abstractions. wasi PR 240 describes how to merge the send and recv on sockets with read and write on files. We can generalize part of files and sockets into a concept of I/O streams. In interface types you’ll have the vocabulary to ask for e.g. a stream you can write to, without knowing or caring that its backed by a socket or file or pipe etc. What is the noun that you use in function signatures to describe an I/O Stream? Beyond I/O Streams there’s non-streaming operations on files which don’t work on sockets or pipes - pread/pwrite - there’s a place for an I/O object with non-stream personality as well, an array of bytes or a we can call it a dynamic array because it can be resized. There will be other concepts as well - key-value stores, windowed IO with buffers... At the moment the nascent WASI I/O proposal will evolve to develop these ideas. There will still be files, and then a function that gives you a stream from a file. Files are going to be required to interop with existing systems, but we can push people towards interfaces that don’t tie them to the complications of those existing systems, particularly file semantics are very difficult to compose but streams are. This will help us enable shared-nothing linking of modules - we don’t want modules to have to share a filesystem to talk to each other. Questions? + +**Ralph Squillace:** What kinds of objections to this direction do you anticipate? + +**Dan Gohman:** This is going off the path of POSIX. Existing applications and programming languages will be more work to port to I/O streams than having us port libc and standard libraries to WASI. We have ideas for making the standard io operations work on top of I/O streams - you can treat an i/o stream as a libc FILE if you only ever read and write from it, other operations give an error. + +**Ralph Squillace:** The philosophical discussion is about how you weigh the objectives of different applications moving to WASI - some will have to adapt specific POSIX-isms to WASI, where does the work of porting existing code break down - does the code stay in WASM and not use WASI, have its own custom runtime - or does it move to WASI in the coherent way that resolves the semantic differences. I don’t personally see myself trying to port an existing huge monolithic application to WASI, whereas I do see myself working on libraries to make them work in WASI. + +**Lin Clark:** How much is WASI filesystem still going to allow porting POSIX applications? + +**Dan Gohman:** It will allow it. Its a question of priorities rather than absolutes. WASI today runs plenty of interesting POSIX code that doesnt do things like fork(2), WASI filesystem is going to still be there for these applications to use. But we don’t want that to be part of the default for WASI, we want to encourage applications to use simpler concepts that don’t imply a whole filesystem. I want to build tooling that bridges the gap between the shared-nothing-linking space and making big applications work. + +**Till Schneidereit:** We can look at this in terms of layering - there is a core of WASI that may not apply to every use case but you can virtualize many of the other needs on top of it. You can add a filesystem ion top of the core, in many cases, and let applications that need it use it. + +**Dan Gohman:** In terms of migration from where WASI is today to this ideal system - the WASI I/O abstractions can be worked on now, we have witx where we need it. We can flesh out exactly how streams and dynamic arrays work today. + +**Dan Gohman:** Another aspect is portability. I’ve been working on support for WASI on Windows vs Unix the last few months - there are so many differences between those platforms, the semantics of filesystems is radically different and there’s no portability in many cases (its too expensive to bridge them). The WASI I/O abstractions can be designed to hide all of the non-portable parts of filesystems. We can get away from having to specify “what does windows do here” and instead specify the things an application actually needs. + +**Ralph Squillace:** Layering will require thought. + +**Pat Hickey:** The customers we have writing applications right now aren’t concerned with the differences between the filesystem guarantees on linux vs windows, they care about http requests and responses. If we have I/O abstractions that unify the way http bodies work with the way certain aspects of the filesystem work, that is better for the applications we care about. + +**Till Schneidereit:** There are lots of use cases that work with streaming, which has traditionally been a file or a socket, but with abstractions that are hard to generalize. My interpretation of what you were just saying is that if we had a way to have a cleaner system that didn’t have that incidental platform dependence, it would be much easier to build code that works across these very different environments. We have all these applications that are popping up that are very different. Ideally we have a layer that doesn’t care about host differences, and then the layer that cares about that. What we do is just one specific example of that. Don’t want to optimize for old use cases, but all of the new novel ones that are coming about. + +**Radu Matei:** Is the assumption that wasi-filesystem will be developed in parallel? + +**Dan Gohman:** Yes, WASI-filesystem will continue, and wasi-io will be a peer. + +**Ralph Squillace:** Drawing older threads in, what about BSD sockets PR. + +**Dan Gohman:** The contributor who created that hasn’t been active, but I expect that will fit into the system in the same way as wasi-fs. You could get a stream. Networking is a complex topic and I dont’ want to simplify, but the first step will be to take sockets and say the socket gives you a stream that you can read, a stream you can write, and bi-directional r/w. + +Async is a subtlety that we’re leaving out. We can say that async is an orthogonal concern. We expect the Wasm platform will give us better answers over time. But the fundamental concepts of I/O are independent of whether you block that I/O. + +**Lin Clark:** Any other thoughts/comments + +**Luke Wagner:** I have a hypothesis I want to test. Why are people going to want to use wasm outside of a browser? Some people think it’s great because of ISA. We don’t think that’s a great motivator. We think running guest code in latency sensitive and low trust scenarios is the motivator. Things like routers ____ would be host APIs. The libraries would be wasm. These problematic cases don’t have a high value reason to be ported to Wasm. + +**Ralph Squillace:** I understand where you’re coming from. I don’t see WASI as a monolithic process sandbox. I do think that the idea about the sweet spot is right. I’m not a big believer in the thought that the world’s code is going to all be running on WASI. But I think it’s worth consideration how much of the world’s knowledge can be run as WASI. Shouldn’t wall off for all time, but I think the way that Dan laid out the direction, it lets us start with the sweet spot and either layer the others, or add support to WASI later on. I would hate to frame the boundary ruling out knowledge transfer. + +**Luke Wagner:** I agree with your points, so the layering and virtualization are also motivated by that. + +**Dan Gohman:** I can add one thing. Thinking of lib-c, and lots of languages have lib-c like std lib: under the covers, something that people are using as a file could be represented by streams. We can make that work under the covers. We could talk about how that will exactly work. But this is the framework. We can make porting easier by allowing you to use streams by allowing you to use files, but discourage from using file stat and depending on i node. + +**Andrew Brown:** It feels to me that filesystem should be in phase 3 or 4. How do these changes affect moving those to later stages + +**Dan Gohman:** That’s a great question. Wasi-fs is waiting to figure out it’s place. This conversation moves that forward. Understanding that wasi-fs won’t attempt to be abstracting over all hosts, wasi-io does that, and accepting that’s ok means that wasi-fs can probably move to phase 3 at this point. + +**Till Schneidereit:** I think the better way to put it is that it’s not an either/or, we don’t need to make it completely host specific, but let’s find a balance that’s actually viable. + +**Radu Matei:** do we have a document? + +**Dan Gohman:** Will be writing that up. Wanted to introduce here first. Will write up wasi-io ideas soon + +**Pat Hickey:** One blocker to wasi-fs advancing. The filesystem has cloud ABI system of rights. Need to work out what to do with that. From e2b11481f302492d5ec0d034e94fa29598f73194 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 18 Feb 2021 11:39:17 -0600 Subject: [PATCH 0868/1772] Take another step towards interface types (#395) * Take another step towards interface types This commit is another large refactoring on the tail of #391 which is intended to help march one step closer to using pure interface types for specifying WASI and using `*.witx` files. Contained here is a large amount of refactoring of the `*.witx` files, the internals of the `witx` crate, and how code generators are supposed to work. At the `*.witx` level, some notable changes have been made: * All functions returning results now return `(expected ok? (error $errno))`. This helps signify that the intention of all functions is that they return a packaged value which is either a successful result or the erroneous error code on failure. ABI-wise nothing has changed, but this is intended to model more closely what the interface-types API of this would be. * The `flags` type in `*.witx` now desugars as a struct-of-bools rather than simply an `int`. This doesn't have any effect on the ABI today, but it does change the AST and type-level representation of these types. All existing `*.witx` files in this repository have been updated for all phases with these new forms. To reiterate, though, no details of the ABI have changed (or at least not intentionally). Everything should still be ABI-compatible with before. Under the hood for code generators this is a very large breaking change. The intention of this commit is to start moving code generators relying on `witx` into the direction that we'll end up with interface types. Namely the `coretypes` module is entirely replaced with a new `abi` module with the intention of handling lots more high-level details of translation than the previous module did. The `InterfaceFunc` type now sports two new methods: `call_wasm` and `call_interface`. These two methods represent the two halves of lifting/lowering operations performed by code generators. The `call_wasm` function takes interface types values (or whatever they are represented as in the source language) and converts them to wasm types to call a wasm import. The wasm import's return values are then "deserialized" back into the language's interface types values too. The `call_interface` function is the opposite, it assumes that you're coming from wasm values and calling, e.g., a host function with interface values. The `abi` module is refactored with an `Instruction` `enum` which lists out what are the current set of "adapter instructions". These adapter instructions are intended to somewhat model the eventual idea of adapter functions and their instructions, but for now they're pretty specific to WASI as-is today. All instructions currently model what WASI currently does, sometimes in very specific manners. It's expected that the `Instruction` type will be in flux as we tweak the ABI of WASI over time, but the current set of instructions will likely only be expanded because of maintaining compatibility with the current snapshot. The expected usage of `Instruction` is that code generators will implement how to generate code for each `Instruction`. This should be a very low-level operation (generating code per instruction) and should be in theory quite easy to implement. Not all code generators need to implement all instructions depending on their use case. Additionally WASI as-is today doesn't always exercise all types of instructions. The next steps after a PR like this include starting to define a new ABI for WASI which supports all types in all positions rather than the current ABI which supports only a limited subset of types in some positions. The intention is that this new ABI may add a new instruction or two but will generally not be a large breaking change for all existing code generators. Some new additions are expected but other than that existing code generators updated to use this PR will require little effort to support new ABIs. * Add more documentation and some more tests for shorthand syntax * Bump to 0.9.0 and bump wast dependency * Support variants as arguments Same as records, they use pointers * Fix a typo --- proposals/clocks/phases/ephemeral/docs.md | 969 +++++++++++++----- .../phases/ephemeral/witx/typenames.witx | 22 +- .../ephemeral/witx/wasi_ephemeral_args.witx | 10 +- .../ephemeral/witx/wasi_ephemeral_clock.witx | 6 +- .../witx/wasi_ephemeral_environ.witx | 10 +- .../ephemeral/witx/wasi_ephemeral_fd.witx | 54 +- .../ephemeral/witx/wasi_ephemeral_path.witx | 25 +- .../ephemeral/witx/wasi_ephemeral_poll.witx | 3 +- .../ephemeral/witx/wasi_ephemeral_random.witx | 2 +- .../ephemeral/witx/wasi_ephemeral_sched.witx | 2 +- .../ephemeral/witx/wasi_ephemeral_sock.witx | 12 +- .../clocks/phases/old/snapshot_0/docs.md | 929 +++++++++++++---- .../phases/old/snapshot_0/witx/typenames.witx | 20 +- .../old/snapshot_0/witx/wasi_unstable.witx | 127 +-- proposals/clocks/phases/snapshot/docs.md | 927 +++++++++++++---- .../phases/snapshot/witx/typenames.witx | 20 +- .../snapshot/witx/wasi_snapshot_preview1.witx | 125 +-- proposals/clocks/tools/witx/Cargo.toml | 4 +- proposals/clocks/tools/witx/src/abi.rs | 925 +++++++++++++++++ proposals/clocks/tools/witx/src/ast.rs | 178 +++- proposals/clocks/tools/witx/src/coretypes.rs | 173 ---- proposals/clocks/tools/witx/src/docs/ast.rs | 93 +- proposals/clocks/tools/witx/src/docs/md.rs | 51 +- proposals/clocks/tools/witx/src/layout.rs | 26 +- proposals/clocks/tools/witx/src/lib.rs | 6 +- proposals/clocks/tools/witx/src/parser.rs | 77 +- proposals/clocks/tools/witx/src/render.rs | 61 +- proposals/clocks/tools/witx/src/toplevel.rs | 6 +- proposals/clocks/tools/witx/src/validate.rs | 172 +++- proposals/clocks/tools/witx/tests/witxt.rs | 249 ++++- .../clocks/tools/witx/tests/witxt/abi.witxt | 490 +++++++++ .../witx/tests/witxt/representation.witxt | 4 +- .../tools/witx/tests/witxt/shorthand.witxt | 59 ++ 33 files changed, 4528 insertions(+), 1309 deletions(-) create mode 100644 proposals/clocks/tools/witx/src/abi.rs delete mode 100644 proposals/clocks/tools/witx/src/coretypes.rs create mode 100644 proposals/clocks/tools/witx/tests/witxt/abi.witxt create mode 100644 proposals/clocks/tools/witx/tests/witxt/shorthand.witxt diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index a3c0d0a47..7fa4c11de 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -22,7 +22,7 @@ Size: 8 Alignment: 8 -## `clockid`: Variant +## `clockid`: `Variant` Identifiers for clocks. Size: 4 @@ -40,7 +40,7 @@ real time, whose value cannot be adjusted and which cannot have negative clock jumps. The epoch of this clock is undefined. The absolute time value of this clock therefore has no meaning. -## `errno`: Variant +## `errno`: `Variant` Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -282,82 +282,120 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: `u64` +## `rights`: `Record` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Constants -- `fd_datasync` +### Record members +- `fd_datasync`: `bool` The right to invoke `fd_datasync`. If `path_open` is set, includes the right to invoke `path_open` with [`fdflags::dsync`](#fdflags.dsync). -- `fd_read` +Bit: 0 + +- `fd_read`: `bool` The right to invoke `fd_read` and `sock_recv`. If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. -- `fd_seek` +Bit: 1 + +- `fd_seek`: `bool` The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). -- `fd_fdstat_set_flags` +Bit: 2 + +- `fd_fdstat_set_flags`: `bool` The right to invoke `fd_fdstat_set_flags`. -- `fd_sync` +Bit: 3 + +- `fd_sync`: `bool` The right to invoke `fd_sync`. If `path_open` is set, includes the right to invoke `path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). -- `fd_tell` +Bit: 4 + +- `fd_tell`: `bool` The right to invoke `fd_seek` in such a way that the file offset remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke `fd_tell`. -- `fd_write` +Bit: 5 + +- `fd_write`: `bool` The right to invoke `fd_write` and `sock_send`. If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. -- `fd_advise` +Bit: 6 + +- `fd_advise`: `bool` The right to invoke `fd_advise`. -- `fd_allocate` +Bit: 7 + +- `fd_allocate`: `bool` The right to invoke `fd_allocate`. -- `path_create_directory` +Bit: 8 + +- `path_create_directory`: `bool` The right to invoke `path_create_directory`. -- `path_create_file` +Bit: 9 + +- `path_create_file`: `bool` If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). -- `path_link_source` +Bit: 10 + +- `path_link_source`: `bool` The right to invoke `path_link` with the file descriptor as the source directory. -- `path_link_target` +Bit: 11 + +- `path_link_target`: `bool` The right to invoke `path_link` with the file descriptor as the target directory. -- `path_open` +Bit: 12 + +- `path_open`: `bool` The right to invoke `path_open`. -- `fd_readdir` +Bit: 13 + +- `fd_readdir`: `bool` The right to invoke `fd_readdir`. -- `path_readlink` +Bit: 14 + +- `path_readlink`: `bool` The right to invoke `path_readlink`. -- `path_rename_source` +Bit: 15 + +- `path_rename_source`: `bool` The right to invoke `path_rename` with the file descriptor as the source directory. -- `path_rename_target` +Bit: 16 + +- `path_rename_target`: `bool` The right to invoke `path_rename` with the file descriptor as the target directory. -- `path_filestat_get` +Bit: 17 + +- `path_filestat_get`: `bool` The right to invoke `path_filestat_get`. -- `path_filestat_set_size` +Bit: 18 + +- `path_filestat_set_size`: `bool` The right to change a file's size. If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). Note: there is no function named `path_filestat_set_size`. This follows POSIX design, @@ -366,41 +404,65 @@ While such function would be desirable from the API design perspective, there ar no use cases for it since no code written for POSIX systems would use it. Moreover, implementing it would require multiple syscalls, leading to inferior performance. -- `path_filestat_set_times` +Bit: 19 + +- `path_filestat_set_times`: `bool` The right to invoke `path_filestat_set_times`. -- `path_permissions_set` +Bit: 20 + +- `path_permissions_set`: `bool` The right to invoke `path_permissions_set`. -- `fd_filestat_get` +Bit: 21 + +- `fd_filestat_get`: `bool` The right to invoke `fd_filestat_get`. -- `fd_filestat_set_size` +Bit: 22 + +- `fd_filestat_set_size`: `bool` The right to invoke `fd_filestat_set_size`. -- `fd_filestat_set_times` +Bit: 23 + +- `fd_filestat_set_times`: `bool` The right to invoke `fd_filestat_set_times`. -- `fd_permissions_set` +Bit: 24 + +- `fd_permissions_set`: `bool` The right to invoke `fd_permissions_set`. -- `path_symlink` +Bit: 25 + +- `path_symlink`: `bool` The right to invoke `path_symlink`. -- `path_remove_directory` +Bit: 26 + +- `path_remove_directory`: `bool` The right to invoke `path_remove_directory`. -- `path_unlink_file` +Bit: 27 + +- `path_unlink_file`: `bool` The right to invoke `path_unlink_file`. -- `poll_fd_readwrite` +Bit: 28 + +- `poll_fd_readwrite`: `bool` If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). -- `sock_shutdown` +Bit: 29 + +- `sock_shutdown`: `bool` The right to invoke `sock_shutdown`. -## `fd` +Bit: 30 + +## `fd`: `Handle` A file descriptor handle. Size: 4 @@ -408,7 +470,7 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Record +## `iovec`: `Record` A region of memory for scatter/gather reads. Size: 8 @@ -426,7 +488,7 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Record +## `ciovec`: `Record` A region of memory for scatter/gather writes. Size: 8 @@ -463,7 +525,7 @@ Size: 8 Alignment: 8 -## `whence`: Variant +## `whence`: `Variant` The position relative to which to set the offset of the file descriptor. Size: 1 @@ -504,7 +566,7 @@ Size: 8 Alignment: 8 -## `filetype`: Variant +## `filetype`: `Variant` The type of a file descriptor or file. Size: 1 @@ -539,7 +601,7 @@ The file refers to a symbolic link inode. - `fifo` The file descriptor or file refers to a FIFO. -## `dirent`: Record +## `dirent`: `Record` A directory entry. Size: 24 @@ -567,7 +629,7 @@ The length of the name of the directory entry. Offset: 20 -## `advice`: Variant +## `advice`: `Variant` File or memory access pattern advisory information. Size: 1 @@ -593,32 +655,42 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: `u16` +## `fdflags`: `Record` File descriptor flags. Size: 2 Alignment: 2 -### Constants -- `append` +### Record members +- `append`: `bool` Append mode: Data written to the file is always appended to the file's end. -- `dsync` +Bit: 0 + +- `dsync`: `bool` Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. -- `nonblock` +Bit: 1 + +- `nonblock`: `bool` Non-blocking mode. -- `rsync` +Bit: 2 + +- `rsync`: `bool` Synchronized read I/O operations. -- `sync` +Bit: 3 + +- `sync`: `bool` Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Record +Bit: 4 + +## `fdstat`: `Record` File descriptor attributes. Size: 24 @@ -655,57 +727,75 @@ Size: 8 Alignment: 8 -## `fstflags`: `u16` +## `fstflags`: `Record` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Constants -- `atim` +### Record members +- `atim`: `bool` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). -- `atim_now` +Bit: 0 + +- `atim_now`: `bool` Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -- `mtim` +Bit: 1 + +- `mtim`: `bool` Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). -- `mtim_now` +Bit: 2 + +- `mtim_now`: `bool` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: `u32` +Bit: 3 + +## `lookupflags`: `Record` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Constants -- `symlink_follow` +### Record members +- `symlink_follow`: `bool` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: `u16` +Bit: 0 + +## `oflags`: `Record` Open flags used by `path_open`. Size: 2 Alignment: 2 -### Constants -- `create` +### Record members +- `create`: `bool` Create file if it does not exist. -- `directory` +Bit: 0 + +- `directory`: `bool` Fail if not a directory. -- `excl` +Bit: 1 + +- `excl`: `bool` Fail if file already exists. -- `trunc` +Bit: 2 + +- `trunc`: `bool` Truncate file to size 0. +Bit: 3 + ## `linkcount`: `u64` Number of hard links to an inode. @@ -713,7 +803,7 @@ Size: 8 Alignment: 8 -## `permissions`: `u8` +## `permissions`: `Record` File permissions. This represents the permissions associated with a file in a filesystem, and don't fully reflect all the conditions which determine whether a given WASI program can access the file. @@ -722,8 +812,8 @@ Size: 1 Alignment: 1 -### Constants -- `read` +### Record members +- `read`: `bool` For files, permission to read the file. For directories, permission to do [`readdir`](#readdir) and access files within the directory. @@ -731,23 +821,31 @@ within the directory. Note: This is similar to the read bit being set on files, and the read *and* execute bits being set on directories, in POSIX. -- `write` +Bit: 0 + +- `write`: `bool` For files, permission to mutate the file. For directories, permission to create, remove, and rename items within the directory. -- `execute` +Bit: 1 + +- `execute`: `bool` For files, permission to "execute" the file, using whatever concept of "executing" the host filesystem has. This flag is not valid for directories. -- `private` +Bit: 2 + +- `private`: `bool` For filesystems which have a concept of multiple "users", this flag indicates that the file is only accessible by the effective "user" that the WASI store uses to access the filesystem, and inaccessible to other "users". -## `filestat`: Record +Bit: 3 + +## `filestat`: `Record` File attributes. Size: 64 @@ -808,7 +906,7 @@ Size: 8 Alignment: 8 -## `eventtype`: Variant +## `eventtype`: `Variant` Type of a subscription to an event or its occurrence. Size: 1 @@ -828,7 +926,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: `u16` +## `eventrwflags`: `Record` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -836,11 +934,13 @@ Size: 2 Alignment: 2 -### Constants -- `fd_readwrite_hangup` +### Record members +- `fd_readwrite_hangup`: `bool` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Record +Bit: 0 + +## `event_fd_readwrite`: `Record` The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -859,7 +959,7 @@ The state of the file descriptor. Offset: 8 -## `event_u`: Variant +## `event_u`: `Variant` The contents of an [`event`](#event). Size: 24 @@ -877,7 +977,7 @@ Alignment: 8 - `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) -## `event`: Record +## `event`: `Record` An event that occurred. Size: 40 @@ -900,7 +1000,7 @@ The type of the event that occurred, and the contents of the event Offset: 16 -## `subclockflags`: `u16` +## `subclockflags`: `Record` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -908,15 +1008,17 @@ Size: 2 Alignment: 2 -### Constants -- `subscription_clock_abstime` +### Record members +- `subscription_clock_abstime`: `bool` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock [`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Record +Bit: 0 + +## `subscription_clock`: `Record` The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 32 @@ -945,7 +1047,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 24 -## `subscription_fd_readwrite`: Record +## `subscription_fd_readwrite`: `Record` The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -959,7 +1061,7 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Variant +## `subscription_u`: `Variant` The contents of a [`subscription`](#subscription). Size: 40 @@ -977,7 +1079,7 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Record +## `subscription`: `Record` Subscription to an event. Size: 48 @@ -1003,31 +1105,37 @@ Size: 4 Alignment: 4 -## `riflags`: `u16` +## `riflags`: `Record` Flags provided to `sock_recv`. Size: 2 Alignment: 2 -### Constants -- `recv_peek` +### Record members +- `recv_peek`: `bool` Returns the message without removing it from the socket's receive queue. -- `recv_waitall` +Bit: 0 + +- `recv_waitall`: `bool` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: `u16` +Bit: 1 + +## `roflags`: `Record` Flags returned by `sock_recv`. Size: 2 Alignment: 2 -### Constants -- `recv_data_truncated` +### Record members +- `recv_data_truncated`: `bool` Returned by `sock_recv`: Message data has been truncated. +Bit: 0 + ## `siflags`: `u16` Flags provided to `sock_send`. As there are currently no flags defined, it must be set to zero. @@ -1036,21 +1144,25 @@ Size: 2 Alignment: 2 -## `sdflags`: `u8` +## `sdflags`: `Record` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Constants -- `rd` +### Record members +- `rd`: `bool` Disables further receive operations. -- `wr` +Bit: 0 + +- `wr`: `bool` Disables further send operations. -## `preopentype`: Variant +Bit: 1 + +## `preopentype`: `Variant` Identifiers for preopened capabilities. Size: 1 @@ -1061,7 +1173,7 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Record +## `prestat_dir`: `Record` The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). Size: 4 @@ -1074,7 +1186,7 @@ The length of the directory name for use with `fd_prestat_dir_name`. Offset: 0 -## `prestat`: Variant +## `prestat`: `Variant` Information about a pre-opened capability. Size: 8 @@ -1097,7 +1209,7 @@ When type is [`preopentype::dir`](#preopentype.dir): --- -#### `get(argv: Pointer>, argv_buf: Pointer) -> errno` +#### `get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. The size of the array should match that returned by [`sizes_get`](#sizes_get) @@ -1107,23 +1219,46 @@ The size of the array should match that returned by [`sizes_get`](#sizes_get) - `argv_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sizes_get() -> (errno, size, size)` +#### `sizes_get() -> Result<(size, size), errno>` Return command-line argument data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of arguments and the size of the argument string +data, or an error. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` -- `argc`: [`size`](#size) -The number of arguments. +####### Record members +- `0`: [`size`](#size) -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +Offset: 0 + +- `1`: [`size`](#size) + +Offset: 4 + +- `err`: [`errno`](#errno) ## wasi_ephemeral_clock ### Imports @@ -1132,7 +1267,7 @@ The size of the argument string data. --- -#### `res_get(id: clockid) -> (errno, timestamp)` +#### `res_get(id: clockid) -> Result` Return the resolution of a clock. Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return [`errno::inval`](#errno.inval). @@ -1143,15 +1278,22 @@ Note: This is similar to `clock_getres` in POSIX. The clock for which to return the resolution. ##### Results -- `error`: [`errno`](#errno) - -- `resolution`: [`timestamp`](#timestamp) +- `error`: `Result` The resolution of the clock. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) + +- `err`: [`errno`](#errno) + --- -#### `time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +#### `time_get(id: clockid, precision: timestamp) -> Result` Return the time value of a clock. Note: This is similar to `clock_gettime` in POSIX. @@ -1163,11 +1305,18 @@ The clock for which to return the time. The maximum lag (exclusive) that the returned time value may have, compared to its actual value. ##### Results -- `error`: [`errno`](#errno) - -- `time`: [`timestamp`](#timestamp) +- `error`: `Result` The time value of the clock. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) + +- `err`: [`errno`](#errno) + ## wasi_ephemeral_environ ### Imports #### Memory @@ -1175,7 +1324,7 @@ The time value of the clock. --- -#### `get(environ: Pointer>, environ_buf: Pointer) -> errno` +#### `get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). @@ -1185,23 +1334,46 @@ The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get) - `environ_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sizes_get() -> (errno, size, size)` +#### `sizes_get() -> Result<(size, size), errno>` Return environment variable data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of environment variable arguments and the size of the +environment variable data. -- `environc`: [`size`](#size) -The number of environment variable arguments. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) + +Offset: 0 -- `environ_buf_size`: [`size`](#size) -The size of the environment variable data. +- `1`: [`size`](#size) + +Offset: 4 + +- `err`: [`errno`](#errno) ## wasi_ephemeral_fd ### Imports @@ -1210,7 +1382,7 @@ The size of the environment variable data. --- -#### `advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +#### `advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` Provide file advisory information on a file descriptor. Note: This is similar to `posix_fadvise` in POSIX. @@ -1227,12 +1399,21 @@ The length of the region to which the advisory applies. The advice. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `allocate(fd: fd, offset: filesize, len: filesize) -> errno` +#### `allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` Force the allocation of space in a file. Note: This is similar to `posix_fallocate` in POSIX. @@ -1246,12 +1427,21 @@ The offset at which to start the allocation. The length of the area that is allocated. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `close(fd: fd) -> errno` +#### `close(fd: fd) -> Result<(), errno>` Close a file descriptor. Note: This is similar to [`close`](#close) in POSIX. @@ -1259,12 +1449,21 @@ Note: This is similar to [`close`](#close) in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `datasync(fd: fd) -> errno` +#### `datasync(fd: fd) -> Result<(), errno>` Synchronize the data of a file to disk. Note: This is similar to `fdatasync` in POSIX. @@ -1272,12 +1471,21 @@ Note: This is similar to `fdatasync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fdstat_get(fd: fd) -> (errno, fdstat)` +#### `fdstat_get(fd: fd) -> Result` Get the attributes of a file descriptor. Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. @@ -1285,15 +1493,22 @@ Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as ad - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `stat`: [`fdstat`](#fdstat) +- `error`: `Result` The buffer where the file descriptor's attributes are stored. +###### Variant Layout +- size: 32 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`fdstat`](#fdstat) + +- `err`: [`errno`](#errno) + --- -#### `fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +#### `fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` Adjust the flags associated with a file descriptor. Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. @@ -1304,12 +1519,21 @@ Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. The desired values of the file descriptor flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +#### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` Adjust the rights associated with a file descriptor. This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights @@ -1322,27 +1546,43 @@ The desired rights of the file descriptor. - `fs_rights_inheriting`: [`rights`](#rights) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `filestat_get(fd: fd) -> (errno, filestat)` +#### `filestat_get(fd: fd) -> Result` Return the attributes of an open file. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 72 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `filestat_set_size(fd: fd, size: filesize) -> errno` +#### `filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. Note: This is similar to `ftruncate` in POSIX. @@ -1353,12 +1593,21 @@ Note: This is similar to `ftruncate` in POSIX. The desired file size. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of an open file or directory. Note: This is similar to `futimens` in POSIX. @@ -1375,12 +1624,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `permissions_set(fd: fd, permissions: permissions) -> errno` +#### `permissions_set(fd: fd, permissions: permissions) -> Result<(), errno>` Set the permissions of a file or directory. This sets the permissions associated with a file or directory in @@ -1401,12 +1659,21 @@ umask to determine which of the user/group/other flags to modify. The permissions associated with the file. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +#### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` Read from a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `preadv` in Linux (and other Unix-es). @@ -1420,30 +1687,44 @@ List of scatter/gather vectors in which to store data. The offset within the file at which to read. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `prestat_get(fd: fd) -> (errno, prestat)` +#### `prestat_get(fd: fd) -> Result` Return a description of the given preopened file descriptor. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`prestat`](#prestat) +- `error`: `Result` The buffer where the description is stored. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`prestat`](#prestat) + +- `err`: [`errno`](#errno) + --- -#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` Return a description of the given preopened file descriptor. ##### Params @@ -1455,12 +1736,21 @@ A buffer into which to write the preopened directory name. - `path_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +#### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` Write to a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `pwritev` in Linux (and other Unix-es). @@ -1478,15 +1768,22 @@ List of scatter/gather vectors from which to retrieve data. The offset within the file at which to write. ##### Results -- `error`: [`errno`](#errno) - -- `nwritten`: [`size`](#size) +- `error`: `Result` The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `read(fd: fd, iovs: iovec_array) -> (errno, size)` +#### `read(fd: fd, iovs: iovec_array) -> Result` Read from a file descriptor. Note: This is similar to `readv` in POSIX. @@ -1497,15 +1794,22 @@ Note: This is similar to `readv` in POSIX. List of scatter/gather vectors to which to store data. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +#### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of directory entries. Each directory entry consists of a [`dirent`](#dirent) object, @@ -1528,15 +1832,22 @@ The buffer where directory entries are stored The location within the directory to start reading ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `renumber(fd: fd, to: fd) -> errno` +#### `renumber(fd: fd, to: fd) -> Result<(), errno>` Atomically replace a file descriptor by renumbering another file descriptor. Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary @@ -1553,12 +1864,21 @@ would disappear if `dup2()` were to be removed entirely. The file descriptor to overwrite. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +#### `seek(fd: fd, offset: filedelta, whence: whence) -> Result` Move the offset of a file descriptor. Note: This is similar to `lseek` in POSIX. @@ -1572,15 +1892,22 @@ The number of bytes to move. The base from which the offset is relative. ##### Results -- `error`: [`errno`](#errno) - -- `newoffset`: [`filesize`](#filesize) +- `error`: `Result` The new offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `sync(fd: fd) -> errno` +#### `sync(fd: fd) -> Result<(), errno>` Synchronize the data and metadata of a file to disk. Note: This is similar to `fsync` in POSIX. @@ -1588,12 +1915,21 @@ Note: This is similar to `fsync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `tell(fd: fd) -> (errno, filesize)` +#### `tell(fd: fd) -> Result` Return the current offset of a file descriptor. Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. @@ -1601,15 +1937,22 @@ Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `offset`: [`filesize`](#filesize) +- `error`: `Result` The current offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `write(fd: fd, iovs: ciovec_array) -> (errno, size)` +#### `write(fd: fd, iovs: ciovec_array) -> Result` Write to a file descriptor. Note: This is similar to `writev` in POSIX. @@ -1624,11 +1967,18 @@ interleaved while [`write`](#write) is executed. List of scatter/gather vectors from which to retrieve data. ##### Results -- `error`: [`errno`](#errno) - -- `nwritten`: [`size`](#size) +- `error`: `Result` The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + ## wasi_ephemeral_path ### Imports #### Memory @@ -1636,7 +1986,7 @@ The number of bytes written. --- -#### `create_directory(fd: fd, path: string) -> errno` +#### `create_directory(fd: fd, path: string) -> Result<(), errno>` Create a directory. Note: This is similar to `mkdirat` in POSIX. @@ -1647,12 +1997,21 @@ Note: This is similar to `mkdirat` in POSIX. The path at which to create the directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +#### `filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` Return the attributes of a file or directory. Note: This is similar to `stat` in POSIX. @@ -1666,15 +2025,22 @@ Flags determining the method of how the path is resolved. The path of the file or directory to inspect. ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 72 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of a file or directory. Note: This is similar to `utimensat` in POSIX. @@ -1697,12 +2063,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `permissions_set(fd: fd, flags: lookupflags, path: string, permissions: permissions) -> errno` +#### `permissions_set(fd: fd, flags: lookupflags, path: string, permissions: permissions) -> Result<(), errno>` Set the permissions of a file or directory. This sets the permissions associated with a file or directory in @@ -1729,12 +2104,21 @@ The path to a file to query. The permissions to associate with the file. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Create a hard link. Note: This is similar to `linkat` in POSIX. @@ -1754,12 +2138,21 @@ The working directory at which the resolution of the new path starts. The destination path at which to create the hard link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, permissions: permissions) -> (errno, fd)` +#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, permissions: permissions) -> Result` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1798,15 +2191,22 @@ file descriptors derived from it. If a file is created, the filesystem permissions to associate with it. ##### Results -- `error`: [`errno`](#errno) - -- `opened_fd`: [`fd`](#fd) +- `error`: `Result` The file descriptor of the file that has been opened. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`fd`](#fd) + +- `err`: [`errno`](#errno) + --- -#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` Read the contents of a symbolic link. Note: This is similar to `readlinkat` in POSIX. @@ -1822,15 +2222,22 @@ The buffer to which to write the contents of the symbolic link. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes placed in the buffer. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `remove_directory(fd: fd, path: string) -> errno` +#### `remove_directory(fd: fd, path: string) -> Result<(), errno>` Remove a directory. Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. @@ -1842,12 +2249,21 @@ Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. The path to a directory to remove. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Rename a file or directory. Note: This is similar to `renameat` in POSIX. @@ -1864,12 +2280,21 @@ The working directory at which the resolution of the new path starts. The destination path to which to rename the file or directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `symlink(old_path: string, fd: fd, new_path: string) -> errno` +#### `symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` Create a symbolic link. Note: This is similar to `symlinkat` in POSIX. @@ -1883,12 +2308,21 @@ The contents of the symbolic link. The destination path at which to create the symbolic link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `unlink_file(fd: fd, path: string) -> errno` +#### `unlink_file(fd: fd, path: string) -> Result<(), errno>` Unlink a file. Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. @@ -1900,7 +2334,16 @@ Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. The path to a file to unlink. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) ## wasi_ephemeral_poll ### Imports @@ -1909,7 +2352,7 @@ The path to a file to unlink. --- -#### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +#### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` Concurrently poll for the occurrence of a set of events. If `nsubscriptions` is 0, returns [`errno::inval`](#errno.inval). @@ -1925,11 +2368,18 @@ The events that have occurred. Both the number of subscriptions and events. ##### Results -- `error`: [`errno`](#errno) - -- `nevents`: [`size`](#size) +- `error`: `Result` The number of events stored. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + ## wasi_ephemeral_proc ### Imports ### Functions @@ -1953,7 +2403,7 @@ The exit code returned by the process. --- -#### `get(buf: Pointer, buf_len: size) -> errno` +#### `get(buf: Pointer, buf_len: size) -> Result<(), errno>` Write high-quality random data into a buffer. This function blocks when the implementation is unable to immediately provide sufficient high-quality random data. @@ -1968,7 +2418,16 @@ The buffer to fill with random data. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) ## wasi_ephemeral_sched ### Imports @@ -1976,13 +2435,22 @@ The buffer to fill with random data. --- -#### `yield() -> errno` +#### `yield() -> Result<(), errno>` Temporarily yield execution of the calling thread. Note: This is similar to [`yield`](#yield) in POSIX. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) ## wasi_ephemeral_sock ### Imports @@ -1991,7 +2459,7 @@ Note: This is similar to [`yield`](#yield) in POSIX. --- -#### `recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +#### `recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` Receive a message from a socket. Note: This is similar to [`recv`](#recv) in POSIX, though it also supports reading the data into multiple buffers in the manner of `readv`. @@ -2006,18 +2474,31 @@ List of scatter/gather vectors to which to store data. Message flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, roflags), errno>` +Number of bytes stored in ri_data and message flags. -- `ro_datalen`: [`size`](#size) -Number of bytes stored in ri_data. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, roflags)` -- `ro_flags`: [`roflags`](#roflags) -Message flags. +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`roflags`](#roflags) + +Offset: 4 + +- `err`: [`errno`](#errno) --- -#### `send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +#### `send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` Send a message on a socket. Note: This is similar to [`send`](#send) in POSIX, though it also supports writing the data from multiple buffers in the manner of `writev`. @@ -2032,15 +2513,22 @@ List of scatter/gather vectors to which to retrieve data Message flags. ##### Results -- `error`: [`errno`](#errno) - -- `so_datalen`: [`size`](#size) +- `error`: `Result` Number of bytes transmitted. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `shutdown(fd: fd, how: sdflags) -> errno` +#### `shutdown(fd: fd, how: sdflags) -> Result<(), errno>` Shut down socket send and receive channels. Note: This is similar to [`shutdown`](#shutdown) in POSIX. @@ -2051,5 +2539,14 @@ Note: This is similar to [`shutdown`](#shutdown) in POSIX. Which channels on the socket to shut down. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 503aa0cf6..1f9abc59b 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -195,7 +195,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags (@witx bitflags u64) + (flags (@witx repr u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke @@ -392,7 +392,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -429,7 +429,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -443,7 +443,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags (@witx bitflags u32) + (flags (@witx repr u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -451,7 +451,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Create file if it does not exist. $create ;;; Fail if not a directory. @@ -470,7 +470,7 @@ ;;; file in a filesystem, and don't fully reflect all the conditions ;;; which determine whether a given WASI program can access the file. (typename $permissions - (flags (@witx bitflags u8) + (flags (@witx repr u8) ;;; For files, permission to read the file. ;;; For directories, permission to do `readdir` and access files ;;; within the directory. @@ -543,7 +543,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -584,7 +584,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -643,7 +643,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -653,7 +653,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -665,7 +665,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags (@witx bitflags u8) + (flags (@witx repr u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx index 803605fee..b8d77b504 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -14,15 +14,13 @@ (@interface func (export "get") (param $argv (@witx pointer (@witx pointer (@witx char8)))) (param $argv_buf (@witx pointer (@witx char8))) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return command-line argument data sizes. (@interface func (export "sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; Returns the number of arguments and the size of the argument string + ;;; data, or an error. + (result $error (expected (tuple $size $size) (error $errno))) ) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx index 3b00e0ac4..a980529f8 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx @@ -18,9 +18,8 @@ (@interface func (export "res_get") ;;; The clock for which to return the resolution. (param $id $clockid) - (result $error $errno) ;;; The resolution of the clock. - (result $resolution $timestamp) + (result $error (expected $timestamp (error $errno))) ) ;;; Return the time value of a clock. @@ -30,8 +29,7 @@ (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp) - (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp) + (result $error (expected $timestamp (error $errno))) ) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx index 6357fe602..0cad3c1cc 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -14,15 +14,13 @@ (@interface func (export "get") (param $environ (@witx pointer (@witx pointer (@witx char8)))) (param $environ_buf (@witx pointer (@witx char8))) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return environment variable data sizes. (@interface func (export "sizes_get") - (result $error $errno) - ;;; The number of environment variable arguments. - (result $environc $size) - ;;; The size of the environment variable data. - (result $environ_buf_size $size) + ;;; Returns the number of environment variable arguments and the size of the + ;;; environment variable data. + (result $error (expected (tuple $size $size) (error $errno))) ) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx index 8192c9b7f..979e9a333 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -21,7 +21,7 @@ (param $len $filesize) ;;; The advice. (param $advice $advice) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Force the allocation of space in a file. @@ -32,30 +32,29 @@ (param $offset $filesize) ;;; The length of the area that is allocated. (param $len $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "close") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "datasync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fdstat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat) + (result $error (expected $fdstat (error $errno))) ) ;;; Adjust the flags associated with a file descriptor. @@ -64,7 +63,7 @@ (param $fd $fd) ;;; The desired values of the file descriptor flags. (param $flags $fdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the rights associated with a file descriptor. @@ -74,15 +73,14 @@ ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of an open file. (@interface func (export "filestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. @@ -91,7 +89,7 @@ (param $fd $fd) ;;; The desired file size. (param $size $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the timestamps of an open file or directory. @@ -104,7 +102,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Set the permissions of a file or directory. @@ -123,7 +121,7 @@ (param $fd $fd) ;;; The permissions associated with the file. (param $permissions $permissions) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. @@ -134,17 +132,15 @@ (param $iovs $iovec_array) ;;; The offset within the file at which to read. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "prestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat) + (result $error (expected $prestat (error $errno))) ) ;;; Return a description of the given preopened file descriptor. @@ -153,7 +149,7 @@ ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer (@witx char8))) (param $path_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. @@ -168,9 +164,8 @@ (param $iovs $ciovec_array) ;;; The offset within the file at which to write. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Read from a file descriptor. @@ -179,9 +174,8 @@ (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_array) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Read directory entries from a directory. @@ -201,9 +195,8 @@ (param $buf_len $size) ;;; The location within the directory to start reading (param $cookie $dircookie) - (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -220,7 +213,7 @@ (param $fd $fd) ;;; The file descriptor to overwrite. (param $to $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Move the offset of a file descriptor. @@ -231,25 +224,23 @@ (param $offset $filedelta) ;;; The base from which the offset is relative. (param $whence $whence) - (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "sync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "tell") (param $fd $fd) - (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Write to a file descriptor. @@ -262,8 +253,7 @@ (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_array) - (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx index 5b3e17e88..2901decb7 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -17,7 +17,7 @@ (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of a file or directory. @@ -28,9 +28,8 @@ (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the timestamps of a file or directory. @@ -47,7 +46,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Set the permissions of a file or directory. @@ -70,7 +69,7 @@ (param $path string) ;;; The permissions to associate with the file. (param $permissions $permissions) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a hard link. @@ -85,7 +84,7 @@ (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Open a file or directory. @@ -119,9 +118,8 @@ (param $fdflags $fdflags) ;;; If a file is created, the filesystem permissions to associate with it. (param $permissions $permissions) - (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd) + (result $error (expected $fd (error $errno))) ) ;;; Read the contents of a symbolic link. @@ -133,9 +131,8 @@ ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer (@witx char8))) (param $buf_len $size) - (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Remove a directory. @@ -145,7 +142,7 @@ (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Rename a file or directory. @@ -158,7 +155,7 @@ (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a symbolic link. @@ -169,7 +166,7 @@ (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Unlink a file. @@ -179,6 +176,6 @@ (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx index a30b96afc..08da5f03a 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx @@ -21,8 +21,7 @@ (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. (param $nsubscriptions $size) - (result $error $errno) ;;; The number of events stored. - (result $nevents $size) + (result $error (expected $size (error $errno))) ) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx index 55c6df021..4dc8e1a47 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx @@ -21,6 +21,6 @@ ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sched.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sched.witx index 799a75fa9..3b70856dc 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sched.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sched.witx @@ -11,6 +11,6 @@ ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `yield` in POSIX. (@interface func (export "yield") - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sock.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sock.witx index becf80ffc..a05b02ea6 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sock.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sock.witx @@ -20,11 +20,8 @@ (param $ri_data $iovec_array) ;;; Message flags. (param $ri_flags $riflags) - (result $error $errno) - ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size) - ;;; Message flags. - (result $ro_flags $roflags) + ;;; Number of bytes stored in ri_data and message flags. + (result $error (expected (tuple $size $roflags) (error $errno))) ) ;;; Send a message on a socket. @@ -36,9 +33,8 @@ (param $si_data $ciovec_array) ;;; Message flags. (param $si_flags $siflags) - (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size) + (result $error (expected $size (error $errno))) ) ;;; Shut down socket send and receive channels. @@ -47,6 +43,6 @@ (param $fd $fd) ;;; Which channels on the socket to shut down. (param $how $sdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index e77002bc6..707c836b2 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -19,7 +19,7 @@ Size: 8 Alignment: 8 -## `clockid`: Variant +## `clockid`: `Variant` Identifiers for clocks. Size: 4 @@ -43,7 +43,7 @@ The CPU-time clock associated with the current process. - `thread_cputime_id` The CPU-time clock associated with the current thread. -## `errno`: Variant +## `errno`: `Variant` Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -285,114 +285,172 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: `u64` +## `rights`: `Record` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Constants -- `fd_datasync` +### Record members +- `fd_datasync`: `bool` The right to invoke [`fd_datasync`](#fd_datasync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). -- `fd_read` +Bit: 0 + +- `fd_read`: `bool` The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). -- `fd_seek` +Bit: 1 + +- `fd_seek`: `bool` The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). -- `fd_fdstat_set_flags` +Bit: 2 + +- `fd_fdstat_set_flags`: `bool` The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). -- `fd_sync` +Bit: 3 + +- `fd_sync`: `bool` The right to invoke [`fd_sync`](#fd_sync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). -- `fd_tell` +Bit: 4 + +- `fd_tell`: `bool` The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke [`fd_tell`](#fd_tell). -- `fd_write` +Bit: 5 + +- `fd_write`: `bool` The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). -- `fd_advise` +Bit: 6 + +- `fd_advise`: `bool` The right to invoke [`fd_advise`](#fd_advise). -- `fd_allocate` +Bit: 7 + +- `fd_allocate`: `bool` The right to invoke [`fd_allocate`](#fd_allocate). -- `path_create_directory` +Bit: 8 + +- `path_create_directory`: `bool` The right to invoke [`path_create_directory`](#path_create_directory). -- `path_create_file` +Bit: 9 + +- `path_create_file`: `bool` If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). -- `path_link_source` +Bit: 10 + +- `path_link_source`: `bool` The right to invoke [`path_link`](#path_link) with the file descriptor as the source directory. -- `path_link_target` +Bit: 11 + +- `path_link_target`: `bool` The right to invoke [`path_link`](#path_link) with the file descriptor as the target directory. -- `path_open` +Bit: 12 + +- `path_open`: `bool` The right to invoke [`path_open`](#path_open). -- `fd_readdir` +Bit: 13 + +- `fd_readdir`: `bool` The right to invoke [`fd_readdir`](#fd_readdir). -- `path_readlink` +Bit: 14 + +- `path_readlink`: `bool` The right to invoke [`path_readlink`](#path_readlink). -- `path_rename_source` +Bit: 15 + +- `path_rename_source`: `bool` The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. -- `path_rename_target` +Bit: 16 + +- `path_rename_target`: `bool` The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. -- `path_filestat_get` +Bit: 17 + +- `path_filestat_get`: `bool` The right to invoke [`path_filestat_get`](#path_filestat_get). -- `path_filestat_set_size` +Bit: 18 + +- `path_filestat_set_size`: `bool` The right to change a file's size (there is no `path_filestat_set_size`). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). -- `path_filestat_set_times` +Bit: 19 + +- `path_filestat_set_times`: `bool` The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). -- `fd_filestat_get` +Bit: 20 + +- `fd_filestat_get`: `bool` The right to invoke [`fd_filestat_get`](#fd_filestat_get). -- `fd_filestat_set_size` +Bit: 21 + +- `fd_filestat_set_size`: `bool` The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). -- `fd_filestat_set_times` +Bit: 22 + +- `fd_filestat_set_times`: `bool` The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). -- `path_symlink` +Bit: 23 + +- `path_symlink`: `bool` The right to invoke [`path_symlink`](#path_symlink). -- `path_remove_directory` +Bit: 24 + +- `path_remove_directory`: `bool` The right to invoke [`path_remove_directory`](#path_remove_directory). -- `path_unlink_file` +Bit: 25 + +- `path_unlink_file`: `bool` The right to invoke [`path_unlink_file`](#path_unlink_file). -- `poll_fd_readwrite` +Bit: 26 + +- `poll_fd_readwrite`: `bool` If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). -- `sock_shutdown` +Bit: 27 + +- `sock_shutdown`: `bool` The right to invoke [`sock_shutdown`](#sock_shutdown). -## `fd` +Bit: 28 + +## `fd`: `Handle` A file descriptor handle. Size: 4 @@ -400,7 +458,7 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Record +## `iovec`: `Record` A region of memory for scatter/gather reads. Size: 8 @@ -418,7 +476,7 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Record +## `ciovec`: `Record` A region of memory for scatter/gather writes. Size: 8 @@ -455,7 +513,7 @@ Size: 8 Alignment: 8 -## `whence`: Variant +## `whence`: `Variant` The position relative to which to set the offset of the file descriptor. Size: 1 @@ -493,7 +551,7 @@ Size: 8 Alignment: 8 -## `filetype`: Variant +## `filetype`: `Variant` The type of a file descriptor or file. Size: 1 @@ -525,7 +583,7 @@ The file descriptor or file refers to a byte-stream socket. - `symbolic_link` The file refers to a symbolic link inode. -## `dirent`: Record +## `dirent`: `Record` A directory entry. Size: 24 @@ -553,7 +611,7 @@ The type of the file referred to by this directory entry. Offset: 20 -## `advice`: Variant +## `advice`: `Variant` File or memory access pattern advisory information. Size: 1 @@ -579,32 +637,42 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: `u16` +## `fdflags`: `Record` File descriptor flags. Size: 2 Alignment: 2 -### Constants -- `append` +### Record members +- `append`: `bool` Append mode: Data written to the file is always appended to the file's end. -- `dsync` +Bit: 0 + +- `dsync`: `bool` Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. -- `nonblock` +Bit: 1 + +- `nonblock`: `bool` Non-blocking mode. -- `rsync` +Bit: 2 + +- `rsync`: `bool` Synchronized read I/O operations. -- `sync` +Bit: 3 + +- `sync`: `bool` Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Record +Bit: 4 + +## `fdstat`: `Record` File descriptor attributes. Size: 24 @@ -641,57 +709,75 @@ Size: 8 Alignment: 8 -## `fstflags`: `u16` +## `fstflags`: `Record` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Constants -- `atim` +### Record members +- `atim`: `bool` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). -- `atim_now` +Bit: 0 + +- `atim_now`: `bool` Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -- `mtim` +Bit: 1 + +- `mtim`: `bool` Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). -- `mtim_now` +Bit: 2 + +- `mtim_now`: `bool` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: `u32` +Bit: 3 + +## `lookupflags`: `Record` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Constants -- `symlink_follow` +### Record members +- `symlink_follow`: `bool` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: `u16` +Bit: 0 + +## `oflags`: `Record` Open flags used by [`path_open`](#path_open). Size: 2 Alignment: 2 -### Constants -- `creat` +### Record members +- `creat`: `bool` Create file if it does not exist. -- `directory` +Bit: 0 + +- `directory`: `bool` Fail if not a directory. -- `excl` +Bit: 1 + +- `excl`: `bool` Fail if file already exists. -- `trunc` +Bit: 2 + +- `trunc`: `bool` Truncate file to size 0. +Bit: 3 + ## `linkcount`: `u32` Number of hard links to an inode. @@ -699,7 +785,7 @@ Size: 4 Alignment: 4 -## `filestat`: Record +## `filestat`: `Record` File attributes. Size: 56 @@ -755,7 +841,7 @@ Size: 8 Alignment: 8 -## `eventtype`: Variant +## `eventtype`: `Variant` Type of a subscription to an event or its occurrence. Size: 1 @@ -775,7 +861,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: `u16` +## `eventrwflags`: `Record` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -783,11 +869,13 @@ Size: 2 Alignment: 2 -### Constants -- `fd_readwrite_hangup` +### Record members +- `fd_readwrite_hangup`: `bool` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Record +Bit: 0 + +## `event_fd_readwrite`: `Record` The contents of an [`event`](#event) for the [`eventtype::fd_read`](#eventtype.fd_read) and [`eventtype::fd_write`](#eventtype.fd_write) variants @@ -806,7 +894,7 @@ The state of the file descriptor. Offset: 8 -## `event`: Record +## `event`: `Record` An event that occurred. Size: 32 @@ -835,7 +923,7 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read Offset: 16 -## `subclockflags`: `u16` +## `subclockflags`: `Record` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -843,15 +931,17 @@ Size: 2 Alignment: 2 -### Constants -- `subscription_clock_abstime` +### Record members +- `subscription_clock_abstime`: `bool` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock [`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Record +Bit: 0 + +## `subscription_clock`: `Record` The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 40 @@ -885,7 +975,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 32 -## `subscription_fd_readwrite`: Record +## `subscription_fd_readwrite`: `Record` The contents of a [`subscription`](#subscription) when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -899,7 +989,7 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Variant +## `subscription_u`: `Variant` The contents of a [`subscription`](#subscription). Size: 48 @@ -917,7 +1007,7 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Record +## `subscription`: `Record` Subscription to an event. Size: 56 @@ -943,7 +1033,7 @@ Size: 4 Alignment: 4 -## `signal`: Variant +## `signal`: `Variant` Signal condition. Size: 1 @@ -1075,31 +1165,37 @@ Action: Terminates the process. Bad system call. Action: Terminates the process. -## `riflags`: `u16` +## `riflags`: `Record` Flags provided to [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Constants -- `recv_peek` +### Record members +- `recv_peek`: `bool` Returns the message without removing it from the socket's receive queue. -- `recv_waitall` +Bit: 0 + +- `recv_waitall`: `bool` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: `u16` +Bit: 1 + +## `roflags`: `Record` Flags returned by [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Constants -- `recv_data_truncated` +### Record members +- `recv_data_truncated`: `bool` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. +Bit: 0 + ## `siflags`: `u16` Flags provided to [`sock_send`](#sock_send). As there are currently no flags defined, it must be set to zero. @@ -1108,21 +1204,25 @@ Size: 2 Alignment: 2 -## `sdflags`: `u8` +## `sdflags`: `Record` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Constants -- `rd` +### Record members +- `rd`: `bool` Disables further receive operations. -- `wr` +Bit: 0 + +- `wr`: `bool` Disables further send operations. -## `preopentype`: Variant +Bit: 1 + +## `preopentype`: `Variant` Identifiers for preopened capabilities. Size: 1 @@ -1133,7 +1233,7 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Record +## `prestat_dir`: `Record` The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). Size: 4 @@ -1146,7 +1246,7 @@ The length of the directory name for use with [`fd_prestat_dir_name`](#fd_presta Offset: 0 -## `prestat`: Variant +## `prestat`: `Variant` Information about a pre-opened capability. Size: 8 @@ -1168,7 +1268,7 @@ Alignment: 4 --- -#### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` +#### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) @@ -1178,28 +1278,51 @@ The size of the array should match that returned by [`args_sizes_get`](#args_siz - `argv_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `args_sizes_get() -> (errno, size, size)` +#### `args_sizes_get() -> Result<(size, size), errno>` Return command-line argument data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of arguments and the size of the argument string +data, or an error. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) -- `argc`: [`size`](#size) -The number of arguments. +Offset: 0 + +- `1`: [`size`](#size) + +Offset: 4 -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `err`: [`errno`](#errno) --- -#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` +#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). @@ -1209,28 +1332,51 @@ The sizes of the buffers should match that returned by [`environ_sizes_get`](#en - `environ_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `environ_sizes_get() -> (errno, size, size)` +#### `environ_sizes_get() -> Result<(size, size), errno>` Return environment variable data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of environment variable arguments and the size of the +environment variable data. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`size`](#size) -- `environc`: [`size`](#size) -The number of environment variable arguments. +Offset: 4 -- `environ_buf_size`: [`size`](#size) -The size of the environment variable data. +- `err`: [`errno`](#errno) --- -#### `clock_res_get(id: clockid) -> (errno, timestamp)` +#### `clock_res_get(id: clockid) -> Result` Return the resolution of a clock. Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return [`errno::inval`](#errno.inval). @@ -1241,15 +1387,22 @@ Note: This is similar to `clock_getres` in POSIX. The clock for which to return the resolution. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result` +The resolution of the clock, or an error if one happened. + +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) -- `resolution`: [`timestamp`](#timestamp) -The resolution of the clock. +- `err`: [`errno`](#errno) --- -#### `clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +#### `clock_time_get(id: clockid, precision: timestamp) -> Result` Return the time value of a clock. Note: This is similar to `clock_gettime` in POSIX. @@ -1261,15 +1414,22 @@ The clock for which to return the time. The maximum lag (exclusive) that the returned time value may have, compared to its actual value. ##### Results -- `error`: [`errno`](#errno) - -- `time`: [`timestamp`](#timestamp) +- `error`: `Result` The time value of the clock. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) + +- `err`: [`errno`](#errno) + --- -#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` Provide file advisory information on a file descriptor. Note: This is similar to `posix_fadvise` in POSIX. @@ -1286,12 +1446,21 @@ The length of the region to which the advisory applies. The advice. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno` +#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` Force the allocation of space in a file. Note: This is similar to `posix_fallocate` in POSIX. @@ -1305,12 +1474,21 @@ The offset at which to start the allocation. The length of the area that is allocated. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_close(fd: fd) -> errno` +#### `fd_close(fd: fd) -> Result<(), errno>` Close a file descriptor. Note: This is similar to `close` in POSIX. @@ -1318,12 +1496,21 @@ Note: This is similar to `close` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_datasync(fd: fd) -> errno` +#### `fd_datasync(fd: fd) -> Result<(), errno>` Synchronize the data of a file to disk. Note: This is similar to `fdatasync` in POSIX. @@ -1331,12 +1518,21 @@ Note: This is similar to `fdatasync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_fdstat_get(fd: fd) -> (errno, fdstat)` +#### `fd_fdstat_get(fd: fd) -> Result` Get the attributes of a file descriptor. Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. @@ -1344,15 +1540,22 @@ Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as ad - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `stat`: [`fdstat`](#fdstat) +- `error`: `Result` The buffer where the file descriptor's attributes are stored. +###### Variant Layout +- size: 32 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`fdstat`](#fdstat) + +- `err`: [`errno`](#errno) + --- -#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` Adjust the flags associated with a file descriptor. Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. @@ -1363,12 +1566,21 @@ Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. The desired values of the file descriptor flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` Adjust the rights associated with a file descriptor. This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights @@ -1381,27 +1593,43 @@ The desired rights of the file descriptor. - `fs_rights_inheriting`: [`rights`](#rights) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_filestat_get(fd: fd) -> (errno, filestat)` +#### `fd_filestat_get(fd: fd) -> Result` Return the attributes of an open file. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 64 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `fd_filestat_set_size(fd: fd, size: filesize) -> errno` +#### `fd_filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. Note: This is similar to `ftruncate` in POSIX. @@ -1412,12 +1640,21 @@ Note: This is similar to `ftruncate` in POSIX. The desired file size. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of an open file or directory. Note: This is similar to `futimens` in POSIX. @@ -1434,12 +1671,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` Read from a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `preadv` in POSIX. @@ -1453,30 +1699,44 @@ List of scatter/gather vectors in which to store data. The offset within the file at which to read. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_prestat_get(fd: fd) -> (errno, prestat)` +#### `fd_prestat_get(fd: fd) -> Result` Return a description of the given preopened file descriptor. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`prestat`](#prestat) +- `error`: `Result` The buffer where the description is stored. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`prestat`](#prestat) + +- `err`: [`errno`](#errno) + --- -#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` Return a description of the given preopened file descriptor. ##### Params @@ -1488,12 +1748,21 @@ A buffer into which to write the preopened directory name. - `path_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` Write to a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `pwritev` in POSIX. @@ -1507,15 +1776,22 @@ List of scatter/gather vectors from which to retrieve data. The offset within the file at which to write. ##### Results -- `error`: [`errno`](#errno) - -- `nwritten`: [`size`](#size) +- `error`: `Result` The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_read(fd: fd, iovs: iovec_array) -> (errno, size)` +#### `fd_read(fd: fd, iovs: iovec_array) -> Result` Read from a file descriptor. Note: This is similar to `readv` in POSIX. @@ -1526,15 +1802,22 @@ Note: This is similar to `readv` in POSIX. List of scatter/gather vectors to which to store data. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of directory entries. Each directory entry consists of a [`dirent`](#dirent) object, @@ -1557,15 +1840,22 @@ The buffer where directory entries are stored The location within the directory to start reading ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_renumber(fd: fd, to: fd) -> errno` +#### `fd_renumber(fd: fd, to: fd) -> Result<(), errno>` Atomically replace a file descriptor by renumbering another file descriptor. Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary @@ -1582,12 +1872,21 @@ would disappear if `dup2()` were to be removed entirely. The file descriptor to overwrite. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> Result` Move the offset of a file descriptor. Note: This is similar to `lseek` in POSIX. @@ -1601,15 +1900,22 @@ The number of bytes to move. The base from which the offset is relative. ##### Results -- `error`: [`errno`](#errno) - -- `newoffset`: [`filesize`](#filesize) +- `error`: `Result` The new offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `fd_sync(fd: fd) -> errno` +#### `fd_sync(fd: fd) -> Result<(), errno>` Synchronize the data and metadata of a file to disk. Note: This is similar to `fsync` in POSIX. @@ -1617,12 +1923,21 @@ Note: This is similar to `fsync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_tell(fd: fd) -> (errno, filesize)` +#### `fd_tell(fd: fd) -> Result` Return the current offset of a file descriptor. Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. @@ -1630,15 +1945,22 @@ Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `offset`: [`filesize`](#filesize) +- `error`: `Result` The current offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)` +#### `fd_write(fd: fd, iovs: ciovec_array) -> Result` Write to a file descriptor. Note: This is similar to `writev` in POSIX. @@ -1649,15 +1971,21 @@ Note: This is similar to `writev` in POSIX. List of scatter/gather vectors from which to retrieve data. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result` -- `nwritten`: [`size`](#size) -The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) --- -#### `path_create_directory(fd: fd, path: string) -> errno` +#### `path_create_directory(fd: fd, path: string) -> Result<(), errno>` Create a directory. Note: This is similar to `mkdirat` in POSIX. @@ -1668,12 +1996,21 @@ Note: This is similar to `mkdirat` in POSIX. The path at which to create the directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` Return the attributes of a file or directory. Note: This is similar to `stat` in POSIX. @@ -1687,15 +2024,22 @@ Flags determining the method of how the path is resolved. The path of the file or directory to inspect. ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 64 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of a file or directory. Note: This is similar to `utimensat` in POSIX. @@ -1718,12 +2062,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Create a hard link. Note: This is similar to `linkat` in POSIX. @@ -1743,12 +2096,21 @@ The working directory at which the resolution of the new path starts. The destination path at which to create the hard link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> (errno, fd)` +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> Result` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1765,7 +2127,7 @@ Flags determining the method of how the path is resolved. - `path`: `string` The relative path of the file or directory to open, relative to the -[`fd`](#fd) directory. +[`path_open::fd`](#path_open.fd) directory. - `oflags`: [`oflags`](#oflags) The method by which to open the file. @@ -1784,15 +2146,22 @@ file descriptors derived from it. - `fdflags`: [`fdflags`](#fdflags) ##### Results -- `error`: [`errno`](#errno) - -- `opened_fd`: [`fd`](#fd) +- `error`: `Result` The file descriptor of the file that has been opened. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`fd`](#fd) + +- `err`: [`errno`](#errno) + --- -#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` Read the contents of a symbolic link. Note: This is similar to `readlinkat` in POSIX. @@ -1808,15 +2177,22 @@ The buffer to which to write the contents of the symbolic link. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes placed in the buffer. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `path_remove_directory(fd: fd, path: string) -> errno` +#### `path_remove_directory(fd: fd, path: string) -> Result<(), errno>` Remove a directory. Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. @@ -1828,12 +2204,21 @@ Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. The path to a directory to remove. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Rename a file or directory. Note: This is similar to `renameat` in POSIX. @@ -1850,12 +2235,21 @@ The working directory at which the resolution of the new path starts. The destination path to which to rename the file or directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_symlink(old_path: string, fd: fd, new_path: string) -> errno` +#### `path_symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` Create a symbolic link. Note: This is similar to `symlinkat` in POSIX. @@ -1869,12 +2263,21 @@ The contents of the symbolic link. The destination path at which to create the symbolic link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_unlink_file(fd: fd, path: string) -> errno` +#### `path_unlink_file(fd: fd, path: string) -> Result<(), errno>` Unlink a file. Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. @@ -1886,12 +2289,21 @@ Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. The path to a file to unlink. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` Concurrently poll for the occurrence of a set of events. ##### Params @@ -1905,11 +2317,18 @@ The events that have occurred. Both the number of subscriptions and events. ##### Results -- `error`: [`errno`](#errno) - -- `nevents`: [`size`](#size) +- `error`: `Result` The number of events stored. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- @@ -1926,7 +2345,7 @@ The exit code returned by the process. --- -#### `proc_raise(sig: signal) -> errno` +#### `proc_raise(sig: signal) -> Result<(), errno>` Send a signal to the process of the calling thread. Note: This is similar to `raise` in POSIX. @@ -1935,23 +2354,41 @@ Note: This is similar to `raise` in POSIX. The signal condition to trigger. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sched_yield() -> errno` +#### `sched_yield() -> Result<(), errno>` Temporarily yield execution of the calling thread. Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `random_get(buf: Pointer, buf_len: size) -> errno` +#### `random_get(buf: Pointer, buf_len: size) -> Result<(), errno>` Write high-quality random data into a buffer. This function blocks when the implementation is unable to immediately provide sufficient high-quality random data. @@ -1966,12 +2403,21 @@ The buffer to fill with random data. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` Receive a message from a socket. Note: This is similar to `recv` in POSIX, though it also supports reading the data into multiple buffers in the manner of `readv`. @@ -1986,18 +2432,31 @@ List of scatter/gather vectors to which to store data. Message flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, roflags), errno>` +Number of bytes stored in ri_data and message flags. -- `ro_datalen`: [`size`](#size) -Number of bytes stored in ri_data. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, roflags)` -- `ro_flags`: [`roflags`](#roflags) -Message flags. +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`roflags`](#roflags) + +Offset: 4 + +- `err`: [`errno`](#errno) --- -#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` Send a message on a socket. Note: This is similar to `send` in POSIX, though it also supports writing the data from multiple buffers in the manner of `writev`. @@ -2012,15 +2471,22 @@ List of scatter/gather vectors to which to retrieve data Message flags. ##### Results -- `error`: [`errno`](#errno) - -- `so_datalen`: [`size`](#size) +- `error`: `Result` Number of bytes transmitted. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `sock_shutdown(fd: fd, how: sdflags) -> errno` +#### `sock_shutdown(fd: fd, how: sdflags) -> Result<(), errno>` Shut down socket send and receive channels. Note: This is similar to `shutdown` in POSIX. @@ -2031,5 +2497,14 @@ Note: This is similar to `shutdown` in POSIX. Which channels on the socket to shut down. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx index eb6f70020..f4ba78802 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags (@witx bitflags u64) + (flags (@witx repr u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `rights::path_open` is set, includes the right to invoke @@ -379,7 +379,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -416,7 +416,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -430,7 +430,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags (@witx bitflags u32) + (flags (@witx repr u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -438,7 +438,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Create file if it does not exist. $creat ;;; Fail if not a directory. @@ -497,7 +497,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -532,7 +532,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -692,7 +692,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -702,7 +702,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -714,7 +714,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags (@witx bitflags u8) + (flags (@witx repr u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx index 0d16f1b18..5481882ae 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -20,15 +20,13 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; Returns the number of arguments and the size of the argument string + ;;; data, or an error. + (result $error (expected (tuple $size $size) (error $errno))) ) ;;; Read environment variable data. @@ -36,15 +34,13 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return environment variable data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno) - ;;; The number of environment variable arguments. - (result $environc $size) - ;;; The size of the environment variable data. - (result $environ_buf_size $size) + ;;; Returns the number of environment variable arguments and the size of the + ;;; environment variable data. + (result $error (expected (tuple $size $size) (error $errno))) ) ;;; Return the resolution of a clock. @@ -54,9 +50,8 @@ (@interface func (export "clock_res_get") ;;; The clock for which to return the resolution. (param $id $clockid) - (result $error $errno) - ;;; The resolution of the clock. - (result $resolution $timestamp) + ;;; The resolution of the clock, or an error if one happened. + (result $error (expected $timestamp (error $errno))) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. @@ -65,9 +60,8 @@ (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp) - (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp) + (result $error (expected $timestamp (error $errno))) ) ;;; Provide file advisory information on a file descriptor. @@ -80,7 +74,7 @@ (param $len $filesize) ;;; The advice. (param $advice $advice) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Force the allocation of space in a file. @@ -91,30 +85,29 @@ (param $offset $filesize) ;;; The length of the area that is allocated. (param $len $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat) + (result $error (expected $fdstat (error $errno))) ) ;;; Adjust the flags associated with a file descriptor. @@ -123,7 +116,7 @@ (param $fd $fd) ;;; The desired values of the file descriptor flags. (param $flags $fdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the rights associated with a file descriptor. @@ -133,15 +126,14 @@ ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. @@ -150,7 +142,7 @@ (param $fd $fd) ;;; The desired file size. (param $size $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the timestamps of an open file or directory. @@ -163,7 +155,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. @@ -174,17 +166,15 @@ (param $iovs $iovec_array) ;;; The offset within the file at which to read. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat) + (result $error (expected $prestat (error $errno))) ) ;;; Return a description of the given preopened file descriptor. @@ -193,7 +183,7 @@ ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. @@ -204,9 +194,8 @@ (param $iovs $ciovec_array) ;;; The offset within the file at which to write. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Read from a file descriptor. @@ -215,9 +204,8 @@ (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_array) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Read directory entries from a directory. @@ -237,9 +225,8 @@ (param $buf_len $size) ;;; The location within the directory to start reading (param $cookie $dircookie) - (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -256,7 +243,7 @@ (param $fd $fd) ;;; The file descriptor to overwrite. (param $to $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Move the offset of a file descriptor. @@ -267,25 +254,23 @@ (param $offset $filedelta) ;;; The base from which the offset is relative. (param $whence $whence) - (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd) - (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Write to a file descriptor. @@ -294,9 +279,7 @@ (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_array) - (result $error $errno) - ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Create a directory. @@ -305,7 +288,7 @@ (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of a file or directory. @@ -316,9 +299,8 @@ (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the timestamps of a file or directory. @@ -335,7 +317,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a hard link. @@ -350,7 +332,7 @@ (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Open a file or directory. @@ -367,7 +349,7 @@ ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the - ;;; `fd` directory. + ;;; `path_open::fd` directory. (param $path string) ;;; The method by which to open the file. (param $oflags $oflags) @@ -382,9 +364,8 @@ (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) - (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd) + (result $error (expected $fd (error $errno))) ) ;;; Read the contents of a symbolic link. @@ -396,9 +377,8 @@ ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Remove a directory. @@ -408,7 +388,7 @@ (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Rename a file or directory. @@ -421,7 +401,7 @@ (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a symbolic link. @@ -432,7 +412,7 @@ (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) @@ -443,7 +423,7 @@ (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Concurrently poll for the occurrence of a set of events. @@ -454,9 +434,8 @@ (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. (param $nsubscriptions $size) - (result $error $errno) ;;; The number of events stored. - (result $nevents $size) + (result $error (expected $size (error $errno))) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -473,13 +452,13 @@ (@interface func (export "proc_raise") ;;; The signal condition to trigger. (param $sig $signal) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write high-quality random data into a buffer. @@ -492,7 +471,7 @@ ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Receive a message from a socket. @@ -504,11 +483,8 @@ (param $ri_data $iovec_array) ;;; Message flags. (param $ri_flags $riflags) - (result $error $errno) - ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size) - ;;; Message flags. - (result $ro_flags $roflags) + ;;; Number of bytes stored in ri_data and message flags. + (result $error (expected (tuple $size $roflags) (error $errno))) ) ;;; Send a message on a socket. @@ -520,9 +496,8 @@ (param $si_data $ciovec_array) ;;; Message flags. (param $si_flags $siflags) - (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size) + (result $error (expected $size (error $errno))) ) ;;; Shut down socket send and receive channels. @@ -531,6 +506,6 @@ (param $fd $fd) ;;; Which channels on the socket to shut down. (param $how $sdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index 1bbbe59f2..c55a661b1 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -19,7 +19,7 @@ Size: 8 Alignment: 8 -## `clockid`: Variant +## `clockid`: `Variant` Identifiers for clocks. Size: 4 @@ -43,7 +43,7 @@ The CPU-time clock associated with the current process. - `thread_cputime_id` The CPU-time clock associated with the current thread. -## `errno`: Variant +## `errno`: `Variant` Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -285,114 +285,172 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: `u64` +## `rights`: `Record` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Constants -- `fd_datasync` +### Record members +- `fd_datasync`: `bool` The right to invoke [`fd_datasync`](#fd_datasync). If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). -- `fd_read` +Bit: 0 + +- `fd_read`: `bool` The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). -- `fd_seek` +Bit: 1 + +- `fd_seek`: `bool` The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). -- `fd_fdstat_set_flags` +Bit: 2 + +- `fd_fdstat_set_flags`: `bool` The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). -- `fd_sync` +Bit: 3 + +- `fd_sync`: `bool` The right to invoke [`fd_sync`](#fd_sync). If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). -- `fd_tell` +Bit: 4 + +- `fd_tell`: `bool` The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke [`fd_tell`](#fd_tell). -- `fd_write` +Bit: 5 + +- `fd_write`: `bool` The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). -- `fd_advise` +Bit: 6 + +- `fd_advise`: `bool` The right to invoke [`fd_advise`](#fd_advise). -- `fd_allocate` +Bit: 7 + +- `fd_allocate`: `bool` The right to invoke [`fd_allocate`](#fd_allocate). -- `path_create_directory` +Bit: 8 + +- `path_create_directory`: `bool` The right to invoke [`path_create_directory`](#path_create_directory). -- `path_create_file` +Bit: 9 + +- `path_create_file`: `bool` If [`path_open`](#path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). -- `path_link_source` +Bit: 10 + +- `path_link_source`: `bool` The right to invoke [`path_link`](#path_link) with the file descriptor as the source directory. -- `path_link_target` +Bit: 11 + +- `path_link_target`: `bool` The right to invoke [`path_link`](#path_link) with the file descriptor as the target directory. -- `path_open` +Bit: 12 + +- `path_open`: `bool` The right to invoke [`path_open`](#path_open). -- `fd_readdir` +Bit: 13 + +- `fd_readdir`: `bool` The right to invoke [`fd_readdir`](#fd_readdir). -- `path_readlink` +Bit: 14 + +- `path_readlink`: `bool` The right to invoke [`path_readlink`](#path_readlink). -- `path_rename_source` +Bit: 15 + +- `path_rename_source`: `bool` The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. -- `path_rename_target` +Bit: 16 + +- `path_rename_target`: `bool` The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. -- `path_filestat_get` +Bit: 17 + +- `path_filestat_get`: `bool` The right to invoke [`path_filestat_get`](#path_filestat_get). -- `path_filestat_set_size` +Bit: 18 + +- `path_filestat_set_size`: `bool` The right to change a file's size (there is no `path_filestat_set_size`). If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). -- `path_filestat_set_times` +Bit: 19 + +- `path_filestat_set_times`: `bool` The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). -- `fd_filestat_get` +Bit: 20 + +- `fd_filestat_get`: `bool` The right to invoke [`fd_filestat_get`](#fd_filestat_get). -- `fd_filestat_set_size` +Bit: 21 + +- `fd_filestat_set_size`: `bool` The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). -- `fd_filestat_set_times` +Bit: 22 + +- `fd_filestat_set_times`: `bool` The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). -- `path_symlink` +Bit: 23 + +- `path_symlink`: `bool` The right to invoke [`path_symlink`](#path_symlink). -- `path_remove_directory` +Bit: 24 + +- `path_remove_directory`: `bool` The right to invoke [`path_remove_directory`](#path_remove_directory). -- `path_unlink_file` +Bit: 25 + +- `path_unlink_file`: `bool` The right to invoke [`path_unlink_file`](#path_unlink_file). -- `poll_fd_readwrite` +Bit: 26 + +- `poll_fd_readwrite`: `bool` If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). -- `sock_shutdown` +Bit: 27 + +- `sock_shutdown`: `bool` The right to invoke [`sock_shutdown`](#sock_shutdown). -## `fd` +Bit: 28 + +## `fd`: `Handle` A file descriptor handle. Size: 4 @@ -400,7 +458,7 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Record +## `iovec`: `Record` A region of memory for scatter/gather reads. Size: 8 @@ -418,7 +476,7 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Record +## `ciovec`: `Record` A region of memory for scatter/gather writes. Size: 8 @@ -455,7 +513,7 @@ Size: 8 Alignment: 8 -## `whence`: Variant +## `whence`: `Variant` The position relative to which to set the offset of the file descriptor. Size: 1 @@ -495,7 +553,7 @@ Size: 8 Alignment: 8 -## `filetype`: Variant +## `filetype`: `Variant` The type of a file descriptor or file. Size: 1 @@ -527,7 +585,7 @@ The file descriptor or file refers to a byte-stream socket. - `symbolic_link` The file refers to a symbolic link inode. -## `dirent`: Record +## `dirent`: `Record` A directory entry. Size: 24 @@ -555,7 +613,7 @@ The type of the file referred to by this directory entry. Offset: 20 -## `advice`: Variant +## `advice`: `Variant` File or memory access pattern advisory information. Size: 1 @@ -581,32 +639,42 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: `u16` +## `fdflags`: `Record` File descriptor flags. Size: 2 Alignment: 2 -### Constants -- `append` +### Record members +- `append`: `bool` Append mode: Data written to the file is always appended to the file's end. -- `dsync` +Bit: 0 + +- `dsync`: `bool` Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. -- `nonblock` +Bit: 1 + +- `nonblock`: `bool` Non-blocking mode. -- `rsync` +Bit: 2 + +- `rsync`: `bool` Synchronized read I/O operations. -- `sync` +Bit: 3 + +- `sync`: `bool` Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Record +Bit: 4 + +## `fdstat`: `Record` File descriptor attributes. Size: 24 @@ -643,57 +711,75 @@ Size: 8 Alignment: 8 -## `fstflags`: `u16` +## `fstflags`: `Record` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Constants -- `atim` +### Record members +- `atim`: `bool` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). -- `atim_now` +Bit: 0 + +- `atim_now`: `bool` Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -- `mtim` +Bit: 1 + +- `mtim`: `bool` Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). -- `mtim_now` +Bit: 2 + +- `mtim_now`: `bool` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: `u32` +Bit: 3 + +## `lookupflags`: `Record` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Constants -- `symlink_follow` +### Record members +- `symlink_follow`: `bool` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: `u16` +Bit: 0 + +## `oflags`: `Record` Open flags used by [`path_open`](#path_open). Size: 2 Alignment: 2 -### Constants -- `creat` +### Record members +- `creat`: `bool` Create file if it does not exist. -- `directory` +Bit: 0 + +- `directory`: `bool` Fail if not a directory. -- `excl` +Bit: 1 + +- `excl`: `bool` Fail if file already exists. -- `trunc` +Bit: 2 + +- `trunc`: `bool` Truncate file to size 0. +Bit: 3 + ## `linkcount`: `u64` Number of hard links to an inode. @@ -701,7 +787,7 @@ Size: 8 Alignment: 8 -## `filestat`: Record +## `filestat`: `Record` File attributes. Size: 64 @@ -757,7 +843,7 @@ Size: 8 Alignment: 8 -## `eventtype`: Variant +## `eventtype`: `Variant` Type of a subscription to an event or its occurrence. Size: 1 @@ -777,7 +863,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: `u16` +## `eventrwflags`: `Record` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -785,11 +871,13 @@ Size: 2 Alignment: 2 -### Constants -- `fd_readwrite_hangup` +### Record members +- `fd_readwrite_hangup`: `bool` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Record +Bit: 0 + +## `event_fd_readwrite`: `Record` The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -808,7 +896,7 @@ The state of the file descriptor. Offset: 8 -## `event`: Record +## `event`: `Record` An event that occurred. Size: 32 @@ -837,7 +925,7 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read Offset: 16 -## `subclockflags`: `u16` +## `subclockflags`: `Record` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -845,15 +933,17 @@ Size: 2 Alignment: 2 -### Constants -- `subscription_clock_abstime` +### Record members +- `subscription_clock_abstime`: `bool` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock [`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Record +Bit: 0 + +## `subscription_clock`: `Record` The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 32 @@ -882,7 +972,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 24 -## `subscription_fd_readwrite`: Record +## `subscription_fd_readwrite`: `Record` The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -896,7 +986,7 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Variant +## `subscription_u`: `Variant` The contents of a [`subscription`](#subscription). Size: 40 @@ -914,7 +1004,7 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Record +## `subscription`: `Record` Subscription to an event. Size: 48 @@ -940,7 +1030,7 @@ Size: 4 Alignment: 4 -## `signal`: Variant +## `signal`: `Variant` Signal condition. Size: 1 @@ -1072,31 +1162,37 @@ Action: Terminates the process. Bad system call. Action: Terminates the process. -## `riflags`: `u16` +## `riflags`: `Record` Flags provided to [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Constants -- `recv_peek` +### Record members +- `recv_peek`: `bool` Returns the message without removing it from the socket's receive queue. -- `recv_waitall` +Bit: 0 + +- `recv_waitall`: `bool` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: `u16` +Bit: 1 + +## `roflags`: `Record` Flags returned by [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Constants -- `recv_data_truncated` +### Record members +- `recv_data_truncated`: `bool` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. +Bit: 0 + ## `siflags`: `u16` Flags provided to [`sock_send`](#sock_send). As there are currently no flags defined, it must be set to zero. @@ -1105,21 +1201,25 @@ Size: 2 Alignment: 2 -## `sdflags`: `u8` +## `sdflags`: `Record` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Constants -- `rd` +### Record members +- `rd`: `bool` Disables further receive operations. -- `wr` +Bit: 0 + +- `wr`: `bool` Disables further send operations. -## `preopentype`: Variant +Bit: 1 + +## `preopentype`: `Variant` Identifiers for preopened capabilities. Size: 1 @@ -1130,7 +1230,7 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Record +## `prestat_dir`: `Record` The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). Size: 4 @@ -1143,7 +1243,7 @@ The length of the directory name for use with [`fd_prestat_dir_name`](#fd_presta Offset: 0 -## `prestat`: Variant +## `prestat`: `Variant` Information about a pre-opened capability. Size: 8 @@ -1165,7 +1265,7 @@ Alignment: 4 --- -#### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` +#### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) @@ -1175,28 +1275,51 @@ The size of the array should match that returned by [`args_sizes_get`](#args_siz - `argv_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `args_sizes_get() -> (errno, size, size)` +#### `args_sizes_get() -> Result<(size, size), errno>` Return command-line argument data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of arguments and the size of the argument string +data, or an error. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) -- `argc`: [`size`](#size) -The number of arguments. +Offset: 0 + +- `1`: [`size`](#size) + +Offset: 4 -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `err`: [`errno`](#errno) --- -#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` +#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). @@ -1206,28 +1329,51 @@ The sizes of the buffers should match that returned by [`environ_sizes_get`](#en - `environ_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `environ_sizes_get() -> (errno, size, size)` +#### `environ_sizes_get() -> Result<(size, size), errno>` Return environment variable data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of environment variable arguments and the size of the +environment variable data. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`size`](#size) -- `environc`: [`size`](#size) -The number of environment variable arguments. +Offset: 4 -- `environ_buf_size`: [`size`](#size) -The size of the environment variable data. +- `err`: [`errno`](#errno) --- -#### `clock_res_get(id: clockid) -> (errno, timestamp)` +#### `clock_res_get(id: clockid) -> Result` Return the resolution of a clock. Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return [`errno::inval`](#errno.inval). @@ -1238,15 +1384,22 @@ Note: This is similar to `clock_getres` in POSIX. The clock for which to return the resolution. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result` +The resolution of the clock, or an error if one happened. + +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) -- `resolution`: [`timestamp`](#timestamp) -The resolution of the clock. +- `err`: [`errno`](#errno) --- -#### `clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +#### `clock_time_get(id: clockid, precision: timestamp) -> Result` Return the time value of a clock. Note: This is similar to `clock_gettime` in POSIX. @@ -1258,15 +1411,22 @@ The clock for which to return the time. The maximum lag (exclusive) that the returned time value may have, compared to its actual value. ##### Results -- `error`: [`errno`](#errno) - -- `time`: [`timestamp`](#timestamp) +- `error`: `Result` The time value of the clock. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) + +- `err`: [`errno`](#errno) + --- -#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` Provide file advisory information on a file descriptor. Note: This is similar to `posix_fadvise` in POSIX. @@ -1283,12 +1443,21 @@ The length of the region to which the advisory applies. The advice. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno` +#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` Force the allocation of space in a file. Note: This is similar to `posix_fallocate` in POSIX. @@ -1302,12 +1471,21 @@ The offset at which to start the allocation. The length of the area that is allocated. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_close(fd: fd) -> errno` +#### `fd_close(fd: fd) -> Result<(), errno>` Close a file descriptor. Note: This is similar to `close` in POSIX. @@ -1315,12 +1493,21 @@ Note: This is similar to `close` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_datasync(fd: fd) -> errno` +#### `fd_datasync(fd: fd) -> Result<(), errno>` Synchronize the data of a file to disk. Note: This is similar to `fdatasync` in POSIX. @@ -1328,12 +1515,21 @@ Note: This is similar to `fdatasync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_fdstat_get(fd: fd) -> (errno, fdstat)` +#### `fd_fdstat_get(fd: fd) -> Result` Get the attributes of a file descriptor. Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. @@ -1341,15 +1537,22 @@ Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as ad - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `stat`: [`fdstat`](#fdstat) +- `error`: `Result` The buffer where the file descriptor's attributes are stored. +###### Variant Layout +- size: 32 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`fdstat`](#fdstat) + +- `err`: [`errno`](#errno) + --- -#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` Adjust the flags associated with a file descriptor. Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. @@ -1360,12 +1563,21 @@ Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. The desired values of the file descriptor flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` Adjust the rights associated with a file descriptor. This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights @@ -1378,27 +1590,43 @@ The desired rights of the file descriptor. - `fs_rights_inheriting`: [`rights`](#rights) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_filestat_get(fd: fd) -> (errno, filestat)` +#### `fd_filestat_get(fd: fd) -> Result` Return the attributes of an open file. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 72 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `fd_filestat_set_size(fd: fd, size: filesize) -> errno` +#### `fd_filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. Note: This is similar to `ftruncate` in POSIX. @@ -1409,12 +1637,21 @@ Note: This is similar to `ftruncate` in POSIX. The desired file size. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of an open file or directory. Note: This is similar to `futimens` in POSIX. @@ -1431,12 +1668,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` Read from a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `preadv` in POSIX. @@ -1450,30 +1696,44 @@ List of scatter/gather vectors in which to store data. The offset within the file at which to read. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_prestat_get(fd: fd) -> (errno, prestat)` +#### `fd_prestat_get(fd: fd) -> Result` Return a description of the given preopened file descriptor. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`prestat`](#prestat) +- `error`: `Result` The buffer where the description is stored. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`prestat`](#prestat) + +- `err`: [`errno`](#errno) + --- -#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` Return a description of the given preopened file descriptor. ##### Params @@ -1485,12 +1745,21 @@ A buffer into which to write the preopened directory name. - `path_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` Write to a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `pwritev` in POSIX. @@ -1504,15 +1773,22 @@ List of scatter/gather vectors from which to retrieve data. The offset within the file at which to write. ##### Results -- `error`: [`errno`](#errno) - -- `nwritten`: [`size`](#size) +- `error`: `Result` The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_read(fd: fd, iovs: iovec_array) -> (errno, size)` +#### `fd_read(fd: fd, iovs: iovec_array) -> Result` Read from a file descriptor. Note: This is similar to `readv` in POSIX. @@ -1523,15 +1799,22 @@ Note: This is similar to `readv` in POSIX. List of scatter/gather vectors to which to store data. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of directory entries. Each directory entry consists of a [`dirent`](#dirent) object, @@ -1554,15 +1837,22 @@ The buffer where directory entries are stored The location within the directory to start reading ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_renumber(fd: fd, to: fd) -> errno` +#### `fd_renumber(fd: fd, to: fd) -> Result<(), errno>` Atomically replace a file descriptor by renumbering another file descriptor. Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary @@ -1579,12 +1869,21 @@ would disappear if `dup2()` were to be removed entirely. The file descriptor to overwrite. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> Result` Move the offset of a file descriptor. Note: This is similar to `lseek` in POSIX. @@ -1598,15 +1897,22 @@ The number of bytes to move. The base from which the offset is relative. ##### Results -- `error`: [`errno`](#errno) - -- `newoffset`: [`filesize`](#filesize) +- `error`: `Result` The new offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `fd_sync(fd: fd) -> errno` +#### `fd_sync(fd: fd) -> Result<(), errno>` Synchronize the data and metadata of a file to disk. Note: This is similar to `fsync` in POSIX. @@ -1614,12 +1920,21 @@ Note: This is similar to `fsync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_tell(fd: fd) -> (errno, filesize)` +#### `fd_tell(fd: fd) -> Result` Return the current offset of a file descriptor. Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. @@ -1627,15 +1942,22 @@ Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `offset`: [`filesize`](#filesize) +- `error`: `Result` The current offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)` +#### `fd_write(fd: fd, iovs: ciovec_array) -> Result` Write to a file descriptor. Note: This is similar to `writev` in POSIX. @@ -1646,15 +1968,21 @@ Note: This is similar to `writev` in POSIX. List of scatter/gather vectors from which to retrieve data. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result` -- `nwritten`: [`size`](#size) -The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) --- -#### `path_create_directory(fd: fd, path: string) -> errno` +#### `path_create_directory(fd: fd, path: string) -> Result<(), errno>` Create a directory. Note: This is similar to `mkdirat` in POSIX. @@ -1665,12 +1993,21 @@ Note: This is similar to `mkdirat` in POSIX. The path at which to create the directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` Return the attributes of a file or directory. Note: This is similar to `stat` in POSIX. @@ -1684,15 +2021,22 @@ Flags determining the method of how the path is resolved. The path of the file or directory to inspect. ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 72 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of a file or directory. Note: This is similar to `utimensat` in POSIX. @@ -1715,12 +2059,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Create a hard link. Note: This is similar to `linkat` in POSIX. @@ -1740,12 +2093,21 @@ The working directory at which the resolution of the new path starts. The destination path at which to create the hard link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> (errno, fd)` +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> Result` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1781,15 +2143,22 @@ file descriptors derived from it. - `fdflags`: [`fdflags`](#fdflags) ##### Results -- `error`: [`errno`](#errno) - -- `opened_fd`: [`fd`](#fd) +- `error`: `Result` The file descriptor of the file that has been opened. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`fd`](#fd) + +- `err`: [`errno`](#errno) + --- -#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` Read the contents of a symbolic link. Note: This is similar to `readlinkat` in POSIX. @@ -1805,15 +2174,22 @@ The buffer to which to write the contents of the symbolic link. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes placed in the buffer. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `path_remove_directory(fd: fd, path: string) -> errno` +#### `path_remove_directory(fd: fd, path: string) -> Result<(), errno>` Remove a directory. Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. @@ -1825,12 +2201,21 @@ Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. The path to a directory to remove. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Rename a file or directory. Note: This is similar to `renameat` in POSIX. @@ -1847,12 +2232,21 @@ The working directory at which the resolution of the new path starts. The destination path to which to rename the file or directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_symlink(old_path: string, fd: fd, new_path: string) -> errno` +#### `path_symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` Create a symbolic link. Note: This is similar to `symlinkat` in POSIX. @@ -1866,12 +2260,21 @@ The contents of the symbolic link. The destination path at which to create the symbolic link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_unlink_file(fd: fd, path: string) -> errno` +#### `path_unlink_file(fd: fd, path: string) -> Result<(), errno>` Unlink a file. Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. @@ -1883,12 +2286,21 @@ Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. The path to a file to unlink. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` Concurrently poll for the occurrence of a set of events. ##### Params @@ -1902,11 +2314,18 @@ The events that have occurred. Both the number of subscriptions and events. ##### Results -- `error`: [`errno`](#errno) - -- `nevents`: [`size`](#size) +- `error`: `Result` The number of events stored. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- @@ -1923,7 +2342,7 @@ The exit code returned by the process. --- -#### `proc_raise(sig: signal) -> errno` +#### `proc_raise(sig: signal) -> Result<(), errno>` Send a signal to the process of the calling thread. Note: This is similar to `raise` in POSIX. @@ -1932,23 +2351,41 @@ Note: This is similar to `raise` in POSIX. The signal condition to trigger. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sched_yield() -> errno` +#### `sched_yield() -> Result<(), errno>` Temporarily yield execution of the calling thread. Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `random_get(buf: Pointer, buf_len: size) -> errno` +#### `random_get(buf: Pointer, buf_len: size) -> Result<(), errno>` Write high-quality random data into a buffer. This function blocks when the implementation is unable to immediately provide sufficient high-quality random data. @@ -1963,12 +2400,21 @@ The buffer to fill with random data. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` Receive a message from a socket. Note: This is similar to `recv` in POSIX, though it also supports reading the data into multiple buffers in the manner of `readv`. @@ -1983,18 +2429,31 @@ List of scatter/gather vectors to which to store data. Message flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, roflags), errno>` +Number of bytes stored in ri_data and message flags. -- `ro_datalen`: [`size`](#size) -Number of bytes stored in ri_data. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, roflags)` -- `ro_flags`: [`roflags`](#roflags) -Message flags. +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`roflags`](#roflags) + +Offset: 4 + +- `err`: [`errno`](#errno) --- -#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` Send a message on a socket. Note: This is similar to `send` in POSIX, though it also supports writing the data from multiple buffers in the manner of `writev`. @@ -2009,15 +2468,22 @@ List of scatter/gather vectors to which to retrieve data Message flags. ##### Results -- `error`: [`errno`](#errno) - -- `so_datalen`: [`size`](#size) +- `error`: `Result` Number of bytes transmitted. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `sock_shutdown(fd: fd, how: sdflags) -> errno` +#### `sock_shutdown(fd: fd, how: sdflags) -> Result<(), errno>` Shut down socket send and receive channels. Note: This is similar to `shutdown` in POSIX. @@ -2028,5 +2494,14 @@ Note: This is similar to `shutdown` in POSIX. Which channels on the socket to shut down. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx index 70e726553..311b42233 100644 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ b/proposals/clocks/phases/snapshot/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags (@witx bitflags u64) + (flags (@witx repr u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke @@ -381,7 +381,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -418,7 +418,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -432,7 +432,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags (@witx bitflags u32) + (flags (@witx repr u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -440,7 +440,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Create file if it does not exist. $creat ;;; Fail if not a directory. @@ -499,7 +499,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -534,7 +534,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -693,7 +693,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -703,7 +703,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -715,7 +715,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags (@witx bitflags u8) + (flags (@witx repr u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx index eacfab268..df3c670f3 100644 --- a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -17,15 +17,13 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; Returns the number of arguments and the size of the argument string + ;;; data, or an error. + (result $error (expected (tuple $size $size) (error $errno))) ) ;;; Read environment variable data. @@ -33,15 +31,13 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return environment variable data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno) - ;;; The number of environment variable arguments. - (result $environc $size) - ;;; The size of the environment variable data. - (result $environ_buf_size $size) + ;;; Returns the number of environment variable arguments and the size of the + ;;; environment variable data. + (result $error (expected (tuple $size $size) (error $errno))) ) ;;; Return the resolution of a clock. @@ -51,9 +47,8 @@ (@interface func (export "clock_res_get") ;;; The clock for which to return the resolution. (param $id $clockid) - (result $error $errno) - ;;; The resolution of the clock. - (result $resolution $timestamp) + ;;; The resolution of the clock, or an error if one happened. + (result $error (expected $timestamp (error $errno))) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. @@ -62,9 +57,8 @@ (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp) - (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp) + (result $error (expected $timestamp (error $errno))) ) ;;; Provide file advisory information on a file descriptor. @@ -77,7 +71,7 @@ (param $len $filesize) ;;; The advice. (param $advice $advice) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Force the allocation of space in a file. @@ -88,30 +82,29 @@ (param $offset $filesize) ;;; The length of the area that is allocated. (param $len $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat) + (result $error (expected $fdstat (error $errno))) ) ;;; Adjust the flags associated with a file descriptor. @@ -120,7 +113,7 @@ (param $fd $fd) ;;; The desired values of the file descriptor flags. (param $flags $fdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the rights associated with a file descriptor. @@ -130,15 +123,14 @@ ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. @@ -147,7 +139,7 @@ (param $fd $fd) ;;; The desired file size. (param $size $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the timestamps of an open file or directory. @@ -160,7 +152,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. @@ -171,17 +163,15 @@ (param $iovs $iovec_array) ;;; The offset within the file at which to read. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat) + (result $error (expected $prestat (error $errno))) ) ;;; Return a description of the given preopened file descriptor. @@ -190,7 +180,7 @@ ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. @@ -201,9 +191,8 @@ (param $iovs $ciovec_array) ;;; The offset within the file at which to write. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Read from a file descriptor. @@ -212,9 +201,8 @@ (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_array) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Read directory entries from a directory. @@ -234,9 +222,8 @@ (param $buf_len $size) ;;; The location within the directory to start reading (param $cookie $dircookie) - (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -253,7 +240,7 @@ (param $fd $fd) ;;; The file descriptor to overwrite. (param $to $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Move the offset of a file descriptor. @@ -264,25 +251,23 @@ (param $offset $filedelta) ;;; The base from which the offset is relative. (param $whence $whence) - (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd) - (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Write to a file descriptor. @@ -291,9 +276,7 @@ (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_array) - (result $error $errno) - ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Create a directory. @@ -302,7 +285,7 @@ (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of a file or directory. @@ -313,9 +296,8 @@ (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the timestamps of a file or directory. @@ -332,7 +314,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a hard link. @@ -347,7 +329,7 @@ (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Open a file or directory. @@ -379,9 +361,8 @@ (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) - (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd) + (result $error (expected $fd (error $errno))) ) ;;; Read the contents of a symbolic link. @@ -393,9 +374,8 @@ ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Remove a directory. @@ -405,7 +385,7 @@ (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Rename a file or directory. @@ -418,7 +398,7 @@ (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a symbolic link. @@ -429,7 +409,7 @@ (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) @@ -440,7 +420,7 @@ (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Concurrently poll for the occurrence of a set of events. @@ -451,9 +431,8 @@ (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. (param $nsubscriptions $size) - (result $error $errno) ;;; The number of events stored. - (result $nevents $size) + (result $error (expected $size (error $errno))) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -470,13 +449,13 @@ (@interface func (export "proc_raise") ;;; The signal condition to trigger. (param $sig $signal) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write high-quality random data into a buffer. @@ -489,7 +468,7 @@ ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Receive a message from a socket. @@ -501,11 +480,8 @@ (param $ri_data $iovec_array) ;;; Message flags. (param $ri_flags $riflags) - (result $error $errno) - ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size) - ;;; Message flags. - (result $ro_flags $roflags) + ;;; Number of bytes stored in ri_data and message flags. + (result $error (expected (tuple $size $roflags) (error $errno))) ) ;;; Send a message on a socket. @@ -517,9 +493,8 @@ (param $si_data $ciovec_array) ;;; Message flags. (param $si_flags $siflags) - (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size) + (result $error (expected $size (error $errno))) ) ;;; Shut down socket send and receive channels. @@ -528,6 +503,6 @@ (param $fd $fd) ;;; Which channels on the socket to shut down. (param $how $sdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index bf9ce16cd..bd4bfc076 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.8" +version = "0.9.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" @@ -17,7 +17,7 @@ crate-type=["rlib"] anyhow = "1" log = "0.4" thiserror = "1.0" -wast = { version = "22.0.0", default-features = false } +wast = { version = "33.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" diff --git a/proposals/clocks/tools/witx/src/abi.rs b/proposals/clocks/tools/witx/src/abi.rs new file mode 100644 index 000000000..0e1ca9cb4 --- /dev/null +++ b/proposals/clocks/tools/witx/src/abi.rs @@ -0,0 +1,925 @@ +//! Definition of the ABI of witx functions +//! +//! This module is intended to assist with code generators which are binding or +//! implementing APIs defined by `*.witx` files. THis module contains all +//! details necessary to implement the actual ABI of these functions so wasm +//! modules and hosts can communicate with one another. +//! +//! Each interface types function (a function defined in `*.witx`) currently has +//! a well-known wasm signature associated with it. There's then also a standard +//! way to convert from interface-types values (whose representation is defined +//! per-language) into this wasm API. This module is intended to assist with +//! this definition. +//! +//! Contained within are two primary functions, [`InterfaceFunc::call_wasm`] and +//! [`InterfaceFunc::call_interface`]. These functions implement the two ways to +//! interact with an interface types function, namely calling the raw wasm +//! version and calling the high-level version with interface types. These two +//! functions are fed a structure that implements [`Bindgen`]. An instance of +//! [`Bindgen`] receives instructions which are low-level implementation details +//! of how to convert to and from wasm types and interface types. Code +//! generators will need to implement the various instructions to support APIs. + +use crate::{ + BuiltinType, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, NamedType, Type, TypeRef, +}; + +/// Enumerates wasm types used by interface types when lowering/lifting. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum WasmType { + I32, + I64, + F32, + F64, + // NOTE: we don't lower interface types to any other Wasm type, + // e.g. externref, so we don't need to define them here. +} + +impl From for WasmType { + fn from(i: IntRepr) -> WasmType { + match i { + IntRepr::U8 | IntRepr::U16 | IntRepr::U32 => WasmType::I32, + IntRepr::U64 => WasmType::I64, + } + } +} + +/// Possible ABIs for interface functions to have. +/// +/// Note that this is a stopgap until we have more of interface types. Interface +/// types functions do not have ABIs, they have APIs. For the meantime, however, +/// we mandate ABIs to ensure we can all talk to each other. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum Abi { + /// Only stable ABI currently, and is the historical WASI ABI since it was + /// first created. + /// + /// Note that this ABI is limited notably in its return values where it can + /// only return 0 results or one `Result` lookalike. + Preview1, +} + +// Helper macro for defining instructions without having to have tons of +// exhaustive `match` statements to update +macro_rules! def_instruction { + ( + $( #[$enum_attr:meta] )* + pub enum Instruction<'a> { + $( + $( #[$attr:meta] )* + $variant:ident $( { + $($field:ident : $field_ty:ty $(,)* )* + } )? + : + [$num_popped:expr] => [$num_pushed:expr], + )* + } + ) => { + $( #[$enum_attr] )* + pub enum Instruction<'a> { + $( + $( #[$attr] )* + $variant $( { + $( + $field : $field_ty, + )* + } )? , + )* + } + + impl Instruction<'_> { + /// How many operands does this instruction pop from the stack? + #[allow(unused_variables)] + pub fn operands_len(&self) -> usize { + match self { + $( + Self::$variant $( { + $( + $field, + )* + } )? => $num_popped, + )* + } + } + + /// How many results does this instruction push onto the stack? + #[allow(unused_variables)] + pub fn results_len(&self) -> usize { + match self { + $( + Self::$variant $( { + $( + $field, + )* + } )? => $num_pushed, + )* + } + } + } + }; +} + +def_instruction! { + #[derive(Debug)] + pub enum Instruction<'a> { + /// Acquires the specified parameter and places it on the stack. + /// Depending on the context this may refer to wasm parameters or + /// interface types parameters. + GetArg { nth: usize } : [0] => [1], + /// Takes the value off the top of the stack and writes it into linear + /// memory. Pushes the address in linear memory as an `i32`. + AddrOf : [1] => [1], + /// Converts an interface type `char` value to a 32-bit integer + /// representing the unicode scalar value. + I32FromChar : [1] => [1], + /// Converts an interface type `u64` value to a wasm `i64`. + I64FromU64 : [1] => [1], + /// Converts an interface type `s64` value to a wasm `i64`. + I64FromS64 : [1] => [1], + /// Converts an interface type `u32` value to a wasm `i32`. + I32FromU32 : [1] => [1], + /// Converts an interface type `s32` value to a wasm `i32`. + I32FromS32 : [1] => [1], + /// Converts a language-specific `usize` value to a wasm `i32`. + I32FromUsize : [1] => [1], + /// Converts an interface type `u16` value to a wasm `i32`. + I32FromU16 : [1] => [1], + /// Converts an interface type `s16` value to a wasm `i32`. + I32FromS16 : [1] => [1], + /// Converts an interface type `u8` value to a wasm `i32`. + I32FromU8 : [1] => [1], + /// Converts an interface type `s8` value to a wasm `i32`. + I32FromS8 : [1] => [1], + /// Converts a language-specific C `char` value to a wasm `i32`. + I32FromChar8 : [1] => [1], + /// Converts a language-specific pointer value to a wasm `i32`. + I32FromPointer : [1] => [1], + /// Converts a language-specific pointer value to a wasm `i32`. + I32FromConstPointer : [1] => [1], + /// Converts a language-specific handle value to a wasm `i32`. + I32FromHandle { ty: &'a NamedType } : [1] => [1], + /// Converts a language-specific record-of-bools to the packed + /// representation as an `i32`. + I32FromBitflags { ty: &'a NamedType } : [1] => [1], + /// Converts a language-specific record-of-bools to the packed + /// representation as an `i64`. + I64FromBitflags { ty: &'a NamedType } : [1] => [1], + /// Converts an interface type list into its pointer/length, pushing + /// them both on the stack. + ListPointerLength : [1] => [2], + /// Pops two `i32` values from the stack and creates a list from them of + /// the specified type. The first operand is the pointer in linear + /// memory to the start of the list and the second operand is the + /// length. + ListFromPointerLength { ty: &'a TypeRef } : [2] => [1], + /// Conversion an interface type `f32` value to a wasm `f32`. + /// + /// This may be a noop for some implementations, but it's here in case the + /// native language representation of `f32` is different than the wasm + /// representation of `f32`. + F32FromIf32 : [1] => [1], + /// Conversion an interface type `f64` value to a wasm `f64`. + /// + /// This may be a noop for some implementations, but it's here in case the + /// native language representation of `f64` is different than the wasm + /// representation of `f64`. + F64FromIf64 : [1] => [1], + + /// Represents a call to a raw WebAssembly API. The module/name are + /// provided inline as well as the types if necessary. + CallWasm { + module: &'a str, + name: &'a str, + params: &'a [WasmType], + results: &'a [WasmType], + } : [params.len()] => [results.len()], + + /// Same as `CallWasm`, except the dual where an interface is being + /// called rather than a raw wasm function. + CallInterface { + module: &'a str, + func: &'a InterfaceFunc, + } : [func.params.len()] => [func.results.len()], + + /// Converts a native wasm `i32` to an interface type `s8`. + /// + /// This will truncate the upper bits of the `i32`. + S8FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `u8`. + /// + /// This will truncate the upper bits of the `i32`. + U8FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `s16`. + /// + /// This will truncate the upper bits of the `i32`. + S16FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `u16`. + /// + /// This will truncate the upper bits of the `i32`. + U16FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `s32`. + S32FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `u32`. + U32FromI32 : [1] => [1], + /// Converts a native wasm `i64` to an interface type `s64`. + S64FromI64 : [1] => [1], + /// Converts a native wasm `i64` to an interface type `u64`. + U64FromI64 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `char`. + /// + /// It's safe to assume that the `i32` is indeed a valid unicode code point. + CharFromI32 : [1] => [1], + /// Converts a native wasm `i32` to a language-specific C `char`. + /// + /// This will truncate the upper bits of the `i32`. + Char8FromI32 : [1] => [1], + /// Converts a native wasm `i32` to a language-specific `usize`. + UsizeFromI32 : [1] => [1], + /// Converts a native wasm `f32` to an interface type `f32`. + If32FromF32 : [1] => [1], + /// Converts a native wasm `f64` to an interface type `f64`. + If64FromF64 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `handle`. + HandleFromI32 { ty: &'a NamedType } : [1] => [1], + /// Converts a native wasm `i32` to a language-specific pointer. + PointerFromI32 { ty: &'a TypeRef }: [1] => [1], + /// Converts a native wasm `i32` to a language-specific pointer. + ConstPointerFromI32 { ty: &'a TypeRef } : [1] => [1], + /// Converts a native wasm `i32` to a language-specific record-of-bools. + BitflagsFromI32 { ty: &'a NamedType } : [1] => [1], + /// Converts a native wasm `i64` to a language-specific record-of-bools. + BitflagsFromI64 { ty: &'a NamedType } : [1] => [1], + /// Acquires the return pointer `n` and pushes an `i32` on the stack. + /// + /// Implementations of [`Bindgen`] may have [`Bindgen::allocate_space`] + /// called to reserve space in memory for the result of a computation to + /// get written. This instruction acquires a pointer to the space + /// reserved in `allocate_space`. + ReturnPointerGet { n: usize } : [0] => [1], + /// Loads the interface types value from an `i32` pointer popped from + /// the stack. + Load { ty: &'a NamedType } : [1] => [1], + /// Stores an interface types value into linear memory. The first + /// operand is the value to store and the second operand is the pointer + /// in linear memory to store it at. + Store { ty: &'a NamedType } : [2] => [0], + /// Pops a native wasm `i32` from the stack, as well as two blocks + /// internally from the code generator. + /// + /// If the value is 0 then the first "ok" block value should be used. + /// If the value is anything else then the second "err" block value + /// should be used, and the value is used as the error enum. + /// + /// Note that this is a special instruction matching the current ABI of + /// WASI and intentionally differs from the type-level grammar of + /// interface types results. + ResultLift : [1] => [1], + /// Pops a native interface value from the stack as well as two blocks + /// internally from the code generator. + /// + /// A `match` is performed on the value popped and the corresponding + /// block for ok/err is used depending on value. This pushes a single + /// `i32` onto the stack representing the error code for this result. + /// + /// Note that like `ResultLift` this is specialized to the current WASI + /// ABI. + ResultLower { + ok: Option<&'a TypeRef>, + err: Option<&'a TypeRef>, + } : [1] => [1], + /// Converts a native wasm `i32` to an interface type `enum` value. + /// + /// It's guaranteed that the interface type integer value is within + /// range for this enum's type. Additionally `ty` is guaranteed to be + /// enum-like as a `Variant` where all `case` arms have no associated + /// type with them. The purpose of this instruction is to convert a + /// native wasm integer into the enum type for the interface. + EnumLift { ty: &'a NamedType } : [1] => [1], + /// Converts an interface types enum value into a wasm `i32`. + EnumLower { ty: &'a NamedType } : [1] => [1], + /// Creates a tuple from the top `n` elements on the stack, pushing the + /// tuple onto the stack. + TupleLift { amt: usize } : [*amt] => [1], + /// Splits a tuple at the top of the stack into its `n` components, + /// pushing them all onto the stack. + TupleLower { amt: usize } : [1] => [*amt], + /// This is a special instruction specifically for the original ABI of + /// WASI. The raw return `i32` of a function is re-pushed onto the + /// stack for reuse. + ReuseReturn : [0] => [1], + /// Returns `amt` values on the stack. This is always the last + /// instruction. + Return { amt: usize } : [*amt] => [0], + /// This is a special instruction used at the entry of blocks used as + /// part of `ResultLower`, representing that the payload of that variant + /// being matched on should be pushed onto the stack. + VariantPayload : [0] => [1], + } +} + +impl Abi { + /// Validates the parameters/results are representable in this ABI. + /// + /// Returns an error string if they're not representable or returns `Ok` if + /// they're indeed representable. + pub fn validate( + &self, + _params: &[InterfaceFuncParam], + results: &[InterfaceFuncParam], + ) -> Result<(), String> { + assert_eq!(*self, Abi::Preview1); + match results.len() { + 0 => {} + 1 => match &**results[0].tref.type_() { + Type::Handle(_) | Type::Builtin(_) | Type::ConstPointer(_) | Type::Pointer(_) => {} + Type::Variant(v) => { + let (ok, err) = match v.as_expected() { + Some(pair) => pair, + None => return Err("invalid return type".to_string()), + }; + if let Some(ty) = ok { + match &**ty.type_() { + Type::Record(r) if r.is_tuple() => { + for member in r.members.iter() { + if !member.tref.named() { + return Err( + "only named types are allowed in results".to_string() + ); + } + } + } + _ => { + if !ty.named() { + return Err( + "only named types are allowed in results".to_string() + ); + } + } + } + } + if let Some(ty) = err { + if !ty.named() { + return Err("only named types are allowed in results".to_string()); + } + if let Type::Variant(v) = &**ty.type_() { + if v.is_enum() { + return Ok(()); + } + } + } + } + Type::Record(r) if r.bitflags_repr().is_some() => {} + Type::Record(_) | Type::List(_) => return Err("invalid return type".to_string()), + }, + _ => return Err("more than one result".to_string()), + } + Ok(()) + } +} + +/// Trait for language implementors to use to generate glue code between native +/// WebAssembly signatures and interface types signatures. +/// +/// This is used as an implementation detail in interpreting the ABI between +/// interface types and wasm types. Eventually this will be driven by interface +/// types adapters themselves, but for now the ABI of a function dictates what +/// instructions are fed in. +/// +/// Types implementing `Bindgen` are incrementally fed `Instruction` values to +/// generate code for. Instructions operate like a stack machine where each +/// instruction has a list of inputs and a list of outputs (provided by the +/// `emit` function). +pub trait Bindgen { + /// The intermediate type for fragments of code for this type. + /// + /// For most languages `String` is a suitable intermediate type. + type Operand; + + /// Emit code to implement the given instruction. + /// + /// Each operand is given in `operands` and can be popped off if ownership + /// is required. It's guaranteed that `operands` has the appropriate length + /// for the `inst` given, as specified with [`Instruction`]. + /// + /// Each result variable should be pushed onto `results`. This function must + /// push the appropriate number of results or binding generation will panic. + fn emit( + &mut self, + inst: &Instruction<'_>, + operands: &mut Vec, + results: &mut Vec, + ); + + /// Allocates temporary space in linear memory indexed by `slot` with enough + /// space to store `ty`. + /// + /// This is called when calling some wasm functions where a return pointer + /// is needed. + fn allocate_space(&mut self, slot: usize, ty: &NamedType); + + /// Enters a new block of code to generate code for. + /// + /// This is currently exclusively used for constructing variants. When a + /// variant is constructed a block here will be pushed for each case of a + /// variant, generating the code necessary to translate a variant case. + /// + /// Blocks are completed with `finish_block` below. It's expected that `emit` + /// will always push code (if necessary) into the "current block", which is + /// updated by calling this method and `finish_block` below. + fn push_block(&mut self); + + /// Indicates to the code generator that a block is completed, and the + /// `operand` specified was the resulting value of the block. + /// + /// This method will be used to compute the value of each arm of lifting a + /// variant. The `operand` will be `None` if the variant case didn't + /// actually have any type associated with it. Otherwise it will be `Some` + /// as the last value remaining on the stack representing the value + /// associated with a variant's `case`. + /// + /// It's expected that this will resume code generation in the previous + /// block before `push_block` was called. This must also save the results + /// of the current block internally for instructions like `ResultLift` to + /// use later. + fn finish_block(&mut self, operand: Option); +} + +impl InterfaceFunc { + /// Get the WebAssembly type signature for this interface function + /// + /// The first entry returned is the list of parameters and the second entry + /// is the list of results for the wasm function signature. + pub fn wasm_signature(&self) -> (Vec, Vec) { + assert_eq!(self.abi, Abi::Preview1); + let mut params = Vec::new(); + let mut results = Vec::new(); + for param in self.params.iter() { + match &**param.tref.type_() { + Type::Builtin(BuiltinType::S8) + | Type::Builtin(BuiltinType::U8 { .. }) + | Type::Builtin(BuiltinType::S16) + | Type::Builtin(BuiltinType::U16) + | Type::Builtin(BuiltinType::S32) + | Type::Builtin(BuiltinType::U32 { .. }) + | Type::Builtin(BuiltinType::Char) + | Type::Pointer(_) + | Type::ConstPointer(_) + | Type::Handle(_) + | Type::Variant(_) => params.push(WasmType::I32), + + Type::Record(r) => match r.bitflags_repr() { + Some(repr) => params.push(WasmType::from(repr)), + None => params.push(WasmType::I32), + }, + + Type::Builtin(BuiltinType::S64) | Type::Builtin(BuiltinType::U64) => { + params.push(WasmType::I64) + } + + Type::Builtin(BuiltinType::F32) => params.push(WasmType::F32), + Type::Builtin(BuiltinType::F64) => params.push(WasmType::F64), + + Type::List(_) => { + params.push(WasmType::I32); + params.push(WasmType::I32); + } + } + } + + for param in self.results.iter() { + match &**param.tref.type_() { + Type::Builtin(BuiltinType::S8) + | Type::Builtin(BuiltinType::U8 { .. }) + | Type::Builtin(BuiltinType::S16) + | Type::Builtin(BuiltinType::U16) + | Type::Builtin(BuiltinType::S32) + | Type::Builtin(BuiltinType::U32 { .. }) + | Type::Builtin(BuiltinType::Char) + | Type::Pointer(_) + | Type::ConstPointer(_) + | Type::Handle(_) => results.push(WasmType::I32), + + Type::Builtin(BuiltinType::S64) | Type::Builtin(BuiltinType::U64) => { + results.push(WasmType::I64) + } + + Type::Builtin(BuiltinType::F32) => results.push(WasmType::F32), + Type::Builtin(BuiltinType::F64) => results.push(WasmType::F64), + + Type::Record(r) => match r.bitflags_repr() { + Some(repr) => results.push(WasmType::from(repr)), + None => unreachable!(), + }, + Type::List(_) => unreachable!(), + + Type::Variant(v) => { + results.push(match v.tag_repr { + IntRepr::U64 => WasmType::I64, + IntRepr::U32 | IntRepr::U16 | IntRepr::U8 => WasmType::I32, + }); + if v.is_enum() { + continue; + } + // return pointer + if let Some(ty) = &v.cases[0].tref { + match &**ty.type_() { + Type::Record(r) if r.is_tuple() => { + for _ in 0..r.members.len() { + params.push(WasmType::I32); + } + } + _ => params.push(WasmType::I32), + } + } + } + } + } + (params, results) + } + + /// Generates an abstract sequence of instructions which represents this + /// function being adapted as an imported function. + /// + /// The instructions here, when executed, will emulate a language with + /// interface types calling the concrete wasm implementation. The parameters + /// for the returned instruction sequence are the language's own + /// interface-types parameters. One instruction in the instruction stream + /// will be a `Call` which represents calling the actual raw wasm function + /// signature. + /// + /// This function is useful, for example, if you're building a language + /// generator for WASI bindings. This will document how to translate + /// language-specific values into the wasm types to call a WASI function, + /// and it will also automatically convert the results of the WASI function + /// back to a language-specific value. + pub fn call_wasm(&self, module: &Id, bindgen: &mut impl Bindgen) { + assert_eq!(self.abi, Abi::Preview1); + Generator { + bindgen, + operands: vec![], + results: vec![], + stack: vec![], + } + .call_wasm(module, self); + } + + /// This is the dual of [`InterfaceFunc::call_wasm`], except that instead of + /// calling a wasm signature it generates code to come from a wasm signature + /// and call an interface types signature. + pub fn call_interface(&self, module: &Id, bindgen: &mut impl Bindgen) { + assert_eq!(self.abi, Abi::Preview1); + Generator { + bindgen, + operands: vec![], + results: vec![], + stack: vec![], + } + .call_interface(module, self); + } +} + +struct Generator<'a, B: Bindgen> { + bindgen: &'a mut B, + operands: Vec, + results: Vec, + stack: Vec, +} + +impl Generator<'_, B> { + fn call_wasm(&mut self, module: &Id, func: &InterfaceFunc) { + // Translate all parameters which are interface values by lowering them + // to their wasm types. + for (nth, param) in func.params.iter().enumerate() { + self.emit(&Instruction::GetArg { nth }); + self.lower(¶m.tref, None); + } + + // If necessary for our ABI, insert return pointers for any returned + // values through a result. + assert!(func.results.len() < 2); + if let Some(result) = func.results.get(0) { + self.prep_return_pointer(&result.tref.type_()); + } + + let (params, results) = func.wasm_signature(); + self.emit(&Instruction::CallWasm { + module: module.as_str(), + name: func.name.as_str(), + params: ¶ms, + results: &results, + }); + + // Lift the return value if one is present. + if let Some(result) = func.results.get(0) { + self.lift(&result.tref, true); + } + + self.emit(&Instruction::Return { + amt: func.results.len(), + }); + } + + fn call_interface(&mut self, module: &Id, func: &InterfaceFunc) { + // Lift all wasm parameters into interface types first. + // + // Note that consuming arguments is somewhat janky right now by manually + // giving lists a second argument for their length. In the future we'll + // probably want to refactor the `lift` function to internally know how + // to consume arguments. + let mut nth = 0; + for param in func.params.iter() { + self.emit(&Instruction::GetArg { nth }); + nth += 1; + if let Type::List(_) = &**param.tref.type_() { + self.emit(&Instruction::GetArg { nth }); + nth += 1; + } + self.lift(¶m.tref, false); + } + + self.emit(&Instruction::CallInterface { + module: module.as_str(), + func, + }); + + // Like above the current ABI only has at most one result, so lower it + // here if necessary. + if let Some(result) = func.results.get(0) { + self.lower(&result.tref, Some(&mut nth)); + } + + let (_params, results) = func.wasm_signature(); + self.emit(&Instruction::Return { amt: results.len() }); + } + + fn emit(&mut self, inst: &Instruction<'_>) { + self.operands.clear(); + self.results.clear(); + + let operands_len = inst.operands_len(); + assert!( + self.stack.len() >= operands_len, + "not enough operands on stack for {:?}", + inst + ); + self.operands + .extend(self.stack.drain((self.stack.len() - operands_len)..)); + self.results.reserve(inst.results_len()); + + self.bindgen + .emit(inst, &mut self.operands, &mut self.results); + + assert_eq!( + self.results.len(), + inst.results_len(), + "{:?} expected {} results, got {}", + inst, + inst.results_len(), + self.results.len() + ); + self.stack.extend(self.results.drain(..)); + } + + fn lower(&mut self, ty: &TypeRef, retptr: Option<&mut usize>) { + use Instruction::*; + match &**ty.type_() { + Type::Builtin(BuiltinType::S8) => self.emit(&I32FromS8), + Type::Builtin(BuiltinType::U8 { lang_c_char: true }) => self.emit(&I32FromChar8), + Type::Builtin(BuiltinType::U8 { lang_c_char: false }) => self.emit(&I32FromU8), + Type::Builtin(BuiltinType::S16) => self.emit(&I32FromS16), + Type::Builtin(BuiltinType::U16) => self.emit(&I32FromU16), + Type::Builtin(BuiltinType::S32) => self.emit(&I32FromS32), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: true, + }) => self.emit(&I32FromUsize), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: false, + }) => self.emit(&I32FromU32), + Type::Builtin(BuiltinType::S64) => self.emit(&I64FromS64), + Type::Builtin(BuiltinType::U64) => self.emit(&I64FromU64), + Type::Builtin(BuiltinType::Char) => self.emit(&I32FromChar), + Type::Pointer(_) => self.emit(&I32FromPointer), + Type::ConstPointer(_) => self.emit(&I32FromConstPointer), + Type::Handle(_) => self.emit(&I32FromHandle { + ty: match ty { + TypeRef::Name(ty) => ty, + _ => unreachable!(), + }, + }), + Type::Record(r) => { + let ty = match ty { + TypeRef::Name(ty) => ty, + _ => unreachable!(), + }; + match r.bitflags_repr() { + Some(IntRepr::U64) => self.emit(&I64FromBitflags { ty }), + Some(_) => self.emit(&I32FromBitflags { ty }), + None => self.emit(&AddrOf), + } + } + Type::Variant(v) => { + // Enum-like variants are simply lowered to their discriminant. + if v.is_enum() { + return self.emit(&EnumLower { + ty: match ty { + TypeRef::Name(n) => n, + _ => unreachable!(), + }, + }); + } + + // If this variant is in the return position then it's special, + // otherwise it's an argument and we just pass the address. + let retptr = match retptr { + Some(ptr) => ptr, + None => return self.emit(&AddrOf), + }; + + // For the return position we emit some blocks to lower the + // ok/err payloads which means that in the ok branch we're + // storing to out-params and in the err branch we're simply + // lowering the error enum. + // + // Note that this is all very specific to the current WASI ABI. + let (ok, err) = v.as_expected().unwrap(); + self.bindgen.push_block(); + if let Some(ok) = ok { + self.emit(&VariantPayload); + let store = |me: &mut Self, ty: &TypeRef, n| { + me.emit(&GetArg { nth: *retptr + n }); + match ty { + TypeRef::Name(ty) => me.emit(&Store { ty }), + _ => unreachable!(), + } + }; + match &**ok.type_() { + Type::Record(r) if r.is_tuple() => { + self.emit(&TupleLower { + amt: r.members.len(), + }); + // Note that `rev()` is used here due to the order + // that tuples are pushed onto the stack and how we + // consume the last item first from the stack. + for (i, member) in r.members.iter().enumerate().rev() { + store(self, &member.tref, i); + } + } + _ => store(self, ok, 0), + } + }; + self.bindgen.finish_block(None); + + self.bindgen.push_block(); + let err_expr = if let Some(ty) = err { + self.emit(&VariantPayload); + self.lower(ty, None); + Some(self.stack.pop().unwrap()) + } else { + None + }; + self.bindgen.finish_block(err_expr); + + self.emit(&ResultLower { ok, err }); + } + Type::Builtin(BuiltinType::F32) => self.emit(&F32FromIf32), + Type::Builtin(BuiltinType::F64) => self.emit(&F64FromIf64), + Type::List(_) => self.emit(&ListPointerLength), + } + } + + fn prep_return_pointer(&mut self, ty: &Type) { + // Return pointers are only needed for `Result`... + let variant = match ty { + Type::Variant(v) => v, + _ => return, + }; + // ... and only if `T` is actually present in `Result` + let ok = match &variant.cases[0].tref { + Some(t) => t, + None => return, + }; + + // Tuples have each individual item in a separate return pointer while + // all other types go through a singular return pointer. + let mut n = 0; + let mut prep = |ty: &TypeRef| { + match ty { + TypeRef::Name(ty) => self.bindgen.allocate_space(n, ty), + _ => unreachable!(), + } + self.emit(&Instruction::ReturnPointerGet { n }); + n += 1; + }; + match &**ok.type_() { + Type::Record(r) if r.is_tuple() => { + for member in r.members.iter() { + prep(&member.tref); + } + } + _ => prep(ok), + } + } + + // Note that in general everything in this function is the opposite of the + // `lower` function above. This is intentional and should be kept this way! + fn lift(&mut self, ty: &TypeRef, is_return: bool) { + use Instruction::*; + match &**ty.type_() { + Type::Builtin(BuiltinType::S8) => self.emit(&S8FromI32), + Type::Builtin(BuiltinType::U8 { lang_c_char: true }) => self.emit(&Char8FromI32), + Type::Builtin(BuiltinType::U8 { lang_c_char: false }) => self.emit(&U8FromI32), + Type::Builtin(BuiltinType::S16) => self.emit(&S16FromI32), + Type::Builtin(BuiltinType::U16) => self.emit(&U16FromI32), + Type::Builtin(BuiltinType::S32) => self.emit(&S32FromI32), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: true, + }) => self.emit(&UsizeFromI32), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: false, + }) => self.emit(&U32FromI32), + Type::Builtin(BuiltinType::S64) => self.emit(&S64FromI64), + Type::Builtin(BuiltinType::U64) => self.emit(&U64FromI64), + Type::Builtin(BuiltinType::Char) => self.emit(&CharFromI32), + Type::Builtin(BuiltinType::F32) => self.emit(&If32FromF32), + Type::Builtin(BuiltinType::F64) => self.emit(&If64FromF64), + Type::Pointer(ty) => self.emit(&PointerFromI32 { ty }), + Type::ConstPointer(ty) => self.emit(&ConstPointerFromI32 { ty }), + Type::Handle(_) => self.emit(&HandleFromI32 { + ty: match ty { + TypeRef::Name(ty) => ty, + _ => unreachable!(), + }, + }), + Type::Variant(v) => { + if v.is_enum() { + return self.emit(&EnumLift { + ty: match ty { + TypeRef::Name(n) => n, + _ => unreachable!(), + }, + }); + } else if !is_return { + return self.emit(&Load { + ty: match ty { + TypeRef::Name(n) => n, + _ => unreachable!(), + }, + }); + } + + let (ok, err) = v.as_expected().unwrap(); + self.bindgen.push_block(); + let ok_expr = if let Some(ok) = ok { + let mut n = 0; + let mut load = |ty: &TypeRef| { + self.emit(&ReturnPointerGet { n }); + n += 1; + match ty { + TypeRef::Name(ty) => self.emit(&Load { ty }), + _ => unreachable!(), + } + }; + match &**ok.type_() { + Type::Record(r) if r.is_tuple() => { + for member in r.members.iter() { + load(&member.tref); + } + self.emit(&TupleLift { + amt: r.members.len(), + }); + } + _ => load(ok), + } + Some(self.stack.pop().unwrap()) + } else { + None + }; + self.bindgen.finish_block(ok_expr); + + self.bindgen.push_block(); + let err_expr = if let Some(ty) = err { + self.emit(&ReuseReturn); + self.lift(ty, false); + Some(self.stack.pop().unwrap()) + } else { + None + }; + self.bindgen.finish_block(err_expr); + + self.emit(&ResultLift); + } + Type::Record(r) => { + let ty = match ty { + TypeRef::Name(ty) => ty, + _ => unreachable!(), + }; + match r.bitflags_repr() { + Some(IntRepr::U64) => self.emit(&BitflagsFromI64 { ty }), + Some(_) => self.emit(&BitflagsFromI32 { ty }), + None => self.emit(&Load { ty }), + } + } + Type::List(ty) => self.emit(&ListFromPointerLength { ty }), + } + } +} diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs index 7d34b5f7f..ee985d302 100644 --- a/proposals/clocks/tools/witx/src/ast.rs +++ b/proposals/clocks/tools/witx/src/ast.rs @@ -1,4 +1,4 @@ -#![allow(dead_code)] +use crate::Abi; use std::collections::{HashMap, HashSet}; use std::rc::{Rc, Weak}; @@ -63,13 +63,27 @@ impl Document { _ => None, }) } - /// All of the (unique) types used as the first result value of a function. + /// All of the (unique) types used as "err" variant of results returned from + /// functions. pub fn error_types<'a>(&'a self) -> impl Iterator + 'a { let errors: HashSet = self .modules() .flat_map(|m| { m.funcs() - .filter_map(|f| f.results.get(0).as_ref().map(|r| r.tref.clone())) + .filter_map(|f| { + if f.results.len() == 1 { + Some(f.results[0].tref.type_().clone()) + } else { + None + } + }) + .filter_map(|t| match &*t { + Type::Variant(v) => { + let (_ok, err) = v.as_expected()?; + Some(err?.clone()) + } + _ => None, + }) .collect::>() }) .collect(); @@ -162,10 +176,17 @@ pub enum TypeRef { } impl TypeRef { - pub fn type_(&self) -> Rc { + pub fn type_(&self) -> &Rc { match self { TypeRef::Name(named) => named.type_(), - TypeRef::Value(ref v) => v.clone(), + TypeRef::Value(v) => v, + } + } + + pub fn named(&self) -> bool { + match self { + TypeRef::Name(_) => true, + TypeRef::Value(_) => false, } } } @@ -178,23 +199,42 @@ pub struct NamedType { } impl NamedType { - pub fn type_(&self) -> Rc { + pub fn type_(&self) -> &Rc { self.tref.type_() } } +/// Structure of all possible interface types. +/// +/// Note that this is intended to match the interface types proposal itself. +/// Currently this is relatively close to that with just a few `*.witx` +/// extensions for now. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { + /// A structure with named field. Record(RecordDatatype), + /// An enumeration where a value is one of a number of variants. Variant(Variant), + /// A "handle" which is an un-forgeable reference. Today this is an `i32` + /// where a module can't forge and use integers it was not already given + /// access to. Handle(HandleDatatype), + /// A list of a type, stored in linear memory. + /// + /// Note that lists of `char` are specialized to indicate strings. List(TypeRef), + /// A `witx`-specific type representing a raw mutable pointer into linear + /// memory Pointer(TypeRef), + /// A `witx`-specific type representing a raw const pointer into linear + /// memory ConstPointer(TypeRef), + /// A builtin base-case type. Builtin(BuiltinType), } impl Type { + /// Returns a human-readable string to describe this type. pub fn kind(&self) -> &'static str { use Type::*; match self { @@ -215,6 +255,7 @@ pub enum BuiltinType { /// /// Same as the Rust language's `char` type. Char, + /// An 8-bit unsigned integer. U8 { /// Indicates whether this type is intended to represent the `char` /// type in the C language. The C `char` type is often unsigned, but @@ -226,7 +267,9 @@ pub enum BuiltinType { /// pointer` to hint that it's pointing to unicode string data as well. lang_c_char: bool, }, + /// A 16-bit unsigned integer. U16, + /// A 32-bit unsigned integer. U32 { /// Indicates that this 32-bit value should actually be considered a /// pointer-like value in language bindings. At the interface types @@ -238,12 +281,19 @@ pub enum BuiltinType { /// argument or return-value is pointer-like. lang_ptr_size: bool, }, + /// A 64-bit unsigned integer. U64, + /// An 8-bit signed integer S8, + /// A 16-bit signed integer S16, + /// A 32-bit signed integer S32, + /// A 64-bit signed integer S64, + /// A 32-bit floating point value. F32, + /// A 64-bit floating point value. F64, } @@ -268,11 +318,37 @@ impl IntRepr { } } +/// A struct-like value with named fields. +/// +/// Records map to `struct`s in most languages where this is a type with a +/// number of named fields that all have their own particular type. Field order +/// dictates layout in memory. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct RecordDatatype { + /// A hint as to what this record might be. + /// + /// Note that in the future this will only be a hint, not a control of the + /// actual representation itself. At this time though the record layout of + /// bitflags is different from other types. + pub kind: RecordKind, + + /// A list of named fields for this record. pub members: Vec, } +/// Different kinds of records used for hinting various language-specific types. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum RecordKind { + /// A tuple where the name of all fields are consecutive integers starting + /// at "0". + Tuple, + /// A record where all fields are `bool`s. Currently represented as an + /// integer with bits set or not set. + Bitflags(IntRepr), + /// All other structures. + Other, +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct RecordMember { pub name: Id, @@ -280,16 +356,98 @@ pub struct RecordMember { pub docs: String, } +impl RecordDatatype { + pub fn is_tuple(&self) -> bool { + match self.kind { + RecordKind::Tuple => true, + _ => false, + } + } + + pub fn bitflags_repr(&self) -> Option { + match self.kind { + RecordKind::Bitflags(i) => Some(i), + _ => None, + } + } +} + +/// A type which represents how values can be one of a set of possible cases. +/// +/// This type maps to an `enum` in languages like Rust, but doesn't have an +/// equivalent in languages like JS or C. The closest analog in C is a tagged +/// union, but a `Variant` is always consistent whereas a tagged union in C +/// could be mis-tagged or such. +/// +/// Variants are used to represent one of a possible set of types. For example +/// an enum-like variant, a result that is either success or failure, or even a +/// simple `bool`. Variants are primarily used heavily with various kinds of +/// shorthands in the `*.witx` format to represent idioms in languages. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Variant { + /// The bit representation of the width of this variant's tag when the + /// variant is stored in memory. pub tag_repr: IntRepr, + /// The possible cases that values of this variant type can take. pub cases: Vec, } +impl Variant { + /// If this variant looks like an `expected` shorthand, return the ok/err + /// types associated with this result. + /// + /// Only matches variants fo the form: + /// + /// ```text + /// (variant + /// (case "ok" ok?) + /// (case "err" err?)) + /// ``` + pub fn as_expected(&self) -> Option<(Option<&TypeRef>, Option<&TypeRef>)> { + if self.cases.len() != 2 { + return None; + } + if self.cases[0].name != "ok" { + return None; + } + if self.cases[1].name != "err" { + return None; + } + Some((self.cases[0].tref.as_ref(), self.cases[1].tref.as_ref())) + } + + /// Returns whether this variant type is "bool-like" meaning that it matches + /// this type: + /// + /// ```text + /// (variant + /// (case "false") + /// (case "true")) + /// ``` + pub fn is_bool(&self) -> bool { + self.cases.len() == 2 + && self.cases[0].name == "false" + && self.cases[1].name == "true" + && self.cases[0].tref.is_none() + && self.cases[1].tref.is_none() + } + + /// Returns whether this variant type is "enum-like" meaning that all of its + /// cases have no payload associated with them. + pub fn is_enum(&self) -> bool { + self.cases.iter().all(|c| c.tref.is_none()) + } +} + +/// One of a number of possible types that a `Variant` can take. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Case { + /// The name of this case and how to identify it. pub name: Id, + /// An optional payload type for this case and data that can be associated + /// with it. pub tref: Option, + /// Documentation for this case. pub docs: String, } @@ -409,6 +567,7 @@ pub enum ModuleImportVariant { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct InterfaceFunc { + pub abi: Abi, pub name: Id, pub params: Vec, pub results: Vec, @@ -420,16 +579,9 @@ pub struct InterfaceFunc { pub struct InterfaceFuncParam { pub name: Id, pub tref: TypeRef, - pub position: InterfaceFuncParamPosition, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum InterfaceFuncParamPosition { - Param(usize), - Result(usize), -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Constant { pub ty: Id, diff --git a/proposals/clocks/tools/witx/src/coretypes.rs b/proposals/clocks/tools/witx/src/coretypes.rs deleted file mode 100644 index 826990369..000000000 --- a/proposals/clocks/tools/witx/src/coretypes.rs +++ /dev/null @@ -1,173 +0,0 @@ -use crate::{BuiltinType, IntRepr, InterfaceFunc, InterfaceFuncParam, Type}; - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -/// Enumerates the types permitted for function arguments in the WebAssembly spec -pub enum AtomType { - I32, - I64, - F32, - F64, -} - -impl From for AtomType { - fn from(i: IntRepr) -> AtomType { - match i { - IntRepr::U8 | IntRepr::U16 | IntRepr::U32 => AtomType::I32, - IntRepr::U64 => AtomType::I64, - } - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -/// Enumerates the strategies which may be used to pass a datatype as an argument -pub enum TypePassedBy { - /// Pass by value specifies the AtomType used to represent that value - Value(AtomType), - /// Pass by a pointer into linear memory - Pointer, - /// Pass by a pointer and length pair, into linear memory - PointerLengthPair, -} - -impl Type { - /// Determine the simplest strategy by which a type may be passed. Value always preferred over - /// Pointer. - pub fn passed_by(&self) -> TypePassedBy { - match self { - Type::Builtin(b) => match b { - BuiltinType::U8 { .. } - | BuiltinType::U16 - | BuiltinType::U32 { .. } - | BuiltinType::S8 - | BuiltinType::S16 - | BuiltinType::S32 - | BuiltinType::Char => TypePassedBy::Value(AtomType::I32), - BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), - BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), - BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), - }, - Type::List { .. } => TypePassedBy::PointerLengthPair, - Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), - Type::Record { .. } => TypePassedBy::Pointer, - Type::Variant(v) => { - if v.cases.iter().all(|c| c.tref.is_none()) { - TypePassedBy::Value(v.tag_repr.into()) - } else { - TypePassedBy::Pointer - } - } - Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), - } - } -} - -/// A parameter in the WebAssembly type of a function. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CoreParamType { - /// The interface function parameter to which this - pub param: InterfaceFuncParam, - /// The relationship of the WebAssembly parameter to the function interface parameter - pub signifies: CoreParamSignifies, -} - -impl CoreParamType { - /// Representation of the WebAssembly parameter. This is the type that will appear - /// in the function's WebAssembly type signature. - pub fn repr(&self) -> AtomType { - self.signifies.repr() - } -} - -/// Enumerates the sort of relationship an WebAssembly parameter to an interface function -/// parameter. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum CoreParamSignifies { - /// Core type represents the value using an AtomType - Value(AtomType), - /// Core type represents a pointer into linear memory - PointerTo, - /// Core type represents a length of a region of linear memory - LengthOf, -} - -impl CoreParamSignifies { - /// Representation of the WebAssembly parameter. - pub fn repr(&self) -> AtomType { - match self { - CoreParamSignifies::Value(a) => *a, - CoreParamSignifies::PointerTo | CoreParamSignifies::LengthOf => AtomType::I32, - } - } -} - -impl InterfaceFuncParam { - /// Gives the WebAssembly type that corresponds to passing this interface func parameter by value. - /// Not all types can be passed by value: those which cannot return None - pub fn pass_by_value(&self) -> Option { - match self.tref.type_().passed_by() { - TypePassedBy::Value(atom) => Some(CoreParamType { - signifies: CoreParamSignifies::Value(atom), - param: self.clone(), - }), - TypePassedBy::Pointer | TypePassedBy::PointerLengthPair => None, - } - } - - /// Gives the WebAssembly types that correspond to passing this interface func parameter - /// by reference. Some types are passed by reference using a single pointer, others - /// require both a pointer and length. - pub fn pass_by_reference(&self) -> Vec { - match self.tref.type_().passed_by() { - TypePassedBy::Value(_) | TypePassedBy::Pointer => vec![CoreParamType { - signifies: CoreParamSignifies::PointerTo, - param: self.clone(), - }], - TypePassedBy::PointerLengthPair => vec![ - CoreParamType { - signifies: CoreParamSignifies::PointerTo, - param: self.clone(), - }, - CoreParamType { - signifies: CoreParamSignifies::LengthOf, - param: self.clone(), - }, - ], - } - } -} - -/// Describes the WebAssembly signature of a function -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CoreFuncType { - pub args: Vec, - pub ret: Option, -} - -impl InterfaceFunc { - /// Get the WebAssembly type signature for this interface function - pub fn core_type(&self) -> CoreFuncType { - let mut results = self.results.iter(); - // The ret value is the first result (if there is one), passed - // by value. - let ret = results.next().map(|param| { - param - .pass_by_value() - .expect("validation ensures first result can be passed by value") - }); - let args = self - .params - .iter() - .flat_map(|param| { - // interface function parameters are passed by value if possible, - // and fall back on passing by reference. - param - .pass_by_value() - .map(|ptype| vec![ptype]) - .unwrap_or_else(|| param.pass_by_reference()) - }) - // Then, the remaining results are passed by reference. - .chain(results.flat_map(|param| param.pass_by_reference())) - .collect(); - CoreFuncType { args, ret } - } -} diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs index 6048f73a1..a295a6756 100644 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ b/proposals/clocks/tools/witx/src/docs/ast.rs @@ -1,5 +1,5 @@ use super::{ - md::{MdFunc, MdHeading, MdNamedType, MdNodeRef, MdSection, MdType, ToMarkdown}, + md::{MdFunc, MdHeading, MdNamedType, MdNodeRef, MdSection, ToMarkdown}, Documentation, }; use crate::{ @@ -68,11 +68,13 @@ impl ToMarkdown for Document { impl ToMarkdown for TypeRef { fn generate(&self, node: MdNodeRef) { match self { - TypeRef::Value(v) => v.generate(node.clone()), + TypeRef::Value(v) => { + v.generate(node.clone()); + node.content_ref_mut::().ty = Some(format!("`{}`", self.type_name())); + } TypeRef::Name(n) => { - node.content_ref_mut::().r#type = Some(MdType::Alias { - r#type: n.name.as_str().to_owned(), - }) + node.content_ref_mut::().ty = + Some(format!("[`{0}`](#{0})", n.name.as_str().to_owned())); } } } @@ -90,26 +92,10 @@ impl ToMarkdown for Type { Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), - Self::List(a) => { - node.content_ref_mut::().r#type = Some(MdType::List { - r#type: a.type_name().to_owned(), - }) - } - Self::Pointer(a) => { - node.content_ref_mut::().r#type = Some(MdType::Pointer { - r#type: a.type_name().to_owned(), - }) - } - Self::ConstPointer(a) => { - node.content_ref_mut::().r#type = Some(MdType::ConstPointer { - r#type: a.type_name().to_owned(), - }) - } - Self::Builtin(a) => { - node.content_ref_mut::().r#type = Some(MdType::Builtin { - repr: a.type_name().to_owned(), - }) - } + Self::List(_) => {} + Self::Pointer(_) => {} + Self::ConstPointer(_) => {} + Self::Builtin(_) => {} } } } @@ -128,21 +114,27 @@ impl ToMarkdown for RecordDatatype { } else { name.to_owned() }; + let (div, offset_desc) = if self.bitflags_repr().is_some() { + (4, "Bit") + } else { + (1, "Offset") + }; let n = node.new_child(MdNamedType::new( MdHeading::new_bullet(), id.as_str(), name, - format!("{}\nOffset: {}\n", &member.docs, &offset).as_str(), + format!("{}\n{}: {}\n", &member.docs, offset_desc, offset / div).as_str(), )); member.tref.generate(n.clone()); } - - node.content_ref_mut::().r#type = Some(MdType::Record); } } impl ToMarkdown for Variant { fn generate(&self, node: MdNodeRef) { + if self.is_bool() { + return; + } if self.cases.iter().any(|c| c.tref.is_some()) { let heading = heading_from_node(&node, 1); node.new_child(MdSection::new(heading, "Variant Layout")); @@ -184,8 +176,6 @@ impl ToMarkdown for Variant { ty.generate(n.clone()); } } - - node.content_ref_mut::().r#type = Some(MdType::Variant); } } @@ -194,7 +184,6 @@ impl ToMarkdown for HandleDatatype { // TODO this needs more work let heading = heading_from_node(&node, 1); node.new_child(MdSection::new(heading, "Supertypes")); - node.content_ref_mut::().r#type = Some(MdType::Handle); } } @@ -312,16 +301,50 @@ impl TypeRef { pub fn type_name(&self) -> String { match self { TypeRef::Name(n) => n.name.as_str().to_string(), - TypeRef::Value(ref v) => match &**v { - Type::List(a) => match &*a.type_() { + TypeRef::Value(v) => match &**v { + Type::List(a) => match &**a.type_() { Type::Builtin(BuiltinType::Char) => "string".to_string(), _ => format!("List<{}>", a.type_name()), }, Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), - Type::Record { .. } | Type::Variant { .. } | Type::Handle { .. } => { - unimplemented!("type_name of anonymous compound datatypes") + Type::Record(RecordDatatype { + kind: RecordKind::Tuple, + members, + }) => { + let mut ret = "(".to_string(); + for (i, member) in members.iter().enumerate() { + if i > 0 { + ret.push_str(", "); + } + ret.push_str(&member.tref.type_name()); + } + ret.push_str(")"); + ret + } + Type::Record { .. } => { + format!("Record") + } + Type::Handle { .. } => { + format!("Handle") + } + Type::Variant(v) => { + if let Some((ok, err)) = v.as_expected() { + let ok = match ok { + Some(ty) => ty.type_name(), + None => "()".to_string(), + }; + let err = match err { + Some(ty) => ty.type_name(), + None => "()".to_string(), + }; + format!("Result<{}, {}>", ok, err) + } else if v.is_bool() { + format!("bool") + } else { + format!("Variant") + } } }, } diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs index d3d5b756d..569b31837 100644 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ b/proposals/clocks/tools/witx/src/docs/md.rs @@ -322,7 +322,7 @@ pub(super) struct MdNamedType { pub id: String, pub name: String, pub docs: String, - pub r#type: Option, + pub ty: Option, } impl MdNamedType { @@ -332,54 +332,11 @@ impl MdNamedType { id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), docs: docs.as_ref().to_owned(), - r#type: None, + ty: None, } } } -/// Helper struct encapsulating the `TypeRef` value. -// TODO `MdType` should probably store `TypeRef` and recursively -// unwind itself into final `String` representation rather than -// being outright flattened. -#[derive(Debug)] -pub(super) enum MdType { - Record, - Variant, - List { r#type: String }, - Pointer { r#type: String }, - ConstPointer { r#type: String }, - Builtin { repr: String }, - Handle, - Alias { r#type: String }, -} - -impl fmt::Display for MdType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Record => f.write_fmt(format_args!(": Record"))?, - Self::Variant => f.write_fmt(format_args!(": Variant"))?, - Self::List { r#type } => { - if r#type == "char" { - f.write_str(": `string`")? - } else { - f.write_fmt(format_args!(": `List<{}>`", r#type))? - } - } - Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, - Self::ConstPointer { r#type } => { - f.write_fmt(format_args!(": `ConstPointer<{}>`", r#type))? - } - Self::Builtin { repr } => f.write_fmt(format_args!(": `{}`", repr))?, - Self::Handle => {} - Self::Alias { r#type } => { - f.write_fmt(format_args!(": [`{tt}`](#{tt})", tt = r#type))? - } - }; - - Ok(()) - } -} - impl MdElement for MdNamedType { fn id(&self) -> Option<&str> { Some(&self.id) @@ -411,8 +368,8 @@ impl fmt::Display for MdNamedType { name = self.name, ))?; - if let Some(tt) = &self.r#type { - f.write_fmt(format_args!("{}", tt))?; + if let Some(tt) = &self.ty { + f.write_fmt(format_args!(": {}", tt))?; } writeln!(f, "\n{}", self.docs) diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs index 2bcd1042a..6812f01ae 100644 --- a/proposals/clocks/tools/witx/src/layout.rs +++ b/proposals/clocks/tools/witx/src/layout.rs @@ -64,7 +64,10 @@ impl Layout for NamedType { impl Type { fn layout(&self, cache: &mut HashMap) -> SizeAlign { match &self { - Type::Record(s) => s.layout(cache), + Type::Record(s) => match s.bitflags_repr() { + Some(repr) => repr.mem_size_align(), + None => s.layout(cache), + }, Type::Variant(s) => s.mem_size_align(), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length @@ -122,8 +125,13 @@ impl RecordDatatype { impl Layout for RecordDatatype { fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) + match self.bitflags_repr() { + Some(repr) => repr.mem_size_align(), + None => { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } + } } } @@ -143,6 +151,18 @@ impl Layout for Variant { } } +impl Variant { + pub fn payload_offset(&self) -> usize { + let mut offset = self.tag_repr.mem_size_align().size; + for case in self.cases.iter() { + if let Some(payload) = &case.tref { + offset = offset.max(align_to(offset, payload.mem_size_align().align)); + } + } + offset + } +} + /// If the next free byte in the struct is `offs`, and the next /// element has alignment `alignment`, determine the offset at /// which to place that element. diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index 2c876aa13..f1cc7e229 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -1,7 +1,7 @@ +/// Map witx types to core (wasm standard) types +mod abi; /// Types describing a validated witx document mod ast; -/// Map witx types to core (wasm standard) types -mod coretypes; /// Render documentation mod docs; /// Interface for filesystem or mock IO @@ -23,8 +23,8 @@ mod toplevel; /// Validate declarations into ast mod validate; +pub use abi::*; pub use ast::*; -pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use layout::{Layout, RecordMemberLayout, SizeAlign}; diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs index 19d1a0303..33cf745ff 100644 --- a/proposals/clocks/tools/witx/src/parser.rs +++ b/proposals/clocks/tools/witx/src/parser.rs @@ -1,5 +1,4 @@ use crate::BuiltinType; -use wast::lexer::Comment; use wast::parser::{Parse, Parser, Peek, Result}; ///! Parser turns s-expressions into unvalidated syntax constructs. @@ -18,7 +17,6 @@ use wast::parser::{Parse, Parser, Peek, Result}; mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; - wast::custom_keyword!(bitflags); wast::custom_keyword!(case); wast::custom_keyword!(char8); wast::custom_keyword!(char); @@ -27,6 +25,8 @@ mod kw { wast::custom_keyword!(f64); wast::custom_keyword!(field); wast::custom_keyword!(empty); + wast::custom_keyword!(error); + wast::custom_keyword!(expected); wast::custom_keyword!(flags); wast::custom_keyword!(handle); wast::custom_keyword!(list); @@ -37,12 +37,14 @@ mod kw { wast::custom_keyword!(r#enum = "enum"); wast::custom_keyword!(r#union = "union"); wast::custom_keyword!(r#use = "use"); + wast::custom_keyword!(repr); wast::custom_keyword!(s16); wast::custom_keyword!(s32); wast::custom_keyword!(s64); wast::custom_keyword!(s8); wast::custom_keyword!(string); wast::custom_keyword!(tag); + wast::custom_keyword!(tuple); wast::custom_keyword!(typename); wast::custom_keyword!(u16); wast::custom_keyword!(u32); @@ -50,6 +52,7 @@ mod kw { wast::custom_keyword!(u8); wast::custom_keyword!(usize); wast::custom_keyword!(variant); + wast::custom_keyword!(bool_ = "bool"); } mod annotation { @@ -136,9 +139,10 @@ impl<'a> Parse<'a> for CommentSyntax<'a> { None => break, }; cursor = c; - comments.push(match comment { - Comment::Block(s) => &s[2..s.len() - 2], - Comment::Line(s) => &s[2..], + comments.push(if comment.starts_with(";;") { + &comment[2..] + } else { + &comment[2..comment.len() - 2] }); } Ok((comments, cursor)) @@ -277,6 +281,8 @@ impl<'a> Parse<'a> for TypenameSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub enum TypedefSyntax<'a> { Enum(EnumSyntax<'a>), + Tuple(TupleSyntax<'a>), + Expected(ExpectedSyntax<'a>), Flags(FlagsSyntax<'a>), Record(RecordSyntax<'a>), Union(UnionSyntax<'a>), @@ -288,6 +294,7 @@ pub enum TypedefSyntax<'a> { Builtin(BuiltinType), Ident(wast::Id<'a>), String, + Bool, } impl<'a> Parse<'a> for TypedefSyntax<'a> { @@ -300,11 +307,18 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { } else if l.peek::() { parser.parse::()?; Ok(TypedefSyntax::String) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::Bool) } else if l.peek::() { parser.parens(|parser| { let mut l = parser.lookahead1(); if l.peek::() { Ok(TypedefSyntax::Enum(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Tuple(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Expected(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Flags(parser.parse()?)) } else if l.peek::() { @@ -377,6 +391,48 @@ impl<'a> Parse<'a> for EnumSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TupleSyntax<'a> { + pub types: Vec>, +} + +impl<'a> Parse<'a> for TupleSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let mut types = Vec::new(); + while !parser.is_empty() { + types.push(parser.parse()?); + } + Ok(TupleSyntax { types }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ExpectedSyntax<'a> { + pub ok: Option>>, + pub err: Option>>, +} + +impl<'a> Parse<'a> for ExpectedSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let ok = if !parser.is_empty() && !parser.peek2::() { + Some(Box::new(parser.parse()?)) + } else { + None + }; + let err = parser.parens(|p| { + p.parse::()?; + Ok(if p.is_empty() { + None + } else { + Some(Box::new(p.parse()?)) + }) + })?; + Ok(ExpectedSyntax { ok, err }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConstSyntax<'a> { pub ty: wast::Id<'a>, @@ -397,17 +453,17 @@ impl<'a> Parse<'a> for ConstSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsSyntax<'a> { - pub bitflags_repr: Option, + pub repr: Option, pub flags: Vec>>, } impl<'a> Parse<'a> for FlagsSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let bitflags_repr = if parser.peek2::() { + let repr = if parser.peek2::() { Some(parser.parens(|p| { p.parse::()?; - p.parse::()?; + p.parse::()?; p.parse() })?) } else { @@ -417,10 +473,7 @@ impl<'a> Parse<'a> for FlagsSyntax<'a> { while !parser.is_empty() { flags.push(parser.parse()?); } - Ok(FlagsSyntax { - bitflags_repr, - flags, - }) + Ok(FlagsSyntax { repr, flags }) } } diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs index ad551ae9b..a740e282c 100644 --- a/proposals/clocks/tools/witx/src/render.rs +++ b/proposals/clocks/tools/witx/src/render.rs @@ -143,29 +143,56 @@ impl Type { impl RecordDatatype { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("record")]; - let members = self - .members - .iter() - .map(|m| { - SExpr::docs( - &m.docs, - SExpr::Vec(vec![ - SExpr::word("field"), - m.name.to_sexpr(), - m.tref.to_sexpr(), - ]), - ) - }) - .collect::>(); - SExpr::Vec([header, members].concat()) + match self.kind { + RecordKind::Tuple => { + let mut tuple = vec![SExpr::word("tuple")]; + for m in self.members.iter() { + tuple.push(SExpr::docs(&m.docs, m.tref.to_sexpr())); + } + SExpr::Vec(tuple) + } + RecordKind::Bitflags(repr) => { + let mut flags = vec![SExpr::word("flags")]; + flags.push(SExpr::Vec(vec![ + SExpr::word("@witx"), + SExpr::word("repr"), + repr.to_sexpr(), + ])); + flags.extend( + self.members + .iter() + .map(|m| SExpr::docs(&m.docs, m.name.to_sexpr())), + ); + SExpr::Vec(flags) + } + RecordKind::Other => { + let header = vec![SExpr::word("record")]; + let members = self + .members + .iter() + .map(|m| { + SExpr::docs( + &m.docs, + SExpr::Vec(vec![ + SExpr::word("field"), + m.name.to_sexpr(), + m.tref.to_sexpr(), + ]), + ) + }) + .collect::>(); + SExpr::Vec([header, members].concat()) + } + } } } impl Variant { pub fn to_sexpr(&self) -> SExpr { let mut list = Vec::new(); - if self.cases.iter().all(|c| c.tref.is_none()) { + if self.is_bool() { + return SExpr::word("bool"); + } else if self.is_enum() { list.push(SExpr::word("enum")); list.push(SExpr::Vec(vec![ SExpr::word("@witx"), diff --git a/proposals/clocks/tools/witx/src/toplevel.rs b/proposals/clocks/tools/witx/src/toplevel.rs index 83e940c7c..257e6edd8 100644 --- a/proposals/clocks/tools/witx/src/toplevel.rs +++ b/proposals/clocks/tools/witx/src/toplevel.rs @@ -107,11 +107,11 @@ mod test { .expect("parse"); let b_float = doc.typename(&Id::new("b_float")).unwrap(); - assert_eq!(*b_float.type_(), Type::Builtin(BuiltinType::F64)); + assert_eq!(**b_float.type_(), Type::Builtin(BuiltinType::F64)); let c_int = doc.typename(&Id::new("c_int")).unwrap(); assert_eq!( - *c_int.type_(), + **c_int.type_(), Type::Builtin(BuiltinType::U32 { lang_ptr_size: false }) @@ -133,7 +133,7 @@ mod test { let d_char = doc.typename(&Id::new("d_char")).unwrap(); assert_eq!( - *d_char.type_(), + **d_char.type_(), Type::Builtin(BuiltinType::U8 { lang_c_char: false }) ); } diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs index ade02282b..cf4d0ad7f 100644 --- a/proposals/clocks/tools/witx/src/validate.rs +++ b/proposals/clocks/tools/witx/src/validate.rs @@ -1,14 +1,14 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ - CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, - ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, - VariantSyntax, + CommentSyntax, DeclSyntax, Documented, EnumSyntax, ExpectedSyntax, FlagsSyntax, + HandleSyntax, ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TupleSyntax, TypedefSyntax, + UnionSyntax, VariantSyntax, }, - BuiltinType, Case, Constant, Definition, Document, Entry, HandleDatatype, Id, IntRepr, - InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, - ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, - RecordMember, Type, TypePassedBy, TypeRef, Variant, + Abi, BuiltinType, Case, Constant, Definition, Document, Entry, HandleDatatype, Id, IntRepr, + InterfaceFunc, InterfaceFuncParam, Location, Module, ModuleDefinition, ModuleEntry, + ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordKind, RecordMember, Type, + TypeRef, Variant, }; use std::collections::{HashMap, HashSet}; use std::path::Path; @@ -39,8 +39,8 @@ pub enum ValidationError { repr: BuiltinType, location: Location, }, - #[error("First result type must be pass-by-value")] - InvalidFirstResultType { location: Location }, + #[error("ABI error: {reason}")] + Abi { reason: String, location: Location }, #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] AnonymousRecord { location: Location }, #[error("Union expected {expected} variants, found {found}")] @@ -67,7 +67,7 @@ impl ValidationError { | WrongKindName { location, .. } | Recursive { location, .. } | InvalidRepr { location, .. } - | InvalidFirstResultType { location, .. } + | Abi { location, .. } | AnonymousRecord { location, .. } | UnionSizeMismatch { location, .. } | InvalidUnionField { location, .. } @@ -131,6 +131,7 @@ pub struct DocValidation { scope: IdentValidation, entries: HashMap, constant_scopes: HashMap, + bool_ty: TypeRef, } pub struct DocValidationScope<'a> { @@ -145,6 +146,21 @@ impl DocValidation { scope: IdentValidation::new(), entries: HashMap::new(), constant_scopes: HashMap::new(), + bool_ty: TypeRef::Value(Rc::new(Type::Variant(Variant { + tag_repr: IntRepr::U32, + cases: vec![ + Case { + name: Id::new("false"), + tref: None, + docs: String::new(), + }, + Case { + name: Id::new("true"), + tref: None, + docs: String::new(), + }, + ], + }))), } } @@ -203,24 +219,6 @@ impl DocValidationScope<'_> { .entries .insert(name.clone(), Entry::Typename(Rc::downgrade(&rc_datatype))); definitions.push(Definition::Typename(rc_datatype)); - - if let TypedefSyntax::Flags(syntax) = &decl.def { - if syntax.bitflags_repr.is_some() { - let mut flags_scope = IdentValidation::new(); - let ty = name; - for (i, flag) in syntax.flags.iter().enumerate() { - let name = flags_scope - .introduce(flag.item.name(), self.location(flag.item.span()))?; - let docs = flag.comments.docs(); - definitions.push(Definition::Constant(Constant { - ty: ty.clone(), - name, - value: 1 << i, - docs, - })); - } - } - } } DeclSyntax::Module(syntax) => { @@ -304,7 +302,11 @@ impl DocValidationScope<'_> { } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), - TypedefSyntax::Flags(syntax) => self.validate_flags(&syntax, span)?, + TypedefSyntax::Tuple(syntax) => Type::Record(self.validate_tuple(&syntax, span)?), + TypedefSyntax::Expected(syntax) => { + Type::Variant(self.validate_expected(&syntax, span)?) + } + TypedefSyntax::Flags(syntax) => Type::Record(self.validate_flags(&syntax, span)?), TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Variant(self.validate_union(&syntax, span)?), TypedefSyntax::Variant(syntax) => { @@ -324,6 +326,7 @@ impl DocValidationScope<'_> { TypedefSyntax::String => { Type::List(TypeRef::Value(Rc::new(Type::Builtin(BuiltinType::Char)))) } + TypedefSyntax::Bool => return Ok(self.doc.bool_ty.clone()), TypedefSyntax::Ident { .. } => unreachable!(), }))), } @@ -356,17 +359,83 @@ impl DocValidationScope<'_> { Ok(Variant { tag_repr, cases }) } + fn validate_tuple( + &self, + syntax: &TupleSyntax, + span: wast::Span, + ) -> Result { + let members = syntax + .types + .iter() + .enumerate() + .map(|(i, ty)| { + Ok(RecordMember { + name: Id::new(i.to_string()), + tref: self.validate_datatype(ty, false, span)?, + docs: String::new(), + }) + }) + .collect::, _>>()?; + + Ok(RecordDatatype { + kind: RecordKind::Tuple, + members, + }) + } + + fn validate_expected( + &self, + syntax: &ExpectedSyntax, + span: wast::Span, + ) -> Result { + let ok_ty = match &syntax.ok { + Some(ok) => Some(self.validate_datatype(ok, false, span)?), + None => None, + }; + let err_ty = match &syntax.err { + Some(err) => Some(self.validate_datatype(err, false, span)?), + None => None, + }; + Ok(Variant { + tag_repr: IntRepr::U32, + cases: vec![ + Case { + name: Id::new("ok"), + tref: ok_ty, + docs: String::new(), + }, + Case { + name: Id::new("err"), + tref: err_ty, + docs: String::new(), + }, + ], + }) + } + fn validate_flags( &self, syntax: &FlagsSyntax, span: wast::Span, - ) -> Result { - Ok(match &syntax.bitflags_repr { - Some(repr) => Type::Builtin(self.validate_int_repr(repr, span)?.to_builtin()), - None => { - // TODO: auto-translate to a struct-of-bool-fields - unimplemented!(); - } + ) -> Result { + let repr = match syntax.repr { + Some(ty) => self.validate_int_repr(&ty, span)?, + None => IntRepr::U32, + }; + let mut flags_scope = IdentValidation::new(); + let mut members = Vec::new(); + for flag in syntax.flags.iter() { + let name = flags_scope.introduce(flag.item.name(), self.location(flag.item.span()))?; + let docs = flag.comments.docs(); + members.push(RecordMember { + name, + docs, + tref: self.doc.bool_ty.clone(), + }); + } + Ok(RecordDatatype { + kind: RecordKind::Bitflags(repr), + members, }) } @@ -388,7 +457,10 @@ impl DocValidationScope<'_> { }) .collect::, _>>()?; - Ok(RecordDatatype { members }) + Ok(RecordDatatype { + kind: RecordKind::Other, + members, + }) } fn validate_union( @@ -497,7 +569,7 @@ impl DocValidationScope<'_> { Some(tag) => self.validate_datatype(tag, false, span)?, None => return Ok((IntRepr::U32, None)), }; - match &*ty.type_() { + match &**ty.type_() { Type::Variant(e) => { let mut names = Vec::new(); for c in e.cases.iter() { @@ -594,8 +666,7 @@ impl<'a> ModuleValidation<'a> { let params = syntax .params .iter() - .enumerate() - .map(|(ix, f)| { + .map(|f| { Ok(InterfaceFuncParam { name: argnames.introduce( f.item.name.name(), @@ -606,7 +677,6 @@ impl<'a> ModuleValidation<'a> { false, f.item.name.span(), )?, - position: InterfaceFuncParamPosition::Param(ix), docs: f.comments.docs(), }) }) @@ -614,33 +684,29 @@ impl<'a> ModuleValidation<'a> { let results = syntax .results .iter() - .enumerate() - .map(|(ix, f)| { + .map(|f| { let tref = self.doc .validate_datatype(&f.item.type_, false, f.item.name.span())?; - if ix == 0 { - match tref.type_().passed_by() { - TypePassedBy::Value(_) => {} - _ => Err(ValidationError::InvalidFirstResultType { - location: self.doc.location(f.item.name.span()), - })?, - } - } Ok(InterfaceFuncParam { name: argnames.introduce( f.item.name.name(), self.doc.location(f.item.name.span()), )?, tref, - position: InterfaceFuncParamPosition::Result(ix), docs: f.comments.docs(), }) }) .collect::, _>>()?; let noreturn = syntax.noreturn; - + let abi = Abi::Preview1; + abi.validate(¶ms, &results) + .map_err(|reason| ValidationError::Abi { + reason, + location: self.doc.location(syntax.export_loc), + })?; let rc_func = Rc::new(InterfaceFunc { + abi, name: name.clone(), params, results, diff --git a/proposals/clocks/tools/witx/tests/witxt.rs b/proposals/clocks/tools/witx/tests/witxt.rs index 1056947a3..7c002fe1b 100644 --- a/proposals/clocks/tools/witx/tests/witxt.rs +++ b/proposals/clocks/tools/witx/tests/witxt.rs @@ -14,7 +14,7 @@ use std::path::{Path, PathBuf}; use std::str; use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use wast::parser::{self, Parse, ParseBuffer, Parser}; -use witx::{Documentation, Representable}; +use witx::{Documentation, Instruction, Representable, WasmType}; fn main() { let tests = find_tests(); @@ -192,6 +192,36 @@ impl WitxtRunner<'_> { } } } + WitxtDirective::AssertAbi { + witx, + wasm, + interface, + wasm_signature: (wasm_params, wasm_results), + .. + } => { + let doc = witx.document(contents, test)?; + let module = doc.modules().next().ok_or_else(|| anyhow!("no modules"))?; + let func = module.funcs().next().ok_or_else(|| anyhow!("no funcs"))?; + + let (params, results) = func.wasm_signature(); + if params != wasm_params { + bail!("expected params {:?}, found {:?}", wasm_params, params); + } + if results != wasm_results { + bail!("expected results {:?}, found {:?}", wasm_results, results); + } + + let mut check = AbiBindgen { + abi: wasm.instrs.iter(), + err: None, + contents, + }; + func.call_wasm(&module.name, &mut check); + check.check()?; + check.abi = interface.instrs.iter(); + func.call_interface(&module.name, &mut check); + check.check()?; + } } Ok(()) } @@ -249,14 +279,147 @@ impl WitxtRunner<'_> { } } +struct AbiBindgen<'a> { + abi: std::slice::Iter<'a, (wast::Span, &'a str)>, + err: Option, + contents: &'a str, +} + +impl AbiBindgen<'_> { + fn check(&mut self) -> Result<()> { + match self.err.take() { + None => Ok(()), + Some(e) => Err(e), + } + } + + fn assert(&mut self, name: &str) { + if self.err.is_some() { + return; + } + match self.abi.next() { + Some((_, s)) if *s == name => {} + Some((span, s)) => { + let (line, col) = span.linecol_in(self.contents); + self.err = Some(anyhow!( + "line {}:{} - expected `{}` found `{}`", + line + 1, + col + 1, + name, + s, + )); + } + None => { + self.err = Some(anyhow!( + "extra instruction `{}` found when none was expected", + name + )); + } + } + } +} + +impl witx::Bindgen for AbiBindgen<'_> { + type Operand = (); + fn emit( + &mut self, + inst: &Instruction<'_>, + _operands: &mut Vec, + results: &mut Vec, + ) { + use witx::Instruction::*; + match inst { + GetArg { nth } => self.assert(&format!("get-arg{}", nth)), + AddrOf => self.assert("addr-of"), + I32FromChar => self.assert("i32.from_char"), + I64FromU64 => self.assert("i64.from_u64"), + I64FromS64 => self.assert("i64.from_s64"), + I32FromU32 => self.assert("i32.from_u32"), + I32FromS32 => self.assert("i32.from_s32"), + I32FromUsize => self.assert("i32.from_usize"), + I32FromU16 => self.assert("i32.from_u16"), + I32FromS16 => self.assert("i32.from_s16"), + I32FromU8 => self.assert("i32.from_u8"), + I32FromS8 => self.assert("i32.from_s8"), + I32FromChar8 => self.assert("i32.from_char8"), + I32FromPointer => self.assert("i32.from_pointer"), + I32FromConstPointer => self.assert("i32.from_const_pointer"), + I32FromHandle { .. } => self.assert("i32.from_handle"), + ListPointerLength => self.assert("list.pointer_length"), + ListFromPointerLength { .. } => self.assert("list.from_pointer_length"), + F32FromIf32 => self.assert("f32.from_if32"), + F64FromIf64 => self.assert("f64.from_if64"), + CallWasm { .. } => self.assert("call.wasm"), + CallInterface { .. } => self.assert("call.interface"), + S8FromI32 => self.assert("s8.from_i32"), + U8FromI32 => self.assert("u8.from_i32"), + S16FromI32 => self.assert("s16.from_i32"), + U16FromI32 => self.assert("u16.from_i32"), + S32FromI32 => self.assert("s32.from_i32"), + U32FromI32 => self.assert("u32.from_i32"), + S64FromI64 => self.assert("s64.from_i64"), + U64FromI64 => self.assert("u64.from_i64"), + CharFromI32 => self.assert("char.from_i32"), + Char8FromI32 => self.assert("char8.from_i32"), + UsizeFromI32 => self.assert("usize.from_i32"), + If32FromF32 => self.assert("if32.from_f32"), + If64FromF64 => self.assert("if64.from_f64"), + HandleFromI32 { .. } => self.assert("handle.from_i32"), + PointerFromI32 { .. } => self.assert("pointer.from_i32"), + ConstPointerFromI32 { .. } => self.assert("const_pointer.from_i32"), + ReturnPointerGet { n } => self.assert(&format!("return_pointer.get{}", n)), + ResultLift => self.assert("result.lift"), + ResultLower { .. } => self.assert("result.lower"), + EnumLift { .. } => self.assert("enum.lift"), + EnumLower { .. } => self.assert("enum.lower"), + TupleLift { .. } => self.assert("tuple.lift"), + TupleLower { .. } => self.assert("tuple.lower"), + ReuseReturn => self.assert("reuse_return"), + Load { .. } => self.assert("load"), + Store { .. } => self.assert("store"), + Return { .. } => self.assert("return"), + VariantPayload => self.assert("variant-payload"), + I32FromBitflags { .. } => self.assert("i32.from_bitflags"), + BitflagsFromI32 { .. } => self.assert("bitflags.from_i32"), + I64FromBitflags { .. } => self.assert("i64.from_bitflags"), + BitflagsFromI64 { .. } => self.assert("bitflags.from_i64"), + } + for _ in 0..inst.results_len() { + results.push(()); + } + } + + fn allocate_space(&mut self, _: usize, _: &witx::NamedType) { + self.assert("allocate-space"); + } + + fn push_block(&mut self) { + self.assert("block.push"); + } + + fn finish_block(&mut self, _operand: Option) { + self.assert("block.finish"); + } +} + mod kw { wast::custom_keyword!(assert_invalid); wast::custom_keyword!(assert_representable); + wast::custom_keyword!(assert_abi); wast::custom_keyword!(witx); wast::custom_keyword!(eq); wast::custom_keyword!(noteq); wast::custom_keyword!(load); wast::custom_keyword!(superset); + wast::custom_keyword!(call_wasm); + wast::custom_keyword!(call_interface); + wast::custom_keyword!(param); + wast::custom_keyword!(result); + wast::custom_keyword!(wasm); + wast::custom_keyword!(i32); + wast::custom_keyword!(i64); + wast::custom_keyword!(f32); + wast::custom_keyword!(f64); } struct Witxt<'a> { @@ -286,6 +449,13 @@ enum WitxtDirective<'a> { t1: (wast::Id<'a>, &'a str), t2: (wast::Id<'a>, &'a str), }, + AssertAbi { + span: wast::Span, + witx: Witx<'a>, + wasm_signature: (Vec, Vec), + wasm: Abi<'a>, + interface: Abi<'a>, + }, } impl WitxtDirective<'_> { @@ -293,6 +463,7 @@ impl WitxtDirective<'_> { match self { WitxtDirective::Witx(w) => w.span, WitxtDirective::AssertInvalid { span, .. } + | WitxtDirective::AssertAbi { span, .. } | WitxtDirective::AssertRepresentable { span, .. } => *span, } } @@ -318,12 +489,69 @@ impl<'a> Parse<'a> for WitxtDirective<'a> { t1: (parser.parse()?, parser.parse()?), t2: (parser.parse()?, parser.parse()?), }) + } else if l.peek::() { + let span = parser.parse::()?.0; + Ok(WitxtDirective::AssertAbi { + span, + witx: parser.parens(|p| p.parse())?, + wasm_signature: parser.parens(|p| { + p.parse::()?; + let mut params = Vec::new(); + let mut results = Vec::new(); + if p.peek2::() { + p.parens(|p| { + p.parse::()?; + while !p.is_empty() { + params.push(parse_wasmtype(p)?); + } + Ok(()) + })?; + } + if p.peek2::() { + p.parens(|p| { + p.parse::()?; + while !p.is_empty() { + results.push(parse_wasmtype(p)?); + } + Ok(()) + })?; + } + Ok((params, results)) + })?, + wasm: parser.parens(|p| { + p.parse::()?; + p.parse() + })?, + interface: parser.parens(|p| { + p.parse::()?; + p.parse() + })?, + }) } else { Err(l.error()) } } } +fn parse_wasmtype(p: Parser<'_>) -> parser::Result { + let mut l = p.lookahead1(); + if l.peek::() { + p.parse::()?; + Ok(WasmType::I32) + } else if l.peek::() { + p.parse::()?; + Ok(WasmType::I64) + } else if l.peek::() { + p.parse::()?; + Ok(WasmType::F32) + } else if l.peek::() { + p.parse::()?; + Ok(WasmType::F64) + } else { + Err(l.error()) + } +} + struct Witx<'a> { span: wast::Span, id: Option>, @@ -407,3 +635,22 @@ impl<'a> Parse<'a> for RepEquality { } } } + +struct Abi<'a> { + instrs: Vec<(wast::Span, &'a str)>, +} + +impl<'a> Parse<'a> for Abi<'a> { + fn parse(parser: Parser<'a>) -> parser::Result { + let mut instrs = Vec::new(); + while !parser.is_empty() { + instrs.push(parser.step(|cursor| { + let (kw, next) = cursor + .keyword() + .ok_or_else(|| cursor.error("expected keyword"))?; + Ok(((cursor.cur_span(), kw), next)) + })?); + } + Ok(Abi { instrs }) + } +} diff --git a/proposals/clocks/tools/witx/tests/witxt/abi.witxt b/proposals/clocks/tools/witx/tests/witxt/abi.witxt new file mode 100644 index 000000000..ccdad7bf4 --- /dev/null +++ b/proposals/clocks/tools/witx/tests/witxt/abi.witxt @@ -0,0 +1,490 @@ +(assert_abi + (witx (module $x (@interface func (export "f")))) + (wasm) + (call_wasm call.wasm return) + (call_interface call.interface return) +) + +;; scalar arguments +(assert_abi + (witx (module $x (@interface func (export "f") (param $p u8)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_u8 call.wasm return) + (call_interface get-arg0 u8.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p s8)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_s8 call.wasm return) + (call_interface get-arg0 s8.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p u16)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_u16 call.wasm return) + (call_interface get-arg0 u16.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p s16)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_s16 call.wasm return) + (call_interface get-arg0 s16.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p u32)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_u32 call.wasm return) + (call_interface get-arg0 u32.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p s32)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_s32 call.wasm return) + (call_interface get-arg0 s32.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p u64)))) + (wasm (param i64)) + (call_wasm get-arg0 i64.from_u64 call.wasm return) + (call_interface get-arg0 u64.from_i64 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p s64)))) + (wasm (param i64)) + (call_wasm get-arg0 i64.from_s64 call.wasm return) + (call_interface get-arg0 s64.from_i64 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p f32)))) + (wasm (param f32)) + (call_wasm get-arg0 f32.from_if32 call.wasm return) + (call_interface get-arg0 if32.from_f32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p f64)))) + (wasm (param f64)) + (call_wasm get-arg0 f64.from_if64 call.wasm return) + (call_interface get-arg0 if64.from_f64 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p (@witx usize))))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_usize call.wasm return) + (call_interface get-arg0 usize.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p (@witx char8))))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_char8 call.wasm return) + (call_interface get-arg0 char8.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p char)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_char call.wasm return) + (call_interface get-arg0 char.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p (@witx pointer u8))))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_pointer call.wasm return) + (call_interface get-arg0 pointer.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p (@witx const_pointer u8))))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_const_pointer call.wasm return) + (call_interface get-arg0 const_pointer.from_i32 call.interface return) +) + +;; flags parameter +(assert_abi + (witx + (typename $a (flags $x $y)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_bitflags call.wasm return) + (call_interface get-arg0 bitflags.from_i32 call.interface return) +) +(assert_abi + (witx + (typename $a (flags (@witx repr u64) $x $y)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i64)) + (call_wasm get-arg0 i64.from_bitflags call.wasm return) + (call_interface get-arg0 bitflags.from_i64 call.interface return) +) + +;; struct parameter +(assert_abi + (witx + (typename $a (record (field $x u8))) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 addr-of call.wasm return) + (call_interface get-arg0 load call.interface return) +) + +;; handle parameter +(assert_abi + (witx + (typename $a (handle)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_handle call.wasm return) + (call_interface get-arg0 handle.from_i32 call.interface return) +) + +;; list parameter +(assert_abi + (witx + (module $x (@interface func (export "f") (param $p (list u8)))) + ) + (wasm (param i32 i32)) + (call_wasm get-arg0 list.pointer_length call.wasm return) + (call_interface get-arg0 get-arg1 list.from_pointer_length call.interface return) +) + +;; variant parameter -- some not allowed at this time +(assert_abi + (witx + (typename $a (enum $b)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 enum.lower call.wasm return) + (call_interface get-arg0 enum.lift call.interface return) +) +(assert_abi + (witx + (typename $a (union f32)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 addr-of call.wasm return) + (call_interface get-arg0 load call.interface return) +) + +;; scalar returns +(assert_abi + (witx (module $x (@interface func (export "f") (result $p u8)))) + (wasm (result i32)) + (call_wasm call.wasm u8.from_i32 return) + (call_interface call.interface i32.from_u8 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p s8)))) + (wasm (result i32)) + (call_wasm call.wasm s8.from_i32 return) + (call_interface call.interface i32.from_s8 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p u16)))) + (wasm (result i32)) + (call_wasm call.wasm u16.from_i32 return) + (call_interface call.interface i32.from_u16 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p s16)))) + (wasm (result i32)) + (call_wasm call.wasm s16.from_i32 return) + (call_interface call.interface i32.from_s16 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p u32)))) + (wasm (result i32)) + (call_wasm call.wasm u32.from_i32 return) + (call_interface call.interface i32.from_u32 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p s32)))) + (wasm (result i32)) + (call_wasm call.wasm s32.from_i32 return) + (call_interface call.interface i32.from_s32 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p u64)))) + (wasm (result i64)) + (call_wasm call.wasm u64.from_i64 return) + (call_interface call.interface i64.from_u64 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p s64)))) + (wasm (result i64)) + (call_wasm call.wasm s64.from_i64 return) + (call_interface call.interface i64.from_s64 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p f32)))) + (wasm (result f32)) + (call_wasm call.wasm if32.from_f32 return) + (call_interface call.interface f32.from_if32 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p f64)))) + (wasm (result f64)) + (call_wasm call.wasm if64.from_f64 return) + (call_interface call.interface f64.from_if64 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p (@witx usize))))) + (wasm (result i32)) + (call_wasm call.wasm usize.from_i32 return) + (call_interface call.interface i32.from_usize return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p (@witx char8))))) + (wasm (result i32)) + (call_wasm call.wasm char8.from_i32 return) + (call_interface call.interface i32.from_char8 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p char)))) + (wasm (result i32)) + (call_wasm call.wasm char.from_i32 return) + (call_interface call.interface i32.from_char return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p (@witx pointer u8))))) + (wasm (result i32)) + (call_wasm call.wasm pointer.from_i32 return) + (call_interface call.interface i32.from_pointer return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p (@witx const_pointer u8))))) + (wasm (result i32)) + (call_wasm call.wasm const_pointer.from_i32 return) + (call_interface call.interface i32.from_const_pointer return) +) + +;; flags return +(assert_abi + (witx + (typename $a (flags $x $y)) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (result i32)) + (call_wasm call.wasm bitflags.from_i32 return) + (call_interface call.interface i32.from_bitflags return) +) +(assert_abi + (witx + (typename $a (flags (@witx repr u64) $x $y)) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (result i64)) + (call_wasm call.wasm bitflags.from_i64 return) + (call_interface call.interface i64.from_bitflags return) +) + +;; handle return +(assert_abi + (witx + (typename $a (handle)) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (result i32)) + (call_wasm call.wasm handle.from_i32 return) + (call_interface call.interface i32.from_handle return) +) + +;; struct return -- not supported +(assert_invalid + (witx + (typename $a (record (field $x u8))) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: invalid return type" +) + +;; list return -- not supported +(assert_invalid + (witx + (module $x (@interface func (export "f") (result $p (list u8)))) + ) + "ABI error: invalid return type" +) + +;; variant return -- only some allowed +(assert_invalid + (witx + (typename $a (enum $b)) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: invalid return type" +) +(assert_invalid + (witx + (typename $a (union s32 f32)) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: invalid return type" +) +(assert_invalid + (witx + (typename $a (expected (error f32))) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: only named types are allowed in results" +) +(assert_invalid + (witx + (typename $errno (enum $success $bad)) + (typename $a (expected f32 (error $errno))) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: only named types are allowed in results" +) + +;; Result<(), $errno> +(assert_abi + (witx + (typename $errno (enum $success $bad)) + (typename $a (expected (error $errno))) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (result i32)) + + (call_wasm + call.wasm + ;; ok block, nothing happens + block.push + block.finish + ;; err block, we lift the return value as the num + block.push + reuse_return + enum.lift + block.finish + ;; consumes 2 blocks and uses the return value of the call to discriminate + result.lift + return) + + (call_interface + call.interface + + ;; ok block, nothing happens + block.push + block.finish + + ;; err block, lift the enum + block.push + variant-payload + enum.lower + block.finish + + ;; consume the 2 blocks and lower based on the call + result.lower + return) +) + +;; Result<$ty, $errno> +(assert_abi + (witx + (typename $errno (enum $success $bad)) + (typename $size u32) + (typename $a (expected $size (error $errno))) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (param i32) (result i32)) + + (call_wasm + ;; make space for the return value and push its pointer + allocate-space + return_pointer.get0 + + call.wasm + + ;; ok block, load the return pointer and have it be the result for the `Ok` + block.push + return_pointer.get0 + load + block.finish + + block.push + reuse_return + enum.lift + block.finish + + result.lift + return) + + (call_interface + call.interface + + ;; store the successful result at the first return pointer (the first param) + block.push + variant-payload + get-arg0 + store + block.finish + + block.push + variant-payload + enum.lower + block.finish + + result.lower + return) +) + +;; Result<($a, $b), $errno> +(assert_abi + (witx + (typename $errno (enum $success $bad)) + (typename $size u32) + (typename $other (record (field $a $size))) + (module $x (@interface func (export "f") + (result $p (expected (tuple $size $other) (error $errno))))) + ) + (wasm (param i32 i32) (result i32)) + + (call_wasm + allocate-space + return_pointer.get0 + allocate-space + return_pointer.get1 + + call.wasm + + block.push + return_pointer.get0 + load + return_pointer.get1 + load + tuple.lift + block.finish + + block.push + reuse_return + enum.lift + block.finish + + result.lift + return) + + (call_interface + call.interface + + ;; note the reverse order since we're consuming the results of lowering the + ;; tuple + block.push + variant-payload + tuple.lower + get-arg1 + store + get-arg0 + store + block.finish + + block.push + variant-payload + enum.lower + block.finish + + result.lower + return) +) diff --git a/proposals/clocks/tools/witx/tests/witxt/representation.witxt b/proposals/clocks/tools/witx/tests/witxt/representation.witxt index 37d20a70a..53f71f196 100644 --- a/proposals/clocks/tools/witx/tests/witxt/representation.witxt +++ b/proposals/clocks/tools/witx/tests/witxt/representation.witxt @@ -1,8 +1,8 @@ ;; type names don't matter (witx $a - (typename $a (flags (@witx bitflags u8) $b $c))) + (typename $a (flags (@witx repr u8) $b $c))) (witx $b - (typename $b (flags (@witx bitflags u8) $b $c))) + (typename $b (flags (@witx repr u8) $b $c))) (assert_representable eq $a "a" $b "b") (assert_representable eq $b "b" $a "a") diff --git a/proposals/clocks/tools/witx/tests/witxt/shorthand.witxt b/proposals/clocks/tools/witx/tests/witxt/shorthand.witxt new file mode 100644 index 000000000..960615f3c --- /dev/null +++ b/proposals/clocks/tools/witx/tests/witxt/shorthand.witxt @@ -0,0 +1,59 @@ +(witx $a + (typename $a bool)) +(witx $b + (typename $a (variant (case $false) (case $true)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (expected (error)))) +(witx $b + (typename $a (variant (case $ok) (case $err)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (expected (error u32)))) +(witx $b + (typename $a (variant (case $ok) (case $err u32)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (expected u32 (error)))) +(witx $b + (typename $a (variant (case $ok u32) (case $err)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (expected u32 (error u64)))) +(witx $b + (typename $a (variant (case $ok u32) (case $err u64)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (flags $a $b))) +(witx $b + (typename $a (record (field $a bool) (field $b bool)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (enum $a $b))) +(witx $b + (typename $a (variant (case $a) (case $b)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a string)) +(witx $b + (typename $a (list char))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (tuple u32 u64))) +(witx $b + (typename $a (record (field $0 u32) (field $1 u64)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (union u32 u64))) +(witx $b + (typename $a (variant (case $0 u32) (case $1 u64)))) +(assert_representable eq $a "a" $b "a") From 8027aeab35cee5db63a8ef39de95d78899bb5cff Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 18 Feb 2021 11:39:17 -0600 Subject: [PATCH 0869/1772] Take another step towards interface types (#395) * Take another step towards interface types This commit is another large refactoring on the tail of #391 which is intended to help march one step closer to using pure interface types for specifying WASI and using `*.witx` files. Contained here is a large amount of refactoring of the `*.witx` files, the internals of the `witx` crate, and how code generators are supposed to work. At the `*.witx` level, some notable changes have been made: * All functions returning results now return `(expected ok? (error $errno))`. This helps signify that the intention of all functions is that they return a packaged value which is either a successful result or the erroneous error code on failure. ABI-wise nothing has changed, but this is intended to model more closely what the interface-types API of this would be. * The `flags` type in `*.witx` now desugars as a struct-of-bools rather than simply an `int`. This doesn't have any effect on the ABI today, but it does change the AST and type-level representation of these types. All existing `*.witx` files in this repository have been updated for all phases with these new forms. To reiterate, though, no details of the ABI have changed (or at least not intentionally). Everything should still be ABI-compatible with before. Under the hood for code generators this is a very large breaking change. The intention of this commit is to start moving code generators relying on `witx` into the direction that we'll end up with interface types. Namely the `coretypes` module is entirely replaced with a new `abi` module with the intention of handling lots more high-level details of translation than the previous module did. The `InterfaceFunc` type now sports two new methods: `call_wasm` and `call_interface`. These two methods represent the two halves of lifting/lowering operations performed by code generators. The `call_wasm` function takes interface types values (or whatever they are represented as in the source language) and converts them to wasm types to call a wasm import. The wasm import's return values are then "deserialized" back into the language's interface types values too. The `call_interface` function is the opposite, it assumes that you're coming from wasm values and calling, e.g., a host function with interface values. The `abi` module is refactored with an `Instruction` `enum` which lists out what are the current set of "adapter instructions". These adapter instructions are intended to somewhat model the eventual idea of adapter functions and their instructions, but for now they're pretty specific to WASI as-is today. All instructions currently model what WASI currently does, sometimes in very specific manners. It's expected that the `Instruction` type will be in flux as we tweak the ABI of WASI over time, but the current set of instructions will likely only be expanded because of maintaining compatibility with the current snapshot. The expected usage of `Instruction` is that code generators will implement how to generate code for each `Instruction`. This should be a very low-level operation (generating code per instruction) and should be in theory quite easy to implement. Not all code generators need to implement all instructions depending on their use case. Additionally WASI as-is today doesn't always exercise all types of instructions. The next steps after a PR like this include starting to define a new ABI for WASI which supports all types in all positions rather than the current ABI which supports only a limited subset of types in some positions. The intention is that this new ABI may add a new instruction or two but will generally not be a large breaking change for all existing code generators. Some new additions are expected but other than that existing code generators updated to use this PR will require little effort to support new ABIs. * Add more documentation and some more tests for shorthand syntax * Bump to 0.9.0 and bump wast dependency * Support variants as arguments Same as records, they use pointers * Fix a typo --- proposals/random/phases/ephemeral/docs.md | 969 +++++++++++++----- .../phases/ephemeral/witx/typenames.witx | 22 +- .../ephemeral/witx/wasi_ephemeral_args.witx | 10 +- .../ephemeral/witx/wasi_ephemeral_clock.witx | 6 +- .../witx/wasi_ephemeral_environ.witx | 10 +- .../ephemeral/witx/wasi_ephemeral_fd.witx | 54 +- .../ephemeral/witx/wasi_ephemeral_path.witx | 25 +- .../ephemeral/witx/wasi_ephemeral_poll.witx | 3 +- .../ephemeral/witx/wasi_ephemeral_random.witx | 2 +- .../ephemeral/witx/wasi_ephemeral_sched.witx | 2 +- .../ephemeral/witx/wasi_ephemeral_sock.witx | 12 +- .../random/phases/old/snapshot_0/docs.md | 929 +++++++++++++---- .../phases/old/snapshot_0/witx/typenames.witx | 20 +- .../old/snapshot_0/witx/wasi_unstable.witx | 127 +-- proposals/random/phases/snapshot/docs.md | 927 +++++++++++++---- .../phases/snapshot/witx/typenames.witx | 20 +- .../snapshot/witx/wasi_snapshot_preview1.witx | 125 +-- proposals/random/tools/witx/Cargo.toml | 4 +- proposals/random/tools/witx/src/abi.rs | 925 +++++++++++++++++ proposals/random/tools/witx/src/ast.rs | 178 +++- proposals/random/tools/witx/src/coretypes.rs | 173 ---- proposals/random/tools/witx/src/docs/ast.rs | 93 +- proposals/random/tools/witx/src/docs/md.rs | 51 +- proposals/random/tools/witx/src/layout.rs | 26 +- proposals/random/tools/witx/src/lib.rs | 6 +- proposals/random/tools/witx/src/parser.rs | 77 +- proposals/random/tools/witx/src/render.rs | 61 +- proposals/random/tools/witx/src/toplevel.rs | 6 +- proposals/random/tools/witx/src/validate.rs | 172 +++- proposals/random/tools/witx/tests/witxt.rs | 249 ++++- .../random/tools/witx/tests/witxt/abi.witxt | 490 +++++++++ .../witx/tests/witxt/representation.witxt | 4 +- .../tools/witx/tests/witxt/shorthand.witxt | 59 ++ 33 files changed, 4528 insertions(+), 1309 deletions(-) create mode 100644 proposals/random/tools/witx/src/abi.rs delete mode 100644 proposals/random/tools/witx/src/coretypes.rs create mode 100644 proposals/random/tools/witx/tests/witxt/abi.witxt create mode 100644 proposals/random/tools/witx/tests/witxt/shorthand.witxt diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index a3c0d0a47..7fa4c11de 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -22,7 +22,7 @@ Size: 8 Alignment: 8 -## `clockid`: Variant +## `clockid`: `Variant` Identifiers for clocks. Size: 4 @@ -40,7 +40,7 @@ real time, whose value cannot be adjusted and which cannot have negative clock jumps. The epoch of this clock is undefined. The absolute time value of this clock therefore has no meaning. -## `errno`: Variant +## `errno`: `Variant` Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -282,82 +282,120 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: `u64` +## `rights`: `Record` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Constants -- `fd_datasync` +### Record members +- `fd_datasync`: `bool` The right to invoke `fd_datasync`. If `path_open` is set, includes the right to invoke `path_open` with [`fdflags::dsync`](#fdflags.dsync). -- `fd_read` +Bit: 0 + +- `fd_read`: `bool` The right to invoke `fd_read` and `sock_recv`. If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. -- `fd_seek` +Bit: 1 + +- `fd_seek`: `bool` The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). -- `fd_fdstat_set_flags` +Bit: 2 + +- `fd_fdstat_set_flags`: `bool` The right to invoke `fd_fdstat_set_flags`. -- `fd_sync` +Bit: 3 + +- `fd_sync`: `bool` The right to invoke `fd_sync`. If `path_open` is set, includes the right to invoke `path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). -- `fd_tell` +Bit: 4 + +- `fd_tell`: `bool` The right to invoke `fd_seek` in such a way that the file offset remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke `fd_tell`. -- `fd_write` +Bit: 5 + +- `fd_write`: `bool` The right to invoke `fd_write` and `sock_send`. If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. -- `fd_advise` +Bit: 6 + +- `fd_advise`: `bool` The right to invoke `fd_advise`. -- `fd_allocate` +Bit: 7 + +- `fd_allocate`: `bool` The right to invoke `fd_allocate`. -- `path_create_directory` +Bit: 8 + +- `path_create_directory`: `bool` The right to invoke `path_create_directory`. -- `path_create_file` +Bit: 9 + +- `path_create_file`: `bool` If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). -- `path_link_source` +Bit: 10 + +- `path_link_source`: `bool` The right to invoke `path_link` with the file descriptor as the source directory. -- `path_link_target` +Bit: 11 + +- `path_link_target`: `bool` The right to invoke `path_link` with the file descriptor as the target directory. -- `path_open` +Bit: 12 + +- `path_open`: `bool` The right to invoke `path_open`. -- `fd_readdir` +Bit: 13 + +- `fd_readdir`: `bool` The right to invoke `fd_readdir`. -- `path_readlink` +Bit: 14 + +- `path_readlink`: `bool` The right to invoke `path_readlink`. -- `path_rename_source` +Bit: 15 + +- `path_rename_source`: `bool` The right to invoke `path_rename` with the file descriptor as the source directory. -- `path_rename_target` +Bit: 16 + +- `path_rename_target`: `bool` The right to invoke `path_rename` with the file descriptor as the target directory. -- `path_filestat_get` +Bit: 17 + +- `path_filestat_get`: `bool` The right to invoke `path_filestat_get`. -- `path_filestat_set_size` +Bit: 18 + +- `path_filestat_set_size`: `bool` The right to change a file's size. If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). Note: there is no function named `path_filestat_set_size`. This follows POSIX design, @@ -366,41 +404,65 @@ While such function would be desirable from the API design perspective, there ar no use cases for it since no code written for POSIX systems would use it. Moreover, implementing it would require multiple syscalls, leading to inferior performance. -- `path_filestat_set_times` +Bit: 19 + +- `path_filestat_set_times`: `bool` The right to invoke `path_filestat_set_times`. -- `path_permissions_set` +Bit: 20 + +- `path_permissions_set`: `bool` The right to invoke `path_permissions_set`. -- `fd_filestat_get` +Bit: 21 + +- `fd_filestat_get`: `bool` The right to invoke `fd_filestat_get`. -- `fd_filestat_set_size` +Bit: 22 + +- `fd_filestat_set_size`: `bool` The right to invoke `fd_filestat_set_size`. -- `fd_filestat_set_times` +Bit: 23 + +- `fd_filestat_set_times`: `bool` The right to invoke `fd_filestat_set_times`. -- `fd_permissions_set` +Bit: 24 + +- `fd_permissions_set`: `bool` The right to invoke `fd_permissions_set`. -- `path_symlink` +Bit: 25 + +- `path_symlink`: `bool` The right to invoke `path_symlink`. -- `path_remove_directory` +Bit: 26 + +- `path_remove_directory`: `bool` The right to invoke `path_remove_directory`. -- `path_unlink_file` +Bit: 27 + +- `path_unlink_file`: `bool` The right to invoke `path_unlink_file`. -- `poll_fd_readwrite` +Bit: 28 + +- `poll_fd_readwrite`: `bool` If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). -- `sock_shutdown` +Bit: 29 + +- `sock_shutdown`: `bool` The right to invoke `sock_shutdown`. -## `fd` +Bit: 30 + +## `fd`: `Handle` A file descriptor handle. Size: 4 @@ -408,7 +470,7 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Record +## `iovec`: `Record` A region of memory for scatter/gather reads. Size: 8 @@ -426,7 +488,7 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Record +## `ciovec`: `Record` A region of memory for scatter/gather writes. Size: 8 @@ -463,7 +525,7 @@ Size: 8 Alignment: 8 -## `whence`: Variant +## `whence`: `Variant` The position relative to which to set the offset of the file descriptor. Size: 1 @@ -504,7 +566,7 @@ Size: 8 Alignment: 8 -## `filetype`: Variant +## `filetype`: `Variant` The type of a file descriptor or file. Size: 1 @@ -539,7 +601,7 @@ The file refers to a symbolic link inode. - `fifo` The file descriptor or file refers to a FIFO. -## `dirent`: Record +## `dirent`: `Record` A directory entry. Size: 24 @@ -567,7 +629,7 @@ The length of the name of the directory entry. Offset: 20 -## `advice`: Variant +## `advice`: `Variant` File or memory access pattern advisory information. Size: 1 @@ -593,32 +655,42 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: `u16` +## `fdflags`: `Record` File descriptor flags. Size: 2 Alignment: 2 -### Constants -- `append` +### Record members +- `append`: `bool` Append mode: Data written to the file is always appended to the file's end. -- `dsync` +Bit: 0 + +- `dsync`: `bool` Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. -- `nonblock` +Bit: 1 + +- `nonblock`: `bool` Non-blocking mode. -- `rsync` +Bit: 2 + +- `rsync`: `bool` Synchronized read I/O operations. -- `sync` +Bit: 3 + +- `sync`: `bool` Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Record +Bit: 4 + +## `fdstat`: `Record` File descriptor attributes. Size: 24 @@ -655,57 +727,75 @@ Size: 8 Alignment: 8 -## `fstflags`: `u16` +## `fstflags`: `Record` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Constants -- `atim` +### Record members +- `atim`: `bool` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). -- `atim_now` +Bit: 0 + +- `atim_now`: `bool` Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -- `mtim` +Bit: 1 + +- `mtim`: `bool` Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). -- `mtim_now` +Bit: 2 + +- `mtim_now`: `bool` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: `u32` +Bit: 3 + +## `lookupflags`: `Record` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Constants -- `symlink_follow` +### Record members +- `symlink_follow`: `bool` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: `u16` +Bit: 0 + +## `oflags`: `Record` Open flags used by `path_open`. Size: 2 Alignment: 2 -### Constants -- `create` +### Record members +- `create`: `bool` Create file if it does not exist. -- `directory` +Bit: 0 + +- `directory`: `bool` Fail if not a directory. -- `excl` +Bit: 1 + +- `excl`: `bool` Fail if file already exists. -- `trunc` +Bit: 2 + +- `trunc`: `bool` Truncate file to size 0. +Bit: 3 + ## `linkcount`: `u64` Number of hard links to an inode. @@ -713,7 +803,7 @@ Size: 8 Alignment: 8 -## `permissions`: `u8` +## `permissions`: `Record` File permissions. This represents the permissions associated with a file in a filesystem, and don't fully reflect all the conditions which determine whether a given WASI program can access the file. @@ -722,8 +812,8 @@ Size: 1 Alignment: 1 -### Constants -- `read` +### Record members +- `read`: `bool` For files, permission to read the file. For directories, permission to do [`readdir`](#readdir) and access files within the directory. @@ -731,23 +821,31 @@ within the directory. Note: This is similar to the read bit being set on files, and the read *and* execute bits being set on directories, in POSIX. -- `write` +Bit: 0 + +- `write`: `bool` For files, permission to mutate the file. For directories, permission to create, remove, and rename items within the directory. -- `execute` +Bit: 1 + +- `execute`: `bool` For files, permission to "execute" the file, using whatever concept of "executing" the host filesystem has. This flag is not valid for directories. -- `private` +Bit: 2 + +- `private`: `bool` For filesystems which have a concept of multiple "users", this flag indicates that the file is only accessible by the effective "user" that the WASI store uses to access the filesystem, and inaccessible to other "users". -## `filestat`: Record +Bit: 3 + +## `filestat`: `Record` File attributes. Size: 64 @@ -808,7 +906,7 @@ Size: 8 Alignment: 8 -## `eventtype`: Variant +## `eventtype`: `Variant` Type of a subscription to an event or its occurrence. Size: 1 @@ -828,7 +926,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: `u16` +## `eventrwflags`: `Record` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -836,11 +934,13 @@ Size: 2 Alignment: 2 -### Constants -- `fd_readwrite_hangup` +### Record members +- `fd_readwrite_hangup`: `bool` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Record +Bit: 0 + +## `event_fd_readwrite`: `Record` The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -859,7 +959,7 @@ The state of the file descriptor. Offset: 8 -## `event_u`: Variant +## `event_u`: `Variant` The contents of an [`event`](#event). Size: 24 @@ -877,7 +977,7 @@ Alignment: 8 - `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) -## `event`: Record +## `event`: `Record` An event that occurred. Size: 40 @@ -900,7 +1000,7 @@ The type of the event that occurred, and the contents of the event Offset: 16 -## `subclockflags`: `u16` +## `subclockflags`: `Record` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -908,15 +1008,17 @@ Size: 2 Alignment: 2 -### Constants -- `subscription_clock_abstime` +### Record members +- `subscription_clock_abstime`: `bool` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock [`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Record +Bit: 0 + +## `subscription_clock`: `Record` The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 32 @@ -945,7 +1047,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 24 -## `subscription_fd_readwrite`: Record +## `subscription_fd_readwrite`: `Record` The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -959,7 +1061,7 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Variant +## `subscription_u`: `Variant` The contents of a [`subscription`](#subscription). Size: 40 @@ -977,7 +1079,7 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Record +## `subscription`: `Record` Subscription to an event. Size: 48 @@ -1003,31 +1105,37 @@ Size: 4 Alignment: 4 -## `riflags`: `u16` +## `riflags`: `Record` Flags provided to `sock_recv`. Size: 2 Alignment: 2 -### Constants -- `recv_peek` +### Record members +- `recv_peek`: `bool` Returns the message without removing it from the socket's receive queue. -- `recv_waitall` +Bit: 0 + +- `recv_waitall`: `bool` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: `u16` +Bit: 1 + +## `roflags`: `Record` Flags returned by `sock_recv`. Size: 2 Alignment: 2 -### Constants -- `recv_data_truncated` +### Record members +- `recv_data_truncated`: `bool` Returned by `sock_recv`: Message data has been truncated. +Bit: 0 + ## `siflags`: `u16` Flags provided to `sock_send`. As there are currently no flags defined, it must be set to zero. @@ -1036,21 +1144,25 @@ Size: 2 Alignment: 2 -## `sdflags`: `u8` +## `sdflags`: `Record` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Constants -- `rd` +### Record members +- `rd`: `bool` Disables further receive operations. -- `wr` +Bit: 0 + +- `wr`: `bool` Disables further send operations. -## `preopentype`: Variant +Bit: 1 + +## `preopentype`: `Variant` Identifiers for preopened capabilities. Size: 1 @@ -1061,7 +1173,7 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Record +## `prestat_dir`: `Record` The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). Size: 4 @@ -1074,7 +1186,7 @@ The length of the directory name for use with `fd_prestat_dir_name`. Offset: 0 -## `prestat`: Variant +## `prestat`: `Variant` Information about a pre-opened capability. Size: 8 @@ -1097,7 +1209,7 @@ When type is [`preopentype::dir`](#preopentype.dir): --- -#### `get(argv: Pointer>, argv_buf: Pointer) -> errno` +#### `get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. The size of the array should match that returned by [`sizes_get`](#sizes_get) @@ -1107,23 +1219,46 @@ The size of the array should match that returned by [`sizes_get`](#sizes_get) - `argv_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sizes_get() -> (errno, size, size)` +#### `sizes_get() -> Result<(size, size), errno>` Return command-line argument data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of arguments and the size of the argument string +data, or an error. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` -- `argc`: [`size`](#size) -The number of arguments. +####### Record members +- `0`: [`size`](#size) -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +Offset: 0 + +- `1`: [`size`](#size) + +Offset: 4 + +- `err`: [`errno`](#errno) ## wasi_ephemeral_clock ### Imports @@ -1132,7 +1267,7 @@ The size of the argument string data. --- -#### `res_get(id: clockid) -> (errno, timestamp)` +#### `res_get(id: clockid) -> Result` Return the resolution of a clock. Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return [`errno::inval`](#errno.inval). @@ -1143,15 +1278,22 @@ Note: This is similar to `clock_getres` in POSIX. The clock for which to return the resolution. ##### Results -- `error`: [`errno`](#errno) - -- `resolution`: [`timestamp`](#timestamp) +- `error`: `Result` The resolution of the clock. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) + +- `err`: [`errno`](#errno) + --- -#### `time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +#### `time_get(id: clockid, precision: timestamp) -> Result` Return the time value of a clock. Note: This is similar to `clock_gettime` in POSIX. @@ -1163,11 +1305,18 @@ The clock for which to return the time. The maximum lag (exclusive) that the returned time value may have, compared to its actual value. ##### Results -- `error`: [`errno`](#errno) - -- `time`: [`timestamp`](#timestamp) +- `error`: `Result` The time value of the clock. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) + +- `err`: [`errno`](#errno) + ## wasi_ephemeral_environ ### Imports #### Memory @@ -1175,7 +1324,7 @@ The time value of the clock. --- -#### `get(environ: Pointer>, environ_buf: Pointer) -> errno` +#### `get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). @@ -1185,23 +1334,46 @@ The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get) - `environ_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sizes_get() -> (errno, size, size)` +#### `sizes_get() -> Result<(size, size), errno>` Return environment variable data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of environment variable arguments and the size of the +environment variable data. -- `environc`: [`size`](#size) -The number of environment variable arguments. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) + +Offset: 0 -- `environ_buf_size`: [`size`](#size) -The size of the environment variable data. +- `1`: [`size`](#size) + +Offset: 4 + +- `err`: [`errno`](#errno) ## wasi_ephemeral_fd ### Imports @@ -1210,7 +1382,7 @@ The size of the environment variable data. --- -#### `advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +#### `advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` Provide file advisory information on a file descriptor. Note: This is similar to `posix_fadvise` in POSIX. @@ -1227,12 +1399,21 @@ The length of the region to which the advisory applies. The advice. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `allocate(fd: fd, offset: filesize, len: filesize) -> errno` +#### `allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` Force the allocation of space in a file. Note: This is similar to `posix_fallocate` in POSIX. @@ -1246,12 +1427,21 @@ The offset at which to start the allocation. The length of the area that is allocated. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `close(fd: fd) -> errno` +#### `close(fd: fd) -> Result<(), errno>` Close a file descriptor. Note: This is similar to [`close`](#close) in POSIX. @@ -1259,12 +1449,21 @@ Note: This is similar to [`close`](#close) in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `datasync(fd: fd) -> errno` +#### `datasync(fd: fd) -> Result<(), errno>` Synchronize the data of a file to disk. Note: This is similar to `fdatasync` in POSIX. @@ -1272,12 +1471,21 @@ Note: This is similar to `fdatasync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fdstat_get(fd: fd) -> (errno, fdstat)` +#### `fdstat_get(fd: fd) -> Result` Get the attributes of a file descriptor. Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. @@ -1285,15 +1493,22 @@ Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as ad - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `stat`: [`fdstat`](#fdstat) +- `error`: `Result` The buffer where the file descriptor's attributes are stored. +###### Variant Layout +- size: 32 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`fdstat`](#fdstat) + +- `err`: [`errno`](#errno) + --- -#### `fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +#### `fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` Adjust the flags associated with a file descriptor. Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. @@ -1304,12 +1519,21 @@ Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. The desired values of the file descriptor flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +#### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` Adjust the rights associated with a file descriptor. This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights @@ -1322,27 +1546,43 @@ The desired rights of the file descriptor. - `fs_rights_inheriting`: [`rights`](#rights) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `filestat_get(fd: fd) -> (errno, filestat)` +#### `filestat_get(fd: fd) -> Result` Return the attributes of an open file. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 72 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `filestat_set_size(fd: fd, size: filesize) -> errno` +#### `filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. Note: This is similar to `ftruncate` in POSIX. @@ -1353,12 +1593,21 @@ Note: This is similar to `ftruncate` in POSIX. The desired file size. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of an open file or directory. Note: This is similar to `futimens` in POSIX. @@ -1375,12 +1624,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `permissions_set(fd: fd, permissions: permissions) -> errno` +#### `permissions_set(fd: fd, permissions: permissions) -> Result<(), errno>` Set the permissions of a file or directory. This sets the permissions associated with a file or directory in @@ -1401,12 +1659,21 @@ umask to determine which of the user/group/other flags to modify. The permissions associated with the file. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +#### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` Read from a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `preadv` in Linux (and other Unix-es). @@ -1420,30 +1687,44 @@ List of scatter/gather vectors in which to store data. The offset within the file at which to read. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `prestat_get(fd: fd) -> (errno, prestat)` +#### `prestat_get(fd: fd) -> Result` Return a description of the given preopened file descriptor. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`prestat`](#prestat) +- `error`: `Result` The buffer where the description is stored. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`prestat`](#prestat) + +- `err`: [`errno`](#errno) + --- -#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` Return a description of the given preopened file descriptor. ##### Params @@ -1455,12 +1736,21 @@ A buffer into which to write the preopened directory name. - `path_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +#### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` Write to a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `pwritev` in Linux (and other Unix-es). @@ -1478,15 +1768,22 @@ List of scatter/gather vectors from which to retrieve data. The offset within the file at which to write. ##### Results -- `error`: [`errno`](#errno) - -- `nwritten`: [`size`](#size) +- `error`: `Result` The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `read(fd: fd, iovs: iovec_array) -> (errno, size)` +#### `read(fd: fd, iovs: iovec_array) -> Result` Read from a file descriptor. Note: This is similar to `readv` in POSIX. @@ -1497,15 +1794,22 @@ Note: This is similar to `readv` in POSIX. List of scatter/gather vectors to which to store data. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +#### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of directory entries. Each directory entry consists of a [`dirent`](#dirent) object, @@ -1528,15 +1832,22 @@ The buffer where directory entries are stored The location within the directory to start reading ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `renumber(fd: fd, to: fd) -> errno` +#### `renumber(fd: fd, to: fd) -> Result<(), errno>` Atomically replace a file descriptor by renumbering another file descriptor. Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary @@ -1553,12 +1864,21 @@ would disappear if `dup2()` were to be removed entirely. The file descriptor to overwrite. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +#### `seek(fd: fd, offset: filedelta, whence: whence) -> Result` Move the offset of a file descriptor. Note: This is similar to `lseek` in POSIX. @@ -1572,15 +1892,22 @@ The number of bytes to move. The base from which the offset is relative. ##### Results -- `error`: [`errno`](#errno) - -- `newoffset`: [`filesize`](#filesize) +- `error`: `Result` The new offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `sync(fd: fd) -> errno` +#### `sync(fd: fd) -> Result<(), errno>` Synchronize the data and metadata of a file to disk. Note: This is similar to `fsync` in POSIX. @@ -1588,12 +1915,21 @@ Note: This is similar to `fsync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `tell(fd: fd) -> (errno, filesize)` +#### `tell(fd: fd) -> Result` Return the current offset of a file descriptor. Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. @@ -1601,15 +1937,22 @@ Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `offset`: [`filesize`](#filesize) +- `error`: `Result` The current offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `write(fd: fd, iovs: ciovec_array) -> (errno, size)` +#### `write(fd: fd, iovs: ciovec_array) -> Result` Write to a file descriptor. Note: This is similar to `writev` in POSIX. @@ -1624,11 +1967,18 @@ interleaved while [`write`](#write) is executed. List of scatter/gather vectors from which to retrieve data. ##### Results -- `error`: [`errno`](#errno) - -- `nwritten`: [`size`](#size) +- `error`: `Result` The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + ## wasi_ephemeral_path ### Imports #### Memory @@ -1636,7 +1986,7 @@ The number of bytes written. --- -#### `create_directory(fd: fd, path: string) -> errno` +#### `create_directory(fd: fd, path: string) -> Result<(), errno>` Create a directory. Note: This is similar to `mkdirat` in POSIX. @@ -1647,12 +1997,21 @@ Note: This is similar to `mkdirat` in POSIX. The path at which to create the directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +#### `filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` Return the attributes of a file or directory. Note: This is similar to `stat` in POSIX. @@ -1666,15 +2025,22 @@ Flags determining the method of how the path is resolved. The path of the file or directory to inspect. ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 72 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of a file or directory. Note: This is similar to `utimensat` in POSIX. @@ -1697,12 +2063,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `permissions_set(fd: fd, flags: lookupflags, path: string, permissions: permissions) -> errno` +#### `permissions_set(fd: fd, flags: lookupflags, path: string, permissions: permissions) -> Result<(), errno>` Set the permissions of a file or directory. This sets the permissions associated with a file or directory in @@ -1729,12 +2104,21 @@ The path to a file to query. The permissions to associate with the file. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Create a hard link. Note: This is similar to `linkat` in POSIX. @@ -1754,12 +2138,21 @@ The working directory at which the resolution of the new path starts. The destination path at which to create the hard link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, permissions: permissions) -> (errno, fd)` +#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, permissions: permissions) -> Result` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1798,15 +2191,22 @@ file descriptors derived from it. If a file is created, the filesystem permissions to associate with it. ##### Results -- `error`: [`errno`](#errno) - -- `opened_fd`: [`fd`](#fd) +- `error`: `Result` The file descriptor of the file that has been opened. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`fd`](#fd) + +- `err`: [`errno`](#errno) + --- -#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` Read the contents of a symbolic link. Note: This is similar to `readlinkat` in POSIX. @@ -1822,15 +2222,22 @@ The buffer to which to write the contents of the symbolic link. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes placed in the buffer. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `remove_directory(fd: fd, path: string) -> errno` +#### `remove_directory(fd: fd, path: string) -> Result<(), errno>` Remove a directory. Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. @@ -1842,12 +2249,21 @@ Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. The path to a directory to remove. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Rename a file or directory. Note: This is similar to `renameat` in POSIX. @@ -1864,12 +2280,21 @@ The working directory at which the resolution of the new path starts. The destination path to which to rename the file or directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `symlink(old_path: string, fd: fd, new_path: string) -> errno` +#### `symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` Create a symbolic link. Note: This is similar to `symlinkat` in POSIX. @@ -1883,12 +2308,21 @@ The contents of the symbolic link. The destination path at which to create the symbolic link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `unlink_file(fd: fd, path: string) -> errno` +#### `unlink_file(fd: fd, path: string) -> Result<(), errno>` Unlink a file. Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. @@ -1900,7 +2334,16 @@ Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. The path to a file to unlink. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) ## wasi_ephemeral_poll ### Imports @@ -1909,7 +2352,7 @@ The path to a file to unlink. --- -#### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +#### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` Concurrently poll for the occurrence of a set of events. If `nsubscriptions` is 0, returns [`errno::inval`](#errno.inval). @@ -1925,11 +2368,18 @@ The events that have occurred. Both the number of subscriptions and events. ##### Results -- `error`: [`errno`](#errno) - -- `nevents`: [`size`](#size) +- `error`: `Result` The number of events stored. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + ## wasi_ephemeral_proc ### Imports ### Functions @@ -1953,7 +2403,7 @@ The exit code returned by the process. --- -#### `get(buf: Pointer, buf_len: size) -> errno` +#### `get(buf: Pointer, buf_len: size) -> Result<(), errno>` Write high-quality random data into a buffer. This function blocks when the implementation is unable to immediately provide sufficient high-quality random data. @@ -1968,7 +2418,16 @@ The buffer to fill with random data. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) ## wasi_ephemeral_sched ### Imports @@ -1976,13 +2435,22 @@ The buffer to fill with random data. --- -#### `yield() -> errno` +#### `yield() -> Result<(), errno>` Temporarily yield execution of the calling thread. Note: This is similar to [`yield`](#yield) in POSIX. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) ## wasi_ephemeral_sock ### Imports @@ -1991,7 +2459,7 @@ Note: This is similar to [`yield`](#yield) in POSIX. --- -#### `recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +#### `recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` Receive a message from a socket. Note: This is similar to [`recv`](#recv) in POSIX, though it also supports reading the data into multiple buffers in the manner of `readv`. @@ -2006,18 +2474,31 @@ List of scatter/gather vectors to which to store data. Message flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, roflags), errno>` +Number of bytes stored in ri_data and message flags. -- `ro_datalen`: [`size`](#size) -Number of bytes stored in ri_data. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, roflags)` -- `ro_flags`: [`roflags`](#roflags) -Message flags. +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`roflags`](#roflags) + +Offset: 4 + +- `err`: [`errno`](#errno) --- -#### `send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +#### `send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` Send a message on a socket. Note: This is similar to [`send`](#send) in POSIX, though it also supports writing the data from multiple buffers in the manner of `writev`. @@ -2032,15 +2513,22 @@ List of scatter/gather vectors to which to retrieve data Message flags. ##### Results -- `error`: [`errno`](#errno) - -- `so_datalen`: [`size`](#size) +- `error`: `Result` Number of bytes transmitted. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `shutdown(fd: fd, how: sdflags) -> errno` +#### `shutdown(fd: fd, how: sdflags) -> Result<(), errno>` Shut down socket send and receive channels. Note: This is similar to [`shutdown`](#shutdown) in POSIX. @@ -2051,5 +2539,14 @@ Note: This is similar to [`shutdown`](#shutdown) in POSIX. Which channels on the socket to shut down. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 503aa0cf6..1f9abc59b 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -195,7 +195,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags (@witx bitflags u64) + (flags (@witx repr u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke @@ -392,7 +392,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -429,7 +429,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -443,7 +443,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags (@witx bitflags u32) + (flags (@witx repr u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -451,7 +451,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Create file if it does not exist. $create ;;; Fail if not a directory. @@ -470,7 +470,7 @@ ;;; file in a filesystem, and don't fully reflect all the conditions ;;; which determine whether a given WASI program can access the file. (typename $permissions - (flags (@witx bitflags u8) + (flags (@witx repr u8) ;;; For files, permission to read the file. ;;; For directories, permission to do `readdir` and access files ;;; within the directory. @@ -543,7 +543,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -584,7 +584,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -643,7 +643,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -653,7 +653,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -665,7 +665,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags (@witx bitflags u8) + (flags (@witx repr u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx index 803605fee..b8d77b504 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -14,15 +14,13 @@ (@interface func (export "get") (param $argv (@witx pointer (@witx pointer (@witx char8)))) (param $argv_buf (@witx pointer (@witx char8))) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return command-line argument data sizes. (@interface func (export "sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; Returns the number of arguments and the size of the argument string + ;;; data, or an error. + (result $error (expected (tuple $size $size) (error $errno))) ) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx index 3b00e0ac4..a980529f8 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx @@ -18,9 +18,8 @@ (@interface func (export "res_get") ;;; The clock for which to return the resolution. (param $id $clockid) - (result $error $errno) ;;; The resolution of the clock. - (result $resolution $timestamp) + (result $error (expected $timestamp (error $errno))) ) ;;; Return the time value of a clock. @@ -30,8 +29,7 @@ (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp) - (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp) + (result $error (expected $timestamp (error $errno))) ) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx index 6357fe602..0cad3c1cc 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -14,15 +14,13 @@ (@interface func (export "get") (param $environ (@witx pointer (@witx pointer (@witx char8)))) (param $environ_buf (@witx pointer (@witx char8))) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return environment variable data sizes. (@interface func (export "sizes_get") - (result $error $errno) - ;;; The number of environment variable arguments. - (result $environc $size) - ;;; The size of the environment variable data. - (result $environ_buf_size $size) + ;;; Returns the number of environment variable arguments and the size of the + ;;; environment variable data. + (result $error (expected (tuple $size $size) (error $errno))) ) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx index 8192c9b7f..979e9a333 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -21,7 +21,7 @@ (param $len $filesize) ;;; The advice. (param $advice $advice) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Force the allocation of space in a file. @@ -32,30 +32,29 @@ (param $offset $filesize) ;;; The length of the area that is allocated. (param $len $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "close") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "datasync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fdstat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat) + (result $error (expected $fdstat (error $errno))) ) ;;; Adjust the flags associated with a file descriptor. @@ -64,7 +63,7 @@ (param $fd $fd) ;;; The desired values of the file descriptor flags. (param $flags $fdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the rights associated with a file descriptor. @@ -74,15 +73,14 @@ ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of an open file. (@interface func (export "filestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. @@ -91,7 +89,7 @@ (param $fd $fd) ;;; The desired file size. (param $size $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the timestamps of an open file or directory. @@ -104,7 +102,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Set the permissions of a file or directory. @@ -123,7 +121,7 @@ (param $fd $fd) ;;; The permissions associated with the file. (param $permissions $permissions) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. @@ -134,17 +132,15 @@ (param $iovs $iovec_array) ;;; The offset within the file at which to read. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "prestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat) + (result $error (expected $prestat (error $errno))) ) ;;; Return a description of the given preopened file descriptor. @@ -153,7 +149,7 @@ ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer (@witx char8))) (param $path_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. @@ -168,9 +164,8 @@ (param $iovs $ciovec_array) ;;; The offset within the file at which to write. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Read from a file descriptor. @@ -179,9 +174,8 @@ (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_array) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Read directory entries from a directory. @@ -201,9 +195,8 @@ (param $buf_len $size) ;;; The location within the directory to start reading (param $cookie $dircookie) - (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -220,7 +213,7 @@ (param $fd $fd) ;;; The file descriptor to overwrite. (param $to $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Move the offset of a file descriptor. @@ -231,25 +224,23 @@ (param $offset $filedelta) ;;; The base from which the offset is relative. (param $whence $whence) - (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "sync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "tell") (param $fd $fd) - (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Write to a file descriptor. @@ -262,8 +253,7 @@ (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_array) - (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx index 5b3e17e88..2901decb7 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -17,7 +17,7 @@ (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of a file or directory. @@ -28,9 +28,8 @@ (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the timestamps of a file or directory. @@ -47,7 +46,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Set the permissions of a file or directory. @@ -70,7 +69,7 @@ (param $path string) ;;; The permissions to associate with the file. (param $permissions $permissions) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a hard link. @@ -85,7 +84,7 @@ (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Open a file or directory. @@ -119,9 +118,8 @@ (param $fdflags $fdflags) ;;; If a file is created, the filesystem permissions to associate with it. (param $permissions $permissions) - (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd) + (result $error (expected $fd (error $errno))) ) ;;; Read the contents of a symbolic link. @@ -133,9 +131,8 @@ ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer (@witx char8))) (param $buf_len $size) - (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Remove a directory. @@ -145,7 +142,7 @@ (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Rename a file or directory. @@ -158,7 +155,7 @@ (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a symbolic link. @@ -169,7 +166,7 @@ (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Unlink a file. @@ -179,6 +176,6 @@ (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx index a30b96afc..08da5f03a 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx @@ -21,8 +21,7 @@ (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. (param $nsubscriptions $size) - (result $error $errno) ;;; The number of events stored. - (result $nevents $size) + (result $error (expected $size (error $errno))) ) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx index 55c6df021..4dc8e1a47 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx @@ -21,6 +21,6 @@ ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sched.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sched.witx index 799a75fa9..3b70856dc 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sched.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sched.witx @@ -11,6 +11,6 @@ ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `yield` in POSIX. (@interface func (export "yield") - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sock.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sock.witx index becf80ffc..a05b02ea6 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sock.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sock.witx @@ -20,11 +20,8 @@ (param $ri_data $iovec_array) ;;; Message flags. (param $ri_flags $riflags) - (result $error $errno) - ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size) - ;;; Message flags. - (result $ro_flags $roflags) + ;;; Number of bytes stored in ri_data and message flags. + (result $error (expected (tuple $size $roflags) (error $errno))) ) ;;; Send a message on a socket. @@ -36,9 +33,8 @@ (param $si_data $ciovec_array) ;;; Message flags. (param $si_flags $siflags) - (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size) + (result $error (expected $size (error $errno))) ) ;;; Shut down socket send and receive channels. @@ -47,6 +43,6 @@ (param $fd $fd) ;;; Which channels on the socket to shut down. (param $how $sdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index e77002bc6..707c836b2 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -19,7 +19,7 @@ Size: 8 Alignment: 8 -## `clockid`: Variant +## `clockid`: `Variant` Identifiers for clocks. Size: 4 @@ -43,7 +43,7 @@ The CPU-time clock associated with the current process. - `thread_cputime_id` The CPU-time clock associated with the current thread. -## `errno`: Variant +## `errno`: `Variant` Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -285,114 +285,172 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: `u64` +## `rights`: `Record` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Constants -- `fd_datasync` +### Record members +- `fd_datasync`: `bool` The right to invoke [`fd_datasync`](#fd_datasync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). -- `fd_read` +Bit: 0 + +- `fd_read`: `bool` The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). -- `fd_seek` +Bit: 1 + +- `fd_seek`: `bool` The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). -- `fd_fdstat_set_flags` +Bit: 2 + +- `fd_fdstat_set_flags`: `bool` The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). -- `fd_sync` +Bit: 3 + +- `fd_sync`: `bool` The right to invoke [`fd_sync`](#fd_sync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). -- `fd_tell` +Bit: 4 + +- `fd_tell`: `bool` The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke [`fd_tell`](#fd_tell). -- `fd_write` +Bit: 5 + +- `fd_write`: `bool` The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). -- `fd_advise` +Bit: 6 + +- `fd_advise`: `bool` The right to invoke [`fd_advise`](#fd_advise). -- `fd_allocate` +Bit: 7 + +- `fd_allocate`: `bool` The right to invoke [`fd_allocate`](#fd_allocate). -- `path_create_directory` +Bit: 8 + +- `path_create_directory`: `bool` The right to invoke [`path_create_directory`](#path_create_directory). -- `path_create_file` +Bit: 9 + +- `path_create_file`: `bool` If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). -- `path_link_source` +Bit: 10 + +- `path_link_source`: `bool` The right to invoke [`path_link`](#path_link) with the file descriptor as the source directory. -- `path_link_target` +Bit: 11 + +- `path_link_target`: `bool` The right to invoke [`path_link`](#path_link) with the file descriptor as the target directory. -- `path_open` +Bit: 12 + +- `path_open`: `bool` The right to invoke [`path_open`](#path_open). -- `fd_readdir` +Bit: 13 + +- `fd_readdir`: `bool` The right to invoke [`fd_readdir`](#fd_readdir). -- `path_readlink` +Bit: 14 + +- `path_readlink`: `bool` The right to invoke [`path_readlink`](#path_readlink). -- `path_rename_source` +Bit: 15 + +- `path_rename_source`: `bool` The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. -- `path_rename_target` +Bit: 16 + +- `path_rename_target`: `bool` The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. -- `path_filestat_get` +Bit: 17 + +- `path_filestat_get`: `bool` The right to invoke [`path_filestat_get`](#path_filestat_get). -- `path_filestat_set_size` +Bit: 18 + +- `path_filestat_set_size`: `bool` The right to change a file's size (there is no `path_filestat_set_size`). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). -- `path_filestat_set_times` +Bit: 19 + +- `path_filestat_set_times`: `bool` The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). -- `fd_filestat_get` +Bit: 20 + +- `fd_filestat_get`: `bool` The right to invoke [`fd_filestat_get`](#fd_filestat_get). -- `fd_filestat_set_size` +Bit: 21 + +- `fd_filestat_set_size`: `bool` The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). -- `fd_filestat_set_times` +Bit: 22 + +- `fd_filestat_set_times`: `bool` The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). -- `path_symlink` +Bit: 23 + +- `path_symlink`: `bool` The right to invoke [`path_symlink`](#path_symlink). -- `path_remove_directory` +Bit: 24 + +- `path_remove_directory`: `bool` The right to invoke [`path_remove_directory`](#path_remove_directory). -- `path_unlink_file` +Bit: 25 + +- `path_unlink_file`: `bool` The right to invoke [`path_unlink_file`](#path_unlink_file). -- `poll_fd_readwrite` +Bit: 26 + +- `poll_fd_readwrite`: `bool` If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). -- `sock_shutdown` +Bit: 27 + +- `sock_shutdown`: `bool` The right to invoke [`sock_shutdown`](#sock_shutdown). -## `fd` +Bit: 28 + +## `fd`: `Handle` A file descriptor handle. Size: 4 @@ -400,7 +458,7 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Record +## `iovec`: `Record` A region of memory for scatter/gather reads. Size: 8 @@ -418,7 +476,7 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Record +## `ciovec`: `Record` A region of memory for scatter/gather writes. Size: 8 @@ -455,7 +513,7 @@ Size: 8 Alignment: 8 -## `whence`: Variant +## `whence`: `Variant` The position relative to which to set the offset of the file descriptor. Size: 1 @@ -493,7 +551,7 @@ Size: 8 Alignment: 8 -## `filetype`: Variant +## `filetype`: `Variant` The type of a file descriptor or file. Size: 1 @@ -525,7 +583,7 @@ The file descriptor or file refers to a byte-stream socket. - `symbolic_link` The file refers to a symbolic link inode. -## `dirent`: Record +## `dirent`: `Record` A directory entry. Size: 24 @@ -553,7 +611,7 @@ The type of the file referred to by this directory entry. Offset: 20 -## `advice`: Variant +## `advice`: `Variant` File or memory access pattern advisory information. Size: 1 @@ -579,32 +637,42 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: `u16` +## `fdflags`: `Record` File descriptor flags. Size: 2 Alignment: 2 -### Constants -- `append` +### Record members +- `append`: `bool` Append mode: Data written to the file is always appended to the file's end. -- `dsync` +Bit: 0 + +- `dsync`: `bool` Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. -- `nonblock` +Bit: 1 + +- `nonblock`: `bool` Non-blocking mode. -- `rsync` +Bit: 2 + +- `rsync`: `bool` Synchronized read I/O operations. -- `sync` +Bit: 3 + +- `sync`: `bool` Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Record +Bit: 4 + +## `fdstat`: `Record` File descriptor attributes. Size: 24 @@ -641,57 +709,75 @@ Size: 8 Alignment: 8 -## `fstflags`: `u16` +## `fstflags`: `Record` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Constants -- `atim` +### Record members +- `atim`: `bool` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). -- `atim_now` +Bit: 0 + +- `atim_now`: `bool` Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -- `mtim` +Bit: 1 + +- `mtim`: `bool` Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). -- `mtim_now` +Bit: 2 + +- `mtim_now`: `bool` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: `u32` +Bit: 3 + +## `lookupflags`: `Record` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Constants -- `symlink_follow` +### Record members +- `symlink_follow`: `bool` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: `u16` +Bit: 0 + +## `oflags`: `Record` Open flags used by [`path_open`](#path_open). Size: 2 Alignment: 2 -### Constants -- `creat` +### Record members +- `creat`: `bool` Create file if it does not exist. -- `directory` +Bit: 0 + +- `directory`: `bool` Fail if not a directory. -- `excl` +Bit: 1 + +- `excl`: `bool` Fail if file already exists. -- `trunc` +Bit: 2 + +- `trunc`: `bool` Truncate file to size 0. +Bit: 3 + ## `linkcount`: `u32` Number of hard links to an inode. @@ -699,7 +785,7 @@ Size: 4 Alignment: 4 -## `filestat`: Record +## `filestat`: `Record` File attributes. Size: 56 @@ -755,7 +841,7 @@ Size: 8 Alignment: 8 -## `eventtype`: Variant +## `eventtype`: `Variant` Type of a subscription to an event or its occurrence. Size: 1 @@ -775,7 +861,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: `u16` +## `eventrwflags`: `Record` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -783,11 +869,13 @@ Size: 2 Alignment: 2 -### Constants -- `fd_readwrite_hangup` +### Record members +- `fd_readwrite_hangup`: `bool` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Record +Bit: 0 + +## `event_fd_readwrite`: `Record` The contents of an [`event`](#event) for the [`eventtype::fd_read`](#eventtype.fd_read) and [`eventtype::fd_write`](#eventtype.fd_write) variants @@ -806,7 +894,7 @@ The state of the file descriptor. Offset: 8 -## `event`: Record +## `event`: `Record` An event that occurred. Size: 32 @@ -835,7 +923,7 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read Offset: 16 -## `subclockflags`: `u16` +## `subclockflags`: `Record` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -843,15 +931,17 @@ Size: 2 Alignment: 2 -### Constants -- `subscription_clock_abstime` +### Record members +- `subscription_clock_abstime`: `bool` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock [`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Record +Bit: 0 + +## `subscription_clock`: `Record` The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 40 @@ -885,7 +975,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 32 -## `subscription_fd_readwrite`: Record +## `subscription_fd_readwrite`: `Record` The contents of a [`subscription`](#subscription) when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -899,7 +989,7 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Variant +## `subscription_u`: `Variant` The contents of a [`subscription`](#subscription). Size: 48 @@ -917,7 +1007,7 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Record +## `subscription`: `Record` Subscription to an event. Size: 56 @@ -943,7 +1033,7 @@ Size: 4 Alignment: 4 -## `signal`: Variant +## `signal`: `Variant` Signal condition. Size: 1 @@ -1075,31 +1165,37 @@ Action: Terminates the process. Bad system call. Action: Terminates the process. -## `riflags`: `u16` +## `riflags`: `Record` Flags provided to [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Constants -- `recv_peek` +### Record members +- `recv_peek`: `bool` Returns the message without removing it from the socket's receive queue. -- `recv_waitall` +Bit: 0 + +- `recv_waitall`: `bool` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: `u16` +Bit: 1 + +## `roflags`: `Record` Flags returned by [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Constants -- `recv_data_truncated` +### Record members +- `recv_data_truncated`: `bool` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. +Bit: 0 + ## `siflags`: `u16` Flags provided to [`sock_send`](#sock_send). As there are currently no flags defined, it must be set to zero. @@ -1108,21 +1204,25 @@ Size: 2 Alignment: 2 -## `sdflags`: `u8` +## `sdflags`: `Record` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Constants -- `rd` +### Record members +- `rd`: `bool` Disables further receive operations. -- `wr` +Bit: 0 + +- `wr`: `bool` Disables further send operations. -## `preopentype`: Variant +Bit: 1 + +## `preopentype`: `Variant` Identifiers for preopened capabilities. Size: 1 @@ -1133,7 +1233,7 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Record +## `prestat_dir`: `Record` The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). Size: 4 @@ -1146,7 +1246,7 @@ The length of the directory name for use with [`fd_prestat_dir_name`](#fd_presta Offset: 0 -## `prestat`: Variant +## `prestat`: `Variant` Information about a pre-opened capability. Size: 8 @@ -1168,7 +1268,7 @@ Alignment: 4 --- -#### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` +#### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) @@ -1178,28 +1278,51 @@ The size of the array should match that returned by [`args_sizes_get`](#args_siz - `argv_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `args_sizes_get() -> (errno, size, size)` +#### `args_sizes_get() -> Result<(size, size), errno>` Return command-line argument data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of arguments and the size of the argument string +data, or an error. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) -- `argc`: [`size`](#size) -The number of arguments. +Offset: 0 + +- `1`: [`size`](#size) + +Offset: 4 -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `err`: [`errno`](#errno) --- -#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` +#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). @@ -1209,28 +1332,51 @@ The sizes of the buffers should match that returned by [`environ_sizes_get`](#en - `environ_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `environ_sizes_get() -> (errno, size, size)` +#### `environ_sizes_get() -> Result<(size, size), errno>` Return environment variable data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of environment variable arguments and the size of the +environment variable data. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`size`](#size) -- `environc`: [`size`](#size) -The number of environment variable arguments. +Offset: 4 -- `environ_buf_size`: [`size`](#size) -The size of the environment variable data. +- `err`: [`errno`](#errno) --- -#### `clock_res_get(id: clockid) -> (errno, timestamp)` +#### `clock_res_get(id: clockid) -> Result` Return the resolution of a clock. Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return [`errno::inval`](#errno.inval). @@ -1241,15 +1387,22 @@ Note: This is similar to `clock_getres` in POSIX. The clock for which to return the resolution. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result` +The resolution of the clock, or an error if one happened. + +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) -- `resolution`: [`timestamp`](#timestamp) -The resolution of the clock. +- `err`: [`errno`](#errno) --- -#### `clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +#### `clock_time_get(id: clockid, precision: timestamp) -> Result` Return the time value of a clock. Note: This is similar to `clock_gettime` in POSIX. @@ -1261,15 +1414,22 @@ The clock for which to return the time. The maximum lag (exclusive) that the returned time value may have, compared to its actual value. ##### Results -- `error`: [`errno`](#errno) - -- `time`: [`timestamp`](#timestamp) +- `error`: `Result` The time value of the clock. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) + +- `err`: [`errno`](#errno) + --- -#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` Provide file advisory information on a file descriptor. Note: This is similar to `posix_fadvise` in POSIX. @@ -1286,12 +1446,21 @@ The length of the region to which the advisory applies. The advice. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno` +#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` Force the allocation of space in a file. Note: This is similar to `posix_fallocate` in POSIX. @@ -1305,12 +1474,21 @@ The offset at which to start the allocation. The length of the area that is allocated. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_close(fd: fd) -> errno` +#### `fd_close(fd: fd) -> Result<(), errno>` Close a file descriptor. Note: This is similar to `close` in POSIX. @@ -1318,12 +1496,21 @@ Note: This is similar to `close` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_datasync(fd: fd) -> errno` +#### `fd_datasync(fd: fd) -> Result<(), errno>` Synchronize the data of a file to disk. Note: This is similar to `fdatasync` in POSIX. @@ -1331,12 +1518,21 @@ Note: This is similar to `fdatasync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_fdstat_get(fd: fd) -> (errno, fdstat)` +#### `fd_fdstat_get(fd: fd) -> Result` Get the attributes of a file descriptor. Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. @@ -1344,15 +1540,22 @@ Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as ad - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `stat`: [`fdstat`](#fdstat) +- `error`: `Result` The buffer where the file descriptor's attributes are stored. +###### Variant Layout +- size: 32 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`fdstat`](#fdstat) + +- `err`: [`errno`](#errno) + --- -#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` Adjust the flags associated with a file descriptor. Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. @@ -1363,12 +1566,21 @@ Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. The desired values of the file descriptor flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` Adjust the rights associated with a file descriptor. This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights @@ -1381,27 +1593,43 @@ The desired rights of the file descriptor. - `fs_rights_inheriting`: [`rights`](#rights) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_filestat_get(fd: fd) -> (errno, filestat)` +#### `fd_filestat_get(fd: fd) -> Result` Return the attributes of an open file. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 64 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `fd_filestat_set_size(fd: fd, size: filesize) -> errno` +#### `fd_filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. Note: This is similar to `ftruncate` in POSIX. @@ -1412,12 +1640,21 @@ Note: This is similar to `ftruncate` in POSIX. The desired file size. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of an open file or directory. Note: This is similar to `futimens` in POSIX. @@ -1434,12 +1671,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` Read from a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `preadv` in POSIX. @@ -1453,30 +1699,44 @@ List of scatter/gather vectors in which to store data. The offset within the file at which to read. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_prestat_get(fd: fd) -> (errno, prestat)` +#### `fd_prestat_get(fd: fd) -> Result` Return a description of the given preopened file descriptor. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`prestat`](#prestat) +- `error`: `Result` The buffer where the description is stored. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`prestat`](#prestat) + +- `err`: [`errno`](#errno) + --- -#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` Return a description of the given preopened file descriptor. ##### Params @@ -1488,12 +1748,21 @@ A buffer into which to write the preopened directory name. - `path_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` Write to a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `pwritev` in POSIX. @@ -1507,15 +1776,22 @@ List of scatter/gather vectors from which to retrieve data. The offset within the file at which to write. ##### Results -- `error`: [`errno`](#errno) - -- `nwritten`: [`size`](#size) +- `error`: `Result` The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_read(fd: fd, iovs: iovec_array) -> (errno, size)` +#### `fd_read(fd: fd, iovs: iovec_array) -> Result` Read from a file descriptor. Note: This is similar to `readv` in POSIX. @@ -1526,15 +1802,22 @@ Note: This is similar to `readv` in POSIX. List of scatter/gather vectors to which to store data. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of directory entries. Each directory entry consists of a [`dirent`](#dirent) object, @@ -1557,15 +1840,22 @@ The buffer where directory entries are stored The location within the directory to start reading ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_renumber(fd: fd, to: fd) -> errno` +#### `fd_renumber(fd: fd, to: fd) -> Result<(), errno>` Atomically replace a file descriptor by renumbering another file descriptor. Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary @@ -1582,12 +1872,21 @@ would disappear if `dup2()` were to be removed entirely. The file descriptor to overwrite. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> Result` Move the offset of a file descriptor. Note: This is similar to `lseek` in POSIX. @@ -1601,15 +1900,22 @@ The number of bytes to move. The base from which the offset is relative. ##### Results -- `error`: [`errno`](#errno) - -- `newoffset`: [`filesize`](#filesize) +- `error`: `Result` The new offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `fd_sync(fd: fd) -> errno` +#### `fd_sync(fd: fd) -> Result<(), errno>` Synchronize the data and metadata of a file to disk. Note: This is similar to `fsync` in POSIX. @@ -1617,12 +1923,21 @@ Note: This is similar to `fsync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_tell(fd: fd) -> (errno, filesize)` +#### `fd_tell(fd: fd) -> Result` Return the current offset of a file descriptor. Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. @@ -1630,15 +1945,22 @@ Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `offset`: [`filesize`](#filesize) +- `error`: `Result` The current offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)` +#### `fd_write(fd: fd, iovs: ciovec_array) -> Result` Write to a file descriptor. Note: This is similar to `writev` in POSIX. @@ -1649,15 +1971,21 @@ Note: This is similar to `writev` in POSIX. List of scatter/gather vectors from which to retrieve data. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result` -- `nwritten`: [`size`](#size) -The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) --- -#### `path_create_directory(fd: fd, path: string) -> errno` +#### `path_create_directory(fd: fd, path: string) -> Result<(), errno>` Create a directory. Note: This is similar to `mkdirat` in POSIX. @@ -1668,12 +1996,21 @@ Note: This is similar to `mkdirat` in POSIX. The path at which to create the directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` Return the attributes of a file or directory. Note: This is similar to `stat` in POSIX. @@ -1687,15 +2024,22 @@ Flags determining the method of how the path is resolved. The path of the file or directory to inspect. ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 64 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of a file or directory. Note: This is similar to `utimensat` in POSIX. @@ -1718,12 +2062,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Create a hard link. Note: This is similar to `linkat` in POSIX. @@ -1743,12 +2096,21 @@ The working directory at which the resolution of the new path starts. The destination path at which to create the hard link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> (errno, fd)` +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> Result` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1765,7 +2127,7 @@ Flags determining the method of how the path is resolved. - `path`: `string` The relative path of the file or directory to open, relative to the -[`fd`](#fd) directory. +[`path_open::fd`](#path_open.fd) directory. - `oflags`: [`oflags`](#oflags) The method by which to open the file. @@ -1784,15 +2146,22 @@ file descriptors derived from it. - `fdflags`: [`fdflags`](#fdflags) ##### Results -- `error`: [`errno`](#errno) - -- `opened_fd`: [`fd`](#fd) +- `error`: `Result` The file descriptor of the file that has been opened. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`fd`](#fd) + +- `err`: [`errno`](#errno) + --- -#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` Read the contents of a symbolic link. Note: This is similar to `readlinkat` in POSIX. @@ -1808,15 +2177,22 @@ The buffer to which to write the contents of the symbolic link. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes placed in the buffer. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `path_remove_directory(fd: fd, path: string) -> errno` +#### `path_remove_directory(fd: fd, path: string) -> Result<(), errno>` Remove a directory. Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. @@ -1828,12 +2204,21 @@ Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. The path to a directory to remove. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Rename a file or directory. Note: This is similar to `renameat` in POSIX. @@ -1850,12 +2235,21 @@ The working directory at which the resolution of the new path starts. The destination path to which to rename the file or directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_symlink(old_path: string, fd: fd, new_path: string) -> errno` +#### `path_symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` Create a symbolic link. Note: This is similar to `symlinkat` in POSIX. @@ -1869,12 +2263,21 @@ The contents of the symbolic link. The destination path at which to create the symbolic link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_unlink_file(fd: fd, path: string) -> errno` +#### `path_unlink_file(fd: fd, path: string) -> Result<(), errno>` Unlink a file. Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. @@ -1886,12 +2289,21 @@ Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. The path to a file to unlink. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` Concurrently poll for the occurrence of a set of events. ##### Params @@ -1905,11 +2317,18 @@ The events that have occurred. Both the number of subscriptions and events. ##### Results -- `error`: [`errno`](#errno) - -- `nevents`: [`size`](#size) +- `error`: `Result` The number of events stored. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- @@ -1926,7 +2345,7 @@ The exit code returned by the process. --- -#### `proc_raise(sig: signal) -> errno` +#### `proc_raise(sig: signal) -> Result<(), errno>` Send a signal to the process of the calling thread. Note: This is similar to `raise` in POSIX. @@ -1935,23 +2354,41 @@ Note: This is similar to `raise` in POSIX. The signal condition to trigger. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sched_yield() -> errno` +#### `sched_yield() -> Result<(), errno>` Temporarily yield execution of the calling thread. Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `random_get(buf: Pointer, buf_len: size) -> errno` +#### `random_get(buf: Pointer, buf_len: size) -> Result<(), errno>` Write high-quality random data into a buffer. This function blocks when the implementation is unable to immediately provide sufficient high-quality random data. @@ -1966,12 +2403,21 @@ The buffer to fill with random data. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` Receive a message from a socket. Note: This is similar to `recv` in POSIX, though it also supports reading the data into multiple buffers in the manner of `readv`. @@ -1986,18 +2432,31 @@ List of scatter/gather vectors to which to store data. Message flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, roflags), errno>` +Number of bytes stored in ri_data and message flags. -- `ro_datalen`: [`size`](#size) -Number of bytes stored in ri_data. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, roflags)` -- `ro_flags`: [`roflags`](#roflags) -Message flags. +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`roflags`](#roflags) + +Offset: 4 + +- `err`: [`errno`](#errno) --- -#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` Send a message on a socket. Note: This is similar to `send` in POSIX, though it also supports writing the data from multiple buffers in the manner of `writev`. @@ -2012,15 +2471,22 @@ List of scatter/gather vectors to which to retrieve data Message flags. ##### Results -- `error`: [`errno`](#errno) - -- `so_datalen`: [`size`](#size) +- `error`: `Result` Number of bytes transmitted. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `sock_shutdown(fd: fd, how: sdflags) -> errno` +#### `sock_shutdown(fd: fd, how: sdflags) -> Result<(), errno>` Shut down socket send and receive channels. Note: This is similar to `shutdown` in POSIX. @@ -2031,5 +2497,14 @@ Note: This is similar to `shutdown` in POSIX. Which channels on the socket to shut down. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx index eb6f70020..f4ba78802 100644 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/random/phases/old/snapshot_0/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags (@witx bitflags u64) + (flags (@witx repr u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `rights::path_open` is set, includes the right to invoke @@ -379,7 +379,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -416,7 +416,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -430,7 +430,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags (@witx bitflags u32) + (flags (@witx repr u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -438,7 +438,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Create file if it does not exist. $creat ;;; Fail if not a directory. @@ -497,7 +497,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -532,7 +532,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -692,7 +692,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -702,7 +702,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -714,7 +714,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags (@witx bitflags u8) + (flags (@witx repr u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx index 0d16f1b18..5481882ae 100644 --- a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -20,15 +20,13 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; Returns the number of arguments and the size of the argument string + ;;; data, or an error. + (result $error (expected (tuple $size $size) (error $errno))) ) ;;; Read environment variable data. @@ -36,15 +34,13 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return environment variable data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno) - ;;; The number of environment variable arguments. - (result $environc $size) - ;;; The size of the environment variable data. - (result $environ_buf_size $size) + ;;; Returns the number of environment variable arguments and the size of the + ;;; environment variable data. + (result $error (expected (tuple $size $size) (error $errno))) ) ;;; Return the resolution of a clock. @@ -54,9 +50,8 @@ (@interface func (export "clock_res_get") ;;; The clock for which to return the resolution. (param $id $clockid) - (result $error $errno) - ;;; The resolution of the clock. - (result $resolution $timestamp) + ;;; The resolution of the clock, or an error if one happened. + (result $error (expected $timestamp (error $errno))) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. @@ -65,9 +60,8 @@ (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp) - (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp) + (result $error (expected $timestamp (error $errno))) ) ;;; Provide file advisory information on a file descriptor. @@ -80,7 +74,7 @@ (param $len $filesize) ;;; The advice. (param $advice $advice) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Force the allocation of space in a file. @@ -91,30 +85,29 @@ (param $offset $filesize) ;;; The length of the area that is allocated. (param $len $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat) + (result $error (expected $fdstat (error $errno))) ) ;;; Adjust the flags associated with a file descriptor. @@ -123,7 +116,7 @@ (param $fd $fd) ;;; The desired values of the file descriptor flags. (param $flags $fdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the rights associated with a file descriptor. @@ -133,15 +126,14 @@ ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. @@ -150,7 +142,7 @@ (param $fd $fd) ;;; The desired file size. (param $size $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the timestamps of an open file or directory. @@ -163,7 +155,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. @@ -174,17 +166,15 @@ (param $iovs $iovec_array) ;;; The offset within the file at which to read. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat) + (result $error (expected $prestat (error $errno))) ) ;;; Return a description of the given preopened file descriptor. @@ -193,7 +183,7 @@ ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. @@ -204,9 +194,8 @@ (param $iovs $ciovec_array) ;;; The offset within the file at which to write. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Read from a file descriptor. @@ -215,9 +204,8 @@ (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_array) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Read directory entries from a directory. @@ -237,9 +225,8 @@ (param $buf_len $size) ;;; The location within the directory to start reading (param $cookie $dircookie) - (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -256,7 +243,7 @@ (param $fd $fd) ;;; The file descriptor to overwrite. (param $to $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Move the offset of a file descriptor. @@ -267,25 +254,23 @@ (param $offset $filedelta) ;;; The base from which the offset is relative. (param $whence $whence) - (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd) - (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Write to a file descriptor. @@ -294,9 +279,7 @@ (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_array) - (result $error $errno) - ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Create a directory. @@ -305,7 +288,7 @@ (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of a file or directory. @@ -316,9 +299,8 @@ (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the timestamps of a file or directory. @@ -335,7 +317,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a hard link. @@ -350,7 +332,7 @@ (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Open a file or directory. @@ -367,7 +349,7 @@ ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the - ;;; `fd` directory. + ;;; `path_open::fd` directory. (param $path string) ;;; The method by which to open the file. (param $oflags $oflags) @@ -382,9 +364,8 @@ (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) - (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd) + (result $error (expected $fd (error $errno))) ) ;;; Read the contents of a symbolic link. @@ -396,9 +377,8 @@ ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Remove a directory. @@ -408,7 +388,7 @@ (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Rename a file or directory. @@ -421,7 +401,7 @@ (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a symbolic link. @@ -432,7 +412,7 @@ (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) @@ -443,7 +423,7 @@ (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Concurrently poll for the occurrence of a set of events. @@ -454,9 +434,8 @@ (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. (param $nsubscriptions $size) - (result $error $errno) ;;; The number of events stored. - (result $nevents $size) + (result $error (expected $size (error $errno))) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -473,13 +452,13 @@ (@interface func (export "proc_raise") ;;; The signal condition to trigger. (param $sig $signal) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write high-quality random data into a buffer. @@ -492,7 +471,7 @@ ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Receive a message from a socket. @@ -504,11 +483,8 @@ (param $ri_data $iovec_array) ;;; Message flags. (param $ri_flags $riflags) - (result $error $errno) - ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size) - ;;; Message flags. - (result $ro_flags $roflags) + ;;; Number of bytes stored in ri_data and message flags. + (result $error (expected (tuple $size $roflags) (error $errno))) ) ;;; Send a message on a socket. @@ -520,9 +496,8 @@ (param $si_data $ciovec_array) ;;; Message flags. (param $si_flags $siflags) - (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size) + (result $error (expected $size (error $errno))) ) ;;; Shut down socket send and receive channels. @@ -531,6 +506,6 @@ (param $fd $fd) ;;; Which channels on the socket to shut down. (param $how $sdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index 1bbbe59f2..c55a661b1 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -19,7 +19,7 @@ Size: 8 Alignment: 8 -## `clockid`: Variant +## `clockid`: `Variant` Identifiers for clocks. Size: 4 @@ -43,7 +43,7 @@ The CPU-time clock associated with the current process. - `thread_cputime_id` The CPU-time clock associated with the current thread. -## `errno`: Variant +## `errno`: `Variant` Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -285,114 +285,172 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: `u64` +## `rights`: `Record` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Constants -- `fd_datasync` +### Record members +- `fd_datasync`: `bool` The right to invoke [`fd_datasync`](#fd_datasync). If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). -- `fd_read` +Bit: 0 + +- `fd_read`: `bool` The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). -- `fd_seek` +Bit: 1 + +- `fd_seek`: `bool` The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). -- `fd_fdstat_set_flags` +Bit: 2 + +- `fd_fdstat_set_flags`: `bool` The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). -- `fd_sync` +Bit: 3 + +- `fd_sync`: `bool` The right to invoke [`fd_sync`](#fd_sync). If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). -- `fd_tell` +Bit: 4 + +- `fd_tell`: `bool` The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke [`fd_tell`](#fd_tell). -- `fd_write` +Bit: 5 + +- `fd_write`: `bool` The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). -- `fd_advise` +Bit: 6 + +- `fd_advise`: `bool` The right to invoke [`fd_advise`](#fd_advise). -- `fd_allocate` +Bit: 7 + +- `fd_allocate`: `bool` The right to invoke [`fd_allocate`](#fd_allocate). -- `path_create_directory` +Bit: 8 + +- `path_create_directory`: `bool` The right to invoke [`path_create_directory`](#path_create_directory). -- `path_create_file` +Bit: 9 + +- `path_create_file`: `bool` If [`path_open`](#path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). -- `path_link_source` +Bit: 10 + +- `path_link_source`: `bool` The right to invoke [`path_link`](#path_link) with the file descriptor as the source directory. -- `path_link_target` +Bit: 11 + +- `path_link_target`: `bool` The right to invoke [`path_link`](#path_link) with the file descriptor as the target directory. -- `path_open` +Bit: 12 + +- `path_open`: `bool` The right to invoke [`path_open`](#path_open). -- `fd_readdir` +Bit: 13 + +- `fd_readdir`: `bool` The right to invoke [`fd_readdir`](#fd_readdir). -- `path_readlink` +Bit: 14 + +- `path_readlink`: `bool` The right to invoke [`path_readlink`](#path_readlink). -- `path_rename_source` +Bit: 15 + +- `path_rename_source`: `bool` The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. -- `path_rename_target` +Bit: 16 + +- `path_rename_target`: `bool` The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. -- `path_filestat_get` +Bit: 17 + +- `path_filestat_get`: `bool` The right to invoke [`path_filestat_get`](#path_filestat_get). -- `path_filestat_set_size` +Bit: 18 + +- `path_filestat_set_size`: `bool` The right to change a file's size (there is no `path_filestat_set_size`). If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). -- `path_filestat_set_times` +Bit: 19 + +- `path_filestat_set_times`: `bool` The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). -- `fd_filestat_get` +Bit: 20 + +- `fd_filestat_get`: `bool` The right to invoke [`fd_filestat_get`](#fd_filestat_get). -- `fd_filestat_set_size` +Bit: 21 + +- `fd_filestat_set_size`: `bool` The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). -- `fd_filestat_set_times` +Bit: 22 + +- `fd_filestat_set_times`: `bool` The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). -- `path_symlink` +Bit: 23 + +- `path_symlink`: `bool` The right to invoke [`path_symlink`](#path_symlink). -- `path_remove_directory` +Bit: 24 + +- `path_remove_directory`: `bool` The right to invoke [`path_remove_directory`](#path_remove_directory). -- `path_unlink_file` +Bit: 25 + +- `path_unlink_file`: `bool` The right to invoke [`path_unlink_file`](#path_unlink_file). -- `poll_fd_readwrite` +Bit: 26 + +- `poll_fd_readwrite`: `bool` If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). -- `sock_shutdown` +Bit: 27 + +- `sock_shutdown`: `bool` The right to invoke [`sock_shutdown`](#sock_shutdown). -## `fd` +Bit: 28 + +## `fd`: `Handle` A file descriptor handle. Size: 4 @@ -400,7 +458,7 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Record +## `iovec`: `Record` A region of memory for scatter/gather reads. Size: 8 @@ -418,7 +476,7 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Record +## `ciovec`: `Record` A region of memory for scatter/gather writes. Size: 8 @@ -455,7 +513,7 @@ Size: 8 Alignment: 8 -## `whence`: Variant +## `whence`: `Variant` The position relative to which to set the offset of the file descriptor. Size: 1 @@ -495,7 +553,7 @@ Size: 8 Alignment: 8 -## `filetype`: Variant +## `filetype`: `Variant` The type of a file descriptor or file. Size: 1 @@ -527,7 +585,7 @@ The file descriptor or file refers to a byte-stream socket. - `symbolic_link` The file refers to a symbolic link inode. -## `dirent`: Record +## `dirent`: `Record` A directory entry. Size: 24 @@ -555,7 +613,7 @@ The type of the file referred to by this directory entry. Offset: 20 -## `advice`: Variant +## `advice`: `Variant` File or memory access pattern advisory information. Size: 1 @@ -581,32 +639,42 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: `u16` +## `fdflags`: `Record` File descriptor flags. Size: 2 Alignment: 2 -### Constants -- `append` +### Record members +- `append`: `bool` Append mode: Data written to the file is always appended to the file's end. -- `dsync` +Bit: 0 + +- `dsync`: `bool` Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. -- `nonblock` +Bit: 1 + +- `nonblock`: `bool` Non-blocking mode. -- `rsync` +Bit: 2 + +- `rsync`: `bool` Synchronized read I/O operations. -- `sync` +Bit: 3 + +- `sync`: `bool` Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Record +Bit: 4 + +## `fdstat`: `Record` File descriptor attributes. Size: 24 @@ -643,57 +711,75 @@ Size: 8 Alignment: 8 -## `fstflags`: `u16` +## `fstflags`: `Record` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Constants -- `atim` +### Record members +- `atim`: `bool` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). -- `atim_now` +Bit: 0 + +- `atim_now`: `bool` Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -- `mtim` +Bit: 1 + +- `mtim`: `bool` Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). -- `mtim_now` +Bit: 2 + +- `mtim_now`: `bool` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: `u32` +Bit: 3 + +## `lookupflags`: `Record` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Constants -- `symlink_follow` +### Record members +- `symlink_follow`: `bool` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: `u16` +Bit: 0 + +## `oflags`: `Record` Open flags used by [`path_open`](#path_open). Size: 2 Alignment: 2 -### Constants -- `creat` +### Record members +- `creat`: `bool` Create file if it does not exist. -- `directory` +Bit: 0 + +- `directory`: `bool` Fail if not a directory. -- `excl` +Bit: 1 + +- `excl`: `bool` Fail if file already exists. -- `trunc` +Bit: 2 + +- `trunc`: `bool` Truncate file to size 0. +Bit: 3 + ## `linkcount`: `u64` Number of hard links to an inode. @@ -701,7 +787,7 @@ Size: 8 Alignment: 8 -## `filestat`: Record +## `filestat`: `Record` File attributes. Size: 64 @@ -757,7 +843,7 @@ Size: 8 Alignment: 8 -## `eventtype`: Variant +## `eventtype`: `Variant` Type of a subscription to an event or its occurrence. Size: 1 @@ -777,7 +863,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: `u16` +## `eventrwflags`: `Record` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -785,11 +871,13 @@ Size: 2 Alignment: 2 -### Constants -- `fd_readwrite_hangup` +### Record members +- `fd_readwrite_hangup`: `bool` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Record +Bit: 0 + +## `event_fd_readwrite`: `Record` The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -808,7 +896,7 @@ The state of the file descriptor. Offset: 8 -## `event`: Record +## `event`: `Record` An event that occurred. Size: 32 @@ -837,7 +925,7 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read Offset: 16 -## `subclockflags`: `u16` +## `subclockflags`: `Record` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -845,15 +933,17 @@ Size: 2 Alignment: 2 -### Constants -- `subscription_clock_abstime` +### Record members +- `subscription_clock_abstime`: `bool` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock [`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Record +Bit: 0 + +## `subscription_clock`: `Record` The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 32 @@ -882,7 +972,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 24 -## `subscription_fd_readwrite`: Record +## `subscription_fd_readwrite`: `Record` The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -896,7 +986,7 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Variant +## `subscription_u`: `Variant` The contents of a [`subscription`](#subscription). Size: 40 @@ -914,7 +1004,7 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Record +## `subscription`: `Record` Subscription to an event. Size: 48 @@ -940,7 +1030,7 @@ Size: 4 Alignment: 4 -## `signal`: Variant +## `signal`: `Variant` Signal condition. Size: 1 @@ -1072,31 +1162,37 @@ Action: Terminates the process. Bad system call. Action: Terminates the process. -## `riflags`: `u16` +## `riflags`: `Record` Flags provided to [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Constants -- `recv_peek` +### Record members +- `recv_peek`: `bool` Returns the message without removing it from the socket's receive queue. -- `recv_waitall` +Bit: 0 + +- `recv_waitall`: `bool` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: `u16` +Bit: 1 + +## `roflags`: `Record` Flags returned by [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Constants -- `recv_data_truncated` +### Record members +- `recv_data_truncated`: `bool` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. +Bit: 0 + ## `siflags`: `u16` Flags provided to [`sock_send`](#sock_send). As there are currently no flags defined, it must be set to zero. @@ -1105,21 +1201,25 @@ Size: 2 Alignment: 2 -## `sdflags`: `u8` +## `sdflags`: `Record` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Constants -- `rd` +### Record members +- `rd`: `bool` Disables further receive operations. -- `wr` +Bit: 0 + +- `wr`: `bool` Disables further send operations. -## `preopentype`: Variant +Bit: 1 + +## `preopentype`: `Variant` Identifiers for preopened capabilities. Size: 1 @@ -1130,7 +1230,7 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Record +## `prestat_dir`: `Record` The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). Size: 4 @@ -1143,7 +1243,7 @@ The length of the directory name for use with [`fd_prestat_dir_name`](#fd_presta Offset: 0 -## `prestat`: Variant +## `prestat`: `Variant` Information about a pre-opened capability. Size: 8 @@ -1165,7 +1265,7 @@ Alignment: 4 --- -#### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` +#### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) @@ -1175,28 +1275,51 @@ The size of the array should match that returned by [`args_sizes_get`](#args_siz - `argv_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `args_sizes_get() -> (errno, size, size)` +#### `args_sizes_get() -> Result<(size, size), errno>` Return command-line argument data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of arguments and the size of the argument string +data, or an error. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) -- `argc`: [`size`](#size) -The number of arguments. +Offset: 0 + +- `1`: [`size`](#size) + +Offset: 4 -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `err`: [`errno`](#errno) --- -#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` +#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). @@ -1206,28 +1329,51 @@ The sizes of the buffers should match that returned by [`environ_sizes_get`](#en - `environ_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `environ_sizes_get() -> (errno, size, size)` +#### `environ_sizes_get() -> Result<(size, size), errno>` Return environment variable data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of environment variable arguments and the size of the +environment variable data. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`size`](#size) -- `environc`: [`size`](#size) -The number of environment variable arguments. +Offset: 4 -- `environ_buf_size`: [`size`](#size) -The size of the environment variable data. +- `err`: [`errno`](#errno) --- -#### `clock_res_get(id: clockid) -> (errno, timestamp)` +#### `clock_res_get(id: clockid) -> Result` Return the resolution of a clock. Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return [`errno::inval`](#errno.inval). @@ -1238,15 +1384,22 @@ Note: This is similar to `clock_getres` in POSIX. The clock for which to return the resolution. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result` +The resolution of the clock, or an error if one happened. + +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) -- `resolution`: [`timestamp`](#timestamp) -The resolution of the clock. +- `err`: [`errno`](#errno) --- -#### `clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +#### `clock_time_get(id: clockid, precision: timestamp) -> Result` Return the time value of a clock. Note: This is similar to `clock_gettime` in POSIX. @@ -1258,15 +1411,22 @@ The clock for which to return the time. The maximum lag (exclusive) that the returned time value may have, compared to its actual value. ##### Results -- `error`: [`errno`](#errno) - -- `time`: [`timestamp`](#timestamp) +- `error`: `Result` The time value of the clock. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) + +- `err`: [`errno`](#errno) + --- -#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` Provide file advisory information on a file descriptor. Note: This is similar to `posix_fadvise` in POSIX. @@ -1283,12 +1443,21 @@ The length of the region to which the advisory applies. The advice. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno` +#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` Force the allocation of space in a file. Note: This is similar to `posix_fallocate` in POSIX. @@ -1302,12 +1471,21 @@ The offset at which to start the allocation. The length of the area that is allocated. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_close(fd: fd) -> errno` +#### `fd_close(fd: fd) -> Result<(), errno>` Close a file descriptor. Note: This is similar to `close` in POSIX. @@ -1315,12 +1493,21 @@ Note: This is similar to `close` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_datasync(fd: fd) -> errno` +#### `fd_datasync(fd: fd) -> Result<(), errno>` Synchronize the data of a file to disk. Note: This is similar to `fdatasync` in POSIX. @@ -1328,12 +1515,21 @@ Note: This is similar to `fdatasync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_fdstat_get(fd: fd) -> (errno, fdstat)` +#### `fd_fdstat_get(fd: fd) -> Result` Get the attributes of a file descriptor. Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. @@ -1341,15 +1537,22 @@ Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as ad - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `stat`: [`fdstat`](#fdstat) +- `error`: `Result` The buffer where the file descriptor's attributes are stored. +###### Variant Layout +- size: 32 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`fdstat`](#fdstat) + +- `err`: [`errno`](#errno) + --- -#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` Adjust the flags associated with a file descriptor. Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. @@ -1360,12 +1563,21 @@ Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. The desired values of the file descriptor flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` Adjust the rights associated with a file descriptor. This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights @@ -1378,27 +1590,43 @@ The desired rights of the file descriptor. - `fs_rights_inheriting`: [`rights`](#rights) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_filestat_get(fd: fd) -> (errno, filestat)` +#### `fd_filestat_get(fd: fd) -> Result` Return the attributes of an open file. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 72 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `fd_filestat_set_size(fd: fd, size: filesize) -> errno` +#### `fd_filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. Note: This is similar to `ftruncate` in POSIX. @@ -1409,12 +1637,21 @@ Note: This is similar to `ftruncate` in POSIX. The desired file size. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of an open file or directory. Note: This is similar to `futimens` in POSIX. @@ -1431,12 +1668,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` Read from a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `preadv` in POSIX. @@ -1450,30 +1696,44 @@ List of scatter/gather vectors in which to store data. The offset within the file at which to read. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_prestat_get(fd: fd) -> (errno, prestat)` +#### `fd_prestat_get(fd: fd) -> Result` Return a description of the given preopened file descriptor. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`prestat`](#prestat) +- `error`: `Result` The buffer where the description is stored. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`prestat`](#prestat) + +- `err`: [`errno`](#errno) + --- -#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` Return a description of the given preopened file descriptor. ##### Params @@ -1485,12 +1745,21 @@ A buffer into which to write the preopened directory name. - `path_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` Write to a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `pwritev` in POSIX. @@ -1504,15 +1773,22 @@ List of scatter/gather vectors from which to retrieve data. The offset within the file at which to write. ##### Results -- `error`: [`errno`](#errno) - -- `nwritten`: [`size`](#size) +- `error`: `Result` The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_read(fd: fd, iovs: iovec_array) -> (errno, size)` +#### `fd_read(fd: fd, iovs: iovec_array) -> Result` Read from a file descriptor. Note: This is similar to `readv` in POSIX. @@ -1523,15 +1799,22 @@ Note: This is similar to `readv` in POSIX. List of scatter/gather vectors to which to store data. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of directory entries. Each directory entry consists of a [`dirent`](#dirent) object, @@ -1554,15 +1837,22 @@ The buffer where directory entries are stored The location within the directory to start reading ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_renumber(fd: fd, to: fd) -> errno` +#### `fd_renumber(fd: fd, to: fd) -> Result<(), errno>` Atomically replace a file descriptor by renumbering another file descriptor. Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary @@ -1579,12 +1869,21 @@ would disappear if `dup2()` were to be removed entirely. The file descriptor to overwrite. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> Result` Move the offset of a file descriptor. Note: This is similar to `lseek` in POSIX. @@ -1598,15 +1897,22 @@ The number of bytes to move. The base from which the offset is relative. ##### Results -- `error`: [`errno`](#errno) - -- `newoffset`: [`filesize`](#filesize) +- `error`: `Result` The new offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `fd_sync(fd: fd) -> errno` +#### `fd_sync(fd: fd) -> Result<(), errno>` Synchronize the data and metadata of a file to disk. Note: This is similar to `fsync` in POSIX. @@ -1614,12 +1920,21 @@ Note: This is similar to `fsync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_tell(fd: fd) -> (errno, filesize)` +#### `fd_tell(fd: fd) -> Result` Return the current offset of a file descriptor. Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. @@ -1627,15 +1942,22 @@ Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `offset`: [`filesize`](#filesize) +- `error`: `Result` The current offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)` +#### `fd_write(fd: fd, iovs: ciovec_array) -> Result` Write to a file descriptor. Note: This is similar to `writev` in POSIX. @@ -1646,15 +1968,21 @@ Note: This is similar to `writev` in POSIX. List of scatter/gather vectors from which to retrieve data. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result` -- `nwritten`: [`size`](#size) -The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) --- -#### `path_create_directory(fd: fd, path: string) -> errno` +#### `path_create_directory(fd: fd, path: string) -> Result<(), errno>` Create a directory. Note: This is similar to `mkdirat` in POSIX. @@ -1665,12 +1993,21 @@ Note: This is similar to `mkdirat` in POSIX. The path at which to create the directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` Return the attributes of a file or directory. Note: This is similar to `stat` in POSIX. @@ -1684,15 +2021,22 @@ Flags determining the method of how the path is resolved. The path of the file or directory to inspect. ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 72 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of a file or directory. Note: This is similar to `utimensat` in POSIX. @@ -1715,12 +2059,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Create a hard link. Note: This is similar to `linkat` in POSIX. @@ -1740,12 +2093,21 @@ The working directory at which the resolution of the new path starts. The destination path at which to create the hard link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> (errno, fd)` +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> Result` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1781,15 +2143,22 @@ file descriptors derived from it. - `fdflags`: [`fdflags`](#fdflags) ##### Results -- `error`: [`errno`](#errno) - -- `opened_fd`: [`fd`](#fd) +- `error`: `Result` The file descriptor of the file that has been opened. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`fd`](#fd) + +- `err`: [`errno`](#errno) + --- -#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` Read the contents of a symbolic link. Note: This is similar to `readlinkat` in POSIX. @@ -1805,15 +2174,22 @@ The buffer to which to write the contents of the symbolic link. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes placed in the buffer. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `path_remove_directory(fd: fd, path: string) -> errno` +#### `path_remove_directory(fd: fd, path: string) -> Result<(), errno>` Remove a directory. Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. @@ -1825,12 +2201,21 @@ Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. The path to a directory to remove. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Rename a file or directory. Note: This is similar to `renameat` in POSIX. @@ -1847,12 +2232,21 @@ The working directory at which the resolution of the new path starts. The destination path to which to rename the file or directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_symlink(old_path: string, fd: fd, new_path: string) -> errno` +#### `path_symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` Create a symbolic link. Note: This is similar to `symlinkat` in POSIX. @@ -1866,12 +2260,21 @@ The contents of the symbolic link. The destination path at which to create the symbolic link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_unlink_file(fd: fd, path: string) -> errno` +#### `path_unlink_file(fd: fd, path: string) -> Result<(), errno>` Unlink a file. Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. @@ -1883,12 +2286,21 @@ Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. The path to a file to unlink. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` Concurrently poll for the occurrence of a set of events. ##### Params @@ -1902,11 +2314,18 @@ The events that have occurred. Both the number of subscriptions and events. ##### Results -- `error`: [`errno`](#errno) - -- `nevents`: [`size`](#size) +- `error`: `Result` The number of events stored. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- @@ -1923,7 +2342,7 @@ The exit code returned by the process. --- -#### `proc_raise(sig: signal) -> errno` +#### `proc_raise(sig: signal) -> Result<(), errno>` Send a signal to the process of the calling thread. Note: This is similar to `raise` in POSIX. @@ -1932,23 +2351,41 @@ Note: This is similar to `raise` in POSIX. The signal condition to trigger. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sched_yield() -> errno` +#### `sched_yield() -> Result<(), errno>` Temporarily yield execution of the calling thread. Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `random_get(buf: Pointer, buf_len: size) -> errno` +#### `random_get(buf: Pointer, buf_len: size) -> Result<(), errno>` Write high-quality random data into a buffer. This function blocks when the implementation is unable to immediately provide sufficient high-quality random data. @@ -1963,12 +2400,21 @@ The buffer to fill with random data. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` Receive a message from a socket. Note: This is similar to `recv` in POSIX, though it also supports reading the data into multiple buffers in the manner of `readv`. @@ -1983,18 +2429,31 @@ List of scatter/gather vectors to which to store data. Message flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, roflags), errno>` +Number of bytes stored in ri_data and message flags. -- `ro_datalen`: [`size`](#size) -Number of bytes stored in ri_data. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, roflags)` -- `ro_flags`: [`roflags`](#roflags) -Message flags. +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`roflags`](#roflags) + +Offset: 4 + +- `err`: [`errno`](#errno) --- -#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` Send a message on a socket. Note: This is similar to `send` in POSIX, though it also supports writing the data from multiple buffers in the manner of `writev`. @@ -2009,15 +2468,22 @@ List of scatter/gather vectors to which to retrieve data Message flags. ##### Results -- `error`: [`errno`](#errno) - -- `so_datalen`: [`size`](#size) +- `error`: `Result` Number of bytes transmitted. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `sock_shutdown(fd: fd, how: sdflags) -> errno` +#### `sock_shutdown(fd: fd, how: sdflags) -> Result<(), errno>` Shut down socket send and receive channels. Note: This is similar to `shutdown` in POSIX. @@ -2028,5 +2494,14 @@ Note: This is similar to `shutdown` in POSIX. Which channels on the socket to shut down. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx index 70e726553..311b42233 100644 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ b/proposals/random/phases/snapshot/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags (@witx bitflags u64) + (flags (@witx repr u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke @@ -381,7 +381,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -418,7 +418,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -432,7 +432,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags (@witx bitflags u32) + (flags (@witx repr u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -440,7 +440,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Create file if it does not exist. $creat ;;; Fail if not a directory. @@ -499,7 +499,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -534,7 +534,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -693,7 +693,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -703,7 +703,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -715,7 +715,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags (@witx bitflags u8) + (flags (@witx repr u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx index eacfab268..df3c670f3 100644 --- a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -17,15 +17,13 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; Returns the number of arguments and the size of the argument string + ;;; data, or an error. + (result $error (expected (tuple $size $size) (error $errno))) ) ;;; Read environment variable data. @@ -33,15 +31,13 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return environment variable data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno) - ;;; The number of environment variable arguments. - (result $environc $size) - ;;; The size of the environment variable data. - (result $environ_buf_size $size) + ;;; Returns the number of environment variable arguments and the size of the + ;;; environment variable data. + (result $error (expected (tuple $size $size) (error $errno))) ) ;;; Return the resolution of a clock. @@ -51,9 +47,8 @@ (@interface func (export "clock_res_get") ;;; The clock for which to return the resolution. (param $id $clockid) - (result $error $errno) - ;;; The resolution of the clock. - (result $resolution $timestamp) + ;;; The resolution of the clock, or an error if one happened. + (result $error (expected $timestamp (error $errno))) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. @@ -62,9 +57,8 @@ (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp) - (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp) + (result $error (expected $timestamp (error $errno))) ) ;;; Provide file advisory information on a file descriptor. @@ -77,7 +71,7 @@ (param $len $filesize) ;;; The advice. (param $advice $advice) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Force the allocation of space in a file. @@ -88,30 +82,29 @@ (param $offset $filesize) ;;; The length of the area that is allocated. (param $len $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat) + (result $error (expected $fdstat (error $errno))) ) ;;; Adjust the flags associated with a file descriptor. @@ -120,7 +113,7 @@ (param $fd $fd) ;;; The desired values of the file descriptor flags. (param $flags $fdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the rights associated with a file descriptor. @@ -130,15 +123,14 @@ ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. @@ -147,7 +139,7 @@ (param $fd $fd) ;;; The desired file size. (param $size $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the timestamps of an open file or directory. @@ -160,7 +152,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. @@ -171,17 +163,15 @@ (param $iovs $iovec_array) ;;; The offset within the file at which to read. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat) + (result $error (expected $prestat (error $errno))) ) ;;; Return a description of the given preopened file descriptor. @@ -190,7 +180,7 @@ ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. @@ -201,9 +191,8 @@ (param $iovs $ciovec_array) ;;; The offset within the file at which to write. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Read from a file descriptor. @@ -212,9 +201,8 @@ (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_array) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Read directory entries from a directory. @@ -234,9 +222,8 @@ (param $buf_len $size) ;;; The location within the directory to start reading (param $cookie $dircookie) - (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -253,7 +240,7 @@ (param $fd $fd) ;;; The file descriptor to overwrite. (param $to $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Move the offset of a file descriptor. @@ -264,25 +251,23 @@ (param $offset $filedelta) ;;; The base from which the offset is relative. (param $whence $whence) - (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd) - (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Write to a file descriptor. @@ -291,9 +276,7 @@ (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_array) - (result $error $errno) - ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Create a directory. @@ -302,7 +285,7 @@ (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of a file or directory. @@ -313,9 +296,8 @@ (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the timestamps of a file or directory. @@ -332,7 +314,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a hard link. @@ -347,7 +329,7 @@ (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Open a file or directory. @@ -379,9 +361,8 @@ (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) - (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd) + (result $error (expected $fd (error $errno))) ) ;;; Read the contents of a symbolic link. @@ -393,9 +374,8 @@ ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Remove a directory. @@ -405,7 +385,7 @@ (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Rename a file or directory. @@ -418,7 +398,7 @@ (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a symbolic link. @@ -429,7 +409,7 @@ (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) @@ -440,7 +420,7 @@ (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Concurrently poll for the occurrence of a set of events. @@ -451,9 +431,8 @@ (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. (param $nsubscriptions $size) - (result $error $errno) ;;; The number of events stored. - (result $nevents $size) + (result $error (expected $size (error $errno))) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -470,13 +449,13 @@ (@interface func (export "proc_raise") ;;; The signal condition to trigger. (param $sig $signal) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write high-quality random data into a buffer. @@ -489,7 +468,7 @@ ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Receive a message from a socket. @@ -501,11 +480,8 @@ (param $ri_data $iovec_array) ;;; Message flags. (param $ri_flags $riflags) - (result $error $errno) - ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size) - ;;; Message flags. - (result $ro_flags $roflags) + ;;; Number of bytes stored in ri_data and message flags. + (result $error (expected (tuple $size $roflags) (error $errno))) ) ;;; Send a message on a socket. @@ -517,9 +493,8 @@ (param $si_data $ciovec_array) ;;; Message flags. (param $si_flags $siflags) - (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size) + (result $error (expected $size (error $errno))) ) ;;; Shut down socket send and receive channels. @@ -528,6 +503,6 @@ (param $fd $fd) ;;; Which channels on the socket to shut down. (param $how $sdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index bf9ce16cd..bd4bfc076 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.8" +version = "0.9.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" @@ -17,7 +17,7 @@ crate-type=["rlib"] anyhow = "1" log = "0.4" thiserror = "1.0" -wast = { version = "22.0.0", default-features = false } +wast = { version = "33.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" diff --git a/proposals/random/tools/witx/src/abi.rs b/proposals/random/tools/witx/src/abi.rs new file mode 100644 index 000000000..0e1ca9cb4 --- /dev/null +++ b/proposals/random/tools/witx/src/abi.rs @@ -0,0 +1,925 @@ +//! Definition of the ABI of witx functions +//! +//! This module is intended to assist with code generators which are binding or +//! implementing APIs defined by `*.witx` files. THis module contains all +//! details necessary to implement the actual ABI of these functions so wasm +//! modules and hosts can communicate with one another. +//! +//! Each interface types function (a function defined in `*.witx`) currently has +//! a well-known wasm signature associated with it. There's then also a standard +//! way to convert from interface-types values (whose representation is defined +//! per-language) into this wasm API. This module is intended to assist with +//! this definition. +//! +//! Contained within are two primary functions, [`InterfaceFunc::call_wasm`] and +//! [`InterfaceFunc::call_interface`]. These functions implement the two ways to +//! interact with an interface types function, namely calling the raw wasm +//! version and calling the high-level version with interface types. These two +//! functions are fed a structure that implements [`Bindgen`]. An instance of +//! [`Bindgen`] receives instructions which are low-level implementation details +//! of how to convert to and from wasm types and interface types. Code +//! generators will need to implement the various instructions to support APIs. + +use crate::{ + BuiltinType, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, NamedType, Type, TypeRef, +}; + +/// Enumerates wasm types used by interface types when lowering/lifting. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum WasmType { + I32, + I64, + F32, + F64, + // NOTE: we don't lower interface types to any other Wasm type, + // e.g. externref, so we don't need to define them here. +} + +impl From for WasmType { + fn from(i: IntRepr) -> WasmType { + match i { + IntRepr::U8 | IntRepr::U16 | IntRepr::U32 => WasmType::I32, + IntRepr::U64 => WasmType::I64, + } + } +} + +/// Possible ABIs for interface functions to have. +/// +/// Note that this is a stopgap until we have more of interface types. Interface +/// types functions do not have ABIs, they have APIs. For the meantime, however, +/// we mandate ABIs to ensure we can all talk to each other. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum Abi { + /// Only stable ABI currently, and is the historical WASI ABI since it was + /// first created. + /// + /// Note that this ABI is limited notably in its return values where it can + /// only return 0 results or one `Result` lookalike. + Preview1, +} + +// Helper macro for defining instructions without having to have tons of +// exhaustive `match` statements to update +macro_rules! def_instruction { + ( + $( #[$enum_attr:meta] )* + pub enum Instruction<'a> { + $( + $( #[$attr:meta] )* + $variant:ident $( { + $($field:ident : $field_ty:ty $(,)* )* + } )? + : + [$num_popped:expr] => [$num_pushed:expr], + )* + } + ) => { + $( #[$enum_attr] )* + pub enum Instruction<'a> { + $( + $( #[$attr] )* + $variant $( { + $( + $field : $field_ty, + )* + } )? , + )* + } + + impl Instruction<'_> { + /// How many operands does this instruction pop from the stack? + #[allow(unused_variables)] + pub fn operands_len(&self) -> usize { + match self { + $( + Self::$variant $( { + $( + $field, + )* + } )? => $num_popped, + )* + } + } + + /// How many results does this instruction push onto the stack? + #[allow(unused_variables)] + pub fn results_len(&self) -> usize { + match self { + $( + Self::$variant $( { + $( + $field, + )* + } )? => $num_pushed, + )* + } + } + } + }; +} + +def_instruction! { + #[derive(Debug)] + pub enum Instruction<'a> { + /// Acquires the specified parameter and places it on the stack. + /// Depending on the context this may refer to wasm parameters or + /// interface types parameters. + GetArg { nth: usize } : [0] => [1], + /// Takes the value off the top of the stack and writes it into linear + /// memory. Pushes the address in linear memory as an `i32`. + AddrOf : [1] => [1], + /// Converts an interface type `char` value to a 32-bit integer + /// representing the unicode scalar value. + I32FromChar : [1] => [1], + /// Converts an interface type `u64` value to a wasm `i64`. + I64FromU64 : [1] => [1], + /// Converts an interface type `s64` value to a wasm `i64`. + I64FromS64 : [1] => [1], + /// Converts an interface type `u32` value to a wasm `i32`. + I32FromU32 : [1] => [1], + /// Converts an interface type `s32` value to a wasm `i32`. + I32FromS32 : [1] => [1], + /// Converts a language-specific `usize` value to a wasm `i32`. + I32FromUsize : [1] => [1], + /// Converts an interface type `u16` value to a wasm `i32`. + I32FromU16 : [1] => [1], + /// Converts an interface type `s16` value to a wasm `i32`. + I32FromS16 : [1] => [1], + /// Converts an interface type `u8` value to a wasm `i32`. + I32FromU8 : [1] => [1], + /// Converts an interface type `s8` value to a wasm `i32`. + I32FromS8 : [1] => [1], + /// Converts a language-specific C `char` value to a wasm `i32`. + I32FromChar8 : [1] => [1], + /// Converts a language-specific pointer value to a wasm `i32`. + I32FromPointer : [1] => [1], + /// Converts a language-specific pointer value to a wasm `i32`. + I32FromConstPointer : [1] => [1], + /// Converts a language-specific handle value to a wasm `i32`. + I32FromHandle { ty: &'a NamedType } : [1] => [1], + /// Converts a language-specific record-of-bools to the packed + /// representation as an `i32`. + I32FromBitflags { ty: &'a NamedType } : [1] => [1], + /// Converts a language-specific record-of-bools to the packed + /// representation as an `i64`. + I64FromBitflags { ty: &'a NamedType } : [1] => [1], + /// Converts an interface type list into its pointer/length, pushing + /// them both on the stack. + ListPointerLength : [1] => [2], + /// Pops two `i32` values from the stack and creates a list from them of + /// the specified type. The first operand is the pointer in linear + /// memory to the start of the list and the second operand is the + /// length. + ListFromPointerLength { ty: &'a TypeRef } : [2] => [1], + /// Conversion an interface type `f32` value to a wasm `f32`. + /// + /// This may be a noop for some implementations, but it's here in case the + /// native language representation of `f32` is different than the wasm + /// representation of `f32`. + F32FromIf32 : [1] => [1], + /// Conversion an interface type `f64` value to a wasm `f64`. + /// + /// This may be a noop for some implementations, but it's here in case the + /// native language representation of `f64` is different than the wasm + /// representation of `f64`. + F64FromIf64 : [1] => [1], + + /// Represents a call to a raw WebAssembly API. The module/name are + /// provided inline as well as the types if necessary. + CallWasm { + module: &'a str, + name: &'a str, + params: &'a [WasmType], + results: &'a [WasmType], + } : [params.len()] => [results.len()], + + /// Same as `CallWasm`, except the dual where an interface is being + /// called rather than a raw wasm function. + CallInterface { + module: &'a str, + func: &'a InterfaceFunc, + } : [func.params.len()] => [func.results.len()], + + /// Converts a native wasm `i32` to an interface type `s8`. + /// + /// This will truncate the upper bits of the `i32`. + S8FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `u8`. + /// + /// This will truncate the upper bits of the `i32`. + U8FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `s16`. + /// + /// This will truncate the upper bits of the `i32`. + S16FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `u16`. + /// + /// This will truncate the upper bits of the `i32`. + U16FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `s32`. + S32FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `u32`. + U32FromI32 : [1] => [1], + /// Converts a native wasm `i64` to an interface type `s64`. + S64FromI64 : [1] => [1], + /// Converts a native wasm `i64` to an interface type `u64`. + U64FromI64 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `char`. + /// + /// It's safe to assume that the `i32` is indeed a valid unicode code point. + CharFromI32 : [1] => [1], + /// Converts a native wasm `i32` to a language-specific C `char`. + /// + /// This will truncate the upper bits of the `i32`. + Char8FromI32 : [1] => [1], + /// Converts a native wasm `i32` to a language-specific `usize`. + UsizeFromI32 : [1] => [1], + /// Converts a native wasm `f32` to an interface type `f32`. + If32FromF32 : [1] => [1], + /// Converts a native wasm `f64` to an interface type `f64`. + If64FromF64 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `handle`. + HandleFromI32 { ty: &'a NamedType } : [1] => [1], + /// Converts a native wasm `i32` to a language-specific pointer. + PointerFromI32 { ty: &'a TypeRef }: [1] => [1], + /// Converts a native wasm `i32` to a language-specific pointer. + ConstPointerFromI32 { ty: &'a TypeRef } : [1] => [1], + /// Converts a native wasm `i32` to a language-specific record-of-bools. + BitflagsFromI32 { ty: &'a NamedType } : [1] => [1], + /// Converts a native wasm `i64` to a language-specific record-of-bools. + BitflagsFromI64 { ty: &'a NamedType } : [1] => [1], + /// Acquires the return pointer `n` and pushes an `i32` on the stack. + /// + /// Implementations of [`Bindgen`] may have [`Bindgen::allocate_space`] + /// called to reserve space in memory for the result of a computation to + /// get written. This instruction acquires a pointer to the space + /// reserved in `allocate_space`. + ReturnPointerGet { n: usize } : [0] => [1], + /// Loads the interface types value from an `i32` pointer popped from + /// the stack. + Load { ty: &'a NamedType } : [1] => [1], + /// Stores an interface types value into linear memory. The first + /// operand is the value to store and the second operand is the pointer + /// in linear memory to store it at. + Store { ty: &'a NamedType } : [2] => [0], + /// Pops a native wasm `i32` from the stack, as well as two blocks + /// internally from the code generator. + /// + /// If the value is 0 then the first "ok" block value should be used. + /// If the value is anything else then the second "err" block value + /// should be used, and the value is used as the error enum. + /// + /// Note that this is a special instruction matching the current ABI of + /// WASI and intentionally differs from the type-level grammar of + /// interface types results. + ResultLift : [1] => [1], + /// Pops a native interface value from the stack as well as two blocks + /// internally from the code generator. + /// + /// A `match` is performed on the value popped and the corresponding + /// block for ok/err is used depending on value. This pushes a single + /// `i32` onto the stack representing the error code for this result. + /// + /// Note that like `ResultLift` this is specialized to the current WASI + /// ABI. + ResultLower { + ok: Option<&'a TypeRef>, + err: Option<&'a TypeRef>, + } : [1] => [1], + /// Converts a native wasm `i32` to an interface type `enum` value. + /// + /// It's guaranteed that the interface type integer value is within + /// range for this enum's type. Additionally `ty` is guaranteed to be + /// enum-like as a `Variant` where all `case` arms have no associated + /// type with them. The purpose of this instruction is to convert a + /// native wasm integer into the enum type for the interface. + EnumLift { ty: &'a NamedType } : [1] => [1], + /// Converts an interface types enum value into a wasm `i32`. + EnumLower { ty: &'a NamedType } : [1] => [1], + /// Creates a tuple from the top `n` elements on the stack, pushing the + /// tuple onto the stack. + TupleLift { amt: usize } : [*amt] => [1], + /// Splits a tuple at the top of the stack into its `n` components, + /// pushing them all onto the stack. + TupleLower { amt: usize } : [1] => [*amt], + /// This is a special instruction specifically for the original ABI of + /// WASI. The raw return `i32` of a function is re-pushed onto the + /// stack for reuse. + ReuseReturn : [0] => [1], + /// Returns `amt` values on the stack. This is always the last + /// instruction. + Return { amt: usize } : [*amt] => [0], + /// This is a special instruction used at the entry of blocks used as + /// part of `ResultLower`, representing that the payload of that variant + /// being matched on should be pushed onto the stack. + VariantPayload : [0] => [1], + } +} + +impl Abi { + /// Validates the parameters/results are representable in this ABI. + /// + /// Returns an error string if they're not representable or returns `Ok` if + /// they're indeed representable. + pub fn validate( + &self, + _params: &[InterfaceFuncParam], + results: &[InterfaceFuncParam], + ) -> Result<(), String> { + assert_eq!(*self, Abi::Preview1); + match results.len() { + 0 => {} + 1 => match &**results[0].tref.type_() { + Type::Handle(_) | Type::Builtin(_) | Type::ConstPointer(_) | Type::Pointer(_) => {} + Type::Variant(v) => { + let (ok, err) = match v.as_expected() { + Some(pair) => pair, + None => return Err("invalid return type".to_string()), + }; + if let Some(ty) = ok { + match &**ty.type_() { + Type::Record(r) if r.is_tuple() => { + for member in r.members.iter() { + if !member.tref.named() { + return Err( + "only named types are allowed in results".to_string() + ); + } + } + } + _ => { + if !ty.named() { + return Err( + "only named types are allowed in results".to_string() + ); + } + } + } + } + if let Some(ty) = err { + if !ty.named() { + return Err("only named types are allowed in results".to_string()); + } + if let Type::Variant(v) = &**ty.type_() { + if v.is_enum() { + return Ok(()); + } + } + } + } + Type::Record(r) if r.bitflags_repr().is_some() => {} + Type::Record(_) | Type::List(_) => return Err("invalid return type".to_string()), + }, + _ => return Err("more than one result".to_string()), + } + Ok(()) + } +} + +/// Trait for language implementors to use to generate glue code between native +/// WebAssembly signatures and interface types signatures. +/// +/// This is used as an implementation detail in interpreting the ABI between +/// interface types and wasm types. Eventually this will be driven by interface +/// types adapters themselves, but for now the ABI of a function dictates what +/// instructions are fed in. +/// +/// Types implementing `Bindgen` are incrementally fed `Instruction` values to +/// generate code for. Instructions operate like a stack machine where each +/// instruction has a list of inputs and a list of outputs (provided by the +/// `emit` function). +pub trait Bindgen { + /// The intermediate type for fragments of code for this type. + /// + /// For most languages `String` is a suitable intermediate type. + type Operand; + + /// Emit code to implement the given instruction. + /// + /// Each operand is given in `operands` and can be popped off if ownership + /// is required. It's guaranteed that `operands` has the appropriate length + /// for the `inst` given, as specified with [`Instruction`]. + /// + /// Each result variable should be pushed onto `results`. This function must + /// push the appropriate number of results or binding generation will panic. + fn emit( + &mut self, + inst: &Instruction<'_>, + operands: &mut Vec, + results: &mut Vec, + ); + + /// Allocates temporary space in linear memory indexed by `slot` with enough + /// space to store `ty`. + /// + /// This is called when calling some wasm functions where a return pointer + /// is needed. + fn allocate_space(&mut self, slot: usize, ty: &NamedType); + + /// Enters a new block of code to generate code for. + /// + /// This is currently exclusively used for constructing variants. When a + /// variant is constructed a block here will be pushed for each case of a + /// variant, generating the code necessary to translate a variant case. + /// + /// Blocks are completed with `finish_block` below. It's expected that `emit` + /// will always push code (if necessary) into the "current block", which is + /// updated by calling this method and `finish_block` below. + fn push_block(&mut self); + + /// Indicates to the code generator that a block is completed, and the + /// `operand` specified was the resulting value of the block. + /// + /// This method will be used to compute the value of each arm of lifting a + /// variant. The `operand` will be `None` if the variant case didn't + /// actually have any type associated with it. Otherwise it will be `Some` + /// as the last value remaining on the stack representing the value + /// associated with a variant's `case`. + /// + /// It's expected that this will resume code generation in the previous + /// block before `push_block` was called. This must also save the results + /// of the current block internally for instructions like `ResultLift` to + /// use later. + fn finish_block(&mut self, operand: Option); +} + +impl InterfaceFunc { + /// Get the WebAssembly type signature for this interface function + /// + /// The first entry returned is the list of parameters and the second entry + /// is the list of results for the wasm function signature. + pub fn wasm_signature(&self) -> (Vec, Vec) { + assert_eq!(self.abi, Abi::Preview1); + let mut params = Vec::new(); + let mut results = Vec::new(); + for param in self.params.iter() { + match &**param.tref.type_() { + Type::Builtin(BuiltinType::S8) + | Type::Builtin(BuiltinType::U8 { .. }) + | Type::Builtin(BuiltinType::S16) + | Type::Builtin(BuiltinType::U16) + | Type::Builtin(BuiltinType::S32) + | Type::Builtin(BuiltinType::U32 { .. }) + | Type::Builtin(BuiltinType::Char) + | Type::Pointer(_) + | Type::ConstPointer(_) + | Type::Handle(_) + | Type::Variant(_) => params.push(WasmType::I32), + + Type::Record(r) => match r.bitflags_repr() { + Some(repr) => params.push(WasmType::from(repr)), + None => params.push(WasmType::I32), + }, + + Type::Builtin(BuiltinType::S64) | Type::Builtin(BuiltinType::U64) => { + params.push(WasmType::I64) + } + + Type::Builtin(BuiltinType::F32) => params.push(WasmType::F32), + Type::Builtin(BuiltinType::F64) => params.push(WasmType::F64), + + Type::List(_) => { + params.push(WasmType::I32); + params.push(WasmType::I32); + } + } + } + + for param in self.results.iter() { + match &**param.tref.type_() { + Type::Builtin(BuiltinType::S8) + | Type::Builtin(BuiltinType::U8 { .. }) + | Type::Builtin(BuiltinType::S16) + | Type::Builtin(BuiltinType::U16) + | Type::Builtin(BuiltinType::S32) + | Type::Builtin(BuiltinType::U32 { .. }) + | Type::Builtin(BuiltinType::Char) + | Type::Pointer(_) + | Type::ConstPointer(_) + | Type::Handle(_) => results.push(WasmType::I32), + + Type::Builtin(BuiltinType::S64) | Type::Builtin(BuiltinType::U64) => { + results.push(WasmType::I64) + } + + Type::Builtin(BuiltinType::F32) => results.push(WasmType::F32), + Type::Builtin(BuiltinType::F64) => results.push(WasmType::F64), + + Type::Record(r) => match r.bitflags_repr() { + Some(repr) => results.push(WasmType::from(repr)), + None => unreachable!(), + }, + Type::List(_) => unreachable!(), + + Type::Variant(v) => { + results.push(match v.tag_repr { + IntRepr::U64 => WasmType::I64, + IntRepr::U32 | IntRepr::U16 | IntRepr::U8 => WasmType::I32, + }); + if v.is_enum() { + continue; + } + // return pointer + if let Some(ty) = &v.cases[0].tref { + match &**ty.type_() { + Type::Record(r) if r.is_tuple() => { + for _ in 0..r.members.len() { + params.push(WasmType::I32); + } + } + _ => params.push(WasmType::I32), + } + } + } + } + } + (params, results) + } + + /// Generates an abstract sequence of instructions which represents this + /// function being adapted as an imported function. + /// + /// The instructions here, when executed, will emulate a language with + /// interface types calling the concrete wasm implementation. The parameters + /// for the returned instruction sequence are the language's own + /// interface-types parameters. One instruction in the instruction stream + /// will be a `Call` which represents calling the actual raw wasm function + /// signature. + /// + /// This function is useful, for example, if you're building a language + /// generator for WASI bindings. This will document how to translate + /// language-specific values into the wasm types to call a WASI function, + /// and it will also automatically convert the results of the WASI function + /// back to a language-specific value. + pub fn call_wasm(&self, module: &Id, bindgen: &mut impl Bindgen) { + assert_eq!(self.abi, Abi::Preview1); + Generator { + bindgen, + operands: vec![], + results: vec![], + stack: vec![], + } + .call_wasm(module, self); + } + + /// This is the dual of [`InterfaceFunc::call_wasm`], except that instead of + /// calling a wasm signature it generates code to come from a wasm signature + /// and call an interface types signature. + pub fn call_interface(&self, module: &Id, bindgen: &mut impl Bindgen) { + assert_eq!(self.abi, Abi::Preview1); + Generator { + bindgen, + operands: vec![], + results: vec![], + stack: vec![], + } + .call_interface(module, self); + } +} + +struct Generator<'a, B: Bindgen> { + bindgen: &'a mut B, + operands: Vec, + results: Vec, + stack: Vec, +} + +impl Generator<'_, B> { + fn call_wasm(&mut self, module: &Id, func: &InterfaceFunc) { + // Translate all parameters which are interface values by lowering them + // to their wasm types. + for (nth, param) in func.params.iter().enumerate() { + self.emit(&Instruction::GetArg { nth }); + self.lower(¶m.tref, None); + } + + // If necessary for our ABI, insert return pointers for any returned + // values through a result. + assert!(func.results.len() < 2); + if let Some(result) = func.results.get(0) { + self.prep_return_pointer(&result.tref.type_()); + } + + let (params, results) = func.wasm_signature(); + self.emit(&Instruction::CallWasm { + module: module.as_str(), + name: func.name.as_str(), + params: ¶ms, + results: &results, + }); + + // Lift the return value if one is present. + if let Some(result) = func.results.get(0) { + self.lift(&result.tref, true); + } + + self.emit(&Instruction::Return { + amt: func.results.len(), + }); + } + + fn call_interface(&mut self, module: &Id, func: &InterfaceFunc) { + // Lift all wasm parameters into interface types first. + // + // Note that consuming arguments is somewhat janky right now by manually + // giving lists a second argument for their length. In the future we'll + // probably want to refactor the `lift` function to internally know how + // to consume arguments. + let mut nth = 0; + for param in func.params.iter() { + self.emit(&Instruction::GetArg { nth }); + nth += 1; + if let Type::List(_) = &**param.tref.type_() { + self.emit(&Instruction::GetArg { nth }); + nth += 1; + } + self.lift(¶m.tref, false); + } + + self.emit(&Instruction::CallInterface { + module: module.as_str(), + func, + }); + + // Like above the current ABI only has at most one result, so lower it + // here if necessary. + if let Some(result) = func.results.get(0) { + self.lower(&result.tref, Some(&mut nth)); + } + + let (_params, results) = func.wasm_signature(); + self.emit(&Instruction::Return { amt: results.len() }); + } + + fn emit(&mut self, inst: &Instruction<'_>) { + self.operands.clear(); + self.results.clear(); + + let operands_len = inst.operands_len(); + assert!( + self.stack.len() >= operands_len, + "not enough operands on stack for {:?}", + inst + ); + self.operands + .extend(self.stack.drain((self.stack.len() - operands_len)..)); + self.results.reserve(inst.results_len()); + + self.bindgen + .emit(inst, &mut self.operands, &mut self.results); + + assert_eq!( + self.results.len(), + inst.results_len(), + "{:?} expected {} results, got {}", + inst, + inst.results_len(), + self.results.len() + ); + self.stack.extend(self.results.drain(..)); + } + + fn lower(&mut self, ty: &TypeRef, retptr: Option<&mut usize>) { + use Instruction::*; + match &**ty.type_() { + Type::Builtin(BuiltinType::S8) => self.emit(&I32FromS8), + Type::Builtin(BuiltinType::U8 { lang_c_char: true }) => self.emit(&I32FromChar8), + Type::Builtin(BuiltinType::U8 { lang_c_char: false }) => self.emit(&I32FromU8), + Type::Builtin(BuiltinType::S16) => self.emit(&I32FromS16), + Type::Builtin(BuiltinType::U16) => self.emit(&I32FromU16), + Type::Builtin(BuiltinType::S32) => self.emit(&I32FromS32), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: true, + }) => self.emit(&I32FromUsize), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: false, + }) => self.emit(&I32FromU32), + Type::Builtin(BuiltinType::S64) => self.emit(&I64FromS64), + Type::Builtin(BuiltinType::U64) => self.emit(&I64FromU64), + Type::Builtin(BuiltinType::Char) => self.emit(&I32FromChar), + Type::Pointer(_) => self.emit(&I32FromPointer), + Type::ConstPointer(_) => self.emit(&I32FromConstPointer), + Type::Handle(_) => self.emit(&I32FromHandle { + ty: match ty { + TypeRef::Name(ty) => ty, + _ => unreachable!(), + }, + }), + Type::Record(r) => { + let ty = match ty { + TypeRef::Name(ty) => ty, + _ => unreachable!(), + }; + match r.bitflags_repr() { + Some(IntRepr::U64) => self.emit(&I64FromBitflags { ty }), + Some(_) => self.emit(&I32FromBitflags { ty }), + None => self.emit(&AddrOf), + } + } + Type::Variant(v) => { + // Enum-like variants are simply lowered to their discriminant. + if v.is_enum() { + return self.emit(&EnumLower { + ty: match ty { + TypeRef::Name(n) => n, + _ => unreachable!(), + }, + }); + } + + // If this variant is in the return position then it's special, + // otherwise it's an argument and we just pass the address. + let retptr = match retptr { + Some(ptr) => ptr, + None => return self.emit(&AddrOf), + }; + + // For the return position we emit some blocks to lower the + // ok/err payloads which means that in the ok branch we're + // storing to out-params and in the err branch we're simply + // lowering the error enum. + // + // Note that this is all very specific to the current WASI ABI. + let (ok, err) = v.as_expected().unwrap(); + self.bindgen.push_block(); + if let Some(ok) = ok { + self.emit(&VariantPayload); + let store = |me: &mut Self, ty: &TypeRef, n| { + me.emit(&GetArg { nth: *retptr + n }); + match ty { + TypeRef::Name(ty) => me.emit(&Store { ty }), + _ => unreachable!(), + } + }; + match &**ok.type_() { + Type::Record(r) if r.is_tuple() => { + self.emit(&TupleLower { + amt: r.members.len(), + }); + // Note that `rev()` is used here due to the order + // that tuples are pushed onto the stack and how we + // consume the last item first from the stack. + for (i, member) in r.members.iter().enumerate().rev() { + store(self, &member.tref, i); + } + } + _ => store(self, ok, 0), + } + }; + self.bindgen.finish_block(None); + + self.bindgen.push_block(); + let err_expr = if let Some(ty) = err { + self.emit(&VariantPayload); + self.lower(ty, None); + Some(self.stack.pop().unwrap()) + } else { + None + }; + self.bindgen.finish_block(err_expr); + + self.emit(&ResultLower { ok, err }); + } + Type::Builtin(BuiltinType::F32) => self.emit(&F32FromIf32), + Type::Builtin(BuiltinType::F64) => self.emit(&F64FromIf64), + Type::List(_) => self.emit(&ListPointerLength), + } + } + + fn prep_return_pointer(&mut self, ty: &Type) { + // Return pointers are only needed for `Result`... + let variant = match ty { + Type::Variant(v) => v, + _ => return, + }; + // ... and only if `T` is actually present in `Result` + let ok = match &variant.cases[0].tref { + Some(t) => t, + None => return, + }; + + // Tuples have each individual item in a separate return pointer while + // all other types go through a singular return pointer. + let mut n = 0; + let mut prep = |ty: &TypeRef| { + match ty { + TypeRef::Name(ty) => self.bindgen.allocate_space(n, ty), + _ => unreachable!(), + } + self.emit(&Instruction::ReturnPointerGet { n }); + n += 1; + }; + match &**ok.type_() { + Type::Record(r) if r.is_tuple() => { + for member in r.members.iter() { + prep(&member.tref); + } + } + _ => prep(ok), + } + } + + // Note that in general everything in this function is the opposite of the + // `lower` function above. This is intentional and should be kept this way! + fn lift(&mut self, ty: &TypeRef, is_return: bool) { + use Instruction::*; + match &**ty.type_() { + Type::Builtin(BuiltinType::S8) => self.emit(&S8FromI32), + Type::Builtin(BuiltinType::U8 { lang_c_char: true }) => self.emit(&Char8FromI32), + Type::Builtin(BuiltinType::U8 { lang_c_char: false }) => self.emit(&U8FromI32), + Type::Builtin(BuiltinType::S16) => self.emit(&S16FromI32), + Type::Builtin(BuiltinType::U16) => self.emit(&U16FromI32), + Type::Builtin(BuiltinType::S32) => self.emit(&S32FromI32), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: true, + }) => self.emit(&UsizeFromI32), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: false, + }) => self.emit(&U32FromI32), + Type::Builtin(BuiltinType::S64) => self.emit(&S64FromI64), + Type::Builtin(BuiltinType::U64) => self.emit(&U64FromI64), + Type::Builtin(BuiltinType::Char) => self.emit(&CharFromI32), + Type::Builtin(BuiltinType::F32) => self.emit(&If32FromF32), + Type::Builtin(BuiltinType::F64) => self.emit(&If64FromF64), + Type::Pointer(ty) => self.emit(&PointerFromI32 { ty }), + Type::ConstPointer(ty) => self.emit(&ConstPointerFromI32 { ty }), + Type::Handle(_) => self.emit(&HandleFromI32 { + ty: match ty { + TypeRef::Name(ty) => ty, + _ => unreachable!(), + }, + }), + Type::Variant(v) => { + if v.is_enum() { + return self.emit(&EnumLift { + ty: match ty { + TypeRef::Name(n) => n, + _ => unreachable!(), + }, + }); + } else if !is_return { + return self.emit(&Load { + ty: match ty { + TypeRef::Name(n) => n, + _ => unreachable!(), + }, + }); + } + + let (ok, err) = v.as_expected().unwrap(); + self.bindgen.push_block(); + let ok_expr = if let Some(ok) = ok { + let mut n = 0; + let mut load = |ty: &TypeRef| { + self.emit(&ReturnPointerGet { n }); + n += 1; + match ty { + TypeRef::Name(ty) => self.emit(&Load { ty }), + _ => unreachable!(), + } + }; + match &**ok.type_() { + Type::Record(r) if r.is_tuple() => { + for member in r.members.iter() { + load(&member.tref); + } + self.emit(&TupleLift { + amt: r.members.len(), + }); + } + _ => load(ok), + } + Some(self.stack.pop().unwrap()) + } else { + None + }; + self.bindgen.finish_block(ok_expr); + + self.bindgen.push_block(); + let err_expr = if let Some(ty) = err { + self.emit(&ReuseReturn); + self.lift(ty, false); + Some(self.stack.pop().unwrap()) + } else { + None + }; + self.bindgen.finish_block(err_expr); + + self.emit(&ResultLift); + } + Type::Record(r) => { + let ty = match ty { + TypeRef::Name(ty) => ty, + _ => unreachable!(), + }; + match r.bitflags_repr() { + Some(IntRepr::U64) => self.emit(&BitflagsFromI64 { ty }), + Some(_) => self.emit(&BitflagsFromI32 { ty }), + None => self.emit(&Load { ty }), + } + } + Type::List(ty) => self.emit(&ListFromPointerLength { ty }), + } + } +} diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs index 7d34b5f7f..ee985d302 100644 --- a/proposals/random/tools/witx/src/ast.rs +++ b/proposals/random/tools/witx/src/ast.rs @@ -1,4 +1,4 @@ -#![allow(dead_code)] +use crate::Abi; use std::collections::{HashMap, HashSet}; use std::rc::{Rc, Weak}; @@ -63,13 +63,27 @@ impl Document { _ => None, }) } - /// All of the (unique) types used as the first result value of a function. + /// All of the (unique) types used as "err" variant of results returned from + /// functions. pub fn error_types<'a>(&'a self) -> impl Iterator + 'a { let errors: HashSet = self .modules() .flat_map(|m| { m.funcs() - .filter_map(|f| f.results.get(0).as_ref().map(|r| r.tref.clone())) + .filter_map(|f| { + if f.results.len() == 1 { + Some(f.results[0].tref.type_().clone()) + } else { + None + } + }) + .filter_map(|t| match &*t { + Type::Variant(v) => { + let (_ok, err) = v.as_expected()?; + Some(err?.clone()) + } + _ => None, + }) .collect::>() }) .collect(); @@ -162,10 +176,17 @@ pub enum TypeRef { } impl TypeRef { - pub fn type_(&self) -> Rc { + pub fn type_(&self) -> &Rc { match self { TypeRef::Name(named) => named.type_(), - TypeRef::Value(ref v) => v.clone(), + TypeRef::Value(v) => v, + } + } + + pub fn named(&self) -> bool { + match self { + TypeRef::Name(_) => true, + TypeRef::Value(_) => false, } } } @@ -178,23 +199,42 @@ pub struct NamedType { } impl NamedType { - pub fn type_(&self) -> Rc { + pub fn type_(&self) -> &Rc { self.tref.type_() } } +/// Structure of all possible interface types. +/// +/// Note that this is intended to match the interface types proposal itself. +/// Currently this is relatively close to that with just a few `*.witx` +/// extensions for now. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { + /// A structure with named field. Record(RecordDatatype), + /// An enumeration where a value is one of a number of variants. Variant(Variant), + /// A "handle" which is an un-forgeable reference. Today this is an `i32` + /// where a module can't forge and use integers it was not already given + /// access to. Handle(HandleDatatype), + /// A list of a type, stored in linear memory. + /// + /// Note that lists of `char` are specialized to indicate strings. List(TypeRef), + /// A `witx`-specific type representing a raw mutable pointer into linear + /// memory Pointer(TypeRef), + /// A `witx`-specific type representing a raw const pointer into linear + /// memory ConstPointer(TypeRef), + /// A builtin base-case type. Builtin(BuiltinType), } impl Type { + /// Returns a human-readable string to describe this type. pub fn kind(&self) -> &'static str { use Type::*; match self { @@ -215,6 +255,7 @@ pub enum BuiltinType { /// /// Same as the Rust language's `char` type. Char, + /// An 8-bit unsigned integer. U8 { /// Indicates whether this type is intended to represent the `char` /// type in the C language. The C `char` type is often unsigned, but @@ -226,7 +267,9 @@ pub enum BuiltinType { /// pointer` to hint that it's pointing to unicode string data as well. lang_c_char: bool, }, + /// A 16-bit unsigned integer. U16, + /// A 32-bit unsigned integer. U32 { /// Indicates that this 32-bit value should actually be considered a /// pointer-like value in language bindings. At the interface types @@ -238,12 +281,19 @@ pub enum BuiltinType { /// argument or return-value is pointer-like. lang_ptr_size: bool, }, + /// A 64-bit unsigned integer. U64, + /// An 8-bit signed integer S8, + /// A 16-bit signed integer S16, + /// A 32-bit signed integer S32, + /// A 64-bit signed integer S64, + /// A 32-bit floating point value. F32, + /// A 64-bit floating point value. F64, } @@ -268,11 +318,37 @@ impl IntRepr { } } +/// A struct-like value with named fields. +/// +/// Records map to `struct`s in most languages where this is a type with a +/// number of named fields that all have their own particular type. Field order +/// dictates layout in memory. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct RecordDatatype { + /// A hint as to what this record might be. + /// + /// Note that in the future this will only be a hint, not a control of the + /// actual representation itself. At this time though the record layout of + /// bitflags is different from other types. + pub kind: RecordKind, + + /// A list of named fields for this record. pub members: Vec, } +/// Different kinds of records used for hinting various language-specific types. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum RecordKind { + /// A tuple where the name of all fields are consecutive integers starting + /// at "0". + Tuple, + /// A record where all fields are `bool`s. Currently represented as an + /// integer with bits set or not set. + Bitflags(IntRepr), + /// All other structures. + Other, +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct RecordMember { pub name: Id, @@ -280,16 +356,98 @@ pub struct RecordMember { pub docs: String, } +impl RecordDatatype { + pub fn is_tuple(&self) -> bool { + match self.kind { + RecordKind::Tuple => true, + _ => false, + } + } + + pub fn bitflags_repr(&self) -> Option { + match self.kind { + RecordKind::Bitflags(i) => Some(i), + _ => None, + } + } +} + +/// A type which represents how values can be one of a set of possible cases. +/// +/// This type maps to an `enum` in languages like Rust, but doesn't have an +/// equivalent in languages like JS or C. The closest analog in C is a tagged +/// union, but a `Variant` is always consistent whereas a tagged union in C +/// could be mis-tagged or such. +/// +/// Variants are used to represent one of a possible set of types. For example +/// an enum-like variant, a result that is either success or failure, or even a +/// simple `bool`. Variants are primarily used heavily with various kinds of +/// shorthands in the `*.witx` format to represent idioms in languages. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Variant { + /// The bit representation of the width of this variant's tag when the + /// variant is stored in memory. pub tag_repr: IntRepr, + /// The possible cases that values of this variant type can take. pub cases: Vec, } +impl Variant { + /// If this variant looks like an `expected` shorthand, return the ok/err + /// types associated with this result. + /// + /// Only matches variants fo the form: + /// + /// ```text + /// (variant + /// (case "ok" ok?) + /// (case "err" err?)) + /// ``` + pub fn as_expected(&self) -> Option<(Option<&TypeRef>, Option<&TypeRef>)> { + if self.cases.len() != 2 { + return None; + } + if self.cases[0].name != "ok" { + return None; + } + if self.cases[1].name != "err" { + return None; + } + Some((self.cases[0].tref.as_ref(), self.cases[1].tref.as_ref())) + } + + /// Returns whether this variant type is "bool-like" meaning that it matches + /// this type: + /// + /// ```text + /// (variant + /// (case "false") + /// (case "true")) + /// ``` + pub fn is_bool(&self) -> bool { + self.cases.len() == 2 + && self.cases[0].name == "false" + && self.cases[1].name == "true" + && self.cases[0].tref.is_none() + && self.cases[1].tref.is_none() + } + + /// Returns whether this variant type is "enum-like" meaning that all of its + /// cases have no payload associated with them. + pub fn is_enum(&self) -> bool { + self.cases.iter().all(|c| c.tref.is_none()) + } +} + +/// One of a number of possible types that a `Variant` can take. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Case { + /// The name of this case and how to identify it. pub name: Id, + /// An optional payload type for this case and data that can be associated + /// with it. pub tref: Option, + /// Documentation for this case. pub docs: String, } @@ -409,6 +567,7 @@ pub enum ModuleImportVariant { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct InterfaceFunc { + pub abi: Abi, pub name: Id, pub params: Vec, pub results: Vec, @@ -420,16 +579,9 @@ pub struct InterfaceFunc { pub struct InterfaceFuncParam { pub name: Id, pub tref: TypeRef, - pub position: InterfaceFuncParamPosition, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum InterfaceFuncParamPosition { - Param(usize), - Result(usize), -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Constant { pub ty: Id, diff --git a/proposals/random/tools/witx/src/coretypes.rs b/proposals/random/tools/witx/src/coretypes.rs deleted file mode 100644 index 826990369..000000000 --- a/proposals/random/tools/witx/src/coretypes.rs +++ /dev/null @@ -1,173 +0,0 @@ -use crate::{BuiltinType, IntRepr, InterfaceFunc, InterfaceFuncParam, Type}; - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -/// Enumerates the types permitted for function arguments in the WebAssembly spec -pub enum AtomType { - I32, - I64, - F32, - F64, -} - -impl From for AtomType { - fn from(i: IntRepr) -> AtomType { - match i { - IntRepr::U8 | IntRepr::U16 | IntRepr::U32 => AtomType::I32, - IntRepr::U64 => AtomType::I64, - } - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -/// Enumerates the strategies which may be used to pass a datatype as an argument -pub enum TypePassedBy { - /// Pass by value specifies the AtomType used to represent that value - Value(AtomType), - /// Pass by a pointer into linear memory - Pointer, - /// Pass by a pointer and length pair, into linear memory - PointerLengthPair, -} - -impl Type { - /// Determine the simplest strategy by which a type may be passed. Value always preferred over - /// Pointer. - pub fn passed_by(&self) -> TypePassedBy { - match self { - Type::Builtin(b) => match b { - BuiltinType::U8 { .. } - | BuiltinType::U16 - | BuiltinType::U32 { .. } - | BuiltinType::S8 - | BuiltinType::S16 - | BuiltinType::S32 - | BuiltinType::Char => TypePassedBy::Value(AtomType::I32), - BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), - BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), - BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), - }, - Type::List { .. } => TypePassedBy::PointerLengthPair, - Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), - Type::Record { .. } => TypePassedBy::Pointer, - Type::Variant(v) => { - if v.cases.iter().all(|c| c.tref.is_none()) { - TypePassedBy::Value(v.tag_repr.into()) - } else { - TypePassedBy::Pointer - } - } - Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), - } - } -} - -/// A parameter in the WebAssembly type of a function. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CoreParamType { - /// The interface function parameter to which this - pub param: InterfaceFuncParam, - /// The relationship of the WebAssembly parameter to the function interface parameter - pub signifies: CoreParamSignifies, -} - -impl CoreParamType { - /// Representation of the WebAssembly parameter. This is the type that will appear - /// in the function's WebAssembly type signature. - pub fn repr(&self) -> AtomType { - self.signifies.repr() - } -} - -/// Enumerates the sort of relationship an WebAssembly parameter to an interface function -/// parameter. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum CoreParamSignifies { - /// Core type represents the value using an AtomType - Value(AtomType), - /// Core type represents a pointer into linear memory - PointerTo, - /// Core type represents a length of a region of linear memory - LengthOf, -} - -impl CoreParamSignifies { - /// Representation of the WebAssembly parameter. - pub fn repr(&self) -> AtomType { - match self { - CoreParamSignifies::Value(a) => *a, - CoreParamSignifies::PointerTo | CoreParamSignifies::LengthOf => AtomType::I32, - } - } -} - -impl InterfaceFuncParam { - /// Gives the WebAssembly type that corresponds to passing this interface func parameter by value. - /// Not all types can be passed by value: those which cannot return None - pub fn pass_by_value(&self) -> Option { - match self.tref.type_().passed_by() { - TypePassedBy::Value(atom) => Some(CoreParamType { - signifies: CoreParamSignifies::Value(atom), - param: self.clone(), - }), - TypePassedBy::Pointer | TypePassedBy::PointerLengthPair => None, - } - } - - /// Gives the WebAssembly types that correspond to passing this interface func parameter - /// by reference. Some types are passed by reference using a single pointer, others - /// require both a pointer and length. - pub fn pass_by_reference(&self) -> Vec { - match self.tref.type_().passed_by() { - TypePassedBy::Value(_) | TypePassedBy::Pointer => vec![CoreParamType { - signifies: CoreParamSignifies::PointerTo, - param: self.clone(), - }], - TypePassedBy::PointerLengthPair => vec![ - CoreParamType { - signifies: CoreParamSignifies::PointerTo, - param: self.clone(), - }, - CoreParamType { - signifies: CoreParamSignifies::LengthOf, - param: self.clone(), - }, - ], - } - } -} - -/// Describes the WebAssembly signature of a function -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CoreFuncType { - pub args: Vec, - pub ret: Option, -} - -impl InterfaceFunc { - /// Get the WebAssembly type signature for this interface function - pub fn core_type(&self) -> CoreFuncType { - let mut results = self.results.iter(); - // The ret value is the first result (if there is one), passed - // by value. - let ret = results.next().map(|param| { - param - .pass_by_value() - .expect("validation ensures first result can be passed by value") - }); - let args = self - .params - .iter() - .flat_map(|param| { - // interface function parameters are passed by value if possible, - // and fall back on passing by reference. - param - .pass_by_value() - .map(|ptype| vec![ptype]) - .unwrap_or_else(|| param.pass_by_reference()) - }) - // Then, the remaining results are passed by reference. - .chain(results.flat_map(|param| param.pass_by_reference())) - .collect(); - CoreFuncType { args, ret } - } -} diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs index 6048f73a1..a295a6756 100644 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ b/proposals/random/tools/witx/src/docs/ast.rs @@ -1,5 +1,5 @@ use super::{ - md::{MdFunc, MdHeading, MdNamedType, MdNodeRef, MdSection, MdType, ToMarkdown}, + md::{MdFunc, MdHeading, MdNamedType, MdNodeRef, MdSection, ToMarkdown}, Documentation, }; use crate::{ @@ -68,11 +68,13 @@ impl ToMarkdown for Document { impl ToMarkdown for TypeRef { fn generate(&self, node: MdNodeRef) { match self { - TypeRef::Value(v) => v.generate(node.clone()), + TypeRef::Value(v) => { + v.generate(node.clone()); + node.content_ref_mut::().ty = Some(format!("`{}`", self.type_name())); + } TypeRef::Name(n) => { - node.content_ref_mut::().r#type = Some(MdType::Alias { - r#type: n.name.as_str().to_owned(), - }) + node.content_ref_mut::().ty = + Some(format!("[`{0}`](#{0})", n.name.as_str().to_owned())); } } } @@ -90,26 +92,10 @@ impl ToMarkdown for Type { Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), - Self::List(a) => { - node.content_ref_mut::().r#type = Some(MdType::List { - r#type: a.type_name().to_owned(), - }) - } - Self::Pointer(a) => { - node.content_ref_mut::().r#type = Some(MdType::Pointer { - r#type: a.type_name().to_owned(), - }) - } - Self::ConstPointer(a) => { - node.content_ref_mut::().r#type = Some(MdType::ConstPointer { - r#type: a.type_name().to_owned(), - }) - } - Self::Builtin(a) => { - node.content_ref_mut::().r#type = Some(MdType::Builtin { - repr: a.type_name().to_owned(), - }) - } + Self::List(_) => {} + Self::Pointer(_) => {} + Self::ConstPointer(_) => {} + Self::Builtin(_) => {} } } } @@ -128,21 +114,27 @@ impl ToMarkdown for RecordDatatype { } else { name.to_owned() }; + let (div, offset_desc) = if self.bitflags_repr().is_some() { + (4, "Bit") + } else { + (1, "Offset") + }; let n = node.new_child(MdNamedType::new( MdHeading::new_bullet(), id.as_str(), name, - format!("{}\nOffset: {}\n", &member.docs, &offset).as_str(), + format!("{}\n{}: {}\n", &member.docs, offset_desc, offset / div).as_str(), )); member.tref.generate(n.clone()); } - - node.content_ref_mut::().r#type = Some(MdType::Record); } } impl ToMarkdown for Variant { fn generate(&self, node: MdNodeRef) { + if self.is_bool() { + return; + } if self.cases.iter().any(|c| c.tref.is_some()) { let heading = heading_from_node(&node, 1); node.new_child(MdSection::new(heading, "Variant Layout")); @@ -184,8 +176,6 @@ impl ToMarkdown for Variant { ty.generate(n.clone()); } } - - node.content_ref_mut::().r#type = Some(MdType::Variant); } } @@ -194,7 +184,6 @@ impl ToMarkdown for HandleDatatype { // TODO this needs more work let heading = heading_from_node(&node, 1); node.new_child(MdSection::new(heading, "Supertypes")); - node.content_ref_mut::().r#type = Some(MdType::Handle); } } @@ -312,16 +301,50 @@ impl TypeRef { pub fn type_name(&self) -> String { match self { TypeRef::Name(n) => n.name.as_str().to_string(), - TypeRef::Value(ref v) => match &**v { - Type::List(a) => match &*a.type_() { + TypeRef::Value(v) => match &**v { + Type::List(a) => match &**a.type_() { Type::Builtin(BuiltinType::Char) => "string".to_string(), _ => format!("List<{}>", a.type_name()), }, Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), - Type::Record { .. } | Type::Variant { .. } | Type::Handle { .. } => { - unimplemented!("type_name of anonymous compound datatypes") + Type::Record(RecordDatatype { + kind: RecordKind::Tuple, + members, + }) => { + let mut ret = "(".to_string(); + for (i, member) in members.iter().enumerate() { + if i > 0 { + ret.push_str(", "); + } + ret.push_str(&member.tref.type_name()); + } + ret.push_str(")"); + ret + } + Type::Record { .. } => { + format!("Record") + } + Type::Handle { .. } => { + format!("Handle") + } + Type::Variant(v) => { + if let Some((ok, err)) = v.as_expected() { + let ok = match ok { + Some(ty) => ty.type_name(), + None => "()".to_string(), + }; + let err = match err { + Some(ty) => ty.type_name(), + None => "()".to_string(), + }; + format!("Result<{}, {}>", ok, err) + } else if v.is_bool() { + format!("bool") + } else { + format!("Variant") + } } }, } diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs index d3d5b756d..569b31837 100644 --- a/proposals/random/tools/witx/src/docs/md.rs +++ b/proposals/random/tools/witx/src/docs/md.rs @@ -322,7 +322,7 @@ pub(super) struct MdNamedType { pub id: String, pub name: String, pub docs: String, - pub r#type: Option, + pub ty: Option, } impl MdNamedType { @@ -332,54 +332,11 @@ impl MdNamedType { id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), docs: docs.as_ref().to_owned(), - r#type: None, + ty: None, } } } -/// Helper struct encapsulating the `TypeRef` value. -// TODO `MdType` should probably store `TypeRef` and recursively -// unwind itself into final `String` representation rather than -// being outright flattened. -#[derive(Debug)] -pub(super) enum MdType { - Record, - Variant, - List { r#type: String }, - Pointer { r#type: String }, - ConstPointer { r#type: String }, - Builtin { repr: String }, - Handle, - Alias { r#type: String }, -} - -impl fmt::Display for MdType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Record => f.write_fmt(format_args!(": Record"))?, - Self::Variant => f.write_fmt(format_args!(": Variant"))?, - Self::List { r#type } => { - if r#type == "char" { - f.write_str(": `string`")? - } else { - f.write_fmt(format_args!(": `List<{}>`", r#type))? - } - } - Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, - Self::ConstPointer { r#type } => { - f.write_fmt(format_args!(": `ConstPointer<{}>`", r#type))? - } - Self::Builtin { repr } => f.write_fmt(format_args!(": `{}`", repr))?, - Self::Handle => {} - Self::Alias { r#type } => { - f.write_fmt(format_args!(": [`{tt}`](#{tt})", tt = r#type))? - } - }; - - Ok(()) - } -} - impl MdElement for MdNamedType { fn id(&self) -> Option<&str> { Some(&self.id) @@ -411,8 +368,8 @@ impl fmt::Display for MdNamedType { name = self.name, ))?; - if let Some(tt) = &self.r#type { - f.write_fmt(format_args!("{}", tt))?; + if let Some(tt) = &self.ty { + f.write_fmt(format_args!(": {}", tt))?; } writeln!(f, "\n{}", self.docs) diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs index 2bcd1042a..6812f01ae 100644 --- a/proposals/random/tools/witx/src/layout.rs +++ b/proposals/random/tools/witx/src/layout.rs @@ -64,7 +64,10 @@ impl Layout for NamedType { impl Type { fn layout(&self, cache: &mut HashMap) -> SizeAlign { match &self { - Type::Record(s) => s.layout(cache), + Type::Record(s) => match s.bitflags_repr() { + Some(repr) => repr.mem_size_align(), + None => s.layout(cache), + }, Type::Variant(s) => s.mem_size_align(), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length @@ -122,8 +125,13 @@ impl RecordDatatype { impl Layout for RecordDatatype { fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) + match self.bitflags_repr() { + Some(repr) => repr.mem_size_align(), + None => { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } + } } } @@ -143,6 +151,18 @@ impl Layout for Variant { } } +impl Variant { + pub fn payload_offset(&self) -> usize { + let mut offset = self.tag_repr.mem_size_align().size; + for case in self.cases.iter() { + if let Some(payload) = &case.tref { + offset = offset.max(align_to(offset, payload.mem_size_align().align)); + } + } + offset + } +} + /// If the next free byte in the struct is `offs`, and the next /// element has alignment `alignment`, determine the offset at /// which to place that element. diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index 2c876aa13..f1cc7e229 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -1,7 +1,7 @@ +/// Map witx types to core (wasm standard) types +mod abi; /// Types describing a validated witx document mod ast; -/// Map witx types to core (wasm standard) types -mod coretypes; /// Render documentation mod docs; /// Interface for filesystem or mock IO @@ -23,8 +23,8 @@ mod toplevel; /// Validate declarations into ast mod validate; +pub use abi::*; pub use ast::*; -pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use layout::{Layout, RecordMemberLayout, SizeAlign}; diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs index 19d1a0303..33cf745ff 100644 --- a/proposals/random/tools/witx/src/parser.rs +++ b/proposals/random/tools/witx/src/parser.rs @@ -1,5 +1,4 @@ use crate::BuiltinType; -use wast::lexer::Comment; use wast::parser::{Parse, Parser, Peek, Result}; ///! Parser turns s-expressions into unvalidated syntax constructs. @@ -18,7 +17,6 @@ use wast::parser::{Parse, Parser, Peek, Result}; mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; - wast::custom_keyword!(bitflags); wast::custom_keyword!(case); wast::custom_keyword!(char8); wast::custom_keyword!(char); @@ -27,6 +25,8 @@ mod kw { wast::custom_keyword!(f64); wast::custom_keyword!(field); wast::custom_keyword!(empty); + wast::custom_keyword!(error); + wast::custom_keyword!(expected); wast::custom_keyword!(flags); wast::custom_keyword!(handle); wast::custom_keyword!(list); @@ -37,12 +37,14 @@ mod kw { wast::custom_keyword!(r#enum = "enum"); wast::custom_keyword!(r#union = "union"); wast::custom_keyword!(r#use = "use"); + wast::custom_keyword!(repr); wast::custom_keyword!(s16); wast::custom_keyword!(s32); wast::custom_keyword!(s64); wast::custom_keyword!(s8); wast::custom_keyword!(string); wast::custom_keyword!(tag); + wast::custom_keyword!(tuple); wast::custom_keyword!(typename); wast::custom_keyword!(u16); wast::custom_keyword!(u32); @@ -50,6 +52,7 @@ mod kw { wast::custom_keyword!(u8); wast::custom_keyword!(usize); wast::custom_keyword!(variant); + wast::custom_keyword!(bool_ = "bool"); } mod annotation { @@ -136,9 +139,10 @@ impl<'a> Parse<'a> for CommentSyntax<'a> { None => break, }; cursor = c; - comments.push(match comment { - Comment::Block(s) => &s[2..s.len() - 2], - Comment::Line(s) => &s[2..], + comments.push(if comment.starts_with(";;") { + &comment[2..] + } else { + &comment[2..comment.len() - 2] }); } Ok((comments, cursor)) @@ -277,6 +281,8 @@ impl<'a> Parse<'a> for TypenameSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub enum TypedefSyntax<'a> { Enum(EnumSyntax<'a>), + Tuple(TupleSyntax<'a>), + Expected(ExpectedSyntax<'a>), Flags(FlagsSyntax<'a>), Record(RecordSyntax<'a>), Union(UnionSyntax<'a>), @@ -288,6 +294,7 @@ pub enum TypedefSyntax<'a> { Builtin(BuiltinType), Ident(wast::Id<'a>), String, + Bool, } impl<'a> Parse<'a> for TypedefSyntax<'a> { @@ -300,11 +307,18 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { } else if l.peek::() { parser.parse::()?; Ok(TypedefSyntax::String) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::Bool) } else if l.peek::() { parser.parens(|parser| { let mut l = parser.lookahead1(); if l.peek::() { Ok(TypedefSyntax::Enum(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Tuple(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Expected(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Flags(parser.parse()?)) } else if l.peek::() { @@ -377,6 +391,48 @@ impl<'a> Parse<'a> for EnumSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TupleSyntax<'a> { + pub types: Vec>, +} + +impl<'a> Parse<'a> for TupleSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let mut types = Vec::new(); + while !parser.is_empty() { + types.push(parser.parse()?); + } + Ok(TupleSyntax { types }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ExpectedSyntax<'a> { + pub ok: Option>>, + pub err: Option>>, +} + +impl<'a> Parse<'a> for ExpectedSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let ok = if !parser.is_empty() && !parser.peek2::() { + Some(Box::new(parser.parse()?)) + } else { + None + }; + let err = parser.parens(|p| { + p.parse::()?; + Ok(if p.is_empty() { + None + } else { + Some(Box::new(p.parse()?)) + }) + })?; + Ok(ExpectedSyntax { ok, err }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConstSyntax<'a> { pub ty: wast::Id<'a>, @@ -397,17 +453,17 @@ impl<'a> Parse<'a> for ConstSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsSyntax<'a> { - pub bitflags_repr: Option, + pub repr: Option, pub flags: Vec>>, } impl<'a> Parse<'a> for FlagsSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let bitflags_repr = if parser.peek2::() { + let repr = if parser.peek2::() { Some(parser.parens(|p| { p.parse::()?; - p.parse::()?; + p.parse::()?; p.parse() })?) } else { @@ -417,10 +473,7 @@ impl<'a> Parse<'a> for FlagsSyntax<'a> { while !parser.is_empty() { flags.push(parser.parse()?); } - Ok(FlagsSyntax { - bitflags_repr, - flags, - }) + Ok(FlagsSyntax { repr, flags }) } } diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs index ad551ae9b..a740e282c 100644 --- a/proposals/random/tools/witx/src/render.rs +++ b/proposals/random/tools/witx/src/render.rs @@ -143,29 +143,56 @@ impl Type { impl RecordDatatype { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("record")]; - let members = self - .members - .iter() - .map(|m| { - SExpr::docs( - &m.docs, - SExpr::Vec(vec![ - SExpr::word("field"), - m.name.to_sexpr(), - m.tref.to_sexpr(), - ]), - ) - }) - .collect::>(); - SExpr::Vec([header, members].concat()) + match self.kind { + RecordKind::Tuple => { + let mut tuple = vec![SExpr::word("tuple")]; + for m in self.members.iter() { + tuple.push(SExpr::docs(&m.docs, m.tref.to_sexpr())); + } + SExpr::Vec(tuple) + } + RecordKind::Bitflags(repr) => { + let mut flags = vec![SExpr::word("flags")]; + flags.push(SExpr::Vec(vec![ + SExpr::word("@witx"), + SExpr::word("repr"), + repr.to_sexpr(), + ])); + flags.extend( + self.members + .iter() + .map(|m| SExpr::docs(&m.docs, m.name.to_sexpr())), + ); + SExpr::Vec(flags) + } + RecordKind::Other => { + let header = vec![SExpr::word("record")]; + let members = self + .members + .iter() + .map(|m| { + SExpr::docs( + &m.docs, + SExpr::Vec(vec![ + SExpr::word("field"), + m.name.to_sexpr(), + m.tref.to_sexpr(), + ]), + ) + }) + .collect::>(); + SExpr::Vec([header, members].concat()) + } + } } } impl Variant { pub fn to_sexpr(&self) -> SExpr { let mut list = Vec::new(); - if self.cases.iter().all(|c| c.tref.is_none()) { + if self.is_bool() { + return SExpr::word("bool"); + } else if self.is_enum() { list.push(SExpr::word("enum")); list.push(SExpr::Vec(vec![ SExpr::word("@witx"), diff --git a/proposals/random/tools/witx/src/toplevel.rs b/proposals/random/tools/witx/src/toplevel.rs index 83e940c7c..257e6edd8 100644 --- a/proposals/random/tools/witx/src/toplevel.rs +++ b/proposals/random/tools/witx/src/toplevel.rs @@ -107,11 +107,11 @@ mod test { .expect("parse"); let b_float = doc.typename(&Id::new("b_float")).unwrap(); - assert_eq!(*b_float.type_(), Type::Builtin(BuiltinType::F64)); + assert_eq!(**b_float.type_(), Type::Builtin(BuiltinType::F64)); let c_int = doc.typename(&Id::new("c_int")).unwrap(); assert_eq!( - *c_int.type_(), + **c_int.type_(), Type::Builtin(BuiltinType::U32 { lang_ptr_size: false }) @@ -133,7 +133,7 @@ mod test { let d_char = doc.typename(&Id::new("d_char")).unwrap(); assert_eq!( - *d_char.type_(), + **d_char.type_(), Type::Builtin(BuiltinType::U8 { lang_c_char: false }) ); } diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs index ade02282b..cf4d0ad7f 100644 --- a/proposals/random/tools/witx/src/validate.rs +++ b/proposals/random/tools/witx/src/validate.rs @@ -1,14 +1,14 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ - CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, - ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, - VariantSyntax, + CommentSyntax, DeclSyntax, Documented, EnumSyntax, ExpectedSyntax, FlagsSyntax, + HandleSyntax, ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TupleSyntax, TypedefSyntax, + UnionSyntax, VariantSyntax, }, - BuiltinType, Case, Constant, Definition, Document, Entry, HandleDatatype, Id, IntRepr, - InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, - ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, - RecordMember, Type, TypePassedBy, TypeRef, Variant, + Abi, BuiltinType, Case, Constant, Definition, Document, Entry, HandleDatatype, Id, IntRepr, + InterfaceFunc, InterfaceFuncParam, Location, Module, ModuleDefinition, ModuleEntry, + ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordKind, RecordMember, Type, + TypeRef, Variant, }; use std::collections::{HashMap, HashSet}; use std::path::Path; @@ -39,8 +39,8 @@ pub enum ValidationError { repr: BuiltinType, location: Location, }, - #[error("First result type must be pass-by-value")] - InvalidFirstResultType { location: Location }, + #[error("ABI error: {reason}")] + Abi { reason: String, location: Location }, #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] AnonymousRecord { location: Location }, #[error("Union expected {expected} variants, found {found}")] @@ -67,7 +67,7 @@ impl ValidationError { | WrongKindName { location, .. } | Recursive { location, .. } | InvalidRepr { location, .. } - | InvalidFirstResultType { location, .. } + | Abi { location, .. } | AnonymousRecord { location, .. } | UnionSizeMismatch { location, .. } | InvalidUnionField { location, .. } @@ -131,6 +131,7 @@ pub struct DocValidation { scope: IdentValidation, entries: HashMap, constant_scopes: HashMap, + bool_ty: TypeRef, } pub struct DocValidationScope<'a> { @@ -145,6 +146,21 @@ impl DocValidation { scope: IdentValidation::new(), entries: HashMap::new(), constant_scopes: HashMap::new(), + bool_ty: TypeRef::Value(Rc::new(Type::Variant(Variant { + tag_repr: IntRepr::U32, + cases: vec![ + Case { + name: Id::new("false"), + tref: None, + docs: String::new(), + }, + Case { + name: Id::new("true"), + tref: None, + docs: String::new(), + }, + ], + }))), } } @@ -203,24 +219,6 @@ impl DocValidationScope<'_> { .entries .insert(name.clone(), Entry::Typename(Rc::downgrade(&rc_datatype))); definitions.push(Definition::Typename(rc_datatype)); - - if let TypedefSyntax::Flags(syntax) = &decl.def { - if syntax.bitflags_repr.is_some() { - let mut flags_scope = IdentValidation::new(); - let ty = name; - for (i, flag) in syntax.flags.iter().enumerate() { - let name = flags_scope - .introduce(flag.item.name(), self.location(flag.item.span()))?; - let docs = flag.comments.docs(); - definitions.push(Definition::Constant(Constant { - ty: ty.clone(), - name, - value: 1 << i, - docs, - })); - } - } - } } DeclSyntax::Module(syntax) => { @@ -304,7 +302,11 @@ impl DocValidationScope<'_> { } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), - TypedefSyntax::Flags(syntax) => self.validate_flags(&syntax, span)?, + TypedefSyntax::Tuple(syntax) => Type::Record(self.validate_tuple(&syntax, span)?), + TypedefSyntax::Expected(syntax) => { + Type::Variant(self.validate_expected(&syntax, span)?) + } + TypedefSyntax::Flags(syntax) => Type::Record(self.validate_flags(&syntax, span)?), TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Variant(self.validate_union(&syntax, span)?), TypedefSyntax::Variant(syntax) => { @@ -324,6 +326,7 @@ impl DocValidationScope<'_> { TypedefSyntax::String => { Type::List(TypeRef::Value(Rc::new(Type::Builtin(BuiltinType::Char)))) } + TypedefSyntax::Bool => return Ok(self.doc.bool_ty.clone()), TypedefSyntax::Ident { .. } => unreachable!(), }))), } @@ -356,17 +359,83 @@ impl DocValidationScope<'_> { Ok(Variant { tag_repr, cases }) } + fn validate_tuple( + &self, + syntax: &TupleSyntax, + span: wast::Span, + ) -> Result { + let members = syntax + .types + .iter() + .enumerate() + .map(|(i, ty)| { + Ok(RecordMember { + name: Id::new(i.to_string()), + tref: self.validate_datatype(ty, false, span)?, + docs: String::new(), + }) + }) + .collect::, _>>()?; + + Ok(RecordDatatype { + kind: RecordKind::Tuple, + members, + }) + } + + fn validate_expected( + &self, + syntax: &ExpectedSyntax, + span: wast::Span, + ) -> Result { + let ok_ty = match &syntax.ok { + Some(ok) => Some(self.validate_datatype(ok, false, span)?), + None => None, + }; + let err_ty = match &syntax.err { + Some(err) => Some(self.validate_datatype(err, false, span)?), + None => None, + }; + Ok(Variant { + tag_repr: IntRepr::U32, + cases: vec![ + Case { + name: Id::new("ok"), + tref: ok_ty, + docs: String::new(), + }, + Case { + name: Id::new("err"), + tref: err_ty, + docs: String::new(), + }, + ], + }) + } + fn validate_flags( &self, syntax: &FlagsSyntax, span: wast::Span, - ) -> Result { - Ok(match &syntax.bitflags_repr { - Some(repr) => Type::Builtin(self.validate_int_repr(repr, span)?.to_builtin()), - None => { - // TODO: auto-translate to a struct-of-bool-fields - unimplemented!(); - } + ) -> Result { + let repr = match syntax.repr { + Some(ty) => self.validate_int_repr(&ty, span)?, + None => IntRepr::U32, + }; + let mut flags_scope = IdentValidation::new(); + let mut members = Vec::new(); + for flag in syntax.flags.iter() { + let name = flags_scope.introduce(flag.item.name(), self.location(flag.item.span()))?; + let docs = flag.comments.docs(); + members.push(RecordMember { + name, + docs, + tref: self.doc.bool_ty.clone(), + }); + } + Ok(RecordDatatype { + kind: RecordKind::Bitflags(repr), + members, }) } @@ -388,7 +457,10 @@ impl DocValidationScope<'_> { }) .collect::, _>>()?; - Ok(RecordDatatype { members }) + Ok(RecordDatatype { + kind: RecordKind::Other, + members, + }) } fn validate_union( @@ -497,7 +569,7 @@ impl DocValidationScope<'_> { Some(tag) => self.validate_datatype(tag, false, span)?, None => return Ok((IntRepr::U32, None)), }; - match &*ty.type_() { + match &**ty.type_() { Type::Variant(e) => { let mut names = Vec::new(); for c in e.cases.iter() { @@ -594,8 +666,7 @@ impl<'a> ModuleValidation<'a> { let params = syntax .params .iter() - .enumerate() - .map(|(ix, f)| { + .map(|f| { Ok(InterfaceFuncParam { name: argnames.introduce( f.item.name.name(), @@ -606,7 +677,6 @@ impl<'a> ModuleValidation<'a> { false, f.item.name.span(), )?, - position: InterfaceFuncParamPosition::Param(ix), docs: f.comments.docs(), }) }) @@ -614,33 +684,29 @@ impl<'a> ModuleValidation<'a> { let results = syntax .results .iter() - .enumerate() - .map(|(ix, f)| { + .map(|f| { let tref = self.doc .validate_datatype(&f.item.type_, false, f.item.name.span())?; - if ix == 0 { - match tref.type_().passed_by() { - TypePassedBy::Value(_) => {} - _ => Err(ValidationError::InvalidFirstResultType { - location: self.doc.location(f.item.name.span()), - })?, - } - } Ok(InterfaceFuncParam { name: argnames.introduce( f.item.name.name(), self.doc.location(f.item.name.span()), )?, tref, - position: InterfaceFuncParamPosition::Result(ix), docs: f.comments.docs(), }) }) .collect::, _>>()?; let noreturn = syntax.noreturn; - + let abi = Abi::Preview1; + abi.validate(¶ms, &results) + .map_err(|reason| ValidationError::Abi { + reason, + location: self.doc.location(syntax.export_loc), + })?; let rc_func = Rc::new(InterfaceFunc { + abi, name: name.clone(), params, results, diff --git a/proposals/random/tools/witx/tests/witxt.rs b/proposals/random/tools/witx/tests/witxt.rs index 1056947a3..7c002fe1b 100644 --- a/proposals/random/tools/witx/tests/witxt.rs +++ b/proposals/random/tools/witx/tests/witxt.rs @@ -14,7 +14,7 @@ use std::path::{Path, PathBuf}; use std::str; use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use wast::parser::{self, Parse, ParseBuffer, Parser}; -use witx::{Documentation, Representable}; +use witx::{Documentation, Instruction, Representable, WasmType}; fn main() { let tests = find_tests(); @@ -192,6 +192,36 @@ impl WitxtRunner<'_> { } } } + WitxtDirective::AssertAbi { + witx, + wasm, + interface, + wasm_signature: (wasm_params, wasm_results), + .. + } => { + let doc = witx.document(contents, test)?; + let module = doc.modules().next().ok_or_else(|| anyhow!("no modules"))?; + let func = module.funcs().next().ok_or_else(|| anyhow!("no funcs"))?; + + let (params, results) = func.wasm_signature(); + if params != wasm_params { + bail!("expected params {:?}, found {:?}", wasm_params, params); + } + if results != wasm_results { + bail!("expected results {:?}, found {:?}", wasm_results, results); + } + + let mut check = AbiBindgen { + abi: wasm.instrs.iter(), + err: None, + contents, + }; + func.call_wasm(&module.name, &mut check); + check.check()?; + check.abi = interface.instrs.iter(); + func.call_interface(&module.name, &mut check); + check.check()?; + } } Ok(()) } @@ -249,14 +279,147 @@ impl WitxtRunner<'_> { } } +struct AbiBindgen<'a> { + abi: std::slice::Iter<'a, (wast::Span, &'a str)>, + err: Option, + contents: &'a str, +} + +impl AbiBindgen<'_> { + fn check(&mut self) -> Result<()> { + match self.err.take() { + None => Ok(()), + Some(e) => Err(e), + } + } + + fn assert(&mut self, name: &str) { + if self.err.is_some() { + return; + } + match self.abi.next() { + Some((_, s)) if *s == name => {} + Some((span, s)) => { + let (line, col) = span.linecol_in(self.contents); + self.err = Some(anyhow!( + "line {}:{} - expected `{}` found `{}`", + line + 1, + col + 1, + name, + s, + )); + } + None => { + self.err = Some(anyhow!( + "extra instruction `{}` found when none was expected", + name + )); + } + } + } +} + +impl witx::Bindgen for AbiBindgen<'_> { + type Operand = (); + fn emit( + &mut self, + inst: &Instruction<'_>, + _operands: &mut Vec, + results: &mut Vec, + ) { + use witx::Instruction::*; + match inst { + GetArg { nth } => self.assert(&format!("get-arg{}", nth)), + AddrOf => self.assert("addr-of"), + I32FromChar => self.assert("i32.from_char"), + I64FromU64 => self.assert("i64.from_u64"), + I64FromS64 => self.assert("i64.from_s64"), + I32FromU32 => self.assert("i32.from_u32"), + I32FromS32 => self.assert("i32.from_s32"), + I32FromUsize => self.assert("i32.from_usize"), + I32FromU16 => self.assert("i32.from_u16"), + I32FromS16 => self.assert("i32.from_s16"), + I32FromU8 => self.assert("i32.from_u8"), + I32FromS8 => self.assert("i32.from_s8"), + I32FromChar8 => self.assert("i32.from_char8"), + I32FromPointer => self.assert("i32.from_pointer"), + I32FromConstPointer => self.assert("i32.from_const_pointer"), + I32FromHandle { .. } => self.assert("i32.from_handle"), + ListPointerLength => self.assert("list.pointer_length"), + ListFromPointerLength { .. } => self.assert("list.from_pointer_length"), + F32FromIf32 => self.assert("f32.from_if32"), + F64FromIf64 => self.assert("f64.from_if64"), + CallWasm { .. } => self.assert("call.wasm"), + CallInterface { .. } => self.assert("call.interface"), + S8FromI32 => self.assert("s8.from_i32"), + U8FromI32 => self.assert("u8.from_i32"), + S16FromI32 => self.assert("s16.from_i32"), + U16FromI32 => self.assert("u16.from_i32"), + S32FromI32 => self.assert("s32.from_i32"), + U32FromI32 => self.assert("u32.from_i32"), + S64FromI64 => self.assert("s64.from_i64"), + U64FromI64 => self.assert("u64.from_i64"), + CharFromI32 => self.assert("char.from_i32"), + Char8FromI32 => self.assert("char8.from_i32"), + UsizeFromI32 => self.assert("usize.from_i32"), + If32FromF32 => self.assert("if32.from_f32"), + If64FromF64 => self.assert("if64.from_f64"), + HandleFromI32 { .. } => self.assert("handle.from_i32"), + PointerFromI32 { .. } => self.assert("pointer.from_i32"), + ConstPointerFromI32 { .. } => self.assert("const_pointer.from_i32"), + ReturnPointerGet { n } => self.assert(&format!("return_pointer.get{}", n)), + ResultLift => self.assert("result.lift"), + ResultLower { .. } => self.assert("result.lower"), + EnumLift { .. } => self.assert("enum.lift"), + EnumLower { .. } => self.assert("enum.lower"), + TupleLift { .. } => self.assert("tuple.lift"), + TupleLower { .. } => self.assert("tuple.lower"), + ReuseReturn => self.assert("reuse_return"), + Load { .. } => self.assert("load"), + Store { .. } => self.assert("store"), + Return { .. } => self.assert("return"), + VariantPayload => self.assert("variant-payload"), + I32FromBitflags { .. } => self.assert("i32.from_bitflags"), + BitflagsFromI32 { .. } => self.assert("bitflags.from_i32"), + I64FromBitflags { .. } => self.assert("i64.from_bitflags"), + BitflagsFromI64 { .. } => self.assert("bitflags.from_i64"), + } + for _ in 0..inst.results_len() { + results.push(()); + } + } + + fn allocate_space(&mut self, _: usize, _: &witx::NamedType) { + self.assert("allocate-space"); + } + + fn push_block(&mut self) { + self.assert("block.push"); + } + + fn finish_block(&mut self, _operand: Option) { + self.assert("block.finish"); + } +} + mod kw { wast::custom_keyword!(assert_invalid); wast::custom_keyword!(assert_representable); + wast::custom_keyword!(assert_abi); wast::custom_keyword!(witx); wast::custom_keyword!(eq); wast::custom_keyword!(noteq); wast::custom_keyword!(load); wast::custom_keyword!(superset); + wast::custom_keyword!(call_wasm); + wast::custom_keyword!(call_interface); + wast::custom_keyword!(param); + wast::custom_keyword!(result); + wast::custom_keyword!(wasm); + wast::custom_keyword!(i32); + wast::custom_keyword!(i64); + wast::custom_keyword!(f32); + wast::custom_keyword!(f64); } struct Witxt<'a> { @@ -286,6 +449,13 @@ enum WitxtDirective<'a> { t1: (wast::Id<'a>, &'a str), t2: (wast::Id<'a>, &'a str), }, + AssertAbi { + span: wast::Span, + witx: Witx<'a>, + wasm_signature: (Vec, Vec), + wasm: Abi<'a>, + interface: Abi<'a>, + }, } impl WitxtDirective<'_> { @@ -293,6 +463,7 @@ impl WitxtDirective<'_> { match self { WitxtDirective::Witx(w) => w.span, WitxtDirective::AssertInvalid { span, .. } + | WitxtDirective::AssertAbi { span, .. } | WitxtDirective::AssertRepresentable { span, .. } => *span, } } @@ -318,12 +489,69 @@ impl<'a> Parse<'a> for WitxtDirective<'a> { t1: (parser.parse()?, parser.parse()?), t2: (parser.parse()?, parser.parse()?), }) + } else if l.peek::() { + let span = parser.parse::()?.0; + Ok(WitxtDirective::AssertAbi { + span, + witx: parser.parens(|p| p.parse())?, + wasm_signature: parser.parens(|p| { + p.parse::()?; + let mut params = Vec::new(); + let mut results = Vec::new(); + if p.peek2::() { + p.parens(|p| { + p.parse::()?; + while !p.is_empty() { + params.push(parse_wasmtype(p)?); + } + Ok(()) + })?; + } + if p.peek2::() { + p.parens(|p| { + p.parse::()?; + while !p.is_empty() { + results.push(parse_wasmtype(p)?); + } + Ok(()) + })?; + } + Ok((params, results)) + })?, + wasm: parser.parens(|p| { + p.parse::()?; + p.parse() + })?, + interface: parser.parens(|p| { + p.parse::()?; + p.parse() + })?, + }) } else { Err(l.error()) } } } +fn parse_wasmtype(p: Parser<'_>) -> parser::Result { + let mut l = p.lookahead1(); + if l.peek::() { + p.parse::()?; + Ok(WasmType::I32) + } else if l.peek::() { + p.parse::()?; + Ok(WasmType::I64) + } else if l.peek::() { + p.parse::()?; + Ok(WasmType::F32) + } else if l.peek::() { + p.parse::()?; + Ok(WasmType::F64) + } else { + Err(l.error()) + } +} + struct Witx<'a> { span: wast::Span, id: Option>, @@ -407,3 +635,22 @@ impl<'a> Parse<'a> for RepEquality { } } } + +struct Abi<'a> { + instrs: Vec<(wast::Span, &'a str)>, +} + +impl<'a> Parse<'a> for Abi<'a> { + fn parse(parser: Parser<'a>) -> parser::Result { + let mut instrs = Vec::new(); + while !parser.is_empty() { + instrs.push(parser.step(|cursor| { + let (kw, next) = cursor + .keyword() + .ok_or_else(|| cursor.error("expected keyword"))?; + Ok(((cursor.cur_span(), kw), next)) + })?); + } + Ok(Abi { instrs }) + } +} diff --git a/proposals/random/tools/witx/tests/witxt/abi.witxt b/proposals/random/tools/witx/tests/witxt/abi.witxt new file mode 100644 index 000000000..ccdad7bf4 --- /dev/null +++ b/proposals/random/tools/witx/tests/witxt/abi.witxt @@ -0,0 +1,490 @@ +(assert_abi + (witx (module $x (@interface func (export "f")))) + (wasm) + (call_wasm call.wasm return) + (call_interface call.interface return) +) + +;; scalar arguments +(assert_abi + (witx (module $x (@interface func (export "f") (param $p u8)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_u8 call.wasm return) + (call_interface get-arg0 u8.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p s8)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_s8 call.wasm return) + (call_interface get-arg0 s8.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p u16)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_u16 call.wasm return) + (call_interface get-arg0 u16.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p s16)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_s16 call.wasm return) + (call_interface get-arg0 s16.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p u32)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_u32 call.wasm return) + (call_interface get-arg0 u32.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p s32)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_s32 call.wasm return) + (call_interface get-arg0 s32.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p u64)))) + (wasm (param i64)) + (call_wasm get-arg0 i64.from_u64 call.wasm return) + (call_interface get-arg0 u64.from_i64 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p s64)))) + (wasm (param i64)) + (call_wasm get-arg0 i64.from_s64 call.wasm return) + (call_interface get-arg0 s64.from_i64 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p f32)))) + (wasm (param f32)) + (call_wasm get-arg0 f32.from_if32 call.wasm return) + (call_interface get-arg0 if32.from_f32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p f64)))) + (wasm (param f64)) + (call_wasm get-arg0 f64.from_if64 call.wasm return) + (call_interface get-arg0 if64.from_f64 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p (@witx usize))))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_usize call.wasm return) + (call_interface get-arg0 usize.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p (@witx char8))))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_char8 call.wasm return) + (call_interface get-arg0 char8.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p char)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_char call.wasm return) + (call_interface get-arg0 char.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p (@witx pointer u8))))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_pointer call.wasm return) + (call_interface get-arg0 pointer.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p (@witx const_pointer u8))))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_const_pointer call.wasm return) + (call_interface get-arg0 const_pointer.from_i32 call.interface return) +) + +;; flags parameter +(assert_abi + (witx + (typename $a (flags $x $y)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_bitflags call.wasm return) + (call_interface get-arg0 bitflags.from_i32 call.interface return) +) +(assert_abi + (witx + (typename $a (flags (@witx repr u64) $x $y)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i64)) + (call_wasm get-arg0 i64.from_bitflags call.wasm return) + (call_interface get-arg0 bitflags.from_i64 call.interface return) +) + +;; struct parameter +(assert_abi + (witx + (typename $a (record (field $x u8))) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 addr-of call.wasm return) + (call_interface get-arg0 load call.interface return) +) + +;; handle parameter +(assert_abi + (witx + (typename $a (handle)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_handle call.wasm return) + (call_interface get-arg0 handle.from_i32 call.interface return) +) + +;; list parameter +(assert_abi + (witx + (module $x (@interface func (export "f") (param $p (list u8)))) + ) + (wasm (param i32 i32)) + (call_wasm get-arg0 list.pointer_length call.wasm return) + (call_interface get-arg0 get-arg1 list.from_pointer_length call.interface return) +) + +;; variant parameter -- some not allowed at this time +(assert_abi + (witx + (typename $a (enum $b)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 enum.lower call.wasm return) + (call_interface get-arg0 enum.lift call.interface return) +) +(assert_abi + (witx + (typename $a (union f32)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 addr-of call.wasm return) + (call_interface get-arg0 load call.interface return) +) + +;; scalar returns +(assert_abi + (witx (module $x (@interface func (export "f") (result $p u8)))) + (wasm (result i32)) + (call_wasm call.wasm u8.from_i32 return) + (call_interface call.interface i32.from_u8 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p s8)))) + (wasm (result i32)) + (call_wasm call.wasm s8.from_i32 return) + (call_interface call.interface i32.from_s8 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p u16)))) + (wasm (result i32)) + (call_wasm call.wasm u16.from_i32 return) + (call_interface call.interface i32.from_u16 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p s16)))) + (wasm (result i32)) + (call_wasm call.wasm s16.from_i32 return) + (call_interface call.interface i32.from_s16 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p u32)))) + (wasm (result i32)) + (call_wasm call.wasm u32.from_i32 return) + (call_interface call.interface i32.from_u32 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p s32)))) + (wasm (result i32)) + (call_wasm call.wasm s32.from_i32 return) + (call_interface call.interface i32.from_s32 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p u64)))) + (wasm (result i64)) + (call_wasm call.wasm u64.from_i64 return) + (call_interface call.interface i64.from_u64 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p s64)))) + (wasm (result i64)) + (call_wasm call.wasm s64.from_i64 return) + (call_interface call.interface i64.from_s64 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p f32)))) + (wasm (result f32)) + (call_wasm call.wasm if32.from_f32 return) + (call_interface call.interface f32.from_if32 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p f64)))) + (wasm (result f64)) + (call_wasm call.wasm if64.from_f64 return) + (call_interface call.interface f64.from_if64 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p (@witx usize))))) + (wasm (result i32)) + (call_wasm call.wasm usize.from_i32 return) + (call_interface call.interface i32.from_usize return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p (@witx char8))))) + (wasm (result i32)) + (call_wasm call.wasm char8.from_i32 return) + (call_interface call.interface i32.from_char8 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p char)))) + (wasm (result i32)) + (call_wasm call.wasm char.from_i32 return) + (call_interface call.interface i32.from_char return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p (@witx pointer u8))))) + (wasm (result i32)) + (call_wasm call.wasm pointer.from_i32 return) + (call_interface call.interface i32.from_pointer return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p (@witx const_pointer u8))))) + (wasm (result i32)) + (call_wasm call.wasm const_pointer.from_i32 return) + (call_interface call.interface i32.from_const_pointer return) +) + +;; flags return +(assert_abi + (witx + (typename $a (flags $x $y)) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (result i32)) + (call_wasm call.wasm bitflags.from_i32 return) + (call_interface call.interface i32.from_bitflags return) +) +(assert_abi + (witx + (typename $a (flags (@witx repr u64) $x $y)) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (result i64)) + (call_wasm call.wasm bitflags.from_i64 return) + (call_interface call.interface i64.from_bitflags return) +) + +;; handle return +(assert_abi + (witx + (typename $a (handle)) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (result i32)) + (call_wasm call.wasm handle.from_i32 return) + (call_interface call.interface i32.from_handle return) +) + +;; struct return -- not supported +(assert_invalid + (witx + (typename $a (record (field $x u8))) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: invalid return type" +) + +;; list return -- not supported +(assert_invalid + (witx + (module $x (@interface func (export "f") (result $p (list u8)))) + ) + "ABI error: invalid return type" +) + +;; variant return -- only some allowed +(assert_invalid + (witx + (typename $a (enum $b)) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: invalid return type" +) +(assert_invalid + (witx + (typename $a (union s32 f32)) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: invalid return type" +) +(assert_invalid + (witx + (typename $a (expected (error f32))) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: only named types are allowed in results" +) +(assert_invalid + (witx + (typename $errno (enum $success $bad)) + (typename $a (expected f32 (error $errno))) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: only named types are allowed in results" +) + +;; Result<(), $errno> +(assert_abi + (witx + (typename $errno (enum $success $bad)) + (typename $a (expected (error $errno))) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (result i32)) + + (call_wasm + call.wasm + ;; ok block, nothing happens + block.push + block.finish + ;; err block, we lift the return value as the num + block.push + reuse_return + enum.lift + block.finish + ;; consumes 2 blocks and uses the return value of the call to discriminate + result.lift + return) + + (call_interface + call.interface + + ;; ok block, nothing happens + block.push + block.finish + + ;; err block, lift the enum + block.push + variant-payload + enum.lower + block.finish + + ;; consume the 2 blocks and lower based on the call + result.lower + return) +) + +;; Result<$ty, $errno> +(assert_abi + (witx + (typename $errno (enum $success $bad)) + (typename $size u32) + (typename $a (expected $size (error $errno))) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (param i32) (result i32)) + + (call_wasm + ;; make space for the return value and push its pointer + allocate-space + return_pointer.get0 + + call.wasm + + ;; ok block, load the return pointer and have it be the result for the `Ok` + block.push + return_pointer.get0 + load + block.finish + + block.push + reuse_return + enum.lift + block.finish + + result.lift + return) + + (call_interface + call.interface + + ;; store the successful result at the first return pointer (the first param) + block.push + variant-payload + get-arg0 + store + block.finish + + block.push + variant-payload + enum.lower + block.finish + + result.lower + return) +) + +;; Result<($a, $b), $errno> +(assert_abi + (witx + (typename $errno (enum $success $bad)) + (typename $size u32) + (typename $other (record (field $a $size))) + (module $x (@interface func (export "f") + (result $p (expected (tuple $size $other) (error $errno))))) + ) + (wasm (param i32 i32) (result i32)) + + (call_wasm + allocate-space + return_pointer.get0 + allocate-space + return_pointer.get1 + + call.wasm + + block.push + return_pointer.get0 + load + return_pointer.get1 + load + tuple.lift + block.finish + + block.push + reuse_return + enum.lift + block.finish + + result.lift + return) + + (call_interface + call.interface + + ;; note the reverse order since we're consuming the results of lowering the + ;; tuple + block.push + variant-payload + tuple.lower + get-arg1 + store + get-arg0 + store + block.finish + + block.push + variant-payload + enum.lower + block.finish + + result.lower + return) +) diff --git a/proposals/random/tools/witx/tests/witxt/representation.witxt b/proposals/random/tools/witx/tests/witxt/representation.witxt index 37d20a70a..53f71f196 100644 --- a/proposals/random/tools/witx/tests/witxt/representation.witxt +++ b/proposals/random/tools/witx/tests/witxt/representation.witxt @@ -1,8 +1,8 @@ ;; type names don't matter (witx $a - (typename $a (flags (@witx bitflags u8) $b $c))) + (typename $a (flags (@witx repr u8) $b $c))) (witx $b - (typename $b (flags (@witx bitflags u8) $b $c))) + (typename $b (flags (@witx repr u8) $b $c))) (assert_representable eq $a "a" $b "b") (assert_representable eq $b "b" $a "a") diff --git a/proposals/random/tools/witx/tests/witxt/shorthand.witxt b/proposals/random/tools/witx/tests/witxt/shorthand.witxt new file mode 100644 index 000000000..960615f3c --- /dev/null +++ b/proposals/random/tools/witx/tests/witxt/shorthand.witxt @@ -0,0 +1,59 @@ +(witx $a + (typename $a bool)) +(witx $b + (typename $a (variant (case $false) (case $true)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (expected (error)))) +(witx $b + (typename $a (variant (case $ok) (case $err)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (expected (error u32)))) +(witx $b + (typename $a (variant (case $ok) (case $err u32)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (expected u32 (error)))) +(witx $b + (typename $a (variant (case $ok u32) (case $err)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (expected u32 (error u64)))) +(witx $b + (typename $a (variant (case $ok u32) (case $err u64)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (flags $a $b))) +(witx $b + (typename $a (record (field $a bool) (field $b bool)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (enum $a $b))) +(witx $b + (typename $a (variant (case $a) (case $b)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a string)) +(witx $b + (typename $a (list char))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (tuple u32 u64))) +(witx $b + (typename $a (record (field $0 u32) (field $1 u64)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (union u32 u64))) +(witx $b + (typename $a (variant (case $0 u32) (case $1 u64)))) +(assert_representable eq $a "a" $b "a") From 41ee4144ce664837a158b0fa87f782ef6656b627 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 18 Feb 2021 11:39:17 -0600 Subject: [PATCH 0870/1772] Take another step towards interface types (#395) * Take another step towards interface types This commit is another large refactoring on the tail of #391 which is intended to help march one step closer to using pure interface types for specifying WASI and using `*.witx` files. Contained here is a large amount of refactoring of the `*.witx` files, the internals of the `witx` crate, and how code generators are supposed to work. At the `*.witx` level, some notable changes have been made: * All functions returning results now return `(expected ok? (error $errno))`. This helps signify that the intention of all functions is that they return a packaged value which is either a successful result or the erroneous error code on failure. ABI-wise nothing has changed, but this is intended to model more closely what the interface-types API of this would be. * The `flags` type in `*.witx` now desugars as a struct-of-bools rather than simply an `int`. This doesn't have any effect on the ABI today, but it does change the AST and type-level representation of these types. All existing `*.witx` files in this repository have been updated for all phases with these new forms. To reiterate, though, no details of the ABI have changed (or at least not intentionally). Everything should still be ABI-compatible with before. Under the hood for code generators this is a very large breaking change. The intention of this commit is to start moving code generators relying on `witx` into the direction that we'll end up with interface types. Namely the `coretypes` module is entirely replaced with a new `abi` module with the intention of handling lots more high-level details of translation than the previous module did. The `InterfaceFunc` type now sports two new methods: `call_wasm` and `call_interface`. These two methods represent the two halves of lifting/lowering operations performed by code generators. The `call_wasm` function takes interface types values (or whatever they are represented as in the source language) and converts them to wasm types to call a wasm import. The wasm import's return values are then "deserialized" back into the language's interface types values too. The `call_interface` function is the opposite, it assumes that you're coming from wasm values and calling, e.g., a host function with interface values. The `abi` module is refactored with an `Instruction` `enum` which lists out what are the current set of "adapter instructions". These adapter instructions are intended to somewhat model the eventual idea of adapter functions and their instructions, but for now they're pretty specific to WASI as-is today. All instructions currently model what WASI currently does, sometimes in very specific manners. It's expected that the `Instruction` type will be in flux as we tweak the ABI of WASI over time, but the current set of instructions will likely only be expanded because of maintaining compatibility with the current snapshot. The expected usage of `Instruction` is that code generators will implement how to generate code for each `Instruction`. This should be a very low-level operation (generating code per instruction) and should be in theory quite easy to implement. Not all code generators need to implement all instructions depending on their use case. Additionally WASI as-is today doesn't always exercise all types of instructions. The next steps after a PR like this include starting to define a new ABI for WASI which supports all types in all positions rather than the current ABI which supports only a limited subset of types in some positions. The intention is that this new ABI may add a new instruction or two but will generally not be a large breaking change for all existing code generators. Some new additions are expected but other than that existing code generators updated to use this PR will require little effort to support new ABIs. * Add more documentation and some more tests for shorthand syntax * Bump to 0.9.0 and bump wast dependency * Support variants as arguments Same as records, they use pointers * Fix a typo --- proposals/filesystem/phases/ephemeral/docs.md | 969 +++++++++++++----- .../phases/ephemeral/witx/typenames.witx | 22 +- .../ephemeral/witx/wasi_ephemeral_args.witx | 10 +- .../ephemeral/witx/wasi_ephemeral_clock.witx | 6 +- .../witx/wasi_ephemeral_environ.witx | 10 +- .../ephemeral/witx/wasi_ephemeral_fd.witx | 54 +- .../ephemeral/witx/wasi_ephemeral_path.witx | 25 +- .../ephemeral/witx/wasi_ephemeral_poll.witx | 3 +- .../ephemeral/witx/wasi_ephemeral_random.witx | 2 +- .../ephemeral/witx/wasi_ephemeral_sched.witx | 2 +- .../ephemeral/witx/wasi_ephemeral_sock.witx | 12 +- .../filesystem/phases/old/snapshot_0/docs.md | 929 +++++++++++++---- .../phases/old/snapshot_0/witx/typenames.witx | 20 +- .../old/snapshot_0/witx/wasi_unstable.witx | 127 +-- proposals/filesystem/phases/snapshot/docs.md | 927 +++++++++++++---- .../phases/snapshot/witx/typenames.witx | 20 +- .../snapshot/witx/wasi_snapshot_preview1.witx | 125 +-- proposals/filesystem/tools/witx/Cargo.toml | 4 +- proposals/filesystem/tools/witx/src/abi.rs | 925 +++++++++++++++++ proposals/filesystem/tools/witx/src/ast.rs | 178 +++- .../filesystem/tools/witx/src/coretypes.rs | 173 ---- .../filesystem/tools/witx/src/docs/ast.rs | 93 +- .../filesystem/tools/witx/src/docs/md.rs | 51 +- proposals/filesystem/tools/witx/src/layout.rs | 26 +- proposals/filesystem/tools/witx/src/lib.rs | 6 +- proposals/filesystem/tools/witx/src/parser.rs | 77 +- proposals/filesystem/tools/witx/src/render.rs | 61 +- .../filesystem/tools/witx/src/toplevel.rs | 6 +- .../filesystem/tools/witx/src/validate.rs | 172 +++- .../filesystem/tools/witx/tests/witxt.rs | 249 ++++- .../tools/witx/tests/witxt/abi.witxt | 490 +++++++++ .../witx/tests/witxt/representation.witxt | 4 +- .../tools/witx/tests/witxt/shorthand.witxt | 59 ++ 33 files changed, 4528 insertions(+), 1309 deletions(-) create mode 100644 proposals/filesystem/tools/witx/src/abi.rs delete mode 100644 proposals/filesystem/tools/witx/src/coretypes.rs create mode 100644 proposals/filesystem/tools/witx/tests/witxt/abi.witxt create mode 100644 proposals/filesystem/tools/witx/tests/witxt/shorthand.witxt diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index a3c0d0a47..7fa4c11de 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -22,7 +22,7 @@ Size: 8 Alignment: 8 -## `clockid`: Variant +## `clockid`: `Variant` Identifiers for clocks. Size: 4 @@ -40,7 +40,7 @@ real time, whose value cannot be adjusted and which cannot have negative clock jumps. The epoch of this clock is undefined. The absolute time value of this clock therefore has no meaning. -## `errno`: Variant +## `errno`: `Variant` Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -282,82 +282,120 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: `u64` +## `rights`: `Record` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Constants -- `fd_datasync` +### Record members +- `fd_datasync`: `bool` The right to invoke `fd_datasync`. If `path_open` is set, includes the right to invoke `path_open` with [`fdflags::dsync`](#fdflags.dsync). -- `fd_read` +Bit: 0 + +- `fd_read`: `bool` The right to invoke `fd_read` and `sock_recv`. If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. -- `fd_seek` +Bit: 1 + +- `fd_seek`: `bool` The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). -- `fd_fdstat_set_flags` +Bit: 2 + +- `fd_fdstat_set_flags`: `bool` The right to invoke `fd_fdstat_set_flags`. -- `fd_sync` +Bit: 3 + +- `fd_sync`: `bool` The right to invoke `fd_sync`. If `path_open` is set, includes the right to invoke `path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). -- `fd_tell` +Bit: 4 + +- `fd_tell`: `bool` The right to invoke `fd_seek` in such a way that the file offset remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke `fd_tell`. -- `fd_write` +Bit: 5 + +- `fd_write`: `bool` The right to invoke `fd_write` and `sock_send`. If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. -- `fd_advise` +Bit: 6 + +- `fd_advise`: `bool` The right to invoke `fd_advise`. -- `fd_allocate` +Bit: 7 + +- `fd_allocate`: `bool` The right to invoke `fd_allocate`. -- `path_create_directory` +Bit: 8 + +- `path_create_directory`: `bool` The right to invoke `path_create_directory`. -- `path_create_file` +Bit: 9 + +- `path_create_file`: `bool` If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). -- `path_link_source` +Bit: 10 + +- `path_link_source`: `bool` The right to invoke `path_link` with the file descriptor as the source directory. -- `path_link_target` +Bit: 11 + +- `path_link_target`: `bool` The right to invoke `path_link` with the file descriptor as the target directory. -- `path_open` +Bit: 12 + +- `path_open`: `bool` The right to invoke `path_open`. -- `fd_readdir` +Bit: 13 + +- `fd_readdir`: `bool` The right to invoke `fd_readdir`. -- `path_readlink` +Bit: 14 + +- `path_readlink`: `bool` The right to invoke `path_readlink`. -- `path_rename_source` +Bit: 15 + +- `path_rename_source`: `bool` The right to invoke `path_rename` with the file descriptor as the source directory. -- `path_rename_target` +Bit: 16 + +- `path_rename_target`: `bool` The right to invoke `path_rename` with the file descriptor as the target directory. -- `path_filestat_get` +Bit: 17 + +- `path_filestat_get`: `bool` The right to invoke `path_filestat_get`. -- `path_filestat_set_size` +Bit: 18 + +- `path_filestat_set_size`: `bool` The right to change a file's size. If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). Note: there is no function named `path_filestat_set_size`. This follows POSIX design, @@ -366,41 +404,65 @@ While such function would be desirable from the API design perspective, there ar no use cases for it since no code written for POSIX systems would use it. Moreover, implementing it would require multiple syscalls, leading to inferior performance. -- `path_filestat_set_times` +Bit: 19 + +- `path_filestat_set_times`: `bool` The right to invoke `path_filestat_set_times`. -- `path_permissions_set` +Bit: 20 + +- `path_permissions_set`: `bool` The right to invoke `path_permissions_set`. -- `fd_filestat_get` +Bit: 21 + +- `fd_filestat_get`: `bool` The right to invoke `fd_filestat_get`. -- `fd_filestat_set_size` +Bit: 22 + +- `fd_filestat_set_size`: `bool` The right to invoke `fd_filestat_set_size`. -- `fd_filestat_set_times` +Bit: 23 + +- `fd_filestat_set_times`: `bool` The right to invoke `fd_filestat_set_times`. -- `fd_permissions_set` +Bit: 24 + +- `fd_permissions_set`: `bool` The right to invoke `fd_permissions_set`. -- `path_symlink` +Bit: 25 + +- `path_symlink`: `bool` The right to invoke `path_symlink`. -- `path_remove_directory` +Bit: 26 + +- `path_remove_directory`: `bool` The right to invoke `path_remove_directory`. -- `path_unlink_file` +Bit: 27 + +- `path_unlink_file`: `bool` The right to invoke `path_unlink_file`. -- `poll_fd_readwrite` +Bit: 28 + +- `poll_fd_readwrite`: `bool` If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). -- `sock_shutdown` +Bit: 29 + +- `sock_shutdown`: `bool` The right to invoke `sock_shutdown`. -## `fd` +Bit: 30 + +## `fd`: `Handle` A file descriptor handle. Size: 4 @@ -408,7 +470,7 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Record +## `iovec`: `Record` A region of memory for scatter/gather reads. Size: 8 @@ -426,7 +488,7 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Record +## `ciovec`: `Record` A region of memory for scatter/gather writes. Size: 8 @@ -463,7 +525,7 @@ Size: 8 Alignment: 8 -## `whence`: Variant +## `whence`: `Variant` The position relative to which to set the offset of the file descriptor. Size: 1 @@ -504,7 +566,7 @@ Size: 8 Alignment: 8 -## `filetype`: Variant +## `filetype`: `Variant` The type of a file descriptor or file. Size: 1 @@ -539,7 +601,7 @@ The file refers to a symbolic link inode. - `fifo` The file descriptor or file refers to a FIFO. -## `dirent`: Record +## `dirent`: `Record` A directory entry. Size: 24 @@ -567,7 +629,7 @@ The length of the name of the directory entry. Offset: 20 -## `advice`: Variant +## `advice`: `Variant` File or memory access pattern advisory information. Size: 1 @@ -593,32 +655,42 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: `u16` +## `fdflags`: `Record` File descriptor flags. Size: 2 Alignment: 2 -### Constants -- `append` +### Record members +- `append`: `bool` Append mode: Data written to the file is always appended to the file's end. -- `dsync` +Bit: 0 + +- `dsync`: `bool` Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. -- `nonblock` +Bit: 1 + +- `nonblock`: `bool` Non-blocking mode. -- `rsync` +Bit: 2 + +- `rsync`: `bool` Synchronized read I/O operations. -- `sync` +Bit: 3 + +- `sync`: `bool` Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Record +Bit: 4 + +## `fdstat`: `Record` File descriptor attributes. Size: 24 @@ -655,57 +727,75 @@ Size: 8 Alignment: 8 -## `fstflags`: `u16` +## `fstflags`: `Record` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Constants -- `atim` +### Record members +- `atim`: `bool` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). -- `atim_now` +Bit: 0 + +- `atim_now`: `bool` Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -- `mtim` +Bit: 1 + +- `mtim`: `bool` Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). -- `mtim_now` +Bit: 2 + +- `mtim_now`: `bool` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: `u32` +Bit: 3 + +## `lookupflags`: `Record` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Constants -- `symlink_follow` +### Record members +- `symlink_follow`: `bool` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: `u16` +Bit: 0 + +## `oflags`: `Record` Open flags used by `path_open`. Size: 2 Alignment: 2 -### Constants -- `create` +### Record members +- `create`: `bool` Create file if it does not exist. -- `directory` +Bit: 0 + +- `directory`: `bool` Fail if not a directory. -- `excl` +Bit: 1 + +- `excl`: `bool` Fail if file already exists. -- `trunc` +Bit: 2 + +- `trunc`: `bool` Truncate file to size 0. +Bit: 3 + ## `linkcount`: `u64` Number of hard links to an inode. @@ -713,7 +803,7 @@ Size: 8 Alignment: 8 -## `permissions`: `u8` +## `permissions`: `Record` File permissions. This represents the permissions associated with a file in a filesystem, and don't fully reflect all the conditions which determine whether a given WASI program can access the file. @@ -722,8 +812,8 @@ Size: 1 Alignment: 1 -### Constants -- `read` +### Record members +- `read`: `bool` For files, permission to read the file. For directories, permission to do [`readdir`](#readdir) and access files within the directory. @@ -731,23 +821,31 @@ within the directory. Note: This is similar to the read bit being set on files, and the read *and* execute bits being set on directories, in POSIX. -- `write` +Bit: 0 + +- `write`: `bool` For files, permission to mutate the file. For directories, permission to create, remove, and rename items within the directory. -- `execute` +Bit: 1 + +- `execute`: `bool` For files, permission to "execute" the file, using whatever concept of "executing" the host filesystem has. This flag is not valid for directories. -- `private` +Bit: 2 + +- `private`: `bool` For filesystems which have a concept of multiple "users", this flag indicates that the file is only accessible by the effective "user" that the WASI store uses to access the filesystem, and inaccessible to other "users". -## `filestat`: Record +Bit: 3 + +## `filestat`: `Record` File attributes. Size: 64 @@ -808,7 +906,7 @@ Size: 8 Alignment: 8 -## `eventtype`: Variant +## `eventtype`: `Variant` Type of a subscription to an event or its occurrence. Size: 1 @@ -828,7 +926,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: `u16` +## `eventrwflags`: `Record` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -836,11 +934,13 @@ Size: 2 Alignment: 2 -### Constants -- `fd_readwrite_hangup` +### Record members +- `fd_readwrite_hangup`: `bool` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Record +Bit: 0 + +## `event_fd_readwrite`: `Record` The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -859,7 +959,7 @@ The state of the file descriptor. Offset: 8 -## `event_u`: Variant +## `event_u`: `Variant` The contents of an [`event`](#event). Size: 24 @@ -877,7 +977,7 @@ Alignment: 8 - `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) -## `event`: Record +## `event`: `Record` An event that occurred. Size: 40 @@ -900,7 +1000,7 @@ The type of the event that occurred, and the contents of the event Offset: 16 -## `subclockflags`: `u16` +## `subclockflags`: `Record` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -908,15 +1008,17 @@ Size: 2 Alignment: 2 -### Constants -- `subscription_clock_abstime` +### Record members +- `subscription_clock_abstime`: `bool` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock [`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Record +Bit: 0 + +## `subscription_clock`: `Record` The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 32 @@ -945,7 +1047,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 24 -## `subscription_fd_readwrite`: Record +## `subscription_fd_readwrite`: `Record` The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -959,7 +1061,7 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Variant +## `subscription_u`: `Variant` The contents of a [`subscription`](#subscription). Size: 40 @@ -977,7 +1079,7 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Record +## `subscription`: `Record` Subscription to an event. Size: 48 @@ -1003,31 +1105,37 @@ Size: 4 Alignment: 4 -## `riflags`: `u16` +## `riflags`: `Record` Flags provided to `sock_recv`. Size: 2 Alignment: 2 -### Constants -- `recv_peek` +### Record members +- `recv_peek`: `bool` Returns the message without removing it from the socket's receive queue. -- `recv_waitall` +Bit: 0 + +- `recv_waitall`: `bool` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: `u16` +Bit: 1 + +## `roflags`: `Record` Flags returned by `sock_recv`. Size: 2 Alignment: 2 -### Constants -- `recv_data_truncated` +### Record members +- `recv_data_truncated`: `bool` Returned by `sock_recv`: Message data has been truncated. +Bit: 0 + ## `siflags`: `u16` Flags provided to `sock_send`. As there are currently no flags defined, it must be set to zero. @@ -1036,21 +1144,25 @@ Size: 2 Alignment: 2 -## `sdflags`: `u8` +## `sdflags`: `Record` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Constants -- `rd` +### Record members +- `rd`: `bool` Disables further receive operations. -- `wr` +Bit: 0 + +- `wr`: `bool` Disables further send operations. -## `preopentype`: Variant +Bit: 1 + +## `preopentype`: `Variant` Identifiers for preopened capabilities. Size: 1 @@ -1061,7 +1173,7 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Record +## `prestat_dir`: `Record` The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). Size: 4 @@ -1074,7 +1186,7 @@ The length of the directory name for use with `fd_prestat_dir_name`. Offset: 0 -## `prestat`: Variant +## `prestat`: `Variant` Information about a pre-opened capability. Size: 8 @@ -1097,7 +1209,7 @@ When type is [`preopentype::dir`](#preopentype.dir): --- -#### `get(argv: Pointer>, argv_buf: Pointer) -> errno` +#### `get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. The size of the array should match that returned by [`sizes_get`](#sizes_get) @@ -1107,23 +1219,46 @@ The size of the array should match that returned by [`sizes_get`](#sizes_get) - `argv_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sizes_get() -> (errno, size, size)` +#### `sizes_get() -> Result<(size, size), errno>` Return command-line argument data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of arguments and the size of the argument string +data, or an error. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` -- `argc`: [`size`](#size) -The number of arguments. +####### Record members +- `0`: [`size`](#size) -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +Offset: 0 + +- `1`: [`size`](#size) + +Offset: 4 + +- `err`: [`errno`](#errno) ## wasi_ephemeral_clock ### Imports @@ -1132,7 +1267,7 @@ The size of the argument string data. --- -#### `res_get(id: clockid) -> (errno, timestamp)` +#### `res_get(id: clockid) -> Result` Return the resolution of a clock. Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return [`errno::inval`](#errno.inval). @@ -1143,15 +1278,22 @@ Note: This is similar to `clock_getres` in POSIX. The clock for which to return the resolution. ##### Results -- `error`: [`errno`](#errno) - -- `resolution`: [`timestamp`](#timestamp) +- `error`: `Result` The resolution of the clock. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) + +- `err`: [`errno`](#errno) + --- -#### `time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +#### `time_get(id: clockid, precision: timestamp) -> Result` Return the time value of a clock. Note: This is similar to `clock_gettime` in POSIX. @@ -1163,11 +1305,18 @@ The clock for which to return the time. The maximum lag (exclusive) that the returned time value may have, compared to its actual value. ##### Results -- `error`: [`errno`](#errno) - -- `time`: [`timestamp`](#timestamp) +- `error`: `Result` The time value of the clock. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) + +- `err`: [`errno`](#errno) + ## wasi_ephemeral_environ ### Imports #### Memory @@ -1175,7 +1324,7 @@ The time value of the clock. --- -#### `get(environ: Pointer>, environ_buf: Pointer) -> errno` +#### `get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). @@ -1185,23 +1334,46 @@ The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get) - `environ_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sizes_get() -> (errno, size, size)` +#### `sizes_get() -> Result<(size, size), errno>` Return environment variable data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of environment variable arguments and the size of the +environment variable data. -- `environc`: [`size`](#size) -The number of environment variable arguments. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) + +Offset: 0 -- `environ_buf_size`: [`size`](#size) -The size of the environment variable data. +- `1`: [`size`](#size) + +Offset: 4 + +- `err`: [`errno`](#errno) ## wasi_ephemeral_fd ### Imports @@ -1210,7 +1382,7 @@ The size of the environment variable data. --- -#### `advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +#### `advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` Provide file advisory information on a file descriptor. Note: This is similar to `posix_fadvise` in POSIX. @@ -1227,12 +1399,21 @@ The length of the region to which the advisory applies. The advice. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `allocate(fd: fd, offset: filesize, len: filesize) -> errno` +#### `allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` Force the allocation of space in a file. Note: This is similar to `posix_fallocate` in POSIX. @@ -1246,12 +1427,21 @@ The offset at which to start the allocation. The length of the area that is allocated. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `close(fd: fd) -> errno` +#### `close(fd: fd) -> Result<(), errno>` Close a file descriptor. Note: This is similar to [`close`](#close) in POSIX. @@ -1259,12 +1449,21 @@ Note: This is similar to [`close`](#close) in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `datasync(fd: fd) -> errno` +#### `datasync(fd: fd) -> Result<(), errno>` Synchronize the data of a file to disk. Note: This is similar to `fdatasync` in POSIX. @@ -1272,12 +1471,21 @@ Note: This is similar to `fdatasync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fdstat_get(fd: fd) -> (errno, fdstat)` +#### `fdstat_get(fd: fd) -> Result` Get the attributes of a file descriptor. Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. @@ -1285,15 +1493,22 @@ Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as ad - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `stat`: [`fdstat`](#fdstat) +- `error`: `Result` The buffer where the file descriptor's attributes are stored. +###### Variant Layout +- size: 32 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`fdstat`](#fdstat) + +- `err`: [`errno`](#errno) + --- -#### `fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +#### `fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` Adjust the flags associated with a file descriptor. Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. @@ -1304,12 +1519,21 @@ Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. The desired values of the file descriptor flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +#### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` Adjust the rights associated with a file descriptor. This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights @@ -1322,27 +1546,43 @@ The desired rights of the file descriptor. - `fs_rights_inheriting`: [`rights`](#rights) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `filestat_get(fd: fd) -> (errno, filestat)` +#### `filestat_get(fd: fd) -> Result` Return the attributes of an open file. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 72 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `filestat_set_size(fd: fd, size: filesize) -> errno` +#### `filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. Note: This is similar to `ftruncate` in POSIX. @@ -1353,12 +1593,21 @@ Note: This is similar to `ftruncate` in POSIX. The desired file size. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of an open file or directory. Note: This is similar to `futimens` in POSIX. @@ -1375,12 +1624,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `permissions_set(fd: fd, permissions: permissions) -> errno` +#### `permissions_set(fd: fd, permissions: permissions) -> Result<(), errno>` Set the permissions of a file or directory. This sets the permissions associated with a file or directory in @@ -1401,12 +1659,21 @@ umask to determine which of the user/group/other flags to modify. The permissions associated with the file. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +#### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` Read from a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `preadv` in Linux (and other Unix-es). @@ -1420,30 +1687,44 @@ List of scatter/gather vectors in which to store data. The offset within the file at which to read. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `prestat_get(fd: fd) -> (errno, prestat)` +#### `prestat_get(fd: fd) -> Result` Return a description of the given preopened file descriptor. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`prestat`](#prestat) +- `error`: `Result` The buffer where the description is stored. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`prestat`](#prestat) + +- `err`: [`errno`](#errno) + --- -#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` Return a description of the given preopened file descriptor. ##### Params @@ -1455,12 +1736,21 @@ A buffer into which to write the preopened directory name. - `path_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +#### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` Write to a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `pwritev` in Linux (and other Unix-es). @@ -1478,15 +1768,22 @@ List of scatter/gather vectors from which to retrieve data. The offset within the file at which to write. ##### Results -- `error`: [`errno`](#errno) - -- `nwritten`: [`size`](#size) +- `error`: `Result` The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `read(fd: fd, iovs: iovec_array) -> (errno, size)` +#### `read(fd: fd, iovs: iovec_array) -> Result` Read from a file descriptor. Note: This is similar to `readv` in POSIX. @@ -1497,15 +1794,22 @@ Note: This is similar to `readv` in POSIX. List of scatter/gather vectors to which to store data. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +#### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of directory entries. Each directory entry consists of a [`dirent`](#dirent) object, @@ -1528,15 +1832,22 @@ The buffer where directory entries are stored The location within the directory to start reading ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `renumber(fd: fd, to: fd) -> errno` +#### `renumber(fd: fd, to: fd) -> Result<(), errno>` Atomically replace a file descriptor by renumbering another file descriptor. Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary @@ -1553,12 +1864,21 @@ would disappear if `dup2()` were to be removed entirely. The file descriptor to overwrite. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +#### `seek(fd: fd, offset: filedelta, whence: whence) -> Result` Move the offset of a file descriptor. Note: This is similar to `lseek` in POSIX. @@ -1572,15 +1892,22 @@ The number of bytes to move. The base from which the offset is relative. ##### Results -- `error`: [`errno`](#errno) - -- `newoffset`: [`filesize`](#filesize) +- `error`: `Result` The new offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `sync(fd: fd) -> errno` +#### `sync(fd: fd) -> Result<(), errno>` Synchronize the data and metadata of a file to disk. Note: This is similar to `fsync` in POSIX. @@ -1588,12 +1915,21 @@ Note: This is similar to `fsync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `tell(fd: fd) -> (errno, filesize)` +#### `tell(fd: fd) -> Result` Return the current offset of a file descriptor. Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. @@ -1601,15 +1937,22 @@ Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `offset`: [`filesize`](#filesize) +- `error`: `Result` The current offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `write(fd: fd, iovs: ciovec_array) -> (errno, size)` +#### `write(fd: fd, iovs: ciovec_array) -> Result` Write to a file descriptor. Note: This is similar to `writev` in POSIX. @@ -1624,11 +1967,18 @@ interleaved while [`write`](#write) is executed. List of scatter/gather vectors from which to retrieve data. ##### Results -- `error`: [`errno`](#errno) - -- `nwritten`: [`size`](#size) +- `error`: `Result` The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + ## wasi_ephemeral_path ### Imports #### Memory @@ -1636,7 +1986,7 @@ The number of bytes written. --- -#### `create_directory(fd: fd, path: string) -> errno` +#### `create_directory(fd: fd, path: string) -> Result<(), errno>` Create a directory. Note: This is similar to `mkdirat` in POSIX. @@ -1647,12 +1997,21 @@ Note: This is similar to `mkdirat` in POSIX. The path at which to create the directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +#### `filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` Return the attributes of a file or directory. Note: This is similar to `stat` in POSIX. @@ -1666,15 +2025,22 @@ Flags determining the method of how the path is resolved. The path of the file or directory to inspect. ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 72 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of a file or directory. Note: This is similar to `utimensat` in POSIX. @@ -1697,12 +2063,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `permissions_set(fd: fd, flags: lookupflags, path: string, permissions: permissions) -> errno` +#### `permissions_set(fd: fd, flags: lookupflags, path: string, permissions: permissions) -> Result<(), errno>` Set the permissions of a file or directory. This sets the permissions associated with a file or directory in @@ -1729,12 +2104,21 @@ The path to a file to query. The permissions to associate with the file. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Create a hard link. Note: This is similar to `linkat` in POSIX. @@ -1754,12 +2138,21 @@ The working directory at which the resolution of the new path starts. The destination path at which to create the hard link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, permissions: permissions) -> (errno, fd)` +#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, permissions: permissions) -> Result` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1798,15 +2191,22 @@ file descriptors derived from it. If a file is created, the filesystem permissions to associate with it. ##### Results -- `error`: [`errno`](#errno) - -- `opened_fd`: [`fd`](#fd) +- `error`: `Result` The file descriptor of the file that has been opened. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`fd`](#fd) + +- `err`: [`errno`](#errno) + --- -#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` Read the contents of a symbolic link. Note: This is similar to `readlinkat` in POSIX. @@ -1822,15 +2222,22 @@ The buffer to which to write the contents of the symbolic link. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes placed in the buffer. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `remove_directory(fd: fd, path: string) -> errno` +#### `remove_directory(fd: fd, path: string) -> Result<(), errno>` Remove a directory. Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. @@ -1842,12 +2249,21 @@ Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. The path to a directory to remove. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Rename a file or directory. Note: This is similar to `renameat` in POSIX. @@ -1864,12 +2280,21 @@ The working directory at which the resolution of the new path starts. The destination path to which to rename the file or directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `symlink(old_path: string, fd: fd, new_path: string) -> errno` +#### `symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` Create a symbolic link. Note: This is similar to `symlinkat` in POSIX. @@ -1883,12 +2308,21 @@ The contents of the symbolic link. The destination path at which to create the symbolic link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `unlink_file(fd: fd, path: string) -> errno` +#### `unlink_file(fd: fd, path: string) -> Result<(), errno>` Unlink a file. Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. @@ -1900,7 +2334,16 @@ Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. The path to a file to unlink. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) ## wasi_ephemeral_poll ### Imports @@ -1909,7 +2352,7 @@ The path to a file to unlink. --- -#### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +#### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` Concurrently poll for the occurrence of a set of events. If `nsubscriptions` is 0, returns [`errno::inval`](#errno.inval). @@ -1925,11 +2368,18 @@ The events that have occurred. Both the number of subscriptions and events. ##### Results -- `error`: [`errno`](#errno) - -- `nevents`: [`size`](#size) +- `error`: `Result` The number of events stored. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + ## wasi_ephemeral_proc ### Imports ### Functions @@ -1953,7 +2403,7 @@ The exit code returned by the process. --- -#### `get(buf: Pointer, buf_len: size) -> errno` +#### `get(buf: Pointer, buf_len: size) -> Result<(), errno>` Write high-quality random data into a buffer. This function blocks when the implementation is unable to immediately provide sufficient high-quality random data. @@ -1968,7 +2418,16 @@ The buffer to fill with random data. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) ## wasi_ephemeral_sched ### Imports @@ -1976,13 +2435,22 @@ The buffer to fill with random data. --- -#### `yield() -> errno` +#### `yield() -> Result<(), errno>` Temporarily yield execution of the calling thread. Note: This is similar to [`yield`](#yield) in POSIX. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) ## wasi_ephemeral_sock ### Imports @@ -1991,7 +2459,7 @@ Note: This is similar to [`yield`](#yield) in POSIX. --- -#### `recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +#### `recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` Receive a message from a socket. Note: This is similar to [`recv`](#recv) in POSIX, though it also supports reading the data into multiple buffers in the manner of `readv`. @@ -2006,18 +2474,31 @@ List of scatter/gather vectors to which to store data. Message flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, roflags), errno>` +Number of bytes stored in ri_data and message flags. -- `ro_datalen`: [`size`](#size) -Number of bytes stored in ri_data. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, roflags)` -- `ro_flags`: [`roflags`](#roflags) -Message flags. +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`roflags`](#roflags) + +Offset: 4 + +- `err`: [`errno`](#errno) --- -#### `send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +#### `send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` Send a message on a socket. Note: This is similar to [`send`](#send) in POSIX, though it also supports writing the data from multiple buffers in the manner of `writev`. @@ -2032,15 +2513,22 @@ List of scatter/gather vectors to which to retrieve data Message flags. ##### Results -- `error`: [`errno`](#errno) - -- `so_datalen`: [`size`](#size) +- `error`: `Result` Number of bytes transmitted. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `shutdown(fd: fd, how: sdflags) -> errno` +#### `shutdown(fd: fd, how: sdflags) -> Result<(), errno>` Shut down socket send and receive channels. Note: This is similar to [`shutdown`](#shutdown) in POSIX. @@ -2051,5 +2539,14 @@ Note: This is similar to [`shutdown`](#shutdown) in POSIX. Which channels on the socket to shut down. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 503aa0cf6..1f9abc59b 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -195,7 +195,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags (@witx bitflags u64) + (flags (@witx repr u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke @@ -392,7 +392,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -429,7 +429,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -443,7 +443,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags (@witx bitflags u32) + (flags (@witx repr u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -451,7 +451,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Create file if it does not exist. $create ;;; Fail if not a directory. @@ -470,7 +470,7 @@ ;;; file in a filesystem, and don't fully reflect all the conditions ;;; which determine whether a given WASI program can access the file. (typename $permissions - (flags (@witx bitflags u8) + (flags (@witx repr u8) ;;; For files, permission to read the file. ;;; For directories, permission to do `readdir` and access files ;;; within the directory. @@ -543,7 +543,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -584,7 +584,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -643,7 +643,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -653,7 +653,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -665,7 +665,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags (@witx bitflags u8) + (flags (@witx repr u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx index 803605fee..b8d77b504 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -14,15 +14,13 @@ (@interface func (export "get") (param $argv (@witx pointer (@witx pointer (@witx char8)))) (param $argv_buf (@witx pointer (@witx char8))) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return command-line argument data sizes. (@interface func (export "sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; Returns the number of arguments and the size of the argument string + ;;; data, or an error. + (result $error (expected (tuple $size $size) (error $errno))) ) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx index 3b00e0ac4..a980529f8 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx @@ -18,9 +18,8 @@ (@interface func (export "res_get") ;;; The clock for which to return the resolution. (param $id $clockid) - (result $error $errno) ;;; The resolution of the clock. - (result $resolution $timestamp) + (result $error (expected $timestamp (error $errno))) ) ;;; Return the time value of a clock. @@ -30,8 +29,7 @@ (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp) - (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp) + (result $error (expected $timestamp (error $errno))) ) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx index 6357fe602..0cad3c1cc 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -14,15 +14,13 @@ (@interface func (export "get") (param $environ (@witx pointer (@witx pointer (@witx char8)))) (param $environ_buf (@witx pointer (@witx char8))) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return environment variable data sizes. (@interface func (export "sizes_get") - (result $error $errno) - ;;; The number of environment variable arguments. - (result $environc $size) - ;;; The size of the environment variable data. - (result $environ_buf_size $size) + ;;; Returns the number of environment variable arguments and the size of the + ;;; environment variable data. + (result $error (expected (tuple $size $size) (error $errno))) ) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx index 8192c9b7f..979e9a333 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx @@ -21,7 +21,7 @@ (param $len $filesize) ;;; The advice. (param $advice $advice) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Force the allocation of space in a file. @@ -32,30 +32,29 @@ (param $offset $filesize) ;;; The length of the area that is allocated. (param $len $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "close") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "datasync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fdstat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat) + (result $error (expected $fdstat (error $errno))) ) ;;; Adjust the flags associated with a file descriptor. @@ -64,7 +63,7 @@ (param $fd $fd) ;;; The desired values of the file descriptor flags. (param $flags $fdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the rights associated with a file descriptor. @@ -74,15 +73,14 @@ ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of an open file. (@interface func (export "filestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. @@ -91,7 +89,7 @@ (param $fd $fd) ;;; The desired file size. (param $size $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the timestamps of an open file or directory. @@ -104,7 +102,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Set the permissions of a file or directory. @@ -123,7 +121,7 @@ (param $fd $fd) ;;; The permissions associated with the file. (param $permissions $permissions) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. @@ -134,17 +132,15 @@ (param $iovs $iovec_array) ;;; The offset within the file at which to read. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "prestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat) + (result $error (expected $prestat (error $errno))) ) ;;; Return a description of the given preopened file descriptor. @@ -153,7 +149,7 @@ ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer (@witx char8))) (param $path_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. @@ -168,9 +164,8 @@ (param $iovs $ciovec_array) ;;; The offset within the file at which to write. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Read from a file descriptor. @@ -179,9 +174,8 @@ (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_array) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Read directory entries from a directory. @@ -201,9 +195,8 @@ (param $buf_len $size) ;;; The location within the directory to start reading (param $cookie $dircookie) - (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -220,7 +213,7 @@ (param $fd $fd) ;;; The file descriptor to overwrite. (param $to $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Move the offset of a file descriptor. @@ -231,25 +224,23 @@ (param $offset $filedelta) ;;; The base from which the offset is relative. (param $whence $whence) - (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "sync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "tell") (param $fd $fd) - (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Write to a file descriptor. @@ -262,8 +253,7 @@ (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_array) - (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx index 5b3e17e88..2901decb7 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx @@ -17,7 +17,7 @@ (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of a file or directory. @@ -28,9 +28,8 @@ (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the timestamps of a file or directory. @@ -47,7 +46,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Set the permissions of a file or directory. @@ -70,7 +69,7 @@ (param $path string) ;;; The permissions to associate with the file. (param $permissions $permissions) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a hard link. @@ -85,7 +84,7 @@ (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Open a file or directory. @@ -119,9 +118,8 @@ (param $fdflags $fdflags) ;;; If a file is created, the filesystem permissions to associate with it. (param $permissions $permissions) - (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd) + (result $error (expected $fd (error $errno))) ) ;;; Read the contents of a symbolic link. @@ -133,9 +131,8 @@ ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer (@witx char8))) (param $buf_len $size) - (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Remove a directory. @@ -145,7 +142,7 @@ (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Rename a file or directory. @@ -158,7 +155,7 @@ (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a symbolic link. @@ -169,7 +166,7 @@ (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Unlink a file. @@ -179,6 +176,6 @@ (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx index a30b96afc..08da5f03a 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx @@ -21,8 +21,7 @@ (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. (param $nsubscriptions $size) - (result $error $errno) ;;; The number of events stored. - (result $nevents $size) + (result $error (expected $size (error $errno))) ) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx index 55c6df021..4dc8e1a47 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx @@ -21,6 +21,6 @@ ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sched.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sched.witx index 799a75fa9..3b70856dc 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sched.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sched.witx @@ -11,6 +11,6 @@ ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `yield` in POSIX. (@interface func (export "yield") - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sock.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sock.witx index becf80ffc..a05b02ea6 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sock.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sock.witx @@ -20,11 +20,8 @@ (param $ri_data $iovec_array) ;;; Message flags. (param $ri_flags $riflags) - (result $error $errno) - ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size) - ;;; Message flags. - (result $ro_flags $roflags) + ;;; Number of bytes stored in ri_data and message flags. + (result $error (expected (tuple $size $roflags) (error $errno))) ) ;;; Send a message on a socket. @@ -36,9 +33,8 @@ (param $si_data $ciovec_array) ;;; Message flags. (param $si_flags $siflags) - (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size) + (result $error (expected $size (error $errno))) ) ;;; Shut down socket send and receive channels. @@ -47,6 +43,6 @@ (param $fd $fd) ;;; Which channels on the socket to shut down. (param $how $sdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index e77002bc6..707c836b2 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -19,7 +19,7 @@ Size: 8 Alignment: 8 -## `clockid`: Variant +## `clockid`: `Variant` Identifiers for clocks. Size: 4 @@ -43,7 +43,7 @@ The CPU-time clock associated with the current process. - `thread_cputime_id` The CPU-time clock associated with the current thread. -## `errno`: Variant +## `errno`: `Variant` Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -285,114 +285,172 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: `u64` +## `rights`: `Record` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Constants -- `fd_datasync` +### Record members +- `fd_datasync`: `bool` The right to invoke [`fd_datasync`](#fd_datasync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). -- `fd_read` +Bit: 0 + +- `fd_read`: `bool` The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). -- `fd_seek` +Bit: 1 + +- `fd_seek`: `bool` The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). -- `fd_fdstat_set_flags` +Bit: 2 + +- `fd_fdstat_set_flags`: `bool` The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). -- `fd_sync` +Bit: 3 + +- `fd_sync`: `bool` The right to invoke [`fd_sync`](#fd_sync). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). -- `fd_tell` +Bit: 4 + +- `fd_tell`: `bool` The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke [`fd_tell`](#fd_tell). -- `fd_write` +Bit: 5 + +- `fd_write`: `bool` The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). -- `fd_advise` +Bit: 6 + +- `fd_advise`: `bool` The right to invoke [`fd_advise`](#fd_advise). -- `fd_allocate` +Bit: 7 + +- `fd_allocate`: `bool` The right to invoke [`fd_allocate`](#fd_allocate). -- `path_create_directory` +Bit: 8 + +- `path_create_directory`: `bool` The right to invoke [`path_create_directory`](#path_create_directory). -- `path_create_file` +Bit: 9 + +- `path_create_file`: `bool` If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). -- `path_link_source` +Bit: 10 + +- `path_link_source`: `bool` The right to invoke [`path_link`](#path_link) with the file descriptor as the source directory. -- `path_link_target` +Bit: 11 + +- `path_link_target`: `bool` The right to invoke [`path_link`](#path_link) with the file descriptor as the target directory. -- `path_open` +Bit: 12 + +- `path_open`: `bool` The right to invoke [`path_open`](#path_open). -- `fd_readdir` +Bit: 13 + +- `fd_readdir`: `bool` The right to invoke [`fd_readdir`](#fd_readdir). -- `path_readlink` +Bit: 14 + +- `path_readlink`: `bool` The right to invoke [`path_readlink`](#path_readlink). -- `path_rename_source` +Bit: 15 + +- `path_rename_source`: `bool` The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. -- `path_rename_target` +Bit: 16 + +- `path_rename_target`: `bool` The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. -- `path_filestat_get` +Bit: 17 + +- `path_filestat_get`: `bool` The right to invoke [`path_filestat_get`](#path_filestat_get). -- `path_filestat_set_size` +Bit: 18 + +- `path_filestat_set_size`: `bool` The right to change a file's size (there is no `path_filestat_set_size`). If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). -- `path_filestat_set_times` +Bit: 19 + +- `path_filestat_set_times`: `bool` The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). -- `fd_filestat_get` +Bit: 20 + +- `fd_filestat_get`: `bool` The right to invoke [`fd_filestat_get`](#fd_filestat_get). -- `fd_filestat_set_size` +Bit: 21 + +- `fd_filestat_set_size`: `bool` The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). -- `fd_filestat_set_times` +Bit: 22 + +- `fd_filestat_set_times`: `bool` The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). -- `path_symlink` +Bit: 23 + +- `path_symlink`: `bool` The right to invoke [`path_symlink`](#path_symlink). -- `path_remove_directory` +Bit: 24 + +- `path_remove_directory`: `bool` The right to invoke [`path_remove_directory`](#path_remove_directory). -- `path_unlink_file` +Bit: 25 + +- `path_unlink_file`: `bool` The right to invoke [`path_unlink_file`](#path_unlink_file). -- `poll_fd_readwrite` +Bit: 26 + +- `poll_fd_readwrite`: `bool` If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). -- `sock_shutdown` +Bit: 27 + +- `sock_shutdown`: `bool` The right to invoke [`sock_shutdown`](#sock_shutdown). -## `fd` +Bit: 28 + +## `fd`: `Handle` A file descriptor handle. Size: 4 @@ -400,7 +458,7 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Record +## `iovec`: `Record` A region of memory for scatter/gather reads. Size: 8 @@ -418,7 +476,7 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Record +## `ciovec`: `Record` A region of memory for scatter/gather writes. Size: 8 @@ -455,7 +513,7 @@ Size: 8 Alignment: 8 -## `whence`: Variant +## `whence`: `Variant` The position relative to which to set the offset of the file descriptor. Size: 1 @@ -493,7 +551,7 @@ Size: 8 Alignment: 8 -## `filetype`: Variant +## `filetype`: `Variant` The type of a file descriptor or file. Size: 1 @@ -525,7 +583,7 @@ The file descriptor or file refers to a byte-stream socket. - `symbolic_link` The file refers to a symbolic link inode. -## `dirent`: Record +## `dirent`: `Record` A directory entry. Size: 24 @@ -553,7 +611,7 @@ The type of the file referred to by this directory entry. Offset: 20 -## `advice`: Variant +## `advice`: `Variant` File or memory access pattern advisory information. Size: 1 @@ -579,32 +637,42 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: `u16` +## `fdflags`: `Record` File descriptor flags. Size: 2 Alignment: 2 -### Constants -- `append` +### Record members +- `append`: `bool` Append mode: Data written to the file is always appended to the file's end. -- `dsync` +Bit: 0 + +- `dsync`: `bool` Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. -- `nonblock` +Bit: 1 + +- `nonblock`: `bool` Non-blocking mode. -- `rsync` +Bit: 2 + +- `rsync`: `bool` Synchronized read I/O operations. -- `sync` +Bit: 3 + +- `sync`: `bool` Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Record +Bit: 4 + +## `fdstat`: `Record` File descriptor attributes. Size: 24 @@ -641,57 +709,75 @@ Size: 8 Alignment: 8 -## `fstflags`: `u16` +## `fstflags`: `Record` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Constants -- `atim` +### Record members +- `atim`: `bool` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). -- `atim_now` +Bit: 0 + +- `atim_now`: `bool` Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -- `mtim` +Bit: 1 + +- `mtim`: `bool` Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). -- `mtim_now` +Bit: 2 + +- `mtim_now`: `bool` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: `u32` +Bit: 3 + +## `lookupflags`: `Record` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Constants -- `symlink_follow` +### Record members +- `symlink_follow`: `bool` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: `u16` +Bit: 0 + +## `oflags`: `Record` Open flags used by [`path_open`](#path_open). Size: 2 Alignment: 2 -### Constants -- `creat` +### Record members +- `creat`: `bool` Create file if it does not exist. -- `directory` +Bit: 0 + +- `directory`: `bool` Fail if not a directory. -- `excl` +Bit: 1 + +- `excl`: `bool` Fail if file already exists. -- `trunc` +Bit: 2 + +- `trunc`: `bool` Truncate file to size 0. +Bit: 3 + ## `linkcount`: `u32` Number of hard links to an inode. @@ -699,7 +785,7 @@ Size: 4 Alignment: 4 -## `filestat`: Record +## `filestat`: `Record` File attributes. Size: 56 @@ -755,7 +841,7 @@ Size: 8 Alignment: 8 -## `eventtype`: Variant +## `eventtype`: `Variant` Type of a subscription to an event or its occurrence. Size: 1 @@ -775,7 +861,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: `u16` +## `eventrwflags`: `Record` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -783,11 +869,13 @@ Size: 2 Alignment: 2 -### Constants -- `fd_readwrite_hangup` +### Record members +- `fd_readwrite_hangup`: `bool` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Record +Bit: 0 + +## `event_fd_readwrite`: `Record` The contents of an [`event`](#event) for the [`eventtype::fd_read`](#eventtype.fd_read) and [`eventtype::fd_write`](#eventtype.fd_write) variants @@ -806,7 +894,7 @@ The state of the file descriptor. Offset: 8 -## `event`: Record +## `event`: `Record` An event that occurred. Size: 32 @@ -835,7 +923,7 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read Offset: 16 -## `subclockflags`: `u16` +## `subclockflags`: `Record` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -843,15 +931,17 @@ Size: 2 Alignment: 2 -### Constants -- `subscription_clock_abstime` +### Record members +- `subscription_clock_abstime`: `bool` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock [`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Record +Bit: 0 + +## `subscription_clock`: `Record` The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 40 @@ -885,7 +975,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 32 -## `subscription_fd_readwrite`: Record +## `subscription_fd_readwrite`: `Record` The contents of a [`subscription`](#subscription) when the variant is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -899,7 +989,7 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Variant +## `subscription_u`: `Variant` The contents of a [`subscription`](#subscription). Size: 48 @@ -917,7 +1007,7 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Record +## `subscription`: `Record` Subscription to an event. Size: 56 @@ -943,7 +1033,7 @@ Size: 4 Alignment: 4 -## `signal`: Variant +## `signal`: `Variant` Signal condition. Size: 1 @@ -1075,31 +1165,37 @@ Action: Terminates the process. Bad system call. Action: Terminates the process. -## `riflags`: `u16` +## `riflags`: `Record` Flags provided to [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Constants -- `recv_peek` +### Record members +- `recv_peek`: `bool` Returns the message without removing it from the socket's receive queue. -- `recv_waitall` +Bit: 0 + +- `recv_waitall`: `bool` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: `u16` +Bit: 1 + +## `roflags`: `Record` Flags returned by [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Constants -- `recv_data_truncated` +### Record members +- `recv_data_truncated`: `bool` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. +Bit: 0 + ## `siflags`: `u16` Flags provided to [`sock_send`](#sock_send). As there are currently no flags defined, it must be set to zero. @@ -1108,21 +1204,25 @@ Size: 2 Alignment: 2 -## `sdflags`: `u8` +## `sdflags`: `Record` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Constants -- `rd` +### Record members +- `rd`: `bool` Disables further receive operations. -- `wr` +Bit: 0 + +- `wr`: `bool` Disables further send operations. -## `preopentype`: Variant +Bit: 1 + +## `preopentype`: `Variant` Identifiers for preopened capabilities. Size: 1 @@ -1133,7 +1233,7 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Record +## `prestat_dir`: `Record` The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). Size: 4 @@ -1146,7 +1246,7 @@ The length of the directory name for use with [`fd_prestat_dir_name`](#fd_presta Offset: 0 -## `prestat`: Variant +## `prestat`: `Variant` Information about a pre-opened capability. Size: 8 @@ -1168,7 +1268,7 @@ Alignment: 4 --- -#### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` +#### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) @@ -1178,28 +1278,51 @@ The size of the array should match that returned by [`args_sizes_get`](#args_siz - `argv_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `args_sizes_get() -> (errno, size, size)` +#### `args_sizes_get() -> Result<(size, size), errno>` Return command-line argument data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of arguments and the size of the argument string +data, or an error. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) -- `argc`: [`size`](#size) -The number of arguments. +Offset: 0 + +- `1`: [`size`](#size) + +Offset: 4 -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `err`: [`errno`](#errno) --- -#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` +#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). @@ -1209,28 +1332,51 @@ The sizes of the buffers should match that returned by [`environ_sizes_get`](#en - `environ_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `environ_sizes_get() -> (errno, size, size)` +#### `environ_sizes_get() -> Result<(size, size), errno>` Return environment variable data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of environment variable arguments and the size of the +environment variable data. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`size`](#size) -- `environc`: [`size`](#size) -The number of environment variable arguments. +Offset: 4 -- `environ_buf_size`: [`size`](#size) -The size of the environment variable data. +- `err`: [`errno`](#errno) --- -#### `clock_res_get(id: clockid) -> (errno, timestamp)` +#### `clock_res_get(id: clockid) -> Result` Return the resolution of a clock. Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return [`errno::inval`](#errno.inval). @@ -1241,15 +1387,22 @@ Note: This is similar to `clock_getres` in POSIX. The clock for which to return the resolution. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result` +The resolution of the clock, or an error if one happened. + +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) -- `resolution`: [`timestamp`](#timestamp) -The resolution of the clock. +- `err`: [`errno`](#errno) --- -#### `clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +#### `clock_time_get(id: clockid, precision: timestamp) -> Result` Return the time value of a clock. Note: This is similar to `clock_gettime` in POSIX. @@ -1261,15 +1414,22 @@ The clock for which to return the time. The maximum lag (exclusive) that the returned time value may have, compared to its actual value. ##### Results -- `error`: [`errno`](#errno) - -- `time`: [`timestamp`](#timestamp) +- `error`: `Result` The time value of the clock. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) + +- `err`: [`errno`](#errno) + --- -#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` Provide file advisory information on a file descriptor. Note: This is similar to `posix_fadvise` in POSIX. @@ -1286,12 +1446,21 @@ The length of the region to which the advisory applies. The advice. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno` +#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` Force the allocation of space in a file. Note: This is similar to `posix_fallocate` in POSIX. @@ -1305,12 +1474,21 @@ The offset at which to start the allocation. The length of the area that is allocated. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_close(fd: fd) -> errno` +#### `fd_close(fd: fd) -> Result<(), errno>` Close a file descriptor. Note: This is similar to `close` in POSIX. @@ -1318,12 +1496,21 @@ Note: This is similar to `close` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_datasync(fd: fd) -> errno` +#### `fd_datasync(fd: fd) -> Result<(), errno>` Synchronize the data of a file to disk. Note: This is similar to `fdatasync` in POSIX. @@ -1331,12 +1518,21 @@ Note: This is similar to `fdatasync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_fdstat_get(fd: fd) -> (errno, fdstat)` +#### `fd_fdstat_get(fd: fd) -> Result` Get the attributes of a file descriptor. Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. @@ -1344,15 +1540,22 @@ Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as ad - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `stat`: [`fdstat`](#fdstat) +- `error`: `Result` The buffer where the file descriptor's attributes are stored. +###### Variant Layout +- size: 32 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`fdstat`](#fdstat) + +- `err`: [`errno`](#errno) + --- -#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` Adjust the flags associated with a file descriptor. Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. @@ -1363,12 +1566,21 @@ Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. The desired values of the file descriptor flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` Adjust the rights associated with a file descriptor. This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights @@ -1381,27 +1593,43 @@ The desired rights of the file descriptor. - `fs_rights_inheriting`: [`rights`](#rights) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_filestat_get(fd: fd) -> (errno, filestat)` +#### `fd_filestat_get(fd: fd) -> Result` Return the attributes of an open file. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 64 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `fd_filestat_set_size(fd: fd, size: filesize) -> errno` +#### `fd_filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. Note: This is similar to `ftruncate` in POSIX. @@ -1412,12 +1640,21 @@ Note: This is similar to `ftruncate` in POSIX. The desired file size. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of an open file or directory. Note: This is similar to `futimens` in POSIX. @@ -1434,12 +1671,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` Read from a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `preadv` in POSIX. @@ -1453,30 +1699,44 @@ List of scatter/gather vectors in which to store data. The offset within the file at which to read. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_prestat_get(fd: fd) -> (errno, prestat)` +#### `fd_prestat_get(fd: fd) -> Result` Return a description of the given preopened file descriptor. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`prestat`](#prestat) +- `error`: `Result` The buffer where the description is stored. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`prestat`](#prestat) + +- `err`: [`errno`](#errno) + --- -#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` Return a description of the given preopened file descriptor. ##### Params @@ -1488,12 +1748,21 @@ A buffer into which to write the preopened directory name. - `path_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` Write to a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `pwritev` in POSIX. @@ -1507,15 +1776,22 @@ List of scatter/gather vectors from which to retrieve data. The offset within the file at which to write. ##### Results -- `error`: [`errno`](#errno) - -- `nwritten`: [`size`](#size) +- `error`: `Result` The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_read(fd: fd, iovs: iovec_array) -> (errno, size)` +#### `fd_read(fd: fd, iovs: iovec_array) -> Result` Read from a file descriptor. Note: This is similar to `readv` in POSIX. @@ -1526,15 +1802,22 @@ Note: This is similar to `readv` in POSIX. List of scatter/gather vectors to which to store data. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of directory entries. Each directory entry consists of a [`dirent`](#dirent) object, @@ -1557,15 +1840,22 @@ The buffer where directory entries are stored The location within the directory to start reading ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_renumber(fd: fd, to: fd) -> errno` +#### `fd_renumber(fd: fd, to: fd) -> Result<(), errno>` Atomically replace a file descriptor by renumbering another file descriptor. Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary @@ -1582,12 +1872,21 @@ would disappear if `dup2()` were to be removed entirely. The file descriptor to overwrite. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> Result` Move the offset of a file descriptor. Note: This is similar to `lseek` in POSIX. @@ -1601,15 +1900,22 @@ The number of bytes to move. The base from which the offset is relative. ##### Results -- `error`: [`errno`](#errno) - -- `newoffset`: [`filesize`](#filesize) +- `error`: `Result` The new offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `fd_sync(fd: fd) -> errno` +#### `fd_sync(fd: fd) -> Result<(), errno>` Synchronize the data and metadata of a file to disk. Note: This is similar to `fsync` in POSIX. @@ -1617,12 +1923,21 @@ Note: This is similar to `fsync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_tell(fd: fd) -> (errno, filesize)` +#### `fd_tell(fd: fd) -> Result` Return the current offset of a file descriptor. Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. @@ -1630,15 +1945,22 @@ Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `offset`: [`filesize`](#filesize) +- `error`: `Result` The current offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)` +#### `fd_write(fd: fd, iovs: ciovec_array) -> Result` Write to a file descriptor. Note: This is similar to `writev` in POSIX. @@ -1649,15 +1971,21 @@ Note: This is similar to `writev` in POSIX. List of scatter/gather vectors from which to retrieve data. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result` -- `nwritten`: [`size`](#size) -The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) --- -#### `path_create_directory(fd: fd, path: string) -> errno` +#### `path_create_directory(fd: fd, path: string) -> Result<(), errno>` Create a directory. Note: This is similar to `mkdirat` in POSIX. @@ -1668,12 +1996,21 @@ Note: This is similar to `mkdirat` in POSIX. The path at which to create the directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` Return the attributes of a file or directory. Note: This is similar to `stat` in POSIX. @@ -1687,15 +2024,22 @@ Flags determining the method of how the path is resolved. The path of the file or directory to inspect. ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 64 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of a file or directory. Note: This is similar to `utimensat` in POSIX. @@ -1718,12 +2062,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Create a hard link. Note: This is similar to `linkat` in POSIX. @@ -1743,12 +2096,21 @@ The working directory at which the resolution of the new path starts. The destination path at which to create the hard link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> (errno, fd)` +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> Result` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1765,7 +2127,7 @@ Flags determining the method of how the path is resolved. - `path`: `string` The relative path of the file or directory to open, relative to the -[`fd`](#fd) directory. +[`path_open::fd`](#path_open.fd) directory. - `oflags`: [`oflags`](#oflags) The method by which to open the file. @@ -1784,15 +2146,22 @@ file descriptors derived from it. - `fdflags`: [`fdflags`](#fdflags) ##### Results -- `error`: [`errno`](#errno) - -- `opened_fd`: [`fd`](#fd) +- `error`: `Result` The file descriptor of the file that has been opened. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`fd`](#fd) + +- `err`: [`errno`](#errno) + --- -#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` Read the contents of a symbolic link. Note: This is similar to `readlinkat` in POSIX. @@ -1808,15 +2177,22 @@ The buffer to which to write the contents of the symbolic link. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes placed in the buffer. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `path_remove_directory(fd: fd, path: string) -> errno` +#### `path_remove_directory(fd: fd, path: string) -> Result<(), errno>` Remove a directory. Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. @@ -1828,12 +2204,21 @@ Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. The path to a directory to remove. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Rename a file or directory. Note: This is similar to `renameat` in POSIX. @@ -1850,12 +2235,21 @@ The working directory at which the resolution of the new path starts. The destination path to which to rename the file or directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_symlink(old_path: string, fd: fd, new_path: string) -> errno` +#### `path_symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` Create a symbolic link. Note: This is similar to `symlinkat` in POSIX. @@ -1869,12 +2263,21 @@ The contents of the symbolic link. The destination path at which to create the symbolic link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_unlink_file(fd: fd, path: string) -> errno` +#### `path_unlink_file(fd: fd, path: string) -> Result<(), errno>` Unlink a file. Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. @@ -1886,12 +2289,21 @@ Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. The path to a file to unlink. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` Concurrently poll for the occurrence of a set of events. ##### Params @@ -1905,11 +2317,18 @@ The events that have occurred. Both the number of subscriptions and events. ##### Results -- `error`: [`errno`](#errno) - -- `nevents`: [`size`](#size) +- `error`: `Result` The number of events stored. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- @@ -1926,7 +2345,7 @@ The exit code returned by the process. --- -#### `proc_raise(sig: signal) -> errno` +#### `proc_raise(sig: signal) -> Result<(), errno>` Send a signal to the process of the calling thread. Note: This is similar to `raise` in POSIX. @@ -1935,23 +2354,41 @@ Note: This is similar to `raise` in POSIX. The signal condition to trigger. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sched_yield() -> errno` +#### `sched_yield() -> Result<(), errno>` Temporarily yield execution of the calling thread. Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `random_get(buf: Pointer, buf_len: size) -> errno` +#### `random_get(buf: Pointer, buf_len: size) -> Result<(), errno>` Write high-quality random data into a buffer. This function blocks when the implementation is unable to immediately provide sufficient high-quality random data. @@ -1966,12 +2403,21 @@ The buffer to fill with random data. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` Receive a message from a socket. Note: This is similar to `recv` in POSIX, though it also supports reading the data into multiple buffers in the manner of `readv`. @@ -1986,18 +2432,31 @@ List of scatter/gather vectors to which to store data. Message flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, roflags), errno>` +Number of bytes stored in ri_data and message flags. -- `ro_datalen`: [`size`](#size) -Number of bytes stored in ri_data. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, roflags)` -- `ro_flags`: [`roflags`](#roflags) -Message flags. +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`roflags`](#roflags) + +Offset: 4 + +- `err`: [`errno`](#errno) --- -#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` Send a message on a socket. Note: This is similar to `send` in POSIX, though it also supports writing the data from multiple buffers in the manner of `writev`. @@ -2012,15 +2471,22 @@ List of scatter/gather vectors to which to retrieve data Message flags. ##### Results -- `error`: [`errno`](#errno) - -- `so_datalen`: [`size`](#size) +- `error`: `Result` Number of bytes transmitted. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `sock_shutdown(fd: fd, how: sdflags) -> errno` +#### `sock_shutdown(fd: fd, how: sdflags) -> Result<(), errno>` Shut down socket send and receive channels. Note: This is similar to `shutdown` in POSIX. @@ -2031,5 +2497,14 @@ Note: This is similar to `shutdown` in POSIX. Which channels on the socket to shut down. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx index eb6f70020..f4ba78802 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags (@witx bitflags u64) + (flags (@witx repr u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `rights::path_open` is set, includes the right to invoke @@ -379,7 +379,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -416,7 +416,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -430,7 +430,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags (@witx bitflags u32) + (flags (@witx repr u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -438,7 +438,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Create file if it does not exist. $creat ;;; Fail if not a directory. @@ -497,7 +497,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -532,7 +532,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -692,7 +692,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -702,7 +702,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -714,7 +714,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags (@witx bitflags u8) + (flags (@witx repr u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx index 0d16f1b18..5481882ae 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -20,15 +20,13 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; Returns the number of arguments and the size of the argument string + ;;; data, or an error. + (result $error (expected (tuple $size $size) (error $errno))) ) ;;; Read environment variable data. @@ -36,15 +34,13 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return environment variable data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno) - ;;; The number of environment variable arguments. - (result $environc $size) - ;;; The size of the environment variable data. - (result $environ_buf_size $size) + ;;; Returns the number of environment variable arguments and the size of the + ;;; environment variable data. + (result $error (expected (tuple $size $size) (error $errno))) ) ;;; Return the resolution of a clock. @@ -54,9 +50,8 @@ (@interface func (export "clock_res_get") ;;; The clock for which to return the resolution. (param $id $clockid) - (result $error $errno) - ;;; The resolution of the clock. - (result $resolution $timestamp) + ;;; The resolution of the clock, or an error if one happened. + (result $error (expected $timestamp (error $errno))) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. @@ -65,9 +60,8 @@ (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp) - (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp) + (result $error (expected $timestamp (error $errno))) ) ;;; Provide file advisory information on a file descriptor. @@ -80,7 +74,7 @@ (param $len $filesize) ;;; The advice. (param $advice $advice) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Force the allocation of space in a file. @@ -91,30 +85,29 @@ (param $offset $filesize) ;;; The length of the area that is allocated. (param $len $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat) + (result $error (expected $fdstat (error $errno))) ) ;;; Adjust the flags associated with a file descriptor. @@ -123,7 +116,7 @@ (param $fd $fd) ;;; The desired values of the file descriptor flags. (param $flags $fdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the rights associated with a file descriptor. @@ -133,15 +126,14 @@ ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. @@ -150,7 +142,7 @@ (param $fd $fd) ;;; The desired file size. (param $size $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the timestamps of an open file or directory. @@ -163,7 +155,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. @@ -174,17 +166,15 @@ (param $iovs $iovec_array) ;;; The offset within the file at which to read. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat) + (result $error (expected $prestat (error $errno))) ) ;;; Return a description of the given preopened file descriptor. @@ -193,7 +183,7 @@ ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. @@ -204,9 +194,8 @@ (param $iovs $ciovec_array) ;;; The offset within the file at which to write. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Read from a file descriptor. @@ -215,9 +204,8 @@ (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_array) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Read directory entries from a directory. @@ -237,9 +225,8 @@ (param $buf_len $size) ;;; The location within the directory to start reading (param $cookie $dircookie) - (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -256,7 +243,7 @@ (param $fd $fd) ;;; The file descriptor to overwrite. (param $to $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Move the offset of a file descriptor. @@ -267,25 +254,23 @@ (param $offset $filedelta) ;;; The base from which the offset is relative. (param $whence $whence) - (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd) - (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Write to a file descriptor. @@ -294,9 +279,7 @@ (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_array) - (result $error $errno) - ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Create a directory. @@ -305,7 +288,7 @@ (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of a file or directory. @@ -316,9 +299,8 @@ (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the timestamps of a file or directory. @@ -335,7 +317,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a hard link. @@ -350,7 +332,7 @@ (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Open a file or directory. @@ -367,7 +349,7 @@ ;;; Flags determining the method of how the path is resolved. (param $dirflags $lookupflags) ;;; The relative path of the file or directory to open, relative to the - ;;; `fd` directory. + ;;; `path_open::fd` directory. (param $path string) ;;; The method by which to open the file. (param $oflags $oflags) @@ -382,9 +364,8 @@ (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) - (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd) + (result $error (expected $fd (error $errno))) ) ;;; Read the contents of a symbolic link. @@ -396,9 +377,8 @@ ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Remove a directory. @@ -408,7 +388,7 @@ (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Rename a file or directory. @@ -421,7 +401,7 @@ (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a symbolic link. @@ -432,7 +412,7 @@ (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) @@ -443,7 +423,7 @@ (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Concurrently poll for the occurrence of a set of events. @@ -454,9 +434,8 @@ (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. (param $nsubscriptions $size) - (result $error $errno) ;;; The number of events stored. - (result $nevents $size) + (result $error (expected $size (error $errno))) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -473,13 +452,13 @@ (@interface func (export "proc_raise") ;;; The signal condition to trigger. (param $sig $signal) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write high-quality random data into a buffer. @@ -492,7 +471,7 @@ ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Receive a message from a socket. @@ -504,11 +483,8 @@ (param $ri_data $iovec_array) ;;; Message flags. (param $ri_flags $riflags) - (result $error $errno) - ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size) - ;;; Message flags. - (result $ro_flags $roflags) + ;;; Number of bytes stored in ri_data and message flags. + (result $error (expected (tuple $size $roflags) (error $errno))) ) ;;; Send a message on a socket. @@ -520,9 +496,8 @@ (param $si_data $ciovec_array) ;;; Message flags. (param $si_flags $siflags) - (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size) + (result $error (expected $size (error $errno))) ) ;;; Shut down socket send and receive channels. @@ -531,6 +506,6 @@ (param $fd $fd) ;;; Which channels on the socket to shut down. (param $how $sdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index 1bbbe59f2..c55a661b1 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -19,7 +19,7 @@ Size: 8 Alignment: 8 -## `clockid`: Variant +## `clockid`: `Variant` Identifiers for clocks. Size: 4 @@ -43,7 +43,7 @@ The CPU-time clock associated with the current process. - `thread_cputime_id` The CPU-time clock associated with the current thread. -## `errno`: Variant +## `errno`: `Variant` Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -285,114 +285,172 @@ Cross-device link. - `notcapable` Extension: Capabilities insufficient. -## `rights`: `u64` +## `rights`: `Record` File descriptor rights, determining which actions may be performed. Size: 8 Alignment: 8 -### Constants -- `fd_datasync` +### Record members +- `fd_datasync`: `bool` The right to invoke [`fd_datasync`](#fd_datasync). If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). -- `fd_read` +Bit: 0 + +- `fd_read`: `bool` The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). -- `fd_seek` +Bit: 1 + +- `fd_seek`: `bool` The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). -- `fd_fdstat_set_flags` +Bit: 2 + +- `fd_fdstat_set_flags`: `bool` The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). -- `fd_sync` +Bit: 3 + +- `fd_sync`: `bool` The right to invoke [`fd_sync`](#fd_sync). If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). -- `fd_tell` +Bit: 4 + +- `fd_tell`: `bool` The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to invoke [`fd_tell`](#fd_tell). -- `fd_write` +Bit: 5 + +- `fd_write`: `bool` The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). -- `fd_advise` +Bit: 6 + +- `fd_advise`: `bool` The right to invoke [`fd_advise`](#fd_advise). -- `fd_allocate` +Bit: 7 + +- `fd_allocate`: `bool` The right to invoke [`fd_allocate`](#fd_allocate). -- `path_create_directory` +Bit: 8 + +- `path_create_directory`: `bool` The right to invoke [`path_create_directory`](#path_create_directory). -- `path_create_file` +Bit: 9 + +- `path_create_file`: `bool` If [`path_open`](#path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). -- `path_link_source` +Bit: 10 + +- `path_link_source`: `bool` The right to invoke [`path_link`](#path_link) with the file descriptor as the source directory. -- `path_link_target` +Bit: 11 + +- `path_link_target`: `bool` The right to invoke [`path_link`](#path_link) with the file descriptor as the target directory. -- `path_open` +Bit: 12 + +- `path_open`: `bool` The right to invoke [`path_open`](#path_open). -- `fd_readdir` +Bit: 13 + +- `fd_readdir`: `bool` The right to invoke [`fd_readdir`](#fd_readdir). -- `path_readlink` +Bit: 14 + +- `path_readlink`: `bool` The right to invoke [`path_readlink`](#path_readlink). -- `path_rename_source` +Bit: 15 + +- `path_rename_source`: `bool` The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. -- `path_rename_target` +Bit: 16 + +- `path_rename_target`: `bool` The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. -- `path_filestat_get` +Bit: 17 + +- `path_filestat_get`: `bool` The right to invoke [`path_filestat_get`](#path_filestat_get). -- `path_filestat_set_size` +Bit: 18 + +- `path_filestat_set_size`: `bool` The right to change a file's size (there is no `path_filestat_set_size`). If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). -- `path_filestat_set_times` +Bit: 19 + +- `path_filestat_set_times`: `bool` The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). -- `fd_filestat_get` +Bit: 20 + +- `fd_filestat_get`: `bool` The right to invoke [`fd_filestat_get`](#fd_filestat_get). -- `fd_filestat_set_size` +Bit: 21 + +- `fd_filestat_set_size`: `bool` The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). -- `fd_filestat_set_times` +Bit: 22 + +- `fd_filestat_set_times`: `bool` The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). -- `path_symlink` +Bit: 23 + +- `path_symlink`: `bool` The right to invoke [`path_symlink`](#path_symlink). -- `path_remove_directory` +Bit: 24 + +- `path_remove_directory`: `bool` The right to invoke [`path_remove_directory`](#path_remove_directory). -- `path_unlink_file` +Bit: 25 + +- `path_unlink_file`: `bool` The right to invoke [`path_unlink_file`](#path_unlink_file). -- `poll_fd_readwrite` +Bit: 26 + +- `poll_fd_readwrite`: `bool` If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). -- `sock_shutdown` +Bit: 27 + +- `sock_shutdown`: `bool` The right to invoke [`sock_shutdown`](#sock_shutdown). -## `fd` +Bit: 28 + +## `fd`: `Handle` A file descriptor handle. Size: 4 @@ -400,7 +458,7 @@ Size: 4 Alignment: 4 ### Supertypes -## `iovec`: Record +## `iovec`: `Record` A region of memory for scatter/gather reads. Size: 8 @@ -418,7 +476,7 @@ The length of the buffer to be filled. Offset: 4 -## `ciovec`: Record +## `ciovec`: `Record` A region of memory for scatter/gather writes. Size: 8 @@ -455,7 +513,7 @@ Size: 8 Alignment: 8 -## `whence`: Variant +## `whence`: `Variant` The position relative to which to set the offset of the file descriptor. Size: 1 @@ -495,7 +553,7 @@ Size: 8 Alignment: 8 -## `filetype`: Variant +## `filetype`: `Variant` The type of a file descriptor or file. Size: 1 @@ -527,7 +585,7 @@ The file descriptor or file refers to a byte-stream socket. - `symbolic_link` The file refers to a symbolic link inode. -## `dirent`: Record +## `dirent`: `Record` A directory entry. Size: 24 @@ -555,7 +613,7 @@ The type of the file referred to by this directory entry. Offset: 20 -## `advice`: Variant +## `advice`: `Variant` File or memory access pattern advisory information. Size: 1 @@ -581,32 +639,42 @@ The application expects that it will not access the specified data in the near f - `noreuse` The application expects to access the specified data once and then not reuse it thereafter. -## `fdflags`: `u16` +## `fdflags`: `Record` File descriptor flags. Size: 2 Alignment: 2 -### Constants -- `append` +### Record members +- `append`: `bool` Append mode: Data written to the file is always appended to the file's end. -- `dsync` +Bit: 0 + +- `dsync`: `bool` Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. -- `nonblock` +Bit: 1 + +- `nonblock`: `bool` Non-blocking mode. -- `rsync` +Bit: 2 + +- `rsync`: `bool` Synchronized read I/O operations. -- `sync` +Bit: 3 + +- `sync`: `bool` Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the implementation may also synchronously update the file's metadata. -## `fdstat`: Record +Bit: 4 + +## `fdstat`: `Record` File descriptor attributes. Size: 24 @@ -643,57 +711,75 @@ Size: 8 Alignment: 8 -## `fstflags`: `u16` +## `fstflags`: `Record` Which file time attributes to adjust. Size: 2 Alignment: 2 -### Constants -- `atim` +### Record members +- `atim`: `bool` Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). -- `atim_now` +Bit: 0 + +- `atim_now`: `bool` Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -- `mtim` +Bit: 1 + +- `mtim`: `bool` Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). -- `mtim_now` +Bit: 2 + +- `mtim_now`: `bool` Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). -## `lookupflags`: `u32` +Bit: 3 + +## `lookupflags`: `Record` Flags determining the method of how paths are resolved. Size: 4 Alignment: 4 -### Constants -- `symlink_follow` +### Record members +- `symlink_follow`: `bool` As long as the resolved path corresponds to a symbolic link, it is expanded. -## `oflags`: `u16` +Bit: 0 + +## `oflags`: `Record` Open flags used by [`path_open`](#path_open). Size: 2 Alignment: 2 -### Constants -- `creat` +### Record members +- `creat`: `bool` Create file if it does not exist. -- `directory` +Bit: 0 + +- `directory`: `bool` Fail if not a directory. -- `excl` +Bit: 1 + +- `excl`: `bool` Fail if file already exists. -- `trunc` +Bit: 2 + +- `trunc`: `bool` Truncate file to size 0. +Bit: 3 + ## `linkcount`: `u64` Number of hard links to an inode. @@ -701,7 +787,7 @@ Size: 8 Alignment: 8 -## `filestat`: Record +## `filestat`: `Record` File attributes. Size: 64 @@ -757,7 +843,7 @@ Size: 8 Alignment: 8 -## `eventtype`: Variant +## `eventtype`: `Variant` Type of a subscription to an event or its occurrence. Size: 1 @@ -777,7 +863,7 @@ available for reading. This event always triggers for regular files. File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity available for writing. This event always triggers for regular files. -## `eventrwflags`: `u16` +## `eventrwflags`: `Record` The state of the file descriptor subscribed to with [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -785,11 +871,13 @@ Size: 2 Alignment: 2 -### Constants -- `fd_readwrite_hangup` +### Record members +- `fd_readwrite_hangup`: `bool` The peer of this socket has closed or disconnected. -## `event_fd_readwrite`: Record +Bit: 0 + +## `event_fd_readwrite`: `Record` The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -808,7 +896,7 @@ The state of the file descriptor. Offset: 8 -## `event`: Record +## `event`: `Record` An event that occurred. Size: 32 @@ -837,7 +925,7 @@ The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read Offset: 16 -## `subclockflags`: `u16` +## `subclockflags`: `Record` Flags determining how to interpret the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout). @@ -845,15 +933,17 @@ Size: 2 Alignment: 2 -### Constants -- `subscription_clock_abstime` +### Record members +- `subscription_clock_abstime`: `bool` If set, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock [`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the current time value of clock [`subscription_clock::id`](#subscription_clock.id). -## `subscription_clock`: Record +Bit: 0 + +## `subscription_clock`: `Record` The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). Size: 32 @@ -882,7 +972,7 @@ Flags specifying whether the timeout is absolute or relative Offset: 24 -## `subscription_fd_readwrite`: Record +## `subscription_fd_readwrite`: `Record` The contents of a [`subscription`](#subscription) when type is type is [`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). @@ -896,7 +986,7 @@ The file descriptor on which to wait for it to become ready for reading or writi Offset: 0 -## `subscription_u`: Variant +## `subscription_u`: `Variant` The contents of a [`subscription`](#subscription). Size: 40 @@ -914,7 +1004,7 @@ Alignment: 8 - `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) -## `subscription`: Record +## `subscription`: `Record` Subscription to an event. Size: 48 @@ -940,7 +1030,7 @@ Size: 4 Alignment: 4 -## `signal`: Variant +## `signal`: `Variant` Signal condition. Size: 1 @@ -1072,31 +1162,37 @@ Action: Terminates the process. Bad system call. Action: Terminates the process. -## `riflags`: `u16` +## `riflags`: `Record` Flags provided to [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Constants -- `recv_peek` +### Record members +- `recv_peek`: `bool` Returns the message without removing it from the socket's receive queue. -- `recv_waitall` +Bit: 0 + +- `recv_waitall`: `bool` On byte-stream sockets, block until the full amount of data can be returned. -## `roflags`: `u16` +Bit: 1 + +## `roflags`: `Record` Flags returned by [`sock_recv`](#sock_recv). Size: 2 Alignment: 2 -### Constants -- `recv_data_truncated` +### Record members +- `recv_data_truncated`: `bool` Returned by [`sock_recv`](#sock_recv): Message data has been truncated. +Bit: 0 + ## `siflags`: `u16` Flags provided to [`sock_send`](#sock_send). As there are currently no flags defined, it must be set to zero. @@ -1105,21 +1201,25 @@ Size: 2 Alignment: 2 -## `sdflags`: `u8` +## `sdflags`: `Record` Which channels on a socket to shut down. Size: 1 Alignment: 1 -### Constants -- `rd` +### Record members +- `rd`: `bool` Disables further receive operations. -- `wr` +Bit: 0 + +- `wr`: `bool` Disables further send operations. -## `preopentype`: Variant +Bit: 1 + +## `preopentype`: `Variant` Identifiers for preopened capabilities. Size: 1 @@ -1130,7 +1230,7 @@ Alignment: 1 - `dir` A pre-opened directory. -## `prestat_dir`: Record +## `prestat_dir`: `Record` The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). Size: 4 @@ -1143,7 +1243,7 @@ The length of the directory name for use with [`fd_prestat_dir_name`](#fd_presta Offset: 0 -## `prestat`: Variant +## `prestat`: `Variant` Information about a pre-opened capability. Size: 8 @@ -1165,7 +1265,7 @@ Alignment: 4 --- -#### `args_get(argv: Pointer>, argv_buf: Pointer) -> errno` +#### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) @@ -1175,28 +1275,51 @@ The size of the array should match that returned by [`args_sizes_get`](#args_siz - `argv_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `args_sizes_get() -> (errno, size, size)` +#### `args_sizes_get() -> Result<(size, size), errno>` Return command-line argument data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of arguments and the size of the argument string +data, or an error. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) -- `argc`: [`size`](#size) -The number of arguments. +Offset: 0 + +- `1`: [`size`](#size) + +Offset: 4 -- `argv_buf_size`: [`size`](#size) -The size of the argument string data. +- `err`: [`errno`](#errno) --- -#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> errno` +#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). @@ -1206,28 +1329,51 @@ The sizes of the buffers should match that returned by [`environ_sizes_get`](#en - `environ_buf`: `Pointer` ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `environ_sizes_get() -> (errno, size, size)` +#### `environ_sizes_get() -> Result<(size, size), errno>` Return environment variable data sizes. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, size), errno>` +Returns the number of environment variable arguments and the size of the +environment variable data. + +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, size)` + +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`size`](#size) -- `environc`: [`size`](#size) -The number of environment variable arguments. +Offset: 4 -- `environ_buf_size`: [`size`](#size) -The size of the environment variable data. +- `err`: [`errno`](#errno) --- -#### `clock_res_get(id: clockid) -> (errno, timestamp)` +#### `clock_res_get(id: clockid) -> Result` Return the resolution of a clock. Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return [`errno::inval`](#errno.inval). @@ -1238,15 +1384,22 @@ Note: This is similar to `clock_getres` in POSIX. The clock for which to return the resolution. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result` +The resolution of the clock, or an error if one happened. + +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) -- `resolution`: [`timestamp`](#timestamp) -The resolution of the clock. +- `err`: [`errno`](#errno) --- -#### `clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)` +#### `clock_time_get(id: clockid, precision: timestamp) -> Result` Return the time value of a clock. Note: This is similar to `clock_gettime` in POSIX. @@ -1258,15 +1411,22 @@ The clock for which to return the time. The maximum lag (exclusive) that the returned time value may have, compared to its actual value. ##### Results -- `error`: [`errno`](#errno) - -- `time`: [`timestamp`](#timestamp) +- `error`: `Result` The time value of the clock. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) + +- `err`: [`errno`](#errno) + --- -#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno` +#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` Provide file advisory information on a file descriptor. Note: This is similar to `posix_fadvise` in POSIX. @@ -1283,12 +1443,21 @@ The length of the region to which the advisory applies. The advice. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno` +#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` Force the allocation of space in a file. Note: This is similar to `posix_fallocate` in POSIX. @@ -1302,12 +1471,21 @@ The offset at which to start the allocation. The length of the area that is allocated. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_close(fd: fd) -> errno` +#### `fd_close(fd: fd) -> Result<(), errno>` Close a file descriptor. Note: This is similar to `close` in POSIX. @@ -1315,12 +1493,21 @@ Note: This is similar to `close` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_datasync(fd: fd) -> errno` +#### `fd_datasync(fd: fd) -> Result<(), errno>` Synchronize the data of a file to disk. Note: This is similar to `fdatasync` in POSIX. @@ -1328,12 +1515,21 @@ Note: This is similar to `fdatasync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_fdstat_get(fd: fd) -> (errno, fdstat)` +#### `fd_fdstat_get(fd: fd) -> Result` Get the attributes of a file descriptor. Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. @@ -1341,15 +1537,22 @@ Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as ad - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `stat`: [`fdstat`](#fdstat) +- `error`: `Result` The buffer where the file descriptor's attributes are stored. +###### Variant Layout +- size: 32 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`fdstat`](#fdstat) + +- `err`: [`errno`](#errno) + --- -#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno` +#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` Adjust the flags associated with a file descriptor. Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. @@ -1360,12 +1563,21 @@ Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. The desired values of the file descriptor flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno` +#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` Adjust the rights associated with a file descriptor. This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights @@ -1378,27 +1590,43 @@ The desired rights of the file descriptor. - `fs_rights_inheriting`: [`rights`](#rights) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_filestat_get(fd: fd) -> (errno, filestat)` +#### `fd_filestat_get(fd: fd) -> Result` Return the attributes of an open file. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 72 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `fd_filestat_set_size(fd: fd, size: filesize) -> errno` +#### `fd_filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. Note: This is similar to `ftruncate` in POSIX. @@ -1409,12 +1637,21 @@ Note: This is similar to `ftruncate` in POSIX. The desired file size. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of an open file or directory. Note: This is similar to `futimens` in POSIX. @@ -1431,12 +1668,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)` +#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` Read from a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `preadv` in POSIX. @@ -1450,30 +1696,44 @@ List of scatter/gather vectors in which to store data. The offset within the file at which to read. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_prestat_get(fd: fd) -> (errno, prestat)` +#### `fd_prestat_get(fd: fd) -> Result` Return a description of the given preopened file descriptor. ##### Params - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`prestat`](#prestat) +- `error`: `Result` The buffer where the description is stored. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`prestat`](#prestat) + +- `err`: [`errno`](#errno) + --- -#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> errno` +#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` Return a description of the given preopened file descriptor. ##### Params @@ -1485,12 +1745,21 @@ A buffer into which to write the preopened directory name. - `path_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)` +#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` Write to a file descriptor, without using and updating the file descriptor's offset. Note: This is similar to `pwritev` in POSIX. @@ -1504,15 +1773,22 @@ List of scatter/gather vectors from which to retrieve data. The offset within the file at which to write. ##### Results -- `error`: [`errno`](#errno) - -- `nwritten`: [`size`](#size) +- `error`: `Result` The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_read(fd: fd, iovs: iovec_array) -> (errno, size)` +#### `fd_read(fd: fd, iovs: iovec_array) -> Result` Read from a file descriptor. Note: This is similar to `readv` in POSIX. @@ -1523,15 +1799,22 @@ Note: This is similar to `readv` in POSIX. List of scatter/gather vectors to which to store data. ##### Results -- `error`: [`errno`](#errno) - -- `nread`: [`size`](#size) +- `error`: `Result` The number of bytes read. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> (errno, size)` +#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` Read directory entries from a directory. When successful, the contents of the output buffer consist of a sequence of directory entries. Each directory entry consists of a [`dirent`](#dirent) object, @@ -1554,15 +1837,22 @@ The buffer where directory entries are stored The location within the directory to start reading ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `fd_renumber(fd: fd, to: fd) -> errno` +#### `fd_renumber(fd: fd, to: fd) -> Result<(), errno>` Atomically replace a file descriptor by renumbering another file descriptor. Due to the strong focus on thread safety, this environment does not provide a mechanism to duplicate or renumber a file descriptor to an arbitrary @@ -1579,12 +1869,21 @@ would disappear if `dup2()` were to be removed entirely. The file descriptor to overwrite. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)` +#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> Result` Move the offset of a file descriptor. Note: This is similar to `lseek` in POSIX. @@ -1598,15 +1897,22 @@ The number of bytes to move. The base from which the offset is relative. ##### Results -- `error`: [`errno`](#errno) - -- `newoffset`: [`filesize`](#filesize) +- `error`: `Result` The new offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `fd_sync(fd: fd) -> errno` +#### `fd_sync(fd: fd) -> Result<(), errno>` Synchronize the data and metadata of a file to disk. Note: This is similar to `fsync` in POSIX. @@ -1614,12 +1920,21 @@ Note: This is similar to `fsync` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `fd_tell(fd: fd) -> (errno, filesize)` +#### `fd_tell(fd: fd) -> Result` Return the current offset of a file descriptor. Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. @@ -1627,15 +1942,22 @@ Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - `fd`: [`fd`](#fd) ##### Results -- `error`: [`errno`](#errno) - -- `offset`: [`filesize`](#filesize) +- `error`: `Result` The current offset of the file descriptor, relative to the start of the file. +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + --- -#### `fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)` +#### `fd_write(fd: fd, iovs: ciovec_array) -> Result` Write to a file descriptor. Note: This is similar to `writev` in POSIX. @@ -1646,15 +1968,21 @@ Note: This is similar to `writev` in POSIX. List of scatter/gather vectors from which to retrieve data. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result` -- `nwritten`: [`size`](#size) -The number of bytes written. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) --- -#### `path_create_directory(fd: fd, path: string) -> errno` +#### `path_create_directory(fd: fd, path: string) -> Result<(), errno>` Create a directory. Note: This is similar to `mkdirat` in POSIX. @@ -1665,12 +1993,21 @@ Note: This is similar to `mkdirat` in POSIX. The path at which to create the directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)` +#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` Return the attributes of a file or directory. Note: This is similar to `stat` in POSIX. @@ -1684,15 +2021,22 @@ Flags determining the method of how the path is resolved. The path of the file or directory to inspect. ##### Results -- `error`: [`errno`](#errno) - -- `buf`: [`filestat`](#filestat) +- `error`: `Result` The buffer where the file's attributes are stored. +###### Variant Layout +- size: 72 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + --- -#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno` +#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` Adjust the timestamps of a file or directory. Note: This is similar to `utimensat` in POSIX. @@ -1715,12 +2059,21 @@ The desired values of the data modification timestamp. A bitmask indicating which timestamps to adjust. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Create a hard link. Note: This is similar to `linkat` in POSIX. @@ -1740,12 +2093,21 @@ The working directory at which the resolution of the new path starts. The destination path at which to create the hard link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> (errno, fd)` +#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> Result` Open a file or directory. The returned file descriptor is not guaranteed to be the lowest-numbered file descriptor not currently open; it is randomized to prevent @@ -1781,15 +2143,22 @@ file descriptors derived from it. - `fdflags`: [`fdflags`](#fdflags) ##### Results -- `error`: [`errno`](#errno) - -- `opened_fd`: [`fd`](#fd) +- `error`: `Result` The file descriptor of the file that has been opened. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`fd`](#fd) + +- `err`: [`errno`](#errno) + --- -#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> (errno, size)` +#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` Read the contents of a symbolic link. Note: This is similar to `readlinkat` in POSIX. @@ -1805,15 +2174,22 @@ The buffer to which to write the contents of the symbolic link. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) - -- `bufused`: [`size`](#size) +- `error`: `Result` The number of bytes placed in the buffer. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `path_remove_directory(fd: fd, path: string) -> errno` +#### `path_remove_directory(fd: fd, path: string) -> Result<(), errno>` Remove a directory. Return [`errno::notempty`](#errno.notempty) if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. @@ -1825,12 +2201,21 @@ Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. The path to a directory to remove. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno` +#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` Rename a file or directory. Note: This is similar to `renameat` in POSIX. @@ -1847,12 +2232,21 @@ The working directory at which the resolution of the new path starts. The destination path to which to rename the file or directory. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_symlink(old_path: string, fd: fd, new_path: string) -> errno` +#### `path_symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` Create a symbolic link. Note: This is similar to `symlinkat` in POSIX. @@ -1866,12 +2260,21 @@ The contents of the symbolic link. The destination path at which to create the symbolic link. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `path_unlink_file(fd: fd, path: string) -> errno` +#### `path_unlink_file(fd: fd, path: string) -> Result<(), errno>` Unlink a file. Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. @@ -1883,12 +2286,21 @@ Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. The path to a file to unlink. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> (errno, size)` +#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` Concurrently poll for the occurrence of a set of events. ##### Params @@ -1902,11 +2314,18 @@ The events that have occurred. Both the number of subscriptions and events. ##### Results -- `error`: [`errno`](#errno) - -- `nevents`: [`size`](#size) +- `error`: `Result` The number of events stored. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- @@ -1923,7 +2342,7 @@ The exit code returned by the process. --- -#### `proc_raise(sig: signal) -> errno` +#### `proc_raise(sig: signal) -> Result<(), errno>` Send a signal to the process of the calling thread. Note: This is similar to `raise` in POSIX. @@ -1932,23 +2351,41 @@ Note: This is similar to `raise` in POSIX. The signal condition to trigger. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sched_yield() -> errno` +#### `sched_yield() -> Result<(), errno>` Temporarily yield execution of the calling thread. Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. ##### Params ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `random_get(buf: Pointer, buf_len: size) -> errno` +#### `random_get(buf: Pointer, buf_len: size) -> Result<(), errno>` Write high-quality random data into a buffer. This function blocks when the implementation is unable to immediately provide sufficient high-quality random data. @@ -1963,12 +2400,21 @@ The buffer to fill with random data. - `buf_len`: [`size`](#size) ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) --- -#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)` +#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` Receive a message from a socket. Note: This is similar to `recv` in POSIX, though it also supports reading the data into multiple buffers in the manner of `readv`. @@ -1983,18 +2429,31 @@ List of scatter/gather vectors to which to store data. Message flags. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(size, roflags), errno>` +Number of bytes stored in ri_data and message flags. -- `ro_datalen`: [`size`](#size) -Number of bytes stored in ri_data. +###### Variant Layout +- size: 12 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: `(size, roflags)` -- `ro_flags`: [`roflags`](#roflags) -Message flags. +####### Record members +- `0`: [`size`](#size) + +Offset: 0 + +- `1`: [`roflags`](#roflags) + +Offset: 4 + +- `err`: [`errno`](#errno) --- -#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)` +#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` Send a message on a socket. Note: This is similar to `send` in POSIX, though it also supports writing the data from multiple buffers in the manner of `writev`. @@ -2009,15 +2468,22 @@ List of scatter/gather vectors to which to retrieve data Message flags. ##### Results -- `error`: [`errno`](#errno) - -- `so_datalen`: [`size`](#size) +- `error`: `Result` Number of bytes transmitted. +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + --- -#### `sock_shutdown(fd: fd, how: sdflags) -> errno` +#### `sock_shutdown(fd: fd, how: sdflags) -> Result<(), errno>` Shut down socket send and receive channels. Note: This is similar to `shutdown` in POSIX. @@ -2028,5 +2494,14 @@ Note: This is similar to `shutdown` in POSIX. Which channels on the socket to shut down. ##### Results -- `error`: [`errno`](#errno) +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx index 70e726553..311b42233 100644 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ b/proposals/filesystem/phases/snapshot/witx/typenames.witx @@ -196,7 +196,7 @@ ;;; File descriptor rights, determining which actions may be performed. (typename $rights - (flags (@witx bitflags u64) + (flags (@witx repr u64) ;;; The right to invoke `fd_datasync`. ;; ;;; If `path_open` is set, includes the right to invoke @@ -381,7 +381,7 @@ ;;; File descriptor flags. (typename $fdflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Append mode: Data written to the file is always appended to the file's end. $append ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. @@ -418,7 +418,7 @@ ;;; Which file time attributes to adjust. (typename $fstflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. $atim ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. @@ -432,7 +432,7 @@ ;;; Flags determining the method of how paths are resolved. (typename $lookupflags - (flags (@witx bitflags u32) + (flags (@witx repr u32) ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. $symlink_follow ) @@ -440,7 +440,7 @@ ;;; Open flags used by `path_open`. (typename $oflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Create file if it does not exist. $creat ;;; Fail if not a directory. @@ -499,7 +499,7 @@ ;;; The state of the file descriptor subscribed to with ;;; `eventtype::fd_read` or `eventtype::fd_write`. (typename $eventrwflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; The peer of this socket has closed or disconnected. $fd_readwrite_hangup ) @@ -534,7 +534,7 @@ ;;; Flags determining how to interpret the timestamp provided in ;;; `subscription_clock::timeout`. (typename $subclockflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; If set, treat the timestamp provided in ;;; `subscription_clock::timeout` as an absolute timestamp of clock ;;; `subscription_clock::id`. If clear, treat the timestamp @@ -693,7 +693,7 @@ ;;; Flags provided to `sock_recv`. (typename $riflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returns the message without removing it from the socket's receive queue. $recv_peek ;;; On byte-stream sockets, block until the full amount of data can be returned. @@ -703,7 +703,7 @@ ;;; Flags returned by `sock_recv`. (typename $roflags - (flags (@witx bitflags u16) + (flags (@witx repr u16) ;;; Returned by `sock_recv`: Message data has been truncated. $recv_data_truncated ) @@ -715,7 +715,7 @@ ;;; Which channels on a socket to shut down. (typename $sdflags - (flags (@witx bitflags u8) + (flags (@witx repr u8) ;;; Disables further receive operations. $rd ;;; Disables further send operations. diff --git a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx index eacfab268..df3c670f3 100644 --- a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -17,15 +17,13 @@ (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return command-line argument data sizes. (@interface func (export "args_sizes_get") - (result $error $errno) - ;;; The number of arguments. - (result $argc $size) - ;;; The size of the argument string data. - (result $argv_buf_size $size) + ;;; Returns the number of arguments and the size of the argument string + ;;; data, or an error. + (result $error (expected (tuple $size $size) (error $errno))) ) ;;; Read environment variable data. @@ -33,15 +31,13 @@ (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return environment variable data sizes. (@interface func (export "environ_sizes_get") - (result $error $errno) - ;;; The number of environment variable arguments. - (result $environc $size) - ;;; The size of the environment variable data. - (result $environ_buf_size $size) + ;;; Returns the number of environment variable arguments and the size of the + ;;; environment variable data. + (result $error (expected (tuple $size $size) (error $errno))) ) ;;; Return the resolution of a clock. @@ -51,9 +47,8 @@ (@interface func (export "clock_res_get") ;;; The clock for which to return the resolution. (param $id $clockid) - (result $error $errno) - ;;; The resolution of the clock. - (result $resolution $timestamp) + ;;; The resolution of the clock, or an error if one happened. + (result $error (expected $timestamp (error $errno))) ) ;;; Return the time value of a clock. ;;; Note: This is similar to `clock_gettime` in POSIX. @@ -62,9 +57,8 @@ (param $id $clockid) ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. (param $precision $timestamp) - (result $error $errno) ;;; The time value of the clock. - (result $time $timestamp) + (result $error (expected $timestamp (error $errno))) ) ;;; Provide file advisory information on a file descriptor. @@ -77,7 +71,7 @@ (param $len $filesize) ;;; The advice. (param $advice $advice) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Force the allocation of space in a file. @@ -88,30 +82,29 @@ (param $offset $filesize) ;;; The length of the area that is allocated. (param $len $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Close a file descriptor. ;;; Note: This is similar to `close` in POSIX. (@interface func (export "fd_close") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Synchronize the data of a file to disk. ;;; Note: This is similar to `fdatasync` in POSIX. (@interface func (export "fd_datasync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Get the attributes of a file descriptor. ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. (@interface func (export "fd_fdstat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file descriptor's attributes are stored. - (result $stat $fdstat) + (result $error (expected $fdstat (error $errno))) ) ;;; Adjust the flags associated with a file descriptor. @@ -120,7 +113,7 @@ (param $fd $fd) ;;; The desired values of the file descriptor flags. (param $flags $fdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the rights associated with a file descriptor. @@ -130,15 +123,14 @@ ;;; The desired rights of the file descriptor. (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of an open file. (@interface func (export "fd_filestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. @@ -147,7 +139,7 @@ (param $fd $fd) ;;; The desired file size. (param $size $filesize) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Adjust the timestamps of an open file or directory. @@ -160,7 +152,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Read from a file descriptor, without using and updating the file descriptor's offset. @@ -171,17 +163,15 @@ (param $iovs $iovec_array) ;;; The offset within the file at which to read. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Return a description of the given preopened file descriptor. (@interface func (export "fd_prestat_get") (param $fd $fd) - (result $error $errno) ;;; The buffer where the description is stored. - (result $buf $prestat) + (result $error (expected $prestat (error $errno))) ) ;;; Return a description of the given preopened file descriptor. @@ -190,7 +180,7 @@ ;;; A buffer into which to write the preopened directory name. (param $path (@witx pointer u8)) (param $path_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write to a file descriptor, without using and updating the file descriptor's offset. @@ -201,9 +191,8 @@ (param $iovs $ciovec_array) ;;; The offset within the file at which to write. (param $offset $filesize) - (result $error $errno) ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Read from a file descriptor. @@ -212,9 +201,8 @@ (param $fd $fd) ;;; List of scatter/gather vectors to which to store data. (param $iovs $iovec_array) - (result $error $errno) ;;; The number of bytes read. - (result $nread $size) + (result $error (expected $size (error $errno))) ) ;;; Read directory entries from a directory. @@ -234,9 +222,8 @@ (param $buf_len $size) ;;; The location within the directory to start reading (param $cookie $dircookie) - (result $error $errno) ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Atomically replace a file descriptor by renumbering another file descriptor. @@ -253,7 +240,7 @@ (param $fd $fd) ;;; The file descriptor to overwrite. (param $to $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Move the offset of a file descriptor. @@ -264,25 +251,23 @@ (param $offset $filedelta) ;;; The base from which the offset is relative. (param $whence $whence) - (result $error $errno) ;;; The new offset of the file descriptor, relative to the start of the file. - (result $newoffset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Synchronize the data and metadata of a file to disk. ;;; Note: This is similar to `fsync` in POSIX. (@interface func (export "fd_sync") (param $fd $fd) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the current offset of a file descriptor. ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. (@interface func (export "fd_tell") (param $fd $fd) - (result $error $errno) ;;; The current offset of the file descriptor, relative to the start of the file. - (result $offset $filesize) + (result $error (expected $filesize (error $errno))) ) ;;; Write to a file descriptor. @@ -291,9 +276,7 @@ (param $fd $fd) ;;; List of scatter/gather vectors from which to retrieve data. (param $iovs $ciovec_array) - (result $error $errno) - ;;; The number of bytes written. - (result $nwritten $size) + (result $error (expected $size (error $errno))) ) ;;; Create a directory. @@ -302,7 +285,7 @@ (param $fd $fd) ;;; The path at which to create the directory. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Return the attributes of a file or directory. @@ -313,9 +296,8 @@ (param $flags $lookupflags) ;;; The path of the file or directory to inspect. (param $path string) - (result $error $errno) ;;; The buffer where the file's attributes are stored. - (result $buf $filestat) + (result $error (expected $filestat (error $errno))) ) ;;; Adjust the timestamps of a file or directory. @@ -332,7 +314,7 @@ (param $mtim $timestamp) ;;; A bitmask indicating which timestamps to adjust. (param $fst_flags $fstflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a hard link. @@ -347,7 +329,7 @@ (param $new_fd $fd) ;;; The destination path at which to create the hard link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Open a file or directory. @@ -379,9 +361,8 @@ (param $fs_rights_base $rights) (param $fs_rights_inheriting $rights) (param $fdflags $fdflags) - (result $error $errno) ;;; The file descriptor of the file that has been opened. - (result $opened_fd $fd) + (result $error (expected $fd (error $errno))) ) ;;; Read the contents of a symbolic link. @@ -393,9 +374,8 @@ ;;; The buffer to which to write the contents of the symbolic link. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) ;;; The number of bytes placed in the buffer. - (result $bufused $size) + (result $error (expected $size (error $errno))) ) ;;; Remove a directory. @@ -405,7 +385,7 @@ (param $fd $fd) ;;; The path to a directory to remove. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Rename a file or directory. @@ -418,7 +398,7 @@ (param $new_fd $fd) ;;; The destination path to which to rename the file or directory. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Create a symbolic link. @@ -429,7 +409,7 @@ (param $fd $fd) ;;; The destination path at which to create the symbolic link. (param $new_path string) - (result $error $errno) + (result $error (expected (error $errno))) ) @@ -440,7 +420,7 @@ (param $fd $fd) ;;; The path to a file to unlink. (param $path string) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Concurrently poll for the occurrence of a set of events. @@ -451,9 +431,8 @@ (param $out (@witx pointer $event)) ;;; Both the number of subscriptions and events. (param $nsubscriptions $size) - (result $error $errno) ;;; The number of events stored. - (result $nevents $size) + (result $error (expected $size (error $errno))) ) ;;; Terminate the process normally. An exit code of 0 indicates successful @@ -470,13 +449,13 @@ (@interface func (export "proc_raise") ;;; The signal condition to trigger. (param $sig $signal) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Temporarily yield execution of the calling thread. ;;; Note: This is similar to `sched_yield` in POSIX. (@interface func (export "sched_yield") - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Write high-quality random data into a buffer. @@ -489,7 +468,7 @@ ;;; The buffer to fill with random data. (param $buf (@witx pointer u8)) (param $buf_len $size) - (result $error $errno) + (result $error (expected (error $errno))) ) ;;; Receive a message from a socket. @@ -501,11 +480,8 @@ (param $ri_data $iovec_array) ;;; Message flags. (param $ri_flags $riflags) - (result $error $errno) - ;;; Number of bytes stored in ri_data. - (result $ro_datalen $size) - ;;; Message flags. - (result $ro_flags $roflags) + ;;; Number of bytes stored in ri_data and message flags. + (result $error (expected (tuple $size $roflags) (error $errno))) ) ;;; Send a message on a socket. @@ -517,9 +493,8 @@ (param $si_data $ciovec_array) ;;; Message flags. (param $si_flags $siflags) - (result $error $errno) ;;; Number of bytes transmitted. - (result $so_datalen $size) + (result $error (expected $size (error $errno))) ) ;;; Shut down socket send and receive channels. @@ -528,6 +503,6 @@ (param $fd $fd) ;;; Which channels on the socket to shut down. (param $how $sdflags) - (result $error $errno) + (result $error (expected (error $errno))) ) ) diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index bf9ce16cd..bd4bfc076 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witx" -version = "0.8.8" +version = "0.9.0" description = "Parse and validate witx file format" homepage = "https://github.com/WebAssembly/WASI" repository = "https://github.com/WebAssembly/WASI" @@ -17,7 +17,7 @@ crate-type=["rlib"] anyhow = "1" log = "0.4" thiserror = "1.0" -wast = { version = "22.0.0", default-features = false } +wast = { version = "33.0.0", default-features = false } [dev-dependencies] diff = "0.1.11" diff --git a/proposals/filesystem/tools/witx/src/abi.rs b/proposals/filesystem/tools/witx/src/abi.rs new file mode 100644 index 000000000..0e1ca9cb4 --- /dev/null +++ b/proposals/filesystem/tools/witx/src/abi.rs @@ -0,0 +1,925 @@ +//! Definition of the ABI of witx functions +//! +//! This module is intended to assist with code generators which are binding or +//! implementing APIs defined by `*.witx` files. THis module contains all +//! details necessary to implement the actual ABI of these functions so wasm +//! modules and hosts can communicate with one another. +//! +//! Each interface types function (a function defined in `*.witx`) currently has +//! a well-known wasm signature associated with it. There's then also a standard +//! way to convert from interface-types values (whose representation is defined +//! per-language) into this wasm API. This module is intended to assist with +//! this definition. +//! +//! Contained within are two primary functions, [`InterfaceFunc::call_wasm`] and +//! [`InterfaceFunc::call_interface`]. These functions implement the two ways to +//! interact with an interface types function, namely calling the raw wasm +//! version and calling the high-level version with interface types. These two +//! functions are fed a structure that implements [`Bindgen`]. An instance of +//! [`Bindgen`] receives instructions which are low-level implementation details +//! of how to convert to and from wasm types and interface types. Code +//! generators will need to implement the various instructions to support APIs. + +use crate::{ + BuiltinType, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, NamedType, Type, TypeRef, +}; + +/// Enumerates wasm types used by interface types when lowering/lifting. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum WasmType { + I32, + I64, + F32, + F64, + // NOTE: we don't lower interface types to any other Wasm type, + // e.g. externref, so we don't need to define them here. +} + +impl From for WasmType { + fn from(i: IntRepr) -> WasmType { + match i { + IntRepr::U8 | IntRepr::U16 | IntRepr::U32 => WasmType::I32, + IntRepr::U64 => WasmType::I64, + } + } +} + +/// Possible ABIs for interface functions to have. +/// +/// Note that this is a stopgap until we have more of interface types. Interface +/// types functions do not have ABIs, they have APIs. For the meantime, however, +/// we mandate ABIs to ensure we can all talk to each other. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum Abi { + /// Only stable ABI currently, and is the historical WASI ABI since it was + /// first created. + /// + /// Note that this ABI is limited notably in its return values where it can + /// only return 0 results or one `Result` lookalike. + Preview1, +} + +// Helper macro for defining instructions without having to have tons of +// exhaustive `match` statements to update +macro_rules! def_instruction { + ( + $( #[$enum_attr:meta] )* + pub enum Instruction<'a> { + $( + $( #[$attr:meta] )* + $variant:ident $( { + $($field:ident : $field_ty:ty $(,)* )* + } )? + : + [$num_popped:expr] => [$num_pushed:expr], + )* + } + ) => { + $( #[$enum_attr] )* + pub enum Instruction<'a> { + $( + $( #[$attr] )* + $variant $( { + $( + $field : $field_ty, + )* + } )? , + )* + } + + impl Instruction<'_> { + /// How many operands does this instruction pop from the stack? + #[allow(unused_variables)] + pub fn operands_len(&self) -> usize { + match self { + $( + Self::$variant $( { + $( + $field, + )* + } )? => $num_popped, + )* + } + } + + /// How many results does this instruction push onto the stack? + #[allow(unused_variables)] + pub fn results_len(&self) -> usize { + match self { + $( + Self::$variant $( { + $( + $field, + )* + } )? => $num_pushed, + )* + } + } + } + }; +} + +def_instruction! { + #[derive(Debug)] + pub enum Instruction<'a> { + /// Acquires the specified parameter and places it on the stack. + /// Depending on the context this may refer to wasm parameters or + /// interface types parameters. + GetArg { nth: usize } : [0] => [1], + /// Takes the value off the top of the stack and writes it into linear + /// memory. Pushes the address in linear memory as an `i32`. + AddrOf : [1] => [1], + /// Converts an interface type `char` value to a 32-bit integer + /// representing the unicode scalar value. + I32FromChar : [1] => [1], + /// Converts an interface type `u64` value to a wasm `i64`. + I64FromU64 : [1] => [1], + /// Converts an interface type `s64` value to a wasm `i64`. + I64FromS64 : [1] => [1], + /// Converts an interface type `u32` value to a wasm `i32`. + I32FromU32 : [1] => [1], + /// Converts an interface type `s32` value to a wasm `i32`. + I32FromS32 : [1] => [1], + /// Converts a language-specific `usize` value to a wasm `i32`. + I32FromUsize : [1] => [1], + /// Converts an interface type `u16` value to a wasm `i32`. + I32FromU16 : [1] => [1], + /// Converts an interface type `s16` value to a wasm `i32`. + I32FromS16 : [1] => [1], + /// Converts an interface type `u8` value to a wasm `i32`. + I32FromU8 : [1] => [1], + /// Converts an interface type `s8` value to a wasm `i32`. + I32FromS8 : [1] => [1], + /// Converts a language-specific C `char` value to a wasm `i32`. + I32FromChar8 : [1] => [1], + /// Converts a language-specific pointer value to a wasm `i32`. + I32FromPointer : [1] => [1], + /// Converts a language-specific pointer value to a wasm `i32`. + I32FromConstPointer : [1] => [1], + /// Converts a language-specific handle value to a wasm `i32`. + I32FromHandle { ty: &'a NamedType } : [1] => [1], + /// Converts a language-specific record-of-bools to the packed + /// representation as an `i32`. + I32FromBitflags { ty: &'a NamedType } : [1] => [1], + /// Converts a language-specific record-of-bools to the packed + /// representation as an `i64`. + I64FromBitflags { ty: &'a NamedType } : [1] => [1], + /// Converts an interface type list into its pointer/length, pushing + /// them both on the stack. + ListPointerLength : [1] => [2], + /// Pops two `i32` values from the stack and creates a list from them of + /// the specified type. The first operand is the pointer in linear + /// memory to the start of the list and the second operand is the + /// length. + ListFromPointerLength { ty: &'a TypeRef } : [2] => [1], + /// Conversion an interface type `f32` value to a wasm `f32`. + /// + /// This may be a noop for some implementations, but it's here in case the + /// native language representation of `f32` is different than the wasm + /// representation of `f32`. + F32FromIf32 : [1] => [1], + /// Conversion an interface type `f64` value to a wasm `f64`. + /// + /// This may be a noop for some implementations, but it's here in case the + /// native language representation of `f64` is different than the wasm + /// representation of `f64`. + F64FromIf64 : [1] => [1], + + /// Represents a call to a raw WebAssembly API. The module/name are + /// provided inline as well as the types if necessary. + CallWasm { + module: &'a str, + name: &'a str, + params: &'a [WasmType], + results: &'a [WasmType], + } : [params.len()] => [results.len()], + + /// Same as `CallWasm`, except the dual where an interface is being + /// called rather than a raw wasm function. + CallInterface { + module: &'a str, + func: &'a InterfaceFunc, + } : [func.params.len()] => [func.results.len()], + + /// Converts a native wasm `i32` to an interface type `s8`. + /// + /// This will truncate the upper bits of the `i32`. + S8FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `u8`. + /// + /// This will truncate the upper bits of the `i32`. + U8FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `s16`. + /// + /// This will truncate the upper bits of the `i32`. + S16FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `u16`. + /// + /// This will truncate the upper bits of the `i32`. + U16FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `s32`. + S32FromI32 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `u32`. + U32FromI32 : [1] => [1], + /// Converts a native wasm `i64` to an interface type `s64`. + S64FromI64 : [1] => [1], + /// Converts a native wasm `i64` to an interface type `u64`. + U64FromI64 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `char`. + /// + /// It's safe to assume that the `i32` is indeed a valid unicode code point. + CharFromI32 : [1] => [1], + /// Converts a native wasm `i32` to a language-specific C `char`. + /// + /// This will truncate the upper bits of the `i32`. + Char8FromI32 : [1] => [1], + /// Converts a native wasm `i32` to a language-specific `usize`. + UsizeFromI32 : [1] => [1], + /// Converts a native wasm `f32` to an interface type `f32`. + If32FromF32 : [1] => [1], + /// Converts a native wasm `f64` to an interface type `f64`. + If64FromF64 : [1] => [1], + /// Converts a native wasm `i32` to an interface type `handle`. + HandleFromI32 { ty: &'a NamedType } : [1] => [1], + /// Converts a native wasm `i32` to a language-specific pointer. + PointerFromI32 { ty: &'a TypeRef }: [1] => [1], + /// Converts a native wasm `i32` to a language-specific pointer. + ConstPointerFromI32 { ty: &'a TypeRef } : [1] => [1], + /// Converts a native wasm `i32` to a language-specific record-of-bools. + BitflagsFromI32 { ty: &'a NamedType } : [1] => [1], + /// Converts a native wasm `i64` to a language-specific record-of-bools. + BitflagsFromI64 { ty: &'a NamedType } : [1] => [1], + /// Acquires the return pointer `n` and pushes an `i32` on the stack. + /// + /// Implementations of [`Bindgen`] may have [`Bindgen::allocate_space`] + /// called to reserve space in memory for the result of a computation to + /// get written. This instruction acquires a pointer to the space + /// reserved in `allocate_space`. + ReturnPointerGet { n: usize } : [0] => [1], + /// Loads the interface types value from an `i32` pointer popped from + /// the stack. + Load { ty: &'a NamedType } : [1] => [1], + /// Stores an interface types value into linear memory. The first + /// operand is the value to store and the second operand is the pointer + /// in linear memory to store it at. + Store { ty: &'a NamedType } : [2] => [0], + /// Pops a native wasm `i32` from the stack, as well as two blocks + /// internally from the code generator. + /// + /// If the value is 0 then the first "ok" block value should be used. + /// If the value is anything else then the second "err" block value + /// should be used, and the value is used as the error enum. + /// + /// Note that this is a special instruction matching the current ABI of + /// WASI and intentionally differs from the type-level grammar of + /// interface types results. + ResultLift : [1] => [1], + /// Pops a native interface value from the stack as well as two blocks + /// internally from the code generator. + /// + /// A `match` is performed on the value popped and the corresponding + /// block for ok/err is used depending on value. This pushes a single + /// `i32` onto the stack representing the error code for this result. + /// + /// Note that like `ResultLift` this is specialized to the current WASI + /// ABI. + ResultLower { + ok: Option<&'a TypeRef>, + err: Option<&'a TypeRef>, + } : [1] => [1], + /// Converts a native wasm `i32` to an interface type `enum` value. + /// + /// It's guaranteed that the interface type integer value is within + /// range for this enum's type. Additionally `ty` is guaranteed to be + /// enum-like as a `Variant` where all `case` arms have no associated + /// type with them. The purpose of this instruction is to convert a + /// native wasm integer into the enum type for the interface. + EnumLift { ty: &'a NamedType } : [1] => [1], + /// Converts an interface types enum value into a wasm `i32`. + EnumLower { ty: &'a NamedType } : [1] => [1], + /// Creates a tuple from the top `n` elements on the stack, pushing the + /// tuple onto the stack. + TupleLift { amt: usize } : [*amt] => [1], + /// Splits a tuple at the top of the stack into its `n` components, + /// pushing them all onto the stack. + TupleLower { amt: usize } : [1] => [*amt], + /// This is a special instruction specifically for the original ABI of + /// WASI. The raw return `i32` of a function is re-pushed onto the + /// stack for reuse. + ReuseReturn : [0] => [1], + /// Returns `amt` values on the stack. This is always the last + /// instruction. + Return { amt: usize } : [*amt] => [0], + /// This is a special instruction used at the entry of blocks used as + /// part of `ResultLower`, representing that the payload of that variant + /// being matched on should be pushed onto the stack. + VariantPayload : [0] => [1], + } +} + +impl Abi { + /// Validates the parameters/results are representable in this ABI. + /// + /// Returns an error string if they're not representable or returns `Ok` if + /// they're indeed representable. + pub fn validate( + &self, + _params: &[InterfaceFuncParam], + results: &[InterfaceFuncParam], + ) -> Result<(), String> { + assert_eq!(*self, Abi::Preview1); + match results.len() { + 0 => {} + 1 => match &**results[0].tref.type_() { + Type::Handle(_) | Type::Builtin(_) | Type::ConstPointer(_) | Type::Pointer(_) => {} + Type::Variant(v) => { + let (ok, err) = match v.as_expected() { + Some(pair) => pair, + None => return Err("invalid return type".to_string()), + }; + if let Some(ty) = ok { + match &**ty.type_() { + Type::Record(r) if r.is_tuple() => { + for member in r.members.iter() { + if !member.tref.named() { + return Err( + "only named types are allowed in results".to_string() + ); + } + } + } + _ => { + if !ty.named() { + return Err( + "only named types are allowed in results".to_string() + ); + } + } + } + } + if let Some(ty) = err { + if !ty.named() { + return Err("only named types are allowed in results".to_string()); + } + if let Type::Variant(v) = &**ty.type_() { + if v.is_enum() { + return Ok(()); + } + } + } + } + Type::Record(r) if r.bitflags_repr().is_some() => {} + Type::Record(_) | Type::List(_) => return Err("invalid return type".to_string()), + }, + _ => return Err("more than one result".to_string()), + } + Ok(()) + } +} + +/// Trait for language implementors to use to generate glue code between native +/// WebAssembly signatures and interface types signatures. +/// +/// This is used as an implementation detail in interpreting the ABI between +/// interface types and wasm types. Eventually this will be driven by interface +/// types adapters themselves, but for now the ABI of a function dictates what +/// instructions are fed in. +/// +/// Types implementing `Bindgen` are incrementally fed `Instruction` values to +/// generate code for. Instructions operate like a stack machine where each +/// instruction has a list of inputs and a list of outputs (provided by the +/// `emit` function). +pub trait Bindgen { + /// The intermediate type for fragments of code for this type. + /// + /// For most languages `String` is a suitable intermediate type. + type Operand; + + /// Emit code to implement the given instruction. + /// + /// Each operand is given in `operands` and can be popped off if ownership + /// is required. It's guaranteed that `operands` has the appropriate length + /// for the `inst` given, as specified with [`Instruction`]. + /// + /// Each result variable should be pushed onto `results`. This function must + /// push the appropriate number of results or binding generation will panic. + fn emit( + &mut self, + inst: &Instruction<'_>, + operands: &mut Vec, + results: &mut Vec, + ); + + /// Allocates temporary space in linear memory indexed by `slot` with enough + /// space to store `ty`. + /// + /// This is called when calling some wasm functions where a return pointer + /// is needed. + fn allocate_space(&mut self, slot: usize, ty: &NamedType); + + /// Enters a new block of code to generate code for. + /// + /// This is currently exclusively used for constructing variants. When a + /// variant is constructed a block here will be pushed for each case of a + /// variant, generating the code necessary to translate a variant case. + /// + /// Blocks are completed with `finish_block` below. It's expected that `emit` + /// will always push code (if necessary) into the "current block", which is + /// updated by calling this method and `finish_block` below. + fn push_block(&mut self); + + /// Indicates to the code generator that a block is completed, and the + /// `operand` specified was the resulting value of the block. + /// + /// This method will be used to compute the value of each arm of lifting a + /// variant. The `operand` will be `None` if the variant case didn't + /// actually have any type associated with it. Otherwise it will be `Some` + /// as the last value remaining on the stack representing the value + /// associated with a variant's `case`. + /// + /// It's expected that this will resume code generation in the previous + /// block before `push_block` was called. This must also save the results + /// of the current block internally for instructions like `ResultLift` to + /// use later. + fn finish_block(&mut self, operand: Option); +} + +impl InterfaceFunc { + /// Get the WebAssembly type signature for this interface function + /// + /// The first entry returned is the list of parameters and the second entry + /// is the list of results for the wasm function signature. + pub fn wasm_signature(&self) -> (Vec, Vec) { + assert_eq!(self.abi, Abi::Preview1); + let mut params = Vec::new(); + let mut results = Vec::new(); + for param in self.params.iter() { + match &**param.tref.type_() { + Type::Builtin(BuiltinType::S8) + | Type::Builtin(BuiltinType::U8 { .. }) + | Type::Builtin(BuiltinType::S16) + | Type::Builtin(BuiltinType::U16) + | Type::Builtin(BuiltinType::S32) + | Type::Builtin(BuiltinType::U32 { .. }) + | Type::Builtin(BuiltinType::Char) + | Type::Pointer(_) + | Type::ConstPointer(_) + | Type::Handle(_) + | Type::Variant(_) => params.push(WasmType::I32), + + Type::Record(r) => match r.bitflags_repr() { + Some(repr) => params.push(WasmType::from(repr)), + None => params.push(WasmType::I32), + }, + + Type::Builtin(BuiltinType::S64) | Type::Builtin(BuiltinType::U64) => { + params.push(WasmType::I64) + } + + Type::Builtin(BuiltinType::F32) => params.push(WasmType::F32), + Type::Builtin(BuiltinType::F64) => params.push(WasmType::F64), + + Type::List(_) => { + params.push(WasmType::I32); + params.push(WasmType::I32); + } + } + } + + for param in self.results.iter() { + match &**param.tref.type_() { + Type::Builtin(BuiltinType::S8) + | Type::Builtin(BuiltinType::U8 { .. }) + | Type::Builtin(BuiltinType::S16) + | Type::Builtin(BuiltinType::U16) + | Type::Builtin(BuiltinType::S32) + | Type::Builtin(BuiltinType::U32 { .. }) + | Type::Builtin(BuiltinType::Char) + | Type::Pointer(_) + | Type::ConstPointer(_) + | Type::Handle(_) => results.push(WasmType::I32), + + Type::Builtin(BuiltinType::S64) | Type::Builtin(BuiltinType::U64) => { + results.push(WasmType::I64) + } + + Type::Builtin(BuiltinType::F32) => results.push(WasmType::F32), + Type::Builtin(BuiltinType::F64) => results.push(WasmType::F64), + + Type::Record(r) => match r.bitflags_repr() { + Some(repr) => results.push(WasmType::from(repr)), + None => unreachable!(), + }, + Type::List(_) => unreachable!(), + + Type::Variant(v) => { + results.push(match v.tag_repr { + IntRepr::U64 => WasmType::I64, + IntRepr::U32 | IntRepr::U16 | IntRepr::U8 => WasmType::I32, + }); + if v.is_enum() { + continue; + } + // return pointer + if let Some(ty) = &v.cases[0].tref { + match &**ty.type_() { + Type::Record(r) if r.is_tuple() => { + for _ in 0..r.members.len() { + params.push(WasmType::I32); + } + } + _ => params.push(WasmType::I32), + } + } + } + } + } + (params, results) + } + + /// Generates an abstract sequence of instructions which represents this + /// function being adapted as an imported function. + /// + /// The instructions here, when executed, will emulate a language with + /// interface types calling the concrete wasm implementation. The parameters + /// for the returned instruction sequence are the language's own + /// interface-types parameters. One instruction in the instruction stream + /// will be a `Call` which represents calling the actual raw wasm function + /// signature. + /// + /// This function is useful, for example, if you're building a language + /// generator for WASI bindings. This will document how to translate + /// language-specific values into the wasm types to call a WASI function, + /// and it will also automatically convert the results of the WASI function + /// back to a language-specific value. + pub fn call_wasm(&self, module: &Id, bindgen: &mut impl Bindgen) { + assert_eq!(self.abi, Abi::Preview1); + Generator { + bindgen, + operands: vec![], + results: vec![], + stack: vec![], + } + .call_wasm(module, self); + } + + /// This is the dual of [`InterfaceFunc::call_wasm`], except that instead of + /// calling a wasm signature it generates code to come from a wasm signature + /// and call an interface types signature. + pub fn call_interface(&self, module: &Id, bindgen: &mut impl Bindgen) { + assert_eq!(self.abi, Abi::Preview1); + Generator { + bindgen, + operands: vec![], + results: vec![], + stack: vec![], + } + .call_interface(module, self); + } +} + +struct Generator<'a, B: Bindgen> { + bindgen: &'a mut B, + operands: Vec, + results: Vec, + stack: Vec, +} + +impl Generator<'_, B> { + fn call_wasm(&mut self, module: &Id, func: &InterfaceFunc) { + // Translate all parameters which are interface values by lowering them + // to their wasm types. + for (nth, param) in func.params.iter().enumerate() { + self.emit(&Instruction::GetArg { nth }); + self.lower(¶m.tref, None); + } + + // If necessary for our ABI, insert return pointers for any returned + // values through a result. + assert!(func.results.len() < 2); + if let Some(result) = func.results.get(0) { + self.prep_return_pointer(&result.tref.type_()); + } + + let (params, results) = func.wasm_signature(); + self.emit(&Instruction::CallWasm { + module: module.as_str(), + name: func.name.as_str(), + params: ¶ms, + results: &results, + }); + + // Lift the return value if one is present. + if let Some(result) = func.results.get(0) { + self.lift(&result.tref, true); + } + + self.emit(&Instruction::Return { + amt: func.results.len(), + }); + } + + fn call_interface(&mut self, module: &Id, func: &InterfaceFunc) { + // Lift all wasm parameters into interface types first. + // + // Note that consuming arguments is somewhat janky right now by manually + // giving lists a second argument for their length. In the future we'll + // probably want to refactor the `lift` function to internally know how + // to consume arguments. + let mut nth = 0; + for param in func.params.iter() { + self.emit(&Instruction::GetArg { nth }); + nth += 1; + if let Type::List(_) = &**param.tref.type_() { + self.emit(&Instruction::GetArg { nth }); + nth += 1; + } + self.lift(¶m.tref, false); + } + + self.emit(&Instruction::CallInterface { + module: module.as_str(), + func, + }); + + // Like above the current ABI only has at most one result, so lower it + // here if necessary. + if let Some(result) = func.results.get(0) { + self.lower(&result.tref, Some(&mut nth)); + } + + let (_params, results) = func.wasm_signature(); + self.emit(&Instruction::Return { amt: results.len() }); + } + + fn emit(&mut self, inst: &Instruction<'_>) { + self.operands.clear(); + self.results.clear(); + + let operands_len = inst.operands_len(); + assert!( + self.stack.len() >= operands_len, + "not enough operands on stack for {:?}", + inst + ); + self.operands + .extend(self.stack.drain((self.stack.len() - operands_len)..)); + self.results.reserve(inst.results_len()); + + self.bindgen + .emit(inst, &mut self.operands, &mut self.results); + + assert_eq!( + self.results.len(), + inst.results_len(), + "{:?} expected {} results, got {}", + inst, + inst.results_len(), + self.results.len() + ); + self.stack.extend(self.results.drain(..)); + } + + fn lower(&mut self, ty: &TypeRef, retptr: Option<&mut usize>) { + use Instruction::*; + match &**ty.type_() { + Type::Builtin(BuiltinType::S8) => self.emit(&I32FromS8), + Type::Builtin(BuiltinType::U8 { lang_c_char: true }) => self.emit(&I32FromChar8), + Type::Builtin(BuiltinType::U8 { lang_c_char: false }) => self.emit(&I32FromU8), + Type::Builtin(BuiltinType::S16) => self.emit(&I32FromS16), + Type::Builtin(BuiltinType::U16) => self.emit(&I32FromU16), + Type::Builtin(BuiltinType::S32) => self.emit(&I32FromS32), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: true, + }) => self.emit(&I32FromUsize), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: false, + }) => self.emit(&I32FromU32), + Type::Builtin(BuiltinType::S64) => self.emit(&I64FromS64), + Type::Builtin(BuiltinType::U64) => self.emit(&I64FromU64), + Type::Builtin(BuiltinType::Char) => self.emit(&I32FromChar), + Type::Pointer(_) => self.emit(&I32FromPointer), + Type::ConstPointer(_) => self.emit(&I32FromConstPointer), + Type::Handle(_) => self.emit(&I32FromHandle { + ty: match ty { + TypeRef::Name(ty) => ty, + _ => unreachable!(), + }, + }), + Type::Record(r) => { + let ty = match ty { + TypeRef::Name(ty) => ty, + _ => unreachable!(), + }; + match r.bitflags_repr() { + Some(IntRepr::U64) => self.emit(&I64FromBitflags { ty }), + Some(_) => self.emit(&I32FromBitflags { ty }), + None => self.emit(&AddrOf), + } + } + Type::Variant(v) => { + // Enum-like variants are simply lowered to their discriminant. + if v.is_enum() { + return self.emit(&EnumLower { + ty: match ty { + TypeRef::Name(n) => n, + _ => unreachable!(), + }, + }); + } + + // If this variant is in the return position then it's special, + // otherwise it's an argument and we just pass the address. + let retptr = match retptr { + Some(ptr) => ptr, + None => return self.emit(&AddrOf), + }; + + // For the return position we emit some blocks to lower the + // ok/err payloads which means that in the ok branch we're + // storing to out-params and in the err branch we're simply + // lowering the error enum. + // + // Note that this is all very specific to the current WASI ABI. + let (ok, err) = v.as_expected().unwrap(); + self.bindgen.push_block(); + if let Some(ok) = ok { + self.emit(&VariantPayload); + let store = |me: &mut Self, ty: &TypeRef, n| { + me.emit(&GetArg { nth: *retptr + n }); + match ty { + TypeRef::Name(ty) => me.emit(&Store { ty }), + _ => unreachable!(), + } + }; + match &**ok.type_() { + Type::Record(r) if r.is_tuple() => { + self.emit(&TupleLower { + amt: r.members.len(), + }); + // Note that `rev()` is used here due to the order + // that tuples are pushed onto the stack and how we + // consume the last item first from the stack. + for (i, member) in r.members.iter().enumerate().rev() { + store(self, &member.tref, i); + } + } + _ => store(self, ok, 0), + } + }; + self.bindgen.finish_block(None); + + self.bindgen.push_block(); + let err_expr = if let Some(ty) = err { + self.emit(&VariantPayload); + self.lower(ty, None); + Some(self.stack.pop().unwrap()) + } else { + None + }; + self.bindgen.finish_block(err_expr); + + self.emit(&ResultLower { ok, err }); + } + Type::Builtin(BuiltinType::F32) => self.emit(&F32FromIf32), + Type::Builtin(BuiltinType::F64) => self.emit(&F64FromIf64), + Type::List(_) => self.emit(&ListPointerLength), + } + } + + fn prep_return_pointer(&mut self, ty: &Type) { + // Return pointers are only needed for `Result`... + let variant = match ty { + Type::Variant(v) => v, + _ => return, + }; + // ... and only if `T` is actually present in `Result` + let ok = match &variant.cases[0].tref { + Some(t) => t, + None => return, + }; + + // Tuples have each individual item in a separate return pointer while + // all other types go through a singular return pointer. + let mut n = 0; + let mut prep = |ty: &TypeRef| { + match ty { + TypeRef::Name(ty) => self.bindgen.allocate_space(n, ty), + _ => unreachable!(), + } + self.emit(&Instruction::ReturnPointerGet { n }); + n += 1; + }; + match &**ok.type_() { + Type::Record(r) if r.is_tuple() => { + for member in r.members.iter() { + prep(&member.tref); + } + } + _ => prep(ok), + } + } + + // Note that in general everything in this function is the opposite of the + // `lower` function above. This is intentional and should be kept this way! + fn lift(&mut self, ty: &TypeRef, is_return: bool) { + use Instruction::*; + match &**ty.type_() { + Type::Builtin(BuiltinType::S8) => self.emit(&S8FromI32), + Type::Builtin(BuiltinType::U8 { lang_c_char: true }) => self.emit(&Char8FromI32), + Type::Builtin(BuiltinType::U8 { lang_c_char: false }) => self.emit(&U8FromI32), + Type::Builtin(BuiltinType::S16) => self.emit(&S16FromI32), + Type::Builtin(BuiltinType::U16) => self.emit(&U16FromI32), + Type::Builtin(BuiltinType::S32) => self.emit(&S32FromI32), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: true, + }) => self.emit(&UsizeFromI32), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: false, + }) => self.emit(&U32FromI32), + Type::Builtin(BuiltinType::S64) => self.emit(&S64FromI64), + Type::Builtin(BuiltinType::U64) => self.emit(&U64FromI64), + Type::Builtin(BuiltinType::Char) => self.emit(&CharFromI32), + Type::Builtin(BuiltinType::F32) => self.emit(&If32FromF32), + Type::Builtin(BuiltinType::F64) => self.emit(&If64FromF64), + Type::Pointer(ty) => self.emit(&PointerFromI32 { ty }), + Type::ConstPointer(ty) => self.emit(&ConstPointerFromI32 { ty }), + Type::Handle(_) => self.emit(&HandleFromI32 { + ty: match ty { + TypeRef::Name(ty) => ty, + _ => unreachable!(), + }, + }), + Type::Variant(v) => { + if v.is_enum() { + return self.emit(&EnumLift { + ty: match ty { + TypeRef::Name(n) => n, + _ => unreachable!(), + }, + }); + } else if !is_return { + return self.emit(&Load { + ty: match ty { + TypeRef::Name(n) => n, + _ => unreachable!(), + }, + }); + } + + let (ok, err) = v.as_expected().unwrap(); + self.bindgen.push_block(); + let ok_expr = if let Some(ok) = ok { + let mut n = 0; + let mut load = |ty: &TypeRef| { + self.emit(&ReturnPointerGet { n }); + n += 1; + match ty { + TypeRef::Name(ty) => self.emit(&Load { ty }), + _ => unreachable!(), + } + }; + match &**ok.type_() { + Type::Record(r) if r.is_tuple() => { + for member in r.members.iter() { + load(&member.tref); + } + self.emit(&TupleLift { + amt: r.members.len(), + }); + } + _ => load(ok), + } + Some(self.stack.pop().unwrap()) + } else { + None + }; + self.bindgen.finish_block(ok_expr); + + self.bindgen.push_block(); + let err_expr = if let Some(ty) = err { + self.emit(&ReuseReturn); + self.lift(ty, false); + Some(self.stack.pop().unwrap()) + } else { + None + }; + self.bindgen.finish_block(err_expr); + + self.emit(&ResultLift); + } + Type::Record(r) => { + let ty = match ty { + TypeRef::Name(ty) => ty, + _ => unreachable!(), + }; + match r.bitflags_repr() { + Some(IntRepr::U64) => self.emit(&BitflagsFromI64 { ty }), + Some(_) => self.emit(&BitflagsFromI32 { ty }), + None => self.emit(&Load { ty }), + } + } + Type::List(ty) => self.emit(&ListFromPointerLength { ty }), + } + } +} diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs index 7d34b5f7f..ee985d302 100644 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ b/proposals/filesystem/tools/witx/src/ast.rs @@ -1,4 +1,4 @@ -#![allow(dead_code)] +use crate::Abi; use std::collections::{HashMap, HashSet}; use std::rc::{Rc, Weak}; @@ -63,13 +63,27 @@ impl Document { _ => None, }) } - /// All of the (unique) types used as the first result value of a function. + /// All of the (unique) types used as "err" variant of results returned from + /// functions. pub fn error_types<'a>(&'a self) -> impl Iterator + 'a { let errors: HashSet = self .modules() .flat_map(|m| { m.funcs() - .filter_map(|f| f.results.get(0).as_ref().map(|r| r.tref.clone())) + .filter_map(|f| { + if f.results.len() == 1 { + Some(f.results[0].tref.type_().clone()) + } else { + None + } + }) + .filter_map(|t| match &*t { + Type::Variant(v) => { + let (_ok, err) = v.as_expected()?; + Some(err?.clone()) + } + _ => None, + }) .collect::>() }) .collect(); @@ -162,10 +176,17 @@ pub enum TypeRef { } impl TypeRef { - pub fn type_(&self) -> Rc { + pub fn type_(&self) -> &Rc { match self { TypeRef::Name(named) => named.type_(), - TypeRef::Value(ref v) => v.clone(), + TypeRef::Value(v) => v, + } + } + + pub fn named(&self) -> bool { + match self { + TypeRef::Name(_) => true, + TypeRef::Value(_) => false, } } } @@ -178,23 +199,42 @@ pub struct NamedType { } impl NamedType { - pub fn type_(&self) -> Rc { + pub fn type_(&self) -> &Rc { self.tref.type_() } } +/// Structure of all possible interface types. +/// +/// Note that this is intended to match the interface types proposal itself. +/// Currently this is relatively close to that with just a few `*.witx` +/// extensions for now. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { + /// A structure with named field. Record(RecordDatatype), + /// An enumeration where a value is one of a number of variants. Variant(Variant), + /// A "handle" which is an un-forgeable reference. Today this is an `i32` + /// where a module can't forge and use integers it was not already given + /// access to. Handle(HandleDatatype), + /// A list of a type, stored in linear memory. + /// + /// Note that lists of `char` are specialized to indicate strings. List(TypeRef), + /// A `witx`-specific type representing a raw mutable pointer into linear + /// memory Pointer(TypeRef), + /// A `witx`-specific type representing a raw const pointer into linear + /// memory ConstPointer(TypeRef), + /// A builtin base-case type. Builtin(BuiltinType), } impl Type { + /// Returns a human-readable string to describe this type. pub fn kind(&self) -> &'static str { use Type::*; match self { @@ -215,6 +255,7 @@ pub enum BuiltinType { /// /// Same as the Rust language's `char` type. Char, + /// An 8-bit unsigned integer. U8 { /// Indicates whether this type is intended to represent the `char` /// type in the C language. The C `char` type is often unsigned, but @@ -226,7 +267,9 @@ pub enum BuiltinType { /// pointer` to hint that it's pointing to unicode string data as well. lang_c_char: bool, }, + /// A 16-bit unsigned integer. U16, + /// A 32-bit unsigned integer. U32 { /// Indicates that this 32-bit value should actually be considered a /// pointer-like value in language bindings. At the interface types @@ -238,12 +281,19 @@ pub enum BuiltinType { /// argument or return-value is pointer-like. lang_ptr_size: bool, }, + /// A 64-bit unsigned integer. U64, + /// An 8-bit signed integer S8, + /// A 16-bit signed integer S16, + /// A 32-bit signed integer S32, + /// A 64-bit signed integer S64, + /// A 32-bit floating point value. F32, + /// A 64-bit floating point value. F64, } @@ -268,11 +318,37 @@ impl IntRepr { } } +/// A struct-like value with named fields. +/// +/// Records map to `struct`s in most languages where this is a type with a +/// number of named fields that all have their own particular type. Field order +/// dictates layout in memory. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct RecordDatatype { + /// A hint as to what this record might be. + /// + /// Note that in the future this will only be a hint, not a control of the + /// actual representation itself. At this time though the record layout of + /// bitflags is different from other types. + pub kind: RecordKind, + + /// A list of named fields for this record. pub members: Vec, } +/// Different kinds of records used for hinting various language-specific types. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum RecordKind { + /// A tuple where the name of all fields are consecutive integers starting + /// at "0". + Tuple, + /// A record where all fields are `bool`s. Currently represented as an + /// integer with bits set or not set. + Bitflags(IntRepr), + /// All other structures. + Other, +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct RecordMember { pub name: Id, @@ -280,16 +356,98 @@ pub struct RecordMember { pub docs: String, } +impl RecordDatatype { + pub fn is_tuple(&self) -> bool { + match self.kind { + RecordKind::Tuple => true, + _ => false, + } + } + + pub fn bitflags_repr(&self) -> Option { + match self.kind { + RecordKind::Bitflags(i) => Some(i), + _ => None, + } + } +} + +/// A type which represents how values can be one of a set of possible cases. +/// +/// This type maps to an `enum` in languages like Rust, but doesn't have an +/// equivalent in languages like JS or C. The closest analog in C is a tagged +/// union, but a `Variant` is always consistent whereas a tagged union in C +/// could be mis-tagged or such. +/// +/// Variants are used to represent one of a possible set of types. For example +/// an enum-like variant, a result that is either success or failure, or even a +/// simple `bool`. Variants are primarily used heavily with various kinds of +/// shorthands in the `*.witx` format to represent idioms in languages. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Variant { + /// The bit representation of the width of this variant's tag when the + /// variant is stored in memory. pub tag_repr: IntRepr, + /// The possible cases that values of this variant type can take. pub cases: Vec, } +impl Variant { + /// If this variant looks like an `expected` shorthand, return the ok/err + /// types associated with this result. + /// + /// Only matches variants fo the form: + /// + /// ```text + /// (variant + /// (case "ok" ok?) + /// (case "err" err?)) + /// ``` + pub fn as_expected(&self) -> Option<(Option<&TypeRef>, Option<&TypeRef>)> { + if self.cases.len() != 2 { + return None; + } + if self.cases[0].name != "ok" { + return None; + } + if self.cases[1].name != "err" { + return None; + } + Some((self.cases[0].tref.as_ref(), self.cases[1].tref.as_ref())) + } + + /// Returns whether this variant type is "bool-like" meaning that it matches + /// this type: + /// + /// ```text + /// (variant + /// (case "false") + /// (case "true")) + /// ``` + pub fn is_bool(&self) -> bool { + self.cases.len() == 2 + && self.cases[0].name == "false" + && self.cases[1].name == "true" + && self.cases[0].tref.is_none() + && self.cases[1].tref.is_none() + } + + /// Returns whether this variant type is "enum-like" meaning that all of its + /// cases have no payload associated with them. + pub fn is_enum(&self) -> bool { + self.cases.iter().all(|c| c.tref.is_none()) + } +} + +/// One of a number of possible types that a `Variant` can take. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Case { + /// The name of this case and how to identify it. pub name: Id, + /// An optional payload type for this case and data that can be associated + /// with it. pub tref: Option, + /// Documentation for this case. pub docs: String, } @@ -409,6 +567,7 @@ pub enum ModuleImportVariant { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct InterfaceFunc { + pub abi: Abi, pub name: Id, pub params: Vec, pub results: Vec, @@ -420,16 +579,9 @@ pub struct InterfaceFunc { pub struct InterfaceFuncParam { pub name: Id, pub tref: TypeRef, - pub position: InterfaceFuncParamPosition, pub docs: String, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum InterfaceFuncParamPosition { - Param(usize), - Result(usize), -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Constant { pub ty: Id, diff --git a/proposals/filesystem/tools/witx/src/coretypes.rs b/proposals/filesystem/tools/witx/src/coretypes.rs deleted file mode 100644 index 826990369..000000000 --- a/proposals/filesystem/tools/witx/src/coretypes.rs +++ /dev/null @@ -1,173 +0,0 @@ -use crate::{BuiltinType, IntRepr, InterfaceFunc, InterfaceFuncParam, Type}; - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -/// Enumerates the types permitted for function arguments in the WebAssembly spec -pub enum AtomType { - I32, - I64, - F32, - F64, -} - -impl From for AtomType { - fn from(i: IntRepr) -> AtomType { - match i { - IntRepr::U8 | IntRepr::U16 | IntRepr::U32 => AtomType::I32, - IntRepr::U64 => AtomType::I64, - } - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -/// Enumerates the strategies which may be used to pass a datatype as an argument -pub enum TypePassedBy { - /// Pass by value specifies the AtomType used to represent that value - Value(AtomType), - /// Pass by a pointer into linear memory - Pointer, - /// Pass by a pointer and length pair, into linear memory - PointerLengthPair, -} - -impl Type { - /// Determine the simplest strategy by which a type may be passed. Value always preferred over - /// Pointer. - pub fn passed_by(&self) -> TypePassedBy { - match self { - Type::Builtin(b) => match b { - BuiltinType::U8 { .. } - | BuiltinType::U16 - | BuiltinType::U32 { .. } - | BuiltinType::S8 - | BuiltinType::S16 - | BuiltinType::S32 - | BuiltinType::Char => TypePassedBy::Value(AtomType::I32), - BuiltinType::U64 | BuiltinType::S64 => TypePassedBy::Value(AtomType::I64), - BuiltinType::F32 => TypePassedBy::Value(AtomType::F32), - BuiltinType::F64 => TypePassedBy::Value(AtomType::F64), - }, - Type::List { .. } => TypePassedBy::PointerLengthPair, - Type::Pointer { .. } | Type::ConstPointer { .. } => TypePassedBy::Value(AtomType::I32), - Type::Record { .. } => TypePassedBy::Pointer, - Type::Variant(v) => { - if v.cases.iter().all(|c| c.tref.is_none()) { - TypePassedBy::Value(v.tag_repr.into()) - } else { - TypePassedBy::Pointer - } - } - Type::Handle { .. } => TypePassedBy::Value(AtomType::I32), - } - } -} - -/// A parameter in the WebAssembly type of a function. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CoreParamType { - /// The interface function parameter to which this - pub param: InterfaceFuncParam, - /// The relationship of the WebAssembly parameter to the function interface parameter - pub signifies: CoreParamSignifies, -} - -impl CoreParamType { - /// Representation of the WebAssembly parameter. This is the type that will appear - /// in the function's WebAssembly type signature. - pub fn repr(&self) -> AtomType { - self.signifies.repr() - } -} - -/// Enumerates the sort of relationship an WebAssembly parameter to an interface function -/// parameter. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum CoreParamSignifies { - /// Core type represents the value using an AtomType - Value(AtomType), - /// Core type represents a pointer into linear memory - PointerTo, - /// Core type represents a length of a region of linear memory - LengthOf, -} - -impl CoreParamSignifies { - /// Representation of the WebAssembly parameter. - pub fn repr(&self) -> AtomType { - match self { - CoreParamSignifies::Value(a) => *a, - CoreParamSignifies::PointerTo | CoreParamSignifies::LengthOf => AtomType::I32, - } - } -} - -impl InterfaceFuncParam { - /// Gives the WebAssembly type that corresponds to passing this interface func parameter by value. - /// Not all types can be passed by value: those which cannot return None - pub fn pass_by_value(&self) -> Option { - match self.tref.type_().passed_by() { - TypePassedBy::Value(atom) => Some(CoreParamType { - signifies: CoreParamSignifies::Value(atom), - param: self.clone(), - }), - TypePassedBy::Pointer | TypePassedBy::PointerLengthPair => None, - } - } - - /// Gives the WebAssembly types that correspond to passing this interface func parameter - /// by reference. Some types are passed by reference using a single pointer, others - /// require both a pointer and length. - pub fn pass_by_reference(&self) -> Vec { - match self.tref.type_().passed_by() { - TypePassedBy::Value(_) | TypePassedBy::Pointer => vec![CoreParamType { - signifies: CoreParamSignifies::PointerTo, - param: self.clone(), - }], - TypePassedBy::PointerLengthPair => vec![ - CoreParamType { - signifies: CoreParamSignifies::PointerTo, - param: self.clone(), - }, - CoreParamType { - signifies: CoreParamSignifies::LengthOf, - param: self.clone(), - }, - ], - } - } -} - -/// Describes the WebAssembly signature of a function -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CoreFuncType { - pub args: Vec, - pub ret: Option, -} - -impl InterfaceFunc { - /// Get the WebAssembly type signature for this interface function - pub fn core_type(&self) -> CoreFuncType { - let mut results = self.results.iter(); - // The ret value is the first result (if there is one), passed - // by value. - let ret = results.next().map(|param| { - param - .pass_by_value() - .expect("validation ensures first result can be passed by value") - }); - let args = self - .params - .iter() - .flat_map(|param| { - // interface function parameters are passed by value if possible, - // and fall back on passing by reference. - param - .pass_by_value() - .map(|ptype| vec![ptype]) - .unwrap_or_else(|| param.pass_by_reference()) - }) - // Then, the remaining results are passed by reference. - .chain(results.flat_map(|param| param.pass_by_reference())) - .collect(); - CoreFuncType { args, ret } - } -} diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs index 6048f73a1..a295a6756 100644 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ b/proposals/filesystem/tools/witx/src/docs/ast.rs @@ -1,5 +1,5 @@ use super::{ - md::{MdFunc, MdHeading, MdNamedType, MdNodeRef, MdSection, MdType, ToMarkdown}, + md::{MdFunc, MdHeading, MdNamedType, MdNodeRef, MdSection, ToMarkdown}, Documentation, }; use crate::{ @@ -68,11 +68,13 @@ impl ToMarkdown for Document { impl ToMarkdown for TypeRef { fn generate(&self, node: MdNodeRef) { match self { - TypeRef::Value(v) => v.generate(node.clone()), + TypeRef::Value(v) => { + v.generate(node.clone()); + node.content_ref_mut::().ty = Some(format!("`{}`", self.type_name())); + } TypeRef::Name(n) => { - node.content_ref_mut::().r#type = Some(MdType::Alias { - r#type: n.name.as_str().to_owned(), - }) + node.content_ref_mut::().ty = + Some(format!("[`{0}`](#{0})", n.name.as_str().to_owned())); } } } @@ -90,26 +92,10 @@ impl ToMarkdown for Type { Self::Record(a) => a.generate(node.clone()), Self::Variant(a) => a.generate(node.clone()), Self::Handle(a) => a.generate(node.clone()), - Self::List(a) => { - node.content_ref_mut::().r#type = Some(MdType::List { - r#type: a.type_name().to_owned(), - }) - } - Self::Pointer(a) => { - node.content_ref_mut::().r#type = Some(MdType::Pointer { - r#type: a.type_name().to_owned(), - }) - } - Self::ConstPointer(a) => { - node.content_ref_mut::().r#type = Some(MdType::ConstPointer { - r#type: a.type_name().to_owned(), - }) - } - Self::Builtin(a) => { - node.content_ref_mut::().r#type = Some(MdType::Builtin { - repr: a.type_name().to_owned(), - }) - } + Self::List(_) => {} + Self::Pointer(_) => {} + Self::ConstPointer(_) => {} + Self::Builtin(_) => {} } } } @@ -128,21 +114,27 @@ impl ToMarkdown for RecordDatatype { } else { name.to_owned() }; + let (div, offset_desc) = if self.bitflags_repr().is_some() { + (4, "Bit") + } else { + (1, "Offset") + }; let n = node.new_child(MdNamedType::new( MdHeading::new_bullet(), id.as_str(), name, - format!("{}\nOffset: {}\n", &member.docs, &offset).as_str(), + format!("{}\n{}: {}\n", &member.docs, offset_desc, offset / div).as_str(), )); member.tref.generate(n.clone()); } - - node.content_ref_mut::().r#type = Some(MdType::Record); } } impl ToMarkdown for Variant { fn generate(&self, node: MdNodeRef) { + if self.is_bool() { + return; + } if self.cases.iter().any(|c| c.tref.is_some()) { let heading = heading_from_node(&node, 1); node.new_child(MdSection::new(heading, "Variant Layout")); @@ -184,8 +176,6 @@ impl ToMarkdown for Variant { ty.generate(n.clone()); } } - - node.content_ref_mut::().r#type = Some(MdType::Variant); } } @@ -194,7 +184,6 @@ impl ToMarkdown for HandleDatatype { // TODO this needs more work let heading = heading_from_node(&node, 1); node.new_child(MdSection::new(heading, "Supertypes")); - node.content_ref_mut::().r#type = Some(MdType::Handle); } } @@ -312,16 +301,50 @@ impl TypeRef { pub fn type_name(&self) -> String { match self { TypeRef::Name(n) => n.name.as_str().to_string(), - TypeRef::Value(ref v) => match &**v { - Type::List(a) => match &*a.type_() { + TypeRef::Value(v) => match &**v { + Type::List(a) => match &**a.type_() { Type::Builtin(BuiltinType::Char) => "string".to_string(), _ => format!("List<{}>", a.type_name()), }, Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), Type::Builtin(b) => b.type_name().to_string(), - Type::Record { .. } | Type::Variant { .. } | Type::Handle { .. } => { - unimplemented!("type_name of anonymous compound datatypes") + Type::Record(RecordDatatype { + kind: RecordKind::Tuple, + members, + }) => { + let mut ret = "(".to_string(); + for (i, member) in members.iter().enumerate() { + if i > 0 { + ret.push_str(", "); + } + ret.push_str(&member.tref.type_name()); + } + ret.push_str(")"); + ret + } + Type::Record { .. } => { + format!("Record") + } + Type::Handle { .. } => { + format!("Handle") + } + Type::Variant(v) => { + if let Some((ok, err)) = v.as_expected() { + let ok = match ok { + Some(ty) => ty.type_name(), + None => "()".to_string(), + }; + let err = match err { + Some(ty) => ty.type_name(), + None => "()".to_string(), + }; + format!("Result<{}, {}>", ok, err) + } else if v.is_bool() { + format!("bool") + } else { + format!("Variant") + } } }, } diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs index d3d5b756d..569b31837 100644 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ b/proposals/filesystem/tools/witx/src/docs/md.rs @@ -322,7 +322,7 @@ pub(super) struct MdNamedType { pub id: String, pub name: String, pub docs: String, - pub r#type: Option, + pub ty: Option, } impl MdNamedType { @@ -332,54 +332,11 @@ impl MdNamedType { id: id.as_ref().to_owned(), name: name.as_ref().to_owned(), docs: docs.as_ref().to_owned(), - r#type: None, + ty: None, } } } -/// Helper struct encapsulating the `TypeRef` value. -// TODO `MdType` should probably store `TypeRef` and recursively -// unwind itself into final `String` representation rather than -// being outright flattened. -#[derive(Debug)] -pub(super) enum MdType { - Record, - Variant, - List { r#type: String }, - Pointer { r#type: String }, - ConstPointer { r#type: String }, - Builtin { repr: String }, - Handle, - Alias { r#type: String }, -} - -impl fmt::Display for MdType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Record => f.write_fmt(format_args!(": Record"))?, - Self::Variant => f.write_fmt(format_args!(": Variant"))?, - Self::List { r#type } => { - if r#type == "char" { - f.write_str(": `string`")? - } else { - f.write_fmt(format_args!(": `List<{}>`", r#type))? - } - } - Self::Pointer { r#type } => f.write_fmt(format_args!(": `Pointer<{}>`", r#type))?, - Self::ConstPointer { r#type } => { - f.write_fmt(format_args!(": `ConstPointer<{}>`", r#type))? - } - Self::Builtin { repr } => f.write_fmt(format_args!(": `{}`", repr))?, - Self::Handle => {} - Self::Alias { r#type } => { - f.write_fmt(format_args!(": [`{tt}`](#{tt})", tt = r#type))? - } - }; - - Ok(()) - } -} - impl MdElement for MdNamedType { fn id(&self) -> Option<&str> { Some(&self.id) @@ -411,8 +368,8 @@ impl fmt::Display for MdNamedType { name = self.name, ))?; - if let Some(tt) = &self.r#type { - f.write_fmt(format_args!("{}", tt))?; + if let Some(tt) = &self.ty { + f.write_fmt(format_args!(": {}", tt))?; } writeln!(f, "\n{}", self.docs) diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs index 2bcd1042a..6812f01ae 100644 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ b/proposals/filesystem/tools/witx/src/layout.rs @@ -64,7 +64,10 @@ impl Layout for NamedType { impl Type { fn layout(&self, cache: &mut HashMap) -> SizeAlign { match &self { - Type::Record(s) => s.layout(cache), + Type::Record(s) => match s.bitflags_repr() { + Some(repr) => repr.mem_size_align(), + None => s.layout(cache), + }, Type::Variant(s) => s.mem_size_align(), Type::Handle(h) => h.mem_size_align(), Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length @@ -122,8 +125,13 @@ impl RecordDatatype { impl Layout for RecordDatatype { fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) + match self.bitflags_repr() { + Some(repr) => repr.mem_size_align(), + None => { + let mut cache = HashMap::new(); + self.layout(&mut cache) + } + } } } @@ -143,6 +151,18 @@ impl Layout for Variant { } } +impl Variant { + pub fn payload_offset(&self) -> usize { + let mut offset = self.tag_repr.mem_size_align().size; + for case in self.cases.iter() { + if let Some(payload) = &case.tref { + offset = offset.max(align_to(offset, payload.mem_size_align().align)); + } + } + offset + } +} + /// If the next free byte in the struct is `offs`, and the next /// element has alignment `alignment`, determine the offset at /// which to place that element. diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index 2c876aa13..f1cc7e229 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -1,7 +1,7 @@ +/// Map witx types to core (wasm standard) types +mod abi; /// Types describing a validated witx document mod ast; -/// Map witx types to core (wasm standard) types -mod coretypes; /// Render documentation mod docs; /// Interface for filesystem or mock IO @@ -23,8 +23,8 @@ mod toplevel; /// Validate declarations into ast mod validate; +pub use abi::*; pub use ast::*; -pub use coretypes::{AtomType, CoreFuncType, CoreParamSignifies, CoreParamType, TypePassedBy}; pub use docs::Documentation; pub use io::{Filesystem, MockFs, WitxIo}; pub use layout::{Layout, RecordMemberLayout, SizeAlign}; diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs index 19d1a0303..33cf745ff 100644 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ b/proposals/filesystem/tools/witx/src/parser.rs @@ -1,5 +1,4 @@ use crate::BuiltinType; -use wast::lexer::Comment; use wast::parser::{Parse, Parser, Peek, Result}; ///! Parser turns s-expressions into unvalidated syntax constructs. @@ -18,7 +17,6 @@ use wast::parser::{Parse, Parser, Peek, Result}; mod kw { pub use wast::kw::{export, func, import, memory, module, param, result}; - wast::custom_keyword!(bitflags); wast::custom_keyword!(case); wast::custom_keyword!(char8); wast::custom_keyword!(char); @@ -27,6 +25,8 @@ mod kw { wast::custom_keyword!(f64); wast::custom_keyword!(field); wast::custom_keyword!(empty); + wast::custom_keyword!(error); + wast::custom_keyword!(expected); wast::custom_keyword!(flags); wast::custom_keyword!(handle); wast::custom_keyword!(list); @@ -37,12 +37,14 @@ mod kw { wast::custom_keyword!(r#enum = "enum"); wast::custom_keyword!(r#union = "union"); wast::custom_keyword!(r#use = "use"); + wast::custom_keyword!(repr); wast::custom_keyword!(s16); wast::custom_keyword!(s32); wast::custom_keyword!(s64); wast::custom_keyword!(s8); wast::custom_keyword!(string); wast::custom_keyword!(tag); + wast::custom_keyword!(tuple); wast::custom_keyword!(typename); wast::custom_keyword!(u16); wast::custom_keyword!(u32); @@ -50,6 +52,7 @@ mod kw { wast::custom_keyword!(u8); wast::custom_keyword!(usize); wast::custom_keyword!(variant); + wast::custom_keyword!(bool_ = "bool"); } mod annotation { @@ -136,9 +139,10 @@ impl<'a> Parse<'a> for CommentSyntax<'a> { None => break, }; cursor = c; - comments.push(match comment { - Comment::Block(s) => &s[2..s.len() - 2], - Comment::Line(s) => &s[2..], + comments.push(if comment.starts_with(";;") { + &comment[2..] + } else { + &comment[2..comment.len() - 2] }); } Ok((comments, cursor)) @@ -277,6 +281,8 @@ impl<'a> Parse<'a> for TypenameSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub enum TypedefSyntax<'a> { Enum(EnumSyntax<'a>), + Tuple(TupleSyntax<'a>), + Expected(ExpectedSyntax<'a>), Flags(FlagsSyntax<'a>), Record(RecordSyntax<'a>), Union(UnionSyntax<'a>), @@ -288,6 +294,7 @@ pub enum TypedefSyntax<'a> { Builtin(BuiltinType), Ident(wast::Id<'a>), String, + Bool, } impl<'a> Parse<'a> for TypedefSyntax<'a> { @@ -300,11 +307,18 @@ impl<'a> Parse<'a> for TypedefSyntax<'a> { } else if l.peek::() { parser.parse::()?; Ok(TypedefSyntax::String) + } else if l.peek::() { + parser.parse::()?; + Ok(TypedefSyntax::Bool) } else if l.peek::() { parser.parens(|parser| { let mut l = parser.lookahead1(); if l.peek::() { Ok(TypedefSyntax::Enum(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Tuple(parser.parse()?)) + } else if l.peek::() { + Ok(TypedefSyntax::Expected(parser.parse()?)) } else if l.peek::() { Ok(TypedefSyntax::Flags(parser.parse()?)) } else if l.peek::() { @@ -377,6 +391,48 @@ impl<'a> Parse<'a> for EnumSyntax<'a> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TupleSyntax<'a> { + pub types: Vec>, +} + +impl<'a> Parse<'a> for TupleSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let mut types = Vec::new(); + while !parser.is_empty() { + types.push(parser.parse()?); + } + Ok(TupleSyntax { types }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ExpectedSyntax<'a> { + pub ok: Option>>, + pub err: Option>>, +} + +impl<'a> Parse<'a> for ExpectedSyntax<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let ok = if !parser.is_empty() && !parser.peek2::() { + Some(Box::new(parser.parse()?)) + } else { + None + }; + let err = parser.parens(|p| { + p.parse::()?; + Ok(if p.is_empty() { + None + } else { + Some(Box::new(p.parse()?)) + }) + })?; + Ok(ExpectedSyntax { ok, err }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConstSyntax<'a> { pub ty: wast::Id<'a>, @@ -397,17 +453,17 @@ impl<'a> Parse<'a> for ConstSyntax<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct FlagsSyntax<'a> { - pub bitflags_repr: Option, + pub repr: Option, pub flags: Vec>>, } impl<'a> Parse<'a> for FlagsSyntax<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; - let bitflags_repr = if parser.peek2::() { + let repr = if parser.peek2::() { Some(parser.parens(|p| { p.parse::()?; - p.parse::()?; + p.parse::()?; p.parse() })?) } else { @@ -417,10 +473,7 @@ impl<'a> Parse<'a> for FlagsSyntax<'a> { while !parser.is_empty() { flags.push(parser.parse()?); } - Ok(FlagsSyntax { - bitflags_repr, - flags, - }) + Ok(FlagsSyntax { repr, flags }) } } diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs index ad551ae9b..a740e282c 100644 --- a/proposals/filesystem/tools/witx/src/render.rs +++ b/proposals/filesystem/tools/witx/src/render.rs @@ -143,29 +143,56 @@ impl Type { impl RecordDatatype { pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("record")]; - let members = self - .members - .iter() - .map(|m| { - SExpr::docs( - &m.docs, - SExpr::Vec(vec![ - SExpr::word("field"), - m.name.to_sexpr(), - m.tref.to_sexpr(), - ]), - ) - }) - .collect::>(); - SExpr::Vec([header, members].concat()) + match self.kind { + RecordKind::Tuple => { + let mut tuple = vec![SExpr::word("tuple")]; + for m in self.members.iter() { + tuple.push(SExpr::docs(&m.docs, m.tref.to_sexpr())); + } + SExpr::Vec(tuple) + } + RecordKind::Bitflags(repr) => { + let mut flags = vec![SExpr::word("flags")]; + flags.push(SExpr::Vec(vec![ + SExpr::word("@witx"), + SExpr::word("repr"), + repr.to_sexpr(), + ])); + flags.extend( + self.members + .iter() + .map(|m| SExpr::docs(&m.docs, m.name.to_sexpr())), + ); + SExpr::Vec(flags) + } + RecordKind::Other => { + let header = vec![SExpr::word("record")]; + let members = self + .members + .iter() + .map(|m| { + SExpr::docs( + &m.docs, + SExpr::Vec(vec![ + SExpr::word("field"), + m.name.to_sexpr(), + m.tref.to_sexpr(), + ]), + ) + }) + .collect::>(); + SExpr::Vec([header, members].concat()) + } + } } } impl Variant { pub fn to_sexpr(&self) -> SExpr { let mut list = Vec::new(); - if self.cases.iter().all(|c| c.tref.is_none()) { + if self.is_bool() { + return SExpr::word("bool"); + } else if self.is_enum() { list.push(SExpr::word("enum")); list.push(SExpr::Vec(vec![ SExpr::word("@witx"), diff --git a/proposals/filesystem/tools/witx/src/toplevel.rs b/proposals/filesystem/tools/witx/src/toplevel.rs index 83e940c7c..257e6edd8 100644 --- a/proposals/filesystem/tools/witx/src/toplevel.rs +++ b/proposals/filesystem/tools/witx/src/toplevel.rs @@ -107,11 +107,11 @@ mod test { .expect("parse"); let b_float = doc.typename(&Id::new("b_float")).unwrap(); - assert_eq!(*b_float.type_(), Type::Builtin(BuiltinType::F64)); + assert_eq!(**b_float.type_(), Type::Builtin(BuiltinType::F64)); let c_int = doc.typename(&Id::new("c_int")).unwrap(); assert_eq!( - *c_int.type_(), + **c_int.type_(), Type::Builtin(BuiltinType::U32 { lang_ptr_size: false }) @@ -133,7 +133,7 @@ mod test { let d_char = doc.typename(&Id::new("d_char")).unwrap(); assert_eq!( - *d_char.type_(), + **d_char.type_(), Type::Builtin(BuiltinType::U8 { lang_c_char: false }) ); } diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs index ade02282b..cf4d0ad7f 100644 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ b/proposals/filesystem/tools/witx/src/validate.rs @@ -1,14 +1,14 @@ use crate::{ io::{Filesystem, WitxIo}, parser::{ - CommentSyntax, DeclSyntax, Documented, EnumSyntax, FlagsSyntax, HandleSyntax, - ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TypedefSyntax, UnionSyntax, - VariantSyntax, + CommentSyntax, DeclSyntax, Documented, EnumSyntax, ExpectedSyntax, FlagsSyntax, + HandleSyntax, ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TupleSyntax, TypedefSyntax, + UnionSyntax, VariantSyntax, }, - BuiltinType, Case, Constant, Definition, Document, Entry, HandleDatatype, Id, IntRepr, - InterfaceFunc, InterfaceFuncParam, InterfaceFuncParamPosition, Location, Module, - ModuleDefinition, ModuleEntry, ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, - RecordMember, Type, TypePassedBy, TypeRef, Variant, + Abi, BuiltinType, Case, Constant, Definition, Document, Entry, HandleDatatype, Id, IntRepr, + InterfaceFunc, InterfaceFuncParam, Location, Module, ModuleDefinition, ModuleEntry, + ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordKind, RecordMember, Type, + TypeRef, Variant, }; use std::collections::{HashMap, HashSet}; use std::path::Path; @@ -39,8 +39,8 @@ pub enum ValidationError { repr: BuiltinType, location: Location, }, - #[error("First result type must be pass-by-value")] - InvalidFirstResultType { location: Location }, + #[error("ABI error: {reason}")] + Abi { reason: String, location: Location }, #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] AnonymousRecord { location: Location }, #[error("Union expected {expected} variants, found {found}")] @@ -67,7 +67,7 @@ impl ValidationError { | WrongKindName { location, .. } | Recursive { location, .. } | InvalidRepr { location, .. } - | InvalidFirstResultType { location, .. } + | Abi { location, .. } | AnonymousRecord { location, .. } | UnionSizeMismatch { location, .. } | InvalidUnionField { location, .. } @@ -131,6 +131,7 @@ pub struct DocValidation { scope: IdentValidation, entries: HashMap, constant_scopes: HashMap, + bool_ty: TypeRef, } pub struct DocValidationScope<'a> { @@ -145,6 +146,21 @@ impl DocValidation { scope: IdentValidation::new(), entries: HashMap::new(), constant_scopes: HashMap::new(), + bool_ty: TypeRef::Value(Rc::new(Type::Variant(Variant { + tag_repr: IntRepr::U32, + cases: vec![ + Case { + name: Id::new("false"), + tref: None, + docs: String::new(), + }, + Case { + name: Id::new("true"), + tref: None, + docs: String::new(), + }, + ], + }))), } } @@ -203,24 +219,6 @@ impl DocValidationScope<'_> { .entries .insert(name.clone(), Entry::Typename(Rc::downgrade(&rc_datatype))); definitions.push(Definition::Typename(rc_datatype)); - - if let TypedefSyntax::Flags(syntax) = &decl.def { - if syntax.bitflags_repr.is_some() { - let mut flags_scope = IdentValidation::new(); - let ty = name; - for (i, flag) in syntax.flags.iter().enumerate() { - let name = flags_scope - .introduce(flag.item.name(), self.location(flag.item.span()))?; - let docs = flag.comments.docs(); - definitions.push(Definition::Constant(Constant { - ty: ty.clone(), - name, - value: 1 << i, - docs, - })); - } - } - } } DeclSyntax::Module(syntax) => { @@ -304,7 +302,11 @@ impl DocValidationScope<'_> { } other => Ok(TypeRef::Value(Rc::new(match other { TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), - TypedefSyntax::Flags(syntax) => self.validate_flags(&syntax, span)?, + TypedefSyntax::Tuple(syntax) => Type::Record(self.validate_tuple(&syntax, span)?), + TypedefSyntax::Expected(syntax) => { + Type::Variant(self.validate_expected(&syntax, span)?) + } + TypedefSyntax::Flags(syntax) => Type::Record(self.validate_flags(&syntax, span)?), TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), TypedefSyntax::Union(syntax) => Type::Variant(self.validate_union(&syntax, span)?), TypedefSyntax::Variant(syntax) => { @@ -324,6 +326,7 @@ impl DocValidationScope<'_> { TypedefSyntax::String => { Type::List(TypeRef::Value(Rc::new(Type::Builtin(BuiltinType::Char)))) } + TypedefSyntax::Bool => return Ok(self.doc.bool_ty.clone()), TypedefSyntax::Ident { .. } => unreachable!(), }))), } @@ -356,17 +359,83 @@ impl DocValidationScope<'_> { Ok(Variant { tag_repr, cases }) } + fn validate_tuple( + &self, + syntax: &TupleSyntax, + span: wast::Span, + ) -> Result { + let members = syntax + .types + .iter() + .enumerate() + .map(|(i, ty)| { + Ok(RecordMember { + name: Id::new(i.to_string()), + tref: self.validate_datatype(ty, false, span)?, + docs: String::new(), + }) + }) + .collect::, _>>()?; + + Ok(RecordDatatype { + kind: RecordKind::Tuple, + members, + }) + } + + fn validate_expected( + &self, + syntax: &ExpectedSyntax, + span: wast::Span, + ) -> Result { + let ok_ty = match &syntax.ok { + Some(ok) => Some(self.validate_datatype(ok, false, span)?), + None => None, + }; + let err_ty = match &syntax.err { + Some(err) => Some(self.validate_datatype(err, false, span)?), + None => None, + }; + Ok(Variant { + tag_repr: IntRepr::U32, + cases: vec![ + Case { + name: Id::new("ok"), + tref: ok_ty, + docs: String::new(), + }, + Case { + name: Id::new("err"), + tref: err_ty, + docs: String::new(), + }, + ], + }) + } + fn validate_flags( &self, syntax: &FlagsSyntax, span: wast::Span, - ) -> Result { - Ok(match &syntax.bitflags_repr { - Some(repr) => Type::Builtin(self.validate_int_repr(repr, span)?.to_builtin()), - None => { - // TODO: auto-translate to a struct-of-bool-fields - unimplemented!(); - } + ) -> Result { + let repr = match syntax.repr { + Some(ty) => self.validate_int_repr(&ty, span)?, + None => IntRepr::U32, + }; + let mut flags_scope = IdentValidation::new(); + let mut members = Vec::new(); + for flag in syntax.flags.iter() { + let name = flags_scope.introduce(flag.item.name(), self.location(flag.item.span()))?; + let docs = flag.comments.docs(); + members.push(RecordMember { + name, + docs, + tref: self.doc.bool_ty.clone(), + }); + } + Ok(RecordDatatype { + kind: RecordKind::Bitflags(repr), + members, }) } @@ -388,7 +457,10 @@ impl DocValidationScope<'_> { }) .collect::, _>>()?; - Ok(RecordDatatype { members }) + Ok(RecordDatatype { + kind: RecordKind::Other, + members, + }) } fn validate_union( @@ -497,7 +569,7 @@ impl DocValidationScope<'_> { Some(tag) => self.validate_datatype(tag, false, span)?, None => return Ok((IntRepr::U32, None)), }; - match &*ty.type_() { + match &**ty.type_() { Type::Variant(e) => { let mut names = Vec::new(); for c in e.cases.iter() { @@ -594,8 +666,7 @@ impl<'a> ModuleValidation<'a> { let params = syntax .params .iter() - .enumerate() - .map(|(ix, f)| { + .map(|f| { Ok(InterfaceFuncParam { name: argnames.introduce( f.item.name.name(), @@ -606,7 +677,6 @@ impl<'a> ModuleValidation<'a> { false, f.item.name.span(), )?, - position: InterfaceFuncParamPosition::Param(ix), docs: f.comments.docs(), }) }) @@ -614,33 +684,29 @@ impl<'a> ModuleValidation<'a> { let results = syntax .results .iter() - .enumerate() - .map(|(ix, f)| { + .map(|f| { let tref = self.doc .validate_datatype(&f.item.type_, false, f.item.name.span())?; - if ix == 0 { - match tref.type_().passed_by() { - TypePassedBy::Value(_) => {} - _ => Err(ValidationError::InvalidFirstResultType { - location: self.doc.location(f.item.name.span()), - })?, - } - } Ok(InterfaceFuncParam { name: argnames.introduce( f.item.name.name(), self.doc.location(f.item.name.span()), )?, tref, - position: InterfaceFuncParamPosition::Result(ix), docs: f.comments.docs(), }) }) .collect::, _>>()?; let noreturn = syntax.noreturn; - + let abi = Abi::Preview1; + abi.validate(¶ms, &results) + .map_err(|reason| ValidationError::Abi { + reason, + location: self.doc.location(syntax.export_loc), + })?; let rc_func = Rc::new(InterfaceFunc { + abi, name: name.clone(), params, results, diff --git a/proposals/filesystem/tools/witx/tests/witxt.rs b/proposals/filesystem/tools/witx/tests/witxt.rs index 1056947a3..7c002fe1b 100644 --- a/proposals/filesystem/tools/witx/tests/witxt.rs +++ b/proposals/filesystem/tools/witx/tests/witxt.rs @@ -14,7 +14,7 @@ use std::path::{Path, PathBuf}; use std::str; use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use wast::parser::{self, Parse, ParseBuffer, Parser}; -use witx::{Documentation, Representable}; +use witx::{Documentation, Instruction, Representable, WasmType}; fn main() { let tests = find_tests(); @@ -192,6 +192,36 @@ impl WitxtRunner<'_> { } } } + WitxtDirective::AssertAbi { + witx, + wasm, + interface, + wasm_signature: (wasm_params, wasm_results), + .. + } => { + let doc = witx.document(contents, test)?; + let module = doc.modules().next().ok_or_else(|| anyhow!("no modules"))?; + let func = module.funcs().next().ok_or_else(|| anyhow!("no funcs"))?; + + let (params, results) = func.wasm_signature(); + if params != wasm_params { + bail!("expected params {:?}, found {:?}", wasm_params, params); + } + if results != wasm_results { + bail!("expected results {:?}, found {:?}", wasm_results, results); + } + + let mut check = AbiBindgen { + abi: wasm.instrs.iter(), + err: None, + contents, + }; + func.call_wasm(&module.name, &mut check); + check.check()?; + check.abi = interface.instrs.iter(); + func.call_interface(&module.name, &mut check); + check.check()?; + } } Ok(()) } @@ -249,14 +279,147 @@ impl WitxtRunner<'_> { } } +struct AbiBindgen<'a> { + abi: std::slice::Iter<'a, (wast::Span, &'a str)>, + err: Option, + contents: &'a str, +} + +impl AbiBindgen<'_> { + fn check(&mut self) -> Result<()> { + match self.err.take() { + None => Ok(()), + Some(e) => Err(e), + } + } + + fn assert(&mut self, name: &str) { + if self.err.is_some() { + return; + } + match self.abi.next() { + Some((_, s)) if *s == name => {} + Some((span, s)) => { + let (line, col) = span.linecol_in(self.contents); + self.err = Some(anyhow!( + "line {}:{} - expected `{}` found `{}`", + line + 1, + col + 1, + name, + s, + )); + } + None => { + self.err = Some(anyhow!( + "extra instruction `{}` found when none was expected", + name + )); + } + } + } +} + +impl witx::Bindgen for AbiBindgen<'_> { + type Operand = (); + fn emit( + &mut self, + inst: &Instruction<'_>, + _operands: &mut Vec, + results: &mut Vec, + ) { + use witx::Instruction::*; + match inst { + GetArg { nth } => self.assert(&format!("get-arg{}", nth)), + AddrOf => self.assert("addr-of"), + I32FromChar => self.assert("i32.from_char"), + I64FromU64 => self.assert("i64.from_u64"), + I64FromS64 => self.assert("i64.from_s64"), + I32FromU32 => self.assert("i32.from_u32"), + I32FromS32 => self.assert("i32.from_s32"), + I32FromUsize => self.assert("i32.from_usize"), + I32FromU16 => self.assert("i32.from_u16"), + I32FromS16 => self.assert("i32.from_s16"), + I32FromU8 => self.assert("i32.from_u8"), + I32FromS8 => self.assert("i32.from_s8"), + I32FromChar8 => self.assert("i32.from_char8"), + I32FromPointer => self.assert("i32.from_pointer"), + I32FromConstPointer => self.assert("i32.from_const_pointer"), + I32FromHandle { .. } => self.assert("i32.from_handle"), + ListPointerLength => self.assert("list.pointer_length"), + ListFromPointerLength { .. } => self.assert("list.from_pointer_length"), + F32FromIf32 => self.assert("f32.from_if32"), + F64FromIf64 => self.assert("f64.from_if64"), + CallWasm { .. } => self.assert("call.wasm"), + CallInterface { .. } => self.assert("call.interface"), + S8FromI32 => self.assert("s8.from_i32"), + U8FromI32 => self.assert("u8.from_i32"), + S16FromI32 => self.assert("s16.from_i32"), + U16FromI32 => self.assert("u16.from_i32"), + S32FromI32 => self.assert("s32.from_i32"), + U32FromI32 => self.assert("u32.from_i32"), + S64FromI64 => self.assert("s64.from_i64"), + U64FromI64 => self.assert("u64.from_i64"), + CharFromI32 => self.assert("char.from_i32"), + Char8FromI32 => self.assert("char8.from_i32"), + UsizeFromI32 => self.assert("usize.from_i32"), + If32FromF32 => self.assert("if32.from_f32"), + If64FromF64 => self.assert("if64.from_f64"), + HandleFromI32 { .. } => self.assert("handle.from_i32"), + PointerFromI32 { .. } => self.assert("pointer.from_i32"), + ConstPointerFromI32 { .. } => self.assert("const_pointer.from_i32"), + ReturnPointerGet { n } => self.assert(&format!("return_pointer.get{}", n)), + ResultLift => self.assert("result.lift"), + ResultLower { .. } => self.assert("result.lower"), + EnumLift { .. } => self.assert("enum.lift"), + EnumLower { .. } => self.assert("enum.lower"), + TupleLift { .. } => self.assert("tuple.lift"), + TupleLower { .. } => self.assert("tuple.lower"), + ReuseReturn => self.assert("reuse_return"), + Load { .. } => self.assert("load"), + Store { .. } => self.assert("store"), + Return { .. } => self.assert("return"), + VariantPayload => self.assert("variant-payload"), + I32FromBitflags { .. } => self.assert("i32.from_bitflags"), + BitflagsFromI32 { .. } => self.assert("bitflags.from_i32"), + I64FromBitflags { .. } => self.assert("i64.from_bitflags"), + BitflagsFromI64 { .. } => self.assert("bitflags.from_i64"), + } + for _ in 0..inst.results_len() { + results.push(()); + } + } + + fn allocate_space(&mut self, _: usize, _: &witx::NamedType) { + self.assert("allocate-space"); + } + + fn push_block(&mut self) { + self.assert("block.push"); + } + + fn finish_block(&mut self, _operand: Option) { + self.assert("block.finish"); + } +} + mod kw { wast::custom_keyword!(assert_invalid); wast::custom_keyword!(assert_representable); + wast::custom_keyword!(assert_abi); wast::custom_keyword!(witx); wast::custom_keyword!(eq); wast::custom_keyword!(noteq); wast::custom_keyword!(load); wast::custom_keyword!(superset); + wast::custom_keyword!(call_wasm); + wast::custom_keyword!(call_interface); + wast::custom_keyword!(param); + wast::custom_keyword!(result); + wast::custom_keyword!(wasm); + wast::custom_keyword!(i32); + wast::custom_keyword!(i64); + wast::custom_keyword!(f32); + wast::custom_keyword!(f64); } struct Witxt<'a> { @@ -286,6 +449,13 @@ enum WitxtDirective<'a> { t1: (wast::Id<'a>, &'a str), t2: (wast::Id<'a>, &'a str), }, + AssertAbi { + span: wast::Span, + witx: Witx<'a>, + wasm_signature: (Vec, Vec), + wasm: Abi<'a>, + interface: Abi<'a>, + }, } impl WitxtDirective<'_> { @@ -293,6 +463,7 @@ impl WitxtDirective<'_> { match self { WitxtDirective::Witx(w) => w.span, WitxtDirective::AssertInvalid { span, .. } + | WitxtDirective::AssertAbi { span, .. } | WitxtDirective::AssertRepresentable { span, .. } => *span, } } @@ -318,12 +489,69 @@ impl<'a> Parse<'a> for WitxtDirective<'a> { t1: (parser.parse()?, parser.parse()?), t2: (parser.parse()?, parser.parse()?), }) + } else if l.peek::() { + let span = parser.parse::()?.0; + Ok(WitxtDirective::AssertAbi { + span, + witx: parser.parens(|p| p.parse())?, + wasm_signature: parser.parens(|p| { + p.parse::()?; + let mut params = Vec::new(); + let mut results = Vec::new(); + if p.peek2::() { + p.parens(|p| { + p.parse::()?; + while !p.is_empty() { + params.push(parse_wasmtype(p)?); + } + Ok(()) + })?; + } + if p.peek2::() { + p.parens(|p| { + p.parse::()?; + while !p.is_empty() { + results.push(parse_wasmtype(p)?); + } + Ok(()) + })?; + } + Ok((params, results)) + })?, + wasm: parser.parens(|p| { + p.parse::()?; + p.parse() + })?, + interface: parser.parens(|p| { + p.parse::()?; + p.parse() + })?, + }) } else { Err(l.error()) } } } +fn parse_wasmtype(p: Parser<'_>) -> parser::Result { + let mut l = p.lookahead1(); + if l.peek::() { + p.parse::()?; + Ok(WasmType::I32) + } else if l.peek::() { + p.parse::()?; + Ok(WasmType::I64) + } else if l.peek::() { + p.parse::()?; + Ok(WasmType::F32) + } else if l.peek::() { + p.parse::()?; + Ok(WasmType::F64) + } else { + Err(l.error()) + } +} + struct Witx<'a> { span: wast::Span, id: Option>, @@ -407,3 +635,22 @@ impl<'a> Parse<'a> for RepEquality { } } } + +struct Abi<'a> { + instrs: Vec<(wast::Span, &'a str)>, +} + +impl<'a> Parse<'a> for Abi<'a> { + fn parse(parser: Parser<'a>) -> parser::Result { + let mut instrs = Vec::new(); + while !parser.is_empty() { + instrs.push(parser.step(|cursor| { + let (kw, next) = cursor + .keyword() + .ok_or_else(|| cursor.error("expected keyword"))?; + Ok(((cursor.cur_span(), kw), next)) + })?); + } + Ok(Abi { instrs }) + } +} diff --git a/proposals/filesystem/tools/witx/tests/witxt/abi.witxt b/proposals/filesystem/tools/witx/tests/witxt/abi.witxt new file mode 100644 index 000000000..ccdad7bf4 --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/witxt/abi.witxt @@ -0,0 +1,490 @@ +(assert_abi + (witx (module $x (@interface func (export "f")))) + (wasm) + (call_wasm call.wasm return) + (call_interface call.interface return) +) + +;; scalar arguments +(assert_abi + (witx (module $x (@interface func (export "f") (param $p u8)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_u8 call.wasm return) + (call_interface get-arg0 u8.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p s8)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_s8 call.wasm return) + (call_interface get-arg0 s8.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p u16)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_u16 call.wasm return) + (call_interface get-arg0 u16.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p s16)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_s16 call.wasm return) + (call_interface get-arg0 s16.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p u32)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_u32 call.wasm return) + (call_interface get-arg0 u32.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p s32)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_s32 call.wasm return) + (call_interface get-arg0 s32.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p u64)))) + (wasm (param i64)) + (call_wasm get-arg0 i64.from_u64 call.wasm return) + (call_interface get-arg0 u64.from_i64 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p s64)))) + (wasm (param i64)) + (call_wasm get-arg0 i64.from_s64 call.wasm return) + (call_interface get-arg0 s64.from_i64 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p f32)))) + (wasm (param f32)) + (call_wasm get-arg0 f32.from_if32 call.wasm return) + (call_interface get-arg0 if32.from_f32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p f64)))) + (wasm (param f64)) + (call_wasm get-arg0 f64.from_if64 call.wasm return) + (call_interface get-arg0 if64.from_f64 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p (@witx usize))))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_usize call.wasm return) + (call_interface get-arg0 usize.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p (@witx char8))))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_char8 call.wasm return) + (call_interface get-arg0 char8.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p char)))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_char call.wasm return) + (call_interface get-arg0 char.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p (@witx pointer u8))))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_pointer call.wasm return) + (call_interface get-arg0 pointer.from_i32 call.interface return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (param $p (@witx const_pointer u8))))) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_const_pointer call.wasm return) + (call_interface get-arg0 const_pointer.from_i32 call.interface return) +) + +;; flags parameter +(assert_abi + (witx + (typename $a (flags $x $y)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_bitflags call.wasm return) + (call_interface get-arg0 bitflags.from_i32 call.interface return) +) +(assert_abi + (witx + (typename $a (flags (@witx repr u64) $x $y)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i64)) + (call_wasm get-arg0 i64.from_bitflags call.wasm return) + (call_interface get-arg0 bitflags.from_i64 call.interface return) +) + +;; struct parameter +(assert_abi + (witx + (typename $a (record (field $x u8))) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 addr-of call.wasm return) + (call_interface get-arg0 load call.interface return) +) + +;; handle parameter +(assert_abi + (witx + (typename $a (handle)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 i32.from_handle call.wasm return) + (call_interface get-arg0 handle.from_i32 call.interface return) +) + +;; list parameter +(assert_abi + (witx + (module $x (@interface func (export "f") (param $p (list u8)))) + ) + (wasm (param i32 i32)) + (call_wasm get-arg0 list.pointer_length call.wasm return) + (call_interface get-arg0 get-arg1 list.from_pointer_length call.interface return) +) + +;; variant parameter -- some not allowed at this time +(assert_abi + (witx + (typename $a (enum $b)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 enum.lower call.wasm return) + (call_interface get-arg0 enum.lift call.interface return) +) +(assert_abi + (witx + (typename $a (union f32)) + (module $x (@interface func (export "f") (param $p $a))) + ) + (wasm (param i32)) + (call_wasm get-arg0 addr-of call.wasm return) + (call_interface get-arg0 load call.interface return) +) + +;; scalar returns +(assert_abi + (witx (module $x (@interface func (export "f") (result $p u8)))) + (wasm (result i32)) + (call_wasm call.wasm u8.from_i32 return) + (call_interface call.interface i32.from_u8 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p s8)))) + (wasm (result i32)) + (call_wasm call.wasm s8.from_i32 return) + (call_interface call.interface i32.from_s8 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p u16)))) + (wasm (result i32)) + (call_wasm call.wasm u16.from_i32 return) + (call_interface call.interface i32.from_u16 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p s16)))) + (wasm (result i32)) + (call_wasm call.wasm s16.from_i32 return) + (call_interface call.interface i32.from_s16 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p u32)))) + (wasm (result i32)) + (call_wasm call.wasm u32.from_i32 return) + (call_interface call.interface i32.from_u32 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p s32)))) + (wasm (result i32)) + (call_wasm call.wasm s32.from_i32 return) + (call_interface call.interface i32.from_s32 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p u64)))) + (wasm (result i64)) + (call_wasm call.wasm u64.from_i64 return) + (call_interface call.interface i64.from_u64 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p s64)))) + (wasm (result i64)) + (call_wasm call.wasm s64.from_i64 return) + (call_interface call.interface i64.from_s64 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p f32)))) + (wasm (result f32)) + (call_wasm call.wasm if32.from_f32 return) + (call_interface call.interface f32.from_if32 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p f64)))) + (wasm (result f64)) + (call_wasm call.wasm if64.from_f64 return) + (call_interface call.interface f64.from_if64 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p (@witx usize))))) + (wasm (result i32)) + (call_wasm call.wasm usize.from_i32 return) + (call_interface call.interface i32.from_usize return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p (@witx char8))))) + (wasm (result i32)) + (call_wasm call.wasm char8.from_i32 return) + (call_interface call.interface i32.from_char8 return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p char)))) + (wasm (result i32)) + (call_wasm call.wasm char.from_i32 return) + (call_interface call.interface i32.from_char return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p (@witx pointer u8))))) + (wasm (result i32)) + (call_wasm call.wasm pointer.from_i32 return) + (call_interface call.interface i32.from_pointer return) +) +(assert_abi + (witx (module $x (@interface func (export "f") (result $p (@witx const_pointer u8))))) + (wasm (result i32)) + (call_wasm call.wasm const_pointer.from_i32 return) + (call_interface call.interface i32.from_const_pointer return) +) + +;; flags return +(assert_abi + (witx + (typename $a (flags $x $y)) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (result i32)) + (call_wasm call.wasm bitflags.from_i32 return) + (call_interface call.interface i32.from_bitflags return) +) +(assert_abi + (witx + (typename $a (flags (@witx repr u64) $x $y)) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (result i64)) + (call_wasm call.wasm bitflags.from_i64 return) + (call_interface call.interface i64.from_bitflags return) +) + +;; handle return +(assert_abi + (witx + (typename $a (handle)) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (result i32)) + (call_wasm call.wasm handle.from_i32 return) + (call_interface call.interface i32.from_handle return) +) + +;; struct return -- not supported +(assert_invalid + (witx + (typename $a (record (field $x u8))) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: invalid return type" +) + +;; list return -- not supported +(assert_invalid + (witx + (module $x (@interface func (export "f") (result $p (list u8)))) + ) + "ABI error: invalid return type" +) + +;; variant return -- only some allowed +(assert_invalid + (witx + (typename $a (enum $b)) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: invalid return type" +) +(assert_invalid + (witx + (typename $a (union s32 f32)) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: invalid return type" +) +(assert_invalid + (witx + (typename $a (expected (error f32))) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: only named types are allowed in results" +) +(assert_invalid + (witx + (typename $errno (enum $success $bad)) + (typename $a (expected f32 (error $errno))) + (module $x (@interface func (export "f") (result $p $a))) + ) + "ABI error: only named types are allowed in results" +) + +;; Result<(), $errno> +(assert_abi + (witx + (typename $errno (enum $success $bad)) + (typename $a (expected (error $errno))) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (result i32)) + + (call_wasm + call.wasm + ;; ok block, nothing happens + block.push + block.finish + ;; err block, we lift the return value as the num + block.push + reuse_return + enum.lift + block.finish + ;; consumes 2 blocks and uses the return value of the call to discriminate + result.lift + return) + + (call_interface + call.interface + + ;; ok block, nothing happens + block.push + block.finish + + ;; err block, lift the enum + block.push + variant-payload + enum.lower + block.finish + + ;; consume the 2 blocks and lower based on the call + result.lower + return) +) + +;; Result<$ty, $errno> +(assert_abi + (witx + (typename $errno (enum $success $bad)) + (typename $size u32) + (typename $a (expected $size (error $errno))) + (module $x (@interface func (export "f") (result $p $a))) + ) + (wasm (param i32) (result i32)) + + (call_wasm + ;; make space for the return value and push its pointer + allocate-space + return_pointer.get0 + + call.wasm + + ;; ok block, load the return pointer and have it be the result for the `Ok` + block.push + return_pointer.get0 + load + block.finish + + block.push + reuse_return + enum.lift + block.finish + + result.lift + return) + + (call_interface + call.interface + + ;; store the successful result at the first return pointer (the first param) + block.push + variant-payload + get-arg0 + store + block.finish + + block.push + variant-payload + enum.lower + block.finish + + result.lower + return) +) + +;; Result<($a, $b), $errno> +(assert_abi + (witx + (typename $errno (enum $success $bad)) + (typename $size u32) + (typename $other (record (field $a $size))) + (module $x (@interface func (export "f") + (result $p (expected (tuple $size $other) (error $errno))))) + ) + (wasm (param i32 i32) (result i32)) + + (call_wasm + allocate-space + return_pointer.get0 + allocate-space + return_pointer.get1 + + call.wasm + + block.push + return_pointer.get0 + load + return_pointer.get1 + load + tuple.lift + block.finish + + block.push + reuse_return + enum.lift + block.finish + + result.lift + return) + + (call_interface + call.interface + + ;; note the reverse order since we're consuming the results of lowering the + ;; tuple + block.push + variant-payload + tuple.lower + get-arg1 + store + get-arg0 + store + block.finish + + block.push + variant-payload + enum.lower + block.finish + + result.lower + return) +) diff --git a/proposals/filesystem/tools/witx/tests/witxt/representation.witxt b/proposals/filesystem/tools/witx/tests/witxt/representation.witxt index 37d20a70a..53f71f196 100644 --- a/proposals/filesystem/tools/witx/tests/witxt/representation.witxt +++ b/proposals/filesystem/tools/witx/tests/witxt/representation.witxt @@ -1,8 +1,8 @@ ;; type names don't matter (witx $a - (typename $a (flags (@witx bitflags u8) $b $c))) + (typename $a (flags (@witx repr u8) $b $c))) (witx $b - (typename $b (flags (@witx bitflags u8) $b $c))) + (typename $b (flags (@witx repr u8) $b $c))) (assert_representable eq $a "a" $b "b") (assert_representable eq $b "b" $a "a") diff --git a/proposals/filesystem/tools/witx/tests/witxt/shorthand.witxt b/proposals/filesystem/tools/witx/tests/witxt/shorthand.witxt new file mode 100644 index 000000000..960615f3c --- /dev/null +++ b/proposals/filesystem/tools/witx/tests/witxt/shorthand.witxt @@ -0,0 +1,59 @@ +(witx $a + (typename $a bool)) +(witx $b + (typename $a (variant (case $false) (case $true)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (expected (error)))) +(witx $b + (typename $a (variant (case $ok) (case $err)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (expected (error u32)))) +(witx $b + (typename $a (variant (case $ok) (case $err u32)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (expected u32 (error)))) +(witx $b + (typename $a (variant (case $ok u32) (case $err)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (expected u32 (error u64)))) +(witx $b + (typename $a (variant (case $ok u32) (case $err u64)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (flags $a $b))) +(witx $b + (typename $a (record (field $a bool) (field $b bool)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (enum $a $b))) +(witx $b + (typename $a (variant (case $a) (case $b)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a string)) +(witx $b + (typename $a (list char))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (tuple u32 u64))) +(witx $b + (typename $a (record (field $0 u32) (field $1 u64)))) +(assert_representable eq $a "a" $b "a") + +(witx $a + (typename $a (union u32 u64))) +(witx $b + (typename $a (variant (case $0 u32) (case $1 u64)))) +(assert_representable eq $a "a" $b "a") From b8686ae2a732c9300661162189b3b1969a7fa761 Mon Sep 17 00:00:00 2001 From: MaulingMonkey Date: Wed, 24 Feb 2021 09:38:47 -0800 Subject: [PATCH 0871/1772] Document `=` and `\0` use in args/environ docs. (#399) --- proposals/clocks/phases/ephemeral/docs.md | 4 +++- .../clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx | 3 ++- .../clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx | 1 + proposals/clocks/phases/old/snapshot_0/docs.md | 4 +++- .../clocks/phases/old/snapshot_0/witx/wasi_unstable.witx | 4 +++- proposals/clocks/phases/snapshot/docs.md | 4 +++- .../clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx | 4 +++- 7 files changed, 18 insertions(+), 6 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 7fa4c11de..e7a3aa91b 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -1211,7 +1211,8 @@ When type is [`preopentype::dir`](#preopentype.dir): #### `get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. -The size of the array should match that returned by [`sizes_get`](#sizes_get) +The size of the array should match that returned by [`sizes_get`](#sizes_get). +Each argument is expected to be `\0` terminated. ##### Params - `argv`: `Pointer>` @@ -1327,6 +1328,7 @@ The time value of the clock. #### `get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). +Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. ##### Params - `environ`: `Pointer>` diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx index b8d77b504..bb956fc53 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -10,7 +10,8 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `sizes_get` + ;;; The size of the array should match that returned by `sizes_get`. + ;;; Each argument is expected to be `\0` terminated. (@interface func (export "get") (param $argv (@witx pointer (@witx pointer (@witx char8)))) (param $argv_buf (@witx pointer (@witx char8))) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx index 0cad3c1cc..ef1c20b22 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -11,6 +11,7 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `sizes_get`. + ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. (@interface func (export "get") (param $environ (@witx pointer (@witx pointer (@witx char8)))) (param $environ_buf (@witx pointer (@witx char8))) diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md index 707c836b2..634e304b3 100644 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ b/proposals/clocks/phases/old/snapshot_0/docs.md @@ -1270,7 +1270,8 @@ Alignment: 4 #### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. -The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) +The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get). +Each argument is expected to be `\0` terminated. ##### Params - `argv`: `Pointer>` @@ -1325,6 +1326,7 @@ Offset: 4 #### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). +Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. ##### Params - `environ`: `Pointer>` diff --git a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx index 5481882ae..dbece2641 100644 --- a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -16,7 +16,8 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `args_sizes_get` + ;;; The size of the array should match that returned by `args_sizes_get`. + ;;; Each argument is expected to be `\0` terminated. (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) @@ -31,6 +32,7 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. + ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md index c55a661b1..44c3c35f2 100644 --- a/proposals/clocks/phases/snapshot/docs.md +++ b/proposals/clocks/phases/snapshot/docs.md @@ -1267,7 +1267,8 @@ Alignment: 4 #### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. -The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) +The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get). +Each argument is expected to be `\0` terminated. ##### Params - `argv`: `Pointer>` @@ -1322,6 +1323,7 @@ Offset: 4 #### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). +Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. ##### Params - `environ`: `Pointer>` diff --git a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx index df3c670f3..efb2c797f 100644 --- a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -13,7 +13,8 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `args_sizes_get` + ;;; The size of the array should match that returned by `args_sizes_get`. + ;;; Each argument is expected to be `\0` terminated. (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) @@ -28,6 +29,7 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. + ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) From 256dfd1e29579a25ddc227a641b13a91e77ccb47 Mon Sep 17 00:00:00 2001 From: MaulingMonkey Date: Wed, 24 Feb 2021 09:38:47 -0800 Subject: [PATCH 0872/1772] Document `=` and `\0` use in args/environ docs. (#399) --- proposals/random/phases/ephemeral/docs.md | 4 +++- .../random/phases/ephemeral/witx/wasi_ephemeral_args.witx | 3 ++- .../random/phases/ephemeral/witx/wasi_ephemeral_environ.witx | 1 + proposals/random/phases/old/snapshot_0/docs.md | 4 +++- .../random/phases/old/snapshot_0/witx/wasi_unstable.witx | 4 +++- proposals/random/phases/snapshot/docs.md | 4 +++- .../random/phases/snapshot/witx/wasi_snapshot_preview1.witx | 4 +++- 7 files changed, 18 insertions(+), 6 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 7fa4c11de..e7a3aa91b 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -1211,7 +1211,8 @@ When type is [`preopentype::dir`](#preopentype.dir): #### `get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. -The size of the array should match that returned by [`sizes_get`](#sizes_get) +The size of the array should match that returned by [`sizes_get`](#sizes_get). +Each argument is expected to be `\0` terminated. ##### Params - `argv`: `Pointer>` @@ -1327,6 +1328,7 @@ The time value of the clock. #### `get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). +Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. ##### Params - `environ`: `Pointer>` diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx index b8d77b504..bb956fc53 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -10,7 +10,8 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `sizes_get` + ;;; The size of the array should match that returned by `sizes_get`. + ;;; Each argument is expected to be `\0` terminated. (@interface func (export "get") (param $argv (@witx pointer (@witx pointer (@witx char8)))) (param $argv_buf (@witx pointer (@witx char8))) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx index 0cad3c1cc..ef1c20b22 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -11,6 +11,7 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `sizes_get`. + ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. (@interface func (export "get") (param $environ (@witx pointer (@witx pointer (@witx char8)))) (param $environ_buf (@witx pointer (@witx char8))) diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md index 707c836b2..634e304b3 100644 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ b/proposals/random/phases/old/snapshot_0/docs.md @@ -1270,7 +1270,8 @@ Alignment: 4 #### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. -The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) +The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get). +Each argument is expected to be `\0` terminated. ##### Params - `argv`: `Pointer>` @@ -1325,6 +1326,7 @@ Offset: 4 #### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). +Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. ##### Params - `environ`: `Pointer>` diff --git a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx index 5481882ae..dbece2641 100644 --- a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -16,7 +16,8 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `args_sizes_get` + ;;; The size of the array should match that returned by `args_sizes_get`. + ;;; Each argument is expected to be `\0` terminated. (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) @@ -31,6 +32,7 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. + ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md index c55a661b1..44c3c35f2 100644 --- a/proposals/random/phases/snapshot/docs.md +++ b/proposals/random/phases/snapshot/docs.md @@ -1267,7 +1267,8 @@ Alignment: 4 #### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. -The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) +The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get). +Each argument is expected to be `\0` terminated. ##### Params - `argv`: `Pointer>` @@ -1322,6 +1323,7 @@ Offset: 4 #### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). +Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. ##### Params - `environ`: `Pointer>` diff --git a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx index df3c670f3..efb2c797f 100644 --- a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -13,7 +13,8 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `args_sizes_get` + ;;; The size of the array should match that returned by `args_sizes_get`. + ;;; Each argument is expected to be `\0` terminated. (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) @@ -28,6 +29,7 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. + ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) From 09b055ddc6b168555f70d81376a4776cf43671d3 Mon Sep 17 00:00:00 2001 From: MaulingMonkey Date: Wed, 24 Feb 2021 09:38:47 -0800 Subject: [PATCH 0873/1772] Document `=` and `\0` use in args/environ docs. (#399) --- proposals/filesystem/phases/ephemeral/docs.md | 4 +++- .../filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx | 3 ++- .../phases/ephemeral/witx/wasi_ephemeral_environ.witx | 1 + proposals/filesystem/phases/old/snapshot_0/docs.md | 4 +++- .../filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx | 4 +++- proposals/filesystem/phases/snapshot/docs.md | 4 +++- .../phases/snapshot/witx/wasi_snapshot_preview1.witx | 4 +++- 7 files changed, 18 insertions(+), 6 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 7fa4c11de..e7a3aa91b 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -1211,7 +1211,8 @@ When type is [`preopentype::dir`](#preopentype.dir): #### `get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. -The size of the array should match that returned by [`sizes_get`](#sizes_get) +The size of the array should match that returned by [`sizes_get`](#sizes_get). +Each argument is expected to be `\0` terminated. ##### Params - `argv`: `Pointer>` @@ -1327,6 +1328,7 @@ The time value of the clock. #### `get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). +Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. ##### Params - `environ`: `Pointer>` diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx index b8d77b504..bb956fc53 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx @@ -10,7 +10,8 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `sizes_get` + ;;; The size of the array should match that returned by `sizes_get`. + ;;; Each argument is expected to be `\0` terminated. (@interface func (export "get") (param $argv (@witx pointer (@witx pointer (@witx char8)))) (param $argv_buf (@witx pointer (@witx char8))) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx index 0cad3c1cc..ef1c20b22 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx @@ -11,6 +11,7 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `sizes_get`. + ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. (@interface func (export "get") (param $environ (@witx pointer (@witx pointer (@witx char8)))) (param $environ_buf (@witx pointer (@witx char8))) diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md index 707c836b2..634e304b3 100644 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ b/proposals/filesystem/phases/old/snapshot_0/docs.md @@ -1270,7 +1270,8 @@ Alignment: 4 #### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. -The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) +The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get). +Each argument is expected to be `\0` terminated. ##### Params - `argv`: `Pointer>` @@ -1325,6 +1326,7 @@ Offset: 4 #### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). +Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. ##### Params - `environ`: `Pointer>` diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx index 5481882ae..dbece2641 100644 --- a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx +++ b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx @@ -16,7 +16,8 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `args_sizes_get` + ;;; The size of the array should match that returned by `args_sizes_get`. + ;;; Each argument is expected to be `\0` terminated. (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) @@ -31,6 +32,7 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. + ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md index c55a661b1..44c3c35f2 100644 --- a/proposals/filesystem/phases/snapshot/docs.md +++ b/proposals/filesystem/phases/snapshot/docs.md @@ -1267,7 +1267,8 @@ Alignment: 4 #### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` Read command-line argument data. -The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get) +The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get). +Each argument is expected to be `\0` terminated. ##### Params - `argv`: `Pointer>` @@ -1322,6 +1323,7 @@ Offset: 4 #### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` Read environment variable data. The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). +Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. ##### Params - `environ`: `Pointer>` diff --git a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx index df3c670f3..efb2c797f 100644 --- a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx @@ -13,7 +13,8 @@ (import "memory" (memory)) ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `args_sizes_get` + ;;; The size of the array should match that returned by `args_sizes_get`. + ;;; Each argument is expected to be `\0` terminated. (@interface func (export "args_get") (param $argv (@witx pointer (@witx pointer u8))) (param $argv_buf (@witx pointer u8)) @@ -28,6 +29,7 @@ ;;; Read environment variable data. ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. + ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. (@interface func (export "environ_get") (param $environ (@witx pointer (@witx pointer u8))) (param $environ_buf (@witx pointer u8)) From 63f66d6158e3179de00a0d73bff2dff16fd0bbd8 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Feb 2021 10:47:06 -0800 Subject: [PATCH 0874/1772] make witx cli a new crate, refactor how we validate repo contents (#398) * make the witx cli tool a separate crate * delete phases.rs: not the witx crate's responsibility * use `witx docs --check` to replace specialized tests * repo-docs can be a shell script * parallelize CI a little * wibble * typo; only need to validate witx on one os * add ephemeral * delete wasi-docs test file * i love too program in yaml * repo-docs: reduce duplication * drop dev-dependencies in witx --- proposals/clocks/.github/workflows/main.yml | 20 ++- proposals/clocks/tools/repo_docs.sh | 17 +++ proposals/clocks/tools/witx/Cargo.toml | 8 +- proposals/clocks/tools/witx/cli/Cargo.toml | 25 ++++ .../{examples/witx.rs => cli/src/main.rs} | 129 +++++++++++++++--- proposals/clocks/tools/witx/src/lib.rs | 2 - proposals/clocks/tools/witx/src/phases.rs | 75 ---------- .../clocks/tools/witx/tests/wasi-docs.rs | 99 -------------- 8 files changed, 174 insertions(+), 201 deletions(-) create mode 100755 proposals/clocks/tools/repo_docs.sh create mode 100644 proposals/clocks/tools/witx/cli/Cargo.toml rename proposals/clocks/tools/witx/{examples/witx.rs => cli/src/main.rs} (55%) delete mode 100644 proposals/clocks/tools/witx/src/phases.rs delete mode 100644 proposals/clocks/tools/witx/tests/wasi-docs.rs diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 138782c2c..0305f7f32 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -3,7 +3,7 @@ on: [push, pull_request] jobs: test: - name: Test + name: Test witx tools runs-on: ${{ matrix.os }} strategy: matrix: @@ -21,11 +21,21 @@ jobs: if: matrix.os == 'macos-latest' - run: cargo fetch working-directory: tools/witx - - run: cargo build - working-directory: tools/witx - - run: cargo test + - run: cargo test --all working-directory: tools/witx + validate: + name: Validate witx files and docs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Install Rust (rustup) + shell: bash + run: rustup update stable --no-self-update && rustup default stable + + - name: Check that repository docs reflect witx + run: ./tools/repo_docs.sh --check + rustfmt: name: Rustfmt runs-on: ubuntu-latest @@ -33,5 +43,5 @@ jobs: - uses: actions/checkout@v1 - name: Install Rust run: rustup update stable && rustup default stable && rustup component add rustfmt - - run: cargo fmt -- --check + - run: cargo fmt --all -- --check working-directory: tools/witx diff --git a/proposals/clocks/tools/repo_docs.sh b/proposals/clocks/tools/repo_docs.sh new file mode 100755 index 000000000..e0187bcaf --- /dev/null +++ b/proposals/clocks/tools/repo_docs.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -ex +cd $(dirname $(realpath $0))/witx +cargo run -p witx-cli -- docs $1 ../../phases/snapshot/witx/wasi_snapshot_preview1.witx --output ../../phases/snapshot/docs.md +cargo run -p witx-cli -- docs $1 ../../phases/old/snapshot_0/witx/wasi_unstable.witx --output ../../phases/old/snapshot_0/docs.md +cargo run -p witx-cli -- docs $1 \ + ../../phases/ephemeral/witx/wasi_ephemeral_args.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_clock.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_environ.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_fd.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_path.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_poll.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_proc.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_random.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_sched.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_sock.witx \ + --output ../../phases/ephemeral/docs.md diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml index bd4bfc076..1dd39a8b1 100644 --- a/proposals/clocks/tools/witx/Cargo.toml +++ b/proposals/clocks/tools/witx/Cargo.toml @@ -20,11 +20,13 @@ thiserror = "1.0" wast = { version = "33.0.0", default-features = false } [dev-dependencies] -diff = "0.1.11" -pretty_env_logger = "0.4" -structopt = "0.3" rayon = "1.0" [[test]] name = "witxt" harness = false + +[workspace] +members = [ + "cli", +] diff --git a/proposals/clocks/tools/witx/cli/Cargo.toml b/proposals/clocks/tools/witx/cli/Cargo.toml new file mode 100644 index 000000000..6f45ef3d9 --- /dev/null +++ b/proposals/clocks/tools/witx/cli/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "witx-cli" +version = "0.9.0" +description = "CLI for operating on witx file format" +homepage = "https://github.com/WebAssembly/WASI" +repository = "https://github.com/WebAssembly/WASI" +license = "Apache-2.0" +categories = ["wasm"] +keywords = ["webassembly", "wasm"] +authors = ["Pat Hickey ", "Alex Crichton "] +edition = "2018" + +[[bin]] +name = "witx" +path = "src/main.rs" + +[dependencies] +witx = { path = "../", version = "0.9.0" } +anyhow = "1" +log = "0.4" +thiserror = "1.0" +diff = "0.1.11" +pretty_env_logger = "0.4" +structopt = "0.3" +rayon = "1.0" diff --git a/proposals/clocks/tools/witx/examples/witx.rs b/proposals/clocks/tools/witx/cli/src/main.rs similarity index 55% rename from proposals/clocks/tools/witx/examples/witx.rs rename to proposals/clocks/tools/witx/cli/src/main.rs index f86140ab8..bd1d38dc8 100644 --- a/proposals/clocks/tools/witx/examples/witx.rs +++ b/proposals/clocks/tools/witx/cli/src/main.rs @@ -4,7 +4,7 @@ use std::io::Write; use std::path::{Path, PathBuf}; use std::process; use structopt::{clap::AppSettings, StructOpt}; -use witx::{load, phases, Document, Documentation}; +use witx::{load, Document, Documentation}; /// Validate and process witx files #[derive(StructOpt, Debug)] @@ -31,6 +31,9 @@ enum Command { /// Path to root of witx document #[structopt(number_of_values = 1, value_name = "INPUT", parse(from_os_str))] input: Vec, + /// Perform check that output matches witx documents + #[structopt(long = "check")] + check: bool, /// Path to generated documentation in Markdown format #[structopt( short = "o", @@ -40,8 +43,6 @@ enum Command { )] output: Option, }, - /// Update documentation in WASI repository to reflect witx specs - RepoDocs, /// Examine differences between interfaces Polyfill { /// Path to root of witx document @@ -80,22 +81,32 @@ pub fn main() { let verbose = args.verbose; match args.cmd { - Command::Docs { input, output } => { + Command::Docs { + input, + check, + output, + } => { let doc = load_witx(&input, "input", verbose); - if let Some(output) = output { - write_docs(&doc, output) + if check { + let output = output.expect("output argument required in docs --check mode"); + if diff_against_filesystem(&doc.to_md(), &output).is_err() { + println!("Docs in tree are out-of-date with witx files. Re-run this executable with the following arguments to to re-generate:"); + println!( + "> witx docs {} --output {}", + input + .iter() + .map(|p| p.to_string_lossy().into_owned()) + .collect::>() + .join(" "), + output.to_string_lossy(), + ); + } } else { - println!("{}", doc.to_md()) - } - } - Command::RepoDocs => { - for phase in &[ - phases::snapshot().unwrap(), - phases::ephemeral().unwrap(), - phases::old::snapshot_0().unwrap(), - ] { - let doc = load(&phase).expect("parse phase"); - write_docs(&doc, phases::docs_path(&phase)); + if let Some(output) = output { + write_docs(&doc, output) + } else { + println!("{}", doc.to_md()) + } } } Command::Polyfill { @@ -173,3 +184,87 @@ fn parse_module_mapping(m: &str) -> Result<(String, String)> { }; Ok((n.to_string(), o.to_string())) } + +fn dos2unix(s: &str) -> String { + let mut t = String::new(); + t.reserve(s.len()); + for c in s.chars() { + if c != '\r' { + t.push(c) + } + } + t +} + +fn diff_against_filesystem(expected: &str, path: &Path) -> Result<(), ()> { + let actual = std::fs::read_to_string(path) + .unwrap_or_else(|e| panic!("couldn't read {}: {:?}", Path::display(path), e)); + // Git may checkout the file with dos line endings on windows. Strip all \r: + let actual = dos2unix(&actual); + if &actual == expected { + return Ok(()); + } + + eprintln!("The following diff was found between the docs generated from .witx and the"); + eprintln!("source {:?} in the tree:", path); + eprintln!(); + + let mut expected_line = 1; + let mut actual_line = 1; + let mut separated = false; + let mut any_lines = false; + for diff in diff::lines(&expected, &actual) { + match diff { + diff::Result::Left(l) => { + eprintln!("line {}: -{}", expected_line, l); + expected_line += 1; + separated = false; + any_lines = true; + } + diff::Result::Both(_, _) => { + expected_line += 1; + actual_line += 1; + if !separated { + eprintln!("..."); + separated = true; + } + } + diff::Result::Right(r) => { + eprintln!("line {}: +{}", actual_line, r); + actual_line += 1; + separated = false; + any_lines = true; + } + } + } + + if !any_lines { + eprintln!(); + eprintln!( + "Somehow there was a diff with no lines differing. Lengths: {} and {}.", + expected.len(), + actual.len() + ); + for (index, (a, b)) in actual.chars().zip(expected.chars()).enumerate() { + if a != b { + eprintln!("char difference at index {}: '{}' != '{}'", index, a, b); + } + } + for (index, (a, b)) in actual.bytes().zip(expected.bytes()).enumerate() { + if a != b { + eprintln!("byte difference at index {}: b'{}' != b'{}'", index, a, b); + } + } + eprintln!(); + eprintln!("actual: {}", actual); + eprintln!(); + eprintln!("expected: {}", expected); + } + + eprintln!(); + eprintln!( + "To regenerate the files, run `cd tools/witx && cargo run --example witx repo-docs`." + ); + eprintln!(); + Err(()) +} diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs index f1cc7e229..a0eba6a17 100644 --- a/proposals/clocks/tools/witx/src/lib.rs +++ b/proposals/clocks/tools/witx/src/lib.rs @@ -10,8 +10,6 @@ mod io; mod layout; /// Witx syntax parsing from SExprs pub mod parser; -/// Paths to witx documents for various proposal phases -pub mod phases; /// Calculate required polyfill between interfaces pub mod polyfill; /// Render ast to text diff --git a/proposals/clocks/tools/witx/src/phases.rs b/proposals/clocks/tools/witx/src/phases.rs deleted file mode 100644 index 0bf697e21..000000000 --- a/proposals/clocks/tools/witx/src/phases.rs +++ /dev/null @@ -1,75 +0,0 @@ -use anyhow::{bail, Result}; -use std::env; -use std::path::{Path, PathBuf}; - -pub fn docs_path(phase_paths: &[PathBuf]) -> PathBuf { - phase_paths - .get(0) - .expect("at least one path") - .parent() - .expect("drop file") - .join("../docs.md") -} - -pub fn snapshot() -> Result> { - let root = repo_root()?; - let snapshot = root.join("phases/snapshot/witx"); - let paths = vec![snapshot.join("wasi_snapshot_preview1.witx")]; - ensure_exists(&paths)?; - Ok(paths) -} - -pub fn ephemeral() -> Result> { - let root = repo_root()?; - let ephemeral = root.join("phases/ephemeral/witx"); - let paths = vec![ - ephemeral.join("wasi_ephemeral_args.witx"), - ephemeral.join("wasi_ephemeral_clock.witx"), - ephemeral.join("wasi_ephemeral_environ.witx"), - ephemeral.join("wasi_ephemeral_fd.witx"), - ephemeral.join("wasi_ephemeral_path.witx"), - ephemeral.join("wasi_ephemeral_poll.witx"), - ephemeral.join("wasi_ephemeral_proc.witx"), - ephemeral.join("wasi_ephemeral_random.witx"), - ephemeral.join("wasi_ephemeral_sched.witx"), - ephemeral.join("wasi_ephemeral_sock.witx"), - ]; - ensure_exists(&paths)?; - Ok(paths) -} - -pub mod old { - use super::*; - pub fn snapshot_0() -> Result> { - let root = repo_root()?; - let snapshot_0 = root.join("phases/old/snapshot_0/witx"); - let paths = vec![snapshot_0.join("wasi_unstable.witx")]; - ensure_exists(&paths)?; - Ok(paths) - } -} - -fn repo_root() -> Result { - let repo_root = if let Ok(e) = env::var("WASI_REPO") { - PathBuf::from(e) - } else { - PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..") - }; - if repo_root.exists() { - Ok(repo_root) - } else { - bail!("could not find WASI repo root - try setting WASI_REPO env variable") - } -} - -fn ensure_exists(paths: &[PathBuf]) -> Result<()> { - for p in paths.iter() { - if !p.exists() { - bail!( - "{} does not exist - is WASI_REPO set to repository root?", - Path::display(p) - ) - } - } - Ok(()) -} diff --git a/proposals/clocks/tools/witx/tests/wasi-docs.rs b/proposals/clocks/tools/witx/tests/wasi-docs.rs deleted file mode 100644 index 6702edfbd..000000000 --- a/proposals/clocks/tools/witx/tests/wasi-docs.rs +++ /dev/null @@ -1,99 +0,0 @@ -use std::fs; -use std::path::Path; -use witx::{self, Documentation}; - -#[test] -fn validate_docs() { - for phase in &[ - witx::phases::snapshot().unwrap(), - witx::phases::ephemeral().unwrap(), - witx::phases::old::snapshot_0().unwrap(), - ] { - let doc = witx::load(&phase).unwrap_or_else(|e| panic!("failed to parse: {}", e)); - diff_against_filesystem(&doc.to_md(), &witx::phases::docs_path(&phase)); - } -} - -fn dos2unix(s: &str) -> String { - let mut t = String::new(); - t.reserve(s.len()); - for c in s.chars() { - if c != '\r' { - t.push(c) - } - } - t -} - -fn diff_against_filesystem(expected: &str, path: &Path) { - let actual = fs::read_to_string(path) - .unwrap_or_else(|e| panic!("couldn't read {}: {:?}", Path::display(path), e)); - // Git may checkout the file with dos line endings on windows. Strip all \r: - let actual = dos2unix(&actual); - if &actual == expected { - return; - } - - eprintln!("The following diff was found between the docs generated from .witx and the"); - eprintln!("source {:?} in the tree:", path); - eprintln!(); - - let mut expected_line = 1; - let mut actual_line = 1; - let mut separated = false; - let mut any_lines = false; - for diff in diff::lines(&expected, &actual) { - match diff { - diff::Result::Left(l) => { - eprintln!("line {}: -{}", expected_line, l); - expected_line += 1; - separated = false; - any_lines = true; - } - diff::Result::Both(_, _) => { - expected_line += 1; - actual_line += 1; - if !separated { - eprintln!("..."); - separated = true; - } - } - diff::Result::Right(r) => { - eprintln!("line {}: +{}", actual_line, r); - actual_line += 1; - separated = false; - any_lines = true; - } - } - } - - if !any_lines { - eprintln!(); - eprintln!( - "Somehow there was a diff with no lines differing. Lengths: {} and {}.", - expected.len(), - actual.len() - ); - for (index, (a, b)) in actual.chars().zip(expected.chars()).enumerate() { - if a != b { - eprintln!("char difference at index {}: '{}' != '{}'", index, a, b); - } - } - for (index, (a, b)) in actual.bytes().zip(expected.bytes()).enumerate() { - if a != b { - eprintln!("byte difference at index {}: b'{}' != b'{}'", index, a, b); - } - } - eprintln!(); - eprintln!("actual: {}", actual); - eprintln!(); - eprintln!("expected: {}", expected); - } - - eprintln!(); - eprintln!( - "To regenerate the files, run `cd tools/witx && cargo run --example witx repo-docs`." - ); - eprintln!(); - panic!(); -} From aeff0f9d0791f7a12d2da04fbcb8c0be17389d9e Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Feb 2021 10:47:06 -0800 Subject: [PATCH 0875/1772] make witx cli a new crate, refactor how we validate repo contents (#398) * make the witx cli tool a separate crate * delete phases.rs: not the witx crate's responsibility * use `witx docs --check` to replace specialized tests * repo-docs can be a shell script * parallelize CI a little * wibble * typo; only need to validate witx on one os * add ephemeral * delete wasi-docs test file * i love too program in yaml * repo-docs: reduce duplication * drop dev-dependencies in witx --- proposals/random/.github/workflows/main.yml | 20 ++- proposals/random/tools/repo_docs.sh | 17 +++ proposals/random/tools/witx/Cargo.toml | 8 +- proposals/random/tools/witx/cli/Cargo.toml | 25 ++++ .../{examples/witx.rs => cli/src/main.rs} | 129 +++++++++++++++--- proposals/random/tools/witx/src/lib.rs | 2 - proposals/random/tools/witx/src/phases.rs | 75 ---------- .../random/tools/witx/tests/wasi-docs.rs | 99 -------------- 8 files changed, 174 insertions(+), 201 deletions(-) create mode 100755 proposals/random/tools/repo_docs.sh create mode 100644 proposals/random/tools/witx/cli/Cargo.toml rename proposals/random/tools/witx/{examples/witx.rs => cli/src/main.rs} (55%) delete mode 100644 proposals/random/tools/witx/src/phases.rs delete mode 100644 proposals/random/tools/witx/tests/wasi-docs.rs diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index 138782c2c..0305f7f32 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -3,7 +3,7 @@ on: [push, pull_request] jobs: test: - name: Test + name: Test witx tools runs-on: ${{ matrix.os }} strategy: matrix: @@ -21,11 +21,21 @@ jobs: if: matrix.os == 'macos-latest' - run: cargo fetch working-directory: tools/witx - - run: cargo build - working-directory: tools/witx - - run: cargo test + - run: cargo test --all working-directory: tools/witx + validate: + name: Validate witx files and docs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Install Rust (rustup) + shell: bash + run: rustup update stable --no-self-update && rustup default stable + + - name: Check that repository docs reflect witx + run: ./tools/repo_docs.sh --check + rustfmt: name: Rustfmt runs-on: ubuntu-latest @@ -33,5 +43,5 @@ jobs: - uses: actions/checkout@v1 - name: Install Rust run: rustup update stable && rustup default stable && rustup component add rustfmt - - run: cargo fmt -- --check + - run: cargo fmt --all -- --check working-directory: tools/witx diff --git a/proposals/random/tools/repo_docs.sh b/proposals/random/tools/repo_docs.sh new file mode 100755 index 000000000..e0187bcaf --- /dev/null +++ b/proposals/random/tools/repo_docs.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -ex +cd $(dirname $(realpath $0))/witx +cargo run -p witx-cli -- docs $1 ../../phases/snapshot/witx/wasi_snapshot_preview1.witx --output ../../phases/snapshot/docs.md +cargo run -p witx-cli -- docs $1 ../../phases/old/snapshot_0/witx/wasi_unstable.witx --output ../../phases/old/snapshot_0/docs.md +cargo run -p witx-cli -- docs $1 \ + ../../phases/ephemeral/witx/wasi_ephemeral_args.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_clock.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_environ.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_fd.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_path.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_poll.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_proc.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_random.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_sched.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_sock.witx \ + --output ../../phases/ephemeral/docs.md diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml index bd4bfc076..1dd39a8b1 100644 --- a/proposals/random/tools/witx/Cargo.toml +++ b/proposals/random/tools/witx/Cargo.toml @@ -20,11 +20,13 @@ thiserror = "1.0" wast = { version = "33.0.0", default-features = false } [dev-dependencies] -diff = "0.1.11" -pretty_env_logger = "0.4" -structopt = "0.3" rayon = "1.0" [[test]] name = "witxt" harness = false + +[workspace] +members = [ + "cli", +] diff --git a/proposals/random/tools/witx/cli/Cargo.toml b/proposals/random/tools/witx/cli/Cargo.toml new file mode 100644 index 000000000..6f45ef3d9 --- /dev/null +++ b/proposals/random/tools/witx/cli/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "witx-cli" +version = "0.9.0" +description = "CLI for operating on witx file format" +homepage = "https://github.com/WebAssembly/WASI" +repository = "https://github.com/WebAssembly/WASI" +license = "Apache-2.0" +categories = ["wasm"] +keywords = ["webassembly", "wasm"] +authors = ["Pat Hickey ", "Alex Crichton "] +edition = "2018" + +[[bin]] +name = "witx" +path = "src/main.rs" + +[dependencies] +witx = { path = "../", version = "0.9.0" } +anyhow = "1" +log = "0.4" +thiserror = "1.0" +diff = "0.1.11" +pretty_env_logger = "0.4" +structopt = "0.3" +rayon = "1.0" diff --git a/proposals/random/tools/witx/examples/witx.rs b/proposals/random/tools/witx/cli/src/main.rs similarity index 55% rename from proposals/random/tools/witx/examples/witx.rs rename to proposals/random/tools/witx/cli/src/main.rs index f86140ab8..bd1d38dc8 100644 --- a/proposals/random/tools/witx/examples/witx.rs +++ b/proposals/random/tools/witx/cli/src/main.rs @@ -4,7 +4,7 @@ use std::io::Write; use std::path::{Path, PathBuf}; use std::process; use structopt::{clap::AppSettings, StructOpt}; -use witx::{load, phases, Document, Documentation}; +use witx::{load, Document, Documentation}; /// Validate and process witx files #[derive(StructOpt, Debug)] @@ -31,6 +31,9 @@ enum Command { /// Path to root of witx document #[structopt(number_of_values = 1, value_name = "INPUT", parse(from_os_str))] input: Vec, + /// Perform check that output matches witx documents + #[structopt(long = "check")] + check: bool, /// Path to generated documentation in Markdown format #[structopt( short = "o", @@ -40,8 +43,6 @@ enum Command { )] output: Option, }, - /// Update documentation in WASI repository to reflect witx specs - RepoDocs, /// Examine differences between interfaces Polyfill { /// Path to root of witx document @@ -80,22 +81,32 @@ pub fn main() { let verbose = args.verbose; match args.cmd { - Command::Docs { input, output } => { + Command::Docs { + input, + check, + output, + } => { let doc = load_witx(&input, "input", verbose); - if let Some(output) = output { - write_docs(&doc, output) + if check { + let output = output.expect("output argument required in docs --check mode"); + if diff_against_filesystem(&doc.to_md(), &output).is_err() { + println!("Docs in tree are out-of-date with witx files. Re-run this executable with the following arguments to to re-generate:"); + println!( + "> witx docs {} --output {}", + input + .iter() + .map(|p| p.to_string_lossy().into_owned()) + .collect::>() + .join(" "), + output.to_string_lossy(), + ); + } } else { - println!("{}", doc.to_md()) - } - } - Command::RepoDocs => { - for phase in &[ - phases::snapshot().unwrap(), - phases::ephemeral().unwrap(), - phases::old::snapshot_0().unwrap(), - ] { - let doc = load(&phase).expect("parse phase"); - write_docs(&doc, phases::docs_path(&phase)); + if let Some(output) = output { + write_docs(&doc, output) + } else { + println!("{}", doc.to_md()) + } } } Command::Polyfill { @@ -173,3 +184,87 @@ fn parse_module_mapping(m: &str) -> Result<(String, String)> { }; Ok((n.to_string(), o.to_string())) } + +fn dos2unix(s: &str) -> String { + let mut t = String::new(); + t.reserve(s.len()); + for c in s.chars() { + if c != '\r' { + t.push(c) + } + } + t +} + +fn diff_against_filesystem(expected: &str, path: &Path) -> Result<(), ()> { + let actual = std::fs::read_to_string(path) + .unwrap_or_else(|e| panic!("couldn't read {}: {:?}", Path::display(path), e)); + // Git may checkout the file with dos line endings on windows. Strip all \r: + let actual = dos2unix(&actual); + if &actual == expected { + return Ok(()); + } + + eprintln!("The following diff was found between the docs generated from .witx and the"); + eprintln!("source {:?} in the tree:", path); + eprintln!(); + + let mut expected_line = 1; + let mut actual_line = 1; + let mut separated = false; + let mut any_lines = false; + for diff in diff::lines(&expected, &actual) { + match diff { + diff::Result::Left(l) => { + eprintln!("line {}: -{}", expected_line, l); + expected_line += 1; + separated = false; + any_lines = true; + } + diff::Result::Both(_, _) => { + expected_line += 1; + actual_line += 1; + if !separated { + eprintln!("..."); + separated = true; + } + } + diff::Result::Right(r) => { + eprintln!("line {}: +{}", actual_line, r); + actual_line += 1; + separated = false; + any_lines = true; + } + } + } + + if !any_lines { + eprintln!(); + eprintln!( + "Somehow there was a diff with no lines differing. Lengths: {} and {}.", + expected.len(), + actual.len() + ); + for (index, (a, b)) in actual.chars().zip(expected.chars()).enumerate() { + if a != b { + eprintln!("char difference at index {}: '{}' != '{}'", index, a, b); + } + } + for (index, (a, b)) in actual.bytes().zip(expected.bytes()).enumerate() { + if a != b { + eprintln!("byte difference at index {}: b'{}' != b'{}'", index, a, b); + } + } + eprintln!(); + eprintln!("actual: {}", actual); + eprintln!(); + eprintln!("expected: {}", expected); + } + + eprintln!(); + eprintln!( + "To regenerate the files, run `cd tools/witx && cargo run --example witx repo-docs`." + ); + eprintln!(); + Err(()) +} diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs index f1cc7e229..a0eba6a17 100644 --- a/proposals/random/tools/witx/src/lib.rs +++ b/proposals/random/tools/witx/src/lib.rs @@ -10,8 +10,6 @@ mod io; mod layout; /// Witx syntax parsing from SExprs pub mod parser; -/// Paths to witx documents for various proposal phases -pub mod phases; /// Calculate required polyfill between interfaces pub mod polyfill; /// Render ast to text diff --git a/proposals/random/tools/witx/src/phases.rs b/proposals/random/tools/witx/src/phases.rs deleted file mode 100644 index 0bf697e21..000000000 --- a/proposals/random/tools/witx/src/phases.rs +++ /dev/null @@ -1,75 +0,0 @@ -use anyhow::{bail, Result}; -use std::env; -use std::path::{Path, PathBuf}; - -pub fn docs_path(phase_paths: &[PathBuf]) -> PathBuf { - phase_paths - .get(0) - .expect("at least one path") - .parent() - .expect("drop file") - .join("../docs.md") -} - -pub fn snapshot() -> Result> { - let root = repo_root()?; - let snapshot = root.join("phases/snapshot/witx"); - let paths = vec![snapshot.join("wasi_snapshot_preview1.witx")]; - ensure_exists(&paths)?; - Ok(paths) -} - -pub fn ephemeral() -> Result> { - let root = repo_root()?; - let ephemeral = root.join("phases/ephemeral/witx"); - let paths = vec![ - ephemeral.join("wasi_ephemeral_args.witx"), - ephemeral.join("wasi_ephemeral_clock.witx"), - ephemeral.join("wasi_ephemeral_environ.witx"), - ephemeral.join("wasi_ephemeral_fd.witx"), - ephemeral.join("wasi_ephemeral_path.witx"), - ephemeral.join("wasi_ephemeral_poll.witx"), - ephemeral.join("wasi_ephemeral_proc.witx"), - ephemeral.join("wasi_ephemeral_random.witx"), - ephemeral.join("wasi_ephemeral_sched.witx"), - ephemeral.join("wasi_ephemeral_sock.witx"), - ]; - ensure_exists(&paths)?; - Ok(paths) -} - -pub mod old { - use super::*; - pub fn snapshot_0() -> Result> { - let root = repo_root()?; - let snapshot_0 = root.join("phases/old/snapshot_0/witx"); - let paths = vec![snapshot_0.join("wasi_unstable.witx")]; - ensure_exists(&paths)?; - Ok(paths) - } -} - -fn repo_root() -> Result { - let repo_root = if let Ok(e) = env::var("WASI_REPO") { - PathBuf::from(e) - } else { - PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..") - }; - if repo_root.exists() { - Ok(repo_root) - } else { - bail!("could not find WASI repo root - try setting WASI_REPO env variable") - } -} - -fn ensure_exists(paths: &[PathBuf]) -> Result<()> { - for p in paths.iter() { - if !p.exists() { - bail!( - "{} does not exist - is WASI_REPO set to repository root?", - Path::display(p) - ) - } - } - Ok(()) -} diff --git a/proposals/random/tools/witx/tests/wasi-docs.rs b/proposals/random/tools/witx/tests/wasi-docs.rs deleted file mode 100644 index 6702edfbd..000000000 --- a/proposals/random/tools/witx/tests/wasi-docs.rs +++ /dev/null @@ -1,99 +0,0 @@ -use std::fs; -use std::path::Path; -use witx::{self, Documentation}; - -#[test] -fn validate_docs() { - for phase in &[ - witx::phases::snapshot().unwrap(), - witx::phases::ephemeral().unwrap(), - witx::phases::old::snapshot_0().unwrap(), - ] { - let doc = witx::load(&phase).unwrap_or_else(|e| panic!("failed to parse: {}", e)); - diff_against_filesystem(&doc.to_md(), &witx::phases::docs_path(&phase)); - } -} - -fn dos2unix(s: &str) -> String { - let mut t = String::new(); - t.reserve(s.len()); - for c in s.chars() { - if c != '\r' { - t.push(c) - } - } - t -} - -fn diff_against_filesystem(expected: &str, path: &Path) { - let actual = fs::read_to_string(path) - .unwrap_or_else(|e| panic!("couldn't read {}: {:?}", Path::display(path), e)); - // Git may checkout the file with dos line endings on windows. Strip all \r: - let actual = dos2unix(&actual); - if &actual == expected { - return; - } - - eprintln!("The following diff was found between the docs generated from .witx and the"); - eprintln!("source {:?} in the tree:", path); - eprintln!(); - - let mut expected_line = 1; - let mut actual_line = 1; - let mut separated = false; - let mut any_lines = false; - for diff in diff::lines(&expected, &actual) { - match diff { - diff::Result::Left(l) => { - eprintln!("line {}: -{}", expected_line, l); - expected_line += 1; - separated = false; - any_lines = true; - } - diff::Result::Both(_, _) => { - expected_line += 1; - actual_line += 1; - if !separated { - eprintln!("..."); - separated = true; - } - } - diff::Result::Right(r) => { - eprintln!("line {}: +{}", actual_line, r); - actual_line += 1; - separated = false; - any_lines = true; - } - } - } - - if !any_lines { - eprintln!(); - eprintln!( - "Somehow there was a diff with no lines differing. Lengths: {} and {}.", - expected.len(), - actual.len() - ); - for (index, (a, b)) in actual.chars().zip(expected.chars()).enumerate() { - if a != b { - eprintln!("char difference at index {}: '{}' != '{}'", index, a, b); - } - } - for (index, (a, b)) in actual.bytes().zip(expected.bytes()).enumerate() { - if a != b { - eprintln!("byte difference at index {}: b'{}' != b'{}'", index, a, b); - } - } - eprintln!(); - eprintln!("actual: {}", actual); - eprintln!(); - eprintln!("expected: {}", expected); - } - - eprintln!(); - eprintln!( - "To regenerate the files, run `cd tools/witx && cargo run --example witx repo-docs`." - ); - eprintln!(); - panic!(); -} From 6db453c11210fb9d1a71eeb7fbd8f4a8717f2f0e Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Feb 2021 10:47:06 -0800 Subject: [PATCH 0876/1772] make witx cli a new crate, refactor how we validate repo contents (#398) * make the witx cli tool a separate crate * delete phases.rs: not the witx crate's responsibility * use `witx docs --check` to replace specialized tests * repo-docs can be a shell script * parallelize CI a little * wibble * typo; only need to validate witx on one os * add ephemeral * delete wasi-docs test file * i love too program in yaml * repo-docs: reduce duplication * drop dev-dependencies in witx --- .../filesystem/.github/workflows/main.yml | 20 ++- proposals/filesystem/tools/repo_docs.sh | 17 +++ proposals/filesystem/tools/witx/Cargo.toml | 8 +- .../filesystem/tools/witx/cli/Cargo.toml | 25 ++++ .../{examples/witx.rs => cli/src/main.rs} | 129 +++++++++++++++--- proposals/filesystem/tools/witx/src/lib.rs | 2 - proposals/filesystem/tools/witx/src/phases.rs | 75 ---------- .../filesystem/tools/witx/tests/wasi-docs.rs | 99 -------------- 8 files changed, 174 insertions(+), 201 deletions(-) create mode 100755 proposals/filesystem/tools/repo_docs.sh create mode 100644 proposals/filesystem/tools/witx/cli/Cargo.toml rename proposals/filesystem/tools/witx/{examples/witx.rs => cli/src/main.rs} (55%) delete mode 100644 proposals/filesystem/tools/witx/src/phases.rs delete mode 100644 proposals/filesystem/tools/witx/tests/wasi-docs.rs diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index 138782c2c..0305f7f32 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -3,7 +3,7 @@ on: [push, pull_request] jobs: test: - name: Test + name: Test witx tools runs-on: ${{ matrix.os }} strategy: matrix: @@ -21,11 +21,21 @@ jobs: if: matrix.os == 'macos-latest' - run: cargo fetch working-directory: tools/witx - - run: cargo build - working-directory: tools/witx - - run: cargo test + - run: cargo test --all working-directory: tools/witx + validate: + name: Validate witx files and docs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Install Rust (rustup) + shell: bash + run: rustup update stable --no-self-update && rustup default stable + + - name: Check that repository docs reflect witx + run: ./tools/repo_docs.sh --check + rustfmt: name: Rustfmt runs-on: ubuntu-latest @@ -33,5 +43,5 @@ jobs: - uses: actions/checkout@v1 - name: Install Rust run: rustup update stable && rustup default stable && rustup component add rustfmt - - run: cargo fmt -- --check + - run: cargo fmt --all -- --check working-directory: tools/witx diff --git a/proposals/filesystem/tools/repo_docs.sh b/proposals/filesystem/tools/repo_docs.sh new file mode 100755 index 000000000..e0187bcaf --- /dev/null +++ b/proposals/filesystem/tools/repo_docs.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -ex +cd $(dirname $(realpath $0))/witx +cargo run -p witx-cli -- docs $1 ../../phases/snapshot/witx/wasi_snapshot_preview1.witx --output ../../phases/snapshot/docs.md +cargo run -p witx-cli -- docs $1 ../../phases/old/snapshot_0/witx/wasi_unstable.witx --output ../../phases/old/snapshot_0/docs.md +cargo run -p witx-cli -- docs $1 \ + ../../phases/ephemeral/witx/wasi_ephemeral_args.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_clock.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_environ.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_fd.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_path.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_poll.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_proc.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_random.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_sched.witx \ + ../../phases/ephemeral/witx/wasi_ephemeral_sock.witx \ + --output ../../phases/ephemeral/docs.md diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml index bd4bfc076..1dd39a8b1 100644 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ b/proposals/filesystem/tools/witx/Cargo.toml @@ -20,11 +20,13 @@ thiserror = "1.0" wast = { version = "33.0.0", default-features = false } [dev-dependencies] -diff = "0.1.11" -pretty_env_logger = "0.4" -structopt = "0.3" rayon = "1.0" [[test]] name = "witxt" harness = false + +[workspace] +members = [ + "cli", +] diff --git a/proposals/filesystem/tools/witx/cli/Cargo.toml b/proposals/filesystem/tools/witx/cli/Cargo.toml new file mode 100644 index 000000000..6f45ef3d9 --- /dev/null +++ b/proposals/filesystem/tools/witx/cli/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "witx-cli" +version = "0.9.0" +description = "CLI for operating on witx file format" +homepage = "https://github.com/WebAssembly/WASI" +repository = "https://github.com/WebAssembly/WASI" +license = "Apache-2.0" +categories = ["wasm"] +keywords = ["webassembly", "wasm"] +authors = ["Pat Hickey ", "Alex Crichton "] +edition = "2018" + +[[bin]] +name = "witx" +path = "src/main.rs" + +[dependencies] +witx = { path = "../", version = "0.9.0" } +anyhow = "1" +log = "0.4" +thiserror = "1.0" +diff = "0.1.11" +pretty_env_logger = "0.4" +structopt = "0.3" +rayon = "1.0" diff --git a/proposals/filesystem/tools/witx/examples/witx.rs b/proposals/filesystem/tools/witx/cli/src/main.rs similarity index 55% rename from proposals/filesystem/tools/witx/examples/witx.rs rename to proposals/filesystem/tools/witx/cli/src/main.rs index f86140ab8..bd1d38dc8 100644 --- a/proposals/filesystem/tools/witx/examples/witx.rs +++ b/proposals/filesystem/tools/witx/cli/src/main.rs @@ -4,7 +4,7 @@ use std::io::Write; use std::path::{Path, PathBuf}; use std::process; use structopt::{clap::AppSettings, StructOpt}; -use witx::{load, phases, Document, Documentation}; +use witx::{load, Document, Documentation}; /// Validate and process witx files #[derive(StructOpt, Debug)] @@ -31,6 +31,9 @@ enum Command { /// Path to root of witx document #[structopt(number_of_values = 1, value_name = "INPUT", parse(from_os_str))] input: Vec, + /// Perform check that output matches witx documents + #[structopt(long = "check")] + check: bool, /// Path to generated documentation in Markdown format #[structopt( short = "o", @@ -40,8 +43,6 @@ enum Command { )] output: Option, }, - /// Update documentation in WASI repository to reflect witx specs - RepoDocs, /// Examine differences between interfaces Polyfill { /// Path to root of witx document @@ -80,22 +81,32 @@ pub fn main() { let verbose = args.verbose; match args.cmd { - Command::Docs { input, output } => { + Command::Docs { + input, + check, + output, + } => { let doc = load_witx(&input, "input", verbose); - if let Some(output) = output { - write_docs(&doc, output) + if check { + let output = output.expect("output argument required in docs --check mode"); + if diff_against_filesystem(&doc.to_md(), &output).is_err() { + println!("Docs in tree are out-of-date with witx files. Re-run this executable with the following arguments to to re-generate:"); + println!( + "> witx docs {} --output {}", + input + .iter() + .map(|p| p.to_string_lossy().into_owned()) + .collect::>() + .join(" "), + output.to_string_lossy(), + ); + } } else { - println!("{}", doc.to_md()) - } - } - Command::RepoDocs => { - for phase in &[ - phases::snapshot().unwrap(), - phases::ephemeral().unwrap(), - phases::old::snapshot_0().unwrap(), - ] { - let doc = load(&phase).expect("parse phase"); - write_docs(&doc, phases::docs_path(&phase)); + if let Some(output) = output { + write_docs(&doc, output) + } else { + println!("{}", doc.to_md()) + } } } Command::Polyfill { @@ -173,3 +184,87 @@ fn parse_module_mapping(m: &str) -> Result<(String, String)> { }; Ok((n.to_string(), o.to_string())) } + +fn dos2unix(s: &str) -> String { + let mut t = String::new(); + t.reserve(s.len()); + for c in s.chars() { + if c != '\r' { + t.push(c) + } + } + t +} + +fn diff_against_filesystem(expected: &str, path: &Path) -> Result<(), ()> { + let actual = std::fs::read_to_string(path) + .unwrap_or_else(|e| panic!("couldn't read {}: {:?}", Path::display(path), e)); + // Git may checkout the file with dos line endings on windows. Strip all \r: + let actual = dos2unix(&actual); + if &actual == expected { + return Ok(()); + } + + eprintln!("The following diff was found between the docs generated from .witx and the"); + eprintln!("source {:?} in the tree:", path); + eprintln!(); + + let mut expected_line = 1; + let mut actual_line = 1; + let mut separated = false; + let mut any_lines = false; + for diff in diff::lines(&expected, &actual) { + match diff { + diff::Result::Left(l) => { + eprintln!("line {}: -{}", expected_line, l); + expected_line += 1; + separated = false; + any_lines = true; + } + diff::Result::Both(_, _) => { + expected_line += 1; + actual_line += 1; + if !separated { + eprintln!("..."); + separated = true; + } + } + diff::Result::Right(r) => { + eprintln!("line {}: +{}", actual_line, r); + actual_line += 1; + separated = false; + any_lines = true; + } + } + } + + if !any_lines { + eprintln!(); + eprintln!( + "Somehow there was a diff with no lines differing. Lengths: {} and {}.", + expected.len(), + actual.len() + ); + for (index, (a, b)) in actual.chars().zip(expected.chars()).enumerate() { + if a != b { + eprintln!("char difference at index {}: '{}' != '{}'", index, a, b); + } + } + for (index, (a, b)) in actual.bytes().zip(expected.bytes()).enumerate() { + if a != b { + eprintln!("byte difference at index {}: b'{}' != b'{}'", index, a, b); + } + } + eprintln!(); + eprintln!("actual: {}", actual); + eprintln!(); + eprintln!("expected: {}", expected); + } + + eprintln!(); + eprintln!( + "To regenerate the files, run `cd tools/witx && cargo run --example witx repo-docs`." + ); + eprintln!(); + Err(()) +} diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs index f1cc7e229..a0eba6a17 100644 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ b/proposals/filesystem/tools/witx/src/lib.rs @@ -10,8 +10,6 @@ mod io; mod layout; /// Witx syntax parsing from SExprs pub mod parser; -/// Paths to witx documents for various proposal phases -pub mod phases; /// Calculate required polyfill between interfaces pub mod polyfill; /// Render ast to text diff --git a/proposals/filesystem/tools/witx/src/phases.rs b/proposals/filesystem/tools/witx/src/phases.rs deleted file mode 100644 index 0bf697e21..000000000 --- a/proposals/filesystem/tools/witx/src/phases.rs +++ /dev/null @@ -1,75 +0,0 @@ -use anyhow::{bail, Result}; -use std::env; -use std::path::{Path, PathBuf}; - -pub fn docs_path(phase_paths: &[PathBuf]) -> PathBuf { - phase_paths - .get(0) - .expect("at least one path") - .parent() - .expect("drop file") - .join("../docs.md") -} - -pub fn snapshot() -> Result> { - let root = repo_root()?; - let snapshot = root.join("phases/snapshot/witx"); - let paths = vec![snapshot.join("wasi_snapshot_preview1.witx")]; - ensure_exists(&paths)?; - Ok(paths) -} - -pub fn ephemeral() -> Result> { - let root = repo_root()?; - let ephemeral = root.join("phases/ephemeral/witx"); - let paths = vec![ - ephemeral.join("wasi_ephemeral_args.witx"), - ephemeral.join("wasi_ephemeral_clock.witx"), - ephemeral.join("wasi_ephemeral_environ.witx"), - ephemeral.join("wasi_ephemeral_fd.witx"), - ephemeral.join("wasi_ephemeral_path.witx"), - ephemeral.join("wasi_ephemeral_poll.witx"), - ephemeral.join("wasi_ephemeral_proc.witx"), - ephemeral.join("wasi_ephemeral_random.witx"), - ephemeral.join("wasi_ephemeral_sched.witx"), - ephemeral.join("wasi_ephemeral_sock.witx"), - ]; - ensure_exists(&paths)?; - Ok(paths) -} - -pub mod old { - use super::*; - pub fn snapshot_0() -> Result> { - let root = repo_root()?; - let snapshot_0 = root.join("phases/old/snapshot_0/witx"); - let paths = vec![snapshot_0.join("wasi_unstable.witx")]; - ensure_exists(&paths)?; - Ok(paths) - } -} - -fn repo_root() -> Result { - let repo_root = if let Ok(e) = env::var("WASI_REPO") { - PathBuf::from(e) - } else { - PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..") - }; - if repo_root.exists() { - Ok(repo_root) - } else { - bail!("could not find WASI repo root - try setting WASI_REPO env variable") - } -} - -fn ensure_exists(paths: &[PathBuf]) -> Result<()> { - for p in paths.iter() { - if !p.exists() { - bail!( - "{} does not exist - is WASI_REPO set to repository root?", - Path::display(p) - ) - } - } - Ok(()) -} diff --git a/proposals/filesystem/tools/witx/tests/wasi-docs.rs b/proposals/filesystem/tools/witx/tests/wasi-docs.rs deleted file mode 100644 index 6702edfbd..000000000 --- a/proposals/filesystem/tools/witx/tests/wasi-docs.rs +++ /dev/null @@ -1,99 +0,0 @@ -use std::fs; -use std::path::Path; -use witx::{self, Documentation}; - -#[test] -fn validate_docs() { - for phase in &[ - witx::phases::snapshot().unwrap(), - witx::phases::ephemeral().unwrap(), - witx::phases::old::snapshot_0().unwrap(), - ] { - let doc = witx::load(&phase).unwrap_or_else(|e| panic!("failed to parse: {}", e)); - diff_against_filesystem(&doc.to_md(), &witx::phases::docs_path(&phase)); - } -} - -fn dos2unix(s: &str) -> String { - let mut t = String::new(); - t.reserve(s.len()); - for c in s.chars() { - if c != '\r' { - t.push(c) - } - } - t -} - -fn diff_against_filesystem(expected: &str, path: &Path) { - let actual = fs::read_to_string(path) - .unwrap_or_else(|e| panic!("couldn't read {}: {:?}", Path::display(path), e)); - // Git may checkout the file with dos line endings on windows. Strip all \r: - let actual = dos2unix(&actual); - if &actual == expected { - return; - } - - eprintln!("The following diff was found between the docs generated from .witx and the"); - eprintln!("source {:?} in the tree:", path); - eprintln!(); - - let mut expected_line = 1; - let mut actual_line = 1; - let mut separated = false; - let mut any_lines = false; - for diff in diff::lines(&expected, &actual) { - match diff { - diff::Result::Left(l) => { - eprintln!("line {}: -{}", expected_line, l); - expected_line += 1; - separated = false; - any_lines = true; - } - diff::Result::Both(_, _) => { - expected_line += 1; - actual_line += 1; - if !separated { - eprintln!("..."); - separated = true; - } - } - diff::Result::Right(r) => { - eprintln!("line {}: +{}", actual_line, r); - actual_line += 1; - separated = false; - any_lines = true; - } - } - } - - if !any_lines { - eprintln!(); - eprintln!( - "Somehow there was a diff with no lines differing. Lengths: {} and {}.", - expected.len(), - actual.len() - ); - for (index, (a, b)) in actual.chars().zip(expected.chars()).enumerate() { - if a != b { - eprintln!("char difference at index {}: '{}' != '{}'", index, a, b); - } - } - for (index, (a, b)) in actual.bytes().zip(expected.bytes()).enumerate() { - if a != b { - eprintln!("byte difference at index {}: b'{}' != b'{}'", index, a, b); - } - } - eprintln!(); - eprintln!("actual: {}", actual); - eprintln!(); - eprintln!("expected: {}", expected); - } - - eprintln!(); - eprintln!( - "To regenerate the files, run `cd tools/witx && cargo run --example witx repo-docs`." - ); - eprintln!(); - panic!(); -} From ad1ac4d1e0ba1d0e4b95eca9e58c33bfe695689d Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 1 Mar 2021 15:15:03 -0500 Subject: [PATCH 0877/1772] Add 02-25 meeting notes (#403) --- proposals/clocks/meetings/2021/WASI-02-25.md | 98 ++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/proposals/clocks/meetings/2021/WASI-02-25.md b/proposals/clocks/meetings/2021/WASI-02-25.md index dd4892efc..2bc89278a 100644 --- a/proposals/clocks/meetings/2021/WASI-02-25.md +++ b/proposals/clocks/meetings/2021/WASI-02-25.md @@ -31,3 +31,101 @@ Installation is required, see the calendar invite. 1. Proposals and discussions 1. Discussion: Better error handling in WASI 1. _Sumbit a PR to add your agenda item here_ + +## Notes +### Attendees +- Lin Clark +- Dan Gohman +- Andrew Brown +- Johnnie Birch +- Sergey Rubanov +- Mark McCaskey +- Peter Huene +- Radu Matei +- Luke Wagner +- Ralph Squillace +- Pat Hickey +- Till Schneidereit +- Mingqiu Sun +- David Piepgrass +- Yong He + +**Dan Gohman:** Overview—errors handled like POSIX with single enum of errno. More APIs in WASI, not feasible to have a single errno enum. Also not reasonable to have a single error type. My expectation for errors is that every library will define its own error types. IT will make it possible for us to define a variant type like Rust’s Result. Does that shape of things make sense? + +**Andrew Brown:** Makes sense to me. Errors for wasi-nn are just a totally different sphere than files. + +**Dan Gohman:** wasi-libc will still have errno. Errno only describes small set of system errors + +**Andrew Brown:** Right now wasi-nn has own kind of error types. What’s changing? Will we just change witx and wiggle + +**Dan Gohman:** It’s not a fundamental change. We’re just making what wasi-nn is doing explicit. We’ll also be getting new features from IT which will describe what you’re doing in a better way. Enum with either success or failure, maybe called Expected. + +**Andrew Brown:** I think Alex has already made this change. + +**Dan Gohman:** Yeah, we wanted to give people a heads up about this plan. + +**Andrew Brown:** One question about the future—will this expected type, in the failure case will you be able to pass things that aren’t just an integer, like strings and stuff + +**Dan Gohman:** There is no master plan, but I expect the basic mech will be that you can have any type for errors, with full expressiveness of IT. One caveat, how do we want to handle strings? English isn’t appropriate for all envs. Will need to apply more design thought. Underlying tool won’t have a restriction against that, though + +**Andrew Brown:** Agreed. On thing I’ve found with wasi-nn is just having an errno isn’t enough + +**Dan Gohman:** Agreed, and that’s a place where tooling might be able to help. We can go down the path of thinkking of enums not just as ints but high-level types + +**Luke Wagner:** Along that line, one thing that has bugged me about classical error codes, is sometimes you want to use them for conditionals, and sometimes you just want to debug. Two level nesting of variants? Top level “You called it wrong” and second level provides detail of how you called it wrong. + +**Dan Gohman:** Yes, let’s do that. I think that’s totally a good idea to do. Another idea, in POSIX they have system calls that are never supposed to crash. In WASI, we don’t need to be as strict. If you pass a bad pointer into a syscall, it could trap. + +**Pat Hickey:** Yeah, that’s also a kind of a concession for virtualization. Awfully convenient for that + +**Dan Gohman:** So that’s the basic vision of it. Any more questions on that level of detail? One thing this does mean, we won’t have unified error handling across WASI. Another thing, we want to go through the APIs and figure out what errors things like the clock apis can return. In practice, the only thing that can fail in a clock is failing to get a clock. Wasi-filesystem will probably be where most of the error codes land. Simplifying property across different APIs. Don’t overload error codes to represent similar but not the same errors. Exception handling is coming. A possible approach is to use unwinding. I think that for WASI, errors work better. If languages want to use unwinding, they can expect errors and unwind. I think using variants instead of exceptions will work well for us. + +**Pat Hickey:** The one thing I’ll call out is that proc_exit should be implemented as unwind. + +**Dan Gohman:** That’s true. I’m going to claim that proc_exit is special. It might be something that we unwind and then turn into a clean exit status. Then the unwinding becomes an implementation detail. That wouldn’t be a thing that leaks across module boundaries. Often not a good idea for libraries to call exit directly. + +**Pat Hickey:** So we basically get rid of proc_exit as a library function + +**Dan Gohman:** So I think what we want to say is return type from main is an error type. + +**Pat Hickey:** Yeah, that way we keep types all the way down and don’t turn into bare integer. + +**Dan Gohman:** Yeah, so 3 error types. Return values, unwinding, and trapping. Trapping is for program has a bug. Maybe sometimes when return values. ____. And we’ll use unwinding across language boundaries. + +**Pat Hickey:** Unlike with errors, we can’t invent new ways to trap. + +**Dan Gohman:** Although I wonder if there’s something we could do there. I wonder if it makes sense for wasm to be able to trap with extra info. + +**Luke Wagner:** Or there could be a WASI function that says “I’m going to trap, but you can provide me with an error to print” + +**Pat Hickey:** You can imagine that a malicious module would do that + +**Luke Wagner:** They can do that already. We don’t want wasm to casually be able to catch traps. Because at a very fine granularity. But having a blast zone that allows a set to go away without taking down the rest. I think that belongs at some point of time in wasm’s future. + +**Dan Gohman:** yeah, if we add those mechanisms, then programmer errors could just be trapped. + +**Lin Clark:** Best way to collaborate + +**Dan Gohman:** Once we’ve fully modularized, each module will audit their own errors. The wasi-libc work will start after the next snapshot which includes those changes. + +**Andrew Brown:** Question about sockets. Who’s driving that + +**Dan Gohman:** Haven’t heard from them. Don’t know what their status is. Expect that if they don’t respond soon we’ll find someone else + +**Andrew Brown:** Who was originally driving it? + +**Dan Gohman:** Somebody working for a company called ____. The person who filed it is the person working there. + +**Andrew Brown:** Radu, was someone on your side interested in that? + +**Radu Matei:** We should probably have a chat at some point. How will that relate to these changes? + +**Dan Gohman:** Sockets are the other major user of errno. I expect sockets will have their own errno, and then wasi-libc will have some way to concatenate errnos and turn it into appropriate POSIX errno space. I think that’s basically it. + +**Radu Matei:** How about IO Streams? + +**Dan Gohman:** We haven’t talked about how it’s going to work with libc. I expect from a POSIX point of view, we might have a bunch of different error codes in wasi-io. Have been talking about wasi-io not reporting very specific errors because it leaks information. We aren’t necessarily going to want to return a lot of detail there either. + +**Ralph Squillace:** I think we want to try to figure out, if we help pick up the PR, what’s the best way to move forward without having to reimplement too much. Will reach out to original champion. + +**Dan Gohman:** I see wasi-filesystem and wasi-sockets being peers. At a good place for them to work the same way. From a5a35d85c20379c2d8ccd3519a4b93db6f1a4c61 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 1 Mar 2021 15:15:03 -0500 Subject: [PATCH 0878/1772] Add 02-25 meeting notes (#403) --- proposals/random/meetings/2021/WASI-02-25.md | 98 ++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/proposals/random/meetings/2021/WASI-02-25.md b/proposals/random/meetings/2021/WASI-02-25.md index dd4892efc..2bc89278a 100644 --- a/proposals/random/meetings/2021/WASI-02-25.md +++ b/proposals/random/meetings/2021/WASI-02-25.md @@ -31,3 +31,101 @@ Installation is required, see the calendar invite. 1. Proposals and discussions 1. Discussion: Better error handling in WASI 1. _Sumbit a PR to add your agenda item here_ + +## Notes +### Attendees +- Lin Clark +- Dan Gohman +- Andrew Brown +- Johnnie Birch +- Sergey Rubanov +- Mark McCaskey +- Peter Huene +- Radu Matei +- Luke Wagner +- Ralph Squillace +- Pat Hickey +- Till Schneidereit +- Mingqiu Sun +- David Piepgrass +- Yong He + +**Dan Gohman:** Overview—errors handled like POSIX with single enum of errno. More APIs in WASI, not feasible to have a single errno enum. Also not reasonable to have a single error type. My expectation for errors is that every library will define its own error types. IT will make it possible for us to define a variant type like Rust’s Result. Does that shape of things make sense? + +**Andrew Brown:** Makes sense to me. Errors for wasi-nn are just a totally different sphere than files. + +**Dan Gohman:** wasi-libc will still have errno. Errno only describes small set of system errors + +**Andrew Brown:** Right now wasi-nn has own kind of error types. What’s changing? Will we just change witx and wiggle + +**Dan Gohman:** It’s not a fundamental change. We’re just making what wasi-nn is doing explicit. We’ll also be getting new features from IT which will describe what you’re doing in a better way. Enum with either success or failure, maybe called Expected. + +**Andrew Brown:** I think Alex has already made this change. + +**Dan Gohman:** Yeah, we wanted to give people a heads up about this plan. + +**Andrew Brown:** One question about the future—will this expected type, in the failure case will you be able to pass things that aren’t just an integer, like strings and stuff + +**Dan Gohman:** There is no master plan, but I expect the basic mech will be that you can have any type for errors, with full expressiveness of IT. One caveat, how do we want to handle strings? English isn’t appropriate for all envs. Will need to apply more design thought. Underlying tool won’t have a restriction against that, though + +**Andrew Brown:** Agreed. On thing I’ve found with wasi-nn is just having an errno isn’t enough + +**Dan Gohman:** Agreed, and that’s a place where tooling might be able to help. We can go down the path of thinkking of enums not just as ints but high-level types + +**Luke Wagner:** Along that line, one thing that has bugged me about classical error codes, is sometimes you want to use them for conditionals, and sometimes you just want to debug. Two level nesting of variants? Top level “You called it wrong” and second level provides detail of how you called it wrong. + +**Dan Gohman:** Yes, let’s do that. I think that’s totally a good idea to do. Another idea, in POSIX they have system calls that are never supposed to crash. In WASI, we don’t need to be as strict. If you pass a bad pointer into a syscall, it could trap. + +**Pat Hickey:** Yeah, that’s also a kind of a concession for virtualization. Awfully convenient for that + +**Dan Gohman:** So that’s the basic vision of it. Any more questions on that level of detail? One thing this does mean, we won’t have unified error handling across WASI. Another thing, we want to go through the APIs and figure out what errors things like the clock apis can return. In practice, the only thing that can fail in a clock is failing to get a clock. Wasi-filesystem will probably be where most of the error codes land. Simplifying property across different APIs. Don’t overload error codes to represent similar but not the same errors. Exception handling is coming. A possible approach is to use unwinding. I think that for WASI, errors work better. If languages want to use unwinding, they can expect errors and unwind. I think using variants instead of exceptions will work well for us. + +**Pat Hickey:** The one thing I’ll call out is that proc_exit should be implemented as unwind. + +**Dan Gohman:** That’s true. I’m going to claim that proc_exit is special. It might be something that we unwind and then turn into a clean exit status. Then the unwinding becomes an implementation detail. That wouldn’t be a thing that leaks across module boundaries. Often not a good idea for libraries to call exit directly. + +**Pat Hickey:** So we basically get rid of proc_exit as a library function + +**Dan Gohman:** So I think what we want to say is return type from main is an error type. + +**Pat Hickey:** Yeah, that way we keep types all the way down and don’t turn into bare integer. + +**Dan Gohman:** Yeah, so 3 error types. Return values, unwinding, and trapping. Trapping is for program has a bug. Maybe sometimes when return values. ____. And we’ll use unwinding across language boundaries. + +**Pat Hickey:** Unlike with errors, we can’t invent new ways to trap. + +**Dan Gohman:** Although I wonder if there’s something we could do there. I wonder if it makes sense for wasm to be able to trap with extra info. + +**Luke Wagner:** Or there could be a WASI function that says “I’m going to trap, but you can provide me with an error to print” + +**Pat Hickey:** You can imagine that a malicious module would do that + +**Luke Wagner:** They can do that already. We don’t want wasm to casually be able to catch traps. Because at a very fine granularity. But having a blast zone that allows a set to go away without taking down the rest. I think that belongs at some point of time in wasm’s future. + +**Dan Gohman:** yeah, if we add those mechanisms, then programmer errors could just be trapped. + +**Lin Clark:** Best way to collaborate + +**Dan Gohman:** Once we’ve fully modularized, each module will audit their own errors. The wasi-libc work will start after the next snapshot which includes those changes. + +**Andrew Brown:** Question about sockets. Who’s driving that + +**Dan Gohman:** Haven’t heard from them. Don’t know what their status is. Expect that if they don’t respond soon we’ll find someone else + +**Andrew Brown:** Who was originally driving it? + +**Dan Gohman:** Somebody working for a company called ____. The person who filed it is the person working there. + +**Andrew Brown:** Radu, was someone on your side interested in that? + +**Radu Matei:** We should probably have a chat at some point. How will that relate to these changes? + +**Dan Gohman:** Sockets are the other major user of errno. I expect sockets will have their own errno, and then wasi-libc will have some way to concatenate errnos and turn it into appropriate POSIX errno space. I think that’s basically it. + +**Radu Matei:** How about IO Streams? + +**Dan Gohman:** We haven’t talked about how it’s going to work with libc. I expect from a POSIX point of view, we might have a bunch of different error codes in wasi-io. Have been talking about wasi-io not reporting very specific errors because it leaks information. We aren’t necessarily going to want to return a lot of detail there either. + +**Ralph Squillace:** I think we want to try to figure out, if we help pick up the PR, what’s the best way to move forward without having to reimplement too much. Will reach out to original champion. + +**Dan Gohman:** I see wasi-filesystem and wasi-sockets being peers. At a good place for them to work the same way. From d49ee1d971165a9555f6e516a66de2fad90447d2 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 1 Mar 2021 15:15:03 -0500 Subject: [PATCH 0879/1772] Add 02-25 meeting notes (#403) --- .../filesystem/meetings/2021/WASI-02-25.md | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/proposals/filesystem/meetings/2021/WASI-02-25.md b/proposals/filesystem/meetings/2021/WASI-02-25.md index dd4892efc..2bc89278a 100644 --- a/proposals/filesystem/meetings/2021/WASI-02-25.md +++ b/proposals/filesystem/meetings/2021/WASI-02-25.md @@ -31,3 +31,101 @@ Installation is required, see the calendar invite. 1. Proposals and discussions 1. Discussion: Better error handling in WASI 1. _Sumbit a PR to add your agenda item here_ + +## Notes +### Attendees +- Lin Clark +- Dan Gohman +- Andrew Brown +- Johnnie Birch +- Sergey Rubanov +- Mark McCaskey +- Peter Huene +- Radu Matei +- Luke Wagner +- Ralph Squillace +- Pat Hickey +- Till Schneidereit +- Mingqiu Sun +- David Piepgrass +- Yong He + +**Dan Gohman:** Overview—errors handled like POSIX with single enum of errno. More APIs in WASI, not feasible to have a single errno enum. Also not reasonable to have a single error type. My expectation for errors is that every library will define its own error types. IT will make it possible for us to define a variant type like Rust’s Result. Does that shape of things make sense? + +**Andrew Brown:** Makes sense to me. Errors for wasi-nn are just a totally different sphere than files. + +**Dan Gohman:** wasi-libc will still have errno. Errno only describes small set of system errors + +**Andrew Brown:** Right now wasi-nn has own kind of error types. What’s changing? Will we just change witx and wiggle + +**Dan Gohman:** It’s not a fundamental change. We’re just making what wasi-nn is doing explicit. We’ll also be getting new features from IT which will describe what you’re doing in a better way. Enum with either success or failure, maybe called Expected. + +**Andrew Brown:** I think Alex has already made this change. + +**Dan Gohman:** Yeah, we wanted to give people a heads up about this plan. + +**Andrew Brown:** One question about the future—will this expected type, in the failure case will you be able to pass things that aren’t just an integer, like strings and stuff + +**Dan Gohman:** There is no master plan, but I expect the basic mech will be that you can have any type for errors, with full expressiveness of IT. One caveat, how do we want to handle strings? English isn’t appropriate for all envs. Will need to apply more design thought. Underlying tool won’t have a restriction against that, though + +**Andrew Brown:** Agreed. On thing I’ve found with wasi-nn is just having an errno isn’t enough + +**Dan Gohman:** Agreed, and that’s a place where tooling might be able to help. We can go down the path of thinkking of enums not just as ints but high-level types + +**Luke Wagner:** Along that line, one thing that has bugged me about classical error codes, is sometimes you want to use them for conditionals, and sometimes you just want to debug. Two level nesting of variants? Top level “You called it wrong” and second level provides detail of how you called it wrong. + +**Dan Gohman:** Yes, let’s do that. I think that’s totally a good idea to do. Another idea, in POSIX they have system calls that are never supposed to crash. In WASI, we don’t need to be as strict. If you pass a bad pointer into a syscall, it could trap. + +**Pat Hickey:** Yeah, that’s also a kind of a concession for virtualization. Awfully convenient for that + +**Dan Gohman:** So that’s the basic vision of it. Any more questions on that level of detail? One thing this does mean, we won’t have unified error handling across WASI. Another thing, we want to go through the APIs and figure out what errors things like the clock apis can return. In practice, the only thing that can fail in a clock is failing to get a clock. Wasi-filesystem will probably be where most of the error codes land. Simplifying property across different APIs. Don’t overload error codes to represent similar but not the same errors. Exception handling is coming. A possible approach is to use unwinding. I think that for WASI, errors work better. If languages want to use unwinding, they can expect errors and unwind. I think using variants instead of exceptions will work well for us. + +**Pat Hickey:** The one thing I’ll call out is that proc_exit should be implemented as unwind. + +**Dan Gohman:** That’s true. I’m going to claim that proc_exit is special. It might be something that we unwind and then turn into a clean exit status. Then the unwinding becomes an implementation detail. That wouldn’t be a thing that leaks across module boundaries. Often not a good idea for libraries to call exit directly. + +**Pat Hickey:** So we basically get rid of proc_exit as a library function + +**Dan Gohman:** So I think what we want to say is return type from main is an error type. + +**Pat Hickey:** Yeah, that way we keep types all the way down and don’t turn into bare integer. + +**Dan Gohman:** Yeah, so 3 error types. Return values, unwinding, and trapping. Trapping is for program has a bug. Maybe sometimes when return values. ____. And we’ll use unwinding across language boundaries. + +**Pat Hickey:** Unlike with errors, we can’t invent new ways to trap. + +**Dan Gohman:** Although I wonder if there’s something we could do there. I wonder if it makes sense for wasm to be able to trap with extra info. + +**Luke Wagner:** Or there could be a WASI function that says “I’m going to trap, but you can provide me with an error to print” + +**Pat Hickey:** You can imagine that a malicious module would do that + +**Luke Wagner:** They can do that already. We don’t want wasm to casually be able to catch traps. Because at a very fine granularity. But having a blast zone that allows a set to go away without taking down the rest. I think that belongs at some point of time in wasm’s future. + +**Dan Gohman:** yeah, if we add those mechanisms, then programmer errors could just be trapped. + +**Lin Clark:** Best way to collaborate + +**Dan Gohman:** Once we’ve fully modularized, each module will audit their own errors. The wasi-libc work will start after the next snapshot which includes those changes. + +**Andrew Brown:** Question about sockets. Who’s driving that + +**Dan Gohman:** Haven’t heard from them. Don’t know what their status is. Expect that if they don’t respond soon we’ll find someone else + +**Andrew Brown:** Who was originally driving it? + +**Dan Gohman:** Somebody working for a company called ____. The person who filed it is the person working there. + +**Andrew Brown:** Radu, was someone on your side interested in that? + +**Radu Matei:** We should probably have a chat at some point. How will that relate to these changes? + +**Dan Gohman:** Sockets are the other major user of errno. I expect sockets will have their own errno, and then wasi-libc will have some way to concatenate errnos and turn it into appropriate POSIX errno space. I think that’s basically it. + +**Radu Matei:** How about IO Streams? + +**Dan Gohman:** We haven’t talked about how it’s going to work with libc. I expect from a POSIX point of view, we might have a bunch of different error codes in wasi-io. Have been talking about wasi-io not reporting very specific errors because it leaks information. We aren’t necessarily going to want to return a lot of detail there either. + +**Ralph Squillace:** I think we want to try to figure out, if we help pick up the PR, what’s the best way to move forward without having to reimplement too much. Will reach out to original champion. + +**Dan Gohman:** I see wasi-filesystem and wasi-sockets being peers. At a good place for them to work the same way. From b0b9aa4274b1aabd0752d0af0511044eef636e72 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 1 Mar 2021 15:37:45 -0500 Subject: [PATCH 0880/1772] Add 03-11 agenda --- proposals/clocks/meetings/2021/WASI-03-11.md | 32 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 3 ++ 2 files changed, 35 insertions(+) create mode 100644 proposals/clocks/meetings/2021/WASI-03-11.md diff --git a/proposals/clocks/meetings/2021/WASI-03-11.md b/proposals/clocks/meetings/2021/WASI-03-11.md new file mode 100644 index 000000000..f6170a738 --- /dev/null +++ b/proposals/clocks/meetings/2021/WASI-03-11.md @@ -0,0 +1,32 @@ +![WASI logo](/WASI.png) + +## Agenda for the March 11 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: March 11, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. Presentation: Passing capabilities into programs with Typed Main (Dan Gohman) + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 3436863ab..54e106ca1 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -48,3 +48,6 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow ### 2021 * [WASI January 14th video call](2021/WASI-01-14.md) * [WASI January 28th video call](2021/WASI-01-28.md) + * [WASI February 11th video call](2021/WASI-02-11.md) + * [WASI February 25th video call](2021/WASI-02-25.md) + * [WASI March 11th video call](2021/WASI-03-11.md) From 316881932d10a695bae9f56228a65f5f7362bad9 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 1 Mar 2021 15:37:45 -0500 Subject: [PATCH 0881/1772] Add 03-11 agenda --- proposals/random/meetings/2021/WASI-03-11.md | 32 ++++++++++++++++++++ proposals/random/meetings/README.md | 3 ++ 2 files changed, 35 insertions(+) create mode 100644 proposals/random/meetings/2021/WASI-03-11.md diff --git a/proposals/random/meetings/2021/WASI-03-11.md b/proposals/random/meetings/2021/WASI-03-11.md new file mode 100644 index 000000000..f6170a738 --- /dev/null +++ b/proposals/random/meetings/2021/WASI-03-11.md @@ -0,0 +1,32 @@ +![WASI logo](/WASI.png) + +## Agenda for the March 11 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: March 11, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. Presentation: Passing capabilities into programs with Typed Main (Dan Gohman) + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 3436863ab..54e106ca1 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -48,3 +48,6 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow ### 2021 * [WASI January 14th video call](2021/WASI-01-14.md) * [WASI January 28th video call](2021/WASI-01-28.md) + * [WASI February 11th video call](2021/WASI-02-11.md) + * [WASI February 25th video call](2021/WASI-02-25.md) + * [WASI March 11th video call](2021/WASI-03-11.md) From e272aaf1a08cf0540f69e2cf9cc672cf7e7dc4d4 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 1 Mar 2021 15:37:45 -0500 Subject: [PATCH 0882/1772] Add 03-11 agenda --- .../filesystem/meetings/2021/WASI-03-11.md | 32 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 3 ++ 2 files changed, 35 insertions(+) create mode 100644 proposals/filesystem/meetings/2021/WASI-03-11.md diff --git a/proposals/filesystem/meetings/2021/WASI-03-11.md b/proposals/filesystem/meetings/2021/WASI-03-11.md new file mode 100644 index 000000000..f6170a738 --- /dev/null +++ b/proposals/filesystem/meetings/2021/WASI-03-11.md @@ -0,0 +1,32 @@ +![WASI logo](/WASI.png) + +## Agenda for the March 11 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: March 11, 17:00-18:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. Presentation: Passing capabilities into programs with Typed Main (Dan Gohman) + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 3436863ab..54e106ca1 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -48,3 +48,6 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow ### 2021 * [WASI January 14th video call](2021/WASI-01-14.md) * [WASI January 28th video call](2021/WASI-01-28.md) + * [WASI February 11th video call](2021/WASI-02-11.md) + * [WASI February 25th video call](2021/WASI-02-25.md) + * [WASI March 11th video call](2021/WASI-03-11.md) From 5d0750211a4ecb2f69468e62bbe681b057f02282 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 1 Mar 2021 17:13:36 -0500 Subject: [PATCH 0883/1772] Add stub agendas for Q2 2021 --- proposals/clocks/meetings/2021/WASI-03-25.md | 31 ++++++++++++++++++++ proposals/clocks/meetings/2021/WASI-04-08.md | 31 ++++++++++++++++++++ proposals/clocks/meetings/2021/WASI-04-22.md | 31 ++++++++++++++++++++ proposals/clocks/meetings/2021/WASI-05-06.md | 31 ++++++++++++++++++++ proposals/clocks/meetings/2021/WASI-05-20.md | 31 ++++++++++++++++++++ proposals/clocks/meetings/2021/WASI-06-03.md | 31 ++++++++++++++++++++ proposals/clocks/meetings/2021/WASI-06-17.md | 31 ++++++++++++++++++++ proposals/clocks/meetings/README.md | 8 +++++ 8 files changed, 225 insertions(+) create mode 100644 proposals/clocks/meetings/2021/WASI-03-25.md create mode 100644 proposals/clocks/meetings/2021/WASI-04-08.md create mode 100644 proposals/clocks/meetings/2021/WASI-04-22.md create mode 100644 proposals/clocks/meetings/2021/WASI-05-06.md create mode 100644 proposals/clocks/meetings/2021/WASI-05-20.md create mode 100644 proposals/clocks/meetings/2021/WASI-06-03.md create mode 100644 proposals/clocks/meetings/2021/WASI-06-17.md diff --git a/proposals/clocks/meetings/2021/WASI-03-25.md b/proposals/clocks/meetings/2021/WASI-03-25.md new file mode 100644 index 000000000..a35f4e17e --- /dev/null +++ b/proposals/clocks/meetings/2021/WASI-03-25.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the March 25 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: March 25, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/2021/WASI-04-08.md b/proposals/clocks/meetings/2021/WASI-04-08.md new file mode 100644 index 000000000..35d2286f9 --- /dev/null +++ b/proposals/clocks/meetings/2021/WASI-04-08.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the April 8 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: April 8, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/2021/WASI-04-22.md b/proposals/clocks/meetings/2021/WASI-04-22.md new file mode 100644 index 000000000..722d57ca0 --- /dev/null +++ b/proposals/clocks/meetings/2021/WASI-04-22.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the April 22 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: April 22, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/2021/WASI-05-06.md b/proposals/clocks/meetings/2021/WASI-05-06.md new file mode 100644 index 000000000..da5cf7cbb --- /dev/null +++ b/proposals/clocks/meetings/2021/WASI-05-06.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 6 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 6, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/2021/WASI-05-20.md b/proposals/clocks/meetings/2021/WASI-05-20.md new file mode 100644 index 000000000..c91e5777f --- /dev/null +++ b/proposals/clocks/meetings/2021/WASI-05-20.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 20 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 20, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/2021/WASI-06-03.md b/proposals/clocks/meetings/2021/WASI-06-03.md new file mode 100644 index 000000000..89487782a --- /dev/null +++ b/proposals/clocks/meetings/2021/WASI-06-03.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the June 3 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: June 3, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/2021/WASI-06-17.md b/proposals/clocks/meetings/2021/WASI-06-17.md new file mode 100644 index 000000000..583b7f02b --- /dev/null +++ b/proposals/clocks/meetings/2021/WASI-06-17.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the June 17 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: June 17, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md index 54e106ca1..a9fcf2e21 100644 --- a/proposals/clocks/meetings/README.md +++ b/proposals/clocks/meetings/README.md @@ -51,3 +51,11 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI February 11th video call](2021/WASI-02-11.md) * [WASI February 25th video call](2021/WASI-02-25.md) * [WASI March 11th video call](2021/WASI-03-11.md) + * [WASI March 25th video call](2021/WASI-03-25.md) + * [WASI April 8th video call](2021/WASI-04-08.md) + * [WASI April 22nd video call](2021/WASI-04-22.md) + * [WASI May 6th video call](2021/WASI-05-06.md) + * [WASI May 20th video call](2021/WASI-05-20.md) + * [WASI June 3rd video call](2021/WASI-06-03.md) + * [WASI June 17th video call](2021/WASI-06-17.md) + \ No newline at end of file From 41d1e833eb57371649ee19903d501917e3676bb0 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 1 Mar 2021 17:13:36 -0500 Subject: [PATCH 0884/1772] Add stub agendas for Q2 2021 --- proposals/random/meetings/2021/WASI-03-25.md | 31 ++++++++++++++++++++ proposals/random/meetings/2021/WASI-04-08.md | 31 ++++++++++++++++++++ proposals/random/meetings/2021/WASI-04-22.md | 31 ++++++++++++++++++++ proposals/random/meetings/2021/WASI-05-06.md | 31 ++++++++++++++++++++ proposals/random/meetings/2021/WASI-05-20.md | 31 ++++++++++++++++++++ proposals/random/meetings/2021/WASI-06-03.md | 31 ++++++++++++++++++++ proposals/random/meetings/2021/WASI-06-17.md | 31 ++++++++++++++++++++ proposals/random/meetings/README.md | 8 +++++ 8 files changed, 225 insertions(+) create mode 100644 proposals/random/meetings/2021/WASI-03-25.md create mode 100644 proposals/random/meetings/2021/WASI-04-08.md create mode 100644 proposals/random/meetings/2021/WASI-04-22.md create mode 100644 proposals/random/meetings/2021/WASI-05-06.md create mode 100644 proposals/random/meetings/2021/WASI-05-20.md create mode 100644 proposals/random/meetings/2021/WASI-06-03.md create mode 100644 proposals/random/meetings/2021/WASI-06-17.md diff --git a/proposals/random/meetings/2021/WASI-03-25.md b/proposals/random/meetings/2021/WASI-03-25.md new file mode 100644 index 000000000..a35f4e17e --- /dev/null +++ b/proposals/random/meetings/2021/WASI-03-25.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the March 25 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: March 25, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/2021/WASI-04-08.md b/proposals/random/meetings/2021/WASI-04-08.md new file mode 100644 index 000000000..35d2286f9 --- /dev/null +++ b/proposals/random/meetings/2021/WASI-04-08.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the April 8 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: April 8, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/2021/WASI-04-22.md b/proposals/random/meetings/2021/WASI-04-22.md new file mode 100644 index 000000000..722d57ca0 --- /dev/null +++ b/proposals/random/meetings/2021/WASI-04-22.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the April 22 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: April 22, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/2021/WASI-05-06.md b/proposals/random/meetings/2021/WASI-05-06.md new file mode 100644 index 000000000..da5cf7cbb --- /dev/null +++ b/proposals/random/meetings/2021/WASI-05-06.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 6 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 6, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/2021/WASI-05-20.md b/proposals/random/meetings/2021/WASI-05-20.md new file mode 100644 index 000000000..c91e5777f --- /dev/null +++ b/proposals/random/meetings/2021/WASI-05-20.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 20 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 20, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/2021/WASI-06-03.md b/proposals/random/meetings/2021/WASI-06-03.md new file mode 100644 index 000000000..89487782a --- /dev/null +++ b/proposals/random/meetings/2021/WASI-06-03.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the June 3 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: June 3, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/2021/WASI-06-17.md b/proposals/random/meetings/2021/WASI-06-17.md new file mode 100644 index 000000000..583b7f02b --- /dev/null +++ b/proposals/random/meetings/2021/WASI-06-17.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the June 17 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: June 17, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md index 54e106ca1..a9fcf2e21 100644 --- a/proposals/random/meetings/README.md +++ b/proposals/random/meetings/README.md @@ -51,3 +51,11 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI February 11th video call](2021/WASI-02-11.md) * [WASI February 25th video call](2021/WASI-02-25.md) * [WASI March 11th video call](2021/WASI-03-11.md) + * [WASI March 25th video call](2021/WASI-03-25.md) + * [WASI April 8th video call](2021/WASI-04-08.md) + * [WASI April 22nd video call](2021/WASI-04-22.md) + * [WASI May 6th video call](2021/WASI-05-06.md) + * [WASI May 20th video call](2021/WASI-05-20.md) + * [WASI June 3rd video call](2021/WASI-06-03.md) + * [WASI June 17th video call](2021/WASI-06-17.md) + \ No newline at end of file From 1980ec0025e09caa5898bf356b7610c283c9b57e Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 1 Mar 2021 17:13:36 -0500 Subject: [PATCH 0885/1772] Add stub agendas for Q2 2021 --- .../filesystem/meetings/2021/WASI-03-25.md | 31 +++++++++++++++++++ .../filesystem/meetings/2021/WASI-04-08.md | 31 +++++++++++++++++++ .../filesystem/meetings/2021/WASI-04-22.md | 31 +++++++++++++++++++ .../filesystem/meetings/2021/WASI-05-06.md | 31 +++++++++++++++++++ .../filesystem/meetings/2021/WASI-05-20.md | 31 +++++++++++++++++++ .../filesystem/meetings/2021/WASI-06-03.md | 31 +++++++++++++++++++ .../filesystem/meetings/2021/WASI-06-17.md | 31 +++++++++++++++++++ proposals/filesystem/meetings/README.md | 8 +++++ 8 files changed, 225 insertions(+) create mode 100644 proposals/filesystem/meetings/2021/WASI-03-25.md create mode 100644 proposals/filesystem/meetings/2021/WASI-04-08.md create mode 100644 proposals/filesystem/meetings/2021/WASI-04-22.md create mode 100644 proposals/filesystem/meetings/2021/WASI-05-06.md create mode 100644 proposals/filesystem/meetings/2021/WASI-05-20.md create mode 100644 proposals/filesystem/meetings/2021/WASI-06-03.md create mode 100644 proposals/filesystem/meetings/2021/WASI-06-17.md diff --git a/proposals/filesystem/meetings/2021/WASI-03-25.md b/proposals/filesystem/meetings/2021/WASI-03-25.md new file mode 100644 index 000000000..a35f4e17e --- /dev/null +++ b/proposals/filesystem/meetings/2021/WASI-03-25.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the March 25 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: March 25, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/2021/WASI-04-08.md b/proposals/filesystem/meetings/2021/WASI-04-08.md new file mode 100644 index 000000000..35d2286f9 --- /dev/null +++ b/proposals/filesystem/meetings/2021/WASI-04-08.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the April 8 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: April 8, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/2021/WASI-04-22.md b/proposals/filesystem/meetings/2021/WASI-04-22.md new file mode 100644 index 000000000..722d57ca0 --- /dev/null +++ b/proposals/filesystem/meetings/2021/WASI-04-22.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the April 22 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: April 22, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/2021/WASI-05-06.md b/proposals/filesystem/meetings/2021/WASI-05-06.md new file mode 100644 index 000000000..da5cf7cbb --- /dev/null +++ b/proposals/filesystem/meetings/2021/WASI-05-06.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 6 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 6, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/2021/WASI-05-20.md b/proposals/filesystem/meetings/2021/WASI-05-20.md new file mode 100644 index 000000000..c91e5777f --- /dev/null +++ b/proposals/filesystem/meetings/2021/WASI-05-20.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the May 20 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: May 20, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/2021/WASI-06-03.md b/proposals/filesystem/meetings/2021/WASI-06-03.md new file mode 100644 index 000000000..89487782a --- /dev/null +++ b/proposals/filesystem/meetings/2021/WASI-06-03.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the June 3 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: June 3, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/2021/WASI-06-17.md b/proposals/filesystem/meetings/2021/WASI-06-17.md new file mode 100644 index 000000000..583b7f02b --- /dev/null +++ b/proposals/filesystem/meetings/2021/WASI-06-17.md @@ -0,0 +1,31 @@ +![WASI logo](/WASI.png) + +## Agenda for the June 17 video call of WASI Subgroup + +- **Where**: zoom.us +- **When**: June 17, 16:00-17:00 UTC +- **Location**: *link on calendar invite* +- **Contact**: + - Name: Lin Clark + - Email: lclark@fastly.com + +### Registration + +None required if you've attended before. Email Lin Clark to sign up if it's your first time. + +The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). + +## Logistics + +The meeting will be on a zoom.us video conference. + +## Agenda items + +1. Opening, welcome and roll call + 1. Please help add your name to the meeting notes. + 1. Please help take notes. + 1. Thanks! +1. Announcements + 1. _Sumbit a PR to add your announcement here_ +1. Proposals and discussions + 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md index 54e106ca1..a9fcf2e21 100644 --- a/proposals/filesystem/meetings/README.md +++ b/proposals/filesystem/meetings/README.md @@ -51,3 +51,11 @@ Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow * [WASI February 11th video call](2021/WASI-02-11.md) * [WASI February 25th video call](2021/WASI-02-25.md) * [WASI March 11th video call](2021/WASI-03-11.md) + * [WASI March 25th video call](2021/WASI-03-25.md) + * [WASI April 8th video call](2021/WASI-04-08.md) + * [WASI April 22nd video call](2021/WASI-04-22.md) + * [WASI May 6th video call](2021/WASI-05-06.md) + * [WASI May 20th video call](2021/WASI-05-20.md) + * [WASI June 3rd video call](2021/WASI-06-03.md) + * [WASI June 17th video call](2021/WASI-06-17.md) + \ No newline at end of file From b67d25b9364987e60bd20afb323daa5b5e7ded0b Mon Sep 17 00:00:00 2001 From: Yonggang Luo Date: Tue, 2 Mar 2021 18:02:51 +0000 Subject: [PATCH 0886/1772] rename main to master for broken link (#406) --- proposals/clocks/docs/Proposals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/docs/Proposals.md b/proposals/clocks/docs/Proposals.md index 854467222..31c565b2e 100644 --- a/proposals/clocks/docs/Proposals.md +++ b/proposals/clocks/docs/Proposals.md @@ -6,7 +6,7 @@ adoption of this process and so don't fit exactly into the defined phases, however our intention is to align them going forward. [WASI]: https://github.com/WebAssembly/WASI -[proposals page]: https://github.com/WebAssembly/proposals/blob/main/README.md +[proposals page]: https://github.com/WebAssembly/proposals/blob/master/README.md ## Active proposals From 89711156b411857dcf2fa4d91993feeed10cd88b Mon Sep 17 00:00:00 2001 From: Yonggang Luo Date: Tue, 2 Mar 2021 18:02:51 +0000 Subject: [PATCH 0887/1772] rename main to master for broken link (#406) --- proposals/random/docs/Proposals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/docs/Proposals.md b/proposals/random/docs/Proposals.md index 854467222..31c565b2e 100644 --- a/proposals/random/docs/Proposals.md +++ b/proposals/random/docs/Proposals.md @@ -6,7 +6,7 @@ adoption of this process and so don't fit exactly into the defined phases, however our intention is to align them going forward. [WASI]: https://github.com/WebAssembly/WASI -[proposals page]: https://github.com/WebAssembly/proposals/blob/main/README.md +[proposals page]: https://github.com/WebAssembly/proposals/blob/master/README.md ## Active proposals From b13f99d97f30fd49564b8838afb5800cc421b0fc Mon Sep 17 00:00:00 2001 From: Yonggang Luo Date: Tue, 2 Mar 2021 18:02:51 +0000 Subject: [PATCH 0888/1772] rename main to master for broken link (#406) --- proposals/filesystem/docs/Proposals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/docs/Proposals.md b/proposals/filesystem/docs/Proposals.md index 854467222..31c565b2e 100644 --- a/proposals/filesystem/docs/Proposals.md +++ b/proposals/filesystem/docs/Proposals.md @@ -6,7 +6,7 @@ adoption of this process and so don't fit exactly into the defined phases, however our intention is to align them going forward. [WASI]: https://github.com/WebAssembly/WASI -[proposals page]: https://github.com/WebAssembly/proposals/blob/main/README.md +[proposals page]: https://github.com/WebAssembly/proposals/blob/master/README.md ## Active proposals From 9cf7413869498b8c5d488bb6f849ad0755e67171 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 9 Mar 2021 10:20:44 -0800 Subject: [PATCH 0889/1772] Disallow non-portable and signal values as exit statuses. (#235) * Disallow non-portable and signal values as exit statuses. Exit codes of at least 256 aren't portable to [POSIX exit], so programs expecting to return full 32-bit [Windows System Error Codes] aren't practically portable. And on POSIX, error codes of at least 128 are reserved for reporting program exits via signals, and 127 and 126 are reserved for POSIX-style shells. While it's theoretically possible for POSIX applications to return these explicitly, this is very rare, not often useful, particularly in programs intended to be portable, and could potentially be confusing to users. If a need arrises for programs to return values in [126,256), or to provide other kinds of information upon program exit, we can look at relaxing these restrictions or adding new APIs to WASI for program termination, but for now it makes sense to start with something simple. With that, this PR proposes: - The WASI `exit` function takes a `u8`, but if the value is at least 126, it traps. Otherwise it is provided to the environment. - WASI libc's `exit` will map from `int` to `u8` by applying the mask as specified in [POSIX exit]. No other WASI syscalls trap right now, but `exit` has no other way to indicate errors. [POSIX exit]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/_Exit.html [Windows System Error Codes]: https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes?redirectedfrom=MSDN#system-error-codes * Update the docs. * Say "or greater" instead of "at least". Co-authored-by: Dan Gohman --- proposals/clocks/phases/ephemeral/docs.md | 9 ++++++--- .../clocks/phases/ephemeral/witx/typenames.witx | 14 ++++++++++++-- .../phases/ephemeral/witx/wasi_ephemeral_proc.witx | 9 ++++++--- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index e7a3aa91b..555d74e27 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -2389,9 +2389,12 @@ The number of events stored. --- #### `exit(rval: exitcode)` -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. +Terminate the process normally. An exit code of `$exitcode::success` +reports successful completion of the program. An exit code of +`$exitcode::failure` or any other value less than 126 reports a +failure, and the value is provided to the environment. If a value +of 126 or greater is given, this function behaves as if it were +implemented by an `unreachable` instruction. ##### Params - `rval`: [`exitcode`](#exitcode) diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx index 1f9abc59b..bbd6489df 100644 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ b/proposals/clocks/phases/ephemeral/witx/typenames.witx @@ -638,8 +638,18 @@ ) ) -;;; Exit code generated by a process when exiting. -(typename $exitcode u32) +;;; Exit code generated by a program when exiting. +(typename $exitcode u8) + +;;; Indicate the program exited successfully. +;;; +;;; Note: This is similar to `EXIT_SUCCESS` in POSIX. +(@witx const $exitcode $success 0) + +;;; Indicate the program exited unsuccessfully. +;;; +;;; Note: This is similar to `EXIT_FAILURE` in POSIX. +(@witx const $exitcode $failure 1) ;;; Flags provided to `sock_recv`. (typename $riflags diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx index 0507d4ff7..0bd57682d 100644 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx +++ b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx @@ -8,9 +8,12 @@ (use "typenames.witx") (module $wasi_ephemeral_proc - ;;; Terminate the process normally. An exit code of 0 indicates successful - ;;; termination of the program. The meanings of other values is dependent on - ;;; the environment. + ;;; Terminate the process normally. An exit code of `$exitcode::success` + ;;; reports successful completion of the program. An exit code of + ;;; `$exitcode::failure` or any other value less than 126 reports a + ;;; failure, and the value is provided to the environment. If a value + ;;; of 126 or greater is given, this function behaves as if it were + ;;; implemented by an `unreachable` instruction. (@interface func (export "exit") ;;; The exit code returned by the process. (param $rval $exitcode) From 98725082763779426bdede45d431971111fb623f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 9 Mar 2021 10:20:44 -0800 Subject: [PATCH 0890/1772] Disallow non-portable and signal values as exit statuses. (#235) * Disallow non-portable and signal values as exit statuses. Exit codes of at least 256 aren't portable to [POSIX exit], so programs expecting to return full 32-bit [Windows System Error Codes] aren't practically portable. And on POSIX, error codes of at least 128 are reserved for reporting program exits via signals, and 127 and 126 are reserved for POSIX-style shells. While it's theoretically possible for POSIX applications to return these explicitly, this is very rare, not often useful, particularly in programs intended to be portable, and could potentially be confusing to users. If a need arrises for programs to return values in [126,256), or to provide other kinds of information upon program exit, we can look at relaxing these restrictions or adding new APIs to WASI for program termination, but for now it makes sense to start with something simple. With that, this PR proposes: - The WASI `exit` function takes a `u8`, but if the value is at least 126, it traps. Otherwise it is provided to the environment. - WASI libc's `exit` will map from `int` to `u8` by applying the mask as specified in [POSIX exit]. No other WASI syscalls trap right now, but `exit` has no other way to indicate errors. [POSIX exit]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/_Exit.html [Windows System Error Codes]: https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes?redirectedfrom=MSDN#system-error-codes * Update the docs. * Say "or greater" instead of "at least". Co-authored-by: Dan Gohman --- proposals/random/phases/ephemeral/docs.md | 9 ++++++--- .../random/phases/ephemeral/witx/typenames.witx | 14 ++++++++++++-- .../phases/ephemeral/witx/wasi_ephemeral_proc.witx | 9 ++++++--- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index e7a3aa91b..555d74e27 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -2389,9 +2389,12 @@ The number of events stored. --- #### `exit(rval: exitcode)` -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. +Terminate the process normally. An exit code of `$exitcode::success` +reports successful completion of the program. An exit code of +`$exitcode::failure` or any other value less than 126 reports a +failure, and the value is provided to the environment. If a value +of 126 or greater is given, this function behaves as if it were +implemented by an `unreachable` instruction. ##### Params - `rval`: [`exitcode`](#exitcode) diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx index 1f9abc59b..bbd6489df 100644 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ b/proposals/random/phases/ephemeral/witx/typenames.witx @@ -638,8 +638,18 @@ ) ) -;;; Exit code generated by a process when exiting. -(typename $exitcode u32) +;;; Exit code generated by a program when exiting. +(typename $exitcode u8) + +;;; Indicate the program exited successfully. +;;; +;;; Note: This is similar to `EXIT_SUCCESS` in POSIX. +(@witx const $exitcode $success 0) + +;;; Indicate the program exited unsuccessfully. +;;; +;;; Note: This is similar to `EXIT_FAILURE` in POSIX. +(@witx const $exitcode $failure 1) ;;; Flags provided to `sock_recv`. (typename $riflags diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx index 0507d4ff7..0bd57682d 100644 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx +++ b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx @@ -8,9 +8,12 @@ (use "typenames.witx") (module $wasi_ephemeral_proc - ;;; Terminate the process normally. An exit code of 0 indicates successful - ;;; termination of the program. The meanings of other values is dependent on - ;;; the environment. + ;;; Terminate the process normally. An exit code of `$exitcode::success` + ;;; reports successful completion of the program. An exit code of + ;;; `$exitcode::failure` or any other value less than 126 reports a + ;;; failure, and the value is provided to the environment. If a value + ;;; of 126 or greater is given, this function behaves as if it were + ;;; implemented by an `unreachable` instruction. (@interface func (export "exit") ;;; The exit code returned by the process. (param $rval $exitcode) From 165801a0c74297331968f55bf11c780549c9fa58 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 9 Mar 2021 10:20:44 -0800 Subject: [PATCH 0891/1772] Disallow non-portable and signal values as exit statuses. (#235) * Disallow non-portable and signal values as exit statuses. Exit codes of at least 256 aren't portable to [POSIX exit], so programs expecting to return full 32-bit [Windows System Error Codes] aren't practically portable. And on POSIX, error codes of at least 128 are reserved for reporting program exits via signals, and 127 and 126 are reserved for POSIX-style shells. While it's theoretically possible for POSIX applications to return these explicitly, this is very rare, not often useful, particularly in programs intended to be portable, and could potentially be confusing to users. If a need arrises for programs to return values in [126,256), or to provide other kinds of information upon program exit, we can look at relaxing these restrictions or adding new APIs to WASI for program termination, but for now it makes sense to start with something simple. With that, this PR proposes: - The WASI `exit` function takes a `u8`, but if the value is at least 126, it traps. Otherwise it is provided to the environment. - WASI libc's `exit` will map from `int` to `u8` by applying the mask as specified in [POSIX exit]. No other WASI syscalls trap right now, but `exit` has no other way to indicate errors. [POSIX exit]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/_Exit.html [Windows System Error Codes]: https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes?redirectedfrom=MSDN#system-error-codes * Update the docs. * Say "or greater" instead of "at least". Co-authored-by: Dan Gohman --- proposals/filesystem/phases/ephemeral/docs.md | 9 ++++++--- .../phases/ephemeral/witx/typenames.witx | 14 ++++++++++++-- .../phases/ephemeral/witx/wasi_ephemeral_proc.witx | 9 ++++++--- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index e7a3aa91b..555d74e27 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -2389,9 +2389,12 @@ The number of events stored. --- #### `exit(rval: exitcode)` -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. +Terminate the process normally. An exit code of `$exitcode::success` +reports successful completion of the program. An exit code of +`$exitcode::failure` or any other value less than 126 reports a +failure, and the value is provided to the environment. If a value +of 126 or greater is given, this function behaves as if it were +implemented by an `unreachable` instruction. ##### Params - `rval`: [`exitcode`](#exitcode) diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx index 1f9abc59b..bbd6489df 100644 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ b/proposals/filesystem/phases/ephemeral/witx/typenames.witx @@ -638,8 +638,18 @@ ) ) -;;; Exit code generated by a process when exiting. -(typename $exitcode u32) +;;; Exit code generated by a program when exiting. +(typename $exitcode u8) + +;;; Indicate the program exited successfully. +;;; +;;; Note: This is similar to `EXIT_SUCCESS` in POSIX. +(@witx const $exitcode $success 0) + +;;; Indicate the program exited unsuccessfully. +;;; +;;; Note: This is similar to `EXIT_FAILURE` in POSIX. +(@witx const $exitcode $failure 1) ;;; Flags provided to `sock_recv`. (typename $riflags diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx index 0507d4ff7..0bd57682d 100644 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx +++ b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx @@ -8,9 +8,12 @@ (use "typenames.witx") (module $wasi_ephemeral_proc - ;;; Terminate the process normally. An exit code of 0 indicates successful - ;;; termination of the program. The meanings of other values is dependent on - ;;; the environment. + ;;; Terminate the process normally. An exit code of `$exitcode::success` + ;;; reports successful completion of the program. An exit code of + ;;; `$exitcode::failure` or any other value less than 126 reports a + ;;; failure, and the value is provided to the environment. If a value + ;;; of 126 or greater is given, this function behaves as if it were + ;;; implemented by an `unreachable` instruction. (@interface func (export "exit") ;;; The exit code returned by the process. (param $rval $exitcode) From 0ef89976a9383cb78b4d5710f5c59b3ce2e8417c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 9 Mar 2021 13:42:13 -0800 Subject: [PATCH 0892/1772] Regenerate the docs. (#407) It appears I didn't fully regenerate the docs after merging #235. This runs the tools/repo_docs.sh script to regenerate them. --- proposals/random/phases/ephemeral/docs.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md index 555d74e27..f29d401c4 100644 --- a/proposals/random/phases/ephemeral/docs.md +++ b/proposals/random/phases/ephemeral/docs.md @@ -1098,12 +1098,17 @@ The type of the event to which to subscribe, and the contents of the subscriptio Offset: 8 -## `exitcode`: `u32` -Exit code generated by a process when exiting. +## `exitcode`: `u8` +Exit code generated by a program when exiting. -Size: 4 +Size: 1 -Alignment: 4 +Alignment: 1 + +### Constants +- `success` + +- `failure` ## `riflags`: `Record` Flags provided to `sock_recv`. From 1ac5bc34bc059d36716a910b918588fde85b8464 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 9 Mar 2021 13:42:13 -0800 Subject: [PATCH 0893/1772] Regenerate the docs. (#407) It appears I didn't fully regenerate the docs after merging #235. This runs the tools/repo_docs.sh script to regenerate them. --- proposals/clocks/phases/ephemeral/docs.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md index 555d74e27..f29d401c4 100644 --- a/proposals/clocks/phases/ephemeral/docs.md +++ b/proposals/clocks/phases/ephemeral/docs.md @@ -1098,12 +1098,17 @@ The type of the event to which to subscribe, and the contents of the subscriptio Offset: 8 -## `exitcode`: `u32` -Exit code generated by a process when exiting. +## `exitcode`: `u8` +Exit code generated by a program when exiting. -Size: 4 +Size: 1 -Alignment: 4 +Alignment: 1 + +### Constants +- `success` + +- `failure` ## `riflags`: `Record` Flags provided to `sock_recv`. From c96a143626d28d4e997afadfa8fb1725e758fad3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 9 Mar 2021 13:52:37 -0800 Subject: [PATCH 0894/1772] Update the message that says how to regenerate the docs. (#408) * Update the message that says how to regenerate the docs. * rustfmt --- proposals/random/tools/witx/cli/src/main.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/proposals/random/tools/witx/cli/src/main.rs b/proposals/random/tools/witx/cli/src/main.rs index bd1d38dc8..bdb1c6a9c 100644 --- a/proposals/random/tools/witx/cli/src/main.rs +++ b/proposals/random/tools/witx/cli/src/main.rs @@ -262,9 +262,7 @@ fn diff_against_filesystem(expected: &str, path: &Path) -> Result<(), ()> { } eprintln!(); - eprintln!( - "To regenerate the files, run `cd tools/witx && cargo run --example witx repo-docs`." - ); + eprintln!("To regenerate the files, run `tools/repo_docs.sh`."); eprintln!(); Err(()) } From d6901712995534e54d4d4e7f6afe6340b9b32fc3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 9 Mar 2021 13:52:37 -0800 Subject: [PATCH 0895/1772] Update the message that says how to regenerate the docs. (#408) * Update the message that says how to regenerate the docs. * rustfmt --- proposals/clocks/tools/witx/cli/src/main.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/proposals/clocks/tools/witx/cli/src/main.rs b/proposals/clocks/tools/witx/cli/src/main.rs index bd1d38dc8..bdb1c6a9c 100644 --- a/proposals/clocks/tools/witx/cli/src/main.rs +++ b/proposals/clocks/tools/witx/cli/src/main.rs @@ -262,9 +262,7 @@ fn diff_against_filesystem(expected: &str, path: &Path) -> Result<(), ()> { } eprintln!(); - eprintln!( - "To regenerate the files, run `cd tools/witx && cargo run --example witx repo-docs`." - ); + eprintln!("To regenerate the files, run `tools/repo_docs.sh`."); eprintln!(); Err(()) } From f7236cfbb33f870da3f9baf23af1157cd0583a26 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 9 Mar 2021 12:23:57 -0800 Subject: [PATCH 0896/1772] Update and rebase on WASI main. As part of the move to modularize WASI, I've now reset the `main` branch in this repository to be the same as that if the [`WASI` repository], and this is now a PR on top of that. This implements the directory structure described in WebAssembly/WASI#360, with a standard directory, and a wasi-clocks directory under that. [`WASI` repository]: https://github.com/WebAssembly/WASI/ --- .../standard/wasi-random/witx/typenames.witx | 708 ++++++++++++++++++ .../witx/wasi_ephemeral_random.witx | 26 + 2 files changed, 734 insertions(+) create mode 100644 proposals/random/standard/wasi-random/witx/typenames.witx create mode 100644 proposals/random/standard/wasi-random/witx/wasi_ephemeral_random.witx diff --git a/proposals/random/standard/wasi-random/witx/typenames.witx b/proposals/random/standard/wasi-random/witx/typenames.witx new file mode 100644 index 000000000..bbd6489df --- /dev/null +++ b/proposals/random/standard/wasi-random/witx/typenames.witx @@ -0,0 +1,708 @@ +;; Type names used by low-level WASI interfaces. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +;;; An array size. +;;; +;;; Note: This is similar to `size_t` in POSIX. +(typename $size (@witx usize)) + +;;; Non-negative file size or length of a region within a file. +(typename $filesize u64) + +;;; Timestamp in nanoseconds. +(typename $timestamp u64) + +;;; Identifiers for clocks. +(typename $clockid + (enum (@witx tag u32) + ;;; The clock measuring real time. Time value zero corresponds with + ;;; 1970-01-01T00:00:00Z. + $realtime + ;;; The store-wide monotonic clock, which is defined as a clock measuring + ;;; real time, whose value cannot be adjusted and which cannot have negative + ;;; clock jumps. The epoch of this clock is undefined. The absolute time + ;;; value of this clock therefore has no meaning. + $monotonic + ) +) + +;;; Error codes returned by functions. +;;; Not all of these error codes are returned by the functions provided by this +;;; API; some are used in higher-level library layers, and others are provided +;;; merely for alignment with POSIX. +(typename $errno + (enum (@witx tag u16) + ;;; No error occurred. System call completed successfully. + $success + ;;; Argument list too long. + $2big + ;;; Permission denied. + $access + ;;; Address in use. + $addrinuse + ;;; Address not available. + $addrnotavail + ;;; Address family not supported. + $afnosupport + ;;; Resource unavailable, or operation would block. + $again + ;;; Connection already in progress. + $already + ;;; Bad file descriptor. + $badf + ;;; Bad message. + $badmsg + ;;; Device or resource busy. + $busy + ;;; Operation canceled. + $canceled + ;;; No child processes. + $child + ;;; Connection aborted. + $connaborted + ;;; Connection refused. + $connrefused + ;;; Connection reset. + $connreset + ;;; Resource deadlock would occur. + $deadlk + ;;; Destination address required. + $destaddrreq + ;;; Mathematics argument out of domain of function. + $dom + ;;; Reserved. + $dquot + ;;; File exists. + $exist + ;;; Bad address. + $fault + ;;; File too large. + $fbig + ;;; Host is unreachable. + $hostunreach + ;;; Identifier removed. + $idrm + ;;; Illegal byte sequence. + $ilseq + ;;; Operation in progress. + $inprogress + ;;; Interrupted function. + $intr + ;;; Invalid argument. + $inval + ;;; I/O error. + $io + ;;; Socket is connected. + $isconn + ;;; Is a directory. + $isdir + ;;; Too many levels of symbolic links. + $loop + ;;; File descriptor value too large. + $mfile + ;;; Too many links. + $mlink + ;;; Message too large. + $msgsize + ;;; Reserved. + $multihop + ;;; Filename too long. + $nametoolong + ;;; Network is down. + $netdown + ;;; Connection aborted by network. + $netreset + ;;; Network unreachable. + $netunreach + ;;; Too many files open in system. + $nfile + ;;; No buffer space available. + $nobufs + ;;; No such device. + $nodev + ;;; No such file or directory. + $noent + ;;; Executable file format error. + $noexec + ;;; No locks available. + $nolck + ;;; Reserved. + $nolink + ;;; Not enough space. + $nomem + ;;; No message of the desired type. + $nomsg + ;;; Protocol not available. + $noprotoopt + ;;; No space left on device. + $nospc + ;;; Function not supported. + $nosys + ;;; The socket is not connected. + $notconn + ;;; Not a directory or a symbolic link to a directory. + $notdir + ;;; Directory not empty. + $notempty + ;;; State not recoverable. + $notrecoverable + ;;; Not a socket. + $notsock + ;;; Not supported, or operation not supported on socket. + $notsup + ;;; Inappropriate I/O control operation. + $notty + ;;; No such device or address. + $nxio + ;;; Value too large to be stored in data type. + $overflow + ;;; Previous owner died. + $ownerdead + ;;; Operation not permitted. + $perm + ;;; Broken pipe. + $pipe + ;;; Protocol error. + $proto + ;;; Protocol not supported. + $protonosupport + ;;; Protocol wrong type for socket. + $prototype + ;;; Result too large. + $range + ;;; Read-only file system. + $rofs + ;;; Invalid seek. + $spipe + ;;; No such process. + $srch + ;;; Reserved. + $stale + ;;; Connection timed out. + $timedout + ;;; Text file busy. + $txtbsy + ;;; Cross-device link. + $xdev + ;;; Extension: Capabilities insufficient. + $notcapable + ) +) + +;;; File descriptor rights, determining which actions may be performed. +(typename $rights + (flags (@witx repr u64) + ;;; The right to invoke `fd_datasync`. + ;; + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflags::dsync`. + $fd_datasync + ;;; The right to invoke `fd_read` and `sock_recv`. + ;; + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. + $fd_read + ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. + $fd_seek + ;;; The right to invoke `fd_fdstat_set_flags`. + $fd_fdstat_set_flags + ;;; The right to invoke `fd_sync`. + ;; + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. + $fd_sync + ;;; The right to invoke `fd_seek` in such a way that the file offset + ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to + ;;; invoke `fd_tell`. + $fd_tell + ;;; The right to invoke `fd_write` and `sock_send`. + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. + $fd_write + ;;; The right to invoke `fd_advise`. + $fd_advise + ;;; The right to invoke `fd_allocate`. + $fd_allocate + ;;; The right to invoke `path_create_directory`. + $path_create_directory + ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::create`. + $path_create_file + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; source directory. + $path_link_source + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; target directory. + $path_link_target + ;;; The right to invoke `path_open`. + $path_open + ;;; The right to invoke `fd_readdir`. + $fd_readdir + ;;; The right to invoke `path_readlink`. + $path_readlink + ;;; The right to invoke `path_rename` with the file descriptor as the source directory. + $path_rename_source + ;;; The right to invoke `path_rename` with the file descriptor as the target directory. + $path_rename_target + ;;; The right to invoke `path_filestat_get`. + $path_filestat_get + ;;; The right to change a file's size. + ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. + ;;; Note: there is no function named `path_filestat_set_size`. This follows POSIX design, + ;;; which only has `ftruncate` and does not provide `ftruncateat`. + ;;; While such function would be desirable from the API design perspective, there are virtually + ;;; no use cases for it since no code written for POSIX systems would use it. + ;;; Moreover, implementing it would require multiple syscalls, leading to inferior performance. + $path_filestat_set_size + ;;; The right to invoke `path_filestat_set_times`. + $path_filestat_set_times + ;;; The right to invoke `path_permissions_set`. + $path_permissions_set + ;;; The right to invoke `fd_filestat_get`. + $fd_filestat_get + ;;; The right to invoke `fd_filestat_set_size`. + $fd_filestat_set_size + ;;; The right to invoke `fd_filestat_set_times`. + $fd_filestat_set_times + ;;; The right to invoke `fd_permissions_set`. + $fd_permissions_set + ;;; The right to invoke `path_symlink`. + $path_symlink + ;;; The right to invoke `path_remove_directory`. + $path_remove_directory + ;;; The right to invoke `path_unlink_file`. + $path_unlink_file + ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. + ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. + $poll_fd_readwrite + ;;; The right to invoke `sock_shutdown`. + $sock_shutdown + ) +) + +;;; A file descriptor handle. +(typename $fd (handle)) + +;;; A region of memory for scatter/gather reads. +(typename $iovec + (record + ;;; The address of the buffer to be filled. + (field $buf (@witx pointer u8)) + ;;; The length of the buffer to be filled. + (field $buf_len $size) + ) +) + +;;; A region of memory for scatter/gather writes. +(typename $ciovec + (record + ;;; The address of the buffer to be written. + (field $buf (@witx const_pointer u8)) + ;;; The length of the buffer to be written. + (field $buf_len $size) + ) +) + +(typename $iovec_array (list $iovec)) +(typename $ciovec_array (list $ciovec)) + +;;; Relative offset within a file. +(typename $filedelta s64) + +;;; The position relative to which to set the offset of the file descriptor. +(typename $whence + (enum (@witx tag u8) + ;;; Seek relative to start-of-file. + $set + ;;; Seek relative to current position. + $cur + ;;; Seek relative to end-of-file. + $end + ) +) + +;;; A reference to the offset of a directory entry. +(typename $dircookie u64) + +;;; In an `fd_readdir` call, this value signifies the start of the directory. +(@witx const $dircookie $start 0) + +;;; The type for the `dirent::d_namlen` field of `dirent`. +(typename $dirnamlen u32) + +;;; File serial number that is unique within its file system. +(typename $inode u64) + +;;; The type of a file descriptor or file. +(typename $filetype + (enum (@witx tag u8) + ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $unknown + ;;; The file descriptor or file refers to a block device inode. + $block_device + ;;; The file descriptor or file refers to a character device inode. + $character_device + ;;; The file descriptor or file refers to a directory inode. + $directory + ;;; The file descriptor or file refers to a regular file inode. + $regular_file + ;;; The file descriptor or file refers to a datagram socket. + $socket_dgram + ;;; The file descriptor or file refers to a byte-stream socket. + $socket_stream + ;;; The file refers to a symbolic link inode. + $symbolic_link + ;;; The file descriptor or file refers to a FIFO. + $fifo + ) +) + +;;; A directory entry. +(typename $dirent + (record + ;;; The offset of the next directory entry stored in this directory. + (field $d_next $dircookie) + ;;; The serial number of the file referred to by this directory entry. + (field $d_ino $inode) + ;;; The type of the file referred to by this directory entry. + (field $d_type $filetype) + ;;; The length of the name of the directory entry. + (field $d_namlen $dirnamlen) + ) +) + +;;; File or memory access pattern advisory information. +(typename $advice + (enum (@witx tag u8) + ;;; The application has no advice to give on its behavior with respect to the specified data. + $normal + ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + $sequential + ;;; The application expects to access the specified data in a random order. + $random + ;;; The application expects to access the specified data in the near future. + $willneed + ;;; The application expects that it will not access the specified data in the near future. + $dontneed + ;;; The application expects to access the specified data once and then not reuse it thereafter. + $noreuse + ) +) + +;;; File descriptor flags. +(typename $fdflags + (flags (@witx repr u16) + ;;; Append mode: Data written to the file is always appended to the file's end. + $append + ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + $dsync + ;;; Non-blocking mode. + $nonblock + ;;; Synchronized read I/O operations. + $rsync + ;;; Write according to synchronized I/O file integrity completion. In + ;;; addition to synchronizing the data stored in the file, the implementation + ;;; may also synchronously update the file's metadata. + $sync + ) +) + +;;; File descriptor attributes. +(typename $fdstat + (record + ;;; File type. + (field $fs_filetype $filetype) + ;;; File descriptor flags. + (field $fs_flags $fdflags) + ;;; Rights that apply to this file descriptor. + (field $fs_rights_base $rights) + ;;; Maximum set of rights that may be installed on new file descriptors that + ;;; are created through this file descriptor, e.g., through `path_open`. + (field $fs_rights_inheriting $rights) + ) +) + +;;; Identifier for a device containing a file system. Can be used in combination +;;; with `inode` to uniquely identify a file or directory in the filesystem. +(typename $device u64) + +;;; Which file time attributes to adjust. +(typename $fstflags + (flags (@witx repr u16) + ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. + $atim + ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. + $atim_now + ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. + $mtim + ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. + $mtim_now + ) +) + +;;; Flags determining the method of how paths are resolved. +(typename $lookupflags + (flags (@witx repr u32) + ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. + $symlink_follow + ) +) + +;;; Open flags used by `path_open`. +(typename $oflags + (flags (@witx repr u16) + ;;; Create file if it does not exist. + $create + ;;; Fail if not a directory. + $directory + ;;; Fail if file already exists. + $excl + ;;; Truncate file to size 0. + $trunc + ) +) + +;;; Number of hard links to an inode. +(typename $linkcount u64) + +;;; File permissions. This represents the permissions associated with a +;;; file in a filesystem, and don't fully reflect all the conditions +;;; which determine whether a given WASI program can access the file. +(typename $permissions + (flags (@witx repr u8) + ;;; For files, permission to read the file. + ;;; For directories, permission to do `readdir` and access files + ;;; within the directory. + ;;; + ;;; Note: This is similar to the read bit being set on files, and the + ;;; read *and* execute bits being set on directories, in POSIX. + $read + + ;;; For files, permission to mutate the file. + ;;; For directories, permission to create, remove, and rename items + ;;; within the directory. + $write + + ;;; For files, permission to "execute" the file, using whatever + ;;; concept of "executing" the host filesystem has. + ;;; This flag is not valid for directories. + $execute + + ;;; For filesystems which have a concept of multiple "users", this flag + ;;; indicates that the file is only accessible by the effective "user" + ;;; that the WASI store uses to access the filesystem, and inaccessible + ;;; to other "users". + $private + ) +) + +;;; File attributes. +(typename $filestat + (record + ;;; Device ID of device containing the file. + (field $dev $device) + ;;; File serial number. + (field $ino $inode) + ;;; File type. + (field $filetype $filetype) + ;;; File permissions. + (field $permissions $permissions) + ;;; Number of hard links to the file. + (field $nlink $linkcount) + ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + (field $size $filesize) + ;;; Last data access timestamp. + (field $atim $timestamp) + ;;; Last data modification timestamp. + (field $mtim $timestamp) + ;;; Last file status change timestamp. + (field $ctim $timestamp) + ) +) + +;;; User-provided value that may be attached to objects that is retained when +;;; extracted from the implementation. +(typename $userdata u64) + +;;; Type of a subscription to an event or its occurrence. +(typename $eventtype + (enum (@witx tag u8) + ;;; The time value of clock `subscription_clock::id` has + ;;; reached timestamp `subscription_clock::timeout`. + $clock + ;;; File descriptor `subscription_fd_readwrite::fd` has data + ;;; available for reading. This event always triggers for regular files. + $fd_read + ;;; File descriptor `subscription_fd_readwrite::fd` has capacity + ;;; available for writing. This event always triggers for regular files. + $fd_write + ) +) + +;;; The state of the file descriptor subscribed to with +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $eventrwflags + (flags (@witx repr u16) + ;;; The peer of this socket has closed or disconnected. + $fd_readwrite_hangup + ) +) + +;;; The contents of an `event` when type is `eventtype::fd_read` or +;;; `eventtype::fd_write`. +(typename $event_fd_readwrite + (record + ;;; The number of bytes available for reading or writing. + (field $nbytes $filesize) + ;;; The state of the file descriptor. + (field $flags $eventrwflags) + ) +) + +;;; The contents of an `event`. +(typename $event_u + (variant (@witx tag $eventtype) + (case $fd_read $event_fd_readwrite) + (case $fd_write $event_fd_readwrite) + (case $clock) + ) +) + +;;; An event that occurred. +(typename $event + (record + ;;; User-provided value that got attached to `subscription::userdata`. + (field $userdata $userdata) + ;;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno) + ;;; The type of the event that occurred, and the contents of the event + (field $u $event_u) + ) +) + +;;; Flags determining how to interpret the timestamp provided in +;;; `subscription_clock::timeout`. +(typename $subclockflags + (flags (@witx repr u16) + ;;; If set, treat the timestamp provided in + ;;; `subscription_clock::timeout` as an absolute timestamp of clock + ;;; `subscription_clock::id`. If clear, treat the timestamp + ;;; provided in `subscription_clock::timeout` relative to the + ;;; current time value of clock `subscription_clock::id`. + $subscription_clock_abstime + ) +) + +;;; The contents of a `subscription` when type is `eventtype::clock`. +(typename $subscription_clock + (record + ;;; The clock against which to compare the timestamp. + (field $id $clockid) + ;;; The absolute or relative timestamp. + (field $timeout $timestamp) + ;;; The amount of time that the implementation may wait additionally + ;;; to coalesce with other events. + (field $precision $timestamp) + ;;; Flags specifying whether the timeout is absolute or relative + (field $flags $subclockflags) + ) +) + +;;; The contents of a `subscription` when type is type is +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $subscription_fd_readwrite + (record + ;;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $fd $fd) + ) +) + +;;; The contents of a `subscription`. +(typename $subscription_u + (union (@witx tag $eventtype) + $subscription_clock + $subscription_fd_readwrite + $subscription_fd_readwrite + ) +) + +;;; Subscription to an event. +(typename $subscription + (record + ;;; User-provided value that is attached to the subscription in the + ;;; implementation and returned through `event::userdata`. + (field $userdata $userdata) + ;;; The type of the event to which to subscribe, and the contents of the subscription. + (field $u $subscription_u) + ) +) + +;;; Exit code generated by a program when exiting. +(typename $exitcode u8) + +;;; Indicate the program exited successfully. +;;; +;;; Note: This is similar to `EXIT_SUCCESS` in POSIX. +(@witx const $exitcode $success 0) + +;;; Indicate the program exited unsuccessfully. +;;; +;;; Note: This is similar to `EXIT_FAILURE` in POSIX. +(@witx const $exitcode $failure 1) + +;;; Flags provided to `sock_recv`. +(typename $riflags + (flags (@witx repr u16) + ;;; Returns the message without removing it from the socket's receive queue. + $recv_peek + ;;; On byte-stream sockets, block until the full amount of data can be returned. + $recv_waitall + ) +) + +;;; Flags returned by `sock_recv`. +(typename $roflags + (flags (@witx repr u16) + ;;; Returned by `sock_recv`: Message data has been truncated. + $recv_data_truncated + ) +) + +;;; Flags provided to `sock_send`. As there are currently no flags +;;; defined, it must be set to zero. +(typename $siflags u16) + +;;; Which channels on a socket to shut down. +(typename $sdflags + (flags (@witx repr u8) + ;;; Disables further receive operations. + $rd + ;;; Disables further send operations. + $wr + ) +) + +;;; Identifiers for preopened capabilities. +(typename $preopentype + (enum (@witx tag u8) + ;;; A pre-opened directory. + $dir + ) +) + +;;; The contents of a `prestat` when its type is `preopentype::dir`. +(typename $prestat_dir + (record + ;;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size) + ) +) + +;;; Information about a pre-opened capability. +(typename $prestat + (union (@witx tag $preopentype) + ;;; When type is `preopentype::dir`: + $prestat_dir + ) +) diff --git a/proposals/random/standard/wasi-random/witx/wasi_ephemeral_random.witx b/proposals/random/standard/wasi-random/witx/wasi_ephemeral_random.witx new file mode 100644 index 000000000..41a2ef1c9 --- /dev/null +++ b/proposals/random/standard/wasi-random/witx/wasi_ephemeral_random.witx @@ -0,0 +1,26 @@ +;; WASI Random API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_random + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Write high-quality random data into a buffer. + ;;; This function blocks when the implementation is unable to immediately + ;;; provide sufficient high-quality random data. + ;;; This function may execute slowly, so when large amounts of random data are + ;;; required, it's advisable to use this function to seed a pseudo-random + ;;; number generator, rather than to provide the random data directly. + (@interface func (export "get") + ;;; The buffer to fill with random data. + (param $buf (@witx pointer u8)) + (param $buf_len $size) + (result $error (expected (error $errno))) + ) +) From 8fcf970eda1c9698d35afb0b13a3d5f0396fa2c7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 9 Mar 2021 12:31:16 -0800 Subject: [PATCH 0897/1772] Rename the witx file to random.witx. --- .../wasi-random/witx/{wasi_ephemeral_random.witx => random.witx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/random/standard/wasi-random/witx/{wasi_ephemeral_random.witx => random.witx} (100%) diff --git a/proposals/random/standard/wasi-random/witx/wasi_ephemeral_random.witx b/proposals/random/standard/wasi-random/witx/random.witx similarity index 100% rename from proposals/random/standard/wasi-random/witx/wasi_ephemeral_random.witx rename to proposals/random/standard/wasi-random/witx/random.witx From 7cac57c7e77339afec51e02579159bf1ef27ec7c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 9 Mar 2021 12:07:57 -0800 Subject: [PATCH 0898/1772] Update and rebase on WASI main. As part of the move to modularize WASI, I've now reset the `main` branch in this repository to be the same as that if the [`WASI` repository], and this is now a PR on top of that. This implements the directory structure described in WebAssembly/WASI#360, with a standard directory, and a wasi-clocks directory under that. [`WASI` repository]: https://github.com/WebAssembly/WASI/ --- proposals/clocks/standard/wasi-clocks/docs.md | 1266 +++++++++++++++++ .../standard/wasi-clocks/witx/clocks.witx | 35 + .../standard/wasi-clocks/witx/typenames.witx | 708 +++++++++ proposals/clocks/tools/repo_docs.sh | 5 + 4 files changed, 2014 insertions(+) create mode 100644 proposals/clocks/standard/wasi-clocks/docs.md create mode 100644 proposals/clocks/standard/wasi-clocks/witx/clocks.witx create mode 100644 proposals/clocks/standard/wasi-clocks/witx/typenames.witx diff --git a/proposals/clocks/standard/wasi-clocks/docs.md b/proposals/clocks/standard/wasi-clocks/docs.md new file mode 100644 index 000000000..4b7ba07c1 --- /dev/null +++ b/proposals/clocks/standard/wasi-clocks/docs.md @@ -0,0 +1,1266 @@ +# Types +## `size`: `usize` +An array size. + +Note: This is similar to `size_t` in POSIX. + +Size: 4 + +Alignment: 4 + +## `filesize`: `u64` +Non-negative file size or length of a region within a file. + +Size: 8 + +Alignment: 8 + +## `timestamp`: `u64` +Timestamp in nanoseconds. + +Size: 8 + +Alignment: 8 + +## `clockid`: `Variant` +Identifiers for clocks. + +Size: 4 + +Alignment: 4 + +### Variant cases +- `realtime` +The clock measuring real time. Time value zero corresponds with +1970-01-01T00:00:00Z. + +- `monotonic` +The store-wide monotonic clock, which is defined as a clock measuring +real time, whose value cannot be adjusted and which cannot have negative +clock jumps. The epoch of this clock is undefined. The absolute time +value of this clock therefore has no meaning. + +## `errno`: `Variant` +Error codes returned by functions. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX. + +Size: 2 + +Alignment: 2 + +### Variant cases +- `success` +No error occurred. System call completed successfully. + +- `2big` +Argument list too long. + +- `access` +Permission denied. + +- `addrinuse` +Address in use. + +- `addrnotavail` +Address not available. + +- `afnosupport` +Address family not supported. + +- `again` +Resource unavailable, or operation would block. + +- `already` +Connection already in progress. + +- `badf` +Bad file descriptor. + +- `badmsg` +Bad message. + +- `busy` +Device or resource busy. + +- `canceled` +Operation canceled. + +- `child` +No child processes. + +- `connaborted` +Connection aborted. + +- `connrefused` +Connection refused. + +- `connreset` +Connection reset. + +- `deadlk` +Resource deadlock would occur. + +- `destaddrreq` +Destination address required. + +- `dom` +Mathematics argument out of domain of function. + +- `dquot` +Reserved. + +- `exist` +File exists. + +- `fault` +Bad address. + +- `fbig` +File too large. + +- `hostunreach` +Host is unreachable. + +- `idrm` +Identifier removed. + +- `ilseq` +Illegal byte sequence. + +- `inprogress` +Operation in progress. + +- `intr` +Interrupted function. + +- `inval` +Invalid argument. + +- `io` +I/O error. + +- `isconn` +Socket is connected. + +- `isdir` +Is a directory. + +- `loop` +Too many levels of symbolic links. + +- `mfile` +File descriptor value too large. + +- `mlink` +Too many links. + +- `msgsize` +Message too large. + +- `multihop` +Reserved. + +- `nametoolong` +Filename too long. + +- `netdown` +Network is down. + +- `netreset` +Connection aborted by network. + +- `netunreach` +Network unreachable. + +- `nfile` +Too many files open in system. + +- `nobufs` +No buffer space available. + +- `nodev` +No such device. + +- `noent` +No such file or directory. + +- `noexec` +Executable file format error. + +- `nolck` +No locks available. + +- `nolink` +Reserved. + +- `nomem` +Not enough space. + +- `nomsg` +No message of the desired type. + +- `noprotoopt` +Protocol not available. + +- `nospc` +No space left on device. + +- `nosys` +Function not supported. + +- `notconn` +The socket is not connected. + +- `notdir` +Not a directory or a symbolic link to a directory. + +- `notempty` +Directory not empty. + +- `notrecoverable` +State not recoverable. + +- `notsock` +Not a socket. + +- `notsup` +Not supported, or operation not supported on socket. + +- `notty` +Inappropriate I/O control operation. + +- `nxio` +No such device or address. + +- `overflow` +Value too large to be stored in data type. + +- `ownerdead` +Previous owner died. + +- `perm` +Operation not permitted. + +- `pipe` +Broken pipe. + +- `proto` +Protocol error. + +- `protonosupport` +Protocol not supported. + +- `prototype` +Protocol wrong type for socket. + +- `range` +Result too large. + +- `rofs` +Read-only file system. + +- `spipe` +Invalid seek. + +- `srch` +No such process. + +- `stale` +Reserved. + +- `timedout` +Connection timed out. + +- `txtbsy` +Text file busy. + +- `xdev` +Cross-device link. + +- `notcapable` +Extension: Capabilities insufficient. + +## `rights`: `Record` +File descriptor rights, determining which actions may be performed. + +Size: 8 + +Alignment: 8 + +### Record members +- `fd_datasync`: `bool` +The right to invoke `fd_datasync`. +If `path_open` is set, includes the right to invoke +`path_open` with [`fdflags::dsync`](#fdflags.dsync). + +Bit: 0 + +- `fd_read`: `bool` +The right to invoke `fd_read` and `sock_recv`. +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. + +Bit: 1 + +- `fd_seek`: `bool` +The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). + +Bit: 2 + +- `fd_fdstat_set_flags`: `bool` +The right to invoke `fd_fdstat_set_flags`. + +Bit: 3 + +- `fd_sync`: `bool` +The right to invoke `fd_sync`. +If `path_open` is set, includes the right to invoke +`path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). + +Bit: 4 + +- `fd_tell`: `bool` +The right to invoke `fd_seek` in such a way that the file offset +remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to +invoke `fd_tell`. + +Bit: 5 + +- `fd_write`: `bool` +The right to invoke `fd_write` and `sock_send`. +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. + +Bit: 6 + +- `fd_advise`: `bool` +The right to invoke `fd_advise`. + +Bit: 7 + +- `fd_allocate`: `bool` +The right to invoke `fd_allocate`. + +Bit: 8 + +- `path_create_directory`: `bool` +The right to invoke `path_create_directory`. + +Bit: 9 + +- `path_create_file`: `bool` +If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). + +Bit: 10 + +- `path_link_source`: `bool` +The right to invoke `path_link` with the file descriptor as the +source directory. + +Bit: 11 + +- `path_link_target`: `bool` +The right to invoke `path_link` with the file descriptor as the +target directory. + +Bit: 12 + +- `path_open`: `bool` +The right to invoke `path_open`. + +Bit: 13 + +- `fd_readdir`: `bool` +The right to invoke `fd_readdir`. + +Bit: 14 + +- `path_readlink`: `bool` +The right to invoke `path_readlink`. + +Bit: 15 + +- `path_rename_source`: `bool` +The right to invoke `path_rename` with the file descriptor as the source directory. + +Bit: 16 + +- `path_rename_target`: `bool` +The right to invoke `path_rename` with the file descriptor as the target directory. + +Bit: 17 + +- `path_filestat_get`: `bool` +The right to invoke `path_filestat_get`. + +Bit: 18 + +- `path_filestat_set_size`: `bool` +The right to change a file's size. +If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). +Note: there is no function named `path_filestat_set_size`. This follows POSIX design, +which only has `ftruncate` and does not provide `ftruncateat`. +While such function would be desirable from the API design perspective, there are virtually +no use cases for it since no code written for POSIX systems would use it. +Moreover, implementing it would require multiple syscalls, leading to inferior performance. + +Bit: 19 + +- `path_filestat_set_times`: `bool` +The right to invoke `path_filestat_set_times`. + +Bit: 20 + +- `path_permissions_set`: `bool` +The right to invoke `path_permissions_set`. + +Bit: 21 + +- `fd_filestat_get`: `bool` +The right to invoke `fd_filestat_get`. + +Bit: 22 + +- `fd_filestat_set_size`: `bool` +The right to invoke `fd_filestat_set_size`. + +Bit: 23 + +- `fd_filestat_set_times`: `bool` +The right to invoke `fd_filestat_set_times`. + +Bit: 24 + +- `fd_permissions_set`: `bool` +The right to invoke `fd_permissions_set`. + +Bit: 25 + +- `path_symlink`: `bool` +The right to invoke `path_symlink`. + +Bit: 26 + +- `path_remove_directory`: `bool` +The right to invoke `path_remove_directory`. + +Bit: 27 + +- `path_unlink_file`: `bool` +The right to invoke `path_unlink_file`. + +Bit: 28 + +- `poll_fd_readwrite`: `bool` +If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). +If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). + +Bit: 29 + +- `sock_shutdown`: `bool` +The right to invoke `sock_shutdown`. + +Bit: 30 + +## `fd`: `Handle` +A file descriptor handle. + +Size: 4 + +Alignment: 4 + +### Supertypes +## `iovec`: `Record` +A region of memory for scatter/gather reads. + +Size: 8 + +Alignment: 4 + +### Record members +- `buf`: `Pointer` +The address of the buffer to be filled. + +Offset: 0 + +- `buf_len`: [`size`](#size) +The length of the buffer to be filled. + +Offset: 4 + +## `ciovec`: `Record` +A region of memory for scatter/gather writes. + +Size: 8 + +Alignment: 4 + +### Record members +- `buf`: `ConstPointer` +The address of the buffer to be written. + +Offset: 0 + +- `buf_len`: [`size`](#size) +The length of the buffer to be written. + +Offset: 4 + +## `iovec_array`: `List` + +Size: 8 + +Alignment: 4 + +## `ciovec_array`: `List` + +Size: 8 + +Alignment: 4 + +## `filedelta`: `s64` +Relative offset within a file. + +Size: 8 + +Alignment: 8 + +## `whence`: `Variant` +The position relative to which to set the offset of the file descriptor. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `set` +Seek relative to start-of-file. + +- `cur` +Seek relative to current position. + +- `end` +Seek relative to end-of-file. + +## `dircookie`: `u64` +A reference to the offset of a directory entry. + +Size: 8 + +Alignment: 8 + +### Constants +- `start` + +## `dirnamlen`: `u32` +The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). + +Size: 4 + +Alignment: 4 + +## `inode`: `u64` +File serial number that is unique within its file system. + +Size: 8 + +Alignment: 8 + +## `filetype`: `Variant` +The type of a file descriptor or file. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `unknown` +The type of the file descriptor or file is unknown or is different from any of the other types specified. + +- `block_device` +The file descriptor or file refers to a block device inode. + +- `character_device` +The file descriptor or file refers to a character device inode. + +- `directory` +The file descriptor or file refers to a directory inode. + +- `regular_file` +The file descriptor or file refers to a regular file inode. + +- `socket_dgram` +The file descriptor or file refers to a datagram socket. + +- `socket_stream` +The file descriptor or file refers to a byte-stream socket. + +- `symbolic_link` +The file refers to a symbolic link inode. + +- `fifo` +The file descriptor or file refers to a FIFO. + +## `dirent`: `Record` +A directory entry. + +Size: 24 + +Alignment: 8 + +### Record members +- `d_next`: [`dircookie`](#dircookie) +The offset of the next directory entry stored in this directory. + +Offset: 0 + +- `d_ino`: [`inode`](#inode) +The serial number of the file referred to by this directory entry. + +Offset: 8 + +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. + +Offset: 16 + +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. + +Offset: 20 + +## `advice`: `Variant` +File or memory access pattern advisory information. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `normal` +The application has no advice to give on its behavior with respect to the specified data. + +- `sequential` +The application expects to access the specified data sequentially from lower offsets to higher offsets. + +- `random` +The application expects to access the specified data in a random order. + +- `willneed` +The application expects to access the specified data in the near future. + +- `dontneed` +The application expects that it will not access the specified data in the near future. + +- `noreuse` +The application expects to access the specified data once and then not reuse it thereafter. + +## `fdflags`: `Record` +File descriptor flags. + +Size: 2 + +Alignment: 2 + +### Record members +- `append`: `bool` +Append mode: Data written to the file is always appended to the file's end. + +Bit: 0 + +- `dsync`: `bool` +Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + +Bit: 1 + +- `nonblock`: `bool` +Non-blocking mode. + +Bit: 2 + +- `rsync`: `bool` +Synchronized read I/O operations. + +Bit: 3 + +- `sync`: `bool` +Write according to synchronized I/O file integrity completion. In +addition to synchronizing the data stored in the file, the implementation +may also synchronously update the file's metadata. + +Bit: 4 + +## `fdstat`: `Record` +File descriptor attributes. + +Size: 24 + +Alignment: 8 + +### Record members +- `fs_filetype`: [`filetype`](#filetype) +File type. + +Offset: 0 + +- `fs_flags`: [`fdflags`](#fdflags) +File descriptor flags. + +Offset: 2 + +- `fs_rights_base`: [`rights`](#rights) +Rights that apply to this file descriptor. + +Offset: 8 + +- `fs_rights_inheriting`: [`rights`](#rights) +Maximum set of rights that may be installed on new file descriptors that +are created through this file descriptor, e.g., through `path_open`. + +Offset: 16 + +## `device`: `u64` +Identifier for a device containing a file system. Can be used in combination +with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. + +Size: 8 + +Alignment: 8 + +## `fstflags`: `Record` +Which file time attributes to adjust. + +Size: 2 + +Alignment: 2 + +### Record members +- `atim`: `bool` +Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). + +Bit: 0 + +- `atim_now`: `bool` +Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). + +Bit: 1 + +- `mtim`: `bool` +Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). + +Bit: 2 + +- `mtim_now`: `bool` +Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). + +Bit: 3 + +## `lookupflags`: `Record` +Flags determining the method of how paths are resolved. + +Size: 4 + +Alignment: 4 + +### Record members +- `symlink_follow`: `bool` +As long as the resolved path corresponds to a symbolic link, it is expanded. + +Bit: 0 + +## `oflags`: `Record` +Open flags used by `path_open`. + +Size: 2 + +Alignment: 2 + +### Record members +- `create`: `bool` +Create file if it does not exist. + +Bit: 0 + +- `directory`: `bool` +Fail if not a directory. + +Bit: 1 + +- `excl`: `bool` +Fail if file already exists. + +Bit: 2 + +- `trunc`: `bool` +Truncate file to size 0. + +Bit: 3 + +## `linkcount`: `u64` +Number of hard links to an inode. + +Size: 8 + +Alignment: 8 + +## `permissions`: `Record` +File permissions. This represents the permissions associated with a +file in a filesystem, and don't fully reflect all the conditions +which determine whether a given WASI program can access the file. + +Size: 1 + +Alignment: 1 + +### Record members +- `read`: `bool` +For files, permission to read the file. +For directories, permission to do `readdir` and access files +within the directory. + +Note: This is similar to the read bit being set on files, and the +read *and* execute bits being set on directories, in POSIX. + +Bit: 0 + +- `write`: `bool` +For files, permission to mutate the file. +For directories, permission to create, remove, and rename items +within the directory. + +Bit: 1 + +- `execute`: `bool` +For files, permission to "execute" the file, using whatever +concept of "executing" the host filesystem has. +This flag is not valid for directories. + +Bit: 2 + +- `private`: `bool` +For filesystems which have a concept of multiple "users", this flag +indicates that the file is only accessible by the effective "user" +that the WASI store uses to access the filesystem, and inaccessible +to other "users". + +Bit: 3 + +## `filestat`: `Record` +File attributes. + +Size: 64 + +Alignment: 8 + +### Record members +- `dev`: [`device`](#device) +Device ID of device containing the file. + +Offset: 0 + +- `ino`: [`inode`](#inode) +File serial number. + +Offset: 8 + +- `filetype`: [`filetype`](#filetype) +File type. + +Offset: 16 + +- `permissions`: [`permissions`](#permissions) +File permissions. + +Offset: 17 + +- `nlink`: [`linkcount`](#linkcount) +Number of hard links to the file. + +Offset: 24 + +- `size`: [`filesize`](#filesize) +For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + +Offset: 32 + +- `atim`: [`timestamp`](#timestamp) +Last data access timestamp. + +Offset: 40 + +- `mtim`: [`timestamp`](#timestamp) +Last data modification timestamp. + +Offset: 48 + +- `ctim`: [`timestamp`](#timestamp) +Last file status change timestamp. + +Offset: 56 + +## `userdata`: `u64` +User-provided value that may be attached to objects that is retained when +extracted from the implementation. + +Size: 8 + +Alignment: 8 + +## `eventtype`: `Variant` +Type of a subscription to an event or its occurrence. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `clock` +The time value of clock [`subscription_clock::id`](#subscription_clock.id) has +reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). + +- `fd_read` +File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has data +available for reading. This event always triggers for regular files. + +- `fd_write` +File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity +available for writing. This event always triggers for regular files. + +## `eventrwflags`: `Record` +The state of the file descriptor subscribed to with +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +Size: 2 + +Alignment: 2 + +### Record members +- `fd_readwrite_hangup`: `bool` +The peer of this socket has closed or disconnected. + +Bit: 0 + +## `event_fd_readwrite`: `Record` +The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). + +Size: 16 + +Alignment: 8 + +### Record members +- `nbytes`: [`filesize`](#filesize) +The number of bytes available for reading or writing. + +Offset: 0 + +- `flags`: [`eventrwflags`](#eventrwflags) +The state of the file descriptor. + +Offset: 8 + +## `event_u`: `Variant` +The contents of an [`event`](#event). + +Size: 24 + +Alignment: 8 + +### Variant Layout +- size: 24 +- align: 8 +- tag_size: 1 +### Variant cases +- `clock` + +- `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) + +- `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) + +## `event`: `Record` +An event that occurred. + +Size: 40 + +Alignment: 8 + +### Record members +- `userdata`: [`userdata`](#userdata) +User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). + +Offset: 0 + +- `error`: [`errno`](#errno) +If non-zero, an error that occurred while processing the subscription request. + +Offset: 8 + +- `u`: [`event_u`](#event_u) +The type of the event that occurred, and the contents of the event + +Offset: 16 + +## `subclockflags`: `Record` +Flags determining how to interpret the timestamp provided in +[`subscription_clock::timeout`](#subscription_clock.timeout). + +Size: 2 + +Alignment: 2 + +### Record members +- `subscription_clock_abstime`: `bool` +If set, treat the timestamp provided in +[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock +[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp +provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the +current time value of clock [`subscription_clock::id`](#subscription_clock.id). + +Bit: 0 + +## `subscription_clock`: `Record` +The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). + +Size: 32 + +Alignment: 8 + +### Record members +- `id`: [`clockid`](#clockid) +The clock against which to compare the timestamp. + +Offset: 0 + +- `timeout`: [`timestamp`](#timestamp) +The absolute or relative timestamp. + +Offset: 8 + +- `precision`: [`timestamp`](#timestamp) +The amount of time that the implementation may wait additionally +to coalesce with other events. + +Offset: 16 + +- `flags`: [`subclockflags`](#subclockflags) +Flags specifying whether the timeout is absolute or relative + +Offset: 24 + +## `subscription_fd_readwrite`: `Record` +The contents of a [`subscription`](#subscription) when type is type is +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +Size: 4 + +Alignment: 4 + +### Record members +- `fd`: [`fd`](#fd) +The file descriptor on which to wait for it to become ready for reading or writing. + +Offset: 0 + +## `subscription_u`: `Variant` +The contents of a [`subscription`](#subscription). + +Size: 40 + +Alignment: 8 + +### Variant Layout +- size: 40 +- align: 8 +- tag_size: 1 +### Variant cases +- `clock`: [`subscription_clock`](#subscription_clock) + +- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +## `subscription`: `Record` +Subscription to an event. + +Size: 48 + +Alignment: 8 + +### Record members +- `userdata`: [`userdata`](#userdata) +User-provided value that is attached to the subscription in the +implementation and returned through [`event::userdata`](#event.userdata). + +Offset: 0 + +- `u`: [`subscription_u`](#subscription_u) +The type of the event to which to subscribe, and the contents of the subscription. + +Offset: 8 + +## `exitcode`: `u8` +Exit code generated by a program when exiting. + +Size: 1 + +Alignment: 1 + +### Constants +- `success` + +- `failure` + +## `riflags`: `Record` +Flags provided to `sock_recv`. + +Size: 2 + +Alignment: 2 + +### Record members +- `recv_peek`: `bool` +Returns the message without removing it from the socket's receive queue. + +Bit: 0 + +- `recv_waitall`: `bool` +On byte-stream sockets, block until the full amount of data can be returned. + +Bit: 1 + +## `roflags`: `Record` +Flags returned by `sock_recv`. + +Size: 2 + +Alignment: 2 + +### Record members +- `recv_data_truncated`: `bool` +Returned by `sock_recv`: Message data has been truncated. + +Bit: 0 + +## `siflags`: `u16` +Flags provided to `sock_send`. As there are currently no flags +defined, it must be set to zero. + +Size: 2 + +Alignment: 2 + +## `sdflags`: `Record` +Which channels on a socket to shut down. + +Size: 1 + +Alignment: 1 + +### Record members +- `rd`: `bool` +Disables further receive operations. + +Bit: 0 + +- `wr`: `bool` +Disables further send operations. + +Bit: 1 + +## `preopentype`: `Variant` +Identifiers for preopened capabilities. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `dir` +A pre-opened directory. + +## `prestat_dir`: `Record` +The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). + +Size: 4 + +Alignment: 4 + +### Record members +- `pr_name_len`: [`size`](#size) +The length of the directory name for use with `fd_prestat_dir_name`. + +Offset: 0 + +## `prestat`: `Variant` +Information about a pre-opened capability. + +Size: 8 + +Alignment: 4 + +### Variant Layout +- size: 8 +- align: 4 +- tag_size: 1 +### Variant cases +- `dir`: [`prestat_dir`](#prestat_dir) +When type is [`preopentype::dir`](#preopentype.dir): + +# Modules +## wasi_ephemeral_clock +### Imports +#### Memory +### Functions + +--- + +#### `res_get(id: clockid) -> Result` +Return the resolution of a clock. +Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, +return [`errno::inval`](#errno.inval). +Note: This is similar to `clock_getres` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the resolution. + +##### Results +- `error`: `Result` +The resolution of the clock. + +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) + +- `err`: [`errno`](#errno) + + +--- + +#### `time_get(id: clockid, precision: timestamp) -> Result` +Return the time value of a clock. +Note: This is similar to `clock_gettime` in POSIX. + +##### Params +- `id`: [`clockid`](#clockid) +The clock for which to return the time. + +- `precision`: [`timestamp`](#timestamp) +The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + +##### Results +- `error`: `Result` +The time value of the clock. + +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`timestamp`](#timestamp) + +- `err`: [`errno`](#errno) + diff --git a/proposals/clocks/standard/wasi-clocks/witx/clocks.witx b/proposals/clocks/standard/wasi-clocks/witx/clocks.witx new file mode 100644 index 000000000..a980529f8 --- /dev/null +++ b/proposals/clocks/standard/wasi-clocks/witx/clocks.witx @@ -0,0 +1,35 @@ +;; WASI Clocks. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_clock + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Return the resolution of a clock. + ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, + ;;; return `errno::inval`. + ;;; Note: This is similar to `clock_getres` in POSIX. + (@interface func (export "res_get") + ;;; The clock for which to return the resolution. + (param $id $clockid) + ;;; The resolution of the clock. + (result $error (expected $timestamp (error $errno))) + ) + + ;;; Return the time value of a clock. + ;;; Note: This is similar to `clock_gettime` in POSIX. + (@interface func (export "time_get") + ;;; The clock for which to return the time. + (param $id $clockid) + ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. + (param $precision $timestamp) + ;;; The time value of the clock. + (result $error (expected $timestamp (error $errno))) + ) +) diff --git a/proposals/clocks/standard/wasi-clocks/witx/typenames.witx b/proposals/clocks/standard/wasi-clocks/witx/typenames.witx new file mode 100644 index 000000000..bbd6489df --- /dev/null +++ b/proposals/clocks/standard/wasi-clocks/witx/typenames.witx @@ -0,0 +1,708 @@ +;; Type names used by low-level WASI interfaces. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +;;; An array size. +;;; +;;; Note: This is similar to `size_t` in POSIX. +(typename $size (@witx usize)) + +;;; Non-negative file size or length of a region within a file. +(typename $filesize u64) + +;;; Timestamp in nanoseconds. +(typename $timestamp u64) + +;;; Identifiers for clocks. +(typename $clockid + (enum (@witx tag u32) + ;;; The clock measuring real time. Time value zero corresponds with + ;;; 1970-01-01T00:00:00Z. + $realtime + ;;; The store-wide monotonic clock, which is defined as a clock measuring + ;;; real time, whose value cannot be adjusted and which cannot have negative + ;;; clock jumps. The epoch of this clock is undefined. The absolute time + ;;; value of this clock therefore has no meaning. + $monotonic + ) +) + +;;; Error codes returned by functions. +;;; Not all of these error codes are returned by the functions provided by this +;;; API; some are used in higher-level library layers, and others are provided +;;; merely for alignment with POSIX. +(typename $errno + (enum (@witx tag u16) + ;;; No error occurred. System call completed successfully. + $success + ;;; Argument list too long. + $2big + ;;; Permission denied. + $access + ;;; Address in use. + $addrinuse + ;;; Address not available. + $addrnotavail + ;;; Address family not supported. + $afnosupport + ;;; Resource unavailable, or operation would block. + $again + ;;; Connection already in progress. + $already + ;;; Bad file descriptor. + $badf + ;;; Bad message. + $badmsg + ;;; Device or resource busy. + $busy + ;;; Operation canceled. + $canceled + ;;; No child processes. + $child + ;;; Connection aborted. + $connaborted + ;;; Connection refused. + $connrefused + ;;; Connection reset. + $connreset + ;;; Resource deadlock would occur. + $deadlk + ;;; Destination address required. + $destaddrreq + ;;; Mathematics argument out of domain of function. + $dom + ;;; Reserved. + $dquot + ;;; File exists. + $exist + ;;; Bad address. + $fault + ;;; File too large. + $fbig + ;;; Host is unreachable. + $hostunreach + ;;; Identifier removed. + $idrm + ;;; Illegal byte sequence. + $ilseq + ;;; Operation in progress. + $inprogress + ;;; Interrupted function. + $intr + ;;; Invalid argument. + $inval + ;;; I/O error. + $io + ;;; Socket is connected. + $isconn + ;;; Is a directory. + $isdir + ;;; Too many levels of symbolic links. + $loop + ;;; File descriptor value too large. + $mfile + ;;; Too many links. + $mlink + ;;; Message too large. + $msgsize + ;;; Reserved. + $multihop + ;;; Filename too long. + $nametoolong + ;;; Network is down. + $netdown + ;;; Connection aborted by network. + $netreset + ;;; Network unreachable. + $netunreach + ;;; Too many files open in system. + $nfile + ;;; No buffer space available. + $nobufs + ;;; No such device. + $nodev + ;;; No such file or directory. + $noent + ;;; Executable file format error. + $noexec + ;;; No locks available. + $nolck + ;;; Reserved. + $nolink + ;;; Not enough space. + $nomem + ;;; No message of the desired type. + $nomsg + ;;; Protocol not available. + $noprotoopt + ;;; No space left on device. + $nospc + ;;; Function not supported. + $nosys + ;;; The socket is not connected. + $notconn + ;;; Not a directory or a symbolic link to a directory. + $notdir + ;;; Directory not empty. + $notempty + ;;; State not recoverable. + $notrecoverable + ;;; Not a socket. + $notsock + ;;; Not supported, or operation not supported on socket. + $notsup + ;;; Inappropriate I/O control operation. + $notty + ;;; No such device or address. + $nxio + ;;; Value too large to be stored in data type. + $overflow + ;;; Previous owner died. + $ownerdead + ;;; Operation not permitted. + $perm + ;;; Broken pipe. + $pipe + ;;; Protocol error. + $proto + ;;; Protocol not supported. + $protonosupport + ;;; Protocol wrong type for socket. + $prototype + ;;; Result too large. + $range + ;;; Read-only file system. + $rofs + ;;; Invalid seek. + $spipe + ;;; No such process. + $srch + ;;; Reserved. + $stale + ;;; Connection timed out. + $timedout + ;;; Text file busy. + $txtbsy + ;;; Cross-device link. + $xdev + ;;; Extension: Capabilities insufficient. + $notcapable + ) +) + +;;; File descriptor rights, determining which actions may be performed. +(typename $rights + (flags (@witx repr u64) + ;;; The right to invoke `fd_datasync`. + ;; + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflags::dsync`. + $fd_datasync + ;;; The right to invoke `fd_read` and `sock_recv`. + ;; + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. + $fd_read + ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. + $fd_seek + ;;; The right to invoke `fd_fdstat_set_flags`. + $fd_fdstat_set_flags + ;;; The right to invoke `fd_sync`. + ;; + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. + $fd_sync + ;;; The right to invoke `fd_seek` in such a way that the file offset + ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to + ;;; invoke `fd_tell`. + $fd_tell + ;;; The right to invoke `fd_write` and `sock_send`. + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. + $fd_write + ;;; The right to invoke `fd_advise`. + $fd_advise + ;;; The right to invoke `fd_allocate`. + $fd_allocate + ;;; The right to invoke `path_create_directory`. + $path_create_directory + ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::create`. + $path_create_file + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; source directory. + $path_link_source + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; target directory. + $path_link_target + ;;; The right to invoke `path_open`. + $path_open + ;;; The right to invoke `fd_readdir`. + $fd_readdir + ;;; The right to invoke `path_readlink`. + $path_readlink + ;;; The right to invoke `path_rename` with the file descriptor as the source directory. + $path_rename_source + ;;; The right to invoke `path_rename` with the file descriptor as the target directory. + $path_rename_target + ;;; The right to invoke `path_filestat_get`. + $path_filestat_get + ;;; The right to change a file's size. + ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. + ;;; Note: there is no function named `path_filestat_set_size`. This follows POSIX design, + ;;; which only has `ftruncate` and does not provide `ftruncateat`. + ;;; While such function would be desirable from the API design perspective, there are virtually + ;;; no use cases for it since no code written for POSIX systems would use it. + ;;; Moreover, implementing it would require multiple syscalls, leading to inferior performance. + $path_filestat_set_size + ;;; The right to invoke `path_filestat_set_times`. + $path_filestat_set_times + ;;; The right to invoke `path_permissions_set`. + $path_permissions_set + ;;; The right to invoke `fd_filestat_get`. + $fd_filestat_get + ;;; The right to invoke `fd_filestat_set_size`. + $fd_filestat_set_size + ;;; The right to invoke `fd_filestat_set_times`. + $fd_filestat_set_times + ;;; The right to invoke `fd_permissions_set`. + $fd_permissions_set + ;;; The right to invoke `path_symlink`. + $path_symlink + ;;; The right to invoke `path_remove_directory`. + $path_remove_directory + ;;; The right to invoke `path_unlink_file`. + $path_unlink_file + ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. + ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. + $poll_fd_readwrite + ;;; The right to invoke `sock_shutdown`. + $sock_shutdown + ) +) + +;;; A file descriptor handle. +(typename $fd (handle)) + +;;; A region of memory for scatter/gather reads. +(typename $iovec + (record + ;;; The address of the buffer to be filled. + (field $buf (@witx pointer u8)) + ;;; The length of the buffer to be filled. + (field $buf_len $size) + ) +) + +;;; A region of memory for scatter/gather writes. +(typename $ciovec + (record + ;;; The address of the buffer to be written. + (field $buf (@witx const_pointer u8)) + ;;; The length of the buffer to be written. + (field $buf_len $size) + ) +) + +(typename $iovec_array (list $iovec)) +(typename $ciovec_array (list $ciovec)) + +;;; Relative offset within a file. +(typename $filedelta s64) + +;;; The position relative to which to set the offset of the file descriptor. +(typename $whence + (enum (@witx tag u8) + ;;; Seek relative to start-of-file. + $set + ;;; Seek relative to current position. + $cur + ;;; Seek relative to end-of-file. + $end + ) +) + +;;; A reference to the offset of a directory entry. +(typename $dircookie u64) + +;;; In an `fd_readdir` call, this value signifies the start of the directory. +(@witx const $dircookie $start 0) + +;;; The type for the `dirent::d_namlen` field of `dirent`. +(typename $dirnamlen u32) + +;;; File serial number that is unique within its file system. +(typename $inode u64) + +;;; The type of a file descriptor or file. +(typename $filetype + (enum (@witx tag u8) + ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $unknown + ;;; The file descriptor or file refers to a block device inode. + $block_device + ;;; The file descriptor or file refers to a character device inode. + $character_device + ;;; The file descriptor or file refers to a directory inode. + $directory + ;;; The file descriptor or file refers to a regular file inode. + $regular_file + ;;; The file descriptor or file refers to a datagram socket. + $socket_dgram + ;;; The file descriptor or file refers to a byte-stream socket. + $socket_stream + ;;; The file refers to a symbolic link inode. + $symbolic_link + ;;; The file descriptor or file refers to a FIFO. + $fifo + ) +) + +;;; A directory entry. +(typename $dirent + (record + ;;; The offset of the next directory entry stored in this directory. + (field $d_next $dircookie) + ;;; The serial number of the file referred to by this directory entry. + (field $d_ino $inode) + ;;; The type of the file referred to by this directory entry. + (field $d_type $filetype) + ;;; The length of the name of the directory entry. + (field $d_namlen $dirnamlen) + ) +) + +;;; File or memory access pattern advisory information. +(typename $advice + (enum (@witx tag u8) + ;;; The application has no advice to give on its behavior with respect to the specified data. + $normal + ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + $sequential + ;;; The application expects to access the specified data in a random order. + $random + ;;; The application expects to access the specified data in the near future. + $willneed + ;;; The application expects that it will not access the specified data in the near future. + $dontneed + ;;; The application expects to access the specified data once and then not reuse it thereafter. + $noreuse + ) +) + +;;; File descriptor flags. +(typename $fdflags + (flags (@witx repr u16) + ;;; Append mode: Data written to the file is always appended to the file's end. + $append + ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + $dsync + ;;; Non-blocking mode. + $nonblock + ;;; Synchronized read I/O operations. + $rsync + ;;; Write according to synchronized I/O file integrity completion. In + ;;; addition to synchronizing the data stored in the file, the implementation + ;;; may also synchronously update the file's metadata. + $sync + ) +) + +;;; File descriptor attributes. +(typename $fdstat + (record + ;;; File type. + (field $fs_filetype $filetype) + ;;; File descriptor flags. + (field $fs_flags $fdflags) + ;;; Rights that apply to this file descriptor. + (field $fs_rights_base $rights) + ;;; Maximum set of rights that may be installed on new file descriptors that + ;;; are created through this file descriptor, e.g., through `path_open`. + (field $fs_rights_inheriting $rights) + ) +) + +;;; Identifier for a device containing a file system. Can be used in combination +;;; with `inode` to uniquely identify a file or directory in the filesystem. +(typename $device u64) + +;;; Which file time attributes to adjust. +(typename $fstflags + (flags (@witx repr u16) + ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. + $atim + ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. + $atim_now + ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. + $mtim + ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. + $mtim_now + ) +) + +;;; Flags determining the method of how paths are resolved. +(typename $lookupflags + (flags (@witx repr u32) + ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. + $symlink_follow + ) +) + +;;; Open flags used by `path_open`. +(typename $oflags + (flags (@witx repr u16) + ;;; Create file if it does not exist. + $create + ;;; Fail if not a directory. + $directory + ;;; Fail if file already exists. + $excl + ;;; Truncate file to size 0. + $trunc + ) +) + +;;; Number of hard links to an inode. +(typename $linkcount u64) + +;;; File permissions. This represents the permissions associated with a +;;; file in a filesystem, and don't fully reflect all the conditions +;;; which determine whether a given WASI program can access the file. +(typename $permissions + (flags (@witx repr u8) + ;;; For files, permission to read the file. + ;;; For directories, permission to do `readdir` and access files + ;;; within the directory. + ;;; + ;;; Note: This is similar to the read bit being set on files, and the + ;;; read *and* execute bits being set on directories, in POSIX. + $read + + ;;; For files, permission to mutate the file. + ;;; For directories, permission to create, remove, and rename items + ;;; within the directory. + $write + + ;;; For files, permission to "execute" the file, using whatever + ;;; concept of "executing" the host filesystem has. + ;;; This flag is not valid for directories. + $execute + + ;;; For filesystems which have a concept of multiple "users", this flag + ;;; indicates that the file is only accessible by the effective "user" + ;;; that the WASI store uses to access the filesystem, and inaccessible + ;;; to other "users". + $private + ) +) + +;;; File attributes. +(typename $filestat + (record + ;;; Device ID of device containing the file. + (field $dev $device) + ;;; File serial number. + (field $ino $inode) + ;;; File type. + (field $filetype $filetype) + ;;; File permissions. + (field $permissions $permissions) + ;;; Number of hard links to the file. + (field $nlink $linkcount) + ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + (field $size $filesize) + ;;; Last data access timestamp. + (field $atim $timestamp) + ;;; Last data modification timestamp. + (field $mtim $timestamp) + ;;; Last file status change timestamp. + (field $ctim $timestamp) + ) +) + +;;; User-provided value that may be attached to objects that is retained when +;;; extracted from the implementation. +(typename $userdata u64) + +;;; Type of a subscription to an event or its occurrence. +(typename $eventtype + (enum (@witx tag u8) + ;;; The time value of clock `subscription_clock::id` has + ;;; reached timestamp `subscription_clock::timeout`. + $clock + ;;; File descriptor `subscription_fd_readwrite::fd` has data + ;;; available for reading. This event always triggers for regular files. + $fd_read + ;;; File descriptor `subscription_fd_readwrite::fd` has capacity + ;;; available for writing. This event always triggers for regular files. + $fd_write + ) +) + +;;; The state of the file descriptor subscribed to with +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $eventrwflags + (flags (@witx repr u16) + ;;; The peer of this socket has closed or disconnected. + $fd_readwrite_hangup + ) +) + +;;; The contents of an `event` when type is `eventtype::fd_read` or +;;; `eventtype::fd_write`. +(typename $event_fd_readwrite + (record + ;;; The number of bytes available for reading or writing. + (field $nbytes $filesize) + ;;; The state of the file descriptor. + (field $flags $eventrwflags) + ) +) + +;;; The contents of an `event`. +(typename $event_u + (variant (@witx tag $eventtype) + (case $fd_read $event_fd_readwrite) + (case $fd_write $event_fd_readwrite) + (case $clock) + ) +) + +;;; An event that occurred. +(typename $event + (record + ;;; User-provided value that got attached to `subscription::userdata`. + (field $userdata $userdata) + ;;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno) + ;;; The type of the event that occurred, and the contents of the event + (field $u $event_u) + ) +) + +;;; Flags determining how to interpret the timestamp provided in +;;; `subscription_clock::timeout`. +(typename $subclockflags + (flags (@witx repr u16) + ;;; If set, treat the timestamp provided in + ;;; `subscription_clock::timeout` as an absolute timestamp of clock + ;;; `subscription_clock::id`. If clear, treat the timestamp + ;;; provided in `subscription_clock::timeout` relative to the + ;;; current time value of clock `subscription_clock::id`. + $subscription_clock_abstime + ) +) + +;;; The contents of a `subscription` when type is `eventtype::clock`. +(typename $subscription_clock + (record + ;;; The clock against which to compare the timestamp. + (field $id $clockid) + ;;; The absolute or relative timestamp. + (field $timeout $timestamp) + ;;; The amount of time that the implementation may wait additionally + ;;; to coalesce with other events. + (field $precision $timestamp) + ;;; Flags specifying whether the timeout is absolute or relative + (field $flags $subclockflags) + ) +) + +;;; The contents of a `subscription` when type is type is +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $subscription_fd_readwrite + (record + ;;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $fd $fd) + ) +) + +;;; The contents of a `subscription`. +(typename $subscription_u + (union (@witx tag $eventtype) + $subscription_clock + $subscription_fd_readwrite + $subscription_fd_readwrite + ) +) + +;;; Subscription to an event. +(typename $subscription + (record + ;;; User-provided value that is attached to the subscription in the + ;;; implementation and returned through `event::userdata`. + (field $userdata $userdata) + ;;; The type of the event to which to subscribe, and the contents of the subscription. + (field $u $subscription_u) + ) +) + +;;; Exit code generated by a program when exiting. +(typename $exitcode u8) + +;;; Indicate the program exited successfully. +;;; +;;; Note: This is similar to `EXIT_SUCCESS` in POSIX. +(@witx const $exitcode $success 0) + +;;; Indicate the program exited unsuccessfully. +;;; +;;; Note: This is similar to `EXIT_FAILURE` in POSIX. +(@witx const $exitcode $failure 1) + +;;; Flags provided to `sock_recv`. +(typename $riflags + (flags (@witx repr u16) + ;;; Returns the message without removing it from the socket's receive queue. + $recv_peek + ;;; On byte-stream sockets, block until the full amount of data can be returned. + $recv_waitall + ) +) + +;;; Flags returned by `sock_recv`. +(typename $roflags + (flags (@witx repr u16) + ;;; Returned by `sock_recv`: Message data has been truncated. + $recv_data_truncated + ) +) + +;;; Flags provided to `sock_send`. As there are currently no flags +;;; defined, it must be set to zero. +(typename $siflags u16) + +;;; Which channels on a socket to shut down. +(typename $sdflags + (flags (@witx repr u8) + ;;; Disables further receive operations. + $rd + ;;; Disables further send operations. + $wr + ) +) + +;;; Identifiers for preopened capabilities. +(typename $preopentype + (enum (@witx tag u8) + ;;; A pre-opened directory. + $dir + ) +) + +;;; The contents of a `prestat` when its type is `preopentype::dir`. +(typename $prestat_dir + (record + ;;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size) + ) +) + +;;; Information about a pre-opened capability. +(typename $prestat + (union (@witx tag $preopentype) + ;;; When type is `preopentype::dir`: + $prestat_dir + ) +) diff --git a/proposals/clocks/tools/repo_docs.sh b/proposals/clocks/tools/repo_docs.sh index e0187bcaf..76d1462bc 100755 --- a/proposals/clocks/tools/repo_docs.sh +++ b/proposals/clocks/tools/repo_docs.sh @@ -15,3 +15,8 @@ cargo run -p witx-cli -- docs $1 \ ../../phases/ephemeral/witx/wasi_ephemeral_sched.witx \ ../../phases/ephemeral/witx/wasi_ephemeral_sock.witx \ --output ../../phases/ephemeral/docs.md + +for dir in ../../standard/*/witx; do + cargo run -p witx-cli -- docs $1 "$dir"/*.witx \ + --output "$dir"/../docs.md +done From e875485ee2ef08b62ce58677dead012723f2e3da Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 9 Mar 2021 12:37:08 -0800 Subject: [PATCH 0899/1772] Auto-generate the documentation. --- proposals/random/standard/wasi-random/docs.md | 1242 +++++++++++++++++ proposals/random/tools/repo_docs.sh | 5 + 2 files changed, 1247 insertions(+) create mode 100644 proposals/random/standard/wasi-random/docs.md diff --git a/proposals/random/standard/wasi-random/docs.md b/proposals/random/standard/wasi-random/docs.md new file mode 100644 index 000000000..cfe589f3b --- /dev/null +++ b/proposals/random/standard/wasi-random/docs.md @@ -0,0 +1,1242 @@ +# Types +## `size`: `usize` +An array size. + +Note: This is similar to `size_t` in POSIX. + +Size: 4 + +Alignment: 4 + +## `filesize`: `u64` +Non-negative file size or length of a region within a file. + +Size: 8 + +Alignment: 8 + +## `timestamp`: `u64` +Timestamp in nanoseconds. + +Size: 8 + +Alignment: 8 + +## `clockid`: `Variant` +Identifiers for clocks. + +Size: 4 + +Alignment: 4 + +### Variant cases +- `realtime` +The clock measuring real time. Time value zero corresponds with +1970-01-01T00:00:00Z. + +- `monotonic` +The store-wide monotonic clock, which is defined as a clock measuring +real time, whose value cannot be adjusted and which cannot have negative +clock jumps. The epoch of this clock is undefined. The absolute time +value of this clock therefore has no meaning. + +## `errno`: `Variant` +Error codes returned by functions. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX. + +Size: 2 + +Alignment: 2 + +### Variant cases +- `success` +No error occurred. System call completed successfully. + +- `2big` +Argument list too long. + +- `access` +Permission denied. + +- `addrinuse` +Address in use. + +- `addrnotavail` +Address not available. + +- `afnosupport` +Address family not supported. + +- `again` +Resource unavailable, or operation would block. + +- `already` +Connection already in progress. + +- `badf` +Bad file descriptor. + +- `badmsg` +Bad message. + +- `busy` +Device or resource busy. + +- `canceled` +Operation canceled. + +- `child` +No child processes. + +- `connaborted` +Connection aborted. + +- `connrefused` +Connection refused. + +- `connreset` +Connection reset. + +- `deadlk` +Resource deadlock would occur. + +- `destaddrreq` +Destination address required. + +- `dom` +Mathematics argument out of domain of function. + +- `dquot` +Reserved. + +- `exist` +File exists. + +- `fault` +Bad address. + +- `fbig` +File too large. + +- `hostunreach` +Host is unreachable. + +- `idrm` +Identifier removed. + +- `ilseq` +Illegal byte sequence. + +- `inprogress` +Operation in progress. + +- `intr` +Interrupted function. + +- `inval` +Invalid argument. + +- `io` +I/O error. + +- `isconn` +Socket is connected. + +- `isdir` +Is a directory. + +- `loop` +Too many levels of symbolic links. + +- `mfile` +File descriptor value too large. + +- `mlink` +Too many links. + +- `msgsize` +Message too large. + +- `multihop` +Reserved. + +- `nametoolong` +Filename too long. + +- `netdown` +Network is down. + +- `netreset` +Connection aborted by network. + +- `netunreach` +Network unreachable. + +- `nfile` +Too many files open in system. + +- `nobufs` +No buffer space available. + +- `nodev` +No such device. + +- `noent` +No such file or directory. + +- `noexec` +Executable file format error. + +- `nolck` +No locks available. + +- `nolink` +Reserved. + +- `nomem` +Not enough space. + +- `nomsg` +No message of the desired type. + +- `noprotoopt` +Protocol not available. + +- `nospc` +No space left on device. + +- `nosys` +Function not supported. + +- `notconn` +The socket is not connected. + +- `notdir` +Not a directory or a symbolic link to a directory. + +- `notempty` +Directory not empty. + +- `notrecoverable` +State not recoverable. + +- `notsock` +Not a socket. + +- `notsup` +Not supported, or operation not supported on socket. + +- `notty` +Inappropriate I/O control operation. + +- `nxio` +No such device or address. + +- `overflow` +Value too large to be stored in data type. + +- `ownerdead` +Previous owner died. + +- `perm` +Operation not permitted. + +- `pipe` +Broken pipe. + +- `proto` +Protocol error. + +- `protonosupport` +Protocol not supported. + +- `prototype` +Protocol wrong type for socket. + +- `range` +Result too large. + +- `rofs` +Read-only file system. + +- `spipe` +Invalid seek. + +- `srch` +No such process. + +- `stale` +Reserved. + +- `timedout` +Connection timed out. + +- `txtbsy` +Text file busy. + +- `xdev` +Cross-device link. + +- `notcapable` +Extension: Capabilities insufficient. + +## `rights`: `Record` +File descriptor rights, determining which actions may be performed. + +Size: 8 + +Alignment: 8 + +### Record members +- `fd_datasync`: `bool` +The right to invoke `fd_datasync`. +If `path_open` is set, includes the right to invoke +`path_open` with [`fdflags::dsync`](#fdflags.dsync). + +Bit: 0 + +- `fd_read`: `bool` +The right to invoke `fd_read` and `sock_recv`. +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. + +Bit: 1 + +- `fd_seek`: `bool` +The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). + +Bit: 2 + +- `fd_fdstat_set_flags`: `bool` +The right to invoke `fd_fdstat_set_flags`. + +Bit: 3 + +- `fd_sync`: `bool` +The right to invoke `fd_sync`. +If `path_open` is set, includes the right to invoke +`path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). + +Bit: 4 + +- `fd_tell`: `bool` +The right to invoke `fd_seek` in such a way that the file offset +remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to +invoke `fd_tell`. + +Bit: 5 + +- `fd_write`: `bool` +The right to invoke `fd_write` and `sock_send`. +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. + +Bit: 6 + +- `fd_advise`: `bool` +The right to invoke `fd_advise`. + +Bit: 7 + +- `fd_allocate`: `bool` +The right to invoke `fd_allocate`. + +Bit: 8 + +- `path_create_directory`: `bool` +The right to invoke `path_create_directory`. + +Bit: 9 + +- `path_create_file`: `bool` +If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). + +Bit: 10 + +- `path_link_source`: `bool` +The right to invoke `path_link` with the file descriptor as the +source directory. + +Bit: 11 + +- `path_link_target`: `bool` +The right to invoke `path_link` with the file descriptor as the +target directory. + +Bit: 12 + +- `path_open`: `bool` +The right to invoke `path_open`. + +Bit: 13 + +- `fd_readdir`: `bool` +The right to invoke `fd_readdir`. + +Bit: 14 + +- `path_readlink`: `bool` +The right to invoke `path_readlink`. + +Bit: 15 + +- `path_rename_source`: `bool` +The right to invoke `path_rename` with the file descriptor as the source directory. + +Bit: 16 + +- `path_rename_target`: `bool` +The right to invoke `path_rename` with the file descriptor as the target directory. + +Bit: 17 + +- `path_filestat_get`: `bool` +The right to invoke `path_filestat_get`. + +Bit: 18 + +- `path_filestat_set_size`: `bool` +The right to change a file's size. +If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). +Note: there is no function named `path_filestat_set_size`. This follows POSIX design, +which only has `ftruncate` and does not provide `ftruncateat`. +While such function would be desirable from the API design perspective, there are virtually +no use cases for it since no code written for POSIX systems would use it. +Moreover, implementing it would require multiple syscalls, leading to inferior performance. + +Bit: 19 + +- `path_filestat_set_times`: `bool` +The right to invoke `path_filestat_set_times`. + +Bit: 20 + +- `path_permissions_set`: `bool` +The right to invoke `path_permissions_set`. + +Bit: 21 + +- `fd_filestat_get`: `bool` +The right to invoke `fd_filestat_get`. + +Bit: 22 + +- `fd_filestat_set_size`: `bool` +The right to invoke `fd_filestat_set_size`. + +Bit: 23 + +- `fd_filestat_set_times`: `bool` +The right to invoke `fd_filestat_set_times`. + +Bit: 24 + +- `fd_permissions_set`: `bool` +The right to invoke `fd_permissions_set`. + +Bit: 25 + +- `path_symlink`: `bool` +The right to invoke `path_symlink`. + +Bit: 26 + +- `path_remove_directory`: `bool` +The right to invoke `path_remove_directory`. + +Bit: 27 + +- `path_unlink_file`: `bool` +The right to invoke `path_unlink_file`. + +Bit: 28 + +- `poll_fd_readwrite`: `bool` +If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). +If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). + +Bit: 29 + +- `sock_shutdown`: `bool` +The right to invoke `sock_shutdown`. + +Bit: 30 + +## `fd`: `Handle` +A file descriptor handle. + +Size: 4 + +Alignment: 4 + +### Supertypes +## `iovec`: `Record` +A region of memory for scatter/gather reads. + +Size: 8 + +Alignment: 4 + +### Record members +- `buf`: `Pointer` +The address of the buffer to be filled. + +Offset: 0 + +- `buf_len`: [`size`](#size) +The length of the buffer to be filled. + +Offset: 4 + +## `ciovec`: `Record` +A region of memory for scatter/gather writes. + +Size: 8 + +Alignment: 4 + +### Record members +- `buf`: `ConstPointer` +The address of the buffer to be written. + +Offset: 0 + +- `buf_len`: [`size`](#size) +The length of the buffer to be written. + +Offset: 4 + +## `iovec_array`: `List` + +Size: 8 + +Alignment: 4 + +## `ciovec_array`: `List` + +Size: 8 + +Alignment: 4 + +## `filedelta`: `s64` +Relative offset within a file. + +Size: 8 + +Alignment: 8 + +## `whence`: `Variant` +The position relative to which to set the offset of the file descriptor. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `set` +Seek relative to start-of-file. + +- `cur` +Seek relative to current position. + +- `end` +Seek relative to end-of-file. + +## `dircookie`: `u64` +A reference to the offset of a directory entry. + +Size: 8 + +Alignment: 8 + +### Constants +- `start` + +## `dirnamlen`: `u32` +The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). + +Size: 4 + +Alignment: 4 + +## `inode`: `u64` +File serial number that is unique within its file system. + +Size: 8 + +Alignment: 8 + +## `filetype`: `Variant` +The type of a file descriptor or file. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `unknown` +The type of the file descriptor or file is unknown or is different from any of the other types specified. + +- `block_device` +The file descriptor or file refers to a block device inode. + +- `character_device` +The file descriptor or file refers to a character device inode. + +- `directory` +The file descriptor or file refers to a directory inode. + +- `regular_file` +The file descriptor or file refers to a regular file inode. + +- `socket_dgram` +The file descriptor or file refers to a datagram socket. + +- `socket_stream` +The file descriptor or file refers to a byte-stream socket. + +- `symbolic_link` +The file refers to a symbolic link inode. + +- `fifo` +The file descriptor or file refers to a FIFO. + +## `dirent`: `Record` +A directory entry. + +Size: 24 + +Alignment: 8 + +### Record members +- `d_next`: [`dircookie`](#dircookie) +The offset of the next directory entry stored in this directory. + +Offset: 0 + +- `d_ino`: [`inode`](#inode) +The serial number of the file referred to by this directory entry. + +Offset: 8 + +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. + +Offset: 16 + +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. + +Offset: 20 + +## `advice`: `Variant` +File or memory access pattern advisory information. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `normal` +The application has no advice to give on its behavior with respect to the specified data. + +- `sequential` +The application expects to access the specified data sequentially from lower offsets to higher offsets. + +- `random` +The application expects to access the specified data in a random order. + +- `willneed` +The application expects to access the specified data in the near future. + +- `dontneed` +The application expects that it will not access the specified data in the near future. + +- `noreuse` +The application expects to access the specified data once and then not reuse it thereafter. + +## `fdflags`: `Record` +File descriptor flags. + +Size: 2 + +Alignment: 2 + +### Record members +- `append`: `bool` +Append mode: Data written to the file is always appended to the file's end. + +Bit: 0 + +- `dsync`: `bool` +Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + +Bit: 1 + +- `nonblock`: `bool` +Non-blocking mode. + +Bit: 2 + +- `rsync`: `bool` +Synchronized read I/O operations. + +Bit: 3 + +- `sync`: `bool` +Write according to synchronized I/O file integrity completion. In +addition to synchronizing the data stored in the file, the implementation +may also synchronously update the file's metadata. + +Bit: 4 + +## `fdstat`: `Record` +File descriptor attributes. + +Size: 24 + +Alignment: 8 + +### Record members +- `fs_filetype`: [`filetype`](#filetype) +File type. + +Offset: 0 + +- `fs_flags`: [`fdflags`](#fdflags) +File descriptor flags. + +Offset: 2 + +- `fs_rights_base`: [`rights`](#rights) +Rights that apply to this file descriptor. + +Offset: 8 + +- `fs_rights_inheriting`: [`rights`](#rights) +Maximum set of rights that may be installed on new file descriptors that +are created through this file descriptor, e.g., through `path_open`. + +Offset: 16 + +## `device`: `u64` +Identifier for a device containing a file system. Can be used in combination +with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. + +Size: 8 + +Alignment: 8 + +## `fstflags`: `Record` +Which file time attributes to adjust. + +Size: 2 + +Alignment: 2 + +### Record members +- `atim`: `bool` +Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). + +Bit: 0 + +- `atim_now`: `bool` +Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). + +Bit: 1 + +- `mtim`: `bool` +Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). + +Bit: 2 + +- `mtim_now`: `bool` +Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). + +Bit: 3 + +## `lookupflags`: `Record` +Flags determining the method of how paths are resolved. + +Size: 4 + +Alignment: 4 + +### Record members +- `symlink_follow`: `bool` +As long as the resolved path corresponds to a symbolic link, it is expanded. + +Bit: 0 + +## `oflags`: `Record` +Open flags used by `path_open`. + +Size: 2 + +Alignment: 2 + +### Record members +- `create`: `bool` +Create file if it does not exist. + +Bit: 0 + +- `directory`: `bool` +Fail if not a directory. + +Bit: 1 + +- `excl`: `bool` +Fail if file already exists. + +Bit: 2 + +- `trunc`: `bool` +Truncate file to size 0. + +Bit: 3 + +## `linkcount`: `u64` +Number of hard links to an inode. + +Size: 8 + +Alignment: 8 + +## `permissions`: `Record` +File permissions. This represents the permissions associated with a +file in a filesystem, and don't fully reflect all the conditions +which determine whether a given WASI program can access the file. + +Size: 1 + +Alignment: 1 + +### Record members +- `read`: `bool` +For files, permission to read the file. +For directories, permission to do `readdir` and access files +within the directory. + +Note: This is similar to the read bit being set on files, and the +read *and* execute bits being set on directories, in POSIX. + +Bit: 0 + +- `write`: `bool` +For files, permission to mutate the file. +For directories, permission to create, remove, and rename items +within the directory. + +Bit: 1 + +- `execute`: `bool` +For files, permission to "execute" the file, using whatever +concept of "executing" the host filesystem has. +This flag is not valid for directories. + +Bit: 2 + +- `private`: `bool` +For filesystems which have a concept of multiple "users", this flag +indicates that the file is only accessible by the effective "user" +that the WASI store uses to access the filesystem, and inaccessible +to other "users". + +Bit: 3 + +## `filestat`: `Record` +File attributes. + +Size: 64 + +Alignment: 8 + +### Record members +- `dev`: [`device`](#device) +Device ID of device containing the file. + +Offset: 0 + +- `ino`: [`inode`](#inode) +File serial number. + +Offset: 8 + +- `filetype`: [`filetype`](#filetype) +File type. + +Offset: 16 + +- `permissions`: [`permissions`](#permissions) +File permissions. + +Offset: 17 + +- `nlink`: [`linkcount`](#linkcount) +Number of hard links to the file. + +Offset: 24 + +- `size`: [`filesize`](#filesize) +For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + +Offset: 32 + +- `atim`: [`timestamp`](#timestamp) +Last data access timestamp. + +Offset: 40 + +- `mtim`: [`timestamp`](#timestamp) +Last data modification timestamp. + +Offset: 48 + +- `ctim`: [`timestamp`](#timestamp) +Last file status change timestamp. + +Offset: 56 + +## `userdata`: `u64` +User-provided value that may be attached to objects that is retained when +extracted from the implementation. + +Size: 8 + +Alignment: 8 + +## `eventtype`: `Variant` +Type of a subscription to an event or its occurrence. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `clock` +The time value of clock [`subscription_clock::id`](#subscription_clock.id) has +reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). + +- `fd_read` +File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has data +available for reading. This event always triggers for regular files. + +- `fd_write` +File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity +available for writing. This event always triggers for regular files. + +## `eventrwflags`: `Record` +The state of the file descriptor subscribed to with +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +Size: 2 + +Alignment: 2 + +### Record members +- `fd_readwrite_hangup`: `bool` +The peer of this socket has closed or disconnected. + +Bit: 0 + +## `event_fd_readwrite`: `Record` +The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). + +Size: 16 + +Alignment: 8 + +### Record members +- `nbytes`: [`filesize`](#filesize) +The number of bytes available for reading or writing. + +Offset: 0 + +- `flags`: [`eventrwflags`](#eventrwflags) +The state of the file descriptor. + +Offset: 8 + +## `event_u`: `Variant` +The contents of an [`event`](#event). + +Size: 24 + +Alignment: 8 + +### Variant Layout +- size: 24 +- align: 8 +- tag_size: 1 +### Variant cases +- `clock` + +- `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) + +- `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) + +## `event`: `Record` +An event that occurred. + +Size: 40 + +Alignment: 8 + +### Record members +- `userdata`: [`userdata`](#userdata) +User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). + +Offset: 0 + +- `error`: [`errno`](#errno) +If non-zero, an error that occurred while processing the subscription request. + +Offset: 8 + +- `u`: [`event_u`](#event_u) +The type of the event that occurred, and the contents of the event + +Offset: 16 + +## `subclockflags`: `Record` +Flags determining how to interpret the timestamp provided in +[`subscription_clock::timeout`](#subscription_clock.timeout). + +Size: 2 + +Alignment: 2 + +### Record members +- `subscription_clock_abstime`: `bool` +If set, treat the timestamp provided in +[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock +[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp +provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the +current time value of clock [`subscription_clock::id`](#subscription_clock.id). + +Bit: 0 + +## `subscription_clock`: `Record` +The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). + +Size: 32 + +Alignment: 8 + +### Record members +- `id`: [`clockid`](#clockid) +The clock against which to compare the timestamp. + +Offset: 0 + +- `timeout`: [`timestamp`](#timestamp) +The absolute or relative timestamp. + +Offset: 8 + +- `precision`: [`timestamp`](#timestamp) +The amount of time that the implementation may wait additionally +to coalesce with other events. + +Offset: 16 + +- `flags`: [`subclockflags`](#subclockflags) +Flags specifying whether the timeout is absolute or relative + +Offset: 24 + +## `subscription_fd_readwrite`: `Record` +The contents of a [`subscription`](#subscription) when type is type is +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +Size: 4 + +Alignment: 4 + +### Record members +- `fd`: [`fd`](#fd) +The file descriptor on which to wait for it to become ready for reading or writing. + +Offset: 0 + +## `subscription_u`: `Variant` +The contents of a [`subscription`](#subscription). + +Size: 40 + +Alignment: 8 + +### Variant Layout +- size: 40 +- align: 8 +- tag_size: 1 +### Variant cases +- `clock`: [`subscription_clock`](#subscription_clock) + +- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +## `subscription`: `Record` +Subscription to an event. + +Size: 48 + +Alignment: 8 + +### Record members +- `userdata`: [`userdata`](#userdata) +User-provided value that is attached to the subscription in the +implementation and returned through [`event::userdata`](#event.userdata). + +Offset: 0 + +- `u`: [`subscription_u`](#subscription_u) +The type of the event to which to subscribe, and the contents of the subscription. + +Offset: 8 + +## `exitcode`: `u8` +Exit code generated by a program when exiting. + +Size: 1 + +Alignment: 1 + +### Constants +- `success` + +- `failure` + +## `riflags`: `Record` +Flags provided to `sock_recv`. + +Size: 2 + +Alignment: 2 + +### Record members +- `recv_peek`: `bool` +Returns the message without removing it from the socket's receive queue. + +Bit: 0 + +- `recv_waitall`: `bool` +On byte-stream sockets, block until the full amount of data can be returned. + +Bit: 1 + +## `roflags`: `Record` +Flags returned by `sock_recv`. + +Size: 2 + +Alignment: 2 + +### Record members +- `recv_data_truncated`: `bool` +Returned by `sock_recv`: Message data has been truncated. + +Bit: 0 + +## `siflags`: `u16` +Flags provided to `sock_send`. As there are currently no flags +defined, it must be set to zero. + +Size: 2 + +Alignment: 2 + +## `sdflags`: `Record` +Which channels on a socket to shut down. + +Size: 1 + +Alignment: 1 + +### Record members +- `rd`: `bool` +Disables further receive operations. + +Bit: 0 + +- `wr`: `bool` +Disables further send operations. + +Bit: 1 + +## `preopentype`: `Variant` +Identifiers for preopened capabilities. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `dir` +A pre-opened directory. + +## `prestat_dir`: `Record` +The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). + +Size: 4 + +Alignment: 4 + +### Record members +- `pr_name_len`: [`size`](#size) +The length of the directory name for use with `fd_prestat_dir_name`. + +Offset: 0 + +## `prestat`: `Variant` +Information about a pre-opened capability. + +Size: 8 + +Alignment: 4 + +### Variant Layout +- size: 8 +- align: 4 +- tag_size: 1 +### Variant cases +- `dir`: [`prestat_dir`](#prestat_dir) +When type is [`preopentype::dir`](#preopentype.dir): + +# Modules +## wasi_ephemeral_random +### Imports +#### Memory +### Functions + +--- + +#### `get(buf: Pointer, buf_len: size) -> Result<(), errno>` +Write high-quality random data into a buffer. +This function blocks when the implementation is unable to immediately +provide sufficient high-quality random data. +This function may execute slowly, so when large amounts of random data are +required, it's advisable to use this function to seed a pseudo-random +number generator, rather than to provide the random data directly. + +##### Params +- `buf`: `Pointer` +The buffer to fill with random data. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + diff --git a/proposals/random/tools/repo_docs.sh b/proposals/random/tools/repo_docs.sh index e0187bcaf..76d1462bc 100755 --- a/proposals/random/tools/repo_docs.sh +++ b/proposals/random/tools/repo_docs.sh @@ -15,3 +15,8 @@ cargo run -p witx-cli -- docs $1 \ ../../phases/ephemeral/witx/wasi_ephemeral_sched.witx \ ../../phases/ephemeral/witx/wasi_ephemeral_sock.witx \ --output ../../phases/ephemeral/docs.md + +for dir in ../../standard/*/witx; do + cargo run -p witx-cli -- docs $1 "$dir"/*.witx \ + --output "$dir"/../docs.md +done From 40db8c58d8532e0ca4db348ecb3b57ad9034ba07 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 9 Mar 2021 13:42:13 -0800 Subject: [PATCH 0900/1772] Regenerate the docs. (#407) It appears I didn't fully regenerate the docs after merging #235. This runs the tools/repo_docs.sh script to regenerate them. --- proposals/filesystem/phases/ephemeral/docs.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md index 555d74e27..f29d401c4 100644 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ b/proposals/filesystem/phases/ephemeral/docs.md @@ -1098,12 +1098,17 @@ The type of the event to which to subscribe, and the contents of the subscriptio Offset: 8 -## `exitcode`: `u32` -Exit code generated by a process when exiting. +## `exitcode`: `u8` +Exit code generated by a program when exiting. -Size: 4 +Size: 1 -Alignment: 4 +Alignment: 1 + +### Constants +- `success` + +- `failure` ## `riflags`: `Record` Flags provided to `sock_recv`. From 9424311f866c8107acde332688a8310b375777a6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 9 Mar 2021 13:52:37 -0800 Subject: [PATCH 0901/1772] Update the message that says how to regenerate the docs. (#408) * Update the message that says how to regenerate the docs. * rustfmt --- proposals/filesystem/tools/witx/cli/src/main.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/proposals/filesystem/tools/witx/cli/src/main.rs b/proposals/filesystem/tools/witx/cli/src/main.rs index bd1d38dc8..bdb1c6a9c 100644 --- a/proposals/filesystem/tools/witx/cli/src/main.rs +++ b/proposals/filesystem/tools/witx/cli/src/main.rs @@ -262,9 +262,7 @@ fn diff_against_filesystem(expected: &str, path: &Path) -> Result<(), ()> { } eprintln!(); - eprintln!( - "To regenerate the files, run `cd tools/witx && cargo run --example witx repo-docs`." - ); + eprintln!("To regenerate the files, run `tools/repo_docs.sh`."); eprintln!(); Err(()) } From bfdbd4602808e205a60a63cb0398cfcc5aceb414 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 9 Mar 2021 13:37:41 -0800 Subject: [PATCH 0902/1772] Update and rebase on WASI main. As part of the move to modularize WASI, I've now reset the `main` branch in this repository to be the same as that if the [`WASI` repository], and this is now a PR on top of that. This implements the directory structure described in WebAssembly/WASI#360, with a standard directory, and a wasi-clocks directory under that. [`WASI` repository]: https://github.com/WebAssembly/WASI/ --- .../standard/wasi-filesystem/docs.md | 2109 +++++++++++++++++ .../wasi-filesystem/witx/file_io.witx | 236 ++ .../standard/wasi-filesystem/witx/path.witx | 181 ++ .../wasi-filesystem/witx/typenames.witx | 708 ++++++ proposals/filesystem/tools/repo_docs.sh | 5 + 5 files changed, 3239 insertions(+) create mode 100644 proposals/filesystem/standard/wasi-filesystem/docs.md create mode 100644 proposals/filesystem/standard/wasi-filesystem/witx/file_io.witx create mode 100644 proposals/filesystem/standard/wasi-filesystem/witx/path.witx create mode 100644 proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx diff --git a/proposals/filesystem/standard/wasi-filesystem/docs.md b/proposals/filesystem/standard/wasi-filesystem/docs.md new file mode 100644 index 000000000..a172f08b2 --- /dev/null +++ b/proposals/filesystem/standard/wasi-filesystem/docs.md @@ -0,0 +1,2109 @@ +# Types +## `size`: `usize` +An array size. + +Note: This is similar to `size_t` in POSIX. + +Size: 4 + +Alignment: 4 + +## `filesize`: `u64` +Non-negative file size or length of a region within a file. + +Size: 8 + +Alignment: 8 + +## `timestamp`: `u64` +Timestamp in nanoseconds. + +Size: 8 + +Alignment: 8 + +## `clockid`: `Variant` +Identifiers for clocks. + +Size: 4 + +Alignment: 4 + +### Variant cases +- `realtime` +The clock measuring real time. Time value zero corresponds with +1970-01-01T00:00:00Z. + +- `monotonic` +The store-wide monotonic clock, which is defined as a clock measuring +real time, whose value cannot be adjusted and which cannot have negative +clock jumps. The epoch of this clock is undefined. The absolute time +value of this clock therefore has no meaning. + +## `errno`: `Variant` +Error codes returned by functions. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX. + +Size: 2 + +Alignment: 2 + +### Variant cases +- `success` +No error occurred. System call completed successfully. + +- `2big` +Argument list too long. + +- `access` +Permission denied. + +- `addrinuse` +Address in use. + +- `addrnotavail` +Address not available. + +- `afnosupport` +Address family not supported. + +- `again` +Resource unavailable, or operation would block. + +- `already` +Connection already in progress. + +- `badf` +Bad file descriptor. + +- `badmsg` +Bad message. + +- `busy` +Device or resource busy. + +- `canceled` +Operation canceled. + +- `child` +No child processes. + +- `connaborted` +Connection aborted. + +- `connrefused` +Connection refused. + +- `connreset` +Connection reset. + +- `deadlk` +Resource deadlock would occur. + +- `destaddrreq` +Destination address required. + +- `dom` +Mathematics argument out of domain of function. + +- `dquot` +Reserved. + +- `exist` +File exists. + +- `fault` +Bad address. + +- `fbig` +File too large. + +- `hostunreach` +Host is unreachable. + +- `idrm` +Identifier removed. + +- `ilseq` +Illegal byte sequence. + +- `inprogress` +Operation in progress. + +- `intr` +Interrupted function. + +- `inval` +Invalid argument. + +- `io` +I/O error. + +- `isconn` +Socket is connected. + +- `isdir` +Is a directory. + +- `loop` +Too many levels of symbolic links. + +- `mfile` +File descriptor value too large. + +- `mlink` +Too many links. + +- `msgsize` +Message too large. + +- `multihop` +Reserved. + +- `nametoolong` +Filename too long. + +- `netdown` +Network is down. + +- `netreset` +Connection aborted by network. + +- `netunreach` +Network unreachable. + +- `nfile` +Too many files open in system. + +- `nobufs` +No buffer space available. + +- `nodev` +No such device. + +- `noent` +No such file or directory. + +- `noexec` +Executable file format error. + +- `nolck` +No locks available. + +- `nolink` +Reserved. + +- `nomem` +Not enough space. + +- `nomsg` +No message of the desired type. + +- `noprotoopt` +Protocol not available. + +- `nospc` +No space left on device. + +- `nosys` +Function not supported. + +- `notconn` +The socket is not connected. + +- `notdir` +Not a directory or a symbolic link to a directory. + +- `notempty` +Directory not empty. + +- `notrecoverable` +State not recoverable. + +- `notsock` +Not a socket. + +- `notsup` +Not supported, or operation not supported on socket. + +- `notty` +Inappropriate I/O control operation. + +- `nxio` +No such device or address. + +- `overflow` +Value too large to be stored in data type. + +- `ownerdead` +Previous owner died. + +- `perm` +Operation not permitted. + +- `pipe` +Broken pipe. + +- `proto` +Protocol error. + +- `protonosupport` +Protocol not supported. + +- `prototype` +Protocol wrong type for socket. + +- `range` +Result too large. + +- `rofs` +Read-only file system. + +- `spipe` +Invalid seek. + +- `srch` +No such process. + +- `stale` +Reserved. + +- `timedout` +Connection timed out. + +- `txtbsy` +Text file busy. + +- `xdev` +Cross-device link. + +- `notcapable` +Extension: Capabilities insufficient. + +## `rights`: `Record` +File descriptor rights, determining which actions may be performed. + +Size: 8 + +Alignment: 8 + +### Record members +- `fd_datasync`: `bool` +The right to invoke `fd_datasync`. +If `path_open` is set, includes the right to invoke +`path_open` with [`fdflags::dsync`](#fdflags.dsync). + +Bit: 0 + +- `fd_read`: `bool` +The right to invoke `fd_read` and `sock_recv`. +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. + +Bit: 1 + +- `fd_seek`: `bool` +The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). + +Bit: 2 + +- `fd_fdstat_set_flags`: `bool` +The right to invoke `fd_fdstat_set_flags`. + +Bit: 3 + +- `fd_sync`: `bool` +The right to invoke `fd_sync`. +If `path_open` is set, includes the right to invoke +`path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). + +Bit: 4 + +- `fd_tell`: `bool` +The right to invoke `fd_seek` in such a way that the file offset +remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to +invoke `fd_tell`. + +Bit: 5 + +- `fd_write`: `bool` +The right to invoke `fd_write` and `sock_send`. +If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. + +Bit: 6 + +- `fd_advise`: `bool` +The right to invoke `fd_advise`. + +Bit: 7 + +- `fd_allocate`: `bool` +The right to invoke `fd_allocate`. + +Bit: 8 + +- `path_create_directory`: `bool` +The right to invoke `path_create_directory`. + +Bit: 9 + +- `path_create_file`: `bool` +If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). + +Bit: 10 + +- `path_link_source`: `bool` +The right to invoke `path_link` with the file descriptor as the +source directory. + +Bit: 11 + +- `path_link_target`: `bool` +The right to invoke `path_link` with the file descriptor as the +target directory. + +Bit: 12 + +- `path_open`: `bool` +The right to invoke `path_open`. + +Bit: 13 + +- `fd_readdir`: `bool` +The right to invoke `fd_readdir`. + +Bit: 14 + +- `path_readlink`: `bool` +The right to invoke `path_readlink`. + +Bit: 15 + +- `path_rename_source`: `bool` +The right to invoke `path_rename` with the file descriptor as the source directory. + +Bit: 16 + +- `path_rename_target`: `bool` +The right to invoke `path_rename` with the file descriptor as the target directory. + +Bit: 17 + +- `path_filestat_get`: `bool` +The right to invoke `path_filestat_get`. + +Bit: 18 + +- `path_filestat_set_size`: `bool` +The right to change a file's size. +If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). +Note: there is no function named `path_filestat_set_size`. This follows POSIX design, +which only has `ftruncate` and does not provide `ftruncateat`. +While such function would be desirable from the API design perspective, there are virtually +no use cases for it since no code written for POSIX systems would use it. +Moreover, implementing it would require multiple syscalls, leading to inferior performance. + +Bit: 19 + +- `path_filestat_set_times`: `bool` +The right to invoke `path_filestat_set_times`. + +Bit: 20 + +- `path_permissions_set`: `bool` +The right to invoke `path_permissions_set`. + +Bit: 21 + +- `fd_filestat_get`: `bool` +The right to invoke `fd_filestat_get`. + +Bit: 22 + +- `fd_filestat_set_size`: `bool` +The right to invoke `fd_filestat_set_size`. + +Bit: 23 + +- `fd_filestat_set_times`: `bool` +The right to invoke `fd_filestat_set_times`. + +Bit: 24 + +- `fd_permissions_set`: `bool` +The right to invoke `fd_permissions_set`. + +Bit: 25 + +- `path_symlink`: `bool` +The right to invoke `path_symlink`. + +Bit: 26 + +- `path_remove_directory`: `bool` +The right to invoke `path_remove_directory`. + +Bit: 27 + +- `path_unlink_file`: `bool` +The right to invoke `path_unlink_file`. + +Bit: 28 + +- `poll_fd_readwrite`: `bool` +If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). +If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). + +Bit: 29 + +- `sock_shutdown`: `bool` +The right to invoke `sock_shutdown`. + +Bit: 30 + +## `fd`: `Handle` +A file descriptor handle. + +Size: 4 + +Alignment: 4 + +### Supertypes +## `iovec`: `Record` +A region of memory for scatter/gather reads. + +Size: 8 + +Alignment: 4 + +### Record members +- `buf`: `Pointer` +The address of the buffer to be filled. + +Offset: 0 + +- `buf_len`: [`size`](#size) +The length of the buffer to be filled. + +Offset: 4 + +## `ciovec`: `Record` +A region of memory for scatter/gather writes. + +Size: 8 + +Alignment: 4 + +### Record members +- `buf`: `ConstPointer` +The address of the buffer to be written. + +Offset: 0 + +- `buf_len`: [`size`](#size) +The length of the buffer to be written. + +Offset: 4 + +## `iovec_array`: `List` + +Size: 8 + +Alignment: 4 + +## `ciovec_array`: `List` + +Size: 8 + +Alignment: 4 + +## `filedelta`: `s64` +Relative offset within a file. + +Size: 8 + +Alignment: 8 + +## `whence`: `Variant` +The position relative to which to set the offset of the file descriptor. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `set` +Seek relative to start-of-file. + +- `cur` +Seek relative to current position. + +- `end` +Seek relative to end-of-file. + +## `dircookie`: `u64` +A reference to the offset of a directory entry. + +Size: 8 + +Alignment: 8 + +### Constants +- `start` + +## `dirnamlen`: `u32` +The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). + +Size: 4 + +Alignment: 4 + +## `inode`: `u64` +File serial number that is unique within its file system. + +Size: 8 + +Alignment: 8 + +## `filetype`: `Variant` +The type of a file descriptor or file. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `unknown` +The type of the file descriptor or file is unknown or is different from any of the other types specified. + +- `block_device` +The file descriptor or file refers to a block device inode. + +- `character_device` +The file descriptor or file refers to a character device inode. + +- `directory` +The file descriptor or file refers to a directory inode. + +- `regular_file` +The file descriptor or file refers to a regular file inode. + +- `socket_dgram` +The file descriptor or file refers to a datagram socket. + +- `socket_stream` +The file descriptor or file refers to a byte-stream socket. + +- `symbolic_link` +The file refers to a symbolic link inode. + +- `fifo` +The file descriptor or file refers to a FIFO. + +## `dirent`: `Record` +A directory entry. + +Size: 24 + +Alignment: 8 + +### Record members +- `d_next`: [`dircookie`](#dircookie) +The offset of the next directory entry stored in this directory. + +Offset: 0 + +- `d_ino`: [`inode`](#inode) +The serial number of the file referred to by this directory entry. + +Offset: 8 + +- `d_type`: [`filetype`](#filetype) +The type of the file referred to by this directory entry. + +Offset: 16 + +- `d_namlen`: [`dirnamlen`](#dirnamlen) +The length of the name of the directory entry. + +Offset: 20 + +## `advice`: `Variant` +File or memory access pattern advisory information. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `normal` +The application has no advice to give on its behavior with respect to the specified data. + +- `sequential` +The application expects to access the specified data sequentially from lower offsets to higher offsets. + +- `random` +The application expects to access the specified data in a random order. + +- `willneed` +The application expects to access the specified data in the near future. + +- `dontneed` +The application expects that it will not access the specified data in the near future. + +- `noreuse` +The application expects to access the specified data once and then not reuse it thereafter. + +## `fdflags`: `Record` +File descriptor flags. + +Size: 2 + +Alignment: 2 + +### Record members +- `append`: `bool` +Append mode: Data written to the file is always appended to the file's end. + +Bit: 0 + +- `dsync`: `bool` +Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + +Bit: 1 + +- `nonblock`: `bool` +Non-blocking mode. + +Bit: 2 + +- `rsync`: `bool` +Synchronized read I/O operations. + +Bit: 3 + +- `sync`: `bool` +Write according to synchronized I/O file integrity completion. In +addition to synchronizing the data stored in the file, the implementation +may also synchronously update the file's metadata. + +Bit: 4 + +## `fdstat`: `Record` +File descriptor attributes. + +Size: 24 + +Alignment: 8 + +### Record members +- `fs_filetype`: [`filetype`](#filetype) +File type. + +Offset: 0 + +- `fs_flags`: [`fdflags`](#fdflags) +File descriptor flags. + +Offset: 2 + +- `fs_rights_base`: [`rights`](#rights) +Rights that apply to this file descriptor. + +Offset: 8 + +- `fs_rights_inheriting`: [`rights`](#rights) +Maximum set of rights that may be installed on new file descriptors that +are created through this file descriptor, e.g., through `path_open`. + +Offset: 16 + +## `device`: `u64` +Identifier for a device containing a file system. Can be used in combination +with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. + +Size: 8 + +Alignment: 8 + +## `fstflags`: `Record` +Which file time attributes to adjust. + +Size: 2 + +Alignment: 2 + +### Record members +- `atim`: `bool` +Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). + +Bit: 0 + +- `atim_now`: `bool` +Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). + +Bit: 1 + +- `mtim`: `bool` +Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). + +Bit: 2 + +- `mtim_now`: `bool` +Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). + +Bit: 3 + +## `lookupflags`: `Record` +Flags determining the method of how paths are resolved. + +Size: 4 + +Alignment: 4 + +### Record members +- `symlink_follow`: `bool` +As long as the resolved path corresponds to a symbolic link, it is expanded. + +Bit: 0 + +## `oflags`: `Record` +Open flags used by `path_open`. + +Size: 2 + +Alignment: 2 + +### Record members +- `create`: `bool` +Create file if it does not exist. + +Bit: 0 + +- `directory`: `bool` +Fail if not a directory. + +Bit: 1 + +- `excl`: `bool` +Fail if file already exists. + +Bit: 2 + +- `trunc`: `bool` +Truncate file to size 0. + +Bit: 3 + +## `linkcount`: `u64` +Number of hard links to an inode. + +Size: 8 + +Alignment: 8 + +## `permissions`: `Record` +File permissions. This represents the permissions associated with a +file in a filesystem, and don't fully reflect all the conditions +which determine whether a given WASI program can access the file. + +Size: 1 + +Alignment: 1 + +### Record members +- `read`: `bool` +For files, permission to read the file. +For directories, permission to do [`readdir`](#readdir) and access files +within the directory. + +Note: This is similar to the read bit being set on files, and the +read *and* execute bits being set on directories, in POSIX. + +Bit: 0 + +- `write`: `bool` +For files, permission to mutate the file. +For directories, permission to create, remove, and rename items +within the directory. + +Bit: 1 + +- `execute`: `bool` +For files, permission to "execute" the file, using whatever +concept of "executing" the host filesystem has. +This flag is not valid for directories. + +Bit: 2 + +- `private`: `bool` +For filesystems which have a concept of multiple "users", this flag +indicates that the file is only accessible by the effective "user" +that the WASI store uses to access the filesystem, and inaccessible +to other "users". + +Bit: 3 + +## `filestat`: `Record` +File attributes. + +Size: 64 + +Alignment: 8 + +### Record members +- `dev`: [`device`](#device) +Device ID of device containing the file. + +Offset: 0 + +- `ino`: [`inode`](#inode) +File serial number. + +Offset: 8 + +- `filetype`: [`filetype`](#filetype) +File type. + +Offset: 16 + +- `permissions`: [`permissions`](#permissions) +File permissions. + +Offset: 17 + +- `nlink`: [`linkcount`](#linkcount) +Number of hard links to the file. + +Offset: 24 + +- `size`: [`filesize`](#filesize) +For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + +Offset: 32 + +- `atim`: [`timestamp`](#timestamp) +Last data access timestamp. + +Offset: 40 + +- `mtim`: [`timestamp`](#timestamp) +Last data modification timestamp. + +Offset: 48 + +- `ctim`: [`timestamp`](#timestamp) +Last file status change timestamp. + +Offset: 56 + +## `userdata`: `u64` +User-provided value that may be attached to objects that is retained when +extracted from the implementation. + +Size: 8 + +Alignment: 8 + +## `eventtype`: `Variant` +Type of a subscription to an event or its occurrence. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `clock` +The time value of clock [`subscription_clock::id`](#subscription_clock.id) has +reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). + +- `fd_read` +File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has data +available for reading. This event always triggers for regular files. + +- `fd_write` +File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity +available for writing. This event always triggers for regular files. + +## `eventrwflags`: `Record` +The state of the file descriptor subscribed to with +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +Size: 2 + +Alignment: 2 + +### Record members +- `fd_readwrite_hangup`: `bool` +The peer of this socket has closed or disconnected. + +Bit: 0 + +## `event_fd_readwrite`: `Record` +The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or +[`eventtype::fd_write`](#eventtype.fd_write). + +Size: 16 + +Alignment: 8 + +### Record members +- `nbytes`: [`filesize`](#filesize) +The number of bytes available for reading or writing. + +Offset: 0 + +- `flags`: [`eventrwflags`](#eventrwflags) +The state of the file descriptor. + +Offset: 8 + +## `event_u`: `Variant` +The contents of an [`event`](#event). + +Size: 24 + +Alignment: 8 + +### Variant Layout +- size: 24 +- align: 8 +- tag_size: 1 +### Variant cases +- `clock` + +- `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) + +- `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) + +## `event`: `Record` +An event that occurred. + +Size: 40 + +Alignment: 8 + +### Record members +- `userdata`: [`userdata`](#userdata) +User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). + +Offset: 0 + +- `error`: [`errno`](#errno) +If non-zero, an error that occurred while processing the subscription request. + +Offset: 8 + +- `u`: [`event_u`](#event_u) +The type of the event that occurred, and the contents of the event + +Offset: 16 + +## `subclockflags`: `Record` +Flags determining how to interpret the timestamp provided in +[`subscription_clock::timeout`](#subscription_clock.timeout). + +Size: 2 + +Alignment: 2 + +### Record members +- `subscription_clock_abstime`: `bool` +If set, treat the timestamp provided in +[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock +[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp +provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the +current time value of clock [`subscription_clock::id`](#subscription_clock.id). + +Bit: 0 + +## `subscription_clock`: `Record` +The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). + +Size: 32 + +Alignment: 8 + +### Record members +- `id`: [`clockid`](#clockid) +The clock against which to compare the timestamp. + +Offset: 0 + +- `timeout`: [`timestamp`](#timestamp) +The absolute or relative timestamp. + +Offset: 8 + +- `precision`: [`timestamp`](#timestamp) +The amount of time that the implementation may wait additionally +to coalesce with other events. + +Offset: 16 + +- `flags`: [`subclockflags`](#subclockflags) +Flags specifying whether the timeout is absolute or relative + +Offset: 24 + +## `subscription_fd_readwrite`: `Record` +The contents of a [`subscription`](#subscription) when type is type is +[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). + +Size: 4 + +Alignment: 4 + +### Record members +- `fd`: [`fd`](#fd) +The file descriptor on which to wait for it to become ready for reading or writing. + +Offset: 0 + +## `subscription_u`: `Variant` +The contents of a [`subscription`](#subscription). + +Size: 40 + +Alignment: 8 + +### Variant Layout +- size: 40 +- align: 8 +- tag_size: 1 +### Variant cases +- `clock`: [`subscription_clock`](#subscription_clock) + +- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) + +## `subscription`: `Record` +Subscription to an event. + +Size: 48 + +Alignment: 8 + +### Record members +- `userdata`: [`userdata`](#userdata) +User-provided value that is attached to the subscription in the +implementation and returned through [`event::userdata`](#event.userdata). + +Offset: 0 + +- `u`: [`subscription_u`](#subscription_u) +The type of the event to which to subscribe, and the contents of the subscription. + +Offset: 8 + +## `exitcode`: `u8` +Exit code generated by a program when exiting. + +Size: 1 + +Alignment: 1 + +### Constants +- `success` + +- `failure` + +## `riflags`: `Record` +Flags provided to `sock_recv`. + +Size: 2 + +Alignment: 2 + +### Record members +- `recv_peek`: `bool` +Returns the message without removing it from the socket's receive queue. + +Bit: 0 + +- `recv_waitall`: `bool` +On byte-stream sockets, block until the full amount of data can be returned. + +Bit: 1 + +## `roflags`: `Record` +Flags returned by `sock_recv`. + +Size: 2 + +Alignment: 2 + +### Record members +- `recv_data_truncated`: `bool` +Returned by `sock_recv`: Message data has been truncated. + +Bit: 0 + +## `siflags`: `u16` +Flags provided to `sock_send`. As there are currently no flags +defined, it must be set to zero. + +Size: 2 + +Alignment: 2 + +## `sdflags`: `Record` +Which channels on a socket to shut down. + +Size: 1 + +Alignment: 1 + +### Record members +- `rd`: `bool` +Disables further receive operations. + +Bit: 0 + +- `wr`: `bool` +Disables further send operations. + +Bit: 1 + +## `preopentype`: `Variant` +Identifiers for preopened capabilities. + +Size: 1 + +Alignment: 1 + +### Variant cases +- `dir` +A pre-opened directory. + +## `prestat_dir`: `Record` +The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). + +Size: 4 + +Alignment: 4 + +### Record members +- `pr_name_len`: [`size`](#size) +The length of the directory name for use with `fd_prestat_dir_name`. + +Offset: 0 + +## `prestat`: `Variant` +Information about a pre-opened capability. + +Size: 8 + +Alignment: 4 + +### Variant Layout +- size: 8 +- align: 4 +- tag_size: 1 +### Variant cases +- `dir`: [`prestat_dir`](#prestat_dir) +When type is [`preopentype::dir`](#preopentype.dir): + +# Modules +## wasi_ephemeral_fd +### Imports +#### Memory +### Functions + +--- + +#### `advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` +Provide file advisory information on a file descriptor. +Note: This is similar to `posix_fadvise` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset within the file to which the advisory applies. + +- `len`: [`filesize`](#filesize) +The length of the region to which the advisory applies. + +- `advice`: [`advice`](#advice) +The advice. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` +Force the allocation of space in a file. +Note: This is similar to `posix_fallocate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filesize`](#filesize) +The offset at which to start the allocation. + +- `len`: [`filesize`](#filesize) +The length of the area that is allocated. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `datasync(fd: fd) -> Result<(), errno>` +Synchronize the data of a file to disk. +Note: This is similar to `fdatasync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `fdstat_get(fd: fd) -> Result` +Get the attributes of a file descriptor. +Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: `Result` +The buffer where the file descriptor's attributes are stored. + +###### Variant Layout +- size: 32 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`fdstat`](#fdstat) + +- `err`: [`errno`](#errno) + + +--- + +#### `fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` +Adjust the flags associated with a file descriptor. +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`fdflags`](#fdflags) +The desired values of the file descriptor flags. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` +Adjust the rights associated with a file descriptor. +This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights + +##### Params +- `fd`: [`fd`](#fd) + +- `fs_rights_base`: [`rights`](#rights) +The desired rights of the file descriptor. + +- `fs_rights_inheriting`: [`rights`](#rights) + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `filestat_get(fd: fd) -> Result` +Return the attributes of an open file. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: `Result` +The buffer where the file's attributes are stored. + +###### Variant Layout +- size: 72 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + + +--- + +#### `filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` +Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. +Note: This is similar to `ftruncate` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `size`: [`filesize`](#filesize) +The desired file size. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` +Adjust the timestamps of an open file or directory. +Note: This is similar to `futimens` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `permissions_set(fd: fd, permissions: permissions) -> Result<(), errno>` +Set the permissions of a file or directory. + +This sets the permissions associated with a file or directory in +a filesystem at the time it is called. The ability to actually access +a file or directory may depend on additional permissions not reflected +here. + +Note: This is similar `fchmod` in POSIX. + +Unlike POSIX, this doesn't expose a user/group/other distinction; +implementations in POSIX environments are suggested to consult the +umask to determine which of the user/group/other flags to modify. + +##### Params +- `fd`: [`fd`](#fd) + +- `permissions`: [`permissions`](#permissions) +The permissions associated with the file. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` +Read from a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `preadv` in Linux (and other Unix-es). + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors in which to store data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to read. + +##### Results +- `error`: `Result` +The number of bytes read. + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + + +--- + +#### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` +Write to a file descriptor, without using and updating the file descriptor's offset. +Note: This is similar to `pwritev` in Linux (and other Unix-es). + +Like Linux (and other Unix-es), any calls of [`pwrite`](#pwrite) (and other +functions to read or write) for a regular file by other threads in the +WASI process should not be interleaved while [`pwrite`](#pwrite) is executed. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +- `offset`: [`filesize`](#filesize) +The offset within the file at which to write. + +##### Results +- `error`: `Result` +The number of bytes written. + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + + +--- + +#### `read(fd: fd, iovs: iovec_array) -> Result` +Read from a file descriptor. +Note: This is similar to `readv` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`iovec_array`](#iovec_array) +List of scatter/gather vectors to which to store data. + +##### Results +- `error`: `Result` +The number of bytes read. + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + + +--- + +#### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` +Read directory entries from a directory. +When successful, the contents of the output buffer consist of a sequence of +directory entries. Each directory entry consists of a [`dirent`](#dirent) object, +followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory +entry. +This function fills the output buffer as much as possible, potentially +truncating the last directory entry. This allows the caller to grow its +read buffer size in case it's too small to fit a single large directory +entry, or skip the oversized directory entry. + +##### Params +- `fd`: [`fd`](#fd) + +- `buf`: `Pointer` +The buffer where directory entries are stored + +- `buf_len`: [`size`](#size) + +- `cookie`: [`dircookie`](#dircookie) +The location within the directory to start reading + +##### Results +- `error`: `Result` +The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + + +--- + +#### `renumber(fd: fd, to: fd) -> Result<(), errno>` +Atomically replace a file descriptor by renumbering another file descriptor. +Due to the strong focus on thread safety, this environment does not provide +a mechanism to duplicate or renumber a file descriptor to an arbitrary +number, like `dup2()`. This would be prone to race conditions, as an actual +file descriptor with the same number could be allocated by a different +thread at the same time. +This function provides a way to atomically renumber file descriptors, which +would disappear if `dup2()` were to be removed entirely. + +##### Params +- `fd`: [`fd`](#fd) + +- `to`: [`fd`](#fd) +The file descriptor to overwrite. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `seek(fd: fd, offset: filedelta, whence: whence) -> Result` +Move the offset of a file descriptor. +Note: This is similar to `lseek` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `offset`: [`filedelta`](#filedelta) +The number of bytes to move. + +- `whence`: [`whence`](#whence) +The base from which the offset is relative. + +##### Results +- `error`: `Result` +The new offset of the file descriptor, relative to the start of the file. + +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + + +--- + +#### `sync(fd: fd) -> Result<(), errno>` +Synchronize the data and metadata of a file to disk. +Note: This is similar to `fsync` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `tell(fd: fd) -> Result` +Return the current offset of a file descriptor. +Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +##### Results +- `error`: `Result` +The current offset of the file descriptor, relative to the start of the file. + +###### Variant Layout +- size: 16 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filesize`](#filesize) + +- `err`: [`errno`](#errno) + + +--- + +#### `write(fd: fd, iovs: ciovec_array) -> Result` +Write to a file descriptor. +Note: This is similar to `writev` in POSIX. + +Like POSIX, any calls of [`write`](#write) (and other functions to read or write) +for a regular file by other threads in the WASI process should not be +interleaved while [`write`](#write) is executed. + +##### Params +- `fd`: [`fd`](#fd) + +- `iovs`: [`ciovec_array`](#ciovec_array) +List of scatter/gather vectors from which to retrieve data. + +##### Results +- `error`: `Result` +The number of bytes written. + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + +## wasi_ephemeral_path +### Imports +#### Memory +### Functions + +--- + +#### `create_directory(fd: fd, path: string) -> Result<(), errno>` +Create a directory. +Note: This is similar to `mkdirat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path at which to create the directory. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` +Return the attributes of a file or directory. +Note: This is similar to `stat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to inspect. + +##### Results +- `error`: `Result` +The buffer where the file's attributes are stored. + +###### Variant Layout +- size: 72 +- align: 8 +- tag_size: 4 +###### Variant cases +- `ok`: [`filestat`](#filestat) + +- `err`: [`errno`](#errno) + + +--- + +#### `filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` +Adjust the timestamps of a file or directory. +Note: This is similar to `utimensat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path of the file or directory to operate on. + +- `atim`: [`timestamp`](#timestamp) +The desired values of the data access timestamp. + +- `mtim`: [`timestamp`](#timestamp) +The desired values of the data modification timestamp. + +- `fst_flags`: [`fstflags`](#fstflags) +A bitmask indicating which timestamps to adjust. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `permissions_set(fd: fd, flags: lookupflags, path: string, permissions: permissions) -> Result<(), errno>` +Set the permissions of a file or directory. + +This sets the permissions associated with a file or directory in +a filesystem at the time it is called. The ability to actually access +a file or directory may depend on additional permissions not reflected +here. + +Note: This is similar to `fchmodat` in POSIX. + +Unlike POSIX, this doesn't expose a user/group/other distinction; +implementations in POSIX environments are suggested to consult the +umask to determine which of the user/group/other flags to modify. + +##### Params +- `fd`: [`fd`](#fd) + +- `flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The path to a file to query. + +- `permissions`: [`permissions`](#permissions) +The permissions to associate with the file. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` +Create a hard link. +Note: This is similar to `linkat` in POSIX. + +##### Params +- `old_fd`: [`fd`](#fd) + +- `old_flags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `old_path`: `string` +The source path from which to link. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path at which to create the hard link. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, permissions: permissions) -> Result` +Open a file or directory. +The returned file descriptor is not guaranteed to be the lowest-numbered +file descriptor not currently open; it is randomized to prevent +applications from depending on making assumptions about indexes, since this +is error-prone in multi-threaded contexts. The returned file descriptor is +guaranteed to be less than 2**31. +Note: This is similar to `openat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `dirflags`: [`lookupflags`](#lookupflags) +Flags determining the method of how the path is resolved. + +- `path`: `string` +The relative path of the file or directory to open, relative to the +[`fd`](#fd) directory. + +- `oflags`: [`oflags`](#oflags) +The method by which to open the file. + +- `fs_rights_base`: [`rights`](#rights) +The initial rights of the newly created file descriptor. The +implementation is allowed to return a file descriptor with fewer rights +than specified, if and only if those rights do not apply to the type of +file being opened. +The *base* rights are rights that will apply to operations using the file +descriptor itself, while the *inheriting* rights are rights that apply to +file descriptors derived from it. + +- `fs_rights_inheriting`: [`rights`](#rights) + +- `fdflags`: [`fdflags`](#fdflags) + +- `permissions`: [`permissions`](#permissions) +If a file is created, the filesystem permissions to associate with it. + +##### Results +- `error`: `Result` +The file descriptor of the file that has been opened. + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`fd`](#fd) + +- `err`: [`errno`](#errno) + + +--- + +#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` +Read the contents of a symbolic link. +Note: This is similar to `readlinkat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path of the symbolic link from which to read. + +- `buf`: `Pointer` +The buffer to which to write the contents of the symbolic link. + +- `buf_len`: [`size`](#size) + +##### Results +- `error`: `Result` +The number of bytes placed in the buffer. + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok`: [`size`](#size) + +- `err`: [`errno`](#errno) + + +--- + +#### `remove_directory(fd: fd, path: string) -> Result<(), errno>` +Remove a directory. +Return [`errno::notempty`](#errno.notempty) if the directory is not empty. +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a directory to remove. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` +Rename a file or directory. +Note: This is similar to `renameat` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `old_path`: `string` +The source path of the file or directory to rename. + +- `new_fd`: [`fd`](#fd) +The working directory at which the resolution of the new path starts. + +- `new_path`: `string` +The destination path to which to rename the file or directory. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` +Create a symbolic link. +Note: This is similar to `symlinkat` in POSIX. + +##### Params +- `old_path`: `string` +The contents of the symbolic link. + +- `fd`: [`fd`](#fd) + +- `new_path`: `string` +The destination path at which to create the symbolic link. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + + +--- + +#### `unlink_file(fd: fd, path: string) -> Result<(), errno>` +Unlink a file. +Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + +##### Params +- `fd`: [`fd`](#fd) + +- `path`: `string` +The path to a file to unlink. + +##### Results +- `error`: `Result<(), errno>` + +###### Variant Layout +- size: 8 +- align: 4 +- tag_size: 4 +###### Variant cases +- `ok` + +- `err`: [`errno`](#errno) + diff --git a/proposals/filesystem/standard/wasi-filesystem/witx/file_io.witx b/proposals/filesystem/standard/wasi-filesystem/witx/file_io.witx new file mode 100644 index 000000000..f06827e2c --- /dev/null +++ b/proposals/filesystem/standard/wasi-filesystem/witx/file_io.witx @@ -0,0 +1,236 @@ +;; WASI File I/O. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_fd + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Provide file advisory information on a file descriptor. + ;;; Note: This is similar to `posix_fadvise` in POSIX. + (@interface func (export "advise") + (param $fd $fd) + ;;; The offset within the file to which the advisory applies. + (param $offset $filesize) + ;;; The length of the region to which the advisory applies. + (param $len $filesize) + ;;; The advice. + (param $advice $advice) + (result $error (expected (error $errno))) + ) + + ;;; Force the allocation of space in a file. + ;;; Note: This is similar to `posix_fallocate` in POSIX. + (@interface func (export "allocate") + (param $fd $fd) + ;;; The offset at which to start the allocation. + (param $offset $filesize) + ;;; The length of the area that is allocated. + (param $len $filesize) + (result $error (expected (error $errno))) + ) + + ;;; Synchronize the data of a file to disk. + ;;; Note: This is similar to `fdatasync` in POSIX. + (@interface func (export "datasync") + (param $fd $fd) + (result $error (expected (error $errno))) + ) + + ;;; Get the attributes of a file descriptor. + ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. + (@interface func (export "fdstat_get") + (param $fd $fd) + ;;; The buffer where the file descriptor's attributes are stored. + (result $error (expected $fdstat (error $errno))) + ) + + ;;; Adjust the flags associated with a file descriptor. + ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + (@interface func (export "fdstat_set_flags") + (param $fd $fd) + ;;; The desired values of the file descriptor flags. + (param $flags $fdflags) + (result $error (expected (error $errno))) + ) + + ;;; Adjust the rights associated with a file descriptor. + ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights + (@interface func (export "fdstat_set_rights") + (param $fd $fd) + ;;; The desired rights of the file descriptor. + (param $fs_rights_base $rights) + (param $fs_rights_inheriting $rights) + (result $error (expected (error $errno))) + ) + + ;;; Return the attributes of an open file. + (@interface func (export "filestat_get") + (param $fd $fd) + ;;; The buffer where the file's attributes are stored. + (result $error (expected $filestat (error $errno))) + ) + + ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. + ;;; Note: This is similar to `ftruncate` in POSIX. + (@interface func (export "filestat_set_size") + (param $fd $fd) + ;;; The desired file size. + (param $size $filesize) + (result $error (expected (error $errno))) + ) + + ;;; Adjust the timestamps of an open file or directory. + ;;; Note: This is similar to `futimens` in POSIX. + (@interface func (export "filestat_set_times") + (param $fd $fd) + ;;; The desired values of the data access timestamp. + (param $atim $timestamp) + ;;; The desired values of the data modification timestamp. + (param $mtim $timestamp) + ;;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags) + (result $error (expected (error $errno))) + ) + + ;;; Set the permissions of a file or directory. + ;;; + ;;; This sets the permissions associated with a file or directory in + ;;; a filesystem at the time it is called. The ability to actually access + ;;; a file or directory may depend on additional permissions not reflected + ;;; here. + ;;; + ;;; Note: This is similar `fchmod` in POSIX. + ;;; + ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; + ;;; implementations in POSIX environments are suggested to consult the + ;;; umask to determine which of the user/group/other flags to modify. + (@interface func (export "permissions_set") + (param $fd $fd) + ;;; The permissions associated with the file. + (param $permissions $permissions) + (result $error (expected (error $errno))) + ) + + ;;; Read from a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `preadv` in Linux (and other Unix-es). + (@interface func (export "pread") + (param $fd $fd) + ;;; List of scatter/gather vectors in which to store data. + (param $iovs $iovec_array) + ;;; The offset within the file at which to read. + (param $offset $filesize) + ;;; The number of bytes read. + (result $error (expected $size (error $errno))) + ) + + ;;; Write to a file descriptor, without using and updating the file descriptor's offset. + ;;; Note: This is similar to `pwritev` in Linux (and other Unix-es). + ;;; + ;;; Like Linux (and other Unix-es), any calls of `pwrite` (and other + ;;; functions to read or write) for a regular file by other threads in the + ;;; WASI process should not be interleaved while `pwrite` is executed. + (@interface func (export "pwrite") + (param $fd $fd) + ;;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_array) + ;;; The offset within the file at which to write. + (param $offset $filesize) + ;;; The number of bytes written. + (result $error (expected $size (error $errno))) + ) + + ;;; Read from a file descriptor. + ;;; Note: This is similar to `readv` in POSIX. + (@interface func (export "read") + (param $fd $fd) + ;;; List of scatter/gather vectors to which to store data. + (param $iovs $iovec_array) + ;;; The number of bytes read. + (result $error (expected $size (error $errno))) + ) + + ;;; Read directory entries from a directory. + ;;; When successful, the contents of the output buffer consist of a sequence of + ;;; directory entries. Each directory entry consists of a `dirent` object, + ;;; followed by `dirent::d_namlen` bytes holding the name of the directory + ;;; entry. + ;; + ;;; This function fills the output buffer as much as possible, potentially + ;;; truncating the last directory entry. This allows the caller to grow its + ;;; read buffer size in case it's too small to fit a single large directory + ;;; entry, or skip the oversized directory entry. + (@interface func (export "readdir") + (param $fd $fd) + ;;; The buffer where directory entries are stored + (param $buf (@witx pointer u8)) + (param $buf_len $size) + ;;; The location within the directory to start reading + (param $cookie $dircookie) + ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. + (result $error (expected $size (error $errno))) + ) + + ;;; Atomically replace a file descriptor by renumbering another file descriptor. + ;; + ;;; Due to the strong focus on thread safety, this environment does not provide + ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary + ;;; number, like `dup2()`. This would be prone to race conditions, as an actual + ;;; file descriptor with the same number could be allocated by a different + ;;; thread at the same time. + ;; + ;;; This function provides a way to atomically renumber file descriptors, which + ;;; would disappear if `dup2()` were to be removed entirely. + (@interface func (export "renumber") + (param $fd $fd) + ;;; The file descriptor to overwrite. + (param $to $fd) + (result $error (expected (error $errno))) + ) + + ;;; Move the offset of a file descriptor. + ;;; Note: This is similar to `lseek` in POSIX. + (@interface func (export "seek") + (param $fd $fd) + ;;; The number of bytes to move. + (param $offset $filedelta) + ;;; The base from which the offset is relative. + (param $whence $whence) + ;;; The new offset of the file descriptor, relative to the start of the file. + (result $error (expected $filesize (error $errno))) + ) + + ;;; Synchronize the data and metadata of a file to disk. + ;;; Note: This is similar to `fsync` in POSIX. + (@interface func (export "sync") + (param $fd $fd) + (result $error (expected (error $errno))) + ) + + ;;; Return the current offset of a file descriptor. + ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. + (@interface func (export "tell") + (param $fd $fd) + ;;; The current offset of the file descriptor, relative to the start of the file. + (result $error (expected $filesize (error $errno))) + ) + + ;;; Write to a file descriptor. + ;;; Note: This is similar to `writev` in POSIX. + ;;; + ;;; Like POSIX, any calls of `write` (and other functions to read or write) + ;;; for a regular file by other threads in the WASI process should not be + ;;; interleaved while `write` is executed. + (@interface func (export "write") + (param $fd $fd) + ;;; List of scatter/gather vectors from which to retrieve data. + (param $iovs $ciovec_array) + ;;; The number of bytes written. + (result $error (expected $size (error $errno))) + ) +) diff --git a/proposals/filesystem/standard/wasi-filesystem/witx/path.witx b/proposals/filesystem/standard/wasi-filesystem/witx/path.witx new file mode 100644 index 000000000..2901decb7 --- /dev/null +++ b/proposals/filesystem/standard/wasi-filesystem/witx/path.witx @@ -0,0 +1,181 @@ +;; WASI Filesystem Path API. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +(use "typenames.witx") + +(module $wasi_ephemeral_path + ;;; Linear memory to be accessed by WASI functions that need it. + (import "memory" (memory)) + + ;;; Create a directory. + ;;; Note: This is similar to `mkdirat` in POSIX. + (@interface func (export "create_directory") + (param $fd $fd) + ;;; The path at which to create the directory. + (param $path string) + (result $error (expected (error $errno))) + ) + + ;;; Return the attributes of a file or directory. + ;;; Note: This is similar to `stat` in POSIX. + (@interface func (export "filestat_get") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags) + ;;; The path of the file or directory to inspect. + (param $path string) + ;;; The buffer where the file's attributes are stored. + (result $error (expected $filestat (error $errno))) + ) + + ;;; Adjust the timestamps of a file or directory. + ;;; Note: This is similar to `utimensat` in POSIX. + (@interface func (export "filestat_set_times") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags) + ;;; The path of the file or directory to operate on. + (param $path string) + ;;; The desired values of the data access timestamp. + (param $atim $timestamp) + ;;; The desired values of the data modification timestamp. + (param $mtim $timestamp) + ;;; A bitmask indicating which timestamps to adjust. + (param $fst_flags $fstflags) + (result $error (expected (error $errno))) + ) + + ;;; Set the permissions of a file or directory. + ;;; + ;;; This sets the permissions associated with a file or directory in + ;;; a filesystem at the time it is called. The ability to actually access + ;;; a file or directory may depend on additional permissions not reflected + ;;; here. + ;;; + ;;; Note: This is similar to `fchmodat` in POSIX. + ;;; + ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; + ;;; implementations in POSIX environments are suggested to consult the + ;;; umask to determine which of the user/group/other flags to modify. + (@interface func (export "permissions_set") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $flags $lookupflags) + ;;; The path to a file to query. + (param $path string) + ;;; The permissions to associate with the file. + (param $permissions $permissions) + (result $error (expected (error $errno))) + ) + + ;;; Create a hard link. + ;;; Note: This is similar to `linkat` in POSIX. + (@interface func (export "link") + (param $old_fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $old_flags $lookupflags) + ;;; The source path from which to link. + (param $old_path string) + ;;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd) + ;;; The destination path at which to create the hard link. + (param $new_path string) + (result $error (expected (error $errno))) + ) + + ;;; Open a file or directory. + ;; + ;;; The returned file descriptor is not guaranteed to be the lowest-numbered + ;;; file descriptor not currently open; it is randomized to prevent + ;;; applications from depending on making assumptions about indexes, since this + ;;; is error-prone in multi-threaded contexts. The returned file descriptor is + ;;; guaranteed to be less than 2**31. + ;; + ;;; Note: This is similar to `openat` in POSIX. + (@interface func (export "open") + (param $fd $fd) + ;;; Flags determining the method of how the path is resolved. + (param $dirflags $lookupflags) + ;;; The relative path of the file or directory to open, relative to the + ;;; `fd` directory. + (param $path string) + ;;; The method by which to open the file. + (param $oflags $oflags) + ;;; The initial rights of the newly created file descriptor. The + ;;; implementation is allowed to return a file descriptor with fewer rights + ;;; than specified, if and only if those rights do not apply to the type of + ;;; file being opened. + ;; + ;;; The *base* rights are rights that will apply to operations using the file + ;;; descriptor itself, while the *inheriting* rights are rights that apply to + ;;; file descriptors derived from it. + (param $fs_rights_base $rights) + (param $fs_rights_inheriting $rights) + (param $fdflags $fdflags) + ;;; If a file is created, the filesystem permissions to associate with it. + (param $permissions $permissions) + ;;; The file descriptor of the file that has been opened. + (result $error (expected $fd (error $errno))) + ) + + ;;; Read the contents of a symbolic link. + ;;; Note: This is similar to `readlinkat` in POSIX. + (@interface func (export "readlink") + (param $fd $fd) + ;;; The path of the symbolic link from which to read. + (param $path string) + ;;; The buffer to which to write the contents of the symbolic link. + (param $buf (@witx pointer (@witx char8))) + (param $buf_len $size) + ;;; The number of bytes placed in the buffer. + (result $error (expected $size (error $errno))) + ) + + ;;; Remove a directory. + ;;; Return `errno::notempty` if the directory is not empty. + ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + (@interface func (export "remove_directory") + (param $fd $fd) + ;;; The path to a directory to remove. + (param $path string) + (result $error (expected (error $errno))) + ) + + ;;; Rename a file or directory. + ;;; Note: This is similar to `renameat` in POSIX. + (@interface func (export "rename") + (param $fd $fd) + ;;; The source path of the file or directory to rename. + (param $old_path string) + ;;; The working directory at which the resolution of the new path starts. + (param $new_fd $fd) + ;;; The destination path to which to rename the file or directory. + (param $new_path string) + (result $error (expected (error $errno))) + ) + + ;;; Create a symbolic link. + ;;; Note: This is similar to `symlinkat` in POSIX. + (@interface func (export "symlink") + ;;; The contents of the symbolic link. + (param $old_path string) + (param $fd $fd) + ;;; The destination path at which to create the symbolic link. + (param $new_path string) + (result $error (expected (error $errno))) + ) + + ;;; Unlink a file. + ;;; Return `errno::isdir` if the path refers to a directory. + ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + (@interface func (export "unlink_file") + (param $fd $fd) + ;;; The path to a file to unlink. + (param $path string) + (result $error (expected (error $errno))) + ) +) diff --git a/proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx b/proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx new file mode 100644 index 000000000..bbd6489df --- /dev/null +++ b/proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx @@ -0,0 +1,708 @@ +;; Type names used by low-level WASI interfaces. +;; +;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). +;; +;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) +;; for an explanation of what that means. + +;;; An array size. +;;; +;;; Note: This is similar to `size_t` in POSIX. +(typename $size (@witx usize)) + +;;; Non-negative file size or length of a region within a file. +(typename $filesize u64) + +;;; Timestamp in nanoseconds. +(typename $timestamp u64) + +;;; Identifiers for clocks. +(typename $clockid + (enum (@witx tag u32) + ;;; The clock measuring real time. Time value zero corresponds with + ;;; 1970-01-01T00:00:00Z. + $realtime + ;;; The store-wide monotonic clock, which is defined as a clock measuring + ;;; real time, whose value cannot be adjusted and which cannot have negative + ;;; clock jumps. The epoch of this clock is undefined. The absolute time + ;;; value of this clock therefore has no meaning. + $monotonic + ) +) + +;;; Error codes returned by functions. +;;; Not all of these error codes are returned by the functions provided by this +;;; API; some are used in higher-level library layers, and others are provided +;;; merely for alignment with POSIX. +(typename $errno + (enum (@witx tag u16) + ;;; No error occurred. System call completed successfully. + $success + ;;; Argument list too long. + $2big + ;;; Permission denied. + $access + ;;; Address in use. + $addrinuse + ;;; Address not available. + $addrnotavail + ;;; Address family not supported. + $afnosupport + ;;; Resource unavailable, or operation would block. + $again + ;;; Connection already in progress. + $already + ;;; Bad file descriptor. + $badf + ;;; Bad message. + $badmsg + ;;; Device or resource busy. + $busy + ;;; Operation canceled. + $canceled + ;;; No child processes. + $child + ;;; Connection aborted. + $connaborted + ;;; Connection refused. + $connrefused + ;;; Connection reset. + $connreset + ;;; Resource deadlock would occur. + $deadlk + ;;; Destination address required. + $destaddrreq + ;;; Mathematics argument out of domain of function. + $dom + ;;; Reserved. + $dquot + ;;; File exists. + $exist + ;;; Bad address. + $fault + ;;; File too large. + $fbig + ;;; Host is unreachable. + $hostunreach + ;;; Identifier removed. + $idrm + ;;; Illegal byte sequence. + $ilseq + ;;; Operation in progress. + $inprogress + ;;; Interrupted function. + $intr + ;;; Invalid argument. + $inval + ;;; I/O error. + $io + ;;; Socket is connected. + $isconn + ;;; Is a directory. + $isdir + ;;; Too many levels of symbolic links. + $loop + ;;; File descriptor value too large. + $mfile + ;;; Too many links. + $mlink + ;;; Message too large. + $msgsize + ;;; Reserved. + $multihop + ;;; Filename too long. + $nametoolong + ;;; Network is down. + $netdown + ;;; Connection aborted by network. + $netreset + ;;; Network unreachable. + $netunreach + ;;; Too many files open in system. + $nfile + ;;; No buffer space available. + $nobufs + ;;; No such device. + $nodev + ;;; No such file or directory. + $noent + ;;; Executable file format error. + $noexec + ;;; No locks available. + $nolck + ;;; Reserved. + $nolink + ;;; Not enough space. + $nomem + ;;; No message of the desired type. + $nomsg + ;;; Protocol not available. + $noprotoopt + ;;; No space left on device. + $nospc + ;;; Function not supported. + $nosys + ;;; The socket is not connected. + $notconn + ;;; Not a directory or a symbolic link to a directory. + $notdir + ;;; Directory not empty. + $notempty + ;;; State not recoverable. + $notrecoverable + ;;; Not a socket. + $notsock + ;;; Not supported, or operation not supported on socket. + $notsup + ;;; Inappropriate I/O control operation. + $notty + ;;; No such device or address. + $nxio + ;;; Value too large to be stored in data type. + $overflow + ;;; Previous owner died. + $ownerdead + ;;; Operation not permitted. + $perm + ;;; Broken pipe. + $pipe + ;;; Protocol error. + $proto + ;;; Protocol not supported. + $protonosupport + ;;; Protocol wrong type for socket. + $prototype + ;;; Result too large. + $range + ;;; Read-only file system. + $rofs + ;;; Invalid seek. + $spipe + ;;; No such process. + $srch + ;;; Reserved. + $stale + ;;; Connection timed out. + $timedout + ;;; Text file busy. + $txtbsy + ;;; Cross-device link. + $xdev + ;;; Extension: Capabilities insufficient. + $notcapable + ) +) + +;;; File descriptor rights, determining which actions may be performed. +(typename $rights + (flags (@witx repr u64) + ;;; The right to invoke `fd_datasync`. + ;; + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflags::dsync`. + $fd_datasync + ;;; The right to invoke `fd_read` and `sock_recv`. + ;; + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. + $fd_read + ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. + $fd_seek + ;;; The right to invoke `fd_fdstat_set_flags`. + $fd_fdstat_set_flags + ;;; The right to invoke `fd_sync`. + ;; + ;;; If `path_open` is set, includes the right to invoke + ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. + $fd_sync + ;;; The right to invoke `fd_seek` in such a way that the file offset + ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to + ;;; invoke `fd_tell`. + $fd_tell + ;;; The right to invoke `fd_write` and `sock_send`. + ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. + $fd_write + ;;; The right to invoke `fd_advise`. + $fd_advise + ;;; The right to invoke `fd_allocate`. + $fd_allocate + ;;; The right to invoke `path_create_directory`. + $path_create_directory + ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::create`. + $path_create_file + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; source directory. + $path_link_source + ;;; The right to invoke `path_link` with the file descriptor as the + ;;; target directory. + $path_link_target + ;;; The right to invoke `path_open`. + $path_open + ;;; The right to invoke `fd_readdir`. + $fd_readdir + ;;; The right to invoke `path_readlink`. + $path_readlink + ;;; The right to invoke `path_rename` with the file descriptor as the source directory. + $path_rename_source + ;;; The right to invoke `path_rename` with the file descriptor as the target directory. + $path_rename_target + ;;; The right to invoke `path_filestat_get`. + $path_filestat_get + ;;; The right to change a file's size. + ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. + ;;; Note: there is no function named `path_filestat_set_size`. This follows POSIX design, + ;;; which only has `ftruncate` and does not provide `ftruncateat`. + ;;; While such function would be desirable from the API design perspective, there are virtually + ;;; no use cases for it since no code written for POSIX systems would use it. + ;;; Moreover, implementing it would require multiple syscalls, leading to inferior performance. + $path_filestat_set_size + ;;; The right to invoke `path_filestat_set_times`. + $path_filestat_set_times + ;;; The right to invoke `path_permissions_set`. + $path_permissions_set + ;;; The right to invoke `fd_filestat_get`. + $fd_filestat_get + ;;; The right to invoke `fd_filestat_set_size`. + $fd_filestat_set_size + ;;; The right to invoke `fd_filestat_set_times`. + $fd_filestat_set_times + ;;; The right to invoke `fd_permissions_set`. + $fd_permissions_set + ;;; The right to invoke `path_symlink`. + $path_symlink + ;;; The right to invoke `path_remove_directory`. + $path_remove_directory + ;;; The right to invoke `path_unlink_file`. + $path_unlink_file + ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. + ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. + $poll_fd_readwrite + ;;; The right to invoke `sock_shutdown`. + $sock_shutdown + ) +) + +;;; A file descriptor handle. +(typename $fd (handle)) + +;;; A region of memory for scatter/gather reads. +(typename $iovec + (record + ;;; The address of the buffer to be filled. + (field $buf (@witx pointer u8)) + ;;; The length of the buffer to be filled. + (field $buf_len $size) + ) +) + +;;; A region of memory for scatter/gather writes. +(typename $ciovec + (record + ;;; The address of the buffer to be written. + (field $buf (@witx const_pointer u8)) + ;;; The length of the buffer to be written. + (field $buf_len $size) + ) +) + +(typename $iovec_array (list $iovec)) +(typename $ciovec_array (list $ciovec)) + +;;; Relative offset within a file. +(typename $filedelta s64) + +;;; The position relative to which to set the offset of the file descriptor. +(typename $whence + (enum (@witx tag u8) + ;;; Seek relative to start-of-file. + $set + ;;; Seek relative to current position. + $cur + ;;; Seek relative to end-of-file. + $end + ) +) + +;;; A reference to the offset of a directory entry. +(typename $dircookie u64) + +;;; In an `fd_readdir` call, this value signifies the start of the directory. +(@witx const $dircookie $start 0) + +;;; The type for the `dirent::d_namlen` field of `dirent`. +(typename $dirnamlen u32) + +;;; File serial number that is unique within its file system. +(typename $inode u64) + +;;; The type of a file descriptor or file. +(typename $filetype + (enum (@witx tag u8) + ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. + $unknown + ;;; The file descriptor or file refers to a block device inode. + $block_device + ;;; The file descriptor or file refers to a character device inode. + $character_device + ;;; The file descriptor or file refers to a directory inode. + $directory + ;;; The file descriptor or file refers to a regular file inode. + $regular_file + ;;; The file descriptor or file refers to a datagram socket. + $socket_dgram + ;;; The file descriptor or file refers to a byte-stream socket. + $socket_stream + ;;; The file refers to a symbolic link inode. + $symbolic_link + ;;; The file descriptor or file refers to a FIFO. + $fifo + ) +) + +;;; A directory entry. +(typename $dirent + (record + ;;; The offset of the next directory entry stored in this directory. + (field $d_next $dircookie) + ;;; The serial number of the file referred to by this directory entry. + (field $d_ino $inode) + ;;; The type of the file referred to by this directory entry. + (field $d_type $filetype) + ;;; The length of the name of the directory entry. + (field $d_namlen $dirnamlen) + ) +) + +;;; File or memory access pattern advisory information. +(typename $advice + (enum (@witx tag u8) + ;;; The application has no advice to give on its behavior with respect to the specified data. + $normal + ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. + $sequential + ;;; The application expects to access the specified data in a random order. + $random + ;;; The application expects to access the specified data in the near future. + $willneed + ;;; The application expects that it will not access the specified data in the near future. + $dontneed + ;;; The application expects to access the specified data once and then not reuse it thereafter. + $noreuse + ) +) + +;;; File descriptor flags. +(typename $fdflags + (flags (@witx repr u16) + ;;; Append mode: Data written to the file is always appended to the file's end. + $append + ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. + $dsync + ;;; Non-blocking mode. + $nonblock + ;;; Synchronized read I/O operations. + $rsync + ;;; Write according to synchronized I/O file integrity completion. In + ;;; addition to synchronizing the data stored in the file, the implementation + ;;; may also synchronously update the file's metadata. + $sync + ) +) + +;;; File descriptor attributes. +(typename $fdstat + (record + ;;; File type. + (field $fs_filetype $filetype) + ;;; File descriptor flags. + (field $fs_flags $fdflags) + ;;; Rights that apply to this file descriptor. + (field $fs_rights_base $rights) + ;;; Maximum set of rights that may be installed on new file descriptors that + ;;; are created through this file descriptor, e.g., through `path_open`. + (field $fs_rights_inheriting $rights) + ) +) + +;;; Identifier for a device containing a file system. Can be used in combination +;;; with `inode` to uniquely identify a file or directory in the filesystem. +(typename $device u64) + +;;; Which file time attributes to adjust. +(typename $fstflags + (flags (@witx repr u16) + ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. + $atim + ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. + $atim_now + ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. + $mtim + ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. + $mtim_now + ) +) + +;;; Flags determining the method of how paths are resolved. +(typename $lookupflags + (flags (@witx repr u32) + ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. + $symlink_follow + ) +) + +;;; Open flags used by `path_open`. +(typename $oflags + (flags (@witx repr u16) + ;;; Create file if it does not exist. + $create + ;;; Fail if not a directory. + $directory + ;;; Fail if file already exists. + $excl + ;;; Truncate file to size 0. + $trunc + ) +) + +;;; Number of hard links to an inode. +(typename $linkcount u64) + +;;; File permissions. This represents the permissions associated with a +;;; file in a filesystem, and don't fully reflect all the conditions +;;; which determine whether a given WASI program can access the file. +(typename $permissions + (flags (@witx repr u8) + ;;; For files, permission to read the file. + ;;; For directories, permission to do `readdir` and access files + ;;; within the directory. + ;;; + ;;; Note: This is similar to the read bit being set on files, and the + ;;; read *and* execute bits being set on directories, in POSIX. + $read + + ;;; For files, permission to mutate the file. + ;;; For directories, permission to create, remove, and rename items + ;;; within the directory. + $write + + ;;; For files, permission to "execute" the file, using whatever + ;;; concept of "executing" the host filesystem has. + ;;; This flag is not valid for directories. + $execute + + ;;; For filesystems which have a concept of multiple "users", this flag + ;;; indicates that the file is only accessible by the effective "user" + ;;; that the WASI store uses to access the filesystem, and inaccessible + ;;; to other "users". + $private + ) +) + +;;; File attributes. +(typename $filestat + (record + ;;; Device ID of device containing the file. + (field $dev $device) + ;;; File serial number. + (field $ino $inode) + ;;; File type. + (field $filetype $filetype) + ;;; File permissions. + (field $permissions $permissions) + ;;; Number of hard links to the file. + (field $nlink $linkcount) + ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. + (field $size $filesize) + ;;; Last data access timestamp. + (field $atim $timestamp) + ;;; Last data modification timestamp. + (field $mtim $timestamp) + ;;; Last file status change timestamp. + (field $ctim $timestamp) + ) +) + +;;; User-provided value that may be attached to objects that is retained when +;;; extracted from the implementation. +(typename $userdata u64) + +;;; Type of a subscription to an event or its occurrence. +(typename $eventtype + (enum (@witx tag u8) + ;;; The time value of clock `subscription_clock::id` has + ;;; reached timestamp `subscription_clock::timeout`. + $clock + ;;; File descriptor `subscription_fd_readwrite::fd` has data + ;;; available for reading. This event always triggers for regular files. + $fd_read + ;;; File descriptor `subscription_fd_readwrite::fd` has capacity + ;;; available for writing. This event always triggers for regular files. + $fd_write + ) +) + +;;; The state of the file descriptor subscribed to with +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $eventrwflags + (flags (@witx repr u16) + ;;; The peer of this socket has closed or disconnected. + $fd_readwrite_hangup + ) +) + +;;; The contents of an `event` when type is `eventtype::fd_read` or +;;; `eventtype::fd_write`. +(typename $event_fd_readwrite + (record + ;;; The number of bytes available for reading or writing. + (field $nbytes $filesize) + ;;; The state of the file descriptor. + (field $flags $eventrwflags) + ) +) + +;;; The contents of an `event`. +(typename $event_u + (variant (@witx tag $eventtype) + (case $fd_read $event_fd_readwrite) + (case $fd_write $event_fd_readwrite) + (case $clock) + ) +) + +;;; An event that occurred. +(typename $event + (record + ;;; User-provided value that got attached to `subscription::userdata`. + (field $userdata $userdata) + ;;; If non-zero, an error that occurred while processing the subscription request. + (field $error $errno) + ;;; The type of the event that occurred, and the contents of the event + (field $u $event_u) + ) +) + +;;; Flags determining how to interpret the timestamp provided in +;;; `subscription_clock::timeout`. +(typename $subclockflags + (flags (@witx repr u16) + ;;; If set, treat the timestamp provided in + ;;; `subscription_clock::timeout` as an absolute timestamp of clock + ;;; `subscription_clock::id`. If clear, treat the timestamp + ;;; provided in `subscription_clock::timeout` relative to the + ;;; current time value of clock `subscription_clock::id`. + $subscription_clock_abstime + ) +) + +;;; The contents of a `subscription` when type is `eventtype::clock`. +(typename $subscription_clock + (record + ;;; The clock against which to compare the timestamp. + (field $id $clockid) + ;;; The absolute or relative timestamp. + (field $timeout $timestamp) + ;;; The amount of time that the implementation may wait additionally + ;;; to coalesce with other events. + (field $precision $timestamp) + ;;; Flags specifying whether the timeout is absolute or relative + (field $flags $subclockflags) + ) +) + +;;; The contents of a `subscription` when type is type is +;;; `eventtype::fd_read` or `eventtype::fd_write`. +(typename $subscription_fd_readwrite + (record + ;;; The file descriptor on which to wait for it to become ready for reading or writing. + (field $fd $fd) + ) +) + +;;; The contents of a `subscription`. +(typename $subscription_u + (union (@witx tag $eventtype) + $subscription_clock + $subscription_fd_readwrite + $subscription_fd_readwrite + ) +) + +;;; Subscription to an event. +(typename $subscription + (record + ;;; User-provided value that is attached to the subscription in the + ;;; implementation and returned through `event::userdata`. + (field $userdata $userdata) + ;;; The type of the event to which to subscribe, and the contents of the subscription. + (field $u $subscription_u) + ) +) + +;;; Exit code generated by a program when exiting. +(typename $exitcode u8) + +;;; Indicate the program exited successfully. +;;; +;;; Note: This is similar to `EXIT_SUCCESS` in POSIX. +(@witx const $exitcode $success 0) + +;;; Indicate the program exited unsuccessfully. +;;; +;;; Note: This is similar to `EXIT_FAILURE` in POSIX. +(@witx const $exitcode $failure 1) + +;;; Flags provided to `sock_recv`. +(typename $riflags + (flags (@witx repr u16) + ;;; Returns the message without removing it from the socket's receive queue. + $recv_peek + ;;; On byte-stream sockets, block until the full amount of data can be returned. + $recv_waitall + ) +) + +;;; Flags returned by `sock_recv`. +(typename $roflags + (flags (@witx repr u16) + ;;; Returned by `sock_recv`: Message data has been truncated. + $recv_data_truncated + ) +) + +;;; Flags provided to `sock_send`. As there are currently no flags +;;; defined, it must be set to zero. +(typename $siflags u16) + +;;; Which channels on a socket to shut down. +(typename $sdflags + (flags (@witx repr u8) + ;;; Disables further receive operations. + $rd + ;;; Disables further send operations. + $wr + ) +) + +;;; Identifiers for preopened capabilities. +(typename $preopentype + (enum (@witx tag u8) + ;;; A pre-opened directory. + $dir + ) +) + +;;; The contents of a `prestat` when its type is `preopentype::dir`. +(typename $prestat_dir + (record + ;;; The length of the directory name for use with `fd_prestat_dir_name`. + (field $pr_name_len $size) + ) +) + +;;; Information about a pre-opened capability. +(typename $prestat + (union (@witx tag $preopentype) + ;;; When type is `preopentype::dir`: + $prestat_dir + ) +) diff --git a/proposals/filesystem/tools/repo_docs.sh b/proposals/filesystem/tools/repo_docs.sh index e0187bcaf..76d1462bc 100755 --- a/proposals/filesystem/tools/repo_docs.sh +++ b/proposals/filesystem/tools/repo_docs.sh @@ -15,3 +15,8 @@ cargo run -p witx-cli -- docs $1 \ ../../phases/ephemeral/witx/wasi_ephemeral_sched.witx \ ../../phases/ephemeral/witx/wasi_ephemeral_sock.witx \ --output ../../phases/ephemeral/docs.md + +for dir in ../../standard/*/witx; do + cargo run -p witx-cli -- docs $1 "$dir"/*.witx \ + --output "$dir"/../docs.md +done From 19c06cc6330bdafcb1ea61b37ef55001e01ab1c7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 22 Mar 2021 12:23:16 -0700 Subject: [PATCH 0903/1772] Rename `2big` to `too_big`. --- proposals/filesystem/standard/wasi-filesystem/docs.md | 4 ++-- .../filesystem/standard/wasi-filesystem/witx/typenames.witx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/filesystem/standard/wasi-filesystem/docs.md b/proposals/filesystem/standard/wasi-filesystem/docs.md index a172f08b2..081b10540 100644 --- a/proposals/filesystem/standard/wasi-filesystem/docs.md +++ b/proposals/filesystem/standard/wasi-filesystem/docs.md @@ -54,8 +54,8 @@ Alignment: 2 - `success` No error occurred. System call completed successfully. -- `2big` -Argument list too long. +- `too_big` +Argument list too long. This is similar to `E2BIG` in POSIX. - `access` Permission denied. diff --git a/proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx b/proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx index bbd6489df..ed4f44621 100644 --- a/proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx +++ b/proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx @@ -38,8 +38,8 @@ (enum (@witx tag u16) ;;; No error occurred. System call completed successfully. $success - ;;; Argument list too long. - $2big + ;;; Argument list too long. This is similar to `E2BIG` in POSIX. + $too_big ;;; Permission denied. $access ;;; Address in use. From 6385e610d23368404d4f9afb7d9b52b01790ad01 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 22 Mar 2021 12:29:52 -0700 Subject: [PATCH 0904/1772] Rename `too_big` to `toobig` for now. --- proposals/filesystem/standard/wasi-filesystem/docs.md | 2 +- .../filesystem/standard/wasi-filesystem/witx/typenames.witx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/standard/wasi-filesystem/docs.md b/proposals/filesystem/standard/wasi-filesystem/docs.md index 081b10540..faf0d37dc 100644 --- a/proposals/filesystem/standard/wasi-filesystem/docs.md +++ b/proposals/filesystem/standard/wasi-filesystem/docs.md @@ -54,7 +54,7 @@ Alignment: 2 - `success` No error occurred. System call completed successfully. -- `too_big` +- `toobig` Argument list too long. This is similar to `E2BIG` in POSIX. - `access` diff --git a/proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx b/proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx index ed4f44621..8821132c6 100644 --- a/proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx +++ b/proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx @@ -39,7 +39,7 @@ ;;; No error occurred. System call completed successfully. $success ;;; Argument list too long. This is similar to `E2BIG` in POSIX. - $too_big + $toobig ;;; Permission denied. $access ;;; Address in use. From 9e6eb649110eca13b7f3be98cd245d18b387c70e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 26 Mar 2021 17:35:41 -0700 Subject: [PATCH 0905/1772] Update the top-level README.md with more information. (#6) --- proposals/clocks/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 22449e08b..6fe6176b6 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -1,5 +1,11 @@ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4323447.svg)](https://doi.org/10.5281/zenodo.4323447) +This repository is a clone of github.com/WebAssembly/WASI/. It is meant for +discussion, prototype specification and implementation of the WASI Clocks +proposal. + +Original README from upstream repo follows... + # WebAssembly System Interface ![WASI](WASI.png) From 0334942fbf8da4a4484af3ad91727e077c512e3e Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 7 Oct 2021 16:42:12 -0400 Subject: [PATCH 0906/1772] Initial commit --- proposals/io/README.md | 91 ++++++++++++++++++++++++++ proposals/io/proposal-template.witx.md | 3 + proposals/io/test/README.md | 11 ++++ 3 files changed, 105 insertions(+) create mode 100644 proposals/io/README.md create mode 100644 proposals/io/proposal-template.witx.md create mode 100644 proposals/io/test/README.md diff --git a/proposals/io/README.md b/proposals/io/README.md new file mode 100644 index 000000000..c9be33c98 --- /dev/null +++ b/proposals/io/README.md @@ -0,0 +1,91 @@ +# [Example WASI proposal] + +This template can be used to start a new proposal, which can then be proposed in the WASI Subgroup meetings. + +The sections below are recommended. However, every proposal is different, and the community can help you flesh out the proposal, so don't block on having something filled in for each one of them. + +Thank you to the W3C Privacy CG for the [inspiration](https://github.com/privacycg/template)! + +# [Title] + +A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. + +### Champions + +- [Champion 1] +- [Champion 2] +- [etc.] + +### Phase 4 Advancement Criteria + +[For your proposal to enter Phase 2, you will need to define your advancement criteria for entering Phase 4.] + +## Table of Contents [if the explainer is longer than one printed page] + +- Introduction +- Goals [or Motivating Use Cases, or Scenarios] +- Non-goals +- Detailed design discussion + - [Tricky design choice #1] + - [Tricky design choice 2] +- Considered alternatives + - [Alternative 1] + - [Alternative 2] +- Stakeholder Feedback +- References & acknowledgements + +### Introduction + +[The "executive summary" or "abstract". Explain in a few sentences what the goals of the project are, and a brief overview of how the solution works. This should be no more than 1-2 paragraphs.] + +### Goals [or Motivating Use Cases, or Scenarios] + +[What is the end-user need which this project aims to address?] + +### Non-goals + +[If there are "adjacent" goals which may appear to be in scope but aren't, enumerate them here. This section may be fleshed out as your design progresses and you encounter necessary technical and other trade-offs.] + +### Detailed design discussion + +[Short summary of the approach.] + +[This section should mostly refer to the .witx.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] + +#### [Tricky design choice #1] + +[Talk through the tradeoffs in coming to the specific design point you want to make.] + +``` +// Illustrated with example code. +``` + +[This may be an open question, in which case you should link to any active discussion threads.] + +#### [Tricky design choice 2] + +[etc.] + +### Considered alternatives + +[This should include as many alternatives as you can, from high level architectural decisions down to alternative naming choices.] + +#### [Alternative 1] + +[Describe an alternative which was considered, and why you decided against it.] + +#### [Alternative 2] + +[etc.] + +### Stakeholder Feedback + +[Summarize feedback from implementers, linking to issues or other posts as necessary]. + +### References & acknowledgements + +Many thanks for valuable feedback and advice from: + +- [Person 1] +- [Person 2] +- [etc.] diff --git a/proposals/io/proposal-template.witx.md b/proposals/io/proposal-template.witx.md new file mode 100644 index 000000000..c73563174 --- /dev/null +++ b/proposals/io/proposal-template.witx.md @@ -0,0 +1,3 @@ +# [Proposal Template] API + +TK fill in template diff --git a/proposals/io/test/README.md b/proposals/io/test/README.md new file mode 100644 index 000000000..c274acd9d --- /dev/null +++ b/proposals/io/test/README.md @@ -0,0 +1,11 @@ +# Testing guidelines + +TK fill in testing guidelines + +## Installing the tools + +TK fill in instructions + +## Running the tests + +TK fill in instructions From dbd9293dba33fc8bfc682da2085b6136542690aa Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 7 Oct 2021 16:42:12 -0400 Subject: [PATCH 0907/1772] Initial commit --- proposals/sockets/README.md | 91 +++++++++++++++++++++ proposals/sockets/proposal-template.witx.md | 3 + proposals/sockets/test/README.md | 11 +++ 3 files changed, 105 insertions(+) create mode 100644 proposals/sockets/README.md create mode 100644 proposals/sockets/proposal-template.witx.md create mode 100644 proposals/sockets/test/README.md diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md new file mode 100644 index 000000000..c9be33c98 --- /dev/null +++ b/proposals/sockets/README.md @@ -0,0 +1,91 @@ +# [Example WASI proposal] + +This template can be used to start a new proposal, which can then be proposed in the WASI Subgroup meetings. + +The sections below are recommended. However, every proposal is different, and the community can help you flesh out the proposal, so don't block on having something filled in for each one of them. + +Thank you to the W3C Privacy CG for the [inspiration](https://github.com/privacycg/template)! + +# [Title] + +A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. + +### Champions + +- [Champion 1] +- [Champion 2] +- [etc.] + +### Phase 4 Advancement Criteria + +[For your proposal to enter Phase 2, you will need to define your advancement criteria for entering Phase 4.] + +## Table of Contents [if the explainer is longer than one printed page] + +- Introduction +- Goals [or Motivating Use Cases, or Scenarios] +- Non-goals +- Detailed design discussion + - [Tricky design choice #1] + - [Tricky design choice 2] +- Considered alternatives + - [Alternative 1] + - [Alternative 2] +- Stakeholder Feedback +- References & acknowledgements + +### Introduction + +[The "executive summary" or "abstract". Explain in a few sentences what the goals of the project are, and a brief overview of how the solution works. This should be no more than 1-2 paragraphs.] + +### Goals [or Motivating Use Cases, or Scenarios] + +[What is the end-user need which this project aims to address?] + +### Non-goals + +[If there are "adjacent" goals which may appear to be in scope but aren't, enumerate them here. This section may be fleshed out as your design progresses and you encounter necessary technical and other trade-offs.] + +### Detailed design discussion + +[Short summary of the approach.] + +[This section should mostly refer to the .witx.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] + +#### [Tricky design choice #1] + +[Talk through the tradeoffs in coming to the specific design point you want to make.] + +``` +// Illustrated with example code. +``` + +[This may be an open question, in which case you should link to any active discussion threads.] + +#### [Tricky design choice 2] + +[etc.] + +### Considered alternatives + +[This should include as many alternatives as you can, from high level architectural decisions down to alternative naming choices.] + +#### [Alternative 1] + +[Describe an alternative which was considered, and why you decided against it.] + +#### [Alternative 2] + +[etc.] + +### Stakeholder Feedback + +[Summarize feedback from implementers, linking to issues or other posts as necessary]. + +### References & acknowledgements + +Many thanks for valuable feedback and advice from: + +- [Person 1] +- [Person 2] +- [etc.] diff --git a/proposals/sockets/proposal-template.witx.md b/proposals/sockets/proposal-template.witx.md new file mode 100644 index 000000000..c73563174 --- /dev/null +++ b/proposals/sockets/proposal-template.witx.md @@ -0,0 +1,3 @@ +# [Proposal Template] API + +TK fill in template diff --git a/proposals/sockets/test/README.md b/proposals/sockets/test/README.md new file mode 100644 index 000000000..c274acd9d --- /dev/null +++ b/proposals/sockets/test/README.md @@ -0,0 +1,11 @@ +# Testing guidelines + +TK fill in testing guidelines + +## Installing the tools + +TK fill in instructions + +## Running the tests + +TK fill in instructions From 27b8328b00ed32915e1292ff08f73a0047370856 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 11 Oct 2021 17:13:01 -0400 Subject: [PATCH 0908/1772] Incorporate feedback --- proposals/io/README.md | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/proposals/io/README.md b/proposals/io/README.md index c9be33c98..c513a7c70 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -10,6 +10,10 @@ Thank you to the W3C Privacy CG for the [inspiration](https://github.com/privacy A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. +### Current Phase + +[Fill in the current phase, e.g. Phase 1] + ### Champions - [Champion 1] @@ -18,20 +22,21 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Phase 4 Advancement Criteria -[For your proposal to enter Phase 2, you will need to define your advancement criteria for entering Phase 4.] +TODO before entering Phase 2. ## Table of Contents [if the explainer is longer than one printed page] - Introduction - Goals [or Motivating Use Cases, or Scenarios] - Non-goals +- API walk-through - Detailed design discussion - [Tricky design choice #1] - [Tricky design choice 2] - Considered alternatives - [Alternative 1] - [Alternative 2] -- Stakeholder Feedback +- Stakeholder Interest & Feedback - References & acknowledgements ### Introduction @@ -46,9 +51,19 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A [If there are "adjacent" goals which may appear to be in scope but aren't, enumerate them here. This section may be fleshed out as your design progresses and you encounter necessary technical and other trade-offs.] -### Detailed design discussion +### API walk-through + +[Walk through of how someone would use this API.] + +#### [Use case 1] + +[Provide example code snippets and diagrams explaining how the API would be used to solve the given problem] -[Short summary of the approach.] +#### [Use case 2] + +[etc.] + +### Detailed design discussion [This section should mostly refer to the .witx.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] @@ -68,7 +83,7 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Considered alternatives -[This should include as many alternatives as you can, from high level architectural decisions down to alternative naming choices.] +[This section is not required if you already covered considered alternatives in the design discussion above.] #### [Alternative 1] @@ -78,9 +93,11 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A [etc.] -### Stakeholder Feedback +### Stakeholder Interest & Feedback + +TODO before entering Phase 3. -[Summarize feedback from implementers, linking to issues or other posts as necessary]. +[This should include a list of implementers who have expressed interest in implementing the proposal] ### References & acknowledgements From ff6b93fbd78ccbfe88b5361ea6b65592acc53c1b Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 11 Oct 2021 17:13:01 -0400 Subject: [PATCH 0909/1772] Incorporate feedback --- proposals/sockets/README.md | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index c9be33c98..c513a7c70 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -10,6 +10,10 @@ Thank you to the W3C Privacy CG for the [inspiration](https://github.com/privacy A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. +### Current Phase + +[Fill in the current phase, e.g. Phase 1] + ### Champions - [Champion 1] @@ -18,20 +22,21 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Phase 4 Advancement Criteria -[For your proposal to enter Phase 2, you will need to define your advancement criteria for entering Phase 4.] +TODO before entering Phase 2. ## Table of Contents [if the explainer is longer than one printed page] - Introduction - Goals [or Motivating Use Cases, or Scenarios] - Non-goals +- API walk-through - Detailed design discussion - [Tricky design choice #1] - [Tricky design choice 2] - Considered alternatives - [Alternative 1] - [Alternative 2] -- Stakeholder Feedback +- Stakeholder Interest & Feedback - References & acknowledgements ### Introduction @@ -46,9 +51,19 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A [If there are "adjacent" goals which may appear to be in scope but aren't, enumerate them here. This section may be fleshed out as your design progresses and you encounter necessary technical and other trade-offs.] -### Detailed design discussion +### API walk-through + +[Walk through of how someone would use this API.] + +#### [Use case 1] + +[Provide example code snippets and diagrams explaining how the API would be used to solve the given problem] -[Short summary of the approach.] +#### [Use case 2] + +[etc.] + +### Detailed design discussion [This section should mostly refer to the .witx.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] @@ -68,7 +83,7 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Considered alternatives -[This should include as many alternatives as you can, from high level architectural decisions down to alternative naming choices.] +[This section is not required if you already covered considered alternatives in the design discussion above.] #### [Alternative 1] @@ -78,9 +93,11 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A [etc.] -### Stakeholder Feedback +### Stakeholder Interest & Feedback + +TODO before entering Phase 3. -[Summarize feedback from implementers, linking to issues or other posts as necessary]. +[This should include a list of implementers who have expressed interest in implementing the proposal] ### References & acknowledgements From 81bdf67d57002390deedbe9c1e15c63b1c09a751 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 11 Oct 2021 17:15:38 -0400 Subject: [PATCH 0910/1772] Change file extension --- proposals/io/README.md | 2 +- .../io/{proposal-template.witx.md => proposal-template.wai.md} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename proposals/io/{proposal-template.witx.md => proposal-template.wai.md} (100%) diff --git a/proposals/io/README.md b/proposals/io/README.md index c513a7c70..903bf374f 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -65,7 +65,7 @@ TODO before entering Phase 2. ### Detailed design discussion -[This section should mostly refer to the .witx.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] +[This section should mostly refer to the .wai.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] #### [Tricky design choice #1] diff --git a/proposals/io/proposal-template.witx.md b/proposals/io/proposal-template.wai.md similarity index 100% rename from proposals/io/proposal-template.witx.md rename to proposals/io/proposal-template.wai.md From 464532ff635a11308afb6208070fcee49219a52c Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Mon, 11 Oct 2021 17:15:38 -0400 Subject: [PATCH 0911/1772] Change file extension --- proposals/sockets/README.md | 2 +- .../{proposal-template.witx.md => proposal-template.wai.md} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename proposals/sockets/{proposal-template.witx.md => proposal-template.wai.md} (100%) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index c513a7c70..903bf374f 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -65,7 +65,7 @@ TODO before entering Phase 2. ### Detailed design discussion -[This section should mostly refer to the .witx.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] +[This section should mostly refer to the .wai.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] #### [Tricky design choice #1] diff --git a/proposals/sockets/proposal-template.witx.md b/proposals/sockets/proposal-template.wai.md similarity index 100% rename from proposals/sockets/proposal-template.witx.md rename to proposals/sockets/proposal-template.wai.md From dd6c237df37e7f5ed384850cc4cd82db18f233b4 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Wed, 20 Oct 2021 11:10:28 -0400 Subject: [PATCH 0912/1772] Link the TOC --- proposals/io/README.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/proposals/io/README.md b/proposals/io/README.md index 903bf374f..fa5687731 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -26,18 +26,20 @@ TODO before entering Phase 2. ## Table of Contents [if the explainer is longer than one printed page] -- Introduction -- Goals [or Motivating Use Cases, or Scenarios] -- Non-goals -- API walk-through -- Detailed design discussion - - [Tricky design choice #1] - - [Tricky design choice 2] -- Considered alternatives - - [Alternative 1] - - [Alternative 2] -- Stakeholder Interest & Feedback -- References & acknowledgements +- [Introduction](#introduction) +- [Goals [or Motivating Use Cases, or Scenarios]](#goals-or-motivating-use-cases-or-scenarios) +- [Non-goals](#non-goals) +- [API walk-through](#api-walk-through) + - [Use case 1](#use-case-1) + - [Use case 2](#use-case-2) +- [Detailed design discussion](#detailed-design-discussion) + - [[Tricky design choice 1]](#tricky-design-choice-1) + - [[Tricky design choice 2]](#tricky-design-choice-2) +- [Considered alternatives](#considered-alternatives) + - [[Alternative 1]](#alternative-1) + - [[Alternative 2]](#alternative-2) +- [Stakeholder Interest & Feedback](#stakeholder-interest--feedback) +- [References & acknowledgements](#references--acknowledgements) ### Introduction From f9846fe950bbd05901c82f3f8400a6ef3b51c343 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Wed, 20 Oct 2021 11:10:28 -0400 Subject: [PATCH 0913/1772] Link the TOC --- proposals/sockets/README.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 903bf374f..fa5687731 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -26,18 +26,20 @@ TODO before entering Phase 2. ## Table of Contents [if the explainer is longer than one printed page] -- Introduction -- Goals [or Motivating Use Cases, or Scenarios] -- Non-goals -- API walk-through -- Detailed design discussion - - [Tricky design choice #1] - - [Tricky design choice 2] -- Considered alternatives - - [Alternative 1] - - [Alternative 2] -- Stakeholder Interest & Feedback -- References & acknowledgements +- [Introduction](#introduction) +- [Goals [or Motivating Use Cases, or Scenarios]](#goals-or-motivating-use-cases-or-scenarios) +- [Non-goals](#non-goals) +- [API walk-through](#api-walk-through) + - [Use case 1](#use-case-1) + - [Use case 2](#use-case-2) +- [Detailed design discussion](#detailed-design-discussion) + - [[Tricky design choice 1]](#tricky-design-choice-1) + - [[Tricky design choice 2]](#tricky-design-choice-2) +- [Considered alternatives](#considered-alternatives) + - [[Alternative 1]](#alternative-1) + - [[Alternative 2]](#alternative-2) +- [Stakeholder Interest & Feedback](#stakeholder-interest--feedback) +- [References & acknowledgements](#references--acknowledgements) ### Introduction From da822fe39071654b86b9b1632ce56f33512b62a2 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Wed, 20 Oct 2021 12:13:49 -0400 Subject: [PATCH 0914/1772] Fill in template example --- proposals/io/proposal-template.wai.md | 31 ++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/proposals/io/proposal-template.wai.md b/proposals/io/proposal-template.wai.md index c73563174..123236673 100644 --- a/proposals/io/proposal-template.wai.md +++ b/proposals/io/proposal-template.wai.md @@ -1,3 +1,32 @@ # [Proposal Template] API -TK fill in template +[This document contains the actual specification. It should be written in the WAI interface definition format. You can find more documentation on the WAI syntax (coming soon!).] + +[Note that all comments inside of WAI code blocks will be included in the developer facing documentation for language bindings generated using this WAI file. If there is additional information that needs to be communicated to implementers of the API, then these should be captured in text directly below the code block.] + +[If you want to include examples of the API in use, these should be in the README and linked to from this file.] + +## api_type_one + +```wai +/// Short description +/// +/// Explanation for developers using the API. +record api_type_one { + property_1: u64, + property_2: string, +} +``` + +More rigorous specification details for the implementer go here, if needed. + +## api_function_one + +```wai +/// Short description +/// +/// Explanation for developers using the API. +api_function_one: function() -> api_type_one +``` + +If needed, this would explain what a compliant implementation MUST do, such as never returning an earlier result from a later call. From 067e2b457ea00bf56ee8bb246c2e1df2b57ba5cd Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Wed, 20 Oct 2021 12:13:49 -0400 Subject: [PATCH 0915/1772] Fill in template example --- proposals/sockets/proposal-template.wai.md | 31 +++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/proposals/sockets/proposal-template.wai.md b/proposals/sockets/proposal-template.wai.md index c73563174..123236673 100644 --- a/proposals/sockets/proposal-template.wai.md +++ b/proposals/sockets/proposal-template.wai.md @@ -1,3 +1,32 @@ # [Proposal Template] API -TK fill in template +[This document contains the actual specification. It should be written in the WAI interface definition format. You can find more documentation on the WAI syntax (coming soon!).] + +[Note that all comments inside of WAI code blocks will be included in the developer facing documentation for language bindings generated using this WAI file. If there is additional information that needs to be communicated to implementers of the API, then these should be captured in text directly below the code block.] + +[If you want to include examples of the API in use, these should be in the README and linked to from this file.] + +## api_type_one + +```wai +/// Short description +/// +/// Explanation for developers using the API. +record api_type_one { + property_1: u64, + property_2: string, +} +``` + +More rigorous specification details for the implementer go here, if needed. + +## api_function_one + +```wai +/// Short description +/// +/// Explanation for developers using the API. +api_function_one: function() -> api_type_one +``` + +If needed, this would explain what a compliant implementation MUST do, such as never returning an earlier result from a later call. From ebb76e523bb735f2a71da12116ccc9d64d7817c2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 16 Nov 2021 07:55:32 -0800 Subject: [PATCH 0916/1772] Add GitHub Actions configuration This adds to the template some configuration for CI to automatically verify that `*.abi.md` files are up-to-date, and additionally adds a `*.abi.md` file for the current example. --- proposals/io/.github/workflows/main.yml | 16 +++++++++++++ proposals/io/proposal-template.abi.md | 31 +++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 proposals/io/.github/workflows/main.yml create mode 100644 proposals/io/proposal-template.abi.md diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml new file mode 100644 index 000000000..0e6263384 --- /dev/null +++ b/proposals/io/.github/workflows/main.yml @@ -0,0 +1,16 @@ +name: CI +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + abi-up-to-date: + name: Check ABI files are up-to-date + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: WebAssembly/wai-abi-up-to-date@v1 + with: + wai-abi-tag: wai-abi-0.1.0 diff --git a/proposals/io/proposal-template.abi.md b/proposals/io/proposal-template.abi.md new file mode 100644 index 000000000..34daa27ab --- /dev/null +++ b/proposals/io/proposal-template.abi.md @@ -0,0 +1,31 @@ +# Types + +## `api_type_one`: record + + Short description + + Explanation for developers using the API. + +Size: 16, Alignment: 8 + +### Record Fields + +- [`property_1`](#api_type_one.property_1): `u64` + + +- [`property_2`](#api_type_one.property_2): `string` + + +# Functions + +---- + +#### `api_function_one` + + Short description + + Explanation for developers using the API. +##### Results + +- ``: [`api_type_one`](#api_type_one) + From 66b377a680a57769c4f97a7d4395213c524d229b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 16 Nov 2021 07:55:32 -0800 Subject: [PATCH 0917/1772] Add GitHub Actions configuration This adds to the template some configuration for CI to automatically verify that `*.abi.md` files are up-to-date, and additionally adds a `*.abi.md` file for the current example. --- proposals/sockets/.github/workflows/main.yml | 16 ++++++++++ proposals/sockets/proposal-template.abi.md | 31 ++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 proposals/sockets/.github/workflows/main.yml create mode 100644 proposals/sockets/proposal-template.abi.md diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml new file mode 100644 index 000000000..0e6263384 --- /dev/null +++ b/proposals/sockets/.github/workflows/main.yml @@ -0,0 +1,16 @@ +name: CI +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + abi-up-to-date: + name: Check ABI files are up-to-date + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: WebAssembly/wai-abi-up-to-date@v1 + with: + wai-abi-tag: wai-abi-0.1.0 diff --git a/proposals/sockets/proposal-template.abi.md b/proposals/sockets/proposal-template.abi.md new file mode 100644 index 000000000..34daa27ab --- /dev/null +++ b/proposals/sockets/proposal-template.abi.md @@ -0,0 +1,31 @@ +# Types + +## `api_type_one`: record + + Short description + + Explanation for developers using the API. + +Size: 16, Alignment: 8 + +### Record Fields + +- [`property_1`](#api_type_one.property_1): `u64` + + +- [`property_2`](#api_type_one.property_2): `string` + + +# Functions + +---- + +#### `api_function_one` + + Short description + + Explanation for developers using the API. +##### Results + +- ``: [`api_type_one`](#api_type_one) + From f8820553ce79d1d6b156d9e91433a04a8b01522e Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Wed, 1 Dec 2021 16:26:19 -0500 Subject: [PATCH 0918/1772] Update references of to --- proposals/io/README.md | 2 +- ...{proposal-template.wai.md => proposal-template.wit.md} | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) rename proposals/io/{proposal-template.wai.md => proposal-template.wit.md} (78%) diff --git a/proposals/io/README.md b/proposals/io/README.md index fa5687731..e76604398 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -67,7 +67,7 @@ TODO before entering Phase 2. ### Detailed design discussion -[This section should mostly refer to the .wai.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] +[This section should mostly refer to the .wit.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] #### [Tricky design choice #1] diff --git a/proposals/io/proposal-template.wai.md b/proposals/io/proposal-template.wit.md similarity index 78% rename from proposals/io/proposal-template.wai.md rename to proposals/io/proposal-template.wit.md index 123236673..900b74e75 100644 --- a/proposals/io/proposal-template.wai.md +++ b/proposals/io/proposal-template.wit.md @@ -1,14 +1,14 @@ # [Proposal Template] API -[This document contains the actual specification. It should be written in the WAI interface definition format. You can find more documentation on the WAI syntax (coming soon!).] +[This document contains the actual specification. It should be written in the WIT interface definition format. You can find more documentation on the WIT syntax (coming soon!).] -[Note that all comments inside of WAI code blocks will be included in the developer facing documentation for language bindings generated using this WAI file. If there is additional information that needs to be communicated to implementers of the API, then these should be captured in text directly below the code block.] +[Note that all comments inside of WIT code blocks will be included in the developer facing documentation for language bindings generated using this WIT file. If there is additional information that needs to be communicated to implementers of the API, then these should be captured in text directly below the code block.] [If you want to include examples of the API in use, these should be in the README and linked to from this file.] ## api_type_one -```wai +```wit /// Short description /// /// Explanation for developers using the API. @@ -22,7 +22,7 @@ More rigorous specification details for the implementer go here, if needed. ## api_function_one -```wai +```wit /// Short description /// /// Explanation for developers using the API. From d8c7db2a9c89ce106e86314b32edbb634c3877ed Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Wed, 1 Dec 2021 16:26:19 -0500 Subject: [PATCH 0919/1772] Update references of to --- proposals/sockets/README.md | 2 +- ...{proposal-template.wai.md => proposal-template.wit.md} | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) rename proposals/sockets/{proposal-template.wai.md => proposal-template.wit.md} (78%) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index fa5687731..e76604398 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -67,7 +67,7 @@ TODO before entering Phase 2. ### Detailed design discussion -[This section should mostly refer to the .wai.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] +[This section should mostly refer to the .wit.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] #### [Tricky design choice #1] diff --git a/proposals/sockets/proposal-template.wai.md b/proposals/sockets/proposal-template.wit.md similarity index 78% rename from proposals/sockets/proposal-template.wai.md rename to proposals/sockets/proposal-template.wit.md index 123236673..900b74e75 100644 --- a/proposals/sockets/proposal-template.wai.md +++ b/proposals/sockets/proposal-template.wit.md @@ -1,14 +1,14 @@ # [Proposal Template] API -[This document contains the actual specification. It should be written in the WAI interface definition format. You can find more documentation on the WAI syntax (coming soon!).] +[This document contains the actual specification. It should be written in the WIT interface definition format. You can find more documentation on the WIT syntax (coming soon!).] -[Note that all comments inside of WAI code blocks will be included in the developer facing documentation for language bindings generated using this WAI file. If there is additional information that needs to be communicated to implementers of the API, then these should be captured in text directly below the code block.] +[Note that all comments inside of WIT code blocks will be included in the developer facing documentation for language bindings generated using this WIT file. If there is additional information that needs to be communicated to implementers of the API, then these should be captured in text directly below the code block.] [If you want to include examples of the API in use, these should be in the README and linked to from this file.] ## api_type_one -```wai +```wit /// Short description /// /// Explanation for developers using the API. @@ -22,7 +22,7 @@ More rigorous specification details for the implementer go here, if needed. ## api_function_one -```wai +```wit /// Short description /// /// Explanation for developers using the API. From fe5f300e63661c97d3985f678ce8fbdc6d139a71 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 22 Nov 2021 13:32:24 -0800 Subject: [PATCH 0920/1772] Remove the old repo contents. --- .../filesystem/.github/workflows/main.yml | 47 - proposals/filesystem/.gitignore | 11 - proposals/filesystem/Charter.md | 55 - proposals/filesystem/Contributing.md | 8 - proposals/filesystem/README.md | 26 - proposals/filesystem/WASI.png | Bin 11059 -> 0 bytes .../filesystem/design/application-abi.md | 60 - .../filesystem/design/optional-imports.md | 108 - proposals/filesystem/docs/DesignPrinciples.md | 291 -- proposals/filesystem/docs/HighLevelGoals.md | 25 - proposals/filesystem/docs/Process.md | 37 - proposals/filesystem/docs/Proposals.md | 64 - proposals/filesystem/docs/README.md | 15 - proposals/filesystem/docs/WASI-overview.md | 147 - .../docs/wasi-software-architecture.png | Bin 28267 -> 0 bytes proposals/filesystem/docs/witx.md | 30 - .../filesystem/meetings/2019/WASI-05-02.md | 377 --- .../filesystem/meetings/2019/WASI-05-16.md | 291 -- .../filesystem/meetings/2019/WASI-05-30.md | 116 - .../filesystem/meetings/2019/WASI-06-27.md | 241 -- .../filesystem/meetings/2019/WASI-07-18.md | 262 -- .../filesystem/meetings/2019/WASI-08-15.md | 121 - .../filesystem/meetings/2019/WASI-08-30.md | 64 - .../filesystem/meetings/2019/WASI-09-12.md | 92 - .../filesystem/meetings/2019/WASI-09-26.md | 60 - .../filesystem/meetings/2019/WASI-10-15.md | 116 - .../filesystem/meetings/2019/WASI-10-24.md | 171 -- .../filesystem/meetings/2019/WASI-11-07.md | 102 - .../filesystem/meetings/2019/WASI-11-21.md | 63 - .../filesystem/meetings/2019/WASI-12-05.md | 124 - .../filesystem/meetings/2019/WASI-12-19.md | 44 - .../2019/What HTTP Needs from WebAssembly.pdf | Bin 82687 -> 0 bytes .../filesystem/meetings/2020/WASI-01-16.md | 123 - .../filesystem/meetings/2020/WASI-02-27.md | 92 - .../filesystem/meetings/2020/WASI-03-12.md | 85 - .../filesystem/meetings/2020/WASI-03-26.md | 126 - .../filesystem/meetings/2020/WASI-04-09.md | 83 - .../filesystem/meetings/2020/WASI-05-07.md | 89 - .../filesystem/meetings/2020/WASI-05-21.md | 99 - .../filesystem/meetings/2020/WASI-06-04.md | 43 - .../filesystem/meetings/2020/WASI-07-02.md | 41 - .../filesystem/meetings/2020/WASI-07-16.md | 41 - .../filesystem/meetings/2020/WASI-07-30.md | 36 - .../filesystem/meetings/2020/WASI-08-27.md | 42 - .../filesystem/meetings/2020/WASI-09-10.md | 33 - .../filesystem/meetings/2020/WASI-09-24.md | 30 - .../filesystem/meetings/2020/WASI-10-08.md | 42 - .../filesystem/meetings/2020/WASI-10-22.md | 211 -- .../filesystem/meetings/2020/WASI-11-19.md | 153 - .../filesystem/meetings/2020/WASI-12-03.md | 130 - .../filesystem/meetings/2021/WASI-01-14.md | 75 - .../filesystem/meetings/2021/WASI-01-28.md | 206 -- .../filesystem/meetings/2021/WASI-02-11.md | 118 - .../filesystem/meetings/2021/WASI-02-25.md | 131 - .../filesystem/meetings/2021/WASI-03-11.md | 32 - .../filesystem/meetings/2021/WASI-03-25.md | 31 - .../filesystem/meetings/2021/WASI-04-08.md | 31 - .../filesystem/meetings/2021/WASI-04-22.md | 31 - .../filesystem/meetings/2021/WASI-05-06.md | 31 - .../filesystem/meetings/2021/WASI-05-20.md | 31 - .../filesystem/meetings/2021/WASI-06-03.md | 31 - .../filesystem/meetings/2021/WASI-06-17.md | 31 - proposals/filesystem/meetings/README.md | 61 - proposals/filesystem/phases/README.md | 50 - proposals/filesystem/phases/ephemeral/docs.md | 2562 ----------------- .../phases/ephemeral/witx/typenames.witx | 708 ----- .../ephemeral/witx/wasi_ephemeral_args.witx | 27 - .../ephemeral/witx/wasi_ephemeral_clock.witx | 35 - .../witx/wasi_ephemeral_environ.witx | 27 - .../ephemeral/witx/wasi_ephemeral_fd.witx | 259 -- .../ephemeral/witx/wasi_ephemeral_path.witx | 181 -- .../ephemeral/witx/wasi_ephemeral_poll.witx | 27 - .../ephemeral/witx/wasi_ephemeral_proc.witx | 22 - .../ephemeral/witx/wasi_ephemeral_random.witx | 26 - .../ephemeral/witx/wasi_ephemeral_sched.witx | 16 - .../ephemeral/witx/wasi_ephemeral_sock.witx | 48 - .../filesystem/phases/old/snapshot_0/docs.md | 2512 ---------------- .../phases/old/snapshot_0/witx/typenames.witx | 746 ----- .../old/snapshot_0/witx/wasi_unstable.witx | 513 ---- .../filesystem/phases/snapshot/docs.html | 1279 -------- proposals/filesystem/phases/snapshot/docs.md | 2509 ---------------- .../phases/snapshot/witx/typenames.witx | 748 ----- .../snapshot/witx/wasi_snapshot_preview1.witx | 510 ---- .../filesystem/proposal-template/README.md | 4 - proposals/filesystem/proposals/README.md | 8 - proposals/filesystem/snapshots/README.md | 5 - .../filesystem/snapshots/make-snapshot.sh | 159 - proposals/filesystem/standard/README.md | 12 - .../standard/wasi-filesystem/docs.md | 2109 -------------- .../wasi-filesystem/witx/file_io.witx | 236 -- .../standard/wasi-filesystem/witx/path.witx | 181 -- .../wasi-filesystem/witx/typenames.witx | 708 ----- proposals/filesystem/tools/repo_docs.sh | 22 - proposals/filesystem/tools/witx/.gitignore | 2 - proposals/filesystem/tools/witx/Cargo.toml | 32 - proposals/filesystem/tools/witx/LICENSE | 13 - .../filesystem/tools/witx/cli/Cargo.toml | 25 - .../filesystem/tools/witx/cli/src/main.rs | 268 -- proposals/filesystem/tools/witx/src/abi.rs | 925 ------ proposals/filesystem/tools/witx/src/ast.rs | 591 ---- .../filesystem/tools/witx/src/docs/ast.rs | 503 ---- .../filesystem/tools/witx/src/docs/md.rs | 480 --- .../filesystem/tools/witx/src/docs/mod.rs | 87 - proposals/filesystem/tools/witx/src/io.rs | 103 - proposals/filesystem/tools/witx/src/layout.rs | 219 -- proposals/filesystem/tools/witx/src/lib.rs | 97 - proposals/filesystem/tools/witx/src/parser.rs | 778 ----- .../filesystem/tools/witx/src/polyfill.rs | 255 -- proposals/filesystem/tools/witx/src/render.rs | 320 -- .../tools/witx/src/representation.rs | 161 -- .../filesystem/tools/witx/src/toplevel.rs | 166 -- .../filesystem/tools/witx/src/validate.rs | 722 ----- .../filesystem/tools/witx/tests/witxt.rs | 656 ----- .../tools/witx/tests/witxt/abi.witxt | 490 ---- .../tools/witx/tests/witxt/anonymous.witxt | 56 - .../tools/witx/tests/witxt/multimodule.witxt | 22 - .../tests/witxt/multimodule/redefine_a.witx | 1 - .../witx/tests/witxt/multimodule/type_a.witx | 1 - .../witx/tests/witxt/multimodule/type_b.witx | 2 - .../witx/tests/witxt/multimodule/type_c.witx | 2 - .../witx/tests/witxt/representation.witxt | 60 - .../tools/witx/tests/witxt/shorthand.witxt | 59 - .../tools/witx/tests/witxt/simple.witxt | 12 - .../tools/witx/tests/witxt/union.witxt | 97 - .../tools/witx/tests/witxt/wasi.witxt | 26 - 125 files changed, 28987 deletions(-) delete mode 100644 proposals/filesystem/.github/workflows/main.yml delete mode 100644 proposals/filesystem/.gitignore delete mode 100644 proposals/filesystem/Charter.md delete mode 100644 proposals/filesystem/Contributing.md delete mode 100644 proposals/filesystem/README.md delete mode 100644 proposals/filesystem/WASI.png delete mode 100644 proposals/filesystem/design/application-abi.md delete mode 100644 proposals/filesystem/design/optional-imports.md delete mode 100644 proposals/filesystem/docs/DesignPrinciples.md delete mode 100644 proposals/filesystem/docs/HighLevelGoals.md delete mode 100644 proposals/filesystem/docs/Process.md delete mode 100644 proposals/filesystem/docs/Proposals.md delete mode 100644 proposals/filesystem/docs/README.md delete mode 100644 proposals/filesystem/docs/WASI-overview.md delete mode 100644 proposals/filesystem/docs/wasi-software-architecture.png delete mode 100644 proposals/filesystem/docs/witx.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-05-02.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-05-16.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-05-30.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-06-27.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-07-18.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-08-15.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-08-30.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-09-12.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-09-26.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-10-15.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-10-24.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-11-07.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-11-21.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-12-05.md delete mode 100644 proposals/filesystem/meetings/2019/WASI-12-19.md delete mode 100644 proposals/filesystem/meetings/2019/What HTTP Needs from WebAssembly.pdf delete mode 100644 proposals/filesystem/meetings/2020/WASI-01-16.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-02-27.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-03-12.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-03-26.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-04-09.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-05-07.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-05-21.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-06-04.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-07-02.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-07-16.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-07-30.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-08-27.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-09-10.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-09-24.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-10-08.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-10-22.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-11-19.md delete mode 100644 proposals/filesystem/meetings/2020/WASI-12-03.md delete mode 100644 proposals/filesystem/meetings/2021/WASI-01-14.md delete mode 100644 proposals/filesystem/meetings/2021/WASI-01-28.md delete mode 100644 proposals/filesystem/meetings/2021/WASI-02-11.md delete mode 100644 proposals/filesystem/meetings/2021/WASI-02-25.md delete mode 100644 proposals/filesystem/meetings/2021/WASI-03-11.md delete mode 100644 proposals/filesystem/meetings/2021/WASI-03-25.md delete mode 100644 proposals/filesystem/meetings/2021/WASI-04-08.md delete mode 100644 proposals/filesystem/meetings/2021/WASI-04-22.md delete mode 100644 proposals/filesystem/meetings/2021/WASI-05-06.md delete mode 100644 proposals/filesystem/meetings/2021/WASI-05-20.md delete mode 100644 proposals/filesystem/meetings/2021/WASI-06-03.md delete mode 100644 proposals/filesystem/meetings/2021/WASI-06-17.md delete mode 100644 proposals/filesystem/meetings/README.md delete mode 100644 proposals/filesystem/phases/README.md delete mode 100644 proposals/filesystem/phases/ephemeral/docs.md delete mode 100644 proposals/filesystem/phases/ephemeral/witx/typenames.witx delete mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx delete mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx delete mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx delete mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx delete mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx delete mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx delete mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx delete mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx delete mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sched.witx delete mode 100644 proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sock.witx delete mode 100644 proposals/filesystem/phases/old/snapshot_0/docs.md delete mode 100644 proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx delete mode 100644 proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx delete mode 100644 proposals/filesystem/phases/snapshot/docs.html delete mode 100644 proposals/filesystem/phases/snapshot/docs.md delete mode 100644 proposals/filesystem/phases/snapshot/witx/typenames.witx delete mode 100644 proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx delete mode 100644 proposals/filesystem/proposal-template/README.md delete mode 100644 proposals/filesystem/proposals/README.md delete mode 100644 proposals/filesystem/snapshots/README.md delete mode 100755 proposals/filesystem/snapshots/make-snapshot.sh delete mode 100644 proposals/filesystem/standard/README.md delete mode 100644 proposals/filesystem/standard/wasi-filesystem/docs.md delete mode 100644 proposals/filesystem/standard/wasi-filesystem/witx/file_io.witx delete mode 100644 proposals/filesystem/standard/wasi-filesystem/witx/path.witx delete mode 100644 proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx delete mode 100755 proposals/filesystem/tools/repo_docs.sh delete mode 100644 proposals/filesystem/tools/witx/.gitignore delete mode 100644 proposals/filesystem/tools/witx/Cargo.toml delete mode 100644 proposals/filesystem/tools/witx/LICENSE delete mode 100644 proposals/filesystem/tools/witx/cli/Cargo.toml delete mode 100644 proposals/filesystem/tools/witx/cli/src/main.rs delete mode 100644 proposals/filesystem/tools/witx/src/abi.rs delete mode 100644 proposals/filesystem/tools/witx/src/ast.rs delete mode 100644 proposals/filesystem/tools/witx/src/docs/ast.rs delete mode 100644 proposals/filesystem/tools/witx/src/docs/md.rs delete mode 100644 proposals/filesystem/tools/witx/src/docs/mod.rs delete mode 100644 proposals/filesystem/tools/witx/src/io.rs delete mode 100644 proposals/filesystem/tools/witx/src/layout.rs delete mode 100644 proposals/filesystem/tools/witx/src/lib.rs delete mode 100644 proposals/filesystem/tools/witx/src/parser.rs delete mode 100644 proposals/filesystem/tools/witx/src/polyfill.rs delete mode 100644 proposals/filesystem/tools/witx/src/render.rs delete mode 100644 proposals/filesystem/tools/witx/src/representation.rs delete mode 100644 proposals/filesystem/tools/witx/src/toplevel.rs delete mode 100644 proposals/filesystem/tools/witx/src/validate.rs delete mode 100644 proposals/filesystem/tools/witx/tests/witxt.rs delete mode 100644 proposals/filesystem/tools/witx/tests/witxt/abi.witxt delete mode 100644 proposals/filesystem/tools/witx/tests/witxt/anonymous.witxt delete mode 100644 proposals/filesystem/tools/witx/tests/witxt/multimodule.witxt delete mode 100644 proposals/filesystem/tools/witx/tests/witxt/multimodule/redefine_a.witx delete mode 100644 proposals/filesystem/tools/witx/tests/witxt/multimodule/type_a.witx delete mode 100644 proposals/filesystem/tools/witx/tests/witxt/multimodule/type_b.witx delete mode 100644 proposals/filesystem/tools/witx/tests/witxt/multimodule/type_c.witx delete mode 100644 proposals/filesystem/tools/witx/tests/witxt/representation.witxt delete mode 100644 proposals/filesystem/tools/witx/tests/witxt/shorthand.witxt delete mode 100644 proposals/filesystem/tools/witx/tests/witxt/simple.witxt delete mode 100644 proposals/filesystem/tools/witx/tests/witxt/union.witxt delete mode 100644 proposals/filesystem/tools/witx/tests/witxt/wasi.witxt diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml deleted file mode 100644 index 0305f7f32..000000000 --- a/proposals/filesystem/.github/workflows/main.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: CI -on: [push, pull_request] - -jobs: - test: - name: Test witx tools - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - steps: - - uses: actions/checkout@v1 - - name: Install Rust (rustup) - shell: bash - run: rustup update stable --no-self-update && rustup default stable - if: matrix.os != 'macos-latest' - - name: Install Rust (macos) - run: | - curl https://sh.rustup.rs | sh -s -- -y - echo "$HOME/.cargo/bin" >> $GITHUB_PATH - if: matrix.os == 'macos-latest' - - run: cargo fetch - working-directory: tools/witx - - run: cargo test --all - working-directory: tools/witx - - validate: - name: Validate witx files and docs - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Install Rust (rustup) - shell: bash - run: rustup update stable --no-self-update && rustup default stable - - - name: Check that repository docs reflect witx - run: ./tools/repo_docs.sh --check - - rustfmt: - name: Rustfmt - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Install Rust - run: rustup update stable && rustup default stable && rustup component add rustfmt - - run: cargo fmt --all -- --check - working-directory: tools/witx diff --git a/proposals/filesystem/.gitignore b/proposals/filesystem/.gitignore deleted file mode 100644 index c0476d12f..000000000 --- a/proposals/filesystem/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -*.bk -*.swp -*.swo -*.swx -tags -target -Cargo.lock -.*.rustfmt -rusty-tags.* -*~ -\#*\# diff --git a/proposals/filesystem/Charter.md b/proposals/filesystem/Charter.md deleted file mode 100644 index c50381166..000000000 --- a/proposals/filesystem/Charter.md +++ /dev/null @@ -1,55 +0,0 @@ -# WebAssembly System Interface Subgroup Charter - -The System Interface Subgroup is a sub-organization of the -[WebAssembly Community Group](https://www.w3.org/community/webassembly/) of the W3C. -As such, it is intended that its charter align with that of the CG. In particular, -the sections of the [CG charter](https://webassembly.github.io/cg-charter/) relating to -[Community and Business Group Process](https://webassembly.github.io/cg-charter/#process), -[Contribution Mechanics](https://webassembly.github.io/cg-charter/#contrib), -[Transparency](https://webassembly.github.io/cg-charter/#transparency), and -[Decision Process](https://webassembly.github.io/cg-charter/#decision) also apply to the Subgroup. - -## Goals - -The mission of this subgroup is to provide a forum for pre-standardization -collaboration on a system interface API for WebAssembly programs. - -## Scope - -The Subgroup will consider topics related to system interface APIs, including: - -- APIs for host filesystems, network stacks, and other resources. -- APIs for graphics, audio, input devices -- APIs for encryption, format conversion, and other transformations - (particularly where hardware acceleration may be available on some platforms) - - -## Deliverables - -### Specifications -The Subgroup may produce several kinds of specification-related work output: -- Creation of new specifications in standards bodies or working -groups (e.g. Wasm WG or TC39) -- Creation of new specifications outside of standards bodies -(e.g. similar to the LLVM object file format documentation in Wasm tool conventions) - -### Non-normative reports -The Subgroup may produce non-normative material such as requirements -documents, recommendations, and use cases. - -### Software -The Subgroup may produce software related to Wasm system interface APIs (either -as standalone libraries, tooling, or integration of interface-related -functionality in existing CG software such as Binaryen or WABT). Capabilities may -include: -- Libraries implementing external standard APIs in terms of WebAssembly - System Interface APIs -- Tools for producing code that uses WebAssembly System Interface APIs -- Tools for implementing WebAssembly APIs -- Tools for debugging programs using WebAssembly System Interface APIs - -## Amendments to this Charter and Chair Selection - -This charter may be amended, and Subgroup Chairs may be selected by vote of the full -WebAssembly Community Group. - diff --git a/proposals/filesystem/Contributing.md b/proposals/filesystem/Contributing.md deleted file mode 100644 index 1cc607fa4..000000000 --- a/proposals/filesystem/Contributing.md +++ /dev/null @@ -1,8 +0,0 @@ -# Contributing to WebAssembly - -Interested in participating? Please follow -[the same contributing guidelines as the design repository][]. - - [the same contributing guidelines as the design repository]: https://github.com/WebAssembly/design/blob/master/Contributing.md - -Also, please be sure to read [the README.md](README.md) for this repository. diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md deleted file mode 100644 index 22449e08b..000000000 --- a/proposals/filesystem/README.md +++ /dev/null @@ -1,26 +0,0 @@ -[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4323447.svg)](https://doi.org/10.5281/zenodo.4323447) - -# WebAssembly System Interface - -![WASI](WASI.png) - -This repository is for the WebAssembly System Interface (WASI) Subgroup of the -[WebAssembly Community Group]. It includes: - - [charter]: describes the goals, scope and deliverables of the group - - [docs]: learn more about WASI - - [meetings]: schedules and agendas for video conference and in-person meetings - - [phases]: the current WASI specifications - - [proposals]: the status of each new specification proposal - -[charter]: Charter.md -[docs]: docs/README.md -[meetings]: meetings/README.md -[phases]: phases/README.md -[proposals]: docs/Proposals.md -[WebAssembly Community Group]: https://www.w3.org/community/webassembly/ - -### Contributing - -The [issue tracker] is the place to ask questions, make suggestions, and start discussions. - -[issue tracker]: https://github.com/WebAssembly/WASI/issues diff --git a/proposals/filesystem/WASI.png b/proposals/filesystem/WASI.png deleted file mode 100644 index bb018e99e3ec2a66d8f2d6a7bcc63105b74d9262..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11059 zcmdsdcTiKo+b%_lbU}*rqM#rk(xpT|1f+`ej!5s)Yv`yTASgv3bdV0xLkS(Eo6sSI z-btvThTQnOGvCbp@0&Z{{pTigCbN6??ECDydv@RV$@5u9ONEk*nG6pPk5Wzbl`bA0 z{(mk~Vq8t`lpzZDL;PM{@|oudLkND#=h;BUO$>jKmAAL!(^RtaaD zcqPu5--0PggunD?lNe;Ec$F0u=+!tqi3pykveI%c^?B;jMC66}5RrX+8TPVG-k@$t zsoa#AO|+mTaI6Egbw1279$)XQ4ui0dI7!a%kf~vF2}o#e6dd)Jq{UQ@a8JC&Y&A0yClJI%bqLx)p8Nu@_2ELZQz~bAwU-` zjNtOX@;5wjVL73l)e7_%-}-}{kTi!%olwF+_vf8CcsVdreP%gTplVt;$K@^c_=!Lc z%B6;N1JC0IA0jD8rt9b(E`+a~d!%@3@JV)i2z)1>(=~YWqPFGWE4omNHFK0e#yjZM z{lZaBv1UI>tBxkTp#PLL-+m+L`Fi{Tgy}rqh1iAT!`bfTD^4?Eqx7TLNU%`f6vK;)D=kOd1xeX0QM0Q$+m}Z#+c9&oXyO zXGeVb;stIT4BmrI1irsaIdqK!WQv*LS|$Vw{_D$YySKI*VXRr(q@+DQdUl32X;ONn zFdyHD2Rz5!K?83UCHWFYmtZ6S&x+3RP+w}k1bX>9tgr)`w@DJ^=L8%wp8IbO7s*YL zbB}L7Q#1PGP-(FWoZ@4(niOz7jVLbDO&nz>q0>MYgNw!T%SSdupzB~sKF|}UWdMGw z56eG?RIyzA>llRZkMwJmI0y&H87yBif??S0HN(GnDW4)v<)PGV9;-Z#>GG|2HE(d! z7%OQ3+Py?S5@{t#-A+*UmbQjE!r67;pv>T%_%7N_5L| zh$#$m|Ds9<9m;5UKmrL`HCh3@7zRji^=V_>{63260b~bC0G6#g*nPjT;~m7@@urg) zc^jR7f;UmhCowObEGYvIFogwgI0w-!$+OEva`+D)v8~o{^G+4Rj>1OEKx8x$Qa#LB zriw}{mJcRw#*+o&j0kteN3sOr?kzN)VbM*D5y7eWB<-E@(91l8`U{ztI3G|~w0COb zD|=Mq^J%jRWZ}Pg*=Dj+ZMNV_l|T?{5TS=_a?BgBT>3-!UO<@Rq{XXO3jDa4rN8$! z>C30bs>=VP*wv5N9; zZk(wlH>FBQA@qK9sZjVoF!u|&{||8g6J;{pd;c}qfBpU6mR%ZueakUpQltqxxvWAn~wd*u;(OPQ3~dOj|&4;24}nh}3mJ zV6ospuj#|%GutPWjXLw})}mGhkqnzZ2a$_R;<(I?fCANVHKaCouSt>3QIREhY+|EPc z3L)_ZSbXLbJvPIz6YTnJT0r?D9sTnY5h1aib2sn3s`nYeSc9t28Famq#Ts4X{JoFc zCBhSzyAia%=OXKMJ*?;sE)ONe`^#|D_;EC#s;V054kZ(NYWjvynt|QPW^+eqlVdNp zS&sWxm>Q=^MafUiNZ+$DqK(s>qK>D1UF`iG1+mk^^k56)+@KHPV>66{T86cARyG29 zBod4|2MIL~>g?zM$cGqq$6L+@hGITJb@GJ9gn7w^0$9>G%ck8fHIy?9S$PYXZ0MV) zbIoQ;qWUNp(`60O^$mpTru#pm&H*I7oQ>@3p}$}%(<*n{|c{xFvB?e#k(^H26BL`NQ&VO0TM zi9R$%xGtGM!rBNOCu~^sxW!czB%-w$Aujv!vi8xG!_x%^_#AK>PK>qY$%v zspccYKxs@tP)2|~qni8yVf&VTMr7_!Dl$y~Y_x@Av2XvK`5jxztH-J+ZdLNSggAT5 zwVDi=a^;1S3mua$sv1SoL`{TSCt!q&0$zJaXd2ukJ)?fWJ_UEFt*Pf5?_28`0W2x#=%<%C zLY8Klqg#yCY1inJ2xSyaj$@#|%lG;gB$+1JI$P1P-rhvW-RyV; zx3nHDVG2C={ZAcU@wV2Ub7hL}2T83%Th=?AmNI)iaS&S2Ggl(|yFYDqD54&z?`_!5 zj|-<{meHm@HS);oYGmR!ef|{XU>)G+%nY4mg!U_XJ|5UcFn>S^Cnj?UtPoJ*0?a+Z zG{VOk#<+DELfBB=9KI5k+NQQ;dL{pwG!f9yF+7nh>BGo^^9X44YU9zsWYihE*qisW zwUQ6xCD5aG1pWi9qFFNZL9v0NQQN(i$c-VyHbgqv;yMNX?Md%xur25oE3Lc`y^*QE z(ld8U#qIZC5RHac}Qv z`inGO=7bLCkd%k#@~p|ur6~Kr#v*+$!6|+-dG}fnra+A%i28NCpNm%CES#>!M%#Zz z-G+r*RnSaUe%~-ECJAD)nx}34e!SX@>v7S$!f9A<;{&B+@@?6=-mV;JZ3Gq+(aWR3 zrq@bfm$Tm;?KCf-x)<74LU*!dhe@dgs=U-uQEv1xt*OH259W(IaHk6Fjo{D^JSgDt7G=r-sJ_wErt3*UcACN=rSllcs%F5__(XN)RIu)v+!j>Y zf4{Vq#eJb2P~lAU*9OFcCO=6ya-J>+`wC=Mow`v=xN5eE)P$(0BCI@ST3y=V7-jYA zd5;F-b&4ou6;#exVMtac=N}^P_TMkvey=ukEJfEeSJS^us^U?#zWHhEIfjC_qE>!Y zy+y{dx3qG?Yxz#8kdJM)=XGUvlJAVQBLRaS1St+E+Cu%V63pgS4m2(0=jSP}+1-}@ zT=pwAh#r%@W_-D~LAzq76(dO_$XBoN9cG&$-ufuF*;HZvQ+^Eah(ss7Rs-%KyMBaW z%Z_QJQmXBrb|33Xt=z22>?Z6{U|v)^s96BcqCWD~u6;Fpk8;$I@T54P+F3G@;VkBT z3c0Bp)<{^$oO1Tl?o7NbmpB&ZJ@)fuq2l;_0R-yJ9k!I6M|m|#92}BD7eDNP^akg4 zykUl>Yd_~HdMp2}pPB22Jk5bm^31-p5x#lIA%-!}#CpXy z&!x#@a}EVWQtk+4CA14brL;&oUc7L&%ydqpBZH-G^qFS18aW4Cs*4~FJLYE!ngF?8 z>Mx7-e|~h9W0|Tghss?Lt_62axF?EUbVnHyIn%zTHWH*q1%(?B!zV7~suov7vS+w3A1|lKYl7Cm4Ly>D7ZC>~+)lIkkGt=Ri1X5>Tj$f_qcS}jL>CuwV%X6>prp+gTVy=(cLq`IpUp*6>C=x2M}=z z7#wrr+GWmWbKGe3U{M4#{4|o^>?S<>;pO49v^w`Fb78r4;K6Uin;f&H3h6X4HLLNi zdHwZhn20d26usjfMD@y9>+WwgFxgO3_swpa4OW?exDiFVjVuijaE~`-*mSG&MZB!t zZkFGjY2%ouhe}%g^wM%%b!gYct=g2AE1xA^W6_)&9WLM}pO5u^N~;!-YPFjc?HX(D zoANwP={-8Mxz}KDY0lA*70}?@ygys#`rhVmQBvJhSx30`>^2#-2x=Qpbo{@3E)doxNfdUCIPTJz~N(R+?RGYwm z7+{2ZuYOi@Q&JiVUsuZkF1E8J=TzVOUmVS!XpVO!;I(nXINRqd_)8EZn`Bo76 zXtOlU2KB?ZftQ2%#Qf?DH`C$+iH-Y@Sss8bjUP(BMFS7? z^A7z<7_}(8(6PRv=q~wH^rxD1DuU8CKZ@@{pGE!k@*FM5Fg&9qZmLYrip0I4_I?L7 zU~hSA&#|}s)1f8%0Pkx~9|mwBwC6ZDzRjr8+16l&0iszdV4Kd|)GYITOaV_cCBZoj zBVURJutKNcS(w6Nr@153wdNPRuIUfqEurW?TCXAYNi*^RVJ935f7XM7NNH7?vuN~O z=52GW^phlhOZAs4-toVv{p2(UNBhZs6e|nhwzrL`SW-bgQ%rJ`v z+Iyaj6#6z1_yqilWC74)4p?=wu+lDP3xl7Q~ zoJ+lD#)4`oJ=V`Bv=ck5_J*qlBBLxPYwoW8PajB`R7RmJ7@UWSA?vR+dmAyG1 zlx_L^{J=hKTejhoC@}#P=tRdyw6kC!9~<+R{8p*&n))?vszQcI{Tq_qDzYj?v`<#& zqTW2BY!F~iocn9Ly+o^X`;#8vNzqDupFr#wY+ewLMHIS{xz93lHEAcn371?dckLF3#aTRW5v4-AWPR-BLV0 zczGOQv--1AT2h=8)_K<6(H_zTPIPq4`hCA!w_6FjN!tqW`f=m%IoAb7_p;|JrI-zj zEi2-AlK(Rn| zWhc4;bY4;_bC>UmH#q)d!xtPZv7-L#Z;^?w-81ArR2BdqbFS4cp6nLY6QEI>VVKw( z=KJb#344agKQZ#_G2z>*pVmdXq}JETiM^cOYW7BP&Lnihl#|8n-ZdsVRpZ?)*6!>p5(2a z(wbKbCa)6?wHpsD{MHM4{`A1jHlR5gYL!rAK3D$-w0H$xAcIy+-aUymeS)0rT3s^m zz1d{?`!T-n)E}bbWGc3T11yHIbUR63ZWHK}-#w z^lTIDwP#M2&8U=7pvc>={5XIwRw2Nu{j>Jb`F+c5LNc1~Pv?^Rq*QL5G7=58_;u=Y6a!U+jemb?;oG6&0g+n!%nRSP{k zyu8bP`A1Y16H@*BB1rPnu1hfqee+HG!V{{dU;O$>Zt(()H}fiU71sXlgVV0~O07=V zmbepiqv=_nNW6I^CcTBB2e%UiFHJP`p^hye-)VwkQZ;Wf&!&sv#O)#YZ07yf<*j_# z9{`ejIq}*ZGO+rRxTQM&>B30kw_JAPUWNfT9PJ9@ab7-O2mhJ&izW50oT^78X@@;y zGq3ic(q&S#H+*T`|97szw`Nq!xXP>z6Rb}7R7eV!DYRq!Zsq2(tetbZ?m+>1GOEHk z+D2wIODd|St_b1em7oYxwkRH4YIn6iRqz0rX{5>jY!usH1VV8&O8r z`jVC&8rn-M6Vik~K7th;Dmh)9CHLiN-kK#iqAD=_Ijl|Y88;}pLY1WrKv~Lg2_Lb` zEr}_3Yu6CMN~auX6A)q$P0Yv?gWY3#m>__VTW5^FyXcQKhykv>5GsGD54#n5csDDc z(ih-JQ#h=6P3#o=r#s6ga22iK6!uXhySUzto~dhEUP-$eA^j$8jCZF>qeEu3iG|ot zV#!sM7)7G|bNTdKSQ=hZis$ zGs0q%dKtk3Y<;3moXW_SHa3OigHLmK9M;aKNqmMOqaJoS>&dAt|5fRUagk?9Nm#P? z`nu32S*xCCgC68ye30zoG5&hM^~3B@i)S%nN_n~VnT;o~+(71uswB4>%nC=V!Qffb z6H{~(76rii=KW@0+XF|%>7pRtdFHMrXW-yO)%+i+P{Eb{^fS=U@4X2Fpdm3Ajt}-} zII=j&t0Xzbd5J`SU~!EtKIB>=8SOFp%;#I)^}6f=5cnLvi)0r+Sr`}mmif8V_qBM> zQX{d`w1BE)v6|kK68iU*oRkDkND>qNVnQ`%*Zq4HthACMb`OjSAmTIcZ+t5`ns#gg ziEUaaNH`o9*%b3DR=)8(Sh{f1xG!!oKX4h=M_8%XXg5v4pBe5T(yvU+e~y-J%(k>c zvt_57^cC||rZ;R@*aYiHo}^S8Sbub};g5-qSlf5L`?lHFf1L4Yip`%GSv%|gw?;NI zS50j#f)rFl-sciX!Ql_k%fd17C7Fc>pT0;9^oDr zl-T|vOVUHii}#k&N~LzMjUQ9K(resA9-OGNZn#QU%P;0S+>N`N&j}Ap^hnR~dOC(M zFA1VesWK@$+Huoh4kP#SL;L|)8vX0FP?eU6iL7lbG*HIJn;Dl8a#w+4f{M2KhhCl3 z&Xmjl>YNN}MVa?)L0gK*sV~_Apq_ybGT%ziKmHlmpCh7U;;UiSRPR>>VKWet(F#EC zJ+NVdI2oIH)caLnquc72(^<85Uj$y(mONjIl)}+FEKTtfov9X(?22R8n0D%DN0!psZZV0IPHlWhGr}Fy9-dGaCq+~m;a#w_97n#B zfb7WhU(_;--YW<#*iyiQNj{BsR1X@s;yCF~-?;i!G|Ch2nvA^8a2H(yj%(j6uf`BL z(sagl$PC0nTKo2{n^2@X926PZjkhZ52to@PFPVhOYChY)-@a-tZ&@dawgMlkFi&*l88A4VOjO`8XMLA+_6*F<8cU%G- z6K;&=glo!n&^`qSQPpJXyJajg^g~7}MjA%46a6iTsQmej+IyO$=ECE!z@mD`E+J~8 zB*j3A!R{<`zjsh+DIh;D+UybS9Y^s1NttfOw3XG2-k>i!tUb3qc{5AJj!FGH><{d0 zIyfu4L$I4jP#BI;04Hd*7z(D>IP6?ozGE6!=*Xp5P)lQEuO zcvGL{kKJd>d7VY<0HuA7OF_plk>*cXUCt;hXD^*+)IR=HDl5jk?vRY|mfyUXiV9!3 z%A6nT{-K`wE8*|qLr;x_5`pAtuR~MEInNdEeN0_{p=J<*3_Vq?C)t+x+e9sGT^_d8 zl=5d{%v*Rmu<3BYMNK02T-!b))Q&vb&-+Th_^w8KN#;hjpi4;YODu=R-{)`pUlTJH z?QKA+sHfm%FEo?ct?X%IyPlmp$ap0-ie7(U#03wYrppa;UQnu5c^R!+Cp8!d7mXp> zax#5JG^B}RW{kgee4A{D3}z}mF~m{%=&>uyzi}rC-4!RyZEDHhMUy5hMZuM&no@vL zGvBtGzI6K~)PurS#YSqPEI_u{^pgVOc(48IzPA>)EwP_lxly5iRudSi&d)?IHRW)O zVe#5m5Y{*Sz_A-|C|t3gY))9;D~2 zTQ6XRYB1D%^!a4a(Yw&@cw4)VAuDey3kRI)Cu@~-X_)(~jZR8gs^)NnkmAUSHfU`sCy=xi ztoUn_I%1URUr5_%ml04VQ2D&lRQlA-Hlj_W`NuPJx%~A_fFYnJ8%uTBNCZ}4m^&+< zxtk{DSAS1DL?uq7rtP~B$}I6{PYup-Xq}Ga0fR0JC5~ilLiNpjaI9my7J#VP|3&GZ z7&MT-rAT?8sP5K%J^Py5WI?k>Gx|->{bNIQ)~l^8=-KI68>tyscSxBylU((f%QHxI z@!q{Am0njaHD^^Q?RzhL3A)8y0*^`Y%x>kHjW}}Fi|FBX-r+Y-iFSBXryle)4Bw63 zx#~GROYwxKEE;ZAr+zu(d(}YT-nQCgU*eVIE>5ve+Fo+coI_Jp!rGA2#wv9B`05i@ z=O$dq8vMhmz)klfv+w?lXO`#8pjfJsZOe+6Qq5lfSojnkK^K`H8 zU(T@m8HQ_Ms+gb?a?EN*lvDN;;;YE;{&(zcf$242Bl;Q=E(Fq)aGif!L_p`W@A|Aw zxUf#ZVSg=J!z4rgYR!Hd0}+i<&UCA~k@%2G4y~?9p9l@jz+gkahd{hD9R4_sITSE@ zo%e9ui}Bdd?H>7F*+PCh^8(0gJX3h|*rwUzMX~NsV0L{AbG&=7IC}m88T9t=l56<+ zOIYt&J;E0z??buRoa)bZL_nil;{_b-^Ac$cZ$+Cqd}4Ty#&+8lFNuzSbw9B6bQe$y zN&;y^KFjR1aJqJo=nrZdII;;sLp~;S0Df|rXsMcrjjAaGQVT#^9t`a3g;ZZ;I1aD2 zna;fC>>8>sZywu4o#8002Lxk^2&>L%*HHK3Bj;2n+mndNJI~~Hm|EYrN8DeYSmUz1 zq4P2%XF}?yujZl>OLhW%zRls%V%fi4tG5zglrl_Pm5iqm`qpmx*+LpX%g_qNTa(X? zX!hL%d z-Au$D8~NtaCOwcjpDX(D%K|Es)V)Y{-%fSq-nHZmCYUY40~ty zR42n1+?KoJZx{b6F5a`oC02xuk9wnt-!(+hXO0O}zKHn3BWcbBY=2cuL&reZT@?f!EnUS%OCB^al^fJ)~eTVSa^*7xbm|{97T{j~iQ@DUk_PoaU69PCg_|n|6Xl zJ{DV2q@lN&V>yrRMsS1%Sz7J93NU=wyWjs$8Oiwh7 zGwhv^7=(^?9w)VxvXcgQ@2%X48cM>$pvS)>VLU&OUG%ec;O`EIJuGvaH@jPZ+=B4D zPx{=>Ru{7yYxZYJx^U#6ysb$t`+fo$^mPc#4ZSArMEaop3BB&el>W_E|51kgQ*IEI z;-pG?|DEzj%fB6OpoiSK`NN!){NxX>I@9b(p?p3M3g4P)&}Fk3y3z#erYTOk(6*3| zb4Xvtbq;txDzpY1`P}{QbpOAFB>#Ol|J8mlL=gIjrllH=XK`lS{GWsGK(|4F zkH?JRi92sD%!QV>!fV%fRLJ+5rvt254kg2LbZa+o;u`Mr*ms?h%=YrW!Ry-jkiwcpIqfMbNbRj3^%@fQ1H3~bG~-G2hLCoU~m_O!*S{t4k5blvqO)= z9EXs`RTLzl-PwVcgT-;asBs8qG?diy91lofKjt)2rc-7hA(tfxFmr?Hi$lA>MZ(ZX444s>;l>)hQr_Q%*@PmSd$}>38_@d1=4?UyC{i czhJ3-6EkB9r^7gK@>V=GWvy3LidGT-3mCQ^bN~PV diff --git a/proposals/filesystem/design/application-abi.md b/proposals/filesystem/design/application-abi.md deleted file mode 100644 index 0ef259a51..000000000 --- a/proposals/filesystem/design/application-abi.md +++ /dev/null @@ -1,60 +0,0 @@ -WASI Application ABI -==================== - -In addition to the APIs defined by the various WASI modules there -are also certain expectations that the WASI runtime places on an application -that wishes to be portable across WASI implementations. - -This document describes how a conforming WASI application is expected to behave -in terms of lifecycle (startup, shutdown, etc) and any exports it is expected to -include. - -Current Unstable ABI --------------------- - -There are two kinds of modules: - - - A *command* exports a function named `_start`, with no arguments and no return - values. - - Command instances may assume that they will be called from the environment - at most once. Command instances may assume that none of their exports are - accessed outside the duraction of that call. - - - All other modules are *reactors*. A reactor may export a function named - `_initialize`, with no arguments and no return values. - - If an `_initialize` export is present, reactor instances may assume that it - will be called by the environment at most once, and that none of their - other exports are accessed before that call. - - After being instantiated, and after any `_initialize` function is called, - a reactor instance remains live, and its exports may be accessed. - -These kinds are mutually exclusive; implementations should report an error if -asked to instantiate a module containing exports which declare it to be of -multiple kinds. - -Regardless of the kind, all modules accessing WASI APIs also export a linear -memory with the name `memory`. Data pointers in WASI API calls are relative to -this memory's index space. - -Regardless of the kind, all modules accessing WASI APIs also export a table -with the name `__indirect_function_table`. Function pointers in WASI API calls -are relative to this table's index space. - -Environments shall not access exports named `__heap_base` or `__data_end`. -Toolchains are encouraged to avoid providing these exports. - -In the future, as the underlying WebAssembly platform offers more features, we -we hope to eliminate the requirement to export all of linear memory or all of -the indirect function table. - -Planned Stable ABI ------------------- - -There is ongoing discussion about what the stable ABI might look like: - -- https://github.com/WebAssembly/WASI/issues/13 -- https://github.com/WebAssembly/WASI/issues/19 -- https://github.com/WebAssembly/WASI/issues/24 diff --git a/proposals/filesystem/design/optional-imports.md b/proposals/filesystem/design/optional-imports.md deleted file mode 100644 index 543599a10..000000000 --- a/proposals/filesystem/design/optional-imports.md +++ /dev/null @@ -1,108 +0,0 @@ -Optional Imports -================ - -It can be useful for WASI programs to optionally depend on certain functions in a -WASI API. For example, if a WASI API evolves to include a new function a -program might want to continue to run on older systems that don't yet support -the new function. In this case a optional import mechanism allows the program -to run on older systems and detect the presence of the function at runtime. -Another use case is an API that is not applicable on certain embedding. In this -case optionals imports would allow program to continue to run in such an -embedding, albeit with reduced or modified behavior. - -*Note*: In the ELF specification this type of import is known as *weak*. -We chose *optional* because the term weak is already used other context in -WebAssembly and JavaScript, specifically in JavaScript [weakrefs] proposal where -it relates to garbage collection. - -WebAssembly itself does not currently provide a mechanism for optional imports. -There is some discussion of adding it to the [spec][spec], and WASI would likely -use such a feature if/when it is added. In the absence of first class optional -imports this document describes the mechanism used by WASI to specify optional -imports using a custom section. Currently this is only specified for function -imports. - -Declaring an optional import ----------------------------- - -Optional function imports are implemented using two imports for each function. -The first being the optional function itself and the second being an i32 global -which indicates if the function is present at runtime. We call this addition -import the guard. - -For example, if a module called `wasi:fs` added a new `statvfs` function to its -interface a program could optionally import this new function in the following -way: - -```wasm -(func $statvfs (import "wasi:fs" "statvfs.optional")) -(global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) -``` - -These two imports would also need to be added to the `import.optional` custom -section (See below). - -On older systems that don't support the new function, `$statvfs_is_present` -would be set to 0 and calling `$statvfs` would result in a trap. - -On systems that do support the new function, `$statvfs_is_present` is set to -1 and calling `$statvfs` would work as expected. - -Using an optional function import ---------------------------------- - -In order to use the above options function its presence should first be tested -for. In C code this would look something like this: - -```c -if (__wasm_is_present(wasm_fs.statvfs)) { - wasm_fs.statvfs(...) -} -``` - -At the WebAssembly level it might look like this: - -```wasm -global.get $statvfs_is_present -if i32 - call $statvfs -end -``` - -Custom section --------------- - -A custom section is used to specify which imports are optional, and for each -optional import the name of the corresponding guard (the global import which is -used to signal its presence). For each module that contains optional imports -the module name is specified once followed by a list of its optional imports -along with their corresponding guards. - -The name of this custom section is `import.optional` and its contents are as -follows: - -| Field | Type | Description | -| ----------------| ---------------------- | -------------------------------- | -| count | `varuint32` | count of mod_optionals to follow | -| mod_optionals | `optional_import_list*`| sequence if optional_import_list | - -Each `optional_import_list` has the following content: - -| Field | Type | Description | -| --------------| ------------------- | ------------------------------------- | -| mod_name_len | `varuint32` | the length of `mod_name_data` in bytes| -| mod_name_data | `bytes` | UTF-8 encoding of the module name | -| count | `varuint32` | count of `opt_import` to follow | -| opt_import | `opt_import*` | sequence of `opt_import` | - -Each `opt_import` has the following content: - -| Field | Type | Description | -| --------------- | ---------------- | --------------------------------------- | -| name_len | `varuint32` | the length of `name_data` in bytes | -| name_data | `bytes` | UTF-8 encoding of the import name | -| guard_name_len | `varuint32` | the length of `guard_name_data` in bytes| -| guard_name_data | `bytes` | UTF-8 encoding of the import name | - -[weakrefs]: https://github.com/tc39/proposal-weakrefs -[spec]: https://github.com/WebAssembly/design/issues/1281 diff --git a/proposals/filesystem/docs/DesignPrinciples.md b/proposals/filesystem/docs/DesignPrinciples.md deleted file mode 100644 index df82c8692..000000000 --- a/proposals/filesystem/docs/DesignPrinciples.md +++ /dev/null @@ -1,291 +0,0 @@ -# WASI Design Principles - -## Capability-based security - -WASI is built using capability-based security principles. Access to -external resources is always represented by *handles*, which are special -values that are *unforgeable*, meaning there's no way to coerce an -arbitrary integer or other type of value into a handle. WASI is also -aiming to have no *ambient authorities*, meaning that there should -be no way to request a handle purely by providing a string or other -user-controlled identifier providing the name of a resource. With these -two properties, the only ways to obtain access to resources are to be -explicitly given handles, or to perform operations on handles which -return new handles. - -Note that this is a different sense of "capability" than [Linux -capabilities](http://man7.org/linux/man-pages/man7/capabilities.7.html) -or the withdrawn [POSIX -capabilities](https://archive.org/details/posix_1003.1e-990310), which -are per-process rather than per-resource. - -The simplest representation of handles are values of [reference -type](https://github.com/WebAssembly/reference-types). References in -wasm are inherently unforgeable, so they can represent handles directly. - -Some programming languages operate primarily within linear memory, -such as C, C++, and Rust, and there currently is no easy way for -these languages to use references in normal code. And even if it does -become possible, it's likely that source code will still require -annotations to fully opt into references, so it won't always be -feasible to use. For these languages, references are stored in a -[table](https://webassembly.github.io/spec/core/bikeshed/index.html#tables%E2%91%A0) -called a *c-list*. Integer indices into the table then identify -resources, which can be easily passed around or stored in memory. In -some contexts, these indices are called *file descriptors* since they're -similar to what POSIX uses that term for. There are even some tools, -such as wasm-bindgen, which make this fairly easy. (Internally, tools -and engines don't always use actual WebAssembly tables to do this, -however those are implementation details. Conceptually, they work as if -they had tables.) - -Integer indices are themselves forgeable, however a program can only -access handles within the c-list it has access to, so isolation can still -be achieved, even between libraries which internally use integer indices, -by witholding access to each library's c-list to the other libraries. -Instances can be given access to some c-lists and not others, or even -no c-lists at all, so it's still possible to establish isolation between -instances. - -Witx-specified APIs use a special `handle` keyword to mark parameters -and return values which are handles. In the short term, these are -lowered to integer indices, with an implied table, so that the APIs -can be easily used from C and similar languages today. Once [interface -types](https://github.com/WebAssembly/interface-types) and [type -imports](https://github.com/WebAssembly/proposal-type-imports) are -ready, we expect to make use of them to provide APIs which can be used -either from languages using references or from languages using integer -indices, with tables being used and managed automatically. - -## WASI's Scope - -WASI started out with a very POSIX-like API, however WASI will grow to -include many APIs that are outside of the scope of POSIX. WASI is a -forum for cooperatively designing APIs, along with a W3C CG Subgroup for -eventually standardizing them. - -For example, WASI may include high-level network APIs, such as APIs for -HTTP. This is outside the scope of POSIX, and while some WebAssembly -engines are very interested in implementing it natively, others will -find it too complex and high-level. But one of the great things about -WebAssembly is that there's no syscall instruction, so "syscalls" -in WebAssembly are just calls to imported functions, which could be -native functions provided by the runtime, or could be other WebAssembly -modules. We expect to leverage this capability to provide polyfill -implementations of things like high-level network APIs on top of -low-level APIs, such as a raw socket API, so that engines which wish to -keep things simple and just implement the low-level socket APIs can do -so. - -WASI also aims to include domain-specific APIs, such as -database, blockchain, or specialized APIs for embedded -systems. Another key building block for WASI is [optional -imports](https://github.com/WebAssembly/WASI/blob/main/design/optional-imports.md), -which give applications the ability to dynamically test for the -availability of APIs. - -## Relationship to POSIX - -POSIX specifies a C API rather than an actual system call ABI, with -the expectation that implementation details will differ at the system -call level. In the same way, the primary vehicle for WASI's POSIX -compatibility is libraries such as WASI libc, rather than the WASI API -itself. WASI libc provides a wide range of POSIX-compatible APIs. - -In the parts of WASI which do correspond to POSIX functionality, WASI -follows POSIX when it doesn't conflict with WASI's other goals. And, -we consult POSIX even when we aren't strictly following it. POSIX is -valuable for several reasons: POSIX represents a large body of lessons -learned about systems programming, portability, and robustness. POSIX -is available on many existing hosts that we want to port WASI to. And, -there's a large amount of application code that we want to port to WASI -that uses POSIX-style interfaces. - -All this said, maximal POSIX conformance is not WASI's primary goal. -Some reasons include: - - - `fork` -- It's not that we can't make `fork` work -- we can, it's -that `fork` carries with it the assumption of copy-on-write memory -optimizations which won't be feasible in many environments where we -want to run WASI, such as nano-processes. There may eventually be -compatibility layers that provide `fork` to help people port POSIX -code to WASI, however there's a difference between providing `fork` as -an optional compatibility layer and having it as a cornerstone of an -ecosystem as it is in POSIX. - - And when we take `fork` out of the focus, it changes the way we think -about a lot of other things, such as `execve`, `dup`, `fcntl`-style file -locking, and even processes. - - - Users and Groups -- POSIX's Users and Groups subsystem are -notoriously inflexible, to the point where much of the computing world -has moved to using containers and VMs and other forms of single-user -environments because traditional multi-user OS functionality doesn't do -what's needed. - - And, when running untrusted code, it isn't desirable to run it as a -user's normal identity, because it shouldn't inherit all of the rights a -user has, but it also doesn't help to run it as user "nobody", as it's -still useful to grant it some rights and restrict it from others. - - And, we are aiming for portability to OS's which don't have -POSIX-style users and groups, and systems which don't have OS's at all. - - - Asynchronous signals and handlers -- The core WebAssembly semantics -don't support these, which would need to change before WASI could -consider supporting them, and there are currently no proposals for doing -so. In POSIX, some interfaces are designed with the assumption that -signals like `SIGPIPE`, `SIGALRM`, `SIGCHLD`, `SIGIO` and others exist -and can cover certain situations, so in the absence of these signals, -those interfaces won't always make sense. - - - Shared filesystem views - One of the unique capabilities WebAssembly -brings to the table is the possibility of shared-nothing linking between -applications and libraries. Shared-nothing means that all communication -is via explicit calls, and the libraries don't share an address space -or any other implicit shared state. But if we run both sides within -the same filesystem view, that would give them a large body of shared -state. Union mounts, mandatory access control systems, user namespaces, -and other techniques can help, but often require complex configuration, -heavy-weight boundaries, and sometimes even admin privileges to set up. - -This has wide-ranging implications. Much of POSIX is oriented around -passing around strings, whether through command-line arguments, -environment variables, or paths embedded in files, with the assumption -that there's a shared filesystem view between components. As we said -above, we're de-emphasizing strings, which dovetails with de-emphasizing -shared filesystem views. Instead of having shared state and passing -around values which identify things within the shared state, WASI -prefers to share as little as possible, and use handles which represent -the things which need to be shared. - -Compatibility with existing host environments and applications is -important, and we have put a lot of work into WASI libc to provide POSIX -compatibility and support existing applications. There's a lot more work -that can be done, and a lot more we can do to improve compatibility and -user convenience. We're continuing to make progress -- and users are -encouraged to [file bugs](https://github.com/WebAssembly/WASI/issues) -when they find things that don't work or are awkward. This approach -supports existing applications, while also supporting applications and -libraries willing to opt in to enable stronger and more fine-grained -security properties than are possible in regular POSIX. - -For example, a typical POSIX-style API might include a function that -accepts a file name to open. That requires the implementation to -have a filesystem view, and to have appropriate permissions within -that filesystem view. WASI APIs typically prefer to instead have a -function which accepts a handle for an already-open file. That way, the -implementation doesn't need a filesystem view, or permissions within -the filesystem. It doesn't even need to care whether there even is a -filesystem. When needed, compatibility with POSIX-style APIs is then -provided as a thin layer on top implementing a simple name-to-handle -mapping. - -We recognize that this approach has trade-offs. It often does take more -work to design and implement the compatibility layers needed to support -existing applications than if we just made WASI always expose -POSIX-style APIs directly. It will take more work to port existing -libraries to work with shared-nothing linking. And, even when we do have -compatibility mechanisms, they aren't always the most locally optimal -ones. The compatibility layer overhead is usually quite modest, but it -is present. - -However, libraries built to use shared-nothing linking can be used in -more circumstances, because you don't have to have the trust implied by -a shared filesystem view, or the complexity of configuring filesystem -rules for each library. With a better story for libraries and tools to -work together in cooperation with the sandbox, we can build a stronger -ecosystem which makes up for the downsides in the long run. - -## Relationship to the Web - -It is possible to run WASI code on the Web with the help of polyfills, -however WASI isn't limited to APIs which run well or are easy or -efficient to polyfill on the Web. - -That said, where other considerations don't interfere, WASI should use -existing Web standards and work with Web standardization efforts rather -than gratuitously inventing its own versions of them and/or duplicating -efforts. - -When using Web standards, WASI APIs should be careful to avoid depending -on JavaScript in the engine in APIs where it isn't essential. - -## Use WebAssembly standards and proposals - -WASI should align with and build on WebAssembly standards and proposals -where applicable. - -For example, WASI seeks to align with and build on [interface -types](https://github.com/WebAssembly/interface-types), [multiple -return values](https://github.com/WebAssembly/multi-value/), [reference -types](https://github.com/WebAssembly/reference-types), [type -imports](https://github.com/WebAssembly/proposal-type-imports), and -more. As of this writing, some of these are early-stage proposals, so -we're not actually depending on them yet, however we are carefully -aligning with them so that we'll be ready when they are. - -As another example, WASI's -[witx](https://github.com/WebAssembly/WASI/blob/main/docs/witx.md) -file format is designed to be a -straightforward superset of the [module linking -proposal](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md)'s -.wit format and the [annotations -proposal](https://github.com/WebAssembly/annotations/)'s annotation -syntax. - -## Interposition - -Interposition in the context of WASI interfaces is the ability for a -Webassembly instance to implement a given WASI interface, and for a -consumer WebAssembly instance to be able to use this implementation -transparently. This can be used to adapt or attenuate the functionality -of a WASI API without changing the code using it. - -In WASI, we envision interposition will primarily be configured -through the mechanisms in the module linking' [link-time virtualization -](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md#link-time-virtualization). -Imports are resolved when a module is instantiated, which may happen -during the runtime of a larger logical application, so we can support -interposition of WASI APIs without defining them in terms of explicit -dynamic dispatch mechanisms. - -Interposition is sometimes referred to as "virtualization", however we -use "interposition" here because the word "virtualization" has several -related meanings. - -## Compatibility - -Compatibility with existing applications and libraries, as well as -existing host platforms, is important, but will sometimes be in conflict -with overall API cleanliness, safety, performance, or portability. -Where practical, WASI seeks to keep the WASI API itself free of -compatibility concerns, and provides compatibility through libraries, -such as WASI libc, and tools. This way, applications which don't require -compatibility for compatibility' sake aren't burdened by it. - -## Portability - -Portability is important to WASI, however the meaning of portability -will be specific to each API. - -WASI's modular nature means that engines don't need to implement every -API in WASI, so we don't need to exclude APIs just because some host -environments can't implement them. We prefer APIs which can run across -a wide variety of engines when feasible, but we'll ultimately decide -whether something is "portable enough" on an API-by-API basis. - -## Strings - -WASI in general de-emphasizes strings in areas where typed interfaces -can be sufficient, and especially when the strings would be serving as -identifiers in a global shared resource pool. - -Where strings are passed through APIs, WASI will use [interface -types](https://github.com/WebAssembly/interface-types) to manage the -strings. - -Where string encodings are exposed, WASI prefers to use UTF-8 -encodings for strings, and to provide explicit length values -rather than NUL-terminated strings, (as [WebAssembly itself -does](https://webassembly.github.io/spec/core/bikeshed/index.html#binary-utf8)). diff --git a/proposals/filesystem/docs/HighLevelGoals.md b/proposals/filesystem/docs/HighLevelGoals.md deleted file mode 100644 index e871cfd08..000000000 --- a/proposals/filesystem/docs/HighLevelGoals.md +++ /dev/null @@ -1,25 +0,0 @@ -# WASI High-Level Goals - -(In the spirit of [WebAssembly's High-Level Goals](https://github.com/WebAssembly/design/blob/master/HighLevelGoals.md).) - -1. Define a portable, modular, runtime-independent, and WebAssembly-native API - to serve as a system interface which can be used by WebAssembly code to - interact with the outside world, that preserves the essential sandboxed - nature of WebAssembly through a [Capability-based] API design. -2. Specify and implement incrementally: - * Start with a Minimum Viable Product (MVP) for the standard, covering - basic API versioning, feature detection, and namespacing. - * Then add additional features, prioritized by feedback and experience. -3. Supplement API designs with documentation and tests, and, when feasible, - reference implementations which can be shared between wasm engines. -4. Make a great platform: - * Work with WebAssembly tool and library authors to help them provide - WASI support for their users. - * When being WebAssembly-native means the platform isn't directly - compatible with existing applications written for other platforms, - build tools and libraries to provide compatibility. - * Allow the overall API to evolve over time; to make changes to API - modules that have been standardized, build implementations of them - using libraries on top of new API modules to provide compatibility. - -[Capability-based]: https://en.wikipedia.org/wiki/Capability-based_security diff --git a/proposals/filesystem/docs/Process.md b/proposals/filesystem/docs/Process.md deleted file mode 100644 index 3b4affc3c..000000000 --- a/proposals/filesystem/docs/Process.md +++ /dev/null @@ -1,37 +0,0 @@ -# WASI Standardization Process - -WASI follows the [WebAssembly CG Phases process], with the following adaptations: - - - Entry into Stage 2 requires [witx] specifications. - - - Starting in Stage 2, proposals may follow WASI's [ephemeral/snapshot/old] process - to provide a balance between the need for stability so that toolchains and engines - can sync up, and the need for evolution. - - - The Phase 4's entry requirements for "Two or more Web VMs implement the feature", - "At least one toolchain implements the feature", and "The formalization and the - reference interpreter are usually updated (though these two can be done as part - of step 3 at the Working Group chair's discretion)." are waived. - - In their place, as an additional entry requirement into Phase 2, champion(s) must - include a set of entry criteria into Phase 4 in their proposal, which the Subgroup - will vote on as part of Phase 2 approval. - - Phase 4 criteria will vary depending on the API and its expected use cases, - but may include things like multiple independent production implementations, - implementations on multiple host platforms, polyfill implementations, and - bindings in toolchains and libraries. Note that, portability requirements may - vary between proposals, as not all features will necessarily make sense in all - host environments. - - - The specific process in Phases 4 and 5 will be determined when we have a - proposal ready for them. - - - Requirements around the reference interpreter don't apply. - - - WASI proposals don't require formal notation. Formal notation may be used in the - documentation of a feature, but it isn't expected to be practical for all APIs. - -[WebAssembly CG Phases process]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md -[witx]: https://github.com/WebAssembly/WASI/blob/master/docs/witx.md -[ephemeral/snapshot/old process]: https://github.com/WebAssembly/WASI/blob/master/phases/README.md diff --git a/proposals/filesystem/docs/Proposals.md b/proposals/filesystem/docs/Proposals.md deleted file mode 100644 index 31c565b2e..000000000 --- a/proposals/filesystem/docs/Proposals.md +++ /dev/null @@ -1,64 +0,0 @@ -# WASI proposals - -This page is under construction. The intent is to follow the CG's -[proposals page], but adapted for [WASI]. Some of the proposals predate our -adoption of this process and so don't fit exactly into the defined phases, -however our intention is to align them going forward. - -[WASI]: https://github.com/WebAssembly/WASI -[proposals page]: https://github.com/WebAssembly/proposals/blob/master/README.md - -## Active proposals - -Proposals follow [this process document](https://github.com/WebAssembly/WASI/blob/main/docs/Process.md). - -### Phase 4 - Standardize the Feature (WG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | - -### Phase 3 - Implementation Phase (CG + WG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | - -### Phase 2 - Proposed Spec Text Available (CG + WG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | -| [I/O][wasi-io] | Dan Gohman | -| [Filesystem][wasi-filesystem] | Dan Gohman | -| ["Classic" Command-Line][wasi-classic-command] | Dan Gohman | -| [Clocks][wasi-clocks] | Dan Gohman | -| [Random][wasi-random] | Dan Gohman | -| [Handle Index][wasi-handle-index] | Dan Gohman | -| [Poll][wasi-poll] | Dan Gohman | -| [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | - -### Phase 1 - Feature Proposal (CG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | -| [Crypto][wasi-crypto] | Frank Denis and Daiki Ueno | - -### Phase 0 - Pre-Proposal (CG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | -| [proxy-wasm][wasi-proxy-wasm] | Piotr Sikora | - -### Contributing new proposals - -Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. - -[wasi-clocks]: https://github.com/WebAssembly/wasi-clocks -[wasi-classic-command]: https://github.com/WebAssembly/wasi-classic-command -[wasi-crypto]: https://github.com/WebAssembly/wasi-crypto -[wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem -[wasi-io]: https://github.com/WebAssembly/wasi-io -[wasi-misc]: https://github.com/WebAssembly/wasi-misc -[wasi-nn]: https://github.com/WebAssembly/wasi-nn -[wasi-proxy-wasm]: https://github.com/proxy-wasm/spec -[wasi-random]: https://github.com/WebAssembly/wasi-random -[wasi-handle-index]: https://github.com/WebAssembly/wasi-handle-index -[wasi-poll]: https://github.com/WebAssembly/wasi-poll diff --git a/proposals/filesystem/docs/README.md b/proposals/filesystem/docs/README.md deleted file mode 100644 index bb6d81b25..000000000 --- a/proposals/filesystem/docs/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Documentation - -WASI documentation includes: - - [Overview](WASI-overview.md): provides an introduction to WASI and its history - - [Goals](HighLevelGoals.md): a succinct list of WASI's design goals - - [Design Principles](DesignPrinciples.md): discusses details on the principles of capability-based security, scope, - POSIX/Web, etc. - - [WITX](witx.md): an introduction to the WITX specification language - - [Process](Process.md): describes how to move a WASI proposal in to the specification - - [Proposals](Proposals.md): lists the current WASI proposals by phase - -Additionally, here are some links that may be helpful in understanding WASI: - - The blog post introducing WASI: [Standardizing WASI: A system interface to run WebAssembly outside the web](https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/) - - The [wasi.dev](https://wasi.dev) web site includes links to more information about WASI, including how to get started using it - - This repository's [issue tracker](https://github.com/WebAssembly/WASI/issues) \ No newline at end of file diff --git a/proposals/filesystem/docs/WASI-overview.md b/proposals/filesystem/docs/WASI-overview.md deleted file mode 100644 index faabc2eff..000000000 --- a/proposals/filesystem/docs/WASI-overview.md +++ /dev/null @@ -1,147 +0,0 @@ -# WASI: WebAssembly System Interface - -WebAssembly System Interface, or WASI, is a family of APIs for WebAssembly -being designed and standardized through the WASI Subgroup of the W3C -WebAssembly Commmunity Group. Initially, the focus is on system-oriented APIs, -covering files, networking, and a few other things. Additional domains are -expected to be added in the future. - -WebAssembly is designed to run well on the Web, however it's -[not limited to the Web](https://github.com/WebAssembly/design/blob/master/NonWeb.md). -The core WebAssembly language is independent of its surrounding -environment, and WebAssembly interacts with the outside world -exclusively through APIs. On the Web, it naturally uses the -existing Web APIs provided by browsers. - -WASI is an effort to provide general-purpose APIs for supporting -non-Web use cases. The focus is on designing clean and portable APIs which -can be implemented on multiple platforms by multiple engines, and which -don't depend on browser functionality (although they still can run in -browsers; see below). - -## Capability-Oriented - -WASI's core design follows -[CloudABI](https://cloudabi.org/)'s -(and in turn -[Capsicum](https://www.cl.cam.ac.uk/research/security/capsicum/))'s concept of -[capability-based security](https://en.wikipedia.org/wiki/Capability-based_security), -which fits well into WebAssembly's sandbox model. Files, -directories, network sockets, and other resources are identified -by UNIX-like file descriptors, which are indices into external -tables whose elements represent capabilities. Similar to how core -WebAssembly provides no ability to access the outside world without -calling imported functions, WASI APIs provide no ability to access -the outside world without an associated capability. - -For example, instead of a typical -[open](http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html) -system call, WASI provides an -[openat](https://linux.die.net/man/2/openat)-like -system call, requiring the calling process to have a file -descriptor for a directory that contains the file, representing the -capability to open files within that directory. (These ideas are -common in capability-based systems.) - -However, the WASI libc implementation still does provide an -implementation of open, by taking the approach of -[libpreopen](https://github.com/musec/libpreopen). -Programs may be granted capabilities for directories on launch, and -the library maintains a mapping from their filesystem path to the -file descriptor indices representing the associated capabilities. -When a program calls open, they look up the file name in the map, -and automatically supply the appropriate directory capability. It -also means WASI doesn't require the use of CloudABI's `program_main` -construct. This eases porting of existing applications without -compromising the underlying capability model. See the diagram below -for how libpreopen fits into the overall software architecture. - -WASI also automatically provides file descriptors for standard -input and output, and WASI libc provides a normal `printf`. In -general, WASI is aiming to support a fairly full-featured libc -implementation, with the current implementation work being based on -[musl](http://www.musl-libc.org/). - -## Portable System Interface for WebAssembly - -WASI is being designed from the ground up for WebAssembly, with -sandboxing, portability, and API tidiness in mind, making natural -use of WebAssembly features such as i64, import functions with -descriptive names and typed arguments, and aiming to avoid being -tied to a particular implementation. - -We often call functions in these APIs "syscalls", because they -serve an analogous purpose to system calls in native executables. -However, they're just functions that are provided by the -surrounding environment that can do I/O on behalf of the program. - -WASI is starting with a basic POSIX-like set of syscall functions, -though adapted to suit the needs of WebAssembly, such as in -excluding functions such as fork and exec which aren't easily -implementable in some of the places people want to run WebAssembly, -and such as in adopting a capabilities-oriented design. - -And, as WebAssembly grows support for -[host bindings](https://github.com/webassembly/host-bindings) -and related features, capabilities can evolve to being represented -as opaque, unforgeable -[reference typed values](https://github.com/WebAssembly/reference-types), -which can allow for finer-grained control over capabilities, and -make the API more accessible beyond the C-like languages that -POSIX-style APIs are typically aimed at. - -## WASI Software Architecture - -To facilitate use of the WASI API, a libc -implementation called WASI libc is being developed, which presents -a relatively normal musl-based libc interface, implemented on top -of a libpreopen-like layer and a system call wrapper layer (derived -from the "bottom half" of -[cloudlibc](https://github.com/NuxiNL/cloudlibc)). -The system call wrapper layer makes calls to the actual WASI -implementation, which may map these calls to whatever the -surrounding environment provides, whether it's native OS resources, -JS runtime resources, or something else entirely. - -[This libc is part of a "sysroot"](https://github.com/CraneStation/wasi-sysroot), -which is a directory containing compiled libraries and C/C++ header -files providing standard library and related facilities laid out in -a standard way to allow compilers to use it directly. - -With the [LLVM 8.0](http://llvm.org/) -release, the WebAssembly backend is now officially stable, but LLVM -itself doesn't provide a libc - a standard C library, which you -need to build anything with clang. This is what the WASI-enabled -sysroot provides, so the combination of clang in LLVM 8.0 and the -new WASI-enabled sysroot provides usable Rust and C compilation -environments that can produce executable wasm programs. - -![WASI software architecture diagram](wasi-software-architecture.png "WASI software architecture diagram") - -## Future Evolution - -The first version of WASI is relatively simple, small, and -POSIX-like in order to make it easy for implementers to prototype -it and port existing code to it, making it a good way to start -building momentum and allow us to start getting feedback based on -experience. - -Future versions will change based on experience -and feedback with the first version, and add features to address -new use cases. They may also see significant architectural -changes. Because all of the APIs are accessed through regular -WebAssembly imports, APIs can be implemented either by wasm -runtimes directly or by other WebAssembly modules. So if WASI APIs -change significantly, the old APIs can be implemented as a library -on top of the new APIs. - -## Can WASI apps run on the Web? - -While this isn't the initial focus, it's possible to implement WASI -APIs from JavaScript, since they're just regular WebAssembly imports, -so it's possible to run WASI modules on the Web. - -And in the future, it's possible that -[builtin modules](https://github.com/tc39/ecma262/issues/395) -could take these ideas even further allowing easier and tighter -integration between .wasm modules importing WASI and the Web. diff --git a/proposals/filesystem/docs/wasi-software-architecture.png b/proposals/filesystem/docs/wasi-software-architecture.png deleted file mode 100644 index 6cb8345cc43cba2410d05ee1db06e929ba335fcb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28267 zcmbTdbySpH)HZI?DP1DnGBk*QG$P&I9Rov3i_{PUN;fj}P$JzDf+CH8zyQL~Eh+uG z!RL8??;r2_*0;XpTCQ35xzD-xIcJ}JUHdwlNHrCCTr5hgJ9qBjzEqIWxO3+o_|BcX zZ!pk+C&YL={&((xd0)y%YQ3J`%EI&~UcT(ng%Lb?fkC$#@3fPE41REr@c|COlH7~L z4+`q)Y6R-)>THX_2KiVzr4xB}>h`j)IM^Q_opD&S4!?!J{-E*jq2xo+Yaix=&hMb+ zDaMT1wAt13)8{!>-aBdD^CxNZej?PNKcg{p<$9LjpQ1{AlM?51vP}1ke7$xezOR5kAz&k6@4c>j=UEvCII`o*@X|VUZoUTFZ-*F z1Py1uBAw4ix=l*=1q21?`0OvABo2rkYiNC4Uss+abonlAY%}^t z%vKS7lbo_z5Z^+-AO>CNpQIl@Vh9~1Yihwue_BBf+|H*_4+Uj?2u!S=8Z}tuoW&p5 zI~jFi9oZ81W`+_-DP)X_4Ni#)@SSgK4y7NBVebYG-b;fUe9#UGyik*TxvR?1?Afk; zsV~cGOBYJ8=t$37eUM!u>VrJFe!YF4w2gTAetE;m`_@RYgnC4KrLPSSFsi@Q>e^aa z;$i>LuuVi5m+YxdrSoh74wcB&SS(@Iu2vA(ydMHsTSK105ug=lK2;y{NnLAZW17VK zy8hMV*CN7Mn?Y#|y8J1tWil@6=T1u}Td!ZJUyWo1>9@1+BF;DYU4YM|%PQ(jJgBj? zG*?u=8mFBso3E6g({ok?I@;62;rsj1eeKdSRHXUD%R$EVi`ld9)n|9j!7@NQ8~qrs zdt3J%c&>pR;^al+!9qLjL4dw>(DD{G_km%EXYDVYsP7yBfzB3YR;Sm=8xwxC>Jv_{ zmCtEU&`zK|--Rf}y+%{EMZKuMaYhnIK@Bzd+)M)YB3GrGKG(d3H1E{;C7CcSEB2~n z;ZZS|Qq?4|i zHXat%_uw)=%vm+{Y_*6{v*@eTKd5|eLlLf}-wa9kT&>IEHb3+FP?g0M z|DsqO9FKM62RDF~g2T6$cB?KwY2({{Uo~lyNefsPm_Fur?A@q4e=JJ8t8{kXodvM6 z_YLNPP}@uy5gM*szF(Z)z;KL&bCV6&%;BTcQYf3E zj!7_cDql6qa*ZVO{#ECm$Ij>xYe?9^=c`S**hw6ct6rWkimuf61(pZ;c(rx*YRd?x=<;nfUC>La(+=ySjdQ|LbZbZi)|))49gA)y}O<& zxujD{c2cQQmWX^w2~{pli2F?XtJb1+zeUzv24fE!JEeTJiqPf2*(w?)zIs( z$WZeTdxK9GPwRV>Q~AuNs|J28Y_YPl8bms>Tv`hAy_aa#9nW zzhemNIe$qrLQ^`)rhgiC!jnQDO5m3IBc^O!oy6t=mJw*wnyIXOD73Nl5~9%JX;}}P z-s7GIx@jAy-Ehkf4qD_wsMZ3Adu8TZ3z^x@G)+P&42aAZ#zW^+pN=8UCsbhwdBWWI zFoc-MSttfoKNb#V490Y(B#5iiq13pEi`9iT7P$@C1{Kbc3ps^2@}%==t&cVcm^Pd=o`%`-)&tXA{JO2Ze`l3W ztjY3?T^y6{5nVj964rEWBr8=Yl(bHg!7su*6_=d6#`~bBA-9|Y?rbw64pI4IO3s7P z`eqrSK`t-ii`5mWg0&MvH8|9OyK}eSQB`+CeMC%VgxdF9RJ8}!hSYgx2@ezGPA(qW zQ-0bh#<4Sd;<=&&1PW@3sneWl*Tg~^4H$+JWj}U51_EPbP-#c$PDogt1N23Q>l4KY zJF4W4*SQ0v;$0x~H0Tc>UhvvC%=fP3$+|+s8tFp zXl=Iz%L2h)TLQcjxqAc1bRPh+E5$(0zA={A^7h!uJS9I^vUJ076eW0U%Zzs>v&k$?RU-?sIXIPSk1G#!tD~+9MO(>;+ zp*daTzylZLBzG2g9y(K;1p>FIcCfTOk4fV{dbVN^O7N(YIOW8cW`mDuxIx{E0G`1D zBR^36+p=`X9w@67t$s{^;8;$>waV>F7~*@KxMzN^Fh4OiH|K^Y>W}BE3@oiAJIre?wru$=~6%CSgCn-Fpw;%58d& zvPS|C(gS-)FFVoz_;oHMk2R_XMj(X&qxxT-sPlsXPq0J&_s+6}c@tt2+^m}s?Qvm0 zmUOpPT3wHWfki3TiT$}mKey=XKX%)VPYsXW%&>j8yZP2|gT9e!+eJ3-$v%_f{05!k z<ROaP#sJ}Ku1zegCwccxVX7Q(2OE$KFR ztj$Qg!lW4osqU}#G;nDYq+)D>b&uePS_D{2KvO#j zfw2+@n2(b4$pwObd4Jm>Wr36??c4luK65Qq;(1w?nsdO_ksQD3{uS1n|T+$*f(HlrUP48U_CpoIWuCiNRG(4ZO` zoX*pH@21Ca18^LJ2Zg<#<~b*-hAl|m?s5;TryMtQLE<$ntEp})J_XO2{Ea=i5X+7= zl!Jzn;g5J{0L2wmbrH?#2er#LJZRe;;!_~lTQKE&P}y{~XRBnEW2gonP@Sp>XsFA2 z?$`Ar&7I%JJy1_|%TOHeN=P(i1;e>PjfVAVQ4|>=s#AGz$`@am$26pXl<4Q8q!>4D zu5VTB6L4o*+H`NT`mNjtg(L(O{xh4Wv{)!`t;har^NM87_RZACh(C|Nn>&RDgE9_? zN5swjhZzWGa)*1p{=`_*hj2xr%mJY$9!8^aoxZoN0s@-PV*l-$j3@EeH}V>z2g8CYO}z+_hZ z0wBx*0kB?nlCIgbiK5et1}gk3T$s!pX=boD`TCL^O5TI^9a($X75JqwI*r-&dH)QX zJO)ny`EiJd7!ObLg;-rj%zeGsA!Xy4k30>>xhHj{kQ)@BNKMO;AxusL{+%4ygHZ9$zz>2PZFLsTZkTpX$+Wny=jTo(%S^3d(d@eQJzviXEE+aExvAO>-J*`BWiu zq>ZUBY_wIr%`HAdlT(SmPLsFr=^Z45jX+LW#=rtaBoH!cgkpw+e?Fe+ zEc^VNZgj~JCHVT!nq_R{wYh`Yba!S3C;=q5Po25LsGGEyX)d*_Ksh}TiNfMzIgW-> z;H0I!?`+x^Sup8(66NK%Uu)(^u1@~aQoDp30lf`~!wnDB+;ZoE-Ea_6H^xGRY&0ZO z3N?;BKp2^W&ECl51({L^HM-w}>j>+ns%UvGQX05PSfRq*Bc|e0q6hCTB34sBwI-k z3?)d@e%Kd|^`6nYM^*+cz#2)g5I+NrbpOJem+KG-kv>8|Qb~{;NEQfKj_9GL?Sy*w zPZ3E$@Y;hn+pe6cf`nrEH=YheJJd>DFa30MhY^(hc^*XCO10md?Li(o0|Rp%8SEU^ z8%+1Ulsv#3xl~NqPY>6E8s%1pBfmddg(5U+EFEJZL?Z%?Q6#BSx~D`%9Xv5(li;{V(Wu}V9-Iqp4M7fAL*=O}B%N(3$mo^R7}Fhlw8U zDJ%rR$>f{92M+*XexI+?Gh>$JpEaQ~Ll%F=K{%4#f-4ZG|NHkhaH?MsA-D~nSw6gJ z_~#Mv-#9EpDFguVO{fOo_V)KJDE|*whUD2H{|UD6o8PzKI?|y2|1bd8>)PMts)@2f z$U>zw@mB!t55A|#XEj$`#4*093aF}B`zM0 zU-o8;Yu|HOt}SnV?NTf_LPfi)lkI;hW<7;K=jYQkGAT)GAe+0){EI#rqOCQ{9Lq88 zs}AAYw3PubG$kMQe>HYLU?2F*Wz_WVTWR*2hGH^}M|1Lak6FKyH&k=CD3un)JKH}f64^X!SZDBFrU2JAYcCu0A$LWeA50A>-UYpi0g`&G~|n$NX%FR z9JgR;e)Poguy&FVo_x z!TManxB6P3l|WYirK-zx;o-V&`S9)M4HZbf#uxqM(zaO6;h5U^qJd1(=^J3ztd|^K+ZdAG`d*74Oux{h-HXl4fFBypFNZ(zC zh?BHmN~6bPRhlf;#|4vi^9wFc{);^4Z$CPNB{8vFoK1hW>*)XvVf5(_vvbZ*+Ckmy zKmI$*uWGD+a<7aVHABW0BrU7BeD}O|2}^-ASG)N!C5TdJHj_q+gf0L*q*iy_p{vPI zOF2b6qIA04Atmx#^pDB;4-SP0eT2!6_Gpk%B?ZWK=IDA;YZiWupI85$3GIgF_H47F zn6L3sqyRZ^JUE`7FutLm)82aF3e;G%smvpf@p@j?M0W9}^5O8tJgxybSJWsuiyRAB z9)AG$Ds7eH5xAe}OOd_tN)W zHkQyZ`%R1H^Q*HmFKV1#DIyy-luiK^MUY%#r$>SgM*wP^0H7e0O#{ZPA~HfJ5%EY@4t2jsj#{de0vKCA>=zwCXvJ2 z#6&$j@+e?`l|1kH<4HHj7GL~#3+Y2Xm1_a}X{7;HEEKc+FEg|%uB%;bjlh2YN@zvL zMMuNJbF=BCHJZ{OE?Z=$r{>#$cDO@TUX=syCs=h(Z7hR!vT(%x*dB+$tfsUFd53ms zU1ocv8zXi1!wC8Uanb^H$zhUVR zzI1A0VUWrn6Pfv?OQ<7|ld0@`fwVy8p9rk^94#Y;EUxubcV^jfC=joz`kmTAz7}G2 zGu15+cLip97}%fKIA`4kZ+?Ew&gpvmgM1x=$-4gYS}vt~>s3$|IEvbrSeZP>kXjzW zLF2oGySn^CqDyIjPiAswa*|NJ(N~(d-w-wNM0UyyiMKI>mFJ}W{*4R?tVD`ba?2Bb{MAxY`wNRKg=@xIyYkA~tSaJR!un9L@Vey zgukVldC0jBFA_`TtWk9Uiqr(;>az7enJ(sPTBz&#KB9kjej&AIE=O3rt+(n4xxfem zNjPrS6M_-GY;;&gdCbi7S;h|X@*jC7r?GV|cHI5HOuDK}Ci7fB(INPF++N_E(_OWX zEeT`iL-k+5W_-JvgnQG#^k7ZuGIk~){diaeaa05uL-TW`ga4@1K%^hweqX}7qdedp zS)BSjGlJka*t#bm5}~0LjD`A{d8v^s1SV;EufMhz6sM4yXWX<9ua5|7|4gvZG;c*~ zm*K4zS2wmf5t<*#mhCf5qtZ#5y3TW;lq zl7mnS(Juag#Y0%**)PxiFZq14;8_Oc-^9%Xg*HdH3Ad*=gf(Ce{BKC`4(KF8>HO5s zOb^+!@-liRkBXOU!`(~VsAo$(9={^H&F5y+4>F>HJ!cHoihn&Fl^bc$PsQl1+Me~7 z^uSKJN%;(m{|7(#9|`&Y&JTKE@c$z}_OSjvlNE)uzYGS{rJ;8hLh3c z%3BllW*R#3af@jXoQ6ktu-(|L!pM@vwFUYd4ZZ)8s0>fo%nc2hM7BhQ36bnKZC}++ z?*{+HI!=4!V}tAXiNT04L0JK;frsI+Y=ys|Ji(EFBYYw+*EBglvMC~XX#^eq$zb&> z-)(4XRMf7U2P>eO#;Cw0TW{*yug zx#T~V_n&kE$SMEOByqx((C%ODi8K#rT5JZRkHVEKKa#SL4rW~f}?X$oiC%NvC`nIFSj z{KA{5Bh91#x*<@XU-KU-e9s08lqR$yzilYCwD-K^%W_g5kVMDwysoI}*P$sb`_%4s z9F{WG*C2MIayteAcO^CL|Mb34Sbj6jZI6t_ApB^!W>~`6BBcZs>Q!$ikIzx zfNuS5zd6NeJ8*7r%&x zXy<5S7z&?Ls)=g79O@e%MBlU&+nPy;?DRddWU)X0a%|CFT$tr|`e?f)rq{z3siqv` z*m<;A`CG3+C-oW6s6=*Nu}#=b7Qxkf+C|O~6)7TIwFTTQj11!UzAYi?(KnJvM)@K6 zGVAri&m%k`oJj18q@nVX^C;V3zh?lH8<2=p+|7Z2_aV0~_aL*SbCiZ3oc+-9&0Adc zhErYRAgvi8a~mMnjN|pZQLMKY&B$H3K=_~+#TKoA!=?KK-|hHROC@A4cV7-K9RIsn z%*Us7UE=08AH|RF=0T+NQf;1oQkgcbu5VFCg}xRGD##q}+SWj}=ua4skY@p9 z?K^PmT-23(H*M9h7phvho@HmigKX zIOLvjSF>|d3Y|!q$Fe?xKkt0k@q^BS3852KA{~m+gZYr*sq0??k(QY319&KA}9hKh(X|hUISGQu&j6km|h02fCqodv24Tv^O}_ zR&B)fY(oj&OG&zrdUl+^hsnfLWslM!srWL9W=dwnGWjnBx&Pp4d+ZG66##j0Zs*0f z_X4S&sbm=EVO9IG-MCVrxM;X1(poui_D5)a{WVc`nNS2~NI1LlRKvFsN&mRZ$QlbL z6goqcgD&~j3Q~6}6O~D*?`i9Qn>PH(+PZ)Pl8X$=MtqPG%R3VvuCNGrcnu#Bp%CG+ zWQbQIIy+p@jf#yNQ@uPQe802BEC}?B{wxwjzt1oYsr}K=5!3Mtdf6%5L6B?kh>)xC zjBtd>lpMJJ!HH{7F}mMh=JW)hJ14p_oXf|MPmqKG3i?coYq;iHP}om7nbZCqj%Svi zhtp?uITK3rtFobkx52I|)SF7I${Zh-;g{P)B=-OfqX*}@i=5mqp57t!o?0wUM~%5? zDh{~-z^zLO$^cSwe!GZVb$AY6AWfe?wYRGA_*Gn*Ug|2$p|8G=TQ3#8v0 zh^YgvVBSVwV%%q>_ko|3r9nbEI>o+-ya1`e$KEsqVyxiL^l29f2N}^$^wxnK_NzMr zzIZOSEoS>RRSM((Zh1l|dmFJWD2(hWMD392u`M009Rwd-g&a>p*OIE}TI^2397IuG zKUtK5oeqb4ux#+1yOuU|wxnbK(7k2c{r+c)waWBVuhVM5Z^TcN8vW6T%<1(?&Hcoo z$v+gUj%9&8&j6_|k$@+}D&%4ANm&aw4>_pf?$GBgqpJRlbM`^y=iD5gO1Jtc{C)cS zOWV>~_v*3Y3sxlL+H4vr+gd#F&DfBCssVDxN=XE*MwrNv-c{aRBiKbY8h z{VVGFHoV!X3)#ADMCedBB?3GkcKjtv+--h5s?dx_)1xAK-sxih4~#)^p|Dr}$~d@^ zC^_}yQufQFTkMXh1_tO2uHY>I@Jtis_3rlR`>400bE5aAzTXV1nfb=JE!6tA&t?95SpS2k> z@0O1+(2mw>&D;0@o&zM52XuM9-97CB=kcZOcAEepUG9Vd1VN5!Op%} zw-MqK4QxDHEenCB?XJb8;~9q_)877(=QvEN&7n=gV|Zf#Gmi7T1?tgU4*&L696(Dd z1xuu4ttxL&ce6F_<6fbZ&e`s-j0$xgmc~=Dr}6!%>gZa|+O_IJE+7bz_7@&1U=#v= zR|I0(du>lNwV|U+{@V7GmR5Xk_$;LcBe)Wa%d>rY?};6X=xfz7Yu~&nsA=<+N*Ae2%FB5M@gw{WsUlxi2vzT62^HB`IdiaA zB9R&e*2@8l$Htk^UuX^DJWdpg$*Ab^Bfzh9PXTS>tejmjjRPgBKMcon~1t=s4!w4nT^3;SD zXnch8z)#zr8b(za2WV)ykZSa<MQx4Gi-m!fT71_?!8gn=eQnPdE-wvbk43H<(rp zeVzUFb!;HDF7|G;|A6v9vo2S;W8r#i59EC((usQ_+RE)P zsus}ucJiwhjtHfoq9Je9t9W{iLeVYh+h2ACrz<}v7!}bpR_L8QHOUJ z%QzQyxigk4nYN8U7}IM%cZrOP#>$i+Wpyd3S6)rpZh@&0v{+zsJ{Or>@IJQcI*RiwP`NUNPyA>q; zNwV}P7h=egCSbm3;#2^+UwwE~H{4JgRRAn1>EC_srh&vVjK8*_AOvLM zQcty0}^oIT~iJ>ipNRv!;Y=)~n}SU7ljto)b`7;)5VYGS{eKYsZLTAcNq^5Xer zv*+XfC6jNgD)uY*?FBu~!EIT{QkSr+*(hMh0>G>L+!|$`V z7)#tj8{FN7As6+ppr(!LLiqb1pPZg~JLd21cu>!*l;&buR!f?Se=+OF+i(*?_6UD# z!R#=D!>H*!37yT5b^$^ir$Swq z_-aew=f$j2Z`+75K+5%o)_a`j4Me|1AH|$UyC<~8LYerN zIeffeBZk`L`joWklY#cUyuN41zM#PVLxKIWYM>&=Tw(BwB9fw)ZI^jn0oyoq`4lp1 zE;4TCr7-4jsYBjbd(cbtbg10yIx`j%j%q5|YHB%E(ReI_^NLJwuq!ROkok)N%J68! z?4+1c9*gtjBp;OyBLTnw2~R{?s6qypS4=3Ztt>evW_CK>)myc~9`Cf4`5{~UYdl(I z!6pRA^2raCC~zxU0!G%9@3={!rpx4kAg-QB`RfccgLIvVKWsO@?q%t)D&K8mAa%4Y427c zTHs#pn&4CZd!K6>t4G;r_pWqdltWAcBkBn;*aBXvY?WV3vYCb}s+lWqm*QKM4GEG3 z!^`BXGi1aJsfhrta%J;dHIZjUh zwe_89(579?%69>#m%>q@A;ij6@JH1v!yP`rP_@?)S}6s>=6X#_CD`@ z-!Up{vb*R^*DVD7c+3^c5VADkqqnQl`~LS-f4D7yWwVb%mk#6Qhw6fQ{@>Cr4k}{? z5k4d~?ywmSyc6f25AqlpC@CKF45XHH=Fgb3vppYMmjol<*8UcR8QLxW2&z|^!;G0#5TQOaDcFkr_sA>6c~*$(Rei)^mZO6wZ08?JK%D z?`E_L7wUP}TM=_m%hO9z9d#NAx<36@L&MJ#F~9@1U`?zY(DQypKq1sjxYgs#^cPoJ ztYfVhSA6tbnz{mpm?BVL-?X{62s0ySWIa?W?(xNp}KGc`d?| zPU}Bw`N4N{S--*zK|@~@Z*n$qv@!Wep0Cffa~kuHV#HE1A160jmY}{qIP5_^=?jDW zSVF5XJo+lrlyO-;aiaU98}j||NKJrhE~cMi28u_48$L8p(0IcBgV3Hn6+6h5!1VTR ziQth%4_7L-g2{g_x|!7k?2)>Mf>R!E5K6 zC=Mv-T)#g41EZLfS0x+wwc~~p|HWX(gP1%BXM6A4!?U-wFsf;$w#p66+boLFgS>D< zS9@9VwR7Av$|6la0Sx8OT}=ytTnb~$^V-fDM|XnYH;_&UQl46Q(po2hIMW$diSRzy zn#NQjJgG*!lswxq8HcSiTtq$s43STGoIm-{{QwZFp9z!Wo)kV&Ng&d?RMozFOAQq4 z?zkUhBlIZ2hT_fMX`z^Oq3?$2c;(cw4P6 z-bMB4ztBhwBSCGojd!qX0x5+vqDVWUXi4;B{$i_ulbWrslhS?e*JYJh9t+=XEm5I| z>l{-VeF5txc2*egE2ALWzokQpZ3o+5;s)$L4LAHcwpZLe1kRQuY_e0*FQH8x)AoAh zu}Z{khtJPIDFpi7HV%5 ztD0qHzhl{K9wUo0IVQqxQGcdcVRL-*EylqVQ9eqcmJvU8(9@tj>hgnoSD)?_usWtT zjCT0sgnMHJeeQU^&SzWZKhSW|!hPZ%eNt!mDNnTi3NJFQYzH_`Kp)ysGmx5QqSdJOS0Os(O1ssha+14w}oz zX-#~{D68KxU9**cG2V}dN!LBiKQ&V$0F;Ib>bwVP>2vS z@LY6K3BiakdfBNLwnkz)FTZV`8rnny<~xsyaXG;tj))>QS@j7@c1AjZ6(*ZVpvBU_ z5-FT;Pj>3n;Nj2uv`wHO5K1YedXTO`Y%NwmDlEh|d0SBx^{*(e{x^XKE-3$(C$|DJ zP?z`rOUcCl%F72j2Rp)=kx_Anr-6sg%o|_*5{YQB} zn{$|Q>_jZ?ScKnQz6|wDr>Rxtzp6c*IZ{oSd*fQEy6irkWd*3-}ms>9*CCPG(j*haB();zwRm4yhXD{eGPKZHpY3 zTjN6YZ+&`7X7Qo+P0oQgory_!gQD!u!l7v`T>UgV0yybBynvb)@O6ISqU!06(BBe{ z`a2Xt#D~z957W5XZXnD*rmeKow&eHC89##k9b!gLmMjV!JW5E*gTL{RE`j_kBtW=- zf<`aSx_Tq*U2VGUH!X8c1NiWQdU*YlOYcLJ$a!>4;5O``BAs>62j&6fNhnoe6TT0x zax#ko;@rtr`7PvNb>f5Q^K?-UyWV;d*2YhM@$KwaN)=UVRx#p^B^;^EbL-e1!;>#` zRarzrvN}N>P;+A>2Q|@kb7|9;Rvu9_gy6D!Lg}-x^=@8sDF{sXF%I=H%MQ_?x_BMP z|EGz}T+H}f13Jj7vshoO^OmpB$$@33CvzQ;YQLiEltH*|%|%~RpGM3CQOwAgi;^>1 zO5#-q*Xg)1V#r|Q-mx%-1PVXxe+R-BmPlnZzXw~rk75|?(9^~u ziVBDx0=)$l*=QGZHZ1r<=7i;|aGd)He1JmkO{|ay)l7pls~BC3^0+{^p}Z1H@}U7% zq@&DojPrr(ysLPFH>jp(jTI*wie=I0@A471pQ@jx0=)NXZoe_lf$&5!^)X=q zpWox1*t?qJi4dZ3c;_7~ccvYQ9sHeKr@oJm`*UAE26cg2djc5fBbI;S)8{tWT3p{s z8TTBKpBCrk&6QAIhqif;gqfDy4VA4|Prv@Axk|w$dthnFPoEt_b$nOT9Ep#R9vCF~ z9!deAhfLuf1=>SGcA3l;9xzmxat6L|u}9XMkkk6xz^ujWovTwSQ{!yf#q;Mhd2A@O z15P-c{*0}Hb`m`Si=x!JN(o~{BUKz@(z=ZPi>(t2{BP0VJw-|F2^ZB?s|PScq8{bP zg7& zIyIv$?)!2LvfDo(8vg-J#2Qn&i4lw+mb6!8^8tnv{Whs*0ND`PX;>pcv?6n}MoRZ% zKuY(gw(A5}idwT`RI2>9M_4IL~Uo$HxWV|7FFL{Uz zHoQC+)iVV3jXc%|5wLa>&PuAP5C#OReg01Pikz&B1+gh3z<=73Pam*W|Xw4v}AupZ_SnL=6+sI)a~sfUx5F;+Pva*I?xKpb!bO8RDJL@@O*6( zxmkYL$p};o-&C*x>BXB!ougR9eFR=f(~wiaW3jw8I7HOzj0v@N`4{-|xxVQDb=ou9 z0XxH`3NRTt?>V~(X12tCFSCEw+s_oUSCo)+iH50Wct9>y0fGCk=G|GS{JK80=4T}g z1^%!0%`r_7)_wT%m3)8kDWG8g1y#MDHJI^ki>Aax-edn1$-S$~D;6kJX5lRVu)0b9 zm3X}Hzj05rN(|-|$GlQ6q7JPAvhVk=M6NKCT8BZqE7X!NcoOvA>(hnG4AtGWfd2i@ z$B;F_G4TAMrEhirc7#4uruw>@;d2c@7*MbGcky%tou9Dt^rflCUoiYTTYGVoR{24M zJrSdI@AbluhYW!?viof!HNfXwsvUNE{+Z|Htm&hbau3(X*wRs--e;y&-9(E=?1jp) zExFVDA}qmSbh1-2gnnxj>s#q4FC+m#ikQpW>^>;W_%O8i_{&yRm#pV4f^p z9x5h)X!AKg%IgbXk{FbF4=<~XI)m?0!^Rc>nvE$rhSsSfybx-eQju{kfGr1bts82} z)I)K^UacX8VeeO{_oD{0kKWH?%8EKO1|4VSxCdCf?x#7s3Z&M&t}G?Q-G z8;k727tp{Qzp)a zJvOP_Z&Ctz%ZLvJk{)6zvo)6ps)jJc=xHiID+>n(Wu8%rz9qP~1K}S;r&coBwTo#O zM>J`UqiILePy=OJQg+i$3SoIXk0ha>eJYy3O#Gj!p;Y3!>pu7up7sRk+JGV|@|DwN z$r(dF!t#Vz@_Pi=0)dvYc-CH5- zL40k?!*1MDCEAGK;H-l7wKBl;9VsGtV6qH>Oh(*L3`j5a?8kQuX0G$=O(n)f*F$%M zFzNW6^9Lkl!f0d^G(Trr9SEkrEzU?a^l8l=67ey_p!0gTZKX3@qn`}%t$9PB`Wfov z@v+ES^T}J7m+Q$UbL{=AM^a9<(|e@TpAF6R)jn$N2@-HCUun#R+bjoB@1+n}h>rFA z?kK~}R%dj%|2y6+Q@g{|^|R^Cr0fN#USlipVNB?gT;QT#0F^#9?@2oz7vwi;iAp)@ zgw=)LjBYm#)osu!UvhrJ^-Jz*aOMHtpI0|?0(WGH`JKlnU(HDe{QK^742GC{u6;F` zyT^f?!mD3pSXUu8WB5Bv6HM6Rvz-S!Xpp(ww=Xzd1)7H3MSgJuYsc07T57zxe=iar z=n#C{!ERdW0gm)uG=j#rP*vd-M1(R=!sWNl1LD6Q$F_K?bySV8rGa&c5{!yZ{BGjS#xaZbwuYyWO9a!xoA%I9))9VZ$uEX@c-$}i z(N`D)!|OZtZ`MRARQS@lJf^;LzhUEyEHP6ni_d<4ZQq9h?Zn{OMt9% zd$swplY?p^FCF3{f1T9L3%IGzna$C;t}10}v)60oD`UN&KOb7EKepyoT|N>85pWs9 zXbiMsJs{H!a|iMhBqnhl1%)XrvQ2%8(U*lmyN9Y`1*O4B`b4P}oFUri7qa}r0t-u{ z?D_RSMFM`Srm8)#5VZ;fKj7B-c!%8E4nu-F&HdpLiE$#}$bF z49N~HwznMO!5%4MEHK*|UUYOkw{F+aNo^@DG@ZCws69n5%o^2gTx!Yf(>_qq*}0tM zU(QY9ON7PsYnoi2TlXF7R%#z#t?J00F2;6Ew=R=zpX*L=4Nv%)eM##x{$A)XW9o7I zvhN3GQbhRS&}CInPRwrff#1%WVe;8fFbPGq{vH|&=&~q=wK-7XI&*TG*EmbOZIO)2 z_()}5Gja6-2p84?)-TUE3rpV+LhlB3snF;O`uBfal$g-6Y17rtu4@j;IlM&4Ctk!H zdYxu2^tq75JY#Ql4%~2yTgP2j&lhrvI1KlQ_ILXE;iBtQ&)R;2PrG%D?4uC_aGuJc zKj3B?GgiCwlf41oM*|zoNSVxaqFA?o{KcTzjEVzDsJy!C>)e37p?kS3PhP zJs?U`w}|mb_)A9z3==qncL}8(-CT+}m1iEfhYAhP8wW&@whHh4-n~rk5MXLKUBvaC zNfTC1jZ618MQlp4Q3sy+R#Rvy~fhqu1b!_jjcV@T~EW&1EQ&*I7Cacl^LPv3o^v>{A5uEX8zF11?hvlTGkp9z<1G$`5 zNY$;E5_#|1+OB+{hNaCZ~L>q(wrB!H`}?}TvR%fl6@9^X0d0jh3j1fBm=#RtpKjlrTxtl-g_Arl*~f zc8p}~*(V_|21U);;}OF8V&*N+qw?RaWi>xl$CW%bLkSCL2eQTO&X2Hr18Xn{qaq%vT z@C0Ju7RQu5Hyr6QHvR!oCg2cwKr?;%z_KabQ*I!;?C@utZ;!ljm&dYq9b&pPqh1K@ zWT-_gK;$RyetzeDkf@h{<4!07xyem+t|=LNaBxx9eXcK#Mmt4FGn2EuF?H!e!B(|9 zsk6M*u=A;Eo*u_0(xeOHInv zdgD*u?9@7hwvbtV$nzs^AyC$8s9kRxmkh?U+tz4~ z5BE?|?=dEA_)9n^V?f`nb_@bwf4 z>SWcHX-feLYe`ryKN=Cp=Qte3Ir8vCEu&5VKMCse7`F+WXT1wHXt zI>tL>`(nRz!1u8>AVvqosta!t!S?)Z47Tc~#?S*IHeNM{g}-lfdA;^lnn*qw?9J@q zckl-lcdpf10r9VKCc<1d-a0$@btQ6M_7f!ZPRdG{n`2>YXZD$Cr^3sFF>P!6=`K5> zZyugXO=lu341s==gEUWp)xx#o&>!VE-PE2`#cV>TnLd!yl0H|qalk>SGo%@C$`q+= ztM;kH`30(JAFG6}UTPn$#|cH8gT+wjTC-n{)}rR5N&KhVa%*(=jgH!Oqy*^rgip@8 zaErEIDnidbj|j($+Q03KuQ|1A@9|jH_eO%2XS)A@clnHKGm(c4&v86uv9xwF63V!RKP2 zV@9|D?kF*7^6bp)Be{Q&Oz=?JvtQ8-sTHZu*s@B#F3CROZY%^%HhQiXSO!`*?TZ@^ zJP-J6%QM^TWY*+B`W}eb+2kVmuI=r;N7a7K-{-m04lNxt4(p)My(Yp`EuiE#{waj&_I$TwbU3-ktdE z)h0~+Qn%GDb4WEytubdE5w^Zz+Afw)`96;RSzUY5dLM)NWuIo{wr2b%QQ~I}HOsE_ zV=TJcFJHxWL>EVYL*TxA74=ls<^A_n9Es03pVZ02m-=4@w2v~-DZK&niptoaAAbAe z!YcIhsNm{!Rm5-1NKE|s?`|TSP`4)b!OcbsGwT&^CEd0WiN~4Mz2nvA=XBW>O6$hy zymz$&yysp&V`vi3B*{lSzobg3K6lf}sgu;x3&;y_G79*H-(f;Co$l~M{7c1(yUcxkc9vAv*%V)m>mb~Ytq{Y`C5njE(u<<4I(Z_TFc2v2k$xLp$Zf}oh*V-JB zQD-sP7p}>U|B=RU#_nj_mPYYqRA9o0iD@m>deU>U`yVXs7%_h=Jo+5PcanS6X4!k( zmF7#Wf>Rum{Y8n&x#&DO=eLj5Bp#JC)0lfBy|DcczfLar&@bz4rRrCuYtOVc-@MECBS5ut zCSO@$__5iqUd08?uds-+?(SM-zsGXXU2R&^z4@;dH1ilEo&0##PyATUy*KI>FY+rb zn!Rac$R_$7M&@KISXeTR&KOE%4NU_K^pl(TM0gzZS+#R)3VSofKhPf->Tvwg6`gC? zVF5l|Pa`?4U#M%cSd-qS@0VI}ky&BV4mOo?S~83!*a!_fM*5`vo_EFh{P}@6+R^tb z7caSfrD-1SHQo2(pUOZ!_@%M|r4sXA|6fN}!B$n*M3s~lk#3Nd?(UKjiA#4~x?7O$ z2I=nZZqQ42H*)Fjj_+jrkHwu91?ISq5hx~cKmneHcl;!HQ3ZegwV+eRR#N^*x67>N8sL?ge1 z@XN1a&g!bKo;`)x*+v&!RnWQm$V!@MORTz;NM{22Vn0~^8n9^omRiV3L;Uuj}UjJj= z7PWzay^yvQ@`H%1&oo+tHM+C}SoHDaBTCWd0UDDgXa_2lY zE>gAbB*}$}j?6;FJmHI|q!&=D$KJ9gCi4y~2Tl-;^V+Q);Y96bQc|kGoe?@4b*Zt9 zoDI}=q@GD36~=N(F^+j7jK#+vDo8qP9{slelzChcp&J|bGF+QY83JJr4wKIw&hoPE=Mo7 zIttE~#+C>?UB_0%hr-r`B@9iQEnPtqr|De6F1*?KXxD?JWJ7o;lLbj8<#nc=C5g9 zY+f;18pa{X$Kj{*4<_Z!!ow4ai$f04$E9}bdQH{FA+GzF7LBO_Ta!LP2g6y9k0+)Z zS{%BmO;#g{5i3JniMJ$L<+R;J@$Rb2(P?!X56aBz_;^_If2OJhdCa}9|J zIL+}kV#k#X%oWn_tx9X*fRf}j?qGPmZTmTwS&LCORr$xH6Oy#bhj7>S;n3dBQ}kt5 zn-qv8ke6N)v##dqC-v?iOAofBu78ky!Q3lgf9@-1rH1 z0`_DjM9}GBT&}uX@u3@mFS91%185A(u&`|r*#C)HoC4= zxri`=Egua3;sqBiBOlNU^E;3b5M8w{>I3;ZVP$-kJb!n=K!#8M4ix=T6F#J>-MWI! zM`G!(sOhp4I^DA%QzXWs&$JmxCX~pgmc(~u5rK~9`fob7HzAH|pRu|Os5SK>n?)C1 zuC49$2pY|QiaEk{BNOw6vC;$|^F2XBIsQ^|GNlO!@Et&{f=68I;MIJcNMdn@0}i^L z&DTygbn<0SQR#z=^EBn3nr9T8JUGm&52<;v`AEmWcuN%mZ>}n$H0?xKmKp+|YL>PB zwji57VinNWf>tr;jT10;(Yx$!KcdEd>vFQ%`^j)~barup=T+bS;P1e$oeJp*qn|v; zBNfSxO&2~n%gf|+#ZM7bq;{!^#Ox3pxJiU~Q{dNX2OnS;QBpO!l`hE=*}il9N{UiY ze68#v`L@H3Bn0F(m%i^K4~t?5_4*uE{J#t4@pT&|EyED+)ucVId2{ua=5juCX9za3 zP0d%?*uP~YVN_=HA`-y0ZTUai%}Vpp=bVVKZM}`|+t^#~xD|3vfFgkJk3+p~1LsbMp|i8Lg$tcJ^gw8{ZqPnG&onjJeYl z3-5!-7;nbdgHpG+BXKkIUOJ9h+lAA>8{n(hRHfPvsQw(foxUSV1H^8tSn70GBgpa1 z7p-u2zdBxqXS(Vu!T+z@iM`@&y-l+6vR+v?`Wyavv8yap+!`^M({}5#E&UF2>)SP0ytmN@icYB3APSHm}$wIXVD|0*yDd=my=cZ@8mc z3S*SENA3|NKYG*3JfyOXO{LXxeW=OC8-F4H=7b;OwEg57*>Co)6`J?^@OU0$ z&vEVUZvh}Ahd5I00yi*RTE=-QTyvRcaegGJ4gU;RjX?eLsO$^+(nXP%70_fEKDZRx z3qO4S_-QBX31IAW9#`P=6LUE|hJk8;NH6$jyQk~IDB)q>iM#JNlmua<@5UQ-<|JMA z!tBADYPv2Y6m3{9sU>aB2a|~1a_euKb2&bmE6Dg^Mwe=4D`kEzM0ECUIscBeeHq5f2qa%-NI(MVeU}~PJRfykKOxpFm z_0DZ3@%)yC-Xb>KD?XE?IFdxGV6oBf(AZbtY46$P3DM;%n{H8@bE{Huej(^>OvTjsLD3U-o=@s1glM595f!MX5+Q4WD95 zpO;F|E*}{uz16=_X1+9UI|TjqF(jMDp2pJK42;z$dpnmV)Y=y3p}wT6Z|ac2)VTR>JM0!;K5!cau?f)*cl2Y09#uIA9=#HZq8==gvK~ z=fXi~P#%+0iU4EV;xxrb;pZ&Fb86M&ooqMr_X8vdQV?>(@$kj+2r1i7-yH`TSSd=s z2C_@xvtZ%DtH;0aPpA^kDuUg1fCG%;P0~PPUWxkX@>HJkBXRsuY4c;pw_Px0S^(@y zkMru{R+Ca+A}Lp9y05mKtVv-NWC$_5lk@^4<1D?no^NK zU`7dTz+dQfh$WGfzzar8ExSk=oHV?Lafxx*n3et+BRr#~uyMQxlav)1L`IP>qYv?h z2O~}BE4opfkSPpeGC#-M2udnRl7zqz4sbBoM?n;hK|<M?(5j@nI!yxvbwC>vlJr_=^X`N5;(F$gyfaFPHrGS3ni-?z3oQH1My z$~EE5e1IIrvWPQEuGi=A!H<%=L8I`P=wJJNB+UGs{cpCLzvKN>{sr|aAT@CxEHD^d zRcr2XZ}p;t@EUtvNQEXNr*JT!*}<}}{1=3umr0u0u3*dYxC<~PFt+`1CO(6a4&Fob zqgSDYAHj&2>Tx)KAMcNt!YM9!3fPx=C>bd#dq;;LXkf&r{?>ohGH>qh0SC3c*H^6% z-z8f_oGxd{@ME);0sVJB&)|f%*j((nKzZ|SrK9ir$#VIWC0sEJ#q`LsFqdthsau** zUL&tsR51DhJg_td_^Bl;p@v>!+0Rlq@Vb4aat7u|w0*_zSMXFdBW z8PL6c133mTH|tqWEBi2I3#mK~8ero4JPJYEm2c3-8o8LKL)QNCsg;QopO}qJIm*%v z8mzoK=f(PWM^hEB>tdZ`&>#bbkjz8rwPSHEjyAK@XbHzxfyYT5VX|X z49x?~FEjpf-;)c5(WdD1jDUxD#(&V5)JumJ<^@c9-YK09&Ks(5` zVusEa)4D`w?mb^MflA%kMMcBKK+$PAAOEDo{r;!$?hS=9WMc4M0&YCI4`XQr(lz*u z-Zv_@(OXfO{JK#=$Q1)!FTwxgTWPQw=piN=F*;CD_SvqM_WZnJhXV?T$-z-X<-EgT zhQCKcg1Rl#m4>W@k%jy3K(6{9f!@_T1MIypr+(g0?sbt;Ai0h4NS&K47jyYz{ut5w z@HQc*(Yd(Mze zc#Uv&|D!cnc+KAXmB#Ju{M=A4t%L*J537Q=kY;AL!t_URYie|z;5@{Dyf45 z%l51)^=}?CQk|7V({ub|jD+>mMtAp5ZH8@eq`4iR(C*@j401l=_qlC7M97psS4h$j zTvWv24n2fekeHaQo*(bHZpmaDQBxIwjeX$yLtp*@=BBo6IdAW&jeQHlC14=nUQGtL zgpHNqmKz48_Jvc*mUL4lTGflr)p0l^v@qhZB@14nU3|_s@gpJS4%1P zcHAMua9IRU`Qa~9PgmPeR5p38qtxT;xJ9zS@r<>|3e&d z3T*+tDoyAMdBUgEl!{&Tq`Y^yYK0{foVReF?H1OrnXDLI&a<`eO75&mafjZ|9eEX& zFjLr8%Yni9dgr@G%ow)HXHVlI1q}6NKQa)fQ7#d-v1s?t<>N@spJR7{z1hV~$hbkA zDR3LiAPTCKA5}**{IdwD+2hkz(w1UWdde#ZJRinbm z%_I=to0Kf-`Ox*aWsTyqnHc9A8t=gw!y2}h^;w60@I45?t@6@7qH}Op_F5#lS(-6^KQ-Ju%KIC-4jBf=QNd)QgLvC#W#J3r=zuGZ z6_Nvz1FY`%O9EO`E&tryE_hwuEMTEcGR*vfE)B}gt!a%IzT7wZ}85>M^O<4qc*+O+AT%EoP5;Ih34_B9Gk2T8Ot2A2{@40>UXy1>6E| z-nPRnVTV5|7!cr-qtfyCq>gb9zA4fys-q74+JHq?$NOGj&iV{HP8AEWS?k=Zw2^Al zGLEm>#`Oca$Jd;5V%L%T|%xeZGwV8gy|t*Tp-#im}{ z!W$b$X8Z}0_%nnyLo%HcniETVA8Fj4J1Hdoz?aanqi;)Cns@`DDHy5D~96g zZ)@+Yp&(wn$OKuOuWmBPX!%{Z4v_fpIW&iH6>%zaR#;xzF<(-%Wkn4_J1vwCMHrN+6v;X)$&=s4< z)mI^yIak2Rc>k>AhgN)Hs7Jp{Kraoc%(O+GRJxTy>Kv|18L>sp~zExB%#)fiqeRcE}< z4mKvgwnAABzixW3>!gV!m#W+_|`0y_YKasGj+ND zo28Voes+91{u?oS-R5VX>P*UI;ZLCg+1hG$@K)vVVy5;0&D-j)A#$0?FM<_Dva>$6i%p3ZWi&@=`h6$L#uJot%mQUJN!8RnxKk(eZz#>`0)=f~}` zI~(&=HWg!A6je$`j;dg=xT<{CVL$ElVS?8wzL)%PeiC6+di#E=17Rz7WbNT%de~5H zX1f!|xaol%qk!+dxE|N-4PC&K`N9})`ENBe(GmcO#(<40YUo86P>;Sahnf!i(w`<> z+vZFs;X@DQ4gugK+e0H3`NWj8<7AW$o$!Y+SoLATuMNEKM<0nsR2GOdHz>;q%>?&%Quwx?i%sI49odg_>eY9R~^DZc{$E#eE^+K z7V_Cy&W2HYIrXr}Ph?(17r2KLHfYDk+D1t6D;XHTc#k04P#qwf(2m~U0@OXH6Gp3) zQ*!VlACa(}-g;HT4vbduxdG9cEc8BeBCLR~ea>Mec;gCHU7U*YOp)m+h$^Tfzf3PJ z?u}BAjxh!T@KGh03r)=LewhXX%r`SO6j`}9cV+-&J;zT77pWqZ2(VztObSE*y_GYQ z1XkK@>+?`ROA=jDvVdvaj-MJiwp=Bu%9_f4dMYCK430HcCb-ach)_P2oTC#muAr2-41DiozH0CoDQF&x_h)bikdtemqP2Kl z6G9KJ6?bnBflcY?`*xYIm?9t(NDFdS-CJOcwFxSH=#TNH?oFs_b2+&$QyY=lHtaeU zk%sS5>FXID%}zSG3tX9Rp#s3^3pZH#6t;o50}^z(6e`x6klM;rJl;7z6yY5P%VA9HR%YDgYgGd-TGAFFOe|_gKddnCG=toC2U1?}O^} z;6ud}QV%As4=25U{w$kea;p}Hw=P6Zu~)>z<*(rb^AEhJSjTzNNEE(CS)#4|FnPe} zD!1ww!5(~KcfG%ZoZRV!V-Dey(Q)O!0M8TiU_)O3L@*q!U|}%P3ZQ4ll14qfVb6|u z!N#4rAub1!1#0=hi2V(kOu)xWn)Gk0Cj|HymQEpKad@PyL;7ee%6~29BR-$38HArN zEJDyQIa`U-Rv~D?a#^SSx`f<#^v7QN7A!=E2UK8E$* zgb17JtF$~k(h>G|NHID@rQ6;*3z8<#3iSp8W|KVS%TlCCVQ z5XFmN@>{#{pC$LA|CwvDLJ5RueTiq11UdIAmX-SZl>}y(g0>g`QI*4Rp3=>El7~7y zwuGZa8{~O4k0%SbuUx}&*xoKg(!J^cH*H_&9<(%*@E>C zB36ONjrgA8ziLfZzZ*tH*;DP`x3GvxjT2-^NVRcxrQ!)t1O6{ zC^GD{Zs-s=0*96$lkE7!H6vQOVUqr_lAUosIdilLR6v$q}OTrG;++O>$teqGyyA7}Ay#9C~2cHRI`PinP^*obQdHw0?z6mEAG{%hrJglaI zV`=K0{fZ|sJwWENz^1FIy(dq6U%LiGfs{_;^-=PSf!VFTSbgJQ9KqcWu9F`;#x)!D zFLGCufKWS`&@hjlX&8Q$AcX#BwNiD)bF1sB>ukPpM*nzmsH~#rhHfT_^X9&D?=*b> za~Ge+@bG(V{OZ@6Q>O=O#?`9Ij>*P;pe-G^<@3$fy&ld_@&UqnAdxlVI36-Rlb@0D zE%+q9qHsd5`_w?*dCzyH_61Pd*3^n^h&dScJSh8*gk9#;ZS_*7Wt4dhHb&B_*Cj0a zEB*wM{(u=hRk7qWL*jW+`>^s~^zK~yq}d&Q9oHH0!^c2e-^yad2}JrWGUhqv(W34o z!-HH`EwSKv(AgBN^KErb7y$9>{+=ET>kgy`>`YMBxP`xdp=$dnEJb{ zUN<&T4G?}Q>%O|a*%5c(HLbaidLKHV{kx<80)D{Xkdk!u!_x^DhkJ+n=R;W()T)p1#%r9n@gp=?6^>35V(ew>5=&>BcCW4DDvY z!I>nwxu5JLDXfKuxY47V`jrp;cIZ3iR9#pU%t-5Pq<}2Qba29h1WS;M#5;a z?A>Y#8v)nF0_k(aLpvS}1u7kGsIny_0`)PGJv2O&hgJULXe~lX|4$u|1~sE-Uu?bQ;vK| zXM~DvCSR_j@P^h()qonnGvuG2yA}ukpjOxX{rL1>n*ob%qi!4h=^R!9L<#i<28-B) zMGlpJu;E0muN7_X$#Hs1eLBy>-74yoClyR3XUmv{(3|V_AqQnxnKaO{jSUuU8^sZ; z+pHLV1BFr#wPf&_Yi!P#OC=50fbCIP9L4Rja&E(}egwm;=x+zUkzIXN#^^owZl<7# za5=G7vF_Pw!R*5Aa*+}qDeY;GAZc3@G5T*){BgFWKx&5@DYg zZqX`diT*8yx28oW%kW=p+*#l3_|H*wEa^k#_&Lp`k6ahz zMa_}hDGo~q7jGNusfd!g!4BTinv15)x9g_Kor|WtIKSC(dVjH!E95x83mc(?FZ>`O zR?hlaVeF$^y?D^K;U^3FFV%w#7*bX5cm?0he3uEEHVO7ovN8TmO>rl*k$NY5OEYo? zeG=Mx;;_+tgW+Pjrug=Bn|F=_{cZ<)s^_*-f*r&U{+k?EzV2`{f26{6&J)Q#s5X%S z-cDd&28unL;Rgvgw z1+k!32`$&q;}DvXkTZUJezX1*p>ZU;$hl1OX-Q@g8?mVy2qqP{y9tl%nxt*&W!Uvhtk5(S;cl@q=cr zHf8oKuDojvl0p0hF+cmN%MVI*rqF-38hak0(^tvbIDXd~t7thU^rUt9himoRvpMIM zoMQHhC_(fEMkQZR&gp_D@`0ZBOh;^VvAihlknd)$Z#)d@oaBuTi#~6`aZ8%bV1>yb zUio>J8uHkjMh~Lt*0OgJ%c=4o$;}q2dQ|%QyD&tGZqd#j)a3oTjzWFJ^6Mh)BY#s? z4drm@t{Hv`m_UT}V764NvF80d3FG4_dZ?tM@|kljc@qO8*{Rr4ky#4#FUj-jb#=Wl_f0I-$>Hc#k?23 z7-{}vAm#hCG<+X4A$&9!4GMXt`MSzEpHphiN=r)C@Y4Jc=02+Aq9xnUFGsNwY=vgF zR$Hih-~<7ET6a%PT`EcXBA<`J2bvcv_cr%Bg1FTKkBC(1%#n<>aSF4Rh*btx$RIShdd)Ij93OZ|UAMqy`VQj9G_-kf6d& zu!V81Kqar8i~4oLv24f#Un58pify3|*8CE)~1-WJU!muyOZ};%W zMYwi)9n|s{g9SnU%va>N@;LKBOosT8+#OMl^%VupbXM;B=iHMkTMTE_s!sa7@%cM* zZizt8&;6>f3^+I1TW;F6&ZsQ;96u!Tl_9*#nxwZ^Ki(vWbaW{z_i-&hIkHjmk!8Yw zu~AVlz@mS8lQd+l8Ab#RMEsKR_KiWj?8D7pDCt@}UCi8Xs?d-?w|24*GyOjo&n;xK zMTw>V?F|X$hzAA>%r*dD&Qw&ySmB^mTn;)1xOnT~Qt8DW&yc zpZHJrOI@5>2({{>i`k;ZM4v7+H!gUue9poF*BkYOMxmj2-55gm(@x`i?R4 zl@Wb4q*(^)q!TqENr@);!)t%%A#gzhHjW1mrjy(4RJ_x_x5LeBPa0{hKI^Xi^z^IM zd|40`m(gwdpS#$ta*5pUw4aepEwf6?L-d+7&Mcf}70jK$z?OcFZGA{dS`eHpRV%^& z1qnAr$?ANW)p#nuB~Z>!Q2#;psb)8ph1gH*|6jNv)g1bAEQ{c##uOQNIXj|V9PHux z@H*)u+-mxeNn#MS0r4<1}Us!+GB=I2QC!z}zA zFK8>0?TPI;m%=1=d402<>{Qn1@MnN has a proposal but they’re out sick today - -Till: This would make it hard to make minor updates, because then you’d have to change names every time a version changes. - -Dan: Resolution of imports happens in the VM. So we can program how that works - -Till: If resolution happens in a client they may not have a complete index of all modules available. - -Dan: The current proposal (wasi:package:semver) assumes all modules are packaged & available together. If we want to have something more elaborate - a url, a hash string, those are possibilities. - -Luke I: Its desirable for the resolver to have some way to find other versions, so that you can specify dependencies as “greater than this patch but not incompatible” - -Till: If resolution has to happen using a map, you can put the version numbers in the map, rather than in identifiers - -Dan: Resolution is necessarily not the host, some earlier packaging step can occur that takes advantage of semantic information - -Luke I: is it always a precise version in the import name? (some examples given) - -Dan: We should make a convention about whether the VM is going to download modules for you, or the VM is going to just resolve links as they exist - -Tlively: It sounds like we have differences in opinion about who should be doing resolution of version numbers to packages, and where packages come from. Before agreeing on specifics we should figure out the user story and what goals we’re trying to achieve with the versioning scheme - -Dan: Sounds good, does anyone want to propose a story or a set of scenarios to look at? - -Pat: I can provide a story for our use case, but I want to get input from others as well. - -Dan: Moving on to the next item, Weak Imports. In Issue 36, there is discussion about not wanting a system that forces an additional indirection e.g. through a GC Ref. - -Sam Klegg: In your example of importing v2 features and then an optional v3 feature - -Dan: V2 to V3 is a major semver bump, If it was a minor bump maybe that would be OK. What about e.g. most features from 2.2, and this new feature from 2.3 would be nice to use if its available, but if not I’ll fall back. - -Luke I: If you’re importing from different versions are those versions separate instances - -Dan: That’s up to the VM and the module API - -Sam K: We don’t want to have two versions of the same module instantiated to satisfy a dep. - -Sam K: Would you put a weak dependency on an entire module, or just on an import? -Dan: I think we want the ability to do both. E.g. If we have a filesystem, then we will use it to do stuff, and also if the filesystem supports this individual extra feature, i’ll use it. In both cases we want to be able to fall back. - -Sam K: Seems like lots of overlap with the semver proposal - -Dan: Semver just gives you the minimum requirement to be functional, weak imports are for things that may or may not be present - -Luke I: Semver protects you from the ABA problem, where the function name and signature stays the same but the functionality totally changed. - -Dan: You could have a weak import, and the weak import itself could have a semver tag on it, or other semver relation operators. I’m looking for a general sense from the group whether this general idea is what we want to pursue. Out of all the proposals it has the advantage of not implying indirection. - -Luke I: Does this mean that wasm is going to have to support weak imports so that there is no indirection cost? - -Dan: It would be a requirement of the engine to implement imports so that there is no indirection cost. - -Sam K: We’re explicitly trying to not push a new concept into the core spec - -Dan: Is there consensus about not trying to push new concepts into the core spec? - -Jacob: are we going to expect this in web embeddings? - -Luke Wagner: You could polyfill this on the web using javascript stubs - -Luke Wagner: Rather than mangling the string name maybe you could use a regex to carve out what part of an import name is the name, and the rest is the wasi-specific specifiers like version, weak - -(Some discussion on details of those ideas) - -Dan: Is the basic idea of weak import, somehow mangled into import names, - -Jacob: We could use custom sections for this. - -(Some discussion of how you might use a custom section) - -Luke I: If the custom section gets stripped thats a bad sign about your toolchain in the first place. I prefer this to string mangling, it doesn’t eat names that now become reserved - -Dan: There are escape characters and ways we can make name mangling work. - -Tlively, Luke I, Sam C: all in support of using custom sections as opposed to name mangling - -Luke I: Import maps are separate from the module itself, or you could put a default map in at build time, but the idea is that it makes polyfill possible - -Sam C: There would be a lot of repetition of these annotation in the import names, custom section could solve that - -Dan: Pushback that custom sections are for non-semantic information - -Paul S: Would this mean we now require those custom sections? - -Sam C: its extra information that says the module would like to have the following version, the following weak sym. The engine could throw it away and it would still possibly work - -Jacob: This is roughly what we’re trying to solve in the webidl proposal as well, we’re specifying a custom section. - -(Some discussion) - -Sam C: You’re describing the environment in which you’d like to be run, and the engine may be able to provide the right implementation there - -Luke I: tooling is easier with custom sections, you won’t have to change imports and byte offsets and so on. - -Luke I: The import map proposal says to just specify the bare name to import, and - -Dan: Does someone want to champion writing down how using a custom section for this will work? - -Sam C: I will write something down for the next meeting [action item] - -Standardization phases -https://github.com/WebAssembly/WASI/issues/38 - -Dan: Derek wrote up a proposal of phases (linked above). In the core wasm they use the concept of web engines implementing a proposal as part of gating moving it forward. We have more non-web embeddings to consider here. - -Luke I: We should document why we made certain arguments about compatibility as we go along. - -Dan: Rationale is important, should that process live in the phase document? - -(?): Maybe when we move to stage 3 with a proposal it should come with an agreement about what stage 4 may be. - -Derek: My desire was just to come up with something that mirrors the CG without specific opinions on exactly how. What do we want the role of the subgroup vs the CG to be? Should the CG just rubber-stamp things? - -Derek: We haven’t talked about the goals for the WASI api spec, should it go through the W3C WG process? - -Dan: That is what I want us to do. - -Till: wrt where it lives exactly, it could be a sibling to the JS API. - -Dan: this is a non-web use case and W3C is a web org but I don’t think its a problem in practice. - -Derek: This is something between the core spec and the JS API. WASI will build on top of core. Maybe some of the WASI loading semantics will be baked into the JS spec, or maybe not. - -Dan: How the individual module specs get packaged into a spec document is something we can resolve in the future. - -Till: Volunteers to champion the phases document diff --git a/proposals/filesystem/meetings/2019/WASI-05-30.md b/proposals/filesystem/meetings/2019/WASI-05-30.md deleted file mode 100644 index d6c773aa7..000000000 --- a/proposals/filesystem/meetings/2019/WASI-05-30.md +++ /dev/null @@ -1,116 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the May 30 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: May 30, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Review of action items from prior meeting. - - Import names - 1. Weak imports - - https://github.com/WebAssembly/WASI/issues/36 - - Relationship to core wasm feature testing? - - https://github.com/WebAssembly/design/issues/1280 - - Should we push for weak imports in the core wasm spec? - - Looking for volunteers to draft a weak-import custom section doc - 1. Where should wasi-sysroot live? - - https://github.com/WebAssembly/reference-sysroot/pull/11 - 1. Identify a module for an MVP. - 1. (Time permitting) Plan iteration on additional modules - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes - -Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-05-30.md - -Attendees: - -Dan Gohman -Luke Imhoff -Alex Crichton -Martin Becze -Mark S. Miler -Pat Hickey -Tyler McMullen -Thomas Lively -Dan Gebhardt -Sam Clegg -Mark McCaskey -Nick Hynes -Nathaniel McCallum -Lin Clark -Yury Delendik -Mingqiu Sun - - -Meeting notes: - -Review action items: - -Sam has a document about import naming. TODO: insert the link here. We’ll discuss it in the next meeting. - -Action item: Sam to send out the import naming document. - -Weak imports: - -“Weak” in this context is not related to weak GC references. - -Desire to avoid depending on GC spec -Depend instead of reference types -Pat and others: push back on depending on reference types which aren’t in wasm MVP and not all tools support yet, causing schedule delays. -Mark Miller: How do capabilities work if we don’t have references? -Discussion of the mechanics of i32 file descriptors, which are forgeable, and which don’t enforce PoLA -Luke Wagner: Multiple tables may help i32-based environments have better granularity. -If you’re using C, you have to trust anyone you share your linear memory with. But other tools and languages and implementation strategies could do better. -Discussion of techniques to achieve various granularities of PoLA. - - -Action item: Sam to write up a name mangling proposal. - -Action item: Mark Miller to write up a vision document for using reference types and reference-counted closures in WASI. - -Existing toolchains for C-family and similar languages don’t use references. They typically need bindings tools to interoperate with reference-using APIs - -Discussion of how bindings work in various languages. - - -Action item: Dan to rename wasi-sysroot to wasi-libc - -Discussion of the WASI repo structure, pros and cons of using multiple repos, inside and outside the org - -Discussion about organizations and repos. Emscripten has its own org. LLVM wasm backend is maintained in a third party repository. Concern about having things in the WebAssembly org might raise the barrier to entry for contributing. Having things in the WebAssembly org may make things easier to find. - -Action item: Mark Miller to write up a vision document for using OCAP in WASI. diff --git a/proposals/filesystem/meetings/2019/WASI-06-27.md b/proposals/filesystem/meetings/2019/WASI-06-27.md deleted file mode 100644 index d988ee47b..000000000 --- a/proposals/filesystem/meetings/2019/WASI-06-27.md +++ /dev/null @@ -1,241 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the June 27 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: June 27, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Review of action items from prior meeting. - - Import names - - https://github.com/WebAssembly/design/issues/1286 - - Weak imports - - https://github.com/WebAssembly/WASI/pull/47 - 1. Meeting Schedule - - It was pointed out that having the WASI meetings the same week - as the CG meetings is inconvenient for some. Should we change - the schedule? - 1. IDL - - Cap'n Proto: - https://github.com/WebAssembly/WASI/pull/58 - - What action items can we take here? - 1. Blockchain call extension - - https://github.com/WebAssembly/WASI/issues/56 - - Meta-discussion: How should we approach new API proposals? - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -2019-06-27 WebAssembly CG WASI Subgroup Video Meeting Notes - -Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-06-27.md - -Attendees: - -Dan Gohman -Luke Imhoff -Sergey Rubanov -Paul Dworzanski -Pat Hickey -Alex Crichton -Martin Becze -Till Schneidereit -Lin Clark -Mark Miller -Mark McCaskey -Sam Clegg -Nick Hynes -Jakub Konka -Jlbirch -vwo - -Meeting notes: - -DG: Second agenda: -Luke Imhoff seconded. (Till seconds for posterity) - -DG: Import names Proposal: presenter is not here, lets move on to the Weak imports proposal - -SC: We talked about the weak imports proposal at the Wasm CG meeting about whether to represent weakness in the function name versus a custom section. - -DG: … align with the (missed it) proposal - -SC: I can update the proposal to go back to being a custom section. The function is imported as normal but whether or not it is allowed to be missing at runtime is specified in a custom section - -DG: This allows us to skip all the questions about name mangling, polluting the import/export space - -SC: One issue is that the embedders will have programmatic access to the module versus parsing the bytes, e.g. through the javascript api. - -DG: It makes sense for there to be a custom section javascript api that can do this for you. - -SC: I’ll update the PR to go back to custom sections - -DG: What is the point where we can establish a baseline for modularity and move on to breaking up the stuff currently known as wasi core into modules? - -LI: Will the JS embedding have a weak imports attribute on imports? What about support in all the browsers? - -DG: If someone doesnt support the custom section then they just have to resolve all of the weak imports, and if they cant provide all imports then instantiation will fail. - -LI: Can toolchains ship js that detect that instantiation failed, and use a different binary? - -SC: The point of weak imports is that only a single binary is needed - -DG: In web use cases browsers might not support the weak imports natively but you’ll be shipping a JS polyfill for those to implement WASI anyway. You either support WASI or you don’t. Supporting WASI includes support for weak imports. - -LI: Will there be a document that explains the layering of these various features required to support WASI? - -DG: Sam’s document is a start on that. We need to do more to clarify on the layering. Sam, Can you add more to the document to show how it fits into the bigger picture? - -SC: Yes it makes sense to make all of that part of the core wasi spec. The things we’re talking about being in the core so far are the import system, modularity, naming conventions, application lifecycle - -DG: This will be easier to do once we have more of the import stuff in place. I’m proposing we defer more explanation until we have the import system figured out. - -LI: There was back-and-forth about different patterns of WASI modules, reactor and command, in the spec - was there more discussion about that? - -DG: That is ongoing. This can be an adjunct to snowman bindings - the reactor and command model can be adjunct to the spec about bindings, since bindings are specifically about how to use a module, and so is a description of the lifecycle - -SC: ES6 Modules need the same sort of lifecycle support as WASI does - -DG: We’ll also want a custom section to say the entry points of applications and so on. - -LI: Where do I subscribe to updates on this, how far is it in chromium or mozilla? - -DG: I don’t know about that, https://github.com/WebAssembly/esm-integration tracks the ESM integration status but nobody here knows about the status of it in browsers right now. - -TS: The status of Node is they have almost complete implementation. I’m not aware of browser implementations that have made significant progress. - -LC: I’m not aware of any advances of implementations, apple had an early implementation but i’m not aware of updates given the changes to the proposal. - -DG: Let’s move on to the next item, left out of the agenda: last meeting Mark Miller discussed a vision document that laid out the use of Object Capabilities (OCap) in wasi. - -MM: Yes thanks for the reminder. It had dropped out of mind. - -DG: That’s ok we’re all busy here. - -MM: At the wasm blockchain meeting we discussed styles of ocap systems that do not support virtualizability, versus method style, where the behavior of a call on an object is up to the implementer. (...) and I looked at using a Capnp-like IDL to describe APIs in an object style. (unintelligible) looked at an IDL that could fetch type bindings and an adaptor from old style bindings to new style, to realize the virtualizaiblity of ocap systems. - -TS: Mark you’re dropping out a third of the time unfortunately. - -MM: Ok I will put my concerns in the document that I need to write. - -DG: Mark and I discussed this and it is a big idea that I think needs to be explained in detail. - -DG: At the CG we had feedback on the meeting schedule. Right now we’re on the same week as the Wasm meeting, an arbitrary choice. Would people prefer to change it to the opposite week? - -LI: I’m the one that brought it up, it would be nice to have more open time around lunch on these weeks (in my time zone). - -DG: As a poll, does anyone object to moving it to the opposite week from the CG meeting? - -(no objections) -DG: Then we’ll skip next week, the next meeting will be scheduled for 3 weeks out so that it alternates with the WASM CG call. - -DG: We also have an agenda item for talking about the CapnP issue: https://github.com/WebAssembly/WASI/issues/56, Martin can you fill us in: - -MB: I prototyped what it would look like to describe the interface in terms of capnp, we got feedback on that which was helpful. The impression I got from everyone is that customizing the Capnp idl is appropriate, we’ll write a custom IDL that is influenced by capnp and I’m working on that right now. - -MM: You saw my attempt at a BNF of the relevant subset of Capnp? - -MB: Yes I want to rework my pull request with that in mind. We want to pull out the versioning integers on all of the methods, and adding (missed it). It would be nice if we could express things like the ability to import globals, memories, tables, as well as functions. It would be nice if it looked like the rest of the webassembly stack, so I was looking at using s-expressions. - -MB: We need to figure out how this maps to the snowman bindings, I talked to Dan who explained more about how that worked. I see the point of the snowman bindings now. I think it would be interesting to reuse the ideas from the GC proposal re defining structs and so on, and having a binding section from the snowman proposal to describe how they are bound. - -TS: Martin, the original motivation of snowman bindings (prev webidl bindings prev host bindings) was to make DOM apis fast, interacting with them directly from wasm rather than going through javascript. While by now we have lots of reasons to want these bindings, that is still a requirement of the snowman bindings. How are you making sure that your work stays compatible with that, or are you focusing on the syntax layer and it won’t interfere with that? - -MB: I’m not considering how we’re binding to JavaScript, just interested in how to express the structures that these interfaces pass around - e.g. how do we express the structure of a directory entry and how do we read and write to it? That is partially covered by what snowman bindings does so we should reuse that. Maybe snowman bindings does cover everything we need. But the syntax should look like everything else - -TS: It seems like the syntax is purely in the tooling space - -MB: We have the syntax from GC to express struct and arrays, I think that's all we need to express things like directory entries. I want to reuse that syntax, and use that as a path for compatibility with GC implementations in the future. - -DG: Take the set of bindings and types we have in wasi core as the base language, and the IDL describes what those are and gives us the clean descriptions we want - -MB: The tooling is a big hurdle in webidl right now, we want to make it easier for people to read and write these descriptions. - -TS: That makes sense. Luke wagner has had a lot of conversations around this, including with all the webidl people. They are all open to improving things. Its clear that snowman bindings won't be webidl bindings, but they need to be semantically compatible enough to describe the dom bindings pieces. If we end up having different surface syntaxes, thats fine because its mostly about tooling, but I also think we should have something that is not gratuitously different. One constraint is that browser implementers will have to be able to consume webidl in order to make the dom bindings work (already used throughout browsers). Keep in mind that there are constraints that don’t allow us to completely evolve this tooling in ways that break the DOM bindings use case. - -DG: If you can go with whats in snowman bindings now, and build on top of that, then we can achieve the parity we’re going for without defining new semantics. The key vocabulary is the types and the operations. Webidl has a lot of things in it that are distracting, even if you reduce it down to just the parts we need there are still syntax things like how “unsigned long” is the way to write u64, so i’m sympathetic to changing that syntax. - -MM: When I did my minimal BNF subset of capnp, I did take a look at the WASI ABI document and all of the capnp names for the types like u64 seemed obviously much better. I did not include wasm-specific concepts like memory, I agree that's an important thing to figure out how to accommodate. - -DG: Actions going forward: martin will take the capnp PR and make a version with the new syntax. - -MB: I will get that done in the next week and get more feedback. - -MM: There is a long term issue of how we support, at the wasm level, how we manage method dispatch. There are several ways we could map that to the current wasm, none of which are very natural. This problem goes away with GC but I continue to assume that is a long ways out. The smallest step from where we are to a natural method dispatch binding would be to add sum types, where sum types are passed on the stack rather than by separate allocation of reference counts, and the message - the thing that one invokes - would be a sum type where the constructor is the method name, and the contents of that branch of the sum type are the arguments, and the pattern match at the receiver would be the method dispatch. Given that we’re doing an IDL we dont have to decide up-front what the method dispatch representation is, but it would be good to have a candidate in mind. - -DG: My understanding is that not everyone has seen material on dynamic dispatch, so it would be a good thing to start with a paper on how dynamic dispatch works and what use cases it has -MB: Once we have proper function references doesn’t that cover? Are sum types part of GC? - -MM: The repr of sum types I’m thinking of would not require dynamic allocation so we could implement it before GC. It would still be a significant additional piece of engineering. The problem with just using function pointers is that method dispatch with what we have now, the options are 1. You pass by copy a record of function references, and the client of the object invokes a method by looking up the method name in that record, the problem with that is the size of the reference to the object is passed by copy and proportional in size to the num of methods on the type. -2. You pass by reference a … it loses the static type information given our current system, so you’d have to cast after the method lookup to the right signature. -None of these are natural for intra-module communication given the current wasm representation of things. - -DG: One thing we talked about was virtualizing an API and how we might do that. Dynamic dispatch approach allows you to virtualize in more ways. There are a lot of new ideas here and we need to motivate what problems we’re solving here and spread the ideas more broadly. - -DG: Lets move on to the next issue, the blockchain call extension. The main thing I want to address is the meta-discussion of whether this digs inside wasi. Nick are you here? - -DG: I encourage folks in the blockchain space to submit proposals, it fits well with our modularization story. It is a bit ahead of the curve as we’re still figuring out how imports and weak import names and so on. - -DG: Implementers of wasi that don’t have anything to do with blockchain wouldn’t have to implement these interfaces but its good to have the standard for how they work all in one system. - -NH: (missed it) - -MB: It would be nice if we had an interface for persistently storing function references and loading them. One idea is that we could extend the number of file types to one that could load a function reference and put it into an anyfunc table. This would require the call-ref operation to call the method, from in the function refs proposal. - -MB: The file types we have now are a file, directory, block device, character device. Are there problems with extending those filetypes? - -DG: Part of that question we might not quite be ready to answer yet. Does anyone have problems with extending the idea of a stream beyond posix-style streams? - -LI: If plan 9 could do it we can to -DG: We can talk more about stream APIs but I think extending streams to be useful for blockchains is a good idea, as long as it does not incur a cost to implementors that dont need blockchain. - -LI: We say blockchain but is any o f that not descended from etherium? - -NH: I want to generalize this in way for systems beyond etherium descendents - -MB: I worked on ewasm and dfinity, I also want this interface to work beyond etherium family as well. - -MM: The plan at agoric for using blockchain and wasm is not etherium-like, it is consistent with ocap approach, and the issue of dynamic dispatch becomes important to us. - -DG: For some context there's discussion in the CG about webvms and the requirement for 2 implementations that are webvms. In wasi we’ve decided that the committee would accept non webvm implementations and make decisions on what exact vms would be accepted as we go - -LI: Whatever system we come up with should handle more than just one currency, it should handle multiple currencies on a single chain - -MB: We should standardize that we aren’t dealing with one particular currency. This would probably be a good document to put together. - -DG: We should record our thoughts on what requirements we have for blockchains. Martin can you write up … we want diversity, we want to make sure we’re standardizing on something that more than one implementation will use. - -NH and MB will collaborate on that document. - -DG: Any further items? - -Meeting adjourned diff --git a/proposals/filesystem/meetings/2019/WASI-07-18.md b/proposals/filesystem/meetings/2019/WASI-07-18.md deleted file mode 100644 index 670da9f4d..000000000 --- a/proposals/filesystem/meetings/2019/WASI-07-18.md +++ /dev/null @@ -1,262 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the July 18 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: July 18, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Import names - - https://github.com/WebAssembly/design/issues/1286 - - There's a lot of big-picture design work to be done here. - - To unblock modularization and general design work, can we adopt - a new temporary scheme, still containing "wasi_unstable"? - 1. Weak Imports - - https://github.com/WebAssembly/WASI/issues/36 - 1. IDL - - WatIDL: https://github.com/WebAssembly/WASI/pull/64 - 1. What other blockers do we have before we can start designing new - "wasi_unstable" APIs? - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -2019-07-18 WebAssembly CG WASI Subgroup Video Meeting Notes - -Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-07-18.md - -Attendees: - -Dan Gohman -Martin Becze -Mark McCaskey -Alex Crichton -Andrew Brown -Sam Clegg -Yury Delendik -Arun Purushan -Pat Hickey -Jacob Gravelle -Luke Wagner -Till Schneidereit -Luke Imhoff - -Meeting notes: - -Pat - agenda seconded - -DG: -Import resolution outside of the scope of WASI. - -Pick naming convention that involves the name wasi_unstable + a possible additional identifier, to allow us to continue designing APIs. - -SC: wasi_unstable implies a bulk rename in the future - -DG: agreeing but bringing up additional prefix to clarify. Does anyone have an opinion. Suggested wasi_unstable/ - -_ : Is there any reason to use a / - -DG: We want to split the existing wasi_unstable into multiple modules, :, $, the specific character doesn’t matter. - -DG: is there a problem with / - -_ : Agreeing that separator doesn’t matter, but we should move everything into namespaces - -DG: it will allow us to start design work on other APIs… - -DG: wasi_unstable/identifier is the current proposal. We’ll call that a decision, we can use that to unblock things and start modularizing things. We’ll start queueing up those issues for the next meetings. Let’s have those issues and we’ll start tagging them. Part of that work will be deciding what goes in what modules - -DG: next agenda item. Weak imports - -SC: I got as far as implementing the custom section and realized that there’s quite a lot of redundancy, we’ll have a global corresponding to each global import. All we need is a way of finding that list of globals, we’ll probably use name mangling, so all we need to do is specify the suffix and the runtime can find all imports matching that pattern. Name mangling just for is_present. It would just be a simple custom section saying “is present” - -DG: that strikes me as overkill - -SC: (something)… we can find all weak imports by looking for that suffix - -SC: someone asked why we weren’t going forward with the official Wasm spec proposal of weak imports - -DG: one possibility is that we can take weak imports as being in the same bucket as snowman bindings. It’s a way of describing an interface to Wasm, so maybe we should put it in the snowman bindings custom section. If that’s the case, we can roll it into the snowman bindings proposal. I think it aligns pretty well with the snowman bindings things, because it’s a custom section, and (justification regarding name mangling) - -PH: if you have a whole bunch of weak imports, you can map them to the same global if you want to. So that’s an advantage of a custom section - -SC: what does that mean, if anyone of them is missing - -PH: that’s useful if you’re importing an entire module of things - -SC: that’s useful for all-or-none situations - -SC: yeah, I like it - -DG: alright, so with that, I’ll put that to the group, is this a good way to go forward, put it in a custom section and roll it into snowman bindings? - -(Luke allegedly nods head) - -SC: I don’t see how it fits into snowman bindings -DG: it’s part of a custom section that is the interpretation of the module; it’s not quite the same thing but it’s in the same category. It would be in a different part of the custom section, and eventually things like specifying the entry point - -LW: (missed)... this is in the same kind of layer - -SC: that makes sense when you put it like that - -DG: does anyone want to comment on the issue then? Someone in the WASI repo brought up the question of using a custom section - -J: if that is the case then we should put it in the webidl bindings repo - -LW: the webidl bindings repo is itself a layer of …. - -J: should add assuming it does exist (snowman bindings) - -PH: there’s a large overlap in the people working on both, so it’s probably a non-issue - -J: do we want to use weak imports for something else? Mentioning it there will get more eyes on it. Weak imports in contexts outside of WASI - -… - -SC: should I keep going with specing that in the WASI repo? - -DG: yeah, for now.. We’ll figure it out as it goes - -DG: next agenda item: WAT IDL proposal - -M: So where we got stuck last week is with conflating two things, the way watidl was written made the interface an object, that’s a mistake because an interface is a Wasm module. I rewrote it and I’ll push up the changes today. We should take a key from webidl we can add the extra field that this is a method and then we know that the bindings need to bind some sort of context, so I’ll introduce a method field. It’s also important to remember what the whole point of this was which was partially virtualization, ideally we should be able to have an IDL that Wasm binaries can bind to in two different ways, one using aztrack? Data ADT where all the functions are imported, the other way that would be easy to virtualize, I’m also trying to, I wrote up a little doc on how to do virtualization which I’ll throw up today, so that’s where we’re at with watidl. - -LW: what does virtualization specifically mean? You’ve requested to import this fn but I’ll give you a virtualized one instead - -M: the ability for a Wasm module that a Wasm module can implement a given interface and another module can use that, there’s 2 types of virt. Static: another module importing fd_close, open, sync, which another imports. Dynamic: a module being able to on the fly create a file descriptor or implement it to hand to another module, which is what I meant - -LW: do you mean as a reference to a struct that contains fn refs? - -M: yeah, exactly. SO in that case, the WASI interface, ref to structs of fns, you would just import types at that point. It would be nice to have an IDL that can describe both ways of interacting. - -LW: and who would use the IDL? - -M: used to describe interface and then you’d write bindings. - -LW: so this would be the interface of WASI? - -M: yeah - -LW: would this be equivalent to a list of Wasm function signatures that would be allowed to use snowman binding types in their signatures along with module and field name - -M: list of functions of types, it’s pretty basic - -LW: If we go the snowman bindings format and have a Wasm style and there were fn sigs that could use these types instead of core Wasm types. What if I make a module that just describes the interface… just a subset of the text format. - -M: that’s pretty much what this is + the addition of whether a function can be virtualized or not - -LW: that has some pretty significant runtime and compile time implications - -M: We don’t even have structs or fields, we need partial GC and func ref before we can do dynamic dispatch properly anyways, so we’re looking ahead. - -LW: thanks for explaining that - -M: it’s the text format - bodies, just types and function signatures - -MM: Wasm interfaces are overlapping, we should consolidate these or figure out what’s going on -SC: virtualization isn’t needed for what we need right now, so maybe we shouldn’t push on that too hard if we don’t need it right now. - -M: agreement/partial agreement - -M: I think virt. Is important in a context where you have multiple untrusted modules working together. As WASI is now, it’s generally a single module, they can add object capabilities to each other. In that context it’s not as useful, once we have func refs, …. Then the capab to virt interfaces is more important - -TS: I thought that was a different layer, instead of the runtime built-in you use this instead. I don’t see how that would interact with the IDL, can you explain that more? - -SC: you’re talking about interposition vs method calls, interposition is like intercepting a method call. - -M: Are you all familiar with ADT style? RIght now everything is ADT style, so you can’t really virtualize ADT style. A module can’t really implement those functions, it can’t generate them on the fly. So to be able to generate or implement a file descriptor, that’s /udev/random , so a module can do this and generate a FD on the file when requested by creating a struct and hand it off to the requester, why this matters at an IDL level is, a module may only want to use OO interface and in that scenario, you’d only implement types and the entrypoint fn would only receive capabilities, references to structs which point to functions. One use case for an IDL here is the host system would know that the module wants OO type vs ADT style, does that make sense? - -TS: I think so, thanks for the clarification - -M: that said, since we don’t have, since it’s not given we don’t have GC or func ref, (func ref?) looks more promising, it might not be worthwhile to worry about this. It might not be worth worrying about this yet and just focus on ADT style - -DG: as far as next steps, martin you mentioned that you’ll post an updated version of the proposal? - -M: yep - -DG: we’ll iterate from there. Anything else we want to cover in this meeting? - -M: I also wrote up some stuff about virtualization, should I add that to the repo? - -DG: Sure, make a PR and we can discuss it and decide if we want to incorporate it - -DG: that’s a good point, virt. Is an interesting enough point that we should document what we’re going to do in this space - -DG: next on the agenda, with the theme of setting up the wasi_unstable namespace, what are the blockers that we have before we can split up wasi_unstable into modules and working on them. Having an IDL nicer than a C header file or markdown is good, are there other blockers? - -LW: do you think we should hold off until we can make use of reference types and type imports? Or do we want to do it later - -DG: I think that’s something we can deal with later. When we have full snowman bindings, we’ll want to convert them into that form, and emulating lower level concepts with our higher level types. We need to figure out what is a file and that doesn’t need to wait for (those things) - -TS: maybe we should say that the changes we make going forward should take these concepts into mind, (describes using indirection of fds in a table of anyref to make transition easier) - -DG: that seems reasonable and I think that will somewhat naturally fallout given API design. We want a vocab to talk about things until we have an actual IDL, we can do API design with C headers but it’s not ideal, so we should figure out what to do there. MAking it easier to migrate to future bindings systems seems great - -TS: two advantages, we can do API design now knowing thta API design can map well, later on we have a straight forward way to make it easy to consume in C/CPP/Rust. Two APIs with the AnyRef being the fundamental and an indice-only one on top of it - -DG: how much do we want to do now vs waiting for snowman bindings? If we just design with this in mind, it will be pretty straight forward to retro fit this, that’s my gut feeling here. - -TS: All I’m proposing is making that explicit that we want to have this 1-to-1 relationship, making that relationship straight-forward - -DG: should we have a document about “How to design a WASI API” - -M: that sounds like a good idea - -DG: martin or till do you want to start a document like that? - -TS: I can start that document by writing what I just said and then we can flesh it out with more content - -DG: it can evolve as we get snowman bindings and other tools - -LW: it might be good to have a “future intended steps” section. The intent to move to ref types and binding types are only in our own heads and we should document that somewhere - -DG: looking for someone to document OCAP vision and put it in a repo, if someone wants to do that, that’d be great. It’s been discussed in various places, but we don’t have a document in the repo describing the plan. IF someone could digest that down and start that, that’s what we’re looking for - -LW: I can help there - -DG: we have the docs directory in the WASI repo. Alright, I’m trying to push forward to the point where we can do API design. Are there any other blockers? We’ll have a document, (somethinG) in progress, and a plan … for a module naming system, temporary one, pending discussion about import naming schemes. That’s the end of the agenda. Is there anything else? - -SC: presumably we’ll need an IDL to header file conversion after, -DG: yes (..) + rust interface generation - -M: … -LW: … -TS: s-expressions as type definitions minus the body is the obvious way to define the functions. WHat’s missing is how to fit the binding expressions in there - -LW: importantly, binding expressions don’t fit in there, interface is just the types - -M: to generate a header file, you’d need the IDL and the bindings and they do need to be separate because different languages want different bindings - -LW: I’m not quite sure what you mean by supplying the bindings. You could generate for say, C, there’d be policy choices like what to do with strings, but it’s possible. Sounds like a cool tool though - -DG: that sounds like the end of the meeting, see you all in 2 weeks diff --git a/proposals/filesystem/meetings/2019/WASI-08-15.md b/proposals/filesystem/meetings/2019/WASI-08-15.md deleted file mode 100644 index 8062b2745..000000000 --- a/proposals/filesystem/meetings/2019/WASI-08-15.md +++ /dev/null @@ -1,121 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the August 15 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: August 15, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Weak Imports: https://github.com/WebAssembly/WASI/pull/47#issuecomment-521061962 - 1. Interface description based on Module types - - https://github.com/WebAssembly/WASI/pull/74 - - This is a rough sketch, similar to WatIDL, but stripped down, and is - meant to be just enough to let us start describing API proposals. - 1. Meeting time - - I received a request from someone who would like to present a proposal to hold a meeting at an APAC-friendly time. - - We have been following the CG which held some APAC-friendly meeting times for a while but - [dropped them due to low attendance](https://github.com/WebAssembly/meetings/blob/master/2018/CG-04-03.md#drop-apac-timezone). - - Assuming this works for the presenter, move the time of the next meeting to 08-30 at 06:00–07:00 UTC? (This is 08-29 at 11:00pm in Pacific Time)? - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -Attendees: - -Dan Gohman -Till Schneidereit -Alex Crichton -Luke Wagner -Jacob Gravelle -Sam Clegg -Andrew Scheidecker -Mark S. Miller -Johnnie Birch -Stefan Junker -Andrew Brown - -Meeting notes: -Topic: Weak Imports: https://github.com/WebAssembly/WASI/pull/47#issuecomment-521061962 -sbc: moved back to custom section design -[please fill in notes here] -MarkM: could a rename be considered—I always think of weak references -Sbc: very strong precedence in C/C++ -MarkM: weak/optional imports should be brought up with TC39 -Luke: [posts a link https://github.com/guybedford/proposal-weak-imports] -Dan: good question, should we rename? -Stefan: +1 on “optional” -Mark: would “optional” be confusing? -Seems like “no” -Dan: seems like consensus -Sbc: [takes an action item to rename] -Dan: anyone opposed to landing the PR once the rename is done? -[no] -Dan: let’s do it -Topic: Interface description based on Module types (https://github.com/WebAssembly/WASI/pull/74) -Dan: lots of stuff going on around OCap, and that should go on -But in parallel, we need a simple text format -This PR introduces a stripped down text format (see PR description for details) - -Mark: should we introduce a term such as “compartment” to describe sets of instances which share memories and tables? -Sam: This relates to the concept of “shared-nothing linking” which we have been introducing. -Luke: In full generality, we won’t need the term compartment, because we’ll just have references and different linking approaches. -Luke: if we want wasi_unstable to become wasi, we need to spec ways to send capabilities between modules. We don’t if we just have references -Till: brings up the question if we need to support wasi_unstable, instead of just breaking it -[discussion] -Mark: This is a useful concept, whether or not it’s something -[discussion] -Luke: getting back to the proposal, looks good for the transitional role -Dan: idea is, once we have a parser for this, we could land it, and have it be the specification -Could generate header files and documentation from it -Sbc: comments go into some kind of comment syntax? -Dan: double-semicolon -Sbc: need some kind of include mechanism -Dan: yes, good point. Want to really keep this simple -Luke: same requirement came up in conversations with Andreas about defining types in one module and using them in another -Luke: but as long this is all structural, can just agree on structure of types -Dan: - -Dan: We need to factor out types so they can be shared between multiple modules. Maybe something like a #include mechanism? -Mark: #include would be unfortunate in any kind of standards context. -Luke: We could put multiple modules in one file -Dan: Could we design a more declarative form which achieves the same goal but doesn’t have the same problem? -Mark: It’s premature to do a lot of IDL design work -Dan: agree - -Timezone discussion -Till, Johnnie: conversations about voting, and people not being able to attend all meetings. Perhaps we can find a way to do votes offline to allow people to vote even if they can’t attend the meeting. -Sam: Another option is to do the vote in the meeting, but hold it open for a week or so after to allow others to vote. -Till: That does change the dynamics. -Johnnie: Would it makes sense to record the meetings? -Dan: What if we ask the CG to record their meetings? We can follow their lead. -Johnnie volunteers to take that to the CG. diff --git a/proposals/filesystem/meetings/2019/WASI-08-30.md b/proposals/filesystem/meetings/2019/WASI-08-30.md deleted file mode 100644 index cbd14a725..000000000 --- a/proposals/filesystem/meetings/2019/WASI-08-30.md +++ /dev/null @@ -1,64 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the August 30 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: August 30, 06:00–07:00 UTC -- Note the time change! -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. WASI for Embedded, by Wang, Xin - 1. Update on the Interface description based on Module types: - - https://github.com/WebAssembly/WASI/pull/74 - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -Attendees: - -Dan Gohman -Xin Wang -Leon Wang -Arun Purushan -Till Schneidereit -Tyler McMullen -Sam Clegg - -Meeting notes: - -Time zone: -XW: Seems like we can move to the previous time. -DG: We can be flexible in the future too. - -XW: Presentation on WASI for Embedded - -DG: Update on https://github.com/WebAssembly/WASI/pull/74 diff --git a/proposals/filesystem/meetings/2019/WASI-09-12.md b/proposals/filesystem/meetings/2019/WASI-09-12.md deleted file mode 100644 index e8bf1a518..000000000 --- a/proposals/filesystem/meetings/2019/WASI-09-12.md +++ /dev/null @@ -1,92 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the September 12 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: September 12, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. `witx` API description files: - - https://github.com/WebAssembly/WASI/pull/74 - 1. Phased API development proposal - - https://github.com/WebAssembly/WASI/pull/88 - -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Sam Clegg -Pat Hickey -Yury Delendik -Artur Jamro -Mark McCaskey -Alex Crichton -Jacob Gravelle -Mingqiu Sun -Nathaniel McCallum -Luke Wagner -Johnnie Birch - -Meeting notes: - -Agenda seconded by Pat - -Dan: Last meeting was at a different time than usual. There were only 6 attendees. We are going to resume meetings at the normal time, 1600 UTC. - -Dan: Next topic is WITX. - -Independent of WASI, there is a new file format called WIT from the interface-types proposal. Its a lot like WAT, but it does not have function bodies. - -WITX is WIT with extensions. It has some of the types from interface-types. The idea is that WITX is not a stable format, its going to evolve to align with WIT as interface types evolves. - -Fortunately our needs are pretty simple at the moment: we are adding strings, arrays, enums, and structs to the wit file. - -We want WITX to be the way we specify WASI apis. It feels like a better place than the C header file we started with. - -Pat: lucet-idl tool has a witx parser in development. - -Working on hooking up this parser to the C and Rust interface generators. -Goal, be able to feed witx files into lucet-idl and generate C headers and Rust interfaces. - -Can be used to generate libc definitions for WASI - - -Stefan: Does WITX have modules? - -Dan: Yes, but the file we have at the moment attempts to be the exact same wasi_unstable module we have right now. Once we land this, we can immediately start factoring that module into multiple modules, and witx should support that. - -Sam: Is there a way to use types from a different module? - -Dan: Yes, there is a `use` mechanism, and in the PR there’s two witx files, wasi_unstable’s first declaration is to `use “typenames.witx”` - -Dan: Next agenda item: Phased API development (PR 88). Apologies for getting this up late. - -Stefan: Could there be a standalone parser implementation somewhere? - -tdoPat: I’ll make the lucet-idl parser and validator for witx into its own crate, and that crate will live in the WASI repo. - -Johnnie: I followed up on whether we can record these meetings, I talked to the W3C and they expressed the same concerns we heard here about privacy, making people feel comfortable speaking up. They suggested I talk to the WASM CG, but given that I’ve heard the same feedback from multiple places, I’m going to just drop the issue. diff --git a/proposals/filesystem/meetings/2019/WASI-09-26.md b/proposals/filesystem/meetings/2019/WASI-09-26.md deleted file mode 100644 index 704aed13a..000000000 --- a/proposals/filesystem/meetings/2019/WASI-09-26.md +++ /dev/null @@ -1,60 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the September 26 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: September 26, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Initial WASI modularization draft - - https://github.com/WebAssembly/WASI/pull/98 - -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Andrew Brown -Mark Bestavros -Leon Wang -Alex Crichton -Peter Huene -Luke Wagner -Yury Delendik -Pat Hickey -Artur Jamro - -Meeting notes: - -DG: WASI modularization draft PR is up, comments are welcome - -Also, this makes the start of the point where we can start taking PRs for new API proposals, in the form of PRs which add and modify witx files. - -Pat: We’re working on an HTTP API proposal. - -Dan: There are also people working on Berkeley sockets APIs. Note that though there is a potential for overlap here, it makes sense to develop both. - -Pat: In cases of overlap like this, the higher-level APIs may even by polyfillable on top of the lower-level APIs. diff --git a/proposals/filesystem/meetings/2019/WASI-10-15.md b/proposals/filesystem/meetings/2019/WASI-10-15.md deleted file mode 100644 index 4a9566f3d..000000000 --- a/proposals/filesystem/meetings/2019/WASI-10-15.md +++ /dev/null @@ -1,116 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the October 15 in-person meeting of the WASI Subgroup - -- **Where**: 10355 N De Anza Blvd, Cupertino, CA 95014, USA -- **When**: October 15, 1:00pm PDT -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -This meeting is open to WebAssembly CG members only. To register, please -visit the CG participants page: - -https://www.w3.org/community/webassembly/participants - -Also, the host for this in-person meeting has requested we provide a list -of attendees, so please email Dan Gohman if you plan on attending. - -## Agenda items - -The topic for this meeting is low-level WebAssembly APIs for -HTTP (servers and clients). - -## Meeting Notes - -Attendees: - -Dan Gohman -Syrus Akbary -John Plevyak -Pitor Sikora -Alon Zakai -Mark Nottingham -Leif Hedstrom -Jorge Lopez Silva -Pat Hickey -Johnnie Birch -Roberto Peon - -Meeting Notes: - -Presentation: [Proxy-WASM: a “standard” WebAssembly interface for the data plane, Piotr Sikora, John Plevyak](https://docs.google.com/presentation/d/1QMGEuVD9p5iNbzxzgT4p2PXpxg1MjfSbpbJdw6g6Q_Y/edit?usp=sharing) -Resources: -[WebAssembly in Envoy](https://docs.google.com/document/d/1HLV35OZP0A_a8dVjDo4kwTsovDkaycS83ZLKFpG9W8Q/edit) - -Described the envoy use case and then reviewed an API (logs, network, http, etc) - -Dan: Is there a main function? -Piotr: No, there is no main. The module functions are the entry points - -Dan: How is `__post_instantiate` used? -Piotr: It’s an initialization function which is called at Vm startup, which may live across multiple requests. - -Dan: Does `proxy_set_effective_context` imply persistent state? -Piotr: That’s an ABI design question, it could work that way or by passing in the context to each call. - -Roberto: Is there an api for caching -Piotr: Not at the moment. Not supported by envoy. -Roberto: What about streaming? What if the data you’re receiving is not in order? -Pat: We have a different proposal that addresses this. -Piotr: We don’t have an answer for this yet. - -Syrus: Have you thought about using this proxy api on the client-side (browser, [via extensions](https://developer.chrome.com/extensions/webRequest)) as well? -Piotr: Our use case is not focused on that - -Roberto: Are you thinking about having a Session abstraction in addition to Connection? -John: We don’t have it yet, but we may add it in the future - -Jorge: Version management? - limitations of current toolchains mean that the abi version is encoded as numbers in a function symbol name. But this can change as tools and standardization progress. -Pat: optional imports may alleviate some of the versioning problems too - - -Presentation: [“What HTTP Needs from WebAssembly”](https://github.com/WebAssembly/WASI/blob/main/meetings/2019/What%20HTTP%20Needs%20from%20WebAssembly.pdf), Mark Nottingham - -Roberto: What about multiple headers with one name? -Mark: [paraphrase] we probably need to talk about that - -Dan: Does this include DNS? -Mark: Yes, the API accepts names, and they are translated implicitly - -Discussion of optional imports, which will be important as different use cases will need different parts of these APIs. -Spec: https://github.com/WebAssembly/WASI/blob/main/design/optional-imports.md - -(general presentation of the people in the meeting) - -Dan: Could you use this for general-purpose HTTP programming? -Mark: Yes, there are some features which are proxy-specific, but this could be used for clients and servers - - -Presentation: [WASI HTTP proposal](https://github.com/pchickey/wasi_http_strawman), Pat Hickey - -John: This concept of futures doesn’t allow you to chain futures, right? -Pat: Yes, this is a difference from JS futures - -Pat: This is a low-level API; most customers would be using higher-level libraries on top of this - -John: This API allows you to decide what you want to poll for - -Pat: The `future_close` function allows you to release resources - -Roberto: How much would this API change if you had threads? -Pat: Our goal is mostly to have threads in the background, so that users don’t need to worry about them. But some users may want more threads in the future. We don’t have all the answers here yet. - -Alon: The `request_new` function takes a string url; how does this relate to `path_open` which doesn’t support absolute paths? -Dan: That’s a good point; one possibility is to change this API to make URL access more capability-oriented -John: That enables nested sandboxing -Alon: This model entails some overhead. If every WASI API uses OCAP, it could add up - -Action items: -Dan to post a skeleton Reactor design document -Dan to finish WASI modularization API -Pat to make a Futures proposal -John, Piotr, Mark. Pat to flesh out their API proposals offline and figure out next steps diff --git a/proposals/filesystem/meetings/2019/WASI-10-24.md b/proposals/filesystem/meetings/2019/WASI-10-24.md deleted file mode 100644 index c9dae6238..000000000 --- a/proposals/filesystem/meetings/2019/WASI-10-24.md +++ /dev/null @@ -1,171 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the October 24 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: October 24, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. WASI and OCap - 1. https://github.com/WebAssembly/WASI/issues/109#issuecomment-541191297 - 1. https://github.com/WebAssembly/WASI/pull/69 - 1. "Handle" terminology - 1. https://github.com/WebAssembly/WASI/issues/62 - 1. https://github.com/WebAssembly/WASI/pull/117 - 1. Quick ping on reordering `clockid_t` values - 1. https://github.com/WebAssembly/WASI/pull/112/files - 1. Modularization update - 1. https://github.com/WebAssembly/WASI/pull/98 - 1. https://github.com/WebAssembly/WASI/issues/2 - 1. Some good first issues - 1. Make __wasi_linkcount_t 64-bit - 1. https://github.com/WebAssembly/WASI/issues/70 - 1. Incorrect size returned by __wasi_environ_sizes_get - 1. https://github.com/WebAssembly/WASI/issues/27 - 1. Make clocks/random into capabilities - 1. https://github.com/WebAssembly/WASI/issues/118 - 1. Should random continue to be `random_get`, or should it become - `fd_read` from a special stream? - -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Mark Miller -Mark McCaskey -Pat Hickey -Barbara Nichols -Andrew Brown -Peter Huene -Artur Jamro -Till Schneidereit -Luke Wagner -Yury Delendik -Alon Zakai -Alex Crichton -Aaron Turner -Jacob Gravelle -Wvo -Sam Clegg - -Meeting notes: - -Dan: First discussion is WASI and OCAP. We have Mark Miller here. First off, what does OCAP mean and why is it interesting, and second what do we want to do. Mark can you please talk about what fine grained OCAP means. - -Mark: We have to distinguish two forms of fine grain. What is the unit of computation being protected, and what is the nature of a permission that can be separately reified (turned into something that can be passed around). Wasm has a coarse-grained unit of protected computation - a wasm module instance. It has a flat address space (two: memory for data, and functions, are separate). All toolchains are currently built around the assumption that all Wasm modules that are linked together share a memory and function table. I’ll introduce the term “compartment” for all Wasm instances that share those address spaces. Inside that compartment, all computations inside are vulnerable to all other computations inside. We’ll eventually address that better with the GC proposal but thats a way out and we wont address it further in this conversation. -The other issue is what is the unit of passable permission. Thats permission to access outside resources and also for units of computation to effect each other. We’ll assume that there are a set of separate compartments that are units of protection - their only initial relationship is through imported and exported functions. As far as the Wasm mechanism is concerned, import functions between compartments are a perfect OCAP protection mechanism. (details this by example) -Currently the only things that Wasm can pass over function interfaces are numbers (ints and floats). As a result the permissions communicated between compartments are only communicated statically - you can't pass them dynamically once compartments are linked. So you can convey permission at whatever fine-grain you want by having many different exported functions. You can use procedural abstraction to attenuate permissions, e.g. you can use a function to provide an abstraction of a read-write file as an append-only file. - -Dan: I want to temporarily ignore address spaces and tables: in a world where we have references, does it make sense to talk about compartments still? - -Mark: Current Wasm architecture plus references still has flat address spaces - our current toolchains push us into it, there will still be multiple module instances linked together sharing address spaces. - -Dan: I’m trying to hypothetically see if we take address spaces out of the situation and have wasm gc everywhere, are compartments still relevant? - -Mark: In that hypothetical the Wasm module can use the memory and table space as empty, and Wasm becomes a fine-grained object capability machine. - -Dan: The question that came up on github is that we currently are trying to do much finer grained permissions than the function level. - -Mark: Yes in the hypothetical GC situation you have capabilities that are fine grained at the level of the objects in your programming language - -Dan: How do we bridge the gap between the situation we have now, with these compartments and the failures of granularity associated with that, and where we want to be with GC with finer grained permissions. - -Till: What about the host? (I didn’t follow this close enough for good note taking) - -Mark: There are OCAP languages and operating systems, and research on running OCAP languages on a OCAP operating system with a bridge between the language’s idea of capabilities and the operating system - when you’re writing in the language its as if the operating system’s view of capabilities are just ordinary programming language capabilities. - -Mark: If you design that all interfaces between compartments are designed around reference types, the inter-compartment protocols that are natural to future GC based compartments. - -Mark: Even with reference types, the notion of a virtualizable capability is the natural way to express capabilities in the - -In the Wasm GC machine there’s support for both virtualizable and abstract datatype capabilities, theres no penalty for virtualizable capabilities and its quite natural. In the current world the only way cross-compartment is abstract datatype capabilities. That’s going to be an impedance mismatch. - -Dan: I’d like to steer this back towards what do we do with WASI right now for languages that don't have GC or reference types. Its going to be a long term problem because we’re going to have C/C++ forever. How can we deal with an integer based approach that can approximate reference types in a useful way, at the penalty of being coarser grained? - -Mark: Let’s take very basic C++ as the representative (worst) case. There’s two approaches: one is the approach the Cheri team (University of Cambridge) has taken, they’ve added reference types to existing RISC machine architectures as additional instructions and registers and used that to put protection boundaries inside existing C/C++ code. They built a compiler and LLVM fork that can run in two modes: one mode every C++ pointer is turned into a Cheri capability, at which point you’re treating the Cheri hardware like we’d eventaully do Wasm GC. - -Dan: In Cheri pointers are still bit patterns right? - -Mark: Sort of, in the other compilation mode: in that mode the pointers are still bit patterns that are readable, but the capability gives you a range of addressable memory (which is potentially very fine grained) that is valid to dereference. This is expensive and not really what we’re doing with Wasm GC. - -(at this point i lost the ability to follow and take good notes) - -Dan: Any solution that involves users annotating their source code is going to get a lot of resistance from our users. Any solution where capabilities are held on by a side table and theres bit patterns in the wasm, is better for C compatibility but not the best for actually doing OCAP. Cheri is cool but it doesn't magically solve our problems here yet. - -Mark: A completely different way to approach this issue: Let’s say all your inter-compartment capability interfaces are defined in an IDL, and then we can generate (like capnp) bindings to particular non-capability-based ABIs, so only the code generated from the IDL directly handles the reference types and does the context switch between compartments. All of the C code just uses the C ABI bindings generated by the IDL. Those ABI bindings use integers that require the capabilities be looked up from tables - -Till: A lot of this is actively in the works as the interface types proposal. A lot of these concerns are actively being addressed by how WASI and interface types are developing. The biggest thing is that moving capabilities from being expressed as integers to references, and all compartment interfaces are in terms of reference. Inside a compartment you can do whatever you like. - -Dan: We have an IDL now where we’re moving to talk about APIs in terms of references. At the WASI level we should design in references using OCAP. - -Jacob: In the interface types polyfill we have a way to automate the side-table translation so you don’t have to even generate glue code, its just done in javascript (the host) for you. You can add an interface instruction to convert an index into a ref. This lets us use C without annotations beyond the toolchain knowing about interface types. - -Dan: Next topic: there's a virtualization doc that is coming along, and a paper -http://www.cs.cmu.edu/~aldrich/papers/ecoop17modules.pdf -(summarizes part of paper in way I couldnt follow for notes) - -Dan: Mark’s idea of virtualizatbility is an object with vtables inside them. -(more discussion of the paper) - -Mark: I’ll have to read the paper to understand this fully. - -http://www.cs.cmu.edu/~aldrich/papers/ecoop17modules.pdf - -Mark: Just followed the link, I know this paper. The language in the paper is fine-grained OCAP, individual objects are vtable-like. In that language, there’s still an issue of how you start the world off - a static configuration with good safety properties so you can move forward with dynamic properties. This paper is about the initial permissions with least-authority linkage between the modules. It is in the context of a dynamic system with full fine-grained virtualizability. I don’t see exactly how that addresses our Wasm representation problem, we still cant use references as fine-grained virtualizable capabilities. - -Dan: I think we should table and continue this discussion at a different time. I’d like to go to the rest of the agenda for the remaining 15 mins. - -Dan: What do we call handles, or descriptors? PR 117, or the last comments on issue 62 on file descriptors vs handles. POSIX has called things file descriptors when they're not really files. I want to talk about OCAP capabilities as handles. - -Mark: Historically, descriptors and capabilities are aligned, and the numbers you are familiar with as file descriptors are often just called indices, so clists are the list of capabilities and clist indices are the file descriptor ints you know. - -Dan: We settled more or less on Handle as an identifier that refers to a capability. When we say handles we’re just saying the OCAP sense. Does that make sense? - -Mark: Yes! - -Dan: Let’s call that a decision then. - -Dan: Witx files are up in the repos, you can make a PR into the ephemeral phase and we can then promote that to unstable when a decent number are landed and move on to implementing it. - - -Dan: Moving on to the modularization update: look at PR 98 for the basic change. This wont be the end of the story for modularization, but its a logical first step. - -Sam: Does this change the import field name strings? - -Dan: Yes, right now “wasi\_unstable” is the module name everything imports from. - -Sam: Yes I see that there are N different modules. - -Dan: Does it make sense to limit witx to one module per file? Wat only allows one module per file. - -Pat: We have to figure out how to deal with type names being global, we’ll need some sort of namespacing and import mechanism. - -Dan: Ok, we’ll figure that out and move forward. - -Dan: I put some basic issues in the agenda that are hopefully straightforward to implement. I’d like to encourage more people to step in and make PRs on the witx files and get involved. - -Dan: for example on the issue about using capabilities for randomness, we can propose solutions with PRs that change the witx. diff --git a/proposals/filesystem/meetings/2019/WASI-11-07.md b/proposals/filesystem/meetings/2019/WASI-11-07.md deleted file mode 100644 index bda872b71..000000000 --- a/proposals/filesystem/meetings/2019/WASI-11-07.md +++ /dev/null @@ -1,102 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the November 07 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: November 07, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Publishing a first snapshot - 1. https://github.com/WebAssembly/WASI/issues/138 - 1. Issues for discussion - 1. Make clocks/random into capabilities - 1. https://github.com/WebAssembly/WASI/issues/118 - 1. Should random continue to be `random_get`, or should it become - `fd_read` from a special stream? - 1. Increase the timestamp range - 1. https://github.com/WebAssembly/WASI/issues/33 - 1. Remove remaining "process" dependencies - 1. https://github.com/WebAssembly/WASI/issues/26 - 1. Remove `CLOCK_PROCESS_CPUTIME_ID`? - -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Stefan Junker -Mark Bestavros -Nathaniel McCallum -Johnnie Birch Jr. -Mark S. Miller -Alon Zakai -Yury Delendik -Alex Chrichton -Luke Wagner -Mark McCaskey -Pat Hickey -Sam Clegg -Peter Huene -Alon Zakai - - -Meeting notes: - -## Making a first snapshot - call it “snapshot” - -AI: Dan to add a note to the phases document about how we make syntax changes to old versions while keeping the ABI compatible - -## Make clocks/random into capabilities - -DG: Currently clocks/random are ambient authority in WASI. Can keep compatibility with (C-style) programs out there which expect this to be the case? If so, how? -LW: Would this step mean that the program will always ask for clocks/random with the future option of allowing to not ask for it? -DG: What troubles me about that is that we’d still have to think about the mechanism for asking for it - -(discussion about clocks/random as stream vs. datagram) - -## Increase the timestamp range - -DG: this would be a good opportunity for someone who just wants to do this for the sake of learning how to change the API. happy to talk about this offline - -## Remove remaining "process" dependencies - -(discussion about exception handling in JS when interacting with WASM) - -DG: proc_raise is going away, proc_exit should ideally be implemented in terms of unwinding, though there are some details to figure out there. Can we remove the process-oriented clock identifiers? - -(Discussion, concluding in general approval) - -(Discussion of whether a “gas” clock could be defined; see also - -https://medium.com/@erights/a-pack-of-watchdogs-is-cheaper-than-gas-7e118edfb4cc - -Answer: there are some potentially subtle issues — programs could use this to determine how much time other parts of the program take, which may be undesirable. In any case, WASI itself would have no trouble defining new kinds of clocks in the future.) - -NM: Our implementation is able to implement the process-oriented clocks efficiently. If we remove them today, could they be reintroduced in the future if we want them? -DG: Yes, once we have modularity established and optional imports, it would be straightforward to add new features like this. - -NM: Is working on a proposal for a high level crypto API -MM: A request would be to not have the keys and algorithms in the same address space.. diff --git a/proposals/filesystem/meetings/2019/WASI-11-21.md b/proposals/filesystem/meetings/2019/WASI-11-21.md deleted file mode 100644 index 005585876..000000000 --- a/proposals/filesystem/meetings/2019/WASI-11-21.md +++ /dev/null @@ -1,63 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the November 21 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: November 21, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. `wasi_snapshot_preview1` update: now live! - 1. wasi-libc update here: https://github.com/CraneStation/wasi-libc/pull/136 - 1. Other toolchains should start moving to it as well. - 1. `wasi-sdk` and `wasi-libc` will be moving into the `WebAssembly org - 1. Discussed here: https://github.com/WebAssembly/meetings/blob/master/2019/CG-11-12.md - 1. Modularization update. - 1. Link to be posted soon. - 1. Calling for volunteers. - -1. Closure - -## Meeting Notes - -Attendees: - -Pat Hickey -Jan Falkin -Alex crichton -Jay Phelps -Andrew brown -Luke Wagner -Alon Zakai -Dan Gohman -Mark McCaskey - -Meeting notes: - -DG: WASI Snapshot 1 is out. - -DG: WASI-SDK and WASI-libc. Currently in Cranestation orginization. They will move under the WebAssembly orginization, that was approved at the last CG meeting. We just have to work out some minor licensing issues for that to move forward. - -DG: Modularization update. I don’t have an update, haven’t had enough time. The current PR shows the shape of it, but it needs to be updated to the current set of APIs and witx. - -DG: Call for volunteers. I want to emphasize that WASI is a big opportunity, and now is the time to make changes. Please make PRs against the ephemeral directory diff --git a/proposals/filesystem/meetings/2019/WASI-12-05.md b/proposals/filesystem/meetings/2019/WASI-12-05.md deleted file mode 100644 index 0dc54deb4..000000000 --- a/proposals/filesystem/meetings/2019/WASI-12-05.md +++ /dev/null @@ -1,124 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the December 5 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: December 5, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Stack trace API - 1. https://github.com/WebAssembly/WASI/issues/159 - 1. Whare are the next steps here? - 1. Character encodings - 1. https://github.com/WebAssembly/WASI/issues/8 - 1. Can we decide on this, or do we need more information? - 1. Case sensitivity - 1. https://github.com/WebAssembly/WASI/issues/72 - 1. Can we decide on this, or do we need more information? - 1. ANSI escape sequences - 1. https://github.com/WebAssembly/WASI/issues/162 - 1. Can we agree on the overall framework proposed here? - 1. Input sequences - 1. https://github.com/WebAssembly/WASI/issues/163 - 1. What standards govern this space? -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Pat Hickey -Stefan Junker -Wouter van Oortmerssen -Jan Falkin -Andrew Brown -Mark McCaskey -Peter Huene - -Meeting notes: - -https://github.com/bytecodealliance/wasmtime/pull/235#issuecomment-518897502 - -DG: If people have comments on the process we’re following with these meetings, please give feedback. - -PH: I’ll second the agenda - -DG: First item, stack trace API. Thomas Lively proposed this, but he’s not in the meeting at this time. Let’s table this until he’s here. - -DG: Character encodings. This issue has been open for a while and there’s no easy answer. There’s a shape of a proposal in the issue that most engines are following - we say that everything is UTF-8. Is there any disagreement with that consensus here? - -(none) - -DG: For things like environment variables, it would simplify things a lot if we could guarantee those are UTF-8 strings. - -DG: What about filesystems with file names that are unencodable? Can we find a way to tunnel that through? We currently use pointer+length to pass all filenames. No filesystem permits null in a filename, so we can encode a non-UTF8 string by putting extra information after the null. The trouble comes when you have to manipulate the path. - -PH: What about interface types interaction? - -DG: The stuff after the null will still be valid UTF-8 which encodes the non-UTF-8 part of the filename. So any library code that expects UTF-8 will still work. -DG: We’ll take this as consensus, and go forward with this design for now. We can change it if problems happen or we have objections during implementations. - -AB: Can you clarify what is being encoded after the null? - -DG: Two things: in the part before the null we want a normal-looking string, so any bytes that cant be translated get the unencodable-character (uffd). Then, after the null, we put the information that was lost. Something like, index of the string, then the missing bytes. We want something that is reversible. I agree it is goofy. Does anyone know how to encode an arbitrary integer in a utf-8 byte pattern? Obviously we could invent something, like using ascii digits. If theres an existing way to encode it, we’d want to follow that. - -AB: So we can’t just say we support all unicode strings? - -DG: The problem is that there are names out there that can’t be expressed in unicode. And from people I’ve talked to, its rare in practice. So the goal here is that if you get a path from one wasi api, and treat it as a utf-8 string without manipulating it, and then pass it to another wasi api, it works exactly as is. - -AB: I misstated my question - is there no unicode format where this reconstruction wouldn't be necessary? Or will there always be some way for there to be an unencodable string? - -DG: My understanding is there’s no way out of this. - -Peter H: This would be for bytes which are not valid unicode codepoints. - -DG: I’m looking for enough agreement that we can keep designing this for now. - -Peter H: is there currently a part of the spec that allows non-utf8? - -DG: Witx String type is always UTF-8. We don’t have a byte vector type right now, but there are byte pointer-length pairs. For any string passed to WASI we’ll require it to be UTF-8, and any string coming from WASI would be guaranteed to be UTF-8. - -DG: Next topic, case sensitivity in filesystems. If you look at issue 72, the big picture strategy is that WASI doesn’t dictate case sensitivity or insensitivity, or what variation of sensitivity it has (because different filesystems have different rules, whether they case map ascii or different versions of unicode). I think the point of the API is to interact with existing filesystems, and we can’t control those, so this is going to be a portability hazard for WASI. We can make tools that help you detect these pitfalls. Does anyone have ideas of how we can make this better? - -DG: Ok, so to use the wasm scary word, it is nondeterministic to use different cases to access the same file in the WASI api. -DG: Alright, so the next two issues are about virtual terminal handling. Its a space largely defined by compatibility with existing systems like xterm, unix consoles, and windows consoles. It makes sense to have something simple here. You could imagine unifying terminals with GUIs, modernizing terminals, lots of blue sky stuff here. My sense is that the value here is to find a simple thing that will interoperate with lots of different existing systems. - -Sbc: Not just to interoperate with existing systems but to allow existing programs to run on many different systems? - -DG: Yes my goal is something like vi on wasi just works. It looks like lots of people don’t use terminfo to figure out colors and just hard-code them. And windows support is tricky because it doesn’t have exactly the same features as unix. In cases where the terminals differ, should we expose WASI programs to the differences between them? - -DG: The direction I’m going is we don’t try to do terminfo, the WASI implementation will be responsible for remapping escape sequences and all that. You could imagine having an environment variable TERM=WASI. It would look a lot like xterm, which in turn looks a lot like windows. - -DG: On that topic, input sequences are a subfield of escape sequences. Input varies way more than output, across platforms. This made me think we could do a cool radical thing like use unicode symbols. But maybe the simplest thing is, just do what xterm does, and if it needs to be remapped by a WASI implementation to fit another console, thats up to them. But there are interesting questions to still ask here like what set of input sequences to support - -DG: Its tempting to say, we can go and design a modern system that doesn’t have all the legacy baggage. But my instinct now is to pull back from that and pick a reasonable set of defaults based on some of the successful modern implementations. If someone wants to design a whole new system, I won’t stand in their way. - -SJ: Can you clarify about how vim would work on this? - -DG: Vim itself wouldnt have to change. Terminfo is a library that gets linked in, but hopefully we could provide a radically simplified version that works on wasi. Inside the wasi implementation, anything like a TTY would have to filter the output coming from WASI program to neutralize all escape sequences, and then encode in terms of whatever its client expects. - -SJ: I would have assumed that stdin/out/err just map to whatever the host of the WASI implementation expects - -DG: We’re worried about security, because the terminal interface wasn’t designed to deal with untrusted code running on the terminal. So one example is that you could run a program and you think that it exited, but really its just showing you something that looks like your shell. We want to not allow applications to do things like that, by default. So if you wanted to run vim, you’d have to give it permission to rewrite your entire screen, versus just print ordinary text to stdout, which would be the default. So, controlling cursor position and colors and that would be exposed to wasi as a capability. diff --git a/proposals/filesystem/meetings/2019/WASI-12-19.md b/proposals/filesystem/meetings/2019/WASI-12-19.md deleted file mode 100644 index 0621c97b1..000000000 --- a/proposals/filesystem/meetings/2019/WASI-12-19.md +++ /dev/null @@ -1,44 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the December 19 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: December 19, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Stack trace API - 1. https://github.com/WebAssembly/WASI/issues/159 - 1. Whare are the next steps here? - 1. Windowing and Framebuffer APIs - 1. https://github.com/WebAssembly/WASI/issues/171 - 1. https://github.com/WebAssembly/WASI/issues/174 - 1. What guidance can we give to folks interested in working on these? -1. Closure - -## Meeting Notes - -Windowing and Framebuffer APIs: - -There's an early demo out, and it's gotten some feedback. Aarron Turner is -working on incorporating the feedback and putting together a proposal. diff --git a/proposals/filesystem/meetings/2019/What HTTP Needs from WebAssembly.pdf b/proposals/filesystem/meetings/2019/What HTTP Needs from WebAssembly.pdf deleted file mode 100644 index 7aa294ee64e815455dd95821e1aca68f98bd9fcd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82687 zcmdqJbyQtTw)RcX;10pv-QAtw?(Xg`!Civ8yF0;yTkzoS5Q4jZz&Yu@N5&of-R^(h z9vLH>wRi2gX6;q;sb9$~A{jwpDmrRL2qN5#&9Ny6MhIF6YdtdvPEH6K1y>tG2pR!h z2VDzmV+a~4T}wmzw-3a1opj~(?M!VPAQ)cC%Rz8+L(s_R8XHRJ>KR)6Rz}Lv(jG$n z<Q=wM-L^{4)ly05BwbHTQdQ=KoRrH}_xNdUeju(CYQ}uhwZK4Gm0n`K?{v z{G)|np{Iplq-A>Xi$=iO%HgG;Jp{{dCFKn5tsU+3U%X`f?F~LFE9;k!>1cnu6tS~* zwE0y<1v_0Udz;rg>ASv|dabmflc~O;oCyD`i~scU)%dSU37c9t7}`P52wUhn7z!Hd zTN}K%D`9A5>|g@H_I8t(@7X)NRNWH7C9PaR(*8Rw)U<>(xri5FkS4draDrtr22_9- zrb+TRHYpfr!LsgT7s}H!u5oG~**;Q31ab9)-YuD%U4m$zUNtI3kmdO40UPxMx;dE$ zctQ&@%WiWK)b5_X=!DbyA+0SlA+=N(3-NZ-SN&F*7$U1SGjHm470&y7s4aTLe1|Z1 z*9MerKGOEh69_U-7;GR*FHEC$^9J z%_28t#!YaHK`xasto&^_|7HQwC=DFUw0b=@x}k zO$DnymM%HpMSfrvJ!4Br9gU52ro@S7I4J1MH%>Yj)p z*%UityapoOZ4;e2FTIR%dte+qg4GY$d~X3ZuDTo30(gId{^0%SfY{CU!?+}ur!IPC zD(aym+DncH6-q=8{ovX~bJ~g|*F@!>z1MWeJE43I$KwN6*=r;I{Yn4coL?KjYeQjV zVf)p>-&)@5d+IOk_4i_Qe~sGzW3#7wjklKw`DeSQdkv|VcYZbe-{au_*6`oV|0^w@ z?zi~+pH06_WzlMp`NPf{M+NT!fV*E#aHG`vtxZ#Bb^3P|^RdV&#+DDvb)9QY9~+0c z`d0Ehzj{6p^@5RU?uggugyfNWZ9PANJ+-dWBXVl4?tl7 znIPj@u{$ht_T|GHUMkmk^B=~@A2*)kM~$qP)Eo8N83Y&bg$4cZR^^k9bE|&hwzD0 zSE;E7Wv`x$Dm3@OK8sE_iQ0D@{g=_MS5Q<8PMxDNKdL{?&}B#$^(UoY-#)N-(XYDm zqd-oH^IMx0D#ASD@VCHv_Jw?C+^0xo-izgPHE+CGG`WKU%tufS?^~SoO@kHwD6d{3 zE`tWuK*5PdPvL+>-O1~Z;d{T4Dd!M@tD0G92)Tv)eTU2)n8~FFCJPDZ!JE+0wYQ?8 z=q!zK7caGn?BJ3uKG{oq1OoVx`udEfV4q}rBgWwDM9LRbbuZ-$&RG&SwD zM+DC)nV=J4pb{(;0;v6$=S&kCIjM5ga$VMCIzIXbxlJ}0`QH@JuG6y}5A*TM)- zOOy*GQ)F|*x*~@)5gw4SWf&mDc430n3){(Al!}mQBUzV>(x43>lp|hr@R~k=`-$%~ zWUYC_^k1`D!Y$B}L}{X)VJZ{&Fc&LUbC^-6e2dAa}1iq>QlM;91Ls0oy~>nT6E3bOCE zKSd3}lei*D+D=K9Au-6~>G!>tVOcuM)mP5TmRAIVL4zmjIq8S#0dtSlUFXyO07(~5 zjV)rm!{wR9XC5k##E0oFT>{!HgX4=C1|n%ku?$mJ3=Wu(Y4F(G2^z_3vvt>^(+LmpA2z~{KCv0$K$ln4be~hAf)!KP#c!ps=S5<@rT%GYIF<&bW92bx`(X8xj>T19 z-UaXJ@4FFSQ0>uiuPdpHa4*;UmUwD15grQT$`rLcSC>kN zMEgj)28F4gB)4sx2$>-ir{%1OvwAj^K>K&19^|98ngVXrfg8dS<2!Otf_OX8(BsAf z`M1>`WX8K^4h@&zed)%HXw%O**b{0qO)tE4kLlblWOtXo>ywr2ParYVfyd*U=R9YN z>DLd<7s^=WCqW#CA5+$Y*J1lv+8IM2*A25HKwarXe7Sz2EIt4s%iC5%$2H)}3Fb#uOeZ}BtRG7;eQWIMT3VEEby>vVQ)EX{~@;THiat64QBpIYX0oW zS4gTCGOmBa+R7PZ5UsIaG@k3K=BGh6_fP#<;xEc>6heJfU_uSNf`FcgMFv&P-i-y% zY$k18omkrG*Sya1XMY@x=Ahn(-ksi$oO0aX6%O;wkqXh#g}(wS9bS#=}wY!fJ- zz>M;l&B&SVld064D3}dP;?E2%oAk10AhQpr8{JR4JK^#xE!5;rgYLBVn{5F^88!+o zFvn}XgD^Jm-mw%OU>DSElBV8iR(i5Or)k&WliJk!5KE1FRPX-=Mqz)k`oSD9P6Tfcttgwu3t_Z!D*vilfvJL>6*0fN2l zE3j{{Z4x*>=zqZSab(Gcl<25KcU$u-g(O?Nny}8ygk8>v1u6+$VmUZnqHE(zyL99Hn+)`OySjup7B6hS(QYVUa<(74Ue(D;2v5ykSAU?5EO>bX^L%{O zPc77^>rDnwS?=y)S0w&WJWFQ};mO`r9F5&VctKp82$l$G*p1k7zgs^YVsh)Ue(E3o z9(4(O$n^gfA-|dbm&EmN z2w7>-YKj+5vuCmWWB~S)AfLrGy}LVbez83HL|AGaBPXtmdUjoO7eQtxn7va(HDX~7 zaHDE32lm)q_}I76(KHG?S9BT*pS<3O)0nX)B)O73-}pGHgk#;ff{#{dmr^_1wL8Ke z56Hk7+8tsmP(8XT0qA#AD~+^ixJA95px=v&$PL|N^c#B+qXy2S>u(2CxK~| zGByF|Z~I9|0Cb^aIeug^S0HQ)S5>SuXY~GxkOt1w5fL|7ZaryHcakD%YX=9gi=KK1 zi>jSiMN@gZb22>bJQ9IQ{K!Z%hLW4~fQ!)C^8t&dlr}!|hT+P;t(R5jcuwF7>6|%L z3Xh#xSENh_sG;9!o_leAZQHnAvEtC@lrV03q2emn>rq>!S+aFt@B`|mVyW7x9G|;6 zD&UOVqexF&0>1EB!wUT<7=5UcxF#smy5aCvF>V>7Y%{Q5+YJ6u=U7U!R&-fqyWzVn zB-fm1D3F>>JcLbv*>@bBt*K1vKa(PuV-gV(2VKw2R+Z;HVG5fJ^bha!=lnL)s*82fv`x%K(@vnHVw_UQ3WZ zeiJ2uO~rRAd&^mtz;0OB&HVTAFCc5<3E8vCMk?Mzkh4d}4?15i z^}=P7FB{zWwzs^q4)D6rNc1$2D;TN3N&L=cDo7g*?!fl*UWUG)80o!{=ba{|RxxZZ#L<3~CdWl2Pol)Q$ylcF2@m zG3auA&$#`>LvnM3XVPKz6~U=;AxM&*p()Hu&EJRS?a$D^NlT(PV5@;K@+D&K0?stk zfCX??plMb&^-m5}1nuRT)cg2u7JbQ>{H%oSKm`%~j)TBdD&)ZToWLz|fX5Y!-v_@Z za>l9=rsb;ymj^hT#WC4j-=>?P9G$$>U8v=BC?eT9-}r_SG{%;r>3v86gGDt*uD&2} z#NPSwxaxO6Dk3&xB(U4EN8dfkAmuQl0aF8b#0azzu>{2Ed1LF{S_fleb=dqb#xbA7 z0-an-rpNpukvYd7l_*f`&<^V$rav(mFsKE=2?WByj+T77l&zrvl&t}H?^^N}%zx4nhW{8fF#LrY82(5N4F482yqW)(wB&E7 zL2>v+OOTjS(piFuyvK2E9=)o7Bqzs(&0?ft&eU*aFkYFV@C5beEq5eW^5~YVY*(-f zqV{UjRrMH`eOsQdE&5{Z>|@XRaXyLGJ|s`N{&^7ETMw>I?rCz13W2Ah7H3M%JpptUYd}asVCSzDO_v;v*H>u3 zTaX94D&NXMuxkK%&&K9s9rFNDEnoL;AHR7uyVrPu>S`scJ_aqnX}N90?3O3mCDXxd zSU^SEc-t&b-eo^rb=bK35*8derWUS_VH(vieO7!geTLajPQP06%-=Y$6yOZNPr90K z$qxtFu^bmoIl~akzm)?wYJe^yNJbcT=mS5442S|^Jp!^kuYl(s(T@Q{AWg#$>9|*z zpJhFlky2x4T|iH^^J^wkM1nCsYnxt`=1ppaa(6$w1jMf&CK()N&ZdlIPk-_1-zr9hD1+TRRup-#Ycl~6%@BzuxNDs&j9 zAx@$^YUVa|d#wl_MvG;Ug$`;Zv3XT0&L8indD!Zbr@H__HA9ope{XhRMXQ@ET<_$> zveh<)vS_U?RnYo3k@>5aXJ+_EFaH)Ae~!%mSTE1`mtLOnkG(wOztzjXng3TJlku;; ze7T~e^-C{bU)R`VvkR4@-ZQg`v&3tPkP^&%*uY1G30D*$qb9npeM;hbWmKEWh)hJ7 zJGXf{$KW-#nI22ZD&(q2mV$AiZDk_Wx~2hq06jaX?+H~nw;Wy5_cCf5OYzz2+b{ZN zVhOiM7O{`Qx8rbPbftfnJas882uE*%m*&pf*0Msr6<2X(3Y^@CABsc=-heEp4r{#5 z86}GAFH1j=U^DOyBG<(CW2H1$*qczwiRt{nc39@dnDgXR=V-ewL z8w<;!WA!N}Pa}InTF$k8Nbj4#L02i9Z+=Zq@q;*yY1E?;n)@iHJzGf9HTJL_J+bN7 z9Nku&W|whhdMyk_HEfkbR%2UpG-ir^8Cx4Ap7~m%Ti^3>$SY?!YEfjf zm|erip{H6lgS`Kwr`h%nB|QC8ad>(*mymm!aAL^uY0Q*>4Ns2-?A-xpjY2igAmZr+ zo782@IT;Ex%0)+i4Xg9#pU2}))gy4V(^tkPp;x*!k#n;4vQBn3g_?MrRT?~xXI(#` zw5^Xf4-(?(lh?`w(%NGo%;^U|tEafe$YATx`#Qvw7}pgQz9&#JqP@Ut^S^wIDaEW+ zD5%x}qab4S^@>sYj>-7sspPxB$|4ma2vdV)57!BgU$!2lFj|V_Jme3uG)dNmw*iy! zKED;VU53=rJWs@K|Gt|`>!87Q<^xgUcRLy@~dY7aQxoST}DDJInw7e3Wkt@iA@Ug~8ieCb9jm7B7fIv+QQ(&a~4 zQ9Iqb9nq`j`mzQ?(ZJ+zC~<{ zQ0r4G!WIaZw-l_+he@brVk&h*uR^ZEyal;?^k#bdm#kX@Z)Tzb8>$j(}bxw z&z!CwBbILyxi^mqc31k!ktgVcGbd)CpGb^R_gejcB+ta*i&v@*Z&35HM7Wkd{W zaoh2(PFV=D)W)yQu=YchnW(Qe@np>>etE#5bVIeO-^OEXqEcY83P>DH0&QZN=Bc6} zG{!SA4n3(EH79Z?t+U`Ou2#XA2H+KBHf;|m?>Vs5djfv2@_F>s2#TJ~TJ(2H$q+i8 z>-2%Xzqo%t}<7tI{w1Xdeqo0-QHxLu}&4xgW5?NFn9!0SWbMSb|iA!gL##~~m; zRGNr^|FarYD9k#g6H)r)a8h~~ZaB2Ek2<-Yk_7dz;b1;5 zxer22#htAylLF=ncO*taW0-iyi};I?L%QmQZ0f0+qJ)j4ZVC@&2NW`gF~cO2izbmE zZ7)J}hS#TvZzm&&e^jtB2NpQ2pfF}4iZO%pZ7HHGY$P|Il3kRYX%YK@yhs1;@xf-= z7MZMZ1$3_OB>mJp)dy~4!4Xj0&<~(Dtw~mCNUVOLg6VtYeAJsLOok(6T^p7HNJYW)87z%*V}jz?^r^;)eA_ocDD0x z#OD_)urf3LLwx>bVTJKO#tKY-VFji?vI5h;#R_lc{}u6J`YS86sjONrGQ;hxu~_j= z04`276zUWuN)ic$#$mItHeh1dr`?LAIKg&@GJjaI+P^CNX+6K%cpRBP^pQEmtwulv zUz#wg^|)n|?pjVnT<(@zp-lYb>9D*tkz7vPm|8M!8~c)(ed3^;k@{5X^h9w!SaE|& zQK@DoYd2kE$XUjYCiAiC?)*rZX!QXEntilvX63lJ-P=BTh~xH7olU5z(&T&DXUKx- zYDY45^Gxy@U z>Vvw35=(|uu3)kRn;ejG*@vT8Z-}Y-9I{hg8g=ntK?vaF&_tS+Np+)sf|DIHDnZA0 zITw6IY{B(VIhhk*P*8PLA~PUG-J-W#u4P-+@qp^6`LF2;e&~NqFchQ5NBbySxhgxk!Gp(Me#mCw0R3ybS54yX16OhiMl-C(^7*Sask=+p3UB;w%HGq zr(QnB@a%gSVj`RyD0BYR`Uz1zyBpvc+I8UxA1#0@rzI({!OJPR-l;hfy`!qNZDKf$ z2-cBajE+x&X4Q%EnRPhS`Y2qj%m(a>Lp4F6Ge-f`c9T-=9zLV*Wcy`@>1#m<_z&+{ ztNCv57}VHCDC$Li49!|r>j=OeWRZlbCGtz*8|L*pr@1d{5!b!a82TFgD}HGWE1gmU zP%QY?$g+hRTWMntk>!{nc?J&!81Og@nf|Khthv5swa)uV+OsZ}`8nF_ic=V+58dtG#n{v+** zqYf*KWC!V1RA3m)1%bXh?Y4?7iDFjF@4)yo8cP2aTp8(xHyQ+v4Rc+(tPwH&XcAU| z<+@dH+I6EIZm3q)xC_Dk-V`@SERbAgS=2eX7Xj%WU z`RGmG{={}nuSE7swf?O=cTB&N+&?!TG5tnazcwE+y(;<3UZnrqy7im+UylB7+wNXi z_VqS@ShrSMmP4fb5HZ#AHJttoPQh^Sc`RSb2QX4iLoMEIeGgz0sctX#hLSUL_hZYl zWlOjUYU=*ZVk`~YynW0_WYag`!Wu5{@Twvn?K3*mWH|a}od7YkuxrtrA2H^}ZHUG9 zMXj=3ZUUXbG)v=`zOXmQqJ18_w|n=!B%Nd4pMINfO*pypAR2=7y7Ir4=|dJy{vh93 zC5MI@P3Z}j2Tb}h->R4;3y!ufBq1|VDQILMSSXNfjYeb}hEY;K)JiXGw+Z)YG@h*& zN8aNz0Z+#chx=-U7kPze!G58O7xOXxNOuzD-iO@H+n$04$W^^=DyN~98vPk#%^5ue z*(ff(Zf5t8tZpr!I+GuTd0OHJjjm7e$2%0#{SfgWrv9aw3Um)Rge_sNFB^?^M<}vF zUFk`!57XR{_i%p3iW|_OTZcVvdeEw+ESRYB8PckxC*pohpdjK1h?PzjnXr_=LQ_9E zeE)PQdtFd~t-z_NpGx}_S5CmKdV#6}cFO(3EVH?l>HG01k8U>}#;2G`*oko=RB<)y z^C(UpLLLlP4;;fC|2iu%|M_N9e=u^jY=RjR8%R!AFQy>_F6xhjCui@^_@+|{IR{t8 zCIos~eqw#M>V)D4B^9-JM>q&86RV9g`JPMAgcDTsV|EySUrfldQ6|vXTG^!0t?tnv z8ri0Il~G85(;|bY7sH}?9pY8>1+3Bg!_>Adpn1kmOAdzs?(z6`J0sr%QEJ$~nxIZZ z{>al38LScbUcL|697X3m!K@0X+2Au1fiz|Ajx)e)KVr>VTASrxA=@HbuFtM==_yYN zB5k|nA1IAkE)b08C-E*7SI2BWR}dI;UC~CtS6qkQ3<71jbZs@0^8+Engpd{78pgog zv=nwRiE(4a?6^^%7{M+N5%c_};&OAk)WinE#E{!02ZqQt3r+pi>EA^8FJ5AyqyNQF zZ&CKAAZLChpI@=_Zv{E?@5J=aAZPxKW_|_v3(Wl+LH=g`m!tn%kTd^=YJUiF<;6%0 zAvnveMq-3_+lX*#xwMPd8D4~E3oDuwD~=xO2-t9>s(2(-J|f(HJnv3D(@K)7`!m47 zBipQ83!0k?OPi%Mn~(EGTpX*+73FHZXe=CzLrwNltYdk<2k$I`vr7p8{Om zF6`~@U7k)Sb*SrjiFgFDr0HtQBWTp({mPjL}mA66iG0NMNJrXE0#Z;q-}6@XYrn*Vn0h?SC97|4wy05MLQ2Wlczq-Yc2(%Ns| zkEs)P+D>}DE{XOjj$*%6)~lWy)QgPL3g!S2tO&Bg!*3I_BYc_5wd|O**VC|TL7x9Z zZ7H;CxCO72b1$>&z`d$nLkHz`BO8YzlUL98wW=GU#M>@KbPTqykNpdr(ym79F`XEK z!dnMbL$Xj zm;?70Iq<*SBd8hT5W?^)Ep41=AU|2hmAgk({)F~7(_3#E@hT>Cv@iQIeqShh)2Bbn z)XHf!=XDD6>GZEB|V3rL-1W#!Y~uC5%$G8mSp>`5H62{l(0unIXB zGFJyUiXrkHU&RV453&z#C!!k(=%r}Q>YfC#^8>b^Aq zpZb8G=pI70pmr!N9Z__X#L&lvLPOHvv*qFO?F^SOfz1tLf453E;K)71Sn*4q#?Mc? zGMt3ZaGZ5*aImhpx%!M``G}CpX&t5vNxndC!aGOq}3~j|7xP^6X`W_UL$sxltX(qA?9w(U> zQ&bEmNNhFTWI+A^ z-aW(7dNgP*Sz#A`fgcNa?B-OnIO`&FKxz3nsep06xC*Q_#Phu_v@k^C=P#J-+@Lte z&MH$4?1u|dLlHC@<5I^N)jY_V%ZZiOEes8!eTJ1S>0Y$94v#=VSL`}}g+=CHut-Ns z`;Q^vn;!j14q5(Vw8-)oT4ebnEwcPuwD@NJUy(zWztUoF(yBEk6I?&l_J|<9P_Q#L zF9`T7c9eIUf{dp9?A3S13$MIrRA4g#2dcc2=deo8`K6=70@TPaX^vXQWzNP|47IhJ zZE?b;$&1bh@63Y^E3LQlzl)p4dN`yEhaY-M45cxoo^`^O^3ZrqoQ-IY>yTE{;Vsd6JR8x(qn=$ho*^C9d&)I2>*iutfGS=^QW+1moO>eEw1Ej+k#0DxlPh}gyA?8leefrtv zVe`=6(jm5xW%2Ymt?kH-Zn3j0N0Q8yO})kRDz%lS9mU?3xK9rs#vk?L&xjuB4N(&d zX}tUDi;t&e-)`Z!z33vXPAYnQ0%m3ugaO=ur0!GU1O|gOBe?r6zXUpktJy(+pIQ0lTxE zVMN>lXV!go-NB-Ip*guNW8s33Rb&*lB1zlv-jg7;|kV$;Br9}yY zAPrY0n(9Z1z}`3H$t@BYB%&Rjp9&EiJt0wcA5oArHQ9GvFT zAYos{MY}xBDP%hr2oi^FNs_Xg4|UCVWJ{fjAwrUo0x;PG8kD=@E~F&Fs3fL`*&u}B z{kp1L9Ys|HIK;w-UF2${DJ;n0a0^=1izkX7T1tA%xF{otRkn>YR&>exTtI0 zx6|_m|0bWePbQOD7UoBWJv$Y%PGY!l$7K`#Aq`a(TU+wm;IqZ^#S`Ag-`evBV!p20G_9b2Aw_*6(B^|_@m%k_a+F9$%8#=rs zAkw@f55J@d8@f0^(1=;SB----{wnbMtJrV3zQ1bv%C^6LkN=k|@|I5XUr~|&mM8MI zGxxvYiM(wK{BNkp+b*jAii-TV#K_xP^?$Y%I%=dpqMSg9?_VJJgO@W=OdVXQL|>0IvDbg$IbAD<*KfTZ@xt=kl;z9mDGJt#R;F(!n6Ugd zY57meeM8g#yFXN7FNe^W>i_?7i}kn7I)8AB^*5;fr(17~{C{#w;N@HxQ$sr`L+5|} zmty^m&;RJsKPdfoN`Cw4e!29&tzfbKb&A$dZrI9?7OwRinY$q9y@lw4==)-E#Sj4; z@O9e2l|am!`-K)Ubh(c@Moz}Y5iHBI()EYL3GMfMEVR`PwSC>Jm~Eg1Yvc3& zkVfoW>2U3iG@3D>whU2-7xk7wd6cSm@V=W{#tm+ae!eY)p68$*#;_Kb_11t^k)w~i zuugiaa*E%0F(BGRugTqY$cAR>!B4GHX8Fz&PuVzh0O<;iE_8GpE5>m!52VWfGfmpNIYtF zr+$}|F5fub3@tx`hQ>h$m)5G z+U<{1QGM%IXP*;wk2tK8ua8=;(^gfFno#}W`60~sFeiGytfogJ>jea zZ}Y!eBRDA?F(EM%=n#0v2(@ycc41$K9%4d{*#x5b9_L-;GiDHkWf3|T#Ni3)0@$pU ze}za(G!7V~b`Hk4_>tw!w77wY;T|R5|r$ z(i31egu^W_d2+RBrNlfte{S)7~R50kOuAKfQ?gg0%VFHbk%hw zb#ZS68B+$etVA{BV4awXbnxToNwUhh@IsyX0dQRG3c~o;PRx&$2|Z?_GMRFmgZ4j zd4yNklW+GI^r&umQKBYa&Tmx0^qkc=9!A-&<15#l%RHTEt$rp3JlCwxnBM%9gE*9| zSt65rsC#%9^bOsqeWwT>1YWSu@lZrlgERw$OJldjH$37DYvta)C^?Jc_IuiM5n!9( zH+r0?+F{C@9H);iI9`z6e4}`=1Au2#EQ#hjUcH%+nIR7dPsFu0#q^mz!&b`ZIm0BCTLBG+6vhI#rkGMfw0+n`! z^bYOlSzY(uKm_g-A%u^?H9QfE>D?;a+TG%-!Qr<4Tshd$1fbk!_~o4j*6e`hyLz>e z@}M!NBN~sS)iKnp^n1wb_fhXL0(Skmy5MDFt>QjE>=02o6aNU;QHgsu6 z!`{(CmCJjqh3^-E~uJ5h6^;%WPs`6#cvdARFknJv@qbl#Y$q!JUV#$h5U$~<``vRDr za(>dq)Hg2nDB4N%ctG-NdI#U)1Y}V^4);L$TA=;n#9>|_?B~_kRUjT|k=ieGz^w5W zJ>~LyqIW^8jQjB6wTmNxZeEfxc%niZ7wK0 zV9SwaC-r;w7f7N)`8G`|M0Y3V2G|`5E;bnW4-6+xsv41OoncmeY)9`-)z98FBOLB3 zUVvY7e)risEz#}QE4nvdU(Pq;QP>6QC;Vk!JXlgPENpV;4@ zT5r(^%0o(L-$UAuZwIu<;C%I)4lrMj#F#MNgQFw$Lg z{T2}Y=Ouf$XMXcS8#qspOzp1G`K~Y%s%P$$;2)3&5XXSd*MRXNZ= z@W3vt!1JF)?yi_8zdcwZ z*vhDc5aBP-`Du0c@{4Bkl4 z_|yr}%=MwK_CYT_5jPTNJtT`Wtfk8GxrM(v2PZ3yl=EzbCYJRwZFctVJTMgo#ya+i zdJOtRof9yp8y4e6QHZSzy6XJgc&Kt0!RCeJo_g{z3kO>owrL8EwPMUJ@oq)>DzGM^ z)?z4iD|s~&CbJU?OwP&4&4L*8prE-Y;XJFpibEJ`dD}^eB_07b`=dnWin>GMe3d%p zD1P?5J3?*C7+t8QRIx0oQzK;olXxU>ph?77xPT;j%!!nrDV;m58izft2B>$$2d`;% zNH+tmQu;d6a&CX@!VYU>IXC+DtIYSTxbwG{`yxh2QNd)7nZYq}(#@*Sqv{Uk#8YaD zLaKu35S|c@oT-PfdsFVJ9Ad<%`?hnu=h>&@4Gic(3IgXO2z7qemMr5$RZ|P}*_}&K zxgYV>Kg*_@S`bNINCY|du_R}hR*yP7w~~RUEd>@e{Vak2^WCkyJ>UxaR^11GZsX1E_ zZPAcyY(a%)X@(Pw%819>zy>HQwxpS8Pf$b7AZ{|*&8*hm2Z@e|&q_ck7Nl(eH)EU% zOI(LtqMxn&d4|$G-J$@p)LWbc>ACeRrxwr-0}?*Q*m5;Fk<1HRm1#1z4(g>{bycVn zloQM_@vD#Y3hQWu3O1>aJ;}CqcN_#DKLFa?!!;g zY>|DwX2e1c6QsbzC2<2MPlG}q8Ay)dS|AH=BM#x8Nfub$CPo}|QTsD=fc-A#Nu7}s zJfU;~Bup1u*u*grFS!!nMxYI!zUn2yiGM+;KtlQucQnX4YdZ-y4vw_Tu_pcakpkfh!GS!Mm)Py7zI#q+DWC*TZ3e(s2GP^>csQtjk)8J!Vx@5Piui*3*Xdx6l z=((c_tw#SeJVO76j_i^K2e zhaeGdR*!LP!#6Cf+0o7# zG}WWXVX~HmF6$d5-GB3SxdVs6@jA4Wd{o@XhL}f}T$7Ih_u1DbVb|C&}I4lpJUQr!A`ZEj$4fn zzw>15-JPU9IJ=^m-C8^$dLZ7|k)yY0f`Gb6S@ds4Fdm?nZLsGdz&J&-s-V-u{9K~= zYPJaQ*wHE60?B@`hu4O92RuE6a93W6*s?V5FA`orfcOv9a=Y z<|1i4JZ!ybcg=}DlM*=Nz|tS(vk)elU;kHv*kJzvAsfD6Z3lI@xpf&Sp74@>hpU6I zlyxF7LXX{O@uhZ8j>An&nX=6}LHG9;AioB|*XHfu0)pLb z)P#1fn2K`xVT4nLGCHtTF?BuJK49SS1$5JRW*39MYqq~l!HF1^dsmYm>_hMu8PI*u{ZVNd3M-2rfJ(Dw7$2&%+rAMN7Pr=+PM zHn%WOt7HQfssS0a88cZ0$lR+B){b6(gEpS!-mrI(%$<# z_lsFyoS5sLYYQBCPjI7AWI7fvDlQUn&h5pG-DMki^A(V`8Y8 zd(S!>Zf8RK*nMJY@lC~>H1>4w$cO3i(TgRxJc+VY)ZM{b^4W))E1fd7XAp8_rOM)9 z(tfw&agRfJx#>LFywYmG+_EPd-eo^$^9E}eN?)V0Pl*B_u4Qov;ZR^ z19|LuoOZV4YdGBAD~WbrJzLG8A+QBI5XF`H53Qh zo4@FX9mP5?<=VHc*TWK+bHLl%${%hg^GORXY@)Wh2xzp2@vfoT=`1H3o(V2E@dvex zOa7;*>EoZd+uRD0s)X{=!)=enH=mEd%&b^+VHuGM!&JuDOy-ub>DhMj`}f)!yUIsU zapPt?m{o?K=cbATCwC_btAo&h#*jvlw2`zBwBxkmwZp^->V++1^nI9zZR_vN#;A^# zkH)$(g(Cgy6D??5L%wa?XZkv2Kk%#&J z07yW$zehQHOm8PoY#Zmou67*UPTv60DsRI?Q!PPNEkRYOpfWU5mjvDh=B2`lUnDC~ z9O-zlp}Dr#lj-CNas!w}yGS`I#dmCBVwVFDK9-?a%;c@EtFFGYD|g7{rn~~hYR4HF z2SBr_nUE!egHaCW78fNkO zZhR2$^nCw^w~w9w^q$A2#Wrm^r*3A)^?N_NbivOaT751WqX& z=Ka8X8Qivm3o?*zFLEFyw)KE-TPSGI&I?8nrm~UIU1>+a!AlsPi)o)y>+?lS zqq2590A9w&2X~PtP>9Sm6sV;D)wH{5_mb)HE8-*`q#_b;k*rH4>r$!v zQfWz=!FC#>w4NsLrbl0(ze=y~6KuzWw}#%vyYOJp=N*Qv8>83vZpU{Oxg*ob_@ju& zM>Dx@SnfJR8o*_Eq!et@E}ezWU|z*B4wm>&Er@FW!5(fNu)kzq<9tYajJKOqO3a z^TwNRj&FZ;&emDeA3P)WtJ^#B|2#~sg)ktN4wkkG?fb$`q!o@E&(rp?i;Qs?go~_H zOgLwyz~EeDrD8%mDI}d5L?GyohA*EjAb`;(53Py{_`@}4}`ul6DgQ?y)O2xWPKddvgp&zX~R_DsnPR?dmpON7K51dXXbT_!TJCPj> zKzA0<_8r4kljX|#WI4X1q>kRA5tsq4F}#{#%W5s-vzn34YGqN__Q^8rXvCTS{6iV= zq6Xj^SB)>};#`>A({(d>=x49I(v}~9r$5QJ*3=0ZMt8b?9a#7qko-CPd~%l=3iR(alO*ko7mch;{bqD6|t{ zXl*-fUL19(F`qB$rYg+l2-L#4yPU9 z#_-UJ7>*6#138?A4;L%-f|JK@Qz!!UVz_AaT+{U{^c(a$bYB1e0F@vEl^{kzJxGEU zs07!?-MjGsI(s&uy)9~;7h&P)$$n`0ay+(6~wd; zZU#T0@rP{F6K?=yJPBWd1E4`ZuLPE1dh)M)_g{8n+op9Ft?Tv7?c{^57slOuX9t#- z-gfkNUARSGd+XlE9@sjr-cSDie16%q{INg0dgs=I6j8yhCK8;heNTSJ?~>xQV=GL|5b4W+I-^vAosj5>ig+@f zpeJ0kmgDUN>KVarQ`@nfsx+(4m?|8!J!Lgf%Hph4H)o}m=!~<#*Vh5y;02GoKy6=r zeQ!Xv!G+0;HNbWw3G5}nQl+R z)MGtauhUd&OqoG575R)_N)=j9lmedvOX&*cUWgLaWNvEdB+HOXA4K&U_V!>y?!>lW z?~x0poHO|na?b8KZCyWo>*l}Y4?T3t7n?rr8Z_?qv5TL0?3$~e~H=& zvnl_tKd$Y(9*@G;;%8poxaZ`@xn~>OAHHw%W@ynFpxgYy)5wk%8IHYn%)>t-^9m>r z3N(EQ<`vDpgyRTp$Z^c(<4D*kFH!!6#sM=;CtN*juD~~d0~B%;g^`Ain(M|K?HsEg zquv7b%c(7xb!AP%4+M_J4@AU?QgWc%J!l5EeO?#6%I!XMwX?(V!hf1>@P zP53MP>Vq^QHW8#I1X2?~Nz|7cu@gltS3S&NSPB+pr+BoC?N_t1k7egoc4K$?)aA^x zFJqDv?cNWw{Yp#l`mp;_s+yfhv(o%IWt=jG8i6ERWf6?5BT)S_U4gQGiG+#utm7(r#zX*n8{U?-hH&I(^~)>T}$ zOmpQvjb83!cl0rt_MM6koF06j9!h66+Z}^=fmKAbDk7Q{ImBWSPD}9@pHGhgandNG z2kB$!FMUkw_}H7CdOz!7@GM+itbp~Uurg?XA6NQE`bVY@YhU&il)m^nbRE8yUn)1- z7He19uMXUb*5Y;iDtU$NW^I-Iw!oXNS3K@AfRC-wc$jYD@oKv16Hil2301~56bm8^ zsQXh5~DD}Ks2`GB?T+H$Q+a@UX-ye%5-B*W{J~?1J*b(a_UavY{z#R zq5eSzFhK?|K?X3vC9NFh+Q}TlSI$nBvyx$#GhBJ&TY(*tUY-j!uMBRJym_Q0H;0EFi+y6o^v z9bYY2xcavIu@64TAG`CCRSV{>yyen4Yle(mKXJvzO*h`~G#9D7Z~lf44{W&f-pby4 z*X%AJj63dl8Bdyf^G(xduD_#gdMhN{3b>UlM5BQ%6?+$iMSZ=6&vT6PEEroeI$N+ys5U^XeCN587sBKr__q_lXsvy;Ucc}nbYJ5G<8viiW1aq zBwCsp<(hG>@jpz$ZmaNYGN87CYH8Ra5FfXTg$vV|35kzM&!SEKYiCTnZu~$z@Wq8Y zPGaemJ36nq`tOfD{~>wf$)(G;K6CALkK&2?)t8UH;ZKXS;FJYe{?h@hKal@x{=59= z`E9>^iL3p^j=c}A162)DvJ+gBReYL_4GlKpynsYWAz~fR)nSoWNgbH{h|oyjqjGUX zpqc93PMwVdWEnJg2GscIP|ePL`}T2-`}UoDdfz^{Hye9k_jaI_M)eZgO}3xe9=9E_ z3CM=i>L7K5Iz^qWZdX55C7bGy=rg4{Q4}1!?Kzc>QzV5to>gN7LV_sO@#tw(qSdk4f+pw*#jTl_41%g)(YOh8rHeOReD*!>wTF&aCZI`fymYbz4pGb|zWzKu-HGL}2uaxTJaE6yZ2}%tw!LabEMnuauY|$T5)<+sPtBL9+IxK`X9U@nv8*ebU9Iok>)5+@wP0?6 zJ4UtICXQ;2O_-Y$~J3ov}#rN#|>20@C%kv(vlD`E0a#4>BuiS}v=&4FN z!ou?-l2ekGCYLBTE8@KHmBJzgWJkEkCRX?rE?7|&^Oq==?b#g*U;%^(bNCgHJ62Uy zS&5=0F=*-1Sj>fFK=wTQMbH9Ds(B1M^+JMaQKKdvsHnq6is}K;O?7}M(tZ?WS}T!p zj_9RaB~D6NckAgP9Wy-iZmF~urFYX*dJm0qUERry^y*lg4K&1yqYTHG z8e&9ogyDD_V=$8t%`pd+jWgsjXHE-tk0Iphx}dBZ%l5~Zp+NKRRM;540LXQK6;vZ; zTv-|xG^2uayrIUG=n?XBkR(p@HzUUBWCG3&q6kgtdq{fY8%r*ov+|CMT3%k4{~11O z#o!A@jkxjQ{6~16D72{`Q$@5n5W(f^IHZj~)=7 zo~w&BG@PPiWnd;Q#sQH}mX$-J zy31?&^8qPM6&>+;-Bi`_ZF|nj|K_vK{QJMyjEC;|GwyxnOEr6b_RL?WEj+yH@lOfq z_w9+7@#TN~3{T#2@Qpqj?s_c$?VT^?zg)YUYPN>~zo&wHIZ+7?8SZ!~9x9vi;L>AG zBnK=G?m3cp%qT0qn1V}LtX^S^sikS zw-`G1BMe>K&7H=@{rV2Q${5H+Bw3UNnU{Gn6buK6Xj4JzR8I8yy?&3M6C+$8f!z)$ zf^sy0{i-WLV*{B?75uHhIm+rKu+?b<>{sS5M^@T?9C5qq2`0|qvbD5LxayJXRHs$M|&)YXajljj= zSHc@A=rQ9g_J(&zxcepH1s{x)xQ&po?f=(XQ5S?T_0L`<{~zz9o;mHmzSAKyEbjKT&qBbToq#_nJk|(Dyb&L1s=z;yJ=o2am!pI`KvF11 z7(n=FJunsnF$V`;u7Yv8B2{ilQn@8b8HrGcP_3YR2ffW5u@6S!2*BS$E_C z8U*&uQJ^f17J>W>oy6fXrUY)kaC>{aQ=XF1_6YliAG*G4;VMd#f>Hl z@5sNk;ZONT+P2~GA3cKcUFpq<++%mZcyJ+i7F6c zlL0ZTE|aY;lWCVJ49eq@B+|heW(UA|>cj%Y;DgYgABko3FQ-e$niaUxRi$39)VPSu7)BTTQLG?bFxX z_Np|u$&|S*iJ9AA*vz1)vg@^RVZE?f08s*)`wp}LwIaS68E8B@fQ}%+9fyPK5hs}A zXtY^_#peFnYVL2W=B9$l40hJskMZv{_Ru&(r!{PC0joUM*u1!|tJ~_O18hulTYt1Y zU)n>>T4=dJh0nPe%#!`g&}Wl5;!<*@xW>N5B`ORx+H4dw+Hn{hcBi6PtfyG4r*yNP zl2+9pXU!dqGt)L2r=YK9vqq+D=H-kqjV5};U}1GzF7Cl`kKq~bY4Y$MoJOYAY^JkV zZ1(3OrjBy&u$rP%&ov+GHXXr{Fdh2N4738u6^C#J4uD2rLG|>Ro25lFN6zoHr}5<* zU*3l|1UFtgbjkJHcPB&buh0L4$|YF)!i7{WiN}a>WrMP^GNeKsAP!W|Q!nCHaqn}| zGW7%Q15n)*3z?zOOIXLR6`tk4k_DB=1NirNn$vX9P~3@HE=~(D-L`32H$A!y_T}Q1 zr`r;??bzn_)8n5QXNBOIsnl7r5(=FK2&AZrtO^{@#|70Z2(Sl&FMJC?}tUL5tg;J^xa)-=EH=bgCI#TRX%AhfOhq65VmPN84 zc%SU>1L@C-w5@IKtX$^J@`g7{+kSfrNME*x%h*V7jGGtdGKl(?RGe@E!#~M&&mQt8 zEOp&aZY-d#V@Cj`D#`m@zdU&#Is8?gFY*#!#jA-327mct|^W+DJ&mge{JB z0mr(4`=8CIWB*~2ia%zO9?qFo6SXaq=OLk9Ub~xZ*|Z#kW9wxQe-7WmP!l|MOJdG@}gdJc4%U}!B7pHe)1iQ(LWD0U4 zolG(8Me9$rI)vR8(IJh@(dwhj7Xa2bUnbWBolTyN7&jo|l)WS(^UJhV+V7w#wUOFL zCs)a*?7bZg+{OGd`*O!>yKEzZoV5>hj3cACVUi(_v7hTu?<4nf_el518@ZA@4xRQ>le@)D+`Gs|WXJus3URp|_X9*$ zR2JGY16gX^&~C6{+b(!v2e!dgq#ZU+jI2N{(^V`KkK)cnI@a6Clo#Sclh7i7rXw4- zxu_`+qB+XBx?mT>X&M89y>O4+Lpc-#d$>;T@d@jlEHMa(r=Le`o-nj)fQVQ#R)tgk2}TyYu|}r8zZvt-W@weWM!kjN%qf50P-|AvLgg!f0Lv~lV%>dEt!=Z zUifZe55CHgU9X6Z-CBjInhGr zd4N~;vG5LZpa}LGqry(?)xF+GAQItuo%h-Twg~@BV29%s2NwtgBP3p8xW;+L1&nZm z(4btTPj*fBObtvAP6=NWxixS<(L*tgbH{9o&oZ!lR-gN*q%lR|OUJ>DwGyXU;wK&)y$JaVh@B1MQ5IJ zX|3Q0}w2iPzwPZ{QKnwdHrbv_HRV zrWpXEO@<41fK z$eA4l(Gepy+qJ+;M(Lxx7wZ>$d7BmkL_~q0>Fv9%COs_^atBMvN;A*O#d2v_KvdR? z3gxKLhrYQSj)yV)3kU72$?UAj?5xS`|JO*te?~t-J@xmgAZfGNw8dt%!XM0A0?(C& zg<=F+Hj!`v-5n7km3NJ~?5@Ud@~`FB;A?h2oEzQm=KL+fE{A*ej)gDgySkp|@VXnO z-Q=^=7+gc)cHtY~VIS&+A2;rvo_-`vLcu{kVvF*n)cN+7dXr+6&?k^dpDEM@hNMRe zqXQ$;Ibm|LA$^5#4R^J$j$0?(jUM2hK+kdSqIdnDq0a)J1;bGxgQ|ox1wJR-6}%_? zZkkW|tJ1apY5wgmf%o6p8p$G>8Q3?H<%8Z}l`ur$3Fq&{NxjlRzktL9=Lrjh?jWH&7ISh$E{{n{ z*y{GM)$QT#ka{@n3DVB;Sfb;xd=C$mA=+IYOLQn96IA;aIeos;1_} zDStppSBO0#7F4+4=)j^>xu}Q@N>}jzT)jB^@I#OP_SO9E&8>L&YgE!M?>fA3;d3Bh zALKv9kw4F!cJb_oa+%fHYcB4<(?0wF&)W5J{>cxw=MUUgoqG^xw_^2Y`Su8;+CE_Mgoy?ToAn=KG8NU zx-hy}S?;*Xxl&!@yx0DWv)%cH<8!ADwqV@l^txP5ms3;R5t0b|Rnbi|{e_^S_ygfk zEWq4hGuGT;_-HQ%0w__&U?d0(4VMHm+a|5rp2|EnHOQm^bkV~<6!4jl>>Bh}Q>Dgp~QZm^TBW*Pft z!oJWwm#W7fRgWwgSCtKC)~OG1xrb1NiJO_ND3^qcpALqF%Rn97)PNw2#XzB4rV2i>R=OBZ$Q5$;qk9Z1e349G7}$2d}bSZNJ)ioqlEclGG}0 zt?d^3TIX&0%JQ31ciHc8-s6iEU9LWfv^$axE9pv{MyN9E=KJ?cquGE1_C8ldZi$dc z%5U!zt4QIL;1?)HnnT#JK1wX+=a?~&0X)l@fnB=Eu^j*EPV*Bn`lQMocAJohmc$~m zB=Q^)ajLuwj)_7n(kEJyiVG(X--Rd}w$Kxiv2(QN?ZpW>LqYr%~eKgeg z0>w%?=^4W+CUz-lREaC8dE{^qnyYuzD5dwT4EIlHJusc+lt2sMw3`~)^kTOqhVJfh zb@wDHt)YI!Sa)vBAr_u04y{>$UmRc4yK0ccADX(A&Tx|YBaZJwV4fy#06Dq16($ikBPygL@S3Em${IoOkmra;A=lbt{ z{`kLF3A>z|o@sqFI~ae^&~o*v6A!(b|Hu9Kef{#=E;@I~u;Fu(ff<=WkI%m1&)%TuH3(5>6cWp`hwlHi{)K>VuVD7UlJ=t7J-%iTO3wo5m@O* z;;=4C2_y!+kJu6#N;_GyEpFx+ydcIgsixU;7;neLnDrNijp3tQ1jp~J@W`hYN}jY( zF>ku%^p5h5`+G)8=uBt5>rn2n&gRe77emqAe{}i)9g`uRdz2RJ@kv@LF8ywIZk9 zG_gE6((TC+y*T!A&^UudHga)4j{C>^Nt1t(zs1k_f5aeV<1m(+sm6;_JWMsBTKuba zs}Yqi#y3ngqIRnhHRq%5+$l9;#`nhPxnk(G+u&y=X$IwRjjL$rv%o8h!MgaSJ+tyB z-uZq0_@X`MZMyEg9m1}YTRzU8eEfE7|B@Sba_dXmFWG~=(5ed979;448{BDlgx-v0 z7@+dOVvxBz?0lRNsD~TW9fW}y7AMbP3)Bq#Zvux*xQC=)LW1bj~f zFCl^gkNPsMB3YR&L6%duf2s%sr)%m|k$%Ko*HXY<&mj5B?zky$7--aE%#jslnu&uHXF;Uw1}nSs%Ra zm99PDalhZPX!&x!l8s}42`Vk4)+f1^=8NXd;FCEN_{7{?0&5hY*`6<$}dJDg6<>v6k%{y;DYUQ^vR z0R`i9tGQitYfSaYN*oDv%?H3PjDmtJ$9zGr&lhxSiW2j=fpohxr!%g*yt?jkE1Dei z2~L*|AO=+uxS;NIDvB%t zi|SbbJ34_KU6gCxDov;|c{BwFt4{G~F}CP{Bil4XFb11!yEuos14BLZ0u`K6MVZeD!IKhB)Sk!DH27>_G+DXVzR8`>!0Is8*1i{x*E;Q5@m8k7_J2aI|izDvB zapVq$ciRmGnA>YPP=<{e30l!G__Sy$kl+rxV^4x&V20^4Y7cbMBvraOOznX>pjrGL zICAwFnT!lDD6mvTO0A{|iaHddS_8m4QJR`4Yl_D2DjY>z;V8=}W`-SR9+ScbrQplA z7e3h%qR!B%OymEA#)Rt>F1pB>U2lAi6XS=U`x6}fwCe@3kQv*6LKlB_nm)}~$g9D4Elz%2a@5URcKYu~t3qH!9je4O$ zWTVkru`5*}d$_97UR9N~5A+R+45=Dfm9yun=G*60HT7L{N7XK#>}Piyv#Cfwf36!Z~MP9u0gd9%`>#-`SNpWUi0U{o7{KWwfS*BNl~V6E;zEiVf*g|7Q^U45+Oz z=W3o!m_y|E`Mmx>GR=vSgP2MAa1mEGYv=sUyU$y4{(uD^&cQXq*W7SbNo(-(w{BVU z?08)Xlhqf}9(UGHsWhzuX`&-PIx4}h8P{MzbCwGOgyDivU)owqN=wV4 zHPLgUi%Qp*ibFhg{<`pJ|LAZ|&e^X1FzbDfv_FAsN=exQ9A_%QUT=j*`N zp}&?KEG?9V;zG5v+S^yCcN)TI=Xl{#;lq-D^2c>e_c?fxphy&Skm`#%Y(Xo|5wvU; znp13~7;~4uWy8A7ur=9QY`mF6X=4&&3l@iMk697ABUZkKxd4rg&eUWfP0CplY2VwH z0ywcnS{S>yYLJ@=2hZezHwTQE16E^NSDd-XNs5pT49@!o+=`E2z7*HvahSu@#;02l`f2rWkR`vd1ZW(Joj2$-?}f6}Vl(rM9Roj| zjY#$2Rx=D+&ytQ!+-_csniEOzX28{s5uc8dWfdHF+NUN)^?AB&@s>+AHyioyezki6 zshxc1vgen`sf(k30tklgmm3w#|wT>H{*lEKwwP+DQJ@1a%q+pb{VTVtWX@g0u!6Y^} zh^}J@D`EwC&0cb-SkdwN=_*3Fj!A?!3ZzgOhV&ik<1cEZ?aKs52Kg#q3H(Tm6=^+NB&=o~Ujn61q8 zHbpy1-x1#Rd>s1B^O^VCz~4fjF>LXdmS(~fkVb_mI!R}MD}0832pM1>MTXl)ct=Jr zQm5GG*gq3L_aDbc9Xj@bhpjsSb8M0e0qAh2fzJ0YFwm)?{rTMstQS)*r**;UOi;m? zAf@YXxv=gsTurVP7vK`*ToavKZVCx5rj992xkSq6E{0Yv7A&Ft=yK40bXkcSE-N8} z5=Ijfq@`|iK@D?l2gVKVa)~+l<|X30ErAne~%D(#p;kfr$ znD6Hv66zN{$2}%|PIQ8MTIj;)4EMtDjOcQ4x$hV`7Sxd+JMDqMcs~tHasH@ty}m&w zy3R+Us)TltXQ`A}$lhVFuF^rE@Ad#J1gsShPFpgJnKc2!4)zfXS=p`SN$gf?pq<`I zsi>-LwPSm@l;+Z<(zSH^0yTq5ajBo`hG}euXN?J_#n}Li5A<@$D6guu`r4Fw69M8q z`aR0}-NcG0>v5L#O8fnE4U@~Tah5}H40zxei{Oswo@xju%*lpzUCnjHsd>d&EiBW_ zf(3Jo+$$wm{0t}9A^{@zlU=>P+4*JuTkQSwyV!wGexYt%Idfgthh%~_c*-r;K7*$O z9&f{?phGp>EB{IU-+FxWuDST`RYT`KMRkq`*r7#u8wGHs5%Vh88LAHT4H=)R6?X)=L}vtpCsws$10Y zZMaudN5`D z-+P2@L}Ga5q{O7kdD6_p%*v+TExkXi_#*L5^4khmz%TmR$(FWWQIEt_u^vZ#nIdjM z9q26to(#Fp(1mE!sSYoTYO3E?ld9>t?ALeJ%*pSK3KjxQ1%qz|upTf1O@WpG-y6Dw zOzzFlIKa?2(2d3chQ@S(40iM@6OHLrbis@w8VAgDKSmt4Wc|1?mvPQgCr+WVQpQZB zjG0OqGnJOV#ls?&9>Bh;h*%`|8 zUYelroEdvcOq+{CGI~#hW)RK9_ZVG2=1_5V@F6q0-3%%`K&Rm_U!uaC0ZdUkFu+PN z?m2h<(#^L1LziB+Cg{M+T0c5+`5$iEef3kbKicr?ukL^9x@$LXx_bG>hVX<`|5;N9 zwcd*BKE4m*b@#QLod5m)<7v6r*NfZ9%~u3idOF z>o?eBs$Q)0(vDTA2kTa!WnJoJo$pPVxoA4n>IhvSG!EQ*5b-Q+rWnpSZUh)w z@Ya-s9vNxJO+Nq;1`mX}9bA3Be-RlZUX8)Pc15 z$0_TT4N9xhp&U?-C=yail|@R6@<{Q}L8YLmr3%>Z5>Gfqq{(|mANJJiF%kulS4Al$ zApQ}41K-Mb@CSLZgFnI(#K-x!V2|fbSC7yq7rUQl-OsD^`8-n;yrn33Ysin)Q>CoH zkClJO1dHp~qGZt38EnOxsh}_JIqrJ;ADf#F{k^8Gt&RWN{{1I>eEP(PR7#;Yx$oKB zfme2L){xVw5h<&`zBBrnt5UF@GS`bM(#)U`r-)M(&T0RLa7^SBYre0UC8Jt|Vi8<% zZ5eU$WbUUbaf@*e3&S4S=B}V&*&}VRbqnl3f*mk!h9e@+3%oc;Igb}oVjs0Z{V8{) z`XTpMQF=7uk$+D-Bz`IVOZ>O&bE~Sr zaXg_D6%-kE6j@H0(-SzJPnlB|ROoJ=4r=iN9jLI`kjl4Xr=bWu3kH_SbZ>Z^d1Jbn znz$Z}x#H{u1`sxL4Ym|AM`{Q=XpYg46vkjz)T41AQgl*DKL!mf`y82*Xc&jkm;^up zbMX-KHBm^j|0QwWr9Bk`UAssxnhSLBzWEp(ya%VQdyE3?^+1-6it*Mo20EWX(&ak2 zj$>tUgvUNg!KKR098rRHn#&5#pSjMRp(?#gvWi?%Qb*?@Y%QVF5#HGvXPYgF;%as* z5xE($xePmzSm@ZAU^%Z_{dDumR-H{^fDPNz*k+5(N@S*PCViCqV;;+1KRnIrtz!jE zNZJ~tKmK}4#Jn8m8qL_+sgwg$obFJAaS}_w?)cd+^YigbpX49CLD+S2H*U=@>zYMM zug=qTq;CQN7{q2}jWO&!aqKkgD$c~}fmElVleu(LPb@kOf6OskfuRkXc{OOTIRmS9 zfVu74&)k-oGqj8ps7a?#Dm)?_5cqLW91*xuVUf@x6a*ghib^Om2H&{+O-_@VeigP_G(TWs%#f3yp3 zYGV_)OglhKgEg5XpYBASBBba&a#>BnWf3J-^F=KpVi94BD6tmGh+0I%BElA-S%dC& zi*Q(k(;_^U{is`n+ag>R;jzpR-6Gr;;j#$3m2D|o1RY#5#@Ot&DgF?DNcl_Pv$*iC za4b#&ay+R7BXNb}lCh}hqlTY^#bh|7t8b<7`qYLLNd*F7M{2zbyLc8pV9A~?7LRA) z120=Vr?{{lP=o~$G!{f)k$9JttlJ}$fOAGHDECO&W6T;%t&iXcdqAZ70TK3q2n}Po z=mR3mN{O&&Q-p#QGnXP7eN@B>`bX#!dLdGiWVcT;uuC$qOQ!H!2-DCSDMb|WI0kto z{{eX{K9BrGo9LwFJsmZ?%s4Vx(qW=td8!>R-}0u30k%XHv#gl&)zij$ zwEt7{m)%=>{p$}uyDd5G>_tCsYnU~9#SlJy_t@!|H0;{EqpN~EblLPFcR$f}FWI_$ z`S=I!?E0W+Q6C0L^5ZRrN8m&c*{HYcf8{>+9N~_6M4sx&GGMu@bbO!wR`6i35ai>s z*WvZM!J@{Z->%vnn!{pRhb3{2VjdY#oyGkY-58Iwt7>$I(Q^V76ms1TZ0`zKFE<8pP%uK zpYf2NagRS`&f9Uhiqpw{)SOm-U{1SwnA3a_-8u~S56$zj0k*PI_n&ECA7v)?X(uw) zd`&hDq`vc%jqMj*iYlv;%87c~B|0M5sk(~{L+5HYQzgn6qd3IVgDX})cIC%SkB-;X zwyFi^FL|0z-@AGEqA~ri>smrqUB2*~yWZ?#>rD(Re8E>h&)ZQ5zqG>_EGBk;!9<&` zr)SKjREV8$OKM0vPds0qA~wo%#Cft@s}FGx@ec?N*GIWW`G*Im3DcAd^_)BBzc9E^ zSg6d>7rGbvX9a(XeTpd9FXko*lhli~%edLXZ1plt4Mcg#1whp^_v@&Y4feg^Va`x_ zg!$MJ#yV2>lI{|Vbrz%f*02mCiW57`1^9}SKN!(rILcGCeI<+}U5eAmpWUm2_B#M* zMXy*$!(>1^7`r&kycfnaj&h_qXlRD5GK1J)0*W&3V1ckAelWB|Y$`7@;Bgd~2x1|$ z;v)TQeI(Q`OhaYG<@tMZg5I3Tfti&%ojaE0sD{fzw|4Y}tzukyq*#71lZ~o!8 zZ@dnbU7erDCx9#5D2DGbmTGz*{VaWy&ez9V5?t^dBU&OPMEN+aNpzk6Ss~Y(shD+V&C33 z-hJcs_bD2jpP$Dagnrji6fZX}vylv`3Z6+uk*hSZ-d7(Q6-QSj`*(ou=u6+RZy=aWm?9UB?GjPWP~=A%p)IY9|iyF|1xwqa*{YP zZ}*0yHpwA+qdatWz)^#&{_Z)}RSdi#It=2(y3=qrIa~gp_Pzv8isJ11>FS>Dp4pk5 zYwv4@yeTDyN;)-o_gwNzg8d>Zw0c% z{ZjGfZ&SSarQ*#m6>t7#Yc(9(xitLNUKZW*K1H^0i|wyzBz|9`_@o(+#2K(++1^ME zn;|u9Mus&;v-IEj1smTJbN!+xHeP$pPg-XSv+qcyn_{eOz4?i|j-9Xmbno65U)g`~6_%85LE*lP zat+dZu?s81N~)0 z@bM8VyH2l}Y8xT^GZswfN_E*-o*;i&$|*fz6go0A&XP8|+RIl7QfiQ)XJb`DLa z!0wf)awqJRg?uoORVysTw1Ix`mUaDR*Iqoe-+%#qr=}HXrH?KcdhU~DLu#ilY}t=E z*Tz3mHz8-btB`yw)x9OeX3J}N!l~1ip)}!;<)hB|F_xjoF%&w6PL3hUNnIwjOoeHM z=emcx2NsVnoLRWUeV2Ph@e|<wDDWY6T3 z$==DnIp!Sq9M7DTIo>(GEu~w^{JiMBxO4B~NuK(Y8KpDI7Z)uqZYaLj^RV}x^835~ zsQY7{r@cQZd#rqO=}V;<<<1DA&@mJ_hGNHHr&o89pgW1uon-1fM0zh4DyW`hmX&xt zT28byT}$bfpTkP_!tAbciZZ)4dsOzc?2XxPWb6LyNcQ~f_p`M~_TAYc`{&?*bnv5` z{fecr_W*Cl4k-H+K}tZ8r*CXd%jhX*#rRMIMd>yr3=54!*_AEGj(y=lrGkaSZO%Am7mfjN5-I2S(l#Et9Dh1 z+Ny>sQN9lxfMSv9hxYid<=3OM`(>ARJKjLSHnO+~r2D;yMeLf;3n=r55Ek zcJ|~d8$IpKG zyKlUuoR>Fu;mm>O6=juF4O>2P$PML@ilN`RJnN##7xgL1%MW{sd-Pv2dD5B*&v4sX z9RFN&aXmnpN`$|N(dwMr+O{sg)j93oGU$%MBahE1Wi8~cSRD)v*$OFMpGQ$CBjB#^ zdmsy`DgHnq6)L_H#1oGto_LkGVGeQ+nr>WeG@SiqR9s!qFo*^ZjdTd^5Zv9}9fG^N zyL$+3!QI{6J-BOd3+@h$Go9z1?|yUd+#j=Mtv>tgT~)jM^pEa+s<5^=Sbu!)ShQeu z!+t^3wexQV2@xhuP`5yj>@zM(PO>la6vRqx8at+mQL1&VDmAcSF}j6uB^KRnveHOd zlk_y1O%mW85S%M-vi#=Ls+9nGhLn+vB%6S{!SDuRosski5`#p-1gBuwQl?JZjRp_Q zbCA>%F?rj`XY3ES9ar!pm}>5)c(g9MYORs2|IDZn?l7d&aM+jNWgo~-pHb!iMcll2 z)THG}Tx|GOiI(vfvF7WPq!1j2=(}PpqPb4`-_O|Cw!3pt@s+X!f(IkBmc@7}W+8if zx@**fvMZjZ&C!x9^JkX4-fk4iw)E%A`?L9?0DP6L0qtetV3 zcerpEzU{P8XeR2_@EtEK#@)F0=3n?;h}cb@yA)nD$1G&q-;8LIxAAIB(T>iRYRg}= zN|@#3YBZQT$P>6}WtHn}sw&$OipP#+7QiU^`VlhZABsFP-Ys;t?Xd*44M0uP>n4lH z3rTwGiffjwFU7C;wf@rT*y~-$i2@YbNWtr|nN8^Ww(xeE9wilc(R~Fq+H~KZ5gVUe zbjzs_`s0$N_p^9XD#jj79#;6+<DD8WYZ`fCygzm z@mga~H1fm{H5J>jLu7yslu;z@ zeuD#E{Ep8~3`DT8A5KnoKb2C{dEJ~+xuCySQD&I_j zqFM^aojBcC@>HXy8LT>?-ete_z95{p0s(oaXSk=QEi>vy8#456I_2Pa{fmIS!^fp1 zH1WHm`G^W!*Hi-qln0I-MtM=$^d|BOhY1Fqa1!P#(QSViT4>|WusIo)e z+B&H^$L=-&dq}k{M)okO&9;ljyG*hT1LsoC9ejlVMWgdL2T$I;I(FWpkm0KMo$@>C zO<@*{$Tr+Z5;y6K1}60&nO1{{wt{cPXvMGl923bo2PQ4DmTB<`;CHO39yBLxo#FdV zP^UTm2JbuomLBwXva!vVgjz%MUn^ZV{qgC;O;lf9y-!uOEXO0p4`aL3*3Blxujzl- zZa4n2#<{es<(kA<8Xw*AsbLHHeWFp;2ZYi70$BJps=A3!WP9wC{%P~zfqG!ekjv_L57GL**)FyiG+yIrx#)P?IY)ca zWOue2Z#5})5usX7g_Yo@@LhETK}cuz%>X+`onZ15iCXy9LMXP%w)r`q$p6H^etUbf z*U$4TuB%C+K45VJrPP z(l!zewBS<1Q+e3lAVMF_$~Tx5ZxsTGrZykN%fdk>(3C12MQg<<`4aiEbo5xf_xiUvJ$g+aW#qN*BRRpY}BEb?s*+4)}qj^yI84b_nG z^XpUta|NOi1S|;~H^tAwr?tzpu>x$*Ml*~B;*4nJ4%n9TDRB`_^w&kjPd;Vju*c{G zEJ%Hx<4GHtzrIKPGJ6i%RLP0b`}{_k(>-=BGcs+S>@nAk_=v_YUDsFgoSsBsoP9(Y z%e>VP1?mWMWCE4uG7GfQj;u)!4=O>@o3>}JDa}IiJyqVAK8|ZDAy0K*9VJp}{xZIv zrkhQyRJL!a&nV9Ad`IZ0idqmv3Yv^UiH>Uz*Y;7gSK%cT_*pkaEFFEhCcN>cxUef? zyH!+5IJ?{+pH1IvpU?+)(VwTh5jI5Ngk6O#&^QY2zeD_zNx}c!U`s6u^2(+W`XxQ; z;&p(WTjH#CbK&8t*&&TthtbcXfudaO7|)v~#h14a98;?kocQ5z8$iotU){lW>+>i} zu6$y*0%(_9vw7sNY#V|sopKUN)%3YXyV~jX-2+?K)LMI;>$tOmyC16Dok(bq_kb#0 zh5j0i8NR?oj$BfzwG5RaMt*aoV&-bJaHMrHqF9W>i8Jg$(0vk1jN9hiy!l1yq zH>cjin#y0DbU=rxjRPRn`)`}m(vI1cKMAiOOHdlHkpF0Ff3@h6S?{*vtuE>WkL^qz zv=8k?by!TRej&|7BZAuKRlsj*bn-T4HGPt3o4@j6HI}`g53{KTZ1q2X@!b|t7%3~D z(gVP}Y4VSR-r(Yu+1#9x`s`hQ*3G^h$W&D{wAaWiIxRPB--xL0@Z`WEwGY$hAG`#? zC=tN}^dnA?JY0INydfFp$L&xkiQRGHw9&g$d?RWGDvCY3%7@R@RP&5QkMHBnRV3k& zZt3nZyk1j|E{d3dUVm+wd>c23rW*tVl5td1B7Q55oEi3!^)&XVQSq4FjRyjuBm|Po z_nXuap70Gbj!TyH5i1^E)YIcvs%Snh1>iIc9aPbkX+Hg-x>+uJwX!!fYXa1El_|Rl zUJS|Cr~!CXJB&SThY=UYHIcaBrq%9F`Iy^6FZ)?8t-&h&SNwI5$shJ$145wzz}6-{h-|7kUB{oCb8FN*XGQR2Ns>xd?u# z_n0Yk5k#wMQTuaUQ`hK?hqA#F)$q$0fVh?0F<87%)0nmr4%C$wI&J(V6=wVEehH+1 zy%o1Do~W)I@#LVewwHGc2wyNCwWD`$5QuGo?8NL~u4(7B?es5@h<-Ane6sKaWkYmh z>A6$(r=U~IP~9d!d3k%kcop$~k);AAg@&3fgr4-@A2*0J^f%1g&(z#+eCcF5AG*`_ z*+SR^pAqP!wrx5rOFV>{hH)=^8@xSiWbmO2teM;Kgh4(v`>A~6#P%Wh0q8lIwu|g8 zvPWn-uRY%dc|%#O5hI(G1ox8>E8x)jG2mRrqbX=fM^H>;tSY(qecFe)5jEYM;*DFP zwaU3CVKB0sG_s*BVn;&=x6I2TMzKnwsmpQq0@Wx6(b5+KwhyfJEUt~jFDrUT_PK=6B z<3_JC#?Tr*WOVxoQ`#Y<3b!@ZdhM$6E$0jNEmwYOZNEFo^)-;;0~S4^$z~{^4$Mb5 zq&0o3k6lNyjx2fYTFn1#YU$gth&YLu+^(cm^E%jp9vl||Y;K%7)nE4=eax;(5x}Qp zn94exUK-OTXf=C^w;o*It+B)Vu0PzV6QkxR;K8NpX;?Am_9MGVl5~OAE#q6Eisp-= zer%iJ_h8)WBLfUMe3MBM=?=%|->pV={uYxoV{ zwC)KXbUsFRKn+qKQ;f^7O{UJ81h_XnwLTRaIaF<6NM2ISXt#P6xGR=wp&YjJ{l4>% zMho23p?vK^atyD4qybm)Q?1Ay^knxw-krjnK4cMR1&9k>H7cQ$? zI4(mf%PDFveAJ$3QNm0xFUz+fHAR~&;VdInh|jn2H*ln|>(*GYt5N|p*8X(});Ykl zFvM4r+wNaYPX_K+Lwb9lNWK;M#ury93mXcoX;QIif-Ls4M?K-!7@8gFoz%1>%os{j zaMjza{c1+1(+m<~oA=c^CZpDGH5P5gDx0U&MoTd)1?9!Pp@wC`y{NoUatiXWy1ZSa z88Bn%(wDiVvu1C8zv3QH=ByW_Kl3d$$-c$B5WgP`q3kJ1`YCMYqLqgSyQF+)RX~!F zOfUB0Wy7*J<-lh9;#%KQ#&(wus$yuBv;Qm5ferLY*EIFD>Q0Cz@lFCgP+xX;tG`Qr z&w2(jjoxc_k|g+HW^|H!8#i+r;lW3OqCx#TNW0Os%a&(|k4fyv};*sV4H$sCx4miK;uXS*#Waiz{ zFk81R4f)DXQAPgeuqv<=b9~}B%`4g{(|GZ7u$9WaU0&E(C5(cWmTWfZ?yb~bN>Wj{ zRmno*f)5Vo-(9Xnkh8{%C;}#}MlNlw{}>usR~TjuXmr7~K>3HJlsEC}{!X>8SNRwa zKjC3qU%=0L@@OiEg&}*!PFNmEQ2>KPx5HHajh|iVV8Q&r+)|h+iPdq06Aj}f%Ga=N zd>I`hTHIKpl4UV?kZ*|3&@sVLSwqKG2OooFGR-o7sSE6i{;^%ThUwd@sqU;6be9=(x1mwXnqnd!93r+ilDZ98FbQ zvfFX9&VH_Q%ATkgtee}yA;dCDxXvf$=ScFNl#r_%=^RDdok%PGQf%}M?hG1p1e#{s zJ$O}#A|d7c?Hb8;!k}dAIU+ubz$qeYoR0}!Mjl-|8)TEOsukxI<&zjmsZQqeTIEh& zQ|U;)Ej^g|^ipGMyU||Nbiev`Tk?7~7X;e!-=51U8^*ZM|I8s~qkXp)j45lI>GjbU z1PUU0JD-;Ks!#P+eQA*Qfjq>Gqj~Am6|w8|PwzQEU|Ax4uX@R?M3`R^2W@!S7?1Bm zFn86q|J9EpaA13GiYdH>aGXnFIwZ$Bq3Uz?%aEG%37CJh&Y{p6Bm%`2y( zHb+{Qoy@r46Ja?$BmAff^!A^@$HRCZhPZ@c>-8WScI)`k3SDZ<^J;fk>oN4_6;BFt zmXt;KR(E%o&ST5BTHONU>hr{DBk+i-E4}*X8`ICVGL(BmfzQr4-PvmWZ-(nVh<337 z@;~1cQz=Mv+}F<7FA8mn1CT*e9#iLTUgHaxr7g{r?{I}h1k-rnnmq1Nu=t2k0Xd9E zpA3p_02{@fU-d&@a$Q(9d*U|&1KIH-4%dIYG<{Y_e3@iCBqHE0B|L&oj5Pn81;Gc@ z3cpjRokQvrR(D8WoBR2==E#k$h9^M^dHKrqowR(H@JBo9PI6R60;BA?5K^vlppHS* zvW&VF=C2>GUcL9kWrz+0hx6XOo~wvB@Et!q7TcOvqq10$1ncv;66yf*5RxRosWanBPxXez zBg9kr2F|1Z9&q!;F@e{*=r4+9wpy0wf*(dtNy0ngWYcVT&ggxxCx+w79&g4e+HI5w zng4W>&j*J*#jOgi*v3469x)!ACS0F3^1fFnr?YRXLR7(;AR#p2)&%ePwKL@*!fpBl z>H>VmB57e$M` z&-yQdM_aU<8L|^)`D-OBzR)mKY<*p1!m;$H;7Ko5% zs>HcuAgt&(Xxv&J~0KHrx3A1{gM?3evhw3L#wLGyahzYtb^eoxpHD8lm!8}?( zdoX9bz}n@Qegv@NwEo#ydaPrAUzdvw+Pt_j|C%!;x1(UstWU1I(vs`zenPcVHzp;} z61zU+h&y_Y*TNF>VUqsk-P?%oF?H>47wc&CQZRc6NsNEvDgUZrBIu`w4k4bu($-gh zX{5oNxe9}K{Ot&Va2Nfp#S;0bmen^)^Ad)pb*jN*30=M;=?*?`*=CNMd7!BPx8Bfn zm3^UU^)97*V<2<4^*MLgt7zw;)qLC`a1LKmqPhL+J<3I|$rP$4hN$K`gF{Z~`{$<# z-`OmehG*{)1iWTA7*l^m8PqSJjX5M=YGpTPxm?$03YDU05$%phGY3saZccukhXb}f zmibwEyxfMSlD`yLyjLx12SQQVi9UUXhr)%zdRQrO5ZUIy z&7YpBw~*5d^T*$)6nuoOb#^TvPi6|lq4**KDf9GrgUxwk9CkVBKc|qqoD$9smg=|U z*|sCuB1^sJpb1pl33`EhQy`ZjjT9gy?pp~GOeI+omTKCbNmmP;cu|`Y%=-UyOWhAA zoCP%ka0;i3c>cPTAe@tKdh@KS<-WT~Z0H7Gp>%AJcY33*bJ@_1Gt-hd_%a!xE#em9 z2{I$omTbSB4BwSwTWi{9)y7p&Jy|L35aO13VLLfdzx#DkV!2A-C23vEvs@iqreiDm+#=X) z0^+b>?TFm!?M^4RWc%!ot6L;jAa+82wdr?b(eQoo^IN@^1qbI11Xaf1DKAsktL|Z$^#0;2|1At zXA<6FR=*T3KapYB;*(qyBK2xrvuD-lNpess47wBP!%-Mo;}FsvH5X+~B}W(J4e^_7MYpX~VOpt9`uc-kIkOx7 z(N$q&Si=Y>>*mwsBj%MnWHfWrONc*@-3R^m?(qOBX8#ZIV+^2TxfA0%@{z|r5zK;h zZ_uYR^F9K%n|UgV)-9TigfU>JaOUCY#puJH6JLU^O|fOT!((nV;YFSwVim@Fph-tt z#xv7hio<15!ue`~c`xZnKL3a#BrrM4W=TR3TLg`ynhOus71^SpCy*V|poh6LHiWVD zf_VTVYAK-krOV^PUF2uu{9XOt&My~mv;*LJ>ejYx%(!;i=e5Oeo!m69*XrRh z_%Q5Re`9Ol4tihRKfOI&y9?=m(nb347ivY%?Ww(Jkqvs&+V)%)2=pajL^-$&Dh_gk z`7QYQ@1=1quhSgooq)Uo-}|FFl}YmWm+8-^oq{Q(vBdADCy9sH7B?FGR39v}&{;xX zn{FVCiv@%)tYz_DeCDx+^C+hmMJ;xB=zdXk(MmMXj^8vS653J^+bhKkdWX;9jn%V^ z*U<7byaJv}7qDARe1@($^@qkUIKHl_?NjnWLI>z%Oav-a4V&1K>8B>vg>1@f=`Z()QNvtre1a zx|{f<=pD~SIgkCAFS)=!SnW3wmu>oLUo8uJH|svQ@BGqHzA7 zK0x01^AZXYqW8er$xPOijlEK-_Px^v_%+-s&tUriU80>RPFr^AYPX=h1=ncaH zsbop|wF@p=q7B>EVqkW@FMFz;m}KlZ-lL%^C!^Xw#?JxrS%d?G?{VqDMZv0W%y)5k zC&CsCyUM-CDv>hrOm$InXNUI7D@v5_2F|6KJq;GJDV6}sFwg-vgE$-IUMZ$?MZgyDoC5u`Z9%;4Et_~1dZ7;0(U18{vZX2W z_EaM&cC)uUc;X_+yv@IjcFmd9Ge5ZNa#1uI;C<{*L{Q>wr^vjmcZYP18;95$`-pMP zsmqT^0d+CB^(8iLG~i`q&m-6OH)r#`X_Qdn!ou= z2Vw6c$NQ&%Iwzk1q()Ci0;n43H<|!PS07m(E%%@U%~Qrq(7+{3`={M1cgN+$!%BCV z$^7D00nYOOuR8A*3?B*+ks9av6i34k=8>x%%neBI?QtIzl~7r?)z-&oPTL+ zOrc!6CzhM9&JR3M8yOUt+1$Z*(u18oaLX`7c173yJklo3MKRz^u{19|jX~7|y-gwa z!m{)7>3ksdoP9}D>5Cpmd*8e7-D&LHef8x`^g&Xi@&_XL&&q}weX%=BmGk!S5N>1b zH)*Gi&R+;NR@KGhQPmFm3X10niHCadZFYpw;@S6(n;Y!z_TO>Vb87Es;y(gvXaW#S zGEwwL3~`1QEvMQcmeBS_5wUaPoTiQ~=NQE)mQe0C`b*axL>|fu*VZ)~)jqx+&k&cW zjd(t3x^222K2hvCaj!MSOJ~(}_+dTqCi5ciKXFPBep)$KJO@xQgzR-DR{<>wrdT|> zs{${!o4$@ZMUzN0jiNQjXB$=CbNe{2x z0#j@}7nh~_kTYaYePG1Fl{;2axsJobqo)GBixkNmL$=d&|&%(3OTd zW(T3dx2J>XMjRzs73G_jls3G++U9hazhnD|KQo-nv?AZ8mn%@DNyU;bgm*``I;zcn)b_TypFa9m~#8t2`(Np z(;RY2e$^X}HNAZgUGgI)`={Xq4@z^Uzt)jE37&y?Jjw?gl%t*<@%yi61)ECaQozt$ zz(bJ9zz4D8$-OJoJ>hOwfM+s{aSII9hd>`M-YD5-rVD zmeeBQKRx5sLM$8a>cO5!BiE=Zng7T!8@rFNHI&~8;$dPpU3T++i>?-_XQ{9B>b3T# z{r*;VGn{I9oug>BpPq?3=F*ApvbsyKK|b+m z$92(zyBqnf5aB(jdXQD46XPTNRJ;*BXHegjE{OKiwl0m$S##ZD{M!!hx$CcX9bjj6 zwmkGuGYsNG5Qq+vpk?1S*%(vH;;mtSlYpV*T=gT|1+T=Wt(%p6c&VUi1#5n~*ybK} zJ+!m;R_=ssA?F3LiNl0O&)K=FOE1|Kcp0d5MXWDgp+L4^uczOCYW1m&Jaqin^bX?e z!xVcHdn-leZBD0gx2Ggb=OxJ7Ne-CZXPu=%uf&w^5Dlpx6}ZK8tzS_g6uSCI;efuw zlWi7>?vl)nu>05dm;2n`?oX*eXN*$9QaA$G>Y|3C7jPXdrbjpxqzC=LcE)D+zH=H} zca7~Ar_Qb;cn{??oZP}0)cVyfN){CmPzi5tsf3NRo6VH z=*vBwhmVdeFOI&_L3|AswFIzggYK=*!|s%X%F*oMKPZ(6XAn%^+WGtpxK5BhwW0e% zKk$9?)D2)!uv1=Auxvi%5--Rb$_=Sh$B8D&7bE?>ES3yZ$a;^}LHr)Ya>~U$sWvg?VPtp^eqXS)7 zPOc3MO1mz+li37dvC&)=8Wzivtz(tD$%e17%F)}<51+q>Hs{HK#uAqrne12UiGB>_ zp!EE8wCw~=tA@>X>dAz3E#ssNY3jd;1h^&xDJBFqh97(QddT7r^5i-6U5cBq&9y2V zqvYwwGA(mSp1O#86u|x_ybWSAbJZ+QG zf3$aD8P6E1*qn-LDrf~fR0wv6oZQ(rWlI<~%0ba?_`F(s=L9X3)Z4}EE3wI31dY^z z*sg9v*PgZ8?DORm))Iyswa0DC&saQcIfg7P?9Ck3zPTv_ubckBQo)git$iy?!3*F- z{-u&GhS?#9Eoe6jW!bj$<0SSn*;c9ik6GEzLpEpckoP64nwvj(6>nc(s@Nqv;RKLl zApQTg;SeZ{GqKf#dT2e!4OhA;H3wIQ{?xpXs2fu7s}AY}9?0Ir(`nmD=1+6o$vWlX zn+4$?n0!2}BR$90o+aq#O?5W6*shB$h*U?vC*ai}4*Dhwt?v6sY|)Ryo0?3X(~Ryy zW>5dEcOAM*-mG->hs-h)dYI3Q^$*cG5bE&`^nqLDIGM7JH}U`Q`Th976rv+ipFxmfohJ0R8S_0v>n-F=L=W--q6hXJ z7O(M6h0gwZlXxnn`FaLNPhh5f;~x3u)YK^h^Lul5f4uqvtk#H^BkU!O!AO@f@?wFW zBTskOJ;%)w89bZ<@b0eAX9KwoYnj-6>Wi1ZaFpZ+Nt`#eB4E{FtBMjsG9<4euFF#t z`zi%0-I-6(?oyeA&{qU{9WQuGI8k|4Bj4z5hs>Xhnno;HA@s53M=7M|AN1)e(ao$b zblRV_eD5LhE|M9Ts0_@f$|GInHIU0hF9D3+u{iQdSp1)*s~)zwdc=D0Ii3<9CLi-5-fv!Td4_t`1rfRy`zX*=LwPND^+x zDc)#8G+X~^)=2^GosRa^Z2gXLcCtoGgQ*4z|EO2W$YxYn@M1VX98m2T}!S_$L)DweK+_Jp!pPR`d%{brbimc-=L<>`L=udIyR%z*5 z3mjjq)gswL=PF*`rj-gjw2C^#9kYNo&~A`8a>@wX1ih}T=wrD!aUDi^xm{`88};~dI|3f0`4YU<3|n0LBh@69*WrNf~v zvobijRy{w-$ulF0!w!4=(@MRQvZsy~F{8zng#(dy(kvs3WJ^z9rPZMPM^Z7kd}8MH;1>pcld51-OIj~!W2VT2W0i4^nSVA!TEB@*fK(sVGTjN*~doY z7i;oHpx)zwTii0Z7Pe}i@vNe5n-UTsz4nEw4k@jznK)7L53S$)ovOKm3Y9bt-hHN) zxGoJ&-9gsdL*1h5e__dIdXx=EO)wpBNH5XccOecEULb=M07BGirMu@^G>~Fj-qptg?~>g za+?dj(=qqnoNHnD>0@m79H$+S&Gq;Po;Rb~Y@1A>Vd&gd=bS^_T&=uiY8fl7Do!#D z5}S0tN>QG$<%lv4ATcC$?kdv>xjtVg+?K0P3x8Y*=YbMQKotjr3aLn1Bz*3BC97x> zf1TNEnWY9$3RbGVO+cM{=Jq-7{yI{AWLAFrN!|k0ZRZ*GOG+~quNVT|^a_kDxMg8k z)7i#URr;2HsRs&#z9>_t#e%%IfEJ$r}YyEys) zf+*qGh+qajAid9Qu;sqT_v6)`uuU*1RHwG8TE|$!^g7ajz z`Dh2? zveq$#5vmS^sm0?!zMEvbU{*`y&)s9URNo8Gm1i8R5GzOq!rCFm!iIEHX2WC(qV*Ti z*=Vwv5^!|Ipc02>KI1UC3GQ;ClcYyKibeZUi?iYsFl4t%DPEL^S{JldY39|TW+ZX) zY{ai&ar^JMDJ5>xxgRjo_3TeQdyS2?HnUf-FED8Ed2CbB&!1cWrbuXzXFTNCfcU*(#{65~Fdn$nc zKGu>pVLq5r1cZE!2~toe(>XS?livoR{Iasw%KQYyw@>`yJzw0$w9-4E=Ejs0l@zy* z=x}C^pdJ@B-=ve9x}8huOxX#Sui0tkHBqGDS+~n|ap% zNtlVD-;ZslOM{Vh5$YX;W1NDh)0k=@YMj!J65V7>F1K!i<&ZTcWyQPXC?kcvfVXAJ zput^nEoH#Kj8nSXW{}dbN)k|DWss2?Wz{vVcAGuhTsX7!URfBP$rn0;XYQ{AU>}c>TYiy8ps$Y6s2> ztN)4e|2+r)FM04^UdS8Tg0u7gH|@l249%SZtpAfb!ov0*U=eie?5qGf7G_oe^FQsu zCa{4OVGwdQ{+DSS;0QDPWBzYJ#|#b}gOrP*jis@WowWV~0FO*lrE$9;#xI>OG(I*!l*?aG^(sZ>19`xt2dJp7!sLj$DCg}< zYqtzmDZ0SajkK(!P?IhG=0)i2&L=6?FOLS54~z;DH31+8#$;2jCGlYWpZ09h!|{|C z$y~k5tA<8${RyDu%pm>8ji79=R`bz{rR`|GtBz@3OhR#PkLUkPa7YFCPs1ONnJ8| zB90-aCY{^O8jCD7T*R@!pef*n?kJuA6-Njtr9YP;dys;&gLM1HhB=@?VgA(3!0`3}aVk|Wz>%cF{J1**N0I4n>24N1@(iw#N6Z_JzXImdp=`%7x^zAV{9 zp*IUyt;v##<4cWUE;GZ~GslNGG=?qgSMJAxc6^#kLESQrq&eZr11YcM&HUISIQ9s+ zeSW_-Rtffz`2|i_frCt0T?-=qAWO7AGi)w&oNkzZuDy%y`zV68P=jP86QeaTzXL0K z0G(dh?}M4Nfkh3-l>)efQkP;1L8EXk_!*_Nw#uG=D;=a9X^aE`y=7poun zKL6@2zD$dDHRRJo$r!6PiClp?`@}P%XTor6#UHrUpOez5gg&%MpP=&%m~c4G07tdV z*UGPf=_Axsc7MWjkI)3a?h%Jezl1n5cT@^aD0T^M z3l?s)JykrjPFi{8_iEK@Wdi27QR`KSdro{;4a-PE{^W~d^=0Ebf;Fnat1cU?twB3O zcB*VMY4_R`MAJKUy#Xj2#@K{z!^q`t5lI)uTXQXUUs9ejCMYhA){amz3-5i%^=a2u zES~t=!s&kLCzJW5yWKDhat>j6Vv1{v4w%*HNy-&y-T?_jrf<%dgWK+)-})^MGHNez zse(Wyb~XXaxPCEH+b*1%OuB*2a|0J_wA=0tMRO&*KfuMs{B!PEX>-fO;i^oKe8TQ% zd7=|QpZAKQ99sXsxQqZDG5Q0VQ2SeA=>}Wv}p?gR)eBw>71LzT!COnL`(e zs1EcseaBgF$eNZ6&s*@(bqTVPMZ3J4pFN|4?O1jbK|u#NqPxpWoJv3krJQdIQ(sld< zGWN0M<^o!5hp$sd;lNK1bsZa7m&AF)7BO)RIt-5Jo)nOmeunkXsF^ef{CbPb>yuw~B)_K3|dB`+p!`?;#g=-Y2m zC7;ojH)zB)enWTgJX~N>XDB9Xt!R|Mr%)y}LzlcuPK5p1NoE9qpz3n@z1Lg&7rlr~ zii#>}MH6DtJ>K0Ypwk!9EobrPvsFKIlrK~Sdz5*I26ENyf+@akNB67{sDA#q<}@?8_+2+J2)ldcSy-)O6*;;>NeK3z8%kE>Ms^ z1Iq}%8MwI{m@)&Befy?OUd*~= zNmbP*nG|hdMuEz5gB*Yb&6~iRDiw^0a7<6H+&;f5wK0n*kc8L;nNWws0(sEQW{uA$ z+IB?9Sjf|v-L!?$yy5*287V{lQ#$H6=2DV0*nt%R>!klUU>fsiS#czI4ih(=>tXI@ zqrL%y?Z)R4FBA^?tiTZcNNt4#j#ohnrK7!iRsl5*egU~==9VBmRYl<)Pv10PDJ;F< zZ~C%gelfew{Cd|A!u5v2Z{0|wROWR5^O)A7xnn*^+6!QL$05LJR)(4uR9^ z`E*HIMtaPDrA(2J!OL<_xMhYFiq8l0&|5FD$HEK6noL$>YTGnLy-L@*t+bl(ZfdpZ ztux!t+ImsmLdBZGix2s7Rm2BwtIkc{QqDsH_fP+6JmlM=x)I8}CQy>5gx^)K*~}v= zrwUtB)o}!Z!fkRN{XX-$o6VQ{bnd&lVU7`?Cm*qimW6A! zMD?Z-l?FVM9$^f0E|s(S!>-kt(U$e=!f9+(jgf&OXZnh2c|$4~DrtZ*1C#g6c~Z?S zY*$|m;%tZ8n+wKz0rkBym;MC|VLLA01tC9qMv?Yh)n?dTC4mhQ%RwqYu0XlCXhgSx zTWddaB1&>p{`kBrjh~8pZjOv;{&2irbV!3X&e75i(>XfKje;6Gnci;nq`Y>xu2uX& z!T$v>mWgER!cqYp`4W!-RDS+8Ra(8UIqT=H+Fh?vPP!m~u7-13>?dZvpA1yvOWNf^1)4q2o6XOV!ZTI}R!X?)k6Gw_VSLrm_ zJV*@M=;69sc#Zg(eZGUd$}ow=cTc!T&iZP7G_vB}>9&PQMf=}$R!9p)Vw|*- zpgCSE0l;z7%&e9{&%`LV2S7cS&AM9hdY5eNwZNYsHsowqpNfVn8x=$OdrOIVOK?vu zUzJH6Vmq;-eb?|vRc7cKVc9q(H^-5b~40VY_Bqj(0z&bpKp@wF%>`T;De>(*$Q?Chd_rqocbGyC~B`PaH9>DO>IS4F6hV~P6{9K(vNjqa*6_){I)j~g|7 zQ9fCYYM$59`PVzsiv~}^p!ysWBY%Dhn=;nJKn>kT7=>W5(Q#UL+^V8z&endtOB{R& zVmJdFnCUV(tnA^wGq-^zu-`uPKHe)7YB$$nuCfL0jbo>(@l`txOVBwUG(hc~n(6_B zU3I7MiP924MZlv0tjIcn&JMIXHMDwETG{E&64}T#dkBiD;Ur zwzM=URRq`hXyQRY*1^wh8?3L)xKtEmW?UR%wvjuEiuJ?zd96g)iqWs+{z_59iGSrD zmfz?V)a!Z9oX;+Ul)L7by^eSO&hLwu$CBd-gV^D^}BT6VLeXUY}0m?P+-XeZ{_=J#t`X?5wack?Ro#lFw-56_;oof%uy#Nx?y z7wN03PiGB(&25eaRCO&lDv_iEBou{_2P5TXSf4b{qKi)u4NbdO4?N}y;j8Ey_*2HQ z4(A3Mb8~}VG4`a`tL>FsqGU!K{Zu4lyz%zRj3si)EtMdioI)F zrI<=aP9_V)Maa%~#yY09GGtuI#A#UVF}1tf)!xJ^A?iVb&lDFIW6`4cH!bQL%cv21 zLFc!*&e=XZWM_F3$GxUF2Jx|&k-WHF5_5^MxVUJaHUXa5i8e0&?jIA1vZ>2DUl-#- z<~&jzs1+DloJ4!&gL9Iei}I9&pr4UG)5&uJ)3QY{y=;Oj%`SS2~2US^N0w z&z}dGWnIH$!QEg8H5)Op_L!<{i9gP_8rh^1v1Y!Vvw8hSDurJc_j`X+0i)i=<+4@b z)F?m(0&3 zQOvo=+h7n3>dIo5e@;0_RS> z*q#>25@G6J<3hLeJvlFB)vF|zl^ivNvPLf{vtr(ji`z9gJ>6Jzeh*oznxD96dFiI) zM%^3D$$#M91_3C^goaLq>`QX+d{F;`H(2aYs&b)a3zOFKve)}&Kx%A&i7*LHI~sfX9fu3(Pyv|A8CHNpB-cHXJk4Q3=zlQgyHB^-tuCV_H- z^#7pk9)m>p+6B?KZSJ;h+qSLUwr$(J+qUi9wr$(CG5vqvI`__;IWu?W!~Kw|WTleI zT1hIYG`XkR>t^j`kS1wc{l0gC8+{ z98o&#D{v?ijDSq;9+=TSvu@T@b`zc#hEzO zt}3;nE-QH6yIv{7dh9E;mg&3TY0&vujw28Qy=vORkTLVOYh}TdusK@9LNSLH>wo0V zri^r*vhU6VBOTwjp5U0^<<#9B_s)Q^48RksJ*jNdGwscm4j!RBb=Mm+w|N*!v~u>h zK??9e{_Fxr0X$nBZf*SZ8J(G;p|X3gbb)_uaBNc)l?(_)31t+EPkb%IP||$ytUXKTL0>YU zb&8|knvDVS#?WTk1?{tX-kao|ItXm>aebKB4mh^yJX%cyXPvxaur)BR^t@LoSem{Z zvM~XjzU2Mh=-p9juW>WDr*S=4pl-LCOO??I-F_vEiSi(27rKgl0xl(km_2#c6(77^t9z+`vaR~(0ukvL_+m^MpMAlbydUJ>kW()L>Q)ntJl+KBmJCEjhhOiJb@_L&=02qKuT zVc43mh-8U|O6zq7r#J!-dTC2NzJ6HUm!YOtv$$?iO5aoBQ|u_!~vykl(b++fw%g_2%!c)y7q7 zETVlv*YudtoKZfBA((6mSJT%HKCQm5F_erfDOH=6P*^HKNXsy97ajXmM8+5EnCdX` zyf*B(8EwShJ#yuF9P;|d_T>-vBnp3p<_)KD4Mb>w<}4=Jrve$dgh4=2{vavJv7$4} z8)a4}*Xv+b+2YNKClSn_y~|i?VlVBX95Dv5d!gt=9GUGw*o@=aFNb~P0Xw$E^69FR zn07Q-DTHp8)qqWdjR*7M1vrxV>uEeZ0$Pf3bzF%)K7z?hw8lez425gq!>A)RAZEHDt#kSwnA2tEm`7ab@oQI<|< zo7)rRQ$*KEA#Kh^^m>Q0tnP=_)cYAjs%=bAa`&O?-|!iJ#8@Gc<*>PvZ^lo}PY*-J zaLm)5O4`S;e*p>}4Ra;&RpXuh?dsiDWy`7-b=cAvVdH)3?oj8y-Ci!eY4KzmaqpiC$6!&Np$P<>2*wn{vSU*JZc$ zboDYNXM!%r&dPazEXk_ac|_&Y!sFQKqLq3#Vf9n(g3rlPcrx>jR)-PkzM?Ir!{fx- za42e)aFgy;CS)^F-0}kle63^+eN}DUwqX;ua~#{uwQ;j#7R^99AB0OpqahP<2&BcR zDaW-BZh;F;7{^2);z$CP0repJce|Av9W+U&QY|<=*9>eE3vaJ zLac4M_jdLd+6RIf&ypo2C72!*4q4DcA=MgZyE9GL6WW0Yy109U+MFS}OR@L0RL#RN zY4t{GN8Qfg?&IZo^4~cww9OAT)0PRvYbahr9wut|YV~cW-?EuxsOJ^I+B6AFzk>t5 zf+34R?$OSL#)OjP4EQ3{CP*7z=@8ilY!#Z-pCq3#WN@fKZzB^$l0gxn_oFqahZRn+ zcM=Ve_w=#%kqq{JL)Q$t43j|Yo6!%ZI_P7|O#G&gry!WJ5)3jBtIa^LWgs>gB1wgT zQxnOg_k4PZ*aJBd|CLV9tM3w!32@y)07<5;KH-9xtqsg&{?cQ&g@5=f0(K*Ahp`nV zJozd%bYUC8-V8kFQMG41}X5(eB`-UQ5Xme&ZL*PQ5^eY2g6LGPaxT@+=#h^ra_V&YUs_Wl8CE z59%SP=6%C zvbj&{y$=T#p{EjB@v`wANRU`acEZ8LZ{^1p<#UB!CA?J`oeH1Ry#p>fGRbZs@M5UA822tCCq2YZf;aE`DmsiBDXxLu>I1h_ir&3s?no`X9)lpw z#ixIYZMUeiFtuqfbnRL@u(_l2em>Ij*#A}a4dSzD8vGqoD@r)fN(qy;t%f~tyiivB&Hea3Ilqc1Z z^O!n-?2{pDDps)M%Ze6z5XwGcP73?(Pch-76DPDFVr3$F6^-Hvk>#@uXqkqN=fWa< zq-%W(o;4=ZZL`E+ZkWg+i|bI`yNiw(+Qi&Dl(JHHp7lU&Yh_{RSPsnNaI`iaR*Bukqni&kOd9slOqlLY@=#7OJ2M_(p!mB5o_lhk9BP4@ZghYj;a5jyLp< zwpEV!2H>bu)C1f4xPs~hcM0*i5=fGM$ZLkmpK3<7vLJ)pbofNkMVckA3vcfAS9i^l z53kG+&lE(qKUw}aLa)?;WqcR-{R-uuwV+0bIi^?M^ijhT#4fo`?DOsF8Z3nKq4bR9 zpx4l&2g?)3j(igOqr2o*`WC&sW>h#S_X)^1*BF6j)|2VIolJfxX@m z%F5eH?zC!#cn`j#S3iBeH-hb`S7p*|3BFPy%|wMP9B(7 z%;@)RxQl)sbn|-pG+ME5*)?z8eBr`tuz?i}eO}0|9TY1y))~p0Pjq|2nQxgLXP2ln z0Ksp~sBZNe?F%j{+c%VFj2KpAKa|AjCHkDookfC+bG5i@Hv1YD0uF3X|GAa84OXEE z0vMSo!5O#i&}{G+ATqy}-UclHFL8JdpsK8C!puN$&$Seh&0rDm~E|*^u=n|CHu(K&e)GGY>DV|gRn zTM=8NxgA5*^w>poEIwVLuKrU=di!N}mNzm_ zhu>^FHCRt`%7uJv9mVD9(=vO~c zV0Ducaz{NIOLlE;^n8)#;(cO5CGMBP3G`F@^vPK7g$9dX7X>n+9TZw=g;f7V%e zKDbqar=GU`GW;b<$9uT>dj9H=I$;cXEV3t(V&vqXDsrWpRra~*$wxE9Ce&WhWmuoF zKSsv!Tp~3W1;~|t6IzME{xzC=SaoF9oM)R>Xf_dJVAJP|<|-ZiB_>&V&0!DM#KfK= zImkPrbc*&$`p8tdk2eQ+gLQak)+Sp)M42#EF+GlqsMA9#$!5uER^K7QLz5M95#F`G zpb?UCDr+d0zTw3;3#ObH{)&ZHAZJuLYnNkk&ldbxx8gZ(@#uJnQ~7QGCe9niI{Fa4 zi&2Mmlbg|8ELnBUbJnz{EBV(${ws5O!CU6LhQmDFJ4??d>WVA?NB;HPfn6QDS;+7O2kH`+`@jy>=J)K0f5HfyvribEgV>E*gd|aj645v+!M% zHP-@zQ|zhuC?~$h`M53Gq$u+5Y*L8VC2x$)9EGxI*$;eF zp%fUlOaIEKBJWa4Qbk*^t670a{%*)T32-hb4<0kJh1f*w2h=%WcU&DYVxGV@UxR6r zQ7Q@zS~b38P9fUN+Iu<$j`#QwNf(Q_9RF&YLgx`aLa}*oML!gCKG4QH^wDu2W#1jT zisQre-@_3LY6mP%CEVF}g`6Jp9x9(;j6~r+Ay~V z=%2z^uW*zAIa`2p&Y0L+0YjhYZY7|P5D`3^v=;&PpiW!oGu}xz8u_JY&mYO9Wo&i` zmz4b7{2FqFb-os^g_Gp{yx>^;);-FJ1<`NBW0D8NnW#E)G(xMWrMAKxPk&F@e?szx z!+bcPSDcs!{cOOh0d0WZ01M}Hwik~J;DB}f88@y|Xin~V?%c(<;XWWTft!KOXO4Lm zOaYBY=)j7hSHF_8qytsW~eFw3*kzb*bso>930;eMJo7#-R79@+4+ zZ~MaBC&tA3Zjr~*k}PBGQ^<>dAw6#2|0(@hTcQ`gagp;miUGa){(+$LweF)G=~mEm zp@Z!!9XDKFBSp0UJlSP}N~;1ONPCq*9rXbLUjN2E+j zzibCjgXEKV1f2<*k1&r?PS|`_tdDurXI|nZ8(CEYxea}H2cmj=KXXbr1?+sM|ep1E zr*_}Ng*OBDd;*-oE_%Nx?hWej1$ENy;JKDRdJF>a4$mF>!PLW$3vgr65i$Hr;by$} zvPYuRII|qKEKDqRr}7i)`9ya1 z!{Us9pReq>cDM|D2KS`rIv>{orn673=PJ@v)3$cy<{oJC+9Ygs^>gRgv&WJqTVa#V zudU_b7_X8j4#>wEFlWgB3r2Us-QHAiS=6$s7`_!*zoI}2Cn!Sz ziGMwubHOn07^0>>rK{7YT_ z5 zaN1AF4^Le1Cq~ih@6LP=8Nd*XPw1UQZoce`3zHwrZwClSk8jckcvaw=*MMgNUo7&E zm7ReZxBTyQe)xl3!?{E8X~J7YwQtv;hWMBT@9mwRDz63Rz;ik0jz39dKn6SOx=7jX zeyluw!hl+igmDk#0+EZtZbSJfKl2^lnWH>|+9T+1ggY|l&Rm}mM^5GD9T?dn!hU_u zl9dxo0hUfGrz__(DjKUrdl~fXe2dYrRt=F%RS-SSgr{-WS=XVGh4~?#FcH%Do6U0p zZ-)SnpKC6?`v!2YyTmMd*K^~Vav+(AJhnSD70Yns`8V|oUEfv2ZQ)|6o{a3J`w_w9 zG$Mn3)gjb_cL3=x!<~$WLZqU&H$qYh2IW$&+)zA~sD)wr*f-4UVxxY>Gt0B62d(sP zCVmU$j3_R3LW8H0^h-S$P(<)ek&RG z=L``7qU6zE?pFTjfdwCFSG<~q+4fHh!KShM>NLGd&s~_VsC`86#xKtykpz#yy5fge z`%OE@-xDnBSMKI9)GT;Wt%w&PdmFR{0TE^|8=M`F+J+Ihrb77=U8Gou)D!`6T+uS_33hMv@XM8hhR82H?J z3Eod?&Cg^u9wV19f59Srg*u?a(qDmgCZ|PR{yyh5B#l}x?I_D;;4SMimki>*$~BnO z3yfy%5Gp@)Jd6B%Cwnr7w24lY{@~(5HKlPA-)4GL0jSH0xckjB26Q8T7vBx_N)<2G zLE3eW{y|>I_p}f5rL~N>hYgNM2WH<4VHz`_p;dkkEEqNR)D(shMeqTujz6aPVv*Fw zw;IuWb3XW{HG5licld2hO*U2QruN`DO-m==1nKZT8El$vLBWOgL3=SB@_DkPyp&_; zvldZ&#!PP1Dmh|rx%T$=@B8GZi7&vu=)=0Wr;N=SAhx-H9F(?O z*YkSZFCFlUB({0D9dT$6#eUmvwoI!I=>4r=`vwMG)+0}#dmewEzVB~fKX8L+F=>T0 zOgTucmr!*{CQxa#C_{mqtY4-jqT7fN_dFBB^m={gmf4POA2Z(Hdd~{k&{^N$FAd(W z+nUdKlbs|xDbmQi5@EQDTbsJfroC(v@0=cxtwS%cCu}zw16%<-3%~lxw*M5|+`F1X zb%JOIHq(XLovAt0ittnsBrb1L&2U6{=G+=aMLQyR@No$YsCN(If$sBvRV%#tLFtA+ zBYH?TL%!2^g+~hxhdSx$H3VBE!X_4+&MG<4U0h)i$|m8Jlo9ya0^wV!l4q;R)XQ~h zd6F6yQn@Fcv8LuC$5dd!6qw}!94+$(=@T3Pz2|-h^g#D8-W=c`IR(PqPJuCqkv%f( zATC69SIi>+3bWt!1<#rBR)OslIvjV>V|J5Mf0itNtKUU@#9Q-pEbh$7i2bAjq>azc zN7|+P{Z%8?Pp;~@T_3F2@Xx&Zv>SpL;t0F%Num^HvADD#aYNMHJEgG>Jr8iE-?aNfTFf9TB&%RBuDV31aN z@A|x7ub3GTIyhTI2QtGOsSfHQWDTM*Fv=ErrW?8dchS1SL$=-^7Cr8#+yL&`bj`-v zdsSInR#M{Jo=*kLvI5&DM>*$FpR4r(Q)|u3)er)O?qxL(_)@nPk(H}T^SF@v9-@PO?16Xmf%>y(KT!4H&TLqY7NKIU{p`PSLR53Qms|>O?K+p6#71Oi z(^l&_uOPlA{oj?HjnT>ayfzc2b#66L%um1$=pJ;ojb^-uFbiV8yWC5+G2djB;ynLhY(M^8H z^4kcW#V+@pH^ogh)&&i$<41zz>xjS}*rM6us`j>hTzgB}V{U)_FIv18F8pQJ%wr#zP9DwV zk^bkUcHb!*qr=CmoQ-Hw)$6a>&5<;|wa>u!#&^%3Y&q8(z?)>8SI&5X72V72Sewy| zn%3tlBhPP_SI$?6sT=0c2G2=X72KMONfh`#6`n|(D$bP-YHpZ=KcZXmYIzbpD4yr88!O>Q)v7HZo*BR|G#{tbMV$fl&h9-f=$mZ9F zXZQGudSIm)yQ%c-T=oMg7%RKD=e+Q{>S+|@$3URGi~)_+GN3v~ZK{XQ0qD(-oZLl- zCgVp`%OQQ&tP@;V^gUuFfT+}L%WFv3M@H;N7I<(#zbAbR6_Gkw-=F9eg4g--H+u3TG%|I{4(8*aX6P=jjY``dFRlq(Jh<57 z-dS9B*k?zsHJLs~y5N8ca4mx`=vppsJqkp+IEQu?kvQwxzUYQFv4%c+f<`ow+OVY; zwll06W2joZ+K*g%eBfB{u+JO`;!v)(2`_P7-1l%|Wc&3&f?MzhWFTU-x~h}`#%Axt)mg7~FS2$1hQ zo%n((5o&DE-n4{B9s{Fd{5*9-oR5 zWi3`tSYJzq;^0 zkMsYxpZf2H_TP-^=cxZ>oc_a6u`sax+fgwvv9LpNaIpQa85KR-|H!Cl7#L~)6QyGL zuPN2P=+6H@ss4d)|IwfSEv5SRx%-i1{|}||{(mWzG(6%_d^xxgg``Tj5FX_vxL>Ed z)S&th_RD*^P68{(0uovS7n81gW@h>DSbEPNHokI9pzEkb++zDDC^zWNI_k+*R!S=f zR~F_N5(RBKCBMA-&5^MLvg|p z))AwE?rlA;N^6D+cbFP3qXah8NgC%OCa zqe=wB;D=2lkjK+g7y|D_Nm|w9=LQf`8nkqr&(P#5Bh3J;vG4dHyF?m#(w&H0R1}NQ zt$kuDK5D%ylYm%#zIHw@zjsytX*$-=V!3R3u7*MYm=Pee!=LCpgEG%>?+PP<2Q<5C zb$T_HYPagA1Z)HaD2J!ha=0vFVdLdQ?1_@G2%$;k^W5@W)}sSpUNY#d1y%p8F0!Ah z7xQ`(P^6~qh~MZ+aCANRHJ4!QXxh)BqR!`n?$_mVdSRJd@h$ZSn*PwzijJn+>+8<6 zr5YYUn#I5y{Tmd(7ygC*$ZQlG1@F_bvc)}EuHzUywGc7J$ z9~V2M$c}9z)>!4h+6@Tlckf+)4prg){(bGlZzu?qcn2GFdq z*_4uQqUn3^dB>e?iOjBPK2TdhJjlDaHjYl(PLfZAglFQE^>4*C!cG)VnNYY^q-rr3 z&fS(9H1mRjldp%%FeR$JTFh*JHt|I8t{+MRs`ZV<4dA&0ZwJ8}G!03BrpV7Z+I~ zL-fM5TbeCfF#ngV7rbDHFg0*tBaEE~5PTP6Ho<~1fq10K2)r}m_zgZ+`gVsO>Zf3@ zFPoJ>IxiU4Ey-P`(jonuHC0OI-U%=K(`~Ah$?YKII$1usz#t&5d5s zmfZO~d~r^XyLTKg5(=TI#je-EvDOVqmmVSo>EnSMvt%SkAJ)54S@}ci!`Z|5DLg*N z>xv5s^DdX1A4b??lO5AVpjz#<)(tCmXg5I;`%nF}!eC)RBd9dVYGLYZ;_Wz}GvTkr zIg-W<+@t&rtq+*5vM(J9v2w0Q8Op4!Y}sNx$?mcn*I!ffVc2G&hqa2kD>j+O#_V9< zu-p6C7D)Ws!wI)9UGO_EVk71#WHg=eSGndkC@ub6Bc3ndis*&O#kk^+g%$J2^3Ck> z{@~@e7~ylwIBRwndPFRE{?;RDxQW@%yEOwcABCBjVzk6ng@M%g<0B6B0hNTyL@GJ> z?IXN*ysu2JREK5hoN=-WoGD-FHihjcfN#7!Lx5~amWQf#6|K=5v{yJ+bR9kD_lF-K zU4h-n-LjyRvX={8?rY8-=HHoL;O}~pNyX`kkxJ)^bcI`T-pQB&+XOW1`9!({?725ph_~5(snht@2Z~;3aU$a1vh`U` ze@sX34?rE_It0Fic?q`V16ES@kcDVcW$6Z8-QsLYB;F8tx97hn5A6rFNz?`x?QvdM zEnC-byswUVcX^K~u6L+je(G3!si2mmm$b<>i8%8=rk_bQ<#w@K5>2TieAwB}p}%n2 zKw1S$B<^<=`sUj^0P~3Wh&hfzvun|^g=Yw3nZuB;hAMWU2v4FlRVJ4~1QZ8G3$V>2 z*?{E?W9&jLu;rr9YMFy`%Vq~FIZ;clscdLDQDqHU?_TeokAT-=9)nmA^6>*R$8jEP zw$}o2DED0+Y?~03H*T0ODq2X^>~_m5T*;Y%iy@A6%F+^g8zDIpHW@t7Lg?$_d;iJ_ z#e6}O{K91fwsglhiAmW+ncNO%;gou#&AEKaP~Y%?1TDdzS7w~) zl6mw#m$pCO#FvDkg#CE)rTS%?#Ik+n;g#Z8BSwigQVVhqwnxjiEjMa+%lm6iP*q1& zcJSN~bbA(eA^MFBhSNfcQh-*jV;I>El0oJi{qx>1h=7*eG$aIPzWGWSmuuMcg&aCF~nZYw`K$kl;X#DR!nO zZ{2xpQsxQPtW|prSTSHdvQ!IHZ?Q?_H?S>E;}YC)BzWnVU92F-Lrn~OF9<+!Bp@R- zr)>TtaweM0t9%#uBl%;4h|3#g5Wer{{G|EZH z&MjmkH%Bfu#^4g4yaJU`OmGsP98Io3tF*o{>)UOEc^i`7_wtrta5{xeW&TZh3Pp2G zSk0MFTw397gbrE-887J}Br_=?R~oJ#cR)DVa7;obV`FV|H|n4zVV}S}1v@DrXy!DB zq>|2Gz$l}*nYuteFAlxB-osf|@$%Z_`T#{=LS&JNp3dfJVwsS!IdoJjYQI%nc;04s z#iW6~v9!`=VpbKawSJ*XUU#w9WLbEyG+HHOX^hs~wEJr%MO2e>sd;C?6(4a}F3FD7 zLrTjsVIx3E@*nZRTVqped3wj%BM!BGsX4=tZ`PI#mza@_5OB>7xoU7g12qQr+86$A{k@Pp5NkY~iEhcx!qn9=U1vG1^IXKn(5B_LF&Wcm)QjCi& zL_vuy(1}r3;wJY%U$kCxTU~laiA+8v9zG>L9}BaOgGkMyqb3}UwU`_iRazxIF7*@{ zlFR6-%vckpg<*;&@r-ED69W<_FLJ6)JS0vIyagfY#NrWCJzW0-aH4GCUc^5-eMyp=XbwIG zF>zUx#wbA1F9-Qn)yjI8QZ};*2;1mX#?m>^3O(5rVG0TNV1Y`SeZ+pYXs*6G55m0` zUa>I?9rWiG^79rt2yYKL=!<<}_1Kduv@}H2~2U5aBQ%cv`y@N5#lDTw%qGU0sSSFeas{utHLAx-|{($!e{4$yaVOGAUb_aNb zTIm_Zo#%;}O*!DbXf4AL+H?r+a8yNG;W7M*pLkLH^@|oN(Rjp@3!`|dKE~}{%+qw^TO}@!_W*u+6|Tw)UKL{O;EDX_mhqE1 zOxStnOb^`=*^cbnlCWL(TkOzvRHkkTbf5}I7FwldGHL1(@T^{xlI=O*V-jDhrtOW|`iBa4Ek6}@>h3EyW+?y!a390LW5WXiB?0Vo5BUy60&DWZ>T!6ILzjzaip@hm-RBP*9Q3Q2B#@ z5qWBuXO-V`5)=a3>>$ zKiqfeFN>CWE|KrObkhSRjIsr4$ksNn`A$g&A@TU_2^9?~vemgO+%#_A_J{`03~VV5 zKUncBZCWPl=^AQUa%%6y#@8O zUzHkNWz133a)W}+1_L|@H67^@ydH@$qnoS#?)qT`eJL~}8ru+h`QG)=jWy={q#fDn z0$NiWAuyOc3$8p7QAuJ+l!^0C%v8b7raj$mB-wccQ?#wEH4ffBfAkehvAXr-0c4Ci z9J;BVFVJ?$ShsFyZ>7_5X+K{;-x#Mh@#B;gD|-7YV|H6PlQ7bNIk63>j9IGsh(nO1 z8K^t6<`?7~(51~MF@4I@{3=Iou`#6zR9a)ojMT-49cmSo!1e;QL|y)H#fHIHRv>J^ z;5*It)Uc|e*M`V6;6I@B`Jf9L+7{$Q3m4E^JRd5-BYD(wQ37tl=W4TvA77~fH221~ zk|`{SV|**C0-VtI2~S1@bszW!e`{MLXjUcN&Ww%>tf!h>2XrTIaGxQ|lmB}Q_r~oF z9yTGiFXRF7ORyUGS*Cv^bKt-_T?}|#@-MdxF~WXLt=?tl*fPb|UZ>c`!DjU;CGVMc zxmC-NhGRC~o$g5GXP%PF8VIPlK=dzSqQZ>z{V%ua#=fh#dGbL}$3>t{%sS>1Z zp>&LJfJ1FhvZX63+#h{)g5C0{wmtpM1G7Cs2Q9#p3ZtpqKY8lpy1Emn=tEIMK(_<} zQ;W4w$l?i^^c?3jj1+&)55w=MU-jKfI`nu6EsbrfEWQ6$nmmp#z*jt1#Fn}@nYzt( z38C)Ys&yLB37L6Uh2YmKDjG2W@Xn7F`biplVsIo zoOQ|BTk}n@{Q+0^?-DsfPb$l?Su-uYkFwrda6W$@SR-?B9Xm;I_7<^Cdz;PmZ;q!O zbzr}@+-Lv22&kabYqPy-g16Ci*_=n)Z9b9`JK1Ed*!szyKe_SMFReS$trZ+zM{!J- z$^aerOfvG0LEgk+_R^7=q6{1jXc6!-TlBRw2=0$lXn905tRwDmS7R^#{zVq1)28 z(-+_()>{7u*_vTFU6U%Ao&cpv0Zg<}{x0`-uu)sN&b&>k7_ABogSLd)soHA|?8enL zmK$v=*BGjt|*BmEl$dtAPlvzYvJiEOwqF47UEp1Y;Bm&y4_`LdjS2 z`=4k!ra`T|71pa3yluznVVIYnoE6?AkDrm?ie$R(QLC(7F{=slH9Q}9-?#KY7Edk* zQ*H|rgzR-%OIXy8Ft8UTf+{+U0oud1e?kTwzT# zZP4V-j|C`U@pRBeL$*@|-Y`jmW(mR7&APv)|7-I47>=AjRoF11E}LutyeOZY1zz4#W_OFQ(t&tS+hS)jPutforj7*vfUK>;CD zXflzA?;1uQyz@{V!J<5`Ji#+9O=z!POGml$e#@J#tJ``CO9?w*k>xvnc}qNtFoaEa zN18)g>I>nf&C8IpyW=~)-;gYv*3#+0ps(`{jDb<76|t-{YjYjHlh6CDBOg?x6<#0e zHyEly5@J$BLhjPFiAX@r#Nqv49f9sG4CYUQaNAjw42hXD?mOl-?EH6FQ$pdY6u;WQ=0<|&+Ly@R_9d^hjwE)A#2y1pHJabH5`4@N1*%8Hx5 z?7QxPnY__KlV6iTY#ugu*E1VdzoW(+iX3gH0I&Qme@_W?YrfYnQc1J|X*n9Fgrrn~ z?K9h2QNXW{ z9DnK(VZjX9?q$#;=Q*zjpY9RhTYpd8i=8MvL+((qD<%8A_4(=u#78SUb(x&b19W}K->!?DOXLw9I zEOR{4xN3ABBW2EORgkQoU4XxURIV0DiUCFT`vZG}E zXM@2~Qb);?Rc%vF-n$XyTu@vUK1yz`i%)%3DxRMv<;F|DV+`<}D3est3wL5wTS(9En~3z^V^*MI$DDw~K#eVc0jb$Lvk^xl*5<0BqM zuL!M;ZQrgpeP|vGs@1io@&yf1si^Ifck9)-4*uL~i%rlRJt zEH;;qxFnddf*8lEE>` zc^7#A|4p$WiJc=p&3hYOh_!SnbFtK&^(y7qTXbtuO)+SpG2k!UlWrkz+YqqSPusge znWmn&KfOT1`Uq-wg{V;c&lkjqQ)zys3IbB}3-tVWI{h9MG2rhH1lqbxb>JgCSvHexqLPx%Dl7CZH#hzK(zkdrj(yqeQ33eu5g`brnb3RY zh{}{TktVIkssd#;waAS1O{Bym%3PPP?%Ou-ZCuAoC)~;Tdl?uMLk+U&nIjRbWDE-1 zqqYKBL_n^HY&UH$?fh@wy)AC^CUIlL$#8jen`#oJnbVOQE5}Uip>A>K!B&am0%-y6 z2rnb_yV6ETs=F=;2Wf=x!-1@>w@GXmmzA-h&bQDuht?p0){x5{#Nx_yo%tOA;7Q22 z+8_Ii&iBnR6Pt}^pB%Q_dY=aci@Ve75OvB20X z<-GynjJz+#_k9Xcx0(z`o@!9?L%=pt<(QY+g;~uU{er z^3LjJ4v!6^piM=gpdE<>4943LV<%gb52mM|#hJCNl0bw55Y#RQiKv8u7;%WiK<|1zx=`Jk{G0|d3J!M_=hh>FPicv*WLz%fS z9aB{!TDl$j8N**az&*e0KR)S3Ifj@T$QhHmB$3;n zd5<8x#pScsvwh-Rx%!Tz2B2O}-1efaSSU6xZhI1DTTmEMr~)|d76cCSn5w!^aU6q$ z#W_-g5lq9a(soK8iJ>|(Ff68Josqy#tHwmi*3PM)`8cRpT*gh#^NBMk;U~*}vMjRZ zsv414EbuOnBeIOaUWT7>#3aRJ;Iw{VYNag)`6yD|$6MJ9lUA^tfH_6`iK_~vl3$>+ z_wHj@z^78YU~t|1VcofEpy_d)0D@tk7Mj4^JLA`WE>N2jj6|{@x09-J4>B$!vB5Bw zP{*X1xan7W)fo}JBFG>;EWKscHX7)xHMsq=g z@i@tuQ%#JKePnZmjT)(Yi2A;9_$p4!X9U>OAH{uG}}O z8;H!CVdlA^cGot}P1gw2V5`|Luq{q!TT+u$C&S9${A-tRhtd+O!&w^nLSt)QCgyNi z?W#Eyg}xdch59kt?G6Wn{XKzNlKYYyuVwH#HN6_@AxDQ?umA;eP$!?_9(ljoPoi;loy9@*X*p5aRqZ0&8FmXM`dz5 zUTd47b}Ge=c0m1exUiK+zMt1C(GJzxhAPy{%aeYXahpybVjNSc*;wojj4IbAXX(mL z_4rV^r2Y>*x-5^)h`cWyRaMm%7Sy-ptmW@XjPGh|m3^Ae?QA0alkLqc-o9Z4L6{vv zL*yn_vTGC_*(-bwGq>0;jYqunXPE!i+E<4~-L!2ZEg&hK(#XNX0Gd+nOzRfIXBvp zUucMA^siDsrrw}Viq~456mqd<6t;|VNtJ#N>~7p|TgcNiDZdv?!6~my{t9Dxz;DY? zNI%A5(#!=jC68jvBFVGiH1ag}G*BmdizDNpW)S;^`&LcO!9jJgkqSukgPE)RxCJe4 zwYJKXMKJ0#!ye@SaF`?6LU~lq6f?UaS)TRSvWHvkTVPXHk;xq@t?_Fa(+kD0S2R`! zG*()^%Z6M|gNsA2aOpKn=57`iiA3SJ4ziX};gLg?)(+N?*4k2tdn_t%X*Cyn--ne9 z_4rY|&RiASc{GdqtmVT|g(XD(bN_y|{dw%Q@e{8N?9weuY9yDz@pm7llRg>wh>~*C zDFozC#OrR)ZYS~d)TuY1az$F(;MRbrb)IKrMx{<+5PUva@)cOhg9dsQuh_tx%C|=EXSi z>8fB$zXS^}ApVDJQ3A_omR!sono+(l7lU!kbW63(j;=N9o%UI=rb`)*^2$|WI)2pb zo=O%f9Y`LnGbW|vn#&N!`Rr|BrI0YscwHFV_pgLl8aS@)PUr1|cpyVuu3ar1H-oI^ zr-Nq39gakU#yl8y?df*~vCWsx#7UJe2JC1bb_N!Y2ruv)r~Syohv8UwtTq*Y3|WeE zs6Wd8k}|LIqcA&VkBRqF!+!8b#q z3&V%o0qnrqh$FU))sZXnS&s9KZhyF3WZwDCX|MiT1hL%n_U`mPtzvxCrxF=jk!G?| z8p_f-snA1KOTy3dwkuPf4oTt(g-NDO+Xy^%Q3H*B)i{c;!%oW&Y^E(g=bTIt1Y)Fb*E}d#qKBGxE zJDBtCqJlvb!u0PY4h!kc6j${3g!}hW7 zmDL?g6m_!a`lZv?M6~Gzh?dpa<=P7B?L)K|0pY$I-MgfQBE2S1C(k)#`dIG6GIjgm zqv&M))JKYn&$_&WQ$HG)5dr)5$#(Bt@Lvc^t{zoAQX*_4V07{?j8@Sjp|I;AP{@2= z`>-W%Z@+9l8rfayT;LgvpyeEt$dq(W8J(TQ3+?z$v#%>3YhJ95H|?~%Vu@Y%Lpmti z_1G#UmZDT%&m|nA)r$?&tR~RU4s4Nju!T`G<&q`0(mt55)4ovYXMBy69{HNDkD)+G zN|-NYVUfteM^gzovMQGH3sWz*UOBhQWx-*1CjAX4-Fd|<=DUVw1>cN|KvAj4lxyo9 zqQ~Q}zfmzHw!8@zC{<<^%vXNfq?*yvF5O)s_ZiS}+pH;)gG%#g^ITnHVz=C_R*>si z8Q0`nr&{%x`i*803$n-gdwb0uNrWa_r@i*^)3#q#w4GORO5=BR-JpHx2Zsg4MI$0g zy)vw%6{hEoM8tQ_CddYp-KE3Zwutp5U3Y%0;K`Pc zUa-F|&H_I$@X;T_F*jE|@IQ|JYCGyd;;9QfETn}e;%DrV#eDvj6|v#=&2YG(Kr%;D z-~7|pk6mXqCzLHeaVziL1NZuGFYN}(^z6~uMdH8hH?G9jNXgx$A$-=wcD+E7irB^^ z(079S8PS5BmyieREh=go7uEDLf+c)}YX5HPIf8c|L*fUIF}?WV4WZ??^Y5H)WqE~U zHwZbace1ag$|g<&+`T;mnhFSgXDo@NR$fZime_G&(b-deu7B56fcV+ov@Yd#0Wo(h ztaobL*L)em*<=^}tIA|iO*giW#1t16#N&3s{5eI9BS}mnL?ON8P*JCy;G&-nC}I$b zl67B^lF%{9N}v7y4o79-tIpHcIM8_OFu63SRhJ$IofoxPG5MZ(ypSK@diCA;5`LV$ z;2~B;C!*a0K{x)nBi)J*iAE1Yge@c4F%n|FOFw<#ul|MU3+W9}6G8aVD@2i3%>B}8 zC2iqZx3jjMdEZ*)H3ffK-F0MuSxTB_0jui_9Y%^y?*oafmxo9?2|VIQl3XG(Rr{9X zqM&6y(i54^;%$rLq|HVci~aP@M1JdVufl*o;mkx)$vnL|ed$JK`v_m2p>cbf8kKm8 zf`y7IEs4pdn|o&fX;NJ7m`c^8>li{oh?YIeEV?&ZwmD5Vba+B;LMS^yoBB1OjA-c~ zv`&DG#nTViY>XLW#0zrFAw+V<7~R+?tmS@cD=1H=Z}3fcbZ@C; zy{Pk+N7G#C`#5seaU|;&TN|mb8MSPke#IpIS~*^-#I2lF6VEh}n-tHw-Uc?Qn3|7x zepBJIoW4ipm$pWp6Brgd89!b%F;luzwc4o?n}i<)LJ6soi99c>zYou2&?NS{fs`=N zsFG8s(|2z1gJf^z?q(O?vV8e{H650oCSIMq94AC~yN=;>Fw@{`EeF^`bHk0Ax5EHP zRmAp{Ow}_;mDJJ=a|l7Pn96;Bn<)3>^5kU#x)30`#OpU1ZTxVJp zOrXk@(i9yPbrZRm6I)P1RO(tsGrdiX9~GJUIQdYD@B~x-Q$c*OOXzZkh{ZOjRYShu zedU~LS)$=wO|MJRYMH%nT6AW(8udDu*xUOWgL=#ZuNH-QlcVgLhs9SqC}{ zxqClXI&5cu*846T^-)SVDRjf!e&KnS%$TeblkGlxw~bh^zf~m{SyuUKNDYCkB@4p z=b8pwr?Px1NOyiB^Xu@ClJB|R;o@!CpZ%%uO~C=rijNNMnYR*p=)!weag`oxkbFPn ztvgQ@-m1cR=1DE4-Wj`t`akxWVNkK#IjgIPcPgSDCvat-nN0?~ugZJqqs+{ZpS?FY zBY0cD?%feP6bE^YzVfS%rB+@*wAn`5zKux1#Bok@H#~%99Nj|?!G)T&C_;;?7dXooO0LImJ*gd#$4$_ zmL-13!=N<{C$)5|CjC=4C7zM&!*_=~gjyT)4WlNX*5nzQLL{A#!$3H5GXEr5QgR44mo+Mt&VlD1G-q%v1MMHRM7@hVG}%n^Mqa53m_zUV=7p%$z<9@G2M%>4&WO$CDE5=`S*j^h@BUA)W5w-&H?-nEJh zr7Bh;_Bh~-*AC6y^_=vU1s8bLK9Mr-Pw<5_BcED7f3D3fDak-U^}_$KTaoAHO_|I$ zlwT9hJsU0XRD&s@eAfyM&4+-a9jg?k211X)=0*468jr|Ai?8!LwT(|{cSKg19_8Fq9rZXfh-vZAL#(lZI&Zd-{Sup_Z2j`9 z_=$#@ki26i*eb=2Ge`y4PhqVo7x3s{Df}$UIy=#0xK8kyhyUfs6Uu4!ho(qLi{VLp_-_JN!8{fSpDY`mq($Hlh5KC-G zCcYV9iqEslW5>m@O>4{YaO~cU|Kc`c#5O2l&KoXeyDjJ?y}2ZyO6crBS(`96k5$r4 zq;;d=g@!wgh%xYRjM#3|o=MU8+CED~Gm{pHnzS#zl7H;hak($W|!)+mC$ zv;)rpODSm8hO49k&N;EoeA4YkmcD$?+Y>QfHtjDL8CVvYclHkB$ zCy|@4;}2R~;`8d6%p?RRz5Y>2_Y4?H#WFUxwO@UF=)-x=?w@5V{c)9b8d8#|f(06z zzxf47An(Y3m;t4!VEr!q8FM))U+kFz!)j ztO@g-Hs7IXW4m_5nGt}}x)Y=Hff3}>t)C5yb-^S|zHUb9r_LrV6|~&7#u!@o_gM;| zEx5@&tuZTK^r$S1=49*}bw+ef&K{kcg&BHzDy|{)gMdIj#(XG+PwW_t+=z) zrli9p_2k;{4}#Xk@5te^jRdSNY4>xY0oK5Kq*a-<_1hN=?&}xC!z&k9HK@1nrd0i( zeeL;uf5Ckn>3n&v8~x(*1rR6wB*7q~=GrMIswp4~$2>N;)_G1SH8+c~gw1V8N+?Mj z8Sz7XTi5q3i`2f2uW)L?uF&R%_&MP(oC|-SriMAgZJ}f8GfBLfxJHz}hVn<#_`}uc-{0Q(t#O|%eZpgE5Mk}Z=p_n zSlq&7nTZ1^R>WRK6l=TQ6fG4H^bEh$^RMqyTp9l?`=(t1txq^T)!fUvW7TpF+_eDF zN6?)I)on=vO?Lv)ZDb5<$%Cx=+Cephb$nPq=|yVR;rl8aQ{Bof4)x^ys?EWQH9C3v zh3^u0*3A_^7$}Td4)OETljFt?G~c!-fKeXtUb7d5sRVO5_SL`$9VmdG7YJ+iV%;%e za>1WFoM7#XrD-=79rZ$@B}w*_X(HOhLOL7-rj`A6UoIzRyl|=US=REPSQrR|LvBTB zb$JFB;>*WIYtt0T!2=t41g?(;-e;4zp@(&NcaG*dQURlbV>_?oeRx4j@-VKWZ|ZZN3wzjbA{< zBsUiP=EbR!as{~O>FSY@gLEO}= z-7k*wv1&0eWe2;0&hdjt!&w0St8BpCD4LUF|C2FEL+fmf3GaYNxw!|gb{)^kCv#(G zt_7Ce$}0JS$U+7=^#hs>Jj<2JJAX%a=?dE4g>reG*KFF1}JWY zdBb;wJLBVpxl~&3RygJ=uc>f^D7 z-ASy#o3l>uh3Km*OC<{R#cKEZp$-P>KZ>fqYRgxE&tu-O(G%Bxb|k5vGEQ9L{6Q~S z38@vR7SQe@U!SVlxr;c=xHufp5kb~klQ8zbtr`(ORneIgdlC0dG-aZ{0_%ED%As#B zYc}IuB;(!HioKzEq<)}mlI!#AvxWiqr8++MSHvNB+JLk+jT|euo1rdTyxQ7bC%OJFnN{jDf_5? zWnT|TPk>;+6ME1uDP z2ka>}N+zMg39JX)@j5iqBXAJK(SracoSGJ{>M&P=o^Lm;!@IWVy`OooG~mfp2v`$^ zsU(wXsVm4RU=`dJFjcoWoCTJvZ_%5UJrO$bu2O6?v9SWzq)g!v_zw;*6s3y!zfy=mIEw!Jf0aUn zpyVL`RSFS)$r=4W_`8=fk(a>&frT$adHE~+QWo+z282WZMt^G|{zg&s;s4Y`DN+8Z z2^5B+)EECkFR8wNYJ&d8{?hydqG%g`_xV@zO9j$DnexEc(%hLq=$^Hi^CeFk)sgBS z5m40Qa#*SaD5c2Xk3S{QpAt&q^AZIADS`i#P*m?r5c)^N@wY^$D#35LOw~)jqGEv( zl>~zRAq?s6WNtwKU_r@hqO>Ugd1_OXs#sUxq3k#!TU~~)$yxJBBfkF{i+k#-QtMdS$ z)K1aHjM6(r#}H`o1w!C3G#`Lb(y&+Uf?)`B3=Txc5O6f#Ljka>b3>&Xx(x^%-3A1K zZUYMV7aPJbG@n9Y2sHme;lO{vKxh~Y0JxfeKqwe3PXVZKpxK4Np#Orw(J|CEc*V~^ zC=@-ua5&;>Jpc;&7Yu}kAyBfjXg1)mtGNLL2&3ga3PblZ9F@^m`vZUgXfX$X(QUv0 zFtmE8?GEd&TbiyP{03^bpjmgUuY5C9b21{{R8H$i~t z7!VEvU(F#X7~OxU;i0W9C>Q~`>QhuLz}2+?2LObx&KC*+qOBuT`a!SeIO-GwU&Y`6 zFyv~CP#BsIP-h<6`aogASLchu(AGH$`{($cIvJxhnVo)Xj;mRFnxllYQR3rIo;*d} k&vJQK3;k9k|8sEvzAMDo>FMuN84kGAg680my)Q@bKLL -MM: What is the intellectual property side of neural networks? -MS: The weights and the model constitute the intellectual property. By keeping the model outside of the primary source programming language and outside of the main wasm program state, intellectual property is better protected. -MS: We’re working closely with WebNN proposal -MS: We expect many different hardware architectures will implement backend support. -MS: Initial POC would target a CPU backend but future devices (GPU, FPGA, TPU) could also be supported. -MM: Intellectual property is a legal term; is there any attempt at legal protection of these weights? -MS: It’s hard to protect a model across a development and deployment workflow. Model authors want to ensure that their specific weights are protected. What this proposal says is, the model can be opaque. -MM: So you’re not talking about legal protection, just about hiding the information? -MS: Yes, it’s mainly about confidentiality of the model. -MM: So since the questions that wasm would ask of the model through the API would expose information about the model, has there been any analysis? -MS: If you use a programmatic model to define weights it’s a lot harder to protect. -AB: -AB: Showed the proposal: https://github.com/WebAssembly/WASI/issues/272 -DG: Why explicitly expose the target instead of making it an implementation detail -AB/MS: Current thought is that it gives the developer more options. -MM: Could you refactor this to move the target enum into init_execution_context? -What happens if you ask for a target architecture and it isn’t available? -JB: Would it help to say that the target parameter is a hint? - -AB: I agree; 99% of the time, what you want is just “pick the best one for me” -Open question: Web-nn exposes this target parameter; why do that do it? -AB: I’ll summarize this discussion in an issue. -AB: Let’s look at how we represent tensors next. -AB: Is there a better way to represent multi-dimensional arrays? - -PH: You need a dynamic number of dimensions, and it’s hard to do that, especially with witx in its current form. -DG: Does this definition give everything the implementer need to be efficient .. to change to the format needed? Agree with Pat multi-dimensional support is a hard problem right now. -AB: We’ll learn more about the implementation concerns as we start prototyping this. -AB: How do we specify how to include dependencies? -DG/LC: The concept of optional imports may be useful here. -PH: Also have a PR for profiles that is a way to specify in witx dependencies. -DG: Have met the requirements for phase 1. Can vote. -LC: What happens if there is a fail? -AB: Have a mechanism to return error. -Vote: WASI-nn advance to phase 1 -SF: 7 -F: 5 -N: 2 - -Vote succeeds. diff --git a/proposals/filesystem/meetings/2020/WASI-06-04.md b/proposals/filesystem/meetings/2020/WASI-06-04.md deleted file mode 100644 index 6c7e2d7ee..000000000 --- a/proposals/filesystem/meetings/2020/WASI-06-04.md +++ /dev/null @@ -1,43 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the June 4 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: June 4, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. wasi-sdk release 11 - 1. https://github.com/WebAssembly/wasi-sdk/issues/139 - 1. Commands and Reactors: - 1. Heads-up: -mexec-model=reactor on clang trunk, use with wasi-libc trunk - 1. Update on repositories: wasi-nn, wasi-http-proxy, etc. - 1. WASI-http-proxy next steps - 1. https://github.com/WebAssembly/WASI-http-proxy - 1. Feedback given earlier is that it'd be good to look - at splitting out some of the parts. How can we help? - 1. Multi-call commands (Dan) - 1. https://github.com/WebAssembly/WASI/pull/281 - 1. Async - 1. https://github.com/WebAssembly/WASI/issues/276 - -## Meeting Notes diff --git a/proposals/filesystem/meetings/2020/WASI-07-02.md b/proposals/filesystem/meetings/2020/WASI-07-02.md deleted file mode 100644 index cc9ac5576..000000000 --- a/proposals/filesystem/meetings/2020/WASI-07-02.md +++ /dev/null @@ -1,41 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the July 2 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: July 2, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. Update on action items. - 1. proxy-wasm repo - 1. Discussion topic: WASI and POSIX - 1. https://github.com/WebAssembly/WASI/issues/292 - 1. What should we do on `lseek` past the end of a file? - 1. Should POSIX be a normative reference for the filesystem etc. APIs? - 1. Documentation philosophy. - 1. Heads-up: Module-linking-based dynamic linking: - 1. https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Example-SharedEverythingDynamicLinking.md - 1. Tooling for new-style commands: - 1. https://reviews.llvm.org/D81689 - -## Meeting Notes diff --git a/proposals/filesystem/meetings/2020/WASI-07-16.md b/proposals/filesystem/meetings/2020/WASI-07-16.md deleted file mode 100644 index f4ba68088..000000000 --- a/proposals/filesystem/meetings/2020/WASI-07-16.md +++ /dev/null @@ -1,41 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the July 16 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: July 16, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. WASI testsuite activities - 1. https://github.com/WebAssembly/WASI/issues/9 - 1. What kinds of tests should be in an official testsuite? - 1. Where should we collect them? - 1. Discussion topic: Threads - 1. https://github.com/WebAssembly/threads/issues/8 - 1. https://github.com/WebAssembly/threads/issues/95 - 1. https://github.com/WebAssembly/threads/issues/138 - 1. Discussion topic: `fd_seek` past the end of a file on Windows - 1. https://github.com/WebAssembly/WASI/issues/292 - 1. Discussion topic: Symbolic links and Windows - -## Meeting Notes diff --git a/proposals/filesystem/meetings/2020/WASI-07-30.md b/proposals/filesystem/meetings/2020/WASI-07-30.md deleted file mode 100644 index 1a164d624..000000000 --- a/proposals/filesystem/meetings/2020/WASI-07-30.md +++ /dev/null @@ -1,36 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the July 30 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: July 30, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. Documentation for WASI APIs - 1. https://github.com/WebAssembly/WASI/issues/292 - 1. WASI committee processes - 1. Proposal repos - 1. Further harmonizing the spec process with the core CG - 1. What work needs to be done, and who wants to do it? - -## Meeting Notes diff --git a/proposals/filesystem/meetings/2020/WASI-08-27.md b/proposals/filesystem/meetings/2020/WASI-08-27.md deleted file mode 100644 index e5cbbef58..000000000 --- a/proposals/filesystem/meetings/2020/WASI-08-27.md +++ /dev/null @@ -1,42 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the Aug 27 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: August 27, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. WASI Status - 1. Update from Dan - 1. WASI moving forward - 1. Sockets API - 1. https://github.com/WebAssembly/WASI/pull/312 - 1. API discussion - 1. Process discussion - 1. Testsuite - 1. https://github.com/WebAssembly/WASI/issues/9 - 1. https://github.com/khronosproject/wasi-test/ - 1. Should we work to make this an official testsuite? - 1. Where should it live? - -## Meeting Notes diff --git a/proposals/filesystem/meetings/2020/WASI-09-10.md b/proposals/filesystem/meetings/2020/WASI-09-10.md deleted file mode 100644 index feacffd1e..000000000 --- a/proposals/filesystem/meetings/2020/WASI-09-10.md +++ /dev/null @@ -1,33 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the September 10 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: September 10, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. Sockets API - 1. https://github.com/WebAssembly/WASI/pull/312 - 1. API discussion - -## Meeting Notes diff --git a/proposals/filesystem/meetings/2020/WASI-09-24.md b/proposals/filesystem/meetings/2020/WASI-09-24.md deleted file mode 100644 index dd3127e8f..000000000 --- a/proposals/filesystem/meetings/2020/WASI-09-24.md +++ /dev/null @@ -1,30 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the September 24 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: September 24, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Add items here! - -## Meeting Notes diff --git a/proposals/filesystem/meetings/2020/WASI-10-08.md b/proposals/filesystem/meetings/2020/WASI-10-08.md deleted file mode 100644 index 78d943918..000000000 --- a/proposals/filesystem/meetings/2020/WASI-10-08.md +++ /dev/null @@ -1,42 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the October 8 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: October 8, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Add items here! - 1. wasi-sdk update waiting for LLVM 11.0 release - 1. https://llvm.org/ - 1. Interface Types update: - 1. https://github.com/WebAssembly/interface-types/pull/122 - 1. WASI is being mentioned a lot in the GC repo: - 1. eg. https://github.com/WebAssembly/gc/issues/143 - 1. WASI testsuite - 1. https://github.com/WebAssembly/WASI/issues/9 - 1. What do we want to build towards? - 1. WASI sockets - 1. https://github.com/WebAssembly/WASI/pull/312 - 1. Merge soon, and iterate? - -## Meeting Notes diff --git a/proposals/filesystem/meetings/2020/WASI-10-22.md b/proposals/filesystem/meetings/2020/WASI-10-22.md deleted file mode 100644 index eb7d737de..000000000 --- a/proposals/filesystem/meetings/2020/WASI-10-22.md +++ /dev/null @@ -1,211 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the October 22 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: October 22, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -**Note**: This meeting will be hosted by the subgroup co-chair Sam Clegg (@sbc100) - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Review of action items from previous meeting(s). -1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). -1. Character encodings - 1. A presentation on: Summarizing several current discussions around character encodings - 1. For details, see the individual issues: - 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 "case-sensitivity of filesystem apis" - 1. https://github.com/WebAssembly/WASI/issues/8 "Specify UTF-8 as the character set" - 1. https://github.com/WebAssembly/gc/issues/145 "GC story for strings?" -1. Discuss about how to move forward with a [WASI Logo](https://github.com/WebAssembly/WASI/issues/3). Proposals: - 1. We would never like to change the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png). - 2. We would like to keep the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png) for now, and change it in the future when WASI is more mature. - TODO: Ask the risks of changing the logo short-term and see if there is any way to address them. - TODO: define what "mature" means (objectively) and how the process will be then - 3. We would like to start researching on a new logo now. - TODO: define how the process will be - 4. Other ideas? - -## Meeting Notes - -### Attendees - -- Sam Clegg -- Thomas Lively -- Martin Duke -- Syrus Akbary -- Pat Hickey -- Tanya Crenshaw -- Alon Zakai -- Andrew Brown -- Mingqiu Sun -- Alex Crichton -- Dan Gohman -- Steven Dabell -- David Piepgrass -- Johnnie Birch -- Martin Duke -- Yong -- Sergey Rubanov -- Arun Purushan - -### Find volunteers for note taking - -TL volunteers - -### Adoption of the agenda - -PH seconds - -### Notes - -#### Review of action items from prior meeting - -DG: Next time ??? is in the meeting we will check up on ??? - -#### Vote to move wasi-nn to stage 2 - -- Phases: https://github.com/WebAssembly/WASI/blob/master/docs/Process.md - -AB: We proposed wasi-nn a while back. Have a witx spec. I’ve been creating a POC -to see if this works. When looking at docs, realized we are essentially in stage -2. Moving to phase 2 would reflect reality. Asking for feedback on API. - -SC: English spec text requirement doesn’t apply? - -DG: Right, we only have witx. - -AB: Also generates md, which might count. - -SC: Implementation and test writing starts in stage 2. Probably don’t need a -full vote. Does anyone have any comments or objections? - -PH: I followed it and I’m happy with how it looks. - -SC: Unanimous consent achieved to move to stage 2. - -AB: I will submit a PR updating which table it is in. - -#### Character encodings - -DG: Several threads about encodings going on. Want feedback about direction. - - TODO: Add link to slides - -SC: Won’t the C program truncate on strcpy? - -DG: Yes, but then you’ll get a file not found error. - -SC: Where does this ARF encoding come from? - -DG: I invented this after a lot of tries. - -SA: Is this for filenames only or also for contents? - -DG: File names, env vars, commandline args, but not file contents. - -SC: Anywhere a known string crosses the WASI boundary? - -DG: There might be other places. Where invalid strings should be roundtrippable without trapping. Some APIs trap, others wouldn’t. Some tools will want different things as well. - -TL: wasi seems like it may be the wrong layer to solve encoding problems since it is not related to capability-based security. Can we leave this to an optional userspace virtualization layer? - -DG: That seems reasonable since virtualization is an option. - -PH: When IT describe interfaces, it would be great to use strings for these types, and IT guarantees unicode. ARF lets us use the IT string type. - -AC: In windows, filenames are lists of 16-bit values. How do we go from 16-bit to 8-bit strings? We need an extra layer. - -DG: We can extend ARF to handle Windows character space as well. ARF would be a little different on Windows and Linux. - -SC: But there are filesystem out there with different filename encodings. e.g. Shift-JIS in asia. - -DG: wasi engines can translate host character encodings into unicode. - -AC: What would the users look like? Not raw API users, but e.g. rust stdlib users. Would the entire ARF string be stored in Rust’s Path object? - -DG: Two cases: in do nothing case, use all the standard APIs. In ARF encoding case, get string as ARF encoded OSString or similar. WASI will either detect ARF string and not validate or would get file not found. There is a Rust library that can take an OSString and be ARF-aware to do things. - -SC: But most programs won’t need to do this because these files don’t exist in practice. - -AC: Not sure about this. Rust stdlib would want to do the proper decoding to show better error messages. It seems only extremely low-level C developers would be in the do-nothing case. - -SC: Do-nothing only prints first half, right? - -AC: Only in C. When there is a pointer and length, the second half gets printed too. - -DG: Good point. Don’t have an answer for that. - -SC: Curious about prior art. - -DG: Perl 6 has UTF8-C8. Uses highest private use code point as an escape char. - -AC: Using nul character seems reasonable given that native filesystems already disallow it. - -DG: Python uses lone surrogates. Not great because you end up with invalid unicode. - -SC: To be clear, status quo is passing through raw bytes from OS with no validation? - -DG: Some implementations already have some validation and different behavior. - -#### Discuss about how to move forward with a WASI logo - -Slides: -https://speakerdeck.com/syrusakbary/wasi-logo-proposal - -WASI issue: -https://github.com/WebAssembly/WASI/issues/3#issuecomment-714740192 - -SA: I’m the founder and CEO of Wasmer, want to see what the risks are about -moving forward with a different logo and what are the issues with the current -logo. - -SA: Show we replace the logo at some point? - -TL: Agree with identified issues. - -SC: Another options would be to fix the problems in the current logo. - -TS: It’s clear that the current logo is a draft. I actually like this property -because WASI itself is also in a draft stage. For example, the proposed logo -uses an office CLI metaphor, which is not what WASI has shaped up to be about. - -SA: One idea would be to replace the current logo with a short term logo that -fixes some of the issues and is more accessible. Then separately it would be -good to organize a contest for a new WASI logo. Back to slides… - -TS: It would be good to mention reasons on the issue so others can weigh in. - -SA: Will follow up on the issue. - -TL: What if we just fix all issues except for wasted space in the current logo? - -SA: That would be an improvement, but it would be good to fix the wasted space as well. - -SC: Any objections to incremental fix? - -PH: Don’t want to spend any more time on this. - -SA: I can handle this and release the results with a copyleft license to resolve any other issues. - -TS: I think we still need to check what the situation is with IP rights just in case. - -SA: I understand those concerns and want to make this as easy as possible. diff --git a/proposals/filesystem/meetings/2020/WASI-11-19.md b/proposals/filesystem/meetings/2020/WASI-11-19.md deleted file mode 100644 index c9d6a819b..000000000 --- a/proposals/filesystem/meetings/2020/WASI-11-19.md +++ /dev/null @@ -1,153 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the November 19 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: November 19, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Review of action items from previous meeting(s). - 1. Ralph Squillance to write up a draft on "WASI experimental" or - versioning for WASI API experimentation. -1. Removing support for `seekdir`/`telldir` from wasi-filesystem - 1. https://github.com/WebAssembly/wasi-filesystem/issues/7 -1. Filesystem Case Insensitivity - 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 - 1. https://github.com/nicowilliams/ietf-fs-i18n - -## Meeting Notes - -### Attendees -- Peter Huene -- Sam Clegg (SC) -- Lin Clark (LC) -- Andrew Brown -- Dan Gohman (DG) -- Sergey Rubanov -- Syrus Akbary (SA) -- Matt Fisher -- Eric Rosenberg -- Ralph Squillace (RS) -- Till Schneidereit (TS) -- Harun Oz -- Pat Hickey (PH) - -### Action Items from Last Week -RS: had conversation with Pat and Dan about how people are testing out experimental proposals. Pretty obv that we wanted to use these experiments for inputs. At same time, second issue was wanting to be very clear that none of the experiments were destined to the spec - -Wanted people to be able to play with sockets in Krustlet. Dan proposed creating an experimental namespace. Ralph will now begin tackling the doc. Will talk with Fastly about how they are handling exp. - -DG: need standard convention for naming - -SC: Are you talking about system level imports? - -DG: We have wasi_ naming convention. Should be a naming convention for things not in snapshot yet - -RS: That makes sense. Explicitly not destined to be migrated. Signal that these are things to be used as ways of stimulating thought. Kind of a firewall between these and what’s going into the spec. - -DG: One additional thing—some prior art wrt web standards e.g. vendor prefixes. We can probably avoid - -SC: How would we avoid. By not shipping prod VMs with them enabled? - -DG: Yes, or behind flags - -TS: Situation might become slightly different once module linking and ability to virtualize comes in. Then you could say you don’t need to ship as long as you provide a shim implemented in user space - -SC: presumably not the module name - -PH: unfortunate that there’s only one name - -DG: Module linking has concept of nested modules. Might be useful - -PH: That’s used for definitions but not for imports. - -SC: You can chain imports - -TS: IIRC you have to re-export - -DG: typically you do, but … if we don’t have this, then mangling - -PH: we need this before module linking lands in any toolchain. - -From chat: -wasi_experimental_tests? -wasi_experimental_temp? -From Pat Hickey to Everyone: 12:16 PM -wasi_experimental_ for a mangling scheme - -**ACTION ITEM: Ralph will compile doc** - -### Removing support for seekdir/telldir from wasi-filesystem - -DG: from days when OSs used flat lists. Now they are BTrees. These have become awkward abstractions. - -DG: want to remove from WASI altogether. Can’t do a 64 bit seekdir. In order to satisfy POSIX, we’d need to do some complicated indirection. Theoretically possible, but think better to remove altogether. - -SC: Proposal is just to remove, not emulate in user space? - -DG: I don’t think it’s worth it unless use case - -SA: Don’t have context, but what do you think wouldn’t be possible? - -DG: ls will work. This is why I’m asking whether anyone has heard of someone using this. Scan through, then restart from beginning, and then keep going is pretty rare. This originated when it was hard to keep file in memory at same time - -RS: What’s request? Could potentially search GitHub. There are tools - -DG: Found a million hits in code, a lot are libc code - -SC: Yeah, we’ll need to skip headers and impls - -TS: Have experience from TC39. People have tried to use as code search, but there’s quite a lot more dark matter that’s not in public repos, and also test suites are copied all over place and not ways to exclude. Perhaps possible to do regex to exclude - -RS: Both MS and GitHub have internal tools for this. GH is strongly motivated to make this work. If we can write a user story that’s in the sweet spot, I will see what can be done as a feature, either privately or as a preview test, or ultimately as a public feature - -DG: That feature would be really useful for other questions too - -RS: I do need a user story to pursue in an aggressive way, but I think they actively want user stories. - -DG: WASI libc is already trying to guess what you’ll need. - -RS: Side issue—feature set is that we want to know what the community is using. - -DG: Roughly the plan for removal is to remove from libc. Second step is to remove from WASI itself, removing parameter and introducing rewind call - -**ACTION ITEM: Ralph will use internal tool to search for use** -**(possible) ACTION ITEM: Put together user story for feature that would allow WASI SG to search for usage of other APIs** - -### Filesystem Case Insensitivity - -DG: GitHub repos and offline chatting. ONe question, what is the goal of the ___ API Fully deterministic? Will behave same way across all platforms. - -DG: People want to access existing files that already have their own restrictions. Hard to abstract away. If we can assume WASI runtime owns filesystem, could do a lot, but if we assume you have your own files, we have to pass it on to applications. Somewhat unfortunate, but after a lot of discussion think we’re going non-deterministic. Best we can do is good debugging tools. Those wouldn’t be part of the spec, just side debugging tools. Disappointing from the Wasm perspective, where we try to be deterministic. Not within our power at the WASI level to choose one side - -DG: Also want to mention, link in meeting notes that will hopefully turn into an IETF proposal that will define portable semantics - -### Additional Questions - -SA: One quick question. What do you want me to do with the logo - -DG: Researching IP rules - -LC: I can help with this and serve as point of contact - -SA: Lmk if you need changes to the PR - diff --git a/proposals/filesystem/meetings/2020/WASI-12-03.md b/proposals/filesystem/meetings/2020/WASI-12-03.md deleted file mode 100644 index 7d9b521b5..000000000 --- a/proposals/filesystem/meetings/2020/WASI-12-03.md +++ /dev/null @@ -1,130 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the December 3 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: December 3, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Review of action items from previous meeting(s). - 1. Ralph Squillace to write up a draft on "WASI experimental" or versioning for WASI API experimentation. -1. Proposals and discussions - 1. Discussion topic: Repository organization to enable independent proposal repos ([#360](https://github.com/WebAssembly/WASI/issues/360)) - 1. Discussion topic: Using releases to make the repo citable ([#356](https://github.com/WebAssembly/WASI/issues/356)) - -## Meeting Notes - -### Attendees -Lin Clark (LC) -Pat Hickey (PAH) -Martin Duke (MD) -Andrew Brown (AB) -Dan Gohman (DG) -Till Schneidereit (TS) -Matt Fisher (MF) -Mingqiu Sun (MS) -Mark McCaskey (MM) -Johnnie Birch (JB) -Ralph Squillace (RS) -Peter Huene (PEH) -Sam Clegg (SBC) - -LC: Action items from last meeting - Ralph is not on the call, so we’ll skip over follow ups with him - -LC: Dan put up a PR yesterday about repo organization to enable independent proposal repos - -DG: In a CG there's the core spec repo, and proposals that add new features are fork repos of the spec. When a proposal gets to stage 5 (spec), the proposal gets merged into the central repository. We want WASI to have a parallel structure to this. - -DG: One thing we want to move away from is a single snapshot path. So when we make a snapshot its url remains stable (we don't put it into old). What this enables is one snapshot referring to another. We want documentation to describe the differences between snapshots and eventually tools will too. Stable URLs are a good first step towards that - -DG: Another feature is moving away from ephemeral. That was envisioned as the place where we do development, where PRs target, but we want to move all development into proposal repositories. The main proposal repo will no longer have an ephemeral directory. -DG: A final piece of this is a place in the repo for a script, similar to core CG’s test suite repository, that pulls in the proposals from all the places they live, and creates the snapshot. All of the proposals will be separate modules in the snapshot. - -AB: When do proposal repos get added to the script so they land in the snapshot? - -DG: As soon as you create them you can create a PR to the script. One rule we could have is that if there's a merge conflict or other obvious errors we just skip over merging a proposal for now. But we want a snapshot to contain all proposals. - -DG: In the root spec repo, there will be a `standards/` directory, it's empty for now because we aren't at stage 5 yet. But out in the proposals they can put whatever they want to land in the spec repo snapshot in their `standards/` directory. This convention is that we don't have to wait for everyone to sync up - -TS: Will it make sense to say “only show me sections for proposals for stage of my choice in the rendered output”. - -DG: We don't have that information yet but that's a good idea. Maybe a magic doc comment in the witx files. Or we can iterate - -TS: There has to be some index about pulling in the proposals, and that can contain the metadata about what stage various proposals are at. - -AB: This is a better system than we have today - -DG: We are learning from our mistakes - -TS: We need to iterate on the infrastructure of the spec in a central place, and make use of it without copying code over, are you envisioning the proposals will pull in the (upstream) spec repo? And we iterate on that outside of the snapshot mechanism? - -DG: Some proposals need to make change to witx. They all have a witx crate in them to make changes to how witx works. You can experiment there and make a non-snapshot PR into the spec repo to merge bigger changes in. You can keep - -PAH: For some changes to WITX, it would make sense to do in the core spec repo and then proposals merge or rebase - -DG: That is something that becomes more awkward with this setup. The question is would you also modify existing snapshots to use the new syntax? Because if not, then snapshots don’t work with new tooling. - - -PAH: let’s set that discussion aside. We have been updating to keep semantics but use new syntax. The hard part of this is that if we have to make a breaking change to WITX that could affect our ability to merge in proposals that haven’t taken in the breaking changes yet. Is it the responsibility of WITX maintainer to un-break all the proposals? - -DG: Initial way that falls out is that the script that merges will run the new version of the tool over that. If it doesn’t run, we leave out of the snapshot - -PAH: That sounds fine to me. What I’m thinking now is the CGs waterfall, continuous integration of tip of tree which makes it possible to find before releases. Could run it on a cron job and does red/green for various proposals - -DG: If someone wants to set up a waterfall, that would be good. Might be more than we need right now. - -PAH: If you have to update both your WITX files and ref implementation on downstream tooling, might not be able you - -DG: You can do it on your local as a champion - -PAH: This also makes me think about the value of the snapshot version being date based. You could have an id and a date. E.g. nightly-YYYY-MM-DD. That could give people ability to find breakages before time for snapshot. I think the biggest thing I’ve messed up in WASI and WITX is not having tooling that makes ephemeral work. Want the new process to be tip of tree always working. I could be wrong on that, but that’s my personal feeling. - -DG: Ephemeral in main repo goes away. If they want to dev in standards dir, they can. If they have their own ephemeral, then it’s on them to keep it working. - -TS: It seems to me that there’s value in cross-proposal CI so that you don’t find out when cutting a snapshot more work to do. I could see value in /standards and /in-progress, where we maybe have GitHub action that tries to do an integration build - -PAH: I think I agree. I would love it if the CI action could be run in any of the fork repos so that they could alert on their own breakage. - -DG: If we put that in the main repo, then they’ll all have a fork of it - -PAH: They’d be able to id if any contrib to main repo is breaking. That’s an implementation detail. - -TS: I feel like it would also be kind of nice to have a snapshot that’s always up to date for what it looks like today with all proposals combined. - -LC: Are there more questions? (no). Dan what are the next steps? -DG: I can make a PR into the spec repo and proposal repos to adopt the new organization. The first step is to reorganize the spec repo and get the scripts setup, then reach out to the proposal champions to integrate up there. - -LC: You can put that list of work into the issue and we can distribute that work out. - -LC: Ralph has joined, do you want to talk about experimental stuff at all or next time? - -RS: I need more time before I present that. - -LC: Next thing on the agenda, we need to talk about releases. Someone is asking us to make citation easier using a tool called zenodo. For that to work we need to cut (GitHub) releases. Should we do this and when should we do them? It seems like we should do them when we do a snapshot. Does anyone have opinions on this? - -JB: Question about zenodo: what does that tool do? - -LC: It (??) DOI’s. I don’t know exactly why a DOI is important for a bibliography but its recommended over a URL when possible by the (APA?). The tool archives the data associated with the DOI, I believe. - -LC: Then we’ll start cutting releases with snapshots. We can do one release now to capture the current snapshot. I’ll work with the wasm cg chair to get zenodo configured for the repo. - -LC: Any other topics? (None) diff --git a/proposals/filesystem/meetings/2021/WASI-01-14.md b/proposals/filesystem/meetings/2021/WASI-01-14.md deleted file mode 100644 index 9ee3e0be7..000000000 --- a/proposals/filesystem/meetings/2021/WASI-01-14.md +++ /dev/null @@ -1,75 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the January 14 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: January 14, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcement - 1. Pat will be changing branch name from `master` to `main` -1. Review of action items from previous meeting(s). - 1. Lin update on repository organization progress -1. Proposals and discussions - 1. Discussion: Testing guidelines for proposals - 1. _Sumbit a PR to add your agenda item here_ - -## Meeting Notes -### Attendees -Lin Clark -Josh Dolitsky -Dan Gohman -Pat Hickey -Sam Clegg -Casper Beyer -Mark McCaskey -Johnnie Birch -Andrew Brown -Yong He -Peter Engelbert -Peter Huene -Martin Duke -Till Schneidereit -Bogus Wolf - -For people taking notes, just type names; we’ll replace them with abbreviations before posting them publicly. - -**Pat Hickey:** Github is now rolling out features to allow for renaming git branches from “master” to “main”, including blob url redirection. It’s mostly automatic, but it does require people to do some changes locally to update. We’ll put the steps in the WASI github issue tracking this. - -Main topic: Testing. - -**Lin Clark:** - -The context here is WASI modularization -- breaking up the core WASI module into separate modules. - -Pat and Dan are working on a new witx mechanism for expressing dependencies between witx files, allowing modules to depend on each other. - -The main WASI repo will be the source of truth for stage-5 (standardized) proposals. - -Tests should include both the source, in high-level languages, and compiled wasm binaries. - -Things we still need to build: -A test runner -Tests. We’ll start with some tests from Wasmtime, and everyone can add tests. - - - diff --git a/proposals/filesystem/meetings/2021/WASI-01-28.md b/proposals/filesystem/meetings/2021/WASI-01-28.md deleted file mode 100644 index cab4dbd21..000000000 --- a/proposals/filesystem/meetings/2021/WASI-01-28.md +++ /dev/null @@ -1,206 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the January 28 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: January 28, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. Lin Clark on WASI modularization milestone -1. Proposals and discussions - 1. Presentation: Update from Luke Wagner on handles and resources in interface types - 1. _Sumbit a PR to add your agenda item here_ - -## Meeting Notes -### Attendees -- Martin Duke, F5 -- Sam Clegg -- Dan Gohman -- Luke Wagner -- Mark McCaskey -- Lin Clark -- Dave Protasowski -- Alex Crichton -- Andrew Brown -- Mingqiu Sun -- Till Schneidereit -- Pat Hickey -- Josh Dolitsky -- Matt Butcher -- Ralph Squillace - -### Announcements -**Lin Clark:** We now have a [milestone for WASI modularization](https://github.com/WebAssembly/WASI/milestone/1). Will be using milestones more in the future. - -### Proposals and discussions -#### Presentation: Update from Luke Wagner on handles and resources in interface types [(Slides)](https://docs.google.com/presentation/d/1ikwS2Ps-KLXFofuS5VAs6Bn14q4LBEaxMjPfLj61UZE) - -**Luke Wagner:** Handles and resources. Have been working on this for a while with a number of y’all -Give background, motivating problems, and proposed solution -Not at all final, still working on a PR. Your feedback is most welcome - -IT gives WASI a bunch of value types -In addition to core basic types, a bunch of abbreviations -Don’t want to have to add core types -This lets us take a WASI function and use a bunch of high level types - -Plan of record for a while has been abstract types for file descriptors -Type imports builds on reference types -Reference types are unforgeable, better than ints - -How does this get virtualized? -Virtualization is a core value of WASI. You can implement with another WASI module -For this, we use module linking proposal - -What does it look like to write that virtualized WASI? (walk through) -Packed the file index into the reference, that’s efficient - -Type imports and exports are transparent by default -This is forgeable. That’s why that was take one - -Type imports has a private type definition -I would take abstract type and make it a private type definition -Private.get and private.new only works inside module that defined the type definition -These private types have to be boxed. -Actually no worse than the native implementation to have one level of indirection - -Two remaining problem areas: resource lifetimes and dynamic casting - -Resource lifetimes -How do resources get released? -Could reference count. -Problematic for a variety of reasons. -Not virtualizable. -Because of downsides, WASI resources have explicit destructor - -Virt WASI then looks like…. -What happens on double close or use-after-close? -Spectrum of options, none of them good -How do I efficiently support cross-instance resource sharing? -Not great options either -How can a WASI impl robustly clean up after clients are destroyed? -Could leak. -Want FDs to be closed when the instance goes away, just like OS process -A native WASI impl could do this, but not a virtualized one -How do instances even get different lifetimes? This is a next step, to add ability to dynamically create and destroy instances -Also problems around dynamic casting -E.g. when store n distinct DOM node types in a single table -Not supporting would be a kind of regression - -Dynamic casting breaks otherwise-static invariants -If there’s a run function and I pass a RO, is it possible for X to somehow do a write? -It would be nice to have that answer based only on the static type -Fix is to treat different imports as different things for purpose of dynamic cast -To fix this, you need a wrapping at some membrane/boundary -OK for core wasm, because that’s just a compiler target -But not ok for ecosystem - -When we’re virtualizingWASI we want: … -Is all of this just for virtualization? -Resources are not a uniquely WASI concern -We should treat WASI as an unprivileged set of library interfaces - -Proposal -Add a new interface type called handle -Handle is a value that can be copied -Refers to a resource -A resource is some entity with a lifetime. It can not be copied -So resource types are like abstract type, but only private option -Additionally resource type definitions can have an optional destructor -Resource creation and use is symmetric to private.new/get -Handles are semantically ref-counted and call the destructor when they get to 0 -That’s what gives virt WASI same privileges as native -Also possible to explicitly destroy handles, and references trap - -**Sam Clegg:** would need to be at WASI core? -**Luke Wagner:** So far everything in Interface Types - -**Pat Hickey:** Attenuation -**Luke Wagner:** I’ve gone back and forth. Have an idea in open questions - -**Luke Wagner:** High level summary of IT -They’re lazy copy operations -Need a way to box all interface types -Generally valuable because it solves interesting performance use cases -For handle values, creates a root that creates the stack -That makes it so handles can outlive stack frame - -Once I have a reference, it can be cast -Will always trap if cast to differently privileged - -IT gives us the boundary/membrane where to wrap - -Proposal summary -Additions -New types -New definition -New instructions -Extend rtt.canon - -Problems: -Robust and efficient handling of double-free/use-after-free -…. - -Open Questions -Add abstract subtyping? -Should we have specialized versions of handle (e.g. a strong handle, unique handle) - -Next steps -Need to give lifetimes to instances -Can instances just be resources? -Could implement WASI command pattern in the toolchain rather than host magic - -**Sam Clegg:** What happens if you destroy a resource and another module still has a copy - -**Luke Wagner:** It will have a handle. That handle is then in a null state. When you try to use the handle, it would trap probably at resource.get - -**Sam Clegg:** So the trap would happen in the callee - -**Luke Wagner:** That’s where we might want to have a strong handle where no one could pass you an invalid handle. It’s an open question - -**Ralph Squillace:** For what it’s worth, I’ve been spinning around Pat’s question and going back to DCE-RPC. Believe that you should make or signal a strong decision about shared resources. - -**Luke Wagner:** That’s one of the reasons I like unique, because then when I give you a handle I’m explicitly saying I dont’ still have it. I guess that’s an argument for both unique and strong - -**Ralph Squillace:** Having the ability to make those choices is what comes to mind. If I choose a convention, I can signal it to others. Previous technologies tried to let people do it without signaling capabilities - -**Luke Wagner:** Would a summary be that you’re in favor of those two types of handles - -**Ralph Squillace:** I would say those two handles express two slices of the problem space. I wouldn’t say that I’ve thought through other possible types. - -**Luke Wagner:** Your’e right, I was trying to survey the literature and there are like 20 types - -**Ralph Squillace:** Even if you don’t have strong type, at least you can trap. Maybe that’s the first step. - -**Luke Wagner:** Hierarchy, undefined is worst, trap is better, statically preventing is best - -**Sam Clegg:** These handles are at IT types and at core go to reference. So references can be copied - -**Luke Wagner:** Once you exclusively use IT, there’s no back door - -**Sam Clegg:** Any incremental steps? - -**Luke Wagner:** In some sense, witx already has handle - -**Lin Clark** proposes that we make that the main topic for next meeting - diff --git a/proposals/filesystem/meetings/2021/WASI-02-11.md b/proposals/filesystem/meetings/2021/WASI-02-11.md deleted file mode 100644 index c18c4b8fa..000000000 --- a/proposals/filesystem/meetings/2021/WASI-02-11.md +++ /dev/null @@ -1,118 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the February 11 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: February 11, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. Discussion: What are the next steps in adapting WASI to use Interface Types handles and resources? - 1. _Sumbit a PR to add your agenda item here_ - -## Notes -### Attendees -Pat Hickey -Andrew Brown -Sergey Rubanov -Lin Clark -Mark McCaskey -Till Schneidereit -Dan Gohman -Josh Dolitsky -Mingqiu Sun -Ralph Squillace -Nicholas -Radu Matei -Matt Fisher -Johnnie Birch -Luke Wagner - -**Lin Clark:** Are there any announcements? -(none) - -**Lin Clark:** Lets talk about how we’re going to move from this version of WASI to a new version that uses handles - -**Dan Gohman:** Witx has been designed to anticipate interface types. It has String and Handle types. These are pretty close to the ones in interface types - PR 391 takes things to the next level and evolves the rest of the witx types towards the interface types. Going forward we need to get rid of the witx pointer and get buffers to work the way they will in interface types, but we’re still waiting to hear from interface types the final word on how those will work. See Interface Types issue 68. Our job on the witx side is to evolve into the Interface Types buffer types. Without waiting we can add support for strings and return types and lower them into the existing C ABI that WASI programs use. - -**Dan Gohman:** Another piece is WASI modularization. It has been in progress for a while but several pieces are coming together. Issue 378. Describes a more granular include mechanism than witx uses right now - import a symbol from a module, rather than import a file. - -**Dan Gohman:** The next two big pieces, which we can address in detail in the future: How do you pass handles into programs? Currently there is a table with preopens in it, but interface types is going to give us new mechanisms that are better than the preopen concept. - -**Dan Gohman:** The last piece is defining new abstractions. wasi PR 240 describes how to merge the send and recv on sockets with read and write on files. We can generalize part of files and sockets into a concept of I/O streams. In interface types you’ll have the vocabulary to ask for e.g. a stream you can write to, without knowing or caring that its backed by a socket or file or pipe etc. What is the noun that you use in function signatures to describe an I/O Stream? Beyond I/O Streams there’s non-streaming operations on files which don’t work on sockets or pipes - pread/pwrite - there’s a place for an I/O object with non-stream personality as well, an array of bytes or a we can call it a dynamic array because it can be resized. There will be other concepts as well - key-value stores, windowed IO with buffers... At the moment the nascent WASI I/O proposal will evolve to develop these ideas. There will still be files, and then a function that gives you a stream from a file. Files are going to be required to interop with existing systems, but we can push people towards interfaces that don’t tie them to the complications of those existing systems, particularly file semantics are very difficult to compose but streams are. This will help us enable shared-nothing linking of modules - we don’t want modules to have to share a filesystem to talk to each other. Questions? - -**Ralph Squillace:** What kinds of objections to this direction do you anticipate? - -**Dan Gohman:** This is going off the path of POSIX. Existing applications and programming languages will be more work to port to I/O streams than having us port libc and standard libraries to WASI. We have ideas for making the standard io operations work on top of I/O streams - you can treat an i/o stream as a libc FILE if you only ever read and write from it, other operations give an error. - -**Ralph Squillace:** The philosophical discussion is about how you weigh the objectives of different applications moving to WASI - some will have to adapt specific POSIX-isms to WASI, where does the work of porting existing code break down - does the code stay in WASM and not use WASI, have its own custom runtime - or does it move to WASI in the coherent way that resolves the semantic differences. I don’t personally see myself trying to port an existing huge monolithic application to WASI, whereas I do see myself working on libraries to make them work in WASI. - -**Lin Clark:** How much is WASI filesystem still going to allow porting POSIX applications? - -**Dan Gohman:** It will allow it. Its a question of priorities rather than absolutes. WASI today runs plenty of interesting POSIX code that doesnt do things like fork(2), WASI filesystem is going to still be there for these applications to use. But we don’t want that to be part of the default for WASI, we want to encourage applications to use simpler concepts that don’t imply a whole filesystem. I want to build tooling that bridges the gap between the shared-nothing-linking space and making big applications work. - -**Till Schneidereit:** We can look at this in terms of layering - there is a core of WASI that may not apply to every use case but you can virtualize many of the other needs on top of it. You can add a filesystem ion top of the core, in many cases, and let applications that need it use it. - -**Dan Gohman:** In terms of migration from where WASI is today to this ideal system - the WASI I/O abstractions can be worked on now, we have witx where we need it. We can flesh out exactly how streams and dynamic arrays work today. - -**Dan Gohman:** Another aspect is portability. I’ve been working on support for WASI on Windows vs Unix the last few months - there are so many differences between those platforms, the semantics of filesystems is radically different and there’s no portability in many cases (its too expensive to bridge them). The WASI I/O abstractions can be designed to hide all of the non-portable parts of filesystems. We can get away from having to specify “what does windows do here” and instead specify the things an application actually needs. - -**Ralph Squillace:** Layering will require thought. - -**Pat Hickey:** The customers we have writing applications right now aren’t concerned with the differences between the filesystem guarantees on linux vs windows, they care about http requests and responses. If we have I/O abstractions that unify the way http bodies work with the way certain aspects of the filesystem work, that is better for the applications we care about. - -**Till Schneidereit:** There are lots of use cases that work with streaming, which has traditionally been a file or a socket, but with abstractions that are hard to generalize. My interpretation of what you were just saying is that if we had a way to have a cleaner system that didn’t have that incidental platform dependence, it would be much easier to build code that works across these very different environments. We have all these applications that are popping up that are very different. Ideally we have a layer that doesn’t care about host differences, and then the layer that cares about that. What we do is just one specific example of that. Don’t want to optimize for old use cases, but all of the new novel ones that are coming about. - -**Radu Matei:** Is the assumption that wasi-filesystem will be developed in parallel? - -**Dan Gohman:** Yes, WASI-filesystem will continue, and wasi-io will be a peer. - -**Ralph Squillace:** Drawing older threads in, what about BSD sockets PR. - -**Dan Gohman:** The contributor who created that hasn’t been active, but I expect that will fit into the system in the same way as wasi-fs. You could get a stream. Networking is a complex topic and I dont’ want to simplify, but the first step will be to take sockets and say the socket gives you a stream that you can read, a stream you can write, and bi-directional r/w. - -Async is a subtlety that we’re leaving out. We can say that async is an orthogonal concern. We expect the Wasm platform will give us better answers over time. But the fundamental concepts of I/O are independent of whether you block that I/O. - -**Lin Clark:** Any other thoughts/comments - -**Luke Wagner:** I have a hypothesis I want to test. Why are people going to want to use wasm outside of a browser? Some people think it’s great because of ISA. We don’t think that’s a great motivator. We think running guest code in latency sensitive and low trust scenarios is the motivator. Things like routers ____ would be host APIs. The libraries would be wasm. These problematic cases don’t have a high value reason to be ported to Wasm. - -**Ralph Squillace:** I understand where you’re coming from. I don’t see WASI as a monolithic process sandbox. I do think that the idea about the sweet spot is right. I’m not a big believer in the thought that the world’s code is going to all be running on WASI. But I think it’s worth consideration how much of the world’s knowledge can be run as WASI. Shouldn’t wall off for all time, but I think the way that Dan laid out the direction, it lets us start with the sweet spot and either layer the others, or add support to WASI later on. I would hate to frame the boundary ruling out knowledge transfer. - -**Luke Wagner:** I agree with your points, so the layering and virtualization are also motivated by that. - -**Dan Gohman:** I can add one thing. Thinking of lib-c, and lots of languages have lib-c like std lib: under the covers, something that people are using as a file could be represented by streams. We can make that work under the covers. We could talk about how that will exactly work. But this is the framework. We can make porting easier by allowing you to use streams by allowing you to use files, but discourage from using file stat and depending on i node. - -**Andrew Brown:** It feels to me that filesystem should be in phase 3 or 4. How do these changes affect moving those to later stages - -**Dan Gohman:** That’s a great question. Wasi-fs is waiting to figure out it’s place. This conversation moves that forward. Understanding that wasi-fs won’t attempt to be abstracting over all hosts, wasi-io does that, and accepting that’s ok means that wasi-fs can probably move to phase 3 at this point. - -**Till Schneidereit:** I think the better way to put it is that it’s not an either/or, we don’t need to make it completely host specific, but let’s find a balance that’s actually viable. - -**Radu Matei:** do we have a document? - -**Dan Gohman:** Will be writing that up. Wanted to introduce here first. Will write up wasi-io ideas soon - -**Pat Hickey:** One blocker to wasi-fs advancing. The filesystem has cloud ABI system of rights. Need to work out what to do with that. diff --git a/proposals/filesystem/meetings/2021/WASI-02-25.md b/proposals/filesystem/meetings/2021/WASI-02-25.md deleted file mode 100644 index 2bc89278a..000000000 --- a/proposals/filesystem/meetings/2021/WASI-02-25.md +++ /dev/null @@ -1,131 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the February 25 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: February 25, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. Discussion: Better error handling in WASI - 1. _Sumbit a PR to add your agenda item here_ - -## Notes -### Attendees -- Lin Clark -- Dan Gohman -- Andrew Brown -- Johnnie Birch -- Sergey Rubanov -- Mark McCaskey -- Peter Huene -- Radu Matei -- Luke Wagner -- Ralph Squillace -- Pat Hickey -- Till Schneidereit -- Mingqiu Sun -- David Piepgrass -- Yong He - -**Dan Gohman:** Overview—errors handled like POSIX with single enum of errno. More APIs in WASI, not feasible to have a single errno enum. Also not reasonable to have a single error type. My expectation for errors is that every library will define its own error types. IT will make it possible for us to define a variant type like Rust’s Result. Does that shape of things make sense? - -**Andrew Brown:** Makes sense to me. Errors for wasi-nn are just a totally different sphere than files. - -**Dan Gohman:** wasi-libc will still have errno. Errno only describes small set of system errors - -**Andrew Brown:** Right now wasi-nn has own kind of error types. What’s changing? Will we just change witx and wiggle - -**Dan Gohman:** It’s not a fundamental change. We’re just making what wasi-nn is doing explicit. We’ll also be getting new features from IT which will describe what you’re doing in a better way. Enum with either success or failure, maybe called Expected. - -**Andrew Brown:** I think Alex has already made this change. - -**Dan Gohman:** Yeah, we wanted to give people a heads up about this plan. - -**Andrew Brown:** One question about the future—will this expected type, in the failure case will you be able to pass things that aren’t just an integer, like strings and stuff - -**Dan Gohman:** There is no master plan, but I expect the basic mech will be that you can have any type for errors, with full expressiveness of IT. One caveat, how do we want to handle strings? English isn’t appropriate for all envs. Will need to apply more design thought. Underlying tool won’t have a restriction against that, though - -**Andrew Brown:** Agreed. On thing I’ve found with wasi-nn is just having an errno isn’t enough - -**Dan Gohman:** Agreed, and that’s a place where tooling might be able to help. We can go down the path of thinkking of enums not just as ints but high-level types - -**Luke Wagner:** Along that line, one thing that has bugged me about classical error codes, is sometimes you want to use them for conditionals, and sometimes you just want to debug. Two level nesting of variants? Top level “You called it wrong” and second level provides detail of how you called it wrong. - -**Dan Gohman:** Yes, let’s do that. I think that’s totally a good idea to do. Another idea, in POSIX they have system calls that are never supposed to crash. In WASI, we don’t need to be as strict. If you pass a bad pointer into a syscall, it could trap. - -**Pat Hickey:** Yeah, that’s also a kind of a concession for virtualization. Awfully convenient for that - -**Dan Gohman:** So that’s the basic vision of it. Any more questions on that level of detail? One thing this does mean, we won’t have unified error handling across WASI. Another thing, we want to go through the APIs and figure out what errors things like the clock apis can return. In practice, the only thing that can fail in a clock is failing to get a clock. Wasi-filesystem will probably be where most of the error codes land. Simplifying property across different APIs. Don’t overload error codes to represent similar but not the same errors. Exception handling is coming. A possible approach is to use unwinding. I think that for WASI, errors work better. If languages want to use unwinding, they can expect errors and unwind. I think using variants instead of exceptions will work well for us. - -**Pat Hickey:** The one thing I’ll call out is that proc_exit should be implemented as unwind. - -**Dan Gohman:** That’s true. I’m going to claim that proc_exit is special. It might be something that we unwind and then turn into a clean exit status. Then the unwinding becomes an implementation detail. That wouldn’t be a thing that leaks across module boundaries. Often not a good idea for libraries to call exit directly. - -**Pat Hickey:** So we basically get rid of proc_exit as a library function - -**Dan Gohman:** So I think what we want to say is return type from main is an error type. - -**Pat Hickey:** Yeah, that way we keep types all the way down and don’t turn into bare integer. - -**Dan Gohman:** Yeah, so 3 error types. Return values, unwinding, and trapping. Trapping is for program has a bug. Maybe sometimes when return values. ____. And we’ll use unwinding across language boundaries. - -**Pat Hickey:** Unlike with errors, we can’t invent new ways to trap. - -**Dan Gohman:** Although I wonder if there’s something we could do there. I wonder if it makes sense for wasm to be able to trap with extra info. - -**Luke Wagner:** Or there could be a WASI function that says “I’m going to trap, but you can provide me with an error to print” - -**Pat Hickey:** You can imagine that a malicious module would do that - -**Luke Wagner:** They can do that already. We don’t want wasm to casually be able to catch traps. Because at a very fine granularity. But having a blast zone that allows a set to go away without taking down the rest. I think that belongs at some point of time in wasm’s future. - -**Dan Gohman:** yeah, if we add those mechanisms, then programmer errors could just be trapped. - -**Lin Clark:** Best way to collaborate - -**Dan Gohman:** Once we’ve fully modularized, each module will audit their own errors. The wasi-libc work will start after the next snapshot which includes those changes. - -**Andrew Brown:** Question about sockets. Who’s driving that - -**Dan Gohman:** Haven’t heard from them. Don’t know what their status is. Expect that if they don’t respond soon we’ll find someone else - -**Andrew Brown:** Who was originally driving it? - -**Dan Gohman:** Somebody working for a company called ____. The person who filed it is the person working there. - -**Andrew Brown:** Radu, was someone on your side interested in that? - -**Radu Matei:** We should probably have a chat at some point. How will that relate to these changes? - -**Dan Gohman:** Sockets are the other major user of errno. I expect sockets will have their own errno, and then wasi-libc will have some way to concatenate errnos and turn it into appropriate POSIX errno space. I think that’s basically it. - -**Radu Matei:** How about IO Streams? - -**Dan Gohman:** We haven’t talked about how it’s going to work with libc. I expect from a POSIX point of view, we might have a bunch of different error codes in wasi-io. Have been talking about wasi-io not reporting very specific errors because it leaks information. We aren’t necessarily going to want to return a lot of detail there either. - -**Ralph Squillace:** I think we want to try to figure out, if we help pick up the PR, what’s the best way to move forward without having to reimplement too much. Will reach out to original champion. - -**Dan Gohman:** I see wasi-filesystem and wasi-sockets being peers. At a good place for them to work the same way. diff --git a/proposals/filesystem/meetings/2021/WASI-03-11.md b/proposals/filesystem/meetings/2021/WASI-03-11.md deleted file mode 100644 index f6170a738..000000000 --- a/proposals/filesystem/meetings/2021/WASI-03-11.md +++ /dev/null @@ -1,32 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the March 11 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: March 11, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. Presentation: Passing capabilities into programs with Typed Main (Dan Gohman) - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/2021/WASI-03-25.md b/proposals/filesystem/meetings/2021/WASI-03-25.md deleted file mode 100644 index a35f4e17e..000000000 --- a/proposals/filesystem/meetings/2021/WASI-03-25.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the March 25 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: March 25, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/2021/WASI-04-08.md b/proposals/filesystem/meetings/2021/WASI-04-08.md deleted file mode 100644 index 35d2286f9..000000000 --- a/proposals/filesystem/meetings/2021/WASI-04-08.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the April 8 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: April 8, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/2021/WASI-04-22.md b/proposals/filesystem/meetings/2021/WASI-04-22.md deleted file mode 100644 index 722d57ca0..000000000 --- a/proposals/filesystem/meetings/2021/WASI-04-22.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the April 22 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: April 22, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/2021/WASI-05-06.md b/proposals/filesystem/meetings/2021/WASI-05-06.md deleted file mode 100644 index da5cf7cbb..000000000 --- a/proposals/filesystem/meetings/2021/WASI-05-06.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the May 6 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: May 6, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/2021/WASI-05-20.md b/proposals/filesystem/meetings/2021/WASI-05-20.md deleted file mode 100644 index c91e5777f..000000000 --- a/proposals/filesystem/meetings/2021/WASI-05-20.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the May 20 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: May 20, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/2021/WASI-06-03.md b/proposals/filesystem/meetings/2021/WASI-06-03.md deleted file mode 100644 index 89487782a..000000000 --- a/proposals/filesystem/meetings/2021/WASI-06-03.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the June 3 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: June 3, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/2021/WASI-06-17.md b/proposals/filesystem/meetings/2021/WASI-06-17.md deleted file mode 100644 index 583b7f02b..000000000 --- a/proposals/filesystem/meetings/2021/WASI-06-17.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the June 17 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: June 17, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/filesystem/meetings/README.md b/proposals/filesystem/meetings/README.md deleted file mode 100644 index a9fcf2e21..000000000 --- a/proposals/filesystem/meetings/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# WASI meetings - -Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow -[the process of the CG](https://github.com/WebAssembly/meetings). - -## Meetings - -### 2019 - - * [WASI May 2nd video call](2019/WASI-05-02.md) - * [WASI May 16th video call](2019/WASI-05-16.md) - * [WASI May 30th video call](2019/WASI-05-30.md) - * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) - * [WASI June 27th video call](2019/WASI-06-27.md) - * [WASI July 18th video call](2019/WASI-07-18.md) - * [WASI August 15th video call](2019/WASI-08-15.md) - * [WASI August 30th video call](2019/WASI-08-30.md) - * [WASI September 12th video call](2019/WASI-09-12.md) - * [WASI September 26th video call](2019/WASI-09-26.md) - * [WASI October 15th in-person meeting](2019/WASI-10-15.md) - * [WASI October 24th video call](2019/WASI-10-24.md) - * [WASI November 7th video call](2019/WASI-11-07.md) - * [WASI November 21st video call](2019/WASI-11-21.md) - * [WASI December 5th video call](2019/WASI-12-05.md) - * [WASI December 19th video call](2019/WASI-12-19.md) - -### 2020 - - * [WASI January 16th video call](2020/WASI-01-16.md) - * [WASI February 27th video call](2020/WASI-02-27.md) - * [WASI March 12th video call](2020/WASI-03-12.md) - * [WASI March 26th video call](2020/WASI-03-26.md) - * [WASI April 9th video call](2020/WASI-04-09.md) - * [WASI May 7th video call](2020/WASI-05-07.md) - * [WASI May 21st video call](2020/WASI-05-21.md) - * [WASI June 4th video call](2020/WASI-06-04.md) - * [WASI July 2nd video call](2020/WASI-07-02.md) - * [WASI July 16th video call](2020/WASI-07-16.md) - * [WASI July 30th video call](2020/WASI-07-30.md) - * [WASI August 27th video call](2020/WASI-08-27.md) - * [WASI September 10th video call](2020/WASI-09-10.md) - * [WASI September 21st video call](2020/WASI-09-21.md) - * [WASI October 8th video call](2020/WASI-10-08.md) - * [WASI October 22nd video call](2020/WASI-10-22.md) - * [WASI November 19th video call](2020/WASI-11-19.md) - * [WASI December 3rd video call](2020/WASI-12-03.md) - - ### 2021 - * [WASI January 14th video call](2021/WASI-01-14.md) - * [WASI January 28th video call](2021/WASI-01-28.md) - * [WASI February 11th video call](2021/WASI-02-11.md) - * [WASI February 25th video call](2021/WASI-02-25.md) - * [WASI March 11th video call](2021/WASI-03-11.md) - * [WASI March 25th video call](2021/WASI-03-25.md) - * [WASI April 8th video call](2021/WASI-04-08.md) - * [WASI April 22nd video call](2021/WASI-04-22.md) - * [WASI May 6th video call](2021/WASI-05-06.md) - * [WASI May 20th video call](2021/WASI-05-20.md) - * [WASI June 3rd video call](2021/WASI-06-03.md) - * [WASI June 17th video call](2021/WASI-06-17.md) - \ No newline at end of file diff --git a/proposals/filesystem/phases/README.md b/proposals/filesystem/phases/README.md deleted file mode 100644 index 9f66686bd..000000000 --- a/proposals/filesystem/phases/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# WASI's ephemeral/snapshot/old Process - -For the standardization process, WASI overall uses a [process] -modeled after the WebAssembly CG's phased process. - -For development of features in Phase 2 and later of that process, WASI -has a ephemeral/snapshot/old process, which is designed to allow -for a balance between the need for stability to allow people to build -compatible implementations, libraries, and tools and gain implementation -experience, and the need for proposals to evolve. - -[process]: https://github.com/WebAssembly/WASI/blob/main/docs/Process.md - -## The ephemeral/snapshot/old Phases - -- [`ephemeral`](ephemeral): The development staging area. New API - proposals API-changing fixes to existing APIs should be submitted - as Pull Requests making changes to this directory. This directory - provides no API stability or versioning. APIs in this directory use - API module names starting with `wasi_ephemeral_`. - -- [`snapshot`](snapshot): Usable APIs. APIs in `ephemeral` will be - occasionally snapshotted and promoted into `snapshot`, with approval - from the Subgroup, considering the overall suitability of the APIs - themselves, their documentation, test coverage, and availability of - polyfills when appropriate. Once merged, the API modules will be - considered stable, though they may be superseded by newer versions. - Proposals to promote specific APIs should be submitted as Pull Requests - that: - 1. `git mv` contents of `phases/snapshot/` to - `phases/old/snapshot_{old_snapshot_number}`. - 2. `cp -R` contents of `phases/ephemeral/` into `phases/snapshot/`. - 3. Rename files copied into `phases/snapshot/` to substitute `ephemeral` - for `snapshot` in file names. Append the new snapshot number to each - name. - 4. Update module names given in `.witx` files according to the previous - step. - 5. Update tests in `tools/witx/tests/wasi.rs` to point at new snapshot, and - add a test pointing at the just-archived snapshot under `old`. - 6. Optionally, under `phases/old/snapshot_{old_snapshot_number}, add - polyfills for superceded APIs using the new APIs. - - - Pull Requests may also add additional tests, documentation, or - polyfills for existing `snapshot` APIs. - -- [`old`](old): When APIs in `snapshot` spec are replaced by new - versions, the old API modules are moved to the `old` directory. When - possible, `old` APIs may be accompanied by polyfill modules which - implement their API in terms of newer versions of the API. diff --git a/proposals/filesystem/phases/ephemeral/docs.md b/proposals/filesystem/phases/ephemeral/docs.md deleted file mode 100644 index f29d401c4..000000000 --- a/proposals/filesystem/phases/ephemeral/docs.md +++ /dev/null @@ -1,2562 +0,0 @@ -# Types -## `size`: `usize` -An array size. - -Note: This is similar to `size_t` in POSIX. - -Size: 4 - -Alignment: 4 - -## `filesize`: `u64` -Non-negative file size or length of a region within a file. - -Size: 8 - -Alignment: 8 - -## `timestamp`: `u64` -Timestamp in nanoseconds. - -Size: 8 - -Alignment: 8 - -## `clockid`: `Variant` -Identifiers for clocks. - -Size: 4 - -Alignment: 4 - -### Variant cases -- `realtime` -The clock measuring real time. Time value zero corresponds with -1970-01-01T00:00:00Z. - -- `monotonic` -The store-wide monotonic clock, which is defined as a clock measuring -real time, whose value cannot be adjusted and which cannot have negative -clock jumps. The epoch of this clock is undefined. The absolute time -value of this clock therefore has no meaning. - -## `errno`: `Variant` -Error codes returned by functions. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX. - -Size: 2 - -Alignment: 2 - -### Variant cases -- `success` -No error occurred. System call completed successfully. - -- `2big` -Argument list too long. - -- `access` -Permission denied. - -- `addrinuse` -Address in use. - -- `addrnotavail` -Address not available. - -- `afnosupport` -Address family not supported. - -- `again` -Resource unavailable, or operation would block. - -- `already` -Connection already in progress. - -- `badf` -Bad file descriptor. - -- `badmsg` -Bad message. - -- `busy` -Device or resource busy. - -- `canceled` -Operation canceled. - -- `child` -No child processes. - -- `connaborted` -Connection aborted. - -- `connrefused` -Connection refused. - -- `connreset` -Connection reset. - -- `deadlk` -Resource deadlock would occur. - -- `destaddrreq` -Destination address required. - -- `dom` -Mathematics argument out of domain of function. - -- `dquot` -Reserved. - -- `exist` -File exists. - -- `fault` -Bad address. - -- `fbig` -File too large. - -- `hostunreach` -Host is unreachable. - -- `idrm` -Identifier removed. - -- `ilseq` -Illegal byte sequence. - -- `inprogress` -Operation in progress. - -- `intr` -Interrupted function. - -- `inval` -Invalid argument. - -- `io` -I/O error. - -- `isconn` -Socket is connected. - -- `isdir` -Is a directory. - -- `loop` -Too many levels of symbolic links. - -- `mfile` -File descriptor value too large. - -- `mlink` -Too many links. - -- `msgsize` -Message too large. - -- `multihop` -Reserved. - -- `nametoolong` -Filename too long. - -- `netdown` -Network is down. - -- `netreset` -Connection aborted by network. - -- `netunreach` -Network unreachable. - -- `nfile` -Too many files open in system. - -- `nobufs` -No buffer space available. - -- `nodev` -No such device. - -- `noent` -No such file or directory. - -- `noexec` -Executable file format error. - -- `nolck` -No locks available. - -- `nolink` -Reserved. - -- `nomem` -Not enough space. - -- `nomsg` -No message of the desired type. - -- `noprotoopt` -Protocol not available. - -- `nospc` -No space left on device. - -- `nosys` -Function not supported. - -- `notconn` -The socket is not connected. - -- `notdir` -Not a directory or a symbolic link to a directory. - -- `notempty` -Directory not empty. - -- `notrecoverable` -State not recoverable. - -- `notsock` -Not a socket. - -- `notsup` -Not supported, or operation not supported on socket. - -- `notty` -Inappropriate I/O control operation. - -- `nxio` -No such device or address. - -- `overflow` -Value too large to be stored in data type. - -- `ownerdead` -Previous owner died. - -- `perm` -Operation not permitted. - -- `pipe` -Broken pipe. - -- `proto` -Protocol error. - -- `protonosupport` -Protocol not supported. - -- `prototype` -Protocol wrong type for socket. - -- `range` -Result too large. - -- `rofs` -Read-only file system. - -- `spipe` -Invalid seek. - -- `srch` -No such process. - -- `stale` -Reserved. - -- `timedout` -Connection timed out. - -- `txtbsy` -Text file busy. - -- `xdev` -Cross-device link. - -- `notcapable` -Extension: Capabilities insufficient. - -## `rights`: `Record` -File descriptor rights, determining which actions may be performed. - -Size: 8 - -Alignment: 8 - -### Record members -- `fd_datasync`: `bool` -The right to invoke `fd_datasync`. -If `path_open` is set, includes the right to invoke -`path_open` with [`fdflags::dsync`](#fdflags.dsync). - -Bit: 0 - -- `fd_read`: `bool` -The right to invoke `fd_read` and `sock_recv`. -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. - -Bit: 1 - -- `fd_seek`: `bool` -The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). - -Bit: 2 - -- `fd_fdstat_set_flags`: `bool` -The right to invoke `fd_fdstat_set_flags`. - -Bit: 3 - -- `fd_sync`: `bool` -The right to invoke `fd_sync`. -If `path_open` is set, includes the right to invoke -`path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - -Bit: 4 - -- `fd_tell`: `bool` -The right to invoke `fd_seek` in such a way that the file offset -remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to -invoke `fd_tell`. - -Bit: 5 - -- `fd_write`: `bool` -The right to invoke `fd_write` and `sock_send`. -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. - -Bit: 6 - -- `fd_advise`: `bool` -The right to invoke `fd_advise`. - -Bit: 7 - -- `fd_allocate`: `bool` -The right to invoke `fd_allocate`. - -Bit: 8 - -- `path_create_directory`: `bool` -The right to invoke `path_create_directory`. - -Bit: 9 - -- `path_create_file`: `bool` -If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). - -Bit: 10 - -- `path_link_source`: `bool` -The right to invoke `path_link` with the file descriptor as the -source directory. - -Bit: 11 - -- `path_link_target`: `bool` -The right to invoke `path_link` with the file descriptor as the -target directory. - -Bit: 12 - -- `path_open`: `bool` -The right to invoke `path_open`. - -Bit: 13 - -- `fd_readdir`: `bool` -The right to invoke `fd_readdir`. - -Bit: 14 - -- `path_readlink`: `bool` -The right to invoke `path_readlink`. - -Bit: 15 - -- `path_rename_source`: `bool` -The right to invoke `path_rename` with the file descriptor as the source directory. - -Bit: 16 - -- `path_rename_target`: `bool` -The right to invoke `path_rename` with the file descriptor as the target directory. - -Bit: 17 - -- `path_filestat_get`: `bool` -The right to invoke `path_filestat_get`. - -Bit: 18 - -- `path_filestat_set_size`: `bool` -The right to change a file's size. -If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). -Note: there is no function named `path_filestat_set_size`. This follows POSIX design, -which only has `ftruncate` and does not provide `ftruncateat`. -While such function would be desirable from the API design perspective, there are virtually -no use cases for it since no code written for POSIX systems would use it. -Moreover, implementing it would require multiple syscalls, leading to inferior performance. - -Bit: 19 - -- `path_filestat_set_times`: `bool` -The right to invoke `path_filestat_set_times`. - -Bit: 20 - -- `path_permissions_set`: `bool` -The right to invoke `path_permissions_set`. - -Bit: 21 - -- `fd_filestat_get`: `bool` -The right to invoke `fd_filestat_get`. - -Bit: 22 - -- `fd_filestat_set_size`: `bool` -The right to invoke `fd_filestat_set_size`. - -Bit: 23 - -- `fd_filestat_set_times`: `bool` -The right to invoke `fd_filestat_set_times`. - -Bit: 24 - -- `fd_permissions_set`: `bool` -The right to invoke `fd_permissions_set`. - -Bit: 25 - -- `path_symlink`: `bool` -The right to invoke `path_symlink`. - -Bit: 26 - -- `path_remove_directory`: `bool` -The right to invoke `path_remove_directory`. - -Bit: 27 - -- `path_unlink_file`: `bool` -The right to invoke `path_unlink_file`. - -Bit: 28 - -- `poll_fd_readwrite`: `bool` -If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). -If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). - -Bit: 29 - -- `sock_shutdown`: `bool` -The right to invoke `sock_shutdown`. - -Bit: 30 - -## `fd`: `Handle` -A file descriptor handle. - -Size: 4 - -Alignment: 4 - -### Supertypes -## `iovec`: `Record` -A region of memory for scatter/gather reads. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `Pointer` -The address of the buffer to be filled. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be filled. - -Offset: 4 - -## `ciovec`: `Record` -A region of memory for scatter/gather writes. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `ConstPointer` -The address of the buffer to be written. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be written. - -Offset: 4 - -## `iovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `ciovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `filedelta`: `s64` -Relative offset within a file. - -Size: 8 - -Alignment: 8 - -## `whence`: `Variant` -The position relative to which to set the offset of the file descriptor. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `set` -Seek relative to start-of-file. - -- `cur` -Seek relative to current position. - -- `end` -Seek relative to end-of-file. - -## `dircookie`: `u64` -A reference to the offset of a directory entry. - -Size: 8 - -Alignment: 8 - -### Constants -- `start` - -## `dirnamlen`: `u32` -The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). - -Size: 4 - -Alignment: 4 - -## `inode`: `u64` -File serial number that is unique within its file system. - -Size: 8 - -Alignment: 8 - -## `filetype`: `Variant` -The type of a file descriptor or file. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `unknown` -The type of the file descriptor or file is unknown or is different from any of the other types specified. - -- `block_device` -The file descriptor or file refers to a block device inode. - -- `character_device` -The file descriptor or file refers to a character device inode. - -- `directory` -The file descriptor or file refers to a directory inode. - -- `regular_file` -The file descriptor or file refers to a regular file inode. - -- `socket_dgram` -The file descriptor or file refers to a datagram socket. - -- `socket_stream` -The file descriptor or file refers to a byte-stream socket. - -- `symbolic_link` -The file refers to a symbolic link inode. - -- `fifo` -The file descriptor or file refers to a FIFO. - -## `dirent`: `Record` -A directory entry. - -Size: 24 - -Alignment: 8 - -### Record members -- `d_next`: [`dircookie`](#dircookie) -The offset of the next directory entry stored in this directory. - -Offset: 0 - -- `d_ino`: [`inode`](#inode) -The serial number of the file referred to by this directory entry. - -Offset: 8 - -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. - -Offset: 16 - -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. - -Offset: 20 - -## `advice`: `Variant` -File or memory access pattern advisory information. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `normal` -The application has no advice to give on its behavior with respect to the specified data. - -- `sequential` -The application expects to access the specified data sequentially from lower offsets to higher offsets. - -- `random` -The application expects to access the specified data in a random order. - -- `willneed` -The application expects to access the specified data in the near future. - -- `dontneed` -The application expects that it will not access the specified data in the near future. - -- `noreuse` -The application expects to access the specified data once and then not reuse it thereafter. - -## `fdflags`: `Record` -File descriptor flags. - -Size: 2 - -Alignment: 2 - -### Record members -- `append`: `bool` -Append mode: Data written to the file is always appended to the file's end. - -Bit: 0 - -- `dsync`: `bool` -Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - -Bit: 1 - -- `nonblock`: `bool` -Non-blocking mode. - -Bit: 2 - -- `rsync`: `bool` -Synchronized read I/O operations. - -Bit: 3 - -- `sync`: `bool` -Write according to synchronized I/O file integrity completion. In -addition to synchronizing the data stored in the file, the implementation -may also synchronously update the file's metadata. - -Bit: 4 - -## `fdstat`: `Record` -File descriptor attributes. - -Size: 24 - -Alignment: 8 - -### Record members -- `fs_filetype`: [`filetype`](#filetype) -File type. - -Offset: 0 - -- `fs_flags`: [`fdflags`](#fdflags) -File descriptor flags. - -Offset: 2 - -- `fs_rights_base`: [`rights`](#rights) -Rights that apply to this file descriptor. - -Offset: 8 - -- `fs_rights_inheriting`: [`rights`](#rights) -Maximum set of rights that may be installed on new file descriptors that -are created through this file descriptor, e.g., through `path_open`. - -Offset: 16 - -## `device`: `u64` -Identifier for a device containing a file system. Can be used in combination -with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. - -Size: 8 - -Alignment: 8 - -## `fstflags`: `Record` -Which file time attributes to adjust. - -Size: 2 - -Alignment: 2 - -### Record members -- `atim`: `bool` -Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - -Bit: 0 - -- `atim_now`: `bool` -Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 1 - -- `mtim`: `bool` -Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - -Bit: 2 - -- `mtim_now`: `bool` -Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 3 - -## `lookupflags`: `Record` -Flags determining the method of how paths are resolved. - -Size: 4 - -Alignment: 4 - -### Record members -- `symlink_follow`: `bool` -As long as the resolved path corresponds to a symbolic link, it is expanded. - -Bit: 0 - -## `oflags`: `Record` -Open flags used by `path_open`. - -Size: 2 - -Alignment: 2 - -### Record members -- `create`: `bool` -Create file if it does not exist. - -Bit: 0 - -- `directory`: `bool` -Fail if not a directory. - -Bit: 1 - -- `excl`: `bool` -Fail if file already exists. - -Bit: 2 - -- `trunc`: `bool` -Truncate file to size 0. - -Bit: 3 - -## `linkcount`: `u64` -Number of hard links to an inode. - -Size: 8 - -Alignment: 8 - -## `permissions`: `Record` -File permissions. This represents the permissions associated with a -file in a filesystem, and don't fully reflect all the conditions -which determine whether a given WASI program can access the file. - -Size: 1 - -Alignment: 1 - -### Record members -- `read`: `bool` -For files, permission to read the file. -For directories, permission to do [`readdir`](#readdir) and access files -within the directory. - -Note: This is similar to the read bit being set on files, and the -read *and* execute bits being set on directories, in POSIX. - -Bit: 0 - -- `write`: `bool` -For files, permission to mutate the file. -For directories, permission to create, remove, and rename items -within the directory. - -Bit: 1 - -- `execute`: `bool` -For files, permission to "execute" the file, using whatever -concept of "executing" the host filesystem has. -This flag is not valid for directories. - -Bit: 2 - -- `private`: `bool` -For filesystems which have a concept of multiple "users", this flag -indicates that the file is only accessible by the effective "user" -that the WASI store uses to access the filesystem, and inaccessible -to other "users". - -Bit: 3 - -## `filestat`: `Record` -File attributes. - -Size: 64 - -Alignment: 8 - -### Record members -- `dev`: [`device`](#device) -Device ID of device containing the file. - -Offset: 0 - -- `ino`: [`inode`](#inode) -File serial number. - -Offset: 8 - -- `filetype`: [`filetype`](#filetype) -File type. - -Offset: 16 - -- `permissions`: [`permissions`](#permissions) -File permissions. - -Offset: 17 - -- `nlink`: [`linkcount`](#linkcount) -Number of hard links to the file. - -Offset: 24 - -- `size`: [`filesize`](#filesize) -For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - -Offset: 32 - -- `atim`: [`timestamp`](#timestamp) -Last data access timestamp. - -Offset: 40 - -- `mtim`: [`timestamp`](#timestamp) -Last data modification timestamp. - -Offset: 48 - -- `ctim`: [`timestamp`](#timestamp) -Last file status change timestamp. - -Offset: 56 - -## `userdata`: `u64` -User-provided value that may be attached to objects that is retained when -extracted from the implementation. - -Size: 8 - -Alignment: 8 - -## `eventtype`: `Variant` -Type of a subscription to an event or its occurrence. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `clock` -The time value of clock [`subscription_clock::id`](#subscription_clock.id) has -reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - -- `fd_read` -File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has data -available for reading. This event always triggers for regular files. - -- `fd_write` -File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity -available for writing. This event always triggers for regular files. - -## `eventrwflags`: `Record` -The state of the file descriptor subscribed to with -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 2 - -Alignment: 2 - -### Record members -- `fd_readwrite_hangup`: `bool` -The peer of this socket has closed or disconnected. - -Bit: 0 - -## `event_fd_readwrite`: `Record` -The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). - -Size: 16 - -Alignment: 8 - -### Record members -- `nbytes`: [`filesize`](#filesize) -The number of bytes available for reading or writing. - -Offset: 0 - -- `flags`: [`eventrwflags`](#eventrwflags) -The state of the file descriptor. - -Offset: 8 - -## `event_u`: `Variant` -The contents of an [`event`](#event). - -Size: 24 - -Alignment: 8 - -### Variant Layout -- size: 24 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock` - -- `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) - -- `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) - -## `event`: `Record` -An event that occurred. - -Size: 40 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). - -Offset: 0 - -- `error`: [`errno`](#errno) -If non-zero, an error that occurred while processing the subscription request. - -Offset: 8 - -- `u`: [`event_u`](#event_u) -The type of the event that occurred, and the contents of the event - -Offset: 16 - -## `subclockflags`: `Record` -Flags determining how to interpret the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout). - -Size: 2 - -Alignment: 2 - -### Record members -- `subscription_clock_abstime`: `bool` -If set, treat the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock -[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp -provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the -current time value of clock [`subscription_clock::id`](#subscription_clock.id). - -Bit: 0 - -## `subscription_clock`: `Record` -The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). - -Size: 32 - -Alignment: 8 - -### Record members -- `id`: [`clockid`](#clockid) -The clock against which to compare the timestamp. - -Offset: 0 - -- `timeout`: [`timestamp`](#timestamp) -The absolute or relative timestamp. - -Offset: 8 - -- `precision`: [`timestamp`](#timestamp) -The amount of time that the implementation may wait additionally -to coalesce with other events. - -Offset: 16 - -- `flags`: [`subclockflags`](#subclockflags) -Flags specifying whether the timeout is absolute or relative - -Offset: 24 - -## `subscription_fd_readwrite`: `Record` -The contents of a [`subscription`](#subscription) when type is type is -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 4 - -Alignment: 4 - -### Record members -- `fd`: [`fd`](#fd) -The file descriptor on which to wait for it to become ready for reading or writing. - -Offset: 0 - -## `subscription_u`: `Variant` -The contents of a [`subscription`](#subscription). - -Size: 40 - -Alignment: 8 - -### Variant Layout -- size: 40 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock`: [`subscription_clock`](#subscription_clock) - -- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -## `subscription`: `Record` -Subscription to an event. - -Size: 48 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that is attached to the subscription in the -implementation and returned through [`event::userdata`](#event.userdata). - -Offset: 0 - -- `u`: [`subscription_u`](#subscription_u) -The type of the event to which to subscribe, and the contents of the subscription. - -Offset: 8 - -## `exitcode`: `u8` -Exit code generated by a program when exiting. - -Size: 1 - -Alignment: 1 - -### Constants -- `success` - -- `failure` - -## `riflags`: `Record` -Flags provided to `sock_recv`. - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_peek`: `bool` -Returns the message without removing it from the socket's receive queue. - -Bit: 0 - -- `recv_waitall`: `bool` -On byte-stream sockets, block until the full amount of data can be returned. - -Bit: 1 - -## `roflags`: `Record` -Flags returned by `sock_recv`. - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_data_truncated`: `bool` -Returned by `sock_recv`: Message data has been truncated. - -Bit: 0 - -## `siflags`: `u16` -Flags provided to `sock_send`. As there are currently no flags -defined, it must be set to zero. - -Size: 2 - -Alignment: 2 - -## `sdflags`: `Record` -Which channels on a socket to shut down. - -Size: 1 - -Alignment: 1 - -### Record members -- `rd`: `bool` -Disables further receive operations. - -Bit: 0 - -- `wr`: `bool` -Disables further send operations. - -Bit: 1 - -## `preopentype`: `Variant` -Identifiers for preopened capabilities. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `dir` -A pre-opened directory. - -## `prestat_dir`: `Record` -The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). - -Size: 4 - -Alignment: 4 - -### Record members -- `pr_name_len`: [`size`](#size) -The length of the directory name for use with `fd_prestat_dir_name`. - -Offset: 0 - -## `prestat`: `Variant` -Information about a pre-opened capability. - -Size: 8 - -Alignment: 4 - -### Variant Layout -- size: 8 -- align: 4 -- tag_size: 1 -### Variant cases -- `dir`: [`prestat_dir`](#prestat_dir) -When type is [`preopentype::dir`](#preopentype.dir): - -# Modules -## wasi_ephemeral_args -### Imports -#### Memory -### Functions - ---- - -#### `get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` -Read command-line argument data. -The size of the array should match that returned by [`sizes_get`](#sizes_get). -Each argument is expected to be `\0` terminated. - -##### Params -- `argv`: `Pointer>` - -- `argv_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sizes_get() -> Result<(size, size), errno>` -Return command-line argument data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of arguments and the size of the argument string -data, or an error. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_clock -### Imports -#### Memory -### Functions - ---- - -#### `res_get(id: clockid) -> Result` -Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, -return [`errno::inval`](#errno.inval). -Note: This is similar to `clock_getres` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the resolution. - -##### Results -- `error`: `Result` -The resolution of the clock. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `time_get(id: clockid, precision: timestamp) -> Result` -Return the time value of a clock. -Note: This is similar to `clock_gettime` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the time. - -- `precision`: [`timestamp`](#timestamp) -The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - -##### Results -- `error`: `Result` -The time value of the clock. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_environ -### Imports -#### Memory -### Functions - ---- - -#### `get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` -Read environment variable data. -The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). -Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - -##### Params -- `environ`: `Pointer>` - -- `environ_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sizes_get() -> Result<(size, size), errno>` -Return environment variable data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of environment variable arguments and the size of the -environment variable data. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_fd -### Imports -#### Memory -### Functions - ---- - -#### `advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` -Provide file advisory information on a file descriptor. -Note: This is similar to `posix_fadvise` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset within the file to which the advisory applies. - -- `len`: [`filesize`](#filesize) -The length of the region to which the advisory applies. - -- `advice`: [`advice`](#advice) -The advice. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` -Force the allocation of space in a file. -Note: This is similar to `posix_fallocate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset at which to start the allocation. - -- `len`: [`filesize`](#filesize) -The length of the area that is allocated. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `close(fd: fd) -> Result<(), errno>` -Close a file descriptor. -Note: This is similar to [`close`](#close) in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `datasync(fd: fd) -> Result<(), errno>` -Synchronize the data of a file to disk. -Note: This is similar to `fdatasync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fdstat_get(fd: fd) -> Result` -Get the attributes of a file descriptor. -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file descriptor's attributes are stored. - -###### Variant Layout -- size: 32 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`fdstat`](#fdstat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` -Adjust the flags associated with a file descriptor. -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`fdflags`](#fdflags) -The desired values of the file descriptor flags. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` -Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights - -##### Params -- `fd`: [`fd`](#fd) - -- `fs_rights_base`: [`rights`](#rights) -The desired rights of the file descriptor. - -- `fs_rights_inheriting`: [`rights`](#rights) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_get(fd: fd) -> Result` -Return the attributes of an open file. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 72 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` -Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. -Note: This is similar to `ftruncate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `size`: [`filesize`](#filesize) -The desired file size. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of an open file or directory. -Note: This is similar to `futimens` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `permissions_set(fd: fd, permissions: permissions) -> Result<(), errno>` -Set the permissions of a file or directory. - -This sets the permissions associated with a file or directory in -a filesystem at the time it is called. The ability to actually access -a file or directory may depend on additional permissions not reflected -here. - -Note: This is similar `fchmod` in POSIX. - -Unlike POSIX, this doesn't expose a user/group/other distinction; -implementations in POSIX environments are suggested to consult the -umask to determine which of the user/group/other flags to modify. - -##### Params -- `fd`: [`fd`](#fd) - -- `permissions`: [`permissions`](#permissions) -The permissions associated with the file. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` -Read from a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `preadv` in Linux (and other Unix-es). - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors in which to store data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to read. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `prestat_get(fd: fd) -> Result` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the description is stored. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`prestat`](#prestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `Pointer` -A buffer into which to write the preopened directory name. - -- `path_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` -Write to a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `pwritev` in Linux (and other Unix-es). - -Like Linux (and other Unix-es), any calls of [`pwrite`](#pwrite) (and other -functions to read or write) for a regular file by other threads in the -WASI process should not be interleaved while [`pwrite`](#pwrite) is executed. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to write. - -##### Results -- `error`: `Result` -The number of bytes written. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `read(fd: fd, iovs: iovec_array) -> Result` -Read from a file descriptor. -Note: This is similar to `readv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` -Read directory entries from a directory. -When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a [`dirent`](#dirent) object, -followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory -entry. -This function fills the output buffer as much as possible, potentially -truncating the last directory entry. This allows the caller to grow its -read buffer size in case it's too small to fit a single large directory -entry, or skip the oversized directory entry. - -##### Params -- `fd`: [`fd`](#fd) - -- `buf`: `Pointer` -The buffer where directory entries are stored - -- `buf_len`: [`size`](#size) - -- `cookie`: [`dircookie`](#dircookie) -The location within the directory to start reading - -##### Results -- `error`: `Result` -The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `renumber(fd: fd, to: fd) -> Result<(), errno>` -Atomically replace a file descriptor by renumbering another file descriptor. -Due to the strong focus on thread safety, this environment does not provide -a mechanism to duplicate or renumber a file descriptor to an arbitrary -number, like `dup2()`. This would be prone to race conditions, as an actual -file descriptor with the same number could be allocated by a different -thread at the same time. -This function provides a way to atomically renumber file descriptors, which -would disappear if `dup2()` were to be removed entirely. - -##### Params -- `fd`: [`fd`](#fd) - -- `to`: [`fd`](#fd) -The file descriptor to overwrite. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `seek(fd: fd, offset: filedelta, whence: whence) -> Result` -Move the offset of a file descriptor. -Note: This is similar to `lseek` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filedelta`](#filedelta) -The number of bytes to move. - -- `whence`: [`whence`](#whence) -The base from which the offset is relative. - -##### Results -- `error`: `Result` -The new offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `sync(fd: fd) -> Result<(), errno>` -Synchronize the data and metadata of a file to disk. -Note: This is similar to `fsync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `tell(fd: fd) -> Result` -Return the current offset of a file descriptor. -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The current offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `write(fd: fd, iovs: ciovec_array) -> Result` -Write to a file descriptor. -Note: This is similar to `writev` in POSIX. - -Like POSIX, any calls of [`write`](#write) (and other functions to read or write) -for a regular file by other threads in the WASI process should not be -interleaved while [`write`](#write) is executed. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -##### Results -- `error`: `Result` -The number of bytes written. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_path -### Imports -#### Memory -### Functions - ---- - -#### `create_directory(fd: fd, path: string) -> Result<(), errno>` -Create a directory. -Note: This is similar to `mkdirat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path at which to create the directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` -Return the attributes of a file or directory. -Note: This is similar to `stat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to inspect. - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 72 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of a file or directory. -Note: This is similar to `utimensat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to operate on. - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `permissions_set(fd: fd, flags: lookupflags, path: string, permissions: permissions) -> Result<(), errno>` -Set the permissions of a file or directory. - -This sets the permissions associated with a file or directory in -a filesystem at the time it is called. The ability to actually access -a file or directory may depend on additional permissions not reflected -here. - -Note: This is similar to `fchmodat` in POSIX. - -Unlike POSIX, this doesn't expose a user/group/other distinction; -implementations in POSIX environments are suggested to consult the -umask to determine which of the user/group/other flags to modify. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path to a file to query. - -- `permissions`: [`permissions`](#permissions) -The permissions to associate with the file. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Create a hard link. -Note: This is similar to `linkat` in POSIX. - -##### Params -- `old_fd`: [`fd`](#fd) - -- `old_flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `old_path`: `string` -The source path from which to link. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path at which to create the hard link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, permissions: permissions) -> Result` -Open a file or directory. -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since this -is error-prone in multi-threaded contexts. The returned file descriptor is -guaranteed to be less than 2**31. -Note: This is similar to `openat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `dirflags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The relative path of the file or directory to open, relative to the -[`fd`](#fd) directory. - -- `oflags`: [`oflags`](#oflags) -The method by which to open the file. - -- `fs_rights_base`: [`rights`](#rights) -The initial rights of the newly created file descriptor. The -implementation is allowed to return a file descriptor with fewer rights -than specified, if and only if those rights do not apply to the type of -file being opened. -The *base* rights are rights that will apply to operations using the file -descriptor itself, while the *inheriting* rights are rights that apply to -file descriptors derived from it. - -- `fs_rights_inheriting`: [`rights`](#rights) - -- `fdflags`: [`fdflags`](#fdflags) - -- `permissions`: [`permissions`](#permissions) -If a file is created, the filesystem permissions to associate with it. - -##### Results -- `error`: `Result` -The file descriptor of the file that has been opened. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`fd`](#fd) - -- `err`: [`errno`](#errno) - - ---- - -#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` -Read the contents of a symbolic link. -Note: This is similar to `readlinkat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path of the symbolic link from which to read. - -- `buf`: `Pointer` -The buffer to which to write the contents of the symbolic link. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result` -The number of bytes placed in the buffer. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `remove_directory(fd: fd, path: string) -> Result<(), errno>` -Remove a directory. -Return [`errno::notempty`](#errno.notempty) if the directory is not empty. -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a directory to remove. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Rename a file or directory. -Note: This is similar to `renameat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `old_path`: `string` -The source path of the file or directory to rename. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path to which to rename the file or directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` -Create a symbolic link. -Note: This is similar to `symlinkat` in POSIX. - -##### Params -- `old_path`: `string` -The contents of the symbolic link. - -- `fd`: [`fd`](#fd) - -- `new_path`: `string` -The destination path at which to create the symbolic link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `unlink_file(fd: fd, path: string) -> Result<(), errno>` -Unlink a file. -Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a file to unlink. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_poll -### Imports -#### Memory -### Functions - ---- - -#### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` -Concurrently poll for the occurrence of a set of events. - -If `nsubscriptions` is 0, returns [`errno::inval`](#errno.inval). - -##### Params -- `in`: `ConstPointer` -The events to which to subscribe. - -- `out`: `Pointer` -The events that have occurred. - -- `nsubscriptions`: [`size`](#size) -Both the number of subscriptions and events. - -##### Results -- `error`: `Result` -The number of events stored. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_proc -### Imports -### Functions - ---- - -#### `exit(rval: exitcode)` -Terminate the process normally. An exit code of `$exitcode::success` -reports successful completion of the program. An exit code of -`$exitcode::failure` or any other value less than 126 reports a -failure, and the value is provided to the environment. If a value -of 126 or greater is given, this function behaves as if it were -implemented by an `unreachable` instruction. - -##### Params -- `rval`: [`exitcode`](#exitcode) -The exit code returned by the process. - -##### Results -## wasi_ephemeral_random -### Imports -#### Memory -### Functions - ---- - -#### `get(buf: Pointer, buf_len: size) -> Result<(), errno>` -Write high-quality random data into a buffer. -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. -This function may execute slowly, so when large mounts of random data are -required, it's advisable to use this function to seed a pseudo-random -number generator, rather than to provide the random data directly. - -##### Params -- `buf`: `Pointer` -The buffer to fill with random data. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_sched -### Imports -### Functions - ---- - -#### `yield() -> Result<(), errno>` -Temporarily yield execution of the calling thread. -Note: This is similar to [`yield`](#yield) in POSIX. - -##### Params -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_sock -### Imports -#### Memory -### Functions - ---- - -#### `recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` -Receive a message from a socket. -Note: This is similar to [`recv`](#recv) in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -##### Params -- `fd`: [`fd`](#fd) - -- `ri_data`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -- `ri_flags`: [`riflags`](#riflags) -Message flags. - -##### Results -- `error`: `Result<(size, roflags), errno>` -Number of bytes stored in ri_data and message flags. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, roflags)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`roflags`](#roflags) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` -Send a message on a socket. -Note: This is similar to [`send`](#send) in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -##### Params -- `fd`: [`fd`](#fd) - -- `si_data`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors to which to retrieve data - -- `si_flags`: [`siflags`](#siflags) -Message flags. - -##### Results -- `error`: `Result` -Number of bytes transmitted. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `shutdown(fd: fd, how: sdflags) -> Result<(), errno>` -Shut down socket send and receive channels. -Note: This is similar to [`shutdown`](#shutdown) in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `how`: [`sdflags`](#sdflags) -Which channels on the socket to shut down. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - diff --git a/proposals/filesystem/phases/ephemeral/witx/typenames.witx b/proposals/filesystem/phases/ephemeral/witx/typenames.witx deleted file mode 100644 index bbd6489df..000000000 --- a/proposals/filesystem/phases/ephemeral/witx/typenames.witx +++ /dev/null @@ -1,708 +0,0 @@ -;; Type names used by low-level WASI interfaces. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -;;; An array size. -;;; -;;; Note: This is similar to `size_t` in POSIX. -(typename $size (@witx usize)) - -;;; Non-negative file size or length of a region within a file. -(typename $filesize u64) - -;;; Timestamp in nanoseconds. -(typename $timestamp u64) - -;;; Identifiers for clocks. -(typename $clockid - (enum (@witx tag u32) - ;;; The clock measuring real time. Time value zero corresponds with - ;;; 1970-01-01T00:00:00Z. - $realtime - ;;; The store-wide monotonic clock, which is defined as a clock measuring - ;;; real time, whose value cannot be adjusted and which cannot have negative - ;;; clock jumps. The epoch of this clock is undefined. The absolute time - ;;; value of this clock therefore has no meaning. - $monotonic - ) -) - -;;; Error codes returned by functions. -;;; Not all of these error codes are returned by the functions provided by this -;;; API; some are used in higher-level library layers, and others are provided -;;; merely for alignment with POSIX. -(typename $errno - (enum (@witx tag u16) - ;;; No error occurred. System call completed successfully. - $success - ;;; Argument list too long. - $2big - ;;; Permission denied. - $access - ;;; Address in use. - $addrinuse - ;;; Address not available. - $addrnotavail - ;;; Address family not supported. - $afnosupport - ;;; Resource unavailable, or operation would block. - $again - ;;; Connection already in progress. - $already - ;;; Bad file descriptor. - $badf - ;;; Bad message. - $badmsg - ;;; Device or resource busy. - $busy - ;;; Operation canceled. - $canceled - ;;; No child processes. - $child - ;;; Connection aborted. - $connaborted - ;;; Connection refused. - $connrefused - ;;; Connection reset. - $connreset - ;;; Resource deadlock would occur. - $deadlk - ;;; Destination address required. - $destaddrreq - ;;; Mathematics argument out of domain of function. - $dom - ;;; Reserved. - $dquot - ;;; File exists. - $exist - ;;; Bad address. - $fault - ;;; File too large. - $fbig - ;;; Host is unreachable. - $hostunreach - ;;; Identifier removed. - $idrm - ;;; Illegal byte sequence. - $ilseq - ;;; Operation in progress. - $inprogress - ;;; Interrupted function. - $intr - ;;; Invalid argument. - $inval - ;;; I/O error. - $io - ;;; Socket is connected. - $isconn - ;;; Is a directory. - $isdir - ;;; Too many levels of symbolic links. - $loop - ;;; File descriptor value too large. - $mfile - ;;; Too many links. - $mlink - ;;; Message too large. - $msgsize - ;;; Reserved. - $multihop - ;;; Filename too long. - $nametoolong - ;;; Network is down. - $netdown - ;;; Connection aborted by network. - $netreset - ;;; Network unreachable. - $netunreach - ;;; Too many files open in system. - $nfile - ;;; No buffer space available. - $nobufs - ;;; No such device. - $nodev - ;;; No such file or directory. - $noent - ;;; Executable file format error. - $noexec - ;;; No locks available. - $nolck - ;;; Reserved. - $nolink - ;;; Not enough space. - $nomem - ;;; No message of the desired type. - $nomsg - ;;; Protocol not available. - $noprotoopt - ;;; No space left on device. - $nospc - ;;; Function not supported. - $nosys - ;;; The socket is not connected. - $notconn - ;;; Not a directory or a symbolic link to a directory. - $notdir - ;;; Directory not empty. - $notempty - ;;; State not recoverable. - $notrecoverable - ;;; Not a socket. - $notsock - ;;; Not supported, or operation not supported on socket. - $notsup - ;;; Inappropriate I/O control operation. - $notty - ;;; No such device or address. - $nxio - ;;; Value too large to be stored in data type. - $overflow - ;;; Previous owner died. - $ownerdead - ;;; Operation not permitted. - $perm - ;;; Broken pipe. - $pipe - ;;; Protocol error. - $proto - ;;; Protocol not supported. - $protonosupport - ;;; Protocol wrong type for socket. - $prototype - ;;; Result too large. - $range - ;;; Read-only file system. - $rofs - ;;; Invalid seek. - $spipe - ;;; No such process. - $srch - ;;; Reserved. - $stale - ;;; Connection timed out. - $timedout - ;;; Text file busy. - $txtbsy - ;;; Cross-device link. - $xdev - ;;; Extension: Capabilities insufficient. - $notcapable - ) -) - -;;; File descriptor rights, determining which actions may be performed. -(typename $rights - (flags (@witx repr u64) - ;;; The right to invoke `fd_datasync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::dsync`. - $fd_datasync - ;;; The right to invoke `fd_read` and `sock_recv`. - ;; - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. - $fd_read - ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. - $fd_seek - ;;; The right to invoke `fd_fdstat_set_flags`. - $fd_fdstat_set_flags - ;;; The right to invoke `fd_sync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. - $fd_sync - ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to - ;;; invoke `fd_tell`. - $fd_tell - ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. - $fd_write - ;;; The right to invoke `fd_advise`. - $fd_advise - ;;; The right to invoke `fd_allocate`. - $fd_allocate - ;;; The right to invoke `path_create_directory`. - $path_create_directory - ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::create`. - $path_create_file - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; source directory. - $path_link_source - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; target directory. - $path_link_target - ;;; The right to invoke `path_open`. - $path_open - ;;; The right to invoke `fd_readdir`. - $fd_readdir - ;;; The right to invoke `path_readlink`. - $path_readlink - ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $path_rename_source - ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $path_rename_target - ;;; The right to invoke `path_filestat_get`. - $path_filestat_get - ;;; The right to change a file's size. - ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. - ;;; Note: there is no function named `path_filestat_set_size`. This follows POSIX design, - ;;; which only has `ftruncate` and does not provide `ftruncateat`. - ;;; While such function would be desirable from the API design perspective, there are virtually - ;;; no use cases for it since no code written for POSIX systems would use it. - ;;; Moreover, implementing it would require multiple syscalls, leading to inferior performance. - $path_filestat_set_size - ;;; The right to invoke `path_filestat_set_times`. - $path_filestat_set_times - ;;; The right to invoke `path_permissions_set`. - $path_permissions_set - ;;; The right to invoke `fd_filestat_get`. - $fd_filestat_get - ;;; The right to invoke `fd_filestat_set_size`. - $fd_filestat_set_size - ;;; The right to invoke `fd_filestat_set_times`. - $fd_filestat_set_times - ;;; The right to invoke `fd_permissions_set`. - $fd_permissions_set - ;;; The right to invoke `path_symlink`. - $path_symlink - ;;; The right to invoke `path_remove_directory`. - $path_remove_directory - ;;; The right to invoke `path_unlink_file`. - $path_unlink_file - ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. - ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. - $poll_fd_readwrite - ;;; The right to invoke `sock_shutdown`. - $sock_shutdown - ) -) - -;;; A file descriptor handle. -(typename $fd (handle)) - -;;; A region of memory for scatter/gather reads. -(typename $iovec - (record - ;;; The address of the buffer to be filled. - (field $buf (@witx pointer u8)) - ;;; The length of the buffer to be filled. - (field $buf_len $size) - ) -) - -;;; A region of memory for scatter/gather writes. -(typename $ciovec - (record - ;;; The address of the buffer to be written. - (field $buf (@witx const_pointer u8)) - ;;; The length of the buffer to be written. - (field $buf_len $size) - ) -) - -(typename $iovec_array (list $iovec)) -(typename $ciovec_array (list $ciovec)) - -;;; Relative offset within a file. -(typename $filedelta s64) - -;;; The position relative to which to set the offset of the file descriptor. -(typename $whence - (enum (@witx tag u8) - ;;; Seek relative to start-of-file. - $set - ;;; Seek relative to current position. - $cur - ;;; Seek relative to end-of-file. - $end - ) -) - -;;; A reference to the offset of a directory entry. -(typename $dircookie u64) - -;;; In an `fd_readdir` call, this value signifies the start of the directory. -(@witx const $dircookie $start 0) - -;;; The type for the `dirent::d_namlen` field of `dirent`. -(typename $dirnamlen u32) - -;;; File serial number that is unique within its file system. -(typename $inode u64) - -;;; The type of a file descriptor or file. -(typename $filetype - (enum (@witx tag u8) - ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $unknown - ;;; The file descriptor or file refers to a block device inode. - $block_device - ;;; The file descriptor or file refers to a character device inode. - $character_device - ;;; The file descriptor or file refers to a directory inode. - $directory - ;;; The file descriptor or file refers to a regular file inode. - $regular_file - ;;; The file descriptor or file refers to a datagram socket. - $socket_dgram - ;;; The file descriptor or file refers to a byte-stream socket. - $socket_stream - ;;; The file refers to a symbolic link inode. - $symbolic_link - ;;; The file descriptor or file refers to a FIFO. - $fifo - ) -) - -;;; A directory entry. -(typename $dirent - (record - ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie) - ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode) - ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) - ) -) - -;;; File or memory access pattern advisory information. -(typename $advice - (enum (@witx tag u8) - ;;; The application has no advice to give on its behavior with respect to the specified data. - $normal - ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $sequential - ;;; The application expects to access the specified data in a random order. - $random - ;;; The application expects to access the specified data in the near future. - $willneed - ;;; The application expects that it will not access the specified data in the near future. - $dontneed - ;;; The application expects to access the specified data once and then not reuse it thereafter. - $noreuse - ) -) - -;;; File descriptor flags. -(typename $fdflags - (flags (@witx repr u16) - ;;; Append mode: Data written to the file is always appended to the file's end. - $append - ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $dsync - ;;; Non-blocking mode. - $nonblock - ;;; Synchronized read I/O operations. - $rsync - ;;; Write according to synchronized I/O file integrity completion. In - ;;; addition to synchronizing the data stored in the file, the implementation - ;;; may also synchronously update the file's metadata. - $sync - ) -) - -;;; File descriptor attributes. -(typename $fdstat - (record - ;;; File type. - (field $fs_filetype $filetype) - ;;; File descriptor flags. - (field $fs_flags $fdflags) - ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights) - ;;; Maximum set of rights that may be installed on new file descriptors that - ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights) - ) -) - -;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode` to uniquely identify a file or directory in the filesystem. -(typename $device u64) - -;;; Which file time attributes to adjust. -(typename $fstflags - (flags (@witx repr u16) - ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. - $atim - ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. - $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. - $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. - $mtim_now - ) -) - -;;; Flags determining the method of how paths are resolved. -(typename $lookupflags - (flags (@witx repr u32) - ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $symlink_follow - ) -) - -;;; Open flags used by `path_open`. -(typename $oflags - (flags (@witx repr u16) - ;;; Create file if it does not exist. - $create - ;;; Fail if not a directory. - $directory - ;;; Fail if file already exists. - $excl - ;;; Truncate file to size 0. - $trunc - ) -) - -;;; Number of hard links to an inode. -(typename $linkcount u64) - -;;; File permissions. This represents the permissions associated with a -;;; file in a filesystem, and don't fully reflect all the conditions -;;; which determine whether a given WASI program can access the file. -(typename $permissions - (flags (@witx repr u8) - ;;; For files, permission to read the file. - ;;; For directories, permission to do `readdir` and access files - ;;; within the directory. - ;;; - ;;; Note: This is similar to the read bit being set on files, and the - ;;; read *and* execute bits being set on directories, in POSIX. - $read - - ;;; For files, permission to mutate the file. - ;;; For directories, permission to create, remove, and rename items - ;;; within the directory. - $write - - ;;; For files, permission to "execute" the file, using whatever - ;;; concept of "executing" the host filesystem has. - ;;; This flag is not valid for directories. - $execute - - ;;; For filesystems which have a concept of multiple "users", this flag - ;;; indicates that the file is only accessible by the effective "user" - ;;; that the WASI store uses to access the filesystem, and inaccessible - ;;; to other "users". - $private - ) -) - -;;; File attributes. -(typename $filestat - (record - ;;; Device ID of device containing the file. - (field $dev $device) - ;;; File serial number. - (field $ino $inode) - ;;; File type. - (field $filetype $filetype) - ;;; File permissions. - (field $permissions $permissions) - ;;; Number of hard links to the file. - (field $nlink $linkcount) - ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $size $filesize) - ;;; Last data access timestamp. - (field $atim $timestamp) - ;;; Last data modification timestamp. - (field $mtim $timestamp) - ;;; Last file status change timestamp. - (field $ctim $timestamp) - ) -) - -;;; User-provided value that may be attached to objects that is retained when -;;; extracted from the implementation. -(typename $userdata u64) - -;;; Type of a subscription to an event or its occurrence. -(typename $eventtype - (enum (@witx tag u8) - ;;; The time value of clock `subscription_clock::id` has - ;;; reached timestamp `subscription_clock::timeout`. - $clock - ;;; File descriptor `subscription_fd_readwrite::fd` has data - ;;; available for reading. This event always triggers for regular files. - $fd_read - ;;; File descriptor `subscription_fd_readwrite::fd` has capacity - ;;; available for writing. This event always triggers for regular files. - $fd_write - ) -) - -;;; The state of the file descriptor subscribed to with -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $eventrwflags - (flags (@witx repr u16) - ;;; The peer of this socket has closed or disconnected. - $fd_readwrite_hangup - ) -) - -;;; The contents of an `event` when type is `eventtype::fd_read` or -;;; `eventtype::fd_write`. -(typename $event_fd_readwrite - (record - ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize) - ;;; The state of the file descriptor. - (field $flags $eventrwflags) - ) -) - -;;; The contents of an `event`. -(typename $event_u - (variant (@witx tag $eventtype) - (case $fd_read $event_fd_readwrite) - (case $fd_write $event_fd_readwrite) - (case $clock) - ) -) - -;;; An event that occurred. -(typename $event - (record - ;;; User-provided value that got attached to `subscription::userdata`. - (field $userdata $userdata) - ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno) - ;;; The type of the event that occurred, and the contents of the event - (field $u $event_u) - ) -) - -;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_clock::timeout`. -(typename $subclockflags - (flags (@witx repr u16) - ;;; If set, treat the timestamp provided in - ;;; `subscription_clock::timeout` as an absolute timestamp of clock - ;;; `subscription_clock::id`. If clear, treat the timestamp - ;;; provided in `subscription_clock::timeout` relative to the - ;;; current time value of clock `subscription_clock::id`. - $subscription_clock_abstime - ) -) - -;;; The contents of a `subscription` when type is `eventtype::clock`. -(typename $subscription_clock - (record - ;;; The clock against which to compare the timestamp. - (field $id $clockid) - ;;; The absolute or relative timestamp. - (field $timeout $timestamp) - ;;; The amount of time that the implementation may wait additionally - ;;; to coalesce with other events. - (field $precision $timestamp) - ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags) - ) -) - -;;; The contents of a `subscription` when type is type is -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $subscription_fd_readwrite - (record - ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $fd $fd) - ) -) - -;;; The contents of a `subscription`. -(typename $subscription_u - (union (@witx tag $eventtype) - $subscription_clock - $subscription_fd_readwrite - $subscription_fd_readwrite - ) -) - -;;; Subscription to an event. -(typename $subscription - (record - ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event::userdata`. - (field $userdata $userdata) - ;;; The type of the event to which to subscribe, and the contents of the subscription. - (field $u $subscription_u) - ) -) - -;;; Exit code generated by a program when exiting. -(typename $exitcode u8) - -;;; Indicate the program exited successfully. -;;; -;;; Note: This is similar to `EXIT_SUCCESS` in POSIX. -(@witx const $exitcode $success 0) - -;;; Indicate the program exited unsuccessfully. -;;; -;;; Note: This is similar to `EXIT_FAILURE` in POSIX. -(@witx const $exitcode $failure 1) - -;;; Flags provided to `sock_recv`. -(typename $riflags - (flags (@witx repr u16) - ;;; Returns the message without removing it from the socket's receive queue. - $recv_peek - ;;; On byte-stream sockets, block until the full amount of data can be returned. - $recv_waitall - ) -) - -;;; Flags returned by `sock_recv`. -(typename $roflags - (flags (@witx repr u16) - ;;; Returned by `sock_recv`: Message data has been truncated. - $recv_data_truncated - ) -) - -;;; Flags provided to `sock_send`. As there are currently no flags -;;; defined, it must be set to zero. -(typename $siflags u16) - -;;; Which channels on a socket to shut down. -(typename $sdflags - (flags (@witx repr u8) - ;;; Disables further receive operations. - $rd - ;;; Disables further send operations. - $wr - ) -) - -;;; Identifiers for preopened capabilities. -(typename $preopentype - (enum (@witx tag u8) - ;;; A pre-opened directory. - $dir - ) -) - -;;; The contents of a `prestat` when its type is `preopentype::dir`. -(typename $prestat_dir - (record - ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size) - ) -) - -;;; Information about a pre-opened capability. -(typename $prestat - (union (@witx tag $preopentype) - ;;; When type is `preopentype::dir`: - $prestat_dir - ) -) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx deleted file mode 100644 index bb956fc53..000000000 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ /dev/null @@ -1,27 +0,0 @@ -;; WASI Command-line Arguments. -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_args - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `sizes_get`. - ;;; Each argument is expected to be `\0` terminated. - (@interface func (export "get") - (param $argv (@witx pointer (@witx pointer (@witx char8)))) - (param $argv_buf (@witx pointer (@witx char8))) - (result $error (expected (error $errno))) - ) - - ;;; Return command-line argument data sizes. - (@interface func (export "sizes_get") - ;;; Returns the number of arguments and the size of the argument string - ;;; data, or an error. - (result $error (expected (tuple $size $size) (error $errno))) - ) -) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx deleted file mode 100644 index a980529f8..000000000 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_clock.witx +++ /dev/null @@ -1,35 +0,0 @@ -;; WASI Clocks. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_clock - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, - ;;; return `errno::inval`. - ;;; Note: This is similar to `clock_getres` in POSIX. - (@interface func (export "res_get") - ;;; The clock for which to return the resolution. - (param $id $clockid) - ;;; The resolution of the clock. - (result $error (expected $timestamp (error $errno))) - ) - - ;;; Return the time value of a clock. - ;;; Note: This is similar to `clock_gettime` in POSIX. - (@interface func (export "time_get") - ;;; The clock for which to return the time. - (param $id $clockid) - ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp) - ;;; The time value of the clock. - (result $error (expected $timestamp (error $errno))) - ) -) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx deleted file mode 100644 index ef1c20b22..000000000 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ /dev/null @@ -1,27 +0,0 @@ -;; WASI Environment Variables. -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_environ - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `sizes_get`. - ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - (@interface func (export "get") - (param $environ (@witx pointer (@witx pointer (@witx char8)))) - (param $environ_buf (@witx pointer (@witx char8))) - (result $error (expected (error $errno))) - ) - - ;;; Return environment variable data sizes. - (@interface func (export "sizes_get") - ;;; Returns the number of environment variable arguments and the size of the - ;;; environment variable data. - (result $error (expected (tuple $size $size) (error $errno))) - ) -) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx deleted file mode 100644 index 979e9a333..000000000 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ /dev/null @@ -1,259 +0,0 @@ -;; WASI I/O. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_fd - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Provide file advisory information on a file descriptor. - ;;; Note: This is similar to `posix_fadvise` in POSIX. - (@interface func (export "advise") - (param $fd $fd) - ;;; The offset within the file to which the advisory applies. - (param $offset $filesize) - ;;; The length of the region to which the advisory applies. - (param $len $filesize) - ;;; The advice. - (param $advice $advice) - (result $error (expected (error $errno))) - ) - - ;;; Force the allocation of space in a file. - ;;; Note: This is similar to `posix_fallocate` in POSIX. - (@interface func (export "allocate") - (param $fd $fd) - ;;; The offset at which to start the allocation. - (param $offset $filesize) - ;;; The length of the area that is allocated. - (param $len $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Close a file descriptor. - ;;; Note: This is similar to `close` in POSIX. - (@interface func (export "close") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Synchronize the data of a file to disk. - ;;; Note: This is similar to `fdatasync` in POSIX. - (@interface func (export "datasync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Get the attributes of a file descriptor. - ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (@interface func (export "fdstat_get") - (param $fd $fd) - ;;; The buffer where the file descriptor's attributes are stored. - (result $error (expected $fdstat (error $errno))) - ) - - ;;; Adjust the flags associated with a file descriptor. - ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (@interface func (export "fdstat_set_flags") - (param $fd $fd) - ;;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights - (@interface func (export "fdstat_set_rights") - (param $fd $fd) - ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of an open file. - (@interface func (export "filestat_get") - (param $fd $fd) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;;; Note: This is similar to `ftruncate` in POSIX. - (@interface func (export "filestat_set_size") - (param $fd $fd) - ;;; The desired file size. - (param $size $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the timestamps of an open file or directory. - ;;; Note: This is similar to `futimens` in POSIX. - (@interface func (export "filestat_set_times") - (param $fd $fd) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Set the permissions of a file or directory. - ;;; - ;;; This sets the permissions associated with a file or directory in - ;;; a filesystem at the time it is called. The ability to actually access - ;;; a file or directory may depend on additional permissions not reflected - ;;; here. - ;;; - ;;; Note: This is similar `fchmod` in POSIX. - ;;; - ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; - ;;; implementations in POSIX environments are suggested to consult the - ;;; umask to determine which of the user/group/other flags to modify. - (@interface func (export "permissions_set") - (param $fd $fd) - ;;; The permissions associated with the file. - (param $permissions $permissions) - (result $error (expected (error $errno))) - ) - - ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in Linux (and other Unix-es). - (@interface func (export "pread") - (param $fd $fd) - ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_array) - ;;; The offset within the file at which to read. - (param $offset $filesize) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "prestat_get") - (param $fd $fd) - ;;; The buffer where the description is stored. - (result $error (expected $prestat (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "prestat_dir_name") - (param $fd $fd) - ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer (@witx char8))) - (param $path_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in Linux (and other Unix-es). - ;;; - ;;; Like Linux (and other Unix-es), any calls of `pwrite` (and other - ;;; functions to read or write) for a regular file by other threads in the - ;;; WASI process should not be interleaved while `pwrite` is executed. - (@interface func (export "pwrite") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The offset within the file at which to write. - (param $offset $filesize) - ;;; The number of bytes written. - (result $error (expected $size (error $errno))) - ) - - ;;; Read from a file descriptor. - ;;; Note: This is similar to `readv` in POSIX. - (@interface func (export "read") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_array) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Read directory entries from a directory. - ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a `dirent` object, - ;;; followed by `dirent::d_namlen` bytes holding the name of the directory - ;;; entry. - ;; - ;;; This function fills the output buffer as much as possible, potentially - ;;; truncating the last directory entry. This allows the caller to grow its - ;;; read buffer size in case it's too small to fit a single large directory - ;;; entry, or skip the oversized directory entry. - (@interface func (export "readdir") - (param $fd $fd) - ;;; The buffer where directory entries are stored - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The location within the directory to start reading - (param $cookie $dircookie) - ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $error (expected $size (error $errno))) - ) - - ;;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;;; Due to the strong focus on thread safety, this environment does not provide - ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;;; file descriptor with the same number could be allocated by a different - ;;; thread at the same time. - ;; - ;;; This function provides a way to atomically renumber file descriptors, which - ;;; would disappear if `dup2()` were to be removed entirely. - (@interface func (export "renumber") - (param $fd $fd) - ;;; The file descriptor to overwrite. - (param $to $fd) - (result $error (expected (error $errno))) - ) - - ;;; Move the offset of a file descriptor. - ;;; Note: This is similar to `lseek` in POSIX. - (@interface func (export "seek") - (param $fd $fd) - ;;; The number of bytes to move. - (param $offset $filedelta) - ;;; The base from which the offset is relative. - (param $whence $whence) - ;;; The new offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Synchronize the data and metadata of a file to disk. - ;;; Note: This is similar to `fsync` in POSIX. - (@interface func (export "sync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Return the current offset of a file descriptor. - ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (@interface func (export "tell") - (param $fd $fd) - ;;; The current offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Write to a file descriptor. - ;;; Note: This is similar to `writev` in POSIX. - ;;; - ;;; Like POSIX, any calls of `write` (and other functions to read or write) - ;;; for a regular file by other threads in the WASI process should not be - ;;; interleaved while `write` is executed. - (@interface func (export "write") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The number of bytes written. - (result $error (expected $size (error $errno))) - ) -) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx deleted file mode 100644 index 2901decb7..000000000 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ /dev/null @@ -1,181 +0,0 @@ -;; WASI Filesystem Path API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_path - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Create a directory. - ;;; Note: This is similar to `mkdirat` in POSIX. - (@interface func (export "create_directory") - (param $fd $fd) - ;;; The path at which to create the directory. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of a file or directory. - ;;; Note: This is similar to `stat` in POSIX. - (@interface func (export "filestat_get") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to inspect. - (param $path string) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the timestamps of a file or directory. - ;;; Note: This is similar to `utimensat` in POSIX. - (@interface func (export "filestat_set_times") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to operate on. - (param $path string) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Set the permissions of a file or directory. - ;;; - ;;; This sets the permissions associated with a file or directory in - ;;; a filesystem at the time it is called. The ability to actually access - ;;; a file or directory may depend on additional permissions not reflected - ;;; here. - ;;; - ;;; Note: This is similar to `fchmodat` in POSIX. - ;;; - ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; - ;;; implementations in POSIX environments are suggested to consult the - ;;; umask to determine which of the user/group/other flags to modify. - (@interface func (export "permissions_set") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path to a file to query. - (param $path string) - ;;; The permissions to associate with the file. - (param $permissions $permissions) - (result $error (expected (error $errno))) - ) - - ;;; Create a hard link. - ;;; Note: This is similar to `linkat` in POSIX. - (@interface func (export "link") - (param $old_fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags) - ;;; The source path from which to link. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path at which to create the hard link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Open a file or directory. - ;; - ;;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;;; file descriptor not currently open; it is randomized to prevent - ;;; applications from depending on making assumptions about indexes, since this - ;;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;;; guaranteed to be less than 2**31. - ;; - ;;; Note: This is similar to `openat` in POSIX. - (@interface func (export "open") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags) - ;;; The relative path of the file or directory to open, relative to the - ;;; `fd` directory. - (param $path string) - ;;; The method by which to open the file. - (param $oflags $oflags) - ;;; The initial rights of the newly created file descriptor. The - ;;; implementation is allowed to return a file descriptor with fewer rights - ;;; than specified, if and only if those rights do not apply to the type of - ;;; file being opened. - ;; - ;;; The *base* rights are rights that will apply to operations using the file - ;;; descriptor itself, while the *inheriting* rights are rights that apply to - ;;; file descriptors derived from it. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (param $fdflags $fdflags) - ;;; If a file is created, the filesystem permissions to associate with it. - (param $permissions $permissions) - ;;; The file descriptor of the file that has been opened. - (result $error (expected $fd (error $errno))) - ) - - ;;; Read the contents of a symbolic link. - ;;; Note: This is similar to `readlinkat` in POSIX. - (@interface func (export "readlink") - (param $fd $fd) - ;;; The path of the symbolic link from which to read. - (param $path string) - ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer (@witx char8))) - (param $buf_len $size) - ;;; The number of bytes placed in the buffer. - (result $error (expected $size (error $errno))) - ) - - ;;; Remove a directory. - ;;; Return `errno::notempty` if the directory is not empty. - ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (@interface func (export "remove_directory") - (param $fd $fd) - ;;; The path to a directory to remove. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Rename a file or directory. - ;;; Note: This is similar to `renameat` in POSIX. - (@interface func (export "rename") - (param $fd $fd) - ;;; The source path of the file or directory to rename. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Create a symbolic link. - ;;; Note: This is similar to `symlinkat` in POSIX. - (@interface func (export "symlink") - ;;; The contents of the symbolic link. - (param $old_path string) - (param $fd $fd) - ;;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Unlink a file. - ;;; Return `errno::isdir` if the path refers to a directory. - ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (@interface func (export "unlink_file") - (param $fd $fd) - ;;; The path to a file to unlink. - (param $path string) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx deleted file mode 100644 index 08da5f03a..000000000 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_poll.witx +++ /dev/null @@ -1,27 +0,0 @@ -;; WASI Poll API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_poll - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Concurrently poll for the occurrence of a set of events. - ;;; - ;;; If `nsubscriptions` is 0, returns `errno::inval`. - (@interface func (export "oneoff") - ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription)) - ;;; The events that have occurred. - (param $out (@witx pointer $event)) - ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size) - ;;; The number of events stored. - (result $error (expected $size (error $errno))) - ) -) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx deleted file mode 100644 index 0bd57682d..000000000 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_proc.witx +++ /dev/null @@ -1,22 +0,0 @@ -;; WASI Process API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_proc - ;;; Terminate the process normally. An exit code of `$exitcode::success` - ;;; reports successful completion of the program. An exit code of - ;;; `$exitcode::failure` or any other value less than 126 reports a - ;;; failure, and the value is provided to the environment. If a value - ;;; of 126 or greater is given, this function behaves as if it were - ;;; implemented by an `unreachable` instruction. - (@interface func (export "exit") - ;;; The exit code returned by the process. - (param $rval $exitcode) - (@witx noreturn) - ) -) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx deleted file mode 100644 index 4dc8e1a47..000000000 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_random.witx +++ /dev/null @@ -1,26 +0,0 @@ -;; WASI Random API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_random - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Write high-quality random data into a buffer. - ;;; This function blocks when the implementation is unable to immediately - ;;; provide sufficient high-quality random data. - ;;; This function may execute slowly, so when large mounts of random data are - ;;; required, it's advisable to use this function to seed a pseudo-random - ;;; number generator, rather than to provide the random data directly. - (@interface func (export "get") - ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sched.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sched.witx deleted file mode 100644 index 3b70856dc..000000000 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sched.witx +++ /dev/null @@ -1,16 +0,0 @@ -;; WASI Scheduler API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_sched - ;;; Temporarily yield execution of the calling thread. - ;;; Note: This is similar to `yield` in POSIX. - (@interface func (export "yield") - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sock.witx b/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sock.witx deleted file mode 100644 index a05b02ea6..000000000 --- a/proposals/filesystem/phases/ephemeral/witx/wasi_ephemeral_sock.witx +++ /dev/null @@ -1,48 +0,0 @@ -;; WASI Sockets. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_sock - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Receive a message from a socket. - ;;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;;; the data into multiple buffers in the manner of `readv`. - (@interface func (export "recv") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_array) - ;;; Message flags. - (param $ri_flags $riflags) - ;;; Number of bytes stored in ri_data and message flags. - (result $error (expected (tuple $size $roflags) (error $errno))) - ) - - ;;; Send a message on a socket. - ;;; Note: This is similar to `send` in POSIX, though it also supports writing - ;;; the data from multiple buffers in the manner of `writev`. - (@interface func (export "send") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_array) - ;;; Message flags. - (param $si_flags $siflags) - ;;; Number of bytes transmitted. - (result $error (expected $size (error $errno))) - ) - - ;;; Shut down socket send and receive channels. - ;;; Note: This is similar to `shutdown` in POSIX. - (@interface func (export "shutdown") - (param $fd $fd) - ;;; Which channels on the socket to shut down. - (param $how $sdflags) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/filesystem/phases/old/snapshot_0/docs.md b/proposals/filesystem/phases/old/snapshot_0/docs.md deleted file mode 100644 index 634e304b3..000000000 --- a/proposals/filesystem/phases/old/snapshot_0/docs.md +++ /dev/null @@ -1,2512 +0,0 @@ -# Types -## `size`: `u32` - -Size: 4 - -Alignment: 4 - -## `filesize`: `u64` -Non-negative file size or length of a region within a file. - -Size: 8 - -Alignment: 8 - -## `timestamp`: `u64` -Timestamp in nanoseconds. - -Size: 8 - -Alignment: 8 - -## `clockid`: `Variant` -Identifiers for clocks. - -Size: 4 - -Alignment: 4 - -### Variant cases -- `realtime` -The clock measuring real time. Time value zero corresponds with -1970-01-01T00:00:00Z. - -- `monotonic` -The store-wide monotonic clock, which is defined as a clock measuring -real time, whose value cannot be adjusted and which cannot have negative -clock jumps. The epoch of this clock is undefined. The absolute time -value of this clock therefore has no meaning. - -- `process_cputime_id` -The CPU-time clock associated with the current process. - -- `thread_cputime_id` -The CPU-time clock associated with the current thread. - -## `errno`: `Variant` -Error codes returned by functions. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX. - -Size: 2 - -Alignment: 2 - -### Variant cases -- `success` -No error occurred. System call completed successfully. - -- `2big` -Argument list too long. - -- `acces` -Permission denied. - -- `addrinuse` -Address in use. - -- `addrnotavail` -Address not available. - -- `afnosupport` -Address family not supported. - -- `again` -Resource unavailable, or operation would block. - -- `already` -Connection already in progress. - -- `badf` -Bad file descriptor. - -- `badmsg` -Bad message. - -- `busy` -Device or resource busy. - -- `canceled` -Operation canceled. - -- `child` -No child processes. - -- `connaborted` -Connection aborted. - -- `connrefused` -Connection refused. - -- `connreset` -Connection reset. - -- `deadlk` -Resource deadlock would occur. - -- `destaddrreq` -Destination address required. - -- `dom` -Mathematics argument out of domain of function. - -- `dquot` -Reserved. - -- `exist` -File exists. - -- `fault` -Bad address. - -- `fbig` -File too large. - -- `hostunreach` -Host is unreachable. - -- `idrm` -Identifier removed. - -- `ilseq` -Illegal byte sequence. - -- `inprogress` -Operation in progress. - -- `intr` -Interrupted function. - -- `inval` -Invalid argument. - -- `io` -I/O error. - -- `isconn` -Socket is connected. - -- `isdir` -Is a directory. - -- `loop` -Too many levels of symbolic links. - -- `mfile` -File descriptor value too large. - -- `mlink` -Too many links. - -- `msgsize` -Message too large. - -- `multihop` -Reserved. - -- `nametoolong` -Filename too long. - -- `netdown` -Network is down. - -- `netreset` -Connection aborted by network. - -- `netunreach` -Network unreachable. - -- `nfile` -Too many files open in system. - -- `nobufs` -No buffer space available. - -- `nodev` -No such device. - -- `noent` -No such file or directory. - -- `noexec` -Executable file format error. - -- `nolck` -No locks available. - -- `nolink` -Reserved. - -- `nomem` -Not enough space. - -- `nomsg` -No message of the desired type. - -- `noprotoopt` -Protocol not available. - -- `nospc` -No space left on device. - -- `nosys` -Function not supported. - -- `notconn` -The socket is not connected. - -- `notdir` -Not a directory or a symbolic link to a directory. - -- `notempty` -Directory not empty. - -- `notrecoverable` -State not recoverable. - -- `notsock` -Not a socket. - -- `notsup` -Not supported, or operation not supported on socket. - -- `notty` -Inappropriate I/O control operation. - -- `nxio` -No such device or address. - -- `overflow` -Value too large to be stored in data type. - -- `ownerdead` -Previous owner died. - -- `perm` -Operation not permitted. - -- `pipe` -Broken pipe. - -- `proto` -Protocol error. - -- `protonosupport` -Protocol not supported. - -- `prototype` -Protocol wrong type for socket. - -- `range` -Result too large. - -- `rofs` -Read-only file system. - -- `spipe` -Invalid seek. - -- `srch` -No such process. - -- `stale` -Reserved. - -- `timedout` -Connection timed out. - -- `txtbsy` -Text file busy. - -- `xdev` -Cross-device link. - -- `notcapable` -Extension: Capabilities insufficient. - -## `rights`: `Record` -File descriptor rights, determining which actions may be performed. - -Size: 8 - -Alignment: 8 - -### Record members -- `fd_datasync`: `bool` -The right to invoke [`fd_datasync`](#fd_datasync). -If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke -[`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). - -Bit: 0 - -- `fd_read`: `bool` -The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). - -Bit: 1 - -- `fd_seek`: `bool` -The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). - -Bit: 2 - -- `fd_fdstat_set_flags`: `bool` -The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). - -Bit: 3 - -- `fd_sync`: `bool` -The right to invoke [`fd_sync`](#fd_sync). -If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke -[`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - -Bit: 4 - -- `fd_tell`: `bool` -The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset -remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to -invoke [`fd_tell`](#fd_tell). - -Bit: 5 - -- `fd_write`: `bool` -The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). - -Bit: 6 - -- `fd_advise`: `bool` -The right to invoke [`fd_advise`](#fd_advise). - -Bit: 7 - -- `fd_allocate`: `bool` -The right to invoke [`fd_allocate`](#fd_allocate). - -Bit: 8 - -- `path_create_directory`: `bool` -The right to invoke [`path_create_directory`](#path_create_directory). - -Bit: 9 - -- `path_create_file`: `bool` -If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). - -Bit: 10 - -- `path_link_source`: `bool` -The right to invoke [`path_link`](#path_link) with the file descriptor as the -source directory. - -Bit: 11 - -- `path_link_target`: `bool` -The right to invoke [`path_link`](#path_link) with the file descriptor as the -target directory. - -Bit: 12 - -- `path_open`: `bool` -The right to invoke [`path_open`](#path_open). - -Bit: 13 - -- `fd_readdir`: `bool` -The right to invoke [`fd_readdir`](#fd_readdir). - -Bit: 14 - -- `path_readlink`: `bool` -The right to invoke [`path_readlink`](#path_readlink). - -Bit: 15 - -- `path_rename_source`: `bool` -The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. - -Bit: 16 - -- `path_rename_target`: `bool` -The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. - -Bit: 17 - -- `path_filestat_get`: `bool` -The right to invoke [`path_filestat_get`](#path_filestat_get). - -Bit: 18 - -- `path_filestat_set_size`: `bool` -The right to change a file's size (there is no `path_filestat_set_size`). -If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). - -Bit: 19 - -- `path_filestat_set_times`: `bool` -The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). - -Bit: 20 - -- `fd_filestat_get`: `bool` -The right to invoke [`fd_filestat_get`](#fd_filestat_get). - -Bit: 21 - -- `fd_filestat_set_size`: `bool` -The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). - -Bit: 22 - -- `fd_filestat_set_times`: `bool` -The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). - -Bit: 23 - -- `path_symlink`: `bool` -The right to invoke [`path_symlink`](#path_symlink). - -Bit: 24 - -- `path_remove_directory`: `bool` -The right to invoke [`path_remove_directory`](#path_remove_directory). - -Bit: 25 - -- `path_unlink_file`: `bool` -The right to invoke [`path_unlink_file`](#path_unlink_file). - -Bit: 26 - -- `poll_fd_readwrite`: `bool` -If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). -If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). - -Bit: 27 - -- `sock_shutdown`: `bool` -The right to invoke [`sock_shutdown`](#sock_shutdown). - -Bit: 28 - -## `fd`: `Handle` -A file descriptor handle. - -Size: 4 - -Alignment: 4 - -### Supertypes -## `iovec`: `Record` -A region of memory for scatter/gather reads. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `Pointer` -The address of the buffer to be filled. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be filled. - -Offset: 4 - -## `ciovec`: `Record` -A region of memory for scatter/gather writes. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `ConstPointer` -The address of the buffer to be written. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be written. - -Offset: 4 - -## `iovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `ciovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `filedelta`: `s64` -Relative offset within a file. - -Size: 8 - -Alignment: 8 - -## `whence`: `Variant` -The position relative to which to set the offset of the file descriptor. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `cur` -Seek relative to current position. - -- `end` -Seek relative to end-of-file. - -- `set` -Seek relative to start-of-file. - -## `dircookie`: `u64` -A reference to the offset of a directory entry. - -Size: 8 - -Alignment: 8 - -## `dirnamlen`: `u32` -The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent) struct. - -Size: 4 - -Alignment: 4 - -## `inode`: `u64` -File serial number that is unique within its file system. - -Size: 8 - -Alignment: 8 - -## `filetype`: `Variant` -The type of a file descriptor or file. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `unknown` -The type of the file descriptor or file is unknown or is different from any of the other types specified. - -- `block_device` -The file descriptor or file refers to a block device inode. - -- `character_device` -The file descriptor or file refers to a character device inode. - -- `directory` -The file descriptor or file refers to a directory inode. - -- `regular_file` -The file descriptor or file refers to a regular file inode. - -- `socket_dgram` -The file descriptor or file refers to a datagram socket. - -- `socket_stream` -The file descriptor or file refers to a byte-stream socket. - -- `symbolic_link` -The file refers to a symbolic link inode. - -## `dirent`: `Record` -A directory entry. - -Size: 24 - -Alignment: 8 - -### Record members -- `d_next`: [`dircookie`](#dircookie) -The offset of the next directory entry stored in this directory. - -Offset: 0 - -- `d_ino`: [`inode`](#inode) -The serial number of the file referred to by this directory entry. - -Offset: 8 - -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. - -Offset: 16 - -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. - -Offset: 20 - -## `advice`: `Variant` -File or memory access pattern advisory information. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `normal` -The application has no advice to give on its behavior with respect to the specified data. - -- `sequential` -The application expects to access the specified data sequentially from lower offsets to higher offsets. - -- `random` -The application expects to access the specified data in a random order. - -- `willneed` -The application expects to access the specified data in the near future. - -- `dontneed` -The application expects that it will not access the specified data in the near future. - -- `noreuse` -The application expects to access the specified data once and then not reuse it thereafter. - -## `fdflags`: `Record` -File descriptor flags. - -Size: 2 - -Alignment: 2 - -### Record members -- `append`: `bool` -Append mode: Data written to the file is always appended to the file's end. - -Bit: 0 - -- `dsync`: `bool` -Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - -Bit: 1 - -- `nonblock`: `bool` -Non-blocking mode. - -Bit: 2 - -- `rsync`: `bool` -Synchronized read I/O operations. - -Bit: 3 - -- `sync`: `bool` -Write according to synchronized I/O file integrity completion. In -addition to synchronizing the data stored in the file, the implementation -may also synchronously update the file's metadata. - -Bit: 4 - -## `fdstat`: `Record` -File descriptor attributes. - -Size: 24 - -Alignment: 8 - -### Record members -- `fs_filetype`: [`filetype`](#filetype) -File type. - -Offset: 0 - -- `fs_flags`: [`fdflags`](#fdflags) -File descriptor flags. - -Offset: 2 - -- `fs_rights_base`: [`rights`](#rights) -Rights that apply to this file descriptor. - -Offset: 8 - -- `fs_rights_inheriting`: [`rights`](#rights) -Maximum set of rights that may be installed on new file descriptors that -are created through this file descriptor, e.g., through [`path_open`](#path_open). - -Offset: 16 - -## `device`: `u64` -Identifier for a device containing a file system. Can be used in combination -with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. - -Size: 8 - -Alignment: 8 - -## `fstflags`: `Record` -Which file time attributes to adjust. - -Size: 2 - -Alignment: 2 - -### Record members -- `atim`: `bool` -Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - -Bit: 0 - -- `atim_now`: `bool` -Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 1 - -- `mtim`: `bool` -Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - -Bit: 2 - -- `mtim_now`: `bool` -Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 3 - -## `lookupflags`: `Record` -Flags determining the method of how paths are resolved. - -Size: 4 - -Alignment: 4 - -### Record members -- `symlink_follow`: `bool` -As long as the resolved path corresponds to a symbolic link, it is expanded. - -Bit: 0 - -## `oflags`: `Record` -Open flags used by [`path_open`](#path_open). - -Size: 2 - -Alignment: 2 - -### Record members -- `creat`: `bool` -Create file if it does not exist. - -Bit: 0 - -- `directory`: `bool` -Fail if not a directory. - -Bit: 1 - -- `excl`: `bool` -Fail if file already exists. - -Bit: 2 - -- `trunc`: `bool` -Truncate file to size 0. - -Bit: 3 - -## `linkcount`: `u32` -Number of hard links to an inode. - -Size: 4 - -Alignment: 4 - -## `filestat`: `Record` -File attributes. - -Size: 56 - -Alignment: 8 - -### Record members -- `dev`: [`device`](#device) -Device ID of device containing the file. - -Offset: 0 - -- `ino`: [`inode`](#inode) -File serial number. - -Offset: 8 - -- `filetype`: [`filetype`](#filetype) -File type. - -Offset: 16 - -- `nlink`: [`linkcount`](#linkcount) -Number of hard links to the file. - -Offset: 20 - -- `size`: [`filesize`](#filesize) -For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - -Offset: 24 - -- `atim`: [`timestamp`](#timestamp) -Last data access timestamp. - -Offset: 32 - -- `mtim`: [`timestamp`](#timestamp) -Last data modification timestamp. - -Offset: 40 - -- `ctim`: [`timestamp`](#timestamp) -Last file status change timestamp. - -Offset: 48 - -## `userdata`: `u64` -User-provided value that may be attached to objects that is retained when -extracted from the implementation. - -Size: 8 - -Alignment: 8 - -## `eventtype`: `Variant` -Type of a subscription to an event or its occurrence. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `clock` -The time value of clock [`subscription_clock::id`](#subscription_clock.id) has -reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - -- `fd_read` -File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has data -available for reading. This event always triggers for regular files. - -- `fd_write` -File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity -available for writing. This event always triggers for regular files. - -## `eventrwflags`: `Record` -The state of the file descriptor subscribed to with -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 2 - -Alignment: 2 - -### Record members -- `fd_readwrite_hangup`: `bool` -The peer of this socket has closed or disconnected. - -Bit: 0 - -## `event_fd_readwrite`: `Record` -The contents of an [`event`](#event) for the [`eventtype::fd_read`](#eventtype.fd_read) and -[`eventtype::fd_write`](#eventtype.fd_write) variants - -Size: 16 - -Alignment: 8 - -### Record members -- `nbytes`: [`filesize`](#filesize) -The number of bytes available for reading or writing. - -Offset: 0 - -- `flags`: [`eventrwflags`](#eventrwflags) -The state of the file descriptor. - -Offset: 8 - -## `event`: `Record` -An event that occurred. - -Size: 32 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). - -Offset: 0 - -- `error`: [`errno`](#errno) -If non-zero, an error that occurred while processing the subscription request. - -Offset: 8 - -- `type`: [`eventtype`](#eventtype) -The type of event that occured - -Offset: 10 - -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. - -Offset: 16 - -## `subclockflags`: `Record` -Flags determining how to interpret the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout). - -Size: 2 - -Alignment: 2 - -### Record members -- `subscription_clock_abstime`: `bool` -If set, treat the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock -[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp -provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the -current time value of clock [`subscription_clock::id`](#subscription_clock.id). - -Bit: 0 - -## `subscription_clock`: `Record` -The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). - -Size: 40 - -Alignment: 8 - -### Record members -- `identifier`: [`userdata`](#userdata) -The user-defined unique identifier of the clock. - -Offset: 0 - -- `id`: [`clockid`](#clockid) -The clock against which to compare the timestamp. - -Offset: 8 - -- `timeout`: [`timestamp`](#timestamp) -The absolute or relative timestamp. - -Offset: 16 - -- `precision`: [`timestamp`](#timestamp) -The amount of time that the implementation may wait additionally -to coalesce with other events. - -Offset: 24 - -- `flags`: [`subclockflags`](#subclockflags) -Flags specifying whether the timeout is absolute or relative - -Offset: 32 - -## `subscription_fd_readwrite`: `Record` -The contents of a [`subscription`](#subscription) when the variant is -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 4 - -Alignment: 4 - -### Record members -- `file_descriptor`: [`fd`](#fd) -The file descriptor on which to wait for it to become ready for reading or writing. - -Offset: 0 - -## `subscription_u`: `Variant` -The contents of a [`subscription`](#subscription). - -Size: 48 - -Alignment: 8 - -### Variant Layout -- size: 48 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock`: [`subscription_clock`](#subscription_clock) - -- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -## `subscription`: `Record` -Subscription to an event. - -Size: 56 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that is attached to the subscription in the -implementation and returned through [`event::userdata`](#event.userdata). - -Offset: 0 - -- `u`: [`subscription_u`](#subscription_u) -The type of the event to which to subscribe. - -Offset: 8 - -## `exitcode`: `u32` -Exit code generated by a process when exiting. - -Size: 4 - -Alignment: 4 - -## `signal`: `Variant` -Signal condition. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `none` -No signal. Note that POSIX has special semantics for `kill(pid, 0)`, -so this value is reserved. - -- `hup` -Hangup. -Action: Terminates the process. - -- `int` -Terminate interrupt signal. -Action: Terminates the process. - -- `quit` -Terminal quit signal. -Action: Terminates the process. - -- `ill` -Illegal instruction. -Action: Terminates the process. - -- `trap` -Trace/breakpoint trap. -Action: Terminates the process. - -- `abrt` -Process abort signal. -Action: Terminates the process. - -- `bus` -Access to an undefined portion of a memory object. -Action: Terminates the process. - -- `fpe` -Erroneous arithmetic operation. -Action: Terminates the process. - -- `kill` -Kill. -Action: Terminates the process. - -- `usr1` -User-defined signal 1. -Action: Terminates the process. - -- `segv` -Invalid memory reference. -Action: Terminates the process. - -- `usr2` -User-defined signal 2. -Action: Terminates the process. - -- `pipe` -Write on a pipe with no one to read it. -Action: Ignored. - -- `alrm` -Alarm clock. -Action: Terminates the process. - -- `term` -Termination signal. -Action: Terminates the process. - -- `chld` -Child process terminated, stopped, or continued. -Action: Ignored. - -- `cont` -Continue executing, if stopped. -Action: Continues executing, if stopped. - -- `stop` -Stop executing. -Action: Stops executing. - -- `tstp` -Terminal stop signal. -Action: Stops executing. - -- `ttin` -Background process attempting read. -Action: Stops executing. - -- `ttou` -Background process attempting write. -Action: Stops executing. - -- `urg` -High bandwidth data is available at a socket. -Action: Ignored. - -- `xcpu` -CPU time limit exceeded. -Action: Terminates the process. - -- `xfsz` -File size limit exceeded. -Action: Terminates the process. - -- `vtalrm` -Virtual timer expired. -Action: Terminates the process. - -- `prof` -Profiling timer expired. -Action: Terminates the process. - -- `winch` -Window changed. -Action: Ignored. - -- `poll` -I/O possible. -Action: Terminates the process. - -- `pwr` -Power failure. -Action: Terminates the process. - -- `sys` -Bad system call. -Action: Terminates the process. - -## `riflags`: `Record` -Flags provided to [`sock_recv`](#sock_recv). - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_peek`: `bool` -Returns the message without removing it from the socket's receive queue. - -Bit: 0 - -- `recv_waitall`: `bool` -On byte-stream sockets, block until the full amount of data can be returned. - -Bit: 1 - -## `roflags`: `Record` -Flags returned by [`sock_recv`](#sock_recv). - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_data_truncated`: `bool` -Returned by [`sock_recv`](#sock_recv): Message data has been truncated. - -Bit: 0 - -## `siflags`: `u16` -Flags provided to [`sock_send`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Size: 2 - -Alignment: 2 - -## `sdflags`: `Record` -Which channels on a socket to shut down. - -Size: 1 - -Alignment: 1 - -### Record members -- `rd`: `bool` -Disables further receive operations. - -Bit: 0 - -- `wr`: `bool` -Disables further send operations. - -Bit: 1 - -## `preopentype`: `Variant` -Identifiers for preopened capabilities. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `dir` -A pre-opened directory. - -## `prestat_dir`: `Record` -The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). - -Size: 4 - -Alignment: 4 - -### Record members -- `pr_name_len`: [`size`](#size) -The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). - -Offset: 0 - -## `prestat`: `Variant` -Information about a pre-opened capability. - -Size: 8 - -Alignment: 4 - -### Variant Layout -- size: 8 -- align: 4 -- tag_size: 1 -### Variant cases -- `dir`: [`prestat_dir`](#prestat_dir) - -# Modules -## wasi_unstable -### Imports -#### Memory -### Functions - ---- - -#### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` -Read command-line argument data. -The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get). -Each argument is expected to be `\0` terminated. - -##### Params -- `argv`: `Pointer>` - -- `argv_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `args_sizes_get() -> Result<(size, size), errno>` -Return command-line argument data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of arguments and the size of the argument string -data, or an error. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` -Read environment variable data. -The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). -Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - -##### Params -- `environ`: `Pointer>` - -- `environ_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `environ_sizes_get() -> Result<(size, size), errno>` -Return environment variable data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of environment variable arguments and the size of the -environment variable data. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `clock_res_get(id: clockid) -> Result` -Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return -[`errno::inval`](#errno.inval). -Note: This is similar to `clock_getres` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the resolution. - -##### Results -- `error`: `Result` -The resolution of the clock, or an error if one happened. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `clock_time_get(id: clockid, precision: timestamp) -> Result` -Return the time value of a clock. -Note: This is similar to `clock_gettime` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the time. - -- `precision`: [`timestamp`](#timestamp) -The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - -##### Results -- `error`: `Result` -The time value of the clock. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` -Provide file advisory information on a file descriptor. -Note: This is similar to `posix_fadvise` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset within the file to which the advisory applies. - -- `len`: [`filesize`](#filesize) -The length of the region to which the advisory applies. - -- `advice`: [`advice`](#advice) -The advice. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` -Force the allocation of space in a file. -Note: This is similar to `posix_fallocate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset at which to start the allocation. - -- `len`: [`filesize`](#filesize) -The length of the area that is allocated. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_close(fd: fd) -> Result<(), errno>` -Close a file descriptor. -Note: This is similar to `close` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_datasync(fd: fd) -> Result<(), errno>` -Synchronize the data of a file to disk. -Note: This is similar to `fdatasync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_get(fd: fd) -> Result` -Get the attributes of a file descriptor. -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file descriptor's attributes are stored. - -###### Variant Layout -- size: 32 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`fdstat`](#fdstat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` -Adjust the flags associated with a file descriptor. -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`fdflags`](#fdflags) -The desired values of the file descriptor flags. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` -Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights - -##### Params -- `fd`: [`fd`](#fd) - -- `fs_rights_base`: [`rights`](#rights) -The desired rights of the file descriptor. - -- `fs_rights_inheriting`: [`rights`](#rights) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_get(fd: fd) -> Result` -Return the attributes of an open file. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 64 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` -Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. -Note: This is similar to `ftruncate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `size`: [`filesize`](#filesize) -The desired file size. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of an open file or directory. -Note: This is similar to `futimens` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` -Read from a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `preadv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors in which to store data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to read. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_prestat_get(fd: fd) -> Result` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the description is stored. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`prestat`](#prestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `Pointer` -A buffer into which to write the preopened directory name. - -- `path_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` -Write to a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `pwritev` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to write. - -##### Results -- `error`: `Result` -The number of bytes written. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_read(fd: fd, iovs: iovec_array) -> Result` -Read from a file descriptor. -Note: This is similar to `readv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` -Read directory entries from a directory. -When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a [`dirent`](#dirent) object, -followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory -entry. -This function fills the output buffer as much as possible, potentially -truncating the last directory entry. This allows the caller to grow its -read buffer size in case it's too small to fit a single large directory -entry, or skip the oversized directory entry. - -##### Params -- `fd`: [`fd`](#fd) - -- `buf`: `Pointer` -The buffer where directory entries are stored - -- `buf_len`: [`size`](#size) - -- `cookie`: [`dircookie`](#dircookie) -The location within the directory to start reading - -##### Results -- `error`: `Result` -The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_renumber(fd: fd, to: fd) -> Result<(), errno>` -Atomically replace a file descriptor by renumbering another file descriptor. -Due to the strong focus on thread safety, this environment does not provide -a mechanism to duplicate or renumber a file descriptor to an arbitrary -number, like `dup2()`. This would be prone to race conditions, as an actual -file descriptor with the same number could be allocated by a different -thread at the same time. -This function provides a way to atomically renumber file descriptors, which -would disappear if `dup2()` were to be removed entirely. - -##### Params -- `fd`: [`fd`](#fd) - -- `to`: [`fd`](#fd) -The file descriptor to overwrite. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> Result` -Move the offset of a file descriptor. -Note: This is similar to `lseek` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filedelta`](#filedelta) -The number of bytes to move. - -- `whence`: [`whence`](#whence) -The base from which the offset is relative. - -##### Results -- `error`: `Result` -The new offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_sync(fd: fd) -> Result<(), errno>` -Synchronize the data and metadata of a file to disk. -Note: This is similar to `fsync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_tell(fd: fd) -> Result` -Return the current offset of a file descriptor. -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The current offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_write(fd: fd, iovs: ciovec_array) -> Result` -Write to a file descriptor. -Note: This is similar to `writev` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -##### Results -- `error`: `Result` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_create_directory(fd: fd, path: string) -> Result<(), errno>` -Create a directory. -Note: This is similar to `mkdirat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path at which to create the directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` -Return the attributes of a file or directory. -Note: This is similar to `stat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to inspect. - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 64 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of a file or directory. -Note: This is similar to `utimensat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to operate on. - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Create a hard link. -Note: This is similar to `linkat` in POSIX. - -##### Params -- `old_fd`: [`fd`](#fd) - -- `old_flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `old_path`: `string` -The source path from which to link. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path at which to create the hard link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> Result` -Open a file or directory. -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since this -is error-prone in multi-threaded contexts. The returned file descriptor is -guaranteed to be less than 2**31. -Note: This is similar to `openat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `dirflags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The relative path of the file or directory to open, relative to the -[`path_open::fd`](#path_open.fd) directory. - -- `oflags`: [`oflags`](#oflags) -The method by which to open the file. - -- `fs_rights_base`: [`rights`](#rights) -The initial rights of the newly created file descriptor. The -implementation is allowed to return a file descriptor with fewer rights -than specified, if and only if those rights do not apply to the type of -file being opened. -The *base* rights are rights that will apply to operations using the file -descriptor itself, while the *inheriting* rights are rights that apply to -file descriptors derived from it. - -- `fs_rights_inheriting`: [`rights`](#rights) - -- `fdflags`: [`fdflags`](#fdflags) - -##### Results -- `error`: `Result` -The file descriptor of the file that has been opened. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`fd`](#fd) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` -Read the contents of a symbolic link. -Note: This is similar to `readlinkat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path of the symbolic link from which to read. - -- `buf`: `Pointer` -The buffer to which to write the contents of the symbolic link. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result` -The number of bytes placed in the buffer. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_remove_directory(fd: fd, path: string) -> Result<(), errno>` -Remove a directory. -Return [`errno::notempty`](#errno.notempty) if the directory is not empty. -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a directory to remove. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Rename a file or directory. -Note: This is similar to `renameat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `old_path`: `string` -The source path of the file or directory to rename. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path to which to rename the file or directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` -Create a symbolic link. -Note: This is similar to `symlinkat` in POSIX. - -##### Params -- `old_path`: `string` -The contents of the symbolic link. - -- `fd`: [`fd`](#fd) - -- `new_path`: `string` -The destination path at which to create the symbolic link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_unlink_file(fd: fd, path: string) -> Result<(), errno>` -Unlink a file. -Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a file to unlink. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` -Concurrently poll for the occurrence of a set of events. - -##### Params -- `in`: `ConstPointer` -The events to which to subscribe. - -- `out`: `Pointer` -The events that have occurred. - -- `nsubscriptions`: [`size`](#size) -Both the number of subscriptions and events. - -##### Results -- `error`: `Result` -The number of events stored. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `proc_exit(rval: exitcode)` -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -##### Params -- `rval`: [`exitcode`](#exitcode) -The exit code returned by the process. - -##### Results - ---- - -#### `proc_raise(sig: signal) -> Result<(), errno>` -Send a signal to the process of the calling thread. -Note: This is similar to `raise` in POSIX. - -##### Params -- `sig`: [`signal`](#signal) -The signal condition to trigger. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sched_yield() -> Result<(), errno>` -Temporarily yield execution of the calling thread. -Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. - -##### Params -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `random_get(buf: Pointer, buf_len: size) -> Result<(), errno>` -Write high-quality random data into a buffer. -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. -This function may execute slowly, so when large mounts of random data are -required, it's advisable to use this function to seed a pseudo-random -number generator, rather than to provide the random data directly. - -##### Params -- `buf`: `Pointer` -The buffer to fill with random data. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` -Receive a message from a socket. -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -##### Params -- `fd`: [`fd`](#fd) - -- `ri_data`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -- `ri_flags`: [`riflags`](#riflags) -Message flags. - -##### Results -- `error`: `Result<(size, roflags), errno>` -Number of bytes stored in ri_data and message flags. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, roflags)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`roflags`](#roflags) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` -Send a message on a socket. -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -##### Params -- `fd`: [`fd`](#fd) - -- `si_data`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors to which to retrieve data - -- `si_flags`: [`siflags`](#siflags) -Message flags. - -##### Results -- `error`: `Result` -Number of bytes transmitted. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_shutdown(fd: fd, how: sdflags) -> Result<(), errno>` -Shut down socket send and receive channels. -Note: This is similar to `shutdown` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `how`: [`sdflags`](#sdflags) -Which channels on the socket to shut down. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx b/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx deleted file mode 100644 index f4ba78802..000000000 --- a/proposals/filesystem/phases/old/snapshot_0/witx/typenames.witx +++ /dev/null @@ -1,746 +0,0 @@ -;; Type names used by low-level WASI interfaces. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/main/docs/witx.md) -;; for an explanation of what that means. - -(typename $size u32) - -;;; Non-negative file size or length of a region within a file. -(typename $filesize u64) - -;;; Timestamp in nanoseconds. -(typename $timestamp u64) - -;;; Identifiers for clocks. -(typename $clockid - (enum (@witx tag u32) - ;;; The clock measuring real time. Time value zero corresponds with - ;;; 1970-01-01T00:00:00Z. - $realtime - ;;; The store-wide monotonic clock, which is defined as a clock measuring - ;;; real time, whose value cannot be adjusted and which cannot have negative - ;;; clock jumps. The epoch of this clock is undefined. The absolute time - ;;; value of this clock therefore has no meaning. - $monotonic - ;;; The CPU-time clock associated with the current process. - $process_cputime_id - ;;; The CPU-time clock associated with the current thread. - $thread_cputime_id - ) -) - -;;; Error codes returned by functions. -;;; Not all of these error codes are returned by the functions provided by this -;;; API; some are used in higher-level library layers, and others are provided -;;; merely for alignment with POSIX. -(typename $errno - (enum (@witx tag u16) - ;;; No error occurred. System call completed successfully. - $success - ;;; Argument list too long. - $2big - ;;; Permission denied. - $acces - ;;; Address in use. - $addrinuse - ;;; Address not available. - $addrnotavail - ;;; Address family not supported. - $afnosupport - ;;; Resource unavailable, or operation would block. - $again - ;;; Connection already in progress. - $already - ;;; Bad file descriptor. - $badf - ;;; Bad message. - $badmsg - ;;; Device or resource busy. - $busy - ;;; Operation canceled. - $canceled - ;;; No child processes. - $child - ;;; Connection aborted. - $connaborted - ;;; Connection refused. - $connrefused - ;;; Connection reset. - $connreset - ;;; Resource deadlock would occur. - $deadlk - ;;; Destination address required. - $destaddrreq - ;;; Mathematics argument out of domain of function. - $dom - ;;; Reserved. - $dquot - ;;; File exists. - $exist - ;;; Bad address. - $fault - ;;; File too large. - $fbig - ;;; Host is unreachable. - $hostunreach - ;;; Identifier removed. - $idrm - ;;; Illegal byte sequence. - $ilseq - ;;; Operation in progress. - $inprogress - ;;; Interrupted function. - $intr - ;;; Invalid argument. - $inval - ;;; I/O error. - $io - ;;; Socket is connected. - $isconn - ;;; Is a directory. - $isdir - ;;; Too many levels of symbolic links. - $loop - ;;; File descriptor value too large. - $mfile - ;;; Too many links. - $mlink - ;;; Message too large. - $msgsize - ;;; Reserved. - $multihop - ;;; Filename too long. - $nametoolong - ;;; Network is down. - $netdown - ;;; Connection aborted by network. - $netreset - ;;; Network unreachable. - $netunreach - ;;; Too many files open in system. - $nfile - ;;; No buffer space available. - $nobufs - ;;; No such device. - $nodev - ;;; No such file or directory. - $noent - ;;; Executable file format error. - $noexec - ;;; No locks available. - $nolck - ;;; Reserved. - $nolink - ;;; Not enough space. - $nomem - ;;; No message of the desired type. - $nomsg - ;;; Protocol not available. - $noprotoopt - ;;; No space left on device. - $nospc - ;;; Function not supported. - $nosys - ;;; The socket is not connected. - $notconn - ;;; Not a directory or a symbolic link to a directory. - $notdir - ;;; Directory not empty. - $notempty - ;;; State not recoverable. - $notrecoverable - ;;; Not a socket. - $notsock - ;;; Not supported, or operation not supported on socket. - $notsup - ;;; Inappropriate I/O control operation. - $notty - ;;; No such device or address. - $nxio - ;;; Value too large to be stored in data type. - $overflow - ;;; Previous owner died. - $ownerdead - ;;; Operation not permitted. - $perm - ;;; Broken pipe. - $pipe - ;;; Protocol error. - $proto - ;;; Protocol not supported. - $protonosupport - ;;; Protocol wrong type for socket. - $prototype - ;;; Result too large. - $range - ;;; Read-only file system. - $rofs - ;;; Invalid seek. - $spipe - ;;; No such process. - $srch - ;;; Reserved. - $stale - ;;; Connection timed out. - $timedout - ;;; Text file busy. - $txtbsy - ;;; Cross-device link. - $xdev - ;;; Extension: Capabilities insufficient. - $notcapable - ) -) - -;;; File descriptor rights, determining which actions may be performed. -(typename $rights - (flags (@witx repr u64) - ;;; The right to invoke `fd_datasync`. - ;; - ;;; If `rights::path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::dsync`. - $fd_datasync - ;;; The right to invoke `fd_read` and `sock_recv`. - ;; - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. - $fd_read - ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. - $fd_seek - ;;; The right to invoke `fd_fdstat_set_flags`. - $fd_fdstat_set_flags - ;;; The right to invoke `fd_sync`. - ;; - ;;; If `rights::path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. - $fd_sync - ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to - ;;; invoke `fd_tell`. - $fd_tell - ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. - $fd_write - ;;; The right to invoke `fd_advise`. - $fd_advise - ;;; The right to invoke `fd_allocate`. - $fd_allocate - ;;; The right to invoke `path_create_directory`. - $path_create_directory - ;;; If `rights::path_open` is set, the right to invoke `path_open` with `oflags::creat`. - $path_create_file - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; source directory. - $path_link_source - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; target directory. - $path_link_target - ;;; The right to invoke `path_open`. - $path_open - ;;; The right to invoke `fd_readdir`. - $fd_readdir - ;;; The right to invoke `path_readlink`. - $path_readlink - ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $path_rename_source - ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $path_rename_target - ;;; The right to invoke `path_filestat_get`. - $path_filestat_get - ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `rights::path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. - $path_filestat_set_size - ;;; The right to invoke `path_filestat_set_times`. - $path_filestat_set_times - ;;; The right to invoke `fd_filestat_get`. - $fd_filestat_get - ;;; The right to invoke `fd_filestat_set_size`. - $fd_filestat_set_size - ;;; The right to invoke `fd_filestat_set_times`. - $fd_filestat_set_times - ;;; The right to invoke `path_symlink`. - $path_symlink - ;;; The right to invoke `path_remove_directory`. - $path_remove_directory - ;;; The right to invoke `path_unlink_file`. - $path_unlink_file - ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. - ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. - $poll_fd_readwrite - ;;; The right to invoke `sock_shutdown`. - $sock_shutdown - ) -) - -;;; A file descriptor handle. -(typename $fd (handle)) - -;;; A region of memory for scatter/gather reads. -(typename $iovec - (record - ;;; The address of the buffer to be filled. - (field $buf (@witx pointer u8)) - ;;; The length of the buffer to be filled. - (field $buf_len $size) - ) -) - -;;; A region of memory for scatter/gather writes. -(typename $ciovec - (record - ;;; The address of the buffer to be written. - (field $buf (@witx const_pointer u8)) - ;;; The length of the buffer to be written. - (field $buf_len $size) - ) -) - -(typename $iovec_array (list $iovec)) -(typename $ciovec_array (list $ciovec)) - -;;; Relative offset within a file. -(typename $filedelta s64) - -;;; The position relative to which to set the offset of the file descriptor. -(typename $whence - (enum (@witx tag u8) - ;;; Seek relative to current position. - $cur - ;;; Seek relative to end-of-file. - $end - ;;; Seek relative to start-of-file. - $set - ) -) - -;;; A reference to the offset of a directory entry. -(typename $dircookie u64) - -;;; The type for the `dirent::d_namlen` field of `dirent` struct. -(typename $dirnamlen u32) - -;;; File serial number that is unique within its file system. -(typename $inode u64) - -;;; The type of a file descriptor or file. -(typename $filetype - (enum (@witx tag u8) - ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $unknown - ;;; The file descriptor or file refers to a block device inode. - $block_device - ;;; The file descriptor or file refers to a character device inode. - $character_device - ;;; The file descriptor or file refers to a directory inode. - $directory - ;;; The file descriptor or file refers to a regular file inode. - $regular_file - ;;; The file descriptor or file refers to a datagram socket. - $socket_dgram - ;;; The file descriptor or file refers to a byte-stream socket. - $socket_stream - ;;; The file refers to a symbolic link inode. - $symbolic_link - ) -) - -;;; A directory entry. -(typename $dirent - (record - ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie) - ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) - ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype) - ) -) - -;;; File or memory access pattern advisory information. -(typename $advice - (enum (@witx tag u8) - ;;; The application has no advice to give on its behavior with respect to the specified data. - $normal - ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $sequential - ;;; The application expects to access the specified data in a random order. - $random - ;;; The application expects to access the specified data in the near future. - $willneed - ;;; The application expects that it will not access the specified data in the near future. - $dontneed - ;;; The application expects to access the specified data once and then not reuse it thereafter. - $noreuse - ) -) - -;;; File descriptor flags. -(typename $fdflags - (flags (@witx repr u16) - ;;; Append mode: Data written to the file is always appended to the file's end. - $append - ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $dsync - ;;; Non-blocking mode. - $nonblock - ;;; Synchronized read I/O operations. - $rsync - ;;; Write according to synchronized I/O file integrity completion. In - ;;; addition to synchronizing the data stored in the file, the implementation - ;;; may also synchronously update the file's metadata. - $sync - ) -) - -;;; File descriptor attributes. -(typename $fdstat - (record - ;;; File type. - (field $fs_filetype $filetype) - ;;; File descriptor flags. - (field $fs_flags $fdflags) - ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights) - ;;; Maximum set of rights that may be installed on new file descriptors that - ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights) - ) -) - -;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode` to uniquely identify a file or directory in the filesystem. -(typename $device u64) - -;;; Which file time attributes to adjust. -(typename $fstflags - (flags (@witx repr u16) - ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. - $atim - ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. - $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. - $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. - $mtim_now - ) -) - -;;; Flags determining the method of how paths are resolved. -(typename $lookupflags - (flags (@witx repr u32) - ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $symlink_follow - ) -) - -;;; Open flags used by `path_open`. -(typename $oflags - (flags (@witx repr u16) - ;;; Create file if it does not exist. - $creat - ;;; Fail if not a directory. - $directory - ;;; Fail if file already exists. - $excl - ;;; Truncate file to size 0. - $trunc - ) -) - -;;; Number of hard links to an inode. -(typename $linkcount u32) - -;;; File attributes. -(typename $filestat - (record - ;;; Device ID of device containing the file. - (field $dev $device) - ;;; File serial number. - (field $ino $inode) - ;;; File type. - (field $filetype $filetype) - ;;; Number of hard links to the file. - (field $nlink $linkcount) - ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $size $filesize) - ;;; Last data access timestamp. - (field $atim $timestamp) - ;;; Last data modification timestamp. - (field $mtim $timestamp) - ;;; Last file status change timestamp. - (field $ctim $timestamp) - ) -) - -;;; User-provided value that may be attached to objects that is retained when -;;; extracted from the implementation. -(typename $userdata u64) - -;;; Type of a subscription to an event or its occurrence. -(typename $eventtype - (enum (@witx tag u8) - ;;; The time value of clock `subscription_clock::id` has - ;;; reached timestamp `subscription_clock::timeout`. - $clock - ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has data - ;;; available for reading. This event always triggers for regular files. - $fd_read - ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has capacity - ;;; available for writing. This event always triggers for regular files. - $fd_write - ) -) - -;;; The state of the file descriptor subscribed to with -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $eventrwflags - (flags (@witx repr u16) - ;;; The peer of this socket has closed or disconnected. - $fd_readwrite_hangup - ) -) - -;;; The contents of an `event` for the `eventtype::fd_read` and -;;; `eventtype::fd_write` variants -(typename $event_fd_readwrite - (record - ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize) - ;;; The state of the file descriptor. - (field $flags $eventrwflags) - ) -) - -;;; An event that occurred. -(typename $event - (record - ;;; User-provided value that got attached to `subscription::userdata`. - (field $userdata $userdata) - ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno) - ;;; The type of event that occured - (field $type $eventtype) - ;;; The contents of the event, if it is an `eventtype::fd_read` or - ;;; `eventtype::fd_write`. `eventtype::clock` events ignore this field. - (field $fd_readwrite $event_fd_readwrite) - ) -) - -;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_clock::timeout`. -(typename $subclockflags - (flags (@witx repr u16) - ;;; If set, treat the timestamp provided in - ;;; `subscription_clock::timeout` as an absolute timestamp of clock - ;;; `subscription_clock::id`. If clear, treat the timestamp - ;;; provided in `subscription_clock::timeout` relative to the - ;;; current time value of clock `subscription_clock::id`. - $subscription_clock_abstime - ) -) - -;;; The contents of a `subscription` when type is `eventtype::clock`. -(typename $subscription_clock - (record - ;;; The user-defined unique identifier of the clock. - (field $identifier $userdata) - ;;; The clock against which to compare the timestamp. - (field $id $clockid) - ;;; The absolute or relative timestamp. - (field $timeout $timestamp) - ;;; The amount of time that the implementation may wait additionally - ;;; to coalesce with other events. - (field $precision $timestamp) - ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags) - ) -) - -;;; The contents of a `subscription` when the variant is -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $subscription_fd_readwrite - (record - ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd) - ) -) - -;;; The contents of a `subscription`. -(typename $subscription_u - (union (@witx tag $eventtype) - $subscription_clock - $subscription_fd_readwrite - $subscription_fd_readwrite - ) -) - -;;; Subscription to an event. -(typename $subscription - (record - ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event::userdata`. - (field $userdata $userdata) - ;;; The type of the event to which to subscribe. - (field $u $subscription_u) - ) -) - -;;; Exit code generated by a process when exiting. -(typename $exitcode u32) - -;;; Signal condition. -(typename $signal - (enum (@witx tag u8) - ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;;; so this value is reserved. - $none - ;;; Hangup. - ;;; Action: Terminates the process. - $hup - ;;; Terminate interrupt signal. - ;;; Action: Terminates the process. - $int - ;;; Terminal quit signal. - ;;; Action: Terminates the process. - $quit - ;;; Illegal instruction. - ;;; Action: Terminates the process. - $ill - ;;; Trace/breakpoint trap. - ;;; Action: Terminates the process. - $trap - ;;; Process abort signal. - ;;; Action: Terminates the process. - $abrt - ;;; Access to an undefined portion of a memory object. - ;;; Action: Terminates the process. - $bus - ;;; Erroneous arithmetic operation. - ;;; Action: Terminates the process. - $fpe - ;;; Kill. - ;;; Action: Terminates the process. - $kill - ;;; User-defined signal 1. - ;;; Action: Terminates the process. - $usr1 - ;;; Invalid memory reference. - ;;; Action: Terminates the process. - $segv - ;;; User-defined signal 2. - ;;; Action: Terminates the process. - $usr2 - ;;; Write on a pipe with no one to read it. - ;;; Action: Ignored. - $pipe - ;;; Alarm clock. - ;;; Action: Terminates the process. - $alrm - ;;; Termination signal. - ;;; Action: Terminates the process. - $term - ;;; Child process terminated, stopped, or continued. - ;;; Action: Ignored. - $chld - ;;; Continue executing, if stopped. - ;;; Action: Continues executing, if stopped. - $cont - ;;; Stop executing. - ;;; Action: Stops executing. - $stop - ;;; Terminal stop signal. - ;;; Action: Stops executing. - $tstp - ;;; Background process attempting read. - ;;; Action: Stops executing. - $ttin - ;;; Background process attempting write. - ;;; Action: Stops executing. - $ttou - ;;; High bandwidth data is available at a socket. - ;;; Action: Ignored. - $urg - ;;; CPU time limit exceeded. - ;;; Action: Terminates the process. - $xcpu - ;;; File size limit exceeded. - ;;; Action: Terminates the process. - $xfsz - ;;; Virtual timer expired. - ;;; Action: Terminates the process. - $vtalrm - ;;; Profiling timer expired. - ;;; Action: Terminates the process. - $prof - ;;; Window changed. - ;;; Action: Ignored. - $winch - ;;; I/O possible. - ;;; Action: Terminates the process. - $poll - ;;; Power failure. - ;;; Action: Terminates the process. - $pwr - ;;; Bad system call. - ;;; Action: Terminates the process. - $sys - ) -) - -;;; Flags provided to `sock_recv`. -(typename $riflags - (flags (@witx repr u16) - ;;; Returns the message without removing it from the socket's receive queue. - $recv_peek - ;;; On byte-stream sockets, block until the full amount of data can be returned. - $recv_waitall - ) -) - -;;; Flags returned by `sock_recv`. -(typename $roflags - (flags (@witx repr u16) - ;;; Returned by `sock_recv`: Message data has been truncated. - $recv_data_truncated - ) -) - -;;; Flags provided to `sock_send`. As there are currently no flags -;;; defined, it must be set to zero. -(typename $siflags u16) - -;;; Which channels on a socket to shut down. -(typename $sdflags - (flags (@witx repr u8) - ;;; Disables further receive operations. - $rd - ;;; Disables further send operations. - $wr - ) -) - -;;; Identifiers for preopened capabilities. -(typename $preopentype - (enum (@witx tag u8) - ;;; A pre-opened directory. - $dir - ) -) - -;;; The contents of a $prestat when type is `preopentype::dir`. -(typename $prestat_dir - (record - ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size) - ) -) - -;;; Information about a pre-opened capability. -(typename $prestat - (union (@witx tag $preopentype) - $prestat_dir - ) -) diff --git a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx deleted file mode 100644 index dbece2641..000000000 --- a/proposals/filesystem/phases/old/snapshot_0/witx/wasi_unstable.witx +++ /dev/null @@ -1,513 +0,0 @@ -;; WASI Preview. This is an evolution of the API that WASI initially -;; launched with. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -;;; This API predated the convention of naming modules with a `wasi_unstable_` -;;; prefix and a version number. It is preserved here for compatibility, but -;;; we shouldn't follow this pattern in new APIs. -(module $wasi_unstable - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `args_sizes_get`. - ;;; Each argument is expected to be `\0` terminated. - (@interface func (export "args_get") - (param $argv (@witx pointer (@witx pointer u8))) - (param $argv_buf (@witx pointer u8)) - (result $error (expected (error $errno))) - ) - ;;; Return command-line argument data sizes. - (@interface func (export "args_sizes_get") - ;;; Returns the number of arguments and the size of the argument string - ;;; data, or an error. - (result $error (expected (tuple $size $size) (error $errno))) - ) - - ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. - ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - (@interface func (export "environ_get") - (param $environ (@witx pointer (@witx pointer u8))) - (param $environ_buf (@witx pointer u8)) - (result $error (expected (error $errno))) - ) - ;;; Return environment variable data sizes. - (@interface func (export "environ_sizes_get") - ;;; Returns the number of environment variable arguments and the size of the - ;;; environment variable data. - (result $error (expected (tuple $size $size) (error $errno))) - ) - - ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return - ;;; `errno::inval`. - ;;; Note: This is similar to `clock_getres` in POSIX. - (@interface func (export "clock_res_get") - ;;; The clock for which to return the resolution. - (param $id $clockid) - ;;; The resolution of the clock, or an error if one happened. - (result $error (expected $timestamp (error $errno))) - ) - ;;; Return the time value of a clock. - ;;; Note: This is similar to `clock_gettime` in POSIX. - (@interface func (export "clock_time_get") - ;;; The clock for which to return the time. - (param $id $clockid) - ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp) - ;;; The time value of the clock. - (result $error (expected $timestamp (error $errno))) - ) - - ;;; Provide file advisory information on a file descriptor. - ;;; Note: This is similar to `posix_fadvise` in POSIX. - (@interface func (export "fd_advise") - (param $fd $fd) - ;;; The offset within the file to which the advisory applies. - (param $offset $filesize) - ;;; The length of the region to which the advisory applies. - (param $len $filesize) - ;;; The advice. - (param $advice $advice) - (result $error (expected (error $errno))) - ) - - ;;; Force the allocation of space in a file. - ;;; Note: This is similar to `posix_fallocate` in POSIX. - (@interface func (export "fd_allocate") - (param $fd $fd) - ;;; The offset at which to start the allocation. - (param $offset $filesize) - ;;; The length of the area that is allocated. - (param $len $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Close a file descriptor. - ;;; Note: This is similar to `close` in POSIX. - (@interface func (export "fd_close") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Synchronize the data of a file to disk. - ;;; Note: This is similar to `fdatasync` in POSIX. - (@interface func (export "fd_datasync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Get the attributes of a file descriptor. - ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (@interface func (export "fd_fdstat_get") - (param $fd $fd) - ;;; The buffer where the file descriptor's attributes are stored. - (result $error (expected $fdstat (error $errno))) - ) - - ;;; Adjust the flags associated with a file descriptor. - ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd) - ;;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights - (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd) - ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of an open file. - (@interface func (export "fd_filestat_get") - (param $fd $fd) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;;; Note: This is similar to `ftruncate` in POSIX. - (@interface func (export "fd_filestat_set_size") - (param $fd $fd) - ;;; The desired file size. - (param $size $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the timestamps of an open file or directory. - ;;; Note: This is similar to `futimens` in POSIX. - (@interface func (export "fd_filestat_set_times") - (param $fd $fd) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in POSIX. - (@interface func (export "fd_pread") - (param $fd $fd) - ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_array) - ;;; The offset within the file at which to read. - (param $offset $filesize) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_get") - (param $fd $fd) - ;;; The buffer where the description is stored. - (result $error (expected $prestat (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_dir_name") - (param $fd $fd) - ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer u8)) - (param $path_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in POSIX. - (@interface func (export "fd_pwrite") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The offset within the file at which to write. - (param $offset $filesize) - ;;; The number of bytes written. - (result $error (expected $size (error $errno))) - ) - - ;;; Read from a file descriptor. - ;;; Note: This is similar to `readv` in POSIX. - (@interface func (export "fd_read") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_array) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Read directory entries from a directory. - ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a `dirent` object, - ;;; followed by `dirent::d_namlen` bytes holding the name of the directory - ;;; entry. - ;; - ;;; This function fills the output buffer as much as possible, potentially - ;;; truncating the last directory entry. This allows the caller to grow its - ;;; read buffer size in case it's too small to fit a single large directory - ;;; entry, or skip the oversized directory entry. - (@interface func (export "fd_readdir") - (param $fd $fd) - ;;; The buffer where directory entries are stored - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The location within the directory to start reading - (param $cookie $dircookie) - ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $error (expected $size (error $errno))) - ) - - ;;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;;; Due to the strong focus on thread safety, this environment does not provide - ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;;; file descriptor with the same number could be allocated by a different - ;;; thread at the same time. - ;; - ;;; This function provides a way to atomically renumber file descriptors, which - ;;; would disappear if `dup2()` were to be removed entirely. - (@interface func (export "fd_renumber") - (param $fd $fd) - ;;; The file descriptor to overwrite. - (param $to $fd) - (result $error (expected (error $errno))) - ) - - ;;; Move the offset of a file descriptor. - ;;; Note: This is similar to `lseek` in POSIX. - (@interface func (export "fd_seek") - (param $fd $fd) - ;;; The number of bytes to move. - (param $offset $filedelta) - ;;; The base from which the offset is relative. - (param $whence $whence) - ;;; The new offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Synchronize the data and metadata of a file to disk. - ;;; Note: This is similar to `fsync` in POSIX. - (@interface func (export "fd_sync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Return the current offset of a file descriptor. - ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (@interface func (export "fd_tell") - (param $fd $fd) - ;;; The current offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Write to a file descriptor. - ;;; Note: This is similar to `writev` in POSIX. - (@interface func (export "fd_write") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - (result $error (expected $size (error $errno))) - ) - - ;;; Create a directory. - ;;; Note: This is similar to `mkdirat` in POSIX. - (@interface func (export "path_create_directory") - (param $fd $fd) - ;;; The path at which to create the directory. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of a file or directory. - ;;; Note: This is similar to `stat` in POSIX. - (@interface func (export "path_filestat_get") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to inspect. - (param $path string) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the timestamps of a file or directory. - ;;; Note: This is similar to `utimensat` in POSIX. - (@interface func (export "path_filestat_set_times") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to operate on. - (param $path string) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Create a hard link. - ;;; Note: This is similar to `linkat` in POSIX. - (@interface func (export "path_link") - (param $old_fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags) - ;;; The source path from which to link. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path at which to create the hard link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Open a file or directory. - ;; - ;;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;;; file descriptor not currently open; it is randomized to prevent - ;;; applications from depending on making assumptions about indexes, since this - ;;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;;; guaranteed to be less than 2**31. - ;; - ;;; Note: This is similar to `openat` in POSIX. - (@interface func (export "path_open") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags) - ;;; The relative path of the file or directory to open, relative to the - ;;; `path_open::fd` directory. - (param $path string) - ;;; The method by which to open the file. - (param $oflags $oflags) - ;;; The initial rights of the newly created file descriptor. The - ;;; implementation is allowed to return a file descriptor with fewer rights - ;;; than specified, if and only if those rights do not apply to the type of - ;;; file being opened. - ;; - ;;; The *base* rights are rights that will apply to operations using the file - ;;; descriptor itself, while the *inheriting* rights are rights that apply to - ;;; file descriptors derived from it. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (param $fdflags $fdflags) - ;;; The file descriptor of the file that has been opened. - (result $error (expected $fd (error $errno))) - ) - - ;;; Read the contents of a symbolic link. - ;;; Note: This is similar to `readlinkat` in POSIX. - (@interface func (export "path_readlink") - (param $fd $fd) - ;;; The path of the symbolic link from which to read. - (param $path string) - ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The number of bytes placed in the buffer. - (result $error (expected $size (error $errno))) - ) - - ;;; Remove a directory. - ;;; Return `errno::notempty` if the directory is not empty. - ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (@interface func (export "path_remove_directory") - (param $fd $fd) - ;;; The path to a directory to remove. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Rename a file or directory. - ;;; Note: This is similar to `renameat` in POSIX. - (@interface func (export "path_rename") - (param $fd $fd) - ;;; The source path of the file or directory to rename. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Create a symbolic link. - ;;; Note: This is similar to `symlinkat` in POSIX. - (@interface func (export "path_symlink") - ;;; The contents of the symbolic link. - (param $old_path string) - (param $fd $fd) - ;;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - - ;;; Unlink a file. - ;;; Return `errno::isdir` if the path refers to a directory. - ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (@interface func (export "path_unlink_file") - (param $fd $fd) - ;;; The path to a file to unlink. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Concurrently poll for the occurrence of a set of events. - (@interface func (export "poll_oneoff") - ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription)) - ;;; The events that have occurred. - (param $out (@witx pointer $event)) - ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size) - ;;; The number of events stored. - (result $error (expected $size (error $errno))) - ) - - ;;; Terminate the process normally. An exit code of 0 indicates successful - ;;; termination of the program. The meanings of other values is dependent on - ;;; the environment. - (@interface func (export "proc_exit") - ;;; The exit code returned by the process. - (param $rval $exitcode) - (@witx noreturn) - ) - - ;;; Send a signal to the process of the calling thread. - ;;; Note: This is similar to `raise` in POSIX. - (@interface func (export "proc_raise") - ;;; The signal condition to trigger. - (param $sig $signal) - (result $error (expected (error $errno))) - ) - - ;;; Temporarily yield execution of the calling thread. - ;;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "sched_yield") - (result $error (expected (error $errno))) - ) - - ;;; Write high-quality random data into a buffer. - ;;; This function blocks when the implementation is unable to immediately - ;;; provide sufficient high-quality random data. - ;;; This function may execute slowly, so when large mounts of random data are - ;;; required, it's advisable to use this function to seed a pseudo-random - ;;; number generator, rather than to provide the random data directly. - (@interface func (export "random_get") - ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Receive a message from a socket. - ;;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;;; the data into multiple buffers in the manner of `readv`. - (@interface func (export "sock_recv") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_array) - ;;; Message flags. - (param $ri_flags $riflags) - ;;; Number of bytes stored in ri_data and message flags. - (result $error (expected (tuple $size $roflags) (error $errno))) - ) - - ;;; Send a message on a socket. - ;;; Note: This is similar to `send` in POSIX, though it also supports writing - ;;; the data from multiple buffers in the manner of `writev`. - (@interface func (export "sock_send") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_array) - ;;; Message flags. - (param $si_flags $siflags) - ;;; Number of bytes transmitted. - (result $error (expected $size (error $errno))) - ) - - ;;; Shut down socket send and receive channels. - ;;; Note: This is similar to `shutdown` in POSIX. - (@interface func (export "sock_shutdown") - (param $fd $fd) - ;;; Which channels on the socket to shut down. - (param $how $sdflags) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/filesystem/phases/snapshot/docs.html b/proposals/filesystem/phases/snapshot/docs.html deleted file mode 100644 index 83ea3c7d2..000000000 --- a/proposals/filesystem/phases/snapshot/docs.html +++ /dev/null @@ -1,1279 +0,0 @@ -

Types

-

<a href="#size" name="size"></a> size: u32

-

Size: 4
Alignment: 4

-

<a href="#filesize" name="filesize"></a> filesize: u64

-

Non-negative file size or length of a region within a file.
Size: 8
Alignment: 8

-

<a href="#timestamp" name="timestamp"></a> timestamp: u64

-

Timestamp in nanoseconds.
Size: 8
Alignment: 8

-

<a href="#clockid" name="clockid"></a> clockid: Enum(u32)

-

Identifiers for clocks.
Size: 4
Alignment: 4

-

Variants

-
    -
  • <a href="#clockid.realtime" name="clockid.realtime"></a> realtime
    The clock measuring real time. Time value zero corresponds with
    1970-01-01T00:00:00Z.

    -
  • -
  • <a href="#clockid.monotonic" name="clockid.monotonic"></a> monotonic
    The store-wide monotonic clock, which is defined as a clock measuring
    real time, whose value cannot be adjusted and which cannot have negative
    clock jumps. The epoch of this clock is undefined. The absolute time
    value of this clock therefore has no meaning.

    -
  • -
  • <a href="#clockid.process_cputime_id" name="clockid.process_cputime_id"></a> process_cputime_id
    The CPU-time clock associated with the current process.

    -
  • -
  • <a href="#clockid.thread_cputime_id" name="clockid.thread_cputime_id"></a> thread_cputime_id
    The CPU-time clock associated with the current thread.

    -
  • -
-

<a href="#errno" name="errno"></a> errno: Enum(u16)

-

Error codes returned by functions.
Not all of these error codes are returned by the functions provided by this
API; some are used in higher-level library layers, and others are provided
merely for alignment with POSIX.
Size: 2
Alignment: 2

-

Variants

-
    -
  • <a href="#errno.success" name="errno.success"></a> success
    No error occurred. System call completed successfully.

    -
  • -
  • <a href="#errno.2big" name="errno.2big"></a> 2big
    Argument list too long.

    -
  • -
  • <a href="#errno.acces" name="errno.acces"></a> acces
    Permission denied.

    -
  • -
  • <a href="#errno.addrinuse" name="errno.addrinuse"></a> addrinuse
    Address in use.

    -
  • -
  • <a href="#errno.addrnotavail" name="errno.addrnotavail"></a> addrnotavail
    Address not available.

    -
  • -
  • <a href="#errno.afnosupport" name="errno.afnosupport"></a> afnosupport
    Address family not supported.

    -
  • -
  • <a href="#errno.again" name="errno.again"></a> again
    Resource unavailable, or operation would block.

    -
  • -
  • <a href="#errno.already" name="errno.already"></a> already
    Connection already in progress.

    -
  • -
  • <a href="#errno.badf" name="errno.badf"></a> badf
    Bad file descriptor.

    -
  • -
  • <a href="#errno.badmsg" name="errno.badmsg"></a> badmsg
    Bad message.

    -
  • -
  • <a href="#errno.busy" name="errno.busy"></a> busy
    Device or resource busy.

    -
  • -
  • <a href="#errno.canceled" name="errno.canceled"></a> canceled
    Operation canceled.

    -
  • -
  • <a href="#errno.child" name="errno.child"></a> child
    No child processes.

    -
  • -
  • <a href="#errno.connaborted" name="errno.connaborted"></a> connaborted
    Connection aborted.

    -
  • -
  • <a href="#errno.connrefused" name="errno.connrefused"></a> connrefused
    Connection refused.

    -
  • -
  • <a href="#errno.connreset" name="errno.connreset"></a> connreset
    Connection reset.

    -
  • -
  • <a href="#errno.deadlk" name="errno.deadlk"></a> deadlk
    Resource deadlock would occur.

    -
  • -
  • <a href="#errno.destaddrreq" name="errno.destaddrreq"></a> destaddrreq
    Destination address required.

    -
  • -
  • <a href="#errno.dom" name="errno.dom"></a> dom
    Mathematics argument out of domain of function.

    -
  • -
  • <a href="#errno.dquot" name="errno.dquot"></a> dquot
    Reserved.

    -
  • -
  • <a href="#errno.exist" name="errno.exist"></a> exist
    File exists.

    -
  • -
  • <a href="#errno.fault" name="errno.fault"></a> fault
    Bad address.

    -
  • -
  • <a href="#errno.fbig" name="errno.fbig"></a> fbig
    File too large.

    -
  • -
  • <a href="#errno.hostunreach" name="errno.hostunreach"></a> hostunreach
    Host is unreachable.

    -
  • -
  • <a href="#errno.idrm" name="errno.idrm"></a> idrm
    Identifier removed.

    -
  • -
  • <a href="#errno.ilseq" name="errno.ilseq"></a> ilseq
    Illegal byte sequence.

    -
  • -
  • <a href="#errno.inprogress" name="errno.inprogress"></a> inprogress
    Operation in progress.

    -
  • -
  • <a href="#errno.intr" name="errno.intr"></a> intr
    Interrupted function.

    -
  • -
  • <a href="#errno.inval" name="errno.inval"></a> inval
    Invalid argument.

    -
  • -
  • <a href="#errno.io" name="errno.io"></a> io
    I/O error.

    -
  • -
  • <a href="#errno.isconn" name="errno.isconn"></a> isconn
    Socket is connected.

    -
  • -
  • <a href="#errno.isdir" name="errno.isdir"></a> isdir
    Is a directory.

    -
  • -
  • <a href="#errno.loop" name="errno.loop"></a> loop
    Too many levels of symbolic links.

    -
  • -
  • <a href="#errno.mfile" name="errno.mfile"></a> mfile
    File descriptor value too large.

    -
  • -
  • <a href="#errno.mlink" name="errno.mlink"></a> mlink
    Too many links.

    -
  • -
  • <a href="#errno.msgsize" name="errno.msgsize"></a> msgsize
    Message too large.

    -
  • -
  • <a href="#errno.multihop" name="errno.multihop"></a> multihop
    Reserved.

    -
  • -
  • <a href="#errno.nametoolong" name="errno.nametoolong"></a> nametoolong
    Filename too long.

    -
  • -
  • <a href="#errno.netdown" name="errno.netdown"></a> netdown
    Network is down.

    -
  • -
  • <a href="#errno.netreset" name="errno.netreset"></a> netreset
    Connection aborted by network.

    -
  • -
  • <a href="#errno.netunreach" name="errno.netunreach"></a> netunreach
    Network unreachable.

    -
  • -
  • <a href="#errno.nfile" name="errno.nfile"></a> nfile
    Too many files open in system.

    -
  • -
  • <a href="#errno.nobufs" name="errno.nobufs"></a> nobufs
    No buffer space available.

    -
  • -
  • <a href="#errno.nodev" name="errno.nodev"></a> nodev
    No such device.

    -
  • -
  • <a href="#errno.noent" name="errno.noent"></a> noent
    No such file or directory.

    -
  • -
  • <a href="#errno.noexec" name="errno.noexec"></a> noexec
    Executable file format error.

    -
  • -
  • <a href="#errno.nolck" name="errno.nolck"></a> nolck
    No locks available.

    -
  • -
  • <a href="#errno.nolink" name="errno.nolink"></a> nolink
    Reserved.

    -
  • -
  • <a href="#errno.nomem" name="errno.nomem"></a> nomem
    Not enough space.

    -
  • -
  • <a href="#errno.nomsg" name="errno.nomsg"></a> nomsg
    No message of the desired type.

    -
  • -
  • <a href="#errno.noprotoopt" name="errno.noprotoopt"></a> noprotoopt
    Protocol not available.

    -
  • -
  • <a href="#errno.nospc" name="errno.nospc"></a> nospc
    No space left on device.

    -
  • -
  • <a href="#errno.nosys" name="errno.nosys"></a> nosys
    Function not supported.

    -
  • -
  • <a href="#errno.notconn" name="errno.notconn"></a> notconn
    The socket is not connected.

    -
  • -
  • <a href="#errno.notdir" name="errno.notdir"></a> notdir
    Not a directory or a symbolic link to a directory.

    -
  • -
  • <a href="#errno.notempty" name="errno.notempty"></a> notempty
    Directory not empty.

    -
  • -
  • <a href="#errno.notrecoverable" name="errno.notrecoverable"></a> notrecoverable
    State not recoverable.

    -
  • -
  • <a href="#errno.notsock" name="errno.notsock"></a> notsock
    Not a socket.

    -
  • -
  • <a href="#errno.notsup" name="errno.notsup"></a> notsup
    Not supported, or operation not supported on socket.

    -
  • -
  • <a href="#errno.notty" name="errno.notty"></a> notty
    Inappropriate I/O control operation.

    -
  • -
  • <a href="#errno.nxio" name="errno.nxio"></a> nxio
    No such device or address.

    -
  • -
  • <a href="#errno.overflow" name="errno.overflow"></a> overflow
    Value too large to be stored in data type.

    -
  • -
  • <a href="#errno.ownerdead" name="errno.ownerdead"></a> ownerdead
    Previous owner died.

    -
  • -
  • <a href="#errno.perm" name="errno.perm"></a> perm
    Operation not permitted.

    -
  • -
  • <a href="#errno.pipe" name="errno.pipe"></a> pipe
    Broken pipe.

    -
  • -
  • <a href="#errno.proto" name="errno.proto"></a> proto
    Protocol error.

    -
  • -
  • <a href="#errno.protonosupport" name="errno.protonosupport"></a> protonosupport
    Protocol not supported.

    -
  • -
  • <a href="#errno.prototype" name="errno.prototype"></a> prototype
    Protocol wrong type for socket.

    -
  • -
  • <a href="#errno.range" name="errno.range"></a> range
    Result too large.

    -
  • -
  • <a href="#errno.rofs" name="errno.rofs"></a> rofs
    Read-only file system.

    -
  • -
  • <a href="#errno.spipe" name="errno.spipe"></a> spipe
    Invalid seek.

    -
  • -
  • <a href="#errno.srch" name="errno.srch"></a> srch
    No such process.

    -
  • -
  • <a href="#errno.stale" name="errno.stale"></a> stale
    Reserved.

    -
  • -
  • <a href="#errno.timedout" name="errno.timedout"></a> timedout
    Connection timed out.

    -
  • -
  • <a href="#errno.txtbsy" name="errno.txtbsy"></a> txtbsy
    Text file busy.

    -
  • -
  • <a href="#errno.xdev" name="errno.xdev"></a> xdev
    Cross-device link.

    -
  • -
  • <a href="#errno.notcapable" name="errno.notcapable"></a> notcapable
    Extension: Capabilities insufficient.

    -
  • -
-

<a href="#rights" name="rights"></a> rights: Flags(u64)

-

File descriptor rights, determining which actions may be performed.
Size: 8
Alignment: 8

-

Flags

-
    -
  • <a href="#rights.fd_datasync" name="rights.fd_datasync"></a> fd_datasync
    The right to invoke fd_datasync.
    If path_open is set, includes the right to invoke
    path_open with fdflags::dsync.

    -
  • -
  • <a href="#rights.fd_read" name="rights.fd_read"></a> fd_read
    The right to invoke fd_read and sock_recv.
    If rights::fd_seek is set, includes the right to invoke fd_pread.

    -
  • -
  • <a href="#rights.fd_seek" name="rights.fd_seek"></a> fd_seek
    The right to invoke fd_seek. This flag implies rights::fd_tell.

    -
  • -
  • <a href="#rights.fd_fdstat_set_flags" name="rights.fd_fdstat_set_flags"></a> fd_fdstat_set_flags
    The right to invoke fd_fdstat_set_flags.

    -
  • -
  • <a href="#rights.fd_sync" name="rights.fd_sync"></a> fd_sync
    The right to invoke fd_sync.
    If path_open is set, includes the right to invoke
    path_open with fdflags::rsync and fdflags::dsync.

    -
  • -
  • <a href="#rights.fd_tell" name="rights.fd_tell"></a> fd_tell
    The right to invoke fd_seek in such a way that the file offset
    remains unaltered (i.e., whence::cur with offset zero), or to
    invoke fd_tell.

    -
  • -
  • <a href="#rights.fd_write" name="rights.fd_write"></a> fd_write
    The right to invoke fd_write and sock_send.
    If rights::fd_seek is set, includes the right to invoke fd_pwrite.

    -
  • -
  • <a href="#rights.fd_advise" name="rights.fd_advise"></a> fd_advise
    The right to invoke fd_advise.

    -
  • -
  • <a href="#rights.fd_allocate" name="rights.fd_allocate"></a> fd_allocate
    The right to invoke fd_allocate.

    -
  • -
  • <a href="#rights.path_create_directory" name="rights.path_create_directory"></a> path_create_directory
    The right to invoke path_create_directory.

    -
  • -
  • <a href="#rights.path_create_file" name="rights.path_create_file"></a> path_create_file
    If path_open is set, the right to invoke path_open with oflags::creat.

    -
  • -
  • <a href="#rights.path_link_source" name="rights.path_link_source"></a> path_link_source
    The right to invoke path_link with the file descriptor as the
    source directory.

    -
  • -
  • <a href="#rights.path_link_target" name="rights.path_link_target"></a> path_link_target
    The right to invoke path_link with the file descriptor as the
    target directory.

    -
  • -
  • <a href="#rights.path_open" name="rights.path_open"></a> path_open
    The right to invoke path_open.

    -
  • -
  • <a href="#rights.fd_readdir" name="rights.fd_readdir"></a> fd_readdir
    The right to invoke fd_readdir.

    -
  • -
  • <a href="#rights.path_readlink" name="rights.path_readlink"></a> path_readlink
    The right to invoke path_readlink.

    -
  • -
  • <a href="#rights.path_rename_source" name="rights.path_rename_source"></a> path_rename_source
    The right to invoke path_rename with the file descriptor as the source directory.

    -
  • -
  • <a href="#rights.path_rename_target" name="rights.path_rename_target"></a> path_rename_target
    The right to invoke path_rename with the file descriptor as the target directory.

    -
  • -
  • <a href="#rights.path_filestat_get" name="rights.path_filestat_get"></a> path_filestat_get
    The right to invoke path_filestat_get.

    -
  • -
  • <a href="#rights.path_filestat_set_size" name="rights.path_filestat_set_size"></a> path_filestat_set_size
    The right to change a file's size (there is no path_filestat_set_size).
    If path_open is set, includes the right to invoke path_open with oflags::trunc.

    -
  • -
  • <a href="#rights.path_filestat_set_times" name="rights.path_filestat_set_times"></a> path_filestat_set_times
    The right to invoke path_filestat_set_times.

    -
  • -
  • <a href="#rights.fd_filestat_get" name="rights.fd_filestat_get"></a> fd_filestat_get
    The right to invoke fd_filestat_get.

    -
  • -
  • <a href="#rights.fd_filestat_set_size" name="rights.fd_filestat_set_size"></a> fd_filestat_set_size
    The right to invoke fd_filestat_set_size.

    -
  • -
  • <a href="#rights.fd_filestat_set_times" name="rights.fd_filestat_set_times"></a> fd_filestat_set_times
    The right to invoke fd_filestat_set_times.

    -
  • -
  • <a href="#rights.path_symlink" name="rights.path_symlink"></a> path_symlink
    The right to invoke path_symlink.

    -
  • -
  • <a href="#rights.path_remove_directory" name="rights.path_remove_directory"></a> path_remove_directory
    The right to invoke path_remove_directory.

    -
  • -
  • <a href="#rights.path_unlink_file" name="rights.path_unlink_file"></a> path_unlink_file
    The right to invoke path_unlink_file.

    -
  • -
  • <a href="#rights.poll_fd_readwrite" name="rights.poll_fd_readwrite"></a> poll_fd_readwrite
    If rights::fd_read is set, includes the right to invoke poll_oneoff to subscribe to eventtype::fd_read.
    If rights::fd_write is set, includes the right to invoke poll_oneoff to subscribe to eventtype::fd_write.

    -
  • -
  • <a href="#rights.sock_shutdown" name="rights.sock_shutdown"></a> sock_shutdown
    The right to invoke sock_shutdown.

    -
  • -
-

<a href="#fd" name="fd"></a> fd

-

A file descriptor handle.
Size: 4
Alignment: 4

-

Supertypes

-

<a href="#iovec" name="iovec"></a> iovec: Struct

-

A region of memory for scatter/gather reads.
Size: 8
Alignment: 4

-

Struct members

-
    -
  • <a href="#iovec.buf" name="iovec.buf"></a> buf: Pointer<u8>
    The address of the buffer to be filled.
    Offset: 0
  • -
  • <a href="#iovec.buf_len" name="iovec.buf_len"></a> buf_len: size
    The length of the buffer to be filled.
    Offset: 4

    <a href="#ciovec" name="ciovec"></a> ciovec: Struct

    -A region of memory for scatter/gather writes.
    Size: 8
    Alignment: 4

    Struct members

    -
  • -
  • <a href="#ciovec.buf" name="ciovec.buf"></a> buf: ConstPointer<u8>
    The address of the buffer to be written.
    Offset: 0
  • -
  • <a href="#ciovec.buf_len" name="ciovec.buf_len"></a> buf_len: size
    The length of the buffer to be written.
    Offset: 4

    <a href="#iovec_array" name="iovec_array"></a> iovec_array: Array<iovec>

    -Size: 8
    Alignment: 4

    <a href="#ciovec_array" name="ciovec_array"></a> ciovec_array: Array<ciovec>

    -Size: 8
    Alignment: 4

    <a href="#filedelta" name="filedelta"></a> filedelta: s64

    -Relative offset within a file.
    Size: 8
    Alignment: 8

    <a href="#whence" name="whence"></a> whence: Enum(u8)

    -The position relative to which to set the offset of the file descriptor.
    Size: 1
    Alignment: 1

    Variants

    -
  • -
  • <a href="#whence.set" name="whence.set"></a> set
    Seek relative to start-of-file.

    -
  • -
  • <a href="#whence.cur" name="whence.cur"></a> cur
    Seek relative to current position.

    -
  • -
  • <a href="#whence.end" name="whence.end"></a> end
    Seek relative to end-of-file.

    -
  • -
-

<a href="#dircookie" name="dircookie"></a> dircookie: u64

-

A reference to the offset of a directory entry.

-

The value 0 signifies the start of the directory.
Size: 8
Alignment: 8

-

<a href="#dirnamlen" name="dirnamlen"></a> dirnamlen: u32

-

The type for the $d_namlen field of $dirent.
Size: 4
Alignment: 4

-

<a href="#inode" name="inode"></a> inode: u64

-

File serial number that is unique within its file system.
Size: 8
Alignment: 8

-

<a href="#filetype" name="filetype"></a> filetype: Enum(u8)

-

The type of a file descriptor or file.
Size: 1
Alignment: 1

-

Variants

-
    -
  • <a href="#filetype.unknown" name="filetype.unknown"></a> unknown
    The type of the file descriptor or file is unknown or is different from any of the other types specified.

    -
  • -
  • <a href="#filetype.block_device" name="filetype.block_device"></a> block_device
    The file descriptor or file refers to a block device inode.

    -
  • -
  • <a href="#filetype.character_device" name="filetype.character_device"></a> character_device
    The file descriptor or file refers to a character device inode.

    -
  • -
  • <a href="#filetype.directory" name="filetype.directory"></a> directory
    The file descriptor or file refers to a directory inode.

    -
  • -
  • <a href="#filetype.regular_file" name="filetype.regular_file"></a> regular_file
    The file descriptor or file refers to a regular file inode.

    -
  • -
  • <a href="#filetype.socket_dgram" name="filetype.socket_dgram"></a> socket_dgram
    The file descriptor or file refers to a datagram socket.

    -
  • -
  • <a href="#filetype.socket_stream" name="filetype.socket_stream"></a> socket_stream
    The file descriptor or file refers to a byte-stream socket.

    -
  • -
  • <a href="#filetype.symbolic_link" name="filetype.symbolic_link"></a> symbolic_link
    The file refers to a symbolic link inode.

    -
  • -
-

<a href="#dirent" name="dirent"></a> dirent: Struct

-

A directory entry.
Size: 24
Alignment: 8

-

Struct members

-
    -
  • <a href="#dirent.d_next" name="dirent.d_next"></a> d_next: dircookie
    The offset of the next directory entry stored in this directory.
    Offset: 0
  • -
  • <a href="#dirent.d_ino" name="dirent.d_ino"></a> d_ino: inode
    The serial number of the file referred to by this directory entry.
    Offset: 8
  • -
  • <a href="#dirent.d_namlen" name="dirent.d_namlen"></a> d_namlen: dirnamlen
    The length of the name of the directory entry.
    Offset: 16
  • -
  • <a href="#dirent.d_type" name="dirent.d_type"></a> d_type: filetype
    The type of the file referred to by this directory entry.
    Offset: 20

    <a href="#advice" name="advice"></a> advice: Enum(u8)

    -File or memory access pattern advisory information.
    Size: 1
    Alignment: 1

    Variants

    -
  • -
  • <a href="#advice.normal" name="advice.normal"></a> normal
    The application has no advice to give on its behavior with respect to the specified data.

    -
  • -
  • <a href="#advice.sequential" name="advice.sequential"></a> sequential
    The application expects to access the specified data sequentially from lower offsets to higher offsets.

    -
  • -
  • <a href="#advice.random" name="advice.random"></a> random
    The application expects to access the specified data in a random order.

    -
  • -
  • <a href="#advice.willneed" name="advice.willneed"></a> willneed
    The application expects to access the specified data in the near future.

    -
  • -
  • <a href="#advice.dontneed" name="advice.dontneed"></a> dontneed
    The application expects that it will not access the specified data in the near future.

    -
  • -
  • <a href="#advice.noreuse" name="advice.noreuse"></a> noreuse
    The application expects to access the specified data once and then not reuse it thereafter.

    -
  • -
-

<a href="#fdflags" name="fdflags"></a> fdflags: Flags(u16)

-

File descriptor flags.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#fdflags.append" name="fdflags.append"></a> append
    Append mode: Data written to the file is always appended to the file's end.

    -
  • -
  • <a href="#fdflags.dsync" name="fdflags.dsync"></a> dsync
    Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized.

    -
  • -
  • <a href="#fdflags.nonblock" name="fdflags.nonblock"></a> nonblock
    Non-blocking mode.

    -
  • -
  • <a href="#fdflags.rsync" name="fdflags.rsync"></a> rsync
    Synchronized read I/O operations.

    -
  • -
  • <a href="#fdflags.sync" name="fdflags.sync"></a> sync
    Write according to synchronized I/O file integrity completion. In
    addition to synchronizing the data stored in the file, the implementation
    may also synchronously update the file's metadata.

    -
  • -
-

<a href="#fdstat" name="fdstat"></a> fdstat: Struct

-

File descriptor attributes.
Size: 24
Alignment: 8

-

Struct members

-
    -
  • <a href="#fdstat.fs_filetype" name="fdstat.fs_filetype"></a> fs_filetype: filetype
    File type.
    Offset: 0
  • -
  • <a href="#fdstat.fs_flags" name="fdstat.fs_flags"></a> fs_flags: fdflags
    File descriptor flags.
    Offset: 2
  • -
  • <a href="#fdstat.fs_rights_base" name="fdstat.fs_rights_base"></a> fs_rights_base: rights
    Rights that apply to this file descriptor.
    Offset: 8
  • -
  • <a href="#fdstat.fs_rights_inheriting" name="fdstat.fs_rights_inheriting"></a> fs_rights_inheriting: rights
    Maximum set of rights that may be installed on new file descriptors that
    are created through this file descriptor, e.g., through path_open.
    Offset: 16

    <a href="#device" name="device"></a> device: u64

    -Identifier for a device containing a file system. Can be used in combination
    with inode to uniquely identify a file or directory in the filesystem.
    Size: 8
    Alignment: 8

    <a href="#fstflags" name="fstflags"></a> fstflags: Flags(u16)

    -Which file time attributes to adjust.
    Size: 2
    Alignment: 2

    Flags

    -
  • -
  • <a href="#fstflags.atim" name="fstflags.atim"></a> atim
    Adjust the last data access timestamp to the value stored in filestat::atim.

    -
  • -
  • <a href="#fstflags.atim_now" name="fstflags.atim_now"></a> atim_now
    Adjust the last data access timestamp to the time of clock clockid::realtime.

    -
  • -
  • <a href="#fstflags.mtim" name="fstflags.mtim"></a> mtim
    Adjust the last data modification timestamp to the value stored in filestat::mtim.

    -
  • -
  • <a href="#fstflags.mtim_now" name="fstflags.mtim_now"></a> mtim_now
    Adjust the last data modification timestamp to the time of clock clockid::realtime.

    -
  • -
-

<a href="#lookupflags" name="lookupflags"></a> lookupflags: Flags(u32)

-

Flags determining the method of how paths are resolved.
Size: 4
Alignment: 4

-

Flags

-
    -
  • <a href="#lookupflags.symlink_follow" name="lookupflags.symlink_follow"></a> symlink_follow
    As long as the resolved path corresponds to a symbolic link, it is expanded.
  • -
-

<a href="#oflags" name="oflags"></a> oflags: Flags(u16)

-

Open flags used by path_open.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#oflags.creat" name="oflags.creat"></a> creat
    Create file if it does not exist.

    -
  • -
  • <a href="#oflags.directory" name="oflags.directory"></a> directory
    Fail if not a directory.

    -
  • -
  • <a href="#oflags.excl" name="oflags.excl"></a> excl
    Fail if file already exists.

    -
  • -
  • <a href="#oflags.trunc" name="oflags.trunc"></a> trunc
    Truncate file to size 0.

    -
  • -
-

<a href="#linkcount" name="linkcount"></a> linkcount: u64

-

Number of hard links to an inode.
Size: 8
Alignment: 8

-

<a href="#filestat" name="filestat"></a> filestat: Struct

-

File attributes.
Size: 64
Alignment: 8

-

Struct members

-
    -
  • <a href="#filestat.dev" name="filestat.dev"></a> dev: device
    Device ID of device containing the file.
    Offset: 0
  • -
  • <a href="#filestat.ino" name="filestat.ino"></a> ino: inode
    File serial number.
    Offset: 8
  • -
  • <a href="#filestat.filetype" name="filestat.filetype"></a> filetype: filetype
    File type.
    Offset: 16
  • -
  • <a href="#filestat.nlink" name="filestat.nlink"></a> nlink: linkcount
    Number of hard links to the file.
    Offset: 24
  • -
  • <a href="#filestat.size" name="filestat.size"></a> size: filesize
    For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link.
    Offset: 32
  • -
  • <a href="#filestat.atim" name="filestat.atim"></a> atim: timestamp
    Last data access timestamp.
    Offset: 40
  • -
  • <a href="#filestat.mtim" name="filestat.mtim"></a> mtim: timestamp
    Last data modification timestamp.
    Offset: 48
  • -
  • <a href="#filestat.ctim" name="filestat.ctim"></a> ctim: timestamp
    Last file status change timestamp.
    Offset: 56

    <a href="#userdata" name="userdata"></a> userdata: u64

    -User-provided value that may be attached to objects that is retained when
    extracted from the implementation.
    Size: 8
    Alignment: 8

    <a href="#eventtype" name="eventtype"></a> eventtype: Enum(u8)

    -Type of a subscription to an event or its occurrence.
    Size: 1
    Alignment: 1

    Variants

    -
  • -
  • <a href="#eventtype.clock" name="eventtype.clock"></a> clock
    The time value of clock subscription_clock::id has
    reached timestamp subscription_clock::timeout.

    -
  • -
  • <a href="#eventtype.fd_read" name="eventtype.fd_read"></a> fd_read
    File descriptor subscription_fd_readwrite::file_descriptor has data
    available for reading. This event always triggers for regular files.

    -
  • -
  • <a href="#eventtype.fd_write" name="eventtype.fd_write"></a> fd_write
    File descriptor subscription_fd_readwrite::file_descriptor has capacity
    available for writing. This event always triggers for regular files.

    -
  • -
-

<a href="#eventrwflags" name="eventrwflags"></a> eventrwflags: Flags(u16)

-

The state of the file descriptor subscribed to with
eventtype::fd_read or eventtype::fd_write.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#eventrwflags.fd_readwrite_hangup" name="eventrwflags.fd_readwrite_hangup"></a> fd_readwrite_hangup
    The peer of this socket has closed or disconnected.
  • -
-

<a href="#event_fd_readwrite" name="event_fd_readwrite"></a> event_fd_readwrite: Struct

-

The contents of an $event when type is eventtype::fd_read or
eventtype::fd_write.
Size: 16
Alignment: 8

-

Struct members

-
    -
  • <a href="#event_fd_readwrite.nbytes" name="event_fd_readwrite.nbytes"></a> nbytes: filesize
    The number of bytes available for reading or writing.
    Offset: 0
  • -
  • <a href="#event_fd_readwrite.flags" name="event_fd_readwrite.flags"></a> flags: eventrwflags
    The state of the file descriptor.
    Offset: 8

    <a href="#event" name="event"></a> event: Struct

    -An event that occurred.
    Size: 32
    Alignment: 8

    Struct members

    -
  • -
  • <a href="#event.userdata" name="event.userdata"></a> userdata: userdata
    User-provided value that got attached to subscription::userdata.
    Offset: 0
  • -
  • <a href="#event.error" name="event.error"></a> error: errno
    If non-zero, an error that occurred while processing the subscription request.
    Offset: 8
  • -
  • <a href="#event.type" name="event.type"></a> type: eventtype
    The type of event that occured
    Offset: 10
  • -
  • <a href="#event.fd_readwrite" name="event.fd_readwrite"></a> fd_readwrite: event_fd_readwrite
    The contents of the event, if it is an eventtype::fd_read or
    eventtype::fd_write. eventtype::clock events ignore this field.
    Offset: 16

    <a href="#subclockflags" name="subclockflags"></a> subclockflags: Flags(u16)

    -Flags determining how to interpret the timestamp provided in
    subscription_clock::timeout.
    Size: 2
    Alignment: 2

    Flags

    -
  • -
  • <a href="#subclockflags.subscription_clock_abstime" name="subclockflags.subscription_clock_abstime"></a> subscription_clock_abstime
    If set, treat the timestamp provided in
    subscription_clock::timeout as an absolute timestamp of clock
    subscription_clock::id. If clear, treat the timestamp
    provided in subscription_clock::timeout relative to the
    current time value of clock subscription_clock::id.
  • -
-

<a href="#subscription_clock" name="subscription_clock"></a> subscription_clock: Struct

-

The contents of a subscription when type is eventtype::clock.
Size: 32
Alignment: 8

-

Struct members

-
    -
  • <a href="#subscription_clock.id" name="subscription_clock.id"></a> id: clockid
    The clock against which to compare the timestamp.
    Offset: 0
  • -
  • <a href="#subscription_clock.timeout" name="subscription_clock.timeout"></a> timeout: timestamp
    The absolute or relative timestamp.
    Offset: 8
  • -
  • <a href="#subscription_clock.precision" name="subscription_clock.precision"></a> precision: timestamp
    The amount of time that the implementation may wait additionally
    to coalesce with other events.
    Offset: 16
  • -
  • <a href="#subscription_clock.flags" name="subscription_clock.flags"></a> flags: subclockflags
    Flags specifying whether the timeout is absolute or relative
    Offset: 24

    <a href="#subscription_fd_readwrite" name="subscription_fd_readwrite"></a> subscription_fd_readwrite: Struct

    -The contents of a subscription when type is type is
    eventtype::fd_read or eventtype::fd_write.
    Size: 4
    Alignment: 4

    Struct members

    -
  • -
  • <a href="#subscription_fd_readwrite.file_descriptor" name="subscription_fd_readwrite.file_descriptor"></a> file_descriptor: fd
    The file descriptor on which to wait for it to become ready for reading or writing.
    Offset: 0

    <a href="#subscription_u" name="subscription_u"></a> subscription_u: Union

    -The contents of a subscription.
    Size: 40
    Alignment: 8

    Union Layout

    -
  • -
  • tag_size: 1
  • -
  • tag_align: 1
  • -
  • contents_offset: 8
  • -
  • contents_size: 32
  • -
  • contents_align: 8

    Union variants

    -
  • -
  • <a href="#subscription_u.clock" name="subscription_u.clock"></a> clock: subscription_clock

    -
  • -
  • <a href="#subscription_u.fd_read" name="subscription_u.fd_read"></a> fd_read: subscription_fd_readwrite

    -
  • -
  • <a href="#subscription_u.fd_write" name="subscription_u.fd_write"></a> fd_write: subscription_fd_readwrite

    -
  • -
-

<a href="#subscription" name="subscription"></a> subscription: Struct

-

Subscription to an event.
Size: 48
Alignment: 8

-

Struct members

-
    -
  • <a href="#subscription.userdata" name="subscription.userdata"></a> userdata: userdata
    User-provided value that is attached to the subscription in the
    implementation and returned through event::userdata.
    Offset: 0
  • -
  • <a href="#subscription.u" name="subscription.u"></a> u: subscription_u
    The type of the event to which to subscribe, and its contents
    Offset: 8

    <a href="#exitcode" name="exitcode"></a> exitcode: u32

    -Exit code generated by a process when exiting.
    Size: 4
    Alignment: 4

    <a href="#signal" name="signal"></a> signal: Enum(u8)

    -Signal condition.
    Size: 1
    Alignment: 1

    Variants

    -
  • -
  • <a href="#signal.none" name="signal.none"></a> none
    No signal. Note that POSIX has special semantics for kill(pid, 0),
    so this value is reserved.

    -
  • -
  • <a href="#signal.hup" name="signal.hup"></a> hup
    Hangup.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.int" name="signal.int"></a> int
    Terminate interrupt signal.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.quit" name="signal.quit"></a> quit
    Terminal quit signal.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.ill" name="signal.ill"></a> ill
    Illegal instruction.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.trap" name="signal.trap"></a> trap
    Trace/breakpoint trap.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.abrt" name="signal.abrt"></a> abrt
    Process abort signal.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.bus" name="signal.bus"></a> bus
    Access to an undefined portion of a memory object.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.fpe" name="signal.fpe"></a> fpe
    Erroneous arithmetic operation.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.kill" name="signal.kill"></a> kill
    Kill.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.usr1" name="signal.usr1"></a> usr1
    User-defined signal 1.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.segv" name="signal.segv"></a> segv
    Invalid memory reference.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.usr2" name="signal.usr2"></a> usr2
    User-defined signal 2.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.pipe" name="signal.pipe"></a> pipe
    Write on a pipe with no one to read it.
    Action: Ignored.

    -
  • -
  • <a href="#signal.alrm" name="signal.alrm"></a> alrm
    Alarm clock.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.term" name="signal.term"></a> term
    Termination signal.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.chld" name="signal.chld"></a> chld
    Child process terminated, stopped, or continued.
    Action: Ignored.

    -
  • -
  • <a href="#signal.cont" name="signal.cont"></a> cont
    Continue executing, if stopped.
    Action: Continues executing, if stopped.

    -
  • -
  • <a href="#signal.stop" name="signal.stop"></a> stop
    Stop executing.
    Action: Stops executing.

    -
  • -
  • <a href="#signal.tstp" name="signal.tstp"></a> tstp
    Terminal stop signal.
    Action: Stops executing.

    -
  • -
  • <a href="#signal.ttin" name="signal.ttin"></a> ttin
    Background process attempting read.
    Action: Stops executing.

    -
  • -
  • <a href="#signal.ttou" name="signal.ttou"></a> ttou
    Background process attempting write.
    Action: Stops executing.

    -
  • -
  • <a href="#signal.urg" name="signal.urg"></a> urg
    High bandwidth data is available at a socket.
    Action: Ignored.

    -
  • -
  • <a href="#signal.xcpu" name="signal.xcpu"></a> xcpu
    CPU time limit exceeded.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.xfsz" name="signal.xfsz"></a> xfsz
    File size limit exceeded.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.vtalrm" name="signal.vtalrm"></a> vtalrm
    Virtual timer expired.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.prof" name="signal.prof"></a> prof
    Profiling timer expired.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.winch" name="signal.winch"></a> winch
    Window changed.
    Action: Ignored.

    -
  • -
  • <a href="#signal.poll" name="signal.poll"></a> poll
    I/O possible.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.pwr" name="signal.pwr"></a> pwr
    Power failure.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.sys" name="signal.sys"></a> sys
    Bad system call.
    Action: Terminates the process.

    -
  • -
-

<a href="#riflags" name="riflags"></a> riflags: Flags(u16)

-

Flags provided to sock_recv.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#riflags.recv_peek" name="riflags.recv_peek"></a> recv_peek
    Returns the message without removing it from the socket's receive queue.

    -
  • -
  • <a href="#riflags.recv_waitall" name="riflags.recv_waitall"></a> recv_waitall
    On byte-stream sockets, block until the full amount of data can be returned.

    -
  • -
-

<a href="#roflags" name="roflags"></a> roflags: Flags(u16)

-

Flags returned by sock_recv.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#roflags.recv_data_truncated" name="roflags.recv_data_truncated"></a> recv_data_truncated
    Returned by sock_recv: Message data has been truncated.
  • -
-

<a href="#siflags" name="siflags"></a> siflags: u16

-

Flags provided to sock_send. As there are currently no flags
defined, it must be set to zero.
Size: 2
Alignment: 2

-

<a href="#sdflags" name="sdflags"></a> sdflags: Flags(u8)

-

Which channels on a socket to shut down.
Size: 1
Alignment: 1

-

Flags

-
    -
  • <a href="#sdflags.rd" name="sdflags.rd"></a> rd
    Disables further receive operations.

    -
  • -
  • <a href="#sdflags.wr" name="sdflags.wr"></a> wr
    Disables further send operations.

    -
  • -
-

<a href="#preopentype" name="preopentype"></a> preopentype: Enum(u8)

-

Identifiers for preopened capabilities.
Size: 1
Alignment: 1

-

Variants

-
    -
  • <a href="#preopentype.dir" name="preopentype.dir"></a> dir
    A pre-opened directory.
  • -
-

<a href="#prestat_dir" name="prestat_dir"></a> prestat_dir: Struct

-

The contents of a $prestat when type is preopentype::dir.
Size: 4
Alignment: 4

-

Struct members

-
    -
  • <a href="#prestat_dir.pr_name_len" name="prestat_dir.pr_name_len"></a> pr_name_len: size
    The length of the directory name for use with fd_prestat_dir_name.
    Offset: 0

    <a href="#prestat" name="prestat"></a> prestat: Union

    -Information about a pre-opened capability.
    Size: 8
    Alignment: 4

    Union Layout

    -
  • -
  • tag_size: 1
  • -
  • tag_align: 1
  • -
  • contents_offset: 4
  • -
  • contents_size: 4
  • -
  • contents_align: 4

    Union variants

    -
  • -
  • <a href="#prestat.dir" name="prestat.dir"></a> dir: prestat_dir
  • -
-

Modules

-

<a href="#wasi_snapshot_preview1" name="wasi_snapshot_preview1"></a> wasi_snapshot_preview1

-

Imports

-

Memory

-

Functions

-
-

<a href="#args_get" name="args_get"></a> args_get(argv: Pointer<Pointer<u8>>, argv_buf: Pointer<u8>) -> errno

-

Read command-line argument data.
The size of the array should match that returned by args_sizes_get

-
Params
-
    -
  • <a href="#args_get.argv" name="args_get.argv"></a> argv: Pointer<Pointer<u8>>

    -
  • -
  • <a href="#args_get.argv_buf" name="args_get.argv_buf"></a> argv_buf: Pointer<u8>

    -
  • -
-
Results
-
    -
  • <a href="#args_get.error" name="args_get.error"></a> error: errno
  • -
-
-

<a href="#args_sizes_get" name="args_sizes_get"></a> args_sizes_get() -> (errno, size, size)

-

Return command-line argument data sizes.

-
Params
-
Results
-
    -
  • <a href="#args_sizes_get.error" name="args_sizes_get.error"></a> error: errno

    -
  • -
  • <a href="#args_sizes_get.argc" name="args_sizes_get.argc"></a> argc: size
    The number of arguments.

    -
  • -
  • <a href="#args_sizes_get.argv_buf_size" name="args_sizes_get.argv_buf_size"></a> argv_buf_size: size
    The size of the argument string data.

    -
  • -
-
-

<a href="#environ_get" name="environ_get"></a> environ_get(environ: Pointer<Pointer<u8>>, environ_buf: Pointer<u8>) -> errno

-

Read environment variable data.
The sizes of the buffers should match that returned by environ_sizes_get.

-
Params
-
    -
  • <a href="#environ_get.environ" name="environ_get.environ"></a> environ: Pointer<Pointer<u8>>

    -
  • -
  • <a href="#environ_get.environ_buf" name="environ_get.environ_buf"></a> environ_buf: Pointer<u8>

    -
  • -
-
Results
-
    -
  • <a href="#environ_get.error" name="environ_get.error"></a> error: errno
  • -
-
-

<a href="#environ_sizes_get" name="environ_sizes_get"></a> environ_sizes_get() -> (errno, size, size)

-

Return environment variable data sizes.

-
Params
-
Results
-
    -
  • <a href="#environ_sizes_get.error" name="environ_sizes_get.error"></a> error: errno

    -
  • -
  • <a href="#environ_sizes_get.environc" name="environ_sizes_get.environc"></a> environc: size
    The number of environment variable arguments.

    -
  • -
  • <a href="#environ_sizes_get.environ_buf_size" name="environ_sizes_get.environ_buf_size"></a> environ_buf_size: size
    The size of the environment variable data.

    -
  • -
-
-

<a href="#clock_res_get" name="clock_res_get"></a> clock_res_get(id: clockid) -> (errno, timestamp)

-

Return the resolution of a clock.
Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks,
return errno::inval.
Note: This is similar to clock_getres in POSIX.

-
Params
-
    -
  • <a href="#clock_res_get.id" name="clock_res_get.id"></a> id: clockid
    The clock for which to return the resolution.
  • -
-
Results
-
    -
  • <a href="#clock_res_get.error" name="clock_res_get.error"></a> error: errno

    -
  • -
  • <a href="#clock_res_get.resolution" name="clock_res_get.resolution"></a> resolution: timestamp
    The resolution of the clock.

    -
  • -
-
-

<a href="#clock_time_get" name="clock_time_get"></a> clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)

-

Return the time value of a clock.
Note: This is similar to clock_gettime in POSIX.

-
Params
-
    -
  • <a href="#clock_time_get.id" name="clock_time_get.id"></a> id: clockid
    The clock for which to return the time.

    -
  • -
  • <a href="#clock_time_get.precision" name="clock_time_get.precision"></a> precision: timestamp
    The maximum lag (exclusive) that the returned time value may have, compared to its actual value.

    -
  • -
-
Results
-
    -
  • <a href="#clock_time_get.error" name="clock_time_get.error"></a> error: errno

    -
  • -
  • <a href="#clock_time_get.time" name="clock_time_get.time"></a> time: timestamp
    The time value of the clock.

    -
  • -
-
-

<a href="#fd_advise" name="fd_advise"></a> fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno

-

Provide file advisory information on a file descriptor.
Note: This is similar to posix_fadvise in POSIX.

-
Params
-
    -
  • <a href="#fd_advise.fd" name="fd_advise.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_advise.offset" name="fd_advise.offset"></a> offset: filesize
    The offset within the file to which the advisory applies.

    -
  • -
  • <a href="#fd_advise.len" name="fd_advise.len"></a> len: filesize
    The length of the region to which the advisory applies.

    -
  • -
  • <a href="#fd_advise.advice" name="fd_advise.advice"></a> advice: advice
    The advice.

    -
  • -
-
Results
-
    -
  • <a href="#fd_advise.error" name="fd_advise.error"></a> error: errno
  • -
-
-

<a href="#fd_allocate" name="fd_allocate"></a> fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno

-

Force the allocation of space in a file.
Note: This is similar to posix_fallocate in POSIX.

-
Params
-
    -
  • <a href="#fd_allocate.fd" name="fd_allocate.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_allocate.offset" name="fd_allocate.offset"></a> offset: filesize
    The offset at which to start the allocation.

    -
  • -
  • <a href="#fd_allocate.len" name="fd_allocate.len"></a> len: filesize
    The length of the area that is allocated.

    -
  • -
-
Results
-
    -
  • <a href="#fd_allocate.error" name="fd_allocate.error"></a> error: errno
  • -
-
-

<a href="#fd_close" name="fd_close"></a> fd_close(fd: fd) -> errno

-

Close a file descriptor.
Note: This is similar to close in POSIX.

-
Params
-
    -
  • <a href="#fd_close.fd" name="fd_close.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_close.error" name="fd_close.error"></a> error: errno
  • -
-
-

<a href="#fd_datasync" name="fd_datasync"></a> fd_datasync(fd: fd) -> errno

-

Synchronize the data of a file to disk.
Note: This is similar to fdatasync in POSIX.

-
Params
-
    -
  • <a href="#fd_datasync.fd" name="fd_datasync.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_datasync.error" name="fd_datasync.error"></a> error: errno
  • -
-
-

<a href="#fd_fdstat_get" name="fd_fdstat_get"></a> fd_fdstat_get(fd: fd) -> (errno, fdstat)

-

Get the attributes of a file descriptor.
Note: This returns similar flags to fsync(fd, F_GETFL) in POSIX, as well as additional fields.

-
Params
-
    -
  • <a href="#fd_fdstat_get.fd" name="fd_fdstat_get.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_fdstat_get.error" name="fd_fdstat_get.error"></a> error: errno

    -
  • -
  • <a href="#fd_fdstat_get.stat" name="fd_fdstat_get.stat"></a> stat: fdstat
    The buffer where the file descriptor's attributes are stored.

    -
  • -
-
-

<a href="#fd_fdstat_set_flags" name="fd_fdstat_set_flags"></a> fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno

-

Adjust the flags associated with a file descriptor.
Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

-
Params
-
    -
  • <a href="#fd_fdstat_set_flags.fd" name="fd_fdstat_set_flags.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_fdstat_set_flags.flags" name="fd_fdstat_set_flags.flags"></a> flags: fdflags
    The desired values of the file descriptor flags.

    -
  • -
-
Results
-
    -
  • <a href="#fd_fdstat_set_flags.error" name="fd_fdstat_set_flags.error"></a> error: errno
  • -
-
-

<a href="#fd_fdstat_set_rights" name="fd_fdstat_set_rights"></a> fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno

-

Adjust the rights associated with a file descriptor.
This can only be used to remove rights, and returns errno::notcapable if called in a way that would attempt to add rights

-
Params
-
    -
  • <a href="#fd_fdstat_set_rights.fd" name="fd_fdstat_set_rights.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_fdstat_set_rights.fs_rights_base" name="fd_fdstat_set_rights.fs_rights_base"></a> fs_rights_base: rights
    The desired rights of the file descriptor.

    -
  • -
  • <a href="#fd_fdstat_set_rights.fs_rights_inheriting" name="fd_fdstat_set_rights.fs_rights_inheriting"></a> fs_rights_inheriting: rights

    -
  • -
-
Results
-
    -
  • <a href="#fd_fdstat_set_rights.error" name="fd_fdstat_set_rights.error"></a> error: errno
  • -
-
-

<a href="#fd_filestat_get" name="fd_filestat_get"></a> fd_filestat_get(fd: fd) -> (errno, filestat)

-

Return the attributes of an open file.

-
Params
-
    -
  • <a href="#fd_filestat_get.fd" name="fd_filestat_get.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_filestat_get.error" name="fd_filestat_get.error"></a> error: errno

    -
  • -
  • <a href="#fd_filestat_get.buf" name="fd_filestat_get.buf"></a> buf: filestat
    The buffer where the file's attributes are stored.

    -
  • -
-
-

<a href="#fd_filestat_set_size" name="fd_filestat_set_size"></a> fd_filestat_set_size(fd: fd, size: filesize) -> errno

-

Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.
Note: This is similar to ftruncate in POSIX.

-
Params
-
    -
  • <a href="#fd_filestat_set_size.fd" name="fd_filestat_set_size.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_filestat_set_size.size" name="fd_filestat_set_size.size"></a> size: filesize
    The desired file size.

    -
  • -
-
Results
-
    -
  • <a href="#fd_filestat_set_size.error" name="fd_filestat_set_size.error"></a> error: errno
  • -
-
-

<a href="#fd_filestat_set_times" name="fd_filestat_set_times"></a> fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno

-

Adjust the timestamps of an open file or directory.
Note: This is similar to futimens in POSIX.

-
Params
-
    -
  • <a href="#fd_filestat_set_times.fd" name="fd_filestat_set_times.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_filestat_set_times.atim" name="fd_filestat_set_times.atim"></a> atim: timestamp
    The desired values of the data access timestamp.

    -
  • -
  • <a href="#fd_filestat_set_times.mtim" name="fd_filestat_set_times.mtim"></a> mtim: timestamp
    The desired values of the data modification timestamp.

    -
  • -
  • <a href="#fd_filestat_set_times.fst_flags" name="fd_filestat_set_times.fst_flags"></a> fst_flags: fstflags
    A bitmask indicating which timestamps to adjust.

    -
  • -
-
Results
-
    -
  • <a href="#fd_filestat_set_times.error" name="fd_filestat_set_times.error"></a> error: errno
  • -
-
-

<a href="#fd_pread" name="fd_pread"></a> fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)

-

Read from a file descriptor, without using and updating the file descriptor's offset.
Note: This is similar to preadv in POSIX.

-
Params
-
    -
  • <a href="#fd_pread.fd" name="fd_pread.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_pread.iovs" name="fd_pread.iovs"></a> iovs: iovec_array
    List of scatter/gather vectors in which to store data.

    -
  • -
  • <a href="#fd_pread.offset" name="fd_pread.offset"></a> offset: filesize
    The offset within the file at which to read.

    -
  • -
-
Results
-
    -
  • <a href="#fd_pread.error" name="fd_pread.error"></a> error: errno

    -
  • -
  • <a href="#fd_pread.nread" name="fd_pread.nread"></a> nread: size
    The number of bytes read.

    -
  • -
-
-

<a href="#fd_prestat_get" name="fd_prestat_get"></a> fd_prestat_get(fd: fd) -> (errno, prestat)

-

Return a description of the given preopened file descriptor.

-
Params
-
    -
  • <a href="#fd_prestat_get.fd" name="fd_prestat_get.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_prestat_get.error" name="fd_prestat_get.error"></a> error: errno

    -
  • -
  • <a href="#fd_prestat_get.buf" name="fd_prestat_get.buf"></a> buf: prestat
    The buffer where the description is stored.

    -
  • -
-
-

<a href="#fd_prestat_dir_name" name="fd_prestat_dir_name"></a> fd_prestat_dir_name(fd: fd, path: Pointer<u8>, path_len: size) -> errno

-

Return a description of the given preopened file descriptor.

-
Params
-
    -
  • <a href="#fd_prestat_dir_name.fd" name="fd_prestat_dir_name.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_prestat_dir_name.path" name="fd_prestat_dir_name.path"></a> path: Pointer<u8>
    A buffer into which to write the preopened directory name.

    -
  • -
  • <a href="#fd_prestat_dir_name.path_len" name="fd_prestat_dir_name.path_len"></a> path_len: size

    -
  • -
-
Results
-
    -
  • <a href="#fd_prestat_dir_name.error" name="fd_prestat_dir_name.error"></a> error: errno
  • -
-
-

<a href="#fd_pwrite" name="fd_pwrite"></a> fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)

-

Write to a file descriptor, without using and updating the file descriptor's offset.
Note: This is similar to pwritev in POSIX.

-
Params
-
    -
  • <a href="#fd_pwrite.fd" name="fd_pwrite.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_pwrite.iovs" name="fd_pwrite.iovs"></a> iovs: ciovec_array
    List of scatter/gather vectors from which to retrieve data.

    -
  • -
  • <a href="#fd_pwrite.offset" name="fd_pwrite.offset"></a> offset: filesize
    The offset within the file at which to write.

    -
  • -
-
Results
-
    -
  • <a href="#fd_pwrite.error" name="fd_pwrite.error"></a> error: errno

    -
  • -
  • <a href="#fd_pwrite.nwritten" name="fd_pwrite.nwritten"></a> nwritten: size
    The number of bytes written.

    -
  • -
-
-

<a href="#fd_read" name="fd_read"></a> fd_read(fd: fd, iovs: iovec_array) -> (errno, size)

-

Read from a file descriptor.
Note: This is similar to readv in POSIX.

-
Params
-
    -
  • <a href="#fd_read.fd" name="fd_read.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_read.iovs" name="fd_read.iovs"></a> iovs: iovec_array
    List of scatter/gather vectors to which to store data.

    -
  • -
-
Results
-
    -
  • <a href="#fd_read.error" name="fd_read.error"></a> error: errno

    -
  • -
  • <a href="#fd_read.nread" name="fd_read.nread"></a> nread: size
    The number of bytes read.

    -
  • -
-
- -

Read directory entries from a directory.
When successful, the contents of the output buffer consist of a sequence of
directory entries. Each directory entry consists of a dirent_t object,
followed by dirent_t::d_namlen bytes holding the name of the directory
entry.
This function fills the output buffer as much as possible, potentially
truncating the last directory entry. This allows the caller to grow its
read buffer size in case it's too small to fit a single large directory
entry, or skip the oversized directory entry.

-
Params
-
    -
  • <a href="#fd_readdir.fd" name="fd_readdir.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_readdir.buf" name="fd_readdir.buf"></a> buf: Pointer<u8>
    The buffer where directory entries are stored

    -
  • -
  • <a href="#fd_readdir.buf_len" name="fd_readdir.buf_len"></a> buf_len: size

    -
  • -
  • <a href="#fd_readdir.cookie" name="fd_readdir.cookie"></a> cookie: dircookie
    The location within the directory to start reading

    -
  • -
-
Results
-
    -
  • <a href="#fd_readdir.error" name="fd_readdir.error"></a> error: errno

    -
  • -
  • <a href="#fd_readdir.bufused" name="fd_readdir.bufused"></a> bufused: size
    The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached.

    -
  • -
-
-

<a href="#fd_renumber" name="fd_renumber"></a> fd_renumber(fd: fd, to: fd) -> errno

-

Atomically replace a file descriptor by renumbering another file descriptor.
Due to the strong focus on thread safety, this environment does not provide
a mechanism to duplicate or renumber a file descriptor to an arbitrary
number, like dup2(). This would be prone to race conditions, as an actual
file descriptor with the same number could be allocated by a different
thread at the same time.
This function provides a way to atomically renumber file descriptors, which
would disappear if dup2() were to be removed entirely.

-
Params
-
    -
  • <a href="#fd_renumber.fd" name="fd_renumber.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_renumber.to" name="fd_renumber.to"></a> to: fd
    The file descriptor to overwrite.

    -
  • -
-
Results
-
    -
  • <a href="#fd_renumber.error" name="fd_renumber.error"></a> error: errno
  • -
-
-

<a href="#fd_seek" name="fd_seek"></a> fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)

-

Move the offset of a file descriptor.
Note: This is similar to lseek in POSIX.

-
Params
-
    -
  • <a href="#fd_seek.fd" name="fd_seek.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_seek.offset" name="fd_seek.offset"></a> offset: filedelta
    The number of bytes to move.

    -
  • -
  • <a href="#fd_seek.whence" name="fd_seek.whence"></a> whence: whence
    The base from which the offset is relative.

    -
  • -
-
Results
-
    -
  • <a href="#fd_seek.error" name="fd_seek.error"></a> error: errno

    -
  • -
  • <a href="#fd_seek.newoffset" name="fd_seek.newoffset"></a> newoffset: filesize
    The new offset of the file descriptor, relative to the start of the file.

    -
  • -
-
-

<a href="#fd_sync" name="fd_sync"></a> fd_sync(fd: fd) -> errno

-

Synchronize the data and metadata of a file to disk.
Note: This is similar to fsync in POSIX.

-
Params
-
    -
  • <a href="#fd_sync.fd" name="fd_sync.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_sync.error" name="fd_sync.error"></a> error: errno
  • -
-
-

<a href="#fd_tell" name="fd_tell"></a> fd_tell(fd: fd) -> (errno, filesize)

-

Return the current offset of a file descriptor.
Note: This is similar to lseek(fd, 0, SEEK_CUR) in POSIX.

-
Params
-
    -
  • <a href="#fd_tell.fd" name="fd_tell.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_tell.error" name="fd_tell.error"></a> error: errno

    -
  • -
  • <a href="#fd_tell.offset" name="fd_tell.offset"></a> offset: filesize
    The current offset of the file descriptor, relative to the start of the file.

    -
  • -
-
-

<a href="#fd_write" name="fd_write"></a> fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)

-

Write to a file descriptor.
Note: This is similar to writev in POSIX.

-
Params
-
    -
  • <a href="#fd_write.fd" name="fd_write.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_write.iovs" name="fd_write.iovs"></a> iovs: ciovec_array
    List of scatter/gather vectors from which to retrieve data.

    -
  • -
-
Results
-
    -
  • <a href="#fd_write.error" name="fd_write.error"></a> error: errno

    -
  • -
  • <a href="#fd_write.nwritten" name="fd_write.nwritten"></a> nwritten: size
    The number of bytes written.

    -
  • -
-
-

<a href="#path_create_directory" name="path_create_directory"></a> path_create_directory(fd: fd, path: string) -> errno

-

Create a directory.
Note: This is similar to mkdirat in POSIX.

-
Params
-
    -
  • <a href="#path_create_directory.fd" name="path_create_directory.fd"></a> fd: fd

    -
  • -
  • <a href="#path_create_directory.path" name="path_create_directory.path"></a> path: string
    The path at which to create the directory.

    -
  • -
-
Results
-
    -
  • <a href="#path_create_directory.error" name="path_create_directory.error"></a> error: errno
  • -
-
-

<a href="#path_filestat_get" name="path_filestat_get"></a> path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)

-

Return the attributes of a file or directory.
Note: This is similar to stat in POSIX.

-
Params
-
    -
  • <a href="#path_filestat_get.fd" name="path_filestat_get.fd"></a> fd: fd

    -
  • -
  • <a href="#path_filestat_get.flags" name="path_filestat_get.flags"></a> flags: lookupflags
    Flags determining the method of how the path is resolved.

    -
  • -
  • <a href="#path_filestat_get.path" name="path_filestat_get.path"></a> path: string
    The path of the file or directory to inspect.

    -
  • -
-
Results
-
    -
  • <a href="#path_filestat_get.error" name="path_filestat_get.error"></a> error: errno

    -
  • -
  • <a href="#path_filestat_get.buf" name="path_filestat_get.buf"></a> buf: filestat
    The buffer where the file's attributes are stored.

    -
  • -
-
-

<a href="#path_filestat_set_times" name="path_filestat_set_times"></a> path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno

-

Adjust the timestamps of a file or directory.
Note: This is similar to utimensat in POSIX.

-
Params
-
    -
  • <a href="#path_filestat_set_times.fd" name="path_filestat_set_times.fd"></a> fd: fd

    -
  • -
  • <a href="#path_filestat_set_times.flags" name="path_filestat_set_times.flags"></a> flags: lookupflags
    Flags determining the method of how the path is resolved.

    -
  • -
  • <a href="#path_filestat_set_times.path" name="path_filestat_set_times.path"></a> path: string
    The path of the file or directory to operate on.

    -
  • -
  • <a href="#path_filestat_set_times.atim" name="path_filestat_set_times.atim"></a> atim: timestamp
    The desired values of the data access timestamp.

    -
  • -
  • <a href="#path_filestat_set_times.mtim" name="path_filestat_set_times.mtim"></a> mtim: timestamp
    The desired values of the data modification timestamp.

    -
  • -
  • <a href="#path_filestat_set_times.fst_flags" name="path_filestat_set_times.fst_flags"></a> fst_flags: fstflags
    A bitmask indicating which timestamps to adjust.

    -
  • -
-
Results
-
    -
  • <a href="#path_filestat_set_times.error" name="path_filestat_set_times.error"></a> error: errno
  • -
-
- -

Create a hard link.
Note: This is similar to linkat in POSIX.

-
Params
-
    -
  • <a href="#path_link.old_fd" name="path_link.old_fd"></a> old_fd: fd

    -
  • -
  • <a href="#path_link.old_flags" name="path_link.old_flags"></a> old_flags: lookupflags
    Flags determining the method of how the path is resolved.

    -
  • -
  • <a href="#path_link.old_path" name="path_link.old_path"></a> old_path: string
    The source path from which to link.

    -
  • -
  • <a href="#path_link.new_fd" name="path_link.new_fd"></a> new_fd: fd
    The working directory at which the resolution of the new path starts.

    -
  • -
  • <a href="#path_link.new_path" name="path_link.new_path"></a> new_path: string
    The destination path at which to create the hard link.

    -
  • -
-
Results
-
    -
  • <a href="#path_link.error" name="path_link.error"></a> error: errno
  • -
-
-

<a href="#path_open" name="path_open"></a> path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)

-

Open a file or directory.
The returned file descriptor is not guaranteed to be the lowest-numbered
file descriptor not currently open; it is randomized to prevent
applications from depending on making assumptions about indexes, since this
is error-prone in multi-threaded contexts. The returned file descriptor is
guaranteed to be less than 2**31.
Note: This is similar to openat in POSIX.

-
Params
-
    -
  • <a href="#path_open.fd" name="path_open.fd"></a> fd: fd

    -
  • -
  • <a href="#path_open.dirflags" name="path_open.dirflags"></a> dirflags: lookupflags
    Flags determining the method of how the path is resolved.

    -
  • -
  • <a href="#path_open.path" name="path_open.path"></a> path: string
    The relative path of the file or directory to open, relative to the
    path_open::fd directory.

    -
  • -
  • <a href="#path_open.oflags" name="path_open.oflags"></a> oflags: oflags
    The method by which to open the file.

    -
  • -
  • <a href="#path_open.fs_rights_base" name="path_open.fs_rights_base"></a> fs_rights_base: rights
    The initial rights of the newly created file descriptor. The
    implementation is allowed to return a file descriptor with fewer rights
    than specified, if and only if those rights do not apply to the type of
    file being opened.
    The base rights are rights that will apply to operations using the file
    descriptor itself, while the inheriting rights are rights that apply to
    file descriptors derived from it.

    -
  • -
  • <a href="#path_open.fs_rights_inherting" name="path_open.fs_rights_inherting"></a> fs_rights_inherting: rights

    -
  • -
  • <a href="#path_open.fdflags" name="path_open.fdflags"></a> fdflags: fdflags

    -
  • -
-
Results
-
    -
  • <a href="#path_open.error" name="path_open.error"></a> error: errno

    -
  • -
  • <a href="#path_open.opened_fd" name="path_open.opened_fd"></a> opened_fd: fd
    The file descriptor of the file that has been opened.

    -
  • -
-
- -

Read the contents of a symbolic link.
Note: This is similar to readlinkat in POSIX.

-
Params
-
    -
  • <a href="#path_readlink.fd" name="path_readlink.fd"></a> fd: fd

    -
  • -
  • <a href="#path_readlink.path" name="path_readlink.path"></a> path: string
    The path of the symbolic link from which to read.

    -
  • -
  • <a href="#path_readlink.buf" name="path_readlink.buf"></a> buf: Pointer<u8>
    The buffer to which to write the contents of the symbolic link.

    -
  • -
  • <a href="#path_readlink.buf_len" name="path_readlink.buf_len"></a> buf_len: size

    -
  • -
-
Results
-
    -
  • <a href="#path_readlink.error" name="path_readlink.error"></a> error: errno

    -
  • -
  • <a href="#path_readlink.bufused" name="path_readlink.bufused"></a> bufused: size
    The number of bytes placed in the buffer.

    -
  • -
-
-

<a href="#path_remove_directory" name="path_remove_directory"></a> path_remove_directory(fd: fd, path: string) -> errno

-

Remove a directory.
Return errno::notempty if the directory is not empty.
Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

-
Params
-
    -
  • <a href="#path_remove_directory.fd" name="path_remove_directory.fd"></a> fd: fd

    -
  • -
  • <a href="#path_remove_directory.path" name="path_remove_directory.path"></a> path: string
    The path to a directory to remove.

    -
  • -
-
Results
-
    -
  • <a href="#path_remove_directory.error" name="path_remove_directory.error"></a> error: errno
  • -
-
-

<a href="#path_rename" name="path_rename"></a> path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno

-

Rename a file or directory.
Note: This is similar to renameat in POSIX.

-
Params
-
    -
  • <a href="#path_rename.fd" name="path_rename.fd"></a> fd: fd

    -
  • -
  • <a href="#path_rename.old_path" name="path_rename.old_path"></a> old_path: string
    The source path of the file or directory to rename.

    -
  • -
  • <a href="#path_rename.new_fd" name="path_rename.new_fd"></a> new_fd: fd
    The working directory at which the resolution of the new path starts.

    -
  • -
  • <a href="#path_rename.new_path" name="path_rename.new_path"></a> new_path: string
    The destination path to which to rename the file or directory.

    -
  • -
-
Results
-
    -
  • <a href="#path_rename.error" name="path_rename.error"></a> error: errno
  • -
-
- -

Create a symbolic link.
Note: This is similar to symlinkat in POSIX.

-
Params
-
    -
  • <a href="#path_symlink.old_path" name="path_symlink.old_path"></a> old_path: string
    The contents of the symbolic link.

    -
  • -
  • <a href="#path_symlink.fd" name="path_symlink.fd"></a> fd: fd

    -
  • -
  • <a href="#path_symlink.new_path" name="path_symlink.new_path"></a> new_path: string
    The destination path at which to create the symbolic link.

    -
  • -
-
Results
-
    -
  • <a href="#path_symlink.error" name="path_symlink.error"></a> error: errno
  • -
-
- -

Unlink a file.
Return errno::isdir if the path refers to a directory.
Note: This is similar to unlinkat(fd, path, 0) in POSIX.

-
Params
-
    -
  • <a href="#path_unlink_file.fd" name="path_unlink_file.fd"></a> fd: fd

    -
  • -
  • <a href="#path_unlink_file.path" name="path_unlink_file.path"></a> path: string
    The path to a file to unlink.

    -
  • -
-
Results
-
    -
  • <a href="#path_unlink_file.error" name="path_unlink_file.error"></a> error: errno
  • -
-
-

<a href="#poll_oneoff" name="poll_oneoff"></a> poll_oneoff(in: ConstPointer<subscription>, out: Pointer<event>, nsubscriptions: size) -> (errno, size)

-

Concurrently poll for the occurrence of a set of events.

-
Params
-
    -
  • <a href="#poll_oneoff.in" name="poll_oneoff.in"></a> in: ConstPointer<subscription>
    The events to which to subscribe.

    -
  • -
  • <a href="#poll_oneoff.out" name="poll_oneoff.out"></a> out: Pointer<event>
    The events that have occurred.

    -
  • -
  • <a href="#poll_oneoff.nsubscriptions" name="poll_oneoff.nsubscriptions"></a> nsubscriptions: size
    Both the number of subscriptions and events.

    -
  • -
-
Results
-
    -
  • <a href="#poll_oneoff.error" name="poll_oneoff.error"></a> error: errno

    -
  • -
  • <a href="#poll_oneoff.nevents" name="poll_oneoff.nevents"></a> nevents: size
    The number of events stored.

    -
  • -
-
-

<a href="#proc_exit" name="proc_exit"></a> proc_exit(rval: exitcode)

-

Terminate the process normally. An exit code of 0 indicates successful
termination of the program. The meanings of other values is dependent on
the environment.

-
Params
-
    -
  • <a href="#proc_exit.rval" name="proc_exit.rval"></a> rval: exitcode
    The exit code returned by the process.
  • -
-
Results
-
-

<a href="#proc_raise" name="proc_raise"></a> proc_raise(sig: signal) -> errno

-

Send a signal to the process of the calling thread.
Note: This is similar to raise in POSIX.

-
Params
-
    -
  • <a href="#proc_raise.sig" name="proc_raise.sig"></a> sig: signal
    The signal condition to trigger.
  • -
-
Results
-
    -
  • <a href="#proc_raise.error" name="proc_raise.error"></a> error: errno
  • -
-
-

<a href="#sched_yield" name="sched_yield"></a> sched_yield() -> errno

-

Temporarily yield execution of the calling thread.
Note: This is similar to sched_yield in POSIX.

-
Params
-
Results
-
    -
  • <a href="#sched_yield.error" name="sched_yield.error"></a> error: errno
  • -
-
-

<a href="#random_get" name="random_get"></a> random_get(buf: Pointer<u8>, buf_len: size) -> errno

-

Write high-quality random data into a buffer.
This function blocks when the implementation is unable to immediately
provide sufficient high-quality random data.
This function may execute slowly, so when large mounts of random data are
required, it's advisable to use this function to seed a pseudo-random
number generator, rather than to provide the random data directly.

-
Params
-
    -
  • <a href="#random_get.buf" name="random_get.buf"></a> buf: Pointer<u8>
    The buffer to fill with random data.

    -
  • -
  • <a href="#random_get.buf_len" name="random_get.buf_len"></a> buf_len: size

    -
  • -
-
Results
-
    -
  • <a href="#random_get.error" name="random_get.error"></a> error: errno
  • -
-
-

<a href="#sock_recv" name="sock_recv"></a> sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)

-

Receive a message from a socket.
Note: This is similar to recv in POSIX, though it also supports reading
the data into multiple buffers in the manner of readv.

-
Params
-
    -
  • <a href="#sock_recv.fd" name="sock_recv.fd"></a> fd: fd

    -
  • -
  • <a href="#sock_recv.ri_data" name="sock_recv.ri_data"></a> ri_data: iovec_array
    List of scatter/gather vectors to which to store data.

    -
  • -
  • <a href="#sock_recv.ri_flags" name="sock_recv.ri_flags"></a> ri_flags: riflags
    Message flags.

    -
  • -
-
Results
-
    -
  • <a href="#sock_recv.error" name="sock_recv.error"></a> error: errno

    -
  • -
  • <a href="#sock_recv.ro_datalen" name="sock_recv.ro_datalen"></a> ro_datalen: size
    Number of bytes stored in ri_data.

    -
  • -
  • <a href="#sock_recv.ro_flags" name="sock_recv.ro_flags"></a> ro_flags: roflags
    Message flags.

    -
  • -
-
-

<a href="#sock_send" name="sock_send"></a> sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)

-

Send a message on a socket.
Note: This is similar to send in POSIX, though it also supports writing
the data from multiple buffers in the manner of writev.

-
Params
-
    -
  • <a href="#sock_send.fd" name="sock_send.fd"></a> fd: fd

    -
  • -
  • <a href="#sock_send.si_data" name="sock_send.si_data"></a> si_data: ciovec_array
    List of scatter/gather vectors to which to retrieve data

    -
  • -
  • <a href="#sock_send.si_flags" name="sock_send.si_flags"></a> si_flags: siflags
    Message flags.

    -
  • -
-
Results
-
    -
  • <a href="#sock_send.error" name="sock_send.error"></a> error: errno

    -
  • -
  • <a href="#sock_send.so_datalen" name="sock_send.so_datalen"></a> so_datalen: size
    Number of bytes transmitted.

    -
  • -
-
-

<a href="#sock_shutdown" name="sock_shutdown"></a> sock_shutdown(fd: fd, how: sdflags) -> errno

-

Shut down socket send and receive channels.
Note: This is similar to shutdown in POSIX.

-
Params
-
    -
  • <a href="#sock_shutdown.fd" name="sock_shutdown.fd"></a> fd: fd

    -
  • -
  • <a href="#sock_shutdown.how" name="sock_shutdown.how"></a> how: sdflags
    Which channels on the socket to shut down.

    -
  • -
-
Results
-
    -
  • <a href="#sock_shutdown.error" name="sock_shutdown.error"></a> error: errno
  • -
diff --git a/proposals/filesystem/phases/snapshot/docs.md b/proposals/filesystem/phases/snapshot/docs.md deleted file mode 100644 index 44c3c35f2..000000000 --- a/proposals/filesystem/phases/snapshot/docs.md +++ /dev/null @@ -1,2509 +0,0 @@ -# Types -## `size`: `u32` - -Size: 4 - -Alignment: 4 - -## `filesize`: `u64` -Non-negative file size or length of a region within a file. - -Size: 8 - -Alignment: 8 - -## `timestamp`: `u64` -Timestamp in nanoseconds. - -Size: 8 - -Alignment: 8 - -## `clockid`: `Variant` -Identifiers for clocks. - -Size: 4 - -Alignment: 4 - -### Variant cases -- `realtime` -The clock measuring real time. Time value zero corresponds with -1970-01-01T00:00:00Z. - -- `monotonic` -The store-wide monotonic clock, which is defined as a clock measuring -real time, whose value cannot be adjusted and which cannot have negative -clock jumps. The epoch of this clock is undefined. The absolute time -value of this clock therefore has no meaning. - -- `process_cputime_id` -The CPU-time clock associated with the current process. - -- `thread_cputime_id` -The CPU-time clock associated with the current thread. - -## `errno`: `Variant` -Error codes returned by functions. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX. - -Size: 2 - -Alignment: 2 - -### Variant cases -- `success` -No error occurred. System call completed successfully. - -- `2big` -Argument list too long. - -- `acces` -Permission denied. - -- `addrinuse` -Address in use. - -- `addrnotavail` -Address not available. - -- `afnosupport` -Address family not supported. - -- `again` -Resource unavailable, or operation would block. - -- `already` -Connection already in progress. - -- `badf` -Bad file descriptor. - -- `badmsg` -Bad message. - -- `busy` -Device or resource busy. - -- `canceled` -Operation canceled. - -- `child` -No child processes. - -- `connaborted` -Connection aborted. - -- `connrefused` -Connection refused. - -- `connreset` -Connection reset. - -- `deadlk` -Resource deadlock would occur. - -- `destaddrreq` -Destination address required. - -- `dom` -Mathematics argument out of domain of function. - -- `dquot` -Reserved. - -- `exist` -File exists. - -- `fault` -Bad address. - -- `fbig` -File too large. - -- `hostunreach` -Host is unreachable. - -- `idrm` -Identifier removed. - -- `ilseq` -Illegal byte sequence. - -- `inprogress` -Operation in progress. - -- `intr` -Interrupted function. - -- `inval` -Invalid argument. - -- `io` -I/O error. - -- `isconn` -Socket is connected. - -- `isdir` -Is a directory. - -- `loop` -Too many levels of symbolic links. - -- `mfile` -File descriptor value too large. - -- `mlink` -Too many links. - -- `msgsize` -Message too large. - -- `multihop` -Reserved. - -- `nametoolong` -Filename too long. - -- `netdown` -Network is down. - -- `netreset` -Connection aborted by network. - -- `netunreach` -Network unreachable. - -- `nfile` -Too many files open in system. - -- `nobufs` -No buffer space available. - -- `nodev` -No such device. - -- `noent` -No such file or directory. - -- `noexec` -Executable file format error. - -- `nolck` -No locks available. - -- `nolink` -Reserved. - -- `nomem` -Not enough space. - -- `nomsg` -No message of the desired type. - -- `noprotoopt` -Protocol not available. - -- `nospc` -No space left on device. - -- `nosys` -Function not supported. - -- `notconn` -The socket is not connected. - -- `notdir` -Not a directory or a symbolic link to a directory. - -- `notempty` -Directory not empty. - -- `notrecoverable` -State not recoverable. - -- `notsock` -Not a socket. - -- `notsup` -Not supported, or operation not supported on socket. - -- `notty` -Inappropriate I/O control operation. - -- `nxio` -No such device or address. - -- `overflow` -Value too large to be stored in data type. - -- `ownerdead` -Previous owner died. - -- `perm` -Operation not permitted. - -- `pipe` -Broken pipe. - -- `proto` -Protocol error. - -- `protonosupport` -Protocol not supported. - -- `prototype` -Protocol wrong type for socket. - -- `range` -Result too large. - -- `rofs` -Read-only file system. - -- `spipe` -Invalid seek. - -- `srch` -No such process. - -- `stale` -Reserved. - -- `timedout` -Connection timed out. - -- `txtbsy` -Text file busy. - -- `xdev` -Cross-device link. - -- `notcapable` -Extension: Capabilities insufficient. - -## `rights`: `Record` -File descriptor rights, determining which actions may be performed. - -Size: 8 - -Alignment: 8 - -### Record members -- `fd_datasync`: `bool` -The right to invoke [`fd_datasync`](#fd_datasync). -If [`path_open`](#path_open) is set, includes the right to invoke -[`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). - -Bit: 0 - -- `fd_read`: `bool` -The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). - -Bit: 1 - -- `fd_seek`: `bool` -The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). - -Bit: 2 - -- `fd_fdstat_set_flags`: `bool` -The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). - -Bit: 3 - -- `fd_sync`: `bool` -The right to invoke [`fd_sync`](#fd_sync). -If [`path_open`](#path_open) is set, includes the right to invoke -[`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - -Bit: 4 - -- `fd_tell`: `bool` -The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset -remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to -invoke [`fd_tell`](#fd_tell). - -Bit: 5 - -- `fd_write`: `bool` -The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). - -Bit: 6 - -- `fd_advise`: `bool` -The right to invoke [`fd_advise`](#fd_advise). - -Bit: 7 - -- `fd_allocate`: `bool` -The right to invoke [`fd_allocate`](#fd_allocate). - -Bit: 8 - -- `path_create_directory`: `bool` -The right to invoke [`path_create_directory`](#path_create_directory). - -Bit: 9 - -- `path_create_file`: `bool` -If [`path_open`](#path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). - -Bit: 10 - -- `path_link_source`: `bool` -The right to invoke [`path_link`](#path_link) with the file descriptor as the -source directory. - -Bit: 11 - -- `path_link_target`: `bool` -The right to invoke [`path_link`](#path_link) with the file descriptor as the -target directory. - -Bit: 12 - -- `path_open`: `bool` -The right to invoke [`path_open`](#path_open). - -Bit: 13 - -- `fd_readdir`: `bool` -The right to invoke [`fd_readdir`](#fd_readdir). - -Bit: 14 - -- `path_readlink`: `bool` -The right to invoke [`path_readlink`](#path_readlink). - -Bit: 15 - -- `path_rename_source`: `bool` -The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. - -Bit: 16 - -- `path_rename_target`: `bool` -The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. - -Bit: 17 - -- `path_filestat_get`: `bool` -The right to invoke [`path_filestat_get`](#path_filestat_get). - -Bit: 18 - -- `path_filestat_set_size`: `bool` -The right to change a file's size (there is no `path_filestat_set_size`). -If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). - -Bit: 19 - -- `path_filestat_set_times`: `bool` -The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). - -Bit: 20 - -- `fd_filestat_get`: `bool` -The right to invoke [`fd_filestat_get`](#fd_filestat_get). - -Bit: 21 - -- `fd_filestat_set_size`: `bool` -The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). - -Bit: 22 - -- `fd_filestat_set_times`: `bool` -The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). - -Bit: 23 - -- `path_symlink`: `bool` -The right to invoke [`path_symlink`](#path_symlink). - -Bit: 24 - -- `path_remove_directory`: `bool` -The right to invoke [`path_remove_directory`](#path_remove_directory). - -Bit: 25 - -- `path_unlink_file`: `bool` -The right to invoke [`path_unlink_file`](#path_unlink_file). - -Bit: 26 - -- `poll_fd_readwrite`: `bool` -If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). -If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). - -Bit: 27 - -- `sock_shutdown`: `bool` -The right to invoke [`sock_shutdown`](#sock_shutdown). - -Bit: 28 - -## `fd`: `Handle` -A file descriptor handle. - -Size: 4 - -Alignment: 4 - -### Supertypes -## `iovec`: `Record` -A region of memory for scatter/gather reads. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `Pointer` -The address of the buffer to be filled. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be filled. - -Offset: 4 - -## `ciovec`: `Record` -A region of memory for scatter/gather writes. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `ConstPointer` -The address of the buffer to be written. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be written. - -Offset: 4 - -## `iovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `ciovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `filedelta`: `s64` -Relative offset within a file. - -Size: 8 - -Alignment: 8 - -## `whence`: `Variant` -The position relative to which to set the offset of the file descriptor. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `set` -Seek relative to start-of-file. - -- `cur` -Seek relative to current position. - -- `end` -Seek relative to end-of-file. - -## `dircookie`: `u64` -A reference to the offset of a directory entry. - -The value 0 signifies the start of the directory. - -Size: 8 - -Alignment: 8 - -## `dirnamlen`: `u32` -The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent) struct. - -Size: 4 - -Alignment: 4 - -## `inode`: `u64` -File serial number that is unique within its file system. - -Size: 8 - -Alignment: 8 - -## `filetype`: `Variant` -The type of a file descriptor or file. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `unknown` -The type of the file descriptor or file is unknown or is different from any of the other types specified. - -- `block_device` -The file descriptor or file refers to a block device inode. - -- `character_device` -The file descriptor or file refers to a character device inode. - -- `directory` -The file descriptor or file refers to a directory inode. - -- `regular_file` -The file descriptor or file refers to a regular file inode. - -- `socket_dgram` -The file descriptor or file refers to a datagram socket. - -- `socket_stream` -The file descriptor or file refers to a byte-stream socket. - -- `symbolic_link` -The file refers to a symbolic link inode. - -## `dirent`: `Record` -A directory entry. - -Size: 24 - -Alignment: 8 - -### Record members -- `d_next`: [`dircookie`](#dircookie) -The offset of the next directory entry stored in this directory. - -Offset: 0 - -- `d_ino`: [`inode`](#inode) -The serial number of the file referred to by this directory entry. - -Offset: 8 - -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. - -Offset: 16 - -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. - -Offset: 20 - -## `advice`: `Variant` -File or memory access pattern advisory information. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `normal` -The application has no advice to give on its behavior with respect to the specified data. - -- `sequential` -The application expects to access the specified data sequentially from lower offsets to higher offsets. - -- `random` -The application expects to access the specified data in a random order. - -- `willneed` -The application expects to access the specified data in the near future. - -- `dontneed` -The application expects that it will not access the specified data in the near future. - -- `noreuse` -The application expects to access the specified data once and then not reuse it thereafter. - -## `fdflags`: `Record` -File descriptor flags. - -Size: 2 - -Alignment: 2 - -### Record members -- `append`: `bool` -Append mode: Data written to the file is always appended to the file's end. - -Bit: 0 - -- `dsync`: `bool` -Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - -Bit: 1 - -- `nonblock`: `bool` -Non-blocking mode. - -Bit: 2 - -- `rsync`: `bool` -Synchronized read I/O operations. - -Bit: 3 - -- `sync`: `bool` -Write according to synchronized I/O file integrity completion. In -addition to synchronizing the data stored in the file, the implementation -may also synchronously update the file's metadata. - -Bit: 4 - -## `fdstat`: `Record` -File descriptor attributes. - -Size: 24 - -Alignment: 8 - -### Record members -- `fs_filetype`: [`filetype`](#filetype) -File type. - -Offset: 0 - -- `fs_flags`: [`fdflags`](#fdflags) -File descriptor flags. - -Offset: 2 - -- `fs_rights_base`: [`rights`](#rights) -Rights that apply to this file descriptor. - -Offset: 8 - -- `fs_rights_inheriting`: [`rights`](#rights) -Maximum set of rights that may be installed on new file descriptors that -are created through this file descriptor, e.g., through [`path_open`](#path_open). - -Offset: 16 - -## `device`: `u64` -Identifier for a device containing a file system. Can be used in combination -with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. - -Size: 8 - -Alignment: 8 - -## `fstflags`: `Record` -Which file time attributes to adjust. - -Size: 2 - -Alignment: 2 - -### Record members -- `atim`: `bool` -Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - -Bit: 0 - -- `atim_now`: `bool` -Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 1 - -- `mtim`: `bool` -Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - -Bit: 2 - -- `mtim_now`: `bool` -Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 3 - -## `lookupflags`: `Record` -Flags determining the method of how paths are resolved. - -Size: 4 - -Alignment: 4 - -### Record members -- `symlink_follow`: `bool` -As long as the resolved path corresponds to a symbolic link, it is expanded. - -Bit: 0 - -## `oflags`: `Record` -Open flags used by [`path_open`](#path_open). - -Size: 2 - -Alignment: 2 - -### Record members -- `creat`: `bool` -Create file if it does not exist. - -Bit: 0 - -- `directory`: `bool` -Fail if not a directory. - -Bit: 1 - -- `excl`: `bool` -Fail if file already exists. - -Bit: 2 - -- `trunc`: `bool` -Truncate file to size 0. - -Bit: 3 - -## `linkcount`: `u64` -Number of hard links to an inode. - -Size: 8 - -Alignment: 8 - -## `filestat`: `Record` -File attributes. - -Size: 64 - -Alignment: 8 - -### Record members -- `dev`: [`device`](#device) -Device ID of device containing the file. - -Offset: 0 - -- `ino`: [`inode`](#inode) -File serial number. - -Offset: 8 - -- `filetype`: [`filetype`](#filetype) -File type. - -Offset: 16 - -- `nlink`: [`linkcount`](#linkcount) -Number of hard links to the file. - -Offset: 24 - -- `size`: [`filesize`](#filesize) -For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - -Offset: 32 - -- `atim`: [`timestamp`](#timestamp) -Last data access timestamp. - -Offset: 40 - -- `mtim`: [`timestamp`](#timestamp) -Last data modification timestamp. - -Offset: 48 - -- `ctim`: [`timestamp`](#timestamp) -Last file status change timestamp. - -Offset: 56 - -## `userdata`: `u64` -User-provided value that may be attached to objects that is retained when -extracted from the implementation. - -Size: 8 - -Alignment: 8 - -## `eventtype`: `Variant` -Type of a subscription to an event or its occurrence. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `clock` -The time value of clock [`subscription_clock::id`](#subscription_clock.id) has -reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - -- `fd_read` -File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has data -available for reading. This event always triggers for regular files. - -- `fd_write` -File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity -available for writing. This event always triggers for regular files. - -## `eventrwflags`: `Record` -The state of the file descriptor subscribed to with -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 2 - -Alignment: 2 - -### Record members -- `fd_readwrite_hangup`: `bool` -The peer of this socket has closed or disconnected. - -Bit: 0 - -## `event_fd_readwrite`: `Record` -The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). - -Size: 16 - -Alignment: 8 - -### Record members -- `nbytes`: [`filesize`](#filesize) -The number of bytes available for reading or writing. - -Offset: 0 - -- `flags`: [`eventrwflags`](#eventrwflags) -The state of the file descriptor. - -Offset: 8 - -## `event`: `Record` -An event that occurred. - -Size: 32 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). - -Offset: 0 - -- `error`: [`errno`](#errno) -If non-zero, an error that occurred while processing the subscription request. - -Offset: 8 - -- `type`: [`eventtype`](#eventtype) -The type of event that occured - -Offset: 10 - -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. - -Offset: 16 - -## `subclockflags`: `Record` -Flags determining how to interpret the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout). - -Size: 2 - -Alignment: 2 - -### Record members -- `subscription_clock_abstime`: `bool` -If set, treat the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock -[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp -provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the -current time value of clock [`subscription_clock::id`](#subscription_clock.id). - -Bit: 0 - -## `subscription_clock`: `Record` -The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). - -Size: 32 - -Alignment: 8 - -### Record members -- `id`: [`clockid`](#clockid) -The clock against which to compare the timestamp. - -Offset: 0 - -- `timeout`: [`timestamp`](#timestamp) -The absolute or relative timestamp. - -Offset: 8 - -- `precision`: [`timestamp`](#timestamp) -The amount of time that the implementation may wait additionally -to coalesce with other events. - -Offset: 16 - -- `flags`: [`subclockflags`](#subclockflags) -Flags specifying whether the timeout is absolute or relative - -Offset: 24 - -## `subscription_fd_readwrite`: `Record` -The contents of a [`subscription`](#subscription) when type is type is -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 4 - -Alignment: 4 - -### Record members -- `file_descriptor`: [`fd`](#fd) -The file descriptor on which to wait for it to become ready for reading or writing. - -Offset: 0 - -## `subscription_u`: `Variant` -The contents of a [`subscription`](#subscription). - -Size: 40 - -Alignment: 8 - -### Variant Layout -- size: 40 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock`: [`subscription_clock`](#subscription_clock) - -- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -## `subscription`: `Record` -Subscription to an event. - -Size: 48 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that is attached to the subscription in the -implementation and returned through [`event::userdata`](#event.userdata). - -Offset: 0 - -- `u`: [`subscription_u`](#subscription_u) -The type of the event to which to subscribe, and its contents - -Offset: 8 - -## `exitcode`: `u32` -Exit code generated by a process when exiting. - -Size: 4 - -Alignment: 4 - -## `signal`: `Variant` -Signal condition. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `none` -No signal. Note that POSIX has special semantics for `kill(pid, 0)`, -so this value is reserved. - -- `hup` -Hangup. -Action: Terminates the process. - -- `int` -Terminate interrupt signal. -Action: Terminates the process. - -- `quit` -Terminal quit signal. -Action: Terminates the process. - -- `ill` -Illegal instruction. -Action: Terminates the process. - -- `trap` -Trace/breakpoint trap. -Action: Terminates the process. - -- `abrt` -Process abort signal. -Action: Terminates the process. - -- `bus` -Access to an undefined portion of a memory object. -Action: Terminates the process. - -- `fpe` -Erroneous arithmetic operation. -Action: Terminates the process. - -- `kill` -Kill. -Action: Terminates the process. - -- `usr1` -User-defined signal 1. -Action: Terminates the process. - -- `segv` -Invalid memory reference. -Action: Terminates the process. - -- `usr2` -User-defined signal 2. -Action: Terminates the process. - -- `pipe` -Write on a pipe with no one to read it. -Action: Ignored. - -- `alrm` -Alarm clock. -Action: Terminates the process. - -- `term` -Termination signal. -Action: Terminates the process. - -- `chld` -Child process terminated, stopped, or continued. -Action: Ignored. - -- `cont` -Continue executing, if stopped. -Action: Continues executing, if stopped. - -- `stop` -Stop executing. -Action: Stops executing. - -- `tstp` -Terminal stop signal. -Action: Stops executing. - -- `ttin` -Background process attempting read. -Action: Stops executing. - -- `ttou` -Background process attempting write. -Action: Stops executing. - -- `urg` -High bandwidth data is available at a socket. -Action: Ignored. - -- `xcpu` -CPU time limit exceeded. -Action: Terminates the process. - -- `xfsz` -File size limit exceeded. -Action: Terminates the process. - -- `vtalrm` -Virtual timer expired. -Action: Terminates the process. - -- `prof` -Profiling timer expired. -Action: Terminates the process. - -- `winch` -Window changed. -Action: Ignored. - -- `poll` -I/O possible. -Action: Terminates the process. - -- `pwr` -Power failure. -Action: Terminates the process. - -- `sys` -Bad system call. -Action: Terminates the process. - -## `riflags`: `Record` -Flags provided to [`sock_recv`](#sock_recv). - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_peek`: `bool` -Returns the message without removing it from the socket's receive queue. - -Bit: 0 - -- `recv_waitall`: `bool` -On byte-stream sockets, block until the full amount of data can be returned. - -Bit: 1 - -## `roflags`: `Record` -Flags returned by [`sock_recv`](#sock_recv). - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_data_truncated`: `bool` -Returned by [`sock_recv`](#sock_recv): Message data has been truncated. - -Bit: 0 - -## `siflags`: `u16` -Flags provided to [`sock_send`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Size: 2 - -Alignment: 2 - -## `sdflags`: `Record` -Which channels on a socket to shut down. - -Size: 1 - -Alignment: 1 - -### Record members -- `rd`: `bool` -Disables further receive operations. - -Bit: 0 - -- `wr`: `bool` -Disables further send operations. - -Bit: 1 - -## `preopentype`: `Variant` -Identifiers for preopened capabilities. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `dir` -A pre-opened directory. - -## `prestat_dir`: `Record` -The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). - -Size: 4 - -Alignment: 4 - -### Record members -- `pr_name_len`: [`size`](#size) -The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). - -Offset: 0 - -## `prestat`: `Variant` -Information about a pre-opened capability. - -Size: 8 - -Alignment: 4 - -### Variant Layout -- size: 8 -- align: 4 -- tag_size: 1 -### Variant cases -- `dir`: [`prestat_dir`](#prestat_dir) - -# Modules -## wasi_snapshot_preview1 -### Imports -#### Memory -### Functions - ---- - -#### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` -Read command-line argument data. -The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get). -Each argument is expected to be `\0` terminated. - -##### Params -- `argv`: `Pointer>` - -- `argv_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `args_sizes_get() -> Result<(size, size), errno>` -Return command-line argument data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of arguments and the size of the argument string -data, or an error. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` -Read environment variable data. -The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). -Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - -##### Params -- `environ`: `Pointer>` - -- `environ_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `environ_sizes_get() -> Result<(size, size), errno>` -Return environment variable data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of environment variable arguments and the size of the -environment variable data. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `clock_res_get(id: clockid) -> Result` -Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, -return [`errno::inval`](#errno.inval). -Note: This is similar to `clock_getres` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the resolution. - -##### Results -- `error`: `Result` -The resolution of the clock, or an error if one happened. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `clock_time_get(id: clockid, precision: timestamp) -> Result` -Return the time value of a clock. -Note: This is similar to `clock_gettime` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the time. - -- `precision`: [`timestamp`](#timestamp) -The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - -##### Results -- `error`: `Result` -The time value of the clock. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` -Provide file advisory information on a file descriptor. -Note: This is similar to `posix_fadvise` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset within the file to which the advisory applies. - -- `len`: [`filesize`](#filesize) -The length of the region to which the advisory applies. - -- `advice`: [`advice`](#advice) -The advice. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` -Force the allocation of space in a file. -Note: This is similar to `posix_fallocate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset at which to start the allocation. - -- `len`: [`filesize`](#filesize) -The length of the area that is allocated. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_close(fd: fd) -> Result<(), errno>` -Close a file descriptor. -Note: This is similar to `close` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_datasync(fd: fd) -> Result<(), errno>` -Synchronize the data of a file to disk. -Note: This is similar to `fdatasync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_get(fd: fd) -> Result` -Get the attributes of a file descriptor. -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file descriptor's attributes are stored. - -###### Variant Layout -- size: 32 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`fdstat`](#fdstat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` -Adjust the flags associated with a file descriptor. -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`fdflags`](#fdflags) -The desired values of the file descriptor flags. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` -Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights - -##### Params -- `fd`: [`fd`](#fd) - -- `fs_rights_base`: [`rights`](#rights) -The desired rights of the file descriptor. - -- `fs_rights_inheriting`: [`rights`](#rights) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_get(fd: fd) -> Result` -Return the attributes of an open file. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 72 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` -Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. -Note: This is similar to `ftruncate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `size`: [`filesize`](#filesize) -The desired file size. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of an open file or directory. -Note: This is similar to `futimens` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` -Read from a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `preadv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors in which to store data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to read. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_prestat_get(fd: fd) -> Result` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the description is stored. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`prestat`](#prestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `Pointer` -A buffer into which to write the preopened directory name. - -- `path_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` -Write to a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `pwritev` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to write. - -##### Results -- `error`: `Result` -The number of bytes written. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_read(fd: fd, iovs: iovec_array) -> Result` -Read from a file descriptor. -Note: This is similar to `readv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` -Read directory entries from a directory. -When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a [`dirent`](#dirent) object, -followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory -entry. -This function fills the output buffer as much as possible, potentially -truncating the last directory entry. This allows the caller to grow its -read buffer size in case it's too small to fit a single large directory -entry, or skip the oversized directory entry. - -##### Params -- `fd`: [`fd`](#fd) - -- `buf`: `Pointer` -The buffer where directory entries are stored - -- `buf_len`: [`size`](#size) - -- `cookie`: [`dircookie`](#dircookie) -The location within the directory to start reading - -##### Results -- `error`: `Result` -The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_renumber(fd: fd, to: fd) -> Result<(), errno>` -Atomically replace a file descriptor by renumbering another file descriptor. -Due to the strong focus on thread safety, this environment does not provide -a mechanism to duplicate or renumber a file descriptor to an arbitrary -number, like `dup2()`. This would be prone to race conditions, as an actual -file descriptor with the same number could be allocated by a different -thread at the same time. -This function provides a way to atomically renumber file descriptors, which -would disappear if `dup2()` were to be removed entirely. - -##### Params -- `fd`: [`fd`](#fd) - -- `to`: [`fd`](#fd) -The file descriptor to overwrite. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> Result` -Move the offset of a file descriptor. -Note: This is similar to `lseek` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filedelta`](#filedelta) -The number of bytes to move. - -- `whence`: [`whence`](#whence) -The base from which the offset is relative. - -##### Results -- `error`: `Result` -The new offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_sync(fd: fd) -> Result<(), errno>` -Synchronize the data and metadata of a file to disk. -Note: This is similar to `fsync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_tell(fd: fd) -> Result` -Return the current offset of a file descriptor. -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The current offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_write(fd: fd, iovs: ciovec_array) -> Result` -Write to a file descriptor. -Note: This is similar to `writev` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -##### Results -- `error`: `Result` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_create_directory(fd: fd, path: string) -> Result<(), errno>` -Create a directory. -Note: This is similar to `mkdirat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path at which to create the directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` -Return the attributes of a file or directory. -Note: This is similar to `stat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to inspect. - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 72 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of a file or directory. -Note: This is similar to `utimensat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to operate on. - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Create a hard link. -Note: This is similar to `linkat` in POSIX. - -##### Params -- `old_fd`: [`fd`](#fd) - -- `old_flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `old_path`: `string` -The source path from which to link. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path at which to create the hard link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> Result` -Open a file or directory. -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since this -is error-prone in multi-threaded contexts. The returned file descriptor is -guaranteed to be less than 2**31. -Note: This is similar to `openat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `dirflags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The relative path of the file or directory to open, relative to the -[`path_open::fd`](#path_open.fd) directory. - -- `oflags`: [`oflags`](#oflags) -The method by which to open the file. - -- `fs_rights_base`: [`rights`](#rights) -The initial rights of the newly created file descriptor. The -implementation is allowed to return a file descriptor with fewer rights -than specified, if and only if those rights do not apply to the type of -file being opened. -The *base* rights are rights that will apply to operations using the file -descriptor itself, while the *inheriting* rights are rights that apply to -file descriptors derived from it. - -- `fs_rights_inheriting`: [`rights`](#rights) - -- `fdflags`: [`fdflags`](#fdflags) - -##### Results -- `error`: `Result` -The file descriptor of the file that has been opened. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`fd`](#fd) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` -Read the contents of a symbolic link. -Note: This is similar to `readlinkat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path of the symbolic link from which to read. - -- `buf`: `Pointer` -The buffer to which to write the contents of the symbolic link. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result` -The number of bytes placed in the buffer. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_remove_directory(fd: fd, path: string) -> Result<(), errno>` -Remove a directory. -Return [`errno::notempty`](#errno.notempty) if the directory is not empty. -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a directory to remove. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Rename a file or directory. -Note: This is similar to `renameat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `old_path`: `string` -The source path of the file or directory to rename. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path to which to rename the file or directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` -Create a symbolic link. -Note: This is similar to `symlinkat` in POSIX. - -##### Params -- `old_path`: `string` -The contents of the symbolic link. - -- `fd`: [`fd`](#fd) - -- `new_path`: `string` -The destination path at which to create the symbolic link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_unlink_file(fd: fd, path: string) -> Result<(), errno>` -Unlink a file. -Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a file to unlink. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` -Concurrently poll for the occurrence of a set of events. - -##### Params -- `in`: `ConstPointer` -The events to which to subscribe. - -- `out`: `Pointer` -The events that have occurred. - -- `nsubscriptions`: [`size`](#size) -Both the number of subscriptions and events. - -##### Results -- `error`: `Result` -The number of events stored. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `proc_exit(rval: exitcode)` -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -##### Params -- `rval`: [`exitcode`](#exitcode) -The exit code returned by the process. - -##### Results - ---- - -#### `proc_raise(sig: signal) -> Result<(), errno>` -Send a signal to the process of the calling thread. -Note: This is similar to `raise` in POSIX. - -##### Params -- `sig`: [`signal`](#signal) -The signal condition to trigger. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sched_yield() -> Result<(), errno>` -Temporarily yield execution of the calling thread. -Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. - -##### Params -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `random_get(buf: Pointer, buf_len: size) -> Result<(), errno>` -Write high-quality random data into a buffer. -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. -This function may execute slowly, so when large mounts of random data are -required, it's advisable to use this function to seed a pseudo-random -number generator, rather than to provide the random data directly. - -##### Params -- `buf`: `Pointer` -The buffer to fill with random data. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` -Receive a message from a socket. -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -##### Params -- `fd`: [`fd`](#fd) - -- `ri_data`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -- `ri_flags`: [`riflags`](#riflags) -Message flags. - -##### Results -- `error`: `Result<(size, roflags), errno>` -Number of bytes stored in ri_data and message flags. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, roflags)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`roflags`](#roflags) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` -Send a message on a socket. -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -##### Params -- `fd`: [`fd`](#fd) - -- `si_data`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors to which to retrieve data - -- `si_flags`: [`siflags`](#siflags) -Message flags. - -##### Results -- `error`: `Result` -Number of bytes transmitted. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_shutdown(fd: fd, how: sdflags) -> Result<(), errno>` -Shut down socket send and receive channels. -Note: This is similar to `shutdown` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `how`: [`sdflags`](#sdflags) -Which channels on the socket to shut down. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - diff --git a/proposals/filesystem/phases/snapshot/witx/typenames.witx b/proposals/filesystem/phases/snapshot/witx/typenames.witx deleted file mode 100644 index 311b42233..000000000 --- a/proposals/filesystem/phases/snapshot/witx/typenames.witx +++ /dev/null @@ -1,748 +0,0 @@ -;; Type names used by low-level WASI interfaces. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(typename $size u32) - -;;; Non-negative file size or length of a region within a file. -(typename $filesize u64) - -;;; Timestamp in nanoseconds. -(typename $timestamp u64) - -;;; Identifiers for clocks. -(typename $clockid - (enum (@witx tag u32) - ;;; The clock measuring real time. Time value zero corresponds with - ;;; 1970-01-01T00:00:00Z. - $realtime - ;;; The store-wide monotonic clock, which is defined as a clock measuring - ;;; real time, whose value cannot be adjusted and which cannot have negative - ;;; clock jumps. The epoch of this clock is undefined. The absolute time - ;;; value of this clock therefore has no meaning. - $monotonic - ;;; The CPU-time clock associated with the current process. - $process_cputime_id - ;;; The CPU-time clock associated with the current thread. - $thread_cputime_id - ) -) - -;;; Error codes returned by functions. -;;; Not all of these error codes are returned by the functions provided by this -;;; API; some are used in higher-level library layers, and others are provided -;;; merely for alignment with POSIX. -(typename $errno - (enum (@witx tag u16) - ;;; No error occurred. System call completed successfully. - $success - ;;; Argument list too long. - $2big - ;;; Permission denied. - $acces - ;;; Address in use. - $addrinuse - ;;; Address not available. - $addrnotavail - ;;; Address family not supported. - $afnosupport - ;;; Resource unavailable, or operation would block. - $again - ;;; Connection already in progress. - $already - ;;; Bad file descriptor. - $badf - ;;; Bad message. - $badmsg - ;;; Device or resource busy. - $busy - ;;; Operation canceled. - $canceled - ;;; No child processes. - $child - ;;; Connection aborted. - $connaborted - ;;; Connection refused. - $connrefused - ;;; Connection reset. - $connreset - ;;; Resource deadlock would occur. - $deadlk - ;;; Destination address required. - $destaddrreq - ;;; Mathematics argument out of domain of function. - $dom - ;;; Reserved. - $dquot - ;;; File exists. - $exist - ;;; Bad address. - $fault - ;;; File too large. - $fbig - ;;; Host is unreachable. - $hostunreach - ;;; Identifier removed. - $idrm - ;;; Illegal byte sequence. - $ilseq - ;;; Operation in progress. - $inprogress - ;;; Interrupted function. - $intr - ;;; Invalid argument. - $inval - ;;; I/O error. - $io - ;;; Socket is connected. - $isconn - ;;; Is a directory. - $isdir - ;;; Too many levels of symbolic links. - $loop - ;;; File descriptor value too large. - $mfile - ;;; Too many links. - $mlink - ;;; Message too large. - $msgsize - ;;; Reserved. - $multihop - ;;; Filename too long. - $nametoolong - ;;; Network is down. - $netdown - ;;; Connection aborted by network. - $netreset - ;;; Network unreachable. - $netunreach - ;;; Too many files open in system. - $nfile - ;;; No buffer space available. - $nobufs - ;;; No such device. - $nodev - ;;; No such file or directory. - $noent - ;;; Executable file format error. - $noexec - ;;; No locks available. - $nolck - ;;; Reserved. - $nolink - ;;; Not enough space. - $nomem - ;;; No message of the desired type. - $nomsg - ;;; Protocol not available. - $noprotoopt - ;;; No space left on device. - $nospc - ;;; Function not supported. - $nosys - ;;; The socket is not connected. - $notconn - ;;; Not a directory or a symbolic link to a directory. - $notdir - ;;; Directory not empty. - $notempty - ;;; State not recoverable. - $notrecoverable - ;;; Not a socket. - $notsock - ;;; Not supported, or operation not supported on socket. - $notsup - ;;; Inappropriate I/O control operation. - $notty - ;;; No such device or address. - $nxio - ;;; Value too large to be stored in data type. - $overflow - ;;; Previous owner died. - $ownerdead - ;;; Operation not permitted. - $perm - ;;; Broken pipe. - $pipe - ;;; Protocol error. - $proto - ;;; Protocol not supported. - $protonosupport - ;;; Protocol wrong type for socket. - $prototype - ;;; Result too large. - $range - ;;; Read-only file system. - $rofs - ;;; Invalid seek. - $spipe - ;;; No such process. - $srch - ;;; Reserved. - $stale - ;;; Connection timed out. - $timedout - ;;; Text file busy. - $txtbsy - ;;; Cross-device link. - $xdev - ;;; Extension: Capabilities insufficient. - $notcapable - ) -) - -;;; File descriptor rights, determining which actions may be performed. -(typename $rights - (flags (@witx repr u64) - ;;; The right to invoke `fd_datasync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::dsync`. - $fd_datasync - ;;; The right to invoke `fd_read` and `sock_recv`. - ;; - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. - $fd_read - ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. - $fd_seek - ;;; The right to invoke `fd_fdstat_set_flags`. - $fd_fdstat_set_flags - ;;; The right to invoke `fd_sync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. - $fd_sync - ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to - ;;; invoke `fd_tell`. - $fd_tell - ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. - $fd_write - ;;; The right to invoke `fd_advise`. - $fd_advise - ;;; The right to invoke `fd_allocate`. - $fd_allocate - ;;; The right to invoke `path_create_directory`. - $path_create_directory - ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::creat`. - $path_create_file - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; source directory. - $path_link_source - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; target directory. - $path_link_target - ;;; The right to invoke `path_open`. - $path_open - ;;; The right to invoke `fd_readdir`. - $fd_readdir - ;;; The right to invoke `path_readlink`. - $path_readlink - ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $path_rename_source - ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $path_rename_target - ;;; The right to invoke `path_filestat_get`. - $path_filestat_get - ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. - $path_filestat_set_size - ;;; The right to invoke `path_filestat_set_times`. - $path_filestat_set_times - ;;; The right to invoke `fd_filestat_get`. - $fd_filestat_get - ;;; The right to invoke `fd_filestat_set_size`. - $fd_filestat_set_size - ;;; The right to invoke `fd_filestat_set_times`. - $fd_filestat_set_times - ;;; The right to invoke `path_symlink`. - $path_symlink - ;;; The right to invoke `path_remove_directory`. - $path_remove_directory - ;;; The right to invoke `path_unlink_file`. - $path_unlink_file - ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. - ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. - $poll_fd_readwrite - ;;; The right to invoke `sock_shutdown`. - $sock_shutdown - ) -) - -;;; A file descriptor handle. -(typename $fd (handle)) - -;;; A region of memory for scatter/gather reads. -(typename $iovec - (record - ;;; The address of the buffer to be filled. - (field $buf (@witx pointer u8)) - ;;; The length of the buffer to be filled. - (field $buf_len $size) - ) -) - -;;; A region of memory for scatter/gather writes. -(typename $ciovec - (record - ;;; The address of the buffer to be written. - (field $buf (@witx const_pointer u8)) - ;;; The length of the buffer to be written. - (field $buf_len $size) - ) -) - -(typename $iovec_array (list $iovec)) -(typename $ciovec_array (list $ciovec)) - -;;; Relative offset within a file. -(typename $filedelta s64) - -;;; The position relative to which to set the offset of the file descriptor. -(typename $whence - (enum (@witx tag u8) - ;;; Seek relative to start-of-file. - $set - ;;; Seek relative to current position. - $cur - ;;; Seek relative to end-of-file. - $end - ) -) - -;;; A reference to the offset of a directory entry. -;;; -;;; The value 0 signifies the start of the directory. -(typename $dircookie u64) - -;;; The type for the `dirent::d_namlen` field of `dirent` struct. -(typename $dirnamlen u32) - -;;; File serial number that is unique within its file system. -(typename $inode u64) - -;;; The type of a file descriptor or file. -(typename $filetype - (enum (@witx tag u8) - ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $unknown - ;;; The file descriptor or file refers to a block device inode. - $block_device - ;;; The file descriptor or file refers to a character device inode. - $character_device - ;;; The file descriptor or file refers to a directory inode. - $directory - ;;; The file descriptor or file refers to a regular file inode. - $regular_file - ;;; The file descriptor or file refers to a datagram socket. - $socket_dgram - ;;; The file descriptor or file refers to a byte-stream socket. - $socket_stream - ;;; The file refers to a symbolic link inode. - $symbolic_link - ) -) - -;;; A directory entry. -(typename $dirent - (record - ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie) - ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) - ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype) - ) -) - -;;; File or memory access pattern advisory information. -(typename $advice - (enum (@witx tag u8) - ;;; The application has no advice to give on its behavior with respect to the specified data. - $normal - ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $sequential - ;;; The application expects to access the specified data in a random order. - $random - ;;; The application expects to access the specified data in the near future. - $willneed - ;;; The application expects that it will not access the specified data in the near future. - $dontneed - ;;; The application expects to access the specified data once and then not reuse it thereafter. - $noreuse - ) -) - -;;; File descriptor flags. -(typename $fdflags - (flags (@witx repr u16) - ;;; Append mode: Data written to the file is always appended to the file's end. - $append - ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $dsync - ;;; Non-blocking mode. - $nonblock - ;;; Synchronized read I/O operations. - $rsync - ;;; Write according to synchronized I/O file integrity completion. In - ;;; addition to synchronizing the data stored in the file, the implementation - ;;; may also synchronously update the file's metadata. - $sync - ) -) - -;;; File descriptor attributes. -(typename $fdstat - (record - ;;; File type. - (field $fs_filetype $filetype) - ;;; File descriptor flags. - (field $fs_flags $fdflags) - ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights) - ;;; Maximum set of rights that may be installed on new file descriptors that - ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights) - ) -) - -;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode` to uniquely identify a file or directory in the filesystem. -(typename $device u64) - -;;; Which file time attributes to adjust. -(typename $fstflags - (flags (@witx repr u16) - ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. - $atim - ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. - $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. - $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. - $mtim_now - ) -) - -;;; Flags determining the method of how paths are resolved. -(typename $lookupflags - (flags (@witx repr u32) - ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $symlink_follow - ) -) - -;;; Open flags used by `path_open`. -(typename $oflags - (flags (@witx repr u16) - ;;; Create file if it does not exist. - $creat - ;;; Fail if not a directory. - $directory - ;;; Fail if file already exists. - $excl - ;;; Truncate file to size 0. - $trunc - ) -) - -;;; Number of hard links to an inode. -(typename $linkcount u64) - -;;; File attributes. -(typename $filestat - (record - ;;; Device ID of device containing the file. - (field $dev $device) - ;;; File serial number. - (field $ino $inode) - ;;; File type. - (field $filetype $filetype) - ;;; Number of hard links to the file. - (field $nlink $linkcount) - ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $size $filesize) - ;;; Last data access timestamp. - (field $atim $timestamp) - ;;; Last data modification timestamp. - (field $mtim $timestamp) - ;;; Last file status change timestamp. - (field $ctim $timestamp) - ) -) - -;;; User-provided value that may be attached to objects that is retained when -;;; extracted from the implementation. -(typename $userdata u64) - -;;; Type of a subscription to an event or its occurrence. -(typename $eventtype - (enum (@witx tag u8) - ;;; The time value of clock `subscription_clock::id` has - ;;; reached timestamp `subscription_clock::timeout`. - $clock - ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has data - ;;; available for reading. This event always triggers for regular files. - $fd_read - ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has capacity - ;;; available for writing. This event always triggers for regular files. - $fd_write - ) -) - -;;; The state of the file descriptor subscribed to with -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $eventrwflags - (flags (@witx repr u16) - ;;; The peer of this socket has closed or disconnected. - $fd_readwrite_hangup - ) -) - -;;; The contents of an `event` when type is `eventtype::fd_read` or -;;; `eventtype::fd_write`. -(typename $event_fd_readwrite - (record - ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize) - ;;; The state of the file descriptor. - (field $flags $eventrwflags) - ) -) - -;;; An event that occurred. -(typename $event - (record - ;;; User-provided value that got attached to `subscription::userdata`. - (field $userdata $userdata) - ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno) - ;;; The type of event that occured - (field $type $eventtype) - ;;; The contents of the event, if it is an `eventtype::fd_read` or - ;;; `eventtype::fd_write`. `eventtype::clock` events ignore this field. - (field $fd_readwrite $event_fd_readwrite) - ) -) - -;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_clock::timeout`. -(typename $subclockflags - (flags (@witx repr u16) - ;;; If set, treat the timestamp provided in - ;;; `subscription_clock::timeout` as an absolute timestamp of clock - ;;; `subscription_clock::id`. If clear, treat the timestamp - ;;; provided in `subscription_clock::timeout` relative to the - ;;; current time value of clock `subscription_clock::id`. - $subscription_clock_abstime - ) -) - -;;; The contents of a `subscription` when type is `eventtype::clock`. -(typename $subscription_clock - (record - ;;; The clock against which to compare the timestamp. - (field $id $clockid) - ;;; The absolute or relative timestamp. - (field $timeout $timestamp) - ;;; The amount of time that the implementation may wait additionally - ;;; to coalesce with other events. - (field $precision $timestamp) - ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags) - ) -) - -;;; The contents of a `subscription` when type is type is -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $subscription_fd_readwrite - (record - ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd) - ) -) - -;;; The contents of a `subscription`. -(typename $subscription_u - (union - (@witx tag $eventtype) - $subscription_clock - $subscription_fd_readwrite - $subscription_fd_readwrite - ) -) - -;;; Subscription to an event. -(typename $subscription - (record - ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event::userdata`. - (field $userdata $userdata) - ;;; The type of the event to which to subscribe, and its contents - (field $u $subscription_u) - ) -) - -;;; Exit code generated by a process when exiting. -(typename $exitcode u32) - -;;; Signal condition. -(typename $signal - (enum (@witx tag u8) - ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;;; so this value is reserved. - $none - ;;; Hangup. - ;;; Action: Terminates the process. - $hup - ;;; Terminate interrupt signal. - ;;; Action: Terminates the process. - $int - ;;; Terminal quit signal. - ;;; Action: Terminates the process. - $quit - ;;; Illegal instruction. - ;;; Action: Terminates the process. - $ill - ;;; Trace/breakpoint trap. - ;;; Action: Terminates the process. - $trap - ;;; Process abort signal. - ;;; Action: Terminates the process. - $abrt - ;;; Access to an undefined portion of a memory object. - ;;; Action: Terminates the process. - $bus - ;;; Erroneous arithmetic operation. - ;;; Action: Terminates the process. - $fpe - ;;; Kill. - ;;; Action: Terminates the process. - $kill - ;;; User-defined signal 1. - ;;; Action: Terminates the process. - $usr1 - ;;; Invalid memory reference. - ;;; Action: Terminates the process. - $segv - ;;; User-defined signal 2. - ;;; Action: Terminates the process. - $usr2 - ;;; Write on a pipe with no one to read it. - ;;; Action: Ignored. - $pipe - ;;; Alarm clock. - ;;; Action: Terminates the process. - $alrm - ;;; Termination signal. - ;;; Action: Terminates the process. - $term - ;;; Child process terminated, stopped, or continued. - ;;; Action: Ignored. - $chld - ;;; Continue executing, if stopped. - ;;; Action: Continues executing, if stopped. - $cont - ;;; Stop executing. - ;;; Action: Stops executing. - $stop - ;;; Terminal stop signal. - ;;; Action: Stops executing. - $tstp - ;;; Background process attempting read. - ;;; Action: Stops executing. - $ttin - ;;; Background process attempting write. - ;;; Action: Stops executing. - $ttou - ;;; High bandwidth data is available at a socket. - ;;; Action: Ignored. - $urg - ;;; CPU time limit exceeded. - ;;; Action: Terminates the process. - $xcpu - ;;; File size limit exceeded. - ;;; Action: Terminates the process. - $xfsz - ;;; Virtual timer expired. - ;;; Action: Terminates the process. - $vtalrm - ;;; Profiling timer expired. - ;;; Action: Terminates the process. - $prof - ;;; Window changed. - ;;; Action: Ignored. - $winch - ;;; I/O possible. - ;;; Action: Terminates the process. - $poll - ;;; Power failure. - ;;; Action: Terminates the process. - $pwr - ;;; Bad system call. - ;;; Action: Terminates the process. - $sys - ) -) - -;;; Flags provided to `sock_recv`. -(typename $riflags - (flags (@witx repr u16) - ;;; Returns the message without removing it from the socket's receive queue. - $recv_peek - ;;; On byte-stream sockets, block until the full amount of data can be returned. - $recv_waitall - ) -) - -;;; Flags returned by `sock_recv`. -(typename $roflags - (flags (@witx repr u16) - ;;; Returned by `sock_recv`: Message data has been truncated. - $recv_data_truncated - ) -) - -;;; Flags provided to `sock_send`. As there are currently no flags -;;; defined, it must be set to zero. -(typename $siflags u16) - -;;; Which channels on a socket to shut down. -(typename $sdflags - (flags (@witx repr u8) - ;;; Disables further receive operations. - $rd - ;;; Disables further send operations. - $wr - ) -) - -;;; Identifiers for preopened capabilities. -(typename $preopentype - (enum (@witx tag u8) - ;;; A pre-opened directory. - $dir - ) -) - -;;; The contents of a $prestat when type is `preopentype::dir`. -(typename $prestat_dir - (record - ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size) - ) -) - -;;; Information about a pre-opened capability. -(typename $prestat - (union (@witx tag $preopentype) - $prestat_dir - ) -) - diff --git a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx deleted file mode 100644 index efb2c797f..000000000 --- a/proposals/filesystem/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ /dev/null @@ -1,510 +0,0 @@ -;; WASI Preview. This is an evolution of the API that WASI initially -;; launched with. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_snapshot_preview1 - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `args_sizes_get`. - ;;; Each argument is expected to be `\0` terminated. - (@interface func (export "args_get") - (param $argv (@witx pointer (@witx pointer u8))) - (param $argv_buf (@witx pointer u8)) - (result $error (expected (error $errno))) - ) - ;;; Return command-line argument data sizes. - (@interface func (export "args_sizes_get") - ;;; Returns the number of arguments and the size of the argument string - ;;; data, or an error. - (result $error (expected (tuple $size $size) (error $errno))) - ) - - ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. - ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - (@interface func (export "environ_get") - (param $environ (@witx pointer (@witx pointer u8))) - (param $environ_buf (@witx pointer u8)) - (result $error (expected (error $errno))) - ) - ;;; Return environment variable data sizes. - (@interface func (export "environ_sizes_get") - ;;; Returns the number of environment variable arguments and the size of the - ;;; environment variable data. - (result $error (expected (tuple $size $size) (error $errno))) - ) - - ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, - ;;; return `errno::inval`. - ;;; Note: This is similar to `clock_getres` in POSIX. - (@interface func (export "clock_res_get") - ;;; The clock for which to return the resolution. - (param $id $clockid) - ;;; The resolution of the clock, or an error if one happened. - (result $error (expected $timestamp (error $errno))) - ) - ;;; Return the time value of a clock. - ;;; Note: This is similar to `clock_gettime` in POSIX. - (@interface func (export "clock_time_get") - ;;; The clock for which to return the time. - (param $id $clockid) - ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp) - ;;; The time value of the clock. - (result $error (expected $timestamp (error $errno))) - ) - - ;;; Provide file advisory information on a file descriptor. - ;;; Note: This is similar to `posix_fadvise` in POSIX. - (@interface func (export "fd_advise") - (param $fd $fd) - ;;; The offset within the file to which the advisory applies. - (param $offset $filesize) - ;;; The length of the region to which the advisory applies. - (param $len $filesize) - ;;; The advice. - (param $advice $advice) - (result $error (expected (error $errno))) - ) - - ;;; Force the allocation of space in a file. - ;;; Note: This is similar to `posix_fallocate` in POSIX. - (@interface func (export "fd_allocate") - (param $fd $fd) - ;;; The offset at which to start the allocation. - (param $offset $filesize) - ;;; The length of the area that is allocated. - (param $len $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Close a file descriptor. - ;;; Note: This is similar to `close` in POSIX. - (@interface func (export "fd_close") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Synchronize the data of a file to disk. - ;;; Note: This is similar to `fdatasync` in POSIX. - (@interface func (export "fd_datasync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Get the attributes of a file descriptor. - ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (@interface func (export "fd_fdstat_get") - (param $fd $fd) - ;;; The buffer where the file descriptor's attributes are stored. - (result $error (expected $fdstat (error $errno))) - ) - - ;;; Adjust the flags associated with a file descriptor. - ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd) - ;;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights - (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd) - ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of an open file. - (@interface func (export "fd_filestat_get") - (param $fd $fd) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;;; Note: This is similar to `ftruncate` in POSIX. - (@interface func (export "fd_filestat_set_size") - (param $fd $fd) - ;;; The desired file size. - (param $size $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the timestamps of an open file or directory. - ;;; Note: This is similar to `futimens` in POSIX. - (@interface func (export "fd_filestat_set_times") - (param $fd $fd) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in POSIX. - (@interface func (export "fd_pread") - (param $fd $fd) - ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_array) - ;;; The offset within the file at which to read. - (param $offset $filesize) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_get") - (param $fd $fd) - ;;; The buffer where the description is stored. - (result $error (expected $prestat (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_dir_name") - (param $fd $fd) - ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer u8)) - (param $path_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in POSIX. - (@interface func (export "fd_pwrite") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The offset within the file at which to write. - (param $offset $filesize) - ;;; The number of bytes written. - (result $error (expected $size (error $errno))) - ) - - ;;; Read from a file descriptor. - ;;; Note: This is similar to `readv` in POSIX. - (@interface func (export "fd_read") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_array) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Read directory entries from a directory. - ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a `dirent` object, - ;;; followed by `dirent::d_namlen` bytes holding the name of the directory - ;;; entry. - ;; - ;;; This function fills the output buffer as much as possible, potentially - ;;; truncating the last directory entry. This allows the caller to grow its - ;;; read buffer size in case it's too small to fit a single large directory - ;;; entry, or skip the oversized directory entry. - (@interface func (export "fd_readdir") - (param $fd $fd) - ;;; The buffer where directory entries are stored - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The location within the directory to start reading - (param $cookie $dircookie) - ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $error (expected $size (error $errno))) - ) - - ;;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;;; Due to the strong focus on thread safety, this environment does not provide - ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;;; file descriptor with the same number could be allocated by a different - ;;; thread at the same time. - ;; - ;;; This function provides a way to atomically renumber file descriptors, which - ;;; would disappear if `dup2()` were to be removed entirely. - (@interface func (export "fd_renumber") - (param $fd $fd) - ;;; The file descriptor to overwrite. - (param $to $fd) - (result $error (expected (error $errno))) - ) - - ;;; Move the offset of a file descriptor. - ;;; Note: This is similar to `lseek` in POSIX. - (@interface func (export "fd_seek") - (param $fd $fd) - ;;; The number of bytes to move. - (param $offset $filedelta) - ;;; The base from which the offset is relative. - (param $whence $whence) - ;;; The new offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Synchronize the data and metadata of a file to disk. - ;;; Note: This is similar to `fsync` in POSIX. - (@interface func (export "fd_sync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Return the current offset of a file descriptor. - ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (@interface func (export "fd_tell") - (param $fd $fd) - ;;; The current offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Write to a file descriptor. - ;;; Note: This is similar to `writev` in POSIX. - (@interface func (export "fd_write") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - (result $error (expected $size (error $errno))) - ) - - ;;; Create a directory. - ;;; Note: This is similar to `mkdirat` in POSIX. - (@interface func (export "path_create_directory") - (param $fd $fd) - ;;; The path at which to create the directory. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of a file or directory. - ;;; Note: This is similar to `stat` in POSIX. - (@interface func (export "path_filestat_get") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to inspect. - (param $path string) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the timestamps of a file or directory. - ;;; Note: This is similar to `utimensat` in POSIX. - (@interface func (export "path_filestat_set_times") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to operate on. - (param $path string) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Create a hard link. - ;;; Note: This is similar to `linkat` in POSIX. - (@interface func (export "path_link") - (param $old_fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags) - ;;; The source path from which to link. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path at which to create the hard link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Open a file or directory. - ;; - ;;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;;; file descriptor not currently open; it is randomized to prevent - ;;; applications from depending on making assumptions about indexes, since this - ;;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;;; guaranteed to be less than 2**31. - ;; - ;;; Note: This is similar to `openat` in POSIX. - (@interface func (export "path_open") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags) - ;;; The relative path of the file or directory to open, relative to the - ;;; `path_open::fd` directory. - (param $path string) - ;;; The method by which to open the file. - (param $oflags $oflags) - ;;; The initial rights of the newly created file descriptor. The - ;;; implementation is allowed to return a file descriptor with fewer rights - ;;; than specified, if and only if those rights do not apply to the type of - ;;; file being opened. - ;; - ;;; The *base* rights are rights that will apply to operations using the file - ;;; descriptor itself, while the *inheriting* rights are rights that apply to - ;;; file descriptors derived from it. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (param $fdflags $fdflags) - ;;; The file descriptor of the file that has been opened. - (result $error (expected $fd (error $errno))) - ) - - ;;; Read the contents of a symbolic link. - ;;; Note: This is similar to `readlinkat` in POSIX. - (@interface func (export "path_readlink") - (param $fd $fd) - ;;; The path of the symbolic link from which to read. - (param $path string) - ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The number of bytes placed in the buffer. - (result $error (expected $size (error $errno))) - ) - - ;;; Remove a directory. - ;;; Return `errno::notempty` if the directory is not empty. - ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (@interface func (export "path_remove_directory") - (param $fd $fd) - ;;; The path to a directory to remove. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Rename a file or directory. - ;;; Note: This is similar to `renameat` in POSIX. - (@interface func (export "path_rename") - (param $fd $fd) - ;;; The source path of the file or directory to rename. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Create a symbolic link. - ;;; Note: This is similar to `symlinkat` in POSIX. - (@interface func (export "path_symlink") - ;;; The contents of the symbolic link. - (param $old_path string) - (param $fd $fd) - ;;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - - ;;; Unlink a file. - ;;; Return `errno::isdir` if the path refers to a directory. - ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (@interface func (export "path_unlink_file") - (param $fd $fd) - ;;; The path to a file to unlink. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Concurrently poll for the occurrence of a set of events. - (@interface func (export "poll_oneoff") - ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription)) - ;;; The events that have occurred. - (param $out (@witx pointer $event)) - ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size) - ;;; The number of events stored. - (result $error (expected $size (error $errno))) - ) - - ;;; Terminate the process normally. An exit code of 0 indicates successful - ;;; termination of the program. The meanings of other values is dependent on - ;;; the environment. - (@interface func (export "proc_exit") - ;;; The exit code returned by the process. - (param $rval $exitcode) - (@witx noreturn) - ) - - ;;; Send a signal to the process of the calling thread. - ;;; Note: This is similar to `raise` in POSIX. - (@interface func (export "proc_raise") - ;;; The signal condition to trigger. - (param $sig $signal) - (result $error (expected (error $errno))) - ) - - ;;; Temporarily yield execution of the calling thread. - ;;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "sched_yield") - (result $error (expected (error $errno))) - ) - - ;;; Write high-quality random data into a buffer. - ;;; This function blocks when the implementation is unable to immediately - ;;; provide sufficient high-quality random data. - ;;; This function may execute slowly, so when large mounts of random data are - ;;; required, it's advisable to use this function to seed a pseudo-random - ;;; number generator, rather than to provide the random data directly. - (@interface func (export "random_get") - ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Receive a message from a socket. - ;;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;;; the data into multiple buffers in the manner of `readv`. - (@interface func (export "sock_recv") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_array) - ;;; Message flags. - (param $ri_flags $riflags) - ;;; Number of bytes stored in ri_data and message flags. - (result $error (expected (tuple $size $roflags) (error $errno))) - ) - - ;;; Send a message on a socket. - ;;; Note: This is similar to `send` in POSIX, though it also supports writing - ;;; the data from multiple buffers in the manner of `writev`. - (@interface func (export "sock_send") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_array) - ;;; Message flags. - (param $si_flags $siflags) - ;;; Number of bytes transmitted. - (result $error (expected $size (error $errno))) - ) - - ;;; Shut down socket send and receive channels. - ;;; Note: This is similar to `shutdown` in POSIX. - (@interface func (export "sock_shutdown") - (param $fd $fd) - ;;; Which channels on the socket to shut down. - (param $how $sdflags) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/filesystem/proposal-template/README.md b/proposals/filesystem/proposal-template/README.md deleted file mode 100644 index b97035935..000000000 --- a/proposals/filesystem/proposal-template/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Proposal template - -This directory will hold a template for creating new proposals, to help people -get started. diff --git a/proposals/filesystem/proposals/README.md b/proposals/filesystem/proposals/README.md deleted file mode 100644 index 45c2c2852..000000000 --- a/proposals/filesystem/proposals/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Proposals - -This directory contains overviews for proposals that are included in this -repository. - -This is analogous to [the correpsonding directory in the spec repository]. - -[the correpsonding directory in the spec repository]: https://github.com/WebAssembly/spec/tree/master/proposals diff --git a/proposals/filesystem/snapshots/README.md b/proposals/filesystem/snapshots/README.md deleted file mode 100644 index af94dbdef..000000000 --- a/proposals/filesystem/snapshots/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# WASI Snapshots - -To balance between the needs of development and stability, snapshots -represent the state of all active proposals at a moment in time. Individual -Snapshots are stable, but WASI as a whole is evolving. diff --git a/proposals/filesystem/snapshots/make-snapshot.sh b/proposals/filesystem/snapshots/make-snapshot.sh deleted file mode 100755 index b30dfa2e5..000000000 --- a/proposals/filesystem/snapshots/make-snapshot.sh +++ /dev/null @@ -1,159 +0,0 @@ -#!/bin/bash -# Creates a snapshot based on upstream proposal repositories. -# Derived from update-testsuite.sh in https://github.com/WebAssembly/testsuite -set -e -set -u -set -o pipefail - -ignore_dirs='' - -# TODO: Add the rest. -repos=' - WASI - wasi-filesystem - wasi-clocks - wasi-random -' - -log_and_run() { - echo ">>" $* - if ! $*; then - echo "sub-command failed: $*" - exit - fi -} - -try_log_and_run() { - echo ">>" $* - $* -} - -pushdir() { - pushd $1 >/dev/null || exit -} - -popdir() { - popd >/dev/null || exit -} - -update_repo() { - local repo=$1 - pushdir repos - if [ -d ${repo} ]; then - log_and_run git -C ${repo} fetch origin - log_and_run git -C ${repo} reset origin/main --hard - else - log_and_run git clone https://github.com/WebAssembly/${repo} - fi - - # Add upstream WASI as "WASI" remote. - if [ "${repo}" != "WASI" ]; then - pushdir ${repo} - if ! git remote | grep WASI >/dev/null; then - log_and_run git remote add WASI https://github.com/WebAssembly/WASI - fi - - log_and_run git fetch WASI - popdir - fi - popdir -} - -merge_with_WASI() { - local repo=$1 - - [ "${repo}" == "WASI" ] && return - - pushdir repos/${repo} - # Create and checkout "try-merge" branch. - if ! git branch | grep try-merge >/dev/null; then - log_and_run git branch try-merge origin/main - fi - log_and_run git checkout try-merge - - # Attempt to merge with WASI/main. - log_and_run git reset origin/main --hard - try_log_and_run git merge -q WASI/main -m "merged" - if [ $? -ne 0 ]; then - # Ignore merge conflicts in non-test directories. - # We don't care about those changes. - try_log_and_run git checkout --ours ${ignore_dirs} - try_log_and_run git add ${ignore_dirs} - try_log_and_run git -c core.editor=true merge --continue - if [ $? -ne 0 ]; then - git merge --abort - popdir - return 1 - fi - fi - popdir - return 0 -} - -snapshot_name=$(date --iso-8601) -snapshot_dir=snapshots/$snapshot_name -mkdir -p $snapshot_dir - -commit_message_file=$PWD/commit_message -echo -e "Update repos\n" > $commit_message_file - -failed_repos= - -for repo in ${repos}; do - echo "++ updating ${repo}" - update_repo ${repo} - - if ! merge_with_WASI ${repo}; then - echo -e "!! error merging ${repo}, skipping\n" - failed_repos="${failed_repos} ${repo}" - continue - fi - - if [ "${repo}" = "WASI" ]; then - dest_dir=$snapshot_dir - log_and_run cp -r repos/${repo}/standard ${dest_dir} - else - dest_dir=$snapshot_dir/proposals/${repo} - mkdir -p ${dest_dir} - - # Don't add tests from proposal that are the same as WASI. - pushdir repos/${repo} - for new in $(find standard -type f); do - old=../../repos/WASI/${new} - if [[ ! -f ${old} ]] || ! diff ${old} ${new} >/dev/null; then - log_and_run cp ${new} ../../${dest_dir} - fi - done - popdir - fi - - # Check whether any files were removed. - for old in $(find ${dest_dir} -type f); do - new=$(find repos/${repo}/standard -name ${old##*/}) - if [[ ! -f ${new} ]]; then - log_and_run git rm ${old} - fi - done - - # Check whether any files were updated. - if [ $(git status -s ${dest_dir} | wc -l) -ne 0 ]; then - log_and_run git add ${dest_dir}/* - - repo_sha=$(git -C repos/${repo} log --max-count=1 --oneline origin/main| sed -e 's/ .*//') - echo " ${repo}:" >> $commit_message_file - echo " https://github.com/WebAssembly/${repo}/commit/${repo_sha}" >> $commit_message_file - fi - - echo -e "-- ${repo}\n" -done - -echo "" >> $commit_message_file -echo "This change was automatically generated by \`make-snapshot.sh\`" >> $commit_message_file -git commit -a -F $commit_message_file -# git push - -echo "done" - -if [ -n "${failed_repos}" ]; then - echo "!! failed to update repos: ${failed_repos}" -fi diff --git a/proposals/filesystem/standard/README.md b/proposals/filesystem/standard/README.md deleted file mode 100644 index ad6f93c7c..000000000 --- a/proposals/filesystem/standard/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# WASI Standard - -In the [main WASI repository], this directory holds proposals which have -[completed the standardization process]. - -In a proposal repository, which is a fork of the main WASI repository, -this directory holds the current proposal, including witx specifications, -tests, and documentation. When the proposal is standardized, the fork is -merged into the main repository. - -[main WASI repository]: https://github.com/WebAssembly/WASI/issues/360 -[completed the standardization process]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md#5-the-feature-is-standardized-working-group diff --git a/proposals/filesystem/standard/wasi-filesystem/docs.md b/proposals/filesystem/standard/wasi-filesystem/docs.md deleted file mode 100644 index faf0d37dc..000000000 --- a/proposals/filesystem/standard/wasi-filesystem/docs.md +++ /dev/null @@ -1,2109 +0,0 @@ -# Types -## `size`: `usize` -An array size. - -Note: This is similar to `size_t` in POSIX. - -Size: 4 - -Alignment: 4 - -## `filesize`: `u64` -Non-negative file size or length of a region within a file. - -Size: 8 - -Alignment: 8 - -## `timestamp`: `u64` -Timestamp in nanoseconds. - -Size: 8 - -Alignment: 8 - -## `clockid`: `Variant` -Identifiers for clocks. - -Size: 4 - -Alignment: 4 - -### Variant cases -- `realtime` -The clock measuring real time. Time value zero corresponds with -1970-01-01T00:00:00Z. - -- `monotonic` -The store-wide monotonic clock, which is defined as a clock measuring -real time, whose value cannot be adjusted and which cannot have negative -clock jumps. The epoch of this clock is undefined. The absolute time -value of this clock therefore has no meaning. - -## `errno`: `Variant` -Error codes returned by functions. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX. - -Size: 2 - -Alignment: 2 - -### Variant cases -- `success` -No error occurred. System call completed successfully. - -- `toobig` -Argument list too long. This is similar to `E2BIG` in POSIX. - -- `access` -Permission denied. - -- `addrinuse` -Address in use. - -- `addrnotavail` -Address not available. - -- `afnosupport` -Address family not supported. - -- `again` -Resource unavailable, or operation would block. - -- `already` -Connection already in progress. - -- `badf` -Bad file descriptor. - -- `badmsg` -Bad message. - -- `busy` -Device or resource busy. - -- `canceled` -Operation canceled. - -- `child` -No child processes. - -- `connaborted` -Connection aborted. - -- `connrefused` -Connection refused. - -- `connreset` -Connection reset. - -- `deadlk` -Resource deadlock would occur. - -- `destaddrreq` -Destination address required. - -- `dom` -Mathematics argument out of domain of function. - -- `dquot` -Reserved. - -- `exist` -File exists. - -- `fault` -Bad address. - -- `fbig` -File too large. - -- `hostunreach` -Host is unreachable. - -- `idrm` -Identifier removed. - -- `ilseq` -Illegal byte sequence. - -- `inprogress` -Operation in progress. - -- `intr` -Interrupted function. - -- `inval` -Invalid argument. - -- `io` -I/O error. - -- `isconn` -Socket is connected. - -- `isdir` -Is a directory. - -- `loop` -Too many levels of symbolic links. - -- `mfile` -File descriptor value too large. - -- `mlink` -Too many links. - -- `msgsize` -Message too large. - -- `multihop` -Reserved. - -- `nametoolong` -Filename too long. - -- `netdown` -Network is down. - -- `netreset` -Connection aborted by network. - -- `netunreach` -Network unreachable. - -- `nfile` -Too many files open in system. - -- `nobufs` -No buffer space available. - -- `nodev` -No such device. - -- `noent` -No such file or directory. - -- `noexec` -Executable file format error. - -- `nolck` -No locks available. - -- `nolink` -Reserved. - -- `nomem` -Not enough space. - -- `nomsg` -No message of the desired type. - -- `noprotoopt` -Protocol not available. - -- `nospc` -No space left on device. - -- `nosys` -Function not supported. - -- `notconn` -The socket is not connected. - -- `notdir` -Not a directory or a symbolic link to a directory. - -- `notempty` -Directory not empty. - -- `notrecoverable` -State not recoverable. - -- `notsock` -Not a socket. - -- `notsup` -Not supported, or operation not supported on socket. - -- `notty` -Inappropriate I/O control operation. - -- `nxio` -No such device or address. - -- `overflow` -Value too large to be stored in data type. - -- `ownerdead` -Previous owner died. - -- `perm` -Operation not permitted. - -- `pipe` -Broken pipe. - -- `proto` -Protocol error. - -- `protonosupport` -Protocol not supported. - -- `prototype` -Protocol wrong type for socket. - -- `range` -Result too large. - -- `rofs` -Read-only file system. - -- `spipe` -Invalid seek. - -- `srch` -No such process. - -- `stale` -Reserved. - -- `timedout` -Connection timed out. - -- `txtbsy` -Text file busy. - -- `xdev` -Cross-device link. - -- `notcapable` -Extension: Capabilities insufficient. - -## `rights`: `Record` -File descriptor rights, determining which actions may be performed. - -Size: 8 - -Alignment: 8 - -### Record members -- `fd_datasync`: `bool` -The right to invoke `fd_datasync`. -If `path_open` is set, includes the right to invoke -`path_open` with [`fdflags::dsync`](#fdflags.dsync). - -Bit: 0 - -- `fd_read`: `bool` -The right to invoke `fd_read` and `sock_recv`. -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. - -Bit: 1 - -- `fd_seek`: `bool` -The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). - -Bit: 2 - -- `fd_fdstat_set_flags`: `bool` -The right to invoke `fd_fdstat_set_flags`. - -Bit: 3 - -- `fd_sync`: `bool` -The right to invoke `fd_sync`. -If `path_open` is set, includes the right to invoke -`path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - -Bit: 4 - -- `fd_tell`: `bool` -The right to invoke `fd_seek` in such a way that the file offset -remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to -invoke `fd_tell`. - -Bit: 5 - -- `fd_write`: `bool` -The right to invoke `fd_write` and `sock_send`. -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. - -Bit: 6 - -- `fd_advise`: `bool` -The right to invoke `fd_advise`. - -Bit: 7 - -- `fd_allocate`: `bool` -The right to invoke `fd_allocate`. - -Bit: 8 - -- `path_create_directory`: `bool` -The right to invoke `path_create_directory`. - -Bit: 9 - -- `path_create_file`: `bool` -If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). - -Bit: 10 - -- `path_link_source`: `bool` -The right to invoke `path_link` with the file descriptor as the -source directory. - -Bit: 11 - -- `path_link_target`: `bool` -The right to invoke `path_link` with the file descriptor as the -target directory. - -Bit: 12 - -- `path_open`: `bool` -The right to invoke `path_open`. - -Bit: 13 - -- `fd_readdir`: `bool` -The right to invoke `fd_readdir`. - -Bit: 14 - -- `path_readlink`: `bool` -The right to invoke `path_readlink`. - -Bit: 15 - -- `path_rename_source`: `bool` -The right to invoke `path_rename` with the file descriptor as the source directory. - -Bit: 16 - -- `path_rename_target`: `bool` -The right to invoke `path_rename` with the file descriptor as the target directory. - -Bit: 17 - -- `path_filestat_get`: `bool` -The right to invoke `path_filestat_get`. - -Bit: 18 - -- `path_filestat_set_size`: `bool` -The right to change a file's size. -If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). -Note: there is no function named `path_filestat_set_size`. This follows POSIX design, -which only has `ftruncate` and does not provide `ftruncateat`. -While such function would be desirable from the API design perspective, there are virtually -no use cases for it since no code written for POSIX systems would use it. -Moreover, implementing it would require multiple syscalls, leading to inferior performance. - -Bit: 19 - -- `path_filestat_set_times`: `bool` -The right to invoke `path_filestat_set_times`. - -Bit: 20 - -- `path_permissions_set`: `bool` -The right to invoke `path_permissions_set`. - -Bit: 21 - -- `fd_filestat_get`: `bool` -The right to invoke `fd_filestat_get`. - -Bit: 22 - -- `fd_filestat_set_size`: `bool` -The right to invoke `fd_filestat_set_size`. - -Bit: 23 - -- `fd_filestat_set_times`: `bool` -The right to invoke `fd_filestat_set_times`. - -Bit: 24 - -- `fd_permissions_set`: `bool` -The right to invoke `fd_permissions_set`. - -Bit: 25 - -- `path_symlink`: `bool` -The right to invoke `path_symlink`. - -Bit: 26 - -- `path_remove_directory`: `bool` -The right to invoke `path_remove_directory`. - -Bit: 27 - -- `path_unlink_file`: `bool` -The right to invoke `path_unlink_file`. - -Bit: 28 - -- `poll_fd_readwrite`: `bool` -If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). -If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). - -Bit: 29 - -- `sock_shutdown`: `bool` -The right to invoke `sock_shutdown`. - -Bit: 30 - -## `fd`: `Handle` -A file descriptor handle. - -Size: 4 - -Alignment: 4 - -### Supertypes -## `iovec`: `Record` -A region of memory for scatter/gather reads. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `Pointer` -The address of the buffer to be filled. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be filled. - -Offset: 4 - -## `ciovec`: `Record` -A region of memory for scatter/gather writes. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `ConstPointer` -The address of the buffer to be written. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be written. - -Offset: 4 - -## `iovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `ciovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `filedelta`: `s64` -Relative offset within a file. - -Size: 8 - -Alignment: 8 - -## `whence`: `Variant` -The position relative to which to set the offset of the file descriptor. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `set` -Seek relative to start-of-file. - -- `cur` -Seek relative to current position. - -- `end` -Seek relative to end-of-file. - -## `dircookie`: `u64` -A reference to the offset of a directory entry. - -Size: 8 - -Alignment: 8 - -### Constants -- `start` - -## `dirnamlen`: `u32` -The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). - -Size: 4 - -Alignment: 4 - -## `inode`: `u64` -File serial number that is unique within its file system. - -Size: 8 - -Alignment: 8 - -## `filetype`: `Variant` -The type of a file descriptor or file. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `unknown` -The type of the file descriptor or file is unknown or is different from any of the other types specified. - -- `block_device` -The file descriptor or file refers to a block device inode. - -- `character_device` -The file descriptor or file refers to a character device inode. - -- `directory` -The file descriptor or file refers to a directory inode. - -- `regular_file` -The file descriptor or file refers to a regular file inode. - -- `socket_dgram` -The file descriptor or file refers to a datagram socket. - -- `socket_stream` -The file descriptor or file refers to a byte-stream socket. - -- `symbolic_link` -The file refers to a symbolic link inode. - -- `fifo` -The file descriptor or file refers to a FIFO. - -## `dirent`: `Record` -A directory entry. - -Size: 24 - -Alignment: 8 - -### Record members -- `d_next`: [`dircookie`](#dircookie) -The offset of the next directory entry stored in this directory. - -Offset: 0 - -- `d_ino`: [`inode`](#inode) -The serial number of the file referred to by this directory entry. - -Offset: 8 - -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. - -Offset: 16 - -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. - -Offset: 20 - -## `advice`: `Variant` -File or memory access pattern advisory information. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `normal` -The application has no advice to give on its behavior with respect to the specified data. - -- `sequential` -The application expects to access the specified data sequentially from lower offsets to higher offsets. - -- `random` -The application expects to access the specified data in a random order. - -- `willneed` -The application expects to access the specified data in the near future. - -- `dontneed` -The application expects that it will not access the specified data in the near future. - -- `noreuse` -The application expects to access the specified data once and then not reuse it thereafter. - -## `fdflags`: `Record` -File descriptor flags. - -Size: 2 - -Alignment: 2 - -### Record members -- `append`: `bool` -Append mode: Data written to the file is always appended to the file's end. - -Bit: 0 - -- `dsync`: `bool` -Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - -Bit: 1 - -- `nonblock`: `bool` -Non-blocking mode. - -Bit: 2 - -- `rsync`: `bool` -Synchronized read I/O operations. - -Bit: 3 - -- `sync`: `bool` -Write according to synchronized I/O file integrity completion. In -addition to synchronizing the data stored in the file, the implementation -may also synchronously update the file's metadata. - -Bit: 4 - -## `fdstat`: `Record` -File descriptor attributes. - -Size: 24 - -Alignment: 8 - -### Record members -- `fs_filetype`: [`filetype`](#filetype) -File type. - -Offset: 0 - -- `fs_flags`: [`fdflags`](#fdflags) -File descriptor flags. - -Offset: 2 - -- `fs_rights_base`: [`rights`](#rights) -Rights that apply to this file descriptor. - -Offset: 8 - -- `fs_rights_inheriting`: [`rights`](#rights) -Maximum set of rights that may be installed on new file descriptors that -are created through this file descriptor, e.g., through `path_open`. - -Offset: 16 - -## `device`: `u64` -Identifier for a device containing a file system. Can be used in combination -with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. - -Size: 8 - -Alignment: 8 - -## `fstflags`: `Record` -Which file time attributes to adjust. - -Size: 2 - -Alignment: 2 - -### Record members -- `atim`: `bool` -Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - -Bit: 0 - -- `atim_now`: `bool` -Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 1 - -- `mtim`: `bool` -Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - -Bit: 2 - -- `mtim_now`: `bool` -Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 3 - -## `lookupflags`: `Record` -Flags determining the method of how paths are resolved. - -Size: 4 - -Alignment: 4 - -### Record members -- `symlink_follow`: `bool` -As long as the resolved path corresponds to a symbolic link, it is expanded. - -Bit: 0 - -## `oflags`: `Record` -Open flags used by `path_open`. - -Size: 2 - -Alignment: 2 - -### Record members -- `create`: `bool` -Create file if it does not exist. - -Bit: 0 - -- `directory`: `bool` -Fail if not a directory. - -Bit: 1 - -- `excl`: `bool` -Fail if file already exists. - -Bit: 2 - -- `trunc`: `bool` -Truncate file to size 0. - -Bit: 3 - -## `linkcount`: `u64` -Number of hard links to an inode. - -Size: 8 - -Alignment: 8 - -## `permissions`: `Record` -File permissions. This represents the permissions associated with a -file in a filesystem, and don't fully reflect all the conditions -which determine whether a given WASI program can access the file. - -Size: 1 - -Alignment: 1 - -### Record members -- `read`: `bool` -For files, permission to read the file. -For directories, permission to do [`readdir`](#readdir) and access files -within the directory. - -Note: This is similar to the read bit being set on files, and the -read *and* execute bits being set on directories, in POSIX. - -Bit: 0 - -- `write`: `bool` -For files, permission to mutate the file. -For directories, permission to create, remove, and rename items -within the directory. - -Bit: 1 - -- `execute`: `bool` -For files, permission to "execute" the file, using whatever -concept of "executing" the host filesystem has. -This flag is not valid for directories. - -Bit: 2 - -- `private`: `bool` -For filesystems which have a concept of multiple "users", this flag -indicates that the file is only accessible by the effective "user" -that the WASI store uses to access the filesystem, and inaccessible -to other "users". - -Bit: 3 - -## `filestat`: `Record` -File attributes. - -Size: 64 - -Alignment: 8 - -### Record members -- `dev`: [`device`](#device) -Device ID of device containing the file. - -Offset: 0 - -- `ino`: [`inode`](#inode) -File serial number. - -Offset: 8 - -- `filetype`: [`filetype`](#filetype) -File type. - -Offset: 16 - -- `permissions`: [`permissions`](#permissions) -File permissions. - -Offset: 17 - -- `nlink`: [`linkcount`](#linkcount) -Number of hard links to the file. - -Offset: 24 - -- `size`: [`filesize`](#filesize) -For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - -Offset: 32 - -- `atim`: [`timestamp`](#timestamp) -Last data access timestamp. - -Offset: 40 - -- `mtim`: [`timestamp`](#timestamp) -Last data modification timestamp. - -Offset: 48 - -- `ctim`: [`timestamp`](#timestamp) -Last file status change timestamp. - -Offset: 56 - -## `userdata`: `u64` -User-provided value that may be attached to objects that is retained when -extracted from the implementation. - -Size: 8 - -Alignment: 8 - -## `eventtype`: `Variant` -Type of a subscription to an event or its occurrence. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `clock` -The time value of clock [`subscription_clock::id`](#subscription_clock.id) has -reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - -- `fd_read` -File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has data -available for reading. This event always triggers for regular files. - -- `fd_write` -File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity -available for writing. This event always triggers for regular files. - -## `eventrwflags`: `Record` -The state of the file descriptor subscribed to with -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 2 - -Alignment: 2 - -### Record members -- `fd_readwrite_hangup`: `bool` -The peer of this socket has closed or disconnected. - -Bit: 0 - -## `event_fd_readwrite`: `Record` -The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). - -Size: 16 - -Alignment: 8 - -### Record members -- `nbytes`: [`filesize`](#filesize) -The number of bytes available for reading or writing. - -Offset: 0 - -- `flags`: [`eventrwflags`](#eventrwflags) -The state of the file descriptor. - -Offset: 8 - -## `event_u`: `Variant` -The contents of an [`event`](#event). - -Size: 24 - -Alignment: 8 - -### Variant Layout -- size: 24 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock` - -- `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) - -- `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) - -## `event`: `Record` -An event that occurred. - -Size: 40 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). - -Offset: 0 - -- `error`: [`errno`](#errno) -If non-zero, an error that occurred while processing the subscription request. - -Offset: 8 - -- `u`: [`event_u`](#event_u) -The type of the event that occurred, and the contents of the event - -Offset: 16 - -## `subclockflags`: `Record` -Flags determining how to interpret the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout). - -Size: 2 - -Alignment: 2 - -### Record members -- `subscription_clock_abstime`: `bool` -If set, treat the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock -[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp -provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the -current time value of clock [`subscription_clock::id`](#subscription_clock.id). - -Bit: 0 - -## `subscription_clock`: `Record` -The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). - -Size: 32 - -Alignment: 8 - -### Record members -- `id`: [`clockid`](#clockid) -The clock against which to compare the timestamp. - -Offset: 0 - -- `timeout`: [`timestamp`](#timestamp) -The absolute or relative timestamp. - -Offset: 8 - -- `precision`: [`timestamp`](#timestamp) -The amount of time that the implementation may wait additionally -to coalesce with other events. - -Offset: 16 - -- `flags`: [`subclockflags`](#subclockflags) -Flags specifying whether the timeout is absolute or relative - -Offset: 24 - -## `subscription_fd_readwrite`: `Record` -The contents of a [`subscription`](#subscription) when type is type is -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 4 - -Alignment: 4 - -### Record members -- `fd`: [`fd`](#fd) -The file descriptor on which to wait for it to become ready for reading or writing. - -Offset: 0 - -## `subscription_u`: `Variant` -The contents of a [`subscription`](#subscription). - -Size: 40 - -Alignment: 8 - -### Variant Layout -- size: 40 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock`: [`subscription_clock`](#subscription_clock) - -- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -## `subscription`: `Record` -Subscription to an event. - -Size: 48 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that is attached to the subscription in the -implementation and returned through [`event::userdata`](#event.userdata). - -Offset: 0 - -- `u`: [`subscription_u`](#subscription_u) -The type of the event to which to subscribe, and the contents of the subscription. - -Offset: 8 - -## `exitcode`: `u8` -Exit code generated by a program when exiting. - -Size: 1 - -Alignment: 1 - -### Constants -- `success` - -- `failure` - -## `riflags`: `Record` -Flags provided to `sock_recv`. - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_peek`: `bool` -Returns the message without removing it from the socket's receive queue. - -Bit: 0 - -- `recv_waitall`: `bool` -On byte-stream sockets, block until the full amount of data can be returned. - -Bit: 1 - -## `roflags`: `Record` -Flags returned by `sock_recv`. - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_data_truncated`: `bool` -Returned by `sock_recv`: Message data has been truncated. - -Bit: 0 - -## `siflags`: `u16` -Flags provided to `sock_send`. As there are currently no flags -defined, it must be set to zero. - -Size: 2 - -Alignment: 2 - -## `sdflags`: `Record` -Which channels on a socket to shut down. - -Size: 1 - -Alignment: 1 - -### Record members -- `rd`: `bool` -Disables further receive operations. - -Bit: 0 - -- `wr`: `bool` -Disables further send operations. - -Bit: 1 - -## `preopentype`: `Variant` -Identifiers for preopened capabilities. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `dir` -A pre-opened directory. - -## `prestat_dir`: `Record` -The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). - -Size: 4 - -Alignment: 4 - -### Record members -- `pr_name_len`: [`size`](#size) -The length of the directory name for use with `fd_prestat_dir_name`. - -Offset: 0 - -## `prestat`: `Variant` -Information about a pre-opened capability. - -Size: 8 - -Alignment: 4 - -### Variant Layout -- size: 8 -- align: 4 -- tag_size: 1 -### Variant cases -- `dir`: [`prestat_dir`](#prestat_dir) -When type is [`preopentype::dir`](#preopentype.dir): - -# Modules -## wasi_ephemeral_fd -### Imports -#### Memory -### Functions - ---- - -#### `advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` -Provide file advisory information on a file descriptor. -Note: This is similar to `posix_fadvise` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset within the file to which the advisory applies. - -- `len`: [`filesize`](#filesize) -The length of the region to which the advisory applies. - -- `advice`: [`advice`](#advice) -The advice. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` -Force the allocation of space in a file. -Note: This is similar to `posix_fallocate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset at which to start the allocation. - -- `len`: [`filesize`](#filesize) -The length of the area that is allocated. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `datasync(fd: fd) -> Result<(), errno>` -Synchronize the data of a file to disk. -Note: This is similar to `fdatasync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fdstat_get(fd: fd) -> Result` -Get the attributes of a file descriptor. -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file descriptor's attributes are stored. - -###### Variant Layout -- size: 32 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`fdstat`](#fdstat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` -Adjust the flags associated with a file descriptor. -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`fdflags`](#fdflags) -The desired values of the file descriptor flags. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` -Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights - -##### Params -- `fd`: [`fd`](#fd) - -- `fs_rights_base`: [`rights`](#rights) -The desired rights of the file descriptor. - -- `fs_rights_inheriting`: [`rights`](#rights) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_get(fd: fd) -> Result` -Return the attributes of an open file. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 72 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` -Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. -Note: This is similar to `ftruncate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `size`: [`filesize`](#filesize) -The desired file size. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of an open file or directory. -Note: This is similar to `futimens` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `permissions_set(fd: fd, permissions: permissions) -> Result<(), errno>` -Set the permissions of a file or directory. - -This sets the permissions associated with a file or directory in -a filesystem at the time it is called. The ability to actually access -a file or directory may depend on additional permissions not reflected -here. - -Note: This is similar `fchmod` in POSIX. - -Unlike POSIX, this doesn't expose a user/group/other distinction; -implementations in POSIX environments are suggested to consult the -umask to determine which of the user/group/other flags to modify. - -##### Params -- `fd`: [`fd`](#fd) - -- `permissions`: [`permissions`](#permissions) -The permissions associated with the file. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` -Read from a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `preadv` in Linux (and other Unix-es). - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors in which to store data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to read. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` -Write to a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `pwritev` in Linux (and other Unix-es). - -Like Linux (and other Unix-es), any calls of [`pwrite`](#pwrite) (and other -functions to read or write) for a regular file by other threads in the -WASI process should not be interleaved while [`pwrite`](#pwrite) is executed. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to write. - -##### Results -- `error`: `Result` -The number of bytes written. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `read(fd: fd, iovs: iovec_array) -> Result` -Read from a file descriptor. -Note: This is similar to `readv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` -Read directory entries from a directory. -When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a [`dirent`](#dirent) object, -followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory -entry. -This function fills the output buffer as much as possible, potentially -truncating the last directory entry. This allows the caller to grow its -read buffer size in case it's too small to fit a single large directory -entry, or skip the oversized directory entry. - -##### Params -- `fd`: [`fd`](#fd) - -- `buf`: `Pointer` -The buffer where directory entries are stored - -- `buf_len`: [`size`](#size) - -- `cookie`: [`dircookie`](#dircookie) -The location within the directory to start reading - -##### Results -- `error`: `Result` -The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `renumber(fd: fd, to: fd) -> Result<(), errno>` -Atomically replace a file descriptor by renumbering another file descriptor. -Due to the strong focus on thread safety, this environment does not provide -a mechanism to duplicate or renumber a file descriptor to an arbitrary -number, like `dup2()`. This would be prone to race conditions, as an actual -file descriptor with the same number could be allocated by a different -thread at the same time. -This function provides a way to atomically renumber file descriptors, which -would disappear if `dup2()` were to be removed entirely. - -##### Params -- `fd`: [`fd`](#fd) - -- `to`: [`fd`](#fd) -The file descriptor to overwrite. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `seek(fd: fd, offset: filedelta, whence: whence) -> Result` -Move the offset of a file descriptor. -Note: This is similar to `lseek` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filedelta`](#filedelta) -The number of bytes to move. - -- `whence`: [`whence`](#whence) -The base from which the offset is relative. - -##### Results -- `error`: `Result` -The new offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `sync(fd: fd) -> Result<(), errno>` -Synchronize the data and metadata of a file to disk. -Note: This is similar to `fsync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `tell(fd: fd) -> Result` -Return the current offset of a file descriptor. -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The current offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `write(fd: fd, iovs: ciovec_array) -> Result` -Write to a file descriptor. -Note: This is similar to `writev` in POSIX. - -Like POSIX, any calls of [`write`](#write) (and other functions to read or write) -for a regular file by other threads in the WASI process should not be -interleaved while [`write`](#write) is executed. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -##### Results -- `error`: `Result` -The number of bytes written. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_path -### Imports -#### Memory -### Functions - ---- - -#### `create_directory(fd: fd, path: string) -> Result<(), errno>` -Create a directory. -Note: This is similar to `mkdirat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path at which to create the directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` -Return the attributes of a file or directory. -Note: This is similar to `stat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to inspect. - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 72 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of a file or directory. -Note: This is similar to `utimensat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to operate on. - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `permissions_set(fd: fd, flags: lookupflags, path: string, permissions: permissions) -> Result<(), errno>` -Set the permissions of a file or directory. - -This sets the permissions associated with a file or directory in -a filesystem at the time it is called. The ability to actually access -a file or directory may depend on additional permissions not reflected -here. - -Note: This is similar to `fchmodat` in POSIX. - -Unlike POSIX, this doesn't expose a user/group/other distinction; -implementations in POSIX environments are suggested to consult the -umask to determine which of the user/group/other flags to modify. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path to a file to query. - -- `permissions`: [`permissions`](#permissions) -The permissions to associate with the file. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Create a hard link. -Note: This is similar to `linkat` in POSIX. - -##### Params -- `old_fd`: [`fd`](#fd) - -- `old_flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `old_path`: `string` -The source path from which to link. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path at which to create the hard link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, permissions: permissions) -> Result` -Open a file or directory. -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since this -is error-prone in multi-threaded contexts. The returned file descriptor is -guaranteed to be less than 2**31. -Note: This is similar to `openat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `dirflags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The relative path of the file or directory to open, relative to the -[`fd`](#fd) directory. - -- `oflags`: [`oflags`](#oflags) -The method by which to open the file. - -- `fs_rights_base`: [`rights`](#rights) -The initial rights of the newly created file descriptor. The -implementation is allowed to return a file descriptor with fewer rights -than specified, if and only if those rights do not apply to the type of -file being opened. -The *base* rights are rights that will apply to operations using the file -descriptor itself, while the *inheriting* rights are rights that apply to -file descriptors derived from it. - -- `fs_rights_inheriting`: [`rights`](#rights) - -- `fdflags`: [`fdflags`](#fdflags) - -- `permissions`: [`permissions`](#permissions) -If a file is created, the filesystem permissions to associate with it. - -##### Results -- `error`: `Result` -The file descriptor of the file that has been opened. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`fd`](#fd) - -- `err`: [`errno`](#errno) - - ---- - -#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` -Read the contents of a symbolic link. -Note: This is similar to `readlinkat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path of the symbolic link from which to read. - -- `buf`: `Pointer` -The buffer to which to write the contents of the symbolic link. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result` -The number of bytes placed in the buffer. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `remove_directory(fd: fd, path: string) -> Result<(), errno>` -Remove a directory. -Return [`errno::notempty`](#errno.notempty) if the directory is not empty. -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a directory to remove. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Rename a file or directory. -Note: This is similar to `renameat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `old_path`: `string` -The source path of the file or directory to rename. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path to which to rename the file or directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` -Create a symbolic link. -Note: This is similar to `symlinkat` in POSIX. - -##### Params -- `old_path`: `string` -The contents of the symbolic link. - -- `fd`: [`fd`](#fd) - -- `new_path`: `string` -The destination path at which to create the symbolic link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `unlink_file(fd: fd, path: string) -> Result<(), errno>` -Unlink a file. -Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a file to unlink. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - diff --git a/proposals/filesystem/standard/wasi-filesystem/witx/file_io.witx b/proposals/filesystem/standard/wasi-filesystem/witx/file_io.witx deleted file mode 100644 index f06827e2c..000000000 --- a/proposals/filesystem/standard/wasi-filesystem/witx/file_io.witx +++ /dev/null @@ -1,236 +0,0 @@ -;; WASI File I/O. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_fd - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Provide file advisory information on a file descriptor. - ;;; Note: This is similar to `posix_fadvise` in POSIX. - (@interface func (export "advise") - (param $fd $fd) - ;;; The offset within the file to which the advisory applies. - (param $offset $filesize) - ;;; The length of the region to which the advisory applies. - (param $len $filesize) - ;;; The advice. - (param $advice $advice) - (result $error (expected (error $errno))) - ) - - ;;; Force the allocation of space in a file. - ;;; Note: This is similar to `posix_fallocate` in POSIX. - (@interface func (export "allocate") - (param $fd $fd) - ;;; The offset at which to start the allocation. - (param $offset $filesize) - ;;; The length of the area that is allocated. - (param $len $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Synchronize the data of a file to disk. - ;;; Note: This is similar to `fdatasync` in POSIX. - (@interface func (export "datasync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Get the attributes of a file descriptor. - ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (@interface func (export "fdstat_get") - (param $fd $fd) - ;;; The buffer where the file descriptor's attributes are stored. - (result $error (expected $fdstat (error $errno))) - ) - - ;;; Adjust the flags associated with a file descriptor. - ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (@interface func (export "fdstat_set_flags") - (param $fd $fd) - ;;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights - (@interface func (export "fdstat_set_rights") - (param $fd $fd) - ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of an open file. - (@interface func (export "filestat_get") - (param $fd $fd) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;;; Note: This is similar to `ftruncate` in POSIX. - (@interface func (export "filestat_set_size") - (param $fd $fd) - ;;; The desired file size. - (param $size $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the timestamps of an open file or directory. - ;;; Note: This is similar to `futimens` in POSIX. - (@interface func (export "filestat_set_times") - (param $fd $fd) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Set the permissions of a file or directory. - ;;; - ;;; This sets the permissions associated with a file or directory in - ;;; a filesystem at the time it is called. The ability to actually access - ;;; a file or directory may depend on additional permissions not reflected - ;;; here. - ;;; - ;;; Note: This is similar `fchmod` in POSIX. - ;;; - ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; - ;;; implementations in POSIX environments are suggested to consult the - ;;; umask to determine which of the user/group/other flags to modify. - (@interface func (export "permissions_set") - (param $fd $fd) - ;;; The permissions associated with the file. - (param $permissions $permissions) - (result $error (expected (error $errno))) - ) - - ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in Linux (and other Unix-es). - (@interface func (export "pread") - (param $fd $fd) - ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_array) - ;;; The offset within the file at which to read. - (param $offset $filesize) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in Linux (and other Unix-es). - ;;; - ;;; Like Linux (and other Unix-es), any calls of `pwrite` (and other - ;;; functions to read or write) for a regular file by other threads in the - ;;; WASI process should not be interleaved while `pwrite` is executed. - (@interface func (export "pwrite") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The offset within the file at which to write. - (param $offset $filesize) - ;;; The number of bytes written. - (result $error (expected $size (error $errno))) - ) - - ;;; Read from a file descriptor. - ;;; Note: This is similar to `readv` in POSIX. - (@interface func (export "read") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_array) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Read directory entries from a directory. - ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a `dirent` object, - ;;; followed by `dirent::d_namlen` bytes holding the name of the directory - ;;; entry. - ;; - ;;; This function fills the output buffer as much as possible, potentially - ;;; truncating the last directory entry. This allows the caller to grow its - ;;; read buffer size in case it's too small to fit a single large directory - ;;; entry, or skip the oversized directory entry. - (@interface func (export "readdir") - (param $fd $fd) - ;;; The buffer where directory entries are stored - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The location within the directory to start reading - (param $cookie $dircookie) - ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $error (expected $size (error $errno))) - ) - - ;;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;;; Due to the strong focus on thread safety, this environment does not provide - ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;;; file descriptor with the same number could be allocated by a different - ;;; thread at the same time. - ;; - ;;; This function provides a way to atomically renumber file descriptors, which - ;;; would disappear if `dup2()` were to be removed entirely. - (@interface func (export "renumber") - (param $fd $fd) - ;;; The file descriptor to overwrite. - (param $to $fd) - (result $error (expected (error $errno))) - ) - - ;;; Move the offset of a file descriptor. - ;;; Note: This is similar to `lseek` in POSIX. - (@interface func (export "seek") - (param $fd $fd) - ;;; The number of bytes to move. - (param $offset $filedelta) - ;;; The base from which the offset is relative. - (param $whence $whence) - ;;; The new offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Synchronize the data and metadata of a file to disk. - ;;; Note: This is similar to `fsync` in POSIX. - (@interface func (export "sync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Return the current offset of a file descriptor. - ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (@interface func (export "tell") - (param $fd $fd) - ;;; The current offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Write to a file descriptor. - ;;; Note: This is similar to `writev` in POSIX. - ;;; - ;;; Like POSIX, any calls of `write` (and other functions to read or write) - ;;; for a regular file by other threads in the WASI process should not be - ;;; interleaved while `write` is executed. - (@interface func (export "write") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The number of bytes written. - (result $error (expected $size (error $errno))) - ) -) diff --git a/proposals/filesystem/standard/wasi-filesystem/witx/path.witx b/proposals/filesystem/standard/wasi-filesystem/witx/path.witx deleted file mode 100644 index 2901decb7..000000000 --- a/proposals/filesystem/standard/wasi-filesystem/witx/path.witx +++ /dev/null @@ -1,181 +0,0 @@ -;; WASI Filesystem Path API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_path - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Create a directory. - ;;; Note: This is similar to `mkdirat` in POSIX. - (@interface func (export "create_directory") - (param $fd $fd) - ;;; The path at which to create the directory. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of a file or directory. - ;;; Note: This is similar to `stat` in POSIX. - (@interface func (export "filestat_get") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to inspect. - (param $path string) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the timestamps of a file or directory. - ;;; Note: This is similar to `utimensat` in POSIX. - (@interface func (export "filestat_set_times") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to operate on. - (param $path string) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Set the permissions of a file or directory. - ;;; - ;;; This sets the permissions associated with a file or directory in - ;;; a filesystem at the time it is called. The ability to actually access - ;;; a file or directory may depend on additional permissions not reflected - ;;; here. - ;;; - ;;; Note: This is similar to `fchmodat` in POSIX. - ;;; - ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; - ;;; implementations in POSIX environments are suggested to consult the - ;;; umask to determine which of the user/group/other flags to modify. - (@interface func (export "permissions_set") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path to a file to query. - (param $path string) - ;;; The permissions to associate with the file. - (param $permissions $permissions) - (result $error (expected (error $errno))) - ) - - ;;; Create a hard link. - ;;; Note: This is similar to `linkat` in POSIX. - (@interface func (export "link") - (param $old_fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags) - ;;; The source path from which to link. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path at which to create the hard link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Open a file or directory. - ;; - ;;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;;; file descriptor not currently open; it is randomized to prevent - ;;; applications from depending on making assumptions about indexes, since this - ;;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;;; guaranteed to be less than 2**31. - ;; - ;;; Note: This is similar to `openat` in POSIX. - (@interface func (export "open") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags) - ;;; The relative path of the file or directory to open, relative to the - ;;; `fd` directory. - (param $path string) - ;;; The method by which to open the file. - (param $oflags $oflags) - ;;; The initial rights of the newly created file descriptor. The - ;;; implementation is allowed to return a file descriptor with fewer rights - ;;; than specified, if and only if those rights do not apply to the type of - ;;; file being opened. - ;; - ;;; The *base* rights are rights that will apply to operations using the file - ;;; descriptor itself, while the *inheriting* rights are rights that apply to - ;;; file descriptors derived from it. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (param $fdflags $fdflags) - ;;; If a file is created, the filesystem permissions to associate with it. - (param $permissions $permissions) - ;;; The file descriptor of the file that has been opened. - (result $error (expected $fd (error $errno))) - ) - - ;;; Read the contents of a symbolic link. - ;;; Note: This is similar to `readlinkat` in POSIX. - (@interface func (export "readlink") - (param $fd $fd) - ;;; The path of the symbolic link from which to read. - (param $path string) - ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer (@witx char8))) - (param $buf_len $size) - ;;; The number of bytes placed in the buffer. - (result $error (expected $size (error $errno))) - ) - - ;;; Remove a directory. - ;;; Return `errno::notempty` if the directory is not empty. - ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (@interface func (export "remove_directory") - (param $fd $fd) - ;;; The path to a directory to remove. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Rename a file or directory. - ;;; Note: This is similar to `renameat` in POSIX. - (@interface func (export "rename") - (param $fd $fd) - ;;; The source path of the file or directory to rename. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Create a symbolic link. - ;;; Note: This is similar to `symlinkat` in POSIX. - (@interface func (export "symlink") - ;;; The contents of the symbolic link. - (param $old_path string) - (param $fd $fd) - ;;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Unlink a file. - ;;; Return `errno::isdir` if the path refers to a directory. - ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (@interface func (export "unlink_file") - (param $fd $fd) - ;;; The path to a file to unlink. - (param $path string) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx b/proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx deleted file mode 100644 index 8821132c6..000000000 --- a/proposals/filesystem/standard/wasi-filesystem/witx/typenames.witx +++ /dev/null @@ -1,708 +0,0 @@ -;; Type names used by low-level WASI interfaces. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -;;; An array size. -;;; -;;; Note: This is similar to `size_t` in POSIX. -(typename $size (@witx usize)) - -;;; Non-negative file size or length of a region within a file. -(typename $filesize u64) - -;;; Timestamp in nanoseconds. -(typename $timestamp u64) - -;;; Identifiers for clocks. -(typename $clockid - (enum (@witx tag u32) - ;;; The clock measuring real time. Time value zero corresponds with - ;;; 1970-01-01T00:00:00Z. - $realtime - ;;; The store-wide monotonic clock, which is defined as a clock measuring - ;;; real time, whose value cannot be adjusted and which cannot have negative - ;;; clock jumps. The epoch of this clock is undefined. The absolute time - ;;; value of this clock therefore has no meaning. - $monotonic - ) -) - -;;; Error codes returned by functions. -;;; Not all of these error codes are returned by the functions provided by this -;;; API; some are used in higher-level library layers, and others are provided -;;; merely for alignment with POSIX. -(typename $errno - (enum (@witx tag u16) - ;;; No error occurred. System call completed successfully. - $success - ;;; Argument list too long. This is similar to `E2BIG` in POSIX. - $toobig - ;;; Permission denied. - $access - ;;; Address in use. - $addrinuse - ;;; Address not available. - $addrnotavail - ;;; Address family not supported. - $afnosupport - ;;; Resource unavailable, or operation would block. - $again - ;;; Connection already in progress. - $already - ;;; Bad file descriptor. - $badf - ;;; Bad message. - $badmsg - ;;; Device or resource busy. - $busy - ;;; Operation canceled. - $canceled - ;;; No child processes. - $child - ;;; Connection aborted. - $connaborted - ;;; Connection refused. - $connrefused - ;;; Connection reset. - $connreset - ;;; Resource deadlock would occur. - $deadlk - ;;; Destination address required. - $destaddrreq - ;;; Mathematics argument out of domain of function. - $dom - ;;; Reserved. - $dquot - ;;; File exists. - $exist - ;;; Bad address. - $fault - ;;; File too large. - $fbig - ;;; Host is unreachable. - $hostunreach - ;;; Identifier removed. - $idrm - ;;; Illegal byte sequence. - $ilseq - ;;; Operation in progress. - $inprogress - ;;; Interrupted function. - $intr - ;;; Invalid argument. - $inval - ;;; I/O error. - $io - ;;; Socket is connected. - $isconn - ;;; Is a directory. - $isdir - ;;; Too many levels of symbolic links. - $loop - ;;; File descriptor value too large. - $mfile - ;;; Too many links. - $mlink - ;;; Message too large. - $msgsize - ;;; Reserved. - $multihop - ;;; Filename too long. - $nametoolong - ;;; Network is down. - $netdown - ;;; Connection aborted by network. - $netreset - ;;; Network unreachable. - $netunreach - ;;; Too many files open in system. - $nfile - ;;; No buffer space available. - $nobufs - ;;; No such device. - $nodev - ;;; No such file or directory. - $noent - ;;; Executable file format error. - $noexec - ;;; No locks available. - $nolck - ;;; Reserved. - $nolink - ;;; Not enough space. - $nomem - ;;; No message of the desired type. - $nomsg - ;;; Protocol not available. - $noprotoopt - ;;; No space left on device. - $nospc - ;;; Function not supported. - $nosys - ;;; The socket is not connected. - $notconn - ;;; Not a directory or a symbolic link to a directory. - $notdir - ;;; Directory not empty. - $notempty - ;;; State not recoverable. - $notrecoverable - ;;; Not a socket. - $notsock - ;;; Not supported, or operation not supported on socket. - $notsup - ;;; Inappropriate I/O control operation. - $notty - ;;; No such device or address. - $nxio - ;;; Value too large to be stored in data type. - $overflow - ;;; Previous owner died. - $ownerdead - ;;; Operation not permitted. - $perm - ;;; Broken pipe. - $pipe - ;;; Protocol error. - $proto - ;;; Protocol not supported. - $protonosupport - ;;; Protocol wrong type for socket. - $prototype - ;;; Result too large. - $range - ;;; Read-only file system. - $rofs - ;;; Invalid seek. - $spipe - ;;; No such process. - $srch - ;;; Reserved. - $stale - ;;; Connection timed out. - $timedout - ;;; Text file busy. - $txtbsy - ;;; Cross-device link. - $xdev - ;;; Extension: Capabilities insufficient. - $notcapable - ) -) - -;;; File descriptor rights, determining which actions may be performed. -(typename $rights - (flags (@witx repr u64) - ;;; The right to invoke `fd_datasync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::dsync`. - $fd_datasync - ;;; The right to invoke `fd_read` and `sock_recv`. - ;; - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. - $fd_read - ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. - $fd_seek - ;;; The right to invoke `fd_fdstat_set_flags`. - $fd_fdstat_set_flags - ;;; The right to invoke `fd_sync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. - $fd_sync - ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to - ;;; invoke `fd_tell`. - $fd_tell - ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. - $fd_write - ;;; The right to invoke `fd_advise`. - $fd_advise - ;;; The right to invoke `fd_allocate`. - $fd_allocate - ;;; The right to invoke `path_create_directory`. - $path_create_directory - ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::create`. - $path_create_file - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; source directory. - $path_link_source - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; target directory. - $path_link_target - ;;; The right to invoke `path_open`. - $path_open - ;;; The right to invoke `fd_readdir`. - $fd_readdir - ;;; The right to invoke `path_readlink`. - $path_readlink - ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $path_rename_source - ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $path_rename_target - ;;; The right to invoke `path_filestat_get`. - $path_filestat_get - ;;; The right to change a file's size. - ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. - ;;; Note: there is no function named `path_filestat_set_size`. This follows POSIX design, - ;;; which only has `ftruncate` and does not provide `ftruncateat`. - ;;; While such function would be desirable from the API design perspective, there are virtually - ;;; no use cases for it since no code written for POSIX systems would use it. - ;;; Moreover, implementing it would require multiple syscalls, leading to inferior performance. - $path_filestat_set_size - ;;; The right to invoke `path_filestat_set_times`. - $path_filestat_set_times - ;;; The right to invoke `path_permissions_set`. - $path_permissions_set - ;;; The right to invoke `fd_filestat_get`. - $fd_filestat_get - ;;; The right to invoke `fd_filestat_set_size`. - $fd_filestat_set_size - ;;; The right to invoke `fd_filestat_set_times`. - $fd_filestat_set_times - ;;; The right to invoke `fd_permissions_set`. - $fd_permissions_set - ;;; The right to invoke `path_symlink`. - $path_symlink - ;;; The right to invoke `path_remove_directory`. - $path_remove_directory - ;;; The right to invoke `path_unlink_file`. - $path_unlink_file - ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. - ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. - $poll_fd_readwrite - ;;; The right to invoke `sock_shutdown`. - $sock_shutdown - ) -) - -;;; A file descriptor handle. -(typename $fd (handle)) - -;;; A region of memory for scatter/gather reads. -(typename $iovec - (record - ;;; The address of the buffer to be filled. - (field $buf (@witx pointer u8)) - ;;; The length of the buffer to be filled. - (field $buf_len $size) - ) -) - -;;; A region of memory for scatter/gather writes. -(typename $ciovec - (record - ;;; The address of the buffer to be written. - (field $buf (@witx const_pointer u8)) - ;;; The length of the buffer to be written. - (field $buf_len $size) - ) -) - -(typename $iovec_array (list $iovec)) -(typename $ciovec_array (list $ciovec)) - -;;; Relative offset within a file. -(typename $filedelta s64) - -;;; The position relative to which to set the offset of the file descriptor. -(typename $whence - (enum (@witx tag u8) - ;;; Seek relative to start-of-file. - $set - ;;; Seek relative to current position. - $cur - ;;; Seek relative to end-of-file. - $end - ) -) - -;;; A reference to the offset of a directory entry. -(typename $dircookie u64) - -;;; In an `fd_readdir` call, this value signifies the start of the directory. -(@witx const $dircookie $start 0) - -;;; The type for the `dirent::d_namlen` field of `dirent`. -(typename $dirnamlen u32) - -;;; File serial number that is unique within its file system. -(typename $inode u64) - -;;; The type of a file descriptor or file. -(typename $filetype - (enum (@witx tag u8) - ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $unknown - ;;; The file descriptor or file refers to a block device inode. - $block_device - ;;; The file descriptor or file refers to a character device inode. - $character_device - ;;; The file descriptor or file refers to a directory inode. - $directory - ;;; The file descriptor or file refers to a regular file inode. - $regular_file - ;;; The file descriptor or file refers to a datagram socket. - $socket_dgram - ;;; The file descriptor or file refers to a byte-stream socket. - $socket_stream - ;;; The file refers to a symbolic link inode. - $symbolic_link - ;;; The file descriptor or file refers to a FIFO. - $fifo - ) -) - -;;; A directory entry. -(typename $dirent - (record - ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie) - ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode) - ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) - ) -) - -;;; File or memory access pattern advisory information. -(typename $advice - (enum (@witx tag u8) - ;;; The application has no advice to give on its behavior with respect to the specified data. - $normal - ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $sequential - ;;; The application expects to access the specified data in a random order. - $random - ;;; The application expects to access the specified data in the near future. - $willneed - ;;; The application expects that it will not access the specified data in the near future. - $dontneed - ;;; The application expects to access the specified data once and then not reuse it thereafter. - $noreuse - ) -) - -;;; File descriptor flags. -(typename $fdflags - (flags (@witx repr u16) - ;;; Append mode: Data written to the file is always appended to the file's end. - $append - ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $dsync - ;;; Non-blocking mode. - $nonblock - ;;; Synchronized read I/O operations. - $rsync - ;;; Write according to synchronized I/O file integrity completion. In - ;;; addition to synchronizing the data stored in the file, the implementation - ;;; may also synchronously update the file's metadata. - $sync - ) -) - -;;; File descriptor attributes. -(typename $fdstat - (record - ;;; File type. - (field $fs_filetype $filetype) - ;;; File descriptor flags. - (field $fs_flags $fdflags) - ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights) - ;;; Maximum set of rights that may be installed on new file descriptors that - ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights) - ) -) - -;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode` to uniquely identify a file or directory in the filesystem. -(typename $device u64) - -;;; Which file time attributes to adjust. -(typename $fstflags - (flags (@witx repr u16) - ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. - $atim - ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. - $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. - $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. - $mtim_now - ) -) - -;;; Flags determining the method of how paths are resolved. -(typename $lookupflags - (flags (@witx repr u32) - ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $symlink_follow - ) -) - -;;; Open flags used by `path_open`. -(typename $oflags - (flags (@witx repr u16) - ;;; Create file if it does not exist. - $create - ;;; Fail if not a directory. - $directory - ;;; Fail if file already exists. - $excl - ;;; Truncate file to size 0. - $trunc - ) -) - -;;; Number of hard links to an inode. -(typename $linkcount u64) - -;;; File permissions. This represents the permissions associated with a -;;; file in a filesystem, and don't fully reflect all the conditions -;;; which determine whether a given WASI program can access the file. -(typename $permissions - (flags (@witx repr u8) - ;;; For files, permission to read the file. - ;;; For directories, permission to do `readdir` and access files - ;;; within the directory. - ;;; - ;;; Note: This is similar to the read bit being set on files, and the - ;;; read *and* execute bits being set on directories, in POSIX. - $read - - ;;; For files, permission to mutate the file. - ;;; For directories, permission to create, remove, and rename items - ;;; within the directory. - $write - - ;;; For files, permission to "execute" the file, using whatever - ;;; concept of "executing" the host filesystem has. - ;;; This flag is not valid for directories. - $execute - - ;;; For filesystems which have a concept of multiple "users", this flag - ;;; indicates that the file is only accessible by the effective "user" - ;;; that the WASI store uses to access the filesystem, and inaccessible - ;;; to other "users". - $private - ) -) - -;;; File attributes. -(typename $filestat - (record - ;;; Device ID of device containing the file. - (field $dev $device) - ;;; File serial number. - (field $ino $inode) - ;;; File type. - (field $filetype $filetype) - ;;; File permissions. - (field $permissions $permissions) - ;;; Number of hard links to the file. - (field $nlink $linkcount) - ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $size $filesize) - ;;; Last data access timestamp. - (field $atim $timestamp) - ;;; Last data modification timestamp. - (field $mtim $timestamp) - ;;; Last file status change timestamp. - (field $ctim $timestamp) - ) -) - -;;; User-provided value that may be attached to objects that is retained when -;;; extracted from the implementation. -(typename $userdata u64) - -;;; Type of a subscription to an event or its occurrence. -(typename $eventtype - (enum (@witx tag u8) - ;;; The time value of clock `subscription_clock::id` has - ;;; reached timestamp `subscription_clock::timeout`. - $clock - ;;; File descriptor `subscription_fd_readwrite::fd` has data - ;;; available for reading. This event always triggers for regular files. - $fd_read - ;;; File descriptor `subscription_fd_readwrite::fd` has capacity - ;;; available for writing. This event always triggers for regular files. - $fd_write - ) -) - -;;; The state of the file descriptor subscribed to with -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $eventrwflags - (flags (@witx repr u16) - ;;; The peer of this socket has closed or disconnected. - $fd_readwrite_hangup - ) -) - -;;; The contents of an `event` when type is `eventtype::fd_read` or -;;; `eventtype::fd_write`. -(typename $event_fd_readwrite - (record - ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize) - ;;; The state of the file descriptor. - (field $flags $eventrwflags) - ) -) - -;;; The contents of an `event`. -(typename $event_u - (variant (@witx tag $eventtype) - (case $fd_read $event_fd_readwrite) - (case $fd_write $event_fd_readwrite) - (case $clock) - ) -) - -;;; An event that occurred. -(typename $event - (record - ;;; User-provided value that got attached to `subscription::userdata`. - (field $userdata $userdata) - ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno) - ;;; The type of the event that occurred, and the contents of the event - (field $u $event_u) - ) -) - -;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_clock::timeout`. -(typename $subclockflags - (flags (@witx repr u16) - ;;; If set, treat the timestamp provided in - ;;; `subscription_clock::timeout` as an absolute timestamp of clock - ;;; `subscription_clock::id`. If clear, treat the timestamp - ;;; provided in `subscription_clock::timeout` relative to the - ;;; current time value of clock `subscription_clock::id`. - $subscription_clock_abstime - ) -) - -;;; The contents of a `subscription` when type is `eventtype::clock`. -(typename $subscription_clock - (record - ;;; The clock against which to compare the timestamp. - (field $id $clockid) - ;;; The absolute or relative timestamp. - (field $timeout $timestamp) - ;;; The amount of time that the implementation may wait additionally - ;;; to coalesce with other events. - (field $precision $timestamp) - ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags) - ) -) - -;;; The contents of a `subscription` when type is type is -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $subscription_fd_readwrite - (record - ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $fd $fd) - ) -) - -;;; The contents of a `subscription`. -(typename $subscription_u - (union (@witx tag $eventtype) - $subscription_clock - $subscription_fd_readwrite - $subscription_fd_readwrite - ) -) - -;;; Subscription to an event. -(typename $subscription - (record - ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event::userdata`. - (field $userdata $userdata) - ;;; The type of the event to which to subscribe, and the contents of the subscription. - (field $u $subscription_u) - ) -) - -;;; Exit code generated by a program when exiting. -(typename $exitcode u8) - -;;; Indicate the program exited successfully. -;;; -;;; Note: This is similar to `EXIT_SUCCESS` in POSIX. -(@witx const $exitcode $success 0) - -;;; Indicate the program exited unsuccessfully. -;;; -;;; Note: This is similar to `EXIT_FAILURE` in POSIX. -(@witx const $exitcode $failure 1) - -;;; Flags provided to `sock_recv`. -(typename $riflags - (flags (@witx repr u16) - ;;; Returns the message without removing it from the socket's receive queue. - $recv_peek - ;;; On byte-stream sockets, block until the full amount of data can be returned. - $recv_waitall - ) -) - -;;; Flags returned by `sock_recv`. -(typename $roflags - (flags (@witx repr u16) - ;;; Returned by `sock_recv`: Message data has been truncated. - $recv_data_truncated - ) -) - -;;; Flags provided to `sock_send`. As there are currently no flags -;;; defined, it must be set to zero. -(typename $siflags u16) - -;;; Which channels on a socket to shut down. -(typename $sdflags - (flags (@witx repr u8) - ;;; Disables further receive operations. - $rd - ;;; Disables further send operations. - $wr - ) -) - -;;; Identifiers for preopened capabilities. -(typename $preopentype - (enum (@witx tag u8) - ;;; A pre-opened directory. - $dir - ) -) - -;;; The contents of a `prestat` when its type is `preopentype::dir`. -(typename $prestat_dir - (record - ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size) - ) -) - -;;; Information about a pre-opened capability. -(typename $prestat - (union (@witx tag $preopentype) - ;;; When type is `preopentype::dir`: - $prestat_dir - ) -) diff --git a/proposals/filesystem/tools/repo_docs.sh b/proposals/filesystem/tools/repo_docs.sh deleted file mode 100755 index 76d1462bc..000000000 --- a/proposals/filesystem/tools/repo_docs.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -set -ex -cd $(dirname $(realpath $0))/witx -cargo run -p witx-cli -- docs $1 ../../phases/snapshot/witx/wasi_snapshot_preview1.witx --output ../../phases/snapshot/docs.md -cargo run -p witx-cli -- docs $1 ../../phases/old/snapshot_0/witx/wasi_unstable.witx --output ../../phases/old/snapshot_0/docs.md -cargo run -p witx-cli -- docs $1 \ - ../../phases/ephemeral/witx/wasi_ephemeral_args.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_clock.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_environ.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_fd.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_path.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_poll.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_proc.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_random.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_sched.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_sock.witx \ - --output ../../phases/ephemeral/docs.md - -for dir in ../../standard/*/witx; do - cargo run -p witx-cli -- docs $1 "$dir"/*.witx \ - --output "$dir"/../docs.md -done diff --git a/proposals/filesystem/tools/witx/.gitignore b/proposals/filesystem/tools/witx/.gitignore deleted file mode 100644 index a9d37c560..000000000 --- a/proposals/filesystem/tools/witx/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target -Cargo.lock diff --git a/proposals/filesystem/tools/witx/Cargo.toml b/proposals/filesystem/tools/witx/Cargo.toml deleted file mode 100644 index 1dd39a8b1..000000000 --- a/proposals/filesystem/tools/witx/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -[package] -name = "witx" -version = "0.9.0" -description = "Parse and validate witx file format" -homepage = "https://github.com/WebAssembly/WASI" -repository = "https://github.com/WebAssembly/WASI" -license = "Apache-2.0" -categories = ["wasm"] -keywords = ["webassembly", "wasm"] -authors = ["Pat Hickey ", "Alex Crichton "] -edition = "2018" - -[lib] -crate-type=["rlib"] - -[dependencies] -anyhow = "1" -log = "0.4" -thiserror = "1.0" -wast = { version = "33.0.0", default-features = false } - -[dev-dependencies] -rayon = "1.0" - -[[test]] -name = "witxt" -harness = false - -[workspace] -members = [ - "cli", -] diff --git a/proposals/filesystem/tools/witx/LICENSE b/proposals/filesystem/tools/witx/LICENSE deleted file mode 100644 index e061f56ab..000000000 --- a/proposals/filesystem/tools/witx/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2019 WebAssembly Community Group participants - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/proposals/filesystem/tools/witx/cli/Cargo.toml b/proposals/filesystem/tools/witx/cli/Cargo.toml deleted file mode 100644 index 6f45ef3d9..000000000 --- a/proposals/filesystem/tools/witx/cli/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "witx-cli" -version = "0.9.0" -description = "CLI for operating on witx file format" -homepage = "https://github.com/WebAssembly/WASI" -repository = "https://github.com/WebAssembly/WASI" -license = "Apache-2.0" -categories = ["wasm"] -keywords = ["webassembly", "wasm"] -authors = ["Pat Hickey ", "Alex Crichton "] -edition = "2018" - -[[bin]] -name = "witx" -path = "src/main.rs" - -[dependencies] -witx = { path = "../", version = "0.9.0" } -anyhow = "1" -log = "0.4" -thiserror = "1.0" -diff = "0.1.11" -pretty_env_logger = "0.4" -structopt = "0.3" -rayon = "1.0" diff --git a/proposals/filesystem/tools/witx/cli/src/main.rs b/proposals/filesystem/tools/witx/cli/src/main.rs deleted file mode 100644 index bdb1c6a9c..000000000 --- a/proposals/filesystem/tools/witx/cli/src/main.rs +++ /dev/null @@ -1,268 +0,0 @@ -use anyhow::{anyhow, bail, Result}; -use std::fs::File; -use std::io::Write; -use std::path::{Path, PathBuf}; -use std::process; -use structopt::{clap::AppSettings, StructOpt}; -use witx::{load, Document, Documentation}; - -/// Validate and process witx files -#[derive(StructOpt, Debug)] -#[structopt( - name = "witx", - version = env!("CARGO_PKG_VERSION"), - global_settings = &[ - AppSettings::VersionlessSubcommands, - AppSettings::ColoredHelp - ] -)] -struct Args { - #[structopt(short = "v", long = "verbose")] - verbose: bool, - - #[structopt(subcommand)] - cmd: Command, -} - -#[derive(StructOpt, Debug)] -enum Command { - /// Output documentation - Docs { - /// Path to root of witx document - #[structopt(number_of_values = 1, value_name = "INPUT", parse(from_os_str))] - input: Vec, - /// Perform check that output matches witx documents - #[structopt(long = "check")] - check: bool, - /// Path to generated documentation in Markdown format - #[structopt( - short = "o", - long = "output", - value_name = "OUTPUT", - parse(from_os_str) - )] - output: Option, - }, - /// Examine differences between interfaces - Polyfill { - /// Path to root of witx document - #[structopt( - required = true, - number_of_values = 1, - value_name = "INPUT", - parse(from_os_str) - )] - input: Vec, - /// Path to root of witx document describing interface to polyfill - #[structopt( - required = true, - number_of_values = 1, - value_name = "OLDER_INTERFACE", - parse(from_os_str) - )] - older_interface: Vec, - /// Module to examine (use newname=oldname syntax if name is different - /// between new and old interfaces) - #[structopt( - short = "m", - long = "module_mapping", - required = true, - number_of_values = 1, - value_name = "NEWNAME=OLDNAME", - parse(try_from_str = parse_module_mapping) - )] - module_mapping: Vec<(String, String)>, - }, -} - -pub fn main() { - let args = Args::from_args(); - pretty_env_logger::init(); - let verbose = args.verbose; - - match args.cmd { - Command::Docs { - input, - check, - output, - } => { - let doc = load_witx(&input, "input", verbose); - if check { - let output = output.expect("output argument required in docs --check mode"); - if diff_against_filesystem(&doc.to_md(), &output).is_err() { - println!("Docs in tree are out-of-date with witx files. Re-run this executable with the following arguments to to re-generate:"); - println!( - "> witx docs {} --output {}", - input - .iter() - .map(|p| p.to_string_lossy().into_owned()) - .collect::>() - .join(" "), - output.to_string_lossy(), - ); - } - } else { - if let Some(output) = output { - write_docs(&doc, output) - } else { - println!("{}", doc.to_md()) - } - } - } - Command::Polyfill { - input, - older_interface, - module_mapping, - } => { - use std::{collections::HashMap, iter::FromIterator}; - use witx::polyfill::Polyfill; - - let doc = load_witx(&input, "input", verbose); - let older_doc = load_witx(&older_interface, "older_interface", verbose); - let module_mapping = HashMap::from_iter(module_mapping.into_iter()); - let polyfill = match Polyfill::new(&doc, &older_doc, &module_mapping) { - Ok(polyfill) => polyfill, - Err(e) => { - eprintln!("couldn't calculate polyfill"); - if verbose { - println!("{:?}", e); - } - process::exit(1); - } - }; - println!("{}", polyfill.to_md()); - if verbose { - println!("{:?}", polyfill); - } - } - } -} - -fn load_witx(input: &[PathBuf], field_name: &str, verbose: bool) -> Document { - match load(input) { - Ok(doc) => { - if verbose { - println!("{}: {:?}", field_name, doc); - } - doc - } - Err(e) => { - eprintln!("{}", e.report()); - if verbose { - println!("{:?}", e); - } - process::exit(1) - } - } -} - -fn write_docs>(document: &Document, path: P) { - let mut file = File::create(path.as_ref()).expect("create output file"); - file.write_all(document.to_md().as_bytes()) - .expect("write output file"); -} - -fn parse_module_mapping(m: &str) -> Result<(String, String)> { - let s: Vec<_> = m.split('=').collect(); - let (n, o) = match s.len() { - 1 => { - let mname = s - .get(0) - .ok_or(anyhow!("module name cannot be an empty string"))?; - (mname, mname) - } - 2 => { - let newname = s - .get(0) - .ok_or(anyhow!("new module name cannot be an empty string"))?; - let oldname = s - .get(1) - .ok_or(anyhow!("old module name cannot be an empty string"))?; - (newname, oldname) - } - _ => bail!("invalid module mapping: '{}'", m), - }; - Ok((n.to_string(), o.to_string())) -} - -fn dos2unix(s: &str) -> String { - let mut t = String::new(); - t.reserve(s.len()); - for c in s.chars() { - if c != '\r' { - t.push(c) - } - } - t -} - -fn diff_against_filesystem(expected: &str, path: &Path) -> Result<(), ()> { - let actual = std::fs::read_to_string(path) - .unwrap_or_else(|e| panic!("couldn't read {}: {:?}", Path::display(path), e)); - // Git may checkout the file with dos line endings on windows. Strip all \r: - let actual = dos2unix(&actual); - if &actual == expected { - return Ok(()); - } - - eprintln!("The following diff was found between the docs generated from .witx and the"); - eprintln!("source {:?} in the tree:", path); - eprintln!(); - - let mut expected_line = 1; - let mut actual_line = 1; - let mut separated = false; - let mut any_lines = false; - for diff in diff::lines(&expected, &actual) { - match diff { - diff::Result::Left(l) => { - eprintln!("line {}: -{}", expected_line, l); - expected_line += 1; - separated = false; - any_lines = true; - } - diff::Result::Both(_, _) => { - expected_line += 1; - actual_line += 1; - if !separated { - eprintln!("..."); - separated = true; - } - } - diff::Result::Right(r) => { - eprintln!("line {}: +{}", actual_line, r); - actual_line += 1; - separated = false; - any_lines = true; - } - } - } - - if !any_lines { - eprintln!(); - eprintln!( - "Somehow there was a diff with no lines differing. Lengths: {} and {}.", - expected.len(), - actual.len() - ); - for (index, (a, b)) in actual.chars().zip(expected.chars()).enumerate() { - if a != b { - eprintln!("char difference at index {}: '{}' != '{}'", index, a, b); - } - } - for (index, (a, b)) in actual.bytes().zip(expected.bytes()).enumerate() { - if a != b { - eprintln!("byte difference at index {}: b'{}' != b'{}'", index, a, b); - } - } - eprintln!(); - eprintln!("actual: {}", actual); - eprintln!(); - eprintln!("expected: {}", expected); - } - - eprintln!(); - eprintln!("To regenerate the files, run `tools/repo_docs.sh`."); - eprintln!(); - Err(()) -} diff --git a/proposals/filesystem/tools/witx/src/abi.rs b/proposals/filesystem/tools/witx/src/abi.rs deleted file mode 100644 index 0e1ca9cb4..000000000 --- a/proposals/filesystem/tools/witx/src/abi.rs +++ /dev/null @@ -1,925 +0,0 @@ -//! Definition of the ABI of witx functions -//! -//! This module is intended to assist with code generators which are binding or -//! implementing APIs defined by `*.witx` files. THis module contains all -//! details necessary to implement the actual ABI of these functions so wasm -//! modules and hosts can communicate with one another. -//! -//! Each interface types function (a function defined in `*.witx`) currently has -//! a well-known wasm signature associated with it. There's then also a standard -//! way to convert from interface-types values (whose representation is defined -//! per-language) into this wasm API. This module is intended to assist with -//! this definition. -//! -//! Contained within are two primary functions, [`InterfaceFunc::call_wasm`] and -//! [`InterfaceFunc::call_interface`]. These functions implement the two ways to -//! interact with an interface types function, namely calling the raw wasm -//! version and calling the high-level version with interface types. These two -//! functions are fed a structure that implements [`Bindgen`]. An instance of -//! [`Bindgen`] receives instructions which are low-level implementation details -//! of how to convert to and from wasm types and interface types. Code -//! generators will need to implement the various instructions to support APIs. - -use crate::{ - BuiltinType, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, NamedType, Type, TypeRef, -}; - -/// Enumerates wasm types used by interface types when lowering/lifting. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum WasmType { - I32, - I64, - F32, - F64, - // NOTE: we don't lower interface types to any other Wasm type, - // e.g. externref, so we don't need to define them here. -} - -impl From for WasmType { - fn from(i: IntRepr) -> WasmType { - match i { - IntRepr::U8 | IntRepr::U16 | IntRepr::U32 => WasmType::I32, - IntRepr::U64 => WasmType::I64, - } - } -} - -/// Possible ABIs for interface functions to have. -/// -/// Note that this is a stopgap until we have more of interface types. Interface -/// types functions do not have ABIs, they have APIs. For the meantime, however, -/// we mandate ABIs to ensure we can all talk to each other. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum Abi { - /// Only stable ABI currently, and is the historical WASI ABI since it was - /// first created. - /// - /// Note that this ABI is limited notably in its return values where it can - /// only return 0 results or one `Result` lookalike. - Preview1, -} - -// Helper macro for defining instructions without having to have tons of -// exhaustive `match` statements to update -macro_rules! def_instruction { - ( - $( #[$enum_attr:meta] )* - pub enum Instruction<'a> { - $( - $( #[$attr:meta] )* - $variant:ident $( { - $($field:ident : $field_ty:ty $(,)* )* - } )? - : - [$num_popped:expr] => [$num_pushed:expr], - )* - } - ) => { - $( #[$enum_attr] )* - pub enum Instruction<'a> { - $( - $( #[$attr] )* - $variant $( { - $( - $field : $field_ty, - )* - } )? , - )* - } - - impl Instruction<'_> { - /// How many operands does this instruction pop from the stack? - #[allow(unused_variables)] - pub fn operands_len(&self) -> usize { - match self { - $( - Self::$variant $( { - $( - $field, - )* - } )? => $num_popped, - )* - } - } - - /// How many results does this instruction push onto the stack? - #[allow(unused_variables)] - pub fn results_len(&self) -> usize { - match self { - $( - Self::$variant $( { - $( - $field, - )* - } )? => $num_pushed, - )* - } - } - } - }; -} - -def_instruction! { - #[derive(Debug)] - pub enum Instruction<'a> { - /// Acquires the specified parameter and places it on the stack. - /// Depending on the context this may refer to wasm parameters or - /// interface types parameters. - GetArg { nth: usize } : [0] => [1], - /// Takes the value off the top of the stack and writes it into linear - /// memory. Pushes the address in linear memory as an `i32`. - AddrOf : [1] => [1], - /// Converts an interface type `char` value to a 32-bit integer - /// representing the unicode scalar value. - I32FromChar : [1] => [1], - /// Converts an interface type `u64` value to a wasm `i64`. - I64FromU64 : [1] => [1], - /// Converts an interface type `s64` value to a wasm `i64`. - I64FromS64 : [1] => [1], - /// Converts an interface type `u32` value to a wasm `i32`. - I32FromU32 : [1] => [1], - /// Converts an interface type `s32` value to a wasm `i32`. - I32FromS32 : [1] => [1], - /// Converts a language-specific `usize` value to a wasm `i32`. - I32FromUsize : [1] => [1], - /// Converts an interface type `u16` value to a wasm `i32`. - I32FromU16 : [1] => [1], - /// Converts an interface type `s16` value to a wasm `i32`. - I32FromS16 : [1] => [1], - /// Converts an interface type `u8` value to a wasm `i32`. - I32FromU8 : [1] => [1], - /// Converts an interface type `s8` value to a wasm `i32`. - I32FromS8 : [1] => [1], - /// Converts a language-specific C `char` value to a wasm `i32`. - I32FromChar8 : [1] => [1], - /// Converts a language-specific pointer value to a wasm `i32`. - I32FromPointer : [1] => [1], - /// Converts a language-specific pointer value to a wasm `i32`. - I32FromConstPointer : [1] => [1], - /// Converts a language-specific handle value to a wasm `i32`. - I32FromHandle { ty: &'a NamedType } : [1] => [1], - /// Converts a language-specific record-of-bools to the packed - /// representation as an `i32`. - I32FromBitflags { ty: &'a NamedType } : [1] => [1], - /// Converts a language-specific record-of-bools to the packed - /// representation as an `i64`. - I64FromBitflags { ty: &'a NamedType } : [1] => [1], - /// Converts an interface type list into its pointer/length, pushing - /// them both on the stack. - ListPointerLength : [1] => [2], - /// Pops two `i32` values from the stack and creates a list from them of - /// the specified type. The first operand is the pointer in linear - /// memory to the start of the list and the second operand is the - /// length. - ListFromPointerLength { ty: &'a TypeRef } : [2] => [1], - /// Conversion an interface type `f32` value to a wasm `f32`. - /// - /// This may be a noop for some implementations, but it's here in case the - /// native language representation of `f32` is different than the wasm - /// representation of `f32`. - F32FromIf32 : [1] => [1], - /// Conversion an interface type `f64` value to a wasm `f64`. - /// - /// This may be a noop for some implementations, but it's here in case the - /// native language representation of `f64` is different than the wasm - /// representation of `f64`. - F64FromIf64 : [1] => [1], - - /// Represents a call to a raw WebAssembly API. The module/name are - /// provided inline as well as the types if necessary. - CallWasm { - module: &'a str, - name: &'a str, - params: &'a [WasmType], - results: &'a [WasmType], - } : [params.len()] => [results.len()], - - /// Same as `CallWasm`, except the dual where an interface is being - /// called rather than a raw wasm function. - CallInterface { - module: &'a str, - func: &'a InterfaceFunc, - } : [func.params.len()] => [func.results.len()], - - /// Converts a native wasm `i32` to an interface type `s8`. - /// - /// This will truncate the upper bits of the `i32`. - S8FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `u8`. - /// - /// This will truncate the upper bits of the `i32`. - U8FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `s16`. - /// - /// This will truncate the upper bits of the `i32`. - S16FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `u16`. - /// - /// This will truncate the upper bits of the `i32`. - U16FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `s32`. - S32FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `u32`. - U32FromI32 : [1] => [1], - /// Converts a native wasm `i64` to an interface type `s64`. - S64FromI64 : [1] => [1], - /// Converts a native wasm `i64` to an interface type `u64`. - U64FromI64 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `char`. - /// - /// It's safe to assume that the `i32` is indeed a valid unicode code point. - CharFromI32 : [1] => [1], - /// Converts a native wasm `i32` to a language-specific C `char`. - /// - /// This will truncate the upper bits of the `i32`. - Char8FromI32 : [1] => [1], - /// Converts a native wasm `i32` to a language-specific `usize`. - UsizeFromI32 : [1] => [1], - /// Converts a native wasm `f32` to an interface type `f32`. - If32FromF32 : [1] => [1], - /// Converts a native wasm `f64` to an interface type `f64`. - If64FromF64 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `handle`. - HandleFromI32 { ty: &'a NamedType } : [1] => [1], - /// Converts a native wasm `i32` to a language-specific pointer. - PointerFromI32 { ty: &'a TypeRef }: [1] => [1], - /// Converts a native wasm `i32` to a language-specific pointer. - ConstPointerFromI32 { ty: &'a TypeRef } : [1] => [1], - /// Converts a native wasm `i32` to a language-specific record-of-bools. - BitflagsFromI32 { ty: &'a NamedType } : [1] => [1], - /// Converts a native wasm `i64` to a language-specific record-of-bools. - BitflagsFromI64 { ty: &'a NamedType } : [1] => [1], - /// Acquires the return pointer `n` and pushes an `i32` on the stack. - /// - /// Implementations of [`Bindgen`] may have [`Bindgen::allocate_space`] - /// called to reserve space in memory for the result of a computation to - /// get written. This instruction acquires a pointer to the space - /// reserved in `allocate_space`. - ReturnPointerGet { n: usize } : [0] => [1], - /// Loads the interface types value from an `i32` pointer popped from - /// the stack. - Load { ty: &'a NamedType } : [1] => [1], - /// Stores an interface types value into linear memory. The first - /// operand is the value to store and the second operand is the pointer - /// in linear memory to store it at. - Store { ty: &'a NamedType } : [2] => [0], - /// Pops a native wasm `i32` from the stack, as well as two blocks - /// internally from the code generator. - /// - /// If the value is 0 then the first "ok" block value should be used. - /// If the value is anything else then the second "err" block value - /// should be used, and the value is used as the error enum. - /// - /// Note that this is a special instruction matching the current ABI of - /// WASI and intentionally differs from the type-level grammar of - /// interface types results. - ResultLift : [1] => [1], - /// Pops a native interface value from the stack as well as two blocks - /// internally from the code generator. - /// - /// A `match` is performed on the value popped and the corresponding - /// block for ok/err is used depending on value. This pushes a single - /// `i32` onto the stack representing the error code for this result. - /// - /// Note that like `ResultLift` this is specialized to the current WASI - /// ABI. - ResultLower { - ok: Option<&'a TypeRef>, - err: Option<&'a TypeRef>, - } : [1] => [1], - /// Converts a native wasm `i32` to an interface type `enum` value. - /// - /// It's guaranteed that the interface type integer value is within - /// range for this enum's type. Additionally `ty` is guaranteed to be - /// enum-like as a `Variant` where all `case` arms have no associated - /// type with them. The purpose of this instruction is to convert a - /// native wasm integer into the enum type for the interface. - EnumLift { ty: &'a NamedType } : [1] => [1], - /// Converts an interface types enum value into a wasm `i32`. - EnumLower { ty: &'a NamedType } : [1] => [1], - /// Creates a tuple from the top `n` elements on the stack, pushing the - /// tuple onto the stack. - TupleLift { amt: usize } : [*amt] => [1], - /// Splits a tuple at the top of the stack into its `n` components, - /// pushing them all onto the stack. - TupleLower { amt: usize } : [1] => [*amt], - /// This is a special instruction specifically for the original ABI of - /// WASI. The raw return `i32` of a function is re-pushed onto the - /// stack for reuse. - ReuseReturn : [0] => [1], - /// Returns `amt` values on the stack. This is always the last - /// instruction. - Return { amt: usize } : [*amt] => [0], - /// This is a special instruction used at the entry of blocks used as - /// part of `ResultLower`, representing that the payload of that variant - /// being matched on should be pushed onto the stack. - VariantPayload : [0] => [1], - } -} - -impl Abi { - /// Validates the parameters/results are representable in this ABI. - /// - /// Returns an error string if they're not representable or returns `Ok` if - /// they're indeed representable. - pub fn validate( - &self, - _params: &[InterfaceFuncParam], - results: &[InterfaceFuncParam], - ) -> Result<(), String> { - assert_eq!(*self, Abi::Preview1); - match results.len() { - 0 => {} - 1 => match &**results[0].tref.type_() { - Type::Handle(_) | Type::Builtin(_) | Type::ConstPointer(_) | Type::Pointer(_) => {} - Type::Variant(v) => { - let (ok, err) = match v.as_expected() { - Some(pair) => pair, - None => return Err("invalid return type".to_string()), - }; - if let Some(ty) = ok { - match &**ty.type_() { - Type::Record(r) if r.is_tuple() => { - for member in r.members.iter() { - if !member.tref.named() { - return Err( - "only named types are allowed in results".to_string() - ); - } - } - } - _ => { - if !ty.named() { - return Err( - "only named types are allowed in results".to_string() - ); - } - } - } - } - if let Some(ty) = err { - if !ty.named() { - return Err("only named types are allowed in results".to_string()); - } - if let Type::Variant(v) = &**ty.type_() { - if v.is_enum() { - return Ok(()); - } - } - } - } - Type::Record(r) if r.bitflags_repr().is_some() => {} - Type::Record(_) | Type::List(_) => return Err("invalid return type".to_string()), - }, - _ => return Err("more than one result".to_string()), - } - Ok(()) - } -} - -/// Trait for language implementors to use to generate glue code between native -/// WebAssembly signatures and interface types signatures. -/// -/// This is used as an implementation detail in interpreting the ABI between -/// interface types and wasm types. Eventually this will be driven by interface -/// types adapters themselves, but for now the ABI of a function dictates what -/// instructions are fed in. -/// -/// Types implementing `Bindgen` are incrementally fed `Instruction` values to -/// generate code for. Instructions operate like a stack machine where each -/// instruction has a list of inputs and a list of outputs (provided by the -/// `emit` function). -pub trait Bindgen { - /// The intermediate type for fragments of code for this type. - /// - /// For most languages `String` is a suitable intermediate type. - type Operand; - - /// Emit code to implement the given instruction. - /// - /// Each operand is given in `operands` and can be popped off if ownership - /// is required. It's guaranteed that `operands` has the appropriate length - /// for the `inst` given, as specified with [`Instruction`]. - /// - /// Each result variable should be pushed onto `results`. This function must - /// push the appropriate number of results or binding generation will panic. - fn emit( - &mut self, - inst: &Instruction<'_>, - operands: &mut Vec, - results: &mut Vec, - ); - - /// Allocates temporary space in linear memory indexed by `slot` with enough - /// space to store `ty`. - /// - /// This is called when calling some wasm functions where a return pointer - /// is needed. - fn allocate_space(&mut self, slot: usize, ty: &NamedType); - - /// Enters a new block of code to generate code for. - /// - /// This is currently exclusively used for constructing variants. When a - /// variant is constructed a block here will be pushed for each case of a - /// variant, generating the code necessary to translate a variant case. - /// - /// Blocks are completed with `finish_block` below. It's expected that `emit` - /// will always push code (if necessary) into the "current block", which is - /// updated by calling this method and `finish_block` below. - fn push_block(&mut self); - - /// Indicates to the code generator that a block is completed, and the - /// `operand` specified was the resulting value of the block. - /// - /// This method will be used to compute the value of each arm of lifting a - /// variant. The `operand` will be `None` if the variant case didn't - /// actually have any type associated with it. Otherwise it will be `Some` - /// as the last value remaining on the stack representing the value - /// associated with a variant's `case`. - /// - /// It's expected that this will resume code generation in the previous - /// block before `push_block` was called. This must also save the results - /// of the current block internally for instructions like `ResultLift` to - /// use later. - fn finish_block(&mut self, operand: Option); -} - -impl InterfaceFunc { - /// Get the WebAssembly type signature for this interface function - /// - /// The first entry returned is the list of parameters and the second entry - /// is the list of results for the wasm function signature. - pub fn wasm_signature(&self) -> (Vec, Vec) { - assert_eq!(self.abi, Abi::Preview1); - let mut params = Vec::new(); - let mut results = Vec::new(); - for param in self.params.iter() { - match &**param.tref.type_() { - Type::Builtin(BuiltinType::S8) - | Type::Builtin(BuiltinType::U8 { .. }) - | Type::Builtin(BuiltinType::S16) - | Type::Builtin(BuiltinType::U16) - | Type::Builtin(BuiltinType::S32) - | Type::Builtin(BuiltinType::U32 { .. }) - | Type::Builtin(BuiltinType::Char) - | Type::Pointer(_) - | Type::ConstPointer(_) - | Type::Handle(_) - | Type::Variant(_) => params.push(WasmType::I32), - - Type::Record(r) => match r.bitflags_repr() { - Some(repr) => params.push(WasmType::from(repr)), - None => params.push(WasmType::I32), - }, - - Type::Builtin(BuiltinType::S64) | Type::Builtin(BuiltinType::U64) => { - params.push(WasmType::I64) - } - - Type::Builtin(BuiltinType::F32) => params.push(WasmType::F32), - Type::Builtin(BuiltinType::F64) => params.push(WasmType::F64), - - Type::List(_) => { - params.push(WasmType::I32); - params.push(WasmType::I32); - } - } - } - - for param in self.results.iter() { - match &**param.tref.type_() { - Type::Builtin(BuiltinType::S8) - | Type::Builtin(BuiltinType::U8 { .. }) - | Type::Builtin(BuiltinType::S16) - | Type::Builtin(BuiltinType::U16) - | Type::Builtin(BuiltinType::S32) - | Type::Builtin(BuiltinType::U32 { .. }) - | Type::Builtin(BuiltinType::Char) - | Type::Pointer(_) - | Type::ConstPointer(_) - | Type::Handle(_) => results.push(WasmType::I32), - - Type::Builtin(BuiltinType::S64) | Type::Builtin(BuiltinType::U64) => { - results.push(WasmType::I64) - } - - Type::Builtin(BuiltinType::F32) => results.push(WasmType::F32), - Type::Builtin(BuiltinType::F64) => results.push(WasmType::F64), - - Type::Record(r) => match r.bitflags_repr() { - Some(repr) => results.push(WasmType::from(repr)), - None => unreachable!(), - }, - Type::List(_) => unreachable!(), - - Type::Variant(v) => { - results.push(match v.tag_repr { - IntRepr::U64 => WasmType::I64, - IntRepr::U32 | IntRepr::U16 | IntRepr::U8 => WasmType::I32, - }); - if v.is_enum() { - continue; - } - // return pointer - if let Some(ty) = &v.cases[0].tref { - match &**ty.type_() { - Type::Record(r) if r.is_tuple() => { - for _ in 0..r.members.len() { - params.push(WasmType::I32); - } - } - _ => params.push(WasmType::I32), - } - } - } - } - } - (params, results) - } - - /// Generates an abstract sequence of instructions which represents this - /// function being adapted as an imported function. - /// - /// The instructions here, when executed, will emulate a language with - /// interface types calling the concrete wasm implementation. The parameters - /// for the returned instruction sequence are the language's own - /// interface-types parameters. One instruction in the instruction stream - /// will be a `Call` which represents calling the actual raw wasm function - /// signature. - /// - /// This function is useful, for example, if you're building a language - /// generator for WASI bindings. This will document how to translate - /// language-specific values into the wasm types to call a WASI function, - /// and it will also automatically convert the results of the WASI function - /// back to a language-specific value. - pub fn call_wasm(&self, module: &Id, bindgen: &mut impl Bindgen) { - assert_eq!(self.abi, Abi::Preview1); - Generator { - bindgen, - operands: vec![], - results: vec![], - stack: vec![], - } - .call_wasm(module, self); - } - - /// This is the dual of [`InterfaceFunc::call_wasm`], except that instead of - /// calling a wasm signature it generates code to come from a wasm signature - /// and call an interface types signature. - pub fn call_interface(&self, module: &Id, bindgen: &mut impl Bindgen) { - assert_eq!(self.abi, Abi::Preview1); - Generator { - bindgen, - operands: vec![], - results: vec![], - stack: vec![], - } - .call_interface(module, self); - } -} - -struct Generator<'a, B: Bindgen> { - bindgen: &'a mut B, - operands: Vec, - results: Vec, - stack: Vec, -} - -impl Generator<'_, B> { - fn call_wasm(&mut self, module: &Id, func: &InterfaceFunc) { - // Translate all parameters which are interface values by lowering them - // to their wasm types. - for (nth, param) in func.params.iter().enumerate() { - self.emit(&Instruction::GetArg { nth }); - self.lower(¶m.tref, None); - } - - // If necessary for our ABI, insert return pointers for any returned - // values through a result. - assert!(func.results.len() < 2); - if let Some(result) = func.results.get(0) { - self.prep_return_pointer(&result.tref.type_()); - } - - let (params, results) = func.wasm_signature(); - self.emit(&Instruction::CallWasm { - module: module.as_str(), - name: func.name.as_str(), - params: ¶ms, - results: &results, - }); - - // Lift the return value if one is present. - if let Some(result) = func.results.get(0) { - self.lift(&result.tref, true); - } - - self.emit(&Instruction::Return { - amt: func.results.len(), - }); - } - - fn call_interface(&mut self, module: &Id, func: &InterfaceFunc) { - // Lift all wasm parameters into interface types first. - // - // Note that consuming arguments is somewhat janky right now by manually - // giving lists a second argument for their length. In the future we'll - // probably want to refactor the `lift` function to internally know how - // to consume arguments. - let mut nth = 0; - for param in func.params.iter() { - self.emit(&Instruction::GetArg { nth }); - nth += 1; - if let Type::List(_) = &**param.tref.type_() { - self.emit(&Instruction::GetArg { nth }); - nth += 1; - } - self.lift(¶m.tref, false); - } - - self.emit(&Instruction::CallInterface { - module: module.as_str(), - func, - }); - - // Like above the current ABI only has at most one result, so lower it - // here if necessary. - if let Some(result) = func.results.get(0) { - self.lower(&result.tref, Some(&mut nth)); - } - - let (_params, results) = func.wasm_signature(); - self.emit(&Instruction::Return { amt: results.len() }); - } - - fn emit(&mut self, inst: &Instruction<'_>) { - self.operands.clear(); - self.results.clear(); - - let operands_len = inst.operands_len(); - assert!( - self.stack.len() >= operands_len, - "not enough operands on stack for {:?}", - inst - ); - self.operands - .extend(self.stack.drain((self.stack.len() - operands_len)..)); - self.results.reserve(inst.results_len()); - - self.bindgen - .emit(inst, &mut self.operands, &mut self.results); - - assert_eq!( - self.results.len(), - inst.results_len(), - "{:?} expected {} results, got {}", - inst, - inst.results_len(), - self.results.len() - ); - self.stack.extend(self.results.drain(..)); - } - - fn lower(&mut self, ty: &TypeRef, retptr: Option<&mut usize>) { - use Instruction::*; - match &**ty.type_() { - Type::Builtin(BuiltinType::S8) => self.emit(&I32FromS8), - Type::Builtin(BuiltinType::U8 { lang_c_char: true }) => self.emit(&I32FromChar8), - Type::Builtin(BuiltinType::U8 { lang_c_char: false }) => self.emit(&I32FromU8), - Type::Builtin(BuiltinType::S16) => self.emit(&I32FromS16), - Type::Builtin(BuiltinType::U16) => self.emit(&I32FromU16), - Type::Builtin(BuiltinType::S32) => self.emit(&I32FromS32), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: true, - }) => self.emit(&I32FromUsize), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: false, - }) => self.emit(&I32FromU32), - Type::Builtin(BuiltinType::S64) => self.emit(&I64FromS64), - Type::Builtin(BuiltinType::U64) => self.emit(&I64FromU64), - Type::Builtin(BuiltinType::Char) => self.emit(&I32FromChar), - Type::Pointer(_) => self.emit(&I32FromPointer), - Type::ConstPointer(_) => self.emit(&I32FromConstPointer), - Type::Handle(_) => self.emit(&I32FromHandle { - ty: match ty { - TypeRef::Name(ty) => ty, - _ => unreachable!(), - }, - }), - Type::Record(r) => { - let ty = match ty { - TypeRef::Name(ty) => ty, - _ => unreachable!(), - }; - match r.bitflags_repr() { - Some(IntRepr::U64) => self.emit(&I64FromBitflags { ty }), - Some(_) => self.emit(&I32FromBitflags { ty }), - None => self.emit(&AddrOf), - } - } - Type::Variant(v) => { - // Enum-like variants are simply lowered to their discriminant. - if v.is_enum() { - return self.emit(&EnumLower { - ty: match ty { - TypeRef::Name(n) => n, - _ => unreachable!(), - }, - }); - } - - // If this variant is in the return position then it's special, - // otherwise it's an argument and we just pass the address. - let retptr = match retptr { - Some(ptr) => ptr, - None => return self.emit(&AddrOf), - }; - - // For the return position we emit some blocks to lower the - // ok/err payloads which means that in the ok branch we're - // storing to out-params and in the err branch we're simply - // lowering the error enum. - // - // Note that this is all very specific to the current WASI ABI. - let (ok, err) = v.as_expected().unwrap(); - self.bindgen.push_block(); - if let Some(ok) = ok { - self.emit(&VariantPayload); - let store = |me: &mut Self, ty: &TypeRef, n| { - me.emit(&GetArg { nth: *retptr + n }); - match ty { - TypeRef::Name(ty) => me.emit(&Store { ty }), - _ => unreachable!(), - } - }; - match &**ok.type_() { - Type::Record(r) if r.is_tuple() => { - self.emit(&TupleLower { - amt: r.members.len(), - }); - // Note that `rev()` is used here due to the order - // that tuples are pushed onto the stack and how we - // consume the last item first from the stack. - for (i, member) in r.members.iter().enumerate().rev() { - store(self, &member.tref, i); - } - } - _ => store(self, ok, 0), - } - }; - self.bindgen.finish_block(None); - - self.bindgen.push_block(); - let err_expr = if let Some(ty) = err { - self.emit(&VariantPayload); - self.lower(ty, None); - Some(self.stack.pop().unwrap()) - } else { - None - }; - self.bindgen.finish_block(err_expr); - - self.emit(&ResultLower { ok, err }); - } - Type::Builtin(BuiltinType::F32) => self.emit(&F32FromIf32), - Type::Builtin(BuiltinType::F64) => self.emit(&F64FromIf64), - Type::List(_) => self.emit(&ListPointerLength), - } - } - - fn prep_return_pointer(&mut self, ty: &Type) { - // Return pointers are only needed for `Result`... - let variant = match ty { - Type::Variant(v) => v, - _ => return, - }; - // ... and only if `T` is actually present in `Result` - let ok = match &variant.cases[0].tref { - Some(t) => t, - None => return, - }; - - // Tuples have each individual item in a separate return pointer while - // all other types go through a singular return pointer. - let mut n = 0; - let mut prep = |ty: &TypeRef| { - match ty { - TypeRef::Name(ty) => self.bindgen.allocate_space(n, ty), - _ => unreachable!(), - } - self.emit(&Instruction::ReturnPointerGet { n }); - n += 1; - }; - match &**ok.type_() { - Type::Record(r) if r.is_tuple() => { - for member in r.members.iter() { - prep(&member.tref); - } - } - _ => prep(ok), - } - } - - // Note that in general everything in this function is the opposite of the - // `lower` function above. This is intentional and should be kept this way! - fn lift(&mut self, ty: &TypeRef, is_return: bool) { - use Instruction::*; - match &**ty.type_() { - Type::Builtin(BuiltinType::S8) => self.emit(&S8FromI32), - Type::Builtin(BuiltinType::U8 { lang_c_char: true }) => self.emit(&Char8FromI32), - Type::Builtin(BuiltinType::U8 { lang_c_char: false }) => self.emit(&U8FromI32), - Type::Builtin(BuiltinType::S16) => self.emit(&S16FromI32), - Type::Builtin(BuiltinType::U16) => self.emit(&U16FromI32), - Type::Builtin(BuiltinType::S32) => self.emit(&S32FromI32), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: true, - }) => self.emit(&UsizeFromI32), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: false, - }) => self.emit(&U32FromI32), - Type::Builtin(BuiltinType::S64) => self.emit(&S64FromI64), - Type::Builtin(BuiltinType::U64) => self.emit(&U64FromI64), - Type::Builtin(BuiltinType::Char) => self.emit(&CharFromI32), - Type::Builtin(BuiltinType::F32) => self.emit(&If32FromF32), - Type::Builtin(BuiltinType::F64) => self.emit(&If64FromF64), - Type::Pointer(ty) => self.emit(&PointerFromI32 { ty }), - Type::ConstPointer(ty) => self.emit(&ConstPointerFromI32 { ty }), - Type::Handle(_) => self.emit(&HandleFromI32 { - ty: match ty { - TypeRef::Name(ty) => ty, - _ => unreachable!(), - }, - }), - Type::Variant(v) => { - if v.is_enum() { - return self.emit(&EnumLift { - ty: match ty { - TypeRef::Name(n) => n, - _ => unreachable!(), - }, - }); - } else if !is_return { - return self.emit(&Load { - ty: match ty { - TypeRef::Name(n) => n, - _ => unreachable!(), - }, - }); - } - - let (ok, err) = v.as_expected().unwrap(); - self.bindgen.push_block(); - let ok_expr = if let Some(ok) = ok { - let mut n = 0; - let mut load = |ty: &TypeRef| { - self.emit(&ReturnPointerGet { n }); - n += 1; - match ty { - TypeRef::Name(ty) => self.emit(&Load { ty }), - _ => unreachable!(), - } - }; - match &**ok.type_() { - Type::Record(r) if r.is_tuple() => { - for member in r.members.iter() { - load(&member.tref); - } - self.emit(&TupleLift { - amt: r.members.len(), - }); - } - _ => load(ok), - } - Some(self.stack.pop().unwrap()) - } else { - None - }; - self.bindgen.finish_block(ok_expr); - - self.bindgen.push_block(); - let err_expr = if let Some(ty) = err { - self.emit(&ReuseReturn); - self.lift(ty, false); - Some(self.stack.pop().unwrap()) - } else { - None - }; - self.bindgen.finish_block(err_expr); - - self.emit(&ResultLift); - } - Type::Record(r) => { - let ty = match ty { - TypeRef::Name(ty) => ty, - _ => unreachable!(), - }; - match r.bitflags_repr() { - Some(IntRepr::U64) => self.emit(&BitflagsFromI64 { ty }), - Some(_) => self.emit(&BitflagsFromI32 { ty }), - None => self.emit(&Load { ty }), - } - } - Type::List(ty) => self.emit(&ListFromPointerLength { ty }), - } - } -} diff --git a/proposals/filesystem/tools/witx/src/ast.rs b/proposals/filesystem/tools/witx/src/ast.rs deleted file mode 100644 index ee985d302..000000000 --- a/proposals/filesystem/tools/witx/src/ast.rs +++ /dev/null @@ -1,591 +0,0 @@ -use crate::Abi; -use std::collections::{HashMap, HashSet}; -use std::rc::{Rc, Weak}; - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Id(String); - -impl Id { - pub fn new>(s: S) -> Self { - Id(s.as_ref().to_string()) - } - pub fn as_str(&self) -> &str { - self.0.as_str() - } -} - -impl AsRef for Id { - fn as_ref(&self) -> &str { - self.0.as_ref() - } -} - -impl PartialEq<&str> for Id { - fn eq(&self, rhs: &&str) -> bool { - PartialEq::eq(self.as_ref(), *rhs) - } -} - -impl PartialEq for &str { - fn eq(&self, rhs: &Id) -> bool { - PartialEq::eq(*self, rhs.as_ref()) - } -} - -impl From<&str> for Id { - fn from(s: &str) -> Self { - Self::new(s) - } -} - -#[derive(Debug, Clone)] -pub struct Document { - definitions: Vec, - entries: HashMap, -} - -impl Document { - pub(crate) fn new(definitions: Vec, entries: HashMap) -> Self { - Document { - definitions, - entries, - } - } - pub fn typename(&self, name: &Id) -> Option> { - self.entries.get(name).and_then(|e| match e { - Entry::Typename(nt) => Some(nt.upgrade().expect("always possible to upgrade entry")), - _ => None, - }) - } - pub fn typenames<'a>(&'a self) -> impl Iterator> + 'a { - self.definitions.iter().filter_map(|d| match d { - Definition::Typename(nt) => Some(nt.clone()), - _ => None, - }) - } - /// All of the (unique) types used as "err" variant of results returned from - /// functions. - pub fn error_types<'a>(&'a self) -> impl Iterator + 'a { - let errors: HashSet = self - .modules() - .flat_map(|m| { - m.funcs() - .filter_map(|f| { - if f.results.len() == 1 { - Some(f.results[0].tref.type_().clone()) - } else { - None - } - }) - .filter_map(|t| match &*t { - Type::Variant(v) => { - let (_ok, err) = v.as_expected()?; - Some(err?.clone()) - } - _ => None, - }) - .collect::>() - }) - .collect(); - errors.into_iter() - } - pub fn module(&self, name: &Id) -> Option> { - self.entries.get(&name).and_then(|e| match e { - Entry::Module(m) => Some(m.upgrade().expect("always possible to upgrade entry")), - _ => None, - }) - } - pub fn modules<'a>(&'a self) -> impl Iterator> + 'a { - self.definitions.iter().filter_map(|d| match d { - Definition::Module(m) => Some(m.clone()), - _ => None, - }) - } - - pub fn constants<'a>(&'a self) -> impl Iterator + 'a { - self.definitions.iter().filter_map(|d| match d { - Definition::Constant(c) => Some(c), - _ => None, - }) - } -} - -impl PartialEq for Document { - fn eq(&self, rhs: &Document) -> bool { - // For equality, we don't care about the ordering of definitions, - // so we only need to check that the entries map is equal - self.entries == rhs.entries - } -} -impl Eq for Document {} - -impl std::hash::Hash for Document { - fn hash(&self, state: &mut H) { - std::hash::Hash::hash(&self.definitions, state); - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum Definition { - Typename(Rc), - Module(Rc), - Constant(Constant), -} - -#[derive(Debug, Clone)] -pub enum Entry { - Typename(Weak), - Module(Weak), -} - -impl Entry { - pub fn kind(&self) -> &'static str { - match self { - Entry::Typename { .. } => "typename", - Entry::Module { .. } => "module", - } - } -} - -impl PartialEq for Entry { - fn eq(&self, rhs: &Entry) -> bool { - match (self, rhs) { - (Entry::Typename(t), Entry::Typename(t_rhs)) => { - t.upgrade() - .expect("possible to upgrade entry when part of document") - == t_rhs - .upgrade() - .expect("possible to upgrade entry when part of document") - } - (Entry::Module(m), Entry::Module(m_rhs)) => { - m.upgrade() - .expect("possible to upgrade entry when part of document") - == m_rhs - .upgrade() - .expect("possible to upgrade entry when part of document") - } - _ => false, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum TypeRef { - Name(Rc), - Value(Rc), -} - -impl TypeRef { - pub fn type_(&self) -> &Rc { - match self { - TypeRef::Name(named) => named.type_(), - TypeRef::Value(v) => v, - } - } - - pub fn named(&self) -> bool { - match self { - TypeRef::Name(_) => true, - TypeRef::Value(_) => false, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct NamedType { - pub name: Id, - pub tref: TypeRef, - pub docs: String, -} - -impl NamedType { - pub fn type_(&self) -> &Rc { - self.tref.type_() - } -} - -/// Structure of all possible interface types. -/// -/// Note that this is intended to match the interface types proposal itself. -/// Currently this is relatively close to that with just a few `*.witx` -/// extensions for now. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum Type { - /// A structure with named field. - Record(RecordDatatype), - /// An enumeration where a value is one of a number of variants. - Variant(Variant), - /// A "handle" which is an un-forgeable reference. Today this is an `i32` - /// where a module can't forge and use integers it was not already given - /// access to. - Handle(HandleDatatype), - /// A list of a type, stored in linear memory. - /// - /// Note that lists of `char` are specialized to indicate strings. - List(TypeRef), - /// A `witx`-specific type representing a raw mutable pointer into linear - /// memory - Pointer(TypeRef), - /// A `witx`-specific type representing a raw const pointer into linear - /// memory - ConstPointer(TypeRef), - /// A builtin base-case type. - Builtin(BuiltinType), -} - -impl Type { - /// Returns a human-readable string to describe this type. - pub fn kind(&self) -> &'static str { - use Type::*; - match self { - Record(_) => "record", - Variant(_) => "variant", - Handle(_) => "handle", - List(_) => "list", - Pointer(_) => "pointer", - ConstPointer(_) => "constpointer", - Builtin(_) => "builtin", - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum BuiltinType { - /// This is a 32-bit unicode scalar value, not a code point. - /// - /// Same as the Rust language's `char` type. - Char, - /// An 8-bit unsigned integer. - U8 { - /// Indicates whether this type is intended to represent the `char` - /// type in the C language. The C `char` type is often unsigned, but - /// it's language-specific. At an interface-types level this is an - /// unsigned byte but binding generators may wish to bind this as the - /// language-specific representation for a C character instead. - /// - /// This is also currently used exclusively in conjunction with `@witx - /// pointer` to hint that it's pointing to unicode string data as well. - lang_c_char: bool, - }, - /// A 16-bit unsigned integer. - U16, - /// A 32-bit unsigned integer. - U32 { - /// Indicates that this 32-bit value should actually be considered a - /// pointer-like value in language bindings. At the interface types - /// layer this is always a 32-bit unsigned value, but binding - /// generators may wish to instead bind this as the equivalent of C's - /// `size_t` for convenience with other APIs. - /// - /// This allows witx authors to communicate the intent that the - /// argument or return-value is pointer-like. - lang_ptr_size: bool, - }, - /// A 64-bit unsigned integer. - U64, - /// An 8-bit signed integer - S8, - /// A 16-bit signed integer - S16, - /// A 32-bit signed integer - S32, - /// A 64-bit signed integer - S64, - /// A 32-bit floating point value. - F32, - /// A 64-bit floating point value. - F64, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum IntRepr { - U8, - U16, - U32, - U64, -} - -impl IntRepr { - pub fn to_builtin(&self) -> BuiltinType { - match self { - IntRepr::U8 => BuiltinType::U8 { lang_c_char: false }, - IntRepr::U16 => BuiltinType::U16, - IntRepr::U32 => BuiltinType::U32 { - lang_ptr_size: false, - }, - IntRepr::U64 => BuiltinType::U64, - } - } -} - -/// A struct-like value with named fields. -/// -/// Records map to `struct`s in most languages where this is a type with a -/// number of named fields that all have their own particular type. Field order -/// dictates layout in memory. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct RecordDatatype { - /// A hint as to what this record might be. - /// - /// Note that in the future this will only be a hint, not a control of the - /// actual representation itself. At this time though the record layout of - /// bitflags is different from other types. - pub kind: RecordKind, - - /// A list of named fields for this record. - pub members: Vec, -} - -/// Different kinds of records used for hinting various language-specific types. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum RecordKind { - /// A tuple where the name of all fields are consecutive integers starting - /// at "0". - Tuple, - /// A record where all fields are `bool`s. Currently represented as an - /// integer with bits set or not set. - Bitflags(IntRepr), - /// All other structures. - Other, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct RecordMember { - pub name: Id, - pub tref: TypeRef, - pub docs: String, -} - -impl RecordDatatype { - pub fn is_tuple(&self) -> bool { - match self.kind { - RecordKind::Tuple => true, - _ => false, - } - } - - pub fn bitflags_repr(&self) -> Option { - match self.kind { - RecordKind::Bitflags(i) => Some(i), - _ => None, - } - } -} - -/// A type which represents how values can be one of a set of possible cases. -/// -/// This type maps to an `enum` in languages like Rust, but doesn't have an -/// equivalent in languages like JS or C. The closest analog in C is a tagged -/// union, but a `Variant` is always consistent whereas a tagged union in C -/// could be mis-tagged or such. -/// -/// Variants are used to represent one of a possible set of types. For example -/// an enum-like variant, a result that is either success or failure, or even a -/// simple `bool`. Variants are primarily used heavily with various kinds of -/// shorthands in the `*.witx` format to represent idioms in languages. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Variant { - /// The bit representation of the width of this variant's tag when the - /// variant is stored in memory. - pub tag_repr: IntRepr, - /// The possible cases that values of this variant type can take. - pub cases: Vec, -} - -impl Variant { - /// If this variant looks like an `expected` shorthand, return the ok/err - /// types associated with this result. - /// - /// Only matches variants fo the form: - /// - /// ```text - /// (variant - /// (case "ok" ok?) - /// (case "err" err?)) - /// ``` - pub fn as_expected(&self) -> Option<(Option<&TypeRef>, Option<&TypeRef>)> { - if self.cases.len() != 2 { - return None; - } - if self.cases[0].name != "ok" { - return None; - } - if self.cases[1].name != "err" { - return None; - } - Some((self.cases[0].tref.as_ref(), self.cases[1].tref.as_ref())) - } - - /// Returns whether this variant type is "bool-like" meaning that it matches - /// this type: - /// - /// ```text - /// (variant - /// (case "false") - /// (case "true")) - /// ``` - pub fn is_bool(&self) -> bool { - self.cases.len() == 2 - && self.cases[0].name == "false" - && self.cases[1].name == "true" - && self.cases[0].tref.is_none() - && self.cases[1].tref.is_none() - } - - /// Returns whether this variant type is "enum-like" meaning that all of its - /// cases have no payload associated with them. - pub fn is_enum(&self) -> bool { - self.cases.iter().all(|c| c.tref.is_none()) - } -} - -/// One of a number of possible types that a `Variant` can take. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Case { - /// The name of this case and how to identify it. - pub name: Id, - /// An optional payload type for this case and data that can be associated - /// with it. - pub tref: Option, - /// Documentation for this case. - pub docs: String, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct HandleDatatype {} - -#[derive(Debug, Clone)] -pub struct Module { - pub name: Id, - definitions: Vec, - entries: HashMap, - pub docs: String, -} - -impl Module { - pub(crate) fn new( - name: Id, - definitions: Vec, - entries: HashMap, - docs: String, - ) -> Self { - Module { - name, - definitions, - entries, - docs, - } - } - pub fn import(&self, name: &Id) -> Option> { - self.entries.get(name).and_then(|e| match e { - ModuleEntry::Import(d) => Some(d.upgrade().expect("always possible to upgrade entry")), - _ => None, - }) - } - pub fn imports<'a>(&'a self) -> impl Iterator> + 'a { - self.definitions.iter().filter_map(|d| match d { - ModuleDefinition::Import(d) => Some(d.clone()), - _ => None, - }) - } - pub fn func(&self, name: &Id) -> Option> { - self.entries.get(name).and_then(|e| match e { - ModuleEntry::Func(d) => Some(d.upgrade().expect("always possible to upgrade entry")), - _ => None, - }) - } - pub fn funcs<'a>(&'a self) -> impl Iterator> + 'a { - self.definitions.iter().filter_map(|d| match d { - ModuleDefinition::Func(d) => Some(d.clone()), - _ => None, - }) - } -} - -impl PartialEq for Module { - fn eq(&self, rhs: &Module) -> bool { - // For equality, we don't care about the ordering of definitions, - // so we only need to check that the entries map is equal - self.name == rhs.name && self.entries == rhs.entries && self.docs == rhs.docs - } -} -impl Eq for Module {} - -impl std::hash::Hash for Module { - fn hash(&self, state: &mut H) { - std::hash::Hash::hash(&self.name, state); - std::hash::Hash::hash(&self.definitions, state); - std::hash::Hash::hash(&self.docs, state); - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum ModuleDefinition { - Import(Rc), - Func(Rc), -} - -#[derive(Debug, Clone)] -pub enum ModuleEntry { - Import(Weak), - Func(Weak), -} - -impl PartialEq for ModuleEntry { - fn eq(&self, rhs: &ModuleEntry) -> bool { - match (self, rhs) { - (ModuleEntry::Import(i), ModuleEntry::Import(i_rhs)) => { - i.upgrade() - .expect("always possible to upgrade moduleentry when part of module") - == i_rhs - .upgrade() - .expect("always possible to upgrade moduleentry when part of module") - } - (ModuleEntry::Func(i), ModuleEntry::Func(i_rhs)) => { - i.upgrade() - .expect("always possible to upgrade moduleentry when part of module") - == i_rhs - .upgrade() - .expect("always possible to upgrade moduleentry when part of module") - } - _ => false, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ModuleImport { - pub name: Id, - pub variant: ModuleImportVariant, - pub docs: String, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum ModuleImportVariant { - Memory, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct InterfaceFunc { - pub abi: Abi, - pub name: Id, - pub params: Vec, - pub results: Vec, - pub noreturn: bool, - pub docs: String, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct InterfaceFuncParam { - pub name: Id, - pub tref: TypeRef, - pub docs: String, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Constant { - pub ty: Id, - pub name: Id, - pub value: u64, - pub docs: String, -} diff --git a/proposals/filesystem/tools/witx/src/docs/ast.rs b/proposals/filesystem/tools/witx/src/docs/ast.rs deleted file mode 100644 index a295a6756..000000000 --- a/proposals/filesystem/tools/witx/src/docs/ast.rs +++ /dev/null @@ -1,503 +0,0 @@ -use super::{ - md::{MdFunc, MdHeading, MdNamedType, MdNodeRef, MdSection, ToMarkdown}, - Documentation, -}; -use crate::{ - ast::*, - layout::Layout, - polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, - RepEquality, -}; -use std::collections::HashMap; - -fn heading_from_node(node: &MdNodeRef, levels_down: usize) -> MdHeading { - MdHeading::new_header(node.borrow().ancestors().len() + levels_down) -} - -impl ToMarkdown for Document { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - let types = node.new_child(MdSection::new(heading, "Types")); - - let mut constants_by_name = HashMap::new(); - for c in self.constants() { - constants_by_name.entry(&c.ty).or_insert(Vec::new()).push(c); - } - - for d in self.typenames() { - let name = d.name.as_str(); - let child = types.new_child(MdNamedType::new( - heading.new_level_down(), - name, - name, - format!( - "{}\nSize: {}\n\nAlignment: {}\n", - &d.docs, - &d.mem_size(), - &d.mem_align() - ) - .as_str(), - )); - if let Some(constants) = constants_by_name.remove(&d.name) { - let heading = heading_from_node(&child, 1); - child.new_child(MdSection::new(heading, "Constants")); - for constant in constants { - child.new_child(MdNamedType::new( - MdHeading::new_bullet(), - format!("{}.{}", name, constant.name.as_str()).as_str(), - constant.name.as_str(), - &constant.docs, - )); - } - } - d.generate(child.clone()); - } - - let modules = node.new_child(MdSection::new(heading, "Modules")); - for d in self.modules() { - let mut content = MdSection::new(heading.new_level_down(), d.name.as_str()); - content.id = Some(d.name.as_str().to_owned()); - let child = modules.new_child(content); - d.generate(child.clone()); - } - - assert!(constants_by_name.is_empty()); - } -} - -impl ToMarkdown for TypeRef { - fn generate(&self, node: MdNodeRef) { - match self { - TypeRef::Value(v) => { - v.generate(node.clone()); - node.content_ref_mut::().ty = Some(format!("`{}`", self.type_name())); - } - TypeRef::Name(n) => { - node.content_ref_mut::().ty = - Some(format!("[`{0}`](#{0})", n.name.as_str().to_owned())); - } - } - } -} - -impl ToMarkdown for NamedType { - fn generate(&self, node: MdNodeRef) { - self.tref.generate(node.clone()); - } -} - -impl ToMarkdown for Type { - fn generate(&self, node: MdNodeRef) { - match self { - Self::Record(a) => a.generate(node.clone()), - Self::Variant(a) => a.generate(node.clone()), - Self::Handle(a) => a.generate(node.clone()), - Self::List(_) => {} - Self::Pointer(_) => {} - Self::ConstPointer(_) => {} - Self::Builtin(_) => {} - } - } -} - -impl ToMarkdown for RecordDatatype { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Record members")); - - for member_layout in &self.member_layout() { - let member = member_layout.member; - let offset = member_layout.offset; - let name = member.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let (div, offset_desc) = if self.bitflags_repr().is_some() { - (4, "Bit") - } else { - (1, "Offset") - }; - let n = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - format!("{}\n{}: {}\n", &member.docs, offset_desc, offset / div).as_str(), - )); - member.tref.generate(n.clone()); - } - } -} - -impl ToMarkdown for Variant { - fn generate(&self, node: MdNodeRef) { - if self.is_bool() { - return; - } - if self.cases.iter().any(|c| c.tref.is_some()) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Variant Layout")); - - let whole = self.mem_size_align(); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("size: {}", whole.size), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("align: {}", whole.align), - )); - - let tag = self.tag_repr.mem_size_align(); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("tag_size: {}", tag.size), - )); - } - - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Variant cases")); - - for case in self.cases.iter() { - let name = case.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let n = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - &case.docs, - )); - if let Some(ty) = &case.tref { - ty.generate(n.clone()); - } - } - } -} - -impl ToMarkdown for HandleDatatype { - fn generate(&self, node: MdNodeRef) { - // TODO this needs more work - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Supertypes")); - } -} - -impl ToMarkdown for Module { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - let imports = node.new_child(MdSection::new(heading, "Imports")); - for import in self.imports() { - let child = imports.new_child(MdSection::new(heading.new_level_down(), "")); - import.generate(child.clone()); - } - - let funcs = node.new_child(MdSection::new(heading, "Functions")); - for func in self.funcs() { - let name = func.name.as_str(); - let child = funcs.new_child(MdFunc::new( - heading.new_level_down(), - name, - name, - &func.docs, - )); - func.generate(child.clone()); - } - } -} - -impl ToMarkdown for ModuleImport { - fn generate(&self, node: MdNodeRef) { - match self.variant { - ModuleImportVariant::Memory => { - node.content_ref_mut::().title = "Memory".to_owned(); - } - } - } -} - -impl ToMarkdown for InterfaceFunc { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Params")); - for param in &self.params { - let name = param.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let child = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - param.name.as_str(), - )); - param.generate(child.clone()); - // TODO should this be expanded recursively instead of using flattened type names? - node.content_ref_mut::() - .inputs - .push((param.name.as_str().to_owned(), param.tref.type_name())); - } - - node.new_child(MdSection::new(heading, "Results")); - for result in &self.results { - let name = result.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let child = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - result.name.as_str(), - )); - result.generate(child.clone()); - // TODO should this be expanded recursively instead of using flattened type names? - node.content_ref_mut::() - .outputs - .push(result.tref.type_name()); - } - } -} - -impl ToMarkdown for InterfaceFuncParam { - fn generate(&self, node: MdNodeRef) { - self.tref.generate(node.clone()); - node.content_ref_mut::().docs = self.docs.clone(); - } -} - -impl BuiltinType { - pub fn type_name(&self) -> &'static str { - match self { - BuiltinType::Char => "char", - BuiltinType::U8 { .. } => "u8", - BuiltinType::U16 => "u16", - BuiltinType::U32 { - lang_ptr_size: false, - } => "u32", - BuiltinType::U32 { - lang_ptr_size: true, - } => "usize", - BuiltinType::U64 => "u64", - BuiltinType::S8 => "s8", - BuiltinType::S16 => "s16", - BuiltinType::S32 => "s32", - BuiltinType::S64 => "s64", - BuiltinType::F32 => "f32", - BuiltinType::F64 => "f64", - } - } -} - -impl TypeRef { - pub fn type_name(&self) -> String { - match self { - TypeRef::Name(n) => n.name.as_str().to_string(), - TypeRef::Value(v) => match &**v { - Type::List(a) => match &**a.type_() { - Type::Builtin(BuiltinType::Char) => "string".to_string(), - _ => format!("List<{}>", a.type_name()), - }, - Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), - Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), - Type::Builtin(b) => b.type_name().to_string(), - Type::Record(RecordDatatype { - kind: RecordKind::Tuple, - members, - }) => { - let mut ret = "(".to_string(); - for (i, member) in members.iter().enumerate() { - if i > 0 { - ret.push_str(", "); - } - ret.push_str(&member.tref.type_name()); - } - ret.push_str(")"); - ret - } - Type::Record { .. } => { - format!("Record") - } - Type::Handle { .. } => { - format!("Handle") - } - Type::Variant(v) => { - if let Some((ok, err)) = v.as_expected() { - let ok = match ok { - Some(ty) => ty.type_name(), - None => "()".to_string(), - }; - let err = match err { - Some(ty) => ty.type_name(), - None => "()".to_string(), - }; - format!("Result<{}, {}>", ok, err) - } else if v.is_bool() { - format!("bool") - } else { - format!("Variant") - } - } - }, - } - } -} - -// TODO -// Generate Markdown tree for the polyfill -impl Documentation for Polyfill { - fn to_md(&self) -> String { - let module_docs = self - .modules - .iter() - .map(|m| m.to_md()) - .collect::>() - .join("\n"); - let type_docs = self - .type_polyfills() - .iter() - .filter_map(|t| { - if t.repeq() == RepEquality::Eq { - None - } else { - Some(t.to_md()) - } - }) - .collect::>() - .join("\n"); - format!( - "# Modules\n{}\n# Type Conversions\n{}\n", - module_docs, type_docs - ) - } -} - -impl Documentation for ModulePolyfill { - fn to_md(&self) -> String { - format!( - "## `{}` in terms of `{}`\n{}", - self.new.name.as_str(), - self.old.name.as_str(), - self.funcs - .iter() - .map(|f| f.to_md()) - .collect::>() - .join("\n"), - ) - } -} - -impl Documentation for FuncPolyfill { - fn to_md(&self) -> String { - if self.full_compat() { - format!("* `{}`: full compatibility", self.new.name.as_str()) - } else { - let name = if self.new.name != self.old.name { - format!( - "* `{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("* `{}`", self.new.name.as_str()) - }; - let mut contents = Vec::new(); - for p in self.mapped_params.iter() { - contents.push(if !p.full_compat() { - format!("param {}", p.to_md()) - } else { - format!("param `{}`: compatible", p.new.name.as_str()) - }) - } - for u in self.unknown_params.iter() { - contents.push(format!( - "{} param `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - for r in self.mapped_results.iter() { - contents.push(if !r.full_compat() { - format!("result {}", r.to_md()) - } else { - format!("result `{}`: compatible", r.new.name.as_str()) - }) - } - for u in self.unknown_results.iter() { - contents.push(format!( - "{} result `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - let contents = if contents.is_empty() { - String::new() - } else { - format!(":\n - {}", contents.join("\n - ")) - }; - format!("{}{}", name, contents) - } - } -} - -impl Documentation for ParamPolyfill { - fn to_md(&self) -> String { - let name = if self.new.name != self.old.name { - format!( - "`{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("`{}`", self.new.name.as_str()) - }; - let repr = match self.repeq() { - RepEquality::Eq => "compatible types".to_string(), - RepEquality::Superset => format!( - "`{}` is superset-compatible with `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - RepEquality::NotEq => format!( - "`{}` is incompatible with new `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - }; - format!("{}: {}", name, repr) - } -} - -impl Documentation for TypePolyfill { - fn to_md(&self) -> String { - fn repeq_name(r: RepEquality) -> &'static str { - match r { - RepEquality::Eq => ": compatible", - RepEquality::Superset => ": superset", - RepEquality::NotEq => "", - } - } - match self { - TypePolyfill::OldToNew(o, n) => format!( - "* old `{}` => new `{}`{}", - o.type_name(), - n.type_name(), - repeq_name(self.repeq()) - ), - TypePolyfill::NewToOld(n, o) => format!( - "* new `{}` => old `{}`{}", - n.type_name(), - o.type_name(), - repeq_name(self.repeq()) - ), - } - } -} diff --git a/proposals/filesystem/tools/witx/src/docs/md.rs b/proposals/filesystem/tools/witx/src/docs/md.rs deleted file mode 100644 index 569b31837..000000000 --- a/proposals/filesystem/tools/witx/src/docs/md.rs +++ /dev/null @@ -1,480 +0,0 @@ -use std::{ - any::Any, - cell::{self, RefCell}, - fmt, - rc::{Rc, Weak}, -}; - -/// Helper trait which simplifies generation of the Markdown document represented -/// as a tree of `MdNodeRef`s. -pub(super) trait ToMarkdown { - /// Drives the generation of the `MdNodeRef` tree by either mutating - /// the outer (parent) `MdNodeRef`, shared reference to the `MdNode` `node`, - /// or spawning new child `MdNodeRef` references to nodes. - fn generate(&self, node: MdNodeRef); -} - -/// Interface required for any "content" that is expected to be generated into a -/// Markdown valid format, hence the constraint of `fmt::Display`. -/// -/// In essence, any AST element that is meant to be rendered into Markdown, should -/// define a type implementing this trait. -pub(super) trait MdElement: fmt::Display + fmt::Debug + 'static { - /// Returns `Some(id)` of this `MdElement`. Here `id` is synonym for a Markdown actionable - /// link. - fn id(&self) -> Option<&str>; - - /// Returns `Some(docs)`, the "docs" of this `MdElement`. - fn docs(&self) -> Option<&str>; - - /// Sets `docs`, the "docs" of this `MdElement`. - fn set_docs(&mut self, docs: &str); - - fn as_any(&self) -> &dyn Any; - fn as_any_mut(&mut self) -> &mut dyn Any; -} - -/// A Markdown node containing: -/// * the Markdown renderable `content`, -/// * a weak reference to the `parent` `MdNode` (if any), and -/// * children `MdNodeRef`s -/// -/// `content` is expected to implement the `MdElement` trait. -#[derive(Debug)] -pub(super) struct MdNode { - content: Box, - parent: Option>>, - children: Vec, -} - -/// Helper function for walking the tree up from some starting `MdNode`, all the way up -/// to the root of the tree. -fn walk_ancestors(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { - if let Some(parent) = parent.and_then(|x| x.upgrade()) { - cb(parent.clone().into()); - walk_ancestors(parent.borrow().parent.as_ref(), cb) - } -} - -impl MdNode { - fn new(item: T) -> Self { - Self { - content: Box::new(item), - parent: None, - children: vec![], - } - } - - /// Returns all ancestors of this `MdNode` all the way to the tree's root. - pub fn ancestors(&self) -> Vec { - let mut ancestors = Vec::new(); - walk_ancestors(self.parent.as_ref(), &mut |parent| ancestors.push(parent)); - ancestors - } - - /// Returns all children of this `MdNode` in a BFS order. - pub fn children(&self) -> Vec { - let mut children = self.children.clone(); - for child in &self.children { - children.append(&mut child.borrow().children()); - } - children - } -} - -impl fmt::Display for MdNode { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.content.fmt(f)?; - - for child in &self.children { - child.fmt(f)?; - } - - Ok(()) - } -} - -/// Helper struct for storing a shared mutable reference to `MdNode`. -#[derive(Debug)] -pub(super) struct MdNodeRef(Rc>); - -impl MdNodeRef { - pub fn new(item: T) -> Self { - Self(Rc::new(RefCell::new(MdNode::new(item)))) - } - - /// Spawns new `MdNode` child node, automatically wrapping it in a - /// `MdNodeRef` and creating a weak link from child to itself. - pub fn new_child(&self, item: T) -> Self { - let mut child_node = MdNode::new(item); - child_node.parent = Some(Rc::downgrade(&self.0)); - let child_ref = Self(Rc::new(RefCell::new(child_node))); - self.borrow_mut().children.push(child_ref.clone()); - child_ref - } - - pub fn borrow(&self) -> cell::Ref { - self.0.borrow() - } - - pub fn borrow_mut(&self) -> cell::RefMut { - self.0.borrow_mut() - } - - /// Returns an immutable reference to `MdNode`'s `content` as-is, that - /// is as some type implementing the `MdElement` trait. - pub fn any_ref(&self) -> cell::Ref> { - cell::Ref::map(self.borrow(), |b| &b.content) - } - - /// Returns a mutable reference to `MdNode`'s `content` as-is, that - /// is as some type implementing the `MdElement` trait. - pub fn any_ref_mut(&self) -> cell::RefMut> { - cell::RefMut::map(self.borrow_mut(), |b| &mut b.content) - } - - /// Returns a mutable reference to `MdNode`'s `content` cast to some type - /// `T` which implements `MdElement` trait. - /// - /// Panics if `content` cannot be downcast to `T`. - pub fn content_ref_mut(&self) -> cell::RefMut { - cell::RefMut::map(self.borrow_mut(), |b| { - let r = b.content.as_any_mut(); - r.downcast_mut::().expect("reference is not T type") - }) - } -} - -impl Clone for MdNodeRef { - fn clone(&self) -> Self { - Self(self.0.clone()) - } -} - -impl From>> for MdNodeRef { - fn from(node: Rc>) -> Self { - Self(node) - } -} - -impl fmt::Display for MdNodeRef { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.borrow().fmt(f) - } -} - -/// Record representing the Markdown tree's root. -/// -/// Doesn't render to anything. -#[derive(Debug, Default)] -pub(super) struct MdRoot; - -impl MdElement for MdRoot { - fn id(&self) -> Option<&str> { - None - } - - fn docs(&self) -> Option<&str> { - None - } - - fn set_docs(&mut self, _: &str) {} - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } -} - -impl fmt::Display for MdRoot { - fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { - Ok(()) - } -} - -/// Helper enum representing either a Markdown header "#" nested at some -/// `level` down the tree, or a bullet "-" in a list which is idempotent -/// to changing the nesting level. -#[derive(Debug, Clone, Copy)] -pub(super) enum MdHeading { - Header { level: usize }, - Bullet, -} - -impl MdHeading { - /// Creates new instance of `MdHeading::Header` variant nested at some - /// `level` down the Markdown tree. - pub fn new_header(level: usize) -> Self { - MdHeading::Header { level } - } - - /// Creates new instance of `MdHeading::Bullet` variant. - pub fn new_bullet() -> Self { - MdHeading::Bullet - } - - /// Copies `MdHeading` and if `MdHeading::Header`, pushes it down one - /// level in the Markdown tree by incrementing `level`. - pub fn new_level_down(&self) -> Self { - let mut copy = *self; - if let Self::Header { ref mut level } = &mut copy { - *level += 1; - } - copy - } -} - -impl fmt::Display for MdHeading { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let as_string = match self { - Self::Header { level } => "#".repeat(*level), - Self::Bullet => "-".to_owned(), - }; - f.write_str(&as_string) - } -} - -/// Record representing a Markdown section without any `docs`, consisting -/// of only a `header` (e.g., "###"), maybe some referencable `id` (i.e., -/// a Markdown link), and some `title`. -/// -/// Example rendering: -/// -/// ### Typenames -/// -#[derive(Debug)] -pub(super) struct MdSection { - pub heading: MdHeading, - pub id: Option, - pub title: String, -} - -impl MdSection { - pub fn new>(heading: MdHeading, title: S) -> Self { - Self { - heading, - id: None, - title: title.as_ref().to_owned(), - } - } -} - -impl MdElement for MdSection { - fn id(&self) -> Option<&str> { - self.id.as_ref().map(|s| s.as_str()) - } - - fn docs(&self) -> Option<&str> { - None - } - - fn set_docs(&mut self, _: &str) {} - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } -} - -fn gen_link>(id: S) -> String { - format!("", id = id.as_ref()) -} - -impl fmt::Display for MdSection { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_fmt(format_args!("{} ", self.heading))?; - - if let Some(id) = &self.id { - f.write_fmt(format_args!("{} ", gen_link(id)))?; - } - - writeln!(f, "{}", self.title) - } -} - -/// Record representing a Markdown section representing any `NamedType` element -/// of the AST. -/// Consists of: -/// * `header`, e.g., "###", or "-" for Enum variants, etc., -/// * referencable `id`, -/// * some `name`, e.g., `errno`, -/// * `docs` paragraph, and -/// * maybe `MdType`. -/// -/// Example rendering (recursive): -/// -/// ### `errno`: Enum(`u16`) -/// Error codes returned by... -/// -/// #### Variants -/// - `success` No error occurred... -/// - `2big` Argument list too long... -/// -#[derive(Debug)] -pub(super) struct MdNamedType { - pub heading: MdHeading, - pub id: String, - pub name: String, - pub docs: String, - pub ty: Option, -} - -impl MdNamedType { - pub fn new>(heading: MdHeading, id: S, name: S, docs: S) -> Self { - Self { - heading, - id: id.as_ref().to_owned(), - name: name.as_ref().to_owned(), - docs: docs.as_ref().to_owned(), - ty: None, - } - } -} - -impl MdElement for MdNamedType { - fn id(&self) -> Option<&str> { - Some(&self.id) - } - - fn docs(&self) -> Option<&str> { - Some(&self.docs) - } - - fn set_docs(&mut self, docs: &str) { - self.docs = docs.to_owned(); - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } -} - -impl fmt::Display for MdNamedType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_fmt(format_args!( - "{heading} {link} `{name}`", - heading = self.heading, - link = gen_link(&self.id), - name = self.name, - ))?; - - if let Some(tt) = &self.ty { - f.write_fmt(format_args!(": {}", tt))?; - } - - writeln!(f, "\n{}", self.docs) - } -} - -/// Record representing a Markdown section representing any `InterfaceFunc` element -/// of the AST. -/// Consists of: -/// * `header`, e.g., "###", -/// * referencable `id`, -/// * some `name`, e.g., `path_open`, -/// * function `inputs`, i.e., arguments, -/// * function `outputs`, i.e., results, and -/// * `docs` paragraph. -/// -/// Example rendering: -/// -/// ### Fn args_get(argv: `Pointer>`, ...) -> `errno` -/// Read command-line... -/// -/// #### Params -/// - `argv`: `Pointer>` Some docs... -/// - ... -/// -/// #### Results -/// - `error`: `errno` Error code... -/// -#[derive(Debug)] -pub(super) struct MdFunc { - pub heading: MdHeading, - pub id: String, - pub name: String, - pub inputs: Vec<(String, String)>, - pub outputs: Vec, - pub docs: String, -} - -impl MdFunc { - pub fn new>(heading: MdHeading, id: S, name: S, docs: S) -> Self { - Self { - heading, - id: id.as_ref().to_owned(), - name: name.as_ref().to_owned(), - inputs: vec![], - outputs: vec![], - docs: docs.as_ref().to_owned(), - } - } -} - -impl MdElement for MdFunc { - fn id(&self) -> Option<&str> { - Some(&self.id) - } - - fn docs(&self) -> Option<&str> { - Some(&self.docs) - } - - fn set_docs(&mut self, docs: &str) { - self.docs = docs.to_owned(); - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } -} - -impl fmt::Display for MdFunc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Expand inputs - let inputs = self - .inputs - .iter() - .map(|(name, r#type)| format!("{}: {}", name, r#type)) - .collect::>() - .join(", "); - // Expand outputs - let outputs: Vec<_> = self - .outputs - .iter() - .map(|r#type| format!("{}", r#type)) - .collect(); - let outputs = match outputs.len() { - 0 => "".to_owned(), - 1 => format!(" -> {}", outputs[0]), - _ => format!(" -> ({})", outputs.join(", ")), - }; - // Format - writeln!(f, "\n---\n")?; - - f.write_fmt(format_args!( - "{heading} {link} `{name}({inputs}){outputs}`", - heading = self.heading, - link = gen_link(&self.id), - name = self.name, - inputs = inputs, - outputs = outputs, - ))?; - - writeln!(f, "\n{}", self.docs) - } -} diff --git a/proposals/filesystem/tools/witx/src/docs/mod.rs b/proposals/filesystem/tools/witx/src/docs/mod.rs deleted file mode 100644 index 8f082cba5..000000000 --- a/proposals/filesystem/tools/witx/src/docs/mod.rs +++ /dev/null @@ -1,87 +0,0 @@ -mod ast; -mod md; - -use crate::ast::Document; -use md::{MdNodeRef, MdRoot, ToMarkdown}; -use std::{ - collections::{hash_map, HashSet}, - iter::FromIterator, -}; - -/// Enables generating Markdown formatted content. -pub trait Documentation { - fn to_md(&self) -> String; -} - -/// Helper function which given input `text` and a `HashSet` of existing links converts -/// any slice of the form '`{link}`' into either -/// 1. "[`{link}`](#{md_link})" where `md_link` is `link` with "::" replaced with "." -/// (in Markdown, scoping should be done with ".") if `md_link` exists in the `HashSet` -/// 2. "`{link}`" otherwise. That is, if `md_link` could not be found in the `HashSet`, we -/// just leave what we've consumed. -fn parse_links>(text: S, existing_links: &HashSet) -> String { - let text = text.as_ref(); - let mut parsed_text = String::with_capacity(text.len()); - let mut link = String::with_capacity(text.len()); - let mut is_link = false; - - for ch in text.chars() { - match (ch, is_link) { - // Found the beginning of a link! - ('`', false) => { - is_link = true; - } - // Reached the end, expand into a link! - ('`', true) => { - // Sanitise scoping by replacing "::" with '.' - let md_link = link.replace("::", "."); - // Before committing to pasting the link in, - // first verify that it actually exists. - let expanded = if let Some(_) = existing_links.get(&md_link) { - format!("[`{}`](#{})", link, md_link) - } else { - log::warn!( - "Link [`{}`](#{}) could not be found in the document!", - link, - md_link - ); - format!("`{}`", link) - }; - parsed_text.push_str(&expanded); - link.drain(..); - is_link = false; - } - (ch, false) => parsed_text.push(ch), - (ch, true) => link.push(ch), - } - } - - parsed_text -} - -impl Documentation for Document { - fn to_md(&self) -> String { - let root = MdNodeRef::new(MdRoot::default()); - self.generate(root.clone()); - // Get all children of the `root` element. - let children = root.borrow().children(); - // Gather all existing links in the document into a set. - let existing_links: HashSet = HashSet::from_iter( - children - .iter() - .filter_map(|x| x.any_ref().id().map(String::from)), - ); - // Traverse each docs section of each child, and parse links - // logging a warning in case the generated is invalid. - for child in children { - let docs_with_links = child - .any_ref() - .docs() - .map(|docs| parse_links(docs, &existing_links)); - if let Some(docs) = docs_with_links { - child.any_ref_mut().set_docs(&docs); - } - } - format!("{}", root) - } -} diff --git a/proposals/filesystem/tools/witx/src/io.rs b/proposals/filesystem/tools/witx/src/io.rs deleted file mode 100644 index f46ab1766..000000000 --- a/proposals/filesystem/tools/witx/src/io.rs +++ /dev/null @@ -1,103 +0,0 @@ -use crate::WitxError; -use std::collections::HashMap; -use std::fs::{read_to_string, File}; -use std::io::{BufRead, BufReader, Error, ErrorKind}; -use std::path::{Path, PathBuf}; - -pub trait WitxIo { - /// Read the entire file into a String. Used to resolve `use` declarations. - fn fgets(&self, path: &Path) -> Result; - /// Read a line of a file into a String. Used for error reporting. - fn fget_line(&self, path: &Path, line_num: usize) -> Result; - /// Return the canonical (non-symlinked) path of a file. Used to resolve `use` declarations. - fn canonicalize(&self, path: &Path) -> Result; -} - -impl WitxIo for &'_ T { - fn fgets(&self, path: &Path) -> Result { - T::fgets(self, path) - } - fn fget_line(&self, path: &Path, line_num: usize) -> Result { - T::fget_line(self, path, line_num) - } - fn canonicalize(&self, path: &Path) -> Result { - T::canonicalize(self, path) - } -} - -pub struct Filesystem; - -impl WitxIo for Filesystem { - fn fgets(&self, path: &Path) -> Result { - read_to_string(path).map_err(|e| WitxError::Io(path.to_path_buf(), e)) - } - fn fget_line(&self, path: &Path, line_num: usize) -> Result { - let f = File::open(path).map_err(|e| WitxError::Io(path.into(), e))?; - let buf = BufReader::new(f); - let l = buf - .lines() - .skip(line_num - 1) - .next() - .ok_or_else(|| { - WitxError::Io(path.into(), Error::new(ErrorKind::Other, "Line not found")) - })? - .map_err(|e| WitxError::Io(path.into(), e))?; - - Ok(l) - } - fn canonicalize(&self, path: &Path) -> Result { - path.canonicalize() - .map_err(|e| WitxError::Io(path.to_path_buf(), e)) - } -} - -pub struct MockFs { - map: HashMap, -} - -impl MockFs { - pub fn new(strings: &[(&str, &str)]) -> Self { - MockFs { - map: strings - .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - } - } -} - -impl WitxIo for MockFs { - fn fgets(&self, path: &Path) -> Result { - if let Some(entry) = self.map.get(path.to_str().unwrap()) { - Ok(entry.to_string()) - } else { - Err(WitxError::Io( - path.to_path_buf(), - Error::new(ErrorKind::Other, "mock fs: file not found"), - )) - } - } - fn fget_line(&self, path: &Path, line: usize) -> Result { - if let Some(entry) = self.map.get(path.to_str().unwrap()) { - entry - .lines() - .skip(line - 1) - .next() - .map(|s| s.to_string()) - .ok_or_else(|| { - WitxError::Io( - path.to_path_buf(), - Error::new(ErrorKind::Other, "mock fs: file not found"), - ) - }) - } else { - Err(WitxError::Io( - path.to_path_buf(), - Error::new(ErrorKind::Other, "mock fs: file not found"), - )) - } - } - fn canonicalize(&self, path: &Path) -> Result { - Ok(PathBuf::from(path)) - } -} diff --git a/proposals/filesystem/tools/witx/src/layout.rs b/proposals/filesystem/tools/witx/src/layout.rs deleted file mode 100644 index 6812f01ae..000000000 --- a/proposals/filesystem/tools/witx/src/layout.rs +++ /dev/null @@ -1,219 +0,0 @@ -use crate::ast::*; -use std::collections::HashMap; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct SizeAlign { - pub size: usize, - pub align: usize, -} - -impl SizeAlign { - fn zero() -> SizeAlign { - SizeAlign { size: 0, align: 0 } - } - fn append_field(&mut self, other: &SizeAlign) { - self.align = self.align.max(other.align); - self.size = align_to(self.size, other.align); - self.size += other.size; - } -} - -pub trait Layout { - fn mem_size_align(&self) -> SizeAlign; - fn mem_size(&self) -> usize { - self.mem_size_align().size - } - fn mem_align(&self) -> usize { - self.mem_size_align().align - } -} - -impl TypeRef { - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - if let Some(hit) = cache.get(self) { - return *hit; - } - let layout = match &self { - TypeRef::Name(nt) => nt.layout(cache), - TypeRef::Value(v) => v.layout(cache), - }; - cache.insert(self.clone(), layout); - layout - } -} - -impl Layout for TypeRef { - fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } -} - -impl NamedType { - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - self.tref.layout(cache) - } -} -impl Layout for NamedType { - fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } -} - -impl Type { - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - match &self { - Type::Record(s) => match s.bitflags_repr() { - Some(repr) => repr.mem_size_align(), - None => s.layout(cache), - }, - Type::Variant(s) => s.mem_size_align(), - Type::Handle(h) => h.mem_size_align(), - Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length - Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::S32.mem_size_align(), - Type::Builtin(b) => b.mem_size_align(), - } - } -} - -impl Layout for Type { - fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } -} - -impl Layout for IntRepr { - fn mem_size_align(&self) -> SizeAlign { - self.to_builtin().mem_size_align() - } -} - -pub struct RecordMemberLayout<'a> { - pub member: &'a RecordMember, - pub offset: usize, -} - -impl RecordDatatype { - pub fn member_layout(&self) -> Vec { - self.member_layout_(&mut HashMap::new()).1 - } - - fn member_layout_( - &self, - cache: &mut HashMap, - ) -> (SizeAlign, Vec) { - let mut members = Vec::new(); - let mut sa = SizeAlign::zero(); - for m in self.members.iter() { - let member = m.tref.layout(cache); - sa.append_field(&member); - members.push(RecordMemberLayout { - member: m, - offset: sa.size - member.size, - }); - } - sa.size = align_to(sa.size, sa.align); - (sa, members) - } - - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - self.member_layout_(cache).0 - } -} - -impl Layout for RecordDatatype { - fn mem_size_align(&self) -> SizeAlign { - match self.bitflags_repr() { - Some(repr) => repr.mem_size_align(), - None => { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } - } - } -} - -impl Layout for Variant { - fn mem_size_align(&self) -> SizeAlign { - let mut max = SizeAlign { size: 0, align: 0 }; - for case in self.cases.iter() { - let mut size = self.tag_repr.mem_size_align(); - if let Some(payload) = &case.tref { - size.append_field(&payload.mem_size_align()); - } - size.size = align_to(size.size, size.align); - max.size = max.size.max(size.size); - max.align = max.align.max(size.align); - } - max - } -} - -impl Variant { - pub fn payload_offset(&self) -> usize { - let mut offset = self.tag_repr.mem_size_align().size; - for case in self.cases.iter() { - if let Some(payload) = &case.tref { - offset = offset.max(align_to(offset, payload.mem_size_align().align)); - } - } - offset - } -} - -/// If the next free byte in the struct is `offs`, and the next -/// element has alignment `alignment`, determine the offset at -/// which to place that element. -fn align_to(offs: usize, alignment: usize) -> usize { - offs + alignment - 1 - ((offs + alignment - 1) % alignment) -} - -#[cfg(test)] -mod test { - use super::align_to; - #[test] - fn align() { - assert_eq!(0, align_to(0, 1)); - assert_eq!(0, align_to(0, 2)); - assert_eq!(0, align_to(0, 4)); - assert_eq!(0, align_to(0, 8)); - - assert_eq!(1, align_to(1, 1)); - assert_eq!(2, align_to(1, 2)); - assert_eq!(4, align_to(1, 4)); - assert_eq!(8, align_to(1, 8)); - - assert_eq!(2, align_to(2, 1)); - assert_eq!(2, align_to(2, 2)); - assert_eq!(4, align_to(2, 4)); - assert_eq!(8, align_to(2, 8)); - - assert_eq!(5, align_to(5, 1)); - assert_eq!(6, align_to(5, 2)); - assert_eq!(8, align_to(5, 4)); - assert_eq!(8, align_to(5, 8)); - } -} - -impl Layout for HandleDatatype { - fn mem_size_align(&self) -> SizeAlign { - BuiltinType::S32.mem_size_align() - } -} - -impl Layout for BuiltinType { - fn mem_size_align(&self) -> SizeAlign { - match self { - BuiltinType::U8 { .. } | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, - BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, - BuiltinType::Char | BuiltinType::U32 { .. } | BuiltinType::S32 | BuiltinType::F32 => { - SizeAlign { size: 4, align: 4 } - } - BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { - SizeAlign { size: 8, align: 8 } - } - } - } -} diff --git a/proposals/filesystem/tools/witx/src/lib.rs b/proposals/filesystem/tools/witx/src/lib.rs deleted file mode 100644 index a0eba6a17..000000000 --- a/proposals/filesystem/tools/witx/src/lib.rs +++ /dev/null @@ -1,97 +0,0 @@ -/// Map witx types to core (wasm standard) types -mod abi; -/// Types describing a validated witx document -mod ast; -/// Render documentation -mod docs; -/// Interface for filesystem or mock IO -mod io; -/// Calculate memory layout of types -mod layout; -/// Witx syntax parsing from SExprs -pub mod parser; -/// Calculate required polyfill between interfaces -pub mod polyfill; -/// Render ast to text -mod render; -/// Representational equality of types -mod representation; -/// Resolve toplevel `use` declarations across files -mod toplevel; -/// Validate declarations into ast -mod validate; - -pub use abi::*; -pub use ast::*; -pub use docs::Documentation; -pub use io::{Filesystem, MockFs, WitxIo}; -pub use layout::{Layout, RecordMemberLayout, SizeAlign}; -pub use render::SExpr; -pub use representation::{RepEquality, Representable}; -pub use validate::{DocValidation, ValidationError}; - -use std::path::{Path, PathBuf}; -use thiserror::Error; - -/// Load a witx document from the filesystem -pub fn load>(paths: &[P]) -> Result { - toplevel::parse_witx(paths) -} - -/// Parse a witx document from a str. `(use ...)` directives are not permitted. -pub fn parse(source: &str) -> Result { - let mockfs = MockFs::new(&[("-", source)]); - toplevel::parse_witx_with(&[Path::new("-")], &mockfs) -} - -/// Location in the source text -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct Location { - pub path: PathBuf, - pub line: usize, - pub column: usize, -} - -#[derive(Debug, Error)] -pub enum WitxError { - #[error("IO error with file {0:?}")] - Io(PathBuf, #[source] ::std::io::Error), - #[error("Parse error")] - Parse(#[from] wast::Error), - #[error("Validation error")] - Validation(#[from] ValidationError), -} - -impl WitxError { - pub fn report_with(&self, witxio: &dyn WitxIo) -> String { - use WitxError::*; - match self { - Io(path, ioerr) => format!("with file {:?}: {}", path, ioerr), - Parse(parse) => parse.to_string(), - Validation(validation) => validation.report_with(witxio), - } - } - pub fn report(&self) -> String { - self.report_with(&Filesystem) - } -} - -impl Location { - pub fn highlight_source_with(&self, witxio: &dyn WitxIo) -> String { - let mut msg = format!("in {:?}:\n", self.path); - if let Ok(src_line) = witxio.fget_line(&self.path, self.line) { - msg += &format!( - "{line_num: >5} | {src_line}\n{blank: >5} {caret: >column$}", - line_num = self.line, - src_line = src_line, - blank = " ", - caret = "^", - column = self.column, - ); - } - msg - } - pub fn highlight_source(&self) -> String { - self.highlight_source_with(&Filesystem) - } -} diff --git a/proposals/filesystem/tools/witx/src/parser.rs b/proposals/filesystem/tools/witx/src/parser.rs deleted file mode 100644 index 33cf745ff..000000000 --- a/proposals/filesystem/tools/witx/src/parser.rs +++ /dev/null @@ -1,778 +0,0 @@ -use crate::BuiltinType; -use wast::parser::{Parse, Parser, Peek, Result}; - -///! Parser turns s-expressions into unvalidated syntax constructs. -///! conventions: -///! `Type::starts_parsing(s-expr) -> bool` is for look-ahead: we use -///! this predicate to combine parsers for different `Type`s where both -///! alternatives are accepted. -///! `Type::parse(sexpr: &SExpr) -> Result` takes a single -///! s-expression and parses it into a `Self`. -///! for parsers that take a subset of a vector s-expression, the signature -///! `Type::parse(sexprs: &[SExpr], location: Location) -> Result` -///! has an additional `Location` argument, which should point to the parent SExpr::Vec. -///! This is used for error reporting in case the slice doesn't have the number of elements -///! expected. - -mod kw { - pub use wast::kw::{export, func, import, memory, module, param, result}; - - wast::custom_keyword!(case); - wast::custom_keyword!(char8); - wast::custom_keyword!(char); - wast::custom_keyword!(const_pointer); - wast::custom_keyword!(f32); - wast::custom_keyword!(f64); - wast::custom_keyword!(field); - wast::custom_keyword!(empty); - wast::custom_keyword!(error); - wast::custom_keyword!(expected); - wast::custom_keyword!(flags); - wast::custom_keyword!(handle); - wast::custom_keyword!(list); - wast::custom_keyword!(noreturn); - wast::custom_keyword!(pointer); - wast::custom_keyword!(record); - wast::custom_keyword!(r#const = "const"); - wast::custom_keyword!(r#enum = "enum"); - wast::custom_keyword!(r#union = "union"); - wast::custom_keyword!(r#use = "use"); - wast::custom_keyword!(repr); - wast::custom_keyword!(s16); - wast::custom_keyword!(s32); - wast::custom_keyword!(s64); - wast::custom_keyword!(s8); - wast::custom_keyword!(string); - wast::custom_keyword!(tag); - wast::custom_keyword!(tuple); - wast::custom_keyword!(typename); - wast::custom_keyword!(u16); - wast::custom_keyword!(u32); - wast::custom_keyword!(u64); - wast::custom_keyword!(u8); - wast::custom_keyword!(usize); - wast::custom_keyword!(variant); - wast::custom_keyword!(bool_ = "bool"); -} - -mod annotation { - wast::annotation!(interface); - wast::annotation!(witx); -} - -impl Parse<'_> for BuiltinType { - fn parse(parser: Parser<'_>) -> Result { - let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::Char) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::U8 { lang_c_char: false }) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::U16) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::U32 { - lang_ptr_size: false, - }) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::U64) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::S8) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::S16) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::S32) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::S64) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::F32) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::F64) - } else { - Err(l.error()) - } - } -} - -impl wast::parser::Peek for BuiltinType { - fn peek(cursor: wast::parser::Cursor<'_>) -> bool { - ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - } - - fn display() -> &'static str { - "builtin type" - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Default)] -pub struct CommentSyntax<'a> { - pub comments: Vec<&'a str>, -} - -impl<'a> Parse<'a> for CommentSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result> { - let comments = parser.step(|mut cursor| { - let mut comments = Vec::new(); - loop { - let (comment, c) = match cursor.comment() { - Some(pair) => pair, - None => break, - }; - cursor = c; - comments.push(if comment.starts_with(";;") { - &comment[2..] - } else { - &comment[2..comment.len() - 2] - }); - } - Ok((comments, cursor)) - })?; - Ok(CommentSyntax { comments }) - } -} - -impl<'a> CommentSyntax<'a> { - pub fn docs(&self) -> String { - // Perform a small amount of preprocessing by removing all trailing - // whitespace, and then also filter for only "doc comments" which are `;;;` - // or `(;; ... ;)`. - let docs = self - .comments - .iter() - .map(|d| d.trim_end()) - .filter_map(|d| { - if d.starts_with(";") { - Some(&d[1..]) - } else { - None - } - }) - .collect::>(); - - // Figure out how much leading whitespace we're going to be trimming from - // all docs, trimming the minimum amount in each doc comment. - let to_trim = docs - .iter() - .filter(|d| !d.is_empty()) - .map(|d| d.len() - d.trim().len()) - .min() - .unwrap_or(0); - - // Separate all documents by a newline and collect everything into a single - // string. - let mut ret = String::new(); - for doc in docs { - if !doc.is_empty() { - ret.push_str(doc[to_trim..].trim_end()); - } - ret.push_str("\n"); - } - return ret; - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Default)] -pub struct Documented<'a, T> { - pub comments: CommentSyntax<'a>, - pub item: T, -} - -impl<'a, T: Parse<'a>> Parse<'a> for Documented<'a, T> { - fn parse(parser: Parser<'a>) -> Result { - let _r1 = parser.register_annotation("witx"); - let _r1 = parser.register_annotation("interface"); - let comments = parser.parse()?; - let item = parser.parse()?; - Ok(Documented { comments, item }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TopLevelDocument<'a> { - pub items: Vec>>, -} - -impl<'a> Parse<'a> for TopLevelDocument<'a> { - fn parse(parser: Parser<'a>) -> Result { - let mut items = Vec::new(); - while !parser.is_empty() { - items.push(parser.parse()?); - } - Ok(TopLevelDocument { items }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum TopLevelSyntax<'a> { - Decl(DeclSyntax<'a>), - Use(&'a str), -} - -impl<'a> Parse<'a> for TopLevelSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - if p.peek::() { - p.parse::()?; - Ok(TopLevelSyntax::Use(p.parse()?)) - } else { - Ok(TopLevelSyntax::Decl(p.parse()?)) - } - }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum DeclSyntax<'a> { - Typename(TypenameSyntax<'a>), - Module(ModuleSyntax<'a>), - Const(Documented<'a, ConstSyntax<'a>>), -} - -impl<'a> Parse<'a> for DeclSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(DeclSyntax::Module(parser.parse()?)) - } else if l.peek::() { - Ok(DeclSyntax::Typename(parser.parse()?)) - } else if l.peek::() { - Ok(DeclSyntax::Const(parser.parse()?)) - } else { - Err(l.error()) - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TypenameSyntax<'a> { - pub ident: wast::Id<'a>, - pub def: TypedefSyntax<'a>, -} - -impl<'a> Parse<'a> for TypenameSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let ident = parser.parse()?; - let def = parser.parse()?; - Ok(TypenameSyntax { ident, def }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum TypedefSyntax<'a> { - Enum(EnumSyntax<'a>), - Tuple(TupleSyntax<'a>), - Expected(ExpectedSyntax<'a>), - Flags(FlagsSyntax<'a>), - Record(RecordSyntax<'a>), - Union(UnionSyntax<'a>), - Variant(VariantSyntax<'a>), - Handle(HandleSyntax), - List(Box>), - Pointer(Box>), - ConstPointer(Box>), - Builtin(BuiltinType), - Ident(wast::Id<'a>), - String, - Bool, -} - -impl<'a> Parse<'a> for TypedefSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(TypedefSyntax::Ident(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Builtin(parser.parse()?)) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::String) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Bool) - } else if l.peek::() { - parser.parens(|parser| { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(TypedefSyntax::Enum(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Tuple(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Expected(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Flags(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Record(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Union(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Variant(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Handle(parser.parse()?)) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::List(Box::new(parser.parse()?))) - } else if l.peek::() { - parser.parse::()?; - let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::ConstPointer(Box::new(parser.parse()?))) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Builtin(BuiltinType::U32 { - lang_ptr_size: true, - })) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Builtin(BuiltinType::U8 { - lang_c_char: true, - })) - } else { - Err(l.error()) - } - } else { - Err(l.error()) - } - }) - } else { - Err(l.error()) - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct EnumSyntax<'a> { - pub repr: Option, - pub members: Vec>>, -} - -impl<'a> Parse<'a> for EnumSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let repr = if parser.peek2::() { - Some(parser.parens(|p| { - p.parse::()?; - p.parse::()?; - p.parse() - })?) - } else { - None - }; - let mut members = Vec::new(); - members.push(parser.parse()?); - while !parser.is_empty() { - members.push(parser.parse()?); - } - Ok(EnumSyntax { repr, members }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TupleSyntax<'a> { - pub types: Vec>, -} - -impl<'a> Parse<'a> for TupleSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let mut types = Vec::new(); - while !parser.is_empty() { - types.push(parser.parse()?); - } - Ok(TupleSyntax { types }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ExpectedSyntax<'a> { - pub ok: Option>>, - pub err: Option>>, -} - -impl<'a> Parse<'a> for ExpectedSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let ok = if !parser.is_empty() && !parser.peek2::() { - Some(Box::new(parser.parse()?)) - } else { - None - }; - let err = parser.parens(|p| { - p.parse::()?; - Ok(if p.is_empty() { - None - } else { - Some(Box::new(p.parse()?)) - }) - })?; - Ok(ExpectedSyntax { ok, err }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ConstSyntax<'a> { - pub ty: wast::Id<'a>, - pub name: wast::Id<'a>, - pub value: u64, -} - -impl<'a> Parse<'a> for ConstSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - parser.parse::()?; - let ty = parser.parse()?; - let name = parser.parse()?; - let value = parser.parse()?; - Ok(ConstSyntax { ty, name, value }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct FlagsSyntax<'a> { - pub repr: Option, - pub flags: Vec>>, -} - -impl<'a> Parse<'a> for FlagsSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let repr = if parser.peek2::() { - Some(parser.parens(|p| { - p.parse::()?; - p.parse::()?; - p.parse() - })?) - } else { - None - }; - let mut flags = Vec::new(); - while !parser.is_empty() { - flags.push(parser.parse()?); - } - Ok(FlagsSyntax { repr, flags }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct RecordSyntax<'a> { - pub fields: Vec>>, -} - -impl<'a> Parse<'a> for RecordSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let mut fields = Vec::new(); - fields.push(parser.parse()?); - while !parser.is_empty() { - fields.push(parser.parse()?); - } - Ok(RecordSyntax { fields }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct FieldSyntax<'a> { - pub name: wast::Id<'a>, - pub type_: TypedefSyntax<'a>, -} - -impl<'a> Parse<'a> for FieldSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - p.parse::()?; - let name = p.parse()?; - let type_ = p.parse()?; - Ok(FieldSyntax { name, type_ }) - }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct UnionSyntax<'a> { - pub tag: Option>>, - pub fields: Vec>>, -} - -impl<'a> Parse<'a> for UnionSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let tag = if parser.peek2::() { - Some(parser.parens(|p| { - p.parse::()?; - p.parse::()?; - p.parse().map(Box::new) - })?) - } else { - None - }; - let mut fields = Vec::new(); - while !parser.is_empty() { - fields.push(parser.parse()?); - } - Ok(UnionSyntax { tag, fields }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct VariantSyntax<'a> { - pub tag: Option>>, - pub cases: Vec>>, -} - -impl<'a> Parse<'a> for VariantSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let tag = if parser.peek2::() { - Some(parser.parens(|p| { - p.parse::()?; - p.parse::()?; - p.parse().map(Box::new) - })?) - } else { - None - }; - let mut cases = Vec::new(); - while !parser.is_empty() { - let comments = parser.parse()?; - let item = parser.parens(|p| p.parse())?; - cases.push(Documented { comments, item }); - } - Ok(VariantSyntax { tag, cases }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CaseSyntax<'a> { - pub name: wast::Id<'a>, - pub ty: Option>, -} - -impl<'a> Parse<'a> for CaseSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - Ok(CaseSyntax { - name: parser.parse()?, - ty: if parser.is_empty() { - None - } else { - Some(parser.parse()?) - }, - }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct HandleSyntax {} - -impl<'a> Parse<'a> for HandleSyntax { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - Ok(HandleSyntax {}) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ModuleSyntax<'a> { - pub name: wast::Id<'a>, - pub decls: Vec>>, -} - -impl<'a> Parse<'a> for ModuleSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let name = parser.parse()?; - let mut decls = Vec::new(); - while !parser.is_empty() { - decls.push(parser.parse()?); - } - Ok(ModuleSyntax { name, decls }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum ModuleDeclSyntax<'a> { - Import(ModuleImportSyntax<'a>), - Func(InterfaceFuncSyntax<'a>), -} - -impl<'a> Parse<'a> for ModuleDeclSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - let mut l = p.lookahead1(); - if l.peek::() { - Ok(ModuleDeclSyntax::Import(p.parse()?)) - } else if l.peek::() { - Ok(ModuleDeclSyntax::Func(p.parse()?)) - } else { - Err(l.error()) - } - }) - } -} - -#[derive(Debug, Clone)] -pub struct ModuleImportSyntax<'a> { - pub name: &'a str, - pub name_loc: wast::Span, - pub type_: ImportTypeSyntax, -} - -impl<'a> Parse<'a> for ModuleImportSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let name_loc = parser.cur_span(); - Ok(ModuleImportSyntax { - name: parser.parse()?, - name_loc, - type_: parser.parens(|p| p.parse())?, - }) - } -} - -impl PartialEq for ModuleImportSyntax<'_> { - fn eq(&self, other: &ModuleImportSyntax<'_>) -> bool { - // skip the `name_loc` field - self.name == other.name && self.type_ == other.type_ - } -} - -impl Eq for ModuleImportSyntax<'_> {} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum ImportTypeSyntax { - Memory, -} - -impl Parse<'_> for ImportTypeSyntax { - fn parse(parser: Parser<'_>) -> Result { - parser.parse::()?; - Ok(ImportTypeSyntax::Memory) - } -} - -#[derive(Debug, Clone)] -pub struct InterfaceFuncSyntax<'a> { - pub export: &'a str, - pub export_loc: wast::Span, - pub params: Vec>>, - pub results: Vec>>, - pub noreturn: bool, -} - -impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - parser.parse::()?; - - let (export_loc, export) = parser.parens(|p| { - p.parse::()?; - Ok((p.cur_span(), p.parse()?)) - })?; - - let mut params = Vec::new(); - let mut results = Vec::new(); - let mut noreturn = false; - - while !parser.is_empty() { - let func_field = parser.parse::>()?; - match func_field.item { - InterfaceFuncField::Param(item) => { - params.push(Documented { - comments: func_field.comments, - item, - }); - } - InterfaceFuncField::Result(item) => { - results.push(Documented { - comments: func_field.comments, - item, - }); - } - InterfaceFuncField::Noreturn => { - noreturn = true; - } - } - } - - Ok(InterfaceFuncSyntax { - export, - export_loc, - params, - results, - noreturn, - }) - } -} - -enum InterfaceFuncField<'a> { - Param(FieldSyntax<'a>), - Result(FieldSyntax<'a>), - Noreturn, -} -impl<'a> Parse<'a> for InterfaceFuncField<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - let mut l = p.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(InterfaceFuncField::Param(FieldSyntax { - name: parser.parse()?, - type_: parser.parse()?, - })) - } else if l.peek::() { - parser.parse::()?; - Ok(InterfaceFuncField::Result(FieldSyntax { - name: parser.parse()?, - type_: parser.parse()?, - })) - } else if l.peek::() { - parser.parse::()?; - let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(InterfaceFuncField::Noreturn) - } else { - Err(l.error()) - } - } else { - Err(l.error()) - } - }) - } -} - -impl PartialEq for InterfaceFuncSyntax<'_> { - fn eq(&self, other: &InterfaceFuncSyntax<'_>) -> bool { - // skip the `export_loc` field - self.export == other.export - && self.params == other.params - && self.results == other.results - && self.noreturn == other.noreturn - } -} - -impl Eq for InterfaceFuncSyntax<'_> {} diff --git a/proposals/filesystem/tools/witx/src/polyfill.rs b/proposals/filesystem/tools/witx/src/polyfill.rs deleted file mode 100644 index c779cfa4e..000000000 --- a/proposals/filesystem/tools/witx/src/polyfill.rs +++ /dev/null @@ -1,255 +0,0 @@ -use crate::{ - Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable, Type, - TypeRef, -}; -use std::collections::{HashMap, HashSet}; -use std::rc::Rc; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum PolyfillError { - #[error("Module not present: {name:?}")] - ModuleNotPresent { name: Id }, - #[error("Function not present: {name:?}")] - FuncNotPresent { module: Id, name: Id }, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Polyfill { - pub modules: Vec, -} - -impl Polyfill { - pub fn new( - new: &Document, - old: &Document, - module_mapping: &HashMap, // Will need a more sophisticated mapping - what about function names, argument names? - ) -> Result { - let mut modules = Vec::new(); - for (newname, oldname) in module_mapping { - let newname = Id::new(newname); - let oldname = Id::new(oldname); - let newmod = new - .module(&newname) - .ok_or_else(|| PolyfillError::ModuleNotPresent { name: newname })?; - let oldmod = old - .module(&oldname) - .ok_or_else(|| PolyfillError::ModuleNotPresent { name: oldname })?; - modules.push(ModulePolyfill::new(newmod, oldmod)?); - } - Ok(Polyfill { modules }) - } - - pub fn type_polyfills(&self) -> HashSet { - self.modules - .iter() - .map(|m| m.type_polyfills()) - .flatten() - .collect() - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ModulePolyfill { - pub new: Rc, - pub old: Rc, - pub funcs: Vec, -} - -impl ModulePolyfill { - pub fn new(new: Rc, old: Rc) -> Result { - let mut funcs = Vec::new(); - for oldfunc in old.funcs() { - let newfunc = new - .func(&oldfunc.name) - .ok_or_else(|| PolyfillError::FuncNotPresent { - module: new.name.clone(), - name: oldfunc.name.clone(), - })?; - funcs.push(FuncPolyfill::new(newfunc, oldfunc)); - } - Ok(ModulePolyfill { new, old, funcs }) - } - pub fn type_polyfills(&self) -> HashSet { - self.funcs - .iter() - .map(|f| f.type_polyfills()) - .flatten() - .collect() - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct FuncPolyfill { - pub new: Rc, - pub old: Rc, - pub mapped_params: Vec, - pub unknown_params: Vec, - pub mapped_results: Vec, - pub unknown_results: Vec, -} - -impl FuncPolyfill { - pub fn new(new: Rc, old: Rc) -> FuncPolyfill { - let mut mapped_params = Vec::new(); - let mut unknown_params = Vec::new(); - - // Old function is called. Need to map each of its parameters to the new function: - for old_param in old.params.iter() { - if let Some(new_param) = new.params.iter().find(|p| p.name == old_param.name) { - mapped_params.push(ParamPolyfill::param(new_param.clone(), old_param.clone())) - } else { - unknown_params.push(ParamUnknown::Old(old_param.clone())); - } - } - // Are any new params not covered by the old params? - // This search is O(n^2), but n ought to be small. - for new_param in new.params.iter() { - if mapped_params - .iter() - .find(|m| m.new.name == new_param.name) - .is_none() - { - unknown_params.push(ParamUnknown::New(new_param.clone())); - } - } - - let mut mapped_results = Vec::new(); - let mut unknown_results = Vec::new(); - - // New function has returned. Need to map each of its results to the old function: - for new_result in new.results.iter() { - if let Some(old_result) = old.results.iter().find(|p| p.name == new_result.name) { - mapped_results.push(ParamPolyfill::result( - new_result.clone(), - old_result.clone(), - )) - } else { - unknown_results.push(ParamUnknown::New(new_result.clone())); - } - } - - // Are any old results not covered by the new results? - for old_result in old.results.iter() { - if mapped_results - .iter() - .find(|m| m.old.name == old_result.name) - .is_none() - { - unknown_results.push(ParamUnknown::Old(old_result.clone())); - } - } - - FuncPolyfill { - new, - old, - mapped_params, - unknown_params, - mapped_results, - unknown_results, - } - } - - pub fn full_compat(&self) -> bool { - self.new.name == self.old.name - && self.mapped_params.iter().all(|p| p.full_compat()) - && self.unknown_params.is_empty() - && self.mapped_results.iter().all(|p| p.full_compat()) - && self.unknown_results.is_empty() - } - - pub fn type_polyfills(&self) -> HashSet { - self.mapped_params - .iter() - .map(|p| p.type_polyfill.clone()) - .chain(self.mapped_results.iter().map(|p| p.type_polyfill.clone())) - .collect() - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ParamPolyfill { - pub new: InterfaceFuncParam, - pub old: InterfaceFuncParam, - pub type_polyfill: TypePolyfill, -} - -impl ParamPolyfill { - fn common_denominator(a: TypeRef, b: TypeRef) -> (TypeRef, TypeRef) { - match (&a, &b) { - (TypeRef::Value(va), TypeRef::Value(vb)) => match (&**va, &**vb) { - (Type::List(a), Type::List(b)) => (a.clone(), b.clone()), - (Type::Pointer(a), Type::Pointer(b)) => (a.clone(), b.clone()), - (Type::ConstPointer(a), Type::ConstPointer(b)) => (a.clone(), b.clone()), - _ => (a, b), - }, - _ => (a, b), - } - } - - pub fn param(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { - let (told, tnew) = Self::common_denominator(old.tref.clone(), new.tref.clone()); - // Call new param type with old param: - let type_polyfill = TypePolyfill::OldToNew(told, tnew); - ParamPolyfill { - new, - old, - type_polyfill, - } - } - - pub fn result(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { - let (told, tnew) = Self::common_denominator(old.tref.clone(), new.tref.clone()); - // Return old result type from new result: - let type_polyfill = TypePolyfill::NewToOld(tnew, told); - ParamPolyfill { - new, - old, - type_polyfill, - } - } - - pub fn full_compat(&self) -> bool { - self.new.name == self.old.name && self.repeq() == RepEquality::Eq - } - - pub fn repeq(&self) -> RepEquality { - self.type_polyfill.repeq() - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum ParamUnknown { - Old(InterfaceFuncParam), - New(InterfaceFuncParam), -} - -impl ParamUnknown { - pub fn which(&self) -> &'static str { - match self { - ParamUnknown::Old { .. } => "old", - ParamUnknown::New { .. } => "new", - } - } - pub fn param(&self) -> &InterfaceFuncParam { - match self { - ParamUnknown::Old(p) => &p, - ParamUnknown::New(p) => &p, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum TypePolyfill { - NewToOld(TypeRef, TypeRef), - OldToNew(TypeRef, TypeRef), -} - -impl TypePolyfill { - pub fn repeq(&self) -> RepEquality { - match self { - TypePolyfill::NewToOld(new, old) => old.type_().representable(&new.type_()), - TypePolyfill::OldToNew(old, new) => new.type_().representable(&old.type_()), - } - } -} diff --git a/proposals/filesystem/tools/witx/src/render.rs b/proposals/filesystem/tools/witx/src/render.rs deleted file mode 100644 index a740e282c..000000000 --- a/proposals/filesystem/tools/witx/src/render.rs +++ /dev/null @@ -1,320 +0,0 @@ -use crate::ast::*; -use std::fmt; - -impl fmt::Display for Document { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for d in self.typenames() { - write!(f, "{}\n", d.to_sexpr())?; - } - for m in self.modules() { - write!(f, "{}\n", m.to_sexpr())?; - } - Ok(()) - } -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub enum SExpr { - Vec(Vec), - Word(String), - Ident(String), - Quote(String), - /// Short for Annotation - Annot(String), - /// Doc comment - Docs(String, Box), -} - -impl fmt::Display for SExpr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - SExpr::Vec(vs) => { - write!(f, "(")?; - let mut vss = Vec::new(); - for v in vs { - vss.push(format!("{}", v)); - } - f.write_str(&vss.join(" "))?; - write!(f, ")") - } - SExpr::Word(w) => write!(f, "{}", w), - SExpr::Ident(i) => write!(f, "${}", i), - SExpr::Quote(q) => write!(f, "\"{}\"", q), - SExpr::Annot(a) => write!(f, "@{}", a), - SExpr::Docs(d, s) => write!(f, "(;; {} ;) {}", d, s), - } - } -} - -impl SExpr { - pub fn word(s: &str) -> SExpr { - SExpr::Word(s.to_string()) - } - pub fn ident(s: &str) -> SExpr { - SExpr::Ident(s.to_string()) - } - pub fn quote(s: &str) -> SExpr { - SExpr::Quote(s.to_string()) - } - pub fn annot(s: &str) -> SExpr { - SExpr::Annot(s.to_string()) - } - pub fn docs(d: &str, s: SExpr) -> SExpr { - if d.is_empty() { - s - } else { - SExpr::Docs(d.to_string(), Box::new(s)) - } - } -} - -impl Id { - pub fn to_sexpr(&self) -> SExpr { - SExpr::ident(self.as_str()) - } -} - -impl BuiltinType { - pub fn to_sexpr(&self) -> SExpr { - match self { - BuiltinType::Char => SExpr::word("char"), - BuiltinType::U8 { lang_c_char: true } => { - SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("char8")]) - } - BuiltinType::U8 { lang_c_char: false } => SExpr::word("u8"), - BuiltinType::U16 => SExpr::word("u16"), - BuiltinType::U32 { - lang_ptr_size: false, - } => SExpr::word("u32"), - BuiltinType::U32 { - lang_ptr_size: true, - } => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), - BuiltinType::U64 => SExpr::word("u64"), - BuiltinType::S8 => SExpr::word("s8"), - BuiltinType::S16 => SExpr::word("s16"), - BuiltinType::S32 => SExpr::word("s32"), - BuiltinType::S64 => SExpr::word("s64"), - BuiltinType::F32 => SExpr::word("f32"), - BuiltinType::F64 => SExpr::word("f64"), - } - } -} - -impl NamedType { - pub fn to_sexpr(&self) -> SExpr { - let body = self.tref.to_sexpr(); - SExpr::docs( - &self.docs, - SExpr::Vec(vec![SExpr::word("typename"), self.name.to_sexpr(), body]), - ) - } -} - -impl TypeRef { - pub fn to_sexpr(&self) -> SExpr { - match self { - TypeRef::Name(n) => n.name.to_sexpr(), - TypeRef::Value(v) => v.to_sexpr(), - } - } -} - -impl Type { - pub fn to_sexpr(&self) -> SExpr { - match self { - Type::Record(a) => a.to_sexpr(), - Type::Variant(a) => a.to_sexpr(), - Type::Handle(a) => a.to_sexpr(), - Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), - Type::Pointer(p) => SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("pointer"), - p.to_sexpr(), - ]), - Type::ConstPointer(p) => SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("const_pointer"), - p.to_sexpr(), - ]), - Type::Builtin(b) => b.to_sexpr(), - } - } -} - -impl RecordDatatype { - pub fn to_sexpr(&self) -> SExpr { - match self.kind { - RecordKind::Tuple => { - let mut tuple = vec![SExpr::word("tuple")]; - for m in self.members.iter() { - tuple.push(SExpr::docs(&m.docs, m.tref.to_sexpr())); - } - SExpr::Vec(tuple) - } - RecordKind::Bitflags(repr) => { - let mut flags = vec![SExpr::word("flags")]; - flags.push(SExpr::Vec(vec![ - SExpr::word("@witx"), - SExpr::word("repr"), - repr.to_sexpr(), - ])); - flags.extend( - self.members - .iter() - .map(|m| SExpr::docs(&m.docs, m.name.to_sexpr())), - ); - SExpr::Vec(flags) - } - RecordKind::Other => { - let header = vec![SExpr::word("record")]; - let members = self - .members - .iter() - .map(|m| { - SExpr::docs( - &m.docs, - SExpr::Vec(vec![ - SExpr::word("field"), - m.name.to_sexpr(), - m.tref.to_sexpr(), - ]), - ) - }) - .collect::>(); - SExpr::Vec([header, members].concat()) - } - } - } -} - -impl Variant { - pub fn to_sexpr(&self) -> SExpr { - let mut list = Vec::new(); - if self.is_bool() { - return SExpr::word("bool"); - } else if self.is_enum() { - list.push(SExpr::word("enum")); - list.push(SExpr::Vec(vec![ - SExpr::word("@witx"), - SExpr::word("tag"), - self.tag_repr.to_sexpr(), - ])); - for case in self.cases.iter() { - list.push(SExpr::docs(&case.docs, case.name.to_sexpr())); - } - } else { - list.push(SExpr::word("variant")); - list.push(SExpr::Vec(vec![ - SExpr::word("@witx"), - SExpr::word("tag"), - self.tag_repr.to_sexpr(), - ])); - for case in self.cases.iter() { - let mut case_expr = vec![SExpr::word("case"), case.name.to_sexpr()]; - if let Some(ty) = &case.tref { - case_expr.push(ty.to_sexpr()); - } - list.push(SExpr::docs(&case.docs, SExpr::Vec(case_expr))); - } - } - SExpr::Vec(list) - } -} - -impl HandleDatatype { - pub fn to_sexpr(&self) -> SExpr { - SExpr::Vec(vec![SExpr::word("handle")]) - } -} - -impl IntRepr { - pub fn to_sexpr(&self) -> SExpr { - match self { - IntRepr::U8 => SExpr::word("u8"), - IntRepr::U16 => SExpr::word("u16"), - IntRepr::U32 => SExpr::word("u32"), - IntRepr::U64 => SExpr::word("u64"), - } - } -} - -impl Module { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("module"), self.name.to_sexpr()]; - let definitions = self - .imports() - .map(|i| i.to_sexpr()) - .chain(self.funcs().map(|f| f.to_sexpr())) - .collect::>(); - SExpr::docs(&self.docs, SExpr::Vec([header, definitions].concat())) - } -} - -impl ModuleImport { - pub fn to_sexpr(&self) -> SExpr { - let variant = match self.variant { - ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), - }; - SExpr::docs( - &self.docs, - SExpr::Vec(vec![ - SExpr::word("import"), - SExpr::quote(self.name.as_str()), - variant, - ]), - ) - } -} - -impl InterfaceFunc { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![ - SExpr::annot("interface"), - SExpr::word("func"), - SExpr::Vec(vec![ - SExpr::word("export"), - SExpr::quote(self.name.as_str()), - ]), - ]; - let params = self - .params - .iter() - .map(|f| { - SExpr::docs( - &f.docs, - SExpr::Vec(vec![ - SExpr::word("param"), - f.name.to_sexpr(), - f.tref.to_sexpr(), - ]), - ) - }) - .collect(); - let results = self - .results - .iter() - .map(|f| { - SExpr::docs( - &f.docs, - SExpr::Vec(vec![ - SExpr::word("result"), - f.name.to_sexpr(), - f.tref.to_sexpr(), - ]), - ) - }) - .collect(); - let attrs = if self.noreturn { - vec![SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("noreturn"), - ])] - } else { - vec![] - }; - SExpr::docs( - &self.docs, - SExpr::Vec([header, params, results, attrs].concat()), - ) - } -} diff --git a/proposals/filesystem/tools/witx/src/representation.rs b/proposals/filesystem/tools/witx/src/representation.rs deleted file mode 100644 index 589b64e39..000000000 --- a/proposals/filesystem/tools/witx/src/representation.rs +++ /dev/null @@ -1,161 +0,0 @@ -use crate::{BuiltinType, IntRepr, NamedType, RecordDatatype, Type, TypeRef, Variant}; -use std::collections::HashMap; - -// A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum RepEquality { - Eq, - Superset, - NotEq, -} - -impl RepEquality { - pub fn join(&self, rhs: &Self) -> Self { - match (self, rhs) { - (RepEquality::Eq, RepEquality::Eq) => RepEquality::Eq, - _ => RepEquality::NotEq, - } - } -} - -pub trait Representable { - fn representable(&self, by: &Self) -> RepEquality; -} - -impl Representable for BuiltinType { - fn representable(&self, by: &Self) -> RepEquality { - // An unsigned integer can be used to represent an unsigned integer of smaller width. - // Otherwise, types must be equal. - if self == by { - return RepEquality::Eq; - } - match self { - BuiltinType::U8 { .. } => match by { - BuiltinType::U64 | BuiltinType::U32 { .. } | BuiltinType::U16 => { - RepEquality::Superset - } - _ => RepEquality::NotEq, - }, - BuiltinType::U16 => match by { - BuiltinType::U64 | BuiltinType::U32 { .. } => RepEquality::Superset, - _ => RepEquality::NotEq, - }, - BuiltinType::U32 { .. } => match by { - BuiltinType::U64 => RepEquality::Superset, - _ => RepEquality::NotEq, - }, - _ => RepEquality::NotEq, - } - } -} - -impl Representable for IntRepr { - fn representable(&self, by: &Self) -> RepEquality { - if self == by { - return RepEquality::Eq; - } - // An unsigned integer can be used to represent an unsigned integer of smaller width. - match self { - IntRepr::U16 => match by { - IntRepr::U32 | IntRepr::U64 => RepEquality::Superset, - _ => RepEquality::NotEq, - }, - IntRepr::U32 => match by { - IntRepr::U64 => RepEquality::Superset, - _ => RepEquality::NotEq, - }, - _ => RepEquality::NotEq, - } - } -} - -impl Representable for Variant { - fn representable(&self, by: &Self) -> RepEquality { - let mut superset = false; - // Integer representation must be compatible - match self.tag_repr.representable(&by.tag_repr) { - RepEquality::NotEq => return RepEquality::NotEq, - RepEquality::Eq => {} - RepEquality::Superset => superset = true, - } - let other_by_name = by - .cases - .iter() - .enumerate() - .map(|(i, c)| (&c.name, (c, i))) - .collect::>(); - // For each variant in self, must have variant of same name in by: - for (i, v) in self.cases.iter().enumerate() { - let other_ty = match other_by_name.get(&v.name) { - Some((_, j)) if i != *j => return RepEquality::NotEq, - Some((other, _)) => &other.tref, - None => return RepEquality::NotEq, - }; - match (&v.tref, other_ty) { - (Some(me), Some(other)) => match me.representable(other) { - RepEquality::NotEq => return RepEquality::NotEq, - RepEquality::Eq => {} - RepEquality::Superset => superset = true, - }, - // We added fields, that's not ok - (Some(_), None) => return RepEquality::NotEq, - // Fields were deleted, that's ok - (None, Some(_)) => superset = true, - (None, None) => {} - } - } - if superset || self.cases.len() < by.cases.len() { - RepEquality::Superset - } else { - RepEquality::Eq - } - } -} - -impl Representable for RecordDatatype { - fn representable(&self, by: &Self) -> RepEquality { - // Records must have exact structural equality - same members, must - // be Eq, in the same order. - // We would require require a more expressive RepEquality enum to describe which members - // might be supersets. - if self.members.len() != by.members.len() { - return RepEquality::NotEq; - } - for (m, bym) in self.members.iter().zip(by.members.iter()) { - if m.name != bym.name { - return RepEquality::NotEq; - } - if m.tref.type_().representable(&*bym.tref.type_()) != RepEquality::Eq { - return RepEquality::NotEq; - } - } - RepEquality::Eq - } -} - -impl Representable for TypeRef { - fn representable(&self, by: &Self) -> RepEquality { - self.type_().representable(&*by.type_()) - } -} - -impl Representable for NamedType { - fn representable(&self, by: &Self) -> RepEquality { - self.tref.representable(&by.tref) - } -} - -impl Representable for Type { - fn representable(&self, by: &Self) -> RepEquality { - match (&self, &by) { - (Type::Variant(s), Type::Variant(b)) => s.representable(b), - (Type::Record(s), Type::Record(b)) => s.representable(b), - (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural - (Type::List(s), Type::List(b)) => s.representable(b), - (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), - (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), - (Type::Builtin(s), Type::Builtin(b)) => s.representable(b), - _ => RepEquality::NotEq, - } - } -} diff --git a/proposals/filesystem/tools/witx/src/toplevel.rs b/proposals/filesystem/tools/witx/src/toplevel.rs deleted file mode 100644 index 257e6edd8..000000000 --- a/proposals/filesystem/tools/witx/src/toplevel.rs +++ /dev/null @@ -1,166 +0,0 @@ -use crate::ast::{Definition, Document}; -use crate::io::{Filesystem, WitxIo}; -use crate::parser::{TopLevelDocument, TopLevelSyntax}; -use crate::validate::DocValidation; -use crate::WitxError; -use std::collections::HashSet; -use std::path::{Path, PathBuf}; - -pub fn parse_witx(i: &[impl AsRef]) -> Result { - let paths = i.iter().map(|p| p.as_ref()).collect::>(); - _parse_witx_with(&paths, &Filesystem) -} - -pub fn parse_witx_with(i: &[impl AsRef], witxio: impl WitxIo) -> Result { - let paths = i.iter().map(|p| p.as_ref()).collect::>(); - _parse_witx_with(&paths, &witxio) -} - -fn _parse_witx_with(paths: &[&Path], io: &dyn WitxIo) -> Result { - let mut validator = DocValidation::new(); - let mut definitions = Vec::new(); - let mut parsed = HashSet::new(); - for path in paths { - let root = path.parent().unwrap_or(Path::new(".")); - - parse_file( - path.file_name().unwrap().as_ref(), - io, - root, - &mut validator, - &mut definitions, - &mut parsed, - )?; - } - Ok(validator.into_document(definitions)) -} - -fn parse_file( - path: &Path, - io: &dyn WitxIo, - root: &Path, - validator: &mut DocValidation, - definitions: &mut Vec, - parsed: &mut HashSet, -) -> Result<(), WitxError> { - let path = io.canonicalize(&root.join(path))?; - if !parsed.insert(path.clone()) { - return Ok(()); - } - let input = io.fgets(&path)?; - - let adjust_err = |mut error: wast::Error| { - error.set_path(&path); - error.set_text(&input); - WitxError::Parse(error) - }; - let buf = wast::parser::ParseBuffer::new(&input).map_err(adjust_err)?; - let doc = wast::parser::parse::(&buf).map_err(adjust_err)?; - - for t in doc.items { - match t.item { - TopLevelSyntax::Decl(d) => { - validator - .scope(&input, &path) - .validate_decl(&d, &t.comments, definitions) - .map_err(WitxError::Validation)?; - } - TopLevelSyntax::Use(u) => { - parse_file(u.as_ref(), io, root, validator, definitions, parsed)?; - } - } - } - - Ok(()) -} - -#[cfg(test)] -mod test { - use super::*; - use crate::ast::*; - use crate::io::MockFs; - - #[test] - fn empty() { - parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", ";; empty")])).expect("parse"); - } - - #[test] - fn one_use() { - parse_witx_with( - &[Path::new("/a")], - &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]), - ) - .unwrap(); - } - - #[test] - fn multi_use() { - let doc = parse_witx_with( - &[Path::new("/a")], - &MockFs::new(&[ - ("/a", "(use \"b\")"), - ("/b", "(use \"c\")\n(typename $b_float f64)"), - ("/c", "(typename $c_int u32)"), - ]), - ) - .expect("parse"); - - let b_float = doc.typename(&Id::new("b_float")).unwrap(); - assert_eq!(**b_float.type_(), Type::Builtin(BuiltinType::F64)); - - let c_int = doc.typename(&Id::new("c_int")).unwrap(); - assert_eq!( - **c_int.type_(), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: false - }) - ); - } - - #[test] - fn diamond_dependency() { - let doc = parse_witx_with( - &[Path::new("/a")], - &MockFs::new(&[ - ("/a", "(use \"b\")\n(use \"c\")"), - ("/b", "(use \"d\")"), - ("/c", "(use \"d\")"), - ("/d", "(typename $d_char u8)"), - ]), - ) - .expect("parse"); - - let d_char = doc.typename(&Id::new("d_char")).unwrap(); - assert_eq!( - **d_char.type_(), - Type::Builtin(BuiltinType::U8 { lang_c_char: false }) - ); - } - - #[test] - fn use_not_found() { - match parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", "(use \"b\")")])) - .err() - .unwrap() - { - WitxError::Io(path, _error) => assert_eq!(path, PathBuf::from("/b")), - e => panic!("wrong error: {:?}", e), - } - } - - #[test] - fn use_invalid() { - match parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", "(use bbbbbbb)")])) - .err() - .unwrap() - { - WitxError::Parse(e) => { - let err = e.to_string(); - assert!(err.contains("expected a string"), "bad error: {}", err); - assert!(err.contains("/a:1:6")); - } - e => panic!("wrong error: {:?}", e), - } - } -} diff --git a/proposals/filesystem/tools/witx/src/validate.rs b/proposals/filesystem/tools/witx/src/validate.rs deleted file mode 100644 index cf4d0ad7f..000000000 --- a/proposals/filesystem/tools/witx/src/validate.rs +++ /dev/null @@ -1,722 +0,0 @@ -use crate::{ - io::{Filesystem, WitxIo}, - parser::{ - CommentSyntax, DeclSyntax, Documented, EnumSyntax, ExpectedSyntax, FlagsSyntax, - HandleSyntax, ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TupleSyntax, TypedefSyntax, - UnionSyntax, VariantSyntax, - }, - Abi, BuiltinType, Case, Constant, Definition, Document, Entry, HandleDatatype, Id, IntRepr, - InterfaceFunc, InterfaceFuncParam, Location, Module, ModuleDefinition, ModuleEntry, - ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordKind, RecordMember, Type, - TypeRef, Variant, -}; -use std::collections::{HashMap, HashSet}; -use std::path::Path; -use std::rc::Rc; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum ValidationError { - #[error("Unknown name `{name}`")] - UnknownName { name: String, location: Location }, - #[error("Redefinition of name `{name}`")] - NameAlreadyExists { - name: String, - at_location: Location, - previous_location: Location, - }, - #[error("Wrong kind of name `{name}`: expected {expected}, got {got}")] - WrongKindName { - name: String, - location: Location, - expected: &'static str, - got: &'static str, - }, - #[error("Recursive definition of name `{name}`")] - Recursive { name: String, location: Location }, - #[error("Invalid representation `{repr:?}`")] - InvalidRepr { - repr: BuiltinType, - location: Location, - }, - #[error("ABI error: {reason}")] - Abi { reason: String, location: Location }, - #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] - AnonymousRecord { location: Location }, - #[error("Union expected {expected} variants, found {found}")] - UnionSizeMismatch { - expected: usize, - found: usize, - location: Location, - }, - #[error("Invalid union tag: {reason}")] - InvalidUnionTag { reason: String, location: Location }, - #[error("Invalid union field `{name}`: {reason}")] - InvalidUnionField { - name: String, - reason: String, - location: Location, - }, -} - -impl ValidationError { - pub fn report_with(&self, witxio: &dyn WitxIo) -> String { - use ValidationError::*; - match self { - UnknownName { location, .. } - | WrongKindName { location, .. } - | Recursive { location, .. } - | InvalidRepr { location, .. } - | Abi { location, .. } - | AnonymousRecord { location, .. } - | UnionSizeMismatch { location, .. } - | InvalidUnionField { location, .. } - | InvalidUnionTag { location, .. } => { - format!("{}\n{}", location.highlight_source_with(witxio), &self) - } - NameAlreadyExists { - at_location, - previous_location, - .. - } => format!( - "{}\n{}\nOriginally defined at:\n{}", - at_location.highlight_source_with(witxio), - &self, - previous_location.highlight_source_with(witxio), - ), - } - } - pub fn report(&self) -> String { - self.report_with(&Filesystem) - } -} - -struct IdentValidation { - names: HashMap, -} - -impl IdentValidation { - fn new() -> Self { - Self { - names: HashMap::new(), - } - } - - fn introduce(&mut self, syntax: &str, location: Location) -> Result { - if let Some(introduced) = self.names.get(syntax) { - Err(ValidationError::NameAlreadyExists { - name: syntax.to_string(), - at_location: location, - previous_location: introduced.clone(), - }) - } else { - self.names.insert(syntax.to_string(), location); - Ok(Id::new(syntax)) - } - } - - fn get(&self, syntax: &str, location: Location) -> Result { - if self.names.get(syntax).is_some() { - Ok(Id::new(syntax)) - } else { - Err(ValidationError::UnknownName { - name: syntax.to_string(), - location, - }) - } - } -} - -pub struct DocValidation { - scope: IdentValidation, - entries: HashMap, - constant_scopes: HashMap, - bool_ty: TypeRef, -} - -pub struct DocValidationScope<'a> { - doc: &'a mut DocValidation, - text: &'a str, - path: &'a Path, -} - -impl DocValidation { - pub fn new() -> Self { - Self { - scope: IdentValidation::new(), - entries: HashMap::new(), - constant_scopes: HashMap::new(), - bool_ty: TypeRef::Value(Rc::new(Type::Variant(Variant { - tag_repr: IntRepr::U32, - cases: vec![ - Case { - name: Id::new("false"), - tref: None, - docs: String::new(), - }, - Case { - name: Id::new("true"), - tref: None, - docs: String::new(), - }, - ], - }))), - } - } - - pub fn scope<'a>(&'a mut self, text: &'a str, path: &'a Path) -> DocValidationScope<'a> { - DocValidationScope { - doc: self, - text, - path, - } - } - - pub fn into_document(self, defs: Vec) -> Document { - Document::new(defs, self.entries) - } -} - -impl DocValidationScope<'_> { - fn location(&self, span: wast::Span) -> Location { - // Wast Span gives 0-indexed lines and columns. Location is 1-indexed. - let (line, column) = span.linecol_in(self.text); - Location { - line: line + 1, - column: column + 1, - path: self.path.to_path_buf(), - } - } - - fn introduce(&mut self, name: &wast::Id<'_>) -> Result { - let loc = self.location(name.span()); - self.doc.scope.introduce(name.name(), loc) - } - - fn get(&self, name: &wast::Id<'_>) -> Result { - let loc = self.location(name.span()); - self.doc.scope.get(name.name(), loc) - } - - pub fn validate_decl( - &mut self, - decl: &DeclSyntax, - comments: &CommentSyntax, - definitions: &mut Vec, - ) -> Result<(), ValidationError> { - match decl { - DeclSyntax::Typename(decl) => { - let name = self.introduce(&decl.ident)?; - let docs = comments.docs(); - let tref = self.validate_datatype(&decl.def, true, decl.ident.span())?; - - let rc_datatype = Rc::new(NamedType { - name: name.clone(), - tref, - docs, - }); - self.doc - .entries - .insert(name.clone(), Entry::Typename(Rc::downgrade(&rc_datatype))); - definitions.push(Definition::Typename(rc_datatype)); - } - - DeclSyntax::Module(syntax) => { - let name = self.introduce(&syntax.name)?; - let mut module_validator = ModuleValidation::new(self); - let decls = syntax - .decls - .iter() - .map(|d| module_validator.validate_decl(&d)) - .collect::, _>>()?; - - let rc_module = Rc::new(Module::new( - name.clone(), - decls, - module_validator.entries, - comments.docs(), - )); - self.doc - .entries - .insert(name, Entry::Module(Rc::downgrade(&rc_module))); - definitions.push(Definition::Module(rc_module)); - } - - DeclSyntax::Const(syntax) => { - let ty = Id::new(syntax.item.ty.name()); - let loc = self.location(syntax.item.name.span()); - let scope = self - .doc - .constant_scopes - .entry(ty.clone()) - .or_insert_with(IdentValidation::new); - let name = scope.introduce(syntax.item.name.name(), loc)?; - // TODO: validate `ty` is a integer datatype that `syntax.value` - // fits within. - definitions.push(Definition::Constant(Constant { - ty, - name, - value: syntax.item.value, - docs: syntax.comments.docs(), - })); - } - } - Ok(()) - } - - fn validate_datatype( - &self, - syntax: &TypedefSyntax, - named: bool, - span: wast::Span, - ) -> Result { - match syntax { - TypedefSyntax::Ident(syntax) => { - let i = self.get(syntax)?; - match self.doc.entries.get(&i) { - Some(Entry::Typename(weak_ref)) => Ok(TypeRef::Name( - weak_ref.upgrade().expect("weak backref to defined type"), - )), - Some(e) => Err(ValidationError::WrongKindName { - name: i.as_str().to_string(), - location: self.location(syntax.span()), - expected: "datatype", - got: e.kind(), - }), - None => Err(ValidationError::Recursive { - name: i.as_str().to_string(), - location: self.location(syntax.span()), - }), - } - } - TypedefSyntax::Enum { .. } - | TypedefSyntax::Flags { .. } - | TypedefSyntax::Record { .. } - | TypedefSyntax::Union { .. } - | TypedefSyntax::Handle { .. } - if !named => - { - Err(ValidationError::AnonymousRecord { - location: self.location(span), - }) - } - other => Ok(TypeRef::Value(Rc::new(match other { - TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), - TypedefSyntax::Tuple(syntax) => Type::Record(self.validate_tuple(&syntax, span)?), - TypedefSyntax::Expected(syntax) => { - Type::Variant(self.validate_expected(&syntax, span)?) - } - TypedefSyntax::Flags(syntax) => Type::Record(self.validate_flags(&syntax, span)?), - TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), - TypedefSyntax::Union(syntax) => Type::Variant(self.validate_union(&syntax, span)?), - TypedefSyntax::Variant(syntax) => { - Type::Variant(self.validate_variant(&syntax, span)?) - } - TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), - TypedefSyntax::List(syntax) => { - Type::List(self.validate_datatype(syntax, false, span)?) - } - TypedefSyntax::Pointer(syntax) => { - Type::Pointer(self.validate_datatype(syntax, false, span)?) - } - TypedefSyntax::ConstPointer(syntax) => { - Type::ConstPointer(self.validate_datatype(syntax, false, span)?) - } - TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), - TypedefSyntax::String => { - Type::List(TypeRef::Value(Rc::new(Type::Builtin(BuiltinType::Char)))) - } - TypedefSyntax::Bool => return Ok(self.doc.bool_ty.clone()), - TypedefSyntax::Ident { .. } => unreachable!(), - }))), - } - } - - fn validate_enum( - &self, - syntax: &EnumSyntax, - span: wast::Span, - ) -> Result { - let mut enum_scope = IdentValidation::new(); - let tag_repr = match &syntax.repr { - Some(repr) => self.validate_int_repr(repr, span)?, - None => IntRepr::U32, - }; - let cases = syntax - .members - .iter() - .map(|i| { - let name = enum_scope.introduce(i.item.name(), self.location(i.item.span()))?; - let docs = i.comments.docs(); - Ok(Case { - name, - tref: None, - docs, - }) - }) - .collect::, _>>()?; - - Ok(Variant { tag_repr, cases }) - } - - fn validate_tuple( - &self, - syntax: &TupleSyntax, - span: wast::Span, - ) -> Result { - let members = syntax - .types - .iter() - .enumerate() - .map(|(i, ty)| { - Ok(RecordMember { - name: Id::new(i.to_string()), - tref: self.validate_datatype(ty, false, span)?, - docs: String::new(), - }) - }) - .collect::, _>>()?; - - Ok(RecordDatatype { - kind: RecordKind::Tuple, - members, - }) - } - - fn validate_expected( - &self, - syntax: &ExpectedSyntax, - span: wast::Span, - ) -> Result { - let ok_ty = match &syntax.ok { - Some(ok) => Some(self.validate_datatype(ok, false, span)?), - None => None, - }; - let err_ty = match &syntax.err { - Some(err) => Some(self.validate_datatype(err, false, span)?), - None => None, - }; - Ok(Variant { - tag_repr: IntRepr::U32, - cases: vec![ - Case { - name: Id::new("ok"), - tref: ok_ty, - docs: String::new(), - }, - Case { - name: Id::new("err"), - tref: err_ty, - docs: String::new(), - }, - ], - }) - } - - fn validate_flags( - &self, - syntax: &FlagsSyntax, - span: wast::Span, - ) -> Result { - let repr = match syntax.repr { - Some(ty) => self.validate_int_repr(&ty, span)?, - None => IntRepr::U32, - }; - let mut flags_scope = IdentValidation::new(); - let mut members = Vec::new(); - for flag in syntax.flags.iter() { - let name = flags_scope.introduce(flag.item.name(), self.location(flag.item.span()))?; - let docs = flag.comments.docs(); - members.push(RecordMember { - name, - docs, - tref: self.doc.bool_ty.clone(), - }); - } - Ok(RecordDatatype { - kind: RecordKind::Bitflags(repr), - members, - }) - } - - fn validate_record( - &self, - syntax: &RecordSyntax, - _span: wast::Span, - ) -> Result { - let mut member_scope = IdentValidation::new(); - let members = syntax - .fields - .iter() - .map(|f| { - let name = member_scope - .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; - let docs = f.comments.docs(); - Ok(RecordMember { name, tref, docs }) - }) - .collect::, _>>()?; - - Ok(RecordDatatype { - kind: RecordKind::Other, - members, - }) - } - - fn validate_union( - &self, - syntax: &UnionSyntax, - span: wast::Span, - ) -> Result { - let (tag_repr, names) = self.union_tag_repr(&syntax.tag, span)?; - - if let Some(names) = &names { - if names.len() != syntax.fields.len() { - return Err(ValidationError::UnionSizeMismatch { - expected: names.len(), - found: syntax.fields.len(), - location: self.location(span), - }); - } - } - - let cases = syntax - .fields - .iter() - .enumerate() - .map(|(i, case)| { - Ok(Case { - name: match &names { - Some(names) => names[i].clone(), - None => Id::new(i.to_string()), - }, - tref: Some(self.validate_datatype(&case.item, false, span)?), - docs: case.comments.docs(), - }) - }) - .collect::, _>>()?; - Ok(Variant { tag_repr, cases }) - } - - fn validate_variant( - &self, - syntax: &VariantSyntax, - span: wast::Span, - ) -> Result { - let (tag_repr, names) = self.union_tag_repr(&syntax.tag, span)?; - - if let Some(names) = &names { - if names.len() != syntax.cases.len() { - return Err(ValidationError::UnionSizeMismatch { - expected: names.len(), - found: syntax.cases.len(), - location: self.location(span), - }); - } - } - - let mut name_set = names - .as_ref() - .map(|names| names.iter().collect::>()); - - let mut cases = syntax - .cases - .iter() - .map(|case| { - let name = Id::new(case.item.name.name()); - if let Some(names) = &mut name_set { - if !names.remove(&name) { - return Err(ValidationError::InvalidUnionField { - name: name.as_str().to_string(), - location: self.location(case.item.name.span()), - reason: format!("does not correspond to variant in tag `tag`"), - }); - } - } - Ok(Case { - name: Id::new(case.item.name.name()), - tref: match &case.item.ty { - Some(ty) => { - Some(self.validate_datatype(ty, false, case.item.name.span())?) - } - None => None, - }, - docs: case.comments.docs(), - }) - }) - .collect::, _>>()?; - - // If we have an explicit tag with an enum then that's instructing us to - // reorder cases based on the order of the enum itself, so do that here. - if let Some(names) = names { - let name_pos = names - .iter() - .enumerate() - .map(|(i, name)| (name, i)) - .collect::>(); - cases.sort_by_key(|c| name_pos[&&c.name]); - } - - Ok(Variant { tag_repr, cases }) - } - - fn union_tag_repr( - &self, - tag: &Option>>, - span: wast::Span, - ) -> Result<(IntRepr, Option>), ValidationError> { - let ty = match tag { - Some(tag) => self.validate_datatype(tag, false, span)?, - None => return Ok((IntRepr::U32, None)), - }; - match &**ty.type_() { - Type::Variant(e) => { - let mut names = Vec::new(); - for c in e.cases.iter() { - if c.tref.is_some() { - return Err(ValidationError::InvalidUnionTag { - location: self.location(span), - reason: format!("all variant cases should have empty payloads"), - }); - } - names.push(c.name.clone()); - } - return Ok((e.tag_repr, Some(names))); - } - Type::Builtin(BuiltinType::U8 { .. }) => return Ok((IntRepr::U8, None)), - Type::Builtin(BuiltinType::U16) => return Ok((IntRepr::U16, None)), - Type::Builtin(BuiltinType::U32 { .. }) => return Ok((IntRepr::U32, None)), - Type::Builtin(BuiltinType::U64) => return Ok((IntRepr::U64, None)), - _ => {} - } - - Err(ValidationError::WrongKindName { - name: "tag".to_string(), - location: self.location(span), - expected: "enum or builtin", - got: ty.type_().kind(), - }) - } - - fn validate_handle( - &self, - _syntax: &HandleSyntax, - _span: wast::Span, - ) -> Result { - Ok(HandleDatatype {}) - } - - fn validate_int_repr( - &self, - type_: &BuiltinType, - span: wast::Span, - ) -> Result { - match type_ { - BuiltinType::U8 { .. } => Ok(IntRepr::U8), - BuiltinType::U16 => Ok(IntRepr::U16), - BuiltinType::U32 { .. } => Ok(IntRepr::U32), - BuiltinType::U64 => Ok(IntRepr::U64), - _ => Err(ValidationError::InvalidRepr { - repr: type_.clone(), - location: self.location(span), - }), - } - } -} - -struct ModuleValidation<'a> { - doc: &'a DocValidationScope<'a>, - scope: IdentValidation, - pub entries: HashMap, -} - -impl<'a> ModuleValidation<'a> { - fn new(doc: &'a DocValidationScope<'a>) -> Self { - Self { - doc, - scope: IdentValidation::new(), - entries: HashMap::new(), - } - } - - fn validate_decl( - &mut self, - decl: &Documented, - ) -> Result { - match &decl.item { - ModuleDeclSyntax::Import(syntax) => { - let loc = self.doc.location(syntax.name_loc); - let name = self.scope.introduce(syntax.name, loc)?; - let variant = match syntax.type_ { - ImportTypeSyntax::Memory => ModuleImportVariant::Memory, - }; - let rc_import = Rc::new(ModuleImport { - name: name.clone(), - variant, - docs: decl.comments.docs(), - }); - self.entries - .insert(name, ModuleEntry::Import(Rc::downgrade(&rc_import))); - Ok(ModuleDefinition::Import(rc_import)) - } - ModuleDeclSyntax::Func(syntax) => { - let loc = self.doc.location(syntax.export_loc); - let name = self.scope.introduce(syntax.export, loc)?; - let mut argnames = IdentValidation::new(); - let params = syntax - .params - .iter() - .map(|f| { - Ok(InterfaceFuncParam { - name: argnames.introduce( - f.item.name.name(), - self.doc.location(f.item.name.span()), - )?, - tref: self.doc.validate_datatype( - &f.item.type_, - false, - f.item.name.span(), - )?, - docs: f.comments.docs(), - }) - }) - .collect::, _>>()?; - let results = syntax - .results - .iter() - .map(|f| { - let tref = - self.doc - .validate_datatype(&f.item.type_, false, f.item.name.span())?; - Ok(InterfaceFuncParam { - name: argnames.introduce( - f.item.name.name(), - self.doc.location(f.item.name.span()), - )?, - tref, - docs: f.comments.docs(), - }) - }) - .collect::, _>>()?; - let noreturn = syntax.noreturn; - let abi = Abi::Preview1; - abi.validate(¶ms, &results) - .map_err(|reason| ValidationError::Abi { - reason, - location: self.doc.location(syntax.export_loc), - })?; - let rc_func = Rc::new(InterfaceFunc { - abi, - name: name.clone(), - params, - results, - noreturn, - docs: decl.comments.docs(), - }); - self.entries - .insert(name, ModuleEntry::Func(Rc::downgrade(&rc_func))); - Ok(ModuleDefinition::Func(rc_func)) - } - } - } -} diff --git a/proposals/filesystem/tools/witx/tests/witxt.rs b/proposals/filesystem/tools/witx/tests/witxt.rs deleted file mode 100644 index 7c002fe1b..000000000 --- a/proposals/filesystem/tools/witx/tests/witxt.rs +++ /dev/null @@ -1,656 +0,0 @@ -//! You can run this test suite with: -//! -//! cargo test --test witxt -//! -//! An argument can be passed as well to filter, based on filename, which test -//! to run -//! -//! cargo test --test witxt foo.witxt - -use anyhow::{anyhow, bail, Context, Result}; -use rayon::prelude::*; -use std::collections::HashMap; -use std::path::{Path, PathBuf}; -use std::str; -use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; -use wast::parser::{self, Parse, ParseBuffer, Parser}; -use witx::{Documentation, Instruction, Representable, WasmType}; - -fn main() { - let tests = find_tests(); - let filter = std::env::args().nth(1); - - let tests = tests - .par_iter() - .filter_map(|test| { - if let Some(filter) = &filter { - if let Some(s) = test.to_str() { - if !s.contains(filter) { - return None; - } - } - } - let contents = std::fs::read(test).unwrap(); - Some((test, contents)) - }) - .collect::>(); - - println!("running {} test files\n", tests.len()); - - let ntests = AtomicUsize::new(0); - let errors = tests - .par_iter() - .filter_map(|(test, contents)| { - WitxtRunner { - ntests: &ntests, - documents: HashMap::new(), - } - .run(test, contents) - .err() - }) - .collect::>(); - - if !errors.is_empty() { - for msg in errors.iter() { - eprintln!("{:?}", msg); - } - - panic!("{} tests failed", errors.len()) - } - - println!( - "test result: ok. {} directives passed\n", - ntests.load(SeqCst) - ); -} - -/// Recursively finds all tests in a whitelisted set of directories which we -/// then load up and test in parallel. -fn find_tests() -> Vec { - let mut tests = Vec::new(); - find_tests("tests/witxt".as_ref(), &mut tests); - tests.sort(); - return tests; - - fn find_tests(path: &Path, tests: &mut Vec) { - for f in path.read_dir().unwrap() { - let f = f.unwrap(); - if f.file_type().unwrap().is_dir() { - find_tests(&f.path(), tests); - continue; - } - - match f.path().extension().and_then(|s| s.to_str()) { - Some("witxt") => {} - _ => continue, - } - tests.push(f.path()); - } - } -} - -struct WitxtRunner<'a> { - ntests: &'a AtomicUsize, - documents: HashMap, -} - -impl WitxtRunner<'_> { - fn run(&mut self, test: &Path, contents: &[u8]) -> Result<()> { - let contents = str::from_utf8(contents)?; - macro_rules! adjust { - ($e:expr) => {{ - let mut e = wast::Error::from($e); - e.set_path(test); - e.set_text(contents); - e - }}; - } - let buf = ParseBuffer::new(contents).map_err(|e| adjust!(e))?; - let witxt = parser::parse::(&buf).map_err(|e| adjust!(e))?; - - let errors = witxt - .directives - .into_iter() - .filter_map(|directive| { - let (line, col) = directive.span().linecol_in(contents); - self.test_directive(contents, test, directive) - .with_context(|| { - format!( - "failed directive on {}:{}:{}", - test.display(), - line + 1, - col + 1 - ) - }) - .err() - }) - .collect::>(); - if errors.is_empty() { - return Ok(()); - } - let mut s = format!("{} test failures in {}:", errors.len(), test.display()); - for mut error in errors { - if let Some(err) = error.downcast_mut::() { - err.set_path(test); - err.set_text(contents); - } - s.push_str("\n\n\t--------------------------------\n\n\t"); - s.push_str(&format!("{:?}", error).replace("\n", "\n\t")); - } - bail!("{}", s) - } - - fn test_directive( - &mut self, - contents: &str, - test: &Path, - directive: WitxtDirective, - ) -> Result<()> { - self.bump_ntests(); - match directive { - WitxtDirective::Witx(witx) => { - let doc = witx.document(contents, test)?; - self.assert_roundtrip(&doc) - .context("failed to round-trip the document")?; - self.assert_md(&doc)?; - if let Some(name) = witx.id { - self.documents.insert(name.name().to_string(), doc); - } - } - WitxtDirective::AssertInvalid { witx, message, .. } => { - let err = match witx.document(contents, test) { - Ok(_) => bail!("witx was valid when it shouldn't be"), - Err(e) => format!("{:?}", anyhow::Error::from(e)), - }; - if !err.contains(message) { - bail!("expected error {:?}\nfound error {}", message, err); - } - } - WitxtDirective::AssertRepresentable { repr, t1, t2, .. } => { - let (t1m, t1t) = t1; - let (t2m, t2t) = t2; - let t1d = self - .documents - .get(t1m.name()) - .ok_or_else(|| anyhow!("no document named {:?}", t1m.name()))?; - let t2d = self - .documents - .get(t2m.name()) - .ok_or_else(|| anyhow!("no document named {:?}", t2m.name()))?; - let t1 = t1d - .typename(&witx::Id::new(t1t)) - .ok_or_else(|| anyhow!("no type named {:?}", t1t))?; - let t2 = t2d - .typename(&witx::Id::new(t2t)) - .ok_or_else(|| anyhow!("no type named {:?}", t2t))?; - match (repr, t1.type_().representable(&t2.type_())) { - (RepEquality::Eq, witx::RepEquality::Eq) - | (RepEquality::Superset, witx::RepEquality::Superset) - | (RepEquality::NotEq, witx::RepEquality::NotEq) => {} - (a, b) => { - bail!("expected {:?} representation, got {:?}", a, b); - } - } - } - WitxtDirective::AssertAbi { - witx, - wasm, - interface, - wasm_signature: (wasm_params, wasm_results), - .. - } => { - let doc = witx.document(contents, test)?; - let module = doc.modules().next().ok_or_else(|| anyhow!("no modules"))?; - let func = module.funcs().next().ok_or_else(|| anyhow!("no funcs"))?; - - let (params, results) = func.wasm_signature(); - if params != wasm_params { - bail!("expected params {:?}, found {:?}", wasm_params, params); - } - if results != wasm_results { - bail!("expected results {:?}, found {:?}", wasm_results, results); - } - - let mut check = AbiBindgen { - abi: wasm.instrs.iter(), - err: None, - contents, - }; - func.call_wasm(&module.name, &mut check); - check.check()?; - check.abi = interface.instrs.iter(); - func.call_interface(&module.name, &mut check); - check.check()?; - } - } - Ok(()) - } - - fn assert_roundtrip(&self, doc: &witx::Document) -> Result<()> { - self.bump_ntests(); - let back_to_sexprs = format!("{}", doc); - let doc2 = witx::parse(&back_to_sexprs)?; - if *doc == doc2 { - return Ok(()); - } - - // Try to get a more specific error message that isn't thousands of - // lines long of debug representations. - for type_ in doc.typenames() { - let type2 = match doc2.typename(&type_.name) { - Some(t) => t, - None => bail!("doc2 missing datatype"), - }; - if type_ != type2 { - bail!("types are not equal\n{:?}\n !=\n{:?}", type_, type2); - } - } - for mod_ in doc.modules() { - let mod2 = match doc2.module(&mod_.name) { - Some(m) => m, - None => bail!("doc2 missing module"), - }; - for import in mod_.imports() { - let import2 = match mod2.import(&import.name) { - Some(i) => i, - None => bail!("mod2 missing import"), - }; - assert_eq!(import, import2); - } - for func in mod_.funcs() { - let func2 = match mod2.func(&func.name) { - Some(f) => f, - None => bail!("mod2 missing func"), - }; - assert_eq!(func, func2); - } - } - bail!("{:?} != {:?}", doc, doc2) - } - - fn assert_md(&self, doc: &witx::Document) -> Result<()> { - self.bump_ntests(); - doc.to_md(); - Ok(()) - } - - fn bump_ntests(&self) { - self.ntests.fetch_add(1, SeqCst); - } -} - -struct AbiBindgen<'a> { - abi: std::slice::Iter<'a, (wast::Span, &'a str)>, - err: Option, - contents: &'a str, -} - -impl AbiBindgen<'_> { - fn check(&mut self) -> Result<()> { - match self.err.take() { - None => Ok(()), - Some(e) => Err(e), - } - } - - fn assert(&mut self, name: &str) { - if self.err.is_some() { - return; - } - match self.abi.next() { - Some((_, s)) if *s == name => {} - Some((span, s)) => { - let (line, col) = span.linecol_in(self.contents); - self.err = Some(anyhow!( - "line {}:{} - expected `{}` found `{}`", - line + 1, - col + 1, - name, - s, - )); - } - None => { - self.err = Some(anyhow!( - "extra instruction `{}` found when none was expected", - name - )); - } - } - } -} - -impl witx::Bindgen for AbiBindgen<'_> { - type Operand = (); - fn emit( - &mut self, - inst: &Instruction<'_>, - _operands: &mut Vec, - results: &mut Vec, - ) { - use witx::Instruction::*; - match inst { - GetArg { nth } => self.assert(&format!("get-arg{}", nth)), - AddrOf => self.assert("addr-of"), - I32FromChar => self.assert("i32.from_char"), - I64FromU64 => self.assert("i64.from_u64"), - I64FromS64 => self.assert("i64.from_s64"), - I32FromU32 => self.assert("i32.from_u32"), - I32FromS32 => self.assert("i32.from_s32"), - I32FromUsize => self.assert("i32.from_usize"), - I32FromU16 => self.assert("i32.from_u16"), - I32FromS16 => self.assert("i32.from_s16"), - I32FromU8 => self.assert("i32.from_u8"), - I32FromS8 => self.assert("i32.from_s8"), - I32FromChar8 => self.assert("i32.from_char8"), - I32FromPointer => self.assert("i32.from_pointer"), - I32FromConstPointer => self.assert("i32.from_const_pointer"), - I32FromHandle { .. } => self.assert("i32.from_handle"), - ListPointerLength => self.assert("list.pointer_length"), - ListFromPointerLength { .. } => self.assert("list.from_pointer_length"), - F32FromIf32 => self.assert("f32.from_if32"), - F64FromIf64 => self.assert("f64.from_if64"), - CallWasm { .. } => self.assert("call.wasm"), - CallInterface { .. } => self.assert("call.interface"), - S8FromI32 => self.assert("s8.from_i32"), - U8FromI32 => self.assert("u8.from_i32"), - S16FromI32 => self.assert("s16.from_i32"), - U16FromI32 => self.assert("u16.from_i32"), - S32FromI32 => self.assert("s32.from_i32"), - U32FromI32 => self.assert("u32.from_i32"), - S64FromI64 => self.assert("s64.from_i64"), - U64FromI64 => self.assert("u64.from_i64"), - CharFromI32 => self.assert("char.from_i32"), - Char8FromI32 => self.assert("char8.from_i32"), - UsizeFromI32 => self.assert("usize.from_i32"), - If32FromF32 => self.assert("if32.from_f32"), - If64FromF64 => self.assert("if64.from_f64"), - HandleFromI32 { .. } => self.assert("handle.from_i32"), - PointerFromI32 { .. } => self.assert("pointer.from_i32"), - ConstPointerFromI32 { .. } => self.assert("const_pointer.from_i32"), - ReturnPointerGet { n } => self.assert(&format!("return_pointer.get{}", n)), - ResultLift => self.assert("result.lift"), - ResultLower { .. } => self.assert("result.lower"), - EnumLift { .. } => self.assert("enum.lift"), - EnumLower { .. } => self.assert("enum.lower"), - TupleLift { .. } => self.assert("tuple.lift"), - TupleLower { .. } => self.assert("tuple.lower"), - ReuseReturn => self.assert("reuse_return"), - Load { .. } => self.assert("load"), - Store { .. } => self.assert("store"), - Return { .. } => self.assert("return"), - VariantPayload => self.assert("variant-payload"), - I32FromBitflags { .. } => self.assert("i32.from_bitflags"), - BitflagsFromI32 { .. } => self.assert("bitflags.from_i32"), - I64FromBitflags { .. } => self.assert("i64.from_bitflags"), - BitflagsFromI64 { .. } => self.assert("bitflags.from_i64"), - } - for _ in 0..inst.results_len() { - results.push(()); - } - } - - fn allocate_space(&mut self, _: usize, _: &witx::NamedType) { - self.assert("allocate-space"); - } - - fn push_block(&mut self) { - self.assert("block.push"); - } - - fn finish_block(&mut self, _operand: Option) { - self.assert("block.finish"); - } -} - -mod kw { - wast::custom_keyword!(assert_invalid); - wast::custom_keyword!(assert_representable); - wast::custom_keyword!(assert_abi); - wast::custom_keyword!(witx); - wast::custom_keyword!(eq); - wast::custom_keyword!(noteq); - wast::custom_keyword!(load); - wast::custom_keyword!(superset); - wast::custom_keyword!(call_wasm); - wast::custom_keyword!(call_interface); - wast::custom_keyword!(param); - wast::custom_keyword!(result); - wast::custom_keyword!(wasm); - wast::custom_keyword!(i32); - wast::custom_keyword!(i64); - wast::custom_keyword!(f32); - wast::custom_keyword!(f64); -} - -struct Witxt<'a> { - directives: Vec>, -} - -impl<'a> Parse<'a> for Witxt<'a> { - fn parse(parser: Parser<'a>) -> parser::Result { - let mut directives = Vec::new(); - while !parser.is_empty() { - directives.push(parser.parens(|p| p.parse())?); - } - Ok(Witxt { directives }) - } -} - -enum WitxtDirective<'a> { - Witx(Witx<'a>), - AssertInvalid { - span: wast::Span, - witx: Witx<'a>, - message: &'a str, - }, - AssertRepresentable { - span: wast::Span, - repr: RepEquality, - t1: (wast::Id<'a>, &'a str), - t2: (wast::Id<'a>, &'a str), - }, - AssertAbi { - span: wast::Span, - witx: Witx<'a>, - wasm_signature: (Vec, Vec), - wasm: Abi<'a>, - interface: Abi<'a>, - }, -} - -impl WitxtDirective<'_> { - fn span(&self) -> wast::Span { - match self { - WitxtDirective::Witx(w) => w.span, - WitxtDirective::AssertInvalid { span, .. } - | WitxtDirective::AssertAbi { span, .. } - | WitxtDirective::AssertRepresentable { span, .. } => *span, - } - } -} - -impl<'a> Parse<'a> for WitxtDirective<'a> { - fn parse(parser: Parser<'a>) -> parser::Result { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(WitxtDirective::Witx(parser.parse()?)) - } else if l.peek::() { - let span = parser.parse::()?.0; - Ok(WitxtDirective::AssertInvalid { - span, - witx: parser.parens(|p| p.parse())?, - message: parser.parse()?, - }) - } else if l.peek::() { - let span = parser.parse::()?.0; - Ok(WitxtDirective::AssertRepresentable { - span, - repr: parser.parse()?, - t1: (parser.parse()?, parser.parse()?), - t2: (parser.parse()?, parser.parse()?), - }) - } else if l.peek::() { - let span = parser.parse::()?.0; - Ok(WitxtDirective::AssertAbi { - span, - witx: parser.parens(|p| p.parse())?, - wasm_signature: parser.parens(|p| { - p.parse::()?; - let mut params = Vec::new(); - let mut results = Vec::new(); - if p.peek2::() { - p.parens(|p| { - p.parse::()?; - while !p.is_empty() { - params.push(parse_wasmtype(p)?); - } - Ok(()) - })?; - } - if p.peek2::() { - p.parens(|p| { - p.parse::()?; - while !p.is_empty() { - results.push(parse_wasmtype(p)?); - } - Ok(()) - })?; - } - Ok((params, results)) - })?, - wasm: parser.parens(|p| { - p.parse::()?; - p.parse() - })?, - interface: parser.parens(|p| { - p.parse::()?; - p.parse() - })?, - }) - } else { - Err(l.error()) - } - } -} - -fn parse_wasmtype(p: Parser<'_>) -> parser::Result { - let mut l = p.lookahead1(); - if l.peek::() { - p.parse::()?; - Ok(WasmType::I32) - } else if l.peek::() { - p.parse::()?; - Ok(WasmType::I64) - } else if l.peek::() { - p.parse::()?; - Ok(WasmType::F32) - } else if l.peek::() { - p.parse::()?; - Ok(WasmType::F64) - } else { - Err(l.error()) - } -} - -struct Witx<'a> { - span: wast::Span, - id: Option>, - def: WitxDef<'a>, -} - -enum WitxDef<'a> { - Fs(Vec<&'a str>), - Inline(Vec>>), -} - -impl Witx<'_> { - fn document(&self, contents: &str, file: &Path) -> Result { - match &self.def { - WitxDef::Inline(decls) => { - let mut validator = witx::DocValidation::new(); - let mut definitions = Vec::new(); - for decl in decls { - validator - .scope(contents, file) - .validate_decl(&decl.item, &decl.comments, &mut definitions) - .map_err(witx::WitxError::Validation)?; - } - Ok(validator.into_document(definitions)) - } - WitxDef::Fs(paths) => { - let parent = file.parent().unwrap(); - let paths = paths.iter().map(|p| parent.join(p)).collect::>(); - Ok(witx::load(&paths)?) - } - } - } -} - -impl<'a> Parse<'a> for Witx<'a> { - fn parse(parser: Parser<'a>) -> parser::Result { - let span = parser.parse::()?.0; - let id = parser.parse()?; - - let def = if parser.peek2::() { - parser.parens(|p| { - p.parse::()?; - let mut paths = Vec::new(); - while !p.is_empty() { - paths.push(p.parse()?); - } - Ok(WitxDef::Fs(paths)) - })? - } else { - let mut decls = Vec::new(); - while !parser.is_empty() { - decls.push(parser.parens(|p| p.parse())?); - } - WitxDef::Inline(decls) - }; - Ok(Witx { id, span, def }) - } -} - -#[derive(Debug)] -enum RepEquality { - Eq, - NotEq, - Superset, -} - -impl<'a> Parse<'a> for RepEquality { - fn parse(parser: Parser<'a>) -> parser::Result { - let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(RepEquality::Eq) - } else if l.peek::() { - parser.parse::()?; - Ok(RepEquality::NotEq) - } else if l.peek::() { - parser.parse::()?; - Ok(RepEquality::Superset) - } else { - Err(l.error()) - } - } -} - -struct Abi<'a> { - instrs: Vec<(wast::Span, &'a str)>, -} - -impl<'a> Parse<'a> for Abi<'a> { - fn parse(parser: Parser<'a>) -> parser::Result { - let mut instrs = Vec::new(); - while !parser.is_empty() { - instrs.push(parser.step(|cursor| { - let (kw, next) = cursor - .keyword() - .ok_or_else(|| cursor.error("expected keyword"))?; - Ok(((cursor.cur_span(), kw), next)) - })?); - } - Ok(Abi { instrs }) - } -} diff --git a/proposals/filesystem/tools/witx/tests/witxt/abi.witxt b/proposals/filesystem/tools/witx/tests/witxt/abi.witxt deleted file mode 100644 index ccdad7bf4..000000000 --- a/proposals/filesystem/tools/witx/tests/witxt/abi.witxt +++ /dev/null @@ -1,490 +0,0 @@ -(assert_abi - (witx (module $x (@interface func (export "f")))) - (wasm) - (call_wasm call.wasm return) - (call_interface call.interface return) -) - -;; scalar arguments -(assert_abi - (witx (module $x (@interface func (export "f") (param $p u8)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_u8 call.wasm return) - (call_interface get-arg0 u8.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p s8)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_s8 call.wasm return) - (call_interface get-arg0 s8.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p u16)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_u16 call.wasm return) - (call_interface get-arg0 u16.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p s16)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_s16 call.wasm return) - (call_interface get-arg0 s16.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p u32)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_u32 call.wasm return) - (call_interface get-arg0 u32.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p s32)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_s32 call.wasm return) - (call_interface get-arg0 s32.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p u64)))) - (wasm (param i64)) - (call_wasm get-arg0 i64.from_u64 call.wasm return) - (call_interface get-arg0 u64.from_i64 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p s64)))) - (wasm (param i64)) - (call_wasm get-arg0 i64.from_s64 call.wasm return) - (call_interface get-arg0 s64.from_i64 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p f32)))) - (wasm (param f32)) - (call_wasm get-arg0 f32.from_if32 call.wasm return) - (call_interface get-arg0 if32.from_f32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p f64)))) - (wasm (param f64)) - (call_wasm get-arg0 f64.from_if64 call.wasm return) - (call_interface get-arg0 if64.from_f64 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p (@witx usize))))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_usize call.wasm return) - (call_interface get-arg0 usize.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p (@witx char8))))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_char8 call.wasm return) - (call_interface get-arg0 char8.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p char)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_char call.wasm return) - (call_interface get-arg0 char.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p (@witx pointer u8))))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_pointer call.wasm return) - (call_interface get-arg0 pointer.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p (@witx const_pointer u8))))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_const_pointer call.wasm return) - (call_interface get-arg0 const_pointer.from_i32 call.interface return) -) - -;; flags parameter -(assert_abi - (witx - (typename $a (flags $x $y)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_bitflags call.wasm return) - (call_interface get-arg0 bitflags.from_i32 call.interface return) -) -(assert_abi - (witx - (typename $a (flags (@witx repr u64) $x $y)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i64)) - (call_wasm get-arg0 i64.from_bitflags call.wasm return) - (call_interface get-arg0 bitflags.from_i64 call.interface return) -) - -;; struct parameter -(assert_abi - (witx - (typename $a (record (field $x u8))) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 addr-of call.wasm return) - (call_interface get-arg0 load call.interface return) -) - -;; handle parameter -(assert_abi - (witx - (typename $a (handle)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_handle call.wasm return) - (call_interface get-arg0 handle.from_i32 call.interface return) -) - -;; list parameter -(assert_abi - (witx - (module $x (@interface func (export "f") (param $p (list u8)))) - ) - (wasm (param i32 i32)) - (call_wasm get-arg0 list.pointer_length call.wasm return) - (call_interface get-arg0 get-arg1 list.from_pointer_length call.interface return) -) - -;; variant parameter -- some not allowed at this time -(assert_abi - (witx - (typename $a (enum $b)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 enum.lower call.wasm return) - (call_interface get-arg0 enum.lift call.interface return) -) -(assert_abi - (witx - (typename $a (union f32)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 addr-of call.wasm return) - (call_interface get-arg0 load call.interface return) -) - -;; scalar returns -(assert_abi - (witx (module $x (@interface func (export "f") (result $p u8)))) - (wasm (result i32)) - (call_wasm call.wasm u8.from_i32 return) - (call_interface call.interface i32.from_u8 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p s8)))) - (wasm (result i32)) - (call_wasm call.wasm s8.from_i32 return) - (call_interface call.interface i32.from_s8 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p u16)))) - (wasm (result i32)) - (call_wasm call.wasm u16.from_i32 return) - (call_interface call.interface i32.from_u16 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p s16)))) - (wasm (result i32)) - (call_wasm call.wasm s16.from_i32 return) - (call_interface call.interface i32.from_s16 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p u32)))) - (wasm (result i32)) - (call_wasm call.wasm u32.from_i32 return) - (call_interface call.interface i32.from_u32 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p s32)))) - (wasm (result i32)) - (call_wasm call.wasm s32.from_i32 return) - (call_interface call.interface i32.from_s32 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p u64)))) - (wasm (result i64)) - (call_wasm call.wasm u64.from_i64 return) - (call_interface call.interface i64.from_u64 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p s64)))) - (wasm (result i64)) - (call_wasm call.wasm s64.from_i64 return) - (call_interface call.interface i64.from_s64 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p f32)))) - (wasm (result f32)) - (call_wasm call.wasm if32.from_f32 return) - (call_interface call.interface f32.from_if32 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p f64)))) - (wasm (result f64)) - (call_wasm call.wasm if64.from_f64 return) - (call_interface call.interface f64.from_if64 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p (@witx usize))))) - (wasm (result i32)) - (call_wasm call.wasm usize.from_i32 return) - (call_interface call.interface i32.from_usize return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p (@witx char8))))) - (wasm (result i32)) - (call_wasm call.wasm char8.from_i32 return) - (call_interface call.interface i32.from_char8 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p char)))) - (wasm (result i32)) - (call_wasm call.wasm char.from_i32 return) - (call_interface call.interface i32.from_char return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p (@witx pointer u8))))) - (wasm (result i32)) - (call_wasm call.wasm pointer.from_i32 return) - (call_interface call.interface i32.from_pointer return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p (@witx const_pointer u8))))) - (wasm (result i32)) - (call_wasm call.wasm const_pointer.from_i32 return) - (call_interface call.interface i32.from_const_pointer return) -) - -;; flags return -(assert_abi - (witx - (typename $a (flags $x $y)) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (result i32)) - (call_wasm call.wasm bitflags.from_i32 return) - (call_interface call.interface i32.from_bitflags return) -) -(assert_abi - (witx - (typename $a (flags (@witx repr u64) $x $y)) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (result i64)) - (call_wasm call.wasm bitflags.from_i64 return) - (call_interface call.interface i64.from_bitflags return) -) - -;; handle return -(assert_abi - (witx - (typename $a (handle)) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (result i32)) - (call_wasm call.wasm handle.from_i32 return) - (call_interface call.interface i32.from_handle return) -) - -;; struct return -- not supported -(assert_invalid - (witx - (typename $a (record (field $x u8))) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: invalid return type" -) - -;; list return -- not supported -(assert_invalid - (witx - (module $x (@interface func (export "f") (result $p (list u8)))) - ) - "ABI error: invalid return type" -) - -;; variant return -- only some allowed -(assert_invalid - (witx - (typename $a (enum $b)) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: invalid return type" -) -(assert_invalid - (witx - (typename $a (union s32 f32)) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: invalid return type" -) -(assert_invalid - (witx - (typename $a (expected (error f32))) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: only named types are allowed in results" -) -(assert_invalid - (witx - (typename $errno (enum $success $bad)) - (typename $a (expected f32 (error $errno))) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: only named types are allowed in results" -) - -;; Result<(), $errno> -(assert_abi - (witx - (typename $errno (enum $success $bad)) - (typename $a (expected (error $errno))) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (result i32)) - - (call_wasm - call.wasm - ;; ok block, nothing happens - block.push - block.finish - ;; err block, we lift the return value as the num - block.push - reuse_return - enum.lift - block.finish - ;; consumes 2 blocks and uses the return value of the call to discriminate - result.lift - return) - - (call_interface - call.interface - - ;; ok block, nothing happens - block.push - block.finish - - ;; err block, lift the enum - block.push - variant-payload - enum.lower - block.finish - - ;; consume the 2 blocks and lower based on the call - result.lower - return) -) - -;; Result<$ty, $errno> -(assert_abi - (witx - (typename $errno (enum $success $bad)) - (typename $size u32) - (typename $a (expected $size (error $errno))) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (param i32) (result i32)) - - (call_wasm - ;; make space for the return value and push its pointer - allocate-space - return_pointer.get0 - - call.wasm - - ;; ok block, load the return pointer and have it be the result for the `Ok` - block.push - return_pointer.get0 - load - block.finish - - block.push - reuse_return - enum.lift - block.finish - - result.lift - return) - - (call_interface - call.interface - - ;; store the successful result at the first return pointer (the first param) - block.push - variant-payload - get-arg0 - store - block.finish - - block.push - variant-payload - enum.lower - block.finish - - result.lower - return) -) - -;; Result<($a, $b), $errno> -(assert_abi - (witx - (typename $errno (enum $success $bad)) - (typename $size u32) - (typename $other (record (field $a $size))) - (module $x (@interface func (export "f") - (result $p (expected (tuple $size $other) (error $errno))))) - ) - (wasm (param i32 i32) (result i32)) - - (call_wasm - allocate-space - return_pointer.get0 - allocate-space - return_pointer.get1 - - call.wasm - - block.push - return_pointer.get0 - load - return_pointer.get1 - load - tuple.lift - block.finish - - block.push - reuse_return - enum.lift - block.finish - - result.lift - return) - - (call_interface - call.interface - - ;; note the reverse order since we're consuming the results of lowering the - ;; tuple - block.push - variant-payload - tuple.lower - get-arg1 - store - get-arg0 - store - block.finish - - block.push - variant-payload - enum.lower - block.finish - - result.lower - return) -) diff --git a/proposals/filesystem/tools/witx/tests/witxt/anonymous.witxt b/proposals/filesystem/tools/witx/tests/witxt/anonymous.witxt deleted file mode 100644 index 0ed3bc0d2..000000000 --- a/proposals/filesystem/tools/witx/tests/witxt/anonymous.witxt +++ /dev/null @@ -1,56 +0,0 @@ -;; Ensure that anonymous structured types are not allowed in type positions at -;; this time, everything has to be named to assist in binding in languages. - -(assert_invalid - (witx - (typename $a (@witx pointer (record (field $b u8)))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (@witx pointer (union))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (@witx pointer (enum $b))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (@witx pointer (flags $b))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (@witx pointer (handle))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (record (field $b (record (field $c u8))))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $tag (enum $c)) - (typename $a (record (field $b (union)))) - ) - "Anonymous structured types") - - -;; pointers don't count for anonymous indirections -(witx - (typename $a (@witx pointer u8))) - -(witx - (typename $a (@witx pointer (@witx const_pointer u8)))) - -(witx - (typename $a (record (field $b (@witx pointer u8))))) diff --git a/proposals/filesystem/tools/witx/tests/witxt/multimodule.witxt b/proposals/filesystem/tools/witx/tests/witxt/multimodule.witxt deleted file mode 100644 index d8b6559ac..000000000 --- a/proposals/filesystem/tools/witx/tests/witxt/multimodule.witxt +++ /dev/null @@ -1,22 +0,0 @@ -;; B uses A, and C uses A. -(witx $multi - (load "multimodule/type_b.witx" "multimodule/type_c.witx") -) - -(witx $reference - (typename $a u32) - (typename $b (record (field $member_a $a))) - (typename $c (record (field $first_a $a) (field $second_a $a))) -) - -(assert_representable eq $reference "a" $multi "a") -(assert_representable eq $reference "b" $multi "b") -(assert_representable eq $reference "c" $multi "c") - -(assert_invalid - (witx - (load - "multimodule/type_a.witx" - "multimodule/redefine_a.witx") - ) - "Redefinition of name `a`") diff --git a/proposals/filesystem/tools/witx/tests/witxt/multimodule/redefine_a.witx b/proposals/filesystem/tools/witx/tests/witxt/multimodule/redefine_a.witx deleted file mode 100644 index e5d99d82c..000000000 --- a/proposals/filesystem/tools/witx/tests/witxt/multimodule/redefine_a.witx +++ /dev/null @@ -1 +0,0 @@ -(typename $a u8) diff --git a/proposals/filesystem/tools/witx/tests/witxt/multimodule/type_a.witx b/proposals/filesystem/tools/witx/tests/witxt/multimodule/type_a.witx deleted file mode 100644 index 5499ff3db..000000000 --- a/proposals/filesystem/tools/witx/tests/witxt/multimodule/type_a.witx +++ /dev/null @@ -1 +0,0 @@ -(typename $a u32) diff --git a/proposals/filesystem/tools/witx/tests/witxt/multimodule/type_b.witx b/proposals/filesystem/tools/witx/tests/witxt/multimodule/type_b.witx deleted file mode 100644 index fe169d3ec..000000000 --- a/proposals/filesystem/tools/witx/tests/witxt/multimodule/type_b.witx +++ /dev/null @@ -1,2 +0,0 @@ -(use "type_a.witx") -(typename $b (record (field $member_a $a))) diff --git a/proposals/filesystem/tools/witx/tests/witxt/multimodule/type_c.witx b/proposals/filesystem/tools/witx/tests/witxt/multimodule/type_c.witx deleted file mode 100644 index f42aac2d0..000000000 --- a/proposals/filesystem/tools/witx/tests/witxt/multimodule/type_c.witx +++ /dev/null @@ -1,2 +0,0 @@ -(use "type_a.witx") -(typename $c (record (field $first_a $a) (field $second_a $a))) diff --git a/proposals/filesystem/tools/witx/tests/witxt/representation.witxt b/proposals/filesystem/tools/witx/tests/witxt/representation.witxt deleted file mode 100644 index 53f71f196..000000000 --- a/proposals/filesystem/tools/witx/tests/witxt/representation.witxt +++ /dev/null @@ -1,60 +0,0 @@ -;; type names don't matter -(witx $a - (typename $a (flags (@witx repr u8) $b $c))) -(witx $b - (typename $b (flags (@witx repr u8) $b $c))) - -(assert_representable eq $a "a" $b "b") -(assert_representable eq $b "b" $a "a") - -(; TODO: perhaps add assertions eventually for document-level representability? -;; flags -(witx $a - (typename $a (flags (@witx bitflags u8) $b $c))) -(witx $b - (typename $b (flags (@witx bitflags u8) $b $c $d))) - -(assert_representable noteq $b "b" $a "a") -(assert_representable superset $a "a" $b "b") - -(witx $c - (typename $c (flags (@witx bitflags u8) $b $e))) -(assert_representable noteq $a "a" $c "c") -(assert_representable noteq $c "c" $a "a") - -(witx $d - (typename $d (flags (@witx bitflags u16) $b $c))) -(assert_representable noteq $a "a" $d "d") -(assert_representable superset $d "d" $a "a") -(assert_representable superset $d "d" $b "b") -;) - -;; enums -(witx $a - (typename $a (enum $b $c))) -(witx $b - (typename $b (enum $b $c $d))) -(assert_representable superset $a "a" $b "b") -(assert_representable noteq $b "b" $a "a") - -(witx $c - (typename $c (enum (@witx tag u16) $b $c))) -(assert_representable superset $c "c" $a "a") -(assert_representable superset $c "c" $b "b") - -;; unions -(witx $a - (typename $tag (enum $b $c)) - (typename $a (union (@witx tag $tag) u32 f32))) -(witx $b - (typename $tag (enum $b $c $d)) - (typename $b (union (@witx tag $tag) u32 f32 f64))) -(assert_representable superset $a "a" $b "b") -(assert_representable noteq $b "b" $a "a") - -(witx $c - (typename $tag (enum $b $c)) - (typename $c (variant (@witx tag $tag) (case $c f32) (case $b u32)))) -(assert_representable eq $a "a" $c "c") -(assert_representable eq $c "c" $a "a") -(assert_representable superset $c "c" $b "b") diff --git a/proposals/filesystem/tools/witx/tests/witxt/shorthand.witxt b/proposals/filesystem/tools/witx/tests/witxt/shorthand.witxt deleted file mode 100644 index 960615f3c..000000000 --- a/proposals/filesystem/tools/witx/tests/witxt/shorthand.witxt +++ /dev/null @@ -1,59 +0,0 @@ -(witx $a - (typename $a bool)) -(witx $b - (typename $a (variant (case $false) (case $true)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (expected (error)))) -(witx $b - (typename $a (variant (case $ok) (case $err)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (expected (error u32)))) -(witx $b - (typename $a (variant (case $ok) (case $err u32)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (expected u32 (error)))) -(witx $b - (typename $a (variant (case $ok u32) (case $err)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (expected u32 (error u64)))) -(witx $b - (typename $a (variant (case $ok u32) (case $err u64)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (flags $a $b))) -(witx $b - (typename $a (record (field $a bool) (field $b bool)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (enum $a $b))) -(witx $b - (typename $a (variant (case $a) (case $b)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a string)) -(witx $b - (typename $a (list char))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (tuple u32 u64))) -(witx $b - (typename $a (record (field $0 u32) (field $1 u64)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (union u32 u64))) -(witx $b - (typename $a (variant (case $0 u32) (case $1 u64)))) -(assert_representable eq $a "a" $b "a") diff --git a/proposals/filesystem/tools/witx/tests/witxt/simple.witxt b/proposals/filesystem/tools/witx/tests/witxt/simple.witxt deleted file mode 100644 index af2403043..000000000 --- a/proposals/filesystem/tools/witx/tests/witxt/simple.witxt +++ /dev/null @@ -1,12 +0,0 @@ -(witx) - -(witx - (typename $x u32) -) - -(assert_invalid - (witx - (typename $x u32) - (typename $x u32) - ) - "Redefinition of name `x`") diff --git a/proposals/filesystem/tools/witx/tests/witxt/union.witxt b/proposals/filesystem/tools/witx/tests/witxt/union.witxt deleted file mode 100644 index 92be3dcd9..000000000 --- a/proposals/filesystem/tools/witx/tests/witxt/union.witxt +++ /dev/null @@ -1,97 +0,0 @@ - -(witx - (typename $u (union u8)) -) -(witx - (typename $tag (enum (@witx tag u8) $c)) - (typename $u (union (@witx tag $tag) u8)) -) - -(witx - (typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $a) (case $b u16))) -) - -(witx - (typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $a) (case $b))) -) - - -(witx - (typename $u - (union - u8 - u16 - u32 - u64 - s8 - s16 - s32 - s64 - f32 - f64 - (@witx usize) - (@witx char8) - ) - ) -) - -(assert_invalid - (witx (typename $u (union (@witx tag $tag) u8 u16))) - "Unknown name `tag`" -) - -(assert_invalid - (witx - (typename $tag string) - (typename $u (union (@witx tag $tag) u8 u16)) - ) - "Wrong kind of name `tag`: expected enum or builtin, got list" -) - -(assert_invalid - (witx - (typename $tag (enum $c)) - (typename $u (variant (@witx tag $tag) (case $b u8))) - ) - "Invalid union field `b`: does not correspond to variant in tag `tag`" -) - -(assert_invalid - (witx - (typename $tag (enum $c)) - (typename $u (union (@witx tag $tag) f32 u8)) - ) - "Union expected 1 variants, found 2" -) - -(assert_invalid - (witx - (typename $tag (enum $c $d)) - (typename $u (union (@witx tag $tag) f32)) - ) - "Union expected 2 variants, found 1" -) - -(witx $d1 - (typename $tag (enum $a $b)) - (typename $u (union (@witx tag $tag) u8 u16)) -) - -(witx $d2 - (typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $b u16) (case $a u8))) -) - -;; These two unions should be represented the same: -(assert_representable eq $d1 "u" $d2 "u") -(assert_representable eq $d2 "u" $d1 "u") - -;; Tag order doesnt matter for validation, but does for rep equality -(witx $d3 - (typename $tag (enum $b $a)) - (typename $u (union (@witx tag $tag) u16 u8)) -) - -(assert_representable noteq $d3 "u" $d1 "u") diff --git a/proposals/filesystem/tools/witx/tests/witxt/wasi.witxt b/proposals/filesystem/tools/witx/tests/witxt/wasi.witxt deleted file mode 100644 index f654a7ee3..000000000 --- a/proposals/filesystem/tools/witx/tests/witxt/wasi.witxt +++ /dev/null @@ -1,26 +0,0 @@ -;; Ensure that all current witx definitions in this repository load, parse, -;; roundtrip, and are documentable. - -(witx - (load "../../../../phases/old/snapshot_0/witx/wasi_unstable.witx")) -(witx - (load "../../../../phases/snapshot/witx/wasi_snapshot_preview1.witx")) - -(witx - (load - "../../../../phases/ephemeral/witx/wasi_ephemeral_args.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_clock.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_environ.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_fd.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_path.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_poll.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_proc.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_random.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_sched.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_sock.witx" - ) -) -;; should be singularly-loadable as well -(witx - (load - "../../../../phases/ephemeral/witx/wasi_ephemeral_fd.witx")) From 527e45e1b2949528ee691ea00d1b67750ff0f63b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 22 Nov 2021 13:32:41 -0800 Subject: [PATCH 0921/1772] Port the wasi-filesystem API to the new wai format. #35 This makes a number of changes, to make use of interface-types features such as expected, variant types, and resources. The change to use resources in particular means that filesystem functions are now methods of the descriptor resource. Since this means renaming everything, take this opportunity to introduce a new naming conventions, with _at being used for functions that take dirfd+path arguments. This also eliminates the rights concept what was present in earlier versions of WASI, has has discussed in #31. This required adding new flags to open_at, so while here, this also adds basic chmod-like support, as discussed in #33. And, this removes support for readdir seeking (seekdir/telldir), as discussed in #7. And it adds a fifo file type and a more general socket type, as discussed in #4. --- proposals/filesystem/README.md | 110 ++ proposals/filesystem/test/README.md | 11 + proposals/filesystem/wasi-filesystem.abi.md | 1121 +++++++++++++++++++ proposals/filesystem/wasi-filesystem.wai.md | 815 ++++++++++++++ 4 files changed, 2057 insertions(+) create mode 100644 proposals/filesystem/README.md create mode 100644 proposals/filesystem/test/README.md create mode 100644 proposals/filesystem/wasi-filesystem.abi.md create mode 100644 proposals/filesystem/wasi-filesystem.wai.md diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md new file mode 100644 index 000000000..fa5687731 --- /dev/null +++ b/proposals/filesystem/README.md @@ -0,0 +1,110 @@ +# [Example WASI proposal] + +This template can be used to start a new proposal, which can then be proposed in the WASI Subgroup meetings. + +The sections below are recommended. However, every proposal is different, and the community can help you flesh out the proposal, so don't block on having something filled in for each one of them. + +Thank you to the W3C Privacy CG for the [inspiration](https://github.com/privacycg/template)! + +# [Title] + +A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. + +### Current Phase + +[Fill in the current phase, e.g. Phase 1] + +### Champions + +- [Champion 1] +- [Champion 2] +- [etc.] + +### Phase 4 Advancement Criteria + +TODO before entering Phase 2. + +## Table of Contents [if the explainer is longer than one printed page] + +- [Introduction](#introduction) +- [Goals [or Motivating Use Cases, or Scenarios]](#goals-or-motivating-use-cases-or-scenarios) +- [Non-goals](#non-goals) +- [API walk-through](#api-walk-through) + - [Use case 1](#use-case-1) + - [Use case 2](#use-case-2) +- [Detailed design discussion](#detailed-design-discussion) + - [[Tricky design choice 1]](#tricky-design-choice-1) + - [[Tricky design choice 2]](#tricky-design-choice-2) +- [Considered alternatives](#considered-alternatives) + - [[Alternative 1]](#alternative-1) + - [[Alternative 2]](#alternative-2) +- [Stakeholder Interest & Feedback](#stakeholder-interest--feedback) +- [References & acknowledgements](#references--acknowledgements) + +### Introduction + +[The "executive summary" or "abstract". Explain in a few sentences what the goals of the project are, and a brief overview of how the solution works. This should be no more than 1-2 paragraphs.] + +### Goals [or Motivating Use Cases, or Scenarios] + +[What is the end-user need which this project aims to address?] + +### Non-goals + +[If there are "adjacent" goals which may appear to be in scope but aren't, enumerate them here. This section may be fleshed out as your design progresses and you encounter necessary technical and other trade-offs.] + +### API walk-through + +[Walk through of how someone would use this API.] + +#### [Use case 1] + +[Provide example code snippets and diagrams explaining how the API would be used to solve the given problem] + +#### [Use case 2] + +[etc.] + +### Detailed design discussion + +[This section should mostly refer to the .wai.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] + +#### [Tricky design choice #1] + +[Talk through the tradeoffs in coming to the specific design point you want to make.] + +``` +// Illustrated with example code. +``` + +[This may be an open question, in which case you should link to any active discussion threads.] + +#### [Tricky design choice 2] + +[etc.] + +### Considered alternatives + +[This section is not required if you already covered considered alternatives in the design discussion above.] + +#### [Alternative 1] + +[Describe an alternative which was considered, and why you decided against it.] + +#### [Alternative 2] + +[etc.] + +### Stakeholder Interest & Feedback + +TODO before entering Phase 3. + +[This should include a list of implementers who have expressed interest in implementing the proposal] + +### References & acknowledgements + +Many thanks for valuable feedback and advice from: + +- [Person 1] +- [Person 2] +- [etc.] diff --git a/proposals/filesystem/test/README.md b/proposals/filesystem/test/README.md new file mode 100644 index 000000000..c274acd9d --- /dev/null +++ b/proposals/filesystem/test/README.md @@ -0,0 +1,11 @@ +# Testing guidelines + +TK fill in testing guidelines + +## Installing the tools + +TK fill in instructions + +## Running the tests + +TK fill in instructions diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md new file mode 100644 index 000000000..80a6f381f --- /dev/null +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -0,0 +1,1121 @@ +# Types + +## `size`: `u32` + + Size of a range of bytes in memory. + +Size: 4, Alignment: 4 + +## `filesize`: `u64` + + Non-negative file size or length of a region within a file. + +Size: 8, Alignment: 8 + +## `filedelta`: `s64` + + Relative offset within a file. + +Size: 8, Alignment: 8 + +## `timestamp`: `u64` + + Timestamp in nanoseconds. + + TODO: wasi-clocks is moving to seconds+nanoseconds. + +Size: 8, Alignment: 8 + +## `info`: record + + Information associated with a descriptor. + + Note: This was called `fdstat` in earlier versions of WASI. + +Size: 2, Alignment: 1 + +### Record Fields + +- [`type`](#info.type): [`type`](#type) + + The type of filesystem object referenced by a descriptor. + +- [`flags`](#info.flags): [`flags`](#flags) + + Flags associated with a descriptor. + +## `type`: variant + + The type of a filesystem object referenced by a descriptor. + + Note: This was called `filetype` in earlier versions of WASI. + +Size: 1, Alignment: 1 + +### Variant Cases + +- [`unknown`](#type.unknown) + + The type of the descriptor or file is unknown or is different from + any of the other types specified. + +- [`block_device`](#type.block_device) + + The descriptor refers to a block device inode. + +- [`character_device`](#type.character_device) + + The descriptor refers to a character device inode. + +- [`directory`](#type.directory) + + The descriptor refers to a directory inode. + +- [`fifo`](#type.fifo) + + The descriptor refers to a named pipe. + +- [`symbolic_link`](#type.symbolic_link) + + The file refers to a symbolic link inode. + +- [`regular_file`](#type.regular_file) + + The descriptor refers to a regular file inode. + +- [`socket`](#type.socket) + + The descriptor refers to a socket. + +## `flags`: record + + Descriptor flags. + + Note: This was called `fdflags` in earlier versions of WASI. + +Size: 1, Alignment: 1 + +### Record Fields + +- [`read`](#flags.read): `bool` + + Read mode: Data can be read. +Bit: 0 + +- [`write`](#flags.write): `bool` + + Write mode: Data can be written to. +Bit: 1 + +- [`append`](#flags.append): `bool` + + Append mode: Data written to the file is always appended to the file's + end. +Bit: 2 + +- [`dsync`](#flags.dsync): `bool` + + Write according to synchronized I/O data integrity completion. Only the + data stored in the file is synchronized. +Bit: 3 + +- [`nonblock`](#flags.nonblock): `bool` + + Non-blocking mode. +Bit: 4 + +- [`rsync`](#flags.rsync): `bool` + + Synchronized read I/O operations. +Bit: 5 + +- [`sync`](#flags.sync): `bool` + + Write according to synchronized I/O file integrity completion. In + addition to synchronizing the data stored in the file, the + implementation may also synchronously update the file's metadata. +Bit: 6 + +## `stat`: record + + File attributes. + + Note: This was called `filestat` in earlier versions of WASI. + +Size: 64, Alignment: 8 + +### Record Fields + +- [`dev`](#stat.dev): [`device`](#device) + + Device ID of device containing the file. + +- [`ino`](#stat.ino): [`inode`](#inode) + + File serial number. + +- [`type`](#stat.type): [`type`](#type) + + File type. + +- [`nlink`](#stat.nlink): [`linkcount`](#linkcount) + + Number of hard links to the file. + +- [`size`](#stat.size): [`filesize`](#filesize) + + For regular files, the file size in bytes. For symbolic links, the length + in bytes of the pathname contained in the symbolic link. + +- [`atim`](#stat.atim): [`timestamp`](#timestamp) + + Last data access timestamp. + +- [`mtim`](#stat.mtim): [`timestamp`](#timestamp) + + Last data modification timestamp. + +- [`ctim`](#stat.ctim): [`timestamp`](#timestamp) + + Last file status change timestamp. + +## `lookupflags`: record + + Flags determining the method of how paths are resolved. + +Size: 1, Alignment: 1 + +### Record Fields + +- [`symlink_follow`](#lookupflags.symlink_follow): `bool` + + As long as the resolved path corresponds to a symbolic link, it is expanded. +Bit: 0 + +## `oflags`: record + + Open flags used by `open_at`. + +Size: 1, Alignment: 1 + +### Record Fields + +- [`nofollow`](#oflags.nofollow): `bool` + + Fail if path names an existing symbolic link. +Bit: 0 + +- [`creat`](#oflags.creat): `bool` + + Create file if it does not exist. +Bit: 1 + +- [`directory`](#oflags.directory): `bool` + + Fail if not a directory. +Bit: 2 + +- [`excl`](#oflags.excl): `bool` + + Fail if file already exists. +Bit: 3 + +- [`trunc`](#oflags.trunc): `bool` + + Truncate file to size 0. +Bit: 4 + +## `mode`: record + + Permissions mode used by `open_at`, `change_permissions_at`, and similar. + +Size: 1, Alignment: 1 + +### Record Fields + +- [`readable`](#mode.readable): `bool` + + True if the resource is considered readable by the containing + filesystem. +Bit: 0 + +- [`writeable`](#mode.writeable): `bool` + + True if the resource is considered writeable by the containing + filesystem. +Bit: 1 + +- [`executable`](#mode.executable): `bool` + + True if the resource is considered executable by the containing + filesystem. This does not apply to directories. +Bit: 2 + +## `linkcount`: `u64` + + Number of hard links to an inode. + +Size: 8, Alignment: 8 + +## `device`: `u64` + + Identifier for a device containing a file system. Can be used in combination + with `inode` to uniquely identify a file or directory in the filesystem. + +Size: 8, Alignment: 8 + +## `inode`: `u64` + + +Size: 8, Alignment: 8 + +## `new_timestamp`: variant + + When setting a timestamp, this gives the value to set it to. + +Size: 16, Alignment: 8 + +### Variant Cases + +- [`no_change`](#new_timestamp.no_change) + + Leave the timestamp set to its previous value. + +- [`now`](#new_timestamp.now) + + Set the timestamp to the current time of the system clock associated + with the filesystem. + +- [`timestamp`](#new_timestamp.timestamp): [`timestamp`](#timestamp) + + Set the timestamp to the given value. + +## `dirent`: record + + A directory entry. + +Size: 16, Alignment: 8 + +### Record Fields + +- [`ino`](#dirent.ino): [`inode`](#inode) + + The serial number of the file referred to by this directory entry. + +- [`namelen`](#dirent.namelen): [`size`](#size) + + The length of the name of the directory entry. + +- [`type`](#dirent.type): [`type`](#type) + + The type of the file referred to by this directory entry. + +## `errno`: variant + + Error codes returned by functions. + Not all of these error codes are returned by the functions provided by this + API; some are used in higher-level library layers, and others are provided + merely for alignment with POSIX. + +Size: 1, Alignment: 1 + +### Variant Cases + +- [`success`](#errno.success) + + No error occurred. System call completed successfully. + +- [`toobig`](#errno.toobig) + + Argument list too long. This is similar to `E2BIG` in POSIX. + +- [`access`](#errno.access) + + Permission denied. + +- [`addrinuse`](#errno.addrinuse) + + Address in use. + +- [`addrnotavail`](#errno.addrnotavail) + + Address not available. + +- [`afnosupport`](#errno.afnosupport) + + Address family not supported. + +- [`again`](#errno.again) + + Resource unavailable, or operation would block. + +- [`already`](#errno.already) + + Connection already in progress. + +- [`badmsg`](#errno.badmsg) + + Bad message. + +- [`busy`](#errno.busy) + + Device or resource busy. + +- [`canceled`](#errno.canceled) + + Operation canceled. + +- [`child`](#errno.child) + + No child processes. + +- [`connaborted`](#errno.connaborted) + + Connection aborted. + +- [`connrefused`](#errno.connrefused) + + Connection refused. + +- [`connreset`](#errno.connreset) + + Connection reset. + +- [`deadlk`](#errno.deadlk) + + Resource deadlock would occur. + +- [`destaddrreq`](#errno.destaddrreq) + + Destination address required. + +- [`dom`](#errno.dom) + + Mathematics argument out of domain of function. + +- [`dquot`](#errno.dquot) + + Reserved. + +- [`exist`](#errno.exist) + + File exists. + +- [`fault`](#errno.fault) + + Bad address. + +- [`fbig`](#errno.fbig) + + File too large. + +- [`hostunreach`](#errno.hostunreach) + + Host is unreachable. + +- [`idrm`](#errno.idrm) + + Identifier removed. + +- [`ilseq`](#errno.ilseq) + + Illegal byte sequence. + +- [`inprogress`](#errno.inprogress) + + Operation in progress. + +- [`intr`](#errno.intr) + + Interrupted function. + +- [`inval`](#errno.inval) + + Invalid argument. + +- [`io`](#errno.io) + + I/O error. + +- [`isconn`](#errno.isconn) + + Socket is connected. + +- [`isdir`](#errno.isdir) + + Is a directory. + +- [`loop`](#errno.loop) + + Too many levels of symbolic links. + +- [`mfile`](#errno.mfile) + + File descriptor value too large. + +- [`mlink`](#errno.mlink) + + Too many links. + +- [`msgsize`](#errno.msgsize) + + Message too large. + +- [`multihop`](#errno.multihop) + + Reserved. + +- [`nametoolong`](#errno.nametoolong) + + Filename too long. + +- [`netdown`](#errno.netdown) + + Network is down. + +- [`netreset`](#errno.netreset) + + Connection aborted by network. + +- [`netunreach`](#errno.netunreach) + + Network unreachable. + +- [`nfile`](#errno.nfile) + + Too many files open in system. + +- [`nobufs`](#errno.nobufs) + + No buffer space available. + +- [`nodev`](#errno.nodev) + + No such device. + +- [`noent`](#errno.noent) + + No such file or directory. + +- [`noexec`](#errno.noexec) + + Executable file format error. + +- [`nolck`](#errno.nolck) + + No locks available. + +- [`nolink`](#errno.nolink) + + Reserved. + +- [`nomem`](#errno.nomem) + + Not enough space. + +- [`nomsg`](#errno.nomsg) + + No message of the desired type. + +- [`noprotoopt`](#errno.noprotoopt) + + Protocol not available. + +- [`nospc`](#errno.nospc) + + No space left on device. + +- [`nosys`](#errno.nosys) + + Function not supported. + +- [`notconn`](#errno.notconn) + + The socket is not connected. + +- [`notdir`](#errno.notdir) + + Not a directory or a symbolic link to a directory. + +- [`notempty`](#errno.notempty) + + Directory not empty. + +- [`notrecoverable`](#errno.notrecoverable) + + State not recoverable. + +- [`notsock`](#errno.notsock) + + Not a socket. + +- [`notsup`](#errno.notsup) + + Not supported, or operation not supported on socket. + +- [`notty`](#errno.notty) + + Inappropriate I/O control operation. + +- [`nxio`](#errno.nxio) + + No such device or address. + +- [`overflow`](#errno.overflow) + + Value too large to be stored in data type. + +- [`ownerdead`](#errno.ownerdead) + + Previous owner died. + +- [`perm`](#errno.perm) + + Operation not permitted. + +- [`pipe`](#errno.pipe) + + Broken pipe. + +- [`proto`](#errno.proto) + + Protocol error. + +- [`protonosupport`](#errno.protonosupport) + + Protocol not supported. + +- [`prototype`](#errno.prototype) + + Protocol wrong type for socket. + +- [`range`](#errno.range) + + Result too large. + +- [`rofs`](#errno.rofs) + + Read-only file system. + +- [`spipe`](#errno.spipe) + + Invalid seek. + +- [`srch`](#errno.srch) + + No such process. + +- [`stale`](#errno.stale) + + Reserved. + +- [`timedout`](#errno.timedout) + + Connection timed out. + +- [`txtbsy`](#errno.txtbsy) + + Text file busy. + +- [`xdev`](#errno.xdev) + + Cross-device link. + +- [`notcapable`](#errno.notcapable) + + Extension: Capabilities insufficient. + +## `advice`: variant + + File or memory access pattern advisory information. + +Size: 1, Alignment: 1 + +### Variant Cases + +- [`normal`](#advice.normal) + + The application has no advice to give on its behavior with respect to the specified data. + +- [`sequential`](#advice.sequential) + + The application expects to access the specified data sequentially from lower offsets to higher offsets. + +- [`random`](#advice.random) + + The application expects to access the specified data in a random order. + +- [`willneed`](#advice.willneed) + + The application expects to access the specified data in the near future. + +- [`dontneed`](#advice.dontneed) + + The application expects that it will not access the specified data in the near future. + +- [`noreuse`](#advice.noreuse) + + The application expects to access the specified data once and then not reuse it thereafter. + +## `seek_from`: variant + + The position relative to which to set the offset of the descriptor. + +Size: 16, Alignment: 8 + +### Variant Cases + +- [`set`](#seek_from.set): [`filesize`](#filesize) + + Seek relative to start-of-file. + +- [`cur`](#seek_from.cur): [`filedelta`](#filedelta) + + Seek relative to current position. + +- [`end`](#seek_from.end): [`filesize`](#filesize) + + Seek relative to end-of-file. + +# Functions + +---- + +#### `descriptor::fadvise` + + Provide file advisory information on a descriptor. + + This is similar to `posix_fadvise` in POSIX. +##### Params + +- `self`: handle +- `offset`: `u64` +- `len`: `u64` +- `advice`: [`advice`](#advice) +##### Results + +- ``: expected<_, [`errno`](#errno)> + +---- + +#### `descriptor::fallocate` + + Force the allocation of space in a file. + + Note: This is similar to `posix_fallocate` in POSIX. +##### Params + +- `self`: handle +- `offset`: [`filesize`](#filesize) +- `len`: [`filesize`](#filesize) +##### Results + +- ``: expected<_, [`errno`](#errno)> + +---- + +#### `descriptor::datasync` + + Synchronize the data of a file to disk. + + Note: This is similar to `fdatasync` in POSIX. +##### Params + +- `self`: handle +##### Results + +- ``: expected<_, [`errno`](#errno)> + +---- + +#### `descriptor::info` + + Get information associated with a descriptor. + + Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well + as additional fields. + + Note: This was called `fdstat_get` in earlier versions of WASI. +##### Params + +- `self`: handle +##### Results + +- ``: expected<[`info`](#info), [`errno`](#errno)> + +---- + +#### `descriptor::set_size` + + Adjust the size of an open file. If this increases the file's size, the + extra bytes are filled with zeros. + + Note: This was called `fd_filestat_set_size` in earlier versions of WASI. +##### Params + +- `self`: handle +- `size`: [`filesize`](#filesize) +##### Results + +- ``: expected<_, [`errno`](#errno)> + +---- + +#### `descriptor::set_times` + + Adjust the timestamps of an open file or directory. + + Note: This is similar to `futimens` in POSIX. + + Note: This was called `fd_filestat_set_times` in earlier versions of WASI. +##### Params + +- `self`: handle +- `atim`: [`new_timestamp`](#new_timestamp) +- `mtim`: [`new_timestamp`](#new_timestamp) +##### Results + +- ``: expected<_, [`errno`](#errno)> + +---- + +#### `descriptor::pread` + + Read from a descriptor, without using and updating the descriptor's offset. + + Note: This is similar to `pread` in POSIX. +##### Params + +- `self`: handle +- `buf`: push-buffer<`u8`> +- `offset`: [`filesize`](#filesize) +##### Results + +- ``: expected<[`size`](#size), [`errno`](#errno)> + +---- + +#### `descriptor::pwrite` + + Write to a descriptor, without using and updating the descriptor's offset. + + Note: This is similar to `pwrite` in POSIX. +##### Params + +- `self`: handle +- `buf`: pull-buffer<`u8`> +- `offset`: [`filesize`](#filesize) +##### Results + +- ``: expected<[`size`](#size), [`errno`](#errno)> + +---- + +#### `descriptor::read` + + Read from a descriptor. + + The meaning of `read` on a directory is unspecified. + + Note: This is similar to `read` in POSIX. +##### Params + +- `self`: handle +- `buf`: push-buffer<`u8`> +##### Results + +- ``: expected<[`size`](#size), [`errno`](#errno)> + +---- + +#### `descriptor::readdir` + + Read directory entries from a directory. + + When successful, the contents of the output buffer consist of a sequence of + directory entries. Each directory entry consists of a `dirent` object, + followed by `dirent::d_namlen` bytes holding the name of the directory + entry. + + This function fills the output buffer as much as possible, potentially + truncating the last directory entry. This allows the caller to grow its + read buffer size in case it's too small to fit a single large directory + entry, or skip the oversized directory entry. +##### Params + +- `self`: handle +- `buf`: push-buffer<`u8`> +- `rewind`: `bool` +##### Results + +- ``: expected<[`size`](#size), [`errno`](#errno)> + +---- + +#### `descriptor::seek` + + Move the offset of a descriptor. + + The meaning of `seek` on a directory is unspecified. + + Note: This is similar to `lseek` in POSIX. +##### Params + +- `self`: handle +- `from`: [`seek_from`](#seek_from) +##### Results + +- ``: expected<[`filesize`](#filesize), [`errno`](#errno)> + +---- + +#### `descriptor::sync` + + Synchronize the data and metadata of a file to disk. + + Note: This is similar to `fsync` in POSIX. +##### Params + +- `self`: handle +##### Results + +- ``: expected<_, [`errno`](#errno)> + +---- + +#### `descriptor::tell` + + Return the current offset of a descriptor. + + Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. +##### Params + +- `self`: handle +##### Results + +- ``: expected<[`filesize`](#filesize), [`errno`](#errno)> + +---- + +#### `descriptor::write` + + Write to a descriptor. + + Note: This is similar to `write` in POSIX. +##### Params + +- `self`: handle +- `buf`: pull-buffer<`u8`> +##### Results + +- ``: expected<[`size`](#size), [`errno`](#errno)> + +---- + +#### `descriptor::create_directory_at` + + Create a directory. + + Note: This is similar to `mkdirat` in POSIX. +##### Params + +- `self`: handle +- `path`: `string` +##### Results + +- ``: expected<_, [`errno`](#errno)> + +---- + +#### `descriptor::stat_at` + + Return the attributes of a file or directory. + + Note: This is similar to `fstatat` in POSIX. + + Note: This was called `fd_filestat_get` in earlier versions of WASI. +##### Params + +- `self`: handle +- `lookupflags`: [`lookupflags`](#lookupflags) +- `path`: `string` +##### Results + +- ``: expected<[`stat`](#stat), [`errno`](#errno)> + +---- + +#### `descriptor::set_times_at` + + Adjust the timestamps of a file or directory. + + Note: This is similar to `utimensat` in POSIX. + + Note: This was called `path_filestat_set_times` in earlier versions of WASI. +##### Params + +- `self`: handle +- `lookupflags`: [`lookupflags`](#lookupflags) +- `path`: `string` +- `atim`: [`new_timestamp`](#new_timestamp) +- `mtim`: [`new_timestamp`](#new_timestamp) +##### Results + +- ``: expected<_, [`errno`](#errno)> + +---- + +#### `descriptor::link_at` + + Create a hard link. + + Note: This is similar to `linkat` in POSIX. +##### Params + +- `self`: handle +- `old_lookupflags`: [`lookupflags`](#lookupflags) +- `old_path`: `string` +- `new_descriptor`: handle +- `new_path`: `string` +##### Results + +- ``: expected<_, [`errno`](#errno)> + +---- + +#### `descriptor::open_at` + + Open a file or directory. + + The returned descriptor is not guaranteed to be the lowest-numbered + descriptor not currently open/ it is randomized to prevent applications + from depending on making assumptions about indexes, since this is + error-prone in multi-threaded contexts. The returned descriptor is + guaranteed to be less than 2**31. + + Note: This is similar to `openat` in POSIX. + + TODO: Re-evaluate `direflags` here. + TODO: Add a permissions mode. +##### Params + +- `self`: handle +- `lookupflags`: [`lookupflags`](#lookupflags) +- `path`: `string` +- `oflags`: [`oflags`](#oflags) +- `fdflags`: [`flags`](#flags) +- `mode`: [`mode`](#mode) +##### Results + +- ``: expected, [`errno`](#errno)> + +---- + +#### `descriptor::readlink_at` + + Read the contents of a symbolic link. + + Note: This is similar to `readlinkat` in POSIX. +##### Params + +- `self`: handle +- `path`: `string` +- `buf`: push-buffer<`u8`> +##### Results + +- ``: expected<[`size`](#size), [`errno`](#errno)> + +---- + +#### `descriptor::remove_directory_at` + + Remove a directory. + + Return `errno::notempty` if the directory is not empty. + + Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. +##### Params + +- `self`: handle +- `path`: `string` +##### Results + +- ``: expected<_, [`errno`](#errno)> + +---- + +#### `descriptor::rename_at` + + Rename a filesystem object. + + Note: This is similar to `renameat` in POSIX. +##### Params + +- `self`: handle +- `old_path`: `string` +- `new_descriptor`: handle +- `new_path`: `string` +##### Results + +- ``: expected<_, [`errno`](#errno)> + +---- + +#### `descriptor::symlink_at` + + Create a symbolic link. + + Note: This is similar to `symlinkat` in POSIX. +##### Params + +- `self`: handle +- `old_path`: `string` +- `new_path`: `string` +##### Results + +- ``: expected<_, [`errno`](#errno)> + +---- + +#### `descriptor::unlink_file_at` + + Unlink a filesystem object that is not a directory. + + Return `errno::isdir` if the path refers to a directory. + Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. +##### Params + +- `self`: handle +- `path`: `string` +##### Results + +- ``: expected<_, [`errno`](#errno)> + +---- + +#### `descriptor::change_file_permissions_at` + +##### Params + +- `self`: handle +- `lookupflags`: [`lookupflags`](#lookupflags) +- `path`: `string` +- `mode`: [`mode`](#mode) +##### Results + +- ``: expected<_, [`errno`](#errno)> + +---- + +#### `descriptor::change_directory_permissions_at` + +##### Params + +- `self`: handle +- `lookupflags`: [`lookupflags`](#lookupflags) +- `path`: `string` +- `mode`: [`mode`](#mode) +##### Results + +- ``: expected<_, [`errno`](#errno)> + diff --git a/proposals/filesystem/wasi-filesystem.wai.md b/proposals/filesystem/wasi-filesystem.wai.md new file mode 100644 index 000000000..5ce49a4e1 --- /dev/null +++ b/proposals/filesystem/wasi-filesystem.wai.md @@ -0,0 +1,815 @@ +# WASI Filesystem API + +WASI filesystem is a filesystem API primarily intended to let users run WASI +programs that access their files on their existing filesystems, without +significant overhead. + +It is intended to be roughly portable between Unix-family platforms and +Windows, though it does not hide many of the major differences. + +Paths are passed as interface-type `string`s, meaning they must consist of +a sequence of Unicode Scalar Values (USVs). Some filesystems may contain paths +which are not accessible by this API. + +Some of the content and ideas here are derived from +[CloudABI](https://github.com/NuxiNL/cloudabi). + +## `size` +```wai +/// Size of a range of bytes in memory. +type size = u32 +``` + +## `filesize` +```wai +/// Non-negative file size or length of a region within a file. +type filesize = u64 +``` + +## `filedelta` +```wai +/// Relative offset within a file. +type filedelta = s64 +``` + +## `timestamp` +```wai +/// Timestamp in nanoseconds. +/// +/// TODO: wasi-clocks is moving to seconds+nanoseconds. +type timestamp = u64 +``` + +## `info` +```wai +/// Information associated with a descriptor. +/// +/// Note: This was called `fdstat` in earlier versions of WASI. +record info { + /// The type of filesystem object referenced by a descriptor. + "type": "type", + /// Flags associated with a descriptor. + "flags": "flags", +} +``` + +## `type` +```wai +/// The type of a filesystem object referenced by a descriptor. +/// +/// Note: This was called `filetype` in earlier versions of WASI. +enum "type" { + /// The type of the descriptor or file is unknown or is different from + /// any of the other types specified. + unknown, + /// The descriptor refers to a block device inode. + block_device, + /// The descriptor refers to a character device inode. + character_device, + /// The descriptor refers to a directory inode. + directory, + /// The descriptor refers to a named pipe. + fifo, + /// The file refers to a symbolic link inode. + symbolic_link, + /// The descriptor refers to a regular file inode. + regular_file, + /// The descriptor refers to a socket. + socket, +} +``` + +## `flags` +```wai +/// Descriptor flags. +/// +/// Note: This was called `fdflags` in earlier versions of WASI. +flags "flags" { + /// Read mode: Data can be read. + read, + /// Write mode: Data can be written to. + write, + /// Append mode: Data written to the file is always appended to the file's + /// end. + append, + /// Write according to synchronized I/O data integrity completion. Only the + /// data stored in the file is synchronized. + dsync, + /// Non-blocking mode. + nonblock, + /// Synchronized read I/O operations. + rsync, + /// Write according to synchronized I/O file integrity completion. In + /// addition to synchronizing the data stored in the file, the + /// implementation may also synchronously update the file's metadata. + sync, +} +``` + +## `stat` +```wai +/// File attributes. +/// +/// Note: This was called `filestat` in earlier versions of WASI. +record stat { + /// Device ID of device containing the file. + dev: device, + /// File serial number. + ino: inode, + /// File type. + "type": "type", + /// Number of hard links to the file. + nlink: linkcount, + /// For regular files, the file size in bytes. For symbolic links, the length + /// in bytes of the pathname contained in the symbolic link. + size: filesize, + /// Last data access timestamp. + atim: timestamp, + /// Last data modification timestamp. + mtim: timestamp, + /// Last file status change timestamp. + ctim: timestamp, +} +``` + +## `lookupflags` +```wai +/// Flags determining the method of how paths are resolved. +flags lookupflags { + /// As long as the resolved path corresponds to a symbolic link, it is expanded. + symlink_follow, +} +``` + +## `oflags` +```wai +/// Open flags used by `open_at`. +flags oflags { + /// Fail if path names an existing symbolic link. + nofollow, + /// Create file if it does not exist. + creat, + /// Fail if not a directory. + directory, + /// Fail if file already exists. + excl, + /// Truncate file to size 0. + trunc, +} +``` + +## `mode` +```wai +/// Permissions mode used by `open_at`, `change_permissions_at`, and similar. +flags mode { + /// True if the resource is considered readable by the containing + /// filesystem. + readable, + /// True if the resource is considered writeable by the containing + /// filesystem. + writeable, + /// True if the resource is considered executable by the containing + /// filesystem. This does not apply to directories. + executable, +} +``` + +## `linkcount` +```wai +/// Number of hard links to an inode. +type linkcount = u64 +``` + +## `device` +```wai +/// Identifier for a device containing a file system. Can be used in combination +/// with `inode` to uniquely identify a file or directory in the filesystem. +type device = u64 +``` + +## `inode` +/// Filesystem object serial number that is unique within its file system. +```wai +type inode = u64 +``` + +## `new_timestamp` +```wai +/// When setting a timestamp, this gives the value to set it to. +variant new_timestamp { + /// Leave the timestamp set to its previous value. + no_change, + /// Set the timestamp to the current time of the system clock associated + /// with the filesystem. + now, + /// Set the timestamp to the given value. + timestamp(timestamp), +} +``` + +## `dirent` +```wai +/// A directory entry. +record dirent { + /// The serial number of the file referred to by this directory entry. + ino: inode, + /// The length of the name of the directory entry. + namelen: size, + /// The type of the file referred to by this directory entry. + "type": "type", +} +``` + +## `errno` +```wai +/// Error codes returned by functions. +/// Not all of these error codes are returned by the functions provided by this +/// API; some are used in higher-level library layers, and others are provided +/// merely for alignment with POSIX. +enum errno { + /// No error occurred. System call completed successfully. + success, + /// Argument list too long. This is similar to `E2BIG` in POSIX. + toobig, + /// Permission denied. + access, + /// Address in use. + addrinuse, + /// Address not available. + addrnotavail, + /// Address family not supported. + afnosupport, + /// Resource unavailable, or operation would block. + again, + /// Connection already in progress. + already, + /// Bad message. + badmsg, + /// Device or resource busy. + busy, + /// Operation canceled. + canceled, + /// No child processes. + child, + /// Connection aborted. + connaborted, + /// Connection refused. + connrefused, + /// Connection reset. + connreset, + /// Resource deadlock would occur. + deadlk, + /// Destination address required. + destaddrreq, + /// Mathematics argument out of domain of function. + dom, + /// Reserved. + dquot, + /// File exists. + exist, + /// Bad address. + fault, + /// File too large. + fbig, + /// Host is unreachable. + hostunreach, + /// Identifier removed. + idrm, + /// Illegal byte sequence. + ilseq, + /// Operation in progress. + inprogress, + /// Interrupted function. + intr, + /// Invalid argument. + inval, + /// I/O error. + io, + /// Socket is connected. + isconn, + /// Is a directory. + isdir, + /// Too many levels of symbolic links. + loop, + /// File descriptor value too large. + mfile, + /// Too many links. + mlink, + /// Message too large. + msgsize, + /// Reserved. + multihop, + /// Filename too long. + nametoolong, + /// Network is down. + netdown, + /// Connection aborted by network. + netreset, + /// Network unreachable. + netunreach, + /// Too many files open in system. + nfile, + /// No buffer space available. + nobufs, + /// No such device. + nodev, + /// No such file or directory. + noent, + /// Executable file format error. + noexec, + /// No locks available. + nolck, + /// Reserved. + nolink, + /// Not enough space. + nomem, + /// No message of the desired type. + nomsg, + /// Protocol not available. + noprotoopt, + /// No space left on device. + nospc, + /// Function not supported. + nosys, + /// The socket is not connected. + notconn, + /// Not a directory or a symbolic link to a directory. + notdir, + /// Directory not empty. + notempty, + /// State not recoverable. + notrecoverable, + /// Not a socket. + notsock, + /// Not supported, or operation not supported on socket. + notsup, + /// Inappropriate I/O control operation. + notty, + /// No such device or address. + nxio, + /// Value too large to be stored in data type. + overflow, + /// Previous owner died. + ownerdead, + /// Operation not permitted. + perm, + /// Broken pipe. + pipe, + /// Protocol error. + proto, + /// Protocol not supported. + protonosupport, + /// Protocol wrong type for socket. + prototype, + /// Result too large. + range, + /// Read-only file system. + rofs, + /// Invalid seek. + spipe, + /// No such process. + srch, + /// Reserved. + stale, + /// Connection timed out. + timedout, + /// Text file busy. + txtbsy, + /// Cross-device link. + xdev, + /// Extension: Capabilities insufficient. + notcapable, +} +``` + +## `advice` +```wai +/// File or memory access pattern advisory information. +enum advice { + /// The application has no advice to give on its behavior with respect to the specified data. + normal, + /// The application expects to access the specified data sequentially from lower offsets to higher offsets. + sequential, + /// The application expects to access the specified data in a random order. + random, + /// The application expects to access the specified data in the near future. + willneed, + /// The application expects that it will not access the specified data in the near future. + dontneed, + /// The application expects to access the specified data once and then not reuse it thereafter. + noreuse, +} +``` + +## `seek_from` +```wai +/// The position relative to which to set the offset of the descriptor. +variant seek_from { + /// Seek relative to start-of-file. + set(filesize), + /// Seek relative to current position. + cur(filedelta), + /// Seek relative to end-of-file. + end(filesize), +} +``` + +## `descriptor` +```wai +/// A descriptor is a reference to a filesystem object, which may be a file, +/// directory, named pipe, special file, or other object on which filesystem +/// calls may be made. +resource descriptor { +``` + +## `fadvise` +```wai +/// Provide file advisory information on a descriptor. +/// +/// This is similar to `posix_fadvise` in POSIX. +fadvise: function( + /// The offset within the file to which the advisory applies. + offset: u64, + /// The length of the region to which the advisory applies. + len: u64, + /// The advice. + advice: advice +) -> expected<_, errno> +``` + +## `fallocate` +```wai +/// Force the allocation of space in a file. +/// +/// Note: This is similar to `posix_fallocate` in POSIX. +fallocate: function( + /// The offset at which to start the allocation. + offset: filesize, + /// The length of the area that is allocated. + len: filesize +) -> expected<_, errno> +``` + +## `fdatasync` +```wai +/// Synchronize the data of a file to disk. +/// +/// Note: This is similar to `fdatasync` in POSIX. +datasync: function() -> expected<_, errno> +``` + +## `info` +```wai +/// Get information associated with a descriptor. +/// +/// Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well +/// as additional fields. +/// +/// Note: This was called `fdstat_get` in earlier versions of WASI. +info: function() -> expected +``` + +## `set_size` +```wai +/// Adjust the size of an open file. If this increases the file's size, the +/// extra bytes are filled with zeros. +/// +/// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. +set_size: function(size: filesize) -> expected<_, errno> +``` + +## `set_times` +```wai +/// Adjust the timestamps of an open file or directory. +/// +/// Note: This is similar to `futimens` in POSIX. +/// +/// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. +set_times: function( + /// The desired values of the data access timestamp. + atim: new_timestamp, + /// The desired values of the data modification timestamp. + mtim: new_timestamp, +) -> expected<_, errno> +``` + +## `pread` +```wai +/// Read from a descriptor, without using and updating the descriptor's offset. +/// +/// Note: This is similar to `pread` in POSIX. +pread: function( + /// Buffer to read into + buf: push-buffer, + /// The offset within the file at which to read. + offset: filesize, +) -> expected +``` + +## `pwrite` +```wai +/// Write to a descriptor, without using and updating the descriptor's offset. +/// +/// Note: This is similar to `pwrite` in POSIX. +pwrite: function( + /// Data to write + buf: pull-buffer, + /// The offset within the file at which to write. + offset: filesize, +) -> expected +``` + +## `read` +```wai +/// Read from a descriptor. +/// +/// The meaning of `read` on a directory is unspecified. +/// +/// Note: This is similar to `read` in POSIX. +read: function( + /// Where to read into + buf: push-buffer, +) -> expected +``` + +## `readdir` +```wai +/// Read directory entries from a directory. +/// +/// When successful, the contents of the output buffer consist of a sequence of +/// directory entries. Each directory entry consists of a `dirent` object, +/// followed by `dirent::d_namlen` bytes holding the name of the directory +/// entry. +// +/// This function fills the output buffer as much as possible, potentially +/// truncating the last directory entry. This allows the caller to grow its +/// read buffer size in case it's too small to fit a single large directory +/// entry, or skip the oversized directory entry. +readdir: function( + /// The buffer where directory entries are stored + /// + /// TODO: Ideally we should return directory entries as typed records. + buf: push-buffer, + /// If true, rewind the current position to the beginning before reading. + rewind: bool, +) -> ( + /// The number of bytes stored in the read buffer. If less than the size of + /// the read buffer, the end of the directory has been reached. + expected +) +``` + +## `seek` +```wai +/// Move the offset of a descriptor. +/// +/// The meaning of `seek` on a directory is unspecified. +/// +/// Note: This is similar to `lseek` in POSIX. +seek: function( + /// The method to compute the new offset. + "from": seek_from, +) -> ( + /// The new offset of the descriptor, relative to the start of the file. + expected +) +``` + +## `sync` +```wai +/// Synchronize the data and metadata of a file to disk. +/// +/// Note: This is similar to `fsync` in POSIX. +sync: function() -> expected<_, errno> +``` + +## `tell` +```wai +/// Return the current offset of a descriptor. +/// +/// Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. +tell: function() -> ( + /// The current offset of the descriptor, relative to the start of the file. + expected +) +``` + +## `write` +```wai +/// Write to a descriptor. +/// +/// Note: This is similar to `write` in POSIX. +write: function( + /// Data to write + buf: pull-buffer, +) -> expected +``` + +## `create_directory_at` +```wai +/// Create a directory. +/// +/// Note: This is similar to `mkdirat` in POSIX. +create_directory_at: function( + /// The relative path at which to create the directory. + path: string, +) -> expected<_, errno> +``` + +## `stat_at` +```wai +/// Return the attributes of a file or directory. +/// +/// Note: This is similar to `fstatat` in POSIX. +/// +/// Note: This was called `fd_filestat_get` in earlier versions of WASI. +stat_at: function( + /// Flags determining the method of how the path is resolved. + lookupflags: lookupflags, + /// The relative path of the file or directory to inspect. + path: string, +) -> ( + /// The buffer where the file's attributes are stored. + expected +) +``` + +## `set_times_at` +```wai +/// Adjust the timestamps of a file or directory. +/// +/// Note: This is similar to `utimensat` in POSIX. +/// +/// Note: This was called `path_filestat_set_times` in earlier versions of WASI. +set_times_at: function( + /// Flags determining the method of how the path is resolved. + lookupflags: lookupflags, + /// The relative path of the file or directory to operate on. + path: string, + /// The desired values of the data access timestamp. + atim: new_timestamp, + /// The desired values of the data modification timestamp. + mtim: new_timestamp, +) -> expected<_, errno> +``` + +## `link_at` +```wai +/// Create a hard link. +/// +/// Note: This is similar to `linkat` in POSIX. +link_at: function( + /// Flags determining the method of how the path is resolved. + old_lookupflags: lookupflags, + /// The relative source path from which to link. + old_path: string, + /// The base directory for `new_path`. + new_descriptor: handle descriptor, + /// The relative destination path at which to create the hard link. + new_path: string, +) -> expected<_, errno> +``` + +## `open_at` +```wai +/// Open a file or directory. +/// +/// The returned descriptor is not guaranteed to be the lowest-numbered +/// descriptor not currently open/ it is randomized to prevent applications +/// from depending on making assumptions about indexes, since this is +/// error-prone in multi-threaded contexts. The returned descriptor is +/// guaranteed to be less than 2**31. +/// +/// Note: This is similar to `openat` in POSIX. +/// +/// TODO: Re-evaluate `direflags` here. +/// TODO: Add a permissions mode. +open_at: function( + /// Flags determining the method of how the path is resolved. + lookupflags: lookupflags, + /// The relative path of the object to open. + path: string, + /// The method by which to open the file. + oflags: oflags, + /// Flags to use for the resulting descriptor. + fdflags: "flags", + /// Permissions to use when creating a new file. + mode: mode +) -> ( + /// The descriptor of the file that has been opened. + expected +) +``` + +## `readlink_at` +```wai +/// Read the contents of a symbolic link. +/// +/// Note: This is similar to `readlinkat` in POSIX. +readlink_at: function( + /// The relative path of the symbolic link from which to read. + path: string, + /// The buffer to which to write the contents of the symbolic link. + buf: push-buffer, +) -> ( + /// The number of bytes placed in the buffer. + expected +) +``` + +## `remove_directory_at` +```wai +/// Remove a directory. +/// +/// Return `errno::notempty` if the directory is not empty. +/// +/// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. +remove_directory_at: function( + /// The relative path to a directory to remove. + path: string, +) -> expected<_, errno> +``` + +## `rename_at` +```wai +/// Rename a filesystem object. +/// +/// Note: This is similar to `renameat` in POSIX. +rename_at: function( + /// The relative source path of the file or directory to rename. + old_path: string, + /// The base directory for `new_path`. + new_descriptor: handle descriptor, + /// The relative destination path to which to rename the file or directory. + new_path: string, +) -> expected<_, errno> +``` + +## `symlink_at` +```wai +/// Create a symbolic link. +/// +/// Note: This is similar to `symlinkat` in POSIX. +symlink_at: function( + /// The contents of the symbolic link. + old_path: string, + /// The relative destination path at which to create the symbolic link. + new_path: string, +) -> expected<_, errno> +``` + +## `unlink_file_at` +```wai +/// Unlink a filesystem object that is not a directory. +/// +/// Return `errno::isdir` if the path refers to a directory. +/// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. +unlink_file_at: function( + /// The relative path to a file to unlink. + path: string, +) -> expected<_, errno> +``` + +## `change_file_permissions_at` +/// Change the permissions of a filesystem object that is not a directory. +/// +/// Note that the ultimate meanings of these permissions is +/// filesystem-specific. +/// +/// Note: This is similar to `fchmodat` in POSIX. +```wai +change_file_permissions_at: function( + /// Flags determining the method of how the path is resolved. + lookupflags: lookupflags, + /// The relative path to operate on. + path: string, + /// The new permissions for the filesystem object. + mode: mode, +) -> expected<_, errno> +``` + +## `change_dir_permissions_at` +/// Change the permissions of a directory. +/// +/// Note that the ultimate meanings of these permissions is +/// filesystem-specific. +/// +/// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" +/// flag. `read` on a directory implies readability and searchability, and +/// `execute` is not valid for directories. +/// +/// Note: This is similar to `fchmodat` in POSIX. +```wai +change_directory_permissions_at: function( + /// Flags determining the method of how the path is resolved. + lookupflags: lookupflags, + /// The relative path to operate on. + path: string, + /// The new permissions for the directory. + mode: mode, +) -> expected<_, errno> +``` + +```wai +} +``` From 2e386c3c74d80bc992e5cf5c03dcc372f8c902b4 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Dec 2021 09:21:38 -0800 Subject: [PATCH 0922/1772] Rename `wai` to `wit`. --- proposals/filesystem/README.md | 2 +- ...lesystem.wai.md => wasi-filesystem.wit.md} | 94 +++++++++---------- 2 files changed, 48 insertions(+), 48 deletions(-) rename proposals/filesystem/{wasi-filesystem.wai.md => wasi-filesystem.wit.md} (98%) diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index fa5687731..e76604398 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -67,7 +67,7 @@ TODO before entering Phase 2. ### Detailed design discussion -[This section should mostly refer to the .wai.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] +[This section should mostly refer to the .wit.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] #### [Tricky design choice #1] diff --git a/proposals/filesystem/wasi-filesystem.wai.md b/proposals/filesystem/wasi-filesystem.wit.md similarity index 98% rename from proposals/filesystem/wasi-filesystem.wai.md rename to proposals/filesystem/wasi-filesystem.wit.md index 5ce49a4e1..282b630b0 100644 --- a/proposals/filesystem/wasi-filesystem.wai.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -15,25 +15,25 @@ Some of the content and ideas here are derived from [CloudABI](https://github.com/NuxiNL/cloudabi). ## `size` -```wai +```wit /// Size of a range of bytes in memory. type size = u32 ``` ## `filesize` -```wai +```wit /// Non-negative file size or length of a region within a file. type filesize = u64 ``` ## `filedelta` -```wai +```wit /// Relative offset within a file. type filedelta = s64 ``` ## `timestamp` -```wai +```wit /// Timestamp in nanoseconds. /// /// TODO: wasi-clocks is moving to seconds+nanoseconds. @@ -41,7 +41,7 @@ type timestamp = u64 ``` ## `info` -```wai +```wit /// Information associated with a descriptor. /// /// Note: This was called `fdstat` in earlier versions of WASI. @@ -54,7 +54,7 @@ record info { ``` ## `type` -```wai +```wit /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. @@ -80,7 +80,7 @@ enum "type" { ``` ## `flags` -```wai +```wit /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. @@ -107,7 +107,7 @@ flags "flags" { ``` ## `stat` -```wai +```wit /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. @@ -133,7 +133,7 @@ record stat { ``` ## `lookupflags` -```wai +```wit /// Flags determining the method of how paths are resolved. flags lookupflags { /// As long as the resolved path corresponds to a symbolic link, it is expanded. @@ -142,7 +142,7 @@ flags lookupflags { ``` ## `oflags` -```wai +```wit /// Open flags used by `open_at`. flags oflags { /// Fail if path names an existing symbolic link. @@ -159,7 +159,7 @@ flags oflags { ``` ## `mode` -```wai +```wit /// Permissions mode used by `open_at`, `change_permissions_at`, and similar. flags mode { /// True if the resource is considered readable by the containing @@ -175,13 +175,13 @@ flags mode { ``` ## `linkcount` -```wai +```wit /// Number of hard links to an inode. type linkcount = u64 ``` ## `device` -```wai +```wit /// Identifier for a device containing a file system. Can be used in combination /// with `inode` to uniquely identify a file or directory in the filesystem. type device = u64 @@ -189,12 +189,12 @@ type device = u64 ## `inode` /// Filesystem object serial number that is unique within its file system. -```wai +```wit type inode = u64 ``` ## `new_timestamp` -```wai +```wit /// When setting a timestamp, this gives the value to set it to. variant new_timestamp { /// Leave the timestamp set to its previous value. @@ -208,7 +208,7 @@ variant new_timestamp { ``` ## `dirent` -```wai +```wit /// A directory entry. record dirent { /// The serial number of the file referred to by this directory entry. @@ -221,7 +221,7 @@ record dirent { ``` ## `errno` -```wai +```wit /// Error codes returned by functions. /// Not all of these error codes are returned by the functions provided by this /// API; some are used in higher-level library layers, and others are provided @@ -383,7 +383,7 @@ enum errno { ``` ## `advice` -```wai +```wit /// File or memory access pattern advisory information. enum advice { /// The application has no advice to give on its behavior with respect to the specified data. @@ -402,7 +402,7 @@ enum advice { ``` ## `seek_from` -```wai +```wit /// The position relative to which to set the offset of the descriptor. variant seek_from { /// Seek relative to start-of-file. @@ -415,7 +415,7 @@ variant seek_from { ``` ## `descriptor` -```wai +```wit /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. @@ -423,7 +423,7 @@ resource descriptor { ``` ## `fadvise` -```wai +```wit /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. @@ -438,7 +438,7 @@ fadvise: function( ``` ## `fallocate` -```wai +```wit /// Force the allocation of space in a file. /// /// Note: This is similar to `posix_fallocate` in POSIX. @@ -451,7 +451,7 @@ fallocate: function( ``` ## `fdatasync` -```wai +```wit /// Synchronize the data of a file to disk. /// /// Note: This is similar to `fdatasync` in POSIX. @@ -459,7 +459,7 @@ datasync: function() -> expected<_, errno> ``` ## `info` -```wai +```wit /// Get information associated with a descriptor. /// /// Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well @@ -470,7 +470,7 @@ info: function() -> expected ``` ## `set_size` -```wai +```wit /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// @@ -479,7 +479,7 @@ set_size: function(size: filesize) -> expected<_, errno> ``` ## `set_times` -```wai +```wit /// Adjust the timestamps of an open file or directory. /// /// Note: This is similar to `futimens` in POSIX. @@ -494,7 +494,7 @@ set_times: function( ``` ## `pread` -```wai +```wit /// Read from a descriptor, without using and updating the descriptor's offset. /// /// Note: This is similar to `pread` in POSIX. @@ -507,7 +507,7 @@ pread: function( ``` ## `pwrite` -```wai +```wit /// Write to a descriptor, without using and updating the descriptor's offset. /// /// Note: This is similar to `pwrite` in POSIX. @@ -520,7 +520,7 @@ pwrite: function( ``` ## `read` -```wai +```wit /// Read from a descriptor. /// /// The meaning of `read` on a directory is unspecified. @@ -533,7 +533,7 @@ read: function( ``` ## `readdir` -```wai +```wit /// Read directory entries from a directory. /// /// When successful, the contents of the output buffer consist of a sequence of @@ -560,7 +560,7 @@ readdir: function( ``` ## `seek` -```wai +```wit /// Move the offset of a descriptor. /// /// The meaning of `seek` on a directory is unspecified. @@ -576,7 +576,7 @@ seek: function( ``` ## `sync` -```wai +```wit /// Synchronize the data and metadata of a file to disk. /// /// Note: This is similar to `fsync` in POSIX. @@ -584,7 +584,7 @@ sync: function() -> expected<_, errno> ``` ## `tell` -```wai +```wit /// Return the current offset of a descriptor. /// /// Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. @@ -595,7 +595,7 @@ tell: function() -> ( ``` ## `write` -```wai +```wit /// Write to a descriptor. /// /// Note: This is similar to `write` in POSIX. @@ -606,7 +606,7 @@ write: function( ``` ## `create_directory_at` -```wai +```wit /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. @@ -617,7 +617,7 @@ create_directory_at: function( ``` ## `stat_at` -```wai +```wit /// Return the attributes of a file or directory. /// /// Note: This is similar to `fstatat` in POSIX. @@ -635,7 +635,7 @@ stat_at: function( ``` ## `set_times_at` -```wai +```wit /// Adjust the timestamps of a file or directory. /// /// Note: This is similar to `utimensat` in POSIX. @@ -654,7 +654,7 @@ set_times_at: function( ``` ## `link_at` -```wai +```wit /// Create a hard link. /// /// Note: This is similar to `linkat` in POSIX. @@ -671,7 +671,7 @@ link_at: function( ``` ## `open_at` -```wai +```wit /// Open a file or directory. /// /// The returned descriptor is not guaranteed to be the lowest-numbered @@ -702,7 +702,7 @@ open_at: function( ``` ## `readlink_at` -```wai +```wit /// Read the contents of a symbolic link. /// /// Note: This is similar to `readlinkat` in POSIX. @@ -718,7 +718,7 @@ readlink_at: function( ``` ## `remove_directory_at` -```wai +```wit /// Remove a directory. /// /// Return `errno::notempty` if the directory is not empty. @@ -731,7 +731,7 @@ remove_directory_at: function( ``` ## `rename_at` -```wai +```wit /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. @@ -746,7 +746,7 @@ rename_at: function( ``` ## `symlink_at` -```wai +```wit /// Create a symbolic link. /// /// Note: This is similar to `symlinkat` in POSIX. @@ -759,7 +759,7 @@ symlink_at: function( ``` ## `unlink_file_at` -```wai +```wit /// Unlink a filesystem object that is not a directory. /// /// Return `errno::isdir` if the path refers to a directory. @@ -777,7 +777,7 @@ unlink_file_at: function( /// filesystem-specific. /// /// Note: This is similar to `fchmodat` in POSIX. -```wai +```wit change_file_permissions_at: function( /// Flags determining the method of how the path is resolved. lookupflags: lookupflags, @@ -799,7 +799,7 @@ change_file_permissions_at: function( /// `execute` is not valid for directories. /// /// Note: This is similar to `fchmodat` in POSIX. -```wai +```wit change_directory_permissions_at: function( /// Flags determining the method of how the path is resolved. lookupflags: lookupflags, @@ -810,6 +810,6 @@ change_directory_permissions_at: function( ) -> expected<_, errno> ``` -```wai +```wit } ``` From 0806441c82fc49ff90f7cd3cca49c6d73b3bb154 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Dec 2021 09:21:44 -0800 Subject: [PATCH 0923/1772] Port the github actions script from the template repo. --- proposals/filesystem/.github/workflows/main.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 proposals/filesystem/.github/workflows/main.yml diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml new file mode 100644 index 000000000..b33a451b8 --- /dev/null +++ b/proposals/filesystem/.github/workflows/main.yml @@ -0,0 +1,16 @@ +name: CI +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + abi-up-to-date: + name: Check ABI files are up-to-date + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: WebAssembly/wit-abi-up-to-date@v1 + with: + wit-abi-tag: wit-abi-0.1.0 From 0f84ee201bdd1a59ff30f2d78032c85fa3f8a3c4 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Dec 2021 09:21:16 -0800 Subject: [PATCH 0924/1772] Remove finished TODO comments. --- proposals/filesystem/wasi-filesystem.wit.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 282b630b0..94439d9b1 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -681,9 +681,6 @@ link_at: function( /// guaranteed to be less than 2**31. /// /// Note: This is similar to `openat` in POSIX. -/// -/// TODO: Re-evaluate `direflags` here. -/// TODO: Add a permissions mode. open_at: function( /// Flags determining the method of how the path is resolved. lookupflags: lookupflags, From d1e9406a34804e6035f0629ff41e1279dc3e5087 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Dec 2021 13:19:14 -0800 Subject: [PATCH 0925/1772] Rename `lookupflags` to `atflags`. --- proposals/filesystem/wasi-filesystem.abi.md | 16 ++++++++-------- proposals/filesystem/wasi-filesystem.wit.md | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index 80a6f381f..b935239a8 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -179,7 +179,7 @@ Size: 64, Alignment: 8 Last file status change timestamp. -## `lookupflags`: record +## `atflags`: record Flags determining the method of how paths are resolved. @@ -187,7 +187,7 @@ Size: 1, Alignment: 1 ### Record Fields -- [`symlink_follow`](#lookupflags.symlink_follow): `bool` +- [`symlink_follow`](#atflags.symlink_follow): `bool` As long as the resolved path corresponds to a symbolic link, it is expanded. Bit: 0 @@ -937,7 +937,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `lookupflags`: [`lookupflags`](#lookupflags) +- `atflags`: [`atflags`](#atflags) - `path`: `string` ##### Results @@ -955,7 +955,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `lookupflags`: [`lookupflags`](#lookupflags) +- `atflags`: [`atflags`](#atflags) - `path`: `string` - `atim`: [`new_timestamp`](#new_timestamp) - `mtim`: [`new_timestamp`](#new_timestamp) @@ -973,7 +973,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `old_lookupflags`: [`lookupflags`](#lookupflags) +- `old_atflags`: [`atflags`](#atflags) - `old_path`: `string` - `new_descriptor`: handle - `new_path`: `string` @@ -1000,7 +1000,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `lookupflags`: [`lookupflags`](#lookupflags) +- `atflags`: [`atflags`](#atflags) - `path`: `string` - `oflags`: [`oflags`](#oflags) - `fdflags`: [`flags`](#flags) @@ -1098,7 +1098,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `lookupflags`: [`lookupflags`](#lookupflags) +- `atflags`: [`atflags`](#atflags) - `path`: `string` - `mode`: [`mode`](#mode) ##### Results @@ -1112,7 +1112,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `lookupflags`: [`lookupflags`](#lookupflags) +- `atflags`: [`atflags`](#atflags) - `path`: `string` - `mode`: [`mode`](#mode) ##### Results diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 94439d9b1..4f73a85f3 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -132,10 +132,10 @@ record stat { } ``` -## `lookupflags` +## `atflags` ```wit /// Flags determining the method of how paths are resolved. -flags lookupflags { +flags atflags { /// As long as the resolved path corresponds to a symbolic link, it is expanded. symlink_follow, } @@ -625,7 +625,7 @@ create_directory_at: function( /// Note: This was called `fd_filestat_get` in earlier versions of WASI. stat_at: function( /// Flags determining the method of how the path is resolved. - lookupflags: lookupflags, + atflags: atflags, /// The relative path of the file or directory to inspect. path: string, ) -> ( @@ -643,7 +643,7 @@ stat_at: function( /// Note: This was called `path_filestat_set_times` in earlier versions of WASI. set_times_at: function( /// Flags determining the method of how the path is resolved. - lookupflags: lookupflags, + atflags: atflags, /// The relative path of the file or directory to operate on. path: string, /// The desired values of the data access timestamp. @@ -660,7 +660,7 @@ set_times_at: function( /// Note: This is similar to `linkat` in POSIX. link_at: function( /// Flags determining the method of how the path is resolved. - old_lookupflags: lookupflags, + old_atflags: atflags, /// The relative source path from which to link. old_path: string, /// The base directory for `new_path`. @@ -683,7 +683,7 @@ link_at: function( /// Note: This is similar to `openat` in POSIX. open_at: function( /// Flags determining the method of how the path is resolved. - lookupflags: lookupflags, + atflags: atflags, /// The relative path of the object to open. path: string, /// The method by which to open the file. @@ -777,7 +777,7 @@ unlink_file_at: function( ```wit change_file_permissions_at: function( /// Flags determining the method of how the path is resolved. - lookupflags: lookupflags, + atflags: atflags, /// The relative path to operate on. path: string, /// The new permissions for the filesystem object. @@ -799,7 +799,7 @@ change_file_permissions_at: function( ```wit change_directory_permissions_at: function( /// Flags determining the method of how the path is resolved. - lookupflags: lookupflags, + atflags: atflags, /// The relative path to operate on. path: string, /// The new permissions for the directory. From df809f008600f8b72738aa3cdc6d3b4ae3ec2561 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Dec 2021 13:37:32 -0800 Subject: [PATCH 0926/1772] Remove the `nofollow` flag from `oflags`. It's redundant with the `symlink_follow` flag in `atflags`. --- proposals/filesystem/wasi-filesystem.abi.md | 13 ++++--------- proposals/filesystem/wasi-filesystem.wit.md | 2 -- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index b935239a8..983453eb7 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -200,30 +200,25 @@ Size: 1, Alignment: 1 ### Record Fields -- [`nofollow`](#oflags.nofollow): `bool` - - Fail if path names an existing symbolic link. -Bit: 0 - - [`creat`](#oflags.creat): `bool` Create file if it does not exist. -Bit: 1 +Bit: 0 - [`directory`](#oflags.directory): `bool` Fail if not a directory. -Bit: 2 +Bit: 1 - [`excl`](#oflags.excl): `bool` Fail if file already exists. -Bit: 3 +Bit: 2 - [`trunc`](#oflags.trunc): `bool` Truncate file to size 0. -Bit: 4 +Bit: 3 ## `mode`: record diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 4f73a85f3..7284637ab 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -145,8 +145,6 @@ flags atflags { ```wit /// Open flags used by `open_at`. flags oflags { - /// Fail if path names an existing symbolic link. - nofollow, /// Create file if it does not exist. creat, /// Fail if not a directory. From 3dc31f97775aeb5aa37b1ff55bb48d8f0e5f41ef Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 Dec 2021 15:35:39 -0800 Subject: [PATCH 0927/1772] Rename `creat` to `create`. --- proposals/filesystem/wasi-filesystem.wit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 7284637ab..c71152985 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -146,7 +146,7 @@ flags atflags { /// Open flags used by `open_at`. flags oflags { /// Create file if it does not exist. - creat, + create, /// Fail if not a directory. directory, /// Fail if file already exists. From 03c88bd448e516013b0b01cee7b5c108a6344bdd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 Dec 2021 15:36:03 -0800 Subject: [PATCH 0928/1772] Add word separators to the advice names, for readability. --- proposals/filesystem/wasi-filesystem.wit.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index c71152985..84ff2be39 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -391,11 +391,11 @@ enum advice { /// The application expects to access the specified data in a random order. random, /// The application expects to access the specified data in the near future. - willneed, + will-need, /// The application expects that it will not access the specified data in the near future. - dontneed, + dont-need, /// The application expects to access the specified data once and then not reuse it thereafter. - noreuse, + no-reuse, } ``` From 111958383a58c147d5b25d438f8950e20ec1282c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 Dec 2021 15:36:26 -0800 Subject: [PATCH 0929/1772] Simplify `readlink_at` by having it return a string. --- proposals/filesystem/wasi-filesystem.wit.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 84ff2be39..3431a09d2 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -704,11 +704,9 @@ open_at: function( readlink_at: function( /// The relative path of the symbolic link from which to read. path: string, - /// The buffer to which to write the contents of the symbolic link. - buf: push-buffer, ) -> ( - /// The number of bytes placed in the buffer. - expected + /// The contents of the symbolic link. + expected ) ``` From 2d74cf5c7ba52c023fb3d3ab681786658240d73f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 Dec 2021 15:44:18 -0800 Subject: [PATCH 0930/1772] Update the ABI documentation. --- proposals/filesystem/wasi-filesystem.abi.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index 983453eb7..8a769a9d8 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -200,7 +200,7 @@ Size: 1, Alignment: 1 ### Record Fields -- [`creat`](#oflags.creat): `bool` +- [`create`](#oflags.create): `bool` Create file if it does not exist. Bit: 0 @@ -640,15 +640,15 @@ Size: 1, Alignment: 1 The application expects to access the specified data in a random order. -- [`willneed`](#advice.willneed) +- [`will-need`](#advice.will_need) The application expects to access the specified data in the near future. -- [`dontneed`](#advice.dontneed) +- [`dont-need`](#advice.dont_need) The application expects that it will not access the specified data in the near future. -- [`noreuse`](#advice.noreuse) +- [`no-reuse`](#advice.no_reuse) The application expects to access the specified data once and then not reuse it thereafter. @@ -989,9 +989,6 @@ Size: 16, Alignment: 8 guaranteed to be less than 2**31. Note: This is similar to `openat` in POSIX. - - TODO: Re-evaluate `direflags` here. - TODO: Add a permissions mode. ##### Params - `self`: handle @@ -1015,10 +1012,9 @@ Size: 16, Alignment: 8 - `self`: handle - `path`: `string` -- `buf`: push-buffer<`u8`> ##### Results -- ``: expected<[`size`](#size), [`errno`](#errno)> +- ``: expected<`string`, [`errno`](#errno)> ---- From 8f6f3f494a23e2b6f80c9e636a8aa6e8738c4f37 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 Dec 2021 16:50:31 -0800 Subject: [PATCH 0931/1772] Start filling in the README.md. Add some initial content to the WASI filesystem README.md. Lay out the high-level goals that have emerged, and briefly describe some of the lessons learned from implementation experience so far. --- proposals/filesystem/README.md | 75 ++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index e76604398..30c51691b 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -1,33 +1,28 @@ -# [Example WASI proposal] - -This template can be used to start a new proposal, which can then be proposed in the WASI Subgroup meetings. - -The sections below are recommended. However, every proposal is different, and the community can help you flesh out the proposal, so don't block on having something filled in for each one of them. - -Thank you to the W3C Privacy CG for the [inspiration](https://github.com/privacycg/template)! - -# [Title] +# WASI filesystem A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. ### Current Phase -[Fill in the current phase, e.g. Phase 1] +WASI-filesystem is currently in [Phase 2]. + +[Phase 2]: https://github.com/WebAssembly/WASI/blob/42fe2a3ca159011b23099c3d10b5b1d9aff2140e/docs/Proposals.md#phase-2---proposed-spec-text-available-cg--wg ### Champions -- [Champion 1] -- [Champion 2] -- [etc.] +- Dan Gohman ### Phase 4 Advancement Criteria -TODO before entering Phase 2. +WASI filesystem must have host implementations which can pass the testsuite +on at least Windows, macOS, and Linux. + +WASI filesystem must have at least two complete independent implementations. ## Table of Contents [if the explainer is longer than one printed page] - [Introduction](#introduction) -- [Goals [or Motivating Use Cases, or Scenarios]](#goals-or-motivating-use-cases-or-scenarios) +- [Goals](#goals) - [Non-goals](#non-goals) - [API walk-through](#api-walk-through) - [Use case 1](#use-case-1) @@ -43,15 +38,37 @@ TODO before entering Phase 2. ### Introduction -[The "executive summary" or "abstract". Explain in a few sentences what the goals of the project are, and a brief overview of how the solution works. This should be no more than 1-2 paragraphs.] +WASI filesystem is a WASI API primarily for accessing host filesystems. It +has function for opening, reading, and writing files, and for working with +directories. + +Unlike many filesystem APIs, WASI filesystem is capability-oriented. Instead +of having functions that implicitly reference a filesystem namespace, +WASI filesystems' APIs are passed a directory handle along with a path, and +the path is looked up relative to the given handle, and sandboxed to be +resolved within that directory. + +WASI filesystem hides some of the surface differences between Windows and +Unix-style filesystems, however much of its behavior, indluding the +semantics of path lookup, and the semantics of files, directories, and +symlinks, and the constraints on filesystem paths, is host-dependent. -### Goals [or Motivating Use Cases, or Scenarios] +WASI filesystem is not intended to be used as a virtual API for accessing +arbitary resources. Unix's "everything is a file" philosophy is in conflict +with the goals of supporting modularity and the principle of least authority. -[What is the end-user need which this project aims to address?] +### Goals + +The primary goal of WASI filesystem is to allow users to use WASI programs to +access their existing filesystems in a straightforward and efficient manner. ### Non-goals -[If there are "adjacent" goals which may appear to be in scope but aren't, enumerate them here. This section may be fleshed out as your design progresses and you encounter necessary technical and other trade-offs.] +WASI filesystem is not aiming for deterministic semantics. That would either +require restricting it to fully controlled private filesystems, which would +conflict with the goal of giving users access to their existing filesystems, +or requiring implementations to do a lot of extra work to emulate specific +defined behaviors, which would conflict with the goal of being efficient. ### API walk-through @@ -69,15 +86,23 @@ TODO before entering Phase 2. [This section should mostly refer to the .wit.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] -#### [Tricky design choice #1] +#### Should WASI filesystem be case-sensitive, case-insensitive, or platform-dependent? + +Even just among popular platforms, there are case-sensitive and +case-insensitive filesystems in wide use. -[Talk through the tradeoffs in coming to the specific design point you want to make.] +It would be nice to have an API which presented consistent behavior across +platforms, so that applications don't have to worry about subtle differences, +and subtle bugs due to those differences. -``` -// Illustrated with example code. -``` +However, implementing case sensitivity on a case-insensitive filesystem, or +case-insensitivity on a case-sensitive filesystem, are both tricky to do. -[This may be an open question, in which case you should link to any active discussion threads.] +One issue is that case insensitivity depends on a Unicode version, so the +details can differ between different case-insensitive platforms. Another +issue is tha WASI filesystem in general can't assume it has exclusive access +to the filesystem, so approaches that involve checking for files with names +that differ only by case can race with other processes creating new files. #### [Tricky design choice 2] From e4f0fe8521a2f322936cc192bc1750cde473eb92 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 20 Dec 2021 16:02:41 -0800 Subject: [PATCH 0932/1772] Remove the `notcapable` errno code. Remove the `notcapable` errno code, also known as `ENOTCAPABLE`. This errno code was previously used to indicate insufficient rights under the rights system, however the rights system has been dropped, so this errno code is no longer needed. --- proposals/filesystem/wasi-filesystem.abi.md | 4 ---- proposals/filesystem/wasi-filesystem.wit.md | 2 -- 2 files changed, 6 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index 8a769a9d8..409e4fe6a 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -616,10 +616,6 @@ Size: 1, Alignment: 1 Cross-device link. -- [`notcapable`](#errno.notcapable) - - Extension: Capabilities insufficient. - ## `advice`: variant File or memory access pattern advisory information. diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 3431a09d2..0b826eda2 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -375,8 +375,6 @@ enum errno { txtbsy, /// Cross-device link. xdev, - /// Extension: Capabilities insufficient. - notcapable, } ``` From 01a9676dc8e5ee76cacacd52befdb6411b961bd0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 21 Dec 2021 13:33:26 -0800 Subject: [PATCH 0933/1772] Change all identifiers to kebab-case. For consistency, pick a single naming convention and use it throughout wasi-filesystem. This also anticipates an upcoming proposal to interface types to require names to be kebab-case. --- proposals/filesystem/wasi-filesystem.abi.md | 104 +++++++-------- proposals/filesystem/wasi-filesystem.wit.md | 136 ++++++++++---------- 2 files changed, 120 insertions(+), 120 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index 409e4fe6a..d95fc1c35 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -59,11 +59,11 @@ Size: 1, Alignment: 1 The type of the descriptor or file is unknown or is different from any of the other types specified. -- [`block_device`](#type.block_device) +- [`block-device`](#type.block_device) The descriptor refers to a block device inode. -- [`character_device`](#type.character_device) +- [`character-device`](#type.character_device) The descriptor refers to a character device inode. @@ -75,11 +75,11 @@ Size: 1, Alignment: 1 The descriptor refers to a named pipe. -- [`symbolic_link`](#type.symbolic_link) +- [`symbolic-link`](#type.symbolic_link) The file refers to a symbolic link inode. -- [`regular_file`](#type.regular_file) +- [`regular-file`](#type.regular_file) The descriptor refers to a regular file inode. @@ -91,7 +91,7 @@ Size: 1, Alignment: 1 Descriptor flags. - Note: This was called `fdflags` in earlier versions of WASI. + Note: This was called `fd-flags` in earlier versions of WASI. Size: 1, Alignment: 1 @@ -179,7 +179,7 @@ Size: 64, Alignment: 8 Last file status change timestamp. -## `atflags`: record +## `at-flags`: record Flags determining the method of how paths are resolved. @@ -187,42 +187,42 @@ Size: 1, Alignment: 1 ### Record Fields -- [`symlink_follow`](#atflags.symlink_follow): `bool` +- [`symlink-follow`](#at_flags.symlink_follow): `bool` As long as the resolved path corresponds to a symbolic link, it is expanded. Bit: 0 -## `oflags`: record +## `o-flags`: record - Open flags used by `open_at`. + Open flags used by `open-at`. Size: 1, Alignment: 1 ### Record Fields -- [`create`](#oflags.create): `bool` +- [`create`](#o_flags.create): `bool` Create file if it does not exist. Bit: 0 -- [`directory`](#oflags.directory): `bool` +- [`directory`](#o_flags.directory): `bool` Fail if not a directory. Bit: 1 -- [`excl`](#oflags.excl): `bool` +- [`excl`](#o_flags.excl): `bool` Fail if file already exists. Bit: 2 -- [`trunc`](#oflags.trunc): `bool` +- [`trunc`](#o_flags.trunc): `bool` Truncate file to size 0. Bit: 3 ## `mode`: record - Permissions mode used by `open_at`, `change_permissions_at`, and similar. + Permissions mode used by `open-at`, `change-permissions-at`, and similar. Size: 1, Alignment: 1 @@ -264,7 +264,7 @@ Size: 8, Alignment: 8 Size: 8, Alignment: 8 -## `new_timestamp`: variant +## `new-timestamp`: variant When setting a timestamp, this gives the value to set it to. @@ -272,7 +272,7 @@ Size: 16, Alignment: 8 ### Variant Cases -- [`no_change`](#new_timestamp.no_change) +- [`no-change`](#new_timestamp.no_change) Leave the timestamp set to its previous value. @@ -648,7 +648,7 @@ Size: 1, Alignment: 1 The application expects to access the specified data once and then not reuse it thereafter. -## `seek_from`: variant +## `seek-from`: variant The position relative to which to set the offset of the descriptor. @@ -736,7 +736,7 @@ Size: 16, Alignment: 8 ---- -#### `descriptor::set_size` +#### `descriptor::set-size` Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. @@ -752,7 +752,7 @@ Size: 16, Alignment: 8 ---- -#### `descriptor::set_times` +#### `descriptor::set-times` Adjust the timestamps of an open file or directory. @@ -762,8 +762,8 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `atim`: [`new_timestamp`](#new_timestamp) -- `mtim`: [`new_timestamp`](#new_timestamp) +- `atim`: [`new-timestamp`](#new_timestamp) +- `mtim`: [`new-timestamp`](#new_timestamp) ##### Results - ``: expected<_, [`errno`](#errno)> @@ -853,7 +853,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `from`: [`seek_from`](#seek_from) +- `from`: [`seek-from`](#seek_from) ##### Results - ``: expected<[`filesize`](#filesize), [`errno`](#errno)> @@ -903,7 +903,7 @@ Size: 16, Alignment: 8 ---- -#### `descriptor::create_directory_at` +#### `descriptor::create-directory-at` Create a directory. @@ -918,7 +918,7 @@ Size: 16, Alignment: 8 ---- -#### `descriptor::stat_at` +#### `descriptor::stat-at` Return the attributes of a file or directory. @@ -928,7 +928,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `atflags`: [`atflags`](#atflags) +- `at-flags`: [`at-flags`](#at_flags) - `path`: `string` ##### Results @@ -936,7 +936,7 @@ Size: 16, Alignment: 8 ---- -#### `descriptor::set_times_at` +#### `descriptor::set-times-at` Adjust the timestamps of a file or directory. @@ -946,17 +946,17 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `atflags`: [`atflags`](#atflags) +- `at-flags`: [`at-flags`](#at_flags) - `path`: `string` -- `atim`: [`new_timestamp`](#new_timestamp) -- `mtim`: [`new_timestamp`](#new_timestamp) +- `atim`: [`new-timestamp`](#new_timestamp) +- `mtim`: [`new-timestamp`](#new_timestamp) ##### Results - ``: expected<_, [`errno`](#errno)> ---- -#### `descriptor::link_at` +#### `descriptor::link-at` Create a hard link. @@ -964,17 +964,17 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `old_atflags`: [`atflags`](#atflags) -- `old_path`: `string` -- `new_descriptor`: handle -- `new_path`: `string` +- `old-at-flags`: [`at-flags`](#at_flags) +- `old-path`: `string` +- `new-descriptor`: handle +- `new-path`: `string` ##### Results - ``: expected<_, [`errno`](#errno)> ---- -#### `descriptor::open_at` +#### `descriptor::open-at` Open a file or directory. @@ -988,10 +988,10 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `atflags`: [`atflags`](#atflags) +- `at-flags`: [`at-flags`](#at_flags) - `path`: `string` -- `oflags`: [`oflags`](#oflags) -- `fdflags`: [`flags`](#flags) +- `o-flags`: [`o-flags`](#o_flags) +- `fd-flags`: [`flags`](#flags) - `mode`: [`mode`](#mode) ##### Results @@ -999,7 +999,7 @@ Size: 16, Alignment: 8 ---- -#### `descriptor::readlink_at` +#### `descriptor::readlink-at` Read the contents of a symbolic link. @@ -1014,7 +1014,7 @@ Size: 16, Alignment: 8 ---- -#### `descriptor::remove_directory_at` +#### `descriptor::remove-directory-at` Remove a directory. @@ -1031,7 +1031,7 @@ Size: 16, Alignment: 8 ---- -#### `descriptor::rename_at` +#### `descriptor::rename-at` Rename a filesystem object. @@ -1039,16 +1039,16 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `old_path`: `string` -- `new_descriptor`: handle -- `new_path`: `string` +- `old-path`: `string` +- `new-descriptor`: handle +- `new-path`: `string` ##### Results - ``: expected<_, [`errno`](#errno)> ---- -#### `descriptor::symlink_at` +#### `descriptor::symlink-at` Create a symbolic link. @@ -1056,15 +1056,15 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `old_path`: `string` -- `new_path`: `string` +- `old-path`: `string` +- `new-path`: `string` ##### Results - ``: expected<_, [`errno`](#errno)> ---- -#### `descriptor::unlink_file_at` +#### `descriptor::unlink-file-at` Unlink a filesystem object that is not a directory. @@ -1080,12 +1080,12 @@ Size: 16, Alignment: 8 ---- -#### `descriptor::change_file_permissions_at` +#### `descriptor::change-file-permissions-at` ##### Params - `self`: handle -- `atflags`: [`atflags`](#atflags) +- `at-flags`: [`at-flags`](#at_flags) - `path`: `string` - `mode`: [`mode`](#mode) ##### Results @@ -1094,12 +1094,12 @@ Size: 16, Alignment: 8 ---- -#### `descriptor::change_directory_permissions_at` +#### `descriptor::change-directory-permissions-at` ##### Params - `self`: handle -- `atflags`: [`atflags`](#atflags) +- `at-flags`: [`at-flags`](#at_flags) - `path`: `string` - `mode`: [`mode`](#mode) ##### Results diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 0b826eda2..661f00cbb 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -63,17 +63,17 @@ enum "type" { /// any of the other types specified. unknown, /// The descriptor refers to a block device inode. - block_device, + block-device, /// The descriptor refers to a character device inode. - character_device, + character-device, /// The descriptor refers to a directory inode. directory, /// The descriptor refers to a named pipe. fifo, /// The file refers to a symbolic link inode. - symbolic_link, + symbolic-link, /// The descriptor refers to a regular file inode. - regular_file, + regular-file, /// The descriptor refers to a socket. socket, } @@ -83,7 +83,7 @@ enum "type" { ```wit /// Descriptor flags. /// -/// Note: This was called `fdflags` in earlier versions of WASI. +/// Note: This was called `fd-flags` in earlier versions of WASI. flags "flags" { /// Read mode: Data can be read. read, @@ -132,19 +132,19 @@ record stat { } ``` -## `atflags` +## `at-flags` ```wit /// Flags determining the method of how paths are resolved. -flags atflags { +flags at-flags { /// As long as the resolved path corresponds to a symbolic link, it is expanded. - symlink_follow, + symlink-follow, } ``` -## `oflags` +## `o-flags` ```wit -/// Open flags used by `open_at`. -flags oflags { +/// Open flags used by `open-at`. +flags o-flags { /// Create file if it does not exist. create, /// Fail if not a directory. @@ -158,7 +158,7 @@ flags oflags { ## `mode` ```wit -/// Permissions mode used by `open_at`, `change_permissions_at`, and similar. +/// Permissions mode used by `open-at`, `change-permissions-at`, and similar. flags mode { /// True if the resource is considered readable by the containing /// filesystem. @@ -191,12 +191,12 @@ type device = u64 type inode = u64 ``` -## `new_timestamp` +## `new-timestamp` ```wit /// When setting a timestamp, this gives the value to set it to. -variant new_timestamp { +variant new-timestamp { /// Leave the timestamp set to its previous value. - no_change, + no-change, /// Set the timestamp to the current time of the system clock associated /// with the filesystem. now, @@ -397,10 +397,10 @@ enum advice { } ``` -## `seek_from` +## `seek-from` ```wit /// The position relative to which to set the offset of the descriptor. -variant seek_from { +variant seek-from { /// Seek relative to start-of-file. set(filesize), /// Seek relative to current position. @@ -465,27 +465,27 @@ datasync: function() -> expected<_, errno> info: function() -> expected ``` -## `set_size` +## `set-size` ```wit /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. -set_size: function(size: filesize) -> expected<_, errno> +set-size: function(size: filesize) -> expected<_, errno> ``` -## `set_times` +## `set-times` ```wit /// Adjust the timestamps of an open file or directory. /// /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. -set_times: function( +set-times: function( /// The desired values of the data access timestamp. - atim: new_timestamp, + atim: new-timestamp, /// The desired values of the data modification timestamp. - mtim: new_timestamp, + mtim: new-timestamp, ) -> expected<_, errno> ``` @@ -564,7 +564,7 @@ readdir: function( /// Note: This is similar to `lseek` in POSIX. seek: function( /// The method to compute the new offset. - "from": seek_from, + "from": seek-from, ) -> ( /// The new offset of the descriptor, relative to the start of the file. expected @@ -601,27 +601,27 @@ write: function( ) -> expected ``` -## `create_directory_at` +## `create-directory-at` ```wit /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. -create_directory_at: function( +create-directory-at: function( /// The relative path at which to create the directory. path: string, ) -> expected<_, errno> ``` -## `stat_at` +## `stat-at` ```wit /// Return the attributes of a file or directory. /// /// Note: This is similar to `fstatat` in POSIX. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. -stat_at: function( +stat-at: function( /// Flags determining the method of how the path is resolved. - atflags: atflags, + at-flags: at-flags, /// The relative path of the file or directory to inspect. path: string, ) -> ( @@ -630,43 +630,43 @@ stat_at: function( ) ``` -## `set_times_at` +## `set-times-at` ```wit /// Adjust the timestamps of a file or directory. /// /// Note: This is similar to `utimensat` in POSIX. /// /// Note: This was called `path_filestat_set_times` in earlier versions of WASI. -set_times_at: function( +set-times-at: function( /// Flags determining the method of how the path is resolved. - atflags: atflags, + at-flags: at-flags, /// The relative path of the file or directory to operate on. path: string, /// The desired values of the data access timestamp. - atim: new_timestamp, + atim: new-timestamp, /// The desired values of the data modification timestamp. - mtim: new_timestamp, + mtim: new-timestamp, ) -> expected<_, errno> ``` -## `link_at` +## `link-at` ```wit /// Create a hard link. /// /// Note: This is similar to `linkat` in POSIX. -link_at: function( +link-at: function( /// Flags determining the method of how the path is resolved. - old_atflags: atflags, + old-at-flags: at-flags, /// The relative source path from which to link. - old_path: string, - /// The base directory for `new_path`. - new_descriptor: handle descriptor, + old-path: string, + /// The base directory for `new-path`. + new-descriptor: handle descriptor, /// The relative destination path at which to create the hard link. - new_path: string, + new-path: string, ) -> expected<_, errno> ``` -## `open_at` +## `open-at` ```wit /// Open a file or directory. /// @@ -677,15 +677,15 @@ link_at: function( /// guaranteed to be less than 2**31. /// /// Note: This is similar to `openat` in POSIX. -open_at: function( +open-at: function( /// Flags determining the method of how the path is resolved. - atflags: atflags, + at-flags: at-flags, /// The relative path of the object to open. path: string, /// The method by which to open the file. - oflags: oflags, + o-flags: o-flags, /// Flags to use for the resulting descriptor. - fdflags: "flags", + fd-flags: "flags", /// Permissions to use when creating a new file. mode: mode ) -> ( @@ -694,12 +694,12 @@ open_at: function( ) ``` -## `readlink_at` +## `readlink-at` ```wit /// Read the contents of a symbolic link. /// /// Note: This is similar to `readlinkat` in POSIX. -readlink_at: function( +readlink-at: function( /// The relative path of the symbolic link from which to read. path: string, ) -> ( @@ -708,60 +708,60 @@ readlink_at: function( ) ``` -## `remove_directory_at` +## `remove-directory-at` ```wit /// Remove a directory. /// /// Return `errno::notempty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. -remove_directory_at: function( +remove-directory-at: function( /// The relative path to a directory to remove. path: string, ) -> expected<_, errno> ``` -## `rename_at` +## `rename-at` ```wit /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. -rename_at: function( +rename-at: function( /// The relative source path of the file or directory to rename. - old_path: string, - /// The base directory for `new_path`. - new_descriptor: handle descriptor, + old-path: string, + /// The base directory for `new-path`. + new-descriptor: handle descriptor, /// The relative destination path to which to rename the file or directory. - new_path: string, + new-path: string, ) -> expected<_, errno> ``` -## `symlink_at` +## `symlink-at` ```wit /// Create a symbolic link. /// /// Note: This is similar to `symlinkat` in POSIX. -symlink_at: function( +symlink-at: function( /// The contents of the symbolic link. - old_path: string, + old-path: string, /// The relative destination path at which to create the symbolic link. - new_path: string, + new-path: string, ) -> expected<_, errno> ``` -## `unlink_file_at` +## `unlink-file-at` ```wit /// Unlink a filesystem object that is not a directory. /// /// Return `errno::isdir` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. -unlink_file_at: function( +unlink-file-at: function( /// The relative path to a file to unlink. path: string, ) -> expected<_, errno> ``` -## `change_file_permissions_at` +## `change-file-permissions-at` /// Change the permissions of a filesystem object that is not a directory. /// /// Note that the ultimate meanings of these permissions is @@ -769,9 +769,9 @@ unlink_file_at: function( /// /// Note: This is similar to `fchmodat` in POSIX. ```wit -change_file_permissions_at: function( +change-file-permissions-at: function( /// Flags determining the method of how the path is resolved. - atflags: atflags, + at-flags: at-flags, /// The relative path to operate on. path: string, /// The new permissions for the filesystem object. @@ -779,7 +779,7 @@ change_file_permissions_at: function( ) -> expected<_, errno> ``` -## `change_dir_permissions_at` +## `change-dir-permissions-at` /// Change the permissions of a directory. /// /// Note that the ultimate meanings of these permissions is @@ -791,9 +791,9 @@ change_file_permissions_at: function( /// /// Note: This is similar to `fchmodat` in POSIX. ```wit -change_directory_permissions_at: function( +change-directory-permissions-at: function( /// Flags determining the method of how the path is resolved. - atflags: atflags, + at-flags: at-flags, /// The relative path to operate on. path: string, /// The new permissions for the directory. From 8d82d63ec63a6252c096a582edf8551d2f8d72ce Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 27 Jan 2022 14:27:50 -0500 Subject: [PATCH 0934/1772] Update GH action from wai to wit (#3) --- proposals/io/.github/workflows/main.yml | 4 ++-- proposals/io/proposal-template.abi.md | 10 +++++----- proposals/io/proposal-template.wit.md | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index 0e6263384..f27c0a23b 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wai-abi-up-to-date@v1 + - uses: WebAssembly/wit-abi-up-to-date@v2 with: - wai-abi-tag: wai-abi-0.1.0 + wit-abi-tag: wit-abi-0.1.0 diff --git a/proposals/io/proposal-template.abi.md b/proposals/io/proposal-template.abi.md index 34daa27ab..9f935ee8f 100644 --- a/proposals/io/proposal-template.abi.md +++ b/proposals/io/proposal-template.abi.md @@ -1,6 +1,6 @@ # Types -## `api_type_one`: record +## `api-type-one`: record Short description @@ -10,22 +10,22 @@ Size: 16, Alignment: 8 ### Record Fields -- [`property_1`](#api_type_one.property_1): `u64` +- [`property1`](#api_type_one.property1): `u64` -- [`property_2`](#api_type_one.property_2): `string` +- [`property2`](#api_type_one.property2): `string` # Functions ---- -#### `api_function_one` +#### `api-function-one` Short description Explanation for developers using the API. ##### Results -- ``: [`api_type_one`](#api_type_one) +- ``: [`api-type-one`](#api_type_one) diff --git a/proposals/io/proposal-template.wit.md b/proposals/io/proposal-template.wit.md index 900b74e75..efa5364c5 100644 --- a/proposals/io/proposal-template.wit.md +++ b/proposals/io/proposal-template.wit.md @@ -12,9 +12,9 @@ /// Short description /// /// Explanation for developers using the API. -record api_type_one { - property_1: u64, - property_2: string, +record api-type-one { + property1: u64, + property2: string, } ``` @@ -26,7 +26,7 @@ More rigorous specification details for the implementer go here, if needed. /// Short description /// /// Explanation for developers using the API. -api_function_one: function() -> api_type_one +api-function-one: function() -> api-type-one ``` If needed, this would explain what a compliant implementation MUST do, such as never returning an earlier result from a later call. From ace012a540028e9fc775892092b44df6c444d149 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 27 Jan 2022 14:27:50 -0500 Subject: [PATCH 0935/1772] Update GH action from wai to wit (#3) --- proposals/sockets/.github/workflows/main.yml | 4 ++-- proposals/sockets/proposal-template.abi.md | 10 +++++----- proposals/sockets/proposal-template.wit.md | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index 0e6263384..f27c0a23b 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wai-abi-up-to-date@v1 + - uses: WebAssembly/wit-abi-up-to-date@v2 with: - wai-abi-tag: wai-abi-0.1.0 + wit-abi-tag: wit-abi-0.1.0 diff --git a/proposals/sockets/proposal-template.abi.md b/proposals/sockets/proposal-template.abi.md index 34daa27ab..9f935ee8f 100644 --- a/proposals/sockets/proposal-template.abi.md +++ b/proposals/sockets/proposal-template.abi.md @@ -1,6 +1,6 @@ # Types -## `api_type_one`: record +## `api-type-one`: record Short description @@ -10,22 +10,22 @@ Size: 16, Alignment: 8 ### Record Fields -- [`property_1`](#api_type_one.property_1): `u64` +- [`property1`](#api_type_one.property1): `u64` -- [`property_2`](#api_type_one.property_2): `string` +- [`property2`](#api_type_one.property2): `string` # Functions ---- -#### `api_function_one` +#### `api-function-one` Short description Explanation for developers using the API. ##### Results -- ``: [`api_type_one`](#api_type_one) +- ``: [`api-type-one`](#api_type_one) diff --git a/proposals/sockets/proposal-template.wit.md b/proposals/sockets/proposal-template.wit.md index 900b74e75..efa5364c5 100644 --- a/proposals/sockets/proposal-template.wit.md +++ b/proposals/sockets/proposal-template.wit.md @@ -12,9 +12,9 @@ /// Short description /// /// Explanation for developers using the API. -record api_type_one { - property_1: u64, - property_2: string, +record api-type-one { + property1: u64, + property2: string, } ``` @@ -26,7 +26,7 @@ More rigorous specification details for the implementer go here, if needed. /// Short description /// /// Explanation for developers using the API. -api_function_one: function() -> api_type_one +api-function-one: function() -> api-type-one ``` If needed, this would explain what a compliant implementation MUST do, such as never returning an earlier result from a later call. From 34d2be20b0cc2fc3f75ca18eae32d073cbf05604 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 24 Feb 2022 15:18:49 -0500 Subject: [PATCH 0936/1772] Initial commit --- proposals/sockets/.github/workflows/main.yml | 16 +++ proposals/sockets/README.md | 110 +++++++++++++++++++ proposals/sockets/proposal-template.abi.md | 31 ++++++ proposals/sockets/proposal-template.wit.md | 32 ++++++ proposals/sockets/test/README.md | 11 ++ 5 files changed, 200 insertions(+) create mode 100644 proposals/sockets/.github/workflows/main.yml create mode 100644 proposals/sockets/README.md create mode 100644 proposals/sockets/proposal-template.abi.md create mode 100644 proposals/sockets/proposal-template.wit.md create mode 100644 proposals/sockets/test/README.md diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml new file mode 100644 index 000000000..f27c0a23b --- /dev/null +++ b/proposals/sockets/.github/workflows/main.yml @@ -0,0 +1,16 @@ +name: CI +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + abi-up-to-date: + name: Check ABI files are up-to-date + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: WebAssembly/wit-abi-up-to-date@v2 + with: + wit-abi-tag: wit-abi-0.1.0 diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md new file mode 100644 index 000000000..e76604398 --- /dev/null +++ b/proposals/sockets/README.md @@ -0,0 +1,110 @@ +# [Example WASI proposal] + +This template can be used to start a new proposal, which can then be proposed in the WASI Subgroup meetings. + +The sections below are recommended. However, every proposal is different, and the community can help you flesh out the proposal, so don't block on having something filled in for each one of them. + +Thank you to the W3C Privacy CG for the [inspiration](https://github.com/privacycg/template)! + +# [Title] + +A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. + +### Current Phase + +[Fill in the current phase, e.g. Phase 1] + +### Champions + +- [Champion 1] +- [Champion 2] +- [etc.] + +### Phase 4 Advancement Criteria + +TODO before entering Phase 2. + +## Table of Contents [if the explainer is longer than one printed page] + +- [Introduction](#introduction) +- [Goals [or Motivating Use Cases, or Scenarios]](#goals-or-motivating-use-cases-or-scenarios) +- [Non-goals](#non-goals) +- [API walk-through](#api-walk-through) + - [Use case 1](#use-case-1) + - [Use case 2](#use-case-2) +- [Detailed design discussion](#detailed-design-discussion) + - [[Tricky design choice 1]](#tricky-design-choice-1) + - [[Tricky design choice 2]](#tricky-design-choice-2) +- [Considered alternatives](#considered-alternatives) + - [[Alternative 1]](#alternative-1) + - [[Alternative 2]](#alternative-2) +- [Stakeholder Interest & Feedback](#stakeholder-interest--feedback) +- [References & acknowledgements](#references--acknowledgements) + +### Introduction + +[The "executive summary" or "abstract". Explain in a few sentences what the goals of the project are, and a brief overview of how the solution works. This should be no more than 1-2 paragraphs.] + +### Goals [or Motivating Use Cases, or Scenarios] + +[What is the end-user need which this project aims to address?] + +### Non-goals + +[If there are "adjacent" goals which may appear to be in scope but aren't, enumerate them here. This section may be fleshed out as your design progresses and you encounter necessary technical and other trade-offs.] + +### API walk-through + +[Walk through of how someone would use this API.] + +#### [Use case 1] + +[Provide example code snippets and diagrams explaining how the API would be used to solve the given problem] + +#### [Use case 2] + +[etc.] + +### Detailed design discussion + +[This section should mostly refer to the .wit.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] + +#### [Tricky design choice #1] + +[Talk through the tradeoffs in coming to the specific design point you want to make.] + +``` +// Illustrated with example code. +``` + +[This may be an open question, in which case you should link to any active discussion threads.] + +#### [Tricky design choice 2] + +[etc.] + +### Considered alternatives + +[This section is not required if you already covered considered alternatives in the design discussion above.] + +#### [Alternative 1] + +[Describe an alternative which was considered, and why you decided against it.] + +#### [Alternative 2] + +[etc.] + +### Stakeholder Interest & Feedback + +TODO before entering Phase 3. + +[This should include a list of implementers who have expressed interest in implementing the proposal] + +### References & acknowledgements + +Many thanks for valuable feedback and advice from: + +- [Person 1] +- [Person 2] +- [etc.] diff --git a/proposals/sockets/proposal-template.abi.md b/proposals/sockets/proposal-template.abi.md new file mode 100644 index 000000000..9f935ee8f --- /dev/null +++ b/proposals/sockets/proposal-template.abi.md @@ -0,0 +1,31 @@ +# Types + +## `api-type-one`: record + + Short description + + Explanation for developers using the API. + +Size: 16, Alignment: 8 + +### Record Fields + +- [`property1`](#api_type_one.property1): `u64` + + +- [`property2`](#api_type_one.property2): `string` + + +# Functions + +---- + +#### `api-function-one` + + Short description + + Explanation for developers using the API. +##### Results + +- ``: [`api-type-one`](#api_type_one) + diff --git a/proposals/sockets/proposal-template.wit.md b/proposals/sockets/proposal-template.wit.md new file mode 100644 index 000000000..efa5364c5 --- /dev/null +++ b/proposals/sockets/proposal-template.wit.md @@ -0,0 +1,32 @@ +# [Proposal Template] API + +[This document contains the actual specification. It should be written in the WIT interface definition format. You can find more documentation on the WIT syntax (coming soon!).] + +[Note that all comments inside of WIT code blocks will be included in the developer facing documentation for language bindings generated using this WIT file. If there is additional information that needs to be communicated to implementers of the API, then these should be captured in text directly below the code block.] + +[If you want to include examples of the API in use, these should be in the README and linked to from this file.] + +## api_type_one + +```wit +/// Short description +/// +/// Explanation for developers using the API. +record api-type-one { + property1: u64, + property2: string, +} +``` + +More rigorous specification details for the implementer go here, if needed. + +## api_function_one + +```wit +/// Short description +/// +/// Explanation for developers using the API. +api-function-one: function() -> api-type-one +``` + +If needed, this would explain what a compliant implementation MUST do, such as never returning an earlier result from a later call. diff --git a/proposals/sockets/test/README.md b/proposals/sockets/test/README.md new file mode 100644 index 000000000..c274acd9d --- /dev/null +++ b/proposals/sockets/test/README.md @@ -0,0 +1,11 @@ +# Testing guidelines + +TK fill in testing guidelines + +## Installing the tools + +TK fill in instructions + +## Running the tests + +TK fill in instructions From 4d3db4ced86c789b9c46b4af4ae7faa7edeed0a9 Mon Sep 17 00:00:00 2001 From: Lin Clark Date: Thu, 24 Feb 2022 15:21:42 -0500 Subject: [PATCH 0937/1772] Add proposal champion --- proposals/sockets/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index e76604398..303e2b18e 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -12,13 +12,11 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Current Phase -[Fill in the current phase, e.g. Phase 1] +Phase 1 ### Champions -- [Champion 1] -- [Champion 2] -- [etc.] +- Dave Bakker (@badeend) ### Phase 4 Advancement Criteria From 57f97590e00eaf5ef7fa2870d1b280b83f393b59 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Fri, 25 Feb 2022 23:14:12 +0100 Subject: [PATCH 0938/1772] WIT-ified existing proposal at https://github.com/badeend/WASI-Networking --- proposals/sockets/wasi-sockets.wit | 409 +++++++++++++++++++++++++++++ 1 file changed, 409 insertions(+) create mode 100644 proposals/sockets/wasi-sockets.wit diff --git a/proposals/sockets/wasi-sockets.wit b/proposals/sockets/wasi-sockets.wit new file mode 100644 index 000000000..3ae768600 --- /dev/null +++ b/proposals/sockets/wasi-sockets.wit @@ -0,0 +1,409 @@ + +/// TO DISCUSS: Don't want this here. +record unit {} + +/// TO DISCUSS: Don't want this here. +type usize = u32 + +/// TO DISCUSS: Don't want this here. +record iovec { + start: usize, + length: usize, +} + +/// TO DISCUSS: Don't want this here. +type iovecs = list + +/// TO DISCUSS: Don't want this here. +resource input-byte-stream {} + +/// TO DISCUSS: Don't want this here. +resource output-byte-stream {} + + + + + + +/// TODO +enum socket-error { + /// TODO: https://github.com/WebAssembly/interface-types/issues/145 + unknown, +} + +enum socket-kind { + /// TODO: https://github.com/WebAssembly/interface-types/issues/145 + unknown, + tcp, + udp, +} + +enum ip-address-family { + /// Similar to `AF_INET` in POSIX. + ipv4, + + /// Similar to `AF_INET6` in POSIX. + ipv6, +} + +/// Single field record for symmetry with `ipv6-address`. +record ipv4-address { + /// The address in network order (big-endian). Note: WebAssembly is little-endian. + data: u32, +} + +/// Interface Types doesn't have either u128 or fixed length arrays. https://github.com/WebAssembly/interface-types/issues/146 +record ipv6-address { + /// Upper half of the address in network order (big-endian). Note: WebAssembly is little-endian. + data-msb: u64, + + /// Lower half of the address in network order (big-endian). Note: WebAssembly is little-endian. + data-lsb: u64, +} + +variant ip-address { + ipv4(ipv4-address), + ipv6(ipv6-address), +} + +record ipv4-socket-address { + port: u16, // sin_port + address: ipv4-address, // sin_addr +} + +record ipv6-socket-address { + port: u16, // sin6_port + flow-info: u32, // sin6_flowinfo + address: ipv6-address, // sin6_addr + scope-id: u32, // sin6_scope_id +} + +variant ip-socket-address { + ipv4(ipv4-socket-address), + ipv6(ipv6-socket-address), +} + +record udp-receive-result { + bytes-received: usize, + + /// Similar to the `MSG_TRUNC` flag in POSIX. + truncated: bool, + remote-address: ip-socket-address, + + /// Possible future additions: + /// local-address: ip-socket-address, // IP_PKTINFO / IP_RECVDSTADDR / IPV6_PKTINFO + /// local-interface: u32, // IP_PKTINFO / IP_RECVIF + /// ttl: u8, // IP_RECVTTL + /// dscp: u6, // IP_RECVTOS + /// ecn: u2, // IP_RECVTOS +} + +record udp-send-options { + remote-address: ip-socket-address, + + /// Possible future additions: + /// local-address: ip-socket-address, // IP_PKTINFO / IP_SENDSRCADDR / IPV6_PKTINFO +} + +enum tcp-shutdown-type { + /// Similar to `SHUT_RD` in POSIX. + receive, + + /// Similar to `SHUT_WR` in POSIX. + send, + + /// Similar to `SHUT_RDWR` in POSIX. + both, +} + +record ip-resolve-addresses-options { + address-family: option, + include-unavailable: bool, +} + +resource socket { + kind: function() -> expected + + /// TO DISCUSS: Don't want this. + as-udp-socket: function() -> handle udp-socket + + /// TO DISCUSS: Don't want this. + as-tcp-socket: function() -> handle tcp-socket +} + + +/// TO DISCUSS: Want to move these function to their respective module. +resource network { + + /// TO DISCUSS: Want to return a more specific type of socket. + /// + /// Create a new UDP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, 0 or IPPROTO_UDP)` in POSIX. + /// + /// References: + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html + /// - https://man7.org/linux/man-pages/man2/socket.2.html + /// + create-udp-socket: function() -> expected + + /// TO DISCUSS: Want to return a more specific type of socket. + /// + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, 0 or IPPROTO_TCP)` in POSIX. + /// + /// References: + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html + /// - https://man7.org/linux/man-pages/man2/socket.2.html + /// + create-tcp-socket: function(address-family: ip-address-family) -> expected + + /// Resolve an internet host name to a list of IP addresses. + /// + /// Parameters: + /// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted + /// to ASCII using IDNA encoding. + /// - `address-family`: If provided, limit the results to addresses of this specific address family. + /// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime + /// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on + /// systems without an active IPv6 interface. Notes: + /// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. + /// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. + /// + /// Results: + /// - When successful, there is always at least one result. + /// - The results are returned in the order the runtime thinks the application should try to connect to first. + /// - Never returns IPv4-mapped IPv6 addresses. + /// + /// Returns EAI_FAIL when `name` is: + /// - empty + /// - an IP address + /// - a syntactically invalid domain name in another way + /// + /// + /// Comparison with getaddrinfo: + /// + /// `getaddrinfo` is very generic and multipurpose by design. This WASI module is *not*. + /// This module focuses strictly on translating internet domain names to ip addresses. + /// That eliminates many of the other "hats" getaddrinfo has, like: + /// - Mapping service names to port numbers ("https" -> 443) + /// - Mapping service names/ports to socket types ("https" -> SOCK_STREAM) + /// - Network interface name translation + /// - IP address deserialization + /// - IP address string canonicalization + /// - Constants lookup for INADDR_ANY, INADDR_LOOPBACK, IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT + /// + /// Almost all of these functionalities can be shimmed in the libc implementation. The exception is network + /// interface name translation. That requires a future `if_nametoindex`-like syscall. + /// + /// This function has a different signature and semantics than `getaddrinfo`. The dissimilar name is chosen to reflect this. + /// + /// References: + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html + /// - https://man7.org/linux/man-pages/man3/getaddrinfo.3.html + /// + resolve-addresses: function(name: string, options: ip-resolve-addresses-options) -> expected, socket-error> +} + +/// TO DISCUSS: Subtyping. `udp-socket` is a `socket`. +resource udp-socket { + + /// Bind the socket to a specific IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to a send or receive operation will + /// implicitly bind the socket. + /// + /// Returns an error if the socket is already bound. + /// + /// TODO: disallow wildcard binds as long as there isn't a way to pass the local address to send & receive? + /// - https://blog.cloudflare.com/everything-you-ever-wanted-to-know-about-udp-sockets-but-were-afraid-to-ask-part-1/#sourcing-packets-from-a-wildcard-socket + /// - https://blog.powerdns.com/2012/10/08/on-binding-datagram-udp-sockets-to-the-any-addresses/ + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html + /// - https://man7.org/linux/man-pages/man2/bind.2.html + bind: function(local-address: ip-socket-address) -> expected + + /// Get the current bound address. + /// + /// Returns an error if the socket is not bound. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html + /// - https://man7.org/linux/man-pages/man2/getsockname.2.html + local-address: function() -> expected + + /// receive a message. + /// + /// Returns: + /// - The sender address of the datagram + /// - The number of bytes read. + /// - When the received datagram is larger than the provided buffers, + /// the excess data is lost and the `truncated` flag will be set. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html + /// - https://man7.org/linux/man-pages/man2/recv.2.html + receive: function(iovs: iovecs) -> expected + + /// receive a message just like `receive`, but don't remove the message from the queue. + peek: function(iovs: iovecs) -> expected + + /// send a message to a specific destination address. + /// + /// The remote address option is required. To send a message to the "connected" peer, + /// call `remote-address` to get their address. + /// + /// Returns the number of bytes sent. + /// + /// TODO: Does the returned number of bytes sent ever differ from the supplied buffer size for UDP sockets? + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html + /// - https://man7.org/linux/man-pages/man2/send.2.html + send: function(iovs: iovecs, options: udp-send-options) -> expected + + /// Set the destination address. + /// + /// When a destination address is set: + /// - all receive operations will only return datagrams sent from the provided `remote-address`. + /// - the `send` function can still be used to send to any other destination, however you can't receive their response. + /// + /// Similar to `connect(sock, ...)` in POSIX. + /// + /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". + /// + /// TODO: "connect" is a rather odd name for this function because it doesn't reflect what's actually happening. + /// Feels like it was chosen just to shoehorn UDP into the existing Socket interface. + /// Do we have to keep this name? + /// + /// TODO: add unconnect ability. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html + /// - https://man7.org/linux/man-pages/man2/connect.2.html + connect: function(remote-address: ip-socket-address) -> expected + + /// Get the address set with `connect`. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html + /// - https://man7.org/linux/man-pages/man2/getpeername.2.html + remote-address: function() -> expected +} + + +/// TO DISCUSS: Subtyping. `tcp-socket` is a `socket` && `tcp-socket` is a `io-stream`. +resource tcp-socket { + + /// TO DISCUSS: Don't want this. + as-input-byte-stream: function() -> handle input-byte-stream + + /// TO DISCUSS: Don't want this. + as-output-byte-stream: function() -> handle output-byte-stream + + /// Bind the socket to a specific IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will + /// implicitly bind the socket. + /// + /// Returns an error if the socket is already bound. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html + /// - https://man7.org/linux/man-pages/man2/bind.2.html + bind: function(local-address: ip-socket-address) -> expected + + /// Get the current bound address. + /// + /// Returns an error if the socket is not bound. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html + /// - https://man7.org/linux/man-pages/man2/getsockname.2.html + local-address: function() -> expected + + /// Connect to a remote endpoint. + /// + /// Transitions the socket into the Connection state. + /// Fails when the socket is already in the Connection or Listener state. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html + /// - https://man7.org/linux/man-pages/man2/connect.2.html + connect: function(remote-address: ip-socket-address) -> expected + + /// Start listening for new connections. + /// + /// Transitions the socket into the Listener state. + /// Fails when the socket is already in the Connection or Listener state. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html + /// - https://man7.org/linux/man-pages/man2/listen.2.html + listen: function(backlog-size-hint: option) -> expected + + /// Fails when the socket is not in the Connection state. + /// + /// Read data from the stream just like `InputByteStream::read`, but don't remove the data from the queue. + peek: function(iovs: iovecs) -> expected + + /// Fails when the socket is not in the Connection state. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html + /// - https://man7.org/linux/man-pages/man2/getpeername.2.html + remote-address: function() -> expected + + /// Gracefully shut down the connection. + /// + /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read/receive + /// operations will return 0, indicating End Of Stream. If there is still data in the receive queue at time of + /// calling `shutdown` or whenever new data arrives afterwards, then (TODO). + /// - send: the socket is not expecting to send any more data to the peer. After all data in the send queue has + /// been sent and acknowledged, a FIN will be sent. All subsequent write/send operations will return an + /// EPIPE error. + /// - both: receive & send + /// + /// The shutdown function does not close the socket. + /// + /// Fails when the socket is not in the Connection state. + /// + /// TODO: Look into how different platforms behave after shutdown(Read) has been called and new data arrives. According to the internet (unverified): + /// - BSD: silently discards the data + /// - Linux: effectively ignores the shutdown call. New data can still be read. If not done will ultimately block the sender. + /// - Windows: sends RST + /// + /// TODO: Look into how different platforms behave when trying to shut down the same direction multiple times. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html + /// - https://man7.org/linux/man-pages/man2/shutdown.2.html + shutdown: function(shutdown-type: tcp-shutdown-type) -> expected + + /// TO DISCUSS: Want to return a more specific type of socket. + /// + /// Unlike POSIX, this function does not returns the remote address. + /// If you want to know this information, invoke `remote-address` on the newly created socket. + /// + /// Fails when this socket is not in the Listening state. + /// + /// Returns a new bound socket in the Connection state. + /// + /// References: + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html + /// - https://man7.org/linux/man-pages/man2/accept.2.html + accept: function() -> expected +} + From 9b9e0853c32dc0f15ef8189861aab4e8fbb693b6 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Fri, 25 Feb 2022 23:17:01 +0100 Subject: [PATCH 0939/1772] Trying to enable syntax highlighting. --- proposals/sockets/.gitattributes | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 proposals/sockets/.gitattributes diff --git a/proposals/sockets/.gitattributes b/proposals/sockets/.gitattributes new file mode 100644 index 000000000..4101e25d1 --- /dev/null +++ b/proposals/sockets/.gitattributes @@ -0,0 +1,2 @@ +# Enable some degree of syntax highlighting on GitHub: +*.wit linguist-language=Rust \ No newline at end of file From a96847d87adeb141b8fde6308a7820bdacd0be5c Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sat, 26 Feb 2022 10:45:48 +0100 Subject: [PATCH 0940/1772] WIT-ified existing proposal at https://github.com/badeend/WASI-Networking (cont.) --- proposals/sockets/wasi-sockets.wit | 38 ++++++++++-------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/proposals/sockets/wasi-sockets.wit b/proposals/sockets/wasi-sockets.wit index 3ae768600..78bcd7d45 100644 --- a/proposals/sockets/wasi-sockets.wit +++ b/proposals/sockets/wasi-sockets.wit @@ -1,19 +1,7 @@ -/// TO DISCUSS: Don't want this here. -record unit {} - /// TO DISCUSS: Don't want this here. type usize = u32 -/// TO DISCUSS: Don't want this here. -record iovec { - start: usize, - length: usize, -} - -/// TO DISCUSS: Don't want this here. -type iovecs = list - /// TO DISCUSS: Don't want this here. resource input-byte-stream {} @@ -145,7 +133,7 @@ resource network { /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html /// - https://man7.org/linux/man-pages/man2/socket.2.html /// - create-udp-socket: function() -> expected + create-udp-socket: function(address-family: ip-address-family) -> expected /// TO DISCUSS: Want to return a more specific type of socket. /// @@ -203,7 +191,7 @@ resource network { /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html /// - https://man7.org/linux/man-pages/man3/getaddrinfo.3.html /// - resolve-addresses: function(name: string, options: ip-resolve-addresses-options) -> expected, socket-error> + resolve-addresses: async function(name: string, options: ip-resolve-addresses-options) -> expected, socket-error> } /// TO DISCUSS: Subtyping. `udp-socket` is a `socket`. @@ -227,7 +215,7 @@ resource udp-socket { /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html /// - https://man7.org/linux/man-pages/man2/bind.2.html - bind: function(local-address: ip-socket-address) -> expected + bind: async function(local-address: ip-socket-address) -> expected<_, socket-error> /// Get the current bound address. /// @@ -250,10 +238,10 @@ resource udp-socket { /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html /// - https://man7.org/linux/man-pages/man2/recv.2.html - receive: function(iovs: iovecs) -> expected + receive: async function(iovs: push-buffer) -> expected /// receive a message just like `receive`, but don't remove the message from the queue. - peek: function(iovs: iovecs) -> expected + peek: async function(iovs: push-buffer) -> expected /// send a message to a specific destination address. /// @@ -268,7 +256,7 @@ resource udp-socket { /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html /// - https://man7.org/linux/man-pages/man2/send.2.html - send: function(iovs: iovecs, options: udp-send-options) -> expected + send: async function(iovs: pull-buffer, options: udp-send-options) -> expected /// Set the destination address. /// @@ -289,7 +277,7 @@ resource udp-socket { /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html /// - https://man7.org/linux/man-pages/man2/connect.2.html - connect: function(remote-address: ip-socket-address) -> expected + connect: async function(remote-address: ip-socket-address) -> expected<_, socket-error> /// Get the address set with `connect`. /// @@ -323,7 +311,7 @@ resource tcp-socket { /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html /// - https://man7.org/linux/man-pages/man2/bind.2.html - bind: function(local-address: ip-socket-address) -> expected + bind: async function(local-address: ip-socket-address) -> expected<_, socket-error> /// Get the current bound address. /// @@ -342,7 +330,7 @@ resource tcp-socket { /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html /// - https://man7.org/linux/man-pages/man2/connect.2.html - connect: function(remote-address: ip-socket-address) -> expected + connect: async function(remote-address: ip-socket-address) -> expected<_, socket-error> /// Start listening for new connections. /// @@ -352,12 +340,12 @@ resource tcp-socket { /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html /// - https://man7.org/linux/man-pages/man2/listen.2.html - listen: function(backlog-size-hint: option) -> expected + listen: async function(backlog-size-hint: option) -> expected<_, socket-error> /// Fails when the socket is not in the Connection state. /// /// Read data from the stream just like `InputByteStream::read`, but don't remove the data from the queue. - peek: function(iovs: iovecs) -> expected + peek: async function(iovs: push-buffer) -> expected /// Fails when the socket is not in the Connection state. /// @@ -390,7 +378,7 @@ resource tcp-socket { /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html /// - https://man7.org/linux/man-pages/man2/shutdown.2.html - shutdown: function(shutdown-type: tcp-shutdown-type) -> expected + shutdown: async function(shutdown-type: tcp-shutdown-type) -> expected<_, socket-error> /// TO DISCUSS: Want to return a more specific type of socket. /// @@ -404,6 +392,6 @@ resource tcp-socket { /// References: /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html /// - https://man7.org/linux/man-pages/man2/accept.2.html - accept: function() -> expected + accept: async function() -> expected } From 40926dcdc9ae0f67f9a219410c748467587840a3 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sat, 26 Feb 2022 14:44:39 +0100 Subject: [PATCH 0941/1772] WIT-ified existing proposal at https://github.com/badeend/WASI-Networking (cont.) --- proposals/sockets/common-types.wit | 54 +++ proposals/sockets/wasi-io-streams.wit | 7 + proposals/sockets/wasi-ip-name-lookup.wit | 53 +++ proposals/sockets/wasi-network.wit | 3 + proposals/sockets/wasi-socket-tcp.wit | 126 +++++++ proposals/sockets/wasi-socket-udp.wit | 127 +++++++ proposals/sockets/wasi-socket.wit | 13 + proposals/sockets/wasi-sockets.wit | 397 ---------------------- 8 files changed, 383 insertions(+), 397 deletions(-) create mode 100644 proposals/sockets/common-types.wit create mode 100644 proposals/sockets/wasi-io-streams.wit create mode 100644 proposals/sockets/wasi-ip-name-lookup.wit create mode 100644 proposals/sockets/wasi-network.wit create mode 100644 proposals/sockets/wasi-socket-tcp.wit create mode 100644 proposals/sockets/wasi-socket-udp.wit create mode 100644 proposals/sockets/wasi-socket.wit delete mode 100644 proposals/sockets/wasi-sockets.wit diff --git a/proposals/sockets/common-types.wit b/proposals/sockets/common-types.wit new file mode 100644 index 000000000..952117682 --- /dev/null +++ b/proposals/sockets/common-types.wit @@ -0,0 +1,54 @@ + +/// TO DISCUSS +type usize = u32 + +/// TODO +enum error { + /// TODO: https://github.com/WebAssembly/interface-types/issues/145 + unknown, +} + +enum ip-address-family { + /// Similar to `AF_INET` in POSIX. + ipv4, + + /// Similar to `AF_INET6` in POSIX. + ipv6, +} + +/// Single field record for symmetry with `ipv6-address`. +record ipv4-address { + /// The address in network order (big-endian). Note: WebAssembly is little-endian. + data: u32, +} + +/// Interface Types doesn't have either u128 or fixed length arrays. https://github.com/WebAssembly/interface-types/issues/146 +record ipv6-address { + /// Upper half of the address in network order (big-endian). Note: WebAssembly is little-endian. + data-msb: u64, + + /// Lower half of the address in network order (big-endian). Note: WebAssembly is little-endian. + data-lsb: u64, +} + +variant ip-address { + ipv4(ipv4-address), + ipv6(ipv6-address), +} + +record ipv4-socket-address { + port: u16, // sin_port + address: ipv4-address, // sin_addr +} + +record ipv6-socket-address { + port: u16, // sin6_port + flow-info: u32, // sin6_flowinfo + address: ipv6-address, // sin6_addr + scope-id: u32, // sin6_scope_id +} + +variant ip-socket-address { + ipv4(ipv4-socket-address), + ipv6(ipv6-socket-address), +} \ No newline at end of file diff --git a/proposals/sockets/wasi-io-streams.wit b/proposals/sockets/wasi-io-streams.wit new file mode 100644 index 000000000..472924dcf --- /dev/null +++ b/proposals/sockets/wasi-io-streams.wit @@ -0,0 +1,7 @@ + +/// Stubs of https://github.com/WebAssembly/wasi-io/ +/// +/// TO DISCUSS + +resource input-byte-stream {} +resource output-byte-stream {} \ No newline at end of file diff --git a/proposals/sockets/wasi-ip-name-lookup.wit b/proposals/sockets/wasi-ip-name-lookup.wit new file mode 100644 index 000000000..19f8e5030 --- /dev/null +++ b/proposals/sockets/wasi-ip-name-lookup.wit @@ -0,0 +1,53 @@ +use { error, ip-address, ip-address-family } from common-types +use { network } from wasi-network + +record resolve-addresses-options { + address-family: option, + include-unavailable: bool, +} + +/// Resolve an internet host name to a list of IP addresses. +/// +/// Parameters: +/// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted +/// to ASCII using IDNA encoding. +/// - `address-family`: If provided, limit the results to addresses of this specific address family. +/// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime +/// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on +/// systems without an active IPv6 interface. Notes: +/// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. +/// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. +/// +/// Results: +/// - When successful, there is always at least one result. +/// - The results are returned in the order the runtime thinks the application should try to connect to first. +/// - Never returns IPv4-mapped IPv6 addresses. +/// +/// Returns EAI_FAIL when `name` is: +/// - empty +/// - an IP address +/// - a syntactically invalid domain name in another way +/// +/// +/// Comparison with getaddrinfo: +/// +/// `getaddrinfo` is very generic and multipurpose by design. This WASI module is *not*. +/// This module focuses strictly on translating internet domain names to ip addresses. +/// That eliminates many of the other "hats" getaddrinfo has, like: +/// - Mapping service names to port numbers ("https" -> 443) +/// - Mapping service names/ports to socket types ("https" -> SOCK_STREAM) +/// - Network interface name translation +/// - IP address deserialization +/// - IP address string canonicalization +/// - Constants lookup for INADDR_ANY, INADDR_LOOPBACK, IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT +/// +/// Almost all of these functionalities can be shimmed in the libc implementation. The exception is network +/// interface name translation. That requires a future `if_nametoindex`-like syscall. +/// +/// This function has a different signature and semantics than `getaddrinfo`. The dissimilar name is chosen to reflect this. +/// +/// References: +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html +/// - https://man7.org/linux/man-pages/man3/getaddrinfo.3.html +/// +resolve-addresses: async function(name: string, options: resolve-addresses-options) -> expected, error> \ No newline at end of file diff --git a/proposals/sockets/wasi-network.wit b/proposals/sockets/wasi-network.wit new file mode 100644 index 000000000..1a06a6ae1 --- /dev/null +++ b/proposals/sockets/wasi-network.wit @@ -0,0 +1,3 @@ + +/// Capability handle for accessing network-related functions. +resource network {} \ No newline at end of file diff --git a/proposals/sockets/wasi-socket-tcp.wit b/proposals/sockets/wasi-socket-tcp.wit new file mode 100644 index 000000000..a91813cf0 --- /dev/null +++ b/proposals/sockets/wasi-socket-tcp.wit @@ -0,0 +1,126 @@ +use { error, ip-address-family, ip-socket-address, usize } from common-types +use { input-byte-stream, output-byte-stream } from wasi-io-streams +use { network } from wasi-network +use { socket } from wasi-socket + +enum shutdown-type { + /// Similar to `SHUT_RD` in POSIX. + receive, + + /// Similar to `SHUT_WR` in POSIX. + send, + + /// Similar to `SHUT_RDWR` in POSIX. + both, +} + +/// Create a new TCP socket. +/// +/// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, 0 or IPPROTO_TCP)` in POSIX. +/// +/// References: +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html +/// - https://man7.org/linux/man-pages/man2/socket.2.html +/// +create-tcp-socket: function(network: handle network, address-family: ip-address-family) -> expected + +/// TO DISCUSS +as-input-byte-stream: function(tcp-socket: handle socket) -> handle input-byte-stream + +/// TO DISCUSS +as-output-byte-stream: function(tcp-socket: handle socket) -> handle output-byte-stream + +/// Bind the socket to a specific IP address and port. +/// +/// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which +/// network interface(s) to bind to. +/// If the TCP/UDP port is zero, the socket will be bound to a random free port. +/// +/// When a socket is not explicitly bound, the first invocation to a listen or connect operation will +/// implicitly bind the socket. +/// +/// Returns an error if the socket is already bound. +/// +/// References +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html +/// - https://man7.org/linux/man-pages/man2/bind.2.html +bind: async function(tcp-socket: handle socket, local-address: ip-socket-address) -> expected<_, error> + +/// Get the current bound address. +/// +/// Returns an error if the socket is not bound. +/// +/// References +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html +/// - https://man7.org/linux/man-pages/man2/getsockname.2.html +local-address: function(tcp-socket: handle socket) -> expected + +/// Connect to a remote endpoint. +/// +/// Transitions the socket into the Connection state. +/// Fails when the socket is already in the Connection or Listener state. +/// +/// References +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html +/// - https://man7.org/linux/man-pages/man2/connect.2.html +connect: async function(tcp-socket: handle socket, remote-address: ip-socket-address) -> expected<_, error> + +/// Start listening for new connections. +/// +/// Transitions the socket into the Listener state. +/// Fails when the socket is already in the Connection or Listener state. +/// +/// References +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html +/// - https://man7.org/linux/man-pages/man2/listen.2.html +listen: async function(tcp-socket: handle socket, backlog-size-hint: option) -> expected<_, error> + +/// Fails when the socket is not in the Connection state. +/// +/// Read data from the stream just like `InputByteStream::read`, but don't remove the data from the queue. +peek: async function(tcp-socket: handle socket, iovs: push-buffer) -> expected + +/// Fails when the socket is not in the Connection state. +/// +/// References +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html +/// - https://man7.org/linux/man-pages/man2/getpeername.2.html +remote-address: function(tcp-socket: handle socket) -> expected + +/// Gracefully shut down the connection. +/// +/// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read/receive +/// operations will return 0, indicating End Of Stream. If there is still data in the receive queue at time of +/// calling `shutdown` or whenever new data arrives afterwards, then (TODO). +/// - send: the socket is not expecting to send any more data to the peer. After all data in the send queue has +/// been sent and acknowledged, a FIN will be sent. All subsequent write/send operations will return an +/// EPIPE error. +/// - both: receive & send +/// +/// The shutdown function does not close the socket. +/// +/// Fails when the socket is not in the Connection state. +/// +/// TODO: Look into how different platforms behave after shutdown(Read) has been called and new data arrives. According to the internet (unverified): +/// - BSD: silently discards the data +/// - Linux: effectively ignores the shutdown call. New data can still be read. If not done will ultimately block the sender. +/// - Windows: sends RST +/// +/// TODO: Look into how different platforms behave when trying to shut down the same direction multiple times. +/// +/// References +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html +/// - https://man7.org/linux/man-pages/man2/shutdown.2.html +shutdown: async function(tcp-socket: handle socket, shutdown-type: shutdown-type) -> expected<_, error> + +/// Unlike POSIX, this function does not returns the remote address. +/// If you want to know this information, invoke `remote-address` on the newly created socket. +/// +/// Fails when this socket is not in the Listening state. +/// +/// Returns a new bound socket in the Connection state. +/// +/// References: +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html +/// - https://man7.org/linux/man-pages/man2/accept.2.html +accept: async function(tcp-socket: handle socket) -> expected diff --git a/proposals/sockets/wasi-socket-udp.wit b/proposals/sockets/wasi-socket-udp.wit new file mode 100644 index 000000000..568998750 --- /dev/null +++ b/proposals/sockets/wasi-socket-udp.wit @@ -0,0 +1,127 @@ + +use { error, ip-address-family, ip-socket-address, usize } from common-types +use { network } from wasi-network +use { socket } from wasi-socket + + +record receive-result { + bytes-received: usize, + + /// Similar to the `MSG_TRUNC` flag in POSIX. + truncated: bool, + remote-address: ip-socket-address, + + /// Possible future additions: + /// local-address: ip-socket-address, // IP_PKTINFO / IP_RECVDSTADDR / IPV6_PKTINFO + /// local-interface: u32, // IP_PKTINFO / IP_RECVIF + /// ttl: u8, // IP_RECVTTL + /// dscp: u6, // IP_RECVTOS + /// ecn: u2, // IP_RECVTOS +} + +record send-options { + remote-address: ip-socket-address, + + /// Possible future additions: + /// local-address: ip-socket-address, // IP_PKTINFO / IP_SENDSRCADDR / IPV6_PKTINFO +} + + +/// Create a new UDP socket. +/// +/// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, 0 or IPPROTO_UDP)` in POSIX. +/// +/// References: +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html +/// - https://man7.org/linux/man-pages/man2/socket.2.html +/// +create-udp-socket: function(network: handle network, address-family: ip-address-family) -> expected + +/// Bind the socket to a specific IP address and port. +/// +/// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which +/// network interface(s) to bind to. +/// If the TCP/UDP port is zero, the socket will be bound to a random free port. +/// +/// When a socket is not explicitly bound, the first invocation to a send or receive operation will +/// implicitly bind the socket. +/// +/// Returns an error if the socket is already bound. +/// +/// TODO: disallow wildcard binds as long as there isn't a way to pass the local address to send & receive? +/// - https://blog.cloudflare.com/everything-you-ever-wanted-to-know-about-udp-sockets-but-were-afraid-to-ask-part-1/#sourcing-packets-from-a-wildcard-socket +/// - https://blog.powerdns.com/2012/10/08/on-binding-datagram-udp-sockets-to-the-any-addresses/ +/// +/// References +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html +/// - https://man7.org/linux/man-pages/man2/bind.2.html +bind: async function(udp-socket: handle socket, local-address: ip-socket-address) -> expected<_, error> + +/// Get the current bound address. +/// +/// Returns an error if the socket is not bound. +/// +/// References +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html +/// - https://man7.org/linux/man-pages/man2/getsockname.2.html +local-address: function(udp-socket: handle socket) -> expected + +/// receive a message. +/// +/// Returns: +/// - The sender address of the datagram +/// - The number of bytes read. +/// - When the received datagram is larger than the provided buffers, +/// the excess data is lost and the `truncated` flag will be set. +/// +/// References +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html +/// - https://man7.org/linux/man-pages/man2/recv.2.html +receive: async function(udp-socket: handle socket, iovs: push-buffer) -> expected + +/// receive a message just like `receive`, but don't remove the message from the queue. +peek: async function(udp-socket: handle socket, iovs: push-buffer) -> expected + +/// send a message to a specific destination address. +/// +/// The remote address option is required. To send a message to the "connected" peer, +/// call `remote-address` to get their address. +/// +/// Returns the number of bytes sent. +/// +/// TODO: Does the returned number of bytes sent ever differ from the supplied buffer size for UDP sockets? +/// +/// References +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html +/// - https://man7.org/linux/man-pages/man2/send.2.html +send: async function(udp-socket: handle socket, iovs: pull-buffer, options: send-options) -> expected + +/// Set the destination address. +/// +/// When a destination address is set: +/// - all receive operations will only return datagrams sent from the provided `remote-address`. +/// - the `send` function can still be used to send to any other destination, however you can't receive their response. +/// +/// Similar to `connect(sock, ...)` in POSIX. +/// +/// Note that this function does not generate any network traffic and the peer is not aware of this "connection". +/// +/// TODO: "connect" is a rather odd name for this function because it doesn't reflect what's actually happening. +/// Feels like it was chosen just to shoehorn UDP into the existing Socket interface. +/// Do we have to keep this name? +/// +/// TODO: add unconnect ability. +/// +/// References +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html +/// - https://man7.org/linux/man-pages/man2/connect.2.html +connect: async function(udp-socket: handle socket, remote-address: ip-socket-address) -> expected<_, error> + +/// Get the address set with `connect`. +/// +/// References +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html +/// - https://man7.org/linux/man-pages/man2/getpeername.2.html +remote-address: function(udp-socket: handle socket) -> expected \ No newline at end of file diff --git a/proposals/sockets/wasi-socket.wit b/proposals/sockets/wasi-socket.wit new file mode 100644 index 000000000..183c7c742 --- /dev/null +++ b/proposals/sockets/wasi-socket.wit @@ -0,0 +1,13 @@ + +use { error } from common-types + +enum socket-kind { + /// TODO: https://github.com/WebAssembly/interface-types/issues/145 + unknown, + tcp, + udp, +} + +resource socket {} + +kind: function(any-socket: handle socket) -> expected \ No newline at end of file diff --git a/proposals/sockets/wasi-sockets.wit b/proposals/sockets/wasi-sockets.wit deleted file mode 100644 index 78bcd7d45..000000000 --- a/proposals/sockets/wasi-sockets.wit +++ /dev/null @@ -1,397 +0,0 @@ - -/// TO DISCUSS: Don't want this here. -type usize = u32 - -/// TO DISCUSS: Don't want this here. -resource input-byte-stream {} - -/// TO DISCUSS: Don't want this here. -resource output-byte-stream {} - - - - - - -/// TODO -enum socket-error { - /// TODO: https://github.com/WebAssembly/interface-types/issues/145 - unknown, -} - -enum socket-kind { - /// TODO: https://github.com/WebAssembly/interface-types/issues/145 - unknown, - tcp, - udp, -} - -enum ip-address-family { - /// Similar to `AF_INET` in POSIX. - ipv4, - - /// Similar to `AF_INET6` in POSIX. - ipv6, -} - -/// Single field record for symmetry with `ipv6-address`. -record ipv4-address { - /// The address in network order (big-endian). Note: WebAssembly is little-endian. - data: u32, -} - -/// Interface Types doesn't have either u128 or fixed length arrays. https://github.com/WebAssembly/interface-types/issues/146 -record ipv6-address { - /// Upper half of the address in network order (big-endian). Note: WebAssembly is little-endian. - data-msb: u64, - - /// Lower half of the address in network order (big-endian). Note: WebAssembly is little-endian. - data-lsb: u64, -} - -variant ip-address { - ipv4(ipv4-address), - ipv6(ipv6-address), -} - -record ipv4-socket-address { - port: u16, // sin_port - address: ipv4-address, // sin_addr -} - -record ipv6-socket-address { - port: u16, // sin6_port - flow-info: u32, // sin6_flowinfo - address: ipv6-address, // sin6_addr - scope-id: u32, // sin6_scope_id -} - -variant ip-socket-address { - ipv4(ipv4-socket-address), - ipv6(ipv6-socket-address), -} - -record udp-receive-result { - bytes-received: usize, - - /// Similar to the `MSG_TRUNC` flag in POSIX. - truncated: bool, - remote-address: ip-socket-address, - - /// Possible future additions: - /// local-address: ip-socket-address, // IP_PKTINFO / IP_RECVDSTADDR / IPV6_PKTINFO - /// local-interface: u32, // IP_PKTINFO / IP_RECVIF - /// ttl: u8, // IP_RECVTTL - /// dscp: u6, // IP_RECVTOS - /// ecn: u2, // IP_RECVTOS -} - -record udp-send-options { - remote-address: ip-socket-address, - - /// Possible future additions: - /// local-address: ip-socket-address, // IP_PKTINFO / IP_SENDSRCADDR / IPV6_PKTINFO -} - -enum tcp-shutdown-type { - /// Similar to `SHUT_RD` in POSIX. - receive, - - /// Similar to `SHUT_WR` in POSIX. - send, - - /// Similar to `SHUT_RDWR` in POSIX. - both, -} - -record ip-resolve-addresses-options { - address-family: option, - include-unavailable: bool, -} - -resource socket { - kind: function() -> expected - - /// TO DISCUSS: Don't want this. - as-udp-socket: function() -> handle udp-socket - - /// TO DISCUSS: Don't want this. - as-tcp-socket: function() -> handle tcp-socket -} - - -/// TO DISCUSS: Want to move these function to their respective module. -resource network { - - /// TO DISCUSS: Want to return a more specific type of socket. - /// - /// Create a new UDP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, 0 or IPPROTO_UDP)` in POSIX. - /// - /// References: - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html - /// - https://man7.org/linux/man-pages/man2/socket.2.html - /// - create-udp-socket: function(address-family: ip-address-family) -> expected - - /// TO DISCUSS: Want to return a more specific type of socket. - /// - /// Create a new TCP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, 0 or IPPROTO_TCP)` in POSIX. - /// - /// References: - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html - /// - https://man7.org/linux/man-pages/man2/socket.2.html - /// - create-tcp-socket: function(address-family: ip-address-family) -> expected - - /// Resolve an internet host name to a list of IP addresses. - /// - /// Parameters: - /// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted - /// to ASCII using IDNA encoding. - /// - `address-family`: If provided, limit the results to addresses of this specific address family. - /// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime - /// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on - /// systems without an active IPv6 interface. Notes: - /// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. - /// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. - /// - /// Results: - /// - When successful, there is always at least one result. - /// - The results are returned in the order the runtime thinks the application should try to connect to first. - /// - Never returns IPv4-mapped IPv6 addresses. - /// - /// Returns EAI_FAIL when `name` is: - /// - empty - /// - an IP address - /// - a syntactically invalid domain name in another way - /// - /// - /// Comparison with getaddrinfo: - /// - /// `getaddrinfo` is very generic and multipurpose by design. This WASI module is *not*. - /// This module focuses strictly on translating internet domain names to ip addresses. - /// That eliminates many of the other "hats" getaddrinfo has, like: - /// - Mapping service names to port numbers ("https" -> 443) - /// - Mapping service names/ports to socket types ("https" -> SOCK_STREAM) - /// - Network interface name translation - /// - IP address deserialization - /// - IP address string canonicalization - /// - Constants lookup for INADDR_ANY, INADDR_LOOPBACK, IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT - /// - /// Almost all of these functionalities can be shimmed in the libc implementation. The exception is network - /// interface name translation. That requires a future `if_nametoindex`-like syscall. - /// - /// This function has a different signature and semantics than `getaddrinfo`. The dissimilar name is chosen to reflect this. - /// - /// References: - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html - /// - https://man7.org/linux/man-pages/man3/getaddrinfo.3.html - /// - resolve-addresses: async function(name: string, options: ip-resolve-addresses-options) -> expected, socket-error> -} - -/// TO DISCUSS: Subtyping. `udp-socket` is a `socket`. -resource udp-socket { - - /// Bind the socket to a specific IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to a send or receive operation will - /// implicitly bind the socket. - /// - /// Returns an error if the socket is already bound. - /// - /// TODO: disallow wildcard binds as long as there isn't a way to pass the local address to send & receive? - /// - https://blog.cloudflare.com/everything-you-ever-wanted-to-know-about-udp-sockets-but-were-afraid-to-ask-part-1/#sourcing-packets-from-a-wildcard-socket - /// - https://blog.powerdns.com/2012/10/08/on-binding-datagram-udp-sockets-to-the-any-addresses/ - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html - /// - https://man7.org/linux/man-pages/man2/bind.2.html - bind: async function(local-address: ip-socket-address) -> expected<_, socket-error> - - /// Get the current bound address. - /// - /// Returns an error if the socket is not bound. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html - /// - https://man7.org/linux/man-pages/man2/getsockname.2.html - local-address: function() -> expected - - /// receive a message. - /// - /// Returns: - /// - The sender address of the datagram - /// - The number of bytes read. - /// - When the received datagram is larger than the provided buffers, - /// the excess data is lost and the `truncated` flag will be set. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html - /// - https://man7.org/linux/man-pages/man2/recv.2.html - receive: async function(iovs: push-buffer) -> expected - - /// receive a message just like `receive`, but don't remove the message from the queue. - peek: async function(iovs: push-buffer) -> expected - - /// send a message to a specific destination address. - /// - /// The remote address option is required. To send a message to the "connected" peer, - /// call `remote-address` to get their address. - /// - /// Returns the number of bytes sent. - /// - /// TODO: Does the returned number of bytes sent ever differ from the supplied buffer size for UDP sockets? - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html - /// - https://man7.org/linux/man-pages/man2/send.2.html - send: async function(iovs: pull-buffer, options: udp-send-options) -> expected - - /// Set the destination address. - /// - /// When a destination address is set: - /// - all receive operations will only return datagrams sent from the provided `remote-address`. - /// - the `send` function can still be used to send to any other destination, however you can't receive their response. - /// - /// Similar to `connect(sock, ...)` in POSIX. - /// - /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". - /// - /// TODO: "connect" is a rather odd name for this function because it doesn't reflect what's actually happening. - /// Feels like it was chosen just to shoehorn UDP into the existing Socket interface. - /// Do we have to keep this name? - /// - /// TODO: add unconnect ability. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html - /// - https://man7.org/linux/man-pages/man2/connect.2.html - connect: async function(remote-address: ip-socket-address) -> expected<_, socket-error> - - /// Get the address set with `connect`. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html - /// - https://man7.org/linux/man-pages/man2/getpeername.2.html - remote-address: function() -> expected -} - - -/// TO DISCUSS: Subtyping. `tcp-socket` is a `socket` && `tcp-socket` is a `io-stream`. -resource tcp-socket { - - /// TO DISCUSS: Don't want this. - as-input-byte-stream: function() -> handle input-byte-stream - - /// TO DISCUSS: Don't want this. - as-output-byte-stream: function() -> handle output-byte-stream - - /// Bind the socket to a specific IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will - /// implicitly bind the socket. - /// - /// Returns an error if the socket is already bound. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html - /// - https://man7.org/linux/man-pages/man2/bind.2.html - bind: async function(local-address: ip-socket-address) -> expected<_, socket-error> - - /// Get the current bound address. - /// - /// Returns an error if the socket is not bound. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html - /// - https://man7.org/linux/man-pages/man2/getsockname.2.html - local-address: function() -> expected - - /// Connect to a remote endpoint. - /// - /// Transitions the socket into the Connection state. - /// Fails when the socket is already in the Connection or Listener state. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html - /// - https://man7.org/linux/man-pages/man2/connect.2.html - connect: async function(remote-address: ip-socket-address) -> expected<_, socket-error> - - /// Start listening for new connections. - /// - /// Transitions the socket into the Listener state. - /// Fails when the socket is already in the Connection or Listener state. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html - /// - https://man7.org/linux/man-pages/man2/listen.2.html - listen: async function(backlog-size-hint: option) -> expected<_, socket-error> - - /// Fails when the socket is not in the Connection state. - /// - /// Read data from the stream just like `InputByteStream::read`, but don't remove the data from the queue. - peek: async function(iovs: push-buffer) -> expected - - /// Fails when the socket is not in the Connection state. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html - /// - https://man7.org/linux/man-pages/man2/getpeername.2.html - remote-address: function() -> expected - - /// Gracefully shut down the connection. - /// - /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read/receive - /// operations will return 0, indicating End Of Stream. If there is still data in the receive queue at time of - /// calling `shutdown` or whenever new data arrives afterwards, then (TODO). - /// - send: the socket is not expecting to send any more data to the peer. After all data in the send queue has - /// been sent and acknowledged, a FIN will be sent. All subsequent write/send operations will return an - /// EPIPE error. - /// - both: receive & send - /// - /// The shutdown function does not close the socket. - /// - /// Fails when the socket is not in the Connection state. - /// - /// TODO: Look into how different platforms behave after shutdown(Read) has been called and new data arrives. According to the internet (unverified): - /// - BSD: silently discards the data - /// - Linux: effectively ignores the shutdown call. New data can still be read. If not done will ultimately block the sender. - /// - Windows: sends RST - /// - /// TODO: Look into how different platforms behave when trying to shut down the same direction multiple times. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html - /// - https://man7.org/linux/man-pages/man2/shutdown.2.html - shutdown: async function(shutdown-type: tcp-shutdown-type) -> expected<_, socket-error> - - /// TO DISCUSS: Want to return a more specific type of socket. - /// - /// Unlike POSIX, this function does not returns the remote address. - /// If you want to know this information, invoke `remote-address` on the newly created socket. - /// - /// Fails when this socket is not in the Listening state. - /// - /// Returns a new bound socket in the Connection state. - /// - /// References: - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html - /// - https://man7.org/linux/man-pages/man2/accept.2.html - accept: async function() -> expected -} - From be776f7eba59fba52520f62d23f3204f63f99247 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Tue, 1 Mar 2022 21:23:57 +0100 Subject: [PATCH 0942/1772] Initial proposal content. Ported from https://github.com/badeend/WASI-Networking --- proposals/sockets/GrantingAccess.md | 95 +++++++++++++++++ proposals/sockets/README.md | 124 +++++++++++++++++----- proposals/sockets/wasi-ip-name-lookup.wit | 20 +--- proposals/sockets/wasi-socket.wit | 5 + 4 files changed, 199 insertions(+), 45 deletions(-) create mode 100644 proposals/sockets/GrantingAccess.md diff --git a/proposals/sockets/GrantingAccess.md b/proposals/sockets/GrantingAccess.md new file mode 100644 index 000000000..d1d993c8f --- /dev/null +++ b/proposals/sockets/GrantingAccess.md @@ -0,0 +1,95 @@ +## Granting access + +This section is mostly here to illustrate the granularity of permissions that ought to be possible. It is by no means a recommendation of any kind. It's just spitballing how a CLI-based implementation might grant network access. + + +```shell + +# Allow TCP connections to any IP address resolved from `example.com` on port 80. This also implies `--allow-resolve=example.com` +--allow-outbound=tcp://example.com:80 + +# Allow listening only on loopback interfaces on port 80 +--allow-inbound=tcp://localhost:80 + + + + + +# Allow the lookup of a specific domain name +--allow-resolve=example.com + +# Allow the lookup of all subdomains +--allow-resolve=*.example.com + +# Allow any lookup +--allow-resolve=* + +# Only look up IPv4 addresses +--allow-resolve=example.com#ipv4-only + +# Only look up IPv6 addresses +--allow-resolve=example.com#ipv6-only + + + + +# Allow TCP connections to 127.0.0.1 on port 80 +--allow-outbound=tcp://127.0.0.1:80 + +# Allow TCP connections to 127.0.0.1 on any port +--allow-outbound=tcp://127.0.0.1:* + +# Allow TCP connections to any server on port 80 +--allow-outbound=tcp://*:80 + +# Allow all TCP connections +--allow-outbound=tcp://*:* + +# Allow TCP connection with IPv4 only +--allow-outbound=tcp://...#ipv4-only + +# Allow TCP connection with IPv6 only +--allow-outbound=tcp://...#ipv6-only + +# Allow TCP connections to a specific list of ports +--allow-outbound=tcp://*:80,443 + +# Allow TCP connections to a range of ports +--allow-outbound=tcp://*:21,35000-35999 + +# Allow UDP client +--allow-outbound=udp://... + + + + +# Allow listening on a specific network interface on port 80 +--allow-inbound=tcp://eth0:80 + +# Allow listening on any network interface on port 80 +--allow-inbound=tcp://*:80 + +# Allow listening on a randomly generated port +--allow-inbound=tcp://*:0 + +``` + +### Virtualization / mapping + +Just like wasmtime already has the ability to remap directories with `--mapdir`, similar constructs can be conceived for networking. Examples: + +_Again: not an official recommendation of any kind._ + +```shell + +# Map a domain name resolvable from within the wasm module to an IP address. +--allow-resolve=my-database.internal->172.17.0.14 + +# Allow listening to TCP port 80 inside the wasm module, which is mapped to port 8888 on the host. +--allow-inbound=tcp://*:80->8888 + +# Allow TCP connections to any IP address resolved from `my-database.internal` which is mapped to `172.17.0.14` on +# port 5432 which is mapped to 5433. This also implies `--allow-resolve=my-database.internal->172.17.0.14` +--allow-outbound=tcp://my-database.internal->172.17.0.14:5432->5433 + +``` \ No newline at end of file diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 303e2b18e..4915b41df 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -1,12 +1,4 @@ -# [Example WASI proposal] - -This template can be used to start a new proposal, which can then be proposed in the WASI Subgroup meetings. - -The sections below are recommended. However, every proposal is different, and the community can help you flesh out the proposal, so don't block on having something filled in for each one of them. - -Thank you to the W3C Privacy CG for the [inspiration](https://github.com/privacycg/template)! - -# [Title] +# [WASI Sockets] A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. @@ -20,19 +12,23 @@ Phase 1 ### Phase 4 Advancement Criteria -TODO before entering Phase 2. +- At least two independent production implementations. +- Implementations available for at least Windows, Linux & MacOS. +- A testsuite that passes on the platforms and implementations mentioned above. ## Table of Contents [if the explainer is longer than one printed page] - [Introduction](#introduction) -- [Goals [or Motivating Use Cases, or Scenarios]](#goals-or-motivating-use-cases-or-scenarios) +- [Goals](#goals-or-motivating-use-cases-or-scenarios) - [Non-goals](#non-goals) - [API walk-through](#api-walk-through) - [Use case 1](#use-case-1) - [Use case 2](#use-case-2) - [Detailed design discussion](#detailed-design-discussion) - - [[Tricky design choice 1]](#tricky-design-choice-1) - - [[Tricky design choice 2]](#tricky-design-choice-2) + - [Dualstack sockets](#dualstack-sockets) + - [Modularity](#modularity) + - [POSIX compatibility](#posix-compatibility) + - [Why not getaddrinfo?](#why-not-getaddrinfo) - [Considered alternatives](#considered-alternatives) - [[Alternative 1]](#alternative-1) - [[Alternative 2]](#alternative-2) @@ -41,45 +37,119 @@ TODO before entering Phase 2. ### Introduction -[The "executive summary" or "abstract". Explain in a few sentences what the goals of the project are, and a brief overview of how the solution works. This should be no more than 1-2 paragraphs.] +This proposal adds TCP & UDP sockets and domain name lookup to WASI. It adds the basic BSD socket interface with the intent to enable server and client networking software running on WebAssembly. + +Unlike BSD sockets, WASI sockets require capability handles to create sockets and perform domain name lookups. On top of capability handles, WASI Socket implementations should implement deny-by-default firewalling. -### Goals [or Motivating Use Cases, or Scenarios] +The socket APIs have been split up into standalone protocol-specific WASI modules. Both current and future socket modules can then be tailored to the needs of that specific protocol and progress the standardization process independently. -[What is the end-user need which this project aims to address?] +This proposal introduces 4 new WASI modules: +- [wasi-socket.wit](./wasi-socket.wit) +- [wasi-socket-tcp.wit](./wasi-socket-tcp.wit) +- [wasi-socket-udp.wit](./wasi-socket-udp.wit) +- [wasi-ip-name-lookup.wit](./wasi-ip-name-lookup.wit) + +### Goals + +- Start out as an MVP; add the bare minimum amount of APIs required to create a basic functioning TCP/UDP application. +- Toolchains must be able to provide a POSIX compatible interface on top of the functions introduced in this proposal. ### Non-goals -[If there are "adjacent" goals which may appear to be in scope but aren't, enumerate them here. This section may be fleshed out as your design progresses and you encounter necessary technical and other trade-offs.] +- SSL/TLS support +- HTTP(S) support +- Retrieving network-related information of the executing machine, like: installed network interfaces and the computer hostname. ### API walk-through [Walk through of how someone would use this API.] -#### [Use case 1] +#### Use case: Wasm module per connection -[Provide example code snippets and diagrams explaining how the API would be used to solve the given problem] +Due to the low startup cost of Wasm modules, its feasible for server software with Wasm integration to spawn a Wasm module for each inbound connection. Each module instance is passed only the accepted client socket. This way, all connection handlers are completely isolated from each other. This resembles PHP's "shared nothing" architecture. #### [Use case 2] -[etc.] +[Provide example code snippets and diagrams explaining how the API would be used to solve the given problem] ### Detailed design discussion [This section should mostly refer to the .wit.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] -#### [Tricky design choice #1] +#### Dualstack sockets -[Talk through the tradeoffs in coming to the specific design point you want to make.] +IPv6 sockets returned by this proposal are never dualstack because that can't easily be implemented in a cross platform manner. If an application wants to serve both IPv4 and IPv6 traffic, it should create two sockets; one for IPv4 traffic and one for IPv6 traffic. -``` -// Illustrated with example code. +This behaviour is deemed acceptable because all existing applications that are truly cross-platform must already handle this scenario. Dualstack support can be part of a future proposal adding it as an opt-in feature. + +Related issue: [Emulate dualstack sockets in userspace](https://github.com/WebAssembly/wasi-sockets/issues/1) + +#### Modularity + +This proposal is not POSIX compatible by itself. The BSD sockets interface is highly generic. The same functions have different semantics depending on which kind of socket they're called on. The man-pages are riddled with conditional documentation. If this had been translated 1:1 into a WASI API using Interface Types, this would have resulted in a proliferation of optional parameters and result types. + +Instead, the sockets API has been split up into protocol-specific modules. All BSD socket functions have been pushed into these protocol-specific modules and tailored to their specific needs. Functions, parameters and flags that did not apply within a specific context have been dropped. + +A downside of this approach is that functions that do *not* differ per protocol (bind, local_address, connect, shutdown, ...) are duplicated as well. + +#### POSIX compatibility + +The [wasi-socket](./wasi-socket.wit) module exports a `kind` function that can be called on any kind of socket. +The return value can be used to dispatch calls to the correct WASI module. + +In pseudo code: + +```rs +fn socket(address_family: i32, socket_type: i32, protocol: i32) { + + let ambient_network_capability = // Pluck it out of thin air. + + match (socket_type, protocol) { + (SOCK_STREAM, 0) => wasi_socket_tcp::create_tcp_socket(ambient_network_capability, address_family), + (SOCK_DGRAM, 0) => wasi_socket_udp::create_udp_socket(ambient_network_capability, address_family), + _ => EINVAL, + } +} + +fn recvfrom(socket: i32, flags: i32) { + + let kind = wasi_socket::kind(socket); + let peek = flags & MSG_PEEK; + + match (kind, peek) { + (Udp, false) => wasi_socket_udp::receive_from(socket), + (Udp, true) => wasi_socket_udp::peek_from(socket), + (Tcp, false) => (wasi_io_streams::read(socket), address: 0, truncated: false), + (Tcp, true) => (wasi_socket_tcp::peek(socket), address: 0, truncated: false), + _ => EBADF, + } +} ``` -[This may be an open question, in which case you should link to any active discussion threads.] -#### [Tricky design choice 2] +#### Why not getaddrinfo? + +The proposed [wasi-ip-name-lookup](./wasi-ip-name-lookup.wit) module focuses strictly on translating internet domain names to ip addresses and nothing else. + +Like BSD sockets, `getaddrinfo` is very generic and multipurpose by design. The proposed WASI API is *not*. This eliminates many of the other "hats" getaddrinfo has (and potential security holes), like: +- Mapping service names to port numbers (`"https"` -> `443`) +- Mapping service names/ports to socket types (`"https"` -> `SOCK_STREAM`) +- Network interface name translation (`%eth0` -> `1`) +- IP address deserialization (`"127.0.0.1"` -> `Ipv4Address(127, 0, 0, 1)`) +- IP address string canonicalization (`"0:0:0:0:0:0:0:1"` -> `"::1"`) +- Constants lookup for `INADDR_ANY`, `INADDR_LOOPBACK`, `IN6ADDR_ANY_INIT` and `IN6ADDR_LOOPBACK_INIT`. + +Many of these functionalities can be shimmed in the libc implementation. Though some require future WASI additions. An example is network interface name translation. That requires a future `if_nametoindex`-like syscall. + + +#### Security + +Wasm modules can not open sockets by themselves without a network capability handle. Even with capability handles, WASI implementations should deny all network access by default. Access should be granted at the most granular level possible. See [Granting Access](./GrantingAccess.md) for examples. Whenever access is denied, the implementation should return EACCES. + +This means Wasm modules will get a lot more EACCES errors compared to when running unsandboxed. This might break existing applications that, for example, don't expect creating a TCP client to require special permissions. + +At the moment there is no way for a Wasm modules to query which network access permissions it has. The only thing it can do, is to just call the WASI functions it needs and see if they fail. -[etc.] ### Considered alternatives diff --git a/proposals/sockets/wasi-ip-name-lookup.wit b/proposals/sockets/wasi-ip-name-lookup.wit index 19f8e5030..7afd5d04e 100644 --- a/proposals/sockets/wasi-ip-name-lookup.wit +++ b/proposals/sockets/wasi-ip-name-lookup.wit @@ -8,6 +8,8 @@ record resolve-addresses-options { /// Resolve an internet host name to a list of IP addresses. /// +/// See the proposal README.md for a comparison with getaddrinfo. +/// /// Parameters: /// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted /// to ASCII using IDNA encoding. @@ -28,24 +30,6 @@ record resolve-addresses-options { /// - an IP address /// - a syntactically invalid domain name in another way /// -/// -/// Comparison with getaddrinfo: -/// -/// `getaddrinfo` is very generic and multipurpose by design. This WASI module is *not*. -/// This module focuses strictly on translating internet domain names to ip addresses. -/// That eliminates many of the other "hats" getaddrinfo has, like: -/// - Mapping service names to port numbers ("https" -> 443) -/// - Mapping service names/ports to socket types ("https" -> SOCK_STREAM) -/// - Network interface name translation -/// - IP address deserialization -/// - IP address string canonicalization -/// - Constants lookup for INADDR_ANY, INADDR_LOOPBACK, IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT -/// -/// Almost all of these functionalities can be shimmed in the libc implementation. The exception is network -/// interface name translation. That requires a future `if_nametoindex`-like syscall. -/// -/// This function has a different signature and semantics than `getaddrinfo`. The dissimilar name is chosen to reflect this. -/// /// References: /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html /// - https://man7.org/linux/man-pages/man3/getaddrinfo.3.html diff --git a/proposals/sockets/wasi-socket.wit b/proposals/sockets/wasi-socket.wit index 183c7c742..e5094a024 100644 --- a/proposals/sockets/wasi-socket.wit +++ b/proposals/sockets/wasi-socket.wit @@ -10,4 +10,9 @@ enum socket-kind { resource socket {} + +/// Get the type of the socket. +/// +/// When this function does not return an error, the argument is guaranteed to be a socket. +/// Note: `socket-kind::unknown` is not an error. kind: function(any-socket: handle socket) -> expected \ No newline at end of file From 5cf7818daa55299d24218586858b8867a3188f9a Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Tue, 1 Mar 2022 21:37:01 +0100 Subject: [PATCH 0943/1772] Removed unnecessary template artifacts --- proposals/sockets/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 4915b41df..964abd540 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -1,4 +1,4 @@ -# [WASI Sockets] +# WASI Sockets A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. @@ -16,10 +16,10 @@ Phase 1 - Implementations available for at least Windows, Linux & MacOS. - A testsuite that passes on the platforms and implementations mentioned above. -## Table of Contents [if the explainer is longer than one printed page] +## Table of Contents - [Introduction](#introduction) -- [Goals](#goals-or-motivating-use-cases-or-scenarios) +- [Goals](#goals) - [Non-goals](#non-goals) - [API walk-through](#api-walk-through) - [Use case 1](#use-case-1) @@ -66,7 +66,7 @@ This proposal introduces 4 new WASI modules: #### Use case: Wasm module per connection -Due to the low startup cost of Wasm modules, its feasible for server software with Wasm integration to spawn a Wasm module for each inbound connection. Each module instance is passed only the accepted client socket. This way, all connection handlers are completely isolated from each other. This resembles PHP's "shared nothing" architecture. +Thanks to the low startup cost of Wasm modules, its feasible for server software with Wasm integration to spawn a Wasm module for each inbound connection. Each module instance is passed only the accepted client socket. This way, all connection handlers are completely isolated from each other. This resembles PHP's "shared nothing" architecture. #### [Use case 2] From 65f25de08f8968127bb69d548c42082c5f1b5f00 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 2 Mar 2022 21:15:35 +0100 Subject: [PATCH 0944/1772] These options objects only existed because I anticipated future additions. However, the parameter lists themselves can most likely also be added to without breaking backwards compatibility. --- proposals/sockets/wasi-ip-name-lookup.wit | 7 +------ proposals/sockets/wasi-socket-udp.wit | 9 +-------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/proposals/sockets/wasi-ip-name-lookup.wit b/proposals/sockets/wasi-ip-name-lookup.wit index 7afd5d04e..0072b9ecc 100644 --- a/proposals/sockets/wasi-ip-name-lookup.wit +++ b/proposals/sockets/wasi-ip-name-lookup.wit @@ -1,11 +1,6 @@ use { error, ip-address, ip-address-family } from common-types use { network } from wasi-network -record resolve-addresses-options { - address-family: option, - include-unavailable: bool, -} - /// Resolve an internet host name to a list of IP addresses. /// /// See the proposal README.md for a comparison with getaddrinfo. @@ -34,4 +29,4 @@ record resolve-addresses-options { /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html /// - https://man7.org/linux/man-pages/man3/getaddrinfo.3.html /// -resolve-addresses: async function(name: string, options: resolve-addresses-options) -> expected, error> \ No newline at end of file +resolve-addresses: async function(name: string, address-family: option, include-unavailable: bool) -> expected, error> \ No newline at end of file diff --git a/proposals/sockets/wasi-socket-udp.wit b/proposals/sockets/wasi-socket-udp.wit index 568998750..18500bdd3 100644 --- a/proposals/sockets/wasi-socket-udp.wit +++ b/proposals/sockets/wasi-socket-udp.wit @@ -19,13 +19,6 @@ record receive-result { /// ecn: u2, // IP_RECVTOS } -record send-options { - remote-address: ip-socket-address, - - /// Possible future additions: - /// local-address: ip-socket-address, // IP_PKTINFO / IP_SENDSRCADDR / IPV6_PKTINFO -} - /// Create a new UDP socket. /// @@ -96,7 +89,7 @@ peek: async function(udp-socket: handle socket, iovs: push-buffer) -> expect /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html /// - https://man7.org/linux/man-pages/man2/send.2.html -send: async function(udp-socket: handle socket, iovs: pull-buffer, options: send-options) -> expected +send: async function(udp-socket: handle socket, iovs: pull-buffer, remote-address: ip-socket-address) -> expected /// Set the destination address. /// From 85ee594109a2677c1c02d87cfa06d1b603b1c36c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 15 Mar 2022 21:27:58 -0700 Subject: [PATCH 0945/1772] Update to the latest wit-bindgen naming convention. As of bytecodealliance/wit-bindgen#123, wit-bindgen now uses '%' as a leading character to disambiguate identifiers from keywords. --- proposals/filesystem/wasi-filesystem.wit.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 661f00cbb..51cc1ac1b 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -47,9 +47,9 @@ type timestamp = u64 /// Note: This was called `fdstat` in earlier versions of WASI. record info { /// The type of filesystem object referenced by a descriptor. - "type": "type", + %type: %type, /// Flags associated with a descriptor. - "flags": "flags", + %flags: %flags, } ``` @@ -58,7 +58,7 @@ record info { /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. -enum "type" { +enum %type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. unknown, @@ -84,7 +84,7 @@ enum "type" { /// Descriptor flags. /// /// Note: This was called `fd-flags` in earlier versions of WASI. -flags "flags" { +flags %flags { /// Read mode: Data can be read. read, /// Write mode: Data can be written to. @@ -117,7 +117,7 @@ record stat { /// File serial number. ino: inode, /// File type. - "type": "type", + %type: %type, /// Number of hard links to the file. nlink: linkcount, /// For regular files, the file size in bytes. For symbolic links, the length @@ -214,7 +214,7 @@ record dirent { /// The length of the name of the directory entry. namelen: size, /// The type of the file referred to by this directory entry. - "type": "type", + %type: %type, } ``` @@ -564,7 +564,7 @@ readdir: function( /// Note: This is similar to `lseek` in POSIX. seek: function( /// The method to compute the new offset. - "from": seek-from, + %from: seek-from, ) -> ( /// The new offset of the descriptor, relative to the start of the file. expected @@ -685,7 +685,7 @@ open-at: function( /// The method by which to open the file. o-flags: o-flags, /// Flags to use for the resulting descriptor. - fd-flags: "flags", + fd-flags: %flags, /// Permissions to use when creating a new file. mode: mode ) -> ( From 04e347163d000524c1c0e7f7b54efea7b71525e8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 15 Mar 2022 21:34:09 -0700 Subject: [PATCH 0946/1772] Update to wit-abi-up-to-date v2. --- proposals/filesystem/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index b33a451b8..f27c0a23b 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v1 + - uses: WebAssembly/wit-abi-up-to-date@v2 with: wit-abi-tag: wit-abi-0.1.0 From ee2ea1c97ad1633f8aa1fe1e056e3a9d83b6a1e0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 15 Mar 2022 21:39:29 -0700 Subject: [PATCH 0947/1772] Fix documentation comment syntax. --- proposals/filesystem/wasi-filesystem.wit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 51cc1ac1b..d6e30f000 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -536,7 +536,7 @@ read: function( /// directory entries. Each directory entry consists of a `dirent` object, /// followed by `dirent::d_namlen` bytes holding the name of the directory /// entry. -// +/// /// This function fills the output buffer as much as possible, potentially /// truncating the last directory entry. This allows the caller to grow its /// read buffer size in case it's too small to fit a single large directory From b30bc61c6264ba53b85fdf9d9fdef8c5703f6dc7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 28 Apr 2022 13:52:28 -0700 Subject: [PATCH 0948/1772] Port the wasi-clocks API to the new wit format. This converts the wasi-clocks repository to the new [proposal template] format. It also includes a number of minor updates: - It fixes #1, the year 2554 problem, by making the wall clock return a seconds plus nanoseconds pair. - It fixes #4, by converting clocks to wit resources. - It fixes #5, by eliminating the use of errno error codes. - It addresses #8 and #9 by proposing they be out of scope for the current proposal; see those issues for discussion. [proposal template]: https://github.com/linclark/wasi-proposal-template --- proposals/clocks/.github/workflows/main.yml | 53 +- proposals/clocks/.gitignore | 11 - proposals/clocks/Charter.md | 55 - proposals/clocks/Contributing.md | 8 - proposals/clocks/README.md | 130 +- proposals/clocks/WASI.png | Bin 11059 -> 0 bytes proposals/clocks/design/application-abi.md | 60 - proposals/clocks/design/optional-imports.md | 108 - proposals/clocks/docs/DesignPrinciples.md | 291 -- proposals/clocks/docs/HighLevelGoals.md | 25 - proposals/clocks/docs/Process.md | 37 - proposals/clocks/docs/Proposals.md | 64 - proposals/clocks/docs/README.md | 15 - proposals/clocks/docs/WASI-overview.md | 147 - .../docs/wasi-software-architecture.png | Bin 28267 -> 0 bytes proposals/clocks/docs/witx.md | 30 - proposals/clocks/meetings/2019/WASI-05-02.md | 377 --- proposals/clocks/meetings/2019/WASI-05-16.md | 291 -- proposals/clocks/meetings/2019/WASI-05-30.md | 116 - proposals/clocks/meetings/2019/WASI-06-27.md | 241 -- proposals/clocks/meetings/2019/WASI-07-18.md | 262 -- proposals/clocks/meetings/2019/WASI-08-15.md | 121 - proposals/clocks/meetings/2019/WASI-08-30.md | 64 - proposals/clocks/meetings/2019/WASI-09-12.md | 92 - proposals/clocks/meetings/2019/WASI-09-26.md | 60 - proposals/clocks/meetings/2019/WASI-10-15.md | 116 - proposals/clocks/meetings/2019/WASI-10-24.md | 171 -- proposals/clocks/meetings/2019/WASI-11-07.md | 102 - proposals/clocks/meetings/2019/WASI-11-21.md | 63 - proposals/clocks/meetings/2019/WASI-12-05.md | 124 - proposals/clocks/meetings/2019/WASI-12-19.md | 44 - .../2019/What HTTP Needs from WebAssembly.pdf | Bin 82687 -> 0 bytes proposals/clocks/meetings/2020/WASI-01-16.md | 123 - proposals/clocks/meetings/2020/WASI-02-27.md | 92 - proposals/clocks/meetings/2020/WASI-03-12.md | 85 - proposals/clocks/meetings/2020/WASI-03-26.md | 126 - proposals/clocks/meetings/2020/WASI-04-09.md | 83 - proposals/clocks/meetings/2020/WASI-05-07.md | 89 - proposals/clocks/meetings/2020/WASI-05-21.md | 99 - proposals/clocks/meetings/2020/WASI-06-04.md | 43 - proposals/clocks/meetings/2020/WASI-07-02.md | 41 - proposals/clocks/meetings/2020/WASI-07-16.md | 41 - proposals/clocks/meetings/2020/WASI-07-30.md | 36 - proposals/clocks/meetings/2020/WASI-08-27.md | 42 - proposals/clocks/meetings/2020/WASI-09-10.md | 33 - proposals/clocks/meetings/2020/WASI-09-24.md | 30 - proposals/clocks/meetings/2020/WASI-10-08.md | 42 - proposals/clocks/meetings/2020/WASI-10-22.md | 211 -- proposals/clocks/meetings/2020/WASI-11-19.md | 153 - proposals/clocks/meetings/2020/WASI-12-03.md | 130 - proposals/clocks/meetings/2021/WASI-01-14.md | 75 - proposals/clocks/meetings/2021/WASI-01-28.md | 206 -- proposals/clocks/meetings/2021/WASI-02-11.md | 118 - proposals/clocks/meetings/2021/WASI-02-25.md | 131 - proposals/clocks/meetings/2021/WASI-03-11.md | 32 - proposals/clocks/meetings/2021/WASI-03-25.md | 31 - proposals/clocks/meetings/2021/WASI-04-08.md | 31 - proposals/clocks/meetings/2021/WASI-04-22.md | 31 - proposals/clocks/meetings/2021/WASI-05-06.md | 31 - proposals/clocks/meetings/2021/WASI-05-20.md | 31 - proposals/clocks/meetings/2021/WASI-06-03.md | 31 - proposals/clocks/meetings/2021/WASI-06-17.md | 31 - proposals/clocks/meetings/README.md | 61 - proposals/clocks/phases/README.md | 50 - proposals/clocks/phases/ephemeral/docs.md | 2562 ----------------- .../phases/ephemeral/witx/typenames.witx | 708 ----- .../ephemeral/witx/wasi_ephemeral_args.witx | 27 - .../ephemeral/witx/wasi_ephemeral_clock.witx | 35 - .../witx/wasi_ephemeral_environ.witx | 27 - .../ephemeral/witx/wasi_ephemeral_fd.witx | 259 -- .../ephemeral/witx/wasi_ephemeral_path.witx | 181 -- .../ephemeral/witx/wasi_ephemeral_poll.witx | 27 - .../ephemeral/witx/wasi_ephemeral_proc.witx | 22 - .../ephemeral/witx/wasi_ephemeral_random.witx | 26 - .../ephemeral/witx/wasi_ephemeral_sched.witx | 16 - .../ephemeral/witx/wasi_ephemeral_sock.witx | 48 - .../clocks/phases/old/snapshot_0/docs.md | 2512 ---------------- .../phases/old/snapshot_0/witx/typenames.witx | 746 ----- .../old/snapshot_0/witx/wasi_unstable.witx | 513 ---- proposals/clocks/phases/snapshot/docs.html | 1279 -------- proposals/clocks/phases/snapshot/docs.md | 2509 ---------------- .../phases/snapshot/witx/typenames.witx | 748 ----- .../snapshot/witx/wasi_snapshot_preview1.witx | 510 ---- proposals/clocks/proposal-template/README.md | 4 - proposals/clocks/proposals/README.md | 8 - proposals/clocks/snapshots/README.md | 5 - proposals/clocks/snapshots/make-snapshot.sh | 159 - proposals/clocks/standard/README.md | 12 - proposals/clocks/standard/wasi-clocks/docs.md | 1266 -------- .../standard/wasi-clocks/witx/clocks.witx | 35 - .../standard/wasi-clocks/witx/typenames.witx | 708 ----- proposals/clocks/test/README.md | 11 + proposals/clocks/tools/repo_docs.sh | 22 - proposals/clocks/tools/witx/.gitignore | 2 - proposals/clocks/tools/witx/Cargo.toml | 32 - proposals/clocks/tools/witx/LICENSE | 13 - proposals/clocks/tools/witx/cli/Cargo.toml | 25 - proposals/clocks/tools/witx/cli/src/main.rs | 268 -- proposals/clocks/tools/witx/src/abi.rs | 925 ------ proposals/clocks/tools/witx/src/ast.rs | 591 ---- proposals/clocks/tools/witx/src/docs/ast.rs | 503 ---- proposals/clocks/tools/witx/src/docs/md.rs | 480 --- proposals/clocks/tools/witx/src/docs/mod.rs | 87 - proposals/clocks/tools/witx/src/io.rs | 103 - proposals/clocks/tools/witx/src/layout.rs | 219 -- proposals/clocks/tools/witx/src/lib.rs | 97 - proposals/clocks/tools/witx/src/parser.rs | 778 ----- proposals/clocks/tools/witx/src/polyfill.rs | 255 -- proposals/clocks/tools/witx/src/render.rs | 320 -- .../clocks/tools/witx/src/representation.rs | 161 -- proposals/clocks/tools/witx/src/toplevel.rs | 166 -- proposals/clocks/tools/witx/src/validate.rs | 722 ----- proposals/clocks/tools/witx/tests/witxt.rs | 656 ----- .../clocks/tools/witx/tests/witxt/abi.witxt | 490 ---- .../tools/witx/tests/witxt/anonymous.witxt | 56 - .../tools/witx/tests/witxt/multimodule.witxt | 22 - .../tests/witxt/multimodule/redefine_a.witx | 1 - .../witx/tests/witxt/multimodule/type_a.witx | 1 - .../witx/tests/witxt/multimodule/type_b.witx | 2 - .../witx/tests/witxt/multimodule/type_c.witx | 2 - .../witx/tests/witxt/representation.witxt | 60 - .../tools/witx/tests/witxt/shorthand.witxt | 59 - .../tools/witx/tests/witxt/simple.witxt | 12 - .../clocks/tools/witx/tests/witxt/union.witxt | 97 - .../clocks/tools/witx/tests/witxt/wasi.witxt | 26 - proposals/clocks/wasi-clocks.abi.md | 0 proposals/clocks/wasi-clocks.wit.md | 81 + 127 files changed, 209 insertions(+), 27755 deletions(-) delete mode 100644 proposals/clocks/.gitignore delete mode 100644 proposals/clocks/Charter.md delete mode 100644 proposals/clocks/Contributing.md delete mode 100644 proposals/clocks/WASI.png delete mode 100644 proposals/clocks/design/application-abi.md delete mode 100644 proposals/clocks/design/optional-imports.md delete mode 100644 proposals/clocks/docs/DesignPrinciples.md delete mode 100644 proposals/clocks/docs/HighLevelGoals.md delete mode 100644 proposals/clocks/docs/Process.md delete mode 100644 proposals/clocks/docs/Proposals.md delete mode 100644 proposals/clocks/docs/README.md delete mode 100644 proposals/clocks/docs/WASI-overview.md delete mode 100644 proposals/clocks/docs/wasi-software-architecture.png delete mode 100644 proposals/clocks/docs/witx.md delete mode 100644 proposals/clocks/meetings/2019/WASI-05-02.md delete mode 100644 proposals/clocks/meetings/2019/WASI-05-16.md delete mode 100644 proposals/clocks/meetings/2019/WASI-05-30.md delete mode 100644 proposals/clocks/meetings/2019/WASI-06-27.md delete mode 100644 proposals/clocks/meetings/2019/WASI-07-18.md delete mode 100644 proposals/clocks/meetings/2019/WASI-08-15.md delete mode 100644 proposals/clocks/meetings/2019/WASI-08-30.md delete mode 100644 proposals/clocks/meetings/2019/WASI-09-12.md delete mode 100644 proposals/clocks/meetings/2019/WASI-09-26.md delete mode 100644 proposals/clocks/meetings/2019/WASI-10-15.md delete mode 100644 proposals/clocks/meetings/2019/WASI-10-24.md delete mode 100644 proposals/clocks/meetings/2019/WASI-11-07.md delete mode 100644 proposals/clocks/meetings/2019/WASI-11-21.md delete mode 100644 proposals/clocks/meetings/2019/WASI-12-05.md delete mode 100644 proposals/clocks/meetings/2019/WASI-12-19.md delete mode 100644 proposals/clocks/meetings/2019/What HTTP Needs from WebAssembly.pdf delete mode 100644 proposals/clocks/meetings/2020/WASI-01-16.md delete mode 100644 proposals/clocks/meetings/2020/WASI-02-27.md delete mode 100644 proposals/clocks/meetings/2020/WASI-03-12.md delete mode 100644 proposals/clocks/meetings/2020/WASI-03-26.md delete mode 100644 proposals/clocks/meetings/2020/WASI-04-09.md delete mode 100644 proposals/clocks/meetings/2020/WASI-05-07.md delete mode 100644 proposals/clocks/meetings/2020/WASI-05-21.md delete mode 100644 proposals/clocks/meetings/2020/WASI-06-04.md delete mode 100644 proposals/clocks/meetings/2020/WASI-07-02.md delete mode 100644 proposals/clocks/meetings/2020/WASI-07-16.md delete mode 100644 proposals/clocks/meetings/2020/WASI-07-30.md delete mode 100644 proposals/clocks/meetings/2020/WASI-08-27.md delete mode 100644 proposals/clocks/meetings/2020/WASI-09-10.md delete mode 100644 proposals/clocks/meetings/2020/WASI-09-24.md delete mode 100644 proposals/clocks/meetings/2020/WASI-10-08.md delete mode 100644 proposals/clocks/meetings/2020/WASI-10-22.md delete mode 100644 proposals/clocks/meetings/2020/WASI-11-19.md delete mode 100644 proposals/clocks/meetings/2020/WASI-12-03.md delete mode 100644 proposals/clocks/meetings/2021/WASI-01-14.md delete mode 100644 proposals/clocks/meetings/2021/WASI-01-28.md delete mode 100644 proposals/clocks/meetings/2021/WASI-02-11.md delete mode 100644 proposals/clocks/meetings/2021/WASI-02-25.md delete mode 100644 proposals/clocks/meetings/2021/WASI-03-11.md delete mode 100644 proposals/clocks/meetings/2021/WASI-03-25.md delete mode 100644 proposals/clocks/meetings/2021/WASI-04-08.md delete mode 100644 proposals/clocks/meetings/2021/WASI-04-22.md delete mode 100644 proposals/clocks/meetings/2021/WASI-05-06.md delete mode 100644 proposals/clocks/meetings/2021/WASI-05-20.md delete mode 100644 proposals/clocks/meetings/2021/WASI-06-03.md delete mode 100644 proposals/clocks/meetings/2021/WASI-06-17.md delete mode 100644 proposals/clocks/meetings/README.md delete mode 100644 proposals/clocks/phases/README.md delete mode 100644 proposals/clocks/phases/ephemeral/docs.md delete mode 100644 proposals/clocks/phases/ephemeral/witx/typenames.witx delete mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx delete mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx delete mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx delete mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx delete mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx delete mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx delete mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx delete mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx delete mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sched.witx delete mode 100644 proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sock.witx delete mode 100644 proposals/clocks/phases/old/snapshot_0/docs.md delete mode 100644 proposals/clocks/phases/old/snapshot_0/witx/typenames.witx delete mode 100644 proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx delete mode 100644 proposals/clocks/phases/snapshot/docs.html delete mode 100644 proposals/clocks/phases/snapshot/docs.md delete mode 100644 proposals/clocks/phases/snapshot/witx/typenames.witx delete mode 100644 proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx delete mode 100644 proposals/clocks/proposal-template/README.md delete mode 100644 proposals/clocks/proposals/README.md delete mode 100644 proposals/clocks/snapshots/README.md delete mode 100755 proposals/clocks/snapshots/make-snapshot.sh delete mode 100644 proposals/clocks/standard/README.md delete mode 100644 proposals/clocks/standard/wasi-clocks/docs.md delete mode 100644 proposals/clocks/standard/wasi-clocks/witx/clocks.witx delete mode 100644 proposals/clocks/standard/wasi-clocks/witx/typenames.witx create mode 100644 proposals/clocks/test/README.md delete mode 100755 proposals/clocks/tools/repo_docs.sh delete mode 100644 proposals/clocks/tools/witx/.gitignore delete mode 100644 proposals/clocks/tools/witx/Cargo.toml delete mode 100644 proposals/clocks/tools/witx/LICENSE delete mode 100644 proposals/clocks/tools/witx/cli/Cargo.toml delete mode 100644 proposals/clocks/tools/witx/cli/src/main.rs delete mode 100644 proposals/clocks/tools/witx/src/abi.rs delete mode 100644 proposals/clocks/tools/witx/src/ast.rs delete mode 100644 proposals/clocks/tools/witx/src/docs/ast.rs delete mode 100644 proposals/clocks/tools/witx/src/docs/md.rs delete mode 100644 proposals/clocks/tools/witx/src/docs/mod.rs delete mode 100644 proposals/clocks/tools/witx/src/io.rs delete mode 100644 proposals/clocks/tools/witx/src/layout.rs delete mode 100644 proposals/clocks/tools/witx/src/lib.rs delete mode 100644 proposals/clocks/tools/witx/src/parser.rs delete mode 100644 proposals/clocks/tools/witx/src/polyfill.rs delete mode 100644 proposals/clocks/tools/witx/src/render.rs delete mode 100644 proposals/clocks/tools/witx/src/representation.rs delete mode 100644 proposals/clocks/tools/witx/src/toplevel.rs delete mode 100644 proposals/clocks/tools/witx/src/validate.rs delete mode 100644 proposals/clocks/tools/witx/tests/witxt.rs delete mode 100644 proposals/clocks/tools/witx/tests/witxt/abi.witxt delete mode 100644 proposals/clocks/tools/witx/tests/witxt/anonymous.witxt delete mode 100644 proposals/clocks/tools/witx/tests/witxt/multimodule.witxt delete mode 100644 proposals/clocks/tools/witx/tests/witxt/multimodule/redefine_a.witx delete mode 100644 proposals/clocks/tools/witx/tests/witxt/multimodule/type_a.witx delete mode 100644 proposals/clocks/tools/witx/tests/witxt/multimodule/type_b.witx delete mode 100644 proposals/clocks/tools/witx/tests/witxt/multimodule/type_c.witx delete mode 100644 proposals/clocks/tools/witx/tests/witxt/representation.witxt delete mode 100644 proposals/clocks/tools/witx/tests/witxt/shorthand.witxt delete mode 100644 proposals/clocks/tools/witx/tests/witxt/simple.witxt delete mode 100644 proposals/clocks/tools/witx/tests/witxt/union.witxt delete mode 100644 proposals/clocks/tools/witx/tests/witxt/wasi.witxt create mode 100644 proposals/clocks/wasi-clocks.abi.md create mode 100644 proposals/clocks/wasi-clocks.wit.md diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 0305f7f32..f27c0a23b 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -1,47 +1,16 @@ name: CI -on: [push, pull_request] +on: + push: + branches: [main] + pull_request: + branches: [main] jobs: - test: - name: Test witx tools - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - steps: - - uses: actions/checkout@v1 - - name: Install Rust (rustup) - shell: bash - run: rustup update stable --no-self-update && rustup default stable - if: matrix.os != 'macos-latest' - - name: Install Rust (macos) - run: | - curl https://sh.rustup.rs | sh -s -- -y - echo "$HOME/.cargo/bin" >> $GITHUB_PATH - if: matrix.os == 'macos-latest' - - run: cargo fetch - working-directory: tools/witx - - run: cargo test --all - working-directory: tools/witx - - validate: - name: Validate witx files and docs - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Install Rust (rustup) - shell: bash - run: rustup update stable --no-self-update && rustup default stable - - - name: Check that repository docs reflect witx - run: ./tools/repo_docs.sh --check - - rustfmt: - name: Rustfmt + abi-up-to-date: + name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - name: Install Rust - run: rustup update stable && rustup default stable && rustup component add rustfmt - - run: cargo fmt --all -- --check - working-directory: tools/witx + - uses: actions/checkout@v2 + - uses: WebAssembly/wit-abi-up-to-date@v2 + with: + wit-abi-tag: wit-abi-0.1.0 diff --git a/proposals/clocks/.gitignore b/proposals/clocks/.gitignore deleted file mode 100644 index c0476d12f..000000000 --- a/proposals/clocks/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -*.bk -*.swp -*.swo -*.swx -tags -target -Cargo.lock -.*.rustfmt -rusty-tags.* -*~ -\#*\# diff --git a/proposals/clocks/Charter.md b/proposals/clocks/Charter.md deleted file mode 100644 index c50381166..000000000 --- a/proposals/clocks/Charter.md +++ /dev/null @@ -1,55 +0,0 @@ -# WebAssembly System Interface Subgroup Charter - -The System Interface Subgroup is a sub-organization of the -[WebAssembly Community Group](https://www.w3.org/community/webassembly/) of the W3C. -As such, it is intended that its charter align with that of the CG. In particular, -the sections of the [CG charter](https://webassembly.github.io/cg-charter/) relating to -[Community and Business Group Process](https://webassembly.github.io/cg-charter/#process), -[Contribution Mechanics](https://webassembly.github.io/cg-charter/#contrib), -[Transparency](https://webassembly.github.io/cg-charter/#transparency), and -[Decision Process](https://webassembly.github.io/cg-charter/#decision) also apply to the Subgroup. - -## Goals - -The mission of this subgroup is to provide a forum for pre-standardization -collaboration on a system interface API for WebAssembly programs. - -## Scope - -The Subgroup will consider topics related to system interface APIs, including: - -- APIs for host filesystems, network stacks, and other resources. -- APIs for graphics, audio, input devices -- APIs for encryption, format conversion, and other transformations - (particularly where hardware acceleration may be available on some platforms) - - -## Deliverables - -### Specifications -The Subgroup may produce several kinds of specification-related work output: -- Creation of new specifications in standards bodies or working -groups (e.g. Wasm WG or TC39) -- Creation of new specifications outside of standards bodies -(e.g. similar to the LLVM object file format documentation in Wasm tool conventions) - -### Non-normative reports -The Subgroup may produce non-normative material such as requirements -documents, recommendations, and use cases. - -### Software -The Subgroup may produce software related to Wasm system interface APIs (either -as standalone libraries, tooling, or integration of interface-related -functionality in existing CG software such as Binaryen or WABT). Capabilities may -include: -- Libraries implementing external standard APIs in terms of WebAssembly - System Interface APIs -- Tools for producing code that uses WebAssembly System Interface APIs -- Tools for implementing WebAssembly APIs -- Tools for debugging programs using WebAssembly System Interface APIs - -## Amendments to this Charter and Chair Selection - -This charter may be amended, and Subgroup Chairs may be selected by vote of the full -WebAssembly Community Group. - diff --git a/proposals/clocks/Contributing.md b/proposals/clocks/Contributing.md deleted file mode 100644 index 1cc607fa4..000000000 --- a/proposals/clocks/Contributing.md +++ /dev/null @@ -1,8 +0,0 @@ -# Contributing to WebAssembly - -Interested in participating? Please follow -[the same contributing guidelines as the design repository][]. - - [the same contributing guidelines as the design repository]: https://github.com/WebAssembly/design/blob/master/Contributing.md - -Also, please be sure to read [the README.md](README.md) for this repository. diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 6fe6176b6..8f9427c6e 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -1,32 +1,114 @@ -[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4323447.svg)](https://doi.org/10.5281/zenodo.4323447) - -This repository is a clone of github.com/WebAssembly/WASI/. It is meant for -discussion, prototype specification and implementation of the WASI Clocks -proposal. +# WASI Clocks -Original README from upstream repo follows... +A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. -# WebAssembly System Interface +### Current Phase -![WASI](WASI.png) +WASI-clocks is currently in [Phase 2]. -This repository is for the WebAssembly System Interface (WASI) Subgroup of the -[WebAssembly Community Group]. It includes: - - [charter]: describes the goals, scope and deliverables of the group - - [docs]: learn more about WASI - - [meetings]: schedules and agendas for video conference and in-person meetings - - [phases]: the current WASI specifications - - [proposals]: the status of each new specification proposal +[Phase 2]: https://github.com/WebAssembly/WASI/blob/42fe2a3ca159011b23099c3d10b5b1d9aff2140e/docs/Proposals.md#phase-2---proposed-spec-text-available-cg--wg -[charter]: Charter.md -[docs]: docs/README.md -[meetings]: meetings/README.md -[phases]: phases/README.md -[proposals]: docs/Proposals.md -[WebAssembly Community Group]: https://www.w3.org/community/webassembly/ +### Champions -### Contributing +- Dan Gohman -The [issue tracker] is the place to ask questions, make suggestions, and start discussions. +### Phase 4 Advancement Criteria -[issue tracker]: https://github.com/WebAssembly/WASI/issues +WASI clocks must have host implementations which can pass the testsuite +on at least Windows, macOS, and Linux. + +WASI clocks must have at least two complete independent implementations. + +## Table of Contents [if the explainer is longer than one printed page] + +- [Introduction](#introduction) +- [Goals](#goals) +- [Non-goals](#non-goals) +- [API walk-through](#api-walk-through) + - [Use case 1](#use-case-1) + - [Use case 2](#use-case-2) +- [Detailed design discussion](#detailed-design-discussion) + - [[Tricky design choice 1]](#tricky-design-choice-1) + - [[Tricky design choice 2]](#tricky-design-choice-2) +- [Considered alternatives](#considered-alternatives) + - [[Alternative 1]](#alternative-1) + - [[Alternative 2]](#alternative-2) +- [Stakeholder Interest & Feedback](#stakeholder-interest--feedback) +- [References & acknowledgements](#references--acknowledgements) + +### Introduction + +WASI Clocks is a WASI API for reading the current time and measuring elapsed +time. + +Unlike many clock APIs, WASI Clocks is capability-oriented. Instead +of having functions that implicitly reference a clock, WASI clocks' APIs are +passed a clock handle. + +### Goals + +The primary goal of WASI Clocks is to allow users to use WASI programs to +read the current time and to measure elapsed time. + +### Non-goals + +WASI Clocks is not aiming to cover timezones, daylight savings time, date +formatting, or modifying the time of a clock. + +### API walk-through + +[Walk through of how someone would use this API.] + +#### [Use case 1] + +[Provide example code snippets and diagrams explaining how the API would be used to solve the given problem] + +#### [Use case 2] + +[etc.] + +### Detailed design discussion + +[This section should mostly refer to the .wit.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] + +### What should the type of a timestamp be? + +In POSIX, `clock_gettime` uses a single `timespec` type to represent timestamps +from all clocks, with two fields: seconds and nanoseconds. However, in applications +that just need to measure elapsed time, and don't need to care about wall clock +time, working with seconds and nanoseconds as separate fields adds extra code size +and complexity. For these use cases, a single 64-bit nanoseconds value, which can +measure up to about 584 years, is sufficient and simpler. + +For wall clock time, it's still useful to have both seconds and nanoseconds, both +to be able to represent dates in the far future, and to reflect the fact that +code working with wall clock time will often want to treat seconds and fractions +of seconds differently. + +And so, this API uses different data types for different types of clocks. + +### Considered alternatives + +[This section is not required if you already covered considered alternatives in the design discussion above.] + +#### [Alternative 1] + +[Describe an alternative which was considered, and why you decided against it.] + +#### [Alternative 2] + +[etc.] + +### Stakeholder Interest & Feedback + +TODO before entering Phase 3. + +[This should include a list of implementers who have expressed interest in implementing the proposal] + +### References & acknowledgements + +Many thanks for valuable feedback and advice from: + +- [Person 1] +- [Person 2] +- [etc.] diff --git a/proposals/clocks/WASI.png b/proposals/clocks/WASI.png deleted file mode 100644 index bb018e99e3ec2a66d8f2d6a7bcc63105b74d9262..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11059 zcmdsdcTiKo+b%_lbU}*rqM#rk(xpT|1f+`ej!5s)Yv`yTASgv3bdV0xLkS(Eo6sSI z-btvThTQnOGvCbp@0&Z{{pTigCbN6??ECDydv@RV$@5u9ONEk*nG6pPk5Wzbl`bA0 z{(mk~Vq8t`lpzZDL;PM{@|oudLkND#=h;BUO$>jKmAAL!(^RtaaD zcqPu5--0PggunD?lNe;Ec$F0u=+!tqi3pykveI%c^?B;jMC66}5RrX+8TPVG-k@$t zsoa#AO|+mTaI6Egbw1279$)XQ4ui0dI7!a%kf~vF2}o#e6dd)Jq{UQ@a8JC&Y&A0yClJI%bqLx)p8Nu@_2ELZQz~bAwU-` zjNtOX@;5wjVL73l)e7_%-}-}{kTi!%olwF+_vf8CcsVdreP%gTplVt;$K@^c_=!Lc z%B6;N1JC0IA0jD8rt9b(E`+a~d!%@3@JV)i2z)1>(=~YWqPFGWE4omNHFK0e#yjZM z{lZaBv1UI>tBxkTp#PLL-+m+L`Fi{Tgy}rqh1iAT!`bfTD^4?Eqx7TLNU%`f6vK;)D=kOd1xeX0QM0Q$+m}Z#+c9&oXyO zXGeVb;stIT4BmrI1irsaIdqK!WQv*LS|$Vw{_D$YySKI*VXRr(q@+DQdUl32X;ONn zFdyHD2Rz5!K?83UCHWFYmtZ6S&x+3RP+w}k1bX>9tgr)`w@DJ^=L8%wp8IbO7s*YL zbB}L7Q#1PGP-(FWoZ@4(niOz7jVLbDO&nz>q0>MYgNw!T%SSdupzB~sKF|}UWdMGw z56eG?RIyzA>llRZkMwJmI0y&H87yBif??S0HN(GnDW4)v<)PGV9;-Z#>GG|2HE(d! z7%OQ3+Py?S5@{t#-A+*UmbQjE!r67;pv>T%_%7N_5L| zh$#$m|Ds9<9m;5UKmrL`HCh3@7zRji^=V_>{63260b~bC0G6#g*nPjT;~m7@@urg) zc^jR7f;UmhCowObEGYvIFogwgI0w-!$+OEva`+D)v8~o{^G+4Rj>1OEKx8x$Qa#LB zriw}{mJcRw#*+o&j0kteN3sOr?kzN)VbM*D5y7eWB<-E@(91l8`U{ztI3G|~w0COb zD|=Mq^J%jRWZ}Pg*=Dj+ZMNV_l|T?{5TS=_a?BgBT>3-!UO<@Rq{XXO3jDa4rN8$! z>C30bs>=VP*wv5N9; zZk(wlH>FBQA@qK9sZjVoF!u|&{||8g6J;{pd;c}qfBpU6mR%ZueakUpQltqxxvWAn~wd*u;(OPQ3~dOj|&4;24}nh}3mJ zV6ospuj#|%GutPWjXLw})}mGhkqnzZ2a$_R;<(I?fCANVHKaCouSt>3QIREhY+|EPc z3L)_ZSbXLbJvPIz6YTnJT0r?D9sTnY5h1aib2sn3s`nYeSc9t28Famq#Ts4X{JoFc zCBhSzyAia%=OXKMJ*?;sE)ONe`^#|D_;EC#s;V054kZ(NYWjvynt|QPW^+eqlVdNp zS&sWxm>Q=^MafUiNZ+$DqK(s>qK>D1UF`iG1+mk^^k56)+@KHPV>66{T86cARyG29 zBod4|2MIL~>g?zM$cGqq$6L+@hGITJb@GJ9gn7w^0$9>G%ck8fHIy?9S$PYXZ0MV) zbIoQ;qWUNp(`60O^$mpTru#pm&H*I7oQ>@3p}$}%(<*n{|c{xFvB?e#k(^H26BL`NQ&VO0TM zi9R$%xGtGM!rBNOCu~^sxW!czB%-w$Aujv!vi8xG!_x%^_#AK>PK>qY$%v zspccYKxs@tP)2|~qni8yVf&VTMr7_!Dl$y~Y_x@Av2XvK`5jxztH-J+ZdLNSggAT5 zwVDi=a^;1S3mua$sv1SoL`{TSCt!q&0$zJaXd2ukJ)?fWJ_UEFt*Pf5?_28`0W2x#=%<%C zLY8Klqg#yCY1inJ2xSyaj$@#|%lG;gB$+1JI$P1P-rhvW-RyV; zx3nHDVG2C={ZAcU@wV2Ub7hL}2T83%Th=?AmNI)iaS&S2Ggl(|yFYDqD54&z?`_!5 zj|-<{meHm@HS);oYGmR!ef|{XU>)G+%nY4mg!U_XJ|5UcFn>S^Cnj?UtPoJ*0?a+Z zG{VOk#<+DELfBB=9KI5k+NQQ;dL{pwG!f9yF+7nh>BGo^^9X44YU9zsWYihE*qisW zwUQ6xCD5aG1pWi9qFFNZL9v0NQQN(i$c-VyHbgqv;yMNX?Md%xur25oE3Lc`y^*QE z(ld8U#qIZC5RHac}Qv z`inGO=7bLCkd%k#@~p|ur6~Kr#v*+$!6|+-dG}fnra+A%i28NCpNm%CES#>!M%#Zz z-G+r*RnSaUe%~-ECJAD)nx}34e!SX@>v7S$!f9A<;{&B+@@?6=-mV;JZ3Gq+(aWR3 zrq@bfm$Tm;?KCf-x)<74LU*!dhe@dgs=U-uQEv1xt*OH259W(IaHk6Fjo{D^JSgDt7G=r-sJ_wErt3*UcACN=rSllcs%F5__(XN)RIu)v+!j>Y zf4{Vq#eJb2P~lAU*9OFcCO=6ya-J>+`wC=Mow`v=xN5eE)P$(0BCI@ST3y=V7-jYA zd5;F-b&4ou6;#exVMtac=N}^P_TMkvey=ukEJfEeSJS^us^U?#zWHhEIfjC_qE>!Y zy+y{dx3qG?Yxz#8kdJM)=XGUvlJAVQBLRaS1St+E+Cu%V63pgS4m2(0=jSP}+1-}@ zT=pwAh#r%@W_-D~LAzq76(dO_$XBoN9cG&$-ufuF*;HZvQ+^Eah(ss7Rs-%KyMBaW z%Z_QJQmXBrb|33Xt=z22>?Z6{U|v)^s96BcqCWD~u6;Fpk8;$I@T54P+F3G@;VkBT z3c0Bp)<{^$oO1Tl?o7NbmpB&ZJ@)fuq2l;_0R-yJ9k!I6M|m|#92}BD7eDNP^akg4 zykUl>Yd_~HdMp2}pPB22Jk5bm^31-p5x#lIA%-!}#CpXy z&!x#@a}EVWQtk+4CA14brL;&oUc7L&%ydqpBZH-G^qFS18aW4Cs*4~FJLYE!ngF?8 z>Mx7-e|~h9W0|Tghss?Lt_62axF?EUbVnHyIn%zTHWH*q1%(?B!zV7~suov7vS+w3A1|lKYl7Cm4Ly>D7ZC>~+)lIkkGt=Ri1X5>Tj$f_qcS}jL>CuwV%X6>prp+gTVy=(cLq`IpUp*6>C=x2M}=z z7#wrr+GWmWbKGe3U{M4#{4|o^>?S<>;pO49v^w`Fb78r4;K6Uin;f&H3h6X4HLLNi zdHwZhn20d26usjfMD@y9>+WwgFxgO3_swpa4OW?exDiFVjVuijaE~`-*mSG&MZB!t zZkFGjY2%ouhe}%g^wM%%b!gYct=g2AE1xA^W6_)&9WLM}pO5u^N~;!-YPFjc?HX(D zoANwP={-8Mxz}KDY0lA*70}?@ygys#`rhVmQBvJhSx30`>^2#-2x=Qpbo{@3E)doxNfdUCIPTJz~N(R+?RGYwm z7+{2ZuYOi@Q&JiVUsuZkF1E8J=TzVOUmVS!XpVO!;I(nXINRqd_)8EZn`Bo76 zXtOlU2KB?ZftQ2%#Qf?DH`C$+iH-Y@Sss8bjUP(BMFS7? z^A7z<7_}(8(6PRv=q~wH^rxD1DuU8CKZ@@{pGE!k@*FM5Fg&9qZmLYrip0I4_I?L7 zU~hSA&#|}s)1f8%0Pkx~9|mwBwC6ZDzRjr8+16l&0iszdV4Kd|)GYITOaV_cCBZoj zBVURJutKNcS(w6Nr@153wdNPRuIUfqEurW?TCXAYNi*^RVJ935f7XM7NNH7?vuN~O z=52GW^phlhOZAs4-toVv{p2(UNBhZs6e|nhwzrL`SW-bgQ%rJ`v z+Iyaj6#6z1_yqilWC74)4p?=wu+lDP3xl7Q~ zoJ+lD#)4`oJ=V`Bv=ck5_J*qlBBLxPYwoW8PajB`R7RmJ7@UWSA?vR+dmAyG1 zlx_L^{J=hKTejhoC@}#P=tRdyw6kC!9~<+R{8p*&n))?vszQcI{Tq_qDzYj?v`<#& zqTW2BY!F~iocn9Ly+o^X`;#8vNzqDupFr#wY+ewLMHIS{xz93lHEAcn371?dckLF3#aTRW5v4-AWPR-BLV0 zczGOQv--1AT2h=8)_K<6(H_zTPIPq4`hCA!w_6FjN!tqW`f=m%IoAb7_p;|JrI-zj zEi2-AlK(Rn| zWhc4;bY4;_bC>UmH#q)d!xtPZv7-L#Z;^?w-81ArR2BdqbFS4cp6nLY6QEI>VVKw( z=KJb#344agKQZ#_G2z>*pVmdXq}JETiM^cOYW7BP&Lnihl#|8n-ZdsVRpZ?)*6!>p5(2a z(wbKbCa)6?wHpsD{MHM4{`A1jHlR5gYL!rAK3D$-w0H$xAcIy+-aUymeS)0rT3s^m zz1d{?`!T-n)E}bbWGc3T11yHIbUR63ZWHK}-#w z^lTIDwP#M2&8U=7pvc>={5XIwRw2Nu{j>Jb`F+c5LNc1~Pv?^Rq*QL5G7=58_;u=Y6a!U+jemb?;oG6&0g+n!%nRSP{k zyu8bP`A1Y16H@*BB1rPnu1hfqee+HG!V{{dU;O$>Zt(()H}fiU71sXlgVV0~O07=V zmbepiqv=_nNW6I^CcTBB2e%UiFHJP`p^hye-)VwkQZ;Wf&!&sv#O)#YZ07yf<*j_# z9{`ejIq}*ZGO+rRxTQM&>B30kw_JAPUWNfT9PJ9@ab7-O2mhJ&izW50oT^78X@@;y zGq3ic(q&S#H+*T`|97szw`Nq!xXP>z6Rb}7R7eV!DYRq!Zsq2(tetbZ?m+>1GOEHk z+D2wIODd|St_b1em7oYxwkRH4YIn6iRqz0rX{5>jY!usH1VV8&O8r z`jVC&8rn-M6Vik~K7th;Dmh)9CHLiN-kK#iqAD=_Ijl|Y88;}pLY1WrKv~Lg2_Lb` zEr}_3Yu6CMN~auX6A)q$P0Yv?gWY3#m>__VTW5^FyXcQKhykv>5GsGD54#n5csDDc z(ih-JQ#h=6P3#o=r#s6ga22iK6!uXhySUzto~dhEUP-$eA^j$8jCZF>qeEu3iG|ot zV#!sM7)7G|bNTdKSQ=hZis$ zGs0q%dKtk3Y<;3moXW_SHa3OigHLmK9M;aKNqmMOqaJoS>&dAt|5fRUagk?9Nm#P? z`nu32S*xCCgC68ye30zoG5&hM^~3B@i)S%nN_n~VnT;o~+(71uswB4>%nC=V!Qffb z6H{~(76rii=KW@0+XF|%>7pRtdFHMrXW-yO)%+i+P{Eb{^fS=U@4X2Fpdm3Ajt}-} zII=j&t0Xzbd5J`SU~!EtKIB>=8SOFp%;#I)^}6f=5cnLvi)0r+Sr`}mmif8V_qBM> zQX{d`w1BE)v6|kK68iU*oRkDkND>qNVnQ`%*Zq4HthACMb`OjSAmTIcZ+t5`ns#gg ziEUaaNH`o9*%b3DR=)8(Sh{f1xG!!oKX4h=M_8%XXg5v4pBe5T(yvU+e~y-J%(k>c zvt_57^cC||rZ;R@*aYiHo}^S8Sbub};g5-qSlf5L`?lHFf1L4Yip`%GSv%|gw?;NI zS50j#f)rFl-sciX!Ql_k%fd17C7Fc>pT0;9^oDr zl-T|vOVUHii}#k&N~LzMjUQ9K(resA9-OGNZn#QU%P;0S+>N`N&j}Ap^hnR~dOC(M zFA1VesWK@$+Huoh4kP#SL;L|)8vX0FP?eU6iL7lbG*HIJn;Dl8a#w+4f{M2KhhCl3 z&Xmjl>YNN}MVa?)L0gK*sV~_Apq_ybGT%ziKmHlmpCh7U;;UiSRPR>>VKWet(F#EC zJ+NVdI2oIH)caLnquc72(^<85Uj$y(mONjIl)}+FEKTtfov9X(?22R8n0D%DN0!psZZV0IPHlWhGr}Fy9-dGaCq+~m;a#w_97n#B zfb7WhU(_;--YW<#*iyiQNj{BsR1X@s;yCF~-?;i!G|Ch2nvA^8a2H(yj%(j6uf`BL z(sagl$PC0nTKo2{n^2@X926PZjkhZ52to@PFPVhOYChY)-@a-tZ&@dawgMlkFi&*l88A4VOjO`8XMLA+_6*F<8cU%G- z6K;&=glo!n&^`qSQPpJXyJajg^g~7}MjA%46a6iTsQmej+IyO$=ECE!z@mD`E+J~8 zB*j3A!R{<`zjsh+DIh;D+UybS9Y^s1NttfOw3XG2-k>i!tUb3qc{5AJj!FGH><{d0 zIyfu4L$I4jP#BI;04Hd*7z(D>IP6?ozGE6!=*Xp5P)lQEuO zcvGL{kKJd>d7VY<0HuA7OF_plk>*cXUCt;hXD^*+)IR=HDl5jk?vRY|mfyUXiV9!3 z%A6nT{-K`wE8*|qLr;x_5`pAtuR~MEInNdEeN0_{p=J<*3_Vq?C)t+x+e9sGT^_d8 zl=5d{%v*Rmu<3BYMNK02T-!b))Q&vb&-+Th_^w8KN#;hjpi4;YODu=R-{)`pUlTJH z?QKA+sHfm%FEo?ct?X%IyPlmp$ap0-ie7(U#03wYrppa;UQnu5c^R!+Cp8!d7mXp> zax#5JG^B}RW{kgee4A{D3}z}mF~m{%=&>uyzi}rC-4!RyZEDHhMUy5hMZuM&no@vL zGvBtGzI6K~)PurS#YSqPEI_u{^pgVOc(48IzPA>)EwP_lxly5iRudSi&d)?IHRW)O zVe#5m5Y{*Sz_A-|C|t3gY))9;D~2 zTQ6XRYB1D%^!a4a(Yw&@cw4)VAuDey3kRI)Cu@~-X_)(~jZR8gs^)NnkmAUSHfU`sCy=xi ztoUn_I%1URUr5_%ml04VQ2D&lRQlA-Hlj_W`NuPJx%~A_fFYnJ8%uTBNCZ}4m^&+< zxtk{DSAS1DL?uq7rtP~B$}I6{PYup-Xq}Ga0fR0JC5~ilLiNpjaI9my7J#VP|3&GZ z7&MT-rAT?8sP5K%J^Py5WI?k>Gx|->{bNIQ)~l^8=-KI68>tyscSxBylU((f%QHxI z@!q{Am0njaHD^^Q?RzhL3A)8y0*^`Y%x>kHjW}}Fi|FBX-r+Y-iFSBXryle)4Bw63 zx#~GROYwxKEE;ZAr+zu(d(}YT-nQCgU*eVIE>5ve+Fo+coI_Jp!rGA2#wv9B`05i@ z=O$dq8vMhmz)klfv+w?lXO`#8pjfJsZOe+6Qq5lfSojnkK^K`H8 zU(T@m8HQ_Ms+gb?a?EN*lvDN;;;YE;{&(zcf$242Bl;Q=E(Fq)aGif!L_p`W@A|Aw zxUf#ZVSg=J!z4rgYR!Hd0}+i<&UCA~k@%2G4y~?9p9l@jz+gkahd{hD9R4_sITSE@ zo%e9ui}Bdd?H>7F*+PCh^8(0gJX3h|*rwUzMX~NsV0L{AbG&=7IC}m88T9t=l56<+ zOIYt&J;E0z??buRoa)bZL_nil;{_b-^Ac$cZ$+Cqd}4Ty#&+8lFNuzSbw9B6bQe$y zN&;y^KFjR1aJqJo=nrZdII;;sLp~;S0Df|rXsMcrjjAaGQVT#^9t`a3g;ZZ;I1aD2 zna;fC>>8>sZywu4o#8002Lxk^2&>L%*HHK3Bj;2n+mndNJI~~Hm|EYrN8DeYSmUz1 zq4P2%XF}?yujZl>OLhW%zRls%V%fi4tG5zglrl_Pm5iqm`qpmx*+LpX%g_qNTa(X? zX!hL%d z-Au$D8~NtaCOwcjpDX(D%K|Es)V)Y{-%fSq-nHZmCYUY40~ty zR42n1+?KoJZx{b6F5a`oC02xuk9wnt-!(+hXO0O}zKHn3BWcbBY=2cuL&reZT@?f!EnUS%OCB^al^fJ)~eTVSa^*7xbm|{97T{j~iQ@DUk_PoaU69PCg_|n|6Xl zJ{DV2q@lN&V>yrRMsS1%Sz7J93NU=wyWjs$8Oiwh7 zGwhv^7=(^?9w)VxvXcgQ@2%X48cM>$pvS)>VLU&OUG%ec;O`EIJuGvaH@jPZ+=B4D zPx{=>Ru{7yYxZYJx^U#6ysb$t`+fo$^mPc#4ZSArMEaop3BB&el>W_E|51kgQ*IEI z;-pG?|DEzj%fB6OpoiSK`NN!){NxX>I@9b(p?p3M3g4P)&}Fk3y3z#erYTOk(6*3| zb4Xvtbq;txDzpY1`P}{QbpOAFB>#Ol|J8mlL=gIjrllH=XK`lS{GWsGK(|4F zkH?JRi92sD%!QV>!fV%fRLJ+5rvt254kg2LbZa+o;u`Mr*ms?h%=YrW!Ry-jkiwcpIqfMbNbRj3^%@fQ1H3~bG~-G2hLCoU~m_O!*S{t4k5blvqO)= z9EXs`RTLzl-PwVcgT-;asBs8qG?diy91lofKjt)2rc-7hA(tfxFmr?Hi$lA>MZ(ZX444s>;l>)hQr_Q%*@PmSd$}>38_@d1=4?UyC{i czhJ3-6EkB9r^7gK@>V=GWvy3LidGT-3mCQ^bN~PV diff --git a/proposals/clocks/design/application-abi.md b/proposals/clocks/design/application-abi.md deleted file mode 100644 index 0ef259a51..000000000 --- a/proposals/clocks/design/application-abi.md +++ /dev/null @@ -1,60 +0,0 @@ -WASI Application ABI -==================== - -In addition to the APIs defined by the various WASI modules there -are also certain expectations that the WASI runtime places on an application -that wishes to be portable across WASI implementations. - -This document describes how a conforming WASI application is expected to behave -in terms of lifecycle (startup, shutdown, etc) and any exports it is expected to -include. - -Current Unstable ABI --------------------- - -There are two kinds of modules: - - - A *command* exports a function named `_start`, with no arguments and no return - values. - - Command instances may assume that they will be called from the environment - at most once. Command instances may assume that none of their exports are - accessed outside the duraction of that call. - - - All other modules are *reactors*. A reactor may export a function named - `_initialize`, with no arguments and no return values. - - If an `_initialize` export is present, reactor instances may assume that it - will be called by the environment at most once, and that none of their - other exports are accessed before that call. - - After being instantiated, and after any `_initialize` function is called, - a reactor instance remains live, and its exports may be accessed. - -These kinds are mutually exclusive; implementations should report an error if -asked to instantiate a module containing exports which declare it to be of -multiple kinds. - -Regardless of the kind, all modules accessing WASI APIs also export a linear -memory with the name `memory`. Data pointers in WASI API calls are relative to -this memory's index space. - -Regardless of the kind, all modules accessing WASI APIs also export a table -with the name `__indirect_function_table`. Function pointers in WASI API calls -are relative to this table's index space. - -Environments shall not access exports named `__heap_base` or `__data_end`. -Toolchains are encouraged to avoid providing these exports. - -In the future, as the underlying WebAssembly platform offers more features, we -we hope to eliminate the requirement to export all of linear memory or all of -the indirect function table. - -Planned Stable ABI ------------------- - -There is ongoing discussion about what the stable ABI might look like: - -- https://github.com/WebAssembly/WASI/issues/13 -- https://github.com/WebAssembly/WASI/issues/19 -- https://github.com/WebAssembly/WASI/issues/24 diff --git a/proposals/clocks/design/optional-imports.md b/proposals/clocks/design/optional-imports.md deleted file mode 100644 index 543599a10..000000000 --- a/proposals/clocks/design/optional-imports.md +++ /dev/null @@ -1,108 +0,0 @@ -Optional Imports -================ - -It can be useful for WASI programs to optionally depend on certain functions in a -WASI API. For example, if a WASI API evolves to include a new function a -program might want to continue to run on older systems that don't yet support -the new function. In this case a optional import mechanism allows the program -to run on older systems and detect the presence of the function at runtime. -Another use case is an API that is not applicable on certain embedding. In this -case optionals imports would allow program to continue to run in such an -embedding, albeit with reduced or modified behavior. - -*Note*: In the ELF specification this type of import is known as *weak*. -We chose *optional* because the term weak is already used other context in -WebAssembly and JavaScript, specifically in JavaScript [weakrefs] proposal where -it relates to garbage collection. - -WebAssembly itself does not currently provide a mechanism for optional imports. -There is some discussion of adding it to the [spec][spec], and WASI would likely -use such a feature if/when it is added. In the absence of first class optional -imports this document describes the mechanism used by WASI to specify optional -imports using a custom section. Currently this is only specified for function -imports. - -Declaring an optional import ----------------------------- - -Optional function imports are implemented using two imports for each function. -The first being the optional function itself and the second being an i32 global -which indicates if the function is present at runtime. We call this addition -import the guard. - -For example, if a module called `wasi:fs` added a new `statvfs` function to its -interface a program could optionally import this new function in the following -way: - -```wasm -(func $statvfs (import "wasi:fs" "statvfs.optional")) -(global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) -``` - -These two imports would also need to be added to the `import.optional` custom -section (See below). - -On older systems that don't support the new function, `$statvfs_is_present` -would be set to 0 and calling `$statvfs` would result in a trap. - -On systems that do support the new function, `$statvfs_is_present` is set to -1 and calling `$statvfs` would work as expected. - -Using an optional function import ---------------------------------- - -In order to use the above options function its presence should first be tested -for. In C code this would look something like this: - -```c -if (__wasm_is_present(wasm_fs.statvfs)) { - wasm_fs.statvfs(...) -} -``` - -At the WebAssembly level it might look like this: - -```wasm -global.get $statvfs_is_present -if i32 - call $statvfs -end -``` - -Custom section --------------- - -A custom section is used to specify which imports are optional, and for each -optional import the name of the corresponding guard (the global import which is -used to signal its presence). For each module that contains optional imports -the module name is specified once followed by a list of its optional imports -along with their corresponding guards. - -The name of this custom section is `import.optional` and its contents are as -follows: - -| Field | Type | Description | -| ----------------| ---------------------- | -------------------------------- | -| count | `varuint32` | count of mod_optionals to follow | -| mod_optionals | `optional_import_list*`| sequence if optional_import_list | - -Each `optional_import_list` has the following content: - -| Field | Type | Description | -| --------------| ------------------- | ------------------------------------- | -| mod_name_len | `varuint32` | the length of `mod_name_data` in bytes| -| mod_name_data | `bytes` | UTF-8 encoding of the module name | -| count | `varuint32` | count of `opt_import` to follow | -| opt_import | `opt_import*` | sequence of `opt_import` | - -Each `opt_import` has the following content: - -| Field | Type | Description | -| --------------- | ---------------- | --------------------------------------- | -| name_len | `varuint32` | the length of `name_data` in bytes | -| name_data | `bytes` | UTF-8 encoding of the import name | -| guard_name_len | `varuint32` | the length of `guard_name_data` in bytes| -| guard_name_data | `bytes` | UTF-8 encoding of the import name | - -[weakrefs]: https://github.com/tc39/proposal-weakrefs -[spec]: https://github.com/WebAssembly/design/issues/1281 diff --git a/proposals/clocks/docs/DesignPrinciples.md b/proposals/clocks/docs/DesignPrinciples.md deleted file mode 100644 index df82c8692..000000000 --- a/proposals/clocks/docs/DesignPrinciples.md +++ /dev/null @@ -1,291 +0,0 @@ -# WASI Design Principles - -## Capability-based security - -WASI is built using capability-based security principles. Access to -external resources is always represented by *handles*, which are special -values that are *unforgeable*, meaning there's no way to coerce an -arbitrary integer or other type of value into a handle. WASI is also -aiming to have no *ambient authorities*, meaning that there should -be no way to request a handle purely by providing a string or other -user-controlled identifier providing the name of a resource. With these -two properties, the only ways to obtain access to resources are to be -explicitly given handles, or to perform operations on handles which -return new handles. - -Note that this is a different sense of "capability" than [Linux -capabilities](http://man7.org/linux/man-pages/man7/capabilities.7.html) -or the withdrawn [POSIX -capabilities](https://archive.org/details/posix_1003.1e-990310), which -are per-process rather than per-resource. - -The simplest representation of handles are values of [reference -type](https://github.com/WebAssembly/reference-types). References in -wasm are inherently unforgeable, so they can represent handles directly. - -Some programming languages operate primarily within linear memory, -such as C, C++, and Rust, and there currently is no easy way for -these languages to use references in normal code. And even if it does -become possible, it's likely that source code will still require -annotations to fully opt into references, so it won't always be -feasible to use. For these languages, references are stored in a -[table](https://webassembly.github.io/spec/core/bikeshed/index.html#tables%E2%91%A0) -called a *c-list*. Integer indices into the table then identify -resources, which can be easily passed around or stored in memory. In -some contexts, these indices are called *file descriptors* since they're -similar to what POSIX uses that term for. There are even some tools, -such as wasm-bindgen, which make this fairly easy. (Internally, tools -and engines don't always use actual WebAssembly tables to do this, -however those are implementation details. Conceptually, they work as if -they had tables.) - -Integer indices are themselves forgeable, however a program can only -access handles within the c-list it has access to, so isolation can still -be achieved, even between libraries which internally use integer indices, -by witholding access to each library's c-list to the other libraries. -Instances can be given access to some c-lists and not others, or even -no c-lists at all, so it's still possible to establish isolation between -instances. - -Witx-specified APIs use a special `handle` keyword to mark parameters -and return values which are handles. In the short term, these are -lowered to integer indices, with an implied table, so that the APIs -can be easily used from C and similar languages today. Once [interface -types](https://github.com/WebAssembly/interface-types) and [type -imports](https://github.com/WebAssembly/proposal-type-imports) are -ready, we expect to make use of them to provide APIs which can be used -either from languages using references or from languages using integer -indices, with tables being used and managed automatically. - -## WASI's Scope - -WASI started out with a very POSIX-like API, however WASI will grow to -include many APIs that are outside of the scope of POSIX. WASI is a -forum for cooperatively designing APIs, along with a W3C CG Subgroup for -eventually standardizing them. - -For example, WASI may include high-level network APIs, such as APIs for -HTTP. This is outside the scope of POSIX, and while some WebAssembly -engines are very interested in implementing it natively, others will -find it too complex and high-level. But one of the great things about -WebAssembly is that there's no syscall instruction, so "syscalls" -in WebAssembly are just calls to imported functions, which could be -native functions provided by the runtime, or could be other WebAssembly -modules. We expect to leverage this capability to provide polyfill -implementations of things like high-level network APIs on top of -low-level APIs, such as a raw socket API, so that engines which wish to -keep things simple and just implement the low-level socket APIs can do -so. - -WASI also aims to include domain-specific APIs, such as -database, blockchain, or specialized APIs for embedded -systems. Another key building block for WASI is [optional -imports](https://github.com/WebAssembly/WASI/blob/main/design/optional-imports.md), -which give applications the ability to dynamically test for the -availability of APIs. - -## Relationship to POSIX - -POSIX specifies a C API rather than an actual system call ABI, with -the expectation that implementation details will differ at the system -call level. In the same way, the primary vehicle for WASI's POSIX -compatibility is libraries such as WASI libc, rather than the WASI API -itself. WASI libc provides a wide range of POSIX-compatible APIs. - -In the parts of WASI which do correspond to POSIX functionality, WASI -follows POSIX when it doesn't conflict with WASI's other goals. And, -we consult POSIX even when we aren't strictly following it. POSIX is -valuable for several reasons: POSIX represents a large body of lessons -learned about systems programming, portability, and robustness. POSIX -is available on many existing hosts that we want to port WASI to. And, -there's a large amount of application code that we want to port to WASI -that uses POSIX-style interfaces. - -All this said, maximal POSIX conformance is not WASI's primary goal. -Some reasons include: - - - `fork` -- It's not that we can't make `fork` work -- we can, it's -that `fork` carries with it the assumption of copy-on-write memory -optimizations which won't be feasible in many environments where we -want to run WASI, such as nano-processes. There may eventually be -compatibility layers that provide `fork` to help people port POSIX -code to WASI, however there's a difference between providing `fork` as -an optional compatibility layer and having it as a cornerstone of an -ecosystem as it is in POSIX. - - And when we take `fork` out of the focus, it changes the way we think -about a lot of other things, such as `execve`, `dup`, `fcntl`-style file -locking, and even processes. - - - Users and Groups -- POSIX's Users and Groups subsystem are -notoriously inflexible, to the point where much of the computing world -has moved to using containers and VMs and other forms of single-user -environments because traditional multi-user OS functionality doesn't do -what's needed. - - And, when running untrusted code, it isn't desirable to run it as a -user's normal identity, because it shouldn't inherit all of the rights a -user has, but it also doesn't help to run it as user "nobody", as it's -still useful to grant it some rights and restrict it from others. - - And, we are aiming for portability to OS's which don't have -POSIX-style users and groups, and systems which don't have OS's at all. - - - Asynchronous signals and handlers -- The core WebAssembly semantics -don't support these, which would need to change before WASI could -consider supporting them, and there are currently no proposals for doing -so. In POSIX, some interfaces are designed with the assumption that -signals like `SIGPIPE`, `SIGALRM`, `SIGCHLD`, `SIGIO` and others exist -and can cover certain situations, so in the absence of these signals, -those interfaces won't always make sense. - - - Shared filesystem views - One of the unique capabilities WebAssembly -brings to the table is the possibility of shared-nothing linking between -applications and libraries. Shared-nothing means that all communication -is via explicit calls, and the libraries don't share an address space -or any other implicit shared state. But if we run both sides within -the same filesystem view, that would give them a large body of shared -state. Union mounts, mandatory access control systems, user namespaces, -and other techniques can help, but often require complex configuration, -heavy-weight boundaries, and sometimes even admin privileges to set up. - -This has wide-ranging implications. Much of POSIX is oriented around -passing around strings, whether through command-line arguments, -environment variables, or paths embedded in files, with the assumption -that there's a shared filesystem view between components. As we said -above, we're de-emphasizing strings, which dovetails with de-emphasizing -shared filesystem views. Instead of having shared state and passing -around values which identify things within the shared state, WASI -prefers to share as little as possible, and use handles which represent -the things which need to be shared. - -Compatibility with existing host environments and applications is -important, and we have put a lot of work into WASI libc to provide POSIX -compatibility and support existing applications. There's a lot more work -that can be done, and a lot more we can do to improve compatibility and -user convenience. We're continuing to make progress -- and users are -encouraged to [file bugs](https://github.com/WebAssembly/WASI/issues) -when they find things that don't work or are awkward. This approach -supports existing applications, while also supporting applications and -libraries willing to opt in to enable stronger and more fine-grained -security properties than are possible in regular POSIX. - -For example, a typical POSIX-style API might include a function that -accepts a file name to open. That requires the implementation to -have a filesystem view, and to have appropriate permissions within -that filesystem view. WASI APIs typically prefer to instead have a -function which accepts a handle for an already-open file. That way, the -implementation doesn't need a filesystem view, or permissions within -the filesystem. It doesn't even need to care whether there even is a -filesystem. When needed, compatibility with POSIX-style APIs is then -provided as a thin layer on top implementing a simple name-to-handle -mapping. - -We recognize that this approach has trade-offs. It often does take more -work to design and implement the compatibility layers needed to support -existing applications than if we just made WASI always expose -POSIX-style APIs directly. It will take more work to port existing -libraries to work with shared-nothing linking. And, even when we do have -compatibility mechanisms, they aren't always the most locally optimal -ones. The compatibility layer overhead is usually quite modest, but it -is present. - -However, libraries built to use shared-nothing linking can be used in -more circumstances, because you don't have to have the trust implied by -a shared filesystem view, or the complexity of configuring filesystem -rules for each library. With a better story for libraries and tools to -work together in cooperation with the sandbox, we can build a stronger -ecosystem which makes up for the downsides in the long run. - -## Relationship to the Web - -It is possible to run WASI code on the Web with the help of polyfills, -however WASI isn't limited to APIs which run well or are easy or -efficient to polyfill on the Web. - -That said, where other considerations don't interfere, WASI should use -existing Web standards and work with Web standardization efforts rather -than gratuitously inventing its own versions of them and/or duplicating -efforts. - -When using Web standards, WASI APIs should be careful to avoid depending -on JavaScript in the engine in APIs where it isn't essential. - -## Use WebAssembly standards and proposals - -WASI should align with and build on WebAssembly standards and proposals -where applicable. - -For example, WASI seeks to align with and build on [interface -types](https://github.com/WebAssembly/interface-types), [multiple -return values](https://github.com/WebAssembly/multi-value/), [reference -types](https://github.com/WebAssembly/reference-types), [type -imports](https://github.com/WebAssembly/proposal-type-imports), and -more. As of this writing, some of these are early-stage proposals, so -we're not actually depending on them yet, however we are carefully -aligning with them so that we'll be ready when they are. - -As another example, WASI's -[witx](https://github.com/WebAssembly/WASI/blob/main/docs/witx.md) -file format is designed to be a -straightforward superset of the [module linking -proposal](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md)'s -.wit format and the [annotations -proposal](https://github.com/WebAssembly/annotations/)'s annotation -syntax. - -## Interposition - -Interposition in the context of WASI interfaces is the ability for a -Webassembly instance to implement a given WASI interface, and for a -consumer WebAssembly instance to be able to use this implementation -transparently. This can be used to adapt or attenuate the functionality -of a WASI API without changing the code using it. - -In WASI, we envision interposition will primarily be configured -through the mechanisms in the module linking' [link-time virtualization -](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md#link-time-virtualization). -Imports are resolved when a module is instantiated, which may happen -during the runtime of a larger logical application, so we can support -interposition of WASI APIs without defining them in terms of explicit -dynamic dispatch mechanisms. - -Interposition is sometimes referred to as "virtualization", however we -use "interposition" here because the word "virtualization" has several -related meanings. - -## Compatibility - -Compatibility with existing applications and libraries, as well as -existing host platforms, is important, but will sometimes be in conflict -with overall API cleanliness, safety, performance, or portability. -Where practical, WASI seeks to keep the WASI API itself free of -compatibility concerns, and provides compatibility through libraries, -such as WASI libc, and tools. This way, applications which don't require -compatibility for compatibility' sake aren't burdened by it. - -## Portability - -Portability is important to WASI, however the meaning of portability -will be specific to each API. - -WASI's modular nature means that engines don't need to implement every -API in WASI, so we don't need to exclude APIs just because some host -environments can't implement them. We prefer APIs which can run across -a wide variety of engines when feasible, but we'll ultimately decide -whether something is "portable enough" on an API-by-API basis. - -## Strings - -WASI in general de-emphasizes strings in areas where typed interfaces -can be sufficient, and especially when the strings would be serving as -identifiers in a global shared resource pool. - -Where strings are passed through APIs, WASI will use [interface -types](https://github.com/WebAssembly/interface-types) to manage the -strings. - -Where string encodings are exposed, WASI prefers to use UTF-8 -encodings for strings, and to provide explicit length values -rather than NUL-terminated strings, (as [WebAssembly itself -does](https://webassembly.github.io/spec/core/bikeshed/index.html#binary-utf8)). diff --git a/proposals/clocks/docs/HighLevelGoals.md b/proposals/clocks/docs/HighLevelGoals.md deleted file mode 100644 index e871cfd08..000000000 --- a/proposals/clocks/docs/HighLevelGoals.md +++ /dev/null @@ -1,25 +0,0 @@ -# WASI High-Level Goals - -(In the spirit of [WebAssembly's High-Level Goals](https://github.com/WebAssembly/design/blob/master/HighLevelGoals.md).) - -1. Define a portable, modular, runtime-independent, and WebAssembly-native API - to serve as a system interface which can be used by WebAssembly code to - interact with the outside world, that preserves the essential sandboxed - nature of WebAssembly through a [Capability-based] API design. -2. Specify and implement incrementally: - * Start with a Minimum Viable Product (MVP) for the standard, covering - basic API versioning, feature detection, and namespacing. - * Then add additional features, prioritized by feedback and experience. -3. Supplement API designs with documentation and tests, and, when feasible, - reference implementations which can be shared between wasm engines. -4. Make a great platform: - * Work with WebAssembly tool and library authors to help them provide - WASI support for their users. - * When being WebAssembly-native means the platform isn't directly - compatible with existing applications written for other platforms, - build tools and libraries to provide compatibility. - * Allow the overall API to evolve over time; to make changes to API - modules that have been standardized, build implementations of them - using libraries on top of new API modules to provide compatibility. - -[Capability-based]: https://en.wikipedia.org/wiki/Capability-based_security diff --git a/proposals/clocks/docs/Process.md b/proposals/clocks/docs/Process.md deleted file mode 100644 index 3b4affc3c..000000000 --- a/proposals/clocks/docs/Process.md +++ /dev/null @@ -1,37 +0,0 @@ -# WASI Standardization Process - -WASI follows the [WebAssembly CG Phases process], with the following adaptations: - - - Entry into Stage 2 requires [witx] specifications. - - - Starting in Stage 2, proposals may follow WASI's [ephemeral/snapshot/old] process - to provide a balance between the need for stability so that toolchains and engines - can sync up, and the need for evolution. - - - The Phase 4's entry requirements for "Two or more Web VMs implement the feature", - "At least one toolchain implements the feature", and "The formalization and the - reference interpreter are usually updated (though these two can be done as part - of step 3 at the Working Group chair's discretion)." are waived. - - In their place, as an additional entry requirement into Phase 2, champion(s) must - include a set of entry criteria into Phase 4 in their proposal, which the Subgroup - will vote on as part of Phase 2 approval. - - Phase 4 criteria will vary depending on the API and its expected use cases, - but may include things like multiple independent production implementations, - implementations on multiple host platforms, polyfill implementations, and - bindings in toolchains and libraries. Note that, portability requirements may - vary between proposals, as not all features will necessarily make sense in all - host environments. - - - The specific process in Phases 4 and 5 will be determined when we have a - proposal ready for them. - - - Requirements around the reference interpreter don't apply. - - - WASI proposals don't require formal notation. Formal notation may be used in the - documentation of a feature, but it isn't expected to be practical for all APIs. - -[WebAssembly CG Phases process]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md -[witx]: https://github.com/WebAssembly/WASI/blob/master/docs/witx.md -[ephemeral/snapshot/old process]: https://github.com/WebAssembly/WASI/blob/master/phases/README.md diff --git a/proposals/clocks/docs/Proposals.md b/proposals/clocks/docs/Proposals.md deleted file mode 100644 index 31c565b2e..000000000 --- a/proposals/clocks/docs/Proposals.md +++ /dev/null @@ -1,64 +0,0 @@ -# WASI proposals - -This page is under construction. The intent is to follow the CG's -[proposals page], but adapted for [WASI]. Some of the proposals predate our -adoption of this process and so don't fit exactly into the defined phases, -however our intention is to align them going forward. - -[WASI]: https://github.com/WebAssembly/WASI -[proposals page]: https://github.com/WebAssembly/proposals/blob/master/README.md - -## Active proposals - -Proposals follow [this process document](https://github.com/WebAssembly/WASI/blob/main/docs/Process.md). - -### Phase 4 - Standardize the Feature (WG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | - -### Phase 3 - Implementation Phase (CG + WG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | - -### Phase 2 - Proposed Spec Text Available (CG + WG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | -| [I/O][wasi-io] | Dan Gohman | -| [Filesystem][wasi-filesystem] | Dan Gohman | -| ["Classic" Command-Line][wasi-classic-command] | Dan Gohman | -| [Clocks][wasi-clocks] | Dan Gohman | -| [Random][wasi-random] | Dan Gohman | -| [Handle Index][wasi-handle-index] | Dan Gohman | -| [Poll][wasi-poll] | Dan Gohman | -| [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | - -### Phase 1 - Feature Proposal (CG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | -| [Crypto][wasi-crypto] | Frank Denis and Daiki Ueno | - -### Phase 0 - Pre-Proposal (CG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | -| [proxy-wasm][wasi-proxy-wasm] | Piotr Sikora | - -### Contributing new proposals - -Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. - -[wasi-clocks]: https://github.com/WebAssembly/wasi-clocks -[wasi-classic-command]: https://github.com/WebAssembly/wasi-classic-command -[wasi-crypto]: https://github.com/WebAssembly/wasi-crypto -[wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem -[wasi-io]: https://github.com/WebAssembly/wasi-io -[wasi-misc]: https://github.com/WebAssembly/wasi-misc -[wasi-nn]: https://github.com/WebAssembly/wasi-nn -[wasi-proxy-wasm]: https://github.com/proxy-wasm/spec -[wasi-random]: https://github.com/WebAssembly/wasi-random -[wasi-handle-index]: https://github.com/WebAssembly/wasi-handle-index -[wasi-poll]: https://github.com/WebAssembly/wasi-poll diff --git a/proposals/clocks/docs/README.md b/proposals/clocks/docs/README.md deleted file mode 100644 index bb6d81b25..000000000 --- a/proposals/clocks/docs/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Documentation - -WASI documentation includes: - - [Overview](WASI-overview.md): provides an introduction to WASI and its history - - [Goals](HighLevelGoals.md): a succinct list of WASI's design goals - - [Design Principles](DesignPrinciples.md): discusses details on the principles of capability-based security, scope, - POSIX/Web, etc. - - [WITX](witx.md): an introduction to the WITX specification language - - [Process](Process.md): describes how to move a WASI proposal in to the specification - - [Proposals](Proposals.md): lists the current WASI proposals by phase - -Additionally, here are some links that may be helpful in understanding WASI: - - The blog post introducing WASI: [Standardizing WASI: A system interface to run WebAssembly outside the web](https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/) - - The [wasi.dev](https://wasi.dev) web site includes links to more information about WASI, including how to get started using it - - This repository's [issue tracker](https://github.com/WebAssembly/WASI/issues) \ No newline at end of file diff --git a/proposals/clocks/docs/WASI-overview.md b/proposals/clocks/docs/WASI-overview.md deleted file mode 100644 index faabc2eff..000000000 --- a/proposals/clocks/docs/WASI-overview.md +++ /dev/null @@ -1,147 +0,0 @@ -# WASI: WebAssembly System Interface - -WebAssembly System Interface, or WASI, is a family of APIs for WebAssembly -being designed and standardized through the WASI Subgroup of the W3C -WebAssembly Commmunity Group. Initially, the focus is on system-oriented APIs, -covering files, networking, and a few other things. Additional domains are -expected to be added in the future. - -WebAssembly is designed to run well on the Web, however it's -[not limited to the Web](https://github.com/WebAssembly/design/blob/master/NonWeb.md). -The core WebAssembly language is independent of its surrounding -environment, and WebAssembly interacts with the outside world -exclusively through APIs. On the Web, it naturally uses the -existing Web APIs provided by browsers. - -WASI is an effort to provide general-purpose APIs for supporting -non-Web use cases. The focus is on designing clean and portable APIs which -can be implemented on multiple platforms by multiple engines, and which -don't depend on browser functionality (although they still can run in -browsers; see below). - -## Capability-Oriented - -WASI's core design follows -[CloudABI](https://cloudabi.org/)'s -(and in turn -[Capsicum](https://www.cl.cam.ac.uk/research/security/capsicum/))'s concept of -[capability-based security](https://en.wikipedia.org/wiki/Capability-based_security), -which fits well into WebAssembly's sandbox model. Files, -directories, network sockets, and other resources are identified -by UNIX-like file descriptors, which are indices into external -tables whose elements represent capabilities. Similar to how core -WebAssembly provides no ability to access the outside world without -calling imported functions, WASI APIs provide no ability to access -the outside world without an associated capability. - -For example, instead of a typical -[open](http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html) -system call, WASI provides an -[openat](https://linux.die.net/man/2/openat)-like -system call, requiring the calling process to have a file -descriptor for a directory that contains the file, representing the -capability to open files within that directory. (These ideas are -common in capability-based systems.) - -However, the WASI libc implementation still does provide an -implementation of open, by taking the approach of -[libpreopen](https://github.com/musec/libpreopen). -Programs may be granted capabilities for directories on launch, and -the library maintains a mapping from their filesystem path to the -file descriptor indices representing the associated capabilities. -When a program calls open, they look up the file name in the map, -and automatically supply the appropriate directory capability. It -also means WASI doesn't require the use of CloudABI's `program_main` -construct. This eases porting of existing applications without -compromising the underlying capability model. See the diagram below -for how libpreopen fits into the overall software architecture. - -WASI also automatically provides file descriptors for standard -input and output, and WASI libc provides a normal `printf`. In -general, WASI is aiming to support a fairly full-featured libc -implementation, with the current implementation work being based on -[musl](http://www.musl-libc.org/). - -## Portable System Interface for WebAssembly - -WASI is being designed from the ground up for WebAssembly, with -sandboxing, portability, and API tidiness in mind, making natural -use of WebAssembly features such as i64, import functions with -descriptive names and typed arguments, and aiming to avoid being -tied to a particular implementation. - -We often call functions in these APIs "syscalls", because they -serve an analogous purpose to system calls in native executables. -However, they're just functions that are provided by the -surrounding environment that can do I/O on behalf of the program. - -WASI is starting with a basic POSIX-like set of syscall functions, -though adapted to suit the needs of WebAssembly, such as in -excluding functions such as fork and exec which aren't easily -implementable in some of the places people want to run WebAssembly, -and such as in adopting a capabilities-oriented design. - -And, as WebAssembly grows support for -[host bindings](https://github.com/webassembly/host-bindings) -and related features, capabilities can evolve to being represented -as opaque, unforgeable -[reference typed values](https://github.com/WebAssembly/reference-types), -which can allow for finer-grained control over capabilities, and -make the API more accessible beyond the C-like languages that -POSIX-style APIs are typically aimed at. - -## WASI Software Architecture - -To facilitate use of the WASI API, a libc -implementation called WASI libc is being developed, which presents -a relatively normal musl-based libc interface, implemented on top -of a libpreopen-like layer and a system call wrapper layer (derived -from the "bottom half" of -[cloudlibc](https://github.com/NuxiNL/cloudlibc)). -The system call wrapper layer makes calls to the actual WASI -implementation, which may map these calls to whatever the -surrounding environment provides, whether it's native OS resources, -JS runtime resources, or something else entirely. - -[This libc is part of a "sysroot"](https://github.com/CraneStation/wasi-sysroot), -which is a directory containing compiled libraries and C/C++ header -files providing standard library and related facilities laid out in -a standard way to allow compilers to use it directly. - -With the [LLVM 8.0](http://llvm.org/) -release, the WebAssembly backend is now officially stable, but LLVM -itself doesn't provide a libc - a standard C library, which you -need to build anything with clang. This is what the WASI-enabled -sysroot provides, so the combination of clang in LLVM 8.0 and the -new WASI-enabled sysroot provides usable Rust and C compilation -environments that can produce executable wasm programs. - -![WASI software architecture diagram](wasi-software-architecture.png "WASI software architecture diagram") - -## Future Evolution - -The first version of WASI is relatively simple, small, and -POSIX-like in order to make it easy for implementers to prototype -it and port existing code to it, making it a good way to start -building momentum and allow us to start getting feedback based on -experience. - -Future versions will change based on experience -and feedback with the first version, and add features to address -new use cases. They may also see significant architectural -changes. Because all of the APIs are accessed through regular -WebAssembly imports, APIs can be implemented either by wasm -runtimes directly or by other WebAssembly modules. So if WASI APIs -change significantly, the old APIs can be implemented as a library -on top of the new APIs. - -## Can WASI apps run on the Web? - -While this isn't the initial focus, it's possible to implement WASI -APIs from JavaScript, since they're just regular WebAssembly imports, -so it's possible to run WASI modules on the Web. - -And in the future, it's possible that -[builtin modules](https://github.com/tc39/ecma262/issues/395) -could take these ideas even further allowing easier and tighter -integration between .wasm modules importing WASI and the Web. diff --git a/proposals/clocks/docs/wasi-software-architecture.png b/proposals/clocks/docs/wasi-software-architecture.png deleted file mode 100644 index 6cb8345cc43cba2410d05ee1db06e929ba335fcb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28267 zcmbTdbySpH)HZI?DP1DnGBk*QG$P&I9Rov3i_{PUN;fj}P$JzDf+CH8zyQL~Eh+uG z!RL8??;r2_*0;XpTCQ35xzD-xIcJ}JUHdwlNHrCCTr5hgJ9qBjzEqIWxO3+o_|BcX zZ!pk+C&YL={&((xd0)y%YQ3J`%EI&~UcT(ng%Lb?fkC$#@3fPE41REr@c|COlH7~L z4+`q)Y6R-)>THX_2KiVzr4xB}>h`j)IM^Q_opD&S4!?!J{-E*jq2xo+Yaix=&hMb+ zDaMT1wAt13)8{!>-aBdD^CxNZej?PNKcg{p<$9LjpQ1{AlM?51vP}1ke7$xezOR5kAz&k6@4c>j=UEvCII`o*@X|VUZoUTFZ-*F z1Py1uBAw4ix=l*=1q21?`0OvABo2rkYiNC4Uss+abonlAY%}^t z%vKS7lbo_z5Z^+-AO>CNpQIl@Vh9~1Yihwue_BBf+|H*_4+Uj?2u!S=8Z}tuoW&p5 zI~jFi9oZ81W`+_-DP)X_4Ni#)@SSgK4y7NBVebYG-b;fUe9#UGyik*TxvR?1?Afk; zsV~cGOBYJ8=t$37eUM!u>VrJFe!YF4w2gTAetE;m`_@RYgnC4KrLPSSFsi@Q>e^aa z;$i>LuuVi5m+YxdrSoh74wcB&SS(@Iu2vA(ydMHsTSK105ug=lK2;y{NnLAZW17VK zy8hMV*CN7Mn?Y#|y8J1tWil@6=T1u}Td!ZJUyWo1>9@1+BF;DYU4YM|%PQ(jJgBj? zG*?u=8mFBso3E6g({ok?I@;62;rsj1eeKdSRHXUD%R$EVi`ld9)n|9j!7@NQ8~qrs zdt3J%c&>pR;^al+!9qLjL4dw>(DD{G_km%EXYDVYsP7yBfzB3YR;Sm=8xwxC>Jv_{ zmCtEU&`zK|--Rf}y+%{EMZKuMaYhnIK@Bzd+)M)YB3GrGKG(d3H1E{;C7CcSEB2~n z;ZZS|Qq?4|i zHXat%_uw)=%vm+{Y_*6{v*@eTKd5|eLlLf}-wa9kT&>IEHb3+FP?g0M z|DsqO9FKM62RDF~g2T6$cB?KwY2({{Uo~lyNefsPm_Fur?A@q4e=JJ8t8{kXodvM6 z_YLNPP}@uy5gM*szF(Z)z;KL&bCV6&%;BTcQYf3E zj!7_cDql6qa*ZVO{#ECm$Ij>xYe?9^=c`S**hw6ct6rWkimuf61(pZ;c(rx*YRd?x=<;nfUC>La(+=ySjdQ|LbZbZi)|))49gA)y}O<& zxujD{c2cQQmWX^w2~{pli2F?XtJb1+zeUzv24fE!JEeTJiqPf2*(w?)zIs( z$WZeTdxK9GPwRV>Q~AuNs|J28Y_YPl8bms>Tv`hAy_aa#9nW zzhemNIe$qrLQ^`)rhgiC!jnQDO5m3IBc^O!oy6t=mJw*wnyIXOD73Nl5~9%JX;}}P z-s7GIx@jAy-Ehkf4qD_wsMZ3Adu8TZ3z^x@G)+P&42aAZ#zW^+pN=8UCsbhwdBWWI zFoc-MSttfoKNb#V490Y(B#5iiq13pEi`9iT7P$@C1{Kbc3ps^2@}%==t&cVcm^Pd=o`%`-)&tXA{JO2Ze`l3W ztjY3?T^y6{5nVj964rEWBr8=Yl(bHg!7su*6_=d6#`~bBA-9|Y?rbw64pI4IO3s7P z`eqrSK`t-ii`5mWg0&MvH8|9OyK}eSQB`+CeMC%VgxdF9RJ8}!hSYgx2@ezGPA(qW zQ-0bh#<4Sd;<=&&1PW@3sneWl*Tg~^4H$+JWj}U51_EPbP-#c$PDogt1N23Q>l4KY zJF4W4*SQ0v;$0x~H0Tc>UhvvC%=fP3$+|+s8tFp zXl=Iz%L2h)TLQcjxqAc1bRPh+E5$(0zA={A^7h!uJS9I^vUJ076eW0U%Zzs>v&k$?RU-?sIXIPSk1G#!tD~+9MO(>;+ zp*daTzylZLBzG2g9y(K;1p>FIcCfTOk4fV{dbVN^O7N(YIOW8cW`mDuxIx{E0G`1D zBR^36+p=`X9w@67t$s{^;8;$>waV>F7~*@KxMzN^Fh4OiH|K^Y>W}BE3@oiAJIre?wru$=~6%CSgCn-Fpw;%58d& zvPS|C(gS-)FFVoz_;oHMk2R_XMj(X&qxxT-sPlsXPq0J&_s+6}c@tt2+^m}s?Qvm0 zmUOpPT3wHWfki3TiT$}mKey=XKX%)VPYsXW%&>j8yZP2|gT9e!+eJ3-$v%_f{05!k z<ROaP#sJ}Ku1zegCwccxVX7Q(2OE$KFR ztj$Qg!lW4osqU}#G;nDYq+)D>b&uePS_D{2KvO#j zfw2+@n2(b4$pwObd4Jm>Wr36??c4luK65Qq;(1w?nsdO_ksQD3{uS1n|T+$*f(HlrUP48U_CpoIWuCiNRG(4ZO` zoX*pH@21Ca18^LJ2Zg<#<~b*-hAl|m?s5;TryMtQLE<$ntEp})J_XO2{Ea=i5X+7= zl!Jzn;g5J{0L2wmbrH?#2er#LJZRe;;!_~lTQKE&P}y{~XRBnEW2gonP@Sp>XsFA2 z?$`Ar&7I%JJy1_|%TOHeN=P(i1;e>PjfVAVQ4|>=s#AGz$`@am$26pXl<4Q8q!>4D zu5VTB6L4o*+H`NT`mNjtg(L(O{xh4Wv{)!`t;har^NM87_RZACh(C|Nn>&RDgE9_? zN5swjhZzWGa)*1p{=`_*hj2xr%mJY$9!8^aoxZoN0s@-PV*l-$j3@EeH}V>z2g8CYO}z+_hZ z0wBx*0kB?nlCIgbiK5et1}gk3T$s!pX=boD`TCL^O5TI^9a($X75JqwI*r-&dH)QX zJO)ny`EiJd7!ObLg;-rj%zeGsA!Xy4k30>>xhHj{kQ)@BNKMO;AxusL{+%4ygHZ9$zz>2PZFLsTZkTpX$+Wny=jTo(%S^3d(d@eQJzviXEE+aExvAO>-J*`BWiu zq>ZUBY_wIr%`HAdlT(SmPLsFr=^Z45jX+LW#=rtaBoH!cgkpw+e?Fe+ zEc^VNZgj~JCHVT!nq_R{wYh`Yba!S3C;=q5Po25LsGGEyX)d*_Ksh}TiNfMzIgW-> z;H0I!?`+x^Sup8(66NK%Uu)(^u1@~aQoDp30lf`~!wnDB+;ZoE-Ea_6H^xGRY&0ZO z3N?;BKp2^W&ECl51({L^HM-w}>j>+ns%UvGQX05PSfRq*Bc|e0q6hCTB34sBwI-k z3?)d@e%Kd|^`6nYM^*+cz#2)g5I+NrbpOJem+KG-kv>8|Qb~{;NEQfKj_9GL?Sy*w zPZ3E$@Y;hn+pe6cf`nrEH=YheJJd>DFa30MhY^(hc^*XCO10md?Li(o0|Rp%8SEU^ z8%+1Ulsv#3xl~NqPY>6E8s%1pBfmddg(5U+EFEJZL?Z%?Q6#BSx~D`%9Xv5(li;{V(Wu}V9-Iqp4M7fAL*=O}B%N(3$mo^R7}Fhlw8U zDJ%rR$>f{92M+*XexI+?Gh>$JpEaQ~Ll%F=K{%4#f-4ZG|NHkhaH?MsA-D~nSw6gJ z_~#Mv-#9EpDFguVO{fOo_V)KJDE|*whUD2H{|UD6o8PzKI?|y2|1bd8>)PMts)@2f z$U>zw@mB!t55A|#XEj$`#4*093aF}B`zM0 zU-o8;Yu|HOt}SnV?NTf_LPfi)lkI;hW<7;K=jYQkGAT)GAe+0){EI#rqOCQ{9Lq88 zs}AAYw3PubG$kMQe>HYLU?2F*Wz_WVTWR*2hGH^}M|1Lak6FKyH&k=CD3un)JKH}f64^X!SZDBFrU2JAYcCu0A$LWeA50A>-UYpi0g`&G~|n$NX%FR z9JgR;e)Poguy&FVo_x z!TManxB6P3l|WYirK-zx;o-V&`S9)M4HZbf#uxqM(zaO6;h5U^qJd1(=^J3ztd|^K+ZdAG`d*74Oux{h-HXl4fFBypFNZ(zC zh?BHmN~6bPRhlf;#|4vi^9wFc{);^4Z$CPNB{8vFoK1hW>*)XvVf5(_vvbZ*+Ckmy zKmI$*uWGD+a<7aVHABW0BrU7BeD}O|2}^-ASG)N!C5TdJHj_q+gf0L*q*iy_p{vPI zOF2b6qIA04Atmx#^pDB;4-SP0eT2!6_Gpk%B?ZWK=IDA;YZiWupI85$3GIgF_H47F zn6L3sqyRZ^JUE`7FutLm)82aF3e;G%smvpf@p@j?M0W9}^5O8tJgxybSJWsuiyRAB z9)AG$Ds7eH5xAe}OOd_tN)W zHkQyZ`%R1H^Q*HmFKV1#DIyy-luiK^MUY%#r$>SgM*wP^0H7e0O#{ZPA~HfJ5%EY@4t2jsj#{de0vKCA>=zwCXvJ2 z#6&$j@+e?`l|1kH<4HHj7GL~#3+Y2Xm1_a}X{7;HEEKc+FEg|%uB%;bjlh2YN@zvL zMMuNJbF=BCHJZ{OE?Z=$r{>#$cDO@TUX=syCs=h(Z7hR!vT(%x*dB+$tfsUFd53ms zU1ocv8zXi1!wC8Uanb^H$zhUVR zzI1A0VUWrn6Pfv?OQ<7|ld0@`fwVy8p9rk^94#Y;EUxubcV^jfC=joz`kmTAz7}G2 zGu15+cLip97}%fKIA`4kZ+?Ew&gpvmgM1x=$-4gYS}vt~>s3$|IEvbrSeZP>kXjzW zLF2oGySn^CqDyIjPiAswa*|NJ(N~(d-w-wNM0UyyiMKI>mFJ}W{*4R?tVD`ba?2Bb{MAxY`wNRKg=@xIyYkA~tSaJR!un9L@Vey zgukVldC0jBFA_`TtWk9Uiqr(;>az7enJ(sPTBz&#KB9kjej&AIE=O3rt+(n4xxfem zNjPrS6M_-GY;;&gdCbi7S;h|X@*jC7r?GV|cHI5HOuDK}Ci7fB(INPF++N_E(_OWX zEeT`iL-k+5W_-JvgnQG#^k7ZuGIk~){diaeaa05uL-TW`ga4@1K%^hweqX}7qdedp zS)BSjGlJka*t#bm5}~0LjD`A{d8v^s1SV;EufMhz6sM4yXWX<9ua5|7|4gvZG;c*~ zm*K4zS2wmf5t<*#mhCf5qtZ#5y3TW;lq zl7mnS(Juag#Y0%**)PxiFZq14;8_Oc-^9%Xg*HdH3Ad*=gf(Ce{BKC`4(KF8>HO5s zOb^+!@-liRkBXOU!`(~VsAo$(9={^H&F5y+4>F>HJ!cHoihn&Fl^bc$PsQl1+Me~7 z^uSKJN%;(m{|7(#9|`&Y&JTKE@c$z}_OSjvlNE)uzYGS{rJ;8hLh3c z%3BllW*R#3af@jXoQ6ktu-(|L!pM@vwFUYd4ZZ)8s0>fo%nc2hM7BhQ36bnKZC}++ z?*{+HI!=4!V}tAXiNT04L0JK;frsI+Y=ys|Ji(EFBYYw+*EBglvMC~XX#^eq$zb&> z-)(4XRMf7U2P>eO#;Cw0TW{*yug zx#T~V_n&kE$SMEOByqx((C%ODi8K#rT5JZRkHVEKKa#SL4rW~f}?X$oiC%NvC`nIFSj z{KA{5Bh91#x*<@XU-KU-e9s08lqR$yzilYCwD-K^%W_g5kVMDwysoI}*P$sb`_%4s z9F{WG*C2MIayteAcO^CL|Mb34Sbj6jZI6t_ApB^!W>~`6BBcZs>Q!$ikIzx zfNuS5zd6NeJ8*7r%&x zXy<5S7z&?Ls)=g79O@e%MBlU&+nPy;?DRddWU)X0a%|CFT$tr|`e?f)rq{z3siqv` z*m<;A`CG3+C-oW6s6=*Nu}#=b7Qxkf+C|O~6)7TIwFTTQj11!UzAYi?(KnJvM)@K6 zGVAri&m%k`oJj18q@nVX^C;V3zh?lH8<2=p+|7Z2_aV0~_aL*SbCiZ3oc+-9&0Adc zhErYRAgvi8a~mMnjN|pZQLMKY&B$H3K=_~+#TKoA!=?KK-|hHROC@A4cV7-K9RIsn z%*Us7UE=08AH|RF=0T+NQf;1oQkgcbu5VFCg}xRGD##q}+SWj}=ua4skY@p9 z?K^PmT-23(H*M9h7phvho@HmigKX zIOLvjSF>|d3Y|!q$Fe?xKkt0k@q^BS3852KA{~m+gZYr*sq0??k(QY319&KA}9hKh(X|hUISGQu&j6km|h02fCqodv24Tv^O}_ zR&B)fY(oj&OG&zrdUl+^hsnfLWslM!srWL9W=dwnGWjnBx&Pp4d+ZG66##j0Zs*0f z_X4S&sbm=EVO9IG-MCVrxM;X1(poui_D5)a{WVc`nNS2~NI1LlRKvFsN&mRZ$QlbL z6goqcgD&~j3Q~6}6O~D*?`i9Qn>PH(+PZ)Pl8X$=MtqPG%R3VvuCNGrcnu#Bp%CG+ zWQbQIIy+p@jf#yNQ@uPQe802BEC}?B{wxwjzt1oYsr}K=5!3Mtdf6%5L6B?kh>)xC zjBtd>lpMJJ!HH{7F}mMh=JW)hJ14p_oXf|MPmqKG3i?coYq;iHP}om7nbZCqj%Svi zhtp?uITK3rtFobkx52I|)SF7I${Zh-;g{P)B=-OfqX*}@i=5mqp57t!o?0wUM~%5? zDh{~-z^zLO$^cSwe!GZVb$AY6AWfe?wYRGA_*Gn*Ug|2$p|8G=TQ3#8v0 zh^YgvVBSVwV%%q>_ko|3r9nbEI>o+-ya1`e$KEsqVyxiL^l29f2N}^$^wxnK_NzMr zzIZOSEoS>RRSM((Zh1l|dmFJWD2(hWMD392u`M009Rwd-g&a>p*OIE}TI^2397IuG zKUtK5oeqb4ux#+1yOuU|wxnbK(7k2c{r+c)waWBVuhVM5Z^TcN8vW6T%<1(?&Hcoo z$v+gUj%9&8&j6_|k$@+}D&%4ANm&aw4>_pf?$GBgqpJRlbM`^y=iD5gO1Jtc{C)cS zOWV>~_v*3Y3sxlL+H4vr+gd#F&DfBCssVDxN=XE*MwrNv-c{aRBiKbY8h z{VVGFHoV!X3)#ADMCedBB?3GkcKjtv+--h5s?dx_)1xAK-sxih4~#)^p|Dr}$~d@^ zC^_}yQufQFTkMXh1_tO2uHY>I@Jtis_3rlR`>400bE5aAzTXV1nfb=JE!6tA&t?95SpS2k> z@0O1+(2mw>&D;0@o&zM52XuM9-97CB=kcZOcAEepUG9Vd1VN5!Op%} zw-MqK4QxDHEenCB?XJb8;~9q_)877(=QvEN&7n=gV|Zf#Gmi7T1?tgU4*&L696(Dd z1xuu4ttxL&ce6F_<6fbZ&e`s-j0$xgmc~=Dr}6!%>gZa|+O_IJE+7bz_7@&1U=#v= zR|I0(du>lNwV|U+{@V7GmR5Xk_$;LcBe)Wa%d>rY?};6X=xfz7Yu~&nsA=<+N*Ae2%FB5M@gw{WsUlxi2vzT62^HB`IdiaA zB9R&e*2@8l$Htk^UuX^DJWdpg$*Ab^Bfzh9PXTS>tejmjjRPgBKMcon~1t=s4!w4nT^3;SD zXnch8z)#zr8b(za2WV)ykZSa<MQx4Gi-m!fT71_?!8gn=eQnPdE-wvbk43H<(rp zeVzUFb!;HDF7|G;|A6v9vo2S;W8r#i59EC((usQ_+RE)P zsus}ucJiwhjtHfoq9Je9t9W{iLeVYh+h2ACrz<}v7!}bpR_L8QHOUJ z%QzQyxigk4nYN8U7}IM%cZrOP#>$i+Wpyd3S6)rpZh@&0v{+zsJ{Or>@IJQcI*RiwP`NUNPyA>q; zNwV}P7h=egCSbm3;#2^+UwwE~H{4JgRRAn1>EC_srh&vVjK8*_AOvLM zQcty0}^oIT~iJ>ipNRv!;Y=)~n}SU7ljto)b`7;)5VYGS{eKYsZLTAcNq^5Xer zv*+XfC6jNgD)uY*?FBu~!EIT{QkSr+*(hMh0>G>L+!|$`V z7)#tj8{FN7As6+ppr(!LLiqb1pPZg~JLd21cu>!*l;&buR!f?Se=+OF+i(*?_6UD# z!R#=D!>H*!37yT5b^$^ir$Swq z_-aew=f$j2Z`+75K+5%o)_a`j4Me|1AH|$UyC<~8LYerN zIeffeBZk`L`joWklY#cUyuN41zM#PVLxKIWYM>&=Tw(BwB9fw)ZI^jn0oyoq`4lp1 zE;4TCr7-4jsYBjbd(cbtbg10yIx`j%j%q5|YHB%E(ReI_^NLJwuq!ROkok)N%J68! z?4+1c9*gtjBp;OyBLTnw2~R{?s6qypS4=3Ztt>evW_CK>)myc~9`Cf4`5{~UYdl(I z!6pRA^2raCC~zxU0!G%9@3={!rpx4kAg-QB`RfccgLIvVKWsO@?q%t)D&K8mAa%4Y427c zTHs#pn&4CZd!K6>t4G;r_pWqdltWAcBkBn;*aBXvY?WV3vYCb}s+lWqm*QKM4GEG3 z!^`BXGi1aJsfhrta%J;dHIZjUh zwe_89(579?%69>#m%>q@A;ij6@JH1v!yP`rP_@?)S}6s>=6X#_CD`@ z-!Up{vb*R^*DVD7c+3^c5VADkqqnQl`~LS-f4D7yWwVb%mk#6Qhw6fQ{@>Cr4k}{? z5k4d~?ywmSyc6f25AqlpC@CKF45XHH=Fgb3vppYMmjol<*8UcR8QLxW2&z|^!;G0#5TQOaDcFkr_sA>6c~*$(Rei)^mZO6wZ08?JK%D z?`E_L7wUP}TM=_m%hO9z9d#NAx<36@L&MJ#F~9@1U`?zY(DQypKq1sjxYgs#^cPoJ ztYfVhSA6tbnz{mpm?BVL-?X{62s0ySWIa?W?(xNp}KGc`d?| zPU}Bw`N4N{S--*zK|@~@Z*n$qv@!Wep0Cffa~kuHV#HE1A160jmY}{qIP5_^=?jDW zSVF5XJo+lrlyO-;aiaU98}j||NKJrhE~cMi28u_48$L8p(0IcBgV3Hn6+6h5!1VTR ziQth%4_7L-g2{g_x|!7k?2)>Mf>R!E5K6 zC=Mv-T)#g41EZLfS0x+wwc~~p|HWX(gP1%BXM6A4!?U-wFsf;$w#p66+boLFgS>D< zS9@9VwR7Av$|6la0Sx8OT}=ytTnb~$^V-fDM|XnYH;_&UQl46Q(po2hIMW$diSRzy zn#NQjJgG*!lswxq8HcSiTtq$s43STGoIm-{{QwZFp9z!Wo)kV&Ng&d?RMozFOAQq4 z?zkUhBlIZ2hT_fMX`z^Oq3?$2c;(cw4P6 z-bMB4ztBhwBSCGojd!qX0x5+vqDVWUXi4;B{$i_ulbWrslhS?e*JYJh9t+=XEm5I| z>l{-VeF5txc2*egE2ALWzokQpZ3o+5;s)$L4LAHcwpZLe1kRQuY_e0*FQH8x)AoAh zu}Z{khtJPIDFpi7HV%5 ztD0qHzhl{K9wUo0IVQqxQGcdcVRL-*EylqVQ9eqcmJvU8(9@tj>hgnoSD)?_usWtT zjCT0sgnMHJeeQU^&SzWZKhSW|!hPZ%eNt!mDNnTi3NJFQYzH_`Kp)ysGmx5QqSdJOS0Os(O1ssha+14w}oz zX-#~{D68KxU9**cG2V}dN!LBiKQ&V$0F;Ib>bwVP>2vS z@LY6K3BiakdfBNLwnkz)FTZV`8rnny<~xsyaXG;tj))>QS@j7@c1AjZ6(*ZVpvBU_ z5-FT;Pj>3n;Nj2uv`wHO5K1YedXTO`Y%NwmDlEh|d0SBx^{*(e{x^XKE-3$(C$|DJ zP?z`rOUcCl%F72j2Rp)=kx_Anr-6sg%o|_*5{YQB} zn{$|Q>_jZ?ScKnQz6|wDr>Rxtzp6c*IZ{oSd*fQEy6irkWd*3-}ms>9*CCPG(j*haB();zwRm4yhXD{eGPKZHpY3 zTjN6YZ+&`7X7Qo+P0oQgory_!gQD!u!l7v`T>UgV0yybBynvb)@O6ISqU!06(BBe{ z`a2Xt#D~z957W5XZXnD*rmeKow&eHC89##k9b!gLmMjV!JW5E*gTL{RE`j_kBtW=- zf<`aSx_Tq*U2VGUH!X8c1NiWQdU*YlOYcLJ$a!>4;5O``BAs>62j&6fNhnoe6TT0x zax#ko;@rtr`7PvNb>f5Q^K?-UyWV;d*2YhM@$KwaN)=UVRx#p^B^;^EbL-e1!;>#` zRarzrvN}N>P;+A>2Q|@kb7|9;Rvu9_gy6D!Lg}-x^=@8sDF{sXF%I=H%MQ_?x_BMP z|EGz}T+H}f13Jj7vshoO^OmpB$$@33CvzQ;YQLiEltH*|%|%~RpGM3CQOwAgi;^>1 zO5#-q*Xg)1V#r|Q-mx%-1PVXxe+R-BmPlnZzXw~rk75|?(9^~u ziVBDx0=)$l*=QGZHZ1r<=7i;|aGd)He1JmkO{|ay)l7pls~BC3^0+{^p}Z1H@}U7% zq@&DojPrr(ysLPFH>jp(jTI*wie=I0@A471pQ@jx0=)NXZoe_lf$&5!^)X=q zpWox1*t?qJi4dZ3c;_7~ccvYQ9sHeKr@oJm`*UAE26cg2djc5fBbI;S)8{tWT3p{s z8TTBKpBCrk&6QAIhqif;gqfDy4VA4|Prv@Axk|w$dthnFPoEt_b$nOT9Ep#R9vCF~ z9!deAhfLuf1=>SGcA3l;9xzmxat6L|u}9XMkkk6xz^ujWovTwSQ{!yf#q;Mhd2A@O z15P-c{*0}Hb`m`Si=x!JN(o~{BUKz@(z=ZPi>(t2{BP0VJw-|F2^ZB?s|PScq8{bP zg7& zIyIv$?)!2LvfDo(8vg-J#2Qn&i4lw+mb6!8^8tnv{Whs*0ND`PX;>pcv?6n}MoRZ% zKuY(gw(A5}idwT`RI2>9M_4IL~Uo$HxWV|7FFL{Uz zHoQC+)iVV3jXc%|5wLa>&PuAP5C#OReg01Pikz&B1+gh3z<=73Pam*W|Xw4v}AupZ_SnL=6+sI)a~sfUx5F;+Pva*I?xKpb!bO8RDJL@@O*6( zxmkYL$p};o-&C*x>BXB!ougR9eFR=f(~wiaW3jw8I7HOzj0v@N`4{-|xxVQDb=ou9 z0XxH`3NRTt?>V~(X12tCFSCEw+s_oUSCo)+iH50Wct9>y0fGCk=G|GS{JK80=4T}g z1^%!0%`r_7)_wT%m3)8kDWG8g1y#MDHJI^ki>Aax-edn1$-S$~D;6kJX5lRVu)0b9 zm3X}Hzj05rN(|-|$GlQ6q7JPAvhVk=M6NKCT8BZqE7X!NcoOvA>(hnG4AtGWfd2i@ z$B;F_G4TAMrEhirc7#4uruw>@;d2c@7*MbGcky%tou9Dt^rflCUoiYTTYGVoR{24M zJrSdI@AbluhYW!?viof!HNfXwsvUNE{+Z|Htm&hbau3(X*wRs--e;y&-9(E=?1jp) zExFVDA}qmSbh1-2gnnxj>s#q4FC+m#ikQpW>^>;W_%O8i_{&yRm#pV4f^p z9x5h)X!AKg%IgbXk{FbF4=<~XI)m?0!^Rc>nvE$rhSsSfybx-eQju{kfGr1bts82} z)I)K^UacX8VeeO{_oD{0kKWH?%8EKO1|4VSxCdCf?x#7s3Z&M&t}G?Q-G z8;k727tp{Qzp)a zJvOP_Z&Ctz%ZLvJk{)6zvo)6ps)jJc=xHiID+>n(Wu8%rz9qP~1K}S;r&coBwTo#O zM>J`UqiILePy=OJQg+i$3SoIXk0ha>eJYy3O#Gj!p;Y3!>pu7up7sRk+JGV|@|DwN z$r(dF!t#Vz@_Pi=0)dvYc-CH5- zL40k?!*1MDCEAGK;H-l7wKBl;9VsGtV6qH>Oh(*L3`j5a?8kQuX0G$=O(n)f*F$%M zFzNW6^9Lkl!f0d^G(Trr9SEkrEzU?a^l8l=67ey_p!0gTZKX3@qn`}%t$9PB`Wfov z@v+ES^T}J7m+Q$UbL{=AM^a9<(|e@TpAF6R)jn$N2@-HCUun#R+bjoB@1+n}h>rFA z?kK~}R%dj%|2y6+Q@g{|^|R^Cr0fN#USlipVNB?gT;QT#0F^#9?@2oz7vwi;iAp)@ zgw=)LjBYm#)osu!UvhrJ^-Jz*aOMHtpI0|?0(WGH`JKlnU(HDe{QK^742GC{u6;F` zyT^f?!mD3pSXUu8WB5Bv6HM6Rvz-S!Xpp(ww=Xzd1)7H3MSgJuYsc07T57zxe=iar z=n#C{!ERdW0gm)uG=j#rP*vd-M1(R=!sWNl1LD6Q$F_K?bySV8rGa&c5{!yZ{BGjS#xaZbwuYyWO9a!xoA%I9))9VZ$uEX@c-$}i z(N`D)!|OZtZ`MRARQS@lJf^;LzhUEyEHP6ni_d<4ZQq9h?Zn{OMt9% zd$swplY?p^FCF3{f1T9L3%IGzna$C;t}10}v)60oD`UN&KOb7EKepyoT|N>85pWs9 zXbiMsJs{H!a|iMhBqnhl1%)XrvQ2%8(U*lmyN9Y`1*O4B`b4P}oFUri7qa}r0t-u{ z?D_RSMFM`Srm8)#5VZ;fKj7B-c!%8E4nu-F&HdpLiE$#}$bF z49N~HwznMO!5%4MEHK*|UUYOkw{F+aNo^@DG@ZCws69n5%o^2gTx!Yf(>_qq*}0tM zU(QY9ON7PsYnoi2TlXF7R%#z#t?J00F2;6Ew=R=zpX*L=4Nv%)eM##x{$A)XW9o7I zvhN3GQbhRS&}CInPRwrff#1%WVe;8fFbPGq{vH|&=&~q=wK-7XI&*TG*EmbOZIO)2 z_()}5Gja6-2p84?)-TUE3rpV+LhlB3snF;O`uBfal$g-6Y17rtu4@j;IlM&4Ctk!H zdYxu2^tq75JY#Ql4%~2yTgP2j&lhrvI1KlQ_ILXE;iBtQ&)R;2PrG%D?4uC_aGuJc zKj3B?GgiCwlf41oM*|zoNSVxaqFA?o{KcTzjEVzDsJy!C>)e37p?kS3PhP zJs?U`w}|mb_)A9z3==qncL}8(-CT+}m1iEfhYAhP8wW&@whHh4-n~rk5MXLKUBvaC zNfTC1jZ618MQlp4Q3sy+R#Rvy~fhqu1b!_jjcV@T~EW&1EQ&*I7Cacl^LPv3o^v>{A5uEX8zF11?hvlTGkp9z<1G$`5 zNY$;E5_#|1+OB+{hNaCZ~L>q(wrB!H`}?}TvR%fl6@9^X0d0jh3j1fBm=#RtpKjlrTxtl-g_Arl*~f zc8p}~*(V_|21U);;}OF8V&*N+qw?RaWi>xl$CW%bLkSCL2eQTO&X2Hr18Xn{qaq%vT z@C0Ju7RQu5Hyr6QHvR!oCg2cwKr?;%z_KabQ*I!;?C@utZ;!ljm&dYq9b&pPqh1K@ zWT-_gK;$RyetzeDkf@h{<4!07xyem+t|=LNaBxx9eXcK#Mmt4FGn2EuF?H!e!B(|9 zsk6M*u=A;Eo*u_0(xeOHInv zdgD*u?9@7hwvbtV$nzs^AyC$8s9kRxmkh?U+tz4~ z5BE?|?=dEA_)9n^V?f`nb_@bwf4 z>SWcHX-feLYe`ryKN=Cp=Qte3Ir8vCEu&5VKMCse7`F+WXT1wHXt zI>tL>`(nRz!1u8>AVvqosta!t!S?)Z47Tc~#?S*IHeNM{g}-lfdA;^lnn*qw?9J@q zckl-lcdpf10r9VKCc<1d-a0$@btQ6M_7f!ZPRdG{n`2>YXZD$Cr^3sFF>P!6=`K5> zZyugXO=lu341s==gEUWp)xx#o&>!VE-PE2`#cV>TnLd!yl0H|qalk>SGo%@C$`q+= ztM;kH`30(JAFG6}UTPn$#|cH8gT+wjTC-n{)}rR5N&KhVa%*(=jgH!Oqy*^rgip@8 zaErEIDnidbj|j($+Q03KuQ|1A@9|jH_eO%2XS)A@clnHKGm(c4&v86uv9xwF63V!RKP2 zV@9|D?kF*7^6bp)Be{Q&Oz=?JvtQ8-sTHZu*s@B#F3CROZY%^%HhQiXSO!`*?TZ@^ zJP-J6%QM^TWY*+B`W}eb+2kVmuI=r;N7a7K-{-m04lNxt4(p)My(Yp`EuiE#{waj&_I$TwbU3-ktdE z)h0~+Qn%GDb4WEytubdE5w^Zz+Afw)`96;RSzUY5dLM)NWuIo{wr2b%QQ~I}HOsE_ zV=TJcFJHxWL>EVYL*TxA74=ls<^A_n9Es03pVZ02m-=4@w2v~-DZK&niptoaAAbAe z!YcIhsNm{!Rm5-1NKE|s?`|TSP`4)b!OcbsGwT&^CEd0WiN~4Mz2nvA=XBW>O6$hy zymz$&yysp&V`vi3B*{lSzobg3K6lf}sgu;x3&;y_G79*H-(f;Co$l~M{7c1(yUcxkc9vAv*%V)m>mb~Ytq{Y`C5njE(u<<4I(Z_TFc2v2k$xLp$Zf}oh*V-JB zQD-sP7p}>U|B=RU#_nj_mPYYqRA9o0iD@m>deU>U`yVXs7%_h=Jo+5PcanS6X4!k( zmF7#Wf>Rum{Y8n&x#&DO=eLj5Bp#JC)0lfBy|DcczfLar&@bz4rRrCuYtOVc-@MECBS5ut zCSO@$__5iqUd08?uds-+?(SM-zsGXXU2R&^z4@;dH1ilEo&0##PyATUy*KI>FY+rb zn!Rac$R_$7M&@KISXeTR&KOE%4NU_K^pl(TM0gzZS+#R)3VSofKhPf->Tvwg6`gC? zVF5l|Pa`?4U#M%cSd-qS@0VI}ky&BV4mOo?S~83!*a!_fM*5`vo_EFh{P}@6+R^tb z7caSfrD-1SHQo2(pUOZ!_@%M|r4sXA|6fN}!B$n*M3s~lk#3Nd?(UKjiA#4~x?7O$ z2I=nZZqQ42H*)Fjj_+jrkHwu91?ISq5hx~cKmneHcl;!HQ3ZegwV+eRR#N^*x67>N8sL?ge1 z@XN1a&g!bKo;`)x*+v&!RnWQm$V!@MORTz;NM{22Vn0~^8n9^omRiV3L;Uuj}UjJj= z7PWzay^yvQ@`H%1&oo+tHM+C}SoHDaBTCWd0UDDgXa_2lY zE>gAbB*}$}j?6;FJmHI|q!&=D$KJ9gCi4y~2Tl-;^V+Q);Y96bQc|kGoe?@4b*Zt9 zoDI}=q@GD36~=N(F^+j7jK#+vDo8qP9{slelzChcp&J|bGF+QY83JJr4wKIw&hoPE=Mo7 zIttE~#+C>?UB_0%hr-r`B@9iQEnPtqr|De6F1*?KXxD?JWJ7o;lLbj8<#nc=C5g9 zY+f;18pa{X$Kj{*4<_Z!!ow4ai$f04$E9}bdQH{FA+GzF7LBO_Ta!LP2g6y9k0+)Z zS{%BmO;#g{5i3JniMJ$L<+R;J@$Rb2(P?!X56aBz_;^_If2OJhdCa}9|J zIL+}kV#k#X%oWn_tx9X*fRf}j?qGPmZTmTwS&LCORr$xH6Oy#bhj7>S;n3dBQ}kt5 zn-qv8ke6N)v##dqC-v?iOAofBu78ky!Q3lgf9@-1rH1 z0`_DjM9}GBT&}uX@u3@mFS91%185A(u&`|r*#C)HoC4= zxri`=Egua3;sqBiBOlNU^E;3b5M8w{>I3;ZVP$-kJb!n=K!#8M4ix=T6F#J>-MWI! zM`G!(sOhp4I^DA%QzXWs&$JmxCX~pgmc(~u5rK~9`fob7HzAH|pRu|Os5SK>n?)C1 zuC49$2pY|QiaEk{BNOw6vC;$|^F2XBIsQ^|GNlO!@Et&{f=68I;MIJcNMdn@0}i^L z&DTygbn<0SQR#z=^EBn3nr9T8JUGm&52<;v`AEmWcuN%mZ>}n$H0?xKmKp+|YL>PB zwji57VinNWf>tr;jT10;(Yx$!KcdEd>vFQ%`^j)~barup=T+bS;P1e$oeJp*qn|v; zBNfSxO&2~n%gf|+#ZM7bq;{!^#Ox3pxJiU~Q{dNX2OnS;QBpO!l`hE=*}il9N{UiY ze68#v`L@H3Bn0F(m%i^K4~t?5_4*uE{J#t4@pT&|EyED+)ucVId2{ua=5juCX9za3 zP0d%?*uP~YVN_=HA`-y0ZTUai%}Vpp=bVVKZM}`|+t^#~xD|3vfFgkJk3+p~1LsbMp|i8Lg$tcJ^gw8{ZqPnG&onjJeYl z3-5!-7;nbdgHpG+BXKkIUOJ9h+lAA>8{n(hRHfPvsQw(foxUSV1H^8tSn70GBgpa1 z7p-u2zdBxqXS(Vu!T+z@iM`@&y-l+6vR+v?`Wyavv8yap+!`^M({}5#E&UF2>)SP0ytmN@icYB3APSHm}$wIXVD|0*yDd=my=cZ@8mc z3S*SENA3|NKYG*3JfyOXO{LXxeW=OC8-F4H=7b;OwEg57*>Co)6`J?^@OU0$ z&vEVUZvh}Ahd5I00yi*RTE=-QTyvRcaegGJ4gU;RjX?eLsO$^+(nXP%70_fEKDZRx z3qO4S_-QBX31IAW9#`P=6LUE|hJk8;NH6$jyQk~IDB)q>iM#JNlmua<@5UQ-<|JMA z!tBADYPv2Y6m3{9sU>aB2a|~1a_euKb2&bmE6Dg^Mwe=4D`kEzM0ECUIscBeeHq5f2qa%-NI(MVeU}~PJRfykKOxpFm z_0DZ3@%)yC-Xb>KD?XE?IFdxGV6oBf(AZbtY46$P3DM;%n{H8@bE{Huej(^>OvTjsLD3U-o=@s1glM595f!MX5+Q4WD95 zpO;F|E*}{uz16=_X1+9UI|TjqF(jMDp2pJK42;z$dpnmV)Y=y3p}wT6Z|ac2)VTR>JM0!;K5!cau?f)*cl2Y09#uIA9=#HZq8==gvK~ z=fXi~P#%+0iU4EV;xxrb;pZ&Fb86M&ooqMr_X8vdQV?>(@$kj+2r1i7-yH`TSSd=s z2C_@xvtZ%DtH;0aPpA^kDuUg1fCG%;P0~PPUWxkX@>HJkBXRsuY4c;pw_Px0S^(@y zkMru{R+Ca+A}Lp9y05mKtVv-NWC$_5lk@^4<1D?no^NK zU`7dTz+dQfh$WGfzzar8ExSk=oHV?Lafxx*n3et+BRr#~uyMQxlav)1L`IP>qYv?h z2O~}BE4opfkSPpeGC#-M2udnRl7zqz4sbBoM?n;hK|<M?(5j@nI!yxvbwC>vlJr_=^X`N5;(F$gyfaFPHrGS3ni-?z3oQH1My z$~EE5e1IIrvWPQEuGi=A!H<%=L8I`P=wJJNB+UGs{cpCLzvKN>{sr|aAT@CxEHD^d zRcr2XZ}p;t@EUtvNQEXNr*JT!*}<}}{1=3umr0u0u3*dYxC<~PFt+`1CO(6a4&Fob zqgSDYAHj&2>Tx)KAMcNt!YM9!3fPx=C>bd#dq;;LXkf&r{?>ohGH>qh0SC3c*H^6% z-z8f_oGxd{@ME);0sVJB&)|f%*j((nKzZ|SrK9ir$#VIWC0sEJ#q`LsFqdthsau** zUL&tsR51DhJg_td_^Bl;p@v>!+0Rlq@Vb4aat7u|w0*_zSMXFdBW z8PL6c133mTH|tqWEBi2I3#mK~8ero4JPJYEm2c3-8o8LKL)QNCsg;QopO}qJIm*%v z8mzoK=f(PWM^hEB>tdZ`&>#bbkjz8rwPSHEjyAK@XbHzxfyYT5VX|X z49x?~FEjpf-;)c5(WdD1jDUxD#(&V5)JumJ<^@c9-YK09&Ks(5` zVusEa)4D`w?mb^MflA%kMMcBKK+$PAAOEDo{r;!$?hS=9WMc4M0&YCI4`XQr(lz*u z-Zv_@(OXfO{JK#=$Q1)!FTwxgTWPQw=piN=F*;CD_SvqM_WZnJhXV?T$-z-X<-EgT zhQCKcg1Rl#m4>W@k%jy3K(6{9f!@_T1MIypr+(g0?sbt;Ai0h4NS&K47jyYz{ut5w z@HQc*(Yd(Mze zc#Uv&|D!cnc+KAXmB#Ju{M=A4t%L*J537Q=kY;AL!t_URYie|z;5@{Dyf45 z%l51)^=}?CQk|7V({ub|jD+>mMtAp5ZH8@eq`4iR(C*@j401l=_qlC7M97psS4h$j zTvWv24n2fekeHaQo*(bHZpmaDQBxIwjeX$yLtp*@=BBo6IdAW&jeQHlC14=nUQGtL zgpHNqmKz48_Jvc*mUL4lTGflr)p0l^v@qhZB@14nU3|_s@gpJS4%1P zcHAMua9IRU`Qa~9PgmPeR5p38qtxT;xJ9zS@r<>|3e&d z3T*+tDoyAMdBUgEl!{&Tq`Y^yYK0{foVReF?H1OrnXDLI&a<`eO75&mafjZ|9eEX& zFjLr8%Yni9dgr@G%ow)HXHVlI1q}6NKQa)fQ7#d-v1s?t<>N@spJR7{z1hV~$hbkA zDR3LiAPTCKA5}**{IdwD+2hkz(w1UWdde#ZJRinbm z%_I=to0Kf-`Ox*aWsTyqnHc9A8t=gw!y2}h^;w60@I45?t@6@7qH}Op_F5#lS(-6^KQ-Ju%KIC-4jBf=QNd)QgLvC#W#J3r=zuGZ z6_Nvz1FY`%O9EO`E&tryE_hwuEMTEcGR*vfE)B}gt!a%IzT7wZ}85>M^O<4qc*+O+AT%EoP5;Ih34_B9Gk2T8Ot2A2{@40>UXy1>6E| z-nPRnVTV5|7!cr-qtfyCq>gb9zA4fys-q74+JHq?$NOGj&iV{HP8AEWS?k=Zw2^Al zGLEm>#`Oca$Jd;5V%L%T|%xeZGwV8gy|t*Tp-#im}{ z!W$b$X8Z}0_%nnyLo%HcniETVA8Fj4J1Hdoz?aanqi;)Cns@`DDHy5D~96g zZ)@+Yp&(wn$OKuOuWmBPX!%{Z4v_fpIW&iH6>%zaR#;xzF<(-%Wkn4_J1vwCMHrN+6v;X)$&=s4< z)mI^yIak2Rc>k>AhgN)Hs7Jp{Kraoc%(O+GRJxTy>Kv|18L>sp~zExB%#)fiqeRcE}< z4mKvgwnAABzixW3>!gV!m#W+_|`0y_YKasGj+ND zo28Voes+91{u?oS-R5VX>P*UI;ZLCg+1hG$@K)vVVy5;0&D-j)A#$0?FM<_Dva>$6i%p3ZWi&@=`h6$L#uJot%mQUJN!8RnxKk(eZz#>`0)=f~}` zI~(&=HWg!A6je$`j;dg=xT<{CVL$ElVS?8wzL)%PeiC6+di#E=17Rz7WbNT%de~5H zX1f!|xaol%qk!+dxE|N-4PC&K`N9})`ENBe(GmcO#(<40YUo86P>;Sahnf!i(w`<> z+vZFs;X@DQ4gugK+e0H3`NWj8<7AW$o$!Y+SoLATuMNEKM<0nsR2GOdHz>;q%>?&%Quwx?i%sI49odg_>eY9R~^DZc{$E#eE^+K z7V_Cy&W2HYIrXr}Ph?(17r2KLHfYDk+D1t6D;XHTc#k04P#qwf(2m~U0@OXH6Gp3) zQ*!VlACa(}-g;HT4vbduxdG9cEc8BeBCLR~ea>Mec;gCHU7U*YOp)m+h$^Tfzf3PJ z?u}BAjxh!T@KGh03r)=LewhXX%r`SO6j`}9cV+-&J;zT77pWqZ2(VztObSE*y_GYQ z1XkK@>+?`ROA=jDvVdvaj-MJiwp=Bu%9_f4dMYCK430HcCb-ach)_P2oTC#muAr2-41DiozH0CoDQF&x_h)bikdtemqP2Kl z6G9KJ6?bnBflcY?`*xYIm?9t(NDFdS-CJOcwFxSH=#TNH?oFs_b2+&$QyY=lHtaeU zk%sS5>FXID%}zSG3tX9Rp#s3^3pZH#6t;o50}^z(6e`x6klM;rJl;7z6yY5P%VA9HR%YDgYgGd-TGAFFOe|_gKddnCG=toC2U1?}O^} z;6ud}QV%As4=25U{w$kea;p}Hw=P6Zu~)>z<*(rb^AEhJSjTzNNEE(CS)#4|FnPe} zD!1ww!5(~KcfG%ZoZRV!V-Dey(Q)O!0M8TiU_)O3L@*q!U|}%P3ZQ4ll14qfVb6|u z!N#4rAub1!1#0=hi2V(kOu)xWn)Gk0Cj|HymQEpKad@PyL;7ee%6~29BR-$38HArN zEJDyQIa`U-Rv~D?a#^SSx`f<#^v7QN7A!=E2UK8E$* zgb17JtF$~k(h>G|NHID@rQ6;*3z8<#3iSp8W|KVS%TlCCVQ z5XFmN@>{#{pC$LA|CwvDLJ5RueTiq11UdIAmX-SZl>}y(g0>g`QI*4Rp3=>El7~7y zwuGZa8{~O4k0%SbuUx}&*xoKg(!J^cH*H_&9<(%*@E>C zB36ONjrgA8ziLfZzZ*tH*;DP`x3GvxjT2-^NVRcxrQ!)t1O6{ zC^GD{Zs-s=0*96$lkE7!H6vQOVUqr_lAUosIdilLR6v$q}OTrG;++O>$teqGyyA7}Ay#9C~2cHRI`PinP^*obQdHw0?z6mEAG{%hrJglaI zV`=K0{fZ|sJwWENz^1FIy(dq6U%LiGfs{_;^-=PSf!VFTSbgJQ9KqcWu9F`;#x)!D zFLGCufKWS`&@hjlX&8Q$AcX#BwNiD)bF1sB>ukPpM*nzmsH~#rhHfT_^X9&D?=*b> za~Ge+@bG(V{OZ@6Q>O=O#?`9Ij>*P;pe-G^<@3$fy&ld_@&UqnAdxlVI36-Rlb@0D zE%+q9qHsd5`_w?*dCzyH_61Pd*3^n^h&dScJSh8*gk9#;ZS_*7Wt4dhHb&B_*Cj0a zEB*wM{(u=hRk7qWL*jW+`>^s~^zK~yq}d&Q9oHH0!^c2e-^yad2}JrWGUhqv(W34o z!-HH`EwSKv(AgBN^KErb7y$9>{+=ET>kgy`>`YMBxP`xdp=$dnEJb{ zUN<&T4G?}Q>%O|a*%5c(HLbaidLKHV{kx<80)D{Xkdk!u!_x^DhkJ+n=R;W()T)p1#%r9n@gp=?6^>35V(ew>5=&>BcCW4DDvY z!I>nwxu5JLDXfKuxY47V`jrp;cIZ3iR9#pU%t-5Pq<}2Qba29h1WS;M#5;a z?A>Y#8v)nF0_k(aLpvS}1u7kGsIny_0`)PGJv2O&hgJULXe~lX|4$u|1~sE-Uu?bQ;vK| zXM~DvCSR_j@P^h()qonnGvuG2yA}ukpjOxX{rL1>n*ob%qi!4h=^R!9L<#i<28-B) zMGlpJu;E0muN7_X$#Hs1eLBy>-74yoClyR3XUmv{(3|V_AqQnxnKaO{jSUuU8^sZ; z+pHLV1BFr#wPf&_Yi!P#OC=50fbCIP9L4Rja&E(}egwm;=x+zUkzIXN#^^owZl<7# za5=G7vF_Pw!R*5Aa*+}qDeY;GAZc3@G5T*){BgFWKx&5@DYg zZqX`diT*8yx28oW%kW=p+*#l3_|H*wEa^k#_&Lp`k6ahz zMa_}hDGo~q7jGNusfd!g!4BTinv15)x9g_Kor|WtIKSC(dVjH!E95x83mc(?FZ>`O zR?hlaVeF$^y?D^K;U^3FFV%w#7*bX5cm?0he3uEEHVO7ovN8TmO>rl*k$NY5OEYo? zeG=Mx;;_+tgW+Pjrug=Bn|F=_{cZ<)s^_*-f*r&U{+k?EzV2`{f26{6&J)Q#s5X%S z-cDd&28unL;Rgvgw z1+k!32`$&q;}DvXkTZUJezX1*p>ZU;$hl1OX-Q@g8?mVy2qqP{y9tl%nxt*&W!Uvhtk5(S;cl@q=cr zHf8oKuDojvl0p0hF+cmN%MVI*rqF-38hak0(^tvbIDXd~t7thU^rUt9himoRvpMIM zoMQHhC_(fEMkQZR&gp_D@`0ZBOh;^VvAihlknd)$Z#)d@oaBuTi#~6`aZ8%bV1>yb zUio>J8uHkjMh~Lt*0OgJ%c=4o$;}q2dQ|%QyD&tGZqd#j)a3oTjzWFJ^6Mh)BY#s? z4drm@t{Hv`m_UT}V764NvF80d3FG4_dZ?tM@|kljc@qO8*{Rr4ky#4#FUj-jb#=Wl_f0I-$>Hc#k?23 z7-{}vAm#hCG<+X4A$&9!4GMXt`MSzEpHphiN=r)C@Y4Jc=02+Aq9xnUFGsNwY=vgF zR$Hih-~<7ET6a%PT`EcXBA<`J2bvcv_cr%Bg1FTKkBC(1%#n<>aSF4Rh*btx$RIShdd)Ij93OZ|UAMqy`VQj9G_-kf6d& zu!V81Kqar8i~4oLv24f#Un58pify3|*8CE)~1-WJU!muyOZ};%W zMYwi)9n|s{g9SnU%va>N@;LKBOosT8+#OMl^%VupbXM;B=iHMkTMTE_s!sa7@%cM* zZizt8&;6>f3^+I1TW;F6&ZsQ;96u!Tl_9*#nxwZ^Ki(vWbaW{z_i-&hIkHjmk!8Yw zu~AVlz@mS8lQd+l8Ab#RMEsKR_KiWj?8D7pDCt@}UCi8Xs?d-?w|24*GyOjo&n;xK zMTw>V?F|X$hzAA>%r*dD&Qw&ySmB^mTn;)1xOnT~Qt8DW&yc zpZHJrOI@5>2({{>i`k;ZM4v7+H!gUue9poF*BkYOMxmj2-55gm(@x`i?R4 zl@Wb4q*(^)q!TqENr@);!)t%%A#gzhHjW1mrjy(4RJ_x_x5LeBPa0{hKI^Xi^z^IM zd|40`m(gwdpS#$ta*5pUw4aepEwf6?L-d+7&Mcf}70jK$z?OcFZGA{dS`eHpRV%^& z1qnAr$?ANW)p#nuB~Z>!Q2#;psb)8ph1gH*|6jNv)g1bAEQ{c##uOQNIXj|V9PHux z@H*)u+-mxeNn#MS0r4<1}Us!+GB=I2QC!z}zA zFK8>0?TPI;m%=1=d402<>{Qn1@MnN has a proposal but they’re out sick today - -Till: This would make it hard to make minor updates, because then you’d have to change names every time a version changes. - -Dan: Resolution of imports happens in the VM. So we can program how that works - -Till: If resolution happens in a client they may not have a complete index of all modules available. - -Dan: The current proposal (wasi:package:semver) assumes all modules are packaged & available together. If we want to have something more elaborate - a url, a hash string, those are possibilities. - -Luke I: Its desirable for the resolver to have some way to find other versions, so that you can specify dependencies as “greater than this patch but not incompatible” - -Till: If resolution has to happen using a map, you can put the version numbers in the map, rather than in identifiers - -Dan: Resolution is necessarily not the host, some earlier packaging step can occur that takes advantage of semantic information - -Luke I: is it always a precise version in the import name? (some examples given) - -Dan: We should make a convention about whether the VM is going to download modules for you, or the VM is going to just resolve links as they exist - -Tlively: It sounds like we have differences in opinion about who should be doing resolution of version numbers to packages, and where packages come from. Before agreeing on specifics we should figure out the user story and what goals we’re trying to achieve with the versioning scheme - -Dan: Sounds good, does anyone want to propose a story or a set of scenarios to look at? - -Pat: I can provide a story for our use case, but I want to get input from others as well. - -Dan: Moving on to the next item, Weak Imports. In Issue 36, there is discussion about not wanting a system that forces an additional indirection e.g. through a GC Ref. - -Sam Klegg: In your example of importing v2 features and then an optional v3 feature - -Dan: V2 to V3 is a major semver bump, If it was a minor bump maybe that would be OK. What about e.g. most features from 2.2, and this new feature from 2.3 would be nice to use if its available, but if not I’ll fall back. - -Luke I: If you’re importing from different versions are those versions separate instances - -Dan: That’s up to the VM and the module API - -Sam K: We don’t want to have two versions of the same module instantiated to satisfy a dep. - -Sam K: Would you put a weak dependency on an entire module, or just on an import? -Dan: I think we want the ability to do both. E.g. If we have a filesystem, then we will use it to do stuff, and also if the filesystem supports this individual extra feature, i’ll use it. In both cases we want to be able to fall back. - -Sam K: Seems like lots of overlap with the semver proposal - -Dan: Semver just gives you the minimum requirement to be functional, weak imports are for things that may or may not be present - -Luke I: Semver protects you from the ABA problem, where the function name and signature stays the same but the functionality totally changed. - -Dan: You could have a weak import, and the weak import itself could have a semver tag on it, or other semver relation operators. I’m looking for a general sense from the group whether this general idea is what we want to pursue. Out of all the proposals it has the advantage of not implying indirection. - -Luke I: Does this mean that wasm is going to have to support weak imports so that there is no indirection cost? - -Dan: It would be a requirement of the engine to implement imports so that there is no indirection cost. - -Sam K: We’re explicitly trying to not push a new concept into the core spec - -Dan: Is there consensus about not trying to push new concepts into the core spec? - -Jacob: are we going to expect this in web embeddings? - -Luke Wagner: You could polyfill this on the web using javascript stubs - -Luke Wagner: Rather than mangling the string name maybe you could use a regex to carve out what part of an import name is the name, and the rest is the wasi-specific specifiers like version, weak - -(Some discussion on details of those ideas) - -Dan: Is the basic idea of weak import, somehow mangled into import names, - -Jacob: We could use custom sections for this. - -(Some discussion of how you might use a custom section) - -Luke I: If the custom section gets stripped thats a bad sign about your toolchain in the first place. I prefer this to string mangling, it doesn’t eat names that now become reserved - -Dan: There are escape characters and ways we can make name mangling work. - -Tlively, Luke I, Sam C: all in support of using custom sections as opposed to name mangling - -Luke I: Import maps are separate from the module itself, or you could put a default map in at build time, but the idea is that it makes polyfill possible - -Sam C: There would be a lot of repetition of these annotation in the import names, custom section could solve that - -Dan: Pushback that custom sections are for non-semantic information - -Paul S: Would this mean we now require those custom sections? - -Sam C: its extra information that says the module would like to have the following version, the following weak sym. The engine could throw it away and it would still possibly work - -Jacob: This is roughly what we’re trying to solve in the webidl proposal as well, we’re specifying a custom section. - -(Some discussion) - -Sam C: You’re describing the environment in which you’d like to be run, and the engine may be able to provide the right implementation there - -Luke I: tooling is easier with custom sections, you won’t have to change imports and byte offsets and so on. - -Luke I: The import map proposal says to just specify the bare name to import, and - -Dan: Does someone want to champion writing down how using a custom section for this will work? - -Sam C: I will write something down for the next meeting [action item] - -Standardization phases -https://github.com/WebAssembly/WASI/issues/38 - -Dan: Derek wrote up a proposal of phases (linked above). In the core wasm they use the concept of web engines implementing a proposal as part of gating moving it forward. We have more non-web embeddings to consider here. - -Luke I: We should document why we made certain arguments about compatibility as we go along. - -Dan: Rationale is important, should that process live in the phase document? - -(?): Maybe when we move to stage 3 with a proposal it should come with an agreement about what stage 4 may be. - -Derek: My desire was just to come up with something that mirrors the CG without specific opinions on exactly how. What do we want the role of the subgroup vs the CG to be? Should the CG just rubber-stamp things? - -Derek: We haven’t talked about the goals for the WASI api spec, should it go through the W3C WG process? - -Dan: That is what I want us to do. - -Till: wrt where it lives exactly, it could be a sibling to the JS API. - -Dan: this is a non-web use case and W3C is a web org but I don’t think its a problem in practice. - -Derek: This is something between the core spec and the JS API. WASI will build on top of core. Maybe some of the WASI loading semantics will be baked into the JS spec, or maybe not. - -Dan: How the individual module specs get packaged into a spec document is something we can resolve in the future. - -Till: Volunteers to champion the phases document diff --git a/proposals/clocks/meetings/2019/WASI-05-30.md b/proposals/clocks/meetings/2019/WASI-05-30.md deleted file mode 100644 index d6c773aa7..000000000 --- a/proposals/clocks/meetings/2019/WASI-05-30.md +++ /dev/null @@ -1,116 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the May 30 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: May 30, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Review of action items from prior meeting. - - Import names - 1. Weak imports - - https://github.com/WebAssembly/WASI/issues/36 - - Relationship to core wasm feature testing? - - https://github.com/WebAssembly/design/issues/1280 - - Should we push for weak imports in the core wasm spec? - - Looking for volunteers to draft a weak-import custom section doc - 1. Where should wasi-sysroot live? - - https://github.com/WebAssembly/reference-sysroot/pull/11 - 1. Identify a module for an MVP. - 1. (Time permitting) Plan iteration on additional modules - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes - -Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-05-30.md - -Attendees: - -Dan Gohman -Luke Imhoff -Alex Crichton -Martin Becze -Mark S. Miler -Pat Hickey -Tyler McMullen -Thomas Lively -Dan Gebhardt -Sam Clegg -Mark McCaskey -Nick Hynes -Nathaniel McCallum -Lin Clark -Yury Delendik -Mingqiu Sun - - -Meeting notes: - -Review action items: - -Sam has a document about import naming. TODO: insert the link here. We’ll discuss it in the next meeting. - -Action item: Sam to send out the import naming document. - -Weak imports: - -“Weak” in this context is not related to weak GC references. - -Desire to avoid depending on GC spec -Depend instead of reference types -Pat and others: push back on depending on reference types which aren’t in wasm MVP and not all tools support yet, causing schedule delays. -Mark Miller: How do capabilities work if we don’t have references? -Discussion of the mechanics of i32 file descriptors, which are forgeable, and which don’t enforce PoLA -Luke Wagner: Multiple tables may help i32-based environments have better granularity. -If you’re using C, you have to trust anyone you share your linear memory with. But other tools and languages and implementation strategies could do better. -Discussion of techniques to achieve various granularities of PoLA. - - -Action item: Sam to write up a name mangling proposal. - -Action item: Mark Miller to write up a vision document for using reference types and reference-counted closures in WASI. - -Existing toolchains for C-family and similar languages don’t use references. They typically need bindings tools to interoperate with reference-using APIs - -Discussion of how bindings work in various languages. - - -Action item: Dan to rename wasi-sysroot to wasi-libc - -Discussion of the WASI repo structure, pros and cons of using multiple repos, inside and outside the org - -Discussion about organizations and repos. Emscripten has its own org. LLVM wasm backend is maintained in a third party repository. Concern about having things in the WebAssembly org might raise the barrier to entry for contributing. Having things in the WebAssembly org may make things easier to find. - -Action item: Mark Miller to write up a vision document for using OCAP in WASI. diff --git a/proposals/clocks/meetings/2019/WASI-06-27.md b/proposals/clocks/meetings/2019/WASI-06-27.md deleted file mode 100644 index d988ee47b..000000000 --- a/proposals/clocks/meetings/2019/WASI-06-27.md +++ /dev/null @@ -1,241 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the June 27 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: June 27, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Review of action items from prior meeting. - - Import names - - https://github.com/WebAssembly/design/issues/1286 - - Weak imports - - https://github.com/WebAssembly/WASI/pull/47 - 1. Meeting Schedule - - It was pointed out that having the WASI meetings the same week - as the CG meetings is inconvenient for some. Should we change - the schedule? - 1. IDL - - Cap'n Proto: - https://github.com/WebAssembly/WASI/pull/58 - - What action items can we take here? - 1. Blockchain call extension - - https://github.com/WebAssembly/WASI/issues/56 - - Meta-discussion: How should we approach new API proposals? - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -2019-06-27 WebAssembly CG WASI Subgroup Video Meeting Notes - -Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-06-27.md - -Attendees: - -Dan Gohman -Luke Imhoff -Sergey Rubanov -Paul Dworzanski -Pat Hickey -Alex Crichton -Martin Becze -Till Schneidereit -Lin Clark -Mark Miller -Mark McCaskey -Sam Clegg -Nick Hynes -Jakub Konka -Jlbirch -vwo - -Meeting notes: - -DG: Second agenda: -Luke Imhoff seconded. (Till seconds for posterity) - -DG: Import names Proposal: presenter is not here, lets move on to the Weak imports proposal - -SC: We talked about the weak imports proposal at the Wasm CG meeting about whether to represent weakness in the function name versus a custom section. - -DG: … align with the (missed it) proposal - -SC: I can update the proposal to go back to being a custom section. The function is imported as normal but whether or not it is allowed to be missing at runtime is specified in a custom section - -DG: This allows us to skip all the questions about name mangling, polluting the import/export space - -SC: One issue is that the embedders will have programmatic access to the module versus parsing the bytes, e.g. through the javascript api. - -DG: It makes sense for there to be a custom section javascript api that can do this for you. - -SC: I’ll update the PR to go back to custom sections - -DG: What is the point where we can establish a baseline for modularity and move on to breaking up the stuff currently known as wasi core into modules? - -LI: Will the JS embedding have a weak imports attribute on imports? What about support in all the browsers? - -DG: If someone doesnt support the custom section then they just have to resolve all of the weak imports, and if they cant provide all imports then instantiation will fail. - -LI: Can toolchains ship js that detect that instantiation failed, and use a different binary? - -SC: The point of weak imports is that only a single binary is needed - -DG: In web use cases browsers might not support the weak imports natively but you’ll be shipping a JS polyfill for those to implement WASI anyway. You either support WASI or you don’t. Supporting WASI includes support for weak imports. - -LI: Will there be a document that explains the layering of these various features required to support WASI? - -DG: Sam’s document is a start on that. We need to do more to clarify on the layering. Sam, Can you add more to the document to show how it fits into the bigger picture? - -SC: Yes it makes sense to make all of that part of the core wasi spec. The things we’re talking about being in the core so far are the import system, modularity, naming conventions, application lifecycle - -DG: This will be easier to do once we have more of the import stuff in place. I’m proposing we defer more explanation until we have the import system figured out. - -LI: There was back-and-forth about different patterns of WASI modules, reactor and command, in the spec - was there more discussion about that? - -DG: That is ongoing. This can be an adjunct to snowman bindings - the reactor and command model can be adjunct to the spec about bindings, since bindings are specifically about how to use a module, and so is a description of the lifecycle - -SC: ES6 Modules need the same sort of lifecycle support as WASI does - -DG: We’ll also want a custom section to say the entry points of applications and so on. - -LI: Where do I subscribe to updates on this, how far is it in chromium or mozilla? - -DG: I don’t know about that, https://github.com/WebAssembly/esm-integration tracks the ESM integration status but nobody here knows about the status of it in browsers right now. - -TS: The status of Node is they have almost complete implementation. I’m not aware of browser implementations that have made significant progress. - -LC: I’m not aware of any advances of implementations, apple had an early implementation but i’m not aware of updates given the changes to the proposal. - -DG: Let’s move on to the next item, left out of the agenda: last meeting Mark Miller discussed a vision document that laid out the use of Object Capabilities (OCap) in wasi. - -MM: Yes thanks for the reminder. It had dropped out of mind. - -DG: That’s ok we’re all busy here. - -MM: At the wasm blockchain meeting we discussed styles of ocap systems that do not support virtualizability, versus method style, where the behavior of a call on an object is up to the implementer. (...) and I looked at using a Capnp-like IDL to describe APIs in an object style. (unintelligible) looked at an IDL that could fetch type bindings and an adaptor from old style bindings to new style, to realize the virtualizaiblity of ocap systems. - -TS: Mark you’re dropping out a third of the time unfortunately. - -MM: Ok I will put my concerns in the document that I need to write. - -DG: Mark and I discussed this and it is a big idea that I think needs to be explained in detail. - -DG: At the CG we had feedback on the meeting schedule. Right now we’re on the same week as the Wasm meeting, an arbitrary choice. Would people prefer to change it to the opposite week? - -LI: I’m the one that brought it up, it would be nice to have more open time around lunch on these weeks (in my time zone). - -DG: As a poll, does anyone object to moving it to the opposite week from the CG meeting? - -(no objections) -DG: Then we’ll skip next week, the next meeting will be scheduled for 3 weeks out so that it alternates with the WASM CG call. - -DG: We also have an agenda item for talking about the CapnP issue: https://github.com/WebAssembly/WASI/issues/56, Martin can you fill us in: - -MB: I prototyped what it would look like to describe the interface in terms of capnp, we got feedback on that which was helpful. The impression I got from everyone is that customizing the Capnp idl is appropriate, we’ll write a custom IDL that is influenced by capnp and I’m working on that right now. - -MM: You saw my attempt at a BNF of the relevant subset of Capnp? - -MB: Yes I want to rework my pull request with that in mind. We want to pull out the versioning integers on all of the methods, and adding (missed it). It would be nice if we could express things like the ability to import globals, memories, tables, as well as functions. It would be nice if it looked like the rest of the webassembly stack, so I was looking at using s-expressions. - -MB: We need to figure out how this maps to the snowman bindings, I talked to Dan who explained more about how that worked. I see the point of the snowman bindings now. I think it would be interesting to reuse the ideas from the GC proposal re defining structs and so on, and having a binding section from the snowman proposal to describe how they are bound. - -TS: Martin, the original motivation of snowman bindings (prev webidl bindings prev host bindings) was to make DOM apis fast, interacting with them directly from wasm rather than going through javascript. While by now we have lots of reasons to want these bindings, that is still a requirement of the snowman bindings. How are you making sure that your work stays compatible with that, or are you focusing on the syntax layer and it won’t interfere with that? - -MB: I’m not considering how we’re binding to JavaScript, just interested in how to express the structures that these interfaces pass around - e.g. how do we express the structure of a directory entry and how do we read and write to it? That is partially covered by what snowman bindings does so we should reuse that. Maybe snowman bindings does cover everything we need. But the syntax should look like everything else - -TS: It seems like the syntax is purely in the tooling space - -MB: We have the syntax from GC to express struct and arrays, I think that's all we need to express things like directory entries. I want to reuse that syntax, and use that as a path for compatibility with GC implementations in the future. - -DG: Take the set of bindings and types we have in wasi core as the base language, and the IDL describes what those are and gives us the clean descriptions we want - -MB: The tooling is a big hurdle in webidl right now, we want to make it easier for people to read and write these descriptions. - -TS: That makes sense. Luke wagner has had a lot of conversations around this, including with all the webidl people. They are all open to improving things. Its clear that snowman bindings won't be webidl bindings, but they need to be semantically compatible enough to describe the dom bindings pieces. If we end up having different surface syntaxes, thats fine because its mostly about tooling, but I also think we should have something that is not gratuitously different. One constraint is that browser implementers will have to be able to consume webidl in order to make the dom bindings work (already used throughout browsers). Keep in mind that there are constraints that don’t allow us to completely evolve this tooling in ways that break the DOM bindings use case. - -DG: If you can go with whats in snowman bindings now, and build on top of that, then we can achieve the parity we’re going for without defining new semantics. The key vocabulary is the types and the operations. Webidl has a lot of things in it that are distracting, even if you reduce it down to just the parts we need there are still syntax things like how “unsigned long” is the way to write u64, so i’m sympathetic to changing that syntax. - -MM: When I did my minimal BNF subset of capnp, I did take a look at the WASI ABI document and all of the capnp names for the types like u64 seemed obviously much better. I did not include wasm-specific concepts like memory, I agree that's an important thing to figure out how to accommodate. - -DG: Actions going forward: martin will take the capnp PR and make a version with the new syntax. - -MB: I will get that done in the next week and get more feedback. - -MM: There is a long term issue of how we support, at the wasm level, how we manage method dispatch. There are several ways we could map that to the current wasm, none of which are very natural. This problem goes away with GC but I continue to assume that is a long ways out. The smallest step from where we are to a natural method dispatch binding would be to add sum types, where sum types are passed on the stack rather than by separate allocation of reference counts, and the message - the thing that one invokes - would be a sum type where the constructor is the method name, and the contents of that branch of the sum type are the arguments, and the pattern match at the receiver would be the method dispatch. Given that we’re doing an IDL we dont have to decide up-front what the method dispatch representation is, but it would be good to have a candidate in mind. - -DG: My understanding is that not everyone has seen material on dynamic dispatch, so it would be a good thing to start with a paper on how dynamic dispatch works and what use cases it has -MB: Once we have proper function references doesn’t that cover? Are sum types part of GC? - -MM: The repr of sum types I’m thinking of would not require dynamic allocation so we could implement it before GC. It would still be a significant additional piece of engineering. The problem with just using function pointers is that method dispatch with what we have now, the options are 1. You pass by copy a record of function references, and the client of the object invokes a method by looking up the method name in that record, the problem with that is the size of the reference to the object is passed by copy and proportional in size to the num of methods on the type. -2. You pass by reference a … it loses the static type information given our current system, so you’d have to cast after the method lookup to the right signature. -None of these are natural for intra-module communication given the current wasm representation of things. - -DG: One thing we talked about was virtualizing an API and how we might do that. Dynamic dispatch approach allows you to virtualize in more ways. There are a lot of new ideas here and we need to motivate what problems we’re solving here and spread the ideas more broadly. - -DG: Lets move on to the next issue, the blockchain call extension. The main thing I want to address is the meta-discussion of whether this digs inside wasi. Nick are you here? - -DG: I encourage folks in the blockchain space to submit proposals, it fits well with our modularization story. It is a bit ahead of the curve as we’re still figuring out how imports and weak import names and so on. - -DG: Implementers of wasi that don’t have anything to do with blockchain wouldn’t have to implement these interfaces but its good to have the standard for how they work all in one system. - -NH: (missed it) - -MB: It would be nice if we had an interface for persistently storing function references and loading them. One idea is that we could extend the number of file types to one that could load a function reference and put it into an anyfunc table. This would require the call-ref operation to call the method, from in the function refs proposal. - -MB: The file types we have now are a file, directory, block device, character device. Are there problems with extending those filetypes? - -DG: Part of that question we might not quite be ready to answer yet. Does anyone have problems with extending the idea of a stream beyond posix-style streams? - -LI: If plan 9 could do it we can to -DG: We can talk more about stream APIs but I think extending streams to be useful for blockchains is a good idea, as long as it does not incur a cost to implementors that dont need blockchain. - -LI: We say blockchain but is any o f that not descended from etherium? - -NH: I want to generalize this in way for systems beyond etherium descendents - -MB: I worked on ewasm and dfinity, I also want this interface to work beyond etherium family as well. - -MM: The plan at agoric for using blockchain and wasm is not etherium-like, it is consistent with ocap approach, and the issue of dynamic dispatch becomes important to us. - -DG: For some context there's discussion in the CG about webvms and the requirement for 2 implementations that are webvms. In wasi we’ve decided that the committee would accept non webvm implementations and make decisions on what exact vms would be accepted as we go - -LI: Whatever system we come up with should handle more than just one currency, it should handle multiple currencies on a single chain - -MB: We should standardize that we aren’t dealing with one particular currency. This would probably be a good document to put together. - -DG: We should record our thoughts on what requirements we have for blockchains. Martin can you write up … we want diversity, we want to make sure we’re standardizing on something that more than one implementation will use. - -NH and MB will collaborate on that document. - -DG: Any further items? - -Meeting adjourned diff --git a/proposals/clocks/meetings/2019/WASI-07-18.md b/proposals/clocks/meetings/2019/WASI-07-18.md deleted file mode 100644 index 670da9f4d..000000000 --- a/proposals/clocks/meetings/2019/WASI-07-18.md +++ /dev/null @@ -1,262 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the July 18 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: July 18, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Import names - - https://github.com/WebAssembly/design/issues/1286 - - There's a lot of big-picture design work to be done here. - - To unblock modularization and general design work, can we adopt - a new temporary scheme, still containing "wasi_unstable"? - 1. Weak Imports - - https://github.com/WebAssembly/WASI/issues/36 - 1. IDL - - WatIDL: https://github.com/WebAssembly/WASI/pull/64 - 1. What other blockers do we have before we can start designing new - "wasi_unstable" APIs? - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -2019-07-18 WebAssembly CG WASI Subgroup Video Meeting Notes - -Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-07-18.md - -Attendees: - -Dan Gohman -Martin Becze -Mark McCaskey -Alex Crichton -Andrew Brown -Sam Clegg -Yury Delendik -Arun Purushan -Pat Hickey -Jacob Gravelle -Luke Wagner -Till Schneidereit -Luke Imhoff - -Meeting notes: - -Pat - agenda seconded - -DG: -Import resolution outside of the scope of WASI. - -Pick naming convention that involves the name wasi_unstable + a possible additional identifier, to allow us to continue designing APIs. - -SC: wasi_unstable implies a bulk rename in the future - -DG: agreeing but bringing up additional prefix to clarify. Does anyone have an opinion. Suggested wasi_unstable/ - -_ : Is there any reason to use a / - -DG: We want to split the existing wasi_unstable into multiple modules, :, $, the specific character doesn’t matter. - -DG: is there a problem with / - -_ : Agreeing that separator doesn’t matter, but we should move everything into namespaces - -DG: it will allow us to start design work on other APIs… - -DG: wasi_unstable/identifier is the current proposal. We’ll call that a decision, we can use that to unblock things and start modularizing things. We’ll start queueing up those issues for the next meetings. Let’s have those issues and we’ll start tagging them. Part of that work will be deciding what goes in what modules - -DG: next agenda item. Weak imports - -SC: I got as far as implementing the custom section and realized that there’s quite a lot of redundancy, we’ll have a global corresponding to each global import. All we need is a way of finding that list of globals, we’ll probably use name mangling, so all we need to do is specify the suffix and the runtime can find all imports matching that pattern. Name mangling just for is_present. It would just be a simple custom section saying “is present” - -DG: that strikes me as overkill - -SC: (something)… we can find all weak imports by looking for that suffix - -SC: someone asked why we weren’t going forward with the official Wasm spec proposal of weak imports - -DG: one possibility is that we can take weak imports as being in the same bucket as snowman bindings. It’s a way of describing an interface to Wasm, so maybe we should put it in the snowman bindings custom section. If that’s the case, we can roll it into the snowman bindings proposal. I think it aligns pretty well with the snowman bindings things, because it’s a custom section, and (justification regarding name mangling) - -PH: if you have a whole bunch of weak imports, you can map them to the same global if you want to. So that’s an advantage of a custom section - -SC: what does that mean, if anyone of them is missing - -PH: that’s useful if you’re importing an entire module of things - -SC: that’s useful for all-or-none situations - -SC: yeah, I like it - -DG: alright, so with that, I’ll put that to the group, is this a good way to go forward, put it in a custom section and roll it into snowman bindings? - -(Luke allegedly nods head) - -SC: I don’t see how it fits into snowman bindings -DG: it’s part of a custom section that is the interpretation of the module; it’s not quite the same thing but it’s in the same category. It would be in a different part of the custom section, and eventually things like specifying the entry point - -LW: (missed)... this is in the same kind of layer - -SC: that makes sense when you put it like that - -DG: does anyone want to comment on the issue then? Someone in the WASI repo brought up the question of using a custom section - -J: if that is the case then we should put it in the webidl bindings repo - -LW: the webidl bindings repo is itself a layer of …. - -J: should add assuming it does exist (snowman bindings) - -PH: there’s a large overlap in the people working on both, so it’s probably a non-issue - -J: do we want to use weak imports for something else? Mentioning it there will get more eyes on it. Weak imports in contexts outside of WASI - -… - -SC: should I keep going with specing that in the WASI repo? - -DG: yeah, for now.. We’ll figure it out as it goes - -DG: next agenda item: WAT IDL proposal - -M: So where we got stuck last week is with conflating two things, the way watidl was written made the interface an object, that’s a mistake because an interface is a Wasm module. I rewrote it and I’ll push up the changes today. We should take a key from webidl we can add the extra field that this is a method and then we know that the bindings need to bind some sort of context, so I’ll introduce a method field. It’s also important to remember what the whole point of this was which was partially virtualization, ideally we should be able to have an IDL that Wasm binaries can bind to in two different ways, one using aztrack? Data ADT where all the functions are imported, the other way that would be easy to virtualize, I’m also trying to, I wrote up a little doc on how to do virtualization which I’ll throw up today, so that’s where we’re at with watidl. - -LW: what does virtualization specifically mean? You’ve requested to import this fn but I’ll give you a virtualized one instead - -M: the ability for a Wasm module that a Wasm module can implement a given interface and another module can use that, there’s 2 types of virt. Static: another module importing fd_close, open, sync, which another imports. Dynamic: a module being able to on the fly create a file descriptor or implement it to hand to another module, which is what I meant - -LW: do you mean as a reference to a struct that contains fn refs? - -M: yeah, exactly. SO in that case, the WASI interface, ref to structs of fns, you would just import types at that point. It would be nice to have an IDL that can describe both ways of interacting. - -LW: and who would use the IDL? - -M: used to describe interface and then you’d write bindings. - -LW: so this would be the interface of WASI? - -M: yeah - -LW: would this be equivalent to a list of Wasm function signatures that would be allowed to use snowman binding types in their signatures along with module and field name - -M: list of functions of types, it’s pretty basic - -LW: If we go the snowman bindings format and have a Wasm style and there were fn sigs that could use these types instead of core Wasm types. What if I make a module that just describes the interface… just a subset of the text format. - -M: that’s pretty much what this is + the addition of whether a function can be virtualized or not - -LW: that has some pretty significant runtime and compile time implications - -M: We don’t even have structs or fields, we need partial GC and func ref before we can do dynamic dispatch properly anyways, so we’re looking ahead. - -LW: thanks for explaining that - -M: it’s the text format - bodies, just types and function signatures - -MM: Wasm interfaces are overlapping, we should consolidate these or figure out what’s going on -SC: virtualization isn’t needed for what we need right now, so maybe we shouldn’t push on that too hard if we don’t need it right now. - -M: agreement/partial agreement - -M: I think virt. Is important in a context where you have multiple untrusted modules working together. As WASI is now, it’s generally a single module, they can add object capabilities to each other. In that context it’s not as useful, once we have func refs, …. Then the capab to virt interfaces is more important - -TS: I thought that was a different layer, instead of the runtime built-in you use this instead. I don’t see how that would interact with the IDL, can you explain that more? - -SC: you’re talking about interposition vs method calls, interposition is like intercepting a method call. - -M: Are you all familiar with ADT style? RIght now everything is ADT style, so you can’t really virtualize ADT style. A module can’t really implement those functions, it can’t generate them on the fly. So to be able to generate or implement a file descriptor, that’s /udev/random , so a module can do this and generate a FD on the file when requested by creating a struct and hand it off to the requester, why this matters at an IDL level is, a module may only want to use OO interface and in that scenario, you’d only implement types and the entrypoint fn would only receive capabilities, references to structs which point to functions. One use case for an IDL here is the host system would know that the module wants OO type vs ADT style, does that make sense? - -TS: I think so, thanks for the clarification - -M: that said, since we don’t have, since it’s not given we don’t have GC or func ref, (func ref?) looks more promising, it might not be worthwhile to worry about this. It might not be worth worrying about this yet and just focus on ADT style - -DG: as far as next steps, martin you mentioned that you’ll post an updated version of the proposal? - -M: yep - -DG: we’ll iterate from there. Anything else we want to cover in this meeting? - -M: I also wrote up some stuff about virtualization, should I add that to the repo? - -DG: Sure, make a PR and we can discuss it and decide if we want to incorporate it - -DG: that’s a good point, virt. Is an interesting enough point that we should document what we’re going to do in this space - -DG: next on the agenda, with the theme of setting up the wasi_unstable namespace, what are the blockers that we have before we can split up wasi_unstable into modules and working on them. Having an IDL nicer than a C header file or markdown is good, are there other blockers? - -LW: do you think we should hold off until we can make use of reference types and type imports? Or do we want to do it later - -DG: I think that’s something we can deal with later. When we have full snowman bindings, we’ll want to convert them into that form, and emulating lower level concepts with our higher level types. We need to figure out what is a file and that doesn’t need to wait for (those things) - -TS: maybe we should say that the changes we make going forward should take these concepts into mind, (describes using indirection of fds in a table of anyref to make transition easier) - -DG: that seems reasonable and I think that will somewhat naturally fallout given API design. We want a vocab to talk about things until we have an actual IDL, we can do API design with C headers but it’s not ideal, so we should figure out what to do there. MAking it easier to migrate to future bindings systems seems great - -TS: two advantages, we can do API design now knowing thta API design can map well, later on we have a straight forward way to make it easy to consume in C/CPP/Rust. Two APIs with the AnyRef being the fundamental and an indice-only one on top of it - -DG: how much do we want to do now vs waiting for snowman bindings? If we just design with this in mind, it will be pretty straight forward to retro fit this, that’s my gut feeling here. - -TS: All I’m proposing is making that explicit that we want to have this 1-to-1 relationship, making that relationship straight-forward - -DG: should we have a document about “How to design a WASI API” - -M: that sounds like a good idea - -DG: martin or till do you want to start a document like that? - -TS: I can start that document by writing what I just said and then we can flesh it out with more content - -DG: it can evolve as we get snowman bindings and other tools - -LW: it might be good to have a “future intended steps” section. The intent to move to ref types and binding types are only in our own heads and we should document that somewhere - -DG: looking for someone to document OCAP vision and put it in a repo, if someone wants to do that, that’d be great. It’s been discussed in various places, but we don’t have a document in the repo describing the plan. IF someone could digest that down and start that, that’s what we’re looking for - -LW: I can help there - -DG: we have the docs directory in the WASI repo. Alright, I’m trying to push forward to the point where we can do API design. Are there any other blockers? We’ll have a document, (somethinG) in progress, and a plan … for a module naming system, temporary one, pending discussion about import naming schemes. That’s the end of the agenda. Is there anything else? - -SC: presumably we’ll need an IDL to header file conversion after, -DG: yes (..) + rust interface generation - -M: … -LW: … -TS: s-expressions as type definitions minus the body is the obvious way to define the functions. WHat’s missing is how to fit the binding expressions in there - -LW: importantly, binding expressions don’t fit in there, interface is just the types - -M: to generate a header file, you’d need the IDL and the bindings and they do need to be separate because different languages want different bindings - -LW: I’m not quite sure what you mean by supplying the bindings. You could generate for say, C, there’d be policy choices like what to do with strings, but it’s possible. Sounds like a cool tool though - -DG: that sounds like the end of the meeting, see you all in 2 weeks diff --git a/proposals/clocks/meetings/2019/WASI-08-15.md b/proposals/clocks/meetings/2019/WASI-08-15.md deleted file mode 100644 index 8062b2745..000000000 --- a/proposals/clocks/meetings/2019/WASI-08-15.md +++ /dev/null @@ -1,121 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the August 15 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: August 15, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Weak Imports: https://github.com/WebAssembly/WASI/pull/47#issuecomment-521061962 - 1. Interface description based on Module types - - https://github.com/WebAssembly/WASI/pull/74 - - This is a rough sketch, similar to WatIDL, but stripped down, and is - meant to be just enough to let us start describing API proposals. - 1. Meeting time - - I received a request from someone who would like to present a proposal to hold a meeting at an APAC-friendly time. - - We have been following the CG which held some APAC-friendly meeting times for a while but - [dropped them due to low attendance](https://github.com/WebAssembly/meetings/blob/master/2018/CG-04-03.md#drop-apac-timezone). - - Assuming this works for the presenter, move the time of the next meeting to 08-30 at 06:00–07:00 UTC? (This is 08-29 at 11:00pm in Pacific Time)? - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -Attendees: - -Dan Gohman -Till Schneidereit -Alex Crichton -Luke Wagner -Jacob Gravelle -Sam Clegg -Andrew Scheidecker -Mark S. Miller -Johnnie Birch -Stefan Junker -Andrew Brown - -Meeting notes: -Topic: Weak Imports: https://github.com/WebAssembly/WASI/pull/47#issuecomment-521061962 -sbc: moved back to custom section design -[please fill in notes here] -MarkM: could a rename be considered—I always think of weak references -Sbc: very strong precedence in C/C++ -MarkM: weak/optional imports should be brought up with TC39 -Luke: [posts a link https://github.com/guybedford/proposal-weak-imports] -Dan: good question, should we rename? -Stefan: +1 on “optional” -Mark: would “optional” be confusing? -Seems like “no” -Dan: seems like consensus -Sbc: [takes an action item to rename] -Dan: anyone opposed to landing the PR once the rename is done? -[no] -Dan: let’s do it -Topic: Interface description based on Module types (https://github.com/WebAssembly/WASI/pull/74) -Dan: lots of stuff going on around OCap, and that should go on -But in parallel, we need a simple text format -This PR introduces a stripped down text format (see PR description for details) - -Mark: should we introduce a term such as “compartment” to describe sets of instances which share memories and tables? -Sam: This relates to the concept of “shared-nothing linking” which we have been introducing. -Luke: In full generality, we won’t need the term compartment, because we’ll just have references and different linking approaches. -Luke: if we want wasi_unstable to become wasi, we need to spec ways to send capabilities between modules. We don’t if we just have references -Till: brings up the question if we need to support wasi_unstable, instead of just breaking it -[discussion] -Mark: This is a useful concept, whether or not it’s something -[discussion] -Luke: getting back to the proposal, looks good for the transitional role -Dan: idea is, once we have a parser for this, we could land it, and have it be the specification -Could generate header files and documentation from it -Sbc: comments go into some kind of comment syntax? -Dan: double-semicolon -Sbc: need some kind of include mechanism -Dan: yes, good point. Want to really keep this simple -Luke: same requirement came up in conversations with Andreas about defining types in one module and using them in another -Luke: but as long this is all structural, can just agree on structure of types -Dan: - -Dan: We need to factor out types so they can be shared between multiple modules. Maybe something like a #include mechanism? -Mark: #include would be unfortunate in any kind of standards context. -Luke: We could put multiple modules in one file -Dan: Could we design a more declarative form which achieves the same goal but doesn’t have the same problem? -Mark: It’s premature to do a lot of IDL design work -Dan: agree - -Timezone discussion -Till, Johnnie: conversations about voting, and people not being able to attend all meetings. Perhaps we can find a way to do votes offline to allow people to vote even if they can’t attend the meeting. -Sam: Another option is to do the vote in the meeting, but hold it open for a week or so after to allow others to vote. -Till: That does change the dynamics. -Johnnie: Would it makes sense to record the meetings? -Dan: What if we ask the CG to record their meetings? We can follow their lead. -Johnnie volunteers to take that to the CG. diff --git a/proposals/clocks/meetings/2019/WASI-08-30.md b/proposals/clocks/meetings/2019/WASI-08-30.md deleted file mode 100644 index cbd14a725..000000000 --- a/proposals/clocks/meetings/2019/WASI-08-30.md +++ /dev/null @@ -1,64 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the August 30 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: August 30, 06:00–07:00 UTC -- Note the time change! -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. WASI for Embedded, by Wang, Xin - 1. Update on the Interface description based on Module types: - - https://github.com/WebAssembly/WASI/pull/74 - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -Attendees: - -Dan Gohman -Xin Wang -Leon Wang -Arun Purushan -Till Schneidereit -Tyler McMullen -Sam Clegg - -Meeting notes: - -Time zone: -XW: Seems like we can move to the previous time. -DG: We can be flexible in the future too. - -XW: Presentation on WASI for Embedded - -DG: Update on https://github.com/WebAssembly/WASI/pull/74 diff --git a/proposals/clocks/meetings/2019/WASI-09-12.md b/proposals/clocks/meetings/2019/WASI-09-12.md deleted file mode 100644 index e8bf1a518..000000000 --- a/proposals/clocks/meetings/2019/WASI-09-12.md +++ /dev/null @@ -1,92 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the September 12 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: September 12, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. `witx` API description files: - - https://github.com/WebAssembly/WASI/pull/74 - 1. Phased API development proposal - - https://github.com/WebAssembly/WASI/pull/88 - -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Sam Clegg -Pat Hickey -Yury Delendik -Artur Jamro -Mark McCaskey -Alex Crichton -Jacob Gravelle -Mingqiu Sun -Nathaniel McCallum -Luke Wagner -Johnnie Birch - -Meeting notes: - -Agenda seconded by Pat - -Dan: Last meeting was at a different time than usual. There were only 6 attendees. We are going to resume meetings at the normal time, 1600 UTC. - -Dan: Next topic is WITX. - -Independent of WASI, there is a new file format called WIT from the interface-types proposal. Its a lot like WAT, but it does not have function bodies. - -WITX is WIT with extensions. It has some of the types from interface-types. The idea is that WITX is not a stable format, its going to evolve to align with WIT as interface types evolves. - -Fortunately our needs are pretty simple at the moment: we are adding strings, arrays, enums, and structs to the wit file. - -We want WITX to be the way we specify WASI apis. It feels like a better place than the C header file we started with. - -Pat: lucet-idl tool has a witx parser in development. - -Working on hooking up this parser to the C and Rust interface generators. -Goal, be able to feed witx files into lucet-idl and generate C headers and Rust interfaces. - -Can be used to generate libc definitions for WASI - - -Stefan: Does WITX have modules? - -Dan: Yes, but the file we have at the moment attempts to be the exact same wasi_unstable module we have right now. Once we land this, we can immediately start factoring that module into multiple modules, and witx should support that. - -Sam: Is there a way to use types from a different module? - -Dan: Yes, there is a `use` mechanism, and in the PR there’s two witx files, wasi_unstable’s first declaration is to `use “typenames.witx”` - -Dan: Next agenda item: Phased API development (PR 88). Apologies for getting this up late. - -Stefan: Could there be a standalone parser implementation somewhere? - -tdoPat: I’ll make the lucet-idl parser and validator for witx into its own crate, and that crate will live in the WASI repo. - -Johnnie: I followed up on whether we can record these meetings, I talked to the W3C and they expressed the same concerns we heard here about privacy, making people feel comfortable speaking up. They suggested I talk to the WASM CG, but given that I’ve heard the same feedback from multiple places, I’m going to just drop the issue. diff --git a/proposals/clocks/meetings/2019/WASI-09-26.md b/proposals/clocks/meetings/2019/WASI-09-26.md deleted file mode 100644 index 704aed13a..000000000 --- a/proposals/clocks/meetings/2019/WASI-09-26.md +++ /dev/null @@ -1,60 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the September 26 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: September 26, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Initial WASI modularization draft - - https://github.com/WebAssembly/WASI/pull/98 - -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Andrew Brown -Mark Bestavros -Leon Wang -Alex Crichton -Peter Huene -Luke Wagner -Yury Delendik -Pat Hickey -Artur Jamro - -Meeting notes: - -DG: WASI modularization draft PR is up, comments are welcome - -Also, this makes the start of the point where we can start taking PRs for new API proposals, in the form of PRs which add and modify witx files. - -Pat: We’re working on an HTTP API proposal. - -Dan: There are also people working on Berkeley sockets APIs. Note that though there is a potential for overlap here, it makes sense to develop both. - -Pat: In cases of overlap like this, the higher-level APIs may even by polyfillable on top of the lower-level APIs. diff --git a/proposals/clocks/meetings/2019/WASI-10-15.md b/proposals/clocks/meetings/2019/WASI-10-15.md deleted file mode 100644 index 4a9566f3d..000000000 --- a/proposals/clocks/meetings/2019/WASI-10-15.md +++ /dev/null @@ -1,116 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the October 15 in-person meeting of the WASI Subgroup - -- **Where**: 10355 N De Anza Blvd, Cupertino, CA 95014, USA -- **When**: October 15, 1:00pm PDT -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -This meeting is open to WebAssembly CG members only. To register, please -visit the CG participants page: - -https://www.w3.org/community/webassembly/participants - -Also, the host for this in-person meeting has requested we provide a list -of attendees, so please email Dan Gohman if you plan on attending. - -## Agenda items - -The topic for this meeting is low-level WebAssembly APIs for -HTTP (servers and clients). - -## Meeting Notes - -Attendees: - -Dan Gohman -Syrus Akbary -John Plevyak -Pitor Sikora -Alon Zakai -Mark Nottingham -Leif Hedstrom -Jorge Lopez Silva -Pat Hickey -Johnnie Birch -Roberto Peon - -Meeting Notes: - -Presentation: [Proxy-WASM: a “standard” WebAssembly interface for the data plane, Piotr Sikora, John Plevyak](https://docs.google.com/presentation/d/1QMGEuVD9p5iNbzxzgT4p2PXpxg1MjfSbpbJdw6g6Q_Y/edit?usp=sharing) -Resources: -[WebAssembly in Envoy](https://docs.google.com/document/d/1HLV35OZP0A_a8dVjDo4kwTsovDkaycS83ZLKFpG9W8Q/edit) - -Described the envoy use case and then reviewed an API (logs, network, http, etc) - -Dan: Is there a main function? -Piotr: No, there is no main. The module functions are the entry points - -Dan: How is `__post_instantiate` used? -Piotr: It’s an initialization function which is called at Vm startup, which may live across multiple requests. - -Dan: Does `proxy_set_effective_context` imply persistent state? -Piotr: That’s an ABI design question, it could work that way or by passing in the context to each call. - -Roberto: Is there an api for caching -Piotr: Not at the moment. Not supported by envoy. -Roberto: What about streaming? What if the data you’re receiving is not in order? -Pat: We have a different proposal that addresses this. -Piotr: We don’t have an answer for this yet. - -Syrus: Have you thought about using this proxy api on the client-side (browser, [via extensions](https://developer.chrome.com/extensions/webRequest)) as well? -Piotr: Our use case is not focused on that - -Roberto: Are you thinking about having a Session abstraction in addition to Connection? -John: We don’t have it yet, but we may add it in the future - -Jorge: Version management? - limitations of current toolchains mean that the abi version is encoded as numbers in a function symbol name. But this can change as tools and standardization progress. -Pat: optional imports may alleviate some of the versioning problems too - - -Presentation: [“What HTTP Needs from WebAssembly”](https://github.com/WebAssembly/WASI/blob/main/meetings/2019/What%20HTTP%20Needs%20from%20WebAssembly.pdf), Mark Nottingham - -Roberto: What about multiple headers with one name? -Mark: [paraphrase] we probably need to talk about that - -Dan: Does this include DNS? -Mark: Yes, the API accepts names, and they are translated implicitly - -Discussion of optional imports, which will be important as different use cases will need different parts of these APIs. -Spec: https://github.com/WebAssembly/WASI/blob/main/design/optional-imports.md - -(general presentation of the people in the meeting) - -Dan: Could you use this for general-purpose HTTP programming? -Mark: Yes, there are some features which are proxy-specific, but this could be used for clients and servers - - -Presentation: [WASI HTTP proposal](https://github.com/pchickey/wasi_http_strawman), Pat Hickey - -John: This concept of futures doesn’t allow you to chain futures, right? -Pat: Yes, this is a difference from JS futures - -Pat: This is a low-level API; most customers would be using higher-level libraries on top of this - -John: This API allows you to decide what you want to poll for - -Pat: The `future_close` function allows you to release resources - -Roberto: How much would this API change if you had threads? -Pat: Our goal is mostly to have threads in the background, so that users don’t need to worry about them. But some users may want more threads in the future. We don’t have all the answers here yet. - -Alon: The `request_new` function takes a string url; how does this relate to `path_open` which doesn’t support absolute paths? -Dan: That’s a good point; one possibility is to change this API to make URL access more capability-oriented -John: That enables nested sandboxing -Alon: This model entails some overhead. If every WASI API uses OCAP, it could add up - -Action items: -Dan to post a skeleton Reactor design document -Dan to finish WASI modularization API -Pat to make a Futures proposal -John, Piotr, Mark. Pat to flesh out their API proposals offline and figure out next steps diff --git a/proposals/clocks/meetings/2019/WASI-10-24.md b/proposals/clocks/meetings/2019/WASI-10-24.md deleted file mode 100644 index c9dae6238..000000000 --- a/proposals/clocks/meetings/2019/WASI-10-24.md +++ /dev/null @@ -1,171 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the October 24 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: October 24, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. WASI and OCap - 1. https://github.com/WebAssembly/WASI/issues/109#issuecomment-541191297 - 1. https://github.com/WebAssembly/WASI/pull/69 - 1. "Handle" terminology - 1. https://github.com/WebAssembly/WASI/issues/62 - 1. https://github.com/WebAssembly/WASI/pull/117 - 1. Quick ping on reordering `clockid_t` values - 1. https://github.com/WebAssembly/WASI/pull/112/files - 1. Modularization update - 1. https://github.com/WebAssembly/WASI/pull/98 - 1. https://github.com/WebAssembly/WASI/issues/2 - 1. Some good first issues - 1. Make __wasi_linkcount_t 64-bit - 1. https://github.com/WebAssembly/WASI/issues/70 - 1. Incorrect size returned by __wasi_environ_sizes_get - 1. https://github.com/WebAssembly/WASI/issues/27 - 1. Make clocks/random into capabilities - 1. https://github.com/WebAssembly/WASI/issues/118 - 1. Should random continue to be `random_get`, or should it become - `fd_read` from a special stream? - -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Mark Miller -Mark McCaskey -Pat Hickey -Barbara Nichols -Andrew Brown -Peter Huene -Artur Jamro -Till Schneidereit -Luke Wagner -Yury Delendik -Alon Zakai -Alex Crichton -Aaron Turner -Jacob Gravelle -Wvo -Sam Clegg - -Meeting notes: - -Dan: First discussion is WASI and OCAP. We have Mark Miller here. First off, what does OCAP mean and why is it interesting, and second what do we want to do. Mark can you please talk about what fine grained OCAP means. - -Mark: We have to distinguish two forms of fine grain. What is the unit of computation being protected, and what is the nature of a permission that can be separately reified (turned into something that can be passed around). Wasm has a coarse-grained unit of protected computation - a wasm module instance. It has a flat address space (two: memory for data, and functions, are separate). All toolchains are currently built around the assumption that all Wasm modules that are linked together share a memory and function table. I’ll introduce the term “compartment” for all Wasm instances that share those address spaces. Inside that compartment, all computations inside are vulnerable to all other computations inside. We’ll eventually address that better with the GC proposal but thats a way out and we wont address it further in this conversation. -The other issue is what is the unit of passable permission. Thats permission to access outside resources and also for units of computation to effect each other. We’ll assume that there are a set of separate compartments that are units of protection - their only initial relationship is through imported and exported functions. As far as the Wasm mechanism is concerned, import functions between compartments are a perfect OCAP protection mechanism. (details this by example) -Currently the only things that Wasm can pass over function interfaces are numbers (ints and floats). As a result the permissions communicated between compartments are only communicated statically - you can't pass them dynamically once compartments are linked. So you can convey permission at whatever fine-grain you want by having many different exported functions. You can use procedural abstraction to attenuate permissions, e.g. you can use a function to provide an abstraction of a read-write file as an append-only file. - -Dan: I want to temporarily ignore address spaces and tables: in a world where we have references, does it make sense to talk about compartments still? - -Mark: Current Wasm architecture plus references still has flat address spaces - our current toolchains push us into it, there will still be multiple module instances linked together sharing address spaces. - -Dan: I’m trying to hypothetically see if we take address spaces out of the situation and have wasm gc everywhere, are compartments still relevant? - -Mark: In that hypothetical the Wasm module can use the memory and table space as empty, and Wasm becomes a fine-grained object capability machine. - -Dan: The question that came up on github is that we currently are trying to do much finer grained permissions than the function level. - -Mark: Yes in the hypothetical GC situation you have capabilities that are fine grained at the level of the objects in your programming language - -Dan: How do we bridge the gap between the situation we have now, with these compartments and the failures of granularity associated with that, and where we want to be with GC with finer grained permissions. - -Till: What about the host? (I didn’t follow this close enough for good note taking) - -Mark: There are OCAP languages and operating systems, and research on running OCAP languages on a OCAP operating system with a bridge between the language’s idea of capabilities and the operating system - when you’re writing in the language its as if the operating system’s view of capabilities are just ordinary programming language capabilities. - -Mark: If you design that all interfaces between compartments are designed around reference types, the inter-compartment protocols that are natural to future GC based compartments. - -Mark: Even with reference types, the notion of a virtualizable capability is the natural way to express capabilities in the - -In the Wasm GC machine there’s support for both virtualizable and abstract datatype capabilities, theres no penalty for virtualizable capabilities and its quite natural. In the current world the only way cross-compartment is abstract datatype capabilities. That’s going to be an impedance mismatch. - -Dan: I’d like to steer this back towards what do we do with WASI right now for languages that don't have GC or reference types. Its going to be a long term problem because we’re going to have C/C++ forever. How can we deal with an integer based approach that can approximate reference types in a useful way, at the penalty of being coarser grained? - -Mark: Let’s take very basic C++ as the representative (worst) case. There’s two approaches: one is the approach the Cheri team (University of Cambridge) has taken, they’ve added reference types to existing RISC machine architectures as additional instructions and registers and used that to put protection boundaries inside existing C/C++ code. They built a compiler and LLVM fork that can run in two modes: one mode every C++ pointer is turned into a Cheri capability, at which point you’re treating the Cheri hardware like we’d eventaully do Wasm GC. - -Dan: In Cheri pointers are still bit patterns right? - -Mark: Sort of, in the other compilation mode: in that mode the pointers are still bit patterns that are readable, but the capability gives you a range of addressable memory (which is potentially very fine grained) that is valid to dereference. This is expensive and not really what we’re doing with Wasm GC. - -(at this point i lost the ability to follow and take good notes) - -Dan: Any solution that involves users annotating their source code is going to get a lot of resistance from our users. Any solution where capabilities are held on by a side table and theres bit patterns in the wasm, is better for C compatibility but not the best for actually doing OCAP. Cheri is cool but it doesn't magically solve our problems here yet. - -Mark: A completely different way to approach this issue: Let’s say all your inter-compartment capability interfaces are defined in an IDL, and then we can generate (like capnp) bindings to particular non-capability-based ABIs, so only the code generated from the IDL directly handles the reference types and does the context switch between compartments. All of the C code just uses the C ABI bindings generated by the IDL. Those ABI bindings use integers that require the capabilities be looked up from tables - -Till: A lot of this is actively in the works as the interface types proposal. A lot of these concerns are actively being addressed by how WASI and interface types are developing. The biggest thing is that moving capabilities from being expressed as integers to references, and all compartment interfaces are in terms of reference. Inside a compartment you can do whatever you like. - -Dan: We have an IDL now where we’re moving to talk about APIs in terms of references. At the WASI level we should design in references using OCAP. - -Jacob: In the interface types polyfill we have a way to automate the side-table translation so you don’t have to even generate glue code, its just done in javascript (the host) for you. You can add an interface instruction to convert an index into a ref. This lets us use C without annotations beyond the toolchain knowing about interface types. - -Dan: Next topic: there's a virtualization doc that is coming along, and a paper -http://www.cs.cmu.edu/~aldrich/papers/ecoop17modules.pdf -(summarizes part of paper in way I couldnt follow for notes) - -Dan: Mark’s idea of virtualizatbility is an object with vtables inside them. -(more discussion of the paper) - -Mark: I’ll have to read the paper to understand this fully. - -http://www.cs.cmu.edu/~aldrich/papers/ecoop17modules.pdf - -Mark: Just followed the link, I know this paper. The language in the paper is fine-grained OCAP, individual objects are vtable-like. In that language, there’s still an issue of how you start the world off - a static configuration with good safety properties so you can move forward with dynamic properties. This paper is about the initial permissions with least-authority linkage between the modules. It is in the context of a dynamic system with full fine-grained virtualizability. I don’t see exactly how that addresses our Wasm representation problem, we still cant use references as fine-grained virtualizable capabilities. - -Dan: I think we should table and continue this discussion at a different time. I’d like to go to the rest of the agenda for the remaining 15 mins. - -Dan: What do we call handles, or descriptors? PR 117, or the last comments on issue 62 on file descriptors vs handles. POSIX has called things file descriptors when they're not really files. I want to talk about OCAP capabilities as handles. - -Mark: Historically, descriptors and capabilities are aligned, and the numbers you are familiar with as file descriptors are often just called indices, so clists are the list of capabilities and clist indices are the file descriptor ints you know. - -Dan: We settled more or less on Handle as an identifier that refers to a capability. When we say handles we’re just saying the OCAP sense. Does that make sense? - -Mark: Yes! - -Dan: Let’s call that a decision then. - -Dan: Witx files are up in the repos, you can make a PR into the ephemeral phase and we can then promote that to unstable when a decent number are landed and move on to implementing it. - - -Dan: Moving on to the modularization update: look at PR 98 for the basic change. This wont be the end of the story for modularization, but its a logical first step. - -Sam: Does this change the import field name strings? - -Dan: Yes, right now “wasi\_unstable” is the module name everything imports from. - -Sam: Yes I see that there are N different modules. - -Dan: Does it make sense to limit witx to one module per file? Wat only allows one module per file. - -Pat: We have to figure out how to deal with type names being global, we’ll need some sort of namespacing and import mechanism. - -Dan: Ok, we’ll figure that out and move forward. - -Dan: I put some basic issues in the agenda that are hopefully straightforward to implement. I’d like to encourage more people to step in and make PRs on the witx files and get involved. - -Dan: for example on the issue about using capabilities for randomness, we can propose solutions with PRs that change the witx. diff --git a/proposals/clocks/meetings/2019/WASI-11-07.md b/proposals/clocks/meetings/2019/WASI-11-07.md deleted file mode 100644 index bda872b71..000000000 --- a/proposals/clocks/meetings/2019/WASI-11-07.md +++ /dev/null @@ -1,102 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the November 07 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: November 07, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Publishing a first snapshot - 1. https://github.com/WebAssembly/WASI/issues/138 - 1. Issues for discussion - 1. Make clocks/random into capabilities - 1. https://github.com/WebAssembly/WASI/issues/118 - 1. Should random continue to be `random_get`, or should it become - `fd_read` from a special stream? - 1. Increase the timestamp range - 1. https://github.com/WebAssembly/WASI/issues/33 - 1. Remove remaining "process" dependencies - 1. https://github.com/WebAssembly/WASI/issues/26 - 1. Remove `CLOCK_PROCESS_CPUTIME_ID`? - -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Stefan Junker -Mark Bestavros -Nathaniel McCallum -Johnnie Birch Jr. -Mark S. Miller -Alon Zakai -Yury Delendik -Alex Chrichton -Luke Wagner -Mark McCaskey -Pat Hickey -Sam Clegg -Peter Huene -Alon Zakai - - -Meeting notes: - -## Making a first snapshot - call it “snapshot” - -AI: Dan to add a note to the phases document about how we make syntax changes to old versions while keeping the ABI compatible - -## Make clocks/random into capabilities - -DG: Currently clocks/random are ambient authority in WASI. Can keep compatibility with (C-style) programs out there which expect this to be the case? If so, how? -LW: Would this step mean that the program will always ask for clocks/random with the future option of allowing to not ask for it? -DG: What troubles me about that is that we’d still have to think about the mechanism for asking for it - -(discussion about clocks/random as stream vs. datagram) - -## Increase the timestamp range - -DG: this would be a good opportunity for someone who just wants to do this for the sake of learning how to change the API. happy to talk about this offline - -## Remove remaining "process" dependencies - -(discussion about exception handling in JS when interacting with WASM) - -DG: proc_raise is going away, proc_exit should ideally be implemented in terms of unwinding, though there are some details to figure out there. Can we remove the process-oriented clock identifiers? - -(Discussion, concluding in general approval) - -(Discussion of whether a “gas” clock could be defined; see also - -https://medium.com/@erights/a-pack-of-watchdogs-is-cheaper-than-gas-7e118edfb4cc - -Answer: there are some potentially subtle issues — programs could use this to determine how much time other parts of the program take, which may be undesirable. In any case, WASI itself would have no trouble defining new kinds of clocks in the future.) - -NM: Our implementation is able to implement the process-oriented clocks efficiently. If we remove them today, could they be reintroduced in the future if we want them? -DG: Yes, once we have modularity established and optional imports, it would be straightforward to add new features like this. - -NM: Is working on a proposal for a high level crypto API -MM: A request would be to not have the keys and algorithms in the same address space.. diff --git a/proposals/clocks/meetings/2019/WASI-11-21.md b/proposals/clocks/meetings/2019/WASI-11-21.md deleted file mode 100644 index 005585876..000000000 --- a/proposals/clocks/meetings/2019/WASI-11-21.md +++ /dev/null @@ -1,63 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the November 21 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: November 21, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. `wasi_snapshot_preview1` update: now live! - 1. wasi-libc update here: https://github.com/CraneStation/wasi-libc/pull/136 - 1. Other toolchains should start moving to it as well. - 1. `wasi-sdk` and `wasi-libc` will be moving into the `WebAssembly org - 1. Discussed here: https://github.com/WebAssembly/meetings/blob/master/2019/CG-11-12.md - 1. Modularization update. - 1. Link to be posted soon. - 1. Calling for volunteers. - -1. Closure - -## Meeting Notes - -Attendees: - -Pat Hickey -Jan Falkin -Alex crichton -Jay Phelps -Andrew brown -Luke Wagner -Alon Zakai -Dan Gohman -Mark McCaskey - -Meeting notes: - -DG: WASI Snapshot 1 is out. - -DG: WASI-SDK and WASI-libc. Currently in Cranestation orginization. They will move under the WebAssembly orginization, that was approved at the last CG meeting. We just have to work out some minor licensing issues for that to move forward. - -DG: Modularization update. I don’t have an update, haven’t had enough time. The current PR shows the shape of it, but it needs to be updated to the current set of APIs and witx. - -DG: Call for volunteers. I want to emphasize that WASI is a big opportunity, and now is the time to make changes. Please make PRs against the ephemeral directory diff --git a/proposals/clocks/meetings/2019/WASI-12-05.md b/proposals/clocks/meetings/2019/WASI-12-05.md deleted file mode 100644 index 0dc54deb4..000000000 --- a/proposals/clocks/meetings/2019/WASI-12-05.md +++ /dev/null @@ -1,124 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the December 5 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: December 5, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Stack trace API - 1. https://github.com/WebAssembly/WASI/issues/159 - 1. Whare are the next steps here? - 1. Character encodings - 1. https://github.com/WebAssembly/WASI/issues/8 - 1. Can we decide on this, or do we need more information? - 1. Case sensitivity - 1. https://github.com/WebAssembly/WASI/issues/72 - 1. Can we decide on this, or do we need more information? - 1. ANSI escape sequences - 1. https://github.com/WebAssembly/WASI/issues/162 - 1. Can we agree on the overall framework proposed here? - 1. Input sequences - 1. https://github.com/WebAssembly/WASI/issues/163 - 1. What standards govern this space? -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Pat Hickey -Stefan Junker -Wouter van Oortmerssen -Jan Falkin -Andrew Brown -Mark McCaskey -Peter Huene - -Meeting notes: - -https://github.com/bytecodealliance/wasmtime/pull/235#issuecomment-518897502 - -DG: If people have comments on the process we’re following with these meetings, please give feedback. - -PH: I’ll second the agenda - -DG: First item, stack trace API. Thomas Lively proposed this, but he’s not in the meeting at this time. Let’s table this until he’s here. - -DG: Character encodings. This issue has been open for a while and there’s no easy answer. There’s a shape of a proposal in the issue that most engines are following - we say that everything is UTF-8. Is there any disagreement with that consensus here? - -(none) - -DG: For things like environment variables, it would simplify things a lot if we could guarantee those are UTF-8 strings. - -DG: What about filesystems with file names that are unencodable? Can we find a way to tunnel that through? We currently use pointer+length to pass all filenames. No filesystem permits null in a filename, so we can encode a non-UTF8 string by putting extra information after the null. The trouble comes when you have to manipulate the path. - -PH: What about interface types interaction? - -DG: The stuff after the null will still be valid UTF-8 which encodes the non-UTF-8 part of the filename. So any library code that expects UTF-8 will still work. -DG: We’ll take this as consensus, and go forward with this design for now. We can change it if problems happen or we have objections during implementations. - -AB: Can you clarify what is being encoded after the null? - -DG: Two things: in the part before the null we want a normal-looking string, so any bytes that cant be translated get the unencodable-character (uffd). Then, after the null, we put the information that was lost. Something like, index of the string, then the missing bytes. We want something that is reversible. I agree it is goofy. Does anyone know how to encode an arbitrary integer in a utf-8 byte pattern? Obviously we could invent something, like using ascii digits. If theres an existing way to encode it, we’d want to follow that. - -AB: So we can’t just say we support all unicode strings? - -DG: The problem is that there are names out there that can’t be expressed in unicode. And from people I’ve talked to, its rare in practice. So the goal here is that if you get a path from one wasi api, and treat it as a utf-8 string without manipulating it, and then pass it to another wasi api, it works exactly as is. - -AB: I misstated my question - is there no unicode format where this reconstruction wouldn't be necessary? Or will there always be some way for there to be an unencodable string? - -DG: My understanding is there’s no way out of this. - -Peter H: This would be for bytes which are not valid unicode codepoints. - -DG: I’m looking for enough agreement that we can keep designing this for now. - -Peter H: is there currently a part of the spec that allows non-utf8? - -DG: Witx String type is always UTF-8. We don’t have a byte vector type right now, but there are byte pointer-length pairs. For any string passed to WASI we’ll require it to be UTF-8, and any string coming from WASI would be guaranteed to be UTF-8. - -DG: Next topic, case sensitivity in filesystems. If you look at issue 72, the big picture strategy is that WASI doesn’t dictate case sensitivity or insensitivity, or what variation of sensitivity it has (because different filesystems have different rules, whether they case map ascii or different versions of unicode). I think the point of the API is to interact with existing filesystems, and we can’t control those, so this is going to be a portability hazard for WASI. We can make tools that help you detect these pitfalls. Does anyone have ideas of how we can make this better? - -DG: Ok, so to use the wasm scary word, it is nondeterministic to use different cases to access the same file in the WASI api. -DG: Alright, so the next two issues are about virtual terminal handling. Its a space largely defined by compatibility with existing systems like xterm, unix consoles, and windows consoles. It makes sense to have something simple here. You could imagine unifying terminals with GUIs, modernizing terminals, lots of blue sky stuff here. My sense is that the value here is to find a simple thing that will interoperate with lots of different existing systems. - -Sbc: Not just to interoperate with existing systems but to allow existing programs to run on many different systems? - -DG: Yes my goal is something like vi on wasi just works. It looks like lots of people don’t use terminfo to figure out colors and just hard-code them. And windows support is tricky because it doesn’t have exactly the same features as unix. In cases where the terminals differ, should we expose WASI programs to the differences between them? - -DG: The direction I’m going is we don’t try to do terminfo, the WASI implementation will be responsible for remapping escape sequences and all that. You could imagine having an environment variable TERM=WASI. It would look a lot like xterm, which in turn looks a lot like windows. - -DG: On that topic, input sequences are a subfield of escape sequences. Input varies way more than output, across platforms. This made me think we could do a cool radical thing like use unicode symbols. But maybe the simplest thing is, just do what xterm does, and if it needs to be remapped by a WASI implementation to fit another console, thats up to them. But there are interesting questions to still ask here like what set of input sequences to support - -DG: Its tempting to say, we can go and design a modern system that doesn’t have all the legacy baggage. But my instinct now is to pull back from that and pick a reasonable set of defaults based on some of the successful modern implementations. If someone wants to design a whole new system, I won’t stand in their way. - -SJ: Can you clarify about how vim would work on this? - -DG: Vim itself wouldnt have to change. Terminfo is a library that gets linked in, but hopefully we could provide a radically simplified version that works on wasi. Inside the wasi implementation, anything like a TTY would have to filter the output coming from WASI program to neutralize all escape sequences, and then encode in terms of whatever its client expects. - -SJ: I would have assumed that stdin/out/err just map to whatever the host of the WASI implementation expects - -DG: We’re worried about security, because the terminal interface wasn’t designed to deal with untrusted code running on the terminal. So one example is that you could run a program and you think that it exited, but really its just showing you something that looks like your shell. We want to not allow applications to do things like that, by default. So if you wanted to run vim, you’d have to give it permission to rewrite your entire screen, versus just print ordinary text to stdout, which would be the default. So, controlling cursor position and colors and that would be exposed to wasi as a capability. diff --git a/proposals/clocks/meetings/2019/WASI-12-19.md b/proposals/clocks/meetings/2019/WASI-12-19.md deleted file mode 100644 index 0621c97b1..000000000 --- a/proposals/clocks/meetings/2019/WASI-12-19.md +++ /dev/null @@ -1,44 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the December 19 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: December 19, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Stack trace API - 1. https://github.com/WebAssembly/WASI/issues/159 - 1. Whare are the next steps here? - 1. Windowing and Framebuffer APIs - 1. https://github.com/WebAssembly/WASI/issues/171 - 1. https://github.com/WebAssembly/WASI/issues/174 - 1. What guidance can we give to folks interested in working on these? -1. Closure - -## Meeting Notes - -Windowing and Framebuffer APIs: - -There's an early demo out, and it's gotten some feedback. Aarron Turner is -working on incorporating the feedback and putting together a proposal. diff --git a/proposals/clocks/meetings/2019/What HTTP Needs from WebAssembly.pdf b/proposals/clocks/meetings/2019/What HTTP Needs from WebAssembly.pdf deleted file mode 100644 index 7aa294ee64e815455dd95821e1aca68f98bd9fcd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82687 zcmdqJbyQtTw)RcX;10pv-QAtw?(Xg`!Civ8yF0;yTkzoS5Q4jZz&Yu@N5&of-R^(h z9vLH>wRi2gX6;q;sb9$~A{jwpDmrRL2qN5#&9Ny6MhIF6YdtdvPEH6K1y>tG2pR!h z2VDzmV+a~4T}wmzw-3a1opj~(?M!VPAQ)cC%Rz8+L(s_R8XHRJ>KR)6Rz}Lv(jG$n z<Q=wM-L^{4)ly05BwbHTQdQ=KoRrH}_xNdUeju(CYQ}uhwZK4Gm0n`K?{v z{G)|np{Iplq-A>Xi$=iO%HgG;Jp{{dCFKn5tsU+3U%X`f?F~LFE9;k!>1cnu6tS~* zwE0y<1v_0Udz;rg>ASv|dabmflc~O;oCyD`i~scU)%dSU37c9t7}`P52wUhn7z!Hd zTN}K%D`9A5>|g@H_I8t(@7X)NRNWH7C9PaR(*8Rw)U<>(xri5FkS4draDrtr22_9- zrb+TRHYpfr!LsgT7s}H!u5oG~**;Q31ab9)-YuD%U4m$zUNtI3kmdO40UPxMx;dE$ zctQ&@%WiWK)b5_X=!DbyA+0SlA+=N(3-NZ-SN&F*7$U1SGjHm470&y7s4aTLe1|Z1 z*9MerKGOEh69_U-7;GR*FHEC$^9J z%_28t#!YaHK`xasto&^_|7HQwC=DFUw0b=@x}k zO$DnymM%HpMSfrvJ!4Br9gU52ro@S7I4J1MH%>Yj)p z*%UityapoOZ4;e2FTIR%dte+qg4GY$d~X3ZuDTo30(gId{^0%SfY{CU!?+}ur!IPC zD(aym+DncH6-q=8{ovX~bJ~g|*F@!>z1MWeJE43I$KwN6*=r;I{Yn4coL?KjYeQjV zVf)p>-&)@5d+IOk_4i_Qe~sGzW3#7wjklKw`DeSQdkv|VcYZbe-{au_*6`oV|0^w@ z?zi~+pH06_WzlMp`NPf{M+NT!fV*E#aHG`vtxZ#Bb^3P|^RdV&#+DDvb)9QY9~+0c z`d0Ehzj{6p^@5RU?uggugyfNWZ9PANJ+-dWBXVl4?tl7 znIPj@u{$ht_T|GHUMkmk^B=~@A2*)kM~$qP)Eo8N83Y&bg$4cZR^^k9bE|&hwzD0 zSE;E7Wv`x$Dm3@OK8sE_iQ0D@{g=_MS5Q<8PMxDNKdL{?&}B#$^(UoY-#)N-(XYDm zqd-oH^IMx0D#ASD@VCHv_Jw?C+^0xo-izgPHE+CGG`WKU%tufS?^~SoO@kHwD6d{3 zE`tWuK*5PdPvL+>-O1~Z;d{T4Dd!M@tD0G92)Tv)eTU2)n8~FFCJPDZ!JE+0wYQ?8 z=q!zK7caGn?BJ3uKG{oq1OoVx`udEfV4q}rBgWwDM9LRbbuZ-$&RG&SwD zM+DC)nV=J4pb{(;0;v6$=S&kCIjM5ga$VMCIzIXbxlJ}0`QH@JuG6y}5A*TM)- zOOy*GQ)F|*x*~@)5gw4SWf&mDc430n3){(Al!}mQBUzV>(x43>lp|hr@R~k=`-$%~ zWUYC_^k1`D!Y$B}L}{X)VJZ{&Fc&LUbC^-6e2dAa}1iq>QlM;91Ls0oy~>nT6E3bOCE zKSd3}lei*D+D=K9Au-6~>G!>tVOcuM)mP5TmRAIVL4zmjIq8S#0dtSlUFXyO07(~5 zjV)rm!{wR9XC5k##E0oFT>{!HgX4=C1|n%ku?$mJ3=Wu(Y4F(G2^z_3vvt>^(+LmpA2z~{KCv0$K$ln4be~hAf)!KP#c!ps=S5<@rT%GYIF<&bW92bx`(X8xj>T19 z-UaXJ@4FFSQ0>uiuPdpHa4*;UmUwD15grQT$`rLcSC>kN zMEgj)28F4gB)4sx2$>-ir{%1OvwAj^K>K&19^|98ngVXrfg8dS<2!Otf_OX8(BsAf z`M1>`WX8K^4h@&zed)%HXw%O**b{0qO)tE4kLlblWOtXo>ywr2ParYVfyd*U=R9YN z>DLd<7s^=WCqW#CA5+$Y*J1lv+8IM2*A25HKwarXe7Sz2EIt4s%iC5%$2H)}3Fb#uOeZ}BtRG7;eQWIMT3VEEby>vVQ)EX{~@;THiat64QBpIYX0oW zS4gTCGOmBa+R7PZ5UsIaG@k3K=BGh6_fP#<;xEc>6heJfU_uSNf`FcgMFv&P-i-y% zY$k18omkrG*Sya1XMY@x=Ahn(-ksi$oO0aX6%O;wkqXh#g}(wS9bS#=}wY!fJ- zz>M;l&B&SVld064D3}dP;?E2%oAk10AhQpr8{JR4JK^#xE!5;rgYLBVn{5F^88!+o zFvn}XgD^Jm-mw%OU>DSElBV8iR(i5Or)k&WliJk!5KE1FRPX-=Mqz)k`oSD9P6Tfcttgwu3t_Z!D*vilfvJL>6*0fN2l zE3j{{Z4x*>=zqZSab(Gcl<25KcU$u-g(O?Nny}8ygk8>v1u6+$VmUZnqHE(zyL99Hn+)`OySjup7B6hS(QYVUa<(74Ue(D;2v5ykSAU?5EO>bX^L%{O zPc77^>rDnwS?=y)S0w&WJWFQ};mO`r9F5&VctKp82$l$G*p1k7zgs^YVsh)Ue(E3o z9(4(O$n^gfA-|dbm&EmN z2w7>-YKj+5vuCmWWB~S)AfLrGy}LVbez83HL|AGaBPXtmdUjoO7eQtxn7va(HDX~7 zaHDE32lm)q_}I76(KHG?S9BT*pS<3O)0nX)B)O73-}pGHgk#;ff{#{dmr^_1wL8Ke z56Hk7+8tsmP(8XT0qA#AD~+^ixJA95px=v&$PL|N^c#B+qXy2S>u(2CxK~| zGByF|Z~I9|0Cb^aIeug^S0HQ)S5>SuXY~GxkOt1w5fL|7ZaryHcakD%YX=9gi=KK1 zi>jSiMN@gZb22>bJQ9IQ{K!Z%hLW4~fQ!)C^8t&dlr}!|hT+P;t(R5jcuwF7>6|%L z3Xh#xSENh_sG;9!o_leAZQHnAvEtC@lrV03q2emn>rq>!S+aFt@B`|mVyW7x9G|;6 zD&UOVqexF&0>1EB!wUT<7=5UcxF#smy5aCvF>V>7Y%{Q5+YJ6u=U7U!R&-fqyWzVn zB-fm1D3F>>JcLbv*>@bBt*K1vKa(PuV-gV(2VKw2R+Z;HVG5fJ^bha!=lnL)s*82fv`x%K(@vnHVw_UQ3WZ zeiJ2uO~rRAd&^mtz;0OB&HVTAFCc5<3E8vCMk?Mzkh4d}4?15i z^}=P7FB{zWwzs^q4)D6rNc1$2D;TN3N&L=cDo7g*?!fl*UWUG)80o!{=ba{|RxxZZ#L<3~CdWl2Pol)Q$ylcF2@m zG3auA&$#`>LvnM3XVPKz6~U=;AxM&*p()Hu&EJRS?a$D^NlT(PV5@;K@+D&K0?stk zfCX??plMb&^-m5}1nuRT)cg2u7JbQ>{H%oSKm`%~j)TBdD&)ZToWLz|fX5Y!-v_@Z za>l9=rsb;ymj^hT#WC4j-=>?P9G$$>U8v=BC?eT9-}r_SG{%;r>3v86gGDt*uD&2} z#NPSwxaxO6Dk3&xB(U4EN8dfkAmuQl0aF8b#0azzu>{2Ed1LF{S_fleb=dqb#xbA7 z0-an-rpNpukvYd7l_*f`&<^V$rav(mFsKE=2?WByj+T77l&zrvl&t}H?^^N}%zx4nhW{8fF#LrY82(5N4F482yqW)(wB&E7 zL2>v+OOTjS(piFuyvK2E9=)o7Bqzs(&0?ft&eU*aFkYFV@C5beEq5eW^5~YVY*(-f zqV{UjRrMH`eOsQdE&5{Z>|@XRaXyLGJ|s`N{&^7ETMw>I?rCz13W2Ah7H3M%JpptUYd}asVCSzDO_v;v*H>u3 zTaX94D&NXMuxkK%&&K9s9rFNDEnoL;AHR7uyVrPu>S`scJ_aqnX}N90?3O3mCDXxd zSU^SEc-t&b-eo^rb=bK35*8derWUS_VH(vieO7!geTLajPQP06%-=Y$6yOZNPr90K z$qxtFu^bmoIl~akzm)?wYJe^yNJbcT=mS5442S|^Jp!^kuYl(s(T@Q{AWg#$>9|*z zpJhFlky2x4T|iH^^J^wkM1nCsYnxt`=1ppaa(6$w1jMf&CK()N&ZdlIPk-_1-zr9hD1+TRRup-#Ycl~6%@BzuxNDs&j9 zAx@$^YUVa|d#wl_MvG;Ug$`;Zv3XT0&L8indD!Zbr@H__HA9ope{XhRMXQ@ET<_$> zveh<)vS_U?RnYo3k@>5aXJ+_EFaH)Ae~!%mSTE1`mtLOnkG(wOztzjXng3TJlku;; ze7T~e^-C{bU)R`VvkR4@-ZQg`v&3tPkP^&%*uY1G30D*$qb9npeM;hbWmKEWh)hJ7 zJGXf{$KW-#nI22ZD&(q2mV$AiZDk_Wx~2hq06jaX?+H~nw;Wy5_cCf5OYzz2+b{ZN zVhOiM7O{`Qx8rbPbftfnJas882uE*%m*&pf*0Msr6<2X(3Y^@CABsc=-heEp4r{#5 z86}GAFH1j=U^DOyBG<(CW2H1$*qczwiRt{nc39@dnDgXR=V-ewL z8w<;!WA!N}Pa}InTF$k8Nbj4#L02i9Z+=Zq@q;*yY1E?;n)@iHJzGf9HTJL_J+bN7 z9Nku&W|whhdMyk_HEfkbR%2UpG-ir^8Cx4Ap7~m%Ti^3>$SY?!YEfjf zm|erip{H6lgS`Kwr`h%nB|QC8ad>(*mymm!aAL^uY0Q*>4Ns2-?A-xpjY2igAmZr+ zo782@IT;Ex%0)+i4Xg9#pU2}))gy4V(^tkPp;x*!k#n;4vQBn3g_?MrRT?~xXI(#` zw5^Xf4-(?(lh?`w(%NGo%;^U|tEafe$YATx`#Qvw7}pgQz9&#JqP@Ut^S^wIDaEW+ zD5%x}qab4S^@>sYj>-7sspPxB$|4ma2vdV)57!BgU$!2lFj|V_Jme3uG)dNmw*iy! zKED;VU53=rJWs@K|Gt|`>!87Q<^xgUcRLy@~dY7aQxoST}DDJInw7e3Wkt@iA@Ug~8ieCb9jm7B7fIv+QQ(&a~4 zQ9Iqb9nq`j`mzQ?(ZJ+zC~<{ zQ0r4G!WIaZw-l_+he@brVk&h*uR^ZEyal;?^k#bdm#kX@Z)Tzb8>$j(}bxw z&z!CwBbILyxi^mqc31k!ktgVcGbd)CpGb^R_gejcB+ta*i&v@*Z&35HM7Wkd{W zaoh2(PFV=D)W)yQu=YchnW(Qe@np>>etE#5bVIeO-^OEXqEcY83P>DH0&QZN=Bc6} zG{!SA4n3(EH79Z?t+U`Ou2#XA2H+KBHf;|m?>Vs5djfv2@_F>s2#TJ~TJ(2H$q+i8 z>-2%Xzqo%t}<7tI{w1Xdeqo0-QHxLu}&4xgW5?NFn9!0SWbMSb|iA!gL##~~m; zRGNr^|FarYD9k#g6H)r)a8h~~ZaB2Ek2<-Yk_7dz;b1;5 zxer22#htAylLF=ncO*taW0-iyi};I?L%QmQZ0f0+qJ)j4ZVC@&2NW`gF~cO2izbmE zZ7)J}hS#TvZzm&&e^jtB2NpQ2pfF}4iZO%pZ7HHGY$P|Il3kRYX%YK@yhs1;@xf-= z7MZMZ1$3_OB>mJp)dy~4!4Xj0&<~(Dtw~mCNUVOLg6VtYeAJsLOok(6T^p7HNJYW)87z%*V}jz?^r^;)eA_ocDD0x z#OD_)urf3LLwx>bVTJKO#tKY-VFji?vI5h;#R_lc{}u6J`YS86sjONrGQ;hxu~_j= z04`276zUWuN)ic$#$mItHeh1dr`?LAIKg&@GJjaI+P^CNX+6K%cpRBP^pQEmtwulv zUz#wg^|)n|?pjVnT<(@zp-lYb>9D*tkz7vPm|8M!8~c)(ed3^;k@{5X^h9w!SaE|& zQK@DoYd2kE$XUjYCiAiC?)*rZX!QXEntilvX63lJ-P=BTh~xH7olU5z(&T&DXUKx- zYDY45^Gxy@U z>Vvw35=(|uu3)kRn;ejG*@vT8Z-}Y-9I{hg8g=ntK?vaF&_tS+Np+)sf|DIHDnZA0 zITw6IY{B(VIhhk*P*8PLA~PUG-J-W#u4P-+@qp^6`LF2;e&~NqFchQ5NBbySxhgxk!Gp(Me#mCw0R3ybS54yX16OhiMl-C(^7*Sask=+p3UB;w%HGq zr(QnB@a%gSVj`RyD0BYR`Uz1zyBpvc+I8UxA1#0@rzI({!OJPR-l;hfy`!qNZDKf$ z2-cBajE+x&X4Q%EnRPhS`Y2qj%m(a>Lp4F6Ge-f`c9T-=9zLV*Wcy`@>1#m<_z&+{ ztNCv57}VHCDC$Li49!|r>j=OeWRZlbCGtz*8|L*pr@1d{5!b!a82TFgD}HGWE1gmU zP%QY?$g+hRTWMntk>!{nc?J&!81Og@nf|Khthv5swa)uV+OsZ}`8nF_ic=V+58dtG#n{v+** zqYf*KWC!V1RA3m)1%bXh?Y4?7iDFjF@4)yo8cP2aTp8(xHyQ+v4Rc+(tPwH&XcAU| z<+@dH+I6EIZm3q)xC_Dk-V`@SERbAgS=2eX7Xj%WU z`RGmG{={}nuSE7swf?O=cTB&N+&?!TG5tnazcwE+y(;<3UZnrqy7im+UylB7+wNXi z_VqS@ShrSMmP4fb5HZ#AHJttoPQh^Sc`RSb2QX4iLoMEIeGgz0sctX#hLSUL_hZYl zWlOjUYU=*ZVk`~YynW0_WYag`!Wu5{@Twvn?K3*mWH|a}od7YkuxrtrA2H^}ZHUG9 zMXj=3ZUUXbG)v=`zOXmQqJ18_w|n=!B%Nd4pMINfO*pypAR2=7y7Ir4=|dJy{vh93 zC5MI@P3Z}j2Tb}h->R4;3y!ufBq1|VDQILMSSXNfjYeb}hEY;K)JiXGw+Z)YG@h*& zN8aNz0Z+#chx=-U7kPze!G58O7xOXxNOuzD-iO@H+n$04$W^^=DyN~98vPk#%^5ue z*(ff(Zf5t8tZpr!I+GuTd0OHJjjm7e$2%0#{SfgWrv9aw3Um)Rge_sNFB^?^M<}vF zUFk`!57XR{_i%p3iW|_OTZcVvdeEw+ESRYB8PckxC*pohpdjK1h?PzjnXr_=LQ_9E zeE)PQdtFd~t-z_NpGx}_S5CmKdV#6}cFO(3EVH?l>HG01k8U>}#;2G`*oko=RB<)y z^C(UpLLLlP4;;fC|2iu%|M_N9e=u^jY=RjR8%R!AFQy>_F6xhjCui@^_@+|{IR{t8 zCIos~eqw#M>V)D4B^9-JM>q&86RV9g`JPMAgcDTsV|EySUrfldQ6|vXTG^!0t?tnv z8ri0Il~G85(;|bY7sH}?9pY8>1+3Bg!_>Adpn1kmOAdzs?(z6`J0sr%QEJ$~nxIZZ z{>al38LScbUcL|697X3m!K@0X+2Au1fiz|Ajx)e)KVr>VTASrxA=@HbuFtM==_yYN zB5k|nA1IAkE)b08C-E*7SI2BWR}dI;UC~CtS6qkQ3<71jbZs@0^8+Engpd{78pgog zv=nwRiE(4a?6^^%7{M+N5%c_};&OAk)WinE#E{!02ZqQt3r+pi>EA^8FJ5AyqyNQF zZ&CKAAZLChpI@=_Zv{E?@5J=aAZPxKW_|_v3(Wl+LH=g`m!tn%kTd^=YJUiF<;6%0 zAvnveMq-3_+lX*#xwMPd8D4~E3oDuwD~=xO2-t9>s(2(-J|f(HJnv3D(@K)7`!m47 zBipQ83!0k?OPi%Mn~(EGTpX*+73FHZXe=CzLrwNltYdk<2k$I`vr7p8{Om zF6`~@U7k)Sb*SrjiFgFDr0HtQBWTp({mPjL}mA66iG0NMNJrXE0#Z;q-}6@XYrn*Vn0h?SC97|4wy05MLQ2Wlczq-Yc2(%Ns| zkEs)P+D>}DE{XOjj$*%6)~lWy)QgPL3g!S2tO&Bg!*3I_BYc_5wd|O**VC|TL7x9Z zZ7H;CxCO72b1$>&z`d$nLkHz`BO8YzlUL98wW=GU#M>@KbPTqykNpdr(ym79F`XEK z!dnMbL$Xj zm;?70Iq<*SBd8hT5W?^)Ep41=AU|2hmAgk({)F~7(_3#E@hT>Cv@iQIeqShh)2Bbn z)XHf!=XDD6>GZEB|V3rL-1W#!Y~uC5%$G8mSp>`5H62{l(0unIXB zGFJyUiXrkHU&RV453&z#C!!k(=%r}Q>YfC#^8>b^Aq zpZb8G=pI70pmr!N9Z__X#L&lvLPOHvv*qFO?F^SOfz1tLf453E;K)71Sn*4q#?Mc? zGMt3ZaGZ5*aImhpx%!M``G}CpX&t5vNxndC!aGOq}3~j|7xP^6X`W_UL$sxltX(qA?9w(U> zQ&bEmNNhFTWI+A^ z-aW(7dNgP*Sz#A`fgcNa?B-OnIO`&FKxz3nsep06xC*Q_#Phu_v@k^C=P#J-+@Lte z&MH$4?1u|dLlHC@<5I^N)jY_V%ZZiOEes8!eTJ1S>0Y$94v#=VSL`}}g+=CHut-Ns z`;Q^vn;!j14q5(Vw8-)oT4ebnEwcPuwD@NJUy(zWztUoF(yBEk6I?&l_J|<9P_Q#L zF9`T7c9eIUf{dp9?A3S13$MIrRA4g#2dcc2=deo8`K6=70@TPaX^vXQWzNP|47IhJ zZE?b;$&1bh@63Y^E3LQlzl)p4dN`yEhaY-M45cxoo^`^O^3ZrqoQ-IY>yTE{;Vsd6JR8x(qn=$ho*^C9d&)I2>*iutfGS=^QW+1moO>eEw1Ej+k#0DxlPh}gyA?8leefrtv zVe`=6(jm5xW%2Ymt?kH-Zn3j0N0Q8yO})kRDz%lS9mU?3xK9rs#vk?L&xjuB4N(&d zX}tUDi;t&e-)`Z!z33vXPAYnQ0%m3ugaO=ur0!GU1O|gOBe?r6zXUpktJy(+pIQ0lTxE zVMN>lXV!go-NB-Ip*guNW8s33Rb&*lB1zlv-jg7;|kV$;Br9}yY zAPrY0n(9Z1z}`3H$t@BYB%&Rjp9&EiJt0wcA5oArHQ9GvFT zAYos{MY}xBDP%hr2oi^FNs_Xg4|UCVWJ{fjAwrUo0x;PG8kD=@E~F&Fs3fL`*&u}B z{kp1L9Ys|HIK;w-UF2${DJ;n0a0^=1izkX7T1tA%xF{otRkn>YR&>exTtI0 zx6|_m|0bWePbQOD7UoBWJv$Y%PGY!l$7K`#Aq`a(TU+wm;IqZ^#S`Ag-`evBV!p20G_9b2Aw_*6(B^|_@m%k_a+F9$%8#=rs zAkw@f55J@d8@f0^(1=;SB----{wnbMtJrV3zQ1bv%C^6LkN=k|@|I5XUr~|&mM8MI zGxxvYiM(wK{BNkp+b*jAii-TV#K_xP^?$Y%I%=dpqMSg9?_VJJgO@W=OdVXQL|>0IvDbg$IbAD<*KfTZ@xt=kl;z9mDGJt#R;F(!n6Ugd zY57meeM8g#yFXN7FNe^W>i_?7i}kn7I)8AB^*5;fr(17~{C{#w;N@HxQ$sr`L+5|} zmty^m&;RJsKPdfoN`Cw4e!29&tzfbKb&A$dZrI9?7OwRinY$q9y@lw4==)-E#Sj4; z@O9e2l|am!`-K)Ubh(c@Moz}Y5iHBI()EYL3GMfMEVR`PwSC>Jm~Eg1Yvc3& zkVfoW>2U3iG@3D>whU2-7xk7wd6cSm@V=W{#tm+ae!eY)p68$*#;_Kb_11t^k)w~i zuugiaa*E%0F(BGRugTqY$cAR>!B4GHX8Fz&PuVzh0O<;iE_8GpE5>m!52VWfGfmpNIYtF zr+$}|F5fub3@tx`hQ>h$m)5G z+U<{1QGM%IXP*;wk2tK8ua8=;(^gfFno#}W`60~sFeiGytfogJ>jea zZ}Y!eBRDA?F(EM%=n#0v2(@ycc41$K9%4d{*#x5b9_L-;GiDHkWf3|T#Ni3)0@$pU ze}za(G!7V~b`Hk4_>tw!w77wY;T|R5|r$ z(i31egu^W_d2+RBrNlfte{S)7~R50kOuAKfQ?gg0%VFHbk%hw zb#ZS68B+$etVA{BV4awXbnxToNwUhh@IsyX0dQRG3c~o;PRx&$2|Z?_GMRFmgZ4j zd4yNklW+GI^r&umQKBYa&Tmx0^qkc=9!A-&<15#l%RHTEt$rp3JlCwxnBM%9gE*9| zSt65rsC#%9^bOsqeWwT>1YWSu@lZrlgERw$OJldjH$37DYvta)C^?Jc_IuiM5n!9( zH+r0?+F{C@9H);iI9`z6e4}`=1Au2#EQ#hjUcH%+nIR7dPsFu0#q^mz!&b`ZIm0BCTLBG+6vhI#rkGMfw0+n`! z^bYOlSzY(uKm_g-A%u^?H9QfE>D?;a+TG%-!Qr<4Tshd$1fbk!_~o4j*6e`hyLz>e z@}M!NBN~sS)iKnp^n1wb_fhXL0(Skmy5MDFt>QjE>=02o6aNU;QHgsu6 z!`{(CmCJjqh3^-E~uJ5h6^;%WPs`6#cvdARFknJv@qbl#Y$q!JUV#$h5U$~<``vRDr za(>dq)Hg2nDB4N%ctG-NdI#U)1Y}V^4);L$TA=;n#9>|_?B~_kRUjT|k=ieGz^w5W zJ>~LyqIW^8jQjB6wTmNxZeEfxc%niZ7wK0 zV9SwaC-r;w7f7N)`8G`|M0Y3V2G|`5E;bnW4-6+xsv41OoncmeY)9`-)z98FBOLB3 zUVvY7e)risEz#}QE4nvdU(Pq;QP>6QC;Vk!JXlgPENpV;4@ zT5r(^%0o(L-$UAuZwIu<;C%I)4lrMj#F#MNgQFw$Lg z{T2}Y=Ouf$XMXcS8#qspOzp1G`K~Y%s%P$$;2)3&5XXSd*MRXNZ= z@W3vt!1JF)?yi_8zdcwZ z*vhDc5aBP-`Du0c@{4Bkl4 z_|yr}%=MwK_CYT_5jPTNJtT`Wtfk8GxrM(v2PZ3yl=EzbCYJRwZFctVJTMgo#ya+i zdJOtRof9yp8y4e6QHZSzy6XJgc&Kt0!RCeJo_g{z3kO>owrL8EwPMUJ@oq)>DzGM^ z)?z4iD|s~&CbJU?OwP&4&4L*8prE-Y;XJFpibEJ`dD}^eB_07b`=dnWin>GMe3d%p zD1P?5J3?*C7+t8QRIx0oQzK;olXxU>ph?77xPT;j%!!nrDV;m58izft2B>$$2d`;% zNH+tmQu;d6a&CX@!VYU>IXC+DtIYSTxbwG{`yxh2QNd)7nZYq}(#@*Sqv{Uk#8YaD zLaKu35S|c@oT-PfdsFVJ9Ad<%`?hnu=h>&@4Gic(3IgXO2z7qemMr5$RZ|P}*_}&K zxgYV>Kg*_@S`bNINCY|du_R}hR*yP7w~~RUEd>@e{Vak2^WCkyJ>UxaR^11GZsX1E_ zZPAcyY(a%)X@(Pw%819>zy>HQwxpS8Pf$b7AZ{|*&8*hm2Z@e|&q_ck7Nl(eH)EU% zOI(LtqMxn&d4|$G-J$@p)LWbc>ACeRrxwr-0}?*Q*m5;Fk<1HRm1#1z4(g>{bycVn zloQM_@vD#Y3hQWu3O1>aJ;}CqcN_#DKLFa?!!;g zY>|DwX2e1c6QsbzC2<2MPlG}q8Ay)dS|AH=BM#x8Nfub$CPo}|QTsD=fc-A#Nu7}s zJfU;~Bup1u*u*grFS!!nMxYI!zUn2yiGM+;KtlQucQnX4YdZ-y4vw_Tu_pcakpkfh!GS!Mm)Py7zI#q+DWC*TZ3e(s2GP^>csQtjk)8J!Vx@5Piui*3*Xdx6l z=((c_tw#SeJVO76j_i^K2e zhaeGdR*!LP!#6Cf+0o7# zG}WWXVX~HmF6$d5-GB3SxdVs6@jA4Wd{o@XhL}f}T$7Ih_u1DbVb|C&}I4lpJUQr!A`ZEj$4fn zzw>15-JPU9IJ=^m-C8^$dLZ7|k)yY0f`Gb6S@ds4Fdm?nZLsGdz&J&-s-V-u{9K~= zYPJaQ*wHE60?B@`hu4O92RuE6a93W6*s?V5FA`orfcOv9a=Y z<|1i4JZ!ybcg=}DlM*=Nz|tS(vk)elU;kHv*kJzvAsfD6Z3lI@xpf&Sp74@>hpU6I zlyxF7LXX{O@uhZ8j>An&nX=6}LHG9;AioB|*XHfu0)pLb z)P#1fn2K`xVT4nLGCHtTF?BuJK49SS1$5JRW*39MYqq~l!HF1^dsmYm>_hMu8PI*u{ZVNd3M-2rfJ(Dw7$2&%+rAMN7Pr=+PM zHn%WOt7HQfssS0a88cZ0$lR+B){b6(gEpS!-mrI(%$<# z_lsFyoS5sLYYQBCPjI7AWI7fvDlQUn&h5pG-DMki^A(V`8Y8 zd(S!>Zf8RK*nMJY@lC~>H1>4w$cO3i(TgRxJc+VY)ZM{b^4W))E1fd7XAp8_rOM)9 z(tfw&agRfJx#>LFywYmG+_EPd-eo^$^9E}eN?)V0Pl*B_u4Qov;ZR^ z19|LuoOZV4YdGBAD~WbrJzLG8A+QBI5XF`H53Qh zo4@FX9mP5?<=VHc*TWK+bHLl%${%hg^GORXY@)Wh2xzp2@vfoT=`1H3o(V2E@dvex zOa7;*>EoZd+uRD0s)X{=!)=enH=mEd%&b^+VHuGM!&JuDOy-ub>DhMj`}f)!yUIsU zapPt?m{o?K=cbATCwC_btAo&h#*jvlw2`zBwBxkmwZp^->V++1^nI9zZR_vN#;A^# zkH)$(g(Cgy6D??5L%wa?XZkv2Kk%#&J z07yW$zehQHOm8PoY#Zmou67*UPTv60DsRI?Q!PPNEkRYOpfWU5mjvDh=B2`lUnDC~ z9O-zlp}Dr#lj-CNas!w}yGS`I#dmCBVwVFDK9-?a%;c@EtFFGYD|g7{rn~~hYR4HF z2SBr_nUE!egHaCW78fNkO zZhR2$^nCw^w~w9w^q$A2#Wrm^r*3A)^?N_NbivOaT751WqX& z=Ka8X8Qivm3o?*zFLEFyw)KE-TPSGI&I?8nrm~UIU1>+a!AlsPi)o)y>+?lS zqq2590A9w&2X~PtP>9Sm6sV;D)wH{5_mb)HE8-*`q#_b;k*rH4>r$!v zQfWz=!FC#>w4NsLrbl0(ze=y~6KuzWw}#%vyYOJp=N*Qv8>83vZpU{Oxg*ob_@ju& zM>Dx@SnfJR8o*_Eq!et@E}ezWU|z*B4wm>&Er@FW!5(fNu)kzq<9tYajJKOqO3a z^TwNRj&FZ;&emDeA3P)WtJ^#B|2#~sg)ktN4wkkG?fb$`q!o@E&(rp?i;Qs?go~_H zOgLwyz~EeDrD8%mDI}d5L?GyohA*EjAb`;(53Py{_`@}4}`ul6DgQ?y)O2xWPKddvgp&zX~R_DsnPR?dmpON7K51dXXbT_!TJCPj> zKzA0<_8r4kljX|#WI4X1q>kRA5tsq4F}#{#%W5s-vzn34YGqN__Q^8rXvCTS{6iV= zq6Xj^SB)>};#`>A({(d>=x49I(v}~9r$5QJ*3=0ZMt8b?9a#7qko-CPd~%l=3iR(alO*ko7mch;{bqD6|t{ zXl*-fUL19(F`qB$rYg+l2-L#4yPU9 z#_-UJ7>*6#138?A4;L%-f|JK@Qz!!UVz_AaT+{U{^c(a$bYB1e0F@vEl^{kzJxGEU zs07!?-MjGsI(s&uy)9~;7h&P)$$n`0ay+(6~wd; zZU#T0@rP{F6K?=yJPBWd1E4`ZuLPE1dh)M)_g{8n+op9Ft?Tv7?c{^57slOuX9t#- z-gfkNUARSGd+XlE9@sjr-cSDie16%q{INg0dgs=I6j8yhCK8;heNTSJ?~>xQV=GL|5b4W+I-^vAosj5>ig+@f zpeJ0kmgDUN>KVarQ`@nfsx+(4m?|8!J!Lgf%Hph4H)o}m=!~<#*Vh5y;02GoKy6=r zeQ!Xv!G+0;HNbWw3G5}nQl+R z)MGtauhUd&OqoG575R)_N)=j9lmedvOX&*cUWgLaWNvEdB+HOXA4K&U_V!>y?!>lW z?~x0poHO|na?b8KZCyWo>*l}Y4?T3t7n?rr8Z_?qv5TL0?3$~e~H=& zvnl_tKd$Y(9*@G;;%8poxaZ`@xn~>OAHHw%W@ynFpxgYy)5wk%8IHYn%)>t-^9m>r z3N(EQ<`vDpgyRTp$Z^c(<4D*kFH!!6#sM=;CtN*juD~~d0~B%;g^`Ain(M|K?HsEg zquv7b%c(7xb!AP%4+M_J4@AU?QgWc%J!l5EeO?#6%I!XMwX?(V!hf1>@P zP53MP>Vq^QHW8#I1X2?~Nz|7cu@gltS3S&NSPB+pr+BoC?N_t1k7egoc4K$?)aA^x zFJqDv?cNWw{Yp#l`mp;_s+yfhv(o%IWt=jG8i6ERWf6?5BT)S_U4gQGiG+#utm7(r#zX*n8{U?-hH&I(^~)>T}$ zOmpQvjb83!cl0rt_MM6koF06j9!h66+Z}^=fmKAbDk7Q{ImBWSPD}9@pHGhgandNG z2kB$!FMUkw_}H7CdOz!7@GM+itbp~Uurg?XA6NQE`bVY@YhU&il)m^nbRE8yUn)1- z7He19uMXUb*5Y;iDtU$NW^I-Iw!oXNS3K@AfRC-wc$jYD@oKv16Hil2301~56bm8^ zsQXh5~DD}Ks2`GB?T+H$Q+a@UX-ye%5-B*W{J~?1J*b(a_UavY{z#R zq5eSzFhK?|K?X3vC9NFh+Q}TlSI$nBvyx$#GhBJ&TY(*tUY-j!uMBRJym_Q0H;0EFi+y6o^v z9bYY2xcavIu@64TAG`CCRSV{>yyen4Yle(mKXJvzO*h`~G#9D7Z~lf44{W&f-pby4 z*X%AJj63dl8Bdyf^G(xduD_#gdMhN{3b>UlM5BQ%6?+$iMSZ=6&vT6PEEroeI$N+ys5U^XeCN587sBKr__q_lXsvy;Ucc}nbYJ5G<8viiW1aq zBwCsp<(hG>@jpz$ZmaNYGN87CYH8Ra5FfXTg$vV|35kzM&!SEKYiCTnZu~$z@Wq8Y zPGaemJ36nq`tOfD{~>wf$)(G;K6CALkK&2?)t8UH;ZKXS;FJYe{?h@hKal@x{=59= z`E9>^iL3p^j=c}A162)DvJ+gBReYL_4GlKpynsYWAz~fR)nSoWNgbH{h|oyjqjGUX zpqc93PMwVdWEnJg2GscIP|ePL`}T2-`}UoDdfz^{Hye9k_jaI_M)eZgO}3xe9=9E_ z3CM=i>L7K5Iz^qWZdX55C7bGy=rg4{Q4}1!?Kzc>QzV5to>gN7LV_sO@#tw(qSdk4f+pw*#jTl_41%g)(YOh8rHeOReD*!>wTF&aCZI`fymYbz4pGb|zWzKu-HGL}2uaxTJaE6yZ2}%tw!LabEMnuauY|$T5)<+sPtBL9+IxK`X9U@nv8*ebU9Iok>)5+@wP0?6 zJ4UtICXQ;2O_-Y$~J3ov}#rN#|>20@C%kv(vlD`E0a#4>BuiS}v=&4FN z!ou?-l2ekGCYLBTE8@KHmBJzgWJkEkCRX?rE?7|&^Oq==?b#g*U;%^(bNCgHJ62Uy zS&5=0F=*-1Sj>fFK=wTQMbH9Ds(B1M^+JMaQKKdvsHnq6is}K;O?7}M(tZ?WS}T!p zj_9RaB~D6NckAgP9Wy-iZmF~urFYX*dJm0qUERry^y*lg4K&1yqYTHG z8e&9ogyDD_V=$8t%`pd+jWgsjXHE-tk0Iphx}dBZ%l5~Zp+NKRRM;540LXQK6;vZ; zTv-|xG^2uayrIUG=n?XBkR(p@HzUUBWCG3&q6kgtdq{fY8%r*ov+|CMT3%k4{~11O z#o!A@jkxjQ{6~16D72{`Q$@5n5W(f^IHZj~)=7 zo~w&BG@PPiWnd;Q#sQH}mX$-J zy31?&^8qPM6&>+;-Bi`_ZF|nj|K_vK{QJMyjEC;|GwyxnOEr6b_RL?WEj+yH@lOfq z_w9+7@#TN~3{T#2@Qpqj?s_c$?VT^?zg)YUYPN>~zo&wHIZ+7?8SZ!~9x9vi;L>AG zBnK=G?m3cp%qT0qn1V}LtX^S^sikS zw-`G1BMe>K&7H=@{rV2Q${5H+Bw3UNnU{Gn6buK6Xj4JzR8I8yy?&3M6C+$8f!z)$ zf^sy0{i-WLV*{B?75uHhIm+rKu+?b<>{sS5M^@T?9C5qq2`0|qvbD5LxayJXRHs$M|&)YXajljj= zSHc@A=rQ9g_J(&zxcepH1s{x)xQ&po?f=(XQ5S?T_0L`<{~zz9o;mHmzSAKyEbjKT&qBbToq#_nJk|(Dyb&L1s=z;yJ=o2am!pI`KvF11 z7(n=FJunsnF$V`;u7Yv8B2{ilQn@8b8HrGcP_3YR2ffW5u@6S!2*BS$E_C z8U*&uQJ^f17J>W>oy6fXrUY)kaC>{aQ=XF1_6YliAG*G4;VMd#f>Hl z@5sNk;ZONT+P2~GA3cKcUFpq<++%mZcyJ+i7F6c zlL0ZTE|aY;lWCVJ49eq@B+|heW(UA|>cj%Y;DgYgABko3FQ-e$niaUxRi$39)VPSu7)BTTQLG?bFxX z_Np|u$&|S*iJ9AA*vz1)vg@^RVZE?f08s*)`wp}LwIaS68E8B@fQ}%+9fyPK5hs}A zXtY^_#peFnYVL2W=B9$l40hJskMZv{_Ru&(r!{PC0joUM*u1!|tJ~_O18hulTYt1Y zU)n>>T4=dJh0nPe%#!`g&}Wl5;!<*@xW>N5B`ORx+H4dw+Hn{hcBi6PtfyG4r*yNP zl2+9pXU!dqGt)L2r=YK9vqq+D=H-kqjV5};U}1GzF7Cl`kKq~bY4Y$MoJOYAY^JkV zZ1(3OrjBy&u$rP%&ov+GHXXr{Fdh2N4738u6^C#J4uD2rLG|>Ro25lFN6zoHr}5<* zU*3l|1UFtgbjkJHcPB&buh0L4$|YF)!i7{WiN}a>WrMP^GNeKsAP!W|Q!nCHaqn}| zGW7%Q15n)*3z?zOOIXLR6`tk4k_DB=1NirNn$vX9P~3@HE=~(D-L`32H$A!y_T}Q1 zr`r;??bzn_)8n5QXNBOIsnl7r5(=FK2&AZrtO^{@#|70Z2(Sl&FMJC?}tUL5tg;J^xa)-=EH=bgCI#TRX%AhfOhq65VmPN84 zc%SU>1L@C-w5@IKtX$^J@`g7{+kSfrNME*x%h*V7jGGtdGKl(?RGe@E!#~M&&mQt8 zEOp&aZY-d#V@Cj`D#`m@zdU&#Is8?gFY*#!#jA-327mct|^W+DJ&mge{JB z0mr(4`=8CIWB*~2ia%zO9?qFo6SXaq=OLk9Ub~xZ*|Z#kW9wxQe-7WmP!l|MOJdG@}gdJc4%U}!B7pHe)1iQ(LWD0U4 zolG(8Me9$rI)vR8(IJh@(dwhj7Xa2bUnbWBolTyN7&jo|l)WS(^UJhV+V7w#wUOFL zCs)a*?7bZg+{OGd`*O!>yKEzZoV5>hj3cACVUi(_v7hTu?<4nf_el518@ZA@4xRQ>le@)D+`Gs|WXJus3URp|_X9*$ zR2JGY16gX^&~C6{+b(!v2e!dgq#ZU+jI2N{(^V`KkK)cnI@a6Clo#Sclh7i7rXw4- zxu_`+qB+XBx?mT>X&M89y>O4+Lpc-#d$>;T@d@jlEHMa(r=Le`o-nj)fQVQ#R)tgk2}TyYu|}r8zZvt-W@weWM!kjN%qf50P-|AvLgg!f0Lv~lV%>dEt!=Z zUifZe55CHgU9X6Z-CBjInhGr zd4N~;vG5LZpa}LGqry(?)xF+GAQItuo%h-Twg~@BV29%s2NwtgBP3p8xW;+L1&nZm z(4btTPj*fBObtvAP6=NWxixS<(L*tgbH{9o&oZ!lR-gN*q%lR|OUJ>DwGyXU;wK&)y$JaVh@B1MQ5IJ zX|3Q0}w2iPzwPZ{QKnwdHrbv_HRV zrWpXEO@<41fK z$eA4l(Gepy+qJ+;M(Lxx7wZ>$d7BmkL_~q0>Fv9%COs_^atBMvN;A*O#d2v_KvdR? z3gxKLhrYQSj)yV)3kU72$?UAj?5xS`|JO*te?~t-J@xmgAZfGNw8dt%!XM0A0?(C& zg<=F+Hj!`v-5n7km3NJ~?5@Ud@~`FB;A?h2oEzQm=KL+fE{A*ej)gDgySkp|@VXnO z-Q=^=7+gc)cHtY~VIS&+A2;rvo_-`vLcu{kVvF*n)cN+7dXr+6&?k^dpDEM@hNMRe zqXQ$;Ibm|LA$^5#4R^J$j$0?(jUM2hK+kdSqIdnDq0a)J1;bGxgQ|ox1wJR-6}%_? zZkkW|tJ1apY5wgmf%o6p8p$G>8Q3?H<%8Z}l`ur$3Fq&{NxjlRzktL9=Lrjh?jWH&7ISh$E{{n{ z*y{GM)$QT#ka{@n3DVB;Sfb;xd=C$mA=+IYOLQn96IA;aIeos;1_} zDStppSBO0#7F4+4=)j^>xu}Q@N>}jzT)jB^@I#OP_SO9E&8>L&YgE!M?>fA3;d3Bh zALKv9kw4F!cJb_oa+%fHYcB4<(?0wF&)W5J{>cxw=MUUgoqG^xw_^2Y`Su8;+CE_Mgoy?ToAn=KG8NU zx-hy}S?;*Xxl&!@yx0DWv)%cH<8!ADwqV@l^txP5ms3;R5t0b|Rnbi|{e_^S_ygfk zEWq4hGuGT;_-HQ%0w__&U?d0(4VMHm+a|5rp2|EnHOQm^bkV~<6!4jl>>Bh}Q>Dgp~QZm^TBW*Pft z!oJWwm#W7fRgWwgSCtKC)~OG1xrb1NiJO_ND3^qcpALqF%Rn97)PNw2#XzB4rV2i>R=OBZ$Q5$;qk9Z1e349G7}$2d}bSZNJ)ioqlEclGG}0 zt?d^3TIX&0%JQ31ciHc8-s6iEU9LWfv^$axE9pv{MyN9E=KJ?cquGE1_C8ldZi$dc z%5U!zt4QIL;1?)HnnT#JK1wX+=a?~&0X)l@fnB=Eu^j*EPV*Bn`lQMocAJohmc$~m zB=Q^)ajLuwj)_7n(kEJyiVG(X--Rd}w$Kxiv2(QN?ZpW>LqYr%~eKgeg z0>w%?=^4W+CUz-lREaC8dE{^qnyYuzD5dwT4EIlHJusc+lt2sMw3`~)^kTOqhVJfh zb@wDHt)YI!Sa)vBAr_u04y{>$UmRc4yK0ccADX(A&Tx|YBaZJwV4fy#06Dq16($ikBPygL@S3Em${IoOkmra;A=lbt{ z{`kLF3A>z|o@sqFI~ae^&~o*v6A!(b|Hu9Kef{#=E;@I~u;Fu(ff<=WkI%m1&)%TuH3(5>6cWp`hwlHi{)K>VuVD7UlJ=t7J-%iTO3wo5m@O* z;;=4C2_y!+kJu6#N;_GyEpFx+ydcIgsixU;7;neLnDrNijp3tQ1jp~J@W`hYN}jY( zF>ku%^p5h5`+G)8=uBt5>rn2n&gRe77emqAe{}i)9g`uRdz2RJ@kv@LF8ywIZk9 zG_gE6((TC+y*T!A&^UudHga)4j{C>^Nt1t(zs1k_f5aeV<1m(+sm6;_JWMsBTKuba zs}Yqi#y3ngqIRnhHRq%5+$l9;#`nhPxnk(G+u&y=X$IwRjjL$rv%o8h!MgaSJ+tyB z-uZq0_@X`MZMyEg9m1}YTRzU8eEfE7|B@Sba_dXmFWG~=(5ed979;448{BDlgx-v0 z7@+dOVvxBz?0lRNsD~TW9fW}y7AMbP3)Bq#Zvux*xQC=)LW1bj~f zFCl^gkNPsMB3YR&L6%duf2s%sr)%m|k$%Ko*HXY<&mj5B?zky$7--aE%#jslnu&uHXF;Uw1}nSs%Ra zm99PDalhZPX!&x!l8s}42`Vk4)+f1^=8NXd;FCEN_{7{?0&5hY*`6<$}dJDg6<>v6k%{y;DYUQ^vR z0R`i9tGQitYfSaYN*oDv%?H3PjDmtJ$9zGr&lhxSiW2j=fpohxr!%g*yt?jkE1Dei z2~L*|AO=+uxS;NIDvB%t zi|SbbJ34_KU6gCxDov;|c{BwFt4{G~F}CP{Bil4XFb11!yEuos14BLZ0u`K6MVZeD!IKhB)Sk!DH27>_G+DXVzR8`>!0Is8*1i{x*E;Q5@m8k7_J2aI|izDvB zapVq$ciRmGnA>YPP=<{e30l!G__Sy$kl+rxV^4x&V20^4Y7cbMBvraOOznX>pjrGL zICAwFnT!lDD6mvTO0A{|iaHddS_8m4QJR`4Yl_D2DjY>z;V8=}W`-SR9+ScbrQplA z7e3h%qR!B%OymEA#)Rt>F1pB>U2lAi6XS=U`x6}fwCe@3kQv*6LKlB_nm)}~$g9D4Elz%2a@5URcKYu~t3qH!9je4O$ zWTVkru`5*}d$_97UR9N~5A+R+45=Dfm9yun=G*60HT7L{N7XK#>}Piyv#Cfwf36!Z~MP9u0gd9%`>#-`SNpWUi0U{o7{KWwfS*BNl~V6E;zEiVf*g|7Q^U45+Oz z=W3o!m_y|E`Mmx>GR=vSgP2MAa1mEGYv=sUyU$y4{(uD^&cQXq*W7SbNo(-(w{BVU z?08)Xlhqf}9(UGHsWhzuX`&-PIx4}h8P{MzbCwGOgyDivU)owqN=wV4 zHPLgUi%Qp*ibFhg{<`pJ|LAZ|&e^X1FzbDfv_FAsN=exQ9A_%QUT=j*`N zp}&?KEG?9V;zG5v+S^yCcN)TI=Xl{#;lq-D^2c>e_c?fxphy&Skm`#%Y(Xo|5wvU; znp13~7;~4uWy8A7ur=9QY`mF6X=4&&3l@iMk697ABUZkKxd4rg&eUWfP0CplY2VwH z0ywcnS{S>yYLJ@=2hZezHwTQE16E^NSDd-XNs5pT49@!o+=`E2z7*HvahSu@#;02l`f2rWkR`vd1ZW(Joj2$-?}f6}Vl(rM9Roj| zjY#$2Rx=D+&ytQ!+-_csniEOzX28{s5uc8dWfdHF+NUN)^?AB&@s>+AHyioyezki6 zshxc1vgen`sf(k30tklgmm3w#|wT>H{*lEKwwP+DQJ@1a%q+pb{VTVtWX@g0u!6Y^} zh^}J@D`EwC&0cb-SkdwN=_*3Fj!A?!3ZzgOhV&ik<1cEZ?aKs52Kg#q3H(Tm6=^+NB&=o~Ujn61q8 zHbpy1-x1#Rd>s1B^O^VCz~4fjF>LXdmS(~fkVb_mI!R}MD}0832pM1>MTXl)ct=Jr zQm5GG*gq3L_aDbc9Xj@bhpjsSb8M0e0qAh2fzJ0YFwm)?{rTMstQS)*r**;UOi;m? zAf@YXxv=gsTurVP7vK`*ToavKZVCx5rj992xkSq6E{0Yv7A&Ft=yK40bXkcSE-N8} z5=Ijfq@`|iK@D?l2gVKVa)~+l<|X30ErAne~%D(#p;kfr$ znD6Hv66zN{$2}%|PIQ8MTIj;)4EMtDjOcQ4x$hV`7Sxd+JMDqMcs~tHasH@ty}m&w zy3R+Us)TltXQ`A}$lhVFuF^rE@Ad#J1gsShPFpgJnKc2!4)zfXS=p`SN$gf?pq<`I zsi>-LwPSm@l;+Z<(zSH^0yTq5ajBo`hG}euXN?J_#n}Li5A<@$D6guu`r4Fw69M8q z`aR0}-NcG0>v5L#O8fnE4U@~Tah5}H40zxei{Oswo@xju%*lpzUCnjHsd>d&EiBW_ zf(3Jo+$$wm{0t}9A^{@zlU=>P+4*JuTkQSwyV!wGexYt%Idfgthh%~_c*-r;K7*$O z9&f{?phGp>EB{IU-+FxWuDST`RYT`KMRkq`*r7#u8wGHs5%Vh88LAHT4H=)R6?X)=L}vtpCsws$10Y zZMaudN5`D z-+P2@L}Ga5q{O7kdD6_p%*v+TExkXi_#*L5^4khmz%TmR$(FWWQIEt_u^vZ#nIdjM z9q26to(#Fp(1mE!sSYoTYO3E?ld9>t?ALeJ%*pSK3KjxQ1%qz|upTf1O@WpG-y6Dw zOzzFlIKa?2(2d3chQ@S(40iM@6OHLrbis@w8VAgDKSmt4Wc|1?mvPQgCr+WVQpQZB zjG0OqGnJOV#ls?&9>Bh;h*%`|8 zUYelroEdvcOq+{CGI~#hW)RK9_ZVG2=1_5V@F6q0-3%%`K&Rm_U!uaC0ZdUkFu+PN z?m2h<(#^L1LziB+Cg{M+T0c5+`5$iEef3kbKicr?ukL^9x@$LXx_bG>hVX<`|5;N9 zwcd*BKE4m*b@#QLod5m)<7v6r*NfZ9%~u3idOF z>o?eBs$Q)0(vDTA2kTa!WnJoJo$pPVxoA4n>IhvSG!EQ*5b-Q+rWnpSZUh)w z@Ya-s9vNxJO+Nq;1`mX}9bA3Be-RlZUX8)Pc15 z$0_TT4N9xhp&U?-C=yail|@R6@<{Q}L8YLmr3%>Z5>Gfqq{(|mANJJiF%kulS4Al$ zApQ}41K-Mb@CSLZgFnI(#K-x!V2|fbSC7yq7rUQl-OsD^`8-n;yrn33Ysin)Q>CoH zkClJO1dHp~qGZt38EnOxsh}_JIqrJ;ADf#F{k^8Gt&RWN{{1I>eEP(PR7#;Yx$oKB zfme2L){xVw5h<&`zBBrnt5UF@GS`bM(#)U`r-)M(&T0RLa7^SBYre0UC8Jt|Vi8<% zZ5eU$WbUUbaf@*e3&S4S=B}V&*&}VRbqnl3f*mk!h9e@+3%oc;Igb}oVjs0Z{V8{) z`XTpMQF=7uk$+D-Bz`IVOZ>O&bE~Sr zaXg_D6%-kE6j@H0(-SzJPnlB|ROoJ=4r=iN9jLI`kjl4Xr=bWu3kH_SbZ>Z^d1Jbn znz$Z}x#H{u1`sxL4Ym|AM`{Q=XpYg46vkjz)T41AQgl*DKL!mf`y82*Xc&jkm;^up zbMX-KHBm^j|0QwWr9Bk`UAssxnhSLBzWEp(ya%VQdyE3?^+1-6it*Mo20EWX(&ak2 zj$>tUgvUNg!KKR098rRHn#&5#pSjMRp(?#gvWi?%Qb*?@Y%QVF5#HGvXPYgF;%as* z5xE($xePmzSm@ZAU^%Z_{dDumR-H{^fDPNz*k+5(N@S*PCViCqV;;+1KRnIrtz!jE zNZJ~tKmK}4#Jn8m8qL_+sgwg$obFJAaS}_w?)cd+^YigbpX49CLD+S2H*U=@>zYMM zug=qTq;CQN7{q2}jWO&!aqKkgD$c~}fmElVleu(LPb@kOf6OskfuRkXc{OOTIRmS9 zfVu74&)k-oGqj8ps7a?#Dm)?_5cqLW91*xuVUf@x6a*ghib^Om2H&{+O-_@VeigP_G(TWs%#f3yp3 zYGV_)OglhKgEg5XpYBASBBba&a#>BnWf3J-^F=KpVi94BD6tmGh+0I%BElA-S%dC& zi*Q(k(;_^U{is`n+ag>R;jzpR-6Gr;;j#$3m2D|o1RY#5#@Ot&DgF?DNcl_Pv$*iC za4b#&ay+R7BXNb}lCh}hqlTY^#bh|7t8b<7`qYLLNd*F7M{2zbyLc8pV9A~?7LRA) z120=Vr?{{lP=o~$G!{f)k$9JttlJ}$fOAGHDECO&W6T;%t&iXcdqAZ70TK3q2n}Po z=mR3mN{O&&Q-p#QGnXP7eN@B>`bX#!dLdGiWVcT;uuC$qOQ!H!2-DCSDMb|WI0kto z{{eX{K9BrGo9LwFJsmZ?%s4Vx(qW=td8!>R-}0u30k%XHv#gl&)zij$ zwEt7{m)%=>{p$}uyDd5G>_tCsYnU~9#SlJy_t@!|H0;{EqpN~EblLPFcR$f}FWI_$ z`S=I!?E0W+Q6C0L^5ZRrN8m&c*{HYcf8{>+9N~_6M4sx&GGMu@bbO!wR`6i35ai>s z*WvZM!J@{Z->%vnn!{pRhb3{2VjdY#oyGkY-58Iwt7>$I(Q^V76ms1TZ0`zKFE<8pP%uK zpYf2NagRS`&f9Uhiqpw{)SOm-U{1SwnA3a_-8u~S56$zj0k*PI_n&ECA7v)?X(uw) zd`&hDq`vc%jqMj*iYlv;%87c~B|0M5sk(~{L+5HYQzgn6qd3IVgDX})cIC%SkB-;X zwyFi^FL|0z-@AGEqA~ri>smrqUB2*~yWZ?#>rD(Re8E>h&)ZQ5zqG>_EGBk;!9<&` zr)SKjREV8$OKM0vPds0qA~wo%#Cft@s}FGx@ec?N*GIWW`G*Im3DcAd^_)BBzc9E^ zSg6d>7rGbvX9a(XeTpd9FXko*lhli~%edLXZ1plt4Mcg#1whp^_v@&Y4feg^Va`x_ zg!$MJ#yV2>lI{|Vbrz%f*02mCiW57`1^9}SKN!(rILcGCeI<+}U5eAmpWUm2_B#M* zMXy*$!(>1^7`r&kycfnaj&h_qXlRD5GK1J)0*W&3V1ckAelWB|Y$`7@;Bgd~2x1|$ z;v)TQeI(Q`OhaYG<@tMZg5I3Tfti&%ojaE0sD{fzw|4Y}tzukyq*#71lZ~o!8 zZ@dnbU7erDCx9#5D2DGbmTGz*{VaWy&ez9V5?t^dBU&OPMEN+aNpzk6Ss~Y(shD+V&C33 z-hJcs_bD2jpP$Dagnrji6fZX}vylv`3Z6+uk*hSZ-d7(Q6-QSj`*(ou=u6+RZy=aWm?9UB?GjPWP~=A%p)IY9|iyF|1xwqa*{YP zZ}*0yHpwA+qdatWz)^#&{_Z)}RSdi#It=2(y3=qrIa~gp_Pzv8isJ11>FS>Dp4pk5 zYwv4@yeTDyN;)-o_gwNzg8d>Zw0c% z{ZjGfZ&SSarQ*#m6>t7#Yc(9(xitLNUKZW*K1H^0i|wyzBz|9`_@o(+#2K(++1^ME zn;|u9Mus&;v-IEj1smTJbN!+xHeP$pPg-XSv+qcyn_{eOz4?i|j-9Xmbno65U)g`~6_%85LE*lP zat+dZu?s81N~)0 z@bM8VyH2l}Y8xT^GZswfN_E*-o*;i&$|*fz6go0A&XP8|+RIl7QfiQ)XJb`DLa z!0wf)awqJRg?uoORVysTw1Ix`mUaDR*Iqoe-+%#qr=}HXrH?KcdhU~DLu#ilY}t=E z*Tz3mHz8-btB`yw)x9OeX3J}N!l~1ip)}!;<)hB|F_xjoF%&w6PL3hUNnIwjOoeHM z=emcx2NsVnoLRWUeV2Ph@e|<wDDWY6T3 z$==DnIp!Sq9M7DTIo>(GEu~w^{JiMBxO4B~NuK(Y8KpDI7Z)uqZYaLj^RV}x^835~ zsQY7{r@cQZd#rqO=}V;<<<1DA&@mJ_hGNHHr&o89pgW1uon-1fM0zh4DyW`hmX&xt zT28byT}$bfpTkP_!tAbciZZ)4dsOzc?2XxPWb6LyNcQ~f_p`M~_TAYc`{&?*bnv5` z{fecr_W*Cl4k-H+K}tZ8r*CXd%jhX*#rRMIMd>yr3=54!*_AEGj(y=lrGkaSZO%Am7mfjN5-I2S(l#Et9Dh1 z+Ny>sQN9lxfMSv9hxYid<=3OM`(>ARJKjLSHnO+~r2D;yMeLf;3n=r55Ek zcJ|~d8$IpKG zyKlUuoR>Fu;mm>O6=juF4O>2P$PML@ilN`RJnN##7xgL1%MW{sd-Pv2dD5B*&v4sX z9RFN&aXmnpN`$|N(dwMr+O{sg)j93oGU$%MBahE1Wi8~cSRD)v*$OFMpGQ$CBjB#^ zdmsy`DgHnq6)L_H#1oGto_LkGVGeQ+nr>WeG@SiqR9s!qFo*^ZjdTd^5Zv9}9fG^N zyL$+3!QI{6J-BOd3+@h$Go9z1?|yUd+#j=Mtv>tgT~)jM^pEa+s<5^=Sbu!)ShQeu z!+t^3wexQV2@xhuP`5yj>@zM(PO>la6vRqx8at+mQL1&VDmAcSF}j6uB^KRnveHOd zlk_y1O%mW85S%M-vi#=Ls+9nGhLn+vB%6S{!SDuRosski5`#p-1gBuwQl?JZjRp_Q zbCA>%F?rj`XY3ES9ar!pm}>5)c(g9MYORs2|IDZn?l7d&aM+jNWgo~-pHb!iMcll2 z)THG}Tx|GOiI(vfvF7WPq!1j2=(}PpqPb4`-_O|Cw!3pt@s+X!f(IkBmc@7}W+8if zx@**fvMZjZ&C!x9^JkX4-fk4iw)E%A`?L9?0DP6L0qtetV3 zcerpEzU{P8XeR2_@EtEK#@)F0=3n?;h}cb@yA)nD$1G&q-;8LIxAAIB(T>iRYRg}= zN|@#3YBZQT$P>6}WtHn}sw&$OipP#+7QiU^`VlhZABsFP-Ys;t?Xd*44M0uP>n4lH z3rTwGiffjwFU7C;wf@rT*y~-$i2@YbNWtr|nN8^Ww(xeE9wilc(R~Fq+H~KZ5gVUe zbjzs_`s0$N_p^9XD#jj79#;6+<DD8WYZ`fCygzm z@mga~H1fm{H5J>jLu7yslu;z@ zeuD#E{Ep8~3`DT8A5KnoKb2C{dEJ~+xuCySQD&I_j zqFM^aojBcC@>HXy8LT>?-ete_z95{p0s(oaXSk=QEi>vy8#456I_2Pa{fmIS!^fp1 zH1WHm`G^W!*Hi-qln0I-MtM=$^d|BOhY1Fqa1!P#(QSViT4>|WusIo)e z+B&H^$L=-&dq}k{M)okO&9;ljyG*hT1LsoC9ejlVMWgdL2T$I;I(FWpkm0KMo$@>C zO<@*{$Tr+Z5;y6K1}60&nO1{{wt{cPXvMGl923bo2PQ4DmTB<`;CHO39yBLxo#FdV zP^UTm2JbuomLBwXva!vVgjz%MUn^ZV{qgC;O;lf9y-!uOEXO0p4`aL3*3Blxujzl- zZa4n2#<{es<(kA<8Xw*AsbLHHeWFp;2ZYi70$BJps=A3!WP9wC{%P~zfqG!ekjv_L57GL**)FyiG+yIrx#)P?IY)ca zWOue2Z#5})5usX7g_Yo@@LhETK}cuz%>X+`onZ15iCXy9LMXP%w)r`q$p6H^etUbf z*U$4TuB%C+K45VJrPP z(l!zewBS<1Q+e3lAVMF_$~Tx5ZxsTGrZykN%fdk>(3C12MQg<<`4aiEbo5xf_xiUvJ$g+aW#qN*BRRpY}BEb?s*+4)}qj^yI84b_nG z^XpUta|NOi1S|;~H^tAwr?tzpu>x$*Ml*~B;*4nJ4%n9TDRB`_^w&kjPd;Vju*c{G zEJ%Hx<4GHtzrIKPGJ6i%RLP0b`}{_k(>-=BGcs+S>@nAk_=v_YUDsFgoSsBsoP9(Y z%e>VP1?mWMWCE4uG7GfQj;u)!4=O>@o3>}JDa}IiJyqVAK8|ZDAy0K*9VJp}{xZIv zrkhQyRJL!a&nV9Ad`IZ0idqmv3Yv^UiH>Uz*Y;7gSK%cT_*pkaEFFEhCcN>cxUef? zyH!+5IJ?{+pH1IvpU?+)(VwTh5jI5Ngk6O#&^QY2zeD_zNx}c!U`s6u^2(+W`XxQ; z;&p(WTjH#CbK&8t*&&TthtbcXfudaO7|)v~#h14a98;?kocQ5z8$iotU){lW>+>i} zu6$y*0%(_9vw7sNY#V|sopKUN)%3YXyV~jX-2+?K)LMI;>$tOmyC16Dok(bq_kb#0 zh5j0i8NR?oj$BfzwG5RaMt*aoV&-bJaHMrHqF9W>i8Jg$(0vk1jN9hiy!l1yq zH>cjin#y0DbU=rxjRPRn`)`}m(vI1cKMAiOOHdlHkpF0Ff3@h6S?{*vtuE>WkL^qz zv=8k?by!TRej&|7BZAuKRlsj*bn-T4HGPt3o4@j6HI}`g53{KTZ1q2X@!b|t7%3~D z(gVP}Y4VSR-r(Yu+1#9x`s`hQ*3G^h$W&D{wAaWiIxRPB--xL0@Z`WEwGY$hAG`#? zC=tN}^dnA?JY0INydfFp$L&xkiQRGHw9&g$d?RWGDvCY3%7@R@RP&5QkMHBnRV3k& zZt3nZyk1j|E{d3dUVm+wd>c23rW*tVl5td1B7Q55oEi3!^)&XVQSq4FjRyjuBm|Po z_nXuap70Gbj!TyH5i1^E)YIcvs%Snh1>iIc9aPbkX+Hg-x>+uJwX!!fYXa1El_|Rl zUJS|Cr~!CXJB&SThY=UYHIcaBrq%9F`Iy^6FZ)?8t-&h&SNwI5$shJ$145wzz}6-{h-|7kUB{oCb8FN*XGQR2Ns>xd?u# z_n0Yk5k#wMQTuaUQ`hK?hqA#F)$q$0fVh?0F<87%)0nmr4%C$wI&J(V6=wVEehH+1 zy%o1Do~W)I@#LVewwHGc2wyNCwWD`$5QuGo?8NL~u4(7B?es5@h<-Ane6sKaWkYmh z>A6$(r=U~IP~9d!d3k%kcop$~k);AAg@&3fgr4-@A2*0J^f%1g&(z#+eCcF5AG*`_ z*+SR^pAqP!wrx5rOFV>{hH)=^8@xSiWbmO2teM;Kgh4(v`>A~6#P%Wh0q8lIwu|g8 zvPWn-uRY%dc|%#O5hI(G1ox8>E8x)jG2mRrqbX=fM^H>;tSY(qecFe)5jEYM;*DFP zwaU3CVKB0sG_s*BVn;&=x6I2TMzKnwsmpQq0@Wx6(b5+KwhyfJEUt~jFDrUT_PK=6B z<3_JC#?Tr*WOVxoQ`#Y<3b!@ZdhM$6E$0jNEmwYOZNEFo^)-;;0~S4^$z~{^4$Mb5 zq&0o3k6lNyjx2fYTFn1#YU$gth&YLu+^(cm^E%jp9vl||Y;K%7)nE4=eax;(5x}Qp zn94exUK-OTXf=C^w;o*It+B)Vu0PzV6QkxR;K8NpX;?Am_9MGVl5~OAE#q6Eisp-= zer%iJ_h8)WBLfUMe3MBM=?=%|->pV={uYxoV{ zwC)KXbUsFRKn+qKQ;f^7O{UJ81h_XnwLTRaIaF<6NM2ISXt#P6xGR=wp&YjJ{l4>% zMho23p?vK^atyD4qybm)Q?1Ay^knxw-krjnK4cMR1&9k>H7cQ$? zI4(mf%PDFveAJ$3QNm0xFUz+fHAR~&;VdInh|jn2H*ln|>(*GYt5N|p*8X(});Ykl zFvM4r+wNaYPX_K+Lwb9lNWK;M#ury93mXcoX;QIif-Ls4M?K-!7@8gFoz%1>%os{j zaMjza{c1+1(+m<~oA=c^CZpDGH5P5gDx0U&MoTd)1?9!Pp@wC`y{NoUatiXWy1ZSa z88Bn%(wDiVvu1C8zv3QH=ByW_Kl3d$$-c$B5WgP`q3kJ1`YCMYqLqgSyQF+)RX~!F zOfUB0Wy7*J<-lh9;#%KQ#&(wus$yuBv;Qm5ferLY*EIFD>Q0Cz@lFCgP+xX;tG`Qr z&w2(jjoxc_k|g+HW^|H!8#i+r;lW3OqCx#TNW0Os%a&(|k4fyv};*sV4H$sCx4miK;uXS*#Waiz{ zFk81R4f)DXQAPgeuqv<=b9~}B%`4g{(|GZ7u$9WaU0&E(C5(cWmTWfZ?yb~bN>Wj{ zRmno*f)5Vo-(9Xnkh8{%C;}#}MlNlw{}>usR~TjuXmr7~K>3HJlsEC}{!X>8SNRwa zKjC3qU%=0L@@OiEg&}*!PFNmEQ2>KPx5HHajh|iVV8Q&r+)|h+iPdq06Aj}f%Ga=N zd>I`hTHIKpl4UV?kZ*|3&@sVLSwqKG2OooFGR-o7sSE6i{;^%ThUwd@sqU;6be9=(x1mwXnqnd!93r+ilDZ98FbQ zvfFX9&VH_Q%ATkgtee}yA;dCDxXvf$=ScFNl#r_%=^RDdok%PGQf%}M?hG1p1e#{s zJ$O}#A|d7c?Hb8;!k}dAIU+ubz$qeYoR0}!Mjl-|8)TEOsukxI<&zjmsZQqeTIEh& zQ|U;)Ej^g|^ipGMyU||Nbiev`Tk?7~7X;e!-=51U8^*ZM|I8s~qkXp)j45lI>GjbU z1PUU0JD-;Ks!#P+eQA*Qfjq>Gqj~Am6|w8|PwzQEU|Ax4uX@R?M3`R^2W@!S7?1Bm zFn86q|J9EpaA13GiYdH>aGXnFIwZ$Bq3Uz?%aEG%37CJh&Y{p6Bm%`2y( zHb+{Qoy@r46Ja?$BmAff^!A^@$HRCZhPZ@c>-8WScI)`k3SDZ<^J;fk>oN4_6;BFt zmXt;KR(E%o&ST5BTHONU>hr{DBk+i-E4}*X8`ICVGL(BmfzQr4-PvmWZ-(nVh<337 z@;~1cQz=Mv+}F<7FA8mn1CT*e9#iLTUgHaxr7g{r?{I}h1k-rnnmq1Nu=t2k0Xd9E zpA3p_02{@fU-d&@a$Q(9d*U|&1KIH-4%dIYG<{Y_e3@iCBqHE0B|L&oj5Pn81;Gc@ z3cpjRokQvrR(D8WoBR2==E#k$h9^M^dHKrqowR(H@JBo9PI6R60;BA?5K^vlppHS* zvW&VF=C2>GUcL9kWrz+0hx6XOo~wvB@Et!q7TcOvqq10$1ncv;66yf*5RxRosWanBPxXez zBg9kr2F|1Z9&q!;F@e{*=r4+9wpy0wf*(dtNy0ngWYcVT&ggxxCx+w79&g4e+HI5w zng4W>&j*J*#jOgi*v3469x)!ACS0F3^1fFnr?YRXLR7(;AR#p2)&%ePwKL@*!fpBl z>H>VmB57e$M` z&-yQdM_aU<8L|^)`D-OBzR)mKY<*p1!m;$H;7Ko5% zs>HcuAgt&(Xxv&J~0KHrx3A1{gM?3evhw3L#wLGyahzYtb^eoxpHD8lm!8}?( zdoX9bz}n@Qegv@NwEo#ydaPrAUzdvw+Pt_j|C%!;x1(UstWU1I(vs`zenPcVHzp;} z61zU+h&y_Y*TNF>VUqsk-P?%oF?H>47wc&CQZRc6NsNEvDgUZrBIu`w4k4bu($-gh zX{5oNxe9}K{Ot&Va2Nfp#S;0bmen^)^Ad)pb*jN*30=M;=?*?`*=CNMd7!BPx8Bfn zm3^UU^)97*V<2<4^*MLgt7zw;)qLC`a1LKmqPhL+J<3I|$rP$4hN$K`gF{Z~`{$<# z-`OmehG*{)1iWTA7*l^m8PqSJjX5M=YGpTPxm?$03YDU05$%phGY3saZccukhXb}f zmibwEyxfMSlD`yLyjLx12SQQVi9UUXhr)%zdRQrO5ZUIy z&7YpBw~*5d^T*$)6nuoOb#^TvPi6|lq4**KDf9GrgUxwk9CkVBKc|qqoD$9smg=|U z*|sCuB1^sJpb1pl33`EhQy`ZjjT9gy?pp~GOeI+omTKCbNmmP;cu|`Y%=-UyOWhAA zoCP%ka0;i3c>cPTAe@tKdh@KS<-WT~Z0H7Gp>%AJcY33*bJ@_1Gt-hd_%a!xE#em9 z2{I$omTbSB4BwSwTWi{9)y7p&Jy|L35aO13VLLfdzx#DkV!2A-C23vEvs@iqreiDm+#=X) z0^+b>?TFm!?M^4RWc%!ot6L;jAa+82wdr?b(eQoo^IN@^1qbI11Xaf1DKAsktL|Z$^#0;2|1At zXA<6FR=*T3KapYB;*(qyBK2xrvuD-lNpess47wBP!%-Mo;}FsvH5X+~B}W(J4e^_7MYpX~VOpt9`uc-kIkOx7 z(N$q&Si=Y>>*mwsBj%MnWHfWrONc*@-3R^m?(qOBX8#ZIV+^2TxfA0%@{z|r5zK;h zZ_uYR^F9K%n|UgV)-9TigfU>JaOUCY#puJH6JLU^O|fOT!((nV;YFSwVim@Fph-tt z#xv7hio<15!ue`~c`xZnKL3a#BrrM4W=TR3TLg`ynhOus71^SpCy*V|poh6LHiWVD zf_VTVYAK-krOV^PUF2uu{9XOt&My~mv;*LJ>ejYx%(!;i=e5Oeo!m69*XrRh z_%Q5Re`9Ol4tihRKfOI&y9?=m(nb347ivY%?Ww(Jkqvs&+V)%)2=pajL^-$&Dh_gk z`7QYQ@1=1quhSgooq)Uo-}|FFl}YmWm+8-^oq{Q(vBdADCy9sH7B?FGR39v}&{;xX zn{FVCiv@%)tYz_DeCDx+^C+hmMJ;xB=zdXk(MmMXj^8vS653J^+bhKkdWX;9jn%V^ z*U<7byaJv}7qDARe1@($^@qkUIKHl_?NjnWLI>z%Oav-a4V&1K>8B>vg>1@f=`Z()QNvtre1a zx|{f<=pD~SIgkCAFS)=!SnW3wmu>oLUo8uJH|svQ@BGqHzA7 zK0x01^AZXYqW8er$xPOijlEK-_Px^v_%+-s&tUriU80>RPFr^AYPX=h1=ncaH zsbop|wF@p=q7B>EVqkW@FMFz;m}KlZ-lL%^C!^Xw#?JxrS%d?G?{VqDMZv0W%y)5k zC&CsCyUM-CDv>hrOm$InXNUI7D@v5_2F|6KJq;GJDV6}sFwg-vgE$-IUMZ$?MZgyDoC5u`Z9%;4Et_~1dZ7;0(U18{vZX2W z_EaM&cC)uUc;X_+yv@IjcFmd9Ge5ZNa#1uI;C<{*L{Q>wr^vjmcZYP18;95$`-pMP zsmqT^0d+CB^(8iLG~i`q&m-6OH)r#`X_Qdn!ou= z2Vw6c$NQ&%Iwzk1q()Ci0;n43H<|!PS07m(E%%@U%~Qrq(7+{3`={M1cgN+$!%BCV z$^7D00nYOOuR8A*3?B*+ks9av6i34k=8>x%%neBI?QtIzl~7r?)z-&oPTL+ zOrc!6CzhM9&JR3M8yOUt+1$Z*(u18oaLX`7c173yJklo3MKRz^u{19|jX~7|y-gwa z!m{)7>3ksdoP9}D>5Cpmd*8e7-D&LHef8x`^g&Xi@&_XL&&q}weX%=BmGk!S5N>1b zH)*Gi&R+;NR@KGhQPmFm3X10niHCadZFYpw;@S6(n;Y!z_TO>Vb87Es;y(gvXaW#S zGEwwL3~`1QEvMQcmeBS_5wUaPoTiQ~=NQE)mQe0C`b*axL>|fu*VZ)~)jqx+&k&cW zjd(t3x^222K2hvCaj!MSOJ~(}_+dTqCi5ciKXFPBep)$KJO@xQgzR-DR{<>wrdT|> zs{${!o4$@ZMUzN0jiNQjXB$=CbNe{2x z0#j@}7nh~_kTYaYePG1Fl{;2axsJobqo)GBixkNmL$=d&|&%(3OTd zW(T3dx2J>XMjRzs73G_jls3G++U9hazhnD|KQo-nv?AZ8mn%@DNyU;bgm*``I;zcn)b_TypFa9m~#8t2`(Np z(;RY2e$^X}HNAZgUGgI)`={Xq4@z^Uzt)jE37&y?Jjw?gl%t*<@%yi61)ECaQozt$ zz(bJ9zz4D8$-OJoJ>hOwfM+s{aSII9hd>`M-YD5-rVD zmeeBQKRx5sLM$8a>cO5!BiE=Zng7T!8@rFNHI&~8;$dPpU3T++i>?-_XQ{9B>b3T# z{r*;VGn{I9oug>BpPq?3=F*ApvbsyKK|b+m z$92(zyBqnf5aB(jdXQD46XPTNRJ;*BXHegjE{OKiwl0m$S##ZD{M!!hx$CcX9bjj6 zwmkGuGYsNG5Qq+vpk?1S*%(vH;;mtSlYpV*T=gT|1+T=Wt(%p6c&VUi1#5n~*ybK} zJ+!m;R_=ssA?F3LiNl0O&)K=FOE1|Kcp0d5MXWDgp+L4^uczOCYW1m&Jaqin^bX?e z!xVcHdn-leZBD0gx2Ggb=OxJ7Ne-CZXPu=%uf&w^5Dlpx6}ZK8tzS_g6uSCI;efuw zlWi7>?vl)nu>05dm;2n`?oX*eXN*$9QaA$G>Y|3C7jPXdrbjpxqzC=LcE)D+zH=H} zca7~Ar_Qb;cn{??oZP}0)cVyfN){CmPzi5tsf3NRo6VH z=*vBwhmVdeFOI&_L3|AswFIzggYK=*!|s%X%F*oMKPZ(6XAn%^+WGtpxK5BhwW0e% zKk$9?)D2)!uv1=Auxvi%5--Rb$_=Sh$B8D&7bE?>ES3yZ$a;^}LHr)Ya>~U$sWvg?VPtp^eqXS)7 zPOc3MO1mz+li37dvC&)=8Wzivtz(tD$%e17%F)}<51+q>Hs{HK#uAqrne12UiGB>_ zp!EE8wCw~=tA@>X>dAz3E#ssNY3jd;1h^&xDJBFqh97(QddT7r^5i-6U5cBq&9y2V zqvYwwGA(mSp1O#86u|x_ybWSAbJZ+QG zf3$aD8P6E1*qn-LDrf~fR0wv6oZQ(rWlI<~%0ba?_`F(s=L9X3)Z4}EE3wI31dY^z z*sg9v*PgZ8?DORm))Iyswa0DC&saQcIfg7P?9Ck3zPTv_ubckBQo)git$iy?!3*F- z{-u&GhS?#9Eoe6jW!bj$<0SSn*;c9ik6GEzLpEpckoP64nwvj(6>nc(s@Nqv;RKLl zApQTg;SeZ{GqKf#dT2e!4OhA;H3wIQ{?xpXs2fu7s}AY}9?0Ir(`nmD=1+6o$vWlX zn+4$?n0!2}BR$90o+aq#O?5W6*shB$h*U?vC*ai}4*Dhwt?v6sY|)Ryo0?3X(~Ryy zW>5dEcOAM*-mG->hs-h)dYI3Q^$*cG5bE&`^nqLDIGM7JH}U`Q`Th976rv+ipFxmfohJ0R8S_0v>n-F=L=W--q6hXJ z7O(M6h0gwZlXxnn`FaLNPhh5f;~x3u)YK^h^Lul5f4uqvtk#H^BkU!O!AO@f@?wFW zBTskOJ;%)w89bZ<@b0eAX9KwoYnj-6>Wi1ZaFpZ+Nt`#eB4E{FtBMjsG9<4euFF#t z`zi%0-I-6(?oyeA&{qU{9WQuGI8k|4Bj4z5hs>Xhnno;HA@s53M=7M|AN1)e(ao$b zblRV_eD5LhE|M9Ts0_@f$|GInHIU0hF9D3+u{iQdSp1)*s~)zwdc=D0Ii3<9CLi-5-fv!Td4_t`1rfRy`zX*=LwPND^+x zDc)#8G+X~^)=2^GosRa^Z2gXLcCtoGgQ*4z|EO2W$YxYn@M1VX98m2T}!S_$L)DweK+_Jp!pPR`d%{brbimc-=L<>`L=udIyR%z*5 z3mjjq)gswL=PF*`rj-gjw2C^#9kYNo&~A`8a>@wX1ih}T=wrD!aUDi^xm{`88};~dI|3f0`4YU<3|n0LBh@69*WrNf~v zvobijRy{w-$ulF0!w!4=(@MRQvZsy~F{8zng#(dy(kvs3WJ^z9rPZMPM^Z7kd}8MH;1>pcld51-OIj~!W2VT2W0i4^nSVA!TEB@*fK(sVGTjN*~doY z7i;oHpx)zwTii0Z7Pe}i@vNe5n-UTsz4nEw4k@jznK)7L53S$)ovOKm3Y9bt-hHN) zxGoJ&-9gsdL*1h5e__dIdXx=EO)wpBNH5XccOecEULb=M07BGirMu@^G>~Fj-qptg?~>g za+?dj(=qqnoNHnD>0@m79H$+S&Gq;Po;Rb~Y@1A>Vd&gd=bS^_T&=uiY8fl7Do!#D z5}S0tN>QG$<%lv4ATcC$?kdv>xjtVg+?K0P3x8Y*=YbMQKotjr3aLn1Bz*3BC97x> zf1TNEnWY9$3RbGVO+cM{=Jq-7{yI{AWLAFrN!|k0ZRZ*GOG+~quNVT|^a_kDxMg8k z)7i#URr;2HsRs&#z9>_t#e%%IfEJ$r}YyEys) zf+*qGh+qajAid9Qu;sqT_v6)`uuU*1RHwG8TE|$!^g7ajz z`Dh2? zveq$#5vmS^sm0?!zMEvbU{*`y&)s9URNo8Gm1i8R5GzOq!rCFm!iIEHX2WC(qV*Ti z*=Vwv5^!|Ipc02>KI1UC3GQ;ClcYyKibeZUi?iYsFl4t%DPEL^S{JldY39|TW+ZX) zY{ai&ar^JMDJ5>xxgRjo_3TeQdyS2?HnUf-FED8Ed2CbB&!1cWrbuXzXFTNCfcU*(#{65~Fdn$nc zKGu>pVLq5r1cZE!2~toe(>XS?livoR{Iasw%KQYyw@>`yJzw0$w9-4E=Ejs0l@zy* z=x}C^pdJ@B-=ve9x}8huOxX#Sui0tkHBqGDS+~n|ap% zNtlVD-;ZslOM{Vh5$YX;W1NDh)0k=@YMj!J65V7>F1K!i<&ZTcWyQPXC?kcvfVXAJ zput^nEoH#Kj8nSXW{}dbN)k|DWss2?Wz{vVcAGuhTsX7!URfBP$rn0;XYQ{AU>}c>TYiy8ps$Y6s2> ztN)4e|2+r)FM04^UdS8Tg0u7gH|@l249%SZtpAfb!ov0*U=eie?5qGf7G_oe^FQsu zCa{4OVGwdQ{+DSS;0QDPWBzYJ#|#b}gOrP*jis@WowWV~0FO*lrE$9;#xI>OG(I*!l*?aG^(sZ>19`xt2dJp7!sLj$DCg}< zYqtzmDZ0SajkK(!P?IhG=0)i2&L=6?FOLS54~z;DH31+8#$;2jCGlYWpZ09h!|{|C z$y~k5tA<8${RyDu%pm>8ji79=R`bz{rR`|GtBz@3OhR#PkLUkPa7YFCPs1ONnJ8| zB90-aCY{^O8jCD7T*R@!pef*n?kJuA6-Njtr9YP;dys;&gLM1HhB=@?VgA(3!0`3}aVk|Wz>%cF{J1**N0I4n>24N1@(iw#N6Z_JzXImdp=`%7x^zAV{9 zp*IUyt;v##<4cWUE;GZ~GslNGG=?qgSMJAxc6^#kLESQrq&eZr11YcM&HUISIQ9s+ zeSW_-Rtffz`2|i_frCt0T?-=qAWO7AGi)w&oNkzZuDy%y`zV68P=jP86QeaTzXL0K z0G(dh?}M4Nfkh3-l>)efQkP;1L8EXk_!*_Nw#uG=D;=a9X^aE`y=7poun zKL6@2zD$dDHRRJo$r!6PiClp?`@}P%XTor6#UHrUpOez5gg&%MpP=&%m~c4G07tdV z*UGPf=_Axsc7MWjkI)3a?h%Jezl1n5cT@^aD0T^M z3l?s)JykrjPFi{8_iEK@Wdi27QR`KSdro{;4a-PE{^W~d^=0Ebf;Fnat1cU?twB3O zcB*VMY4_R`MAJKUy#Xj2#@K{z!^q`t5lI)uTXQXUUs9ejCMYhA){amz3-5i%^=a2u zES~t=!s&kLCzJW5yWKDhat>j6Vv1{v4w%*HNy-&y-T?_jrf<%dgWK+)-})^MGHNez zse(Wyb~XXaxPCEH+b*1%OuB*2a|0J_wA=0tMRO&*KfuMs{B!PEX>-fO;i^oKe8TQ% zd7=|QpZAKQ99sXsxQqZDG5Q0VQ2SeA=>}Wv}p?gR)eBw>71LzT!COnL`(e zs1EcseaBgF$eNZ6&s*@(bqTVPMZ3J4pFN|4?O1jbK|u#NqPxpWoJv3krJQdIQ(sld< zGWN0M<^o!5hp$sd;lNK1bsZa7m&AF)7BO)RIt-5Jo)nOmeunkXsF^ef{CbPb>yuw~B)_K3|dB`+p!`?;#g=-Y2m zC7;ojH)zB)enWTgJX~N>XDB9Xt!R|Mr%)y}LzlcuPK5p1NoE9qpz3n@z1Lg&7rlr~ zii#>}MH6DtJ>K0Ypwk!9EobrPvsFKIlrK~Sdz5*I26ENyf+@akNB67{sDA#q<}@?8_+2+J2)ldcSy-)O6*;;>NeK3z8%kE>Ms^ z1Iq}%8MwI{m@)&Befy?OUd*~= zNmbP*nG|hdMuEz5gB*Yb&6~iRDiw^0a7<6H+&;f5wK0n*kc8L;nNWws0(sEQW{uA$ z+IB?9Sjf|v-L!?$yy5*287V{lQ#$H6=2DV0*nt%R>!klUU>fsiS#czI4ih(=>tXI@ zqrL%y?Z)R4FBA^?tiTZcNNt4#j#ohnrK7!iRsl5*egU~==9VBmRYl<)Pv10PDJ;F< zZ~C%gelfew{Cd|A!u5v2Z{0|wROWR5^O)A7xnn*^+6!QL$05LJR)(4uR9^ z`E*HIMtaPDrA(2J!OL<_xMhYFiq8l0&|5FD$HEK6noL$>YTGnLy-L@*t+bl(ZfdpZ ztux!t+ImsmLdBZGix2s7Rm2BwtIkc{QqDsH_fP+6JmlM=x)I8}CQy>5gx^)K*~}v= zrwUtB)o}!Z!fkRN{XX-$o6VQ{bnd&lVU7`?Cm*qimW6A! zMD?Z-l?FVM9$^f0E|s(S!>-kt(U$e=!f9+(jgf&OXZnh2c|$4~DrtZ*1C#g6c~Z?S zY*$|m;%tZ8n+wKz0rkBym;MC|VLLA01tC9qMv?Yh)n?dTC4mhQ%RwqYu0XlCXhgSx zTWddaB1&>p{`kBrjh~8pZjOv;{&2irbV!3X&e75i(>XfKje;6Gnci;nq`Y>xu2uX& z!T$v>mWgER!cqYp`4W!-RDS+8Ra(8UIqT=H+Fh?vPP!m~u7-13>?dZvpA1yvOWNf^1)4q2o6XOV!ZTI}R!X?)k6Gw_VSLrm_ zJV*@M=;69sc#Zg(eZGUd$}ow=cTc!T&iZP7G_vB}>9&PQMf=}$R!9p)Vw|*- zpgCSE0l;z7%&e9{&%`LV2S7cS&AM9hdY5eNwZNYsHsowqpNfVn8x=$OdrOIVOK?vu zUzJH6Vmq;-eb?|vRc7cKVc9q(H^-5b~40VY_Bqj(0z&bpKp@wF%>`T;De>(*$Q?Chd_rqocbGyC~B`PaH9>DO>IS4F6hV~P6{9K(vNjqa*6_){I)j~g|7 zQ9fCYYM$59`PVzsiv~}^p!ysWBY%Dhn=;nJKn>kT7=>W5(Q#UL+^V8z&endtOB{R& zVmJdFnCUV(tnA^wGq-^zu-`uPKHe)7YB$$nuCfL0jbo>(@l`txOVBwUG(hc~n(6_B zU3I7MiP924MZlv0tjIcn&JMIXHMDwETG{E&64}T#dkBiD;Ur zwzM=URRq`hXyQRY*1^wh8?3L)xKtEmW?UR%wvjuEiuJ?zd96g)iqWs+{z_59iGSrD zmfz?V)a!Z9oX;+Ul)L7by^eSO&hLwu$CBd-gV^D^}BT6VLeXUY}0m?P+-XeZ{_=J#t`X?5wack?Ro#lFw-56_;oof%uy#Nx?y z7wN03PiGB(&25eaRCO&lDv_iEBou{_2P5TXSf4b{qKi)u4NbdO4?N}y;j8Ey_*2HQ z4(A3Mb8~}VG4`a`tL>FsqGU!K{Zu4lyz%zRj3si)EtMdioI)F zrI<=aP9_V)Maa%~#yY09GGtuI#A#UVF}1tf)!xJ^A?iVb&lDFIW6`4cH!bQL%cv21 zLFc!*&e=XZWM_F3$GxUF2Jx|&k-WHF5_5^MxVUJaHUXa5i8e0&?jIA1vZ>2DUl-#- z<~&jzs1+DloJ4!&gL9Iei}I9&pr4UG)5&uJ)3QY{y=;Oj%`SS2~2US^N0w z&z}dGWnIH$!QEg8H5)Op_L!<{i9gP_8rh^1v1Y!Vvw8hSDurJc_j`X+0i)i=<+4@b z)F?m(0&3 zQOvo=+h7n3>dIo5e@;0_RS> z*q#>25@G6J<3hLeJvlFB)vF|zl^ivNvPLf{vtr(ji`z9gJ>6Jzeh*oznxD96dFiI) zM%^3D$$#M91_3C^goaLq>`QX+d{F;`H(2aYs&b)a3zOFKve)}&Kx%A&i7*LHI~sfX9fu3(Pyv|A8CHNpB-cHXJk4Q3=zlQgyHB^-tuCV_H- z^#7pk9)m>p+6B?KZSJ;h+qSLUwr$(J+qUi9wr$(CG5vqvI`__;IWu?W!~Kw|WTleI zT1hIYG`XkR>t^j`kS1wc{l0gC8+{ z98o&#D{v?ijDSq;9+=TSvu@T@b`zc#hEzO zt}3;nE-QH6yIv{7dh9E;mg&3TY0&vujw28Qy=vORkTLVOYh}TdusK@9LNSLH>wo0V zri^r*vhU6VBOTwjp5U0^<<#9B_s)Q^48RksJ*jNdGwscm4j!RBb=Mm+w|N*!v~u>h zK??9e{_Fxr0X$nBZf*SZ8J(G;p|X3gbb)_uaBNc)l?(_)31t+EPkb%IP||$ytUXKTL0>YU zb&8|knvDVS#?WTk1?{tX-kao|ItXm>aebKB4mh^yJX%cyXPvxaur)BR^t@LoSem{Z zvM~XjzU2Mh=-p9juW>WDr*S=4pl-LCOO??I-F_vEiSi(27rKgl0xl(km_2#c6(77^t9z+`vaR~(0ukvL_+m^MpMAlbydUJ>kW()L>Q)ntJl+KBmJCEjhhOiJb@_L&=02qKuT zVc43mh-8U|O6zq7r#J!-dTC2NzJ6HUm!YOtv$$?iO5aoBQ|u_!~vykl(b++fw%g_2%!c)y7q7 zETVlv*YudtoKZfBA((6mSJT%HKCQm5F_erfDOH=6P*^HKNXsy97ajXmM8+5EnCdX` zyf*B(8EwShJ#yuF9P;|d_T>-vBnp3p<_)KD4Mb>w<}4=Jrve$dgh4=2{vavJv7$4} z8)a4}*Xv+b+2YNKClSn_y~|i?VlVBX95Dv5d!gt=9GUGw*o@=aFNb~P0Xw$E^69FR zn07Q-DTHp8)qqWdjR*7M1vrxV>uEeZ0$Pf3bzF%)K7z?hw8lez425gq!>A)RAZEHDt#kSwnA2tEm`7ab@oQI<|< zo7)rRQ$*KEA#Kh^^m>Q0tnP=_)cYAjs%=bAa`&O?-|!iJ#8@Gc<*>PvZ^lo}PY*-J zaLm)5O4`S;e*p>}4Ra;&RpXuh?dsiDWy`7-b=cAvVdH)3?oj8y-Ci!eY4KzmaqpiC$6!&Np$P<>2*wn{vSU*JZc$ zboDYNXM!%r&dPazEXk_ac|_&Y!sFQKqLq3#Vf9n(g3rlPcrx>jR)-PkzM?Ir!{fx- za42e)aFgy;CS)^F-0}kle63^+eN}DUwqX;ua~#{uwQ;j#7R^99AB0OpqahP<2&BcR zDaW-BZh;F;7{^2);z$CP0repJce|Av9W+U&QY|<=*9>eE3vaJ zLac4M_jdLd+6RIf&ypo2C72!*4q4DcA=MgZyE9GL6WW0Yy109U+MFS}OR@L0RL#RN zY4t{GN8Qfg?&IZo^4~cww9OAT)0PRvYbahr9wut|YV~cW-?EuxsOJ^I+B6AFzk>t5 zf+34R?$OSL#)OjP4EQ3{CP*7z=@8ilY!#Z-pCq3#WN@fKZzB^$l0gxn_oFqahZRn+ zcM=Ve_w=#%kqq{JL)Q$t43j|Yo6!%ZI_P7|O#G&gry!WJ5)3jBtIa^LWgs>gB1wgT zQxnOg_k4PZ*aJBd|CLV9tM3w!32@y)07<5;KH-9xtqsg&{?cQ&g@5=f0(K*Ahp`nV zJozd%bYUC8-V8kFQMG41}X5(eB`-UQ5Xme&ZL*PQ5^eY2g6LGPaxT@+=#h^ra_V&YUs_Wl8CE z59%SP=6%C zvbj&{y$=T#p{EjB@v`wANRU`acEZ8LZ{^1p<#UB!CA?J`oeH1Ry#p>fGRbZs@M5UA822tCCq2YZf;aE`DmsiBDXxLu>I1h_ir&3s?no`X9)lpw z#ixIYZMUeiFtuqfbnRL@u(_l2em>Ij*#A}a4dSzD8vGqoD@r)fN(qy;t%f~tyiivB&Hea3Ilqc1Z z^O!n-?2{pDDps)M%Ze6z5XwGcP73?(Pch-76DPDFVr3$F6^-Hvk>#@uXqkqN=fWa< zq-%W(o;4=ZZL`E+ZkWg+i|bI`yNiw(+Qi&Dl(JHHp7lU&Yh_{RSPsnNaI`iaR*Bukqni&kOd9slOqlLY@=#7OJ2M_(p!mB5o_lhk9BP4@ZghYj;a5jyLp< zwpEV!2H>bu)C1f4xPs~hcM0*i5=fGM$ZLkmpK3<7vLJ)pbofNkMVckA3vcfAS9i^l z53kG+&lE(qKUw}aLa)?;WqcR-{R-uuwV+0bIi^?M^ijhT#4fo`?DOsF8Z3nKq4bR9 zpx4l&2g?)3j(igOqr2o*`WC&sW>h#S_X)^1*BF6j)|2VIolJfxX@m z%F5eH?zC!#cn`j#S3iBeH-hb`S7p*|3BFPy%|wMP9B(7 z%;@)RxQl)sbn|-pG+ME5*)?z8eBr`tuz?i}eO}0|9TY1y))~p0Pjq|2nQxgLXP2ln z0Ksp~sBZNe?F%j{+c%VFj2KpAKa|AjCHkDookfC+bG5i@Hv1YD0uF3X|GAa84OXEE z0vMSo!5O#i&}{G+ATqy}-UclHFL8JdpsK8C!puN$&$Seh&0rDm~E|*^u=n|CHu(K&e)GGY>DV|gRn zTM=8NxgA5*^w>poEIwVLuKrU=di!N}mNzm_ zhu>^FHCRt`%7uJv9mVD9(=vO~c zV0Ducaz{NIOLlE;^n8)#;(cO5CGMBP3G`F@^vPK7g$9dX7X>n+9TZw=g;f7V%e zKDbqar=GU`GW;b<$9uT>dj9H=I$;cXEV3t(V&vqXDsrWpRra~*$wxE9Ce&WhWmuoF zKSsv!Tp~3W1;~|t6IzME{xzC=SaoF9oM)R>Xf_dJVAJP|<|-ZiB_>&V&0!DM#KfK= zImkPrbc*&$`p8tdk2eQ+gLQak)+Sp)M42#EF+GlqsMA9#$!5uER^K7QLz5M95#F`G zpb?UCDr+d0zTw3;3#ObH{)&ZHAZJuLYnNkk&ldbxx8gZ(@#uJnQ~7QGCe9niI{Fa4 zi&2Mmlbg|8ELnBUbJnz{EBV(${ws5O!CU6LhQmDFJ4??d>WVA?NB;HPfn6QDS;+7O2kH`+`@jy>=J)K0f5HfyvribEgV>E*gd|aj645v+!M% zHP-@zQ|zhuC?~$h`M53Gq$u+5Y*L8VC2x$)9EGxI*$;eF zp%fUlOaIEKBJWa4Qbk*^t670a{%*)T32-hb4<0kJh1f*w2h=%WcU&DYVxGV@UxR6r zQ7Q@zS~b38P9fUN+Iu<$j`#QwNf(Q_9RF&YLgx`aLa}*oML!gCKG4QH^wDu2W#1jT zisQre-@_3LY6mP%CEVF}g`6Jp9x9(;j6~r+Ay~V z=%2z^uW*zAIa`2p&Y0L+0YjhYZY7|P5D`3^v=;&PpiW!oGu}xz8u_JY&mYO9Wo&i` zmz4b7{2FqFb-os^g_Gp{yx>^;);-FJ1<`NBW0D8NnW#E)G(xMWrMAKxPk&F@e?szx z!+bcPSDcs!{cOOh0d0WZ01M}Hwik~J;DB}f88@y|Xin~V?%c(<;XWWTft!KOXO4Lm zOaYBY=)j7hSHF_8qytsW~eFw3*kzb*bso>930;eMJo7#-R79@+4+ zZ~MaBC&tA3Zjr~*k}PBGQ^<>dAw6#2|0(@hTcQ`gagp;miUGa){(+$LweF)G=~mEm zp@Z!!9XDKFBSp0UJlSP}N~;1ONPCq*9rXbLUjN2E+j zzibCjgXEKV1f2<*k1&r?PS|`_tdDurXI|nZ8(CEYxea}H2cmj=KXXbr1?+sM|ep1E zr*_}Ng*OBDd;*-oE_%Nx?hWej1$ENy;JKDRdJF>a4$mF>!PLW$3vgr65i$Hr;by$} zvPYuRII|qKEKDqRr}7i)`9ya1 z!{Us9pReq>cDM|D2KS`rIv>{orn673=PJ@v)3$cy<{oJC+9Ygs^>gRgv&WJqTVa#V zudU_b7_X8j4#>wEFlWgB3r2Us-QHAiS=6$s7`_!*zoI}2Cn!Sz ziGMwubHOn07^0>>rK{7YT_ z5 zaN1AF4^Le1Cq~ih@6LP=8Nd*XPw1UQZoce`3zHwrZwClSk8jckcvaw=*MMgNUo7&E zm7ReZxBTyQe)xl3!?{E8X~J7YwQtv;hWMBT@9mwRDz63Rz;ik0jz39dKn6SOx=7jX zeyluw!hl+igmDk#0+EZtZbSJfKl2^lnWH>|+9T+1ggY|l&Rm}mM^5GD9T?dn!hU_u zl9dxo0hUfGrz__(DjKUrdl~fXe2dYrRt=F%RS-SSgr{-WS=XVGh4~?#FcH%Do6U0p zZ-)SnpKC6?`v!2YyTmMd*K^~Vav+(AJhnSD70Yns`8V|oUEfv2ZQ)|6o{a3J`w_w9 zG$Mn3)gjb_cL3=x!<~$WLZqU&H$qYh2IW$&+)zA~sD)wr*f-4UVxxY>Gt0B62d(sP zCVmU$j3_R3LW8H0^h-S$P(<)ek&RG z=L``7qU6zE?pFTjfdwCFSG<~q+4fHh!KShM>NLGd&s~_VsC`86#xKtykpz#yy5fge z`%OE@-xDnBSMKI9)GT;Wt%w&PdmFR{0TE^|8=M`F+J+Ihrb77=U8Gou)D!`6T+uS_33hMv@XM8hhR82H?J z3Eod?&Cg^u9wV19f59Srg*u?a(qDmgCZ|PR{yyh5B#l}x?I_D;;4SMimki>*$~BnO z3yfy%5Gp@)Jd6B%Cwnr7w24lY{@~(5HKlPA-)4GL0jSH0xckjB26Q8T7vBx_N)<2G zLE3eW{y|>I_p}f5rL~N>hYgNM2WH<4VHz`_p;dkkEEqNR)D(shMeqTujz6aPVv*Fw zw;IuWb3XW{HG5licld2hO*U2QruN`DO-m==1nKZT8El$vLBWOgL3=SB@_DkPyp&_; zvldZ&#!PP1Dmh|rx%T$=@B8GZi7&vu=)=0Wr;N=SAhx-H9F(?O z*YkSZFCFlUB({0D9dT$6#eUmvwoI!I=>4r=`vwMG)+0}#dmewEzVB~fKX8L+F=>T0 zOgTucmr!*{CQxa#C_{mqtY4-jqT7fN_dFBB^m={gmf4POA2Z(Hdd~{k&{^N$FAd(W z+nUdKlbs|xDbmQi5@EQDTbsJfroC(v@0=cxtwS%cCu}zw16%<-3%~lxw*M5|+`F1X zb%JOIHq(XLovAt0ittnsBrb1L&2U6{=G+=aMLQyR@No$YsCN(If$sBvRV%#tLFtA+ zBYH?TL%!2^g+~hxhdSx$H3VBE!X_4+&MG<4U0h)i$|m8Jlo9ya0^wV!l4q;R)XQ~h zd6F6yQn@Fcv8LuC$5dd!6qw}!94+$(=@T3Pz2|-h^g#D8-W=c`IR(PqPJuCqkv%f( zATC69SIi>+3bWt!1<#rBR)OslIvjV>V|J5Mf0itNtKUU@#9Q-pEbh$7i2bAjq>azc zN7|+P{Z%8?Pp;~@T_3F2@Xx&Zv>SpL;t0F%Num^HvADD#aYNMHJEgG>Jr8iE-?aNfTFf9TB&%RBuDV31aN z@A|x7ub3GTIyhTI2QtGOsSfHQWDTM*Fv=ErrW?8dchS1SL$=-^7Cr8#+yL&`bj`-v zdsSInR#M{Jo=*kLvI5&DM>*$FpR4r(Q)|u3)er)O?qxL(_)@nPk(H}T^SF@v9-@PO?16Xmf%>y(KT!4H&TLqY7NKIU{p`PSLR53Qms|>O?K+p6#71Oi z(^l&_uOPlA{oj?HjnT>ayfzc2b#66L%um1$=pJ;ojb^-uFbiV8yWC5+G2djB;ynLhY(M^8H z^4kcW#V+@pH^ogh)&&i$<41zz>xjS}*rM6us`j>hTzgB}V{U)_FIv18F8pQJ%wr#zP9DwV zk^bkUcHb!*qr=CmoQ-Hw)$6a>&5<;|wa>u!#&^%3Y&q8(z?)>8SI&5X72V72Sewy| zn%3tlBhPP_SI$?6sT=0c2G2=X72KMONfh`#6`n|(D$bP-YHpZ=KcZXmYIzbpD4yr88!O>Q)v7HZo*BR|G#{tbMV$fl&h9-f=$mZ9F zXZQGudSIm)yQ%c-T=oMg7%RKD=e+Q{>S+|@$3URGi~)_+GN3v~ZK{XQ0qD(-oZLl- zCgVp`%OQQ&tP@;V^gUuFfT+}L%WFv3M@H;N7I<(#zbAbR6_Gkw-=F9eg4g--H+u3TG%|I{4(8*aX6P=jjY``dFRlq(Jh<57 z-dS9B*k?zsHJLs~y5N8ca4mx`=vppsJqkp+IEQu?kvQwxzUYQFv4%c+f<`ow+OVY; zwll06W2joZ+K*g%eBfB{u+JO`;!v)(2`_P7-1l%|Wc&3&f?MzhWFTU-x~h}`#%Axt)mg7~FS2$1hQ zo%n((5o&DE-n4{B9s{Fd{5*9-oR5 zWi3`tSYJzq;^0 zkMsYxpZf2H_TP-^=cxZ>oc_a6u`sax+fgwvv9LpNaIpQa85KR-|H!Cl7#L~)6QyGL zuPN2P=+6H@ss4d)|IwfSEv5SRx%-i1{|}||{(mWzG(6%_d^xxgg``Tj5FX_vxL>Ed z)S&th_RD*^P68{(0uovS7n81gW@h>DSbEPNHokI9pzEkb++zDDC^zWNI_k+*R!S=f zR~F_N5(RBKCBMA-&5^MLvg|p z))AwE?rlA;N^6D+cbFP3qXah8NgC%OCa zqe=wB;D=2lkjK+g7y|D_Nm|w9=LQf`8nkqr&(P#5Bh3J;vG4dHyF?m#(w&H0R1}NQ zt$kuDK5D%ylYm%#zIHw@zjsytX*$-=V!3R3u7*MYm=Pee!=LCpgEG%>?+PP<2Q<5C zb$T_HYPagA1Z)HaD2J!ha=0vFVdLdQ?1_@G2%$;k^W5@W)}sSpUNY#d1y%p8F0!Ah z7xQ`(P^6~qh~MZ+aCANRHJ4!QXxh)BqR!`n?$_mVdSRJd@h$ZSn*PwzijJn+>+8<6 zr5YYUn#I5y{Tmd(7ygC*$ZQlG1@F_bvc)}EuHzUywGc7J$ z9~V2M$c}9z)>!4h+6@Tlckf+)4prg){(bGlZzu?qcn2GFdq z*_4uQqUn3^dB>e?iOjBPK2TdhJjlDaHjYl(PLfZAglFQE^>4*C!cG)VnNYY^q-rr3 z&fS(9H1mRjldp%%FeR$JTFh*JHt|I8t{+MRs`ZV<4dA&0ZwJ8}G!03BrpV7Z+I~ zL-fM5TbeCfF#ngV7rbDHFg0*tBaEE~5PTP6Ho<~1fq10K2)r}m_zgZ+`gVsO>Zf3@ zFPoJ>IxiU4Ey-P`(jonuHC0OI-U%=K(`~Ah$?YKII$1usz#t&5d5s zmfZO~d~r^XyLTKg5(=TI#je-EvDOVqmmVSo>EnSMvt%SkAJ)54S@}ci!`Z|5DLg*N z>xv5s^DdX1A4b??lO5AVpjz#<)(tCmXg5I;`%nF}!eC)RBd9dVYGLYZ;_Wz}GvTkr zIg-W<+@t&rtq+*5vM(J9v2w0Q8Op4!Y}sNx$?mcn*I!ffVc2G&hqa2kD>j+O#_V9< zu-p6C7D)Ws!wI)9UGO_EVk71#WHg=eSGndkC@ub6Bc3ndis*&O#kk^+g%$J2^3Ck> z{@~@e7~ylwIBRwndPFRE{?;RDxQW@%yEOwcABCBjVzk6ng@M%g<0B6B0hNTyL@GJ> z?IXN*ysu2JREK5hoN=-WoGD-FHihjcfN#7!Lx5~amWQf#6|K=5v{yJ+bR9kD_lF-K zU4h-n-LjyRvX={8?rY8-=HHoL;O}~pNyX`kkxJ)^bcI`T-pQB&+XOW1`9!({?725ph_~5(snht@2Z~;3aU$a1vh`U` ze@sX34?rE_It0Fic?q`V16ES@kcDVcW$6Z8-QsLYB;F8tx97hn5A6rFNz?`x?QvdM zEnC-byswUVcX^K~u6L+je(G3!si2mmm$b<>i8%8=rk_bQ<#w@K5>2TieAwB}p}%n2 zKw1S$B<^<=`sUj^0P~3Wh&hfzvun|^g=Yw3nZuB;hAMWU2v4FlRVJ4~1QZ8G3$V>2 z*?{E?W9&jLu;rr9YMFy`%Vq~FIZ;clscdLDQDqHU?_TeokAT-=9)nmA^6>*R$8jEP zw$}o2DED0+Y?~03H*T0ODq2X^>~_m5T*;Y%iy@A6%F+^g8zDIpHW@t7Lg?$_d;iJ_ z#e6}O{K91fwsglhiAmW+ncNO%;gou#&AEKaP~Y%?1TDdzS7w~) zl6mw#m$pCO#FvDkg#CE)rTS%?#Ik+n;g#Z8BSwigQVVhqwnxjiEjMa+%lm6iP*q1& zcJSN~bbA(eA^MFBhSNfcQh-*jV;I>El0oJi{qx>1h=7*eG$aIPzWGWSmuuMcg&aCF~nZYw`K$kl;X#DR!nO zZ{2xpQsxQPtW|prSTSHdvQ!IHZ?Q?_H?S>E;}YC)BzWnVU92F-Lrn~OF9<+!Bp@R- zr)>TtaweM0t9%#uBl%;4h|3#g5Wer{{G|EZH z&MjmkH%Bfu#^4g4yaJU`OmGsP98Io3tF*o{>)UOEc^i`7_wtrta5{xeW&TZh3Pp2G zSk0MFTw397gbrE-887J}Br_=?R~oJ#cR)DVa7;obV`FV|H|n4zVV}S}1v@DrXy!DB zq>|2Gz$l}*nYuteFAlxB-osf|@$%Z_`T#{=LS&JNp3dfJVwsS!IdoJjYQI%nc;04s z#iW6~v9!`=VpbKawSJ*XUU#w9WLbEyG+HHOX^hs~wEJr%MO2e>sd;C?6(4a}F3FD7 zLrTjsVIx3E@*nZRTVqped3wj%BM!BGsX4=tZ`PI#mza@_5OB>7xoU7g12qQr+86$A{k@Pp5NkY~iEhcx!qn9=U1vG1^IXKn(5B_LF&Wcm)QjCi& zL_vuy(1}r3;wJY%U$kCxTU~laiA+8v9zG>L9}BaOgGkMyqb3}UwU`_iRazxIF7*@{ zlFR6-%vckpg<*;&@r-ED69W<_FLJ6)JS0vIyagfY#NrWCJzW0-aH4GCUc^5-eMyp=XbwIG zF>zUx#wbA1F9-Qn)yjI8QZ};*2;1mX#?m>^3O(5rVG0TNV1Y`SeZ+pYXs*6G55m0` zUa>I?9rWiG^79rt2yYKL=!<<}_1Kduv@}H2~2U5aBQ%cv`y@N5#lDTw%qGU0sSSFeas{utHLAx-|{($!e{4$yaVOGAUb_aNb zTIm_Zo#%;}O*!DbXf4AL+H?r+a8yNG;W7M*pLkLH^@|oN(Rjp@3!`|dKE~}{%+qw^TO}@!_W*u+6|Tw)UKL{O;EDX_mhqE1 zOxStnOb^`=*^cbnlCWL(TkOzvRHkkTbf5}I7FwldGHL1(@T^{xlI=O*V-jDhrtOW|`iBa4Ek6}@>h3EyW+?y!a390LW5WXiB?0Vo5BUy60&DWZ>T!6ILzjzaip@hm-RBP*9Q3Q2B#@ z5qWBuXO-V`5)=a3>>$ zKiqfeFN>CWE|KrObkhSRjIsr4$ksNn`A$g&A@TU_2^9?~vemgO+%#_A_J{`03~VV5 zKUncBZCWPl=^AQUa%%6y#@8O zUzHkNWz133a)W}+1_L|@H67^@ydH@$qnoS#?)qT`eJL~}8ru+h`QG)=jWy={q#fDn z0$NiWAuyOc3$8p7QAuJ+l!^0C%v8b7raj$mB-wccQ?#wEH4ffBfAkehvAXr-0c4Ci z9J;BVFVJ?$ShsFyZ>7_5X+K{;-x#Mh@#B;gD|-7YV|H6PlQ7bNIk63>j9IGsh(nO1 z8K^t6<`?7~(51~MF@4I@{3=Iou`#6zR9a)ojMT-49cmSo!1e;QL|y)H#fHIHRv>J^ z;5*It)Uc|e*M`V6;6I@B`Jf9L+7{$Q3m4E^JRd5-BYD(wQ37tl=W4TvA77~fH221~ zk|`{SV|**C0-VtI2~S1@bszW!e`{MLXjUcN&Ww%>tf!h>2XrTIaGxQ|lmB}Q_r~oF z9yTGiFXRF7ORyUGS*Cv^bKt-_T?}|#@-MdxF~WXLt=?tl*fPb|UZ>c`!DjU;CGVMc zxmC-NhGRC~o$g5GXP%PF8VIPlK=dzSqQZ>z{V%ua#=fh#dGbL}$3>t{%sS>1Z zp>&LJfJ1FhvZX63+#h{)g5C0{wmtpM1G7Cs2Q9#p3ZtpqKY8lpy1Emn=tEIMK(_<} zQ;W4w$l?i^^c?3jj1+&)55w=MU-jKfI`nu6EsbrfEWQ6$nmmp#z*jt1#Fn}@nYzt( z38C)Ys&yLB37L6Uh2YmKDjG2W@Xn7F`biplVsIo zoOQ|BTk}n@{Q+0^?-DsfPb$l?Su-uYkFwrda6W$@SR-?B9Xm;I_7<^Cdz;PmZ;q!O zbzr}@+-Lv22&kabYqPy-g16Ci*_=n)Z9b9`JK1Ed*!szyKe_SMFReS$trZ+zM{!J- z$^aerOfvG0LEgk+_R^7=q6{1jXc6!-TlBRw2=0$lXn905tRwDmS7R^#{zVq1)28 z(-+_()>{7u*_vTFU6U%Ao&cpv0Zg<}{x0`-uu)sN&b&>k7_ABogSLd)soHA|?8enL zmK$v=*BGjt|*BmEl$dtAPlvzYvJiEOwqF47UEp1Y;Bm&y4_`LdjS2 z`=4k!ra`T|71pa3yluznVVIYnoE6?AkDrm?ie$R(QLC(7F{=slH9Q}9-?#KY7Edk* zQ*H|rgzR-%OIXy8Ft8UTf+{+U0oud1e?kTwzT# zZP4V-j|C`U@pRBeL$*@|-Y`jmW(mR7&APv)|7-I47>=AjRoF11E}LutyeOZY1zz4#W_OFQ(t&tS+hS)jPutforj7*vfUK>;CD zXflzA?;1uQyz@{V!J<5`Ji#+9O=z!POGml$e#@J#tJ``CO9?w*k>xvnc}qNtFoaEa zN18)g>I>nf&C8IpyW=~)-;gYv*3#+0ps(`{jDb<76|t-{YjYjHlh6CDBOg?x6<#0e zHyEly5@J$BLhjPFiAX@r#Nqv49f9sG4CYUQaNAjw42hXD?mOl-?EH6FQ$pdY6u;WQ=0<|&+Ly@R_9d^hjwE)A#2y1pHJabH5`4@N1*%8Hx5 z?7QxPnY__KlV6iTY#ugu*E1VdzoW(+iX3gH0I&Qme@_W?YrfYnQc1J|X*n9Fgrrn~ z?K9h2QNXW{ z9DnK(VZjX9?q$#;=Q*zjpY9RhTYpd8i=8MvL+((qD<%8A_4(=u#78SUb(x&b19W}K->!?DOXLw9I zEOR{4xN3ABBW2EORgkQoU4XxURIV0DiUCFT`vZG}E zXM@2~Qb);?Rc%vF-n$XyTu@vUK1yz`i%)%3DxRMv<;F|DV+`<}D3est3wL5wTS(9En~3z^V^*MI$DDw~K#eVc0jb$Lvk^xl*5<0BqM zuL!M;ZQrgpeP|vGs@1io@&yf1si^Ifck9)-4*uL~i%rlRJt zEH;;qxFnddf*8lEE>` zc^7#A|4p$WiJc=p&3hYOh_!SnbFtK&^(y7qTXbtuO)+SpG2k!UlWrkz+YqqSPusge znWmn&KfOT1`Uq-wg{V;c&lkjqQ)zys3IbB}3-tVWI{h9MG2rhH1lqbxb>JgCSvHexqLPx%Dl7CZH#hzK(zkdrj(yqeQ33eu5g`brnb3RY zh{}{TktVIkssd#;waAS1O{Bym%3PPP?%Ou-ZCuAoC)~;Tdl?uMLk+U&nIjRbWDE-1 zqqYKBL_n^HY&UH$?fh@wy)AC^CUIlL$#8jen`#oJnbVOQE5}Uip>A>K!B&am0%-y6 z2rnb_yV6ETs=F=;2Wf=x!-1@>w@GXmmzA-h&bQDuht?p0){x5{#Nx_yo%tOA;7Q22 z+8_Ii&iBnR6Pt}^pB%Q_dY=aci@Ve75OvB20X z<-GynjJz+#_k9Xcx0(z`o@!9?L%=pt<(QY+g;~uU{er z^3LjJ4v!6^piM=gpdE<>4943LV<%gb52mM|#hJCNl0bw55Y#RQiKv8u7;%WiK<|1zx=`Jk{G0|d3J!M_=hh>FPicv*WLz%fS z9aB{!TDl$j8N**az&*e0KR)S3Ifj@T$QhHmB$3;n zd5<8x#pScsvwh-Rx%!Tz2B2O}-1efaSSU6xZhI1DTTmEMr~)|d76cCSn5w!^aU6q$ z#W_-g5lq9a(soK8iJ>|(Ff68Josqy#tHwmi*3PM)`8cRpT*gh#^NBMk;U~*}vMjRZ zsv414EbuOnBeIOaUWT7>#3aRJ;Iw{VYNag)`6yD|$6MJ9lUA^tfH_6`iK_~vl3$>+ z_wHj@z^78YU~t|1VcofEpy_d)0D@tk7Mj4^JLA`WE>N2jj6|{@x09-J4>B$!vB5Bw zP{*X1xan7W)fo}JBFG>;EWKscHX7)xHMsq=g z@i@tuQ%#JKePnZmjT)(Yi2A;9_$p4!X9U>OAH{uG}}O z8;H!CVdlA^cGot}P1gw2V5`|Luq{q!TT+u$C&S9${A-tRhtd+O!&w^nLSt)QCgyNi z?W#Eyg}xdch59kt?G6Wn{XKzNlKYYyuVwH#HN6_@AxDQ?umA;eP$!?_9(ljoPoi;loy9@*X*p5aRqZ0&8FmXM`dz5 zUTd47b}Ge=c0m1exUiK+zMt1C(GJzxhAPy{%aeYXahpybVjNSc*;wojj4IbAXX(mL z_4rV^r2Y>*x-5^)h`cWyRaMm%7Sy-ptmW@XjPGh|m3^Ae?QA0alkLqc-o9Z4L6{vv zL*yn_vTGC_*(-bwGq>0;jYqunXPE!i+E<4~-L!2ZEg&hK(#XNX0Gd+nOzRfIXBvp zUucMA^siDsrrw}Viq~456mqd<6t;|VNtJ#N>~7p|TgcNiDZdv?!6~my{t9Dxz;DY? zNI%A5(#!=jC68jvBFVGiH1ag}G*BmdizDNpW)S;^`&LcO!9jJgkqSukgPE)RxCJe4 zwYJKXMKJ0#!ye@SaF`?6LU~lq6f?UaS)TRSvWHvkTVPXHk;xq@t?_Fa(+kD0S2R`! zG*()^%Z6M|gNsA2aOpKn=57`iiA3SJ4ziX};gLg?)(+N?*4k2tdn_t%X*Cyn--ne9 z_4rY|&RiASc{GdqtmVT|g(XD(bN_y|{dw%Q@e{8N?9weuY9yDz@pm7llRg>wh>~*C zDFozC#OrR)ZYS~d)TuY1az$F(;MRbrb)IKrMx{<+5PUva@)cOhg9dsQuh_tx%C|=EXSi z>8fB$zXS^}ApVDJQ3A_omR!sono+(l7lU!kbW63(j;=N9o%UI=rb`)*^2$|WI)2pb zo=O%f9Y`LnGbW|vn#&N!`Rr|BrI0YscwHFV_pgLl8aS@)PUr1|cpyVuu3ar1H-oI^ zr-Nq39gakU#yl8y?df*~vCWsx#7UJe2JC1bb_N!Y2ruv)r~Syohv8UwtTq*Y3|WeE zs6Wd8k}|LIqcA&VkBRqF!+!8b#q z3&V%o0qnrqh$FU))sZXnS&s9KZhyF3WZwDCX|MiT1hL%n_U`mPtzvxCrxF=jk!G?| z8p_f-snA1KOTy3dwkuPf4oTt(g-NDO+Xy^%Q3H*B)i{c;!%oW&Y^E(g=bTIt1Y)Fb*E}d#qKBGxE zJDBtCqJlvb!u0PY4h!kc6j${3g!}hW7 zmDL?g6m_!a`lZv?M6~Gzh?dpa<=P7B?L)K|0pY$I-MgfQBE2S1C(k)#`dIG6GIjgm zqv&M))JKYn&$_&WQ$HG)5dr)5$#(Bt@Lvc^t{zoAQX*_4V07{?j8@Sjp|I;AP{@2= z`>-W%Z@+9l8rfayT;LgvpyeEt$dq(W8J(TQ3+?z$v#%>3YhJ95H|?~%Vu@Y%Lpmti z_1G#UmZDT%&m|nA)r$?&tR~RU4s4Nju!T`G<&q`0(mt55)4ovYXMBy69{HNDkD)+G zN|-NYVUfteM^gzovMQGH3sWz*UOBhQWx-*1CjAX4-Fd|<=DUVw1>cN|KvAj4lxyo9 zqQ~Q}zfmzHw!8@zC{<<^%vXNfq?*yvF5O)s_ZiS}+pH;)gG%#g^ITnHVz=C_R*>si z8Q0`nr&{%x`i*803$n-gdwb0uNrWa_r@i*^)3#q#w4GORO5=BR-JpHx2Zsg4MI$0g zy)vw%6{hEoM8tQ_CddYp-KE3Zwutp5U3Y%0;K`Pc zUa-F|&H_I$@X;T_F*jE|@IQ|JYCGyd;;9QfETn}e;%DrV#eDvj6|v#=&2YG(Kr%;D z-~7|pk6mXqCzLHeaVziL1NZuGFYN}(^z6~uMdH8hH?G9jNXgx$A$-=wcD+E7irB^^ z(079S8PS5BmyieREh=go7uEDLf+c)}YX5HPIf8c|L*fUIF}?WV4WZ??^Y5H)WqE~U zHwZbace1ag$|g<&+`T;mnhFSgXDo@NR$fZime_G&(b-deu7B56fcV+ov@Yd#0Wo(h ztaobL*L)em*<=^}tIA|iO*giW#1t16#N&3s{5eI9BS}mnL?ON8P*JCy;G&-nC}I$b zl67B^lF%{9N}v7y4o79-tIpHcIM8_OFu63SRhJ$IofoxPG5MZ(ypSK@diCA;5`LV$ z;2~B;C!*a0K{x)nBi)J*iAE1Yge@c4F%n|FOFw<#ul|MU3+W9}6G8aVD@2i3%>B}8 zC2iqZx3jjMdEZ*)H3ffK-F0MuSxTB_0jui_9Y%^y?*oafmxo9?2|VIQl3XG(Rr{9X zqM&6y(i54^;%$rLq|HVci~aP@M1JdVufl*o;mkx)$vnL|ed$JK`v_m2p>cbf8kKm8 zf`y7IEs4pdn|o&fX;NJ7m`c^8>li{oh?YIeEV?&ZwmD5Vba+B;LMS^yoBB1OjA-c~ zv`&DG#nTViY>XLW#0zrFAw+V<7~R+?tmS@cD=1H=Z}3fcbZ@C; zy{Pk+N7G#C`#5seaU|;&TN|mb8MSPke#IpIS~*^-#I2lF6VEh}n-tHw-Uc?Qn3|7x zepBJIoW4ipm$pWp6Brgd89!b%F;luzwc4o?n}i<)LJ6soi99c>zYou2&?NS{fs`=N zsFG8s(|2z1gJf^z?q(O?vV8e{H650oCSIMq94AC~yN=;>Fw@{`EeF^`bHk0Ax5EHP zRmAp{Ow}_;mDJJ=a|l7Pn96;Bn<)3>^5kU#x)30`#OpU1ZTxVJp zOrXk@(i9yPbrZRm6I)P1RO(tsGrdiX9~GJUIQdYD@B~x-Q$c*OOXzZkh{ZOjRYShu zedU~LS)$=wO|MJRYMH%nT6AW(8udDu*xUOWgL=#ZuNH-QlcVgLhs9SqC}{ zxqClXI&5cu*846T^-)SVDRjf!e&KnS%$TeblkGlxw~bh^zf~m{SyuUKNDYCkB@4p z=b8pwr?Px1NOyiB^Xu@ClJB|R;o@!CpZ%%uO~C=rijNNMnYR*p=)!weag`oxkbFPn ztvgQ@-m1cR=1DE4-Wj`t`akxWVNkK#IjgIPcPgSDCvat-nN0?~ugZJqqs+{ZpS?FY zBY0cD?%feP6bE^YzVfS%rB+@*wAn`5zKux1#Bok@H#~%99Nj|?!G)T&C_;;?7dXooO0LImJ*gd#$4$_ zmL-13!=N<{C$)5|CjC=4C7zM&!*_=~gjyT)4WlNX*5nzQLL{A#!$3H5GXEr5QgR44mo+Mt&VlD1G-q%v1MMHRM7@hVG}%n^Mqa53m_zUV=7p%$z<9@G2M%>4&WO$CDE5=`S*j^h@BUA)W5w-&H?-nEJh zr7Bh;_Bh~-*AC6y^_=vU1s8bLK9Mr-Pw<5_BcED7f3D3fDak-U^}_$KTaoAHO_|I$ zlwT9hJsU0XRD&s@eAfyM&4+-a9jg?k211X)=0*468jr|Ai?8!LwT(|{cSKg19_8Fq9rZXfh-vZAL#(lZI&Zd-{Sup_Z2j`9 z_=$#@ki26i*eb=2Ge`y4PhqVo7x3s{Df}$UIy=#0xK8kyhyUfs6Uu4!ho(qLi{VLp_-_JN!8{fSpDY`mq($Hlh5KC-G zCcYV9iqEslW5>m@O>4{YaO~cU|Kc`c#5O2l&KoXeyDjJ?y}2ZyO6crBS(`96k5$r4 zq;;d=g@!wgh%xYRjM#3|o=MU8+CED~Gm{pHnzS#zl7H;hak($W|!)+mC$ zv;)rpODSm8hO49k&N;EoeA4YkmcD$?+Y>QfHtjDL8CVvYclHkB$ zCy|@4;}2R~;`8d6%p?RRz5Y>2_Y4?H#WFUxwO@UF=)-x=?w@5V{c)9b8d8#|f(06z zzxf47An(Y3m;t4!VEr!q8FM))U+kFz!)j ztO@g-Hs7IXW4m_5nGt}}x)Y=Hff3}>t)C5yb-^S|zHUb9r_LrV6|~&7#u!@o_gM;| zEx5@&tuZTK^r$S1=49*}bw+ef&K{kcg&BHzDy|{)gMdIj#(XG+PwW_t+=z) zrli9p_2k;{4}#Xk@5te^jRdSNY4>xY0oK5Kq*a-<_1hN=?&}xC!z&k9HK@1nrd0i( zeeL;uf5Ckn>3n&v8~x(*1rR6wB*7q~=GrMIswp4~$2>N;)_G1SH8+c~gw1V8N+?Mj z8Sz7XTi5q3i`2f2uW)L?uF&R%_&MP(oC|-SriMAgZJ}f8GfBLfxJHz}hVn<#_`}uc-{0Q(t#O|%eZpgE5Mk}Z=p_n zSlq&7nTZ1^R>WRK6l=TQ6fG4H^bEh$^RMqyTp9l?`=(t1txq^T)!fUvW7TpF+_eDF zN6?)I)on=vO?Lv)ZDb5<$%Cx=+Cephb$nPq=|yVR;rl8aQ{Bof4)x^ys?EWQH9C3v zh3^u0*3A_^7$}Td4)OETljFt?G~c!-fKeXtUb7d5sRVO5_SL`$9VmdG7YJ+iV%;%e za>1WFoM7#XrD-=79rZ$@B}w*_X(HOhLOL7-rj`A6UoIzRyl|=US=REPSQrR|LvBTB zb$JFB;>*WIYtt0T!2=t41g?(;-e;4zp@(&NcaG*dQURlbV>_?oeRx4j@-VKWZ|ZZN3wzjbA{< zBsUiP=EbR!as{~O>FSY@gLEO}= z-7k*wv1&0eWe2;0&hdjt!&w0St8BpCD4LUF|C2FEL+fmf3GaYNxw!|gb{)^kCv#(G zt_7Ce$}0JS$U+7=^#hs>Jj<2JJAX%a=?dE4g>reG*KFF1}JWY zdBb;wJLBVpxl~&3RygJ=uc>f^D7 z-ASy#o3l>uh3Km*OC<{R#cKEZp$-P>KZ>fqYRgxE&tu-O(G%Bxb|k5vGEQ9L{6Q~S z38@vR7SQe@U!SVlxr;c=xHufp5kb~klQ8zbtr`(ORneIgdlC0dG-aZ{0_%ED%As#B zYc}IuB;(!HioKzEq<)}mlI!#AvxWiqr8++MSHvNB+JLk+jT|euo1rdTyxQ7bC%OJFnN{jDf_5? zWnT|TPk>;+6ME1uDP z2ka>}N+zMg39JX)@j5iqBXAJK(SracoSGJ{>M&P=o^Lm;!@IWVy`OooG~mfp2v`$^ zsU(wXsVm4RU=`dJFjcoWoCTJvZ_%5UJrO$bu2O6?v9SWzq)g!v_zw;*6s3y!zfy=mIEw!Jf0aUn zpyVL`RSFS)$r=4W_`8=fk(a>&frT$adHE~+QWo+z282WZMt^G|{zg&s;s4Y`DN+8Z z2^5B+)EECkFR8wNYJ&d8{?hydqG%g`_xV@zO9j$DnexEc(%hLq=$^Hi^CeFk)sgBS z5m40Qa#*SaD5c2Xk3S{QpAt&q^AZIADS`i#P*m?r5c)^N@wY^$D#35LOw~)jqGEv( zl>~zRAq?s6WNtwKU_r@hqO>Ugd1_OXs#sUxq3k#!TU~~)$yxJBBfkF{i+k#-QtMdS$ z)K1aHjM6(r#}H`o1w!C3G#`Lb(y&+Uf?)`B3=Txc5O6f#Ljka>b3>&Xx(x^%-3A1K zZUYMV7aPJbG@n9Y2sHme;lO{vKxh~Y0JxfeKqwe3PXVZKpxK4Np#Orw(J|CEc*V~^ zC=@-ua5&;>Jpc;&7Yu}kAyBfjXg1)mtGNLL2&3ga3PblZ9F@^m`vZUgXfX$X(QUv0 zFtmE8?GEd&TbiyP{03^bpjmgUuY5C9b21{{R8H$i~t z7!VEvU(F#X7~OxU;i0W9C>Q~`>QhuLz}2+?2LObx&KC*+qOBuT`a!SeIO-GwU&Y`6 zFyv~CP#BsIP-h<6`aogASLchu(AGH$`{($cIvJxhnVo)Xj;mRFnxllYQR3rIo;*d} k&vJQK3;k9k|8sEvzAMDo>FMuN84kGAg680my)Q@bKLL -MM: What is the intellectual property side of neural networks? -MS: The weights and the model constitute the intellectual property. By keeping the model outside of the primary source programming language and outside of the main wasm program state, intellectual property is better protected. -MS: We’re working closely with WebNN proposal -MS: We expect many different hardware architectures will implement backend support. -MS: Initial POC would target a CPU backend but future devices (GPU, FPGA, TPU) could also be supported. -MM: Intellectual property is a legal term; is there any attempt at legal protection of these weights? -MS: It’s hard to protect a model across a development and deployment workflow. Model authors want to ensure that their specific weights are protected. What this proposal says is, the model can be opaque. -MM: So you’re not talking about legal protection, just about hiding the information? -MS: Yes, it’s mainly about confidentiality of the model. -MM: So since the questions that wasm would ask of the model through the API would expose information about the model, has there been any analysis? -MS: If you use a programmatic model to define weights it’s a lot harder to protect. -AB: -AB: Showed the proposal: https://github.com/WebAssembly/WASI/issues/272 -DG: Why explicitly expose the target instead of making it an implementation detail -AB/MS: Current thought is that it gives the developer more options. -MM: Could you refactor this to move the target enum into init_execution_context? -What happens if you ask for a target architecture and it isn’t available? -JB: Would it help to say that the target parameter is a hint? - -AB: I agree; 99% of the time, what you want is just “pick the best one for me” -Open question: Web-nn exposes this target parameter; why do that do it? -AB: I’ll summarize this discussion in an issue. -AB: Let’s look at how we represent tensors next. -AB: Is there a better way to represent multi-dimensional arrays? - -PH: You need a dynamic number of dimensions, and it’s hard to do that, especially with witx in its current form. -DG: Does this definition give everything the implementer need to be efficient .. to change to the format needed? Agree with Pat multi-dimensional support is a hard problem right now. -AB: We’ll learn more about the implementation concerns as we start prototyping this. -AB: How do we specify how to include dependencies? -DG/LC: The concept of optional imports may be useful here. -PH: Also have a PR for profiles that is a way to specify in witx dependencies. -DG: Have met the requirements for phase 1. Can vote. -LC: What happens if there is a fail? -AB: Have a mechanism to return error. -Vote: WASI-nn advance to phase 1 -SF: 7 -F: 5 -N: 2 - -Vote succeeds. diff --git a/proposals/clocks/meetings/2020/WASI-06-04.md b/proposals/clocks/meetings/2020/WASI-06-04.md deleted file mode 100644 index 6c7e2d7ee..000000000 --- a/proposals/clocks/meetings/2020/WASI-06-04.md +++ /dev/null @@ -1,43 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the June 4 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: June 4, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. wasi-sdk release 11 - 1. https://github.com/WebAssembly/wasi-sdk/issues/139 - 1. Commands and Reactors: - 1. Heads-up: -mexec-model=reactor on clang trunk, use with wasi-libc trunk - 1. Update on repositories: wasi-nn, wasi-http-proxy, etc. - 1. WASI-http-proxy next steps - 1. https://github.com/WebAssembly/WASI-http-proxy - 1. Feedback given earlier is that it'd be good to look - at splitting out some of the parts. How can we help? - 1. Multi-call commands (Dan) - 1. https://github.com/WebAssembly/WASI/pull/281 - 1. Async - 1. https://github.com/WebAssembly/WASI/issues/276 - -## Meeting Notes diff --git a/proposals/clocks/meetings/2020/WASI-07-02.md b/proposals/clocks/meetings/2020/WASI-07-02.md deleted file mode 100644 index cc9ac5576..000000000 --- a/proposals/clocks/meetings/2020/WASI-07-02.md +++ /dev/null @@ -1,41 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the July 2 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: July 2, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. Update on action items. - 1. proxy-wasm repo - 1. Discussion topic: WASI and POSIX - 1. https://github.com/WebAssembly/WASI/issues/292 - 1. What should we do on `lseek` past the end of a file? - 1. Should POSIX be a normative reference for the filesystem etc. APIs? - 1. Documentation philosophy. - 1. Heads-up: Module-linking-based dynamic linking: - 1. https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Example-SharedEverythingDynamicLinking.md - 1. Tooling for new-style commands: - 1. https://reviews.llvm.org/D81689 - -## Meeting Notes diff --git a/proposals/clocks/meetings/2020/WASI-07-16.md b/proposals/clocks/meetings/2020/WASI-07-16.md deleted file mode 100644 index f4ba68088..000000000 --- a/proposals/clocks/meetings/2020/WASI-07-16.md +++ /dev/null @@ -1,41 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the July 16 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: July 16, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. WASI testsuite activities - 1. https://github.com/WebAssembly/WASI/issues/9 - 1. What kinds of tests should be in an official testsuite? - 1. Where should we collect them? - 1. Discussion topic: Threads - 1. https://github.com/WebAssembly/threads/issues/8 - 1. https://github.com/WebAssembly/threads/issues/95 - 1. https://github.com/WebAssembly/threads/issues/138 - 1. Discussion topic: `fd_seek` past the end of a file on Windows - 1. https://github.com/WebAssembly/WASI/issues/292 - 1. Discussion topic: Symbolic links and Windows - -## Meeting Notes diff --git a/proposals/clocks/meetings/2020/WASI-07-30.md b/proposals/clocks/meetings/2020/WASI-07-30.md deleted file mode 100644 index 1a164d624..000000000 --- a/proposals/clocks/meetings/2020/WASI-07-30.md +++ /dev/null @@ -1,36 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the July 30 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: July 30, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. Documentation for WASI APIs - 1. https://github.com/WebAssembly/WASI/issues/292 - 1. WASI committee processes - 1. Proposal repos - 1. Further harmonizing the spec process with the core CG - 1. What work needs to be done, and who wants to do it? - -## Meeting Notes diff --git a/proposals/clocks/meetings/2020/WASI-08-27.md b/proposals/clocks/meetings/2020/WASI-08-27.md deleted file mode 100644 index e5cbbef58..000000000 --- a/proposals/clocks/meetings/2020/WASI-08-27.md +++ /dev/null @@ -1,42 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the Aug 27 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: August 27, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. WASI Status - 1. Update from Dan - 1. WASI moving forward - 1. Sockets API - 1. https://github.com/WebAssembly/WASI/pull/312 - 1. API discussion - 1. Process discussion - 1. Testsuite - 1. https://github.com/WebAssembly/WASI/issues/9 - 1. https://github.com/khronosproject/wasi-test/ - 1. Should we work to make this an official testsuite? - 1. Where should it live? - -## Meeting Notes diff --git a/proposals/clocks/meetings/2020/WASI-09-10.md b/proposals/clocks/meetings/2020/WASI-09-10.md deleted file mode 100644 index feacffd1e..000000000 --- a/proposals/clocks/meetings/2020/WASI-09-10.md +++ /dev/null @@ -1,33 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the September 10 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: September 10, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. Sockets API - 1. https://github.com/WebAssembly/WASI/pull/312 - 1. API discussion - -## Meeting Notes diff --git a/proposals/clocks/meetings/2020/WASI-09-24.md b/proposals/clocks/meetings/2020/WASI-09-24.md deleted file mode 100644 index dd3127e8f..000000000 --- a/proposals/clocks/meetings/2020/WASI-09-24.md +++ /dev/null @@ -1,30 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the September 24 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: September 24, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Add items here! - -## Meeting Notes diff --git a/proposals/clocks/meetings/2020/WASI-10-08.md b/proposals/clocks/meetings/2020/WASI-10-08.md deleted file mode 100644 index 78d943918..000000000 --- a/proposals/clocks/meetings/2020/WASI-10-08.md +++ /dev/null @@ -1,42 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the October 8 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: October 8, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Add items here! - 1. wasi-sdk update waiting for LLVM 11.0 release - 1. https://llvm.org/ - 1. Interface Types update: - 1. https://github.com/WebAssembly/interface-types/pull/122 - 1. WASI is being mentioned a lot in the GC repo: - 1. eg. https://github.com/WebAssembly/gc/issues/143 - 1. WASI testsuite - 1. https://github.com/WebAssembly/WASI/issues/9 - 1. What do we want to build towards? - 1. WASI sockets - 1. https://github.com/WebAssembly/WASI/pull/312 - 1. Merge soon, and iterate? - -## Meeting Notes diff --git a/proposals/clocks/meetings/2020/WASI-10-22.md b/proposals/clocks/meetings/2020/WASI-10-22.md deleted file mode 100644 index eb7d737de..000000000 --- a/proposals/clocks/meetings/2020/WASI-10-22.md +++ /dev/null @@ -1,211 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the October 22 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: October 22, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -**Note**: This meeting will be hosted by the subgroup co-chair Sam Clegg (@sbc100) - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Review of action items from previous meeting(s). -1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). -1. Character encodings - 1. A presentation on: Summarizing several current discussions around character encodings - 1. For details, see the individual issues: - 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 "case-sensitivity of filesystem apis" - 1. https://github.com/WebAssembly/WASI/issues/8 "Specify UTF-8 as the character set" - 1. https://github.com/WebAssembly/gc/issues/145 "GC story for strings?" -1. Discuss about how to move forward with a [WASI Logo](https://github.com/WebAssembly/WASI/issues/3). Proposals: - 1. We would never like to change the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png). - 2. We would like to keep the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png) for now, and change it in the future when WASI is more mature. - TODO: Ask the risks of changing the logo short-term and see if there is any way to address them. - TODO: define what "mature" means (objectively) and how the process will be then - 3. We would like to start researching on a new logo now. - TODO: define how the process will be - 4. Other ideas? - -## Meeting Notes - -### Attendees - -- Sam Clegg -- Thomas Lively -- Martin Duke -- Syrus Akbary -- Pat Hickey -- Tanya Crenshaw -- Alon Zakai -- Andrew Brown -- Mingqiu Sun -- Alex Crichton -- Dan Gohman -- Steven Dabell -- David Piepgrass -- Johnnie Birch -- Martin Duke -- Yong -- Sergey Rubanov -- Arun Purushan - -### Find volunteers for note taking - -TL volunteers - -### Adoption of the agenda - -PH seconds - -### Notes - -#### Review of action items from prior meeting - -DG: Next time ??? is in the meeting we will check up on ??? - -#### Vote to move wasi-nn to stage 2 - -- Phases: https://github.com/WebAssembly/WASI/blob/master/docs/Process.md - -AB: We proposed wasi-nn a while back. Have a witx spec. I’ve been creating a POC -to see if this works. When looking at docs, realized we are essentially in stage -2. Moving to phase 2 would reflect reality. Asking for feedback on API. - -SC: English spec text requirement doesn’t apply? - -DG: Right, we only have witx. - -AB: Also generates md, which might count. - -SC: Implementation and test writing starts in stage 2. Probably don’t need a -full vote. Does anyone have any comments or objections? - -PH: I followed it and I’m happy with how it looks. - -SC: Unanimous consent achieved to move to stage 2. - -AB: I will submit a PR updating which table it is in. - -#### Character encodings - -DG: Several threads about encodings going on. Want feedback about direction. - - TODO: Add link to slides - -SC: Won’t the C program truncate on strcpy? - -DG: Yes, but then you’ll get a file not found error. - -SC: Where does this ARF encoding come from? - -DG: I invented this after a lot of tries. - -SA: Is this for filenames only or also for contents? - -DG: File names, env vars, commandline args, but not file contents. - -SC: Anywhere a known string crosses the WASI boundary? - -DG: There might be other places. Where invalid strings should be roundtrippable without trapping. Some APIs trap, others wouldn’t. Some tools will want different things as well. - -TL: wasi seems like it may be the wrong layer to solve encoding problems since it is not related to capability-based security. Can we leave this to an optional userspace virtualization layer? - -DG: That seems reasonable since virtualization is an option. - -PH: When IT describe interfaces, it would be great to use strings for these types, and IT guarantees unicode. ARF lets us use the IT string type. - -AC: In windows, filenames are lists of 16-bit values. How do we go from 16-bit to 8-bit strings? We need an extra layer. - -DG: We can extend ARF to handle Windows character space as well. ARF would be a little different on Windows and Linux. - -SC: But there are filesystem out there with different filename encodings. e.g. Shift-JIS in asia. - -DG: wasi engines can translate host character encodings into unicode. - -AC: What would the users look like? Not raw API users, but e.g. rust stdlib users. Would the entire ARF string be stored in Rust’s Path object? - -DG: Two cases: in do nothing case, use all the standard APIs. In ARF encoding case, get string as ARF encoded OSString or similar. WASI will either detect ARF string and not validate or would get file not found. There is a Rust library that can take an OSString and be ARF-aware to do things. - -SC: But most programs won’t need to do this because these files don’t exist in practice. - -AC: Not sure about this. Rust stdlib would want to do the proper decoding to show better error messages. It seems only extremely low-level C developers would be in the do-nothing case. - -SC: Do-nothing only prints first half, right? - -AC: Only in C. When there is a pointer and length, the second half gets printed too. - -DG: Good point. Don’t have an answer for that. - -SC: Curious about prior art. - -DG: Perl 6 has UTF8-C8. Uses highest private use code point as an escape char. - -AC: Using nul character seems reasonable given that native filesystems already disallow it. - -DG: Python uses lone surrogates. Not great because you end up with invalid unicode. - -SC: To be clear, status quo is passing through raw bytes from OS with no validation? - -DG: Some implementations already have some validation and different behavior. - -#### Discuss about how to move forward with a WASI logo - -Slides: -https://speakerdeck.com/syrusakbary/wasi-logo-proposal - -WASI issue: -https://github.com/WebAssembly/WASI/issues/3#issuecomment-714740192 - -SA: I’m the founder and CEO of Wasmer, want to see what the risks are about -moving forward with a different logo and what are the issues with the current -logo. - -SA: Show we replace the logo at some point? - -TL: Agree with identified issues. - -SC: Another options would be to fix the problems in the current logo. - -TS: It’s clear that the current logo is a draft. I actually like this property -because WASI itself is also in a draft stage. For example, the proposed logo -uses an office CLI metaphor, which is not what WASI has shaped up to be about. - -SA: One idea would be to replace the current logo with a short term logo that -fixes some of the issues and is more accessible. Then separately it would be -good to organize a contest for a new WASI logo. Back to slides… - -TS: It would be good to mention reasons on the issue so others can weigh in. - -SA: Will follow up on the issue. - -TL: What if we just fix all issues except for wasted space in the current logo? - -SA: That would be an improvement, but it would be good to fix the wasted space as well. - -SC: Any objections to incremental fix? - -PH: Don’t want to spend any more time on this. - -SA: I can handle this and release the results with a copyleft license to resolve any other issues. - -TS: I think we still need to check what the situation is with IP rights just in case. - -SA: I understand those concerns and want to make this as easy as possible. diff --git a/proposals/clocks/meetings/2020/WASI-11-19.md b/proposals/clocks/meetings/2020/WASI-11-19.md deleted file mode 100644 index c9d6a819b..000000000 --- a/proposals/clocks/meetings/2020/WASI-11-19.md +++ /dev/null @@ -1,153 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the November 19 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: November 19, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Review of action items from previous meeting(s). - 1. Ralph Squillance to write up a draft on "WASI experimental" or - versioning for WASI API experimentation. -1. Removing support for `seekdir`/`telldir` from wasi-filesystem - 1. https://github.com/WebAssembly/wasi-filesystem/issues/7 -1. Filesystem Case Insensitivity - 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 - 1. https://github.com/nicowilliams/ietf-fs-i18n - -## Meeting Notes - -### Attendees -- Peter Huene -- Sam Clegg (SC) -- Lin Clark (LC) -- Andrew Brown -- Dan Gohman (DG) -- Sergey Rubanov -- Syrus Akbary (SA) -- Matt Fisher -- Eric Rosenberg -- Ralph Squillace (RS) -- Till Schneidereit (TS) -- Harun Oz -- Pat Hickey (PH) - -### Action Items from Last Week -RS: had conversation with Pat and Dan about how people are testing out experimental proposals. Pretty obv that we wanted to use these experiments for inputs. At same time, second issue was wanting to be very clear that none of the experiments were destined to the spec - -Wanted people to be able to play with sockets in Krustlet. Dan proposed creating an experimental namespace. Ralph will now begin tackling the doc. Will talk with Fastly about how they are handling exp. - -DG: need standard convention for naming - -SC: Are you talking about system level imports? - -DG: We have wasi_ naming convention. Should be a naming convention for things not in snapshot yet - -RS: That makes sense. Explicitly not destined to be migrated. Signal that these are things to be used as ways of stimulating thought. Kind of a firewall between these and what’s going into the spec. - -DG: One additional thing—some prior art wrt web standards e.g. vendor prefixes. We can probably avoid - -SC: How would we avoid. By not shipping prod VMs with them enabled? - -DG: Yes, or behind flags - -TS: Situation might become slightly different once module linking and ability to virtualize comes in. Then you could say you don’t need to ship as long as you provide a shim implemented in user space - -SC: presumably not the module name - -PH: unfortunate that there’s only one name - -DG: Module linking has concept of nested modules. Might be useful - -PH: That’s used for definitions but not for imports. - -SC: You can chain imports - -TS: IIRC you have to re-export - -DG: typically you do, but … if we don’t have this, then mangling - -PH: we need this before module linking lands in any toolchain. - -From chat: -wasi_experimental_tests? -wasi_experimental_temp? -From Pat Hickey to Everyone: 12:16 PM -wasi_experimental_ for a mangling scheme - -**ACTION ITEM: Ralph will compile doc** - -### Removing support for seekdir/telldir from wasi-filesystem - -DG: from days when OSs used flat lists. Now they are BTrees. These have become awkward abstractions. - -DG: want to remove from WASI altogether. Can’t do a 64 bit seekdir. In order to satisfy POSIX, we’d need to do some complicated indirection. Theoretically possible, but think better to remove altogether. - -SC: Proposal is just to remove, not emulate in user space? - -DG: I don’t think it’s worth it unless use case - -SA: Don’t have context, but what do you think wouldn’t be possible? - -DG: ls will work. This is why I’m asking whether anyone has heard of someone using this. Scan through, then restart from beginning, and then keep going is pretty rare. This originated when it was hard to keep file in memory at same time - -RS: What’s request? Could potentially search GitHub. There are tools - -DG: Found a million hits in code, a lot are libc code - -SC: Yeah, we’ll need to skip headers and impls - -TS: Have experience from TC39. People have tried to use as code search, but there’s quite a lot more dark matter that’s not in public repos, and also test suites are copied all over place and not ways to exclude. Perhaps possible to do regex to exclude - -RS: Both MS and GitHub have internal tools for this. GH is strongly motivated to make this work. If we can write a user story that’s in the sweet spot, I will see what can be done as a feature, either privately or as a preview test, or ultimately as a public feature - -DG: That feature would be really useful for other questions too - -RS: I do need a user story to pursue in an aggressive way, but I think they actively want user stories. - -DG: WASI libc is already trying to guess what you’ll need. - -RS: Side issue—feature set is that we want to know what the community is using. - -DG: Roughly the plan for removal is to remove from libc. Second step is to remove from WASI itself, removing parameter and introducing rewind call - -**ACTION ITEM: Ralph will use internal tool to search for use** -**(possible) ACTION ITEM: Put together user story for feature that would allow WASI SG to search for usage of other APIs** - -### Filesystem Case Insensitivity - -DG: GitHub repos and offline chatting. ONe question, what is the goal of the ___ API Fully deterministic? Will behave same way across all platforms. - -DG: People want to access existing files that already have their own restrictions. Hard to abstract away. If we can assume WASI runtime owns filesystem, could do a lot, but if we assume you have your own files, we have to pass it on to applications. Somewhat unfortunate, but after a lot of discussion think we’re going non-deterministic. Best we can do is good debugging tools. Those wouldn’t be part of the spec, just side debugging tools. Disappointing from the Wasm perspective, where we try to be deterministic. Not within our power at the WASI level to choose one side - -DG: Also want to mention, link in meeting notes that will hopefully turn into an IETF proposal that will define portable semantics - -### Additional Questions - -SA: One quick question. What do you want me to do with the logo - -DG: Researching IP rules - -LC: I can help with this and serve as point of contact - -SA: Lmk if you need changes to the PR - diff --git a/proposals/clocks/meetings/2020/WASI-12-03.md b/proposals/clocks/meetings/2020/WASI-12-03.md deleted file mode 100644 index 7d9b521b5..000000000 --- a/proposals/clocks/meetings/2020/WASI-12-03.md +++ /dev/null @@ -1,130 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the December 3 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: December 3, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Review of action items from previous meeting(s). - 1. Ralph Squillace to write up a draft on "WASI experimental" or versioning for WASI API experimentation. -1. Proposals and discussions - 1. Discussion topic: Repository organization to enable independent proposal repos ([#360](https://github.com/WebAssembly/WASI/issues/360)) - 1. Discussion topic: Using releases to make the repo citable ([#356](https://github.com/WebAssembly/WASI/issues/356)) - -## Meeting Notes - -### Attendees -Lin Clark (LC) -Pat Hickey (PAH) -Martin Duke (MD) -Andrew Brown (AB) -Dan Gohman (DG) -Till Schneidereit (TS) -Matt Fisher (MF) -Mingqiu Sun (MS) -Mark McCaskey (MM) -Johnnie Birch (JB) -Ralph Squillace (RS) -Peter Huene (PEH) -Sam Clegg (SBC) - -LC: Action items from last meeting - Ralph is not on the call, so we’ll skip over follow ups with him - -LC: Dan put up a PR yesterday about repo organization to enable independent proposal repos - -DG: In a CG there's the core spec repo, and proposals that add new features are fork repos of the spec. When a proposal gets to stage 5 (spec), the proposal gets merged into the central repository. We want WASI to have a parallel structure to this. - -DG: One thing we want to move away from is a single snapshot path. So when we make a snapshot its url remains stable (we don't put it into old). What this enables is one snapshot referring to another. We want documentation to describe the differences between snapshots and eventually tools will too. Stable URLs are a good first step towards that - -DG: Another feature is moving away from ephemeral. That was envisioned as the place where we do development, where PRs target, but we want to move all development into proposal repositories. The main proposal repo will no longer have an ephemeral directory. -DG: A final piece of this is a place in the repo for a script, similar to core CG’s test suite repository, that pulls in the proposals from all the places they live, and creates the snapshot. All of the proposals will be separate modules in the snapshot. - -AB: When do proposal repos get added to the script so they land in the snapshot? - -DG: As soon as you create them you can create a PR to the script. One rule we could have is that if there's a merge conflict or other obvious errors we just skip over merging a proposal for now. But we want a snapshot to contain all proposals. - -DG: In the root spec repo, there will be a `standards/` directory, it's empty for now because we aren't at stage 5 yet. But out in the proposals they can put whatever they want to land in the spec repo snapshot in their `standards/` directory. This convention is that we don't have to wait for everyone to sync up - -TS: Will it make sense to say “only show me sections for proposals for stage of my choice in the rendered output”. - -DG: We don't have that information yet but that's a good idea. Maybe a magic doc comment in the witx files. Or we can iterate - -TS: There has to be some index about pulling in the proposals, and that can contain the metadata about what stage various proposals are at. - -AB: This is a better system than we have today - -DG: We are learning from our mistakes - -TS: We need to iterate on the infrastructure of the spec in a central place, and make use of it without copying code over, are you envisioning the proposals will pull in the (upstream) spec repo? And we iterate on that outside of the snapshot mechanism? - -DG: Some proposals need to make change to witx. They all have a witx crate in them to make changes to how witx works. You can experiment there and make a non-snapshot PR into the spec repo to merge bigger changes in. You can keep - -PAH: For some changes to WITX, it would make sense to do in the core spec repo and then proposals merge or rebase - -DG: That is something that becomes more awkward with this setup. The question is would you also modify existing snapshots to use the new syntax? Because if not, then snapshots don’t work with new tooling. - - -PAH: let’s set that discussion aside. We have been updating to keep semantics but use new syntax. The hard part of this is that if we have to make a breaking change to WITX that could affect our ability to merge in proposals that haven’t taken in the breaking changes yet. Is it the responsibility of WITX maintainer to un-break all the proposals? - -DG: Initial way that falls out is that the script that merges will run the new version of the tool over that. If it doesn’t run, we leave out of the snapshot - -PAH: That sounds fine to me. What I’m thinking now is the CGs waterfall, continuous integration of tip of tree which makes it possible to find before releases. Could run it on a cron job and does red/green for various proposals - -DG: If someone wants to set up a waterfall, that would be good. Might be more than we need right now. - -PAH: If you have to update both your WITX files and ref implementation on downstream tooling, might not be able you - -DG: You can do it on your local as a champion - -PAH: This also makes me think about the value of the snapshot version being date based. You could have an id and a date. E.g. nightly-YYYY-MM-DD. That could give people ability to find breakages before time for snapshot. I think the biggest thing I’ve messed up in WASI and WITX is not having tooling that makes ephemeral work. Want the new process to be tip of tree always working. I could be wrong on that, but that’s my personal feeling. - -DG: Ephemeral in main repo goes away. If they want to dev in standards dir, they can. If they have their own ephemeral, then it’s on them to keep it working. - -TS: It seems to me that there’s value in cross-proposal CI so that you don’t find out when cutting a snapshot more work to do. I could see value in /standards and /in-progress, where we maybe have GitHub action that tries to do an integration build - -PAH: I think I agree. I would love it if the CI action could be run in any of the fork repos so that they could alert on their own breakage. - -DG: If we put that in the main repo, then they’ll all have a fork of it - -PAH: They’d be able to id if any contrib to main repo is breaking. That’s an implementation detail. - -TS: I feel like it would also be kind of nice to have a snapshot that’s always up to date for what it looks like today with all proposals combined. - -LC: Are there more questions? (no). Dan what are the next steps? -DG: I can make a PR into the spec repo and proposal repos to adopt the new organization. The first step is to reorganize the spec repo and get the scripts setup, then reach out to the proposal champions to integrate up there. - -LC: You can put that list of work into the issue and we can distribute that work out. - -LC: Ralph has joined, do you want to talk about experimental stuff at all or next time? - -RS: I need more time before I present that. - -LC: Next thing on the agenda, we need to talk about releases. Someone is asking us to make citation easier using a tool called zenodo. For that to work we need to cut (GitHub) releases. Should we do this and when should we do them? It seems like we should do them when we do a snapshot. Does anyone have opinions on this? - -JB: Question about zenodo: what does that tool do? - -LC: It (??) DOI’s. I don’t know exactly why a DOI is important for a bibliography but its recommended over a URL when possible by the (APA?). The tool archives the data associated with the DOI, I believe. - -LC: Then we’ll start cutting releases with snapshots. We can do one release now to capture the current snapshot. I’ll work with the wasm cg chair to get zenodo configured for the repo. - -LC: Any other topics? (None) diff --git a/proposals/clocks/meetings/2021/WASI-01-14.md b/proposals/clocks/meetings/2021/WASI-01-14.md deleted file mode 100644 index 9ee3e0be7..000000000 --- a/proposals/clocks/meetings/2021/WASI-01-14.md +++ /dev/null @@ -1,75 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the January 14 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: January 14, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcement - 1. Pat will be changing branch name from `master` to `main` -1. Review of action items from previous meeting(s). - 1. Lin update on repository organization progress -1. Proposals and discussions - 1. Discussion: Testing guidelines for proposals - 1. _Sumbit a PR to add your agenda item here_ - -## Meeting Notes -### Attendees -Lin Clark -Josh Dolitsky -Dan Gohman -Pat Hickey -Sam Clegg -Casper Beyer -Mark McCaskey -Johnnie Birch -Andrew Brown -Yong He -Peter Engelbert -Peter Huene -Martin Duke -Till Schneidereit -Bogus Wolf - -For people taking notes, just type names; we’ll replace them with abbreviations before posting them publicly. - -**Pat Hickey:** Github is now rolling out features to allow for renaming git branches from “master” to “main”, including blob url redirection. It’s mostly automatic, but it does require people to do some changes locally to update. We’ll put the steps in the WASI github issue tracking this. - -Main topic: Testing. - -**Lin Clark:** - -The context here is WASI modularization -- breaking up the core WASI module into separate modules. - -Pat and Dan are working on a new witx mechanism for expressing dependencies between witx files, allowing modules to depend on each other. - -The main WASI repo will be the source of truth for stage-5 (standardized) proposals. - -Tests should include both the source, in high-level languages, and compiled wasm binaries. - -Things we still need to build: -A test runner -Tests. We’ll start with some tests from Wasmtime, and everyone can add tests. - - - diff --git a/proposals/clocks/meetings/2021/WASI-01-28.md b/proposals/clocks/meetings/2021/WASI-01-28.md deleted file mode 100644 index cab4dbd21..000000000 --- a/proposals/clocks/meetings/2021/WASI-01-28.md +++ /dev/null @@ -1,206 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the January 28 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: January 28, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. Lin Clark on WASI modularization milestone -1. Proposals and discussions - 1. Presentation: Update from Luke Wagner on handles and resources in interface types - 1. _Sumbit a PR to add your agenda item here_ - -## Meeting Notes -### Attendees -- Martin Duke, F5 -- Sam Clegg -- Dan Gohman -- Luke Wagner -- Mark McCaskey -- Lin Clark -- Dave Protasowski -- Alex Crichton -- Andrew Brown -- Mingqiu Sun -- Till Schneidereit -- Pat Hickey -- Josh Dolitsky -- Matt Butcher -- Ralph Squillace - -### Announcements -**Lin Clark:** We now have a [milestone for WASI modularization](https://github.com/WebAssembly/WASI/milestone/1). Will be using milestones more in the future. - -### Proposals and discussions -#### Presentation: Update from Luke Wagner on handles and resources in interface types [(Slides)](https://docs.google.com/presentation/d/1ikwS2Ps-KLXFofuS5VAs6Bn14q4LBEaxMjPfLj61UZE) - -**Luke Wagner:** Handles and resources. Have been working on this for a while with a number of y’all -Give background, motivating problems, and proposed solution -Not at all final, still working on a PR. Your feedback is most welcome - -IT gives WASI a bunch of value types -In addition to core basic types, a bunch of abbreviations -Don’t want to have to add core types -This lets us take a WASI function and use a bunch of high level types - -Plan of record for a while has been abstract types for file descriptors -Type imports builds on reference types -Reference types are unforgeable, better than ints - -How does this get virtualized? -Virtualization is a core value of WASI. You can implement with another WASI module -For this, we use module linking proposal - -What does it look like to write that virtualized WASI? (walk through) -Packed the file index into the reference, that’s efficient - -Type imports and exports are transparent by default -This is forgeable. That’s why that was take one - -Type imports has a private type definition -I would take abstract type and make it a private type definition -Private.get and private.new only works inside module that defined the type definition -These private types have to be boxed. -Actually no worse than the native implementation to have one level of indirection - -Two remaining problem areas: resource lifetimes and dynamic casting - -Resource lifetimes -How do resources get released? -Could reference count. -Problematic for a variety of reasons. -Not virtualizable. -Because of downsides, WASI resources have explicit destructor - -Virt WASI then looks like…. -What happens on double close or use-after-close? -Spectrum of options, none of them good -How do I efficiently support cross-instance resource sharing? -Not great options either -How can a WASI impl robustly clean up after clients are destroyed? -Could leak. -Want FDs to be closed when the instance goes away, just like OS process -A native WASI impl could do this, but not a virtualized one -How do instances even get different lifetimes? This is a next step, to add ability to dynamically create and destroy instances -Also problems around dynamic casting -E.g. when store n distinct DOM node types in a single table -Not supporting would be a kind of regression - -Dynamic casting breaks otherwise-static invariants -If there’s a run function and I pass a RO, is it possible for X to somehow do a write? -It would be nice to have that answer based only on the static type -Fix is to treat different imports as different things for purpose of dynamic cast -To fix this, you need a wrapping at some membrane/boundary -OK for core wasm, because that’s just a compiler target -But not ok for ecosystem - -When we’re virtualizingWASI we want: … -Is all of this just for virtualization? -Resources are not a uniquely WASI concern -We should treat WASI as an unprivileged set of library interfaces - -Proposal -Add a new interface type called handle -Handle is a value that can be copied -Refers to a resource -A resource is some entity with a lifetime. It can not be copied -So resource types are like abstract type, but only private option -Additionally resource type definitions can have an optional destructor -Resource creation and use is symmetric to private.new/get -Handles are semantically ref-counted and call the destructor when they get to 0 -That’s what gives virt WASI same privileges as native -Also possible to explicitly destroy handles, and references trap - -**Sam Clegg:** would need to be at WASI core? -**Luke Wagner:** So far everything in Interface Types - -**Pat Hickey:** Attenuation -**Luke Wagner:** I’ve gone back and forth. Have an idea in open questions - -**Luke Wagner:** High level summary of IT -They’re lazy copy operations -Need a way to box all interface types -Generally valuable because it solves interesting performance use cases -For handle values, creates a root that creates the stack -That makes it so handles can outlive stack frame - -Once I have a reference, it can be cast -Will always trap if cast to differently privileged - -IT gives us the boundary/membrane where to wrap - -Proposal summary -Additions -New types -New definition -New instructions -Extend rtt.canon - -Problems: -Robust and efficient handling of double-free/use-after-free -…. - -Open Questions -Add abstract subtyping? -Should we have specialized versions of handle (e.g. a strong handle, unique handle) - -Next steps -Need to give lifetimes to instances -Can instances just be resources? -Could implement WASI command pattern in the toolchain rather than host magic - -**Sam Clegg:** What happens if you destroy a resource and another module still has a copy - -**Luke Wagner:** It will have a handle. That handle is then in a null state. When you try to use the handle, it would trap probably at resource.get - -**Sam Clegg:** So the trap would happen in the callee - -**Luke Wagner:** That’s where we might want to have a strong handle where no one could pass you an invalid handle. It’s an open question - -**Ralph Squillace:** For what it’s worth, I’ve been spinning around Pat’s question and going back to DCE-RPC. Believe that you should make or signal a strong decision about shared resources. - -**Luke Wagner:** That’s one of the reasons I like unique, because then when I give you a handle I’m explicitly saying I dont’ still have it. I guess that’s an argument for both unique and strong - -**Ralph Squillace:** Having the ability to make those choices is what comes to mind. If I choose a convention, I can signal it to others. Previous technologies tried to let people do it without signaling capabilities - -**Luke Wagner:** Would a summary be that you’re in favor of those two types of handles - -**Ralph Squillace:** I would say those two handles express two slices of the problem space. I wouldn’t say that I’ve thought through other possible types. - -**Luke Wagner:** Your’e right, I was trying to survey the literature and there are like 20 types - -**Ralph Squillace:** Even if you don’t have strong type, at least you can trap. Maybe that’s the first step. - -**Luke Wagner:** Hierarchy, undefined is worst, trap is better, statically preventing is best - -**Sam Clegg:** These handles are at IT types and at core go to reference. So references can be copied - -**Luke Wagner:** Once you exclusively use IT, there’s no back door - -**Sam Clegg:** Any incremental steps? - -**Luke Wagner:** In some sense, witx already has handle - -**Lin Clark** proposes that we make that the main topic for next meeting - diff --git a/proposals/clocks/meetings/2021/WASI-02-11.md b/proposals/clocks/meetings/2021/WASI-02-11.md deleted file mode 100644 index c18c4b8fa..000000000 --- a/proposals/clocks/meetings/2021/WASI-02-11.md +++ /dev/null @@ -1,118 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the February 11 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: February 11, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. Discussion: What are the next steps in adapting WASI to use Interface Types handles and resources? - 1. _Sumbit a PR to add your agenda item here_ - -## Notes -### Attendees -Pat Hickey -Andrew Brown -Sergey Rubanov -Lin Clark -Mark McCaskey -Till Schneidereit -Dan Gohman -Josh Dolitsky -Mingqiu Sun -Ralph Squillace -Nicholas -Radu Matei -Matt Fisher -Johnnie Birch -Luke Wagner - -**Lin Clark:** Are there any announcements? -(none) - -**Lin Clark:** Lets talk about how we’re going to move from this version of WASI to a new version that uses handles - -**Dan Gohman:** Witx has been designed to anticipate interface types. It has String and Handle types. These are pretty close to the ones in interface types - PR 391 takes things to the next level and evolves the rest of the witx types towards the interface types. Going forward we need to get rid of the witx pointer and get buffers to work the way they will in interface types, but we’re still waiting to hear from interface types the final word on how those will work. See Interface Types issue 68. Our job on the witx side is to evolve into the Interface Types buffer types. Without waiting we can add support for strings and return types and lower them into the existing C ABI that WASI programs use. - -**Dan Gohman:** Another piece is WASI modularization. It has been in progress for a while but several pieces are coming together. Issue 378. Describes a more granular include mechanism than witx uses right now - import a symbol from a module, rather than import a file. - -**Dan Gohman:** The next two big pieces, which we can address in detail in the future: How do you pass handles into programs? Currently there is a table with preopens in it, but interface types is going to give us new mechanisms that are better than the preopen concept. - -**Dan Gohman:** The last piece is defining new abstractions. wasi PR 240 describes how to merge the send and recv on sockets with read and write on files. We can generalize part of files and sockets into a concept of I/O streams. In interface types you’ll have the vocabulary to ask for e.g. a stream you can write to, without knowing or caring that its backed by a socket or file or pipe etc. What is the noun that you use in function signatures to describe an I/O Stream? Beyond I/O Streams there’s non-streaming operations on files which don’t work on sockets or pipes - pread/pwrite - there’s a place for an I/O object with non-stream personality as well, an array of bytes or a we can call it a dynamic array because it can be resized. There will be other concepts as well - key-value stores, windowed IO with buffers... At the moment the nascent WASI I/O proposal will evolve to develop these ideas. There will still be files, and then a function that gives you a stream from a file. Files are going to be required to interop with existing systems, but we can push people towards interfaces that don’t tie them to the complications of those existing systems, particularly file semantics are very difficult to compose but streams are. This will help us enable shared-nothing linking of modules - we don’t want modules to have to share a filesystem to talk to each other. Questions? - -**Ralph Squillace:** What kinds of objections to this direction do you anticipate? - -**Dan Gohman:** This is going off the path of POSIX. Existing applications and programming languages will be more work to port to I/O streams than having us port libc and standard libraries to WASI. We have ideas for making the standard io operations work on top of I/O streams - you can treat an i/o stream as a libc FILE if you only ever read and write from it, other operations give an error. - -**Ralph Squillace:** The philosophical discussion is about how you weigh the objectives of different applications moving to WASI - some will have to adapt specific POSIX-isms to WASI, where does the work of porting existing code break down - does the code stay in WASM and not use WASI, have its own custom runtime - or does it move to WASI in the coherent way that resolves the semantic differences. I don’t personally see myself trying to port an existing huge monolithic application to WASI, whereas I do see myself working on libraries to make them work in WASI. - -**Lin Clark:** How much is WASI filesystem still going to allow porting POSIX applications? - -**Dan Gohman:** It will allow it. Its a question of priorities rather than absolutes. WASI today runs plenty of interesting POSIX code that doesnt do things like fork(2), WASI filesystem is going to still be there for these applications to use. But we don’t want that to be part of the default for WASI, we want to encourage applications to use simpler concepts that don’t imply a whole filesystem. I want to build tooling that bridges the gap between the shared-nothing-linking space and making big applications work. - -**Till Schneidereit:** We can look at this in terms of layering - there is a core of WASI that may not apply to every use case but you can virtualize many of the other needs on top of it. You can add a filesystem ion top of the core, in many cases, and let applications that need it use it. - -**Dan Gohman:** In terms of migration from where WASI is today to this ideal system - the WASI I/O abstractions can be worked on now, we have witx where we need it. We can flesh out exactly how streams and dynamic arrays work today. - -**Dan Gohman:** Another aspect is portability. I’ve been working on support for WASI on Windows vs Unix the last few months - there are so many differences between those platforms, the semantics of filesystems is radically different and there’s no portability in many cases (its too expensive to bridge them). The WASI I/O abstractions can be designed to hide all of the non-portable parts of filesystems. We can get away from having to specify “what does windows do here” and instead specify the things an application actually needs. - -**Ralph Squillace:** Layering will require thought. - -**Pat Hickey:** The customers we have writing applications right now aren’t concerned with the differences between the filesystem guarantees on linux vs windows, they care about http requests and responses. If we have I/O abstractions that unify the way http bodies work with the way certain aspects of the filesystem work, that is better for the applications we care about. - -**Till Schneidereit:** There are lots of use cases that work with streaming, which has traditionally been a file or a socket, but with abstractions that are hard to generalize. My interpretation of what you were just saying is that if we had a way to have a cleaner system that didn’t have that incidental platform dependence, it would be much easier to build code that works across these very different environments. We have all these applications that are popping up that are very different. Ideally we have a layer that doesn’t care about host differences, and then the layer that cares about that. What we do is just one specific example of that. Don’t want to optimize for old use cases, but all of the new novel ones that are coming about. - -**Radu Matei:** Is the assumption that wasi-filesystem will be developed in parallel? - -**Dan Gohman:** Yes, WASI-filesystem will continue, and wasi-io will be a peer. - -**Ralph Squillace:** Drawing older threads in, what about BSD sockets PR. - -**Dan Gohman:** The contributor who created that hasn’t been active, but I expect that will fit into the system in the same way as wasi-fs. You could get a stream. Networking is a complex topic and I dont’ want to simplify, but the first step will be to take sockets and say the socket gives you a stream that you can read, a stream you can write, and bi-directional r/w. - -Async is a subtlety that we’re leaving out. We can say that async is an orthogonal concern. We expect the Wasm platform will give us better answers over time. But the fundamental concepts of I/O are independent of whether you block that I/O. - -**Lin Clark:** Any other thoughts/comments - -**Luke Wagner:** I have a hypothesis I want to test. Why are people going to want to use wasm outside of a browser? Some people think it’s great because of ISA. We don’t think that’s a great motivator. We think running guest code in latency sensitive and low trust scenarios is the motivator. Things like routers ____ would be host APIs. The libraries would be wasm. These problematic cases don’t have a high value reason to be ported to Wasm. - -**Ralph Squillace:** I understand where you’re coming from. I don’t see WASI as a monolithic process sandbox. I do think that the idea about the sweet spot is right. I’m not a big believer in the thought that the world’s code is going to all be running on WASI. But I think it’s worth consideration how much of the world’s knowledge can be run as WASI. Shouldn’t wall off for all time, but I think the way that Dan laid out the direction, it lets us start with the sweet spot and either layer the others, or add support to WASI later on. I would hate to frame the boundary ruling out knowledge transfer. - -**Luke Wagner:** I agree with your points, so the layering and virtualization are also motivated by that. - -**Dan Gohman:** I can add one thing. Thinking of lib-c, and lots of languages have lib-c like std lib: under the covers, something that people are using as a file could be represented by streams. We can make that work under the covers. We could talk about how that will exactly work. But this is the framework. We can make porting easier by allowing you to use streams by allowing you to use files, but discourage from using file stat and depending on i node. - -**Andrew Brown:** It feels to me that filesystem should be in phase 3 or 4. How do these changes affect moving those to later stages - -**Dan Gohman:** That’s a great question. Wasi-fs is waiting to figure out it’s place. This conversation moves that forward. Understanding that wasi-fs won’t attempt to be abstracting over all hosts, wasi-io does that, and accepting that’s ok means that wasi-fs can probably move to phase 3 at this point. - -**Till Schneidereit:** I think the better way to put it is that it’s not an either/or, we don’t need to make it completely host specific, but let’s find a balance that’s actually viable. - -**Radu Matei:** do we have a document? - -**Dan Gohman:** Will be writing that up. Wanted to introduce here first. Will write up wasi-io ideas soon - -**Pat Hickey:** One blocker to wasi-fs advancing. The filesystem has cloud ABI system of rights. Need to work out what to do with that. diff --git a/proposals/clocks/meetings/2021/WASI-02-25.md b/proposals/clocks/meetings/2021/WASI-02-25.md deleted file mode 100644 index 2bc89278a..000000000 --- a/proposals/clocks/meetings/2021/WASI-02-25.md +++ /dev/null @@ -1,131 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the February 25 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: February 25, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. Discussion: Better error handling in WASI - 1. _Sumbit a PR to add your agenda item here_ - -## Notes -### Attendees -- Lin Clark -- Dan Gohman -- Andrew Brown -- Johnnie Birch -- Sergey Rubanov -- Mark McCaskey -- Peter Huene -- Radu Matei -- Luke Wagner -- Ralph Squillace -- Pat Hickey -- Till Schneidereit -- Mingqiu Sun -- David Piepgrass -- Yong He - -**Dan Gohman:** Overview—errors handled like POSIX with single enum of errno. More APIs in WASI, not feasible to have a single errno enum. Also not reasonable to have a single error type. My expectation for errors is that every library will define its own error types. IT will make it possible for us to define a variant type like Rust’s Result. Does that shape of things make sense? - -**Andrew Brown:** Makes sense to me. Errors for wasi-nn are just a totally different sphere than files. - -**Dan Gohman:** wasi-libc will still have errno. Errno only describes small set of system errors - -**Andrew Brown:** Right now wasi-nn has own kind of error types. What’s changing? Will we just change witx and wiggle - -**Dan Gohman:** It’s not a fundamental change. We’re just making what wasi-nn is doing explicit. We’ll also be getting new features from IT which will describe what you’re doing in a better way. Enum with either success or failure, maybe called Expected. - -**Andrew Brown:** I think Alex has already made this change. - -**Dan Gohman:** Yeah, we wanted to give people a heads up about this plan. - -**Andrew Brown:** One question about the future—will this expected type, in the failure case will you be able to pass things that aren’t just an integer, like strings and stuff - -**Dan Gohman:** There is no master plan, but I expect the basic mech will be that you can have any type for errors, with full expressiveness of IT. One caveat, how do we want to handle strings? English isn’t appropriate for all envs. Will need to apply more design thought. Underlying tool won’t have a restriction against that, though - -**Andrew Brown:** Agreed. On thing I’ve found with wasi-nn is just having an errno isn’t enough - -**Dan Gohman:** Agreed, and that’s a place where tooling might be able to help. We can go down the path of thinkking of enums not just as ints but high-level types - -**Luke Wagner:** Along that line, one thing that has bugged me about classical error codes, is sometimes you want to use them for conditionals, and sometimes you just want to debug. Two level nesting of variants? Top level “You called it wrong” and second level provides detail of how you called it wrong. - -**Dan Gohman:** Yes, let’s do that. I think that’s totally a good idea to do. Another idea, in POSIX they have system calls that are never supposed to crash. In WASI, we don’t need to be as strict. If you pass a bad pointer into a syscall, it could trap. - -**Pat Hickey:** Yeah, that’s also a kind of a concession for virtualization. Awfully convenient for that - -**Dan Gohman:** So that’s the basic vision of it. Any more questions on that level of detail? One thing this does mean, we won’t have unified error handling across WASI. Another thing, we want to go through the APIs and figure out what errors things like the clock apis can return. In practice, the only thing that can fail in a clock is failing to get a clock. Wasi-filesystem will probably be where most of the error codes land. Simplifying property across different APIs. Don’t overload error codes to represent similar but not the same errors. Exception handling is coming. A possible approach is to use unwinding. I think that for WASI, errors work better. If languages want to use unwinding, they can expect errors and unwind. I think using variants instead of exceptions will work well for us. - -**Pat Hickey:** The one thing I’ll call out is that proc_exit should be implemented as unwind. - -**Dan Gohman:** That’s true. I’m going to claim that proc_exit is special. It might be something that we unwind and then turn into a clean exit status. Then the unwinding becomes an implementation detail. That wouldn’t be a thing that leaks across module boundaries. Often not a good idea for libraries to call exit directly. - -**Pat Hickey:** So we basically get rid of proc_exit as a library function - -**Dan Gohman:** So I think what we want to say is return type from main is an error type. - -**Pat Hickey:** Yeah, that way we keep types all the way down and don’t turn into bare integer. - -**Dan Gohman:** Yeah, so 3 error types. Return values, unwinding, and trapping. Trapping is for program has a bug. Maybe sometimes when return values. ____. And we’ll use unwinding across language boundaries. - -**Pat Hickey:** Unlike with errors, we can’t invent new ways to trap. - -**Dan Gohman:** Although I wonder if there’s something we could do there. I wonder if it makes sense for wasm to be able to trap with extra info. - -**Luke Wagner:** Or there could be a WASI function that says “I’m going to trap, but you can provide me with an error to print” - -**Pat Hickey:** You can imagine that a malicious module would do that - -**Luke Wagner:** They can do that already. We don’t want wasm to casually be able to catch traps. Because at a very fine granularity. But having a blast zone that allows a set to go away without taking down the rest. I think that belongs at some point of time in wasm’s future. - -**Dan Gohman:** yeah, if we add those mechanisms, then programmer errors could just be trapped. - -**Lin Clark:** Best way to collaborate - -**Dan Gohman:** Once we’ve fully modularized, each module will audit their own errors. The wasi-libc work will start after the next snapshot which includes those changes. - -**Andrew Brown:** Question about sockets. Who’s driving that - -**Dan Gohman:** Haven’t heard from them. Don’t know what their status is. Expect that if they don’t respond soon we’ll find someone else - -**Andrew Brown:** Who was originally driving it? - -**Dan Gohman:** Somebody working for a company called ____. The person who filed it is the person working there. - -**Andrew Brown:** Radu, was someone on your side interested in that? - -**Radu Matei:** We should probably have a chat at some point. How will that relate to these changes? - -**Dan Gohman:** Sockets are the other major user of errno. I expect sockets will have their own errno, and then wasi-libc will have some way to concatenate errnos and turn it into appropriate POSIX errno space. I think that’s basically it. - -**Radu Matei:** How about IO Streams? - -**Dan Gohman:** We haven’t talked about how it’s going to work with libc. I expect from a POSIX point of view, we might have a bunch of different error codes in wasi-io. Have been talking about wasi-io not reporting very specific errors because it leaks information. We aren’t necessarily going to want to return a lot of detail there either. - -**Ralph Squillace:** I think we want to try to figure out, if we help pick up the PR, what’s the best way to move forward without having to reimplement too much. Will reach out to original champion. - -**Dan Gohman:** I see wasi-filesystem and wasi-sockets being peers. At a good place for them to work the same way. diff --git a/proposals/clocks/meetings/2021/WASI-03-11.md b/proposals/clocks/meetings/2021/WASI-03-11.md deleted file mode 100644 index f6170a738..000000000 --- a/proposals/clocks/meetings/2021/WASI-03-11.md +++ /dev/null @@ -1,32 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the March 11 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: March 11, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. Presentation: Passing capabilities into programs with Typed Main (Dan Gohman) - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/2021/WASI-03-25.md b/proposals/clocks/meetings/2021/WASI-03-25.md deleted file mode 100644 index a35f4e17e..000000000 --- a/proposals/clocks/meetings/2021/WASI-03-25.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the March 25 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: March 25, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/2021/WASI-04-08.md b/proposals/clocks/meetings/2021/WASI-04-08.md deleted file mode 100644 index 35d2286f9..000000000 --- a/proposals/clocks/meetings/2021/WASI-04-08.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the April 8 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: April 8, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/2021/WASI-04-22.md b/proposals/clocks/meetings/2021/WASI-04-22.md deleted file mode 100644 index 722d57ca0..000000000 --- a/proposals/clocks/meetings/2021/WASI-04-22.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the April 22 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: April 22, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/2021/WASI-05-06.md b/proposals/clocks/meetings/2021/WASI-05-06.md deleted file mode 100644 index da5cf7cbb..000000000 --- a/proposals/clocks/meetings/2021/WASI-05-06.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the May 6 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: May 6, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/2021/WASI-05-20.md b/proposals/clocks/meetings/2021/WASI-05-20.md deleted file mode 100644 index c91e5777f..000000000 --- a/proposals/clocks/meetings/2021/WASI-05-20.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the May 20 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: May 20, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/2021/WASI-06-03.md b/proposals/clocks/meetings/2021/WASI-06-03.md deleted file mode 100644 index 89487782a..000000000 --- a/proposals/clocks/meetings/2021/WASI-06-03.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the June 3 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: June 3, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/2021/WASI-06-17.md b/proposals/clocks/meetings/2021/WASI-06-17.md deleted file mode 100644 index 583b7f02b..000000000 --- a/proposals/clocks/meetings/2021/WASI-06-17.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the June 17 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: June 17, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/clocks/meetings/README.md b/proposals/clocks/meetings/README.md deleted file mode 100644 index a9fcf2e21..000000000 --- a/proposals/clocks/meetings/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# WASI meetings - -Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow -[the process of the CG](https://github.com/WebAssembly/meetings). - -## Meetings - -### 2019 - - * [WASI May 2nd video call](2019/WASI-05-02.md) - * [WASI May 16th video call](2019/WASI-05-16.md) - * [WASI May 30th video call](2019/WASI-05-30.md) - * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) - * [WASI June 27th video call](2019/WASI-06-27.md) - * [WASI July 18th video call](2019/WASI-07-18.md) - * [WASI August 15th video call](2019/WASI-08-15.md) - * [WASI August 30th video call](2019/WASI-08-30.md) - * [WASI September 12th video call](2019/WASI-09-12.md) - * [WASI September 26th video call](2019/WASI-09-26.md) - * [WASI October 15th in-person meeting](2019/WASI-10-15.md) - * [WASI October 24th video call](2019/WASI-10-24.md) - * [WASI November 7th video call](2019/WASI-11-07.md) - * [WASI November 21st video call](2019/WASI-11-21.md) - * [WASI December 5th video call](2019/WASI-12-05.md) - * [WASI December 19th video call](2019/WASI-12-19.md) - -### 2020 - - * [WASI January 16th video call](2020/WASI-01-16.md) - * [WASI February 27th video call](2020/WASI-02-27.md) - * [WASI March 12th video call](2020/WASI-03-12.md) - * [WASI March 26th video call](2020/WASI-03-26.md) - * [WASI April 9th video call](2020/WASI-04-09.md) - * [WASI May 7th video call](2020/WASI-05-07.md) - * [WASI May 21st video call](2020/WASI-05-21.md) - * [WASI June 4th video call](2020/WASI-06-04.md) - * [WASI July 2nd video call](2020/WASI-07-02.md) - * [WASI July 16th video call](2020/WASI-07-16.md) - * [WASI July 30th video call](2020/WASI-07-30.md) - * [WASI August 27th video call](2020/WASI-08-27.md) - * [WASI September 10th video call](2020/WASI-09-10.md) - * [WASI September 21st video call](2020/WASI-09-21.md) - * [WASI October 8th video call](2020/WASI-10-08.md) - * [WASI October 22nd video call](2020/WASI-10-22.md) - * [WASI November 19th video call](2020/WASI-11-19.md) - * [WASI December 3rd video call](2020/WASI-12-03.md) - - ### 2021 - * [WASI January 14th video call](2021/WASI-01-14.md) - * [WASI January 28th video call](2021/WASI-01-28.md) - * [WASI February 11th video call](2021/WASI-02-11.md) - * [WASI February 25th video call](2021/WASI-02-25.md) - * [WASI March 11th video call](2021/WASI-03-11.md) - * [WASI March 25th video call](2021/WASI-03-25.md) - * [WASI April 8th video call](2021/WASI-04-08.md) - * [WASI April 22nd video call](2021/WASI-04-22.md) - * [WASI May 6th video call](2021/WASI-05-06.md) - * [WASI May 20th video call](2021/WASI-05-20.md) - * [WASI June 3rd video call](2021/WASI-06-03.md) - * [WASI June 17th video call](2021/WASI-06-17.md) - \ No newline at end of file diff --git a/proposals/clocks/phases/README.md b/proposals/clocks/phases/README.md deleted file mode 100644 index 9f66686bd..000000000 --- a/proposals/clocks/phases/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# WASI's ephemeral/snapshot/old Process - -For the standardization process, WASI overall uses a [process] -modeled after the WebAssembly CG's phased process. - -For development of features in Phase 2 and later of that process, WASI -has a ephemeral/snapshot/old process, which is designed to allow -for a balance between the need for stability to allow people to build -compatible implementations, libraries, and tools and gain implementation -experience, and the need for proposals to evolve. - -[process]: https://github.com/WebAssembly/WASI/blob/main/docs/Process.md - -## The ephemeral/snapshot/old Phases - -- [`ephemeral`](ephemeral): The development staging area. New API - proposals API-changing fixes to existing APIs should be submitted - as Pull Requests making changes to this directory. This directory - provides no API stability or versioning. APIs in this directory use - API module names starting with `wasi_ephemeral_`. - -- [`snapshot`](snapshot): Usable APIs. APIs in `ephemeral` will be - occasionally snapshotted and promoted into `snapshot`, with approval - from the Subgroup, considering the overall suitability of the APIs - themselves, their documentation, test coverage, and availability of - polyfills when appropriate. Once merged, the API modules will be - considered stable, though they may be superseded by newer versions. - Proposals to promote specific APIs should be submitted as Pull Requests - that: - 1. `git mv` contents of `phases/snapshot/` to - `phases/old/snapshot_{old_snapshot_number}`. - 2. `cp -R` contents of `phases/ephemeral/` into `phases/snapshot/`. - 3. Rename files copied into `phases/snapshot/` to substitute `ephemeral` - for `snapshot` in file names. Append the new snapshot number to each - name. - 4. Update module names given in `.witx` files according to the previous - step. - 5. Update tests in `tools/witx/tests/wasi.rs` to point at new snapshot, and - add a test pointing at the just-archived snapshot under `old`. - 6. Optionally, under `phases/old/snapshot_{old_snapshot_number}, add - polyfills for superceded APIs using the new APIs. - - - Pull Requests may also add additional tests, documentation, or - polyfills for existing `snapshot` APIs. - -- [`old`](old): When APIs in `snapshot` spec are replaced by new - versions, the old API modules are moved to the `old` directory. When - possible, `old` APIs may be accompanied by polyfill modules which - implement their API in terms of newer versions of the API. diff --git a/proposals/clocks/phases/ephemeral/docs.md b/proposals/clocks/phases/ephemeral/docs.md deleted file mode 100644 index f29d401c4..000000000 --- a/proposals/clocks/phases/ephemeral/docs.md +++ /dev/null @@ -1,2562 +0,0 @@ -# Types -## `size`: `usize` -An array size. - -Note: This is similar to `size_t` in POSIX. - -Size: 4 - -Alignment: 4 - -## `filesize`: `u64` -Non-negative file size or length of a region within a file. - -Size: 8 - -Alignment: 8 - -## `timestamp`: `u64` -Timestamp in nanoseconds. - -Size: 8 - -Alignment: 8 - -## `clockid`: `Variant` -Identifiers for clocks. - -Size: 4 - -Alignment: 4 - -### Variant cases -- `realtime` -The clock measuring real time. Time value zero corresponds with -1970-01-01T00:00:00Z. - -- `monotonic` -The store-wide monotonic clock, which is defined as a clock measuring -real time, whose value cannot be adjusted and which cannot have negative -clock jumps. The epoch of this clock is undefined. The absolute time -value of this clock therefore has no meaning. - -## `errno`: `Variant` -Error codes returned by functions. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX. - -Size: 2 - -Alignment: 2 - -### Variant cases -- `success` -No error occurred. System call completed successfully. - -- `2big` -Argument list too long. - -- `access` -Permission denied. - -- `addrinuse` -Address in use. - -- `addrnotavail` -Address not available. - -- `afnosupport` -Address family not supported. - -- `again` -Resource unavailable, or operation would block. - -- `already` -Connection already in progress. - -- `badf` -Bad file descriptor. - -- `badmsg` -Bad message. - -- `busy` -Device or resource busy. - -- `canceled` -Operation canceled. - -- `child` -No child processes. - -- `connaborted` -Connection aborted. - -- `connrefused` -Connection refused. - -- `connreset` -Connection reset. - -- `deadlk` -Resource deadlock would occur. - -- `destaddrreq` -Destination address required. - -- `dom` -Mathematics argument out of domain of function. - -- `dquot` -Reserved. - -- `exist` -File exists. - -- `fault` -Bad address. - -- `fbig` -File too large. - -- `hostunreach` -Host is unreachable. - -- `idrm` -Identifier removed. - -- `ilseq` -Illegal byte sequence. - -- `inprogress` -Operation in progress. - -- `intr` -Interrupted function. - -- `inval` -Invalid argument. - -- `io` -I/O error. - -- `isconn` -Socket is connected. - -- `isdir` -Is a directory. - -- `loop` -Too many levels of symbolic links. - -- `mfile` -File descriptor value too large. - -- `mlink` -Too many links. - -- `msgsize` -Message too large. - -- `multihop` -Reserved. - -- `nametoolong` -Filename too long. - -- `netdown` -Network is down. - -- `netreset` -Connection aborted by network. - -- `netunreach` -Network unreachable. - -- `nfile` -Too many files open in system. - -- `nobufs` -No buffer space available. - -- `nodev` -No such device. - -- `noent` -No such file or directory. - -- `noexec` -Executable file format error. - -- `nolck` -No locks available. - -- `nolink` -Reserved. - -- `nomem` -Not enough space. - -- `nomsg` -No message of the desired type. - -- `noprotoopt` -Protocol not available. - -- `nospc` -No space left on device. - -- `nosys` -Function not supported. - -- `notconn` -The socket is not connected. - -- `notdir` -Not a directory or a symbolic link to a directory. - -- `notempty` -Directory not empty. - -- `notrecoverable` -State not recoverable. - -- `notsock` -Not a socket. - -- `notsup` -Not supported, or operation not supported on socket. - -- `notty` -Inappropriate I/O control operation. - -- `nxio` -No such device or address. - -- `overflow` -Value too large to be stored in data type. - -- `ownerdead` -Previous owner died. - -- `perm` -Operation not permitted. - -- `pipe` -Broken pipe. - -- `proto` -Protocol error. - -- `protonosupport` -Protocol not supported. - -- `prototype` -Protocol wrong type for socket. - -- `range` -Result too large. - -- `rofs` -Read-only file system. - -- `spipe` -Invalid seek. - -- `srch` -No such process. - -- `stale` -Reserved. - -- `timedout` -Connection timed out. - -- `txtbsy` -Text file busy. - -- `xdev` -Cross-device link. - -- `notcapable` -Extension: Capabilities insufficient. - -## `rights`: `Record` -File descriptor rights, determining which actions may be performed. - -Size: 8 - -Alignment: 8 - -### Record members -- `fd_datasync`: `bool` -The right to invoke `fd_datasync`. -If `path_open` is set, includes the right to invoke -`path_open` with [`fdflags::dsync`](#fdflags.dsync). - -Bit: 0 - -- `fd_read`: `bool` -The right to invoke `fd_read` and `sock_recv`. -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. - -Bit: 1 - -- `fd_seek`: `bool` -The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). - -Bit: 2 - -- `fd_fdstat_set_flags`: `bool` -The right to invoke `fd_fdstat_set_flags`. - -Bit: 3 - -- `fd_sync`: `bool` -The right to invoke `fd_sync`. -If `path_open` is set, includes the right to invoke -`path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - -Bit: 4 - -- `fd_tell`: `bool` -The right to invoke `fd_seek` in such a way that the file offset -remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to -invoke `fd_tell`. - -Bit: 5 - -- `fd_write`: `bool` -The right to invoke `fd_write` and `sock_send`. -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. - -Bit: 6 - -- `fd_advise`: `bool` -The right to invoke `fd_advise`. - -Bit: 7 - -- `fd_allocate`: `bool` -The right to invoke `fd_allocate`. - -Bit: 8 - -- `path_create_directory`: `bool` -The right to invoke `path_create_directory`. - -Bit: 9 - -- `path_create_file`: `bool` -If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). - -Bit: 10 - -- `path_link_source`: `bool` -The right to invoke `path_link` with the file descriptor as the -source directory. - -Bit: 11 - -- `path_link_target`: `bool` -The right to invoke `path_link` with the file descriptor as the -target directory. - -Bit: 12 - -- `path_open`: `bool` -The right to invoke `path_open`. - -Bit: 13 - -- `fd_readdir`: `bool` -The right to invoke `fd_readdir`. - -Bit: 14 - -- `path_readlink`: `bool` -The right to invoke `path_readlink`. - -Bit: 15 - -- `path_rename_source`: `bool` -The right to invoke `path_rename` with the file descriptor as the source directory. - -Bit: 16 - -- `path_rename_target`: `bool` -The right to invoke `path_rename` with the file descriptor as the target directory. - -Bit: 17 - -- `path_filestat_get`: `bool` -The right to invoke `path_filestat_get`. - -Bit: 18 - -- `path_filestat_set_size`: `bool` -The right to change a file's size. -If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). -Note: there is no function named `path_filestat_set_size`. This follows POSIX design, -which only has `ftruncate` and does not provide `ftruncateat`. -While such function would be desirable from the API design perspective, there are virtually -no use cases for it since no code written for POSIX systems would use it. -Moreover, implementing it would require multiple syscalls, leading to inferior performance. - -Bit: 19 - -- `path_filestat_set_times`: `bool` -The right to invoke `path_filestat_set_times`. - -Bit: 20 - -- `path_permissions_set`: `bool` -The right to invoke `path_permissions_set`. - -Bit: 21 - -- `fd_filestat_get`: `bool` -The right to invoke `fd_filestat_get`. - -Bit: 22 - -- `fd_filestat_set_size`: `bool` -The right to invoke `fd_filestat_set_size`. - -Bit: 23 - -- `fd_filestat_set_times`: `bool` -The right to invoke `fd_filestat_set_times`. - -Bit: 24 - -- `fd_permissions_set`: `bool` -The right to invoke `fd_permissions_set`. - -Bit: 25 - -- `path_symlink`: `bool` -The right to invoke `path_symlink`. - -Bit: 26 - -- `path_remove_directory`: `bool` -The right to invoke `path_remove_directory`. - -Bit: 27 - -- `path_unlink_file`: `bool` -The right to invoke `path_unlink_file`. - -Bit: 28 - -- `poll_fd_readwrite`: `bool` -If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). -If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). - -Bit: 29 - -- `sock_shutdown`: `bool` -The right to invoke `sock_shutdown`. - -Bit: 30 - -## `fd`: `Handle` -A file descriptor handle. - -Size: 4 - -Alignment: 4 - -### Supertypes -## `iovec`: `Record` -A region of memory for scatter/gather reads. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `Pointer` -The address of the buffer to be filled. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be filled. - -Offset: 4 - -## `ciovec`: `Record` -A region of memory for scatter/gather writes. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `ConstPointer` -The address of the buffer to be written. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be written. - -Offset: 4 - -## `iovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `ciovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `filedelta`: `s64` -Relative offset within a file. - -Size: 8 - -Alignment: 8 - -## `whence`: `Variant` -The position relative to which to set the offset of the file descriptor. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `set` -Seek relative to start-of-file. - -- `cur` -Seek relative to current position. - -- `end` -Seek relative to end-of-file. - -## `dircookie`: `u64` -A reference to the offset of a directory entry. - -Size: 8 - -Alignment: 8 - -### Constants -- `start` - -## `dirnamlen`: `u32` -The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). - -Size: 4 - -Alignment: 4 - -## `inode`: `u64` -File serial number that is unique within its file system. - -Size: 8 - -Alignment: 8 - -## `filetype`: `Variant` -The type of a file descriptor or file. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `unknown` -The type of the file descriptor or file is unknown or is different from any of the other types specified. - -- `block_device` -The file descriptor or file refers to a block device inode. - -- `character_device` -The file descriptor or file refers to a character device inode. - -- `directory` -The file descriptor or file refers to a directory inode. - -- `regular_file` -The file descriptor or file refers to a regular file inode. - -- `socket_dgram` -The file descriptor or file refers to a datagram socket. - -- `socket_stream` -The file descriptor or file refers to a byte-stream socket. - -- `symbolic_link` -The file refers to a symbolic link inode. - -- `fifo` -The file descriptor or file refers to a FIFO. - -## `dirent`: `Record` -A directory entry. - -Size: 24 - -Alignment: 8 - -### Record members -- `d_next`: [`dircookie`](#dircookie) -The offset of the next directory entry stored in this directory. - -Offset: 0 - -- `d_ino`: [`inode`](#inode) -The serial number of the file referred to by this directory entry. - -Offset: 8 - -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. - -Offset: 16 - -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. - -Offset: 20 - -## `advice`: `Variant` -File or memory access pattern advisory information. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `normal` -The application has no advice to give on its behavior with respect to the specified data. - -- `sequential` -The application expects to access the specified data sequentially from lower offsets to higher offsets. - -- `random` -The application expects to access the specified data in a random order. - -- `willneed` -The application expects to access the specified data in the near future. - -- `dontneed` -The application expects that it will not access the specified data in the near future. - -- `noreuse` -The application expects to access the specified data once and then not reuse it thereafter. - -## `fdflags`: `Record` -File descriptor flags. - -Size: 2 - -Alignment: 2 - -### Record members -- `append`: `bool` -Append mode: Data written to the file is always appended to the file's end. - -Bit: 0 - -- `dsync`: `bool` -Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - -Bit: 1 - -- `nonblock`: `bool` -Non-blocking mode. - -Bit: 2 - -- `rsync`: `bool` -Synchronized read I/O operations. - -Bit: 3 - -- `sync`: `bool` -Write according to synchronized I/O file integrity completion. In -addition to synchronizing the data stored in the file, the implementation -may also synchronously update the file's metadata. - -Bit: 4 - -## `fdstat`: `Record` -File descriptor attributes. - -Size: 24 - -Alignment: 8 - -### Record members -- `fs_filetype`: [`filetype`](#filetype) -File type. - -Offset: 0 - -- `fs_flags`: [`fdflags`](#fdflags) -File descriptor flags. - -Offset: 2 - -- `fs_rights_base`: [`rights`](#rights) -Rights that apply to this file descriptor. - -Offset: 8 - -- `fs_rights_inheriting`: [`rights`](#rights) -Maximum set of rights that may be installed on new file descriptors that -are created through this file descriptor, e.g., through `path_open`. - -Offset: 16 - -## `device`: `u64` -Identifier for a device containing a file system. Can be used in combination -with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. - -Size: 8 - -Alignment: 8 - -## `fstflags`: `Record` -Which file time attributes to adjust. - -Size: 2 - -Alignment: 2 - -### Record members -- `atim`: `bool` -Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - -Bit: 0 - -- `atim_now`: `bool` -Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 1 - -- `mtim`: `bool` -Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - -Bit: 2 - -- `mtim_now`: `bool` -Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 3 - -## `lookupflags`: `Record` -Flags determining the method of how paths are resolved. - -Size: 4 - -Alignment: 4 - -### Record members -- `symlink_follow`: `bool` -As long as the resolved path corresponds to a symbolic link, it is expanded. - -Bit: 0 - -## `oflags`: `Record` -Open flags used by `path_open`. - -Size: 2 - -Alignment: 2 - -### Record members -- `create`: `bool` -Create file if it does not exist. - -Bit: 0 - -- `directory`: `bool` -Fail if not a directory. - -Bit: 1 - -- `excl`: `bool` -Fail if file already exists. - -Bit: 2 - -- `trunc`: `bool` -Truncate file to size 0. - -Bit: 3 - -## `linkcount`: `u64` -Number of hard links to an inode. - -Size: 8 - -Alignment: 8 - -## `permissions`: `Record` -File permissions. This represents the permissions associated with a -file in a filesystem, and don't fully reflect all the conditions -which determine whether a given WASI program can access the file. - -Size: 1 - -Alignment: 1 - -### Record members -- `read`: `bool` -For files, permission to read the file. -For directories, permission to do [`readdir`](#readdir) and access files -within the directory. - -Note: This is similar to the read bit being set on files, and the -read *and* execute bits being set on directories, in POSIX. - -Bit: 0 - -- `write`: `bool` -For files, permission to mutate the file. -For directories, permission to create, remove, and rename items -within the directory. - -Bit: 1 - -- `execute`: `bool` -For files, permission to "execute" the file, using whatever -concept of "executing" the host filesystem has. -This flag is not valid for directories. - -Bit: 2 - -- `private`: `bool` -For filesystems which have a concept of multiple "users", this flag -indicates that the file is only accessible by the effective "user" -that the WASI store uses to access the filesystem, and inaccessible -to other "users". - -Bit: 3 - -## `filestat`: `Record` -File attributes. - -Size: 64 - -Alignment: 8 - -### Record members -- `dev`: [`device`](#device) -Device ID of device containing the file. - -Offset: 0 - -- `ino`: [`inode`](#inode) -File serial number. - -Offset: 8 - -- `filetype`: [`filetype`](#filetype) -File type. - -Offset: 16 - -- `permissions`: [`permissions`](#permissions) -File permissions. - -Offset: 17 - -- `nlink`: [`linkcount`](#linkcount) -Number of hard links to the file. - -Offset: 24 - -- `size`: [`filesize`](#filesize) -For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - -Offset: 32 - -- `atim`: [`timestamp`](#timestamp) -Last data access timestamp. - -Offset: 40 - -- `mtim`: [`timestamp`](#timestamp) -Last data modification timestamp. - -Offset: 48 - -- `ctim`: [`timestamp`](#timestamp) -Last file status change timestamp. - -Offset: 56 - -## `userdata`: `u64` -User-provided value that may be attached to objects that is retained when -extracted from the implementation. - -Size: 8 - -Alignment: 8 - -## `eventtype`: `Variant` -Type of a subscription to an event or its occurrence. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `clock` -The time value of clock [`subscription_clock::id`](#subscription_clock.id) has -reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - -- `fd_read` -File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has data -available for reading. This event always triggers for regular files. - -- `fd_write` -File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity -available for writing. This event always triggers for regular files. - -## `eventrwflags`: `Record` -The state of the file descriptor subscribed to with -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 2 - -Alignment: 2 - -### Record members -- `fd_readwrite_hangup`: `bool` -The peer of this socket has closed or disconnected. - -Bit: 0 - -## `event_fd_readwrite`: `Record` -The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). - -Size: 16 - -Alignment: 8 - -### Record members -- `nbytes`: [`filesize`](#filesize) -The number of bytes available for reading or writing. - -Offset: 0 - -- `flags`: [`eventrwflags`](#eventrwflags) -The state of the file descriptor. - -Offset: 8 - -## `event_u`: `Variant` -The contents of an [`event`](#event). - -Size: 24 - -Alignment: 8 - -### Variant Layout -- size: 24 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock` - -- `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) - -- `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) - -## `event`: `Record` -An event that occurred. - -Size: 40 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). - -Offset: 0 - -- `error`: [`errno`](#errno) -If non-zero, an error that occurred while processing the subscription request. - -Offset: 8 - -- `u`: [`event_u`](#event_u) -The type of the event that occurred, and the contents of the event - -Offset: 16 - -## `subclockflags`: `Record` -Flags determining how to interpret the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout). - -Size: 2 - -Alignment: 2 - -### Record members -- `subscription_clock_abstime`: `bool` -If set, treat the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock -[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp -provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the -current time value of clock [`subscription_clock::id`](#subscription_clock.id). - -Bit: 0 - -## `subscription_clock`: `Record` -The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). - -Size: 32 - -Alignment: 8 - -### Record members -- `id`: [`clockid`](#clockid) -The clock against which to compare the timestamp. - -Offset: 0 - -- `timeout`: [`timestamp`](#timestamp) -The absolute or relative timestamp. - -Offset: 8 - -- `precision`: [`timestamp`](#timestamp) -The amount of time that the implementation may wait additionally -to coalesce with other events. - -Offset: 16 - -- `flags`: [`subclockflags`](#subclockflags) -Flags specifying whether the timeout is absolute or relative - -Offset: 24 - -## `subscription_fd_readwrite`: `Record` -The contents of a [`subscription`](#subscription) when type is type is -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 4 - -Alignment: 4 - -### Record members -- `fd`: [`fd`](#fd) -The file descriptor on which to wait for it to become ready for reading or writing. - -Offset: 0 - -## `subscription_u`: `Variant` -The contents of a [`subscription`](#subscription). - -Size: 40 - -Alignment: 8 - -### Variant Layout -- size: 40 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock`: [`subscription_clock`](#subscription_clock) - -- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -## `subscription`: `Record` -Subscription to an event. - -Size: 48 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that is attached to the subscription in the -implementation and returned through [`event::userdata`](#event.userdata). - -Offset: 0 - -- `u`: [`subscription_u`](#subscription_u) -The type of the event to which to subscribe, and the contents of the subscription. - -Offset: 8 - -## `exitcode`: `u8` -Exit code generated by a program when exiting. - -Size: 1 - -Alignment: 1 - -### Constants -- `success` - -- `failure` - -## `riflags`: `Record` -Flags provided to `sock_recv`. - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_peek`: `bool` -Returns the message without removing it from the socket's receive queue. - -Bit: 0 - -- `recv_waitall`: `bool` -On byte-stream sockets, block until the full amount of data can be returned. - -Bit: 1 - -## `roflags`: `Record` -Flags returned by `sock_recv`. - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_data_truncated`: `bool` -Returned by `sock_recv`: Message data has been truncated. - -Bit: 0 - -## `siflags`: `u16` -Flags provided to `sock_send`. As there are currently no flags -defined, it must be set to zero. - -Size: 2 - -Alignment: 2 - -## `sdflags`: `Record` -Which channels on a socket to shut down. - -Size: 1 - -Alignment: 1 - -### Record members -- `rd`: `bool` -Disables further receive operations. - -Bit: 0 - -- `wr`: `bool` -Disables further send operations. - -Bit: 1 - -## `preopentype`: `Variant` -Identifiers for preopened capabilities. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `dir` -A pre-opened directory. - -## `prestat_dir`: `Record` -The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). - -Size: 4 - -Alignment: 4 - -### Record members -- `pr_name_len`: [`size`](#size) -The length of the directory name for use with `fd_prestat_dir_name`. - -Offset: 0 - -## `prestat`: `Variant` -Information about a pre-opened capability. - -Size: 8 - -Alignment: 4 - -### Variant Layout -- size: 8 -- align: 4 -- tag_size: 1 -### Variant cases -- `dir`: [`prestat_dir`](#prestat_dir) -When type is [`preopentype::dir`](#preopentype.dir): - -# Modules -## wasi_ephemeral_args -### Imports -#### Memory -### Functions - ---- - -#### `get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` -Read command-line argument data. -The size of the array should match that returned by [`sizes_get`](#sizes_get). -Each argument is expected to be `\0` terminated. - -##### Params -- `argv`: `Pointer>` - -- `argv_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sizes_get() -> Result<(size, size), errno>` -Return command-line argument data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of arguments and the size of the argument string -data, or an error. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_clock -### Imports -#### Memory -### Functions - ---- - -#### `res_get(id: clockid) -> Result` -Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, -return [`errno::inval`](#errno.inval). -Note: This is similar to `clock_getres` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the resolution. - -##### Results -- `error`: `Result` -The resolution of the clock. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `time_get(id: clockid, precision: timestamp) -> Result` -Return the time value of a clock. -Note: This is similar to `clock_gettime` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the time. - -- `precision`: [`timestamp`](#timestamp) -The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - -##### Results -- `error`: `Result` -The time value of the clock. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_environ -### Imports -#### Memory -### Functions - ---- - -#### `get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` -Read environment variable data. -The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). -Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - -##### Params -- `environ`: `Pointer>` - -- `environ_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sizes_get() -> Result<(size, size), errno>` -Return environment variable data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of environment variable arguments and the size of the -environment variable data. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_fd -### Imports -#### Memory -### Functions - ---- - -#### `advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` -Provide file advisory information on a file descriptor. -Note: This is similar to `posix_fadvise` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset within the file to which the advisory applies. - -- `len`: [`filesize`](#filesize) -The length of the region to which the advisory applies. - -- `advice`: [`advice`](#advice) -The advice. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` -Force the allocation of space in a file. -Note: This is similar to `posix_fallocate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset at which to start the allocation. - -- `len`: [`filesize`](#filesize) -The length of the area that is allocated. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `close(fd: fd) -> Result<(), errno>` -Close a file descriptor. -Note: This is similar to [`close`](#close) in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `datasync(fd: fd) -> Result<(), errno>` -Synchronize the data of a file to disk. -Note: This is similar to `fdatasync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fdstat_get(fd: fd) -> Result` -Get the attributes of a file descriptor. -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file descriptor's attributes are stored. - -###### Variant Layout -- size: 32 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`fdstat`](#fdstat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` -Adjust the flags associated with a file descriptor. -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`fdflags`](#fdflags) -The desired values of the file descriptor flags. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` -Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights - -##### Params -- `fd`: [`fd`](#fd) - -- `fs_rights_base`: [`rights`](#rights) -The desired rights of the file descriptor. - -- `fs_rights_inheriting`: [`rights`](#rights) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_get(fd: fd) -> Result` -Return the attributes of an open file. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 72 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` -Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. -Note: This is similar to `ftruncate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `size`: [`filesize`](#filesize) -The desired file size. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of an open file or directory. -Note: This is similar to `futimens` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `permissions_set(fd: fd, permissions: permissions) -> Result<(), errno>` -Set the permissions of a file or directory. - -This sets the permissions associated with a file or directory in -a filesystem at the time it is called. The ability to actually access -a file or directory may depend on additional permissions not reflected -here. - -Note: This is similar `fchmod` in POSIX. - -Unlike POSIX, this doesn't expose a user/group/other distinction; -implementations in POSIX environments are suggested to consult the -umask to determine which of the user/group/other flags to modify. - -##### Params -- `fd`: [`fd`](#fd) - -- `permissions`: [`permissions`](#permissions) -The permissions associated with the file. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` -Read from a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `preadv` in Linux (and other Unix-es). - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors in which to store data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to read. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `prestat_get(fd: fd) -> Result` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the description is stored. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`prestat`](#prestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `Pointer` -A buffer into which to write the preopened directory name. - -- `path_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` -Write to a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `pwritev` in Linux (and other Unix-es). - -Like Linux (and other Unix-es), any calls of [`pwrite`](#pwrite) (and other -functions to read or write) for a regular file by other threads in the -WASI process should not be interleaved while [`pwrite`](#pwrite) is executed. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to write. - -##### Results -- `error`: `Result` -The number of bytes written. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `read(fd: fd, iovs: iovec_array) -> Result` -Read from a file descriptor. -Note: This is similar to `readv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` -Read directory entries from a directory. -When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a [`dirent`](#dirent) object, -followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory -entry. -This function fills the output buffer as much as possible, potentially -truncating the last directory entry. This allows the caller to grow its -read buffer size in case it's too small to fit a single large directory -entry, or skip the oversized directory entry. - -##### Params -- `fd`: [`fd`](#fd) - -- `buf`: `Pointer` -The buffer where directory entries are stored - -- `buf_len`: [`size`](#size) - -- `cookie`: [`dircookie`](#dircookie) -The location within the directory to start reading - -##### Results -- `error`: `Result` -The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `renumber(fd: fd, to: fd) -> Result<(), errno>` -Atomically replace a file descriptor by renumbering another file descriptor. -Due to the strong focus on thread safety, this environment does not provide -a mechanism to duplicate or renumber a file descriptor to an arbitrary -number, like `dup2()`. This would be prone to race conditions, as an actual -file descriptor with the same number could be allocated by a different -thread at the same time. -This function provides a way to atomically renumber file descriptors, which -would disappear if `dup2()` were to be removed entirely. - -##### Params -- `fd`: [`fd`](#fd) - -- `to`: [`fd`](#fd) -The file descriptor to overwrite. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `seek(fd: fd, offset: filedelta, whence: whence) -> Result` -Move the offset of a file descriptor. -Note: This is similar to `lseek` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filedelta`](#filedelta) -The number of bytes to move. - -- `whence`: [`whence`](#whence) -The base from which the offset is relative. - -##### Results -- `error`: `Result` -The new offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `sync(fd: fd) -> Result<(), errno>` -Synchronize the data and metadata of a file to disk. -Note: This is similar to `fsync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `tell(fd: fd) -> Result` -Return the current offset of a file descriptor. -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The current offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `write(fd: fd, iovs: ciovec_array) -> Result` -Write to a file descriptor. -Note: This is similar to `writev` in POSIX. - -Like POSIX, any calls of [`write`](#write) (and other functions to read or write) -for a regular file by other threads in the WASI process should not be -interleaved while [`write`](#write) is executed. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -##### Results -- `error`: `Result` -The number of bytes written. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_path -### Imports -#### Memory -### Functions - ---- - -#### `create_directory(fd: fd, path: string) -> Result<(), errno>` -Create a directory. -Note: This is similar to `mkdirat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path at which to create the directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` -Return the attributes of a file or directory. -Note: This is similar to `stat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to inspect. - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 72 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of a file or directory. -Note: This is similar to `utimensat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to operate on. - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `permissions_set(fd: fd, flags: lookupflags, path: string, permissions: permissions) -> Result<(), errno>` -Set the permissions of a file or directory. - -This sets the permissions associated with a file or directory in -a filesystem at the time it is called. The ability to actually access -a file or directory may depend on additional permissions not reflected -here. - -Note: This is similar to `fchmodat` in POSIX. - -Unlike POSIX, this doesn't expose a user/group/other distinction; -implementations in POSIX environments are suggested to consult the -umask to determine which of the user/group/other flags to modify. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path to a file to query. - -- `permissions`: [`permissions`](#permissions) -The permissions to associate with the file. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Create a hard link. -Note: This is similar to `linkat` in POSIX. - -##### Params -- `old_fd`: [`fd`](#fd) - -- `old_flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `old_path`: `string` -The source path from which to link. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path at which to create the hard link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, permissions: permissions) -> Result` -Open a file or directory. -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since this -is error-prone in multi-threaded contexts. The returned file descriptor is -guaranteed to be less than 2**31. -Note: This is similar to `openat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `dirflags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The relative path of the file or directory to open, relative to the -[`fd`](#fd) directory. - -- `oflags`: [`oflags`](#oflags) -The method by which to open the file. - -- `fs_rights_base`: [`rights`](#rights) -The initial rights of the newly created file descriptor. The -implementation is allowed to return a file descriptor with fewer rights -than specified, if and only if those rights do not apply to the type of -file being opened. -The *base* rights are rights that will apply to operations using the file -descriptor itself, while the *inheriting* rights are rights that apply to -file descriptors derived from it. - -- `fs_rights_inheriting`: [`rights`](#rights) - -- `fdflags`: [`fdflags`](#fdflags) - -- `permissions`: [`permissions`](#permissions) -If a file is created, the filesystem permissions to associate with it. - -##### Results -- `error`: `Result` -The file descriptor of the file that has been opened. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`fd`](#fd) - -- `err`: [`errno`](#errno) - - ---- - -#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` -Read the contents of a symbolic link. -Note: This is similar to `readlinkat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path of the symbolic link from which to read. - -- `buf`: `Pointer` -The buffer to which to write the contents of the symbolic link. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result` -The number of bytes placed in the buffer. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `remove_directory(fd: fd, path: string) -> Result<(), errno>` -Remove a directory. -Return [`errno::notempty`](#errno.notempty) if the directory is not empty. -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a directory to remove. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Rename a file or directory. -Note: This is similar to `renameat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `old_path`: `string` -The source path of the file or directory to rename. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path to which to rename the file or directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` -Create a symbolic link. -Note: This is similar to `symlinkat` in POSIX. - -##### Params -- `old_path`: `string` -The contents of the symbolic link. - -- `fd`: [`fd`](#fd) - -- `new_path`: `string` -The destination path at which to create the symbolic link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `unlink_file(fd: fd, path: string) -> Result<(), errno>` -Unlink a file. -Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a file to unlink. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_poll -### Imports -#### Memory -### Functions - ---- - -#### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` -Concurrently poll for the occurrence of a set of events. - -If `nsubscriptions` is 0, returns [`errno::inval`](#errno.inval). - -##### Params -- `in`: `ConstPointer` -The events to which to subscribe. - -- `out`: `Pointer` -The events that have occurred. - -- `nsubscriptions`: [`size`](#size) -Both the number of subscriptions and events. - -##### Results -- `error`: `Result` -The number of events stored. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_proc -### Imports -### Functions - ---- - -#### `exit(rval: exitcode)` -Terminate the process normally. An exit code of `$exitcode::success` -reports successful completion of the program. An exit code of -`$exitcode::failure` or any other value less than 126 reports a -failure, and the value is provided to the environment. If a value -of 126 or greater is given, this function behaves as if it were -implemented by an `unreachable` instruction. - -##### Params -- `rval`: [`exitcode`](#exitcode) -The exit code returned by the process. - -##### Results -## wasi_ephemeral_random -### Imports -#### Memory -### Functions - ---- - -#### `get(buf: Pointer, buf_len: size) -> Result<(), errno>` -Write high-quality random data into a buffer. -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. -This function may execute slowly, so when large mounts of random data are -required, it's advisable to use this function to seed a pseudo-random -number generator, rather than to provide the random data directly. - -##### Params -- `buf`: `Pointer` -The buffer to fill with random data. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_sched -### Imports -### Functions - ---- - -#### `yield() -> Result<(), errno>` -Temporarily yield execution of the calling thread. -Note: This is similar to [`yield`](#yield) in POSIX. - -##### Params -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_sock -### Imports -#### Memory -### Functions - ---- - -#### `recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` -Receive a message from a socket. -Note: This is similar to [`recv`](#recv) in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -##### Params -- `fd`: [`fd`](#fd) - -- `ri_data`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -- `ri_flags`: [`riflags`](#riflags) -Message flags. - -##### Results -- `error`: `Result<(size, roflags), errno>` -Number of bytes stored in ri_data and message flags. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, roflags)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`roflags`](#roflags) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` -Send a message on a socket. -Note: This is similar to [`send`](#send) in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -##### Params -- `fd`: [`fd`](#fd) - -- `si_data`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors to which to retrieve data - -- `si_flags`: [`siflags`](#siflags) -Message flags. - -##### Results -- `error`: `Result` -Number of bytes transmitted. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `shutdown(fd: fd, how: sdflags) -> Result<(), errno>` -Shut down socket send and receive channels. -Note: This is similar to [`shutdown`](#shutdown) in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `how`: [`sdflags`](#sdflags) -Which channels on the socket to shut down. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - diff --git a/proposals/clocks/phases/ephemeral/witx/typenames.witx b/proposals/clocks/phases/ephemeral/witx/typenames.witx deleted file mode 100644 index bbd6489df..000000000 --- a/proposals/clocks/phases/ephemeral/witx/typenames.witx +++ /dev/null @@ -1,708 +0,0 @@ -;; Type names used by low-level WASI interfaces. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -;;; An array size. -;;; -;;; Note: This is similar to `size_t` in POSIX. -(typename $size (@witx usize)) - -;;; Non-negative file size or length of a region within a file. -(typename $filesize u64) - -;;; Timestamp in nanoseconds. -(typename $timestamp u64) - -;;; Identifiers for clocks. -(typename $clockid - (enum (@witx tag u32) - ;;; The clock measuring real time. Time value zero corresponds with - ;;; 1970-01-01T00:00:00Z. - $realtime - ;;; The store-wide monotonic clock, which is defined as a clock measuring - ;;; real time, whose value cannot be adjusted and which cannot have negative - ;;; clock jumps. The epoch of this clock is undefined. The absolute time - ;;; value of this clock therefore has no meaning. - $monotonic - ) -) - -;;; Error codes returned by functions. -;;; Not all of these error codes are returned by the functions provided by this -;;; API; some are used in higher-level library layers, and others are provided -;;; merely for alignment with POSIX. -(typename $errno - (enum (@witx tag u16) - ;;; No error occurred. System call completed successfully. - $success - ;;; Argument list too long. - $2big - ;;; Permission denied. - $access - ;;; Address in use. - $addrinuse - ;;; Address not available. - $addrnotavail - ;;; Address family not supported. - $afnosupport - ;;; Resource unavailable, or operation would block. - $again - ;;; Connection already in progress. - $already - ;;; Bad file descriptor. - $badf - ;;; Bad message. - $badmsg - ;;; Device or resource busy. - $busy - ;;; Operation canceled. - $canceled - ;;; No child processes. - $child - ;;; Connection aborted. - $connaborted - ;;; Connection refused. - $connrefused - ;;; Connection reset. - $connreset - ;;; Resource deadlock would occur. - $deadlk - ;;; Destination address required. - $destaddrreq - ;;; Mathematics argument out of domain of function. - $dom - ;;; Reserved. - $dquot - ;;; File exists. - $exist - ;;; Bad address. - $fault - ;;; File too large. - $fbig - ;;; Host is unreachable. - $hostunreach - ;;; Identifier removed. - $idrm - ;;; Illegal byte sequence. - $ilseq - ;;; Operation in progress. - $inprogress - ;;; Interrupted function. - $intr - ;;; Invalid argument. - $inval - ;;; I/O error. - $io - ;;; Socket is connected. - $isconn - ;;; Is a directory. - $isdir - ;;; Too many levels of symbolic links. - $loop - ;;; File descriptor value too large. - $mfile - ;;; Too many links. - $mlink - ;;; Message too large. - $msgsize - ;;; Reserved. - $multihop - ;;; Filename too long. - $nametoolong - ;;; Network is down. - $netdown - ;;; Connection aborted by network. - $netreset - ;;; Network unreachable. - $netunreach - ;;; Too many files open in system. - $nfile - ;;; No buffer space available. - $nobufs - ;;; No such device. - $nodev - ;;; No such file or directory. - $noent - ;;; Executable file format error. - $noexec - ;;; No locks available. - $nolck - ;;; Reserved. - $nolink - ;;; Not enough space. - $nomem - ;;; No message of the desired type. - $nomsg - ;;; Protocol not available. - $noprotoopt - ;;; No space left on device. - $nospc - ;;; Function not supported. - $nosys - ;;; The socket is not connected. - $notconn - ;;; Not a directory or a symbolic link to a directory. - $notdir - ;;; Directory not empty. - $notempty - ;;; State not recoverable. - $notrecoverable - ;;; Not a socket. - $notsock - ;;; Not supported, or operation not supported on socket. - $notsup - ;;; Inappropriate I/O control operation. - $notty - ;;; No such device or address. - $nxio - ;;; Value too large to be stored in data type. - $overflow - ;;; Previous owner died. - $ownerdead - ;;; Operation not permitted. - $perm - ;;; Broken pipe. - $pipe - ;;; Protocol error. - $proto - ;;; Protocol not supported. - $protonosupport - ;;; Protocol wrong type for socket. - $prototype - ;;; Result too large. - $range - ;;; Read-only file system. - $rofs - ;;; Invalid seek. - $spipe - ;;; No such process. - $srch - ;;; Reserved. - $stale - ;;; Connection timed out. - $timedout - ;;; Text file busy. - $txtbsy - ;;; Cross-device link. - $xdev - ;;; Extension: Capabilities insufficient. - $notcapable - ) -) - -;;; File descriptor rights, determining which actions may be performed. -(typename $rights - (flags (@witx repr u64) - ;;; The right to invoke `fd_datasync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::dsync`. - $fd_datasync - ;;; The right to invoke `fd_read` and `sock_recv`. - ;; - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. - $fd_read - ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. - $fd_seek - ;;; The right to invoke `fd_fdstat_set_flags`. - $fd_fdstat_set_flags - ;;; The right to invoke `fd_sync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. - $fd_sync - ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to - ;;; invoke `fd_tell`. - $fd_tell - ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. - $fd_write - ;;; The right to invoke `fd_advise`. - $fd_advise - ;;; The right to invoke `fd_allocate`. - $fd_allocate - ;;; The right to invoke `path_create_directory`. - $path_create_directory - ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::create`. - $path_create_file - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; source directory. - $path_link_source - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; target directory. - $path_link_target - ;;; The right to invoke `path_open`. - $path_open - ;;; The right to invoke `fd_readdir`. - $fd_readdir - ;;; The right to invoke `path_readlink`. - $path_readlink - ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $path_rename_source - ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $path_rename_target - ;;; The right to invoke `path_filestat_get`. - $path_filestat_get - ;;; The right to change a file's size. - ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. - ;;; Note: there is no function named `path_filestat_set_size`. This follows POSIX design, - ;;; which only has `ftruncate` and does not provide `ftruncateat`. - ;;; While such function would be desirable from the API design perspective, there are virtually - ;;; no use cases for it since no code written for POSIX systems would use it. - ;;; Moreover, implementing it would require multiple syscalls, leading to inferior performance. - $path_filestat_set_size - ;;; The right to invoke `path_filestat_set_times`. - $path_filestat_set_times - ;;; The right to invoke `path_permissions_set`. - $path_permissions_set - ;;; The right to invoke `fd_filestat_get`. - $fd_filestat_get - ;;; The right to invoke `fd_filestat_set_size`. - $fd_filestat_set_size - ;;; The right to invoke `fd_filestat_set_times`. - $fd_filestat_set_times - ;;; The right to invoke `fd_permissions_set`. - $fd_permissions_set - ;;; The right to invoke `path_symlink`. - $path_symlink - ;;; The right to invoke `path_remove_directory`. - $path_remove_directory - ;;; The right to invoke `path_unlink_file`. - $path_unlink_file - ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. - ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. - $poll_fd_readwrite - ;;; The right to invoke `sock_shutdown`. - $sock_shutdown - ) -) - -;;; A file descriptor handle. -(typename $fd (handle)) - -;;; A region of memory for scatter/gather reads. -(typename $iovec - (record - ;;; The address of the buffer to be filled. - (field $buf (@witx pointer u8)) - ;;; The length of the buffer to be filled. - (field $buf_len $size) - ) -) - -;;; A region of memory for scatter/gather writes. -(typename $ciovec - (record - ;;; The address of the buffer to be written. - (field $buf (@witx const_pointer u8)) - ;;; The length of the buffer to be written. - (field $buf_len $size) - ) -) - -(typename $iovec_array (list $iovec)) -(typename $ciovec_array (list $ciovec)) - -;;; Relative offset within a file. -(typename $filedelta s64) - -;;; The position relative to which to set the offset of the file descriptor. -(typename $whence - (enum (@witx tag u8) - ;;; Seek relative to start-of-file. - $set - ;;; Seek relative to current position. - $cur - ;;; Seek relative to end-of-file. - $end - ) -) - -;;; A reference to the offset of a directory entry. -(typename $dircookie u64) - -;;; In an `fd_readdir` call, this value signifies the start of the directory. -(@witx const $dircookie $start 0) - -;;; The type for the `dirent::d_namlen` field of `dirent`. -(typename $dirnamlen u32) - -;;; File serial number that is unique within its file system. -(typename $inode u64) - -;;; The type of a file descriptor or file. -(typename $filetype - (enum (@witx tag u8) - ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $unknown - ;;; The file descriptor or file refers to a block device inode. - $block_device - ;;; The file descriptor or file refers to a character device inode. - $character_device - ;;; The file descriptor or file refers to a directory inode. - $directory - ;;; The file descriptor or file refers to a regular file inode. - $regular_file - ;;; The file descriptor or file refers to a datagram socket. - $socket_dgram - ;;; The file descriptor or file refers to a byte-stream socket. - $socket_stream - ;;; The file refers to a symbolic link inode. - $symbolic_link - ;;; The file descriptor or file refers to a FIFO. - $fifo - ) -) - -;;; A directory entry. -(typename $dirent - (record - ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie) - ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode) - ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) - ) -) - -;;; File or memory access pattern advisory information. -(typename $advice - (enum (@witx tag u8) - ;;; The application has no advice to give on its behavior with respect to the specified data. - $normal - ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $sequential - ;;; The application expects to access the specified data in a random order. - $random - ;;; The application expects to access the specified data in the near future. - $willneed - ;;; The application expects that it will not access the specified data in the near future. - $dontneed - ;;; The application expects to access the specified data once and then not reuse it thereafter. - $noreuse - ) -) - -;;; File descriptor flags. -(typename $fdflags - (flags (@witx repr u16) - ;;; Append mode: Data written to the file is always appended to the file's end. - $append - ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $dsync - ;;; Non-blocking mode. - $nonblock - ;;; Synchronized read I/O operations. - $rsync - ;;; Write according to synchronized I/O file integrity completion. In - ;;; addition to synchronizing the data stored in the file, the implementation - ;;; may also synchronously update the file's metadata. - $sync - ) -) - -;;; File descriptor attributes. -(typename $fdstat - (record - ;;; File type. - (field $fs_filetype $filetype) - ;;; File descriptor flags. - (field $fs_flags $fdflags) - ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights) - ;;; Maximum set of rights that may be installed on new file descriptors that - ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights) - ) -) - -;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode` to uniquely identify a file or directory in the filesystem. -(typename $device u64) - -;;; Which file time attributes to adjust. -(typename $fstflags - (flags (@witx repr u16) - ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. - $atim - ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. - $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. - $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. - $mtim_now - ) -) - -;;; Flags determining the method of how paths are resolved. -(typename $lookupflags - (flags (@witx repr u32) - ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $symlink_follow - ) -) - -;;; Open flags used by `path_open`. -(typename $oflags - (flags (@witx repr u16) - ;;; Create file if it does not exist. - $create - ;;; Fail if not a directory. - $directory - ;;; Fail if file already exists. - $excl - ;;; Truncate file to size 0. - $trunc - ) -) - -;;; Number of hard links to an inode. -(typename $linkcount u64) - -;;; File permissions. This represents the permissions associated with a -;;; file in a filesystem, and don't fully reflect all the conditions -;;; which determine whether a given WASI program can access the file. -(typename $permissions - (flags (@witx repr u8) - ;;; For files, permission to read the file. - ;;; For directories, permission to do `readdir` and access files - ;;; within the directory. - ;;; - ;;; Note: This is similar to the read bit being set on files, and the - ;;; read *and* execute bits being set on directories, in POSIX. - $read - - ;;; For files, permission to mutate the file. - ;;; For directories, permission to create, remove, and rename items - ;;; within the directory. - $write - - ;;; For files, permission to "execute" the file, using whatever - ;;; concept of "executing" the host filesystem has. - ;;; This flag is not valid for directories. - $execute - - ;;; For filesystems which have a concept of multiple "users", this flag - ;;; indicates that the file is only accessible by the effective "user" - ;;; that the WASI store uses to access the filesystem, and inaccessible - ;;; to other "users". - $private - ) -) - -;;; File attributes. -(typename $filestat - (record - ;;; Device ID of device containing the file. - (field $dev $device) - ;;; File serial number. - (field $ino $inode) - ;;; File type. - (field $filetype $filetype) - ;;; File permissions. - (field $permissions $permissions) - ;;; Number of hard links to the file. - (field $nlink $linkcount) - ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $size $filesize) - ;;; Last data access timestamp. - (field $atim $timestamp) - ;;; Last data modification timestamp. - (field $mtim $timestamp) - ;;; Last file status change timestamp. - (field $ctim $timestamp) - ) -) - -;;; User-provided value that may be attached to objects that is retained when -;;; extracted from the implementation. -(typename $userdata u64) - -;;; Type of a subscription to an event or its occurrence. -(typename $eventtype - (enum (@witx tag u8) - ;;; The time value of clock `subscription_clock::id` has - ;;; reached timestamp `subscription_clock::timeout`. - $clock - ;;; File descriptor `subscription_fd_readwrite::fd` has data - ;;; available for reading. This event always triggers for regular files. - $fd_read - ;;; File descriptor `subscription_fd_readwrite::fd` has capacity - ;;; available for writing. This event always triggers for regular files. - $fd_write - ) -) - -;;; The state of the file descriptor subscribed to with -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $eventrwflags - (flags (@witx repr u16) - ;;; The peer of this socket has closed or disconnected. - $fd_readwrite_hangup - ) -) - -;;; The contents of an `event` when type is `eventtype::fd_read` or -;;; `eventtype::fd_write`. -(typename $event_fd_readwrite - (record - ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize) - ;;; The state of the file descriptor. - (field $flags $eventrwflags) - ) -) - -;;; The contents of an `event`. -(typename $event_u - (variant (@witx tag $eventtype) - (case $fd_read $event_fd_readwrite) - (case $fd_write $event_fd_readwrite) - (case $clock) - ) -) - -;;; An event that occurred. -(typename $event - (record - ;;; User-provided value that got attached to `subscription::userdata`. - (field $userdata $userdata) - ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno) - ;;; The type of the event that occurred, and the contents of the event - (field $u $event_u) - ) -) - -;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_clock::timeout`. -(typename $subclockflags - (flags (@witx repr u16) - ;;; If set, treat the timestamp provided in - ;;; `subscription_clock::timeout` as an absolute timestamp of clock - ;;; `subscription_clock::id`. If clear, treat the timestamp - ;;; provided in `subscription_clock::timeout` relative to the - ;;; current time value of clock `subscription_clock::id`. - $subscription_clock_abstime - ) -) - -;;; The contents of a `subscription` when type is `eventtype::clock`. -(typename $subscription_clock - (record - ;;; The clock against which to compare the timestamp. - (field $id $clockid) - ;;; The absolute or relative timestamp. - (field $timeout $timestamp) - ;;; The amount of time that the implementation may wait additionally - ;;; to coalesce with other events. - (field $precision $timestamp) - ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags) - ) -) - -;;; The contents of a `subscription` when type is type is -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $subscription_fd_readwrite - (record - ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $fd $fd) - ) -) - -;;; The contents of a `subscription`. -(typename $subscription_u - (union (@witx tag $eventtype) - $subscription_clock - $subscription_fd_readwrite - $subscription_fd_readwrite - ) -) - -;;; Subscription to an event. -(typename $subscription - (record - ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event::userdata`. - (field $userdata $userdata) - ;;; The type of the event to which to subscribe, and the contents of the subscription. - (field $u $subscription_u) - ) -) - -;;; Exit code generated by a program when exiting. -(typename $exitcode u8) - -;;; Indicate the program exited successfully. -;;; -;;; Note: This is similar to `EXIT_SUCCESS` in POSIX. -(@witx const $exitcode $success 0) - -;;; Indicate the program exited unsuccessfully. -;;; -;;; Note: This is similar to `EXIT_FAILURE` in POSIX. -(@witx const $exitcode $failure 1) - -;;; Flags provided to `sock_recv`. -(typename $riflags - (flags (@witx repr u16) - ;;; Returns the message without removing it from the socket's receive queue. - $recv_peek - ;;; On byte-stream sockets, block until the full amount of data can be returned. - $recv_waitall - ) -) - -;;; Flags returned by `sock_recv`. -(typename $roflags - (flags (@witx repr u16) - ;;; Returned by `sock_recv`: Message data has been truncated. - $recv_data_truncated - ) -) - -;;; Flags provided to `sock_send`. As there are currently no flags -;;; defined, it must be set to zero. -(typename $siflags u16) - -;;; Which channels on a socket to shut down. -(typename $sdflags - (flags (@witx repr u8) - ;;; Disables further receive operations. - $rd - ;;; Disables further send operations. - $wr - ) -) - -;;; Identifiers for preopened capabilities. -(typename $preopentype - (enum (@witx tag u8) - ;;; A pre-opened directory. - $dir - ) -) - -;;; The contents of a `prestat` when its type is `preopentype::dir`. -(typename $prestat_dir - (record - ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size) - ) -) - -;;; Information about a pre-opened capability. -(typename $prestat - (union (@witx tag $preopentype) - ;;; When type is `preopentype::dir`: - $prestat_dir - ) -) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx deleted file mode 100644 index bb956fc53..000000000 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ /dev/null @@ -1,27 +0,0 @@ -;; WASI Command-line Arguments. -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_args - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `sizes_get`. - ;;; Each argument is expected to be `\0` terminated. - (@interface func (export "get") - (param $argv (@witx pointer (@witx pointer (@witx char8)))) - (param $argv_buf (@witx pointer (@witx char8))) - (result $error (expected (error $errno))) - ) - - ;;; Return command-line argument data sizes. - (@interface func (export "sizes_get") - ;;; Returns the number of arguments and the size of the argument string - ;;; data, or an error. - (result $error (expected (tuple $size $size) (error $errno))) - ) -) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx deleted file mode 100644 index a980529f8..000000000 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_clock.witx +++ /dev/null @@ -1,35 +0,0 @@ -;; WASI Clocks. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_clock - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, - ;;; return `errno::inval`. - ;;; Note: This is similar to `clock_getres` in POSIX. - (@interface func (export "res_get") - ;;; The clock for which to return the resolution. - (param $id $clockid) - ;;; The resolution of the clock. - (result $error (expected $timestamp (error $errno))) - ) - - ;;; Return the time value of a clock. - ;;; Note: This is similar to `clock_gettime` in POSIX. - (@interface func (export "time_get") - ;;; The clock for which to return the time. - (param $id $clockid) - ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp) - ;;; The time value of the clock. - (result $error (expected $timestamp (error $errno))) - ) -) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx deleted file mode 100644 index ef1c20b22..000000000 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ /dev/null @@ -1,27 +0,0 @@ -;; WASI Environment Variables. -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_environ - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `sizes_get`. - ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - (@interface func (export "get") - (param $environ (@witx pointer (@witx pointer (@witx char8)))) - (param $environ_buf (@witx pointer (@witx char8))) - (result $error (expected (error $errno))) - ) - - ;;; Return environment variable data sizes. - (@interface func (export "sizes_get") - ;;; Returns the number of environment variable arguments and the size of the - ;;; environment variable data. - (result $error (expected (tuple $size $size) (error $errno))) - ) -) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx deleted file mode 100644 index 979e9a333..000000000 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ /dev/null @@ -1,259 +0,0 @@ -;; WASI I/O. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_fd - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Provide file advisory information on a file descriptor. - ;;; Note: This is similar to `posix_fadvise` in POSIX. - (@interface func (export "advise") - (param $fd $fd) - ;;; The offset within the file to which the advisory applies. - (param $offset $filesize) - ;;; The length of the region to which the advisory applies. - (param $len $filesize) - ;;; The advice. - (param $advice $advice) - (result $error (expected (error $errno))) - ) - - ;;; Force the allocation of space in a file. - ;;; Note: This is similar to `posix_fallocate` in POSIX. - (@interface func (export "allocate") - (param $fd $fd) - ;;; The offset at which to start the allocation. - (param $offset $filesize) - ;;; The length of the area that is allocated. - (param $len $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Close a file descriptor. - ;;; Note: This is similar to `close` in POSIX. - (@interface func (export "close") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Synchronize the data of a file to disk. - ;;; Note: This is similar to `fdatasync` in POSIX. - (@interface func (export "datasync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Get the attributes of a file descriptor. - ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (@interface func (export "fdstat_get") - (param $fd $fd) - ;;; The buffer where the file descriptor's attributes are stored. - (result $error (expected $fdstat (error $errno))) - ) - - ;;; Adjust the flags associated with a file descriptor. - ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (@interface func (export "fdstat_set_flags") - (param $fd $fd) - ;;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights - (@interface func (export "fdstat_set_rights") - (param $fd $fd) - ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of an open file. - (@interface func (export "filestat_get") - (param $fd $fd) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;;; Note: This is similar to `ftruncate` in POSIX. - (@interface func (export "filestat_set_size") - (param $fd $fd) - ;;; The desired file size. - (param $size $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the timestamps of an open file or directory. - ;;; Note: This is similar to `futimens` in POSIX. - (@interface func (export "filestat_set_times") - (param $fd $fd) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Set the permissions of a file or directory. - ;;; - ;;; This sets the permissions associated with a file or directory in - ;;; a filesystem at the time it is called. The ability to actually access - ;;; a file or directory may depend on additional permissions not reflected - ;;; here. - ;;; - ;;; Note: This is similar `fchmod` in POSIX. - ;;; - ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; - ;;; implementations in POSIX environments are suggested to consult the - ;;; umask to determine which of the user/group/other flags to modify. - (@interface func (export "permissions_set") - (param $fd $fd) - ;;; The permissions associated with the file. - (param $permissions $permissions) - (result $error (expected (error $errno))) - ) - - ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in Linux (and other Unix-es). - (@interface func (export "pread") - (param $fd $fd) - ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_array) - ;;; The offset within the file at which to read. - (param $offset $filesize) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "prestat_get") - (param $fd $fd) - ;;; The buffer where the description is stored. - (result $error (expected $prestat (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "prestat_dir_name") - (param $fd $fd) - ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer (@witx char8))) - (param $path_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in Linux (and other Unix-es). - ;;; - ;;; Like Linux (and other Unix-es), any calls of `pwrite` (and other - ;;; functions to read or write) for a regular file by other threads in the - ;;; WASI process should not be interleaved while `pwrite` is executed. - (@interface func (export "pwrite") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The offset within the file at which to write. - (param $offset $filesize) - ;;; The number of bytes written. - (result $error (expected $size (error $errno))) - ) - - ;;; Read from a file descriptor. - ;;; Note: This is similar to `readv` in POSIX. - (@interface func (export "read") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_array) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Read directory entries from a directory. - ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a `dirent` object, - ;;; followed by `dirent::d_namlen` bytes holding the name of the directory - ;;; entry. - ;; - ;;; This function fills the output buffer as much as possible, potentially - ;;; truncating the last directory entry. This allows the caller to grow its - ;;; read buffer size in case it's too small to fit a single large directory - ;;; entry, or skip the oversized directory entry. - (@interface func (export "readdir") - (param $fd $fd) - ;;; The buffer where directory entries are stored - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The location within the directory to start reading - (param $cookie $dircookie) - ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $error (expected $size (error $errno))) - ) - - ;;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;;; Due to the strong focus on thread safety, this environment does not provide - ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;;; file descriptor with the same number could be allocated by a different - ;;; thread at the same time. - ;; - ;;; This function provides a way to atomically renumber file descriptors, which - ;;; would disappear if `dup2()` were to be removed entirely. - (@interface func (export "renumber") - (param $fd $fd) - ;;; The file descriptor to overwrite. - (param $to $fd) - (result $error (expected (error $errno))) - ) - - ;;; Move the offset of a file descriptor. - ;;; Note: This is similar to `lseek` in POSIX. - (@interface func (export "seek") - (param $fd $fd) - ;;; The number of bytes to move. - (param $offset $filedelta) - ;;; The base from which the offset is relative. - (param $whence $whence) - ;;; The new offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Synchronize the data and metadata of a file to disk. - ;;; Note: This is similar to `fsync` in POSIX. - (@interface func (export "sync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Return the current offset of a file descriptor. - ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (@interface func (export "tell") - (param $fd $fd) - ;;; The current offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Write to a file descriptor. - ;;; Note: This is similar to `writev` in POSIX. - ;;; - ;;; Like POSIX, any calls of `write` (and other functions to read or write) - ;;; for a regular file by other threads in the WASI process should not be - ;;; interleaved while `write` is executed. - (@interface func (export "write") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The number of bytes written. - (result $error (expected $size (error $errno))) - ) -) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx deleted file mode 100644 index 2901decb7..000000000 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ /dev/null @@ -1,181 +0,0 @@ -;; WASI Filesystem Path API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_path - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Create a directory. - ;;; Note: This is similar to `mkdirat` in POSIX. - (@interface func (export "create_directory") - (param $fd $fd) - ;;; The path at which to create the directory. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of a file or directory. - ;;; Note: This is similar to `stat` in POSIX. - (@interface func (export "filestat_get") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to inspect. - (param $path string) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the timestamps of a file or directory. - ;;; Note: This is similar to `utimensat` in POSIX. - (@interface func (export "filestat_set_times") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to operate on. - (param $path string) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Set the permissions of a file or directory. - ;;; - ;;; This sets the permissions associated with a file or directory in - ;;; a filesystem at the time it is called. The ability to actually access - ;;; a file or directory may depend on additional permissions not reflected - ;;; here. - ;;; - ;;; Note: This is similar to `fchmodat` in POSIX. - ;;; - ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; - ;;; implementations in POSIX environments are suggested to consult the - ;;; umask to determine which of the user/group/other flags to modify. - (@interface func (export "permissions_set") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path to a file to query. - (param $path string) - ;;; The permissions to associate with the file. - (param $permissions $permissions) - (result $error (expected (error $errno))) - ) - - ;;; Create a hard link. - ;;; Note: This is similar to `linkat` in POSIX. - (@interface func (export "link") - (param $old_fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags) - ;;; The source path from which to link. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path at which to create the hard link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Open a file or directory. - ;; - ;;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;;; file descriptor not currently open; it is randomized to prevent - ;;; applications from depending on making assumptions about indexes, since this - ;;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;;; guaranteed to be less than 2**31. - ;; - ;;; Note: This is similar to `openat` in POSIX. - (@interface func (export "open") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags) - ;;; The relative path of the file or directory to open, relative to the - ;;; `fd` directory. - (param $path string) - ;;; The method by which to open the file. - (param $oflags $oflags) - ;;; The initial rights of the newly created file descriptor. The - ;;; implementation is allowed to return a file descriptor with fewer rights - ;;; than specified, if and only if those rights do not apply to the type of - ;;; file being opened. - ;; - ;;; The *base* rights are rights that will apply to operations using the file - ;;; descriptor itself, while the *inheriting* rights are rights that apply to - ;;; file descriptors derived from it. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (param $fdflags $fdflags) - ;;; If a file is created, the filesystem permissions to associate with it. - (param $permissions $permissions) - ;;; The file descriptor of the file that has been opened. - (result $error (expected $fd (error $errno))) - ) - - ;;; Read the contents of a symbolic link. - ;;; Note: This is similar to `readlinkat` in POSIX. - (@interface func (export "readlink") - (param $fd $fd) - ;;; The path of the symbolic link from which to read. - (param $path string) - ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer (@witx char8))) - (param $buf_len $size) - ;;; The number of bytes placed in the buffer. - (result $error (expected $size (error $errno))) - ) - - ;;; Remove a directory. - ;;; Return `errno::notempty` if the directory is not empty. - ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (@interface func (export "remove_directory") - (param $fd $fd) - ;;; The path to a directory to remove. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Rename a file or directory. - ;;; Note: This is similar to `renameat` in POSIX. - (@interface func (export "rename") - (param $fd $fd) - ;;; The source path of the file or directory to rename. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Create a symbolic link. - ;;; Note: This is similar to `symlinkat` in POSIX. - (@interface func (export "symlink") - ;;; The contents of the symbolic link. - (param $old_path string) - (param $fd $fd) - ;;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Unlink a file. - ;;; Return `errno::isdir` if the path refers to a directory. - ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (@interface func (export "unlink_file") - (param $fd $fd) - ;;; The path to a file to unlink. - (param $path string) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx deleted file mode 100644 index 08da5f03a..000000000 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_poll.witx +++ /dev/null @@ -1,27 +0,0 @@ -;; WASI Poll API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_poll - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Concurrently poll for the occurrence of a set of events. - ;;; - ;;; If `nsubscriptions` is 0, returns `errno::inval`. - (@interface func (export "oneoff") - ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription)) - ;;; The events that have occurred. - (param $out (@witx pointer $event)) - ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size) - ;;; The number of events stored. - (result $error (expected $size (error $errno))) - ) -) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx deleted file mode 100644 index 0bd57682d..000000000 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_proc.witx +++ /dev/null @@ -1,22 +0,0 @@ -;; WASI Process API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_proc - ;;; Terminate the process normally. An exit code of `$exitcode::success` - ;;; reports successful completion of the program. An exit code of - ;;; `$exitcode::failure` or any other value less than 126 reports a - ;;; failure, and the value is provided to the environment. If a value - ;;; of 126 or greater is given, this function behaves as if it were - ;;; implemented by an `unreachable` instruction. - (@interface func (export "exit") - ;;; The exit code returned by the process. - (param $rval $exitcode) - (@witx noreturn) - ) -) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx deleted file mode 100644 index 4dc8e1a47..000000000 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_random.witx +++ /dev/null @@ -1,26 +0,0 @@ -;; WASI Random API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_random - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Write high-quality random data into a buffer. - ;;; This function blocks when the implementation is unable to immediately - ;;; provide sufficient high-quality random data. - ;;; This function may execute slowly, so when large mounts of random data are - ;;; required, it's advisable to use this function to seed a pseudo-random - ;;; number generator, rather than to provide the random data directly. - (@interface func (export "get") - ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sched.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sched.witx deleted file mode 100644 index 3b70856dc..000000000 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sched.witx +++ /dev/null @@ -1,16 +0,0 @@ -;; WASI Scheduler API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_sched - ;;; Temporarily yield execution of the calling thread. - ;;; Note: This is similar to `yield` in POSIX. - (@interface func (export "yield") - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sock.witx b/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sock.witx deleted file mode 100644 index a05b02ea6..000000000 --- a/proposals/clocks/phases/ephemeral/witx/wasi_ephemeral_sock.witx +++ /dev/null @@ -1,48 +0,0 @@ -;; WASI Sockets. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_sock - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Receive a message from a socket. - ;;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;;; the data into multiple buffers in the manner of `readv`. - (@interface func (export "recv") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_array) - ;;; Message flags. - (param $ri_flags $riflags) - ;;; Number of bytes stored in ri_data and message flags. - (result $error (expected (tuple $size $roflags) (error $errno))) - ) - - ;;; Send a message on a socket. - ;;; Note: This is similar to `send` in POSIX, though it also supports writing - ;;; the data from multiple buffers in the manner of `writev`. - (@interface func (export "send") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_array) - ;;; Message flags. - (param $si_flags $siflags) - ;;; Number of bytes transmitted. - (result $error (expected $size (error $errno))) - ) - - ;;; Shut down socket send and receive channels. - ;;; Note: This is similar to `shutdown` in POSIX. - (@interface func (export "shutdown") - (param $fd $fd) - ;;; Which channels on the socket to shut down. - (param $how $sdflags) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/clocks/phases/old/snapshot_0/docs.md b/proposals/clocks/phases/old/snapshot_0/docs.md deleted file mode 100644 index 634e304b3..000000000 --- a/proposals/clocks/phases/old/snapshot_0/docs.md +++ /dev/null @@ -1,2512 +0,0 @@ -# Types -## `size`: `u32` - -Size: 4 - -Alignment: 4 - -## `filesize`: `u64` -Non-negative file size or length of a region within a file. - -Size: 8 - -Alignment: 8 - -## `timestamp`: `u64` -Timestamp in nanoseconds. - -Size: 8 - -Alignment: 8 - -## `clockid`: `Variant` -Identifiers for clocks. - -Size: 4 - -Alignment: 4 - -### Variant cases -- `realtime` -The clock measuring real time. Time value zero corresponds with -1970-01-01T00:00:00Z. - -- `monotonic` -The store-wide monotonic clock, which is defined as a clock measuring -real time, whose value cannot be adjusted and which cannot have negative -clock jumps. The epoch of this clock is undefined. The absolute time -value of this clock therefore has no meaning. - -- `process_cputime_id` -The CPU-time clock associated with the current process. - -- `thread_cputime_id` -The CPU-time clock associated with the current thread. - -## `errno`: `Variant` -Error codes returned by functions. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX. - -Size: 2 - -Alignment: 2 - -### Variant cases -- `success` -No error occurred. System call completed successfully. - -- `2big` -Argument list too long. - -- `acces` -Permission denied. - -- `addrinuse` -Address in use. - -- `addrnotavail` -Address not available. - -- `afnosupport` -Address family not supported. - -- `again` -Resource unavailable, or operation would block. - -- `already` -Connection already in progress. - -- `badf` -Bad file descriptor. - -- `badmsg` -Bad message. - -- `busy` -Device or resource busy. - -- `canceled` -Operation canceled. - -- `child` -No child processes. - -- `connaborted` -Connection aborted. - -- `connrefused` -Connection refused. - -- `connreset` -Connection reset. - -- `deadlk` -Resource deadlock would occur. - -- `destaddrreq` -Destination address required. - -- `dom` -Mathematics argument out of domain of function. - -- `dquot` -Reserved. - -- `exist` -File exists. - -- `fault` -Bad address. - -- `fbig` -File too large. - -- `hostunreach` -Host is unreachable. - -- `idrm` -Identifier removed. - -- `ilseq` -Illegal byte sequence. - -- `inprogress` -Operation in progress. - -- `intr` -Interrupted function. - -- `inval` -Invalid argument. - -- `io` -I/O error. - -- `isconn` -Socket is connected. - -- `isdir` -Is a directory. - -- `loop` -Too many levels of symbolic links. - -- `mfile` -File descriptor value too large. - -- `mlink` -Too many links. - -- `msgsize` -Message too large. - -- `multihop` -Reserved. - -- `nametoolong` -Filename too long. - -- `netdown` -Network is down. - -- `netreset` -Connection aborted by network. - -- `netunreach` -Network unreachable. - -- `nfile` -Too many files open in system. - -- `nobufs` -No buffer space available. - -- `nodev` -No such device. - -- `noent` -No such file or directory. - -- `noexec` -Executable file format error. - -- `nolck` -No locks available. - -- `nolink` -Reserved. - -- `nomem` -Not enough space. - -- `nomsg` -No message of the desired type. - -- `noprotoopt` -Protocol not available. - -- `nospc` -No space left on device. - -- `nosys` -Function not supported. - -- `notconn` -The socket is not connected. - -- `notdir` -Not a directory or a symbolic link to a directory. - -- `notempty` -Directory not empty. - -- `notrecoverable` -State not recoverable. - -- `notsock` -Not a socket. - -- `notsup` -Not supported, or operation not supported on socket. - -- `notty` -Inappropriate I/O control operation. - -- `nxio` -No such device or address. - -- `overflow` -Value too large to be stored in data type. - -- `ownerdead` -Previous owner died. - -- `perm` -Operation not permitted. - -- `pipe` -Broken pipe. - -- `proto` -Protocol error. - -- `protonosupport` -Protocol not supported. - -- `prototype` -Protocol wrong type for socket. - -- `range` -Result too large. - -- `rofs` -Read-only file system. - -- `spipe` -Invalid seek. - -- `srch` -No such process. - -- `stale` -Reserved. - -- `timedout` -Connection timed out. - -- `txtbsy` -Text file busy. - -- `xdev` -Cross-device link. - -- `notcapable` -Extension: Capabilities insufficient. - -## `rights`: `Record` -File descriptor rights, determining which actions may be performed. - -Size: 8 - -Alignment: 8 - -### Record members -- `fd_datasync`: `bool` -The right to invoke [`fd_datasync`](#fd_datasync). -If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke -[`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). - -Bit: 0 - -- `fd_read`: `bool` -The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). - -Bit: 1 - -- `fd_seek`: `bool` -The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). - -Bit: 2 - -- `fd_fdstat_set_flags`: `bool` -The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). - -Bit: 3 - -- `fd_sync`: `bool` -The right to invoke [`fd_sync`](#fd_sync). -If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke -[`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - -Bit: 4 - -- `fd_tell`: `bool` -The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset -remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to -invoke [`fd_tell`](#fd_tell). - -Bit: 5 - -- `fd_write`: `bool` -The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). - -Bit: 6 - -- `fd_advise`: `bool` -The right to invoke [`fd_advise`](#fd_advise). - -Bit: 7 - -- `fd_allocate`: `bool` -The right to invoke [`fd_allocate`](#fd_allocate). - -Bit: 8 - -- `path_create_directory`: `bool` -The right to invoke [`path_create_directory`](#path_create_directory). - -Bit: 9 - -- `path_create_file`: `bool` -If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). - -Bit: 10 - -- `path_link_source`: `bool` -The right to invoke [`path_link`](#path_link) with the file descriptor as the -source directory. - -Bit: 11 - -- `path_link_target`: `bool` -The right to invoke [`path_link`](#path_link) with the file descriptor as the -target directory. - -Bit: 12 - -- `path_open`: `bool` -The right to invoke [`path_open`](#path_open). - -Bit: 13 - -- `fd_readdir`: `bool` -The right to invoke [`fd_readdir`](#fd_readdir). - -Bit: 14 - -- `path_readlink`: `bool` -The right to invoke [`path_readlink`](#path_readlink). - -Bit: 15 - -- `path_rename_source`: `bool` -The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. - -Bit: 16 - -- `path_rename_target`: `bool` -The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. - -Bit: 17 - -- `path_filestat_get`: `bool` -The right to invoke [`path_filestat_get`](#path_filestat_get). - -Bit: 18 - -- `path_filestat_set_size`: `bool` -The right to change a file's size (there is no `path_filestat_set_size`). -If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). - -Bit: 19 - -- `path_filestat_set_times`: `bool` -The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). - -Bit: 20 - -- `fd_filestat_get`: `bool` -The right to invoke [`fd_filestat_get`](#fd_filestat_get). - -Bit: 21 - -- `fd_filestat_set_size`: `bool` -The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). - -Bit: 22 - -- `fd_filestat_set_times`: `bool` -The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). - -Bit: 23 - -- `path_symlink`: `bool` -The right to invoke [`path_symlink`](#path_symlink). - -Bit: 24 - -- `path_remove_directory`: `bool` -The right to invoke [`path_remove_directory`](#path_remove_directory). - -Bit: 25 - -- `path_unlink_file`: `bool` -The right to invoke [`path_unlink_file`](#path_unlink_file). - -Bit: 26 - -- `poll_fd_readwrite`: `bool` -If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). -If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). - -Bit: 27 - -- `sock_shutdown`: `bool` -The right to invoke [`sock_shutdown`](#sock_shutdown). - -Bit: 28 - -## `fd`: `Handle` -A file descriptor handle. - -Size: 4 - -Alignment: 4 - -### Supertypes -## `iovec`: `Record` -A region of memory for scatter/gather reads. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `Pointer` -The address of the buffer to be filled. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be filled. - -Offset: 4 - -## `ciovec`: `Record` -A region of memory for scatter/gather writes. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `ConstPointer` -The address of the buffer to be written. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be written. - -Offset: 4 - -## `iovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `ciovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `filedelta`: `s64` -Relative offset within a file. - -Size: 8 - -Alignment: 8 - -## `whence`: `Variant` -The position relative to which to set the offset of the file descriptor. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `cur` -Seek relative to current position. - -- `end` -Seek relative to end-of-file. - -- `set` -Seek relative to start-of-file. - -## `dircookie`: `u64` -A reference to the offset of a directory entry. - -Size: 8 - -Alignment: 8 - -## `dirnamlen`: `u32` -The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent) struct. - -Size: 4 - -Alignment: 4 - -## `inode`: `u64` -File serial number that is unique within its file system. - -Size: 8 - -Alignment: 8 - -## `filetype`: `Variant` -The type of a file descriptor or file. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `unknown` -The type of the file descriptor or file is unknown or is different from any of the other types specified. - -- `block_device` -The file descriptor or file refers to a block device inode. - -- `character_device` -The file descriptor or file refers to a character device inode. - -- `directory` -The file descriptor or file refers to a directory inode. - -- `regular_file` -The file descriptor or file refers to a regular file inode. - -- `socket_dgram` -The file descriptor or file refers to a datagram socket. - -- `socket_stream` -The file descriptor or file refers to a byte-stream socket. - -- `symbolic_link` -The file refers to a symbolic link inode. - -## `dirent`: `Record` -A directory entry. - -Size: 24 - -Alignment: 8 - -### Record members -- `d_next`: [`dircookie`](#dircookie) -The offset of the next directory entry stored in this directory. - -Offset: 0 - -- `d_ino`: [`inode`](#inode) -The serial number of the file referred to by this directory entry. - -Offset: 8 - -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. - -Offset: 16 - -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. - -Offset: 20 - -## `advice`: `Variant` -File or memory access pattern advisory information. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `normal` -The application has no advice to give on its behavior with respect to the specified data. - -- `sequential` -The application expects to access the specified data sequentially from lower offsets to higher offsets. - -- `random` -The application expects to access the specified data in a random order. - -- `willneed` -The application expects to access the specified data in the near future. - -- `dontneed` -The application expects that it will not access the specified data in the near future. - -- `noreuse` -The application expects to access the specified data once and then not reuse it thereafter. - -## `fdflags`: `Record` -File descriptor flags. - -Size: 2 - -Alignment: 2 - -### Record members -- `append`: `bool` -Append mode: Data written to the file is always appended to the file's end. - -Bit: 0 - -- `dsync`: `bool` -Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - -Bit: 1 - -- `nonblock`: `bool` -Non-blocking mode. - -Bit: 2 - -- `rsync`: `bool` -Synchronized read I/O operations. - -Bit: 3 - -- `sync`: `bool` -Write according to synchronized I/O file integrity completion. In -addition to synchronizing the data stored in the file, the implementation -may also synchronously update the file's metadata. - -Bit: 4 - -## `fdstat`: `Record` -File descriptor attributes. - -Size: 24 - -Alignment: 8 - -### Record members -- `fs_filetype`: [`filetype`](#filetype) -File type. - -Offset: 0 - -- `fs_flags`: [`fdflags`](#fdflags) -File descriptor flags. - -Offset: 2 - -- `fs_rights_base`: [`rights`](#rights) -Rights that apply to this file descriptor. - -Offset: 8 - -- `fs_rights_inheriting`: [`rights`](#rights) -Maximum set of rights that may be installed on new file descriptors that -are created through this file descriptor, e.g., through [`path_open`](#path_open). - -Offset: 16 - -## `device`: `u64` -Identifier for a device containing a file system. Can be used in combination -with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. - -Size: 8 - -Alignment: 8 - -## `fstflags`: `Record` -Which file time attributes to adjust. - -Size: 2 - -Alignment: 2 - -### Record members -- `atim`: `bool` -Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - -Bit: 0 - -- `atim_now`: `bool` -Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 1 - -- `mtim`: `bool` -Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - -Bit: 2 - -- `mtim_now`: `bool` -Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 3 - -## `lookupflags`: `Record` -Flags determining the method of how paths are resolved. - -Size: 4 - -Alignment: 4 - -### Record members -- `symlink_follow`: `bool` -As long as the resolved path corresponds to a symbolic link, it is expanded. - -Bit: 0 - -## `oflags`: `Record` -Open flags used by [`path_open`](#path_open). - -Size: 2 - -Alignment: 2 - -### Record members -- `creat`: `bool` -Create file if it does not exist. - -Bit: 0 - -- `directory`: `bool` -Fail if not a directory. - -Bit: 1 - -- `excl`: `bool` -Fail if file already exists. - -Bit: 2 - -- `trunc`: `bool` -Truncate file to size 0. - -Bit: 3 - -## `linkcount`: `u32` -Number of hard links to an inode. - -Size: 4 - -Alignment: 4 - -## `filestat`: `Record` -File attributes. - -Size: 56 - -Alignment: 8 - -### Record members -- `dev`: [`device`](#device) -Device ID of device containing the file. - -Offset: 0 - -- `ino`: [`inode`](#inode) -File serial number. - -Offset: 8 - -- `filetype`: [`filetype`](#filetype) -File type. - -Offset: 16 - -- `nlink`: [`linkcount`](#linkcount) -Number of hard links to the file. - -Offset: 20 - -- `size`: [`filesize`](#filesize) -For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - -Offset: 24 - -- `atim`: [`timestamp`](#timestamp) -Last data access timestamp. - -Offset: 32 - -- `mtim`: [`timestamp`](#timestamp) -Last data modification timestamp. - -Offset: 40 - -- `ctim`: [`timestamp`](#timestamp) -Last file status change timestamp. - -Offset: 48 - -## `userdata`: `u64` -User-provided value that may be attached to objects that is retained when -extracted from the implementation. - -Size: 8 - -Alignment: 8 - -## `eventtype`: `Variant` -Type of a subscription to an event or its occurrence. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `clock` -The time value of clock [`subscription_clock::id`](#subscription_clock.id) has -reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - -- `fd_read` -File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has data -available for reading. This event always triggers for regular files. - -- `fd_write` -File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity -available for writing. This event always triggers for regular files. - -## `eventrwflags`: `Record` -The state of the file descriptor subscribed to with -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 2 - -Alignment: 2 - -### Record members -- `fd_readwrite_hangup`: `bool` -The peer of this socket has closed or disconnected. - -Bit: 0 - -## `event_fd_readwrite`: `Record` -The contents of an [`event`](#event) for the [`eventtype::fd_read`](#eventtype.fd_read) and -[`eventtype::fd_write`](#eventtype.fd_write) variants - -Size: 16 - -Alignment: 8 - -### Record members -- `nbytes`: [`filesize`](#filesize) -The number of bytes available for reading or writing. - -Offset: 0 - -- `flags`: [`eventrwflags`](#eventrwflags) -The state of the file descriptor. - -Offset: 8 - -## `event`: `Record` -An event that occurred. - -Size: 32 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). - -Offset: 0 - -- `error`: [`errno`](#errno) -If non-zero, an error that occurred while processing the subscription request. - -Offset: 8 - -- `type`: [`eventtype`](#eventtype) -The type of event that occured - -Offset: 10 - -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. - -Offset: 16 - -## `subclockflags`: `Record` -Flags determining how to interpret the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout). - -Size: 2 - -Alignment: 2 - -### Record members -- `subscription_clock_abstime`: `bool` -If set, treat the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock -[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp -provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the -current time value of clock [`subscription_clock::id`](#subscription_clock.id). - -Bit: 0 - -## `subscription_clock`: `Record` -The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). - -Size: 40 - -Alignment: 8 - -### Record members -- `identifier`: [`userdata`](#userdata) -The user-defined unique identifier of the clock. - -Offset: 0 - -- `id`: [`clockid`](#clockid) -The clock against which to compare the timestamp. - -Offset: 8 - -- `timeout`: [`timestamp`](#timestamp) -The absolute or relative timestamp. - -Offset: 16 - -- `precision`: [`timestamp`](#timestamp) -The amount of time that the implementation may wait additionally -to coalesce with other events. - -Offset: 24 - -- `flags`: [`subclockflags`](#subclockflags) -Flags specifying whether the timeout is absolute or relative - -Offset: 32 - -## `subscription_fd_readwrite`: `Record` -The contents of a [`subscription`](#subscription) when the variant is -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 4 - -Alignment: 4 - -### Record members -- `file_descriptor`: [`fd`](#fd) -The file descriptor on which to wait for it to become ready for reading or writing. - -Offset: 0 - -## `subscription_u`: `Variant` -The contents of a [`subscription`](#subscription). - -Size: 48 - -Alignment: 8 - -### Variant Layout -- size: 48 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock`: [`subscription_clock`](#subscription_clock) - -- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -## `subscription`: `Record` -Subscription to an event. - -Size: 56 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that is attached to the subscription in the -implementation and returned through [`event::userdata`](#event.userdata). - -Offset: 0 - -- `u`: [`subscription_u`](#subscription_u) -The type of the event to which to subscribe. - -Offset: 8 - -## `exitcode`: `u32` -Exit code generated by a process when exiting. - -Size: 4 - -Alignment: 4 - -## `signal`: `Variant` -Signal condition. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `none` -No signal. Note that POSIX has special semantics for `kill(pid, 0)`, -so this value is reserved. - -- `hup` -Hangup. -Action: Terminates the process. - -- `int` -Terminate interrupt signal. -Action: Terminates the process. - -- `quit` -Terminal quit signal. -Action: Terminates the process. - -- `ill` -Illegal instruction. -Action: Terminates the process. - -- `trap` -Trace/breakpoint trap. -Action: Terminates the process. - -- `abrt` -Process abort signal. -Action: Terminates the process. - -- `bus` -Access to an undefined portion of a memory object. -Action: Terminates the process. - -- `fpe` -Erroneous arithmetic operation. -Action: Terminates the process. - -- `kill` -Kill. -Action: Terminates the process. - -- `usr1` -User-defined signal 1. -Action: Terminates the process. - -- `segv` -Invalid memory reference. -Action: Terminates the process. - -- `usr2` -User-defined signal 2. -Action: Terminates the process. - -- `pipe` -Write on a pipe with no one to read it. -Action: Ignored. - -- `alrm` -Alarm clock. -Action: Terminates the process. - -- `term` -Termination signal. -Action: Terminates the process. - -- `chld` -Child process terminated, stopped, or continued. -Action: Ignored. - -- `cont` -Continue executing, if stopped. -Action: Continues executing, if stopped. - -- `stop` -Stop executing. -Action: Stops executing. - -- `tstp` -Terminal stop signal. -Action: Stops executing. - -- `ttin` -Background process attempting read. -Action: Stops executing. - -- `ttou` -Background process attempting write. -Action: Stops executing. - -- `urg` -High bandwidth data is available at a socket. -Action: Ignored. - -- `xcpu` -CPU time limit exceeded. -Action: Terminates the process. - -- `xfsz` -File size limit exceeded. -Action: Terminates the process. - -- `vtalrm` -Virtual timer expired. -Action: Terminates the process. - -- `prof` -Profiling timer expired. -Action: Terminates the process. - -- `winch` -Window changed. -Action: Ignored. - -- `poll` -I/O possible. -Action: Terminates the process. - -- `pwr` -Power failure. -Action: Terminates the process. - -- `sys` -Bad system call. -Action: Terminates the process. - -## `riflags`: `Record` -Flags provided to [`sock_recv`](#sock_recv). - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_peek`: `bool` -Returns the message without removing it from the socket's receive queue. - -Bit: 0 - -- `recv_waitall`: `bool` -On byte-stream sockets, block until the full amount of data can be returned. - -Bit: 1 - -## `roflags`: `Record` -Flags returned by [`sock_recv`](#sock_recv). - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_data_truncated`: `bool` -Returned by [`sock_recv`](#sock_recv): Message data has been truncated. - -Bit: 0 - -## `siflags`: `u16` -Flags provided to [`sock_send`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Size: 2 - -Alignment: 2 - -## `sdflags`: `Record` -Which channels on a socket to shut down. - -Size: 1 - -Alignment: 1 - -### Record members -- `rd`: `bool` -Disables further receive operations. - -Bit: 0 - -- `wr`: `bool` -Disables further send operations. - -Bit: 1 - -## `preopentype`: `Variant` -Identifiers for preopened capabilities. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `dir` -A pre-opened directory. - -## `prestat_dir`: `Record` -The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). - -Size: 4 - -Alignment: 4 - -### Record members -- `pr_name_len`: [`size`](#size) -The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). - -Offset: 0 - -## `prestat`: `Variant` -Information about a pre-opened capability. - -Size: 8 - -Alignment: 4 - -### Variant Layout -- size: 8 -- align: 4 -- tag_size: 1 -### Variant cases -- `dir`: [`prestat_dir`](#prestat_dir) - -# Modules -## wasi_unstable -### Imports -#### Memory -### Functions - ---- - -#### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` -Read command-line argument data. -The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get). -Each argument is expected to be `\0` terminated. - -##### Params -- `argv`: `Pointer>` - -- `argv_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `args_sizes_get() -> Result<(size, size), errno>` -Return command-line argument data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of arguments and the size of the argument string -data, or an error. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` -Read environment variable data. -The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). -Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - -##### Params -- `environ`: `Pointer>` - -- `environ_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `environ_sizes_get() -> Result<(size, size), errno>` -Return environment variable data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of environment variable arguments and the size of the -environment variable data. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `clock_res_get(id: clockid) -> Result` -Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return -[`errno::inval`](#errno.inval). -Note: This is similar to `clock_getres` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the resolution. - -##### Results -- `error`: `Result` -The resolution of the clock, or an error if one happened. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `clock_time_get(id: clockid, precision: timestamp) -> Result` -Return the time value of a clock. -Note: This is similar to `clock_gettime` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the time. - -- `precision`: [`timestamp`](#timestamp) -The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - -##### Results -- `error`: `Result` -The time value of the clock. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` -Provide file advisory information on a file descriptor. -Note: This is similar to `posix_fadvise` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset within the file to which the advisory applies. - -- `len`: [`filesize`](#filesize) -The length of the region to which the advisory applies. - -- `advice`: [`advice`](#advice) -The advice. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` -Force the allocation of space in a file. -Note: This is similar to `posix_fallocate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset at which to start the allocation. - -- `len`: [`filesize`](#filesize) -The length of the area that is allocated. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_close(fd: fd) -> Result<(), errno>` -Close a file descriptor. -Note: This is similar to `close` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_datasync(fd: fd) -> Result<(), errno>` -Synchronize the data of a file to disk. -Note: This is similar to `fdatasync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_get(fd: fd) -> Result` -Get the attributes of a file descriptor. -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file descriptor's attributes are stored. - -###### Variant Layout -- size: 32 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`fdstat`](#fdstat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` -Adjust the flags associated with a file descriptor. -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`fdflags`](#fdflags) -The desired values of the file descriptor flags. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` -Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights - -##### Params -- `fd`: [`fd`](#fd) - -- `fs_rights_base`: [`rights`](#rights) -The desired rights of the file descriptor. - -- `fs_rights_inheriting`: [`rights`](#rights) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_get(fd: fd) -> Result` -Return the attributes of an open file. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 64 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` -Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. -Note: This is similar to `ftruncate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `size`: [`filesize`](#filesize) -The desired file size. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of an open file or directory. -Note: This is similar to `futimens` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` -Read from a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `preadv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors in which to store data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to read. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_prestat_get(fd: fd) -> Result` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the description is stored. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`prestat`](#prestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `Pointer` -A buffer into which to write the preopened directory name. - -- `path_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` -Write to a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `pwritev` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to write. - -##### Results -- `error`: `Result` -The number of bytes written. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_read(fd: fd, iovs: iovec_array) -> Result` -Read from a file descriptor. -Note: This is similar to `readv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` -Read directory entries from a directory. -When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a [`dirent`](#dirent) object, -followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory -entry. -This function fills the output buffer as much as possible, potentially -truncating the last directory entry. This allows the caller to grow its -read buffer size in case it's too small to fit a single large directory -entry, or skip the oversized directory entry. - -##### Params -- `fd`: [`fd`](#fd) - -- `buf`: `Pointer` -The buffer where directory entries are stored - -- `buf_len`: [`size`](#size) - -- `cookie`: [`dircookie`](#dircookie) -The location within the directory to start reading - -##### Results -- `error`: `Result` -The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_renumber(fd: fd, to: fd) -> Result<(), errno>` -Atomically replace a file descriptor by renumbering another file descriptor. -Due to the strong focus on thread safety, this environment does not provide -a mechanism to duplicate or renumber a file descriptor to an arbitrary -number, like `dup2()`. This would be prone to race conditions, as an actual -file descriptor with the same number could be allocated by a different -thread at the same time. -This function provides a way to atomically renumber file descriptors, which -would disappear if `dup2()` were to be removed entirely. - -##### Params -- `fd`: [`fd`](#fd) - -- `to`: [`fd`](#fd) -The file descriptor to overwrite. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> Result` -Move the offset of a file descriptor. -Note: This is similar to `lseek` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filedelta`](#filedelta) -The number of bytes to move. - -- `whence`: [`whence`](#whence) -The base from which the offset is relative. - -##### Results -- `error`: `Result` -The new offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_sync(fd: fd) -> Result<(), errno>` -Synchronize the data and metadata of a file to disk. -Note: This is similar to `fsync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_tell(fd: fd) -> Result` -Return the current offset of a file descriptor. -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The current offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_write(fd: fd, iovs: ciovec_array) -> Result` -Write to a file descriptor. -Note: This is similar to `writev` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -##### Results -- `error`: `Result` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_create_directory(fd: fd, path: string) -> Result<(), errno>` -Create a directory. -Note: This is similar to `mkdirat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path at which to create the directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` -Return the attributes of a file or directory. -Note: This is similar to `stat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to inspect. - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 64 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of a file or directory. -Note: This is similar to `utimensat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to operate on. - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Create a hard link. -Note: This is similar to `linkat` in POSIX. - -##### Params -- `old_fd`: [`fd`](#fd) - -- `old_flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `old_path`: `string` -The source path from which to link. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path at which to create the hard link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> Result` -Open a file or directory. -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since this -is error-prone in multi-threaded contexts. The returned file descriptor is -guaranteed to be less than 2**31. -Note: This is similar to `openat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `dirflags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The relative path of the file or directory to open, relative to the -[`path_open::fd`](#path_open.fd) directory. - -- `oflags`: [`oflags`](#oflags) -The method by which to open the file. - -- `fs_rights_base`: [`rights`](#rights) -The initial rights of the newly created file descriptor. The -implementation is allowed to return a file descriptor with fewer rights -than specified, if and only if those rights do not apply to the type of -file being opened. -The *base* rights are rights that will apply to operations using the file -descriptor itself, while the *inheriting* rights are rights that apply to -file descriptors derived from it. - -- `fs_rights_inheriting`: [`rights`](#rights) - -- `fdflags`: [`fdflags`](#fdflags) - -##### Results -- `error`: `Result` -The file descriptor of the file that has been opened. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`fd`](#fd) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` -Read the contents of a symbolic link. -Note: This is similar to `readlinkat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path of the symbolic link from which to read. - -- `buf`: `Pointer` -The buffer to which to write the contents of the symbolic link. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result` -The number of bytes placed in the buffer. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_remove_directory(fd: fd, path: string) -> Result<(), errno>` -Remove a directory. -Return [`errno::notempty`](#errno.notempty) if the directory is not empty. -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a directory to remove. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Rename a file or directory. -Note: This is similar to `renameat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `old_path`: `string` -The source path of the file or directory to rename. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path to which to rename the file or directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` -Create a symbolic link. -Note: This is similar to `symlinkat` in POSIX. - -##### Params -- `old_path`: `string` -The contents of the symbolic link. - -- `fd`: [`fd`](#fd) - -- `new_path`: `string` -The destination path at which to create the symbolic link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_unlink_file(fd: fd, path: string) -> Result<(), errno>` -Unlink a file. -Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a file to unlink. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` -Concurrently poll for the occurrence of a set of events. - -##### Params -- `in`: `ConstPointer` -The events to which to subscribe. - -- `out`: `Pointer` -The events that have occurred. - -- `nsubscriptions`: [`size`](#size) -Both the number of subscriptions and events. - -##### Results -- `error`: `Result` -The number of events stored. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `proc_exit(rval: exitcode)` -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -##### Params -- `rval`: [`exitcode`](#exitcode) -The exit code returned by the process. - -##### Results - ---- - -#### `proc_raise(sig: signal) -> Result<(), errno>` -Send a signal to the process of the calling thread. -Note: This is similar to `raise` in POSIX. - -##### Params -- `sig`: [`signal`](#signal) -The signal condition to trigger. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sched_yield() -> Result<(), errno>` -Temporarily yield execution of the calling thread. -Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. - -##### Params -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `random_get(buf: Pointer, buf_len: size) -> Result<(), errno>` -Write high-quality random data into a buffer. -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. -This function may execute slowly, so when large mounts of random data are -required, it's advisable to use this function to seed a pseudo-random -number generator, rather than to provide the random data directly. - -##### Params -- `buf`: `Pointer` -The buffer to fill with random data. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` -Receive a message from a socket. -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -##### Params -- `fd`: [`fd`](#fd) - -- `ri_data`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -- `ri_flags`: [`riflags`](#riflags) -Message flags. - -##### Results -- `error`: `Result<(size, roflags), errno>` -Number of bytes stored in ri_data and message flags. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, roflags)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`roflags`](#roflags) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` -Send a message on a socket. -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -##### Params -- `fd`: [`fd`](#fd) - -- `si_data`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors to which to retrieve data - -- `si_flags`: [`siflags`](#siflags) -Message flags. - -##### Results -- `error`: `Result` -Number of bytes transmitted. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_shutdown(fd: fd, how: sdflags) -> Result<(), errno>` -Shut down socket send and receive channels. -Note: This is similar to `shutdown` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `how`: [`sdflags`](#sdflags) -Which channels on the socket to shut down. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - diff --git a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx b/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx deleted file mode 100644 index f4ba78802..000000000 --- a/proposals/clocks/phases/old/snapshot_0/witx/typenames.witx +++ /dev/null @@ -1,746 +0,0 @@ -;; Type names used by low-level WASI interfaces. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/main/docs/witx.md) -;; for an explanation of what that means. - -(typename $size u32) - -;;; Non-negative file size or length of a region within a file. -(typename $filesize u64) - -;;; Timestamp in nanoseconds. -(typename $timestamp u64) - -;;; Identifiers for clocks. -(typename $clockid - (enum (@witx tag u32) - ;;; The clock measuring real time. Time value zero corresponds with - ;;; 1970-01-01T00:00:00Z. - $realtime - ;;; The store-wide monotonic clock, which is defined as a clock measuring - ;;; real time, whose value cannot be adjusted and which cannot have negative - ;;; clock jumps. The epoch of this clock is undefined. The absolute time - ;;; value of this clock therefore has no meaning. - $monotonic - ;;; The CPU-time clock associated with the current process. - $process_cputime_id - ;;; The CPU-time clock associated with the current thread. - $thread_cputime_id - ) -) - -;;; Error codes returned by functions. -;;; Not all of these error codes are returned by the functions provided by this -;;; API; some are used in higher-level library layers, and others are provided -;;; merely for alignment with POSIX. -(typename $errno - (enum (@witx tag u16) - ;;; No error occurred. System call completed successfully. - $success - ;;; Argument list too long. - $2big - ;;; Permission denied. - $acces - ;;; Address in use. - $addrinuse - ;;; Address not available. - $addrnotavail - ;;; Address family not supported. - $afnosupport - ;;; Resource unavailable, or operation would block. - $again - ;;; Connection already in progress. - $already - ;;; Bad file descriptor. - $badf - ;;; Bad message. - $badmsg - ;;; Device or resource busy. - $busy - ;;; Operation canceled. - $canceled - ;;; No child processes. - $child - ;;; Connection aborted. - $connaborted - ;;; Connection refused. - $connrefused - ;;; Connection reset. - $connreset - ;;; Resource deadlock would occur. - $deadlk - ;;; Destination address required. - $destaddrreq - ;;; Mathematics argument out of domain of function. - $dom - ;;; Reserved. - $dquot - ;;; File exists. - $exist - ;;; Bad address. - $fault - ;;; File too large. - $fbig - ;;; Host is unreachable. - $hostunreach - ;;; Identifier removed. - $idrm - ;;; Illegal byte sequence. - $ilseq - ;;; Operation in progress. - $inprogress - ;;; Interrupted function. - $intr - ;;; Invalid argument. - $inval - ;;; I/O error. - $io - ;;; Socket is connected. - $isconn - ;;; Is a directory. - $isdir - ;;; Too many levels of symbolic links. - $loop - ;;; File descriptor value too large. - $mfile - ;;; Too many links. - $mlink - ;;; Message too large. - $msgsize - ;;; Reserved. - $multihop - ;;; Filename too long. - $nametoolong - ;;; Network is down. - $netdown - ;;; Connection aborted by network. - $netreset - ;;; Network unreachable. - $netunreach - ;;; Too many files open in system. - $nfile - ;;; No buffer space available. - $nobufs - ;;; No such device. - $nodev - ;;; No such file or directory. - $noent - ;;; Executable file format error. - $noexec - ;;; No locks available. - $nolck - ;;; Reserved. - $nolink - ;;; Not enough space. - $nomem - ;;; No message of the desired type. - $nomsg - ;;; Protocol not available. - $noprotoopt - ;;; No space left on device. - $nospc - ;;; Function not supported. - $nosys - ;;; The socket is not connected. - $notconn - ;;; Not a directory or a symbolic link to a directory. - $notdir - ;;; Directory not empty. - $notempty - ;;; State not recoverable. - $notrecoverable - ;;; Not a socket. - $notsock - ;;; Not supported, or operation not supported on socket. - $notsup - ;;; Inappropriate I/O control operation. - $notty - ;;; No such device or address. - $nxio - ;;; Value too large to be stored in data type. - $overflow - ;;; Previous owner died. - $ownerdead - ;;; Operation not permitted. - $perm - ;;; Broken pipe. - $pipe - ;;; Protocol error. - $proto - ;;; Protocol not supported. - $protonosupport - ;;; Protocol wrong type for socket. - $prototype - ;;; Result too large. - $range - ;;; Read-only file system. - $rofs - ;;; Invalid seek. - $spipe - ;;; No such process. - $srch - ;;; Reserved. - $stale - ;;; Connection timed out. - $timedout - ;;; Text file busy. - $txtbsy - ;;; Cross-device link. - $xdev - ;;; Extension: Capabilities insufficient. - $notcapable - ) -) - -;;; File descriptor rights, determining which actions may be performed. -(typename $rights - (flags (@witx repr u64) - ;;; The right to invoke `fd_datasync`. - ;; - ;;; If `rights::path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::dsync`. - $fd_datasync - ;;; The right to invoke `fd_read` and `sock_recv`. - ;; - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. - $fd_read - ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. - $fd_seek - ;;; The right to invoke `fd_fdstat_set_flags`. - $fd_fdstat_set_flags - ;;; The right to invoke `fd_sync`. - ;; - ;;; If `rights::path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. - $fd_sync - ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to - ;;; invoke `fd_tell`. - $fd_tell - ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. - $fd_write - ;;; The right to invoke `fd_advise`. - $fd_advise - ;;; The right to invoke `fd_allocate`. - $fd_allocate - ;;; The right to invoke `path_create_directory`. - $path_create_directory - ;;; If `rights::path_open` is set, the right to invoke `path_open` with `oflags::creat`. - $path_create_file - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; source directory. - $path_link_source - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; target directory. - $path_link_target - ;;; The right to invoke `path_open`. - $path_open - ;;; The right to invoke `fd_readdir`. - $fd_readdir - ;;; The right to invoke `path_readlink`. - $path_readlink - ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $path_rename_source - ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $path_rename_target - ;;; The right to invoke `path_filestat_get`. - $path_filestat_get - ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `rights::path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. - $path_filestat_set_size - ;;; The right to invoke `path_filestat_set_times`. - $path_filestat_set_times - ;;; The right to invoke `fd_filestat_get`. - $fd_filestat_get - ;;; The right to invoke `fd_filestat_set_size`. - $fd_filestat_set_size - ;;; The right to invoke `fd_filestat_set_times`. - $fd_filestat_set_times - ;;; The right to invoke `path_symlink`. - $path_symlink - ;;; The right to invoke `path_remove_directory`. - $path_remove_directory - ;;; The right to invoke `path_unlink_file`. - $path_unlink_file - ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. - ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. - $poll_fd_readwrite - ;;; The right to invoke `sock_shutdown`. - $sock_shutdown - ) -) - -;;; A file descriptor handle. -(typename $fd (handle)) - -;;; A region of memory for scatter/gather reads. -(typename $iovec - (record - ;;; The address of the buffer to be filled. - (field $buf (@witx pointer u8)) - ;;; The length of the buffer to be filled. - (field $buf_len $size) - ) -) - -;;; A region of memory for scatter/gather writes. -(typename $ciovec - (record - ;;; The address of the buffer to be written. - (field $buf (@witx const_pointer u8)) - ;;; The length of the buffer to be written. - (field $buf_len $size) - ) -) - -(typename $iovec_array (list $iovec)) -(typename $ciovec_array (list $ciovec)) - -;;; Relative offset within a file. -(typename $filedelta s64) - -;;; The position relative to which to set the offset of the file descriptor. -(typename $whence - (enum (@witx tag u8) - ;;; Seek relative to current position. - $cur - ;;; Seek relative to end-of-file. - $end - ;;; Seek relative to start-of-file. - $set - ) -) - -;;; A reference to the offset of a directory entry. -(typename $dircookie u64) - -;;; The type for the `dirent::d_namlen` field of `dirent` struct. -(typename $dirnamlen u32) - -;;; File serial number that is unique within its file system. -(typename $inode u64) - -;;; The type of a file descriptor or file. -(typename $filetype - (enum (@witx tag u8) - ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $unknown - ;;; The file descriptor or file refers to a block device inode. - $block_device - ;;; The file descriptor or file refers to a character device inode. - $character_device - ;;; The file descriptor or file refers to a directory inode. - $directory - ;;; The file descriptor or file refers to a regular file inode. - $regular_file - ;;; The file descriptor or file refers to a datagram socket. - $socket_dgram - ;;; The file descriptor or file refers to a byte-stream socket. - $socket_stream - ;;; The file refers to a symbolic link inode. - $symbolic_link - ) -) - -;;; A directory entry. -(typename $dirent - (record - ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie) - ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) - ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype) - ) -) - -;;; File or memory access pattern advisory information. -(typename $advice - (enum (@witx tag u8) - ;;; The application has no advice to give on its behavior with respect to the specified data. - $normal - ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $sequential - ;;; The application expects to access the specified data in a random order. - $random - ;;; The application expects to access the specified data in the near future. - $willneed - ;;; The application expects that it will not access the specified data in the near future. - $dontneed - ;;; The application expects to access the specified data once and then not reuse it thereafter. - $noreuse - ) -) - -;;; File descriptor flags. -(typename $fdflags - (flags (@witx repr u16) - ;;; Append mode: Data written to the file is always appended to the file's end. - $append - ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $dsync - ;;; Non-blocking mode. - $nonblock - ;;; Synchronized read I/O operations. - $rsync - ;;; Write according to synchronized I/O file integrity completion. In - ;;; addition to synchronizing the data stored in the file, the implementation - ;;; may also synchronously update the file's metadata. - $sync - ) -) - -;;; File descriptor attributes. -(typename $fdstat - (record - ;;; File type. - (field $fs_filetype $filetype) - ;;; File descriptor flags. - (field $fs_flags $fdflags) - ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights) - ;;; Maximum set of rights that may be installed on new file descriptors that - ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights) - ) -) - -;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode` to uniquely identify a file or directory in the filesystem. -(typename $device u64) - -;;; Which file time attributes to adjust. -(typename $fstflags - (flags (@witx repr u16) - ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. - $atim - ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. - $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. - $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. - $mtim_now - ) -) - -;;; Flags determining the method of how paths are resolved. -(typename $lookupflags - (flags (@witx repr u32) - ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $symlink_follow - ) -) - -;;; Open flags used by `path_open`. -(typename $oflags - (flags (@witx repr u16) - ;;; Create file if it does not exist. - $creat - ;;; Fail if not a directory. - $directory - ;;; Fail if file already exists. - $excl - ;;; Truncate file to size 0. - $trunc - ) -) - -;;; Number of hard links to an inode. -(typename $linkcount u32) - -;;; File attributes. -(typename $filestat - (record - ;;; Device ID of device containing the file. - (field $dev $device) - ;;; File serial number. - (field $ino $inode) - ;;; File type. - (field $filetype $filetype) - ;;; Number of hard links to the file. - (field $nlink $linkcount) - ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $size $filesize) - ;;; Last data access timestamp. - (field $atim $timestamp) - ;;; Last data modification timestamp. - (field $mtim $timestamp) - ;;; Last file status change timestamp. - (field $ctim $timestamp) - ) -) - -;;; User-provided value that may be attached to objects that is retained when -;;; extracted from the implementation. -(typename $userdata u64) - -;;; Type of a subscription to an event or its occurrence. -(typename $eventtype - (enum (@witx tag u8) - ;;; The time value of clock `subscription_clock::id` has - ;;; reached timestamp `subscription_clock::timeout`. - $clock - ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has data - ;;; available for reading. This event always triggers for regular files. - $fd_read - ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has capacity - ;;; available for writing. This event always triggers for regular files. - $fd_write - ) -) - -;;; The state of the file descriptor subscribed to with -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $eventrwflags - (flags (@witx repr u16) - ;;; The peer of this socket has closed or disconnected. - $fd_readwrite_hangup - ) -) - -;;; The contents of an `event` for the `eventtype::fd_read` and -;;; `eventtype::fd_write` variants -(typename $event_fd_readwrite - (record - ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize) - ;;; The state of the file descriptor. - (field $flags $eventrwflags) - ) -) - -;;; An event that occurred. -(typename $event - (record - ;;; User-provided value that got attached to `subscription::userdata`. - (field $userdata $userdata) - ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno) - ;;; The type of event that occured - (field $type $eventtype) - ;;; The contents of the event, if it is an `eventtype::fd_read` or - ;;; `eventtype::fd_write`. `eventtype::clock` events ignore this field. - (field $fd_readwrite $event_fd_readwrite) - ) -) - -;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_clock::timeout`. -(typename $subclockflags - (flags (@witx repr u16) - ;;; If set, treat the timestamp provided in - ;;; `subscription_clock::timeout` as an absolute timestamp of clock - ;;; `subscription_clock::id`. If clear, treat the timestamp - ;;; provided in `subscription_clock::timeout` relative to the - ;;; current time value of clock `subscription_clock::id`. - $subscription_clock_abstime - ) -) - -;;; The contents of a `subscription` when type is `eventtype::clock`. -(typename $subscription_clock - (record - ;;; The user-defined unique identifier of the clock. - (field $identifier $userdata) - ;;; The clock against which to compare the timestamp. - (field $id $clockid) - ;;; The absolute or relative timestamp. - (field $timeout $timestamp) - ;;; The amount of time that the implementation may wait additionally - ;;; to coalesce with other events. - (field $precision $timestamp) - ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags) - ) -) - -;;; The contents of a `subscription` when the variant is -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $subscription_fd_readwrite - (record - ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd) - ) -) - -;;; The contents of a `subscription`. -(typename $subscription_u - (union (@witx tag $eventtype) - $subscription_clock - $subscription_fd_readwrite - $subscription_fd_readwrite - ) -) - -;;; Subscription to an event. -(typename $subscription - (record - ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event::userdata`. - (field $userdata $userdata) - ;;; The type of the event to which to subscribe. - (field $u $subscription_u) - ) -) - -;;; Exit code generated by a process when exiting. -(typename $exitcode u32) - -;;; Signal condition. -(typename $signal - (enum (@witx tag u8) - ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;;; so this value is reserved. - $none - ;;; Hangup. - ;;; Action: Terminates the process. - $hup - ;;; Terminate interrupt signal. - ;;; Action: Terminates the process. - $int - ;;; Terminal quit signal. - ;;; Action: Terminates the process. - $quit - ;;; Illegal instruction. - ;;; Action: Terminates the process. - $ill - ;;; Trace/breakpoint trap. - ;;; Action: Terminates the process. - $trap - ;;; Process abort signal. - ;;; Action: Terminates the process. - $abrt - ;;; Access to an undefined portion of a memory object. - ;;; Action: Terminates the process. - $bus - ;;; Erroneous arithmetic operation. - ;;; Action: Terminates the process. - $fpe - ;;; Kill. - ;;; Action: Terminates the process. - $kill - ;;; User-defined signal 1. - ;;; Action: Terminates the process. - $usr1 - ;;; Invalid memory reference. - ;;; Action: Terminates the process. - $segv - ;;; User-defined signal 2. - ;;; Action: Terminates the process. - $usr2 - ;;; Write on a pipe with no one to read it. - ;;; Action: Ignored. - $pipe - ;;; Alarm clock. - ;;; Action: Terminates the process. - $alrm - ;;; Termination signal. - ;;; Action: Terminates the process. - $term - ;;; Child process terminated, stopped, or continued. - ;;; Action: Ignored. - $chld - ;;; Continue executing, if stopped. - ;;; Action: Continues executing, if stopped. - $cont - ;;; Stop executing. - ;;; Action: Stops executing. - $stop - ;;; Terminal stop signal. - ;;; Action: Stops executing. - $tstp - ;;; Background process attempting read. - ;;; Action: Stops executing. - $ttin - ;;; Background process attempting write. - ;;; Action: Stops executing. - $ttou - ;;; High bandwidth data is available at a socket. - ;;; Action: Ignored. - $urg - ;;; CPU time limit exceeded. - ;;; Action: Terminates the process. - $xcpu - ;;; File size limit exceeded. - ;;; Action: Terminates the process. - $xfsz - ;;; Virtual timer expired. - ;;; Action: Terminates the process. - $vtalrm - ;;; Profiling timer expired. - ;;; Action: Terminates the process. - $prof - ;;; Window changed. - ;;; Action: Ignored. - $winch - ;;; I/O possible. - ;;; Action: Terminates the process. - $poll - ;;; Power failure. - ;;; Action: Terminates the process. - $pwr - ;;; Bad system call. - ;;; Action: Terminates the process. - $sys - ) -) - -;;; Flags provided to `sock_recv`. -(typename $riflags - (flags (@witx repr u16) - ;;; Returns the message without removing it from the socket's receive queue. - $recv_peek - ;;; On byte-stream sockets, block until the full amount of data can be returned. - $recv_waitall - ) -) - -;;; Flags returned by `sock_recv`. -(typename $roflags - (flags (@witx repr u16) - ;;; Returned by `sock_recv`: Message data has been truncated. - $recv_data_truncated - ) -) - -;;; Flags provided to `sock_send`. As there are currently no flags -;;; defined, it must be set to zero. -(typename $siflags u16) - -;;; Which channels on a socket to shut down. -(typename $sdflags - (flags (@witx repr u8) - ;;; Disables further receive operations. - $rd - ;;; Disables further send operations. - $wr - ) -) - -;;; Identifiers for preopened capabilities. -(typename $preopentype - (enum (@witx tag u8) - ;;; A pre-opened directory. - $dir - ) -) - -;;; The contents of a $prestat when type is `preopentype::dir`. -(typename $prestat_dir - (record - ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size) - ) -) - -;;; Information about a pre-opened capability. -(typename $prestat - (union (@witx tag $preopentype) - $prestat_dir - ) -) diff --git a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx deleted file mode 100644 index dbece2641..000000000 --- a/proposals/clocks/phases/old/snapshot_0/witx/wasi_unstable.witx +++ /dev/null @@ -1,513 +0,0 @@ -;; WASI Preview. This is an evolution of the API that WASI initially -;; launched with. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -;;; This API predated the convention of naming modules with a `wasi_unstable_` -;;; prefix and a version number. It is preserved here for compatibility, but -;;; we shouldn't follow this pattern in new APIs. -(module $wasi_unstable - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `args_sizes_get`. - ;;; Each argument is expected to be `\0` terminated. - (@interface func (export "args_get") - (param $argv (@witx pointer (@witx pointer u8))) - (param $argv_buf (@witx pointer u8)) - (result $error (expected (error $errno))) - ) - ;;; Return command-line argument data sizes. - (@interface func (export "args_sizes_get") - ;;; Returns the number of arguments and the size of the argument string - ;;; data, or an error. - (result $error (expected (tuple $size $size) (error $errno))) - ) - - ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. - ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - (@interface func (export "environ_get") - (param $environ (@witx pointer (@witx pointer u8))) - (param $environ_buf (@witx pointer u8)) - (result $error (expected (error $errno))) - ) - ;;; Return environment variable data sizes. - (@interface func (export "environ_sizes_get") - ;;; Returns the number of environment variable arguments and the size of the - ;;; environment variable data. - (result $error (expected (tuple $size $size) (error $errno))) - ) - - ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return - ;;; `errno::inval`. - ;;; Note: This is similar to `clock_getres` in POSIX. - (@interface func (export "clock_res_get") - ;;; The clock for which to return the resolution. - (param $id $clockid) - ;;; The resolution of the clock, or an error if one happened. - (result $error (expected $timestamp (error $errno))) - ) - ;;; Return the time value of a clock. - ;;; Note: This is similar to `clock_gettime` in POSIX. - (@interface func (export "clock_time_get") - ;;; The clock for which to return the time. - (param $id $clockid) - ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp) - ;;; The time value of the clock. - (result $error (expected $timestamp (error $errno))) - ) - - ;;; Provide file advisory information on a file descriptor. - ;;; Note: This is similar to `posix_fadvise` in POSIX. - (@interface func (export "fd_advise") - (param $fd $fd) - ;;; The offset within the file to which the advisory applies. - (param $offset $filesize) - ;;; The length of the region to which the advisory applies. - (param $len $filesize) - ;;; The advice. - (param $advice $advice) - (result $error (expected (error $errno))) - ) - - ;;; Force the allocation of space in a file. - ;;; Note: This is similar to `posix_fallocate` in POSIX. - (@interface func (export "fd_allocate") - (param $fd $fd) - ;;; The offset at which to start the allocation. - (param $offset $filesize) - ;;; The length of the area that is allocated. - (param $len $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Close a file descriptor. - ;;; Note: This is similar to `close` in POSIX. - (@interface func (export "fd_close") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Synchronize the data of a file to disk. - ;;; Note: This is similar to `fdatasync` in POSIX. - (@interface func (export "fd_datasync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Get the attributes of a file descriptor. - ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (@interface func (export "fd_fdstat_get") - (param $fd $fd) - ;;; The buffer where the file descriptor's attributes are stored. - (result $error (expected $fdstat (error $errno))) - ) - - ;;; Adjust the flags associated with a file descriptor. - ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd) - ;;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights - (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd) - ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of an open file. - (@interface func (export "fd_filestat_get") - (param $fd $fd) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;;; Note: This is similar to `ftruncate` in POSIX. - (@interface func (export "fd_filestat_set_size") - (param $fd $fd) - ;;; The desired file size. - (param $size $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the timestamps of an open file or directory. - ;;; Note: This is similar to `futimens` in POSIX. - (@interface func (export "fd_filestat_set_times") - (param $fd $fd) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in POSIX. - (@interface func (export "fd_pread") - (param $fd $fd) - ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_array) - ;;; The offset within the file at which to read. - (param $offset $filesize) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_get") - (param $fd $fd) - ;;; The buffer where the description is stored. - (result $error (expected $prestat (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_dir_name") - (param $fd $fd) - ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer u8)) - (param $path_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in POSIX. - (@interface func (export "fd_pwrite") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The offset within the file at which to write. - (param $offset $filesize) - ;;; The number of bytes written. - (result $error (expected $size (error $errno))) - ) - - ;;; Read from a file descriptor. - ;;; Note: This is similar to `readv` in POSIX. - (@interface func (export "fd_read") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_array) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Read directory entries from a directory. - ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a `dirent` object, - ;;; followed by `dirent::d_namlen` bytes holding the name of the directory - ;;; entry. - ;; - ;;; This function fills the output buffer as much as possible, potentially - ;;; truncating the last directory entry. This allows the caller to grow its - ;;; read buffer size in case it's too small to fit a single large directory - ;;; entry, or skip the oversized directory entry. - (@interface func (export "fd_readdir") - (param $fd $fd) - ;;; The buffer where directory entries are stored - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The location within the directory to start reading - (param $cookie $dircookie) - ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $error (expected $size (error $errno))) - ) - - ;;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;;; Due to the strong focus on thread safety, this environment does not provide - ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;;; file descriptor with the same number could be allocated by a different - ;;; thread at the same time. - ;; - ;;; This function provides a way to atomically renumber file descriptors, which - ;;; would disappear if `dup2()` were to be removed entirely. - (@interface func (export "fd_renumber") - (param $fd $fd) - ;;; The file descriptor to overwrite. - (param $to $fd) - (result $error (expected (error $errno))) - ) - - ;;; Move the offset of a file descriptor. - ;;; Note: This is similar to `lseek` in POSIX. - (@interface func (export "fd_seek") - (param $fd $fd) - ;;; The number of bytes to move. - (param $offset $filedelta) - ;;; The base from which the offset is relative. - (param $whence $whence) - ;;; The new offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Synchronize the data and metadata of a file to disk. - ;;; Note: This is similar to `fsync` in POSIX. - (@interface func (export "fd_sync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Return the current offset of a file descriptor. - ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (@interface func (export "fd_tell") - (param $fd $fd) - ;;; The current offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Write to a file descriptor. - ;;; Note: This is similar to `writev` in POSIX. - (@interface func (export "fd_write") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - (result $error (expected $size (error $errno))) - ) - - ;;; Create a directory. - ;;; Note: This is similar to `mkdirat` in POSIX. - (@interface func (export "path_create_directory") - (param $fd $fd) - ;;; The path at which to create the directory. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of a file or directory. - ;;; Note: This is similar to `stat` in POSIX. - (@interface func (export "path_filestat_get") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to inspect. - (param $path string) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the timestamps of a file or directory. - ;;; Note: This is similar to `utimensat` in POSIX. - (@interface func (export "path_filestat_set_times") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to operate on. - (param $path string) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Create a hard link. - ;;; Note: This is similar to `linkat` in POSIX. - (@interface func (export "path_link") - (param $old_fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags) - ;;; The source path from which to link. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path at which to create the hard link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Open a file or directory. - ;; - ;;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;;; file descriptor not currently open; it is randomized to prevent - ;;; applications from depending on making assumptions about indexes, since this - ;;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;;; guaranteed to be less than 2**31. - ;; - ;;; Note: This is similar to `openat` in POSIX. - (@interface func (export "path_open") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags) - ;;; The relative path of the file or directory to open, relative to the - ;;; `path_open::fd` directory. - (param $path string) - ;;; The method by which to open the file. - (param $oflags $oflags) - ;;; The initial rights of the newly created file descriptor. The - ;;; implementation is allowed to return a file descriptor with fewer rights - ;;; than specified, if and only if those rights do not apply to the type of - ;;; file being opened. - ;; - ;;; The *base* rights are rights that will apply to operations using the file - ;;; descriptor itself, while the *inheriting* rights are rights that apply to - ;;; file descriptors derived from it. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (param $fdflags $fdflags) - ;;; The file descriptor of the file that has been opened. - (result $error (expected $fd (error $errno))) - ) - - ;;; Read the contents of a symbolic link. - ;;; Note: This is similar to `readlinkat` in POSIX. - (@interface func (export "path_readlink") - (param $fd $fd) - ;;; The path of the symbolic link from which to read. - (param $path string) - ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The number of bytes placed in the buffer. - (result $error (expected $size (error $errno))) - ) - - ;;; Remove a directory. - ;;; Return `errno::notempty` if the directory is not empty. - ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (@interface func (export "path_remove_directory") - (param $fd $fd) - ;;; The path to a directory to remove. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Rename a file or directory. - ;;; Note: This is similar to `renameat` in POSIX. - (@interface func (export "path_rename") - (param $fd $fd) - ;;; The source path of the file or directory to rename. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Create a symbolic link. - ;;; Note: This is similar to `symlinkat` in POSIX. - (@interface func (export "path_symlink") - ;;; The contents of the symbolic link. - (param $old_path string) - (param $fd $fd) - ;;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - - ;;; Unlink a file. - ;;; Return `errno::isdir` if the path refers to a directory. - ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (@interface func (export "path_unlink_file") - (param $fd $fd) - ;;; The path to a file to unlink. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Concurrently poll for the occurrence of a set of events. - (@interface func (export "poll_oneoff") - ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription)) - ;;; The events that have occurred. - (param $out (@witx pointer $event)) - ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size) - ;;; The number of events stored. - (result $error (expected $size (error $errno))) - ) - - ;;; Terminate the process normally. An exit code of 0 indicates successful - ;;; termination of the program. The meanings of other values is dependent on - ;;; the environment. - (@interface func (export "proc_exit") - ;;; The exit code returned by the process. - (param $rval $exitcode) - (@witx noreturn) - ) - - ;;; Send a signal to the process of the calling thread. - ;;; Note: This is similar to `raise` in POSIX. - (@interface func (export "proc_raise") - ;;; The signal condition to trigger. - (param $sig $signal) - (result $error (expected (error $errno))) - ) - - ;;; Temporarily yield execution of the calling thread. - ;;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "sched_yield") - (result $error (expected (error $errno))) - ) - - ;;; Write high-quality random data into a buffer. - ;;; This function blocks when the implementation is unable to immediately - ;;; provide sufficient high-quality random data. - ;;; This function may execute slowly, so when large mounts of random data are - ;;; required, it's advisable to use this function to seed a pseudo-random - ;;; number generator, rather than to provide the random data directly. - (@interface func (export "random_get") - ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Receive a message from a socket. - ;;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;;; the data into multiple buffers in the manner of `readv`. - (@interface func (export "sock_recv") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_array) - ;;; Message flags. - (param $ri_flags $riflags) - ;;; Number of bytes stored in ri_data and message flags. - (result $error (expected (tuple $size $roflags) (error $errno))) - ) - - ;;; Send a message on a socket. - ;;; Note: This is similar to `send` in POSIX, though it also supports writing - ;;; the data from multiple buffers in the manner of `writev`. - (@interface func (export "sock_send") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_array) - ;;; Message flags. - (param $si_flags $siflags) - ;;; Number of bytes transmitted. - (result $error (expected $size (error $errno))) - ) - - ;;; Shut down socket send and receive channels. - ;;; Note: This is similar to `shutdown` in POSIX. - (@interface func (export "sock_shutdown") - (param $fd $fd) - ;;; Which channels on the socket to shut down. - (param $how $sdflags) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/clocks/phases/snapshot/docs.html b/proposals/clocks/phases/snapshot/docs.html deleted file mode 100644 index 83ea3c7d2..000000000 --- a/proposals/clocks/phases/snapshot/docs.html +++ /dev/null @@ -1,1279 +0,0 @@ -

Types

-

<a href="#size" name="size"></a> size: u32

-

Size: 4
Alignment: 4

-

<a href="#filesize" name="filesize"></a> filesize: u64

-

Non-negative file size or length of a region within a file.
Size: 8
Alignment: 8

-

<a href="#timestamp" name="timestamp"></a> timestamp: u64

-

Timestamp in nanoseconds.
Size: 8
Alignment: 8

-

<a href="#clockid" name="clockid"></a> clockid: Enum(u32)

-

Identifiers for clocks.
Size: 4
Alignment: 4

-

Variants

-
    -
  • <a href="#clockid.realtime" name="clockid.realtime"></a> realtime
    The clock measuring real time. Time value zero corresponds with
    1970-01-01T00:00:00Z.

    -
  • -
  • <a href="#clockid.monotonic" name="clockid.monotonic"></a> monotonic
    The store-wide monotonic clock, which is defined as a clock measuring
    real time, whose value cannot be adjusted and which cannot have negative
    clock jumps. The epoch of this clock is undefined. The absolute time
    value of this clock therefore has no meaning.

    -
  • -
  • <a href="#clockid.process_cputime_id" name="clockid.process_cputime_id"></a> process_cputime_id
    The CPU-time clock associated with the current process.

    -
  • -
  • <a href="#clockid.thread_cputime_id" name="clockid.thread_cputime_id"></a> thread_cputime_id
    The CPU-time clock associated with the current thread.

    -
  • -
-

<a href="#errno" name="errno"></a> errno: Enum(u16)

-

Error codes returned by functions.
Not all of these error codes are returned by the functions provided by this
API; some are used in higher-level library layers, and others are provided
merely for alignment with POSIX.
Size: 2
Alignment: 2

-

Variants

-
    -
  • <a href="#errno.success" name="errno.success"></a> success
    No error occurred. System call completed successfully.

    -
  • -
  • <a href="#errno.2big" name="errno.2big"></a> 2big
    Argument list too long.

    -
  • -
  • <a href="#errno.acces" name="errno.acces"></a> acces
    Permission denied.

    -
  • -
  • <a href="#errno.addrinuse" name="errno.addrinuse"></a> addrinuse
    Address in use.

    -
  • -
  • <a href="#errno.addrnotavail" name="errno.addrnotavail"></a> addrnotavail
    Address not available.

    -
  • -
  • <a href="#errno.afnosupport" name="errno.afnosupport"></a> afnosupport
    Address family not supported.

    -
  • -
  • <a href="#errno.again" name="errno.again"></a> again
    Resource unavailable, or operation would block.

    -
  • -
  • <a href="#errno.already" name="errno.already"></a> already
    Connection already in progress.

    -
  • -
  • <a href="#errno.badf" name="errno.badf"></a> badf
    Bad file descriptor.

    -
  • -
  • <a href="#errno.badmsg" name="errno.badmsg"></a> badmsg
    Bad message.

    -
  • -
  • <a href="#errno.busy" name="errno.busy"></a> busy
    Device or resource busy.

    -
  • -
  • <a href="#errno.canceled" name="errno.canceled"></a> canceled
    Operation canceled.

    -
  • -
  • <a href="#errno.child" name="errno.child"></a> child
    No child processes.

    -
  • -
  • <a href="#errno.connaborted" name="errno.connaborted"></a> connaborted
    Connection aborted.

    -
  • -
  • <a href="#errno.connrefused" name="errno.connrefused"></a> connrefused
    Connection refused.

    -
  • -
  • <a href="#errno.connreset" name="errno.connreset"></a> connreset
    Connection reset.

    -
  • -
  • <a href="#errno.deadlk" name="errno.deadlk"></a> deadlk
    Resource deadlock would occur.

    -
  • -
  • <a href="#errno.destaddrreq" name="errno.destaddrreq"></a> destaddrreq
    Destination address required.

    -
  • -
  • <a href="#errno.dom" name="errno.dom"></a> dom
    Mathematics argument out of domain of function.

    -
  • -
  • <a href="#errno.dquot" name="errno.dquot"></a> dquot
    Reserved.

    -
  • -
  • <a href="#errno.exist" name="errno.exist"></a> exist
    File exists.

    -
  • -
  • <a href="#errno.fault" name="errno.fault"></a> fault
    Bad address.

    -
  • -
  • <a href="#errno.fbig" name="errno.fbig"></a> fbig
    File too large.

    -
  • -
  • <a href="#errno.hostunreach" name="errno.hostunreach"></a> hostunreach
    Host is unreachable.

    -
  • -
  • <a href="#errno.idrm" name="errno.idrm"></a> idrm
    Identifier removed.

    -
  • -
  • <a href="#errno.ilseq" name="errno.ilseq"></a> ilseq
    Illegal byte sequence.

    -
  • -
  • <a href="#errno.inprogress" name="errno.inprogress"></a> inprogress
    Operation in progress.

    -
  • -
  • <a href="#errno.intr" name="errno.intr"></a> intr
    Interrupted function.

    -
  • -
  • <a href="#errno.inval" name="errno.inval"></a> inval
    Invalid argument.

    -
  • -
  • <a href="#errno.io" name="errno.io"></a> io
    I/O error.

    -
  • -
  • <a href="#errno.isconn" name="errno.isconn"></a> isconn
    Socket is connected.

    -
  • -
  • <a href="#errno.isdir" name="errno.isdir"></a> isdir
    Is a directory.

    -
  • -
  • <a href="#errno.loop" name="errno.loop"></a> loop
    Too many levels of symbolic links.

    -
  • -
  • <a href="#errno.mfile" name="errno.mfile"></a> mfile
    File descriptor value too large.

    -
  • -
  • <a href="#errno.mlink" name="errno.mlink"></a> mlink
    Too many links.

    -
  • -
  • <a href="#errno.msgsize" name="errno.msgsize"></a> msgsize
    Message too large.

    -
  • -
  • <a href="#errno.multihop" name="errno.multihop"></a> multihop
    Reserved.

    -
  • -
  • <a href="#errno.nametoolong" name="errno.nametoolong"></a> nametoolong
    Filename too long.

    -
  • -
  • <a href="#errno.netdown" name="errno.netdown"></a> netdown
    Network is down.

    -
  • -
  • <a href="#errno.netreset" name="errno.netreset"></a> netreset
    Connection aborted by network.

    -
  • -
  • <a href="#errno.netunreach" name="errno.netunreach"></a> netunreach
    Network unreachable.

    -
  • -
  • <a href="#errno.nfile" name="errno.nfile"></a> nfile
    Too many files open in system.

    -
  • -
  • <a href="#errno.nobufs" name="errno.nobufs"></a> nobufs
    No buffer space available.

    -
  • -
  • <a href="#errno.nodev" name="errno.nodev"></a> nodev
    No such device.

    -
  • -
  • <a href="#errno.noent" name="errno.noent"></a> noent
    No such file or directory.

    -
  • -
  • <a href="#errno.noexec" name="errno.noexec"></a> noexec
    Executable file format error.

    -
  • -
  • <a href="#errno.nolck" name="errno.nolck"></a> nolck
    No locks available.

    -
  • -
  • <a href="#errno.nolink" name="errno.nolink"></a> nolink
    Reserved.

    -
  • -
  • <a href="#errno.nomem" name="errno.nomem"></a> nomem
    Not enough space.

    -
  • -
  • <a href="#errno.nomsg" name="errno.nomsg"></a> nomsg
    No message of the desired type.

    -
  • -
  • <a href="#errno.noprotoopt" name="errno.noprotoopt"></a> noprotoopt
    Protocol not available.

    -
  • -
  • <a href="#errno.nospc" name="errno.nospc"></a> nospc
    No space left on device.

    -
  • -
  • <a href="#errno.nosys" name="errno.nosys"></a> nosys
    Function not supported.

    -
  • -
  • <a href="#errno.notconn" name="errno.notconn"></a> notconn
    The socket is not connected.

    -
  • -
  • <a href="#errno.notdir" name="errno.notdir"></a> notdir
    Not a directory or a symbolic link to a directory.

    -
  • -
  • <a href="#errno.notempty" name="errno.notempty"></a> notempty
    Directory not empty.

    -
  • -
  • <a href="#errno.notrecoverable" name="errno.notrecoverable"></a> notrecoverable
    State not recoverable.

    -
  • -
  • <a href="#errno.notsock" name="errno.notsock"></a> notsock
    Not a socket.

    -
  • -
  • <a href="#errno.notsup" name="errno.notsup"></a> notsup
    Not supported, or operation not supported on socket.

    -
  • -
  • <a href="#errno.notty" name="errno.notty"></a> notty
    Inappropriate I/O control operation.

    -
  • -
  • <a href="#errno.nxio" name="errno.nxio"></a> nxio
    No such device or address.

    -
  • -
  • <a href="#errno.overflow" name="errno.overflow"></a> overflow
    Value too large to be stored in data type.

    -
  • -
  • <a href="#errno.ownerdead" name="errno.ownerdead"></a> ownerdead
    Previous owner died.

    -
  • -
  • <a href="#errno.perm" name="errno.perm"></a> perm
    Operation not permitted.

    -
  • -
  • <a href="#errno.pipe" name="errno.pipe"></a> pipe
    Broken pipe.

    -
  • -
  • <a href="#errno.proto" name="errno.proto"></a> proto
    Protocol error.

    -
  • -
  • <a href="#errno.protonosupport" name="errno.protonosupport"></a> protonosupport
    Protocol not supported.

    -
  • -
  • <a href="#errno.prototype" name="errno.prototype"></a> prototype
    Protocol wrong type for socket.

    -
  • -
  • <a href="#errno.range" name="errno.range"></a> range
    Result too large.

    -
  • -
  • <a href="#errno.rofs" name="errno.rofs"></a> rofs
    Read-only file system.

    -
  • -
  • <a href="#errno.spipe" name="errno.spipe"></a> spipe
    Invalid seek.

    -
  • -
  • <a href="#errno.srch" name="errno.srch"></a> srch
    No such process.

    -
  • -
  • <a href="#errno.stale" name="errno.stale"></a> stale
    Reserved.

    -
  • -
  • <a href="#errno.timedout" name="errno.timedout"></a> timedout
    Connection timed out.

    -
  • -
  • <a href="#errno.txtbsy" name="errno.txtbsy"></a> txtbsy
    Text file busy.

    -
  • -
  • <a href="#errno.xdev" name="errno.xdev"></a> xdev
    Cross-device link.

    -
  • -
  • <a href="#errno.notcapable" name="errno.notcapable"></a> notcapable
    Extension: Capabilities insufficient.

    -
  • -
-

<a href="#rights" name="rights"></a> rights: Flags(u64)

-

File descriptor rights, determining which actions may be performed.
Size: 8
Alignment: 8

-

Flags

-
    -
  • <a href="#rights.fd_datasync" name="rights.fd_datasync"></a> fd_datasync
    The right to invoke fd_datasync.
    If path_open is set, includes the right to invoke
    path_open with fdflags::dsync.

    -
  • -
  • <a href="#rights.fd_read" name="rights.fd_read"></a> fd_read
    The right to invoke fd_read and sock_recv.
    If rights::fd_seek is set, includes the right to invoke fd_pread.

    -
  • -
  • <a href="#rights.fd_seek" name="rights.fd_seek"></a> fd_seek
    The right to invoke fd_seek. This flag implies rights::fd_tell.

    -
  • -
  • <a href="#rights.fd_fdstat_set_flags" name="rights.fd_fdstat_set_flags"></a> fd_fdstat_set_flags
    The right to invoke fd_fdstat_set_flags.

    -
  • -
  • <a href="#rights.fd_sync" name="rights.fd_sync"></a> fd_sync
    The right to invoke fd_sync.
    If path_open is set, includes the right to invoke
    path_open with fdflags::rsync and fdflags::dsync.

    -
  • -
  • <a href="#rights.fd_tell" name="rights.fd_tell"></a> fd_tell
    The right to invoke fd_seek in such a way that the file offset
    remains unaltered (i.e., whence::cur with offset zero), or to
    invoke fd_tell.

    -
  • -
  • <a href="#rights.fd_write" name="rights.fd_write"></a> fd_write
    The right to invoke fd_write and sock_send.
    If rights::fd_seek is set, includes the right to invoke fd_pwrite.

    -
  • -
  • <a href="#rights.fd_advise" name="rights.fd_advise"></a> fd_advise
    The right to invoke fd_advise.

    -
  • -
  • <a href="#rights.fd_allocate" name="rights.fd_allocate"></a> fd_allocate
    The right to invoke fd_allocate.

    -
  • -
  • <a href="#rights.path_create_directory" name="rights.path_create_directory"></a> path_create_directory
    The right to invoke path_create_directory.

    -
  • -
  • <a href="#rights.path_create_file" name="rights.path_create_file"></a> path_create_file
    If path_open is set, the right to invoke path_open with oflags::creat.

    -
  • -
  • <a href="#rights.path_link_source" name="rights.path_link_source"></a> path_link_source
    The right to invoke path_link with the file descriptor as the
    source directory.

    -
  • -
  • <a href="#rights.path_link_target" name="rights.path_link_target"></a> path_link_target
    The right to invoke path_link with the file descriptor as the
    target directory.

    -
  • -
  • <a href="#rights.path_open" name="rights.path_open"></a> path_open
    The right to invoke path_open.

    -
  • -
  • <a href="#rights.fd_readdir" name="rights.fd_readdir"></a> fd_readdir
    The right to invoke fd_readdir.

    -
  • -
  • <a href="#rights.path_readlink" name="rights.path_readlink"></a> path_readlink
    The right to invoke path_readlink.

    -
  • -
  • <a href="#rights.path_rename_source" name="rights.path_rename_source"></a> path_rename_source
    The right to invoke path_rename with the file descriptor as the source directory.

    -
  • -
  • <a href="#rights.path_rename_target" name="rights.path_rename_target"></a> path_rename_target
    The right to invoke path_rename with the file descriptor as the target directory.

    -
  • -
  • <a href="#rights.path_filestat_get" name="rights.path_filestat_get"></a> path_filestat_get
    The right to invoke path_filestat_get.

    -
  • -
  • <a href="#rights.path_filestat_set_size" name="rights.path_filestat_set_size"></a> path_filestat_set_size
    The right to change a file's size (there is no path_filestat_set_size).
    If path_open is set, includes the right to invoke path_open with oflags::trunc.

    -
  • -
  • <a href="#rights.path_filestat_set_times" name="rights.path_filestat_set_times"></a> path_filestat_set_times
    The right to invoke path_filestat_set_times.

    -
  • -
  • <a href="#rights.fd_filestat_get" name="rights.fd_filestat_get"></a> fd_filestat_get
    The right to invoke fd_filestat_get.

    -
  • -
  • <a href="#rights.fd_filestat_set_size" name="rights.fd_filestat_set_size"></a> fd_filestat_set_size
    The right to invoke fd_filestat_set_size.

    -
  • -
  • <a href="#rights.fd_filestat_set_times" name="rights.fd_filestat_set_times"></a> fd_filestat_set_times
    The right to invoke fd_filestat_set_times.

    -
  • -
  • <a href="#rights.path_symlink" name="rights.path_symlink"></a> path_symlink
    The right to invoke path_symlink.

    -
  • -
  • <a href="#rights.path_remove_directory" name="rights.path_remove_directory"></a> path_remove_directory
    The right to invoke path_remove_directory.

    -
  • -
  • <a href="#rights.path_unlink_file" name="rights.path_unlink_file"></a> path_unlink_file
    The right to invoke path_unlink_file.

    -
  • -
  • <a href="#rights.poll_fd_readwrite" name="rights.poll_fd_readwrite"></a> poll_fd_readwrite
    If rights::fd_read is set, includes the right to invoke poll_oneoff to subscribe to eventtype::fd_read.
    If rights::fd_write is set, includes the right to invoke poll_oneoff to subscribe to eventtype::fd_write.

    -
  • -
  • <a href="#rights.sock_shutdown" name="rights.sock_shutdown"></a> sock_shutdown
    The right to invoke sock_shutdown.

    -
  • -
-

<a href="#fd" name="fd"></a> fd

-

A file descriptor handle.
Size: 4
Alignment: 4

-

Supertypes

-

<a href="#iovec" name="iovec"></a> iovec: Struct

-

A region of memory for scatter/gather reads.
Size: 8
Alignment: 4

-

Struct members

-
    -
  • <a href="#iovec.buf" name="iovec.buf"></a> buf: Pointer<u8>
    The address of the buffer to be filled.
    Offset: 0
  • -
  • <a href="#iovec.buf_len" name="iovec.buf_len"></a> buf_len: size
    The length of the buffer to be filled.
    Offset: 4

    <a href="#ciovec" name="ciovec"></a> ciovec: Struct

    -A region of memory for scatter/gather writes.
    Size: 8
    Alignment: 4

    Struct members

    -
  • -
  • <a href="#ciovec.buf" name="ciovec.buf"></a> buf: ConstPointer<u8>
    The address of the buffer to be written.
    Offset: 0
  • -
  • <a href="#ciovec.buf_len" name="ciovec.buf_len"></a> buf_len: size
    The length of the buffer to be written.
    Offset: 4

    <a href="#iovec_array" name="iovec_array"></a> iovec_array: Array<iovec>

    -Size: 8
    Alignment: 4

    <a href="#ciovec_array" name="ciovec_array"></a> ciovec_array: Array<ciovec>

    -Size: 8
    Alignment: 4

    <a href="#filedelta" name="filedelta"></a> filedelta: s64

    -Relative offset within a file.
    Size: 8
    Alignment: 8

    <a href="#whence" name="whence"></a> whence: Enum(u8)

    -The position relative to which to set the offset of the file descriptor.
    Size: 1
    Alignment: 1

    Variants

    -
  • -
  • <a href="#whence.set" name="whence.set"></a> set
    Seek relative to start-of-file.

    -
  • -
  • <a href="#whence.cur" name="whence.cur"></a> cur
    Seek relative to current position.

    -
  • -
  • <a href="#whence.end" name="whence.end"></a> end
    Seek relative to end-of-file.

    -
  • -
-

<a href="#dircookie" name="dircookie"></a> dircookie: u64

-

A reference to the offset of a directory entry.

-

The value 0 signifies the start of the directory.
Size: 8
Alignment: 8

-

<a href="#dirnamlen" name="dirnamlen"></a> dirnamlen: u32

-

The type for the $d_namlen field of $dirent.
Size: 4
Alignment: 4

-

<a href="#inode" name="inode"></a> inode: u64

-

File serial number that is unique within its file system.
Size: 8
Alignment: 8

-

<a href="#filetype" name="filetype"></a> filetype: Enum(u8)

-

The type of a file descriptor or file.
Size: 1
Alignment: 1

-

Variants

-
    -
  • <a href="#filetype.unknown" name="filetype.unknown"></a> unknown
    The type of the file descriptor or file is unknown or is different from any of the other types specified.

    -
  • -
  • <a href="#filetype.block_device" name="filetype.block_device"></a> block_device
    The file descriptor or file refers to a block device inode.

    -
  • -
  • <a href="#filetype.character_device" name="filetype.character_device"></a> character_device
    The file descriptor or file refers to a character device inode.

    -
  • -
  • <a href="#filetype.directory" name="filetype.directory"></a> directory
    The file descriptor or file refers to a directory inode.

    -
  • -
  • <a href="#filetype.regular_file" name="filetype.regular_file"></a> regular_file
    The file descriptor or file refers to a regular file inode.

    -
  • -
  • <a href="#filetype.socket_dgram" name="filetype.socket_dgram"></a> socket_dgram
    The file descriptor or file refers to a datagram socket.

    -
  • -
  • <a href="#filetype.socket_stream" name="filetype.socket_stream"></a> socket_stream
    The file descriptor or file refers to a byte-stream socket.

    -
  • -
  • <a href="#filetype.symbolic_link" name="filetype.symbolic_link"></a> symbolic_link
    The file refers to a symbolic link inode.

    -
  • -
-

<a href="#dirent" name="dirent"></a> dirent: Struct

-

A directory entry.
Size: 24
Alignment: 8

-

Struct members

-
    -
  • <a href="#dirent.d_next" name="dirent.d_next"></a> d_next: dircookie
    The offset of the next directory entry stored in this directory.
    Offset: 0
  • -
  • <a href="#dirent.d_ino" name="dirent.d_ino"></a> d_ino: inode
    The serial number of the file referred to by this directory entry.
    Offset: 8
  • -
  • <a href="#dirent.d_namlen" name="dirent.d_namlen"></a> d_namlen: dirnamlen
    The length of the name of the directory entry.
    Offset: 16
  • -
  • <a href="#dirent.d_type" name="dirent.d_type"></a> d_type: filetype
    The type of the file referred to by this directory entry.
    Offset: 20

    <a href="#advice" name="advice"></a> advice: Enum(u8)

    -File or memory access pattern advisory information.
    Size: 1
    Alignment: 1

    Variants

    -
  • -
  • <a href="#advice.normal" name="advice.normal"></a> normal
    The application has no advice to give on its behavior with respect to the specified data.

    -
  • -
  • <a href="#advice.sequential" name="advice.sequential"></a> sequential
    The application expects to access the specified data sequentially from lower offsets to higher offsets.

    -
  • -
  • <a href="#advice.random" name="advice.random"></a> random
    The application expects to access the specified data in a random order.

    -
  • -
  • <a href="#advice.willneed" name="advice.willneed"></a> willneed
    The application expects to access the specified data in the near future.

    -
  • -
  • <a href="#advice.dontneed" name="advice.dontneed"></a> dontneed
    The application expects that it will not access the specified data in the near future.

    -
  • -
  • <a href="#advice.noreuse" name="advice.noreuse"></a> noreuse
    The application expects to access the specified data once and then not reuse it thereafter.

    -
  • -
-

<a href="#fdflags" name="fdflags"></a> fdflags: Flags(u16)

-

File descriptor flags.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#fdflags.append" name="fdflags.append"></a> append
    Append mode: Data written to the file is always appended to the file's end.

    -
  • -
  • <a href="#fdflags.dsync" name="fdflags.dsync"></a> dsync
    Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized.

    -
  • -
  • <a href="#fdflags.nonblock" name="fdflags.nonblock"></a> nonblock
    Non-blocking mode.

    -
  • -
  • <a href="#fdflags.rsync" name="fdflags.rsync"></a> rsync
    Synchronized read I/O operations.

    -
  • -
  • <a href="#fdflags.sync" name="fdflags.sync"></a> sync
    Write according to synchronized I/O file integrity completion. In
    addition to synchronizing the data stored in the file, the implementation
    may also synchronously update the file's metadata.

    -
  • -
-

<a href="#fdstat" name="fdstat"></a> fdstat: Struct

-

File descriptor attributes.
Size: 24
Alignment: 8

-

Struct members

-
    -
  • <a href="#fdstat.fs_filetype" name="fdstat.fs_filetype"></a> fs_filetype: filetype
    File type.
    Offset: 0
  • -
  • <a href="#fdstat.fs_flags" name="fdstat.fs_flags"></a> fs_flags: fdflags
    File descriptor flags.
    Offset: 2
  • -
  • <a href="#fdstat.fs_rights_base" name="fdstat.fs_rights_base"></a> fs_rights_base: rights
    Rights that apply to this file descriptor.
    Offset: 8
  • -
  • <a href="#fdstat.fs_rights_inheriting" name="fdstat.fs_rights_inheriting"></a> fs_rights_inheriting: rights
    Maximum set of rights that may be installed on new file descriptors that
    are created through this file descriptor, e.g., through path_open.
    Offset: 16

    <a href="#device" name="device"></a> device: u64

    -Identifier for a device containing a file system. Can be used in combination
    with inode to uniquely identify a file or directory in the filesystem.
    Size: 8
    Alignment: 8

    <a href="#fstflags" name="fstflags"></a> fstflags: Flags(u16)

    -Which file time attributes to adjust.
    Size: 2
    Alignment: 2

    Flags

    -
  • -
  • <a href="#fstflags.atim" name="fstflags.atim"></a> atim
    Adjust the last data access timestamp to the value stored in filestat::atim.

    -
  • -
  • <a href="#fstflags.atim_now" name="fstflags.atim_now"></a> atim_now
    Adjust the last data access timestamp to the time of clock clockid::realtime.

    -
  • -
  • <a href="#fstflags.mtim" name="fstflags.mtim"></a> mtim
    Adjust the last data modification timestamp to the value stored in filestat::mtim.

    -
  • -
  • <a href="#fstflags.mtim_now" name="fstflags.mtim_now"></a> mtim_now
    Adjust the last data modification timestamp to the time of clock clockid::realtime.

    -
  • -
-

<a href="#lookupflags" name="lookupflags"></a> lookupflags: Flags(u32)

-

Flags determining the method of how paths are resolved.
Size: 4
Alignment: 4

-

Flags

-
    -
  • <a href="#lookupflags.symlink_follow" name="lookupflags.symlink_follow"></a> symlink_follow
    As long as the resolved path corresponds to a symbolic link, it is expanded.
  • -
-

<a href="#oflags" name="oflags"></a> oflags: Flags(u16)

-

Open flags used by path_open.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#oflags.creat" name="oflags.creat"></a> creat
    Create file if it does not exist.

    -
  • -
  • <a href="#oflags.directory" name="oflags.directory"></a> directory
    Fail if not a directory.

    -
  • -
  • <a href="#oflags.excl" name="oflags.excl"></a> excl
    Fail if file already exists.

    -
  • -
  • <a href="#oflags.trunc" name="oflags.trunc"></a> trunc
    Truncate file to size 0.

    -
  • -
-

<a href="#linkcount" name="linkcount"></a> linkcount: u64

-

Number of hard links to an inode.
Size: 8
Alignment: 8

-

<a href="#filestat" name="filestat"></a> filestat: Struct

-

File attributes.
Size: 64
Alignment: 8

-

Struct members

-
    -
  • <a href="#filestat.dev" name="filestat.dev"></a> dev: device
    Device ID of device containing the file.
    Offset: 0
  • -
  • <a href="#filestat.ino" name="filestat.ino"></a> ino: inode
    File serial number.
    Offset: 8
  • -
  • <a href="#filestat.filetype" name="filestat.filetype"></a> filetype: filetype
    File type.
    Offset: 16
  • -
  • <a href="#filestat.nlink" name="filestat.nlink"></a> nlink: linkcount
    Number of hard links to the file.
    Offset: 24
  • -
  • <a href="#filestat.size" name="filestat.size"></a> size: filesize
    For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link.
    Offset: 32
  • -
  • <a href="#filestat.atim" name="filestat.atim"></a> atim: timestamp
    Last data access timestamp.
    Offset: 40
  • -
  • <a href="#filestat.mtim" name="filestat.mtim"></a> mtim: timestamp
    Last data modification timestamp.
    Offset: 48
  • -
  • <a href="#filestat.ctim" name="filestat.ctim"></a> ctim: timestamp
    Last file status change timestamp.
    Offset: 56

    <a href="#userdata" name="userdata"></a> userdata: u64

    -User-provided value that may be attached to objects that is retained when
    extracted from the implementation.
    Size: 8
    Alignment: 8

    <a href="#eventtype" name="eventtype"></a> eventtype: Enum(u8)

    -Type of a subscription to an event or its occurrence.
    Size: 1
    Alignment: 1

    Variants

    -
  • -
  • <a href="#eventtype.clock" name="eventtype.clock"></a> clock
    The time value of clock subscription_clock::id has
    reached timestamp subscription_clock::timeout.

    -
  • -
  • <a href="#eventtype.fd_read" name="eventtype.fd_read"></a> fd_read
    File descriptor subscription_fd_readwrite::file_descriptor has data
    available for reading. This event always triggers for regular files.

    -
  • -
  • <a href="#eventtype.fd_write" name="eventtype.fd_write"></a> fd_write
    File descriptor subscription_fd_readwrite::file_descriptor has capacity
    available for writing. This event always triggers for regular files.

    -
  • -
-

<a href="#eventrwflags" name="eventrwflags"></a> eventrwflags: Flags(u16)

-

The state of the file descriptor subscribed to with
eventtype::fd_read or eventtype::fd_write.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#eventrwflags.fd_readwrite_hangup" name="eventrwflags.fd_readwrite_hangup"></a> fd_readwrite_hangup
    The peer of this socket has closed or disconnected.
  • -
-

<a href="#event_fd_readwrite" name="event_fd_readwrite"></a> event_fd_readwrite: Struct

-

The contents of an $event when type is eventtype::fd_read or
eventtype::fd_write.
Size: 16
Alignment: 8

-

Struct members

-
    -
  • <a href="#event_fd_readwrite.nbytes" name="event_fd_readwrite.nbytes"></a> nbytes: filesize
    The number of bytes available for reading or writing.
    Offset: 0
  • -
  • <a href="#event_fd_readwrite.flags" name="event_fd_readwrite.flags"></a> flags: eventrwflags
    The state of the file descriptor.
    Offset: 8

    <a href="#event" name="event"></a> event: Struct

    -An event that occurred.
    Size: 32
    Alignment: 8

    Struct members

    -
  • -
  • <a href="#event.userdata" name="event.userdata"></a> userdata: userdata
    User-provided value that got attached to subscription::userdata.
    Offset: 0
  • -
  • <a href="#event.error" name="event.error"></a> error: errno
    If non-zero, an error that occurred while processing the subscription request.
    Offset: 8
  • -
  • <a href="#event.type" name="event.type"></a> type: eventtype
    The type of event that occured
    Offset: 10
  • -
  • <a href="#event.fd_readwrite" name="event.fd_readwrite"></a> fd_readwrite: event_fd_readwrite
    The contents of the event, if it is an eventtype::fd_read or
    eventtype::fd_write. eventtype::clock events ignore this field.
    Offset: 16

    <a href="#subclockflags" name="subclockflags"></a> subclockflags: Flags(u16)

    -Flags determining how to interpret the timestamp provided in
    subscription_clock::timeout.
    Size: 2
    Alignment: 2

    Flags

    -
  • -
  • <a href="#subclockflags.subscription_clock_abstime" name="subclockflags.subscription_clock_abstime"></a> subscription_clock_abstime
    If set, treat the timestamp provided in
    subscription_clock::timeout as an absolute timestamp of clock
    subscription_clock::id. If clear, treat the timestamp
    provided in subscription_clock::timeout relative to the
    current time value of clock subscription_clock::id.
  • -
-

<a href="#subscription_clock" name="subscription_clock"></a> subscription_clock: Struct

-

The contents of a subscription when type is eventtype::clock.
Size: 32
Alignment: 8

-

Struct members

-
    -
  • <a href="#subscription_clock.id" name="subscription_clock.id"></a> id: clockid
    The clock against which to compare the timestamp.
    Offset: 0
  • -
  • <a href="#subscription_clock.timeout" name="subscription_clock.timeout"></a> timeout: timestamp
    The absolute or relative timestamp.
    Offset: 8
  • -
  • <a href="#subscription_clock.precision" name="subscription_clock.precision"></a> precision: timestamp
    The amount of time that the implementation may wait additionally
    to coalesce with other events.
    Offset: 16
  • -
  • <a href="#subscription_clock.flags" name="subscription_clock.flags"></a> flags: subclockflags
    Flags specifying whether the timeout is absolute or relative
    Offset: 24

    <a href="#subscription_fd_readwrite" name="subscription_fd_readwrite"></a> subscription_fd_readwrite: Struct

    -The contents of a subscription when type is type is
    eventtype::fd_read or eventtype::fd_write.
    Size: 4
    Alignment: 4

    Struct members

    -
  • -
  • <a href="#subscription_fd_readwrite.file_descriptor" name="subscription_fd_readwrite.file_descriptor"></a> file_descriptor: fd
    The file descriptor on which to wait for it to become ready for reading or writing.
    Offset: 0

    <a href="#subscription_u" name="subscription_u"></a> subscription_u: Union

    -The contents of a subscription.
    Size: 40
    Alignment: 8

    Union Layout

    -
  • -
  • tag_size: 1
  • -
  • tag_align: 1
  • -
  • contents_offset: 8
  • -
  • contents_size: 32
  • -
  • contents_align: 8

    Union variants

    -
  • -
  • <a href="#subscription_u.clock" name="subscription_u.clock"></a> clock: subscription_clock

    -
  • -
  • <a href="#subscription_u.fd_read" name="subscription_u.fd_read"></a> fd_read: subscription_fd_readwrite

    -
  • -
  • <a href="#subscription_u.fd_write" name="subscription_u.fd_write"></a> fd_write: subscription_fd_readwrite

    -
  • -
-

<a href="#subscription" name="subscription"></a> subscription: Struct

-

Subscription to an event.
Size: 48
Alignment: 8

-

Struct members

-
    -
  • <a href="#subscription.userdata" name="subscription.userdata"></a> userdata: userdata
    User-provided value that is attached to the subscription in the
    implementation and returned through event::userdata.
    Offset: 0
  • -
  • <a href="#subscription.u" name="subscription.u"></a> u: subscription_u
    The type of the event to which to subscribe, and its contents
    Offset: 8

    <a href="#exitcode" name="exitcode"></a> exitcode: u32

    -Exit code generated by a process when exiting.
    Size: 4
    Alignment: 4

    <a href="#signal" name="signal"></a> signal: Enum(u8)

    -Signal condition.
    Size: 1
    Alignment: 1

    Variants

    -
  • -
  • <a href="#signal.none" name="signal.none"></a> none
    No signal. Note that POSIX has special semantics for kill(pid, 0),
    so this value is reserved.

    -
  • -
  • <a href="#signal.hup" name="signal.hup"></a> hup
    Hangup.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.int" name="signal.int"></a> int
    Terminate interrupt signal.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.quit" name="signal.quit"></a> quit
    Terminal quit signal.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.ill" name="signal.ill"></a> ill
    Illegal instruction.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.trap" name="signal.trap"></a> trap
    Trace/breakpoint trap.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.abrt" name="signal.abrt"></a> abrt
    Process abort signal.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.bus" name="signal.bus"></a> bus
    Access to an undefined portion of a memory object.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.fpe" name="signal.fpe"></a> fpe
    Erroneous arithmetic operation.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.kill" name="signal.kill"></a> kill
    Kill.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.usr1" name="signal.usr1"></a> usr1
    User-defined signal 1.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.segv" name="signal.segv"></a> segv
    Invalid memory reference.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.usr2" name="signal.usr2"></a> usr2
    User-defined signal 2.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.pipe" name="signal.pipe"></a> pipe
    Write on a pipe with no one to read it.
    Action: Ignored.

    -
  • -
  • <a href="#signal.alrm" name="signal.alrm"></a> alrm
    Alarm clock.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.term" name="signal.term"></a> term
    Termination signal.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.chld" name="signal.chld"></a> chld
    Child process terminated, stopped, or continued.
    Action: Ignored.

    -
  • -
  • <a href="#signal.cont" name="signal.cont"></a> cont
    Continue executing, if stopped.
    Action: Continues executing, if stopped.

    -
  • -
  • <a href="#signal.stop" name="signal.stop"></a> stop
    Stop executing.
    Action: Stops executing.

    -
  • -
  • <a href="#signal.tstp" name="signal.tstp"></a> tstp
    Terminal stop signal.
    Action: Stops executing.

    -
  • -
  • <a href="#signal.ttin" name="signal.ttin"></a> ttin
    Background process attempting read.
    Action: Stops executing.

    -
  • -
  • <a href="#signal.ttou" name="signal.ttou"></a> ttou
    Background process attempting write.
    Action: Stops executing.

    -
  • -
  • <a href="#signal.urg" name="signal.urg"></a> urg
    High bandwidth data is available at a socket.
    Action: Ignored.

    -
  • -
  • <a href="#signal.xcpu" name="signal.xcpu"></a> xcpu
    CPU time limit exceeded.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.xfsz" name="signal.xfsz"></a> xfsz
    File size limit exceeded.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.vtalrm" name="signal.vtalrm"></a> vtalrm
    Virtual timer expired.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.prof" name="signal.prof"></a> prof
    Profiling timer expired.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.winch" name="signal.winch"></a> winch
    Window changed.
    Action: Ignored.

    -
  • -
  • <a href="#signal.poll" name="signal.poll"></a> poll
    I/O possible.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.pwr" name="signal.pwr"></a> pwr
    Power failure.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.sys" name="signal.sys"></a> sys
    Bad system call.
    Action: Terminates the process.

    -
  • -
-

<a href="#riflags" name="riflags"></a> riflags: Flags(u16)

-

Flags provided to sock_recv.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#riflags.recv_peek" name="riflags.recv_peek"></a> recv_peek
    Returns the message without removing it from the socket's receive queue.

    -
  • -
  • <a href="#riflags.recv_waitall" name="riflags.recv_waitall"></a> recv_waitall
    On byte-stream sockets, block until the full amount of data can be returned.

    -
  • -
-

<a href="#roflags" name="roflags"></a> roflags: Flags(u16)

-

Flags returned by sock_recv.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#roflags.recv_data_truncated" name="roflags.recv_data_truncated"></a> recv_data_truncated
    Returned by sock_recv: Message data has been truncated.
  • -
-

<a href="#siflags" name="siflags"></a> siflags: u16

-

Flags provided to sock_send. As there are currently no flags
defined, it must be set to zero.
Size: 2
Alignment: 2

-

<a href="#sdflags" name="sdflags"></a> sdflags: Flags(u8)

-

Which channels on a socket to shut down.
Size: 1
Alignment: 1

-

Flags

-
    -
  • <a href="#sdflags.rd" name="sdflags.rd"></a> rd
    Disables further receive operations.

    -
  • -
  • <a href="#sdflags.wr" name="sdflags.wr"></a> wr
    Disables further send operations.

    -
  • -
-

<a href="#preopentype" name="preopentype"></a> preopentype: Enum(u8)

-

Identifiers for preopened capabilities.
Size: 1
Alignment: 1

-

Variants

-
    -
  • <a href="#preopentype.dir" name="preopentype.dir"></a> dir
    A pre-opened directory.
  • -
-

<a href="#prestat_dir" name="prestat_dir"></a> prestat_dir: Struct

-

The contents of a $prestat when type is preopentype::dir.
Size: 4
Alignment: 4

-

Struct members

-
    -
  • <a href="#prestat_dir.pr_name_len" name="prestat_dir.pr_name_len"></a> pr_name_len: size
    The length of the directory name for use with fd_prestat_dir_name.
    Offset: 0

    <a href="#prestat" name="prestat"></a> prestat: Union

    -Information about a pre-opened capability.
    Size: 8
    Alignment: 4

    Union Layout

    -
  • -
  • tag_size: 1
  • -
  • tag_align: 1
  • -
  • contents_offset: 4
  • -
  • contents_size: 4
  • -
  • contents_align: 4

    Union variants

    -
  • -
  • <a href="#prestat.dir" name="prestat.dir"></a> dir: prestat_dir
  • -
-

Modules

-

<a href="#wasi_snapshot_preview1" name="wasi_snapshot_preview1"></a> wasi_snapshot_preview1

-

Imports

-

Memory

-

Functions

-
-

<a href="#args_get" name="args_get"></a> args_get(argv: Pointer<Pointer<u8>>, argv_buf: Pointer<u8>) -> errno

-

Read command-line argument data.
The size of the array should match that returned by args_sizes_get

-
Params
-
    -
  • <a href="#args_get.argv" name="args_get.argv"></a> argv: Pointer<Pointer<u8>>

    -
  • -
  • <a href="#args_get.argv_buf" name="args_get.argv_buf"></a> argv_buf: Pointer<u8>

    -
  • -
-
Results
-
    -
  • <a href="#args_get.error" name="args_get.error"></a> error: errno
  • -
-
-

<a href="#args_sizes_get" name="args_sizes_get"></a> args_sizes_get() -> (errno, size, size)

-

Return command-line argument data sizes.

-
Params
-
Results
-
    -
  • <a href="#args_sizes_get.error" name="args_sizes_get.error"></a> error: errno

    -
  • -
  • <a href="#args_sizes_get.argc" name="args_sizes_get.argc"></a> argc: size
    The number of arguments.

    -
  • -
  • <a href="#args_sizes_get.argv_buf_size" name="args_sizes_get.argv_buf_size"></a> argv_buf_size: size
    The size of the argument string data.

    -
  • -
-
-

<a href="#environ_get" name="environ_get"></a> environ_get(environ: Pointer<Pointer<u8>>, environ_buf: Pointer<u8>) -> errno

-

Read environment variable data.
The sizes of the buffers should match that returned by environ_sizes_get.

-
Params
-
    -
  • <a href="#environ_get.environ" name="environ_get.environ"></a> environ: Pointer<Pointer<u8>>

    -
  • -
  • <a href="#environ_get.environ_buf" name="environ_get.environ_buf"></a> environ_buf: Pointer<u8>

    -
  • -
-
Results
-
    -
  • <a href="#environ_get.error" name="environ_get.error"></a> error: errno
  • -
-
-

<a href="#environ_sizes_get" name="environ_sizes_get"></a> environ_sizes_get() -> (errno, size, size)

-

Return environment variable data sizes.

-
Params
-
Results
-
    -
  • <a href="#environ_sizes_get.error" name="environ_sizes_get.error"></a> error: errno

    -
  • -
  • <a href="#environ_sizes_get.environc" name="environ_sizes_get.environc"></a> environc: size
    The number of environment variable arguments.

    -
  • -
  • <a href="#environ_sizes_get.environ_buf_size" name="environ_sizes_get.environ_buf_size"></a> environ_buf_size: size
    The size of the environment variable data.

    -
  • -
-
-

<a href="#clock_res_get" name="clock_res_get"></a> clock_res_get(id: clockid) -> (errno, timestamp)

-

Return the resolution of a clock.
Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks,
return errno::inval.
Note: This is similar to clock_getres in POSIX.

-
Params
-
    -
  • <a href="#clock_res_get.id" name="clock_res_get.id"></a> id: clockid
    The clock for which to return the resolution.
  • -
-
Results
-
    -
  • <a href="#clock_res_get.error" name="clock_res_get.error"></a> error: errno

    -
  • -
  • <a href="#clock_res_get.resolution" name="clock_res_get.resolution"></a> resolution: timestamp
    The resolution of the clock.

    -
  • -
-
-

<a href="#clock_time_get" name="clock_time_get"></a> clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)

-

Return the time value of a clock.
Note: This is similar to clock_gettime in POSIX.

-
Params
-
    -
  • <a href="#clock_time_get.id" name="clock_time_get.id"></a> id: clockid
    The clock for which to return the time.

    -
  • -
  • <a href="#clock_time_get.precision" name="clock_time_get.precision"></a> precision: timestamp
    The maximum lag (exclusive) that the returned time value may have, compared to its actual value.

    -
  • -
-
Results
-
    -
  • <a href="#clock_time_get.error" name="clock_time_get.error"></a> error: errno

    -
  • -
  • <a href="#clock_time_get.time" name="clock_time_get.time"></a> time: timestamp
    The time value of the clock.

    -
  • -
-
-

<a href="#fd_advise" name="fd_advise"></a> fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno

-

Provide file advisory information on a file descriptor.
Note: This is similar to posix_fadvise in POSIX.

-
Params
-
    -
  • <a href="#fd_advise.fd" name="fd_advise.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_advise.offset" name="fd_advise.offset"></a> offset: filesize
    The offset within the file to which the advisory applies.

    -
  • -
  • <a href="#fd_advise.len" name="fd_advise.len"></a> len: filesize
    The length of the region to which the advisory applies.

    -
  • -
  • <a href="#fd_advise.advice" name="fd_advise.advice"></a> advice: advice
    The advice.

    -
  • -
-
Results
-
    -
  • <a href="#fd_advise.error" name="fd_advise.error"></a> error: errno
  • -
-
-

<a href="#fd_allocate" name="fd_allocate"></a> fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno

-

Force the allocation of space in a file.
Note: This is similar to posix_fallocate in POSIX.

-
Params
-
    -
  • <a href="#fd_allocate.fd" name="fd_allocate.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_allocate.offset" name="fd_allocate.offset"></a> offset: filesize
    The offset at which to start the allocation.

    -
  • -
  • <a href="#fd_allocate.len" name="fd_allocate.len"></a> len: filesize
    The length of the area that is allocated.

    -
  • -
-
Results
-
    -
  • <a href="#fd_allocate.error" name="fd_allocate.error"></a> error: errno
  • -
-
-

<a href="#fd_close" name="fd_close"></a> fd_close(fd: fd) -> errno

-

Close a file descriptor.
Note: This is similar to close in POSIX.

-
Params
-
    -
  • <a href="#fd_close.fd" name="fd_close.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_close.error" name="fd_close.error"></a> error: errno
  • -
-
-

<a href="#fd_datasync" name="fd_datasync"></a> fd_datasync(fd: fd) -> errno

-

Synchronize the data of a file to disk.
Note: This is similar to fdatasync in POSIX.

-
Params
-
    -
  • <a href="#fd_datasync.fd" name="fd_datasync.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_datasync.error" name="fd_datasync.error"></a> error: errno
  • -
-
-

<a href="#fd_fdstat_get" name="fd_fdstat_get"></a> fd_fdstat_get(fd: fd) -> (errno, fdstat)

-

Get the attributes of a file descriptor.
Note: This returns similar flags to fsync(fd, F_GETFL) in POSIX, as well as additional fields.

-
Params
-
    -
  • <a href="#fd_fdstat_get.fd" name="fd_fdstat_get.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_fdstat_get.error" name="fd_fdstat_get.error"></a> error: errno

    -
  • -
  • <a href="#fd_fdstat_get.stat" name="fd_fdstat_get.stat"></a> stat: fdstat
    The buffer where the file descriptor's attributes are stored.

    -
  • -
-
-

<a href="#fd_fdstat_set_flags" name="fd_fdstat_set_flags"></a> fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno

-

Adjust the flags associated with a file descriptor.
Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

-
Params
-
    -
  • <a href="#fd_fdstat_set_flags.fd" name="fd_fdstat_set_flags.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_fdstat_set_flags.flags" name="fd_fdstat_set_flags.flags"></a> flags: fdflags
    The desired values of the file descriptor flags.

    -
  • -
-
Results
-
    -
  • <a href="#fd_fdstat_set_flags.error" name="fd_fdstat_set_flags.error"></a> error: errno
  • -
-
-

<a href="#fd_fdstat_set_rights" name="fd_fdstat_set_rights"></a> fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno

-

Adjust the rights associated with a file descriptor.
This can only be used to remove rights, and returns errno::notcapable if called in a way that would attempt to add rights

-
Params
-
    -
  • <a href="#fd_fdstat_set_rights.fd" name="fd_fdstat_set_rights.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_fdstat_set_rights.fs_rights_base" name="fd_fdstat_set_rights.fs_rights_base"></a> fs_rights_base: rights
    The desired rights of the file descriptor.

    -
  • -
  • <a href="#fd_fdstat_set_rights.fs_rights_inheriting" name="fd_fdstat_set_rights.fs_rights_inheriting"></a> fs_rights_inheriting: rights

    -
  • -
-
Results
-
    -
  • <a href="#fd_fdstat_set_rights.error" name="fd_fdstat_set_rights.error"></a> error: errno
  • -
-
-

<a href="#fd_filestat_get" name="fd_filestat_get"></a> fd_filestat_get(fd: fd) -> (errno, filestat)

-

Return the attributes of an open file.

-
Params
-
    -
  • <a href="#fd_filestat_get.fd" name="fd_filestat_get.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_filestat_get.error" name="fd_filestat_get.error"></a> error: errno

    -
  • -
  • <a href="#fd_filestat_get.buf" name="fd_filestat_get.buf"></a> buf: filestat
    The buffer where the file's attributes are stored.

    -
  • -
-
-

<a href="#fd_filestat_set_size" name="fd_filestat_set_size"></a> fd_filestat_set_size(fd: fd, size: filesize) -> errno

-

Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.
Note: This is similar to ftruncate in POSIX.

-
Params
-
    -
  • <a href="#fd_filestat_set_size.fd" name="fd_filestat_set_size.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_filestat_set_size.size" name="fd_filestat_set_size.size"></a> size: filesize
    The desired file size.

    -
  • -
-
Results
-
    -
  • <a href="#fd_filestat_set_size.error" name="fd_filestat_set_size.error"></a> error: errno
  • -
-
-

<a href="#fd_filestat_set_times" name="fd_filestat_set_times"></a> fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno

-

Adjust the timestamps of an open file or directory.
Note: This is similar to futimens in POSIX.

-
Params
-
    -
  • <a href="#fd_filestat_set_times.fd" name="fd_filestat_set_times.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_filestat_set_times.atim" name="fd_filestat_set_times.atim"></a> atim: timestamp
    The desired values of the data access timestamp.

    -
  • -
  • <a href="#fd_filestat_set_times.mtim" name="fd_filestat_set_times.mtim"></a> mtim: timestamp
    The desired values of the data modification timestamp.

    -
  • -
  • <a href="#fd_filestat_set_times.fst_flags" name="fd_filestat_set_times.fst_flags"></a> fst_flags: fstflags
    A bitmask indicating which timestamps to adjust.

    -
  • -
-
Results
-
    -
  • <a href="#fd_filestat_set_times.error" name="fd_filestat_set_times.error"></a> error: errno
  • -
-
-

<a href="#fd_pread" name="fd_pread"></a> fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)

-

Read from a file descriptor, without using and updating the file descriptor's offset.
Note: This is similar to preadv in POSIX.

-
Params
-
    -
  • <a href="#fd_pread.fd" name="fd_pread.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_pread.iovs" name="fd_pread.iovs"></a> iovs: iovec_array
    List of scatter/gather vectors in which to store data.

    -
  • -
  • <a href="#fd_pread.offset" name="fd_pread.offset"></a> offset: filesize
    The offset within the file at which to read.

    -
  • -
-
Results
-
    -
  • <a href="#fd_pread.error" name="fd_pread.error"></a> error: errno

    -
  • -
  • <a href="#fd_pread.nread" name="fd_pread.nread"></a> nread: size
    The number of bytes read.

    -
  • -
-
-

<a href="#fd_prestat_get" name="fd_prestat_get"></a> fd_prestat_get(fd: fd) -> (errno, prestat)

-

Return a description of the given preopened file descriptor.

-
Params
-
    -
  • <a href="#fd_prestat_get.fd" name="fd_prestat_get.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_prestat_get.error" name="fd_prestat_get.error"></a> error: errno

    -
  • -
  • <a href="#fd_prestat_get.buf" name="fd_prestat_get.buf"></a> buf: prestat
    The buffer where the description is stored.

    -
  • -
-
-

<a href="#fd_prestat_dir_name" name="fd_prestat_dir_name"></a> fd_prestat_dir_name(fd: fd, path: Pointer<u8>, path_len: size) -> errno

-

Return a description of the given preopened file descriptor.

-
Params
-
    -
  • <a href="#fd_prestat_dir_name.fd" name="fd_prestat_dir_name.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_prestat_dir_name.path" name="fd_prestat_dir_name.path"></a> path: Pointer<u8>
    A buffer into which to write the preopened directory name.

    -
  • -
  • <a href="#fd_prestat_dir_name.path_len" name="fd_prestat_dir_name.path_len"></a> path_len: size

    -
  • -
-
Results
-
    -
  • <a href="#fd_prestat_dir_name.error" name="fd_prestat_dir_name.error"></a> error: errno
  • -
-
-

<a href="#fd_pwrite" name="fd_pwrite"></a> fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)

-

Write to a file descriptor, without using and updating the file descriptor's offset.
Note: This is similar to pwritev in POSIX.

-
Params
-
    -
  • <a href="#fd_pwrite.fd" name="fd_pwrite.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_pwrite.iovs" name="fd_pwrite.iovs"></a> iovs: ciovec_array
    List of scatter/gather vectors from which to retrieve data.

    -
  • -
  • <a href="#fd_pwrite.offset" name="fd_pwrite.offset"></a> offset: filesize
    The offset within the file at which to write.

    -
  • -
-
Results
-
    -
  • <a href="#fd_pwrite.error" name="fd_pwrite.error"></a> error: errno

    -
  • -
  • <a href="#fd_pwrite.nwritten" name="fd_pwrite.nwritten"></a> nwritten: size
    The number of bytes written.

    -
  • -
-
-

<a href="#fd_read" name="fd_read"></a> fd_read(fd: fd, iovs: iovec_array) -> (errno, size)

-

Read from a file descriptor.
Note: This is similar to readv in POSIX.

-
Params
-
    -
  • <a href="#fd_read.fd" name="fd_read.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_read.iovs" name="fd_read.iovs"></a> iovs: iovec_array
    List of scatter/gather vectors to which to store data.

    -
  • -
-
Results
-
    -
  • <a href="#fd_read.error" name="fd_read.error"></a> error: errno

    -
  • -
  • <a href="#fd_read.nread" name="fd_read.nread"></a> nread: size
    The number of bytes read.

    -
  • -
-
- -

Read directory entries from a directory.
When successful, the contents of the output buffer consist of a sequence of
directory entries. Each directory entry consists of a dirent_t object,
followed by dirent_t::d_namlen bytes holding the name of the directory
entry.
This function fills the output buffer as much as possible, potentially
truncating the last directory entry. This allows the caller to grow its
read buffer size in case it's too small to fit a single large directory
entry, or skip the oversized directory entry.

-
Params
-
    -
  • <a href="#fd_readdir.fd" name="fd_readdir.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_readdir.buf" name="fd_readdir.buf"></a> buf: Pointer<u8>
    The buffer where directory entries are stored

    -
  • -
  • <a href="#fd_readdir.buf_len" name="fd_readdir.buf_len"></a> buf_len: size

    -
  • -
  • <a href="#fd_readdir.cookie" name="fd_readdir.cookie"></a> cookie: dircookie
    The location within the directory to start reading

    -
  • -
-
Results
-
    -
  • <a href="#fd_readdir.error" name="fd_readdir.error"></a> error: errno

    -
  • -
  • <a href="#fd_readdir.bufused" name="fd_readdir.bufused"></a> bufused: size
    The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached.

    -
  • -
-
-

<a href="#fd_renumber" name="fd_renumber"></a> fd_renumber(fd: fd, to: fd) -> errno

-

Atomically replace a file descriptor by renumbering another file descriptor.
Due to the strong focus on thread safety, this environment does not provide
a mechanism to duplicate or renumber a file descriptor to an arbitrary
number, like dup2(). This would be prone to race conditions, as an actual
file descriptor with the same number could be allocated by a different
thread at the same time.
This function provides a way to atomically renumber file descriptors, which
would disappear if dup2() were to be removed entirely.

-
Params
-
    -
  • <a href="#fd_renumber.fd" name="fd_renumber.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_renumber.to" name="fd_renumber.to"></a> to: fd
    The file descriptor to overwrite.

    -
  • -
-
Results
-
    -
  • <a href="#fd_renumber.error" name="fd_renumber.error"></a> error: errno
  • -
-
-

<a href="#fd_seek" name="fd_seek"></a> fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)

-

Move the offset of a file descriptor.
Note: This is similar to lseek in POSIX.

-
Params
-
    -
  • <a href="#fd_seek.fd" name="fd_seek.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_seek.offset" name="fd_seek.offset"></a> offset: filedelta
    The number of bytes to move.

    -
  • -
  • <a href="#fd_seek.whence" name="fd_seek.whence"></a> whence: whence
    The base from which the offset is relative.

    -
  • -
-
Results
-
    -
  • <a href="#fd_seek.error" name="fd_seek.error"></a> error: errno

    -
  • -
  • <a href="#fd_seek.newoffset" name="fd_seek.newoffset"></a> newoffset: filesize
    The new offset of the file descriptor, relative to the start of the file.

    -
  • -
-
-

<a href="#fd_sync" name="fd_sync"></a> fd_sync(fd: fd) -> errno

-

Synchronize the data and metadata of a file to disk.
Note: This is similar to fsync in POSIX.

-
Params
-
    -
  • <a href="#fd_sync.fd" name="fd_sync.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_sync.error" name="fd_sync.error"></a> error: errno
  • -
-
-

<a href="#fd_tell" name="fd_tell"></a> fd_tell(fd: fd) -> (errno, filesize)

-

Return the current offset of a file descriptor.
Note: This is similar to lseek(fd, 0, SEEK_CUR) in POSIX.

-
Params
-
    -
  • <a href="#fd_tell.fd" name="fd_tell.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_tell.error" name="fd_tell.error"></a> error: errno

    -
  • -
  • <a href="#fd_tell.offset" name="fd_tell.offset"></a> offset: filesize
    The current offset of the file descriptor, relative to the start of the file.

    -
  • -
-
-

<a href="#fd_write" name="fd_write"></a> fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)

-

Write to a file descriptor.
Note: This is similar to writev in POSIX.

-
Params
-
    -
  • <a href="#fd_write.fd" name="fd_write.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_write.iovs" name="fd_write.iovs"></a> iovs: ciovec_array
    List of scatter/gather vectors from which to retrieve data.

    -
  • -
-
Results
-
    -
  • <a href="#fd_write.error" name="fd_write.error"></a> error: errno

    -
  • -
  • <a href="#fd_write.nwritten" name="fd_write.nwritten"></a> nwritten: size
    The number of bytes written.

    -
  • -
-
-

<a href="#path_create_directory" name="path_create_directory"></a> path_create_directory(fd: fd, path: string) -> errno

-

Create a directory.
Note: This is similar to mkdirat in POSIX.

-
Params
-
    -
  • <a href="#path_create_directory.fd" name="path_create_directory.fd"></a> fd: fd

    -
  • -
  • <a href="#path_create_directory.path" name="path_create_directory.path"></a> path: string
    The path at which to create the directory.

    -
  • -
-
Results
-
    -
  • <a href="#path_create_directory.error" name="path_create_directory.error"></a> error: errno
  • -
-
-

<a href="#path_filestat_get" name="path_filestat_get"></a> path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)

-

Return the attributes of a file or directory.
Note: This is similar to stat in POSIX.

-
Params
-
    -
  • <a href="#path_filestat_get.fd" name="path_filestat_get.fd"></a> fd: fd

    -
  • -
  • <a href="#path_filestat_get.flags" name="path_filestat_get.flags"></a> flags: lookupflags
    Flags determining the method of how the path is resolved.

    -
  • -
  • <a href="#path_filestat_get.path" name="path_filestat_get.path"></a> path: string
    The path of the file or directory to inspect.

    -
  • -
-
Results
-
    -
  • <a href="#path_filestat_get.error" name="path_filestat_get.error"></a> error: errno

    -
  • -
  • <a href="#path_filestat_get.buf" name="path_filestat_get.buf"></a> buf: filestat
    The buffer where the file's attributes are stored.

    -
  • -
-
-

<a href="#path_filestat_set_times" name="path_filestat_set_times"></a> path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno

-

Adjust the timestamps of a file or directory.
Note: This is similar to utimensat in POSIX.

-
Params
-
    -
  • <a href="#path_filestat_set_times.fd" name="path_filestat_set_times.fd"></a> fd: fd

    -
  • -
  • <a href="#path_filestat_set_times.flags" name="path_filestat_set_times.flags"></a> flags: lookupflags
    Flags determining the method of how the path is resolved.

    -
  • -
  • <a href="#path_filestat_set_times.path" name="path_filestat_set_times.path"></a> path: string
    The path of the file or directory to operate on.

    -
  • -
  • <a href="#path_filestat_set_times.atim" name="path_filestat_set_times.atim"></a> atim: timestamp
    The desired values of the data access timestamp.

    -
  • -
  • <a href="#path_filestat_set_times.mtim" name="path_filestat_set_times.mtim"></a> mtim: timestamp
    The desired values of the data modification timestamp.

    -
  • -
  • <a href="#path_filestat_set_times.fst_flags" name="path_filestat_set_times.fst_flags"></a> fst_flags: fstflags
    A bitmask indicating which timestamps to adjust.

    -
  • -
-
Results
-
    -
  • <a href="#path_filestat_set_times.error" name="path_filestat_set_times.error"></a> error: errno
  • -
-
- -

Create a hard link.
Note: This is similar to linkat in POSIX.

-
Params
-
    -
  • <a href="#path_link.old_fd" name="path_link.old_fd"></a> old_fd: fd

    -
  • -
  • <a href="#path_link.old_flags" name="path_link.old_flags"></a> old_flags: lookupflags
    Flags determining the method of how the path is resolved.

    -
  • -
  • <a href="#path_link.old_path" name="path_link.old_path"></a> old_path: string
    The source path from which to link.

    -
  • -
  • <a href="#path_link.new_fd" name="path_link.new_fd"></a> new_fd: fd
    The working directory at which the resolution of the new path starts.

    -
  • -
  • <a href="#path_link.new_path" name="path_link.new_path"></a> new_path: string
    The destination path at which to create the hard link.

    -
  • -
-
Results
-
    -
  • <a href="#path_link.error" name="path_link.error"></a> error: errno
  • -
-
-

<a href="#path_open" name="path_open"></a> path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)

-

Open a file or directory.
The returned file descriptor is not guaranteed to be the lowest-numbered
file descriptor not currently open; it is randomized to prevent
applications from depending on making assumptions about indexes, since this
is error-prone in multi-threaded contexts. The returned file descriptor is
guaranteed to be less than 2**31.
Note: This is similar to openat in POSIX.

-
Params
-
    -
  • <a href="#path_open.fd" name="path_open.fd"></a> fd: fd

    -
  • -
  • <a href="#path_open.dirflags" name="path_open.dirflags"></a> dirflags: lookupflags
    Flags determining the method of how the path is resolved.

    -
  • -
  • <a href="#path_open.path" name="path_open.path"></a> path: string
    The relative path of the file or directory to open, relative to the
    path_open::fd directory.

    -
  • -
  • <a href="#path_open.oflags" name="path_open.oflags"></a> oflags: oflags
    The method by which to open the file.

    -
  • -
  • <a href="#path_open.fs_rights_base" name="path_open.fs_rights_base"></a> fs_rights_base: rights
    The initial rights of the newly created file descriptor. The
    implementation is allowed to return a file descriptor with fewer rights
    than specified, if and only if those rights do not apply to the type of
    file being opened.
    The base rights are rights that will apply to operations using the file
    descriptor itself, while the inheriting rights are rights that apply to
    file descriptors derived from it.

    -
  • -
  • <a href="#path_open.fs_rights_inherting" name="path_open.fs_rights_inherting"></a> fs_rights_inherting: rights

    -
  • -
  • <a href="#path_open.fdflags" name="path_open.fdflags"></a> fdflags: fdflags

    -
  • -
-
Results
-
    -
  • <a href="#path_open.error" name="path_open.error"></a> error: errno

    -
  • -
  • <a href="#path_open.opened_fd" name="path_open.opened_fd"></a> opened_fd: fd
    The file descriptor of the file that has been opened.

    -
  • -
-
- -

Read the contents of a symbolic link.
Note: This is similar to readlinkat in POSIX.

-
Params
-
    -
  • <a href="#path_readlink.fd" name="path_readlink.fd"></a> fd: fd

    -
  • -
  • <a href="#path_readlink.path" name="path_readlink.path"></a> path: string
    The path of the symbolic link from which to read.

    -
  • -
  • <a href="#path_readlink.buf" name="path_readlink.buf"></a> buf: Pointer<u8>
    The buffer to which to write the contents of the symbolic link.

    -
  • -
  • <a href="#path_readlink.buf_len" name="path_readlink.buf_len"></a> buf_len: size

    -
  • -
-
Results
-
    -
  • <a href="#path_readlink.error" name="path_readlink.error"></a> error: errno

    -
  • -
  • <a href="#path_readlink.bufused" name="path_readlink.bufused"></a> bufused: size
    The number of bytes placed in the buffer.

    -
  • -
-
-

<a href="#path_remove_directory" name="path_remove_directory"></a> path_remove_directory(fd: fd, path: string) -> errno

-

Remove a directory.
Return errno::notempty if the directory is not empty.
Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

-
Params
-
    -
  • <a href="#path_remove_directory.fd" name="path_remove_directory.fd"></a> fd: fd

    -
  • -
  • <a href="#path_remove_directory.path" name="path_remove_directory.path"></a> path: string
    The path to a directory to remove.

    -
  • -
-
Results
-
    -
  • <a href="#path_remove_directory.error" name="path_remove_directory.error"></a> error: errno
  • -
-
-

<a href="#path_rename" name="path_rename"></a> path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno

-

Rename a file or directory.
Note: This is similar to renameat in POSIX.

-
Params
-
    -
  • <a href="#path_rename.fd" name="path_rename.fd"></a> fd: fd

    -
  • -
  • <a href="#path_rename.old_path" name="path_rename.old_path"></a> old_path: string
    The source path of the file or directory to rename.

    -
  • -
  • <a href="#path_rename.new_fd" name="path_rename.new_fd"></a> new_fd: fd
    The working directory at which the resolution of the new path starts.

    -
  • -
  • <a href="#path_rename.new_path" name="path_rename.new_path"></a> new_path: string
    The destination path to which to rename the file or directory.

    -
  • -
-
Results
-
    -
  • <a href="#path_rename.error" name="path_rename.error"></a> error: errno
  • -
-
- -

Create a symbolic link.
Note: This is similar to symlinkat in POSIX.

-
Params
-
    -
  • <a href="#path_symlink.old_path" name="path_symlink.old_path"></a> old_path: string
    The contents of the symbolic link.

    -
  • -
  • <a href="#path_symlink.fd" name="path_symlink.fd"></a> fd: fd

    -
  • -
  • <a href="#path_symlink.new_path" name="path_symlink.new_path"></a> new_path: string
    The destination path at which to create the symbolic link.

    -
  • -
-
Results
-
    -
  • <a href="#path_symlink.error" name="path_symlink.error"></a> error: errno
  • -
-
- -

Unlink a file.
Return errno::isdir if the path refers to a directory.
Note: This is similar to unlinkat(fd, path, 0) in POSIX.

-
Params
-
    -
  • <a href="#path_unlink_file.fd" name="path_unlink_file.fd"></a> fd: fd

    -
  • -
  • <a href="#path_unlink_file.path" name="path_unlink_file.path"></a> path: string
    The path to a file to unlink.

    -
  • -
-
Results
-
    -
  • <a href="#path_unlink_file.error" name="path_unlink_file.error"></a> error: errno
  • -
-
-

<a href="#poll_oneoff" name="poll_oneoff"></a> poll_oneoff(in: ConstPointer<subscription>, out: Pointer<event>, nsubscriptions: size) -> (errno, size)

-

Concurrently poll for the occurrence of a set of events.

-
Params
-
    -
  • <a href="#poll_oneoff.in" name="poll_oneoff.in"></a> in: ConstPointer<subscription>
    The events to which to subscribe.

    -
  • -
  • <a href="#poll_oneoff.out" name="poll_oneoff.out"></a> out: Pointer<event>
    The events that have occurred.

    -
  • -
  • <a href="#poll_oneoff.nsubscriptions" name="poll_oneoff.nsubscriptions"></a> nsubscriptions: size
    Both the number of subscriptions and events.

    -
  • -
-
Results
-
    -
  • <a href="#poll_oneoff.error" name="poll_oneoff.error"></a> error: errno

    -
  • -
  • <a href="#poll_oneoff.nevents" name="poll_oneoff.nevents"></a> nevents: size
    The number of events stored.

    -
  • -
-
-

<a href="#proc_exit" name="proc_exit"></a> proc_exit(rval: exitcode)

-

Terminate the process normally. An exit code of 0 indicates successful
termination of the program. The meanings of other values is dependent on
the environment.

-
Params
-
    -
  • <a href="#proc_exit.rval" name="proc_exit.rval"></a> rval: exitcode
    The exit code returned by the process.
  • -
-
Results
-
-

<a href="#proc_raise" name="proc_raise"></a> proc_raise(sig: signal) -> errno

-

Send a signal to the process of the calling thread.
Note: This is similar to raise in POSIX.

-
Params
-
    -
  • <a href="#proc_raise.sig" name="proc_raise.sig"></a> sig: signal
    The signal condition to trigger.
  • -
-
Results
-
    -
  • <a href="#proc_raise.error" name="proc_raise.error"></a> error: errno
  • -
-
-

<a href="#sched_yield" name="sched_yield"></a> sched_yield() -> errno

-

Temporarily yield execution of the calling thread.
Note: This is similar to sched_yield in POSIX.

-
Params
-
Results
-
    -
  • <a href="#sched_yield.error" name="sched_yield.error"></a> error: errno
  • -
-
-

<a href="#random_get" name="random_get"></a> random_get(buf: Pointer<u8>, buf_len: size) -> errno

-

Write high-quality random data into a buffer.
This function blocks when the implementation is unable to immediately
provide sufficient high-quality random data.
This function may execute slowly, so when large mounts of random data are
required, it's advisable to use this function to seed a pseudo-random
number generator, rather than to provide the random data directly.

-
Params
-
    -
  • <a href="#random_get.buf" name="random_get.buf"></a> buf: Pointer<u8>
    The buffer to fill with random data.

    -
  • -
  • <a href="#random_get.buf_len" name="random_get.buf_len"></a> buf_len: size

    -
  • -
-
Results
-
    -
  • <a href="#random_get.error" name="random_get.error"></a> error: errno
  • -
-
-

<a href="#sock_recv" name="sock_recv"></a> sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)

-

Receive a message from a socket.
Note: This is similar to recv in POSIX, though it also supports reading
the data into multiple buffers in the manner of readv.

-
Params
-
    -
  • <a href="#sock_recv.fd" name="sock_recv.fd"></a> fd: fd

    -
  • -
  • <a href="#sock_recv.ri_data" name="sock_recv.ri_data"></a> ri_data: iovec_array
    List of scatter/gather vectors to which to store data.

    -
  • -
  • <a href="#sock_recv.ri_flags" name="sock_recv.ri_flags"></a> ri_flags: riflags
    Message flags.

    -
  • -
-
Results
-
    -
  • <a href="#sock_recv.error" name="sock_recv.error"></a> error: errno

    -
  • -
  • <a href="#sock_recv.ro_datalen" name="sock_recv.ro_datalen"></a> ro_datalen: size
    Number of bytes stored in ri_data.

    -
  • -
  • <a href="#sock_recv.ro_flags" name="sock_recv.ro_flags"></a> ro_flags: roflags
    Message flags.

    -
  • -
-
-

<a href="#sock_send" name="sock_send"></a> sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)

-

Send a message on a socket.
Note: This is similar to send in POSIX, though it also supports writing
the data from multiple buffers in the manner of writev.

-
Params
-
    -
  • <a href="#sock_send.fd" name="sock_send.fd"></a> fd: fd

    -
  • -
  • <a href="#sock_send.si_data" name="sock_send.si_data"></a> si_data: ciovec_array
    List of scatter/gather vectors to which to retrieve data

    -
  • -
  • <a href="#sock_send.si_flags" name="sock_send.si_flags"></a> si_flags: siflags
    Message flags.

    -
  • -
-
Results
-
    -
  • <a href="#sock_send.error" name="sock_send.error"></a> error: errno

    -
  • -
  • <a href="#sock_send.so_datalen" name="sock_send.so_datalen"></a> so_datalen: size
    Number of bytes transmitted.

    -
  • -
-
-

<a href="#sock_shutdown" name="sock_shutdown"></a> sock_shutdown(fd: fd, how: sdflags) -> errno

-

Shut down socket send and receive channels.
Note: This is similar to shutdown in POSIX.

-
Params
-
    -
  • <a href="#sock_shutdown.fd" name="sock_shutdown.fd"></a> fd: fd

    -
  • -
  • <a href="#sock_shutdown.how" name="sock_shutdown.how"></a> how: sdflags
    Which channels on the socket to shut down.

    -
  • -
-
Results
-
    -
  • <a href="#sock_shutdown.error" name="sock_shutdown.error"></a> error: errno
  • -
diff --git a/proposals/clocks/phases/snapshot/docs.md b/proposals/clocks/phases/snapshot/docs.md deleted file mode 100644 index 44c3c35f2..000000000 --- a/proposals/clocks/phases/snapshot/docs.md +++ /dev/null @@ -1,2509 +0,0 @@ -# Types -## `size`: `u32` - -Size: 4 - -Alignment: 4 - -## `filesize`: `u64` -Non-negative file size or length of a region within a file. - -Size: 8 - -Alignment: 8 - -## `timestamp`: `u64` -Timestamp in nanoseconds. - -Size: 8 - -Alignment: 8 - -## `clockid`: `Variant` -Identifiers for clocks. - -Size: 4 - -Alignment: 4 - -### Variant cases -- `realtime` -The clock measuring real time. Time value zero corresponds with -1970-01-01T00:00:00Z. - -- `monotonic` -The store-wide monotonic clock, which is defined as a clock measuring -real time, whose value cannot be adjusted and which cannot have negative -clock jumps. The epoch of this clock is undefined. The absolute time -value of this clock therefore has no meaning. - -- `process_cputime_id` -The CPU-time clock associated with the current process. - -- `thread_cputime_id` -The CPU-time clock associated with the current thread. - -## `errno`: `Variant` -Error codes returned by functions. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX. - -Size: 2 - -Alignment: 2 - -### Variant cases -- `success` -No error occurred. System call completed successfully. - -- `2big` -Argument list too long. - -- `acces` -Permission denied. - -- `addrinuse` -Address in use. - -- `addrnotavail` -Address not available. - -- `afnosupport` -Address family not supported. - -- `again` -Resource unavailable, or operation would block. - -- `already` -Connection already in progress. - -- `badf` -Bad file descriptor. - -- `badmsg` -Bad message. - -- `busy` -Device or resource busy. - -- `canceled` -Operation canceled. - -- `child` -No child processes. - -- `connaborted` -Connection aborted. - -- `connrefused` -Connection refused. - -- `connreset` -Connection reset. - -- `deadlk` -Resource deadlock would occur. - -- `destaddrreq` -Destination address required. - -- `dom` -Mathematics argument out of domain of function. - -- `dquot` -Reserved. - -- `exist` -File exists. - -- `fault` -Bad address. - -- `fbig` -File too large. - -- `hostunreach` -Host is unreachable. - -- `idrm` -Identifier removed. - -- `ilseq` -Illegal byte sequence. - -- `inprogress` -Operation in progress. - -- `intr` -Interrupted function. - -- `inval` -Invalid argument. - -- `io` -I/O error. - -- `isconn` -Socket is connected. - -- `isdir` -Is a directory. - -- `loop` -Too many levels of symbolic links. - -- `mfile` -File descriptor value too large. - -- `mlink` -Too many links. - -- `msgsize` -Message too large. - -- `multihop` -Reserved. - -- `nametoolong` -Filename too long. - -- `netdown` -Network is down. - -- `netreset` -Connection aborted by network. - -- `netunreach` -Network unreachable. - -- `nfile` -Too many files open in system. - -- `nobufs` -No buffer space available. - -- `nodev` -No such device. - -- `noent` -No such file or directory. - -- `noexec` -Executable file format error. - -- `nolck` -No locks available. - -- `nolink` -Reserved. - -- `nomem` -Not enough space. - -- `nomsg` -No message of the desired type. - -- `noprotoopt` -Protocol not available. - -- `nospc` -No space left on device. - -- `nosys` -Function not supported. - -- `notconn` -The socket is not connected. - -- `notdir` -Not a directory or a symbolic link to a directory. - -- `notempty` -Directory not empty. - -- `notrecoverable` -State not recoverable. - -- `notsock` -Not a socket. - -- `notsup` -Not supported, or operation not supported on socket. - -- `notty` -Inappropriate I/O control operation. - -- `nxio` -No such device or address. - -- `overflow` -Value too large to be stored in data type. - -- `ownerdead` -Previous owner died. - -- `perm` -Operation not permitted. - -- `pipe` -Broken pipe. - -- `proto` -Protocol error. - -- `protonosupport` -Protocol not supported. - -- `prototype` -Protocol wrong type for socket. - -- `range` -Result too large. - -- `rofs` -Read-only file system. - -- `spipe` -Invalid seek. - -- `srch` -No such process. - -- `stale` -Reserved. - -- `timedout` -Connection timed out. - -- `txtbsy` -Text file busy. - -- `xdev` -Cross-device link. - -- `notcapable` -Extension: Capabilities insufficient. - -## `rights`: `Record` -File descriptor rights, determining which actions may be performed. - -Size: 8 - -Alignment: 8 - -### Record members -- `fd_datasync`: `bool` -The right to invoke [`fd_datasync`](#fd_datasync). -If [`path_open`](#path_open) is set, includes the right to invoke -[`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). - -Bit: 0 - -- `fd_read`: `bool` -The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). - -Bit: 1 - -- `fd_seek`: `bool` -The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). - -Bit: 2 - -- `fd_fdstat_set_flags`: `bool` -The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). - -Bit: 3 - -- `fd_sync`: `bool` -The right to invoke [`fd_sync`](#fd_sync). -If [`path_open`](#path_open) is set, includes the right to invoke -[`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - -Bit: 4 - -- `fd_tell`: `bool` -The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset -remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to -invoke [`fd_tell`](#fd_tell). - -Bit: 5 - -- `fd_write`: `bool` -The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). - -Bit: 6 - -- `fd_advise`: `bool` -The right to invoke [`fd_advise`](#fd_advise). - -Bit: 7 - -- `fd_allocate`: `bool` -The right to invoke [`fd_allocate`](#fd_allocate). - -Bit: 8 - -- `path_create_directory`: `bool` -The right to invoke [`path_create_directory`](#path_create_directory). - -Bit: 9 - -- `path_create_file`: `bool` -If [`path_open`](#path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). - -Bit: 10 - -- `path_link_source`: `bool` -The right to invoke [`path_link`](#path_link) with the file descriptor as the -source directory. - -Bit: 11 - -- `path_link_target`: `bool` -The right to invoke [`path_link`](#path_link) with the file descriptor as the -target directory. - -Bit: 12 - -- `path_open`: `bool` -The right to invoke [`path_open`](#path_open). - -Bit: 13 - -- `fd_readdir`: `bool` -The right to invoke [`fd_readdir`](#fd_readdir). - -Bit: 14 - -- `path_readlink`: `bool` -The right to invoke [`path_readlink`](#path_readlink). - -Bit: 15 - -- `path_rename_source`: `bool` -The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. - -Bit: 16 - -- `path_rename_target`: `bool` -The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. - -Bit: 17 - -- `path_filestat_get`: `bool` -The right to invoke [`path_filestat_get`](#path_filestat_get). - -Bit: 18 - -- `path_filestat_set_size`: `bool` -The right to change a file's size (there is no `path_filestat_set_size`). -If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). - -Bit: 19 - -- `path_filestat_set_times`: `bool` -The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). - -Bit: 20 - -- `fd_filestat_get`: `bool` -The right to invoke [`fd_filestat_get`](#fd_filestat_get). - -Bit: 21 - -- `fd_filestat_set_size`: `bool` -The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). - -Bit: 22 - -- `fd_filestat_set_times`: `bool` -The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). - -Bit: 23 - -- `path_symlink`: `bool` -The right to invoke [`path_symlink`](#path_symlink). - -Bit: 24 - -- `path_remove_directory`: `bool` -The right to invoke [`path_remove_directory`](#path_remove_directory). - -Bit: 25 - -- `path_unlink_file`: `bool` -The right to invoke [`path_unlink_file`](#path_unlink_file). - -Bit: 26 - -- `poll_fd_readwrite`: `bool` -If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). -If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). - -Bit: 27 - -- `sock_shutdown`: `bool` -The right to invoke [`sock_shutdown`](#sock_shutdown). - -Bit: 28 - -## `fd`: `Handle` -A file descriptor handle. - -Size: 4 - -Alignment: 4 - -### Supertypes -## `iovec`: `Record` -A region of memory for scatter/gather reads. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `Pointer` -The address of the buffer to be filled. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be filled. - -Offset: 4 - -## `ciovec`: `Record` -A region of memory for scatter/gather writes. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `ConstPointer` -The address of the buffer to be written. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be written. - -Offset: 4 - -## `iovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `ciovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `filedelta`: `s64` -Relative offset within a file. - -Size: 8 - -Alignment: 8 - -## `whence`: `Variant` -The position relative to which to set the offset of the file descriptor. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `set` -Seek relative to start-of-file. - -- `cur` -Seek relative to current position. - -- `end` -Seek relative to end-of-file. - -## `dircookie`: `u64` -A reference to the offset of a directory entry. - -The value 0 signifies the start of the directory. - -Size: 8 - -Alignment: 8 - -## `dirnamlen`: `u32` -The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent) struct. - -Size: 4 - -Alignment: 4 - -## `inode`: `u64` -File serial number that is unique within its file system. - -Size: 8 - -Alignment: 8 - -## `filetype`: `Variant` -The type of a file descriptor or file. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `unknown` -The type of the file descriptor or file is unknown or is different from any of the other types specified. - -- `block_device` -The file descriptor or file refers to a block device inode. - -- `character_device` -The file descriptor or file refers to a character device inode. - -- `directory` -The file descriptor or file refers to a directory inode. - -- `regular_file` -The file descriptor or file refers to a regular file inode. - -- `socket_dgram` -The file descriptor or file refers to a datagram socket. - -- `socket_stream` -The file descriptor or file refers to a byte-stream socket. - -- `symbolic_link` -The file refers to a symbolic link inode. - -## `dirent`: `Record` -A directory entry. - -Size: 24 - -Alignment: 8 - -### Record members -- `d_next`: [`dircookie`](#dircookie) -The offset of the next directory entry stored in this directory. - -Offset: 0 - -- `d_ino`: [`inode`](#inode) -The serial number of the file referred to by this directory entry. - -Offset: 8 - -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. - -Offset: 16 - -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. - -Offset: 20 - -## `advice`: `Variant` -File or memory access pattern advisory information. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `normal` -The application has no advice to give on its behavior with respect to the specified data. - -- `sequential` -The application expects to access the specified data sequentially from lower offsets to higher offsets. - -- `random` -The application expects to access the specified data in a random order. - -- `willneed` -The application expects to access the specified data in the near future. - -- `dontneed` -The application expects that it will not access the specified data in the near future. - -- `noreuse` -The application expects to access the specified data once and then not reuse it thereafter. - -## `fdflags`: `Record` -File descriptor flags. - -Size: 2 - -Alignment: 2 - -### Record members -- `append`: `bool` -Append mode: Data written to the file is always appended to the file's end. - -Bit: 0 - -- `dsync`: `bool` -Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - -Bit: 1 - -- `nonblock`: `bool` -Non-blocking mode. - -Bit: 2 - -- `rsync`: `bool` -Synchronized read I/O operations. - -Bit: 3 - -- `sync`: `bool` -Write according to synchronized I/O file integrity completion. In -addition to synchronizing the data stored in the file, the implementation -may also synchronously update the file's metadata. - -Bit: 4 - -## `fdstat`: `Record` -File descriptor attributes. - -Size: 24 - -Alignment: 8 - -### Record members -- `fs_filetype`: [`filetype`](#filetype) -File type. - -Offset: 0 - -- `fs_flags`: [`fdflags`](#fdflags) -File descriptor flags. - -Offset: 2 - -- `fs_rights_base`: [`rights`](#rights) -Rights that apply to this file descriptor. - -Offset: 8 - -- `fs_rights_inheriting`: [`rights`](#rights) -Maximum set of rights that may be installed on new file descriptors that -are created through this file descriptor, e.g., through [`path_open`](#path_open). - -Offset: 16 - -## `device`: `u64` -Identifier for a device containing a file system. Can be used in combination -with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. - -Size: 8 - -Alignment: 8 - -## `fstflags`: `Record` -Which file time attributes to adjust. - -Size: 2 - -Alignment: 2 - -### Record members -- `atim`: `bool` -Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - -Bit: 0 - -- `atim_now`: `bool` -Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 1 - -- `mtim`: `bool` -Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - -Bit: 2 - -- `mtim_now`: `bool` -Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 3 - -## `lookupflags`: `Record` -Flags determining the method of how paths are resolved. - -Size: 4 - -Alignment: 4 - -### Record members -- `symlink_follow`: `bool` -As long as the resolved path corresponds to a symbolic link, it is expanded. - -Bit: 0 - -## `oflags`: `Record` -Open flags used by [`path_open`](#path_open). - -Size: 2 - -Alignment: 2 - -### Record members -- `creat`: `bool` -Create file if it does not exist. - -Bit: 0 - -- `directory`: `bool` -Fail if not a directory. - -Bit: 1 - -- `excl`: `bool` -Fail if file already exists. - -Bit: 2 - -- `trunc`: `bool` -Truncate file to size 0. - -Bit: 3 - -## `linkcount`: `u64` -Number of hard links to an inode. - -Size: 8 - -Alignment: 8 - -## `filestat`: `Record` -File attributes. - -Size: 64 - -Alignment: 8 - -### Record members -- `dev`: [`device`](#device) -Device ID of device containing the file. - -Offset: 0 - -- `ino`: [`inode`](#inode) -File serial number. - -Offset: 8 - -- `filetype`: [`filetype`](#filetype) -File type. - -Offset: 16 - -- `nlink`: [`linkcount`](#linkcount) -Number of hard links to the file. - -Offset: 24 - -- `size`: [`filesize`](#filesize) -For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - -Offset: 32 - -- `atim`: [`timestamp`](#timestamp) -Last data access timestamp. - -Offset: 40 - -- `mtim`: [`timestamp`](#timestamp) -Last data modification timestamp. - -Offset: 48 - -- `ctim`: [`timestamp`](#timestamp) -Last file status change timestamp. - -Offset: 56 - -## `userdata`: `u64` -User-provided value that may be attached to objects that is retained when -extracted from the implementation. - -Size: 8 - -Alignment: 8 - -## `eventtype`: `Variant` -Type of a subscription to an event or its occurrence. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `clock` -The time value of clock [`subscription_clock::id`](#subscription_clock.id) has -reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - -- `fd_read` -File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has data -available for reading. This event always triggers for regular files. - -- `fd_write` -File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity -available for writing. This event always triggers for regular files. - -## `eventrwflags`: `Record` -The state of the file descriptor subscribed to with -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 2 - -Alignment: 2 - -### Record members -- `fd_readwrite_hangup`: `bool` -The peer of this socket has closed or disconnected. - -Bit: 0 - -## `event_fd_readwrite`: `Record` -The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). - -Size: 16 - -Alignment: 8 - -### Record members -- `nbytes`: [`filesize`](#filesize) -The number of bytes available for reading or writing. - -Offset: 0 - -- `flags`: [`eventrwflags`](#eventrwflags) -The state of the file descriptor. - -Offset: 8 - -## `event`: `Record` -An event that occurred. - -Size: 32 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). - -Offset: 0 - -- `error`: [`errno`](#errno) -If non-zero, an error that occurred while processing the subscription request. - -Offset: 8 - -- `type`: [`eventtype`](#eventtype) -The type of event that occured - -Offset: 10 - -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. - -Offset: 16 - -## `subclockflags`: `Record` -Flags determining how to interpret the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout). - -Size: 2 - -Alignment: 2 - -### Record members -- `subscription_clock_abstime`: `bool` -If set, treat the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock -[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp -provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the -current time value of clock [`subscription_clock::id`](#subscription_clock.id). - -Bit: 0 - -## `subscription_clock`: `Record` -The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). - -Size: 32 - -Alignment: 8 - -### Record members -- `id`: [`clockid`](#clockid) -The clock against which to compare the timestamp. - -Offset: 0 - -- `timeout`: [`timestamp`](#timestamp) -The absolute or relative timestamp. - -Offset: 8 - -- `precision`: [`timestamp`](#timestamp) -The amount of time that the implementation may wait additionally -to coalesce with other events. - -Offset: 16 - -- `flags`: [`subclockflags`](#subclockflags) -Flags specifying whether the timeout is absolute or relative - -Offset: 24 - -## `subscription_fd_readwrite`: `Record` -The contents of a [`subscription`](#subscription) when type is type is -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 4 - -Alignment: 4 - -### Record members -- `file_descriptor`: [`fd`](#fd) -The file descriptor on which to wait for it to become ready for reading or writing. - -Offset: 0 - -## `subscription_u`: `Variant` -The contents of a [`subscription`](#subscription). - -Size: 40 - -Alignment: 8 - -### Variant Layout -- size: 40 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock`: [`subscription_clock`](#subscription_clock) - -- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -## `subscription`: `Record` -Subscription to an event. - -Size: 48 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that is attached to the subscription in the -implementation and returned through [`event::userdata`](#event.userdata). - -Offset: 0 - -- `u`: [`subscription_u`](#subscription_u) -The type of the event to which to subscribe, and its contents - -Offset: 8 - -## `exitcode`: `u32` -Exit code generated by a process when exiting. - -Size: 4 - -Alignment: 4 - -## `signal`: `Variant` -Signal condition. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `none` -No signal. Note that POSIX has special semantics for `kill(pid, 0)`, -so this value is reserved. - -- `hup` -Hangup. -Action: Terminates the process. - -- `int` -Terminate interrupt signal. -Action: Terminates the process. - -- `quit` -Terminal quit signal. -Action: Terminates the process. - -- `ill` -Illegal instruction. -Action: Terminates the process. - -- `trap` -Trace/breakpoint trap. -Action: Terminates the process. - -- `abrt` -Process abort signal. -Action: Terminates the process. - -- `bus` -Access to an undefined portion of a memory object. -Action: Terminates the process. - -- `fpe` -Erroneous arithmetic operation. -Action: Terminates the process. - -- `kill` -Kill. -Action: Terminates the process. - -- `usr1` -User-defined signal 1. -Action: Terminates the process. - -- `segv` -Invalid memory reference. -Action: Terminates the process. - -- `usr2` -User-defined signal 2. -Action: Terminates the process. - -- `pipe` -Write on a pipe with no one to read it. -Action: Ignored. - -- `alrm` -Alarm clock. -Action: Terminates the process. - -- `term` -Termination signal. -Action: Terminates the process. - -- `chld` -Child process terminated, stopped, or continued. -Action: Ignored. - -- `cont` -Continue executing, if stopped. -Action: Continues executing, if stopped. - -- `stop` -Stop executing. -Action: Stops executing. - -- `tstp` -Terminal stop signal. -Action: Stops executing. - -- `ttin` -Background process attempting read. -Action: Stops executing. - -- `ttou` -Background process attempting write. -Action: Stops executing. - -- `urg` -High bandwidth data is available at a socket. -Action: Ignored. - -- `xcpu` -CPU time limit exceeded. -Action: Terminates the process. - -- `xfsz` -File size limit exceeded. -Action: Terminates the process. - -- `vtalrm` -Virtual timer expired. -Action: Terminates the process. - -- `prof` -Profiling timer expired. -Action: Terminates the process. - -- `winch` -Window changed. -Action: Ignored. - -- `poll` -I/O possible. -Action: Terminates the process. - -- `pwr` -Power failure. -Action: Terminates the process. - -- `sys` -Bad system call. -Action: Terminates the process. - -## `riflags`: `Record` -Flags provided to [`sock_recv`](#sock_recv). - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_peek`: `bool` -Returns the message without removing it from the socket's receive queue. - -Bit: 0 - -- `recv_waitall`: `bool` -On byte-stream sockets, block until the full amount of data can be returned. - -Bit: 1 - -## `roflags`: `Record` -Flags returned by [`sock_recv`](#sock_recv). - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_data_truncated`: `bool` -Returned by [`sock_recv`](#sock_recv): Message data has been truncated. - -Bit: 0 - -## `siflags`: `u16` -Flags provided to [`sock_send`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Size: 2 - -Alignment: 2 - -## `sdflags`: `Record` -Which channels on a socket to shut down. - -Size: 1 - -Alignment: 1 - -### Record members -- `rd`: `bool` -Disables further receive operations. - -Bit: 0 - -- `wr`: `bool` -Disables further send operations. - -Bit: 1 - -## `preopentype`: `Variant` -Identifiers for preopened capabilities. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `dir` -A pre-opened directory. - -## `prestat_dir`: `Record` -The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). - -Size: 4 - -Alignment: 4 - -### Record members -- `pr_name_len`: [`size`](#size) -The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). - -Offset: 0 - -## `prestat`: `Variant` -Information about a pre-opened capability. - -Size: 8 - -Alignment: 4 - -### Variant Layout -- size: 8 -- align: 4 -- tag_size: 1 -### Variant cases -- `dir`: [`prestat_dir`](#prestat_dir) - -# Modules -## wasi_snapshot_preview1 -### Imports -#### Memory -### Functions - ---- - -#### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` -Read command-line argument data. -The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get). -Each argument is expected to be `\0` terminated. - -##### Params -- `argv`: `Pointer>` - -- `argv_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `args_sizes_get() -> Result<(size, size), errno>` -Return command-line argument data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of arguments and the size of the argument string -data, or an error. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` -Read environment variable data. -The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). -Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - -##### Params -- `environ`: `Pointer>` - -- `environ_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `environ_sizes_get() -> Result<(size, size), errno>` -Return environment variable data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of environment variable arguments and the size of the -environment variable data. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `clock_res_get(id: clockid) -> Result` -Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, -return [`errno::inval`](#errno.inval). -Note: This is similar to `clock_getres` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the resolution. - -##### Results -- `error`: `Result` -The resolution of the clock, or an error if one happened. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `clock_time_get(id: clockid, precision: timestamp) -> Result` -Return the time value of a clock. -Note: This is similar to `clock_gettime` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the time. - -- `precision`: [`timestamp`](#timestamp) -The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - -##### Results -- `error`: `Result` -The time value of the clock. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` -Provide file advisory information on a file descriptor. -Note: This is similar to `posix_fadvise` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset within the file to which the advisory applies. - -- `len`: [`filesize`](#filesize) -The length of the region to which the advisory applies. - -- `advice`: [`advice`](#advice) -The advice. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` -Force the allocation of space in a file. -Note: This is similar to `posix_fallocate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset at which to start the allocation. - -- `len`: [`filesize`](#filesize) -The length of the area that is allocated. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_close(fd: fd) -> Result<(), errno>` -Close a file descriptor. -Note: This is similar to `close` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_datasync(fd: fd) -> Result<(), errno>` -Synchronize the data of a file to disk. -Note: This is similar to `fdatasync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_get(fd: fd) -> Result` -Get the attributes of a file descriptor. -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file descriptor's attributes are stored. - -###### Variant Layout -- size: 32 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`fdstat`](#fdstat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` -Adjust the flags associated with a file descriptor. -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`fdflags`](#fdflags) -The desired values of the file descriptor flags. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` -Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights - -##### Params -- `fd`: [`fd`](#fd) - -- `fs_rights_base`: [`rights`](#rights) -The desired rights of the file descriptor. - -- `fs_rights_inheriting`: [`rights`](#rights) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_get(fd: fd) -> Result` -Return the attributes of an open file. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 72 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` -Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. -Note: This is similar to `ftruncate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `size`: [`filesize`](#filesize) -The desired file size. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of an open file or directory. -Note: This is similar to `futimens` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` -Read from a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `preadv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors in which to store data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to read. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_prestat_get(fd: fd) -> Result` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the description is stored. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`prestat`](#prestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `Pointer` -A buffer into which to write the preopened directory name. - -- `path_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` -Write to a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `pwritev` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to write. - -##### Results -- `error`: `Result` -The number of bytes written. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_read(fd: fd, iovs: iovec_array) -> Result` -Read from a file descriptor. -Note: This is similar to `readv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` -Read directory entries from a directory. -When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a [`dirent`](#dirent) object, -followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory -entry. -This function fills the output buffer as much as possible, potentially -truncating the last directory entry. This allows the caller to grow its -read buffer size in case it's too small to fit a single large directory -entry, or skip the oversized directory entry. - -##### Params -- `fd`: [`fd`](#fd) - -- `buf`: `Pointer` -The buffer where directory entries are stored - -- `buf_len`: [`size`](#size) - -- `cookie`: [`dircookie`](#dircookie) -The location within the directory to start reading - -##### Results -- `error`: `Result` -The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_renumber(fd: fd, to: fd) -> Result<(), errno>` -Atomically replace a file descriptor by renumbering another file descriptor. -Due to the strong focus on thread safety, this environment does not provide -a mechanism to duplicate or renumber a file descriptor to an arbitrary -number, like `dup2()`. This would be prone to race conditions, as an actual -file descriptor with the same number could be allocated by a different -thread at the same time. -This function provides a way to atomically renumber file descriptors, which -would disappear if `dup2()` were to be removed entirely. - -##### Params -- `fd`: [`fd`](#fd) - -- `to`: [`fd`](#fd) -The file descriptor to overwrite. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> Result` -Move the offset of a file descriptor. -Note: This is similar to `lseek` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filedelta`](#filedelta) -The number of bytes to move. - -- `whence`: [`whence`](#whence) -The base from which the offset is relative. - -##### Results -- `error`: `Result` -The new offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_sync(fd: fd) -> Result<(), errno>` -Synchronize the data and metadata of a file to disk. -Note: This is similar to `fsync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_tell(fd: fd) -> Result` -Return the current offset of a file descriptor. -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The current offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_write(fd: fd, iovs: ciovec_array) -> Result` -Write to a file descriptor. -Note: This is similar to `writev` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -##### Results -- `error`: `Result` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_create_directory(fd: fd, path: string) -> Result<(), errno>` -Create a directory. -Note: This is similar to `mkdirat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path at which to create the directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` -Return the attributes of a file or directory. -Note: This is similar to `stat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to inspect. - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 72 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of a file or directory. -Note: This is similar to `utimensat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to operate on. - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Create a hard link. -Note: This is similar to `linkat` in POSIX. - -##### Params -- `old_fd`: [`fd`](#fd) - -- `old_flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `old_path`: `string` -The source path from which to link. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path at which to create the hard link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> Result` -Open a file or directory. -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since this -is error-prone in multi-threaded contexts. The returned file descriptor is -guaranteed to be less than 2**31. -Note: This is similar to `openat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `dirflags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The relative path of the file or directory to open, relative to the -[`path_open::fd`](#path_open.fd) directory. - -- `oflags`: [`oflags`](#oflags) -The method by which to open the file. - -- `fs_rights_base`: [`rights`](#rights) -The initial rights of the newly created file descriptor. The -implementation is allowed to return a file descriptor with fewer rights -than specified, if and only if those rights do not apply to the type of -file being opened. -The *base* rights are rights that will apply to operations using the file -descriptor itself, while the *inheriting* rights are rights that apply to -file descriptors derived from it. - -- `fs_rights_inheriting`: [`rights`](#rights) - -- `fdflags`: [`fdflags`](#fdflags) - -##### Results -- `error`: `Result` -The file descriptor of the file that has been opened. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`fd`](#fd) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` -Read the contents of a symbolic link. -Note: This is similar to `readlinkat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path of the symbolic link from which to read. - -- `buf`: `Pointer` -The buffer to which to write the contents of the symbolic link. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result` -The number of bytes placed in the buffer. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_remove_directory(fd: fd, path: string) -> Result<(), errno>` -Remove a directory. -Return [`errno::notempty`](#errno.notempty) if the directory is not empty. -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a directory to remove. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Rename a file or directory. -Note: This is similar to `renameat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `old_path`: `string` -The source path of the file or directory to rename. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path to which to rename the file or directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` -Create a symbolic link. -Note: This is similar to `symlinkat` in POSIX. - -##### Params -- `old_path`: `string` -The contents of the symbolic link. - -- `fd`: [`fd`](#fd) - -- `new_path`: `string` -The destination path at which to create the symbolic link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_unlink_file(fd: fd, path: string) -> Result<(), errno>` -Unlink a file. -Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a file to unlink. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` -Concurrently poll for the occurrence of a set of events. - -##### Params -- `in`: `ConstPointer` -The events to which to subscribe. - -- `out`: `Pointer` -The events that have occurred. - -- `nsubscriptions`: [`size`](#size) -Both the number of subscriptions and events. - -##### Results -- `error`: `Result` -The number of events stored. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `proc_exit(rval: exitcode)` -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -##### Params -- `rval`: [`exitcode`](#exitcode) -The exit code returned by the process. - -##### Results - ---- - -#### `proc_raise(sig: signal) -> Result<(), errno>` -Send a signal to the process of the calling thread. -Note: This is similar to `raise` in POSIX. - -##### Params -- `sig`: [`signal`](#signal) -The signal condition to trigger. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sched_yield() -> Result<(), errno>` -Temporarily yield execution of the calling thread. -Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. - -##### Params -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `random_get(buf: Pointer, buf_len: size) -> Result<(), errno>` -Write high-quality random data into a buffer. -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. -This function may execute slowly, so when large mounts of random data are -required, it's advisable to use this function to seed a pseudo-random -number generator, rather than to provide the random data directly. - -##### Params -- `buf`: `Pointer` -The buffer to fill with random data. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` -Receive a message from a socket. -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -##### Params -- `fd`: [`fd`](#fd) - -- `ri_data`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -- `ri_flags`: [`riflags`](#riflags) -Message flags. - -##### Results -- `error`: `Result<(size, roflags), errno>` -Number of bytes stored in ri_data and message flags. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, roflags)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`roflags`](#roflags) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` -Send a message on a socket. -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -##### Params -- `fd`: [`fd`](#fd) - -- `si_data`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors to which to retrieve data - -- `si_flags`: [`siflags`](#siflags) -Message flags. - -##### Results -- `error`: `Result` -Number of bytes transmitted. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_shutdown(fd: fd, how: sdflags) -> Result<(), errno>` -Shut down socket send and receive channels. -Note: This is similar to `shutdown` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `how`: [`sdflags`](#sdflags) -Which channels on the socket to shut down. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - diff --git a/proposals/clocks/phases/snapshot/witx/typenames.witx b/proposals/clocks/phases/snapshot/witx/typenames.witx deleted file mode 100644 index 311b42233..000000000 --- a/proposals/clocks/phases/snapshot/witx/typenames.witx +++ /dev/null @@ -1,748 +0,0 @@ -;; Type names used by low-level WASI interfaces. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(typename $size u32) - -;;; Non-negative file size or length of a region within a file. -(typename $filesize u64) - -;;; Timestamp in nanoseconds. -(typename $timestamp u64) - -;;; Identifiers for clocks. -(typename $clockid - (enum (@witx tag u32) - ;;; The clock measuring real time. Time value zero corresponds with - ;;; 1970-01-01T00:00:00Z. - $realtime - ;;; The store-wide monotonic clock, which is defined as a clock measuring - ;;; real time, whose value cannot be adjusted and which cannot have negative - ;;; clock jumps. The epoch of this clock is undefined. The absolute time - ;;; value of this clock therefore has no meaning. - $monotonic - ;;; The CPU-time clock associated with the current process. - $process_cputime_id - ;;; The CPU-time clock associated with the current thread. - $thread_cputime_id - ) -) - -;;; Error codes returned by functions. -;;; Not all of these error codes are returned by the functions provided by this -;;; API; some are used in higher-level library layers, and others are provided -;;; merely for alignment with POSIX. -(typename $errno - (enum (@witx tag u16) - ;;; No error occurred. System call completed successfully. - $success - ;;; Argument list too long. - $2big - ;;; Permission denied. - $acces - ;;; Address in use. - $addrinuse - ;;; Address not available. - $addrnotavail - ;;; Address family not supported. - $afnosupport - ;;; Resource unavailable, or operation would block. - $again - ;;; Connection already in progress. - $already - ;;; Bad file descriptor. - $badf - ;;; Bad message. - $badmsg - ;;; Device or resource busy. - $busy - ;;; Operation canceled. - $canceled - ;;; No child processes. - $child - ;;; Connection aborted. - $connaborted - ;;; Connection refused. - $connrefused - ;;; Connection reset. - $connreset - ;;; Resource deadlock would occur. - $deadlk - ;;; Destination address required. - $destaddrreq - ;;; Mathematics argument out of domain of function. - $dom - ;;; Reserved. - $dquot - ;;; File exists. - $exist - ;;; Bad address. - $fault - ;;; File too large. - $fbig - ;;; Host is unreachable. - $hostunreach - ;;; Identifier removed. - $idrm - ;;; Illegal byte sequence. - $ilseq - ;;; Operation in progress. - $inprogress - ;;; Interrupted function. - $intr - ;;; Invalid argument. - $inval - ;;; I/O error. - $io - ;;; Socket is connected. - $isconn - ;;; Is a directory. - $isdir - ;;; Too many levels of symbolic links. - $loop - ;;; File descriptor value too large. - $mfile - ;;; Too many links. - $mlink - ;;; Message too large. - $msgsize - ;;; Reserved. - $multihop - ;;; Filename too long. - $nametoolong - ;;; Network is down. - $netdown - ;;; Connection aborted by network. - $netreset - ;;; Network unreachable. - $netunreach - ;;; Too many files open in system. - $nfile - ;;; No buffer space available. - $nobufs - ;;; No such device. - $nodev - ;;; No such file or directory. - $noent - ;;; Executable file format error. - $noexec - ;;; No locks available. - $nolck - ;;; Reserved. - $nolink - ;;; Not enough space. - $nomem - ;;; No message of the desired type. - $nomsg - ;;; Protocol not available. - $noprotoopt - ;;; No space left on device. - $nospc - ;;; Function not supported. - $nosys - ;;; The socket is not connected. - $notconn - ;;; Not a directory or a symbolic link to a directory. - $notdir - ;;; Directory not empty. - $notempty - ;;; State not recoverable. - $notrecoverable - ;;; Not a socket. - $notsock - ;;; Not supported, or operation not supported on socket. - $notsup - ;;; Inappropriate I/O control operation. - $notty - ;;; No such device or address. - $nxio - ;;; Value too large to be stored in data type. - $overflow - ;;; Previous owner died. - $ownerdead - ;;; Operation not permitted. - $perm - ;;; Broken pipe. - $pipe - ;;; Protocol error. - $proto - ;;; Protocol not supported. - $protonosupport - ;;; Protocol wrong type for socket. - $prototype - ;;; Result too large. - $range - ;;; Read-only file system. - $rofs - ;;; Invalid seek. - $spipe - ;;; No such process. - $srch - ;;; Reserved. - $stale - ;;; Connection timed out. - $timedout - ;;; Text file busy. - $txtbsy - ;;; Cross-device link. - $xdev - ;;; Extension: Capabilities insufficient. - $notcapable - ) -) - -;;; File descriptor rights, determining which actions may be performed. -(typename $rights - (flags (@witx repr u64) - ;;; The right to invoke `fd_datasync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::dsync`. - $fd_datasync - ;;; The right to invoke `fd_read` and `sock_recv`. - ;; - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. - $fd_read - ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. - $fd_seek - ;;; The right to invoke `fd_fdstat_set_flags`. - $fd_fdstat_set_flags - ;;; The right to invoke `fd_sync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. - $fd_sync - ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to - ;;; invoke `fd_tell`. - $fd_tell - ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. - $fd_write - ;;; The right to invoke `fd_advise`. - $fd_advise - ;;; The right to invoke `fd_allocate`. - $fd_allocate - ;;; The right to invoke `path_create_directory`. - $path_create_directory - ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::creat`. - $path_create_file - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; source directory. - $path_link_source - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; target directory. - $path_link_target - ;;; The right to invoke `path_open`. - $path_open - ;;; The right to invoke `fd_readdir`. - $fd_readdir - ;;; The right to invoke `path_readlink`. - $path_readlink - ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $path_rename_source - ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $path_rename_target - ;;; The right to invoke `path_filestat_get`. - $path_filestat_get - ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. - $path_filestat_set_size - ;;; The right to invoke `path_filestat_set_times`. - $path_filestat_set_times - ;;; The right to invoke `fd_filestat_get`. - $fd_filestat_get - ;;; The right to invoke `fd_filestat_set_size`. - $fd_filestat_set_size - ;;; The right to invoke `fd_filestat_set_times`. - $fd_filestat_set_times - ;;; The right to invoke `path_symlink`. - $path_symlink - ;;; The right to invoke `path_remove_directory`. - $path_remove_directory - ;;; The right to invoke `path_unlink_file`. - $path_unlink_file - ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. - ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. - $poll_fd_readwrite - ;;; The right to invoke `sock_shutdown`. - $sock_shutdown - ) -) - -;;; A file descriptor handle. -(typename $fd (handle)) - -;;; A region of memory for scatter/gather reads. -(typename $iovec - (record - ;;; The address of the buffer to be filled. - (field $buf (@witx pointer u8)) - ;;; The length of the buffer to be filled. - (field $buf_len $size) - ) -) - -;;; A region of memory for scatter/gather writes. -(typename $ciovec - (record - ;;; The address of the buffer to be written. - (field $buf (@witx const_pointer u8)) - ;;; The length of the buffer to be written. - (field $buf_len $size) - ) -) - -(typename $iovec_array (list $iovec)) -(typename $ciovec_array (list $ciovec)) - -;;; Relative offset within a file. -(typename $filedelta s64) - -;;; The position relative to which to set the offset of the file descriptor. -(typename $whence - (enum (@witx tag u8) - ;;; Seek relative to start-of-file. - $set - ;;; Seek relative to current position. - $cur - ;;; Seek relative to end-of-file. - $end - ) -) - -;;; A reference to the offset of a directory entry. -;;; -;;; The value 0 signifies the start of the directory. -(typename $dircookie u64) - -;;; The type for the `dirent::d_namlen` field of `dirent` struct. -(typename $dirnamlen u32) - -;;; File serial number that is unique within its file system. -(typename $inode u64) - -;;; The type of a file descriptor or file. -(typename $filetype - (enum (@witx tag u8) - ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $unknown - ;;; The file descriptor or file refers to a block device inode. - $block_device - ;;; The file descriptor or file refers to a character device inode. - $character_device - ;;; The file descriptor or file refers to a directory inode. - $directory - ;;; The file descriptor or file refers to a regular file inode. - $regular_file - ;;; The file descriptor or file refers to a datagram socket. - $socket_dgram - ;;; The file descriptor or file refers to a byte-stream socket. - $socket_stream - ;;; The file refers to a symbolic link inode. - $symbolic_link - ) -) - -;;; A directory entry. -(typename $dirent - (record - ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie) - ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) - ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype) - ) -) - -;;; File or memory access pattern advisory information. -(typename $advice - (enum (@witx tag u8) - ;;; The application has no advice to give on its behavior with respect to the specified data. - $normal - ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $sequential - ;;; The application expects to access the specified data in a random order. - $random - ;;; The application expects to access the specified data in the near future. - $willneed - ;;; The application expects that it will not access the specified data in the near future. - $dontneed - ;;; The application expects to access the specified data once and then not reuse it thereafter. - $noreuse - ) -) - -;;; File descriptor flags. -(typename $fdflags - (flags (@witx repr u16) - ;;; Append mode: Data written to the file is always appended to the file's end. - $append - ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $dsync - ;;; Non-blocking mode. - $nonblock - ;;; Synchronized read I/O operations. - $rsync - ;;; Write according to synchronized I/O file integrity completion. In - ;;; addition to synchronizing the data stored in the file, the implementation - ;;; may also synchronously update the file's metadata. - $sync - ) -) - -;;; File descriptor attributes. -(typename $fdstat - (record - ;;; File type. - (field $fs_filetype $filetype) - ;;; File descriptor flags. - (field $fs_flags $fdflags) - ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights) - ;;; Maximum set of rights that may be installed on new file descriptors that - ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights) - ) -) - -;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode` to uniquely identify a file or directory in the filesystem. -(typename $device u64) - -;;; Which file time attributes to adjust. -(typename $fstflags - (flags (@witx repr u16) - ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. - $atim - ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. - $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. - $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. - $mtim_now - ) -) - -;;; Flags determining the method of how paths are resolved. -(typename $lookupflags - (flags (@witx repr u32) - ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $symlink_follow - ) -) - -;;; Open flags used by `path_open`. -(typename $oflags - (flags (@witx repr u16) - ;;; Create file if it does not exist. - $creat - ;;; Fail if not a directory. - $directory - ;;; Fail if file already exists. - $excl - ;;; Truncate file to size 0. - $trunc - ) -) - -;;; Number of hard links to an inode. -(typename $linkcount u64) - -;;; File attributes. -(typename $filestat - (record - ;;; Device ID of device containing the file. - (field $dev $device) - ;;; File serial number. - (field $ino $inode) - ;;; File type. - (field $filetype $filetype) - ;;; Number of hard links to the file. - (field $nlink $linkcount) - ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $size $filesize) - ;;; Last data access timestamp. - (field $atim $timestamp) - ;;; Last data modification timestamp. - (field $mtim $timestamp) - ;;; Last file status change timestamp. - (field $ctim $timestamp) - ) -) - -;;; User-provided value that may be attached to objects that is retained when -;;; extracted from the implementation. -(typename $userdata u64) - -;;; Type of a subscription to an event or its occurrence. -(typename $eventtype - (enum (@witx tag u8) - ;;; The time value of clock `subscription_clock::id` has - ;;; reached timestamp `subscription_clock::timeout`. - $clock - ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has data - ;;; available for reading. This event always triggers for regular files. - $fd_read - ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has capacity - ;;; available for writing. This event always triggers for regular files. - $fd_write - ) -) - -;;; The state of the file descriptor subscribed to with -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $eventrwflags - (flags (@witx repr u16) - ;;; The peer of this socket has closed or disconnected. - $fd_readwrite_hangup - ) -) - -;;; The contents of an `event` when type is `eventtype::fd_read` or -;;; `eventtype::fd_write`. -(typename $event_fd_readwrite - (record - ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize) - ;;; The state of the file descriptor. - (field $flags $eventrwflags) - ) -) - -;;; An event that occurred. -(typename $event - (record - ;;; User-provided value that got attached to `subscription::userdata`. - (field $userdata $userdata) - ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno) - ;;; The type of event that occured - (field $type $eventtype) - ;;; The contents of the event, if it is an `eventtype::fd_read` or - ;;; `eventtype::fd_write`. `eventtype::clock` events ignore this field. - (field $fd_readwrite $event_fd_readwrite) - ) -) - -;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_clock::timeout`. -(typename $subclockflags - (flags (@witx repr u16) - ;;; If set, treat the timestamp provided in - ;;; `subscription_clock::timeout` as an absolute timestamp of clock - ;;; `subscription_clock::id`. If clear, treat the timestamp - ;;; provided in `subscription_clock::timeout` relative to the - ;;; current time value of clock `subscription_clock::id`. - $subscription_clock_abstime - ) -) - -;;; The contents of a `subscription` when type is `eventtype::clock`. -(typename $subscription_clock - (record - ;;; The clock against which to compare the timestamp. - (field $id $clockid) - ;;; The absolute or relative timestamp. - (field $timeout $timestamp) - ;;; The amount of time that the implementation may wait additionally - ;;; to coalesce with other events. - (field $precision $timestamp) - ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags) - ) -) - -;;; The contents of a `subscription` when type is type is -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $subscription_fd_readwrite - (record - ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd) - ) -) - -;;; The contents of a `subscription`. -(typename $subscription_u - (union - (@witx tag $eventtype) - $subscription_clock - $subscription_fd_readwrite - $subscription_fd_readwrite - ) -) - -;;; Subscription to an event. -(typename $subscription - (record - ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event::userdata`. - (field $userdata $userdata) - ;;; The type of the event to which to subscribe, and its contents - (field $u $subscription_u) - ) -) - -;;; Exit code generated by a process when exiting. -(typename $exitcode u32) - -;;; Signal condition. -(typename $signal - (enum (@witx tag u8) - ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;;; so this value is reserved. - $none - ;;; Hangup. - ;;; Action: Terminates the process. - $hup - ;;; Terminate interrupt signal. - ;;; Action: Terminates the process. - $int - ;;; Terminal quit signal. - ;;; Action: Terminates the process. - $quit - ;;; Illegal instruction. - ;;; Action: Terminates the process. - $ill - ;;; Trace/breakpoint trap. - ;;; Action: Terminates the process. - $trap - ;;; Process abort signal. - ;;; Action: Terminates the process. - $abrt - ;;; Access to an undefined portion of a memory object. - ;;; Action: Terminates the process. - $bus - ;;; Erroneous arithmetic operation. - ;;; Action: Terminates the process. - $fpe - ;;; Kill. - ;;; Action: Terminates the process. - $kill - ;;; User-defined signal 1. - ;;; Action: Terminates the process. - $usr1 - ;;; Invalid memory reference. - ;;; Action: Terminates the process. - $segv - ;;; User-defined signal 2. - ;;; Action: Terminates the process. - $usr2 - ;;; Write on a pipe with no one to read it. - ;;; Action: Ignored. - $pipe - ;;; Alarm clock. - ;;; Action: Terminates the process. - $alrm - ;;; Termination signal. - ;;; Action: Terminates the process. - $term - ;;; Child process terminated, stopped, or continued. - ;;; Action: Ignored. - $chld - ;;; Continue executing, if stopped. - ;;; Action: Continues executing, if stopped. - $cont - ;;; Stop executing. - ;;; Action: Stops executing. - $stop - ;;; Terminal stop signal. - ;;; Action: Stops executing. - $tstp - ;;; Background process attempting read. - ;;; Action: Stops executing. - $ttin - ;;; Background process attempting write. - ;;; Action: Stops executing. - $ttou - ;;; High bandwidth data is available at a socket. - ;;; Action: Ignored. - $urg - ;;; CPU time limit exceeded. - ;;; Action: Terminates the process. - $xcpu - ;;; File size limit exceeded. - ;;; Action: Terminates the process. - $xfsz - ;;; Virtual timer expired. - ;;; Action: Terminates the process. - $vtalrm - ;;; Profiling timer expired. - ;;; Action: Terminates the process. - $prof - ;;; Window changed. - ;;; Action: Ignored. - $winch - ;;; I/O possible. - ;;; Action: Terminates the process. - $poll - ;;; Power failure. - ;;; Action: Terminates the process. - $pwr - ;;; Bad system call. - ;;; Action: Terminates the process. - $sys - ) -) - -;;; Flags provided to `sock_recv`. -(typename $riflags - (flags (@witx repr u16) - ;;; Returns the message without removing it from the socket's receive queue. - $recv_peek - ;;; On byte-stream sockets, block until the full amount of data can be returned. - $recv_waitall - ) -) - -;;; Flags returned by `sock_recv`. -(typename $roflags - (flags (@witx repr u16) - ;;; Returned by `sock_recv`: Message data has been truncated. - $recv_data_truncated - ) -) - -;;; Flags provided to `sock_send`. As there are currently no flags -;;; defined, it must be set to zero. -(typename $siflags u16) - -;;; Which channels on a socket to shut down. -(typename $sdflags - (flags (@witx repr u8) - ;;; Disables further receive operations. - $rd - ;;; Disables further send operations. - $wr - ) -) - -;;; Identifiers for preopened capabilities. -(typename $preopentype - (enum (@witx tag u8) - ;;; A pre-opened directory. - $dir - ) -) - -;;; The contents of a $prestat when type is `preopentype::dir`. -(typename $prestat_dir - (record - ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size) - ) -) - -;;; Information about a pre-opened capability. -(typename $prestat - (union (@witx tag $preopentype) - $prestat_dir - ) -) - diff --git a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx deleted file mode 100644 index efb2c797f..000000000 --- a/proposals/clocks/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ /dev/null @@ -1,510 +0,0 @@ -;; WASI Preview. This is an evolution of the API that WASI initially -;; launched with. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_snapshot_preview1 - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `args_sizes_get`. - ;;; Each argument is expected to be `\0` terminated. - (@interface func (export "args_get") - (param $argv (@witx pointer (@witx pointer u8))) - (param $argv_buf (@witx pointer u8)) - (result $error (expected (error $errno))) - ) - ;;; Return command-line argument data sizes. - (@interface func (export "args_sizes_get") - ;;; Returns the number of arguments and the size of the argument string - ;;; data, or an error. - (result $error (expected (tuple $size $size) (error $errno))) - ) - - ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. - ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - (@interface func (export "environ_get") - (param $environ (@witx pointer (@witx pointer u8))) - (param $environ_buf (@witx pointer u8)) - (result $error (expected (error $errno))) - ) - ;;; Return environment variable data sizes. - (@interface func (export "environ_sizes_get") - ;;; Returns the number of environment variable arguments and the size of the - ;;; environment variable data. - (result $error (expected (tuple $size $size) (error $errno))) - ) - - ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, - ;;; return `errno::inval`. - ;;; Note: This is similar to `clock_getres` in POSIX. - (@interface func (export "clock_res_get") - ;;; The clock for which to return the resolution. - (param $id $clockid) - ;;; The resolution of the clock, or an error if one happened. - (result $error (expected $timestamp (error $errno))) - ) - ;;; Return the time value of a clock. - ;;; Note: This is similar to `clock_gettime` in POSIX. - (@interface func (export "clock_time_get") - ;;; The clock for which to return the time. - (param $id $clockid) - ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp) - ;;; The time value of the clock. - (result $error (expected $timestamp (error $errno))) - ) - - ;;; Provide file advisory information on a file descriptor. - ;;; Note: This is similar to `posix_fadvise` in POSIX. - (@interface func (export "fd_advise") - (param $fd $fd) - ;;; The offset within the file to which the advisory applies. - (param $offset $filesize) - ;;; The length of the region to which the advisory applies. - (param $len $filesize) - ;;; The advice. - (param $advice $advice) - (result $error (expected (error $errno))) - ) - - ;;; Force the allocation of space in a file. - ;;; Note: This is similar to `posix_fallocate` in POSIX. - (@interface func (export "fd_allocate") - (param $fd $fd) - ;;; The offset at which to start the allocation. - (param $offset $filesize) - ;;; The length of the area that is allocated. - (param $len $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Close a file descriptor. - ;;; Note: This is similar to `close` in POSIX. - (@interface func (export "fd_close") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Synchronize the data of a file to disk. - ;;; Note: This is similar to `fdatasync` in POSIX. - (@interface func (export "fd_datasync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Get the attributes of a file descriptor. - ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (@interface func (export "fd_fdstat_get") - (param $fd $fd) - ;;; The buffer where the file descriptor's attributes are stored. - (result $error (expected $fdstat (error $errno))) - ) - - ;;; Adjust the flags associated with a file descriptor. - ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd) - ;;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights - (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd) - ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of an open file. - (@interface func (export "fd_filestat_get") - (param $fd $fd) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;;; Note: This is similar to `ftruncate` in POSIX. - (@interface func (export "fd_filestat_set_size") - (param $fd $fd) - ;;; The desired file size. - (param $size $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the timestamps of an open file or directory. - ;;; Note: This is similar to `futimens` in POSIX. - (@interface func (export "fd_filestat_set_times") - (param $fd $fd) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in POSIX. - (@interface func (export "fd_pread") - (param $fd $fd) - ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_array) - ;;; The offset within the file at which to read. - (param $offset $filesize) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_get") - (param $fd $fd) - ;;; The buffer where the description is stored. - (result $error (expected $prestat (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_dir_name") - (param $fd $fd) - ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer u8)) - (param $path_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in POSIX. - (@interface func (export "fd_pwrite") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The offset within the file at which to write. - (param $offset $filesize) - ;;; The number of bytes written. - (result $error (expected $size (error $errno))) - ) - - ;;; Read from a file descriptor. - ;;; Note: This is similar to `readv` in POSIX. - (@interface func (export "fd_read") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_array) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Read directory entries from a directory. - ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a `dirent` object, - ;;; followed by `dirent::d_namlen` bytes holding the name of the directory - ;;; entry. - ;; - ;;; This function fills the output buffer as much as possible, potentially - ;;; truncating the last directory entry. This allows the caller to grow its - ;;; read buffer size in case it's too small to fit a single large directory - ;;; entry, or skip the oversized directory entry. - (@interface func (export "fd_readdir") - (param $fd $fd) - ;;; The buffer where directory entries are stored - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The location within the directory to start reading - (param $cookie $dircookie) - ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $error (expected $size (error $errno))) - ) - - ;;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;;; Due to the strong focus on thread safety, this environment does not provide - ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;;; file descriptor with the same number could be allocated by a different - ;;; thread at the same time. - ;; - ;;; This function provides a way to atomically renumber file descriptors, which - ;;; would disappear if `dup2()` were to be removed entirely. - (@interface func (export "fd_renumber") - (param $fd $fd) - ;;; The file descriptor to overwrite. - (param $to $fd) - (result $error (expected (error $errno))) - ) - - ;;; Move the offset of a file descriptor. - ;;; Note: This is similar to `lseek` in POSIX. - (@interface func (export "fd_seek") - (param $fd $fd) - ;;; The number of bytes to move. - (param $offset $filedelta) - ;;; The base from which the offset is relative. - (param $whence $whence) - ;;; The new offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Synchronize the data and metadata of a file to disk. - ;;; Note: This is similar to `fsync` in POSIX. - (@interface func (export "fd_sync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Return the current offset of a file descriptor. - ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (@interface func (export "fd_tell") - (param $fd $fd) - ;;; The current offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Write to a file descriptor. - ;;; Note: This is similar to `writev` in POSIX. - (@interface func (export "fd_write") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - (result $error (expected $size (error $errno))) - ) - - ;;; Create a directory. - ;;; Note: This is similar to `mkdirat` in POSIX. - (@interface func (export "path_create_directory") - (param $fd $fd) - ;;; The path at which to create the directory. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of a file or directory. - ;;; Note: This is similar to `stat` in POSIX. - (@interface func (export "path_filestat_get") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to inspect. - (param $path string) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the timestamps of a file or directory. - ;;; Note: This is similar to `utimensat` in POSIX. - (@interface func (export "path_filestat_set_times") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to operate on. - (param $path string) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Create a hard link. - ;;; Note: This is similar to `linkat` in POSIX. - (@interface func (export "path_link") - (param $old_fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags) - ;;; The source path from which to link. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path at which to create the hard link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Open a file or directory. - ;; - ;;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;;; file descriptor not currently open; it is randomized to prevent - ;;; applications from depending on making assumptions about indexes, since this - ;;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;;; guaranteed to be less than 2**31. - ;; - ;;; Note: This is similar to `openat` in POSIX. - (@interface func (export "path_open") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags) - ;;; The relative path of the file or directory to open, relative to the - ;;; `path_open::fd` directory. - (param $path string) - ;;; The method by which to open the file. - (param $oflags $oflags) - ;;; The initial rights of the newly created file descriptor. The - ;;; implementation is allowed to return a file descriptor with fewer rights - ;;; than specified, if and only if those rights do not apply to the type of - ;;; file being opened. - ;; - ;;; The *base* rights are rights that will apply to operations using the file - ;;; descriptor itself, while the *inheriting* rights are rights that apply to - ;;; file descriptors derived from it. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (param $fdflags $fdflags) - ;;; The file descriptor of the file that has been opened. - (result $error (expected $fd (error $errno))) - ) - - ;;; Read the contents of a symbolic link. - ;;; Note: This is similar to `readlinkat` in POSIX. - (@interface func (export "path_readlink") - (param $fd $fd) - ;;; The path of the symbolic link from which to read. - (param $path string) - ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The number of bytes placed in the buffer. - (result $error (expected $size (error $errno))) - ) - - ;;; Remove a directory. - ;;; Return `errno::notempty` if the directory is not empty. - ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (@interface func (export "path_remove_directory") - (param $fd $fd) - ;;; The path to a directory to remove. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Rename a file or directory. - ;;; Note: This is similar to `renameat` in POSIX. - (@interface func (export "path_rename") - (param $fd $fd) - ;;; The source path of the file or directory to rename. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Create a symbolic link. - ;;; Note: This is similar to `symlinkat` in POSIX. - (@interface func (export "path_symlink") - ;;; The contents of the symbolic link. - (param $old_path string) - (param $fd $fd) - ;;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - - ;;; Unlink a file. - ;;; Return `errno::isdir` if the path refers to a directory. - ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (@interface func (export "path_unlink_file") - (param $fd $fd) - ;;; The path to a file to unlink. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Concurrently poll for the occurrence of a set of events. - (@interface func (export "poll_oneoff") - ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription)) - ;;; The events that have occurred. - (param $out (@witx pointer $event)) - ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size) - ;;; The number of events stored. - (result $error (expected $size (error $errno))) - ) - - ;;; Terminate the process normally. An exit code of 0 indicates successful - ;;; termination of the program. The meanings of other values is dependent on - ;;; the environment. - (@interface func (export "proc_exit") - ;;; The exit code returned by the process. - (param $rval $exitcode) - (@witx noreturn) - ) - - ;;; Send a signal to the process of the calling thread. - ;;; Note: This is similar to `raise` in POSIX. - (@interface func (export "proc_raise") - ;;; The signal condition to trigger. - (param $sig $signal) - (result $error (expected (error $errno))) - ) - - ;;; Temporarily yield execution of the calling thread. - ;;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "sched_yield") - (result $error (expected (error $errno))) - ) - - ;;; Write high-quality random data into a buffer. - ;;; This function blocks when the implementation is unable to immediately - ;;; provide sufficient high-quality random data. - ;;; This function may execute slowly, so when large mounts of random data are - ;;; required, it's advisable to use this function to seed a pseudo-random - ;;; number generator, rather than to provide the random data directly. - (@interface func (export "random_get") - ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Receive a message from a socket. - ;;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;;; the data into multiple buffers in the manner of `readv`. - (@interface func (export "sock_recv") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_array) - ;;; Message flags. - (param $ri_flags $riflags) - ;;; Number of bytes stored in ri_data and message flags. - (result $error (expected (tuple $size $roflags) (error $errno))) - ) - - ;;; Send a message on a socket. - ;;; Note: This is similar to `send` in POSIX, though it also supports writing - ;;; the data from multiple buffers in the manner of `writev`. - (@interface func (export "sock_send") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_array) - ;;; Message flags. - (param $si_flags $siflags) - ;;; Number of bytes transmitted. - (result $error (expected $size (error $errno))) - ) - - ;;; Shut down socket send and receive channels. - ;;; Note: This is similar to `shutdown` in POSIX. - (@interface func (export "sock_shutdown") - (param $fd $fd) - ;;; Which channels on the socket to shut down. - (param $how $sdflags) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/clocks/proposal-template/README.md b/proposals/clocks/proposal-template/README.md deleted file mode 100644 index b97035935..000000000 --- a/proposals/clocks/proposal-template/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Proposal template - -This directory will hold a template for creating new proposals, to help people -get started. diff --git a/proposals/clocks/proposals/README.md b/proposals/clocks/proposals/README.md deleted file mode 100644 index 45c2c2852..000000000 --- a/proposals/clocks/proposals/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Proposals - -This directory contains overviews for proposals that are included in this -repository. - -This is analogous to [the correpsonding directory in the spec repository]. - -[the correpsonding directory in the spec repository]: https://github.com/WebAssembly/spec/tree/master/proposals diff --git a/proposals/clocks/snapshots/README.md b/proposals/clocks/snapshots/README.md deleted file mode 100644 index af94dbdef..000000000 --- a/proposals/clocks/snapshots/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# WASI Snapshots - -To balance between the needs of development and stability, snapshots -represent the state of all active proposals at a moment in time. Individual -Snapshots are stable, but WASI as a whole is evolving. diff --git a/proposals/clocks/snapshots/make-snapshot.sh b/proposals/clocks/snapshots/make-snapshot.sh deleted file mode 100755 index b30dfa2e5..000000000 --- a/proposals/clocks/snapshots/make-snapshot.sh +++ /dev/null @@ -1,159 +0,0 @@ -#!/bin/bash -# Creates a snapshot based on upstream proposal repositories. -# Derived from update-testsuite.sh in https://github.com/WebAssembly/testsuite -set -e -set -u -set -o pipefail - -ignore_dirs='' - -# TODO: Add the rest. -repos=' - WASI - wasi-filesystem - wasi-clocks - wasi-random -' - -log_and_run() { - echo ">>" $* - if ! $*; then - echo "sub-command failed: $*" - exit - fi -} - -try_log_and_run() { - echo ">>" $* - $* -} - -pushdir() { - pushd $1 >/dev/null || exit -} - -popdir() { - popd >/dev/null || exit -} - -update_repo() { - local repo=$1 - pushdir repos - if [ -d ${repo} ]; then - log_and_run git -C ${repo} fetch origin - log_and_run git -C ${repo} reset origin/main --hard - else - log_and_run git clone https://github.com/WebAssembly/${repo} - fi - - # Add upstream WASI as "WASI" remote. - if [ "${repo}" != "WASI" ]; then - pushdir ${repo} - if ! git remote | grep WASI >/dev/null; then - log_and_run git remote add WASI https://github.com/WebAssembly/WASI - fi - - log_and_run git fetch WASI - popdir - fi - popdir -} - -merge_with_WASI() { - local repo=$1 - - [ "${repo}" == "WASI" ] && return - - pushdir repos/${repo} - # Create and checkout "try-merge" branch. - if ! git branch | grep try-merge >/dev/null; then - log_and_run git branch try-merge origin/main - fi - log_and_run git checkout try-merge - - # Attempt to merge with WASI/main. - log_and_run git reset origin/main --hard - try_log_and_run git merge -q WASI/main -m "merged" - if [ $? -ne 0 ]; then - # Ignore merge conflicts in non-test directories. - # We don't care about those changes. - try_log_and_run git checkout --ours ${ignore_dirs} - try_log_and_run git add ${ignore_dirs} - try_log_and_run git -c core.editor=true merge --continue - if [ $? -ne 0 ]; then - git merge --abort - popdir - return 1 - fi - fi - popdir - return 0 -} - -snapshot_name=$(date --iso-8601) -snapshot_dir=snapshots/$snapshot_name -mkdir -p $snapshot_dir - -commit_message_file=$PWD/commit_message -echo -e "Update repos\n" > $commit_message_file - -failed_repos= - -for repo in ${repos}; do - echo "++ updating ${repo}" - update_repo ${repo} - - if ! merge_with_WASI ${repo}; then - echo -e "!! error merging ${repo}, skipping\n" - failed_repos="${failed_repos} ${repo}" - continue - fi - - if [ "${repo}" = "WASI" ]; then - dest_dir=$snapshot_dir - log_and_run cp -r repos/${repo}/standard ${dest_dir} - else - dest_dir=$snapshot_dir/proposals/${repo} - mkdir -p ${dest_dir} - - # Don't add tests from proposal that are the same as WASI. - pushdir repos/${repo} - for new in $(find standard -type f); do - old=../../repos/WASI/${new} - if [[ ! -f ${old} ]] || ! diff ${old} ${new} >/dev/null; then - log_and_run cp ${new} ../../${dest_dir} - fi - done - popdir - fi - - # Check whether any files were removed. - for old in $(find ${dest_dir} -type f); do - new=$(find repos/${repo}/standard -name ${old##*/}) - if [[ ! -f ${new} ]]; then - log_and_run git rm ${old} - fi - done - - # Check whether any files were updated. - if [ $(git status -s ${dest_dir} | wc -l) -ne 0 ]; then - log_and_run git add ${dest_dir}/* - - repo_sha=$(git -C repos/${repo} log --max-count=1 --oneline origin/main| sed -e 's/ .*//') - echo " ${repo}:" >> $commit_message_file - echo " https://github.com/WebAssembly/${repo}/commit/${repo_sha}" >> $commit_message_file - fi - - echo -e "-- ${repo}\n" -done - -echo "" >> $commit_message_file -echo "This change was automatically generated by \`make-snapshot.sh\`" >> $commit_message_file -git commit -a -F $commit_message_file -# git push - -echo "done" - -if [ -n "${failed_repos}" ]; then - echo "!! failed to update repos: ${failed_repos}" -fi diff --git a/proposals/clocks/standard/README.md b/proposals/clocks/standard/README.md deleted file mode 100644 index ad6f93c7c..000000000 --- a/proposals/clocks/standard/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# WASI Standard - -In the [main WASI repository], this directory holds proposals which have -[completed the standardization process]. - -In a proposal repository, which is a fork of the main WASI repository, -this directory holds the current proposal, including witx specifications, -tests, and documentation. When the proposal is standardized, the fork is -merged into the main repository. - -[main WASI repository]: https://github.com/WebAssembly/WASI/issues/360 -[completed the standardization process]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md#5-the-feature-is-standardized-working-group diff --git a/proposals/clocks/standard/wasi-clocks/docs.md b/proposals/clocks/standard/wasi-clocks/docs.md deleted file mode 100644 index 4b7ba07c1..000000000 --- a/proposals/clocks/standard/wasi-clocks/docs.md +++ /dev/null @@ -1,1266 +0,0 @@ -# Types -## `size`: `usize` -An array size. - -Note: This is similar to `size_t` in POSIX. - -Size: 4 - -Alignment: 4 - -## `filesize`: `u64` -Non-negative file size or length of a region within a file. - -Size: 8 - -Alignment: 8 - -## `timestamp`: `u64` -Timestamp in nanoseconds. - -Size: 8 - -Alignment: 8 - -## `clockid`: `Variant` -Identifiers for clocks. - -Size: 4 - -Alignment: 4 - -### Variant cases -- `realtime` -The clock measuring real time. Time value zero corresponds with -1970-01-01T00:00:00Z. - -- `monotonic` -The store-wide monotonic clock, which is defined as a clock measuring -real time, whose value cannot be adjusted and which cannot have negative -clock jumps. The epoch of this clock is undefined. The absolute time -value of this clock therefore has no meaning. - -## `errno`: `Variant` -Error codes returned by functions. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX. - -Size: 2 - -Alignment: 2 - -### Variant cases -- `success` -No error occurred. System call completed successfully. - -- `2big` -Argument list too long. - -- `access` -Permission denied. - -- `addrinuse` -Address in use. - -- `addrnotavail` -Address not available. - -- `afnosupport` -Address family not supported. - -- `again` -Resource unavailable, or operation would block. - -- `already` -Connection already in progress. - -- `badf` -Bad file descriptor. - -- `badmsg` -Bad message. - -- `busy` -Device or resource busy. - -- `canceled` -Operation canceled. - -- `child` -No child processes. - -- `connaborted` -Connection aborted. - -- `connrefused` -Connection refused. - -- `connreset` -Connection reset. - -- `deadlk` -Resource deadlock would occur. - -- `destaddrreq` -Destination address required. - -- `dom` -Mathematics argument out of domain of function. - -- `dquot` -Reserved. - -- `exist` -File exists. - -- `fault` -Bad address. - -- `fbig` -File too large. - -- `hostunreach` -Host is unreachable. - -- `idrm` -Identifier removed. - -- `ilseq` -Illegal byte sequence. - -- `inprogress` -Operation in progress. - -- `intr` -Interrupted function. - -- `inval` -Invalid argument. - -- `io` -I/O error. - -- `isconn` -Socket is connected. - -- `isdir` -Is a directory. - -- `loop` -Too many levels of symbolic links. - -- `mfile` -File descriptor value too large. - -- `mlink` -Too many links. - -- `msgsize` -Message too large. - -- `multihop` -Reserved. - -- `nametoolong` -Filename too long. - -- `netdown` -Network is down. - -- `netreset` -Connection aborted by network. - -- `netunreach` -Network unreachable. - -- `nfile` -Too many files open in system. - -- `nobufs` -No buffer space available. - -- `nodev` -No such device. - -- `noent` -No such file or directory. - -- `noexec` -Executable file format error. - -- `nolck` -No locks available. - -- `nolink` -Reserved. - -- `nomem` -Not enough space. - -- `nomsg` -No message of the desired type. - -- `noprotoopt` -Protocol not available. - -- `nospc` -No space left on device. - -- `nosys` -Function not supported. - -- `notconn` -The socket is not connected. - -- `notdir` -Not a directory or a symbolic link to a directory. - -- `notempty` -Directory not empty. - -- `notrecoverable` -State not recoverable. - -- `notsock` -Not a socket. - -- `notsup` -Not supported, or operation not supported on socket. - -- `notty` -Inappropriate I/O control operation. - -- `nxio` -No such device or address. - -- `overflow` -Value too large to be stored in data type. - -- `ownerdead` -Previous owner died. - -- `perm` -Operation not permitted. - -- `pipe` -Broken pipe. - -- `proto` -Protocol error. - -- `protonosupport` -Protocol not supported. - -- `prototype` -Protocol wrong type for socket. - -- `range` -Result too large. - -- `rofs` -Read-only file system. - -- `spipe` -Invalid seek. - -- `srch` -No such process. - -- `stale` -Reserved. - -- `timedout` -Connection timed out. - -- `txtbsy` -Text file busy. - -- `xdev` -Cross-device link. - -- `notcapable` -Extension: Capabilities insufficient. - -## `rights`: `Record` -File descriptor rights, determining which actions may be performed. - -Size: 8 - -Alignment: 8 - -### Record members -- `fd_datasync`: `bool` -The right to invoke `fd_datasync`. -If `path_open` is set, includes the right to invoke -`path_open` with [`fdflags::dsync`](#fdflags.dsync). - -Bit: 0 - -- `fd_read`: `bool` -The right to invoke `fd_read` and `sock_recv`. -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. - -Bit: 1 - -- `fd_seek`: `bool` -The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). - -Bit: 2 - -- `fd_fdstat_set_flags`: `bool` -The right to invoke `fd_fdstat_set_flags`. - -Bit: 3 - -- `fd_sync`: `bool` -The right to invoke `fd_sync`. -If `path_open` is set, includes the right to invoke -`path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - -Bit: 4 - -- `fd_tell`: `bool` -The right to invoke `fd_seek` in such a way that the file offset -remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to -invoke `fd_tell`. - -Bit: 5 - -- `fd_write`: `bool` -The right to invoke `fd_write` and `sock_send`. -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. - -Bit: 6 - -- `fd_advise`: `bool` -The right to invoke `fd_advise`. - -Bit: 7 - -- `fd_allocate`: `bool` -The right to invoke `fd_allocate`. - -Bit: 8 - -- `path_create_directory`: `bool` -The right to invoke `path_create_directory`. - -Bit: 9 - -- `path_create_file`: `bool` -If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). - -Bit: 10 - -- `path_link_source`: `bool` -The right to invoke `path_link` with the file descriptor as the -source directory. - -Bit: 11 - -- `path_link_target`: `bool` -The right to invoke `path_link` with the file descriptor as the -target directory. - -Bit: 12 - -- `path_open`: `bool` -The right to invoke `path_open`. - -Bit: 13 - -- `fd_readdir`: `bool` -The right to invoke `fd_readdir`. - -Bit: 14 - -- `path_readlink`: `bool` -The right to invoke `path_readlink`. - -Bit: 15 - -- `path_rename_source`: `bool` -The right to invoke `path_rename` with the file descriptor as the source directory. - -Bit: 16 - -- `path_rename_target`: `bool` -The right to invoke `path_rename` with the file descriptor as the target directory. - -Bit: 17 - -- `path_filestat_get`: `bool` -The right to invoke `path_filestat_get`. - -Bit: 18 - -- `path_filestat_set_size`: `bool` -The right to change a file's size. -If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). -Note: there is no function named `path_filestat_set_size`. This follows POSIX design, -which only has `ftruncate` and does not provide `ftruncateat`. -While such function would be desirable from the API design perspective, there are virtually -no use cases for it since no code written for POSIX systems would use it. -Moreover, implementing it would require multiple syscalls, leading to inferior performance. - -Bit: 19 - -- `path_filestat_set_times`: `bool` -The right to invoke `path_filestat_set_times`. - -Bit: 20 - -- `path_permissions_set`: `bool` -The right to invoke `path_permissions_set`. - -Bit: 21 - -- `fd_filestat_get`: `bool` -The right to invoke `fd_filestat_get`. - -Bit: 22 - -- `fd_filestat_set_size`: `bool` -The right to invoke `fd_filestat_set_size`. - -Bit: 23 - -- `fd_filestat_set_times`: `bool` -The right to invoke `fd_filestat_set_times`. - -Bit: 24 - -- `fd_permissions_set`: `bool` -The right to invoke `fd_permissions_set`. - -Bit: 25 - -- `path_symlink`: `bool` -The right to invoke `path_symlink`. - -Bit: 26 - -- `path_remove_directory`: `bool` -The right to invoke `path_remove_directory`. - -Bit: 27 - -- `path_unlink_file`: `bool` -The right to invoke `path_unlink_file`. - -Bit: 28 - -- `poll_fd_readwrite`: `bool` -If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). -If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). - -Bit: 29 - -- `sock_shutdown`: `bool` -The right to invoke `sock_shutdown`. - -Bit: 30 - -## `fd`: `Handle` -A file descriptor handle. - -Size: 4 - -Alignment: 4 - -### Supertypes -## `iovec`: `Record` -A region of memory for scatter/gather reads. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `Pointer` -The address of the buffer to be filled. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be filled. - -Offset: 4 - -## `ciovec`: `Record` -A region of memory for scatter/gather writes. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `ConstPointer` -The address of the buffer to be written. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be written. - -Offset: 4 - -## `iovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `ciovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `filedelta`: `s64` -Relative offset within a file. - -Size: 8 - -Alignment: 8 - -## `whence`: `Variant` -The position relative to which to set the offset of the file descriptor. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `set` -Seek relative to start-of-file. - -- `cur` -Seek relative to current position. - -- `end` -Seek relative to end-of-file. - -## `dircookie`: `u64` -A reference to the offset of a directory entry. - -Size: 8 - -Alignment: 8 - -### Constants -- `start` - -## `dirnamlen`: `u32` -The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). - -Size: 4 - -Alignment: 4 - -## `inode`: `u64` -File serial number that is unique within its file system. - -Size: 8 - -Alignment: 8 - -## `filetype`: `Variant` -The type of a file descriptor or file. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `unknown` -The type of the file descriptor or file is unknown or is different from any of the other types specified. - -- `block_device` -The file descriptor or file refers to a block device inode. - -- `character_device` -The file descriptor or file refers to a character device inode. - -- `directory` -The file descriptor or file refers to a directory inode. - -- `regular_file` -The file descriptor or file refers to a regular file inode. - -- `socket_dgram` -The file descriptor or file refers to a datagram socket. - -- `socket_stream` -The file descriptor or file refers to a byte-stream socket. - -- `symbolic_link` -The file refers to a symbolic link inode. - -- `fifo` -The file descriptor or file refers to a FIFO. - -## `dirent`: `Record` -A directory entry. - -Size: 24 - -Alignment: 8 - -### Record members -- `d_next`: [`dircookie`](#dircookie) -The offset of the next directory entry stored in this directory. - -Offset: 0 - -- `d_ino`: [`inode`](#inode) -The serial number of the file referred to by this directory entry. - -Offset: 8 - -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. - -Offset: 16 - -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. - -Offset: 20 - -## `advice`: `Variant` -File or memory access pattern advisory information. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `normal` -The application has no advice to give on its behavior with respect to the specified data. - -- `sequential` -The application expects to access the specified data sequentially from lower offsets to higher offsets. - -- `random` -The application expects to access the specified data in a random order. - -- `willneed` -The application expects to access the specified data in the near future. - -- `dontneed` -The application expects that it will not access the specified data in the near future. - -- `noreuse` -The application expects to access the specified data once and then not reuse it thereafter. - -## `fdflags`: `Record` -File descriptor flags. - -Size: 2 - -Alignment: 2 - -### Record members -- `append`: `bool` -Append mode: Data written to the file is always appended to the file's end. - -Bit: 0 - -- `dsync`: `bool` -Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - -Bit: 1 - -- `nonblock`: `bool` -Non-blocking mode. - -Bit: 2 - -- `rsync`: `bool` -Synchronized read I/O operations. - -Bit: 3 - -- `sync`: `bool` -Write according to synchronized I/O file integrity completion. In -addition to synchronizing the data stored in the file, the implementation -may also synchronously update the file's metadata. - -Bit: 4 - -## `fdstat`: `Record` -File descriptor attributes. - -Size: 24 - -Alignment: 8 - -### Record members -- `fs_filetype`: [`filetype`](#filetype) -File type. - -Offset: 0 - -- `fs_flags`: [`fdflags`](#fdflags) -File descriptor flags. - -Offset: 2 - -- `fs_rights_base`: [`rights`](#rights) -Rights that apply to this file descriptor. - -Offset: 8 - -- `fs_rights_inheriting`: [`rights`](#rights) -Maximum set of rights that may be installed on new file descriptors that -are created through this file descriptor, e.g., through `path_open`. - -Offset: 16 - -## `device`: `u64` -Identifier for a device containing a file system. Can be used in combination -with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. - -Size: 8 - -Alignment: 8 - -## `fstflags`: `Record` -Which file time attributes to adjust. - -Size: 2 - -Alignment: 2 - -### Record members -- `atim`: `bool` -Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - -Bit: 0 - -- `atim_now`: `bool` -Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 1 - -- `mtim`: `bool` -Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - -Bit: 2 - -- `mtim_now`: `bool` -Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 3 - -## `lookupflags`: `Record` -Flags determining the method of how paths are resolved. - -Size: 4 - -Alignment: 4 - -### Record members -- `symlink_follow`: `bool` -As long as the resolved path corresponds to a symbolic link, it is expanded. - -Bit: 0 - -## `oflags`: `Record` -Open flags used by `path_open`. - -Size: 2 - -Alignment: 2 - -### Record members -- `create`: `bool` -Create file if it does not exist. - -Bit: 0 - -- `directory`: `bool` -Fail if not a directory. - -Bit: 1 - -- `excl`: `bool` -Fail if file already exists. - -Bit: 2 - -- `trunc`: `bool` -Truncate file to size 0. - -Bit: 3 - -## `linkcount`: `u64` -Number of hard links to an inode. - -Size: 8 - -Alignment: 8 - -## `permissions`: `Record` -File permissions. This represents the permissions associated with a -file in a filesystem, and don't fully reflect all the conditions -which determine whether a given WASI program can access the file. - -Size: 1 - -Alignment: 1 - -### Record members -- `read`: `bool` -For files, permission to read the file. -For directories, permission to do `readdir` and access files -within the directory. - -Note: This is similar to the read bit being set on files, and the -read *and* execute bits being set on directories, in POSIX. - -Bit: 0 - -- `write`: `bool` -For files, permission to mutate the file. -For directories, permission to create, remove, and rename items -within the directory. - -Bit: 1 - -- `execute`: `bool` -For files, permission to "execute" the file, using whatever -concept of "executing" the host filesystem has. -This flag is not valid for directories. - -Bit: 2 - -- `private`: `bool` -For filesystems which have a concept of multiple "users", this flag -indicates that the file is only accessible by the effective "user" -that the WASI store uses to access the filesystem, and inaccessible -to other "users". - -Bit: 3 - -## `filestat`: `Record` -File attributes. - -Size: 64 - -Alignment: 8 - -### Record members -- `dev`: [`device`](#device) -Device ID of device containing the file. - -Offset: 0 - -- `ino`: [`inode`](#inode) -File serial number. - -Offset: 8 - -- `filetype`: [`filetype`](#filetype) -File type. - -Offset: 16 - -- `permissions`: [`permissions`](#permissions) -File permissions. - -Offset: 17 - -- `nlink`: [`linkcount`](#linkcount) -Number of hard links to the file. - -Offset: 24 - -- `size`: [`filesize`](#filesize) -For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - -Offset: 32 - -- `atim`: [`timestamp`](#timestamp) -Last data access timestamp. - -Offset: 40 - -- `mtim`: [`timestamp`](#timestamp) -Last data modification timestamp. - -Offset: 48 - -- `ctim`: [`timestamp`](#timestamp) -Last file status change timestamp. - -Offset: 56 - -## `userdata`: `u64` -User-provided value that may be attached to objects that is retained when -extracted from the implementation. - -Size: 8 - -Alignment: 8 - -## `eventtype`: `Variant` -Type of a subscription to an event or its occurrence. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `clock` -The time value of clock [`subscription_clock::id`](#subscription_clock.id) has -reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - -- `fd_read` -File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has data -available for reading. This event always triggers for regular files. - -- `fd_write` -File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity -available for writing. This event always triggers for regular files. - -## `eventrwflags`: `Record` -The state of the file descriptor subscribed to with -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 2 - -Alignment: 2 - -### Record members -- `fd_readwrite_hangup`: `bool` -The peer of this socket has closed or disconnected. - -Bit: 0 - -## `event_fd_readwrite`: `Record` -The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). - -Size: 16 - -Alignment: 8 - -### Record members -- `nbytes`: [`filesize`](#filesize) -The number of bytes available for reading or writing. - -Offset: 0 - -- `flags`: [`eventrwflags`](#eventrwflags) -The state of the file descriptor. - -Offset: 8 - -## `event_u`: `Variant` -The contents of an [`event`](#event). - -Size: 24 - -Alignment: 8 - -### Variant Layout -- size: 24 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock` - -- `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) - -- `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) - -## `event`: `Record` -An event that occurred. - -Size: 40 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). - -Offset: 0 - -- `error`: [`errno`](#errno) -If non-zero, an error that occurred while processing the subscription request. - -Offset: 8 - -- `u`: [`event_u`](#event_u) -The type of the event that occurred, and the contents of the event - -Offset: 16 - -## `subclockflags`: `Record` -Flags determining how to interpret the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout). - -Size: 2 - -Alignment: 2 - -### Record members -- `subscription_clock_abstime`: `bool` -If set, treat the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock -[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp -provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the -current time value of clock [`subscription_clock::id`](#subscription_clock.id). - -Bit: 0 - -## `subscription_clock`: `Record` -The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). - -Size: 32 - -Alignment: 8 - -### Record members -- `id`: [`clockid`](#clockid) -The clock against which to compare the timestamp. - -Offset: 0 - -- `timeout`: [`timestamp`](#timestamp) -The absolute or relative timestamp. - -Offset: 8 - -- `precision`: [`timestamp`](#timestamp) -The amount of time that the implementation may wait additionally -to coalesce with other events. - -Offset: 16 - -- `flags`: [`subclockflags`](#subclockflags) -Flags specifying whether the timeout is absolute or relative - -Offset: 24 - -## `subscription_fd_readwrite`: `Record` -The contents of a [`subscription`](#subscription) when type is type is -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 4 - -Alignment: 4 - -### Record members -- `fd`: [`fd`](#fd) -The file descriptor on which to wait for it to become ready for reading or writing. - -Offset: 0 - -## `subscription_u`: `Variant` -The contents of a [`subscription`](#subscription). - -Size: 40 - -Alignment: 8 - -### Variant Layout -- size: 40 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock`: [`subscription_clock`](#subscription_clock) - -- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -## `subscription`: `Record` -Subscription to an event. - -Size: 48 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that is attached to the subscription in the -implementation and returned through [`event::userdata`](#event.userdata). - -Offset: 0 - -- `u`: [`subscription_u`](#subscription_u) -The type of the event to which to subscribe, and the contents of the subscription. - -Offset: 8 - -## `exitcode`: `u8` -Exit code generated by a program when exiting. - -Size: 1 - -Alignment: 1 - -### Constants -- `success` - -- `failure` - -## `riflags`: `Record` -Flags provided to `sock_recv`. - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_peek`: `bool` -Returns the message without removing it from the socket's receive queue. - -Bit: 0 - -- `recv_waitall`: `bool` -On byte-stream sockets, block until the full amount of data can be returned. - -Bit: 1 - -## `roflags`: `Record` -Flags returned by `sock_recv`. - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_data_truncated`: `bool` -Returned by `sock_recv`: Message data has been truncated. - -Bit: 0 - -## `siflags`: `u16` -Flags provided to `sock_send`. As there are currently no flags -defined, it must be set to zero. - -Size: 2 - -Alignment: 2 - -## `sdflags`: `Record` -Which channels on a socket to shut down. - -Size: 1 - -Alignment: 1 - -### Record members -- `rd`: `bool` -Disables further receive operations. - -Bit: 0 - -- `wr`: `bool` -Disables further send operations. - -Bit: 1 - -## `preopentype`: `Variant` -Identifiers for preopened capabilities. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `dir` -A pre-opened directory. - -## `prestat_dir`: `Record` -The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). - -Size: 4 - -Alignment: 4 - -### Record members -- `pr_name_len`: [`size`](#size) -The length of the directory name for use with `fd_prestat_dir_name`. - -Offset: 0 - -## `prestat`: `Variant` -Information about a pre-opened capability. - -Size: 8 - -Alignment: 4 - -### Variant Layout -- size: 8 -- align: 4 -- tag_size: 1 -### Variant cases -- `dir`: [`prestat_dir`](#prestat_dir) -When type is [`preopentype::dir`](#preopentype.dir): - -# Modules -## wasi_ephemeral_clock -### Imports -#### Memory -### Functions - ---- - -#### `res_get(id: clockid) -> Result` -Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, -return [`errno::inval`](#errno.inval). -Note: This is similar to `clock_getres` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the resolution. - -##### Results -- `error`: `Result` -The resolution of the clock. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `time_get(id: clockid, precision: timestamp) -> Result` -Return the time value of a clock. -Note: This is similar to `clock_gettime` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the time. - -- `precision`: [`timestamp`](#timestamp) -The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - -##### Results -- `error`: `Result` -The time value of the clock. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - diff --git a/proposals/clocks/standard/wasi-clocks/witx/clocks.witx b/proposals/clocks/standard/wasi-clocks/witx/clocks.witx deleted file mode 100644 index a980529f8..000000000 --- a/proposals/clocks/standard/wasi-clocks/witx/clocks.witx +++ /dev/null @@ -1,35 +0,0 @@ -;; WASI Clocks. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_clock - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, - ;;; return `errno::inval`. - ;;; Note: This is similar to `clock_getres` in POSIX. - (@interface func (export "res_get") - ;;; The clock for which to return the resolution. - (param $id $clockid) - ;;; The resolution of the clock. - (result $error (expected $timestamp (error $errno))) - ) - - ;;; Return the time value of a clock. - ;;; Note: This is similar to `clock_gettime` in POSIX. - (@interface func (export "time_get") - ;;; The clock for which to return the time. - (param $id $clockid) - ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp) - ;;; The time value of the clock. - (result $error (expected $timestamp (error $errno))) - ) -) diff --git a/proposals/clocks/standard/wasi-clocks/witx/typenames.witx b/proposals/clocks/standard/wasi-clocks/witx/typenames.witx deleted file mode 100644 index bbd6489df..000000000 --- a/proposals/clocks/standard/wasi-clocks/witx/typenames.witx +++ /dev/null @@ -1,708 +0,0 @@ -;; Type names used by low-level WASI interfaces. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -;;; An array size. -;;; -;;; Note: This is similar to `size_t` in POSIX. -(typename $size (@witx usize)) - -;;; Non-negative file size or length of a region within a file. -(typename $filesize u64) - -;;; Timestamp in nanoseconds. -(typename $timestamp u64) - -;;; Identifiers for clocks. -(typename $clockid - (enum (@witx tag u32) - ;;; The clock measuring real time. Time value zero corresponds with - ;;; 1970-01-01T00:00:00Z. - $realtime - ;;; The store-wide monotonic clock, which is defined as a clock measuring - ;;; real time, whose value cannot be adjusted and which cannot have negative - ;;; clock jumps. The epoch of this clock is undefined. The absolute time - ;;; value of this clock therefore has no meaning. - $monotonic - ) -) - -;;; Error codes returned by functions. -;;; Not all of these error codes are returned by the functions provided by this -;;; API; some are used in higher-level library layers, and others are provided -;;; merely for alignment with POSIX. -(typename $errno - (enum (@witx tag u16) - ;;; No error occurred. System call completed successfully. - $success - ;;; Argument list too long. - $2big - ;;; Permission denied. - $access - ;;; Address in use. - $addrinuse - ;;; Address not available. - $addrnotavail - ;;; Address family not supported. - $afnosupport - ;;; Resource unavailable, or operation would block. - $again - ;;; Connection already in progress. - $already - ;;; Bad file descriptor. - $badf - ;;; Bad message. - $badmsg - ;;; Device or resource busy. - $busy - ;;; Operation canceled. - $canceled - ;;; No child processes. - $child - ;;; Connection aborted. - $connaborted - ;;; Connection refused. - $connrefused - ;;; Connection reset. - $connreset - ;;; Resource deadlock would occur. - $deadlk - ;;; Destination address required. - $destaddrreq - ;;; Mathematics argument out of domain of function. - $dom - ;;; Reserved. - $dquot - ;;; File exists. - $exist - ;;; Bad address. - $fault - ;;; File too large. - $fbig - ;;; Host is unreachable. - $hostunreach - ;;; Identifier removed. - $idrm - ;;; Illegal byte sequence. - $ilseq - ;;; Operation in progress. - $inprogress - ;;; Interrupted function. - $intr - ;;; Invalid argument. - $inval - ;;; I/O error. - $io - ;;; Socket is connected. - $isconn - ;;; Is a directory. - $isdir - ;;; Too many levels of symbolic links. - $loop - ;;; File descriptor value too large. - $mfile - ;;; Too many links. - $mlink - ;;; Message too large. - $msgsize - ;;; Reserved. - $multihop - ;;; Filename too long. - $nametoolong - ;;; Network is down. - $netdown - ;;; Connection aborted by network. - $netreset - ;;; Network unreachable. - $netunreach - ;;; Too many files open in system. - $nfile - ;;; No buffer space available. - $nobufs - ;;; No such device. - $nodev - ;;; No such file or directory. - $noent - ;;; Executable file format error. - $noexec - ;;; No locks available. - $nolck - ;;; Reserved. - $nolink - ;;; Not enough space. - $nomem - ;;; No message of the desired type. - $nomsg - ;;; Protocol not available. - $noprotoopt - ;;; No space left on device. - $nospc - ;;; Function not supported. - $nosys - ;;; The socket is not connected. - $notconn - ;;; Not a directory or a symbolic link to a directory. - $notdir - ;;; Directory not empty. - $notempty - ;;; State not recoverable. - $notrecoverable - ;;; Not a socket. - $notsock - ;;; Not supported, or operation not supported on socket. - $notsup - ;;; Inappropriate I/O control operation. - $notty - ;;; No such device or address. - $nxio - ;;; Value too large to be stored in data type. - $overflow - ;;; Previous owner died. - $ownerdead - ;;; Operation not permitted. - $perm - ;;; Broken pipe. - $pipe - ;;; Protocol error. - $proto - ;;; Protocol not supported. - $protonosupport - ;;; Protocol wrong type for socket. - $prototype - ;;; Result too large. - $range - ;;; Read-only file system. - $rofs - ;;; Invalid seek. - $spipe - ;;; No such process. - $srch - ;;; Reserved. - $stale - ;;; Connection timed out. - $timedout - ;;; Text file busy. - $txtbsy - ;;; Cross-device link. - $xdev - ;;; Extension: Capabilities insufficient. - $notcapable - ) -) - -;;; File descriptor rights, determining which actions may be performed. -(typename $rights - (flags (@witx repr u64) - ;;; The right to invoke `fd_datasync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::dsync`. - $fd_datasync - ;;; The right to invoke `fd_read` and `sock_recv`. - ;; - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. - $fd_read - ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. - $fd_seek - ;;; The right to invoke `fd_fdstat_set_flags`. - $fd_fdstat_set_flags - ;;; The right to invoke `fd_sync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. - $fd_sync - ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to - ;;; invoke `fd_tell`. - $fd_tell - ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. - $fd_write - ;;; The right to invoke `fd_advise`. - $fd_advise - ;;; The right to invoke `fd_allocate`. - $fd_allocate - ;;; The right to invoke `path_create_directory`. - $path_create_directory - ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::create`. - $path_create_file - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; source directory. - $path_link_source - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; target directory. - $path_link_target - ;;; The right to invoke `path_open`. - $path_open - ;;; The right to invoke `fd_readdir`. - $fd_readdir - ;;; The right to invoke `path_readlink`. - $path_readlink - ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $path_rename_source - ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $path_rename_target - ;;; The right to invoke `path_filestat_get`. - $path_filestat_get - ;;; The right to change a file's size. - ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. - ;;; Note: there is no function named `path_filestat_set_size`. This follows POSIX design, - ;;; which only has `ftruncate` and does not provide `ftruncateat`. - ;;; While such function would be desirable from the API design perspective, there are virtually - ;;; no use cases for it since no code written for POSIX systems would use it. - ;;; Moreover, implementing it would require multiple syscalls, leading to inferior performance. - $path_filestat_set_size - ;;; The right to invoke `path_filestat_set_times`. - $path_filestat_set_times - ;;; The right to invoke `path_permissions_set`. - $path_permissions_set - ;;; The right to invoke `fd_filestat_get`. - $fd_filestat_get - ;;; The right to invoke `fd_filestat_set_size`. - $fd_filestat_set_size - ;;; The right to invoke `fd_filestat_set_times`. - $fd_filestat_set_times - ;;; The right to invoke `fd_permissions_set`. - $fd_permissions_set - ;;; The right to invoke `path_symlink`. - $path_symlink - ;;; The right to invoke `path_remove_directory`. - $path_remove_directory - ;;; The right to invoke `path_unlink_file`. - $path_unlink_file - ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. - ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. - $poll_fd_readwrite - ;;; The right to invoke `sock_shutdown`. - $sock_shutdown - ) -) - -;;; A file descriptor handle. -(typename $fd (handle)) - -;;; A region of memory for scatter/gather reads. -(typename $iovec - (record - ;;; The address of the buffer to be filled. - (field $buf (@witx pointer u8)) - ;;; The length of the buffer to be filled. - (field $buf_len $size) - ) -) - -;;; A region of memory for scatter/gather writes. -(typename $ciovec - (record - ;;; The address of the buffer to be written. - (field $buf (@witx const_pointer u8)) - ;;; The length of the buffer to be written. - (field $buf_len $size) - ) -) - -(typename $iovec_array (list $iovec)) -(typename $ciovec_array (list $ciovec)) - -;;; Relative offset within a file. -(typename $filedelta s64) - -;;; The position relative to which to set the offset of the file descriptor. -(typename $whence - (enum (@witx tag u8) - ;;; Seek relative to start-of-file. - $set - ;;; Seek relative to current position. - $cur - ;;; Seek relative to end-of-file. - $end - ) -) - -;;; A reference to the offset of a directory entry. -(typename $dircookie u64) - -;;; In an `fd_readdir` call, this value signifies the start of the directory. -(@witx const $dircookie $start 0) - -;;; The type for the `dirent::d_namlen` field of `dirent`. -(typename $dirnamlen u32) - -;;; File serial number that is unique within its file system. -(typename $inode u64) - -;;; The type of a file descriptor or file. -(typename $filetype - (enum (@witx tag u8) - ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $unknown - ;;; The file descriptor or file refers to a block device inode. - $block_device - ;;; The file descriptor or file refers to a character device inode. - $character_device - ;;; The file descriptor or file refers to a directory inode. - $directory - ;;; The file descriptor or file refers to a regular file inode. - $regular_file - ;;; The file descriptor or file refers to a datagram socket. - $socket_dgram - ;;; The file descriptor or file refers to a byte-stream socket. - $socket_stream - ;;; The file refers to a symbolic link inode. - $symbolic_link - ;;; The file descriptor or file refers to a FIFO. - $fifo - ) -) - -;;; A directory entry. -(typename $dirent - (record - ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie) - ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode) - ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) - ) -) - -;;; File or memory access pattern advisory information. -(typename $advice - (enum (@witx tag u8) - ;;; The application has no advice to give on its behavior with respect to the specified data. - $normal - ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $sequential - ;;; The application expects to access the specified data in a random order. - $random - ;;; The application expects to access the specified data in the near future. - $willneed - ;;; The application expects that it will not access the specified data in the near future. - $dontneed - ;;; The application expects to access the specified data once and then not reuse it thereafter. - $noreuse - ) -) - -;;; File descriptor flags. -(typename $fdflags - (flags (@witx repr u16) - ;;; Append mode: Data written to the file is always appended to the file's end. - $append - ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $dsync - ;;; Non-blocking mode. - $nonblock - ;;; Synchronized read I/O operations. - $rsync - ;;; Write according to synchronized I/O file integrity completion. In - ;;; addition to synchronizing the data stored in the file, the implementation - ;;; may also synchronously update the file's metadata. - $sync - ) -) - -;;; File descriptor attributes. -(typename $fdstat - (record - ;;; File type. - (field $fs_filetype $filetype) - ;;; File descriptor flags. - (field $fs_flags $fdflags) - ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights) - ;;; Maximum set of rights that may be installed on new file descriptors that - ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights) - ) -) - -;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode` to uniquely identify a file or directory in the filesystem. -(typename $device u64) - -;;; Which file time attributes to adjust. -(typename $fstflags - (flags (@witx repr u16) - ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. - $atim - ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. - $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. - $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. - $mtim_now - ) -) - -;;; Flags determining the method of how paths are resolved. -(typename $lookupflags - (flags (@witx repr u32) - ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $symlink_follow - ) -) - -;;; Open flags used by `path_open`. -(typename $oflags - (flags (@witx repr u16) - ;;; Create file if it does not exist. - $create - ;;; Fail if not a directory. - $directory - ;;; Fail if file already exists. - $excl - ;;; Truncate file to size 0. - $trunc - ) -) - -;;; Number of hard links to an inode. -(typename $linkcount u64) - -;;; File permissions. This represents the permissions associated with a -;;; file in a filesystem, and don't fully reflect all the conditions -;;; which determine whether a given WASI program can access the file. -(typename $permissions - (flags (@witx repr u8) - ;;; For files, permission to read the file. - ;;; For directories, permission to do `readdir` and access files - ;;; within the directory. - ;;; - ;;; Note: This is similar to the read bit being set on files, and the - ;;; read *and* execute bits being set on directories, in POSIX. - $read - - ;;; For files, permission to mutate the file. - ;;; For directories, permission to create, remove, and rename items - ;;; within the directory. - $write - - ;;; For files, permission to "execute" the file, using whatever - ;;; concept of "executing" the host filesystem has. - ;;; This flag is not valid for directories. - $execute - - ;;; For filesystems which have a concept of multiple "users", this flag - ;;; indicates that the file is only accessible by the effective "user" - ;;; that the WASI store uses to access the filesystem, and inaccessible - ;;; to other "users". - $private - ) -) - -;;; File attributes. -(typename $filestat - (record - ;;; Device ID of device containing the file. - (field $dev $device) - ;;; File serial number. - (field $ino $inode) - ;;; File type. - (field $filetype $filetype) - ;;; File permissions. - (field $permissions $permissions) - ;;; Number of hard links to the file. - (field $nlink $linkcount) - ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $size $filesize) - ;;; Last data access timestamp. - (field $atim $timestamp) - ;;; Last data modification timestamp. - (field $mtim $timestamp) - ;;; Last file status change timestamp. - (field $ctim $timestamp) - ) -) - -;;; User-provided value that may be attached to objects that is retained when -;;; extracted from the implementation. -(typename $userdata u64) - -;;; Type of a subscription to an event or its occurrence. -(typename $eventtype - (enum (@witx tag u8) - ;;; The time value of clock `subscription_clock::id` has - ;;; reached timestamp `subscription_clock::timeout`. - $clock - ;;; File descriptor `subscription_fd_readwrite::fd` has data - ;;; available for reading. This event always triggers for regular files. - $fd_read - ;;; File descriptor `subscription_fd_readwrite::fd` has capacity - ;;; available for writing. This event always triggers for regular files. - $fd_write - ) -) - -;;; The state of the file descriptor subscribed to with -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $eventrwflags - (flags (@witx repr u16) - ;;; The peer of this socket has closed or disconnected. - $fd_readwrite_hangup - ) -) - -;;; The contents of an `event` when type is `eventtype::fd_read` or -;;; `eventtype::fd_write`. -(typename $event_fd_readwrite - (record - ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize) - ;;; The state of the file descriptor. - (field $flags $eventrwflags) - ) -) - -;;; The contents of an `event`. -(typename $event_u - (variant (@witx tag $eventtype) - (case $fd_read $event_fd_readwrite) - (case $fd_write $event_fd_readwrite) - (case $clock) - ) -) - -;;; An event that occurred. -(typename $event - (record - ;;; User-provided value that got attached to `subscription::userdata`. - (field $userdata $userdata) - ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno) - ;;; The type of the event that occurred, and the contents of the event - (field $u $event_u) - ) -) - -;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_clock::timeout`. -(typename $subclockflags - (flags (@witx repr u16) - ;;; If set, treat the timestamp provided in - ;;; `subscription_clock::timeout` as an absolute timestamp of clock - ;;; `subscription_clock::id`. If clear, treat the timestamp - ;;; provided in `subscription_clock::timeout` relative to the - ;;; current time value of clock `subscription_clock::id`. - $subscription_clock_abstime - ) -) - -;;; The contents of a `subscription` when type is `eventtype::clock`. -(typename $subscription_clock - (record - ;;; The clock against which to compare the timestamp. - (field $id $clockid) - ;;; The absolute or relative timestamp. - (field $timeout $timestamp) - ;;; The amount of time that the implementation may wait additionally - ;;; to coalesce with other events. - (field $precision $timestamp) - ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags) - ) -) - -;;; The contents of a `subscription` when type is type is -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $subscription_fd_readwrite - (record - ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $fd $fd) - ) -) - -;;; The contents of a `subscription`. -(typename $subscription_u - (union (@witx tag $eventtype) - $subscription_clock - $subscription_fd_readwrite - $subscription_fd_readwrite - ) -) - -;;; Subscription to an event. -(typename $subscription - (record - ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event::userdata`. - (field $userdata $userdata) - ;;; The type of the event to which to subscribe, and the contents of the subscription. - (field $u $subscription_u) - ) -) - -;;; Exit code generated by a program when exiting. -(typename $exitcode u8) - -;;; Indicate the program exited successfully. -;;; -;;; Note: This is similar to `EXIT_SUCCESS` in POSIX. -(@witx const $exitcode $success 0) - -;;; Indicate the program exited unsuccessfully. -;;; -;;; Note: This is similar to `EXIT_FAILURE` in POSIX. -(@witx const $exitcode $failure 1) - -;;; Flags provided to `sock_recv`. -(typename $riflags - (flags (@witx repr u16) - ;;; Returns the message without removing it from the socket's receive queue. - $recv_peek - ;;; On byte-stream sockets, block until the full amount of data can be returned. - $recv_waitall - ) -) - -;;; Flags returned by `sock_recv`. -(typename $roflags - (flags (@witx repr u16) - ;;; Returned by `sock_recv`: Message data has been truncated. - $recv_data_truncated - ) -) - -;;; Flags provided to `sock_send`. As there are currently no flags -;;; defined, it must be set to zero. -(typename $siflags u16) - -;;; Which channels on a socket to shut down. -(typename $sdflags - (flags (@witx repr u8) - ;;; Disables further receive operations. - $rd - ;;; Disables further send operations. - $wr - ) -) - -;;; Identifiers for preopened capabilities. -(typename $preopentype - (enum (@witx tag u8) - ;;; A pre-opened directory. - $dir - ) -) - -;;; The contents of a `prestat` when its type is `preopentype::dir`. -(typename $prestat_dir - (record - ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size) - ) -) - -;;; Information about a pre-opened capability. -(typename $prestat - (union (@witx tag $preopentype) - ;;; When type is `preopentype::dir`: - $prestat_dir - ) -) diff --git a/proposals/clocks/test/README.md b/proposals/clocks/test/README.md new file mode 100644 index 000000000..c274acd9d --- /dev/null +++ b/proposals/clocks/test/README.md @@ -0,0 +1,11 @@ +# Testing guidelines + +TK fill in testing guidelines + +## Installing the tools + +TK fill in instructions + +## Running the tests + +TK fill in instructions diff --git a/proposals/clocks/tools/repo_docs.sh b/proposals/clocks/tools/repo_docs.sh deleted file mode 100755 index 76d1462bc..000000000 --- a/proposals/clocks/tools/repo_docs.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -set -ex -cd $(dirname $(realpath $0))/witx -cargo run -p witx-cli -- docs $1 ../../phases/snapshot/witx/wasi_snapshot_preview1.witx --output ../../phases/snapshot/docs.md -cargo run -p witx-cli -- docs $1 ../../phases/old/snapshot_0/witx/wasi_unstable.witx --output ../../phases/old/snapshot_0/docs.md -cargo run -p witx-cli -- docs $1 \ - ../../phases/ephemeral/witx/wasi_ephemeral_args.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_clock.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_environ.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_fd.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_path.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_poll.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_proc.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_random.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_sched.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_sock.witx \ - --output ../../phases/ephemeral/docs.md - -for dir in ../../standard/*/witx; do - cargo run -p witx-cli -- docs $1 "$dir"/*.witx \ - --output "$dir"/../docs.md -done diff --git a/proposals/clocks/tools/witx/.gitignore b/proposals/clocks/tools/witx/.gitignore deleted file mode 100644 index a9d37c560..000000000 --- a/proposals/clocks/tools/witx/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target -Cargo.lock diff --git a/proposals/clocks/tools/witx/Cargo.toml b/proposals/clocks/tools/witx/Cargo.toml deleted file mode 100644 index 1dd39a8b1..000000000 --- a/proposals/clocks/tools/witx/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -[package] -name = "witx" -version = "0.9.0" -description = "Parse and validate witx file format" -homepage = "https://github.com/WebAssembly/WASI" -repository = "https://github.com/WebAssembly/WASI" -license = "Apache-2.0" -categories = ["wasm"] -keywords = ["webassembly", "wasm"] -authors = ["Pat Hickey ", "Alex Crichton "] -edition = "2018" - -[lib] -crate-type=["rlib"] - -[dependencies] -anyhow = "1" -log = "0.4" -thiserror = "1.0" -wast = { version = "33.0.0", default-features = false } - -[dev-dependencies] -rayon = "1.0" - -[[test]] -name = "witxt" -harness = false - -[workspace] -members = [ - "cli", -] diff --git a/proposals/clocks/tools/witx/LICENSE b/proposals/clocks/tools/witx/LICENSE deleted file mode 100644 index e061f56ab..000000000 --- a/proposals/clocks/tools/witx/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2019 WebAssembly Community Group participants - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/proposals/clocks/tools/witx/cli/Cargo.toml b/proposals/clocks/tools/witx/cli/Cargo.toml deleted file mode 100644 index 6f45ef3d9..000000000 --- a/proposals/clocks/tools/witx/cli/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "witx-cli" -version = "0.9.0" -description = "CLI for operating on witx file format" -homepage = "https://github.com/WebAssembly/WASI" -repository = "https://github.com/WebAssembly/WASI" -license = "Apache-2.0" -categories = ["wasm"] -keywords = ["webassembly", "wasm"] -authors = ["Pat Hickey ", "Alex Crichton "] -edition = "2018" - -[[bin]] -name = "witx" -path = "src/main.rs" - -[dependencies] -witx = { path = "../", version = "0.9.0" } -anyhow = "1" -log = "0.4" -thiserror = "1.0" -diff = "0.1.11" -pretty_env_logger = "0.4" -structopt = "0.3" -rayon = "1.0" diff --git a/proposals/clocks/tools/witx/cli/src/main.rs b/proposals/clocks/tools/witx/cli/src/main.rs deleted file mode 100644 index bdb1c6a9c..000000000 --- a/proposals/clocks/tools/witx/cli/src/main.rs +++ /dev/null @@ -1,268 +0,0 @@ -use anyhow::{anyhow, bail, Result}; -use std::fs::File; -use std::io::Write; -use std::path::{Path, PathBuf}; -use std::process; -use structopt::{clap::AppSettings, StructOpt}; -use witx::{load, Document, Documentation}; - -/// Validate and process witx files -#[derive(StructOpt, Debug)] -#[structopt( - name = "witx", - version = env!("CARGO_PKG_VERSION"), - global_settings = &[ - AppSettings::VersionlessSubcommands, - AppSettings::ColoredHelp - ] -)] -struct Args { - #[structopt(short = "v", long = "verbose")] - verbose: bool, - - #[structopt(subcommand)] - cmd: Command, -} - -#[derive(StructOpt, Debug)] -enum Command { - /// Output documentation - Docs { - /// Path to root of witx document - #[structopt(number_of_values = 1, value_name = "INPUT", parse(from_os_str))] - input: Vec, - /// Perform check that output matches witx documents - #[structopt(long = "check")] - check: bool, - /// Path to generated documentation in Markdown format - #[structopt( - short = "o", - long = "output", - value_name = "OUTPUT", - parse(from_os_str) - )] - output: Option, - }, - /// Examine differences between interfaces - Polyfill { - /// Path to root of witx document - #[structopt( - required = true, - number_of_values = 1, - value_name = "INPUT", - parse(from_os_str) - )] - input: Vec, - /// Path to root of witx document describing interface to polyfill - #[structopt( - required = true, - number_of_values = 1, - value_name = "OLDER_INTERFACE", - parse(from_os_str) - )] - older_interface: Vec, - /// Module to examine (use newname=oldname syntax if name is different - /// between new and old interfaces) - #[structopt( - short = "m", - long = "module_mapping", - required = true, - number_of_values = 1, - value_name = "NEWNAME=OLDNAME", - parse(try_from_str = parse_module_mapping) - )] - module_mapping: Vec<(String, String)>, - }, -} - -pub fn main() { - let args = Args::from_args(); - pretty_env_logger::init(); - let verbose = args.verbose; - - match args.cmd { - Command::Docs { - input, - check, - output, - } => { - let doc = load_witx(&input, "input", verbose); - if check { - let output = output.expect("output argument required in docs --check mode"); - if diff_against_filesystem(&doc.to_md(), &output).is_err() { - println!("Docs in tree are out-of-date with witx files. Re-run this executable with the following arguments to to re-generate:"); - println!( - "> witx docs {} --output {}", - input - .iter() - .map(|p| p.to_string_lossy().into_owned()) - .collect::>() - .join(" "), - output.to_string_lossy(), - ); - } - } else { - if let Some(output) = output { - write_docs(&doc, output) - } else { - println!("{}", doc.to_md()) - } - } - } - Command::Polyfill { - input, - older_interface, - module_mapping, - } => { - use std::{collections::HashMap, iter::FromIterator}; - use witx::polyfill::Polyfill; - - let doc = load_witx(&input, "input", verbose); - let older_doc = load_witx(&older_interface, "older_interface", verbose); - let module_mapping = HashMap::from_iter(module_mapping.into_iter()); - let polyfill = match Polyfill::new(&doc, &older_doc, &module_mapping) { - Ok(polyfill) => polyfill, - Err(e) => { - eprintln!("couldn't calculate polyfill"); - if verbose { - println!("{:?}", e); - } - process::exit(1); - } - }; - println!("{}", polyfill.to_md()); - if verbose { - println!("{:?}", polyfill); - } - } - } -} - -fn load_witx(input: &[PathBuf], field_name: &str, verbose: bool) -> Document { - match load(input) { - Ok(doc) => { - if verbose { - println!("{}: {:?}", field_name, doc); - } - doc - } - Err(e) => { - eprintln!("{}", e.report()); - if verbose { - println!("{:?}", e); - } - process::exit(1) - } - } -} - -fn write_docs>(document: &Document, path: P) { - let mut file = File::create(path.as_ref()).expect("create output file"); - file.write_all(document.to_md().as_bytes()) - .expect("write output file"); -} - -fn parse_module_mapping(m: &str) -> Result<(String, String)> { - let s: Vec<_> = m.split('=').collect(); - let (n, o) = match s.len() { - 1 => { - let mname = s - .get(0) - .ok_or(anyhow!("module name cannot be an empty string"))?; - (mname, mname) - } - 2 => { - let newname = s - .get(0) - .ok_or(anyhow!("new module name cannot be an empty string"))?; - let oldname = s - .get(1) - .ok_or(anyhow!("old module name cannot be an empty string"))?; - (newname, oldname) - } - _ => bail!("invalid module mapping: '{}'", m), - }; - Ok((n.to_string(), o.to_string())) -} - -fn dos2unix(s: &str) -> String { - let mut t = String::new(); - t.reserve(s.len()); - for c in s.chars() { - if c != '\r' { - t.push(c) - } - } - t -} - -fn diff_against_filesystem(expected: &str, path: &Path) -> Result<(), ()> { - let actual = std::fs::read_to_string(path) - .unwrap_or_else(|e| panic!("couldn't read {}: {:?}", Path::display(path), e)); - // Git may checkout the file with dos line endings on windows. Strip all \r: - let actual = dos2unix(&actual); - if &actual == expected { - return Ok(()); - } - - eprintln!("The following diff was found between the docs generated from .witx and the"); - eprintln!("source {:?} in the tree:", path); - eprintln!(); - - let mut expected_line = 1; - let mut actual_line = 1; - let mut separated = false; - let mut any_lines = false; - for diff in diff::lines(&expected, &actual) { - match diff { - diff::Result::Left(l) => { - eprintln!("line {}: -{}", expected_line, l); - expected_line += 1; - separated = false; - any_lines = true; - } - diff::Result::Both(_, _) => { - expected_line += 1; - actual_line += 1; - if !separated { - eprintln!("..."); - separated = true; - } - } - diff::Result::Right(r) => { - eprintln!("line {}: +{}", actual_line, r); - actual_line += 1; - separated = false; - any_lines = true; - } - } - } - - if !any_lines { - eprintln!(); - eprintln!( - "Somehow there was a diff with no lines differing. Lengths: {} and {}.", - expected.len(), - actual.len() - ); - for (index, (a, b)) in actual.chars().zip(expected.chars()).enumerate() { - if a != b { - eprintln!("char difference at index {}: '{}' != '{}'", index, a, b); - } - } - for (index, (a, b)) in actual.bytes().zip(expected.bytes()).enumerate() { - if a != b { - eprintln!("byte difference at index {}: b'{}' != b'{}'", index, a, b); - } - } - eprintln!(); - eprintln!("actual: {}", actual); - eprintln!(); - eprintln!("expected: {}", expected); - } - - eprintln!(); - eprintln!("To regenerate the files, run `tools/repo_docs.sh`."); - eprintln!(); - Err(()) -} diff --git a/proposals/clocks/tools/witx/src/abi.rs b/proposals/clocks/tools/witx/src/abi.rs deleted file mode 100644 index 0e1ca9cb4..000000000 --- a/proposals/clocks/tools/witx/src/abi.rs +++ /dev/null @@ -1,925 +0,0 @@ -//! Definition of the ABI of witx functions -//! -//! This module is intended to assist with code generators which are binding or -//! implementing APIs defined by `*.witx` files. THis module contains all -//! details necessary to implement the actual ABI of these functions so wasm -//! modules and hosts can communicate with one another. -//! -//! Each interface types function (a function defined in `*.witx`) currently has -//! a well-known wasm signature associated with it. There's then also a standard -//! way to convert from interface-types values (whose representation is defined -//! per-language) into this wasm API. This module is intended to assist with -//! this definition. -//! -//! Contained within are two primary functions, [`InterfaceFunc::call_wasm`] and -//! [`InterfaceFunc::call_interface`]. These functions implement the two ways to -//! interact with an interface types function, namely calling the raw wasm -//! version and calling the high-level version with interface types. These two -//! functions are fed a structure that implements [`Bindgen`]. An instance of -//! [`Bindgen`] receives instructions which are low-level implementation details -//! of how to convert to and from wasm types and interface types. Code -//! generators will need to implement the various instructions to support APIs. - -use crate::{ - BuiltinType, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, NamedType, Type, TypeRef, -}; - -/// Enumerates wasm types used by interface types when lowering/lifting. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum WasmType { - I32, - I64, - F32, - F64, - // NOTE: we don't lower interface types to any other Wasm type, - // e.g. externref, so we don't need to define them here. -} - -impl From for WasmType { - fn from(i: IntRepr) -> WasmType { - match i { - IntRepr::U8 | IntRepr::U16 | IntRepr::U32 => WasmType::I32, - IntRepr::U64 => WasmType::I64, - } - } -} - -/// Possible ABIs for interface functions to have. -/// -/// Note that this is a stopgap until we have more of interface types. Interface -/// types functions do not have ABIs, they have APIs. For the meantime, however, -/// we mandate ABIs to ensure we can all talk to each other. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum Abi { - /// Only stable ABI currently, and is the historical WASI ABI since it was - /// first created. - /// - /// Note that this ABI is limited notably in its return values where it can - /// only return 0 results or one `Result` lookalike. - Preview1, -} - -// Helper macro for defining instructions without having to have tons of -// exhaustive `match` statements to update -macro_rules! def_instruction { - ( - $( #[$enum_attr:meta] )* - pub enum Instruction<'a> { - $( - $( #[$attr:meta] )* - $variant:ident $( { - $($field:ident : $field_ty:ty $(,)* )* - } )? - : - [$num_popped:expr] => [$num_pushed:expr], - )* - } - ) => { - $( #[$enum_attr] )* - pub enum Instruction<'a> { - $( - $( #[$attr] )* - $variant $( { - $( - $field : $field_ty, - )* - } )? , - )* - } - - impl Instruction<'_> { - /// How many operands does this instruction pop from the stack? - #[allow(unused_variables)] - pub fn operands_len(&self) -> usize { - match self { - $( - Self::$variant $( { - $( - $field, - )* - } )? => $num_popped, - )* - } - } - - /// How many results does this instruction push onto the stack? - #[allow(unused_variables)] - pub fn results_len(&self) -> usize { - match self { - $( - Self::$variant $( { - $( - $field, - )* - } )? => $num_pushed, - )* - } - } - } - }; -} - -def_instruction! { - #[derive(Debug)] - pub enum Instruction<'a> { - /// Acquires the specified parameter and places it on the stack. - /// Depending on the context this may refer to wasm parameters or - /// interface types parameters. - GetArg { nth: usize } : [0] => [1], - /// Takes the value off the top of the stack and writes it into linear - /// memory. Pushes the address in linear memory as an `i32`. - AddrOf : [1] => [1], - /// Converts an interface type `char` value to a 32-bit integer - /// representing the unicode scalar value. - I32FromChar : [1] => [1], - /// Converts an interface type `u64` value to a wasm `i64`. - I64FromU64 : [1] => [1], - /// Converts an interface type `s64` value to a wasm `i64`. - I64FromS64 : [1] => [1], - /// Converts an interface type `u32` value to a wasm `i32`. - I32FromU32 : [1] => [1], - /// Converts an interface type `s32` value to a wasm `i32`. - I32FromS32 : [1] => [1], - /// Converts a language-specific `usize` value to a wasm `i32`. - I32FromUsize : [1] => [1], - /// Converts an interface type `u16` value to a wasm `i32`. - I32FromU16 : [1] => [1], - /// Converts an interface type `s16` value to a wasm `i32`. - I32FromS16 : [1] => [1], - /// Converts an interface type `u8` value to a wasm `i32`. - I32FromU8 : [1] => [1], - /// Converts an interface type `s8` value to a wasm `i32`. - I32FromS8 : [1] => [1], - /// Converts a language-specific C `char` value to a wasm `i32`. - I32FromChar8 : [1] => [1], - /// Converts a language-specific pointer value to a wasm `i32`. - I32FromPointer : [1] => [1], - /// Converts a language-specific pointer value to a wasm `i32`. - I32FromConstPointer : [1] => [1], - /// Converts a language-specific handle value to a wasm `i32`. - I32FromHandle { ty: &'a NamedType } : [1] => [1], - /// Converts a language-specific record-of-bools to the packed - /// representation as an `i32`. - I32FromBitflags { ty: &'a NamedType } : [1] => [1], - /// Converts a language-specific record-of-bools to the packed - /// representation as an `i64`. - I64FromBitflags { ty: &'a NamedType } : [1] => [1], - /// Converts an interface type list into its pointer/length, pushing - /// them both on the stack. - ListPointerLength : [1] => [2], - /// Pops two `i32` values from the stack and creates a list from them of - /// the specified type. The first operand is the pointer in linear - /// memory to the start of the list and the second operand is the - /// length. - ListFromPointerLength { ty: &'a TypeRef } : [2] => [1], - /// Conversion an interface type `f32` value to a wasm `f32`. - /// - /// This may be a noop for some implementations, but it's here in case the - /// native language representation of `f32` is different than the wasm - /// representation of `f32`. - F32FromIf32 : [1] => [1], - /// Conversion an interface type `f64` value to a wasm `f64`. - /// - /// This may be a noop for some implementations, but it's here in case the - /// native language representation of `f64` is different than the wasm - /// representation of `f64`. - F64FromIf64 : [1] => [1], - - /// Represents a call to a raw WebAssembly API. The module/name are - /// provided inline as well as the types if necessary. - CallWasm { - module: &'a str, - name: &'a str, - params: &'a [WasmType], - results: &'a [WasmType], - } : [params.len()] => [results.len()], - - /// Same as `CallWasm`, except the dual where an interface is being - /// called rather than a raw wasm function. - CallInterface { - module: &'a str, - func: &'a InterfaceFunc, - } : [func.params.len()] => [func.results.len()], - - /// Converts a native wasm `i32` to an interface type `s8`. - /// - /// This will truncate the upper bits of the `i32`. - S8FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `u8`. - /// - /// This will truncate the upper bits of the `i32`. - U8FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `s16`. - /// - /// This will truncate the upper bits of the `i32`. - S16FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `u16`. - /// - /// This will truncate the upper bits of the `i32`. - U16FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `s32`. - S32FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `u32`. - U32FromI32 : [1] => [1], - /// Converts a native wasm `i64` to an interface type `s64`. - S64FromI64 : [1] => [1], - /// Converts a native wasm `i64` to an interface type `u64`. - U64FromI64 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `char`. - /// - /// It's safe to assume that the `i32` is indeed a valid unicode code point. - CharFromI32 : [1] => [1], - /// Converts a native wasm `i32` to a language-specific C `char`. - /// - /// This will truncate the upper bits of the `i32`. - Char8FromI32 : [1] => [1], - /// Converts a native wasm `i32` to a language-specific `usize`. - UsizeFromI32 : [1] => [1], - /// Converts a native wasm `f32` to an interface type `f32`. - If32FromF32 : [1] => [1], - /// Converts a native wasm `f64` to an interface type `f64`. - If64FromF64 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `handle`. - HandleFromI32 { ty: &'a NamedType } : [1] => [1], - /// Converts a native wasm `i32` to a language-specific pointer. - PointerFromI32 { ty: &'a TypeRef }: [1] => [1], - /// Converts a native wasm `i32` to a language-specific pointer. - ConstPointerFromI32 { ty: &'a TypeRef } : [1] => [1], - /// Converts a native wasm `i32` to a language-specific record-of-bools. - BitflagsFromI32 { ty: &'a NamedType } : [1] => [1], - /// Converts a native wasm `i64` to a language-specific record-of-bools. - BitflagsFromI64 { ty: &'a NamedType } : [1] => [1], - /// Acquires the return pointer `n` and pushes an `i32` on the stack. - /// - /// Implementations of [`Bindgen`] may have [`Bindgen::allocate_space`] - /// called to reserve space in memory for the result of a computation to - /// get written. This instruction acquires a pointer to the space - /// reserved in `allocate_space`. - ReturnPointerGet { n: usize } : [0] => [1], - /// Loads the interface types value from an `i32` pointer popped from - /// the stack. - Load { ty: &'a NamedType } : [1] => [1], - /// Stores an interface types value into linear memory. The first - /// operand is the value to store and the second operand is the pointer - /// in linear memory to store it at. - Store { ty: &'a NamedType } : [2] => [0], - /// Pops a native wasm `i32` from the stack, as well as two blocks - /// internally from the code generator. - /// - /// If the value is 0 then the first "ok" block value should be used. - /// If the value is anything else then the second "err" block value - /// should be used, and the value is used as the error enum. - /// - /// Note that this is a special instruction matching the current ABI of - /// WASI and intentionally differs from the type-level grammar of - /// interface types results. - ResultLift : [1] => [1], - /// Pops a native interface value from the stack as well as two blocks - /// internally from the code generator. - /// - /// A `match` is performed on the value popped and the corresponding - /// block for ok/err is used depending on value. This pushes a single - /// `i32` onto the stack representing the error code for this result. - /// - /// Note that like `ResultLift` this is specialized to the current WASI - /// ABI. - ResultLower { - ok: Option<&'a TypeRef>, - err: Option<&'a TypeRef>, - } : [1] => [1], - /// Converts a native wasm `i32` to an interface type `enum` value. - /// - /// It's guaranteed that the interface type integer value is within - /// range for this enum's type. Additionally `ty` is guaranteed to be - /// enum-like as a `Variant` where all `case` arms have no associated - /// type with them. The purpose of this instruction is to convert a - /// native wasm integer into the enum type for the interface. - EnumLift { ty: &'a NamedType } : [1] => [1], - /// Converts an interface types enum value into a wasm `i32`. - EnumLower { ty: &'a NamedType } : [1] => [1], - /// Creates a tuple from the top `n` elements on the stack, pushing the - /// tuple onto the stack. - TupleLift { amt: usize } : [*amt] => [1], - /// Splits a tuple at the top of the stack into its `n` components, - /// pushing them all onto the stack. - TupleLower { amt: usize } : [1] => [*amt], - /// This is a special instruction specifically for the original ABI of - /// WASI. The raw return `i32` of a function is re-pushed onto the - /// stack for reuse. - ReuseReturn : [0] => [1], - /// Returns `amt` values on the stack. This is always the last - /// instruction. - Return { amt: usize } : [*amt] => [0], - /// This is a special instruction used at the entry of blocks used as - /// part of `ResultLower`, representing that the payload of that variant - /// being matched on should be pushed onto the stack. - VariantPayload : [0] => [1], - } -} - -impl Abi { - /// Validates the parameters/results are representable in this ABI. - /// - /// Returns an error string if they're not representable or returns `Ok` if - /// they're indeed representable. - pub fn validate( - &self, - _params: &[InterfaceFuncParam], - results: &[InterfaceFuncParam], - ) -> Result<(), String> { - assert_eq!(*self, Abi::Preview1); - match results.len() { - 0 => {} - 1 => match &**results[0].tref.type_() { - Type::Handle(_) | Type::Builtin(_) | Type::ConstPointer(_) | Type::Pointer(_) => {} - Type::Variant(v) => { - let (ok, err) = match v.as_expected() { - Some(pair) => pair, - None => return Err("invalid return type".to_string()), - }; - if let Some(ty) = ok { - match &**ty.type_() { - Type::Record(r) if r.is_tuple() => { - for member in r.members.iter() { - if !member.tref.named() { - return Err( - "only named types are allowed in results".to_string() - ); - } - } - } - _ => { - if !ty.named() { - return Err( - "only named types are allowed in results".to_string() - ); - } - } - } - } - if let Some(ty) = err { - if !ty.named() { - return Err("only named types are allowed in results".to_string()); - } - if let Type::Variant(v) = &**ty.type_() { - if v.is_enum() { - return Ok(()); - } - } - } - } - Type::Record(r) if r.bitflags_repr().is_some() => {} - Type::Record(_) | Type::List(_) => return Err("invalid return type".to_string()), - }, - _ => return Err("more than one result".to_string()), - } - Ok(()) - } -} - -/// Trait for language implementors to use to generate glue code between native -/// WebAssembly signatures and interface types signatures. -/// -/// This is used as an implementation detail in interpreting the ABI between -/// interface types and wasm types. Eventually this will be driven by interface -/// types adapters themselves, but for now the ABI of a function dictates what -/// instructions are fed in. -/// -/// Types implementing `Bindgen` are incrementally fed `Instruction` values to -/// generate code for. Instructions operate like a stack machine where each -/// instruction has a list of inputs and a list of outputs (provided by the -/// `emit` function). -pub trait Bindgen { - /// The intermediate type for fragments of code for this type. - /// - /// For most languages `String` is a suitable intermediate type. - type Operand; - - /// Emit code to implement the given instruction. - /// - /// Each operand is given in `operands` and can be popped off if ownership - /// is required. It's guaranteed that `operands` has the appropriate length - /// for the `inst` given, as specified with [`Instruction`]. - /// - /// Each result variable should be pushed onto `results`. This function must - /// push the appropriate number of results or binding generation will panic. - fn emit( - &mut self, - inst: &Instruction<'_>, - operands: &mut Vec, - results: &mut Vec, - ); - - /// Allocates temporary space in linear memory indexed by `slot` with enough - /// space to store `ty`. - /// - /// This is called when calling some wasm functions where a return pointer - /// is needed. - fn allocate_space(&mut self, slot: usize, ty: &NamedType); - - /// Enters a new block of code to generate code for. - /// - /// This is currently exclusively used for constructing variants. When a - /// variant is constructed a block here will be pushed for each case of a - /// variant, generating the code necessary to translate a variant case. - /// - /// Blocks are completed with `finish_block` below. It's expected that `emit` - /// will always push code (if necessary) into the "current block", which is - /// updated by calling this method and `finish_block` below. - fn push_block(&mut self); - - /// Indicates to the code generator that a block is completed, and the - /// `operand` specified was the resulting value of the block. - /// - /// This method will be used to compute the value of each arm of lifting a - /// variant. The `operand` will be `None` if the variant case didn't - /// actually have any type associated with it. Otherwise it will be `Some` - /// as the last value remaining on the stack representing the value - /// associated with a variant's `case`. - /// - /// It's expected that this will resume code generation in the previous - /// block before `push_block` was called. This must also save the results - /// of the current block internally for instructions like `ResultLift` to - /// use later. - fn finish_block(&mut self, operand: Option); -} - -impl InterfaceFunc { - /// Get the WebAssembly type signature for this interface function - /// - /// The first entry returned is the list of parameters and the second entry - /// is the list of results for the wasm function signature. - pub fn wasm_signature(&self) -> (Vec, Vec) { - assert_eq!(self.abi, Abi::Preview1); - let mut params = Vec::new(); - let mut results = Vec::new(); - for param in self.params.iter() { - match &**param.tref.type_() { - Type::Builtin(BuiltinType::S8) - | Type::Builtin(BuiltinType::U8 { .. }) - | Type::Builtin(BuiltinType::S16) - | Type::Builtin(BuiltinType::U16) - | Type::Builtin(BuiltinType::S32) - | Type::Builtin(BuiltinType::U32 { .. }) - | Type::Builtin(BuiltinType::Char) - | Type::Pointer(_) - | Type::ConstPointer(_) - | Type::Handle(_) - | Type::Variant(_) => params.push(WasmType::I32), - - Type::Record(r) => match r.bitflags_repr() { - Some(repr) => params.push(WasmType::from(repr)), - None => params.push(WasmType::I32), - }, - - Type::Builtin(BuiltinType::S64) | Type::Builtin(BuiltinType::U64) => { - params.push(WasmType::I64) - } - - Type::Builtin(BuiltinType::F32) => params.push(WasmType::F32), - Type::Builtin(BuiltinType::F64) => params.push(WasmType::F64), - - Type::List(_) => { - params.push(WasmType::I32); - params.push(WasmType::I32); - } - } - } - - for param in self.results.iter() { - match &**param.tref.type_() { - Type::Builtin(BuiltinType::S8) - | Type::Builtin(BuiltinType::U8 { .. }) - | Type::Builtin(BuiltinType::S16) - | Type::Builtin(BuiltinType::U16) - | Type::Builtin(BuiltinType::S32) - | Type::Builtin(BuiltinType::U32 { .. }) - | Type::Builtin(BuiltinType::Char) - | Type::Pointer(_) - | Type::ConstPointer(_) - | Type::Handle(_) => results.push(WasmType::I32), - - Type::Builtin(BuiltinType::S64) | Type::Builtin(BuiltinType::U64) => { - results.push(WasmType::I64) - } - - Type::Builtin(BuiltinType::F32) => results.push(WasmType::F32), - Type::Builtin(BuiltinType::F64) => results.push(WasmType::F64), - - Type::Record(r) => match r.bitflags_repr() { - Some(repr) => results.push(WasmType::from(repr)), - None => unreachable!(), - }, - Type::List(_) => unreachable!(), - - Type::Variant(v) => { - results.push(match v.tag_repr { - IntRepr::U64 => WasmType::I64, - IntRepr::U32 | IntRepr::U16 | IntRepr::U8 => WasmType::I32, - }); - if v.is_enum() { - continue; - } - // return pointer - if let Some(ty) = &v.cases[0].tref { - match &**ty.type_() { - Type::Record(r) if r.is_tuple() => { - for _ in 0..r.members.len() { - params.push(WasmType::I32); - } - } - _ => params.push(WasmType::I32), - } - } - } - } - } - (params, results) - } - - /// Generates an abstract sequence of instructions which represents this - /// function being adapted as an imported function. - /// - /// The instructions here, when executed, will emulate a language with - /// interface types calling the concrete wasm implementation. The parameters - /// for the returned instruction sequence are the language's own - /// interface-types parameters. One instruction in the instruction stream - /// will be a `Call` which represents calling the actual raw wasm function - /// signature. - /// - /// This function is useful, for example, if you're building a language - /// generator for WASI bindings. This will document how to translate - /// language-specific values into the wasm types to call a WASI function, - /// and it will also automatically convert the results of the WASI function - /// back to a language-specific value. - pub fn call_wasm(&self, module: &Id, bindgen: &mut impl Bindgen) { - assert_eq!(self.abi, Abi::Preview1); - Generator { - bindgen, - operands: vec![], - results: vec![], - stack: vec![], - } - .call_wasm(module, self); - } - - /// This is the dual of [`InterfaceFunc::call_wasm`], except that instead of - /// calling a wasm signature it generates code to come from a wasm signature - /// and call an interface types signature. - pub fn call_interface(&self, module: &Id, bindgen: &mut impl Bindgen) { - assert_eq!(self.abi, Abi::Preview1); - Generator { - bindgen, - operands: vec![], - results: vec![], - stack: vec![], - } - .call_interface(module, self); - } -} - -struct Generator<'a, B: Bindgen> { - bindgen: &'a mut B, - operands: Vec, - results: Vec, - stack: Vec, -} - -impl Generator<'_, B> { - fn call_wasm(&mut self, module: &Id, func: &InterfaceFunc) { - // Translate all parameters which are interface values by lowering them - // to their wasm types. - for (nth, param) in func.params.iter().enumerate() { - self.emit(&Instruction::GetArg { nth }); - self.lower(¶m.tref, None); - } - - // If necessary for our ABI, insert return pointers for any returned - // values through a result. - assert!(func.results.len() < 2); - if let Some(result) = func.results.get(0) { - self.prep_return_pointer(&result.tref.type_()); - } - - let (params, results) = func.wasm_signature(); - self.emit(&Instruction::CallWasm { - module: module.as_str(), - name: func.name.as_str(), - params: ¶ms, - results: &results, - }); - - // Lift the return value if one is present. - if let Some(result) = func.results.get(0) { - self.lift(&result.tref, true); - } - - self.emit(&Instruction::Return { - amt: func.results.len(), - }); - } - - fn call_interface(&mut self, module: &Id, func: &InterfaceFunc) { - // Lift all wasm parameters into interface types first. - // - // Note that consuming arguments is somewhat janky right now by manually - // giving lists a second argument for their length. In the future we'll - // probably want to refactor the `lift` function to internally know how - // to consume arguments. - let mut nth = 0; - for param in func.params.iter() { - self.emit(&Instruction::GetArg { nth }); - nth += 1; - if let Type::List(_) = &**param.tref.type_() { - self.emit(&Instruction::GetArg { nth }); - nth += 1; - } - self.lift(¶m.tref, false); - } - - self.emit(&Instruction::CallInterface { - module: module.as_str(), - func, - }); - - // Like above the current ABI only has at most one result, so lower it - // here if necessary. - if let Some(result) = func.results.get(0) { - self.lower(&result.tref, Some(&mut nth)); - } - - let (_params, results) = func.wasm_signature(); - self.emit(&Instruction::Return { amt: results.len() }); - } - - fn emit(&mut self, inst: &Instruction<'_>) { - self.operands.clear(); - self.results.clear(); - - let operands_len = inst.operands_len(); - assert!( - self.stack.len() >= operands_len, - "not enough operands on stack for {:?}", - inst - ); - self.operands - .extend(self.stack.drain((self.stack.len() - operands_len)..)); - self.results.reserve(inst.results_len()); - - self.bindgen - .emit(inst, &mut self.operands, &mut self.results); - - assert_eq!( - self.results.len(), - inst.results_len(), - "{:?} expected {} results, got {}", - inst, - inst.results_len(), - self.results.len() - ); - self.stack.extend(self.results.drain(..)); - } - - fn lower(&mut self, ty: &TypeRef, retptr: Option<&mut usize>) { - use Instruction::*; - match &**ty.type_() { - Type::Builtin(BuiltinType::S8) => self.emit(&I32FromS8), - Type::Builtin(BuiltinType::U8 { lang_c_char: true }) => self.emit(&I32FromChar8), - Type::Builtin(BuiltinType::U8 { lang_c_char: false }) => self.emit(&I32FromU8), - Type::Builtin(BuiltinType::S16) => self.emit(&I32FromS16), - Type::Builtin(BuiltinType::U16) => self.emit(&I32FromU16), - Type::Builtin(BuiltinType::S32) => self.emit(&I32FromS32), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: true, - }) => self.emit(&I32FromUsize), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: false, - }) => self.emit(&I32FromU32), - Type::Builtin(BuiltinType::S64) => self.emit(&I64FromS64), - Type::Builtin(BuiltinType::U64) => self.emit(&I64FromU64), - Type::Builtin(BuiltinType::Char) => self.emit(&I32FromChar), - Type::Pointer(_) => self.emit(&I32FromPointer), - Type::ConstPointer(_) => self.emit(&I32FromConstPointer), - Type::Handle(_) => self.emit(&I32FromHandle { - ty: match ty { - TypeRef::Name(ty) => ty, - _ => unreachable!(), - }, - }), - Type::Record(r) => { - let ty = match ty { - TypeRef::Name(ty) => ty, - _ => unreachable!(), - }; - match r.bitflags_repr() { - Some(IntRepr::U64) => self.emit(&I64FromBitflags { ty }), - Some(_) => self.emit(&I32FromBitflags { ty }), - None => self.emit(&AddrOf), - } - } - Type::Variant(v) => { - // Enum-like variants are simply lowered to their discriminant. - if v.is_enum() { - return self.emit(&EnumLower { - ty: match ty { - TypeRef::Name(n) => n, - _ => unreachable!(), - }, - }); - } - - // If this variant is in the return position then it's special, - // otherwise it's an argument and we just pass the address. - let retptr = match retptr { - Some(ptr) => ptr, - None => return self.emit(&AddrOf), - }; - - // For the return position we emit some blocks to lower the - // ok/err payloads which means that in the ok branch we're - // storing to out-params and in the err branch we're simply - // lowering the error enum. - // - // Note that this is all very specific to the current WASI ABI. - let (ok, err) = v.as_expected().unwrap(); - self.bindgen.push_block(); - if let Some(ok) = ok { - self.emit(&VariantPayload); - let store = |me: &mut Self, ty: &TypeRef, n| { - me.emit(&GetArg { nth: *retptr + n }); - match ty { - TypeRef::Name(ty) => me.emit(&Store { ty }), - _ => unreachable!(), - } - }; - match &**ok.type_() { - Type::Record(r) if r.is_tuple() => { - self.emit(&TupleLower { - amt: r.members.len(), - }); - // Note that `rev()` is used here due to the order - // that tuples are pushed onto the stack and how we - // consume the last item first from the stack. - for (i, member) in r.members.iter().enumerate().rev() { - store(self, &member.tref, i); - } - } - _ => store(self, ok, 0), - } - }; - self.bindgen.finish_block(None); - - self.bindgen.push_block(); - let err_expr = if let Some(ty) = err { - self.emit(&VariantPayload); - self.lower(ty, None); - Some(self.stack.pop().unwrap()) - } else { - None - }; - self.bindgen.finish_block(err_expr); - - self.emit(&ResultLower { ok, err }); - } - Type::Builtin(BuiltinType::F32) => self.emit(&F32FromIf32), - Type::Builtin(BuiltinType::F64) => self.emit(&F64FromIf64), - Type::List(_) => self.emit(&ListPointerLength), - } - } - - fn prep_return_pointer(&mut self, ty: &Type) { - // Return pointers are only needed for `Result`... - let variant = match ty { - Type::Variant(v) => v, - _ => return, - }; - // ... and only if `T` is actually present in `Result` - let ok = match &variant.cases[0].tref { - Some(t) => t, - None => return, - }; - - // Tuples have each individual item in a separate return pointer while - // all other types go through a singular return pointer. - let mut n = 0; - let mut prep = |ty: &TypeRef| { - match ty { - TypeRef::Name(ty) => self.bindgen.allocate_space(n, ty), - _ => unreachable!(), - } - self.emit(&Instruction::ReturnPointerGet { n }); - n += 1; - }; - match &**ok.type_() { - Type::Record(r) if r.is_tuple() => { - for member in r.members.iter() { - prep(&member.tref); - } - } - _ => prep(ok), - } - } - - // Note that in general everything in this function is the opposite of the - // `lower` function above. This is intentional and should be kept this way! - fn lift(&mut self, ty: &TypeRef, is_return: bool) { - use Instruction::*; - match &**ty.type_() { - Type::Builtin(BuiltinType::S8) => self.emit(&S8FromI32), - Type::Builtin(BuiltinType::U8 { lang_c_char: true }) => self.emit(&Char8FromI32), - Type::Builtin(BuiltinType::U8 { lang_c_char: false }) => self.emit(&U8FromI32), - Type::Builtin(BuiltinType::S16) => self.emit(&S16FromI32), - Type::Builtin(BuiltinType::U16) => self.emit(&U16FromI32), - Type::Builtin(BuiltinType::S32) => self.emit(&S32FromI32), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: true, - }) => self.emit(&UsizeFromI32), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: false, - }) => self.emit(&U32FromI32), - Type::Builtin(BuiltinType::S64) => self.emit(&S64FromI64), - Type::Builtin(BuiltinType::U64) => self.emit(&U64FromI64), - Type::Builtin(BuiltinType::Char) => self.emit(&CharFromI32), - Type::Builtin(BuiltinType::F32) => self.emit(&If32FromF32), - Type::Builtin(BuiltinType::F64) => self.emit(&If64FromF64), - Type::Pointer(ty) => self.emit(&PointerFromI32 { ty }), - Type::ConstPointer(ty) => self.emit(&ConstPointerFromI32 { ty }), - Type::Handle(_) => self.emit(&HandleFromI32 { - ty: match ty { - TypeRef::Name(ty) => ty, - _ => unreachable!(), - }, - }), - Type::Variant(v) => { - if v.is_enum() { - return self.emit(&EnumLift { - ty: match ty { - TypeRef::Name(n) => n, - _ => unreachable!(), - }, - }); - } else if !is_return { - return self.emit(&Load { - ty: match ty { - TypeRef::Name(n) => n, - _ => unreachable!(), - }, - }); - } - - let (ok, err) = v.as_expected().unwrap(); - self.bindgen.push_block(); - let ok_expr = if let Some(ok) = ok { - let mut n = 0; - let mut load = |ty: &TypeRef| { - self.emit(&ReturnPointerGet { n }); - n += 1; - match ty { - TypeRef::Name(ty) => self.emit(&Load { ty }), - _ => unreachable!(), - } - }; - match &**ok.type_() { - Type::Record(r) if r.is_tuple() => { - for member in r.members.iter() { - load(&member.tref); - } - self.emit(&TupleLift { - amt: r.members.len(), - }); - } - _ => load(ok), - } - Some(self.stack.pop().unwrap()) - } else { - None - }; - self.bindgen.finish_block(ok_expr); - - self.bindgen.push_block(); - let err_expr = if let Some(ty) = err { - self.emit(&ReuseReturn); - self.lift(ty, false); - Some(self.stack.pop().unwrap()) - } else { - None - }; - self.bindgen.finish_block(err_expr); - - self.emit(&ResultLift); - } - Type::Record(r) => { - let ty = match ty { - TypeRef::Name(ty) => ty, - _ => unreachable!(), - }; - match r.bitflags_repr() { - Some(IntRepr::U64) => self.emit(&BitflagsFromI64 { ty }), - Some(_) => self.emit(&BitflagsFromI32 { ty }), - None => self.emit(&Load { ty }), - } - } - Type::List(ty) => self.emit(&ListFromPointerLength { ty }), - } - } -} diff --git a/proposals/clocks/tools/witx/src/ast.rs b/proposals/clocks/tools/witx/src/ast.rs deleted file mode 100644 index ee985d302..000000000 --- a/proposals/clocks/tools/witx/src/ast.rs +++ /dev/null @@ -1,591 +0,0 @@ -use crate::Abi; -use std::collections::{HashMap, HashSet}; -use std::rc::{Rc, Weak}; - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Id(String); - -impl Id { - pub fn new>(s: S) -> Self { - Id(s.as_ref().to_string()) - } - pub fn as_str(&self) -> &str { - self.0.as_str() - } -} - -impl AsRef for Id { - fn as_ref(&self) -> &str { - self.0.as_ref() - } -} - -impl PartialEq<&str> for Id { - fn eq(&self, rhs: &&str) -> bool { - PartialEq::eq(self.as_ref(), *rhs) - } -} - -impl PartialEq for &str { - fn eq(&self, rhs: &Id) -> bool { - PartialEq::eq(*self, rhs.as_ref()) - } -} - -impl From<&str> for Id { - fn from(s: &str) -> Self { - Self::new(s) - } -} - -#[derive(Debug, Clone)] -pub struct Document { - definitions: Vec, - entries: HashMap, -} - -impl Document { - pub(crate) fn new(definitions: Vec, entries: HashMap) -> Self { - Document { - definitions, - entries, - } - } - pub fn typename(&self, name: &Id) -> Option> { - self.entries.get(name).and_then(|e| match e { - Entry::Typename(nt) => Some(nt.upgrade().expect("always possible to upgrade entry")), - _ => None, - }) - } - pub fn typenames<'a>(&'a self) -> impl Iterator> + 'a { - self.definitions.iter().filter_map(|d| match d { - Definition::Typename(nt) => Some(nt.clone()), - _ => None, - }) - } - /// All of the (unique) types used as "err" variant of results returned from - /// functions. - pub fn error_types<'a>(&'a self) -> impl Iterator + 'a { - let errors: HashSet = self - .modules() - .flat_map(|m| { - m.funcs() - .filter_map(|f| { - if f.results.len() == 1 { - Some(f.results[0].tref.type_().clone()) - } else { - None - } - }) - .filter_map(|t| match &*t { - Type::Variant(v) => { - let (_ok, err) = v.as_expected()?; - Some(err?.clone()) - } - _ => None, - }) - .collect::>() - }) - .collect(); - errors.into_iter() - } - pub fn module(&self, name: &Id) -> Option> { - self.entries.get(&name).and_then(|e| match e { - Entry::Module(m) => Some(m.upgrade().expect("always possible to upgrade entry")), - _ => None, - }) - } - pub fn modules<'a>(&'a self) -> impl Iterator> + 'a { - self.definitions.iter().filter_map(|d| match d { - Definition::Module(m) => Some(m.clone()), - _ => None, - }) - } - - pub fn constants<'a>(&'a self) -> impl Iterator + 'a { - self.definitions.iter().filter_map(|d| match d { - Definition::Constant(c) => Some(c), - _ => None, - }) - } -} - -impl PartialEq for Document { - fn eq(&self, rhs: &Document) -> bool { - // For equality, we don't care about the ordering of definitions, - // so we only need to check that the entries map is equal - self.entries == rhs.entries - } -} -impl Eq for Document {} - -impl std::hash::Hash for Document { - fn hash(&self, state: &mut H) { - std::hash::Hash::hash(&self.definitions, state); - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum Definition { - Typename(Rc), - Module(Rc), - Constant(Constant), -} - -#[derive(Debug, Clone)] -pub enum Entry { - Typename(Weak), - Module(Weak), -} - -impl Entry { - pub fn kind(&self) -> &'static str { - match self { - Entry::Typename { .. } => "typename", - Entry::Module { .. } => "module", - } - } -} - -impl PartialEq for Entry { - fn eq(&self, rhs: &Entry) -> bool { - match (self, rhs) { - (Entry::Typename(t), Entry::Typename(t_rhs)) => { - t.upgrade() - .expect("possible to upgrade entry when part of document") - == t_rhs - .upgrade() - .expect("possible to upgrade entry when part of document") - } - (Entry::Module(m), Entry::Module(m_rhs)) => { - m.upgrade() - .expect("possible to upgrade entry when part of document") - == m_rhs - .upgrade() - .expect("possible to upgrade entry when part of document") - } - _ => false, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum TypeRef { - Name(Rc), - Value(Rc), -} - -impl TypeRef { - pub fn type_(&self) -> &Rc { - match self { - TypeRef::Name(named) => named.type_(), - TypeRef::Value(v) => v, - } - } - - pub fn named(&self) -> bool { - match self { - TypeRef::Name(_) => true, - TypeRef::Value(_) => false, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct NamedType { - pub name: Id, - pub tref: TypeRef, - pub docs: String, -} - -impl NamedType { - pub fn type_(&self) -> &Rc { - self.tref.type_() - } -} - -/// Structure of all possible interface types. -/// -/// Note that this is intended to match the interface types proposal itself. -/// Currently this is relatively close to that with just a few `*.witx` -/// extensions for now. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum Type { - /// A structure with named field. - Record(RecordDatatype), - /// An enumeration where a value is one of a number of variants. - Variant(Variant), - /// A "handle" which is an un-forgeable reference. Today this is an `i32` - /// where a module can't forge and use integers it was not already given - /// access to. - Handle(HandleDatatype), - /// A list of a type, stored in linear memory. - /// - /// Note that lists of `char` are specialized to indicate strings. - List(TypeRef), - /// A `witx`-specific type representing a raw mutable pointer into linear - /// memory - Pointer(TypeRef), - /// A `witx`-specific type representing a raw const pointer into linear - /// memory - ConstPointer(TypeRef), - /// A builtin base-case type. - Builtin(BuiltinType), -} - -impl Type { - /// Returns a human-readable string to describe this type. - pub fn kind(&self) -> &'static str { - use Type::*; - match self { - Record(_) => "record", - Variant(_) => "variant", - Handle(_) => "handle", - List(_) => "list", - Pointer(_) => "pointer", - ConstPointer(_) => "constpointer", - Builtin(_) => "builtin", - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum BuiltinType { - /// This is a 32-bit unicode scalar value, not a code point. - /// - /// Same as the Rust language's `char` type. - Char, - /// An 8-bit unsigned integer. - U8 { - /// Indicates whether this type is intended to represent the `char` - /// type in the C language. The C `char` type is often unsigned, but - /// it's language-specific. At an interface-types level this is an - /// unsigned byte but binding generators may wish to bind this as the - /// language-specific representation for a C character instead. - /// - /// This is also currently used exclusively in conjunction with `@witx - /// pointer` to hint that it's pointing to unicode string data as well. - lang_c_char: bool, - }, - /// A 16-bit unsigned integer. - U16, - /// A 32-bit unsigned integer. - U32 { - /// Indicates that this 32-bit value should actually be considered a - /// pointer-like value in language bindings. At the interface types - /// layer this is always a 32-bit unsigned value, but binding - /// generators may wish to instead bind this as the equivalent of C's - /// `size_t` for convenience with other APIs. - /// - /// This allows witx authors to communicate the intent that the - /// argument or return-value is pointer-like. - lang_ptr_size: bool, - }, - /// A 64-bit unsigned integer. - U64, - /// An 8-bit signed integer - S8, - /// A 16-bit signed integer - S16, - /// A 32-bit signed integer - S32, - /// A 64-bit signed integer - S64, - /// A 32-bit floating point value. - F32, - /// A 64-bit floating point value. - F64, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum IntRepr { - U8, - U16, - U32, - U64, -} - -impl IntRepr { - pub fn to_builtin(&self) -> BuiltinType { - match self { - IntRepr::U8 => BuiltinType::U8 { lang_c_char: false }, - IntRepr::U16 => BuiltinType::U16, - IntRepr::U32 => BuiltinType::U32 { - lang_ptr_size: false, - }, - IntRepr::U64 => BuiltinType::U64, - } - } -} - -/// A struct-like value with named fields. -/// -/// Records map to `struct`s in most languages where this is a type with a -/// number of named fields that all have their own particular type. Field order -/// dictates layout in memory. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct RecordDatatype { - /// A hint as to what this record might be. - /// - /// Note that in the future this will only be a hint, not a control of the - /// actual representation itself. At this time though the record layout of - /// bitflags is different from other types. - pub kind: RecordKind, - - /// A list of named fields for this record. - pub members: Vec, -} - -/// Different kinds of records used for hinting various language-specific types. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum RecordKind { - /// A tuple where the name of all fields are consecutive integers starting - /// at "0". - Tuple, - /// A record where all fields are `bool`s. Currently represented as an - /// integer with bits set or not set. - Bitflags(IntRepr), - /// All other structures. - Other, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct RecordMember { - pub name: Id, - pub tref: TypeRef, - pub docs: String, -} - -impl RecordDatatype { - pub fn is_tuple(&self) -> bool { - match self.kind { - RecordKind::Tuple => true, - _ => false, - } - } - - pub fn bitflags_repr(&self) -> Option { - match self.kind { - RecordKind::Bitflags(i) => Some(i), - _ => None, - } - } -} - -/// A type which represents how values can be one of a set of possible cases. -/// -/// This type maps to an `enum` in languages like Rust, but doesn't have an -/// equivalent in languages like JS or C. The closest analog in C is a tagged -/// union, but a `Variant` is always consistent whereas a tagged union in C -/// could be mis-tagged or such. -/// -/// Variants are used to represent one of a possible set of types. For example -/// an enum-like variant, a result that is either success or failure, or even a -/// simple `bool`. Variants are primarily used heavily with various kinds of -/// shorthands in the `*.witx` format to represent idioms in languages. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Variant { - /// The bit representation of the width of this variant's tag when the - /// variant is stored in memory. - pub tag_repr: IntRepr, - /// The possible cases that values of this variant type can take. - pub cases: Vec, -} - -impl Variant { - /// If this variant looks like an `expected` shorthand, return the ok/err - /// types associated with this result. - /// - /// Only matches variants fo the form: - /// - /// ```text - /// (variant - /// (case "ok" ok?) - /// (case "err" err?)) - /// ``` - pub fn as_expected(&self) -> Option<(Option<&TypeRef>, Option<&TypeRef>)> { - if self.cases.len() != 2 { - return None; - } - if self.cases[0].name != "ok" { - return None; - } - if self.cases[1].name != "err" { - return None; - } - Some((self.cases[0].tref.as_ref(), self.cases[1].tref.as_ref())) - } - - /// Returns whether this variant type is "bool-like" meaning that it matches - /// this type: - /// - /// ```text - /// (variant - /// (case "false") - /// (case "true")) - /// ``` - pub fn is_bool(&self) -> bool { - self.cases.len() == 2 - && self.cases[0].name == "false" - && self.cases[1].name == "true" - && self.cases[0].tref.is_none() - && self.cases[1].tref.is_none() - } - - /// Returns whether this variant type is "enum-like" meaning that all of its - /// cases have no payload associated with them. - pub fn is_enum(&self) -> bool { - self.cases.iter().all(|c| c.tref.is_none()) - } -} - -/// One of a number of possible types that a `Variant` can take. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Case { - /// The name of this case and how to identify it. - pub name: Id, - /// An optional payload type for this case and data that can be associated - /// with it. - pub tref: Option, - /// Documentation for this case. - pub docs: String, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct HandleDatatype {} - -#[derive(Debug, Clone)] -pub struct Module { - pub name: Id, - definitions: Vec, - entries: HashMap, - pub docs: String, -} - -impl Module { - pub(crate) fn new( - name: Id, - definitions: Vec, - entries: HashMap, - docs: String, - ) -> Self { - Module { - name, - definitions, - entries, - docs, - } - } - pub fn import(&self, name: &Id) -> Option> { - self.entries.get(name).and_then(|e| match e { - ModuleEntry::Import(d) => Some(d.upgrade().expect("always possible to upgrade entry")), - _ => None, - }) - } - pub fn imports<'a>(&'a self) -> impl Iterator> + 'a { - self.definitions.iter().filter_map(|d| match d { - ModuleDefinition::Import(d) => Some(d.clone()), - _ => None, - }) - } - pub fn func(&self, name: &Id) -> Option> { - self.entries.get(name).and_then(|e| match e { - ModuleEntry::Func(d) => Some(d.upgrade().expect("always possible to upgrade entry")), - _ => None, - }) - } - pub fn funcs<'a>(&'a self) -> impl Iterator> + 'a { - self.definitions.iter().filter_map(|d| match d { - ModuleDefinition::Func(d) => Some(d.clone()), - _ => None, - }) - } -} - -impl PartialEq for Module { - fn eq(&self, rhs: &Module) -> bool { - // For equality, we don't care about the ordering of definitions, - // so we only need to check that the entries map is equal - self.name == rhs.name && self.entries == rhs.entries && self.docs == rhs.docs - } -} -impl Eq for Module {} - -impl std::hash::Hash for Module { - fn hash(&self, state: &mut H) { - std::hash::Hash::hash(&self.name, state); - std::hash::Hash::hash(&self.definitions, state); - std::hash::Hash::hash(&self.docs, state); - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum ModuleDefinition { - Import(Rc), - Func(Rc), -} - -#[derive(Debug, Clone)] -pub enum ModuleEntry { - Import(Weak), - Func(Weak), -} - -impl PartialEq for ModuleEntry { - fn eq(&self, rhs: &ModuleEntry) -> bool { - match (self, rhs) { - (ModuleEntry::Import(i), ModuleEntry::Import(i_rhs)) => { - i.upgrade() - .expect("always possible to upgrade moduleentry when part of module") - == i_rhs - .upgrade() - .expect("always possible to upgrade moduleentry when part of module") - } - (ModuleEntry::Func(i), ModuleEntry::Func(i_rhs)) => { - i.upgrade() - .expect("always possible to upgrade moduleentry when part of module") - == i_rhs - .upgrade() - .expect("always possible to upgrade moduleentry when part of module") - } - _ => false, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ModuleImport { - pub name: Id, - pub variant: ModuleImportVariant, - pub docs: String, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum ModuleImportVariant { - Memory, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct InterfaceFunc { - pub abi: Abi, - pub name: Id, - pub params: Vec, - pub results: Vec, - pub noreturn: bool, - pub docs: String, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct InterfaceFuncParam { - pub name: Id, - pub tref: TypeRef, - pub docs: String, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Constant { - pub ty: Id, - pub name: Id, - pub value: u64, - pub docs: String, -} diff --git a/proposals/clocks/tools/witx/src/docs/ast.rs b/proposals/clocks/tools/witx/src/docs/ast.rs deleted file mode 100644 index a295a6756..000000000 --- a/proposals/clocks/tools/witx/src/docs/ast.rs +++ /dev/null @@ -1,503 +0,0 @@ -use super::{ - md::{MdFunc, MdHeading, MdNamedType, MdNodeRef, MdSection, ToMarkdown}, - Documentation, -}; -use crate::{ - ast::*, - layout::Layout, - polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, - RepEquality, -}; -use std::collections::HashMap; - -fn heading_from_node(node: &MdNodeRef, levels_down: usize) -> MdHeading { - MdHeading::new_header(node.borrow().ancestors().len() + levels_down) -} - -impl ToMarkdown for Document { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - let types = node.new_child(MdSection::new(heading, "Types")); - - let mut constants_by_name = HashMap::new(); - for c in self.constants() { - constants_by_name.entry(&c.ty).or_insert(Vec::new()).push(c); - } - - for d in self.typenames() { - let name = d.name.as_str(); - let child = types.new_child(MdNamedType::new( - heading.new_level_down(), - name, - name, - format!( - "{}\nSize: {}\n\nAlignment: {}\n", - &d.docs, - &d.mem_size(), - &d.mem_align() - ) - .as_str(), - )); - if let Some(constants) = constants_by_name.remove(&d.name) { - let heading = heading_from_node(&child, 1); - child.new_child(MdSection::new(heading, "Constants")); - for constant in constants { - child.new_child(MdNamedType::new( - MdHeading::new_bullet(), - format!("{}.{}", name, constant.name.as_str()).as_str(), - constant.name.as_str(), - &constant.docs, - )); - } - } - d.generate(child.clone()); - } - - let modules = node.new_child(MdSection::new(heading, "Modules")); - for d in self.modules() { - let mut content = MdSection::new(heading.new_level_down(), d.name.as_str()); - content.id = Some(d.name.as_str().to_owned()); - let child = modules.new_child(content); - d.generate(child.clone()); - } - - assert!(constants_by_name.is_empty()); - } -} - -impl ToMarkdown for TypeRef { - fn generate(&self, node: MdNodeRef) { - match self { - TypeRef::Value(v) => { - v.generate(node.clone()); - node.content_ref_mut::().ty = Some(format!("`{}`", self.type_name())); - } - TypeRef::Name(n) => { - node.content_ref_mut::().ty = - Some(format!("[`{0}`](#{0})", n.name.as_str().to_owned())); - } - } - } -} - -impl ToMarkdown for NamedType { - fn generate(&self, node: MdNodeRef) { - self.tref.generate(node.clone()); - } -} - -impl ToMarkdown for Type { - fn generate(&self, node: MdNodeRef) { - match self { - Self::Record(a) => a.generate(node.clone()), - Self::Variant(a) => a.generate(node.clone()), - Self::Handle(a) => a.generate(node.clone()), - Self::List(_) => {} - Self::Pointer(_) => {} - Self::ConstPointer(_) => {} - Self::Builtin(_) => {} - } - } -} - -impl ToMarkdown for RecordDatatype { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Record members")); - - for member_layout in &self.member_layout() { - let member = member_layout.member; - let offset = member_layout.offset; - let name = member.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let (div, offset_desc) = if self.bitflags_repr().is_some() { - (4, "Bit") - } else { - (1, "Offset") - }; - let n = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - format!("{}\n{}: {}\n", &member.docs, offset_desc, offset / div).as_str(), - )); - member.tref.generate(n.clone()); - } - } -} - -impl ToMarkdown for Variant { - fn generate(&self, node: MdNodeRef) { - if self.is_bool() { - return; - } - if self.cases.iter().any(|c| c.tref.is_some()) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Variant Layout")); - - let whole = self.mem_size_align(); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("size: {}", whole.size), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("align: {}", whole.align), - )); - - let tag = self.tag_repr.mem_size_align(); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("tag_size: {}", tag.size), - )); - } - - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Variant cases")); - - for case in self.cases.iter() { - let name = case.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let n = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - &case.docs, - )); - if let Some(ty) = &case.tref { - ty.generate(n.clone()); - } - } - } -} - -impl ToMarkdown for HandleDatatype { - fn generate(&self, node: MdNodeRef) { - // TODO this needs more work - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Supertypes")); - } -} - -impl ToMarkdown for Module { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - let imports = node.new_child(MdSection::new(heading, "Imports")); - for import in self.imports() { - let child = imports.new_child(MdSection::new(heading.new_level_down(), "")); - import.generate(child.clone()); - } - - let funcs = node.new_child(MdSection::new(heading, "Functions")); - for func in self.funcs() { - let name = func.name.as_str(); - let child = funcs.new_child(MdFunc::new( - heading.new_level_down(), - name, - name, - &func.docs, - )); - func.generate(child.clone()); - } - } -} - -impl ToMarkdown for ModuleImport { - fn generate(&self, node: MdNodeRef) { - match self.variant { - ModuleImportVariant::Memory => { - node.content_ref_mut::().title = "Memory".to_owned(); - } - } - } -} - -impl ToMarkdown for InterfaceFunc { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Params")); - for param in &self.params { - let name = param.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let child = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - param.name.as_str(), - )); - param.generate(child.clone()); - // TODO should this be expanded recursively instead of using flattened type names? - node.content_ref_mut::() - .inputs - .push((param.name.as_str().to_owned(), param.tref.type_name())); - } - - node.new_child(MdSection::new(heading, "Results")); - for result in &self.results { - let name = result.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let child = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - result.name.as_str(), - )); - result.generate(child.clone()); - // TODO should this be expanded recursively instead of using flattened type names? - node.content_ref_mut::() - .outputs - .push(result.tref.type_name()); - } - } -} - -impl ToMarkdown for InterfaceFuncParam { - fn generate(&self, node: MdNodeRef) { - self.tref.generate(node.clone()); - node.content_ref_mut::().docs = self.docs.clone(); - } -} - -impl BuiltinType { - pub fn type_name(&self) -> &'static str { - match self { - BuiltinType::Char => "char", - BuiltinType::U8 { .. } => "u8", - BuiltinType::U16 => "u16", - BuiltinType::U32 { - lang_ptr_size: false, - } => "u32", - BuiltinType::U32 { - lang_ptr_size: true, - } => "usize", - BuiltinType::U64 => "u64", - BuiltinType::S8 => "s8", - BuiltinType::S16 => "s16", - BuiltinType::S32 => "s32", - BuiltinType::S64 => "s64", - BuiltinType::F32 => "f32", - BuiltinType::F64 => "f64", - } - } -} - -impl TypeRef { - pub fn type_name(&self) -> String { - match self { - TypeRef::Name(n) => n.name.as_str().to_string(), - TypeRef::Value(v) => match &**v { - Type::List(a) => match &**a.type_() { - Type::Builtin(BuiltinType::Char) => "string".to_string(), - _ => format!("List<{}>", a.type_name()), - }, - Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), - Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), - Type::Builtin(b) => b.type_name().to_string(), - Type::Record(RecordDatatype { - kind: RecordKind::Tuple, - members, - }) => { - let mut ret = "(".to_string(); - for (i, member) in members.iter().enumerate() { - if i > 0 { - ret.push_str(", "); - } - ret.push_str(&member.tref.type_name()); - } - ret.push_str(")"); - ret - } - Type::Record { .. } => { - format!("Record") - } - Type::Handle { .. } => { - format!("Handle") - } - Type::Variant(v) => { - if let Some((ok, err)) = v.as_expected() { - let ok = match ok { - Some(ty) => ty.type_name(), - None => "()".to_string(), - }; - let err = match err { - Some(ty) => ty.type_name(), - None => "()".to_string(), - }; - format!("Result<{}, {}>", ok, err) - } else if v.is_bool() { - format!("bool") - } else { - format!("Variant") - } - } - }, - } - } -} - -// TODO -// Generate Markdown tree for the polyfill -impl Documentation for Polyfill { - fn to_md(&self) -> String { - let module_docs = self - .modules - .iter() - .map(|m| m.to_md()) - .collect::>() - .join("\n"); - let type_docs = self - .type_polyfills() - .iter() - .filter_map(|t| { - if t.repeq() == RepEquality::Eq { - None - } else { - Some(t.to_md()) - } - }) - .collect::>() - .join("\n"); - format!( - "# Modules\n{}\n# Type Conversions\n{}\n", - module_docs, type_docs - ) - } -} - -impl Documentation for ModulePolyfill { - fn to_md(&self) -> String { - format!( - "## `{}` in terms of `{}`\n{}", - self.new.name.as_str(), - self.old.name.as_str(), - self.funcs - .iter() - .map(|f| f.to_md()) - .collect::>() - .join("\n"), - ) - } -} - -impl Documentation for FuncPolyfill { - fn to_md(&self) -> String { - if self.full_compat() { - format!("* `{}`: full compatibility", self.new.name.as_str()) - } else { - let name = if self.new.name != self.old.name { - format!( - "* `{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("* `{}`", self.new.name.as_str()) - }; - let mut contents = Vec::new(); - for p in self.mapped_params.iter() { - contents.push(if !p.full_compat() { - format!("param {}", p.to_md()) - } else { - format!("param `{}`: compatible", p.new.name.as_str()) - }) - } - for u in self.unknown_params.iter() { - contents.push(format!( - "{} param `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - for r in self.mapped_results.iter() { - contents.push(if !r.full_compat() { - format!("result {}", r.to_md()) - } else { - format!("result `{}`: compatible", r.new.name.as_str()) - }) - } - for u in self.unknown_results.iter() { - contents.push(format!( - "{} result `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - let contents = if contents.is_empty() { - String::new() - } else { - format!(":\n - {}", contents.join("\n - ")) - }; - format!("{}{}", name, contents) - } - } -} - -impl Documentation for ParamPolyfill { - fn to_md(&self) -> String { - let name = if self.new.name != self.old.name { - format!( - "`{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("`{}`", self.new.name.as_str()) - }; - let repr = match self.repeq() { - RepEquality::Eq => "compatible types".to_string(), - RepEquality::Superset => format!( - "`{}` is superset-compatible with `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - RepEquality::NotEq => format!( - "`{}` is incompatible with new `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - }; - format!("{}: {}", name, repr) - } -} - -impl Documentation for TypePolyfill { - fn to_md(&self) -> String { - fn repeq_name(r: RepEquality) -> &'static str { - match r { - RepEquality::Eq => ": compatible", - RepEquality::Superset => ": superset", - RepEquality::NotEq => "", - } - } - match self { - TypePolyfill::OldToNew(o, n) => format!( - "* old `{}` => new `{}`{}", - o.type_name(), - n.type_name(), - repeq_name(self.repeq()) - ), - TypePolyfill::NewToOld(n, o) => format!( - "* new `{}` => old `{}`{}", - n.type_name(), - o.type_name(), - repeq_name(self.repeq()) - ), - } - } -} diff --git a/proposals/clocks/tools/witx/src/docs/md.rs b/proposals/clocks/tools/witx/src/docs/md.rs deleted file mode 100644 index 569b31837..000000000 --- a/proposals/clocks/tools/witx/src/docs/md.rs +++ /dev/null @@ -1,480 +0,0 @@ -use std::{ - any::Any, - cell::{self, RefCell}, - fmt, - rc::{Rc, Weak}, -}; - -/// Helper trait which simplifies generation of the Markdown document represented -/// as a tree of `MdNodeRef`s. -pub(super) trait ToMarkdown { - /// Drives the generation of the `MdNodeRef` tree by either mutating - /// the outer (parent) `MdNodeRef`, shared reference to the `MdNode` `node`, - /// or spawning new child `MdNodeRef` references to nodes. - fn generate(&self, node: MdNodeRef); -} - -/// Interface required for any "content" that is expected to be generated into a -/// Markdown valid format, hence the constraint of `fmt::Display`. -/// -/// In essence, any AST element that is meant to be rendered into Markdown, should -/// define a type implementing this trait. -pub(super) trait MdElement: fmt::Display + fmt::Debug + 'static { - /// Returns `Some(id)` of this `MdElement`. Here `id` is synonym for a Markdown actionable - /// link. - fn id(&self) -> Option<&str>; - - /// Returns `Some(docs)`, the "docs" of this `MdElement`. - fn docs(&self) -> Option<&str>; - - /// Sets `docs`, the "docs" of this `MdElement`. - fn set_docs(&mut self, docs: &str); - - fn as_any(&self) -> &dyn Any; - fn as_any_mut(&mut self) -> &mut dyn Any; -} - -/// A Markdown node containing: -/// * the Markdown renderable `content`, -/// * a weak reference to the `parent` `MdNode` (if any), and -/// * children `MdNodeRef`s -/// -/// `content` is expected to implement the `MdElement` trait. -#[derive(Debug)] -pub(super) struct MdNode { - content: Box, - parent: Option>>, - children: Vec, -} - -/// Helper function for walking the tree up from some starting `MdNode`, all the way up -/// to the root of the tree. -fn walk_ancestors(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { - if let Some(parent) = parent.and_then(|x| x.upgrade()) { - cb(parent.clone().into()); - walk_ancestors(parent.borrow().parent.as_ref(), cb) - } -} - -impl MdNode { - fn new(item: T) -> Self { - Self { - content: Box::new(item), - parent: None, - children: vec![], - } - } - - /// Returns all ancestors of this `MdNode` all the way to the tree's root. - pub fn ancestors(&self) -> Vec { - let mut ancestors = Vec::new(); - walk_ancestors(self.parent.as_ref(), &mut |parent| ancestors.push(parent)); - ancestors - } - - /// Returns all children of this `MdNode` in a BFS order. - pub fn children(&self) -> Vec { - let mut children = self.children.clone(); - for child in &self.children { - children.append(&mut child.borrow().children()); - } - children - } -} - -impl fmt::Display for MdNode { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.content.fmt(f)?; - - for child in &self.children { - child.fmt(f)?; - } - - Ok(()) - } -} - -/// Helper struct for storing a shared mutable reference to `MdNode`. -#[derive(Debug)] -pub(super) struct MdNodeRef(Rc>); - -impl MdNodeRef { - pub fn new(item: T) -> Self { - Self(Rc::new(RefCell::new(MdNode::new(item)))) - } - - /// Spawns new `MdNode` child node, automatically wrapping it in a - /// `MdNodeRef` and creating a weak link from child to itself. - pub fn new_child(&self, item: T) -> Self { - let mut child_node = MdNode::new(item); - child_node.parent = Some(Rc::downgrade(&self.0)); - let child_ref = Self(Rc::new(RefCell::new(child_node))); - self.borrow_mut().children.push(child_ref.clone()); - child_ref - } - - pub fn borrow(&self) -> cell::Ref { - self.0.borrow() - } - - pub fn borrow_mut(&self) -> cell::RefMut { - self.0.borrow_mut() - } - - /// Returns an immutable reference to `MdNode`'s `content` as-is, that - /// is as some type implementing the `MdElement` trait. - pub fn any_ref(&self) -> cell::Ref> { - cell::Ref::map(self.borrow(), |b| &b.content) - } - - /// Returns a mutable reference to `MdNode`'s `content` as-is, that - /// is as some type implementing the `MdElement` trait. - pub fn any_ref_mut(&self) -> cell::RefMut> { - cell::RefMut::map(self.borrow_mut(), |b| &mut b.content) - } - - /// Returns a mutable reference to `MdNode`'s `content` cast to some type - /// `T` which implements `MdElement` trait. - /// - /// Panics if `content` cannot be downcast to `T`. - pub fn content_ref_mut(&self) -> cell::RefMut { - cell::RefMut::map(self.borrow_mut(), |b| { - let r = b.content.as_any_mut(); - r.downcast_mut::().expect("reference is not T type") - }) - } -} - -impl Clone for MdNodeRef { - fn clone(&self) -> Self { - Self(self.0.clone()) - } -} - -impl From>> for MdNodeRef { - fn from(node: Rc>) -> Self { - Self(node) - } -} - -impl fmt::Display for MdNodeRef { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.borrow().fmt(f) - } -} - -/// Record representing the Markdown tree's root. -/// -/// Doesn't render to anything. -#[derive(Debug, Default)] -pub(super) struct MdRoot; - -impl MdElement for MdRoot { - fn id(&self) -> Option<&str> { - None - } - - fn docs(&self) -> Option<&str> { - None - } - - fn set_docs(&mut self, _: &str) {} - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } -} - -impl fmt::Display for MdRoot { - fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { - Ok(()) - } -} - -/// Helper enum representing either a Markdown header "#" nested at some -/// `level` down the tree, or a bullet "-" in a list which is idempotent -/// to changing the nesting level. -#[derive(Debug, Clone, Copy)] -pub(super) enum MdHeading { - Header { level: usize }, - Bullet, -} - -impl MdHeading { - /// Creates new instance of `MdHeading::Header` variant nested at some - /// `level` down the Markdown tree. - pub fn new_header(level: usize) -> Self { - MdHeading::Header { level } - } - - /// Creates new instance of `MdHeading::Bullet` variant. - pub fn new_bullet() -> Self { - MdHeading::Bullet - } - - /// Copies `MdHeading` and if `MdHeading::Header`, pushes it down one - /// level in the Markdown tree by incrementing `level`. - pub fn new_level_down(&self) -> Self { - let mut copy = *self; - if let Self::Header { ref mut level } = &mut copy { - *level += 1; - } - copy - } -} - -impl fmt::Display for MdHeading { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let as_string = match self { - Self::Header { level } => "#".repeat(*level), - Self::Bullet => "-".to_owned(), - }; - f.write_str(&as_string) - } -} - -/// Record representing a Markdown section without any `docs`, consisting -/// of only a `header` (e.g., "###"), maybe some referencable `id` (i.e., -/// a Markdown link), and some `title`. -/// -/// Example rendering: -/// -/// ### Typenames -/// -#[derive(Debug)] -pub(super) struct MdSection { - pub heading: MdHeading, - pub id: Option, - pub title: String, -} - -impl MdSection { - pub fn new>(heading: MdHeading, title: S) -> Self { - Self { - heading, - id: None, - title: title.as_ref().to_owned(), - } - } -} - -impl MdElement for MdSection { - fn id(&self) -> Option<&str> { - self.id.as_ref().map(|s| s.as_str()) - } - - fn docs(&self) -> Option<&str> { - None - } - - fn set_docs(&mut self, _: &str) {} - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } -} - -fn gen_link>(id: S) -> String { - format!("", id = id.as_ref()) -} - -impl fmt::Display for MdSection { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_fmt(format_args!("{} ", self.heading))?; - - if let Some(id) = &self.id { - f.write_fmt(format_args!("{} ", gen_link(id)))?; - } - - writeln!(f, "{}", self.title) - } -} - -/// Record representing a Markdown section representing any `NamedType` element -/// of the AST. -/// Consists of: -/// * `header`, e.g., "###", or "-" for Enum variants, etc., -/// * referencable `id`, -/// * some `name`, e.g., `errno`, -/// * `docs` paragraph, and -/// * maybe `MdType`. -/// -/// Example rendering (recursive): -/// -/// ### `errno`: Enum(`u16`) -/// Error codes returned by... -/// -/// #### Variants -/// - `success` No error occurred... -/// - `2big` Argument list too long... -/// -#[derive(Debug)] -pub(super) struct MdNamedType { - pub heading: MdHeading, - pub id: String, - pub name: String, - pub docs: String, - pub ty: Option, -} - -impl MdNamedType { - pub fn new>(heading: MdHeading, id: S, name: S, docs: S) -> Self { - Self { - heading, - id: id.as_ref().to_owned(), - name: name.as_ref().to_owned(), - docs: docs.as_ref().to_owned(), - ty: None, - } - } -} - -impl MdElement for MdNamedType { - fn id(&self) -> Option<&str> { - Some(&self.id) - } - - fn docs(&self) -> Option<&str> { - Some(&self.docs) - } - - fn set_docs(&mut self, docs: &str) { - self.docs = docs.to_owned(); - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } -} - -impl fmt::Display for MdNamedType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_fmt(format_args!( - "{heading} {link} `{name}`", - heading = self.heading, - link = gen_link(&self.id), - name = self.name, - ))?; - - if let Some(tt) = &self.ty { - f.write_fmt(format_args!(": {}", tt))?; - } - - writeln!(f, "\n{}", self.docs) - } -} - -/// Record representing a Markdown section representing any `InterfaceFunc` element -/// of the AST. -/// Consists of: -/// * `header`, e.g., "###", -/// * referencable `id`, -/// * some `name`, e.g., `path_open`, -/// * function `inputs`, i.e., arguments, -/// * function `outputs`, i.e., results, and -/// * `docs` paragraph. -/// -/// Example rendering: -/// -/// ### Fn args_get(argv: `Pointer>`, ...) -> `errno` -/// Read command-line... -/// -/// #### Params -/// - `argv`: `Pointer>` Some docs... -/// - ... -/// -/// #### Results -/// - `error`: `errno` Error code... -/// -#[derive(Debug)] -pub(super) struct MdFunc { - pub heading: MdHeading, - pub id: String, - pub name: String, - pub inputs: Vec<(String, String)>, - pub outputs: Vec, - pub docs: String, -} - -impl MdFunc { - pub fn new>(heading: MdHeading, id: S, name: S, docs: S) -> Self { - Self { - heading, - id: id.as_ref().to_owned(), - name: name.as_ref().to_owned(), - inputs: vec![], - outputs: vec![], - docs: docs.as_ref().to_owned(), - } - } -} - -impl MdElement for MdFunc { - fn id(&self) -> Option<&str> { - Some(&self.id) - } - - fn docs(&self) -> Option<&str> { - Some(&self.docs) - } - - fn set_docs(&mut self, docs: &str) { - self.docs = docs.to_owned(); - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } -} - -impl fmt::Display for MdFunc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Expand inputs - let inputs = self - .inputs - .iter() - .map(|(name, r#type)| format!("{}: {}", name, r#type)) - .collect::>() - .join(", "); - // Expand outputs - let outputs: Vec<_> = self - .outputs - .iter() - .map(|r#type| format!("{}", r#type)) - .collect(); - let outputs = match outputs.len() { - 0 => "".to_owned(), - 1 => format!(" -> {}", outputs[0]), - _ => format!(" -> ({})", outputs.join(", ")), - }; - // Format - writeln!(f, "\n---\n")?; - - f.write_fmt(format_args!( - "{heading} {link} `{name}({inputs}){outputs}`", - heading = self.heading, - link = gen_link(&self.id), - name = self.name, - inputs = inputs, - outputs = outputs, - ))?; - - writeln!(f, "\n{}", self.docs) - } -} diff --git a/proposals/clocks/tools/witx/src/docs/mod.rs b/proposals/clocks/tools/witx/src/docs/mod.rs deleted file mode 100644 index 8f082cba5..000000000 --- a/proposals/clocks/tools/witx/src/docs/mod.rs +++ /dev/null @@ -1,87 +0,0 @@ -mod ast; -mod md; - -use crate::ast::Document; -use md::{MdNodeRef, MdRoot, ToMarkdown}; -use std::{ - collections::{hash_map, HashSet}, - iter::FromIterator, -}; - -/// Enables generating Markdown formatted content. -pub trait Documentation { - fn to_md(&self) -> String; -} - -/// Helper function which given input `text` and a `HashSet` of existing links converts -/// any slice of the form '`{link}`' into either -/// 1. "[`{link}`](#{md_link})" where `md_link` is `link` with "::" replaced with "." -/// (in Markdown, scoping should be done with ".") if `md_link` exists in the `HashSet` -/// 2. "`{link}`" otherwise. That is, if `md_link` could not be found in the `HashSet`, we -/// just leave what we've consumed. -fn parse_links>(text: S, existing_links: &HashSet) -> String { - let text = text.as_ref(); - let mut parsed_text = String::with_capacity(text.len()); - let mut link = String::with_capacity(text.len()); - let mut is_link = false; - - for ch in text.chars() { - match (ch, is_link) { - // Found the beginning of a link! - ('`', false) => { - is_link = true; - } - // Reached the end, expand into a link! - ('`', true) => { - // Sanitise scoping by replacing "::" with '.' - let md_link = link.replace("::", "."); - // Before committing to pasting the link in, - // first verify that it actually exists. - let expanded = if let Some(_) = existing_links.get(&md_link) { - format!("[`{}`](#{})", link, md_link) - } else { - log::warn!( - "Link [`{}`](#{}) could not be found in the document!", - link, - md_link - ); - format!("`{}`", link) - }; - parsed_text.push_str(&expanded); - link.drain(..); - is_link = false; - } - (ch, false) => parsed_text.push(ch), - (ch, true) => link.push(ch), - } - } - - parsed_text -} - -impl Documentation for Document { - fn to_md(&self) -> String { - let root = MdNodeRef::new(MdRoot::default()); - self.generate(root.clone()); - // Get all children of the `root` element. - let children = root.borrow().children(); - // Gather all existing links in the document into a set. - let existing_links: HashSet = HashSet::from_iter( - children - .iter() - .filter_map(|x| x.any_ref().id().map(String::from)), - ); - // Traverse each docs section of each child, and parse links - // logging a warning in case the generated is invalid. - for child in children { - let docs_with_links = child - .any_ref() - .docs() - .map(|docs| parse_links(docs, &existing_links)); - if let Some(docs) = docs_with_links { - child.any_ref_mut().set_docs(&docs); - } - } - format!("{}", root) - } -} diff --git a/proposals/clocks/tools/witx/src/io.rs b/proposals/clocks/tools/witx/src/io.rs deleted file mode 100644 index f46ab1766..000000000 --- a/proposals/clocks/tools/witx/src/io.rs +++ /dev/null @@ -1,103 +0,0 @@ -use crate::WitxError; -use std::collections::HashMap; -use std::fs::{read_to_string, File}; -use std::io::{BufRead, BufReader, Error, ErrorKind}; -use std::path::{Path, PathBuf}; - -pub trait WitxIo { - /// Read the entire file into a String. Used to resolve `use` declarations. - fn fgets(&self, path: &Path) -> Result; - /// Read a line of a file into a String. Used for error reporting. - fn fget_line(&self, path: &Path, line_num: usize) -> Result; - /// Return the canonical (non-symlinked) path of a file. Used to resolve `use` declarations. - fn canonicalize(&self, path: &Path) -> Result; -} - -impl WitxIo for &'_ T { - fn fgets(&self, path: &Path) -> Result { - T::fgets(self, path) - } - fn fget_line(&self, path: &Path, line_num: usize) -> Result { - T::fget_line(self, path, line_num) - } - fn canonicalize(&self, path: &Path) -> Result { - T::canonicalize(self, path) - } -} - -pub struct Filesystem; - -impl WitxIo for Filesystem { - fn fgets(&self, path: &Path) -> Result { - read_to_string(path).map_err(|e| WitxError::Io(path.to_path_buf(), e)) - } - fn fget_line(&self, path: &Path, line_num: usize) -> Result { - let f = File::open(path).map_err(|e| WitxError::Io(path.into(), e))?; - let buf = BufReader::new(f); - let l = buf - .lines() - .skip(line_num - 1) - .next() - .ok_or_else(|| { - WitxError::Io(path.into(), Error::new(ErrorKind::Other, "Line not found")) - })? - .map_err(|e| WitxError::Io(path.into(), e))?; - - Ok(l) - } - fn canonicalize(&self, path: &Path) -> Result { - path.canonicalize() - .map_err(|e| WitxError::Io(path.to_path_buf(), e)) - } -} - -pub struct MockFs { - map: HashMap, -} - -impl MockFs { - pub fn new(strings: &[(&str, &str)]) -> Self { - MockFs { - map: strings - .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - } - } -} - -impl WitxIo for MockFs { - fn fgets(&self, path: &Path) -> Result { - if let Some(entry) = self.map.get(path.to_str().unwrap()) { - Ok(entry.to_string()) - } else { - Err(WitxError::Io( - path.to_path_buf(), - Error::new(ErrorKind::Other, "mock fs: file not found"), - )) - } - } - fn fget_line(&self, path: &Path, line: usize) -> Result { - if let Some(entry) = self.map.get(path.to_str().unwrap()) { - entry - .lines() - .skip(line - 1) - .next() - .map(|s| s.to_string()) - .ok_or_else(|| { - WitxError::Io( - path.to_path_buf(), - Error::new(ErrorKind::Other, "mock fs: file not found"), - ) - }) - } else { - Err(WitxError::Io( - path.to_path_buf(), - Error::new(ErrorKind::Other, "mock fs: file not found"), - )) - } - } - fn canonicalize(&self, path: &Path) -> Result { - Ok(PathBuf::from(path)) - } -} diff --git a/proposals/clocks/tools/witx/src/layout.rs b/proposals/clocks/tools/witx/src/layout.rs deleted file mode 100644 index 6812f01ae..000000000 --- a/proposals/clocks/tools/witx/src/layout.rs +++ /dev/null @@ -1,219 +0,0 @@ -use crate::ast::*; -use std::collections::HashMap; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct SizeAlign { - pub size: usize, - pub align: usize, -} - -impl SizeAlign { - fn zero() -> SizeAlign { - SizeAlign { size: 0, align: 0 } - } - fn append_field(&mut self, other: &SizeAlign) { - self.align = self.align.max(other.align); - self.size = align_to(self.size, other.align); - self.size += other.size; - } -} - -pub trait Layout { - fn mem_size_align(&self) -> SizeAlign; - fn mem_size(&self) -> usize { - self.mem_size_align().size - } - fn mem_align(&self) -> usize { - self.mem_size_align().align - } -} - -impl TypeRef { - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - if let Some(hit) = cache.get(self) { - return *hit; - } - let layout = match &self { - TypeRef::Name(nt) => nt.layout(cache), - TypeRef::Value(v) => v.layout(cache), - }; - cache.insert(self.clone(), layout); - layout - } -} - -impl Layout for TypeRef { - fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } -} - -impl NamedType { - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - self.tref.layout(cache) - } -} -impl Layout for NamedType { - fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } -} - -impl Type { - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - match &self { - Type::Record(s) => match s.bitflags_repr() { - Some(repr) => repr.mem_size_align(), - None => s.layout(cache), - }, - Type::Variant(s) => s.mem_size_align(), - Type::Handle(h) => h.mem_size_align(), - Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length - Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::S32.mem_size_align(), - Type::Builtin(b) => b.mem_size_align(), - } - } -} - -impl Layout for Type { - fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } -} - -impl Layout for IntRepr { - fn mem_size_align(&self) -> SizeAlign { - self.to_builtin().mem_size_align() - } -} - -pub struct RecordMemberLayout<'a> { - pub member: &'a RecordMember, - pub offset: usize, -} - -impl RecordDatatype { - pub fn member_layout(&self) -> Vec { - self.member_layout_(&mut HashMap::new()).1 - } - - fn member_layout_( - &self, - cache: &mut HashMap, - ) -> (SizeAlign, Vec) { - let mut members = Vec::new(); - let mut sa = SizeAlign::zero(); - for m in self.members.iter() { - let member = m.tref.layout(cache); - sa.append_field(&member); - members.push(RecordMemberLayout { - member: m, - offset: sa.size - member.size, - }); - } - sa.size = align_to(sa.size, sa.align); - (sa, members) - } - - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - self.member_layout_(cache).0 - } -} - -impl Layout for RecordDatatype { - fn mem_size_align(&self) -> SizeAlign { - match self.bitflags_repr() { - Some(repr) => repr.mem_size_align(), - None => { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } - } - } -} - -impl Layout for Variant { - fn mem_size_align(&self) -> SizeAlign { - let mut max = SizeAlign { size: 0, align: 0 }; - for case in self.cases.iter() { - let mut size = self.tag_repr.mem_size_align(); - if let Some(payload) = &case.tref { - size.append_field(&payload.mem_size_align()); - } - size.size = align_to(size.size, size.align); - max.size = max.size.max(size.size); - max.align = max.align.max(size.align); - } - max - } -} - -impl Variant { - pub fn payload_offset(&self) -> usize { - let mut offset = self.tag_repr.mem_size_align().size; - for case in self.cases.iter() { - if let Some(payload) = &case.tref { - offset = offset.max(align_to(offset, payload.mem_size_align().align)); - } - } - offset - } -} - -/// If the next free byte in the struct is `offs`, and the next -/// element has alignment `alignment`, determine the offset at -/// which to place that element. -fn align_to(offs: usize, alignment: usize) -> usize { - offs + alignment - 1 - ((offs + alignment - 1) % alignment) -} - -#[cfg(test)] -mod test { - use super::align_to; - #[test] - fn align() { - assert_eq!(0, align_to(0, 1)); - assert_eq!(0, align_to(0, 2)); - assert_eq!(0, align_to(0, 4)); - assert_eq!(0, align_to(0, 8)); - - assert_eq!(1, align_to(1, 1)); - assert_eq!(2, align_to(1, 2)); - assert_eq!(4, align_to(1, 4)); - assert_eq!(8, align_to(1, 8)); - - assert_eq!(2, align_to(2, 1)); - assert_eq!(2, align_to(2, 2)); - assert_eq!(4, align_to(2, 4)); - assert_eq!(8, align_to(2, 8)); - - assert_eq!(5, align_to(5, 1)); - assert_eq!(6, align_to(5, 2)); - assert_eq!(8, align_to(5, 4)); - assert_eq!(8, align_to(5, 8)); - } -} - -impl Layout for HandleDatatype { - fn mem_size_align(&self) -> SizeAlign { - BuiltinType::S32.mem_size_align() - } -} - -impl Layout for BuiltinType { - fn mem_size_align(&self) -> SizeAlign { - match self { - BuiltinType::U8 { .. } | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, - BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, - BuiltinType::Char | BuiltinType::U32 { .. } | BuiltinType::S32 | BuiltinType::F32 => { - SizeAlign { size: 4, align: 4 } - } - BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { - SizeAlign { size: 8, align: 8 } - } - } - } -} diff --git a/proposals/clocks/tools/witx/src/lib.rs b/proposals/clocks/tools/witx/src/lib.rs deleted file mode 100644 index a0eba6a17..000000000 --- a/proposals/clocks/tools/witx/src/lib.rs +++ /dev/null @@ -1,97 +0,0 @@ -/// Map witx types to core (wasm standard) types -mod abi; -/// Types describing a validated witx document -mod ast; -/// Render documentation -mod docs; -/// Interface for filesystem or mock IO -mod io; -/// Calculate memory layout of types -mod layout; -/// Witx syntax parsing from SExprs -pub mod parser; -/// Calculate required polyfill between interfaces -pub mod polyfill; -/// Render ast to text -mod render; -/// Representational equality of types -mod representation; -/// Resolve toplevel `use` declarations across files -mod toplevel; -/// Validate declarations into ast -mod validate; - -pub use abi::*; -pub use ast::*; -pub use docs::Documentation; -pub use io::{Filesystem, MockFs, WitxIo}; -pub use layout::{Layout, RecordMemberLayout, SizeAlign}; -pub use render::SExpr; -pub use representation::{RepEquality, Representable}; -pub use validate::{DocValidation, ValidationError}; - -use std::path::{Path, PathBuf}; -use thiserror::Error; - -/// Load a witx document from the filesystem -pub fn load>(paths: &[P]) -> Result { - toplevel::parse_witx(paths) -} - -/// Parse a witx document from a str. `(use ...)` directives are not permitted. -pub fn parse(source: &str) -> Result { - let mockfs = MockFs::new(&[("-", source)]); - toplevel::parse_witx_with(&[Path::new("-")], &mockfs) -} - -/// Location in the source text -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct Location { - pub path: PathBuf, - pub line: usize, - pub column: usize, -} - -#[derive(Debug, Error)] -pub enum WitxError { - #[error("IO error with file {0:?}")] - Io(PathBuf, #[source] ::std::io::Error), - #[error("Parse error")] - Parse(#[from] wast::Error), - #[error("Validation error")] - Validation(#[from] ValidationError), -} - -impl WitxError { - pub fn report_with(&self, witxio: &dyn WitxIo) -> String { - use WitxError::*; - match self { - Io(path, ioerr) => format!("with file {:?}: {}", path, ioerr), - Parse(parse) => parse.to_string(), - Validation(validation) => validation.report_with(witxio), - } - } - pub fn report(&self) -> String { - self.report_with(&Filesystem) - } -} - -impl Location { - pub fn highlight_source_with(&self, witxio: &dyn WitxIo) -> String { - let mut msg = format!("in {:?}:\n", self.path); - if let Ok(src_line) = witxio.fget_line(&self.path, self.line) { - msg += &format!( - "{line_num: >5} | {src_line}\n{blank: >5} {caret: >column$}", - line_num = self.line, - src_line = src_line, - blank = " ", - caret = "^", - column = self.column, - ); - } - msg - } - pub fn highlight_source(&self) -> String { - self.highlight_source_with(&Filesystem) - } -} diff --git a/proposals/clocks/tools/witx/src/parser.rs b/proposals/clocks/tools/witx/src/parser.rs deleted file mode 100644 index 33cf745ff..000000000 --- a/proposals/clocks/tools/witx/src/parser.rs +++ /dev/null @@ -1,778 +0,0 @@ -use crate::BuiltinType; -use wast::parser::{Parse, Parser, Peek, Result}; - -///! Parser turns s-expressions into unvalidated syntax constructs. -///! conventions: -///! `Type::starts_parsing(s-expr) -> bool` is for look-ahead: we use -///! this predicate to combine parsers for different `Type`s where both -///! alternatives are accepted. -///! `Type::parse(sexpr: &SExpr) -> Result` takes a single -///! s-expression and parses it into a `Self`. -///! for parsers that take a subset of a vector s-expression, the signature -///! `Type::parse(sexprs: &[SExpr], location: Location) -> Result` -///! has an additional `Location` argument, which should point to the parent SExpr::Vec. -///! This is used for error reporting in case the slice doesn't have the number of elements -///! expected. - -mod kw { - pub use wast::kw::{export, func, import, memory, module, param, result}; - - wast::custom_keyword!(case); - wast::custom_keyword!(char8); - wast::custom_keyword!(char); - wast::custom_keyword!(const_pointer); - wast::custom_keyword!(f32); - wast::custom_keyword!(f64); - wast::custom_keyword!(field); - wast::custom_keyword!(empty); - wast::custom_keyword!(error); - wast::custom_keyword!(expected); - wast::custom_keyword!(flags); - wast::custom_keyword!(handle); - wast::custom_keyword!(list); - wast::custom_keyword!(noreturn); - wast::custom_keyword!(pointer); - wast::custom_keyword!(record); - wast::custom_keyword!(r#const = "const"); - wast::custom_keyword!(r#enum = "enum"); - wast::custom_keyword!(r#union = "union"); - wast::custom_keyword!(r#use = "use"); - wast::custom_keyword!(repr); - wast::custom_keyword!(s16); - wast::custom_keyword!(s32); - wast::custom_keyword!(s64); - wast::custom_keyword!(s8); - wast::custom_keyword!(string); - wast::custom_keyword!(tag); - wast::custom_keyword!(tuple); - wast::custom_keyword!(typename); - wast::custom_keyword!(u16); - wast::custom_keyword!(u32); - wast::custom_keyword!(u64); - wast::custom_keyword!(u8); - wast::custom_keyword!(usize); - wast::custom_keyword!(variant); - wast::custom_keyword!(bool_ = "bool"); -} - -mod annotation { - wast::annotation!(interface); - wast::annotation!(witx); -} - -impl Parse<'_> for BuiltinType { - fn parse(parser: Parser<'_>) -> Result { - let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::Char) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::U8 { lang_c_char: false }) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::U16) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::U32 { - lang_ptr_size: false, - }) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::U64) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::S8) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::S16) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::S32) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::S64) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::F32) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::F64) - } else { - Err(l.error()) - } - } -} - -impl wast::parser::Peek for BuiltinType { - fn peek(cursor: wast::parser::Cursor<'_>) -> bool { - ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - } - - fn display() -> &'static str { - "builtin type" - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Default)] -pub struct CommentSyntax<'a> { - pub comments: Vec<&'a str>, -} - -impl<'a> Parse<'a> for CommentSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result> { - let comments = parser.step(|mut cursor| { - let mut comments = Vec::new(); - loop { - let (comment, c) = match cursor.comment() { - Some(pair) => pair, - None => break, - }; - cursor = c; - comments.push(if comment.starts_with(";;") { - &comment[2..] - } else { - &comment[2..comment.len() - 2] - }); - } - Ok((comments, cursor)) - })?; - Ok(CommentSyntax { comments }) - } -} - -impl<'a> CommentSyntax<'a> { - pub fn docs(&self) -> String { - // Perform a small amount of preprocessing by removing all trailing - // whitespace, and then also filter for only "doc comments" which are `;;;` - // or `(;; ... ;)`. - let docs = self - .comments - .iter() - .map(|d| d.trim_end()) - .filter_map(|d| { - if d.starts_with(";") { - Some(&d[1..]) - } else { - None - } - }) - .collect::>(); - - // Figure out how much leading whitespace we're going to be trimming from - // all docs, trimming the minimum amount in each doc comment. - let to_trim = docs - .iter() - .filter(|d| !d.is_empty()) - .map(|d| d.len() - d.trim().len()) - .min() - .unwrap_or(0); - - // Separate all documents by a newline and collect everything into a single - // string. - let mut ret = String::new(); - for doc in docs { - if !doc.is_empty() { - ret.push_str(doc[to_trim..].trim_end()); - } - ret.push_str("\n"); - } - return ret; - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Default)] -pub struct Documented<'a, T> { - pub comments: CommentSyntax<'a>, - pub item: T, -} - -impl<'a, T: Parse<'a>> Parse<'a> for Documented<'a, T> { - fn parse(parser: Parser<'a>) -> Result { - let _r1 = parser.register_annotation("witx"); - let _r1 = parser.register_annotation("interface"); - let comments = parser.parse()?; - let item = parser.parse()?; - Ok(Documented { comments, item }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TopLevelDocument<'a> { - pub items: Vec>>, -} - -impl<'a> Parse<'a> for TopLevelDocument<'a> { - fn parse(parser: Parser<'a>) -> Result { - let mut items = Vec::new(); - while !parser.is_empty() { - items.push(parser.parse()?); - } - Ok(TopLevelDocument { items }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum TopLevelSyntax<'a> { - Decl(DeclSyntax<'a>), - Use(&'a str), -} - -impl<'a> Parse<'a> for TopLevelSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - if p.peek::() { - p.parse::()?; - Ok(TopLevelSyntax::Use(p.parse()?)) - } else { - Ok(TopLevelSyntax::Decl(p.parse()?)) - } - }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum DeclSyntax<'a> { - Typename(TypenameSyntax<'a>), - Module(ModuleSyntax<'a>), - Const(Documented<'a, ConstSyntax<'a>>), -} - -impl<'a> Parse<'a> for DeclSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(DeclSyntax::Module(parser.parse()?)) - } else if l.peek::() { - Ok(DeclSyntax::Typename(parser.parse()?)) - } else if l.peek::() { - Ok(DeclSyntax::Const(parser.parse()?)) - } else { - Err(l.error()) - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TypenameSyntax<'a> { - pub ident: wast::Id<'a>, - pub def: TypedefSyntax<'a>, -} - -impl<'a> Parse<'a> for TypenameSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let ident = parser.parse()?; - let def = parser.parse()?; - Ok(TypenameSyntax { ident, def }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum TypedefSyntax<'a> { - Enum(EnumSyntax<'a>), - Tuple(TupleSyntax<'a>), - Expected(ExpectedSyntax<'a>), - Flags(FlagsSyntax<'a>), - Record(RecordSyntax<'a>), - Union(UnionSyntax<'a>), - Variant(VariantSyntax<'a>), - Handle(HandleSyntax), - List(Box>), - Pointer(Box>), - ConstPointer(Box>), - Builtin(BuiltinType), - Ident(wast::Id<'a>), - String, - Bool, -} - -impl<'a> Parse<'a> for TypedefSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(TypedefSyntax::Ident(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Builtin(parser.parse()?)) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::String) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Bool) - } else if l.peek::() { - parser.parens(|parser| { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(TypedefSyntax::Enum(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Tuple(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Expected(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Flags(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Record(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Union(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Variant(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Handle(parser.parse()?)) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::List(Box::new(parser.parse()?))) - } else if l.peek::() { - parser.parse::()?; - let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::ConstPointer(Box::new(parser.parse()?))) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Builtin(BuiltinType::U32 { - lang_ptr_size: true, - })) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Builtin(BuiltinType::U8 { - lang_c_char: true, - })) - } else { - Err(l.error()) - } - } else { - Err(l.error()) - } - }) - } else { - Err(l.error()) - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct EnumSyntax<'a> { - pub repr: Option, - pub members: Vec>>, -} - -impl<'a> Parse<'a> for EnumSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let repr = if parser.peek2::() { - Some(parser.parens(|p| { - p.parse::()?; - p.parse::()?; - p.parse() - })?) - } else { - None - }; - let mut members = Vec::new(); - members.push(parser.parse()?); - while !parser.is_empty() { - members.push(parser.parse()?); - } - Ok(EnumSyntax { repr, members }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TupleSyntax<'a> { - pub types: Vec>, -} - -impl<'a> Parse<'a> for TupleSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let mut types = Vec::new(); - while !parser.is_empty() { - types.push(parser.parse()?); - } - Ok(TupleSyntax { types }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ExpectedSyntax<'a> { - pub ok: Option>>, - pub err: Option>>, -} - -impl<'a> Parse<'a> for ExpectedSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let ok = if !parser.is_empty() && !parser.peek2::() { - Some(Box::new(parser.parse()?)) - } else { - None - }; - let err = parser.parens(|p| { - p.parse::()?; - Ok(if p.is_empty() { - None - } else { - Some(Box::new(p.parse()?)) - }) - })?; - Ok(ExpectedSyntax { ok, err }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ConstSyntax<'a> { - pub ty: wast::Id<'a>, - pub name: wast::Id<'a>, - pub value: u64, -} - -impl<'a> Parse<'a> for ConstSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - parser.parse::()?; - let ty = parser.parse()?; - let name = parser.parse()?; - let value = parser.parse()?; - Ok(ConstSyntax { ty, name, value }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct FlagsSyntax<'a> { - pub repr: Option, - pub flags: Vec>>, -} - -impl<'a> Parse<'a> for FlagsSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let repr = if parser.peek2::() { - Some(parser.parens(|p| { - p.parse::()?; - p.parse::()?; - p.parse() - })?) - } else { - None - }; - let mut flags = Vec::new(); - while !parser.is_empty() { - flags.push(parser.parse()?); - } - Ok(FlagsSyntax { repr, flags }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct RecordSyntax<'a> { - pub fields: Vec>>, -} - -impl<'a> Parse<'a> for RecordSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let mut fields = Vec::new(); - fields.push(parser.parse()?); - while !parser.is_empty() { - fields.push(parser.parse()?); - } - Ok(RecordSyntax { fields }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct FieldSyntax<'a> { - pub name: wast::Id<'a>, - pub type_: TypedefSyntax<'a>, -} - -impl<'a> Parse<'a> for FieldSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - p.parse::()?; - let name = p.parse()?; - let type_ = p.parse()?; - Ok(FieldSyntax { name, type_ }) - }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct UnionSyntax<'a> { - pub tag: Option>>, - pub fields: Vec>>, -} - -impl<'a> Parse<'a> for UnionSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let tag = if parser.peek2::() { - Some(parser.parens(|p| { - p.parse::()?; - p.parse::()?; - p.parse().map(Box::new) - })?) - } else { - None - }; - let mut fields = Vec::new(); - while !parser.is_empty() { - fields.push(parser.parse()?); - } - Ok(UnionSyntax { tag, fields }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct VariantSyntax<'a> { - pub tag: Option>>, - pub cases: Vec>>, -} - -impl<'a> Parse<'a> for VariantSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let tag = if parser.peek2::() { - Some(parser.parens(|p| { - p.parse::()?; - p.parse::()?; - p.parse().map(Box::new) - })?) - } else { - None - }; - let mut cases = Vec::new(); - while !parser.is_empty() { - let comments = parser.parse()?; - let item = parser.parens(|p| p.parse())?; - cases.push(Documented { comments, item }); - } - Ok(VariantSyntax { tag, cases }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CaseSyntax<'a> { - pub name: wast::Id<'a>, - pub ty: Option>, -} - -impl<'a> Parse<'a> for CaseSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - Ok(CaseSyntax { - name: parser.parse()?, - ty: if parser.is_empty() { - None - } else { - Some(parser.parse()?) - }, - }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct HandleSyntax {} - -impl<'a> Parse<'a> for HandleSyntax { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - Ok(HandleSyntax {}) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ModuleSyntax<'a> { - pub name: wast::Id<'a>, - pub decls: Vec>>, -} - -impl<'a> Parse<'a> for ModuleSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let name = parser.parse()?; - let mut decls = Vec::new(); - while !parser.is_empty() { - decls.push(parser.parse()?); - } - Ok(ModuleSyntax { name, decls }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum ModuleDeclSyntax<'a> { - Import(ModuleImportSyntax<'a>), - Func(InterfaceFuncSyntax<'a>), -} - -impl<'a> Parse<'a> for ModuleDeclSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - let mut l = p.lookahead1(); - if l.peek::() { - Ok(ModuleDeclSyntax::Import(p.parse()?)) - } else if l.peek::() { - Ok(ModuleDeclSyntax::Func(p.parse()?)) - } else { - Err(l.error()) - } - }) - } -} - -#[derive(Debug, Clone)] -pub struct ModuleImportSyntax<'a> { - pub name: &'a str, - pub name_loc: wast::Span, - pub type_: ImportTypeSyntax, -} - -impl<'a> Parse<'a> for ModuleImportSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let name_loc = parser.cur_span(); - Ok(ModuleImportSyntax { - name: parser.parse()?, - name_loc, - type_: parser.parens(|p| p.parse())?, - }) - } -} - -impl PartialEq for ModuleImportSyntax<'_> { - fn eq(&self, other: &ModuleImportSyntax<'_>) -> bool { - // skip the `name_loc` field - self.name == other.name && self.type_ == other.type_ - } -} - -impl Eq for ModuleImportSyntax<'_> {} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum ImportTypeSyntax { - Memory, -} - -impl Parse<'_> for ImportTypeSyntax { - fn parse(parser: Parser<'_>) -> Result { - parser.parse::()?; - Ok(ImportTypeSyntax::Memory) - } -} - -#[derive(Debug, Clone)] -pub struct InterfaceFuncSyntax<'a> { - pub export: &'a str, - pub export_loc: wast::Span, - pub params: Vec>>, - pub results: Vec>>, - pub noreturn: bool, -} - -impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - parser.parse::()?; - - let (export_loc, export) = parser.parens(|p| { - p.parse::()?; - Ok((p.cur_span(), p.parse()?)) - })?; - - let mut params = Vec::new(); - let mut results = Vec::new(); - let mut noreturn = false; - - while !parser.is_empty() { - let func_field = parser.parse::>()?; - match func_field.item { - InterfaceFuncField::Param(item) => { - params.push(Documented { - comments: func_field.comments, - item, - }); - } - InterfaceFuncField::Result(item) => { - results.push(Documented { - comments: func_field.comments, - item, - }); - } - InterfaceFuncField::Noreturn => { - noreturn = true; - } - } - } - - Ok(InterfaceFuncSyntax { - export, - export_loc, - params, - results, - noreturn, - }) - } -} - -enum InterfaceFuncField<'a> { - Param(FieldSyntax<'a>), - Result(FieldSyntax<'a>), - Noreturn, -} -impl<'a> Parse<'a> for InterfaceFuncField<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - let mut l = p.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(InterfaceFuncField::Param(FieldSyntax { - name: parser.parse()?, - type_: parser.parse()?, - })) - } else if l.peek::() { - parser.parse::()?; - Ok(InterfaceFuncField::Result(FieldSyntax { - name: parser.parse()?, - type_: parser.parse()?, - })) - } else if l.peek::() { - parser.parse::()?; - let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(InterfaceFuncField::Noreturn) - } else { - Err(l.error()) - } - } else { - Err(l.error()) - } - }) - } -} - -impl PartialEq for InterfaceFuncSyntax<'_> { - fn eq(&self, other: &InterfaceFuncSyntax<'_>) -> bool { - // skip the `export_loc` field - self.export == other.export - && self.params == other.params - && self.results == other.results - && self.noreturn == other.noreturn - } -} - -impl Eq for InterfaceFuncSyntax<'_> {} diff --git a/proposals/clocks/tools/witx/src/polyfill.rs b/proposals/clocks/tools/witx/src/polyfill.rs deleted file mode 100644 index c779cfa4e..000000000 --- a/proposals/clocks/tools/witx/src/polyfill.rs +++ /dev/null @@ -1,255 +0,0 @@ -use crate::{ - Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable, Type, - TypeRef, -}; -use std::collections::{HashMap, HashSet}; -use std::rc::Rc; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum PolyfillError { - #[error("Module not present: {name:?}")] - ModuleNotPresent { name: Id }, - #[error("Function not present: {name:?}")] - FuncNotPresent { module: Id, name: Id }, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Polyfill { - pub modules: Vec, -} - -impl Polyfill { - pub fn new( - new: &Document, - old: &Document, - module_mapping: &HashMap, // Will need a more sophisticated mapping - what about function names, argument names? - ) -> Result { - let mut modules = Vec::new(); - for (newname, oldname) in module_mapping { - let newname = Id::new(newname); - let oldname = Id::new(oldname); - let newmod = new - .module(&newname) - .ok_or_else(|| PolyfillError::ModuleNotPresent { name: newname })?; - let oldmod = old - .module(&oldname) - .ok_or_else(|| PolyfillError::ModuleNotPresent { name: oldname })?; - modules.push(ModulePolyfill::new(newmod, oldmod)?); - } - Ok(Polyfill { modules }) - } - - pub fn type_polyfills(&self) -> HashSet { - self.modules - .iter() - .map(|m| m.type_polyfills()) - .flatten() - .collect() - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ModulePolyfill { - pub new: Rc, - pub old: Rc, - pub funcs: Vec, -} - -impl ModulePolyfill { - pub fn new(new: Rc, old: Rc) -> Result { - let mut funcs = Vec::new(); - for oldfunc in old.funcs() { - let newfunc = new - .func(&oldfunc.name) - .ok_or_else(|| PolyfillError::FuncNotPresent { - module: new.name.clone(), - name: oldfunc.name.clone(), - })?; - funcs.push(FuncPolyfill::new(newfunc, oldfunc)); - } - Ok(ModulePolyfill { new, old, funcs }) - } - pub fn type_polyfills(&self) -> HashSet { - self.funcs - .iter() - .map(|f| f.type_polyfills()) - .flatten() - .collect() - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct FuncPolyfill { - pub new: Rc, - pub old: Rc, - pub mapped_params: Vec, - pub unknown_params: Vec, - pub mapped_results: Vec, - pub unknown_results: Vec, -} - -impl FuncPolyfill { - pub fn new(new: Rc, old: Rc) -> FuncPolyfill { - let mut mapped_params = Vec::new(); - let mut unknown_params = Vec::new(); - - // Old function is called. Need to map each of its parameters to the new function: - for old_param in old.params.iter() { - if let Some(new_param) = new.params.iter().find(|p| p.name == old_param.name) { - mapped_params.push(ParamPolyfill::param(new_param.clone(), old_param.clone())) - } else { - unknown_params.push(ParamUnknown::Old(old_param.clone())); - } - } - // Are any new params not covered by the old params? - // This search is O(n^2), but n ought to be small. - for new_param in new.params.iter() { - if mapped_params - .iter() - .find(|m| m.new.name == new_param.name) - .is_none() - { - unknown_params.push(ParamUnknown::New(new_param.clone())); - } - } - - let mut mapped_results = Vec::new(); - let mut unknown_results = Vec::new(); - - // New function has returned. Need to map each of its results to the old function: - for new_result in new.results.iter() { - if let Some(old_result) = old.results.iter().find(|p| p.name == new_result.name) { - mapped_results.push(ParamPolyfill::result( - new_result.clone(), - old_result.clone(), - )) - } else { - unknown_results.push(ParamUnknown::New(new_result.clone())); - } - } - - // Are any old results not covered by the new results? - for old_result in old.results.iter() { - if mapped_results - .iter() - .find(|m| m.old.name == old_result.name) - .is_none() - { - unknown_results.push(ParamUnknown::Old(old_result.clone())); - } - } - - FuncPolyfill { - new, - old, - mapped_params, - unknown_params, - mapped_results, - unknown_results, - } - } - - pub fn full_compat(&self) -> bool { - self.new.name == self.old.name - && self.mapped_params.iter().all(|p| p.full_compat()) - && self.unknown_params.is_empty() - && self.mapped_results.iter().all(|p| p.full_compat()) - && self.unknown_results.is_empty() - } - - pub fn type_polyfills(&self) -> HashSet { - self.mapped_params - .iter() - .map(|p| p.type_polyfill.clone()) - .chain(self.mapped_results.iter().map(|p| p.type_polyfill.clone())) - .collect() - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ParamPolyfill { - pub new: InterfaceFuncParam, - pub old: InterfaceFuncParam, - pub type_polyfill: TypePolyfill, -} - -impl ParamPolyfill { - fn common_denominator(a: TypeRef, b: TypeRef) -> (TypeRef, TypeRef) { - match (&a, &b) { - (TypeRef::Value(va), TypeRef::Value(vb)) => match (&**va, &**vb) { - (Type::List(a), Type::List(b)) => (a.clone(), b.clone()), - (Type::Pointer(a), Type::Pointer(b)) => (a.clone(), b.clone()), - (Type::ConstPointer(a), Type::ConstPointer(b)) => (a.clone(), b.clone()), - _ => (a, b), - }, - _ => (a, b), - } - } - - pub fn param(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { - let (told, tnew) = Self::common_denominator(old.tref.clone(), new.tref.clone()); - // Call new param type with old param: - let type_polyfill = TypePolyfill::OldToNew(told, tnew); - ParamPolyfill { - new, - old, - type_polyfill, - } - } - - pub fn result(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { - let (told, tnew) = Self::common_denominator(old.tref.clone(), new.tref.clone()); - // Return old result type from new result: - let type_polyfill = TypePolyfill::NewToOld(tnew, told); - ParamPolyfill { - new, - old, - type_polyfill, - } - } - - pub fn full_compat(&self) -> bool { - self.new.name == self.old.name && self.repeq() == RepEquality::Eq - } - - pub fn repeq(&self) -> RepEquality { - self.type_polyfill.repeq() - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum ParamUnknown { - Old(InterfaceFuncParam), - New(InterfaceFuncParam), -} - -impl ParamUnknown { - pub fn which(&self) -> &'static str { - match self { - ParamUnknown::Old { .. } => "old", - ParamUnknown::New { .. } => "new", - } - } - pub fn param(&self) -> &InterfaceFuncParam { - match self { - ParamUnknown::Old(p) => &p, - ParamUnknown::New(p) => &p, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum TypePolyfill { - NewToOld(TypeRef, TypeRef), - OldToNew(TypeRef, TypeRef), -} - -impl TypePolyfill { - pub fn repeq(&self) -> RepEquality { - match self { - TypePolyfill::NewToOld(new, old) => old.type_().representable(&new.type_()), - TypePolyfill::OldToNew(old, new) => new.type_().representable(&old.type_()), - } - } -} diff --git a/proposals/clocks/tools/witx/src/render.rs b/proposals/clocks/tools/witx/src/render.rs deleted file mode 100644 index a740e282c..000000000 --- a/proposals/clocks/tools/witx/src/render.rs +++ /dev/null @@ -1,320 +0,0 @@ -use crate::ast::*; -use std::fmt; - -impl fmt::Display for Document { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for d in self.typenames() { - write!(f, "{}\n", d.to_sexpr())?; - } - for m in self.modules() { - write!(f, "{}\n", m.to_sexpr())?; - } - Ok(()) - } -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub enum SExpr { - Vec(Vec), - Word(String), - Ident(String), - Quote(String), - /// Short for Annotation - Annot(String), - /// Doc comment - Docs(String, Box), -} - -impl fmt::Display for SExpr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - SExpr::Vec(vs) => { - write!(f, "(")?; - let mut vss = Vec::new(); - for v in vs { - vss.push(format!("{}", v)); - } - f.write_str(&vss.join(" "))?; - write!(f, ")") - } - SExpr::Word(w) => write!(f, "{}", w), - SExpr::Ident(i) => write!(f, "${}", i), - SExpr::Quote(q) => write!(f, "\"{}\"", q), - SExpr::Annot(a) => write!(f, "@{}", a), - SExpr::Docs(d, s) => write!(f, "(;; {} ;) {}", d, s), - } - } -} - -impl SExpr { - pub fn word(s: &str) -> SExpr { - SExpr::Word(s.to_string()) - } - pub fn ident(s: &str) -> SExpr { - SExpr::Ident(s.to_string()) - } - pub fn quote(s: &str) -> SExpr { - SExpr::Quote(s.to_string()) - } - pub fn annot(s: &str) -> SExpr { - SExpr::Annot(s.to_string()) - } - pub fn docs(d: &str, s: SExpr) -> SExpr { - if d.is_empty() { - s - } else { - SExpr::Docs(d.to_string(), Box::new(s)) - } - } -} - -impl Id { - pub fn to_sexpr(&self) -> SExpr { - SExpr::ident(self.as_str()) - } -} - -impl BuiltinType { - pub fn to_sexpr(&self) -> SExpr { - match self { - BuiltinType::Char => SExpr::word("char"), - BuiltinType::U8 { lang_c_char: true } => { - SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("char8")]) - } - BuiltinType::U8 { lang_c_char: false } => SExpr::word("u8"), - BuiltinType::U16 => SExpr::word("u16"), - BuiltinType::U32 { - lang_ptr_size: false, - } => SExpr::word("u32"), - BuiltinType::U32 { - lang_ptr_size: true, - } => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), - BuiltinType::U64 => SExpr::word("u64"), - BuiltinType::S8 => SExpr::word("s8"), - BuiltinType::S16 => SExpr::word("s16"), - BuiltinType::S32 => SExpr::word("s32"), - BuiltinType::S64 => SExpr::word("s64"), - BuiltinType::F32 => SExpr::word("f32"), - BuiltinType::F64 => SExpr::word("f64"), - } - } -} - -impl NamedType { - pub fn to_sexpr(&self) -> SExpr { - let body = self.tref.to_sexpr(); - SExpr::docs( - &self.docs, - SExpr::Vec(vec![SExpr::word("typename"), self.name.to_sexpr(), body]), - ) - } -} - -impl TypeRef { - pub fn to_sexpr(&self) -> SExpr { - match self { - TypeRef::Name(n) => n.name.to_sexpr(), - TypeRef::Value(v) => v.to_sexpr(), - } - } -} - -impl Type { - pub fn to_sexpr(&self) -> SExpr { - match self { - Type::Record(a) => a.to_sexpr(), - Type::Variant(a) => a.to_sexpr(), - Type::Handle(a) => a.to_sexpr(), - Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), - Type::Pointer(p) => SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("pointer"), - p.to_sexpr(), - ]), - Type::ConstPointer(p) => SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("const_pointer"), - p.to_sexpr(), - ]), - Type::Builtin(b) => b.to_sexpr(), - } - } -} - -impl RecordDatatype { - pub fn to_sexpr(&self) -> SExpr { - match self.kind { - RecordKind::Tuple => { - let mut tuple = vec![SExpr::word("tuple")]; - for m in self.members.iter() { - tuple.push(SExpr::docs(&m.docs, m.tref.to_sexpr())); - } - SExpr::Vec(tuple) - } - RecordKind::Bitflags(repr) => { - let mut flags = vec![SExpr::word("flags")]; - flags.push(SExpr::Vec(vec![ - SExpr::word("@witx"), - SExpr::word("repr"), - repr.to_sexpr(), - ])); - flags.extend( - self.members - .iter() - .map(|m| SExpr::docs(&m.docs, m.name.to_sexpr())), - ); - SExpr::Vec(flags) - } - RecordKind::Other => { - let header = vec![SExpr::word("record")]; - let members = self - .members - .iter() - .map(|m| { - SExpr::docs( - &m.docs, - SExpr::Vec(vec![ - SExpr::word("field"), - m.name.to_sexpr(), - m.tref.to_sexpr(), - ]), - ) - }) - .collect::>(); - SExpr::Vec([header, members].concat()) - } - } - } -} - -impl Variant { - pub fn to_sexpr(&self) -> SExpr { - let mut list = Vec::new(); - if self.is_bool() { - return SExpr::word("bool"); - } else if self.is_enum() { - list.push(SExpr::word("enum")); - list.push(SExpr::Vec(vec![ - SExpr::word("@witx"), - SExpr::word("tag"), - self.tag_repr.to_sexpr(), - ])); - for case in self.cases.iter() { - list.push(SExpr::docs(&case.docs, case.name.to_sexpr())); - } - } else { - list.push(SExpr::word("variant")); - list.push(SExpr::Vec(vec![ - SExpr::word("@witx"), - SExpr::word("tag"), - self.tag_repr.to_sexpr(), - ])); - for case in self.cases.iter() { - let mut case_expr = vec![SExpr::word("case"), case.name.to_sexpr()]; - if let Some(ty) = &case.tref { - case_expr.push(ty.to_sexpr()); - } - list.push(SExpr::docs(&case.docs, SExpr::Vec(case_expr))); - } - } - SExpr::Vec(list) - } -} - -impl HandleDatatype { - pub fn to_sexpr(&self) -> SExpr { - SExpr::Vec(vec![SExpr::word("handle")]) - } -} - -impl IntRepr { - pub fn to_sexpr(&self) -> SExpr { - match self { - IntRepr::U8 => SExpr::word("u8"), - IntRepr::U16 => SExpr::word("u16"), - IntRepr::U32 => SExpr::word("u32"), - IntRepr::U64 => SExpr::word("u64"), - } - } -} - -impl Module { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("module"), self.name.to_sexpr()]; - let definitions = self - .imports() - .map(|i| i.to_sexpr()) - .chain(self.funcs().map(|f| f.to_sexpr())) - .collect::>(); - SExpr::docs(&self.docs, SExpr::Vec([header, definitions].concat())) - } -} - -impl ModuleImport { - pub fn to_sexpr(&self) -> SExpr { - let variant = match self.variant { - ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), - }; - SExpr::docs( - &self.docs, - SExpr::Vec(vec![ - SExpr::word("import"), - SExpr::quote(self.name.as_str()), - variant, - ]), - ) - } -} - -impl InterfaceFunc { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![ - SExpr::annot("interface"), - SExpr::word("func"), - SExpr::Vec(vec![ - SExpr::word("export"), - SExpr::quote(self.name.as_str()), - ]), - ]; - let params = self - .params - .iter() - .map(|f| { - SExpr::docs( - &f.docs, - SExpr::Vec(vec![ - SExpr::word("param"), - f.name.to_sexpr(), - f.tref.to_sexpr(), - ]), - ) - }) - .collect(); - let results = self - .results - .iter() - .map(|f| { - SExpr::docs( - &f.docs, - SExpr::Vec(vec![ - SExpr::word("result"), - f.name.to_sexpr(), - f.tref.to_sexpr(), - ]), - ) - }) - .collect(); - let attrs = if self.noreturn { - vec![SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("noreturn"), - ])] - } else { - vec![] - }; - SExpr::docs( - &self.docs, - SExpr::Vec([header, params, results, attrs].concat()), - ) - } -} diff --git a/proposals/clocks/tools/witx/src/representation.rs b/proposals/clocks/tools/witx/src/representation.rs deleted file mode 100644 index 589b64e39..000000000 --- a/proposals/clocks/tools/witx/src/representation.rs +++ /dev/null @@ -1,161 +0,0 @@ -use crate::{BuiltinType, IntRepr, NamedType, RecordDatatype, Type, TypeRef, Variant}; -use std::collections::HashMap; - -// A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum RepEquality { - Eq, - Superset, - NotEq, -} - -impl RepEquality { - pub fn join(&self, rhs: &Self) -> Self { - match (self, rhs) { - (RepEquality::Eq, RepEquality::Eq) => RepEquality::Eq, - _ => RepEquality::NotEq, - } - } -} - -pub trait Representable { - fn representable(&self, by: &Self) -> RepEquality; -} - -impl Representable for BuiltinType { - fn representable(&self, by: &Self) -> RepEquality { - // An unsigned integer can be used to represent an unsigned integer of smaller width. - // Otherwise, types must be equal. - if self == by { - return RepEquality::Eq; - } - match self { - BuiltinType::U8 { .. } => match by { - BuiltinType::U64 | BuiltinType::U32 { .. } | BuiltinType::U16 => { - RepEquality::Superset - } - _ => RepEquality::NotEq, - }, - BuiltinType::U16 => match by { - BuiltinType::U64 | BuiltinType::U32 { .. } => RepEquality::Superset, - _ => RepEquality::NotEq, - }, - BuiltinType::U32 { .. } => match by { - BuiltinType::U64 => RepEquality::Superset, - _ => RepEquality::NotEq, - }, - _ => RepEquality::NotEq, - } - } -} - -impl Representable for IntRepr { - fn representable(&self, by: &Self) -> RepEquality { - if self == by { - return RepEquality::Eq; - } - // An unsigned integer can be used to represent an unsigned integer of smaller width. - match self { - IntRepr::U16 => match by { - IntRepr::U32 | IntRepr::U64 => RepEquality::Superset, - _ => RepEquality::NotEq, - }, - IntRepr::U32 => match by { - IntRepr::U64 => RepEquality::Superset, - _ => RepEquality::NotEq, - }, - _ => RepEquality::NotEq, - } - } -} - -impl Representable for Variant { - fn representable(&self, by: &Self) -> RepEquality { - let mut superset = false; - // Integer representation must be compatible - match self.tag_repr.representable(&by.tag_repr) { - RepEquality::NotEq => return RepEquality::NotEq, - RepEquality::Eq => {} - RepEquality::Superset => superset = true, - } - let other_by_name = by - .cases - .iter() - .enumerate() - .map(|(i, c)| (&c.name, (c, i))) - .collect::>(); - // For each variant in self, must have variant of same name in by: - for (i, v) in self.cases.iter().enumerate() { - let other_ty = match other_by_name.get(&v.name) { - Some((_, j)) if i != *j => return RepEquality::NotEq, - Some((other, _)) => &other.tref, - None => return RepEquality::NotEq, - }; - match (&v.tref, other_ty) { - (Some(me), Some(other)) => match me.representable(other) { - RepEquality::NotEq => return RepEquality::NotEq, - RepEquality::Eq => {} - RepEquality::Superset => superset = true, - }, - // We added fields, that's not ok - (Some(_), None) => return RepEquality::NotEq, - // Fields were deleted, that's ok - (None, Some(_)) => superset = true, - (None, None) => {} - } - } - if superset || self.cases.len() < by.cases.len() { - RepEquality::Superset - } else { - RepEquality::Eq - } - } -} - -impl Representable for RecordDatatype { - fn representable(&self, by: &Self) -> RepEquality { - // Records must have exact structural equality - same members, must - // be Eq, in the same order. - // We would require require a more expressive RepEquality enum to describe which members - // might be supersets. - if self.members.len() != by.members.len() { - return RepEquality::NotEq; - } - for (m, bym) in self.members.iter().zip(by.members.iter()) { - if m.name != bym.name { - return RepEquality::NotEq; - } - if m.tref.type_().representable(&*bym.tref.type_()) != RepEquality::Eq { - return RepEquality::NotEq; - } - } - RepEquality::Eq - } -} - -impl Representable for TypeRef { - fn representable(&self, by: &Self) -> RepEquality { - self.type_().representable(&*by.type_()) - } -} - -impl Representable for NamedType { - fn representable(&self, by: &Self) -> RepEquality { - self.tref.representable(&by.tref) - } -} - -impl Representable for Type { - fn representable(&self, by: &Self) -> RepEquality { - match (&self, &by) { - (Type::Variant(s), Type::Variant(b)) => s.representable(b), - (Type::Record(s), Type::Record(b)) => s.representable(b), - (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural - (Type::List(s), Type::List(b)) => s.representable(b), - (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), - (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), - (Type::Builtin(s), Type::Builtin(b)) => s.representable(b), - _ => RepEquality::NotEq, - } - } -} diff --git a/proposals/clocks/tools/witx/src/toplevel.rs b/proposals/clocks/tools/witx/src/toplevel.rs deleted file mode 100644 index 257e6edd8..000000000 --- a/proposals/clocks/tools/witx/src/toplevel.rs +++ /dev/null @@ -1,166 +0,0 @@ -use crate::ast::{Definition, Document}; -use crate::io::{Filesystem, WitxIo}; -use crate::parser::{TopLevelDocument, TopLevelSyntax}; -use crate::validate::DocValidation; -use crate::WitxError; -use std::collections::HashSet; -use std::path::{Path, PathBuf}; - -pub fn parse_witx(i: &[impl AsRef]) -> Result { - let paths = i.iter().map(|p| p.as_ref()).collect::>(); - _parse_witx_with(&paths, &Filesystem) -} - -pub fn parse_witx_with(i: &[impl AsRef], witxio: impl WitxIo) -> Result { - let paths = i.iter().map(|p| p.as_ref()).collect::>(); - _parse_witx_with(&paths, &witxio) -} - -fn _parse_witx_with(paths: &[&Path], io: &dyn WitxIo) -> Result { - let mut validator = DocValidation::new(); - let mut definitions = Vec::new(); - let mut parsed = HashSet::new(); - for path in paths { - let root = path.parent().unwrap_or(Path::new(".")); - - parse_file( - path.file_name().unwrap().as_ref(), - io, - root, - &mut validator, - &mut definitions, - &mut parsed, - )?; - } - Ok(validator.into_document(definitions)) -} - -fn parse_file( - path: &Path, - io: &dyn WitxIo, - root: &Path, - validator: &mut DocValidation, - definitions: &mut Vec, - parsed: &mut HashSet, -) -> Result<(), WitxError> { - let path = io.canonicalize(&root.join(path))?; - if !parsed.insert(path.clone()) { - return Ok(()); - } - let input = io.fgets(&path)?; - - let adjust_err = |mut error: wast::Error| { - error.set_path(&path); - error.set_text(&input); - WitxError::Parse(error) - }; - let buf = wast::parser::ParseBuffer::new(&input).map_err(adjust_err)?; - let doc = wast::parser::parse::(&buf).map_err(adjust_err)?; - - for t in doc.items { - match t.item { - TopLevelSyntax::Decl(d) => { - validator - .scope(&input, &path) - .validate_decl(&d, &t.comments, definitions) - .map_err(WitxError::Validation)?; - } - TopLevelSyntax::Use(u) => { - parse_file(u.as_ref(), io, root, validator, definitions, parsed)?; - } - } - } - - Ok(()) -} - -#[cfg(test)] -mod test { - use super::*; - use crate::ast::*; - use crate::io::MockFs; - - #[test] - fn empty() { - parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", ";; empty")])).expect("parse"); - } - - #[test] - fn one_use() { - parse_witx_with( - &[Path::new("/a")], - &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]), - ) - .unwrap(); - } - - #[test] - fn multi_use() { - let doc = parse_witx_with( - &[Path::new("/a")], - &MockFs::new(&[ - ("/a", "(use \"b\")"), - ("/b", "(use \"c\")\n(typename $b_float f64)"), - ("/c", "(typename $c_int u32)"), - ]), - ) - .expect("parse"); - - let b_float = doc.typename(&Id::new("b_float")).unwrap(); - assert_eq!(**b_float.type_(), Type::Builtin(BuiltinType::F64)); - - let c_int = doc.typename(&Id::new("c_int")).unwrap(); - assert_eq!( - **c_int.type_(), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: false - }) - ); - } - - #[test] - fn diamond_dependency() { - let doc = parse_witx_with( - &[Path::new("/a")], - &MockFs::new(&[ - ("/a", "(use \"b\")\n(use \"c\")"), - ("/b", "(use \"d\")"), - ("/c", "(use \"d\")"), - ("/d", "(typename $d_char u8)"), - ]), - ) - .expect("parse"); - - let d_char = doc.typename(&Id::new("d_char")).unwrap(); - assert_eq!( - **d_char.type_(), - Type::Builtin(BuiltinType::U8 { lang_c_char: false }) - ); - } - - #[test] - fn use_not_found() { - match parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", "(use \"b\")")])) - .err() - .unwrap() - { - WitxError::Io(path, _error) => assert_eq!(path, PathBuf::from("/b")), - e => panic!("wrong error: {:?}", e), - } - } - - #[test] - fn use_invalid() { - match parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", "(use bbbbbbb)")])) - .err() - .unwrap() - { - WitxError::Parse(e) => { - let err = e.to_string(); - assert!(err.contains("expected a string"), "bad error: {}", err); - assert!(err.contains("/a:1:6")); - } - e => panic!("wrong error: {:?}", e), - } - } -} diff --git a/proposals/clocks/tools/witx/src/validate.rs b/proposals/clocks/tools/witx/src/validate.rs deleted file mode 100644 index cf4d0ad7f..000000000 --- a/proposals/clocks/tools/witx/src/validate.rs +++ /dev/null @@ -1,722 +0,0 @@ -use crate::{ - io::{Filesystem, WitxIo}, - parser::{ - CommentSyntax, DeclSyntax, Documented, EnumSyntax, ExpectedSyntax, FlagsSyntax, - HandleSyntax, ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TupleSyntax, TypedefSyntax, - UnionSyntax, VariantSyntax, - }, - Abi, BuiltinType, Case, Constant, Definition, Document, Entry, HandleDatatype, Id, IntRepr, - InterfaceFunc, InterfaceFuncParam, Location, Module, ModuleDefinition, ModuleEntry, - ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordKind, RecordMember, Type, - TypeRef, Variant, -}; -use std::collections::{HashMap, HashSet}; -use std::path::Path; -use std::rc::Rc; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum ValidationError { - #[error("Unknown name `{name}`")] - UnknownName { name: String, location: Location }, - #[error("Redefinition of name `{name}`")] - NameAlreadyExists { - name: String, - at_location: Location, - previous_location: Location, - }, - #[error("Wrong kind of name `{name}`: expected {expected}, got {got}")] - WrongKindName { - name: String, - location: Location, - expected: &'static str, - got: &'static str, - }, - #[error("Recursive definition of name `{name}`")] - Recursive { name: String, location: Location }, - #[error("Invalid representation `{repr:?}`")] - InvalidRepr { - repr: BuiltinType, - location: Location, - }, - #[error("ABI error: {reason}")] - Abi { reason: String, location: Location }, - #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] - AnonymousRecord { location: Location }, - #[error("Union expected {expected} variants, found {found}")] - UnionSizeMismatch { - expected: usize, - found: usize, - location: Location, - }, - #[error("Invalid union tag: {reason}")] - InvalidUnionTag { reason: String, location: Location }, - #[error("Invalid union field `{name}`: {reason}")] - InvalidUnionField { - name: String, - reason: String, - location: Location, - }, -} - -impl ValidationError { - pub fn report_with(&self, witxio: &dyn WitxIo) -> String { - use ValidationError::*; - match self { - UnknownName { location, .. } - | WrongKindName { location, .. } - | Recursive { location, .. } - | InvalidRepr { location, .. } - | Abi { location, .. } - | AnonymousRecord { location, .. } - | UnionSizeMismatch { location, .. } - | InvalidUnionField { location, .. } - | InvalidUnionTag { location, .. } => { - format!("{}\n{}", location.highlight_source_with(witxio), &self) - } - NameAlreadyExists { - at_location, - previous_location, - .. - } => format!( - "{}\n{}\nOriginally defined at:\n{}", - at_location.highlight_source_with(witxio), - &self, - previous_location.highlight_source_with(witxio), - ), - } - } - pub fn report(&self) -> String { - self.report_with(&Filesystem) - } -} - -struct IdentValidation { - names: HashMap, -} - -impl IdentValidation { - fn new() -> Self { - Self { - names: HashMap::new(), - } - } - - fn introduce(&mut self, syntax: &str, location: Location) -> Result { - if let Some(introduced) = self.names.get(syntax) { - Err(ValidationError::NameAlreadyExists { - name: syntax.to_string(), - at_location: location, - previous_location: introduced.clone(), - }) - } else { - self.names.insert(syntax.to_string(), location); - Ok(Id::new(syntax)) - } - } - - fn get(&self, syntax: &str, location: Location) -> Result { - if self.names.get(syntax).is_some() { - Ok(Id::new(syntax)) - } else { - Err(ValidationError::UnknownName { - name: syntax.to_string(), - location, - }) - } - } -} - -pub struct DocValidation { - scope: IdentValidation, - entries: HashMap, - constant_scopes: HashMap, - bool_ty: TypeRef, -} - -pub struct DocValidationScope<'a> { - doc: &'a mut DocValidation, - text: &'a str, - path: &'a Path, -} - -impl DocValidation { - pub fn new() -> Self { - Self { - scope: IdentValidation::new(), - entries: HashMap::new(), - constant_scopes: HashMap::new(), - bool_ty: TypeRef::Value(Rc::new(Type::Variant(Variant { - tag_repr: IntRepr::U32, - cases: vec![ - Case { - name: Id::new("false"), - tref: None, - docs: String::new(), - }, - Case { - name: Id::new("true"), - tref: None, - docs: String::new(), - }, - ], - }))), - } - } - - pub fn scope<'a>(&'a mut self, text: &'a str, path: &'a Path) -> DocValidationScope<'a> { - DocValidationScope { - doc: self, - text, - path, - } - } - - pub fn into_document(self, defs: Vec) -> Document { - Document::new(defs, self.entries) - } -} - -impl DocValidationScope<'_> { - fn location(&self, span: wast::Span) -> Location { - // Wast Span gives 0-indexed lines and columns. Location is 1-indexed. - let (line, column) = span.linecol_in(self.text); - Location { - line: line + 1, - column: column + 1, - path: self.path.to_path_buf(), - } - } - - fn introduce(&mut self, name: &wast::Id<'_>) -> Result { - let loc = self.location(name.span()); - self.doc.scope.introduce(name.name(), loc) - } - - fn get(&self, name: &wast::Id<'_>) -> Result { - let loc = self.location(name.span()); - self.doc.scope.get(name.name(), loc) - } - - pub fn validate_decl( - &mut self, - decl: &DeclSyntax, - comments: &CommentSyntax, - definitions: &mut Vec, - ) -> Result<(), ValidationError> { - match decl { - DeclSyntax::Typename(decl) => { - let name = self.introduce(&decl.ident)?; - let docs = comments.docs(); - let tref = self.validate_datatype(&decl.def, true, decl.ident.span())?; - - let rc_datatype = Rc::new(NamedType { - name: name.clone(), - tref, - docs, - }); - self.doc - .entries - .insert(name.clone(), Entry::Typename(Rc::downgrade(&rc_datatype))); - definitions.push(Definition::Typename(rc_datatype)); - } - - DeclSyntax::Module(syntax) => { - let name = self.introduce(&syntax.name)?; - let mut module_validator = ModuleValidation::new(self); - let decls = syntax - .decls - .iter() - .map(|d| module_validator.validate_decl(&d)) - .collect::, _>>()?; - - let rc_module = Rc::new(Module::new( - name.clone(), - decls, - module_validator.entries, - comments.docs(), - )); - self.doc - .entries - .insert(name, Entry::Module(Rc::downgrade(&rc_module))); - definitions.push(Definition::Module(rc_module)); - } - - DeclSyntax::Const(syntax) => { - let ty = Id::new(syntax.item.ty.name()); - let loc = self.location(syntax.item.name.span()); - let scope = self - .doc - .constant_scopes - .entry(ty.clone()) - .or_insert_with(IdentValidation::new); - let name = scope.introduce(syntax.item.name.name(), loc)?; - // TODO: validate `ty` is a integer datatype that `syntax.value` - // fits within. - definitions.push(Definition::Constant(Constant { - ty, - name, - value: syntax.item.value, - docs: syntax.comments.docs(), - })); - } - } - Ok(()) - } - - fn validate_datatype( - &self, - syntax: &TypedefSyntax, - named: bool, - span: wast::Span, - ) -> Result { - match syntax { - TypedefSyntax::Ident(syntax) => { - let i = self.get(syntax)?; - match self.doc.entries.get(&i) { - Some(Entry::Typename(weak_ref)) => Ok(TypeRef::Name( - weak_ref.upgrade().expect("weak backref to defined type"), - )), - Some(e) => Err(ValidationError::WrongKindName { - name: i.as_str().to_string(), - location: self.location(syntax.span()), - expected: "datatype", - got: e.kind(), - }), - None => Err(ValidationError::Recursive { - name: i.as_str().to_string(), - location: self.location(syntax.span()), - }), - } - } - TypedefSyntax::Enum { .. } - | TypedefSyntax::Flags { .. } - | TypedefSyntax::Record { .. } - | TypedefSyntax::Union { .. } - | TypedefSyntax::Handle { .. } - if !named => - { - Err(ValidationError::AnonymousRecord { - location: self.location(span), - }) - } - other => Ok(TypeRef::Value(Rc::new(match other { - TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), - TypedefSyntax::Tuple(syntax) => Type::Record(self.validate_tuple(&syntax, span)?), - TypedefSyntax::Expected(syntax) => { - Type::Variant(self.validate_expected(&syntax, span)?) - } - TypedefSyntax::Flags(syntax) => Type::Record(self.validate_flags(&syntax, span)?), - TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), - TypedefSyntax::Union(syntax) => Type::Variant(self.validate_union(&syntax, span)?), - TypedefSyntax::Variant(syntax) => { - Type::Variant(self.validate_variant(&syntax, span)?) - } - TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), - TypedefSyntax::List(syntax) => { - Type::List(self.validate_datatype(syntax, false, span)?) - } - TypedefSyntax::Pointer(syntax) => { - Type::Pointer(self.validate_datatype(syntax, false, span)?) - } - TypedefSyntax::ConstPointer(syntax) => { - Type::ConstPointer(self.validate_datatype(syntax, false, span)?) - } - TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), - TypedefSyntax::String => { - Type::List(TypeRef::Value(Rc::new(Type::Builtin(BuiltinType::Char)))) - } - TypedefSyntax::Bool => return Ok(self.doc.bool_ty.clone()), - TypedefSyntax::Ident { .. } => unreachable!(), - }))), - } - } - - fn validate_enum( - &self, - syntax: &EnumSyntax, - span: wast::Span, - ) -> Result { - let mut enum_scope = IdentValidation::new(); - let tag_repr = match &syntax.repr { - Some(repr) => self.validate_int_repr(repr, span)?, - None => IntRepr::U32, - }; - let cases = syntax - .members - .iter() - .map(|i| { - let name = enum_scope.introduce(i.item.name(), self.location(i.item.span()))?; - let docs = i.comments.docs(); - Ok(Case { - name, - tref: None, - docs, - }) - }) - .collect::, _>>()?; - - Ok(Variant { tag_repr, cases }) - } - - fn validate_tuple( - &self, - syntax: &TupleSyntax, - span: wast::Span, - ) -> Result { - let members = syntax - .types - .iter() - .enumerate() - .map(|(i, ty)| { - Ok(RecordMember { - name: Id::new(i.to_string()), - tref: self.validate_datatype(ty, false, span)?, - docs: String::new(), - }) - }) - .collect::, _>>()?; - - Ok(RecordDatatype { - kind: RecordKind::Tuple, - members, - }) - } - - fn validate_expected( - &self, - syntax: &ExpectedSyntax, - span: wast::Span, - ) -> Result { - let ok_ty = match &syntax.ok { - Some(ok) => Some(self.validate_datatype(ok, false, span)?), - None => None, - }; - let err_ty = match &syntax.err { - Some(err) => Some(self.validate_datatype(err, false, span)?), - None => None, - }; - Ok(Variant { - tag_repr: IntRepr::U32, - cases: vec![ - Case { - name: Id::new("ok"), - tref: ok_ty, - docs: String::new(), - }, - Case { - name: Id::new("err"), - tref: err_ty, - docs: String::new(), - }, - ], - }) - } - - fn validate_flags( - &self, - syntax: &FlagsSyntax, - span: wast::Span, - ) -> Result { - let repr = match syntax.repr { - Some(ty) => self.validate_int_repr(&ty, span)?, - None => IntRepr::U32, - }; - let mut flags_scope = IdentValidation::new(); - let mut members = Vec::new(); - for flag in syntax.flags.iter() { - let name = flags_scope.introduce(flag.item.name(), self.location(flag.item.span()))?; - let docs = flag.comments.docs(); - members.push(RecordMember { - name, - docs, - tref: self.doc.bool_ty.clone(), - }); - } - Ok(RecordDatatype { - kind: RecordKind::Bitflags(repr), - members, - }) - } - - fn validate_record( - &self, - syntax: &RecordSyntax, - _span: wast::Span, - ) -> Result { - let mut member_scope = IdentValidation::new(); - let members = syntax - .fields - .iter() - .map(|f| { - let name = member_scope - .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; - let docs = f.comments.docs(); - Ok(RecordMember { name, tref, docs }) - }) - .collect::, _>>()?; - - Ok(RecordDatatype { - kind: RecordKind::Other, - members, - }) - } - - fn validate_union( - &self, - syntax: &UnionSyntax, - span: wast::Span, - ) -> Result { - let (tag_repr, names) = self.union_tag_repr(&syntax.tag, span)?; - - if let Some(names) = &names { - if names.len() != syntax.fields.len() { - return Err(ValidationError::UnionSizeMismatch { - expected: names.len(), - found: syntax.fields.len(), - location: self.location(span), - }); - } - } - - let cases = syntax - .fields - .iter() - .enumerate() - .map(|(i, case)| { - Ok(Case { - name: match &names { - Some(names) => names[i].clone(), - None => Id::new(i.to_string()), - }, - tref: Some(self.validate_datatype(&case.item, false, span)?), - docs: case.comments.docs(), - }) - }) - .collect::, _>>()?; - Ok(Variant { tag_repr, cases }) - } - - fn validate_variant( - &self, - syntax: &VariantSyntax, - span: wast::Span, - ) -> Result { - let (tag_repr, names) = self.union_tag_repr(&syntax.tag, span)?; - - if let Some(names) = &names { - if names.len() != syntax.cases.len() { - return Err(ValidationError::UnionSizeMismatch { - expected: names.len(), - found: syntax.cases.len(), - location: self.location(span), - }); - } - } - - let mut name_set = names - .as_ref() - .map(|names| names.iter().collect::>()); - - let mut cases = syntax - .cases - .iter() - .map(|case| { - let name = Id::new(case.item.name.name()); - if let Some(names) = &mut name_set { - if !names.remove(&name) { - return Err(ValidationError::InvalidUnionField { - name: name.as_str().to_string(), - location: self.location(case.item.name.span()), - reason: format!("does not correspond to variant in tag `tag`"), - }); - } - } - Ok(Case { - name: Id::new(case.item.name.name()), - tref: match &case.item.ty { - Some(ty) => { - Some(self.validate_datatype(ty, false, case.item.name.span())?) - } - None => None, - }, - docs: case.comments.docs(), - }) - }) - .collect::, _>>()?; - - // If we have an explicit tag with an enum then that's instructing us to - // reorder cases based on the order of the enum itself, so do that here. - if let Some(names) = names { - let name_pos = names - .iter() - .enumerate() - .map(|(i, name)| (name, i)) - .collect::>(); - cases.sort_by_key(|c| name_pos[&&c.name]); - } - - Ok(Variant { tag_repr, cases }) - } - - fn union_tag_repr( - &self, - tag: &Option>>, - span: wast::Span, - ) -> Result<(IntRepr, Option>), ValidationError> { - let ty = match tag { - Some(tag) => self.validate_datatype(tag, false, span)?, - None => return Ok((IntRepr::U32, None)), - }; - match &**ty.type_() { - Type::Variant(e) => { - let mut names = Vec::new(); - for c in e.cases.iter() { - if c.tref.is_some() { - return Err(ValidationError::InvalidUnionTag { - location: self.location(span), - reason: format!("all variant cases should have empty payloads"), - }); - } - names.push(c.name.clone()); - } - return Ok((e.tag_repr, Some(names))); - } - Type::Builtin(BuiltinType::U8 { .. }) => return Ok((IntRepr::U8, None)), - Type::Builtin(BuiltinType::U16) => return Ok((IntRepr::U16, None)), - Type::Builtin(BuiltinType::U32 { .. }) => return Ok((IntRepr::U32, None)), - Type::Builtin(BuiltinType::U64) => return Ok((IntRepr::U64, None)), - _ => {} - } - - Err(ValidationError::WrongKindName { - name: "tag".to_string(), - location: self.location(span), - expected: "enum or builtin", - got: ty.type_().kind(), - }) - } - - fn validate_handle( - &self, - _syntax: &HandleSyntax, - _span: wast::Span, - ) -> Result { - Ok(HandleDatatype {}) - } - - fn validate_int_repr( - &self, - type_: &BuiltinType, - span: wast::Span, - ) -> Result { - match type_ { - BuiltinType::U8 { .. } => Ok(IntRepr::U8), - BuiltinType::U16 => Ok(IntRepr::U16), - BuiltinType::U32 { .. } => Ok(IntRepr::U32), - BuiltinType::U64 => Ok(IntRepr::U64), - _ => Err(ValidationError::InvalidRepr { - repr: type_.clone(), - location: self.location(span), - }), - } - } -} - -struct ModuleValidation<'a> { - doc: &'a DocValidationScope<'a>, - scope: IdentValidation, - pub entries: HashMap, -} - -impl<'a> ModuleValidation<'a> { - fn new(doc: &'a DocValidationScope<'a>) -> Self { - Self { - doc, - scope: IdentValidation::new(), - entries: HashMap::new(), - } - } - - fn validate_decl( - &mut self, - decl: &Documented, - ) -> Result { - match &decl.item { - ModuleDeclSyntax::Import(syntax) => { - let loc = self.doc.location(syntax.name_loc); - let name = self.scope.introduce(syntax.name, loc)?; - let variant = match syntax.type_ { - ImportTypeSyntax::Memory => ModuleImportVariant::Memory, - }; - let rc_import = Rc::new(ModuleImport { - name: name.clone(), - variant, - docs: decl.comments.docs(), - }); - self.entries - .insert(name, ModuleEntry::Import(Rc::downgrade(&rc_import))); - Ok(ModuleDefinition::Import(rc_import)) - } - ModuleDeclSyntax::Func(syntax) => { - let loc = self.doc.location(syntax.export_loc); - let name = self.scope.introduce(syntax.export, loc)?; - let mut argnames = IdentValidation::new(); - let params = syntax - .params - .iter() - .map(|f| { - Ok(InterfaceFuncParam { - name: argnames.introduce( - f.item.name.name(), - self.doc.location(f.item.name.span()), - )?, - tref: self.doc.validate_datatype( - &f.item.type_, - false, - f.item.name.span(), - )?, - docs: f.comments.docs(), - }) - }) - .collect::, _>>()?; - let results = syntax - .results - .iter() - .map(|f| { - let tref = - self.doc - .validate_datatype(&f.item.type_, false, f.item.name.span())?; - Ok(InterfaceFuncParam { - name: argnames.introduce( - f.item.name.name(), - self.doc.location(f.item.name.span()), - )?, - tref, - docs: f.comments.docs(), - }) - }) - .collect::, _>>()?; - let noreturn = syntax.noreturn; - let abi = Abi::Preview1; - abi.validate(¶ms, &results) - .map_err(|reason| ValidationError::Abi { - reason, - location: self.doc.location(syntax.export_loc), - })?; - let rc_func = Rc::new(InterfaceFunc { - abi, - name: name.clone(), - params, - results, - noreturn, - docs: decl.comments.docs(), - }); - self.entries - .insert(name, ModuleEntry::Func(Rc::downgrade(&rc_func))); - Ok(ModuleDefinition::Func(rc_func)) - } - } - } -} diff --git a/proposals/clocks/tools/witx/tests/witxt.rs b/proposals/clocks/tools/witx/tests/witxt.rs deleted file mode 100644 index 7c002fe1b..000000000 --- a/proposals/clocks/tools/witx/tests/witxt.rs +++ /dev/null @@ -1,656 +0,0 @@ -//! You can run this test suite with: -//! -//! cargo test --test witxt -//! -//! An argument can be passed as well to filter, based on filename, which test -//! to run -//! -//! cargo test --test witxt foo.witxt - -use anyhow::{anyhow, bail, Context, Result}; -use rayon::prelude::*; -use std::collections::HashMap; -use std::path::{Path, PathBuf}; -use std::str; -use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; -use wast::parser::{self, Parse, ParseBuffer, Parser}; -use witx::{Documentation, Instruction, Representable, WasmType}; - -fn main() { - let tests = find_tests(); - let filter = std::env::args().nth(1); - - let tests = tests - .par_iter() - .filter_map(|test| { - if let Some(filter) = &filter { - if let Some(s) = test.to_str() { - if !s.contains(filter) { - return None; - } - } - } - let contents = std::fs::read(test).unwrap(); - Some((test, contents)) - }) - .collect::>(); - - println!("running {} test files\n", tests.len()); - - let ntests = AtomicUsize::new(0); - let errors = tests - .par_iter() - .filter_map(|(test, contents)| { - WitxtRunner { - ntests: &ntests, - documents: HashMap::new(), - } - .run(test, contents) - .err() - }) - .collect::>(); - - if !errors.is_empty() { - for msg in errors.iter() { - eprintln!("{:?}", msg); - } - - panic!("{} tests failed", errors.len()) - } - - println!( - "test result: ok. {} directives passed\n", - ntests.load(SeqCst) - ); -} - -/// Recursively finds all tests in a whitelisted set of directories which we -/// then load up and test in parallel. -fn find_tests() -> Vec { - let mut tests = Vec::new(); - find_tests("tests/witxt".as_ref(), &mut tests); - tests.sort(); - return tests; - - fn find_tests(path: &Path, tests: &mut Vec) { - for f in path.read_dir().unwrap() { - let f = f.unwrap(); - if f.file_type().unwrap().is_dir() { - find_tests(&f.path(), tests); - continue; - } - - match f.path().extension().and_then(|s| s.to_str()) { - Some("witxt") => {} - _ => continue, - } - tests.push(f.path()); - } - } -} - -struct WitxtRunner<'a> { - ntests: &'a AtomicUsize, - documents: HashMap, -} - -impl WitxtRunner<'_> { - fn run(&mut self, test: &Path, contents: &[u8]) -> Result<()> { - let contents = str::from_utf8(contents)?; - macro_rules! adjust { - ($e:expr) => {{ - let mut e = wast::Error::from($e); - e.set_path(test); - e.set_text(contents); - e - }}; - } - let buf = ParseBuffer::new(contents).map_err(|e| adjust!(e))?; - let witxt = parser::parse::(&buf).map_err(|e| adjust!(e))?; - - let errors = witxt - .directives - .into_iter() - .filter_map(|directive| { - let (line, col) = directive.span().linecol_in(contents); - self.test_directive(contents, test, directive) - .with_context(|| { - format!( - "failed directive on {}:{}:{}", - test.display(), - line + 1, - col + 1 - ) - }) - .err() - }) - .collect::>(); - if errors.is_empty() { - return Ok(()); - } - let mut s = format!("{} test failures in {}:", errors.len(), test.display()); - for mut error in errors { - if let Some(err) = error.downcast_mut::() { - err.set_path(test); - err.set_text(contents); - } - s.push_str("\n\n\t--------------------------------\n\n\t"); - s.push_str(&format!("{:?}", error).replace("\n", "\n\t")); - } - bail!("{}", s) - } - - fn test_directive( - &mut self, - contents: &str, - test: &Path, - directive: WitxtDirective, - ) -> Result<()> { - self.bump_ntests(); - match directive { - WitxtDirective::Witx(witx) => { - let doc = witx.document(contents, test)?; - self.assert_roundtrip(&doc) - .context("failed to round-trip the document")?; - self.assert_md(&doc)?; - if let Some(name) = witx.id { - self.documents.insert(name.name().to_string(), doc); - } - } - WitxtDirective::AssertInvalid { witx, message, .. } => { - let err = match witx.document(contents, test) { - Ok(_) => bail!("witx was valid when it shouldn't be"), - Err(e) => format!("{:?}", anyhow::Error::from(e)), - }; - if !err.contains(message) { - bail!("expected error {:?}\nfound error {}", message, err); - } - } - WitxtDirective::AssertRepresentable { repr, t1, t2, .. } => { - let (t1m, t1t) = t1; - let (t2m, t2t) = t2; - let t1d = self - .documents - .get(t1m.name()) - .ok_or_else(|| anyhow!("no document named {:?}", t1m.name()))?; - let t2d = self - .documents - .get(t2m.name()) - .ok_or_else(|| anyhow!("no document named {:?}", t2m.name()))?; - let t1 = t1d - .typename(&witx::Id::new(t1t)) - .ok_or_else(|| anyhow!("no type named {:?}", t1t))?; - let t2 = t2d - .typename(&witx::Id::new(t2t)) - .ok_or_else(|| anyhow!("no type named {:?}", t2t))?; - match (repr, t1.type_().representable(&t2.type_())) { - (RepEquality::Eq, witx::RepEquality::Eq) - | (RepEquality::Superset, witx::RepEquality::Superset) - | (RepEquality::NotEq, witx::RepEquality::NotEq) => {} - (a, b) => { - bail!("expected {:?} representation, got {:?}", a, b); - } - } - } - WitxtDirective::AssertAbi { - witx, - wasm, - interface, - wasm_signature: (wasm_params, wasm_results), - .. - } => { - let doc = witx.document(contents, test)?; - let module = doc.modules().next().ok_or_else(|| anyhow!("no modules"))?; - let func = module.funcs().next().ok_or_else(|| anyhow!("no funcs"))?; - - let (params, results) = func.wasm_signature(); - if params != wasm_params { - bail!("expected params {:?}, found {:?}", wasm_params, params); - } - if results != wasm_results { - bail!("expected results {:?}, found {:?}", wasm_results, results); - } - - let mut check = AbiBindgen { - abi: wasm.instrs.iter(), - err: None, - contents, - }; - func.call_wasm(&module.name, &mut check); - check.check()?; - check.abi = interface.instrs.iter(); - func.call_interface(&module.name, &mut check); - check.check()?; - } - } - Ok(()) - } - - fn assert_roundtrip(&self, doc: &witx::Document) -> Result<()> { - self.bump_ntests(); - let back_to_sexprs = format!("{}", doc); - let doc2 = witx::parse(&back_to_sexprs)?; - if *doc == doc2 { - return Ok(()); - } - - // Try to get a more specific error message that isn't thousands of - // lines long of debug representations. - for type_ in doc.typenames() { - let type2 = match doc2.typename(&type_.name) { - Some(t) => t, - None => bail!("doc2 missing datatype"), - }; - if type_ != type2 { - bail!("types are not equal\n{:?}\n !=\n{:?}", type_, type2); - } - } - for mod_ in doc.modules() { - let mod2 = match doc2.module(&mod_.name) { - Some(m) => m, - None => bail!("doc2 missing module"), - }; - for import in mod_.imports() { - let import2 = match mod2.import(&import.name) { - Some(i) => i, - None => bail!("mod2 missing import"), - }; - assert_eq!(import, import2); - } - for func in mod_.funcs() { - let func2 = match mod2.func(&func.name) { - Some(f) => f, - None => bail!("mod2 missing func"), - }; - assert_eq!(func, func2); - } - } - bail!("{:?} != {:?}", doc, doc2) - } - - fn assert_md(&self, doc: &witx::Document) -> Result<()> { - self.bump_ntests(); - doc.to_md(); - Ok(()) - } - - fn bump_ntests(&self) { - self.ntests.fetch_add(1, SeqCst); - } -} - -struct AbiBindgen<'a> { - abi: std::slice::Iter<'a, (wast::Span, &'a str)>, - err: Option, - contents: &'a str, -} - -impl AbiBindgen<'_> { - fn check(&mut self) -> Result<()> { - match self.err.take() { - None => Ok(()), - Some(e) => Err(e), - } - } - - fn assert(&mut self, name: &str) { - if self.err.is_some() { - return; - } - match self.abi.next() { - Some((_, s)) if *s == name => {} - Some((span, s)) => { - let (line, col) = span.linecol_in(self.contents); - self.err = Some(anyhow!( - "line {}:{} - expected `{}` found `{}`", - line + 1, - col + 1, - name, - s, - )); - } - None => { - self.err = Some(anyhow!( - "extra instruction `{}` found when none was expected", - name - )); - } - } - } -} - -impl witx::Bindgen for AbiBindgen<'_> { - type Operand = (); - fn emit( - &mut self, - inst: &Instruction<'_>, - _operands: &mut Vec, - results: &mut Vec, - ) { - use witx::Instruction::*; - match inst { - GetArg { nth } => self.assert(&format!("get-arg{}", nth)), - AddrOf => self.assert("addr-of"), - I32FromChar => self.assert("i32.from_char"), - I64FromU64 => self.assert("i64.from_u64"), - I64FromS64 => self.assert("i64.from_s64"), - I32FromU32 => self.assert("i32.from_u32"), - I32FromS32 => self.assert("i32.from_s32"), - I32FromUsize => self.assert("i32.from_usize"), - I32FromU16 => self.assert("i32.from_u16"), - I32FromS16 => self.assert("i32.from_s16"), - I32FromU8 => self.assert("i32.from_u8"), - I32FromS8 => self.assert("i32.from_s8"), - I32FromChar8 => self.assert("i32.from_char8"), - I32FromPointer => self.assert("i32.from_pointer"), - I32FromConstPointer => self.assert("i32.from_const_pointer"), - I32FromHandle { .. } => self.assert("i32.from_handle"), - ListPointerLength => self.assert("list.pointer_length"), - ListFromPointerLength { .. } => self.assert("list.from_pointer_length"), - F32FromIf32 => self.assert("f32.from_if32"), - F64FromIf64 => self.assert("f64.from_if64"), - CallWasm { .. } => self.assert("call.wasm"), - CallInterface { .. } => self.assert("call.interface"), - S8FromI32 => self.assert("s8.from_i32"), - U8FromI32 => self.assert("u8.from_i32"), - S16FromI32 => self.assert("s16.from_i32"), - U16FromI32 => self.assert("u16.from_i32"), - S32FromI32 => self.assert("s32.from_i32"), - U32FromI32 => self.assert("u32.from_i32"), - S64FromI64 => self.assert("s64.from_i64"), - U64FromI64 => self.assert("u64.from_i64"), - CharFromI32 => self.assert("char.from_i32"), - Char8FromI32 => self.assert("char8.from_i32"), - UsizeFromI32 => self.assert("usize.from_i32"), - If32FromF32 => self.assert("if32.from_f32"), - If64FromF64 => self.assert("if64.from_f64"), - HandleFromI32 { .. } => self.assert("handle.from_i32"), - PointerFromI32 { .. } => self.assert("pointer.from_i32"), - ConstPointerFromI32 { .. } => self.assert("const_pointer.from_i32"), - ReturnPointerGet { n } => self.assert(&format!("return_pointer.get{}", n)), - ResultLift => self.assert("result.lift"), - ResultLower { .. } => self.assert("result.lower"), - EnumLift { .. } => self.assert("enum.lift"), - EnumLower { .. } => self.assert("enum.lower"), - TupleLift { .. } => self.assert("tuple.lift"), - TupleLower { .. } => self.assert("tuple.lower"), - ReuseReturn => self.assert("reuse_return"), - Load { .. } => self.assert("load"), - Store { .. } => self.assert("store"), - Return { .. } => self.assert("return"), - VariantPayload => self.assert("variant-payload"), - I32FromBitflags { .. } => self.assert("i32.from_bitflags"), - BitflagsFromI32 { .. } => self.assert("bitflags.from_i32"), - I64FromBitflags { .. } => self.assert("i64.from_bitflags"), - BitflagsFromI64 { .. } => self.assert("bitflags.from_i64"), - } - for _ in 0..inst.results_len() { - results.push(()); - } - } - - fn allocate_space(&mut self, _: usize, _: &witx::NamedType) { - self.assert("allocate-space"); - } - - fn push_block(&mut self) { - self.assert("block.push"); - } - - fn finish_block(&mut self, _operand: Option) { - self.assert("block.finish"); - } -} - -mod kw { - wast::custom_keyword!(assert_invalid); - wast::custom_keyword!(assert_representable); - wast::custom_keyword!(assert_abi); - wast::custom_keyword!(witx); - wast::custom_keyword!(eq); - wast::custom_keyword!(noteq); - wast::custom_keyword!(load); - wast::custom_keyword!(superset); - wast::custom_keyword!(call_wasm); - wast::custom_keyword!(call_interface); - wast::custom_keyword!(param); - wast::custom_keyword!(result); - wast::custom_keyword!(wasm); - wast::custom_keyword!(i32); - wast::custom_keyword!(i64); - wast::custom_keyword!(f32); - wast::custom_keyword!(f64); -} - -struct Witxt<'a> { - directives: Vec>, -} - -impl<'a> Parse<'a> for Witxt<'a> { - fn parse(parser: Parser<'a>) -> parser::Result { - let mut directives = Vec::new(); - while !parser.is_empty() { - directives.push(parser.parens(|p| p.parse())?); - } - Ok(Witxt { directives }) - } -} - -enum WitxtDirective<'a> { - Witx(Witx<'a>), - AssertInvalid { - span: wast::Span, - witx: Witx<'a>, - message: &'a str, - }, - AssertRepresentable { - span: wast::Span, - repr: RepEquality, - t1: (wast::Id<'a>, &'a str), - t2: (wast::Id<'a>, &'a str), - }, - AssertAbi { - span: wast::Span, - witx: Witx<'a>, - wasm_signature: (Vec, Vec), - wasm: Abi<'a>, - interface: Abi<'a>, - }, -} - -impl WitxtDirective<'_> { - fn span(&self) -> wast::Span { - match self { - WitxtDirective::Witx(w) => w.span, - WitxtDirective::AssertInvalid { span, .. } - | WitxtDirective::AssertAbi { span, .. } - | WitxtDirective::AssertRepresentable { span, .. } => *span, - } - } -} - -impl<'a> Parse<'a> for WitxtDirective<'a> { - fn parse(parser: Parser<'a>) -> parser::Result { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(WitxtDirective::Witx(parser.parse()?)) - } else if l.peek::() { - let span = parser.parse::()?.0; - Ok(WitxtDirective::AssertInvalid { - span, - witx: parser.parens(|p| p.parse())?, - message: parser.parse()?, - }) - } else if l.peek::() { - let span = parser.parse::()?.0; - Ok(WitxtDirective::AssertRepresentable { - span, - repr: parser.parse()?, - t1: (parser.parse()?, parser.parse()?), - t2: (parser.parse()?, parser.parse()?), - }) - } else if l.peek::() { - let span = parser.parse::()?.0; - Ok(WitxtDirective::AssertAbi { - span, - witx: parser.parens(|p| p.parse())?, - wasm_signature: parser.parens(|p| { - p.parse::()?; - let mut params = Vec::new(); - let mut results = Vec::new(); - if p.peek2::() { - p.parens(|p| { - p.parse::()?; - while !p.is_empty() { - params.push(parse_wasmtype(p)?); - } - Ok(()) - })?; - } - if p.peek2::() { - p.parens(|p| { - p.parse::()?; - while !p.is_empty() { - results.push(parse_wasmtype(p)?); - } - Ok(()) - })?; - } - Ok((params, results)) - })?, - wasm: parser.parens(|p| { - p.parse::()?; - p.parse() - })?, - interface: parser.parens(|p| { - p.parse::()?; - p.parse() - })?, - }) - } else { - Err(l.error()) - } - } -} - -fn parse_wasmtype(p: Parser<'_>) -> parser::Result { - let mut l = p.lookahead1(); - if l.peek::() { - p.parse::()?; - Ok(WasmType::I32) - } else if l.peek::() { - p.parse::()?; - Ok(WasmType::I64) - } else if l.peek::() { - p.parse::()?; - Ok(WasmType::F32) - } else if l.peek::() { - p.parse::()?; - Ok(WasmType::F64) - } else { - Err(l.error()) - } -} - -struct Witx<'a> { - span: wast::Span, - id: Option>, - def: WitxDef<'a>, -} - -enum WitxDef<'a> { - Fs(Vec<&'a str>), - Inline(Vec>>), -} - -impl Witx<'_> { - fn document(&self, contents: &str, file: &Path) -> Result { - match &self.def { - WitxDef::Inline(decls) => { - let mut validator = witx::DocValidation::new(); - let mut definitions = Vec::new(); - for decl in decls { - validator - .scope(contents, file) - .validate_decl(&decl.item, &decl.comments, &mut definitions) - .map_err(witx::WitxError::Validation)?; - } - Ok(validator.into_document(definitions)) - } - WitxDef::Fs(paths) => { - let parent = file.parent().unwrap(); - let paths = paths.iter().map(|p| parent.join(p)).collect::>(); - Ok(witx::load(&paths)?) - } - } - } -} - -impl<'a> Parse<'a> for Witx<'a> { - fn parse(parser: Parser<'a>) -> parser::Result { - let span = parser.parse::()?.0; - let id = parser.parse()?; - - let def = if parser.peek2::() { - parser.parens(|p| { - p.parse::()?; - let mut paths = Vec::new(); - while !p.is_empty() { - paths.push(p.parse()?); - } - Ok(WitxDef::Fs(paths)) - })? - } else { - let mut decls = Vec::new(); - while !parser.is_empty() { - decls.push(parser.parens(|p| p.parse())?); - } - WitxDef::Inline(decls) - }; - Ok(Witx { id, span, def }) - } -} - -#[derive(Debug)] -enum RepEquality { - Eq, - NotEq, - Superset, -} - -impl<'a> Parse<'a> for RepEquality { - fn parse(parser: Parser<'a>) -> parser::Result { - let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(RepEquality::Eq) - } else if l.peek::() { - parser.parse::()?; - Ok(RepEquality::NotEq) - } else if l.peek::() { - parser.parse::()?; - Ok(RepEquality::Superset) - } else { - Err(l.error()) - } - } -} - -struct Abi<'a> { - instrs: Vec<(wast::Span, &'a str)>, -} - -impl<'a> Parse<'a> for Abi<'a> { - fn parse(parser: Parser<'a>) -> parser::Result { - let mut instrs = Vec::new(); - while !parser.is_empty() { - instrs.push(parser.step(|cursor| { - let (kw, next) = cursor - .keyword() - .ok_or_else(|| cursor.error("expected keyword"))?; - Ok(((cursor.cur_span(), kw), next)) - })?); - } - Ok(Abi { instrs }) - } -} diff --git a/proposals/clocks/tools/witx/tests/witxt/abi.witxt b/proposals/clocks/tools/witx/tests/witxt/abi.witxt deleted file mode 100644 index ccdad7bf4..000000000 --- a/proposals/clocks/tools/witx/tests/witxt/abi.witxt +++ /dev/null @@ -1,490 +0,0 @@ -(assert_abi - (witx (module $x (@interface func (export "f")))) - (wasm) - (call_wasm call.wasm return) - (call_interface call.interface return) -) - -;; scalar arguments -(assert_abi - (witx (module $x (@interface func (export "f") (param $p u8)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_u8 call.wasm return) - (call_interface get-arg0 u8.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p s8)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_s8 call.wasm return) - (call_interface get-arg0 s8.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p u16)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_u16 call.wasm return) - (call_interface get-arg0 u16.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p s16)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_s16 call.wasm return) - (call_interface get-arg0 s16.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p u32)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_u32 call.wasm return) - (call_interface get-arg0 u32.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p s32)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_s32 call.wasm return) - (call_interface get-arg0 s32.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p u64)))) - (wasm (param i64)) - (call_wasm get-arg0 i64.from_u64 call.wasm return) - (call_interface get-arg0 u64.from_i64 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p s64)))) - (wasm (param i64)) - (call_wasm get-arg0 i64.from_s64 call.wasm return) - (call_interface get-arg0 s64.from_i64 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p f32)))) - (wasm (param f32)) - (call_wasm get-arg0 f32.from_if32 call.wasm return) - (call_interface get-arg0 if32.from_f32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p f64)))) - (wasm (param f64)) - (call_wasm get-arg0 f64.from_if64 call.wasm return) - (call_interface get-arg0 if64.from_f64 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p (@witx usize))))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_usize call.wasm return) - (call_interface get-arg0 usize.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p (@witx char8))))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_char8 call.wasm return) - (call_interface get-arg0 char8.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p char)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_char call.wasm return) - (call_interface get-arg0 char.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p (@witx pointer u8))))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_pointer call.wasm return) - (call_interface get-arg0 pointer.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p (@witx const_pointer u8))))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_const_pointer call.wasm return) - (call_interface get-arg0 const_pointer.from_i32 call.interface return) -) - -;; flags parameter -(assert_abi - (witx - (typename $a (flags $x $y)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_bitflags call.wasm return) - (call_interface get-arg0 bitflags.from_i32 call.interface return) -) -(assert_abi - (witx - (typename $a (flags (@witx repr u64) $x $y)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i64)) - (call_wasm get-arg0 i64.from_bitflags call.wasm return) - (call_interface get-arg0 bitflags.from_i64 call.interface return) -) - -;; struct parameter -(assert_abi - (witx - (typename $a (record (field $x u8))) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 addr-of call.wasm return) - (call_interface get-arg0 load call.interface return) -) - -;; handle parameter -(assert_abi - (witx - (typename $a (handle)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_handle call.wasm return) - (call_interface get-arg0 handle.from_i32 call.interface return) -) - -;; list parameter -(assert_abi - (witx - (module $x (@interface func (export "f") (param $p (list u8)))) - ) - (wasm (param i32 i32)) - (call_wasm get-arg0 list.pointer_length call.wasm return) - (call_interface get-arg0 get-arg1 list.from_pointer_length call.interface return) -) - -;; variant parameter -- some not allowed at this time -(assert_abi - (witx - (typename $a (enum $b)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 enum.lower call.wasm return) - (call_interface get-arg0 enum.lift call.interface return) -) -(assert_abi - (witx - (typename $a (union f32)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 addr-of call.wasm return) - (call_interface get-arg0 load call.interface return) -) - -;; scalar returns -(assert_abi - (witx (module $x (@interface func (export "f") (result $p u8)))) - (wasm (result i32)) - (call_wasm call.wasm u8.from_i32 return) - (call_interface call.interface i32.from_u8 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p s8)))) - (wasm (result i32)) - (call_wasm call.wasm s8.from_i32 return) - (call_interface call.interface i32.from_s8 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p u16)))) - (wasm (result i32)) - (call_wasm call.wasm u16.from_i32 return) - (call_interface call.interface i32.from_u16 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p s16)))) - (wasm (result i32)) - (call_wasm call.wasm s16.from_i32 return) - (call_interface call.interface i32.from_s16 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p u32)))) - (wasm (result i32)) - (call_wasm call.wasm u32.from_i32 return) - (call_interface call.interface i32.from_u32 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p s32)))) - (wasm (result i32)) - (call_wasm call.wasm s32.from_i32 return) - (call_interface call.interface i32.from_s32 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p u64)))) - (wasm (result i64)) - (call_wasm call.wasm u64.from_i64 return) - (call_interface call.interface i64.from_u64 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p s64)))) - (wasm (result i64)) - (call_wasm call.wasm s64.from_i64 return) - (call_interface call.interface i64.from_s64 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p f32)))) - (wasm (result f32)) - (call_wasm call.wasm if32.from_f32 return) - (call_interface call.interface f32.from_if32 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p f64)))) - (wasm (result f64)) - (call_wasm call.wasm if64.from_f64 return) - (call_interface call.interface f64.from_if64 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p (@witx usize))))) - (wasm (result i32)) - (call_wasm call.wasm usize.from_i32 return) - (call_interface call.interface i32.from_usize return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p (@witx char8))))) - (wasm (result i32)) - (call_wasm call.wasm char8.from_i32 return) - (call_interface call.interface i32.from_char8 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p char)))) - (wasm (result i32)) - (call_wasm call.wasm char.from_i32 return) - (call_interface call.interface i32.from_char return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p (@witx pointer u8))))) - (wasm (result i32)) - (call_wasm call.wasm pointer.from_i32 return) - (call_interface call.interface i32.from_pointer return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p (@witx const_pointer u8))))) - (wasm (result i32)) - (call_wasm call.wasm const_pointer.from_i32 return) - (call_interface call.interface i32.from_const_pointer return) -) - -;; flags return -(assert_abi - (witx - (typename $a (flags $x $y)) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (result i32)) - (call_wasm call.wasm bitflags.from_i32 return) - (call_interface call.interface i32.from_bitflags return) -) -(assert_abi - (witx - (typename $a (flags (@witx repr u64) $x $y)) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (result i64)) - (call_wasm call.wasm bitflags.from_i64 return) - (call_interface call.interface i64.from_bitflags return) -) - -;; handle return -(assert_abi - (witx - (typename $a (handle)) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (result i32)) - (call_wasm call.wasm handle.from_i32 return) - (call_interface call.interface i32.from_handle return) -) - -;; struct return -- not supported -(assert_invalid - (witx - (typename $a (record (field $x u8))) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: invalid return type" -) - -;; list return -- not supported -(assert_invalid - (witx - (module $x (@interface func (export "f") (result $p (list u8)))) - ) - "ABI error: invalid return type" -) - -;; variant return -- only some allowed -(assert_invalid - (witx - (typename $a (enum $b)) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: invalid return type" -) -(assert_invalid - (witx - (typename $a (union s32 f32)) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: invalid return type" -) -(assert_invalid - (witx - (typename $a (expected (error f32))) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: only named types are allowed in results" -) -(assert_invalid - (witx - (typename $errno (enum $success $bad)) - (typename $a (expected f32 (error $errno))) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: only named types are allowed in results" -) - -;; Result<(), $errno> -(assert_abi - (witx - (typename $errno (enum $success $bad)) - (typename $a (expected (error $errno))) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (result i32)) - - (call_wasm - call.wasm - ;; ok block, nothing happens - block.push - block.finish - ;; err block, we lift the return value as the num - block.push - reuse_return - enum.lift - block.finish - ;; consumes 2 blocks and uses the return value of the call to discriminate - result.lift - return) - - (call_interface - call.interface - - ;; ok block, nothing happens - block.push - block.finish - - ;; err block, lift the enum - block.push - variant-payload - enum.lower - block.finish - - ;; consume the 2 blocks and lower based on the call - result.lower - return) -) - -;; Result<$ty, $errno> -(assert_abi - (witx - (typename $errno (enum $success $bad)) - (typename $size u32) - (typename $a (expected $size (error $errno))) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (param i32) (result i32)) - - (call_wasm - ;; make space for the return value and push its pointer - allocate-space - return_pointer.get0 - - call.wasm - - ;; ok block, load the return pointer and have it be the result for the `Ok` - block.push - return_pointer.get0 - load - block.finish - - block.push - reuse_return - enum.lift - block.finish - - result.lift - return) - - (call_interface - call.interface - - ;; store the successful result at the first return pointer (the first param) - block.push - variant-payload - get-arg0 - store - block.finish - - block.push - variant-payload - enum.lower - block.finish - - result.lower - return) -) - -;; Result<($a, $b), $errno> -(assert_abi - (witx - (typename $errno (enum $success $bad)) - (typename $size u32) - (typename $other (record (field $a $size))) - (module $x (@interface func (export "f") - (result $p (expected (tuple $size $other) (error $errno))))) - ) - (wasm (param i32 i32) (result i32)) - - (call_wasm - allocate-space - return_pointer.get0 - allocate-space - return_pointer.get1 - - call.wasm - - block.push - return_pointer.get0 - load - return_pointer.get1 - load - tuple.lift - block.finish - - block.push - reuse_return - enum.lift - block.finish - - result.lift - return) - - (call_interface - call.interface - - ;; note the reverse order since we're consuming the results of lowering the - ;; tuple - block.push - variant-payload - tuple.lower - get-arg1 - store - get-arg0 - store - block.finish - - block.push - variant-payload - enum.lower - block.finish - - result.lower - return) -) diff --git a/proposals/clocks/tools/witx/tests/witxt/anonymous.witxt b/proposals/clocks/tools/witx/tests/witxt/anonymous.witxt deleted file mode 100644 index 0ed3bc0d2..000000000 --- a/proposals/clocks/tools/witx/tests/witxt/anonymous.witxt +++ /dev/null @@ -1,56 +0,0 @@ -;; Ensure that anonymous structured types are not allowed in type positions at -;; this time, everything has to be named to assist in binding in languages. - -(assert_invalid - (witx - (typename $a (@witx pointer (record (field $b u8)))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (@witx pointer (union))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (@witx pointer (enum $b))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (@witx pointer (flags $b))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (@witx pointer (handle))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (record (field $b (record (field $c u8))))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $tag (enum $c)) - (typename $a (record (field $b (union)))) - ) - "Anonymous structured types") - - -;; pointers don't count for anonymous indirections -(witx - (typename $a (@witx pointer u8))) - -(witx - (typename $a (@witx pointer (@witx const_pointer u8)))) - -(witx - (typename $a (record (field $b (@witx pointer u8))))) diff --git a/proposals/clocks/tools/witx/tests/witxt/multimodule.witxt b/proposals/clocks/tools/witx/tests/witxt/multimodule.witxt deleted file mode 100644 index d8b6559ac..000000000 --- a/proposals/clocks/tools/witx/tests/witxt/multimodule.witxt +++ /dev/null @@ -1,22 +0,0 @@ -;; B uses A, and C uses A. -(witx $multi - (load "multimodule/type_b.witx" "multimodule/type_c.witx") -) - -(witx $reference - (typename $a u32) - (typename $b (record (field $member_a $a))) - (typename $c (record (field $first_a $a) (field $second_a $a))) -) - -(assert_representable eq $reference "a" $multi "a") -(assert_representable eq $reference "b" $multi "b") -(assert_representable eq $reference "c" $multi "c") - -(assert_invalid - (witx - (load - "multimodule/type_a.witx" - "multimodule/redefine_a.witx") - ) - "Redefinition of name `a`") diff --git a/proposals/clocks/tools/witx/tests/witxt/multimodule/redefine_a.witx b/proposals/clocks/tools/witx/tests/witxt/multimodule/redefine_a.witx deleted file mode 100644 index e5d99d82c..000000000 --- a/proposals/clocks/tools/witx/tests/witxt/multimodule/redefine_a.witx +++ /dev/null @@ -1 +0,0 @@ -(typename $a u8) diff --git a/proposals/clocks/tools/witx/tests/witxt/multimodule/type_a.witx b/proposals/clocks/tools/witx/tests/witxt/multimodule/type_a.witx deleted file mode 100644 index 5499ff3db..000000000 --- a/proposals/clocks/tools/witx/tests/witxt/multimodule/type_a.witx +++ /dev/null @@ -1 +0,0 @@ -(typename $a u32) diff --git a/proposals/clocks/tools/witx/tests/witxt/multimodule/type_b.witx b/proposals/clocks/tools/witx/tests/witxt/multimodule/type_b.witx deleted file mode 100644 index fe169d3ec..000000000 --- a/proposals/clocks/tools/witx/tests/witxt/multimodule/type_b.witx +++ /dev/null @@ -1,2 +0,0 @@ -(use "type_a.witx") -(typename $b (record (field $member_a $a))) diff --git a/proposals/clocks/tools/witx/tests/witxt/multimodule/type_c.witx b/proposals/clocks/tools/witx/tests/witxt/multimodule/type_c.witx deleted file mode 100644 index f42aac2d0..000000000 --- a/proposals/clocks/tools/witx/tests/witxt/multimodule/type_c.witx +++ /dev/null @@ -1,2 +0,0 @@ -(use "type_a.witx") -(typename $c (record (field $first_a $a) (field $second_a $a))) diff --git a/proposals/clocks/tools/witx/tests/witxt/representation.witxt b/proposals/clocks/tools/witx/tests/witxt/representation.witxt deleted file mode 100644 index 53f71f196..000000000 --- a/proposals/clocks/tools/witx/tests/witxt/representation.witxt +++ /dev/null @@ -1,60 +0,0 @@ -;; type names don't matter -(witx $a - (typename $a (flags (@witx repr u8) $b $c))) -(witx $b - (typename $b (flags (@witx repr u8) $b $c))) - -(assert_representable eq $a "a" $b "b") -(assert_representable eq $b "b" $a "a") - -(; TODO: perhaps add assertions eventually for document-level representability? -;; flags -(witx $a - (typename $a (flags (@witx bitflags u8) $b $c))) -(witx $b - (typename $b (flags (@witx bitflags u8) $b $c $d))) - -(assert_representable noteq $b "b" $a "a") -(assert_representable superset $a "a" $b "b") - -(witx $c - (typename $c (flags (@witx bitflags u8) $b $e))) -(assert_representable noteq $a "a" $c "c") -(assert_representable noteq $c "c" $a "a") - -(witx $d - (typename $d (flags (@witx bitflags u16) $b $c))) -(assert_representable noteq $a "a" $d "d") -(assert_representable superset $d "d" $a "a") -(assert_representable superset $d "d" $b "b") -;) - -;; enums -(witx $a - (typename $a (enum $b $c))) -(witx $b - (typename $b (enum $b $c $d))) -(assert_representable superset $a "a" $b "b") -(assert_representable noteq $b "b" $a "a") - -(witx $c - (typename $c (enum (@witx tag u16) $b $c))) -(assert_representable superset $c "c" $a "a") -(assert_representable superset $c "c" $b "b") - -;; unions -(witx $a - (typename $tag (enum $b $c)) - (typename $a (union (@witx tag $tag) u32 f32))) -(witx $b - (typename $tag (enum $b $c $d)) - (typename $b (union (@witx tag $tag) u32 f32 f64))) -(assert_representable superset $a "a" $b "b") -(assert_representable noteq $b "b" $a "a") - -(witx $c - (typename $tag (enum $b $c)) - (typename $c (variant (@witx tag $tag) (case $c f32) (case $b u32)))) -(assert_representable eq $a "a" $c "c") -(assert_representable eq $c "c" $a "a") -(assert_representable superset $c "c" $b "b") diff --git a/proposals/clocks/tools/witx/tests/witxt/shorthand.witxt b/proposals/clocks/tools/witx/tests/witxt/shorthand.witxt deleted file mode 100644 index 960615f3c..000000000 --- a/proposals/clocks/tools/witx/tests/witxt/shorthand.witxt +++ /dev/null @@ -1,59 +0,0 @@ -(witx $a - (typename $a bool)) -(witx $b - (typename $a (variant (case $false) (case $true)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (expected (error)))) -(witx $b - (typename $a (variant (case $ok) (case $err)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (expected (error u32)))) -(witx $b - (typename $a (variant (case $ok) (case $err u32)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (expected u32 (error)))) -(witx $b - (typename $a (variant (case $ok u32) (case $err)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (expected u32 (error u64)))) -(witx $b - (typename $a (variant (case $ok u32) (case $err u64)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (flags $a $b))) -(witx $b - (typename $a (record (field $a bool) (field $b bool)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (enum $a $b))) -(witx $b - (typename $a (variant (case $a) (case $b)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a string)) -(witx $b - (typename $a (list char))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (tuple u32 u64))) -(witx $b - (typename $a (record (field $0 u32) (field $1 u64)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (union u32 u64))) -(witx $b - (typename $a (variant (case $0 u32) (case $1 u64)))) -(assert_representable eq $a "a" $b "a") diff --git a/proposals/clocks/tools/witx/tests/witxt/simple.witxt b/proposals/clocks/tools/witx/tests/witxt/simple.witxt deleted file mode 100644 index af2403043..000000000 --- a/proposals/clocks/tools/witx/tests/witxt/simple.witxt +++ /dev/null @@ -1,12 +0,0 @@ -(witx) - -(witx - (typename $x u32) -) - -(assert_invalid - (witx - (typename $x u32) - (typename $x u32) - ) - "Redefinition of name `x`") diff --git a/proposals/clocks/tools/witx/tests/witxt/union.witxt b/proposals/clocks/tools/witx/tests/witxt/union.witxt deleted file mode 100644 index 92be3dcd9..000000000 --- a/proposals/clocks/tools/witx/tests/witxt/union.witxt +++ /dev/null @@ -1,97 +0,0 @@ - -(witx - (typename $u (union u8)) -) -(witx - (typename $tag (enum (@witx tag u8) $c)) - (typename $u (union (@witx tag $tag) u8)) -) - -(witx - (typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $a) (case $b u16))) -) - -(witx - (typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $a) (case $b))) -) - - -(witx - (typename $u - (union - u8 - u16 - u32 - u64 - s8 - s16 - s32 - s64 - f32 - f64 - (@witx usize) - (@witx char8) - ) - ) -) - -(assert_invalid - (witx (typename $u (union (@witx tag $tag) u8 u16))) - "Unknown name `tag`" -) - -(assert_invalid - (witx - (typename $tag string) - (typename $u (union (@witx tag $tag) u8 u16)) - ) - "Wrong kind of name `tag`: expected enum or builtin, got list" -) - -(assert_invalid - (witx - (typename $tag (enum $c)) - (typename $u (variant (@witx tag $tag) (case $b u8))) - ) - "Invalid union field `b`: does not correspond to variant in tag `tag`" -) - -(assert_invalid - (witx - (typename $tag (enum $c)) - (typename $u (union (@witx tag $tag) f32 u8)) - ) - "Union expected 1 variants, found 2" -) - -(assert_invalid - (witx - (typename $tag (enum $c $d)) - (typename $u (union (@witx tag $tag) f32)) - ) - "Union expected 2 variants, found 1" -) - -(witx $d1 - (typename $tag (enum $a $b)) - (typename $u (union (@witx tag $tag) u8 u16)) -) - -(witx $d2 - (typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $b u16) (case $a u8))) -) - -;; These two unions should be represented the same: -(assert_representable eq $d1 "u" $d2 "u") -(assert_representable eq $d2 "u" $d1 "u") - -;; Tag order doesnt matter for validation, but does for rep equality -(witx $d3 - (typename $tag (enum $b $a)) - (typename $u (union (@witx tag $tag) u16 u8)) -) - -(assert_representable noteq $d3 "u" $d1 "u") diff --git a/proposals/clocks/tools/witx/tests/witxt/wasi.witxt b/proposals/clocks/tools/witx/tests/witxt/wasi.witxt deleted file mode 100644 index f654a7ee3..000000000 --- a/proposals/clocks/tools/witx/tests/witxt/wasi.witxt +++ /dev/null @@ -1,26 +0,0 @@ -;; Ensure that all current witx definitions in this repository load, parse, -;; roundtrip, and are documentable. - -(witx - (load "../../../../phases/old/snapshot_0/witx/wasi_unstable.witx")) -(witx - (load "../../../../phases/snapshot/witx/wasi_snapshot_preview1.witx")) - -(witx - (load - "../../../../phases/ephemeral/witx/wasi_ephemeral_args.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_clock.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_environ.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_fd.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_path.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_poll.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_proc.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_random.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_sched.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_sock.witx" - ) -) -;; should be singularly-loadable as well -(witx - (load - "../../../../phases/ephemeral/witx/wasi_ephemeral_fd.witx")) diff --git a/proposals/clocks/wasi-clocks.abi.md b/proposals/clocks/wasi-clocks.abi.md new file mode 100644 index 000000000..e69de29bb diff --git a/proposals/clocks/wasi-clocks.wit.md b/proposals/clocks/wasi-clocks.wit.md new file mode 100644 index 000000000..f8b2ea1ec --- /dev/null +++ b/proposals/clocks/wasi-clocks.wit.md @@ -0,0 +1,81 @@ +# WASI Clocks API + +WASI Clocks is a clock API intended to let users query the current time and +to measure elapsed time. + +It is intended to be portable at least between Unix-family platforms and +Windows. + +## `instant` +```wit +/// A timestamp in nanoseconds. +type instant = u64 +``` + +## `datetime` +```wit +/// A time and date in seconds plus nanoseconds since 1970-01-01T00:00:00Z. +record datetime { + seconds: u64, + nanoseconds: u32, +} +``` + +## `monotonic_clock` +```wit +/// A monotonic clock is a clock which has an unspecified initial value, and +/// successive reads of the clock will produce non-decreasing values. +/// +/// It is intended for measuring elapsed time. +resource monotonic_clock { +``` + +## `now` +/// Read the current value of the clock. +/// +/// As this the clock is monotonic, calling this function repeatedly will produce +/// a sequence of non-decreasing values. +```wit +now: function() -> instant +``` + +## `resolution` +/// Query the resolution of the clock. +```wit +resolution: function() -> instant +``` + +```wit +} +``` + +## `wall_clock` +```wit +/// A wall clock is a clock which measures the date and time according to some +/// external reference. +/// +/// External references may be reset, so this clock is not necessarily +/// monotonic, making it unsuitable for measuring elapsed time. +/// +/// It is intended for reporting the current date and time for humans. +resource wall_clock { +``` + +## `now` +/// Read the current value of the clock. +/// +/// As this the clock is not monotonic, calling this function repeatedly will +/// not necessarily produce a sequence of non-decreasing values. +```wit +now: function() -> datetime +``` + +## `resolution` +/// Query the resolution of the clock. +```wit +resolution: function() -> datetime +``` + +```wit +} +``` From de2551d68cef20fd4bc1a4741ea93dbf856c4972 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 28 Apr 2022 14:40:17 -0700 Subject: [PATCH 0949/1772] Port the wasi-random API to the new wit format. This converts the wasi-random repository to the new [proposal template] format. It also includes a number of minor updates: - It fixes #6, - It fixes #8, by eliminating the use of errno error codes. - It addresses #3, #10, and #11 by proposing they be out of scope for the current proposal; see those issues for discussion. [proposal template]: https://github.com/linclark/wasi-proposal-template --- proposals/random/.github/workflows/main.yml | 53 +- proposals/random/.gitignore | 11 - proposals/random/Charter.md | 55 - proposals/random/Contributing.md | 8 - proposals/random/README.md | 199 +- proposals/random/WASI.png | Bin 11059 -> 0 bytes proposals/random/design/application-abi.md | 60 - proposals/random/design/optional-imports.md | 108 - proposals/random/docs/DesignPrinciples.md | 291 -- proposals/random/docs/HighLevelGoals.md | 25 - proposals/random/docs/Process.md | 37 - proposals/random/docs/Proposals.md | 64 - proposals/random/docs/README.md | 15 - proposals/random/docs/WASI-overview.md | 147 - .../docs/wasi-software-architecture.png | Bin 28267 -> 0 bytes proposals/random/docs/witx.md | 30 - proposals/random/meetings/2019/WASI-05-02.md | 377 --- proposals/random/meetings/2019/WASI-05-16.md | 291 -- proposals/random/meetings/2019/WASI-05-30.md | 116 - proposals/random/meetings/2019/WASI-06-27.md | 241 -- proposals/random/meetings/2019/WASI-07-18.md | 262 -- proposals/random/meetings/2019/WASI-08-15.md | 121 - proposals/random/meetings/2019/WASI-08-30.md | 64 - proposals/random/meetings/2019/WASI-09-12.md | 92 - proposals/random/meetings/2019/WASI-09-26.md | 60 - proposals/random/meetings/2019/WASI-10-15.md | 116 - proposals/random/meetings/2019/WASI-10-24.md | 171 -- proposals/random/meetings/2019/WASI-11-07.md | 102 - proposals/random/meetings/2019/WASI-11-21.md | 63 - proposals/random/meetings/2019/WASI-12-05.md | 124 - proposals/random/meetings/2019/WASI-12-19.md | 44 - .../2019/What HTTP Needs from WebAssembly.pdf | Bin 82687 -> 0 bytes proposals/random/meetings/2020/WASI-01-16.md | 123 - proposals/random/meetings/2020/WASI-02-27.md | 92 - proposals/random/meetings/2020/WASI-03-12.md | 85 - proposals/random/meetings/2020/WASI-03-26.md | 126 - proposals/random/meetings/2020/WASI-04-09.md | 83 - proposals/random/meetings/2020/WASI-05-07.md | 89 - proposals/random/meetings/2020/WASI-05-21.md | 99 - proposals/random/meetings/2020/WASI-06-04.md | 43 - proposals/random/meetings/2020/WASI-07-02.md | 41 - proposals/random/meetings/2020/WASI-07-16.md | 41 - proposals/random/meetings/2020/WASI-07-30.md | 36 - proposals/random/meetings/2020/WASI-08-27.md | 42 - proposals/random/meetings/2020/WASI-09-10.md | 33 - proposals/random/meetings/2020/WASI-09-24.md | 30 - proposals/random/meetings/2020/WASI-10-08.md | 42 - proposals/random/meetings/2020/WASI-10-22.md | 211 -- proposals/random/meetings/2020/WASI-11-19.md | 153 - proposals/random/meetings/2020/WASI-12-03.md | 130 - proposals/random/meetings/2021/WASI-01-14.md | 75 - proposals/random/meetings/2021/WASI-01-28.md | 206 -- proposals/random/meetings/2021/WASI-02-11.md | 118 - proposals/random/meetings/2021/WASI-02-25.md | 131 - proposals/random/meetings/2021/WASI-03-11.md | 32 - proposals/random/meetings/2021/WASI-03-25.md | 31 - proposals/random/meetings/2021/WASI-04-08.md | 31 - proposals/random/meetings/2021/WASI-04-22.md | 31 - proposals/random/meetings/2021/WASI-05-06.md | 31 - proposals/random/meetings/2021/WASI-05-20.md | 31 - proposals/random/meetings/2021/WASI-06-03.md | 31 - proposals/random/meetings/2021/WASI-06-17.md | 31 - proposals/random/meetings/README.md | 61 - proposals/random/phases/README.md | 50 - proposals/random/phases/ephemeral/docs.md | 2562 ----------------- .../phases/ephemeral/witx/typenames.witx | 708 ----- .../ephemeral/witx/wasi_ephemeral_args.witx | 27 - .../ephemeral/witx/wasi_ephemeral_clock.witx | 35 - .../witx/wasi_ephemeral_environ.witx | 27 - .../ephemeral/witx/wasi_ephemeral_fd.witx | 259 -- .../ephemeral/witx/wasi_ephemeral_path.witx | 181 -- .../ephemeral/witx/wasi_ephemeral_poll.witx | 27 - .../ephemeral/witx/wasi_ephemeral_proc.witx | 22 - .../ephemeral/witx/wasi_ephemeral_random.witx | 26 - .../ephemeral/witx/wasi_ephemeral_sched.witx | 16 - .../ephemeral/witx/wasi_ephemeral_sock.witx | 48 - .../random/phases/old/snapshot_0/docs.md | 2512 ---------------- .../phases/old/snapshot_0/witx/typenames.witx | 746 ----- .../old/snapshot_0/witx/wasi_unstable.witx | 513 ---- proposals/random/phases/snapshot/docs.html | 1279 -------- proposals/random/phases/snapshot/docs.md | 2509 ---------------- .../phases/snapshot/witx/typenames.witx | 748 ----- .../snapshot/witx/wasi_snapshot_preview1.witx | 510 ---- proposals/random/proposal-template/README.md | 4 - proposals/random/proposals/README.md | 8 - proposals/random/snapshots/README.md | 5 - proposals/random/snapshots/make-snapshot.sh | 159 - proposals/random/standard/README.md | 12 - proposals/random/standard/wasi-random/docs.md | 1242 -------- .../standard/wasi-random/witx/random.witx | 26 - .../standard/wasi-random/witx/typenames.witx | 708 ----- proposals/random/test/README.md | 11 + proposals/random/tools/repo_docs.sh | 22 - proposals/random/tools/witx/.gitignore | 2 - proposals/random/tools/witx/Cargo.toml | 32 - proposals/random/tools/witx/LICENSE | 13 - proposals/random/tools/witx/cli/Cargo.toml | 25 - proposals/random/tools/witx/cli/src/main.rs | 268 -- proposals/random/tools/witx/src/abi.rs | 925 ------ proposals/random/tools/witx/src/ast.rs | 591 ---- proposals/random/tools/witx/src/docs/ast.rs | 503 ---- proposals/random/tools/witx/src/docs/md.rs | 480 --- proposals/random/tools/witx/src/docs/mod.rs | 87 - proposals/random/tools/witx/src/io.rs | 103 - proposals/random/tools/witx/src/layout.rs | 219 -- proposals/random/tools/witx/src/lib.rs | 97 - proposals/random/tools/witx/src/parser.rs | 778 ----- proposals/random/tools/witx/src/polyfill.rs | 255 -- proposals/random/tools/witx/src/render.rs | 320 -- .../random/tools/witx/src/representation.rs | 161 -- proposals/random/tools/witx/src/toplevel.rs | 166 -- proposals/random/tools/witx/src/validate.rs | 722 ----- proposals/random/tools/witx/tests/witxt.rs | 656 ----- .../random/tools/witx/tests/witxt/abi.witxt | 490 ---- .../tools/witx/tests/witxt/anonymous.witxt | 56 - .../tools/witx/tests/witxt/multimodule.witxt | 22 - .../tests/witxt/multimodule/redefine_a.witx | 1 - .../witx/tests/witxt/multimodule/type_a.witx | 1 - .../witx/tests/witxt/multimodule/type_b.witx | 2 - .../witx/tests/witxt/multimodule/type_c.witx | 2 - .../witx/tests/witxt/representation.witxt | 60 - .../tools/witx/tests/witxt/shorthand.witxt | 59 - .../tools/witx/tests/witxt/simple.witxt | 12 - .../random/tools/witx/tests/witxt/union.witxt | 97 - .../random/tools/witx/tests/witxt/wasi.witxt | 26 - proposals/random/wasi-random.abi.md | 0 proposals/random/wasi-random.wit.md | 12 + 127 files changed, 213 insertions(+), 27718 deletions(-) delete mode 100644 proposals/random/.gitignore delete mode 100644 proposals/random/Charter.md delete mode 100644 proposals/random/Contributing.md delete mode 100644 proposals/random/WASI.png delete mode 100644 proposals/random/design/application-abi.md delete mode 100644 proposals/random/design/optional-imports.md delete mode 100644 proposals/random/docs/DesignPrinciples.md delete mode 100644 proposals/random/docs/HighLevelGoals.md delete mode 100644 proposals/random/docs/Process.md delete mode 100644 proposals/random/docs/Proposals.md delete mode 100644 proposals/random/docs/README.md delete mode 100644 proposals/random/docs/WASI-overview.md delete mode 100644 proposals/random/docs/wasi-software-architecture.png delete mode 100644 proposals/random/docs/witx.md delete mode 100644 proposals/random/meetings/2019/WASI-05-02.md delete mode 100644 proposals/random/meetings/2019/WASI-05-16.md delete mode 100644 proposals/random/meetings/2019/WASI-05-30.md delete mode 100644 proposals/random/meetings/2019/WASI-06-27.md delete mode 100644 proposals/random/meetings/2019/WASI-07-18.md delete mode 100644 proposals/random/meetings/2019/WASI-08-15.md delete mode 100644 proposals/random/meetings/2019/WASI-08-30.md delete mode 100644 proposals/random/meetings/2019/WASI-09-12.md delete mode 100644 proposals/random/meetings/2019/WASI-09-26.md delete mode 100644 proposals/random/meetings/2019/WASI-10-15.md delete mode 100644 proposals/random/meetings/2019/WASI-10-24.md delete mode 100644 proposals/random/meetings/2019/WASI-11-07.md delete mode 100644 proposals/random/meetings/2019/WASI-11-21.md delete mode 100644 proposals/random/meetings/2019/WASI-12-05.md delete mode 100644 proposals/random/meetings/2019/WASI-12-19.md delete mode 100644 proposals/random/meetings/2019/What HTTP Needs from WebAssembly.pdf delete mode 100644 proposals/random/meetings/2020/WASI-01-16.md delete mode 100644 proposals/random/meetings/2020/WASI-02-27.md delete mode 100644 proposals/random/meetings/2020/WASI-03-12.md delete mode 100644 proposals/random/meetings/2020/WASI-03-26.md delete mode 100644 proposals/random/meetings/2020/WASI-04-09.md delete mode 100644 proposals/random/meetings/2020/WASI-05-07.md delete mode 100644 proposals/random/meetings/2020/WASI-05-21.md delete mode 100644 proposals/random/meetings/2020/WASI-06-04.md delete mode 100644 proposals/random/meetings/2020/WASI-07-02.md delete mode 100644 proposals/random/meetings/2020/WASI-07-16.md delete mode 100644 proposals/random/meetings/2020/WASI-07-30.md delete mode 100644 proposals/random/meetings/2020/WASI-08-27.md delete mode 100644 proposals/random/meetings/2020/WASI-09-10.md delete mode 100644 proposals/random/meetings/2020/WASI-09-24.md delete mode 100644 proposals/random/meetings/2020/WASI-10-08.md delete mode 100644 proposals/random/meetings/2020/WASI-10-22.md delete mode 100644 proposals/random/meetings/2020/WASI-11-19.md delete mode 100644 proposals/random/meetings/2020/WASI-12-03.md delete mode 100644 proposals/random/meetings/2021/WASI-01-14.md delete mode 100644 proposals/random/meetings/2021/WASI-01-28.md delete mode 100644 proposals/random/meetings/2021/WASI-02-11.md delete mode 100644 proposals/random/meetings/2021/WASI-02-25.md delete mode 100644 proposals/random/meetings/2021/WASI-03-11.md delete mode 100644 proposals/random/meetings/2021/WASI-03-25.md delete mode 100644 proposals/random/meetings/2021/WASI-04-08.md delete mode 100644 proposals/random/meetings/2021/WASI-04-22.md delete mode 100644 proposals/random/meetings/2021/WASI-05-06.md delete mode 100644 proposals/random/meetings/2021/WASI-05-20.md delete mode 100644 proposals/random/meetings/2021/WASI-06-03.md delete mode 100644 proposals/random/meetings/2021/WASI-06-17.md delete mode 100644 proposals/random/meetings/README.md delete mode 100644 proposals/random/phases/README.md delete mode 100644 proposals/random/phases/ephemeral/docs.md delete mode 100644 proposals/random/phases/ephemeral/witx/typenames.witx delete mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx delete mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx delete mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx delete mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx delete mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx delete mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx delete mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx delete mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx delete mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_sched.witx delete mode 100644 proposals/random/phases/ephemeral/witx/wasi_ephemeral_sock.witx delete mode 100644 proposals/random/phases/old/snapshot_0/docs.md delete mode 100644 proposals/random/phases/old/snapshot_0/witx/typenames.witx delete mode 100644 proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx delete mode 100644 proposals/random/phases/snapshot/docs.html delete mode 100644 proposals/random/phases/snapshot/docs.md delete mode 100644 proposals/random/phases/snapshot/witx/typenames.witx delete mode 100644 proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx delete mode 100644 proposals/random/proposal-template/README.md delete mode 100644 proposals/random/proposals/README.md delete mode 100644 proposals/random/snapshots/README.md delete mode 100755 proposals/random/snapshots/make-snapshot.sh delete mode 100644 proposals/random/standard/README.md delete mode 100644 proposals/random/standard/wasi-random/docs.md delete mode 100644 proposals/random/standard/wasi-random/witx/random.witx delete mode 100644 proposals/random/standard/wasi-random/witx/typenames.witx create mode 100644 proposals/random/test/README.md delete mode 100755 proposals/random/tools/repo_docs.sh delete mode 100644 proposals/random/tools/witx/.gitignore delete mode 100644 proposals/random/tools/witx/Cargo.toml delete mode 100644 proposals/random/tools/witx/LICENSE delete mode 100644 proposals/random/tools/witx/cli/Cargo.toml delete mode 100644 proposals/random/tools/witx/cli/src/main.rs delete mode 100644 proposals/random/tools/witx/src/abi.rs delete mode 100644 proposals/random/tools/witx/src/ast.rs delete mode 100644 proposals/random/tools/witx/src/docs/ast.rs delete mode 100644 proposals/random/tools/witx/src/docs/md.rs delete mode 100644 proposals/random/tools/witx/src/docs/mod.rs delete mode 100644 proposals/random/tools/witx/src/io.rs delete mode 100644 proposals/random/tools/witx/src/layout.rs delete mode 100644 proposals/random/tools/witx/src/lib.rs delete mode 100644 proposals/random/tools/witx/src/parser.rs delete mode 100644 proposals/random/tools/witx/src/polyfill.rs delete mode 100644 proposals/random/tools/witx/src/render.rs delete mode 100644 proposals/random/tools/witx/src/representation.rs delete mode 100644 proposals/random/tools/witx/src/toplevel.rs delete mode 100644 proposals/random/tools/witx/src/validate.rs delete mode 100644 proposals/random/tools/witx/tests/witxt.rs delete mode 100644 proposals/random/tools/witx/tests/witxt/abi.witxt delete mode 100644 proposals/random/tools/witx/tests/witxt/anonymous.witxt delete mode 100644 proposals/random/tools/witx/tests/witxt/multimodule.witxt delete mode 100644 proposals/random/tools/witx/tests/witxt/multimodule/redefine_a.witx delete mode 100644 proposals/random/tools/witx/tests/witxt/multimodule/type_a.witx delete mode 100644 proposals/random/tools/witx/tests/witxt/multimodule/type_b.witx delete mode 100644 proposals/random/tools/witx/tests/witxt/multimodule/type_c.witx delete mode 100644 proposals/random/tools/witx/tests/witxt/representation.witxt delete mode 100644 proposals/random/tools/witx/tests/witxt/shorthand.witxt delete mode 100644 proposals/random/tools/witx/tests/witxt/simple.witxt delete mode 100644 proposals/random/tools/witx/tests/witxt/union.witxt delete mode 100644 proposals/random/tools/witx/tests/witxt/wasi.witxt create mode 100644 proposals/random/wasi-random.abi.md create mode 100644 proposals/random/wasi-random.wit.md diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index 0305f7f32..f27c0a23b 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -1,47 +1,16 @@ name: CI -on: [push, pull_request] +on: + push: + branches: [main] + pull_request: + branches: [main] jobs: - test: - name: Test witx tools - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - steps: - - uses: actions/checkout@v1 - - name: Install Rust (rustup) - shell: bash - run: rustup update stable --no-self-update && rustup default stable - if: matrix.os != 'macos-latest' - - name: Install Rust (macos) - run: | - curl https://sh.rustup.rs | sh -s -- -y - echo "$HOME/.cargo/bin" >> $GITHUB_PATH - if: matrix.os == 'macos-latest' - - run: cargo fetch - working-directory: tools/witx - - run: cargo test --all - working-directory: tools/witx - - validate: - name: Validate witx files and docs - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Install Rust (rustup) - shell: bash - run: rustup update stable --no-self-update && rustup default stable - - - name: Check that repository docs reflect witx - run: ./tools/repo_docs.sh --check - - rustfmt: - name: Rustfmt + abi-up-to-date: + name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - name: Install Rust - run: rustup update stable && rustup default stable && rustup component add rustfmt - - run: cargo fmt --all -- --check - working-directory: tools/witx + - uses: actions/checkout@v2 + - uses: WebAssembly/wit-abi-up-to-date@v2 + with: + wit-abi-tag: wit-abi-0.1.0 diff --git a/proposals/random/.gitignore b/proposals/random/.gitignore deleted file mode 100644 index c0476d12f..000000000 --- a/proposals/random/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -*.bk -*.swp -*.swo -*.swx -tags -target -Cargo.lock -.*.rustfmt -rusty-tags.* -*~ -\#*\# diff --git a/proposals/random/Charter.md b/proposals/random/Charter.md deleted file mode 100644 index c50381166..000000000 --- a/proposals/random/Charter.md +++ /dev/null @@ -1,55 +0,0 @@ -# WebAssembly System Interface Subgroup Charter - -The System Interface Subgroup is a sub-organization of the -[WebAssembly Community Group](https://www.w3.org/community/webassembly/) of the W3C. -As such, it is intended that its charter align with that of the CG. In particular, -the sections of the [CG charter](https://webassembly.github.io/cg-charter/) relating to -[Community and Business Group Process](https://webassembly.github.io/cg-charter/#process), -[Contribution Mechanics](https://webassembly.github.io/cg-charter/#contrib), -[Transparency](https://webassembly.github.io/cg-charter/#transparency), and -[Decision Process](https://webassembly.github.io/cg-charter/#decision) also apply to the Subgroup. - -## Goals - -The mission of this subgroup is to provide a forum for pre-standardization -collaboration on a system interface API for WebAssembly programs. - -## Scope - -The Subgroup will consider topics related to system interface APIs, including: - -- APIs for host filesystems, network stacks, and other resources. -- APIs for graphics, audio, input devices -- APIs for encryption, format conversion, and other transformations - (particularly where hardware acceleration may be available on some platforms) - - -## Deliverables - -### Specifications -The Subgroup may produce several kinds of specification-related work output: -- Creation of new specifications in standards bodies or working -groups (e.g. Wasm WG or TC39) -- Creation of new specifications outside of standards bodies -(e.g. similar to the LLVM object file format documentation in Wasm tool conventions) - -### Non-normative reports -The Subgroup may produce non-normative material such as requirements -documents, recommendations, and use cases. - -### Software -The Subgroup may produce software related to Wasm system interface APIs (either -as standalone libraries, tooling, or integration of interface-related -functionality in existing CG software such as Binaryen or WABT). Capabilities may -include: -- Libraries implementing external standard APIs in terms of WebAssembly - System Interface APIs -- Tools for producing code that uses WebAssembly System Interface APIs -- Tools for implementing WebAssembly APIs -- Tools for debugging programs using WebAssembly System Interface APIs - -## Amendments to this Charter and Chair Selection - -This charter may be amended, and Subgroup Chairs may be selected by vote of the full -WebAssembly Community Group. - diff --git a/proposals/random/Contributing.md b/proposals/random/Contributing.md deleted file mode 100644 index 1cc607fa4..000000000 --- a/proposals/random/Contributing.md +++ /dev/null @@ -1,8 +0,0 @@ -# Contributing to WebAssembly - -Interested in participating? Please follow -[the same contributing guidelines as the design repository][]. - - [the same contributing guidelines as the design repository]: https://github.com/WebAssembly/design/blob/master/Contributing.md - -Also, please be sure to read [the README.md](README.md) for this repository. diff --git a/proposals/random/README.md b/proposals/random/README.md index 22449e08b..ca43ff761 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -1,26 +1,185 @@ -[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4323447.svg)](https://doi.org/10.5281/zenodo.4323447) - -# WebAssembly System Interface +# WASI Random -![WASI](WASI.png) +A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. -This repository is for the WebAssembly System Interface (WASI) Subgroup of the -[WebAssembly Community Group]. It includes: - - [charter]: describes the goals, scope and deliverables of the group - - [docs]: learn more about WASI - - [meetings]: schedules and agendas for video conference and in-person meetings - - [phases]: the current WASI specifications - - [proposals]: the status of each new specification proposal +### Current Phase -[charter]: Charter.md -[docs]: docs/README.md -[meetings]: meetings/README.md -[phases]: phases/README.md -[proposals]: docs/Proposals.md -[WebAssembly Community Group]: https://www.w3.org/community/webassembly/ +WASI-random is currently in [Phase 2]. -### Contributing +[Phase 2]: https://github.com/WebAssembly/WASI/blob/42fe2a3ca159011b23099c3d10b5b1d9aff2140e/docs/Proposals.md#phase-2---proposed-spec-text-available-cg--wg -The [issue tracker] is the place to ask questions, make suggestions, and start discussions. +### Champions -[issue tracker]: https://github.com/WebAssembly/WASI/issues +- Dan Gohman + +### Phase 4 Advancement Criteria + +WASI random must have host implementations which can pass the testsuite +on at least Windows, macOS, and Linux. + +WASI random must have at least two complete independent implementations. + +## Table of Contents [if the explainer is longer than one printed page] + +- [Introduction](#introduction) +- [Goals](#goals) +- [Non-goals](#non-goals) +- [API walk-through](#api-walk-through) + - [Use case 1](#use-case-1) + - [Use case 2](#use-case-2) +- [Detailed design discussion](#detailed-design-discussion) + - [[Tricky design choice 1]](#tricky-design-choice-1) + - [[Tricky design choice 2]](#tricky-design-choice-2) +- [Considered alternatives](#considered-alternatives) + - [[Alternative 1]](#alternative-1) + - [[Alternative 2]](#alternative-2) +- [Stakeholder Interest & Feedback](#stakeholder-interest--feedback) +- [References & acknowledgements](#references--acknowledgements) + +### Introduction + +WASI Random is a WASI API for obtaining random data. + +### Goals + +The primary goal of WASI Random is to allow users to use WASI programs to +obtain high-quality low-level random data. + +### Non-goals + +WASI Random is not aiming to allow programs to handle errors or to query for +availability. It always succeeds (though on platforms where randomness is +unavailable, programs may fail to be instantiated or may trap). + +WASI Random is not aiming to be a full DRBG API. Such an API could be +considered in WASI, but it should be a separate proposal. + +And, WASI Random is not include facilities for feeding entropy back into +the system. It is expected that most entropy that applications would observe +should also be observable by the host implementation, and so there should +be little need to feed it back in. There may be other uses for such an API, +but they can be addressed in separate proposals. + +WASI Random does not have an async API. It is expected to be implemented with +a CSPRNG which is expected to be sufficiently seeded. + +WASI Random does not have an explicit facility for domain separation or +personalization messages. If such features are desired, it would make sense to +define them as custom sections, rather than program data, so that they could +easily be excluded from module caching and possibly also from code signing. +This would make sense as a separate proposal. + +WASI Random does not provide an "entropy API" or a "true random" API directly. +The currently expected use cases want a CSPRNG API. + +WASI Random does not expose an entropy estimation. It is expected to always +have sufficient entropy to seed a CSPRNG. + +WASI Random does not provide any facility for replacing random data with +deterministic data. It is intended to be usable in use cases where determinism +would break application assumptions. Implementations may have debugging +facilities which make this API deterministic, however these should only be +used for debugging, and not production use. + +### API walk-through + +[Walk through of how someone would use this API.] + +#### [Use case 1] + +[Provide example code snippets and diagrams explaining how the API would be used to solve the given problem] + +#### [Use case 2] + +[etc.] + +### Detailed design discussion + +[This section should mostly refer to the .wit.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] + +### What if the system lacks sufficient entropy during early boot? + +Randomness APIs which can fail, or which can be "nonblocking" and return +incomplete results, are error prone and tend to lead applications to resort +to fallbacks which don't tend to be well-tested. + +CSPRNGs are believed to be good enough that most systems in most situations +can provide effectively unlimited random data. The main case where this +isn't the case is on systems which have just booted and which have not yet +collected sufficient entropy to initialize their CSPRNGs. In these cases, +this API is designed with the belief that it's better for implementations +to respond to the problem, rather than to pass the responsibility on to +applications. + +### Should there be a separate "insecure" random API? + +It's a good question. I haven't ruled it out, but I'd like to learn more +about use cases where it would be meaningfully better than just using the +regular random API for everything. In particular, I'm interested in not +just the application, but also the settings in which the application would +be used where this would be relevant. + +### What should happen on host platforms with weak or broken randomness APIs? + +It's implementations' responsibility to handle these situations. They may do +so by supplementing the host platform APIs with data collected from other +sources, they may refuse to run programs that use Random APIs, or if needed, +they may trap programs dynamically to prevent programs from continuing to +execute with poor data. + +Implementations are encouraged to perform regular reseeding (if the host +platform doesn't already do so). + +### Should there be a randomness resource, and should the API take a handle? + +Programs shouldn't need to be aware of *which* random generator they have, since +the data is random and indistinguishable. + +WASI programs using the Random API will have imports specific to the Random API, +because they are distinct from imports used for general-purpose `stream`. + +### Should random data be provided as a `stream`? + +Reusing the `stream` type is tempting, however it's desirable for users of this +API to be provided actually random data, and not the contents of arbitrary +streams which might be substituted, so it doesn't turn out to be useful to unify +this API with `stream`. + +This also ensures that programs using the Random API can be identified by +their imports, as mentioned in the previous question. + +### Should the API specify a number of bits of security? + +Best practices suggest that implementations should provide at least 196 bits of +security. However, many host platforms' CSPRNG APIs do not currently document +their bits of security, and it doesn't seem desirable to require wasm engines to +run their own CSPRNG on a platform which alreay has one, so for now, the API +does not specify a specific number. + +### Considered alternatives + +[This section is not required if you already covered considered alternatives in the design discussion above.] + +#### [Alternative 1] + +[Describe an alternative which was considered, and why you decided against it.] + +#### [Alternative 2] + +[etc.] + +### Stakeholder Interest & Feedback + +TODO before entering Phase 3. + +[This should include a list of implementers who have expressed interest in implementing the proposal] + +### References & acknowledgements + +Many thanks for valuable feedback and advice from: + +- Zach Lym +- Luke Wagner +- Linux Weekly News' many articles about Linux random APIs including [this one]. + +[this one]: https://lwn.net/Articles/808575/ diff --git a/proposals/random/WASI.png b/proposals/random/WASI.png deleted file mode 100644 index bb018e99e3ec2a66d8f2d6a7bcc63105b74d9262..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11059 zcmdsdcTiKo+b%_lbU}*rqM#rk(xpT|1f+`ej!5s)Yv`yTASgv3bdV0xLkS(Eo6sSI z-btvThTQnOGvCbp@0&Z{{pTigCbN6??ECDydv@RV$@5u9ONEk*nG6pPk5Wzbl`bA0 z{(mk~Vq8t`lpzZDL;PM{@|oudLkND#=h;BUO$>jKmAAL!(^RtaaD zcqPu5--0PggunD?lNe;Ec$F0u=+!tqi3pykveI%c^?B;jMC66}5RrX+8TPVG-k@$t zsoa#AO|+mTaI6Egbw1279$)XQ4ui0dI7!a%kf~vF2}o#e6dd)Jq{UQ@a8JC&Y&A0yClJI%bqLx)p8Nu@_2ELZQz~bAwU-` zjNtOX@;5wjVL73l)e7_%-}-}{kTi!%olwF+_vf8CcsVdreP%gTplVt;$K@^c_=!Lc z%B6;N1JC0IA0jD8rt9b(E`+a~d!%@3@JV)i2z)1>(=~YWqPFGWE4omNHFK0e#yjZM z{lZaBv1UI>tBxkTp#PLL-+m+L`Fi{Tgy}rqh1iAT!`bfTD^4?Eqx7TLNU%`f6vK;)D=kOd1xeX0QM0Q$+m}Z#+c9&oXyO zXGeVb;stIT4BmrI1irsaIdqK!WQv*LS|$Vw{_D$YySKI*VXRr(q@+DQdUl32X;ONn zFdyHD2Rz5!K?83UCHWFYmtZ6S&x+3RP+w}k1bX>9tgr)`w@DJ^=L8%wp8IbO7s*YL zbB}L7Q#1PGP-(FWoZ@4(niOz7jVLbDO&nz>q0>MYgNw!T%SSdupzB~sKF|}UWdMGw z56eG?RIyzA>llRZkMwJmI0y&H87yBif??S0HN(GnDW4)v<)PGV9;-Z#>GG|2HE(d! z7%OQ3+Py?S5@{t#-A+*UmbQjE!r67;pv>T%_%7N_5L| zh$#$m|Ds9<9m;5UKmrL`HCh3@7zRji^=V_>{63260b~bC0G6#g*nPjT;~m7@@urg) zc^jR7f;UmhCowObEGYvIFogwgI0w-!$+OEva`+D)v8~o{^G+4Rj>1OEKx8x$Qa#LB zriw}{mJcRw#*+o&j0kteN3sOr?kzN)VbM*D5y7eWB<-E@(91l8`U{ztI3G|~w0COb zD|=Mq^J%jRWZ}Pg*=Dj+ZMNV_l|T?{5TS=_a?BgBT>3-!UO<@Rq{XXO3jDa4rN8$! z>C30bs>=VP*wv5N9; zZk(wlH>FBQA@qK9sZjVoF!u|&{||8g6J;{pd;c}qfBpU6mR%ZueakUpQltqxxvWAn~wd*u;(OPQ3~dOj|&4;24}nh}3mJ zV6ospuj#|%GutPWjXLw})}mGhkqnzZ2a$_R;<(I?fCANVHKaCouSt>3QIREhY+|EPc z3L)_ZSbXLbJvPIz6YTnJT0r?D9sTnY5h1aib2sn3s`nYeSc9t28Famq#Ts4X{JoFc zCBhSzyAia%=OXKMJ*?;sE)ONe`^#|D_;EC#s;V054kZ(NYWjvynt|QPW^+eqlVdNp zS&sWxm>Q=^MafUiNZ+$DqK(s>qK>D1UF`iG1+mk^^k56)+@KHPV>66{T86cARyG29 zBod4|2MIL~>g?zM$cGqq$6L+@hGITJb@GJ9gn7w^0$9>G%ck8fHIy?9S$PYXZ0MV) zbIoQ;qWUNp(`60O^$mpTru#pm&H*I7oQ>@3p}$}%(<*n{|c{xFvB?e#k(^H26BL`NQ&VO0TM zi9R$%xGtGM!rBNOCu~^sxW!czB%-w$Aujv!vi8xG!_x%^_#AK>PK>qY$%v zspccYKxs@tP)2|~qni8yVf&VTMr7_!Dl$y~Y_x@Av2XvK`5jxztH-J+ZdLNSggAT5 zwVDi=a^;1S3mua$sv1SoL`{TSCt!q&0$zJaXd2ukJ)?fWJ_UEFt*Pf5?_28`0W2x#=%<%C zLY8Klqg#yCY1inJ2xSyaj$@#|%lG;gB$+1JI$P1P-rhvW-RyV; zx3nHDVG2C={ZAcU@wV2Ub7hL}2T83%Th=?AmNI)iaS&S2Ggl(|yFYDqD54&z?`_!5 zj|-<{meHm@HS);oYGmR!ef|{XU>)G+%nY4mg!U_XJ|5UcFn>S^Cnj?UtPoJ*0?a+Z zG{VOk#<+DELfBB=9KI5k+NQQ;dL{pwG!f9yF+7nh>BGo^^9X44YU9zsWYihE*qisW zwUQ6xCD5aG1pWi9qFFNZL9v0NQQN(i$c-VyHbgqv;yMNX?Md%xur25oE3Lc`y^*QE z(ld8U#qIZC5RHac}Qv z`inGO=7bLCkd%k#@~p|ur6~Kr#v*+$!6|+-dG}fnra+A%i28NCpNm%CES#>!M%#Zz z-G+r*RnSaUe%~-ECJAD)nx}34e!SX@>v7S$!f9A<;{&B+@@?6=-mV;JZ3Gq+(aWR3 zrq@bfm$Tm;?KCf-x)<74LU*!dhe@dgs=U-uQEv1xt*OH259W(IaHk6Fjo{D^JSgDt7G=r-sJ_wErt3*UcACN=rSllcs%F5__(XN)RIu)v+!j>Y zf4{Vq#eJb2P~lAU*9OFcCO=6ya-J>+`wC=Mow`v=xN5eE)P$(0BCI@ST3y=V7-jYA zd5;F-b&4ou6;#exVMtac=N}^P_TMkvey=ukEJfEeSJS^us^U?#zWHhEIfjC_qE>!Y zy+y{dx3qG?Yxz#8kdJM)=XGUvlJAVQBLRaS1St+E+Cu%V63pgS4m2(0=jSP}+1-}@ zT=pwAh#r%@W_-D~LAzq76(dO_$XBoN9cG&$-ufuF*;HZvQ+^Eah(ss7Rs-%KyMBaW z%Z_QJQmXBrb|33Xt=z22>?Z6{U|v)^s96BcqCWD~u6;Fpk8;$I@T54P+F3G@;VkBT z3c0Bp)<{^$oO1Tl?o7NbmpB&ZJ@)fuq2l;_0R-yJ9k!I6M|m|#92}BD7eDNP^akg4 zykUl>Yd_~HdMp2}pPB22Jk5bm^31-p5x#lIA%-!}#CpXy z&!x#@a}EVWQtk+4CA14brL;&oUc7L&%ydqpBZH-G^qFS18aW4Cs*4~FJLYE!ngF?8 z>Mx7-e|~h9W0|Tghss?Lt_62axF?EUbVnHyIn%zTHWH*q1%(?B!zV7~suov7vS+w3A1|lKYl7Cm4Ly>D7ZC>~+)lIkkGt=Ri1X5>Tj$f_qcS}jL>CuwV%X6>prp+gTVy=(cLq`IpUp*6>C=x2M}=z z7#wrr+GWmWbKGe3U{M4#{4|o^>?S<>;pO49v^w`Fb78r4;K6Uin;f&H3h6X4HLLNi zdHwZhn20d26usjfMD@y9>+WwgFxgO3_swpa4OW?exDiFVjVuijaE~`-*mSG&MZB!t zZkFGjY2%ouhe}%g^wM%%b!gYct=g2AE1xA^W6_)&9WLM}pO5u^N~;!-YPFjc?HX(D zoANwP={-8Mxz}KDY0lA*70}?@ygys#`rhVmQBvJhSx30`>^2#-2x=Qpbo{@3E)doxNfdUCIPTJz~N(R+?RGYwm z7+{2ZuYOi@Q&JiVUsuZkF1E8J=TzVOUmVS!XpVO!;I(nXINRqd_)8EZn`Bo76 zXtOlU2KB?ZftQ2%#Qf?DH`C$+iH-Y@Sss8bjUP(BMFS7? z^A7z<7_}(8(6PRv=q~wH^rxD1DuU8CKZ@@{pGE!k@*FM5Fg&9qZmLYrip0I4_I?L7 zU~hSA&#|}s)1f8%0Pkx~9|mwBwC6ZDzRjr8+16l&0iszdV4Kd|)GYITOaV_cCBZoj zBVURJutKNcS(w6Nr@153wdNPRuIUfqEurW?TCXAYNi*^RVJ935f7XM7NNH7?vuN~O z=52GW^phlhOZAs4-toVv{p2(UNBhZs6e|nhwzrL`SW-bgQ%rJ`v z+Iyaj6#6z1_yqilWC74)4p?=wu+lDP3xl7Q~ zoJ+lD#)4`oJ=V`Bv=ck5_J*qlBBLxPYwoW8PajB`R7RmJ7@UWSA?vR+dmAyG1 zlx_L^{J=hKTejhoC@}#P=tRdyw6kC!9~<+R{8p*&n))?vszQcI{Tq_qDzYj?v`<#& zqTW2BY!F~iocn9Ly+o^X`;#8vNzqDupFr#wY+ewLMHIS{xz93lHEAcn371?dckLF3#aTRW5v4-AWPR-BLV0 zczGOQv--1AT2h=8)_K<6(H_zTPIPq4`hCA!w_6FjN!tqW`f=m%IoAb7_p;|JrI-zj zEi2-AlK(Rn| zWhc4;bY4;_bC>UmH#q)d!xtPZv7-L#Z;^?w-81ArR2BdqbFS4cp6nLY6QEI>VVKw( z=KJb#344agKQZ#_G2z>*pVmdXq}JETiM^cOYW7BP&Lnihl#|8n-ZdsVRpZ?)*6!>p5(2a z(wbKbCa)6?wHpsD{MHM4{`A1jHlR5gYL!rAK3D$-w0H$xAcIy+-aUymeS)0rT3s^m zz1d{?`!T-n)E}bbWGc3T11yHIbUR63ZWHK}-#w z^lTIDwP#M2&8U=7pvc>={5XIwRw2Nu{j>Jb`F+c5LNc1~Pv?^Rq*QL5G7=58_;u=Y6a!U+jemb?;oG6&0g+n!%nRSP{k zyu8bP`A1Y16H@*BB1rPnu1hfqee+HG!V{{dU;O$>Zt(()H}fiU71sXlgVV0~O07=V zmbepiqv=_nNW6I^CcTBB2e%UiFHJP`p^hye-)VwkQZ;Wf&!&sv#O)#YZ07yf<*j_# z9{`ejIq}*ZGO+rRxTQM&>B30kw_JAPUWNfT9PJ9@ab7-O2mhJ&izW50oT^78X@@;y zGq3ic(q&S#H+*T`|97szw`Nq!xXP>z6Rb}7R7eV!DYRq!Zsq2(tetbZ?m+>1GOEHk z+D2wIODd|St_b1em7oYxwkRH4YIn6iRqz0rX{5>jY!usH1VV8&O8r z`jVC&8rn-M6Vik~K7th;Dmh)9CHLiN-kK#iqAD=_Ijl|Y88;}pLY1WrKv~Lg2_Lb` zEr}_3Yu6CMN~auX6A)q$P0Yv?gWY3#m>__VTW5^FyXcQKhykv>5GsGD54#n5csDDc z(ih-JQ#h=6P3#o=r#s6ga22iK6!uXhySUzto~dhEUP-$eA^j$8jCZF>qeEu3iG|ot zV#!sM7)7G|bNTdKSQ=hZis$ zGs0q%dKtk3Y<;3moXW_SHa3OigHLmK9M;aKNqmMOqaJoS>&dAt|5fRUagk?9Nm#P? z`nu32S*xCCgC68ye30zoG5&hM^~3B@i)S%nN_n~VnT;o~+(71uswB4>%nC=V!Qffb z6H{~(76rii=KW@0+XF|%>7pRtdFHMrXW-yO)%+i+P{Eb{^fS=U@4X2Fpdm3Ajt}-} zII=j&t0Xzbd5J`SU~!EtKIB>=8SOFp%;#I)^}6f=5cnLvi)0r+Sr`}mmif8V_qBM> zQX{d`w1BE)v6|kK68iU*oRkDkND>qNVnQ`%*Zq4HthACMb`OjSAmTIcZ+t5`ns#gg ziEUaaNH`o9*%b3DR=)8(Sh{f1xG!!oKX4h=M_8%XXg5v4pBe5T(yvU+e~y-J%(k>c zvt_57^cC||rZ;R@*aYiHo}^S8Sbub};g5-qSlf5L`?lHFf1L4Yip`%GSv%|gw?;NI zS50j#f)rFl-sciX!Ql_k%fd17C7Fc>pT0;9^oDr zl-T|vOVUHii}#k&N~LzMjUQ9K(resA9-OGNZn#QU%P;0S+>N`N&j}Ap^hnR~dOC(M zFA1VesWK@$+Huoh4kP#SL;L|)8vX0FP?eU6iL7lbG*HIJn;Dl8a#w+4f{M2KhhCl3 z&Xmjl>YNN}MVa?)L0gK*sV~_Apq_ybGT%ziKmHlmpCh7U;;UiSRPR>>VKWet(F#EC zJ+NVdI2oIH)caLnquc72(^<85Uj$y(mONjIl)}+FEKTtfov9X(?22R8n0D%DN0!psZZV0IPHlWhGr}Fy9-dGaCq+~m;a#w_97n#B zfb7WhU(_;--YW<#*iyiQNj{BsR1X@s;yCF~-?;i!G|Ch2nvA^8a2H(yj%(j6uf`BL z(sagl$PC0nTKo2{n^2@X926PZjkhZ52to@PFPVhOYChY)-@a-tZ&@dawgMlkFi&*l88A4VOjO`8XMLA+_6*F<8cU%G- z6K;&=glo!n&^`qSQPpJXyJajg^g~7}MjA%46a6iTsQmej+IyO$=ECE!z@mD`E+J~8 zB*j3A!R{<`zjsh+DIh;D+UybS9Y^s1NttfOw3XG2-k>i!tUb3qc{5AJj!FGH><{d0 zIyfu4L$I4jP#BI;04Hd*7z(D>IP6?ozGE6!=*Xp5P)lQEuO zcvGL{kKJd>d7VY<0HuA7OF_plk>*cXUCt;hXD^*+)IR=HDl5jk?vRY|mfyUXiV9!3 z%A6nT{-K`wE8*|qLr;x_5`pAtuR~MEInNdEeN0_{p=J<*3_Vq?C)t+x+e9sGT^_d8 zl=5d{%v*Rmu<3BYMNK02T-!b))Q&vb&-+Th_^w8KN#;hjpi4;YODu=R-{)`pUlTJH z?QKA+sHfm%FEo?ct?X%IyPlmp$ap0-ie7(U#03wYrppa;UQnu5c^R!+Cp8!d7mXp> zax#5JG^B}RW{kgee4A{D3}z}mF~m{%=&>uyzi}rC-4!RyZEDHhMUy5hMZuM&no@vL zGvBtGzI6K~)PurS#YSqPEI_u{^pgVOc(48IzPA>)EwP_lxly5iRudSi&d)?IHRW)O zVe#5m5Y{*Sz_A-|C|t3gY))9;D~2 zTQ6XRYB1D%^!a4a(Yw&@cw4)VAuDey3kRI)Cu@~-X_)(~jZR8gs^)NnkmAUSHfU`sCy=xi ztoUn_I%1URUr5_%ml04VQ2D&lRQlA-Hlj_W`NuPJx%~A_fFYnJ8%uTBNCZ}4m^&+< zxtk{DSAS1DL?uq7rtP~B$}I6{PYup-Xq}Ga0fR0JC5~ilLiNpjaI9my7J#VP|3&GZ z7&MT-rAT?8sP5K%J^Py5WI?k>Gx|->{bNIQ)~l^8=-KI68>tyscSxBylU((f%QHxI z@!q{Am0njaHD^^Q?RzhL3A)8y0*^`Y%x>kHjW}}Fi|FBX-r+Y-iFSBXryle)4Bw63 zx#~GROYwxKEE;ZAr+zu(d(}YT-nQCgU*eVIE>5ve+Fo+coI_Jp!rGA2#wv9B`05i@ z=O$dq8vMhmz)klfv+w?lXO`#8pjfJsZOe+6Qq5lfSojnkK^K`H8 zU(T@m8HQ_Ms+gb?a?EN*lvDN;;;YE;{&(zcf$242Bl;Q=E(Fq)aGif!L_p`W@A|Aw zxUf#ZVSg=J!z4rgYR!Hd0}+i<&UCA~k@%2G4y~?9p9l@jz+gkahd{hD9R4_sITSE@ zo%e9ui}Bdd?H>7F*+PCh^8(0gJX3h|*rwUzMX~NsV0L{AbG&=7IC}m88T9t=l56<+ zOIYt&J;E0z??buRoa)bZL_nil;{_b-^Ac$cZ$+Cqd}4Ty#&+8lFNuzSbw9B6bQe$y zN&;y^KFjR1aJqJo=nrZdII;;sLp~;S0Df|rXsMcrjjAaGQVT#^9t`a3g;ZZ;I1aD2 zna;fC>>8>sZywu4o#8002Lxk^2&>L%*HHK3Bj;2n+mndNJI~~Hm|EYrN8DeYSmUz1 zq4P2%XF}?yujZl>OLhW%zRls%V%fi4tG5zglrl_Pm5iqm`qpmx*+LpX%g_qNTa(X? zX!hL%d z-Au$D8~NtaCOwcjpDX(D%K|Es)V)Y{-%fSq-nHZmCYUY40~ty zR42n1+?KoJZx{b6F5a`oC02xuk9wnt-!(+hXO0O}zKHn3BWcbBY=2cuL&reZT@?f!EnUS%OCB^al^fJ)~eTVSa^*7xbm|{97T{j~iQ@DUk_PoaU69PCg_|n|6Xl zJ{DV2q@lN&V>yrRMsS1%Sz7J93NU=wyWjs$8Oiwh7 zGwhv^7=(^?9w)VxvXcgQ@2%X48cM>$pvS)>VLU&OUG%ec;O`EIJuGvaH@jPZ+=B4D zPx{=>Ru{7yYxZYJx^U#6ysb$t`+fo$^mPc#4ZSArMEaop3BB&el>W_E|51kgQ*IEI z;-pG?|DEzj%fB6OpoiSK`NN!){NxX>I@9b(p?p3M3g4P)&}Fk3y3z#erYTOk(6*3| zb4Xvtbq;txDzpY1`P}{QbpOAFB>#Ol|J8mlL=gIjrllH=XK`lS{GWsGK(|4F zkH?JRi92sD%!QV>!fV%fRLJ+5rvt254kg2LbZa+o;u`Mr*ms?h%=YrW!Ry-jkiwcpIqfMbNbRj3^%@fQ1H3~bG~-G2hLCoU~m_O!*S{t4k5blvqO)= z9EXs`RTLzl-PwVcgT-;asBs8qG?diy91lofKjt)2rc-7hA(tfxFmr?Hi$lA>MZ(ZX444s>;l>)hQr_Q%*@PmSd$}>38_@d1=4?UyC{i czhJ3-6EkB9r^7gK@>V=GWvy3LidGT-3mCQ^bN~PV diff --git a/proposals/random/design/application-abi.md b/proposals/random/design/application-abi.md deleted file mode 100644 index 0ef259a51..000000000 --- a/proposals/random/design/application-abi.md +++ /dev/null @@ -1,60 +0,0 @@ -WASI Application ABI -==================== - -In addition to the APIs defined by the various WASI modules there -are also certain expectations that the WASI runtime places on an application -that wishes to be portable across WASI implementations. - -This document describes how a conforming WASI application is expected to behave -in terms of lifecycle (startup, shutdown, etc) and any exports it is expected to -include. - -Current Unstable ABI --------------------- - -There are two kinds of modules: - - - A *command* exports a function named `_start`, with no arguments and no return - values. - - Command instances may assume that they will be called from the environment - at most once. Command instances may assume that none of their exports are - accessed outside the duraction of that call. - - - All other modules are *reactors*. A reactor may export a function named - `_initialize`, with no arguments and no return values. - - If an `_initialize` export is present, reactor instances may assume that it - will be called by the environment at most once, and that none of their - other exports are accessed before that call. - - After being instantiated, and after any `_initialize` function is called, - a reactor instance remains live, and its exports may be accessed. - -These kinds are mutually exclusive; implementations should report an error if -asked to instantiate a module containing exports which declare it to be of -multiple kinds. - -Regardless of the kind, all modules accessing WASI APIs also export a linear -memory with the name `memory`. Data pointers in WASI API calls are relative to -this memory's index space. - -Regardless of the kind, all modules accessing WASI APIs also export a table -with the name `__indirect_function_table`. Function pointers in WASI API calls -are relative to this table's index space. - -Environments shall not access exports named `__heap_base` or `__data_end`. -Toolchains are encouraged to avoid providing these exports. - -In the future, as the underlying WebAssembly platform offers more features, we -we hope to eliminate the requirement to export all of linear memory or all of -the indirect function table. - -Planned Stable ABI ------------------- - -There is ongoing discussion about what the stable ABI might look like: - -- https://github.com/WebAssembly/WASI/issues/13 -- https://github.com/WebAssembly/WASI/issues/19 -- https://github.com/WebAssembly/WASI/issues/24 diff --git a/proposals/random/design/optional-imports.md b/proposals/random/design/optional-imports.md deleted file mode 100644 index 543599a10..000000000 --- a/proposals/random/design/optional-imports.md +++ /dev/null @@ -1,108 +0,0 @@ -Optional Imports -================ - -It can be useful for WASI programs to optionally depend on certain functions in a -WASI API. For example, if a WASI API evolves to include a new function a -program might want to continue to run on older systems that don't yet support -the new function. In this case a optional import mechanism allows the program -to run on older systems and detect the presence of the function at runtime. -Another use case is an API that is not applicable on certain embedding. In this -case optionals imports would allow program to continue to run in such an -embedding, albeit with reduced or modified behavior. - -*Note*: In the ELF specification this type of import is known as *weak*. -We chose *optional* because the term weak is already used other context in -WebAssembly and JavaScript, specifically in JavaScript [weakrefs] proposal where -it relates to garbage collection. - -WebAssembly itself does not currently provide a mechanism for optional imports. -There is some discussion of adding it to the [spec][spec], and WASI would likely -use such a feature if/when it is added. In the absence of first class optional -imports this document describes the mechanism used by WASI to specify optional -imports using a custom section. Currently this is only specified for function -imports. - -Declaring an optional import ----------------------------- - -Optional function imports are implemented using two imports for each function. -The first being the optional function itself and the second being an i32 global -which indicates if the function is present at runtime. We call this addition -import the guard. - -For example, if a module called `wasi:fs` added a new `statvfs` function to its -interface a program could optionally import this new function in the following -way: - -```wasm -(func $statvfs (import "wasi:fs" "statvfs.optional")) -(global $statvfs_is_present (import "wasm:fs" "statvfs.is_present") i32) -``` - -These two imports would also need to be added to the `import.optional` custom -section (See below). - -On older systems that don't support the new function, `$statvfs_is_present` -would be set to 0 and calling `$statvfs` would result in a trap. - -On systems that do support the new function, `$statvfs_is_present` is set to -1 and calling `$statvfs` would work as expected. - -Using an optional function import ---------------------------------- - -In order to use the above options function its presence should first be tested -for. In C code this would look something like this: - -```c -if (__wasm_is_present(wasm_fs.statvfs)) { - wasm_fs.statvfs(...) -} -``` - -At the WebAssembly level it might look like this: - -```wasm -global.get $statvfs_is_present -if i32 - call $statvfs -end -``` - -Custom section --------------- - -A custom section is used to specify which imports are optional, and for each -optional import the name of the corresponding guard (the global import which is -used to signal its presence). For each module that contains optional imports -the module name is specified once followed by a list of its optional imports -along with their corresponding guards. - -The name of this custom section is `import.optional` and its contents are as -follows: - -| Field | Type | Description | -| ----------------| ---------------------- | -------------------------------- | -| count | `varuint32` | count of mod_optionals to follow | -| mod_optionals | `optional_import_list*`| sequence if optional_import_list | - -Each `optional_import_list` has the following content: - -| Field | Type | Description | -| --------------| ------------------- | ------------------------------------- | -| mod_name_len | `varuint32` | the length of `mod_name_data` in bytes| -| mod_name_data | `bytes` | UTF-8 encoding of the module name | -| count | `varuint32` | count of `opt_import` to follow | -| opt_import | `opt_import*` | sequence of `opt_import` | - -Each `opt_import` has the following content: - -| Field | Type | Description | -| --------------- | ---------------- | --------------------------------------- | -| name_len | `varuint32` | the length of `name_data` in bytes | -| name_data | `bytes` | UTF-8 encoding of the import name | -| guard_name_len | `varuint32` | the length of `guard_name_data` in bytes| -| guard_name_data | `bytes` | UTF-8 encoding of the import name | - -[weakrefs]: https://github.com/tc39/proposal-weakrefs -[spec]: https://github.com/WebAssembly/design/issues/1281 diff --git a/proposals/random/docs/DesignPrinciples.md b/proposals/random/docs/DesignPrinciples.md deleted file mode 100644 index df82c8692..000000000 --- a/proposals/random/docs/DesignPrinciples.md +++ /dev/null @@ -1,291 +0,0 @@ -# WASI Design Principles - -## Capability-based security - -WASI is built using capability-based security principles. Access to -external resources is always represented by *handles*, which are special -values that are *unforgeable*, meaning there's no way to coerce an -arbitrary integer or other type of value into a handle. WASI is also -aiming to have no *ambient authorities*, meaning that there should -be no way to request a handle purely by providing a string or other -user-controlled identifier providing the name of a resource. With these -two properties, the only ways to obtain access to resources are to be -explicitly given handles, or to perform operations on handles which -return new handles. - -Note that this is a different sense of "capability" than [Linux -capabilities](http://man7.org/linux/man-pages/man7/capabilities.7.html) -or the withdrawn [POSIX -capabilities](https://archive.org/details/posix_1003.1e-990310), which -are per-process rather than per-resource. - -The simplest representation of handles are values of [reference -type](https://github.com/WebAssembly/reference-types). References in -wasm are inherently unforgeable, so they can represent handles directly. - -Some programming languages operate primarily within linear memory, -such as C, C++, and Rust, and there currently is no easy way for -these languages to use references in normal code. And even if it does -become possible, it's likely that source code will still require -annotations to fully opt into references, so it won't always be -feasible to use. For these languages, references are stored in a -[table](https://webassembly.github.io/spec/core/bikeshed/index.html#tables%E2%91%A0) -called a *c-list*. Integer indices into the table then identify -resources, which can be easily passed around or stored in memory. In -some contexts, these indices are called *file descriptors* since they're -similar to what POSIX uses that term for. There are even some tools, -such as wasm-bindgen, which make this fairly easy. (Internally, tools -and engines don't always use actual WebAssembly tables to do this, -however those are implementation details. Conceptually, they work as if -they had tables.) - -Integer indices are themselves forgeable, however a program can only -access handles within the c-list it has access to, so isolation can still -be achieved, even between libraries which internally use integer indices, -by witholding access to each library's c-list to the other libraries. -Instances can be given access to some c-lists and not others, or even -no c-lists at all, so it's still possible to establish isolation between -instances. - -Witx-specified APIs use a special `handle` keyword to mark parameters -and return values which are handles. In the short term, these are -lowered to integer indices, with an implied table, so that the APIs -can be easily used from C and similar languages today. Once [interface -types](https://github.com/WebAssembly/interface-types) and [type -imports](https://github.com/WebAssembly/proposal-type-imports) are -ready, we expect to make use of them to provide APIs which can be used -either from languages using references or from languages using integer -indices, with tables being used and managed automatically. - -## WASI's Scope - -WASI started out with a very POSIX-like API, however WASI will grow to -include many APIs that are outside of the scope of POSIX. WASI is a -forum for cooperatively designing APIs, along with a W3C CG Subgroup for -eventually standardizing them. - -For example, WASI may include high-level network APIs, such as APIs for -HTTP. This is outside the scope of POSIX, and while some WebAssembly -engines are very interested in implementing it natively, others will -find it too complex and high-level. But one of the great things about -WebAssembly is that there's no syscall instruction, so "syscalls" -in WebAssembly are just calls to imported functions, which could be -native functions provided by the runtime, or could be other WebAssembly -modules. We expect to leverage this capability to provide polyfill -implementations of things like high-level network APIs on top of -low-level APIs, such as a raw socket API, so that engines which wish to -keep things simple and just implement the low-level socket APIs can do -so. - -WASI also aims to include domain-specific APIs, such as -database, blockchain, or specialized APIs for embedded -systems. Another key building block for WASI is [optional -imports](https://github.com/WebAssembly/WASI/blob/main/design/optional-imports.md), -which give applications the ability to dynamically test for the -availability of APIs. - -## Relationship to POSIX - -POSIX specifies a C API rather than an actual system call ABI, with -the expectation that implementation details will differ at the system -call level. In the same way, the primary vehicle for WASI's POSIX -compatibility is libraries such as WASI libc, rather than the WASI API -itself. WASI libc provides a wide range of POSIX-compatible APIs. - -In the parts of WASI which do correspond to POSIX functionality, WASI -follows POSIX when it doesn't conflict with WASI's other goals. And, -we consult POSIX even when we aren't strictly following it. POSIX is -valuable for several reasons: POSIX represents a large body of lessons -learned about systems programming, portability, and robustness. POSIX -is available on many existing hosts that we want to port WASI to. And, -there's a large amount of application code that we want to port to WASI -that uses POSIX-style interfaces. - -All this said, maximal POSIX conformance is not WASI's primary goal. -Some reasons include: - - - `fork` -- It's not that we can't make `fork` work -- we can, it's -that `fork` carries with it the assumption of copy-on-write memory -optimizations which won't be feasible in many environments where we -want to run WASI, such as nano-processes. There may eventually be -compatibility layers that provide `fork` to help people port POSIX -code to WASI, however there's a difference between providing `fork` as -an optional compatibility layer and having it as a cornerstone of an -ecosystem as it is in POSIX. - - And when we take `fork` out of the focus, it changes the way we think -about a lot of other things, such as `execve`, `dup`, `fcntl`-style file -locking, and even processes. - - - Users and Groups -- POSIX's Users and Groups subsystem are -notoriously inflexible, to the point where much of the computing world -has moved to using containers and VMs and other forms of single-user -environments because traditional multi-user OS functionality doesn't do -what's needed. - - And, when running untrusted code, it isn't desirable to run it as a -user's normal identity, because it shouldn't inherit all of the rights a -user has, but it also doesn't help to run it as user "nobody", as it's -still useful to grant it some rights and restrict it from others. - - And, we are aiming for portability to OS's which don't have -POSIX-style users and groups, and systems which don't have OS's at all. - - - Asynchronous signals and handlers -- The core WebAssembly semantics -don't support these, which would need to change before WASI could -consider supporting them, and there are currently no proposals for doing -so. In POSIX, some interfaces are designed with the assumption that -signals like `SIGPIPE`, `SIGALRM`, `SIGCHLD`, `SIGIO` and others exist -and can cover certain situations, so in the absence of these signals, -those interfaces won't always make sense. - - - Shared filesystem views - One of the unique capabilities WebAssembly -brings to the table is the possibility of shared-nothing linking between -applications and libraries. Shared-nothing means that all communication -is via explicit calls, and the libraries don't share an address space -or any other implicit shared state. But if we run both sides within -the same filesystem view, that would give them a large body of shared -state. Union mounts, mandatory access control systems, user namespaces, -and other techniques can help, but often require complex configuration, -heavy-weight boundaries, and sometimes even admin privileges to set up. - -This has wide-ranging implications. Much of POSIX is oriented around -passing around strings, whether through command-line arguments, -environment variables, or paths embedded in files, with the assumption -that there's a shared filesystem view between components. As we said -above, we're de-emphasizing strings, which dovetails with de-emphasizing -shared filesystem views. Instead of having shared state and passing -around values which identify things within the shared state, WASI -prefers to share as little as possible, and use handles which represent -the things which need to be shared. - -Compatibility with existing host environments and applications is -important, and we have put a lot of work into WASI libc to provide POSIX -compatibility and support existing applications. There's a lot more work -that can be done, and a lot more we can do to improve compatibility and -user convenience. We're continuing to make progress -- and users are -encouraged to [file bugs](https://github.com/WebAssembly/WASI/issues) -when they find things that don't work or are awkward. This approach -supports existing applications, while also supporting applications and -libraries willing to opt in to enable stronger and more fine-grained -security properties than are possible in regular POSIX. - -For example, a typical POSIX-style API might include a function that -accepts a file name to open. That requires the implementation to -have a filesystem view, and to have appropriate permissions within -that filesystem view. WASI APIs typically prefer to instead have a -function which accepts a handle for an already-open file. That way, the -implementation doesn't need a filesystem view, or permissions within -the filesystem. It doesn't even need to care whether there even is a -filesystem. When needed, compatibility with POSIX-style APIs is then -provided as a thin layer on top implementing a simple name-to-handle -mapping. - -We recognize that this approach has trade-offs. It often does take more -work to design and implement the compatibility layers needed to support -existing applications than if we just made WASI always expose -POSIX-style APIs directly. It will take more work to port existing -libraries to work with shared-nothing linking. And, even when we do have -compatibility mechanisms, they aren't always the most locally optimal -ones. The compatibility layer overhead is usually quite modest, but it -is present. - -However, libraries built to use shared-nothing linking can be used in -more circumstances, because you don't have to have the trust implied by -a shared filesystem view, or the complexity of configuring filesystem -rules for each library. With a better story for libraries and tools to -work together in cooperation with the sandbox, we can build a stronger -ecosystem which makes up for the downsides in the long run. - -## Relationship to the Web - -It is possible to run WASI code on the Web with the help of polyfills, -however WASI isn't limited to APIs which run well or are easy or -efficient to polyfill on the Web. - -That said, where other considerations don't interfere, WASI should use -existing Web standards and work with Web standardization efforts rather -than gratuitously inventing its own versions of them and/or duplicating -efforts. - -When using Web standards, WASI APIs should be careful to avoid depending -on JavaScript in the engine in APIs where it isn't essential. - -## Use WebAssembly standards and proposals - -WASI should align with and build on WebAssembly standards and proposals -where applicable. - -For example, WASI seeks to align with and build on [interface -types](https://github.com/WebAssembly/interface-types), [multiple -return values](https://github.com/WebAssembly/multi-value/), [reference -types](https://github.com/WebAssembly/reference-types), [type -imports](https://github.com/WebAssembly/proposal-type-imports), and -more. As of this writing, some of these are early-stage proposals, so -we're not actually depending on them yet, however we are carefully -aligning with them so that we'll be ready when they are. - -As another example, WASI's -[witx](https://github.com/WebAssembly/WASI/blob/main/docs/witx.md) -file format is designed to be a -straightforward superset of the [module linking -proposal](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md)'s -.wit format and the [annotations -proposal](https://github.com/WebAssembly/annotations/)'s annotation -syntax. - -## Interposition - -Interposition in the context of WASI interfaces is the ability for a -Webassembly instance to implement a given WASI interface, and for a -consumer WebAssembly instance to be able to use this implementation -transparently. This can be used to adapt or attenuate the functionality -of a WASI API without changing the code using it. - -In WASI, we envision interposition will primarily be configured -through the mechanisms in the module linking' [link-time virtualization -](https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Explainer.md#link-time-virtualization). -Imports are resolved when a module is instantiated, which may happen -during the runtime of a larger logical application, so we can support -interposition of WASI APIs without defining them in terms of explicit -dynamic dispatch mechanisms. - -Interposition is sometimes referred to as "virtualization", however we -use "interposition" here because the word "virtualization" has several -related meanings. - -## Compatibility - -Compatibility with existing applications and libraries, as well as -existing host platforms, is important, but will sometimes be in conflict -with overall API cleanliness, safety, performance, or portability. -Where practical, WASI seeks to keep the WASI API itself free of -compatibility concerns, and provides compatibility through libraries, -such as WASI libc, and tools. This way, applications which don't require -compatibility for compatibility' sake aren't burdened by it. - -## Portability - -Portability is important to WASI, however the meaning of portability -will be specific to each API. - -WASI's modular nature means that engines don't need to implement every -API in WASI, so we don't need to exclude APIs just because some host -environments can't implement them. We prefer APIs which can run across -a wide variety of engines when feasible, but we'll ultimately decide -whether something is "portable enough" on an API-by-API basis. - -## Strings - -WASI in general de-emphasizes strings in areas where typed interfaces -can be sufficient, and especially when the strings would be serving as -identifiers in a global shared resource pool. - -Where strings are passed through APIs, WASI will use [interface -types](https://github.com/WebAssembly/interface-types) to manage the -strings. - -Where string encodings are exposed, WASI prefers to use UTF-8 -encodings for strings, and to provide explicit length values -rather than NUL-terminated strings, (as [WebAssembly itself -does](https://webassembly.github.io/spec/core/bikeshed/index.html#binary-utf8)). diff --git a/proposals/random/docs/HighLevelGoals.md b/proposals/random/docs/HighLevelGoals.md deleted file mode 100644 index e871cfd08..000000000 --- a/proposals/random/docs/HighLevelGoals.md +++ /dev/null @@ -1,25 +0,0 @@ -# WASI High-Level Goals - -(In the spirit of [WebAssembly's High-Level Goals](https://github.com/WebAssembly/design/blob/master/HighLevelGoals.md).) - -1. Define a portable, modular, runtime-independent, and WebAssembly-native API - to serve as a system interface which can be used by WebAssembly code to - interact with the outside world, that preserves the essential sandboxed - nature of WebAssembly through a [Capability-based] API design. -2. Specify and implement incrementally: - * Start with a Minimum Viable Product (MVP) for the standard, covering - basic API versioning, feature detection, and namespacing. - * Then add additional features, prioritized by feedback and experience. -3. Supplement API designs with documentation and tests, and, when feasible, - reference implementations which can be shared between wasm engines. -4. Make a great platform: - * Work with WebAssembly tool and library authors to help them provide - WASI support for their users. - * When being WebAssembly-native means the platform isn't directly - compatible with existing applications written for other platforms, - build tools and libraries to provide compatibility. - * Allow the overall API to evolve over time; to make changes to API - modules that have been standardized, build implementations of them - using libraries on top of new API modules to provide compatibility. - -[Capability-based]: https://en.wikipedia.org/wiki/Capability-based_security diff --git a/proposals/random/docs/Process.md b/proposals/random/docs/Process.md deleted file mode 100644 index 3b4affc3c..000000000 --- a/proposals/random/docs/Process.md +++ /dev/null @@ -1,37 +0,0 @@ -# WASI Standardization Process - -WASI follows the [WebAssembly CG Phases process], with the following adaptations: - - - Entry into Stage 2 requires [witx] specifications. - - - Starting in Stage 2, proposals may follow WASI's [ephemeral/snapshot/old] process - to provide a balance between the need for stability so that toolchains and engines - can sync up, and the need for evolution. - - - The Phase 4's entry requirements for "Two or more Web VMs implement the feature", - "At least one toolchain implements the feature", and "The formalization and the - reference interpreter are usually updated (though these two can be done as part - of step 3 at the Working Group chair's discretion)." are waived. - - In their place, as an additional entry requirement into Phase 2, champion(s) must - include a set of entry criteria into Phase 4 in their proposal, which the Subgroup - will vote on as part of Phase 2 approval. - - Phase 4 criteria will vary depending on the API and its expected use cases, - but may include things like multiple independent production implementations, - implementations on multiple host platforms, polyfill implementations, and - bindings in toolchains and libraries. Note that, portability requirements may - vary between proposals, as not all features will necessarily make sense in all - host environments. - - - The specific process in Phases 4 and 5 will be determined when we have a - proposal ready for them. - - - Requirements around the reference interpreter don't apply. - - - WASI proposals don't require formal notation. Formal notation may be used in the - documentation of a feature, but it isn't expected to be practical for all APIs. - -[WebAssembly CG Phases process]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md -[witx]: https://github.com/WebAssembly/WASI/blob/master/docs/witx.md -[ephemeral/snapshot/old process]: https://github.com/WebAssembly/WASI/blob/master/phases/README.md diff --git a/proposals/random/docs/Proposals.md b/proposals/random/docs/Proposals.md deleted file mode 100644 index 31c565b2e..000000000 --- a/proposals/random/docs/Proposals.md +++ /dev/null @@ -1,64 +0,0 @@ -# WASI proposals - -This page is under construction. The intent is to follow the CG's -[proposals page], but adapted for [WASI]. Some of the proposals predate our -adoption of this process and so don't fit exactly into the defined phases, -however our intention is to align them going forward. - -[WASI]: https://github.com/WebAssembly/WASI -[proposals page]: https://github.com/WebAssembly/proposals/blob/master/README.md - -## Active proposals - -Proposals follow [this process document](https://github.com/WebAssembly/WASI/blob/main/docs/Process.md). - -### Phase 4 - Standardize the Feature (WG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | - -### Phase 3 - Implementation Phase (CG + WG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | - -### Phase 2 - Proposed Spec Text Available (CG + WG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | -| [I/O][wasi-io] | Dan Gohman | -| [Filesystem][wasi-filesystem] | Dan Gohman | -| ["Classic" Command-Line][wasi-classic-command] | Dan Gohman | -| [Clocks][wasi-clocks] | Dan Gohman | -| [Random][wasi-random] | Dan Gohman | -| [Handle Index][wasi-handle-index] | Dan Gohman | -| [Poll][wasi-poll] | Dan Gohman | -| [Machine Learning (wasi-nn)][wasi-nn] | Andrew Brown and Mingqiu Sun | - -### Phase 1 - Feature Proposal (CG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | -| [Crypto][wasi-crypto] | Frank Denis and Daiki Ueno | - -### Phase 0 - Pre-Proposal (CG) - -| Proposal | Champion | -| ------------------------------------------------------------------------------ | -------------------------------------- | -| [proxy-wasm][wasi-proxy-wasm] | Piotr Sikora | - -### Contributing new proposals - -Please see [Contributing to WebAssembly](https://github.com/WebAssembly/WASI/blob/master/Contributing.md) for the most up-to-date information on contributing proposals to standard. - -[wasi-clocks]: https://github.com/WebAssembly/wasi-clocks -[wasi-classic-command]: https://github.com/WebAssembly/wasi-classic-command -[wasi-crypto]: https://github.com/WebAssembly/wasi-crypto -[wasi-filesystem]: https://github.com/WebAssembly/wasi-filesystem -[wasi-io]: https://github.com/WebAssembly/wasi-io -[wasi-misc]: https://github.com/WebAssembly/wasi-misc -[wasi-nn]: https://github.com/WebAssembly/wasi-nn -[wasi-proxy-wasm]: https://github.com/proxy-wasm/spec -[wasi-random]: https://github.com/WebAssembly/wasi-random -[wasi-handle-index]: https://github.com/WebAssembly/wasi-handle-index -[wasi-poll]: https://github.com/WebAssembly/wasi-poll diff --git a/proposals/random/docs/README.md b/proposals/random/docs/README.md deleted file mode 100644 index bb6d81b25..000000000 --- a/proposals/random/docs/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Documentation - -WASI documentation includes: - - [Overview](WASI-overview.md): provides an introduction to WASI and its history - - [Goals](HighLevelGoals.md): a succinct list of WASI's design goals - - [Design Principles](DesignPrinciples.md): discusses details on the principles of capability-based security, scope, - POSIX/Web, etc. - - [WITX](witx.md): an introduction to the WITX specification language - - [Process](Process.md): describes how to move a WASI proposal in to the specification - - [Proposals](Proposals.md): lists the current WASI proposals by phase - -Additionally, here are some links that may be helpful in understanding WASI: - - The blog post introducing WASI: [Standardizing WASI: A system interface to run WebAssembly outside the web](https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/) - - The [wasi.dev](https://wasi.dev) web site includes links to more information about WASI, including how to get started using it - - This repository's [issue tracker](https://github.com/WebAssembly/WASI/issues) \ No newline at end of file diff --git a/proposals/random/docs/WASI-overview.md b/proposals/random/docs/WASI-overview.md deleted file mode 100644 index faabc2eff..000000000 --- a/proposals/random/docs/WASI-overview.md +++ /dev/null @@ -1,147 +0,0 @@ -# WASI: WebAssembly System Interface - -WebAssembly System Interface, or WASI, is a family of APIs for WebAssembly -being designed and standardized through the WASI Subgroup of the W3C -WebAssembly Commmunity Group. Initially, the focus is on system-oriented APIs, -covering files, networking, and a few other things. Additional domains are -expected to be added in the future. - -WebAssembly is designed to run well on the Web, however it's -[not limited to the Web](https://github.com/WebAssembly/design/blob/master/NonWeb.md). -The core WebAssembly language is independent of its surrounding -environment, and WebAssembly interacts with the outside world -exclusively through APIs. On the Web, it naturally uses the -existing Web APIs provided by browsers. - -WASI is an effort to provide general-purpose APIs for supporting -non-Web use cases. The focus is on designing clean and portable APIs which -can be implemented on multiple platforms by multiple engines, and which -don't depend on browser functionality (although they still can run in -browsers; see below). - -## Capability-Oriented - -WASI's core design follows -[CloudABI](https://cloudabi.org/)'s -(and in turn -[Capsicum](https://www.cl.cam.ac.uk/research/security/capsicum/))'s concept of -[capability-based security](https://en.wikipedia.org/wiki/Capability-based_security), -which fits well into WebAssembly's sandbox model. Files, -directories, network sockets, and other resources are identified -by UNIX-like file descriptors, which are indices into external -tables whose elements represent capabilities. Similar to how core -WebAssembly provides no ability to access the outside world without -calling imported functions, WASI APIs provide no ability to access -the outside world without an associated capability. - -For example, instead of a typical -[open](http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html) -system call, WASI provides an -[openat](https://linux.die.net/man/2/openat)-like -system call, requiring the calling process to have a file -descriptor for a directory that contains the file, representing the -capability to open files within that directory. (These ideas are -common in capability-based systems.) - -However, the WASI libc implementation still does provide an -implementation of open, by taking the approach of -[libpreopen](https://github.com/musec/libpreopen). -Programs may be granted capabilities for directories on launch, and -the library maintains a mapping from their filesystem path to the -file descriptor indices representing the associated capabilities. -When a program calls open, they look up the file name in the map, -and automatically supply the appropriate directory capability. It -also means WASI doesn't require the use of CloudABI's `program_main` -construct. This eases porting of existing applications without -compromising the underlying capability model. See the diagram below -for how libpreopen fits into the overall software architecture. - -WASI also automatically provides file descriptors for standard -input and output, and WASI libc provides a normal `printf`. In -general, WASI is aiming to support a fairly full-featured libc -implementation, with the current implementation work being based on -[musl](http://www.musl-libc.org/). - -## Portable System Interface for WebAssembly - -WASI is being designed from the ground up for WebAssembly, with -sandboxing, portability, and API tidiness in mind, making natural -use of WebAssembly features such as i64, import functions with -descriptive names and typed arguments, and aiming to avoid being -tied to a particular implementation. - -We often call functions in these APIs "syscalls", because they -serve an analogous purpose to system calls in native executables. -However, they're just functions that are provided by the -surrounding environment that can do I/O on behalf of the program. - -WASI is starting with a basic POSIX-like set of syscall functions, -though adapted to suit the needs of WebAssembly, such as in -excluding functions such as fork and exec which aren't easily -implementable in some of the places people want to run WebAssembly, -and such as in adopting a capabilities-oriented design. - -And, as WebAssembly grows support for -[host bindings](https://github.com/webassembly/host-bindings) -and related features, capabilities can evolve to being represented -as opaque, unforgeable -[reference typed values](https://github.com/WebAssembly/reference-types), -which can allow for finer-grained control over capabilities, and -make the API more accessible beyond the C-like languages that -POSIX-style APIs are typically aimed at. - -## WASI Software Architecture - -To facilitate use of the WASI API, a libc -implementation called WASI libc is being developed, which presents -a relatively normal musl-based libc interface, implemented on top -of a libpreopen-like layer and a system call wrapper layer (derived -from the "bottom half" of -[cloudlibc](https://github.com/NuxiNL/cloudlibc)). -The system call wrapper layer makes calls to the actual WASI -implementation, which may map these calls to whatever the -surrounding environment provides, whether it's native OS resources, -JS runtime resources, or something else entirely. - -[This libc is part of a "sysroot"](https://github.com/CraneStation/wasi-sysroot), -which is a directory containing compiled libraries and C/C++ header -files providing standard library and related facilities laid out in -a standard way to allow compilers to use it directly. - -With the [LLVM 8.0](http://llvm.org/) -release, the WebAssembly backend is now officially stable, but LLVM -itself doesn't provide a libc - a standard C library, which you -need to build anything with clang. This is what the WASI-enabled -sysroot provides, so the combination of clang in LLVM 8.0 and the -new WASI-enabled sysroot provides usable Rust and C compilation -environments that can produce executable wasm programs. - -![WASI software architecture diagram](wasi-software-architecture.png "WASI software architecture diagram") - -## Future Evolution - -The first version of WASI is relatively simple, small, and -POSIX-like in order to make it easy for implementers to prototype -it and port existing code to it, making it a good way to start -building momentum and allow us to start getting feedback based on -experience. - -Future versions will change based on experience -and feedback with the first version, and add features to address -new use cases. They may also see significant architectural -changes. Because all of the APIs are accessed through regular -WebAssembly imports, APIs can be implemented either by wasm -runtimes directly or by other WebAssembly modules. So if WASI APIs -change significantly, the old APIs can be implemented as a library -on top of the new APIs. - -## Can WASI apps run on the Web? - -While this isn't the initial focus, it's possible to implement WASI -APIs from JavaScript, since they're just regular WebAssembly imports, -so it's possible to run WASI modules on the Web. - -And in the future, it's possible that -[builtin modules](https://github.com/tc39/ecma262/issues/395) -could take these ideas even further allowing easier and tighter -integration between .wasm modules importing WASI and the Web. diff --git a/proposals/random/docs/wasi-software-architecture.png b/proposals/random/docs/wasi-software-architecture.png deleted file mode 100644 index 6cb8345cc43cba2410d05ee1db06e929ba335fcb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28267 zcmbTdbySpH)HZI?DP1DnGBk*QG$P&I9Rov3i_{PUN;fj}P$JzDf+CH8zyQL~Eh+uG z!RL8??;r2_*0;XpTCQ35xzD-xIcJ}JUHdwlNHrCCTr5hgJ9qBjzEqIWxO3+o_|BcX zZ!pk+C&YL={&((xd0)y%YQ3J`%EI&~UcT(ng%Lb?fkC$#@3fPE41REr@c|COlH7~L z4+`q)Y6R-)>THX_2KiVzr4xB}>h`j)IM^Q_opD&S4!?!J{-E*jq2xo+Yaix=&hMb+ zDaMT1wAt13)8{!>-aBdD^CxNZej?PNKcg{p<$9LjpQ1{AlM?51vP}1ke7$xezOR5kAz&k6@4c>j=UEvCII`o*@X|VUZoUTFZ-*F z1Py1uBAw4ix=l*=1q21?`0OvABo2rkYiNC4Uss+abonlAY%}^t z%vKS7lbo_z5Z^+-AO>CNpQIl@Vh9~1Yihwue_BBf+|H*_4+Uj?2u!S=8Z}tuoW&p5 zI~jFi9oZ81W`+_-DP)X_4Ni#)@SSgK4y7NBVebYG-b;fUe9#UGyik*TxvR?1?Afk; zsV~cGOBYJ8=t$37eUM!u>VrJFe!YF4w2gTAetE;m`_@RYgnC4KrLPSSFsi@Q>e^aa z;$i>LuuVi5m+YxdrSoh74wcB&SS(@Iu2vA(ydMHsTSK105ug=lK2;y{NnLAZW17VK zy8hMV*CN7Mn?Y#|y8J1tWil@6=T1u}Td!ZJUyWo1>9@1+BF;DYU4YM|%PQ(jJgBj? zG*?u=8mFBso3E6g({ok?I@;62;rsj1eeKdSRHXUD%R$EVi`ld9)n|9j!7@NQ8~qrs zdt3J%c&>pR;^al+!9qLjL4dw>(DD{G_km%EXYDVYsP7yBfzB3YR;Sm=8xwxC>Jv_{ zmCtEU&`zK|--Rf}y+%{EMZKuMaYhnIK@Bzd+)M)YB3GrGKG(d3H1E{;C7CcSEB2~n z;ZZS|Qq?4|i zHXat%_uw)=%vm+{Y_*6{v*@eTKd5|eLlLf}-wa9kT&>IEHb3+FP?g0M z|DsqO9FKM62RDF~g2T6$cB?KwY2({{Uo~lyNefsPm_Fur?A@q4e=JJ8t8{kXodvM6 z_YLNPP}@uy5gM*szF(Z)z;KL&bCV6&%;BTcQYf3E zj!7_cDql6qa*ZVO{#ECm$Ij>xYe?9^=c`S**hw6ct6rWkimuf61(pZ;c(rx*YRd?x=<;nfUC>La(+=ySjdQ|LbZbZi)|))49gA)y}O<& zxujD{c2cQQmWX^w2~{pli2F?XtJb1+zeUzv24fE!JEeTJiqPf2*(w?)zIs( z$WZeTdxK9GPwRV>Q~AuNs|J28Y_YPl8bms>Tv`hAy_aa#9nW zzhemNIe$qrLQ^`)rhgiC!jnQDO5m3IBc^O!oy6t=mJw*wnyIXOD73Nl5~9%JX;}}P z-s7GIx@jAy-Ehkf4qD_wsMZ3Adu8TZ3z^x@G)+P&42aAZ#zW^+pN=8UCsbhwdBWWI zFoc-MSttfoKNb#V490Y(B#5iiq13pEi`9iT7P$@C1{Kbc3ps^2@}%==t&cVcm^Pd=o`%`-)&tXA{JO2Ze`l3W ztjY3?T^y6{5nVj964rEWBr8=Yl(bHg!7su*6_=d6#`~bBA-9|Y?rbw64pI4IO3s7P z`eqrSK`t-ii`5mWg0&MvH8|9OyK}eSQB`+CeMC%VgxdF9RJ8}!hSYgx2@ezGPA(qW zQ-0bh#<4Sd;<=&&1PW@3sneWl*Tg~^4H$+JWj}U51_EPbP-#c$PDogt1N23Q>l4KY zJF4W4*SQ0v;$0x~H0Tc>UhvvC%=fP3$+|+s8tFp zXl=Iz%L2h)TLQcjxqAc1bRPh+E5$(0zA={A^7h!uJS9I^vUJ076eW0U%Zzs>v&k$?RU-?sIXIPSk1G#!tD~+9MO(>;+ zp*daTzylZLBzG2g9y(K;1p>FIcCfTOk4fV{dbVN^O7N(YIOW8cW`mDuxIx{E0G`1D zBR^36+p=`X9w@67t$s{^;8;$>waV>F7~*@KxMzN^Fh4OiH|K^Y>W}BE3@oiAJIre?wru$=~6%CSgCn-Fpw;%58d& zvPS|C(gS-)FFVoz_;oHMk2R_XMj(X&qxxT-sPlsXPq0J&_s+6}c@tt2+^m}s?Qvm0 zmUOpPT3wHWfki3TiT$}mKey=XKX%)VPYsXW%&>j8yZP2|gT9e!+eJ3-$v%_f{05!k z<ROaP#sJ}Ku1zegCwccxVX7Q(2OE$KFR ztj$Qg!lW4osqU}#G;nDYq+)D>b&uePS_D{2KvO#j zfw2+@n2(b4$pwObd4Jm>Wr36??c4luK65Qq;(1w?nsdO_ksQD3{uS1n|T+$*f(HlrUP48U_CpoIWuCiNRG(4ZO` zoX*pH@21Ca18^LJ2Zg<#<~b*-hAl|m?s5;TryMtQLE<$ntEp})J_XO2{Ea=i5X+7= zl!Jzn;g5J{0L2wmbrH?#2er#LJZRe;;!_~lTQKE&P}y{~XRBnEW2gonP@Sp>XsFA2 z?$`Ar&7I%JJy1_|%TOHeN=P(i1;e>PjfVAVQ4|>=s#AGz$`@am$26pXl<4Q8q!>4D zu5VTB6L4o*+H`NT`mNjtg(L(O{xh4Wv{)!`t;har^NM87_RZACh(C|Nn>&RDgE9_? zN5swjhZzWGa)*1p{=`_*hj2xr%mJY$9!8^aoxZoN0s@-PV*l-$j3@EeH}V>z2g8CYO}z+_hZ z0wBx*0kB?nlCIgbiK5et1}gk3T$s!pX=boD`TCL^O5TI^9a($X75JqwI*r-&dH)QX zJO)ny`EiJd7!ObLg;-rj%zeGsA!Xy4k30>>xhHj{kQ)@BNKMO;AxusL{+%4ygHZ9$zz>2PZFLsTZkTpX$+Wny=jTo(%S^3d(d@eQJzviXEE+aExvAO>-J*`BWiu zq>ZUBY_wIr%`HAdlT(SmPLsFr=^Z45jX+LW#=rtaBoH!cgkpw+e?Fe+ zEc^VNZgj~JCHVT!nq_R{wYh`Yba!S3C;=q5Po25LsGGEyX)d*_Ksh}TiNfMzIgW-> z;H0I!?`+x^Sup8(66NK%Uu)(^u1@~aQoDp30lf`~!wnDB+;ZoE-Ea_6H^xGRY&0ZO z3N?;BKp2^W&ECl51({L^HM-w}>j>+ns%UvGQX05PSfRq*Bc|e0q6hCTB34sBwI-k z3?)d@e%Kd|^`6nYM^*+cz#2)g5I+NrbpOJem+KG-kv>8|Qb~{;NEQfKj_9GL?Sy*w zPZ3E$@Y;hn+pe6cf`nrEH=YheJJd>DFa30MhY^(hc^*XCO10md?Li(o0|Rp%8SEU^ z8%+1Ulsv#3xl~NqPY>6E8s%1pBfmddg(5U+EFEJZL?Z%?Q6#BSx~D`%9Xv5(li;{V(Wu}V9-Iqp4M7fAL*=O}B%N(3$mo^R7}Fhlw8U zDJ%rR$>f{92M+*XexI+?Gh>$JpEaQ~Ll%F=K{%4#f-4ZG|NHkhaH?MsA-D~nSw6gJ z_~#Mv-#9EpDFguVO{fOo_V)KJDE|*whUD2H{|UD6o8PzKI?|y2|1bd8>)PMts)@2f z$U>zw@mB!t55A|#XEj$`#4*093aF}B`zM0 zU-o8;Yu|HOt}SnV?NTf_LPfi)lkI;hW<7;K=jYQkGAT)GAe+0){EI#rqOCQ{9Lq88 zs}AAYw3PubG$kMQe>HYLU?2F*Wz_WVTWR*2hGH^}M|1Lak6FKyH&k=CD3un)JKH}f64^X!SZDBFrU2JAYcCu0A$LWeA50A>-UYpi0g`&G~|n$NX%FR z9JgR;e)Poguy&FVo_x z!TManxB6P3l|WYirK-zx;o-V&`S9)M4HZbf#uxqM(zaO6;h5U^qJd1(=^J3ztd|^K+ZdAG`d*74Oux{h-HXl4fFBypFNZ(zC zh?BHmN~6bPRhlf;#|4vi^9wFc{);^4Z$CPNB{8vFoK1hW>*)XvVf5(_vvbZ*+Ckmy zKmI$*uWGD+a<7aVHABW0BrU7BeD}O|2}^-ASG)N!C5TdJHj_q+gf0L*q*iy_p{vPI zOF2b6qIA04Atmx#^pDB;4-SP0eT2!6_Gpk%B?ZWK=IDA;YZiWupI85$3GIgF_H47F zn6L3sqyRZ^JUE`7FutLm)82aF3e;G%smvpf@p@j?M0W9}^5O8tJgxybSJWsuiyRAB z9)AG$Ds7eH5xAe}OOd_tN)W zHkQyZ`%R1H^Q*HmFKV1#DIyy-luiK^MUY%#r$>SgM*wP^0H7e0O#{ZPA~HfJ5%EY@4t2jsj#{de0vKCA>=zwCXvJ2 z#6&$j@+e?`l|1kH<4HHj7GL~#3+Y2Xm1_a}X{7;HEEKc+FEg|%uB%;bjlh2YN@zvL zMMuNJbF=BCHJZ{OE?Z=$r{>#$cDO@TUX=syCs=h(Z7hR!vT(%x*dB+$tfsUFd53ms zU1ocv8zXi1!wC8Uanb^H$zhUVR zzI1A0VUWrn6Pfv?OQ<7|ld0@`fwVy8p9rk^94#Y;EUxubcV^jfC=joz`kmTAz7}G2 zGu15+cLip97}%fKIA`4kZ+?Ew&gpvmgM1x=$-4gYS}vt~>s3$|IEvbrSeZP>kXjzW zLF2oGySn^CqDyIjPiAswa*|NJ(N~(d-w-wNM0UyyiMKI>mFJ}W{*4R?tVD`ba?2Bb{MAxY`wNRKg=@xIyYkA~tSaJR!un9L@Vey zgukVldC0jBFA_`TtWk9Uiqr(;>az7enJ(sPTBz&#KB9kjej&AIE=O3rt+(n4xxfem zNjPrS6M_-GY;;&gdCbi7S;h|X@*jC7r?GV|cHI5HOuDK}Ci7fB(INPF++N_E(_OWX zEeT`iL-k+5W_-JvgnQG#^k7ZuGIk~){diaeaa05uL-TW`ga4@1K%^hweqX}7qdedp zS)BSjGlJka*t#bm5}~0LjD`A{d8v^s1SV;EufMhz6sM4yXWX<9ua5|7|4gvZG;c*~ zm*K4zS2wmf5t<*#mhCf5qtZ#5y3TW;lq zl7mnS(Juag#Y0%**)PxiFZq14;8_Oc-^9%Xg*HdH3Ad*=gf(Ce{BKC`4(KF8>HO5s zOb^+!@-liRkBXOU!`(~VsAo$(9={^H&F5y+4>F>HJ!cHoihn&Fl^bc$PsQl1+Me~7 z^uSKJN%;(m{|7(#9|`&Y&JTKE@c$z}_OSjvlNE)uzYGS{rJ;8hLh3c z%3BllW*R#3af@jXoQ6ktu-(|L!pM@vwFUYd4ZZ)8s0>fo%nc2hM7BhQ36bnKZC}++ z?*{+HI!=4!V}tAXiNT04L0JK;frsI+Y=ys|Ji(EFBYYw+*EBglvMC~XX#^eq$zb&> z-)(4XRMf7U2P>eO#;Cw0TW{*yug zx#T~V_n&kE$SMEOByqx((C%ODi8K#rT5JZRkHVEKKa#SL4rW~f}?X$oiC%NvC`nIFSj z{KA{5Bh91#x*<@XU-KU-e9s08lqR$yzilYCwD-K^%W_g5kVMDwysoI}*P$sb`_%4s z9F{WG*C2MIayteAcO^CL|Mb34Sbj6jZI6t_ApB^!W>~`6BBcZs>Q!$ikIzx zfNuS5zd6NeJ8*7r%&x zXy<5S7z&?Ls)=g79O@e%MBlU&+nPy;?DRddWU)X0a%|CFT$tr|`e?f)rq{z3siqv` z*m<;A`CG3+C-oW6s6=*Nu}#=b7Qxkf+C|O~6)7TIwFTTQj11!UzAYi?(KnJvM)@K6 zGVAri&m%k`oJj18q@nVX^C;V3zh?lH8<2=p+|7Z2_aV0~_aL*SbCiZ3oc+-9&0Adc zhErYRAgvi8a~mMnjN|pZQLMKY&B$H3K=_~+#TKoA!=?KK-|hHROC@A4cV7-K9RIsn z%*Us7UE=08AH|RF=0T+NQf;1oQkgcbu5VFCg}xRGD##q}+SWj}=ua4skY@p9 z?K^PmT-23(H*M9h7phvho@HmigKX zIOLvjSF>|d3Y|!q$Fe?xKkt0k@q^BS3852KA{~m+gZYr*sq0??k(QY319&KA}9hKh(X|hUISGQu&j6km|h02fCqodv24Tv^O}_ zR&B)fY(oj&OG&zrdUl+^hsnfLWslM!srWL9W=dwnGWjnBx&Pp4d+ZG66##j0Zs*0f z_X4S&sbm=EVO9IG-MCVrxM;X1(poui_D5)a{WVc`nNS2~NI1LlRKvFsN&mRZ$QlbL z6goqcgD&~j3Q~6}6O~D*?`i9Qn>PH(+PZ)Pl8X$=MtqPG%R3VvuCNGrcnu#Bp%CG+ zWQbQIIy+p@jf#yNQ@uPQe802BEC}?B{wxwjzt1oYsr}K=5!3Mtdf6%5L6B?kh>)xC zjBtd>lpMJJ!HH{7F}mMh=JW)hJ14p_oXf|MPmqKG3i?coYq;iHP}om7nbZCqj%Svi zhtp?uITK3rtFobkx52I|)SF7I${Zh-;g{P)B=-OfqX*}@i=5mqp57t!o?0wUM~%5? zDh{~-z^zLO$^cSwe!GZVb$AY6AWfe?wYRGA_*Gn*Ug|2$p|8G=TQ3#8v0 zh^YgvVBSVwV%%q>_ko|3r9nbEI>o+-ya1`e$KEsqVyxiL^l29f2N}^$^wxnK_NzMr zzIZOSEoS>RRSM((Zh1l|dmFJWD2(hWMD392u`M009Rwd-g&a>p*OIE}TI^2397IuG zKUtK5oeqb4ux#+1yOuU|wxnbK(7k2c{r+c)waWBVuhVM5Z^TcN8vW6T%<1(?&Hcoo z$v+gUj%9&8&j6_|k$@+}D&%4ANm&aw4>_pf?$GBgqpJRlbM`^y=iD5gO1Jtc{C)cS zOWV>~_v*3Y3sxlL+H4vr+gd#F&DfBCssVDxN=XE*MwrNv-c{aRBiKbY8h z{VVGFHoV!X3)#ADMCedBB?3GkcKjtv+--h5s?dx_)1xAK-sxih4~#)^p|Dr}$~d@^ zC^_}yQufQFTkMXh1_tO2uHY>I@Jtis_3rlR`>400bE5aAzTXV1nfb=JE!6tA&t?95SpS2k> z@0O1+(2mw>&D;0@o&zM52XuM9-97CB=kcZOcAEepUG9Vd1VN5!Op%} zw-MqK4QxDHEenCB?XJb8;~9q_)877(=QvEN&7n=gV|Zf#Gmi7T1?tgU4*&L696(Dd z1xuu4ttxL&ce6F_<6fbZ&e`s-j0$xgmc~=Dr}6!%>gZa|+O_IJE+7bz_7@&1U=#v= zR|I0(du>lNwV|U+{@V7GmR5Xk_$;LcBe)Wa%d>rY?};6X=xfz7Yu~&nsA=<+N*Ae2%FB5M@gw{WsUlxi2vzT62^HB`IdiaA zB9R&e*2@8l$Htk^UuX^DJWdpg$*Ab^Bfzh9PXTS>tejmjjRPgBKMcon~1t=s4!w4nT^3;SD zXnch8z)#zr8b(za2WV)ykZSa<MQx4Gi-m!fT71_?!8gn=eQnPdE-wvbk43H<(rp zeVzUFb!;HDF7|G;|A6v9vo2S;W8r#i59EC((usQ_+RE)P zsus}ucJiwhjtHfoq9Je9t9W{iLeVYh+h2ACrz<}v7!}bpR_L8QHOUJ z%QzQyxigk4nYN8U7}IM%cZrOP#>$i+Wpyd3S6)rpZh@&0v{+zsJ{Or>@IJQcI*RiwP`NUNPyA>q; zNwV}P7h=egCSbm3;#2^+UwwE~H{4JgRRAn1>EC_srh&vVjK8*_AOvLM zQcty0}^oIT~iJ>ipNRv!;Y=)~n}SU7ljto)b`7;)5VYGS{eKYsZLTAcNq^5Xer zv*+XfC6jNgD)uY*?FBu~!EIT{QkSr+*(hMh0>G>L+!|$`V z7)#tj8{FN7As6+ppr(!LLiqb1pPZg~JLd21cu>!*l;&buR!f?Se=+OF+i(*?_6UD# z!R#=D!>H*!37yT5b^$^ir$Swq z_-aew=f$j2Z`+75K+5%o)_a`j4Me|1AH|$UyC<~8LYerN zIeffeBZk`L`joWklY#cUyuN41zM#PVLxKIWYM>&=Tw(BwB9fw)ZI^jn0oyoq`4lp1 zE;4TCr7-4jsYBjbd(cbtbg10yIx`j%j%q5|YHB%E(ReI_^NLJwuq!ROkok)N%J68! z?4+1c9*gtjBp;OyBLTnw2~R{?s6qypS4=3Ztt>evW_CK>)myc~9`Cf4`5{~UYdl(I z!6pRA^2raCC~zxU0!G%9@3={!rpx4kAg-QB`RfccgLIvVKWsO@?q%t)D&K8mAa%4Y427c zTHs#pn&4CZd!K6>t4G;r_pWqdltWAcBkBn;*aBXvY?WV3vYCb}s+lWqm*QKM4GEG3 z!^`BXGi1aJsfhrta%J;dHIZjUh zwe_89(579?%69>#m%>q@A;ij6@JH1v!yP`rP_@?)S}6s>=6X#_CD`@ z-!Up{vb*R^*DVD7c+3^c5VADkqqnQl`~LS-f4D7yWwVb%mk#6Qhw6fQ{@>Cr4k}{? z5k4d~?ywmSyc6f25AqlpC@CKF45XHH=Fgb3vppYMmjol<*8UcR8QLxW2&z|^!;G0#5TQOaDcFkr_sA>6c~*$(Rei)^mZO6wZ08?JK%D z?`E_L7wUP}TM=_m%hO9z9d#NAx<36@L&MJ#F~9@1U`?zY(DQypKq1sjxYgs#^cPoJ ztYfVhSA6tbnz{mpm?BVL-?X{62s0ySWIa?W?(xNp}KGc`d?| zPU}Bw`N4N{S--*zK|@~@Z*n$qv@!Wep0Cffa~kuHV#HE1A160jmY}{qIP5_^=?jDW zSVF5XJo+lrlyO-;aiaU98}j||NKJrhE~cMi28u_48$L8p(0IcBgV3Hn6+6h5!1VTR ziQth%4_7L-g2{g_x|!7k?2)>Mf>R!E5K6 zC=Mv-T)#g41EZLfS0x+wwc~~p|HWX(gP1%BXM6A4!?U-wFsf;$w#p66+boLFgS>D< zS9@9VwR7Av$|6la0Sx8OT}=ytTnb~$^V-fDM|XnYH;_&UQl46Q(po2hIMW$diSRzy zn#NQjJgG*!lswxq8HcSiTtq$s43STGoIm-{{QwZFp9z!Wo)kV&Ng&d?RMozFOAQq4 z?zkUhBlIZ2hT_fMX`z^Oq3?$2c;(cw4P6 z-bMB4ztBhwBSCGojd!qX0x5+vqDVWUXi4;B{$i_ulbWrslhS?e*JYJh9t+=XEm5I| z>l{-VeF5txc2*egE2ALWzokQpZ3o+5;s)$L4LAHcwpZLe1kRQuY_e0*FQH8x)AoAh zu}Z{khtJPIDFpi7HV%5 ztD0qHzhl{K9wUo0IVQqxQGcdcVRL-*EylqVQ9eqcmJvU8(9@tj>hgnoSD)?_usWtT zjCT0sgnMHJeeQU^&SzWZKhSW|!hPZ%eNt!mDNnTi3NJFQYzH_`Kp)ysGmx5QqSdJOS0Os(O1ssha+14w}oz zX-#~{D68KxU9**cG2V}dN!LBiKQ&V$0F;Ib>bwVP>2vS z@LY6K3BiakdfBNLwnkz)FTZV`8rnny<~xsyaXG;tj))>QS@j7@c1AjZ6(*ZVpvBU_ z5-FT;Pj>3n;Nj2uv`wHO5K1YedXTO`Y%NwmDlEh|d0SBx^{*(e{x^XKE-3$(C$|DJ zP?z`rOUcCl%F72j2Rp)=kx_Anr-6sg%o|_*5{YQB} zn{$|Q>_jZ?ScKnQz6|wDr>Rxtzp6c*IZ{oSd*fQEy6irkWd*3-}ms>9*CCPG(j*haB();zwRm4yhXD{eGPKZHpY3 zTjN6YZ+&`7X7Qo+P0oQgory_!gQD!u!l7v`T>UgV0yybBynvb)@O6ISqU!06(BBe{ z`a2Xt#D~z957W5XZXnD*rmeKow&eHC89##k9b!gLmMjV!JW5E*gTL{RE`j_kBtW=- zf<`aSx_Tq*U2VGUH!X8c1NiWQdU*YlOYcLJ$a!>4;5O``BAs>62j&6fNhnoe6TT0x zax#ko;@rtr`7PvNb>f5Q^K?-UyWV;d*2YhM@$KwaN)=UVRx#p^B^;^EbL-e1!;>#` zRarzrvN}N>P;+A>2Q|@kb7|9;Rvu9_gy6D!Lg}-x^=@8sDF{sXF%I=H%MQ_?x_BMP z|EGz}T+H}f13Jj7vshoO^OmpB$$@33CvzQ;YQLiEltH*|%|%~RpGM3CQOwAgi;^>1 zO5#-q*Xg)1V#r|Q-mx%-1PVXxe+R-BmPlnZzXw~rk75|?(9^~u ziVBDx0=)$l*=QGZHZ1r<=7i;|aGd)He1JmkO{|ay)l7pls~BC3^0+{^p}Z1H@}U7% zq@&DojPrr(ysLPFH>jp(jTI*wie=I0@A471pQ@jx0=)NXZoe_lf$&5!^)X=q zpWox1*t?qJi4dZ3c;_7~ccvYQ9sHeKr@oJm`*UAE26cg2djc5fBbI;S)8{tWT3p{s z8TTBKpBCrk&6QAIhqif;gqfDy4VA4|Prv@Axk|w$dthnFPoEt_b$nOT9Ep#R9vCF~ z9!deAhfLuf1=>SGcA3l;9xzmxat6L|u}9XMkkk6xz^ujWovTwSQ{!yf#q;Mhd2A@O z15P-c{*0}Hb`m`Si=x!JN(o~{BUKz@(z=ZPi>(t2{BP0VJw-|F2^ZB?s|PScq8{bP zg7& zIyIv$?)!2LvfDo(8vg-J#2Qn&i4lw+mb6!8^8tnv{Whs*0ND`PX;>pcv?6n}MoRZ% zKuY(gw(A5}idwT`RI2>9M_4IL~Uo$HxWV|7FFL{Uz zHoQC+)iVV3jXc%|5wLa>&PuAP5C#OReg01Pikz&B1+gh3z<=73Pam*W|Xw4v}AupZ_SnL=6+sI)a~sfUx5F;+Pva*I?xKpb!bO8RDJL@@O*6( zxmkYL$p};o-&C*x>BXB!ougR9eFR=f(~wiaW3jw8I7HOzj0v@N`4{-|xxVQDb=ou9 z0XxH`3NRTt?>V~(X12tCFSCEw+s_oUSCo)+iH50Wct9>y0fGCk=G|GS{JK80=4T}g z1^%!0%`r_7)_wT%m3)8kDWG8g1y#MDHJI^ki>Aax-edn1$-S$~D;6kJX5lRVu)0b9 zm3X}Hzj05rN(|-|$GlQ6q7JPAvhVk=M6NKCT8BZqE7X!NcoOvA>(hnG4AtGWfd2i@ z$B;F_G4TAMrEhirc7#4uruw>@;d2c@7*MbGcky%tou9Dt^rflCUoiYTTYGVoR{24M zJrSdI@AbluhYW!?viof!HNfXwsvUNE{+Z|Htm&hbau3(X*wRs--e;y&-9(E=?1jp) zExFVDA}qmSbh1-2gnnxj>s#q4FC+m#ikQpW>^>;W_%O8i_{&yRm#pV4f^p z9x5h)X!AKg%IgbXk{FbF4=<~XI)m?0!^Rc>nvE$rhSsSfybx-eQju{kfGr1bts82} z)I)K^UacX8VeeO{_oD{0kKWH?%8EKO1|4VSxCdCf?x#7s3Z&M&t}G?Q-G z8;k727tp{Qzp)a zJvOP_Z&Ctz%ZLvJk{)6zvo)6ps)jJc=xHiID+>n(Wu8%rz9qP~1K}S;r&coBwTo#O zM>J`UqiILePy=OJQg+i$3SoIXk0ha>eJYy3O#Gj!p;Y3!>pu7up7sRk+JGV|@|DwN z$r(dF!t#Vz@_Pi=0)dvYc-CH5- zL40k?!*1MDCEAGK;H-l7wKBl;9VsGtV6qH>Oh(*L3`j5a?8kQuX0G$=O(n)f*F$%M zFzNW6^9Lkl!f0d^G(Trr9SEkrEzU?a^l8l=67ey_p!0gTZKX3@qn`}%t$9PB`Wfov z@v+ES^T}J7m+Q$UbL{=AM^a9<(|e@TpAF6R)jn$N2@-HCUun#R+bjoB@1+n}h>rFA z?kK~}R%dj%|2y6+Q@g{|^|R^Cr0fN#USlipVNB?gT;QT#0F^#9?@2oz7vwi;iAp)@ zgw=)LjBYm#)osu!UvhrJ^-Jz*aOMHtpI0|?0(WGH`JKlnU(HDe{QK^742GC{u6;F` zyT^f?!mD3pSXUu8WB5Bv6HM6Rvz-S!Xpp(ww=Xzd1)7H3MSgJuYsc07T57zxe=iar z=n#C{!ERdW0gm)uG=j#rP*vd-M1(R=!sWNl1LD6Q$F_K?bySV8rGa&c5{!yZ{BGjS#xaZbwuYyWO9a!xoA%I9))9VZ$uEX@c-$}i z(N`D)!|OZtZ`MRARQS@lJf^;LzhUEyEHP6ni_d<4ZQq9h?Zn{OMt9% zd$swplY?p^FCF3{f1T9L3%IGzna$C;t}10}v)60oD`UN&KOb7EKepyoT|N>85pWs9 zXbiMsJs{H!a|iMhBqnhl1%)XrvQ2%8(U*lmyN9Y`1*O4B`b4P}oFUri7qa}r0t-u{ z?D_RSMFM`Srm8)#5VZ;fKj7B-c!%8E4nu-F&HdpLiE$#}$bF z49N~HwznMO!5%4MEHK*|UUYOkw{F+aNo^@DG@ZCws69n5%o^2gTx!Yf(>_qq*}0tM zU(QY9ON7PsYnoi2TlXF7R%#z#t?J00F2;6Ew=R=zpX*L=4Nv%)eM##x{$A)XW9o7I zvhN3GQbhRS&}CInPRwrff#1%WVe;8fFbPGq{vH|&=&~q=wK-7XI&*TG*EmbOZIO)2 z_()}5Gja6-2p84?)-TUE3rpV+LhlB3snF;O`uBfal$g-6Y17rtu4@j;IlM&4Ctk!H zdYxu2^tq75JY#Ql4%~2yTgP2j&lhrvI1KlQ_ILXE;iBtQ&)R;2PrG%D?4uC_aGuJc zKj3B?GgiCwlf41oM*|zoNSVxaqFA?o{KcTzjEVzDsJy!C>)e37p?kS3PhP zJs?U`w}|mb_)A9z3==qncL}8(-CT+}m1iEfhYAhP8wW&@whHh4-n~rk5MXLKUBvaC zNfTC1jZ618MQlp4Q3sy+R#Rvy~fhqu1b!_jjcV@T~EW&1EQ&*I7Cacl^LPv3o^v>{A5uEX8zF11?hvlTGkp9z<1G$`5 zNY$;E5_#|1+OB+{hNaCZ~L>q(wrB!H`}?}TvR%fl6@9^X0d0jh3j1fBm=#RtpKjlrTxtl-g_Arl*~f zc8p}~*(V_|21U);;}OF8V&*N+qw?RaWi>xl$CW%bLkSCL2eQTO&X2Hr18Xn{qaq%vT z@C0Ju7RQu5Hyr6QHvR!oCg2cwKr?;%z_KabQ*I!;?C@utZ;!ljm&dYq9b&pPqh1K@ zWT-_gK;$RyetzeDkf@h{<4!07xyem+t|=LNaBxx9eXcK#Mmt4FGn2EuF?H!e!B(|9 zsk6M*u=A;Eo*u_0(xeOHInv zdgD*u?9@7hwvbtV$nzs^AyC$8s9kRxmkh?U+tz4~ z5BE?|?=dEA_)9n^V?f`nb_@bwf4 z>SWcHX-feLYe`ryKN=Cp=Qte3Ir8vCEu&5VKMCse7`F+WXT1wHXt zI>tL>`(nRz!1u8>AVvqosta!t!S?)Z47Tc~#?S*IHeNM{g}-lfdA;^lnn*qw?9J@q zckl-lcdpf10r9VKCc<1d-a0$@btQ6M_7f!ZPRdG{n`2>YXZD$Cr^3sFF>P!6=`K5> zZyugXO=lu341s==gEUWp)xx#o&>!VE-PE2`#cV>TnLd!yl0H|qalk>SGo%@C$`q+= ztM;kH`30(JAFG6}UTPn$#|cH8gT+wjTC-n{)}rR5N&KhVa%*(=jgH!Oqy*^rgip@8 zaErEIDnidbj|j($+Q03KuQ|1A@9|jH_eO%2XS)A@clnHKGm(c4&v86uv9xwF63V!RKP2 zV@9|D?kF*7^6bp)Be{Q&Oz=?JvtQ8-sTHZu*s@B#F3CROZY%^%HhQiXSO!`*?TZ@^ zJP-J6%QM^TWY*+B`W}eb+2kVmuI=r;N7a7K-{-m04lNxt4(p)My(Yp`EuiE#{waj&_I$TwbU3-ktdE z)h0~+Qn%GDb4WEytubdE5w^Zz+Afw)`96;RSzUY5dLM)NWuIo{wr2b%QQ~I}HOsE_ zV=TJcFJHxWL>EVYL*TxA74=ls<^A_n9Es03pVZ02m-=4@w2v~-DZK&niptoaAAbAe z!YcIhsNm{!Rm5-1NKE|s?`|TSP`4)b!OcbsGwT&^CEd0WiN~4Mz2nvA=XBW>O6$hy zymz$&yysp&V`vi3B*{lSzobg3K6lf}sgu;x3&;y_G79*H-(f;Co$l~M{7c1(yUcxkc9vAv*%V)m>mb~Ytq{Y`C5njE(u<<4I(Z_TFc2v2k$xLp$Zf}oh*V-JB zQD-sP7p}>U|B=RU#_nj_mPYYqRA9o0iD@m>deU>U`yVXs7%_h=Jo+5PcanS6X4!k( zmF7#Wf>Rum{Y8n&x#&DO=eLj5Bp#JC)0lfBy|DcczfLar&@bz4rRrCuYtOVc-@MECBS5ut zCSO@$__5iqUd08?uds-+?(SM-zsGXXU2R&^z4@;dH1ilEo&0##PyATUy*KI>FY+rb zn!Rac$R_$7M&@KISXeTR&KOE%4NU_K^pl(TM0gzZS+#R)3VSofKhPf->Tvwg6`gC? zVF5l|Pa`?4U#M%cSd-qS@0VI}ky&BV4mOo?S~83!*a!_fM*5`vo_EFh{P}@6+R^tb z7caSfrD-1SHQo2(pUOZ!_@%M|r4sXA|6fN}!B$n*M3s~lk#3Nd?(UKjiA#4~x?7O$ z2I=nZZqQ42H*)Fjj_+jrkHwu91?ISq5hx~cKmneHcl;!HQ3ZegwV+eRR#N^*x67>N8sL?ge1 z@XN1a&g!bKo;`)x*+v&!RnWQm$V!@MORTz;NM{22Vn0~^8n9^omRiV3L;Uuj}UjJj= z7PWzay^yvQ@`H%1&oo+tHM+C}SoHDaBTCWd0UDDgXa_2lY zE>gAbB*}$}j?6;FJmHI|q!&=D$KJ9gCi4y~2Tl-;^V+Q);Y96bQc|kGoe?@4b*Zt9 zoDI}=q@GD36~=N(F^+j7jK#+vDo8qP9{slelzChcp&J|bGF+QY83JJr4wKIw&hoPE=Mo7 zIttE~#+C>?UB_0%hr-r`B@9iQEnPtqr|De6F1*?KXxD?JWJ7o;lLbj8<#nc=C5g9 zY+f;18pa{X$Kj{*4<_Z!!ow4ai$f04$E9}bdQH{FA+GzF7LBO_Ta!LP2g6y9k0+)Z zS{%BmO;#g{5i3JniMJ$L<+R;J@$Rb2(P?!X56aBz_;^_If2OJhdCa}9|J zIL+}kV#k#X%oWn_tx9X*fRf}j?qGPmZTmTwS&LCORr$xH6Oy#bhj7>S;n3dBQ}kt5 zn-qv8ke6N)v##dqC-v?iOAofBu78ky!Q3lgf9@-1rH1 z0`_DjM9}GBT&}uX@u3@mFS91%185A(u&`|r*#C)HoC4= zxri`=Egua3;sqBiBOlNU^E;3b5M8w{>I3;ZVP$-kJb!n=K!#8M4ix=T6F#J>-MWI! zM`G!(sOhp4I^DA%QzXWs&$JmxCX~pgmc(~u5rK~9`fob7HzAH|pRu|Os5SK>n?)C1 zuC49$2pY|QiaEk{BNOw6vC;$|^F2XBIsQ^|GNlO!@Et&{f=68I;MIJcNMdn@0}i^L z&DTygbn<0SQR#z=^EBn3nr9T8JUGm&52<;v`AEmWcuN%mZ>}n$H0?xKmKp+|YL>PB zwji57VinNWf>tr;jT10;(Yx$!KcdEd>vFQ%`^j)~barup=T+bS;P1e$oeJp*qn|v; zBNfSxO&2~n%gf|+#ZM7bq;{!^#Ox3pxJiU~Q{dNX2OnS;QBpO!l`hE=*}il9N{UiY ze68#v`L@H3Bn0F(m%i^K4~t?5_4*uE{J#t4@pT&|EyED+)ucVId2{ua=5juCX9za3 zP0d%?*uP~YVN_=HA`-y0ZTUai%}Vpp=bVVKZM}`|+t^#~xD|3vfFgkJk3+p~1LsbMp|i8Lg$tcJ^gw8{ZqPnG&onjJeYl z3-5!-7;nbdgHpG+BXKkIUOJ9h+lAA>8{n(hRHfPvsQw(foxUSV1H^8tSn70GBgpa1 z7p-u2zdBxqXS(Vu!T+z@iM`@&y-l+6vR+v?`Wyavv8yap+!`^M({}5#E&UF2>)SP0ytmN@icYB3APSHm}$wIXVD|0*yDd=my=cZ@8mc z3S*SENA3|NKYG*3JfyOXO{LXxeW=OC8-F4H=7b;OwEg57*>Co)6`J?^@OU0$ z&vEVUZvh}Ahd5I00yi*RTE=-QTyvRcaegGJ4gU;RjX?eLsO$^+(nXP%70_fEKDZRx z3qO4S_-QBX31IAW9#`P=6LUE|hJk8;NH6$jyQk~IDB)q>iM#JNlmua<@5UQ-<|JMA z!tBADYPv2Y6m3{9sU>aB2a|~1a_euKb2&bmE6Dg^Mwe=4D`kEzM0ECUIscBeeHq5f2qa%-NI(MVeU}~PJRfykKOxpFm z_0DZ3@%)yC-Xb>KD?XE?IFdxGV6oBf(AZbtY46$P3DM;%n{H8@bE{Huej(^>OvTjsLD3U-o=@s1glM595f!MX5+Q4WD95 zpO;F|E*}{uz16=_X1+9UI|TjqF(jMDp2pJK42;z$dpnmV)Y=y3p}wT6Z|ac2)VTR>JM0!;K5!cau?f)*cl2Y09#uIA9=#HZq8==gvK~ z=fXi~P#%+0iU4EV;xxrb;pZ&Fb86M&ooqMr_X8vdQV?>(@$kj+2r1i7-yH`TSSd=s z2C_@xvtZ%DtH;0aPpA^kDuUg1fCG%;P0~PPUWxkX@>HJkBXRsuY4c;pw_Px0S^(@y zkMru{R+Ca+A}Lp9y05mKtVv-NWC$_5lk@^4<1D?no^NK zU`7dTz+dQfh$WGfzzar8ExSk=oHV?Lafxx*n3et+BRr#~uyMQxlav)1L`IP>qYv?h z2O~}BE4opfkSPpeGC#-M2udnRl7zqz4sbBoM?n;hK|<M?(5j@nI!yxvbwC>vlJr_=^X`N5;(F$gyfaFPHrGS3ni-?z3oQH1My z$~EE5e1IIrvWPQEuGi=A!H<%=L8I`P=wJJNB+UGs{cpCLzvKN>{sr|aAT@CxEHD^d zRcr2XZ}p;t@EUtvNQEXNr*JT!*}<}}{1=3umr0u0u3*dYxC<~PFt+`1CO(6a4&Fob zqgSDYAHj&2>Tx)KAMcNt!YM9!3fPx=C>bd#dq;;LXkf&r{?>ohGH>qh0SC3c*H^6% z-z8f_oGxd{@ME);0sVJB&)|f%*j((nKzZ|SrK9ir$#VIWC0sEJ#q`LsFqdthsau** zUL&tsR51DhJg_td_^Bl;p@v>!+0Rlq@Vb4aat7u|w0*_zSMXFdBW z8PL6c133mTH|tqWEBi2I3#mK~8ero4JPJYEm2c3-8o8LKL)QNCsg;QopO}qJIm*%v z8mzoK=f(PWM^hEB>tdZ`&>#bbkjz8rwPSHEjyAK@XbHzxfyYT5VX|X z49x?~FEjpf-;)c5(WdD1jDUxD#(&V5)JumJ<^@c9-YK09&Ks(5` zVusEa)4D`w?mb^MflA%kMMcBKK+$PAAOEDo{r;!$?hS=9WMc4M0&YCI4`XQr(lz*u z-Zv_@(OXfO{JK#=$Q1)!FTwxgTWPQw=piN=F*;CD_SvqM_WZnJhXV?T$-z-X<-EgT zhQCKcg1Rl#m4>W@k%jy3K(6{9f!@_T1MIypr+(g0?sbt;Ai0h4NS&K47jyYz{ut5w z@HQc*(Yd(Mze zc#Uv&|D!cnc+KAXmB#Ju{M=A4t%L*J537Q=kY;AL!t_URYie|z;5@{Dyf45 z%l51)^=}?CQk|7V({ub|jD+>mMtAp5ZH8@eq`4iR(C*@j401l=_qlC7M97psS4h$j zTvWv24n2fekeHaQo*(bHZpmaDQBxIwjeX$yLtp*@=BBo6IdAW&jeQHlC14=nUQGtL zgpHNqmKz48_Jvc*mUL4lTGflr)p0l^v@qhZB@14nU3|_s@gpJS4%1P zcHAMua9IRU`Qa~9PgmPeR5p38qtxT;xJ9zS@r<>|3e&d z3T*+tDoyAMdBUgEl!{&Tq`Y^yYK0{foVReF?H1OrnXDLI&a<`eO75&mafjZ|9eEX& zFjLr8%Yni9dgr@G%ow)HXHVlI1q}6NKQa)fQ7#d-v1s?t<>N@spJR7{z1hV~$hbkA zDR3LiAPTCKA5}**{IdwD+2hkz(w1UWdde#ZJRinbm z%_I=to0Kf-`Ox*aWsTyqnHc9A8t=gw!y2}h^;w60@I45?t@6@7qH}Op_F5#lS(-6^KQ-Ju%KIC-4jBf=QNd)QgLvC#W#J3r=zuGZ z6_Nvz1FY`%O9EO`E&tryE_hwuEMTEcGR*vfE)B}gt!a%IzT7wZ}85>M^O<4qc*+O+AT%EoP5;Ih34_B9Gk2T8Ot2A2{@40>UXy1>6E| z-nPRnVTV5|7!cr-qtfyCq>gb9zA4fys-q74+JHq?$NOGj&iV{HP8AEWS?k=Zw2^Al zGLEm>#`Oca$Jd;5V%L%T|%xeZGwV8gy|t*Tp-#im}{ z!W$b$X8Z}0_%nnyLo%HcniETVA8Fj4J1Hdoz?aanqi;)Cns@`DDHy5D~96g zZ)@+Yp&(wn$OKuOuWmBPX!%{Z4v_fpIW&iH6>%zaR#;xzF<(-%Wkn4_J1vwCMHrN+6v;X)$&=s4< z)mI^yIak2Rc>k>AhgN)Hs7Jp{Kraoc%(O+GRJxTy>Kv|18L>sp~zExB%#)fiqeRcE}< z4mKvgwnAABzixW3>!gV!m#W+_|`0y_YKasGj+ND zo28Voes+91{u?oS-R5VX>P*UI;ZLCg+1hG$@K)vVVy5;0&D-j)A#$0?FM<_Dva>$6i%p3ZWi&@=`h6$L#uJot%mQUJN!8RnxKk(eZz#>`0)=f~}` zI~(&=HWg!A6je$`j;dg=xT<{CVL$ElVS?8wzL)%PeiC6+di#E=17Rz7WbNT%de~5H zX1f!|xaol%qk!+dxE|N-4PC&K`N9})`ENBe(GmcO#(<40YUo86P>;Sahnf!i(w`<> z+vZFs;X@DQ4gugK+e0H3`NWj8<7AW$o$!Y+SoLATuMNEKM<0nsR2GOdHz>;q%>?&%Quwx?i%sI49odg_>eY9R~^DZc{$E#eE^+K z7V_Cy&W2HYIrXr}Ph?(17r2KLHfYDk+D1t6D;XHTc#k04P#qwf(2m~U0@OXH6Gp3) zQ*!VlACa(}-g;HT4vbduxdG9cEc8BeBCLR~ea>Mec;gCHU7U*YOp)m+h$^Tfzf3PJ z?u}BAjxh!T@KGh03r)=LewhXX%r`SO6j`}9cV+-&J;zT77pWqZ2(VztObSE*y_GYQ z1XkK@>+?`ROA=jDvVdvaj-MJiwp=Bu%9_f4dMYCK430HcCb-ach)_P2oTC#muAr2-41DiozH0CoDQF&x_h)bikdtemqP2Kl z6G9KJ6?bnBflcY?`*xYIm?9t(NDFdS-CJOcwFxSH=#TNH?oFs_b2+&$QyY=lHtaeU zk%sS5>FXID%}zSG3tX9Rp#s3^3pZH#6t;o50}^z(6e`x6klM;rJl;7z6yY5P%VA9HR%YDgYgGd-TGAFFOe|_gKddnCG=toC2U1?}O^} z;6ud}QV%As4=25U{w$kea;p}Hw=P6Zu~)>z<*(rb^AEhJSjTzNNEE(CS)#4|FnPe} zD!1ww!5(~KcfG%ZoZRV!V-Dey(Q)O!0M8TiU_)O3L@*q!U|}%P3ZQ4ll14qfVb6|u z!N#4rAub1!1#0=hi2V(kOu)xWn)Gk0Cj|HymQEpKad@PyL;7ee%6~29BR-$38HArN zEJDyQIa`U-Rv~D?a#^SSx`f<#^v7QN7A!=E2UK8E$* zgb17JtF$~k(h>G|NHID@rQ6;*3z8<#3iSp8W|KVS%TlCCVQ z5XFmN@>{#{pC$LA|CwvDLJ5RueTiq11UdIAmX-SZl>}y(g0>g`QI*4Rp3=>El7~7y zwuGZa8{~O4k0%SbuUx}&*xoKg(!J^cH*H_&9<(%*@E>C zB36ONjrgA8ziLfZzZ*tH*;DP`x3GvxjT2-^NVRcxrQ!)t1O6{ zC^GD{Zs-s=0*96$lkE7!H6vQOVUqr_lAUosIdilLR6v$q}OTrG;++O>$teqGyyA7}Ay#9C~2cHRI`PinP^*obQdHw0?z6mEAG{%hrJglaI zV`=K0{fZ|sJwWENz^1FIy(dq6U%LiGfs{_;^-=PSf!VFTSbgJQ9KqcWu9F`;#x)!D zFLGCufKWS`&@hjlX&8Q$AcX#BwNiD)bF1sB>ukPpM*nzmsH~#rhHfT_^X9&D?=*b> za~Ge+@bG(V{OZ@6Q>O=O#?`9Ij>*P;pe-G^<@3$fy&ld_@&UqnAdxlVI36-Rlb@0D zE%+q9qHsd5`_w?*dCzyH_61Pd*3^n^h&dScJSh8*gk9#;ZS_*7Wt4dhHb&B_*Cj0a zEB*wM{(u=hRk7qWL*jW+`>^s~^zK~yq}d&Q9oHH0!^c2e-^yad2}JrWGUhqv(W34o z!-HH`EwSKv(AgBN^KErb7y$9>{+=ET>kgy`>`YMBxP`xdp=$dnEJb{ zUN<&T4G?}Q>%O|a*%5c(HLbaidLKHV{kx<80)D{Xkdk!u!_x^DhkJ+n=R;W()T)p1#%r9n@gp=?6^>35V(ew>5=&>BcCW4DDvY z!I>nwxu5JLDXfKuxY47V`jrp;cIZ3iR9#pU%t-5Pq<}2Qba29h1WS;M#5;a z?A>Y#8v)nF0_k(aLpvS}1u7kGsIny_0`)PGJv2O&hgJULXe~lX|4$u|1~sE-Uu?bQ;vK| zXM~DvCSR_j@P^h()qonnGvuG2yA}ukpjOxX{rL1>n*ob%qi!4h=^R!9L<#i<28-B) zMGlpJu;E0muN7_X$#Hs1eLBy>-74yoClyR3XUmv{(3|V_AqQnxnKaO{jSUuU8^sZ; z+pHLV1BFr#wPf&_Yi!P#OC=50fbCIP9L4Rja&E(}egwm;=x+zUkzIXN#^^owZl<7# za5=G7vF_Pw!R*5Aa*+}qDeY;GAZc3@G5T*){BgFWKx&5@DYg zZqX`diT*8yx28oW%kW=p+*#l3_|H*wEa^k#_&Lp`k6ahz zMa_}hDGo~q7jGNusfd!g!4BTinv15)x9g_Kor|WtIKSC(dVjH!E95x83mc(?FZ>`O zR?hlaVeF$^y?D^K;U^3FFV%w#7*bX5cm?0he3uEEHVO7ovN8TmO>rl*k$NY5OEYo? zeG=Mx;;_+tgW+Pjrug=Bn|F=_{cZ<)s^_*-f*r&U{+k?EzV2`{f26{6&J)Q#s5X%S z-cDd&28unL;Rgvgw z1+k!32`$&q;}DvXkTZUJezX1*p>ZU;$hl1OX-Q@g8?mVy2qqP{y9tl%nxt*&W!Uvhtk5(S;cl@q=cr zHf8oKuDojvl0p0hF+cmN%MVI*rqF-38hak0(^tvbIDXd~t7thU^rUt9himoRvpMIM zoMQHhC_(fEMkQZR&gp_D@`0ZBOh;^VvAihlknd)$Z#)d@oaBuTi#~6`aZ8%bV1>yb zUio>J8uHkjMh~Lt*0OgJ%c=4o$;}q2dQ|%QyD&tGZqd#j)a3oTjzWFJ^6Mh)BY#s? z4drm@t{Hv`m_UT}V764NvF80d3FG4_dZ?tM@|kljc@qO8*{Rr4ky#4#FUj-jb#=Wl_f0I-$>Hc#k?23 z7-{}vAm#hCG<+X4A$&9!4GMXt`MSzEpHphiN=r)C@Y4Jc=02+Aq9xnUFGsNwY=vgF zR$Hih-~<7ET6a%PT`EcXBA<`J2bvcv_cr%Bg1FTKkBC(1%#n<>aSF4Rh*btx$RIShdd)Ij93OZ|UAMqy`VQj9G_-kf6d& zu!V81Kqar8i~4oLv24f#Un58pify3|*8CE)~1-WJU!muyOZ};%W zMYwi)9n|s{g9SnU%va>N@;LKBOosT8+#OMl^%VupbXM;B=iHMkTMTE_s!sa7@%cM* zZizt8&;6>f3^+I1TW;F6&ZsQ;96u!Tl_9*#nxwZ^Ki(vWbaW{z_i-&hIkHjmk!8Yw zu~AVlz@mS8lQd+l8Ab#RMEsKR_KiWj?8D7pDCt@}UCi8Xs?d-?w|24*GyOjo&n;xK zMTw>V?F|X$hzAA>%r*dD&Qw&ySmB^mTn;)1xOnT~Qt8DW&yc zpZHJrOI@5>2({{>i`k;ZM4v7+H!gUue9poF*BkYOMxmj2-55gm(@x`i?R4 zl@Wb4q*(^)q!TqENr@);!)t%%A#gzhHjW1mrjy(4RJ_x_x5LeBPa0{hKI^Xi^z^IM zd|40`m(gwdpS#$ta*5pUw4aepEwf6?L-d+7&Mcf}70jK$z?OcFZGA{dS`eHpRV%^& z1qnAr$?ANW)p#nuB~Z>!Q2#;psb)8ph1gH*|6jNv)g1bAEQ{c##uOQNIXj|V9PHux z@H*)u+-mxeNn#MS0r4<1}Us!+GB=I2QC!z}zA zFK8>0?TPI;m%=1=d402<>{Qn1@MnN has a proposal but they’re out sick today - -Till: This would make it hard to make minor updates, because then you’d have to change names every time a version changes. - -Dan: Resolution of imports happens in the VM. So we can program how that works - -Till: If resolution happens in a client they may not have a complete index of all modules available. - -Dan: The current proposal (wasi:package:semver) assumes all modules are packaged & available together. If we want to have something more elaborate - a url, a hash string, those are possibilities. - -Luke I: Its desirable for the resolver to have some way to find other versions, so that you can specify dependencies as “greater than this patch but not incompatible” - -Till: If resolution has to happen using a map, you can put the version numbers in the map, rather than in identifiers - -Dan: Resolution is necessarily not the host, some earlier packaging step can occur that takes advantage of semantic information - -Luke I: is it always a precise version in the import name? (some examples given) - -Dan: We should make a convention about whether the VM is going to download modules for you, or the VM is going to just resolve links as they exist - -Tlively: It sounds like we have differences in opinion about who should be doing resolution of version numbers to packages, and where packages come from. Before agreeing on specifics we should figure out the user story and what goals we’re trying to achieve with the versioning scheme - -Dan: Sounds good, does anyone want to propose a story or a set of scenarios to look at? - -Pat: I can provide a story for our use case, but I want to get input from others as well. - -Dan: Moving on to the next item, Weak Imports. In Issue 36, there is discussion about not wanting a system that forces an additional indirection e.g. through a GC Ref. - -Sam Klegg: In your example of importing v2 features and then an optional v3 feature - -Dan: V2 to V3 is a major semver bump, If it was a minor bump maybe that would be OK. What about e.g. most features from 2.2, and this new feature from 2.3 would be nice to use if its available, but if not I’ll fall back. - -Luke I: If you’re importing from different versions are those versions separate instances - -Dan: That’s up to the VM and the module API - -Sam K: We don’t want to have two versions of the same module instantiated to satisfy a dep. - -Sam K: Would you put a weak dependency on an entire module, or just on an import? -Dan: I think we want the ability to do both. E.g. If we have a filesystem, then we will use it to do stuff, and also if the filesystem supports this individual extra feature, i’ll use it. In both cases we want to be able to fall back. - -Sam K: Seems like lots of overlap with the semver proposal - -Dan: Semver just gives you the minimum requirement to be functional, weak imports are for things that may or may not be present - -Luke I: Semver protects you from the ABA problem, where the function name and signature stays the same but the functionality totally changed. - -Dan: You could have a weak import, and the weak import itself could have a semver tag on it, or other semver relation operators. I’m looking for a general sense from the group whether this general idea is what we want to pursue. Out of all the proposals it has the advantage of not implying indirection. - -Luke I: Does this mean that wasm is going to have to support weak imports so that there is no indirection cost? - -Dan: It would be a requirement of the engine to implement imports so that there is no indirection cost. - -Sam K: We’re explicitly trying to not push a new concept into the core spec - -Dan: Is there consensus about not trying to push new concepts into the core spec? - -Jacob: are we going to expect this in web embeddings? - -Luke Wagner: You could polyfill this on the web using javascript stubs - -Luke Wagner: Rather than mangling the string name maybe you could use a regex to carve out what part of an import name is the name, and the rest is the wasi-specific specifiers like version, weak - -(Some discussion on details of those ideas) - -Dan: Is the basic idea of weak import, somehow mangled into import names, - -Jacob: We could use custom sections for this. - -(Some discussion of how you might use a custom section) - -Luke I: If the custom section gets stripped thats a bad sign about your toolchain in the first place. I prefer this to string mangling, it doesn’t eat names that now become reserved - -Dan: There are escape characters and ways we can make name mangling work. - -Tlively, Luke I, Sam C: all in support of using custom sections as opposed to name mangling - -Luke I: Import maps are separate from the module itself, or you could put a default map in at build time, but the idea is that it makes polyfill possible - -Sam C: There would be a lot of repetition of these annotation in the import names, custom section could solve that - -Dan: Pushback that custom sections are for non-semantic information - -Paul S: Would this mean we now require those custom sections? - -Sam C: its extra information that says the module would like to have the following version, the following weak sym. The engine could throw it away and it would still possibly work - -Jacob: This is roughly what we’re trying to solve in the webidl proposal as well, we’re specifying a custom section. - -(Some discussion) - -Sam C: You’re describing the environment in which you’d like to be run, and the engine may be able to provide the right implementation there - -Luke I: tooling is easier with custom sections, you won’t have to change imports and byte offsets and so on. - -Luke I: The import map proposal says to just specify the bare name to import, and - -Dan: Does someone want to champion writing down how using a custom section for this will work? - -Sam C: I will write something down for the next meeting [action item] - -Standardization phases -https://github.com/WebAssembly/WASI/issues/38 - -Dan: Derek wrote up a proposal of phases (linked above). In the core wasm they use the concept of web engines implementing a proposal as part of gating moving it forward. We have more non-web embeddings to consider here. - -Luke I: We should document why we made certain arguments about compatibility as we go along. - -Dan: Rationale is important, should that process live in the phase document? - -(?): Maybe when we move to stage 3 with a proposal it should come with an agreement about what stage 4 may be. - -Derek: My desire was just to come up with something that mirrors the CG without specific opinions on exactly how. What do we want the role of the subgroup vs the CG to be? Should the CG just rubber-stamp things? - -Derek: We haven’t talked about the goals for the WASI api spec, should it go through the W3C WG process? - -Dan: That is what I want us to do. - -Till: wrt where it lives exactly, it could be a sibling to the JS API. - -Dan: this is a non-web use case and W3C is a web org but I don’t think its a problem in practice. - -Derek: This is something between the core spec and the JS API. WASI will build on top of core. Maybe some of the WASI loading semantics will be baked into the JS spec, or maybe not. - -Dan: How the individual module specs get packaged into a spec document is something we can resolve in the future. - -Till: Volunteers to champion the phases document diff --git a/proposals/random/meetings/2019/WASI-05-30.md b/proposals/random/meetings/2019/WASI-05-30.md deleted file mode 100644 index d6c773aa7..000000000 --- a/proposals/random/meetings/2019/WASI-05-30.md +++ /dev/null @@ -1,116 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the May 30 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: May 30, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Review of action items from prior meeting. - - Import names - 1. Weak imports - - https://github.com/WebAssembly/WASI/issues/36 - - Relationship to core wasm feature testing? - - https://github.com/WebAssembly/design/issues/1280 - - Should we push for weak imports in the core wasm spec? - - Looking for volunteers to draft a weak-import custom section doc - 1. Where should wasi-sysroot live? - - https://github.com/WebAssembly/reference-sysroot/pull/11 - 1. Identify a module for an MVP. - 1. (Time permitting) Plan iteration on additional modules - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -2019-05-02 WebAssembly CG WASI Subgroup Video Meeting Notes - -Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-05-30.md - -Attendees: - -Dan Gohman -Luke Imhoff -Alex Crichton -Martin Becze -Mark S. Miler -Pat Hickey -Tyler McMullen -Thomas Lively -Dan Gebhardt -Sam Clegg -Mark McCaskey -Nick Hynes -Nathaniel McCallum -Lin Clark -Yury Delendik -Mingqiu Sun - - -Meeting notes: - -Review action items: - -Sam has a document about import naming. TODO: insert the link here. We’ll discuss it in the next meeting. - -Action item: Sam to send out the import naming document. - -Weak imports: - -“Weak” in this context is not related to weak GC references. - -Desire to avoid depending on GC spec -Depend instead of reference types -Pat and others: push back on depending on reference types which aren’t in wasm MVP and not all tools support yet, causing schedule delays. -Mark Miller: How do capabilities work if we don’t have references? -Discussion of the mechanics of i32 file descriptors, which are forgeable, and which don’t enforce PoLA -Luke Wagner: Multiple tables may help i32-based environments have better granularity. -If you’re using C, you have to trust anyone you share your linear memory with. But other tools and languages and implementation strategies could do better. -Discussion of techniques to achieve various granularities of PoLA. - - -Action item: Sam to write up a name mangling proposal. - -Action item: Mark Miller to write up a vision document for using reference types and reference-counted closures in WASI. - -Existing toolchains for C-family and similar languages don’t use references. They typically need bindings tools to interoperate with reference-using APIs - -Discussion of how bindings work in various languages. - - -Action item: Dan to rename wasi-sysroot to wasi-libc - -Discussion of the WASI repo structure, pros and cons of using multiple repos, inside and outside the org - -Discussion about organizations and repos. Emscripten has its own org. LLVM wasm backend is maintained in a third party repository. Concern about having things in the WebAssembly org might raise the barrier to entry for contributing. Having things in the WebAssembly org may make things easier to find. - -Action item: Mark Miller to write up a vision document for using OCAP in WASI. diff --git a/proposals/random/meetings/2019/WASI-06-27.md b/proposals/random/meetings/2019/WASI-06-27.md deleted file mode 100644 index d988ee47b..000000000 --- a/proposals/random/meetings/2019/WASI-06-27.md +++ /dev/null @@ -1,241 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the June 27 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: June 27, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Review of action items from prior meeting. - - Import names - - https://github.com/WebAssembly/design/issues/1286 - - Weak imports - - https://github.com/WebAssembly/WASI/pull/47 - 1. Meeting Schedule - - It was pointed out that having the WASI meetings the same week - as the CG meetings is inconvenient for some. Should we change - the schedule? - 1. IDL - - Cap'n Proto: - https://github.com/WebAssembly/WASI/pull/58 - - What action items can we take here? - 1. Blockchain call extension - - https://github.com/WebAssembly/WASI/issues/56 - - Meta-discussion: How should we approach new API proposals? - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -2019-06-27 WebAssembly CG WASI Subgroup Video Meeting Notes - -Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-06-27.md - -Attendees: - -Dan Gohman -Luke Imhoff -Sergey Rubanov -Paul Dworzanski -Pat Hickey -Alex Crichton -Martin Becze -Till Schneidereit -Lin Clark -Mark Miller -Mark McCaskey -Sam Clegg -Nick Hynes -Jakub Konka -Jlbirch -vwo - -Meeting notes: - -DG: Second agenda: -Luke Imhoff seconded. (Till seconds for posterity) - -DG: Import names Proposal: presenter is not here, lets move on to the Weak imports proposal - -SC: We talked about the weak imports proposal at the Wasm CG meeting about whether to represent weakness in the function name versus a custom section. - -DG: … align with the (missed it) proposal - -SC: I can update the proposal to go back to being a custom section. The function is imported as normal but whether or not it is allowed to be missing at runtime is specified in a custom section - -DG: This allows us to skip all the questions about name mangling, polluting the import/export space - -SC: One issue is that the embedders will have programmatic access to the module versus parsing the bytes, e.g. through the javascript api. - -DG: It makes sense for there to be a custom section javascript api that can do this for you. - -SC: I’ll update the PR to go back to custom sections - -DG: What is the point where we can establish a baseline for modularity and move on to breaking up the stuff currently known as wasi core into modules? - -LI: Will the JS embedding have a weak imports attribute on imports? What about support in all the browsers? - -DG: If someone doesnt support the custom section then they just have to resolve all of the weak imports, and if they cant provide all imports then instantiation will fail. - -LI: Can toolchains ship js that detect that instantiation failed, and use a different binary? - -SC: The point of weak imports is that only a single binary is needed - -DG: In web use cases browsers might not support the weak imports natively but you’ll be shipping a JS polyfill for those to implement WASI anyway. You either support WASI or you don’t. Supporting WASI includes support for weak imports. - -LI: Will there be a document that explains the layering of these various features required to support WASI? - -DG: Sam’s document is a start on that. We need to do more to clarify on the layering. Sam, Can you add more to the document to show how it fits into the bigger picture? - -SC: Yes it makes sense to make all of that part of the core wasi spec. The things we’re talking about being in the core so far are the import system, modularity, naming conventions, application lifecycle - -DG: This will be easier to do once we have more of the import stuff in place. I’m proposing we defer more explanation until we have the import system figured out. - -LI: There was back-and-forth about different patterns of WASI modules, reactor and command, in the spec - was there more discussion about that? - -DG: That is ongoing. This can be an adjunct to snowman bindings - the reactor and command model can be adjunct to the spec about bindings, since bindings are specifically about how to use a module, and so is a description of the lifecycle - -SC: ES6 Modules need the same sort of lifecycle support as WASI does - -DG: We’ll also want a custom section to say the entry points of applications and so on. - -LI: Where do I subscribe to updates on this, how far is it in chromium or mozilla? - -DG: I don’t know about that, https://github.com/WebAssembly/esm-integration tracks the ESM integration status but nobody here knows about the status of it in browsers right now. - -TS: The status of Node is they have almost complete implementation. I’m not aware of browser implementations that have made significant progress. - -LC: I’m not aware of any advances of implementations, apple had an early implementation but i’m not aware of updates given the changes to the proposal. - -DG: Let’s move on to the next item, left out of the agenda: last meeting Mark Miller discussed a vision document that laid out the use of Object Capabilities (OCap) in wasi. - -MM: Yes thanks for the reminder. It had dropped out of mind. - -DG: That’s ok we’re all busy here. - -MM: At the wasm blockchain meeting we discussed styles of ocap systems that do not support virtualizability, versus method style, where the behavior of a call on an object is up to the implementer. (...) and I looked at using a Capnp-like IDL to describe APIs in an object style. (unintelligible) looked at an IDL that could fetch type bindings and an adaptor from old style bindings to new style, to realize the virtualizaiblity of ocap systems. - -TS: Mark you’re dropping out a third of the time unfortunately. - -MM: Ok I will put my concerns in the document that I need to write. - -DG: Mark and I discussed this and it is a big idea that I think needs to be explained in detail. - -DG: At the CG we had feedback on the meeting schedule. Right now we’re on the same week as the Wasm meeting, an arbitrary choice. Would people prefer to change it to the opposite week? - -LI: I’m the one that brought it up, it would be nice to have more open time around lunch on these weeks (in my time zone). - -DG: As a poll, does anyone object to moving it to the opposite week from the CG meeting? - -(no objections) -DG: Then we’ll skip next week, the next meeting will be scheduled for 3 weeks out so that it alternates with the WASM CG call. - -DG: We also have an agenda item for talking about the CapnP issue: https://github.com/WebAssembly/WASI/issues/56, Martin can you fill us in: - -MB: I prototyped what it would look like to describe the interface in terms of capnp, we got feedback on that which was helpful. The impression I got from everyone is that customizing the Capnp idl is appropriate, we’ll write a custom IDL that is influenced by capnp and I’m working on that right now. - -MM: You saw my attempt at a BNF of the relevant subset of Capnp? - -MB: Yes I want to rework my pull request with that in mind. We want to pull out the versioning integers on all of the methods, and adding (missed it). It would be nice if we could express things like the ability to import globals, memories, tables, as well as functions. It would be nice if it looked like the rest of the webassembly stack, so I was looking at using s-expressions. - -MB: We need to figure out how this maps to the snowman bindings, I talked to Dan who explained more about how that worked. I see the point of the snowman bindings now. I think it would be interesting to reuse the ideas from the GC proposal re defining structs and so on, and having a binding section from the snowman proposal to describe how they are bound. - -TS: Martin, the original motivation of snowman bindings (prev webidl bindings prev host bindings) was to make DOM apis fast, interacting with them directly from wasm rather than going through javascript. While by now we have lots of reasons to want these bindings, that is still a requirement of the snowman bindings. How are you making sure that your work stays compatible with that, or are you focusing on the syntax layer and it won’t interfere with that? - -MB: I’m not considering how we’re binding to JavaScript, just interested in how to express the structures that these interfaces pass around - e.g. how do we express the structure of a directory entry and how do we read and write to it? That is partially covered by what snowman bindings does so we should reuse that. Maybe snowman bindings does cover everything we need. But the syntax should look like everything else - -TS: It seems like the syntax is purely in the tooling space - -MB: We have the syntax from GC to express struct and arrays, I think that's all we need to express things like directory entries. I want to reuse that syntax, and use that as a path for compatibility with GC implementations in the future. - -DG: Take the set of bindings and types we have in wasi core as the base language, and the IDL describes what those are and gives us the clean descriptions we want - -MB: The tooling is a big hurdle in webidl right now, we want to make it easier for people to read and write these descriptions. - -TS: That makes sense. Luke wagner has had a lot of conversations around this, including with all the webidl people. They are all open to improving things. Its clear that snowman bindings won't be webidl bindings, but they need to be semantically compatible enough to describe the dom bindings pieces. If we end up having different surface syntaxes, thats fine because its mostly about tooling, but I also think we should have something that is not gratuitously different. One constraint is that browser implementers will have to be able to consume webidl in order to make the dom bindings work (already used throughout browsers). Keep in mind that there are constraints that don’t allow us to completely evolve this tooling in ways that break the DOM bindings use case. - -DG: If you can go with whats in snowman bindings now, and build on top of that, then we can achieve the parity we’re going for without defining new semantics. The key vocabulary is the types and the operations. Webidl has a lot of things in it that are distracting, even if you reduce it down to just the parts we need there are still syntax things like how “unsigned long” is the way to write u64, so i’m sympathetic to changing that syntax. - -MM: When I did my minimal BNF subset of capnp, I did take a look at the WASI ABI document and all of the capnp names for the types like u64 seemed obviously much better. I did not include wasm-specific concepts like memory, I agree that's an important thing to figure out how to accommodate. - -DG: Actions going forward: martin will take the capnp PR and make a version with the new syntax. - -MB: I will get that done in the next week and get more feedback. - -MM: There is a long term issue of how we support, at the wasm level, how we manage method dispatch. There are several ways we could map that to the current wasm, none of which are very natural. This problem goes away with GC but I continue to assume that is a long ways out. The smallest step from where we are to a natural method dispatch binding would be to add sum types, where sum types are passed on the stack rather than by separate allocation of reference counts, and the message - the thing that one invokes - would be a sum type where the constructor is the method name, and the contents of that branch of the sum type are the arguments, and the pattern match at the receiver would be the method dispatch. Given that we’re doing an IDL we dont have to decide up-front what the method dispatch representation is, but it would be good to have a candidate in mind. - -DG: My understanding is that not everyone has seen material on dynamic dispatch, so it would be a good thing to start with a paper on how dynamic dispatch works and what use cases it has -MB: Once we have proper function references doesn’t that cover? Are sum types part of GC? - -MM: The repr of sum types I’m thinking of would not require dynamic allocation so we could implement it before GC. It would still be a significant additional piece of engineering. The problem with just using function pointers is that method dispatch with what we have now, the options are 1. You pass by copy a record of function references, and the client of the object invokes a method by looking up the method name in that record, the problem with that is the size of the reference to the object is passed by copy and proportional in size to the num of methods on the type. -2. You pass by reference a … it loses the static type information given our current system, so you’d have to cast after the method lookup to the right signature. -None of these are natural for intra-module communication given the current wasm representation of things. - -DG: One thing we talked about was virtualizing an API and how we might do that. Dynamic dispatch approach allows you to virtualize in more ways. There are a lot of new ideas here and we need to motivate what problems we’re solving here and spread the ideas more broadly. - -DG: Lets move on to the next issue, the blockchain call extension. The main thing I want to address is the meta-discussion of whether this digs inside wasi. Nick are you here? - -DG: I encourage folks in the blockchain space to submit proposals, it fits well with our modularization story. It is a bit ahead of the curve as we’re still figuring out how imports and weak import names and so on. - -DG: Implementers of wasi that don’t have anything to do with blockchain wouldn’t have to implement these interfaces but its good to have the standard for how they work all in one system. - -NH: (missed it) - -MB: It would be nice if we had an interface for persistently storing function references and loading them. One idea is that we could extend the number of file types to one that could load a function reference and put it into an anyfunc table. This would require the call-ref operation to call the method, from in the function refs proposal. - -MB: The file types we have now are a file, directory, block device, character device. Are there problems with extending those filetypes? - -DG: Part of that question we might not quite be ready to answer yet. Does anyone have problems with extending the idea of a stream beyond posix-style streams? - -LI: If plan 9 could do it we can to -DG: We can talk more about stream APIs but I think extending streams to be useful for blockchains is a good idea, as long as it does not incur a cost to implementors that dont need blockchain. - -LI: We say blockchain but is any o f that not descended from etherium? - -NH: I want to generalize this in way for systems beyond etherium descendents - -MB: I worked on ewasm and dfinity, I also want this interface to work beyond etherium family as well. - -MM: The plan at agoric for using blockchain and wasm is not etherium-like, it is consistent with ocap approach, and the issue of dynamic dispatch becomes important to us. - -DG: For some context there's discussion in the CG about webvms and the requirement for 2 implementations that are webvms. In wasi we’ve decided that the committee would accept non webvm implementations and make decisions on what exact vms would be accepted as we go - -LI: Whatever system we come up with should handle more than just one currency, it should handle multiple currencies on a single chain - -MB: We should standardize that we aren’t dealing with one particular currency. This would probably be a good document to put together. - -DG: We should record our thoughts on what requirements we have for blockchains. Martin can you write up … we want diversity, we want to make sure we’re standardizing on something that more than one implementation will use. - -NH and MB will collaborate on that document. - -DG: Any further items? - -Meeting adjourned diff --git a/proposals/random/meetings/2019/WASI-07-18.md b/proposals/random/meetings/2019/WASI-07-18.md deleted file mode 100644 index 670da9f4d..000000000 --- a/proposals/random/meetings/2019/WASI-07-18.md +++ /dev/null @@ -1,262 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the July 18 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: July 18, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Import names - - https://github.com/WebAssembly/design/issues/1286 - - There's a lot of big-picture design work to be done here. - - To unblock modularization and general design work, can we adopt - a new temporary scheme, still containing "wasi_unstable"? - 1. Weak Imports - - https://github.com/WebAssembly/WASI/issues/36 - 1. IDL - - WatIDL: https://github.com/WebAssembly/WASI/pull/64 - 1. What other blockers do we have before we can start designing new - "wasi_unstable" APIs? - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -2019-07-18 WebAssembly CG WASI Subgroup Video Meeting Notes - -Agenda: https://github.com/WebAssembly/WASI/blob/main/meetings/2019/WASI-07-18.md - -Attendees: - -Dan Gohman -Martin Becze -Mark McCaskey -Alex Crichton -Andrew Brown -Sam Clegg -Yury Delendik -Arun Purushan -Pat Hickey -Jacob Gravelle -Luke Wagner -Till Schneidereit -Luke Imhoff - -Meeting notes: - -Pat - agenda seconded - -DG: -Import resolution outside of the scope of WASI. - -Pick naming convention that involves the name wasi_unstable + a possible additional identifier, to allow us to continue designing APIs. - -SC: wasi_unstable implies a bulk rename in the future - -DG: agreeing but bringing up additional prefix to clarify. Does anyone have an opinion. Suggested wasi_unstable/ - -_ : Is there any reason to use a / - -DG: We want to split the existing wasi_unstable into multiple modules, :, $, the specific character doesn’t matter. - -DG: is there a problem with / - -_ : Agreeing that separator doesn’t matter, but we should move everything into namespaces - -DG: it will allow us to start design work on other APIs… - -DG: wasi_unstable/identifier is the current proposal. We’ll call that a decision, we can use that to unblock things and start modularizing things. We’ll start queueing up those issues for the next meetings. Let’s have those issues and we’ll start tagging them. Part of that work will be deciding what goes in what modules - -DG: next agenda item. Weak imports - -SC: I got as far as implementing the custom section and realized that there’s quite a lot of redundancy, we’ll have a global corresponding to each global import. All we need is a way of finding that list of globals, we’ll probably use name mangling, so all we need to do is specify the suffix and the runtime can find all imports matching that pattern. Name mangling just for is_present. It would just be a simple custom section saying “is present” - -DG: that strikes me as overkill - -SC: (something)… we can find all weak imports by looking for that suffix - -SC: someone asked why we weren’t going forward with the official Wasm spec proposal of weak imports - -DG: one possibility is that we can take weak imports as being in the same bucket as snowman bindings. It’s a way of describing an interface to Wasm, so maybe we should put it in the snowman bindings custom section. If that’s the case, we can roll it into the snowman bindings proposal. I think it aligns pretty well with the snowman bindings things, because it’s a custom section, and (justification regarding name mangling) - -PH: if you have a whole bunch of weak imports, you can map them to the same global if you want to. So that’s an advantage of a custom section - -SC: what does that mean, if anyone of them is missing - -PH: that’s useful if you’re importing an entire module of things - -SC: that’s useful for all-or-none situations - -SC: yeah, I like it - -DG: alright, so with that, I’ll put that to the group, is this a good way to go forward, put it in a custom section and roll it into snowman bindings? - -(Luke allegedly nods head) - -SC: I don’t see how it fits into snowman bindings -DG: it’s part of a custom section that is the interpretation of the module; it’s not quite the same thing but it’s in the same category. It would be in a different part of the custom section, and eventually things like specifying the entry point - -LW: (missed)... this is in the same kind of layer - -SC: that makes sense when you put it like that - -DG: does anyone want to comment on the issue then? Someone in the WASI repo brought up the question of using a custom section - -J: if that is the case then we should put it in the webidl bindings repo - -LW: the webidl bindings repo is itself a layer of …. - -J: should add assuming it does exist (snowman bindings) - -PH: there’s a large overlap in the people working on both, so it’s probably a non-issue - -J: do we want to use weak imports for something else? Mentioning it there will get more eyes on it. Weak imports in contexts outside of WASI - -… - -SC: should I keep going with specing that in the WASI repo? - -DG: yeah, for now.. We’ll figure it out as it goes - -DG: next agenda item: WAT IDL proposal - -M: So where we got stuck last week is with conflating two things, the way watidl was written made the interface an object, that’s a mistake because an interface is a Wasm module. I rewrote it and I’ll push up the changes today. We should take a key from webidl we can add the extra field that this is a method and then we know that the bindings need to bind some sort of context, so I’ll introduce a method field. It’s also important to remember what the whole point of this was which was partially virtualization, ideally we should be able to have an IDL that Wasm binaries can bind to in two different ways, one using aztrack? Data ADT where all the functions are imported, the other way that would be easy to virtualize, I’m also trying to, I wrote up a little doc on how to do virtualization which I’ll throw up today, so that’s where we’re at with watidl. - -LW: what does virtualization specifically mean? You’ve requested to import this fn but I’ll give you a virtualized one instead - -M: the ability for a Wasm module that a Wasm module can implement a given interface and another module can use that, there’s 2 types of virt. Static: another module importing fd_close, open, sync, which another imports. Dynamic: a module being able to on the fly create a file descriptor or implement it to hand to another module, which is what I meant - -LW: do you mean as a reference to a struct that contains fn refs? - -M: yeah, exactly. SO in that case, the WASI interface, ref to structs of fns, you would just import types at that point. It would be nice to have an IDL that can describe both ways of interacting. - -LW: and who would use the IDL? - -M: used to describe interface and then you’d write bindings. - -LW: so this would be the interface of WASI? - -M: yeah - -LW: would this be equivalent to a list of Wasm function signatures that would be allowed to use snowman binding types in their signatures along with module and field name - -M: list of functions of types, it’s pretty basic - -LW: If we go the snowman bindings format and have a Wasm style and there were fn sigs that could use these types instead of core Wasm types. What if I make a module that just describes the interface… just a subset of the text format. - -M: that’s pretty much what this is + the addition of whether a function can be virtualized or not - -LW: that has some pretty significant runtime and compile time implications - -M: We don’t even have structs or fields, we need partial GC and func ref before we can do dynamic dispatch properly anyways, so we’re looking ahead. - -LW: thanks for explaining that - -M: it’s the text format - bodies, just types and function signatures - -MM: Wasm interfaces are overlapping, we should consolidate these or figure out what’s going on -SC: virtualization isn’t needed for what we need right now, so maybe we shouldn’t push on that too hard if we don’t need it right now. - -M: agreement/partial agreement - -M: I think virt. Is important in a context where you have multiple untrusted modules working together. As WASI is now, it’s generally a single module, they can add object capabilities to each other. In that context it’s not as useful, once we have func refs, …. Then the capab to virt interfaces is more important - -TS: I thought that was a different layer, instead of the runtime built-in you use this instead. I don’t see how that would interact with the IDL, can you explain that more? - -SC: you’re talking about interposition vs method calls, interposition is like intercepting a method call. - -M: Are you all familiar with ADT style? RIght now everything is ADT style, so you can’t really virtualize ADT style. A module can’t really implement those functions, it can’t generate them on the fly. So to be able to generate or implement a file descriptor, that’s /udev/random , so a module can do this and generate a FD on the file when requested by creating a struct and hand it off to the requester, why this matters at an IDL level is, a module may only want to use OO interface and in that scenario, you’d only implement types and the entrypoint fn would only receive capabilities, references to structs which point to functions. One use case for an IDL here is the host system would know that the module wants OO type vs ADT style, does that make sense? - -TS: I think so, thanks for the clarification - -M: that said, since we don’t have, since it’s not given we don’t have GC or func ref, (func ref?) looks more promising, it might not be worthwhile to worry about this. It might not be worth worrying about this yet and just focus on ADT style - -DG: as far as next steps, martin you mentioned that you’ll post an updated version of the proposal? - -M: yep - -DG: we’ll iterate from there. Anything else we want to cover in this meeting? - -M: I also wrote up some stuff about virtualization, should I add that to the repo? - -DG: Sure, make a PR and we can discuss it and decide if we want to incorporate it - -DG: that’s a good point, virt. Is an interesting enough point that we should document what we’re going to do in this space - -DG: next on the agenda, with the theme of setting up the wasi_unstable namespace, what are the blockers that we have before we can split up wasi_unstable into modules and working on them. Having an IDL nicer than a C header file or markdown is good, are there other blockers? - -LW: do you think we should hold off until we can make use of reference types and type imports? Or do we want to do it later - -DG: I think that’s something we can deal with later. When we have full snowman bindings, we’ll want to convert them into that form, and emulating lower level concepts with our higher level types. We need to figure out what is a file and that doesn’t need to wait for (those things) - -TS: maybe we should say that the changes we make going forward should take these concepts into mind, (describes using indirection of fds in a table of anyref to make transition easier) - -DG: that seems reasonable and I think that will somewhat naturally fallout given API design. We want a vocab to talk about things until we have an actual IDL, we can do API design with C headers but it’s not ideal, so we should figure out what to do there. MAking it easier to migrate to future bindings systems seems great - -TS: two advantages, we can do API design now knowing thta API design can map well, later on we have a straight forward way to make it easy to consume in C/CPP/Rust. Two APIs with the AnyRef being the fundamental and an indice-only one on top of it - -DG: how much do we want to do now vs waiting for snowman bindings? If we just design with this in mind, it will be pretty straight forward to retro fit this, that’s my gut feeling here. - -TS: All I’m proposing is making that explicit that we want to have this 1-to-1 relationship, making that relationship straight-forward - -DG: should we have a document about “How to design a WASI API” - -M: that sounds like a good idea - -DG: martin or till do you want to start a document like that? - -TS: I can start that document by writing what I just said and then we can flesh it out with more content - -DG: it can evolve as we get snowman bindings and other tools - -LW: it might be good to have a “future intended steps” section. The intent to move to ref types and binding types are only in our own heads and we should document that somewhere - -DG: looking for someone to document OCAP vision and put it in a repo, if someone wants to do that, that’d be great. It’s been discussed in various places, but we don’t have a document in the repo describing the plan. IF someone could digest that down and start that, that’s what we’re looking for - -LW: I can help there - -DG: we have the docs directory in the WASI repo. Alright, I’m trying to push forward to the point where we can do API design. Are there any other blockers? We’ll have a document, (somethinG) in progress, and a plan … for a module naming system, temporary one, pending discussion about import naming schemes. That’s the end of the agenda. Is there anything else? - -SC: presumably we’ll need an IDL to header file conversion after, -DG: yes (..) + rust interface generation - -M: … -LW: … -TS: s-expressions as type definitions minus the body is the obvious way to define the functions. WHat’s missing is how to fit the binding expressions in there - -LW: importantly, binding expressions don’t fit in there, interface is just the types - -M: to generate a header file, you’d need the IDL and the bindings and they do need to be separate because different languages want different bindings - -LW: I’m not quite sure what you mean by supplying the bindings. You could generate for say, C, there’d be policy choices like what to do with strings, but it’s possible. Sounds like a cool tool though - -DG: that sounds like the end of the meeting, see you all in 2 weeks diff --git a/proposals/random/meetings/2019/WASI-08-15.md b/proposals/random/meetings/2019/WASI-08-15.md deleted file mode 100644 index 8062b2745..000000000 --- a/proposals/random/meetings/2019/WASI-08-15.md +++ /dev/null @@ -1,121 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the August 15 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: August 15, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Weak Imports: https://github.com/WebAssembly/WASI/pull/47#issuecomment-521061962 - 1. Interface description based on Module types - - https://github.com/WebAssembly/WASI/pull/74 - - This is a rough sketch, similar to WatIDL, but stripped down, and is - meant to be just enough to let us start describing API proposals. - 1. Meeting time - - I received a request from someone who would like to present a proposal to hold a meeting at an APAC-friendly time. - - We have been following the CG which held some APAC-friendly meeting times for a while but - [dropped them due to low attendance](https://github.com/WebAssembly/meetings/blob/master/2018/CG-04-03.md#drop-apac-timezone). - - Assuming this works for the presenter, move the time of the next meeting to 08-30 at 06:00–07:00 UTC? (This is 08-29 at 11:00pm in Pacific Time)? - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -Attendees: - -Dan Gohman -Till Schneidereit -Alex Crichton -Luke Wagner -Jacob Gravelle -Sam Clegg -Andrew Scheidecker -Mark S. Miller -Johnnie Birch -Stefan Junker -Andrew Brown - -Meeting notes: -Topic: Weak Imports: https://github.com/WebAssembly/WASI/pull/47#issuecomment-521061962 -sbc: moved back to custom section design -[please fill in notes here] -MarkM: could a rename be considered—I always think of weak references -Sbc: very strong precedence in C/C++ -MarkM: weak/optional imports should be brought up with TC39 -Luke: [posts a link https://github.com/guybedford/proposal-weak-imports] -Dan: good question, should we rename? -Stefan: +1 on “optional” -Mark: would “optional” be confusing? -Seems like “no” -Dan: seems like consensus -Sbc: [takes an action item to rename] -Dan: anyone opposed to landing the PR once the rename is done? -[no] -Dan: let’s do it -Topic: Interface description based on Module types (https://github.com/WebAssembly/WASI/pull/74) -Dan: lots of stuff going on around OCap, and that should go on -But in parallel, we need a simple text format -This PR introduces a stripped down text format (see PR description for details) - -Mark: should we introduce a term such as “compartment” to describe sets of instances which share memories and tables? -Sam: This relates to the concept of “shared-nothing linking” which we have been introducing. -Luke: In full generality, we won’t need the term compartment, because we’ll just have references and different linking approaches. -Luke: if we want wasi_unstable to become wasi, we need to spec ways to send capabilities between modules. We don’t if we just have references -Till: brings up the question if we need to support wasi_unstable, instead of just breaking it -[discussion] -Mark: This is a useful concept, whether or not it’s something -[discussion] -Luke: getting back to the proposal, looks good for the transitional role -Dan: idea is, once we have a parser for this, we could land it, and have it be the specification -Could generate header files and documentation from it -Sbc: comments go into some kind of comment syntax? -Dan: double-semicolon -Sbc: need some kind of include mechanism -Dan: yes, good point. Want to really keep this simple -Luke: same requirement came up in conversations with Andreas about defining types in one module and using them in another -Luke: but as long this is all structural, can just agree on structure of types -Dan: - -Dan: We need to factor out types so they can be shared between multiple modules. Maybe something like a #include mechanism? -Mark: #include would be unfortunate in any kind of standards context. -Luke: We could put multiple modules in one file -Dan: Could we design a more declarative form which achieves the same goal but doesn’t have the same problem? -Mark: It’s premature to do a lot of IDL design work -Dan: agree - -Timezone discussion -Till, Johnnie: conversations about voting, and people not being able to attend all meetings. Perhaps we can find a way to do votes offline to allow people to vote even if they can’t attend the meeting. -Sam: Another option is to do the vote in the meeting, but hold it open for a week or so after to allow others to vote. -Till: That does change the dynamics. -Johnnie: Would it makes sense to record the meetings? -Dan: What if we ask the CG to record their meetings? We can follow their lead. -Johnnie volunteers to take that to the CG. diff --git a/proposals/random/meetings/2019/WASI-08-30.md b/proposals/random/meetings/2019/WASI-08-30.md deleted file mode 100644 index cbd14a725..000000000 --- a/proposals/random/meetings/2019/WASI-08-30.md +++ /dev/null @@ -1,64 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the August 30 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: August 30, 06:00–07:00 UTC -- Note the time change! -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. WASI for Embedded, by Wang, Xin - 1. Update on the Interface description based on Module types: - - https://github.com/WebAssembly/WASI/pull/74 - -1. Closure - -## Agenda items for future meetings - -*None* - -### Schedule constraints - -*None* - -## Meeting Notes - -Attendees: - -Dan Gohman -Xin Wang -Leon Wang -Arun Purushan -Till Schneidereit -Tyler McMullen -Sam Clegg - -Meeting notes: - -Time zone: -XW: Seems like we can move to the previous time. -DG: We can be flexible in the future too. - -XW: Presentation on WASI for Embedded - -DG: Update on https://github.com/WebAssembly/WASI/pull/74 diff --git a/proposals/random/meetings/2019/WASI-09-12.md b/proposals/random/meetings/2019/WASI-09-12.md deleted file mode 100644 index e8bf1a518..000000000 --- a/proposals/random/meetings/2019/WASI-09-12.md +++ /dev/null @@ -1,92 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the September 12 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: September 12, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. `witx` API description files: - - https://github.com/WebAssembly/WASI/pull/74 - 1. Phased API development proposal - - https://github.com/WebAssembly/WASI/pull/88 - -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Sam Clegg -Pat Hickey -Yury Delendik -Artur Jamro -Mark McCaskey -Alex Crichton -Jacob Gravelle -Mingqiu Sun -Nathaniel McCallum -Luke Wagner -Johnnie Birch - -Meeting notes: - -Agenda seconded by Pat - -Dan: Last meeting was at a different time than usual. There were only 6 attendees. We are going to resume meetings at the normal time, 1600 UTC. - -Dan: Next topic is WITX. - -Independent of WASI, there is a new file format called WIT from the interface-types proposal. Its a lot like WAT, but it does not have function bodies. - -WITX is WIT with extensions. It has some of the types from interface-types. The idea is that WITX is not a stable format, its going to evolve to align with WIT as interface types evolves. - -Fortunately our needs are pretty simple at the moment: we are adding strings, arrays, enums, and structs to the wit file. - -We want WITX to be the way we specify WASI apis. It feels like a better place than the C header file we started with. - -Pat: lucet-idl tool has a witx parser in development. - -Working on hooking up this parser to the C and Rust interface generators. -Goal, be able to feed witx files into lucet-idl and generate C headers and Rust interfaces. - -Can be used to generate libc definitions for WASI - - -Stefan: Does WITX have modules? - -Dan: Yes, but the file we have at the moment attempts to be the exact same wasi_unstable module we have right now. Once we land this, we can immediately start factoring that module into multiple modules, and witx should support that. - -Sam: Is there a way to use types from a different module? - -Dan: Yes, there is a `use` mechanism, and in the PR there’s two witx files, wasi_unstable’s first declaration is to `use “typenames.witx”` - -Dan: Next agenda item: Phased API development (PR 88). Apologies for getting this up late. - -Stefan: Could there be a standalone parser implementation somewhere? - -tdoPat: I’ll make the lucet-idl parser and validator for witx into its own crate, and that crate will live in the WASI repo. - -Johnnie: I followed up on whether we can record these meetings, I talked to the W3C and they expressed the same concerns we heard here about privacy, making people feel comfortable speaking up. They suggested I talk to the WASM CG, but given that I’ve heard the same feedback from multiple places, I’m going to just drop the issue. diff --git a/proposals/random/meetings/2019/WASI-09-26.md b/proposals/random/meetings/2019/WASI-09-26.md deleted file mode 100644 index 704aed13a..000000000 --- a/proposals/random/meetings/2019/WASI-09-26.md +++ /dev/null @@ -1,60 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the September 26 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: September 26, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Initial WASI modularization draft - - https://github.com/WebAssembly/WASI/pull/98 - -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Andrew Brown -Mark Bestavros -Leon Wang -Alex Crichton -Peter Huene -Luke Wagner -Yury Delendik -Pat Hickey -Artur Jamro - -Meeting notes: - -DG: WASI modularization draft PR is up, comments are welcome - -Also, this makes the start of the point where we can start taking PRs for new API proposals, in the form of PRs which add and modify witx files. - -Pat: We’re working on an HTTP API proposal. - -Dan: There are also people working on Berkeley sockets APIs. Note that though there is a potential for overlap here, it makes sense to develop both. - -Pat: In cases of overlap like this, the higher-level APIs may even by polyfillable on top of the lower-level APIs. diff --git a/proposals/random/meetings/2019/WASI-10-15.md b/proposals/random/meetings/2019/WASI-10-15.md deleted file mode 100644 index 4a9566f3d..000000000 --- a/proposals/random/meetings/2019/WASI-10-15.md +++ /dev/null @@ -1,116 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the October 15 in-person meeting of the WASI Subgroup - -- **Where**: 10355 N De Anza Blvd, Cupertino, CA 95014, USA -- **When**: October 15, 1:00pm PDT -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -This meeting is open to WebAssembly CG members only. To register, please -visit the CG participants page: - -https://www.w3.org/community/webassembly/participants - -Also, the host for this in-person meeting has requested we provide a list -of attendees, so please email Dan Gohman if you plan on attending. - -## Agenda items - -The topic for this meeting is low-level WebAssembly APIs for -HTTP (servers and clients). - -## Meeting Notes - -Attendees: - -Dan Gohman -Syrus Akbary -John Plevyak -Pitor Sikora -Alon Zakai -Mark Nottingham -Leif Hedstrom -Jorge Lopez Silva -Pat Hickey -Johnnie Birch -Roberto Peon - -Meeting Notes: - -Presentation: [Proxy-WASM: a “standard” WebAssembly interface for the data plane, Piotr Sikora, John Plevyak](https://docs.google.com/presentation/d/1QMGEuVD9p5iNbzxzgT4p2PXpxg1MjfSbpbJdw6g6Q_Y/edit?usp=sharing) -Resources: -[WebAssembly in Envoy](https://docs.google.com/document/d/1HLV35OZP0A_a8dVjDo4kwTsovDkaycS83ZLKFpG9W8Q/edit) - -Described the envoy use case and then reviewed an API (logs, network, http, etc) - -Dan: Is there a main function? -Piotr: No, there is no main. The module functions are the entry points - -Dan: How is `__post_instantiate` used? -Piotr: It’s an initialization function which is called at Vm startup, which may live across multiple requests. - -Dan: Does `proxy_set_effective_context` imply persistent state? -Piotr: That’s an ABI design question, it could work that way or by passing in the context to each call. - -Roberto: Is there an api for caching -Piotr: Not at the moment. Not supported by envoy. -Roberto: What about streaming? What if the data you’re receiving is not in order? -Pat: We have a different proposal that addresses this. -Piotr: We don’t have an answer for this yet. - -Syrus: Have you thought about using this proxy api on the client-side (browser, [via extensions](https://developer.chrome.com/extensions/webRequest)) as well? -Piotr: Our use case is not focused on that - -Roberto: Are you thinking about having a Session abstraction in addition to Connection? -John: We don’t have it yet, but we may add it in the future - -Jorge: Version management? - limitations of current toolchains mean that the abi version is encoded as numbers in a function symbol name. But this can change as tools and standardization progress. -Pat: optional imports may alleviate some of the versioning problems too - - -Presentation: [“What HTTP Needs from WebAssembly”](https://github.com/WebAssembly/WASI/blob/main/meetings/2019/What%20HTTP%20Needs%20from%20WebAssembly.pdf), Mark Nottingham - -Roberto: What about multiple headers with one name? -Mark: [paraphrase] we probably need to talk about that - -Dan: Does this include DNS? -Mark: Yes, the API accepts names, and they are translated implicitly - -Discussion of optional imports, which will be important as different use cases will need different parts of these APIs. -Spec: https://github.com/WebAssembly/WASI/blob/main/design/optional-imports.md - -(general presentation of the people in the meeting) - -Dan: Could you use this for general-purpose HTTP programming? -Mark: Yes, there are some features which are proxy-specific, but this could be used for clients and servers - - -Presentation: [WASI HTTP proposal](https://github.com/pchickey/wasi_http_strawman), Pat Hickey - -John: This concept of futures doesn’t allow you to chain futures, right? -Pat: Yes, this is a difference from JS futures - -Pat: This is a low-level API; most customers would be using higher-level libraries on top of this - -John: This API allows you to decide what you want to poll for - -Pat: The `future_close` function allows you to release resources - -Roberto: How much would this API change if you had threads? -Pat: Our goal is mostly to have threads in the background, so that users don’t need to worry about them. But some users may want more threads in the future. We don’t have all the answers here yet. - -Alon: The `request_new` function takes a string url; how does this relate to `path_open` which doesn’t support absolute paths? -Dan: That’s a good point; one possibility is to change this API to make URL access more capability-oriented -John: That enables nested sandboxing -Alon: This model entails some overhead. If every WASI API uses OCAP, it could add up - -Action items: -Dan to post a skeleton Reactor design document -Dan to finish WASI modularization API -Pat to make a Futures proposal -John, Piotr, Mark. Pat to flesh out their API proposals offline and figure out next steps diff --git a/proposals/random/meetings/2019/WASI-10-24.md b/proposals/random/meetings/2019/WASI-10-24.md deleted file mode 100644 index c9dae6238..000000000 --- a/proposals/random/meetings/2019/WASI-10-24.md +++ /dev/null @@ -1,171 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the October 24 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: October 24, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. WASI and OCap - 1. https://github.com/WebAssembly/WASI/issues/109#issuecomment-541191297 - 1. https://github.com/WebAssembly/WASI/pull/69 - 1. "Handle" terminology - 1. https://github.com/WebAssembly/WASI/issues/62 - 1. https://github.com/WebAssembly/WASI/pull/117 - 1. Quick ping on reordering `clockid_t` values - 1. https://github.com/WebAssembly/WASI/pull/112/files - 1. Modularization update - 1. https://github.com/WebAssembly/WASI/pull/98 - 1. https://github.com/WebAssembly/WASI/issues/2 - 1. Some good first issues - 1. Make __wasi_linkcount_t 64-bit - 1. https://github.com/WebAssembly/WASI/issues/70 - 1. Incorrect size returned by __wasi_environ_sizes_get - 1. https://github.com/WebAssembly/WASI/issues/27 - 1. Make clocks/random into capabilities - 1. https://github.com/WebAssembly/WASI/issues/118 - 1. Should random continue to be `random_get`, or should it become - `fd_read` from a special stream? - -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Mark Miller -Mark McCaskey -Pat Hickey -Barbara Nichols -Andrew Brown -Peter Huene -Artur Jamro -Till Schneidereit -Luke Wagner -Yury Delendik -Alon Zakai -Alex Crichton -Aaron Turner -Jacob Gravelle -Wvo -Sam Clegg - -Meeting notes: - -Dan: First discussion is WASI and OCAP. We have Mark Miller here. First off, what does OCAP mean and why is it interesting, and second what do we want to do. Mark can you please talk about what fine grained OCAP means. - -Mark: We have to distinguish two forms of fine grain. What is the unit of computation being protected, and what is the nature of a permission that can be separately reified (turned into something that can be passed around). Wasm has a coarse-grained unit of protected computation - a wasm module instance. It has a flat address space (two: memory for data, and functions, are separate). All toolchains are currently built around the assumption that all Wasm modules that are linked together share a memory and function table. I’ll introduce the term “compartment” for all Wasm instances that share those address spaces. Inside that compartment, all computations inside are vulnerable to all other computations inside. We’ll eventually address that better with the GC proposal but thats a way out and we wont address it further in this conversation. -The other issue is what is the unit of passable permission. Thats permission to access outside resources and also for units of computation to effect each other. We’ll assume that there are a set of separate compartments that are units of protection - their only initial relationship is through imported and exported functions. As far as the Wasm mechanism is concerned, import functions between compartments are a perfect OCAP protection mechanism. (details this by example) -Currently the only things that Wasm can pass over function interfaces are numbers (ints and floats). As a result the permissions communicated between compartments are only communicated statically - you can't pass them dynamically once compartments are linked. So you can convey permission at whatever fine-grain you want by having many different exported functions. You can use procedural abstraction to attenuate permissions, e.g. you can use a function to provide an abstraction of a read-write file as an append-only file. - -Dan: I want to temporarily ignore address spaces and tables: in a world where we have references, does it make sense to talk about compartments still? - -Mark: Current Wasm architecture plus references still has flat address spaces - our current toolchains push us into it, there will still be multiple module instances linked together sharing address spaces. - -Dan: I’m trying to hypothetically see if we take address spaces out of the situation and have wasm gc everywhere, are compartments still relevant? - -Mark: In that hypothetical the Wasm module can use the memory and table space as empty, and Wasm becomes a fine-grained object capability machine. - -Dan: The question that came up on github is that we currently are trying to do much finer grained permissions than the function level. - -Mark: Yes in the hypothetical GC situation you have capabilities that are fine grained at the level of the objects in your programming language - -Dan: How do we bridge the gap between the situation we have now, with these compartments and the failures of granularity associated with that, and where we want to be with GC with finer grained permissions. - -Till: What about the host? (I didn’t follow this close enough for good note taking) - -Mark: There are OCAP languages and operating systems, and research on running OCAP languages on a OCAP operating system with a bridge between the language’s idea of capabilities and the operating system - when you’re writing in the language its as if the operating system’s view of capabilities are just ordinary programming language capabilities. - -Mark: If you design that all interfaces between compartments are designed around reference types, the inter-compartment protocols that are natural to future GC based compartments. - -Mark: Even with reference types, the notion of a virtualizable capability is the natural way to express capabilities in the - -In the Wasm GC machine there’s support for both virtualizable and abstract datatype capabilities, theres no penalty for virtualizable capabilities and its quite natural. In the current world the only way cross-compartment is abstract datatype capabilities. That’s going to be an impedance mismatch. - -Dan: I’d like to steer this back towards what do we do with WASI right now for languages that don't have GC or reference types. Its going to be a long term problem because we’re going to have C/C++ forever. How can we deal with an integer based approach that can approximate reference types in a useful way, at the penalty of being coarser grained? - -Mark: Let’s take very basic C++ as the representative (worst) case. There’s two approaches: one is the approach the Cheri team (University of Cambridge) has taken, they’ve added reference types to existing RISC machine architectures as additional instructions and registers and used that to put protection boundaries inside existing C/C++ code. They built a compiler and LLVM fork that can run in two modes: one mode every C++ pointer is turned into a Cheri capability, at which point you’re treating the Cheri hardware like we’d eventaully do Wasm GC. - -Dan: In Cheri pointers are still bit patterns right? - -Mark: Sort of, in the other compilation mode: in that mode the pointers are still bit patterns that are readable, but the capability gives you a range of addressable memory (which is potentially very fine grained) that is valid to dereference. This is expensive and not really what we’re doing with Wasm GC. - -(at this point i lost the ability to follow and take good notes) - -Dan: Any solution that involves users annotating their source code is going to get a lot of resistance from our users. Any solution where capabilities are held on by a side table and theres bit patterns in the wasm, is better for C compatibility but not the best for actually doing OCAP. Cheri is cool but it doesn't magically solve our problems here yet. - -Mark: A completely different way to approach this issue: Let’s say all your inter-compartment capability interfaces are defined in an IDL, and then we can generate (like capnp) bindings to particular non-capability-based ABIs, so only the code generated from the IDL directly handles the reference types and does the context switch between compartments. All of the C code just uses the C ABI bindings generated by the IDL. Those ABI bindings use integers that require the capabilities be looked up from tables - -Till: A lot of this is actively in the works as the interface types proposal. A lot of these concerns are actively being addressed by how WASI and interface types are developing. The biggest thing is that moving capabilities from being expressed as integers to references, and all compartment interfaces are in terms of reference. Inside a compartment you can do whatever you like. - -Dan: We have an IDL now where we’re moving to talk about APIs in terms of references. At the WASI level we should design in references using OCAP. - -Jacob: In the interface types polyfill we have a way to automate the side-table translation so you don’t have to even generate glue code, its just done in javascript (the host) for you. You can add an interface instruction to convert an index into a ref. This lets us use C without annotations beyond the toolchain knowing about interface types. - -Dan: Next topic: there's a virtualization doc that is coming along, and a paper -http://www.cs.cmu.edu/~aldrich/papers/ecoop17modules.pdf -(summarizes part of paper in way I couldnt follow for notes) - -Dan: Mark’s idea of virtualizatbility is an object with vtables inside them. -(more discussion of the paper) - -Mark: I’ll have to read the paper to understand this fully. - -http://www.cs.cmu.edu/~aldrich/papers/ecoop17modules.pdf - -Mark: Just followed the link, I know this paper. The language in the paper is fine-grained OCAP, individual objects are vtable-like. In that language, there’s still an issue of how you start the world off - a static configuration with good safety properties so you can move forward with dynamic properties. This paper is about the initial permissions with least-authority linkage between the modules. It is in the context of a dynamic system with full fine-grained virtualizability. I don’t see exactly how that addresses our Wasm representation problem, we still cant use references as fine-grained virtualizable capabilities. - -Dan: I think we should table and continue this discussion at a different time. I’d like to go to the rest of the agenda for the remaining 15 mins. - -Dan: What do we call handles, or descriptors? PR 117, or the last comments on issue 62 on file descriptors vs handles. POSIX has called things file descriptors when they're not really files. I want to talk about OCAP capabilities as handles. - -Mark: Historically, descriptors and capabilities are aligned, and the numbers you are familiar with as file descriptors are often just called indices, so clists are the list of capabilities and clist indices are the file descriptor ints you know. - -Dan: We settled more or less on Handle as an identifier that refers to a capability. When we say handles we’re just saying the OCAP sense. Does that make sense? - -Mark: Yes! - -Dan: Let’s call that a decision then. - -Dan: Witx files are up in the repos, you can make a PR into the ephemeral phase and we can then promote that to unstable when a decent number are landed and move on to implementing it. - - -Dan: Moving on to the modularization update: look at PR 98 for the basic change. This wont be the end of the story for modularization, but its a logical first step. - -Sam: Does this change the import field name strings? - -Dan: Yes, right now “wasi\_unstable” is the module name everything imports from. - -Sam: Yes I see that there are N different modules. - -Dan: Does it make sense to limit witx to one module per file? Wat only allows one module per file. - -Pat: We have to figure out how to deal with type names being global, we’ll need some sort of namespacing and import mechanism. - -Dan: Ok, we’ll figure that out and move forward. - -Dan: I put some basic issues in the agenda that are hopefully straightforward to implement. I’d like to encourage more people to step in and make PRs on the witx files and get involved. - -Dan: for example on the issue about using capabilities for randomness, we can propose solutions with PRs that change the witx. diff --git a/proposals/random/meetings/2019/WASI-11-07.md b/proposals/random/meetings/2019/WASI-11-07.md deleted file mode 100644 index bda872b71..000000000 --- a/proposals/random/meetings/2019/WASI-11-07.md +++ /dev/null @@ -1,102 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the November 07 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: November 07, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Publishing a first snapshot - 1. https://github.com/WebAssembly/WASI/issues/138 - 1. Issues for discussion - 1. Make clocks/random into capabilities - 1. https://github.com/WebAssembly/WASI/issues/118 - 1. Should random continue to be `random_get`, or should it become - `fd_read` from a special stream? - 1. Increase the timestamp range - 1. https://github.com/WebAssembly/WASI/issues/33 - 1. Remove remaining "process" dependencies - 1. https://github.com/WebAssembly/WASI/issues/26 - 1. Remove `CLOCK_PROCESS_CPUTIME_ID`? - -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Stefan Junker -Mark Bestavros -Nathaniel McCallum -Johnnie Birch Jr. -Mark S. Miller -Alon Zakai -Yury Delendik -Alex Chrichton -Luke Wagner -Mark McCaskey -Pat Hickey -Sam Clegg -Peter Huene -Alon Zakai - - -Meeting notes: - -## Making a first snapshot - call it “snapshot” - -AI: Dan to add a note to the phases document about how we make syntax changes to old versions while keeping the ABI compatible - -## Make clocks/random into capabilities - -DG: Currently clocks/random are ambient authority in WASI. Can keep compatibility with (C-style) programs out there which expect this to be the case? If so, how? -LW: Would this step mean that the program will always ask for clocks/random with the future option of allowing to not ask for it? -DG: What troubles me about that is that we’d still have to think about the mechanism for asking for it - -(discussion about clocks/random as stream vs. datagram) - -## Increase the timestamp range - -DG: this would be a good opportunity for someone who just wants to do this for the sake of learning how to change the API. happy to talk about this offline - -## Remove remaining "process" dependencies - -(discussion about exception handling in JS when interacting with WASM) - -DG: proc_raise is going away, proc_exit should ideally be implemented in terms of unwinding, though there are some details to figure out there. Can we remove the process-oriented clock identifiers? - -(Discussion, concluding in general approval) - -(Discussion of whether a “gas” clock could be defined; see also - -https://medium.com/@erights/a-pack-of-watchdogs-is-cheaper-than-gas-7e118edfb4cc - -Answer: there are some potentially subtle issues — programs could use this to determine how much time other parts of the program take, which may be undesirable. In any case, WASI itself would have no trouble defining new kinds of clocks in the future.) - -NM: Our implementation is able to implement the process-oriented clocks efficiently. If we remove them today, could they be reintroduced in the future if we want them? -DG: Yes, once we have modularity established and optional imports, it would be straightforward to add new features like this. - -NM: Is working on a proposal for a high level crypto API -MM: A request would be to not have the keys and algorithms in the same address space.. diff --git a/proposals/random/meetings/2019/WASI-11-21.md b/proposals/random/meetings/2019/WASI-11-21.md deleted file mode 100644 index 005585876..000000000 --- a/proposals/random/meetings/2019/WASI-11-21.md +++ /dev/null @@ -1,63 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the November 21 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: November 21, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. `wasi_snapshot_preview1` update: now live! - 1. wasi-libc update here: https://github.com/CraneStation/wasi-libc/pull/136 - 1. Other toolchains should start moving to it as well. - 1. `wasi-sdk` and `wasi-libc` will be moving into the `WebAssembly org - 1. Discussed here: https://github.com/WebAssembly/meetings/blob/master/2019/CG-11-12.md - 1. Modularization update. - 1. Link to be posted soon. - 1. Calling for volunteers. - -1. Closure - -## Meeting Notes - -Attendees: - -Pat Hickey -Jan Falkin -Alex crichton -Jay Phelps -Andrew brown -Luke Wagner -Alon Zakai -Dan Gohman -Mark McCaskey - -Meeting notes: - -DG: WASI Snapshot 1 is out. - -DG: WASI-SDK and WASI-libc. Currently in Cranestation orginization. They will move under the WebAssembly orginization, that was approved at the last CG meeting. We just have to work out some minor licensing issues for that to move forward. - -DG: Modularization update. I don’t have an update, haven’t had enough time. The current PR shows the shape of it, but it needs to be updated to the current set of APIs and witx. - -DG: Call for volunteers. I want to emphasize that WASI is a big opportunity, and now is the time to make changes. Please make PRs against the ephemeral directory diff --git a/proposals/random/meetings/2019/WASI-12-05.md b/proposals/random/meetings/2019/WASI-12-05.md deleted file mode 100644 index 0dc54deb4..000000000 --- a/proposals/random/meetings/2019/WASI-12-05.md +++ /dev/null @@ -1,124 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the December 5 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: December 5, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Stack trace API - 1. https://github.com/WebAssembly/WASI/issues/159 - 1. Whare are the next steps here? - 1. Character encodings - 1. https://github.com/WebAssembly/WASI/issues/8 - 1. Can we decide on this, or do we need more information? - 1. Case sensitivity - 1. https://github.com/WebAssembly/WASI/issues/72 - 1. Can we decide on this, or do we need more information? - 1. ANSI escape sequences - 1. https://github.com/WebAssembly/WASI/issues/162 - 1. Can we agree on the overall framework proposed here? - 1. Input sequences - 1. https://github.com/WebAssembly/WASI/issues/163 - 1. What standards govern this space? -1. Closure - -## Meeting Notes - -Attendees: - -Dan Gohman -Pat Hickey -Stefan Junker -Wouter van Oortmerssen -Jan Falkin -Andrew Brown -Mark McCaskey -Peter Huene - -Meeting notes: - -https://github.com/bytecodealliance/wasmtime/pull/235#issuecomment-518897502 - -DG: If people have comments on the process we’re following with these meetings, please give feedback. - -PH: I’ll second the agenda - -DG: First item, stack trace API. Thomas Lively proposed this, but he’s not in the meeting at this time. Let’s table this until he’s here. - -DG: Character encodings. This issue has been open for a while and there’s no easy answer. There’s a shape of a proposal in the issue that most engines are following - we say that everything is UTF-8. Is there any disagreement with that consensus here? - -(none) - -DG: For things like environment variables, it would simplify things a lot if we could guarantee those are UTF-8 strings. - -DG: What about filesystems with file names that are unencodable? Can we find a way to tunnel that through? We currently use pointer+length to pass all filenames. No filesystem permits null in a filename, so we can encode a non-UTF8 string by putting extra information after the null. The trouble comes when you have to manipulate the path. - -PH: What about interface types interaction? - -DG: The stuff after the null will still be valid UTF-8 which encodes the non-UTF-8 part of the filename. So any library code that expects UTF-8 will still work. -DG: We’ll take this as consensus, and go forward with this design for now. We can change it if problems happen or we have objections during implementations. - -AB: Can you clarify what is being encoded after the null? - -DG: Two things: in the part before the null we want a normal-looking string, so any bytes that cant be translated get the unencodable-character (uffd). Then, after the null, we put the information that was lost. Something like, index of the string, then the missing bytes. We want something that is reversible. I agree it is goofy. Does anyone know how to encode an arbitrary integer in a utf-8 byte pattern? Obviously we could invent something, like using ascii digits. If theres an existing way to encode it, we’d want to follow that. - -AB: So we can’t just say we support all unicode strings? - -DG: The problem is that there are names out there that can’t be expressed in unicode. And from people I’ve talked to, its rare in practice. So the goal here is that if you get a path from one wasi api, and treat it as a utf-8 string without manipulating it, and then pass it to another wasi api, it works exactly as is. - -AB: I misstated my question - is there no unicode format where this reconstruction wouldn't be necessary? Or will there always be some way for there to be an unencodable string? - -DG: My understanding is there’s no way out of this. - -Peter H: This would be for bytes which are not valid unicode codepoints. - -DG: I’m looking for enough agreement that we can keep designing this for now. - -Peter H: is there currently a part of the spec that allows non-utf8? - -DG: Witx String type is always UTF-8. We don’t have a byte vector type right now, but there are byte pointer-length pairs. For any string passed to WASI we’ll require it to be UTF-8, and any string coming from WASI would be guaranteed to be UTF-8. - -DG: Next topic, case sensitivity in filesystems. If you look at issue 72, the big picture strategy is that WASI doesn’t dictate case sensitivity or insensitivity, or what variation of sensitivity it has (because different filesystems have different rules, whether they case map ascii or different versions of unicode). I think the point of the API is to interact with existing filesystems, and we can’t control those, so this is going to be a portability hazard for WASI. We can make tools that help you detect these pitfalls. Does anyone have ideas of how we can make this better? - -DG: Ok, so to use the wasm scary word, it is nondeterministic to use different cases to access the same file in the WASI api. -DG: Alright, so the next two issues are about virtual terminal handling. Its a space largely defined by compatibility with existing systems like xterm, unix consoles, and windows consoles. It makes sense to have something simple here. You could imagine unifying terminals with GUIs, modernizing terminals, lots of blue sky stuff here. My sense is that the value here is to find a simple thing that will interoperate with lots of different existing systems. - -Sbc: Not just to interoperate with existing systems but to allow existing programs to run on many different systems? - -DG: Yes my goal is something like vi on wasi just works. It looks like lots of people don’t use terminfo to figure out colors and just hard-code them. And windows support is tricky because it doesn’t have exactly the same features as unix. In cases where the terminals differ, should we expose WASI programs to the differences between them? - -DG: The direction I’m going is we don’t try to do terminfo, the WASI implementation will be responsible for remapping escape sequences and all that. You could imagine having an environment variable TERM=WASI. It would look a lot like xterm, which in turn looks a lot like windows. - -DG: On that topic, input sequences are a subfield of escape sequences. Input varies way more than output, across platforms. This made me think we could do a cool radical thing like use unicode symbols. But maybe the simplest thing is, just do what xterm does, and if it needs to be remapped by a WASI implementation to fit another console, thats up to them. But there are interesting questions to still ask here like what set of input sequences to support - -DG: Its tempting to say, we can go and design a modern system that doesn’t have all the legacy baggage. But my instinct now is to pull back from that and pick a reasonable set of defaults based on some of the successful modern implementations. If someone wants to design a whole new system, I won’t stand in their way. - -SJ: Can you clarify about how vim would work on this? - -DG: Vim itself wouldnt have to change. Terminfo is a library that gets linked in, but hopefully we could provide a radically simplified version that works on wasi. Inside the wasi implementation, anything like a TTY would have to filter the output coming from WASI program to neutralize all escape sequences, and then encode in terms of whatever its client expects. - -SJ: I would have assumed that stdin/out/err just map to whatever the host of the WASI implementation expects - -DG: We’re worried about security, because the terminal interface wasn’t designed to deal with untrusted code running on the terminal. So one example is that you could run a program and you think that it exited, but really its just showing you something that looks like your shell. We want to not allow applications to do things like that, by default. So if you wanted to run vim, you’d have to give it permission to rewrite your entire screen, versus just print ordinary text to stdout, which would be the default. So, controlling cursor position and colors and that would be exposed to wasi as a capability. diff --git a/proposals/random/meetings/2019/WASI-12-19.md b/proposals/random/meetings/2019/WASI-12-19.md deleted file mode 100644 index 0621c97b1..000000000 --- a/proposals/random/meetings/2019/WASI-12-19.md +++ /dev/null @@ -1,44 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the December 19 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: December 19, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Opening of the meeting - 1. Introduction of attendees -1. Find volunteers for note taking (acting chair to volunteer) -1. Adoption of the agenda -1. Proposals and discussions - 1. Stack trace API - 1. https://github.com/WebAssembly/WASI/issues/159 - 1. Whare are the next steps here? - 1. Windowing and Framebuffer APIs - 1. https://github.com/WebAssembly/WASI/issues/171 - 1. https://github.com/WebAssembly/WASI/issues/174 - 1. What guidance can we give to folks interested in working on these? -1. Closure - -## Meeting Notes - -Windowing and Framebuffer APIs: - -There's an early demo out, and it's gotten some feedback. Aarron Turner is -working on incorporating the feedback and putting together a proposal. diff --git a/proposals/random/meetings/2019/What HTTP Needs from WebAssembly.pdf b/proposals/random/meetings/2019/What HTTP Needs from WebAssembly.pdf deleted file mode 100644 index 7aa294ee64e815455dd95821e1aca68f98bd9fcd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82687 zcmdqJbyQtTw)RcX;10pv-QAtw?(Xg`!Civ8yF0;yTkzoS5Q4jZz&Yu@N5&of-R^(h z9vLH>wRi2gX6;q;sb9$~A{jwpDmrRL2qN5#&9Ny6MhIF6YdtdvPEH6K1y>tG2pR!h z2VDzmV+a~4T}wmzw-3a1opj~(?M!VPAQ)cC%Rz8+L(s_R8XHRJ>KR)6Rz}Lv(jG$n z<Q=wM-L^{4)ly05BwbHTQdQ=KoRrH}_xNdUeju(CYQ}uhwZK4Gm0n`K?{v z{G)|np{Iplq-A>Xi$=iO%HgG;Jp{{dCFKn5tsU+3U%X`f?F~LFE9;k!>1cnu6tS~* zwE0y<1v_0Udz;rg>ASv|dabmflc~O;oCyD`i~scU)%dSU37c9t7}`P52wUhn7z!Hd zTN}K%D`9A5>|g@H_I8t(@7X)NRNWH7C9PaR(*8Rw)U<>(xri5FkS4draDrtr22_9- zrb+TRHYpfr!LsgT7s}H!u5oG~**;Q31ab9)-YuD%U4m$zUNtI3kmdO40UPxMx;dE$ zctQ&@%WiWK)b5_X=!DbyA+0SlA+=N(3-NZ-SN&F*7$U1SGjHm470&y7s4aTLe1|Z1 z*9MerKGOEh69_U-7;GR*FHEC$^9J z%_28t#!YaHK`xasto&^_|7HQwC=DFUw0b=@x}k zO$DnymM%HpMSfrvJ!4Br9gU52ro@S7I4J1MH%>Yj)p z*%UityapoOZ4;e2FTIR%dte+qg4GY$d~X3ZuDTo30(gId{^0%SfY{CU!?+}ur!IPC zD(aym+DncH6-q=8{ovX~bJ~g|*F@!>z1MWeJE43I$KwN6*=r;I{Yn4coL?KjYeQjV zVf)p>-&)@5d+IOk_4i_Qe~sGzW3#7wjklKw`DeSQdkv|VcYZbe-{au_*6`oV|0^w@ z?zi~+pH06_WzlMp`NPf{M+NT!fV*E#aHG`vtxZ#Bb^3P|^RdV&#+DDvb)9QY9~+0c z`d0Ehzj{6p^@5RU?uggugyfNWZ9PANJ+-dWBXVl4?tl7 znIPj@u{$ht_T|GHUMkmk^B=~@A2*)kM~$qP)Eo8N83Y&bg$4cZR^^k9bE|&hwzD0 zSE;E7Wv`x$Dm3@OK8sE_iQ0D@{g=_MS5Q<8PMxDNKdL{?&}B#$^(UoY-#)N-(XYDm zqd-oH^IMx0D#ASD@VCHv_Jw?C+^0xo-izgPHE+CGG`WKU%tufS?^~SoO@kHwD6d{3 zE`tWuK*5PdPvL+>-O1~Z;d{T4Dd!M@tD0G92)Tv)eTU2)n8~FFCJPDZ!JE+0wYQ?8 z=q!zK7caGn?BJ3uKG{oq1OoVx`udEfV4q}rBgWwDM9LRbbuZ-$&RG&SwD zM+DC)nV=J4pb{(;0;v6$=S&kCIjM5ga$VMCIzIXbxlJ}0`QH@JuG6y}5A*TM)- zOOy*GQ)F|*x*~@)5gw4SWf&mDc430n3){(Al!}mQBUzV>(x43>lp|hr@R~k=`-$%~ zWUYC_^k1`D!Y$B}L}{X)VJZ{&Fc&LUbC^-6e2dAa}1iq>QlM;91Ls0oy~>nT6E3bOCE zKSd3}lei*D+D=K9Au-6~>G!>tVOcuM)mP5TmRAIVL4zmjIq8S#0dtSlUFXyO07(~5 zjV)rm!{wR9XC5k##E0oFT>{!HgX4=C1|n%ku?$mJ3=Wu(Y4F(G2^z_3vvt>^(+LmpA2z~{KCv0$K$ln4be~hAf)!KP#c!ps=S5<@rT%GYIF<&bW92bx`(X8xj>T19 z-UaXJ@4FFSQ0>uiuPdpHa4*;UmUwD15grQT$`rLcSC>kN zMEgj)28F4gB)4sx2$>-ir{%1OvwAj^K>K&19^|98ngVXrfg8dS<2!Otf_OX8(BsAf z`M1>`WX8K^4h@&zed)%HXw%O**b{0qO)tE4kLlblWOtXo>ywr2ParYVfyd*U=R9YN z>DLd<7s^=WCqW#CA5+$Y*J1lv+8IM2*A25HKwarXe7Sz2EIt4s%iC5%$2H)}3Fb#uOeZ}BtRG7;eQWIMT3VEEby>vVQ)EX{~@;THiat64QBpIYX0oW zS4gTCGOmBa+R7PZ5UsIaG@k3K=BGh6_fP#<;xEc>6heJfU_uSNf`FcgMFv&P-i-y% zY$k18omkrG*Sya1XMY@x=Ahn(-ksi$oO0aX6%O;wkqXh#g}(wS9bS#=}wY!fJ- zz>M;l&B&SVld064D3}dP;?E2%oAk10AhQpr8{JR4JK^#xE!5;rgYLBVn{5F^88!+o zFvn}XgD^Jm-mw%OU>DSElBV8iR(i5Or)k&WliJk!5KE1FRPX-=Mqz)k`oSD9P6Tfcttgwu3t_Z!D*vilfvJL>6*0fN2l zE3j{{Z4x*>=zqZSab(Gcl<25KcU$u-g(O?Nny}8ygk8>v1u6+$VmUZnqHE(zyL99Hn+)`OySjup7B6hS(QYVUa<(74Ue(D;2v5ykSAU?5EO>bX^L%{O zPc77^>rDnwS?=y)S0w&WJWFQ};mO`r9F5&VctKp82$l$G*p1k7zgs^YVsh)Ue(E3o z9(4(O$n^gfA-|dbm&EmN z2w7>-YKj+5vuCmWWB~S)AfLrGy}LVbez83HL|AGaBPXtmdUjoO7eQtxn7va(HDX~7 zaHDE32lm)q_}I76(KHG?S9BT*pS<3O)0nX)B)O73-}pGHgk#;ff{#{dmr^_1wL8Ke z56Hk7+8tsmP(8XT0qA#AD~+^ixJA95px=v&$PL|N^c#B+qXy2S>u(2CxK~| zGByF|Z~I9|0Cb^aIeug^S0HQ)S5>SuXY~GxkOt1w5fL|7ZaryHcakD%YX=9gi=KK1 zi>jSiMN@gZb22>bJQ9IQ{K!Z%hLW4~fQ!)C^8t&dlr}!|hT+P;t(R5jcuwF7>6|%L z3Xh#xSENh_sG;9!o_leAZQHnAvEtC@lrV03q2emn>rq>!S+aFt@B`|mVyW7x9G|;6 zD&UOVqexF&0>1EB!wUT<7=5UcxF#smy5aCvF>V>7Y%{Q5+YJ6u=U7U!R&-fqyWzVn zB-fm1D3F>>JcLbv*>@bBt*K1vKa(PuV-gV(2VKw2R+Z;HVG5fJ^bha!=lnL)s*82fv`x%K(@vnHVw_UQ3WZ zeiJ2uO~rRAd&^mtz;0OB&HVTAFCc5<3E8vCMk?Mzkh4d}4?15i z^}=P7FB{zWwzs^q4)D6rNc1$2D;TN3N&L=cDo7g*?!fl*UWUG)80o!{=ba{|RxxZZ#L<3~CdWl2Pol)Q$ylcF2@m zG3auA&$#`>LvnM3XVPKz6~U=;AxM&*p()Hu&EJRS?a$D^NlT(PV5@;K@+D&K0?stk zfCX??plMb&^-m5}1nuRT)cg2u7JbQ>{H%oSKm`%~j)TBdD&)ZToWLz|fX5Y!-v_@Z za>l9=rsb;ymj^hT#WC4j-=>?P9G$$>U8v=BC?eT9-}r_SG{%;r>3v86gGDt*uD&2} z#NPSwxaxO6Dk3&xB(U4EN8dfkAmuQl0aF8b#0azzu>{2Ed1LF{S_fleb=dqb#xbA7 z0-an-rpNpukvYd7l_*f`&<^V$rav(mFsKE=2?WByj+T77l&zrvl&t}H?^^N}%zx4nhW{8fF#LrY82(5N4F482yqW)(wB&E7 zL2>v+OOTjS(piFuyvK2E9=)o7Bqzs(&0?ft&eU*aFkYFV@C5beEq5eW^5~YVY*(-f zqV{UjRrMH`eOsQdE&5{Z>|@XRaXyLGJ|s`N{&^7ETMw>I?rCz13W2Ah7H3M%JpptUYd}asVCSzDO_v;v*H>u3 zTaX94D&NXMuxkK%&&K9s9rFNDEnoL;AHR7uyVrPu>S`scJ_aqnX}N90?3O3mCDXxd zSU^SEc-t&b-eo^rb=bK35*8derWUS_VH(vieO7!geTLajPQP06%-=Y$6yOZNPr90K z$qxtFu^bmoIl~akzm)?wYJe^yNJbcT=mS5442S|^Jp!^kuYl(s(T@Q{AWg#$>9|*z zpJhFlky2x4T|iH^^J^wkM1nCsYnxt`=1ppaa(6$w1jMf&CK()N&ZdlIPk-_1-zr9hD1+TRRup-#Ycl~6%@BzuxNDs&j9 zAx@$^YUVa|d#wl_MvG;Ug$`;Zv3XT0&L8indD!Zbr@H__HA9ope{XhRMXQ@ET<_$> zveh<)vS_U?RnYo3k@>5aXJ+_EFaH)Ae~!%mSTE1`mtLOnkG(wOztzjXng3TJlku;; ze7T~e^-C{bU)R`VvkR4@-ZQg`v&3tPkP^&%*uY1G30D*$qb9npeM;hbWmKEWh)hJ7 zJGXf{$KW-#nI22ZD&(q2mV$AiZDk_Wx~2hq06jaX?+H~nw;Wy5_cCf5OYzz2+b{ZN zVhOiM7O{`Qx8rbPbftfnJas882uE*%m*&pf*0Msr6<2X(3Y^@CABsc=-heEp4r{#5 z86}GAFH1j=U^DOyBG<(CW2H1$*qczwiRt{nc39@dnDgXR=V-ewL z8w<;!WA!N}Pa}InTF$k8Nbj4#L02i9Z+=Zq@q;*yY1E?;n)@iHJzGf9HTJL_J+bN7 z9Nku&W|whhdMyk_HEfkbR%2UpG-ir^8Cx4Ap7~m%Ti^3>$SY?!YEfjf zm|erip{H6lgS`Kwr`h%nB|QC8ad>(*mymm!aAL^uY0Q*>4Ns2-?A-xpjY2igAmZr+ zo782@IT;Ex%0)+i4Xg9#pU2}))gy4V(^tkPp;x*!k#n;4vQBn3g_?MrRT?~xXI(#` zw5^Xf4-(?(lh?`w(%NGo%;^U|tEafe$YATx`#Qvw7}pgQz9&#JqP@Ut^S^wIDaEW+ zD5%x}qab4S^@>sYj>-7sspPxB$|4ma2vdV)57!BgU$!2lFj|V_Jme3uG)dNmw*iy! zKED;VU53=rJWs@K|Gt|`>!87Q<^xgUcRLy@~dY7aQxoST}DDJInw7e3Wkt@iA@Ug~8ieCb9jm7B7fIv+QQ(&a~4 zQ9Iqb9nq`j`mzQ?(ZJ+zC~<{ zQ0r4G!WIaZw-l_+he@brVk&h*uR^ZEyal;?^k#bdm#kX@Z)Tzb8>$j(}bxw z&z!CwBbILyxi^mqc31k!ktgVcGbd)CpGb^R_gejcB+ta*i&v@*Z&35HM7Wkd{W zaoh2(PFV=D)W)yQu=YchnW(Qe@np>>etE#5bVIeO-^OEXqEcY83P>DH0&QZN=Bc6} zG{!SA4n3(EH79Z?t+U`Ou2#XA2H+KBHf;|m?>Vs5djfv2@_F>s2#TJ~TJ(2H$q+i8 z>-2%Xzqo%t}<7tI{w1Xdeqo0-QHxLu}&4xgW5?NFn9!0SWbMSb|iA!gL##~~m; zRGNr^|FarYD9k#g6H)r)a8h~~ZaB2Ek2<-Yk_7dz;b1;5 zxer22#htAylLF=ncO*taW0-iyi};I?L%QmQZ0f0+qJ)j4ZVC@&2NW`gF~cO2izbmE zZ7)J}hS#TvZzm&&e^jtB2NpQ2pfF}4iZO%pZ7HHGY$P|Il3kRYX%YK@yhs1;@xf-= z7MZMZ1$3_OB>mJp)dy~4!4Xj0&<~(Dtw~mCNUVOLg6VtYeAJsLOok(6T^p7HNJYW)87z%*V}jz?^r^;)eA_ocDD0x z#OD_)urf3LLwx>bVTJKO#tKY-VFji?vI5h;#R_lc{}u6J`YS86sjONrGQ;hxu~_j= z04`276zUWuN)ic$#$mItHeh1dr`?LAIKg&@GJjaI+P^CNX+6K%cpRBP^pQEmtwulv zUz#wg^|)n|?pjVnT<(@zp-lYb>9D*tkz7vPm|8M!8~c)(ed3^;k@{5X^h9w!SaE|& zQK@DoYd2kE$XUjYCiAiC?)*rZX!QXEntilvX63lJ-P=BTh~xH7olU5z(&T&DXUKx- zYDY45^Gxy@U z>Vvw35=(|uu3)kRn;ejG*@vT8Z-}Y-9I{hg8g=ntK?vaF&_tS+Np+)sf|DIHDnZA0 zITw6IY{B(VIhhk*P*8PLA~PUG-J-W#u4P-+@qp^6`LF2;e&~NqFchQ5NBbySxhgxk!Gp(Me#mCw0R3ybS54yX16OhiMl-C(^7*Sask=+p3UB;w%HGq zr(QnB@a%gSVj`RyD0BYR`Uz1zyBpvc+I8UxA1#0@rzI({!OJPR-l;hfy`!qNZDKf$ z2-cBajE+x&X4Q%EnRPhS`Y2qj%m(a>Lp4F6Ge-f`c9T-=9zLV*Wcy`@>1#m<_z&+{ ztNCv57}VHCDC$Li49!|r>j=OeWRZlbCGtz*8|L*pr@1d{5!b!a82TFgD}HGWE1gmU zP%QY?$g+hRTWMntk>!{nc?J&!81Og@nf|Khthv5swa)uV+OsZ}`8nF_ic=V+58dtG#n{v+** zqYf*KWC!V1RA3m)1%bXh?Y4?7iDFjF@4)yo8cP2aTp8(xHyQ+v4Rc+(tPwH&XcAU| z<+@dH+I6EIZm3q)xC_Dk-V`@SERbAgS=2eX7Xj%WU z`RGmG{={}nuSE7swf?O=cTB&N+&?!TG5tnazcwE+y(;<3UZnrqy7im+UylB7+wNXi z_VqS@ShrSMmP4fb5HZ#AHJttoPQh^Sc`RSb2QX4iLoMEIeGgz0sctX#hLSUL_hZYl zWlOjUYU=*ZVk`~YynW0_WYag`!Wu5{@Twvn?K3*mWH|a}od7YkuxrtrA2H^}ZHUG9 zMXj=3ZUUXbG)v=`zOXmQqJ18_w|n=!B%Nd4pMINfO*pypAR2=7y7Ir4=|dJy{vh93 zC5MI@P3Z}j2Tb}h->R4;3y!ufBq1|VDQILMSSXNfjYeb}hEY;K)JiXGw+Z)YG@h*& zN8aNz0Z+#chx=-U7kPze!G58O7xOXxNOuzD-iO@H+n$04$W^^=DyN~98vPk#%^5ue z*(ff(Zf5t8tZpr!I+GuTd0OHJjjm7e$2%0#{SfgWrv9aw3Um)Rge_sNFB^?^M<}vF zUFk`!57XR{_i%p3iW|_OTZcVvdeEw+ESRYB8PckxC*pohpdjK1h?PzjnXr_=LQ_9E zeE)PQdtFd~t-z_NpGx}_S5CmKdV#6}cFO(3EVH?l>HG01k8U>}#;2G`*oko=RB<)y z^C(UpLLLlP4;;fC|2iu%|M_N9e=u^jY=RjR8%R!AFQy>_F6xhjCui@^_@+|{IR{t8 zCIos~eqw#M>V)D4B^9-JM>q&86RV9g`JPMAgcDTsV|EySUrfldQ6|vXTG^!0t?tnv z8ri0Il~G85(;|bY7sH}?9pY8>1+3Bg!_>Adpn1kmOAdzs?(z6`J0sr%QEJ$~nxIZZ z{>al38LScbUcL|697X3m!K@0X+2Au1fiz|Ajx)e)KVr>VTASrxA=@HbuFtM==_yYN zB5k|nA1IAkE)b08C-E*7SI2BWR}dI;UC~CtS6qkQ3<71jbZs@0^8+Engpd{78pgog zv=nwRiE(4a?6^^%7{M+N5%c_};&OAk)WinE#E{!02ZqQt3r+pi>EA^8FJ5AyqyNQF zZ&CKAAZLChpI@=_Zv{E?@5J=aAZPxKW_|_v3(Wl+LH=g`m!tn%kTd^=YJUiF<;6%0 zAvnveMq-3_+lX*#xwMPd8D4~E3oDuwD~=xO2-t9>s(2(-J|f(HJnv3D(@K)7`!m47 zBipQ83!0k?OPi%Mn~(EGTpX*+73FHZXe=CzLrwNltYdk<2k$I`vr7p8{Om zF6`~@U7k)Sb*SrjiFgFDr0HtQBWTp({mPjL}mA66iG0NMNJrXE0#Z;q-}6@XYrn*Vn0h?SC97|4wy05MLQ2Wlczq-Yc2(%Ns| zkEs)P+D>}DE{XOjj$*%6)~lWy)QgPL3g!S2tO&Bg!*3I_BYc_5wd|O**VC|TL7x9Z zZ7H;CxCO72b1$>&z`d$nLkHz`BO8YzlUL98wW=GU#M>@KbPTqykNpdr(ym79F`XEK z!dnMbL$Xj zm;?70Iq<*SBd8hT5W?^)Ep41=AU|2hmAgk({)F~7(_3#E@hT>Cv@iQIeqShh)2Bbn z)XHf!=XDD6>GZEB|V3rL-1W#!Y~uC5%$G8mSp>`5H62{l(0unIXB zGFJyUiXrkHU&RV453&z#C!!k(=%r}Q>YfC#^8>b^Aq zpZb8G=pI70pmr!N9Z__X#L&lvLPOHvv*qFO?F^SOfz1tLf453E;K)71Sn*4q#?Mc? zGMt3ZaGZ5*aImhpx%!M``G}CpX&t5vNxndC!aGOq}3~j|7xP^6X`W_UL$sxltX(qA?9w(U> zQ&bEmNNhFTWI+A^ z-aW(7dNgP*Sz#A`fgcNa?B-OnIO`&FKxz3nsep06xC*Q_#Phu_v@k^C=P#J-+@Lte z&MH$4?1u|dLlHC@<5I^N)jY_V%ZZiOEes8!eTJ1S>0Y$94v#=VSL`}}g+=CHut-Ns z`;Q^vn;!j14q5(Vw8-)oT4ebnEwcPuwD@NJUy(zWztUoF(yBEk6I?&l_J|<9P_Q#L zF9`T7c9eIUf{dp9?A3S13$MIrRA4g#2dcc2=deo8`K6=70@TPaX^vXQWzNP|47IhJ zZE?b;$&1bh@63Y^E3LQlzl)p4dN`yEhaY-M45cxoo^`^O^3ZrqoQ-IY>yTE{;Vsd6JR8x(qn=$ho*^C9d&)I2>*iutfGS=^QW+1moO>eEw1Ej+k#0DxlPh}gyA?8leefrtv zVe`=6(jm5xW%2Ymt?kH-Zn3j0N0Q8yO})kRDz%lS9mU?3xK9rs#vk?L&xjuB4N(&d zX}tUDi;t&e-)`Z!z33vXPAYnQ0%m3ugaO=ur0!GU1O|gOBe?r6zXUpktJy(+pIQ0lTxE zVMN>lXV!go-NB-Ip*guNW8s33Rb&*lB1zlv-jg7;|kV$;Br9}yY zAPrY0n(9Z1z}`3H$t@BYB%&Rjp9&EiJt0wcA5oArHQ9GvFT zAYos{MY}xBDP%hr2oi^FNs_Xg4|UCVWJ{fjAwrUo0x;PG8kD=@E~F&Fs3fL`*&u}B z{kp1L9Ys|HIK;w-UF2${DJ;n0a0^=1izkX7T1tA%xF{otRkn>YR&>exTtI0 zx6|_m|0bWePbQOD7UoBWJv$Y%PGY!l$7K`#Aq`a(TU+wm;IqZ^#S`Ag-`evBV!p20G_9b2Aw_*6(B^|_@m%k_a+F9$%8#=rs zAkw@f55J@d8@f0^(1=;SB----{wnbMtJrV3zQ1bv%C^6LkN=k|@|I5XUr~|&mM8MI zGxxvYiM(wK{BNkp+b*jAii-TV#K_xP^?$Y%I%=dpqMSg9?_VJJgO@W=OdVXQL|>0IvDbg$IbAD<*KfTZ@xt=kl;z9mDGJt#R;F(!n6Ugd zY57meeM8g#yFXN7FNe^W>i_?7i}kn7I)8AB^*5;fr(17~{C{#w;N@HxQ$sr`L+5|} zmty^m&;RJsKPdfoN`Cw4e!29&tzfbKb&A$dZrI9?7OwRinY$q9y@lw4==)-E#Sj4; z@O9e2l|am!`-K)Ubh(c@Moz}Y5iHBI()EYL3GMfMEVR`PwSC>Jm~Eg1Yvc3& zkVfoW>2U3iG@3D>whU2-7xk7wd6cSm@V=W{#tm+ae!eY)p68$*#;_Kb_11t^k)w~i zuugiaa*E%0F(BGRugTqY$cAR>!B4GHX8Fz&PuVzh0O<;iE_8GpE5>m!52VWfGfmpNIYtF zr+$}|F5fub3@tx`hQ>h$m)5G z+U<{1QGM%IXP*;wk2tK8ua8=;(^gfFno#}W`60~sFeiGytfogJ>jea zZ}Y!eBRDA?F(EM%=n#0v2(@ycc41$K9%4d{*#x5b9_L-;GiDHkWf3|T#Ni3)0@$pU ze}za(G!7V~b`Hk4_>tw!w77wY;T|R5|r$ z(i31egu^W_d2+RBrNlfte{S)7~R50kOuAKfQ?gg0%VFHbk%hw zb#ZS68B+$etVA{BV4awXbnxToNwUhh@IsyX0dQRG3c~o;PRx&$2|Z?_GMRFmgZ4j zd4yNklW+GI^r&umQKBYa&Tmx0^qkc=9!A-&<15#l%RHTEt$rp3JlCwxnBM%9gE*9| zSt65rsC#%9^bOsqeWwT>1YWSu@lZrlgERw$OJldjH$37DYvta)C^?Jc_IuiM5n!9( zH+r0?+F{C@9H);iI9`z6e4}`=1Au2#EQ#hjUcH%+nIR7dPsFu0#q^mz!&b`ZIm0BCTLBG+6vhI#rkGMfw0+n`! z^bYOlSzY(uKm_g-A%u^?H9QfE>D?;a+TG%-!Qr<4Tshd$1fbk!_~o4j*6e`hyLz>e z@}M!NBN~sS)iKnp^n1wb_fhXL0(Skmy5MDFt>QjE>=02o6aNU;QHgsu6 z!`{(CmCJjqh3^-E~uJ5h6^;%WPs`6#cvdARFknJv@qbl#Y$q!JUV#$h5U$~<``vRDr za(>dq)Hg2nDB4N%ctG-NdI#U)1Y}V^4);L$TA=;n#9>|_?B~_kRUjT|k=ieGz^w5W zJ>~LyqIW^8jQjB6wTmNxZeEfxc%niZ7wK0 zV9SwaC-r;w7f7N)`8G`|M0Y3V2G|`5E;bnW4-6+xsv41OoncmeY)9`-)z98FBOLB3 zUVvY7e)risEz#}QE4nvdU(Pq;QP>6QC;Vk!JXlgPENpV;4@ zT5r(^%0o(L-$UAuZwIu<;C%I)4lrMj#F#MNgQFw$Lg z{T2}Y=Ouf$XMXcS8#qspOzp1G`K~Y%s%P$$;2)3&5XXSd*MRXNZ= z@W3vt!1JF)?yi_8zdcwZ z*vhDc5aBP-`Du0c@{4Bkl4 z_|yr}%=MwK_CYT_5jPTNJtT`Wtfk8GxrM(v2PZ3yl=EzbCYJRwZFctVJTMgo#ya+i zdJOtRof9yp8y4e6QHZSzy6XJgc&Kt0!RCeJo_g{z3kO>owrL8EwPMUJ@oq)>DzGM^ z)?z4iD|s~&CbJU?OwP&4&4L*8prE-Y;XJFpibEJ`dD}^eB_07b`=dnWin>GMe3d%p zD1P?5J3?*C7+t8QRIx0oQzK;olXxU>ph?77xPT;j%!!nrDV;m58izft2B>$$2d`;% zNH+tmQu;d6a&CX@!VYU>IXC+DtIYSTxbwG{`yxh2QNd)7nZYq}(#@*Sqv{Uk#8YaD zLaKu35S|c@oT-PfdsFVJ9Ad<%`?hnu=h>&@4Gic(3IgXO2z7qemMr5$RZ|P}*_}&K zxgYV>Kg*_@S`bNINCY|du_R}hR*yP7w~~RUEd>@e{Vak2^WCkyJ>UxaR^11GZsX1E_ zZPAcyY(a%)X@(Pw%819>zy>HQwxpS8Pf$b7AZ{|*&8*hm2Z@e|&q_ck7Nl(eH)EU% zOI(LtqMxn&d4|$G-J$@p)LWbc>ACeRrxwr-0}?*Q*m5;Fk<1HRm1#1z4(g>{bycVn zloQM_@vD#Y3hQWu3O1>aJ;}CqcN_#DKLFa?!!;g zY>|DwX2e1c6QsbzC2<2MPlG}q8Ay)dS|AH=BM#x8Nfub$CPo}|QTsD=fc-A#Nu7}s zJfU;~Bup1u*u*grFS!!nMxYI!zUn2yiGM+;KtlQucQnX4YdZ-y4vw_Tu_pcakpkfh!GS!Mm)Py7zI#q+DWC*TZ3e(s2GP^>csQtjk)8J!Vx@5Piui*3*Xdx6l z=((c_tw#SeJVO76j_i^K2e zhaeGdR*!LP!#6Cf+0o7# zG}WWXVX~HmF6$d5-GB3SxdVs6@jA4Wd{o@XhL}f}T$7Ih_u1DbVb|C&}I4lpJUQr!A`ZEj$4fn zzw>15-JPU9IJ=^m-C8^$dLZ7|k)yY0f`Gb6S@ds4Fdm?nZLsGdz&J&-s-V-u{9K~= zYPJaQ*wHE60?B@`hu4O92RuE6a93W6*s?V5FA`orfcOv9a=Y z<|1i4JZ!ybcg=}DlM*=Nz|tS(vk)elU;kHv*kJzvAsfD6Z3lI@xpf&Sp74@>hpU6I zlyxF7LXX{O@uhZ8j>An&nX=6}LHG9;AioB|*XHfu0)pLb z)P#1fn2K`xVT4nLGCHtTF?BuJK49SS1$5JRW*39MYqq~l!HF1^dsmYm>_hMu8PI*u{ZVNd3M-2rfJ(Dw7$2&%+rAMN7Pr=+PM zHn%WOt7HQfssS0a88cZ0$lR+B){b6(gEpS!-mrI(%$<# z_lsFyoS5sLYYQBCPjI7AWI7fvDlQUn&h5pG-DMki^A(V`8Y8 zd(S!>Zf8RK*nMJY@lC~>H1>4w$cO3i(TgRxJc+VY)ZM{b^4W))E1fd7XAp8_rOM)9 z(tfw&agRfJx#>LFywYmG+_EPd-eo^$^9E}eN?)V0Pl*B_u4Qov;ZR^ z19|LuoOZV4YdGBAD~WbrJzLG8A+QBI5XF`H53Qh zo4@FX9mP5?<=VHc*TWK+bHLl%${%hg^GORXY@)Wh2xzp2@vfoT=`1H3o(V2E@dvex zOa7;*>EoZd+uRD0s)X{=!)=enH=mEd%&b^+VHuGM!&JuDOy-ub>DhMj`}f)!yUIsU zapPt?m{o?K=cbATCwC_btAo&h#*jvlw2`zBwBxkmwZp^->V++1^nI9zZR_vN#;A^# zkH)$(g(Cgy6D??5L%wa?XZkv2Kk%#&J z07yW$zehQHOm8PoY#Zmou67*UPTv60DsRI?Q!PPNEkRYOpfWU5mjvDh=B2`lUnDC~ z9O-zlp}Dr#lj-CNas!w}yGS`I#dmCBVwVFDK9-?a%;c@EtFFGYD|g7{rn~~hYR4HF z2SBr_nUE!egHaCW78fNkO zZhR2$^nCw^w~w9w^q$A2#Wrm^r*3A)^?N_NbivOaT751WqX& z=Ka8X8Qivm3o?*zFLEFyw)KE-TPSGI&I?8nrm~UIU1>+a!AlsPi)o)y>+?lS zqq2590A9w&2X~PtP>9Sm6sV;D)wH{5_mb)HE8-*`q#_b;k*rH4>r$!v zQfWz=!FC#>w4NsLrbl0(ze=y~6KuzWw}#%vyYOJp=N*Qv8>83vZpU{Oxg*ob_@ju& zM>Dx@SnfJR8o*_Eq!et@E}ezWU|z*B4wm>&Er@FW!5(fNu)kzq<9tYajJKOqO3a z^TwNRj&FZ;&emDeA3P)WtJ^#B|2#~sg)ktN4wkkG?fb$`q!o@E&(rp?i;Qs?go~_H zOgLwyz~EeDrD8%mDI}d5L?GyohA*EjAb`;(53Py{_`@}4}`ul6DgQ?y)O2xWPKddvgp&zX~R_DsnPR?dmpON7K51dXXbT_!TJCPj> zKzA0<_8r4kljX|#WI4X1q>kRA5tsq4F}#{#%W5s-vzn34YGqN__Q^8rXvCTS{6iV= zq6Xj^SB)>};#`>A({(d>=x49I(v}~9r$5QJ*3=0ZMt8b?9a#7qko-CPd~%l=3iR(alO*ko7mch;{bqD6|t{ zXl*-fUL19(F`qB$rYg+l2-L#4yPU9 z#_-UJ7>*6#138?A4;L%-f|JK@Qz!!UVz_AaT+{U{^c(a$bYB1e0F@vEl^{kzJxGEU zs07!?-MjGsI(s&uy)9~;7h&P)$$n`0ay+(6~wd; zZU#T0@rP{F6K?=yJPBWd1E4`ZuLPE1dh)M)_g{8n+op9Ft?Tv7?c{^57slOuX9t#- z-gfkNUARSGd+XlE9@sjr-cSDie16%q{INg0dgs=I6j8yhCK8;heNTSJ?~>xQV=GL|5b4W+I-^vAosj5>ig+@f zpeJ0kmgDUN>KVarQ`@nfsx+(4m?|8!J!Lgf%Hph4H)o}m=!~<#*Vh5y;02GoKy6=r zeQ!Xv!G+0;HNbWw3G5}nQl+R z)MGtauhUd&OqoG575R)_N)=j9lmedvOX&*cUWgLaWNvEdB+HOXA4K&U_V!>y?!>lW z?~x0poHO|na?b8KZCyWo>*l}Y4?T3t7n?rr8Z_?qv5TL0?3$~e~H=& zvnl_tKd$Y(9*@G;;%8poxaZ`@xn~>OAHHw%W@ynFpxgYy)5wk%8IHYn%)>t-^9m>r z3N(EQ<`vDpgyRTp$Z^c(<4D*kFH!!6#sM=;CtN*juD~~d0~B%;g^`Ain(M|K?HsEg zquv7b%c(7xb!AP%4+M_J4@AU?QgWc%J!l5EeO?#6%I!XMwX?(V!hf1>@P zP53MP>Vq^QHW8#I1X2?~Nz|7cu@gltS3S&NSPB+pr+BoC?N_t1k7egoc4K$?)aA^x zFJqDv?cNWw{Yp#l`mp;_s+yfhv(o%IWt=jG8i6ERWf6?5BT)S_U4gQGiG+#utm7(r#zX*n8{U?-hH&I(^~)>T}$ zOmpQvjb83!cl0rt_MM6koF06j9!h66+Z}^=fmKAbDk7Q{ImBWSPD}9@pHGhgandNG z2kB$!FMUkw_}H7CdOz!7@GM+itbp~Uurg?XA6NQE`bVY@YhU&il)m^nbRE8yUn)1- z7He19uMXUb*5Y;iDtU$NW^I-Iw!oXNS3K@AfRC-wc$jYD@oKv16Hil2301~56bm8^ zsQXh5~DD}Ks2`GB?T+H$Q+a@UX-ye%5-B*W{J~?1J*b(a_UavY{z#R zq5eSzFhK?|K?X3vC9NFh+Q}TlSI$nBvyx$#GhBJ&TY(*tUY-j!uMBRJym_Q0H;0EFi+y6o^v z9bYY2xcavIu@64TAG`CCRSV{>yyen4Yle(mKXJvzO*h`~G#9D7Z~lf44{W&f-pby4 z*X%AJj63dl8Bdyf^G(xduD_#gdMhN{3b>UlM5BQ%6?+$iMSZ=6&vT6PEEroeI$N+ys5U^XeCN587sBKr__q_lXsvy;Ucc}nbYJ5G<8viiW1aq zBwCsp<(hG>@jpz$ZmaNYGN87CYH8Ra5FfXTg$vV|35kzM&!SEKYiCTnZu~$z@Wq8Y zPGaemJ36nq`tOfD{~>wf$)(G;K6CALkK&2?)t8UH;ZKXS;FJYe{?h@hKal@x{=59= z`E9>^iL3p^j=c}A162)DvJ+gBReYL_4GlKpynsYWAz~fR)nSoWNgbH{h|oyjqjGUX zpqc93PMwVdWEnJg2GscIP|ePL`}T2-`}UoDdfz^{Hye9k_jaI_M)eZgO}3xe9=9E_ z3CM=i>L7K5Iz^qWZdX55C7bGy=rg4{Q4}1!?Kzc>QzV5to>gN7LV_sO@#tw(qSdk4f+pw*#jTl_41%g)(YOh8rHeOReD*!>wTF&aCZI`fymYbz4pGb|zWzKu-HGL}2uaxTJaE6yZ2}%tw!LabEMnuauY|$T5)<+sPtBL9+IxK`X9U@nv8*ebU9Iok>)5+@wP0?6 zJ4UtICXQ;2O_-Y$~J3ov}#rN#|>20@C%kv(vlD`E0a#4>BuiS}v=&4FN z!ou?-l2ekGCYLBTE8@KHmBJzgWJkEkCRX?rE?7|&^Oq==?b#g*U;%^(bNCgHJ62Uy zS&5=0F=*-1Sj>fFK=wTQMbH9Ds(B1M^+JMaQKKdvsHnq6is}K;O?7}M(tZ?WS}T!p zj_9RaB~D6NckAgP9Wy-iZmF~urFYX*dJm0qUERry^y*lg4K&1yqYTHG z8e&9ogyDD_V=$8t%`pd+jWgsjXHE-tk0Iphx}dBZ%l5~Zp+NKRRM;540LXQK6;vZ; zTv-|xG^2uayrIUG=n?XBkR(p@HzUUBWCG3&q6kgtdq{fY8%r*ov+|CMT3%k4{~11O z#o!A@jkxjQ{6~16D72{`Q$@5n5W(f^IHZj~)=7 zo~w&BG@PPiWnd;Q#sQH}mX$-J zy31?&^8qPM6&>+;-Bi`_ZF|nj|K_vK{QJMyjEC;|GwyxnOEr6b_RL?WEj+yH@lOfq z_w9+7@#TN~3{T#2@Qpqj?s_c$?VT^?zg)YUYPN>~zo&wHIZ+7?8SZ!~9x9vi;L>AG zBnK=G?m3cp%qT0qn1V}LtX^S^sikS zw-`G1BMe>K&7H=@{rV2Q${5H+Bw3UNnU{Gn6buK6Xj4JzR8I8yy?&3M6C+$8f!z)$ zf^sy0{i-WLV*{B?75uHhIm+rKu+?b<>{sS5M^@T?9C5qq2`0|qvbD5LxayJXRHs$M|&)YXajljj= zSHc@A=rQ9g_J(&zxcepH1s{x)xQ&po?f=(XQ5S?T_0L`<{~zz9o;mHmzSAKyEbjKT&qBbToq#_nJk|(Dyb&L1s=z;yJ=o2am!pI`KvF11 z7(n=FJunsnF$V`;u7Yv8B2{ilQn@8b8HrGcP_3YR2ffW5u@6S!2*BS$E_C z8U*&uQJ^f17J>W>oy6fXrUY)kaC>{aQ=XF1_6YliAG*G4;VMd#f>Hl z@5sNk;ZONT+P2~GA3cKcUFpq<++%mZcyJ+i7F6c zlL0ZTE|aY;lWCVJ49eq@B+|heW(UA|>cj%Y;DgYgABko3FQ-e$niaUxRi$39)VPSu7)BTTQLG?bFxX z_Np|u$&|S*iJ9AA*vz1)vg@^RVZE?f08s*)`wp}LwIaS68E8B@fQ}%+9fyPK5hs}A zXtY^_#peFnYVL2W=B9$l40hJskMZv{_Ru&(r!{PC0joUM*u1!|tJ~_O18hulTYt1Y zU)n>>T4=dJh0nPe%#!`g&}Wl5;!<*@xW>N5B`ORx+H4dw+Hn{hcBi6PtfyG4r*yNP zl2+9pXU!dqGt)L2r=YK9vqq+D=H-kqjV5};U}1GzF7Cl`kKq~bY4Y$MoJOYAY^JkV zZ1(3OrjBy&u$rP%&ov+GHXXr{Fdh2N4738u6^C#J4uD2rLG|>Ro25lFN6zoHr}5<* zU*3l|1UFtgbjkJHcPB&buh0L4$|YF)!i7{WiN}a>WrMP^GNeKsAP!W|Q!nCHaqn}| zGW7%Q15n)*3z?zOOIXLR6`tk4k_DB=1NirNn$vX9P~3@HE=~(D-L`32H$A!y_T}Q1 zr`r;??bzn_)8n5QXNBOIsnl7r5(=FK2&AZrtO^{@#|70Z2(Sl&FMJC?}tUL5tg;J^xa)-=EH=bgCI#TRX%AhfOhq65VmPN84 zc%SU>1L@C-w5@IKtX$^J@`g7{+kSfrNME*x%h*V7jGGtdGKl(?RGe@E!#~M&&mQt8 zEOp&aZY-d#V@Cj`D#`m@zdU&#Is8?gFY*#!#jA-327mct|^W+DJ&mge{JB z0mr(4`=8CIWB*~2ia%zO9?qFo6SXaq=OLk9Ub~xZ*|Z#kW9wxQe-7WmP!l|MOJdG@}gdJc4%U}!B7pHe)1iQ(LWD0U4 zolG(8Me9$rI)vR8(IJh@(dwhj7Xa2bUnbWBolTyN7&jo|l)WS(^UJhV+V7w#wUOFL zCs)a*?7bZg+{OGd`*O!>yKEzZoV5>hj3cACVUi(_v7hTu?<4nf_el518@ZA@4xRQ>le@)D+`Gs|WXJus3URp|_X9*$ zR2JGY16gX^&~C6{+b(!v2e!dgq#ZU+jI2N{(^V`KkK)cnI@a6Clo#Sclh7i7rXw4- zxu_`+qB+XBx?mT>X&M89y>O4+Lpc-#d$>;T@d@jlEHMa(r=Le`o-nj)fQVQ#R)tgk2}TyYu|}r8zZvt-W@weWM!kjN%qf50P-|AvLgg!f0Lv~lV%>dEt!=Z zUifZe55CHgU9X6Z-CBjInhGr zd4N~;vG5LZpa}LGqry(?)xF+GAQItuo%h-Twg~@BV29%s2NwtgBP3p8xW;+L1&nZm z(4btTPj*fBObtvAP6=NWxixS<(L*tgbH{9o&oZ!lR-gN*q%lR|OUJ>DwGyXU;wK&)y$JaVh@B1MQ5IJ zX|3Q0}w2iPzwPZ{QKnwdHrbv_HRV zrWpXEO@<41fK z$eA4l(Gepy+qJ+;M(Lxx7wZ>$d7BmkL_~q0>Fv9%COs_^atBMvN;A*O#d2v_KvdR? z3gxKLhrYQSj)yV)3kU72$?UAj?5xS`|JO*te?~t-J@xmgAZfGNw8dt%!XM0A0?(C& zg<=F+Hj!`v-5n7km3NJ~?5@Ud@~`FB;A?h2oEzQm=KL+fE{A*ej)gDgySkp|@VXnO z-Q=^=7+gc)cHtY~VIS&+A2;rvo_-`vLcu{kVvF*n)cN+7dXr+6&?k^dpDEM@hNMRe zqXQ$;Ibm|LA$^5#4R^J$j$0?(jUM2hK+kdSqIdnDq0a)J1;bGxgQ|ox1wJR-6}%_? zZkkW|tJ1apY5wgmf%o6p8p$G>8Q3?H<%8Z}l`ur$3Fq&{NxjlRzktL9=Lrjh?jWH&7ISh$E{{n{ z*y{GM)$QT#ka{@n3DVB;Sfb;xd=C$mA=+IYOLQn96IA;aIeos;1_} zDStppSBO0#7F4+4=)j^>xu}Q@N>}jzT)jB^@I#OP_SO9E&8>L&YgE!M?>fA3;d3Bh zALKv9kw4F!cJb_oa+%fHYcB4<(?0wF&)W5J{>cxw=MUUgoqG^xw_^2Y`Su8;+CE_Mgoy?ToAn=KG8NU zx-hy}S?;*Xxl&!@yx0DWv)%cH<8!ADwqV@l^txP5ms3;R5t0b|Rnbi|{e_^S_ygfk zEWq4hGuGT;_-HQ%0w__&U?d0(4VMHm+a|5rp2|EnHOQm^bkV~<6!4jl>>Bh}Q>Dgp~QZm^TBW*Pft z!oJWwm#W7fRgWwgSCtKC)~OG1xrb1NiJO_ND3^qcpALqF%Rn97)PNw2#XzB4rV2i>R=OBZ$Q5$;qk9Z1e349G7}$2d}bSZNJ)ioqlEclGG}0 zt?d^3TIX&0%JQ31ciHc8-s6iEU9LWfv^$axE9pv{MyN9E=KJ?cquGE1_C8ldZi$dc z%5U!zt4QIL;1?)HnnT#JK1wX+=a?~&0X)l@fnB=Eu^j*EPV*Bn`lQMocAJohmc$~m zB=Q^)ajLuwj)_7n(kEJyiVG(X--Rd}w$Kxiv2(QN?ZpW>LqYr%~eKgeg z0>w%?=^4W+CUz-lREaC8dE{^qnyYuzD5dwT4EIlHJusc+lt2sMw3`~)^kTOqhVJfh zb@wDHt)YI!Sa)vBAr_u04y{>$UmRc4yK0ccADX(A&Tx|YBaZJwV4fy#06Dq16($ikBPygL@S3Em${IoOkmra;A=lbt{ z{`kLF3A>z|o@sqFI~ae^&~o*v6A!(b|Hu9Kef{#=E;@I~u;Fu(ff<=WkI%m1&)%TuH3(5>6cWp`hwlHi{)K>VuVD7UlJ=t7J-%iTO3wo5m@O* z;;=4C2_y!+kJu6#N;_GyEpFx+ydcIgsixU;7;neLnDrNijp3tQ1jp~J@W`hYN}jY( zF>ku%^p5h5`+G)8=uBt5>rn2n&gRe77emqAe{}i)9g`uRdz2RJ@kv@LF8ywIZk9 zG_gE6((TC+y*T!A&^UudHga)4j{C>^Nt1t(zs1k_f5aeV<1m(+sm6;_JWMsBTKuba zs}Yqi#y3ngqIRnhHRq%5+$l9;#`nhPxnk(G+u&y=X$IwRjjL$rv%o8h!MgaSJ+tyB z-uZq0_@X`MZMyEg9m1}YTRzU8eEfE7|B@Sba_dXmFWG~=(5ed979;448{BDlgx-v0 z7@+dOVvxBz?0lRNsD~TW9fW}y7AMbP3)Bq#Zvux*xQC=)LW1bj~f zFCl^gkNPsMB3YR&L6%duf2s%sr)%m|k$%Ko*HXY<&mj5B?zky$7--aE%#jslnu&uHXF;Uw1}nSs%Ra zm99PDalhZPX!&x!l8s}42`Vk4)+f1^=8NXd;FCEN_{7{?0&5hY*`6<$}dJDg6<>v6k%{y;DYUQ^vR z0R`i9tGQitYfSaYN*oDv%?H3PjDmtJ$9zGr&lhxSiW2j=fpohxr!%g*yt?jkE1Dei z2~L*|AO=+uxS;NIDvB%t zi|SbbJ34_KU6gCxDov;|c{BwFt4{G~F}CP{Bil4XFb11!yEuos14BLZ0u`K6MVZeD!IKhB)Sk!DH27>_G+DXVzR8`>!0Is8*1i{x*E;Q5@m8k7_J2aI|izDvB zapVq$ciRmGnA>YPP=<{e30l!G__Sy$kl+rxV^4x&V20^4Y7cbMBvraOOznX>pjrGL zICAwFnT!lDD6mvTO0A{|iaHddS_8m4QJR`4Yl_D2DjY>z;V8=}W`-SR9+ScbrQplA z7e3h%qR!B%OymEA#)Rt>F1pB>U2lAi6XS=U`x6}fwCe@3kQv*6LKlB_nm)}~$g9D4Elz%2a@5URcKYu~t3qH!9je4O$ zWTVkru`5*}d$_97UR9N~5A+R+45=Dfm9yun=G*60HT7L{N7XK#>}Piyv#Cfwf36!Z~MP9u0gd9%`>#-`SNpWUi0U{o7{KWwfS*BNl~V6E;zEiVf*g|7Q^U45+Oz z=W3o!m_y|E`Mmx>GR=vSgP2MAa1mEGYv=sUyU$y4{(uD^&cQXq*W7SbNo(-(w{BVU z?08)Xlhqf}9(UGHsWhzuX`&-PIx4}h8P{MzbCwGOgyDivU)owqN=wV4 zHPLgUi%Qp*ibFhg{<`pJ|LAZ|&e^X1FzbDfv_FAsN=exQ9A_%QUT=j*`N zp}&?KEG?9V;zG5v+S^yCcN)TI=Xl{#;lq-D^2c>e_c?fxphy&Skm`#%Y(Xo|5wvU; znp13~7;~4uWy8A7ur=9QY`mF6X=4&&3l@iMk697ABUZkKxd4rg&eUWfP0CplY2VwH z0ywcnS{S>yYLJ@=2hZezHwTQE16E^NSDd-XNs5pT49@!o+=`E2z7*HvahSu@#;02l`f2rWkR`vd1ZW(Joj2$-?}f6}Vl(rM9Roj| zjY#$2Rx=D+&ytQ!+-_csniEOzX28{s5uc8dWfdHF+NUN)^?AB&@s>+AHyioyezki6 zshxc1vgen`sf(k30tklgmm3w#|wT>H{*lEKwwP+DQJ@1a%q+pb{VTVtWX@g0u!6Y^} zh^}J@D`EwC&0cb-SkdwN=_*3Fj!A?!3ZzgOhV&ik<1cEZ?aKs52Kg#q3H(Tm6=^+NB&=o~Ujn61q8 zHbpy1-x1#Rd>s1B^O^VCz~4fjF>LXdmS(~fkVb_mI!R}MD}0832pM1>MTXl)ct=Jr zQm5GG*gq3L_aDbc9Xj@bhpjsSb8M0e0qAh2fzJ0YFwm)?{rTMstQS)*r**;UOi;m? zAf@YXxv=gsTurVP7vK`*ToavKZVCx5rj992xkSq6E{0Yv7A&Ft=yK40bXkcSE-N8} z5=Ijfq@`|iK@D?l2gVKVa)~+l<|X30ErAne~%D(#p;kfr$ znD6Hv66zN{$2}%|PIQ8MTIj;)4EMtDjOcQ4x$hV`7Sxd+JMDqMcs~tHasH@ty}m&w zy3R+Us)TltXQ`A}$lhVFuF^rE@Ad#J1gsShPFpgJnKc2!4)zfXS=p`SN$gf?pq<`I zsi>-LwPSm@l;+Z<(zSH^0yTq5ajBo`hG}euXN?J_#n}Li5A<@$D6guu`r4Fw69M8q z`aR0}-NcG0>v5L#O8fnE4U@~Tah5}H40zxei{Oswo@xju%*lpzUCnjHsd>d&EiBW_ zf(3Jo+$$wm{0t}9A^{@zlU=>P+4*JuTkQSwyV!wGexYt%Idfgthh%~_c*-r;K7*$O z9&f{?phGp>EB{IU-+FxWuDST`RYT`KMRkq`*r7#u8wGHs5%Vh88LAHT4H=)R6?X)=L}vtpCsws$10Y zZMaudN5`D z-+P2@L}Ga5q{O7kdD6_p%*v+TExkXi_#*L5^4khmz%TmR$(FWWQIEt_u^vZ#nIdjM z9q26to(#Fp(1mE!sSYoTYO3E?ld9>t?ALeJ%*pSK3KjxQ1%qz|upTf1O@WpG-y6Dw zOzzFlIKa?2(2d3chQ@S(40iM@6OHLrbis@w8VAgDKSmt4Wc|1?mvPQgCr+WVQpQZB zjG0OqGnJOV#ls?&9>Bh;h*%`|8 zUYelroEdvcOq+{CGI~#hW)RK9_ZVG2=1_5V@F6q0-3%%`K&Rm_U!uaC0ZdUkFu+PN z?m2h<(#^L1LziB+Cg{M+T0c5+`5$iEef3kbKicr?ukL^9x@$LXx_bG>hVX<`|5;N9 zwcd*BKE4m*b@#QLod5m)<7v6r*NfZ9%~u3idOF z>o?eBs$Q)0(vDTA2kTa!WnJoJo$pPVxoA4n>IhvSG!EQ*5b-Q+rWnpSZUh)w z@Ya-s9vNxJO+Nq;1`mX}9bA3Be-RlZUX8)Pc15 z$0_TT4N9xhp&U?-C=yail|@R6@<{Q}L8YLmr3%>Z5>Gfqq{(|mANJJiF%kulS4Al$ zApQ}41K-Mb@CSLZgFnI(#K-x!V2|fbSC7yq7rUQl-OsD^`8-n;yrn33Ysin)Q>CoH zkClJO1dHp~qGZt38EnOxsh}_JIqrJ;ADf#F{k^8Gt&RWN{{1I>eEP(PR7#;Yx$oKB zfme2L){xVw5h<&`zBBrnt5UF@GS`bM(#)U`r-)M(&T0RLa7^SBYre0UC8Jt|Vi8<% zZ5eU$WbUUbaf@*e3&S4S=B}V&*&}VRbqnl3f*mk!h9e@+3%oc;Igb}oVjs0Z{V8{) z`XTpMQF=7uk$+D-Bz`IVOZ>O&bE~Sr zaXg_D6%-kE6j@H0(-SzJPnlB|ROoJ=4r=iN9jLI`kjl4Xr=bWu3kH_SbZ>Z^d1Jbn znz$Z}x#H{u1`sxL4Ym|AM`{Q=XpYg46vkjz)T41AQgl*DKL!mf`y82*Xc&jkm;^up zbMX-KHBm^j|0QwWr9Bk`UAssxnhSLBzWEp(ya%VQdyE3?^+1-6it*Mo20EWX(&ak2 zj$>tUgvUNg!KKR098rRHn#&5#pSjMRp(?#gvWi?%Qb*?@Y%QVF5#HGvXPYgF;%as* z5xE($xePmzSm@ZAU^%Z_{dDumR-H{^fDPNz*k+5(N@S*PCViCqV;;+1KRnIrtz!jE zNZJ~tKmK}4#Jn8m8qL_+sgwg$obFJAaS}_w?)cd+^YigbpX49CLD+S2H*U=@>zYMM zug=qTq;CQN7{q2}jWO&!aqKkgD$c~}fmElVleu(LPb@kOf6OskfuRkXc{OOTIRmS9 zfVu74&)k-oGqj8ps7a?#Dm)?_5cqLW91*xuVUf@x6a*ghib^Om2H&{+O-_@VeigP_G(TWs%#f3yp3 zYGV_)OglhKgEg5XpYBASBBba&a#>BnWf3J-^F=KpVi94BD6tmGh+0I%BElA-S%dC& zi*Q(k(;_^U{is`n+ag>R;jzpR-6Gr;;j#$3m2D|o1RY#5#@Ot&DgF?DNcl_Pv$*iC za4b#&ay+R7BXNb}lCh}hqlTY^#bh|7t8b<7`qYLLNd*F7M{2zbyLc8pV9A~?7LRA) z120=Vr?{{lP=o~$G!{f)k$9JttlJ}$fOAGHDECO&W6T;%t&iXcdqAZ70TK3q2n}Po z=mR3mN{O&&Q-p#QGnXP7eN@B>`bX#!dLdGiWVcT;uuC$qOQ!H!2-DCSDMb|WI0kto z{{eX{K9BrGo9LwFJsmZ?%s4Vx(qW=td8!>R-}0u30k%XHv#gl&)zij$ zwEt7{m)%=>{p$}uyDd5G>_tCsYnU~9#SlJy_t@!|H0;{EqpN~EblLPFcR$f}FWI_$ z`S=I!?E0W+Q6C0L^5ZRrN8m&c*{HYcf8{>+9N~_6M4sx&GGMu@bbO!wR`6i35ai>s z*WvZM!J@{Z->%vnn!{pRhb3{2VjdY#oyGkY-58Iwt7>$I(Q^V76ms1TZ0`zKFE<8pP%uK zpYf2NagRS`&f9Uhiqpw{)SOm-U{1SwnA3a_-8u~S56$zj0k*PI_n&ECA7v)?X(uw) zd`&hDq`vc%jqMj*iYlv;%87c~B|0M5sk(~{L+5HYQzgn6qd3IVgDX})cIC%SkB-;X zwyFi^FL|0z-@AGEqA~ri>smrqUB2*~yWZ?#>rD(Re8E>h&)ZQ5zqG>_EGBk;!9<&` zr)SKjREV8$OKM0vPds0qA~wo%#Cft@s}FGx@ec?N*GIWW`G*Im3DcAd^_)BBzc9E^ zSg6d>7rGbvX9a(XeTpd9FXko*lhli~%edLXZ1plt4Mcg#1whp^_v@&Y4feg^Va`x_ zg!$MJ#yV2>lI{|Vbrz%f*02mCiW57`1^9}SKN!(rILcGCeI<+}U5eAmpWUm2_B#M* zMXy*$!(>1^7`r&kycfnaj&h_qXlRD5GK1J)0*W&3V1ckAelWB|Y$`7@;Bgd~2x1|$ z;v)TQeI(Q`OhaYG<@tMZg5I3Tfti&%ojaE0sD{fzw|4Y}tzukyq*#71lZ~o!8 zZ@dnbU7erDCx9#5D2DGbmTGz*{VaWy&ez9V5?t^dBU&OPMEN+aNpzk6Ss~Y(shD+V&C33 z-hJcs_bD2jpP$Dagnrji6fZX}vylv`3Z6+uk*hSZ-d7(Q6-QSj`*(ou=u6+RZy=aWm?9UB?GjPWP~=A%p)IY9|iyF|1xwqa*{YP zZ}*0yHpwA+qdatWz)^#&{_Z)}RSdi#It=2(y3=qrIa~gp_Pzv8isJ11>FS>Dp4pk5 zYwv4@yeTDyN;)-o_gwNzg8d>Zw0c% z{ZjGfZ&SSarQ*#m6>t7#Yc(9(xitLNUKZW*K1H^0i|wyzBz|9`_@o(+#2K(++1^ME zn;|u9Mus&;v-IEj1smTJbN!+xHeP$pPg-XSv+qcyn_{eOz4?i|j-9Xmbno65U)g`~6_%85LE*lP zat+dZu?s81N~)0 z@bM8VyH2l}Y8xT^GZswfN_E*-o*;i&$|*fz6go0A&XP8|+RIl7QfiQ)XJb`DLa z!0wf)awqJRg?uoORVysTw1Ix`mUaDR*Iqoe-+%#qr=}HXrH?KcdhU~DLu#ilY}t=E z*Tz3mHz8-btB`yw)x9OeX3J}N!l~1ip)}!;<)hB|F_xjoF%&w6PL3hUNnIwjOoeHM z=emcx2NsVnoLRWUeV2Ph@e|<wDDWY6T3 z$==DnIp!Sq9M7DTIo>(GEu~w^{JiMBxO4B~NuK(Y8KpDI7Z)uqZYaLj^RV}x^835~ zsQY7{r@cQZd#rqO=}V;<<<1DA&@mJ_hGNHHr&o89pgW1uon-1fM0zh4DyW`hmX&xt zT28byT}$bfpTkP_!tAbciZZ)4dsOzc?2XxPWb6LyNcQ~f_p`M~_TAYc`{&?*bnv5` z{fecr_W*Cl4k-H+K}tZ8r*CXd%jhX*#rRMIMd>yr3=54!*_AEGj(y=lrGkaSZO%Am7mfjN5-I2S(l#Et9Dh1 z+Ny>sQN9lxfMSv9hxYid<=3OM`(>ARJKjLSHnO+~r2D;yMeLf;3n=r55Ek zcJ|~d8$IpKG zyKlUuoR>Fu;mm>O6=juF4O>2P$PML@ilN`RJnN##7xgL1%MW{sd-Pv2dD5B*&v4sX z9RFN&aXmnpN`$|N(dwMr+O{sg)j93oGU$%MBahE1Wi8~cSRD)v*$OFMpGQ$CBjB#^ zdmsy`DgHnq6)L_H#1oGto_LkGVGeQ+nr>WeG@SiqR9s!qFo*^ZjdTd^5Zv9}9fG^N zyL$+3!QI{6J-BOd3+@h$Go9z1?|yUd+#j=Mtv>tgT~)jM^pEa+s<5^=Sbu!)ShQeu z!+t^3wexQV2@xhuP`5yj>@zM(PO>la6vRqx8at+mQL1&VDmAcSF}j6uB^KRnveHOd zlk_y1O%mW85S%M-vi#=Ls+9nGhLn+vB%6S{!SDuRosski5`#p-1gBuwQl?JZjRp_Q zbCA>%F?rj`XY3ES9ar!pm}>5)c(g9MYORs2|IDZn?l7d&aM+jNWgo~-pHb!iMcll2 z)THG}Tx|GOiI(vfvF7WPq!1j2=(}PpqPb4`-_O|Cw!3pt@s+X!f(IkBmc@7}W+8if zx@**fvMZjZ&C!x9^JkX4-fk4iw)E%A`?L9?0DP6L0qtetV3 zcerpEzU{P8XeR2_@EtEK#@)F0=3n?;h}cb@yA)nD$1G&q-;8LIxAAIB(T>iRYRg}= zN|@#3YBZQT$P>6}WtHn}sw&$OipP#+7QiU^`VlhZABsFP-Ys;t?Xd*44M0uP>n4lH z3rTwGiffjwFU7C;wf@rT*y~-$i2@YbNWtr|nN8^Ww(xeE9wilc(R~Fq+H~KZ5gVUe zbjzs_`s0$N_p^9XD#jj79#;6+<DD8WYZ`fCygzm z@mga~H1fm{H5J>jLu7yslu;z@ zeuD#E{Ep8~3`DT8A5KnoKb2C{dEJ~+xuCySQD&I_j zqFM^aojBcC@>HXy8LT>?-ete_z95{p0s(oaXSk=QEi>vy8#456I_2Pa{fmIS!^fp1 zH1WHm`G^W!*Hi-qln0I-MtM=$^d|BOhY1Fqa1!P#(QSViT4>|WusIo)e z+B&H^$L=-&dq}k{M)okO&9;ljyG*hT1LsoC9ejlVMWgdL2T$I;I(FWpkm0KMo$@>C zO<@*{$Tr+Z5;y6K1}60&nO1{{wt{cPXvMGl923bo2PQ4DmTB<`;CHO39yBLxo#FdV zP^UTm2JbuomLBwXva!vVgjz%MUn^ZV{qgC;O;lf9y-!uOEXO0p4`aL3*3Blxujzl- zZa4n2#<{es<(kA<8Xw*AsbLHHeWFp;2ZYi70$BJps=A3!WP9wC{%P~zfqG!ekjv_L57GL**)FyiG+yIrx#)P?IY)ca zWOue2Z#5})5usX7g_Yo@@LhETK}cuz%>X+`onZ15iCXy9LMXP%w)r`q$p6H^etUbf z*U$4TuB%C+K45VJrPP z(l!zewBS<1Q+e3lAVMF_$~Tx5ZxsTGrZykN%fdk>(3C12MQg<<`4aiEbo5xf_xiUvJ$g+aW#qN*BRRpY}BEb?s*+4)}qj^yI84b_nG z^XpUta|NOi1S|;~H^tAwr?tzpu>x$*Ml*~B;*4nJ4%n9TDRB`_^w&kjPd;Vju*c{G zEJ%Hx<4GHtzrIKPGJ6i%RLP0b`}{_k(>-=BGcs+S>@nAk_=v_YUDsFgoSsBsoP9(Y z%e>VP1?mWMWCE4uG7GfQj;u)!4=O>@o3>}JDa}IiJyqVAK8|ZDAy0K*9VJp}{xZIv zrkhQyRJL!a&nV9Ad`IZ0idqmv3Yv^UiH>Uz*Y;7gSK%cT_*pkaEFFEhCcN>cxUef? zyH!+5IJ?{+pH1IvpU?+)(VwTh5jI5Ngk6O#&^QY2zeD_zNx}c!U`s6u^2(+W`XxQ; z;&p(WTjH#CbK&8t*&&TthtbcXfudaO7|)v~#h14a98;?kocQ5z8$iotU){lW>+>i} zu6$y*0%(_9vw7sNY#V|sopKUN)%3YXyV~jX-2+?K)LMI;>$tOmyC16Dok(bq_kb#0 zh5j0i8NR?oj$BfzwG5RaMt*aoV&-bJaHMrHqF9W>i8Jg$(0vk1jN9hiy!l1yq zH>cjin#y0DbU=rxjRPRn`)`}m(vI1cKMAiOOHdlHkpF0Ff3@h6S?{*vtuE>WkL^qz zv=8k?by!TRej&|7BZAuKRlsj*bn-T4HGPt3o4@j6HI}`g53{KTZ1q2X@!b|t7%3~D z(gVP}Y4VSR-r(Yu+1#9x`s`hQ*3G^h$W&D{wAaWiIxRPB--xL0@Z`WEwGY$hAG`#? zC=tN}^dnA?JY0INydfFp$L&xkiQRGHw9&g$d?RWGDvCY3%7@R@RP&5QkMHBnRV3k& zZt3nZyk1j|E{d3dUVm+wd>c23rW*tVl5td1B7Q55oEi3!^)&XVQSq4FjRyjuBm|Po z_nXuap70Gbj!TyH5i1^E)YIcvs%Snh1>iIc9aPbkX+Hg-x>+uJwX!!fYXa1El_|Rl zUJS|Cr~!CXJB&SThY=UYHIcaBrq%9F`Iy^6FZ)?8t-&h&SNwI5$shJ$145wzz}6-{h-|7kUB{oCb8FN*XGQR2Ns>xd?u# z_n0Yk5k#wMQTuaUQ`hK?hqA#F)$q$0fVh?0F<87%)0nmr4%C$wI&J(V6=wVEehH+1 zy%o1Do~W)I@#LVewwHGc2wyNCwWD`$5QuGo?8NL~u4(7B?es5@h<-Ane6sKaWkYmh z>A6$(r=U~IP~9d!d3k%kcop$~k);AAg@&3fgr4-@A2*0J^f%1g&(z#+eCcF5AG*`_ z*+SR^pAqP!wrx5rOFV>{hH)=^8@xSiWbmO2teM;Kgh4(v`>A~6#P%Wh0q8lIwu|g8 zvPWn-uRY%dc|%#O5hI(G1ox8>E8x)jG2mRrqbX=fM^H>;tSY(qecFe)5jEYM;*DFP zwaU3CVKB0sG_s*BVn;&=x6I2TMzKnwsmpQq0@Wx6(b5+KwhyfJEUt~jFDrUT_PK=6B z<3_JC#?Tr*WOVxoQ`#Y<3b!@ZdhM$6E$0jNEmwYOZNEFo^)-;;0~S4^$z~{^4$Mb5 zq&0o3k6lNyjx2fYTFn1#YU$gth&YLu+^(cm^E%jp9vl||Y;K%7)nE4=eax;(5x}Qp zn94exUK-OTXf=C^w;o*It+B)Vu0PzV6QkxR;K8NpX;?Am_9MGVl5~OAE#q6Eisp-= zer%iJ_h8)WBLfUMe3MBM=?=%|->pV={uYxoV{ zwC)KXbUsFRKn+qKQ;f^7O{UJ81h_XnwLTRaIaF<6NM2ISXt#P6xGR=wp&YjJ{l4>% zMho23p?vK^atyD4qybm)Q?1Ay^knxw-krjnK4cMR1&9k>H7cQ$? zI4(mf%PDFveAJ$3QNm0xFUz+fHAR~&;VdInh|jn2H*ln|>(*GYt5N|p*8X(});Ykl zFvM4r+wNaYPX_K+Lwb9lNWK;M#ury93mXcoX;QIif-Ls4M?K-!7@8gFoz%1>%os{j zaMjza{c1+1(+m<~oA=c^CZpDGH5P5gDx0U&MoTd)1?9!Pp@wC`y{NoUatiXWy1ZSa z88Bn%(wDiVvu1C8zv3QH=ByW_Kl3d$$-c$B5WgP`q3kJ1`YCMYqLqgSyQF+)RX~!F zOfUB0Wy7*J<-lh9;#%KQ#&(wus$yuBv;Qm5ferLY*EIFD>Q0Cz@lFCgP+xX;tG`Qr z&w2(jjoxc_k|g+HW^|H!8#i+r;lW3OqCx#TNW0Os%a&(|k4fyv};*sV4H$sCx4miK;uXS*#Waiz{ zFk81R4f)DXQAPgeuqv<=b9~}B%`4g{(|GZ7u$9WaU0&E(C5(cWmTWfZ?yb~bN>Wj{ zRmno*f)5Vo-(9Xnkh8{%C;}#}MlNlw{}>usR~TjuXmr7~K>3HJlsEC}{!X>8SNRwa zKjC3qU%=0L@@OiEg&}*!PFNmEQ2>KPx5HHajh|iVV8Q&r+)|h+iPdq06Aj}f%Ga=N zd>I`hTHIKpl4UV?kZ*|3&@sVLSwqKG2OooFGR-o7sSE6i{;^%ThUwd@sqU;6be9=(x1mwXnqnd!93r+ilDZ98FbQ zvfFX9&VH_Q%ATkgtee}yA;dCDxXvf$=ScFNl#r_%=^RDdok%PGQf%}M?hG1p1e#{s zJ$O}#A|d7c?Hb8;!k}dAIU+ubz$qeYoR0}!Mjl-|8)TEOsukxI<&zjmsZQqeTIEh& zQ|U;)Ej^g|^ipGMyU||Nbiev`Tk?7~7X;e!-=51U8^*ZM|I8s~qkXp)j45lI>GjbU z1PUU0JD-;Ks!#P+eQA*Qfjq>Gqj~Am6|w8|PwzQEU|Ax4uX@R?M3`R^2W@!S7?1Bm zFn86q|J9EpaA13GiYdH>aGXnFIwZ$Bq3Uz?%aEG%37CJh&Y{p6Bm%`2y( zHb+{Qoy@r46Ja?$BmAff^!A^@$HRCZhPZ@c>-8WScI)`k3SDZ<^J;fk>oN4_6;BFt zmXt;KR(E%o&ST5BTHONU>hr{DBk+i-E4}*X8`ICVGL(BmfzQr4-PvmWZ-(nVh<337 z@;~1cQz=Mv+}F<7FA8mn1CT*e9#iLTUgHaxr7g{r?{I}h1k-rnnmq1Nu=t2k0Xd9E zpA3p_02{@fU-d&@a$Q(9d*U|&1KIH-4%dIYG<{Y_e3@iCBqHE0B|L&oj5Pn81;Gc@ z3cpjRokQvrR(D8WoBR2==E#k$h9^M^dHKrqowR(H@JBo9PI6R60;BA?5K^vlppHS* zvW&VF=C2>GUcL9kWrz+0hx6XOo~wvB@Et!q7TcOvqq10$1ncv;66yf*5RxRosWanBPxXez zBg9kr2F|1Z9&q!;F@e{*=r4+9wpy0wf*(dtNy0ngWYcVT&ggxxCx+w79&g4e+HI5w zng4W>&j*J*#jOgi*v3469x)!ACS0F3^1fFnr?YRXLR7(;AR#p2)&%ePwKL@*!fpBl z>H>VmB57e$M` z&-yQdM_aU<8L|^)`D-OBzR)mKY<*p1!m;$H;7Ko5% zs>HcuAgt&(Xxv&J~0KHrx3A1{gM?3evhw3L#wLGyahzYtb^eoxpHD8lm!8}?( zdoX9bz}n@Qegv@NwEo#ydaPrAUzdvw+Pt_j|C%!;x1(UstWU1I(vs`zenPcVHzp;} z61zU+h&y_Y*TNF>VUqsk-P?%oF?H>47wc&CQZRc6NsNEvDgUZrBIu`w4k4bu($-gh zX{5oNxe9}K{Ot&Va2Nfp#S;0bmen^)^Ad)pb*jN*30=M;=?*?`*=CNMd7!BPx8Bfn zm3^UU^)97*V<2<4^*MLgt7zw;)qLC`a1LKmqPhL+J<3I|$rP$4hN$K`gF{Z~`{$<# z-`OmehG*{)1iWTA7*l^m8PqSJjX5M=YGpTPxm?$03YDU05$%phGY3saZccukhXb}f zmibwEyxfMSlD`yLyjLx12SQQVi9UUXhr)%zdRQrO5ZUIy z&7YpBw~*5d^T*$)6nuoOb#^TvPi6|lq4**KDf9GrgUxwk9CkVBKc|qqoD$9smg=|U z*|sCuB1^sJpb1pl33`EhQy`ZjjT9gy?pp~GOeI+omTKCbNmmP;cu|`Y%=-UyOWhAA zoCP%ka0;i3c>cPTAe@tKdh@KS<-WT~Z0H7Gp>%AJcY33*bJ@_1Gt-hd_%a!xE#em9 z2{I$omTbSB4BwSwTWi{9)y7p&Jy|L35aO13VLLfdzx#DkV!2A-C23vEvs@iqreiDm+#=X) z0^+b>?TFm!?M^4RWc%!ot6L;jAa+82wdr?b(eQoo^IN@^1qbI11Xaf1DKAsktL|Z$^#0;2|1At zXA<6FR=*T3KapYB;*(qyBK2xrvuD-lNpess47wBP!%-Mo;}FsvH5X+~B}W(J4e^_7MYpX~VOpt9`uc-kIkOx7 z(N$q&Si=Y>>*mwsBj%MnWHfWrONc*@-3R^m?(qOBX8#ZIV+^2TxfA0%@{z|r5zK;h zZ_uYR^F9K%n|UgV)-9TigfU>JaOUCY#puJH6JLU^O|fOT!((nV;YFSwVim@Fph-tt z#xv7hio<15!ue`~c`xZnKL3a#BrrM4W=TR3TLg`ynhOus71^SpCy*V|poh6LHiWVD zf_VTVYAK-krOV^PUF2uu{9XOt&My~mv;*LJ>ejYx%(!;i=e5Oeo!m69*XrRh z_%Q5Re`9Ol4tihRKfOI&y9?=m(nb347ivY%?Ww(Jkqvs&+V)%)2=pajL^-$&Dh_gk z`7QYQ@1=1quhSgooq)Uo-}|FFl}YmWm+8-^oq{Q(vBdADCy9sH7B?FGR39v}&{;xX zn{FVCiv@%)tYz_DeCDx+^C+hmMJ;xB=zdXk(MmMXj^8vS653J^+bhKkdWX;9jn%V^ z*U<7byaJv}7qDARe1@($^@qkUIKHl_?NjnWLI>z%Oav-a4V&1K>8B>vg>1@f=`Z()QNvtre1a zx|{f<=pD~SIgkCAFS)=!SnW3wmu>oLUo8uJH|svQ@BGqHzA7 zK0x01^AZXYqW8er$xPOijlEK-_Px^v_%+-s&tUriU80>RPFr^AYPX=h1=ncaH zsbop|wF@p=q7B>EVqkW@FMFz;m}KlZ-lL%^C!^Xw#?JxrS%d?G?{VqDMZv0W%y)5k zC&CsCyUM-CDv>hrOm$InXNUI7D@v5_2F|6KJq;GJDV6}sFwg-vgE$-IUMZ$?MZgyDoC5u`Z9%;4Et_~1dZ7;0(U18{vZX2W z_EaM&cC)uUc;X_+yv@IjcFmd9Ge5ZNa#1uI;C<{*L{Q>wr^vjmcZYP18;95$`-pMP zsmqT^0d+CB^(8iLG~i`q&m-6OH)r#`X_Qdn!ou= z2Vw6c$NQ&%Iwzk1q()Ci0;n43H<|!PS07m(E%%@U%~Qrq(7+{3`={M1cgN+$!%BCV z$^7D00nYOOuR8A*3?B*+ks9av6i34k=8>x%%neBI?QtIzl~7r?)z-&oPTL+ zOrc!6CzhM9&JR3M8yOUt+1$Z*(u18oaLX`7c173yJklo3MKRz^u{19|jX~7|y-gwa z!m{)7>3ksdoP9}D>5Cpmd*8e7-D&LHef8x`^g&Xi@&_XL&&q}weX%=BmGk!S5N>1b zH)*Gi&R+;NR@KGhQPmFm3X10niHCadZFYpw;@S6(n;Y!z_TO>Vb87Es;y(gvXaW#S zGEwwL3~`1QEvMQcmeBS_5wUaPoTiQ~=NQE)mQe0C`b*axL>|fu*VZ)~)jqx+&k&cW zjd(t3x^222K2hvCaj!MSOJ~(}_+dTqCi5ciKXFPBep)$KJO@xQgzR-DR{<>wrdT|> zs{${!o4$@ZMUzN0jiNQjXB$=CbNe{2x z0#j@}7nh~_kTYaYePG1Fl{;2axsJobqo)GBixkNmL$=d&|&%(3OTd zW(T3dx2J>XMjRzs73G_jls3G++U9hazhnD|KQo-nv?AZ8mn%@DNyU;bgm*``I;zcn)b_TypFa9m~#8t2`(Np z(;RY2e$^X}HNAZgUGgI)`={Xq4@z^Uzt)jE37&y?Jjw?gl%t*<@%yi61)ECaQozt$ zz(bJ9zz4D8$-OJoJ>hOwfM+s{aSII9hd>`M-YD5-rVD zmeeBQKRx5sLM$8a>cO5!BiE=Zng7T!8@rFNHI&~8;$dPpU3T++i>?-_XQ{9B>b3T# z{r*;VGn{I9oug>BpPq?3=F*ApvbsyKK|b+m z$92(zyBqnf5aB(jdXQD46XPTNRJ;*BXHegjE{OKiwl0m$S##ZD{M!!hx$CcX9bjj6 zwmkGuGYsNG5Qq+vpk?1S*%(vH;;mtSlYpV*T=gT|1+T=Wt(%p6c&VUi1#5n~*ybK} zJ+!m;R_=ssA?F3LiNl0O&)K=FOE1|Kcp0d5MXWDgp+L4^uczOCYW1m&Jaqin^bX?e z!xVcHdn-leZBD0gx2Ggb=OxJ7Ne-CZXPu=%uf&w^5Dlpx6}ZK8tzS_g6uSCI;efuw zlWi7>?vl)nu>05dm;2n`?oX*eXN*$9QaA$G>Y|3C7jPXdrbjpxqzC=LcE)D+zH=H} zca7~Ar_Qb;cn{??oZP}0)cVyfN){CmPzi5tsf3NRo6VH z=*vBwhmVdeFOI&_L3|AswFIzggYK=*!|s%X%F*oMKPZ(6XAn%^+WGtpxK5BhwW0e% zKk$9?)D2)!uv1=Auxvi%5--Rb$_=Sh$B8D&7bE?>ES3yZ$a;^}LHr)Ya>~U$sWvg?VPtp^eqXS)7 zPOc3MO1mz+li37dvC&)=8Wzivtz(tD$%e17%F)}<51+q>Hs{HK#uAqrne12UiGB>_ zp!EE8wCw~=tA@>X>dAz3E#ssNY3jd;1h^&xDJBFqh97(QddT7r^5i-6U5cBq&9y2V zqvYwwGA(mSp1O#86u|x_ybWSAbJZ+QG zf3$aD8P6E1*qn-LDrf~fR0wv6oZQ(rWlI<~%0ba?_`F(s=L9X3)Z4}EE3wI31dY^z z*sg9v*PgZ8?DORm))Iyswa0DC&saQcIfg7P?9Ck3zPTv_ubckBQo)git$iy?!3*F- z{-u&GhS?#9Eoe6jW!bj$<0SSn*;c9ik6GEzLpEpckoP64nwvj(6>nc(s@Nqv;RKLl zApQTg;SeZ{GqKf#dT2e!4OhA;H3wIQ{?xpXs2fu7s}AY}9?0Ir(`nmD=1+6o$vWlX zn+4$?n0!2}BR$90o+aq#O?5W6*shB$h*U?vC*ai}4*Dhwt?v6sY|)Ryo0?3X(~Ryy zW>5dEcOAM*-mG->hs-h)dYI3Q^$*cG5bE&`^nqLDIGM7JH}U`Q`Th976rv+ipFxmfohJ0R8S_0v>n-F=L=W--q6hXJ z7O(M6h0gwZlXxnn`FaLNPhh5f;~x3u)YK^h^Lul5f4uqvtk#H^BkU!O!AO@f@?wFW zBTskOJ;%)w89bZ<@b0eAX9KwoYnj-6>Wi1ZaFpZ+Nt`#eB4E{FtBMjsG9<4euFF#t z`zi%0-I-6(?oyeA&{qU{9WQuGI8k|4Bj4z5hs>Xhnno;HA@s53M=7M|AN1)e(ao$b zblRV_eD5LhE|M9Ts0_@f$|GInHIU0hF9D3+u{iQdSp1)*s~)zwdc=D0Ii3<9CLi-5-fv!Td4_t`1rfRy`zX*=LwPND^+x zDc)#8G+X~^)=2^GosRa^Z2gXLcCtoGgQ*4z|EO2W$YxYn@M1VX98m2T}!S_$L)DweK+_Jp!pPR`d%{brbimc-=L<>`L=udIyR%z*5 z3mjjq)gswL=PF*`rj-gjw2C^#9kYNo&~A`8a>@wX1ih}T=wrD!aUDi^xm{`88};~dI|3f0`4YU<3|n0LBh@69*WrNf~v zvobijRy{w-$ulF0!w!4=(@MRQvZsy~F{8zng#(dy(kvs3WJ^z9rPZMPM^Z7kd}8MH;1>pcld51-OIj~!W2VT2W0i4^nSVA!TEB@*fK(sVGTjN*~doY z7i;oHpx)zwTii0Z7Pe}i@vNe5n-UTsz4nEw4k@jznK)7L53S$)ovOKm3Y9bt-hHN) zxGoJ&-9gsdL*1h5e__dIdXx=EO)wpBNH5XccOecEULb=M07BGirMu@^G>~Fj-qptg?~>g za+?dj(=qqnoNHnD>0@m79H$+S&Gq;Po;Rb~Y@1A>Vd&gd=bS^_T&=uiY8fl7Do!#D z5}S0tN>QG$<%lv4ATcC$?kdv>xjtVg+?K0P3x8Y*=YbMQKotjr3aLn1Bz*3BC97x> zf1TNEnWY9$3RbGVO+cM{=Jq-7{yI{AWLAFrN!|k0ZRZ*GOG+~quNVT|^a_kDxMg8k z)7i#URr;2HsRs&#z9>_t#e%%IfEJ$r}YyEys) zf+*qGh+qajAid9Qu;sqT_v6)`uuU*1RHwG8TE|$!^g7ajz z`Dh2? zveq$#5vmS^sm0?!zMEvbU{*`y&)s9URNo8Gm1i8R5GzOq!rCFm!iIEHX2WC(qV*Ti z*=Vwv5^!|Ipc02>KI1UC3GQ;ClcYyKibeZUi?iYsFl4t%DPEL^S{JldY39|TW+ZX) zY{ai&ar^JMDJ5>xxgRjo_3TeQdyS2?HnUf-FED8Ed2CbB&!1cWrbuXzXFTNCfcU*(#{65~Fdn$nc zKGu>pVLq5r1cZE!2~toe(>XS?livoR{Iasw%KQYyw@>`yJzw0$w9-4E=Ejs0l@zy* z=x}C^pdJ@B-=ve9x}8huOxX#Sui0tkHBqGDS+~n|ap% zNtlVD-;ZslOM{Vh5$YX;W1NDh)0k=@YMj!J65V7>F1K!i<&ZTcWyQPXC?kcvfVXAJ zput^nEoH#Kj8nSXW{}dbN)k|DWss2?Wz{vVcAGuhTsX7!URfBP$rn0;XYQ{AU>}c>TYiy8ps$Y6s2> ztN)4e|2+r)FM04^UdS8Tg0u7gH|@l249%SZtpAfb!ov0*U=eie?5qGf7G_oe^FQsu zCa{4OVGwdQ{+DSS;0QDPWBzYJ#|#b}gOrP*jis@WowWV~0FO*lrE$9;#xI>OG(I*!l*?aG^(sZ>19`xt2dJp7!sLj$DCg}< zYqtzmDZ0SajkK(!P?IhG=0)i2&L=6?FOLS54~z;DH31+8#$;2jCGlYWpZ09h!|{|C z$y~k5tA<8${RyDu%pm>8ji79=R`bz{rR`|GtBz@3OhR#PkLUkPa7YFCPs1ONnJ8| zB90-aCY{^O8jCD7T*R@!pef*n?kJuA6-Njtr9YP;dys;&gLM1HhB=@?VgA(3!0`3}aVk|Wz>%cF{J1**N0I4n>24N1@(iw#N6Z_JzXImdp=`%7x^zAV{9 zp*IUyt;v##<4cWUE;GZ~GslNGG=?qgSMJAxc6^#kLESQrq&eZr11YcM&HUISIQ9s+ zeSW_-Rtffz`2|i_frCt0T?-=qAWO7AGi)w&oNkzZuDy%y`zV68P=jP86QeaTzXL0K z0G(dh?}M4Nfkh3-l>)efQkP;1L8EXk_!*_Nw#uG=D;=a9X^aE`y=7poun zKL6@2zD$dDHRRJo$r!6PiClp?`@}P%XTor6#UHrUpOez5gg&%MpP=&%m~c4G07tdV z*UGPf=_Axsc7MWjkI)3a?h%Jezl1n5cT@^aD0T^M z3l?s)JykrjPFi{8_iEK@Wdi27QR`KSdro{;4a-PE{^W~d^=0Ebf;Fnat1cU?twB3O zcB*VMY4_R`MAJKUy#Xj2#@K{z!^q`t5lI)uTXQXUUs9ejCMYhA){amz3-5i%^=a2u zES~t=!s&kLCzJW5yWKDhat>j6Vv1{v4w%*HNy-&y-T?_jrf<%dgWK+)-})^MGHNez zse(Wyb~XXaxPCEH+b*1%OuB*2a|0J_wA=0tMRO&*KfuMs{B!PEX>-fO;i^oKe8TQ% zd7=|QpZAKQ99sXsxQqZDG5Q0VQ2SeA=>}Wv}p?gR)eBw>71LzT!COnL`(e zs1EcseaBgF$eNZ6&s*@(bqTVPMZ3J4pFN|4?O1jbK|u#NqPxpWoJv3krJQdIQ(sld< zGWN0M<^o!5hp$sd;lNK1bsZa7m&AF)7BO)RIt-5Jo)nOmeunkXsF^ef{CbPb>yuw~B)_K3|dB`+p!`?;#g=-Y2m zC7;ojH)zB)enWTgJX~N>XDB9Xt!R|Mr%)y}LzlcuPK5p1NoE9qpz3n@z1Lg&7rlr~ zii#>}MH6DtJ>K0Ypwk!9EobrPvsFKIlrK~Sdz5*I26ENyf+@akNB67{sDA#q<}@?8_+2+J2)ldcSy-)O6*;;>NeK3z8%kE>Ms^ z1Iq}%8MwI{m@)&Befy?OUd*~= zNmbP*nG|hdMuEz5gB*Yb&6~iRDiw^0a7<6H+&;f5wK0n*kc8L;nNWws0(sEQW{uA$ z+IB?9Sjf|v-L!?$yy5*287V{lQ#$H6=2DV0*nt%R>!klUU>fsiS#czI4ih(=>tXI@ zqrL%y?Z)R4FBA^?tiTZcNNt4#j#ohnrK7!iRsl5*egU~==9VBmRYl<)Pv10PDJ;F< zZ~C%gelfew{Cd|A!u5v2Z{0|wROWR5^O)A7xnn*^+6!QL$05LJR)(4uR9^ z`E*HIMtaPDrA(2J!OL<_xMhYFiq8l0&|5FD$HEK6noL$>YTGnLy-L@*t+bl(ZfdpZ ztux!t+ImsmLdBZGix2s7Rm2BwtIkc{QqDsH_fP+6JmlM=x)I8}CQy>5gx^)K*~}v= zrwUtB)o}!Z!fkRN{XX-$o6VQ{bnd&lVU7`?Cm*qimW6A! zMD?Z-l?FVM9$^f0E|s(S!>-kt(U$e=!f9+(jgf&OXZnh2c|$4~DrtZ*1C#g6c~Z?S zY*$|m;%tZ8n+wKz0rkBym;MC|VLLA01tC9qMv?Yh)n?dTC4mhQ%RwqYu0XlCXhgSx zTWddaB1&>p{`kBrjh~8pZjOv;{&2irbV!3X&e75i(>XfKje;6Gnci;nq`Y>xu2uX& z!T$v>mWgER!cqYp`4W!-RDS+8Ra(8UIqT=H+Fh?vPP!m~u7-13>?dZvpA1yvOWNf^1)4q2o6XOV!ZTI}R!X?)k6Gw_VSLrm_ zJV*@M=;69sc#Zg(eZGUd$}ow=cTc!T&iZP7G_vB}>9&PQMf=}$R!9p)Vw|*- zpgCSE0l;z7%&e9{&%`LV2S7cS&AM9hdY5eNwZNYsHsowqpNfVn8x=$OdrOIVOK?vu zUzJH6Vmq;-eb?|vRc7cKVc9q(H^-5b~40VY_Bqj(0z&bpKp@wF%>`T;De>(*$Q?Chd_rqocbGyC~B`PaH9>DO>IS4F6hV~P6{9K(vNjqa*6_){I)j~g|7 zQ9fCYYM$59`PVzsiv~}^p!ysWBY%Dhn=;nJKn>kT7=>W5(Q#UL+^V8z&endtOB{R& zVmJdFnCUV(tnA^wGq-^zu-`uPKHe)7YB$$nuCfL0jbo>(@l`txOVBwUG(hc~n(6_B zU3I7MiP924MZlv0tjIcn&JMIXHMDwETG{E&64}T#dkBiD;Ur zwzM=URRq`hXyQRY*1^wh8?3L)xKtEmW?UR%wvjuEiuJ?zd96g)iqWs+{z_59iGSrD zmfz?V)a!Z9oX;+Ul)L7by^eSO&hLwu$CBd-gV^D^}BT6VLeXUY}0m?P+-XeZ{_=J#t`X?5wack?Ro#lFw-56_;oof%uy#Nx?y z7wN03PiGB(&25eaRCO&lDv_iEBou{_2P5TXSf4b{qKi)u4NbdO4?N}y;j8Ey_*2HQ z4(A3Mb8~}VG4`a`tL>FsqGU!K{Zu4lyz%zRj3si)EtMdioI)F zrI<=aP9_V)Maa%~#yY09GGtuI#A#UVF}1tf)!xJ^A?iVb&lDFIW6`4cH!bQL%cv21 zLFc!*&e=XZWM_F3$GxUF2Jx|&k-WHF5_5^MxVUJaHUXa5i8e0&?jIA1vZ>2DUl-#- z<~&jzs1+DloJ4!&gL9Iei}I9&pr4UG)5&uJ)3QY{y=;Oj%`SS2~2US^N0w z&z}dGWnIH$!QEg8H5)Op_L!<{i9gP_8rh^1v1Y!Vvw8hSDurJc_j`X+0i)i=<+4@b z)F?m(0&3 zQOvo=+h7n3>dIo5e@;0_RS> z*q#>25@G6J<3hLeJvlFB)vF|zl^ivNvPLf{vtr(ji`z9gJ>6Jzeh*oznxD96dFiI) zM%^3D$$#M91_3C^goaLq>`QX+d{F;`H(2aYs&b)a3zOFKve)}&Kx%A&i7*LHI~sfX9fu3(Pyv|A8CHNpB-cHXJk4Q3=zlQgyHB^-tuCV_H- z^#7pk9)m>p+6B?KZSJ;h+qSLUwr$(J+qUi9wr$(CG5vqvI`__;IWu?W!~Kw|WTleI zT1hIYG`XkR>t^j`kS1wc{l0gC8+{ z98o&#D{v?ijDSq;9+=TSvu@T@b`zc#hEzO zt}3;nE-QH6yIv{7dh9E;mg&3TY0&vujw28Qy=vORkTLVOYh}TdusK@9LNSLH>wo0V zri^r*vhU6VBOTwjp5U0^<<#9B_s)Q^48RksJ*jNdGwscm4j!RBb=Mm+w|N*!v~u>h zK??9e{_Fxr0X$nBZf*SZ8J(G;p|X3gbb)_uaBNc)l?(_)31t+EPkb%IP||$ytUXKTL0>YU zb&8|knvDVS#?WTk1?{tX-kao|ItXm>aebKB4mh^yJX%cyXPvxaur)BR^t@LoSem{Z zvM~XjzU2Mh=-p9juW>WDr*S=4pl-LCOO??I-F_vEiSi(27rKgl0xl(km_2#c6(77^t9z+`vaR~(0ukvL_+m^MpMAlbydUJ>kW()L>Q)ntJl+KBmJCEjhhOiJb@_L&=02qKuT zVc43mh-8U|O6zq7r#J!-dTC2NzJ6HUm!YOtv$$?iO5aoBQ|u_!~vykl(b++fw%g_2%!c)y7q7 zETVlv*YudtoKZfBA((6mSJT%HKCQm5F_erfDOH=6P*^HKNXsy97ajXmM8+5EnCdX` zyf*B(8EwShJ#yuF9P;|d_T>-vBnp3p<_)KD4Mb>w<}4=Jrve$dgh4=2{vavJv7$4} z8)a4}*Xv+b+2YNKClSn_y~|i?VlVBX95Dv5d!gt=9GUGw*o@=aFNb~P0Xw$E^69FR zn07Q-DTHp8)qqWdjR*7M1vrxV>uEeZ0$Pf3bzF%)K7z?hw8lez425gq!>A)RAZEHDt#kSwnA2tEm`7ab@oQI<|< zo7)rRQ$*KEA#Kh^^m>Q0tnP=_)cYAjs%=bAa`&O?-|!iJ#8@Gc<*>PvZ^lo}PY*-J zaLm)5O4`S;e*p>}4Ra;&RpXuh?dsiDWy`7-b=cAvVdH)3?oj8y-Ci!eY4KzmaqpiC$6!&Np$P<>2*wn{vSU*JZc$ zboDYNXM!%r&dPazEXk_ac|_&Y!sFQKqLq3#Vf9n(g3rlPcrx>jR)-PkzM?Ir!{fx- za42e)aFgy;CS)^F-0}kle63^+eN}DUwqX;ua~#{uwQ;j#7R^99AB0OpqahP<2&BcR zDaW-BZh;F;7{^2);z$CP0repJce|Av9W+U&QY|<=*9>eE3vaJ zLac4M_jdLd+6RIf&ypo2C72!*4q4DcA=MgZyE9GL6WW0Yy109U+MFS}OR@L0RL#RN zY4t{GN8Qfg?&IZo^4~cww9OAT)0PRvYbahr9wut|YV~cW-?EuxsOJ^I+B6AFzk>t5 zf+34R?$OSL#)OjP4EQ3{CP*7z=@8ilY!#Z-pCq3#WN@fKZzB^$l0gxn_oFqahZRn+ zcM=Ve_w=#%kqq{JL)Q$t43j|Yo6!%ZI_P7|O#G&gry!WJ5)3jBtIa^LWgs>gB1wgT zQxnOg_k4PZ*aJBd|CLV9tM3w!32@y)07<5;KH-9xtqsg&{?cQ&g@5=f0(K*Ahp`nV zJozd%bYUC8-V8kFQMG41}X5(eB`-UQ5Xme&ZL*PQ5^eY2g6LGPaxT@+=#h^ra_V&YUs_Wl8CE z59%SP=6%C zvbj&{y$=T#p{EjB@v`wANRU`acEZ8LZ{^1p<#UB!CA?J`oeH1Ry#p>fGRbZs@M5UA822tCCq2YZf;aE`DmsiBDXxLu>I1h_ir&3s?no`X9)lpw z#ixIYZMUeiFtuqfbnRL@u(_l2em>Ij*#A}a4dSzD8vGqoD@r)fN(qy;t%f~tyiivB&Hea3Ilqc1Z z^O!n-?2{pDDps)M%Ze6z5XwGcP73?(Pch-76DPDFVr3$F6^-Hvk>#@uXqkqN=fWa< zq-%W(o;4=ZZL`E+ZkWg+i|bI`yNiw(+Qi&Dl(JHHp7lU&Yh_{RSPsnNaI`iaR*Bukqni&kOd9slOqlLY@=#7OJ2M_(p!mB5o_lhk9BP4@ZghYj;a5jyLp< zwpEV!2H>bu)C1f4xPs~hcM0*i5=fGM$ZLkmpK3<7vLJ)pbofNkMVckA3vcfAS9i^l z53kG+&lE(qKUw}aLa)?;WqcR-{R-uuwV+0bIi^?M^ijhT#4fo`?DOsF8Z3nKq4bR9 zpx4l&2g?)3j(igOqr2o*`WC&sW>h#S_X)^1*BF6j)|2VIolJfxX@m z%F5eH?zC!#cn`j#S3iBeH-hb`S7p*|3BFPy%|wMP9B(7 z%;@)RxQl)sbn|-pG+ME5*)?z8eBr`tuz?i}eO}0|9TY1y))~p0Pjq|2nQxgLXP2ln z0Ksp~sBZNe?F%j{+c%VFj2KpAKa|AjCHkDookfC+bG5i@Hv1YD0uF3X|GAa84OXEE z0vMSo!5O#i&}{G+ATqy}-UclHFL8JdpsK8C!puN$&$Seh&0rDm~E|*^u=n|CHu(K&e)GGY>DV|gRn zTM=8NxgA5*^w>poEIwVLuKrU=di!N}mNzm_ zhu>^FHCRt`%7uJv9mVD9(=vO~c zV0Ducaz{NIOLlE;^n8)#;(cO5CGMBP3G`F@^vPK7g$9dX7X>n+9TZw=g;f7V%e zKDbqar=GU`GW;b<$9uT>dj9H=I$;cXEV3t(V&vqXDsrWpRra~*$wxE9Ce&WhWmuoF zKSsv!Tp~3W1;~|t6IzME{xzC=SaoF9oM)R>Xf_dJVAJP|<|-ZiB_>&V&0!DM#KfK= zImkPrbc*&$`p8tdk2eQ+gLQak)+Sp)M42#EF+GlqsMA9#$!5uER^K7QLz5M95#F`G zpb?UCDr+d0zTw3;3#ObH{)&ZHAZJuLYnNkk&ldbxx8gZ(@#uJnQ~7QGCe9niI{Fa4 zi&2Mmlbg|8ELnBUbJnz{EBV(${ws5O!CU6LhQmDFJ4??d>WVA?NB;HPfn6QDS;+7O2kH`+`@jy>=J)K0f5HfyvribEgV>E*gd|aj645v+!M% zHP-@zQ|zhuC?~$h`M53Gq$u+5Y*L8VC2x$)9EGxI*$;eF zp%fUlOaIEKBJWa4Qbk*^t670a{%*)T32-hb4<0kJh1f*w2h=%WcU&DYVxGV@UxR6r zQ7Q@zS~b38P9fUN+Iu<$j`#QwNf(Q_9RF&YLgx`aLa}*oML!gCKG4QH^wDu2W#1jT zisQre-@_3LY6mP%CEVF}g`6Jp9x9(;j6~r+Ay~V z=%2z^uW*zAIa`2p&Y0L+0YjhYZY7|P5D`3^v=;&PpiW!oGu}xz8u_JY&mYO9Wo&i` zmz4b7{2FqFb-os^g_Gp{yx>^;);-FJ1<`NBW0D8NnW#E)G(xMWrMAKxPk&F@e?szx z!+bcPSDcs!{cOOh0d0WZ01M}Hwik~J;DB}f88@y|Xin~V?%c(<;XWWTft!KOXO4Lm zOaYBY=)j7hSHF_8qytsW~eFw3*kzb*bso>930;eMJo7#-R79@+4+ zZ~MaBC&tA3Zjr~*k}PBGQ^<>dAw6#2|0(@hTcQ`gagp;miUGa){(+$LweF)G=~mEm zp@Z!!9XDKFBSp0UJlSP}N~;1ONPCq*9rXbLUjN2E+j zzibCjgXEKV1f2<*k1&r?PS|`_tdDurXI|nZ8(CEYxea}H2cmj=KXXbr1?+sM|ep1E zr*_}Ng*OBDd;*-oE_%Nx?hWej1$ENy;JKDRdJF>a4$mF>!PLW$3vgr65i$Hr;by$} zvPYuRII|qKEKDqRr}7i)`9ya1 z!{Us9pReq>cDM|D2KS`rIv>{orn673=PJ@v)3$cy<{oJC+9Ygs^>gRgv&WJqTVa#V zudU_b7_X8j4#>wEFlWgB3r2Us-QHAiS=6$s7`_!*zoI}2Cn!Sz ziGMwubHOn07^0>>rK{7YT_ z5 zaN1AF4^Le1Cq~ih@6LP=8Nd*XPw1UQZoce`3zHwrZwClSk8jckcvaw=*MMgNUo7&E zm7ReZxBTyQe)xl3!?{E8X~J7YwQtv;hWMBT@9mwRDz63Rz;ik0jz39dKn6SOx=7jX zeyluw!hl+igmDk#0+EZtZbSJfKl2^lnWH>|+9T+1ggY|l&Rm}mM^5GD9T?dn!hU_u zl9dxo0hUfGrz__(DjKUrdl~fXe2dYrRt=F%RS-SSgr{-WS=XVGh4~?#FcH%Do6U0p zZ-)SnpKC6?`v!2YyTmMd*K^~Vav+(AJhnSD70Yns`8V|oUEfv2ZQ)|6o{a3J`w_w9 zG$Mn3)gjb_cL3=x!<~$WLZqU&H$qYh2IW$&+)zA~sD)wr*f-4UVxxY>Gt0B62d(sP zCVmU$j3_R3LW8H0^h-S$P(<)ek&RG z=L``7qU6zE?pFTjfdwCFSG<~q+4fHh!KShM>NLGd&s~_VsC`86#xKtykpz#yy5fge z`%OE@-xDnBSMKI9)GT;Wt%w&PdmFR{0TE^|8=M`F+J+Ihrb77=U8Gou)D!`6T+uS_33hMv@XM8hhR82H?J z3Eod?&Cg^u9wV19f59Srg*u?a(qDmgCZ|PR{yyh5B#l}x?I_D;;4SMimki>*$~BnO z3yfy%5Gp@)Jd6B%Cwnr7w24lY{@~(5HKlPA-)4GL0jSH0xckjB26Q8T7vBx_N)<2G zLE3eW{y|>I_p}f5rL~N>hYgNM2WH<4VHz`_p;dkkEEqNR)D(shMeqTujz6aPVv*Fw zw;IuWb3XW{HG5licld2hO*U2QruN`DO-m==1nKZT8El$vLBWOgL3=SB@_DkPyp&_; zvldZ&#!PP1Dmh|rx%T$=@B8GZi7&vu=)=0Wr;N=SAhx-H9F(?O z*YkSZFCFlUB({0D9dT$6#eUmvwoI!I=>4r=`vwMG)+0}#dmewEzVB~fKX8L+F=>T0 zOgTucmr!*{CQxa#C_{mqtY4-jqT7fN_dFBB^m={gmf4POA2Z(Hdd~{k&{^N$FAd(W z+nUdKlbs|xDbmQi5@EQDTbsJfroC(v@0=cxtwS%cCu}zw16%<-3%~lxw*M5|+`F1X zb%JOIHq(XLovAt0ittnsBrb1L&2U6{=G+=aMLQyR@No$YsCN(If$sBvRV%#tLFtA+ zBYH?TL%!2^g+~hxhdSx$H3VBE!X_4+&MG<4U0h)i$|m8Jlo9ya0^wV!l4q;R)XQ~h zd6F6yQn@Fcv8LuC$5dd!6qw}!94+$(=@T3Pz2|-h^g#D8-W=c`IR(PqPJuCqkv%f( zATC69SIi>+3bWt!1<#rBR)OslIvjV>V|J5Mf0itNtKUU@#9Q-pEbh$7i2bAjq>azc zN7|+P{Z%8?Pp;~@T_3F2@Xx&Zv>SpL;t0F%Num^HvADD#aYNMHJEgG>Jr8iE-?aNfTFf9TB&%RBuDV31aN z@A|x7ub3GTIyhTI2QtGOsSfHQWDTM*Fv=ErrW?8dchS1SL$=-^7Cr8#+yL&`bj`-v zdsSInR#M{Jo=*kLvI5&DM>*$FpR4r(Q)|u3)er)O?qxL(_)@nPk(H}T^SF@v9-@PO?16Xmf%>y(KT!4H&TLqY7NKIU{p`PSLR53Qms|>O?K+p6#71Oi z(^l&_uOPlA{oj?HjnT>ayfzc2b#66L%um1$=pJ;ojb^-uFbiV8yWC5+G2djB;ynLhY(M^8H z^4kcW#V+@pH^ogh)&&i$<41zz>xjS}*rM6us`j>hTzgB}V{U)_FIv18F8pQJ%wr#zP9DwV zk^bkUcHb!*qr=CmoQ-Hw)$6a>&5<;|wa>u!#&^%3Y&q8(z?)>8SI&5X72V72Sewy| zn%3tlBhPP_SI$?6sT=0c2G2=X72KMONfh`#6`n|(D$bP-YHpZ=KcZXmYIzbpD4yr88!O>Q)v7HZo*BR|G#{tbMV$fl&h9-f=$mZ9F zXZQGudSIm)yQ%c-T=oMg7%RKD=e+Q{>S+|@$3URGi~)_+GN3v~ZK{XQ0qD(-oZLl- zCgVp`%OQQ&tP@;V^gUuFfT+}L%WFv3M@H;N7I<(#zbAbR6_Gkw-=F9eg4g--H+u3TG%|I{4(8*aX6P=jjY``dFRlq(Jh<57 z-dS9B*k?zsHJLs~y5N8ca4mx`=vppsJqkp+IEQu?kvQwxzUYQFv4%c+f<`ow+OVY; zwll06W2joZ+K*g%eBfB{u+JO`;!v)(2`_P7-1l%|Wc&3&f?MzhWFTU-x~h}`#%Axt)mg7~FS2$1hQ zo%n((5o&DE-n4{B9s{Fd{5*9-oR5 zWi3`tSYJzq;^0 zkMsYxpZf2H_TP-^=cxZ>oc_a6u`sax+fgwvv9LpNaIpQa85KR-|H!Cl7#L~)6QyGL zuPN2P=+6H@ss4d)|IwfSEv5SRx%-i1{|}||{(mWzG(6%_d^xxgg``Tj5FX_vxL>Ed z)S&th_RD*^P68{(0uovS7n81gW@h>DSbEPNHokI9pzEkb++zDDC^zWNI_k+*R!S=f zR~F_N5(RBKCBMA-&5^MLvg|p z))AwE?rlA;N^6D+cbFP3qXah8NgC%OCa zqe=wB;D=2lkjK+g7y|D_Nm|w9=LQf`8nkqr&(P#5Bh3J;vG4dHyF?m#(w&H0R1}NQ zt$kuDK5D%ylYm%#zIHw@zjsytX*$-=V!3R3u7*MYm=Pee!=LCpgEG%>?+PP<2Q<5C zb$T_HYPagA1Z)HaD2J!ha=0vFVdLdQ?1_@G2%$;k^W5@W)}sSpUNY#d1y%p8F0!Ah z7xQ`(P^6~qh~MZ+aCANRHJ4!QXxh)BqR!`n?$_mVdSRJd@h$ZSn*PwzijJn+>+8<6 zr5YYUn#I5y{Tmd(7ygC*$ZQlG1@F_bvc)}EuHzUywGc7J$ z9~V2M$c}9z)>!4h+6@Tlckf+)4prg){(bGlZzu?qcn2GFdq z*_4uQqUn3^dB>e?iOjBPK2TdhJjlDaHjYl(PLfZAglFQE^>4*C!cG)VnNYY^q-rr3 z&fS(9H1mRjldp%%FeR$JTFh*JHt|I8t{+MRs`ZV<4dA&0ZwJ8}G!03BrpV7Z+I~ zL-fM5TbeCfF#ngV7rbDHFg0*tBaEE~5PTP6Ho<~1fq10K2)r}m_zgZ+`gVsO>Zf3@ zFPoJ>IxiU4Ey-P`(jonuHC0OI-U%=K(`~Ah$?YKII$1usz#t&5d5s zmfZO~d~r^XyLTKg5(=TI#je-EvDOVqmmVSo>EnSMvt%SkAJ)54S@}ci!`Z|5DLg*N z>xv5s^DdX1A4b??lO5AVpjz#<)(tCmXg5I;`%nF}!eC)RBd9dVYGLYZ;_Wz}GvTkr zIg-W<+@t&rtq+*5vM(J9v2w0Q8Op4!Y}sNx$?mcn*I!ffVc2G&hqa2kD>j+O#_V9< zu-p6C7D)Ws!wI)9UGO_EVk71#WHg=eSGndkC@ub6Bc3ndis*&O#kk^+g%$J2^3Ck> z{@~@e7~ylwIBRwndPFRE{?;RDxQW@%yEOwcABCBjVzk6ng@M%g<0B6B0hNTyL@GJ> z?IXN*ysu2JREK5hoN=-WoGD-FHihjcfN#7!Lx5~amWQf#6|K=5v{yJ+bR9kD_lF-K zU4h-n-LjyRvX={8?rY8-=HHoL;O}~pNyX`kkxJ)^bcI`T-pQB&+XOW1`9!({?725ph_~5(snht@2Z~;3aU$a1vh`U` ze@sX34?rE_It0Fic?q`V16ES@kcDVcW$6Z8-QsLYB;F8tx97hn5A6rFNz?`x?QvdM zEnC-byswUVcX^K~u6L+je(G3!si2mmm$b<>i8%8=rk_bQ<#w@K5>2TieAwB}p}%n2 zKw1S$B<^<=`sUj^0P~3Wh&hfzvun|^g=Yw3nZuB;hAMWU2v4FlRVJ4~1QZ8G3$V>2 z*?{E?W9&jLu;rr9YMFy`%Vq~FIZ;clscdLDQDqHU?_TeokAT-=9)nmA^6>*R$8jEP zw$}o2DED0+Y?~03H*T0ODq2X^>~_m5T*;Y%iy@A6%F+^g8zDIpHW@t7Lg?$_d;iJ_ z#e6}O{K91fwsglhiAmW+ncNO%;gou#&AEKaP~Y%?1TDdzS7w~) zl6mw#m$pCO#FvDkg#CE)rTS%?#Ik+n;g#Z8BSwigQVVhqwnxjiEjMa+%lm6iP*q1& zcJSN~bbA(eA^MFBhSNfcQh-*jV;I>El0oJi{qx>1h=7*eG$aIPzWGWSmuuMcg&aCF~nZYw`K$kl;X#DR!nO zZ{2xpQsxQPtW|prSTSHdvQ!IHZ?Q?_H?S>E;}YC)BzWnVU92F-Lrn~OF9<+!Bp@R- zr)>TtaweM0t9%#uBl%;4h|3#g5Wer{{G|EZH z&MjmkH%Bfu#^4g4yaJU`OmGsP98Io3tF*o{>)UOEc^i`7_wtrta5{xeW&TZh3Pp2G zSk0MFTw397gbrE-887J}Br_=?R~oJ#cR)DVa7;obV`FV|H|n4zVV}S}1v@DrXy!DB zq>|2Gz$l}*nYuteFAlxB-osf|@$%Z_`T#{=LS&JNp3dfJVwsS!IdoJjYQI%nc;04s z#iW6~v9!`=VpbKawSJ*XUU#w9WLbEyG+HHOX^hs~wEJr%MO2e>sd;C?6(4a}F3FD7 zLrTjsVIx3E@*nZRTVqped3wj%BM!BGsX4=tZ`PI#mza@_5OB>7xoU7g12qQr+86$A{k@Pp5NkY~iEhcx!qn9=U1vG1^IXKn(5B_LF&Wcm)QjCi& zL_vuy(1}r3;wJY%U$kCxTU~laiA+8v9zG>L9}BaOgGkMyqb3}UwU`_iRazxIF7*@{ zlFR6-%vckpg<*;&@r-ED69W<_FLJ6)JS0vIyagfY#NrWCJzW0-aH4GCUc^5-eMyp=XbwIG zF>zUx#wbA1F9-Qn)yjI8QZ};*2;1mX#?m>^3O(5rVG0TNV1Y`SeZ+pYXs*6G55m0` zUa>I?9rWiG^79rt2yYKL=!<<}_1Kduv@}H2~2U5aBQ%cv`y@N5#lDTw%qGU0sSSFeas{utHLAx-|{($!e{4$yaVOGAUb_aNb zTIm_Zo#%;}O*!DbXf4AL+H?r+a8yNG;W7M*pLkLH^@|oN(Rjp@3!`|dKE~}{%+qw^TO}@!_W*u+6|Tw)UKL{O;EDX_mhqE1 zOxStnOb^`=*^cbnlCWL(TkOzvRHkkTbf5}I7FwldGHL1(@T^{xlI=O*V-jDhrtOW|`iBa4Ek6}@>h3EyW+?y!a390LW5WXiB?0Vo5BUy60&DWZ>T!6ILzjzaip@hm-RBP*9Q3Q2B#@ z5qWBuXO-V`5)=a3>>$ zKiqfeFN>CWE|KrObkhSRjIsr4$ksNn`A$g&A@TU_2^9?~vemgO+%#_A_J{`03~VV5 zKUncBZCWPl=^AQUa%%6y#@8O zUzHkNWz133a)W}+1_L|@H67^@ydH@$qnoS#?)qT`eJL~}8ru+h`QG)=jWy={q#fDn z0$NiWAuyOc3$8p7QAuJ+l!^0C%v8b7raj$mB-wccQ?#wEH4ffBfAkehvAXr-0c4Ci z9J;BVFVJ?$ShsFyZ>7_5X+K{;-x#Mh@#B;gD|-7YV|H6PlQ7bNIk63>j9IGsh(nO1 z8K^t6<`?7~(51~MF@4I@{3=Iou`#6zR9a)ojMT-49cmSo!1e;QL|y)H#fHIHRv>J^ z;5*It)Uc|e*M`V6;6I@B`Jf9L+7{$Q3m4E^JRd5-BYD(wQ37tl=W4TvA77~fH221~ zk|`{SV|**C0-VtI2~S1@bszW!e`{MLXjUcN&Ww%>tf!h>2XrTIaGxQ|lmB}Q_r~oF z9yTGiFXRF7ORyUGS*Cv^bKt-_T?}|#@-MdxF~WXLt=?tl*fPb|UZ>c`!DjU;CGVMc zxmC-NhGRC~o$g5GXP%PF8VIPlK=dzSqQZ>z{V%ua#=fh#dGbL}$3>t{%sS>1Z zp>&LJfJ1FhvZX63+#h{)g5C0{wmtpM1G7Cs2Q9#p3ZtpqKY8lpy1Emn=tEIMK(_<} zQ;W4w$l?i^^c?3jj1+&)55w=MU-jKfI`nu6EsbrfEWQ6$nmmp#z*jt1#Fn}@nYzt( z38C)Ys&yLB37L6Uh2YmKDjG2W@Xn7F`biplVsIo zoOQ|BTk}n@{Q+0^?-DsfPb$l?Su-uYkFwrda6W$@SR-?B9Xm;I_7<^Cdz;PmZ;q!O zbzr}@+-Lv22&kabYqPy-g16Ci*_=n)Z9b9`JK1Ed*!szyKe_SMFReS$trZ+zM{!J- z$^aerOfvG0LEgk+_R^7=q6{1jXc6!-TlBRw2=0$lXn905tRwDmS7R^#{zVq1)28 z(-+_()>{7u*_vTFU6U%Ao&cpv0Zg<}{x0`-uu)sN&b&>k7_ABogSLd)soHA|?8enL zmK$v=*BGjt|*BmEl$dtAPlvzYvJiEOwqF47UEp1Y;Bm&y4_`LdjS2 z`=4k!ra`T|71pa3yluznVVIYnoE6?AkDrm?ie$R(QLC(7F{=slH9Q}9-?#KY7Edk* zQ*H|rgzR-%OIXy8Ft8UTf+{+U0oud1e?kTwzT# zZP4V-j|C`U@pRBeL$*@|-Y`jmW(mR7&APv)|7-I47>=AjRoF11E}LutyeOZY1zz4#W_OFQ(t&tS+hS)jPutforj7*vfUK>;CD zXflzA?;1uQyz@{V!J<5`Ji#+9O=z!POGml$e#@J#tJ``CO9?w*k>xvnc}qNtFoaEa zN18)g>I>nf&C8IpyW=~)-;gYv*3#+0ps(`{jDb<76|t-{YjYjHlh6CDBOg?x6<#0e zHyEly5@J$BLhjPFiAX@r#Nqv49f9sG4CYUQaNAjw42hXD?mOl-?EH6FQ$pdY6u;WQ=0<|&+Ly@R_9d^hjwE)A#2y1pHJabH5`4@N1*%8Hx5 z?7QxPnY__KlV6iTY#ugu*E1VdzoW(+iX3gH0I&Qme@_W?YrfYnQc1J|X*n9Fgrrn~ z?K9h2QNXW{ z9DnK(VZjX9?q$#;=Q*zjpY9RhTYpd8i=8MvL+((qD<%8A_4(=u#78SUb(x&b19W}K->!?DOXLw9I zEOR{4xN3ABBW2EORgkQoU4XxURIV0DiUCFT`vZG}E zXM@2~Qb);?Rc%vF-n$XyTu@vUK1yz`i%)%3DxRMv<;F|DV+`<}D3est3wL5wTS(9En~3z^V^*MI$DDw~K#eVc0jb$Lvk^xl*5<0BqM zuL!M;ZQrgpeP|vGs@1io@&yf1si^Ifck9)-4*uL~i%rlRJt zEH;;qxFnddf*8lEE>` zc^7#A|4p$WiJc=p&3hYOh_!SnbFtK&^(y7qTXbtuO)+SpG2k!UlWrkz+YqqSPusge znWmn&KfOT1`Uq-wg{V;c&lkjqQ)zys3IbB}3-tVWI{h9MG2rhH1lqbxb>JgCSvHexqLPx%Dl7CZH#hzK(zkdrj(yqeQ33eu5g`brnb3RY zh{}{TktVIkssd#;waAS1O{Bym%3PPP?%Ou-ZCuAoC)~;Tdl?uMLk+U&nIjRbWDE-1 zqqYKBL_n^HY&UH$?fh@wy)AC^CUIlL$#8jen`#oJnbVOQE5}Uip>A>K!B&am0%-y6 z2rnb_yV6ETs=F=;2Wf=x!-1@>w@GXmmzA-h&bQDuht?p0){x5{#Nx_yo%tOA;7Q22 z+8_Ii&iBnR6Pt}^pB%Q_dY=aci@Ve75OvB20X z<-GynjJz+#_k9Xcx0(z`o@!9?L%=pt<(QY+g;~uU{er z^3LjJ4v!6^piM=gpdE<>4943LV<%gb52mM|#hJCNl0bw55Y#RQiKv8u7;%WiK<|1zx=`Jk{G0|d3J!M_=hh>FPicv*WLz%fS z9aB{!TDl$j8N**az&*e0KR)S3Ifj@T$QhHmB$3;n zd5<8x#pScsvwh-Rx%!Tz2B2O}-1efaSSU6xZhI1DTTmEMr~)|d76cCSn5w!^aU6q$ z#W_-g5lq9a(soK8iJ>|(Ff68Josqy#tHwmi*3PM)`8cRpT*gh#^NBMk;U~*}vMjRZ zsv414EbuOnBeIOaUWT7>#3aRJ;Iw{VYNag)`6yD|$6MJ9lUA^tfH_6`iK_~vl3$>+ z_wHj@z^78YU~t|1VcofEpy_d)0D@tk7Mj4^JLA`WE>N2jj6|{@x09-J4>B$!vB5Bw zP{*X1xan7W)fo}JBFG>;EWKscHX7)xHMsq=g z@i@tuQ%#JKePnZmjT)(Yi2A;9_$p4!X9U>OAH{uG}}O z8;H!CVdlA^cGot}P1gw2V5`|Luq{q!TT+u$C&S9${A-tRhtd+O!&w^nLSt)QCgyNi z?W#Eyg}xdch59kt?G6Wn{XKzNlKYYyuVwH#HN6_@AxDQ?umA;eP$!?_9(ljoPoi;loy9@*X*p5aRqZ0&8FmXM`dz5 zUTd47b}Ge=c0m1exUiK+zMt1C(GJzxhAPy{%aeYXahpybVjNSc*;wojj4IbAXX(mL z_4rV^r2Y>*x-5^)h`cWyRaMm%7Sy-ptmW@XjPGh|m3^Ae?QA0alkLqc-o9Z4L6{vv zL*yn_vTGC_*(-bwGq>0;jYqunXPE!i+E<4~-L!2ZEg&hK(#XNX0Gd+nOzRfIXBvp zUucMA^siDsrrw}Viq~456mqd<6t;|VNtJ#N>~7p|TgcNiDZdv?!6~my{t9Dxz;DY? zNI%A5(#!=jC68jvBFVGiH1ag}G*BmdizDNpW)S;^`&LcO!9jJgkqSukgPE)RxCJe4 zwYJKXMKJ0#!ye@SaF`?6LU~lq6f?UaS)TRSvWHvkTVPXHk;xq@t?_Fa(+kD0S2R`! zG*()^%Z6M|gNsA2aOpKn=57`iiA3SJ4ziX};gLg?)(+N?*4k2tdn_t%X*Cyn--ne9 z_4rY|&RiASc{GdqtmVT|g(XD(bN_y|{dw%Q@e{8N?9weuY9yDz@pm7llRg>wh>~*C zDFozC#OrR)ZYS~d)TuY1az$F(;MRbrb)IKrMx{<+5PUva@)cOhg9dsQuh_tx%C|=EXSi z>8fB$zXS^}ApVDJQ3A_omR!sono+(l7lU!kbW63(j;=N9o%UI=rb`)*^2$|WI)2pb zo=O%f9Y`LnGbW|vn#&N!`Rr|BrI0YscwHFV_pgLl8aS@)PUr1|cpyVuu3ar1H-oI^ zr-Nq39gakU#yl8y?df*~vCWsx#7UJe2JC1bb_N!Y2ruv)r~Syohv8UwtTq*Y3|WeE zs6Wd8k}|LIqcA&VkBRqF!+!8b#q z3&V%o0qnrqh$FU))sZXnS&s9KZhyF3WZwDCX|MiT1hL%n_U`mPtzvxCrxF=jk!G?| z8p_f-snA1KOTy3dwkuPf4oTt(g-NDO+Xy^%Q3H*B)i{c;!%oW&Y^E(g=bTIt1Y)Fb*E}d#qKBGxE zJDBtCqJlvb!u0PY4h!kc6j${3g!}hW7 zmDL?g6m_!a`lZv?M6~Gzh?dpa<=P7B?L)K|0pY$I-MgfQBE2S1C(k)#`dIG6GIjgm zqv&M))JKYn&$_&WQ$HG)5dr)5$#(Bt@Lvc^t{zoAQX*_4V07{?j8@Sjp|I;AP{@2= z`>-W%Z@+9l8rfayT;LgvpyeEt$dq(W8J(TQ3+?z$v#%>3YhJ95H|?~%Vu@Y%Lpmti z_1G#UmZDT%&m|nA)r$?&tR~RU4s4Nju!T`G<&q`0(mt55)4ovYXMBy69{HNDkD)+G zN|-NYVUfteM^gzovMQGH3sWz*UOBhQWx-*1CjAX4-Fd|<=DUVw1>cN|KvAj4lxyo9 zqQ~Q}zfmzHw!8@zC{<<^%vXNfq?*yvF5O)s_ZiS}+pH;)gG%#g^ITnHVz=C_R*>si z8Q0`nr&{%x`i*803$n-gdwb0uNrWa_r@i*^)3#q#w4GORO5=BR-JpHx2Zsg4MI$0g zy)vw%6{hEoM8tQ_CddYp-KE3Zwutp5U3Y%0;K`Pc zUa-F|&H_I$@X;T_F*jE|@IQ|JYCGyd;;9QfETn}e;%DrV#eDvj6|v#=&2YG(Kr%;D z-~7|pk6mXqCzLHeaVziL1NZuGFYN}(^z6~uMdH8hH?G9jNXgx$A$-=wcD+E7irB^^ z(079S8PS5BmyieREh=go7uEDLf+c)}YX5HPIf8c|L*fUIF}?WV4WZ??^Y5H)WqE~U zHwZbace1ag$|g<&+`T;mnhFSgXDo@NR$fZime_G&(b-deu7B56fcV+ov@Yd#0Wo(h ztaobL*L)em*<=^}tIA|iO*giW#1t16#N&3s{5eI9BS}mnL?ON8P*JCy;G&-nC}I$b zl67B^lF%{9N}v7y4o79-tIpHcIM8_OFu63SRhJ$IofoxPG5MZ(ypSK@diCA;5`LV$ z;2~B;C!*a0K{x)nBi)J*iAE1Yge@c4F%n|FOFw<#ul|MU3+W9}6G8aVD@2i3%>B}8 zC2iqZx3jjMdEZ*)H3ffK-F0MuSxTB_0jui_9Y%^y?*oafmxo9?2|VIQl3XG(Rr{9X zqM&6y(i54^;%$rLq|HVci~aP@M1JdVufl*o;mkx)$vnL|ed$JK`v_m2p>cbf8kKm8 zf`y7IEs4pdn|o&fX;NJ7m`c^8>li{oh?YIeEV?&ZwmD5Vba+B;LMS^yoBB1OjA-c~ zv`&DG#nTViY>XLW#0zrFAw+V<7~R+?tmS@cD=1H=Z}3fcbZ@C; zy{Pk+N7G#C`#5seaU|;&TN|mb8MSPke#IpIS~*^-#I2lF6VEh}n-tHw-Uc?Qn3|7x zepBJIoW4ipm$pWp6Brgd89!b%F;luzwc4o?n}i<)LJ6soi99c>zYou2&?NS{fs`=N zsFG8s(|2z1gJf^z?q(O?vV8e{H650oCSIMq94AC~yN=;>Fw@{`EeF^`bHk0Ax5EHP zRmAp{Ow}_;mDJJ=a|l7Pn96;Bn<)3>^5kU#x)30`#OpU1ZTxVJp zOrXk@(i9yPbrZRm6I)P1RO(tsGrdiX9~GJUIQdYD@B~x-Q$c*OOXzZkh{ZOjRYShu zedU~LS)$=wO|MJRYMH%nT6AW(8udDu*xUOWgL=#ZuNH-QlcVgLhs9SqC}{ zxqClXI&5cu*846T^-)SVDRjf!e&KnS%$TeblkGlxw~bh^zf~m{SyuUKNDYCkB@4p z=b8pwr?Px1NOyiB^Xu@ClJB|R;o@!CpZ%%uO~C=rijNNMnYR*p=)!weag`oxkbFPn ztvgQ@-m1cR=1DE4-Wj`t`akxWVNkK#IjgIPcPgSDCvat-nN0?~ugZJqqs+{ZpS?FY zBY0cD?%feP6bE^YzVfS%rB+@*wAn`5zKux1#Bok@H#~%99Nj|?!G)T&C_;;?7dXooO0LImJ*gd#$4$_ zmL-13!=N<{C$)5|CjC=4C7zM&!*_=~gjyT)4WlNX*5nzQLL{A#!$3H5GXEr5QgR44mo+Mt&VlD1G-q%v1MMHRM7@hVG}%n^Mqa53m_zUV=7p%$z<9@G2M%>4&WO$CDE5=`S*j^h@BUA)W5w-&H?-nEJh zr7Bh;_Bh~-*AC6y^_=vU1s8bLK9Mr-Pw<5_BcED7f3D3fDak-U^}_$KTaoAHO_|I$ zlwT9hJsU0XRD&s@eAfyM&4+-a9jg?k211X)=0*468jr|Ai?8!LwT(|{cSKg19_8Fq9rZXfh-vZAL#(lZI&Zd-{Sup_Z2j`9 z_=$#@ki26i*eb=2Ge`y4PhqVo7x3s{Df}$UIy=#0xK8kyhyUfs6Uu4!ho(qLi{VLp_-_JN!8{fSpDY`mq($Hlh5KC-G zCcYV9iqEslW5>m@O>4{YaO~cU|Kc`c#5O2l&KoXeyDjJ?y}2ZyO6crBS(`96k5$r4 zq;;d=g@!wgh%xYRjM#3|o=MU8+CED~Gm{pHnzS#zl7H;hak($W|!)+mC$ zv;)rpODSm8hO49k&N;EoeA4YkmcD$?+Y>QfHtjDL8CVvYclHkB$ zCy|@4;}2R~;`8d6%p?RRz5Y>2_Y4?H#WFUxwO@UF=)-x=?w@5V{c)9b8d8#|f(06z zzxf47An(Y3m;t4!VEr!q8FM))U+kFz!)j ztO@g-Hs7IXW4m_5nGt}}x)Y=Hff3}>t)C5yb-^S|zHUb9r_LrV6|~&7#u!@o_gM;| zEx5@&tuZTK^r$S1=49*}bw+ef&K{kcg&BHzDy|{)gMdIj#(XG+PwW_t+=z) zrli9p_2k;{4}#Xk@5te^jRdSNY4>xY0oK5Kq*a-<_1hN=?&}xC!z&k9HK@1nrd0i( zeeL;uf5Ckn>3n&v8~x(*1rR6wB*7q~=GrMIswp4~$2>N;)_G1SH8+c~gw1V8N+?Mj z8Sz7XTi5q3i`2f2uW)L?uF&R%_&MP(oC|-SriMAgZJ}f8GfBLfxJHz}hVn<#_`}uc-{0Q(t#O|%eZpgE5Mk}Z=p_n zSlq&7nTZ1^R>WRK6l=TQ6fG4H^bEh$^RMqyTp9l?`=(t1txq^T)!fUvW7TpF+_eDF zN6?)I)on=vO?Lv)ZDb5<$%Cx=+Cephb$nPq=|yVR;rl8aQ{Bof4)x^ys?EWQH9C3v zh3^u0*3A_^7$}Td4)OETljFt?G~c!-fKeXtUb7d5sRVO5_SL`$9VmdG7YJ+iV%;%e za>1WFoM7#XrD-=79rZ$@B}w*_X(HOhLOL7-rj`A6UoIzRyl|=US=REPSQrR|LvBTB zb$JFB;>*WIYtt0T!2=t41g?(;-e;4zp@(&NcaG*dQURlbV>_?oeRx4j@-VKWZ|ZZN3wzjbA{< zBsUiP=EbR!as{~O>FSY@gLEO}= z-7k*wv1&0eWe2;0&hdjt!&w0St8BpCD4LUF|C2FEL+fmf3GaYNxw!|gb{)^kCv#(G zt_7Ce$}0JS$U+7=^#hs>Jj<2JJAX%a=?dE4g>reG*KFF1}JWY zdBb;wJLBVpxl~&3RygJ=uc>f^D7 z-ASy#o3l>uh3Km*OC<{R#cKEZp$-P>KZ>fqYRgxE&tu-O(G%Bxb|k5vGEQ9L{6Q~S z38@vR7SQe@U!SVlxr;c=xHufp5kb~klQ8zbtr`(ORneIgdlC0dG-aZ{0_%ED%As#B zYc}IuB;(!HioKzEq<)}mlI!#AvxWiqr8++MSHvNB+JLk+jT|euo1rdTyxQ7bC%OJFnN{jDf_5? zWnT|TPk>;+6ME1uDP z2ka>}N+zMg39JX)@j5iqBXAJK(SracoSGJ{>M&P=o^Lm;!@IWVy`OooG~mfp2v`$^ zsU(wXsVm4RU=`dJFjcoWoCTJvZ_%5UJrO$bu2O6?v9SWzq)g!v_zw;*6s3y!zfy=mIEw!Jf0aUn zpyVL`RSFS)$r=4W_`8=fk(a>&frT$adHE~+QWo+z282WZMt^G|{zg&s;s4Y`DN+8Z z2^5B+)EECkFR8wNYJ&d8{?hydqG%g`_xV@zO9j$DnexEc(%hLq=$^Hi^CeFk)sgBS z5m40Qa#*SaD5c2Xk3S{QpAt&q^AZIADS`i#P*m?r5c)^N@wY^$D#35LOw~)jqGEv( zl>~zRAq?s6WNtwKU_r@hqO>Ugd1_OXs#sUxq3k#!TU~~)$yxJBBfkF{i+k#-QtMdS$ z)K1aHjM6(r#}H`o1w!C3G#`Lb(y&+Uf?)`B3=Txc5O6f#Ljka>b3>&Xx(x^%-3A1K zZUYMV7aPJbG@n9Y2sHme;lO{vKxh~Y0JxfeKqwe3PXVZKpxK4Np#Orw(J|CEc*V~^ zC=@-ua5&;>Jpc;&7Yu}kAyBfjXg1)mtGNLL2&3ga3PblZ9F@^m`vZUgXfX$X(QUv0 zFtmE8?GEd&TbiyP{03^bpjmgUuY5C9b21{{R8H$i~t z7!VEvU(F#X7~OxU;i0W9C>Q~`>QhuLz}2+?2LObx&KC*+qOBuT`a!SeIO-GwU&Y`6 zFyv~CP#BsIP-h<6`aogASLchu(AGH$`{($cIvJxhnVo)Xj;mRFnxllYQR3rIo;*d} k&vJQK3;k9k|8sEvzAMDo>FMuN84kGAg680my)Q@bKLL -MM: What is the intellectual property side of neural networks? -MS: The weights and the model constitute the intellectual property. By keeping the model outside of the primary source programming language and outside of the main wasm program state, intellectual property is better protected. -MS: We’re working closely with WebNN proposal -MS: We expect many different hardware architectures will implement backend support. -MS: Initial POC would target a CPU backend but future devices (GPU, FPGA, TPU) could also be supported. -MM: Intellectual property is a legal term; is there any attempt at legal protection of these weights? -MS: It’s hard to protect a model across a development and deployment workflow. Model authors want to ensure that their specific weights are protected. What this proposal says is, the model can be opaque. -MM: So you’re not talking about legal protection, just about hiding the information? -MS: Yes, it’s mainly about confidentiality of the model. -MM: So since the questions that wasm would ask of the model through the API would expose information about the model, has there been any analysis? -MS: If you use a programmatic model to define weights it’s a lot harder to protect. -AB: -AB: Showed the proposal: https://github.com/WebAssembly/WASI/issues/272 -DG: Why explicitly expose the target instead of making it an implementation detail -AB/MS: Current thought is that it gives the developer more options. -MM: Could you refactor this to move the target enum into init_execution_context? -What happens if you ask for a target architecture and it isn’t available? -JB: Would it help to say that the target parameter is a hint? - -AB: I agree; 99% of the time, what you want is just “pick the best one for me” -Open question: Web-nn exposes this target parameter; why do that do it? -AB: I’ll summarize this discussion in an issue. -AB: Let’s look at how we represent tensors next. -AB: Is there a better way to represent multi-dimensional arrays? - -PH: You need a dynamic number of dimensions, and it’s hard to do that, especially with witx in its current form. -DG: Does this definition give everything the implementer need to be efficient .. to change to the format needed? Agree with Pat multi-dimensional support is a hard problem right now. -AB: We’ll learn more about the implementation concerns as we start prototyping this. -AB: How do we specify how to include dependencies? -DG/LC: The concept of optional imports may be useful here. -PH: Also have a PR for profiles that is a way to specify in witx dependencies. -DG: Have met the requirements for phase 1. Can vote. -LC: What happens if there is a fail? -AB: Have a mechanism to return error. -Vote: WASI-nn advance to phase 1 -SF: 7 -F: 5 -N: 2 - -Vote succeeds. diff --git a/proposals/random/meetings/2020/WASI-06-04.md b/proposals/random/meetings/2020/WASI-06-04.md deleted file mode 100644 index 6c7e2d7ee..000000000 --- a/proposals/random/meetings/2020/WASI-06-04.md +++ /dev/null @@ -1,43 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the June 4 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: June 4, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. wasi-sdk release 11 - 1. https://github.com/WebAssembly/wasi-sdk/issues/139 - 1. Commands and Reactors: - 1. Heads-up: -mexec-model=reactor on clang trunk, use with wasi-libc trunk - 1. Update on repositories: wasi-nn, wasi-http-proxy, etc. - 1. WASI-http-proxy next steps - 1. https://github.com/WebAssembly/WASI-http-proxy - 1. Feedback given earlier is that it'd be good to look - at splitting out some of the parts. How can we help? - 1. Multi-call commands (Dan) - 1. https://github.com/WebAssembly/WASI/pull/281 - 1. Async - 1. https://github.com/WebAssembly/WASI/issues/276 - -## Meeting Notes diff --git a/proposals/random/meetings/2020/WASI-07-02.md b/proposals/random/meetings/2020/WASI-07-02.md deleted file mode 100644 index cc9ac5576..000000000 --- a/proposals/random/meetings/2020/WASI-07-02.md +++ /dev/null @@ -1,41 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the July 2 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: July 2, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. Update on action items. - 1. proxy-wasm repo - 1. Discussion topic: WASI and POSIX - 1. https://github.com/WebAssembly/WASI/issues/292 - 1. What should we do on `lseek` past the end of a file? - 1. Should POSIX be a normative reference for the filesystem etc. APIs? - 1. Documentation philosophy. - 1. Heads-up: Module-linking-based dynamic linking: - 1. https://github.com/WebAssembly/module-linking/blob/master/proposals/module-linking/Example-SharedEverythingDynamicLinking.md - 1. Tooling for new-style commands: - 1. https://reviews.llvm.org/D81689 - -## Meeting Notes diff --git a/proposals/random/meetings/2020/WASI-07-16.md b/proposals/random/meetings/2020/WASI-07-16.md deleted file mode 100644 index f4ba68088..000000000 --- a/proposals/random/meetings/2020/WASI-07-16.md +++ /dev/null @@ -1,41 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the July 16 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: July 16, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. WASI testsuite activities - 1. https://github.com/WebAssembly/WASI/issues/9 - 1. What kinds of tests should be in an official testsuite? - 1. Where should we collect them? - 1. Discussion topic: Threads - 1. https://github.com/WebAssembly/threads/issues/8 - 1. https://github.com/WebAssembly/threads/issues/95 - 1. https://github.com/WebAssembly/threads/issues/138 - 1. Discussion topic: `fd_seek` past the end of a file on Windows - 1. https://github.com/WebAssembly/WASI/issues/292 - 1. Discussion topic: Symbolic links and Windows - -## Meeting Notes diff --git a/proposals/random/meetings/2020/WASI-07-30.md b/proposals/random/meetings/2020/WASI-07-30.md deleted file mode 100644 index 1a164d624..000000000 --- a/proposals/random/meetings/2020/WASI-07-30.md +++ /dev/null @@ -1,36 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the July 30 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: July 30, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: sunfish@mozilla.com - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. Documentation for WASI APIs - 1. https://github.com/WebAssembly/WASI/issues/292 - 1. WASI committee processes - 1. Proposal repos - 1. Further harmonizing the spec process with the core CG - 1. What work needs to be done, and who wants to do it? - -## Meeting Notes diff --git a/proposals/random/meetings/2020/WASI-08-27.md b/proposals/random/meetings/2020/WASI-08-27.md deleted file mode 100644 index e5cbbef58..000000000 --- a/proposals/random/meetings/2020/WASI-08-27.md +++ /dev/null @@ -1,42 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the Aug 27 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: August 27, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. WASI Status - 1. Update from Dan - 1. WASI moving forward - 1. Sockets API - 1. https://github.com/WebAssembly/WASI/pull/312 - 1. API discussion - 1. Process discussion - 1. Testsuite - 1. https://github.com/WebAssembly/WASI/issues/9 - 1. https://github.com/khronosproject/wasi-test/ - 1. Should we work to make this an official testsuite? - 1. Where should it live? - -## Meeting Notes diff --git a/proposals/random/meetings/2020/WASI-09-10.md b/proposals/random/meetings/2020/WASI-09-10.md deleted file mode 100644 index feacffd1e..000000000 --- a/proposals/random/meetings/2020/WASI-09-10.md +++ /dev/null @@ -1,33 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the September 10 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: September 10, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Proposals and discussions - 1. Sockets API - 1. https://github.com/WebAssembly/WASI/pull/312 - 1. API discussion - -## Meeting Notes diff --git a/proposals/random/meetings/2020/WASI-09-24.md b/proposals/random/meetings/2020/WASI-09-24.md deleted file mode 100644 index dd3127e8f..000000000 --- a/proposals/random/meetings/2020/WASI-09-24.md +++ /dev/null @@ -1,30 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the September 24 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: September 24, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Add items here! - -## Meeting Notes diff --git a/proposals/random/meetings/2020/WASI-10-08.md b/proposals/random/meetings/2020/WASI-10-08.md deleted file mode 100644 index 78d943918..000000000 --- a/proposals/random/meetings/2020/WASI-10-08.md +++ /dev/null @@ -1,42 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the October 8 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: October 8, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Add items here! - 1. wasi-sdk update waiting for LLVM 11.0 release - 1. https://llvm.org/ - 1. Interface Types update: - 1. https://github.com/WebAssembly/interface-types/pull/122 - 1. WASI is being mentioned a lot in the GC repo: - 1. eg. https://github.com/WebAssembly/gc/issues/143 - 1. WASI testsuite - 1. https://github.com/WebAssembly/WASI/issues/9 - 1. What do we want to build towards? - 1. WASI sockets - 1. https://github.com/WebAssembly/WASI/pull/312 - 1. Merge soon, and iterate? - -## Meeting Notes diff --git a/proposals/random/meetings/2020/WASI-10-22.md b/proposals/random/meetings/2020/WASI-10-22.md deleted file mode 100644 index eb7d737de..000000000 --- a/proposals/random/meetings/2020/WASI-10-22.md +++ /dev/null @@ -1,211 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the October 22 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: October 22, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -**Note**: This meeting will be hosted by the subgroup co-chair Sam Clegg (@sbc100) - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Review of action items from previous meeting(s). -1. Vote to move wasi-nn to stage 2; see [witx here](https://github.com/WebAssembly/wasi-nn/blob/master/phases/ephemeral/witx/wasi_ephemeral_nn.witx). -1. Character encodings - 1. A presentation on: Summarizing several current discussions around character encodings - 1. For details, see the individual issues: - 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 "case-sensitivity of filesystem apis" - 1. https://github.com/WebAssembly/WASI/issues/8 "Specify UTF-8 as the character set" - 1. https://github.com/WebAssembly/gc/issues/145 "GC story for strings?" -1. Discuss about how to move forward with a [WASI Logo](https://github.com/WebAssembly/WASI/issues/3). Proposals: - 1. We would never like to change the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png). - 2. We would like to keep the [current logo](https://github.com/WebAssembly/WASI/raw/master/WASI.png) for now, and change it in the future when WASI is more mature. - TODO: Ask the risks of changing the logo short-term and see if there is any way to address them. - TODO: define what "mature" means (objectively) and how the process will be then - 3. We would like to start researching on a new logo now. - TODO: define how the process will be - 4. Other ideas? - -## Meeting Notes - -### Attendees - -- Sam Clegg -- Thomas Lively -- Martin Duke -- Syrus Akbary -- Pat Hickey -- Tanya Crenshaw -- Alon Zakai -- Andrew Brown -- Mingqiu Sun -- Alex Crichton -- Dan Gohman -- Steven Dabell -- David Piepgrass -- Johnnie Birch -- Martin Duke -- Yong -- Sergey Rubanov -- Arun Purushan - -### Find volunteers for note taking - -TL volunteers - -### Adoption of the agenda - -PH seconds - -### Notes - -#### Review of action items from prior meeting - -DG: Next time ??? is in the meeting we will check up on ??? - -#### Vote to move wasi-nn to stage 2 - -- Phases: https://github.com/WebAssembly/WASI/blob/master/docs/Process.md - -AB: We proposed wasi-nn a while back. Have a witx spec. I’ve been creating a POC -to see if this works. When looking at docs, realized we are essentially in stage -2. Moving to phase 2 would reflect reality. Asking for feedback on API. - -SC: English spec text requirement doesn’t apply? - -DG: Right, we only have witx. - -AB: Also generates md, which might count. - -SC: Implementation and test writing starts in stage 2. Probably don’t need a -full vote. Does anyone have any comments or objections? - -PH: I followed it and I’m happy with how it looks. - -SC: Unanimous consent achieved to move to stage 2. - -AB: I will submit a PR updating which table it is in. - -#### Character encodings - -DG: Several threads about encodings going on. Want feedback about direction. - - TODO: Add link to slides - -SC: Won’t the C program truncate on strcpy? - -DG: Yes, but then you’ll get a file not found error. - -SC: Where does this ARF encoding come from? - -DG: I invented this after a lot of tries. - -SA: Is this for filenames only or also for contents? - -DG: File names, env vars, commandline args, but not file contents. - -SC: Anywhere a known string crosses the WASI boundary? - -DG: There might be other places. Where invalid strings should be roundtrippable without trapping. Some APIs trap, others wouldn’t. Some tools will want different things as well. - -TL: wasi seems like it may be the wrong layer to solve encoding problems since it is not related to capability-based security. Can we leave this to an optional userspace virtualization layer? - -DG: That seems reasonable since virtualization is an option. - -PH: When IT describe interfaces, it would be great to use strings for these types, and IT guarantees unicode. ARF lets us use the IT string type. - -AC: In windows, filenames are lists of 16-bit values. How do we go from 16-bit to 8-bit strings? We need an extra layer. - -DG: We can extend ARF to handle Windows character space as well. ARF would be a little different on Windows and Linux. - -SC: But there are filesystem out there with different filename encodings. e.g. Shift-JIS in asia. - -DG: wasi engines can translate host character encodings into unicode. - -AC: What would the users look like? Not raw API users, but e.g. rust stdlib users. Would the entire ARF string be stored in Rust’s Path object? - -DG: Two cases: in do nothing case, use all the standard APIs. In ARF encoding case, get string as ARF encoded OSString or similar. WASI will either detect ARF string and not validate or would get file not found. There is a Rust library that can take an OSString and be ARF-aware to do things. - -SC: But most programs won’t need to do this because these files don’t exist in practice. - -AC: Not sure about this. Rust stdlib would want to do the proper decoding to show better error messages. It seems only extremely low-level C developers would be in the do-nothing case. - -SC: Do-nothing only prints first half, right? - -AC: Only in C. When there is a pointer and length, the second half gets printed too. - -DG: Good point. Don’t have an answer for that. - -SC: Curious about prior art. - -DG: Perl 6 has UTF8-C8. Uses highest private use code point as an escape char. - -AC: Using nul character seems reasonable given that native filesystems already disallow it. - -DG: Python uses lone surrogates. Not great because you end up with invalid unicode. - -SC: To be clear, status quo is passing through raw bytes from OS with no validation? - -DG: Some implementations already have some validation and different behavior. - -#### Discuss about how to move forward with a WASI logo - -Slides: -https://speakerdeck.com/syrusakbary/wasi-logo-proposal - -WASI issue: -https://github.com/WebAssembly/WASI/issues/3#issuecomment-714740192 - -SA: I’m the founder and CEO of Wasmer, want to see what the risks are about -moving forward with a different logo and what are the issues with the current -logo. - -SA: Show we replace the logo at some point? - -TL: Agree with identified issues. - -SC: Another options would be to fix the problems in the current logo. - -TS: It’s clear that the current logo is a draft. I actually like this property -because WASI itself is also in a draft stage. For example, the proposed logo -uses an office CLI metaphor, which is not what WASI has shaped up to be about. - -SA: One idea would be to replace the current logo with a short term logo that -fixes some of the issues and is more accessible. Then separately it would be -good to organize a contest for a new WASI logo. Back to slides… - -TS: It would be good to mention reasons on the issue so others can weigh in. - -SA: Will follow up on the issue. - -TL: What if we just fix all issues except for wasted space in the current logo? - -SA: That would be an improvement, but it would be good to fix the wasted space as well. - -SC: Any objections to incremental fix? - -PH: Don’t want to spend any more time on this. - -SA: I can handle this and release the results with a copyleft license to resolve any other issues. - -TS: I think we still need to check what the situation is with IP rights just in case. - -SA: I understand those concerns and want to make this as easy as possible. diff --git a/proposals/random/meetings/2020/WASI-11-19.md b/proposals/random/meetings/2020/WASI-11-19.md deleted file mode 100644 index c9d6a819b..000000000 --- a/proposals/random/meetings/2020/WASI-11-19.md +++ /dev/null @@ -1,153 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the November 19 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: November 19, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Dan Gohman - - Email: hello@sunfishcode.online - -### Registration - -None required if you've attended before. Email Dan Gohman to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Review of action items from previous meeting(s). - 1. Ralph Squillance to write up a draft on "WASI experimental" or - versioning for WASI API experimentation. -1. Removing support for `seekdir`/`telldir` from wasi-filesystem - 1. https://github.com/WebAssembly/wasi-filesystem/issues/7 -1. Filesystem Case Insensitivity - 1. https://github.com/WebAssembly/wasi-filesystem/issues/5 - 1. https://github.com/nicowilliams/ietf-fs-i18n - -## Meeting Notes - -### Attendees -- Peter Huene -- Sam Clegg (SC) -- Lin Clark (LC) -- Andrew Brown -- Dan Gohman (DG) -- Sergey Rubanov -- Syrus Akbary (SA) -- Matt Fisher -- Eric Rosenberg -- Ralph Squillace (RS) -- Till Schneidereit (TS) -- Harun Oz -- Pat Hickey (PH) - -### Action Items from Last Week -RS: had conversation with Pat and Dan about how people are testing out experimental proposals. Pretty obv that we wanted to use these experiments for inputs. At same time, second issue was wanting to be very clear that none of the experiments were destined to the spec - -Wanted people to be able to play with sockets in Krustlet. Dan proposed creating an experimental namespace. Ralph will now begin tackling the doc. Will talk with Fastly about how they are handling exp. - -DG: need standard convention for naming - -SC: Are you talking about system level imports? - -DG: We have wasi_ naming convention. Should be a naming convention for things not in snapshot yet - -RS: That makes sense. Explicitly not destined to be migrated. Signal that these are things to be used as ways of stimulating thought. Kind of a firewall between these and what’s going into the spec. - -DG: One additional thing—some prior art wrt web standards e.g. vendor prefixes. We can probably avoid - -SC: How would we avoid. By not shipping prod VMs with them enabled? - -DG: Yes, or behind flags - -TS: Situation might become slightly different once module linking and ability to virtualize comes in. Then you could say you don’t need to ship as long as you provide a shim implemented in user space - -SC: presumably not the module name - -PH: unfortunate that there’s only one name - -DG: Module linking has concept of nested modules. Might be useful - -PH: That’s used for definitions but not for imports. - -SC: You can chain imports - -TS: IIRC you have to re-export - -DG: typically you do, but … if we don’t have this, then mangling - -PH: we need this before module linking lands in any toolchain. - -From chat: -wasi_experimental_tests? -wasi_experimental_temp? -From Pat Hickey to Everyone: 12:16 PM -wasi_experimental_ for a mangling scheme - -**ACTION ITEM: Ralph will compile doc** - -### Removing support for seekdir/telldir from wasi-filesystem - -DG: from days when OSs used flat lists. Now they are BTrees. These have become awkward abstractions. - -DG: want to remove from WASI altogether. Can’t do a 64 bit seekdir. In order to satisfy POSIX, we’d need to do some complicated indirection. Theoretically possible, but think better to remove altogether. - -SC: Proposal is just to remove, not emulate in user space? - -DG: I don’t think it’s worth it unless use case - -SA: Don’t have context, but what do you think wouldn’t be possible? - -DG: ls will work. This is why I’m asking whether anyone has heard of someone using this. Scan through, then restart from beginning, and then keep going is pretty rare. This originated when it was hard to keep file in memory at same time - -RS: What’s request? Could potentially search GitHub. There are tools - -DG: Found a million hits in code, a lot are libc code - -SC: Yeah, we’ll need to skip headers and impls - -TS: Have experience from TC39. People have tried to use as code search, but there’s quite a lot more dark matter that’s not in public repos, and also test suites are copied all over place and not ways to exclude. Perhaps possible to do regex to exclude - -RS: Both MS and GitHub have internal tools for this. GH is strongly motivated to make this work. If we can write a user story that’s in the sweet spot, I will see what can be done as a feature, either privately or as a preview test, or ultimately as a public feature - -DG: That feature would be really useful for other questions too - -RS: I do need a user story to pursue in an aggressive way, but I think they actively want user stories. - -DG: WASI libc is already trying to guess what you’ll need. - -RS: Side issue—feature set is that we want to know what the community is using. - -DG: Roughly the plan for removal is to remove from libc. Second step is to remove from WASI itself, removing parameter and introducing rewind call - -**ACTION ITEM: Ralph will use internal tool to search for use** -**(possible) ACTION ITEM: Put together user story for feature that would allow WASI SG to search for usage of other APIs** - -### Filesystem Case Insensitivity - -DG: GitHub repos and offline chatting. ONe question, what is the goal of the ___ API Fully deterministic? Will behave same way across all platforms. - -DG: People want to access existing files that already have their own restrictions. Hard to abstract away. If we can assume WASI runtime owns filesystem, could do a lot, but if we assume you have your own files, we have to pass it on to applications. Somewhat unfortunate, but after a lot of discussion think we’re going non-deterministic. Best we can do is good debugging tools. Those wouldn’t be part of the spec, just side debugging tools. Disappointing from the Wasm perspective, where we try to be deterministic. Not within our power at the WASI level to choose one side - -DG: Also want to mention, link in meeting notes that will hopefully turn into an IETF proposal that will define portable semantics - -### Additional Questions - -SA: One quick question. What do you want me to do with the logo - -DG: Researching IP rules - -LC: I can help with this and serve as point of contact - -SA: Lmk if you need changes to the PR - diff --git a/proposals/random/meetings/2020/WASI-12-03.md b/proposals/random/meetings/2020/WASI-12-03.md deleted file mode 100644 index 7d9b521b5..000000000 --- a/proposals/random/meetings/2020/WASI-12-03.md +++ /dev/null @@ -1,130 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the December 3 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: December 3, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Review of action items from previous meeting(s). - 1. Ralph Squillace to write up a draft on "WASI experimental" or versioning for WASI API experimentation. -1. Proposals and discussions - 1. Discussion topic: Repository organization to enable independent proposal repos ([#360](https://github.com/WebAssembly/WASI/issues/360)) - 1. Discussion topic: Using releases to make the repo citable ([#356](https://github.com/WebAssembly/WASI/issues/356)) - -## Meeting Notes - -### Attendees -Lin Clark (LC) -Pat Hickey (PAH) -Martin Duke (MD) -Andrew Brown (AB) -Dan Gohman (DG) -Till Schneidereit (TS) -Matt Fisher (MF) -Mingqiu Sun (MS) -Mark McCaskey (MM) -Johnnie Birch (JB) -Ralph Squillace (RS) -Peter Huene (PEH) -Sam Clegg (SBC) - -LC: Action items from last meeting - Ralph is not on the call, so we’ll skip over follow ups with him - -LC: Dan put up a PR yesterday about repo organization to enable independent proposal repos - -DG: In a CG there's the core spec repo, and proposals that add new features are fork repos of the spec. When a proposal gets to stage 5 (spec), the proposal gets merged into the central repository. We want WASI to have a parallel structure to this. - -DG: One thing we want to move away from is a single snapshot path. So when we make a snapshot its url remains stable (we don't put it into old). What this enables is one snapshot referring to another. We want documentation to describe the differences between snapshots and eventually tools will too. Stable URLs are a good first step towards that - -DG: Another feature is moving away from ephemeral. That was envisioned as the place where we do development, where PRs target, but we want to move all development into proposal repositories. The main proposal repo will no longer have an ephemeral directory. -DG: A final piece of this is a place in the repo for a script, similar to core CG’s test suite repository, that pulls in the proposals from all the places they live, and creates the snapshot. All of the proposals will be separate modules in the snapshot. - -AB: When do proposal repos get added to the script so they land in the snapshot? - -DG: As soon as you create them you can create a PR to the script. One rule we could have is that if there's a merge conflict or other obvious errors we just skip over merging a proposal for now. But we want a snapshot to contain all proposals. - -DG: In the root spec repo, there will be a `standards/` directory, it's empty for now because we aren't at stage 5 yet. But out in the proposals they can put whatever they want to land in the spec repo snapshot in their `standards/` directory. This convention is that we don't have to wait for everyone to sync up - -TS: Will it make sense to say “only show me sections for proposals for stage of my choice in the rendered output”. - -DG: We don't have that information yet but that's a good idea. Maybe a magic doc comment in the witx files. Or we can iterate - -TS: There has to be some index about pulling in the proposals, and that can contain the metadata about what stage various proposals are at. - -AB: This is a better system than we have today - -DG: We are learning from our mistakes - -TS: We need to iterate on the infrastructure of the spec in a central place, and make use of it without copying code over, are you envisioning the proposals will pull in the (upstream) spec repo? And we iterate on that outside of the snapshot mechanism? - -DG: Some proposals need to make change to witx. They all have a witx crate in them to make changes to how witx works. You can experiment there and make a non-snapshot PR into the spec repo to merge bigger changes in. You can keep - -PAH: For some changes to WITX, it would make sense to do in the core spec repo and then proposals merge or rebase - -DG: That is something that becomes more awkward with this setup. The question is would you also modify existing snapshots to use the new syntax? Because if not, then snapshots don’t work with new tooling. - - -PAH: let’s set that discussion aside. We have been updating to keep semantics but use new syntax. The hard part of this is that if we have to make a breaking change to WITX that could affect our ability to merge in proposals that haven’t taken in the breaking changes yet. Is it the responsibility of WITX maintainer to un-break all the proposals? - -DG: Initial way that falls out is that the script that merges will run the new version of the tool over that. If it doesn’t run, we leave out of the snapshot - -PAH: That sounds fine to me. What I’m thinking now is the CGs waterfall, continuous integration of tip of tree which makes it possible to find before releases. Could run it on a cron job and does red/green for various proposals - -DG: If someone wants to set up a waterfall, that would be good. Might be more than we need right now. - -PAH: If you have to update both your WITX files and ref implementation on downstream tooling, might not be able you - -DG: You can do it on your local as a champion - -PAH: This also makes me think about the value of the snapshot version being date based. You could have an id and a date. E.g. nightly-YYYY-MM-DD. That could give people ability to find breakages before time for snapshot. I think the biggest thing I’ve messed up in WASI and WITX is not having tooling that makes ephemeral work. Want the new process to be tip of tree always working. I could be wrong on that, but that’s my personal feeling. - -DG: Ephemeral in main repo goes away. If they want to dev in standards dir, they can. If they have their own ephemeral, then it’s on them to keep it working. - -TS: It seems to me that there’s value in cross-proposal CI so that you don’t find out when cutting a snapshot more work to do. I could see value in /standards and /in-progress, where we maybe have GitHub action that tries to do an integration build - -PAH: I think I agree. I would love it if the CI action could be run in any of the fork repos so that they could alert on their own breakage. - -DG: If we put that in the main repo, then they’ll all have a fork of it - -PAH: They’d be able to id if any contrib to main repo is breaking. That’s an implementation detail. - -TS: I feel like it would also be kind of nice to have a snapshot that’s always up to date for what it looks like today with all proposals combined. - -LC: Are there more questions? (no). Dan what are the next steps? -DG: I can make a PR into the spec repo and proposal repos to adopt the new organization. The first step is to reorganize the spec repo and get the scripts setup, then reach out to the proposal champions to integrate up there. - -LC: You can put that list of work into the issue and we can distribute that work out. - -LC: Ralph has joined, do you want to talk about experimental stuff at all or next time? - -RS: I need more time before I present that. - -LC: Next thing on the agenda, we need to talk about releases. Someone is asking us to make citation easier using a tool called zenodo. For that to work we need to cut (GitHub) releases. Should we do this and when should we do them? It seems like we should do them when we do a snapshot. Does anyone have opinions on this? - -JB: Question about zenodo: what does that tool do? - -LC: It (??) DOI’s. I don’t know exactly why a DOI is important for a bibliography but its recommended over a URL when possible by the (APA?). The tool archives the data associated with the DOI, I believe. - -LC: Then we’ll start cutting releases with snapshots. We can do one release now to capture the current snapshot. I’ll work with the wasm cg chair to get zenodo configured for the repo. - -LC: Any other topics? (None) diff --git a/proposals/random/meetings/2021/WASI-01-14.md b/proposals/random/meetings/2021/WASI-01-14.md deleted file mode 100644 index 9ee3e0be7..000000000 --- a/proposals/random/meetings/2021/WASI-01-14.md +++ /dev/null @@ -1,75 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the January 14 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: January 14, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcement - 1. Pat will be changing branch name from `master` to `main` -1. Review of action items from previous meeting(s). - 1. Lin update on repository organization progress -1. Proposals and discussions - 1. Discussion: Testing guidelines for proposals - 1. _Sumbit a PR to add your agenda item here_ - -## Meeting Notes -### Attendees -Lin Clark -Josh Dolitsky -Dan Gohman -Pat Hickey -Sam Clegg -Casper Beyer -Mark McCaskey -Johnnie Birch -Andrew Brown -Yong He -Peter Engelbert -Peter Huene -Martin Duke -Till Schneidereit -Bogus Wolf - -For people taking notes, just type names; we’ll replace them with abbreviations before posting them publicly. - -**Pat Hickey:** Github is now rolling out features to allow for renaming git branches from “master” to “main”, including blob url redirection. It’s mostly automatic, but it does require people to do some changes locally to update. We’ll put the steps in the WASI github issue tracking this. - -Main topic: Testing. - -**Lin Clark:** - -The context here is WASI modularization -- breaking up the core WASI module into separate modules. - -Pat and Dan are working on a new witx mechanism for expressing dependencies between witx files, allowing modules to depend on each other. - -The main WASI repo will be the source of truth for stage-5 (standardized) proposals. - -Tests should include both the source, in high-level languages, and compiled wasm binaries. - -Things we still need to build: -A test runner -Tests. We’ll start with some tests from Wasmtime, and everyone can add tests. - - - diff --git a/proposals/random/meetings/2021/WASI-01-28.md b/proposals/random/meetings/2021/WASI-01-28.md deleted file mode 100644 index cab4dbd21..000000000 --- a/proposals/random/meetings/2021/WASI-01-28.md +++ /dev/null @@ -1,206 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the January 28 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: January 28, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's -your first time. The meeting is open to CG members only. - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. Lin Clark on WASI modularization milestone -1. Proposals and discussions - 1. Presentation: Update from Luke Wagner on handles and resources in interface types - 1. _Sumbit a PR to add your agenda item here_ - -## Meeting Notes -### Attendees -- Martin Duke, F5 -- Sam Clegg -- Dan Gohman -- Luke Wagner -- Mark McCaskey -- Lin Clark -- Dave Protasowski -- Alex Crichton -- Andrew Brown -- Mingqiu Sun -- Till Schneidereit -- Pat Hickey -- Josh Dolitsky -- Matt Butcher -- Ralph Squillace - -### Announcements -**Lin Clark:** We now have a [milestone for WASI modularization](https://github.com/WebAssembly/WASI/milestone/1). Will be using milestones more in the future. - -### Proposals and discussions -#### Presentation: Update from Luke Wagner on handles and resources in interface types [(Slides)](https://docs.google.com/presentation/d/1ikwS2Ps-KLXFofuS5VAs6Bn14q4LBEaxMjPfLj61UZE) - -**Luke Wagner:** Handles and resources. Have been working on this for a while with a number of y’all -Give background, motivating problems, and proposed solution -Not at all final, still working on a PR. Your feedback is most welcome - -IT gives WASI a bunch of value types -In addition to core basic types, a bunch of abbreviations -Don’t want to have to add core types -This lets us take a WASI function and use a bunch of high level types - -Plan of record for a while has been abstract types for file descriptors -Type imports builds on reference types -Reference types are unforgeable, better than ints - -How does this get virtualized? -Virtualization is a core value of WASI. You can implement with another WASI module -For this, we use module linking proposal - -What does it look like to write that virtualized WASI? (walk through) -Packed the file index into the reference, that’s efficient - -Type imports and exports are transparent by default -This is forgeable. That’s why that was take one - -Type imports has a private type definition -I would take abstract type and make it a private type definition -Private.get and private.new only works inside module that defined the type definition -These private types have to be boxed. -Actually no worse than the native implementation to have one level of indirection - -Two remaining problem areas: resource lifetimes and dynamic casting - -Resource lifetimes -How do resources get released? -Could reference count. -Problematic for a variety of reasons. -Not virtualizable. -Because of downsides, WASI resources have explicit destructor - -Virt WASI then looks like…. -What happens on double close or use-after-close? -Spectrum of options, none of them good -How do I efficiently support cross-instance resource sharing? -Not great options either -How can a WASI impl robustly clean up after clients are destroyed? -Could leak. -Want FDs to be closed when the instance goes away, just like OS process -A native WASI impl could do this, but not a virtualized one -How do instances even get different lifetimes? This is a next step, to add ability to dynamically create and destroy instances -Also problems around dynamic casting -E.g. when store n distinct DOM node types in a single table -Not supporting would be a kind of regression - -Dynamic casting breaks otherwise-static invariants -If there’s a run function and I pass a RO, is it possible for X to somehow do a write? -It would be nice to have that answer based only on the static type -Fix is to treat different imports as different things for purpose of dynamic cast -To fix this, you need a wrapping at some membrane/boundary -OK for core wasm, because that’s just a compiler target -But not ok for ecosystem - -When we’re virtualizingWASI we want: … -Is all of this just for virtualization? -Resources are not a uniquely WASI concern -We should treat WASI as an unprivileged set of library interfaces - -Proposal -Add a new interface type called handle -Handle is a value that can be copied -Refers to a resource -A resource is some entity with a lifetime. It can not be copied -So resource types are like abstract type, but only private option -Additionally resource type definitions can have an optional destructor -Resource creation and use is symmetric to private.new/get -Handles are semantically ref-counted and call the destructor when they get to 0 -That’s what gives virt WASI same privileges as native -Also possible to explicitly destroy handles, and references trap - -**Sam Clegg:** would need to be at WASI core? -**Luke Wagner:** So far everything in Interface Types - -**Pat Hickey:** Attenuation -**Luke Wagner:** I’ve gone back and forth. Have an idea in open questions - -**Luke Wagner:** High level summary of IT -They’re lazy copy operations -Need a way to box all interface types -Generally valuable because it solves interesting performance use cases -For handle values, creates a root that creates the stack -That makes it so handles can outlive stack frame - -Once I have a reference, it can be cast -Will always trap if cast to differently privileged - -IT gives us the boundary/membrane where to wrap - -Proposal summary -Additions -New types -New definition -New instructions -Extend rtt.canon - -Problems: -Robust and efficient handling of double-free/use-after-free -…. - -Open Questions -Add abstract subtyping? -Should we have specialized versions of handle (e.g. a strong handle, unique handle) - -Next steps -Need to give lifetimes to instances -Can instances just be resources? -Could implement WASI command pattern in the toolchain rather than host magic - -**Sam Clegg:** What happens if you destroy a resource and another module still has a copy - -**Luke Wagner:** It will have a handle. That handle is then in a null state. When you try to use the handle, it would trap probably at resource.get - -**Sam Clegg:** So the trap would happen in the callee - -**Luke Wagner:** That’s where we might want to have a strong handle where no one could pass you an invalid handle. It’s an open question - -**Ralph Squillace:** For what it’s worth, I’ve been spinning around Pat’s question and going back to DCE-RPC. Believe that you should make or signal a strong decision about shared resources. - -**Luke Wagner:** That’s one of the reasons I like unique, because then when I give you a handle I’m explicitly saying I dont’ still have it. I guess that’s an argument for both unique and strong - -**Ralph Squillace:** Having the ability to make those choices is what comes to mind. If I choose a convention, I can signal it to others. Previous technologies tried to let people do it without signaling capabilities - -**Luke Wagner:** Would a summary be that you’re in favor of those two types of handles - -**Ralph Squillace:** I would say those two handles express two slices of the problem space. I wouldn’t say that I’ve thought through other possible types. - -**Luke Wagner:** Your’e right, I was trying to survey the literature and there are like 20 types - -**Ralph Squillace:** Even if you don’t have strong type, at least you can trap. Maybe that’s the first step. - -**Luke Wagner:** Hierarchy, undefined is worst, trap is better, statically preventing is best - -**Sam Clegg:** These handles are at IT types and at core go to reference. So references can be copied - -**Luke Wagner:** Once you exclusively use IT, there’s no back door - -**Sam Clegg:** Any incremental steps? - -**Luke Wagner:** In some sense, witx already has handle - -**Lin Clark** proposes that we make that the main topic for next meeting - diff --git a/proposals/random/meetings/2021/WASI-02-11.md b/proposals/random/meetings/2021/WASI-02-11.md deleted file mode 100644 index c18c4b8fa..000000000 --- a/proposals/random/meetings/2021/WASI-02-11.md +++ /dev/null @@ -1,118 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the February 11 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: February 11, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. Discussion: What are the next steps in adapting WASI to use Interface Types handles and resources? - 1. _Sumbit a PR to add your agenda item here_ - -## Notes -### Attendees -Pat Hickey -Andrew Brown -Sergey Rubanov -Lin Clark -Mark McCaskey -Till Schneidereit -Dan Gohman -Josh Dolitsky -Mingqiu Sun -Ralph Squillace -Nicholas -Radu Matei -Matt Fisher -Johnnie Birch -Luke Wagner - -**Lin Clark:** Are there any announcements? -(none) - -**Lin Clark:** Lets talk about how we’re going to move from this version of WASI to a new version that uses handles - -**Dan Gohman:** Witx has been designed to anticipate interface types. It has String and Handle types. These are pretty close to the ones in interface types - PR 391 takes things to the next level and evolves the rest of the witx types towards the interface types. Going forward we need to get rid of the witx pointer and get buffers to work the way they will in interface types, but we’re still waiting to hear from interface types the final word on how those will work. See Interface Types issue 68. Our job on the witx side is to evolve into the Interface Types buffer types. Without waiting we can add support for strings and return types and lower them into the existing C ABI that WASI programs use. - -**Dan Gohman:** Another piece is WASI modularization. It has been in progress for a while but several pieces are coming together. Issue 378. Describes a more granular include mechanism than witx uses right now - import a symbol from a module, rather than import a file. - -**Dan Gohman:** The next two big pieces, which we can address in detail in the future: How do you pass handles into programs? Currently there is a table with preopens in it, but interface types is going to give us new mechanisms that are better than the preopen concept. - -**Dan Gohman:** The last piece is defining new abstractions. wasi PR 240 describes how to merge the send and recv on sockets with read and write on files. We can generalize part of files and sockets into a concept of I/O streams. In interface types you’ll have the vocabulary to ask for e.g. a stream you can write to, without knowing or caring that its backed by a socket or file or pipe etc. What is the noun that you use in function signatures to describe an I/O Stream? Beyond I/O Streams there’s non-streaming operations on files which don’t work on sockets or pipes - pread/pwrite - there’s a place for an I/O object with non-stream personality as well, an array of bytes or a we can call it a dynamic array because it can be resized. There will be other concepts as well - key-value stores, windowed IO with buffers... At the moment the nascent WASI I/O proposal will evolve to develop these ideas. There will still be files, and then a function that gives you a stream from a file. Files are going to be required to interop with existing systems, but we can push people towards interfaces that don’t tie them to the complications of those existing systems, particularly file semantics are very difficult to compose but streams are. This will help us enable shared-nothing linking of modules - we don’t want modules to have to share a filesystem to talk to each other. Questions? - -**Ralph Squillace:** What kinds of objections to this direction do you anticipate? - -**Dan Gohman:** This is going off the path of POSIX. Existing applications and programming languages will be more work to port to I/O streams than having us port libc and standard libraries to WASI. We have ideas for making the standard io operations work on top of I/O streams - you can treat an i/o stream as a libc FILE if you only ever read and write from it, other operations give an error. - -**Ralph Squillace:** The philosophical discussion is about how you weigh the objectives of different applications moving to WASI - some will have to adapt specific POSIX-isms to WASI, where does the work of porting existing code break down - does the code stay in WASM and not use WASI, have its own custom runtime - or does it move to WASI in the coherent way that resolves the semantic differences. I don’t personally see myself trying to port an existing huge monolithic application to WASI, whereas I do see myself working on libraries to make them work in WASI. - -**Lin Clark:** How much is WASI filesystem still going to allow porting POSIX applications? - -**Dan Gohman:** It will allow it. Its a question of priorities rather than absolutes. WASI today runs plenty of interesting POSIX code that doesnt do things like fork(2), WASI filesystem is going to still be there for these applications to use. But we don’t want that to be part of the default for WASI, we want to encourage applications to use simpler concepts that don’t imply a whole filesystem. I want to build tooling that bridges the gap between the shared-nothing-linking space and making big applications work. - -**Till Schneidereit:** We can look at this in terms of layering - there is a core of WASI that may not apply to every use case but you can virtualize many of the other needs on top of it. You can add a filesystem ion top of the core, in many cases, and let applications that need it use it. - -**Dan Gohman:** In terms of migration from where WASI is today to this ideal system - the WASI I/O abstractions can be worked on now, we have witx where we need it. We can flesh out exactly how streams and dynamic arrays work today. - -**Dan Gohman:** Another aspect is portability. I’ve been working on support for WASI on Windows vs Unix the last few months - there are so many differences between those platforms, the semantics of filesystems is radically different and there’s no portability in many cases (its too expensive to bridge them). The WASI I/O abstractions can be designed to hide all of the non-portable parts of filesystems. We can get away from having to specify “what does windows do here” and instead specify the things an application actually needs. - -**Ralph Squillace:** Layering will require thought. - -**Pat Hickey:** The customers we have writing applications right now aren’t concerned with the differences between the filesystem guarantees on linux vs windows, they care about http requests and responses. If we have I/O abstractions that unify the way http bodies work with the way certain aspects of the filesystem work, that is better for the applications we care about. - -**Till Schneidereit:** There are lots of use cases that work with streaming, which has traditionally been a file or a socket, but with abstractions that are hard to generalize. My interpretation of what you were just saying is that if we had a way to have a cleaner system that didn’t have that incidental platform dependence, it would be much easier to build code that works across these very different environments. We have all these applications that are popping up that are very different. Ideally we have a layer that doesn’t care about host differences, and then the layer that cares about that. What we do is just one specific example of that. Don’t want to optimize for old use cases, but all of the new novel ones that are coming about. - -**Radu Matei:** Is the assumption that wasi-filesystem will be developed in parallel? - -**Dan Gohman:** Yes, WASI-filesystem will continue, and wasi-io will be a peer. - -**Ralph Squillace:** Drawing older threads in, what about BSD sockets PR. - -**Dan Gohman:** The contributor who created that hasn’t been active, but I expect that will fit into the system in the same way as wasi-fs. You could get a stream. Networking is a complex topic and I dont’ want to simplify, but the first step will be to take sockets and say the socket gives you a stream that you can read, a stream you can write, and bi-directional r/w. - -Async is a subtlety that we’re leaving out. We can say that async is an orthogonal concern. We expect the Wasm platform will give us better answers over time. But the fundamental concepts of I/O are independent of whether you block that I/O. - -**Lin Clark:** Any other thoughts/comments - -**Luke Wagner:** I have a hypothesis I want to test. Why are people going to want to use wasm outside of a browser? Some people think it’s great because of ISA. We don’t think that’s a great motivator. We think running guest code in latency sensitive and low trust scenarios is the motivator. Things like routers ____ would be host APIs. The libraries would be wasm. These problematic cases don’t have a high value reason to be ported to Wasm. - -**Ralph Squillace:** I understand where you’re coming from. I don’t see WASI as a monolithic process sandbox. I do think that the idea about the sweet spot is right. I’m not a big believer in the thought that the world’s code is going to all be running on WASI. But I think it’s worth consideration how much of the world’s knowledge can be run as WASI. Shouldn’t wall off for all time, but I think the way that Dan laid out the direction, it lets us start with the sweet spot and either layer the others, or add support to WASI later on. I would hate to frame the boundary ruling out knowledge transfer. - -**Luke Wagner:** I agree with your points, so the layering and virtualization are also motivated by that. - -**Dan Gohman:** I can add one thing. Thinking of lib-c, and lots of languages have lib-c like std lib: under the covers, something that people are using as a file could be represented by streams. We can make that work under the covers. We could talk about how that will exactly work. But this is the framework. We can make porting easier by allowing you to use streams by allowing you to use files, but discourage from using file stat and depending on i node. - -**Andrew Brown:** It feels to me that filesystem should be in phase 3 or 4. How do these changes affect moving those to later stages - -**Dan Gohman:** That’s a great question. Wasi-fs is waiting to figure out it’s place. This conversation moves that forward. Understanding that wasi-fs won’t attempt to be abstracting over all hosts, wasi-io does that, and accepting that’s ok means that wasi-fs can probably move to phase 3 at this point. - -**Till Schneidereit:** I think the better way to put it is that it’s not an either/or, we don’t need to make it completely host specific, but let’s find a balance that’s actually viable. - -**Radu Matei:** do we have a document? - -**Dan Gohman:** Will be writing that up. Wanted to introduce here first. Will write up wasi-io ideas soon - -**Pat Hickey:** One blocker to wasi-fs advancing. The filesystem has cloud ABI system of rights. Need to work out what to do with that. diff --git a/proposals/random/meetings/2021/WASI-02-25.md b/proposals/random/meetings/2021/WASI-02-25.md deleted file mode 100644 index 2bc89278a..000000000 --- a/proposals/random/meetings/2021/WASI-02-25.md +++ /dev/null @@ -1,131 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the February 25 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: February 25, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. -Installation is required, see the calendar invite. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. Discussion: Better error handling in WASI - 1. _Sumbit a PR to add your agenda item here_ - -## Notes -### Attendees -- Lin Clark -- Dan Gohman -- Andrew Brown -- Johnnie Birch -- Sergey Rubanov -- Mark McCaskey -- Peter Huene -- Radu Matei -- Luke Wagner -- Ralph Squillace -- Pat Hickey -- Till Schneidereit -- Mingqiu Sun -- David Piepgrass -- Yong He - -**Dan Gohman:** Overview—errors handled like POSIX with single enum of errno. More APIs in WASI, not feasible to have a single errno enum. Also not reasonable to have a single error type. My expectation for errors is that every library will define its own error types. IT will make it possible for us to define a variant type like Rust’s Result. Does that shape of things make sense? - -**Andrew Brown:** Makes sense to me. Errors for wasi-nn are just a totally different sphere than files. - -**Dan Gohman:** wasi-libc will still have errno. Errno only describes small set of system errors - -**Andrew Brown:** Right now wasi-nn has own kind of error types. What’s changing? Will we just change witx and wiggle - -**Dan Gohman:** It’s not a fundamental change. We’re just making what wasi-nn is doing explicit. We’ll also be getting new features from IT which will describe what you’re doing in a better way. Enum with either success or failure, maybe called Expected. - -**Andrew Brown:** I think Alex has already made this change. - -**Dan Gohman:** Yeah, we wanted to give people a heads up about this plan. - -**Andrew Brown:** One question about the future—will this expected type, in the failure case will you be able to pass things that aren’t just an integer, like strings and stuff - -**Dan Gohman:** There is no master plan, but I expect the basic mech will be that you can have any type for errors, with full expressiveness of IT. One caveat, how do we want to handle strings? English isn’t appropriate for all envs. Will need to apply more design thought. Underlying tool won’t have a restriction against that, though - -**Andrew Brown:** Agreed. On thing I’ve found with wasi-nn is just having an errno isn’t enough - -**Dan Gohman:** Agreed, and that’s a place where tooling might be able to help. We can go down the path of thinkking of enums not just as ints but high-level types - -**Luke Wagner:** Along that line, one thing that has bugged me about classical error codes, is sometimes you want to use them for conditionals, and sometimes you just want to debug. Two level nesting of variants? Top level “You called it wrong” and second level provides detail of how you called it wrong. - -**Dan Gohman:** Yes, let’s do that. I think that’s totally a good idea to do. Another idea, in POSIX they have system calls that are never supposed to crash. In WASI, we don’t need to be as strict. If you pass a bad pointer into a syscall, it could trap. - -**Pat Hickey:** Yeah, that’s also a kind of a concession for virtualization. Awfully convenient for that - -**Dan Gohman:** So that’s the basic vision of it. Any more questions on that level of detail? One thing this does mean, we won’t have unified error handling across WASI. Another thing, we want to go through the APIs and figure out what errors things like the clock apis can return. In practice, the only thing that can fail in a clock is failing to get a clock. Wasi-filesystem will probably be where most of the error codes land. Simplifying property across different APIs. Don’t overload error codes to represent similar but not the same errors. Exception handling is coming. A possible approach is to use unwinding. I think that for WASI, errors work better. If languages want to use unwinding, they can expect errors and unwind. I think using variants instead of exceptions will work well for us. - -**Pat Hickey:** The one thing I’ll call out is that proc_exit should be implemented as unwind. - -**Dan Gohman:** That’s true. I’m going to claim that proc_exit is special. It might be something that we unwind and then turn into a clean exit status. Then the unwinding becomes an implementation detail. That wouldn’t be a thing that leaks across module boundaries. Often not a good idea for libraries to call exit directly. - -**Pat Hickey:** So we basically get rid of proc_exit as a library function - -**Dan Gohman:** So I think what we want to say is return type from main is an error type. - -**Pat Hickey:** Yeah, that way we keep types all the way down and don’t turn into bare integer. - -**Dan Gohman:** Yeah, so 3 error types. Return values, unwinding, and trapping. Trapping is for program has a bug. Maybe sometimes when return values. ____. And we’ll use unwinding across language boundaries. - -**Pat Hickey:** Unlike with errors, we can’t invent new ways to trap. - -**Dan Gohman:** Although I wonder if there’s something we could do there. I wonder if it makes sense for wasm to be able to trap with extra info. - -**Luke Wagner:** Or there could be a WASI function that says “I’m going to trap, but you can provide me with an error to print” - -**Pat Hickey:** You can imagine that a malicious module would do that - -**Luke Wagner:** They can do that already. We don’t want wasm to casually be able to catch traps. Because at a very fine granularity. But having a blast zone that allows a set to go away without taking down the rest. I think that belongs at some point of time in wasm’s future. - -**Dan Gohman:** yeah, if we add those mechanisms, then programmer errors could just be trapped. - -**Lin Clark:** Best way to collaborate - -**Dan Gohman:** Once we’ve fully modularized, each module will audit their own errors. The wasi-libc work will start after the next snapshot which includes those changes. - -**Andrew Brown:** Question about sockets. Who’s driving that - -**Dan Gohman:** Haven’t heard from them. Don’t know what their status is. Expect that if they don’t respond soon we’ll find someone else - -**Andrew Brown:** Who was originally driving it? - -**Dan Gohman:** Somebody working for a company called ____. The person who filed it is the person working there. - -**Andrew Brown:** Radu, was someone on your side interested in that? - -**Radu Matei:** We should probably have a chat at some point. How will that relate to these changes? - -**Dan Gohman:** Sockets are the other major user of errno. I expect sockets will have their own errno, and then wasi-libc will have some way to concatenate errnos and turn it into appropriate POSIX errno space. I think that’s basically it. - -**Radu Matei:** How about IO Streams? - -**Dan Gohman:** We haven’t talked about how it’s going to work with libc. I expect from a POSIX point of view, we might have a bunch of different error codes in wasi-io. Have been talking about wasi-io not reporting very specific errors because it leaks information. We aren’t necessarily going to want to return a lot of detail there either. - -**Ralph Squillace:** I think we want to try to figure out, if we help pick up the PR, what’s the best way to move forward without having to reimplement too much. Will reach out to original champion. - -**Dan Gohman:** I see wasi-filesystem and wasi-sockets being peers. At a good place for them to work the same way. diff --git a/proposals/random/meetings/2021/WASI-03-11.md b/proposals/random/meetings/2021/WASI-03-11.md deleted file mode 100644 index f6170a738..000000000 --- a/proposals/random/meetings/2021/WASI-03-11.md +++ /dev/null @@ -1,32 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the March 11 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: March 11, 17:00-18:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. Presentation: Passing capabilities into programs with Typed Main (Dan Gohman) - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/2021/WASI-03-25.md b/proposals/random/meetings/2021/WASI-03-25.md deleted file mode 100644 index a35f4e17e..000000000 --- a/proposals/random/meetings/2021/WASI-03-25.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the March 25 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: March 25, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/2021/WASI-04-08.md b/proposals/random/meetings/2021/WASI-04-08.md deleted file mode 100644 index 35d2286f9..000000000 --- a/proposals/random/meetings/2021/WASI-04-08.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the April 8 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: April 8, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/2021/WASI-04-22.md b/proposals/random/meetings/2021/WASI-04-22.md deleted file mode 100644 index 722d57ca0..000000000 --- a/proposals/random/meetings/2021/WASI-04-22.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the April 22 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: April 22, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/2021/WASI-05-06.md b/proposals/random/meetings/2021/WASI-05-06.md deleted file mode 100644 index da5cf7cbb..000000000 --- a/proposals/random/meetings/2021/WASI-05-06.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the May 6 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: May 6, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/2021/WASI-05-20.md b/proposals/random/meetings/2021/WASI-05-20.md deleted file mode 100644 index c91e5777f..000000000 --- a/proposals/random/meetings/2021/WASI-05-20.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the May 20 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: May 20, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/2021/WASI-06-03.md b/proposals/random/meetings/2021/WASI-06-03.md deleted file mode 100644 index 89487782a..000000000 --- a/proposals/random/meetings/2021/WASI-06-03.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the June 3 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: June 3, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/2021/WASI-06-17.md b/proposals/random/meetings/2021/WASI-06-17.md deleted file mode 100644 index 583b7f02b..000000000 --- a/proposals/random/meetings/2021/WASI-06-17.md +++ /dev/null @@ -1,31 +0,0 @@ -![WASI logo](/WASI.png) - -## Agenda for the June 17 video call of WASI Subgroup - -- **Where**: zoom.us -- **When**: June 17, 16:00-17:00 UTC -- **Location**: *link on calendar invite* -- **Contact**: - - Name: Lin Clark - - Email: lclark@fastly.com - -### Registration - -None required if you've attended before. Email Lin Clark to sign up if it's your first time. - -The meeting is open to CG members only. You can [join the CG here](https://www.w3.org/community/webassembly/). - -## Logistics - -The meeting will be on a zoom.us video conference. - -## Agenda items - -1. Opening, welcome and roll call - 1. Please help add your name to the meeting notes. - 1. Please help take notes. - 1. Thanks! -1. Announcements - 1. _Sumbit a PR to add your announcement here_ -1. Proposals and discussions - 1. _Sumbit a PR to add your agenda item here_ diff --git a/proposals/random/meetings/README.md b/proposals/random/meetings/README.md deleted file mode 100644 index a9fcf2e21..000000000 --- a/proposals/random/meetings/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# WASI meetings - -Meetings of the WASI Subgroup of the W3C WebAssembly Community Group (CG) follow -[the process of the CG](https://github.com/WebAssembly/meetings). - -## Meetings - -### 2019 - - * [WASI May 2nd video call](2019/WASI-05-02.md) - * [WASI May 16th video call](2019/WASI-05-16.md) - * [WASI May 30th video call](2019/WASI-05-30.md) - * no meeting on 06-13 due to overlap with the [CG meeting](https://github.com/WebAssembly/meetings/blob/master/2019/CG-06.md) - * [WASI June 27th video call](2019/WASI-06-27.md) - * [WASI July 18th video call](2019/WASI-07-18.md) - * [WASI August 15th video call](2019/WASI-08-15.md) - * [WASI August 30th video call](2019/WASI-08-30.md) - * [WASI September 12th video call](2019/WASI-09-12.md) - * [WASI September 26th video call](2019/WASI-09-26.md) - * [WASI October 15th in-person meeting](2019/WASI-10-15.md) - * [WASI October 24th video call](2019/WASI-10-24.md) - * [WASI November 7th video call](2019/WASI-11-07.md) - * [WASI November 21st video call](2019/WASI-11-21.md) - * [WASI December 5th video call](2019/WASI-12-05.md) - * [WASI December 19th video call](2019/WASI-12-19.md) - -### 2020 - - * [WASI January 16th video call](2020/WASI-01-16.md) - * [WASI February 27th video call](2020/WASI-02-27.md) - * [WASI March 12th video call](2020/WASI-03-12.md) - * [WASI March 26th video call](2020/WASI-03-26.md) - * [WASI April 9th video call](2020/WASI-04-09.md) - * [WASI May 7th video call](2020/WASI-05-07.md) - * [WASI May 21st video call](2020/WASI-05-21.md) - * [WASI June 4th video call](2020/WASI-06-04.md) - * [WASI July 2nd video call](2020/WASI-07-02.md) - * [WASI July 16th video call](2020/WASI-07-16.md) - * [WASI July 30th video call](2020/WASI-07-30.md) - * [WASI August 27th video call](2020/WASI-08-27.md) - * [WASI September 10th video call](2020/WASI-09-10.md) - * [WASI September 21st video call](2020/WASI-09-21.md) - * [WASI October 8th video call](2020/WASI-10-08.md) - * [WASI October 22nd video call](2020/WASI-10-22.md) - * [WASI November 19th video call](2020/WASI-11-19.md) - * [WASI December 3rd video call](2020/WASI-12-03.md) - - ### 2021 - * [WASI January 14th video call](2021/WASI-01-14.md) - * [WASI January 28th video call](2021/WASI-01-28.md) - * [WASI February 11th video call](2021/WASI-02-11.md) - * [WASI February 25th video call](2021/WASI-02-25.md) - * [WASI March 11th video call](2021/WASI-03-11.md) - * [WASI March 25th video call](2021/WASI-03-25.md) - * [WASI April 8th video call](2021/WASI-04-08.md) - * [WASI April 22nd video call](2021/WASI-04-22.md) - * [WASI May 6th video call](2021/WASI-05-06.md) - * [WASI May 20th video call](2021/WASI-05-20.md) - * [WASI June 3rd video call](2021/WASI-06-03.md) - * [WASI June 17th video call](2021/WASI-06-17.md) - \ No newline at end of file diff --git a/proposals/random/phases/README.md b/proposals/random/phases/README.md deleted file mode 100644 index 9f66686bd..000000000 --- a/proposals/random/phases/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# WASI's ephemeral/snapshot/old Process - -For the standardization process, WASI overall uses a [process] -modeled after the WebAssembly CG's phased process. - -For development of features in Phase 2 and later of that process, WASI -has a ephemeral/snapshot/old process, which is designed to allow -for a balance between the need for stability to allow people to build -compatible implementations, libraries, and tools and gain implementation -experience, and the need for proposals to evolve. - -[process]: https://github.com/WebAssembly/WASI/blob/main/docs/Process.md - -## The ephemeral/snapshot/old Phases - -- [`ephemeral`](ephemeral): The development staging area. New API - proposals API-changing fixes to existing APIs should be submitted - as Pull Requests making changes to this directory. This directory - provides no API stability or versioning. APIs in this directory use - API module names starting with `wasi_ephemeral_`. - -- [`snapshot`](snapshot): Usable APIs. APIs in `ephemeral` will be - occasionally snapshotted and promoted into `snapshot`, with approval - from the Subgroup, considering the overall suitability of the APIs - themselves, their documentation, test coverage, and availability of - polyfills when appropriate. Once merged, the API modules will be - considered stable, though they may be superseded by newer versions. - Proposals to promote specific APIs should be submitted as Pull Requests - that: - 1. `git mv` contents of `phases/snapshot/` to - `phases/old/snapshot_{old_snapshot_number}`. - 2. `cp -R` contents of `phases/ephemeral/` into `phases/snapshot/`. - 3. Rename files copied into `phases/snapshot/` to substitute `ephemeral` - for `snapshot` in file names. Append the new snapshot number to each - name. - 4. Update module names given in `.witx` files according to the previous - step. - 5. Update tests in `tools/witx/tests/wasi.rs` to point at new snapshot, and - add a test pointing at the just-archived snapshot under `old`. - 6. Optionally, under `phases/old/snapshot_{old_snapshot_number}, add - polyfills for superceded APIs using the new APIs. - - - Pull Requests may also add additional tests, documentation, or - polyfills for existing `snapshot` APIs. - -- [`old`](old): When APIs in `snapshot` spec are replaced by new - versions, the old API modules are moved to the `old` directory. When - possible, `old` APIs may be accompanied by polyfill modules which - implement their API in terms of newer versions of the API. diff --git a/proposals/random/phases/ephemeral/docs.md b/proposals/random/phases/ephemeral/docs.md deleted file mode 100644 index f29d401c4..000000000 --- a/proposals/random/phases/ephemeral/docs.md +++ /dev/null @@ -1,2562 +0,0 @@ -# Types -## `size`: `usize` -An array size. - -Note: This is similar to `size_t` in POSIX. - -Size: 4 - -Alignment: 4 - -## `filesize`: `u64` -Non-negative file size or length of a region within a file. - -Size: 8 - -Alignment: 8 - -## `timestamp`: `u64` -Timestamp in nanoseconds. - -Size: 8 - -Alignment: 8 - -## `clockid`: `Variant` -Identifiers for clocks. - -Size: 4 - -Alignment: 4 - -### Variant cases -- `realtime` -The clock measuring real time. Time value zero corresponds with -1970-01-01T00:00:00Z. - -- `monotonic` -The store-wide monotonic clock, which is defined as a clock measuring -real time, whose value cannot be adjusted and which cannot have negative -clock jumps. The epoch of this clock is undefined. The absolute time -value of this clock therefore has no meaning. - -## `errno`: `Variant` -Error codes returned by functions. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX. - -Size: 2 - -Alignment: 2 - -### Variant cases -- `success` -No error occurred. System call completed successfully. - -- `2big` -Argument list too long. - -- `access` -Permission denied. - -- `addrinuse` -Address in use. - -- `addrnotavail` -Address not available. - -- `afnosupport` -Address family not supported. - -- `again` -Resource unavailable, or operation would block. - -- `already` -Connection already in progress. - -- `badf` -Bad file descriptor. - -- `badmsg` -Bad message. - -- `busy` -Device or resource busy. - -- `canceled` -Operation canceled. - -- `child` -No child processes. - -- `connaborted` -Connection aborted. - -- `connrefused` -Connection refused. - -- `connreset` -Connection reset. - -- `deadlk` -Resource deadlock would occur. - -- `destaddrreq` -Destination address required. - -- `dom` -Mathematics argument out of domain of function. - -- `dquot` -Reserved. - -- `exist` -File exists. - -- `fault` -Bad address. - -- `fbig` -File too large. - -- `hostunreach` -Host is unreachable. - -- `idrm` -Identifier removed. - -- `ilseq` -Illegal byte sequence. - -- `inprogress` -Operation in progress. - -- `intr` -Interrupted function. - -- `inval` -Invalid argument. - -- `io` -I/O error. - -- `isconn` -Socket is connected. - -- `isdir` -Is a directory. - -- `loop` -Too many levels of symbolic links. - -- `mfile` -File descriptor value too large. - -- `mlink` -Too many links. - -- `msgsize` -Message too large. - -- `multihop` -Reserved. - -- `nametoolong` -Filename too long. - -- `netdown` -Network is down. - -- `netreset` -Connection aborted by network. - -- `netunreach` -Network unreachable. - -- `nfile` -Too many files open in system. - -- `nobufs` -No buffer space available. - -- `nodev` -No such device. - -- `noent` -No such file or directory. - -- `noexec` -Executable file format error. - -- `nolck` -No locks available. - -- `nolink` -Reserved. - -- `nomem` -Not enough space. - -- `nomsg` -No message of the desired type. - -- `noprotoopt` -Protocol not available. - -- `nospc` -No space left on device. - -- `nosys` -Function not supported. - -- `notconn` -The socket is not connected. - -- `notdir` -Not a directory or a symbolic link to a directory. - -- `notempty` -Directory not empty. - -- `notrecoverable` -State not recoverable. - -- `notsock` -Not a socket. - -- `notsup` -Not supported, or operation not supported on socket. - -- `notty` -Inappropriate I/O control operation. - -- `nxio` -No such device or address. - -- `overflow` -Value too large to be stored in data type. - -- `ownerdead` -Previous owner died. - -- `perm` -Operation not permitted. - -- `pipe` -Broken pipe. - -- `proto` -Protocol error. - -- `protonosupport` -Protocol not supported. - -- `prototype` -Protocol wrong type for socket. - -- `range` -Result too large. - -- `rofs` -Read-only file system. - -- `spipe` -Invalid seek. - -- `srch` -No such process. - -- `stale` -Reserved. - -- `timedout` -Connection timed out. - -- `txtbsy` -Text file busy. - -- `xdev` -Cross-device link. - -- `notcapable` -Extension: Capabilities insufficient. - -## `rights`: `Record` -File descriptor rights, determining which actions may be performed. - -Size: 8 - -Alignment: 8 - -### Record members -- `fd_datasync`: `bool` -The right to invoke `fd_datasync`. -If `path_open` is set, includes the right to invoke -`path_open` with [`fdflags::dsync`](#fdflags.dsync). - -Bit: 0 - -- `fd_read`: `bool` -The right to invoke `fd_read` and `sock_recv`. -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. - -Bit: 1 - -- `fd_seek`: `bool` -The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). - -Bit: 2 - -- `fd_fdstat_set_flags`: `bool` -The right to invoke `fd_fdstat_set_flags`. - -Bit: 3 - -- `fd_sync`: `bool` -The right to invoke `fd_sync`. -If `path_open` is set, includes the right to invoke -`path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - -Bit: 4 - -- `fd_tell`: `bool` -The right to invoke `fd_seek` in such a way that the file offset -remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to -invoke `fd_tell`. - -Bit: 5 - -- `fd_write`: `bool` -The right to invoke `fd_write` and `sock_send`. -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. - -Bit: 6 - -- `fd_advise`: `bool` -The right to invoke `fd_advise`. - -Bit: 7 - -- `fd_allocate`: `bool` -The right to invoke `fd_allocate`. - -Bit: 8 - -- `path_create_directory`: `bool` -The right to invoke `path_create_directory`. - -Bit: 9 - -- `path_create_file`: `bool` -If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). - -Bit: 10 - -- `path_link_source`: `bool` -The right to invoke `path_link` with the file descriptor as the -source directory. - -Bit: 11 - -- `path_link_target`: `bool` -The right to invoke `path_link` with the file descriptor as the -target directory. - -Bit: 12 - -- `path_open`: `bool` -The right to invoke `path_open`. - -Bit: 13 - -- `fd_readdir`: `bool` -The right to invoke `fd_readdir`. - -Bit: 14 - -- `path_readlink`: `bool` -The right to invoke `path_readlink`. - -Bit: 15 - -- `path_rename_source`: `bool` -The right to invoke `path_rename` with the file descriptor as the source directory. - -Bit: 16 - -- `path_rename_target`: `bool` -The right to invoke `path_rename` with the file descriptor as the target directory. - -Bit: 17 - -- `path_filestat_get`: `bool` -The right to invoke `path_filestat_get`. - -Bit: 18 - -- `path_filestat_set_size`: `bool` -The right to change a file's size. -If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). -Note: there is no function named `path_filestat_set_size`. This follows POSIX design, -which only has `ftruncate` and does not provide `ftruncateat`. -While such function would be desirable from the API design perspective, there are virtually -no use cases for it since no code written for POSIX systems would use it. -Moreover, implementing it would require multiple syscalls, leading to inferior performance. - -Bit: 19 - -- `path_filestat_set_times`: `bool` -The right to invoke `path_filestat_set_times`. - -Bit: 20 - -- `path_permissions_set`: `bool` -The right to invoke `path_permissions_set`. - -Bit: 21 - -- `fd_filestat_get`: `bool` -The right to invoke `fd_filestat_get`. - -Bit: 22 - -- `fd_filestat_set_size`: `bool` -The right to invoke `fd_filestat_set_size`. - -Bit: 23 - -- `fd_filestat_set_times`: `bool` -The right to invoke `fd_filestat_set_times`. - -Bit: 24 - -- `fd_permissions_set`: `bool` -The right to invoke `fd_permissions_set`. - -Bit: 25 - -- `path_symlink`: `bool` -The right to invoke `path_symlink`. - -Bit: 26 - -- `path_remove_directory`: `bool` -The right to invoke `path_remove_directory`. - -Bit: 27 - -- `path_unlink_file`: `bool` -The right to invoke `path_unlink_file`. - -Bit: 28 - -- `poll_fd_readwrite`: `bool` -If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). -If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). - -Bit: 29 - -- `sock_shutdown`: `bool` -The right to invoke `sock_shutdown`. - -Bit: 30 - -## `fd`: `Handle` -A file descriptor handle. - -Size: 4 - -Alignment: 4 - -### Supertypes -## `iovec`: `Record` -A region of memory for scatter/gather reads. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `Pointer` -The address of the buffer to be filled. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be filled. - -Offset: 4 - -## `ciovec`: `Record` -A region of memory for scatter/gather writes. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `ConstPointer` -The address of the buffer to be written. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be written. - -Offset: 4 - -## `iovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `ciovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `filedelta`: `s64` -Relative offset within a file. - -Size: 8 - -Alignment: 8 - -## `whence`: `Variant` -The position relative to which to set the offset of the file descriptor. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `set` -Seek relative to start-of-file. - -- `cur` -Seek relative to current position. - -- `end` -Seek relative to end-of-file. - -## `dircookie`: `u64` -A reference to the offset of a directory entry. - -Size: 8 - -Alignment: 8 - -### Constants -- `start` - -## `dirnamlen`: `u32` -The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). - -Size: 4 - -Alignment: 4 - -## `inode`: `u64` -File serial number that is unique within its file system. - -Size: 8 - -Alignment: 8 - -## `filetype`: `Variant` -The type of a file descriptor or file. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `unknown` -The type of the file descriptor or file is unknown or is different from any of the other types specified. - -- `block_device` -The file descriptor or file refers to a block device inode. - -- `character_device` -The file descriptor or file refers to a character device inode. - -- `directory` -The file descriptor or file refers to a directory inode. - -- `regular_file` -The file descriptor or file refers to a regular file inode. - -- `socket_dgram` -The file descriptor or file refers to a datagram socket. - -- `socket_stream` -The file descriptor or file refers to a byte-stream socket. - -- `symbolic_link` -The file refers to a symbolic link inode. - -- `fifo` -The file descriptor or file refers to a FIFO. - -## `dirent`: `Record` -A directory entry. - -Size: 24 - -Alignment: 8 - -### Record members -- `d_next`: [`dircookie`](#dircookie) -The offset of the next directory entry stored in this directory. - -Offset: 0 - -- `d_ino`: [`inode`](#inode) -The serial number of the file referred to by this directory entry. - -Offset: 8 - -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. - -Offset: 16 - -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. - -Offset: 20 - -## `advice`: `Variant` -File or memory access pattern advisory information. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `normal` -The application has no advice to give on its behavior with respect to the specified data. - -- `sequential` -The application expects to access the specified data sequentially from lower offsets to higher offsets. - -- `random` -The application expects to access the specified data in a random order. - -- `willneed` -The application expects to access the specified data in the near future. - -- `dontneed` -The application expects that it will not access the specified data in the near future. - -- `noreuse` -The application expects to access the specified data once and then not reuse it thereafter. - -## `fdflags`: `Record` -File descriptor flags. - -Size: 2 - -Alignment: 2 - -### Record members -- `append`: `bool` -Append mode: Data written to the file is always appended to the file's end. - -Bit: 0 - -- `dsync`: `bool` -Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - -Bit: 1 - -- `nonblock`: `bool` -Non-blocking mode. - -Bit: 2 - -- `rsync`: `bool` -Synchronized read I/O operations. - -Bit: 3 - -- `sync`: `bool` -Write according to synchronized I/O file integrity completion. In -addition to synchronizing the data stored in the file, the implementation -may also synchronously update the file's metadata. - -Bit: 4 - -## `fdstat`: `Record` -File descriptor attributes. - -Size: 24 - -Alignment: 8 - -### Record members -- `fs_filetype`: [`filetype`](#filetype) -File type. - -Offset: 0 - -- `fs_flags`: [`fdflags`](#fdflags) -File descriptor flags. - -Offset: 2 - -- `fs_rights_base`: [`rights`](#rights) -Rights that apply to this file descriptor. - -Offset: 8 - -- `fs_rights_inheriting`: [`rights`](#rights) -Maximum set of rights that may be installed on new file descriptors that -are created through this file descriptor, e.g., through `path_open`. - -Offset: 16 - -## `device`: `u64` -Identifier for a device containing a file system. Can be used in combination -with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. - -Size: 8 - -Alignment: 8 - -## `fstflags`: `Record` -Which file time attributes to adjust. - -Size: 2 - -Alignment: 2 - -### Record members -- `atim`: `bool` -Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - -Bit: 0 - -- `atim_now`: `bool` -Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 1 - -- `mtim`: `bool` -Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - -Bit: 2 - -- `mtim_now`: `bool` -Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 3 - -## `lookupflags`: `Record` -Flags determining the method of how paths are resolved. - -Size: 4 - -Alignment: 4 - -### Record members -- `symlink_follow`: `bool` -As long as the resolved path corresponds to a symbolic link, it is expanded. - -Bit: 0 - -## `oflags`: `Record` -Open flags used by `path_open`. - -Size: 2 - -Alignment: 2 - -### Record members -- `create`: `bool` -Create file if it does not exist. - -Bit: 0 - -- `directory`: `bool` -Fail if not a directory. - -Bit: 1 - -- `excl`: `bool` -Fail if file already exists. - -Bit: 2 - -- `trunc`: `bool` -Truncate file to size 0. - -Bit: 3 - -## `linkcount`: `u64` -Number of hard links to an inode. - -Size: 8 - -Alignment: 8 - -## `permissions`: `Record` -File permissions. This represents the permissions associated with a -file in a filesystem, and don't fully reflect all the conditions -which determine whether a given WASI program can access the file. - -Size: 1 - -Alignment: 1 - -### Record members -- `read`: `bool` -For files, permission to read the file. -For directories, permission to do [`readdir`](#readdir) and access files -within the directory. - -Note: This is similar to the read bit being set on files, and the -read *and* execute bits being set on directories, in POSIX. - -Bit: 0 - -- `write`: `bool` -For files, permission to mutate the file. -For directories, permission to create, remove, and rename items -within the directory. - -Bit: 1 - -- `execute`: `bool` -For files, permission to "execute" the file, using whatever -concept of "executing" the host filesystem has. -This flag is not valid for directories. - -Bit: 2 - -- `private`: `bool` -For filesystems which have a concept of multiple "users", this flag -indicates that the file is only accessible by the effective "user" -that the WASI store uses to access the filesystem, and inaccessible -to other "users". - -Bit: 3 - -## `filestat`: `Record` -File attributes. - -Size: 64 - -Alignment: 8 - -### Record members -- `dev`: [`device`](#device) -Device ID of device containing the file. - -Offset: 0 - -- `ino`: [`inode`](#inode) -File serial number. - -Offset: 8 - -- `filetype`: [`filetype`](#filetype) -File type. - -Offset: 16 - -- `permissions`: [`permissions`](#permissions) -File permissions. - -Offset: 17 - -- `nlink`: [`linkcount`](#linkcount) -Number of hard links to the file. - -Offset: 24 - -- `size`: [`filesize`](#filesize) -For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - -Offset: 32 - -- `atim`: [`timestamp`](#timestamp) -Last data access timestamp. - -Offset: 40 - -- `mtim`: [`timestamp`](#timestamp) -Last data modification timestamp. - -Offset: 48 - -- `ctim`: [`timestamp`](#timestamp) -Last file status change timestamp. - -Offset: 56 - -## `userdata`: `u64` -User-provided value that may be attached to objects that is retained when -extracted from the implementation. - -Size: 8 - -Alignment: 8 - -## `eventtype`: `Variant` -Type of a subscription to an event or its occurrence. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `clock` -The time value of clock [`subscription_clock::id`](#subscription_clock.id) has -reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - -- `fd_read` -File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has data -available for reading. This event always triggers for regular files. - -- `fd_write` -File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity -available for writing. This event always triggers for regular files. - -## `eventrwflags`: `Record` -The state of the file descriptor subscribed to with -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 2 - -Alignment: 2 - -### Record members -- `fd_readwrite_hangup`: `bool` -The peer of this socket has closed or disconnected. - -Bit: 0 - -## `event_fd_readwrite`: `Record` -The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). - -Size: 16 - -Alignment: 8 - -### Record members -- `nbytes`: [`filesize`](#filesize) -The number of bytes available for reading or writing. - -Offset: 0 - -- `flags`: [`eventrwflags`](#eventrwflags) -The state of the file descriptor. - -Offset: 8 - -## `event_u`: `Variant` -The contents of an [`event`](#event). - -Size: 24 - -Alignment: 8 - -### Variant Layout -- size: 24 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock` - -- `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) - -- `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) - -## `event`: `Record` -An event that occurred. - -Size: 40 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). - -Offset: 0 - -- `error`: [`errno`](#errno) -If non-zero, an error that occurred while processing the subscription request. - -Offset: 8 - -- `u`: [`event_u`](#event_u) -The type of the event that occurred, and the contents of the event - -Offset: 16 - -## `subclockflags`: `Record` -Flags determining how to interpret the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout). - -Size: 2 - -Alignment: 2 - -### Record members -- `subscription_clock_abstime`: `bool` -If set, treat the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock -[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp -provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the -current time value of clock [`subscription_clock::id`](#subscription_clock.id). - -Bit: 0 - -## `subscription_clock`: `Record` -The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). - -Size: 32 - -Alignment: 8 - -### Record members -- `id`: [`clockid`](#clockid) -The clock against which to compare the timestamp. - -Offset: 0 - -- `timeout`: [`timestamp`](#timestamp) -The absolute or relative timestamp. - -Offset: 8 - -- `precision`: [`timestamp`](#timestamp) -The amount of time that the implementation may wait additionally -to coalesce with other events. - -Offset: 16 - -- `flags`: [`subclockflags`](#subclockflags) -Flags specifying whether the timeout is absolute or relative - -Offset: 24 - -## `subscription_fd_readwrite`: `Record` -The contents of a [`subscription`](#subscription) when type is type is -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 4 - -Alignment: 4 - -### Record members -- `fd`: [`fd`](#fd) -The file descriptor on which to wait for it to become ready for reading or writing. - -Offset: 0 - -## `subscription_u`: `Variant` -The contents of a [`subscription`](#subscription). - -Size: 40 - -Alignment: 8 - -### Variant Layout -- size: 40 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock`: [`subscription_clock`](#subscription_clock) - -- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -## `subscription`: `Record` -Subscription to an event. - -Size: 48 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that is attached to the subscription in the -implementation and returned through [`event::userdata`](#event.userdata). - -Offset: 0 - -- `u`: [`subscription_u`](#subscription_u) -The type of the event to which to subscribe, and the contents of the subscription. - -Offset: 8 - -## `exitcode`: `u8` -Exit code generated by a program when exiting. - -Size: 1 - -Alignment: 1 - -### Constants -- `success` - -- `failure` - -## `riflags`: `Record` -Flags provided to `sock_recv`. - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_peek`: `bool` -Returns the message without removing it from the socket's receive queue. - -Bit: 0 - -- `recv_waitall`: `bool` -On byte-stream sockets, block until the full amount of data can be returned. - -Bit: 1 - -## `roflags`: `Record` -Flags returned by `sock_recv`. - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_data_truncated`: `bool` -Returned by `sock_recv`: Message data has been truncated. - -Bit: 0 - -## `siflags`: `u16` -Flags provided to `sock_send`. As there are currently no flags -defined, it must be set to zero. - -Size: 2 - -Alignment: 2 - -## `sdflags`: `Record` -Which channels on a socket to shut down. - -Size: 1 - -Alignment: 1 - -### Record members -- `rd`: `bool` -Disables further receive operations. - -Bit: 0 - -- `wr`: `bool` -Disables further send operations. - -Bit: 1 - -## `preopentype`: `Variant` -Identifiers for preopened capabilities. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `dir` -A pre-opened directory. - -## `prestat_dir`: `Record` -The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). - -Size: 4 - -Alignment: 4 - -### Record members -- `pr_name_len`: [`size`](#size) -The length of the directory name for use with `fd_prestat_dir_name`. - -Offset: 0 - -## `prestat`: `Variant` -Information about a pre-opened capability. - -Size: 8 - -Alignment: 4 - -### Variant Layout -- size: 8 -- align: 4 -- tag_size: 1 -### Variant cases -- `dir`: [`prestat_dir`](#prestat_dir) -When type is [`preopentype::dir`](#preopentype.dir): - -# Modules -## wasi_ephemeral_args -### Imports -#### Memory -### Functions - ---- - -#### `get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` -Read command-line argument data. -The size of the array should match that returned by [`sizes_get`](#sizes_get). -Each argument is expected to be `\0` terminated. - -##### Params -- `argv`: `Pointer>` - -- `argv_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sizes_get() -> Result<(size, size), errno>` -Return command-line argument data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of arguments and the size of the argument string -data, or an error. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_clock -### Imports -#### Memory -### Functions - ---- - -#### `res_get(id: clockid) -> Result` -Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, -return [`errno::inval`](#errno.inval). -Note: This is similar to `clock_getres` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the resolution. - -##### Results -- `error`: `Result` -The resolution of the clock. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `time_get(id: clockid, precision: timestamp) -> Result` -Return the time value of a clock. -Note: This is similar to `clock_gettime` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the time. - -- `precision`: [`timestamp`](#timestamp) -The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - -##### Results -- `error`: `Result` -The time value of the clock. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_environ -### Imports -#### Memory -### Functions - ---- - -#### `get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` -Read environment variable data. -The sizes of the buffers should match that returned by [`sizes_get`](#sizes_get). -Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - -##### Params -- `environ`: `Pointer>` - -- `environ_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sizes_get() -> Result<(size, size), errno>` -Return environment variable data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of environment variable arguments and the size of the -environment variable data. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_fd -### Imports -#### Memory -### Functions - ---- - -#### `advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` -Provide file advisory information on a file descriptor. -Note: This is similar to `posix_fadvise` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset within the file to which the advisory applies. - -- `len`: [`filesize`](#filesize) -The length of the region to which the advisory applies. - -- `advice`: [`advice`](#advice) -The advice. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` -Force the allocation of space in a file. -Note: This is similar to `posix_fallocate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset at which to start the allocation. - -- `len`: [`filesize`](#filesize) -The length of the area that is allocated. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `close(fd: fd) -> Result<(), errno>` -Close a file descriptor. -Note: This is similar to [`close`](#close) in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `datasync(fd: fd) -> Result<(), errno>` -Synchronize the data of a file to disk. -Note: This is similar to `fdatasync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fdstat_get(fd: fd) -> Result` -Get the attributes of a file descriptor. -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file descriptor's attributes are stored. - -###### Variant Layout -- size: 32 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`fdstat`](#fdstat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` -Adjust the flags associated with a file descriptor. -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`fdflags`](#fdflags) -The desired values of the file descriptor flags. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` -Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights - -##### Params -- `fd`: [`fd`](#fd) - -- `fs_rights_base`: [`rights`](#rights) -The desired rights of the file descriptor. - -- `fs_rights_inheriting`: [`rights`](#rights) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_get(fd: fd) -> Result` -Return the attributes of an open file. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 72 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` -Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. -Note: This is similar to `ftruncate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `size`: [`filesize`](#filesize) -The desired file size. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of an open file or directory. -Note: This is similar to `futimens` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `permissions_set(fd: fd, permissions: permissions) -> Result<(), errno>` -Set the permissions of a file or directory. - -This sets the permissions associated with a file or directory in -a filesystem at the time it is called. The ability to actually access -a file or directory may depend on additional permissions not reflected -here. - -Note: This is similar `fchmod` in POSIX. - -Unlike POSIX, this doesn't expose a user/group/other distinction; -implementations in POSIX environments are suggested to consult the -umask to determine which of the user/group/other flags to modify. - -##### Params -- `fd`: [`fd`](#fd) - -- `permissions`: [`permissions`](#permissions) -The permissions associated with the file. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` -Read from a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `preadv` in Linux (and other Unix-es). - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors in which to store data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to read. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `prestat_get(fd: fd) -> Result` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the description is stored. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`prestat`](#prestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `Pointer` -A buffer into which to write the preopened directory name. - -- `path_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` -Write to a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `pwritev` in Linux (and other Unix-es). - -Like Linux (and other Unix-es), any calls of [`pwrite`](#pwrite) (and other -functions to read or write) for a regular file by other threads in the -WASI process should not be interleaved while [`pwrite`](#pwrite) is executed. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to write. - -##### Results -- `error`: `Result` -The number of bytes written. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `read(fd: fd, iovs: iovec_array) -> Result` -Read from a file descriptor. -Note: This is similar to `readv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` -Read directory entries from a directory. -When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a [`dirent`](#dirent) object, -followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory -entry. -This function fills the output buffer as much as possible, potentially -truncating the last directory entry. This allows the caller to grow its -read buffer size in case it's too small to fit a single large directory -entry, or skip the oversized directory entry. - -##### Params -- `fd`: [`fd`](#fd) - -- `buf`: `Pointer` -The buffer where directory entries are stored - -- `buf_len`: [`size`](#size) - -- `cookie`: [`dircookie`](#dircookie) -The location within the directory to start reading - -##### Results -- `error`: `Result` -The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `renumber(fd: fd, to: fd) -> Result<(), errno>` -Atomically replace a file descriptor by renumbering another file descriptor. -Due to the strong focus on thread safety, this environment does not provide -a mechanism to duplicate or renumber a file descriptor to an arbitrary -number, like `dup2()`. This would be prone to race conditions, as an actual -file descriptor with the same number could be allocated by a different -thread at the same time. -This function provides a way to atomically renumber file descriptors, which -would disappear if `dup2()` were to be removed entirely. - -##### Params -- `fd`: [`fd`](#fd) - -- `to`: [`fd`](#fd) -The file descriptor to overwrite. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `seek(fd: fd, offset: filedelta, whence: whence) -> Result` -Move the offset of a file descriptor. -Note: This is similar to `lseek` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filedelta`](#filedelta) -The number of bytes to move. - -- `whence`: [`whence`](#whence) -The base from which the offset is relative. - -##### Results -- `error`: `Result` -The new offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `sync(fd: fd) -> Result<(), errno>` -Synchronize the data and metadata of a file to disk. -Note: This is similar to `fsync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `tell(fd: fd) -> Result` -Return the current offset of a file descriptor. -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The current offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `write(fd: fd, iovs: ciovec_array) -> Result` -Write to a file descriptor. -Note: This is similar to `writev` in POSIX. - -Like POSIX, any calls of [`write`](#write) (and other functions to read or write) -for a regular file by other threads in the WASI process should not be -interleaved while [`write`](#write) is executed. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -##### Results -- `error`: `Result` -The number of bytes written. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_path -### Imports -#### Memory -### Functions - ---- - -#### `create_directory(fd: fd, path: string) -> Result<(), errno>` -Create a directory. -Note: This is similar to `mkdirat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path at which to create the directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` -Return the attributes of a file or directory. -Note: This is similar to `stat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to inspect. - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 72 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of a file or directory. -Note: This is similar to `utimensat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to operate on. - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `permissions_set(fd: fd, flags: lookupflags, path: string, permissions: permissions) -> Result<(), errno>` -Set the permissions of a file or directory. - -This sets the permissions associated with a file or directory in -a filesystem at the time it is called. The ability to actually access -a file or directory may depend on additional permissions not reflected -here. - -Note: This is similar to `fchmodat` in POSIX. - -Unlike POSIX, this doesn't expose a user/group/other distinction; -implementations in POSIX environments are suggested to consult the -umask to determine which of the user/group/other flags to modify. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path to a file to query. - -- `permissions`: [`permissions`](#permissions) -The permissions to associate with the file. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Create a hard link. -Note: This is similar to `linkat` in POSIX. - -##### Params -- `old_fd`: [`fd`](#fd) - -- `old_flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `old_path`: `string` -The source path from which to link. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path at which to create the hard link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, permissions: permissions) -> Result` -Open a file or directory. -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since this -is error-prone in multi-threaded contexts. The returned file descriptor is -guaranteed to be less than 2**31. -Note: This is similar to `openat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `dirflags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The relative path of the file or directory to open, relative to the -[`fd`](#fd) directory. - -- `oflags`: [`oflags`](#oflags) -The method by which to open the file. - -- `fs_rights_base`: [`rights`](#rights) -The initial rights of the newly created file descriptor. The -implementation is allowed to return a file descriptor with fewer rights -than specified, if and only if those rights do not apply to the type of -file being opened. -The *base* rights are rights that will apply to operations using the file -descriptor itself, while the *inheriting* rights are rights that apply to -file descriptors derived from it. - -- `fs_rights_inheriting`: [`rights`](#rights) - -- `fdflags`: [`fdflags`](#fdflags) - -- `permissions`: [`permissions`](#permissions) -If a file is created, the filesystem permissions to associate with it. - -##### Results -- `error`: `Result` -The file descriptor of the file that has been opened. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`fd`](#fd) - -- `err`: [`errno`](#errno) - - ---- - -#### `readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` -Read the contents of a symbolic link. -Note: This is similar to `readlinkat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path of the symbolic link from which to read. - -- `buf`: `Pointer` -The buffer to which to write the contents of the symbolic link. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result` -The number of bytes placed in the buffer. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `remove_directory(fd: fd, path: string) -> Result<(), errno>` -Remove a directory. -Return [`errno::notempty`](#errno.notempty) if the directory is not empty. -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a directory to remove. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Rename a file or directory. -Note: This is similar to `renameat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `old_path`: `string` -The source path of the file or directory to rename. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path to which to rename the file or directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` -Create a symbolic link. -Note: This is similar to `symlinkat` in POSIX. - -##### Params -- `old_path`: `string` -The contents of the symbolic link. - -- `fd`: [`fd`](#fd) - -- `new_path`: `string` -The destination path at which to create the symbolic link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `unlink_file(fd: fd, path: string) -> Result<(), errno>` -Unlink a file. -Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a file to unlink. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_poll -### Imports -#### Memory -### Functions - ---- - -#### `oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` -Concurrently poll for the occurrence of a set of events. - -If `nsubscriptions` is 0, returns [`errno::inval`](#errno.inval). - -##### Params -- `in`: `ConstPointer` -The events to which to subscribe. - -- `out`: `Pointer` -The events that have occurred. - -- `nsubscriptions`: [`size`](#size) -Both the number of subscriptions and events. - -##### Results -- `error`: `Result` -The number of events stored. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_proc -### Imports -### Functions - ---- - -#### `exit(rval: exitcode)` -Terminate the process normally. An exit code of `$exitcode::success` -reports successful completion of the program. An exit code of -`$exitcode::failure` or any other value less than 126 reports a -failure, and the value is provided to the environment. If a value -of 126 or greater is given, this function behaves as if it were -implemented by an `unreachable` instruction. - -##### Params -- `rval`: [`exitcode`](#exitcode) -The exit code returned by the process. - -##### Results -## wasi_ephemeral_random -### Imports -#### Memory -### Functions - ---- - -#### `get(buf: Pointer, buf_len: size) -> Result<(), errno>` -Write high-quality random data into a buffer. -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. -This function may execute slowly, so when large mounts of random data are -required, it's advisable to use this function to seed a pseudo-random -number generator, rather than to provide the random data directly. - -##### Params -- `buf`: `Pointer` -The buffer to fill with random data. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_sched -### Imports -### Functions - ---- - -#### `yield() -> Result<(), errno>` -Temporarily yield execution of the calling thread. -Note: This is similar to [`yield`](#yield) in POSIX. - -##### Params -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - -## wasi_ephemeral_sock -### Imports -#### Memory -### Functions - ---- - -#### `recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` -Receive a message from a socket. -Note: This is similar to [`recv`](#recv) in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -##### Params -- `fd`: [`fd`](#fd) - -- `ri_data`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -- `ri_flags`: [`riflags`](#riflags) -Message flags. - -##### Results -- `error`: `Result<(size, roflags), errno>` -Number of bytes stored in ri_data and message flags. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, roflags)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`roflags`](#roflags) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` -Send a message on a socket. -Note: This is similar to [`send`](#send) in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -##### Params -- `fd`: [`fd`](#fd) - -- `si_data`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors to which to retrieve data - -- `si_flags`: [`siflags`](#siflags) -Message flags. - -##### Results -- `error`: `Result` -Number of bytes transmitted. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `shutdown(fd: fd, how: sdflags) -> Result<(), errno>` -Shut down socket send and receive channels. -Note: This is similar to [`shutdown`](#shutdown) in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `how`: [`sdflags`](#sdflags) -Which channels on the socket to shut down. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - diff --git a/proposals/random/phases/ephemeral/witx/typenames.witx b/proposals/random/phases/ephemeral/witx/typenames.witx deleted file mode 100644 index bbd6489df..000000000 --- a/proposals/random/phases/ephemeral/witx/typenames.witx +++ /dev/null @@ -1,708 +0,0 @@ -;; Type names used by low-level WASI interfaces. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -;;; An array size. -;;; -;;; Note: This is similar to `size_t` in POSIX. -(typename $size (@witx usize)) - -;;; Non-negative file size or length of a region within a file. -(typename $filesize u64) - -;;; Timestamp in nanoseconds. -(typename $timestamp u64) - -;;; Identifiers for clocks. -(typename $clockid - (enum (@witx tag u32) - ;;; The clock measuring real time. Time value zero corresponds with - ;;; 1970-01-01T00:00:00Z. - $realtime - ;;; The store-wide monotonic clock, which is defined as a clock measuring - ;;; real time, whose value cannot be adjusted and which cannot have negative - ;;; clock jumps. The epoch of this clock is undefined. The absolute time - ;;; value of this clock therefore has no meaning. - $monotonic - ) -) - -;;; Error codes returned by functions. -;;; Not all of these error codes are returned by the functions provided by this -;;; API; some are used in higher-level library layers, and others are provided -;;; merely for alignment with POSIX. -(typename $errno - (enum (@witx tag u16) - ;;; No error occurred. System call completed successfully. - $success - ;;; Argument list too long. - $2big - ;;; Permission denied. - $access - ;;; Address in use. - $addrinuse - ;;; Address not available. - $addrnotavail - ;;; Address family not supported. - $afnosupport - ;;; Resource unavailable, or operation would block. - $again - ;;; Connection already in progress. - $already - ;;; Bad file descriptor. - $badf - ;;; Bad message. - $badmsg - ;;; Device or resource busy. - $busy - ;;; Operation canceled. - $canceled - ;;; No child processes. - $child - ;;; Connection aborted. - $connaborted - ;;; Connection refused. - $connrefused - ;;; Connection reset. - $connreset - ;;; Resource deadlock would occur. - $deadlk - ;;; Destination address required. - $destaddrreq - ;;; Mathematics argument out of domain of function. - $dom - ;;; Reserved. - $dquot - ;;; File exists. - $exist - ;;; Bad address. - $fault - ;;; File too large. - $fbig - ;;; Host is unreachable. - $hostunreach - ;;; Identifier removed. - $idrm - ;;; Illegal byte sequence. - $ilseq - ;;; Operation in progress. - $inprogress - ;;; Interrupted function. - $intr - ;;; Invalid argument. - $inval - ;;; I/O error. - $io - ;;; Socket is connected. - $isconn - ;;; Is a directory. - $isdir - ;;; Too many levels of symbolic links. - $loop - ;;; File descriptor value too large. - $mfile - ;;; Too many links. - $mlink - ;;; Message too large. - $msgsize - ;;; Reserved. - $multihop - ;;; Filename too long. - $nametoolong - ;;; Network is down. - $netdown - ;;; Connection aborted by network. - $netreset - ;;; Network unreachable. - $netunreach - ;;; Too many files open in system. - $nfile - ;;; No buffer space available. - $nobufs - ;;; No such device. - $nodev - ;;; No such file or directory. - $noent - ;;; Executable file format error. - $noexec - ;;; No locks available. - $nolck - ;;; Reserved. - $nolink - ;;; Not enough space. - $nomem - ;;; No message of the desired type. - $nomsg - ;;; Protocol not available. - $noprotoopt - ;;; No space left on device. - $nospc - ;;; Function not supported. - $nosys - ;;; The socket is not connected. - $notconn - ;;; Not a directory or a symbolic link to a directory. - $notdir - ;;; Directory not empty. - $notempty - ;;; State not recoverable. - $notrecoverable - ;;; Not a socket. - $notsock - ;;; Not supported, or operation not supported on socket. - $notsup - ;;; Inappropriate I/O control operation. - $notty - ;;; No such device or address. - $nxio - ;;; Value too large to be stored in data type. - $overflow - ;;; Previous owner died. - $ownerdead - ;;; Operation not permitted. - $perm - ;;; Broken pipe. - $pipe - ;;; Protocol error. - $proto - ;;; Protocol not supported. - $protonosupport - ;;; Protocol wrong type for socket. - $prototype - ;;; Result too large. - $range - ;;; Read-only file system. - $rofs - ;;; Invalid seek. - $spipe - ;;; No such process. - $srch - ;;; Reserved. - $stale - ;;; Connection timed out. - $timedout - ;;; Text file busy. - $txtbsy - ;;; Cross-device link. - $xdev - ;;; Extension: Capabilities insufficient. - $notcapable - ) -) - -;;; File descriptor rights, determining which actions may be performed. -(typename $rights - (flags (@witx repr u64) - ;;; The right to invoke `fd_datasync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::dsync`. - $fd_datasync - ;;; The right to invoke `fd_read` and `sock_recv`. - ;; - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. - $fd_read - ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. - $fd_seek - ;;; The right to invoke `fd_fdstat_set_flags`. - $fd_fdstat_set_flags - ;;; The right to invoke `fd_sync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. - $fd_sync - ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to - ;;; invoke `fd_tell`. - $fd_tell - ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. - $fd_write - ;;; The right to invoke `fd_advise`. - $fd_advise - ;;; The right to invoke `fd_allocate`. - $fd_allocate - ;;; The right to invoke `path_create_directory`. - $path_create_directory - ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::create`. - $path_create_file - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; source directory. - $path_link_source - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; target directory. - $path_link_target - ;;; The right to invoke `path_open`. - $path_open - ;;; The right to invoke `fd_readdir`. - $fd_readdir - ;;; The right to invoke `path_readlink`. - $path_readlink - ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $path_rename_source - ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $path_rename_target - ;;; The right to invoke `path_filestat_get`. - $path_filestat_get - ;;; The right to change a file's size. - ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. - ;;; Note: there is no function named `path_filestat_set_size`. This follows POSIX design, - ;;; which only has `ftruncate` and does not provide `ftruncateat`. - ;;; While such function would be desirable from the API design perspective, there are virtually - ;;; no use cases for it since no code written for POSIX systems would use it. - ;;; Moreover, implementing it would require multiple syscalls, leading to inferior performance. - $path_filestat_set_size - ;;; The right to invoke `path_filestat_set_times`. - $path_filestat_set_times - ;;; The right to invoke `path_permissions_set`. - $path_permissions_set - ;;; The right to invoke `fd_filestat_get`. - $fd_filestat_get - ;;; The right to invoke `fd_filestat_set_size`. - $fd_filestat_set_size - ;;; The right to invoke `fd_filestat_set_times`. - $fd_filestat_set_times - ;;; The right to invoke `fd_permissions_set`. - $fd_permissions_set - ;;; The right to invoke `path_symlink`. - $path_symlink - ;;; The right to invoke `path_remove_directory`. - $path_remove_directory - ;;; The right to invoke `path_unlink_file`. - $path_unlink_file - ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. - ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. - $poll_fd_readwrite - ;;; The right to invoke `sock_shutdown`. - $sock_shutdown - ) -) - -;;; A file descriptor handle. -(typename $fd (handle)) - -;;; A region of memory for scatter/gather reads. -(typename $iovec - (record - ;;; The address of the buffer to be filled. - (field $buf (@witx pointer u8)) - ;;; The length of the buffer to be filled. - (field $buf_len $size) - ) -) - -;;; A region of memory for scatter/gather writes. -(typename $ciovec - (record - ;;; The address of the buffer to be written. - (field $buf (@witx const_pointer u8)) - ;;; The length of the buffer to be written. - (field $buf_len $size) - ) -) - -(typename $iovec_array (list $iovec)) -(typename $ciovec_array (list $ciovec)) - -;;; Relative offset within a file. -(typename $filedelta s64) - -;;; The position relative to which to set the offset of the file descriptor. -(typename $whence - (enum (@witx tag u8) - ;;; Seek relative to start-of-file. - $set - ;;; Seek relative to current position. - $cur - ;;; Seek relative to end-of-file. - $end - ) -) - -;;; A reference to the offset of a directory entry. -(typename $dircookie u64) - -;;; In an `fd_readdir` call, this value signifies the start of the directory. -(@witx const $dircookie $start 0) - -;;; The type for the `dirent::d_namlen` field of `dirent`. -(typename $dirnamlen u32) - -;;; File serial number that is unique within its file system. -(typename $inode u64) - -;;; The type of a file descriptor or file. -(typename $filetype - (enum (@witx tag u8) - ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $unknown - ;;; The file descriptor or file refers to a block device inode. - $block_device - ;;; The file descriptor or file refers to a character device inode. - $character_device - ;;; The file descriptor or file refers to a directory inode. - $directory - ;;; The file descriptor or file refers to a regular file inode. - $regular_file - ;;; The file descriptor or file refers to a datagram socket. - $socket_dgram - ;;; The file descriptor or file refers to a byte-stream socket. - $socket_stream - ;;; The file refers to a symbolic link inode. - $symbolic_link - ;;; The file descriptor or file refers to a FIFO. - $fifo - ) -) - -;;; A directory entry. -(typename $dirent - (record - ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie) - ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode) - ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) - ) -) - -;;; File or memory access pattern advisory information. -(typename $advice - (enum (@witx tag u8) - ;;; The application has no advice to give on its behavior with respect to the specified data. - $normal - ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $sequential - ;;; The application expects to access the specified data in a random order. - $random - ;;; The application expects to access the specified data in the near future. - $willneed - ;;; The application expects that it will not access the specified data in the near future. - $dontneed - ;;; The application expects to access the specified data once and then not reuse it thereafter. - $noreuse - ) -) - -;;; File descriptor flags. -(typename $fdflags - (flags (@witx repr u16) - ;;; Append mode: Data written to the file is always appended to the file's end. - $append - ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $dsync - ;;; Non-blocking mode. - $nonblock - ;;; Synchronized read I/O operations. - $rsync - ;;; Write according to synchronized I/O file integrity completion. In - ;;; addition to synchronizing the data stored in the file, the implementation - ;;; may also synchronously update the file's metadata. - $sync - ) -) - -;;; File descriptor attributes. -(typename $fdstat - (record - ;;; File type. - (field $fs_filetype $filetype) - ;;; File descriptor flags. - (field $fs_flags $fdflags) - ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights) - ;;; Maximum set of rights that may be installed on new file descriptors that - ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights) - ) -) - -;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode` to uniquely identify a file or directory in the filesystem. -(typename $device u64) - -;;; Which file time attributes to adjust. -(typename $fstflags - (flags (@witx repr u16) - ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. - $atim - ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. - $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. - $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. - $mtim_now - ) -) - -;;; Flags determining the method of how paths are resolved. -(typename $lookupflags - (flags (@witx repr u32) - ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $symlink_follow - ) -) - -;;; Open flags used by `path_open`. -(typename $oflags - (flags (@witx repr u16) - ;;; Create file if it does not exist. - $create - ;;; Fail if not a directory. - $directory - ;;; Fail if file already exists. - $excl - ;;; Truncate file to size 0. - $trunc - ) -) - -;;; Number of hard links to an inode. -(typename $linkcount u64) - -;;; File permissions. This represents the permissions associated with a -;;; file in a filesystem, and don't fully reflect all the conditions -;;; which determine whether a given WASI program can access the file. -(typename $permissions - (flags (@witx repr u8) - ;;; For files, permission to read the file. - ;;; For directories, permission to do `readdir` and access files - ;;; within the directory. - ;;; - ;;; Note: This is similar to the read bit being set on files, and the - ;;; read *and* execute bits being set on directories, in POSIX. - $read - - ;;; For files, permission to mutate the file. - ;;; For directories, permission to create, remove, and rename items - ;;; within the directory. - $write - - ;;; For files, permission to "execute" the file, using whatever - ;;; concept of "executing" the host filesystem has. - ;;; This flag is not valid for directories. - $execute - - ;;; For filesystems which have a concept of multiple "users", this flag - ;;; indicates that the file is only accessible by the effective "user" - ;;; that the WASI store uses to access the filesystem, and inaccessible - ;;; to other "users". - $private - ) -) - -;;; File attributes. -(typename $filestat - (record - ;;; Device ID of device containing the file. - (field $dev $device) - ;;; File serial number. - (field $ino $inode) - ;;; File type. - (field $filetype $filetype) - ;;; File permissions. - (field $permissions $permissions) - ;;; Number of hard links to the file. - (field $nlink $linkcount) - ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $size $filesize) - ;;; Last data access timestamp. - (field $atim $timestamp) - ;;; Last data modification timestamp. - (field $mtim $timestamp) - ;;; Last file status change timestamp. - (field $ctim $timestamp) - ) -) - -;;; User-provided value that may be attached to objects that is retained when -;;; extracted from the implementation. -(typename $userdata u64) - -;;; Type of a subscription to an event or its occurrence. -(typename $eventtype - (enum (@witx tag u8) - ;;; The time value of clock `subscription_clock::id` has - ;;; reached timestamp `subscription_clock::timeout`. - $clock - ;;; File descriptor `subscription_fd_readwrite::fd` has data - ;;; available for reading. This event always triggers for regular files. - $fd_read - ;;; File descriptor `subscription_fd_readwrite::fd` has capacity - ;;; available for writing. This event always triggers for regular files. - $fd_write - ) -) - -;;; The state of the file descriptor subscribed to with -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $eventrwflags - (flags (@witx repr u16) - ;;; The peer of this socket has closed or disconnected. - $fd_readwrite_hangup - ) -) - -;;; The contents of an `event` when type is `eventtype::fd_read` or -;;; `eventtype::fd_write`. -(typename $event_fd_readwrite - (record - ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize) - ;;; The state of the file descriptor. - (field $flags $eventrwflags) - ) -) - -;;; The contents of an `event`. -(typename $event_u - (variant (@witx tag $eventtype) - (case $fd_read $event_fd_readwrite) - (case $fd_write $event_fd_readwrite) - (case $clock) - ) -) - -;;; An event that occurred. -(typename $event - (record - ;;; User-provided value that got attached to `subscription::userdata`. - (field $userdata $userdata) - ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno) - ;;; The type of the event that occurred, and the contents of the event - (field $u $event_u) - ) -) - -;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_clock::timeout`. -(typename $subclockflags - (flags (@witx repr u16) - ;;; If set, treat the timestamp provided in - ;;; `subscription_clock::timeout` as an absolute timestamp of clock - ;;; `subscription_clock::id`. If clear, treat the timestamp - ;;; provided in `subscription_clock::timeout` relative to the - ;;; current time value of clock `subscription_clock::id`. - $subscription_clock_abstime - ) -) - -;;; The contents of a `subscription` when type is `eventtype::clock`. -(typename $subscription_clock - (record - ;;; The clock against which to compare the timestamp. - (field $id $clockid) - ;;; The absolute or relative timestamp. - (field $timeout $timestamp) - ;;; The amount of time that the implementation may wait additionally - ;;; to coalesce with other events. - (field $precision $timestamp) - ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags) - ) -) - -;;; The contents of a `subscription` when type is type is -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $subscription_fd_readwrite - (record - ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $fd $fd) - ) -) - -;;; The contents of a `subscription`. -(typename $subscription_u - (union (@witx tag $eventtype) - $subscription_clock - $subscription_fd_readwrite - $subscription_fd_readwrite - ) -) - -;;; Subscription to an event. -(typename $subscription - (record - ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event::userdata`. - (field $userdata $userdata) - ;;; The type of the event to which to subscribe, and the contents of the subscription. - (field $u $subscription_u) - ) -) - -;;; Exit code generated by a program when exiting. -(typename $exitcode u8) - -;;; Indicate the program exited successfully. -;;; -;;; Note: This is similar to `EXIT_SUCCESS` in POSIX. -(@witx const $exitcode $success 0) - -;;; Indicate the program exited unsuccessfully. -;;; -;;; Note: This is similar to `EXIT_FAILURE` in POSIX. -(@witx const $exitcode $failure 1) - -;;; Flags provided to `sock_recv`. -(typename $riflags - (flags (@witx repr u16) - ;;; Returns the message without removing it from the socket's receive queue. - $recv_peek - ;;; On byte-stream sockets, block until the full amount of data can be returned. - $recv_waitall - ) -) - -;;; Flags returned by `sock_recv`. -(typename $roflags - (flags (@witx repr u16) - ;;; Returned by `sock_recv`: Message data has been truncated. - $recv_data_truncated - ) -) - -;;; Flags provided to `sock_send`. As there are currently no flags -;;; defined, it must be set to zero. -(typename $siflags u16) - -;;; Which channels on a socket to shut down. -(typename $sdflags - (flags (@witx repr u8) - ;;; Disables further receive operations. - $rd - ;;; Disables further send operations. - $wr - ) -) - -;;; Identifiers for preopened capabilities. -(typename $preopentype - (enum (@witx tag u8) - ;;; A pre-opened directory. - $dir - ) -) - -;;; The contents of a `prestat` when its type is `preopentype::dir`. -(typename $prestat_dir - (record - ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size) - ) -) - -;;; Information about a pre-opened capability. -(typename $prestat - (union (@witx tag $preopentype) - ;;; When type is `preopentype::dir`: - $prestat_dir - ) -) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx deleted file mode 100644 index bb956fc53..000000000 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_args.witx +++ /dev/null @@ -1,27 +0,0 @@ -;; WASI Command-line Arguments. -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_args - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `sizes_get`. - ;;; Each argument is expected to be `\0` terminated. - (@interface func (export "get") - (param $argv (@witx pointer (@witx pointer (@witx char8)))) - (param $argv_buf (@witx pointer (@witx char8))) - (result $error (expected (error $errno))) - ) - - ;;; Return command-line argument data sizes. - (@interface func (export "sizes_get") - ;;; Returns the number of arguments and the size of the argument string - ;;; data, or an error. - (result $error (expected (tuple $size $size) (error $errno))) - ) -) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx deleted file mode 100644 index a980529f8..000000000 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_clock.witx +++ /dev/null @@ -1,35 +0,0 @@ -;; WASI Clocks. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_clock - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, - ;;; return `errno::inval`. - ;;; Note: This is similar to `clock_getres` in POSIX. - (@interface func (export "res_get") - ;;; The clock for which to return the resolution. - (param $id $clockid) - ;;; The resolution of the clock. - (result $error (expected $timestamp (error $errno))) - ) - - ;;; Return the time value of a clock. - ;;; Note: This is similar to `clock_gettime` in POSIX. - (@interface func (export "time_get") - ;;; The clock for which to return the time. - (param $id $clockid) - ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp) - ;;; The time value of the clock. - (result $error (expected $timestamp (error $errno))) - ) -) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx deleted file mode 100644 index ef1c20b22..000000000 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_environ.witx +++ /dev/null @@ -1,27 +0,0 @@ -;; WASI Environment Variables. -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_environ - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `sizes_get`. - ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - (@interface func (export "get") - (param $environ (@witx pointer (@witx pointer (@witx char8)))) - (param $environ_buf (@witx pointer (@witx char8))) - (result $error (expected (error $errno))) - ) - - ;;; Return environment variable data sizes. - (@interface func (export "sizes_get") - ;;; Returns the number of environment variable arguments and the size of the - ;;; environment variable data. - (result $error (expected (tuple $size $size) (error $errno))) - ) -) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx deleted file mode 100644 index 979e9a333..000000000 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_fd.witx +++ /dev/null @@ -1,259 +0,0 @@ -;; WASI I/O. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_fd - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Provide file advisory information on a file descriptor. - ;;; Note: This is similar to `posix_fadvise` in POSIX. - (@interface func (export "advise") - (param $fd $fd) - ;;; The offset within the file to which the advisory applies. - (param $offset $filesize) - ;;; The length of the region to which the advisory applies. - (param $len $filesize) - ;;; The advice. - (param $advice $advice) - (result $error (expected (error $errno))) - ) - - ;;; Force the allocation of space in a file. - ;;; Note: This is similar to `posix_fallocate` in POSIX. - (@interface func (export "allocate") - (param $fd $fd) - ;;; The offset at which to start the allocation. - (param $offset $filesize) - ;;; The length of the area that is allocated. - (param $len $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Close a file descriptor. - ;;; Note: This is similar to `close` in POSIX. - (@interface func (export "close") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Synchronize the data of a file to disk. - ;;; Note: This is similar to `fdatasync` in POSIX. - (@interface func (export "datasync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Get the attributes of a file descriptor. - ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (@interface func (export "fdstat_get") - (param $fd $fd) - ;;; The buffer where the file descriptor's attributes are stored. - (result $error (expected $fdstat (error $errno))) - ) - - ;;; Adjust the flags associated with a file descriptor. - ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (@interface func (export "fdstat_set_flags") - (param $fd $fd) - ;;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights - (@interface func (export "fdstat_set_rights") - (param $fd $fd) - ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of an open file. - (@interface func (export "filestat_get") - (param $fd $fd) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;;; Note: This is similar to `ftruncate` in POSIX. - (@interface func (export "filestat_set_size") - (param $fd $fd) - ;;; The desired file size. - (param $size $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the timestamps of an open file or directory. - ;;; Note: This is similar to `futimens` in POSIX. - (@interface func (export "filestat_set_times") - (param $fd $fd) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Set the permissions of a file or directory. - ;;; - ;;; This sets the permissions associated with a file or directory in - ;;; a filesystem at the time it is called. The ability to actually access - ;;; a file or directory may depend on additional permissions not reflected - ;;; here. - ;;; - ;;; Note: This is similar `fchmod` in POSIX. - ;;; - ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; - ;;; implementations in POSIX environments are suggested to consult the - ;;; umask to determine which of the user/group/other flags to modify. - (@interface func (export "permissions_set") - (param $fd $fd) - ;;; The permissions associated with the file. - (param $permissions $permissions) - (result $error (expected (error $errno))) - ) - - ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in Linux (and other Unix-es). - (@interface func (export "pread") - (param $fd $fd) - ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_array) - ;;; The offset within the file at which to read. - (param $offset $filesize) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "prestat_get") - (param $fd $fd) - ;;; The buffer where the description is stored. - (result $error (expected $prestat (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "prestat_dir_name") - (param $fd $fd) - ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer (@witx char8))) - (param $path_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in Linux (and other Unix-es). - ;;; - ;;; Like Linux (and other Unix-es), any calls of `pwrite` (and other - ;;; functions to read or write) for a regular file by other threads in the - ;;; WASI process should not be interleaved while `pwrite` is executed. - (@interface func (export "pwrite") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The offset within the file at which to write. - (param $offset $filesize) - ;;; The number of bytes written. - (result $error (expected $size (error $errno))) - ) - - ;;; Read from a file descriptor. - ;;; Note: This is similar to `readv` in POSIX. - (@interface func (export "read") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_array) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Read directory entries from a directory. - ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a `dirent` object, - ;;; followed by `dirent::d_namlen` bytes holding the name of the directory - ;;; entry. - ;; - ;;; This function fills the output buffer as much as possible, potentially - ;;; truncating the last directory entry. This allows the caller to grow its - ;;; read buffer size in case it's too small to fit a single large directory - ;;; entry, or skip the oversized directory entry. - (@interface func (export "readdir") - (param $fd $fd) - ;;; The buffer where directory entries are stored - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The location within the directory to start reading - (param $cookie $dircookie) - ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $error (expected $size (error $errno))) - ) - - ;;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;;; Due to the strong focus on thread safety, this environment does not provide - ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;;; file descriptor with the same number could be allocated by a different - ;;; thread at the same time. - ;; - ;;; This function provides a way to atomically renumber file descriptors, which - ;;; would disappear if `dup2()` were to be removed entirely. - (@interface func (export "renumber") - (param $fd $fd) - ;;; The file descriptor to overwrite. - (param $to $fd) - (result $error (expected (error $errno))) - ) - - ;;; Move the offset of a file descriptor. - ;;; Note: This is similar to `lseek` in POSIX. - (@interface func (export "seek") - (param $fd $fd) - ;;; The number of bytes to move. - (param $offset $filedelta) - ;;; The base from which the offset is relative. - (param $whence $whence) - ;;; The new offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Synchronize the data and metadata of a file to disk. - ;;; Note: This is similar to `fsync` in POSIX. - (@interface func (export "sync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Return the current offset of a file descriptor. - ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (@interface func (export "tell") - (param $fd $fd) - ;;; The current offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Write to a file descriptor. - ;;; Note: This is similar to `writev` in POSIX. - ;;; - ;;; Like POSIX, any calls of `write` (and other functions to read or write) - ;;; for a regular file by other threads in the WASI process should not be - ;;; interleaved while `write` is executed. - (@interface func (export "write") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The number of bytes written. - (result $error (expected $size (error $errno))) - ) -) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx deleted file mode 100644 index 2901decb7..000000000 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_path.witx +++ /dev/null @@ -1,181 +0,0 @@ -;; WASI Filesystem Path API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_path - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Create a directory. - ;;; Note: This is similar to `mkdirat` in POSIX. - (@interface func (export "create_directory") - (param $fd $fd) - ;;; The path at which to create the directory. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of a file or directory. - ;;; Note: This is similar to `stat` in POSIX. - (@interface func (export "filestat_get") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to inspect. - (param $path string) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the timestamps of a file or directory. - ;;; Note: This is similar to `utimensat` in POSIX. - (@interface func (export "filestat_set_times") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to operate on. - (param $path string) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Set the permissions of a file or directory. - ;;; - ;;; This sets the permissions associated with a file or directory in - ;;; a filesystem at the time it is called. The ability to actually access - ;;; a file or directory may depend on additional permissions not reflected - ;;; here. - ;;; - ;;; Note: This is similar to `fchmodat` in POSIX. - ;;; - ;;; Unlike POSIX, this doesn't expose a user/group/other distinction; - ;;; implementations in POSIX environments are suggested to consult the - ;;; umask to determine which of the user/group/other flags to modify. - (@interface func (export "permissions_set") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path to a file to query. - (param $path string) - ;;; The permissions to associate with the file. - (param $permissions $permissions) - (result $error (expected (error $errno))) - ) - - ;;; Create a hard link. - ;;; Note: This is similar to `linkat` in POSIX. - (@interface func (export "link") - (param $old_fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags) - ;;; The source path from which to link. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path at which to create the hard link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Open a file or directory. - ;; - ;;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;;; file descriptor not currently open; it is randomized to prevent - ;;; applications from depending on making assumptions about indexes, since this - ;;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;;; guaranteed to be less than 2**31. - ;; - ;;; Note: This is similar to `openat` in POSIX. - (@interface func (export "open") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags) - ;;; The relative path of the file or directory to open, relative to the - ;;; `fd` directory. - (param $path string) - ;;; The method by which to open the file. - (param $oflags $oflags) - ;;; The initial rights of the newly created file descriptor. The - ;;; implementation is allowed to return a file descriptor with fewer rights - ;;; than specified, if and only if those rights do not apply to the type of - ;;; file being opened. - ;; - ;;; The *base* rights are rights that will apply to operations using the file - ;;; descriptor itself, while the *inheriting* rights are rights that apply to - ;;; file descriptors derived from it. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (param $fdflags $fdflags) - ;;; If a file is created, the filesystem permissions to associate with it. - (param $permissions $permissions) - ;;; The file descriptor of the file that has been opened. - (result $error (expected $fd (error $errno))) - ) - - ;;; Read the contents of a symbolic link. - ;;; Note: This is similar to `readlinkat` in POSIX. - (@interface func (export "readlink") - (param $fd $fd) - ;;; The path of the symbolic link from which to read. - (param $path string) - ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer (@witx char8))) - (param $buf_len $size) - ;;; The number of bytes placed in the buffer. - (result $error (expected $size (error $errno))) - ) - - ;;; Remove a directory. - ;;; Return `errno::notempty` if the directory is not empty. - ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (@interface func (export "remove_directory") - (param $fd $fd) - ;;; The path to a directory to remove. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Rename a file or directory. - ;;; Note: This is similar to `renameat` in POSIX. - (@interface func (export "rename") - (param $fd $fd) - ;;; The source path of the file or directory to rename. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Create a symbolic link. - ;;; Note: This is similar to `symlinkat` in POSIX. - (@interface func (export "symlink") - ;;; The contents of the symbolic link. - (param $old_path string) - (param $fd $fd) - ;;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Unlink a file. - ;;; Return `errno::isdir` if the path refers to a directory. - ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (@interface func (export "unlink_file") - (param $fd $fd) - ;;; The path to a file to unlink. - (param $path string) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx deleted file mode 100644 index 08da5f03a..000000000 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_poll.witx +++ /dev/null @@ -1,27 +0,0 @@ -;; WASI Poll API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_poll - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Concurrently poll for the occurrence of a set of events. - ;;; - ;;; If `nsubscriptions` is 0, returns `errno::inval`. - (@interface func (export "oneoff") - ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription)) - ;;; The events that have occurred. - (param $out (@witx pointer $event)) - ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size) - ;;; The number of events stored. - (result $error (expected $size (error $errno))) - ) -) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx deleted file mode 100644 index 0bd57682d..000000000 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_proc.witx +++ /dev/null @@ -1,22 +0,0 @@ -;; WASI Process API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_proc - ;;; Terminate the process normally. An exit code of `$exitcode::success` - ;;; reports successful completion of the program. An exit code of - ;;; `$exitcode::failure` or any other value less than 126 reports a - ;;; failure, and the value is provided to the environment. If a value - ;;; of 126 or greater is given, this function behaves as if it were - ;;; implemented by an `unreachable` instruction. - (@interface func (export "exit") - ;;; The exit code returned by the process. - (param $rval $exitcode) - (@witx noreturn) - ) -) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx deleted file mode 100644 index 4dc8e1a47..000000000 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_random.witx +++ /dev/null @@ -1,26 +0,0 @@ -;; WASI Random API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_random - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Write high-quality random data into a buffer. - ;;; This function blocks when the implementation is unable to immediately - ;;; provide sufficient high-quality random data. - ;;; This function may execute slowly, so when large mounts of random data are - ;;; required, it's advisable to use this function to seed a pseudo-random - ;;; number generator, rather than to provide the random data directly. - (@interface func (export "get") - ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sched.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sched.witx deleted file mode 100644 index 3b70856dc..000000000 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sched.witx +++ /dev/null @@ -1,16 +0,0 @@ -;; WASI Scheduler API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_sched - ;;; Temporarily yield execution of the calling thread. - ;;; Note: This is similar to `yield` in POSIX. - (@interface func (export "yield") - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sock.witx b/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sock.witx deleted file mode 100644 index a05b02ea6..000000000 --- a/proposals/random/phases/ephemeral/witx/wasi_ephemeral_sock.witx +++ /dev/null @@ -1,48 +0,0 @@ -;; WASI Sockets. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_sock - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Receive a message from a socket. - ;;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;;; the data into multiple buffers in the manner of `readv`. - (@interface func (export "recv") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_array) - ;;; Message flags. - (param $ri_flags $riflags) - ;;; Number of bytes stored in ri_data and message flags. - (result $error (expected (tuple $size $roflags) (error $errno))) - ) - - ;;; Send a message on a socket. - ;;; Note: This is similar to `send` in POSIX, though it also supports writing - ;;; the data from multiple buffers in the manner of `writev`. - (@interface func (export "send") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_array) - ;;; Message flags. - (param $si_flags $siflags) - ;;; Number of bytes transmitted. - (result $error (expected $size (error $errno))) - ) - - ;;; Shut down socket send and receive channels. - ;;; Note: This is similar to `shutdown` in POSIX. - (@interface func (export "shutdown") - (param $fd $fd) - ;;; Which channels on the socket to shut down. - (param $how $sdflags) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/random/phases/old/snapshot_0/docs.md b/proposals/random/phases/old/snapshot_0/docs.md deleted file mode 100644 index 634e304b3..000000000 --- a/proposals/random/phases/old/snapshot_0/docs.md +++ /dev/null @@ -1,2512 +0,0 @@ -# Types -## `size`: `u32` - -Size: 4 - -Alignment: 4 - -## `filesize`: `u64` -Non-negative file size or length of a region within a file. - -Size: 8 - -Alignment: 8 - -## `timestamp`: `u64` -Timestamp in nanoseconds. - -Size: 8 - -Alignment: 8 - -## `clockid`: `Variant` -Identifiers for clocks. - -Size: 4 - -Alignment: 4 - -### Variant cases -- `realtime` -The clock measuring real time. Time value zero corresponds with -1970-01-01T00:00:00Z. - -- `monotonic` -The store-wide monotonic clock, which is defined as a clock measuring -real time, whose value cannot be adjusted and which cannot have negative -clock jumps. The epoch of this clock is undefined. The absolute time -value of this clock therefore has no meaning. - -- `process_cputime_id` -The CPU-time clock associated with the current process. - -- `thread_cputime_id` -The CPU-time clock associated with the current thread. - -## `errno`: `Variant` -Error codes returned by functions. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX. - -Size: 2 - -Alignment: 2 - -### Variant cases -- `success` -No error occurred. System call completed successfully. - -- `2big` -Argument list too long. - -- `acces` -Permission denied. - -- `addrinuse` -Address in use. - -- `addrnotavail` -Address not available. - -- `afnosupport` -Address family not supported. - -- `again` -Resource unavailable, or operation would block. - -- `already` -Connection already in progress. - -- `badf` -Bad file descriptor. - -- `badmsg` -Bad message. - -- `busy` -Device or resource busy. - -- `canceled` -Operation canceled. - -- `child` -No child processes. - -- `connaborted` -Connection aborted. - -- `connrefused` -Connection refused. - -- `connreset` -Connection reset. - -- `deadlk` -Resource deadlock would occur. - -- `destaddrreq` -Destination address required. - -- `dom` -Mathematics argument out of domain of function. - -- `dquot` -Reserved. - -- `exist` -File exists. - -- `fault` -Bad address. - -- `fbig` -File too large. - -- `hostunreach` -Host is unreachable. - -- `idrm` -Identifier removed. - -- `ilseq` -Illegal byte sequence. - -- `inprogress` -Operation in progress. - -- `intr` -Interrupted function. - -- `inval` -Invalid argument. - -- `io` -I/O error. - -- `isconn` -Socket is connected. - -- `isdir` -Is a directory. - -- `loop` -Too many levels of symbolic links. - -- `mfile` -File descriptor value too large. - -- `mlink` -Too many links. - -- `msgsize` -Message too large. - -- `multihop` -Reserved. - -- `nametoolong` -Filename too long. - -- `netdown` -Network is down. - -- `netreset` -Connection aborted by network. - -- `netunreach` -Network unreachable. - -- `nfile` -Too many files open in system. - -- `nobufs` -No buffer space available. - -- `nodev` -No such device. - -- `noent` -No such file or directory. - -- `noexec` -Executable file format error. - -- `nolck` -No locks available. - -- `nolink` -Reserved. - -- `nomem` -Not enough space. - -- `nomsg` -No message of the desired type. - -- `noprotoopt` -Protocol not available. - -- `nospc` -No space left on device. - -- `nosys` -Function not supported. - -- `notconn` -The socket is not connected. - -- `notdir` -Not a directory or a symbolic link to a directory. - -- `notempty` -Directory not empty. - -- `notrecoverable` -State not recoverable. - -- `notsock` -Not a socket. - -- `notsup` -Not supported, or operation not supported on socket. - -- `notty` -Inappropriate I/O control operation. - -- `nxio` -No such device or address. - -- `overflow` -Value too large to be stored in data type. - -- `ownerdead` -Previous owner died. - -- `perm` -Operation not permitted. - -- `pipe` -Broken pipe. - -- `proto` -Protocol error. - -- `protonosupport` -Protocol not supported. - -- `prototype` -Protocol wrong type for socket. - -- `range` -Result too large. - -- `rofs` -Read-only file system. - -- `spipe` -Invalid seek. - -- `srch` -No such process. - -- `stale` -Reserved. - -- `timedout` -Connection timed out. - -- `txtbsy` -Text file busy. - -- `xdev` -Cross-device link. - -- `notcapable` -Extension: Capabilities insufficient. - -## `rights`: `Record` -File descriptor rights, determining which actions may be performed. - -Size: 8 - -Alignment: 8 - -### Record members -- `fd_datasync`: `bool` -The right to invoke [`fd_datasync`](#fd_datasync). -If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke -[`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). - -Bit: 0 - -- `fd_read`: `bool` -The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). - -Bit: 1 - -- `fd_seek`: `bool` -The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). - -Bit: 2 - -- `fd_fdstat_set_flags`: `bool` -The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). - -Bit: 3 - -- `fd_sync`: `bool` -The right to invoke [`fd_sync`](#fd_sync). -If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke -[`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - -Bit: 4 - -- `fd_tell`: `bool` -The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset -remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to -invoke [`fd_tell`](#fd_tell). - -Bit: 5 - -- `fd_write`: `bool` -The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). - -Bit: 6 - -- `fd_advise`: `bool` -The right to invoke [`fd_advise`](#fd_advise). - -Bit: 7 - -- `fd_allocate`: `bool` -The right to invoke [`fd_allocate`](#fd_allocate). - -Bit: 8 - -- `path_create_directory`: `bool` -The right to invoke [`path_create_directory`](#path_create_directory). - -Bit: 9 - -- `path_create_file`: `bool` -If [`rights::path_open`](#rights.path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). - -Bit: 10 - -- `path_link_source`: `bool` -The right to invoke [`path_link`](#path_link) with the file descriptor as the -source directory. - -Bit: 11 - -- `path_link_target`: `bool` -The right to invoke [`path_link`](#path_link) with the file descriptor as the -target directory. - -Bit: 12 - -- `path_open`: `bool` -The right to invoke [`path_open`](#path_open). - -Bit: 13 - -- `fd_readdir`: `bool` -The right to invoke [`fd_readdir`](#fd_readdir). - -Bit: 14 - -- `path_readlink`: `bool` -The right to invoke [`path_readlink`](#path_readlink). - -Bit: 15 - -- `path_rename_source`: `bool` -The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. - -Bit: 16 - -- `path_rename_target`: `bool` -The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. - -Bit: 17 - -- `path_filestat_get`: `bool` -The right to invoke [`path_filestat_get`](#path_filestat_get). - -Bit: 18 - -- `path_filestat_set_size`: `bool` -The right to change a file's size (there is no `path_filestat_set_size`). -If [`rights::path_open`](#rights.path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). - -Bit: 19 - -- `path_filestat_set_times`: `bool` -The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). - -Bit: 20 - -- `fd_filestat_get`: `bool` -The right to invoke [`fd_filestat_get`](#fd_filestat_get). - -Bit: 21 - -- `fd_filestat_set_size`: `bool` -The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). - -Bit: 22 - -- `fd_filestat_set_times`: `bool` -The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). - -Bit: 23 - -- `path_symlink`: `bool` -The right to invoke [`path_symlink`](#path_symlink). - -Bit: 24 - -- `path_remove_directory`: `bool` -The right to invoke [`path_remove_directory`](#path_remove_directory). - -Bit: 25 - -- `path_unlink_file`: `bool` -The right to invoke [`path_unlink_file`](#path_unlink_file). - -Bit: 26 - -- `poll_fd_readwrite`: `bool` -If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). -If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). - -Bit: 27 - -- `sock_shutdown`: `bool` -The right to invoke [`sock_shutdown`](#sock_shutdown). - -Bit: 28 - -## `fd`: `Handle` -A file descriptor handle. - -Size: 4 - -Alignment: 4 - -### Supertypes -## `iovec`: `Record` -A region of memory for scatter/gather reads. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `Pointer` -The address of the buffer to be filled. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be filled. - -Offset: 4 - -## `ciovec`: `Record` -A region of memory for scatter/gather writes. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `ConstPointer` -The address of the buffer to be written. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be written. - -Offset: 4 - -## `iovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `ciovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `filedelta`: `s64` -Relative offset within a file. - -Size: 8 - -Alignment: 8 - -## `whence`: `Variant` -The position relative to which to set the offset of the file descriptor. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `cur` -Seek relative to current position. - -- `end` -Seek relative to end-of-file. - -- `set` -Seek relative to start-of-file. - -## `dircookie`: `u64` -A reference to the offset of a directory entry. - -Size: 8 - -Alignment: 8 - -## `dirnamlen`: `u32` -The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent) struct. - -Size: 4 - -Alignment: 4 - -## `inode`: `u64` -File serial number that is unique within its file system. - -Size: 8 - -Alignment: 8 - -## `filetype`: `Variant` -The type of a file descriptor or file. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `unknown` -The type of the file descriptor or file is unknown or is different from any of the other types specified. - -- `block_device` -The file descriptor or file refers to a block device inode. - -- `character_device` -The file descriptor or file refers to a character device inode. - -- `directory` -The file descriptor or file refers to a directory inode. - -- `regular_file` -The file descriptor or file refers to a regular file inode. - -- `socket_dgram` -The file descriptor or file refers to a datagram socket. - -- `socket_stream` -The file descriptor or file refers to a byte-stream socket. - -- `symbolic_link` -The file refers to a symbolic link inode. - -## `dirent`: `Record` -A directory entry. - -Size: 24 - -Alignment: 8 - -### Record members -- `d_next`: [`dircookie`](#dircookie) -The offset of the next directory entry stored in this directory. - -Offset: 0 - -- `d_ino`: [`inode`](#inode) -The serial number of the file referred to by this directory entry. - -Offset: 8 - -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. - -Offset: 16 - -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. - -Offset: 20 - -## `advice`: `Variant` -File or memory access pattern advisory information. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `normal` -The application has no advice to give on its behavior with respect to the specified data. - -- `sequential` -The application expects to access the specified data sequentially from lower offsets to higher offsets. - -- `random` -The application expects to access the specified data in a random order. - -- `willneed` -The application expects to access the specified data in the near future. - -- `dontneed` -The application expects that it will not access the specified data in the near future. - -- `noreuse` -The application expects to access the specified data once and then not reuse it thereafter. - -## `fdflags`: `Record` -File descriptor flags. - -Size: 2 - -Alignment: 2 - -### Record members -- `append`: `bool` -Append mode: Data written to the file is always appended to the file's end. - -Bit: 0 - -- `dsync`: `bool` -Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - -Bit: 1 - -- `nonblock`: `bool` -Non-blocking mode. - -Bit: 2 - -- `rsync`: `bool` -Synchronized read I/O operations. - -Bit: 3 - -- `sync`: `bool` -Write according to synchronized I/O file integrity completion. In -addition to synchronizing the data stored in the file, the implementation -may also synchronously update the file's metadata. - -Bit: 4 - -## `fdstat`: `Record` -File descriptor attributes. - -Size: 24 - -Alignment: 8 - -### Record members -- `fs_filetype`: [`filetype`](#filetype) -File type. - -Offset: 0 - -- `fs_flags`: [`fdflags`](#fdflags) -File descriptor flags. - -Offset: 2 - -- `fs_rights_base`: [`rights`](#rights) -Rights that apply to this file descriptor. - -Offset: 8 - -- `fs_rights_inheriting`: [`rights`](#rights) -Maximum set of rights that may be installed on new file descriptors that -are created through this file descriptor, e.g., through [`path_open`](#path_open). - -Offset: 16 - -## `device`: `u64` -Identifier for a device containing a file system. Can be used in combination -with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. - -Size: 8 - -Alignment: 8 - -## `fstflags`: `Record` -Which file time attributes to adjust. - -Size: 2 - -Alignment: 2 - -### Record members -- `atim`: `bool` -Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - -Bit: 0 - -- `atim_now`: `bool` -Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 1 - -- `mtim`: `bool` -Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - -Bit: 2 - -- `mtim_now`: `bool` -Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 3 - -## `lookupflags`: `Record` -Flags determining the method of how paths are resolved. - -Size: 4 - -Alignment: 4 - -### Record members -- `symlink_follow`: `bool` -As long as the resolved path corresponds to a symbolic link, it is expanded. - -Bit: 0 - -## `oflags`: `Record` -Open flags used by [`path_open`](#path_open). - -Size: 2 - -Alignment: 2 - -### Record members -- `creat`: `bool` -Create file if it does not exist. - -Bit: 0 - -- `directory`: `bool` -Fail if not a directory. - -Bit: 1 - -- `excl`: `bool` -Fail if file already exists. - -Bit: 2 - -- `trunc`: `bool` -Truncate file to size 0. - -Bit: 3 - -## `linkcount`: `u32` -Number of hard links to an inode. - -Size: 4 - -Alignment: 4 - -## `filestat`: `Record` -File attributes. - -Size: 56 - -Alignment: 8 - -### Record members -- `dev`: [`device`](#device) -Device ID of device containing the file. - -Offset: 0 - -- `ino`: [`inode`](#inode) -File serial number. - -Offset: 8 - -- `filetype`: [`filetype`](#filetype) -File type. - -Offset: 16 - -- `nlink`: [`linkcount`](#linkcount) -Number of hard links to the file. - -Offset: 20 - -- `size`: [`filesize`](#filesize) -For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - -Offset: 24 - -- `atim`: [`timestamp`](#timestamp) -Last data access timestamp. - -Offset: 32 - -- `mtim`: [`timestamp`](#timestamp) -Last data modification timestamp. - -Offset: 40 - -- `ctim`: [`timestamp`](#timestamp) -Last file status change timestamp. - -Offset: 48 - -## `userdata`: `u64` -User-provided value that may be attached to objects that is retained when -extracted from the implementation. - -Size: 8 - -Alignment: 8 - -## `eventtype`: `Variant` -Type of a subscription to an event or its occurrence. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `clock` -The time value of clock [`subscription_clock::id`](#subscription_clock.id) has -reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - -- `fd_read` -File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has data -available for reading. This event always triggers for regular files. - -- `fd_write` -File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity -available for writing. This event always triggers for regular files. - -## `eventrwflags`: `Record` -The state of the file descriptor subscribed to with -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 2 - -Alignment: 2 - -### Record members -- `fd_readwrite_hangup`: `bool` -The peer of this socket has closed or disconnected. - -Bit: 0 - -## `event_fd_readwrite`: `Record` -The contents of an [`event`](#event) for the [`eventtype::fd_read`](#eventtype.fd_read) and -[`eventtype::fd_write`](#eventtype.fd_write) variants - -Size: 16 - -Alignment: 8 - -### Record members -- `nbytes`: [`filesize`](#filesize) -The number of bytes available for reading or writing. - -Offset: 0 - -- `flags`: [`eventrwflags`](#eventrwflags) -The state of the file descriptor. - -Offset: 8 - -## `event`: `Record` -An event that occurred. - -Size: 32 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). - -Offset: 0 - -- `error`: [`errno`](#errno) -If non-zero, an error that occurred while processing the subscription request. - -Offset: 8 - -- `type`: [`eventtype`](#eventtype) -The type of event that occured - -Offset: 10 - -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. - -Offset: 16 - -## `subclockflags`: `Record` -Flags determining how to interpret the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout). - -Size: 2 - -Alignment: 2 - -### Record members -- `subscription_clock_abstime`: `bool` -If set, treat the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock -[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp -provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the -current time value of clock [`subscription_clock::id`](#subscription_clock.id). - -Bit: 0 - -## `subscription_clock`: `Record` -The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). - -Size: 40 - -Alignment: 8 - -### Record members -- `identifier`: [`userdata`](#userdata) -The user-defined unique identifier of the clock. - -Offset: 0 - -- `id`: [`clockid`](#clockid) -The clock against which to compare the timestamp. - -Offset: 8 - -- `timeout`: [`timestamp`](#timestamp) -The absolute or relative timestamp. - -Offset: 16 - -- `precision`: [`timestamp`](#timestamp) -The amount of time that the implementation may wait additionally -to coalesce with other events. - -Offset: 24 - -- `flags`: [`subclockflags`](#subclockflags) -Flags specifying whether the timeout is absolute or relative - -Offset: 32 - -## `subscription_fd_readwrite`: `Record` -The contents of a [`subscription`](#subscription) when the variant is -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 4 - -Alignment: 4 - -### Record members -- `file_descriptor`: [`fd`](#fd) -The file descriptor on which to wait for it to become ready for reading or writing. - -Offset: 0 - -## `subscription_u`: `Variant` -The contents of a [`subscription`](#subscription). - -Size: 48 - -Alignment: 8 - -### Variant Layout -- size: 48 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock`: [`subscription_clock`](#subscription_clock) - -- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -## `subscription`: `Record` -Subscription to an event. - -Size: 56 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that is attached to the subscription in the -implementation and returned through [`event::userdata`](#event.userdata). - -Offset: 0 - -- `u`: [`subscription_u`](#subscription_u) -The type of the event to which to subscribe. - -Offset: 8 - -## `exitcode`: `u32` -Exit code generated by a process when exiting. - -Size: 4 - -Alignment: 4 - -## `signal`: `Variant` -Signal condition. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `none` -No signal. Note that POSIX has special semantics for `kill(pid, 0)`, -so this value is reserved. - -- `hup` -Hangup. -Action: Terminates the process. - -- `int` -Terminate interrupt signal. -Action: Terminates the process. - -- `quit` -Terminal quit signal. -Action: Terminates the process. - -- `ill` -Illegal instruction. -Action: Terminates the process. - -- `trap` -Trace/breakpoint trap. -Action: Terminates the process. - -- `abrt` -Process abort signal. -Action: Terminates the process. - -- `bus` -Access to an undefined portion of a memory object. -Action: Terminates the process. - -- `fpe` -Erroneous arithmetic operation. -Action: Terminates the process. - -- `kill` -Kill. -Action: Terminates the process. - -- `usr1` -User-defined signal 1. -Action: Terminates the process. - -- `segv` -Invalid memory reference. -Action: Terminates the process. - -- `usr2` -User-defined signal 2. -Action: Terminates the process. - -- `pipe` -Write on a pipe with no one to read it. -Action: Ignored. - -- `alrm` -Alarm clock. -Action: Terminates the process. - -- `term` -Termination signal. -Action: Terminates the process. - -- `chld` -Child process terminated, stopped, or continued. -Action: Ignored. - -- `cont` -Continue executing, if stopped. -Action: Continues executing, if stopped. - -- `stop` -Stop executing. -Action: Stops executing. - -- `tstp` -Terminal stop signal. -Action: Stops executing. - -- `ttin` -Background process attempting read. -Action: Stops executing. - -- `ttou` -Background process attempting write. -Action: Stops executing. - -- `urg` -High bandwidth data is available at a socket. -Action: Ignored. - -- `xcpu` -CPU time limit exceeded. -Action: Terminates the process. - -- `xfsz` -File size limit exceeded. -Action: Terminates the process. - -- `vtalrm` -Virtual timer expired. -Action: Terminates the process. - -- `prof` -Profiling timer expired. -Action: Terminates the process. - -- `winch` -Window changed. -Action: Ignored. - -- `poll` -I/O possible. -Action: Terminates the process. - -- `pwr` -Power failure. -Action: Terminates the process. - -- `sys` -Bad system call. -Action: Terminates the process. - -## `riflags`: `Record` -Flags provided to [`sock_recv`](#sock_recv). - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_peek`: `bool` -Returns the message without removing it from the socket's receive queue. - -Bit: 0 - -- `recv_waitall`: `bool` -On byte-stream sockets, block until the full amount of data can be returned. - -Bit: 1 - -## `roflags`: `Record` -Flags returned by [`sock_recv`](#sock_recv). - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_data_truncated`: `bool` -Returned by [`sock_recv`](#sock_recv): Message data has been truncated. - -Bit: 0 - -## `siflags`: `u16` -Flags provided to [`sock_send`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Size: 2 - -Alignment: 2 - -## `sdflags`: `Record` -Which channels on a socket to shut down. - -Size: 1 - -Alignment: 1 - -### Record members -- `rd`: `bool` -Disables further receive operations. - -Bit: 0 - -- `wr`: `bool` -Disables further send operations. - -Bit: 1 - -## `preopentype`: `Variant` -Identifiers for preopened capabilities. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `dir` -A pre-opened directory. - -## `prestat_dir`: `Record` -The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). - -Size: 4 - -Alignment: 4 - -### Record members -- `pr_name_len`: [`size`](#size) -The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). - -Offset: 0 - -## `prestat`: `Variant` -Information about a pre-opened capability. - -Size: 8 - -Alignment: 4 - -### Variant Layout -- size: 8 -- align: 4 -- tag_size: 1 -### Variant cases -- `dir`: [`prestat_dir`](#prestat_dir) - -# Modules -## wasi_unstable -### Imports -#### Memory -### Functions - ---- - -#### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` -Read command-line argument data. -The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get). -Each argument is expected to be `\0` terminated. - -##### Params -- `argv`: `Pointer>` - -- `argv_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `args_sizes_get() -> Result<(size, size), errno>` -Return command-line argument data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of arguments and the size of the argument string -data, or an error. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` -Read environment variable data. -The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). -Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - -##### Params -- `environ`: `Pointer>` - -- `environ_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `environ_sizes_get() -> Result<(size, size), errno>` -Return environment variable data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of environment variable arguments and the size of the -environment variable data. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `clock_res_get(id: clockid) -> Result` -Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return -[`errno::inval`](#errno.inval). -Note: This is similar to `clock_getres` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the resolution. - -##### Results -- `error`: `Result` -The resolution of the clock, or an error if one happened. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `clock_time_get(id: clockid, precision: timestamp) -> Result` -Return the time value of a clock. -Note: This is similar to `clock_gettime` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the time. - -- `precision`: [`timestamp`](#timestamp) -The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - -##### Results -- `error`: `Result` -The time value of the clock. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` -Provide file advisory information on a file descriptor. -Note: This is similar to `posix_fadvise` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset within the file to which the advisory applies. - -- `len`: [`filesize`](#filesize) -The length of the region to which the advisory applies. - -- `advice`: [`advice`](#advice) -The advice. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` -Force the allocation of space in a file. -Note: This is similar to `posix_fallocate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset at which to start the allocation. - -- `len`: [`filesize`](#filesize) -The length of the area that is allocated. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_close(fd: fd) -> Result<(), errno>` -Close a file descriptor. -Note: This is similar to `close` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_datasync(fd: fd) -> Result<(), errno>` -Synchronize the data of a file to disk. -Note: This is similar to `fdatasync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_get(fd: fd) -> Result` -Get the attributes of a file descriptor. -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file descriptor's attributes are stored. - -###### Variant Layout -- size: 32 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`fdstat`](#fdstat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` -Adjust the flags associated with a file descriptor. -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`fdflags`](#fdflags) -The desired values of the file descriptor flags. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` -Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights - -##### Params -- `fd`: [`fd`](#fd) - -- `fs_rights_base`: [`rights`](#rights) -The desired rights of the file descriptor. - -- `fs_rights_inheriting`: [`rights`](#rights) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_get(fd: fd) -> Result` -Return the attributes of an open file. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 64 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` -Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. -Note: This is similar to `ftruncate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `size`: [`filesize`](#filesize) -The desired file size. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of an open file or directory. -Note: This is similar to `futimens` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` -Read from a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `preadv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors in which to store data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to read. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_prestat_get(fd: fd) -> Result` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the description is stored. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`prestat`](#prestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `Pointer` -A buffer into which to write the preopened directory name. - -- `path_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` -Write to a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `pwritev` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to write. - -##### Results -- `error`: `Result` -The number of bytes written. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_read(fd: fd, iovs: iovec_array) -> Result` -Read from a file descriptor. -Note: This is similar to `readv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` -Read directory entries from a directory. -When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a [`dirent`](#dirent) object, -followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory -entry. -This function fills the output buffer as much as possible, potentially -truncating the last directory entry. This allows the caller to grow its -read buffer size in case it's too small to fit a single large directory -entry, or skip the oversized directory entry. - -##### Params -- `fd`: [`fd`](#fd) - -- `buf`: `Pointer` -The buffer where directory entries are stored - -- `buf_len`: [`size`](#size) - -- `cookie`: [`dircookie`](#dircookie) -The location within the directory to start reading - -##### Results -- `error`: `Result` -The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_renumber(fd: fd, to: fd) -> Result<(), errno>` -Atomically replace a file descriptor by renumbering another file descriptor. -Due to the strong focus on thread safety, this environment does not provide -a mechanism to duplicate or renumber a file descriptor to an arbitrary -number, like `dup2()`. This would be prone to race conditions, as an actual -file descriptor with the same number could be allocated by a different -thread at the same time. -This function provides a way to atomically renumber file descriptors, which -would disappear if `dup2()` were to be removed entirely. - -##### Params -- `fd`: [`fd`](#fd) - -- `to`: [`fd`](#fd) -The file descriptor to overwrite. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> Result` -Move the offset of a file descriptor. -Note: This is similar to `lseek` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filedelta`](#filedelta) -The number of bytes to move. - -- `whence`: [`whence`](#whence) -The base from which the offset is relative. - -##### Results -- `error`: `Result` -The new offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_sync(fd: fd) -> Result<(), errno>` -Synchronize the data and metadata of a file to disk. -Note: This is similar to `fsync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_tell(fd: fd) -> Result` -Return the current offset of a file descriptor. -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The current offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_write(fd: fd, iovs: ciovec_array) -> Result` -Write to a file descriptor. -Note: This is similar to `writev` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -##### Results -- `error`: `Result` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_create_directory(fd: fd, path: string) -> Result<(), errno>` -Create a directory. -Note: This is similar to `mkdirat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path at which to create the directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` -Return the attributes of a file or directory. -Note: This is similar to `stat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to inspect. - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 64 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of a file or directory. -Note: This is similar to `utimensat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to operate on. - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Create a hard link. -Note: This is similar to `linkat` in POSIX. - -##### Params -- `old_fd`: [`fd`](#fd) - -- `old_flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `old_path`: `string` -The source path from which to link. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path at which to create the hard link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> Result` -Open a file or directory. -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since this -is error-prone in multi-threaded contexts. The returned file descriptor is -guaranteed to be less than 2**31. -Note: This is similar to `openat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `dirflags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The relative path of the file or directory to open, relative to the -[`path_open::fd`](#path_open.fd) directory. - -- `oflags`: [`oflags`](#oflags) -The method by which to open the file. - -- `fs_rights_base`: [`rights`](#rights) -The initial rights of the newly created file descriptor. The -implementation is allowed to return a file descriptor with fewer rights -than specified, if and only if those rights do not apply to the type of -file being opened. -The *base* rights are rights that will apply to operations using the file -descriptor itself, while the *inheriting* rights are rights that apply to -file descriptors derived from it. - -- `fs_rights_inheriting`: [`rights`](#rights) - -- `fdflags`: [`fdflags`](#fdflags) - -##### Results -- `error`: `Result` -The file descriptor of the file that has been opened. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`fd`](#fd) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` -Read the contents of a symbolic link. -Note: This is similar to `readlinkat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path of the symbolic link from which to read. - -- `buf`: `Pointer` -The buffer to which to write the contents of the symbolic link. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result` -The number of bytes placed in the buffer. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_remove_directory(fd: fd, path: string) -> Result<(), errno>` -Remove a directory. -Return [`errno::notempty`](#errno.notempty) if the directory is not empty. -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a directory to remove. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Rename a file or directory. -Note: This is similar to `renameat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `old_path`: `string` -The source path of the file or directory to rename. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path to which to rename the file or directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` -Create a symbolic link. -Note: This is similar to `symlinkat` in POSIX. - -##### Params -- `old_path`: `string` -The contents of the symbolic link. - -- `fd`: [`fd`](#fd) - -- `new_path`: `string` -The destination path at which to create the symbolic link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_unlink_file(fd: fd, path: string) -> Result<(), errno>` -Unlink a file. -Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a file to unlink. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` -Concurrently poll for the occurrence of a set of events. - -##### Params -- `in`: `ConstPointer` -The events to which to subscribe. - -- `out`: `Pointer` -The events that have occurred. - -- `nsubscriptions`: [`size`](#size) -Both the number of subscriptions and events. - -##### Results -- `error`: `Result` -The number of events stored. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `proc_exit(rval: exitcode)` -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -##### Params -- `rval`: [`exitcode`](#exitcode) -The exit code returned by the process. - -##### Results - ---- - -#### `proc_raise(sig: signal) -> Result<(), errno>` -Send a signal to the process of the calling thread. -Note: This is similar to `raise` in POSIX. - -##### Params -- `sig`: [`signal`](#signal) -The signal condition to trigger. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sched_yield() -> Result<(), errno>` -Temporarily yield execution of the calling thread. -Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. - -##### Params -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `random_get(buf: Pointer, buf_len: size) -> Result<(), errno>` -Write high-quality random data into a buffer. -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. -This function may execute slowly, so when large mounts of random data are -required, it's advisable to use this function to seed a pseudo-random -number generator, rather than to provide the random data directly. - -##### Params -- `buf`: `Pointer` -The buffer to fill with random data. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` -Receive a message from a socket. -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -##### Params -- `fd`: [`fd`](#fd) - -- `ri_data`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -- `ri_flags`: [`riflags`](#riflags) -Message flags. - -##### Results -- `error`: `Result<(size, roflags), errno>` -Number of bytes stored in ri_data and message flags. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, roflags)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`roflags`](#roflags) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` -Send a message on a socket. -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -##### Params -- `fd`: [`fd`](#fd) - -- `si_data`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors to which to retrieve data - -- `si_flags`: [`siflags`](#siflags) -Message flags. - -##### Results -- `error`: `Result` -Number of bytes transmitted. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_shutdown(fd: fd, how: sdflags) -> Result<(), errno>` -Shut down socket send and receive channels. -Note: This is similar to `shutdown` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `how`: [`sdflags`](#sdflags) -Which channels on the socket to shut down. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - diff --git a/proposals/random/phases/old/snapshot_0/witx/typenames.witx b/proposals/random/phases/old/snapshot_0/witx/typenames.witx deleted file mode 100644 index f4ba78802..000000000 --- a/proposals/random/phases/old/snapshot_0/witx/typenames.witx +++ /dev/null @@ -1,746 +0,0 @@ -;; Type names used by low-level WASI interfaces. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/main/docs/witx.md) -;; for an explanation of what that means. - -(typename $size u32) - -;;; Non-negative file size or length of a region within a file. -(typename $filesize u64) - -;;; Timestamp in nanoseconds. -(typename $timestamp u64) - -;;; Identifiers for clocks. -(typename $clockid - (enum (@witx tag u32) - ;;; The clock measuring real time. Time value zero corresponds with - ;;; 1970-01-01T00:00:00Z. - $realtime - ;;; The store-wide monotonic clock, which is defined as a clock measuring - ;;; real time, whose value cannot be adjusted and which cannot have negative - ;;; clock jumps. The epoch of this clock is undefined. The absolute time - ;;; value of this clock therefore has no meaning. - $monotonic - ;;; The CPU-time clock associated with the current process. - $process_cputime_id - ;;; The CPU-time clock associated with the current thread. - $thread_cputime_id - ) -) - -;;; Error codes returned by functions. -;;; Not all of these error codes are returned by the functions provided by this -;;; API; some are used in higher-level library layers, and others are provided -;;; merely for alignment with POSIX. -(typename $errno - (enum (@witx tag u16) - ;;; No error occurred. System call completed successfully. - $success - ;;; Argument list too long. - $2big - ;;; Permission denied. - $acces - ;;; Address in use. - $addrinuse - ;;; Address not available. - $addrnotavail - ;;; Address family not supported. - $afnosupport - ;;; Resource unavailable, or operation would block. - $again - ;;; Connection already in progress. - $already - ;;; Bad file descriptor. - $badf - ;;; Bad message. - $badmsg - ;;; Device or resource busy. - $busy - ;;; Operation canceled. - $canceled - ;;; No child processes. - $child - ;;; Connection aborted. - $connaborted - ;;; Connection refused. - $connrefused - ;;; Connection reset. - $connreset - ;;; Resource deadlock would occur. - $deadlk - ;;; Destination address required. - $destaddrreq - ;;; Mathematics argument out of domain of function. - $dom - ;;; Reserved. - $dquot - ;;; File exists. - $exist - ;;; Bad address. - $fault - ;;; File too large. - $fbig - ;;; Host is unreachable. - $hostunreach - ;;; Identifier removed. - $idrm - ;;; Illegal byte sequence. - $ilseq - ;;; Operation in progress. - $inprogress - ;;; Interrupted function. - $intr - ;;; Invalid argument. - $inval - ;;; I/O error. - $io - ;;; Socket is connected. - $isconn - ;;; Is a directory. - $isdir - ;;; Too many levels of symbolic links. - $loop - ;;; File descriptor value too large. - $mfile - ;;; Too many links. - $mlink - ;;; Message too large. - $msgsize - ;;; Reserved. - $multihop - ;;; Filename too long. - $nametoolong - ;;; Network is down. - $netdown - ;;; Connection aborted by network. - $netreset - ;;; Network unreachable. - $netunreach - ;;; Too many files open in system. - $nfile - ;;; No buffer space available. - $nobufs - ;;; No such device. - $nodev - ;;; No such file or directory. - $noent - ;;; Executable file format error. - $noexec - ;;; No locks available. - $nolck - ;;; Reserved. - $nolink - ;;; Not enough space. - $nomem - ;;; No message of the desired type. - $nomsg - ;;; Protocol not available. - $noprotoopt - ;;; No space left on device. - $nospc - ;;; Function not supported. - $nosys - ;;; The socket is not connected. - $notconn - ;;; Not a directory or a symbolic link to a directory. - $notdir - ;;; Directory not empty. - $notempty - ;;; State not recoverable. - $notrecoverable - ;;; Not a socket. - $notsock - ;;; Not supported, or operation not supported on socket. - $notsup - ;;; Inappropriate I/O control operation. - $notty - ;;; No such device or address. - $nxio - ;;; Value too large to be stored in data type. - $overflow - ;;; Previous owner died. - $ownerdead - ;;; Operation not permitted. - $perm - ;;; Broken pipe. - $pipe - ;;; Protocol error. - $proto - ;;; Protocol not supported. - $protonosupport - ;;; Protocol wrong type for socket. - $prototype - ;;; Result too large. - $range - ;;; Read-only file system. - $rofs - ;;; Invalid seek. - $spipe - ;;; No such process. - $srch - ;;; Reserved. - $stale - ;;; Connection timed out. - $timedout - ;;; Text file busy. - $txtbsy - ;;; Cross-device link. - $xdev - ;;; Extension: Capabilities insufficient. - $notcapable - ) -) - -;;; File descriptor rights, determining which actions may be performed. -(typename $rights - (flags (@witx repr u64) - ;;; The right to invoke `fd_datasync`. - ;; - ;;; If `rights::path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::dsync`. - $fd_datasync - ;;; The right to invoke `fd_read` and `sock_recv`. - ;; - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. - $fd_read - ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. - $fd_seek - ;;; The right to invoke `fd_fdstat_set_flags`. - $fd_fdstat_set_flags - ;;; The right to invoke `fd_sync`. - ;; - ;;; If `rights::path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. - $fd_sync - ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to - ;;; invoke `fd_tell`. - $fd_tell - ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. - $fd_write - ;;; The right to invoke `fd_advise`. - $fd_advise - ;;; The right to invoke `fd_allocate`. - $fd_allocate - ;;; The right to invoke `path_create_directory`. - $path_create_directory - ;;; If `rights::path_open` is set, the right to invoke `path_open` with `oflags::creat`. - $path_create_file - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; source directory. - $path_link_source - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; target directory. - $path_link_target - ;;; The right to invoke `path_open`. - $path_open - ;;; The right to invoke `fd_readdir`. - $fd_readdir - ;;; The right to invoke `path_readlink`. - $path_readlink - ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $path_rename_source - ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $path_rename_target - ;;; The right to invoke `path_filestat_get`. - $path_filestat_get - ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `rights::path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. - $path_filestat_set_size - ;;; The right to invoke `path_filestat_set_times`. - $path_filestat_set_times - ;;; The right to invoke `fd_filestat_get`. - $fd_filestat_get - ;;; The right to invoke `fd_filestat_set_size`. - $fd_filestat_set_size - ;;; The right to invoke `fd_filestat_set_times`. - $fd_filestat_set_times - ;;; The right to invoke `path_symlink`. - $path_symlink - ;;; The right to invoke `path_remove_directory`. - $path_remove_directory - ;;; The right to invoke `path_unlink_file`. - $path_unlink_file - ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. - ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. - $poll_fd_readwrite - ;;; The right to invoke `sock_shutdown`. - $sock_shutdown - ) -) - -;;; A file descriptor handle. -(typename $fd (handle)) - -;;; A region of memory for scatter/gather reads. -(typename $iovec - (record - ;;; The address of the buffer to be filled. - (field $buf (@witx pointer u8)) - ;;; The length of the buffer to be filled. - (field $buf_len $size) - ) -) - -;;; A region of memory for scatter/gather writes. -(typename $ciovec - (record - ;;; The address of the buffer to be written. - (field $buf (@witx const_pointer u8)) - ;;; The length of the buffer to be written. - (field $buf_len $size) - ) -) - -(typename $iovec_array (list $iovec)) -(typename $ciovec_array (list $ciovec)) - -;;; Relative offset within a file. -(typename $filedelta s64) - -;;; The position relative to which to set the offset of the file descriptor. -(typename $whence - (enum (@witx tag u8) - ;;; Seek relative to current position. - $cur - ;;; Seek relative to end-of-file. - $end - ;;; Seek relative to start-of-file. - $set - ) -) - -;;; A reference to the offset of a directory entry. -(typename $dircookie u64) - -;;; The type for the `dirent::d_namlen` field of `dirent` struct. -(typename $dirnamlen u32) - -;;; File serial number that is unique within its file system. -(typename $inode u64) - -;;; The type of a file descriptor or file. -(typename $filetype - (enum (@witx tag u8) - ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $unknown - ;;; The file descriptor or file refers to a block device inode. - $block_device - ;;; The file descriptor or file refers to a character device inode. - $character_device - ;;; The file descriptor or file refers to a directory inode. - $directory - ;;; The file descriptor or file refers to a regular file inode. - $regular_file - ;;; The file descriptor or file refers to a datagram socket. - $socket_dgram - ;;; The file descriptor or file refers to a byte-stream socket. - $socket_stream - ;;; The file refers to a symbolic link inode. - $symbolic_link - ) -) - -;;; A directory entry. -(typename $dirent - (record - ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie) - ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) - ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype) - ) -) - -;;; File or memory access pattern advisory information. -(typename $advice - (enum (@witx tag u8) - ;;; The application has no advice to give on its behavior with respect to the specified data. - $normal - ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $sequential - ;;; The application expects to access the specified data in a random order. - $random - ;;; The application expects to access the specified data in the near future. - $willneed - ;;; The application expects that it will not access the specified data in the near future. - $dontneed - ;;; The application expects to access the specified data once and then not reuse it thereafter. - $noreuse - ) -) - -;;; File descriptor flags. -(typename $fdflags - (flags (@witx repr u16) - ;;; Append mode: Data written to the file is always appended to the file's end. - $append - ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $dsync - ;;; Non-blocking mode. - $nonblock - ;;; Synchronized read I/O operations. - $rsync - ;;; Write according to synchronized I/O file integrity completion. In - ;;; addition to synchronizing the data stored in the file, the implementation - ;;; may also synchronously update the file's metadata. - $sync - ) -) - -;;; File descriptor attributes. -(typename $fdstat - (record - ;;; File type. - (field $fs_filetype $filetype) - ;;; File descriptor flags. - (field $fs_flags $fdflags) - ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights) - ;;; Maximum set of rights that may be installed on new file descriptors that - ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights) - ) -) - -;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode` to uniquely identify a file or directory in the filesystem. -(typename $device u64) - -;;; Which file time attributes to adjust. -(typename $fstflags - (flags (@witx repr u16) - ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. - $atim - ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. - $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. - $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. - $mtim_now - ) -) - -;;; Flags determining the method of how paths are resolved. -(typename $lookupflags - (flags (@witx repr u32) - ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $symlink_follow - ) -) - -;;; Open flags used by `path_open`. -(typename $oflags - (flags (@witx repr u16) - ;;; Create file if it does not exist. - $creat - ;;; Fail if not a directory. - $directory - ;;; Fail if file already exists. - $excl - ;;; Truncate file to size 0. - $trunc - ) -) - -;;; Number of hard links to an inode. -(typename $linkcount u32) - -;;; File attributes. -(typename $filestat - (record - ;;; Device ID of device containing the file. - (field $dev $device) - ;;; File serial number. - (field $ino $inode) - ;;; File type. - (field $filetype $filetype) - ;;; Number of hard links to the file. - (field $nlink $linkcount) - ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $size $filesize) - ;;; Last data access timestamp. - (field $atim $timestamp) - ;;; Last data modification timestamp. - (field $mtim $timestamp) - ;;; Last file status change timestamp. - (field $ctim $timestamp) - ) -) - -;;; User-provided value that may be attached to objects that is retained when -;;; extracted from the implementation. -(typename $userdata u64) - -;;; Type of a subscription to an event or its occurrence. -(typename $eventtype - (enum (@witx tag u8) - ;;; The time value of clock `subscription_clock::id` has - ;;; reached timestamp `subscription_clock::timeout`. - $clock - ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has data - ;;; available for reading. This event always triggers for regular files. - $fd_read - ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has capacity - ;;; available for writing. This event always triggers for regular files. - $fd_write - ) -) - -;;; The state of the file descriptor subscribed to with -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $eventrwflags - (flags (@witx repr u16) - ;;; The peer of this socket has closed or disconnected. - $fd_readwrite_hangup - ) -) - -;;; The contents of an `event` for the `eventtype::fd_read` and -;;; `eventtype::fd_write` variants -(typename $event_fd_readwrite - (record - ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize) - ;;; The state of the file descriptor. - (field $flags $eventrwflags) - ) -) - -;;; An event that occurred. -(typename $event - (record - ;;; User-provided value that got attached to `subscription::userdata`. - (field $userdata $userdata) - ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno) - ;;; The type of event that occured - (field $type $eventtype) - ;;; The contents of the event, if it is an `eventtype::fd_read` or - ;;; `eventtype::fd_write`. `eventtype::clock` events ignore this field. - (field $fd_readwrite $event_fd_readwrite) - ) -) - -;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_clock::timeout`. -(typename $subclockflags - (flags (@witx repr u16) - ;;; If set, treat the timestamp provided in - ;;; `subscription_clock::timeout` as an absolute timestamp of clock - ;;; `subscription_clock::id`. If clear, treat the timestamp - ;;; provided in `subscription_clock::timeout` relative to the - ;;; current time value of clock `subscription_clock::id`. - $subscription_clock_abstime - ) -) - -;;; The contents of a `subscription` when type is `eventtype::clock`. -(typename $subscription_clock - (record - ;;; The user-defined unique identifier of the clock. - (field $identifier $userdata) - ;;; The clock against which to compare the timestamp. - (field $id $clockid) - ;;; The absolute or relative timestamp. - (field $timeout $timestamp) - ;;; The amount of time that the implementation may wait additionally - ;;; to coalesce with other events. - (field $precision $timestamp) - ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags) - ) -) - -;;; The contents of a `subscription` when the variant is -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $subscription_fd_readwrite - (record - ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd) - ) -) - -;;; The contents of a `subscription`. -(typename $subscription_u - (union (@witx tag $eventtype) - $subscription_clock - $subscription_fd_readwrite - $subscription_fd_readwrite - ) -) - -;;; Subscription to an event. -(typename $subscription - (record - ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event::userdata`. - (field $userdata $userdata) - ;;; The type of the event to which to subscribe. - (field $u $subscription_u) - ) -) - -;;; Exit code generated by a process when exiting. -(typename $exitcode u32) - -;;; Signal condition. -(typename $signal - (enum (@witx tag u8) - ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;;; so this value is reserved. - $none - ;;; Hangup. - ;;; Action: Terminates the process. - $hup - ;;; Terminate interrupt signal. - ;;; Action: Terminates the process. - $int - ;;; Terminal quit signal. - ;;; Action: Terminates the process. - $quit - ;;; Illegal instruction. - ;;; Action: Terminates the process. - $ill - ;;; Trace/breakpoint trap. - ;;; Action: Terminates the process. - $trap - ;;; Process abort signal. - ;;; Action: Terminates the process. - $abrt - ;;; Access to an undefined portion of a memory object. - ;;; Action: Terminates the process. - $bus - ;;; Erroneous arithmetic operation. - ;;; Action: Terminates the process. - $fpe - ;;; Kill. - ;;; Action: Terminates the process. - $kill - ;;; User-defined signal 1. - ;;; Action: Terminates the process. - $usr1 - ;;; Invalid memory reference. - ;;; Action: Terminates the process. - $segv - ;;; User-defined signal 2. - ;;; Action: Terminates the process. - $usr2 - ;;; Write on a pipe with no one to read it. - ;;; Action: Ignored. - $pipe - ;;; Alarm clock. - ;;; Action: Terminates the process. - $alrm - ;;; Termination signal. - ;;; Action: Terminates the process. - $term - ;;; Child process terminated, stopped, or continued. - ;;; Action: Ignored. - $chld - ;;; Continue executing, if stopped. - ;;; Action: Continues executing, if stopped. - $cont - ;;; Stop executing. - ;;; Action: Stops executing. - $stop - ;;; Terminal stop signal. - ;;; Action: Stops executing. - $tstp - ;;; Background process attempting read. - ;;; Action: Stops executing. - $ttin - ;;; Background process attempting write. - ;;; Action: Stops executing. - $ttou - ;;; High bandwidth data is available at a socket. - ;;; Action: Ignored. - $urg - ;;; CPU time limit exceeded. - ;;; Action: Terminates the process. - $xcpu - ;;; File size limit exceeded. - ;;; Action: Terminates the process. - $xfsz - ;;; Virtual timer expired. - ;;; Action: Terminates the process. - $vtalrm - ;;; Profiling timer expired. - ;;; Action: Terminates the process. - $prof - ;;; Window changed. - ;;; Action: Ignored. - $winch - ;;; I/O possible. - ;;; Action: Terminates the process. - $poll - ;;; Power failure. - ;;; Action: Terminates the process. - $pwr - ;;; Bad system call. - ;;; Action: Terminates the process. - $sys - ) -) - -;;; Flags provided to `sock_recv`. -(typename $riflags - (flags (@witx repr u16) - ;;; Returns the message without removing it from the socket's receive queue. - $recv_peek - ;;; On byte-stream sockets, block until the full amount of data can be returned. - $recv_waitall - ) -) - -;;; Flags returned by `sock_recv`. -(typename $roflags - (flags (@witx repr u16) - ;;; Returned by `sock_recv`: Message data has been truncated. - $recv_data_truncated - ) -) - -;;; Flags provided to `sock_send`. As there are currently no flags -;;; defined, it must be set to zero. -(typename $siflags u16) - -;;; Which channels on a socket to shut down. -(typename $sdflags - (flags (@witx repr u8) - ;;; Disables further receive operations. - $rd - ;;; Disables further send operations. - $wr - ) -) - -;;; Identifiers for preopened capabilities. -(typename $preopentype - (enum (@witx tag u8) - ;;; A pre-opened directory. - $dir - ) -) - -;;; The contents of a $prestat when type is `preopentype::dir`. -(typename $prestat_dir - (record - ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size) - ) -) - -;;; Information about a pre-opened capability. -(typename $prestat - (union (@witx tag $preopentype) - $prestat_dir - ) -) diff --git a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx b/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx deleted file mode 100644 index dbece2641..000000000 --- a/proposals/random/phases/old/snapshot_0/witx/wasi_unstable.witx +++ /dev/null @@ -1,513 +0,0 @@ -;; WASI Preview. This is an evolution of the API that WASI initially -;; launched with. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -;;; This API predated the convention of naming modules with a `wasi_unstable_` -;;; prefix and a version number. It is preserved here for compatibility, but -;;; we shouldn't follow this pattern in new APIs. -(module $wasi_unstable - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `args_sizes_get`. - ;;; Each argument is expected to be `\0` terminated. - (@interface func (export "args_get") - (param $argv (@witx pointer (@witx pointer u8))) - (param $argv_buf (@witx pointer u8)) - (result $error (expected (error $errno))) - ) - ;;; Return command-line argument data sizes. - (@interface func (export "args_sizes_get") - ;;; Returns the number of arguments and the size of the argument string - ;;; data, or an error. - (result $error (expected (tuple $size $size) (error $errno))) - ) - - ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. - ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - (@interface func (export "environ_get") - (param $environ (@witx pointer (@witx pointer u8))) - (param $environ_buf (@witx pointer u8)) - (result $error (expected (error $errno))) - ) - ;;; Return environment variable data sizes. - (@interface func (export "environ_sizes_get") - ;;; Returns the number of environment variable arguments and the size of the - ;;; environment variable data. - (result $error (expected (tuple $size $size) (error $errno))) - ) - - ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return - ;;; `errno::inval`. - ;;; Note: This is similar to `clock_getres` in POSIX. - (@interface func (export "clock_res_get") - ;;; The clock for which to return the resolution. - (param $id $clockid) - ;;; The resolution of the clock, or an error if one happened. - (result $error (expected $timestamp (error $errno))) - ) - ;;; Return the time value of a clock. - ;;; Note: This is similar to `clock_gettime` in POSIX. - (@interface func (export "clock_time_get") - ;;; The clock for which to return the time. - (param $id $clockid) - ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp) - ;;; The time value of the clock. - (result $error (expected $timestamp (error $errno))) - ) - - ;;; Provide file advisory information on a file descriptor. - ;;; Note: This is similar to `posix_fadvise` in POSIX. - (@interface func (export "fd_advise") - (param $fd $fd) - ;;; The offset within the file to which the advisory applies. - (param $offset $filesize) - ;;; The length of the region to which the advisory applies. - (param $len $filesize) - ;;; The advice. - (param $advice $advice) - (result $error (expected (error $errno))) - ) - - ;;; Force the allocation of space in a file. - ;;; Note: This is similar to `posix_fallocate` in POSIX. - (@interface func (export "fd_allocate") - (param $fd $fd) - ;;; The offset at which to start the allocation. - (param $offset $filesize) - ;;; The length of the area that is allocated. - (param $len $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Close a file descriptor. - ;;; Note: This is similar to `close` in POSIX. - (@interface func (export "fd_close") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Synchronize the data of a file to disk. - ;;; Note: This is similar to `fdatasync` in POSIX. - (@interface func (export "fd_datasync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Get the attributes of a file descriptor. - ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (@interface func (export "fd_fdstat_get") - (param $fd $fd) - ;;; The buffer where the file descriptor's attributes are stored. - (result $error (expected $fdstat (error $errno))) - ) - - ;;; Adjust the flags associated with a file descriptor. - ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd) - ;;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights - (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd) - ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of an open file. - (@interface func (export "fd_filestat_get") - (param $fd $fd) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;;; Note: This is similar to `ftruncate` in POSIX. - (@interface func (export "fd_filestat_set_size") - (param $fd $fd) - ;;; The desired file size. - (param $size $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the timestamps of an open file or directory. - ;;; Note: This is similar to `futimens` in POSIX. - (@interface func (export "fd_filestat_set_times") - (param $fd $fd) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in POSIX. - (@interface func (export "fd_pread") - (param $fd $fd) - ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_array) - ;;; The offset within the file at which to read. - (param $offset $filesize) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_get") - (param $fd $fd) - ;;; The buffer where the description is stored. - (result $error (expected $prestat (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_dir_name") - (param $fd $fd) - ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer u8)) - (param $path_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in POSIX. - (@interface func (export "fd_pwrite") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The offset within the file at which to write. - (param $offset $filesize) - ;;; The number of bytes written. - (result $error (expected $size (error $errno))) - ) - - ;;; Read from a file descriptor. - ;;; Note: This is similar to `readv` in POSIX. - (@interface func (export "fd_read") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_array) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Read directory entries from a directory. - ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a `dirent` object, - ;;; followed by `dirent::d_namlen` bytes holding the name of the directory - ;;; entry. - ;; - ;;; This function fills the output buffer as much as possible, potentially - ;;; truncating the last directory entry. This allows the caller to grow its - ;;; read buffer size in case it's too small to fit a single large directory - ;;; entry, or skip the oversized directory entry. - (@interface func (export "fd_readdir") - (param $fd $fd) - ;;; The buffer where directory entries are stored - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The location within the directory to start reading - (param $cookie $dircookie) - ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $error (expected $size (error $errno))) - ) - - ;;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;;; Due to the strong focus on thread safety, this environment does not provide - ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;;; file descriptor with the same number could be allocated by a different - ;;; thread at the same time. - ;; - ;;; This function provides a way to atomically renumber file descriptors, which - ;;; would disappear if `dup2()` were to be removed entirely. - (@interface func (export "fd_renumber") - (param $fd $fd) - ;;; The file descriptor to overwrite. - (param $to $fd) - (result $error (expected (error $errno))) - ) - - ;;; Move the offset of a file descriptor. - ;;; Note: This is similar to `lseek` in POSIX. - (@interface func (export "fd_seek") - (param $fd $fd) - ;;; The number of bytes to move. - (param $offset $filedelta) - ;;; The base from which the offset is relative. - (param $whence $whence) - ;;; The new offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Synchronize the data and metadata of a file to disk. - ;;; Note: This is similar to `fsync` in POSIX. - (@interface func (export "fd_sync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Return the current offset of a file descriptor. - ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (@interface func (export "fd_tell") - (param $fd $fd) - ;;; The current offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Write to a file descriptor. - ;;; Note: This is similar to `writev` in POSIX. - (@interface func (export "fd_write") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - (result $error (expected $size (error $errno))) - ) - - ;;; Create a directory. - ;;; Note: This is similar to `mkdirat` in POSIX. - (@interface func (export "path_create_directory") - (param $fd $fd) - ;;; The path at which to create the directory. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of a file or directory. - ;;; Note: This is similar to `stat` in POSIX. - (@interface func (export "path_filestat_get") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to inspect. - (param $path string) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the timestamps of a file or directory. - ;;; Note: This is similar to `utimensat` in POSIX. - (@interface func (export "path_filestat_set_times") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to operate on. - (param $path string) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Create a hard link. - ;;; Note: This is similar to `linkat` in POSIX. - (@interface func (export "path_link") - (param $old_fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags) - ;;; The source path from which to link. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path at which to create the hard link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Open a file or directory. - ;; - ;;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;;; file descriptor not currently open; it is randomized to prevent - ;;; applications from depending on making assumptions about indexes, since this - ;;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;;; guaranteed to be less than 2**31. - ;; - ;;; Note: This is similar to `openat` in POSIX. - (@interface func (export "path_open") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags) - ;;; The relative path of the file or directory to open, relative to the - ;;; `path_open::fd` directory. - (param $path string) - ;;; The method by which to open the file. - (param $oflags $oflags) - ;;; The initial rights of the newly created file descriptor. The - ;;; implementation is allowed to return a file descriptor with fewer rights - ;;; than specified, if and only if those rights do not apply to the type of - ;;; file being opened. - ;; - ;;; The *base* rights are rights that will apply to operations using the file - ;;; descriptor itself, while the *inheriting* rights are rights that apply to - ;;; file descriptors derived from it. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (param $fdflags $fdflags) - ;;; The file descriptor of the file that has been opened. - (result $error (expected $fd (error $errno))) - ) - - ;;; Read the contents of a symbolic link. - ;;; Note: This is similar to `readlinkat` in POSIX. - (@interface func (export "path_readlink") - (param $fd $fd) - ;;; The path of the symbolic link from which to read. - (param $path string) - ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The number of bytes placed in the buffer. - (result $error (expected $size (error $errno))) - ) - - ;;; Remove a directory. - ;;; Return `errno::notempty` if the directory is not empty. - ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (@interface func (export "path_remove_directory") - (param $fd $fd) - ;;; The path to a directory to remove. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Rename a file or directory. - ;;; Note: This is similar to `renameat` in POSIX. - (@interface func (export "path_rename") - (param $fd $fd) - ;;; The source path of the file or directory to rename. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Create a symbolic link. - ;;; Note: This is similar to `symlinkat` in POSIX. - (@interface func (export "path_symlink") - ;;; The contents of the symbolic link. - (param $old_path string) - (param $fd $fd) - ;;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - - ;;; Unlink a file. - ;;; Return `errno::isdir` if the path refers to a directory. - ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (@interface func (export "path_unlink_file") - (param $fd $fd) - ;;; The path to a file to unlink. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Concurrently poll for the occurrence of a set of events. - (@interface func (export "poll_oneoff") - ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription)) - ;;; The events that have occurred. - (param $out (@witx pointer $event)) - ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size) - ;;; The number of events stored. - (result $error (expected $size (error $errno))) - ) - - ;;; Terminate the process normally. An exit code of 0 indicates successful - ;;; termination of the program. The meanings of other values is dependent on - ;;; the environment. - (@interface func (export "proc_exit") - ;;; The exit code returned by the process. - (param $rval $exitcode) - (@witx noreturn) - ) - - ;;; Send a signal to the process of the calling thread. - ;;; Note: This is similar to `raise` in POSIX. - (@interface func (export "proc_raise") - ;;; The signal condition to trigger. - (param $sig $signal) - (result $error (expected (error $errno))) - ) - - ;;; Temporarily yield execution of the calling thread. - ;;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "sched_yield") - (result $error (expected (error $errno))) - ) - - ;;; Write high-quality random data into a buffer. - ;;; This function blocks when the implementation is unable to immediately - ;;; provide sufficient high-quality random data. - ;;; This function may execute slowly, so when large mounts of random data are - ;;; required, it's advisable to use this function to seed a pseudo-random - ;;; number generator, rather than to provide the random data directly. - (@interface func (export "random_get") - ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Receive a message from a socket. - ;;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;;; the data into multiple buffers in the manner of `readv`. - (@interface func (export "sock_recv") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_array) - ;;; Message flags. - (param $ri_flags $riflags) - ;;; Number of bytes stored in ri_data and message flags. - (result $error (expected (tuple $size $roflags) (error $errno))) - ) - - ;;; Send a message on a socket. - ;;; Note: This is similar to `send` in POSIX, though it also supports writing - ;;; the data from multiple buffers in the manner of `writev`. - (@interface func (export "sock_send") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_array) - ;;; Message flags. - (param $si_flags $siflags) - ;;; Number of bytes transmitted. - (result $error (expected $size (error $errno))) - ) - - ;;; Shut down socket send and receive channels. - ;;; Note: This is similar to `shutdown` in POSIX. - (@interface func (export "sock_shutdown") - (param $fd $fd) - ;;; Which channels on the socket to shut down. - (param $how $sdflags) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/random/phases/snapshot/docs.html b/proposals/random/phases/snapshot/docs.html deleted file mode 100644 index 83ea3c7d2..000000000 --- a/proposals/random/phases/snapshot/docs.html +++ /dev/null @@ -1,1279 +0,0 @@ -

Types

-

<a href="#size" name="size"></a> size: u32

-

Size: 4
Alignment: 4

-

<a href="#filesize" name="filesize"></a> filesize: u64

-

Non-negative file size or length of a region within a file.
Size: 8
Alignment: 8

-

<a href="#timestamp" name="timestamp"></a> timestamp: u64

-

Timestamp in nanoseconds.
Size: 8
Alignment: 8

-

<a href="#clockid" name="clockid"></a> clockid: Enum(u32)

-

Identifiers for clocks.
Size: 4
Alignment: 4

-

Variants

-
    -
  • <a href="#clockid.realtime" name="clockid.realtime"></a> realtime
    The clock measuring real time. Time value zero corresponds with
    1970-01-01T00:00:00Z.

    -
  • -
  • <a href="#clockid.monotonic" name="clockid.monotonic"></a> monotonic
    The store-wide monotonic clock, which is defined as a clock measuring
    real time, whose value cannot be adjusted and which cannot have negative
    clock jumps. The epoch of this clock is undefined. The absolute time
    value of this clock therefore has no meaning.

    -
  • -
  • <a href="#clockid.process_cputime_id" name="clockid.process_cputime_id"></a> process_cputime_id
    The CPU-time clock associated with the current process.

    -
  • -
  • <a href="#clockid.thread_cputime_id" name="clockid.thread_cputime_id"></a> thread_cputime_id
    The CPU-time clock associated with the current thread.

    -
  • -
-

<a href="#errno" name="errno"></a> errno: Enum(u16)

-

Error codes returned by functions.
Not all of these error codes are returned by the functions provided by this
API; some are used in higher-level library layers, and others are provided
merely for alignment with POSIX.
Size: 2
Alignment: 2

-

Variants

-
    -
  • <a href="#errno.success" name="errno.success"></a> success
    No error occurred. System call completed successfully.

    -
  • -
  • <a href="#errno.2big" name="errno.2big"></a> 2big
    Argument list too long.

    -
  • -
  • <a href="#errno.acces" name="errno.acces"></a> acces
    Permission denied.

    -
  • -
  • <a href="#errno.addrinuse" name="errno.addrinuse"></a> addrinuse
    Address in use.

    -
  • -
  • <a href="#errno.addrnotavail" name="errno.addrnotavail"></a> addrnotavail
    Address not available.

    -
  • -
  • <a href="#errno.afnosupport" name="errno.afnosupport"></a> afnosupport
    Address family not supported.

    -
  • -
  • <a href="#errno.again" name="errno.again"></a> again
    Resource unavailable, or operation would block.

    -
  • -
  • <a href="#errno.already" name="errno.already"></a> already
    Connection already in progress.

    -
  • -
  • <a href="#errno.badf" name="errno.badf"></a> badf
    Bad file descriptor.

    -
  • -
  • <a href="#errno.badmsg" name="errno.badmsg"></a> badmsg
    Bad message.

    -
  • -
  • <a href="#errno.busy" name="errno.busy"></a> busy
    Device or resource busy.

    -
  • -
  • <a href="#errno.canceled" name="errno.canceled"></a> canceled
    Operation canceled.

    -
  • -
  • <a href="#errno.child" name="errno.child"></a> child
    No child processes.

    -
  • -
  • <a href="#errno.connaborted" name="errno.connaborted"></a> connaborted
    Connection aborted.

    -
  • -
  • <a href="#errno.connrefused" name="errno.connrefused"></a> connrefused
    Connection refused.

    -
  • -
  • <a href="#errno.connreset" name="errno.connreset"></a> connreset
    Connection reset.

    -
  • -
  • <a href="#errno.deadlk" name="errno.deadlk"></a> deadlk
    Resource deadlock would occur.

    -
  • -
  • <a href="#errno.destaddrreq" name="errno.destaddrreq"></a> destaddrreq
    Destination address required.

    -
  • -
  • <a href="#errno.dom" name="errno.dom"></a> dom
    Mathematics argument out of domain of function.

    -
  • -
  • <a href="#errno.dquot" name="errno.dquot"></a> dquot
    Reserved.

    -
  • -
  • <a href="#errno.exist" name="errno.exist"></a> exist
    File exists.

    -
  • -
  • <a href="#errno.fault" name="errno.fault"></a> fault
    Bad address.

    -
  • -
  • <a href="#errno.fbig" name="errno.fbig"></a> fbig
    File too large.

    -
  • -
  • <a href="#errno.hostunreach" name="errno.hostunreach"></a> hostunreach
    Host is unreachable.

    -
  • -
  • <a href="#errno.idrm" name="errno.idrm"></a> idrm
    Identifier removed.

    -
  • -
  • <a href="#errno.ilseq" name="errno.ilseq"></a> ilseq
    Illegal byte sequence.

    -
  • -
  • <a href="#errno.inprogress" name="errno.inprogress"></a> inprogress
    Operation in progress.

    -
  • -
  • <a href="#errno.intr" name="errno.intr"></a> intr
    Interrupted function.

    -
  • -
  • <a href="#errno.inval" name="errno.inval"></a> inval
    Invalid argument.

    -
  • -
  • <a href="#errno.io" name="errno.io"></a> io
    I/O error.

    -
  • -
  • <a href="#errno.isconn" name="errno.isconn"></a> isconn
    Socket is connected.

    -
  • -
  • <a href="#errno.isdir" name="errno.isdir"></a> isdir
    Is a directory.

    -
  • -
  • <a href="#errno.loop" name="errno.loop"></a> loop
    Too many levels of symbolic links.

    -
  • -
  • <a href="#errno.mfile" name="errno.mfile"></a> mfile
    File descriptor value too large.

    -
  • -
  • <a href="#errno.mlink" name="errno.mlink"></a> mlink
    Too many links.

    -
  • -
  • <a href="#errno.msgsize" name="errno.msgsize"></a> msgsize
    Message too large.

    -
  • -
  • <a href="#errno.multihop" name="errno.multihop"></a> multihop
    Reserved.

    -
  • -
  • <a href="#errno.nametoolong" name="errno.nametoolong"></a> nametoolong
    Filename too long.

    -
  • -
  • <a href="#errno.netdown" name="errno.netdown"></a> netdown
    Network is down.

    -
  • -
  • <a href="#errno.netreset" name="errno.netreset"></a> netreset
    Connection aborted by network.

    -
  • -
  • <a href="#errno.netunreach" name="errno.netunreach"></a> netunreach
    Network unreachable.

    -
  • -
  • <a href="#errno.nfile" name="errno.nfile"></a> nfile
    Too many files open in system.

    -
  • -
  • <a href="#errno.nobufs" name="errno.nobufs"></a> nobufs
    No buffer space available.

    -
  • -
  • <a href="#errno.nodev" name="errno.nodev"></a> nodev
    No such device.

    -
  • -
  • <a href="#errno.noent" name="errno.noent"></a> noent
    No such file or directory.

    -
  • -
  • <a href="#errno.noexec" name="errno.noexec"></a> noexec
    Executable file format error.

    -
  • -
  • <a href="#errno.nolck" name="errno.nolck"></a> nolck
    No locks available.

    -
  • -
  • <a href="#errno.nolink" name="errno.nolink"></a> nolink
    Reserved.

    -
  • -
  • <a href="#errno.nomem" name="errno.nomem"></a> nomem
    Not enough space.

    -
  • -
  • <a href="#errno.nomsg" name="errno.nomsg"></a> nomsg
    No message of the desired type.

    -
  • -
  • <a href="#errno.noprotoopt" name="errno.noprotoopt"></a> noprotoopt
    Protocol not available.

    -
  • -
  • <a href="#errno.nospc" name="errno.nospc"></a> nospc
    No space left on device.

    -
  • -
  • <a href="#errno.nosys" name="errno.nosys"></a> nosys
    Function not supported.

    -
  • -
  • <a href="#errno.notconn" name="errno.notconn"></a> notconn
    The socket is not connected.

    -
  • -
  • <a href="#errno.notdir" name="errno.notdir"></a> notdir
    Not a directory or a symbolic link to a directory.

    -
  • -
  • <a href="#errno.notempty" name="errno.notempty"></a> notempty
    Directory not empty.

    -
  • -
  • <a href="#errno.notrecoverable" name="errno.notrecoverable"></a> notrecoverable
    State not recoverable.

    -
  • -
  • <a href="#errno.notsock" name="errno.notsock"></a> notsock
    Not a socket.

    -
  • -
  • <a href="#errno.notsup" name="errno.notsup"></a> notsup
    Not supported, or operation not supported on socket.

    -
  • -
  • <a href="#errno.notty" name="errno.notty"></a> notty
    Inappropriate I/O control operation.

    -
  • -
  • <a href="#errno.nxio" name="errno.nxio"></a> nxio
    No such device or address.

    -
  • -
  • <a href="#errno.overflow" name="errno.overflow"></a> overflow
    Value too large to be stored in data type.

    -
  • -
  • <a href="#errno.ownerdead" name="errno.ownerdead"></a> ownerdead
    Previous owner died.

    -
  • -
  • <a href="#errno.perm" name="errno.perm"></a> perm
    Operation not permitted.

    -
  • -
  • <a href="#errno.pipe" name="errno.pipe"></a> pipe
    Broken pipe.

    -
  • -
  • <a href="#errno.proto" name="errno.proto"></a> proto
    Protocol error.

    -
  • -
  • <a href="#errno.protonosupport" name="errno.protonosupport"></a> protonosupport
    Protocol not supported.

    -
  • -
  • <a href="#errno.prototype" name="errno.prototype"></a> prototype
    Protocol wrong type for socket.

    -
  • -
  • <a href="#errno.range" name="errno.range"></a> range
    Result too large.

    -
  • -
  • <a href="#errno.rofs" name="errno.rofs"></a> rofs
    Read-only file system.

    -
  • -
  • <a href="#errno.spipe" name="errno.spipe"></a> spipe
    Invalid seek.

    -
  • -
  • <a href="#errno.srch" name="errno.srch"></a> srch
    No such process.

    -
  • -
  • <a href="#errno.stale" name="errno.stale"></a> stale
    Reserved.

    -
  • -
  • <a href="#errno.timedout" name="errno.timedout"></a> timedout
    Connection timed out.

    -
  • -
  • <a href="#errno.txtbsy" name="errno.txtbsy"></a> txtbsy
    Text file busy.

    -
  • -
  • <a href="#errno.xdev" name="errno.xdev"></a> xdev
    Cross-device link.

    -
  • -
  • <a href="#errno.notcapable" name="errno.notcapable"></a> notcapable
    Extension: Capabilities insufficient.

    -
  • -
-

<a href="#rights" name="rights"></a> rights: Flags(u64)

-

File descriptor rights, determining which actions may be performed.
Size: 8
Alignment: 8

-

Flags

-
    -
  • <a href="#rights.fd_datasync" name="rights.fd_datasync"></a> fd_datasync
    The right to invoke fd_datasync.
    If path_open is set, includes the right to invoke
    path_open with fdflags::dsync.

    -
  • -
  • <a href="#rights.fd_read" name="rights.fd_read"></a> fd_read
    The right to invoke fd_read and sock_recv.
    If rights::fd_seek is set, includes the right to invoke fd_pread.

    -
  • -
  • <a href="#rights.fd_seek" name="rights.fd_seek"></a> fd_seek
    The right to invoke fd_seek. This flag implies rights::fd_tell.

    -
  • -
  • <a href="#rights.fd_fdstat_set_flags" name="rights.fd_fdstat_set_flags"></a> fd_fdstat_set_flags
    The right to invoke fd_fdstat_set_flags.

    -
  • -
  • <a href="#rights.fd_sync" name="rights.fd_sync"></a> fd_sync
    The right to invoke fd_sync.
    If path_open is set, includes the right to invoke
    path_open with fdflags::rsync and fdflags::dsync.

    -
  • -
  • <a href="#rights.fd_tell" name="rights.fd_tell"></a> fd_tell
    The right to invoke fd_seek in such a way that the file offset
    remains unaltered (i.e., whence::cur with offset zero), or to
    invoke fd_tell.

    -
  • -
  • <a href="#rights.fd_write" name="rights.fd_write"></a> fd_write
    The right to invoke fd_write and sock_send.
    If rights::fd_seek is set, includes the right to invoke fd_pwrite.

    -
  • -
  • <a href="#rights.fd_advise" name="rights.fd_advise"></a> fd_advise
    The right to invoke fd_advise.

    -
  • -
  • <a href="#rights.fd_allocate" name="rights.fd_allocate"></a> fd_allocate
    The right to invoke fd_allocate.

    -
  • -
  • <a href="#rights.path_create_directory" name="rights.path_create_directory"></a> path_create_directory
    The right to invoke path_create_directory.

    -
  • -
  • <a href="#rights.path_create_file" name="rights.path_create_file"></a> path_create_file
    If path_open is set, the right to invoke path_open with oflags::creat.

    -
  • -
  • <a href="#rights.path_link_source" name="rights.path_link_source"></a> path_link_source
    The right to invoke path_link with the file descriptor as the
    source directory.

    -
  • -
  • <a href="#rights.path_link_target" name="rights.path_link_target"></a> path_link_target
    The right to invoke path_link with the file descriptor as the
    target directory.

    -
  • -
  • <a href="#rights.path_open" name="rights.path_open"></a> path_open
    The right to invoke path_open.

    -
  • -
  • <a href="#rights.fd_readdir" name="rights.fd_readdir"></a> fd_readdir
    The right to invoke fd_readdir.

    -
  • -
  • <a href="#rights.path_readlink" name="rights.path_readlink"></a> path_readlink
    The right to invoke path_readlink.

    -
  • -
  • <a href="#rights.path_rename_source" name="rights.path_rename_source"></a> path_rename_source
    The right to invoke path_rename with the file descriptor as the source directory.

    -
  • -
  • <a href="#rights.path_rename_target" name="rights.path_rename_target"></a> path_rename_target
    The right to invoke path_rename with the file descriptor as the target directory.

    -
  • -
  • <a href="#rights.path_filestat_get" name="rights.path_filestat_get"></a> path_filestat_get
    The right to invoke path_filestat_get.

    -
  • -
  • <a href="#rights.path_filestat_set_size" name="rights.path_filestat_set_size"></a> path_filestat_set_size
    The right to change a file's size (there is no path_filestat_set_size).
    If path_open is set, includes the right to invoke path_open with oflags::trunc.

    -
  • -
  • <a href="#rights.path_filestat_set_times" name="rights.path_filestat_set_times"></a> path_filestat_set_times
    The right to invoke path_filestat_set_times.

    -
  • -
  • <a href="#rights.fd_filestat_get" name="rights.fd_filestat_get"></a> fd_filestat_get
    The right to invoke fd_filestat_get.

    -
  • -
  • <a href="#rights.fd_filestat_set_size" name="rights.fd_filestat_set_size"></a> fd_filestat_set_size
    The right to invoke fd_filestat_set_size.

    -
  • -
  • <a href="#rights.fd_filestat_set_times" name="rights.fd_filestat_set_times"></a> fd_filestat_set_times
    The right to invoke fd_filestat_set_times.

    -
  • -
  • <a href="#rights.path_symlink" name="rights.path_symlink"></a> path_symlink
    The right to invoke path_symlink.

    -
  • -
  • <a href="#rights.path_remove_directory" name="rights.path_remove_directory"></a> path_remove_directory
    The right to invoke path_remove_directory.

    -
  • -
  • <a href="#rights.path_unlink_file" name="rights.path_unlink_file"></a> path_unlink_file
    The right to invoke path_unlink_file.

    -
  • -
  • <a href="#rights.poll_fd_readwrite" name="rights.poll_fd_readwrite"></a> poll_fd_readwrite
    If rights::fd_read is set, includes the right to invoke poll_oneoff to subscribe to eventtype::fd_read.
    If rights::fd_write is set, includes the right to invoke poll_oneoff to subscribe to eventtype::fd_write.

    -
  • -
  • <a href="#rights.sock_shutdown" name="rights.sock_shutdown"></a> sock_shutdown
    The right to invoke sock_shutdown.

    -
  • -
-

<a href="#fd" name="fd"></a> fd

-

A file descriptor handle.
Size: 4
Alignment: 4

-

Supertypes

-

<a href="#iovec" name="iovec"></a> iovec: Struct

-

A region of memory for scatter/gather reads.
Size: 8
Alignment: 4

-

Struct members

-
    -
  • <a href="#iovec.buf" name="iovec.buf"></a> buf: Pointer<u8>
    The address of the buffer to be filled.
    Offset: 0
  • -
  • <a href="#iovec.buf_len" name="iovec.buf_len"></a> buf_len: size
    The length of the buffer to be filled.
    Offset: 4

    <a href="#ciovec" name="ciovec"></a> ciovec: Struct

    -A region of memory for scatter/gather writes.
    Size: 8
    Alignment: 4

    Struct members

    -
  • -
  • <a href="#ciovec.buf" name="ciovec.buf"></a> buf: ConstPointer<u8>
    The address of the buffer to be written.
    Offset: 0
  • -
  • <a href="#ciovec.buf_len" name="ciovec.buf_len"></a> buf_len: size
    The length of the buffer to be written.
    Offset: 4

    <a href="#iovec_array" name="iovec_array"></a> iovec_array: Array<iovec>

    -Size: 8
    Alignment: 4

    <a href="#ciovec_array" name="ciovec_array"></a> ciovec_array: Array<ciovec>

    -Size: 8
    Alignment: 4

    <a href="#filedelta" name="filedelta"></a> filedelta: s64

    -Relative offset within a file.
    Size: 8
    Alignment: 8

    <a href="#whence" name="whence"></a> whence: Enum(u8)

    -The position relative to which to set the offset of the file descriptor.
    Size: 1
    Alignment: 1

    Variants

    -
  • -
  • <a href="#whence.set" name="whence.set"></a> set
    Seek relative to start-of-file.

    -
  • -
  • <a href="#whence.cur" name="whence.cur"></a> cur
    Seek relative to current position.

    -
  • -
  • <a href="#whence.end" name="whence.end"></a> end
    Seek relative to end-of-file.

    -
  • -
-

<a href="#dircookie" name="dircookie"></a> dircookie: u64

-

A reference to the offset of a directory entry.

-

The value 0 signifies the start of the directory.
Size: 8
Alignment: 8

-

<a href="#dirnamlen" name="dirnamlen"></a> dirnamlen: u32

-

The type for the $d_namlen field of $dirent.
Size: 4
Alignment: 4

-

<a href="#inode" name="inode"></a> inode: u64

-

File serial number that is unique within its file system.
Size: 8
Alignment: 8

-

<a href="#filetype" name="filetype"></a> filetype: Enum(u8)

-

The type of a file descriptor or file.
Size: 1
Alignment: 1

-

Variants

-
    -
  • <a href="#filetype.unknown" name="filetype.unknown"></a> unknown
    The type of the file descriptor or file is unknown or is different from any of the other types specified.

    -
  • -
  • <a href="#filetype.block_device" name="filetype.block_device"></a> block_device
    The file descriptor or file refers to a block device inode.

    -
  • -
  • <a href="#filetype.character_device" name="filetype.character_device"></a> character_device
    The file descriptor or file refers to a character device inode.

    -
  • -
  • <a href="#filetype.directory" name="filetype.directory"></a> directory
    The file descriptor or file refers to a directory inode.

    -
  • -
  • <a href="#filetype.regular_file" name="filetype.regular_file"></a> regular_file
    The file descriptor or file refers to a regular file inode.

    -
  • -
  • <a href="#filetype.socket_dgram" name="filetype.socket_dgram"></a> socket_dgram
    The file descriptor or file refers to a datagram socket.

    -
  • -
  • <a href="#filetype.socket_stream" name="filetype.socket_stream"></a> socket_stream
    The file descriptor or file refers to a byte-stream socket.

    -
  • -
  • <a href="#filetype.symbolic_link" name="filetype.symbolic_link"></a> symbolic_link
    The file refers to a symbolic link inode.

    -
  • -
-

<a href="#dirent" name="dirent"></a> dirent: Struct

-

A directory entry.
Size: 24
Alignment: 8

-

Struct members

-
    -
  • <a href="#dirent.d_next" name="dirent.d_next"></a> d_next: dircookie
    The offset of the next directory entry stored in this directory.
    Offset: 0
  • -
  • <a href="#dirent.d_ino" name="dirent.d_ino"></a> d_ino: inode
    The serial number of the file referred to by this directory entry.
    Offset: 8
  • -
  • <a href="#dirent.d_namlen" name="dirent.d_namlen"></a> d_namlen: dirnamlen
    The length of the name of the directory entry.
    Offset: 16
  • -
  • <a href="#dirent.d_type" name="dirent.d_type"></a> d_type: filetype
    The type of the file referred to by this directory entry.
    Offset: 20

    <a href="#advice" name="advice"></a> advice: Enum(u8)

    -File or memory access pattern advisory information.
    Size: 1
    Alignment: 1

    Variants

    -
  • -
  • <a href="#advice.normal" name="advice.normal"></a> normal
    The application has no advice to give on its behavior with respect to the specified data.

    -
  • -
  • <a href="#advice.sequential" name="advice.sequential"></a> sequential
    The application expects to access the specified data sequentially from lower offsets to higher offsets.

    -
  • -
  • <a href="#advice.random" name="advice.random"></a> random
    The application expects to access the specified data in a random order.

    -
  • -
  • <a href="#advice.willneed" name="advice.willneed"></a> willneed
    The application expects to access the specified data in the near future.

    -
  • -
  • <a href="#advice.dontneed" name="advice.dontneed"></a> dontneed
    The application expects that it will not access the specified data in the near future.

    -
  • -
  • <a href="#advice.noreuse" name="advice.noreuse"></a> noreuse
    The application expects to access the specified data once and then not reuse it thereafter.

    -
  • -
-

<a href="#fdflags" name="fdflags"></a> fdflags: Flags(u16)

-

File descriptor flags.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#fdflags.append" name="fdflags.append"></a> append
    Append mode: Data written to the file is always appended to the file's end.

    -
  • -
  • <a href="#fdflags.dsync" name="fdflags.dsync"></a> dsync
    Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized.

    -
  • -
  • <a href="#fdflags.nonblock" name="fdflags.nonblock"></a> nonblock
    Non-blocking mode.

    -
  • -
  • <a href="#fdflags.rsync" name="fdflags.rsync"></a> rsync
    Synchronized read I/O operations.

    -
  • -
  • <a href="#fdflags.sync" name="fdflags.sync"></a> sync
    Write according to synchronized I/O file integrity completion. In
    addition to synchronizing the data stored in the file, the implementation
    may also synchronously update the file's metadata.

    -
  • -
-

<a href="#fdstat" name="fdstat"></a> fdstat: Struct

-

File descriptor attributes.
Size: 24
Alignment: 8

-

Struct members

-
    -
  • <a href="#fdstat.fs_filetype" name="fdstat.fs_filetype"></a> fs_filetype: filetype
    File type.
    Offset: 0
  • -
  • <a href="#fdstat.fs_flags" name="fdstat.fs_flags"></a> fs_flags: fdflags
    File descriptor flags.
    Offset: 2
  • -
  • <a href="#fdstat.fs_rights_base" name="fdstat.fs_rights_base"></a> fs_rights_base: rights
    Rights that apply to this file descriptor.
    Offset: 8
  • -
  • <a href="#fdstat.fs_rights_inheriting" name="fdstat.fs_rights_inheriting"></a> fs_rights_inheriting: rights
    Maximum set of rights that may be installed on new file descriptors that
    are created through this file descriptor, e.g., through path_open.
    Offset: 16

    <a href="#device" name="device"></a> device: u64

    -Identifier for a device containing a file system. Can be used in combination
    with inode to uniquely identify a file or directory in the filesystem.
    Size: 8
    Alignment: 8

    <a href="#fstflags" name="fstflags"></a> fstflags: Flags(u16)

    -Which file time attributes to adjust.
    Size: 2
    Alignment: 2

    Flags

    -
  • -
  • <a href="#fstflags.atim" name="fstflags.atim"></a> atim
    Adjust the last data access timestamp to the value stored in filestat::atim.

    -
  • -
  • <a href="#fstflags.atim_now" name="fstflags.atim_now"></a> atim_now
    Adjust the last data access timestamp to the time of clock clockid::realtime.

    -
  • -
  • <a href="#fstflags.mtim" name="fstflags.mtim"></a> mtim
    Adjust the last data modification timestamp to the value stored in filestat::mtim.

    -
  • -
  • <a href="#fstflags.mtim_now" name="fstflags.mtim_now"></a> mtim_now
    Adjust the last data modification timestamp to the time of clock clockid::realtime.

    -
  • -
-

<a href="#lookupflags" name="lookupflags"></a> lookupflags: Flags(u32)

-

Flags determining the method of how paths are resolved.
Size: 4
Alignment: 4

-

Flags

-
    -
  • <a href="#lookupflags.symlink_follow" name="lookupflags.symlink_follow"></a> symlink_follow
    As long as the resolved path corresponds to a symbolic link, it is expanded.
  • -
-

<a href="#oflags" name="oflags"></a> oflags: Flags(u16)

-

Open flags used by path_open.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#oflags.creat" name="oflags.creat"></a> creat
    Create file if it does not exist.

    -
  • -
  • <a href="#oflags.directory" name="oflags.directory"></a> directory
    Fail if not a directory.

    -
  • -
  • <a href="#oflags.excl" name="oflags.excl"></a> excl
    Fail if file already exists.

    -
  • -
  • <a href="#oflags.trunc" name="oflags.trunc"></a> trunc
    Truncate file to size 0.

    -
  • -
-

<a href="#linkcount" name="linkcount"></a> linkcount: u64

-

Number of hard links to an inode.
Size: 8
Alignment: 8

-

<a href="#filestat" name="filestat"></a> filestat: Struct

-

File attributes.
Size: 64
Alignment: 8

-

Struct members

-
    -
  • <a href="#filestat.dev" name="filestat.dev"></a> dev: device
    Device ID of device containing the file.
    Offset: 0
  • -
  • <a href="#filestat.ino" name="filestat.ino"></a> ino: inode
    File serial number.
    Offset: 8
  • -
  • <a href="#filestat.filetype" name="filestat.filetype"></a> filetype: filetype
    File type.
    Offset: 16
  • -
  • <a href="#filestat.nlink" name="filestat.nlink"></a> nlink: linkcount
    Number of hard links to the file.
    Offset: 24
  • -
  • <a href="#filestat.size" name="filestat.size"></a> size: filesize
    For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link.
    Offset: 32
  • -
  • <a href="#filestat.atim" name="filestat.atim"></a> atim: timestamp
    Last data access timestamp.
    Offset: 40
  • -
  • <a href="#filestat.mtim" name="filestat.mtim"></a> mtim: timestamp
    Last data modification timestamp.
    Offset: 48
  • -
  • <a href="#filestat.ctim" name="filestat.ctim"></a> ctim: timestamp
    Last file status change timestamp.
    Offset: 56

    <a href="#userdata" name="userdata"></a> userdata: u64

    -User-provided value that may be attached to objects that is retained when
    extracted from the implementation.
    Size: 8
    Alignment: 8

    <a href="#eventtype" name="eventtype"></a> eventtype: Enum(u8)

    -Type of a subscription to an event or its occurrence.
    Size: 1
    Alignment: 1

    Variants

    -
  • -
  • <a href="#eventtype.clock" name="eventtype.clock"></a> clock
    The time value of clock subscription_clock::id has
    reached timestamp subscription_clock::timeout.

    -
  • -
  • <a href="#eventtype.fd_read" name="eventtype.fd_read"></a> fd_read
    File descriptor subscription_fd_readwrite::file_descriptor has data
    available for reading. This event always triggers for regular files.

    -
  • -
  • <a href="#eventtype.fd_write" name="eventtype.fd_write"></a> fd_write
    File descriptor subscription_fd_readwrite::file_descriptor has capacity
    available for writing. This event always triggers for regular files.

    -
  • -
-

<a href="#eventrwflags" name="eventrwflags"></a> eventrwflags: Flags(u16)

-

The state of the file descriptor subscribed to with
eventtype::fd_read or eventtype::fd_write.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#eventrwflags.fd_readwrite_hangup" name="eventrwflags.fd_readwrite_hangup"></a> fd_readwrite_hangup
    The peer of this socket has closed or disconnected.
  • -
-

<a href="#event_fd_readwrite" name="event_fd_readwrite"></a> event_fd_readwrite: Struct

-

The contents of an $event when type is eventtype::fd_read or
eventtype::fd_write.
Size: 16
Alignment: 8

-

Struct members

-
    -
  • <a href="#event_fd_readwrite.nbytes" name="event_fd_readwrite.nbytes"></a> nbytes: filesize
    The number of bytes available for reading or writing.
    Offset: 0
  • -
  • <a href="#event_fd_readwrite.flags" name="event_fd_readwrite.flags"></a> flags: eventrwflags
    The state of the file descriptor.
    Offset: 8

    <a href="#event" name="event"></a> event: Struct

    -An event that occurred.
    Size: 32
    Alignment: 8

    Struct members

    -
  • -
  • <a href="#event.userdata" name="event.userdata"></a> userdata: userdata
    User-provided value that got attached to subscription::userdata.
    Offset: 0
  • -
  • <a href="#event.error" name="event.error"></a> error: errno
    If non-zero, an error that occurred while processing the subscription request.
    Offset: 8
  • -
  • <a href="#event.type" name="event.type"></a> type: eventtype
    The type of event that occured
    Offset: 10
  • -
  • <a href="#event.fd_readwrite" name="event.fd_readwrite"></a> fd_readwrite: event_fd_readwrite
    The contents of the event, if it is an eventtype::fd_read or
    eventtype::fd_write. eventtype::clock events ignore this field.
    Offset: 16

    <a href="#subclockflags" name="subclockflags"></a> subclockflags: Flags(u16)

    -Flags determining how to interpret the timestamp provided in
    subscription_clock::timeout.
    Size: 2
    Alignment: 2

    Flags

    -
  • -
  • <a href="#subclockflags.subscription_clock_abstime" name="subclockflags.subscription_clock_abstime"></a> subscription_clock_abstime
    If set, treat the timestamp provided in
    subscription_clock::timeout as an absolute timestamp of clock
    subscription_clock::id. If clear, treat the timestamp
    provided in subscription_clock::timeout relative to the
    current time value of clock subscription_clock::id.
  • -
-

<a href="#subscription_clock" name="subscription_clock"></a> subscription_clock: Struct

-

The contents of a subscription when type is eventtype::clock.
Size: 32
Alignment: 8

-

Struct members

-
    -
  • <a href="#subscription_clock.id" name="subscription_clock.id"></a> id: clockid
    The clock against which to compare the timestamp.
    Offset: 0
  • -
  • <a href="#subscription_clock.timeout" name="subscription_clock.timeout"></a> timeout: timestamp
    The absolute or relative timestamp.
    Offset: 8
  • -
  • <a href="#subscription_clock.precision" name="subscription_clock.precision"></a> precision: timestamp
    The amount of time that the implementation may wait additionally
    to coalesce with other events.
    Offset: 16
  • -
  • <a href="#subscription_clock.flags" name="subscription_clock.flags"></a> flags: subclockflags
    Flags specifying whether the timeout is absolute or relative
    Offset: 24

    <a href="#subscription_fd_readwrite" name="subscription_fd_readwrite"></a> subscription_fd_readwrite: Struct

    -The contents of a subscription when type is type is
    eventtype::fd_read or eventtype::fd_write.
    Size: 4
    Alignment: 4

    Struct members

    -
  • -
  • <a href="#subscription_fd_readwrite.file_descriptor" name="subscription_fd_readwrite.file_descriptor"></a> file_descriptor: fd
    The file descriptor on which to wait for it to become ready for reading or writing.
    Offset: 0

    <a href="#subscription_u" name="subscription_u"></a> subscription_u: Union

    -The contents of a subscription.
    Size: 40
    Alignment: 8

    Union Layout

    -
  • -
  • tag_size: 1
  • -
  • tag_align: 1
  • -
  • contents_offset: 8
  • -
  • contents_size: 32
  • -
  • contents_align: 8

    Union variants

    -
  • -
  • <a href="#subscription_u.clock" name="subscription_u.clock"></a> clock: subscription_clock

    -
  • -
  • <a href="#subscription_u.fd_read" name="subscription_u.fd_read"></a> fd_read: subscription_fd_readwrite

    -
  • -
  • <a href="#subscription_u.fd_write" name="subscription_u.fd_write"></a> fd_write: subscription_fd_readwrite

    -
  • -
-

<a href="#subscription" name="subscription"></a> subscription: Struct

-

Subscription to an event.
Size: 48
Alignment: 8

-

Struct members

-
    -
  • <a href="#subscription.userdata" name="subscription.userdata"></a> userdata: userdata
    User-provided value that is attached to the subscription in the
    implementation and returned through event::userdata.
    Offset: 0
  • -
  • <a href="#subscription.u" name="subscription.u"></a> u: subscription_u
    The type of the event to which to subscribe, and its contents
    Offset: 8

    <a href="#exitcode" name="exitcode"></a> exitcode: u32

    -Exit code generated by a process when exiting.
    Size: 4
    Alignment: 4

    <a href="#signal" name="signal"></a> signal: Enum(u8)

    -Signal condition.
    Size: 1
    Alignment: 1

    Variants

    -
  • -
  • <a href="#signal.none" name="signal.none"></a> none
    No signal. Note that POSIX has special semantics for kill(pid, 0),
    so this value is reserved.

    -
  • -
  • <a href="#signal.hup" name="signal.hup"></a> hup
    Hangup.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.int" name="signal.int"></a> int
    Terminate interrupt signal.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.quit" name="signal.quit"></a> quit
    Terminal quit signal.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.ill" name="signal.ill"></a> ill
    Illegal instruction.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.trap" name="signal.trap"></a> trap
    Trace/breakpoint trap.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.abrt" name="signal.abrt"></a> abrt
    Process abort signal.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.bus" name="signal.bus"></a> bus
    Access to an undefined portion of a memory object.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.fpe" name="signal.fpe"></a> fpe
    Erroneous arithmetic operation.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.kill" name="signal.kill"></a> kill
    Kill.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.usr1" name="signal.usr1"></a> usr1
    User-defined signal 1.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.segv" name="signal.segv"></a> segv
    Invalid memory reference.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.usr2" name="signal.usr2"></a> usr2
    User-defined signal 2.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.pipe" name="signal.pipe"></a> pipe
    Write on a pipe with no one to read it.
    Action: Ignored.

    -
  • -
  • <a href="#signal.alrm" name="signal.alrm"></a> alrm
    Alarm clock.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.term" name="signal.term"></a> term
    Termination signal.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.chld" name="signal.chld"></a> chld
    Child process terminated, stopped, or continued.
    Action: Ignored.

    -
  • -
  • <a href="#signal.cont" name="signal.cont"></a> cont
    Continue executing, if stopped.
    Action: Continues executing, if stopped.

    -
  • -
  • <a href="#signal.stop" name="signal.stop"></a> stop
    Stop executing.
    Action: Stops executing.

    -
  • -
  • <a href="#signal.tstp" name="signal.tstp"></a> tstp
    Terminal stop signal.
    Action: Stops executing.

    -
  • -
  • <a href="#signal.ttin" name="signal.ttin"></a> ttin
    Background process attempting read.
    Action: Stops executing.

    -
  • -
  • <a href="#signal.ttou" name="signal.ttou"></a> ttou
    Background process attempting write.
    Action: Stops executing.

    -
  • -
  • <a href="#signal.urg" name="signal.urg"></a> urg
    High bandwidth data is available at a socket.
    Action: Ignored.

    -
  • -
  • <a href="#signal.xcpu" name="signal.xcpu"></a> xcpu
    CPU time limit exceeded.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.xfsz" name="signal.xfsz"></a> xfsz
    File size limit exceeded.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.vtalrm" name="signal.vtalrm"></a> vtalrm
    Virtual timer expired.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.prof" name="signal.prof"></a> prof
    Profiling timer expired.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.winch" name="signal.winch"></a> winch
    Window changed.
    Action: Ignored.

    -
  • -
  • <a href="#signal.poll" name="signal.poll"></a> poll
    I/O possible.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.pwr" name="signal.pwr"></a> pwr
    Power failure.
    Action: Terminates the process.

    -
  • -
  • <a href="#signal.sys" name="signal.sys"></a> sys
    Bad system call.
    Action: Terminates the process.

    -
  • -
-

<a href="#riflags" name="riflags"></a> riflags: Flags(u16)

-

Flags provided to sock_recv.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#riflags.recv_peek" name="riflags.recv_peek"></a> recv_peek
    Returns the message without removing it from the socket's receive queue.

    -
  • -
  • <a href="#riflags.recv_waitall" name="riflags.recv_waitall"></a> recv_waitall
    On byte-stream sockets, block until the full amount of data can be returned.

    -
  • -
-

<a href="#roflags" name="roflags"></a> roflags: Flags(u16)

-

Flags returned by sock_recv.
Size: 2
Alignment: 2

-

Flags

-
    -
  • <a href="#roflags.recv_data_truncated" name="roflags.recv_data_truncated"></a> recv_data_truncated
    Returned by sock_recv: Message data has been truncated.
  • -
-

<a href="#siflags" name="siflags"></a> siflags: u16

-

Flags provided to sock_send. As there are currently no flags
defined, it must be set to zero.
Size: 2
Alignment: 2

-

<a href="#sdflags" name="sdflags"></a> sdflags: Flags(u8)

-

Which channels on a socket to shut down.
Size: 1
Alignment: 1

-

Flags

-
    -
  • <a href="#sdflags.rd" name="sdflags.rd"></a> rd
    Disables further receive operations.

    -
  • -
  • <a href="#sdflags.wr" name="sdflags.wr"></a> wr
    Disables further send operations.

    -
  • -
-

<a href="#preopentype" name="preopentype"></a> preopentype: Enum(u8)

-

Identifiers for preopened capabilities.
Size: 1
Alignment: 1

-

Variants

-
    -
  • <a href="#preopentype.dir" name="preopentype.dir"></a> dir
    A pre-opened directory.
  • -
-

<a href="#prestat_dir" name="prestat_dir"></a> prestat_dir: Struct

-

The contents of a $prestat when type is preopentype::dir.
Size: 4
Alignment: 4

-

Struct members

-
    -
  • <a href="#prestat_dir.pr_name_len" name="prestat_dir.pr_name_len"></a> pr_name_len: size
    The length of the directory name for use with fd_prestat_dir_name.
    Offset: 0

    <a href="#prestat" name="prestat"></a> prestat: Union

    -Information about a pre-opened capability.
    Size: 8
    Alignment: 4

    Union Layout

    -
  • -
  • tag_size: 1
  • -
  • tag_align: 1
  • -
  • contents_offset: 4
  • -
  • contents_size: 4
  • -
  • contents_align: 4

    Union variants

    -
  • -
  • <a href="#prestat.dir" name="prestat.dir"></a> dir: prestat_dir
  • -
-

Modules

-

<a href="#wasi_snapshot_preview1" name="wasi_snapshot_preview1"></a> wasi_snapshot_preview1

-

Imports

-

Memory

-

Functions

-
-

<a href="#args_get" name="args_get"></a> args_get(argv: Pointer<Pointer<u8>>, argv_buf: Pointer<u8>) -> errno

-

Read command-line argument data.
The size of the array should match that returned by args_sizes_get

-
Params
-
    -
  • <a href="#args_get.argv" name="args_get.argv"></a> argv: Pointer<Pointer<u8>>

    -
  • -
  • <a href="#args_get.argv_buf" name="args_get.argv_buf"></a> argv_buf: Pointer<u8>

    -
  • -
-
Results
-
    -
  • <a href="#args_get.error" name="args_get.error"></a> error: errno
  • -
-
-

<a href="#args_sizes_get" name="args_sizes_get"></a> args_sizes_get() -> (errno, size, size)

-

Return command-line argument data sizes.

-
Params
-
Results
-
    -
  • <a href="#args_sizes_get.error" name="args_sizes_get.error"></a> error: errno

    -
  • -
  • <a href="#args_sizes_get.argc" name="args_sizes_get.argc"></a> argc: size
    The number of arguments.

    -
  • -
  • <a href="#args_sizes_get.argv_buf_size" name="args_sizes_get.argv_buf_size"></a> argv_buf_size: size
    The size of the argument string data.

    -
  • -
-
-

<a href="#environ_get" name="environ_get"></a> environ_get(environ: Pointer<Pointer<u8>>, environ_buf: Pointer<u8>) -> errno

-

Read environment variable data.
The sizes of the buffers should match that returned by environ_sizes_get.

-
Params
-
    -
  • <a href="#environ_get.environ" name="environ_get.environ"></a> environ: Pointer<Pointer<u8>>

    -
  • -
  • <a href="#environ_get.environ_buf" name="environ_get.environ_buf"></a> environ_buf: Pointer<u8>

    -
  • -
-
Results
-
    -
  • <a href="#environ_get.error" name="environ_get.error"></a> error: errno
  • -
-
-

<a href="#environ_sizes_get" name="environ_sizes_get"></a> environ_sizes_get() -> (errno, size, size)

-

Return environment variable data sizes.

-
Params
-
Results
-
    -
  • <a href="#environ_sizes_get.error" name="environ_sizes_get.error"></a> error: errno

    -
  • -
  • <a href="#environ_sizes_get.environc" name="environ_sizes_get.environc"></a> environc: size
    The number of environment variable arguments.

    -
  • -
  • <a href="#environ_sizes_get.environ_buf_size" name="environ_sizes_get.environ_buf_size"></a> environ_buf_size: size
    The size of the environment variable data.

    -
  • -
-
-

<a href="#clock_res_get" name="clock_res_get"></a> clock_res_get(id: clockid) -> (errno, timestamp)

-

Return the resolution of a clock.
Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks,
return errno::inval.
Note: This is similar to clock_getres in POSIX.

-
Params
-
    -
  • <a href="#clock_res_get.id" name="clock_res_get.id"></a> id: clockid
    The clock for which to return the resolution.
  • -
-
Results
-
    -
  • <a href="#clock_res_get.error" name="clock_res_get.error"></a> error: errno

    -
  • -
  • <a href="#clock_res_get.resolution" name="clock_res_get.resolution"></a> resolution: timestamp
    The resolution of the clock.

    -
  • -
-
-

<a href="#clock_time_get" name="clock_time_get"></a> clock_time_get(id: clockid, precision: timestamp) -> (errno, timestamp)

-

Return the time value of a clock.
Note: This is similar to clock_gettime in POSIX.

-
Params
-
    -
  • <a href="#clock_time_get.id" name="clock_time_get.id"></a> id: clockid
    The clock for which to return the time.

    -
  • -
  • <a href="#clock_time_get.precision" name="clock_time_get.precision"></a> precision: timestamp
    The maximum lag (exclusive) that the returned time value may have, compared to its actual value.

    -
  • -
-
Results
-
    -
  • <a href="#clock_time_get.error" name="clock_time_get.error"></a> error: errno

    -
  • -
  • <a href="#clock_time_get.time" name="clock_time_get.time"></a> time: timestamp
    The time value of the clock.

    -
  • -
-
-

<a href="#fd_advise" name="fd_advise"></a> fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> errno

-

Provide file advisory information on a file descriptor.
Note: This is similar to posix_fadvise in POSIX.

-
Params
-
    -
  • <a href="#fd_advise.fd" name="fd_advise.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_advise.offset" name="fd_advise.offset"></a> offset: filesize
    The offset within the file to which the advisory applies.

    -
  • -
  • <a href="#fd_advise.len" name="fd_advise.len"></a> len: filesize
    The length of the region to which the advisory applies.

    -
  • -
  • <a href="#fd_advise.advice" name="fd_advise.advice"></a> advice: advice
    The advice.

    -
  • -
-
Results
-
    -
  • <a href="#fd_advise.error" name="fd_advise.error"></a> error: errno
  • -
-
-

<a href="#fd_allocate" name="fd_allocate"></a> fd_allocate(fd: fd, offset: filesize, len: filesize) -> errno

-

Force the allocation of space in a file.
Note: This is similar to posix_fallocate in POSIX.

-
Params
-
    -
  • <a href="#fd_allocate.fd" name="fd_allocate.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_allocate.offset" name="fd_allocate.offset"></a> offset: filesize
    The offset at which to start the allocation.

    -
  • -
  • <a href="#fd_allocate.len" name="fd_allocate.len"></a> len: filesize
    The length of the area that is allocated.

    -
  • -
-
Results
-
    -
  • <a href="#fd_allocate.error" name="fd_allocate.error"></a> error: errno
  • -
-
-

<a href="#fd_close" name="fd_close"></a> fd_close(fd: fd) -> errno

-

Close a file descriptor.
Note: This is similar to close in POSIX.

-
Params
-
    -
  • <a href="#fd_close.fd" name="fd_close.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_close.error" name="fd_close.error"></a> error: errno
  • -
-
-

<a href="#fd_datasync" name="fd_datasync"></a> fd_datasync(fd: fd) -> errno

-

Synchronize the data of a file to disk.
Note: This is similar to fdatasync in POSIX.

-
Params
-
    -
  • <a href="#fd_datasync.fd" name="fd_datasync.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_datasync.error" name="fd_datasync.error"></a> error: errno
  • -
-
-

<a href="#fd_fdstat_get" name="fd_fdstat_get"></a> fd_fdstat_get(fd: fd) -> (errno, fdstat)

-

Get the attributes of a file descriptor.
Note: This returns similar flags to fsync(fd, F_GETFL) in POSIX, as well as additional fields.

-
Params
-
    -
  • <a href="#fd_fdstat_get.fd" name="fd_fdstat_get.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_fdstat_get.error" name="fd_fdstat_get.error"></a> error: errno

    -
  • -
  • <a href="#fd_fdstat_get.stat" name="fd_fdstat_get.stat"></a> stat: fdstat
    The buffer where the file descriptor's attributes are stored.

    -
  • -
-
-

<a href="#fd_fdstat_set_flags" name="fd_fdstat_set_flags"></a> fd_fdstat_set_flags(fd: fd, flags: fdflags) -> errno

-

Adjust the flags associated with a file descriptor.
Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

-
Params
-
    -
  • <a href="#fd_fdstat_set_flags.fd" name="fd_fdstat_set_flags.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_fdstat_set_flags.flags" name="fd_fdstat_set_flags.flags"></a> flags: fdflags
    The desired values of the file descriptor flags.

    -
  • -
-
Results
-
    -
  • <a href="#fd_fdstat_set_flags.error" name="fd_fdstat_set_flags.error"></a> error: errno
  • -
-
-

<a href="#fd_fdstat_set_rights" name="fd_fdstat_set_rights"></a> fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> errno

-

Adjust the rights associated with a file descriptor.
This can only be used to remove rights, and returns errno::notcapable if called in a way that would attempt to add rights

-
Params
-
    -
  • <a href="#fd_fdstat_set_rights.fd" name="fd_fdstat_set_rights.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_fdstat_set_rights.fs_rights_base" name="fd_fdstat_set_rights.fs_rights_base"></a> fs_rights_base: rights
    The desired rights of the file descriptor.

    -
  • -
  • <a href="#fd_fdstat_set_rights.fs_rights_inheriting" name="fd_fdstat_set_rights.fs_rights_inheriting"></a> fs_rights_inheriting: rights

    -
  • -
-
Results
-
    -
  • <a href="#fd_fdstat_set_rights.error" name="fd_fdstat_set_rights.error"></a> error: errno
  • -
-
-

<a href="#fd_filestat_get" name="fd_filestat_get"></a> fd_filestat_get(fd: fd) -> (errno, filestat)

-

Return the attributes of an open file.

-
Params
-
    -
  • <a href="#fd_filestat_get.fd" name="fd_filestat_get.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_filestat_get.error" name="fd_filestat_get.error"></a> error: errno

    -
  • -
  • <a href="#fd_filestat_get.buf" name="fd_filestat_get.buf"></a> buf: filestat
    The buffer where the file's attributes are stored.

    -
  • -
-
-

<a href="#fd_filestat_set_size" name="fd_filestat_set_size"></a> fd_filestat_set_size(fd: fd, size: filesize) -> errno

-

Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.
Note: This is similar to ftruncate in POSIX.

-
Params
-
    -
  • <a href="#fd_filestat_set_size.fd" name="fd_filestat_set_size.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_filestat_set_size.size" name="fd_filestat_set_size.size"></a> size: filesize
    The desired file size.

    -
  • -
-
Results
-
    -
  • <a href="#fd_filestat_set_size.error" name="fd_filestat_set_size.error"></a> error: errno
  • -
-
-

<a href="#fd_filestat_set_times" name="fd_filestat_set_times"></a> fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno

-

Adjust the timestamps of an open file or directory.
Note: This is similar to futimens in POSIX.

-
Params
-
    -
  • <a href="#fd_filestat_set_times.fd" name="fd_filestat_set_times.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_filestat_set_times.atim" name="fd_filestat_set_times.atim"></a> atim: timestamp
    The desired values of the data access timestamp.

    -
  • -
  • <a href="#fd_filestat_set_times.mtim" name="fd_filestat_set_times.mtim"></a> mtim: timestamp
    The desired values of the data modification timestamp.

    -
  • -
  • <a href="#fd_filestat_set_times.fst_flags" name="fd_filestat_set_times.fst_flags"></a> fst_flags: fstflags
    A bitmask indicating which timestamps to adjust.

    -
  • -
-
Results
-
    -
  • <a href="#fd_filestat_set_times.error" name="fd_filestat_set_times.error"></a> error: errno
  • -
-
-

<a href="#fd_pread" name="fd_pread"></a> fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> (errno, size)

-

Read from a file descriptor, without using and updating the file descriptor's offset.
Note: This is similar to preadv in POSIX.

-
Params
-
    -
  • <a href="#fd_pread.fd" name="fd_pread.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_pread.iovs" name="fd_pread.iovs"></a> iovs: iovec_array
    List of scatter/gather vectors in which to store data.

    -
  • -
  • <a href="#fd_pread.offset" name="fd_pread.offset"></a> offset: filesize
    The offset within the file at which to read.

    -
  • -
-
Results
-
    -
  • <a href="#fd_pread.error" name="fd_pread.error"></a> error: errno

    -
  • -
  • <a href="#fd_pread.nread" name="fd_pread.nread"></a> nread: size
    The number of bytes read.

    -
  • -
-
-

<a href="#fd_prestat_get" name="fd_prestat_get"></a> fd_prestat_get(fd: fd) -> (errno, prestat)

-

Return a description of the given preopened file descriptor.

-
Params
-
    -
  • <a href="#fd_prestat_get.fd" name="fd_prestat_get.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_prestat_get.error" name="fd_prestat_get.error"></a> error: errno

    -
  • -
  • <a href="#fd_prestat_get.buf" name="fd_prestat_get.buf"></a> buf: prestat
    The buffer where the description is stored.

    -
  • -
-
-

<a href="#fd_prestat_dir_name" name="fd_prestat_dir_name"></a> fd_prestat_dir_name(fd: fd, path: Pointer<u8>, path_len: size) -> errno

-

Return a description of the given preopened file descriptor.

-
Params
-
    -
  • <a href="#fd_prestat_dir_name.fd" name="fd_prestat_dir_name.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_prestat_dir_name.path" name="fd_prestat_dir_name.path"></a> path: Pointer<u8>
    A buffer into which to write the preopened directory name.

    -
  • -
  • <a href="#fd_prestat_dir_name.path_len" name="fd_prestat_dir_name.path_len"></a> path_len: size

    -
  • -
-
Results
-
    -
  • <a href="#fd_prestat_dir_name.error" name="fd_prestat_dir_name.error"></a> error: errno
  • -
-
-

<a href="#fd_pwrite" name="fd_pwrite"></a> fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> (errno, size)

-

Write to a file descriptor, without using and updating the file descriptor's offset.
Note: This is similar to pwritev in POSIX.

-
Params
-
    -
  • <a href="#fd_pwrite.fd" name="fd_pwrite.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_pwrite.iovs" name="fd_pwrite.iovs"></a> iovs: ciovec_array
    List of scatter/gather vectors from which to retrieve data.

    -
  • -
  • <a href="#fd_pwrite.offset" name="fd_pwrite.offset"></a> offset: filesize
    The offset within the file at which to write.

    -
  • -
-
Results
-
    -
  • <a href="#fd_pwrite.error" name="fd_pwrite.error"></a> error: errno

    -
  • -
  • <a href="#fd_pwrite.nwritten" name="fd_pwrite.nwritten"></a> nwritten: size
    The number of bytes written.

    -
  • -
-
-

<a href="#fd_read" name="fd_read"></a> fd_read(fd: fd, iovs: iovec_array) -> (errno, size)

-

Read from a file descriptor.
Note: This is similar to readv in POSIX.

-
Params
-
    -
  • <a href="#fd_read.fd" name="fd_read.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_read.iovs" name="fd_read.iovs"></a> iovs: iovec_array
    List of scatter/gather vectors to which to store data.

    -
  • -
-
Results
-
    -
  • <a href="#fd_read.error" name="fd_read.error"></a> error: errno

    -
  • -
  • <a href="#fd_read.nread" name="fd_read.nread"></a> nread: size
    The number of bytes read.

    -
  • -
-
- -

Read directory entries from a directory.
When successful, the contents of the output buffer consist of a sequence of
directory entries. Each directory entry consists of a dirent_t object,
followed by dirent_t::d_namlen bytes holding the name of the directory
entry.
This function fills the output buffer as much as possible, potentially
truncating the last directory entry. This allows the caller to grow its
read buffer size in case it's too small to fit a single large directory
entry, or skip the oversized directory entry.

-
Params
-
    -
  • <a href="#fd_readdir.fd" name="fd_readdir.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_readdir.buf" name="fd_readdir.buf"></a> buf: Pointer<u8>
    The buffer where directory entries are stored

    -
  • -
  • <a href="#fd_readdir.buf_len" name="fd_readdir.buf_len"></a> buf_len: size

    -
  • -
  • <a href="#fd_readdir.cookie" name="fd_readdir.cookie"></a> cookie: dircookie
    The location within the directory to start reading

    -
  • -
-
Results
-
    -
  • <a href="#fd_readdir.error" name="fd_readdir.error"></a> error: errno

    -
  • -
  • <a href="#fd_readdir.bufused" name="fd_readdir.bufused"></a> bufused: size
    The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached.

    -
  • -
-
-

<a href="#fd_renumber" name="fd_renumber"></a> fd_renumber(fd: fd, to: fd) -> errno

-

Atomically replace a file descriptor by renumbering another file descriptor.
Due to the strong focus on thread safety, this environment does not provide
a mechanism to duplicate or renumber a file descriptor to an arbitrary
number, like dup2(). This would be prone to race conditions, as an actual
file descriptor with the same number could be allocated by a different
thread at the same time.
This function provides a way to atomically renumber file descriptors, which
would disappear if dup2() were to be removed entirely.

-
Params
-
    -
  • <a href="#fd_renumber.fd" name="fd_renumber.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_renumber.to" name="fd_renumber.to"></a> to: fd
    The file descriptor to overwrite.

    -
  • -
-
Results
-
    -
  • <a href="#fd_renumber.error" name="fd_renumber.error"></a> error: errno
  • -
-
-

<a href="#fd_seek" name="fd_seek"></a> fd_seek(fd: fd, offset: filedelta, whence: whence) -> (errno, filesize)

-

Move the offset of a file descriptor.
Note: This is similar to lseek in POSIX.

-
Params
-
    -
  • <a href="#fd_seek.fd" name="fd_seek.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_seek.offset" name="fd_seek.offset"></a> offset: filedelta
    The number of bytes to move.

    -
  • -
  • <a href="#fd_seek.whence" name="fd_seek.whence"></a> whence: whence
    The base from which the offset is relative.

    -
  • -
-
Results
-
    -
  • <a href="#fd_seek.error" name="fd_seek.error"></a> error: errno

    -
  • -
  • <a href="#fd_seek.newoffset" name="fd_seek.newoffset"></a> newoffset: filesize
    The new offset of the file descriptor, relative to the start of the file.

    -
  • -
-
-

<a href="#fd_sync" name="fd_sync"></a> fd_sync(fd: fd) -> errno

-

Synchronize the data and metadata of a file to disk.
Note: This is similar to fsync in POSIX.

-
Params
-
    -
  • <a href="#fd_sync.fd" name="fd_sync.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_sync.error" name="fd_sync.error"></a> error: errno
  • -
-
-

<a href="#fd_tell" name="fd_tell"></a> fd_tell(fd: fd) -> (errno, filesize)

-

Return the current offset of a file descriptor.
Note: This is similar to lseek(fd, 0, SEEK_CUR) in POSIX.

-
Params
-
    -
  • <a href="#fd_tell.fd" name="fd_tell.fd"></a> fd: fd
  • -
-
Results
-
    -
  • <a href="#fd_tell.error" name="fd_tell.error"></a> error: errno

    -
  • -
  • <a href="#fd_tell.offset" name="fd_tell.offset"></a> offset: filesize
    The current offset of the file descriptor, relative to the start of the file.

    -
  • -
-
-

<a href="#fd_write" name="fd_write"></a> fd_write(fd: fd, iovs: ciovec_array) -> (errno, size)

-

Write to a file descriptor.
Note: This is similar to writev in POSIX.

-
Params
-
    -
  • <a href="#fd_write.fd" name="fd_write.fd"></a> fd: fd

    -
  • -
  • <a href="#fd_write.iovs" name="fd_write.iovs"></a> iovs: ciovec_array
    List of scatter/gather vectors from which to retrieve data.

    -
  • -
-
Results
-
    -
  • <a href="#fd_write.error" name="fd_write.error"></a> error: errno

    -
  • -
  • <a href="#fd_write.nwritten" name="fd_write.nwritten"></a> nwritten: size
    The number of bytes written.

    -
  • -
-
-

<a href="#path_create_directory" name="path_create_directory"></a> path_create_directory(fd: fd, path: string) -> errno

-

Create a directory.
Note: This is similar to mkdirat in POSIX.

-
Params
-
    -
  • <a href="#path_create_directory.fd" name="path_create_directory.fd"></a> fd: fd

    -
  • -
  • <a href="#path_create_directory.path" name="path_create_directory.path"></a> path: string
    The path at which to create the directory.

    -
  • -
-
Results
-
    -
  • <a href="#path_create_directory.error" name="path_create_directory.error"></a> error: errno
  • -
-
-

<a href="#path_filestat_get" name="path_filestat_get"></a> path_filestat_get(fd: fd, flags: lookupflags, path: string) -> (errno, filestat)

-

Return the attributes of a file or directory.
Note: This is similar to stat in POSIX.

-
Params
-
    -
  • <a href="#path_filestat_get.fd" name="path_filestat_get.fd"></a> fd: fd

    -
  • -
  • <a href="#path_filestat_get.flags" name="path_filestat_get.flags"></a> flags: lookupflags
    Flags determining the method of how the path is resolved.

    -
  • -
  • <a href="#path_filestat_get.path" name="path_filestat_get.path"></a> path: string
    The path of the file or directory to inspect.

    -
  • -
-
Results
-
    -
  • <a href="#path_filestat_get.error" name="path_filestat_get.error"></a> error: errno

    -
  • -
  • <a href="#path_filestat_get.buf" name="path_filestat_get.buf"></a> buf: filestat
    The buffer where the file's attributes are stored.

    -
  • -
-
-

<a href="#path_filestat_set_times" name="path_filestat_set_times"></a> path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> errno

-

Adjust the timestamps of a file or directory.
Note: This is similar to utimensat in POSIX.

-
Params
-
    -
  • <a href="#path_filestat_set_times.fd" name="path_filestat_set_times.fd"></a> fd: fd

    -
  • -
  • <a href="#path_filestat_set_times.flags" name="path_filestat_set_times.flags"></a> flags: lookupflags
    Flags determining the method of how the path is resolved.

    -
  • -
  • <a href="#path_filestat_set_times.path" name="path_filestat_set_times.path"></a> path: string
    The path of the file or directory to operate on.

    -
  • -
  • <a href="#path_filestat_set_times.atim" name="path_filestat_set_times.atim"></a> atim: timestamp
    The desired values of the data access timestamp.

    -
  • -
  • <a href="#path_filestat_set_times.mtim" name="path_filestat_set_times.mtim"></a> mtim: timestamp
    The desired values of the data modification timestamp.

    -
  • -
  • <a href="#path_filestat_set_times.fst_flags" name="path_filestat_set_times.fst_flags"></a> fst_flags: fstflags
    A bitmask indicating which timestamps to adjust.

    -
  • -
-
Results
-
    -
  • <a href="#path_filestat_set_times.error" name="path_filestat_set_times.error"></a> error: errno
  • -
-
- -

Create a hard link.
Note: This is similar to linkat in POSIX.

-
Params
-
    -
  • <a href="#path_link.old_fd" name="path_link.old_fd"></a> old_fd: fd

    -
  • -
  • <a href="#path_link.old_flags" name="path_link.old_flags"></a> old_flags: lookupflags
    Flags determining the method of how the path is resolved.

    -
  • -
  • <a href="#path_link.old_path" name="path_link.old_path"></a> old_path: string
    The source path from which to link.

    -
  • -
  • <a href="#path_link.new_fd" name="path_link.new_fd"></a> new_fd: fd
    The working directory at which the resolution of the new path starts.

    -
  • -
  • <a href="#path_link.new_path" name="path_link.new_path"></a> new_path: string
    The destination path at which to create the hard link.

    -
  • -
-
Results
-
    -
  • <a href="#path_link.error" name="path_link.error"></a> error: errno
  • -
-
-

<a href="#path_open" name="path_open"></a> path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inherting: rights, fdflags: fdflags) -> (errno, fd)

-

Open a file or directory.
The returned file descriptor is not guaranteed to be the lowest-numbered
file descriptor not currently open; it is randomized to prevent
applications from depending on making assumptions about indexes, since this
is error-prone in multi-threaded contexts. The returned file descriptor is
guaranteed to be less than 2**31.
Note: This is similar to openat in POSIX.

-
Params
-
    -
  • <a href="#path_open.fd" name="path_open.fd"></a> fd: fd

    -
  • -
  • <a href="#path_open.dirflags" name="path_open.dirflags"></a> dirflags: lookupflags
    Flags determining the method of how the path is resolved.

    -
  • -
  • <a href="#path_open.path" name="path_open.path"></a> path: string
    The relative path of the file or directory to open, relative to the
    path_open::fd directory.

    -
  • -
  • <a href="#path_open.oflags" name="path_open.oflags"></a> oflags: oflags
    The method by which to open the file.

    -
  • -
  • <a href="#path_open.fs_rights_base" name="path_open.fs_rights_base"></a> fs_rights_base: rights
    The initial rights of the newly created file descriptor. The
    implementation is allowed to return a file descriptor with fewer rights
    than specified, if and only if those rights do not apply to the type of
    file being opened.
    The base rights are rights that will apply to operations using the file
    descriptor itself, while the inheriting rights are rights that apply to
    file descriptors derived from it.

    -
  • -
  • <a href="#path_open.fs_rights_inherting" name="path_open.fs_rights_inherting"></a> fs_rights_inherting: rights

    -
  • -
  • <a href="#path_open.fdflags" name="path_open.fdflags"></a> fdflags: fdflags

    -
  • -
-
Results
-
    -
  • <a href="#path_open.error" name="path_open.error"></a> error: errno

    -
  • -
  • <a href="#path_open.opened_fd" name="path_open.opened_fd"></a> opened_fd: fd
    The file descriptor of the file that has been opened.

    -
  • -
-
- -

Read the contents of a symbolic link.
Note: This is similar to readlinkat in POSIX.

-
Params
-
    -
  • <a href="#path_readlink.fd" name="path_readlink.fd"></a> fd: fd

    -
  • -
  • <a href="#path_readlink.path" name="path_readlink.path"></a> path: string
    The path of the symbolic link from which to read.

    -
  • -
  • <a href="#path_readlink.buf" name="path_readlink.buf"></a> buf: Pointer<u8>
    The buffer to which to write the contents of the symbolic link.

    -
  • -
  • <a href="#path_readlink.buf_len" name="path_readlink.buf_len"></a> buf_len: size

    -
  • -
-
Results
-
    -
  • <a href="#path_readlink.error" name="path_readlink.error"></a> error: errno

    -
  • -
  • <a href="#path_readlink.bufused" name="path_readlink.bufused"></a> bufused: size
    The number of bytes placed in the buffer.

    -
  • -
-
-

<a href="#path_remove_directory" name="path_remove_directory"></a> path_remove_directory(fd: fd, path: string) -> errno

-

Remove a directory.
Return errno::notempty if the directory is not empty.
Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

-
Params
-
    -
  • <a href="#path_remove_directory.fd" name="path_remove_directory.fd"></a> fd: fd

    -
  • -
  • <a href="#path_remove_directory.path" name="path_remove_directory.path"></a> path: string
    The path to a directory to remove.

    -
  • -
-
Results
-
    -
  • <a href="#path_remove_directory.error" name="path_remove_directory.error"></a> error: errno
  • -
-
-

<a href="#path_rename" name="path_rename"></a> path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> errno

-

Rename a file or directory.
Note: This is similar to renameat in POSIX.

-
Params
-
    -
  • <a href="#path_rename.fd" name="path_rename.fd"></a> fd: fd

    -
  • -
  • <a href="#path_rename.old_path" name="path_rename.old_path"></a> old_path: string
    The source path of the file or directory to rename.

    -
  • -
  • <a href="#path_rename.new_fd" name="path_rename.new_fd"></a> new_fd: fd
    The working directory at which the resolution of the new path starts.

    -
  • -
  • <a href="#path_rename.new_path" name="path_rename.new_path"></a> new_path: string
    The destination path to which to rename the file or directory.

    -
  • -
-
Results
-
    -
  • <a href="#path_rename.error" name="path_rename.error"></a> error: errno
  • -
-
- -

Create a symbolic link.
Note: This is similar to symlinkat in POSIX.

-
Params
-
    -
  • <a href="#path_symlink.old_path" name="path_symlink.old_path"></a> old_path: string
    The contents of the symbolic link.

    -
  • -
  • <a href="#path_symlink.fd" name="path_symlink.fd"></a> fd: fd

    -
  • -
  • <a href="#path_symlink.new_path" name="path_symlink.new_path"></a> new_path: string
    The destination path at which to create the symbolic link.

    -
  • -
-
Results
-
    -
  • <a href="#path_symlink.error" name="path_symlink.error"></a> error: errno
  • -
-
- -

Unlink a file.
Return errno::isdir if the path refers to a directory.
Note: This is similar to unlinkat(fd, path, 0) in POSIX.

-
Params
-
    -
  • <a href="#path_unlink_file.fd" name="path_unlink_file.fd"></a> fd: fd

    -
  • -
  • <a href="#path_unlink_file.path" name="path_unlink_file.path"></a> path: string
    The path to a file to unlink.

    -
  • -
-
Results
-
    -
  • <a href="#path_unlink_file.error" name="path_unlink_file.error"></a> error: errno
  • -
-
-

<a href="#poll_oneoff" name="poll_oneoff"></a> poll_oneoff(in: ConstPointer<subscription>, out: Pointer<event>, nsubscriptions: size) -> (errno, size)

-

Concurrently poll for the occurrence of a set of events.

-
Params
-
    -
  • <a href="#poll_oneoff.in" name="poll_oneoff.in"></a> in: ConstPointer<subscription>
    The events to which to subscribe.

    -
  • -
  • <a href="#poll_oneoff.out" name="poll_oneoff.out"></a> out: Pointer<event>
    The events that have occurred.

    -
  • -
  • <a href="#poll_oneoff.nsubscriptions" name="poll_oneoff.nsubscriptions"></a> nsubscriptions: size
    Both the number of subscriptions and events.

    -
  • -
-
Results
-
    -
  • <a href="#poll_oneoff.error" name="poll_oneoff.error"></a> error: errno

    -
  • -
  • <a href="#poll_oneoff.nevents" name="poll_oneoff.nevents"></a> nevents: size
    The number of events stored.

    -
  • -
-
-

<a href="#proc_exit" name="proc_exit"></a> proc_exit(rval: exitcode)

-

Terminate the process normally. An exit code of 0 indicates successful
termination of the program. The meanings of other values is dependent on
the environment.

-
Params
-
    -
  • <a href="#proc_exit.rval" name="proc_exit.rval"></a> rval: exitcode
    The exit code returned by the process.
  • -
-
Results
-
-

<a href="#proc_raise" name="proc_raise"></a> proc_raise(sig: signal) -> errno

-

Send a signal to the process of the calling thread.
Note: This is similar to raise in POSIX.

-
Params
-
    -
  • <a href="#proc_raise.sig" name="proc_raise.sig"></a> sig: signal
    The signal condition to trigger.
  • -
-
Results
-
    -
  • <a href="#proc_raise.error" name="proc_raise.error"></a> error: errno
  • -
-
-

<a href="#sched_yield" name="sched_yield"></a> sched_yield() -> errno

-

Temporarily yield execution of the calling thread.
Note: This is similar to sched_yield in POSIX.

-
Params
-
Results
-
    -
  • <a href="#sched_yield.error" name="sched_yield.error"></a> error: errno
  • -
-
-

<a href="#random_get" name="random_get"></a> random_get(buf: Pointer<u8>, buf_len: size) -> errno

-

Write high-quality random data into a buffer.
This function blocks when the implementation is unable to immediately
provide sufficient high-quality random data.
This function may execute slowly, so when large mounts of random data are
required, it's advisable to use this function to seed a pseudo-random
number generator, rather than to provide the random data directly.

-
Params
-
    -
  • <a href="#random_get.buf" name="random_get.buf"></a> buf: Pointer<u8>
    The buffer to fill with random data.

    -
  • -
  • <a href="#random_get.buf_len" name="random_get.buf_len"></a> buf_len: size

    -
  • -
-
Results
-
    -
  • <a href="#random_get.error" name="random_get.error"></a> error: errno
  • -
-
-

<a href="#sock_recv" name="sock_recv"></a> sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> (errno, size, roflags)

-

Receive a message from a socket.
Note: This is similar to recv in POSIX, though it also supports reading
the data into multiple buffers in the manner of readv.

-
Params
-
    -
  • <a href="#sock_recv.fd" name="sock_recv.fd"></a> fd: fd

    -
  • -
  • <a href="#sock_recv.ri_data" name="sock_recv.ri_data"></a> ri_data: iovec_array
    List of scatter/gather vectors to which to store data.

    -
  • -
  • <a href="#sock_recv.ri_flags" name="sock_recv.ri_flags"></a> ri_flags: riflags
    Message flags.

    -
  • -
-
Results
-
    -
  • <a href="#sock_recv.error" name="sock_recv.error"></a> error: errno

    -
  • -
  • <a href="#sock_recv.ro_datalen" name="sock_recv.ro_datalen"></a> ro_datalen: size
    Number of bytes stored in ri_data.

    -
  • -
  • <a href="#sock_recv.ro_flags" name="sock_recv.ro_flags"></a> ro_flags: roflags
    Message flags.

    -
  • -
-
-

<a href="#sock_send" name="sock_send"></a> sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> (errno, size)

-

Send a message on a socket.
Note: This is similar to send in POSIX, though it also supports writing
the data from multiple buffers in the manner of writev.

-
Params
-
    -
  • <a href="#sock_send.fd" name="sock_send.fd"></a> fd: fd

    -
  • -
  • <a href="#sock_send.si_data" name="sock_send.si_data"></a> si_data: ciovec_array
    List of scatter/gather vectors to which to retrieve data

    -
  • -
  • <a href="#sock_send.si_flags" name="sock_send.si_flags"></a> si_flags: siflags
    Message flags.

    -
  • -
-
Results
-
    -
  • <a href="#sock_send.error" name="sock_send.error"></a> error: errno

    -
  • -
  • <a href="#sock_send.so_datalen" name="sock_send.so_datalen"></a> so_datalen: size
    Number of bytes transmitted.

    -
  • -
-
-

<a href="#sock_shutdown" name="sock_shutdown"></a> sock_shutdown(fd: fd, how: sdflags) -> errno

-

Shut down socket send and receive channels.
Note: This is similar to shutdown in POSIX.

-
Params
-
    -
  • <a href="#sock_shutdown.fd" name="sock_shutdown.fd"></a> fd: fd

    -
  • -
  • <a href="#sock_shutdown.how" name="sock_shutdown.how"></a> how: sdflags
    Which channels on the socket to shut down.

    -
  • -
-
Results
-
    -
  • <a href="#sock_shutdown.error" name="sock_shutdown.error"></a> error: errno
  • -
diff --git a/proposals/random/phases/snapshot/docs.md b/proposals/random/phases/snapshot/docs.md deleted file mode 100644 index 44c3c35f2..000000000 --- a/proposals/random/phases/snapshot/docs.md +++ /dev/null @@ -1,2509 +0,0 @@ -# Types -## `size`: `u32` - -Size: 4 - -Alignment: 4 - -## `filesize`: `u64` -Non-negative file size or length of a region within a file. - -Size: 8 - -Alignment: 8 - -## `timestamp`: `u64` -Timestamp in nanoseconds. - -Size: 8 - -Alignment: 8 - -## `clockid`: `Variant` -Identifiers for clocks. - -Size: 4 - -Alignment: 4 - -### Variant cases -- `realtime` -The clock measuring real time. Time value zero corresponds with -1970-01-01T00:00:00Z. - -- `monotonic` -The store-wide monotonic clock, which is defined as a clock measuring -real time, whose value cannot be adjusted and which cannot have negative -clock jumps. The epoch of this clock is undefined. The absolute time -value of this clock therefore has no meaning. - -- `process_cputime_id` -The CPU-time clock associated with the current process. - -- `thread_cputime_id` -The CPU-time clock associated with the current thread. - -## `errno`: `Variant` -Error codes returned by functions. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX. - -Size: 2 - -Alignment: 2 - -### Variant cases -- `success` -No error occurred. System call completed successfully. - -- `2big` -Argument list too long. - -- `acces` -Permission denied. - -- `addrinuse` -Address in use. - -- `addrnotavail` -Address not available. - -- `afnosupport` -Address family not supported. - -- `again` -Resource unavailable, or operation would block. - -- `already` -Connection already in progress. - -- `badf` -Bad file descriptor. - -- `badmsg` -Bad message. - -- `busy` -Device or resource busy. - -- `canceled` -Operation canceled. - -- `child` -No child processes. - -- `connaborted` -Connection aborted. - -- `connrefused` -Connection refused. - -- `connreset` -Connection reset. - -- `deadlk` -Resource deadlock would occur. - -- `destaddrreq` -Destination address required. - -- `dom` -Mathematics argument out of domain of function. - -- `dquot` -Reserved. - -- `exist` -File exists. - -- `fault` -Bad address. - -- `fbig` -File too large. - -- `hostunreach` -Host is unreachable. - -- `idrm` -Identifier removed. - -- `ilseq` -Illegal byte sequence. - -- `inprogress` -Operation in progress. - -- `intr` -Interrupted function. - -- `inval` -Invalid argument. - -- `io` -I/O error. - -- `isconn` -Socket is connected. - -- `isdir` -Is a directory. - -- `loop` -Too many levels of symbolic links. - -- `mfile` -File descriptor value too large. - -- `mlink` -Too many links. - -- `msgsize` -Message too large. - -- `multihop` -Reserved. - -- `nametoolong` -Filename too long. - -- `netdown` -Network is down. - -- `netreset` -Connection aborted by network. - -- `netunreach` -Network unreachable. - -- `nfile` -Too many files open in system. - -- `nobufs` -No buffer space available. - -- `nodev` -No such device. - -- `noent` -No such file or directory. - -- `noexec` -Executable file format error. - -- `nolck` -No locks available. - -- `nolink` -Reserved. - -- `nomem` -Not enough space. - -- `nomsg` -No message of the desired type. - -- `noprotoopt` -Protocol not available. - -- `nospc` -No space left on device. - -- `nosys` -Function not supported. - -- `notconn` -The socket is not connected. - -- `notdir` -Not a directory or a symbolic link to a directory. - -- `notempty` -Directory not empty. - -- `notrecoverable` -State not recoverable. - -- `notsock` -Not a socket. - -- `notsup` -Not supported, or operation not supported on socket. - -- `notty` -Inappropriate I/O control operation. - -- `nxio` -No such device or address. - -- `overflow` -Value too large to be stored in data type. - -- `ownerdead` -Previous owner died. - -- `perm` -Operation not permitted. - -- `pipe` -Broken pipe. - -- `proto` -Protocol error. - -- `protonosupport` -Protocol not supported. - -- `prototype` -Protocol wrong type for socket. - -- `range` -Result too large. - -- `rofs` -Read-only file system. - -- `spipe` -Invalid seek. - -- `srch` -No such process. - -- `stale` -Reserved. - -- `timedout` -Connection timed out. - -- `txtbsy` -Text file busy. - -- `xdev` -Cross-device link. - -- `notcapable` -Extension: Capabilities insufficient. - -## `rights`: `Record` -File descriptor rights, determining which actions may be performed. - -Size: 8 - -Alignment: 8 - -### Record members -- `fd_datasync`: `bool` -The right to invoke [`fd_datasync`](#fd_datasync). -If [`path_open`](#path_open) is set, includes the right to invoke -[`path_open`](#path_open) with [`fdflags::dsync`](#fdflags.dsync). - -Bit: 0 - -- `fd_read`: `bool` -The right to invoke [`fd_read`](#fd_read) and [`sock_recv`](#sock_recv). -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pread`](#fd_pread). - -Bit: 1 - -- `fd_seek`: `bool` -The right to invoke [`fd_seek`](#fd_seek). This flag implies [`rights::fd_tell`](#rights.fd_tell). - -Bit: 2 - -- `fd_fdstat_set_flags`: `bool` -The right to invoke [`fd_fdstat_set_flags`](#fd_fdstat_set_flags). - -Bit: 3 - -- `fd_sync`: `bool` -The right to invoke [`fd_sync`](#fd_sync). -If [`path_open`](#path_open) is set, includes the right to invoke -[`path_open`](#path_open) with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - -Bit: 4 - -- `fd_tell`: `bool` -The right to invoke [`fd_seek`](#fd_seek) in such a way that the file offset -remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to -invoke [`fd_tell`](#fd_tell). - -Bit: 5 - -- `fd_write`: `bool` -The right to invoke [`fd_write`](#fd_write) and [`sock_send`](#sock_send). -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke [`fd_pwrite`](#fd_pwrite). - -Bit: 6 - -- `fd_advise`: `bool` -The right to invoke [`fd_advise`](#fd_advise). - -Bit: 7 - -- `fd_allocate`: `bool` -The right to invoke [`fd_allocate`](#fd_allocate). - -Bit: 8 - -- `path_create_directory`: `bool` -The right to invoke [`path_create_directory`](#path_create_directory). - -Bit: 9 - -- `path_create_file`: `bool` -If [`path_open`](#path_open) is set, the right to invoke [`path_open`](#path_open) with [`oflags::creat`](#oflags.creat). - -Bit: 10 - -- `path_link_source`: `bool` -The right to invoke [`path_link`](#path_link) with the file descriptor as the -source directory. - -Bit: 11 - -- `path_link_target`: `bool` -The right to invoke [`path_link`](#path_link) with the file descriptor as the -target directory. - -Bit: 12 - -- `path_open`: `bool` -The right to invoke [`path_open`](#path_open). - -Bit: 13 - -- `fd_readdir`: `bool` -The right to invoke [`fd_readdir`](#fd_readdir). - -Bit: 14 - -- `path_readlink`: `bool` -The right to invoke [`path_readlink`](#path_readlink). - -Bit: 15 - -- `path_rename_source`: `bool` -The right to invoke [`path_rename`](#path_rename) with the file descriptor as the source directory. - -Bit: 16 - -- `path_rename_target`: `bool` -The right to invoke [`path_rename`](#path_rename) with the file descriptor as the target directory. - -Bit: 17 - -- `path_filestat_get`: `bool` -The right to invoke [`path_filestat_get`](#path_filestat_get). - -Bit: 18 - -- `path_filestat_set_size`: `bool` -The right to change a file's size (there is no `path_filestat_set_size`). -If [`path_open`](#path_open) is set, includes the right to invoke [`path_open`](#path_open) with [`oflags::trunc`](#oflags.trunc). - -Bit: 19 - -- `path_filestat_set_times`: `bool` -The right to invoke [`path_filestat_set_times`](#path_filestat_set_times). - -Bit: 20 - -- `fd_filestat_get`: `bool` -The right to invoke [`fd_filestat_get`](#fd_filestat_get). - -Bit: 21 - -- `fd_filestat_set_size`: `bool` -The right to invoke [`fd_filestat_set_size`](#fd_filestat_set_size). - -Bit: 22 - -- `fd_filestat_set_times`: `bool` -The right to invoke [`fd_filestat_set_times`](#fd_filestat_set_times). - -Bit: 23 - -- `path_symlink`: `bool` -The right to invoke [`path_symlink`](#path_symlink). - -Bit: 24 - -- `path_remove_directory`: `bool` -The right to invoke [`path_remove_directory`](#path_remove_directory). - -Bit: 25 - -- `path_unlink_file`: `bool` -The right to invoke [`path_unlink_file`](#path_unlink_file). - -Bit: 26 - -- `poll_fd_readwrite`: `bool` -If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). -If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke [`poll_oneoff`](#poll_oneoff) to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). - -Bit: 27 - -- `sock_shutdown`: `bool` -The right to invoke [`sock_shutdown`](#sock_shutdown). - -Bit: 28 - -## `fd`: `Handle` -A file descriptor handle. - -Size: 4 - -Alignment: 4 - -### Supertypes -## `iovec`: `Record` -A region of memory for scatter/gather reads. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `Pointer` -The address of the buffer to be filled. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be filled. - -Offset: 4 - -## `ciovec`: `Record` -A region of memory for scatter/gather writes. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `ConstPointer` -The address of the buffer to be written. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be written. - -Offset: 4 - -## `iovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `ciovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `filedelta`: `s64` -Relative offset within a file. - -Size: 8 - -Alignment: 8 - -## `whence`: `Variant` -The position relative to which to set the offset of the file descriptor. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `set` -Seek relative to start-of-file. - -- `cur` -Seek relative to current position. - -- `end` -Seek relative to end-of-file. - -## `dircookie`: `u64` -A reference to the offset of a directory entry. - -The value 0 signifies the start of the directory. - -Size: 8 - -Alignment: 8 - -## `dirnamlen`: `u32` -The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent) struct. - -Size: 4 - -Alignment: 4 - -## `inode`: `u64` -File serial number that is unique within its file system. - -Size: 8 - -Alignment: 8 - -## `filetype`: `Variant` -The type of a file descriptor or file. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `unknown` -The type of the file descriptor or file is unknown or is different from any of the other types specified. - -- `block_device` -The file descriptor or file refers to a block device inode. - -- `character_device` -The file descriptor or file refers to a character device inode. - -- `directory` -The file descriptor or file refers to a directory inode. - -- `regular_file` -The file descriptor or file refers to a regular file inode. - -- `socket_dgram` -The file descriptor or file refers to a datagram socket. - -- `socket_stream` -The file descriptor or file refers to a byte-stream socket. - -- `symbolic_link` -The file refers to a symbolic link inode. - -## `dirent`: `Record` -A directory entry. - -Size: 24 - -Alignment: 8 - -### Record members -- `d_next`: [`dircookie`](#dircookie) -The offset of the next directory entry stored in this directory. - -Offset: 0 - -- `d_ino`: [`inode`](#inode) -The serial number of the file referred to by this directory entry. - -Offset: 8 - -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. - -Offset: 16 - -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. - -Offset: 20 - -## `advice`: `Variant` -File or memory access pattern advisory information. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `normal` -The application has no advice to give on its behavior with respect to the specified data. - -- `sequential` -The application expects to access the specified data sequentially from lower offsets to higher offsets. - -- `random` -The application expects to access the specified data in a random order. - -- `willneed` -The application expects to access the specified data in the near future. - -- `dontneed` -The application expects that it will not access the specified data in the near future. - -- `noreuse` -The application expects to access the specified data once and then not reuse it thereafter. - -## `fdflags`: `Record` -File descriptor flags. - -Size: 2 - -Alignment: 2 - -### Record members -- `append`: `bool` -Append mode: Data written to the file is always appended to the file's end. - -Bit: 0 - -- `dsync`: `bool` -Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - -Bit: 1 - -- `nonblock`: `bool` -Non-blocking mode. - -Bit: 2 - -- `rsync`: `bool` -Synchronized read I/O operations. - -Bit: 3 - -- `sync`: `bool` -Write according to synchronized I/O file integrity completion. In -addition to synchronizing the data stored in the file, the implementation -may also synchronously update the file's metadata. - -Bit: 4 - -## `fdstat`: `Record` -File descriptor attributes. - -Size: 24 - -Alignment: 8 - -### Record members -- `fs_filetype`: [`filetype`](#filetype) -File type. - -Offset: 0 - -- `fs_flags`: [`fdflags`](#fdflags) -File descriptor flags. - -Offset: 2 - -- `fs_rights_base`: [`rights`](#rights) -Rights that apply to this file descriptor. - -Offset: 8 - -- `fs_rights_inheriting`: [`rights`](#rights) -Maximum set of rights that may be installed on new file descriptors that -are created through this file descriptor, e.g., through [`path_open`](#path_open). - -Offset: 16 - -## `device`: `u64` -Identifier for a device containing a file system. Can be used in combination -with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. - -Size: 8 - -Alignment: 8 - -## `fstflags`: `Record` -Which file time attributes to adjust. - -Size: 2 - -Alignment: 2 - -### Record members -- `atim`: `bool` -Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - -Bit: 0 - -- `atim_now`: `bool` -Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 1 - -- `mtim`: `bool` -Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - -Bit: 2 - -- `mtim_now`: `bool` -Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 3 - -## `lookupflags`: `Record` -Flags determining the method of how paths are resolved. - -Size: 4 - -Alignment: 4 - -### Record members -- `symlink_follow`: `bool` -As long as the resolved path corresponds to a symbolic link, it is expanded. - -Bit: 0 - -## `oflags`: `Record` -Open flags used by [`path_open`](#path_open). - -Size: 2 - -Alignment: 2 - -### Record members -- `creat`: `bool` -Create file if it does not exist. - -Bit: 0 - -- `directory`: `bool` -Fail if not a directory. - -Bit: 1 - -- `excl`: `bool` -Fail if file already exists. - -Bit: 2 - -- `trunc`: `bool` -Truncate file to size 0. - -Bit: 3 - -## `linkcount`: `u64` -Number of hard links to an inode. - -Size: 8 - -Alignment: 8 - -## `filestat`: `Record` -File attributes. - -Size: 64 - -Alignment: 8 - -### Record members -- `dev`: [`device`](#device) -Device ID of device containing the file. - -Offset: 0 - -- `ino`: [`inode`](#inode) -File serial number. - -Offset: 8 - -- `filetype`: [`filetype`](#filetype) -File type. - -Offset: 16 - -- `nlink`: [`linkcount`](#linkcount) -Number of hard links to the file. - -Offset: 24 - -- `size`: [`filesize`](#filesize) -For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - -Offset: 32 - -- `atim`: [`timestamp`](#timestamp) -Last data access timestamp. - -Offset: 40 - -- `mtim`: [`timestamp`](#timestamp) -Last data modification timestamp. - -Offset: 48 - -- `ctim`: [`timestamp`](#timestamp) -Last file status change timestamp. - -Offset: 56 - -## `userdata`: `u64` -User-provided value that may be attached to objects that is retained when -extracted from the implementation. - -Size: 8 - -Alignment: 8 - -## `eventtype`: `Variant` -Type of a subscription to an event or its occurrence. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `clock` -The time value of clock [`subscription_clock::id`](#subscription_clock.id) has -reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - -- `fd_read` -File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has data -available for reading. This event always triggers for regular files. - -- `fd_write` -File descriptor [`subscription_fd_readwrite::file_descriptor`](#subscription_fd_readwrite.file_descriptor) has capacity -available for writing. This event always triggers for regular files. - -## `eventrwflags`: `Record` -The state of the file descriptor subscribed to with -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 2 - -Alignment: 2 - -### Record members -- `fd_readwrite_hangup`: `bool` -The peer of this socket has closed or disconnected. - -Bit: 0 - -## `event_fd_readwrite`: `Record` -The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). - -Size: 16 - -Alignment: 8 - -### Record members -- `nbytes`: [`filesize`](#filesize) -The number of bytes available for reading or writing. - -Offset: 0 - -- `flags`: [`eventrwflags`](#eventrwflags) -The state of the file descriptor. - -Offset: 8 - -## `event`: `Record` -An event that occurred. - -Size: 32 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). - -Offset: 0 - -- `error`: [`errno`](#errno) -If non-zero, an error that occurred while processing the subscription request. - -Offset: 8 - -- `type`: [`eventtype`](#eventtype) -The type of event that occured - -Offset: 10 - -- `fd_readwrite`: [`event_fd_readwrite`](#event_fd_readwrite) -The contents of the event, if it is an [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). [`eventtype::clock`](#eventtype.clock) events ignore this field. - -Offset: 16 - -## `subclockflags`: `Record` -Flags determining how to interpret the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout). - -Size: 2 - -Alignment: 2 - -### Record members -- `subscription_clock_abstime`: `bool` -If set, treat the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock -[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp -provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the -current time value of clock [`subscription_clock::id`](#subscription_clock.id). - -Bit: 0 - -## `subscription_clock`: `Record` -The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). - -Size: 32 - -Alignment: 8 - -### Record members -- `id`: [`clockid`](#clockid) -The clock against which to compare the timestamp. - -Offset: 0 - -- `timeout`: [`timestamp`](#timestamp) -The absolute or relative timestamp. - -Offset: 8 - -- `precision`: [`timestamp`](#timestamp) -The amount of time that the implementation may wait additionally -to coalesce with other events. - -Offset: 16 - -- `flags`: [`subclockflags`](#subclockflags) -Flags specifying whether the timeout is absolute or relative - -Offset: 24 - -## `subscription_fd_readwrite`: `Record` -The contents of a [`subscription`](#subscription) when type is type is -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 4 - -Alignment: 4 - -### Record members -- `file_descriptor`: [`fd`](#fd) -The file descriptor on which to wait for it to become ready for reading or writing. - -Offset: 0 - -## `subscription_u`: `Variant` -The contents of a [`subscription`](#subscription). - -Size: 40 - -Alignment: 8 - -### Variant Layout -- size: 40 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock`: [`subscription_clock`](#subscription_clock) - -- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -## `subscription`: `Record` -Subscription to an event. - -Size: 48 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that is attached to the subscription in the -implementation and returned through [`event::userdata`](#event.userdata). - -Offset: 0 - -- `u`: [`subscription_u`](#subscription_u) -The type of the event to which to subscribe, and its contents - -Offset: 8 - -## `exitcode`: `u32` -Exit code generated by a process when exiting. - -Size: 4 - -Alignment: 4 - -## `signal`: `Variant` -Signal condition. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `none` -No signal. Note that POSIX has special semantics for `kill(pid, 0)`, -so this value is reserved. - -- `hup` -Hangup. -Action: Terminates the process. - -- `int` -Terminate interrupt signal. -Action: Terminates the process. - -- `quit` -Terminal quit signal. -Action: Terminates the process. - -- `ill` -Illegal instruction. -Action: Terminates the process. - -- `trap` -Trace/breakpoint trap. -Action: Terminates the process. - -- `abrt` -Process abort signal. -Action: Terminates the process. - -- `bus` -Access to an undefined portion of a memory object. -Action: Terminates the process. - -- `fpe` -Erroneous arithmetic operation. -Action: Terminates the process. - -- `kill` -Kill. -Action: Terminates the process. - -- `usr1` -User-defined signal 1. -Action: Terminates the process. - -- `segv` -Invalid memory reference. -Action: Terminates the process. - -- `usr2` -User-defined signal 2. -Action: Terminates the process. - -- `pipe` -Write on a pipe with no one to read it. -Action: Ignored. - -- `alrm` -Alarm clock. -Action: Terminates the process. - -- `term` -Termination signal. -Action: Terminates the process. - -- `chld` -Child process terminated, stopped, or continued. -Action: Ignored. - -- `cont` -Continue executing, if stopped. -Action: Continues executing, if stopped. - -- `stop` -Stop executing. -Action: Stops executing. - -- `tstp` -Terminal stop signal. -Action: Stops executing. - -- `ttin` -Background process attempting read. -Action: Stops executing. - -- `ttou` -Background process attempting write. -Action: Stops executing. - -- `urg` -High bandwidth data is available at a socket. -Action: Ignored. - -- `xcpu` -CPU time limit exceeded. -Action: Terminates the process. - -- `xfsz` -File size limit exceeded. -Action: Terminates the process. - -- `vtalrm` -Virtual timer expired. -Action: Terminates the process. - -- `prof` -Profiling timer expired. -Action: Terminates the process. - -- `winch` -Window changed. -Action: Ignored. - -- `poll` -I/O possible. -Action: Terminates the process. - -- `pwr` -Power failure. -Action: Terminates the process. - -- `sys` -Bad system call. -Action: Terminates the process. - -## `riflags`: `Record` -Flags provided to [`sock_recv`](#sock_recv). - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_peek`: `bool` -Returns the message without removing it from the socket's receive queue. - -Bit: 0 - -- `recv_waitall`: `bool` -On byte-stream sockets, block until the full amount of data can be returned. - -Bit: 1 - -## `roflags`: `Record` -Flags returned by [`sock_recv`](#sock_recv). - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_data_truncated`: `bool` -Returned by [`sock_recv`](#sock_recv): Message data has been truncated. - -Bit: 0 - -## `siflags`: `u16` -Flags provided to [`sock_send`](#sock_send). As there are currently no flags -defined, it must be set to zero. - -Size: 2 - -Alignment: 2 - -## `sdflags`: `Record` -Which channels on a socket to shut down. - -Size: 1 - -Alignment: 1 - -### Record members -- `rd`: `bool` -Disables further receive operations. - -Bit: 0 - -- `wr`: `bool` -Disables further send operations. - -Bit: 1 - -## `preopentype`: `Variant` -Identifiers for preopened capabilities. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `dir` -A pre-opened directory. - -## `prestat_dir`: `Record` -The contents of a $prestat when type is [`preopentype::dir`](#preopentype.dir). - -Size: 4 - -Alignment: 4 - -### Record members -- `pr_name_len`: [`size`](#size) -The length of the directory name for use with [`fd_prestat_dir_name`](#fd_prestat_dir_name). - -Offset: 0 - -## `prestat`: `Variant` -Information about a pre-opened capability. - -Size: 8 - -Alignment: 4 - -### Variant Layout -- size: 8 -- align: 4 -- tag_size: 1 -### Variant cases -- `dir`: [`prestat_dir`](#prestat_dir) - -# Modules -## wasi_snapshot_preview1 -### Imports -#### Memory -### Functions - ---- - -#### `args_get(argv: Pointer>, argv_buf: Pointer) -> Result<(), errno>` -Read command-line argument data. -The size of the array should match that returned by [`args_sizes_get`](#args_sizes_get). -Each argument is expected to be `\0` terminated. - -##### Params -- `argv`: `Pointer>` - -- `argv_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `args_sizes_get() -> Result<(size, size), errno>` -Return command-line argument data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of arguments and the size of the argument string -data, or an error. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `environ_get(environ: Pointer>, environ_buf: Pointer) -> Result<(), errno>` -Read environment variable data. -The sizes of the buffers should match that returned by [`environ_sizes_get`](#environ_sizes_get). -Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - -##### Params -- `environ`: `Pointer>` - -- `environ_buf`: `Pointer` - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `environ_sizes_get() -> Result<(size, size), errno>` -Return environment variable data sizes. - -##### Params -##### Results -- `error`: `Result<(size, size), errno>` -Returns the number of environment variable arguments and the size of the -environment variable data. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, size)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`size`](#size) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `clock_res_get(id: clockid) -> Result` -Return the resolution of a clock. -Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, -return [`errno::inval`](#errno.inval). -Note: This is similar to `clock_getres` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the resolution. - -##### Results -- `error`: `Result` -The resolution of the clock, or an error if one happened. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `clock_time_get(id: clockid, precision: timestamp) -> Result` -Return the time value of a clock. -Note: This is similar to `clock_gettime` in POSIX. - -##### Params -- `id`: [`clockid`](#clockid) -The clock for which to return the time. - -- `precision`: [`timestamp`](#timestamp) -The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - -##### Results -- `error`: `Result` -The time value of the clock. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`timestamp`](#timestamp) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_advise(fd: fd, offset: filesize, len: filesize, advice: advice) -> Result<(), errno>` -Provide file advisory information on a file descriptor. -Note: This is similar to `posix_fadvise` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset within the file to which the advisory applies. - -- `len`: [`filesize`](#filesize) -The length of the region to which the advisory applies. - -- `advice`: [`advice`](#advice) -The advice. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_allocate(fd: fd, offset: filesize, len: filesize) -> Result<(), errno>` -Force the allocation of space in a file. -Note: This is similar to `posix_fallocate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filesize`](#filesize) -The offset at which to start the allocation. - -- `len`: [`filesize`](#filesize) -The length of the area that is allocated. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_close(fd: fd) -> Result<(), errno>` -Close a file descriptor. -Note: This is similar to `close` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_datasync(fd: fd) -> Result<(), errno>` -Synchronize the data of a file to disk. -Note: This is similar to `fdatasync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_get(fd: fd) -> Result` -Get the attributes of a file descriptor. -Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file descriptor's attributes are stored. - -###### Variant Layout -- size: 32 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`fdstat`](#fdstat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_set_flags(fd: fd, flags: fdflags) -> Result<(), errno>` -Adjust the flags associated with a file descriptor. -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`fdflags`](#fdflags) -The desired values of the file descriptor flags. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_fdstat_set_rights(fd: fd, fs_rights_base: rights, fs_rights_inheriting: rights) -> Result<(), errno>` -Adjust the rights associated with a file descriptor. -This can only be used to remove rights, and returns [`errno::notcapable`](#errno.notcapable) if called in a way that would attempt to add rights - -##### Params -- `fd`: [`fd`](#fd) - -- `fs_rights_base`: [`rights`](#rights) -The desired rights of the file descriptor. - -- `fs_rights_inheriting`: [`rights`](#rights) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_get(fd: fd) -> Result` -Return the attributes of an open file. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 72 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_set_size(fd: fd, size: filesize) -> Result<(), errno>` -Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. -Note: This is similar to `ftruncate` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `size`: [`filesize`](#filesize) -The desired file size. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_filestat_set_times(fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of an open file or directory. -Note: This is similar to `futimens` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_pread(fd: fd, iovs: iovec_array, offset: filesize) -> Result` -Read from a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `preadv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors in which to store data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to read. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_prestat_get(fd: fd) -> Result` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The buffer where the description is stored. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`prestat`](#prestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_prestat_dir_name(fd: fd, path: Pointer, path_len: size) -> Result<(), errno>` -Return a description of the given preopened file descriptor. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `Pointer` -A buffer into which to write the preopened directory name. - -- `path_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_pwrite(fd: fd, iovs: ciovec_array, offset: filesize) -> Result` -Write to a file descriptor, without using and updating the file descriptor's offset. -Note: This is similar to `pwritev` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -- `offset`: [`filesize`](#filesize) -The offset within the file at which to write. - -##### Results -- `error`: `Result` -The number of bytes written. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_read(fd: fd, iovs: iovec_array) -> Result` -Read from a file descriptor. -Note: This is similar to `readv` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -##### Results -- `error`: `Result` -The number of bytes read. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_readdir(fd: fd, buf: Pointer, buf_len: size, cookie: dircookie) -> Result` -Read directory entries from a directory. -When successful, the contents of the output buffer consist of a sequence of -directory entries. Each directory entry consists of a [`dirent`](#dirent) object, -followed by [`dirent::d_namlen`](#dirent.d_namlen) bytes holding the name of the directory -entry. -This function fills the output buffer as much as possible, potentially -truncating the last directory entry. This allows the caller to grow its -read buffer size in case it's too small to fit a single large directory -entry, or skip the oversized directory entry. - -##### Params -- `fd`: [`fd`](#fd) - -- `buf`: `Pointer` -The buffer where directory entries are stored - -- `buf_len`: [`size`](#size) - -- `cookie`: [`dircookie`](#dircookie) -The location within the directory to start reading - -##### Results -- `error`: `Result` -The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_renumber(fd: fd, to: fd) -> Result<(), errno>` -Atomically replace a file descriptor by renumbering another file descriptor. -Due to the strong focus on thread safety, this environment does not provide -a mechanism to duplicate or renumber a file descriptor to an arbitrary -number, like `dup2()`. This would be prone to race conditions, as an actual -file descriptor with the same number could be allocated by a different -thread at the same time. -This function provides a way to atomically renumber file descriptors, which -would disappear if `dup2()` were to be removed entirely. - -##### Params -- `fd`: [`fd`](#fd) - -- `to`: [`fd`](#fd) -The file descriptor to overwrite. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_seek(fd: fd, offset: filedelta, whence: whence) -> Result` -Move the offset of a file descriptor. -Note: This is similar to `lseek` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `offset`: [`filedelta`](#filedelta) -The number of bytes to move. - -- `whence`: [`whence`](#whence) -The base from which the offset is relative. - -##### Results -- `error`: `Result` -The new offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_sync(fd: fd) -> Result<(), errno>` -Synchronize the data and metadata of a file to disk. -Note: This is similar to `fsync` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_tell(fd: fd) -> Result` -Return the current offset of a file descriptor. -Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -##### Results -- `error`: `Result` -The current offset of the file descriptor, relative to the start of the file. - -###### Variant Layout -- size: 16 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filesize`](#filesize) - -- `err`: [`errno`](#errno) - - ---- - -#### `fd_write(fd: fd, iovs: ciovec_array) -> Result` -Write to a file descriptor. -Note: This is similar to `writev` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `iovs`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors from which to retrieve data. - -##### Results -- `error`: `Result` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_create_directory(fd: fd, path: string) -> Result<(), errno>` -Create a directory. -Note: This is similar to `mkdirat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path at which to create the directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_filestat_get(fd: fd, flags: lookupflags, path: string) -> Result` -Return the attributes of a file or directory. -Note: This is similar to `stat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to inspect. - -##### Results -- `error`: `Result` -The buffer where the file's attributes are stored. - -###### Variant Layout -- size: 72 -- align: 8 -- tag_size: 4 -###### Variant cases -- `ok`: [`filestat`](#filestat) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_filestat_set_times(fd: fd, flags: lookupflags, path: string, atim: timestamp, mtim: timestamp, fst_flags: fstflags) -> Result<(), errno>` -Adjust the timestamps of a file or directory. -Note: This is similar to `utimensat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The path of the file or directory to operate on. - -- `atim`: [`timestamp`](#timestamp) -The desired values of the data access timestamp. - -- `mtim`: [`timestamp`](#timestamp) -The desired values of the data modification timestamp. - -- `fst_flags`: [`fstflags`](#fstflags) -A bitmask indicating which timestamps to adjust. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_link(old_fd: fd, old_flags: lookupflags, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Create a hard link. -Note: This is similar to `linkat` in POSIX. - -##### Params -- `old_fd`: [`fd`](#fd) - -- `old_flags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `old_path`: `string` -The source path from which to link. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path at which to create the hard link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_open(fd: fd, dirflags: lookupflags, path: string, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags) -> Result` -Open a file or directory. -The returned file descriptor is not guaranteed to be the lowest-numbered -file descriptor not currently open; it is randomized to prevent -applications from depending on making assumptions about indexes, since this -is error-prone in multi-threaded contexts. The returned file descriptor is -guaranteed to be less than 2**31. -Note: This is similar to `openat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `dirflags`: [`lookupflags`](#lookupflags) -Flags determining the method of how the path is resolved. - -- `path`: `string` -The relative path of the file or directory to open, relative to the -[`path_open::fd`](#path_open.fd) directory. - -- `oflags`: [`oflags`](#oflags) -The method by which to open the file. - -- `fs_rights_base`: [`rights`](#rights) -The initial rights of the newly created file descriptor. The -implementation is allowed to return a file descriptor with fewer rights -than specified, if and only if those rights do not apply to the type of -file being opened. -The *base* rights are rights that will apply to operations using the file -descriptor itself, while the *inheriting* rights are rights that apply to -file descriptors derived from it. - -- `fs_rights_inheriting`: [`rights`](#rights) - -- `fdflags`: [`fdflags`](#fdflags) - -##### Results -- `error`: `Result` -The file descriptor of the file that has been opened. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`fd`](#fd) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_readlink(fd: fd, path: string, buf: Pointer, buf_len: size) -> Result` -Read the contents of a symbolic link. -Note: This is similar to `readlinkat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path of the symbolic link from which to read. - -- `buf`: `Pointer` -The buffer to which to write the contents of the symbolic link. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result` -The number of bytes placed in the buffer. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `path_remove_directory(fd: fd, path: string) -> Result<(), errno>` -Remove a directory. -Return [`errno::notempty`](#errno.notempty) if the directory is not empty. -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a directory to remove. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_rename(fd: fd, old_path: string, new_fd: fd, new_path: string) -> Result<(), errno>` -Rename a file or directory. -Note: This is similar to `renameat` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `old_path`: `string` -The source path of the file or directory to rename. - -- `new_fd`: [`fd`](#fd) -The working directory at which the resolution of the new path starts. - -- `new_path`: `string` -The destination path to which to rename the file or directory. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_symlink(old_path: string, fd: fd, new_path: string) -> Result<(), errno>` -Create a symbolic link. -Note: This is similar to `symlinkat` in POSIX. - -##### Params -- `old_path`: `string` -The contents of the symbolic link. - -- `fd`: [`fd`](#fd) - -- `new_path`: `string` -The destination path at which to create the symbolic link. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `path_unlink_file(fd: fd, path: string) -> Result<(), errno>` -Unlink a file. -Return [`errno::isdir`](#errno.isdir) if the path refers to a directory. -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `path`: `string` -The path to a file to unlink. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `poll_oneoff(in: ConstPointer, out: Pointer, nsubscriptions: size) -> Result` -Concurrently poll for the occurrence of a set of events. - -##### Params -- `in`: `ConstPointer` -The events to which to subscribe. - -- `out`: `Pointer` -The events that have occurred. - -- `nsubscriptions`: [`size`](#size) -Both the number of subscriptions and events. - -##### Results -- `error`: `Result` -The number of events stored. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `proc_exit(rval: exitcode)` -Terminate the process normally. An exit code of 0 indicates successful -termination of the program. The meanings of other values is dependent on -the environment. - -##### Params -- `rval`: [`exitcode`](#exitcode) -The exit code returned by the process. - -##### Results - ---- - -#### `proc_raise(sig: signal) -> Result<(), errno>` -Send a signal to the process of the calling thread. -Note: This is similar to `raise` in POSIX. - -##### Params -- `sig`: [`signal`](#signal) -The signal condition to trigger. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sched_yield() -> Result<(), errno>` -Temporarily yield execution of the calling thread. -Note: This is similar to [`sched_yield`](#sched_yield) in POSIX. - -##### Params -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `random_get(buf: Pointer, buf_len: size) -> Result<(), errno>` -Write high-quality random data into a buffer. -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. -This function may execute slowly, so when large mounts of random data are -required, it's advisable to use this function to seed a pseudo-random -number generator, rather than to provide the random data directly. - -##### Params -- `buf`: `Pointer` -The buffer to fill with random data. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_recv(fd: fd, ri_data: iovec_array, ri_flags: riflags) -> Result<(size, roflags), errno>` -Receive a message from a socket. -Note: This is similar to `recv` in POSIX, though it also supports reading -the data into multiple buffers in the manner of `readv`. - -##### Params -- `fd`: [`fd`](#fd) - -- `ri_data`: [`iovec_array`](#iovec_array) -List of scatter/gather vectors to which to store data. - -- `ri_flags`: [`riflags`](#riflags) -Message flags. - -##### Results -- `error`: `Result<(size, roflags), errno>` -Number of bytes stored in ri_data and message flags. - -###### Variant Layout -- size: 12 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: `(size, roflags)` - -####### Record members -- `0`: [`size`](#size) - -Offset: 0 - -- `1`: [`roflags`](#roflags) - -Offset: 4 - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_send(fd: fd, si_data: ciovec_array, si_flags: siflags) -> Result` -Send a message on a socket. -Note: This is similar to `send` in POSIX, though it also supports writing -the data from multiple buffers in the manner of `writev`. - -##### Params -- `fd`: [`fd`](#fd) - -- `si_data`: [`ciovec_array`](#ciovec_array) -List of scatter/gather vectors to which to retrieve data - -- `si_flags`: [`siflags`](#siflags) -Message flags. - -##### Results -- `error`: `Result` -Number of bytes transmitted. - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok`: [`size`](#size) - -- `err`: [`errno`](#errno) - - ---- - -#### `sock_shutdown(fd: fd, how: sdflags) -> Result<(), errno>` -Shut down socket send and receive channels. -Note: This is similar to `shutdown` in POSIX. - -##### Params -- `fd`: [`fd`](#fd) - -- `how`: [`sdflags`](#sdflags) -Which channels on the socket to shut down. - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - diff --git a/proposals/random/phases/snapshot/witx/typenames.witx b/proposals/random/phases/snapshot/witx/typenames.witx deleted file mode 100644 index 311b42233..000000000 --- a/proposals/random/phases/snapshot/witx/typenames.witx +++ /dev/null @@ -1,748 +0,0 @@ -;; Type names used by low-level WASI interfaces. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(typename $size u32) - -;;; Non-negative file size or length of a region within a file. -(typename $filesize u64) - -;;; Timestamp in nanoseconds. -(typename $timestamp u64) - -;;; Identifiers for clocks. -(typename $clockid - (enum (@witx tag u32) - ;;; The clock measuring real time. Time value zero corresponds with - ;;; 1970-01-01T00:00:00Z. - $realtime - ;;; The store-wide monotonic clock, which is defined as a clock measuring - ;;; real time, whose value cannot be adjusted and which cannot have negative - ;;; clock jumps. The epoch of this clock is undefined. The absolute time - ;;; value of this clock therefore has no meaning. - $monotonic - ;;; The CPU-time clock associated with the current process. - $process_cputime_id - ;;; The CPU-time clock associated with the current thread. - $thread_cputime_id - ) -) - -;;; Error codes returned by functions. -;;; Not all of these error codes are returned by the functions provided by this -;;; API; some are used in higher-level library layers, and others are provided -;;; merely for alignment with POSIX. -(typename $errno - (enum (@witx tag u16) - ;;; No error occurred. System call completed successfully. - $success - ;;; Argument list too long. - $2big - ;;; Permission denied. - $acces - ;;; Address in use. - $addrinuse - ;;; Address not available. - $addrnotavail - ;;; Address family not supported. - $afnosupport - ;;; Resource unavailable, or operation would block. - $again - ;;; Connection already in progress. - $already - ;;; Bad file descriptor. - $badf - ;;; Bad message. - $badmsg - ;;; Device or resource busy. - $busy - ;;; Operation canceled. - $canceled - ;;; No child processes. - $child - ;;; Connection aborted. - $connaborted - ;;; Connection refused. - $connrefused - ;;; Connection reset. - $connreset - ;;; Resource deadlock would occur. - $deadlk - ;;; Destination address required. - $destaddrreq - ;;; Mathematics argument out of domain of function. - $dom - ;;; Reserved. - $dquot - ;;; File exists. - $exist - ;;; Bad address. - $fault - ;;; File too large. - $fbig - ;;; Host is unreachable. - $hostunreach - ;;; Identifier removed. - $idrm - ;;; Illegal byte sequence. - $ilseq - ;;; Operation in progress. - $inprogress - ;;; Interrupted function. - $intr - ;;; Invalid argument. - $inval - ;;; I/O error. - $io - ;;; Socket is connected. - $isconn - ;;; Is a directory. - $isdir - ;;; Too many levels of symbolic links. - $loop - ;;; File descriptor value too large. - $mfile - ;;; Too many links. - $mlink - ;;; Message too large. - $msgsize - ;;; Reserved. - $multihop - ;;; Filename too long. - $nametoolong - ;;; Network is down. - $netdown - ;;; Connection aborted by network. - $netreset - ;;; Network unreachable. - $netunreach - ;;; Too many files open in system. - $nfile - ;;; No buffer space available. - $nobufs - ;;; No such device. - $nodev - ;;; No such file or directory. - $noent - ;;; Executable file format error. - $noexec - ;;; No locks available. - $nolck - ;;; Reserved. - $nolink - ;;; Not enough space. - $nomem - ;;; No message of the desired type. - $nomsg - ;;; Protocol not available. - $noprotoopt - ;;; No space left on device. - $nospc - ;;; Function not supported. - $nosys - ;;; The socket is not connected. - $notconn - ;;; Not a directory or a symbolic link to a directory. - $notdir - ;;; Directory not empty. - $notempty - ;;; State not recoverable. - $notrecoverable - ;;; Not a socket. - $notsock - ;;; Not supported, or operation not supported on socket. - $notsup - ;;; Inappropriate I/O control operation. - $notty - ;;; No such device or address. - $nxio - ;;; Value too large to be stored in data type. - $overflow - ;;; Previous owner died. - $ownerdead - ;;; Operation not permitted. - $perm - ;;; Broken pipe. - $pipe - ;;; Protocol error. - $proto - ;;; Protocol not supported. - $protonosupport - ;;; Protocol wrong type for socket. - $prototype - ;;; Result too large. - $range - ;;; Read-only file system. - $rofs - ;;; Invalid seek. - $spipe - ;;; No such process. - $srch - ;;; Reserved. - $stale - ;;; Connection timed out. - $timedout - ;;; Text file busy. - $txtbsy - ;;; Cross-device link. - $xdev - ;;; Extension: Capabilities insufficient. - $notcapable - ) -) - -;;; File descriptor rights, determining which actions may be performed. -(typename $rights - (flags (@witx repr u64) - ;;; The right to invoke `fd_datasync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::dsync`. - $fd_datasync - ;;; The right to invoke `fd_read` and `sock_recv`. - ;; - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. - $fd_read - ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. - $fd_seek - ;;; The right to invoke `fd_fdstat_set_flags`. - $fd_fdstat_set_flags - ;;; The right to invoke `fd_sync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. - $fd_sync - ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to - ;;; invoke `fd_tell`. - $fd_tell - ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. - $fd_write - ;;; The right to invoke `fd_advise`. - $fd_advise - ;;; The right to invoke `fd_allocate`. - $fd_allocate - ;;; The right to invoke `path_create_directory`. - $path_create_directory - ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::creat`. - $path_create_file - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; source directory. - $path_link_source - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; target directory. - $path_link_target - ;;; The right to invoke `path_open`. - $path_open - ;;; The right to invoke `fd_readdir`. - $fd_readdir - ;;; The right to invoke `path_readlink`. - $path_readlink - ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $path_rename_source - ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $path_rename_target - ;;; The right to invoke `path_filestat_get`. - $path_filestat_get - ;;; The right to change a file's size (there is no `path_filestat_set_size`). - ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. - $path_filestat_set_size - ;;; The right to invoke `path_filestat_set_times`. - $path_filestat_set_times - ;;; The right to invoke `fd_filestat_get`. - $fd_filestat_get - ;;; The right to invoke `fd_filestat_set_size`. - $fd_filestat_set_size - ;;; The right to invoke `fd_filestat_set_times`. - $fd_filestat_set_times - ;;; The right to invoke `path_symlink`. - $path_symlink - ;;; The right to invoke `path_remove_directory`. - $path_remove_directory - ;;; The right to invoke `path_unlink_file`. - $path_unlink_file - ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. - ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. - $poll_fd_readwrite - ;;; The right to invoke `sock_shutdown`. - $sock_shutdown - ) -) - -;;; A file descriptor handle. -(typename $fd (handle)) - -;;; A region of memory for scatter/gather reads. -(typename $iovec - (record - ;;; The address of the buffer to be filled. - (field $buf (@witx pointer u8)) - ;;; The length of the buffer to be filled. - (field $buf_len $size) - ) -) - -;;; A region of memory for scatter/gather writes. -(typename $ciovec - (record - ;;; The address of the buffer to be written. - (field $buf (@witx const_pointer u8)) - ;;; The length of the buffer to be written. - (field $buf_len $size) - ) -) - -(typename $iovec_array (list $iovec)) -(typename $ciovec_array (list $ciovec)) - -;;; Relative offset within a file. -(typename $filedelta s64) - -;;; The position relative to which to set the offset of the file descriptor. -(typename $whence - (enum (@witx tag u8) - ;;; Seek relative to start-of-file. - $set - ;;; Seek relative to current position. - $cur - ;;; Seek relative to end-of-file. - $end - ) -) - -;;; A reference to the offset of a directory entry. -;;; -;;; The value 0 signifies the start of the directory. -(typename $dircookie u64) - -;;; The type for the `dirent::d_namlen` field of `dirent` struct. -(typename $dirnamlen u32) - -;;; File serial number that is unique within its file system. -(typename $inode u64) - -;;; The type of a file descriptor or file. -(typename $filetype - (enum (@witx tag u8) - ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $unknown - ;;; The file descriptor or file refers to a block device inode. - $block_device - ;;; The file descriptor or file refers to a character device inode. - $character_device - ;;; The file descriptor or file refers to a directory inode. - $directory - ;;; The file descriptor or file refers to a regular file inode. - $regular_file - ;;; The file descriptor or file refers to a datagram socket. - $socket_dgram - ;;; The file descriptor or file refers to a byte-stream socket. - $socket_stream - ;;; The file refers to a symbolic link inode. - $symbolic_link - ) -) - -;;; A directory entry. -(typename $dirent - (record - ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie) - ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) - ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype) - ) -) - -;;; File or memory access pattern advisory information. -(typename $advice - (enum (@witx tag u8) - ;;; The application has no advice to give on its behavior with respect to the specified data. - $normal - ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $sequential - ;;; The application expects to access the specified data in a random order. - $random - ;;; The application expects to access the specified data in the near future. - $willneed - ;;; The application expects that it will not access the specified data in the near future. - $dontneed - ;;; The application expects to access the specified data once and then not reuse it thereafter. - $noreuse - ) -) - -;;; File descriptor flags. -(typename $fdflags - (flags (@witx repr u16) - ;;; Append mode: Data written to the file is always appended to the file's end. - $append - ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $dsync - ;;; Non-blocking mode. - $nonblock - ;;; Synchronized read I/O operations. - $rsync - ;;; Write according to synchronized I/O file integrity completion. In - ;;; addition to synchronizing the data stored in the file, the implementation - ;;; may also synchronously update the file's metadata. - $sync - ) -) - -;;; File descriptor attributes. -(typename $fdstat - (record - ;;; File type. - (field $fs_filetype $filetype) - ;;; File descriptor flags. - (field $fs_flags $fdflags) - ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights) - ;;; Maximum set of rights that may be installed on new file descriptors that - ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights) - ) -) - -;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode` to uniquely identify a file or directory in the filesystem. -(typename $device u64) - -;;; Which file time attributes to adjust. -(typename $fstflags - (flags (@witx repr u16) - ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. - $atim - ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. - $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. - $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. - $mtim_now - ) -) - -;;; Flags determining the method of how paths are resolved. -(typename $lookupflags - (flags (@witx repr u32) - ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $symlink_follow - ) -) - -;;; Open flags used by `path_open`. -(typename $oflags - (flags (@witx repr u16) - ;;; Create file if it does not exist. - $creat - ;;; Fail if not a directory. - $directory - ;;; Fail if file already exists. - $excl - ;;; Truncate file to size 0. - $trunc - ) -) - -;;; Number of hard links to an inode. -(typename $linkcount u64) - -;;; File attributes. -(typename $filestat - (record - ;;; Device ID of device containing the file. - (field $dev $device) - ;;; File serial number. - (field $ino $inode) - ;;; File type. - (field $filetype $filetype) - ;;; Number of hard links to the file. - (field $nlink $linkcount) - ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $size $filesize) - ;;; Last data access timestamp. - (field $atim $timestamp) - ;;; Last data modification timestamp. - (field $mtim $timestamp) - ;;; Last file status change timestamp. - (field $ctim $timestamp) - ) -) - -;;; User-provided value that may be attached to objects that is retained when -;;; extracted from the implementation. -(typename $userdata u64) - -;;; Type of a subscription to an event or its occurrence. -(typename $eventtype - (enum (@witx tag u8) - ;;; The time value of clock `subscription_clock::id` has - ;;; reached timestamp `subscription_clock::timeout`. - $clock - ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has data - ;;; available for reading. This event always triggers for regular files. - $fd_read - ;;; File descriptor `subscription_fd_readwrite::file_descriptor` has capacity - ;;; available for writing. This event always triggers for regular files. - $fd_write - ) -) - -;;; The state of the file descriptor subscribed to with -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $eventrwflags - (flags (@witx repr u16) - ;;; The peer of this socket has closed or disconnected. - $fd_readwrite_hangup - ) -) - -;;; The contents of an `event` when type is `eventtype::fd_read` or -;;; `eventtype::fd_write`. -(typename $event_fd_readwrite - (record - ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize) - ;;; The state of the file descriptor. - (field $flags $eventrwflags) - ) -) - -;;; An event that occurred. -(typename $event - (record - ;;; User-provided value that got attached to `subscription::userdata`. - (field $userdata $userdata) - ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno) - ;;; The type of event that occured - (field $type $eventtype) - ;;; The contents of the event, if it is an `eventtype::fd_read` or - ;;; `eventtype::fd_write`. `eventtype::clock` events ignore this field. - (field $fd_readwrite $event_fd_readwrite) - ) -) - -;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_clock::timeout`. -(typename $subclockflags - (flags (@witx repr u16) - ;;; If set, treat the timestamp provided in - ;;; `subscription_clock::timeout` as an absolute timestamp of clock - ;;; `subscription_clock::id`. If clear, treat the timestamp - ;;; provided in `subscription_clock::timeout` relative to the - ;;; current time value of clock `subscription_clock::id`. - $subscription_clock_abstime - ) -) - -;;; The contents of a `subscription` when type is `eventtype::clock`. -(typename $subscription_clock - (record - ;;; The clock against which to compare the timestamp. - (field $id $clockid) - ;;; The absolute or relative timestamp. - (field $timeout $timestamp) - ;;; The amount of time that the implementation may wait additionally - ;;; to coalesce with other events. - (field $precision $timestamp) - ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags) - ) -) - -;;; The contents of a `subscription` when type is type is -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $subscription_fd_readwrite - (record - ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $file_descriptor $fd) - ) -) - -;;; The contents of a `subscription`. -(typename $subscription_u - (union - (@witx tag $eventtype) - $subscription_clock - $subscription_fd_readwrite - $subscription_fd_readwrite - ) -) - -;;; Subscription to an event. -(typename $subscription - (record - ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event::userdata`. - (field $userdata $userdata) - ;;; The type of the event to which to subscribe, and its contents - (field $u $subscription_u) - ) -) - -;;; Exit code generated by a process when exiting. -(typename $exitcode u32) - -;;; Signal condition. -(typename $signal - (enum (@witx tag u8) - ;;; No signal. Note that POSIX has special semantics for `kill(pid, 0)`, - ;;; so this value is reserved. - $none - ;;; Hangup. - ;;; Action: Terminates the process. - $hup - ;;; Terminate interrupt signal. - ;;; Action: Terminates the process. - $int - ;;; Terminal quit signal. - ;;; Action: Terminates the process. - $quit - ;;; Illegal instruction. - ;;; Action: Terminates the process. - $ill - ;;; Trace/breakpoint trap. - ;;; Action: Terminates the process. - $trap - ;;; Process abort signal. - ;;; Action: Terminates the process. - $abrt - ;;; Access to an undefined portion of a memory object. - ;;; Action: Terminates the process. - $bus - ;;; Erroneous arithmetic operation. - ;;; Action: Terminates the process. - $fpe - ;;; Kill. - ;;; Action: Terminates the process. - $kill - ;;; User-defined signal 1. - ;;; Action: Terminates the process. - $usr1 - ;;; Invalid memory reference. - ;;; Action: Terminates the process. - $segv - ;;; User-defined signal 2. - ;;; Action: Terminates the process. - $usr2 - ;;; Write on a pipe with no one to read it. - ;;; Action: Ignored. - $pipe - ;;; Alarm clock. - ;;; Action: Terminates the process. - $alrm - ;;; Termination signal. - ;;; Action: Terminates the process. - $term - ;;; Child process terminated, stopped, or continued. - ;;; Action: Ignored. - $chld - ;;; Continue executing, if stopped. - ;;; Action: Continues executing, if stopped. - $cont - ;;; Stop executing. - ;;; Action: Stops executing. - $stop - ;;; Terminal stop signal. - ;;; Action: Stops executing. - $tstp - ;;; Background process attempting read. - ;;; Action: Stops executing. - $ttin - ;;; Background process attempting write. - ;;; Action: Stops executing. - $ttou - ;;; High bandwidth data is available at a socket. - ;;; Action: Ignored. - $urg - ;;; CPU time limit exceeded. - ;;; Action: Terminates the process. - $xcpu - ;;; File size limit exceeded. - ;;; Action: Terminates the process. - $xfsz - ;;; Virtual timer expired. - ;;; Action: Terminates the process. - $vtalrm - ;;; Profiling timer expired. - ;;; Action: Terminates the process. - $prof - ;;; Window changed. - ;;; Action: Ignored. - $winch - ;;; I/O possible. - ;;; Action: Terminates the process. - $poll - ;;; Power failure. - ;;; Action: Terminates the process. - $pwr - ;;; Bad system call. - ;;; Action: Terminates the process. - $sys - ) -) - -;;; Flags provided to `sock_recv`. -(typename $riflags - (flags (@witx repr u16) - ;;; Returns the message without removing it from the socket's receive queue. - $recv_peek - ;;; On byte-stream sockets, block until the full amount of data can be returned. - $recv_waitall - ) -) - -;;; Flags returned by `sock_recv`. -(typename $roflags - (flags (@witx repr u16) - ;;; Returned by `sock_recv`: Message data has been truncated. - $recv_data_truncated - ) -) - -;;; Flags provided to `sock_send`. As there are currently no flags -;;; defined, it must be set to zero. -(typename $siflags u16) - -;;; Which channels on a socket to shut down. -(typename $sdflags - (flags (@witx repr u8) - ;;; Disables further receive operations. - $rd - ;;; Disables further send operations. - $wr - ) -) - -;;; Identifiers for preopened capabilities. -(typename $preopentype - (enum (@witx tag u8) - ;;; A pre-opened directory. - $dir - ) -) - -;;; The contents of a $prestat when type is `preopentype::dir`. -(typename $prestat_dir - (record - ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size) - ) -) - -;;; Information about a pre-opened capability. -(typename $prestat - (union (@witx tag $preopentype) - $prestat_dir - ) -) - diff --git a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx b/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx deleted file mode 100644 index efb2c797f..000000000 --- a/proposals/random/phases/snapshot/witx/wasi_snapshot_preview1.witx +++ /dev/null @@ -1,510 +0,0 @@ -;; WASI Preview. This is an evolution of the API that WASI initially -;; launched with. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_snapshot_preview1 - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Read command-line argument data. - ;;; The size of the array should match that returned by `args_sizes_get`. - ;;; Each argument is expected to be `\0` terminated. - (@interface func (export "args_get") - (param $argv (@witx pointer (@witx pointer u8))) - (param $argv_buf (@witx pointer u8)) - (result $error (expected (error $errno))) - ) - ;;; Return command-line argument data sizes. - (@interface func (export "args_sizes_get") - ;;; Returns the number of arguments and the size of the argument string - ;;; data, or an error. - (result $error (expected (tuple $size $size) (error $errno))) - ) - - ;;; Read environment variable data. - ;;; The sizes of the buffers should match that returned by `environ_sizes_get`. - ;;; Key/value pairs are expected to be joined with `=`s, and terminated with `\0`s. - (@interface func (export "environ_get") - (param $environ (@witx pointer (@witx pointer u8))) - (param $environ_buf (@witx pointer u8)) - (result $error (expected (error $errno))) - ) - ;;; Return environment variable data sizes. - (@interface func (export "environ_sizes_get") - ;;; Returns the number of environment variable arguments and the size of the - ;;; environment variable data. - (result $error (expected (tuple $size $size) (error $errno))) - ) - - ;;; Return the resolution of a clock. - ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, - ;;; return `errno::inval`. - ;;; Note: This is similar to `clock_getres` in POSIX. - (@interface func (export "clock_res_get") - ;;; The clock for which to return the resolution. - (param $id $clockid) - ;;; The resolution of the clock, or an error if one happened. - (result $error (expected $timestamp (error $errno))) - ) - ;;; Return the time value of a clock. - ;;; Note: This is similar to `clock_gettime` in POSIX. - (@interface func (export "clock_time_get") - ;;; The clock for which to return the time. - (param $id $clockid) - ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value. - (param $precision $timestamp) - ;;; The time value of the clock. - (result $error (expected $timestamp (error $errno))) - ) - - ;;; Provide file advisory information on a file descriptor. - ;;; Note: This is similar to `posix_fadvise` in POSIX. - (@interface func (export "fd_advise") - (param $fd $fd) - ;;; The offset within the file to which the advisory applies. - (param $offset $filesize) - ;;; The length of the region to which the advisory applies. - (param $len $filesize) - ;;; The advice. - (param $advice $advice) - (result $error (expected (error $errno))) - ) - - ;;; Force the allocation of space in a file. - ;;; Note: This is similar to `posix_fallocate` in POSIX. - (@interface func (export "fd_allocate") - (param $fd $fd) - ;;; The offset at which to start the allocation. - (param $offset $filesize) - ;;; The length of the area that is allocated. - (param $len $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Close a file descriptor. - ;;; Note: This is similar to `close` in POSIX. - (@interface func (export "fd_close") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Synchronize the data of a file to disk. - ;;; Note: This is similar to `fdatasync` in POSIX. - (@interface func (export "fd_datasync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Get the attributes of a file descriptor. - ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields. - (@interface func (export "fd_fdstat_get") - (param $fd $fd) - ;;; The buffer where the file descriptor's attributes are stored. - (result $error (expected $fdstat (error $errno))) - ) - - ;;; Adjust the flags associated with a file descriptor. - ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - (@interface func (export "fd_fdstat_set_flags") - (param $fd $fd) - ;;; The desired values of the file descriptor flags. - (param $flags $fdflags) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the rights associated with a file descriptor. - ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights - (@interface func (export "fd_fdstat_set_rights") - (param $fd $fd) - ;;; The desired rights of the file descriptor. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of an open file. - (@interface func (export "fd_filestat_get") - (param $fd $fd) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. - ;;; Note: This is similar to `ftruncate` in POSIX. - (@interface func (export "fd_filestat_set_size") - (param $fd $fd) - ;;; The desired file size. - (param $size $filesize) - (result $error (expected (error $errno))) - ) - - ;;; Adjust the timestamps of an open file or directory. - ;;; Note: This is similar to `futimens` in POSIX. - (@interface func (export "fd_filestat_set_times") - (param $fd $fd) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Read from a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `preadv` in POSIX. - (@interface func (export "fd_pread") - (param $fd $fd) - ;;; List of scatter/gather vectors in which to store data. - (param $iovs $iovec_array) - ;;; The offset within the file at which to read. - (param $offset $filesize) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_get") - (param $fd $fd) - ;;; The buffer where the description is stored. - (result $error (expected $prestat (error $errno))) - ) - - ;;; Return a description of the given preopened file descriptor. - (@interface func (export "fd_prestat_dir_name") - (param $fd $fd) - ;;; A buffer into which to write the preopened directory name. - (param $path (@witx pointer u8)) - (param $path_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Write to a file descriptor, without using and updating the file descriptor's offset. - ;;; Note: This is similar to `pwritev` in POSIX. - (@interface func (export "fd_pwrite") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - ;;; The offset within the file at which to write. - (param $offset $filesize) - ;;; The number of bytes written. - (result $error (expected $size (error $errno))) - ) - - ;;; Read from a file descriptor. - ;;; Note: This is similar to `readv` in POSIX. - (@interface func (export "fd_read") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $iovs $iovec_array) - ;;; The number of bytes read. - (result $error (expected $size (error $errno))) - ) - - ;;; Read directory entries from a directory. - ;;; When successful, the contents of the output buffer consist of a sequence of - ;;; directory entries. Each directory entry consists of a `dirent` object, - ;;; followed by `dirent::d_namlen` bytes holding the name of the directory - ;;; entry. - ;; - ;;; This function fills the output buffer as much as possible, potentially - ;;; truncating the last directory entry. This allows the caller to grow its - ;;; read buffer size in case it's too small to fit a single large directory - ;;; entry, or skip the oversized directory entry. - (@interface func (export "fd_readdir") - (param $fd $fd) - ;;; The buffer where directory entries are stored - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The location within the directory to start reading - (param $cookie $dircookie) - ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. - (result $error (expected $size (error $errno))) - ) - - ;;; Atomically replace a file descriptor by renumbering another file descriptor. - ;; - ;;; Due to the strong focus on thread safety, this environment does not provide - ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary - ;;; number, like `dup2()`. This would be prone to race conditions, as an actual - ;;; file descriptor with the same number could be allocated by a different - ;;; thread at the same time. - ;; - ;;; This function provides a way to atomically renumber file descriptors, which - ;;; would disappear if `dup2()` were to be removed entirely. - (@interface func (export "fd_renumber") - (param $fd $fd) - ;;; The file descriptor to overwrite. - (param $to $fd) - (result $error (expected (error $errno))) - ) - - ;;; Move the offset of a file descriptor. - ;;; Note: This is similar to `lseek` in POSIX. - (@interface func (export "fd_seek") - (param $fd $fd) - ;;; The number of bytes to move. - (param $offset $filedelta) - ;;; The base from which the offset is relative. - (param $whence $whence) - ;;; The new offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Synchronize the data and metadata of a file to disk. - ;;; Note: This is similar to `fsync` in POSIX. - (@interface func (export "fd_sync") - (param $fd $fd) - (result $error (expected (error $errno))) - ) - - ;;; Return the current offset of a file descriptor. - ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. - (@interface func (export "fd_tell") - (param $fd $fd) - ;;; The current offset of the file descriptor, relative to the start of the file. - (result $error (expected $filesize (error $errno))) - ) - - ;;; Write to a file descriptor. - ;;; Note: This is similar to `writev` in POSIX. - (@interface func (export "fd_write") - (param $fd $fd) - ;;; List of scatter/gather vectors from which to retrieve data. - (param $iovs $ciovec_array) - (result $error (expected $size (error $errno))) - ) - - ;;; Create a directory. - ;;; Note: This is similar to `mkdirat` in POSIX. - (@interface func (export "path_create_directory") - (param $fd $fd) - ;;; The path at which to create the directory. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Return the attributes of a file or directory. - ;;; Note: This is similar to `stat` in POSIX. - (@interface func (export "path_filestat_get") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to inspect. - (param $path string) - ;;; The buffer where the file's attributes are stored. - (result $error (expected $filestat (error $errno))) - ) - - ;;; Adjust the timestamps of a file or directory. - ;;; Note: This is similar to `utimensat` in POSIX. - (@interface func (export "path_filestat_set_times") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $flags $lookupflags) - ;;; The path of the file or directory to operate on. - (param $path string) - ;;; The desired values of the data access timestamp. - (param $atim $timestamp) - ;;; The desired values of the data modification timestamp. - (param $mtim $timestamp) - ;;; A bitmask indicating which timestamps to adjust. - (param $fst_flags $fstflags) - (result $error (expected (error $errno))) - ) - - ;;; Create a hard link. - ;;; Note: This is similar to `linkat` in POSIX. - (@interface func (export "path_link") - (param $old_fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $old_flags $lookupflags) - ;;; The source path from which to link. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path at which to create the hard link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Open a file or directory. - ;; - ;;; The returned file descriptor is not guaranteed to be the lowest-numbered - ;;; file descriptor not currently open; it is randomized to prevent - ;;; applications from depending on making assumptions about indexes, since this - ;;; is error-prone in multi-threaded contexts. The returned file descriptor is - ;;; guaranteed to be less than 2**31. - ;; - ;;; Note: This is similar to `openat` in POSIX. - (@interface func (export "path_open") - (param $fd $fd) - ;;; Flags determining the method of how the path is resolved. - (param $dirflags $lookupflags) - ;;; The relative path of the file or directory to open, relative to the - ;;; `path_open::fd` directory. - (param $path string) - ;;; The method by which to open the file. - (param $oflags $oflags) - ;;; The initial rights of the newly created file descriptor. The - ;;; implementation is allowed to return a file descriptor with fewer rights - ;;; than specified, if and only if those rights do not apply to the type of - ;;; file being opened. - ;; - ;;; The *base* rights are rights that will apply to operations using the file - ;;; descriptor itself, while the *inheriting* rights are rights that apply to - ;;; file descriptors derived from it. - (param $fs_rights_base $rights) - (param $fs_rights_inheriting $rights) - (param $fdflags $fdflags) - ;;; The file descriptor of the file that has been opened. - (result $error (expected $fd (error $errno))) - ) - - ;;; Read the contents of a symbolic link. - ;;; Note: This is similar to `readlinkat` in POSIX. - (@interface func (export "path_readlink") - (param $fd $fd) - ;;; The path of the symbolic link from which to read. - (param $path string) - ;;; The buffer to which to write the contents of the symbolic link. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - ;;; The number of bytes placed in the buffer. - (result $error (expected $size (error $errno))) - ) - - ;;; Remove a directory. - ;;; Return `errno::notempty` if the directory is not empty. - ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - (@interface func (export "path_remove_directory") - (param $fd $fd) - ;;; The path to a directory to remove. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Rename a file or directory. - ;;; Note: This is similar to `renameat` in POSIX. - (@interface func (export "path_rename") - (param $fd $fd) - ;;; The source path of the file or directory to rename. - (param $old_path string) - ;;; The working directory at which the resolution of the new path starts. - (param $new_fd $fd) - ;;; The destination path to which to rename the file or directory. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - ;;; Create a symbolic link. - ;;; Note: This is similar to `symlinkat` in POSIX. - (@interface func (export "path_symlink") - ;;; The contents of the symbolic link. - (param $old_path string) - (param $fd $fd) - ;;; The destination path at which to create the symbolic link. - (param $new_path string) - (result $error (expected (error $errno))) - ) - - - ;;; Unlink a file. - ;;; Return `errno::isdir` if the path refers to a directory. - ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - (@interface func (export "path_unlink_file") - (param $fd $fd) - ;;; The path to a file to unlink. - (param $path string) - (result $error (expected (error $errno))) - ) - - ;;; Concurrently poll for the occurrence of a set of events. - (@interface func (export "poll_oneoff") - ;;; The events to which to subscribe. - (param $in (@witx const_pointer $subscription)) - ;;; The events that have occurred. - (param $out (@witx pointer $event)) - ;;; Both the number of subscriptions and events. - (param $nsubscriptions $size) - ;;; The number of events stored. - (result $error (expected $size (error $errno))) - ) - - ;;; Terminate the process normally. An exit code of 0 indicates successful - ;;; termination of the program. The meanings of other values is dependent on - ;;; the environment. - (@interface func (export "proc_exit") - ;;; The exit code returned by the process. - (param $rval $exitcode) - (@witx noreturn) - ) - - ;;; Send a signal to the process of the calling thread. - ;;; Note: This is similar to `raise` in POSIX. - (@interface func (export "proc_raise") - ;;; The signal condition to trigger. - (param $sig $signal) - (result $error (expected (error $errno))) - ) - - ;;; Temporarily yield execution of the calling thread. - ;;; Note: This is similar to `sched_yield` in POSIX. - (@interface func (export "sched_yield") - (result $error (expected (error $errno))) - ) - - ;;; Write high-quality random data into a buffer. - ;;; This function blocks when the implementation is unable to immediately - ;;; provide sufficient high-quality random data. - ;;; This function may execute slowly, so when large mounts of random data are - ;;; required, it's advisable to use this function to seed a pseudo-random - ;;; number generator, rather than to provide the random data directly. - (@interface func (export "random_get") - ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error (expected (error $errno))) - ) - - ;;; Receive a message from a socket. - ;;; Note: This is similar to `recv` in POSIX, though it also supports reading - ;;; the data into multiple buffers in the manner of `readv`. - (@interface func (export "sock_recv") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to store data. - (param $ri_data $iovec_array) - ;;; Message flags. - (param $ri_flags $riflags) - ;;; Number of bytes stored in ri_data and message flags. - (result $error (expected (tuple $size $roflags) (error $errno))) - ) - - ;;; Send a message on a socket. - ;;; Note: This is similar to `send` in POSIX, though it also supports writing - ;;; the data from multiple buffers in the manner of `writev`. - (@interface func (export "sock_send") - (param $fd $fd) - ;;; List of scatter/gather vectors to which to retrieve data - (param $si_data $ciovec_array) - ;;; Message flags. - (param $si_flags $siflags) - ;;; Number of bytes transmitted. - (result $error (expected $size (error $errno))) - ) - - ;;; Shut down socket send and receive channels. - ;;; Note: This is similar to `shutdown` in POSIX. - (@interface func (export "sock_shutdown") - (param $fd $fd) - ;;; Which channels on the socket to shut down. - (param $how $sdflags) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/random/proposal-template/README.md b/proposals/random/proposal-template/README.md deleted file mode 100644 index b97035935..000000000 --- a/proposals/random/proposal-template/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Proposal template - -This directory will hold a template for creating new proposals, to help people -get started. diff --git a/proposals/random/proposals/README.md b/proposals/random/proposals/README.md deleted file mode 100644 index 45c2c2852..000000000 --- a/proposals/random/proposals/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Proposals - -This directory contains overviews for proposals that are included in this -repository. - -This is analogous to [the correpsonding directory in the spec repository]. - -[the correpsonding directory in the spec repository]: https://github.com/WebAssembly/spec/tree/master/proposals diff --git a/proposals/random/snapshots/README.md b/proposals/random/snapshots/README.md deleted file mode 100644 index af94dbdef..000000000 --- a/proposals/random/snapshots/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# WASI Snapshots - -To balance between the needs of development and stability, snapshots -represent the state of all active proposals at a moment in time. Individual -Snapshots are stable, but WASI as a whole is evolving. diff --git a/proposals/random/snapshots/make-snapshot.sh b/proposals/random/snapshots/make-snapshot.sh deleted file mode 100755 index b30dfa2e5..000000000 --- a/proposals/random/snapshots/make-snapshot.sh +++ /dev/null @@ -1,159 +0,0 @@ -#!/bin/bash -# Creates a snapshot based on upstream proposal repositories. -# Derived from update-testsuite.sh in https://github.com/WebAssembly/testsuite -set -e -set -u -set -o pipefail - -ignore_dirs='' - -# TODO: Add the rest. -repos=' - WASI - wasi-filesystem - wasi-clocks - wasi-random -' - -log_and_run() { - echo ">>" $* - if ! $*; then - echo "sub-command failed: $*" - exit - fi -} - -try_log_and_run() { - echo ">>" $* - $* -} - -pushdir() { - pushd $1 >/dev/null || exit -} - -popdir() { - popd >/dev/null || exit -} - -update_repo() { - local repo=$1 - pushdir repos - if [ -d ${repo} ]; then - log_and_run git -C ${repo} fetch origin - log_and_run git -C ${repo} reset origin/main --hard - else - log_and_run git clone https://github.com/WebAssembly/${repo} - fi - - # Add upstream WASI as "WASI" remote. - if [ "${repo}" != "WASI" ]; then - pushdir ${repo} - if ! git remote | grep WASI >/dev/null; then - log_and_run git remote add WASI https://github.com/WebAssembly/WASI - fi - - log_and_run git fetch WASI - popdir - fi - popdir -} - -merge_with_WASI() { - local repo=$1 - - [ "${repo}" == "WASI" ] && return - - pushdir repos/${repo} - # Create and checkout "try-merge" branch. - if ! git branch | grep try-merge >/dev/null; then - log_and_run git branch try-merge origin/main - fi - log_and_run git checkout try-merge - - # Attempt to merge with WASI/main. - log_and_run git reset origin/main --hard - try_log_and_run git merge -q WASI/main -m "merged" - if [ $? -ne 0 ]; then - # Ignore merge conflicts in non-test directories. - # We don't care about those changes. - try_log_and_run git checkout --ours ${ignore_dirs} - try_log_and_run git add ${ignore_dirs} - try_log_and_run git -c core.editor=true merge --continue - if [ $? -ne 0 ]; then - git merge --abort - popdir - return 1 - fi - fi - popdir - return 0 -} - -snapshot_name=$(date --iso-8601) -snapshot_dir=snapshots/$snapshot_name -mkdir -p $snapshot_dir - -commit_message_file=$PWD/commit_message -echo -e "Update repos\n" > $commit_message_file - -failed_repos= - -for repo in ${repos}; do - echo "++ updating ${repo}" - update_repo ${repo} - - if ! merge_with_WASI ${repo}; then - echo -e "!! error merging ${repo}, skipping\n" - failed_repos="${failed_repos} ${repo}" - continue - fi - - if [ "${repo}" = "WASI" ]; then - dest_dir=$snapshot_dir - log_and_run cp -r repos/${repo}/standard ${dest_dir} - else - dest_dir=$snapshot_dir/proposals/${repo} - mkdir -p ${dest_dir} - - # Don't add tests from proposal that are the same as WASI. - pushdir repos/${repo} - for new in $(find standard -type f); do - old=../../repos/WASI/${new} - if [[ ! -f ${old} ]] || ! diff ${old} ${new} >/dev/null; then - log_and_run cp ${new} ../../${dest_dir} - fi - done - popdir - fi - - # Check whether any files were removed. - for old in $(find ${dest_dir} -type f); do - new=$(find repos/${repo}/standard -name ${old##*/}) - if [[ ! -f ${new} ]]; then - log_and_run git rm ${old} - fi - done - - # Check whether any files were updated. - if [ $(git status -s ${dest_dir} | wc -l) -ne 0 ]; then - log_and_run git add ${dest_dir}/* - - repo_sha=$(git -C repos/${repo} log --max-count=1 --oneline origin/main| sed -e 's/ .*//') - echo " ${repo}:" >> $commit_message_file - echo " https://github.com/WebAssembly/${repo}/commit/${repo_sha}" >> $commit_message_file - fi - - echo -e "-- ${repo}\n" -done - -echo "" >> $commit_message_file -echo "This change was automatically generated by \`make-snapshot.sh\`" >> $commit_message_file -git commit -a -F $commit_message_file -# git push - -echo "done" - -if [ -n "${failed_repos}" ]; then - echo "!! failed to update repos: ${failed_repos}" -fi diff --git a/proposals/random/standard/README.md b/proposals/random/standard/README.md deleted file mode 100644 index ad6f93c7c..000000000 --- a/proposals/random/standard/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# WASI Standard - -In the [main WASI repository], this directory holds proposals which have -[completed the standardization process]. - -In a proposal repository, which is a fork of the main WASI repository, -this directory holds the current proposal, including witx specifications, -tests, and documentation. When the proposal is standardized, the fork is -merged into the main repository. - -[main WASI repository]: https://github.com/WebAssembly/WASI/issues/360 -[completed the standardization process]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md#5-the-feature-is-standardized-working-group diff --git a/proposals/random/standard/wasi-random/docs.md b/proposals/random/standard/wasi-random/docs.md deleted file mode 100644 index cfe589f3b..000000000 --- a/proposals/random/standard/wasi-random/docs.md +++ /dev/null @@ -1,1242 +0,0 @@ -# Types -## `size`: `usize` -An array size. - -Note: This is similar to `size_t` in POSIX. - -Size: 4 - -Alignment: 4 - -## `filesize`: `u64` -Non-negative file size or length of a region within a file. - -Size: 8 - -Alignment: 8 - -## `timestamp`: `u64` -Timestamp in nanoseconds. - -Size: 8 - -Alignment: 8 - -## `clockid`: `Variant` -Identifiers for clocks. - -Size: 4 - -Alignment: 4 - -### Variant cases -- `realtime` -The clock measuring real time. Time value zero corresponds with -1970-01-01T00:00:00Z. - -- `monotonic` -The store-wide monotonic clock, which is defined as a clock measuring -real time, whose value cannot be adjusted and which cannot have negative -clock jumps. The epoch of this clock is undefined. The absolute time -value of this clock therefore has no meaning. - -## `errno`: `Variant` -Error codes returned by functions. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX. - -Size: 2 - -Alignment: 2 - -### Variant cases -- `success` -No error occurred. System call completed successfully. - -- `2big` -Argument list too long. - -- `access` -Permission denied. - -- `addrinuse` -Address in use. - -- `addrnotavail` -Address not available. - -- `afnosupport` -Address family not supported. - -- `again` -Resource unavailable, or operation would block. - -- `already` -Connection already in progress. - -- `badf` -Bad file descriptor. - -- `badmsg` -Bad message. - -- `busy` -Device or resource busy. - -- `canceled` -Operation canceled. - -- `child` -No child processes. - -- `connaborted` -Connection aborted. - -- `connrefused` -Connection refused. - -- `connreset` -Connection reset. - -- `deadlk` -Resource deadlock would occur. - -- `destaddrreq` -Destination address required. - -- `dom` -Mathematics argument out of domain of function. - -- `dquot` -Reserved. - -- `exist` -File exists. - -- `fault` -Bad address. - -- `fbig` -File too large. - -- `hostunreach` -Host is unreachable. - -- `idrm` -Identifier removed. - -- `ilseq` -Illegal byte sequence. - -- `inprogress` -Operation in progress. - -- `intr` -Interrupted function. - -- `inval` -Invalid argument. - -- `io` -I/O error. - -- `isconn` -Socket is connected. - -- `isdir` -Is a directory. - -- `loop` -Too many levels of symbolic links. - -- `mfile` -File descriptor value too large. - -- `mlink` -Too many links. - -- `msgsize` -Message too large. - -- `multihop` -Reserved. - -- `nametoolong` -Filename too long. - -- `netdown` -Network is down. - -- `netreset` -Connection aborted by network. - -- `netunreach` -Network unreachable. - -- `nfile` -Too many files open in system. - -- `nobufs` -No buffer space available. - -- `nodev` -No such device. - -- `noent` -No such file or directory. - -- `noexec` -Executable file format error. - -- `nolck` -No locks available. - -- `nolink` -Reserved. - -- `nomem` -Not enough space. - -- `nomsg` -No message of the desired type. - -- `noprotoopt` -Protocol not available. - -- `nospc` -No space left on device. - -- `nosys` -Function not supported. - -- `notconn` -The socket is not connected. - -- `notdir` -Not a directory or a symbolic link to a directory. - -- `notempty` -Directory not empty. - -- `notrecoverable` -State not recoverable. - -- `notsock` -Not a socket. - -- `notsup` -Not supported, or operation not supported on socket. - -- `notty` -Inappropriate I/O control operation. - -- `nxio` -No such device or address. - -- `overflow` -Value too large to be stored in data type. - -- `ownerdead` -Previous owner died. - -- `perm` -Operation not permitted. - -- `pipe` -Broken pipe. - -- `proto` -Protocol error. - -- `protonosupport` -Protocol not supported. - -- `prototype` -Protocol wrong type for socket. - -- `range` -Result too large. - -- `rofs` -Read-only file system. - -- `spipe` -Invalid seek. - -- `srch` -No such process. - -- `stale` -Reserved. - -- `timedout` -Connection timed out. - -- `txtbsy` -Text file busy. - -- `xdev` -Cross-device link. - -- `notcapable` -Extension: Capabilities insufficient. - -## `rights`: `Record` -File descriptor rights, determining which actions may be performed. - -Size: 8 - -Alignment: 8 - -### Record members -- `fd_datasync`: `bool` -The right to invoke `fd_datasync`. -If `path_open` is set, includes the right to invoke -`path_open` with [`fdflags::dsync`](#fdflags.dsync). - -Bit: 0 - -- `fd_read`: `bool` -The right to invoke `fd_read` and `sock_recv`. -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pread`. - -Bit: 1 - -- `fd_seek`: `bool` -The right to invoke `fd_seek`. This flag implies [`rights::fd_tell`](#rights.fd_tell). - -Bit: 2 - -- `fd_fdstat_set_flags`: `bool` -The right to invoke `fd_fdstat_set_flags`. - -Bit: 3 - -- `fd_sync`: `bool` -The right to invoke `fd_sync`. -If `path_open` is set, includes the right to invoke -`path_open` with [`fdflags::rsync`](#fdflags.rsync) and [`fdflags::dsync`](#fdflags.dsync). - -Bit: 4 - -- `fd_tell`: `bool` -The right to invoke `fd_seek` in such a way that the file offset -remains unaltered (i.e., [`whence::cur`](#whence.cur) with offset zero), or to -invoke `fd_tell`. - -Bit: 5 - -- `fd_write`: `bool` -The right to invoke `fd_write` and `sock_send`. -If [`rights::fd_seek`](#rights.fd_seek) is set, includes the right to invoke `fd_pwrite`. - -Bit: 6 - -- `fd_advise`: `bool` -The right to invoke `fd_advise`. - -Bit: 7 - -- `fd_allocate`: `bool` -The right to invoke `fd_allocate`. - -Bit: 8 - -- `path_create_directory`: `bool` -The right to invoke `path_create_directory`. - -Bit: 9 - -- `path_create_file`: `bool` -If `path_open` is set, the right to invoke `path_open` with [`oflags::create`](#oflags.create). - -Bit: 10 - -- `path_link_source`: `bool` -The right to invoke `path_link` with the file descriptor as the -source directory. - -Bit: 11 - -- `path_link_target`: `bool` -The right to invoke `path_link` with the file descriptor as the -target directory. - -Bit: 12 - -- `path_open`: `bool` -The right to invoke `path_open`. - -Bit: 13 - -- `fd_readdir`: `bool` -The right to invoke `fd_readdir`. - -Bit: 14 - -- `path_readlink`: `bool` -The right to invoke `path_readlink`. - -Bit: 15 - -- `path_rename_source`: `bool` -The right to invoke `path_rename` with the file descriptor as the source directory. - -Bit: 16 - -- `path_rename_target`: `bool` -The right to invoke `path_rename` with the file descriptor as the target directory. - -Bit: 17 - -- `path_filestat_get`: `bool` -The right to invoke `path_filestat_get`. - -Bit: 18 - -- `path_filestat_set_size`: `bool` -The right to change a file's size. -If `path_open` is set, includes the right to invoke `path_open` with [`oflags::trunc`](#oflags.trunc). -Note: there is no function named `path_filestat_set_size`. This follows POSIX design, -which only has `ftruncate` and does not provide `ftruncateat`. -While such function would be desirable from the API design perspective, there are virtually -no use cases for it since no code written for POSIX systems would use it. -Moreover, implementing it would require multiple syscalls, leading to inferior performance. - -Bit: 19 - -- `path_filestat_set_times`: `bool` -The right to invoke `path_filestat_set_times`. - -Bit: 20 - -- `path_permissions_set`: `bool` -The right to invoke `path_permissions_set`. - -Bit: 21 - -- `fd_filestat_get`: `bool` -The right to invoke `fd_filestat_get`. - -Bit: 22 - -- `fd_filestat_set_size`: `bool` -The right to invoke `fd_filestat_set_size`. - -Bit: 23 - -- `fd_filestat_set_times`: `bool` -The right to invoke `fd_filestat_set_times`. - -Bit: 24 - -- `fd_permissions_set`: `bool` -The right to invoke `fd_permissions_set`. - -Bit: 25 - -- `path_symlink`: `bool` -The right to invoke `path_symlink`. - -Bit: 26 - -- `path_remove_directory`: `bool` -The right to invoke `path_remove_directory`. - -Bit: 27 - -- `path_unlink_file`: `bool` -The right to invoke `path_unlink_file`. - -Bit: 28 - -- `poll_fd_readwrite`: `bool` -If [`rights::fd_read`](#rights.fd_read) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_read`](#eventtype.fd_read). -If [`rights::fd_write`](#rights.fd_write) is set, includes the right to invoke `poll_oneoff` to subscribe to [`eventtype::fd_write`](#eventtype.fd_write). - -Bit: 29 - -- `sock_shutdown`: `bool` -The right to invoke `sock_shutdown`. - -Bit: 30 - -## `fd`: `Handle` -A file descriptor handle. - -Size: 4 - -Alignment: 4 - -### Supertypes -## `iovec`: `Record` -A region of memory for scatter/gather reads. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `Pointer` -The address of the buffer to be filled. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be filled. - -Offset: 4 - -## `ciovec`: `Record` -A region of memory for scatter/gather writes. - -Size: 8 - -Alignment: 4 - -### Record members -- `buf`: `ConstPointer` -The address of the buffer to be written. - -Offset: 0 - -- `buf_len`: [`size`](#size) -The length of the buffer to be written. - -Offset: 4 - -## `iovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `ciovec_array`: `List` - -Size: 8 - -Alignment: 4 - -## `filedelta`: `s64` -Relative offset within a file. - -Size: 8 - -Alignment: 8 - -## `whence`: `Variant` -The position relative to which to set the offset of the file descriptor. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `set` -Seek relative to start-of-file. - -- `cur` -Seek relative to current position. - -- `end` -Seek relative to end-of-file. - -## `dircookie`: `u64` -A reference to the offset of a directory entry. - -Size: 8 - -Alignment: 8 - -### Constants -- `start` - -## `dirnamlen`: `u32` -The type for the [`dirent::d_namlen`](#dirent.d_namlen) field of [`dirent`](#dirent). - -Size: 4 - -Alignment: 4 - -## `inode`: `u64` -File serial number that is unique within its file system. - -Size: 8 - -Alignment: 8 - -## `filetype`: `Variant` -The type of a file descriptor or file. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `unknown` -The type of the file descriptor or file is unknown or is different from any of the other types specified. - -- `block_device` -The file descriptor or file refers to a block device inode. - -- `character_device` -The file descriptor or file refers to a character device inode. - -- `directory` -The file descriptor or file refers to a directory inode. - -- `regular_file` -The file descriptor or file refers to a regular file inode. - -- `socket_dgram` -The file descriptor or file refers to a datagram socket. - -- `socket_stream` -The file descriptor or file refers to a byte-stream socket. - -- `symbolic_link` -The file refers to a symbolic link inode. - -- `fifo` -The file descriptor or file refers to a FIFO. - -## `dirent`: `Record` -A directory entry. - -Size: 24 - -Alignment: 8 - -### Record members -- `d_next`: [`dircookie`](#dircookie) -The offset of the next directory entry stored in this directory. - -Offset: 0 - -- `d_ino`: [`inode`](#inode) -The serial number of the file referred to by this directory entry. - -Offset: 8 - -- `d_type`: [`filetype`](#filetype) -The type of the file referred to by this directory entry. - -Offset: 16 - -- `d_namlen`: [`dirnamlen`](#dirnamlen) -The length of the name of the directory entry. - -Offset: 20 - -## `advice`: `Variant` -File or memory access pattern advisory information. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `normal` -The application has no advice to give on its behavior with respect to the specified data. - -- `sequential` -The application expects to access the specified data sequentially from lower offsets to higher offsets. - -- `random` -The application expects to access the specified data in a random order. - -- `willneed` -The application expects to access the specified data in the near future. - -- `dontneed` -The application expects that it will not access the specified data in the near future. - -- `noreuse` -The application expects to access the specified data once and then not reuse it thereafter. - -## `fdflags`: `Record` -File descriptor flags. - -Size: 2 - -Alignment: 2 - -### Record members -- `append`: `bool` -Append mode: Data written to the file is always appended to the file's end. - -Bit: 0 - -- `dsync`: `bool` -Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - -Bit: 1 - -- `nonblock`: `bool` -Non-blocking mode. - -Bit: 2 - -- `rsync`: `bool` -Synchronized read I/O operations. - -Bit: 3 - -- `sync`: `bool` -Write according to synchronized I/O file integrity completion. In -addition to synchronizing the data stored in the file, the implementation -may also synchronously update the file's metadata. - -Bit: 4 - -## `fdstat`: `Record` -File descriptor attributes. - -Size: 24 - -Alignment: 8 - -### Record members -- `fs_filetype`: [`filetype`](#filetype) -File type. - -Offset: 0 - -- `fs_flags`: [`fdflags`](#fdflags) -File descriptor flags. - -Offset: 2 - -- `fs_rights_base`: [`rights`](#rights) -Rights that apply to this file descriptor. - -Offset: 8 - -- `fs_rights_inheriting`: [`rights`](#rights) -Maximum set of rights that may be installed on new file descriptors that -are created through this file descriptor, e.g., through `path_open`. - -Offset: 16 - -## `device`: `u64` -Identifier for a device containing a file system. Can be used in combination -with [`inode`](#inode) to uniquely identify a file or directory in the filesystem. - -Size: 8 - -Alignment: 8 - -## `fstflags`: `Record` -Which file time attributes to adjust. - -Size: 2 - -Alignment: 2 - -### Record members -- `atim`: `bool` -Adjust the last data access timestamp to the value stored in [`filestat::atim`](#filestat.atim). - -Bit: 0 - -- `atim_now`: `bool` -Adjust the last data access timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 1 - -- `mtim`: `bool` -Adjust the last data modification timestamp to the value stored in [`filestat::mtim`](#filestat.mtim). - -Bit: 2 - -- `mtim_now`: `bool` -Adjust the last data modification timestamp to the time of clock [`clockid::realtime`](#clockid.realtime). - -Bit: 3 - -## `lookupflags`: `Record` -Flags determining the method of how paths are resolved. - -Size: 4 - -Alignment: 4 - -### Record members -- `symlink_follow`: `bool` -As long as the resolved path corresponds to a symbolic link, it is expanded. - -Bit: 0 - -## `oflags`: `Record` -Open flags used by `path_open`. - -Size: 2 - -Alignment: 2 - -### Record members -- `create`: `bool` -Create file if it does not exist. - -Bit: 0 - -- `directory`: `bool` -Fail if not a directory. - -Bit: 1 - -- `excl`: `bool` -Fail if file already exists. - -Bit: 2 - -- `trunc`: `bool` -Truncate file to size 0. - -Bit: 3 - -## `linkcount`: `u64` -Number of hard links to an inode. - -Size: 8 - -Alignment: 8 - -## `permissions`: `Record` -File permissions. This represents the permissions associated with a -file in a filesystem, and don't fully reflect all the conditions -which determine whether a given WASI program can access the file. - -Size: 1 - -Alignment: 1 - -### Record members -- `read`: `bool` -For files, permission to read the file. -For directories, permission to do `readdir` and access files -within the directory. - -Note: This is similar to the read bit being set on files, and the -read *and* execute bits being set on directories, in POSIX. - -Bit: 0 - -- `write`: `bool` -For files, permission to mutate the file. -For directories, permission to create, remove, and rename items -within the directory. - -Bit: 1 - -- `execute`: `bool` -For files, permission to "execute" the file, using whatever -concept of "executing" the host filesystem has. -This flag is not valid for directories. - -Bit: 2 - -- `private`: `bool` -For filesystems which have a concept of multiple "users", this flag -indicates that the file is only accessible by the effective "user" -that the WASI store uses to access the filesystem, and inaccessible -to other "users". - -Bit: 3 - -## `filestat`: `Record` -File attributes. - -Size: 64 - -Alignment: 8 - -### Record members -- `dev`: [`device`](#device) -Device ID of device containing the file. - -Offset: 0 - -- `ino`: [`inode`](#inode) -File serial number. - -Offset: 8 - -- `filetype`: [`filetype`](#filetype) -File type. - -Offset: 16 - -- `permissions`: [`permissions`](#permissions) -File permissions. - -Offset: 17 - -- `nlink`: [`linkcount`](#linkcount) -Number of hard links to the file. - -Offset: 24 - -- `size`: [`filesize`](#filesize) -For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - -Offset: 32 - -- `atim`: [`timestamp`](#timestamp) -Last data access timestamp. - -Offset: 40 - -- `mtim`: [`timestamp`](#timestamp) -Last data modification timestamp. - -Offset: 48 - -- `ctim`: [`timestamp`](#timestamp) -Last file status change timestamp. - -Offset: 56 - -## `userdata`: `u64` -User-provided value that may be attached to objects that is retained when -extracted from the implementation. - -Size: 8 - -Alignment: 8 - -## `eventtype`: `Variant` -Type of a subscription to an event or its occurrence. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `clock` -The time value of clock [`subscription_clock::id`](#subscription_clock.id) has -reached timestamp [`subscription_clock::timeout`](#subscription_clock.timeout). - -- `fd_read` -File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has data -available for reading. This event always triggers for regular files. - -- `fd_write` -File descriptor [`subscription_fd_readwrite::fd`](#subscription_fd_readwrite.fd) has capacity -available for writing. This event always triggers for regular files. - -## `eventrwflags`: `Record` -The state of the file descriptor subscribed to with -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 2 - -Alignment: 2 - -### Record members -- `fd_readwrite_hangup`: `bool` -The peer of this socket has closed or disconnected. - -Bit: 0 - -## `event_fd_readwrite`: `Record` -The contents of an [`event`](#event) when type is [`eventtype::fd_read`](#eventtype.fd_read) or -[`eventtype::fd_write`](#eventtype.fd_write). - -Size: 16 - -Alignment: 8 - -### Record members -- `nbytes`: [`filesize`](#filesize) -The number of bytes available for reading or writing. - -Offset: 0 - -- `flags`: [`eventrwflags`](#eventrwflags) -The state of the file descriptor. - -Offset: 8 - -## `event_u`: `Variant` -The contents of an [`event`](#event). - -Size: 24 - -Alignment: 8 - -### Variant Layout -- size: 24 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock` - -- `fd_read`: [`event_fd_readwrite`](#event_fd_readwrite) - -- `fd_write`: [`event_fd_readwrite`](#event_fd_readwrite) - -## `event`: `Record` -An event that occurred. - -Size: 40 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that got attached to [`subscription::userdata`](#subscription.userdata). - -Offset: 0 - -- `error`: [`errno`](#errno) -If non-zero, an error that occurred while processing the subscription request. - -Offset: 8 - -- `u`: [`event_u`](#event_u) -The type of the event that occurred, and the contents of the event - -Offset: 16 - -## `subclockflags`: `Record` -Flags determining how to interpret the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout). - -Size: 2 - -Alignment: 2 - -### Record members -- `subscription_clock_abstime`: `bool` -If set, treat the timestamp provided in -[`subscription_clock::timeout`](#subscription_clock.timeout) as an absolute timestamp of clock -[`subscription_clock::id`](#subscription_clock.id). If clear, treat the timestamp -provided in [`subscription_clock::timeout`](#subscription_clock.timeout) relative to the -current time value of clock [`subscription_clock::id`](#subscription_clock.id). - -Bit: 0 - -## `subscription_clock`: `Record` -The contents of a [`subscription`](#subscription) when type is [`eventtype::clock`](#eventtype.clock). - -Size: 32 - -Alignment: 8 - -### Record members -- `id`: [`clockid`](#clockid) -The clock against which to compare the timestamp. - -Offset: 0 - -- `timeout`: [`timestamp`](#timestamp) -The absolute or relative timestamp. - -Offset: 8 - -- `precision`: [`timestamp`](#timestamp) -The amount of time that the implementation may wait additionally -to coalesce with other events. - -Offset: 16 - -- `flags`: [`subclockflags`](#subclockflags) -Flags specifying whether the timeout is absolute or relative - -Offset: 24 - -## `subscription_fd_readwrite`: `Record` -The contents of a [`subscription`](#subscription) when type is type is -[`eventtype::fd_read`](#eventtype.fd_read) or [`eventtype::fd_write`](#eventtype.fd_write). - -Size: 4 - -Alignment: 4 - -### Record members -- `fd`: [`fd`](#fd) -The file descriptor on which to wait for it to become ready for reading or writing. - -Offset: 0 - -## `subscription_u`: `Variant` -The contents of a [`subscription`](#subscription). - -Size: 40 - -Alignment: 8 - -### Variant Layout -- size: 40 -- align: 8 -- tag_size: 1 -### Variant cases -- `clock`: [`subscription_clock`](#subscription_clock) - -- `fd_read`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -- `fd_write`: [`subscription_fd_readwrite`](#subscription_fd_readwrite) - -## `subscription`: `Record` -Subscription to an event. - -Size: 48 - -Alignment: 8 - -### Record members -- `userdata`: [`userdata`](#userdata) -User-provided value that is attached to the subscription in the -implementation and returned through [`event::userdata`](#event.userdata). - -Offset: 0 - -- `u`: [`subscription_u`](#subscription_u) -The type of the event to which to subscribe, and the contents of the subscription. - -Offset: 8 - -## `exitcode`: `u8` -Exit code generated by a program when exiting. - -Size: 1 - -Alignment: 1 - -### Constants -- `success` - -- `failure` - -## `riflags`: `Record` -Flags provided to `sock_recv`. - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_peek`: `bool` -Returns the message without removing it from the socket's receive queue. - -Bit: 0 - -- `recv_waitall`: `bool` -On byte-stream sockets, block until the full amount of data can be returned. - -Bit: 1 - -## `roflags`: `Record` -Flags returned by `sock_recv`. - -Size: 2 - -Alignment: 2 - -### Record members -- `recv_data_truncated`: `bool` -Returned by `sock_recv`: Message data has been truncated. - -Bit: 0 - -## `siflags`: `u16` -Flags provided to `sock_send`. As there are currently no flags -defined, it must be set to zero. - -Size: 2 - -Alignment: 2 - -## `sdflags`: `Record` -Which channels on a socket to shut down. - -Size: 1 - -Alignment: 1 - -### Record members -- `rd`: `bool` -Disables further receive operations. - -Bit: 0 - -- `wr`: `bool` -Disables further send operations. - -Bit: 1 - -## `preopentype`: `Variant` -Identifiers for preopened capabilities. - -Size: 1 - -Alignment: 1 - -### Variant cases -- `dir` -A pre-opened directory. - -## `prestat_dir`: `Record` -The contents of a [`prestat`](#prestat) when its type is [`preopentype::dir`](#preopentype.dir). - -Size: 4 - -Alignment: 4 - -### Record members -- `pr_name_len`: [`size`](#size) -The length of the directory name for use with `fd_prestat_dir_name`. - -Offset: 0 - -## `prestat`: `Variant` -Information about a pre-opened capability. - -Size: 8 - -Alignment: 4 - -### Variant Layout -- size: 8 -- align: 4 -- tag_size: 1 -### Variant cases -- `dir`: [`prestat_dir`](#prestat_dir) -When type is [`preopentype::dir`](#preopentype.dir): - -# Modules -## wasi_ephemeral_random -### Imports -#### Memory -### Functions - ---- - -#### `get(buf: Pointer, buf_len: size) -> Result<(), errno>` -Write high-quality random data into a buffer. -This function blocks when the implementation is unable to immediately -provide sufficient high-quality random data. -This function may execute slowly, so when large amounts of random data are -required, it's advisable to use this function to seed a pseudo-random -number generator, rather than to provide the random data directly. - -##### Params -- `buf`: `Pointer` -The buffer to fill with random data. - -- `buf_len`: [`size`](#size) - -##### Results -- `error`: `Result<(), errno>` - -###### Variant Layout -- size: 8 -- align: 4 -- tag_size: 4 -###### Variant cases -- `ok` - -- `err`: [`errno`](#errno) - diff --git a/proposals/random/standard/wasi-random/witx/random.witx b/proposals/random/standard/wasi-random/witx/random.witx deleted file mode 100644 index 41a2ef1c9..000000000 --- a/proposals/random/standard/wasi-random/witx/random.witx +++ /dev/null @@ -1,26 +0,0 @@ -;; WASI Random API. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -(use "typenames.witx") - -(module $wasi_ephemeral_random - ;;; Linear memory to be accessed by WASI functions that need it. - (import "memory" (memory)) - - ;;; Write high-quality random data into a buffer. - ;;; This function blocks when the implementation is unable to immediately - ;;; provide sufficient high-quality random data. - ;;; This function may execute slowly, so when large amounts of random data are - ;;; required, it's advisable to use this function to seed a pseudo-random - ;;; number generator, rather than to provide the random data directly. - (@interface func (export "get") - ;;; The buffer to fill with random data. - (param $buf (@witx pointer u8)) - (param $buf_len $size) - (result $error (expected (error $errno))) - ) -) diff --git a/proposals/random/standard/wasi-random/witx/typenames.witx b/proposals/random/standard/wasi-random/witx/typenames.witx deleted file mode 100644 index bbd6489df..000000000 --- a/proposals/random/standard/wasi-random/witx/typenames.witx +++ /dev/null @@ -1,708 +0,0 @@ -;; Type names used by low-level WASI interfaces. -;; -;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi). -;; -;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md) -;; for an explanation of what that means. - -;;; An array size. -;;; -;;; Note: This is similar to `size_t` in POSIX. -(typename $size (@witx usize)) - -;;; Non-negative file size or length of a region within a file. -(typename $filesize u64) - -;;; Timestamp in nanoseconds. -(typename $timestamp u64) - -;;; Identifiers for clocks. -(typename $clockid - (enum (@witx tag u32) - ;;; The clock measuring real time. Time value zero corresponds with - ;;; 1970-01-01T00:00:00Z. - $realtime - ;;; The store-wide monotonic clock, which is defined as a clock measuring - ;;; real time, whose value cannot be adjusted and which cannot have negative - ;;; clock jumps. The epoch of this clock is undefined. The absolute time - ;;; value of this clock therefore has no meaning. - $monotonic - ) -) - -;;; Error codes returned by functions. -;;; Not all of these error codes are returned by the functions provided by this -;;; API; some are used in higher-level library layers, and others are provided -;;; merely for alignment with POSIX. -(typename $errno - (enum (@witx tag u16) - ;;; No error occurred. System call completed successfully. - $success - ;;; Argument list too long. - $2big - ;;; Permission denied. - $access - ;;; Address in use. - $addrinuse - ;;; Address not available. - $addrnotavail - ;;; Address family not supported. - $afnosupport - ;;; Resource unavailable, or operation would block. - $again - ;;; Connection already in progress. - $already - ;;; Bad file descriptor. - $badf - ;;; Bad message. - $badmsg - ;;; Device or resource busy. - $busy - ;;; Operation canceled. - $canceled - ;;; No child processes. - $child - ;;; Connection aborted. - $connaborted - ;;; Connection refused. - $connrefused - ;;; Connection reset. - $connreset - ;;; Resource deadlock would occur. - $deadlk - ;;; Destination address required. - $destaddrreq - ;;; Mathematics argument out of domain of function. - $dom - ;;; Reserved. - $dquot - ;;; File exists. - $exist - ;;; Bad address. - $fault - ;;; File too large. - $fbig - ;;; Host is unreachable. - $hostunreach - ;;; Identifier removed. - $idrm - ;;; Illegal byte sequence. - $ilseq - ;;; Operation in progress. - $inprogress - ;;; Interrupted function. - $intr - ;;; Invalid argument. - $inval - ;;; I/O error. - $io - ;;; Socket is connected. - $isconn - ;;; Is a directory. - $isdir - ;;; Too many levels of symbolic links. - $loop - ;;; File descriptor value too large. - $mfile - ;;; Too many links. - $mlink - ;;; Message too large. - $msgsize - ;;; Reserved. - $multihop - ;;; Filename too long. - $nametoolong - ;;; Network is down. - $netdown - ;;; Connection aborted by network. - $netreset - ;;; Network unreachable. - $netunreach - ;;; Too many files open in system. - $nfile - ;;; No buffer space available. - $nobufs - ;;; No such device. - $nodev - ;;; No such file or directory. - $noent - ;;; Executable file format error. - $noexec - ;;; No locks available. - $nolck - ;;; Reserved. - $nolink - ;;; Not enough space. - $nomem - ;;; No message of the desired type. - $nomsg - ;;; Protocol not available. - $noprotoopt - ;;; No space left on device. - $nospc - ;;; Function not supported. - $nosys - ;;; The socket is not connected. - $notconn - ;;; Not a directory or a symbolic link to a directory. - $notdir - ;;; Directory not empty. - $notempty - ;;; State not recoverable. - $notrecoverable - ;;; Not a socket. - $notsock - ;;; Not supported, or operation not supported on socket. - $notsup - ;;; Inappropriate I/O control operation. - $notty - ;;; No such device or address. - $nxio - ;;; Value too large to be stored in data type. - $overflow - ;;; Previous owner died. - $ownerdead - ;;; Operation not permitted. - $perm - ;;; Broken pipe. - $pipe - ;;; Protocol error. - $proto - ;;; Protocol not supported. - $protonosupport - ;;; Protocol wrong type for socket. - $prototype - ;;; Result too large. - $range - ;;; Read-only file system. - $rofs - ;;; Invalid seek. - $spipe - ;;; No such process. - $srch - ;;; Reserved. - $stale - ;;; Connection timed out. - $timedout - ;;; Text file busy. - $txtbsy - ;;; Cross-device link. - $xdev - ;;; Extension: Capabilities insufficient. - $notcapable - ) -) - -;;; File descriptor rights, determining which actions may be performed. -(typename $rights - (flags (@witx repr u64) - ;;; The right to invoke `fd_datasync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::dsync`. - $fd_datasync - ;;; The right to invoke `fd_read` and `sock_recv`. - ;; - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pread`. - $fd_read - ;;; The right to invoke `fd_seek`. This flag implies `rights::fd_tell`. - $fd_seek - ;;; The right to invoke `fd_fdstat_set_flags`. - $fd_fdstat_set_flags - ;;; The right to invoke `fd_sync`. - ;; - ;;; If `path_open` is set, includes the right to invoke - ;;; `path_open` with `fdflags::rsync` and `fdflags::dsync`. - $fd_sync - ;;; The right to invoke `fd_seek` in such a way that the file offset - ;;; remains unaltered (i.e., `whence::cur` with offset zero), or to - ;;; invoke `fd_tell`. - $fd_tell - ;;; The right to invoke `fd_write` and `sock_send`. - ;;; If `rights::fd_seek` is set, includes the right to invoke `fd_pwrite`. - $fd_write - ;;; The right to invoke `fd_advise`. - $fd_advise - ;;; The right to invoke `fd_allocate`. - $fd_allocate - ;;; The right to invoke `path_create_directory`. - $path_create_directory - ;;; If `path_open` is set, the right to invoke `path_open` with `oflags::create`. - $path_create_file - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; source directory. - $path_link_source - ;;; The right to invoke `path_link` with the file descriptor as the - ;;; target directory. - $path_link_target - ;;; The right to invoke `path_open`. - $path_open - ;;; The right to invoke `fd_readdir`. - $fd_readdir - ;;; The right to invoke `path_readlink`. - $path_readlink - ;;; The right to invoke `path_rename` with the file descriptor as the source directory. - $path_rename_source - ;;; The right to invoke `path_rename` with the file descriptor as the target directory. - $path_rename_target - ;;; The right to invoke `path_filestat_get`. - $path_filestat_get - ;;; The right to change a file's size. - ;;; If `path_open` is set, includes the right to invoke `path_open` with `oflags::trunc`. - ;;; Note: there is no function named `path_filestat_set_size`. This follows POSIX design, - ;;; which only has `ftruncate` and does not provide `ftruncateat`. - ;;; While such function would be desirable from the API design perspective, there are virtually - ;;; no use cases for it since no code written for POSIX systems would use it. - ;;; Moreover, implementing it would require multiple syscalls, leading to inferior performance. - $path_filestat_set_size - ;;; The right to invoke `path_filestat_set_times`. - $path_filestat_set_times - ;;; The right to invoke `path_permissions_set`. - $path_permissions_set - ;;; The right to invoke `fd_filestat_get`. - $fd_filestat_get - ;;; The right to invoke `fd_filestat_set_size`. - $fd_filestat_set_size - ;;; The right to invoke `fd_filestat_set_times`. - $fd_filestat_set_times - ;;; The right to invoke `fd_permissions_set`. - $fd_permissions_set - ;;; The right to invoke `path_symlink`. - $path_symlink - ;;; The right to invoke `path_remove_directory`. - $path_remove_directory - ;;; The right to invoke `path_unlink_file`. - $path_unlink_file - ;;; If `rights::fd_read` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_read`. - ;;; If `rights::fd_write` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype::fd_write`. - $poll_fd_readwrite - ;;; The right to invoke `sock_shutdown`. - $sock_shutdown - ) -) - -;;; A file descriptor handle. -(typename $fd (handle)) - -;;; A region of memory for scatter/gather reads. -(typename $iovec - (record - ;;; The address of the buffer to be filled. - (field $buf (@witx pointer u8)) - ;;; The length of the buffer to be filled. - (field $buf_len $size) - ) -) - -;;; A region of memory for scatter/gather writes. -(typename $ciovec - (record - ;;; The address of the buffer to be written. - (field $buf (@witx const_pointer u8)) - ;;; The length of the buffer to be written. - (field $buf_len $size) - ) -) - -(typename $iovec_array (list $iovec)) -(typename $ciovec_array (list $ciovec)) - -;;; Relative offset within a file. -(typename $filedelta s64) - -;;; The position relative to which to set the offset of the file descriptor. -(typename $whence - (enum (@witx tag u8) - ;;; Seek relative to start-of-file. - $set - ;;; Seek relative to current position. - $cur - ;;; Seek relative to end-of-file. - $end - ) -) - -;;; A reference to the offset of a directory entry. -(typename $dircookie u64) - -;;; In an `fd_readdir` call, this value signifies the start of the directory. -(@witx const $dircookie $start 0) - -;;; The type for the `dirent::d_namlen` field of `dirent`. -(typename $dirnamlen u32) - -;;; File serial number that is unique within its file system. -(typename $inode u64) - -;;; The type of a file descriptor or file. -(typename $filetype - (enum (@witx tag u8) - ;;; The type of the file descriptor or file is unknown or is different from any of the other types specified. - $unknown - ;;; The file descriptor or file refers to a block device inode. - $block_device - ;;; The file descriptor or file refers to a character device inode. - $character_device - ;;; The file descriptor or file refers to a directory inode. - $directory - ;;; The file descriptor or file refers to a regular file inode. - $regular_file - ;;; The file descriptor or file refers to a datagram socket. - $socket_dgram - ;;; The file descriptor or file refers to a byte-stream socket. - $socket_stream - ;;; The file refers to a symbolic link inode. - $symbolic_link - ;;; The file descriptor or file refers to a FIFO. - $fifo - ) -) - -;;; A directory entry. -(typename $dirent - (record - ;;; The offset of the next directory entry stored in this directory. - (field $d_next $dircookie) - ;;; The serial number of the file referred to by this directory entry. - (field $d_ino $inode) - ;;; The type of the file referred to by this directory entry. - (field $d_type $filetype) - ;;; The length of the name of the directory entry. - (field $d_namlen $dirnamlen) - ) -) - -;;; File or memory access pattern advisory information. -(typename $advice - (enum (@witx tag u8) - ;;; The application has no advice to give on its behavior with respect to the specified data. - $normal - ;;; The application expects to access the specified data sequentially from lower offsets to higher offsets. - $sequential - ;;; The application expects to access the specified data in a random order. - $random - ;;; The application expects to access the specified data in the near future. - $willneed - ;;; The application expects that it will not access the specified data in the near future. - $dontneed - ;;; The application expects to access the specified data once and then not reuse it thereafter. - $noreuse - ) -) - -;;; File descriptor flags. -(typename $fdflags - (flags (@witx repr u16) - ;;; Append mode: Data written to the file is always appended to the file's end. - $append - ;;; Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. - $dsync - ;;; Non-blocking mode. - $nonblock - ;;; Synchronized read I/O operations. - $rsync - ;;; Write according to synchronized I/O file integrity completion. In - ;;; addition to synchronizing the data stored in the file, the implementation - ;;; may also synchronously update the file's metadata. - $sync - ) -) - -;;; File descriptor attributes. -(typename $fdstat - (record - ;;; File type. - (field $fs_filetype $filetype) - ;;; File descriptor flags. - (field $fs_flags $fdflags) - ;;; Rights that apply to this file descriptor. - (field $fs_rights_base $rights) - ;;; Maximum set of rights that may be installed on new file descriptors that - ;;; are created through this file descriptor, e.g., through `path_open`. - (field $fs_rights_inheriting $rights) - ) -) - -;;; Identifier for a device containing a file system. Can be used in combination -;;; with `inode` to uniquely identify a file or directory in the filesystem. -(typename $device u64) - -;;; Which file time attributes to adjust. -(typename $fstflags - (flags (@witx repr u16) - ;;; Adjust the last data access timestamp to the value stored in `filestat::atim`. - $atim - ;;; Adjust the last data access timestamp to the time of clock `clockid::realtime`. - $atim_now - ;;; Adjust the last data modification timestamp to the value stored in `filestat::mtim`. - $mtim - ;;; Adjust the last data modification timestamp to the time of clock `clockid::realtime`. - $mtim_now - ) -) - -;;; Flags determining the method of how paths are resolved. -(typename $lookupflags - (flags (@witx repr u32) - ;;; As long as the resolved path corresponds to a symbolic link, it is expanded. - $symlink_follow - ) -) - -;;; Open flags used by `path_open`. -(typename $oflags - (flags (@witx repr u16) - ;;; Create file if it does not exist. - $create - ;;; Fail if not a directory. - $directory - ;;; Fail if file already exists. - $excl - ;;; Truncate file to size 0. - $trunc - ) -) - -;;; Number of hard links to an inode. -(typename $linkcount u64) - -;;; File permissions. This represents the permissions associated with a -;;; file in a filesystem, and don't fully reflect all the conditions -;;; which determine whether a given WASI program can access the file. -(typename $permissions - (flags (@witx repr u8) - ;;; For files, permission to read the file. - ;;; For directories, permission to do `readdir` and access files - ;;; within the directory. - ;;; - ;;; Note: This is similar to the read bit being set on files, and the - ;;; read *and* execute bits being set on directories, in POSIX. - $read - - ;;; For files, permission to mutate the file. - ;;; For directories, permission to create, remove, and rename items - ;;; within the directory. - $write - - ;;; For files, permission to "execute" the file, using whatever - ;;; concept of "executing" the host filesystem has. - ;;; This flag is not valid for directories. - $execute - - ;;; For filesystems which have a concept of multiple "users", this flag - ;;; indicates that the file is only accessible by the effective "user" - ;;; that the WASI store uses to access the filesystem, and inaccessible - ;;; to other "users". - $private - ) -) - -;;; File attributes. -(typename $filestat - (record - ;;; Device ID of device containing the file. - (field $dev $device) - ;;; File serial number. - (field $ino $inode) - ;;; File type. - (field $filetype $filetype) - ;;; File permissions. - (field $permissions $permissions) - ;;; Number of hard links to the file. - (field $nlink $linkcount) - ;;; For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. - (field $size $filesize) - ;;; Last data access timestamp. - (field $atim $timestamp) - ;;; Last data modification timestamp. - (field $mtim $timestamp) - ;;; Last file status change timestamp. - (field $ctim $timestamp) - ) -) - -;;; User-provided value that may be attached to objects that is retained when -;;; extracted from the implementation. -(typename $userdata u64) - -;;; Type of a subscription to an event or its occurrence. -(typename $eventtype - (enum (@witx tag u8) - ;;; The time value of clock `subscription_clock::id` has - ;;; reached timestamp `subscription_clock::timeout`. - $clock - ;;; File descriptor `subscription_fd_readwrite::fd` has data - ;;; available for reading. This event always triggers for regular files. - $fd_read - ;;; File descriptor `subscription_fd_readwrite::fd` has capacity - ;;; available for writing. This event always triggers for regular files. - $fd_write - ) -) - -;;; The state of the file descriptor subscribed to with -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $eventrwflags - (flags (@witx repr u16) - ;;; The peer of this socket has closed or disconnected. - $fd_readwrite_hangup - ) -) - -;;; The contents of an `event` when type is `eventtype::fd_read` or -;;; `eventtype::fd_write`. -(typename $event_fd_readwrite - (record - ;;; The number of bytes available for reading or writing. - (field $nbytes $filesize) - ;;; The state of the file descriptor. - (field $flags $eventrwflags) - ) -) - -;;; The contents of an `event`. -(typename $event_u - (variant (@witx tag $eventtype) - (case $fd_read $event_fd_readwrite) - (case $fd_write $event_fd_readwrite) - (case $clock) - ) -) - -;;; An event that occurred. -(typename $event - (record - ;;; User-provided value that got attached to `subscription::userdata`. - (field $userdata $userdata) - ;;; If non-zero, an error that occurred while processing the subscription request. - (field $error $errno) - ;;; The type of the event that occurred, and the contents of the event - (field $u $event_u) - ) -) - -;;; Flags determining how to interpret the timestamp provided in -;;; `subscription_clock::timeout`. -(typename $subclockflags - (flags (@witx repr u16) - ;;; If set, treat the timestamp provided in - ;;; `subscription_clock::timeout` as an absolute timestamp of clock - ;;; `subscription_clock::id`. If clear, treat the timestamp - ;;; provided in `subscription_clock::timeout` relative to the - ;;; current time value of clock `subscription_clock::id`. - $subscription_clock_abstime - ) -) - -;;; The contents of a `subscription` when type is `eventtype::clock`. -(typename $subscription_clock - (record - ;;; The clock against which to compare the timestamp. - (field $id $clockid) - ;;; The absolute or relative timestamp. - (field $timeout $timestamp) - ;;; The amount of time that the implementation may wait additionally - ;;; to coalesce with other events. - (field $precision $timestamp) - ;;; Flags specifying whether the timeout is absolute or relative - (field $flags $subclockflags) - ) -) - -;;; The contents of a `subscription` when type is type is -;;; `eventtype::fd_read` or `eventtype::fd_write`. -(typename $subscription_fd_readwrite - (record - ;;; The file descriptor on which to wait for it to become ready for reading or writing. - (field $fd $fd) - ) -) - -;;; The contents of a `subscription`. -(typename $subscription_u - (union (@witx tag $eventtype) - $subscription_clock - $subscription_fd_readwrite - $subscription_fd_readwrite - ) -) - -;;; Subscription to an event. -(typename $subscription - (record - ;;; User-provided value that is attached to the subscription in the - ;;; implementation and returned through `event::userdata`. - (field $userdata $userdata) - ;;; The type of the event to which to subscribe, and the contents of the subscription. - (field $u $subscription_u) - ) -) - -;;; Exit code generated by a program when exiting. -(typename $exitcode u8) - -;;; Indicate the program exited successfully. -;;; -;;; Note: This is similar to `EXIT_SUCCESS` in POSIX. -(@witx const $exitcode $success 0) - -;;; Indicate the program exited unsuccessfully. -;;; -;;; Note: This is similar to `EXIT_FAILURE` in POSIX. -(@witx const $exitcode $failure 1) - -;;; Flags provided to `sock_recv`. -(typename $riflags - (flags (@witx repr u16) - ;;; Returns the message without removing it from the socket's receive queue. - $recv_peek - ;;; On byte-stream sockets, block until the full amount of data can be returned. - $recv_waitall - ) -) - -;;; Flags returned by `sock_recv`. -(typename $roflags - (flags (@witx repr u16) - ;;; Returned by `sock_recv`: Message data has been truncated. - $recv_data_truncated - ) -) - -;;; Flags provided to `sock_send`. As there are currently no flags -;;; defined, it must be set to zero. -(typename $siflags u16) - -;;; Which channels on a socket to shut down. -(typename $sdflags - (flags (@witx repr u8) - ;;; Disables further receive operations. - $rd - ;;; Disables further send operations. - $wr - ) -) - -;;; Identifiers for preopened capabilities. -(typename $preopentype - (enum (@witx tag u8) - ;;; A pre-opened directory. - $dir - ) -) - -;;; The contents of a `prestat` when its type is `preopentype::dir`. -(typename $prestat_dir - (record - ;;; The length of the directory name for use with `fd_prestat_dir_name`. - (field $pr_name_len $size) - ) -) - -;;; Information about a pre-opened capability. -(typename $prestat - (union (@witx tag $preopentype) - ;;; When type is `preopentype::dir`: - $prestat_dir - ) -) diff --git a/proposals/random/test/README.md b/proposals/random/test/README.md new file mode 100644 index 000000000..c274acd9d --- /dev/null +++ b/proposals/random/test/README.md @@ -0,0 +1,11 @@ +# Testing guidelines + +TK fill in testing guidelines + +## Installing the tools + +TK fill in instructions + +## Running the tests + +TK fill in instructions diff --git a/proposals/random/tools/repo_docs.sh b/proposals/random/tools/repo_docs.sh deleted file mode 100755 index 76d1462bc..000000000 --- a/proposals/random/tools/repo_docs.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -set -ex -cd $(dirname $(realpath $0))/witx -cargo run -p witx-cli -- docs $1 ../../phases/snapshot/witx/wasi_snapshot_preview1.witx --output ../../phases/snapshot/docs.md -cargo run -p witx-cli -- docs $1 ../../phases/old/snapshot_0/witx/wasi_unstable.witx --output ../../phases/old/snapshot_0/docs.md -cargo run -p witx-cli -- docs $1 \ - ../../phases/ephemeral/witx/wasi_ephemeral_args.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_clock.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_environ.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_fd.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_path.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_poll.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_proc.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_random.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_sched.witx \ - ../../phases/ephemeral/witx/wasi_ephemeral_sock.witx \ - --output ../../phases/ephemeral/docs.md - -for dir in ../../standard/*/witx; do - cargo run -p witx-cli -- docs $1 "$dir"/*.witx \ - --output "$dir"/../docs.md -done diff --git a/proposals/random/tools/witx/.gitignore b/proposals/random/tools/witx/.gitignore deleted file mode 100644 index a9d37c560..000000000 --- a/proposals/random/tools/witx/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target -Cargo.lock diff --git a/proposals/random/tools/witx/Cargo.toml b/proposals/random/tools/witx/Cargo.toml deleted file mode 100644 index 1dd39a8b1..000000000 --- a/proposals/random/tools/witx/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -[package] -name = "witx" -version = "0.9.0" -description = "Parse and validate witx file format" -homepage = "https://github.com/WebAssembly/WASI" -repository = "https://github.com/WebAssembly/WASI" -license = "Apache-2.0" -categories = ["wasm"] -keywords = ["webassembly", "wasm"] -authors = ["Pat Hickey ", "Alex Crichton "] -edition = "2018" - -[lib] -crate-type=["rlib"] - -[dependencies] -anyhow = "1" -log = "0.4" -thiserror = "1.0" -wast = { version = "33.0.0", default-features = false } - -[dev-dependencies] -rayon = "1.0" - -[[test]] -name = "witxt" -harness = false - -[workspace] -members = [ - "cli", -] diff --git a/proposals/random/tools/witx/LICENSE b/proposals/random/tools/witx/LICENSE deleted file mode 100644 index e061f56ab..000000000 --- a/proposals/random/tools/witx/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2019 WebAssembly Community Group participants - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/proposals/random/tools/witx/cli/Cargo.toml b/proposals/random/tools/witx/cli/Cargo.toml deleted file mode 100644 index 6f45ef3d9..000000000 --- a/proposals/random/tools/witx/cli/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "witx-cli" -version = "0.9.0" -description = "CLI for operating on witx file format" -homepage = "https://github.com/WebAssembly/WASI" -repository = "https://github.com/WebAssembly/WASI" -license = "Apache-2.0" -categories = ["wasm"] -keywords = ["webassembly", "wasm"] -authors = ["Pat Hickey ", "Alex Crichton "] -edition = "2018" - -[[bin]] -name = "witx" -path = "src/main.rs" - -[dependencies] -witx = { path = "../", version = "0.9.0" } -anyhow = "1" -log = "0.4" -thiserror = "1.0" -diff = "0.1.11" -pretty_env_logger = "0.4" -structopt = "0.3" -rayon = "1.0" diff --git a/proposals/random/tools/witx/cli/src/main.rs b/proposals/random/tools/witx/cli/src/main.rs deleted file mode 100644 index bdb1c6a9c..000000000 --- a/proposals/random/tools/witx/cli/src/main.rs +++ /dev/null @@ -1,268 +0,0 @@ -use anyhow::{anyhow, bail, Result}; -use std::fs::File; -use std::io::Write; -use std::path::{Path, PathBuf}; -use std::process; -use structopt::{clap::AppSettings, StructOpt}; -use witx::{load, Document, Documentation}; - -/// Validate and process witx files -#[derive(StructOpt, Debug)] -#[structopt( - name = "witx", - version = env!("CARGO_PKG_VERSION"), - global_settings = &[ - AppSettings::VersionlessSubcommands, - AppSettings::ColoredHelp - ] -)] -struct Args { - #[structopt(short = "v", long = "verbose")] - verbose: bool, - - #[structopt(subcommand)] - cmd: Command, -} - -#[derive(StructOpt, Debug)] -enum Command { - /// Output documentation - Docs { - /// Path to root of witx document - #[structopt(number_of_values = 1, value_name = "INPUT", parse(from_os_str))] - input: Vec, - /// Perform check that output matches witx documents - #[structopt(long = "check")] - check: bool, - /// Path to generated documentation in Markdown format - #[structopt( - short = "o", - long = "output", - value_name = "OUTPUT", - parse(from_os_str) - )] - output: Option, - }, - /// Examine differences between interfaces - Polyfill { - /// Path to root of witx document - #[structopt( - required = true, - number_of_values = 1, - value_name = "INPUT", - parse(from_os_str) - )] - input: Vec, - /// Path to root of witx document describing interface to polyfill - #[structopt( - required = true, - number_of_values = 1, - value_name = "OLDER_INTERFACE", - parse(from_os_str) - )] - older_interface: Vec, - /// Module to examine (use newname=oldname syntax if name is different - /// between new and old interfaces) - #[structopt( - short = "m", - long = "module_mapping", - required = true, - number_of_values = 1, - value_name = "NEWNAME=OLDNAME", - parse(try_from_str = parse_module_mapping) - )] - module_mapping: Vec<(String, String)>, - }, -} - -pub fn main() { - let args = Args::from_args(); - pretty_env_logger::init(); - let verbose = args.verbose; - - match args.cmd { - Command::Docs { - input, - check, - output, - } => { - let doc = load_witx(&input, "input", verbose); - if check { - let output = output.expect("output argument required in docs --check mode"); - if diff_against_filesystem(&doc.to_md(), &output).is_err() { - println!("Docs in tree are out-of-date with witx files. Re-run this executable with the following arguments to to re-generate:"); - println!( - "> witx docs {} --output {}", - input - .iter() - .map(|p| p.to_string_lossy().into_owned()) - .collect::>() - .join(" "), - output.to_string_lossy(), - ); - } - } else { - if let Some(output) = output { - write_docs(&doc, output) - } else { - println!("{}", doc.to_md()) - } - } - } - Command::Polyfill { - input, - older_interface, - module_mapping, - } => { - use std::{collections::HashMap, iter::FromIterator}; - use witx::polyfill::Polyfill; - - let doc = load_witx(&input, "input", verbose); - let older_doc = load_witx(&older_interface, "older_interface", verbose); - let module_mapping = HashMap::from_iter(module_mapping.into_iter()); - let polyfill = match Polyfill::new(&doc, &older_doc, &module_mapping) { - Ok(polyfill) => polyfill, - Err(e) => { - eprintln!("couldn't calculate polyfill"); - if verbose { - println!("{:?}", e); - } - process::exit(1); - } - }; - println!("{}", polyfill.to_md()); - if verbose { - println!("{:?}", polyfill); - } - } - } -} - -fn load_witx(input: &[PathBuf], field_name: &str, verbose: bool) -> Document { - match load(input) { - Ok(doc) => { - if verbose { - println!("{}: {:?}", field_name, doc); - } - doc - } - Err(e) => { - eprintln!("{}", e.report()); - if verbose { - println!("{:?}", e); - } - process::exit(1) - } - } -} - -fn write_docs>(document: &Document, path: P) { - let mut file = File::create(path.as_ref()).expect("create output file"); - file.write_all(document.to_md().as_bytes()) - .expect("write output file"); -} - -fn parse_module_mapping(m: &str) -> Result<(String, String)> { - let s: Vec<_> = m.split('=').collect(); - let (n, o) = match s.len() { - 1 => { - let mname = s - .get(0) - .ok_or(anyhow!("module name cannot be an empty string"))?; - (mname, mname) - } - 2 => { - let newname = s - .get(0) - .ok_or(anyhow!("new module name cannot be an empty string"))?; - let oldname = s - .get(1) - .ok_or(anyhow!("old module name cannot be an empty string"))?; - (newname, oldname) - } - _ => bail!("invalid module mapping: '{}'", m), - }; - Ok((n.to_string(), o.to_string())) -} - -fn dos2unix(s: &str) -> String { - let mut t = String::new(); - t.reserve(s.len()); - for c in s.chars() { - if c != '\r' { - t.push(c) - } - } - t -} - -fn diff_against_filesystem(expected: &str, path: &Path) -> Result<(), ()> { - let actual = std::fs::read_to_string(path) - .unwrap_or_else(|e| panic!("couldn't read {}: {:?}", Path::display(path), e)); - // Git may checkout the file with dos line endings on windows. Strip all \r: - let actual = dos2unix(&actual); - if &actual == expected { - return Ok(()); - } - - eprintln!("The following diff was found between the docs generated from .witx and the"); - eprintln!("source {:?} in the tree:", path); - eprintln!(); - - let mut expected_line = 1; - let mut actual_line = 1; - let mut separated = false; - let mut any_lines = false; - for diff in diff::lines(&expected, &actual) { - match diff { - diff::Result::Left(l) => { - eprintln!("line {}: -{}", expected_line, l); - expected_line += 1; - separated = false; - any_lines = true; - } - diff::Result::Both(_, _) => { - expected_line += 1; - actual_line += 1; - if !separated { - eprintln!("..."); - separated = true; - } - } - diff::Result::Right(r) => { - eprintln!("line {}: +{}", actual_line, r); - actual_line += 1; - separated = false; - any_lines = true; - } - } - } - - if !any_lines { - eprintln!(); - eprintln!( - "Somehow there was a diff with no lines differing. Lengths: {} and {}.", - expected.len(), - actual.len() - ); - for (index, (a, b)) in actual.chars().zip(expected.chars()).enumerate() { - if a != b { - eprintln!("char difference at index {}: '{}' != '{}'", index, a, b); - } - } - for (index, (a, b)) in actual.bytes().zip(expected.bytes()).enumerate() { - if a != b { - eprintln!("byte difference at index {}: b'{}' != b'{}'", index, a, b); - } - } - eprintln!(); - eprintln!("actual: {}", actual); - eprintln!(); - eprintln!("expected: {}", expected); - } - - eprintln!(); - eprintln!("To regenerate the files, run `tools/repo_docs.sh`."); - eprintln!(); - Err(()) -} diff --git a/proposals/random/tools/witx/src/abi.rs b/proposals/random/tools/witx/src/abi.rs deleted file mode 100644 index 0e1ca9cb4..000000000 --- a/proposals/random/tools/witx/src/abi.rs +++ /dev/null @@ -1,925 +0,0 @@ -//! Definition of the ABI of witx functions -//! -//! This module is intended to assist with code generators which are binding or -//! implementing APIs defined by `*.witx` files. THis module contains all -//! details necessary to implement the actual ABI of these functions so wasm -//! modules and hosts can communicate with one another. -//! -//! Each interface types function (a function defined in `*.witx`) currently has -//! a well-known wasm signature associated with it. There's then also a standard -//! way to convert from interface-types values (whose representation is defined -//! per-language) into this wasm API. This module is intended to assist with -//! this definition. -//! -//! Contained within are two primary functions, [`InterfaceFunc::call_wasm`] and -//! [`InterfaceFunc::call_interface`]. These functions implement the two ways to -//! interact with an interface types function, namely calling the raw wasm -//! version and calling the high-level version with interface types. These two -//! functions are fed a structure that implements [`Bindgen`]. An instance of -//! [`Bindgen`] receives instructions which are low-level implementation details -//! of how to convert to and from wasm types and interface types. Code -//! generators will need to implement the various instructions to support APIs. - -use crate::{ - BuiltinType, Id, IntRepr, InterfaceFunc, InterfaceFuncParam, NamedType, Type, TypeRef, -}; - -/// Enumerates wasm types used by interface types when lowering/lifting. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum WasmType { - I32, - I64, - F32, - F64, - // NOTE: we don't lower interface types to any other Wasm type, - // e.g. externref, so we don't need to define them here. -} - -impl From for WasmType { - fn from(i: IntRepr) -> WasmType { - match i { - IntRepr::U8 | IntRepr::U16 | IntRepr::U32 => WasmType::I32, - IntRepr::U64 => WasmType::I64, - } - } -} - -/// Possible ABIs for interface functions to have. -/// -/// Note that this is a stopgap until we have more of interface types. Interface -/// types functions do not have ABIs, they have APIs. For the meantime, however, -/// we mandate ABIs to ensure we can all talk to each other. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum Abi { - /// Only stable ABI currently, and is the historical WASI ABI since it was - /// first created. - /// - /// Note that this ABI is limited notably in its return values where it can - /// only return 0 results or one `Result` lookalike. - Preview1, -} - -// Helper macro for defining instructions without having to have tons of -// exhaustive `match` statements to update -macro_rules! def_instruction { - ( - $( #[$enum_attr:meta] )* - pub enum Instruction<'a> { - $( - $( #[$attr:meta] )* - $variant:ident $( { - $($field:ident : $field_ty:ty $(,)* )* - } )? - : - [$num_popped:expr] => [$num_pushed:expr], - )* - } - ) => { - $( #[$enum_attr] )* - pub enum Instruction<'a> { - $( - $( #[$attr] )* - $variant $( { - $( - $field : $field_ty, - )* - } )? , - )* - } - - impl Instruction<'_> { - /// How many operands does this instruction pop from the stack? - #[allow(unused_variables)] - pub fn operands_len(&self) -> usize { - match self { - $( - Self::$variant $( { - $( - $field, - )* - } )? => $num_popped, - )* - } - } - - /// How many results does this instruction push onto the stack? - #[allow(unused_variables)] - pub fn results_len(&self) -> usize { - match self { - $( - Self::$variant $( { - $( - $field, - )* - } )? => $num_pushed, - )* - } - } - } - }; -} - -def_instruction! { - #[derive(Debug)] - pub enum Instruction<'a> { - /// Acquires the specified parameter and places it on the stack. - /// Depending on the context this may refer to wasm parameters or - /// interface types parameters. - GetArg { nth: usize } : [0] => [1], - /// Takes the value off the top of the stack and writes it into linear - /// memory. Pushes the address in linear memory as an `i32`. - AddrOf : [1] => [1], - /// Converts an interface type `char` value to a 32-bit integer - /// representing the unicode scalar value. - I32FromChar : [1] => [1], - /// Converts an interface type `u64` value to a wasm `i64`. - I64FromU64 : [1] => [1], - /// Converts an interface type `s64` value to a wasm `i64`. - I64FromS64 : [1] => [1], - /// Converts an interface type `u32` value to a wasm `i32`. - I32FromU32 : [1] => [1], - /// Converts an interface type `s32` value to a wasm `i32`. - I32FromS32 : [1] => [1], - /// Converts a language-specific `usize` value to a wasm `i32`. - I32FromUsize : [1] => [1], - /// Converts an interface type `u16` value to a wasm `i32`. - I32FromU16 : [1] => [1], - /// Converts an interface type `s16` value to a wasm `i32`. - I32FromS16 : [1] => [1], - /// Converts an interface type `u8` value to a wasm `i32`. - I32FromU8 : [1] => [1], - /// Converts an interface type `s8` value to a wasm `i32`. - I32FromS8 : [1] => [1], - /// Converts a language-specific C `char` value to a wasm `i32`. - I32FromChar8 : [1] => [1], - /// Converts a language-specific pointer value to a wasm `i32`. - I32FromPointer : [1] => [1], - /// Converts a language-specific pointer value to a wasm `i32`. - I32FromConstPointer : [1] => [1], - /// Converts a language-specific handle value to a wasm `i32`. - I32FromHandle { ty: &'a NamedType } : [1] => [1], - /// Converts a language-specific record-of-bools to the packed - /// representation as an `i32`. - I32FromBitflags { ty: &'a NamedType } : [1] => [1], - /// Converts a language-specific record-of-bools to the packed - /// representation as an `i64`. - I64FromBitflags { ty: &'a NamedType } : [1] => [1], - /// Converts an interface type list into its pointer/length, pushing - /// them both on the stack. - ListPointerLength : [1] => [2], - /// Pops two `i32` values from the stack and creates a list from them of - /// the specified type. The first operand is the pointer in linear - /// memory to the start of the list and the second operand is the - /// length. - ListFromPointerLength { ty: &'a TypeRef } : [2] => [1], - /// Conversion an interface type `f32` value to a wasm `f32`. - /// - /// This may be a noop for some implementations, but it's here in case the - /// native language representation of `f32` is different than the wasm - /// representation of `f32`. - F32FromIf32 : [1] => [1], - /// Conversion an interface type `f64` value to a wasm `f64`. - /// - /// This may be a noop for some implementations, but it's here in case the - /// native language representation of `f64` is different than the wasm - /// representation of `f64`. - F64FromIf64 : [1] => [1], - - /// Represents a call to a raw WebAssembly API. The module/name are - /// provided inline as well as the types if necessary. - CallWasm { - module: &'a str, - name: &'a str, - params: &'a [WasmType], - results: &'a [WasmType], - } : [params.len()] => [results.len()], - - /// Same as `CallWasm`, except the dual where an interface is being - /// called rather than a raw wasm function. - CallInterface { - module: &'a str, - func: &'a InterfaceFunc, - } : [func.params.len()] => [func.results.len()], - - /// Converts a native wasm `i32` to an interface type `s8`. - /// - /// This will truncate the upper bits of the `i32`. - S8FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `u8`. - /// - /// This will truncate the upper bits of the `i32`. - U8FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `s16`. - /// - /// This will truncate the upper bits of the `i32`. - S16FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `u16`. - /// - /// This will truncate the upper bits of the `i32`. - U16FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `s32`. - S32FromI32 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `u32`. - U32FromI32 : [1] => [1], - /// Converts a native wasm `i64` to an interface type `s64`. - S64FromI64 : [1] => [1], - /// Converts a native wasm `i64` to an interface type `u64`. - U64FromI64 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `char`. - /// - /// It's safe to assume that the `i32` is indeed a valid unicode code point. - CharFromI32 : [1] => [1], - /// Converts a native wasm `i32` to a language-specific C `char`. - /// - /// This will truncate the upper bits of the `i32`. - Char8FromI32 : [1] => [1], - /// Converts a native wasm `i32` to a language-specific `usize`. - UsizeFromI32 : [1] => [1], - /// Converts a native wasm `f32` to an interface type `f32`. - If32FromF32 : [1] => [1], - /// Converts a native wasm `f64` to an interface type `f64`. - If64FromF64 : [1] => [1], - /// Converts a native wasm `i32` to an interface type `handle`. - HandleFromI32 { ty: &'a NamedType } : [1] => [1], - /// Converts a native wasm `i32` to a language-specific pointer. - PointerFromI32 { ty: &'a TypeRef }: [1] => [1], - /// Converts a native wasm `i32` to a language-specific pointer. - ConstPointerFromI32 { ty: &'a TypeRef } : [1] => [1], - /// Converts a native wasm `i32` to a language-specific record-of-bools. - BitflagsFromI32 { ty: &'a NamedType } : [1] => [1], - /// Converts a native wasm `i64` to a language-specific record-of-bools. - BitflagsFromI64 { ty: &'a NamedType } : [1] => [1], - /// Acquires the return pointer `n` and pushes an `i32` on the stack. - /// - /// Implementations of [`Bindgen`] may have [`Bindgen::allocate_space`] - /// called to reserve space in memory for the result of a computation to - /// get written. This instruction acquires a pointer to the space - /// reserved in `allocate_space`. - ReturnPointerGet { n: usize } : [0] => [1], - /// Loads the interface types value from an `i32` pointer popped from - /// the stack. - Load { ty: &'a NamedType } : [1] => [1], - /// Stores an interface types value into linear memory. The first - /// operand is the value to store and the second operand is the pointer - /// in linear memory to store it at. - Store { ty: &'a NamedType } : [2] => [0], - /// Pops a native wasm `i32` from the stack, as well as two blocks - /// internally from the code generator. - /// - /// If the value is 0 then the first "ok" block value should be used. - /// If the value is anything else then the second "err" block value - /// should be used, and the value is used as the error enum. - /// - /// Note that this is a special instruction matching the current ABI of - /// WASI and intentionally differs from the type-level grammar of - /// interface types results. - ResultLift : [1] => [1], - /// Pops a native interface value from the stack as well as two blocks - /// internally from the code generator. - /// - /// A `match` is performed on the value popped and the corresponding - /// block for ok/err is used depending on value. This pushes a single - /// `i32` onto the stack representing the error code for this result. - /// - /// Note that like `ResultLift` this is specialized to the current WASI - /// ABI. - ResultLower { - ok: Option<&'a TypeRef>, - err: Option<&'a TypeRef>, - } : [1] => [1], - /// Converts a native wasm `i32` to an interface type `enum` value. - /// - /// It's guaranteed that the interface type integer value is within - /// range for this enum's type. Additionally `ty` is guaranteed to be - /// enum-like as a `Variant` where all `case` arms have no associated - /// type with them. The purpose of this instruction is to convert a - /// native wasm integer into the enum type for the interface. - EnumLift { ty: &'a NamedType } : [1] => [1], - /// Converts an interface types enum value into a wasm `i32`. - EnumLower { ty: &'a NamedType } : [1] => [1], - /// Creates a tuple from the top `n` elements on the stack, pushing the - /// tuple onto the stack. - TupleLift { amt: usize } : [*amt] => [1], - /// Splits a tuple at the top of the stack into its `n` components, - /// pushing them all onto the stack. - TupleLower { amt: usize } : [1] => [*amt], - /// This is a special instruction specifically for the original ABI of - /// WASI. The raw return `i32` of a function is re-pushed onto the - /// stack for reuse. - ReuseReturn : [0] => [1], - /// Returns `amt` values on the stack. This is always the last - /// instruction. - Return { amt: usize } : [*amt] => [0], - /// This is a special instruction used at the entry of blocks used as - /// part of `ResultLower`, representing that the payload of that variant - /// being matched on should be pushed onto the stack. - VariantPayload : [0] => [1], - } -} - -impl Abi { - /// Validates the parameters/results are representable in this ABI. - /// - /// Returns an error string if they're not representable or returns `Ok` if - /// they're indeed representable. - pub fn validate( - &self, - _params: &[InterfaceFuncParam], - results: &[InterfaceFuncParam], - ) -> Result<(), String> { - assert_eq!(*self, Abi::Preview1); - match results.len() { - 0 => {} - 1 => match &**results[0].tref.type_() { - Type::Handle(_) | Type::Builtin(_) | Type::ConstPointer(_) | Type::Pointer(_) => {} - Type::Variant(v) => { - let (ok, err) = match v.as_expected() { - Some(pair) => pair, - None => return Err("invalid return type".to_string()), - }; - if let Some(ty) = ok { - match &**ty.type_() { - Type::Record(r) if r.is_tuple() => { - for member in r.members.iter() { - if !member.tref.named() { - return Err( - "only named types are allowed in results".to_string() - ); - } - } - } - _ => { - if !ty.named() { - return Err( - "only named types are allowed in results".to_string() - ); - } - } - } - } - if let Some(ty) = err { - if !ty.named() { - return Err("only named types are allowed in results".to_string()); - } - if let Type::Variant(v) = &**ty.type_() { - if v.is_enum() { - return Ok(()); - } - } - } - } - Type::Record(r) if r.bitflags_repr().is_some() => {} - Type::Record(_) | Type::List(_) => return Err("invalid return type".to_string()), - }, - _ => return Err("more than one result".to_string()), - } - Ok(()) - } -} - -/// Trait for language implementors to use to generate glue code between native -/// WebAssembly signatures and interface types signatures. -/// -/// This is used as an implementation detail in interpreting the ABI between -/// interface types and wasm types. Eventually this will be driven by interface -/// types adapters themselves, but for now the ABI of a function dictates what -/// instructions are fed in. -/// -/// Types implementing `Bindgen` are incrementally fed `Instruction` values to -/// generate code for. Instructions operate like a stack machine where each -/// instruction has a list of inputs and a list of outputs (provided by the -/// `emit` function). -pub trait Bindgen { - /// The intermediate type for fragments of code for this type. - /// - /// For most languages `String` is a suitable intermediate type. - type Operand; - - /// Emit code to implement the given instruction. - /// - /// Each operand is given in `operands` and can be popped off if ownership - /// is required. It's guaranteed that `operands` has the appropriate length - /// for the `inst` given, as specified with [`Instruction`]. - /// - /// Each result variable should be pushed onto `results`. This function must - /// push the appropriate number of results or binding generation will panic. - fn emit( - &mut self, - inst: &Instruction<'_>, - operands: &mut Vec, - results: &mut Vec, - ); - - /// Allocates temporary space in linear memory indexed by `slot` with enough - /// space to store `ty`. - /// - /// This is called when calling some wasm functions where a return pointer - /// is needed. - fn allocate_space(&mut self, slot: usize, ty: &NamedType); - - /// Enters a new block of code to generate code for. - /// - /// This is currently exclusively used for constructing variants. When a - /// variant is constructed a block here will be pushed for each case of a - /// variant, generating the code necessary to translate a variant case. - /// - /// Blocks are completed with `finish_block` below. It's expected that `emit` - /// will always push code (if necessary) into the "current block", which is - /// updated by calling this method and `finish_block` below. - fn push_block(&mut self); - - /// Indicates to the code generator that a block is completed, and the - /// `operand` specified was the resulting value of the block. - /// - /// This method will be used to compute the value of each arm of lifting a - /// variant. The `operand` will be `None` if the variant case didn't - /// actually have any type associated with it. Otherwise it will be `Some` - /// as the last value remaining on the stack representing the value - /// associated with a variant's `case`. - /// - /// It's expected that this will resume code generation in the previous - /// block before `push_block` was called. This must also save the results - /// of the current block internally for instructions like `ResultLift` to - /// use later. - fn finish_block(&mut self, operand: Option); -} - -impl InterfaceFunc { - /// Get the WebAssembly type signature for this interface function - /// - /// The first entry returned is the list of parameters and the second entry - /// is the list of results for the wasm function signature. - pub fn wasm_signature(&self) -> (Vec, Vec) { - assert_eq!(self.abi, Abi::Preview1); - let mut params = Vec::new(); - let mut results = Vec::new(); - for param in self.params.iter() { - match &**param.tref.type_() { - Type::Builtin(BuiltinType::S8) - | Type::Builtin(BuiltinType::U8 { .. }) - | Type::Builtin(BuiltinType::S16) - | Type::Builtin(BuiltinType::U16) - | Type::Builtin(BuiltinType::S32) - | Type::Builtin(BuiltinType::U32 { .. }) - | Type::Builtin(BuiltinType::Char) - | Type::Pointer(_) - | Type::ConstPointer(_) - | Type::Handle(_) - | Type::Variant(_) => params.push(WasmType::I32), - - Type::Record(r) => match r.bitflags_repr() { - Some(repr) => params.push(WasmType::from(repr)), - None => params.push(WasmType::I32), - }, - - Type::Builtin(BuiltinType::S64) | Type::Builtin(BuiltinType::U64) => { - params.push(WasmType::I64) - } - - Type::Builtin(BuiltinType::F32) => params.push(WasmType::F32), - Type::Builtin(BuiltinType::F64) => params.push(WasmType::F64), - - Type::List(_) => { - params.push(WasmType::I32); - params.push(WasmType::I32); - } - } - } - - for param in self.results.iter() { - match &**param.tref.type_() { - Type::Builtin(BuiltinType::S8) - | Type::Builtin(BuiltinType::U8 { .. }) - | Type::Builtin(BuiltinType::S16) - | Type::Builtin(BuiltinType::U16) - | Type::Builtin(BuiltinType::S32) - | Type::Builtin(BuiltinType::U32 { .. }) - | Type::Builtin(BuiltinType::Char) - | Type::Pointer(_) - | Type::ConstPointer(_) - | Type::Handle(_) => results.push(WasmType::I32), - - Type::Builtin(BuiltinType::S64) | Type::Builtin(BuiltinType::U64) => { - results.push(WasmType::I64) - } - - Type::Builtin(BuiltinType::F32) => results.push(WasmType::F32), - Type::Builtin(BuiltinType::F64) => results.push(WasmType::F64), - - Type::Record(r) => match r.bitflags_repr() { - Some(repr) => results.push(WasmType::from(repr)), - None => unreachable!(), - }, - Type::List(_) => unreachable!(), - - Type::Variant(v) => { - results.push(match v.tag_repr { - IntRepr::U64 => WasmType::I64, - IntRepr::U32 | IntRepr::U16 | IntRepr::U8 => WasmType::I32, - }); - if v.is_enum() { - continue; - } - // return pointer - if let Some(ty) = &v.cases[0].tref { - match &**ty.type_() { - Type::Record(r) if r.is_tuple() => { - for _ in 0..r.members.len() { - params.push(WasmType::I32); - } - } - _ => params.push(WasmType::I32), - } - } - } - } - } - (params, results) - } - - /// Generates an abstract sequence of instructions which represents this - /// function being adapted as an imported function. - /// - /// The instructions here, when executed, will emulate a language with - /// interface types calling the concrete wasm implementation. The parameters - /// for the returned instruction sequence are the language's own - /// interface-types parameters. One instruction in the instruction stream - /// will be a `Call` which represents calling the actual raw wasm function - /// signature. - /// - /// This function is useful, for example, if you're building a language - /// generator for WASI bindings. This will document how to translate - /// language-specific values into the wasm types to call a WASI function, - /// and it will also automatically convert the results of the WASI function - /// back to a language-specific value. - pub fn call_wasm(&self, module: &Id, bindgen: &mut impl Bindgen) { - assert_eq!(self.abi, Abi::Preview1); - Generator { - bindgen, - operands: vec![], - results: vec![], - stack: vec![], - } - .call_wasm(module, self); - } - - /// This is the dual of [`InterfaceFunc::call_wasm`], except that instead of - /// calling a wasm signature it generates code to come from a wasm signature - /// and call an interface types signature. - pub fn call_interface(&self, module: &Id, bindgen: &mut impl Bindgen) { - assert_eq!(self.abi, Abi::Preview1); - Generator { - bindgen, - operands: vec![], - results: vec![], - stack: vec![], - } - .call_interface(module, self); - } -} - -struct Generator<'a, B: Bindgen> { - bindgen: &'a mut B, - operands: Vec, - results: Vec, - stack: Vec, -} - -impl Generator<'_, B> { - fn call_wasm(&mut self, module: &Id, func: &InterfaceFunc) { - // Translate all parameters which are interface values by lowering them - // to their wasm types. - for (nth, param) in func.params.iter().enumerate() { - self.emit(&Instruction::GetArg { nth }); - self.lower(¶m.tref, None); - } - - // If necessary for our ABI, insert return pointers for any returned - // values through a result. - assert!(func.results.len() < 2); - if let Some(result) = func.results.get(0) { - self.prep_return_pointer(&result.tref.type_()); - } - - let (params, results) = func.wasm_signature(); - self.emit(&Instruction::CallWasm { - module: module.as_str(), - name: func.name.as_str(), - params: ¶ms, - results: &results, - }); - - // Lift the return value if one is present. - if let Some(result) = func.results.get(0) { - self.lift(&result.tref, true); - } - - self.emit(&Instruction::Return { - amt: func.results.len(), - }); - } - - fn call_interface(&mut self, module: &Id, func: &InterfaceFunc) { - // Lift all wasm parameters into interface types first. - // - // Note that consuming arguments is somewhat janky right now by manually - // giving lists a second argument for their length. In the future we'll - // probably want to refactor the `lift` function to internally know how - // to consume arguments. - let mut nth = 0; - for param in func.params.iter() { - self.emit(&Instruction::GetArg { nth }); - nth += 1; - if let Type::List(_) = &**param.tref.type_() { - self.emit(&Instruction::GetArg { nth }); - nth += 1; - } - self.lift(¶m.tref, false); - } - - self.emit(&Instruction::CallInterface { - module: module.as_str(), - func, - }); - - // Like above the current ABI only has at most one result, so lower it - // here if necessary. - if let Some(result) = func.results.get(0) { - self.lower(&result.tref, Some(&mut nth)); - } - - let (_params, results) = func.wasm_signature(); - self.emit(&Instruction::Return { amt: results.len() }); - } - - fn emit(&mut self, inst: &Instruction<'_>) { - self.operands.clear(); - self.results.clear(); - - let operands_len = inst.operands_len(); - assert!( - self.stack.len() >= operands_len, - "not enough operands on stack for {:?}", - inst - ); - self.operands - .extend(self.stack.drain((self.stack.len() - operands_len)..)); - self.results.reserve(inst.results_len()); - - self.bindgen - .emit(inst, &mut self.operands, &mut self.results); - - assert_eq!( - self.results.len(), - inst.results_len(), - "{:?} expected {} results, got {}", - inst, - inst.results_len(), - self.results.len() - ); - self.stack.extend(self.results.drain(..)); - } - - fn lower(&mut self, ty: &TypeRef, retptr: Option<&mut usize>) { - use Instruction::*; - match &**ty.type_() { - Type::Builtin(BuiltinType::S8) => self.emit(&I32FromS8), - Type::Builtin(BuiltinType::U8 { lang_c_char: true }) => self.emit(&I32FromChar8), - Type::Builtin(BuiltinType::U8 { lang_c_char: false }) => self.emit(&I32FromU8), - Type::Builtin(BuiltinType::S16) => self.emit(&I32FromS16), - Type::Builtin(BuiltinType::U16) => self.emit(&I32FromU16), - Type::Builtin(BuiltinType::S32) => self.emit(&I32FromS32), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: true, - }) => self.emit(&I32FromUsize), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: false, - }) => self.emit(&I32FromU32), - Type::Builtin(BuiltinType::S64) => self.emit(&I64FromS64), - Type::Builtin(BuiltinType::U64) => self.emit(&I64FromU64), - Type::Builtin(BuiltinType::Char) => self.emit(&I32FromChar), - Type::Pointer(_) => self.emit(&I32FromPointer), - Type::ConstPointer(_) => self.emit(&I32FromConstPointer), - Type::Handle(_) => self.emit(&I32FromHandle { - ty: match ty { - TypeRef::Name(ty) => ty, - _ => unreachable!(), - }, - }), - Type::Record(r) => { - let ty = match ty { - TypeRef::Name(ty) => ty, - _ => unreachable!(), - }; - match r.bitflags_repr() { - Some(IntRepr::U64) => self.emit(&I64FromBitflags { ty }), - Some(_) => self.emit(&I32FromBitflags { ty }), - None => self.emit(&AddrOf), - } - } - Type::Variant(v) => { - // Enum-like variants are simply lowered to their discriminant. - if v.is_enum() { - return self.emit(&EnumLower { - ty: match ty { - TypeRef::Name(n) => n, - _ => unreachable!(), - }, - }); - } - - // If this variant is in the return position then it's special, - // otherwise it's an argument and we just pass the address. - let retptr = match retptr { - Some(ptr) => ptr, - None => return self.emit(&AddrOf), - }; - - // For the return position we emit some blocks to lower the - // ok/err payloads which means that in the ok branch we're - // storing to out-params and in the err branch we're simply - // lowering the error enum. - // - // Note that this is all very specific to the current WASI ABI. - let (ok, err) = v.as_expected().unwrap(); - self.bindgen.push_block(); - if let Some(ok) = ok { - self.emit(&VariantPayload); - let store = |me: &mut Self, ty: &TypeRef, n| { - me.emit(&GetArg { nth: *retptr + n }); - match ty { - TypeRef::Name(ty) => me.emit(&Store { ty }), - _ => unreachable!(), - } - }; - match &**ok.type_() { - Type::Record(r) if r.is_tuple() => { - self.emit(&TupleLower { - amt: r.members.len(), - }); - // Note that `rev()` is used here due to the order - // that tuples are pushed onto the stack and how we - // consume the last item first from the stack. - for (i, member) in r.members.iter().enumerate().rev() { - store(self, &member.tref, i); - } - } - _ => store(self, ok, 0), - } - }; - self.bindgen.finish_block(None); - - self.bindgen.push_block(); - let err_expr = if let Some(ty) = err { - self.emit(&VariantPayload); - self.lower(ty, None); - Some(self.stack.pop().unwrap()) - } else { - None - }; - self.bindgen.finish_block(err_expr); - - self.emit(&ResultLower { ok, err }); - } - Type::Builtin(BuiltinType::F32) => self.emit(&F32FromIf32), - Type::Builtin(BuiltinType::F64) => self.emit(&F64FromIf64), - Type::List(_) => self.emit(&ListPointerLength), - } - } - - fn prep_return_pointer(&mut self, ty: &Type) { - // Return pointers are only needed for `Result`... - let variant = match ty { - Type::Variant(v) => v, - _ => return, - }; - // ... and only if `T` is actually present in `Result` - let ok = match &variant.cases[0].tref { - Some(t) => t, - None => return, - }; - - // Tuples have each individual item in a separate return pointer while - // all other types go through a singular return pointer. - let mut n = 0; - let mut prep = |ty: &TypeRef| { - match ty { - TypeRef::Name(ty) => self.bindgen.allocate_space(n, ty), - _ => unreachable!(), - } - self.emit(&Instruction::ReturnPointerGet { n }); - n += 1; - }; - match &**ok.type_() { - Type::Record(r) if r.is_tuple() => { - for member in r.members.iter() { - prep(&member.tref); - } - } - _ => prep(ok), - } - } - - // Note that in general everything in this function is the opposite of the - // `lower` function above. This is intentional and should be kept this way! - fn lift(&mut self, ty: &TypeRef, is_return: bool) { - use Instruction::*; - match &**ty.type_() { - Type::Builtin(BuiltinType::S8) => self.emit(&S8FromI32), - Type::Builtin(BuiltinType::U8 { lang_c_char: true }) => self.emit(&Char8FromI32), - Type::Builtin(BuiltinType::U8 { lang_c_char: false }) => self.emit(&U8FromI32), - Type::Builtin(BuiltinType::S16) => self.emit(&S16FromI32), - Type::Builtin(BuiltinType::U16) => self.emit(&U16FromI32), - Type::Builtin(BuiltinType::S32) => self.emit(&S32FromI32), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: true, - }) => self.emit(&UsizeFromI32), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: false, - }) => self.emit(&U32FromI32), - Type::Builtin(BuiltinType::S64) => self.emit(&S64FromI64), - Type::Builtin(BuiltinType::U64) => self.emit(&U64FromI64), - Type::Builtin(BuiltinType::Char) => self.emit(&CharFromI32), - Type::Builtin(BuiltinType::F32) => self.emit(&If32FromF32), - Type::Builtin(BuiltinType::F64) => self.emit(&If64FromF64), - Type::Pointer(ty) => self.emit(&PointerFromI32 { ty }), - Type::ConstPointer(ty) => self.emit(&ConstPointerFromI32 { ty }), - Type::Handle(_) => self.emit(&HandleFromI32 { - ty: match ty { - TypeRef::Name(ty) => ty, - _ => unreachable!(), - }, - }), - Type::Variant(v) => { - if v.is_enum() { - return self.emit(&EnumLift { - ty: match ty { - TypeRef::Name(n) => n, - _ => unreachable!(), - }, - }); - } else if !is_return { - return self.emit(&Load { - ty: match ty { - TypeRef::Name(n) => n, - _ => unreachable!(), - }, - }); - } - - let (ok, err) = v.as_expected().unwrap(); - self.bindgen.push_block(); - let ok_expr = if let Some(ok) = ok { - let mut n = 0; - let mut load = |ty: &TypeRef| { - self.emit(&ReturnPointerGet { n }); - n += 1; - match ty { - TypeRef::Name(ty) => self.emit(&Load { ty }), - _ => unreachable!(), - } - }; - match &**ok.type_() { - Type::Record(r) if r.is_tuple() => { - for member in r.members.iter() { - load(&member.tref); - } - self.emit(&TupleLift { - amt: r.members.len(), - }); - } - _ => load(ok), - } - Some(self.stack.pop().unwrap()) - } else { - None - }; - self.bindgen.finish_block(ok_expr); - - self.bindgen.push_block(); - let err_expr = if let Some(ty) = err { - self.emit(&ReuseReturn); - self.lift(ty, false); - Some(self.stack.pop().unwrap()) - } else { - None - }; - self.bindgen.finish_block(err_expr); - - self.emit(&ResultLift); - } - Type::Record(r) => { - let ty = match ty { - TypeRef::Name(ty) => ty, - _ => unreachable!(), - }; - match r.bitflags_repr() { - Some(IntRepr::U64) => self.emit(&BitflagsFromI64 { ty }), - Some(_) => self.emit(&BitflagsFromI32 { ty }), - None => self.emit(&Load { ty }), - } - } - Type::List(ty) => self.emit(&ListFromPointerLength { ty }), - } - } -} diff --git a/proposals/random/tools/witx/src/ast.rs b/proposals/random/tools/witx/src/ast.rs deleted file mode 100644 index ee985d302..000000000 --- a/proposals/random/tools/witx/src/ast.rs +++ /dev/null @@ -1,591 +0,0 @@ -use crate::Abi; -use std::collections::{HashMap, HashSet}; -use std::rc::{Rc, Weak}; - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Id(String); - -impl Id { - pub fn new>(s: S) -> Self { - Id(s.as_ref().to_string()) - } - pub fn as_str(&self) -> &str { - self.0.as_str() - } -} - -impl AsRef for Id { - fn as_ref(&self) -> &str { - self.0.as_ref() - } -} - -impl PartialEq<&str> for Id { - fn eq(&self, rhs: &&str) -> bool { - PartialEq::eq(self.as_ref(), *rhs) - } -} - -impl PartialEq for &str { - fn eq(&self, rhs: &Id) -> bool { - PartialEq::eq(*self, rhs.as_ref()) - } -} - -impl From<&str> for Id { - fn from(s: &str) -> Self { - Self::new(s) - } -} - -#[derive(Debug, Clone)] -pub struct Document { - definitions: Vec, - entries: HashMap, -} - -impl Document { - pub(crate) fn new(definitions: Vec, entries: HashMap) -> Self { - Document { - definitions, - entries, - } - } - pub fn typename(&self, name: &Id) -> Option> { - self.entries.get(name).and_then(|e| match e { - Entry::Typename(nt) => Some(nt.upgrade().expect("always possible to upgrade entry")), - _ => None, - }) - } - pub fn typenames<'a>(&'a self) -> impl Iterator> + 'a { - self.definitions.iter().filter_map(|d| match d { - Definition::Typename(nt) => Some(nt.clone()), - _ => None, - }) - } - /// All of the (unique) types used as "err" variant of results returned from - /// functions. - pub fn error_types<'a>(&'a self) -> impl Iterator + 'a { - let errors: HashSet = self - .modules() - .flat_map(|m| { - m.funcs() - .filter_map(|f| { - if f.results.len() == 1 { - Some(f.results[0].tref.type_().clone()) - } else { - None - } - }) - .filter_map(|t| match &*t { - Type::Variant(v) => { - let (_ok, err) = v.as_expected()?; - Some(err?.clone()) - } - _ => None, - }) - .collect::>() - }) - .collect(); - errors.into_iter() - } - pub fn module(&self, name: &Id) -> Option> { - self.entries.get(&name).and_then(|e| match e { - Entry::Module(m) => Some(m.upgrade().expect("always possible to upgrade entry")), - _ => None, - }) - } - pub fn modules<'a>(&'a self) -> impl Iterator> + 'a { - self.definitions.iter().filter_map(|d| match d { - Definition::Module(m) => Some(m.clone()), - _ => None, - }) - } - - pub fn constants<'a>(&'a self) -> impl Iterator + 'a { - self.definitions.iter().filter_map(|d| match d { - Definition::Constant(c) => Some(c), - _ => None, - }) - } -} - -impl PartialEq for Document { - fn eq(&self, rhs: &Document) -> bool { - // For equality, we don't care about the ordering of definitions, - // so we only need to check that the entries map is equal - self.entries == rhs.entries - } -} -impl Eq for Document {} - -impl std::hash::Hash for Document { - fn hash(&self, state: &mut H) { - std::hash::Hash::hash(&self.definitions, state); - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum Definition { - Typename(Rc), - Module(Rc), - Constant(Constant), -} - -#[derive(Debug, Clone)] -pub enum Entry { - Typename(Weak), - Module(Weak), -} - -impl Entry { - pub fn kind(&self) -> &'static str { - match self { - Entry::Typename { .. } => "typename", - Entry::Module { .. } => "module", - } - } -} - -impl PartialEq for Entry { - fn eq(&self, rhs: &Entry) -> bool { - match (self, rhs) { - (Entry::Typename(t), Entry::Typename(t_rhs)) => { - t.upgrade() - .expect("possible to upgrade entry when part of document") - == t_rhs - .upgrade() - .expect("possible to upgrade entry when part of document") - } - (Entry::Module(m), Entry::Module(m_rhs)) => { - m.upgrade() - .expect("possible to upgrade entry when part of document") - == m_rhs - .upgrade() - .expect("possible to upgrade entry when part of document") - } - _ => false, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum TypeRef { - Name(Rc), - Value(Rc), -} - -impl TypeRef { - pub fn type_(&self) -> &Rc { - match self { - TypeRef::Name(named) => named.type_(), - TypeRef::Value(v) => v, - } - } - - pub fn named(&self) -> bool { - match self { - TypeRef::Name(_) => true, - TypeRef::Value(_) => false, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct NamedType { - pub name: Id, - pub tref: TypeRef, - pub docs: String, -} - -impl NamedType { - pub fn type_(&self) -> &Rc { - self.tref.type_() - } -} - -/// Structure of all possible interface types. -/// -/// Note that this is intended to match the interface types proposal itself. -/// Currently this is relatively close to that with just a few `*.witx` -/// extensions for now. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum Type { - /// A structure with named field. - Record(RecordDatatype), - /// An enumeration where a value is one of a number of variants. - Variant(Variant), - /// A "handle" which is an un-forgeable reference. Today this is an `i32` - /// where a module can't forge and use integers it was not already given - /// access to. - Handle(HandleDatatype), - /// A list of a type, stored in linear memory. - /// - /// Note that lists of `char` are specialized to indicate strings. - List(TypeRef), - /// A `witx`-specific type representing a raw mutable pointer into linear - /// memory - Pointer(TypeRef), - /// A `witx`-specific type representing a raw const pointer into linear - /// memory - ConstPointer(TypeRef), - /// A builtin base-case type. - Builtin(BuiltinType), -} - -impl Type { - /// Returns a human-readable string to describe this type. - pub fn kind(&self) -> &'static str { - use Type::*; - match self { - Record(_) => "record", - Variant(_) => "variant", - Handle(_) => "handle", - List(_) => "list", - Pointer(_) => "pointer", - ConstPointer(_) => "constpointer", - Builtin(_) => "builtin", - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum BuiltinType { - /// This is a 32-bit unicode scalar value, not a code point. - /// - /// Same as the Rust language's `char` type. - Char, - /// An 8-bit unsigned integer. - U8 { - /// Indicates whether this type is intended to represent the `char` - /// type in the C language. The C `char` type is often unsigned, but - /// it's language-specific. At an interface-types level this is an - /// unsigned byte but binding generators may wish to bind this as the - /// language-specific representation for a C character instead. - /// - /// This is also currently used exclusively in conjunction with `@witx - /// pointer` to hint that it's pointing to unicode string data as well. - lang_c_char: bool, - }, - /// A 16-bit unsigned integer. - U16, - /// A 32-bit unsigned integer. - U32 { - /// Indicates that this 32-bit value should actually be considered a - /// pointer-like value in language bindings. At the interface types - /// layer this is always a 32-bit unsigned value, but binding - /// generators may wish to instead bind this as the equivalent of C's - /// `size_t` for convenience with other APIs. - /// - /// This allows witx authors to communicate the intent that the - /// argument or return-value is pointer-like. - lang_ptr_size: bool, - }, - /// A 64-bit unsigned integer. - U64, - /// An 8-bit signed integer - S8, - /// A 16-bit signed integer - S16, - /// A 32-bit signed integer - S32, - /// A 64-bit signed integer - S64, - /// A 32-bit floating point value. - F32, - /// A 64-bit floating point value. - F64, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum IntRepr { - U8, - U16, - U32, - U64, -} - -impl IntRepr { - pub fn to_builtin(&self) -> BuiltinType { - match self { - IntRepr::U8 => BuiltinType::U8 { lang_c_char: false }, - IntRepr::U16 => BuiltinType::U16, - IntRepr::U32 => BuiltinType::U32 { - lang_ptr_size: false, - }, - IntRepr::U64 => BuiltinType::U64, - } - } -} - -/// A struct-like value with named fields. -/// -/// Records map to `struct`s in most languages where this is a type with a -/// number of named fields that all have their own particular type. Field order -/// dictates layout in memory. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct RecordDatatype { - /// A hint as to what this record might be. - /// - /// Note that in the future this will only be a hint, not a control of the - /// actual representation itself. At this time though the record layout of - /// bitflags is different from other types. - pub kind: RecordKind, - - /// A list of named fields for this record. - pub members: Vec, -} - -/// Different kinds of records used for hinting various language-specific types. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum RecordKind { - /// A tuple where the name of all fields are consecutive integers starting - /// at "0". - Tuple, - /// A record where all fields are `bool`s. Currently represented as an - /// integer with bits set or not set. - Bitflags(IntRepr), - /// All other structures. - Other, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct RecordMember { - pub name: Id, - pub tref: TypeRef, - pub docs: String, -} - -impl RecordDatatype { - pub fn is_tuple(&self) -> bool { - match self.kind { - RecordKind::Tuple => true, - _ => false, - } - } - - pub fn bitflags_repr(&self) -> Option { - match self.kind { - RecordKind::Bitflags(i) => Some(i), - _ => None, - } - } -} - -/// A type which represents how values can be one of a set of possible cases. -/// -/// This type maps to an `enum` in languages like Rust, but doesn't have an -/// equivalent in languages like JS or C. The closest analog in C is a tagged -/// union, but a `Variant` is always consistent whereas a tagged union in C -/// could be mis-tagged or such. -/// -/// Variants are used to represent one of a possible set of types. For example -/// an enum-like variant, a result that is either success or failure, or even a -/// simple `bool`. Variants are primarily used heavily with various kinds of -/// shorthands in the `*.witx` format to represent idioms in languages. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Variant { - /// The bit representation of the width of this variant's tag when the - /// variant is stored in memory. - pub tag_repr: IntRepr, - /// The possible cases that values of this variant type can take. - pub cases: Vec, -} - -impl Variant { - /// If this variant looks like an `expected` shorthand, return the ok/err - /// types associated with this result. - /// - /// Only matches variants fo the form: - /// - /// ```text - /// (variant - /// (case "ok" ok?) - /// (case "err" err?)) - /// ``` - pub fn as_expected(&self) -> Option<(Option<&TypeRef>, Option<&TypeRef>)> { - if self.cases.len() != 2 { - return None; - } - if self.cases[0].name != "ok" { - return None; - } - if self.cases[1].name != "err" { - return None; - } - Some((self.cases[0].tref.as_ref(), self.cases[1].tref.as_ref())) - } - - /// Returns whether this variant type is "bool-like" meaning that it matches - /// this type: - /// - /// ```text - /// (variant - /// (case "false") - /// (case "true")) - /// ``` - pub fn is_bool(&self) -> bool { - self.cases.len() == 2 - && self.cases[0].name == "false" - && self.cases[1].name == "true" - && self.cases[0].tref.is_none() - && self.cases[1].tref.is_none() - } - - /// Returns whether this variant type is "enum-like" meaning that all of its - /// cases have no payload associated with them. - pub fn is_enum(&self) -> bool { - self.cases.iter().all(|c| c.tref.is_none()) - } -} - -/// One of a number of possible types that a `Variant` can take. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Case { - /// The name of this case and how to identify it. - pub name: Id, - /// An optional payload type for this case and data that can be associated - /// with it. - pub tref: Option, - /// Documentation for this case. - pub docs: String, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct HandleDatatype {} - -#[derive(Debug, Clone)] -pub struct Module { - pub name: Id, - definitions: Vec, - entries: HashMap, - pub docs: String, -} - -impl Module { - pub(crate) fn new( - name: Id, - definitions: Vec, - entries: HashMap, - docs: String, - ) -> Self { - Module { - name, - definitions, - entries, - docs, - } - } - pub fn import(&self, name: &Id) -> Option> { - self.entries.get(name).and_then(|e| match e { - ModuleEntry::Import(d) => Some(d.upgrade().expect("always possible to upgrade entry")), - _ => None, - }) - } - pub fn imports<'a>(&'a self) -> impl Iterator> + 'a { - self.definitions.iter().filter_map(|d| match d { - ModuleDefinition::Import(d) => Some(d.clone()), - _ => None, - }) - } - pub fn func(&self, name: &Id) -> Option> { - self.entries.get(name).and_then(|e| match e { - ModuleEntry::Func(d) => Some(d.upgrade().expect("always possible to upgrade entry")), - _ => None, - }) - } - pub fn funcs<'a>(&'a self) -> impl Iterator> + 'a { - self.definitions.iter().filter_map(|d| match d { - ModuleDefinition::Func(d) => Some(d.clone()), - _ => None, - }) - } -} - -impl PartialEq for Module { - fn eq(&self, rhs: &Module) -> bool { - // For equality, we don't care about the ordering of definitions, - // so we only need to check that the entries map is equal - self.name == rhs.name && self.entries == rhs.entries && self.docs == rhs.docs - } -} -impl Eq for Module {} - -impl std::hash::Hash for Module { - fn hash(&self, state: &mut H) { - std::hash::Hash::hash(&self.name, state); - std::hash::Hash::hash(&self.definitions, state); - std::hash::Hash::hash(&self.docs, state); - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum ModuleDefinition { - Import(Rc), - Func(Rc), -} - -#[derive(Debug, Clone)] -pub enum ModuleEntry { - Import(Weak), - Func(Weak), -} - -impl PartialEq for ModuleEntry { - fn eq(&self, rhs: &ModuleEntry) -> bool { - match (self, rhs) { - (ModuleEntry::Import(i), ModuleEntry::Import(i_rhs)) => { - i.upgrade() - .expect("always possible to upgrade moduleentry when part of module") - == i_rhs - .upgrade() - .expect("always possible to upgrade moduleentry when part of module") - } - (ModuleEntry::Func(i), ModuleEntry::Func(i_rhs)) => { - i.upgrade() - .expect("always possible to upgrade moduleentry when part of module") - == i_rhs - .upgrade() - .expect("always possible to upgrade moduleentry when part of module") - } - _ => false, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ModuleImport { - pub name: Id, - pub variant: ModuleImportVariant, - pub docs: String, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum ModuleImportVariant { - Memory, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct InterfaceFunc { - pub abi: Abi, - pub name: Id, - pub params: Vec, - pub results: Vec, - pub noreturn: bool, - pub docs: String, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct InterfaceFuncParam { - pub name: Id, - pub tref: TypeRef, - pub docs: String, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Constant { - pub ty: Id, - pub name: Id, - pub value: u64, - pub docs: String, -} diff --git a/proposals/random/tools/witx/src/docs/ast.rs b/proposals/random/tools/witx/src/docs/ast.rs deleted file mode 100644 index a295a6756..000000000 --- a/proposals/random/tools/witx/src/docs/ast.rs +++ /dev/null @@ -1,503 +0,0 @@ -use super::{ - md::{MdFunc, MdHeading, MdNamedType, MdNodeRef, MdSection, ToMarkdown}, - Documentation, -}; -use crate::{ - ast::*, - layout::Layout, - polyfill::{FuncPolyfill, ModulePolyfill, ParamPolyfill, Polyfill, TypePolyfill}, - RepEquality, -}; -use std::collections::HashMap; - -fn heading_from_node(node: &MdNodeRef, levels_down: usize) -> MdHeading { - MdHeading::new_header(node.borrow().ancestors().len() + levels_down) -} - -impl ToMarkdown for Document { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - let types = node.new_child(MdSection::new(heading, "Types")); - - let mut constants_by_name = HashMap::new(); - for c in self.constants() { - constants_by_name.entry(&c.ty).or_insert(Vec::new()).push(c); - } - - for d in self.typenames() { - let name = d.name.as_str(); - let child = types.new_child(MdNamedType::new( - heading.new_level_down(), - name, - name, - format!( - "{}\nSize: {}\n\nAlignment: {}\n", - &d.docs, - &d.mem_size(), - &d.mem_align() - ) - .as_str(), - )); - if let Some(constants) = constants_by_name.remove(&d.name) { - let heading = heading_from_node(&child, 1); - child.new_child(MdSection::new(heading, "Constants")); - for constant in constants { - child.new_child(MdNamedType::new( - MdHeading::new_bullet(), - format!("{}.{}", name, constant.name.as_str()).as_str(), - constant.name.as_str(), - &constant.docs, - )); - } - } - d.generate(child.clone()); - } - - let modules = node.new_child(MdSection::new(heading, "Modules")); - for d in self.modules() { - let mut content = MdSection::new(heading.new_level_down(), d.name.as_str()); - content.id = Some(d.name.as_str().to_owned()); - let child = modules.new_child(content); - d.generate(child.clone()); - } - - assert!(constants_by_name.is_empty()); - } -} - -impl ToMarkdown for TypeRef { - fn generate(&self, node: MdNodeRef) { - match self { - TypeRef::Value(v) => { - v.generate(node.clone()); - node.content_ref_mut::().ty = Some(format!("`{}`", self.type_name())); - } - TypeRef::Name(n) => { - node.content_ref_mut::().ty = - Some(format!("[`{0}`](#{0})", n.name.as_str().to_owned())); - } - } - } -} - -impl ToMarkdown for NamedType { - fn generate(&self, node: MdNodeRef) { - self.tref.generate(node.clone()); - } -} - -impl ToMarkdown for Type { - fn generate(&self, node: MdNodeRef) { - match self { - Self::Record(a) => a.generate(node.clone()), - Self::Variant(a) => a.generate(node.clone()), - Self::Handle(a) => a.generate(node.clone()), - Self::List(_) => {} - Self::Pointer(_) => {} - Self::ConstPointer(_) => {} - Self::Builtin(_) => {} - } - } -} - -impl ToMarkdown for RecordDatatype { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Record members")); - - for member_layout in &self.member_layout() { - let member = member_layout.member; - let offset = member_layout.offset; - let name = member.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let (div, offset_desc) = if self.bitflags_repr().is_some() { - (4, "Bit") - } else { - (1, "Offset") - }; - let n = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - format!("{}\n{}: {}\n", &member.docs, offset_desc, offset / div).as_str(), - )); - member.tref.generate(n.clone()); - } - } -} - -impl ToMarkdown for Variant { - fn generate(&self, node: MdNodeRef) { - if self.is_bool() { - return; - } - if self.cases.iter().any(|c| c.tref.is_some()) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Variant Layout")); - - let whole = self.mem_size_align(); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("size: {}", whole.size), - )); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("align: {}", whole.align), - )); - - let tag = self.tag_repr.mem_size_align(); - node.new_child(MdSection::new( - MdHeading::new_bullet(), - format!("tag_size: {}", tag.size), - )); - } - - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Variant cases")); - - for case in self.cases.iter() { - let name = case.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let n = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - &case.docs, - )); - if let Some(ty) = &case.tref { - ty.generate(n.clone()); - } - } - } -} - -impl ToMarkdown for HandleDatatype { - fn generate(&self, node: MdNodeRef) { - // TODO this needs more work - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Supertypes")); - } -} - -impl ToMarkdown for Module { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - let imports = node.new_child(MdSection::new(heading, "Imports")); - for import in self.imports() { - let child = imports.new_child(MdSection::new(heading.new_level_down(), "")); - import.generate(child.clone()); - } - - let funcs = node.new_child(MdSection::new(heading, "Functions")); - for func in self.funcs() { - let name = func.name.as_str(); - let child = funcs.new_child(MdFunc::new( - heading.new_level_down(), - name, - name, - &func.docs, - )); - func.generate(child.clone()); - } - } -} - -impl ToMarkdown for ModuleImport { - fn generate(&self, node: MdNodeRef) { - match self.variant { - ModuleImportVariant::Memory => { - node.content_ref_mut::().title = "Memory".to_owned(); - } - } - } -} - -impl ToMarkdown for InterfaceFunc { - fn generate(&self, node: MdNodeRef) { - let heading = heading_from_node(&node, 1); - node.new_child(MdSection::new(heading, "Params")); - for param in &self.params { - let name = param.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let child = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - param.name.as_str(), - )); - param.generate(child.clone()); - // TODO should this be expanded recursively instead of using flattened type names? - node.content_ref_mut::() - .inputs - .push((param.name.as_str().to_owned(), param.tref.type_name())); - } - - node.new_child(MdSection::new(heading, "Results")); - for result in &self.results { - let name = result.name.as_str(); - let id = if let Some(id) = node.any_ref().id() { - format!("{}.{}", id, name) - } else { - name.to_owned() - }; - let child = node.new_child(MdNamedType::new( - MdHeading::new_bullet(), - id.as_str(), - name, - result.name.as_str(), - )); - result.generate(child.clone()); - // TODO should this be expanded recursively instead of using flattened type names? - node.content_ref_mut::() - .outputs - .push(result.tref.type_name()); - } - } -} - -impl ToMarkdown for InterfaceFuncParam { - fn generate(&self, node: MdNodeRef) { - self.tref.generate(node.clone()); - node.content_ref_mut::().docs = self.docs.clone(); - } -} - -impl BuiltinType { - pub fn type_name(&self) -> &'static str { - match self { - BuiltinType::Char => "char", - BuiltinType::U8 { .. } => "u8", - BuiltinType::U16 => "u16", - BuiltinType::U32 { - lang_ptr_size: false, - } => "u32", - BuiltinType::U32 { - lang_ptr_size: true, - } => "usize", - BuiltinType::U64 => "u64", - BuiltinType::S8 => "s8", - BuiltinType::S16 => "s16", - BuiltinType::S32 => "s32", - BuiltinType::S64 => "s64", - BuiltinType::F32 => "f32", - BuiltinType::F64 => "f64", - } - } -} - -impl TypeRef { - pub fn type_name(&self) -> String { - match self { - TypeRef::Name(n) => n.name.as_str().to_string(), - TypeRef::Value(v) => match &**v { - Type::List(a) => match &**a.type_() { - Type::Builtin(BuiltinType::Char) => "string".to_string(), - _ => format!("List<{}>", a.type_name()), - }, - Type::Pointer(p) => format!("Pointer<{}>", p.type_name()), - Type::ConstPointer(p) => format!("ConstPointer<{}>", p.type_name()), - Type::Builtin(b) => b.type_name().to_string(), - Type::Record(RecordDatatype { - kind: RecordKind::Tuple, - members, - }) => { - let mut ret = "(".to_string(); - for (i, member) in members.iter().enumerate() { - if i > 0 { - ret.push_str(", "); - } - ret.push_str(&member.tref.type_name()); - } - ret.push_str(")"); - ret - } - Type::Record { .. } => { - format!("Record") - } - Type::Handle { .. } => { - format!("Handle") - } - Type::Variant(v) => { - if let Some((ok, err)) = v.as_expected() { - let ok = match ok { - Some(ty) => ty.type_name(), - None => "()".to_string(), - }; - let err = match err { - Some(ty) => ty.type_name(), - None => "()".to_string(), - }; - format!("Result<{}, {}>", ok, err) - } else if v.is_bool() { - format!("bool") - } else { - format!("Variant") - } - } - }, - } - } -} - -// TODO -// Generate Markdown tree for the polyfill -impl Documentation for Polyfill { - fn to_md(&self) -> String { - let module_docs = self - .modules - .iter() - .map(|m| m.to_md()) - .collect::>() - .join("\n"); - let type_docs = self - .type_polyfills() - .iter() - .filter_map(|t| { - if t.repeq() == RepEquality::Eq { - None - } else { - Some(t.to_md()) - } - }) - .collect::>() - .join("\n"); - format!( - "# Modules\n{}\n# Type Conversions\n{}\n", - module_docs, type_docs - ) - } -} - -impl Documentation for ModulePolyfill { - fn to_md(&self) -> String { - format!( - "## `{}` in terms of `{}`\n{}", - self.new.name.as_str(), - self.old.name.as_str(), - self.funcs - .iter() - .map(|f| f.to_md()) - .collect::>() - .join("\n"), - ) - } -} - -impl Documentation for FuncPolyfill { - fn to_md(&self) -> String { - if self.full_compat() { - format!("* `{}`: full compatibility", self.new.name.as_str()) - } else { - let name = if self.new.name != self.old.name { - format!( - "* `{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("* `{}`", self.new.name.as_str()) - }; - let mut contents = Vec::new(); - for p in self.mapped_params.iter() { - contents.push(if !p.full_compat() { - format!("param {}", p.to_md()) - } else { - format!("param `{}`: compatible", p.new.name.as_str()) - }) - } - for u in self.unknown_params.iter() { - contents.push(format!( - "{} param `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - for r in self.mapped_results.iter() { - contents.push(if !r.full_compat() { - format!("result {}", r.to_md()) - } else { - format!("result `{}`: compatible", r.new.name.as_str()) - }) - } - for u in self.unknown_results.iter() { - contents.push(format!( - "{} result `{}`: no corresponding result!", - u.which(), - u.param().name.as_str() - )) - } - let contents = if contents.is_empty() { - String::new() - } else { - format!(":\n - {}", contents.join("\n - ")) - }; - format!("{}{}", name, contents) - } - } -} - -impl Documentation for ParamPolyfill { - fn to_md(&self) -> String { - let name = if self.new.name != self.old.name { - format!( - "`{}` => `{}`", - self.old.name.as_str(), - self.new.name.as_str() - ) - } else { - format!("`{}`", self.new.name.as_str()) - }; - let repr = match self.repeq() { - RepEquality::Eq => "compatible types".to_string(), - RepEquality::Superset => format!( - "`{}` is superset-compatible with `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - RepEquality::NotEq => format!( - "`{}` is incompatible with new `{}`", - self.old.tref.type_name(), - self.new.tref.type_name() - ), - }; - format!("{}: {}", name, repr) - } -} - -impl Documentation for TypePolyfill { - fn to_md(&self) -> String { - fn repeq_name(r: RepEquality) -> &'static str { - match r { - RepEquality::Eq => ": compatible", - RepEquality::Superset => ": superset", - RepEquality::NotEq => "", - } - } - match self { - TypePolyfill::OldToNew(o, n) => format!( - "* old `{}` => new `{}`{}", - o.type_name(), - n.type_name(), - repeq_name(self.repeq()) - ), - TypePolyfill::NewToOld(n, o) => format!( - "* new `{}` => old `{}`{}", - n.type_name(), - o.type_name(), - repeq_name(self.repeq()) - ), - } - } -} diff --git a/proposals/random/tools/witx/src/docs/md.rs b/proposals/random/tools/witx/src/docs/md.rs deleted file mode 100644 index 569b31837..000000000 --- a/proposals/random/tools/witx/src/docs/md.rs +++ /dev/null @@ -1,480 +0,0 @@ -use std::{ - any::Any, - cell::{self, RefCell}, - fmt, - rc::{Rc, Weak}, -}; - -/// Helper trait which simplifies generation of the Markdown document represented -/// as a tree of `MdNodeRef`s. -pub(super) trait ToMarkdown { - /// Drives the generation of the `MdNodeRef` tree by either mutating - /// the outer (parent) `MdNodeRef`, shared reference to the `MdNode` `node`, - /// or spawning new child `MdNodeRef` references to nodes. - fn generate(&self, node: MdNodeRef); -} - -/// Interface required for any "content" that is expected to be generated into a -/// Markdown valid format, hence the constraint of `fmt::Display`. -/// -/// In essence, any AST element that is meant to be rendered into Markdown, should -/// define a type implementing this trait. -pub(super) trait MdElement: fmt::Display + fmt::Debug + 'static { - /// Returns `Some(id)` of this `MdElement`. Here `id` is synonym for a Markdown actionable - /// link. - fn id(&self) -> Option<&str>; - - /// Returns `Some(docs)`, the "docs" of this `MdElement`. - fn docs(&self) -> Option<&str>; - - /// Sets `docs`, the "docs" of this `MdElement`. - fn set_docs(&mut self, docs: &str); - - fn as_any(&self) -> &dyn Any; - fn as_any_mut(&mut self) -> &mut dyn Any; -} - -/// A Markdown node containing: -/// * the Markdown renderable `content`, -/// * a weak reference to the `parent` `MdNode` (if any), and -/// * children `MdNodeRef`s -/// -/// `content` is expected to implement the `MdElement` trait. -#[derive(Debug)] -pub(super) struct MdNode { - content: Box, - parent: Option>>, - children: Vec, -} - -/// Helper function for walking the tree up from some starting `MdNode`, all the way up -/// to the root of the tree. -fn walk_ancestors(parent: Option<&Weak>>, cb: &mut impl FnMut(MdNodeRef)) { - if let Some(parent) = parent.and_then(|x| x.upgrade()) { - cb(parent.clone().into()); - walk_ancestors(parent.borrow().parent.as_ref(), cb) - } -} - -impl MdNode { - fn new(item: T) -> Self { - Self { - content: Box::new(item), - parent: None, - children: vec![], - } - } - - /// Returns all ancestors of this `MdNode` all the way to the tree's root. - pub fn ancestors(&self) -> Vec { - let mut ancestors = Vec::new(); - walk_ancestors(self.parent.as_ref(), &mut |parent| ancestors.push(parent)); - ancestors - } - - /// Returns all children of this `MdNode` in a BFS order. - pub fn children(&self) -> Vec { - let mut children = self.children.clone(); - for child in &self.children { - children.append(&mut child.borrow().children()); - } - children - } -} - -impl fmt::Display for MdNode { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.content.fmt(f)?; - - for child in &self.children { - child.fmt(f)?; - } - - Ok(()) - } -} - -/// Helper struct for storing a shared mutable reference to `MdNode`. -#[derive(Debug)] -pub(super) struct MdNodeRef(Rc>); - -impl MdNodeRef { - pub fn new(item: T) -> Self { - Self(Rc::new(RefCell::new(MdNode::new(item)))) - } - - /// Spawns new `MdNode` child node, automatically wrapping it in a - /// `MdNodeRef` and creating a weak link from child to itself. - pub fn new_child(&self, item: T) -> Self { - let mut child_node = MdNode::new(item); - child_node.parent = Some(Rc::downgrade(&self.0)); - let child_ref = Self(Rc::new(RefCell::new(child_node))); - self.borrow_mut().children.push(child_ref.clone()); - child_ref - } - - pub fn borrow(&self) -> cell::Ref { - self.0.borrow() - } - - pub fn borrow_mut(&self) -> cell::RefMut { - self.0.borrow_mut() - } - - /// Returns an immutable reference to `MdNode`'s `content` as-is, that - /// is as some type implementing the `MdElement` trait. - pub fn any_ref(&self) -> cell::Ref> { - cell::Ref::map(self.borrow(), |b| &b.content) - } - - /// Returns a mutable reference to `MdNode`'s `content` as-is, that - /// is as some type implementing the `MdElement` trait. - pub fn any_ref_mut(&self) -> cell::RefMut> { - cell::RefMut::map(self.borrow_mut(), |b| &mut b.content) - } - - /// Returns a mutable reference to `MdNode`'s `content` cast to some type - /// `T` which implements `MdElement` trait. - /// - /// Panics if `content` cannot be downcast to `T`. - pub fn content_ref_mut(&self) -> cell::RefMut { - cell::RefMut::map(self.borrow_mut(), |b| { - let r = b.content.as_any_mut(); - r.downcast_mut::().expect("reference is not T type") - }) - } -} - -impl Clone for MdNodeRef { - fn clone(&self) -> Self { - Self(self.0.clone()) - } -} - -impl From>> for MdNodeRef { - fn from(node: Rc>) -> Self { - Self(node) - } -} - -impl fmt::Display for MdNodeRef { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.borrow().fmt(f) - } -} - -/// Record representing the Markdown tree's root. -/// -/// Doesn't render to anything. -#[derive(Debug, Default)] -pub(super) struct MdRoot; - -impl MdElement for MdRoot { - fn id(&self) -> Option<&str> { - None - } - - fn docs(&self) -> Option<&str> { - None - } - - fn set_docs(&mut self, _: &str) {} - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } -} - -impl fmt::Display for MdRoot { - fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { - Ok(()) - } -} - -/// Helper enum representing either a Markdown header "#" nested at some -/// `level` down the tree, or a bullet "-" in a list which is idempotent -/// to changing the nesting level. -#[derive(Debug, Clone, Copy)] -pub(super) enum MdHeading { - Header { level: usize }, - Bullet, -} - -impl MdHeading { - /// Creates new instance of `MdHeading::Header` variant nested at some - /// `level` down the Markdown tree. - pub fn new_header(level: usize) -> Self { - MdHeading::Header { level } - } - - /// Creates new instance of `MdHeading::Bullet` variant. - pub fn new_bullet() -> Self { - MdHeading::Bullet - } - - /// Copies `MdHeading` and if `MdHeading::Header`, pushes it down one - /// level in the Markdown tree by incrementing `level`. - pub fn new_level_down(&self) -> Self { - let mut copy = *self; - if let Self::Header { ref mut level } = &mut copy { - *level += 1; - } - copy - } -} - -impl fmt::Display for MdHeading { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let as_string = match self { - Self::Header { level } => "#".repeat(*level), - Self::Bullet => "-".to_owned(), - }; - f.write_str(&as_string) - } -} - -/// Record representing a Markdown section without any `docs`, consisting -/// of only a `header` (e.g., "###"), maybe some referencable `id` (i.e., -/// a Markdown link), and some `title`. -/// -/// Example rendering: -/// -/// ### Typenames -/// -#[derive(Debug)] -pub(super) struct MdSection { - pub heading: MdHeading, - pub id: Option, - pub title: String, -} - -impl MdSection { - pub fn new>(heading: MdHeading, title: S) -> Self { - Self { - heading, - id: None, - title: title.as_ref().to_owned(), - } - } -} - -impl MdElement for MdSection { - fn id(&self) -> Option<&str> { - self.id.as_ref().map(|s| s.as_str()) - } - - fn docs(&self) -> Option<&str> { - None - } - - fn set_docs(&mut self, _: &str) {} - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } -} - -fn gen_link>(id: S) -> String { - format!("", id = id.as_ref()) -} - -impl fmt::Display for MdSection { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_fmt(format_args!("{} ", self.heading))?; - - if let Some(id) = &self.id { - f.write_fmt(format_args!("{} ", gen_link(id)))?; - } - - writeln!(f, "{}", self.title) - } -} - -/// Record representing a Markdown section representing any `NamedType` element -/// of the AST. -/// Consists of: -/// * `header`, e.g., "###", or "-" for Enum variants, etc., -/// * referencable `id`, -/// * some `name`, e.g., `errno`, -/// * `docs` paragraph, and -/// * maybe `MdType`. -/// -/// Example rendering (recursive): -/// -/// ### `errno`: Enum(`u16`) -/// Error codes returned by... -/// -/// #### Variants -/// - `success` No error occurred... -/// - `2big` Argument list too long... -/// -#[derive(Debug)] -pub(super) struct MdNamedType { - pub heading: MdHeading, - pub id: String, - pub name: String, - pub docs: String, - pub ty: Option, -} - -impl MdNamedType { - pub fn new>(heading: MdHeading, id: S, name: S, docs: S) -> Self { - Self { - heading, - id: id.as_ref().to_owned(), - name: name.as_ref().to_owned(), - docs: docs.as_ref().to_owned(), - ty: None, - } - } -} - -impl MdElement for MdNamedType { - fn id(&self) -> Option<&str> { - Some(&self.id) - } - - fn docs(&self) -> Option<&str> { - Some(&self.docs) - } - - fn set_docs(&mut self, docs: &str) { - self.docs = docs.to_owned(); - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } -} - -impl fmt::Display for MdNamedType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_fmt(format_args!( - "{heading} {link} `{name}`", - heading = self.heading, - link = gen_link(&self.id), - name = self.name, - ))?; - - if let Some(tt) = &self.ty { - f.write_fmt(format_args!(": {}", tt))?; - } - - writeln!(f, "\n{}", self.docs) - } -} - -/// Record representing a Markdown section representing any `InterfaceFunc` element -/// of the AST. -/// Consists of: -/// * `header`, e.g., "###", -/// * referencable `id`, -/// * some `name`, e.g., `path_open`, -/// * function `inputs`, i.e., arguments, -/// * function `outputs`, i.e., results, and -/// * `docs` paragraph. -/// -/// Example rendering: -/// -/// ### Fn args_get(argv: `Pointer>`, ...) -> `errno` -/// Read command-line... -/// -/// #### Params -/// - `argv`: `Pointer>` Some docs... -/// - ... -/// -/// #### Results -/// - `error`: `errno` Error code... -/// -#[derive(Debug)] -pub(super) struct MdFunc { - pub heading: MdHeading, - pub id: String, - pub name: String, - pub inputs: Vec<(String, String)>, - pub outputs: Vec, - pub docs: String, -} - -impl MdFunc { - pub fn new>(heading: MdHeading, id: S, name: S, docs: S) -> Self { - Self { - heading, - id: id.as_ref().to_owned(), - name: name.as_ref().to_owned(), - inputs: vec![], - outputs: vec![], - docs: docs.as_ref().to_owned(), - } - } -} - -impl MdElement for MdFunc { - fn id(&self) -> Option<&str> { - Some(&self.id) - } - - fn docs(&self) -> Option<&str> { - Some(&self.docs) - } - - fn set_docs(&mut self, docs: &str) { - self.docs = docs.to_owned(); - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } -} - -impl fmt::Display for MdFunc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Expand inputs - let inputs = self - .inputs - .iter() - .map(|(name, r#type)| format!("{}: {}", name, r#type)) - .collect::>() - .join(", "); - // Expand outputs - let outputs: Vec<_> = self - .outputs - .iter() - .map(|r#type| format!("{}", r#type)) - .collect(); - let outputs = match outputs.len() { - 0 => "".to_owned(), - 1 => format!(" -> {}", outputs[0]), - _ => format!(" -> ({})", outputs.join(", ")), - }; - // Format - writeln!(f, "\n---\n")?; - - f.write_fmt(format_args!( - "{heading} {link} `{name}({inputs}){outputs}`", - heading = self.heading, - link = gen_link(&self.id), - name = self.name, - inputs = inputs, - outputs = outputs, - ))?; - - writeln!(f, "\n{}", self.docs) - } -} diff --git a/proposals/random/tools/witx/src/docs/mod.rs b/proposals/random/tools/witx/src/docs/mod.rs deleted file mode 100644 index 8f082cba5..000000000 --- a/proposals/random/tools/witx/src/docs/mod.rs +++ /dev/null @@ -1,87 +0,0 @@ -mod ast; -mod md; - -use crate::ast::Document; -use md::{MdNodeRef, MdRoot, ToMarkdown}; -use std::{ - collections::{hash_map, HashSet}, - iter::FromIterator, -}; - -/// Enables generating Markdown formatted content. -pub trait Documentation { - fn to_md(&self) -> String; -} - -/// Helper function which given input `text` and a `HashSet` of existing links converts -/// any slice of the form '`{link}`' into either -/// 1. "[`{link}`](#{md_link})" where `md_link` is `link` with "::" replaced with "." -/// (in Markdown, scoping should be done with ".") if `md_link` exists in the `HashSet` -/// 2. "`{link}`" otherwise. That is, if `md_link` could not be found in the `HashSet`, we -/// just leave what we've consumed. -fn parse_links>(text: S, existing_links: &HashSet) -> String { - let text = text.as_ref(); - let mut parsed_text = String::with_capacity(text.len()); - let mut link = String::with_capacity(text.len()); - let mut is_link = false; - - for ch in text.chars() { - match (ch, is_link) { - // Found the beginning of a link! - ('`', false) => { - is_link = true; - } - // Reached the end, expand into a link! - ('`', true) => { - // Sanitise scoping by replacing "::" with '.' - let md_link = link.replace("::", "."); - // Before committing to pasting the link in, - // first verify that it actually exists. - let expanded = if let Some(_) = existing_links.get(&md_link) { - format!("[`{}`](#{})", link, md_link) - } else { - log::warn!( - "Link [`{}`](#{}) could not be found in the document!", - link, - md_link - ); - format!("`{}`", link) - }; - parsed_text.push_str(&expanded); - link.drain(..); - is_link = false; - } - (ch, false) => parsed_text.push(ch), - (ch, true) => link.push(ch), - } - } - - parsed_text -} - -impl Documentation for Document { - fn to_md(&self) -> String { - let root = MdNodeRef::new(MdRoot::default()); - self.generate(root.clone()); - // Get all children of the `root` element. - let children = root.borrow().children(); - // Gather all existing links in the document into a set. - let existing_links: HashSet = HashSet::from_iter( - children - .iter() - .filter_map(|x| x.any_ref().id().map(String::from)), - ); - // Traverse each docs section of each child, and parse links - // logging a warning in case the generated is invalid. - for child in children { - let docs_with_links = child - .any_ref() - .docs() - .map(|docs| parse_links(docs, &existing_links)); - if let Some(docs) = docs_with_links { - child.any_ref_mut().set_docs(&docs); - } - } - format!("{}", root) - } -} diff --git a/proposals/random/tools/witx/src/io.rs b/proposals/random/tools/witx/src/io.rs deleted file mode 100644 index f46ab1766..000000000 --- a/proposals/random/tools/witx/src/io.rs +++ /dev/null @@ -1,103 +0,0 @@ -use crate::WitxError; -use std::collections::HashMap; -use std::fs::{read_to_string, File}; -use std::io::{BufRead, BufReader, Error, ErrorKind}; -use std::path::{Path, PathBuf}; - -pub trait WitxIo { - /// Read the entire file into a String. Used to resolve `use` declarations. - fn fgets(&self, path: &Path) -> Result; - /// Read a line of a file into a String. Used for error reporting. - fn fget_line(&self, path: &Path, line_num: usize) -> Result; - /// Return the canonical (non-symlinked) path of a file. Used to resolve `use` declarations. - fn canonicalize(&self, path: &Path) -> Result; -} - -impl WitxIo for &'_ T { - fn fgets(&self, path: &Path) -> Result { - T::fgets(self, path) - } - fn fget_line(&self, path: &Path, line_num: usize) -> Result { - T::fget_line(self, path, line_num) - } - fn canonicalize(&self, path: &Path) -> Result { - T::canonicalize(self, path) - } -} - -pub struct Filesystem; - -impl WitxIo for Filesystem { - fn fgets(&self, path: &Path) -> Result { - read_to_string(path).map_err(|e| WitxError::Io(path.to_path_buf(), e)) - } - fn fget_line(&self, path: &Path, line_num: usize) -> Result { - let f = File::open(path).map_err(|e| WitxError::Io(path.into(), e))?; - let buf = BufReader::new(f); - let l = buf - .lines() - .skip(line_num - 1) - .next() - .ok_or_else(|| { - WitxError::Io(path.into(), Error::new(ErrorKind::Other, "Line not found")) - })? - .map_err(|e| WitxError::Io(path.into(), e))?; - - Ok(l) - } - fn canonicalize(&self, path: &Path) -> Result { - path.canonicalize() - .map_err(|e| WitxError::Io(path.to_path_buf(), e)) - } -} - -pub struct MockFs { - map: HashMap, -} - -impl MockFs { - pub fn new(strings: &[(&str, &str)]) -> Self { - MockFs { - map: strings - .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - } - } -} - -impl WitxIo for MockFs { - fn fgets(&self, path: &Path) -> Result { - if let Some(entry) = self.map.get(path.to_str().unwrap()) { - Ok(entry.to_string()) - } else { - Err(WitxError::Io( - path.to_path_buf(), - Error::new(ErrorKind::Other, "mock fs: file not found"), - )) - } - } - fn fget_line(&self, path: &Path, line: usize) -> Result { - if let Some(entry) = self.map.get(path.to_str().unwrap()) { - entry - .lines() - .skip(line - 1) - .next() - .map(|s| s.to_string()) - .ok_or_else(|| { - WitxError::Io( - path.to_path_buf(), - Error::new(ErrorKind::Other, "mock fs: file not found"), - ) - }) - } else { - Err(WitxError::Io( - path.to_path_buf(), - Error::new(ErrorKind::Other, "mock fs: file not found"), - )) - } - } - fn canonicalize(&self, path: &Path) -> Result { - Ok(PathBuf::from(path)) - } -} diff --git a/proposals/random/tools/witx/src/layout.rs b/proposals/random/tools/witx/src/layout.rs deleted file mode 100644 index 6812f01ae..000000000 --- a/proposals/random/tools/witx/src/layout.rs +++ /dev/null @@ -1,219 +0,0 @@ -use crate::ast::*; -use std::collections::HashMap; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct SizeAlign { - pub size: usize, - pub align: usize, -} - -impl SizeAlign { - fn zero() -> SizeAlign { - SizeAlign { size: 0, align: 0 } - } - fn append_field(&mut self, other: &SizeAlign) { - self.align = self.align.max(other.align); - self.size = align_to(self.size, other.align); - self.size += other.size; - } -} - -pub trait Layout { - fn mem_size_align(&self) -> SizeAlign; - fn mem_size(&self) -> usize { - self.mem_size_align().size - } - fn mem_align(&self) -> usize { - self.mem_size_align().align - } -} - -impl TypeRef { - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - if let Some(hit) = cache.get(self) { - return *hit; - } - let layout = match &self { - TypeRef::Name(nt) => nt.layout(cache), - TypeRef::Value(v) => v.layout(cache), - }; - cache.insert(self.clone(), layout); - layout - } -} - -impl Layout for TypeRef { - fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } -} - -impl NamedType { - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - self.tref.layout(cache) - } -} -impl Layout for NamedType { - fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } -} - -impl Type { - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - match &self { - Type::Record(s) => match s.bitflags_repr() { - Some(repr) => repr.mem_size_align(), - None => s.layout(cache), - }, - Type::Variant(s) => s.mem_size_align(), - Type::Handle(h) => h.mem_size_align(), - Type::List { .. } => SizeAlign { size: 8, align: 4 }, // Pointer and Length - Type::Pointer { .. } | Type::ConstPointer { .. } => BuiltinType::S32.mem_size_align(), - Type::Builtin(b) => b.mem_size_align(), - } - } -} - -impl Layout for Type { - fn mem_size_align(&self) -> SizeAlign { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } -} - -impl Layout for IntRepr { - fn mem_size_align(&self) -> SizeAlign { - self.to_builtin().mem_size_align() - } -} - -pub struct RecordMemberLayout<'a> { - pub member: &'a RecordMember, - pub offset: usize, -} - -impl RecordDatatype { - pub fn member_layout(&self) -> Vec { - self.member_layout_(&mut HashMap::new()).1 - } - - fn member_layout_( - &self, - cache: &mut HashMap, - ) -> (SizeAlign, Vec) { - let mut members = Vec::new(); - let mut sa = SizeAlign::zero(); - for m in self.members.iter() { - let member = m.tref.layout(cache); - sa.append_field(&member); - members.push(RecordMemberLayout { - member: m, - offset: sa.size - member.size, - }); - } - sa.size = align_to(sa.size, sa.align); - (sa, members) - } - - fn layout(&self, cache: &mut HashMap) -> SizeAlign { - self.member_layout_(cache).0 - } -} - -impl Layout for RecordDatatype { - fn mem_size_align(&self) -> SizeAlign { - match self.bitflags_repr() { - Some(repr) => repr.mem_size_align(), - None => { - let mut cache = HashMap::new(); - self.layout(&mut cache) - } - } - } -} - -impl Layout for Variant { - fn mem_size_align(&self) -> SizeAlign { - let mut max = SizeAlign { size: 0, align: 0 }; - for case in self.cases.iter() { - let mut size = self.tag_repr.mem_size_align(); - if let Some(payload) = &case.tref { - size.append_field(&payload.mem_size_align()); - } - size.size = align_to(size.size, size.align); - max.size = max.size.max(size.size); - max.align = max.align.max(size.align); - } - max - } -} - -impl Variant { - pub fn payload_offset(&self) -> usize { - let mut offset = self.tag_repr.mem_size_align().size; - for case in self.cases.iter() { - if let Some(payload) = &case.tref { - offset = offset.max(align_to(offset, payload.mem_size_align().align)); - } - } - offset - } -} - -/// If the next free byte in the struct is `offs`, and the next -/// element has alignment `alignment`, determine the offset at -/// which to place that element. -fn align_to(offs: usize, alignment: usize) -> usize { - offs + alignment - 1 - ((offs + alignment - 1) % alignment) -} - -#[cfg(test)] -mod test { - use super::align_to; - #[test] - fn align() { - assert_eq!(0, align_to(0, 1)); - assert_eq!(0, align_to(0, 2)); - assert_eq!(0, align_to(0, 4)); - assert_eq!(0, align_to(0, 8)); - - assert_eq!(1, align_to(1, 1)); - assert_eq!(2, align_to(1, 2)); - assert_eq!(4, align_to(1, 4)); - assert_eq!(8, align_to(1, 8)); - - assert_eq!(2, align_to(2, 1)); - assert_eq!(2, align_to(2, 2)); - assert_eq!(4, align_to(2, 4)); - assert_eq!(8, align_to(2, 8)); - - assert_eq!(5, align_to(5, 1)); - assert_eq!(6, align_to(5, 2)); - assert_eq!(8, align_to(5, 4)); - assert_eq!(8, align_to(5, 8)); - } -} - -impl Layout for HandleDatatype { - fn mem_size_align(&self) -> SizeAlign { - BuiltinType::S32.mem_size_align() - } -} - -impl Layout for BuiltinType { - fn mem_size_align(&self) -> SizeAlign { - match self { - BuiltinType::U8 { .. } | BuiltinType::S8 => SizeAlign { size: 1, align: 1 }, - BuiltinType::U16 | BuiltinType::S16 => SizeAlign { size: 2, align: 2 }, - BuiltinType::Char | BuiltinType::U32 { .. } | BuiltinType::S32 | BuiltinType::F32 => { - SizeAlign { size: 4, align: 4 } - } - BuiltinType::U64 | BuiltinType::S64 | BuiltinType::F64 => { - SizeAlign { size: 8, align: 8 } - } - } - } -} diff --git a/proposals/random/tools/witx/src/lib.rs b/proposals/random/tools/witx/src/lib.rs deleted file mode 100644 index a0eba6a17..000000000 --- a/proposals/random/tools/witx/src/lib.rs +++ /dev/null @@ -1,97 +0,0 @@ -/// Map witx types to core (wasm standard) types -mod abi; -/// Types describing a validated witx document -mod ast; -/// Render documentation -mod docs; -/// Interface for filesystem or mock IO -mod io; -/// Calculate memory layout of types -mod layout; -/// Witx syntax parsing from SExprs -pub mod parser; -/// Calculate required polyfill between interfaces -pub mod polyfill; -/// Render ast to text -mod render; -/// Representational equality of types -mod representation; -/// Resolve toplevel `use` declarations across files -mod toplevel; -/// Validate declarations into ast -mod validate; - -pub use abi::*; -pub use ast::*; -pub use docs::Documentation; -pub use io::{Filesystem, MockFs, WitxIo}; -pub use layout::{Layout, RecordMemberLayout, SizeAlign}; -pub use render::SExpr; -pub use representation::{RepEquality, Representable}; -pub use validate::{DocValidation, ValidationError}; - -use std::path::{Path, PathBuf}; -use thiserror::Error; - -/// Load a witx document from the filesystem -pub fn load>(paths: &[P]) -> Result { - toplevel::parse_witx(paths) -} - -/// Parse a witx document from a str. `(use ...)` directives are not permitted. -pub fn parse(source: &str) -> Result { - let mockfs = MockFs::new(&[("-", source)]); - toplevel::parse_witx_with(&[Path::new("-")], &mockfs) -} - -/// Location in the source text -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct Location { - pub path: PathBuf, - pub line: usize, - pub column: usize, -} - -#[derive(Debug, Error)] -pub enum WitxError { - #[error("IO error with file {0:?}")] - Io(PathBuf, #[source] ::std::io::Error), - #[error("Parse error")] - Parse(#[from] wast::Error), - #[error("Validation error")] - Validation(#[from] ValidationError), -} - -impl WitxError { - pub fn report_with(&self, witxio: &dyn WitxIo) -> String { - use WitxError::*; - match self { - Io(path, ioerr) => format!("with file {:?}: {}", path, ioerr), - Parse(parse) => parse.to_string(), - Validation(validation) => validation.report_with(witxio), - } - } - pub fn report(&self) -> String { - self.report_with(&Filesystem) - } -} - -impl Location { - pub fn highlight_source_with(&self, witxio: &dyn WitxIo) -> String { - let mut msg = format!("in {:?}:\n", self.path); - if let Ok(src_line) = witxio.fget_line(&self.path, self.line) { - msg += &format!( - "{line_num: >5} | {src_line}\n{blank: >5} {caret: >column$}", - line_num = self.line, - src_line = src_line, - blank = " ", - caret = "^", - column = self.column, - ); - } - msg - } - pub fn highlight_source(&self) -> String { - self.highlight_source_with(&Filesystem) - } -} diff --git a/proposals/random/tools/witx/src/parser.rs b/proposals/random/tools/witx/src/parser.rs deleted file mode 100644 index 33cf745ff..000000000 --- a/proposals/random/tools/witx/src/parser.rs +++ /dev/null @@ -1,778 +0,0 @@ -use crate::BuiltinType; -use wast::parser::{Parse, Parser, Peek, Result}; - -///! Parser turns s-expressions into unvalidated syntax constructs. -///! conventions: -///! `Type::starts_parsing(s-expr) -> bool` is for look-ahead: we use -///! this predicate to combine parsers for different `Type`s where both -///! alternatives are accepted. -///! `Type::parse(sexpr: &SExpr) -> Result` takes a single -///! s-expression and parses it into a `Self`. -///! for parsers that take a subset of a vector s-expression, the signature -///! `Type::parse(sexprs: &[SExpr], location: Location) -> Result` -///! has an additional `Location` argument, which should point to the parent SExpr::Vec. -///! This is used for error reporting in case the slice doesn't have the number of elements -///! expected. - -mod kw { - pub use wast::kw::{export, func, import, memory, module, param, result}; - - wast::custom_keyword!(case); - wast::custom_keyword!(char8); - wast::custom_keyword!(char); - wast::custom_keyword!(const_pointer); - wast::custom_keyword!(f32); - wast::custom_keyword!(f64); - wast::custom_keyword!(field); - wast::custom_keyword!(empty); - wast::custom_keyword!(error); - wast::custom_keyword!(expected); - wast::custom_keyword!(flags); - wast::custom_keyword!(handle); - wast::custom_keyword!(list); - wast::custom_keyword!(noreturn); - wast::custom_keyword!(pointer); - wast::custom_keyword!(record); - wast::custom_keyword!(r#const = "const"); - wast::custom_keyword!(r#enum = "enum"); - wast::custom_keyword!(r#union = "union"); - wast::custom_keyword!(r#use = "use"); - wast::custom_keyword!(repr); - wast::custom_keyword!(s16); - wast::custom_keyword!(s32); - wast::custom_keyword!(s64); - wast::custom_keyword!(s8); - wast::custom_keyword!(string); - wast::custom_keyword!(tag); - wast::custom_keyword!(tuple); - wast::custom_keyword!(typename); - wast::custom_keyword!(u16); - wast::custom_keyword!(u32); - wast::custom_keyword!(u64); - wast::custom_keyword!(u8); - wast::custom_keyword!(usize); - wast::custom_keyword!(variant); - wast::custom_keyword!(bool_ = "bool"); -} - -mod annotation { - wast::annotation!(interface); - wast::annotation!(witx); -} - -impl Parse<'_> for BuiltinType { - fn parse(parser: Parser<'_>) -> Result { - let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::Char) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::U8 { lang_c_char: false }) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::U16) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::U32 { - lang_ptr_size: false, - }) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::U64) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::S8) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::S16) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::S32) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::S64) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::F32) - } else if l.peek::() { - parser.parse::()?; - Ok(BuiltinType::F64) - } else { - Err(l.error()) - } - } -} - -impl wast::parser::Peek for BuiltinType { - fn peek(cursor: wast::parser::Cursor<'_>) -> bool { - ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - || ::peek(cursor) - } - - fn display() -> &'static str { - "builtin type" - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Default)] -pub struct CommentSyntax<'a> { - pub comments: Vec<&'a str>, -} - -impl<'a> Parse<'a> for CommentSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result> { - let comments = parser.step(|mut cursor| { - let mut comments = Vec::new(); - loop { - let (comment, c) = match cursor.comment() { - Some(pair) => pair, - None => break, - }; - cursor = c; - comments.push(if comment.starts_with(";;") { - &comment[2..] - } else { - &comment[2..comment.len() - 2] - }); - } - Ok((comments, cursor)) - })?; - Ok(CommentSyntax { comments }) - } -} - -impl<'a> CommentSyntax<'a> { - pub fn docs(&self) -> String { - // Perform a small amount of preprocessing by removing all trailing - // whitespace, and then also filter for only "doc comments" which are `;;;` - // or `(;; ... ;)`. - let docs = self - .comments - .iter() - .map(|d| d.trim_end()) - .filter_map(|d| { - if d.starts_with(";") { - Some(&d[1..]) - } else { - None - } - }) - .collect::>(); - - // Figure out how much leading whitespace we're going to be trimming from - // all docs, trimming the minimum amount in each doc comment. - let to_trim = docs - .iter() - .filter(|d| !d.is_empty()) - .map(|d| d.len() - d.trim().len()) - .min() - .unwrap_or(0); - - // Separate all documents by a newline and collect everything into a single - // string. - let mut ret = String::new(); - for doc in docs { - if !doc.is_empty() { - ret.push_str(doc[to_trim..].trim_end()); - } - ret.push_str("\n"); - } - return ret; - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Default)] -pub struct Documented<'a, T> { - pub comments: CommentSyntax<'a>, - pub item: T, -} - -impl<'a, T: Parse<'a>> Parse<'a> for Documented<'a, T> { - fn parse(parser: Parser<'a>) -> Result { - let _r1 = parser.register_annotation("witx"); - let _r1 = parser.register_annotation("interface"); - let comments = parser.parse()?; - let item = parser.parse()?; - Ok(Documented { comments, item }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TopLevelDocument<'a> { - pub items: Vec>>, -} - -impl<'a> Parse<'a> for TopLevelDocument<'a> { - fn parse(parser: Parser<'a>) -> Result { - let mut items = Vec::new(); - while !parser.is_empty() { - items.push(parser.parse()?); - } - Ok(TopLevelDocument { items }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum TopLevelSyntax<'a> { - Decl(DeclSyntax<'a>), - Use(&'a str), -} - -impl<'a> Parse<'a> for TopLevelSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - if p.peek::() { - p.parse::()?; - Ok(TopLevelSyntax::Use(p.parse()?)) - } else { - Ok(TopLevelSyntax::Decl(p.parse()?)) - } - }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum DeclSyntax<'a> { - Typename(TypenameSyntax<'a>), - Module(ModuleSyntax<'a>), - Const(Documented<'a, ConstSyntax<'a>>), -} - -impl<'a> Parse<'a> for DeclSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(DeclSyntax::Module(parser.parse()?)) - } else if l.peek::() { - Ok(DeclSyntax::Typename(parser.parse()?)) - } else if l.peek::() { - Ok(DeclSyntax::Const(parser.parse()?)) - } else { - Err(l.error()) - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TypenameSyntax<'a> { - pub ident: wast::Id<'a>, - pub def: TypedefSyntax<'a>, -} - -impl<'a> Parse<'a> for TypenameSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let ident = parser.parse()?; - let def = parser.parse()?; - Ok(TypenameSyntax { ident, def }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum TypedefSyntax<'a> { - Enum(EnumSyntax<'a>), - Tuple(TupleSyntax<'a>), - Expected(ExpectedSyntax<'a>), - Flags(FlagsSyntax<'a>), - Record(RecordSyntax<'a>), - Union(UnionSyntax<'a>), - Variant(VariantSyntax<'a>), - Handle(HandleSyntax), - List(Box>), - Pointer(Box>), - ConstPointer(Box>), - Builtin(BuiltinType), - Ident(wast::Id<'a>), - String, - Bool, -} - -impl<'a> Parse<'a> for TypedefSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(TypedefSyntax::Ident(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Builtin(parser.parse()?)) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::String) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Bool) - } else if l.peek::() { - parser.parens(|parser| { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(TypedefSyntax::Enum(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Tuple(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Expected(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Flags(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Record(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Union(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Variant(parser.parse()?)) - } else if l.peek::() { - Ok(TypedefSyntax::Handle(parser.parse()?)) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::List(Box::new(parser.parse()?))) - } else if l.peek::() { - parser.parse::()?; - let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::ConstPointer(Box::new(parser.parse()?))) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Pointer(Box::new(parser.parse()?))) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Builtin(BuiltinType::U32 { - lang_ptr_size: true, - })) - } else if l.peek::() { - parser.parse::()?; - Ok(TypedefSyntax::Builtin(BuiltinType::U8 { - lang_c_char: true, - })) - } else { - Err(l.error()) - } - } else { - Err(l.error()) - } - }) - } else { - Err(l.error()) - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct EnumSyntax<'a> { - pub repr: Option, - pub members: Vec>>, -} - -impl<'a> Parse<'a> for EnumSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let repr = if parser.peek2::() { - Some(parser.parens(|p| { - p.parse::()?; - p.parse::()?; - p.parse() - })?) - } else { - None - }; - let mut members = Vec::new(); - members.push(parser.parse()?); - while !parser.is_empty() { - members.push(parser.parse()?); - } - Ok(EnumSyntax { repr, members }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TupleSyntax<'a> { - pub types: Vec>, -} - -impl<'a> Parse<'a> for TupleSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let mut types = Vec::new(); - while !parser.is_empty() { - types.push(parser.parse()?); - } - Ok(TupleSyntax { types }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ExpectedSyntax<'a> { - pub ok: Option>>, - pub err: Option>>, -} - -impl<'a> Parse<'a> for ExpectedSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let ok = if !parser.is_empty() && !parser.peek2::() { - Some(Box::new(parser.parse()?)) - } else { - None - }; - let err = parser.parens(|p| { - p.parse::()?; - Ok(if p.is_empty() { - None - } else { - Some(Box::new(p.parse()?)) - }) - })?; - Ok(ExpectedSyntax { ok, err }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ConstSyntax<'a> { - pub ty: wast::Id<'a>, - pub name: wast::Id<'a>, - pub value: u64, -} - -impl<'a> Parse<'a> for ConstSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - parser.parse::()?; - let ty = parser.parse()?; - let name = parser.parse()?; - let value = parser.parse()?; - Ok(ConstSyntax { ty, name, value }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct FlagsSyntax<'a> { - pub repr: Option, - pub flags: Vec>>, -} - -impl<'a> Parse<'a> for FlagsSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let repr = if parser.peek2::() { - Some(parser.parens(|p| { - p.parse::()?; - p.parse::()?; - p.parse() - })?) - } else { - None - }; - let mut flags = Vec::new(); - while !parser.is_empty() { - flags.push(parser.parse()?); - } - Ok(FlagsSyntax { repr, flags }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct RecordSyntax<'a> { - pub fields: Vec>>, -} - -impl<'a> Parse<'a> for RecordSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let mut fields = Vec::new(); - fields.push(parser.parse()?); - while !parser.is_empty() { - fields.push(parser.parse()?); - } - Ok(RecordSyntax { fields }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct FieldSyntax<'a> { - pub name: wast::Id<'a>, - pub type_: TypedefSyntax<'a>, -} - -impl<'a> Parse<'a> for FieldSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - p.parse::()?; - let name = p.parse()?; - let type_ = p.parse()?; - Ok(FieldSyntax { name, type_ }) - }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct UnionSyntax<'a> { - pub tag: Option>>, - pub fields: Vec>>, -} - -impl<'a> Parse<'a> for UnionSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let tag = if parser.peek2::() { - Some(parser.parens(|p| { - p.parse::()?; - p.parse::()?; - p.parse().map(Box::new) - })?) - } else { - None - }; - let mut fields = Vec::new(); - while !parser.is_empty() { - fields.push(parser.parse()?); - } - Ok(UnionSyntax { tag, fields }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct VariantSyntax<'a> { - pub tag: Option>>, - pub cases: Vec>>, -} - -impl<'a> Parse<'a> for VariantSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let tag = if parser.peek2::() { - Some(parser.parens(|p| { - p.parse::()?; - p.parse::()?; - p.parse().map(Box::new) - })?) - } else { - None - }; - let mut cases = Vec::new(); - while !parser.is_empty() { - let comments = parser.parse()?; - let item = parser.parens(|p| p.parse())?; - cases.push(Documented { comments, item }); - } - Ok(VariantSyntax { tag, cases }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CaseSyntax<'a> { - pub name: wast::Id<'a>, - pub ty: Option>, -} - -impl<'a> Parse<'a> for CaseSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - Ok(CaseSyntax { - name: parser.parse()?, - ty: if parser.is_empty() { - None - } else { - Some(parser.parse()?) - }, - }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct HandleSyntax {} - -impl<'a> Parse<'a> for HandleSyntax { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - Ok(HandleSyntax {}) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ModuleSyntax<'a> { - pub name: wast::Id<'a>, - pub decls: Vec>>, -} - -impl<'a> Parse<'a> for ModuleSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let name = parser.parse()?; - let mut decls = Vec::new(); - while !parser.is_empty() { - decls.push(parser.parse()?); - } - Ok(ModuleSyntax { name, decls }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum ModuleDeclSyntax<'a> { - Import(ModuleImportSyntax<'a>), - Func(InterfaceFuncSyntax<'a>), -} - -impl<'a> Parse<'a> for ModuleDeclSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - let mut l = p.lookahead1(); - if l.peek::() { - Ok(ModuleDeclSyntax::Import(p.parse()?)) - } else if l.peek::() { - Ok(ModuleDeclSyntax::Func(p.parse()?)) - } else { - Err(l.error()) - } - }) - } -} - -#[derive(Debug, Clone)] -pub struct ModuleImportSyntax<'a> { - pub name: &'a str, - pub name_loc: wast::Span, - pub type_: ImportTypeSyntax, -} - -impl<'a> Parse<'a> for ModuleImportSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - let name_loc = parser.cur_span(); - Ok(ModuleImportSyntax { - name: parser.parse()?, - name_loc, - type_: parser.parens(|p| p.parse())?, - }) - } -} - -impl PartialEq for ModuleImportSyntax<'_> { - fn eq(&self, other: &ModuleImportSyntax<'_>) -> bool { - // skip the `name_loc` field - self.name == other.name && self.type_ == other.type_ - } -} - -impl Eq for ModuleImportSyntax<'_> {} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum ImportTypeSyntax { - Memory, -} - -impl Parse<'_> for ImportTypeSyntax { - fn parse(parser: Parser<'_>) -> Result { - parser.parse::()?; - Ok(ImportTypeSyntax::Memory) - } -} - -#[derive(Debug, Clone)] -pub struct InterfaceFuncSyntax<'a> { - pub export: &'a str, - pub export_loc: wast::Span, - pub params: Vec>>, - pub results: Vec>>, - pub noreturn: bool, -} - -impl<'a> Parse<'a> for InterfaceFuncSyntax<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parse::()?; - parser.parse::()?; - - let (export_loc, export) = parser.parens(|p| { - p.parse::()?; - Ok((p.cur_span(), p.parse()?)) - })?; - - let mut params = Vec::new(); - let mut results = Vec::new(); - let mut noreturn = false; - - while !parser.is_empty() { - let func_field = parser.parse::>()?; - match func_field.item { - InterfaceFuncField::Param(item) => { - params.push(Documented { - comments: func_field.comments, - item, - }); - } - InterfaceFuncField::Result(item) => { - results.push(Documented { - comments: func_field.comments, - item, - }); - } - InterfaceFuncField::Noreturn => { - noreturn = true; - } - } - } - - Ok(InterfaceFuncSyntax { - export, - export_loc, - params, - results, - noreturn, - }) - } -} - -enum InterfaceFuncField<'a> { - Param(FieldSyntax<'a>), - Result(FieldSyntax<'a>), - Noreturn, -} -impl<'a> Parse<'a> for InterfaceFuncField<'a> { - fn parse(parser: Parser<'a>) -> Result { - parser.parens(|p| { - let mut l = p.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(InterfaceFuncField::Param(FieldSyntax { - name: parser.parse()?, - type_: parser.parse()?, - })) - } else if l.peek::() { - parser.parse::()?; - Ok(InterfaceFuncField::Result(FieldSyntax { - name: parser.parse()?, - type_: parser.parse()?, - })) - } else if l.peek::() { - parser.parse::()?; - let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(InterfaceFuncField::Noreturn) - } else { - Err(l.error()) - } - } else { - Err(l.error()) - } - }) - } -} - -impl PartialEq for InterfaceFuncSyntax<'_> { - fn eq(&self, other: &InterfaceFuncSyntax<'_>) -> bool { - // skip the `export_loc` field - self.export == other.export - && self.params == other.params - && self.results == other.results - && self.noreturn == other.noreturn - } -} - -impl Eq for InterfaceFuncSyntax<'_> {} diff --git a/proposals/random/tools/witx/src/polyfill.rs b/proposals/random/tools/witx/src/polyfill.rs deleted file mode 100644 index c779cfa4e..000000000 --- a/proposals/random/tools/witx/src/polyfill.rs +++ /dev/null @@ -1,255 +0,0 @@ -use crate::{ - Document, Id, InterfaceFunc, InterfaceFuncParam, Module, RepEquality, Representable, Type, - TypeRef, -}; -use std::collections::{HashMap, HashSet}; -use std::rc::Rc; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum PolyfillError { - #[error("Module not present: {name:?}")] - ModuleNotPresent { name: Id }, - #[error("Function not present: {name:?}")] - FuncNotPresent { module: Id, name: Id }, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Polyfill { - pub modules: Vec, -} - -impl Polyfill { - pub fn new( - new: &Document, - old: &Document, - module_mapping: &HashMap, // Will need a more sophisticated mapping - what about function names, argument names? - ) -> Result { - let mut modules = Vec::new(); - for (newname, oldname) in module_mapping { - let newname = Id::new(newname); - let oldname = Id::new(oldname); - let newmod = new - .module(&newname) - .ok_or_else(|| PolyfillError::ModuleNotPresent { name: newname })?; - let oldmod = old - .module(&oldname) - .ok_or_else(|| PolyfillError::ModuleNotPresent { name: oldname })?; - modules.push(ModulePolyfill::new(newmod, oldmod)?); - } - Ok(Polyfill { modules }) - } - - pub fn type_polyfills(&self) -> HashSet { - self.modules - .iter() - .map(|m| m.type_polyfills()) - .flatten() - .collect() - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ModulePolyfill { - pub new: Rc, - pub old: Rc, - pub funcs: Vec, -} - -impl ModulePolyfill { - pub fn new(new: Rc, old: Rc) -> Result { - let mut funcs = Vec::new(); - for oldfunc in old.funcs() { - let newfunc = new - .func(&oldfunc.name) - .ok_or_else(|| PolyfillError::FuncNotPresent { - module: new.name.clone(), - name: oldfunc.name.clone(), - })?; - funcs.push(FuncPolyfill::new(newfunc, oldfunc)); - } - Ok(ModulePolyfill { new, old, funcs }) - } - pub fn type_polyfills(&self) -> HashSet { - self.funcs - .iter() - .map(|f| f.type_polyfills()) - .flatten() - .collect() - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct FuncPolyfill { - pub new: Rc, - pub old: Rc, - pub mapped_params: Vec, - pub unknown_params: Vec, - pub mapped_results: Vec, - pub unknown_results: Vec, -} - -impl FuncPolyfill { - pub fn new(new: Rc, old: Rc) -> FuncPolyfill { - let mut mapped_params = Vec::new(); - let mut unknown_params = Vec::new(); - - // Old function is called. Need to map each of its parameters to the new function: - for old_param in old.params.iter() { - if let Some(new_param) = new.params.iter().find(|p| p.name == old_param.name) { - mapped_params.push(ParamPolyfill::param(new_param.clone(), old_param.clone())) - } else { - unknown_params.push(ParamUnknown::Old(old_param.clone())); - } - } - // Are any new params not covered by the old params? - // This search is O(n^2), but n ought to be small. - for new_param in new.params.iter() { - if mapped_params - .iter() - .find(|m| m.new.name == new_param.name) - .is_none() - { - unknown_params.push(ParamUnknown::New(new_param.clone())); - } - } - - let mut mapped_results = Vec::new(); - let mut unknown_results = Vec::new(); - - // New function has returned. Need to map each of its results to the old function: - for new_result in new.results.iter() { - if let Some(old_result) = old.results.iter().find(|p| p.name == new_result.name) { - mapped_results.push(ParamPolyfill::result( - new_result.clone(), - old_result.clone(), - )) - } else { - unknown_results.push(ParamUnknown::New(new_result.clone())); - } - } - - // Are any old results not covered by the new results? - for old_result in old.results.iter() { - if mapped_results - .iter() - .find(|m| m.old.name == old_result.name) - .is_none() - { - unknown_results.push(ParamUnknown::Old(old_result.clone())); - } - } - - FuncPolyfill { - new, - old, - mapped_params, - unknown_params, - mapped_results, - unknown_results, - } - } - - pub fn full_compat(&self) -> bool { - self.new.name == self.old.name - && self.mapped_params.iter().all(|p| p.full_compat()) - && self.unknown_params.is_empty() - && self.mapped_results.iter().all(|p| p.full_compat()) - && self.unknown_results.is_empty() - } - - pub fn type_polyfills(&self) -> HashSet { - self.mapped_params - .iter() - .map(|p| p.type_polyfill.clone()) - .chain(self.mapped_results.iter().map(|p| p.type_polyfill.clone())) - .collect() - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ParamPolyfill { - pub new: InterfaceFuncParam, - pub old: InterfaceFuncParam, - pub type_polyfill: TypePolyfill, -} - -impl ParamPolyfill { - fn common_denominator(a: TypeRef, b: TypeRef) -> (TypeRef, TypeRef) { - match (&a, &b) { - (TypeRef::Value(va), TypeRef::Value(vb)) => match (&**va, &**vb) { - (Type::List(a), Type::List(b)) => (a.clone(), b.clone()), - (Type::Pointer(a), Type::Pointer(b)) => (a.clone(), b.clone()), - (Type::ConstPointer(a), Type::ConstPointer(b)) => (a.clone(), b.clone()), - _ => (a, b), - }, - _ => (a, b), - } - } - - pub fn param(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { - let (told, tnew) = Self::common_denominator(old.tref.clone(), new.tref.clone()); - // Call new param type with old param: - let type_polyfill = TypePolyfill::OldToNew(told, tnew); - ParamPolyfill { - new, - old, - type_polyfill, - } - } - - pub fn result(new: InterfaceFuncParam, old: InterfaceFuncParam) -> Self { - let (told, tnew) = Self::common_denominator(old.tref.clone(), new.tref.clone()); - // Return old result type from new result: - let type_polyfill = TypePolyfill::NewToOld(tnew, told); - ParamPolyfill { - new, - old, - type_polyfill, - } - } - - pub fn full_compat(&self) -> bool { - self.new.name == self.old.name && self.repeq() == RepEquality::Eq - } - - pub fn repeq(&self) -> RepEquality { - self.type_polyfill.repeq() - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum ParamUnknown { - Old(InterfaceFuncParam), - New(InterfaceFuncParam), -} - -impl ParamUnknown { - pub fn which(&self) -> &'static str { - match self { - ParamUnknown::Old { .. } => "old", - ParamUnknown::New { .. } => "new", - } - } - pub fn param(&self) -> &InterfaceFuncParam { - match self { - ParamUnknown::Old(p) => &p, - ParamUnknown::New(p) => &p, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum TypePolyfill { - NewToOld(TypeRef, TypeRef), - OldToNew(TypeRef, TypeRef), -} - -impl TypePolyfill { - pub fn repeq(&self) -> RepEquality { - match self { - TypePolyfill::NewToOld(new, old) => old.type_().representable(&new.type_()), - TypePolyfill::OldToNew(old, new) => new.type_().representable(&old.type_()), - } - } -} diff --git a/proposals/random/tools/witx/src/render.rs b/proposals/random/tools/witx/src/render.rs deleted file mode 100644 index a740e282c..000000000 --- a/proposals/random/tools/witx/src/render.rs +++ /dev/null @@ -1,320 +0,0 @@ -use crate::ast::*; -use std::fmt; - -impl fmt::Display for Document { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for d in self.typenames() { - write!(f, "{}\n", d.to_sexpr())?; - } - for m in self.modules() { - write!(f, "{}\n", m.to_sexpr())?; - } - Ok(()) - } -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub enum SExpr { - Vec(Vec), - Word(String), - Ident(String), - Quote(String), - /// Short for Annotation - Annot(String), - /// Doc comment - Docs(String, Box), -} - -impl fmt::Display for SExpr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - SExpr::Vec(vs) => { - write!(f, "(")?; - let mut vss = Vec::new(); - for v in vs { - vss.push(format!("{}", v)); - } - f.write_str(&vss.join(" "))?; - write!(f, ")") - } - SExpr::Word(w) => write!(f, "{}", w), - SExpr::Ident(i) => write!(f, "${}", i), - SExpr::Quote(q) => write!(f, "\"{}\"", q), - SExpr::Annot(a) => write!(f, "@{}", a), - SExpr::Docs(d, s) => write!(f, "(;; {} ;) {}", d, s), - } - } -} - -impl SExpr { - pub fn word(s: &str) -> SExpr { - SExpr::Word(s.to_string()) - } - pub fn ident(s: &str) -> SExpr { - SExpr::Ident(s.to_string()) - } - pub fn quote(s: &str) -> SExpr { - SExpr::Quote(s.to_string()) - } - pub fn annot(s: &str) -> SExpr { - SExpr::Annot(s.to_string()) - } - pub fn docs(d: &str, s: SExpr) -> SExpr { - if d.is_empty() { - s - } else { - SExpr::Docs(d.to_string(), Box::new(s)) - } - } -} - -impl Id { - pub fn to_sexpr(&self) -> SExpr { - SExpr::ident(self.as_str()) - } -} - -impl BuiltinType { - pub fn to_sexpr(&self) -> SExpr { - match self { - BuiltinType::Char => SExpr::word("char"), - BuiltinType::U8 { lang_c_char: true } => { - SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("char8")]) - } - BuiltinType::U8 { lang_c_char: false } => SExpr::word("u8"), - BuiltinType::U16 => SExpr::word("u16"), - BuiltinType::U32 { - lang_ptr_size: false, - } => SExpr::word("u32"), - BuiltinType::U32 { - lang_ptr_size: true, - } => SExpr::Vec(vec![SExpr::annot("witx"), SExpr::word("usize")]), - BuiltinType::U64 => SExpr::word("u64"), - BuiltinType::S8 => SExpr::word("s8"), - BuiltinType::S16 => SExpr::word("s16"), - BuiltinType::S32 => SExpr::word("s32"), - BuiltinType::S64 => SExpr::word("s64"), - BuiltinType::F32 => SExpr::word("f32"), - BuiltinType::F64 => SExpr::word("f64"), - } - } -} - -impl NamedType { - pub fn to_sexpr(&self) -> SExpr { - let body = self.tref.to_sexpr(); - SExpr::docs( - &self.docs, - SExpr::Vec(vec![SExpr::word("typename"), self.name.to_sexpr(), body]), - ) - } -} - -impl TypeRef { - pub fn to_sexpr(&self) -> SExpr { - match self { - TypeRef::Name(n) => n.name.to_sexpr(), - TypeRef::Value(v) => v.to_sexpr(), - } - } -} - -impl Type { - pub fn to_sexpr(&self) -> SExpr { - match self { - Type::Record(a) => a.to_sexpr(), - Type::Variant(a) => a.to_sexpr(), - Type::Handle(a) => a.to_sexpr(), - Type::List(a) => SExpr::Vec(vec![SExpr::word("list"), a.to_sexpr()]), - Type::Pointer(p) => SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("pointer"), - p.to_sexpr(), - ]), - Type::ConstPointer(p) => SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("const_pointer"), - p.to_sexpr(), - ]), - Type::Builtin(b) => b.to_sexpr(), - } - } -} - -impl RecordDatatype { - pub fn to_sexpr(&self) -> SExpr { - match self.kind { - RecordKind::Tuple => { - let mut tuple = vec![SExpr::word("tuple")]; - for m in self.members.iter() { - tuple.push(SExpr::docs(&m.docs, m.tref.to_sexpr())); - } - SExpr::Vec(tuple) - } - RecordKind::Bitflags(repr) => { - let mut flags = vec![SExpr::word("flags")]; - flags.push(SExpr::Vec(vec![ - SExpr::word("@witx"), - SExpr::word("repr"), - repr.to_sexpr(), - ])); - flags.extend( - self.members - .iter() - .map(|m| SExpr::docs(&m.docs, m.name.to_sexpr())), - ); - SExpr::Vec(flags) - } - RecordKind::Other => { - let header = vec![SExpr::word("record")]; - let members = self - .members - .iter() - .map(|m| { - SExpr::docs( - &m.docs, - SExpr::Vec(vec![ - SExpr::word("field"), - m.name.to_sexpr(), - m.tref.to_sexpr(), - ]), - ) - }) - .collect::>(); - SExpr::Vec([header, members].concat()) - } - } - } -} - -impl Variant { - pub fn to_sexpr(&self) -> SExpr { - let mut list = Vec::new(); - if self.is_bool() { - return SExpr::word("bool"); - } else if self.is_enum() { - list.push(SExpr::word("enum")); - list.push(SExpr::Vec(vec![ - SExpr::word("@witx"), - SExpr::word("tag"), - self.tag_repr.to_sexpr(), - ])); - for case in self.cases.iter() { - list.push(SExpr::docs(&case.docs, case.name.to_sexpr())); - } - } else { - list.push(SExpr::word("variant")); - list.push(SExpr::Vec(vec![ - SExpr::word("@witx"), - SExpr::word("tag"), - self.tag_repr.to_sexpr(), - ])); - for case in self.cases.iter() { - let mut case_expr = vec![SExpr::word("case"), case.name.to_sexpr()]; - if let Some(ty) = &case.tref { - case_expr.push(ty.to_sexpr()); - } - list.push(SExpr::docs(&case.docs, SExpr::Vec(case_expr))); - } - } - SExpr::Vec(list) - } -} - -impl HandleDatatype { - pub fn to_sexpr(&self) -> SExpr { - SExpr::Vec(vec![SExpr::word("handle")]) - } -} - -impl IntRepr { - pub fn to_sexpr(&self) -> SExpr { - match self { - IntRepr::U8 => SExpr::word("u8"), - IntRepr::U16 => SExpr::word("u16"), - IntRepr::U32 => SExpr::word("u32"), - IntRepr::U64 => SExpr::word("u64"), - } - } -} - -impl Module { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![SExpr::word("module"), self.name.to_sexpr()]; - let definitions = self - .imports() - .map(|i| i.to_sexpr()) - .chain(self.funcs().map(|f| f.to_sexpr())) - .collect::>(); - SExpr::docs(&self.docs, SExpr::Vec([header, definitions].concat())) - } -} - -impl ModuleImport { - pub fn to_sexpr(&self) -> SExpr { - let variant = match self.variant { - ModuleImportVariant::Memory => SExpr::Vec(vec![SExpr::word("memory")]), - }; - SExpr::docs( - &self.docs, - SExpr::Vec(vec![ - SExpr::word("import"), - SExpr::quote(self.name.as_str()), - variant, - ]), - ) - } -} - -impl InterfaceFunc { - pub fn to_sexpr(&self) -> SExpr { - let header = vec![ - SExpr::annot("interface"), - SExpr::word("func"), - SExpr::Vec(vec![ - SExpr::word("export"), - SExpr::quote(self.name.as_str()), - ]), - ]; - let params = self - .params - .iter() - .map(|f| { - SExpr::docs( - &f.docs, - SExpr::Vec(vec![ - SExpr::word("param"), - f.name.to_sexpr(), - f.tref.to_sexpr(), - ]), - ) - }) - .collect(); - let results = self - .results - .iter() - .map(|f| { - SExpr::docs( - &f.docs, - SExpr::Vec(vec![ - SExpr::word("result"), - f.name.to_sexpr(), - f.tref.to_sexpr(), - ]), - ) - }) - .collect(); - let attrs = if self.noreturn { - vec![SExpr::Vec(vec![ - SExpr::annot("witx"), - SExpr::word("noreturn"), - ])] - } else { - vec![] - }; - SExpr::docs( - &self.docs, - SExpr::Vec([header, params, results, attrs].concat()), - ) - } -} diff --git a/proposals/random/tools/witx/src/representation.rs b/proposals/random/tools/witx/src/representation.rs deleted file mode 100644 index 589b64e39..000000000 --- a/proposals/random/tools/witx/src/representation.rs +++ /dev/null @@ -1,161 +0,0 @@ -use crate::{BuiltinType, IntRepr, NamedType, RecordDatatype, Type, TypeRef, Variant}; -use std::collections::HashMap; - -// A lattice. Eq + Eq = Eq, SuperSet + any = NotEq, NotEq + any = NotEq. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum RepEquality { - Eq, - Superset, - NotEq, -} - -impl RepEquality { - pub fn join(&self, rhs: &Self) -> Self { - match (self, rhs) { - (RepEquality::Eq, RepEquality::Eq) => RepEquality::Eq, - _ => RepEquality::NotEq, - } - } -} - -pub trait Representable { - fn representable(&self, by: &Self) -> RepEquality; -} - -impl Representable for BuiltinType { - fn representable(&self, by: &Self) -> RepEquality { - // An unsigned integer can be used to represent an unsigned integer of smaller width. - // Otherwise, types must be equal. - if self == by { - return RepEquality::Eq; - } - match self { - BuiltinType::U8 { .. } => match by { - BuiltinType::U64 | BuiltinType::U32 { .. } | BuiltinType::U16 => { - RepEquality::Superset - } - _ => RepEquality::NotEq, - }, - BuiltinType::U16 => match by { - BuiltinType::U64 | BuiltinType::U32 { .. } => RepEquality::Superset, - _ => RepEquality::NotEq, - }, - BuiltinType::U32 { .. } => match by { - BuiltinType::U64 => RepEquality::Superset, - _ => RepEquality::NotEq, - }, - _ => RepEquality::NotEq, - } - } -} - -impl Representable for IntRepr { - fn representable(&self, by: &Self) -> RepEquality { - if self == by { - return RepEquality::Eq; - } - // An unsigned integer can be used to represent an unsigned integer of smaller width. - match self { - IntRepr::U16 => match by { - IntRepr::U32 | IntRepr::U64 => RepEquality::Superset, - _ => RepEquality::NotEq, - }, - IntRepr::U32 => match by { - IntRepr::U64 => RepEquality::Superset, - _ => RepEquality::NotEq, - }, - _ => RepEquality::NotEq, - } - } -} - -impl Representable for Variant { - fn representable(&self, by: &Self) -> RepEquality { - let mut superset = false; - // Integer representation must be compatible - match self.tag_repr.representable(&by.tag_repr) { - RepEquality::NotEq => return RepEquality::NotEq, - RepEquality::Eq => {} - RepEquality::Superset => superset = true, - } - let other_by_name = by - .cases - .iter() - .enumerate() - .map(|(i, c)| (&c.name, (c, i))) - .collect::>(); - // For each variant in self, must have variant of same name in by: - for (i, v) in self.cases.iter().enumerate() { - let other_ty = match other_by_name.get(&v.name) { - Some((_, j)) if i != *j => return RepEquality::NotEq, - Some((other, _)) => &other.tref, - None => return RepEquality::NotEq, - }; - match (&v.tref, other_ty) { - (Some(me), Some(other)) => match me.representable(other) { - RepEquality::NotEq => return RepEquality::NotEq, - RepEquality::Eq => {} - RepEquality::Superset => superset = true, - }, - // We added fields, that's not ok - (Some(_), None) => return RepEquality::NotEq, - // Fields were deleted, that's ok - (None, Some(_)) => superset = true, - (None, None) => {} - } - } - if superset || self.cases.len() < by.cases.len() { - RepEquality::Superset - } else { - RepEquality::Eq - } - } -} - -impl Representable for RecordDatatype { - fn representable(&self, by: &Self) -> RepEquality { - // Records must have exact structural equality - same members, must - // be Eq, in the same order. - // We would require require a more expressive RepEquality enum to describe which members - // might be supersets. - if self.members.len() != by.members.len() { - return RepEquality::NotEq; - } - for (m, bym) in self.members.iter().zip(by.members.iter()) { - if m.name != bym.name { - return RepEquality::NotEq; - } - if m.tref.type_().representable(&*bym.tref.type_()) != RepEquality::Eq { - return RepEquality::NotEq; - } - } - RepEquality::Eq - } -} - -impl Representable for TypeRef { - fn representable(&self, by: &Self) -> RepEquality { - self.type_().representable(&*by.type_()) - } -} - -impl Representable for NamedType { - fn representable(&self, by: &Self) -> RepEquality { - self.tref.representable(&by.tref) - } -} - -impl Representable for Type { - fn representable(&self, by: &Self) -> RepEquality { - match (&self, &by) { - (Type::Variant(s), Type::Variant(b)) => s.representable(b), - (Type::Record(s), Type::Record(b)) => s.representable(b), - (Type::Handle(_), Type::Handle(_)) => RepEquality::Eq, // Handles are nominal, not structural - (Type::List(s), Type::List(b)) => s.representable(b), - (Type::Pointer(s), Type::Pointer(b)) => s.representable(b), - (Type::ConstPointer(s), Type::ConstPointer(b)) => s.representable(b), - (Type::Builtin(s), Type::Builtin(b)) => s.representable(b), - _ => RepEquality::NotEq, - } - } -} diff --git a/proposals/random/tools/witx/src/toplevel.rs b/proposals/random/tools/witx/src/toplevel.rs deleted file mode 100644 index 257e6edd8..000000000 --- a/proposals/random/tools/witx/src/toplevel.rs +++ /dev/null @@ -1,166 +0,0 @@ -use crate::ast::{Definition, Document}; -use crate::io::{Filesystem, WitxIo}; -use crate::parser::{TopLevelDocument, TopLevelSyntax}; -use crate::validate::DocValidation; -use crate::WitxError; -use std::collections::HashSet; -use std::path::{Path, PathBuf}; - -pub fn parse_witx(i: &[impl AsRef]) -> Result { - let paths = i.iter().map(|p| p.as_ref()).collect::>(); - _parse_witx_with(&paths, &Filesystem) -} - -pub fn parse_witx_with(i: &[impl AsRef], witxio: impl WitxIo) -> Result { - let paths = i.iter().map(|p| p.as_ref()).collect::>(); - _parse_witx_with(&paths, &witxio) -} - -fn _parse_witx_with(paths: &[&Path], io: &dyn WitxIo) -> Result { - let mut validator = DocValidation::new(); - let mut definitions = Vec::new(); - let mut parsed = HashSet::new(); - for path in paths { - let root = path.parent().unwrap_or(Path::new(".")); - - parse_file( - path.file_name().unwrap().as_ref(), - io, - root, - &mut validator, - &mut definitions, - &mut parsed, - )?; - } - Ok(validator.into_document(definitions)) -} - -fn parse_file( - path: &Path, - io: &dyn WitxIo, - root: &Path, - validator: &mut DocValidation, - definitions: &mut Vec, - parsed: &mut HashSet, -) -> Result<(), WitxError> { - let path = io.canonicalize(&root.join(path))?; - if !parsed.insert(path.clone()) { - return Ok(()); - } - let input = io.fgets(&path)?; - - let adjust_err = |mut error: wast::Error| { - error.set_path(&path); - error.set_text(&input); - WitxError::Parse(error) - }; - let buf = wast::parser::ParseBuffer::new(&input).map_err(adjust_err)?; - let doc = wast::parser::parse::(&buf).map_err(adjust_err)?; - - for t in doc.items { - match t.item { - TopLevelSyntax::Decl(d) => { - validator - .scope(&input, &path) - .validate_decl(&d, &t.comments, definitions) - .map_err(WitxError::Validation)?; - } - TopLevelSyntax::Use(u) => { - parse_file(u.as_ref(), io, root, validator, definitions, parsed)?; - } - } - } - - Ok(()) -} - -#[cfg(test)] -mod test { - use super::*; - use crate::ast::*; - use crate::io::MockFs; - - #[test] - fn empty() { - parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", ";; empty")])).expect("parse"); - } - - #[test] - fn one_use() { - parse_witx_with( - &[Path::new("/a")], - &MockFs::new(&[("/a", "(use \"b\")"), ("/b", ";; empty")]), - ) - .unwrap(); - } - - #[test] - fn multi_use() { - let doc = parse_witx_with( - &[Path::new("/a")], - &MockFs::new(&[ - ("/a", "(use \"b\")"), - ("/b", "(use \"c\")\n(typename $b_float f64)"), - ("/c", "(typename $c_int u32)"), - ]), - ) - .expect("parse"); - - let b_float = doc.typename(&Id::new("b_float")).unwrap(); - assert_eq!(**b_float.type_(), Type::Builtin(BuiltinType::F64)); - - let c_int = doc.typename(&Id::new("c_int")).unwrap(); - assert_eq!( - **c_int.type_(), - Type::Builtin(BuiltinType::U32 { - lang_ptr_size: false - }) - ); - } - - #[test] - fn diamond_dependency() { - let doc = parse_witx_with( - &[Path::new("/a")], - &MockFs::new(&[ - ("/a", "(use \"b\")\n(use \"c\")"), - ("/b", "(use \"d\")"), - ("/c", "(use \"d\")"), - ("/d", "(typename $d_char u8)"), - ]), - ) - .expect("parse"); - - let d_char = doc.typename(&Id::new("d_char")).unwrap(); - assert_eq!( - **d_char.type_(), - Type::Builtin(BuiltinType::U8 { lang_c_char: false }) - ); - } - - #[test] - fn use_not_found() { - match parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", "(use \"b\")")])) - .err() - .unwrap() - { - WitxError::Io(path, _error) => assert_eq!(path, PathBuf::from("/b")), - e => panic!("wrong error: {:?}", e), - } - } - - #[test] - fn use_invalid() { - match parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", "(use bbbbbbb)")])) - .err() - .unwrap() - { - WitxError::Parse(e) => { - let err = e.to_string(); - assert!(err.contains("expected a string"), "bad error: {}", err); - assert!(err.contains("/a:1:6")); - } - e => panic!("wrong error: {:?}", e), - } - } -} diff --git a/proposals/random/tools/witx/src/validate.rs b/proposals/random/tools/witx/src/validate.rs deleted file mode 100644 index cf4d0ad7f..000000000 --- a/proposals/random/tools/witx/src/validate.rs +++ /dev/null @@ -1,722 +0,0 @@ -use crate::{ - io::{Filesystem, WitxIo}, - parser::{ - CommentSyntax, DeclSyntax, Documented, EnumSyntax, ExpectedSyntax, FlagsSyntax, - HandleSyntax, ImportTypeSyntax, ModuleDeclSyntax, RecordSyntax, TupleSyntax, TypedefSyntax, - UnionSyntax, VariantSyntax, - }, - Abi, BuiltinType, Case, Constant, Definition, Document, Entry, HandleDatatype, Id, IntRepr, - InterfaceFunc, InterfaceFuncParam, Location, Module, ModuleDefinition, ModuleEntry, - ModuleImport, ModuleImportVariant, NamedType, RecordDatatype, RecordKind, RecordMember, Type, - TypeRef, Variant, -}; -use std::collections::{HashMap, HashSet}; -use std::path::Path; -use std::rc::Rc; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum ValidationError { - #[error("Unknown name `{name}`")] - UnknownName { name: String, location: Location }, - #[error("Redefinition of name `{name}`")] - NameAlreadyExists { - name: String, - at_location: Location, - previous_location: Location, - }, - #[error("Wrong kind of name `{name}`: expected {expected}, got {got}")] - WrongKindName { - name: String, - location: Location, - expected: &'static str, - got: &'static str, - }, - #[error("Recursive definition of name `{name}`")] - Recursive { name: String, location: Location }, - #[error("Invalid representation `{repr:?}`")] - InvalidRepr { - repr: BuiltinType, - location: Location, - }, - #[error("ABI error: {reason}")] - Abi { reason: String, location: Location }, - #[error("Anonymous structured types (struct, union, enum, flags, handle) are not permitted")] - AnonymousRecord { location: Location }, - #[error("Union expected {expected} variants, found {found}")] - UnionSizeMismatch { - expected: usize, - found: usize, - location: Location, - }, - #[error("Invalid union tag: {reason}")] - InvalidUnionTag { reason: String, location: Location }, - #[error("Invalid union field `{name}`: {reason}")] - InvalidUnionField { - name: String, - reason: String, - location: Location, - }, -} - -impl ValidationError { - pub fn report_with(&self, witxio: &dyn WitxIo) -> String { - use ValidationError::*; - match self { - UnknownName { location, .. } - | WrongKindName { location, .. } - | Recursive { location, .. } - | InvalidRepr { location, .. } - | Abi { location, .. } - | AnonymousRecord { location, .. } - | UnionSizeMismatch { location, .. } - | InvalidUnionField { location, .. } - | InvalidUnionTag { location, .. } => { - format!("{}\n{}", location.highlight_source_with(witxio), &self) - } - NameAlreadyExists { - at_location, - previous_location, - .. - } => format!( - "{}\n{}\nOriginally defined at:\n{}", - at_location.highlight_source_with(witxio), - &self, - previous_location.highlight_source_with(witxio), - ), - } - } - pub fn report(&self) -> String { - self.report_with(&Filesystem) - } -} - -struct IdentValidation { - names: HashMap, -} - -impl IdentValidation { - fn new() -> Self { - Self { - names: HashMap::new(), - } - } - - fn introduce(&mut self, syntax: &str, location: Location) -> Result { - if let Some(introduced) = self.names.get(syntax) { - Err(ValidationError::NameAlreadyExists { - name: syntax.to_string(), - at_location: location, - previous_location: introduced.clone(), - }) - } else { - self.names.insert(syntax.to_string(), location); - Ok(Id::new(syntax)) - } - } - - fn get(&self, syntax: &str, location: Location) -> Result { - if self.names.get(syntax).is_some() { - Ok(Id::new(syntax)) - } else { - Err(ValidationError::UnknownName { - name: syntax.to_string(), - location, - }) - } - } -} - -pub struct DocValidation { - scope: IdentValidation, - entries: HashMap, - constant_scopes: HashMap, - bool_ty: TypeRef, -} - -pub struct DocValidationScope<'a> { - doc: &'a mut DocValidation, - text: &'a str, - path: &'a Path, -} - -impl DocValidation { - pub fn new() -> Self { - Self { - scope: IdentValidation::new(), - entries: HashMap::new(), - constant_scopes: HashMap::new(), - bool_ty: TypeRef::Value(Rc::new(Type::Variant(Variant { - tag_repr: IntRepr::U32, - cases: vec![ - Case { - name: Id::new("false"), - tref: None, - docs: String::new(), - }, - Case { - name: Id::new("true"), - tref: None, - docs: String::new(), - }, - ], - }))), - } - } - - pub fn scope<'a>(&'a mut self, text: &'a str, path: &'a Path) -> DocValidationScope<'a> { - DocValidationScope { - doc: self, - text, - path, - } - } - - pub fn into_document(self, defs: Vec) -> Document { - Document::new(defs, self.entries) - } -} - -impl DocValidationScope<'_> { - fn location(&self, span: wast::Span) -> Location { - // Wast Span gives 0-indexed lines and columns. Location is 1-indexed. - let (line, column) = span.linecol_in(self.text); - Location { - line: line + 1, - column: column + 1, - path: self.path.to_path_buf(), - } - } - - fn introduce(&mut self, name: &wast::Id<'_>) -> Result { - let loc = self.location(name.span()); - self.doc.scope.introduce(name.name(), loc) - } - - fn get(&self, name: &wast::Id<'_>) -> Result { - let loc = self.location(name.span()); - self.doc.scope.get(name.name(), loc) - } - - pub fn validate_decl( - &mut self, - decl: &DeclSyntax, - comments: &CommentSyntax, - definitions: &mut Vec, - ) -> Result<(), ValidationError> { - match decl { - DeclSyntax::Typename(decl) => { - let name = self.introduce(&decl.ident)?; - let docs = comments.docs(); - let tref = self.validate_datatype(&decl.def, true, decl.ident.span())?; - - let rc_datatype = Rc::new(NamedType { - name: name.clone(), - tref, - docs, - }); - self.doc - .entries - .insert(name.clone(), Entry::Typename(Rc::downgrade(&rc_datatype))); - definitions.push(Definition::Typename(rc_datatype)); - } - - DeclSyntax::Module(syntax) => { - let name = self.introduce(&syntax.name)?; - let mut module_validator = ModuleValidation::new(self); - let decls = syntax - .decls - .iter() - .map(|d| module_validator.validate_decl(&d)) - .collect::, _>>()?; - - let rc_module = Rc::new(Module::new( - name.clone(), - decls, - module_validator.entries, - comments.docs(), - )); - self.doc - .entries - .insert(name, Entry::Module(Rc::downgrade(&rc_module))); - definitions.push(Definition::Module(rc_module)); - } - - DeclSyntax::Const(syntax) => { - let ty = Id::new(syntax.item.ty.name()); - let loc = self.location(syntax.item.name.span()); - let scope = self - .doc - .constant_scopes - .entry(ty.clone()) - .or_insert_with(IdentValidation::new); - let name = scope.introduce(syntax.item.name.name(), loc)?; - // TODO: validate `ty` is a integer datatype that `syntax.value` - // fits within. - definitions.push(Definition::Constant(Constant { - ty, - name, - value: syntax.item.value, - docs: syntax.comments.docs(), - })); - } - } - Ok(()) - } - - fn validate_datatype( - &self, - syntax: &TypedefSyntax, - named: bool, - span: wast::Span, - ) -> Result { - match syntax { - TypedefSyntax::Ident(syntax) => { - let i = self.get(syntax)?; - match self.doc.entries.get(&i) { - Some(Entry::Typename(weak_ref)) => Ok(TypeRef::Name( - weak_ref.upgrade().expect("weak backref to defined type"), - )), - Some(e) => Err(ValidationError::WrongKindName { - name: i.as_str().to_string(), - location: self.location(syntax.span()), - expected: "datatype", - got: e.kind(), - }), - None => Err(ValidationError::Recursive { - name: i.as_str().to_string(), - location: self.location(syntax.span()), - }), - } - } - TypedefSyntax::Enum { .. } - | TypedefSyntax::Flags { .. } - | TypedefSyntax::Record { .. } - | TypedefSyntax::Union { .. } - | TypedefSyntax::Handle { .. } - if !named => - { - Err(ValidationError::AnonymousRecord { - location: self.location(span), - }) - } - other => Ok(TypeRef::Value(Rc::new(match other { - TypedefSyntax::Enum(syntax) => Type::Variant(self.validate_enum(&syntax, span)?), - TypedefSyntax::Tuple(syntax) => Type::Record(self.validate_tuple(&syntax, span)?), - TypedefSyntax::Expected(syntax) => { - Type::Variant(self.validate_expected(&syntax, span)?) - } - TypedefSyntax::Flags(syntax) => Type::Record(self.validate_flags(&syntax, span)?), - TypedefSyntax::Record(syntax) => Type::Record(self.validate_record(&syntax, span)?), - TypedefSyntax::Union(syntax) => Type::Variant(self.validate_union(&syntax, span)?), - TypedefSyntax::Variant(syntax) => { - Type::Variant(self.validate_variant(&syntax, span)?) - } - TypedefSyntax::Handle(syntax) => Type::Handle(self.validate_handle(syntax, span)?), - TypedefSyntax::List(syntax) => { - Type::List(self.validate_datatype(syntax, false, span)?) - } - TypedefSyntax::Pointer(syntax) => { - Type::Pointer(self.validate_datatype(syntax, false, span)?) - } - TypedefSyntax::ConstPointer(syntax) => { - Type::ConstPointer(self.validate_datatype(syntax, false, span)?) - } - TypedefSyntax::Builtin(builtin) => Type::Builtin(*builtin), - TypedefSyntax::String => { - Type::List(TypeRef::Value(Rc::new(Type::Builtin(BuiltinType::Char)))) - } - TypedefSyntax::Bool => return Ok(self.doc.bool_ty.clone()), - TypedefSyntax::Ident { .. } => unreachable!(), - }))), - } - } - - fn validate_enum( - &self, - syntax: &EnumSyntax, - span: wast::Span, - ) -> Result { - let mut enum_scope = IdentValidation::new(); - let tag_repr = match &syntax.repr { - Some(repr) => self.validate_int_repr(repr, span)?, - None => IntRepr::U32, - }; - let cases = syntax - .members - .iter() - .map(|i| { - let name = enum_scope.introduce(i.item.name(), self.location(i.item.span()))?; - let docs = i.comments.docs(); - Ok(Case { - name, - tref: None, - docs, - }) - }) - .collect::, _>>()?; - - Ok(Variant { tag_repr, cases }) - } - - fn validate_tuple( - &self, - syntax: &TupleSyntax, - span: wast::Span, - ) -> Result { - let members = syntax - .types - .iter() - .enumerate() - .map(|(i, ty)| { - Ok(RecordMember { - name: Id::new(i.to_string()), - tref: self.validate_datatype(ty, false, span)?, - docs: String::new(), - }) - }) - .collect::, _>>()?; - - Ok(RecordDatatype { - kind: RecordKind::Tuple, - members, - }) - } - - fn validate_expected( - &self, - syntax: &ExpectedSyntax, - span: wast::Span, - ) -> Result { - let ok_ty = match &syntax.ok { - Some(ok) => Some(self.validate_datatype(ok, false, span)?), - None => None, - }; - let err_ty = match &syntax.err { - Some(err) => Some(self.validate_datatype(err, false, span)?), - None => None, - }; - Ok(Variant { - tag_repr: IntRepr::U32, - cases: vec![ - Case { - name: Id::new("ok"), - tref: ok_ty, - docs: String::new(), - }, - Case { - name: Id::new("err"), - tref: err_ty, - docs: String::new(), - }, - ], - }) - } - - fn validate_flags( - &self, - syntax: &FlagsSyntax, - span: wast::Span, - ) -> Result { - let repr = match syntax.repr { - Some(ty) => self.validate_int_repr(&ty, span)?, - None => IntRepr::U32, - }; - let mut flags_scope = IdentValidation::new(); - let mut members = Vec::new(); - for flag in syntax.flags.iter() { - let name = flags_scope.introduce(flag.item.name(), self.location(flag.item.span()))?; - let docs = flag.comments.docs(); - members.push(RecordMember { - name, - docs, - tref: self.doc.bool_ty.clone(), - }); - } - Ok(RecordDatatype { - kind: RecordKind::Bitflags(repr), - members, - }) - } - - fn validate_record( - &self, - syntax: &RecordSyntax, - _span: wast::Span, - ) -> Result { - let mut member_scope = IdentValidation::new(); - let members = syntax - .fields - .iter() - .map(|f| { - let name = member_scope - .introduce(f.item.name.name(), self.location(f.item.name.span()))?; - let tref = self.validate_datatype(&f.item.type_, false, f.item.name.span())?; - let docs = f.comments.docs(); - Ok(RecordMember { name, tref, docs }) - }) - .collect::, _>>()?; - - Ok(RecordDatatype { - kind: RecordKind::Other, - members, - }) - } - - fn validate_union( - &self, - syntax: &UnionSyntax, - span: wast::Span, - ) -> Result { - let (tag_repr, names) = self.union_tag_repr(&syntax.tag, span)?; - - if let Some(names) = &names { - if names.len() != syntax.fields.len() { - return Err(ValidationError::UnionSizeMismatch { - expected: names.len(), - found: syntax.fields.len(), - location: self.location(span), - }); - } - } - - let cases = syntax - .fields - .iter() - .enumerate() - .map(|(i, case)| { - Ok(Case { - name: match &names { - Some(names) => names[i].clone(), - None => Id::new(i.to_string()), - }, - tref: Some(self.validate_datatype(&case.item, false, span)?), - docs: case.comments.docs(), - }) - }) - .collect::, _>>()?; - Ok(Variant { tag_repr, cases }) - } - - fn validate_variant( - &self, - syntax: &VariantSyntax, - span: wast::Span, - ) -> Result { - let (tag_repr, names) = self.union_tag_repr(&syntax.tag, span)?; - - if let Some(names) = &names { - if names.len() != syntax.cases.len() { - return Err(ValidationError::UnionSizeMismatch { - expected: names.len(), - found: syntax.cases.len(), - location: self.location(span), - }); - } - } - - let mut name_set = names - .as_ref() - .map(|names| names.iter().collect::>()); - - let mut cases = syntax - .cases - .iter() - .map(|case| { - let name = Id::new(case.item.name.name()); - if let Some(names) = &mut name_set { - if !names.remove(&name) { - return Err(ValidationError::InvalidUnionField { - name: name.as_str().to_string(), - location: self.location(case.item.name.span()), - reason: format!("does not correspond to variant in tag `tag`"), - }); - } - } - Ok(Case { - name: Id::new(case.item.name.name()), - tref: match &case.item.ty { - Some(ty) => { - Some(self.validate_datatype(ty, false, case.item.name.span())?) - } - None => None, - }, - docs: case.comments.docs(), - }) - }) - .collect::, _>>()?; - - // If we have an explicit tag with an enum then that's instructing us to - // reorder cases based on the order of the enum itself, so do that here. - if let Some(names) = names { - let name_pos = names - .iter() - .enumerate() - .map(|(i, name)| (name, i)) - .collect::>(); - cases.sort_by_key(|c| name_pos[&&c.name]); - } - - Ok(Variant { tag_repr, cases }) - } - - fn union_tag_repr( - &self, - tag: &Option>>, - span: wast::Span, - ) -> Result<(IntRepr, Option>), ValidationError> { - let ty = match tag { - Some(tag) => self.validate_datatype(tag, false, span)?, - None => return Ok((IntRepr::U32, None)), - }; - match &**ty.type_() { - Type::Variant(e) => { - let mut names = Vec::new(); - for c in e.cases.iter() { - if c.tref.is_some() { - return Err(ValidationError::InvalidUnionTag { - location: self.location(span), - reason: format!("all variant cases should have empty payloads"), - }); - } - names.push(c.name.clone()); - } - return Ok((e.tag_repr, Some(names))); - } - Type::Builtin(BuiltinType::U8 { .. }) => return Ok((IntRepr::U8, None)), - Type::Builtin(BuiltinType::U16) => return Ok((IntRepr::U16, None)), - Type::Builtin(BuiltinType::U32 { .. }) => return Ok((IntRepr::U32, None)), - Type::Builtin(BuiltinType::U64) => return Ok((IntRepr::U64, None)), - _ => {} - } - - Err(ValidationError::WrongKindName { - name: "tag".to_string(), - location: self.location(span), - expected: "enum or builtin", - got: ty.type_().kind(), - }) - } - - fn validate_handle( - &self, - _syntax: &HandleSyntax, - _span: wast::Span, - ) -> Result { - Ok(HandleDatatype {}) - } - - fn validate_int_repr( - &self, - type_: &BuiltinType, - span: wast::Span, - ) -> Result { - match type_ { - BuiltinType::U8 { .. } => Ok(IntRepr::U8), - BuiltinType::U16 => Ok(IntRepr::U16), - BuiltinType::U32 { .. } => Ok(IntRepr::U32), - BuiltinType::U64 => Ok(IntRepr::U64), - _ => Err(ValidationError::InvalidRepr { - repr: type_.clone(), - location: self.location(span), - }), - } - } -} - -struct ModuleValidation<'a> { - doc: &'a DocValidationScope<'a>, - scope: IdentValidation, - pub entries: HashMap, -} - -impl<'a> ModuleValidation<'a> { - fn new(doc: &'a DocValidationScope<'a>) -> Self { - Self { - doc, - scope: IdentValidation::new(), - entries: HashMap::new(), - } - } - - fn validate_decl( - &mut self, - decl: &Documented, - ) -> Result { - match &decl.item { - ModuleDeclSyntax::Import(syntax) => { - let loc = self.doc.location(syntax.name_loc); - let name = self.scope.introduce(syntax.name, loc)?; - let variant = match syntax.type_ { - ImportTypeSyntax::Memory => ModuleImportVariant::Memory, - }; - let rc_import = Rc::new(ModuleImport { - name: name.clone(), - variant, - docs: decl.comments.docs(), - }); - self.entries - .insert(name, ModuleEntry::Import(Rc::downgrade(&rc_import))); - Ok(ModuleDefinition::Import(rc_import)) - } - ModuleDeclSyntax::Func(syntax) => { - let loc = self.doc.location(syntax.export_loc); - let name = self.scope.introduce(syntax.export, loc)?; - let mut argnames = IdentValidation::new(); - let params = syntax - .params - .iter() - .map(|f| { - Ok(InterfaceFuncParam { - name: argnames.introduce( - f.item.name.name(), - self.doc.location(f.item.name.span()), - )?, - tref: self.doc.validate_datatype( - &f.item.type_, - false, - f.item.name.span(), - )?, - docs: f.comments.docs(), - }) - }) - .collect::, _>>()?; - let results = syntax - .results - .iter() - .map(|f| { - let tref = - self.doc - .validate_datatype(&f.item.type_, false, f.item.name.span())?; - Ok(InterfaceFuncParam { - name: argnames.introduce( - f.item.name.name(), - self.doc.location(f.item.name.span()), - )?, - tref, - docs: f.comments.docs(), - }) - }) - .collect::, _>>()?; - let noreturn = syntax.noreturn; - let abi = Abi::Preview1; - abi.validate(¶ms, &results) - .map_err(|reason| ValidationError::Abi { - reason, - location: self.doc.location(syntax.export_loc), - })?; - let rc_func = Rc::new(InterfaceFunc { - abi, - name: name.clone(), - params, - results, - noreturn, - docs: decl.comments.docs(), - }); - self.entries - .insert(name, ModuleEntry::Func(Rc::downgrade(&rc_func))); - Ok(ModuleDefinition::Func(rc_func)) - } - } - } -} diff --git a/proposals/random/tools/witx/tests/witxt.rs b/proposals/random/tools/witx/tests/witxt.rs deleted file mode 100644 index 7c002fe1b..000000000 --- a/proposals/random/tools/witx/tests/witxt.rs +++ /dev/null @@ -1,656 +0,0 @@ -//! You can run this test suite with: -//! -//! cargo test --test witxt -//! -//! An argument can be passed as well to filter, based on filename, which test -//! to run -//! -//! cargo test --test witxt foo.witxt - -use anyhow::{anyhow, bail, Context, Result}; -use rayon::prelude::*; -use std::collections::HashMap; -use std::path::{Path, PathBuf}; -use std::str; -use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; -use wast::parser::{self, Parse, ParseBuffer, Parser}; -use witx::{Documentation, Instruction, Representable, WasmType}; - -fn main() { - let tests = find_tests(); - let filter = std::env::args().nth(1); - - let tests = tests - .par_iter() - .filter_map(|test| { - if let Some(filter) = &filter { - if let Some(s) = test.to_str() { - if !s.contains(filter) { - return None; - } - } - } - let contents = std::fs::read(test).unwrap(); - Some((test, contents)) - }) - .collect::>(); - - println!("running {} test files\n", tests.len()); - - let ntests = AtomicUsize::new(0); - let errors = tests - .par_iter() - .filter_map(|(test, contents)| { - WitxtRunner { - ntests: &ntests, - documents: HashMap::new(), - } - .run(test, contents) - .err() - }) - .collect::>(); - - if !errors.is_empty() { - for msg in errors.iter() { - eprintln!("{:?}", msg); - } - - panic!("{} tests failed", errors.len()) - } - - println!( - "test result: ok. {} directives passed\n", - ntests.load(SeqCst) - ); -} - -/// Recursively finds all tests in a whitelisted set of directories which we -/// then load up and test in parallel. -fn find_tests() -> Vec { - let mut tests = Vec::new(); - find_tests("tests/witxt".as_ref(), &mut tests); - tests.sort(); - return tests; - - fn find_tests(path: &Path, tests: &mut Vec) { - for f in path.read_dir().unwrap() { - let f = f.unwrap(); - if f.file_type().unwrap().is_dir() { - find_tests(&f.path(), tests); - continue; - } - - match f.path().extension().and_then(|s| s.to_str()) { - Some("witxt") => {} - _ => continue, - } - tests.push(f.path()); - } - } -} - -struct WitxtRunner<'a> { - ntests: &'a AtomicUsize, - documents: HashMap, -} - -impl WitxtRunner<'_> { - fn run(&mut self, test: &Path, contents: &[u8]) -> Result<()> { - let contents = str::from_utf8(contents)?; - macro_rules! adjust { - ($e:expr) => {{ - let mut e = wast::Error::from($e); - e.set_path(test); - e.set_text(contents); - e - }}; - } - let buf = ParseBuffer::new(contents).map_err(|e| adjust!(e))?; - let witxt = parser::parse::(&buf).map_err(|e| adjust!(e))?; - - let errors = witxt - .directives - .into_iter() - .filter_map(|directive| { - let (line, col) = directive.span().linecol_in(contents); - self.test_directive(contents, test, directive) - .with_context(|| { - format!( - "failed directive on {}:{}:{}", - test.display(), - line + 1, - col + 1 - ) - }) - .err() - }) - .collect::>(); - if errors.is_empty() { - return Ok(()); - } - let mut s = format!("{} test failures in {}:", errors.len(), test.display()); - for mut error in errors { - if let Some(err) = error.downcast_mut::() { - err.set_path(test); - err.set_text(contents); - } - s.push_str("\n\n\t--------------------------------\n\n\t"); - s.push_str(&format!("{:?}", error).replace("\n", "\n\t")); - } - bail!("{}", s) - } - - fn test_directive( - &mut self, - contents: &str, - test: &Path, - directive: WitxtDirective, - ) -> Result<()> { - self.bump_ntests(); - match directive { - WitxtDirective::Witx(witx) => { - let doc = witx.document(contents, test)?; - self.assert_roundtrip(&doc) - .context("failed to round-trip the document")?; - self.assert_md(&doc)?; - if let Some(name) = witx.id { - self.documents.insert(name.name().to_string(), doc); - } - } - WitxtDirective::AssertInvalid { witx, message, .. } => { - let err = match witx.document(contents, test) { - Ok(_) => bail!("witx was valid when it shouldn't be"), - Err(e) => format!("{:?}", anyhow::Error::from(e)), - }; - if !err.contains(message) { - bail!("expected error {:?}\nfound error {}", message, err); - } - } - WitxtDirective::AssertRepresentable { repr, t1, t2, .. } => { - let (t1m, t1t) = t1; - let (t2m, t2t) = t2; - let t1d = self - .documents - .get(t1m.name()) - .ok_or_else(|| anyhow!("no document named {:?}", t1m.name()))?; - let t2d = self - .documents - .get(t2m.name()) - .ok_or_else(|| anyhow!("no document named {:?}", t2m.name()))?; - let t1 = t1d - .typename(&witx::Id::new(t1t)) - .ok_or_else(|| anyhow!("no type named {:?}", t1t))?; - let t2 = t2d - .typename(&witx::Id::new(t2t)) - .ok_or_else(|| anyhow!("no type named {:?}", t2t))?; - match (repr, t1.type_().representable(&t2.type_())) { - (RepEquality::Eq, witx::RepEquality::Eq) - | (RepEquality::Superset, witx::RepEquality::Superset) - | (RepEquality::NotEq, witx::RepEquality::NotEq) => {} - (a, b) => { - bail!("expected {:?} representation, got {:?}", a, b); - } - } - } - WitxtDirective::AssertAbi { - witx, - wasm, - interface, - wasm_signature: (wasm_params, wasm_results), - .. - } => { - let doc = witx.document(contents, test)?; - let module = doc.modules().next().ok_or_else(|| anyhow!("no modules"))?; - let func = module.funcs().next().ok_or_else(|| anyhow!("no funcs"))?; - - let (params, results) = func.wasm_signature(); - if params != wasm_params { - bail!("expected params {:?}, found {:?}", wasm_params, params); - } - if results != wasm_results { - bail!("expected results {:?}, found {:?}", wasm_results, results); - } - - let mut check = AbiBindgen { - abi: wasm.instrs.iter(), - err: None, - contents, - }; - func.call_wasm(&module.name, &mut check); - check.check()?; - check.abi = interface.instrs.iter(); - func.call_interface(&module.name, &mut check); - check.check()?; - } - } - Ok(()) - } - - fn assert_roundtrip(&self, doc: &witx::Document) -> Result<()> { - self.bump_ntests(); - let back_to_sexprs = format!("{}", doc); - let doc2 = witx::parse(&back_to_sexprs)?; - if *doc == doc2 { - return Ok(()); - } - - // Try to get a more specific error message that isn't thousands of - // lines long of debug representations. - for type_ in doc.typenames() { - let type2 = match doc2.typename(&type_.name) { - Some(t) => t, - None => bail!("doc2 missing datatype"), - }; - if type_ != type2 { - bail!("types are not equal\n{:?}\n !=\n{:?}", type_, type2); - } - } - for mod_ in doc.modules() { - let mod2 = match doc2.module(&mod_.name) { - Some(m) => m, - None => bail!("doc2 missing module"), - }; - for import in mod_.imports() { - let import2 = match mod2.import(&import.name) { - Some(i) => i, - None => bail!("mod2 missing import"), - }; - assert_eq!(import, import2); - } - for func in mod_.funcs() { - let func2 = match mod2.func(&func.name) { - Some(f) => f, - None => bail!("mod2 missing func"), - }; - assert_eq!(func, func2); - } - } - bail!("{:?} != {:?}", doc, doc2) - } - - fn assert_md(&self, doc: &witx::Document) -> Result<()> { - self.bump_ntests(); - doc.to_md(); - Ok(()) - } - - fn bump_ntests(&self) { - self.ntests.fetch_add(1, SeqCst); - } -} - -struct AbiBindgen<'a> { - abi: std::slice::Iter<'a, (wast::Span, &'a str)>, - err: Option, - contents: &'a str, -} - -impl AbiBindgen<'_> { - fn check(&mut self) -> Result<()> { - match self.err.take() { - None => Ok(()), - Some(e) => Err(e), - } - } - - fn assert(&mut self, name: &str) { - if self.err.is_some() { - return; - } - match self.abi.next() { - Some((_, s)) if *s == name => {} - Some((span, s)) => { - let (line, col) = span.linecol_in(self.contents); - self.err = Some(anyhow!( - "line {}:{} - expected `{}` found `{}`", - line + 1, - col + 1, - name, - s, - )); - } - None => { - self.err = Some(anyhow!( - "extra instruction `{}` found when none was expected", - name - )); - } - } - } -} - -impl witx::Bindgen for AbiBindgen<'_> { - type Operand = (); - fn emit( - &mut self, - inst: &Instruction<'_>, - _operands: &mut Vec, - results: &mut Vec, - ) { - use witx::Instruction::*; - match inst { - GetArg { nth } => self.assert(&format!("get-arg{}", nth)), - AddrOf => self.assert("addr-of"), - I32FromChar => self.assert("i32.from_char"), - I64FromU64 => self.assert("i64.from_u64"), - I64FromS64 => self.assert("i64.from_s64"), - I32FromU32 => self.assert("i32.from_u32"), - I32FromS32 => self.assert("i32.from_s32"), - I32FromUsize => self.assert("i32.from_usize"), - I32FromU16 => self.assert("i32.from_u16"), - I32FromS16 => self.assert("i32.from_s16"), - I32FromU8 => self.assert("i32.from_u8"), - I32FromS8 => self.assert("i32.from_s8"), - I32FromChar8 => self.assert("i32.from_char8"), - I32FromPointer => self.assert("i32.from_pointer"), - I32FromConstPointer => self.assert("i32.from_const_pointer"), - I32FromHandle { .. } => self.assert("i32.from_handle"), - ListPointerLength => self.assert("list.pointer_length"), - ListFromPointerLength { .. } => self.assert("list.from_pointer_length"), - F32FromIf32 => self.assert("f32.from_if32"), - F64FromIf64 => self.assert("f64.from_if64"), - CallWasm { .. } => self.assert("call.wasm"), - CallInterface { .. } => self.assert("call.interface"), - S8FromI32 => self.assert("s8.from_i32"), - U8FromI32 => self.assert("u8.from_i32"), - S16FromI32 => self.assert("s16.from_i32"), - U16FromI32 => self.assert("u16.from_i32"), - S32FromI32 => self.assert("s32.from_i32"), - U32FromI32 => self.assert("u32.from_i32"), - S64FromI64 => self.assert("s64.from_i64"), - U64FromI64 => self.assert("u64.from_i64"), - CharFromI32 => self.assert("char.from_i32"), - Char8FromI32 => self.assert("char8.from_i32"), - UsizeFromI32 => self.assert("usize.from_i32"), - If32FromF32 => self.assert("if32.from_f32"), - If64FromF64 => self.assert("if64.from_f64"), - HandleFromI32 { .. } => self.assert("handle.from_i32"), - PointerFromI32 { .. } => self.assert("pointer.from_i32"), - ConstPointerFromI32 { .. } => self.assert("const_pointer.from_i32"), - ReturnPointerGet { n } => self.assert(&format!("return_pointer.get{}", n)), - ResultLift => self.assert("result.lift"), - ResultLower { .. } => self.assert("result.lower"), - EnumLift { .. } => self.assert("enum.lift"), - EnumLower { .. } => self.assert("enum.lower"), - TupleLift { .. } => self.assert("tuple.lift"), - TupleLower { .. } => self.assert("tuple.lower"), - ReuseReturn => self.assert("reuse_return"), - Load { .. } => self.assert("load"), - Store { .. } => self.assert("store"), - Return { .. } => self.assert("return"), - VariantPayload => self.assert("variant-payload"), - I32FromBitflags { .. } => self.assert("i32.from_bitflags"), - BitflagsFromI32 { .. } => self.assert("bitflags.from_i32"), - I64FromBitflags { .. } => self.assert("i64.from_bitflags"), - BitflagsFromI64 { .. } => self.assert("bitflags.from_i64"), - } - for _ in 0..inst.results_len() { - results.push(()); - } - } - - fn allocate_space(&mut self, _: usize, _: &witx::NamedType) { - self.assert("allocate-space"); - } - - fn push_block(&mut self) { - self.assert("block.push"); - } - - fn finish_block(&mut self, _operand: Option) { - self.assert("block.finish"); - } -} - -mod kw { - wast::custom_keyword!(assert_invalid); - wast::custom_keyword!(assert_representable); - wast::custom_keyword!(assert_abi); - wast::custom_keyword!(witx); - wast::custom_keyword!(eq); - wast::custom_keyword!(noteq); - wast::custom_keyword!(load); - wast::custom_keyword!(superset); - wast::custom_keyword!(call_wasm); - wast::custom_keyword!(call_interface); - wast::custom_keyword!(param); - wast::custom_keyword!(result); - wast::custom_keyword!(wasm); - wast::custom_keyword!(i32); - wast::custom_keyword!(i64); - wast::custom_keyword!(f32); - wast::custom_keyword!(f64); -} - -struct Witxt<'a> { - directives: Vec>, -} - -impl<'a> Parse<'a> for Witxt<'a> { - fn parse(parser: Parser<'a>) -> parser::Result { - let mut directives = Vec::new(); - while !parser.is_empty() { - directives.push(parser.parens(|p| p.parse())?); - } - Ok(Witxt { directives }) - } -} - -enum WitxtDirective<'a> { - Witx(Witx<'a>), - AssertInvalid { - span: wast::Span, - witx: Witx<'a>, - message: &'a str, - }, - AssertRepresentable { - span: wast::Span, - repr: RepEquality, - t1: (wast::Id<'a>, &'a str), - t2: (wast::Id<'a>, &'a str), - }, - AssertAbi { - span: wast::Span, - witx: Witx<'a>, - wasm_signature: (Vec, Vec), - wasm: Abi<'a>, - interface: Abi<'a>, - }, -} - -impl WitxtDirective<'_> { - fn span(&self) -> wast::Span { - match self { - WitxtDirective::Witx(w) => w.span, - WitxtDirective::AssertInvalid { span, .. } - | WitxtDirective::AssertAbi { span, .. } - | WitxtDirective::AssertRepresentable { span, .. } => *span, - } - } -} - -impl<'a> Parse<'a> for WitxtDirective<'a> { - fn parse(parser: Parser<'a>) -> parser::Result { - let mut l = parser.lookahead1(); - if l.peek::() { - Ok(WitxtDirective::Witx(parser.parse()?)) - } else if l.peek::() { - let span = parser.parse::()?.0; - Ok(WitxtDirective::AssertInvalid { - span, - witx: parser.parens(|p| p.parse())?, - message: parser.parse()?, - }) - } else if l.peek::() { - let span = parser.parse::()?.0; - Ok(WitxtDirective::AssertRepresentable { - span, - repr: parser.parse()?, - t1: (parser.parse()?, parser.parse()?), - t2: (parser.parse()?, parser.parse()?), - }) - } else if l.peek::() { - let span = parser.parse::()?.0; - Ok(WitxtDirective::AssertAbi { - span, - witx: parser.parens(|p| p.parse())?, - wasm_signature: parser.parens(|p| { - p.parse::()?; - let mut params = Vec::new(); - let mut results = Vec::new(); - if p.peek2::() { - p.parens(|p| { - p.parse::()?; - while !p.is_empty() { - params.push(parse_wasmtype(p)?); - } - Ok(()) - })?; - } - if p.peek2::() { - p.parens(|p| { - p.parse::()?; - while !p.is_empty() { - results.push(parse_wasmtype(p)?); - } - Ok(()) - })?; - } - Ok((params, results)) - })?, - wasm: parser.parens(|p| { - p.parse::()?; - p.parse() - })?, - interface: parser.parens(|p| { - p.parse::()?; - p.parse() - })?, - }) - } else { - Err(l.error()) - } - } -} - -fn parse_wasmtype(p: Parser<'_>) -> parser::Result { - let mut l = p.lookahead1(); - if l.peek::() { - p.parse::()?; - Ok(WasmType::I32) - } else if l.peek::() { - p.parse::()?; - Ok(WasmType::I64) - } else if l.peek::() { - p.parse::()?; - Ok(WasmType::F32) - } else if l.peek::() { - p.parse::()?; - Ok(WasmType::F64) - } else { - Err(l.error()) - } -} - -struct Witx<'a> { - span: wast::Span, - id: Option>, - def: WitxDef<'a>, -} - -enum WitxDef<'a> { - Fs(Vec<&'a str>), - Inline(Vec>>), -} - -impl Witx<'_> { - fn document(&self, contents: &str, file: &Path) -> Result { - match &self.def { - WitxDef::Inline(decls) => { - let mut validator = witx::DocValidation::new(); - let mut definitions = Vec::new(); - for decl in decls { - validator - .scope(contents, file) - .validate_decl(&decl.item, &decl.comments, &mut definitions) - .map_err(witx::WitxError::Validation)?; - } - Ok(validator.into_document(definitions)) - } - WitxDef::Fs(paths) => { - let parent = file.parent().unwrap(); - let paths = paths.iter().map(|p| parent.join(p)).collect::>(); - Ok(witx::load(&paths)?) - } - } - } -} - -impl<'a> Parse<'a> for Witx<'a> { - fn parse(parser: Parser<'a>) -> parser::Result { - let span = parser.parse::()?.0; - let id = parser.parse()?; - - let def = if parser.peek2::() { - parser.parens(|p| { - p.parse::()?; - let mut paths = Vec::new(); - while !p.is_empty() { - paths.push(p.parse()?); - } - Ok(WitxDef::Fs(paths)) - })? - } else { - let mut decls = Vec::new(); - while !parser.is_empty() { - decls.push(parser.parens(|p| p.parse())?); - } - WitxDef::Inline(decls) - }; - Ok(Witx { id, span, def }) - } -} - -#[derive(Debug)] -enum RepEquality { - Eq, - NotEq, - Superset, -} - -impl<'a> Parse<'a> for RepEquality { - fn parse(parser: Parser<'a>) -> parser::Result { - let mut l = parser.lookahead1(); - if l.peek::() { - parser.parse::()?; - Ok(RepEquality::Eq) - } else if l.peek::() { - parser.parse::()?; - Ok(RepEquality::NotEq) - } else if l.peek::() { - parser.parse::()?; - Ok(RepEquality::Superset) - } else { - Err(l.error()) - } - } -} - -struct Abi<'a> { - instrs: Vec<(wast::Span, &'a str)>, -} - -impl<'a> Parse<'a> for Abi<'a> { - fn parse(parser: Parser<'a>) -> parser::Result { - let mut instrs = Vec::new(); - while !parser.is_empty() { - instrs.push(parser.step(|cursor| { - let (kw, next) = cursor - .keyword() - .ok_or_else(|| cursor.error("expected keyword"))?; - Ok(((cursor.cur_span(), kw), next)) - })?); - } - Ok(Abi { instrs }) - } -} diff --git a/proposals/random/tools/witx/tests/witxt/abi.witxt b/proposals/random/tools/witx/tests/witxt/abi.witxt deleted file mode 100644 index ccdad7bf4..000000000 --- a/proposals/random/tools/witx/tests/witxt/abi.witxt +++ /dev/null @@ -1,490 +0,0 @@ -(assert_abi - (witx (module $x (@interface func (export "f")))) - (wasm) - (call_wasm call.wasm return) - (call_interface call.interface return) -) - -;; scalar arguments -(assert_abi - (witx (module $x (@interface func (export "f") (param $p u8)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_u8 call.wasm return) - (call_interface get-arg0 u8.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p s8)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_s8 call.wasm return) - (call_interface get-arg0 s8.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p u16)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_u16 call.wasm return) - (call_interface get-arg0 u16.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p s16)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_s16 call.wasm return) - (call_interface get-arg0 s16.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p u32)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_u32 call.wasm return) - (call_interface get-arg0 u32.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p s32)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_s32 call.wasm return) - (call_interface get-arg0 s32.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p u64)))) - (wasm (param i64)) - (call_wasm get-arg0 i64.from_u64 call.wasm return) - (call_interface get-arg0 u64.from_i64 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p s64)))) - (wasm (param i64)) - (call_wasm get-arg0 i64.from_s64 call.wasm return) - (call_interface get-arg0 s64.from_i64 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p f32)))) - (wasm (param f32)) - (call_wasm get-arg0 f32.from_if32 call.wasm return) - (call_interface get-arg0 if32.from_f32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p f64)))) - (wasm (param f64)) - (call_wasm get-arg0 f64.from_if64 call.wasm return) - (call_interface get-arg0 if64.from_f64 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p (@witx usize))))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_usize call.wasm return) - (call_interface get-arg0 usize.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p (@witx char8))))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_char8 call.wasm return) - (call_interface get-arg0 char8.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p char)))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_char call.wasm return) - (call_interface get-arg0 char.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p (@witx pointer u8))))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_pointer call.wasm return) - (call_interface get-arg0 pointer.from_i32 call.interface return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (param $p (@witx const_pointer u8))))) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_const_pointer call.wasm return) - (call_interface get-arg0 const_pointer.from_i32 call.interface return) -) - -;; flags parameter -(assert_abi - (witx - (typename $a (flags $x $y)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_bitflags call.wasm return) - (call_interface get-arg0 bitflags.from_i32 call.interface return) -) -(assert_abi - (witx - (typename $a (flags (@witx repr u64) $x $y)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i64)) - (call_wasm get-arg0 i64.from_bitflags call.wasm return) - (call_interface get-arg0 bitflags.from_i64 call.interface return) -) - -;; struct parameter -(assert_abi - (witx - (typename $a (record (field $x u8))) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 addr-of call.wasm return) - (call_interface get-arg0 load call.interface return) -) - -;; handle parameter -(assert_abi - (witx - (typename $a (handle)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 i32.from_handle call.wasm return) - (call_interface get-arg0 handle.from_i32 call.interface return) -) - -;; list parameter -(assert_abi - (witx - (module $x (@interface func (export "f") (param $p (list u8)))) - ) - (wasm (param i32 i32)) - (call_wasm get-arg0 list.pointer_length call.wasm return) - (call_interface get-arg0 get-arg1 list.from_pointer_length call.interface return) -) - -;; variant parameter -- some not allowed at this time -(assert_abi - (witx - (typename $a (enum $b)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 enum.lower call.wasm return) - (call_interface get-arg0 enum.lift call.interface return) -) -(assert_abi - (witx - (typename $a (union f32)) - (module $x (@interface func (export "f") (param $p $a))) - ) - (wasm (param i32)) - (call_wasm get-arg0 addr-of call.wasm return) - (call_interface get-arg0 load call.interface return) -) - -;; scalar returns -(assert_abi - (witx (module $x (@interface func (export "f") (result $p u8)))) - (wasm (result i32)) - (call_wasm call.wasm u8.from_i32 return) - (call_interface call.interface i32.from_u8 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p s8)))) - (wasm (result i32)) - (call_wasm call.wasm s8.from_i32 return) - (call_interface call.interface i32.from_s8 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p u16)))) - (wasm (result i32)) - (call_wasm call.wasm u16.from_i32 return) - (call_interface call.interface i32.from_u16 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p s16)))) - (wasm (result i32)) - (call_wasm call.wasm s16.from_i32 return) - (call_interface call.interface i32.from_s16 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p u32)))) - (wasm (result i32)) - (call_wasm call.wasm u32.from_i32 return) - (call_interface call.interface i32.from_u32 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p s32)))) - (wasm (result i32)) - (call_wasm call.wasm s32.from_i32 return) - (call_interface call.interface i32.from_s32 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p u64)))) - (wasm (result i64)) - (call_wasm call.wasm u64.from_i64 return) - (call_interface call.interface i64.from_u64 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p s64)))) - (wasm (result i64)) - (call_wasm call.wasm s64.from_i64 return) - (call_interface call.interface i64.from_s64 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p f32)))) - (wasm (result f32)) - (call_wasm call.wasm if32.from_f32 return) - (call_interface call.interface f32.from_if32 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p f64)))) - (wasm (result f64)) - (call_wasm call.wasm if64.from_f64 return) - (call_interface call.interface f64.from_if64 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p (@witx usize))))) - (wasm (result i32)) - (call_wasm call.wasm usize.from_i32 return) - (call_interface call.interface i32.from_usize return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p (@witx char8))))) - (wasm (result i32)) - (call_wasm call.wasm char8.from_i32 return) - (call_interface call.interface i32.from_char8 return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p char)))) - (wasm (result i32)) - (call_wasm call.wasm char.from_i32 return) - (call_interface call.interface i32.from_char return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p (@witx pointer u8))))) - (wasm (result i32)) - (call_wasm call.wasm pointer.from_i32 return) - (call_interface call.interface i32.from_pointer return) -) -(assert_abi - (witx (module $x (@interface func (export "f") (result $p (@witx const_pointer u8))))) - (wasm (result i32)) - (call_wasm call.wasm const_pointer.from_i32 return) - (call_interface call.interface i32.from_const_pointer return) -) - -;; flags return -(assert_abi - (witx - (typename $a (flags $x $y)) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (result i32)) - (call_wasm call.wasm bitflags.from_i32 return) - (call_interface call.interface i32.from_bitflags return) -) -(assert_abi - (witx - (typename $a (flags (@witx repr u64) $x $y)) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (result i64)) - (call_wasm call.wasm bitflags.from_i64 return) - (call_interface call.interface i64.from_bitflags return) -) - -;; handle return -(assert_abi - (witx - (typename $a (handle)) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (result i32)) - (call_wasm call.wasm handle.from_i32 return) - (call_interface call.interface i32.from_handle return) -) - -;; struct return -- not supported -(assert_invalid - (witx - (typename $a (record (field $x u8))) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: invalid return type" -) - -;; list return -- not supported -(assert_invalid - (witx - (module $x (@interface func (export "f") (result $p (list u8)))) - ) - "ABI error: invalid return type" -) - -;; variant return -- only some allowed -(assert_invalid - (witx - (typename $a (enum $b)) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: invalid return type" -) -(assert_invalid - (witx - (typename $a (union s32 f32)) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: invalid return type" -) -(assert_invalid - (witx - (typename $a (expected (error f32))) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: only named types are allowed in results" -) -(assert_invalid - (witx - (typename $errno (enum $success $bad)) - (typename $a (expected f32 (error $errno))) - (module $x (@interface func (export "f") (result $p $a))) - ) - "ABI error: only named types are allowed in results" -) - -;; Result<(), $errno> -(assert_abi - (witx - (typename $errno (enum $success $bad)) - (typename $a (expected (error $errno))) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (result i32)) - - (call_wasm - call.wasm - ;; ok block, nothing happens - block.push - block.finish - ;; err block, we lift the return value as the num - block.push - reuse_return - enum.lift - block.finish - ;; consumes 2 blocks and uses the return value of the call to discriminate - result.lift - return) - - (call_interface - call.interface - - ;; ok block, nothing happens - block.push - block.finish - - ;; err block, lift the enum - block.push - variant-payload - enum.lower - block.finish - - ;; consume the 2 blocks and lower based on the call - result.lower - return) -) - -;; Result<$ty, $errno> -(assert_abi - (witx - (typename $errno (enum $success $bad)) - (typename $size u32) - (typename $a (expected $size (error $errno))) - (module $x (@interface func (export "f") (result $p $a))) - ) - (wasm (param i32) (result i32)) - - (call_wasm - ;; make space for the return value and push its pointer - allocate-space - return_pointer.get0 - - call.wasm - - ;; ok block, load the return pointer and have it be the result for the `Ok` - block.push - return_pointer.get0 - load - block.finish - - block.push - reuse_return - enum.lift - block.finish - - result.lift - return) - - (call_interface - call.interface - - ;; store the successful result at the first return pointer (the first param) - block.push - variant-payload - get-arg0 - store - block.finish - - block.push - variant-payload - enum.lower - block.finish - - result.lower - return) -) - -;; Result<($a, $b), $errno> -(assert_abi - (witx - (typename $errno (enum $success $bad)) - (typename $size u32) - (typename $other (record (field $a $size))) - (module $x (@interface func (export "f") - (result $p (expected (tuple $size $other) (error $errno))))) - ) - (wasm (param i32 i32) (result i32)) - - (call_wasm - allocate-space - return_pointer.get0 - allocate-space - return_pointer.get1 - - call.wasm - - block.push - return_pointer.get0 - load - return_pointer.get1 - load - tuple.lift - block.finish - - block.push - reuse_return - enum.lift - block.finish - - result.lift - return) - - (call_interface - call.interface - - ;; note the reverse order since we're consuming the results of lowering the - ;; tuple - block.push - variant-payload - tuple.lower - get-arg1 - store - get-arg0 - store - block.finish - - block.push - variant-payload - enum.lower - block.finish - - result.lower - return) -) diff --git a/proposals/random/tools/witx/tests/witxt/anonymous.witxt b/proposals/random/tools/witx/tests/witxt/anonymous.witxt deleted file mode 100644 index 0ed3bc0d2..000000000 --- a/proposals/random/tools/witx/tests/witxt/anonymous.witxt +++ /dev/null @@ -1,56 +0,0 @@ -;; Ensure that anonymous structured types are not allowed in type positions at -;; this time, everything has to be named to assist in binding in languages. - -(assert_invalid - (witx - (typename $a (@witx pointer (record (field $b u8)))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (@witx pointer (union))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (@witx pointer (enum $b))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (@witx pointer (flags $b))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (@witx pointer (handle))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $a (record (field $b (record (field $c u8))))) - ) - "Anonymous structured types") - -(assert_invalid - (witx - (typename $tag (enum $c)) - (typename $a (record (field $b (union)))) - ) - "Anonymous structured types") - - -;; pointers don't count for anonymous indirections -(witx - (typename $a (@witx pointer u8))) - -(witx - (typename $a (@witx pointer (@witx const_pointer u8)))) - -(witx - (typename $a (record (field $b (@witx pointer u8))))) diff --git a/proposals/random/tools/witx/tests/witxt/multimodule.witxt b/proposals/random/tools/witx/tests/witxt/multimodule.witxt deleted file mode 100644 index d8b6559ac..000000000 --- a/proposals/random/tools/witx/tests/witxt/multimodule.witxt +++ /dev/null @@ -1,22 +0,0 @@ -;; B uses A, and C uses A. -(witx $multi - (load "multimodule/type_b.witx" "multimodule/type_c.witx") -) - -(witx $reference - (typename $a u32) - (typename $b (record (field $member_a $a))) - (typename $c (record (field $first_a $a) (field $second_a $a))) -) - -(assert_representable eq $reference "a" $multi "a") -(assert_representable eq $reference "b" $multi "b") -(assert_representable eq $reference "c" $multi "c") - -(assert_invalid - (witx - (load - "multimodule/type_a.witx" - "multimodule/redefine_a.witx") - ) - "Redefinition of name `a`") diff --git a/proposals/random/tools/witx/tests/witxt/multimodule/redefine_a.witx b/proposals/random/tools/witx/tests/witxt/multimodule/redefine_a.witx deleted file mode 100644 index e5d99d82c..000000000 --- a/proposals/random/tools/witx/tests/witxt/multimodule/redefine_a.witx +++ /dev/null @@ -1 +0,0 @@ -(typename $a u8) diff --git a/proposals/random/tools/witx/tests/witxt/multimodule/type_a.witx b/proposals/random/tools/witx/tests/witxt/multimodule/type_a.witx deleted file mode 100644 index 5499ff3db..000000000 --- a/proposals/random/tools/witx/tests/witxt/multimodule/type_a.witx +++ /dev/null @@ -1 +0,0 @@ -(typename $a u32) diff --git a/proposals/random/tools/witx/tests/witxt/multimodule/type_b.witx b/proposals/random/tools/witx/tests/witxt/multimodule/type_b.witx deleted file mode 100644 index fe169d3ec..000000000 --- a/proposals/random/tools/witx/tests/witxt/multimodule/type_b.witx +++ /dev/null @@ -1,2 +0,0 @@ -(use "type_a.witx") -(typename $b (record (field $member_a $a))) diff --git a/proposals/random/tools/witx/tests/witxt/multimodule/type_c.witx b/proposals/random/tools/witx/tests/witxt/multimodule/type_c.witx deleted file mode 100644 index f42aac2d0..000000000 --- a/proposals/random/tools/witx/tests/witxt/multimodule/type_c.witx +++ /dev/null @@ -1,2 +0,0 @@ -(use "type_a.witx") -(typename $c (record (field $first_a $a) (field $second_a $a))) diff --git a/proposals/random/tools/witx/tests/witxt/representation.witxt b/proposals/random/tools/witx/tests/witxt/representation.witxt deleted file mode 100644 index 53f71f196..000000000 --- a/proposals/random/tools/witx/tests/witxt/representation.witxt +++ /dev/null @@ -1,60 +0,0 @@ -;; type names don't matter -(witx $a - (typename $a (flags (@witx repr u8) $b $c))) -(witx $b - (typename $b (flags (@witx repr u8) $b $c))) - -(assert_representable eq $a "a" $b "b") -(assert_representable eq $b "b" $a "a") - -(; TODO: perhaps add assertions eventually for document-level representability? -;; flags -(witx $a - (typename $a (flags (@witx bitflags u8) $b $c))) -(witx $b - (typename $b (flags (@witx bitflags u8) $b $c $d))) - -(assert_representable noteq $b "b" $a "a") -(assert_representable superset $a "a" $b "b") - -(witx $c - (typename $c (flags (@witx bitflags u8) $b $e))) -(assert_representable noteq $a "a" $c "c") -(assert_representable noteq $c "c" $a "a") - -(witx $d - (typename $d (flags (@witx bitflags u16) $b $c))) -(assert_representable noteq $a "a" $d "d") -(assert_representable superset $d "d" $a "a") -(assert_representable superset $d "d" $b "b") -;) - -;; enums -(witx $a - (typename $a (enum $b $c))) -(witx $b - (typename $b (enum $b $c $d))) -(assert_representable superset $a "a" $b "b") -(assert_representable noteq $b "b" $a "a") - -(witx $c - (typename $c (enum (@witx tag u16) $b $c))) -(assert_representable superset $c "c" $a "a") -(assert_representable superset $c "c" $b "b") - -;; unions -(witx $a - (typename $tag (enum $b $c)) - (typename $a (union (@witx tag $tag) u32 f32))) -(witx $b - (typename $tag (enum $b $c $d)) - (typename $b (union (@witx tag $tag) u32 f32 f64))) -(assert_representable superset $a "a" $b "b") -(assert_representable noteq $b "b" $a "a") - -(witx $c - (typename $tag (enum $b $c)) - (typename $c (variant (@witx tag $tag) (case $c f32) (case $b u32)))) -(assert_representable eq $a "a" $c "c") -(assert_representable eq $c "c" $a "a") -(assert_representable superset $c "c" $b "b") diff --git a/proposals/random/tools/witx/tests/witxt/shorthand.witxt b/proposals/random/tools/witx/tests/witxt/shorthand.witxt deleted file mode 100644 index 960615f3c..000000000 --- a/proposals/random/tools/witx/tests/witxt/shorthand.witxt +++ /dev/null @@ -1,59 +0,0 @@ -(witx $a - (typename $a bool)) -(witx $b - (typename $a (variant (case $false) (case $true)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (expected (error)))) -(witx $b - (typename $a (variant (case $ok) (case $err)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (expected (error u32)))) -(witx $b - (typename $a (variant (case $ok) (case $err u32)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (expected u32 (error)))) -(witx $b - (typename $a (variant (case $ok u32) (case $err)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (expected u32 (error u64)))) -(witx $b - (typename $a (variant (case $ok u32) (case $err u64)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (flags $a $b))) -(witx $b - (typename $a (record (field $a bool) (field $b bool)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (enum $a $b))) -(witx $b - (typename $a (variant (case $a) (case $b)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a string)) -(witx $b - (typename $a (list char))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (tuple u32 u64))) -(witx $b - (typename $a (record (field $0 u32) (field $1 u64)))) -(assert_representable eq $a "a" $b "a") - -(witx $a - (typename $a (union u32 u64))) -(witx $b - (typename $a (variant (case $0 u32) (case $1 u64)))) -(assert_representable eq $a "a" $b "a") diff --git a/proposals/random/tools/witx/tests/witxt/simple.witxt b/proposals/random/tools/witx/tests/witxt/simple.witxt deleted file mode 100644 index af2403043..000000000 --- a/proposals/random/tools/witx/tests/witxt/simple.witxt +++ /dev/null @@ -1,12 +0,0 @@ -(witx) - -(witx - (typename $x u32) -) - -(assert_invalid - (witx - (typename $x u32) - (typename $x u32) - ) - "Redefinition of name `x`") diff --git a/proposals/random/tools/witx/tests/witxt/union.witxt b/proposals/random/tools/witx/tests/witxt/union.witxt deleted file mode 100644 index 92be3dcd9..000000000 --- a/proposals/random/tools/witx/tests/witxt/union.witxt +++ /dev/null @@ -1,97 +0,0 @@ - -(witx - (typename $u (union u8)) -) -(witx - (typename $tag (enum (@witx tag u8) $c)) - (typename $u (union (@witx tag $tag) u8)) -) - -(witx - (typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $a) (case $b u16))) -) - -(witx - (typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $a) (case $b))) -) - - -(witx - (typename $u - (union - u8 - u16 - u32 - u64 - s8 - s16 - s32 - s64 - f32 - f64 - (@witx usize) - (@witx char8) - ) - ) -) - -(assert_invalid - (witx (typename $u (union (@witx tag $tag) u8 u16))) - "Unknown name `tag`" -) - -(assert_invalid - (witx - (typename $tag string) - (typename $u (union (@witx tag $tag) u8 u16)) - ) - "Wrong kind of name `tag`: expected enum or builtin, got list" -) - -(assert_invalid - (witx - (typename $tag (enum $c)) - (typename $u (variant (@witx tag $tag) (case $b u8))) - ) - "Invalid union field `b`: does not correspond to variant in tag `tag`" -) - -(assert_invalid - (witx - (typename $tag (enum $c)) - (typename $u (union (@witx tag $tag) f32 u8)) - ) - "Union expected 1 variants, found 2" -) - -(assert_invalid - (witx - (typename $tag (enum $c $d)) - (typename $u (union (@witx tag $tag) f32)) - ) - "Union expected 2 variants, found 1" -) - -(witx $d1 - (typename $tag (enum $a $b)) - (typename $u (union (@witx tag $tag) u8 u16)) -) - -(witx $d2 - (typename $tag (enum $a $b)) - (typename $u (variant (@witx tag $tag) (case $b u16) (case $a u8))) -) - -;; These two unions should be represented the same: -(assert_representable eq $d1 "u" $d2 "u") -(assert_representable eq $d2 "u" $d1 "u") - -;; Tag order doesnt matter for validation, but does for rep equality -(witx $d3 - (typename $tag (enum $b $a)) - (typename $u (union (@witx tag $tag) u16 u8)) -) - -(assert_representable noteq $d3 "u" $d1 "u") diff --git a/proposals/random/tools/witx/tests/witxt/wasi.witxt b/proposals/random/tools/witx/tests/witxt/wasi.witxt deleted file mode 100644 index f654a7ee3..000000000 --- a/proposals/random/tools/witx/tests/witxt/wasi.witxt +++ /dev/null @@ -1,26 +0,0 @@ -;; Ensure that all current witx definitions in this repository load, parse, -;; roundtrip, and are documentable. - -(witx - (load "../../../../phases/old/snapshot_0/witx/wasi_unstable.witx")) -(witx - (load "../../../../phases/snapshot/witx/wasi_snapshot_preview1.witx")) - -(witx - (load - "../../../../phases/ephemeral/witx/wasi_ephemeral_args.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_clock.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_environ.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_fd.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_path.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_poll.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_proc.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_random.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_sched.witx" - "../../../../phases/ephemeral/witx/wasi_ephemeral_sock.witx" - ) -) -;; should be singularly-loadable as well -(witx - (load - "../../../../phases/ephemeral/witx/wasi_ephemeral_fd.witx")) diff --git a/proposals/random/wasi-random.abi.md b/proposals/random/wasi-random.abi.md new file mode 100644 index 000000000..e69de29bb diff --git a/proposals/random/wasi-random.wit.md b/proposals/random/wasi-random.wit.md new file mode 100644 index 000000000..825db22ad --- /dev/null +++ b/proposals/random/wasi-random.wit.md @@ -0,0 +1,12 @@ +# WASI Random API + +WASI Random is a random data API. + +It is intended to be portable at least between Unix-family platforms and +Windows. + +## `getrandom` +/// Return `len` random bytes. +```wit +getrandom: function(len: u32) -> list +``` From cb401670762c724a4ff27bb8ba8bdc3d17c8d673 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 28 Apr 2022 16:18:57 -0700 Subject: [PATCH 0950/1772] Use valid wit identifiers, and add more commments. --- proposals/clocks/wasi-clocks.wit.md | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/proposals/clocks/wasi-clocks.wit.md b/proposals/clocks/wasi-clocks.wit.md index f8b2ea1ec..fbbcf390a 100644 --- a/proposals/clocks/wasi-clocks.wit.md +++ b/proposals/clocks/wasi-clocks.wit.md @@ -14,20 +14,20 @@ type instant = u64 ## `datetime` ```wit -/// A time and date in seconds plus nanoseconds since 1970-01-01T00:00:00Z. +/// A time and date in seconds plus nanoseconds. record datetime { seconds: u64, nanoseconds: u32, } ``` -## `monotonic_clock` +## `monotonic-clock` ```wit /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. /// /// It is intended for measuring elapsed time. -resource monotonic_clock { +resource monotonic-clock { ``` ## `now` @@ -49,7 +49,7 @@ resolution: function() -> instant } ``` -## `wall_clock` +## `wall-clock` ```wit /// A wall clock is a clock which measures the date and time according to some /// external reference. @@ -58,7 +58,7 @@ resolution: function() -> instant /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -resource wall_clock { +resource wall-clock { ``` ## `now` @@ -66,12 +66,23 @@ resource wall_clock { /// /// As this the clock is not monotonic, calling this function repeatedly will /// not necessarily produce a sequence of non-decreasing values. +/// +/// The returned timestamps represent the number of seconds since +/// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], also +/// known as [Unix Time]. +/// +/// The nanoseconds field of the output is always less than 1000000000. +/// +/// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 +/// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time ```wit now: function() -> datetime ``` ## `resolution` /// Query the resolution of the clock. +/// +/// The nanoseconds field of the output is always less than 1000000000. ```wit resolution: function() -> datetime ``` From ec5fa37a0000c000189f1bcae805fb93660b1903 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 28 Apr 2022 16:19:12 -0700 Subject: [PATCH 0951/1772] Add a generated abi.md file. --- proposals/clocks/wasi-clocks.abi.md | 68 +++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/proposals/clocks/wasi-clocks.abi.md b/proposals/clocks/wasi-clocks.abi.md index e69de29bb..68e29a18e 100644 --- a/proposals/clocks/wasi-clocks.abi.md +++ b/proposals/clocks/wasi-clocks.abi.md @@ -0,0 +1,68 @@ +# Types + +## `instant`: `u64` + +A timestamp in nanoseconds. + +Size: 8, Alignment: 8 + +## `datetime`: record + +A time and date in seconds plus nanoseconds. + +Size: 16, Alignment: 8 + +### Record Fields + +- [`seconds`](#datetime.seconds): `u64` + + +- [`nanoseconds`](#datetime.nanoseconds): `u32` + + +# Functions + +---- + +#### `monotonic-clock::now` + +##### Params + +- `self`: handle +##### Results + +- `result`: [`instant`](#instant) + +---- + +#### `monotonic-clock::resolution` + +##### Params + +- `self`: handle +##### Results + +- `result`: [`instant`](#instant) + +---- + +#### `wall-clock::now` + +##### Params + +- `self`: handle +##### Results + +- `result`: [`datetime`](#datetime) + +---- + +#### `wall-clock::resolution` + +##### Params + +- `self`: handle +##### Results + +- `result`: [`datetime`](#datetime) + From 311d3cfb1f8272645ab4f4b85bb4dcb872bad5b6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 28 Apr 2022 16:19:26 -0700 Subject: [PATCH 0952/1772] Add a generated abi.md file. --- proposals/random/wasi-random.abi.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/proposals/random/wasi-random.abi.md b/proposals/random/wasi-random.abi.md index e69de29bb..943688071 100644 --- a/proposals/random/wasi-random.abi.md +++ b/proposals/random/wasi-random.abi.md @@ -0,0 +1,13 @@ +# Functions + +---- + +#### `getrandom` + +##### Params + +- `len`: `u32` +##### Results + +- `result`: list<`u8`> + From d569ca5b484ec820355e987ce5c95dfd6bff6ed8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 6 May 2022 16:16:46 -0700 Subject: [PATCH 0953/1772] Fix some syntax errors. The wit code-quote should contain the wit documentation comment. --- proposals/clocks/wasi-clocks.abi.md | 41 ++++++++++++++++++++++------- proposals/clocks/wasi-clocks.wit.md | 8 +++--- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/proposals/clocks/wasi-clocks.abi.md b/proposals/clocks/wasi-clocks.abi.md index 68e29a18e..741e0582b 100644 --- a/proposals/clocks/wasi-clocks.abi.md +++ b/proposals/clocks/wasi-clocks.abi.md @@ -2,67 +2,88 @@ ## `instant`: `u64` -A timestamp in nanoseconds. + A timestamp in nanoseconds. Size: 8, Alignment: 8 ## `datetime`: record -A time and date in seconds plus nanoseconds. + A time and date in seconds plus nanoseconds. Size: 16, Alignment: 8 ### Record Fields - [`seconds`](#datetime.seconds): `u64` - - + + - [`nanoseconds`](#datetime.nanoseconds): `u32` - - + + # Functions ---- #### `monotonic-clock::now` + Read the current value of the clock. + + As this the clock is monotonic, calling this function repeatedly will produce + a sequence of non-decreasing values. ##### Params - `self`: handle ##### Results -- `result`: [`instant`](#instant) +- ``: [`instant`](#instant) ---- #### `monotonic-clock::resolution` + Query the resolution of the clock. ##### Params - `self`: handle ##### Results -- `result`: [`instant`](#instant) +- ``: [`instant`](#instant) ---- #### `wall-clock::now` + Read the current value of the clock. + + As this the clock is not monotonic, calling this function repeatedly will + not necessarily produce a sequence of non-decreasing values. + + The returned timestamps represent the number of seconds since + 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], also + known as [Unix Time]. + + The nanoseconds field of the output is always less than 1000000000. + + [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + [Unix Time]: https://en.wikipedia.org/wiki/Unix_time ##### Params - `self`: handle ##### Results -- `result`: [`datetime`](#datetime) +- ``: [`datetime`](#datetime) ---- #### `wall-clock::resolution` + Query the resolution of the clock. + + The nanoseconds field of the output is always less than 1000000000. ##### Params - `self`: handle ##### Results -- `result`: [`datetime`](#datetime) +- ``: [`datetime`](#datetime) diff --git a/proposals/clocks/wasi-clocks.wit.md b/proposals/clocks/wasi-clocks.wit.md index fbbcf390a..d3cee88dd 100644 --- a/proposals/clocks/wasi-clocks.wit.md +++ b/proposals/clocks/wasi-clocks.wit.md @@ -31,17 +31,17 @@ resource monotonic-clock { ``` ## `now` +```wit /// Read the current value of the clock. /// /// As this the clock is monotonic, calling this function repeatedly will produce /// a sequence of non-decreasing values. -```wit now: function() -> instant ``` ## `resolution` -/// Query the resolution of the clock. ```wit +/// Query the resolution of the clock. resolution: function() -> instant ``` @@ -62,6 +62,7 @@ resource wall-clock { ``` ## `now` +```wit /// Read the current value of the clock. /// /// As this the clock is not monotonic, calling this function repeatedly will @@ -75,15 +76,14 @@ resource wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time -```wit now: function() -> datetime ``` ## `resolution` +```wit /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. -```wit resolution: function() -> datetime ``` From aec06e687faeb93e38b068c2ca956a08509d4448 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 26 May 2022 14:13:20 -0700 Subject: [PATCH 0954/1772] Fix wit formatting. The documentation comment goes inside the code block. --- proposals/random/wasi-random.wit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/wasi-random.wit.md b/proposals/random/wasi-random.wit.md index 825db22ad..bc75485a9 100644 --- a/proposals/random/wasi-random.wit.md +++ b/proposals/random/wasi-random.wit.md @@ -6,7 +6,7 @@ It is intended to be portable at least between Unix-family platforms and Windows. ## `getrandom` -/// Return `len` random bytes. ```wit +/// Return `len` random bytes. getrandom: function(len: u32) -> list ``` From bc6126685e92990b11142be978098ac3455c8095 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 26 May 2022 14:43:49 -0700 Subject: [PATCH 0955/1772] Fix wit formatting. The documentation comment goes inside the code block. --- proposals/filesystem/wasi-filesystem.wit.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index d6e30f000..d80e3a704 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -186,8 +186,8 @@ type device = u64 ``` ## `inode` -/// Filesystem object serial number that is unique within its file system. ```wit +/// Filesystem object serial number that is unique within its file system. type inode = u64 ``` @@ -762,13 +762,13 @@ unlink-file-at: function( ``` ## `change-file-permissions-at` +```wit /// Change the permissions of a filesystem object that is not a directory. /// /// Note that the ultimate meanings of these permissions is /// filesystem-specific. /// /// Note: This is similar to `fchmodat` in POSIX. -```wit change-file-permissions-at: function( /// Flags determining the method of how the path is resolved. at-flags: at-flags, @@ -780,6 +780,7 @@ change-file-permissions-at: function( ``` ## `change-dir-permissions-at` +```wit /// Change the permissions of a directory. /// /// Note that the ultimate meanings of these permissions is @@ -790,7 +791,6 @@ change-file-permissions-at: function( /// `execute` is not valid for directories. /// /// Note: This is similar to `fchmodat` in POSIX. -```wit change-directory-permissions-at: function( /// Flags determining the method of how the path is resolved. at-flags: at-flags, From c8c0c265d4b3c590dc790c86ed04d35ccd9e7d0b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 26 May 2022 16:05:44 -0700 Subject: [PATCH 0956/1772] Regenerate wasi-random.abi.md --- proposals/random/wasi-random.abi.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/random/wasi-random.abi.md b/proposals/random/wasi-random.abi.md index 943688071..6e4d20d0d 100644 --- a/proposals/random/wasi-random.abi.md +++ b/proposals/random/wasi-random.abi.md @@ -4,10 +4,11 @@ #### `getrandom` + Return `len` random bytes. ##### Params - `len`: `u32` ##### Results -- `result`: list<`u8`> +- ``: list<`u8`> From 67faf08e157ca32f0dbc3b36c4b8a19aafb2fe15 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 12 May 2022 12:28:14 -0700 Subject: [PATCH 0957/1772] Add a timer facility to wasi-clocks. Add a timer facility that allows one to create timers that start at a given time and count down to zero, on a given clock. The expectation is that this can be used in combination with polling to implement more flexible timeouts. --- proposals/clocks/wasi-clocks.abi.md | 26 ++++++++++++++++++++++++++ proposals/clocks/wasi-clocks.wit.md | 24 ++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/proposals/clocks/wasi-clocks.abi.md b/proposals/clocks/wasi-clocks.abi.md index 741e0582b..c1c232de2 100644 --- a/proposals/clocks/wasi-clocks.abi.md +++ b/proposals/clocks/wasi-clocks.abi.md @@ -51,6 +51,20 @@ Size: 16, Alignment: 8 ---- +#### `monotonic-clock::new-timer` + + This creates a new `monotonic-timer` with the given starting time. It will + count down from this time until it reaches zero. +##### Params + +- `self`: handle +- `initial`: [`instant`](#instant) +##### Results + +- ``: handle + +---- + #### `wall-clock::now` Read the current value of the clock. @@ -87,3 +101,15 @@ Size: 16, Alignment: 8 - ``: [`datetime`](#datetime) +---- + +#### `monotonic-timer::current` + + Returns the amount of time left before this timer reaches zero. +##### Params + +- `self`: handle +##### Results + +- ``: [`instant`](#instant) + diff --git a/proposals/clocks/wasi-clocks.wit.md b/proposals/clocks/wasi-clocks.wit.md index d3cee88dd..a72ae8d2a 100644 --- a/proposals/clocks/wasi-clocks.wit.md +++ b/proposals/clocks/wasi-clocks.wit.md @@ -45,6 +45,13 @@ now: function() -> instant resolution: function() -> instant ``` +## `new-timer` +```wit +/// This creates a new `monotonic-timer` with the given starting time. It will +/// count down from this time until it reaches zero. +new-timer: function(initial: instant) -> handle monotonic-timer +``` + ```wit } ``` @@ -90,3 +97,20 @@ resolution: function() -> datetime ```wit } ``` + +## `monotonic-timer` +```wit +/// This is a timer that counts down from a given starting time down to zero +/// on a monotonic clock. +resource monotonic-timer { +``` + +## `current` +```wit +/// Returns the amount of time left before this timer reaches zero. +current: function() -> instant +``` + +```wit +} +``` From 1c23952c8b2a3c45362084a9251f635c50675971 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 26 May 2022 16:32:32 -0700 Subject: [PATCH 0958/1772] Add an insecure-random API. This API uses a value import, so it limits the amount of data that can be obtained. This is hopefully enough data to allow source languages to initialize their DoS-resistant hash-maps, but limited so as not to be a `getrandom` alternative. Also, add some more documentation. --- proposals/random/README.md | 24 ++++++++++++------------ proposals/random/wasi-random.wit.md | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/proposals/random/README.md b/proposals/random/README.md index ca43ff761..6ec1db2a6 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -42,8 +42,11 @@ WASI Random is a WASI API for obtaining random data. ### Goals -The primary goal of WASI Random is to allow users to use WASI programs to -obtain high-quality low-level random data. +The primary goals of WASI Random are: + - To allow users to use WASI programs to obtain high-quality low-level + random data. + - To allow source languages to enable DoS protection in their hash-maps + in host environments that support it. ### Non-goals @@ -87,11 +90,11 @@ used for debugging, and not production use. #### [Use case 1] -[Provide example code snippets and diagrams explaining how the API would be used to solve the given problem] +TODO: Describe a use case using `getrandom`. #### [Use case 2] -[etc.] +TODO: Describe a use case using `insecure-random`. ### Detailed design discussion @@ -111,14 +114,6 @@ this API is designed with the belief that it's better for implementations to respond to the problem, rather than to pass the responsibility on to applications. -### Should there be a separate "insecure" random API? - -It's a good question. I haven't ruled it out, but I'd like to learn more -about use cases where it would be meaningfully better than just using the -regular random API for everything. In particular, I'm interested in not -just the application, but also the settings in which the application would -be used where this would be relevant. - ### What should happen on host platforms with weak or broken randomness APIs? It's implementations' responsibility to handle these situations. They may do @@ -156,6 +151,11 @@ their bits of security, and it doesn't seem desirable to require wasm engines to run their own CSPRNG on a platform which alreay has one, so for now, the API does not specify a specific number. +### Why is insecure-random a fixed-length value import? + +This limits the amount of data that can be obtained through it. Since it's +insecure, it's not intended to be used as an alternative to `getrandom`. + ### Considered alternatives [This section is not required if you already covered considered alternatives in the design discussion above.] diff --git a/proposals/random/wasi-random.wit.md b/proposals/random/wasi-random.wit.md index bc75485a9..69aa68f8a 100644 --- a/proposals/random/wasi-random.wit.md +++ b/proposals/random/wasi-random.wit.md @@ -8,5 +8,27 @@ Windows. ## `getrandom` ```wit /// Return `len` random bytes. +/// +/// This function must produce data from an adaquately seeded CSPRNG, so it +/// must not block, and the returned data is always unpredictable. +/// +/// Deterministic environments must omit this function, rather than +/// implementing it with deterministic data. getrandom: function(len: u32) -> list ``` + +## `insecure-random` +```wit +/// A value containing 128 random bits. +/// +/// This is a value import, which means it only provides one value, rather +/// than being a function that could be called multiple times. This is intented +/// to be used by source languages to initialize hash-maps without needing the +/// full `getrandom` API. +/// +/// This value is not required to be computed from a CSPRNG, and may even be +/// entirely deterministic. Host implementatations are encouraged to provide +/// random values to any program exposed to attacker-controlled content, to +/// enable DoS protection built into many languages' hash-map implementations. +insecure-random: tuple +``` From b82228d3ad1a2479ac86e2a71bbf446ed8426483 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 27 Jun 2022 15:17:54 -0700 Subject: [PATCH 0959/1772] Update to the latest wasi-tools. This includes an update to the latest wit-bindgen, which includes the rename from `function` to `func`. --- proposals/clocks/wasi-clocks.abi.md | 24 ++++++++++++------------ proposals/clocks/wasi-clocks.wit.md | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/proposals/clocks/wasi-clocks.abi.md b/proposals/clocks/wasi-clocks.abi.md index c1c232de2..06b1886af 100644 --- a/proposals/clocks/wasi-clocks.abi.md +++ b/proposals/clocks/wasi-clocks.abi.md @@ -33,9 +33,9 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Results +##### Result -- ``: [`instant`](#instant) +- [`instant`](#instant) ---- @@ -45,9 +45,9 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Results +##### Result -- ``: [`instant`](#instant) +- [`instant`](#instant) ---- @@ -59,9 +59,9 @@ Size: 16, Alignment: 8 - `self`: handle - `initial`: [`instant`](#instant) -##### Results +##### Result -- ``: handle +- handle ---- @@ -83,9 +83,9 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Results +##### Result -- ``: [`datetime`](#datetime) +- [`datetime`](#datetime) ---- @@ -97,9 +97,9 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Results +##### Result -- ``: [`datetime`](#datetime) +- [`datetime`](#datetime) ---- @@ -109,7 +109,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Results +##### Result -- ``: [`instant`](#instant) +- [`instant`](#instant) diff --git a/proposals/clocks/wasi-clocks.wit.md b/proposals/clocks/wasi-clocks.wit.md index a72ae8d2a..ff994f087 100644 --- a/proposals/clocks/wasi-clocks.wit.md +++ b/proposals/clocks/wasi-clocks.wit.md @@ -36,20 +36,20 @@ resource monotonic-clock { /// /// As this the clock is monotonic, calling this function repeatedly will produce /// a sequence of non-decreasing values. -now: function() -> instant +now: func() -> instant ``` ## `resolution` ```wit /// Query the resolution of the clock. -resolution: function() -> instant +resolution: func() -> instant ``` ## `new-timer` ```wit /// This creates a new `monotonic-timer` with the given starting time. It will /// count down from this time until it reaches zero. -new-timer: function(initial: instant) -> handle monotonic-timer +new-timer: func(initial: instant) -> handle monotonic-timer ``` ```wit @@ -83,7 +83,7 @@ resource wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time -now: function() -> datetime +now: func() -> datetime ``` ## `resolution` @@ -91,7 +91,7 @@ now: function() -> datetime /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. -resolution: function() -> datetime +resolution: func() -> datetime ``` ```wit @@ -108,7 +108,7 @@ resource monotonic-timer { ## `current` ```wit /// Returns the amount of time left before this timer reaches zero. -current: function() -> instant +current: func() -> instant ``` ```wit From bd68ac5e2f9b48e1d75996fc7409e9c533ab4007 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 29 Jun 2022 07:14:27 -0700 Subject: [PATCH 0960/1772] Update to wit-abi-0.3.0. --- proposals/clocks/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index f27c0a23b..ec76b9210 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -13,4 +13,4 @@ jobs: - uses: actions/checkout@v2 - uses: WebAssembly/wit-abi-up-to-date@v2 with: - wit-abi-tag: wit-abi-0.1.0 + wit-abi-tag: wit-abi-0.3.0 From 7c82a092689e6c040972887719ce57d32e201bd3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 2 Jun 2022 07:25:47 -0700 Subject: [PATCH 0961/1772] Update to wit-abi-up-to-date version v3. This adds --locked to the cargo install for `wit-abi`, which ensures that we get the wit-bindgen it's known to work with. --- proposals/filesystem/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index f27c0a23b..a039b4b9d 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v2 + - uses: WebAssembly/wit-abi-up-to-date@v3 with: wit-abi-tag: wit-abi-0.1.0 From 122ee2727b053c9f0a60e48636a8d6115d2ca81b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 30 Jun 2022 18:15:28 -0700 Subject: [PATCH 0962/1772] Update to wit-abi-up-to-date v4. --- proposals/clocks/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index ec76b9210..64d463248 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v2 + - uses: WebAssembly/wit-abi-up-to-date@v4 with: wit-abi-tag: wit-abi-0.3.0 From e979b781c5544860039dbbbee1f5004be973e4e2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 1 Jul 2022 12:32:55 -0700 Subject: [PATCH 0963/1772] Update to the latest wit-bindgen syntax. For wasi-random, this is just `function` -> `func`. --- proposals/random/.github/workflows/main.yml | 4 ++-- proposals/random/wasi-random.abi.md | 10 ++++++++-- proposals/random/wasi-random.wit.md | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index f27c0a23b..f5a35ef04 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v2 + - uses: WebAssembly/wit-abi-up-to-date@v5 with: - wit-abi-tag: wit-abi-0.1.0 + wit-abi-tag: wit-abi-0.4.0 diff --git a/proposals/random/wasi-random.abi.md b/proposals/random/wasi-random.abi.md index 6e4d20d0d..df192a9b0 100644 --- a/proposals/random/wasi-random.abi.md +++ b/proposals/random/wasi-random.abi.md @@ -5,10 +5,16 @@ #### `getrandom` Return `len` random bytes. + + This function must produce data from an adaquately seeded CSPRNG, so it + must not block, and the returned data is always unpredictable. + + Deterministic environments must omit this function, rather than + implementing it with deterministic data. ##### Params - `len`: `u32` -##### Results +##### Result -- ``: list<`u8`> +- list<`u8`> diff --git a/proposals/random/wasi-random.wit.md b/proposals/random/wasi-random.wit.md index 69aa68f8a..3645ecf30 100644 --- a/proposals/random/wasi-random.wit.md +++ b/proposals/random/wasi-random.wit.md @@ -14,7 +14,7 @@ Windows. /// /// Deterministic environments must omit this function, rather than /// implementing it with deterministic data. -getrandom: function(len: u32) -> list +getrandom: func(len: u32) -> list ``` ## `insecure-random` From 823af171eaa18a7e798e34397150f7fc6d0ee93c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 5 Jul 2022 15:20:11 -0700 Subject: [PATCH 0964/1772] Update to the latest wit-bindgen syntax This adds --locked to the cargo install for `wit-abi`, which ensures that we get the wit-bindgen it's known to work with. This also updates to the latest version of the wit parser. --- .../filesystem/.github/workflows/main.yml | 4 +- proposals/filesystem/wasi-filesystem.abi.md | 194 ++++++++++-------- proposals/filesystem/wasi-filesystem.wit.md | 130 +++++------- 3 files changed, 161 insertions(+), 167 deletions(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index a039b4b9d..f5a35ef04 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v3 + - uses: WebAssembly/wit-abi-up-to-date@v5 with: - wit-abi-tag: wit-abi-0.1.0 + wit-abi-tag: wit-abi-0.4.0 diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index d95fc1c35..b042faea6 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -44,7 +44,7 @@ Size: 2, Alignment: 1 Flags associated with a descriptor. -## `type`: variant +## `type`: enum The type of a filesystem object referenced by a descriptor. @@ -52,7 +52,7 @@ Size: 2, Alignment: 1 Size: 1, Alignment: 1 -### Variant Cases +### Enum Cases - [`unknown`](#type.unknown) @@ -87,7 +87,7 @@ Size: 1, Alignment: 1 The descriptor refers to a socket. -## `flags`: record +## `flags`: flags Descriptor flags. @@ -95,41 +95,41 @@ Size: 1, Alignment: 1 Size: 1, Alignment: 1 -### Record Fields +### Flags Fields -- [`read`](#flags.read): `bool` +- [`read`](#flags.read) Read mode: Data can be read. Bit: 0 -- [`write`](#flags.write): `bool` +- [`write`](#flags.write) Write mode: Data can be written to. Bit: 1 -- [`append`](#flags.append): `bool` +- [`append`](#flags.append) Append mode: Data written to the file is always appended to the file's end. Bit: 2 -- [`dsync`](#flags.dsync): `bool` +- [`dsync`](#flags.dsync) Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. Bit: 3 -- [`nonblock`](#flags.nonblock): `bool` +- [`nonblock`](#flags.nonblock) Non-blocking mode. Bit: 4 -- [`rsync`](#flags.rsync): `bool` +- [`rsync`](#flags.rsync) Synchronized read I/O operations. Bit: 5 -- [`sync`](#flags.sync): `bool` +- [`sync`](#flags.sync) Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the @@ -179,68 +179,68 @@ Size: 64, Alignment: 8 Last file status change timestamp. -## `at-flags`: record +## `at-flags`: flags Flags determining the method of how paths are resolved. Size: 1, Alignment: 1 -### Record Fields +### Flags Fields -- [`symlink-follow`](#at_flags.symlink_follow): `bool` +- [`symlink-follow`](#at_flags.symlink_follow) As long as the resolved path corresponds to a symbolic link, it is expanded. Bit: 0 -## `o-flags`: record +## `o-flags`: flags Open flags used by `open-at`. Size: 1, Alignment: 1 -### Record Fields +### Flags Fields -- [`create`](#o_flags.create): `bool` +- [`create`](#o_flags.create) Create file if it does not exist. Bit: 0 -- [`directory`](#o_flags.directory): `bool` +- [`directory`](#o_flags.directory) Fail if not a directory. Bit: 1 -- [`excl`](#o_flags.excl): `bool` +- [`excl`](#o_flags.excl) Fail if file already exists. Bit: 2 -- [`trunc`](#o_flags.trunc): `bool` +- [`trunc`](#o_flags.trunc) Truncate file to size 0. Bit: 3 -## `mode`: record +## `mode`: flags Permissions mode used by `open-at`, `change-permissions-at`, and similar. Size: 1, Alignment: 1 -### Record Fields +### Flags Fields -- [`readable`](#mode.readable): `bool` +- [`readable`](#mode.readable) True if the resource is considered readable by the containing filesystem. Bit: 0 -- [`writeable`](#mode.writeable): `bool` +- [`writeable`](#mode.writeable) True if the resource is considered writeable by the containing filesystem. Bit: 1 -- [`executable`](#mode.executable): `bool` +- [`executable`](#mode.executable) True if the resource is considered executable by the containing filesystem. This does not apply to directories. @@ -261,6 +261,7 @@ Size: 8, Alignment: 8 ## `inode`: `u64` + Filesystem object serial number that is unique within its file system. Size: 8, Alignment: 8 @@ -272,11 +273,11 @@ Size: 16, Alignment: 8 ### Variant Cases -- [`no-change`](#new_timestamp.no_change) +- [`no-change`](#new_timestamp.no_change): `unit` Leave the timestamp set to its previous value. -- [`now`](#new_timestamp.now) +- [`now`](#new_timestamp.now): `unit` Set the timestamp to the current time of the system clock associated with the filesystem. @@ -305,7 +306,7 @@ Size: 16, Alignment: 8 The type of the file referred to by this directory entry. -## `errno`: variant +## `errno`: enum Error codes returned by functions. Not all of these error codes are returned by the functions provided by this @@ -314,7 +315,7 @@ Size: 16, Alignment: 8 Size: 1, Alignment: 1 -### Variant Cases +### Enum Cases - [`success`](#errno.success) @@ -616,13 +617,13 @@ Size: 1, Alignment: 1 Cross-device link. -## `advice`: variant +## `advice`: enum File or memory access pattern advisory information. Size: 1, Alignment: 1 -### Variant Cases +### Enum Cases - [`normal`](#advice.normal) @@ -683,9 +684,9 @@ Size: 16, Alignment: 8 - `offset`: `u64` - `len`: `u64` - `advice`: [`advice`](#advice) -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> ---- @@ -699,9 +700,9 @@ Size: 16, Alignment: 8 - `self`: handle - `offset`: [`filesize`](#filesize) - `len`: [`filesize`](#filesize) -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> ---- @@ -713,9 +714,9 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> ---- @@ -730,9 +731,9 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Results +##### Result -- ``: expected<[`info`](#info), [`errno`](#errno)> +- expected<[`info`](#info), [`errno`](#errno)> ---- @@ -746,9 +747,9 @@ Size: 16, Alignment: 8 - `self`: handle - `size`: [`filesize`](#filesize) -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> ---- @@ -764,9 +765,9 @@ Size: 16, Alignment: 8 - `self`: handle - `atim`: [`new-timestamp`](#new_timestamp) - `mtim`: [`new-timestamp`](#new_timestamp) -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> ---- @@ -778,11 +779,10 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `buf`: push-buffer<`u8`> - `offset`: [`filesize`](#filesize) -##### Results +##### Result -- ``: expected<[`size`](#size), [`errno`](#errno)> +- stream<`u8`, [`errno`](#errno)> ---- @@ -794,11 +794,11 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `buf`: pull-buffer<`u8`> +- `buf`: stream<`u8`, `unit`> - `offset`: [`filesize`](#filesize) -##### Results +##### Result -- ``: expected<[`size`](#size), [`errno`](#errno)> +- future> ---- @@ -812,10 +812,9 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `buf`: push-buffer<`u8`> -##### Results +##### Result -- ``: expected<[`size`](#size), [`errno`](#errno)> +- stream<`u8`, [`errno`](#errno)> ---- @@ -835,11 +834,10 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `buf`: push-buffer<`u8`> - `rewind`: `bool` -##### Results +##### Result -- ``: expected<[`size`](#size), [`errno`](#errno)> +- stream<`u8`, [`errno`](#errno)> ---- @@ -849,14 +847,16 @@ Size: 16, Alignment: 8 The meaning of `seek` on a directory is unspecified. + Returns new offset of the descriptor, relative to the start of the file. + Note: This is similar to `lseek` in POSIX. ##### Params - `self`: handle - `from`: [`seek-from`](#seek_from) -##### Results +##### Result -- ``: expected<[`filesize`](#filesize), [`errno`](#errno)> +- expected<[`filesize`](#filesize), [`errno`](#errno)> ---- @@ -868,9 +868,9 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> ---- @@ -878,13 +878,15 @@ Size: 16, Alignment: 8 Return the current offset of a descriptor. + Returns the current offset of the descriptor, relative to the start of the file. + Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. ##### Params - `self`: handle -##### Results +##### Result -- ``: expected<[`filesize`](#filesize), [`errno`](#errno)> +- expected<[`filesize`](#filesize), [`errno`](#errno)> ---- @@ -896,10 +898,10 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `buf`: pull-buffer<`u8`> -##### Results +- `buf`: stream<`u8`, `unit`> +##### Result -- ``: expected<[`size`](#size), [`errno`](#errno)> +- future> ---- @@ -912,9 +914,9 @@ Size: 16, Alignment: 8 - `self`: handle - `path`: `string` -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> ---- @@ -930,9 +932,9 @@ Size: 16, Alignment: 8 - `self`: handle - `at-flags`: [`at-flags`](#at_flags) - `path`: `string` -##### Results +##### Result -- ``: expected<[`stat`](#stat), [`errno`](#errno)> +- expected<[`stat`](#stat), [`errno`](#errno)> ---- @@ -950,9 +952,9 @@ Size: 16, Alignment: 8 - `path`: `string` - `atim`: [`new-timestamp`](#new_timestamp) - `mtim`: [`new-timestamp`](#new_timestamp) -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> ---- @@ -968,9 +970,9 @@ Size: 16, Alignment: 8 - `old-path`: `string` - `new-descriptor`: handle - `new-path`: `string` -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> ---- @@ -993,9 +995,9 @@ Size: 16, Alignment: 8 - `o-flags`: [`o-flags`](#o_flags) - `fd-flags`: [`flags`](#flags) - `mode`: [`mode`](#mode) -##### Results +##### Result -- ``: expected, [`errno`](#errno)> +- expected, [`errno`](#errno)> ---- @@ -1008,9 +1010,9 @@ Size: 16, Alignment: 8 - `self`: handle - `path`: `string` -##### Results +##### Result -- ``: expected<`string`, [`errno`](#errno)> +- expected<`string`, [`errno`](#errno)> ---- @@ -1025,9 +1027,9 @@ Size: 16, Alignment: 8 - `self`: handle - `path`: `string` -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> ---- @@ -1042,9 +1044,9 @@ Size: 16, Alignment: 8 - `old-path`: `string` - `new-descriptor`: handle - `new-path`: `string` -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> ---- @@ -1058,9 +1060,9 @@ Size: 16, Alignment: 8 - `self`: handle - `old-path`: `string` - `new-path`: `string` -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> ---- @@ -1074,35 +1076,51 @@ Size: 16, Alignment: 8 - `self`: handle - `path`: `string` -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> ---- #### `descriptor::change-file-permissions-at` + Change the permissions of a filesystem object that is not a directory. + + Note that the ultimate meanings of these permissions is + filesystem-specific. + + Note: This is similar to `fchmodat` in POSIX. ##### Params - `self`: handle - `at-flags`: [`at-flags`](#at_flags) - `path`: `string` - `mode`: [`mode`](#mode) -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> ---- #### `descriptor::change-directory-permissions-at` + Change the permissions of a directory. + + Note that the ultimate meanings of these permissions is + filesystem-specific. + + Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" + flag. `read` on a directory implies readability and searchability, and + `execute` is not valid for directories. + + Note: This is similar to `fchmodat` in POSIX. ##### Params - `self`: handle - `at-flags`: [`at-flags`](#at_flags) - `path`: `string` - `mode`: [`mode`](#mode) -##### Results +##### Result -- ``: expected<_, [`errno`](#errno)> +- expected<`unit`, [`errno`](#errno)> diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index d80e3a704..76d33408a 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -423,14 +423,14 @@ resource descriptor { /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. -fadvise: function( +fadvise: func( /// The offset within the file to which the advisory applies. offset: u64, /// The length of the region to which the advisory applies. len: u64, /// The advice. advice: advice -) -> expected<_, errno> +) -> expected ``` ## `fallocate` @@ -438,12 +438,12 @@ fadvise: function( /// Force the allocation of space in a file. /// /// Note: This is similar to `posix_fallocate` in POSIX. -fallocate: function( +fallocate: func( /// The offset at which to start the allocation. offset: filesize, /// The length of the area that is allocated. len: filesize -) -> expected<_, errno> +) -> expected ``` ## `fdatasync` @@ -451,7 +451,7 @@ fallocate: function( /// Synchronize the data of a file to disk. /// /// Note: This is similar to `fdatasync` in POSIX. -datasync: function() -> expected<_, errno> +datasync: func() -> expected ``` ## `info` @@ -462,7 +462,7 @@ datasync: function() -> expected<_, errno> /// as additional fields. /// /// Note: This was called `fdstat_get` in earlier versions of WASI. -info: function() -> expected +info: func() -> expected ``` ## `set-size` @@ -471,7 +471,7 @@ info: function() -> expected /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. -set-size: function(size: filesize) -> expected<_, errno> +set-size: func(size: filesize) -> expected ``` ## `set-times` @@ -481,12 +481,12 @@ set-size: function(size: filesize) -> expected<_, errno> /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. -set-times: function( +set-times: func( /// The desired values of the data access timestamp. atim: new-timestamp, /// The desired values of the data modification timestamp. mtim: new-timestamp, -) -> expected<_, errno> +) -> expected ``` ## `pread` @@ -494,12 +494,10 @@ set-times: function( /// Read from a descriptor, without using and updating the descriptor's offset. /// /// Note: This is similar to `pread` in POSIX. -pread: function( - /// Buffer to read into - buf: push-buffer, +pread: func( /// The offset within the file at which to read. offset: filesize, -) -> expected +) -> stream ``` ## `pwrite` @@ -507,12 +505,12 @@ pread: function( /// Write to a descriptor, without using and updating the descriptor's offset. /// /// Note: This is similar to `pwrite` in POSIX. -pwrite: function( +pwrite: func( /// Data to write - buf: pull-buffer, + buf: stream, /// The offset within the file at which to write. offset: filesize, -) -> expected +) -> future> ``` ## `read` @@ -522,10 +520,7 @@ pwrite: function( /// The meaning of `read` on a directory is unspecified. /// /// Note: This is similar to `read` in POSIX. -read: function( - /// Where to read into - buf: push-buffer, -) -> expected +read: func() -> stream ``` ## `readdir` @@ -541,18 +536,10 @@ read: function( /// truncating the last directory entry. This allows the caller to grow its /// read buffer size in case it's too small to fit a single large directory /// entry, or skip the oversized directory entry. -readdir: function( - /// The buffer where directory entries are stored - /// - /// TODO: Ideally we should return directory entries as typed records. - buf: push-buffer, +readdir: func( /// If true, rewind the current position to the beginning before reading. - rewind: bool, -) -> ( - /// The number of bytes stored in the read buffer. If less than the size of - /// the read buffer, the end of the directory has been reached. - expected -) + rewind: bool +) -> stream ``` ## `seek` @@ -561,14 +548,13 @@ readdir: function( /// /// The meaning of `seek` on a directory is unspecified. /// +/// Returns new offset of the descriptor, relative to the start of the file. +/// /// Note: This is similar to `lseek` in POSIX. -seek: function( +seek: func( /// The method to compute the new offset. %from: seek-from, -) -> ( - /// The new offset of the descriptor, relative to the start of the file. - expected -) +) -> expected ``` ## `sync` @@ -576,18 +562,17 @@ seek: function( /// Synchronize the data and metadata of a file to disk. /// /// Note: This is similar to `fsync` in POSIX. -sync: function() -> expected<_, errno> +sync: func() -> expected ``` ## `tell` ```wit /// Return the current offset of a descriptor. /// +/// Returns the current offset of the descriptor, relative to the start of the file. +/// /// Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. -tell: function() -> ( - /// The current offset of the descriptor, relative to the start of the file. - expected -) +tell: func() -> expected ``` ## `write` @@ -595,10 +580,10 @@ tell: function() -> ( /// Write to a descriptor. /// /// Note: This is similar to `write` in POSIX. -write: function( +write: func( /// Data to write - buf: pull-buffer, -) -> expected + buf: stream, +) -> future> ``` ## `create-directory-at` @@ -606,10 +591,10 @@ write: function( /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. -create-directory-at: function( +create-directory-at: func( /// The relative path at which to create the directory. path: string, -) -> expected<_, errno> +) -> expected ``` ## `stat-at` @@ -619,15 +604,12 @@ create-directory-at: function( /// Note: This is similar to `fstatat` in POSIX. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. -stat-at: function( +stat-at: func( /// Flags determining the method of how the path is resolved. at-flags: at-flags, /// The relative path of the file or directory to inspect. path: string, -) -> ( - /// The buffer where the file's attributes are stored. - expected -) +) -> expected ``` ## `set-times-at` @@ -637,7 +619,7 @@ stat-at: function( /// Note: This is similar to `utimensat` in POSIX. /// /// Note: This was called `path_filestat_set_times` in earlier versions of WASI. -set-times-at: function( +set-times-at: func( /// Flags determining the method of how the path is resolved. at-flags: at-flags, /// The relative path of the file or directory to operate on. @@ -646,7 +628,7 @@ set-times-at: function( atim: new-timestamp, /// The desired values of the data modification timestamp. mtim: new-timestamp, -) -> expected<_, errno> +) -> expected ``` ## `link-at` @@ -654,7 +636,7 @@ set-times-at: function( /// Create a hard link. /// /// Note: This is similar to `linkat` in POSIX. -link-at: function( +link-at: func( /// Flags determining the method of how the path is resolved. old-at-flags: at-flags, /// The relative source path from which to link. @@ -663,7 +645,7 @@ link-at: function( new-descriptor: handle descriptor, /// The relative destination path at which to create the hard link. new-path: string, -) -> expected<_, errno> +) -> expected ``` ## `open-at` @@ -677,7 +659,7 @@ link-at: function( /// guaranteed to be less than 2**31. /// /// Note: This is similar to `openat` in POSIX. -open-at: function( +open-at: func( /// Flags determining the method of how the path is resolved. at-flags: at-flags, /// The relative path of the object to open. @@ -688,10 +670,7 @@ open-at: function( fd-flags: %flags, /// Permissions to use when creating a new file. mode: mode -) -> ( - /// The descriptor of the file that has been opened. - expected -) +) -> expected ``` ## `readlink-at` @@ -699,13 +678,10 @@ open-at: function( /// Read the contents of a symbolic link. /// /// Note: This is similar to `readlinkat` in POSIX. -readlink-at: function( +readlink-at: func( /// The relative path of the symbolic link from which to read. path: string, -) -> ( - /// The contents of the symbolic link. - expected -) +) -> expected ``` ## `remove-directory-at` @@ -715,10 +691,10 @@ readlink-at: function( /// Return `errno::notempty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. -remove-directory-at: function( +remove-directory-at: func( /// The relative path to a directory to remove. path: string, -) -> expected<_, errno> +) -> expected ``` ## `rename-at` @@ -726,14 +702,14 @@ remove-directory-at: function( /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. -rename-at: function( +rename-at: func( /// The relative source path of the file or directory to rename. old-path: string, /// The base directory for `new-path`. new-descriptor: handle descriptor, /// The relative destination path to which to rename the file or directory. new-path: string, -) -> expected<_, errno> +) -> expected ``` ## `symlink-at` @@ -741,12 +717,12 @@ rename-at: function( /// Create a symbolic link. /// /// Note: This is similar to `symlinkat` in POSIX. -symlink-at: function( +symlink-at: func( /// The contents of the symbolic link. old-path: string, /// The relative destination path at which to create the symbolic link. new-path: string, -) -> expected<_, errno> +) -> expected ``` ## `unlink-file-at` @@ -755,10 +731,10 @@ symlink-at: function( /// /// Return `errno::isdir` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. -unlink-file-at: function( +unlink-file-at: func( /// The relative path to a file to unlink. path: string, -) -> expected<_, errno> +) -> expected ``` ## `change-file-permissions-at` @@ -769,14 +745,14 @@ unlink-file-at: function( /// filesystem-specific. /// /// Note: This is similar to `fchmodat` in POSIX. -change-file-permissions-at: function( +change-file-permissions-at: func( /// Flags determining the method of how the path is resolved. at-flags: at-flags, /// The relative path to operate on. path: string, /// The new permissions for the filesystem object. mode: mode, -) -> expected<_, errno> +) -> expected ``` ## `change-dir-permissions-at` @@ -791,14 +767,14 @@ change-file-permissions-at: function( /// `execute` is not valid for directories. /// /// Note: This is similar to `fchmodat` in POSIX. -change-directory-permissions-at: function( +change-directory-permissions-at: func( /// Flags determining the method of how the path is resolved. at-flags: at-flags, /// The relative path to operate on. path: string, /// The new permissions for the directory. mode: mode, -) -> expected<_, errno> +) -> expected ``` ```wit From ee92c8f29e7149c60f88364bb3079030ad3175d2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 30 Jun 2022 18:00:31 -0700 Subject: [PATCH 0965/1772] Rename `open-at`'s `fd-flags` parameter to `flags`. This matches how the `fd-flags` type was renamed to `flags`. This effectively incorporates the main change from #40. Co-authored-by: Yonggang Luo --- proposals/filesystem/wasi-filesystem.abi.md | 2 +- proposals/filesystem/wasi-filesystem.wit.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index b042faea6..dd7802870 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -993,7 +993,7 @@ Size: 16, Alignment: 8 - `at-flags`: [`at-flags`](#at_flags) - `path`: `string` - `o-flags`: [`o-flags`](#o_flags) -- `fd-flags`: [`flags`](#flags) +- `flags`: [`flags`](#flags) - `mode`: [`mode`](#mode) ##### Result diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 76d33408a..7191e28da 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -667,7 +667,7 @@ open-at: func( /// The method by which to open the file. o-flags: o-flags, /// Flags to use for the resulting descriptor. - fd-flags: %flags, + %flags: %flags, /// Permissions to use when creating a new file. mode: mode ) -> expected From 8f5896d690d0d78a252c411cd130b00b41a382af Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 5 Jul 2022 15:26:28 -0700 Subject: [PATCH 0966/1772] Update to wit-abi-up-to-date@v5 and wit-abi 0.4.0. --- proposals/clocks/.github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 64d463248..f5a35ef04 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v4 + - uses: WebAssembly/wit-abi-up-to-date@v5 with: - wit-abi-tag: wit-abi-0.3.0 + wit-abi-tag: wit-abi-0.4.0 From 3bdb000194b5ff0c866d3399db85a69c14ed4829 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sat, 16 Jul 2022 13:43:42 +0200 Subject: [PATCH 0967/1772] Update to new WIT syntax. --- proposals/sockets/wasi-ip-name-lookup.wit | 2 +- proposals/sockets/wasi-socket-tcp.wit | 22 +++++++++++----------- proposals/sockets/wasi-socket-udp.wit | 16 ++++++++-------- proposals/sockets/wasi-socket.wit | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/proposals/sockets/wasi-ip-name-lookup.wit b/proposals/sockets/wasi-ip-name-lookup.wit index 0072b9ecc..be16a8b43 100644 --- a/proposals/sockets/wasi-ip-name-lookup.wit +++ b/proposals/sockets/wasi-ip-name-lookup.wit @@ -29,4 +29,4 @@ use { network } from wasi-network /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html /// - https://man7.org/linux/man-pages/man3/getaddrinfo.3.html /// -resolve-addresses: async function(name: string, address-family: option, include-unavailable: bool) -> expected, error> \ No newline at end of file +resolve-addresses: async func(name: string, address-family: option, include-unavailable: bool) -> expected, error> \ No newline at end of file diff --git a/proposals/sockets/wasi-socket-tcp.wit b/proposals/sockets/wasi-socket-tcp.wit index a91813cf0..db07e02da 100644 --- a/proposals/sockets/wasi-socket-tcp.wit +++ b/proposals/sockets/wasi-socket-tcp.wit @@ -22,13 +22,13 @@ enum shutdown-type { /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html /// - https://man7.org/linux/man-pages/man2/socket.2.html /// -create-tcp-socket: function(network: handle network, address-family: ip-address-family) -> expected +create-tcp-socket: func(network: handle network, address-family: ip-address-family) -> expected /// TO DISCUSS -as-input-byte-stream: function(tcp-socket: handle socket) -> handle input-byte-stream +as-input-byte-stream: func(tcp-socket: handle socket) -> handle input-byte-stream /// TO DISCUSS -as-output-byte-stream: function(tcp-socket: handle socket) -> handle output-byte-stream +as-output-byte-stream: func(tcp-socket: handle socket) -> handle output-byte-stream /// Bind the socket to a specific IP address and port. /// @@ -44,7 +44,7 @@ as-output-byte-stream: function(tcp-socket: handle socket) -> handle output-byte /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html /// - https://man7.org/linux/man-pages/man2/bind.2.html -bind: async function(tcp-socket: handle socket, local-address: ip-socket-address) -> expected<_, error> +bind: async func(tcp-socket: handle socket, local-address: ip-socket-address) -> expected /// Get the current bound address. /// @@ -53,7 +53,7 @@ bind: async function(tcp-socket: handle socket, local-address: ip-socket-address /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html /// - https://man7.org/linux/man-pages/man2/getsockname.2.html -local-address: function(tcp-socket: handle socket) -> expected +local-address: func(tcp-socket: handle socket) -> expected /// Connect to a remote endpoint. /// @@ -63,7 +63,7 @@ local-address: function(tcp-socket: handle socket) -> expected expected<_, error> +connect: async func(tcp-socket: handle socket, remote-address: ip-socket-address) -> expected /// Start listening for new connections. /// @@ -73,19 +73,19 @@ connect: async function(tcp-socket: handle socket, remote-address: ip-socket-add /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html /// - https://man7.org/linux/man-pages/man2/listen.2.html -listen: async function(tcp-socket: handle socket, backlog-size-hint: option) -> expected<_, error> +listen: async func(tcp-socket: handle socket, backlog-size-hint: option) -> expected /// Fails when the socket is not in the Connection state. /// /// Read data from the stream just like `InputByteStream::read`, but don't remove the data from the queue. -peek: async function(tcp-socket: handle socket, iovs: push-buffer) -> expected +peek: async func(tcp-socket: handle socket, iovs: push-buffer) -> expected /// Fails when the socket is not in the Connection state. /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html /// - https://man7.org/linux/man-pages/man2/getpeername.2.html -remote-address: function(tcp-socket: handle socket) -> expected +remote-address: func(tcp-socket: handle socket) -> expected /// Gracefully shut down the connection. /// @@ -111,7 +111,7 @@ remote-address: function(tcp-socket: handle socket) -> expected expected<_, error> +shutdown: async func(tcp-socket: handle socket, shutdown-type: shutdown-type) -> expected /// Unlike POSIX, this function does not returns the remote address. /// If you want to know this information, invoke `remote-address` on the newly created socket. @@ -123,4 +123,4 @@ shutdown: async function(tcp-socket: handle socket, shutdown-type: shutdown-type /// References: /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html /// - https://man7.org/linux/man-pages/man2/accept.2.html -accept: async function(tcp-socket: handle socket) -> expected +accept: async func(tcp-socket: handle socket) -> expected diff --git a/proposals/sockets/wasi-socket-udp.wit b/proposals/sockets/wasi-socket-udp.wit index 18500bdd3..678b0637a 100644 --- a/proposals/sockets/wasi-socket-udp.wit +++ b/proposals/sockets/wasi-socket-udp.wit @@ -28,7 +28,7 @@ record receive-result { /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html /// - https://man7.org/linux/man-pages/man2/socket.2.html /// -create-udp-socket: function(network: handle network, address-family: ip-address-family) -> expected +create-udp-socket: func(network: handle network, address-family: ip-address-family) -> expected /// Bind the socket to a specific IP address and port. /// @@ -48,7 +48,7 @@ create-udp-socket: function(network: handle network, address-family: ip-address- /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html /// - https://man7.org/linux/man-pages/man2/bind.2.html -bind: async function(udp-socket: handle socket, local-address: ip-socket-address) -> expected<_, error> +bind: async func(udp-socket: handle socket, local-address: ip-socket-address) -> expected /// Get the current bound address. /// @@ -57,7 +57,7 @@ bind: async function(udp-socket: handle socket, local-address: ip-socket-address /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html /// - https://man7.org/linux/man-pages/man2/getsockname.2.html -local-address: function(udp-socket: handle socket) -> expected +local-address: func(udp-socket: handle socket) -> expected /// receive a message. /// @@ -71,10 +71,10 @@ local-address: function(udp-socket: handle socket) -> expected) -> expected +receive: async func(udp-socket: handle socket, iovs: push-buffer) -> expected /// receive a message just like `receive`, but don't remove the message from the queue. -peek: async function(udp-socket: handle socket, iovs: push-buffer) -> expected +peek: async func(udp-socket: handle socket, iovs: push-buffer) -> expected /// send a message to a specific destination address. /// @@ -89,7 +89,7 @@ peek: async function(udp-socket: handle socket, iovs: push-buffer) -> expect /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html /// - https://man7.org/linux/man-pages/man2/send.2.html -send: async function(udp-socket: handle socket, iovs: pull-buffer, remote-address: ip-socket-address) -> expected +send: async func(udp-socket: handle socket, iovs: pull-buffer, remote-address: ip-socket-address) -> expected /// Set the destination address. /// @@ -110,11 +110,11 @@ send: async function(udp-socket: handle socket, iovs: pull-buffer, remote-ad /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html /// - https://man7.org/linux/man-pages/man2/connect.2.html -connect: async function(udp-socket: handle socket, remote-address: ip-socket-address) -> expected<_, error> +connect: async func(udp-socket: handle socket, remote-address: ip-socket-address) -> expected /// Get the address set with `connect`. /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html /// - https://man7.org/linux/man-pages/man2/getpeername.2.html -remote-address: function(udp-socket: handle socket) -> expected \ No newline at end of file +remote-address: func(udp-socket: handle socket) -> expected \ No newline at end of file diff --git a/proposals/sockets/wasi-socket.wit b/proposals/sockets/wasi-socket.wit index e5094a024..42de13d8e 100644 --- a/proposals/sockets/wasi-socket.wit +++ b/proposals/sockets/wasi-socket.wit @@ -15,4 +15,4 @@ resource socket {} /// /// When this function does not return an error, the argument is guaranteed to be a socket. /// Note: `socket-kind::unknown` is not an error. -kind: function(any-socket: handle socket) -> expected \ No newline at end of file +kind: func(any-socket: handle socket) -> expected \ No newline at end of file From 5dbab225e561bc5f8943ccb89f5bec85f4d16e29 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sat, 16 Jul 2022 13:59:11 +0200 Subject: [PATCH 0968/1772] Update Github actions --- proposals/sockets/.github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index f27c0a23b..f5a35ef04 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v2 + - uses: WebAssembly/wit-abi-up-to-date@v5 with: - wit-abi-tag: wit-abi-0.1.0 + wit-abi-tag: wit-abi-0.4.0 From 921fdfb29d3d6485a676442097d9c574783e2b12 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sat, 16 Jul 2022 14:10:03 +0200 Subject: [PATCH 0969/1772] Clear out dummy content --- proposals/sockets/proposal-template.abi.md | 30 --------------------- proposals/sockets/proposal-template.wit.md | 31 ---------------------- 2 files changed, 61 deletions(-) diff --git a/proposals/sockets/proposal-template.abi.md b/proposals/sockets/proposal-template.abi.md index 9f935ee8f..f54cd23d3 100644 --- a/proposals/sockets/proposal-template.abi.md +++ b/proposals/sockets/proposal-template.abi.md @@ -1,31 +1 @@ # Types - -## `api-type-one`: record - - Short description - - Explanation for developers using the API. - -Size: 16, Alignment: 8 - -### Record Fields - -- [`property1`](#api_type_one.property1): `u64` - - -- [`property2`](#api_type_one.property2): `string` - - -# Functions - ----- - -#### `api-function-one` - - Short description - - Explanation for developers using the API. -##### Results - -- ``: [`api-type-one`](#api_type_one) - diff --git a/proposals/sockets/proposal-template.wit.md b/proposals/sockets/proposal-template.wit.md index efa5364c5..b0015e253 100644 --- a/proposals/sockets/proposal-template.wit.md +++ b/proposals/sockets/proposal-template.wit.md @@ -1,32 +1 @@ # [Proposal Template] API - -[This document contains the actual specification. It should be written in the WIT interface definition format. You can find more documentation on the WIT syntax (coming soon!).] - -[Note that all comments inside of WIT code blocks will be included in the developer facing documentation for language bindings generated using this WIT file. If there is additional information that needs to be communicated to implementers of the API, then these should be captured in text directly below the code block.] - -[If you want to include examples of the API in use, these should be in the README and linked to from this file.] - -## api_type_one - -```wit -/// Short description -/// -/// Explanation for developers using the API. -record api-type-one { - property1: u64, - property2: string, -} -``` - -More rigorous specification details for the implementer go here, if needed. - -## api_function_one - -```wit -/// Short description -/// -/// Explanation for developers using the API. -api-function-one: function() -> api-type-one -``` - -If needed, this would explain what a compliant implementation MUST do, such as never returning an earlier result from a later call. From 3e2b0ae24abd4cc993f732e8f6349092a65c76dc Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sat, 16 Jul 2022 14:13:58 +0200 Subject: [PATCH 0970/1772] Delete template files. --- proposals/sockets/proposal-template.abi.md | 1 - proposals/sockets/proposal-template.wit.md | 1 - 2 files changed, 2 deletions(-) delete mode 100644 proposals/sockets/proposal-template.abi.md delete mode 100644 proposals/sockets/proposal-template.wit.md diff --git a/proposals/sockets/proposal-template.abi.md b/proposals/sockets/proposal-template.abi.md deleted file mode 100644 index f54cd23d3..000000000 --- a/proposals/sockets/proposal-template.abi.md +++ /dev/null @@ -1 +0,0 @@ -# Types diff --git a/proposals/sockets/proposal-template.wit.md b/proposals/sockets/proposal-template.wit.md deleted file mode 100644 index b0015e253..000000000 --- a/proposals/sockets/proposal-template.wit.md +++ /dev/null @@ -1 +0,0 @@ -# [Proposal Template] API From 497a8c5cd19e18afad0afce55ed573058686308e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 27 Jun 2022 15:16:52 -0700 Subject: [PATCH 0971/1772] Add a default clocks API. In Preview2 commands, we need a way for commands to obtain handles for wall-clock and monotonic clocks. See also bytecodealliance/wasi-libc#12. This PR adds a new wit file, wasi-default-clocks.wit.md, which defines value exports providing these clock handle values. --- proposals/clocks/wasi-default-clocks.abi.md | 0 proposals/clocks/wasi-default-clocks.wit.md | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 proposals/clocks/wasi-default-clocks.abi.md create mode 100644 proposals/clocks/wasi-default-clocks.wit.md diff --git a/proposals/clocks/wasi-default-clocks.abi.md b/proposals/clocks/wasi-default-clocks.abi.md new file mode 100644 index 000000000..e69de29bb diff --git a/proposals/clocks/wasi-default-clocks.wit.md b/proposals/clocks/wasi-default-clocks.wit.md new file mode 100644 index 000000000..b4c53664b --- /dev/null +++ b/proposals/clocks/wasi-default-clocks.wit.md @@ -0,0 +1,19 @@ +# WASI Default Clocks API + +WASI Default Clocks provides value-exports of clock handles for monotonic +and a wall-clock time, suitable for general-purpose application needs. + +## Imports +```wit +use { monotonic-clock, wall-clock } from wasi-clocks +``` + +## `default-monotonic-clock` +```wit +default-monotonic-clock: monotonic-clock +``` + +## `default-wall-clock` +```wit +default-wall-clock: wall-clock +``` From ffe853463614981459357219a26b37ee39dad469 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 8 Aug 2022 14:41:55 -0700 Subject: [PATCH 0972/1772] Add a way to get a future for a timer. cabi listen needs a future or stream, so add a function that produces a future from a timer, allowing it to be waited for by cabi wait. An alternative would be to have the `new` function return a future directly, rather than a resource, however that wouldn't support reading the current time from a timer. Fixes #18. --- proposals/clocks/wasi-clocks.abi.md | 12 ++++++++++++ proposals/clocks/wasi-clocks.wit.md | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/proposals/clocks/wasi-clocks.abi.md b/proposals/clocks/wasi-clocks.abi.md index 06b1886af..5c81f5ef3 100644 --- a/proposals/clocks/wasi-clocks.abi.md +++ b/proposals/clocks/wasi-clocks.abi.md @@ -113,3 +113,15 @@ Size: 16, Alignment: 8 - [`instant`](#instant) +---- + +#### `monotonic-timer::expiration` + + Returns a future that completes when the timer reaches zero. +##### Params + +- `self`: handle +##### Result + +- future<`unit`> + diff --git a/proposals/clocks/wasi-clocks.wit.md b/proposals/clocks/wasi-clocks.wit.md index ff994f087..51579aefc 100644 --- a/proposals/clocks/wasi-clocks.wit.md +++ b/proposals/clocks/wasi-clocks.wit.md @@ -111,6 +111,12 @@ resource monotonic-timer { current: func() -> instant ``` +## `expiration` +```wit +/// Returns a future that completes when the timer reaches zero. +expiration: func() -> future +``` + ```wit } ``` From ebe2daf54fc1ed90ab34e8d7c01484f77a8ca9de Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Mon, 8 Aug 2022 21:01:45 +0200 Subject: [PATCH 0973/1772] Integrate component-model streams. TCP: - Removed wasi-io-streams stubs - Removed `peek` method. Don't know how to make it interoperable with streams. Maybe this can emulated in libc? - Added `receive` & `send`. - Changed `accept` to return a stream of client sockets instead of a single one. - Potential future work: merge `listen` & `accept` into a single function that puts the socket in listening mode *and* returns a stream of sockets. UDP: - Removed `peek` method for symmetry with TCP. - TODO: `receive` & `send`. --- proposals/sockets/wasi-io-streams.wit | 7 --- proposals/sockets/wasi-socket-tcp.wit | 61 +++++++++++++++++++-------- proposals/sockets/wasi-socket-udp.wit | 18 ++------ 3 files changed, 48 insertions(+), 38 deletions(-) delete mode 100644 proposals/sockets/wasi-io-streams.wit diff --git a/proposals/sockets/wasi-io-streams.wit b/proposals/sockets/wasi-io-streams.wit deleted file mode 100644 index 472924dcf..000000000 --- a/proposals/sockets/wasi-io-streams.wit +++ /dev/null @@ -1,7 +0,0 @@ - -/// Stubs of https://github.com/WebAssembly/wasi-io/ -/// -/// TO DISCUSS - -resource input-byte-stream {} -resource output-byte-stream {} \ No newline at end of file diff --git a/proposals/sockets/wasi-socket-tcp.wit b/proposals/sockets/wasi-socket-tcp.wit index db07e02da..0eecb120a 100644 --- a/proposals/sockets/wasi-socket-tcp.wit +++ b/proposals/sockets/wasi-socket-tcp.wit @@ -1,5 +1,4 @@ use { error, ip-address-family, ip-socket-address, usize } from common-types -use { input-byte-stream, output-byte-stream } from wasi-io-streams use { network } from wasi-network use { socket } from wasi-socket @@ -24,11 +23,41 @@ enum shutdown-type { /// create-tcp-socket: func(network: handle network, address-family: ip-address-family) -> expected -/// TO DISCUSS -as-input-byte-stream: func(tcp-socket: handle socket) -> handle input-byte-stream +/// Receive data on the socket. +/// +/// The returned stream can be used to continually read all data from the socket. The stream's final value will be +/// `Ok(())` when the stream reached end-of-file without errors. +/// +/// The returned stream may be closed prematurely by the consumer. In that case the socket becomes available +/// for reading again. +/// +/// Fails when there is already an active `receive` operation in progress on the socket. +/// Fails when the socket is not in the Connection state. +/// +/// References +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html +/// - https://man7.org/linux/man-pages/man2/recv.2.html +/// - https://man7.org/linux/man-pages/man2/read.2.html +receive: func(tcp-socket: handle socket) -> stream> -/// TO DISCUSS -as-output-byte-stream: func(tcp-socket: handle socket) -> handle output-byte-stream +/// Send data on the socket. +/// +/// The input stream can be used to continually write data to the socket. +/// After the input stream is finalized by the producer, the socket becomes available for writing again. +/// +/// The returned future completes successfully after the input stream is drained completely. +/// If an error occurs during sending, the input stream is closed and the future completes with an error. +/// +/// Fails when there is already an active `send` operation in progress on the socket. +/// Fails when the socket is not in the Connection state. +/// +/// References +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html +/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html +/// - https://man7.org/linux/man-pages/man2/send.2.html +/// - https://man7.org/linux/man-pages/man2/write.2.html +send: func(tcp-socket: handle socket, data: stream) -> future> /// Bind the socket to a specific IP address and port. /// @@ -75,11 +104,6 @@ connect: async func(tcp-socket: handle socket, remote-address: ip-socket-address /// - https://man7.org/linux/man-pages/man2/listen.2.html listen: async func(tcp-socket: handle socket, backlog-size-hint: option) -> expected -/// Fails when the socket is not in the Connection state. -/// -/// Read data from the stream just like `InputByteStream::read`, but don't remove the data from the queue. -peek: async func(tcp-socket: handle socket, iovs: push-buffer) -> expected - /// Fails when the socket is not in the Connection state. /// /// References @@ -89,8 +113,8 @@ remote-address: func(tcp-socket: handle socket) -> expected expected expected -/// Unlike POSIX, this function does not returns the remote address. -/// If you want to know this information, invoke `remote-address` on the newly created socket. +/// Start accepting new client sockets. /// -/// Fails when this socket is not in the Listening state. +/// The returned sockets are bound and in the Connection state. /// -/// Returns a new bound socket in the Connection state. +/// The returned stream may be closed prematurely by the consumer. In that case the socket becomes available +/// for accepting again. +/// +/// Fails when there is already an active `accept` stream operation in progress on the socket. +/// Fails when this socket is not in the Listening state. /// /// References: /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html /// - https://man7.org/linux/man-pages/man2/accept.2.html -accept: async func(tcp-socket: handle socket) -> expected +accept: func(tcp-socket: handle socket) -> stream> diff --git a/proposals/sockets/wasi-socket-udp.wit b/proposals/sockets/wasi-socket-udp.wit index 678b0637a..f75c8a2f8 100644 --- a/proposals/sockets/wasi-socket-udp.wit +++ b/proposals/sockets/wasi-socket-udp.wit @@ -4,11 +4,8 @@ use { network } from wasi-network use { socket } from wasi-socket -record receive-result { - bytes-received: usize, - - /// Similar to the `MSG_TRUNC` flag in POSIX. - truncated: bool, +record datagram { + data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. remote-address: ip-socket-address, /// Possible future additions: @@ -71,25 +68,18 @@ local-address: func(udp-socket: handle socket) -> expected) -> expected - -/// receive a message just like `receive`, but don't remove the message from the queue. -peek: async func(udp-socket: handle socket, iovs: push-buffer) -> expected +receive: async func(udp-socket: handle socket) -> expected /// send a message to a specific destination address. /// /// The remote address option is required. To send a message to the "connected" peer, /// call `remote-address` to get their address. /// -/// Returns the number of bytes sent. -/// -/// TODO: Does the returned number of bytes sent ever differ from the supplied buffer size for UDP sockets? -/// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html /// - https://man7.org/linux/man-pages/man2/send.2.html -send: async func(udp-socket: handle socket, iovs: pull-buffer, remote-address: ip-socket-address) -> expected +send: async func(udp-socket: handle socket, datagram: datagram) -> expected /// Set the destination address. /// From 57da6ad0e7ed8e46f61e180fcea11d3b074b5e70 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 21 Aug 2022 12:32:39 +0200 Subject: [PATCH 0974/1772] Automatically emit shutdown syscalls at the end of streams. Removed the manual `shutdown` function from the WASI interface. --- proposals/sockets/wasi-socket-tcp.wit | 49 ++++----------------------- 1 file changed, 6 insertions(+), 43 deletions(-) diff --git a/proposals/sockets/wasi-socket-tcp.wit b/proposals/sockets/wasi-socket-tcp.wit index 0eecb120a..2d4c46915 100644 --- a/proposals/sockets/wasi-socket-tcp.wit +++ b/proposals/sockets/wasi-socket-tcp.wit @@ -2,17 +2,6 @@ use { error, ip-address-family, ip-socket-address, usize } from common-types use { network } from wasi-network use { socket } from wasi-socket -enum shutdown-type { - /// Similar to `SHUT_RD` in POSIX. - receive, - - /// Similar to `SHUT_WR` in POSIX. - send, - - /// Similar to `SHUT_RDWR` in POSIX. - both, -} - /// Create a new TCP socket. /// /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, 0 or IPPROTO_TCP)` in POSIX. @@ -26,12 +15,11 @@ create-tcp-socket: func(network: handle network, address-family: ip-address-fami /// Receive data on the socket. /// /// The returned stream can be used to continually read all data from the socket. The stream's final value will be -/// `Ok(())` when the stream reached end-of-file without errors. +/// `Ok(())` when the stream reached end-of-file without errors. When the returned stream is closed by the consumer, +/// a `shutdown(this_socket, SHUT_RD)` syscall is executed. /// -/// The returned stream may be closed prematurely by the consumer. In that case the socket becomes available -/// for reading again. +/// This function can only be called successfully _once_ on a socket. All subsequent calls will result in an EPIPE error. /// -/// Fails when there is already an active `receive` operation in progress on the socket. /// Fails when the socket is not in the Connection state. /// /// References @@ -44,12 +32,13 @@ receive: func(tcp-socket: handle socket) -> stream> /// Send data on the socket. /// /// The input stream can be used to continually write data to the socket. -/// After the input stream is finalized by the producer, the socket becomes available for writing again. +/// After the input stream is finalized by the producer, a `shutdown(this_socket, SHUT_WR)` syscall is executed. /// /// The returned future completes successfully after the input stream is drained completely. /// If an error occurs during sending, the input stream is closed and the future completes with an error. /// -/// Fails when there is already an active `send` operation in progress on the socket. +/// This function can only be called successfully _once_ on a socket. All subsequent calls will result in an EPIPE error. +/// /// Fails when the socket is not in the Connection state. /// /// References @@ -111,32 +100,6 @@ listen: async func(tcp-socket: handle socket, backlog-size-hint: option) /// - https://man7.org/linux/man-pages/man2/getpeername.2.html remote-address: func(tcp-socket: handle socket) -> expected -/// Gracefully shut down the connection. -/// -/// - receive: the socket is not expecting to receive any more data from the peer. Any active receive stream will be -/// closed with a success value. If there is still data in the receive queue at time of -/// calling `shutdown` or whenever new data arrives afterwards, then (TODO). -/// - send: the socket is not expecting to send any more data to the peer. After all data in the send queue has -/// been sent and acknowledged, a FIN will be sent. All subsequent write/send operations will return an -/// EPIPE error. -/// - both: receive & send -/// -/// The shutdown function does not close the socket. -/// -/// Fails when the socket is not in the Connection state. -/// -/// TODO: Look into how different platforms behave after shutdown(Read) has been called and new data arrives. According to the internet (unverified): -/// - BSD: silently discards the data -/// - Linux: effectively ignores the shutdown call. New data can still be read. If not done will ultimately block the sender. -/// - Windows: sends RST -/// -/// TODO: Look into how different platforms behave when trying to shut down the same direction multiple times. -/// -/// References -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html -/// - https://man7.org/linux/man-pages/man2/shutdown.2.html -shutdown: async func(tcp-socket: handle socket, shutdown-type: shutdown-type) -> expected - /// Start accepting new client sockets. /// /// The returned sockets are bound and in the Connection state. From 40814b435fa5e2556975bd73f67cabc00dd8a80a Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 21 Aug 2022 12:50:29 +0200 Subject: [PATCH 0975/1772] Changed `accept` to be a one-time action for simplicity. And symmetry with send&receive. --- proposals/sockets/wasi-socket-tcp.wit | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/proposals/sockets/wasi-socket-tcp.wit b/proposals/sockets/wasi-socket-tcp.wit index 2d4c46915..c707892b6 100644 --- a/proposals/sockets/wasi-socket-tcp.wit +++ b/proposals/sockets/wasi-socket-tcp.wit @@ -104,10 +104,8 @@ remote-address: func(tcp-socket: handle socket) -> expected Date: Sun, 21 Aug 2022 14:53:18 +0200 Subject: [PATCH 0976/1772] Made tcp-socket and udp-socket their own type of resource. They both extend a new `ip-socket` resource type, which in its turn extends `socket`. Removed `socket::kind`, because that can be replaced with runtime type checking. --- proposals/sockets/README.md | 7 +- proposals/sockets/common-types.wit | 17 --- proposals/sockets/wasi-socket-ip.wit | 29 ++++ proposals/sockets/wasi-socket-tcp.wit | 212 +++++++++++++------------- proposals/sockets/wasi-socket-udp.wit | 178 ++++++++++----------- proposals/sockets/wasi-socket.wit | 18 +-- 6 files changed, 233 insertions(+), 228 deletions(-) create mode 100644 proposals/sockets/wasi-socket-ip.wit diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 964abd540..d48bd9e57 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -44,10 +44,11 @@ Unlike BSD sockets, WASI sockets require capability handles to create sockets an The socket APIs have been split up into standalone protocol-specific WASI modules. Both current and future socket modules can then be tailored to the needs of that specific protocol and progress the standardization process independently. This proposal introduces 4 new WASI modules: -- [wasi-socket.wit](./wasi-socket.wit) -- [wasi-socket-tcp.wit](./wasi-socket-tcp.wit) -- [wasi-socket-udp.wit](./wasi-socket-udp.wit) - [wasi-ip-name-lookup.wit](./wasi-ip-name-lookup.wit) +- [wasi-socket.wit](./wasi-socket.wit) + - [wasi-socket-ip.wit](./wasi-socket-ip.wit) + - [wasi-socket-tcp.wit](./wasi-socket-tcp.wit) + - [wasi-socket-udp.wit](./wasi-socket-udp.wit) ### Goals diff --git a/proposals/sockets/common-types.wit b/proposals/sockets/common-types.wit index 952117682..281d3898a 100644 --- a/proposals/sockets/common-types.wit +++ b/proposals/sockets/common-types.wit @@ -35,20 +35,3 @@ variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } - -record ipv4-socket-address { - port: u16, // sin_port - address: ipv4-address, // sin_addr -} - -record ipv6-socket-address { - port: u16, // sin6_port - flow-info: u32, // sin6_flowinfo - address: ipv6-address, // sin6_addr - scope-id: u32, // sin6_scope_id -} - -variant ip-socket-address { - ipv4(ipv4-socket-address), - ipv6(ipv6-socket-address), -} \ No newline at end of file diff --git a/proposals/sockets/wasi-socket-ip.wit b/proposals/sockets/wasi-socket-ip.wit new file mode 100644 index 000000000..ccc042818 --- /dev/null +++ b/proposals/sockets/wasi-socket-ip.wit @@ -0,0 +1,29 @@ + +use { error, ipv4-address, ipv6-address, ip-address-family } from common-types +use { socket } from wasi-socket + +record ipv4-socket-address { + port: u16, // sin_port + address: ipv4-address, // sin_addr +} + +record ipv6-socket-address { + port: u16, // sin6_port + flow-info: u32, // sin6_flowinfo + address: ipv6-address, // sin6_addr + scope-id: u32, // sin6_scope_id +} + +variant ip-socket-address { + ipv4(ipv4-socket-address), + ipv6(ipv6-socket-address), +} + +resource ip-socket implements socket { + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family + +} diff --git a/proposals/sockets/wasi-socket-tcp.wit b/proposals/sockets/wasi-socket-tcp.wit index c707892b6..3a03e06e7 100644 --- a/proposals/sockets/wasi-socket-tcp.wit +++ b/proposals/sockets/wasi-socket-tcp.wit @@ -1,114 +1,118 @@ -use { error, ip-address-family, ip-socket-address, usize } from common-types +use { error, ip-address-family, usize } from common-types use { network } from wasi-network -use { socket } from wasi-socket +use { ip-socket, ip-socket-address } from wasi-socket-ip -/// Create a new TCP socket. -/// -/// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, 0 or IPPROTO_TCP)` in POSIX. -/// -/// References: -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html -/// - https://man7.org/linux/man-pages/man2/socket.2.html -/// -create-tcp-socket: func(network: handle network, address-family: ip-address-family) -> expected +resource tcp-socket implements ip-socket { -/// Receive data on the socket. -/// -/// The returned stream can be used to continually read all data from the socket. The stream's final value will be -/// `Ok(())` when the stream reached end-of-file without errors. When the returned stream is closed by the consumer, -/// a `shutdown(this_socket, SHUT_RD)` syscall is executed. -/// -/// This function can only be called successfully _once_ on a socket. All subsequent calls will result in an EPIPE error. -/// -/// Fails when the socket is not in the Connection state. -/// -/// References -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html -/// - https://man7.org/linux/man-pages/man2/recv.2.html -/// - https://man7.org/linux/man-pages/man2/read.2.html -receive: func(tcp-socket: handle socket) -> stream> + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, 0 or IPPROTO_TCP)` in POSIX. + /// + /// References: + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html + /// - https://man7.org/linux/man-pages/man2/socket.2.html + /// + static new: async func(network: handle network, address-family: ip-address-family) -> expected -/// Send data on the socket. -/// -/// The input stream can be used to continually write data to the socket. -/// After the input stream is finalized by the producer, a `shutdown(this_socket, SHUT_WR)` syscall is executed. -/// -/// The returned future completes successfully after the input stream is drained completely. -/// If an error occurs during sending, the input stream is closed and the future completes with an error. -/// -/// This function can only be called successfully _once_ on a socket. All subsequent calls will result in an EPIPE error. -/// -/// Fails when the socket is not in the Connection state. -/// -/// References -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html -/// - https://man7.org/linux/man-pages/man2/send.2.html -/// - https://man7.org/linux/man-pages/man2/write.2.html -send: func(tcp-socket: handle socket, data: stream) -> future> + /// Receive data on the socket. + /// + /// The returned stream can be used to continually read all data from the socket. The stream's final value will be + /// `Ok(())` when the stream reached end-of-file without errors. When the returned stream is closed by the consumer, + /// a `shutdown(this_socket, SHUT_RD)` syscall is executed. + /// + /// This function can only be called successfully _once_ on a socket. All subsequent calls will result in an EPIPE error. + /// + /// Fails when the socket is not in the Connection state. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html + /// - https://man7.org/linux/man-pages/man2/recv.2.html + /// - https://man7.org/linux/man-pages/man2/read.2.html + receive: func() -> stream> -/// Bind the socket to a specific IP address and port. -/// -/// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which -/// network interface(s) to bind to. -/// If the TCP/UDP port is zero, the socket will be bound to a random free port. -/// -/// When a socket is not explicitly bound, the first invocation to a listen or connect operation will -/// implicitly bind the socket. -/// -/// Returns an error if the socket is already bound. -/// -/// References -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html -/// - https://man7.org/linux/man-pages/man2/bind.2.html -bind: async func(tcp-socket: handle socket, local-address: ip-socket-address) -> expected + /// Send data on the socket. + /// + /// The input stream can be used to continually write data to the socket. + /// After the input stream is finalized by the producer, a `shutdown(this_socket, SHUT_WR)` syscall is executed. + /// + /// The returned future completes successfully after the input stream is drained completely. + /// If an error occurs during sending, the input stream is closed and the future completes with an error. + /// + /// This function can only be called successfully _once_ on a socket. All subsequent calls will result in an EPIPE error. + /// + /// Fails when the socket is not in the Connection state. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html + /// - https://man7.org/linux/man-pages/man2/send.2.html + /// - https://man7.org/linux/man-pages/man2/write.2.html + send: func(data: stream) -> future> -/// Get the current bound address. -/// -/// Returns an error if the socket is not bound. -/// -/// References -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html -/// - https://man7.org/linux/man-pages/man2/getsockname.2.html -local-address: func(tcp-socket: handle socket) -> expected + /// Bind the socket to a specific IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will + /// implicitly bind the socket. + /// + /// Returns an error if the socket is already bound. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html + /// - https://man7.org/linux/man-pages/man2/bind.2.html + bind: async func(local-address: ip-socket-address) -> expected -/// Connect to a remote endpoint. -/// -/// Transitions the socket into the Connection state. -/// Fails when the socket is already in the Connection or Listener state. -/// -/// References -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html -/// - https://man7.org/linux/man-pages/man2/connect.2.html -connect: async func(tcp-socket: handle socket, remote-address: ip-socket-address) -> expected + /// Get the current bound address. + /// + /// Returns an error if the socket is not bound. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html + /// - https://man7.org/linux/man-pages/man2/getsockname.2.html + local-address: func() -> expected -/// Start listening for new connections. -/// -/// Transitions the socket into the Listener state. -/// Fails when the socket is already in the Connection or Listener state. -/// -/// References -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html -/// - https://man7.org/linux/man-pages/man2/listen.2.html -listen: async func(tcp-socket: handle socket, backlog-size-hint: option) -> expected + /// Connect to a remote endpoint. + /// + /// Transitions the socket into the Connection state. + /// Fails when the socket is already in the Connection or Listener state. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html + /// - https://man7.org/linux/man-pages/man2/connect.2.html + connect: async func(remote-address: ip-socket-address) -> expected -/// Fails when the socket is not in the Connection state. -/// -/// References -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html -/// - https://man7.org/linux/man-pages/man2/getpeername.2.html -remote-address: func(tcp-socket: handle socket) -> expected + /// Start listening for new connections. + /// + /// Transitions the socket into the Listener state. + /// Fails when the socket is already in the Connection or Listener state. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html + /// - https://man7.org/linux/man-pages/man2/listen.2.html + listen: async func(backlog-size-hint: option) -> expected -/// Start accepting new client sockets. -/// -/// The returned sockets are bound and in the Connection state. -/// -/// This function can only be called successfully _once_ on a socket. All subsequent calls will result in an error. -/// -/// Fails when this socket is not in the Listening state. -/// -/// References: -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html -/// - https://man7.org/linux/man-pages/man2/accept.2.html -accept: func(tcp-socket: handle socket) -> stream> + /// Fails when the socket is not in the Connection state. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html + /// - https://man7.org/linux/man-pages/man2/getpeername.2.html + remote-address: func() -> expected + + /// Start accepting new client sockets. + /// + /// The returned sockets are bound and in the Connection state. + /// + /// This function can only be called successfully _once_ on a socket. All subsequent calls will result in an error. + /// + /// Fails when this socket is not in the Listening state. + /// + /// References: + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html + /// - https://man7.org/linux/man-pages/man2/accept.2.html + accept: func() -> stream> + +} \ No newline at end of file diff --git a/proposals/sockets/wasi-socket-udp.wit b/proposals/sockets/wasi-socket-udp.wit index f75c8a2f8..302567a06 100644 --- a/proposals/sockets/wasi-socket-udp.wit +++ b/proposals/sockets/wasi-socket-udp.wit @@ -1,8 +1,7 @@ -use { error, ip-address-family, ip-socket-address, usize } from common-types +use { error, ip-address-family, usize } from common-types use { network } from wasi-network -use { socket } from wasi-socket - +use { ip-socket, ip-socket-address } from wasi-socket-ip record datagram { data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. @@ -16,95 +15,98 @@ record datagram { /// ecn: u2, // IP_RECVTOS } +resource udp-socket implements ip-socket { + + /// Create a new UDP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, 0 or IPPROTO_UDP)` in POSIX. + /// + /// References: + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html + /// - https://man7.org/linux/man-pages/man2/socket.2.html + /// + static new: async func(network: handle network, address-family: ip-address-family) -> expected -/// Create a new UDP socket. -/// -/// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, 0 or IPPROTO_UDP)` in POSIX. -/// -/// References: -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html -/// - https://man7.org/linux/man-pages/man2/socket.2.html -/// -create-udp-socket: func(network: handle network, address-family: ip-address-family) -> expected + /// Bind the socket to a specific IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to a send or receive operation will + /// implicitly bind the socket. + /// + /// Returns an error if the socket is already bound. + /// + /// TODO: disallow wildcard binds as long as there isn't a way to pass the local address to send & receive? + /// - https://blog.cloudflare.com/everything-you-ever-wanted-to-know-about-udp-sockets-but-were-afraid-to-ask-part-1/#sourcing-packets-from-a-wildcard-socket + /// - https://blog.powerdns.com/2012/10/08/on-binding-datagram-udp-sockets-to-the-any-addresses/ + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html + /// - https://man7.org/linux/man-pages/man2/bind.2.html + bind: async func(local-address: ip-socket-address) -> expected -/// Bind the socket to a specific IP address and port. -/// -/// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which -/// network interface(s) to bind to. -/// If the TCP/UDP port is zero, the socket will be bound to a random free port. -/// -/// When a socket is not explicitly bound, the first invocation to a send or receive operation will -/// implicitly bind the socket. -/// -/// Returns an error if the socket is already bound. -/// -/// TODO: disallow wildcard binds as long as there isn't a way to pass the local address to send & receive? -/// - https://blog.cloudflare.com/everything-you-ever-wanted-to-know-about-udp-sockets-but-were-afraid-to-ask-part-1/#sourcing-packets-from-a-wildcard-socket -/// - https://blog.powerdns.com/2012/10/08/on-binding-datagram-udp-sockets-to-the-any-addresses/ -/// -/// References -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html -/// - https://man7.org/linux/man-pages/man2/bind.2.html -bind: async func(udp-socket: handle socket, local-address: ip-socket-address) -> expected + /// Get the current bound address. + /// + /// Returns an error if the socket is not bound. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html + /// - https://man7.org/linux/man-pages/man2/getsockname.2.html + local-address: func() -> expected -/// Get the current bound address. -/// -/// Returns an error if the socket is not bound. -/// -/// References -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html -/// - https://man7.org/linux/man-pages/man2/getsockname.2.html -local-address: func(udp-socket: handle socket) -> expected + /// receive a message. + /// + /// Returns: + /// - The sender address of the datagram + /// - The number of bytes read. + /// - When the received datagram is larger than the provided buffers, + /// the excess data is lost and the `truncated` flag will be set. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html + /// - https://man7.org/linux/man-pages/man2/recv.2.html + receive: async func() -> expected -/// receive a message. -/// -/// Returns: -/// - The sender address of the datagram -/// - The number of bytes read. -/// - When the received datagram is larger than the provided buffers, -/// the excess data is lost and the `truncated` flag will be set. -/// -/// References -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html -/// - https://man7.org/linux/man-pages/man2/recv.2.html -receive: async func(udp-socket: handle socket) -> expected + /// send a message to a specific destination address. + /// + /// The remote address option is required. To send a message to the "connected" peer, + /// call `remote-address` to get their address. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html + /// - https://man7.org/linux/man-pages/man2/send.2.html + send: async func(datagram: datagram) -> expected -/// send a message to a specific destination address. -/// -/// The remote address option is required. To send a message to the "connected" peer, -/// call `remote-address` to get their address. -/// -/// References -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html -/// - https://man7.org/linux/man-pages/man2/send.2.html -send: async func(udp-socket: handle socket, datagram: datagram) -> expected + /// Set the destination address. + /// + /// When a destination address is set: + /// - all receive operations will only return datagrams sent from the provided `remote-address`. + /// - the `send` function can still be used to send to any other destination, however you can't receive their response. + /// + /// Similar to `connect(sock, ...)` in POSIX. + /// + /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". + /// + /// TODO: "connect" is a rather odd name for this function because it doesn't reflect what's actually happening. + /// Feels like it was chosen just to shoehorn UDP into the existing Socket interface. + /// Do we have to keep this name? + /// + /// TODO: add unconnect ability. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html + /// - https://man7.org/linux/man-pages/man2/connect.2.html + connect: async func(remote-address: ip-socket-address) -> expected -/// Set the destination address. -/// -/// When a destination address is set: -/// - all receive operations will only return datagrams sent from the provided `remote-address`. -/// - the `send` function can still be used to send to any other destination, however you can't receive their response. -/// -/// Similar to `connect(sock, ...)` in POSIX. -/// -/// Note that this function does not generate any network traffic and the peer is not aware of this "connection". -/// -/// TODO: "connect" is a rather odd name for this function because it doesn't reflect what's actually happening. -/// Feels like it was chosen just to shoehorn UDP into the existing Socket interface. -/// Do we have to keep this name? -/// -/// TODO: add unconnect ability. -/// -/// References -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html -/// - https://man7.org/linux/man-pages/man2/connect.2.html -connect: async func(udp-socket: handle socket, remote-address: ip-socket-address) -> expected + /// Get the address set with `connect`. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html + /// - https://man7.org/linux/man-pages/man2/getpeername.2.html + remote-address: func() -> expected -/// Get the address set with `connect`. -/// -/// References -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html -/// - https://man7.org/linux/man-pages/man2/getpeername.2.html -remote-address: func(udp-socket: handle socket) -> expected \ No newline at end of file +} \ No newline at end of file diff --git a/proposals/sockets/wasi-socket.wit b/proposals/sockets/wasi-socket.wit index 42de13d8e..e09b095ac 100644 --- a/proposals/sockets/wasi-socket.wit +++ b/proposals/sockets/wasi-socket.wit @@ -1,18 +1,4 @@ -use { error } from common-types - -enum socket-kind { - /// TODO: https://github.com/WebAssembly/interface-types/issues/145 - unknown, - tcp, - udp, +resource socket { + } - -resource socket {} - - -/// Get the type of the socket. -/// -/// When this function does not return an error, the argument is guaranteed to be a socket. -/// Note: `socket-kind::unknown` is not an error. -kind: func(any-socket: handle socket) -> expected \ No newline at end of file From e58b0cf1e90ca677d75968edc0ef454c9a703859 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 21 Aug 2022 16:49:51 +0200 Subject: [PATCH 0977/1772] Add interfaces for socket options: IP_TTL, IPV6_UNICAST_HOPS, IPV6_V6ONLY, SO_KEEPALIVE, TCP_NODELAY, SO_RCVBUF and SO_SNDBUF. --- proposals/sockets/wasi-socket-ip.wit | 12 ++++++++++++ proposals/sockets/wasi-socket-tcp.wit | 24 ++++++++++++++++++++++++ proposals/sockets/wasi-socket-udp.wit | 16 ++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/proposals/sockets/wasi-socket-ip.wit b/proposals/sockets/wasi-socket-ip.wit index ccc042818..a8dba0581 100644 --- a/proposals/sockets/wasi-socket-ip.wit +++ b/proposals/sockets/wasi-socket-ip.wit @@ -26,4 +26,16 @@ resource ip-socket implements socket { /// Equivalent to the SO_DOMAIN socket option. address-family: func() -> ip-address-family + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + unicast-hop-limit: func() -> expected + set-unicast-hop-limit: func(value: u8) -> expected + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// Implementations are not required to support dual-stack mode, so calling `set-ipv6-only(false)` might fail. + /// + /// Fails when called on an IPv4 socket. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + ipv6-only: func() -> expected + set-ipv6-only: func(value: bool) -> expected } diff --git a/proposals/sockets/wasi-socket-tcp.wit b/proposals/sockets/wasi-socket-tcp.wit index 3a03e06e7..2c87ac88d 100644 --- a/proposals/sockets/wasi-socket-tcp.wit +++ b/proposals/sockets/wasi-socket-tcp.wit @@ -115,4 +115,28 @@ resource tcp-socket implements ip-socket { /// - https://man7.org/linux/man-pages/man2/accept.2.html accept: func() -> stream> + /// Equivalent to the SO_KEEPALIVE socket option. + keep-alive: func() -> expected + set-keep-alive: func(value: bool) -> expected + + /// Equivalent to the TCP_NODELAY socket option. + no-delay: func() -> expected + set-no-delay: func(value: bool) -> expected + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Fails when this socket is in the Listening state. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + receive-buffer-size: func() -> expected + set-receive-buffer-size: func(value: usize) -> expected + send-buffer-size: func() -> expected + set-send-buffer-size: func(value: usize) -> expected } \ No newline at end of file diff --git a/proposals/sockets/wasi-socket-udp.wit b/proposals/sockets/wasi-socket-udp.wit index 302567a06..304d5f50c 100644 --- a/proposals/sockets/wasi-socket-udp.wit +++ b/proposals/sockets/wasi-socket-udp.wit @@ -109,4 +109,20 @@ resource udp-socket implements ip-socket { /// - https://man7.org/linux/man-pages/man2/getpeername.2.html remote-address: func() -> expected + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Fails when this socket is in the Listening state. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + receive-buffer-size: func() -> expected + set-receive-buffer-size: func(value: usize) -> expected + send-buffer-size: func() -> expected + set-send-buffer-size: func(value: usize) -> expected } \ No newline at end of file From 5467ac9fac66915cc62cc09622724c97f8a571c1 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 18 Sep 2022 12:13:26 +0200 Subject: [PATCH 0978/1772] Removed the now defunct `async` keyword and replaced it with `future`s --- proposals/sockets/wasi-ip-name-lookup.wit | 2 +- proposals/sockets/wasi-socket-tcp.wit | 8 ++++---- proposals/sockets/wasi-socket-udp.wit | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/sockets/wasi-ip-name-lookup.wit b/proposals/sockets/wasi-ip-name-lookup.wit index be16a8b43..153133156 100644 --- a/proposals/sockets/wasi-ip-name-lookup.wit +++ b/proposals/sockets/wasi-ip-name-lookup.wit @@ -29,4 +29,4 @@ use { network } from wasi-network /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html /// - https://man7.org/linux/man-pages/man3/getaddrinfo.3.html /// -resolve-addresses: async func(name: string, address-family: option, include-unavailable: bool) -> expected, error> \ No newline at end of file +resolve-addresses: func(name: string, address-family: option, include-unavailable: bool) -> future, error>> \ No newline at end of file diff --git a/proposals/sockets/wasi-socket-tcp.wit b/proposals/sockets/wasi-socket-tcp.wit index 2c87ac88d..41b4e5367 100644 --- a/proposals/sockets/wasi-socket-tcp.wit +++ b/proposals/sockets/wasi-socket-tcp.wit @@ -12,7 +12,7 @@ resource tcp-socket implements ip-socket { /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html /// - https://man7.org/linux/man-pages/man2/socket.2.html /// - static new: async func(network: handle network, address-family: ip-address-family) -> expected + static new: func(network: handle network, address-family: ip-address-family) -> future> /// Receive data on the socket. /// @@ -64,7 +64,7 @@ resource tcp-socket implements ip-socket { /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html /// - https://man7.org/linux/man-pages/man2/bind.2.html - bind: async func(local-address: ip-socket-address) -> expected + bind: func(local-address: ip-socket-address) -> future> /// Get the current bound address. /// @@ -83,7 +83,7 @@ resource tcp-socket implements ip-socket { /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html /// - https://man7.org/linux/man-pages/man2/connect.2.html - connect: async func(remote-address: ip-socket-address) -> expected + connect: func(remote-address: ip-socket-address) -> future> /// Start listening for new connections. /// @@ -93,7 +93,7 @@ resource tcp-socket implements ip-socket { /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html /// - https://man7.org/linux/man-pages/man2/listen.2.html - listen: async func(backlog-size-hint: option) -> expected + listen: func(backlog-size-hint: option) -> future> /// Fails when the socket is not in the Connection state. /// diff --git a/proposals/sockets/wasi-socket-udp.wit b/proposals/sockets/wasi-socket-udp.wit index 304d5f50c..bbb0d7bd3 100644 --- a/proposals/sockets/wasi-socket-udp.wit +++ b/proposals/sockets/wasi-socket-udp.wit @@ -25,7 +25,7 @@ resource udp-socket implements ip-socket { /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html /// - https://man7.org/linux/man-pages/man2/socket.2.html /// - static new: async func(network: handle network, address-family: ip-address-family) -> expected + static new: func(network: handle network, address-family: ip-address-family) -> future> /// Bind the socket to a specific IP address and port. /// @@ -45,7 +45,7 @@ resource udp-socket implements ip-socket { /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html /// - https://man7.org/linux/man-pages/man2/bind.2.html - bind: async func(local-address: ip-socket-address) -> expected + bind: func(local-address: ip-socket-address) -> future> /// Get the current bound address. /// @@ -68,7 +68,7 @@ resource udp-socket implements ip-socket { /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html /// - https://man7.org/linux/man-pages/man2/recv.2.html - receive: async func() -> expected + receive: func() -> future> /// send a message to a specific destination address. /// @@ -79,7 +79,7 @@ resource udp-socket implements ip-socket { /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html /// - https://man7.org/linux/man-pages/man2/send.2.html - send: async func(datagram: datagram) -> expected + send: func(datagram: datagram) -> future> /// Set the destination address. /// @@ -100,7 +100,7 @@ resource udp-socket implements ip-socket { /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html /// - https://man7.org/linux/man-pages/man2/connect.2.html - connect: async func(remote-address: ip-socket-address) -> expected + connect: func(remote-address: ip-socket-address) -> future> /// Get the address set with `connect`. /// From 493ddb2cafdd7d7dc76a0f83e99c2957c3bd4adb Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 20 Jul 2022 12:36:24 -0700 Subject: [PATCH 0979/1772] Fix the docs for `info` to reference the correct POSIX function. Say `fcntl` instead of `fsync`, as the corresponding POSIX function to the `info` function. Fixes #22. --- proposals/filesystem/wasi-filesystem.wit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 7191e28da..439c87a81 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -458,7 +458,7 @@ datasync: func() -> expected ```wit /// Get information associated with a descriptor. /// -/// Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well +/// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX, as well /// as additional fields. /// /// Note: This was called `fdstat_get` in earlier versions of WASI. From ba71a0a159d1e7ad64e7a54f426635f70da2fd63 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 20 Jul 2022 12:39:03 -0700 Subject: [PATCH 0980/1772] Update wasi-filesystem.abi.md. --- proposals/filesystem/wasi-filesystem.abi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index dd7802870..af5e23e7e 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -724,7 +724,7 @@ Size: 16, Alignment: 8 Get information associated with a descriptor. - Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well + Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX, as well as additional fields. Note: This was called `fdstat_get` in earlier versions of WASI. From 01231acede3f70873d5cb7b9a3f662793b3750e4 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 22 Sep 2022 13:16:06 -0700 Subject: [PATCH 0981/1772] Remove unused `errno` values, and document others. (#57) * Remove unused `errno` values, and document others. Remove `dom`, `notconn`, `notsock`, `proto`, `protonosupport`, and `prototype` from the wasi-filesystem `errno` enum. These codes aren't used by filesystem APIs. wasi-libc will be synthesizing its own errno code, so we don't need wasi-filesystem to have errno codes that it itself isn't using. Fixes #29. * Update wasi-filesystem.abi.md. --- proposals/filesystem/wasi-filesystem.abi.md | 32 +++------------------ proposals/filesystem/wasi-filesystem.wit.md | 20 +++---------- 2 files changed, 8 insertions(+), 44 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index af5e23e7e..be65deb45 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -385,13 +385,9 @@ Size: 1, Alignment: 1 Destination address required. -- [`dom`](#errno.dom) - - Mathematics argument out of domain of function. - - [`dquot`](#errno.dquot) - Reserved. + Storage quota exceeded. - [`exist`](#errno.exist) @@ -459,7 +455,7 @@ Size: 1, Alignment: 1 - [`multihop`](#errno.multihop) - Reserved. + Multihop attempted. - [`nametoolong`](#errno.nametoolong) @@ -503,7 +499,7 @@ Size: 1, Alignment: 1 - [`nolink`](#errno.nolink) - Reserved. + Link has been severed. - [`nomem`](#errno.nomem) @@ -525,10 +521,6 @@ Size: 1, Alignment: 1 Function not supported. -- [`notconn`](#errno.notconn) - - The socket is not connected. - - [`notdir`](#errno.notdir) Not a directory or a symbolic link to a directory. @@ -541,10 +533,6 @@ Size: 1, Alignment: 1 State not recoverable. -- [`notsock`](#errno.notsock) - - Not a socket. - - [`notsup`](#errno.notsup) Not supported, or operation not supported on socket. @@ -573,18 +561,6 @@ Size: 1, Alignment: 1 Broken pipe. -- [`proto`](#errno.proto) - - Protocol error. - -- [`protonosupport`](#errno.protonosupport) - - Protocol not supported. - -- [`prototype`](#errno.prototype) - - Protocol wrong type for socket. - - [`range`](#errno.range) Result too large. @@ -603,7 +579,7 @@ Size: 1, Alignment: 1 - [`stale`](#errno.stale) - Reserved. + Stale file handle. - [`timedout`](#errno.timedout) diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 439c87a81..64eba1c00 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -259,9 +259,7 @@ enum errno { deadlk, /// Destination address required. destaddrreq, - /// Mathematics argument out of domain of function. - dom, - /// Reserved. + /// Storage quota exceeded. dquot, /// File exists. exist, @@ -295,7 +293,7 @@ enum errno { mlink, /// Message too large. msgsize, - /// Reserved. + /// Multihop attempted. multihop, /// Filename too long. nametoolong, @@ -317,7 +315,7 @@ enum errno { noexec, /// No locks available. nolck, - /// Reserved. + /// Link has been severed. nolink, /// Not enough space. nomem, @@ -329,16 +327,12 @@ enum errno { nospc, /// Function not supported. nosys, - /// The socket is not connected. - notconn, /// Not a directory or a symbolic link to a directory. notdir, /// Directory not empty. notempty, /// State not recoverable. notrecoverable, - /// Not a socket. - notsock, /// Not supported, or operation not supported on socket. notsup, /// Inappropriate I/O control operation. @@ -353,12 +347,6 @@ enum errno { perm, /// Broken pipe. pipe, - /// Protocol error. - proto, - /// Protocol not supported. - protonosupport, - /// Protocol wrong type for socket. - prototype, /// Result too large. range, /// Read-only file system. @@ -367,7 +355,7 @@ enum errno { spipe, /// No such process. srch, - /// Reserved. + /// Stale file handle. stale, /// Connection timed out. timedout, From 74e21436e90e4f66d17f1c03da597675e4ae5649 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 22 Sep 2022 13:16:40 -0700 Subject: [PATCH 0982/1772] Remove the `success` errno field. (#56) We now use the `expected` type to report errors, so we no longer need a success field in the wasi-filesystem errno enum. wasi-libc will be synthesizing its own `errno` value to present a POSIX abstraction, so it doesn't depend on having a zero "success" value in this enum. Fixes #54. --- proposals/filesystem/wasi-filesystem.abi.md | 4 ---- proposals/filesystem/wasi-filesystem.wit.md | 2 -- 2 files changed, 6 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index be65deb45..e50c51a8c 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -317,10 +317,6 @@ Size: 1, Alignment: 1 ### Enum Cases -- [`success`](#errno.success) - - No error occurred. System call completed successfully. - - [`toobig`](#errno.toobig) Argument list too long. This is similar to `E2BIG` in POSIX. diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 64eba1c00..65d8c9129 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -225,8 +225,6 @@ record dirent { /// API; some are used in higher-level library layers, and others are provided /// merely for alignment with POSIX. enum errno { - /// No error occurred. System call completed successfully. - success, /// Argument list too long. This is similar to `E2BIG` in POSIX. toobig, /// Permission denied. From b06f03e5d1bb8144065aabe770c6590648b66c56 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 22 Sep 2022 13:18:49 -0700 Subject: [PATCH 0983/1772] Remove the `read` and `write` functions. (#55) * Remove the `read` and `write` functions. We can implement libc `read` and `write` using `pread` and `pwrite` and using the streams to stream through files. And this simplifies the `descriptor` resource, as it no longer needs an exposed "current position" state. * Update wasi-filesystem.abi.md. --- proposals/filesystem/wasi-filesystem.abi.md | 31 --------------------- proposals/filesystem/wasi-filesystem.wit.md | 21 -------------- 2 files changed, 52 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index e50c51a8c..85131de22 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -774,22 +774,6 @@ Size: 16, Alignment: 8 ---- -#### `descriptor::read` - - Read from a descriptor. - - The meaning of `read` on a directory is unspecified. - - Note: This is similar to `read` in POSIX. -##### Params - -- `self`: handle -##### Result - -- stream<`u8`, [`errno`](#errno)> - ----- - #### `descriptor::readdir` Read directory entries from a directory. @@ -862,21 +846,6 @@ Size: 16, Alignment: 8 ---- -#### `descriptor::write` - - Write to a descriptor. - - Note: This is similar to `write` in POSIX. -##### Params - -- `self`: handle -- `buf`: stream<`u8`, `unit`> -##### Result - -- future> - ----- - #### `descriptor::create-directory-at` Create a directory. diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 65d8c9129..c82d52059 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -499,16 +499,6 @@ pwrite: func( ) -> future> ``` -## `read` -```wit -/// Read from a descriptor. -/// -/// The meaning of `read` on a directory is unspecified. -/// -/// Note: This is similar to `read` in POSIX. -read: func() -> stream -``` - ## `readdir` ```wit /// Read directory entries from a directory. @@ -561,17 +551,6 @@ sync: func() -> expected tell: func() -> expected ``` -## `write` -```wit -/// Write to a descriptor. -/// -/// Note: This is similar to `write` in POSIX. -write: func( - /// Data to write - buf: stream, -) -> future> -``` - ## `create-directory-at` ```wit /// Create a directory. From 44853d866ec22ab6acdc5e38bc1116940d634df7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Sep 2022 10:51:09 -0700 Subject: [PATCH 0984/1772] Update wit syntax to match the latest wit-bindgen. (#60) * Update wit syntax to match the latest wit-bindgen. This invvolves the removal of the `unit` type, renaming `expected` to `result`. * Update wasi-filesystem.abi.md. --- proposals/filesystem/wasi-filesystem.abi.md | 50 ++++++++++----------- proposals/filesystem/wasi-filesystem.wit.md | 46 +++++++++---------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index 85131de22..17169e8a6 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -273,11 +273,11 @@ Size: 16, Alignment: 8 ### Variant Cases -- [`no-change`](#new_timestamp.no_change): `unit` +- [`no-change`](#new_timestamp.no_change) Leave the timestamp set to its previous value. -- [`now`](#new_timestamp.now): `unit` +- [`now`](#new_timestamp.now) Set the timestamp to the current time of the system clock associated with the filesystem. @@ -658,7 +658,7 @@ Size: 16, Alignment: 8 - `advice`: [`advice`](#advice) ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -674,7 +674,7 @@ Size: 16, Alignment: 8 - `len`: [`filesize`](#filesize) ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -688,7 +688,7 @@ Size: 16, Alignment: 8 - `self`: handle ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -705,7 +705,7 @@ Size: 16, Alignment: 8 - `self`: handle ##### Result -- expected<[`info`](#info), [`errno`](#errno)> +- result<[`info`](#info), [`errno`](#errno)> ---- @@ -721,7 +721,7 @@ Size: 16, Alignment: 8 - `size`: [`filesize`](#filesize) ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -739,7 +739,7 @@ Size: 16, Alignment: 8 - `mtim`: [`new-timestamp`](#new_timestamp) ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -766,11 +766,11 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `buf`: stream<`u8`, `unit`> +- `buf`: stream<`u8`> - `offset`: [`filesize`](#filesize) ##### Result -- future> +- future> ---- @@ -812,7 +812,7 @@ Size: 16, Alignment: 8 - `from`: [`seek-from`](#seek_from) ##### Result -- expected<[`filesize`](#filesize), [`errno`](#errno)> +- result<[`filesize`](#filesize), [`errno`](#errno)> ---- @@ -826,7 +826,7 @@ Size: 16, Alignment: 8 - `self`: handle ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -842,7 +842,7 @@ Size: 16, Alignment: 8 - `self`: handle ##### Result -- expected<[`filesize`](#filesize), [`errno`](#errno)> +- result<[`filesize`](#filesize), [`errno`](#errno)> ---- @@ -857,7 +857,7 @@ Size: 16, Alignment: 8 - `path`: `string` ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -875,7 +875,7 @@ Size: 16, Alignment: 8 - `path`: `string` ##### Result -- expected<[`stat`](#stat), [`errno`](#errno)> +- result<[`stat`](#stat), [`errno`](#errno)> ---- @@ -895,7 +895,7 @@ Size: 16, Alignment: 8 - `mtim`: [`new-timestamp`](#new_timestamp) ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -913,7 +913,7 @@ Size: 16, Alignment: 8 - `new-path`: `string` ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -938,7 +938,7 @@ Size: 16, Alignment: 8 - `mode`: [`mode`](#mode) ##### Result -- expected, [`errno`](#errno)> +- result, [`errno`](#errno)> ---- @@ -953,7 +953,7 @@ Size: 16, Alignment: 8 - `path`: `string` ##### Result -- expected<`string`, [`errno`](#errno)> +- result<`string`, [`errno`](#errno)> ---- @@ -970,7 +970,7 @@ Size: 16, Alignment: 8 - `path`: `string` ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -987,7 +987,7 @@ Size: 16, Alignment: 8 - `new-path`: `string` ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -1003,7 +1003,7 @@ Size: 16, Alignment: 8 - `new-path`: `string` ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -1019,7 +1019,7 @@ Size: 16, Alignment: 8 - `path`: `string` ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -1039,7 +1039,7 @@ Size: 16, Alignment: 8 - `mode`: [`mode`](#mode) ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -1063,5 +1063,5 @@ Size: 16, Alignment: 8 - `mode`: [`mode`](#mode) ##### Result -- expected<`unit`, [`errno`](#errno)> +- result<_, [`errno`](#errno)> diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index c82d52059..738388e98 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -416,7 +416,7 @@ fadvise: func( len: u64, /// The advice. advice: advice -) -> expected +) -> result<_, errno> ``` ## `fallocate` @@ -429,7 +429,7 @@ fallocate: func( offset: filesize, /// The length of the area that is allocated. len: filesize -) -> expected +) -> result<_, errno> ``` ## `fdatasync` @@ -437,7 +437,7 @@ fallocate: func( /// Synchronize the data of a file to disk. /// /// Note: This is similar to `fdatasync` in POSIX. -datasync: func() -> expected +datasync: func() -> result<_, errno> ``` ## `info` @@ -448,7 +448,7 @@ datasync: func() -> expected /// as additional fields. /// /// Note: This was called `fdstat_get` in earlier versions of WASI. -info: func() -> expected +info: func() -> result ``` ## `set-size` @@ -457,7 +457,7 @@ info: func() -> expected /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. -set-size: func(size: filesize) -> expected +set-size: func(size: filesize) -> result<_, errno> ``` ## `set-times` @@ -472,7 +472,7 @@ set-times: func( atim: new-timestamp, /// The desired values of the data modification timestamp. mtim: new-timestamp, -) -> expected +) -> result<_, errno> ``` ## `pread` @@ -493,10 +493,10 @@ pread: func( /// Note: This is similar to `pwrite` in POSIX. pwrite: func( /// Data to write - buf: stream, + buf: stream, /// The offset within the file at which to write. offset: filesize, -) -> future> +) -> future> ``` ## `readdir` @@ -530,7 +530,7 @@ readdir: func( seek: func( /// The method to compute the new offset. %from: seek-from, -) -> expected +) -> result ``` ## `sync` @@ -538,7 +538,7 @@ seek: func( /// Synchronize the data and metadata of a file to disk. /// /// Note: This is similar to `fsync` in POSIX. -sync: func() -> expected +sync: func() -> result<_, errno> ``` ## `tell` @@ -548,7 +548,7 @@ sync: func() -> expected /// Returns the current offset of the descriptor, relative to the start of the file. /// /// Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. -tell: func() -> expected +tell: func() -> result ``` ## `create-directory-at` @@ -559,7 +559,7 @@ tell: func() -> expected create-directory-at: func( /// The relative path at which to create the directory. path: string, -) -> expected +) -> result<_, errno> ``` ## `stat-at` @@ -574,7 +574,7 @@ stat-at: func( at-flags: at-flags, /// The relative path of the file or directory to inspect. path: string, -) -> expected +) -> result ``` ## `set-times-at` @@ -593,7 +593,7 @@ set-times-at: func( atim: new-timestamp, /// The desired values of the data modification timestamp. mtim: new-timestamp, -) -> expected +) -> result<_, errno> ``` ## `link-at` @@ -610,7 +610,7 @@ link-at: func( new-descriptor: handle descriptor, /// The relative destination path at which to create the hard link. new-path: string, -) -> expected +) -> result<_, errno> ``` ## `open-at` @@ -635,7 +635,7 @@ open-at: func( %flags: %flags, /// Permissions to use when creating a new file. mode: mode -) -> expected +) -> result ``` ## `readlink-at` @@ -646,7 +646,7 @@ open-at: func( readlink-at: func( /// The relative path of the symbolic link from which to read. path: string, -) -> expected +) -> result ``` ## `remove-directory-at` @@ -659,7 +659,7 @@ readlink-at: func( remove-directory-at: func( /// The relative path to a directory to remove. path: string, -) -> expected +) -> result<_, errno> ``` ## `rename-at` @@ -674,7 +674,7 @@ rename-at: func( new-descriptor: handle descriptor, /// The relative destination path to which to rename the file or directory. new-path: string, -) -> expected +) -> result<_, errno> ``` ## `symlink-at` @@ -687,7 +687,7 @@ symlink-at: func( old-path: string, /// The relative destination path at which to create the symbolic link. new-path: string, -) -> expected +) -> result<_, errno> ``` ## `unlink-file-at` @@ -699,7 +699,7 @@ symlink-at: func( unlink-file-at: func( /// The relative path to a file to unlink. path: string, -) -> expected +) -> result<_, errno> ``` ## `change-file-permissions-at` @@ -717,7 +717,7 @@ change-file-permissions-at: func( path: string, /// The new permissions for the filesystem object. mode: mode, -) -> expected +) -> result<_, errno> ``` ## `change-dir-permissions-at` @@ -739,7 +739,7 @@ change-directory-permissions-at: func( path: string, /// The new permissions for the directory. mode: mode, -) -> expected +) -> result<_, errno> ``` ```wit From b90918fb407f8ecace301103be74772e67e65e00 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 22 Sep 2022 14:24:36 -0700 Subject: [PATCH 0985/1772] Update to the latest wit-bindgen syntax. --- proposals/clocks/wasi-clocks.abi.md | 2 +- proposals/clocks/wasi-clocks.wit.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/wasi-clocks.abi.md b/proposals/clocks/wasi-clocks.abi.md index 5c81f5ef3..f40ae2cf0 100644 --- a/proposals/clocks/wasi-clocks.abi.md +++ b/proposals/clocks/wasi-clocks.abi.md @@ -123,5 +123,5 @@ Size: 16, Alignment: 8 - `self`: handle ##### Result -- future<`unit`> +- future diff --git a/proposals/clocks/wasi-clocks.wit.md b/proposals/clocks/wasi-clocks.wit.md index 51579aefc..4a2f5757c 100644 --- a/proposals/clocks/wasi-clocks.wit.md +++ b/proposals/clocks/wasi-clocks.wit.md @@ -114,7 +114,7 @@ current: func() -> instant ## `expiration` ```wit /// Returns a future that completes when the timer reaches zero. -expiration: func() -> future +expiration: func() -> future ``` ```wit From 52d600faf738f4bbabcb1a8ea7dd4fd10edaa1ff Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Sep 2022 13:26:09 -0700 Subject: [PATCH 0986/1772] Update to the latest wit-api-up-to-date. (#61) * Update to the latest wit-api-up-to-date. * Update wasi-filesystem.abi.md. --- .../filesystem/.github/workflows/main.yml | 4 +- proposals/filesystem/wasi-filesystem.abi.md | 48 +++++++++---------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index f5a35ef04..b05870f53 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v5 + - uses: WebAssembly/wit-abi-up-to-date@v6 with: - wit-abi-tag: wit-abi-0.4.0 + wit-abi-tag: wit-abi-0.5.0 diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index 17169e8a6..3d8ee89e7 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -656,7 +656,7 @@ Size: 16, Alignment: 8 - `offset`: `u64` - `len`: `u64` - `advice`: [`advice`](#advice) -##### Result +##### Results - result<_, [`errno`](#errno)> @@ -672,7 +672,7 @@ Size: 16, Alignment: 8 - `self`: handle - `offset`: [`filesize`](#filesize) - `len`: [`filesize`](#filesize) -##### Result +##### Results - result<_, [`errno`](#errno)> @@ -686,7 +686,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Result +##### Results - result<_, [`errno`](#errno)> @@ -703,7 +703,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Result +##### Results - result<[`info`](#info), [`errno`](#errno)> @@ -719,7 +719,7 @@ Size: 16, Alignment: 8 - `self`: handle - `size`: [`filesize`](#filesize) -##### Result +##### Results - result<_, [`errno`](#errno)> @@ -737,7 +737,7 @@ Size: 16, Alignment: 8 - `self`: handle - `atim`: [`new-timestamp`](#new_timestamp) - `mtim`: [`new-timestamp`](#new_timestamp) -##### Result +##### Results - result<_, [`errno`](#errno)> @@ -752,7 +752,7 @@ Size: 16, Alignment: 8 - `self`: handle - `offset`: [`filesize`](#filesize) -##### Result +##### Results - stream<`u8`, [`errno`](#errno)> @@ -768,7 +768,7 @@ Size: 16, Alignment: 8 - `self`: handle - `buf`: stream<`u8`> - `offset`: [`filesize`](#filesize) -##### Result +##### Results - future> @@ -791,7 +791,7 @@ Size: 16, Alignment: 8 - `self`: handle - `rewind`: `bool` -##### Result +##### Results - stream<`u8`, [`errno`](#errno)> @@ -810,7 +810,7 @@ Size: 16, Alignment: 8 - `self`: handle - `from`: [`seek-from`](#seek_from) -##### Result +##### Results - result<[`filesize`](#filesize), [`errno`](#errno)> @@ -824,7 +824,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Result +##### Results - result<_, [`errno`](#errno)> @@ -840,7 +840,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Result +##### Results - result<[`filesize`](#filesize), [`errno`](#errno)> @@ -855,7 +855,7 @@ Size: 16, Alignment: 8 - `self`: handle - `path`: `string` -##### Result +##### Results - result<_, [`errno`](#errno)> @@ -873,7 +873,7 @@ Size: 16, Alignment: 8 - `self`: handle - `at-flags`: [`at-flags`](#at_flags) - `path`: `string` -##### Result +##### Results - result<[`stat`](#stat), [`errno`](#errno)> @@ -893,7 +893,7 @@ Size: 16, Alignment: 8 - `path`: `string` - `atim`: [`new-timestamp`](#new_timestamp) - `mtim`: [`new-timestamp`](#new_timestamp) -##### Result +##### Results - result<_, [`errno`](#errno)> @@ -911,7 +911,7 @@ Size: 16, Alignment: 8 - `old-path`: `string` - `new-descriptor`: handle - `new-path`: `string` -##### Result +##### Results - result<_, [`errno`](#errno)> @@ -936,7 +936,7 @@ Size: 16, Alignment: 8 - `o-flags`: [`o-flags`](#o_flags) - `flags`: [`flags`](#flags) - `mode`: [`mode`](#mode) -##### Result +##### Results - result, [`errno`](#errno)> @@ -951,7 +951,7 @@ Size: 16, Alignment: 8 - `self`: handle - `path`: `string` -##### Result +##### Results - result<`string`, [`errno`](#errno)> @@ -968,7 +968,7 @@ Size: 16, Alignment: 8 - `self`: handle - `path`: `string` -##### Result +##### Results - result<_, [`errno`](#errno)> @@ -985,7 +985,7 @@ Size: 16, Alignment: 8 - `old-path`: `string` - `new-descriptor`: handle - `new-path`: `string` -##### Result +##### Results - result<_, [`errno`](#errno)> @@ -1001,7 +1001,7 @@ Size: 16, Alignment: 8 - `self`: handle - `old-path`: `string` - `new-path`: `string` -##### Result +##### Results - result<_, [`errno`](#errno)> @@ -1017,7 +1017,7 @@ Size: 16, Alignment: 8 - `self`: handle - `path`: `string` -##### Result +##### Results - result<_, [`errno`](#errno)> @@ -1037,7 +1037,7 @@ Size: 16, Alignment: 8 - `at-flags`: [`at-flags`](#at_flags) - `path`: `string` - `mode`: [`mode`](#mode) -##### Result +##### Results - result<_, [`errno`](#errno)> @@ -1061,7 +1061,7 @@ Size: 16, Alignment: 8 - `at-flags`: [`at-flags`](#at_flags) - `path`: `string` - `mode`: [`mode`](#mode) -##### Result +##### Results - result<_, [`errno`](#errno)> From 04d99eafa5cfdff16b16aa3faff1e9e5d55478bf Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Sep 2022 13:29:36 -0700 Subject: [PATCH 0987/1772] Sunfishcode/update wit api up to date (#21) * Update to the latest wit-api-up-to-date. * Update wasii-clocks.abi.md. --- proposals/clocks/.github/workflows/main.yml | 4 ++-- proposals/clocks/wasi-clocks.abi.md | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index f5a35ef04..b05870f53 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v5 + - uses: WebAssembly/wit-abi-up-to-date@v6 with: - wit-abi-tag: wit-abi-0.4.0 + wit-abi-tag: wit-abi-0.5.0 diff --git a/proposals/clocks/wasi-clocks.abi.md b/proposals/clocks/wasi-clocks.abi.md index f40ae2cf0..e24584ab2 100644 --- a/proposals/clocks/wasi-clocks.abi.md +++ b/proposals/clocks/wasi-clocks.abi.md @@ -33,7 +33,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Result +##### Results - [`instant`](#instant) @@ -45,7 +45,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Result +##### Results - [`instant`](#instant) @@ -59,7 +59,7 @@ Size: 16, Alignment: 8 - `self`: handle - `initial`: [`instant`](#instant) -##### Result +##### Results - handle @@ -83,7 +83,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Result +##### Results - [`datetime`](#datetime) @@ -97,7 +97,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Result +##### Results - [`datetime`](#datetime) @@ -109,7 +109,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Result +##### Results - [`instant`](#instant) @@ -121,7 +121,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -##### Result +##### Results - future From 98444cac2d86438a4f6c1b7aecb877a1d08cb0f7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Sep 2022 13:29:15 -0700 Subject: [PATCH 0988/1772] Update to the latest wasi-abi-up-to-date. --- proposals/random/.github/workflows/main.yml | 4 ++-- proposals/random/wasi-random.abi.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index f5a35ef04..b05870f53 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v5 + - uses: WebAssembly/wit-abi-up-to-date@v6 with: - wit-abi-tag: wit-abi-0.4.0 + wit-abi-tag: wit-abi-0.5.0 diff --git a/proposals/random/wasi-random.abi.md b/proposals/random/wasi-random.abi.md index df192a9b0..2fc88e39b 100644 --- a/proposals/random/wasi-random.abi.md +++ b/proposals/random/wasi-random.abi.md @@ -14,7 +14,7 @@ ##### Params - `len`: `u32` -##### Result +##### Results - list<`u8`> From 7e1b745b3f37478f09cb3a05b215631ebb33f33a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 10 Oct 2022 13:59:38 -0700 Subject: [PATCH 0989/1772] Add byte lengths to `pread` and `pwrite`. (#63) Add a length parameter to `pread` to specify how many bytes to attempt to read, as otherwise there's no way for it to know how many bytes to read. Similarly, add a length result to `pwrite` indicating how many bytes were written, since there's otherwise no other indication of the number of bytes written. --- proposals/filesystem/wasi-filesystem.abi.md | 3 ++- proposals/filesystem/wasi-filesystem.wit.md | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index 3d8ee89e7..aaab14911 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -751,6 +751,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle +- `len`: [`size`](#size) - `offset`: [`filesize`](#filesize) ##### Results @@ -770,7 +771,7 @@ Size: 16, Alignment: 8 - `offset`: [`filesize`](#filesize) ##### Results -- future> +- future> ---- diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 738388e98..15f6fdbc3 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -481,6 +481,8 @@ set-times: func( /// /// Note: This is similar to `pread` in POSIX. pread: func( + /// The maximim number of bytes to read. + len: size, /// The offset within the file at which to read. offset: filesize, ) -> stream @@ -496,7 +498,7 @@ pwrite: func( buf: stream, /// The offset within the file at which to write. offset: filesize, -) -> future> +) -> future> ``` ## `readdir` From debc353804b057ffd578206c18ed64bbd2195c61 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 10 Oct 2022 13:59:59 -0700 Subject: [PATCH 0990/1772] Re-introduce the `badf` filesystem error code. (#62) * Re-introduce the `badf` filesystem error code. POSIX overloads `EBADF` with two meanings: file descriptor out of bounds, and attempt to read or write on a device that doesn't support reading or writing, respectively. In WASI, the former meaning is being handled at the WIT level, but the latter meaning still applies, so reintroduce `badf` as an error code. * Update wasi-filesystem.abi.md --- proposals/filesystem/wasi-filesystem.abi.md | 4 ++++ proposals/filesystem/wasi-filesystem.wit.md | 2 ++ 2 files changed, 6 insertions(+) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index aaab14911..c721ede12 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -345,6 +345,10 @@ Size: 1, Alignment: 1 Connection already in progress. +- [`badf`](#errno.badf) + + Bad file descriptor. + - [`badmsg`](#errno.badmsg) Bad message. diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 15f6fdbc3..b20615d5c 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -239,6 +239,8 @@ enum errno { again, /// Connection already in progress. already, + /// Bad file descriptor. + badf, /// Bad message. badmsg, /// Device or resource busy. From 4fec02f5ccb1f56074afcf4d929e02d078f4783a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 19 Oct 2022 14:58:54 -0700 Subject: [PATCH 0991/1772] Remove `allocate`. (#64) * Remove `allocate`. There does not appear to be a way to implement `allocate` in a non-racy way on Windows or macOS. Fixes #19. * Update wasi-filesystem.abi.md. --- proposals/filesystem/wasi-filesystem.abi.md | 16 ---------------- proposals/filesystem/wasi-filesystem.wit.md | 13 ------------- 2 files changed, 29 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index c721ede12..34d1ec065 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -666,22 +666,6 @@ Size: 16, Alignment: 8 ---- -#### `descriptor::fallocate` - - Force the allocation of space in a file. - - Note: This is similar to `posix_fallocate` in POSIX. -##### Params - -- `self`: handle -- `offset`: [`filesize`](#filesize) -- `len`: [`filesize`](#filesize) -##### Results - -- result<_, [`errno`](#errno)> - ----- - #### `descriptor::datasync` Synchronize the data of a file to disk. diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index b20615d5c..5a06498c3 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -421,19 +421,6 @@ fadvise: func( ) -> result<_, errno> ``` -## `fallocate` -```wit -/// Force the allocation of space in a file. -/// -/// Note: This is similar to `posix_fallocate` in POSIX. -fallocate: func( - /// The offset at which to start the allocation. - offset: filesize, - /// The length of the area that is allocated. - len: filesize -) -> result<_, errno> -``` - ## `fdatasync` ```wit /// Synchronize the data of a file to disk. From dad27c2f826865036dc92aebf1adf0d491006ccf Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 23 Nov 2022 12:50:51 -0800 Subject: [PATCH 0992/1772] Rename `info` to `fd-info`, and other minor fixes. (#66) * Rename `info` to `fd-info`, and other minor fixes. Rename the `info` function to `fd-info`, to avoid a name collision with the `info` type. While here, also fix the documentation name for the `datasync` function. And use `filesize` and for fadvise arguments. * Swap `info` and `fd-info`. It feels more natural to have the function be named `info` and the record `fd-info`. `info` is a method of the `descriptor` resource, which provides a scope, while `fd-info` is just a standalone record. --- proposals/filesystem/wasi-filesystem.abi.md | 12 ++++++------ proposals/filesystem/wasi-filesystem.wit.md | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index 34d1ec065..3dc7f0ca3 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -26,7 +26,7 @@ Size: 8, Alignment: 8 Size: 8, Alignment: 8 -## `info`: record +## `fd-info`: record Information associated with a descriptor. @@ -36,11 +36,11 @@ Size: 2, Alignment: 1 ### Record Fields -- [`type`](#info.type): [`type`](#type) +- [`type`](#fd_info.type): [`type`](#type) The type of filesystem object referenced by a descriptor. -- [`flags`](#info.flags): [`flags`](#flags) +- [`flags`](#fd_info.flags): [`flags`](#flags) Flags associated with a descriptor. @@ -657,8 +657,8 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `offset`: `u64` -- `len`: `u64` +- `offset`: [`filesize`](#filesize) +- `len`: [`size`](#size) - `advice`: [`advice`](#advice) ##### Results @@ -693,7 +693,7 @@ Size: 16, Alignment: 8 - `self`: handle ##### Results -- result<[`info`](#info), [`errno`](#errno)> +- result<[`fd-info`](#fd_info), [`errno`](#errno)> ---- diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 5a06498c3..cedcd5d36 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -40,12 +40,12 @@ type filedelta = s64 type timestamp = u64 ``` -## `info` +## `fd-info` ```wit /// Information associated with a descriptor. /// /// Note: This was called `fdstat` in earlier versions of WASI. -record info { +record fd-info { /// The type of filesystem object referenced by a descriptor. %type: %type, /// Flags associated with a descriptor. @@ -413,15 +413,15 @@ resource descriptor { /// This is similar to `posix_fadvise` in POSIX. fadvise: func( /// The offset within the file to which the advisory applies. - offset: u64, + offset: filesize, /// The length of the region to which the advisory applies. - len: u64, + len: size, /// The advice. advice: advice ) -> result<_, errno> ``` -## `fdatasync` +## `datasync` ```wit /// Synchronize the data of a file to disk. /// @@ -437,7 +437,7 @@ datasync: func() -> result<_, errno> /// as additional fields. /// /// Note: This was called `fdstat_get` in earlier versions of WASI. -info: func() -> result +info: func() -> result ``` ## `set-size` From 3f74d8421f7c85fa1de8150a16a1c50f9b1f96e2 Mon Sep 17 00:00:00 2001 From: Dan Chiarlone Date: Wed, 23 Nov 2022 15:05:54 -0800 Subject: [PATCH 0993/1772] updated wit-abi to a version that addresses the moving of wit-parser off of wit-bindgen - previous ones fail (#1) Signed-off-by: danbugs Signed-off-by: danbugs --- proposals/io/.github/workflows/main.yml | 4 ++-- proposals/io/proposal-template.abi.md | 2 +- proposals/io/proposal-template.wit.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index f27c0a23b..a61809957 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v2 + - uses: WebAssembly/wit-abi-up-to-date@v6 with: - wit-abi-tag: wit-abi-0.1.0 + wit-abi-tag: wit-abi-0.6.0 diff --git a/proposals/io/proposal-template.abi.md b/proposals/io/proposal-template.abi.md index 9f935ee8f..7a1c37209 100644 --- a/proposals/io/proposal-template.abi.md +++ b/proposals/io/proposal-template.abi.md @@ -27,5 +27,5 @@ Size: 16, Alignment: 8 Explanation for developers using the API. ##### Results -- ``: [`api-type-one`](#api_type_one) +- [`api-type-one`](#api_type_one) diff --git a/proposals/io/proposal-template.wit.md b/proposals/io/proposal-template.wit.md index efa5364c5..3c7e8efbd 100644 --- a/proposals/io/proposal-template.wit.md +++ b/proposals/io/proposal-template.wit.md @@ -26,7 +26,7 @@ More rigorous specification details for the implementer go here, if needed. /// Short description /// /// Explanation for developers using the API. -api-function-one: function() -> api-type-one +api-function-one: func() -> api-type-one ``` If needed, this would explain what a compliant implementation MUST do, such as never returning an earlier result from a later call. From f92872cdfc7bbbdd09ad5e3b1a480425d5e17afd Mon Sep 17 00:00:00 2001 From: Dan Chiarlone Date: Wed, 23 Nov 2022 15:05:54 -0800 Subject: [PATCH 0994/1772] updated wit-abi to a version that addresses the moving of wit-parser off of wit-bindgen - previous ones fail (#1) Signed-off-by: danbugs Signed-off-by: danbugs --- proposals/sockets/.github/workflows/main.yml | 4 ++-- proposals/sockets/proposal-template.abi.md | 2 +- proposals/sockets/proposal-template.wit.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index f27c0a23b..a61809957 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v2 + - uses: WebAssembly/wit-abi-up-to-date@v6 with: - wit-abi-tag: wit-abi-0.1.0 + wit-abi-tag: wit-abi-0.6.0 diff --git a/proposals/sockets/proposal-template.abi.md b/proposals/sockets/proposal-template.abi.md index 9f935ee8f..7a1c37209 100644 --- a/proposals/sockets/proposal-template.abi.md +++ b/proposals/sockets/proposal-template.abi.md @@ -27,5 +27,5 @@ Size: 16, Alignment: 8 Explanation for developers using the API. ##### Results -- ``: [`api-type-one`](#api_type_one) +- [`api-type-one`](#api_type_one) diff --git a/proposals/sockets/proposal-template.wit.md b/proposals/sockets/proposal-template.wit.md index efa5364c5..3c7e8efbd 100644 --- a/proposals/sockets/proposal-template.wit.md +++ b/proposals/sockets/proposal-template.wit.md @@ -26,7 +26,7 @@ More rigorous specification details for the implementer go here, if needed. /// Short description /// /// Explanation for developers using the API. -api-function-one: function() -> api-type-one +api-function-one: func() -> api-type-one ``` If needed, this would explain what a compliant implementation MUST do, such as never returning an earlier result from a later call. From a64e6880f29de4623a82b407f6adadc929f700ba Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 1 Dec 2022 17:19:50 -0800 Subject: [PATCH 0995/1772] Split `info` into `type` and `flags`, and add a `set-info`. (#70) Split the `info` function into `type` and `flags` functions, which return each of the fields. Remove the `fd-info` type, which is no longer needed, and rename `fd-type` and `flags` to `descriptor-type` and `descriptor-flags`, respectively. And add a `set-flags` function, which adds `F_SETFL` functionality which was lost in the translation to wit. --- proposals/filesystem/wasi-filesystem.abi.md | 114 ++++++++++++-------- proposals/filesystem/wasi-filesystem.wit.md | 68 +++++++----- 2 files changed, 107 insertions(+), 75 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index 3dc7f0ca3..ee310c160 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -26,25 +26,7 @@ Size: 8, Alignment: 8 Size: 8, Alignment: 8 -## `fd-info`: record - - Information associated with a descriptor. - - Note: This was called `fdstat` in earlier versions of WASI. - -Size: 2, Alignment: 1 - -### Record Fields - -- [`type`](#fd_info.type): [`type`](#type) - - The type of filesystem object referenced by a descriptor. - -- [`flags`](#fd_info.flags): [`flags`](#flags) - - Flags associated with a descriptor. - -## `type`: enum +## `descriptor-type`: enum The type of a filesystem object referenced by a descriptor. @@ -54,82 +36,82 @@ Size: 1, Alignment: 1 ### Enum Cases -- [`unknown`](#type.unknown) +- [`unknown`](#descriptor_type.unknown) The type of the descriptor or file is unknown or is different from any of the other types specified. -- [`block-device`](#type.block_device) +- [`block-device`](#descriptor_type.block_device) The descriptor refers to a block device inode. -- [`character-device`](#type.character_device) +- [`character-device`](#descriptor_type.character_device) The descriptor refers to a character device inode. -- [`directory`](#type.directory) +- [`directory`](#descriptor_type.directory) The descriptor refers to a directory inode. -- [`fifo`](#type.fifo) +- [`fifo`](#descriptor_type.fifo) The descriptor refers to a named pipe. -- [`symbolic-link`](#type.symbolic_link) +- [`symbolic-link`](#descriptor_type.symbolic_link) The file refers to a symbolic link inode. -- [`regular-file`](#type.regular_file) +- [`regular-file`](#descriptor_type.regular_file) The descriptor refers to a regular file inode. -- [`socket`](#type.socket) +- [`socket`](#descriptor_type.socket) The descriptor refers to a socket. -## `flags`: flags +## `descriptor-flags`: flags Descriptor flags. - Note: This was called `fd-flags` in earlier versions of WASI. + Note: This was called `fdflags` in earlier versions of WASI. Size: 1, Alignment: 1 ### Flags Fields -- [`read`](#flags.read) +- [`read`](#descriptor_flags.read) Read mode: Data can be read. Bit: 0 -- [`write`](#flags.write) +- [`write`](#descriptor_flags.write) Write mode: Data can be written to. Bit: 1 -- [`append`](#flags.append) +- [`append`](#descriptor_flags.append) Append mode: Data written to the file is always appended to the file's end. Bit: 2 -- [`dsync`](#flags.dsync) +- [`dsync`](#descriptor_flags.dsync) Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. Bit: 3 -- [`nonblock`](#flags.nonblock) +- [`nonblock`](#descriptor_flags.nonblock) Non-blocking mode. Bit: 4 -- [`rsync`](#flags.rsync) +- [`rsync`](#descriptor_flags.rsync) Synchronized read I/O operations. Bit: 5 -- [`sync`](#flags.sync) +- [`sync`](#descriptor_flags.sync) Write according to synchronized I/O file integrity completion. In addition to synchronizing the data stored in the file, the @@ -154,7 +136,7 @@ Size: 64, Alignment: 8 File serial number. -- [`type`](#stat.type): [`type`](#type) +- [`type`](#stat.type): [`descriptor-type`](#descriptor_type) File type. @@ -302,7 +284,7 @@ Size: 16, Alignment: 8 The length of the name of the directory entry. -- [`type`](#dirent.type): [`type`](#type) +- [`type`](#dirent.type): [`descriptor-type`](#descriptor_type) The type of the file referred to by this directory entry. @@ -347,7 +329,7 @@ Size: 1, Alignment: 1 - [`badf`](#errno.badf) - Bad file descriptor. + Bad descriptor. - [`badmsg`](#errno.badmsg) @@ -680,20 +662,58 @@ Size: 16, Alignment: 8 ---- -#### `descriptor::info` +#### `descriptor::flags` + + Get flags associated with a descriptor. + + Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. + + Note: This returns the value that was the `fs_flags` value returned + from `fdstat_get` in earlier versions of WASI. +##### Params + +- `self`: handle +##### Results + +- result<[`descriptor-flags`](#descriptor_flags), [`errno`](#errno)> + +---- + +#### `descriptor::type` + + Get the dynamic type of a descriptor. + + Note: This returns the same value as the `type` field of the `fd-stat` + returned by `stat`, `stat-at` and similar. + + Note: This returns similar flags to the `st_mode & S_IFMT` value provided + by `fstat` in POSIX. + + Note: This returns the value that was the `fs_filetype` value returned + from `fdstat_get` in earlier versions of WASI. +##### Params + +- `self`: handle +##### Results + +- result<[`descriptor-type`](#descriptor_type), [`errno`](#errno)> + +---- + +#### `descriptor::set-flags` - Get information associated with a descriptor. + Set flags associated with a descriptor. - Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX, as well - as additional fields. + Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - Note: This was called `fdstat_get` in earlier versions of WASI. + Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. ##### Params -- `self`: handle +- `self`: handle +- `flags`: [`descriptor-flags`](#descriptor_flags) ##### Results -- result<[`fd-info`](#fd_info), [`errno`](#errno)> +- result<_, [`errno`](#errno)> ---- @@ -923,7 +943,7 @@ Size: 16, Alignment: 8 - `at-flags`: [`at-flags`](#at_flags) - `path`: `string` - `o-flags`: [`o-flags`](#o_flags) -- `flags`: [`flags`](#flags) +- `flags`: [`descriptor-flags`](#descriptor_flags) - `mode`: [`mode`](#mode) ##### Results diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index cedcd5d36..08c3652f5 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -40,25 +40,12 @@ type filedelta = s64 type timestamp = u64 ``` -## `fd-info` -```wit -/// Information associated with a descriptor. -/// -/// Note: This was called `fdstat` in earlier versions of WASI. -record fd-info { - /// The type of filesystem object referenced by a descriptor. - %type: %type, - /// Flags associated with a descriptor. - %flags: %flags, -} -``` - -## `type` +## `descriptor-type` ```wit /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. -enum %type { +enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. unknown, @@ -79,12 +66,12 @@ enum %type { } ``` -## `flags` +## `descriptor-flags` ```wit /// Descriptor flags. /// -/// Note: This was called `fd-flags` in earlier versions of WASI. -flags %flags { +/// Note: This was called `fdflags` in earlier versions of WASI. +flags descriptor-flags { /// Read mode: Data can be read. read, /// Write mode: Data can be written to. @@ -117,7 +104,7 @@ record stat { /// File serial number. ino: inode, /// File type. - %type: %type, + %type: descriptor-type, /// Number of hard links to the file. nlink: linkcount, /// For regular files, the file size in bytes. For symbolic links, the length @@ -214,7 +201,7 @@ record dirent { /// The length of the name of the directory entry. namelen: size, /// The type of the file referred to by this directory entry. - %type: %type, + %type: descriptor-type, } ``` @@ -239,7 +226,7 @@ enum errno { again, /// Connection already in progress. already, - /// Bad file descriptor. + /// Bad descriptor. badf, /// Bad message. badmsg, @@ -429,15 +416,40 @@ fadvise: func( datasync: func() -> result<_, errno> ``` -## `info` +## `flags` +```wit +/// Get flags associated with a descriptor. +/// +/// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. +/// +/// Note: This returns the value that was the `fs_flags` value returned +/// from `fdstat_get` in earlier versions of WASI. +%flags: func() -> result +``` + +## `type` +```wit +/// Get the dynamic type of a descriptor. +/// +/// Note: This returns the same value as the `type` field of the `fd-stat` +/// returned by `stat`, `stat-at` and similar. +/// +/// Note: This returns similar flags to the `st_mode & S_IFMT` value provided +/// by `fstat` in POSIX. +/// +/// Note: This returns the value that was the `fs_filetype` value returned +/// from `fdstat_get` in earlier versions of WASI. +%type: func() -> result +``` + +## `set-flags` ```wit -/// Get information associated with a descriptor. +/// Set flags associated with a descriptor. /// -/// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX, as well -/// as additional fields. +/// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. /// -/// Note: This was called `fdstat_get` in earlier versions of WASI. -info: func() -> result +/// Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. +set-flags: func(%flags: descriptor-flags) -> result<_, errno> ``` ## `set-size` @@ -623,7 +635,7 @@ open-at: func( /// The method by which to open the file. o-flags: o-flags, /// Flags to use for the resulting descriptor. - %flags: %flags, + %flags: descriptor-flags, /// Permissions to use when creating a new file. mode: mode ) -> result From 046d4e774007a388ead1240e8d8e9e59d444e970 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 1 Dec 2022 17:28:37 -0800 Subject: [PATCH 0996/1772] Add a `stat` function. (#68) * Update to wit-abi-0.6.0. * Add a `stat` function. This corresponds to `fstat` in POSIX. This was in preview1, and was an accidental omission in the translation to wit here. --- .../filesystem/.github/workflows/main.yml | 2 +- proposals/filesystem/wasi-filesystem.abi.md | 38 +++++++++++++------ proposals/filesystem/wasi-filesystem.wit.md | 18 +++++++-- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index b05870f53..a61809957 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -13,4 +13,4 @@ jobs: - uses: actions/checkout@v2 - uses: WebAssembly/wit-abi-up-to-date@v6 with: - wit-abi-tag: wit-abi-0.5.0 + wit-abi-tag: wit-abi-0.6.0 diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index ee310c160..c85954149 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -118,7 +118,7 @@ Bit: 5 implementation may also synchronously update the file's metadata. Bit: 6 -## `stat`: record +## `descriptor-stat`: record File attributes. @@ -128,36 +128,36 @@ Size: 64, Alignment: 8 ### Record Fields -- [`dev`](#stat.dev): [`device`](#device) +- [`dev`](#descriptor_stat.dev): [`device`](#device) Device ID of device containing the file. -- [`ino`](#stat.ino): [`inode`](#inode) +- [`ino`](#descriptor_stat.ino): [`inode`](#inode) File serial number. -- [`type`](#stat.type): [`descriptor-type`](#descriptor_type) +- [`type`](#descriptor_stat.type): [`descriptor-type`](#descriptor_type) File type. -- [`nlink`](#stat.nlink): [`linkcount`](#linkcount) +- [`nlink`](#descriptor_stat.nlink): [`linkcount`](#linkcount) Number of hard links to the file. -- [`size`](#stat.size): [`filesize`](#filesize) +- [`size`](#descriptor_stat.size): [`filesize`](#filesize) For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. -- [`atim`](#stat.atim): [`timestamp`](#timestamp) +- [`atim`](#descriptor_stat.atim): [`timestamp`](#timestamp) Last data access timestamp. -- [`mtim`](#stat.mtim): [`timestamp`](#timestamp) +- [`mtim`](#descriptor_stat.mtim): [`timestamp`](#timestamp) Last data modification timestamp. -- [`ctim`](#stat.ctim): [`timestamp`](#timestamp) +- [`ctim`](#descriptor_stat.ctim): [`timestamp`](#timestamp) Last file status change timestamp. @@ -870,13 +870,29 @@ Size: 16, Alignment: 8 ---- +#### `descriptor::stat` + + Return the attributes of an open file or directory. + + Note: This is similar to `fstat` in POSIX. + + Note: This was called `fd_filestat_get` in earlier versions of WASI. +##### Params + +- `self`: handle +##### Results + +- result<[`descriptor-stat`](#descriptor_stat), [`errno`](#errno)> + +---- + #### `descriptor::stat-at` Return the attributes of a file or directory. Note: This is similar to `fstatat` in POSIX. - Note: This was called `fd_filestat_get` in earlier versions of WASI. + Note: This was called `path_filestat_get` in earlier versions of WASI. ##### Params - `self`: handle @@ -884,7 +900,7 @@ Size: 16, Alignment: 8 - `path`: `string` ##### Results -- result<[`stat`](#stat), [`errno`](#errno)> +- result<[`descriptor-stat`](#descriptor_stat), [`errno`](#errno)> ---- diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 08c3652f5..38f5e03de 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -93,12 +93,12 @@ flags descriptor-flags { } ``` -## `stat` +## `descriptor-stat` ```wit /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. -record stat { +record descriptor-stat { /// Device ID of device containing the file. dev: device, /// File serial number. @@ -565,19 +565,29 @@ create-directory-at: func( ) -> result<_, errno> ``` +## `stat` +```wit +/// Return the attributes of an open file or directory. +/// +/// Note: This is similar to `fstat` in POSIX. +/// +/// Note: This was called `fd_filestat_get` in earlier versions of WASI. +stat: func() -> result +``` + ## `stat-at` ```wit /// Return the attributes of a file or directory. /// /// Note: This is similar to `fstatat` in POSIX. /// -/// Note: This was called `fd_filestat_get` in earlier versions of WASI. +/// Note: This was called `path_filestat_get` in earlier versions of WASI. stat-at: func( /// Flags determining the method of how the path is resolved. at-flags: at-flags, /// The relative path of the file or directory to inspect. path: string, -) -> result +) -> result ``` ## `set-times-at` From 85199838bf46b08f58ddcada3978128f21108e70 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 1 Dec 2022 17:31:51 -0800 Subject: [PATCH 0997/1772] Add advisory file locking support. (#69) * Add advisory file locking support. Add functions which correspond to `flock` in Unix. This is not a POSIX interface, but it's sufficiently portable, there's a way to implement it on Windows, and it doesn't have problematic process-associated locks. Instead of having a single `flock` function that gets passed and enum, this has separate functions for shared vs. exclusive, and locking vs. non-locking. That's something we can revisit if needed, but it keeps the API simpler for now. * Document what happens if a lock is already held. * Add notes about interactions between WASI locks and non-WASI locks. Also mention that exclusive locks may require write mode on file descriptors, as described in the [Linux `flock` man page]. [Linux `flock` man page]: https://man7.org/linux/man-pages/man2/flock.2.html * Add a comment that not all filesystems support locking. * Update wasi-filesystem.abi.md. --- proposals/filesystem/wasi-filesystem.abi.md | 142 ++++++++++++++++++++ proposals/filesystem/wasi-filesystem.wit.md | 112 +++++++++++++++ 2 files changed, 254 insertions(+) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index c85954149..dfb028b1b 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -1090,3 +1090,145 @@ Size: 16, Alignment: 8 - result<_, [`errno`](#errno)> +---- + +#### `descriptor::lock-shared` + + Request a shared advisory lock for an open file. + + This requests a *shared* lock; more than one shared lock can be held for + a file at the same time. + + If the open file has an exclusive lock, this function downgrades the lock + to a shared lock. If it has a shared lock, this function has no effect. + + This requests an *advisory* lock, meaning that the file could be accessed + by other programs that don't hold the lock. + + It is unspecified how shared locks interact with locks acquired by + non-WASI programs. + + This function blocks until the lock can be acquired. + + Not all filesystems support locking; on filesystems which don't support + locking, this function returns `errno::notsup`. + + Note: This is similar to `flock(fd, LOCK_SH)` in Unix. +##### Params + +- `self`: handle +##### Results + +- result<_, [`errno`](#errno)> + +---- + +#### `descriptor::lock-exclusive` + + Request an exclusive advisory lock for an open file. + + This requests an *exclusive* lock; no other locks may be held for the + file while an exclusive lock is held. + + If the open file has a shared lock and there are no exclusive locks held + for the fhile, this function upgrades the lock to an exclusive lock. If the + open file already has an exclusive lock, this function has no effect. + + This requests an *advisory* lock, meaning that the file could be accessed + by other programs that don't hold the lock. + + It is unspecified whether this function succeeds if the file descriptor + is not opened for writing. It is unspecified how exclusive locks interact + with locks acquired by non-WASI programs. + + This function blocks until the lock can be acquired. + + Not all filesystems support locking; on filesystems which don't support + locking, this function returns `errno::notsup`. + + Note: This is similar to `flock(fd, LOCK_EX)` in Unix. +##### Params + +- `self`: handle +##### Results + +- result<_, [`errno`](#errno)> + +---- + +#### `descriptor::try-lock-shared` + + Request a shared advisory lock for an open file. + + This requests a *shared* lock; more than one shared lock can be held for + a file at the same time. + + If the open file has an exclusive lock, this function downgrades the lock + to a shared lock. If it has a shared lock, this function has no effect. + + This requests an *advisory* lock, meaning that the file could be accessed + by other programs that don't hold the lock. + + It is unspecified how shared locks interact with locks acquired by + non-WASI programs. + + This function returns `errno::wouldblock` if the lock cannot be acquired. + + Not all filesystems support locking; on filesystems which don't support + locking, this function returns `errno::notsup`. + + Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. +##### Params + +- `self`: handle +##### Results + +- result<_, [`errno`](#errno)> + +---- + +#### `descriptor::try-lock-exclusive` + + Request an exclusive advisory lock for an open file. + + This requests an *exclusive* lock; no other locks may be held for the + file while an exclusive lock is held. + + If the open file has a shared lock and there are no exclusive locks held + for the fhile, this function upgrades the lock to an exclusive lock. If the + open file already has an exclusive lock, this function has no effect. + + This requests an *advisory* lock, meaning that the file could be accessed + by other programs that don't hold the lock. + + It is unspecified whether this function succeeds if the file descriptor + is not opened for writing. It is unspecified how exclusive locks interact + with locks acquired by non-WASI programs. + + This function returns `errno::wouldblock` if the lock cannot be acquired. + + Not all filesystems support locking; on filesystems which don't support + locking, this function returns `errno::notsup`. + + Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. +##### Params + +- `self`: handle +##### Results + +- result<_, [`errno`](#errno)> + +---- + +#### `descriptor::unlock` + + Release a shared or exclusive lock on an open file. + + Note: This is similar to `flock(fd, LOCK_UN)` in Unix. +##### Params + +- `self`: handle +##### Results + +- result<_, [`errno`](#errno)> + diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 38f5e03de..0159e1d9d 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -755,6 +755,118 @@ change-directory-permissions-at: func( ) -> result<_, errno> ``` +## `lock-shared` +```wit +/// Request a shared advisory lock for an open file. +/// +/// This requests a *shared* lock; more than one shared lock can be held for +/// a file at the same time. +/// +/// If the open file has an exclusive lock, this function downgrades the lock +/// to a shared lock. If it has a shared lock, this function has no effect. +/// +/// This requests an *advisory* lock, meaning that the file could be accessed +/// by other programs that don't hold the lock. +/// +/// It is unspecified how shared locks interact with locks acquired by +/// non-WASI programs. +/// +/// This function blocks until the lock can be acquired. +/// +/// Not all filesystems support locking; on filesystems which don't support +/// locking, this function returns `errno::notsup`. +/// +/// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. +lock-shared: func() -> result<_, errno> +``` + +## `lock-exclusive` +```wit +/// Request an exclusive advisory lock for an open file. +/// +/// This requests an *exclusive* lock; no other locks may be held for the +/// file while an exclusive lock is held. +/// +/// If the open file has a shared lock and there are no exclusive locks held +/// for the fhile, this function upgrades the lock to an exclusive lock. If the +/// open file already has an exclusive lock, this function has no effect. +/// +/// This requests an *advisory* lock, meaning that the file could be accessed +/// by other programs that don't hold the lock. +/// +/// It is unspecified whether this function succeeds if the file descriptor +/// is not opened for writing. It is unspecified how exclusive locks interact +/// with locks acquired by non-WASI programs. +/// +/// This function blocks until the lock can be acquired. +/// +/// Not all filesystems support locking; on filesystems which don't support +/// locking, this function returns `errno::notsup`. +/// +/// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. +lock-exclusive: func() -> result<_, errno> +``` + +## `try-lock-shared` +```wit +/// Request a shared advisory lock for an open file. +/// +/// This requests a *shared* lock; more than one shared lock can be held for +/// a file at the same time. +/// +/// If the open file has an exclusive lock, this function downgrades the lock +/// to a shared lock. If it has a shared lock, this function has no effect. +/// +/// This requests an *advisory* lock, meaning that the file could be accessed +/// by other programs that don't hold the lock. +/// +/// It is unspecified how shared locks interact with locks acquired by +/// non-WASI programs. +/// +/// This function returns `errno::wouldblock` if the lock cannot be acquired. +/// +/// Not all filesystems support locking; on filesystems which don't support +/// locking, this function returns `errno::notsup`. +/// +/// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. +try-lock-shared: func() -> result<_, errno> +``` + +## `try-lock-exclusive` +```wit +/// Request an exclusive advisory lock for an open file. +/// +/// This requests an *exclusive* lock; no other locks may be held for the +/// file while an exclusive lock is held. +/// +/// If the open file has a shared lock and there are no exclusive locks held +/// for the fhile, this function upgrades the lock to an exclusive lock. If the +/// open file already has an exclusive lock, this function has no effect. +/// +/// This requests an *advisory* lock, meaning that the file could be accessed +/// by other programs that don't hold the lock. +/// +/// It is unspecified whether this function succeeds if the file descriptor +/// is not opened for writing. It is unspecified how exclusive locks interact +/// with locks acquired by non-WASI programs. +/// +/// This function returns `errno::wouldblock` if the lock cannot be acquired. +/// +/// Not all filesystems support locking; on filesystems which don't support +/// locking, this function returns `errno::notsup`. +/// +/// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. +try-lock-exclusive: func() -> result<_, errno> +``` + +## `unlock` +```wit +/// Release a shared or exclusive lock on an open file. +/// +/// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. +unlock: func() -> result<_, errno> +``` + ```wit } ``` From 7f53a95f390dd994e1d29efb615d8766e6f60203 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 7 Dec 2022 15:50:47 -0800 Subject: [PATCH 0998/1772] Change `readdir` from returning bytes to returning a `dir-entry`s. (#72) `readdir` returning bytes has been a source of complexity for both libc and engine implementors, with subtle issues about alignment and partial records. Rename `dirent` to `dir-entry` for readability, and revamp it: - Make the name field a proper `string` rather than being represented by trailing bytes in the buffer. - Make the inode field `optional`, so that we can make it optional as discussed in #65 without special-casing zero, which is reportedly a valid inode number on [some filesystems]. And remove the `rewind` parameter, which isn't needed when we return a stream, as users wanting to start at the beginning can just request a new stream. [some filesystems]: https://sourceware.org/pipermail/libc-alpha/2022-September/142059.html --- proposals/filesystem/wasi-filesystem.abi.md | 35 ++++++++++----------- proposals/filesystem/wasi-filesystem.wit.md | 35 ++++++++++----------- 2 files changed, 32 insertions(+), 38 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index dfb028b1b..8f5fe7887 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -268,25 +268,30 @@ Size: 16, Alignment: 8 Set the timestamp to the given value. -## `dirent`: record +## `dir-entry`: record A directory entry. -Size: 16, Alignment: 8 +Size: 32, Alignment: 8 ### Record Fields -- [`ino`](#dirent.ino): [`inode`](#inode) +- [`ino`](#dir_entry.ino): option<[`inode`](#inode)> - The serial number of the file referred to by this directory entry. + The serial number of the object referred to by this directory entry. + May be none if the inode value is not known. + + When this is none, libc implementations might do an extra `stat-at` + call to retrieve the inode number to fill their `d_ino` fields, so + implementations which can set this to a non-none value should do so. -- [`namelen`](#dirent.namelen): [`size`](#size) +- [`type`](#dir_entry.type): [`descriptor-type`](#descriptor_type) - The length of the name of the directory entry. + The type of the file referred to by this directory entry. -- [`type`](#dirent.type): [`descriptor-type`](#descriptor_type) +- [`name`](#dir_entry.name): `string` - The type of the file referred to by this directory entry. + The name of the object. ## `errno`: enum @@ -787,22 +792,14 @@ Size: 16, Alignment: 8 Read directory entries from a directory. - When successful, the contents of the output buffer consist of a sequence of - directory entries. Each directory entry consists of a `dirent` object, - followed by `dirent::d_namlen` bytes holding the name of the directory - entry. - - This function fills the output buffer as much as possible, potentially - truncating the last directory entry. This allows the caller to grow its - read buffer size in case it's too small to fit a single large directory - entry, or skip the oversized directory entry. + This always returns a new stream which starts at the beginning of the + directory. ##### Params - `self`: handle -- `rewind`: `bool` ##### Results -- stream<`u8`, [`errno`](#errno)> +- stream<[`dir-entry`](#dir_entry), [`errno`](#errno)> ---- diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 0159e1d9d..ed637e2e6 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -192,16 +192,23 @@ variant new-timestamp { } ``` -## `dirent` +## `dir-entry` ```wit /// A directory entry. -record dirent { - /// The serial number of the file referred to by this directory entry. - ino: inode, - /// The length of the name of the directory entry. - namelen: size, +record dir-entry { + /// The serial number of the object referred to by this directory entry. + /// May be none if the inode value is not known. + /// + /// When this is none, libc implementations might do an extra `stat-at` + /// call to retrieve the inode number to fill their `d_ino` fields, so + /// implementations which can set this to a non-none value should do so. + ino: option, + /// The type of the file referred to by this directory entry. %type: descriptor-type, + + /// The name of the object. + name: string, } ``` @@ -506,19 +513,9 @@ pwrite: func( ```wit /// Read directory entries from a directory. /// -/// When successful, the contents of the output buffer consist of a sequence of -/// directory entries. Each directory entry consists of a `dirent` object, -/// followed by `dirent::d_namlen` bytes holding the name of the directory -/// entry. -/// -/// This function fills the output buffer as much as possible, potentially -/// truncating the last directory entry. This allows the caller to grow its -/// read buffer size in case it's too small to fit a single large directory -/// entry, or skip the oversized directory entry. -readdir: func( - /// If true, rewind the current position to the beginning before reading. - rewind: bool -) -> stream +/// This always returns a new stream which starts at the beginning of the +/// directory. +readdir: func() -> stream ``` ## `seek` From 8387493decbdd11fda3934fb51b4ad7892a21170 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 13 Dec 2022 09:30:20 -0800 Subject: [PATCH 0999/1772] Clarify that this wasi-filesystem API is not derived from CloudABI. (#73) CloudABI was an important influence and wasi-filesystem retains some of the core ideas, and the witx API was derived from it. However, the wit API here has been entirely rewritten around the needs and features of Wit, and POSIX and Windows compatibility. --- proposals/filesystem/README.md | 4 ++++ proposals/filesystem/wasi-filesystem.wit.md | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index 30c51691b..a92b92261 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -57,6 +57,10 @@ WASI filesystem is not intended to be used as a virtual API for accessing arbitary resources. Unix's "everything is a file" philosophy is in conflict with the goals of supporting modularity and the principle of least authority. +Many of the ideas related to doing capability-based filesystem sandboxing with +`openat` come from [CloudABI](https://github.com/NuxiNL/cloudabi) and +[Capsicum](https://wiki.freebsd.org/Capsicum). + ### Goals The primary goal of WASI filesystem is to allow users to use WASI programs to diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index ed637e2e6..d19ef6fdc 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -11,9 +11,6 @@ Paths are passed as interface-type `string`s, meaning they must consist of a sequence of Unicode Scalar Values (USVs). Some filesystems may contain paths which are not accessible by this API. -Some of the content and ideas here are derived from -[CloudABI](https://github.com/NuxiNL/cloudabi). - ## `size` ```wit /// Size of a range of bytes in memory. From d821f242c2b69d219e6ba67e7fba80fa8cbd92ae Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 18 Jan 2023 08:28:56 -0800 Subject: [PATCH 1000/1772] Switch timestamps to seconds+nanoseconds. (#76) This matches wasi-clocks' wall clock, and is closer to what popular operating systems provide. Fixes #67. --- proposals/filesystem/wasi-filesystem.abi.md | 31 +++++++++++++-------- proposals/filesystem/wasi-filesystem.wit.md | 22 ++++++++------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index 8f5fe7887..c21093830 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -18,13 +18,19 @@ Size: 8, Alignment: 8 Size: 8, Alignment: 8 -## `timestamp`: `u64` +## `datetime`: record - Timestamp in nanoseconds. - - TODO: wasi-clocks is moving to seconds+nanoseconds. + Timestamp in seconds and nanoseconds. + +Size: 16, Alignment: 8 + +### Record Fields + +- [`seconds`](#datetime.seconds): `u64` + + +- [`nanoseconds`](#datetime.nanoseconds): `u32` -Size: 8, Alignment: 8 ## `descriptor-type`: enum @@ -124,7 +130,7 @@ Bit: 6 Note: This was called `filestat` in earlier versions of WASI. -Size: 64, Alignment: 8 +Size: 88, Alignment: 8 ### Record Fields @@ -149,15 +155,15 @@ Size: 64, Alignment: 8 For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. -- [`atim`](#descriptor_stat.atim): [`timestamp`](#timestamp) +- [`atim`](#descriptor_stat.atim): [`datetime`](#datetime) Last data access timestamp. -- [`mtim`](#descriptor_stat.mtim): [`timestamp`](#timestamp) +- [`mtim`](#descriptor_stat.mtim): [`datetime`](#datetime) Last data modification timestamp. -- [`ctim`](#descriptor_stat.ctim): [`timestamp`](#timestamp) +- [`ctim`](#descriptor_stat.ctim): [`datetime`](#datetime) Last file status change timestamp. @@ -204,7 +210,8 @@ Bit: 3 ## `mode`: flags - Permissions mode used by `open-at`, `change-permissions-at`, and similar. + Permissions mode used by `open-at`, `change-file-permissions-at`, and + similar. Size: 1, Alignment: 1 @@ -251,7 +258,7 @@ Size: 8, Alignment: 8 When setting a timestamp, this gives the value to set it to. -Size: 16, Alignment: 8 +Size: 24, Alignment: 8 ### Variant Cases @@ -264,7 +271,7 @@ Size: 16, Alignment: 8 Set the timestamp to the current time of the system clock associated with the filesystem. -- [`timestamp`](#new_timestamp.timestamp): [`timestamp`](#timestamp) +- [`timestamp`](#new_timestamp.timestamp): [`datetime`](#datetime) Set the timestamp to the given value. diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index d19ef6fdc..d7d25fe95 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -29,12 +29,13 @@ type filesize = u64 type filedelta = s64 ``` -## `timestamp` +## `datetime` ```wit -/// Timestamp in nanoseconds. -/// -/// TODO: wasi-clocks is moving to seconds+nanoseconds. -type timestamp = u64 +/// Timestamp in seconds and nanoseconds. +record datetime { + seconds: u64, + nanoseconds: u32, +} ``` ## `descriptor-type` @@ -108,11 +109,11 @@ record descriptor-stat { /// in bytes of the pathname contained in the symbolic link. size: filesize, /// Last data access timestamp. - atim: timestamp, + atim: datetime, /// Last data modification timestamp. - mtim: timestamp, + mtim: datetime, /// Last file status change timestamp. - ctim: timestamp, + ctim: datetime, } ``` @@ -142,7 +143,8 @@ flags o-flags { ## `mode` ```wit -/// Permissions mode used by `open-at`, `change-permissions-at`, and similar. +/// Permissions mode used by `open-at`, `change-file-permissions-at`, and +/// similar. flags mode { /// True if the resource is considered readable by the containing /// filesystem. @@ -185,7 +187,7 @@ variant new-timestamp { /// with the filesystem. now, /// Set the timestamp to the given value. - timestamp(timestamp), + timestamp(datetime), } ``` From 931556dbb68b58b17494dfefd045e5d7a347702f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 18 Jan 2023 08:31:01 -0800 Subject: [PATCH 1001/1772] Document the behavior of writes past the end of a file. (#77) Document that seek+write and pwrite can write past the end of the file, and that the file is extended with zeros as needed. This will require extra implementation work on Windows, where writes past the end of files extend with uninitialized bytes, however the upside of the tradeoff is cleaner and more POSIX-compliant behavior for applications, which seems worthwhile here. Also, document that `seek` and `tell` fail on a directory. Fixes #13. --- proposals/filesystem/wasi-filesystem.abi.md | 17 +++++++++++++++-- proposals/filesystem/wasi-filesystem.wit.md | 17 +++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index c21093830..d709077fb 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -783,6 +783,10 @@ Size: 16, Alignment: 8 Write to a descriptor, without using and updating the descriptor's offset. + It is valid to write past the end of a file; the file is extended to the + extent of the write, with bytes between the previous end and the start of + the write set to zero. + Note: This is similar to `pwrite` in POSIX. ##### Params @@ -812,12 +816,18 @@ Size: 16, Alignment: 8 #### `descriptor::seek` - Move the offset of a descriptor. + Move the offset of a file descriptor. - The meaning of `seek` on a directory is unspecified. + If the descriptor refers to a directory, this function fails with + `errno::spipe`. Returns new offset of the descriptor, relative to the start of the file. + It is valid to seek past the end of a file. The file size is not modified + until a write is performed, at which time the file is extended to the + extent of the write, with bytes between the previous end and the start of + the write set to zero. + Note: This is similar to `lseek` in POSIX. ##### Params @@ -847,6 +857,9 @@ Size: 16, Alignment: 8 Return the current offset of a descriptor. + If the descriptor refers to a directory, this function fails with + `errno::spipe`. + Returns the current offset of the descriptor, relative to the start of the file. Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index d7d25fe95..2a6351cff 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -499,6 +499,10 @@ pread: func( ```wit /// Write to a descriptor, without using and updating the descriptor's offset. /// +/// It is valid to write past the end of a file; the file is extended to the +/// extent of the write, with bytes between the previous end and the start of +/// the write set to zero. +/// /// Note: This is similar to `pwrite` in POSIX. pwrite: func( /// Data to write @@ -519,12 +523,18 @@ readdir: func() -> stream ## `seek` ```wit -/// Move the offset of a descriptor. +/// Move the offset of a file descriptor. /// -/// The meaning of `seek` on a directory is unspecified. +/// If the descriptor refers to a directory, this function fails with +/// `errno::spipe`. /// /// Returns new offset of the descriptor, relative to the start of the file. /// +/// It is valid to seek past the end of a file. The file size is not modified +/// until a write is performed, at which time the file is extended to the +/// extent of the write, with bytes between the previous end and the start of +/// the write set to zero. +/// /// Note: This is similar to `lseek` in POSIX. seek: func( /// The method to compute the new offset. @@ -544,6 +554,9 @@ sync: func() -> result<_, errno> ```wit /// Return the current offset of a descriptor. /// +/// If the descriptor refers to a directory, this function fails with +/// `errno::spipe`. +/// /// Returns the current offset of the descriptor, relative to the start of the file. /// /// Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. From 796de97678ab4f6e245e25163e465ab8d0359257 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 18 Jan 2023 08:31:23 -0800 Subject: [PATCH 1002/1772] Remove errno codes that aren't used by filesystem APIs. (#80) * Remove errno codes that aren't used by filesystem APIs. Instead of WASI having a single errno space, each WASI interface defines its own error types. POSIX compatibility is provided by the libc layer. Codes used in filesystem APIs but not relevant to WASI: - nfile - This may be reported by libc, but wasi-filesystem itself doesn't because it will let the handle mechanism take care of everything. - mfile - WASI programs should not be able to observe "the system" having an open-file limit. - fault - This is used in POSIX to report invalid pointers, however in WASI that's handled in the bindings layer instead of in individual interfaces. Codes only used in network APIs (these will be defined in wasi-sockets): - afnosupport - addrinuse - addrnotavail - noprotoopt - destaddrreq - hostunreach - isconn - connaborted - connrefused - connreset - netdown - netreset - netunreach - timedout - multihop - nobufs Codes only used in other non-filesystem APIs: - toobig - badmsg - canceled - idrm - noexec - nolink - nomsg - ownerdead - range - srch - stale * Update wasi-filesystem.abi.md. --- proposals/filesystem/wasi-filesystem.abi.md | 120 -------------------- proposals/filesystem/wasi-filesystem.wit.md | 60 ---------- 2 files changed, 180 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index d709077fb..bc5fee0c4 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -311,26 +311,10 @@ Size: 1, Alignment: 1 ### Enum Cases -- [`toobig`](#errno.toobig) - - Argument list too long. This is similar to `E2BIG` in POSIX. - - [`access`](#errno.access) Permission denied. -- [`addrinuse`](#errno.addrinuse) - - Address in use. - -- [`addrnotavail`](#errno.addrnotavail) - - Address not available. - -- [`afnosupport`](#errno.afnosupport) - - Address family not supported. - - [`again`](#errno.again) Resource unavailable, or operation would block. @@ -343,42 +327,18 @@ Size: 1, Alignment: 1 Bad descriptor. -- [`badmsg`](#errno.badmsg) - - Bad message. - - [`busy`](#errno.busy) Device or resource busy. -- [`canceled`](#errno.canceled) - - Operation canceled. - - [`child`](#errno.child) No child processes. -- [`connaborted`](#errno.connaborted) - - Connection aborted. - -- [`connrefused`](#errno.connrefused) - - Connection refused. - -- [`connreset`](#errno.connreset) - - Connection reset. - - [`deadlk`](#errno.deadlk) Resource deadlock would occur. -- [`destaddrreq`](#errno.destaddrreq) - - Destination address required. - - [`dquot`](#errno.dquot) Storage quota exceeded. @@ -387,22 +347,10 @@ Size: 1, Alignment: 1 File exists. -- [`fault`](#errno.fault) - - Bad address. - - [`fbig`](#errno.fbig) File too large. -- [`hostunreach`](#errno.hostunreach) - - Host is unreachable. - -- [`idrm`](#errno.idrm) - - Identifier removed. - - [`ilseq`](#errno.ilseq) Illegal byte sequence. @@ -423,10 +371,6 @@ Size: 1, Alignment: 1 I/O error. -- [`isconn`](#errno.isconn) - - Socket is connected. - - [`isdir`](#errno.isdir) Is a directory. @@ -435,10 +379,6 @@ Size: 1, Alignment: 1 Too many levels of symbolic links. -- [`mfile`](#errno.mfile) - - File descriptor value too large. - - [`mlink`](#errno.mlink) Too many links. @@ -447,34 +387,10 @@ Size: 1, Alignment: 1 Message too large. -- [`multihop`](#errno.multihop) - - Multihop attempted. - - [`nametoolong`](#errno.nametoolong) Filename too long. -- [`netdown`](#errno.netdown) - - Network is down. - -- [`netreset`](#errno.netreset) - - Connection aborted by network. - -- [`netunreach`](#errno.netunreach) - - Network unreachable. - -- [`nfile`](#errno.nfile) - - Too many files open in system. - -- [`nobufs`](#errno.nobufs) - - No buffer space available. - - [`nodev`](#errno.nodev) No such device. @@ -483,30 +399,14 @@ Size: 1, Alignment: 1 No such file or directory. -- [`noexec`](#errno.noexec) - - Executable file format error. - - [`nolck`](#errno.nolck) No locks available. -- [`nolink`](#errno.nolink) - - Link has been severed. - - [`nomem`](#errno.nomem) Not enough space. -- [`nomsg`](#errno.nomsg) - - No message of the desired type. - -- [`noprotoopt`](#errno.noprotoopt) - - Protocol not available. - - [`nospc`](#errno.nospc) No space left on device. @@ -543,10 +443,6 @@ Size: 1, Alignment: 1 Value too large to be stored in data type. -- [`ownerdead`](#errno.ownerdead) - - Previous owner died. - - [`perm`](#errno.perm) Operation not permitted. @@ -555,10 +451,6 @@ Size: 1, Alignment: 1 Broken pipe. -- [`range`](#errno.range) - - Result too large. - - [`rofs`](#errno.rofs) Read-only file system. @@ -567,18 +459,6 @@ Size: 1, Alignment: 1 Invalid seek. -- [`srch`](#errno.srch) - - No such process. - -- [`stale`](#errno.stale) - - Stale file handle. - -- [`timedout`](#errno.timedout) - - Connection timed out. - - [`txtbsy`](#errno.txtbsy) Text file busy. diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 2a6351cff..424bd22cc 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -218,52 +218,26 @@ record dir-entry { /// API; some are used in higher-level library layers, and others are provided /// merely for alignment with POSIX. enum errno { - /// Argument list too long. This is similar to `E2BIG` in POSIX. - toobig, /// Permission denied. access, - /// Address in use. - addrinuse, - /// Address not available. - addrnotavail, - /// Address family not supported. - afnosupport, /// Resource unavailable, or operation would block. again, /// Connection already in progress. already, /// Bad descriptor. badf, - /// Bad message. - badmsg, /// Device or resource busy. busy, - /// Operation canceled. - canceled, /// No child processes. child, - /// Connection aborted. - connaborted, - /// Connection refused. - connrefused, - /// Connection reset. - connreset, /// Resource deadlock would occur. deadlk, - /// Destination address required. - destaddrreq, /// Storage quota exceeded. dquot, /// File exists. exist, - /// Bad address. - fault, /// File too large. fbig, - /// Host is unreachable. - hostunreach, - /// Identifier removed. - idrm, /// Illegal byte sequence. ilseq, /// Operation in progress. @@ -274,48 +248,24 @@ enum errno { inval, /// I/O error. io, - /// Socket is connected. - isconn, /// Is a directory. isdir, /// Too many levels of symbolic links. loop, - /// File descriptor value too large. - mfile, /// Too many links. mlink, /// Message too large. msgsize, - /// Multihop attempted. - multihop, /// Filename too long. nametoolong, - /// Network is down. - netdown, - /// Connection aborted by network. - netreset, - /// Network unreachable. - netunreach, - /// Too many files open in system. - nfile, - /// No buffer space available. - nobufs, /// No such device. nodev, /// No such file or directory. noent, - /// Executable file format error. - noexec, /// No locks available. nolck, - /// Link has been severed. - nolink, /// Not enough space. nomem, - /// No message of the desired type. - nomsg, - /// Protocol not available. - noprotoopt, /// No space left on device. nospc, /// Function not supported. @@ -334,24 +284,14 @@ enum errno { nxio, /// Value too large to be stored in data type. overflow, - /// Previous owner died. - ownerdead, /// Operation not permitted. perm, /// Broken pipe. pipe, - /// Result too large. - range, /// Read-only file system. rofs, /// Invalid seek. spipe, - /// No such process. - srch, - /// Stale file handle. - stale, - /// Connection timed out. - timedout, /// Text file busy. txtbsy, /// Cross-device link. From f351e0918248726c554aa95ebf42f1ddbdd23142 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 18 Jan 2023 09:05:05 -0800 Subject: [PATCH 1003/1772] Add a `get-random-u64` function. (#18) Rename `getrandom` to `get-random-bytes` and add a `get-random-u64` function. It returns the same kind of random data, just in a different format. A `u64` is more convenient for some use cases, and in this time when returning a `list` may incur an allocation, returning a `u64` avoids that overhead. Thanks to @npmccallum for suggesting this! --- proposals/random/wasi-random.abi.md | 19 +++++++++++++++++-- proposals/random/wasi-random.wit.md | 16 ++++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/proposals/random/wasi-random.abi.md b/proposals/random/wasi-random.abi.md index 2fc88e39b..018ca64cb 100644 --- a/proposals/random/wasi-random.abi.md +++ b/proposals/random/wasi-random.abi.md @@ -2,7 +2,7 @@ ---- -#### `getrandom` +#### `get-random-bytes` Return `len` random bytes. @@ -13,8 +13,23 @@ implementing it with deterministic data. ##### Params -- `len`: `u32` +- `len`: `u32` ##### Results - list<`u8`> +---- + +#### `get-random-u64` + + Return a random `u64` value. + + This function must produce data from an adaquately seeded CSPRNG, so it + must not block, and the returned data is always unpredictable. + + Deterministic environments must omit this function, rather than + implementing it with deterministic data. +##### Results + +- `u64` + diff --git a/proposals/random/wasi-random.wit.md b/proposals/random/wasi-random.wit.md index 3645ecf30..38400feb0 100644 --- a/proposals/random/wasi-random.wit.md +++ b/proposals/random/wasi-random.wit.md @@ -5,7 +5,7 @@ WASI Random is a random data API. It is intended to be portable at least between Unix-family platforms and Windows. -## `getrandom` +## `get-random-bytes` ```wit /// Return `len` random bytes. /// @@ -14,7 +14,19 @@ Windows. /// /// Deterministic environments must omit this function, rather than /// implementing it with deterministic data. -getrandom: func(len: u32) -> list +get-random-bytes: func(len: u32) -> list +``` + +## `get-random-u64` +```wit +/// Return a random `u64` value. +/// +/// This function must produce data from an adaquately seeded CSPRNG, so it +/// must not block, and the returned data is always unpredictable. +/// +/// Deterministic environments must omit this function, rather than +/// implementing it with deterministic data. +get-random-u64: func() -> u64 ``` ## `insecure-random` From 5a0c6d5db80f93995f911e5fad2de396af1b75af Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 18 Jan 2023 09:06:21 -0800 Subject: [PATCH 1004/1772] Add comments documenting the default-clock functions. (#22) --- proposals/clocks/wasi-default-clocks.wit.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/proposals/clocks/wasi-default-clocks.wit.md b/proposals/clocks/wasi-default-clocks.wit.md index b4c53664b..ae38601ee 100644 --- a/proposals/clocks/wasi-default-clocks.wit.md +++ b/proposals/clocks/wasi-default-clocks.wit.md @@ -10,10 +10,21 @@ use { monotonic-clock, wall-clock } from wasi-clocks ## `default-monotonic-clock` ```wit +/// Return a default monotonic clock, suitable for general-purpose application +/// needs. +/// +/// This allocates a new handle, so applications with frequent need of a clock +/// handle should call this function once and reuse the handle instead of +/// calling this function each time. default-monotonic-clock: monotonic-clock ``` ## `default-wall-clock` +/// Return a default wall clock, suitable for general-purpose application +/// needs. +/// +/// This allocates a new handle, so applications with frequent need of a clock +/// handle should call this function once and reuse the handle instead of ```wit default-wall-clock: wall-clock ``` From 35d58783d7055119b306c318ef41f9cfe82faa2d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 23 Jan 2023 21:16:54 -0800 Subject: [PATCH 1005/1772] Populate with new wasi-io content. (#14) Populate the wasi-io proposal repo with the wasi-io streams interface that has been presented in recent WASI Subgroup meetings. This proposal is a temporary measure until full support for streams is available in the component model. --- proposals/io/README.md | 18 ++---- proposals/io/proposal-template.abi.md | 31 ---------- proposals/io/proposal-template.wit.md | 32 ----------- proposals/io/wasi-io.abi.md | 80 ++++++++++++++++++++++++++ proposals/io/wasi-io.wit.md | 81 +++++++++++++++++++++++++++ 5 files changed, 165 insertions(+), 77 deletions(-) delete mode 100644 proposals/io/proposal-template.abi.md delete mode 100644 proposals/io/proposal-template.wit.md create mode 100644 proposals/io/wasi-io.abi.md create mode 100644 proposals/io/wasi-io.wit.md diff --git a/proposals/io/README.md b/proposals/io/README.md index e76604398..e3a00c193 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -1,28 +1,18 @@ -# [Example WASI proposal] - -This template can be used to start a new proposal, which can then be proposed in the WASI Subgroup meetings. - -The sections below are recommended. However, every proposal is different, and the community can help you flesh out the proposal, so don't block on having something filled in for each one of them. - -Thank you to the W3C Privacy CG for the [inspiration](https://github.com/privacycg/template)! - -# [Title] +# WASI I/O A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. ### Current Phase -[Fill in the current phase, e.g. Phase 1] +WASI-filesystem is currently in [Phase 2]. ### Champions -- [Champion 1] -- [Champion 2] -- [etc.] +- Dan Gohman ### Phase 4 Advancement Criteria -TODO before entering Phase 2. +WASI I/O has not yet proposed its phase-4 advancement criteria. ## Table of Contents [if the explainer is longer than one printed page] diff --git a/proposals/io/proposal-template.abi.md b/proposals/io/proposal-template.abi.md deleted file mode 100644 index 7a1c37209..000000000 --- a/proposals/io/proposal-template.abi.md +++ /dev/null @@ -1,31 +0,0 @@ -# Types - -## `api-type-one`: record - - Short description - - Explanation for developers using the API. - -Size: 16, Alignment: 8 - -### Record Fields - -- [`property1`](#api_type_one.property1): `u64` - - -- [`property2`](#api_type_one.property2): `string` - - -# Functions - ----- - -#### `api-function-one` - - Short description - - Explanation for developers using the API. -##### Results - -- [`api-type-one`](#api_type_one) - diff --git a/proposals/io/proposal-template.wit.md b/proposals/io/proposal-template.wit.md deleted file mode 100644 index 3c7e8efbd..000000000 --- a/proposals/io/proposal-template.wit.md +++ /dev/null @@ -1,32 +0,0 @@ -# [Proposal Template] API - -[This document contains the actual specification. It should be written in the WIT interface definition format. You can find more documentation on the WIT syntax (coming soon!).] - -[Note that all comments inside of WIT code blocks will be included in the developer facing documentation for language bindings generated using this WIT file. If there is additional information that needs to be communicated to implementers of the API, then these should be captured in text directly below the code block.] - -[If you want to include examples of the API in use, these should be in the README and linked to from this file.] - -## api_type_one - -```wit -/// Short description -/// -/// Explanation for developers using the API. -record api-type-one { - property1: u64, - property2: string, -} -``` - -More rigorous specification details for the implementer go here, if needed. - -## api_function_one - -```wit -/// Short description -/// -/// Explanation for developers using the API. -api-function-one: func() -> api-type-one -``` - -If needed, this would explain what a compliant implementation MUST do, such as never returning an earlier result from a later call. diff --git a/proposals/io/wasi-io.abi.md b/proposals/io/wasi-io.abi.md new file mode 100644 index 000000000..bc6f37d0c --- /dev/null +++ b/proposals/io/wasi-io.abi.md @@ -0,0 +1,80 @@ +# Types + +## `stream-error`: record + + An error type returned from a stream operation. Currently this + doesn't provide any additional information. + +Size: 0, Alignment: 1 + +### Record Fields + +# Functions + +---- + +#### `input-stream::read` + + Read bytes from a stream. +##### Params + +- `self`: handle +- `len`: `u64` +##### Results + +- result<(list<`u8`>, `bool`), [`stream-error`](#stream_error)> + +---- + +#### `input-stream::skip` + + Skip bytes from a stream. +##### Params + +- `self`: handle +- `len`: `u64` +##### Results + +- result<(`u64`, `bool`), [`stream-error`](#stream_error)> + +---- + +#### `output-stream::write` + + Write bytes to a stream. +##### Params + +- `self`: handle +- `buf`: list<`u8`> +##### Results + +- result<`u64`, [`stream-error`](#stream_error)> + +---- + +#### `output-stream::write-repeated` + + Write bytes to a stream. +##### Params + +- `self`: handle +- `byte`: `u8` +- `len`: `u64` +##### Results + +- result<`u64`, [`stream-error`](#stream_error)> + +---- + +#### `output-stream::splice-stream` + + Read from one stream and write to another. +##### Params + +- `self`: handle +- `src`: handle +- `len`: `u64` +##### Results + +- result<(`u64`, `bool`), [`stream-error`](#stream_error)> + diff --git a/proposals/io/wasi-io.wit.md b/proposals/io/wasi-io.wit.md new file mode 100644 index 000000000..28fd8c45f --- /dev/null +++ b/proposals/io/wasi-io.wit.md @@ -0,0 +1,81 @@ +# WASI I/O + +WASI I/O is an I/O abstraction API which is currently focused on providing +stream types. + +In the future, the component model is expected to add built in stream types; +when it does, they are expected to subsume this API. + +## `stream-error` +```wit +/// An error type returned from a stream operation. Currently this +/// doesn't provide any additional information. +record stream-error {} +``` + +## `input-stream` +```wit +resource input-stream { +``` + +## `read` +```wit + /// Read bytes from a stream. + read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, bool>, stream-error> +``` + +## `skip` +```wit + /// Skip bytes from a stream. + skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result, stream-error> +``` + +```wit +} +``` + +## `output-stream` +```wit +resource output-stream { +``` + +## `write` +```wit + /// Write bytes to a stream. + write: func( + /// Data to write + buf: list + ) -> result +``` + +## `write-repeated` +```wit + /// Write bytes to a stream. + write-repeated: func( + /// The byte to write + byte: u8, + /// The number of times to write it + len: u64 + ) -> result +``` + +## `splice` +```wit + /// Read from one stream and write to another. + splice-stream: func( + /// The stream to read from. + src: input-stream, + /// The number of bytes to splice. + len: u64, + ) -> result, stream-error> +``` + +```wit +} +``` From b1745d203f186c2632e9dd8c93238c1bad6e2269 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Sat, 28 Jan 2023 11:07:16 -0500 Subject: [PATCH 1006/1772] docs: minor fixes to comments (#23) Signed-off-by: Bailey Hayes --- proposals/clocks/wasi-clocks.abi.md | 4 ++-- proposals/clocks/wasi-clocks.wit.md | 4 ++-- proposals/clocks/wasi-default-clocks.wit.md | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/proposals/clocks/wasi-clocks.abi.md b/proposals/clocks/wasi-clocks.abi.md index e24584ab2..0909eb4af 100644 --- a/proposals/clocks/wasi-clocks.abi.md +++ b/proposals/clocks/wasi-clocks.abi.md @@ -28,7 +28,7 @@ Size: 16, Alignment: 8 Read the current value of the clock. - As this the clock is monotonic, calling this function repeatedly will produce + The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values. ##### Params @@ -69,7 +69,7 @@ Size: 16, Alignment: 8 Read the current value of the clock. - As this the clock is not monotonic, calling this function repeatedly will + This clock is not monotonic, therefore calling this function repeatedly will not necessarily produce a sequence of non-decreasing values. The returned timestamps represent the number of seconds since diff --git a/proposals/clocks/wasi-clocks.wit.md b/proposals/clocks/wasi-clocks.wit.md index 4a2f5757c..5b3a93225 100644 --- a/proposals/clocks/wasi-clocks.wit.md +++ b/proposals/clocks/wasi-clocks.wit.md @@ -34,7 +34,7 @@ resource monotonic-clock { ```wit /// Read the current value of the clock. /// -/// As this the clock is monotonic, calling this function repeatedly will produce +/// The clock is monotonic, therefore calling this function repeatedly will produce /// a sequence of non-decreasing values. now: func() -> instant ``` @@ -72,7 +72,7 @@ resource wall-clock { ```wit /// Read the current value of the clock. /// -/// As this the clock is not monotonic, calling this function repeatedly will +/// This clock is not monotonic, therefore calling this function repeatedly will /// not necessarily produce a sequence of non-decreasing values. /// /// The returned timestamps represent the number of seconds since diff --git a/proposals/clocks/wasi-default-clocks.wit.md b/proposals/clocks/wasi-default-clocks.wit.md index ae38601ee..1a1fa91a3 100644 --- a/proposals/clocks/wasi-default-clocks.wit.md +++ b/proposals/clocks/wasi-default-clocks.wit.md @@ -25,6 +25,7 @@ default-monotonic-clock: monotonic-clock /// /// This allocates a new handle, so applications with frequent need of a clock /// handle should call this function once and reuse the handle instead of +/// calling this function each time. ```wit default-wall-clock: wall-clock ``` From c62a97a8b8346582f856651469de4a997fa0938d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 30 Jan 2023 10:45:52 -0800 Subject: [PATCH 1007/1772] Remove the `size` type. (#84) Use `filesize` in `fadvise`, `pread`, and `pwrite`, instead of `size`. This makes the API independent of wasm32 vs. wasm64 or even linear memory vs. other options. This does mean that a wasm32 program can request a `pread` of more bytes than it can possibly recieve, but it'll just get a short read. --- proposals/filesystem/wasi-filesystem.abi.md | 12 +++--------- proposals/filesystem/wasi-filesystem.wit.md | 12 +++--------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md index bc5fee0c4..41efd2ad3 100644 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ b/proposals/filesystem/wasi-filesystem.abi.md @@ -1,11 +1,5 @@ # Types -## `size`: `u32` - - Size of a range of bytes in memory. - -Size: 4, Alignment: 4 - ## `filesize`: `u64` Non-negative file size or length of a region within a file. @@ -532,7 +526,7 @@ Size: 16, Alignment: 8 - `self`: handle - `offset`: [`filesize`](#filesize) -- `len`: [`size`](#size) +- `len`: [`filesize`](#filesize) - `advice`: [`advice`](#advice) ##### Results @@ -651,7 +645,7 @@ Size: 16, Alignment: 8 ##### Params - `self`: handle -- `len`: [`size`](#size) +- `len`: [`filesize`](#filesize) - `offset`: [`filesize`](#filesize) ##### Results @@ -675,7 +669,7 @@ Size: 16, Alignment: 8 - `offset`: [`filesize`](#filesize) ##### Results -- future> +- future> ---- diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wasi-filesystem.wit.md index 424bd22cc..ca6225781 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wasi-filesystem.wit.md @@ -11,12 +11,6 @@ Paths are passed as interface-type `string`s, meaning they must consist of a sequence of Unicode Scalar Values (USVs). Some filesystems may contain paths which are not accessible by this API. -## `size` -```wit -/// Size of a range of bytes in memory. -type size = u32 -``` - ## `filesize` ```wit /// Non-negative file size or length of a region within a file. @@ -348,7 +342,7 @@ fadvise: func( /// The offset within the file to which the advisory applies. offset: filesize, /// The length of the region to which the advisory applies. - len: size, + len: filesize, /// The advice. advice: advice ) -> result<_, errno> @@ -429,7 +423,7 @@ set-times: func( /// Note: This is similar to `pread` in POSIX. pread: func( /// The maximim number of bytes to read. - len: size, + len: filesize, /// The offset within the file at which to read. offset: filesize, ) -> stream @@ -449,7 +443,7 @@ pwrite: func( buf: stream, /// The offset within the file at which to write. offset: filesize, -) -> future> +) -> future> ``` ## `readdir` From b4d4ff19c276369866123aad082e29ffe6b1a029 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 3 Feb 2023 16:18:55 -0800 Subject: [PATCH 1008/1772] Add more content to the README.md. (#86) Add more examples, a considered alternative, and replace more of the wasi-proposal-repo template content with real content. Co-authored-by: HackMD <37423+hackmd-hub[bot]@users.noreply.github.com> --- proposals/filesystem/README.md | 76 +++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index a92b92261..ac2e3f0c2 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -19,7 +19,7 @@ on at least Windows, macOS, and Linux. WASI filesystem must have at least two complete independent implementations. -## Table of Contents [if the explainer is longer than one printed page] +## Table of Contents - [Introduction](#introduction) - [Goals](#goals) @@ -76,20 +76,56 @@ defined behaviors, which would conflict with the goal of being efficient. ### API walk-through -[Walk through of how someone would use this API.] - -#### [Use case 1] - -[Provide example code snippets and diagrams explaining how the API would be used to solve the given problem] - -#### [Use case 2] - -[etc.] +#### Opening a file + +```rust= +/// Write "Hello, World" into a file called "greeting.txt" in `dir`. +fn write_hello_world_to_a_file(dir: Descriptor) -> Result<(), Errno> { + let at_flags = AtFlags::FollowSymlinks; + let o_flags = OFlags::Create | OFlags::Trunc; + let descriptor_flags = DescriptorFlags::Write; + let mode = Mode::Readable; + let file = + dir.openat(at_flags, "greeting.txt", o_flags, descriptor_flags, mode)?; + let message = b"Hello, World\n"; + let mut view = &message[..]; + let mut offset = 0; + while !view.is_empty() { + let num_written = file.pwrite(view.to_owned(), 0)?; + offset += num_written; + view = &view[num_writen..]; + } + // The file descriptor is closed when it's dropped! +} +``` + +Perhaps the biggest change from the preview1 version of openat, called +`path_open`, is the removal of the *rights* flags. Preview1 associates +a set of flags with every file descriptor enumerating which operatings +may be performed on it, such as reading, writing, appending, truncating, +and many other operations. In practice, this created a lot of ambiguity +about how it mapped to POSIX semantics, as it doesn't directly correspond +to any feature in POSIX, or in Windows either. + +The other major change from preview1 is the introduction of the mode +argument, which controls the permissions of the generated file. There +was no way to control permissions in preview1, so this is new +functionality. + +#### Streaming read from a file + +TODO + +#### Reading from a directory + +fn read_entries(dir: Descriptor) -> Result<(), Errno> { + // TODO: Implement this example. +} + +[etc. ### Detailed design discussion -[This section should mostly refer to the .wit.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] - #### Should WASI filesystem be case-sensitive, case-insensitive, or platform-dependent? Even just among popular platforms, there are case-sensitive and @@ -108,27 +144,17 @@ issue is tha WASI filesystem in general can't assume it has exclusive access to the filesystem, so approaches that involve checking for files with names that differ only by case can race with other processes creating new files. -#### [Tricky design choice 2] - -[etc.] - ### Considered alternatives -[This section is not required if you already covered considered alternatives in the design discussion above.] - -#### [Alternative 1] - -[Describe an alternative which was considered, and why you decided against it.] - -#### [Alternative 2] +#### Fully deterministic filesystem -[etc.] +The main tradeoff with full determinism is that it makes it difficult to access existing filesystems that the Wasm runtime doesn't have full control over. This proposal is aiming to address use cases where users have existing filesystems they want to access. ### Stakeholder Interest & Feedback TODO before entering Phase 3. -[This should include a list of implementers who have expressed interest in implementing the proposal] +Preview1 has a similar filesystem API, and it's widely exposed in toolchains. ### References & acknowledgements From cca47ffe2eb789c184a2699c9f5e56c70bc516d3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 6 Feb 2023 06:24:33 -0800 Subject: [PATCH 1009/1772] Add more content to the README.md and the documentation (#15) * Add documentation and comments to wasi-io.wit.md. * Add documentation and comments to README.md. * A few more minor fixes. * Update wasi-io.abi.md. --------- Co-authored-by: HackMD <37423+hackmd-hub[bot]@users.noreply.github.com> --- proposals/io/README.md | 115 ++++++++++++++++++++++++------------ proposals/io/wasi-io.abi.md | 47 +++++++++++++-- proposals/io/wasi-io.wit.md | 58 +++++++++++++++++- 3 files changed, 174 insertions(+), 46 deletions(-) diff --git a/proposals/io/README.md b/proposals/io/README.md index e3a00c193..dc932796a 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -4,7 +4,9 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Current Phase -WASI-filesystem is currently in [Phase 2]. +WASI-io is currently in [Phase 2]. + +[Phase 2]: https://github.com/WebAssembly/WASI/blob/42fe2a3ca159011b23099c3d10b5b1d9aff2140e/docs/Proposals.md#phase-2---proposed-spec-text-available-cg--wg ### Champions @@ -14,7 +16,9 @@ WASI-filesystem is currently in [Phase 2]. WASI I/O has not yet proposed its phase-4 advancement criteria. -## Table of Contents [if the explainer is longer than one printed page] +We anticipate it will involve ensuring it works well for streaming files, sockets, and pipes, and is usable from wasi-libc for implementing POSIX APIs. + +## Table of Contents - [Introduction](#introduction) - [Goals [or Motivating Use Cases, or Scenarios]](#goals-or-motivating-use-cases-or-scenarios) @@ -33,68 +37,103 @@ WASI I/O has not yet proposed its phase-4 advancement criteria. ### Introduction -[The "executive summary" or "abstract". Explain in a few sentences what the goals of the project are, and a brief overview of how the solution works. This should be no more than 1-2 paragraphs.] +Wasi I/O is an API providing I/O stream abstractions. There are two +types, `input-stream`, and `output-stream`, which support `read` and +`write`, respectively, as well as a number of utility functions. -### Goals [or Motivating Use Cases, or Scenarios] +### Goals -[What is the end-user need which this project aims to address?] + - Be usable by wasi-libc to implement POSIX-like file and socket APIs. + - Support many different kinds of host streams, including files, sockets, + pipes, character devices, and more. ### Non-goals -[If there are "adjacent" goals which may appear to be in scope but aren't, enumerate them here. This section may be fleshed out as your design progresses and you encounter necessary technical and other trade-offs.] + - Support for async. That will be addressed in the component-model async + design, where we can have the benefit of tigher integration with language + bindings. + - Bidirectional streams. ### API walk-through -[Walk through of how someone would use this API.] - -#### [Use case 1] - -[Provide example code snippets and diagrams explaining how the API would be used to solve the given problem] - -#### [Use case 2] - -[etc.] - -### Detailed design discussion - -[This section should mostly refer to the .wit.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] - -#### [Tricky design choice #1] - -[Talk through the tradeoffs in coming to the specific design point you want to make.] - +#### Copying from input to output using `read`/`write`: + +```rust= + fn copy_data(input: InputStream, output: OutputStream) -> Result<(), StreamError> { + const BUFFER_LEN: usize = 4096; + loop { + let (data, eos) = input.read(BUFFER_LEN)?; + let mut remaining = &data[..]; + while !remaining.is_empty() { + let num_written = output.write(remaining)?; + remaining = &remaining[num_written..]; + } + if eos { + break; + } + } + Ok(()) + } +} ``` -// Illustrated with example code. + +#### Copying from input to output using `splice`: + +```rust= + fn copy_data(input: InputStream, output: OutputStream) -> Result<(), StreamError> { + loop { + let (_num_copied, eos) = output.splice(input, u64::MAX)?; + if eos { + break; + } + } + Ok(()) + } +} ``` -[This may be an open question, in which case you should link to any active discussion threads.] +#### Copying from input to output using `forward`: -#### [Tricky design choice 2] +```rust= + fn copy_data(input: InputStream, output: OutputStream) -> Result<(), StreamError> { + output.forward(input)?; + Ok(()) + } +} +``` -[etc.] +### Detailed design discussion -### Considered alternatives +#### Should we have support for non-blocking read/write? -[This section is not required if you already covered considered alternatives in the design discussion above.] +This may be something we'll need to revisit, but currently, the way +non-blocking streams work is that they perform reads or writes that +read or write fewer bytes than requested. -#### [Alternative 1] +#### Why do read/write use u64 sizes? -[Describe an alternative which was considered, and why you decided against it.] +This is to make the API independent of the address space size of +the caller. Callees are still advised to avoid using sizes that +are larger than their instances will be able to allocate. -#### [Alternative 2] +#### Why have a `forward` function when you can just `splice` in a loop? -[etc.] +This seems like it'll be a common use case, and `forward` +addresses it in a very simple way. ### Stakeholder Interest & Feedback TODO before entering Phase 3. -[This should include a list of implementers who have expressed interest in implementing the proposal] +Wasi-io is being proposed to be a dependency of wasi-filesystem and +wasi-sockets, and is expected to be a foundational piece of WASI +preview2. ### References & acknowledgements Many thanks for valuable feedback and advice from: -- [Person 1] -- [Person 2] -- [etc.] +- Thanks to Luke Wagner for many design functions and the design of + the component-model async streams which inform the design here. +- Thanks to Calvin Prewitt for the idea to include a `forward` function + in this API. diff --git a/proposals/io/wasi-io.abi.md b/proposals/io/wasi-io.abi.md index bc6f37d0c..e1a5c66ad 100644 --- a/proposals/io/wasi-io.abi.md +++ b/proposals/io/wasi-io.abi.md @@ -16,6 +16,23 @@ Size: 0, Alignment: 1 #### `input-stream::read` Read bytes from a stream. + + This function returns a list of bytes containing the data that was + read, along with a bool indicating whether the end of the stream + was reached. The returned list will contain up to `len` bytes; it + may return fewer than requested, but not more. + + Once a stream has reached the end, subsequent calls to read or + `skip` will always report end-of-stream rather than producing more + data. + + If `len` is 0, it represents a request to read 0 bytes, which should + always succeed, assuming the stream hasn't reached its end yet, and + return an empty list. + + The len here is a `u64`, but some callees may not be able to allocate + a buffer as large as that would imply. + FIXME: describe what happens if allocation fails. ##### Params - `self`: handle @@ -29,6 +46,17 @@ Size: 0, Alignment: 1 #### `input-stream::skip` Skip bytes from a stream. + + This is similar to the `read` function, but avoids copying the + bytes into the instance. + + Once a stream has reached the end, subsequent calls to read or + `skip` will always report end-of-stream rather than producing more + data. + + This function returns the number of bytes skipped, along with a bool + indicating whether the end of the stream was reached. The returned + value will be at most `len`; it may be less. ##### Params - `self`: handle @@ -42,6 +70,9 @@ Size: 0, Alignment: 1 #### `output-stream::write` Write bytes to a stream. + + This function returns a `u64` indicating the number of bytes from + `buf` that were written; it may be less than the full list. ##### Params - `self`: handle @@ -54,7 +85,10 @@ Size: 0, Alignment: 1 #### `output-stream::write-repeated` - Write bytes to a stream. + Write a single byte multiple times to a stream. + + This function returns a `u64` indicating the number of copies of + `byte` that were written; it may be less than `len`. ##### Params - `self`: handle @@ -66,14 +100,17 @@ Size: 0, Alignment: 1 ---- -#### `output-stream::splice-stream` +#### `output-stream::splice` Read from one stream and write to another. + + This function returns the number of bytes transferred; it may be less + than `len`. ##### Params -- `self`: handle -- `src`: handle -- `len`: `u64` +- `self`: handle +- `src`: handle +- `len`: `u64` ##### Results - result<(`u64`, `bool`), [`stream-error`](#stream_error)> diff --git a/proposals/io/wasi-io.wit.md b/proposals/io/wasi-io.wit.md index 28fd8c45f..d21cde2e2 100644 --- a/proposals/io/wasi-io.wit.md +++ b/proposals/io/wasi-io.wit.md @@ -3,7 +3,7 @@ WASI I/O is an I/O abstraction API which is currently focused on providing stream types. -In the future, the component model is expected to add built in stream types; +In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API. ## `stream-error` @@ -21,6 +21,23 @@ resource input-stream { ## `read` ```wit /// Read bytes from a stream. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a bool indicating whether the end of the stream + /// was reached. The returned list will contain up to `len` bytes; it + /// may return fewer than requested, but not more. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// If `len` is 0, it represents a request to read 0 bytes, which should + /// always succeed, assuming the stream hasn't reached its end yet, and + /// return an empty list. + /// + /// The len here is a `u64`, but some callees may not be able to allocate + /// a buffer as large as that would imply. + /// FIXME: describe what happens if allocation fails. read: func( /// The maximum number of bytes to read len: u64 @@ -30,6 +47,17 @@ resource input-stream { ## `skip` ```wit /// Skip bytes from a stream. + /// + /// This is similar to the `read` function, but avoids copying the + /// bytes into the instance. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// This function returns the number of bytes skipped, along with a bool + /// indicating whether the end of the stream was reached. The returned + /// value will be at most `len`; it may be less. skip: func( /// The maximum number of bytes to skip. len: u64, @@ -48,6 +76,9 @@ resource output-stream { ## `write` ```wit /// Write bytes to a stream. + /// + /// This function returns a `u64` indicating the number of bytes from + /// `buf` that were written; it may be less than the full list. write: func( /// Data to write buf: list @@ -56,7 +87,10 @@ resource output-stream { ## `write-repeated` ```wit - /// Write bytes to a stream. + /// Write a single byte multiple times to a stream. + /// + /// This function returns a `u64` indicating the number of copies of + /// `byte` that were written; it may be less than `len`. write-repeated: func( /// The byte to write byte: u8, @@ -68,7 +102,10 @@ resource output-stream { ## `splice` ```wit /// Read from one stream and write to another. - splice-stream: func( + /// + /// This function returns the number of bytes transferred; it may be less + /// than `len`. + splice: func( /// The stream to read from. src: input-stream, /// The number of bytes to splice. @@ -76,6 +113,21 @@ resource output-stream { ) -> result, stream-error> ``` +## `forward` +```wit= + /// Forward the entire contents of an input stream to an output stream. + /// + /// This function repeatedly reads from the input stream and writes + /// the data to the output stream, until the end of the input stream + /// is reached, or an error is encountered. + /// + /// This function returns the number of bytes transferred. + forward: func( + /// The stream to read from. + src: input-stream + ) -> result +``` + ```wit } ``` From 717bc06c54ebb390da796e0c08b148838952f1dc Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 6 Feb 2023 08:32:24 -0800 Subject: [PATCH 1010/1772] Improve the documentation (#22) * Add more content to the README.md. Add more examples, a considered alternative, and replace more of the wasi-proposal-repo template content with real content. * Add more documentation to wasi-random.wit.md. * More documentation updates. More documentaion clarifications and additions. --------- Co-authored-by: HackMD <37423+hackmd-hub[bot]@users.noreply.github.com> --- proposals/random/README.md | 56 ++++++++++++++++------------- proposals/random/wasi-random.abi.md | 47 ++++++++++++++++++------ proposals/random/wasi-random.wit.md | 48 ++++++++++++++----------- 3 files changed, 95 insertions(+), 56 deletions(-) diff --git a/proposals/random/README.md b/proposals/random/README.md index 6ec1db2a6..d050b6e65 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -19,7 +19,7 @@ on at least Windows, macOS, and Linux. WASI random must have at least two complete independent implementations. -## Table of Contents [if the explainer is longer than one printed page] +## Table of Contents - [Introduction](#introduction) - [Goals](#goals) @@ -38,13 +38,13 @@ WASI random must have at least two complete independent implementations. ### Introduction -WASI Random is a WASI API for obtaining random data. +WASI Random is a WASI API for obtaining pseudo-random data. ### Goals The primary goals of WASI Random are: - To allow users to use WASI programs to obtain high-quality low-level - random data. + random data suitable for cryptography. - To allow source languages to enable DoS protection in their hash-maps in host environments that support it. @@ -86,19 +86,39 @@ used for debugging, and not production use. ### API walk-through -[Walk through of how someone would use this API.] +#### Main API: getting cryptographically-secure pseudo-random bytes -#### [Use case 1] +Return a list of cryptographically-secure pseudo-random bytes: -TODO: Describe a use case using `getrandom`. +```rust= + let len: u32 = your_own_code_to_decide_how_many_bytes_you_want(); -#### [Use case 2] + let bytes: Vec = get_random_bytes(len); +``` -TODO: Describe a use case using `insecure-random`. +#### Main API: getting cryptographically-secure pseudo-random bytes faster -### Detailed design discussion +Sometimes the bindings for `list` can have some overhead, so +another function is available which returns the same data but as a +`u64`: + +```rust= + let data: u64 = get_random_u64(); +``` + +#### Insecure API: Hash-map DoS protection + +Return a pair of u64's that can be used to initialize a hash implementation: + +```rust= + let init: (u64, u64) = insecure_random(); + + let combined: u128 = init.0 as u128 | (init.1 as u128 << 64); + + your_own_code_to_initialize_hash_map(combined); +``` -[This section should mostly refer to the .wit.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] +### Detailed design discussion ### What if the system lacks sufficient entropy during early boot? @@ -151,28 +171,16 @@ their bits of security, and it doesn't seem desirable to require wasm engines to run their own CSPRNG on a platform which alreay has one, so for now, the API does not specify a specific number. -### Why is insecure-random a fixed-length value import? +### Why is insecure-random a fixed-sized return value? This limits the amount of data that can be obtained through it. Since it's insecure, it's not intended to be used as an alternative to `getrandom`. -### Considered alternatives - -[This section is not required if you already covered considered alternatives in the design discussion above.] - -#### [Alternative 1] - -[Describe an alternative which was considered, and why you decided against it.] - -#### [Alternative 2] - -[etc.] - ### Stakeholder Interest & Feedback TODO before entering Phase 3. -[This should include a list of implementers who have expressed interest in implementing the proposal] +Preview1 has a random function, and it's widely exposed in toolchains. ### References & acknowledgements diff --git a/proposals/random/wasi-random.abi.md b/proposals/random/wasi-random.abi.md index 018ca64cb..0c2ff41e9 100644 --- a/proposals/random/wasi-random.abi.md +++ b/proposals/random/wasi-random.abi.md @@ -4,13 +4,16 @@ #### `get-random-bytes` - Return `len` random bytes. + Return `len` cryptographically-secure pseudo-random bytes. - This function must produce data from an adaquately seeded CSPRNG, so it - must not block, and the returned data is always unpredictable. + This function must produce data from an adaquately seeded + cryptographically-secure pseudo-random number generator (CSPRNG), so it + must not block, from the perspective of the calling program, and the + returned data is always unpredictable. - Deterministic environments must omit this function, rather than - implementing it with deterministic data. + This function must always return fresh pseudo-random data. Deterministic + environments must omit this function, rather than implementing it with + deterministic data. ##### Params - `len`: `u32` @@ -22,14 +25,36 @@ #### `get-random-u64` - Return a random `u64` value. + Return a cryptographically-secure pseudo-random `u64` value. - This function must produce data from an adaquately seeded CSPRNG, so it - must not block, and the returned data is always unpredictable. - - Deterministic environments must omit this function, rather than - implementing it with deterministic data. + This function returns the same type of pseudo-random data as + `get-random-bytes`, represented as a `u64`. ##### Results - `u64` +---- + +#### `insecure-random` + + Return a 128-bit value that may contain a pseudo-random value. + + The returned value is not required to be computed from a CSPRNG, and may + even be entirely deterministic. Host implementatations are encouraged to + provide pseudo-random values to any program exposed to attacker-controlled + content, to enable DoS protection built into many languages' hash-map + implementations. + + This function is intended to only be called once, by a source language + to initialize Denial Of Service (DoS) protection in its hash-map + implementation. + + # Expected future evolution + + This will likely be changed to a value import, to prevent it from being + called multiple times and potentially used for purposes other than DoS + protection. +##### Results + +- (`u64`, `u64`) + diff --git a/proposals/random/wasi-random.wit.md b/proposals/random/wasi-random.wit.md index 38400feb0..8472fa540 100644 --- a/proposals/random/wasi-random.wit.md +++ b/proposals/random/wasi-random.wit.md @@ -7,40 +7,46 @@ Windows. ## `get-random-bytes` ```wit -/// Return `len` random bytes. +/// Return `len` cryptographically-secure pseudo-random bytes. /// -/// This function must produce data from an adaquately seeded CSPRNG, so it -/// must not block, and the returned data is always unpredictable. +/// This function must produce data from an adaquately seeded +/// cryptographically-secure pseudo-random number generator (CSPRNG), so it +/// must not block, from the perspective of the calling program, and the +/// returned data is always unpredictable. /// -/// Deterministic environments must omit this function, rather than -/// implementing it with deterministic data. +/// This function must always return fresh pseudo-random data. Deterministic +/// environments must omit this function, rather than implementing it with +/// deterministic data. get-random-bytes: func(len: u32) -> list ``` ## `get-random-u64` ```wit -/// Return a random `u64` value. +/// Return a cryptographically-secure pseudo-random `u64` value. /// -/// This function must produce data from an adaquately seeded CSPRNG, so it -/// must not block, and the returned data is always unpredictable. -/// -/// Deterministic environments must omit this function, rather than -/// implementing it with deterministic data. +/// This function returns the same type of pseudo-random data as +/// `get-random-bytes`, represented as a `u64`. get-random-u64: func() -> u64 ``` ## `insecure-random` ```wit -/// A value containing 128 random bits. +/// Return a 128-bit value that may contain a pseudo-random value. +/// +/// The returned value is not required to be computed from a CSPRNG, and may +/// even be entirely deterministic. Host implementatations are encouraged to +/// provide pseudo-random values to any program exposed to attacker-controlled +/// content, to enable DoS protection built into many languages' hash-map +/// implementations. +/// +/// This function is intended to only be called once, by a source language +/// to initialize Denial Of Service (DoS) protection in its hash-map +/// implementation. /// -/// This is a value import, which means it only provides one value, rather -/// than being a function that could be called multiple times. This is intented -/// to be used by source languages to initialize hash-maps without needing the -/// full `getrandom` API. +/// # Expected future evolution /// -/// This value is not required to be computed from a CSPRNG, and may even be -/// entirely deterministic. Host implementatations are encouraged to provide -/// random values to any program exposed to attacker-controlled content, to -/// enable DoS protection built into many languages' hash-map implementations. -insecure-random: tuple +/// This will likely be changed to a value import, to prevent it from being +/// called multiple times and potentially used for purposes other than DoS +/// protection. +insecure-random: func() -> tuple ``` From c96160597ca5c2df373dee31f310c857a40344bf Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 6 Feb 2023 08:38:07 -0800 Subject: [PATCH 1011/1772] Add more content to the README.md. (#29) Add usage examples and more descriptions about the intent of the API, and fix a formatting error in wasi-default-clocks.wit.md. Co-authored-by: HackMD <37423+hackmd-hub[bot]@users.noreply.github.com> --- proposals/clocks/README.md | 47 ++++++++++++++------- proposals/clocks/wasi-default-clocks.wit.md | 2 +- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 8f9427c6e..682bebdba 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -19,7 +19,7 @@ on at least Windows, macOS, and Linux. WASI clocks must have at least two complete independent implementations. -## Table of Contents [if the explainer is longer than one printed page] +## Table of Contents - [Introduction](#introduction) - [Goals](#goals) @@ -57,19 +57,38 @@ formatting, or modifying the time of a clock. ### API walk-through -[Walk through of how someone would use this API.] +#### Measuring elapsed time -#### [Use case 1] +The monotonic clock APIs can be used to measure the elapsed time of a region of code: -[Provide example code snippets and diagrams explaining how the API would be used to solve the given problem] +```wit= +default-monotonic-clock: monotonic-clock +``` -#### [Use case 2] +```rust= + let clock: MonotonicClock = default_monotonic_clock(); -[etc.] + let start: Instant = monotonic_clock_now(clock); -### Detailed design discussion + // some stuff + + let stop: Instant = monotonic_clock_now(clock); + + let elapsed: Instant = stop - start; +``` + + +#### Telling the current human time: + +```rust= + let clock: WallClock = default_wall_clock(); -[This section should mostly refer to the .wit.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] + let the_current_time = wall_clock_now(); + + println!("it has been {} seconds and {} nanoseconds since the Unix epoch!", the_current_time.seconds, the_current_time.nanoseconds); +``` + +### Detailed design discussion ### What should the type of a timestamp be? @@ -89,21 +108,17 @@ And so, this API uses different data types for different types of clocks. ### Considered alternatives -[This section is not required if you already covered considered alternatives in the design discussion above.] - -#### [Alternative 1] - -[Describe an alternative which was considered, and why you decided against it.] +#### Per-process and per-thread clocks -#### [Alternative 2] +WASI preview1 included two clocks which measured the CPU time of the current process and the current thread, respectively. These clocks are difficult to implement efficiently in WASI implementations that have multiple wasm instances in the same host process, so they've been omitted from this API. -[etc.] +Wasi-libc has support for emulating these clocks, by using the monotonic clock instead, which isn't a technically precise replacement, but is enough to ensure minimal compatibility with existing code. ### Stakeholder Interest & Feedback TODO before entering Phase 3. -[This should include a list of implementers who have expressed interest in implementing the proposal] +Preview1 has monotonic and wall clock functions, and they're widely exposed in toolchains. ### References & acknowledgements diff --git a/proposals/clocks/wasi-default-clocks.wit.md b/proposals/clocks/wasi-default-clocks.wit.md index 1a1fa91a3..8c76bb905 100644 --- a/proposals/clocks/wasi-default-clocks.wit.md +++ b/proposals/clocks/wasi-default-clocks.wit.md @@ -20,12 +20,12 @@ default-monotonic-clock: monotonic-clock ``` ## `default-wall-clock` +```wit /// Return a default wall clock, suitable for general-purpose application /// needs. /// /// This allocates a new handle, so applications with frequent need of a clock /// handle should call this function once and reuse the handle instead of /// calling this function each time. -```wit default-wall-clock: wall-clock ``` From 0cff1166ac10a87c11e9045c80747248447f60ef Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 6 Feb 2023 14:14:54 -0800 Subject: [PATCH 1012/1772] Change `write-repeated` to `write-zeroes`. (#17) The main use case for `write-repeated` is writing zeros to a bytestream. I had generalized it to `write-repeated` in anticipation of thinking about how it will generalize to typed streams in the future, as not all types have natural zero values. However, not all types can be naturally copied either, such as owned handles and streams. Consequently, I don't think we'll generalize this to a fully-general typed-stream function, so we can specialize it to its intended use case of just writing zeros to a stream. --- proposals/io/wasi-io.abi.md | 7 +++---- proposals/io/wasi-io.wit.md | 12 +++++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/proposals/io/wasi-io.abi.md b/proposals/io/wasi-io.abi.md index e1a5c66ad..c336f7861 100644 --- a/proposals/io/wasi-io.abi.md +++ b/proposals/io/wasi-io.abi.md @@ -85,14 +85,13 @@ Size: 0, Alignment: 1 #### `output-stream::write-repeated` - Write a single byte multiple times to a stream. + Write multiple zero bytes to a stream. - This function returns a `u64` indicating the number of copies of - `byte` that were written; it may be less than `len`. + This function returns a `u64` indicating the number of zero bytes + that were written; it may be less than `len`. ##### Params - `self`: handle -- `byte`: `u8` - `len`: `u64` ##### Results diff --git a/proposals/io/wasi-io.wit.md b/proposals/io/wasi-io.wit.md index d21cde2e2..d076391ae 100644 --- a/proposals/io/wasi-io.wit.md +++ b/proposals/io/wasi-io.wit.md @@ -85,16 +85,14 @@ resource output-stream { ) -> result ``` -## `write-repeated` +## `write-zeroes` ```wit - /// Write a single byte multiple times to a stream. + /// Write multiple zero bytes to a stream. /// - /// This function returns a `u64` indicating the number of copies of - /// `byte` that were written; it may be less than `len`. + /// This function returns a `u64` indicating the number of zero bytes + /// that were written; it may be less than `len`. write-repeated: func( - /// The byte to write - byte: u8, - /// The number of times to write it + /// The number of zero bytes to write len: u64 ) -> result ``` From 57370f3252a115aa44fafe17915379d40e732afa Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 6 Feb 2023 17:46:37 -0800 Subject: [PATCH 1013/1772] Update to the latest wit-bindgen. Update to the latest wit-bindgen, including support for worlds and interfaces. This changes a few things about the directory layout: - Wit files are moved to a `wit` directory, to match how wit-bindgen expects packages to be layed out in their own directory. - There's also a wit/world.wit.md added, which contains a world that pulls in the interfaces in the repository, so that we can generate unified docuentation for the whole repository. - `*.abi.md` is now renamed to just `*.md`. - This also checks in an `.html` file rendered from the generated `.md` file. --- proposals/sockets/.github/workflows/main.yml | 4 +-- proposals/sockets/proposal-template.html | 24 ++++++++++++++ ...l-template.abi.md => proposal-template.md} | 27 +++++++-------- proposals/sockets/wasi-proposal-template.html | 24 ++++++++++++++ proposals/sockets/wasi-proposal-template.md | 33 +++++++++++++++++++ .../{ => wit}/proposal-template.wit.md | 17 ++++++++-- proposals/sockets/wit/world.wit.md | 12 +++++++ 7 files changed, 124 insertions(+), 17 deletions(-) create mode 100644 proposals/sockets/proposal-template.html rename proposals/sockets/{proposal-template.abi.md => proposal-template.md} (72%) create mode 100644 proposals/sockets/wasi-proposal-template.html create mode 100644 proposals/sockets/wasi-proposal-template.md rename proposals/sockets/{ => wit}/proposal-template.wit.md (82%) create mode 100644 proposals/sockets/wit/world.wit.md diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index a61809957..2f9000022 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v6 + - uses: WebAssembly/wit-abi-up-to-date@v10 with: - wit-abi-tag: wit-abi-0.6.0 + wit-abi-tag: wit-abi-0.7.0 diff --git a/proposals/sockets/proposal-template.html b/proposals/sockets/proposal-template.html new file mode 100644 index 000000000..0db3b9a4e --- /dev/null +++ b/proposals/sockets/proposal-template.html @@ -0,0 +1,24 @@ +

Import interface proposal-interface-name

+

Types

+

api-type-one: record

+

Short description

+

Explanation for developers using the API.

+

Size: 16, Alignment: 8

+

Record Fields

+ +

Functions

+
+

api-function-one

+

Short description

+

Explanation for developers using the API.

+
Results
+ diff --git a/proposals/sockets/proposal-template.abi.md b/proposals/sockets/proposal-template.md similarity index 72% rename from proposals/sockets/proposal-template.abi.md rename to proposals/sockets/proposal-template.md index 7a1c37209..da2d6ca21 100644 --- a/proposals/sockets/proposal-template.abi.md +++ b/proposals/sockets/proposal-template.md @@ -1,31 +1,32 @@ -# Types +# Import interface `proposal-interface-name` + +## Types ## `api-type-one`: record - Short description - - Explanation for developers using the API. +Short description + +Explanation for developers using the API. Size: 16, Alignment: 8 ### Record Fields - [`property1`](#api_type_one.property1): `u64` - - + + - [`property2`](#api_type_one.property2): `string` - - -# Functions + + +## Functions ---- #### `api-function-one` - Short description - - Explanation for developers using the API. +Short description + +Explanation for developers using the API. ##### Results - [`api-type-one`](#api_type_one) - diff --git a/proposals/sockets/wasi-proposal-template.html b/proposals/sockets/wasi-proposal-template.html new file mode 100644 index 000000000..0db3b9a4e --- /dev/null +++ b/proposals/sockets/wasi-proposal-template.html @@ -0,0 +1,24 @@ +

Import interface proposal-interface-name

+

Types

+

api-type-one: record

+

Short description

+

Explanation for developers using the API.

+

Size: 16, Alignment: 8

+

Record Fields

+ +

Functions

+
+

api-function-one

+

Short description

+

Explanation for developers using the API.

+
Results
+ diff --git a/proposals/sockets/wasi-proposal-template.md b/proposals/sockets/wasi-proposal-template.md new file mode 100644 index 000000000..ee404c310 --- /dev/null +++ b/proposals/sockets/wasi-proposal-template.md @@ -0,0 +1,33 @@ +# Import interface `proposal-interface-name` + +## Types + +## `api-type-one`: record + +Short description + +Explanation for developers using the API. + +Size: 16, Alignment: 8 + +### Record Fields + +- [`property1`](#api_type_one.property1): `u64` + + +- [`property2`](#api_type_one.property2): `string` + + +## Functions + +---- + +#### `api-function-one` + +Short description + +Explanation for developers using the API. +##### Results + +- `result0`: [`api-type-one`](#api_type_one) + diff --git a/proposals/sockets/proposal-template.wit.md b/proposals/sockets/wit/proposal-template.wit.md similarity index 82% rename from proposals/sockets/proposal-template.wit.md rename to proposals/sockets/wit/proposal-template.wit.md index 3c7e8efbd..c8f0c5bf1 100644 --- a/proposals/sockets/proposal-template.wit.md +++ b/proposals/sockets/wit/proposal-template.wit.md @@ -6,7 +6,16 @@ [If you want to include examples of the API in use, these should be in the README and linked to from this file.] -## api_type_one +## `proposal-interface-name` + +```wit +/// Short interface description. +/// +/// Explanation for developers using the interface API. +default interface proposal-interface-name { +``` + +## `api_type_one` ```wit /// Short description @@ -20,7 +29,7 @@ record api-type-one { More rigorous specification details for the implementer go here, if needed. -## api_function_one +## `api_function_one` ```wit /// Short description @@ -30,3 +39,7 @@ api-function-one: func() -> api-type-one ``` If needed, this would explain what a compliant implementation MUST do, such as never returning an earlier result from a later call. + +```wit +} +``` diff --git a/proposals/sockets/wit/world.wit.md b/proposals/sockets/wit/world.wit.md new file mode 100644 index 000000000..f0f8611a8 --- /dev/null +++ b/proposals/sockets/wit/world.wit.md @@ -0,0 +1,12 @@ +This file contains a world that imports all interfaces in this proposal. Its +primary purpose is to allow unified documentation to be easiy generated for +the whole proposal. + +Proposals should edit replace the import below (and this sentence) with imports +of their own interfaces. + +```wit +default world wasi-proposal-template { + import proposal-interface-name: pkg.proposal-template.proposal-interface-name +} +``` From 6de6f9b2ce54bcfe38cb72a6eebfa9bf8bfbbc22 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 Feb 2023 09:01:47 -0800 Subject: [PATCH 1014/1772] Fix the name of `write-zeroes`. (#18) I missed this in the rename from `write-repeated` to `write-zeroes`. --- proposals/io/wasi-io.abi.md | 6 +++--- proposals/io/wasi-io.wit.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/io/wasi-io.abi.md b/proposals/io/wasi-io.abi.md index c336f7861..ec4076f87 100644 --- a/proposals/io/wasi-io.abi.md +++ b/proposals/io/wasi-io.abi.md @@ -83,7 +83,7 @@ Size: 0, Alignment: 1 ---- -#### `output-stream::write-repeated` +#### `output-stream::write-zeroes` Write multiple zero bytes to a stream. @@ -91,8 +91,8 @@ Size: 0, Alignment: 1 that were written; it may be less than `len`. ##### Params -- `self`: handle -- `len`: `u64` +- `self`: handle +- `len`: `u64` ##### Results - result<`u64`, [`stream-error`](#stream_error)> diff --git a/proposals/io/wasi-io.wit.md b/proposals/io/wasi-io.wit.md index d076391ae..950b48bc7 100644 --- a/proposals/io/wasi-io.wit.md +++ b/proposals/io/wasi-io.wit.md @@ -91,7 +91,7 @@ resource output-stream { /// /// This function returns a `u64` indicating the number of zero bytes /// that were written; it may be less than `len`. - write-repeated: func( + write-zeroes: func( /// The number of zero bytes to write len: u64 ) -> result From c7b9458a8c997002417e602a2c0d1f9c98826ba5 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 Feb 2023 14:33:30 -0800 Subject: [PATCH 1015/1772] Change `get-random-bytes`' size to a `u64`. (#24) Fixes #21. --- proposals/random/wasi-random.abi.md | 2 +- proposals/random/wasi-random.wit.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/wasi-random.abi.md b/proposals/random/wasi-random.abi.md index 0c2ff41e9..bc0e8e3e8 100644 --- a/proposals/random/wasi-random.abi.md +++ b/proposals/random/wasi-random.abi.md @@ -16,7 +16,7 @@ deterministic data. ##### Params -- `len`: `u32` +- `len`: `u64` ##### Results - list<`u8`> diff --git a/proposals/random/wasi-random.wit.md b/proposals/random/wasi-random.wit.md index 8472fa540..79ae7ee39 100644 --- a/proposals/random/wasi-random.wit.md +++ b/proposals/random/wasi-random.wit.md @@ -17,7 +17,7 @@ Windows. /// This function must always return fresh pseudo-random data. Deterministic /// environments must omit this function, rather than implementing it with /// deterministic data. -get-random-bytes: func(len: u32) -> list +get-random-bytes: func(len: u64) -> list ``` ## `get-random-u64` From 15c661ca38939a0c788ce7a0d02ac8304da36c26 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 Feb 2023 14:43:05 -0800 Subject: [PATCH 1016/1772] Add a timezone API. (#32) * Add a timezone API. Add a small timezone API that returns the UTC offset, timezone name, and daylight saving time status for a given `datetime` timestamp. This is not a full timezone database API. It's designed so that implementations that don't wish to do anything with timezones can just support a single "UTC" time zone, which can be easily implemented. It's also not a time formatting or locale API. It doesn't say how to format a human-readable timestamp; it just provides the information that would typically be formatted into a human-readable timestamp. This API expects a `timezone` handle argument will be added to the command entrypoint function, providing programs with a `timezone` to provide timezone information about wall-clock timestamps. Fixes #25. --- proposals/clocks/timezone.abi.md | 93 ++++++++++++++++++++++++++++++++ proposals/clocks/timezone.wit.md | 93 ++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 proposals/clocks/timezone.abi.md create mode 100644 proposals/clocks/timezone.wit.md diff --git a/proposals/clocks/timezone.abi.md b/proposals/clocks/timezone.abi.md new file mode 100644 index 000000000..e3af485bd --- /dev/null +++ b/proposals/clocks/timezone.abi.md @@ -0,0 +1,93 @@ +# Types + +## `datetime`: record + + A time and date in seconds plus nanoseconds. + + TODO: Use the definition from the monotonic clock API instead of defining our own copy. + +Size: 16, Alignment: 8 + +### Record Fields + +- [`seconds`](#datetime.seconds): `u64` + + +- [`nanoseconds`](#datetime.nanoseconds): `u32` + + +## `timezone-display`: record + + Information useful for displaying the timezone of a specific `datetime`. + + This information may vary within a single `timezone` to reflect daylight + saving time adjustments. + +Size: 16, Alignment: 4 + +### Record Fields + +- [`utc-offset`](#timezone_display.utc_offset): `u32` + + The number of seconds difference between UTC time and the local time of + the timezone. + + The returned value will always be less than 86400 which is the number of + seconds in a day (24*60*60). + + In implementations that do not expose an actual time zone, this should + return 0. + +- [`name`](#timezone_display.name): `string` + + The abbreviated name of the timezone to display to a user. The name `UTC` + indicates Coordinated Universal Time. Otherwise, this should reference + local standards for the name of the time zone. + + In implementations that do not expose an actual time zone, this should be + the string `UTC`. + + In time zones that do not have an applicable name, a formatted + representation of the UTC offset may be returned, such as `-04:00`. + +- [`in-daylight-saving-time`](#timezone_display.in_daylight_saving_time): `bool` + + Whether daylight saving time is active. + + In implementations that do not expose an actual time zone, this should + return false. + +# Functions + +---- + +#### `timezone::display` + + Return information needed to display the given `datetime`. This includes + the UTC offset, the time zone name, and a flag indicating whether + daylight saving time is active. + + If the timezone cannot be determined for the given `datetime`, return a + `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + saving time. +##### Params + +- `self`: handle +- `when`: [`datetime`](#datetime) +##### Results + +- [`timezone-display`](#timezone_display) + +---- + +#### `timezone::utc-offset` + + The same as `display`, but only return the UTC offset. +##### Params + +- `self`: handle +- `when`: [`datetime`](#datetime) +##### Results + +- `u32` + diff --git a/proposals/clocks/timezone.wit.md b/proposals/clocks/timezone.wit.md new file mode 100644 index 000000000..af2c8680a --- /dev/null +++ b/proposals/clocks/timezone.wit.md @@ -0,0 +1,93 @@ +# WASI Clocks Timezone API + +## `datetime` +```wit +/// A time and date in seconds plus nanoseconds. +/// +/// TODO: Use the definition from the monotonic clock API instead of defining our own copy. +record datetime { + seconds: u64, + nanoseconds: u32, +} +``` + +## `timezone` +```wit +/// A timezone. +/// +/// In timezones that recognize daylight saving time, also known as daylight +/// time and summer time, the information returned from the functions varies +/// over time to reflect these adjustments. +resource timezone { +``` + +## `display` +```wit + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + display: func(when: datetime) -> timezone-display +``` + +## `utc-offset` +```wit + /// The same as `display`, but only return the UTC offset. + utc-offset: func(when: datetime) -> u32 +``` + +```wit +} +``` + +## `timezone-display` +```wit +/// Information useful for displaying the timezone of a specific `datetime`. +/// +/// This information may vary within a single `timezone` to reflect daylight +/// saving time adjustments. +record timezone-display { +``` + +## `utc-offset` +```wit + /// The number of seconds difference between UTC time and the local time of + /// the timezone. + /// + /// The returned value will always be less than 86400 which is the number of + /// seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this should + /// return 0. + utc-offset: u32, +``` + +## `name` +```wit + /// The abbreviated name of the timezone to display to a user. The name `UTC` + /// indicates Coordinated Universal Time. Otherwise, this should reference + /// local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this should be + /// the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, +``` + +## `in-daylight-saving-time` +```wit + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this should + /// return false. + in-daylight-saving-time: bool, +``` + +```wit +} +``` From 55995c64ebadaedda74e0206f1631835da49cb5e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 8 Feb 2023 04:25:35 -0800 Subject: [PATCH 1017/1772] Update to the latest wasi-proposal-repo format. (#25) This updates to the latest wasi-proposal-repo format, which includes updating to the latest wit-bindgen. --- proposals/random/.github/workflows/main.yml | 4 +- proposals/random/wasi-random.abi.md | 60 ------------------ proposals/random/wasi-random.html | 48 ++++++++++++++ proposals/random/wasi-random.md | 62 +++++++++++++++++++ proposals/random/{ => wit}/wasi-random.wit.md | 20 ++++-- proposals/random/wit/world.wit.md | 9 +++ 6 files changed, 135 insertions(+), 68 deletions(-) delete mode 100644 proposals/random/wasi-random.abi.md create mode 100644 proposals/random/wasi-random.html create mode 100644 proposals/random/wasi-random.md rename proposals/random/{ => wit}/wasi-random.wit.md (81%) create mode 100644 proposals/random/wit/world.wit.md diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index b05870f53..8ca235c4f 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v6 + - uses: WebAssembly/wit-abi-up-to-date@v10 with: - wit-abi-tag: wit-abi-0.5.0 + wit-abi-tag: wit-abi-0.8.0 diff --git a/proposals/random/wasi-random.abi.md b/proposals/random/wasi-random.abi.md deleted file mode 100644 index bc0e8e3e8..000000000 --- a/proposals/random/wasi-random.abi.md +++ /dev/null @@ -1,60 +0,0 @@ -# Functions - ----- - -#### `get-random-bytes` - - Return `len` cryptographically-secure pseudo-random bytes. - - This function must produce data from an adaquately seeded - cryptographically-secure pseudo-random number generator (CSPRNG), so it - must not block, from the perspective of the calling program, and the - returned data is always unpredictable. - - This function must always return fresh pseudo-random data. Deterministic - environments must omit this function, rather than implementing it with - deterministic data. -##### Params - -- `len`: `u64` -##### Results - -- list<`u8`> - ----- - -#### `get-random-u64` - - Return a cryptographically-secure pseudo-random `u64` value. - - This function returns the same type of pseudo-random data as - `get-random-bytes`, represented as a `u64`. -##### Results - -- `u64` - ----- - -#### `insecure-random` - - Return a 128-bit value that may contain a pseudo-random value. - - The returned value is not required to be computed from a CSPRNG, and may - even be entirely deterministic. Host implementatations are encouraged to - provide pseudo-random values to any program exposed to attacker-controlled - content, to enable DoS protection built into many languages' hash-map - implementations. - - This function is intended to only be called once, by a source language - to initialize Denial Of Service (DoS) protection in its hash-map - implementation. - - # Expected future evolution - - This will likely be changed to a value import, to prevent it from being - called multiple times and potentially used for purposes other than DoS - protection. -##### Results - -- (`u64`, `u64`) - diff --git a/proposals/random/wasi-random.html b/proposals/random/wasi-random.html new file mode 100644 index 000000000..a6fe0f693 --- /dev/null +++ b/proposals/random/wasi-random.html @@ -0,0 +1,48 @@ +

Import interface wasi-random

+

Functions

+
+

get-random-bytes

+

Return len cryptographically-secure pseudo-random bytes.

+

This function must produce data from an adequately seeded +cryptographically-secure pseudo-random number generator (CSPRNG), so it +must not block, from the perspective of the calling program, and the +returned data is always unpredictable.

+

This function must always return fresh pseudo-random data. Deterministic +environments must omit this function, rather than implementing it with +deterministic data.

+
Params
+
    +
  • len: u64
  • +
+
Results
+
    +
  • result0: list<u8>
  • +
+
+

get-random-u64

+

Return a cryptographically-secure pseudo-random u64 value.

+

This function returns the same type of pseudo-random data as +get-random-bytes, represented as a u64.

+
Results
+
    +
  • result0: u64
  • +
+
+

insecure-random

+

Return a 128-bit value that may contain a pseudo-random value.

+

The returned value is not required to be computed from a CSPRNG, and may +even be entirely deterministic. Host implementations are encouraged to +provide pseudo-random values to any program exposed to attacker-controlled +content, to enable DoS protection built into many languages' hash-map +implementations.

+

This function is intended to only be called once, by a source language +to initialize Denial Of Service (DoS) protection in its hash-map +implementation.

+

Expected future evolution

+

This will likely be changed to a value import, to prevent it from being +called multiple times and potentially used for purposes other than DoS +protection.

+
Results
+
    +
  • result0: (u64, u64)
  • +
diff --git a/proposals/random/wasi-random.md b/proposals/random/wasi-random.md new file mode 100644 index 000000000..a772cd5dd --- /dev/null +++ b/proposals/random/wasi-random.md @@ -0,0 +1,62 @@ +# Import interface `wasi-random` + +## Functions + +---- + +#### `get-random-bytes` + +Return `len` cryptographically-secure pseudo-random bytes. + +This function must produce data from an adequately seeded +cryptographically-secure pseudo-random number generator (CSPRNG), so it +must not block, from the perspective of the calling program, and the +returned data is always unpredictable. + +This function must always return fresh pseudo-random data. Deterministic +environments must omit this function, rather than implementing it with +deterministic data. +##### Params + +- `len`: `u64` +##### Results + +- `result0`: list<`u8`> + +---- + +#### `get-random-u64` + +Return a cryptographically-secure pseudo-random `u64` value. + +This function returns the same type of pseudo-random data as +`get-random-bytes`, represented as a `u64`. +##### Results + +- `result0`: `u64` + +---- + +#### `insecure-random` + +Return a 128-bit value that may contain a pseudo-random value. + +The returned value is not required to be computed from a CSPRNG, and may +even be entirely deterministic. Host implementations are encouraged to +provide pseudo-random values to any program exposed to attacker-controlled +content, to enable DoS protection built into many languages' hash-map +implementations. + +This function is intended to only be called once, by a source language +to initialize Denial Of Service (DoS) protection in its hash-map +implementation. + +# Expected future evolution + +This will likely be changed to a value import, to prevent it from being +called multiple times and potentially used for purposes other than DoS +protection. +##### Results + +- `result0`: (`u64`, `u64`) + diff --git a/proposals/random/wasi-random.wit.md b/proposals/random/wit/wasi-random.wit.md similarity index 81% rename from proposals/random/wasi-random.wit.md rename to proposals/random/wit/wasi-random.wit.md index 79ae7ee39..1c0a5605e 100644 --- a/proposals/random/wasi-random.wit.md +++ b/proposals/random/wit/wasi-random.wit.md @@ -1,15 +1,19 @@ # WASI Random API -WASI Random is a random data API. - -It is intended to be portable at least between Unix-family platforms and -Windows. +## `wasi-random` +```wit +/// WASI Random is a random data API. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface wasi-random { +``` ## `get-random-bytes` ```wit /// Return `len` cryptographically-secure pseudo-random bytes. /// -/// This function must produce data from an adaquately seeded +/// This function must produce data from an adequately seeded /// cryptographically-secure pseudo-random number generator (CSPRNG), so it /// must not block, from the perspective of the calling program, and the /// returned data is always unpredictable. @@ -34,7 +38,7 @@ get-random-u64: func() -> u64 /// Return a 128-bit value that may contain a pseudo-random value. /// /// The returned value is not required to be computed from a CSPRNG, and may -/// even be entirely deterministic. Host implementatations are encouraged to +/// even be entirely deterministic. Host implementations are encouraged to /// provide pseudo-random values to any program exposed to attacker-controlled /// content, to enable DoS protection built into many languages' hash-map /// implementations. @@ -50,3 +54,7 @@ get-random-u64: func() -> u64 /// protection. insecure-random: func() -> tuple ``` + +```wit +} +``` diff --git a/proposals/random/wit/world.wit.md b/proposals/random/wit/world.wit.md new file mode 100644 index 000000000..5078746d2 --- /dev/null +++ b/proposals/random/wit/world.wit.md @@ -0,0 +1,9 @@ +This file contains a world that imports all interfaces in this proposal. Its +primary purpose is to allow unified documentation to be easily generated for +the whole proposal. + +```wit +default world wasi-random { + import wasi-random: pkg.wasi-random +} +``` From 9d7430be64e7e6852ac900ca07d5af13ccf7cfee Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 8 Feb 2023 04:26:26 -0800 Subject: [PATCH 1018/1772] Update to the latest wasi-proposal-repo format. (#94) This updates to the latest wasi-proposal-repo format, which includes updating to the latest wit-bindgen. That in turm includes temporarily removing resources, though I've left in comments making it clear where the resources will go. --- .../filesystem/.github/workflows/main.yml | 4 +- proposals/filesystem/wasi-filesystem.abi.md | 1125 ----------------- proposals/filesystem/wasi-filesystem.html | 933 ++++++++++++++ proposals/filesystem/wasi-filesystem.md | 1079 ++++++++++++++++ .../{ => wit}/wasi-filesystem.wit.md | 194 ++- proposals/filesystem/wit/world.wit.md | 9 + 6 files changed, 2113 insertions(+), 1231 deletions(-) delete mode 100644 proposals/filesystem/wasi-filesystem.abi.md create mode 100644 proposals/filesystem/wasi-filesystem.html create mode 100644 proposals/filesystem/wasi-filesystem.md rename proposals/filesystem/{ => wit}/wasi-filesystem.wit.md (86%) create mode 100644 proposals/filesystem/wit/world.wit.md diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index a61809957..8ca235c4f 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v6 + - uses: WebAssembly/wit-abi-up-to-date@v10 with: - wit-abi-tag: wit-abi-0.6.0 + wit-abi-tag: wit-abi-0.8.0 diff --git a/proposals/filesystem/wasi-filesystem.abi.md b/proposals/filesystem/wasi-filesystem.abi.md deleted file mode 100644 index 41efd2ad3..000000000 --- a/proposals/filesystem/wasi-filesystem.abi.md +++ /dev/null @@ -1,1125 +0,0 @@ -# Types - -## `filesize`: `u64` - - Non-negative file size or length of a region within a file. - -Size: 8, Alignment: 8 - -## `filedelta`: `s64` - - Relative offset within a file. - -Size: 8, Alignment: 8 - -## `datetime`: record - - Timestamp in seconds and nanoseconds. - -Size: 16, Alignment: 8 - -### Record Fields - -- [`seconds`](#datetime.seconds): `u64` - - -- [`nanoseconds`](#datetime.nanoseconds): `u32` - - -## `descriptor-type`: enum - - The type of a filesystem object referenced by a descriptor. - - Note: This was called `filetype` in earlier versions of WASI. - -Size: 1, Alignment: 1 - -### Enum Cases - -- [`unknown`](#descriptor_type.unknown) - - The type of the descriptor or file is unknown or is different from - any of the other types specified. - -- [`block-device`](#descriptor_type.block_device) - - The descriptor refers to a block device inode. - -- [`character-device`](#descriptor_type.character_device) - - The descriptor refers to a character device inode. - -- [`directory`](#descriptor_type.directory) - - The descriptor refers to a directory inode. - -- [`fifo`](#descriptor_type.fifo) - - The descriptor refers to a named pipe. - -- [`symbolic-link`](#descriptor_type.symbolic_link) - - The file refers to a symbolic link inode. - -- [`regular-file`](#descriptor_type.regular_file) - - The descriptor refers to a regular file inode. - -- [`socket`](#descriptor_type.socket) - - The descriptor refers to a socket. - -## `descriptor-flags`: flags - - Descriptor flags. - - Note: This was called `fdflags` in earlier versions of WASI. - -Size: 1, Alignment: 1 - -### Flags Fields - -- [`read`](#descriptor_flags.read) - - Read mode: Data can be read. -Bit: 0 - -- [`write`](#descriptor_flags.write) - - Write mode: Data can be written to. -Bit: 1 - -- [`append`](#descriptor_flags.append) - - Append mode: Data written to the file is always appended to the file's - end. -Bit: 2 - -- [`dsync`](#descriptor_flags.dsync) - - Write according to synchronized I/O data integrity completion. Only the - data stored in the file is synchronized. -Bit: 3 - -- [`nonblock`](#descriptor_flags.nonblock) - - Non-blocking mode. -Bit: 4 - -- [`rsync`](#descriptor_flags.rsync) - - Synchronized read I/O operations. -Bit: 5 - -- [`sync`](#descriptor_flags.sync) - - Write according to synchronized I/O file integrity completion. In - addition to synchronizing the data stored in the file, the - implementation may also synchronously update the file's metadata. -Bit: 6 - -## `descriptor-stat`: record - - File attributes. - - Note: This was called `filestat` in earlier versions of WASI. - -Size: 88, Alignment: 8 - -### Record Fields - -- [`dev`](#descriptor_stat.dev): [`device`](#device) - - Device ID of device containing the file. - -- [`ino`](#descriptor_stat.ino): [`inode`](#inode) - - File serial number. - -- [`type`](#descriptor_stat.type): [`descriptor-type`](#descriptor_type) - - File type. - -- [`nlink`](#descriptor_stat.nlink): [`linkcount`](#linkcount) - - Number of hard links to the file. - -- [`size`](#descriptor_stat.size): [`filesize`](#filesize) - - For regular files, the file size in bytes. For symbolic links, the length - in bytes of the pathname contained in the symbolic link. - -- [`atim`](#descriptor_stat.atim): [`datetime`](#datetime) - - Last data access timestamp. - -- [`mtim`](#descriptor_stat.mtim): [`datetime`](#datetime) - - Last data modification timestamp. - -- [`ctim`](#descriptor_stat.ctim): [`datetime`](#datetime) - - Last file status change timestamp. - -## `at-flags`: flags - - Flags determining the method of how paths are resolved. - -Size: 1, Alignment: 1 - -### Flags Fields - -- [`symlink-follow`](#at_flags.symlink_follow) - - As long as the resolved path corresponds to a symbolic link, it is expanded. -Bit: 0 - -## `o-flags`: flags - - Open flags used by `open-at`. - -Size: 1, Alignment: 1 - -### Flags Fields - -- [`create`](#o_flags.create) - - Create file if it does not exist. -Bit: 0 - -- [`directory`](#o_flags.directory) - - Fail if not a directory. -Bit: 1 - -- [`excl`](#o_flags.excl) - - Fail if file already exists. -Bit: 2 - -- [`trunc`](#o_flags.trunc) - - Truncate file to size 0. -Bit: 3 - -## `mode`: flags - - Permissions mode used by `open-at`, `change-file-permissions-at`, and - similar. - -Size: 1, Alignment: 1 - -### Flags Fields - -- [`readable`](#mode.readable) - - True if the resource is considered readable by the containing - filesystem. -Bit: 0 - -- [`writeable`](#mode.writeable) - - True if the resource is considered writeable by the containing - filesystem. -Bit: 1 - -- [`executable`](#mode.executable) - - True if the resource is considered executable by the containing - filesystem. This does not apply to directories. -Bit: 2 - -## `linkcount`: `u64` - - Number of hard links to an inode. - -Size: 8, Alignment: 8 - -## `device`: `u64` - - Identifier for a device containing a file system. Can be used in combination - with `inode` to uniquely identify a file or directory in the filesystem. - -Size: 8, Alignment: 8 - -## `inode`: `u64` - - Filesystem object serial number that is unique within its file system. - -Size: 8, Alignment: 8 - -## `new-timestamp`: variant - - When setting a timestamp, this gives the value to set it to. - -Size: 24, Alignment: 8 - -### Variant Cases - -- [`no-change`](#new_timestamp.no_change) - - Leave the timestamp set to its previous value. - -- [`now`](#new_timestamp.now) - - Set the timestamp to the current time of the system clock associated - with the filesystem. - -- [`timestamp`](#new_timestamp.timestamp): [`datetime`](#datetime) - - Set the timestamp to the given value. - -## `dir-entry`: record - - A directory entry. - -Size: 32, Alignment: 8 - -### Record Fields - -- [`ino`](#dir_entry.ino): option<[`inode`](#inode)> - - The serial number of the object referred to by this directory entry. - May be none if the inode value is not known. - - When this is none, libc implementations might do an extra `stat-at` - call to retrieve the inode number to fill their `d_ino` fields, so - implementations which can set this to a non-none value should do so. - -- [`type`](#dir_entry.type): [`descriptor-type`](#descriptor_type) - - The type of the file referred to by this directory entry. - -- [`name`](#dir_entry.name): `string` - - The name of the object. - -## `errno`: enum - - Error codes returned by functions. - Not all of these error codes are returned by the functions provided by this - API; some are used in higher-level library layers, and others are provided - merely for alignment with POSIX. - -Size: 1, Alignment: 1 - -### Enum Cases - -- [`access`](#errno.access) - - Permission denied. - -- [`again`](#errno.again) - - Resource unavailable, or operation would block. - -- [`already`](#errno.already) - - Connection already in progress. - -- [`badf`](#errno.badf) - - Bad descriptor. - -- [`busy`](#errno.busy) - - Device or resource busy. - -- [`child`](#errno.child) - - No child processes. - -- [`deadlk`](#errno.deadlk) - - Resource deadlock would occur. - -- [`dquot`](#errno.dquot) - - Storage quota exceeded. - -- [`exist`](#errno.exist) - - File exists. - -- [`fbig`](#errno.fbig) - - File too large. - -- [`ilseq`](#errno.ilseq) - - Illegal byte sequence. - -- [`inprogress`](#errno.inprogress) - - Operation in progress. - -- [`intr`](#errno.intr) - - Interrupted function. - -- [`inval`](#errno.inval) - - Invalid argument. - -- [`io`](#errno.io) - - I/O error. - -- [`isdir`](#errno.isdir) - - Is a directory. - -- [`loop`](#errno.loop) - - Too many levels of symbolic links. - -- [`mlink`](#errno.mlink) - - Too many links. - -- [`msgsize`](#errno.msgsize) - - Message too large. - -- [`nametoolong`](#errno.nametoolong) - - Filename too long. - -- [`nodev`](#errno.nodev) - - No such device. - -- [`noent`](#errno.noent) - - No such file or directory. - -- [`nolck`](#errno.nolck) - - No locks available. - -- [`nomem`](#errno.nomem) - - Not enough space. - -- [`nospc`](#errno.nospc) - - No space left on device. - -- [`nosys`](#errno.nosys) - - Function not supported. - -- [`notdir`](#errno.notdir) - - Not a directory or a symbolic link to a directory. - -- [`notempty`](#errno.notempty) - - Directory not empty. - -- [`notrecoverable`](#errno.notrecoverable) - - State not recoverable. - -- [`notsup`](#errno.notsup) - - Not supported, or operation not supported on socket. - -- [`notty`](#errno.notty) - - Inappropriate I/O control operation. - -- [`nxio`](#errno.nxio) - - No such device or address. - -- [`overflow`](#errno.overflow) - - Value too large to be stored in data type. - -- [`perm`](#errno.perm) - - Operation not permitted. - -- [`pipe`](#errno.pipe) - - Broken pipe. - -- [`rofs`](#errno.rofs) - - Read-only file system. - -- [`spipe`](#errno.spipe) - - Invalid seek. - -- [`txtbsy`](#errno.txtbsy) - - Text file busy. - -- [`xdev`](#errno.xdev) - - Cross-device link. - -## `advice`: enum - - File or memory access pattern advisory information. - -Size: 1, Alignment: 1 - -### Enum Cases - -- [`normal`](#advice.normal) - - The application has no advice to give on its behavior with respect to the specified data. - -- [`sequential`](#advice.sequential) - - The application expects to access the specified data sequentially from lower offsets to higher offsets. - -- [`random`](#advice.random) - - The application expects to access the specified data in a random order. - -- [`will-need`](#advice.will_need) - - The application expects to access the specified data in the near future. - -- [`dont-need`](#advice.dont_need) - - The application expects that it will not access the specified data in the near future. - -- [`no-reuse`](#advice.no_reuse) - - The application expects to access the specified data once and then not reuse it thereafter. - -## `seek-from`: variant - - The position relative to which to set the offset of the descriptor. - -Size: 16, Alignment: 8 - -### Variant Cases - -- [`set`](#seek_from.set): [`filesize`](#filesize) - - Seek relative to start-of-file. - -- [`cur`](#seek_from.cur): [`filedelta`](#filedelta) - - Seek relative to current position. - -- [`end`](#seek_from.end): [`filesize`](#filesize) - - Seek relative to end-of-file. - -# Functions - ----- - -#### `descriptor::fadvise` - - Provide file advisory information on a descriptor. - - This is similar to `posix_fadvise` in POSIX. -##### Params - -- `self`: handle -- `offset`: [`filesize`](#filesize) -- `len`: [`filesize`](#filesize) -- `advice`: [`advice`](#advice) -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::datasync` - - Synchronize the data of a file to disk. - - Note: This is similar to `fdatasync` in POSIX. -##### Params - -- `self`: handle -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::flags` - - Get flags associated with a descriptor. - - Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. - - Note: This returns the value that was the `fs_flags` value returned - from `fdstat_get` in earlier versions of WASI. -##### Params - -- `self`: handle -##### Results - -- result<[`descriptor-flags`](#descriptor_flags), [`errno`](#errno)> - ----- - -#### `descriptor::type` - - Get the dynamic type of a descriptor. - - Note: This returns the same value as the `type` field of the `fd-stat` - returned by `stat`, `stat-at` and similar. - - Note: This returns similar flags to the `st_mode & S_IFMT` value provided - by `fstat` in POSIX. - - Note: This returns the value that was the `fs_filetype` value returned - from `fdstat_get` in earlier versions of WASI. -##### Params - -- `self`: handle -##### Results - -- result<[`descriptor-type`](#descriptor_type), [`errno`](#errno)> - ----- - -#### `descriptor::set-flags` - - Set flags associated with a descriptor. - - Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - - Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. -##### Params - -- `self`: handle -- `flags`: [`descriptor-flags`](#descriptor_flags) -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::set-size` - - Adjust the size of an open file. If this increases the file's size, the - extra bytes are filled with zeros. - - Note: This was called `fd_filestat_set_size` in earlier versions of WASI. -##### Params - -- `self`: handle -- `size`: [`filesize`](#filesize) -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::set-times` - - Adjust the timestamps of an open file or directory. - - Note: This is similar to `futimens` in POSIX. - - Note: This was called `fd_filestat_set_times` in earlier versions of WASI. -##### Params - -- `self`: handle -- `atim`: [`new-timestamp`](#new_timestamp) -- `mtim`: [`new-timestamp`](#new_timestamp) -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::pread` - - Read from a descriptor, without using and updating the descriptor's offset. - - Note: This is similar to `pread` in POSIX. -##### Params - -- `self`: handle -- `len`: [`filesize`](#filesize) -- `offset`: [`filesize`](#filesize) -##### Results - -- stream<`u8`, [`errno`](#errno)> - ----- - -#### `descriptor::pwrite` - - Write to a descriptor, without using and updating the descriptor's offset. - - It is valid to write past the end of a file; the file is extended to the - extent of the write, with bytes between the previous end and the start of - the write set to zero. - - Note: This is similar to `pwrite` in POSIX. -##### Params - -- `self`: handle -- `buf`: stream<`u8`> -- `offset`: [`filesize`](#filesize) -##### Results - -- future> - ----- - -#### `descriptor::readdir` - - Read directory entries from a directory. - - This always returns a new stream which starts at the beginning of the - directory. -##### Params - -- `self`: handle -##### Results - -- stream<[`dir-entry`](#dir_entry), [`errno`](#errno)> - ----- - -#### `descriptor::seek` - - Move the offset of a file descriptor. - - If the descriptor refers to a directory, this function fails with - `errno::spipe`. - - Returns new offset of the descriptor, relative to the start of the file. - - It is valid to seek past the end of a file. The file size is not modified - until a write is performed, at which time the file is extended to the - extent of the write, with bytes between the previous end and the start of - the write set to zero. - - Note: This is similar to `lseek` in POSIX. -##### Params - -- `self`: handle -- `from`: [`seek-from`](#seek_from) -##### Results - -- result<[`filesize`](#filesize), [`errno`](#errno)> - ----- - -#### `descriptor::sync` - - Synchronize the data and metadata of a file to disk. - - Note: This is similar to `fsync` in POSIX. -##### Params - -- `self`: handle -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::tell` - - Return the current offset of a descriptor. - - If the descriptor refers to a directory, this function fails with - `errno::spipe`. - - Returns the current offset of the descriptor, relative to the start of the file. - - Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. -##### Params - -- `self`: handle -##### Results - -- result<[`filesize`](#filesize), [`errno`](#errno)> - ----- - -#### `descriptor::create-directory-at` - - Create a directory. - - Note: This is similar to `mkdirat` in POSIX. -##### Params - -- `self`: handle -- `path`: `string` -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::stat` - - Return the attributes of an open file or directory. - - Note: This is similar to `fstat` in POSIX. - - Note: This was called `fd_filestat_get` in earlier versions of WASI. -##### Params - -- `self`: handle -##### Results - -- result<[`descriptor-stat`](#descriptor_stat), [`errno`](#errno)> - ----- - -#### `descriptor::stat-at` - - Return the attributes of a file or directory. - - Note: This is similar to `fstatat` in POSIX. - - Note: This was called `path_filestat_get` in earlier versions of WASI. -##### Params - -- `self`: handle -- `at-flags`: [`at-flags`](#at_flags) -- `path`: `string` -##### Results - -- result<[`descriptor-stat`](#descriptor_stat), [`errno`](#errno)> - ----- - -#### `descriptor::set-times-at` - - Adjust the timestamps of a file or directory. - - Note: This is similar to `utimensat` in POSIX. - - Note: This was called `path_filestat_set_times` in earlier versions of WASI. -##### Params - -- `self`: handle -- `at-flags`: [`at-flags`](#at_flags) -- `path`: `string` -- `atim`: [`new-timestamp`](#new_timestamp) -- `mtim`: [`new-timestamp`](#new_timestamp) -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::link-at` - - Create a hard link. - - Note: This is similar to `linkat` in POSIX. -##### Params - -- `self`: handle -- `old-at-flags`: [`at-flags`](#at_flags) -- `old-path`: `string` -- `new-descriptor`: handle -- `new-path`: `string` -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::open-at` - - Open a file or directory. - - The returned descriptor is not guaranteed to be the lowest-numbered - descriptor not currently open/ it is randomized to prevent applications - from depending on making assumptions about indexes, since this is - error-prone in multi-threaded contexts. The returned descriptor is - guaranteed to be less than 2**31. - - Note: This is similar to `openat` in POSIX. -##### Params - -- `self`: handle -- `at-flags`: [`at-flags`](#at_flags) -- `path`: `string` -- `o-flags`: [`o-flags`](#o_flags) -- `flags`: [`descriptor-flags`](#descriptor_flags) -- `mode`: [`mode`](#mode) -##### Results - -- result, [`errno`](#errno)> - ----- - -#### `descriptor::readlink-at` - - Read the contents of a symbolic link. - - Note: This is similar to `readlinkat` in POSIX. -##### Params - -- `self`: handle -- `path`: `string` -##### Results - -- result<`string`, [`errno`](#errno)> - ----- - -#### `descriptor::remove-directory-at` - - Remove a directory. - - Return `errno::notempty` if the directory is not empty. - - Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. -##### Params - -- `self`: handle -- `path`: `string` -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::rename-at` - - Rename a filesystem object. - - Note: This is similar to `renameat` in POSIX. -##### Params - -- `self`: handle -- `old-path`: `string` -- `new-descriptor`: handle -- `new-path`: `string` -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::symlink-at` - - Create a symbolic link. - - Note: This is similar to `symlinkat` in POSIX. -##### Params - -- `self`: handle -- `old-path`: `string` -- `new-path`: `string` -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::unlink-file-at` - - Unlink a filesystem object that is not a directory. - - Return `errno::isdir` if the path refers to a directory. - Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. -##### Params - -- `self`: handle -- `path`: `string` -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::change-file-permissions-at` - - Change the permissions of a filesystem object that is not a directory. - - Note that the ultimate meanings of these permissions is - filesystem-specific. - - Note: This is similar to `fchmodat` in POSIX. -##### Params - -- `self`: handle -- `at-flags`: [`at-flags`](#at_flags) -- `path`: `string` -- `mode`: [`mode`](#mode) -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::change-directory-permissions-at` - - Change the permissions of a directory. - - Note that the ultimate meanings of these permissions is - filesystem-specific. - - Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" - flag. `read` on a directory implies readability and searchability, and - `execute` is not valid for directories. - - Note: This is similar to `fchmodat` in POSIX. -##### Params - -- `self`: handle -- `at-flags`: [`at-flags`](#at_flags) -- `path`: `string` -- `mode`: [`mode`](#mode) -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::lock-shared` - - Request a shared advisory lock for an open file. - - This requests a *shared* lock; more than one shared lock can be held for - a file at the same time. - - If the open file has an exclusive lock, this function downgrades the lock - to a shared lock. If it has a shared lock, this function has no effect. - - This requests an *advisory* lock, meaning that the file could be accessed - by other programs that don't hold the lock. - - It is unspecified how shared locks interact with locks acquired by - non-WASI programs. - - This function blocks until the lock can be acquired. - - Not all filesystems support locking; on filesystems which don't support - locking, this function returns `errno::notsup`. - - Note: This is similar to `flock(fd, LOCK_SH)` in Unix. -##### Params - -- `self`: handle -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::lock-exclusive` - - Request an exclusive advisory lock for an open file. - - This requests an *exclusive* lock; no other locks may be held for the - file while an exclusive lock is held. - - If the open file has a shared lock and there are no exclusive locks held - for the fhile, this function upgrades the lock to an exclusive lock. If the - open file already has an exclusive lock, this function has no effect. - - This requests an *advisory* lock, meaning that the file could be accessed - by other programs that don't hold the lock. - - It is unspecified whether this function succeeds if the file descriptor - is not opened for writing. It is unspecified how exclusive locks interact - with locks acquired by non-WASI programs. - - This function blocks until the lock can be acquired. - - Not all filesystems support locking; on filesystems which don't support - locking, this function returns `errno::notsup`. - - Note: This is similar to `flock(fd, LOCK_EX)` in Unix. -##### Params - -- `self`: handle -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::try-lock-shared` - - Request a shared advisory lock for an open file. - - This requests a *shared* lock; more than one shared lock can be held for - a file at the same time. - - If the open file has an exclusive lock, this function downgrades the lock - to a shared lock. If it has a shared lock, this function has no effect. - - This requests an *advisory* lock, meaning that the file could be accessed - by other programs that don't hold the lock. - - It is unspecified how shared locks interact with locks acquired by - non-WASI programs. - - This function returns `errno::wouldblock` if the lock cannot be acquired. - - Not all filesystems support locking; on filesystems which don't support - locking, this function returns `errno::notsup`. - - Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. -##### Params - -- `self`: handle -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::try-lock-exclusive` - - Request an exclusive advisory lock for an open file. - - This requests an *exclusive* lock; no other locks may be held for the - file while an exclusive lock is held. - - If the open file has a shared lock and there are no exclusive locks held - for the fhile, this function upgrades the lock to an exclusive lock. If the - open file already has an exclusive lock, this function has no effect. - - This requests an *advisory* lock, meaning that the file could be accessed - by other programs that don't hold the lock. - - It is unspecified whether this function succeeds if the file descriptor - is not opened for writing. It is unspecified how exclusive locks interact - with locks acquired by non-WASI programs. - - This function returns `errno::wouldblock` if the lock cannot be acquired. - - Not all filesystems support locking; on filesystems which don't support - locking, this function returns `errno::notsup`. - - Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. -##### Params - -- `self`: handle -##### Results - -- result<_, [`errno`](#errno)> - ----- - -#### `descriptor::unlock` - - Release a shared or exclusive lock on an open file. - - Note: This is similar to `flock(fd, LOCK_UN)` in Unix. -##### Params - -- `self`: handle -##### Results - -- result<_, [`errno`](#errno)> - diff --git a/proposals/filesystem/wasi-filesystem.html b/proposals/filesystem/wasi-filesystem.html new file mode 100644 index 000000000..d66fdc5bb --- /dev/null +++ b/proposals/filesystem/wasi-filesystem.html @@ -0,0 +1,933 @@ +

Import interface wasi-filesystem

+

Types

+

o-flags: record

+

Open flags used by open-at.

+

Size: 1, Alignment: 1

+

Record Fields

+
    +
  • +

    create:

    +

    Create file if it does not exist. +Bit: 0

    +
  • +
  • +

    directory:

    +

    Fail if not a directory. +Bit: 1

    +
  • +
  • +

    excl:

    +

    Fail if file already exists. +Bit: 2

    +
  • +
  • +

    trunc:

    +

    Truncate file to size 0. +Bit: 3

    +
  • +
+

new-timestamp: variant

+

When setting a timestamp, this gives the value to set it to.

+

Size: 16, Alignment: 8

+

Variant Cases

+
    +
  • +

    no-change

    +

    Leave the timestamp set to its previous value.

    +
  • +
  • +

    now

    +

    Set the timestamp to the current time of the system clock associated +with the filesystem.

    +
  • +
  • +

    timestamp: u64

    +

    Set the timestamp to the given value.

    +
  • +
+

mode: record

+

Permissions mode used by open-at, change-file-permissions-at, and +similar.

+

Size: 1, Alignment: 1

+

Record Fields

+
    +
  • +

    readable:

    +

    True if the resource is considered readable by the containing +filesystem. +Bit: 0

    +
  • +
  • +

    writeable:

    +

    True if the resource is considered writeable by the containing +filesystem. +Bit: 1

    +
  • +
  • +

    executable:

    +

    True if the resource is considered executable by the containing +filesystem. This does not apply to directories. +Bit: 2

    +
  • +
+

linkcount: u64

+

Number of hard links to an inode.

+

Size: 8, Alignment: 8

+

inode: u64

+

Filesystem object serial number that is unique within its file system.

+

Size: 8, Alignment: 8

+

filesize: u64

+

File size or length of a region within a file.

+

Size: 8, Alignment: 8

+

errno: enum

+

Error codes returned by functions. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX.

+

Size: 1, Alignment: 1

+

Enum Cases

+
    +
  • +

    access

    +

    Permission denied.

    +
  • +
  • +

    again

    +

    Resource unavailable, or operation would block.

    +
  • +
  • +

    already

    +

    Connection already in progress.

    +
  • +
  • +

    badf

    +

    Bad descriptor.

    +
  • +
  • +

    busy

    +

    Device or resource busy.

    +
  • +
  • +

    deadlk

    +

    Resource deadlock would occur.

    +
  • +
  • +

    dquot

    +

    Storage quota exceeded.

    +
  • +
  • +

    exist

    +

    File exists.

    +
  • +
  • +

    fbig

    +

    File too large.

    +
  • +
  • +

    ilseq

    +

    Illegal byte sequence.

    +
  • +
  • +

    inprogress

    +

    Operation in progress.

    +
  • +
  • +

    intr

    +

    Interrupted function.

    +
  • +
  • +

    inval

    +

    Invalid argument.

    +
  • +
  • +

    io

    +

    I/O error.

    +
  • +
  • +

    isdir

    +

    Is a directory.

    +
  • +
  • +

    loop

    +

    Too many levels of symbolic links.

    +
  • +
  • +

    mlink

    +

    Too many links.

    +
  • +
  • +

    msgsize

    +

    Message too large.

    +
  • +
  • +

    nametoolong

    +

    Filename too long.

    +
  • +
  • +

    nodev

    +

    No such device.

    +
  • +
  • +

    noent

    +

    No such file or directory.

    +
  • +
  • +

    nolck

    +

    No locks available.

    +
  • +
  • +

    nomem

    +

    Not enough space.

    +
  • +
  • +

    nospc

    +

    No space left on device.

    +
  • +
  • +

    nosys

    +

    Function not supported.

    +
  • +
  • +

    notdir

    +

    Not a directory or a symbolic link to a directory.

    +
  • +
  • +

    notempty

    +

    Directory not empty.

    +
  • +
  • +

    notrecoverable

    +

    State not recoverable.

    +
  • +
  • +

    notsup

    +

    Not supported, or operation not supported on socket.

    +
  • +
  • +

    notty

    +

    Inappropriate I/O control operation.

    +
  • +
  • +

    nxio

    +

    No such device or address.

    +
  • +
  • +

    overflow

    +

    Value too large to be stored in data type.

    +
  • +
  • +

    perm

    +

    Operation not permitted.

    +
  • +
  • +

    pipe

    +

    Broken pipe.

    +
  • +
  • +

    rofs

    +

    Read-only file system.

    +
  • +
  • +

    spipe

    +

    Invalid seek.

    +
  • +
  • +

    txtbsy

    +

    Text file busy.

    +
  • +
  • +

    xdev

    +

    Cross-device link.

    +
  • +
+

dir-entry-stream: u32

+

A stream of directory entries.

+

Size: 4, Alignment: 4

+

device: u64

+

Identifier for a device containing a file system. Can be used in combination +with inode to uniquely identify a file or directory in the filesystem.

+

Size: 8, Alignment: 8

+

descriptor-type: enum

+

The type of a filesystem object referenced by a descriptor.

+

Note: This was called filetype in earlier versions of WASI.

+

Size: 1, Alignment: 1

+

Enum Cases

+
    +
  • +

    unknown

    +

    The type of the descriptor or file is unknown or is different from +any of the other types specified.

    +
  • +
  • +

    block-device

    +

    The descriptor refers to a block device inode.

    +
  • +
  • +

    character-device

    +

    The descriptor refers to a character device inode.

    +
  • +
  • +

    directory

    +

    The descriptor refers to a directory inode.

    +
  • +
  • +

    fifo

    +

    The descriptor refers to a named pipe.

    +
  • +
  • +

    symbolic-link

    +

    The file refers to a symbolic link inode.

    +
  • +
  • +

    regular-file

    +

    The descriptor refers to a regular file inode.

    +
  • +
  • +

    socket

    +

    The descriptor refers to a socket.

    +
  • +
+

dir-entry: record

+

A directory entry.

+

Size: 32, Alignment: 8

+

Record Fields

+
    +
  • +

    ino: option<inode>

    +

    The serial number of the object referred to by this directory entry. +May be none if the inode value is not known.

    +

    When this is none, libc implementations might do an extra stat-at +call to retrieve the inode number to fill their d_ino fields, so +implementations which can set this to a non-none value should do so.

    +
  • +
  • +

    type: descriptor-type

    +

    The type of the file referred to by this directory entry.

    +
  • +
  • +

    name: string

    +

    The name of the object.

    +
  • +
+

descriptor-stat: record

+

File attributes.

+

Note: This was called filestat in earlier versions of WASI.

+

Size: 64, Alignment: 8

+

Record Fields

+
    +
  • +

    dev: device

    +

    Device ID of device containing the file.

    +
  • +
  • +

    ino: inode

    +

    File serial number.

    +
  • +
  • +

    type: descriptor-type

    +

    File type.

    +
  • +
  • +

    nlink: linkcount

    +

    Number of hard links to the file.

    +
  • +
  • +

    size: filesize

    +

    For regular files, the file size in bytes. For symbolic links, the length +in bytes of the pathname contained in the symbolic link.

    +
  • +
  • +

    atim: u64

    +

    Last data access timestamp.

    +
  • +
  • +

    mtim: u64

    +

    Last data modification timestamp.

    +
  • +
  • +

    ctim: u64

    +

    Last file status change timestamp.

    +
  • +
+

descriptor-flags: record

+

Descriptor flags.

+

Note: This was called fdflags in earlier versions of WASI.

+

Size: 1, Alignment: 1

+

Record Fields

+
    +
  • +

    read:

    +

    Read mode: Data can be read. +Bit: 0

    +
  • +
  • +

    write:

    +

    Write mode: Data can be written to. +Bit: 1

    +
  • +
  • +

    dsync:

    +

    Write according to synchronized I/O data integrity completion. Only the +data stored in the file is synchronized. +Bit: 2

    +
  • +
  • +

    nonblock:

    +

    Non-blocking mode. +Bit: 3

    +
  • +
  • +

    rsync:

    +

    Synchronized read I/O operations. +Bit: 4

    +
  • +
  • +

    sync:

    +

    Write according to synchronized I/O file integrity completion. In +addition to synchronizing the data stored in the file, the +implementation may also synchronously update the file's metadata. +Bit: 5

    +
  • +
+

descriptor: u32

+

A descriptor is a reference to a filesystem object, which may be a file, +directory, named pipe, special file, or other object on which filesystem +calls may be made.

+

Size: 4, Alignment: 4

+

at-flags: record

+

Flags determining the method of how paths are resolved.

+

Size: 1, Alignment: 1

+

Record Fields

+
    +
  • +

    symlink-follow:

    +

    As long as the resolved path corresponds to a symbolic link, it is expanded. +Bit: 0

    +
  • +
+

advice: enum

+

File or memory access pattern advisory information.

+

Size: 1, Alignment: 1

+

Enum Cases

+
    +
  • +

    normal

    +

    The application has no advice to give on its behavior with respect to the specified data.

    +
  • +
  • +

    sequential

    +

    The application expects to access the specified data sequentially from lower offsets to higher offsets.

    +
  • +
  • +

    random

    +

    The application expects to access the specified data in a random order.

    +
  • +
  • +

    will-need

    +

    The application expects to access the specified data in the near future.

    +
  • +
  • +

    dont-need

    +

    The application expects that it will not access the specified data in the near future.

    +
  • +
  • +

    no-reuse

    +

    The application expects to access the specified data once and then not reuse it thereafter.

    +
  • +
+

Functions

+
+

fadvise

+

Provide file advisory information on a descriptor.

+

This is similar to posix_fadvise in POSIX.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

datasync

+

Synchronize the data of a file to disk.

+

Note: This is similar to fdatasync in POSIX.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

flags

+

Get flags associated with a descriptor.

+

Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

+

Note: This returns the value that was the fs_flags value returned +from fdstat_get in earlier versions of WASI.

+
Params
+ +
Results
+ +
+

type

+

Get the dynamic type of a descriptor.

+

Note: This returns the same value as the type field of the fd-stat +returned by stat, stat-at and similar.

+

Note: This returns similar flags to the st_mode & S_IFMT value provided +by fstat in POSIX.

+

Note: This returns the value that was the fs_filetype value returned +from fdstat_get in earlier versions of WASI.

+
Params
+ +
Results
+ +
+

set-flags

+

Set flags associated with a descriptor.

+

Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

+

Note: This was called fd_fdstat_set_flags in earlier versions of WASI.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

set-size

+

Adjust the size of an open file. If this increases the file's size, the +extra bytes are filled with zeros.

+

Note: This was called fd_filestat_set_size in earlier versions of WASI.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

set-times

+

Adjust the timestamps of an open file or directory.

+

Note: This is similar to futimens in POSIX.

+

Note: This was called fd_filestat_set_times in earlier versions of WASI.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

pread

+

Read from a descriptor, without using and updating the descriptor's offset.

+

Note: This is similar to pread in POSIX.

+
Params
+ +
Results
+
    +
  • result0: result<list<u8>, errno>
  • +
+
+

pwrite

+

Write to a descriptor, without using and updating the descriptor's offset.

+

It is valid to write past the end of a file; the file is extended to the +extent of the write, with bytes between the previous end and the start of +the write set to zero.

+

Note: This is similar to pwrite in POSIX.

+
Params
+ +
Results
+ +
+

readdir

+

Read directory entries from a directory.

+

This always returns a new stream which starts at the beginning of the +directory.

+
Params
+ +
Results
+ +
+

sync

+

Synchronize the data and metadata of a file to disk.

+

Note: This is similar to fsync in POSIX.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

create-directory-at

+

Create a directory.

+

Note: This is similar to mkdirat in POSIX.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

stat

+

Return the attributes of an open file or directory.

+

Note: This is similar to fstat in POSIX.

+

Note: This was called fd_filestat_get in earlier versions of WASI.

+
Params
+ +
Results
+ +
+

stat-at

+

Return the attributes of a file or directory.

+

Note: This is similar to fstatat in POSIX.

+

Note: This was called path_filestat_get in earlier versions of WASI.

+
Params
+ +
Results
+ +
+

set-times-at

+

Adjust the timestamps of a file or directory.

+

Note: This is similar to utimensat in POSIX.

+

Note: This was called path_filestat_set_times in earlier versions of WASI.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

link-at

+

Create a hard link.

+

Note: This is similar to linkat in POSIX.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

open-at

+

Open a file or directory.

+

The returned descriptor is not guaranteed to be the lowest-numbered +descriptor not currently open/ it is randomized to prevent applications +from depending on making assumptions about indexes, since this is +error-prone in multi-threaded contexts. The returned descriptor is +guaranteed to be less than 2**31.

+

Note: This is similar to openat in POSIX.

+
Params
+ +
Results
+ +
+

readlink-at

+

Read the contents of a symbolic link.

+

Note: This is similar to readlinkat in POSIX.

+
Params
+ +
Results
+
    +
  • result0: result<string, errno>
  • +
+
+

remove-directory-at

+

Remove a directory.

+

Return errno::notempty if the directory is not empty.

+

Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

rename-at

+

Rename a filesystem object.

+

Note: This is similar to renameat in POSIX.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

symlink-at

+

Create a symbolic link.

+

Note: This is similar to symlinkat in POSIX.

+
Params
+
    +
  • this: descriptor
  • +
  • old-path: string
  • +
  • new-path: string
  • +
+
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

unlink-file-at

+

Unlink a filesystem object that is not a directory.

+

Return errno::isdir if the path refers to a directory. +Note: This is similar to unlinkat(fd, path, 0) in POSIX.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

change-file-permissions-at

+

Change the permissions of a filesystem object that is not a directory.

+

Note that the ultimate meanings of these permissions is +filesystem-specific.

+

Note: This is similar to fchmodat in POSIX.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

change-directory-permissions-at

+

Change the permissions of a directory.

+

Note that the ultimate meanings of these permissions is +filesystem-specific.

+

Unlike in POSIX, the executable flag is not reinterpreted as a "search" +flag. read on a directory implies readability and searchability, and +execute is not valid for directories.

+

Note: This is similar to fchmodat in POSIX.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

lock-shared

+

Request a shared advisory lock for an open file.

+

This requests a shared lock; more than one shared lock can be held for +a file at the same time.

+

If the open file has an exclusive lock, this function downgrades the lock +to a shared lock. If it has a shared lock, this function has no effect.

+

This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

+

It is unspecified how shared locks interact with locks acquired by +non-WASI programs.

+

This function blocks until the lock can be acquired.

+

Not all filesystems support locking; on filesystems which don't support +locking, this function returns errno::notsup.

+

Note: This is similar to flock(fd, LOCK_SH) in Unix.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

lock-exclusive

+

Request an exclusive advisory lock for an open file.

+

This requests an exclusive lock; no other locks may be held for the +file while an exclusive lock is held.

+

If the open file has a shared lock and there are no exclusive locks held +for the file, this function upgrades the lock to an exclusive lock. If the +open file already has an exclusive lock, this function has no effect.

+

This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

+

It is unspecified whether this function succeeds if the file descriptor +is not opened for writing. It is unspecified how exclusive locks interact +with locks acquired by non-WASI programs.

+

This function blocks until the lock can be acquired.

+

Not all filesystems support locking; on filesystems which don't support +locking, this function returns errno::notsup.

+

Note: This is similar to flock(fd, LOCK_EX) in Unix.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

try-lock-shared

+

Request a shared advisory lock for an open file.

+

This requests a shared lock; more than one shared lock can be held for +a file at the same time.

+

If the open file has an exclusive lock, this function downgrades the lock +to a shared lock. If it has a shared lock, this function has no effect.

+

This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

+

It is unspecified how shared locks interact with locks acquired by +non-WASI programs.

+

This function returns errno::wouldblock if the lock cannot be acquired.

+

Not all filesystems support locking; on filesystems which don't support +locking, this function returns errno::notsup.

+

Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

try-lock-exclusive

+

Request an exclusive advisory lock for an open file.

+

This requests an exclusive lock; no other locks may be held for the +file while an exclusive lock is held.

+

If the open file has a shared lock and there are no exclusive locks held +for the file, this function upgrades the lock to an exclusive lock. If the +open file already has an exclusive lock, this function has no effect.

+

This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

+

It is unspecified whether this function succeeds if the file descriptor +is not opened for writing. It is unspecified how exclusive locks interact +with locks acquired by non-WASI programs.

+

This function returns errno::wouldblock if the lock cannot be acquired.

+

Not all filesystems support locking; on filesystems which don't support +locking, this function returns errno::notsup.

+

Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

unlock

+

Release a shared or exclusive lock on an open file.

+

Note: This is similar to flock(fd, LOCK_UN) in Unix.

+
Params
+ +
Results
+
    +
  • result0: result<_, errno>
  • +
+
+

drop-descriptor

+

Dispose of the specified descriptor, after which it may no longer +be used.

+
Params
+ +
+

read-dir-entry

+

Read a single directory entry from a dir-entry-stream.

+
Params
+ +
Results
+ +
+

drop-dir-entry-stream

+

Dispose of the specified dir-entry-stream, after which it may no longer +be used.

+
Params
+ diff --git a/proposals/filesystem/wasi-filesystem.md b/proposals/filesystem/wasi-filesystem.md new file mode 100644 index 000000000..0363d70dd --- /dev/null +++ b/proposals/filesystem/wasi-filesystem.md @@ -0,0 +1,1079 @@ +# Import interface `wasi-filesystem` + +## Types + +## `o-flags`: record + +Open flags used by `open-at`. + +Size: 1, Alignment: 1 + +### Record Fields + +- [`create`](#o_flags.create): + + Create file if it does not exist. + Bit: 0 + +- [`directory`](#o_flags.directory): + + Fail if not a directory. + Bit: 1 + +- [`excl`](#o_flags.excl): + + Fail if file already exists. + Bit: 2 + +- [`trunc`](#o_flags.trunc): + + Truncate file to size 0. + Bit: 3 + +## `new-timestamp`: variant + +When setting a timestamp, this gives the value to set it to. + +Size: 16, Alignment: 8 + +### Variant Cases + +- [`no-change`](#new_timestamp.no_change) + + Leave the timestamp set to its previous value. + +- [`now`](#new_timestamp.now) + + Set the timestamp to the current time of the system clock associated + with the filesystem. + +- [`timestamp`](#new_timestamp.timestamp): `u64` + + Set the timestamp to the given value. + +## `mode`: record + +Permissions mode used by `open-at`, `change-file-permissions-at`, and +similar. + +Size: 1, Alignment: 1 + +### Record Fields + +- [`readable`](#mode.readable): + + True if the resource is considered readable by the containing + filesystem. + Bit: 0 + +- [`writeable`](#mode.writeable): + + True if the resource is considered writeable by the containing + filesystem. + Bit: 1 + +- [`executable`](#mode.executable): + + True if the resource is considered executable by the containing + filesystem. This does not apply to directories. + Bit: 2 + +## `linkcount`: `u64` + +Number of hard links to an inode. + +Size: 8, Alignment: 8 + +## `inode`: `u64` + +Filesystem object serial number that is unique within its file system. + +Size: 8, Alignment: 8 + +## `filesize`: `u64` + +File size or length of a region within a file. + +Size: 8, Alignment: 8 + +## `errno`: enum + +Error codes returned by functions. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX. + +Size: 1, Alignment: 1 + +### Enum Cases + +- [`access`](#errno.access) + + Permission denied. + +- [`again`](#errno.again) + + Resource unavailable, or operation would block. + +- [`already`](#errno.already) + + Connection already in progress. + +- [`badf`](#errno.badf) + + Bad descriptor. + +- [`busy`](#errno.busy) + + Device or resource busy. + +- [`deadlk`](#errno.deadlk) + + Resource deadlock would occur. + +- [`dquot`](#errno.dquot) + + Storage quota exceeded. + +- [`exist`](#errno.exist) + + File exists. + +- [`fbig`](#errno.fbig) + + File too large. + +- [`ilseq`](#errno.ilseq) + + Illegal byte sequence. + +- [`inprogress`](#errno.inprogress) + + Operation in progress. + +- [`intr`](#errno.intr) + + Interrupted function. + +- [`inval`](#errno.inval) + + Invalid argument. + +- [`io`](#errno.io) + + I/O error. + +- [`isdir`](#errno.isdir) + + Is a directory. + +- [`loop`](#errno.loop) + + Too many levels of symbolic links. + +- [`mlink`](#errno.mlink) + + Too many links. + +- [`msgsize`](#errno.msgsize) + + Message too large. + +- [`nametoolong`](#errno.nametoolong) + + Filename too long. + +- [`nodev`](#errno.nodev) + + No such device. + +- [`noent`](#errno.noent) + + No such file or directory. + +- [`nolck`](#errno.nolck) + + No locks available. + +- [`nomem`](#errno.nomem) + + Not enough space. + +- [`nospc`](#errno.nospc) + + No space left on device. + +- [`nosys`](#errno.nosys) + + Function not supported. + +- [`notdir`](#errno.notdir) + + Not a directory or a symbolic link to a directory. + +- [`notempty`](#errno.notempty) + + Directory not empty. + +- [`notrecoverable`](#errno.notrecoverable) + + State not recoverable. + +- [`notsup`](#errno.notsup) + + Not supported, or operation not supported on socket. + +- [`notty`](#errno.notty) + + Inappropriate I/O control operation. + +- [`nxio`](#errno.nxio) + + No such device or address. + +- [`overflow`](#errno.overflow) + + Value too large to be stored in data type. + +- [`perm`](#errno.perm) + + Operation not permitted. + +- [`pipe`](#errno.pipe) + + Broken pipe. + +- [`rofs`](#errno.rofs) + + Read-only file system. + +- [`spipe`](#errno.spipe) + + Invalid seek. + +- [`txtbsy`](#errno.txtbsy) + + Text file busy. + +- [`xdev`](#errno.xdev) + + Cross-device link. + +## `dir-entry-stream`: `u32` + +A stream of directory entries. + +Size: 4, Alignment: 4 + +## `device`: `u64` + +Identifier for a device containing a file system. Can be used in combination +with `inode` to uniquely identify a file or directory in the filesystem. + +Size: 8, Alignment: 8 + +## `descriptor-type`: enum + +The type of a filesystem object referenced by a descriptor. + +Note: This was called `filetype` in earlier versions of WASI. + +Size: 1, Alignment: 1 + +### Enum Cases + +- [`unknown`](#descriptor_type.unknown) + + The type of the descriptor or file is unknown or is different from + any of the other types specified. + +- [`block-device`](#descriptor_type.block_device) + + The descriptor refers to a block device inode. + +- [`character-device`](#descriptor_type.character_device) + + The descriptor refers to a character device inode. + +- [`directory`](#descriptor_type.directory) + + The descriptor refers to a directory inode. + +- [`fifo`](#descriptor_type.fifo) + + The descriptor refers to a named pipe. + +- [`symbolic-link`](#descriptor_type.symbolic_link) + + The file refers to a symbolic link inode. + +- [`regular-file`](#descriptor_type.regular_file) + + The descriptor refers to a regular file inode. + +- [`socket`](#descriptor_type.socket) + + The descriptor refers to a socket. + +## `dir-entry`: record + +A directory entry. + +Size: 32, Alignment: 8 + +### Record Fields + +- [`ino`](#dir_entry.ino): option<[`inode`](#inode)> + + The serial number of the object referred to by this directory entry. + May be none if the inode value is not known. + + When this is none, libc implementations might do an extra `stat-at` + call to retrieve the inode number to fill their `d_ino` fields, so + implementations which can set this to a non-none value should do so. + +- [`type`](#dir_entry.type): [`descriptor-type`](#descriptor_type) + + The type of the file referred to by this directory entry. + +- [`name`](#dir_entry.name): `string` + + The name of the object. + +## `descriptor-stat`: record + +File attributes. + +Note: This was called `filestat` in earlier versions of WASI. + +Size: 64, Alignment: 8 + +### Record Fields + +- [`dev`](#descriptor_stat.dev): [`device`](#device) + + Device ID of device containing the file. + +- [`ino`](#descriptor_stat.ino): [`inode`](#inode) + + File serial number. + +- [`type`](#descriptor_stat.type): [`descriptor-type`](#descriptor_type) + + File type. + +- [`nlink`](#descriptor_stat.nlink): [`linkcount`](#linkcount) + + Number of hard links to the file. + +- [`size`](#descriptor_stat.size): [`filesize`](#filesize) + + For regular files, the file size in bytes. For symbolic links, the length + in bytes of the pathname contained in the symbolic link. + +- [`atim`](#descriptor_stat.atim): `u64` + + Last data access timestamp. + +- [`mtim`](#descriptor_stat.mtim): `u64` + + Last data modification timestamp. + +- [`ctim`](#descriptor_stat.ctim): `u64` + + Last file status change timestamp. + +## `descriptor-flags`: record + +Descriptor flags. + +Note: This was called `fdflags` in earlier versions of WASI. + +Size: 1, Alignment: 1 + +### Record Fields + +- [`read`](#descriptor_flags.read): + + Read mode: Data can be read. + Bit: 0 + +- [`write`](#descriptor_flags.write): + + Write mode: Data can be written to. + Bit: 1 + +- [`dsync`](#descriptor_flags.dsync): + + Write according to synchronized I/O data integrity completion. Only the + data stored in the file is synchronized. + Bit: 2 + +- [`nonblock`](#descriptor_flags.nonblock): + + Non-blocking mode. + Bit: 3 + +- [`rsync`](#descriptor_flags.rsync): + + Synchronized read I/O operations. + Bit: 4 + +- [`sync`](#descriptor_flags.sync): + + Write according to synchronized I/O file integrity completion. In + addition to synchronizing the data stored in the file, the + implementation may also synchronously update the file's metadata. + Bit: 5 + +## `descriptor`: `u32` + +A descriptor is a reference to a filesystem object, which may be a file, +directory, named pipe, special file, or other object on which filesystem +calls may be made. + +Size: 4, Alignment: 4 + +## `at-flags`: record + +Flags determining the method of how paths are resolved. + +Size: 1, Alignment: 1 + +### Record Fields + +- [`symlink-follow`](#at_flags.symlink_follow): + + As long as the resolved path corresponds to a symbolic link, it is expanded. + Bit: 0 + +## `advice`: enum + +File or memory access pattern advisory information. + +Size: 1, Alignment: 1 + +### Enum Cases + +- [`normal`](#advice.normal) + + The application has no advice to give on its behavior with respect to the specified data. + +- [`sequential`](#advice.sequential) + + The application expects to access the specified data sequentially from lower offsets to higher offsets. + +- [`random`](#advice.random) + + The application expects to access the specified data in a random order. + +- [`will-need`](#advice.will_need) + + The application expects to access the specified data in the near future. + +- [`dont-need`](#advice.dont_need) + + The application expects that it will not access the specified data in the near future. + +- [`no-reuse`](#advice.no_reuse) + + The application expects to access the specified data once and then not reuse it thereafter. + +## Functions + +---- + +#### `fadvise` + +Provide file advisory information on a descriptor. + +This is similar to `posix_fadvise` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `offset`: [`filesize`](#filesize) +- `len`: [`filesize`](#filesize) +- `advice`: [`advice`](#advice) +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `datasync` + +Synchronize the data of a file to disk. + +Note: This is similar to `fdatasync` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `flags` + +Get flags associated with a descriptor. + +Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. + +Note: This returns the value that was the `fs_flags` value returned +from `fdstat_get` in earlier versions of WASI. +##### Params + +- `this`: [`descriptor`](#descriptor) +##### Results + +- `result0`: result<[`descriptor-flags`](#descriptor_flags), [`errno`](#errno)> + +---- + +#### `type` + +Get the dynamic type of a descriptor. + +Note: This returns the same value as the `type` field of the `fd-stat` +returned by `stat`, `stat-at` and similar. + +Note: This returns similar flags to the `st_mode & S_IFMT` value provided +by `fstat` in POSIX. + +Note: This returns the value that was the `fs_filetype` value returned +from `fdstat_get` in earlier versions of WASI. +##### Params + +- `this`: [`descriptor`](#descriptor) +##### Results + +- `result0`: result<[`descriptor-type`](#descriptor_type), [`errno`](#errno)> + +---- + +#### `set-flags` + +Set flags associated with a descriptor. + +Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + +Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `flags`: [`descriptor-flags`](#descriptor_flags) +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `set-size` + +Adjust the size of an open file. If this increases the file's size, the +extra bytes are filled with zeros. + +Note: This was called `fd_filestat_set_size` in earlier versions of WASI. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `size`: [`filesize`](#filesize) +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `set-times` + +Adjust the timestamps of an open file or directory. + +Note: This is similar to `futimens` in POSIX. + +Note: This was called `fd_filestat_set_times` in earlier versions of WASI. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `atim`: [`new-timestamp`](#new_timestamp) +- `mtim`: [`new-timestamp`](#new_timestamp) +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `pread` + +Read from a descriptor, without using and updating the descriptor's offset. + +Note: This is similar to `pread` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `len`: [`filesize`](#filesize) +- `offset`: [`filesize`](#filesize) +##### Results + +- `result0`: result, [`errno`](#errno)> + +---- + +#### `pwrite` + +Write to a descriptor, without using and updating the descriptor's offset. + +It is valid to write past the end of a file; the file is extended to the +extent of the write, with bytes between the previous end and the start of +the write set to zero. + +Note: This is similar to `pwrite` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `buf`: list<`u8`> +- `offset`: [`filesize`](#filesize) +##### Results + +- `result0`: result<[`filesize`](#filesize), [`errno`](#errno)> + +---- + +#### `readdir` + +Read directory entries from a directory. + +This always returns a new stream which starts at the beginning of the +directory. +##### Params + +- `this`: [`descriptor`](#descriptor) +##### Results + +- `result0`: stream<[`dir-entry-stream`](#dir_entry_stream), [`errno`](#errno)> + +---- + +#### `sync` + +Synchronize the data and metadata of a file to disk. + +Note: This is similar to `fsync` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `create-directory-at` + +Create a directory. + +Note: This is similar to `mkdirat` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `path`: `string` +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `stat` + +Return the attributes of an open file or directory. + +Note: This is similar to `fstat` in POSIX. + +Note: This was called `fd_filestat_get` in earlier versions of WASI. +##### Params + +- `this`: [`descriptor`](#descriptor) +##### Results + +- `result0`: result<[`descriptor-stat`](#descriptor_stat), [`errno`](#errno)> + +---- + +#### `stat-at` + +Return the attributes of a file or directory. + +Note: This is similar to `fstatat` in POSIX. + +Note: This was called `path_filestat_get` in earlier versions of WASI. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `at-flags`: [`at-flags`](#at_flags) +- `path`: `string` +##### Results + +- `result0`: result<[`descriptor-stat`](#descriptor_stat), [`errno`](#errno)> + +---- + +#### `set-times-at` + +Adjust the timestamps of a file or directory. + +Note: This is similar to `utimensat` in POSIX. + +Note: This was called `path_filestat_set_times` in earlier versions of WASI. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `at-flags`: [`at-flags`](#at_flags) +- `path`: `string` +- `atim`: [`new-timestamp`](#new_timestamp) +- `mtim`: [`new-timestamp`](#new_timestamp) +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `link-at` + +Create a hard link. + +Note: This is similar to `linkat` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `old-at-flags`: [`at-flags`](#at_flags) +- `old-path`: `string` +- `new-descriptor`: [`descriptor`](#descriptor) +- `new-path`: `string` +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `open-at` + +Open a file or directory. + +The returned descriptor is not guaranteed to be the lowest-numbered +descriptor not currently open/ it is randomized to prevent applications +from depending on making assumptions about indexes, since this is +error-prone in multi-threaded contexts. The returned descriptor is +guaranteed to be less than 2**31. + +Note: This is similar to `openat` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `at-flags`: [`at-flags`](#at_flags) +- `path`: `string` +- `o-flags`: [`o-flags`](#o_flags) +- `flags`: [`descriptor-flags`](#descriptor_flags) +- `mode`: [`mode`](#mode) +##### Results + +- `result0`: result<[`descriptor`](#descriptor), [`errno`](#errno)> + +---- + +#### `readlink-at` + +Read the contents of a symbolic link. + +Note: This is similar to `readlinkat` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `path`: `string` +##### Results + +- `result0`: result<`string`, [`errno`](#errno)> + +---- + +#### `remove-directory-at` + +Remove a directory. + +Return `errno::notempty` if the directory is not empty. + +Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `path`: `string` +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `rename-at` + +Rename a filesystem object. + +Note: This is similar to `renameat` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `old-path`: `string` +- `new-descriptor`: [`descriptor`](#descriptor) +- `new-path`: `string` +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `symlink-at` + +Create a symbolic link. + +Note: This is similar to `symlinkat` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `old-path`: `string` +- `new-path`: `string` +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `unlink-file-at` + +Unlink a filesystem object that is not a directory. + +Return `errno::isdir` if the path refers to a directory. +Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `path`: `string` +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `change-file-permissions-at` + +Change the permissions of a filesystem object that is not a directory. + +Note that the ultimate meanings of these permissions is +filesystem-specific. + +Note: This is similar to `fchmodat` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `at-flags`: [`at-flags`](#at_flags) +- `path`: `string` +- `mode`: [`mode`](#mode) +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `change-directory-permissions-at` + +Change the permissions of a directory. + +Note that the ultimate meanings of these permissions is +filesystem-specific. + +Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" +flag. `read` on a directory implies readability and searchability, and +`execute` is not valid for directories. + +Note: This is similar to `fchmodat` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `at-flags`: [`at-flags`](#at_flags) +- `path`: `string` +- `mode`: [`mode`](#mode) +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `lock-shared` + +Request a shared advisory lock for an open file. + +This requests a *shared* lock; more than one shared lock can be held for +a file at the same time. + +If the open file has an exclusive lock, this function downgrades the lock +to a shared lock. If it has a shared lock, this function has no effect. + +This requests an *advisory* lock, meaning that the file could be accessed +by other programs that don't hold the lock. + +It is unspecified how shared locks interact with locks acquired by +non-WASI programs. + +This function blocks until the lock can be acquired. + +Not all filesystems support locking; on filesystems which don't support +locking, this function returns `errno::notsup`. + +Note: This is similar to `flock(fd, LOCK_SH)` in Unix. +##### Params + +- `this`: [`descriptor`](#descriptor) +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `lock-exclusive` + +Request an exclusive advisory lock for an open file. + +This requests an *exclusive* lock; no other locks may be held for the +file while an exclusive lock is held. + +If the open file has a shared lock and there are no exclusive locks held +for the file, this function upgrades the lock to an exclusive lock. If the +open file already has an exclusive lock, this function has no effect. + +This requests an *advisory* lock, meaning that the file could be accessed +by other programs that don't hold the lock. + +It is unspecified whether this function succeeds if the file descriptor +is not opened for writing. It is unspecified how exclusive locks interact +with locks acquired by non-WASI programs. + +This function blocks until the lock can be acquired. + +Not all filesystems support locking; on filesystems which don't support +locking, this function returns `errno::notsup`. + +Note: This is similar to `flock(fd, LOCK_EX)` in Unix. +##### Params + +- `this`: [`descriptor`](#descriptor) +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `try-lock-shared` + +Request a shared advisory lock for an open file. + +This requests a *shared* lock; more than one shared lock can be held for +a file at the same time. + +If the open file has an exclusive lock, this function downgrades the lock +to a shared lock. If it has a shared lock, this function has no effect. + +This requests an *advisory* lock, meaning that the file could be accessed +by other programs that don't hold the lock. + +It is unspecified how shared locks interact with locks acquired by +non-WASI programs. + +This function returns `errno::wouldblock` if the lock cannot be acquired. + +Not all filesystems support locking; on filesystems which don't support +locking, this function returns `errno::notsup`. + +Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. +##### Params + +- `this`: [`descriptor`](#descriptor) +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `try-lock-exclusive` + +Request an exclusive advisory lock for an open file. + +This requests an *exclusive* lock; no other locks may be held for the +file while an exclusive lock is held. + +If the open file has a shared lock and there are no exclusive locks held +for the file, this function upgrades the lock to an exclusive lock. If the +open file already has an exclusive lock, this function has no effect. + +This requests an *advisory* lock, meaning that the file could be accessed +by other programs that don't hold the lock. + +It is unspecified whether this function succeeds if the file descriptor +is not opened for writing. It is unspecified how exclusive locks interact +with locks acquired by non-WASI programs. + +This function returns `errno::wouldblock` if the lock cannot be acquired. + +Not all filesystems support locking; on filesystems which don't support +locking, this function returns `errno::notsup`. + +Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. +##### Params + +- `this`: [`descriptor`](#descriptor) +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `unlock` + +Release a shared or exclusive lock on an open file. + +Note: This is similar to `flock(fd, LOCK_UN)` in Unix. +##### Params + +- `this`: [`descriptor`](#descriptor) +##### Results + +- `result0`: result<_, [`errno`](#errno)> + +---- + +#### `drop-descriptor` + +Dispose of the specified `descriptor`, after which it may no longer +be used. +##### Params + +- `this`: [`descriptor`](#descriptor) + +---- + +#### `read-dir-entry` + +Read a single directory entry from a `dir-entry-stream`. +##### Params + +- `this`: [`dir-entry-stream`](#dir_entry_stream) +##### Results + +- `result0`: result, [`errno`](#errno)> + +---- + +#### `drop-dir-entry-stream` + +Dispose of the specified `dir-entry-stream`, after which it may no longer +be used. +##### Params + +- `this`: [`dir-entry-stream`](#dir_entry_stream) + diff --git a/proposals/filesystem/wasi-filesystem.wit.md b/proposals/filesystem/wit/wasi-filesystem.wit.md similarity index 86% rename from proposals/filesystem/wasi-filesystem.wit.md rename to proposals/filesystem/wit/wasi-filesystem.wit.md index ca6225781..07420678a 100644 --- a/proposals/filesystem/wasi-filesystem.wit.md +++ b/proposals/filesystem/wit/wasi-filesystem.wit.md @@ -1,35 +1,24 @@ # WASI Filesystem API -WASI filesystem is a filesystem API primarily intended to let users run WASI -programs that access their files on their existing filesystems, without -significant overhead. - -It is intended to be roughly portable between Unix-family platforms and -Windows, though it does not hide many of the major differences. - -Paths are passed as interface-type `string`s, meaning they must consist of -a sequence of Unicode Scalar Values (USVs). Some filesystems may contain paths -which are not accessible by this API. - -## `filesize` -```wit -/// Non-negative file size or length of a region within a file. -type filesize = u64 -``` - -## `filedelta` +## `wasi-filesystem` ```wit -/// Relative offset within a file. -type filedelta = s64 +/// WASI filesystem is a filesystem API primarily intended to let users run WASI +/// programs that access their files on their existing filesystems, without +/// significant overhead. +/// +/// It is intended to be roughly portable between Unix-family platforms and +/// Windows, though it does not hide many of the major differences. +/// +/// Paths are passed as interface-type `string`s, meaning they must consist of +/// a sequence of Unicode Scalar Values (USVs). Some filesystems may contain paths +/// which are not accessible by this API. +default interface wasi-filesystem { ``` -## `datetime` +## `filesize` ```wit -/// Timestamp in seconds and nanoseconds. -record datetime { - seconds: u64, - nanoseconds: u32, -} +/// File size or length of a region within a file. +type filesize = u64 ``` ## `descriptor-type` @@ -68,9 +57,6 @@ flags descriptor-flags { read, /// Write mode: Data can be written to. write, - /// Append mode: Data written to the file is always appended to the file's - /// end. - append, /// Write according to synchronized I/O data integrity completion. Only the /// data stored in the file is synchronized. dsync, @@ -103,11 +89,11 @@ record descriptor-stat { /// in bytes of the pathname contained in the symbolic link. size: filesize, /// Last data access timestamp. - atim: datetime, + atim: u64, /// Last data modification timestamp. - mtim: datetime, + mtim: u64, /// Last file status change timestamp. - ctim: datetime, + ctim: u64, } ``` @@ -181,7 +167,7 @@ variant new-timestamp { /// with the filesystem. now, /// Set the timestamp to the given value. - timestamp(datetime), + timestamp(u64), } ``` @@ -222,8 +208,6 @@ enum errno { badf, /// Device or resource busy. busy, - /// No child processes. - child, /// Resource deadlock would occur. deadlk, /// Storage quota exceeded. @@ -312,25 +296,13 @@ enum advice { } ``` -## `seek-from` -```wit -/// The position relative to which to set the offset of the descriptor. -variant seek-from { - /// Seek relative to start-of-file. - set(filesize), - /// Seek relative to current position. - cur(filedelta), - /// Seek relative to end-of-file. - end(filesize), -} -``` - ## `descriptor` ```wit /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. -resource descriptor { +// TODO(resource descriptor {) +type descriptor = u32 ``` ## `fadvise` @@ -339,6 +311,7 @@ resource descriptor { /// /// This is similar to `posix_fadvise` in POSIX. fadvise: func( + this: descriptor, /// The offset within the file to which the advisory applies. offset: filesize, /// The length of the region to which the advisory applies. @@ -353,7 +326,7 @@ fadvise: func( /// Synchronize the data of a file to disk. /// /// Note: This is similar to `fdatasync` in POSIX. -datasync: func() -> result<_, errno> +datasync: func(this: descriptor) -> result<_, errno> ``` ## `flags` @@ -364,7 +337,7 @@ datasync: func() -> result<_, errno> /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. -%flags: func() -> result +%flags: func(this: descriptor) -> result ``` ## `type` @@ -379,7 +352,7 @@ datasync: func() -> result<_, errno> /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. -%type: func() -> result +%type: func(this: descriptor) -> result ``` ## `set-flags` @@ -389,7 +362,7 @@ datasync: func() -> result<_, errno> /// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. /// /// Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. -set-flags: func(%flags: descriptor-flags) -> result<_, errno> +set-flags: func(this: descriptor, %flags: descriptor-flags) -> result<_, errno> ``` ## `set-size` @@ -398,7 +371,7 @@ set-flags: func(%flags: descriptor-flags) -> result<_, errno> /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. -set-size: func(size: filesize) -> result<_, errno> +set-size: func(this: descriptor, size: filesize) -> result<_, errno> ``` ## `set-times` @@ -409,6 +382,7 @@ set-size: func(size: filesize) -> result<_, errno> /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. set-times: func( + this: descriptor, /// The desired values of the data access timestamp. atim: new-timestamp, /// The desired values of the data modification timestamp. @@ -421,12 +395,14 @@ set-times: func( /// Read from a descriptor, without using and updating the descriptor's offset. /// /// Note: This is similar to `pread` in POSIX. +// TODO(stream) pread: func( - /// The maximim number of bytes to read. + this: descriptor, + /// The maximum number of bytes to read. len: filesize, /// The offset within the file at which to read. offset: filesize, -) -> stream +) -> result, errno> ``` ## `pwrite` @@ -438,12 +414,14 @@ pread: func( /// the write set to zero. /// /// Note: This is similar to `pwrite` in POSIX. +// TODO(stream) pwrite: func( + this: descriptor, /// Data to write - buf: stream, + buf: list, /// The offset within the file at which to write. offset: filesize, -) -> future> +) -> result ``` ## `readdir` @@ -452,28 +430,7 @@ pwrite: func( /// /// This always returns a new stream which starts at the beginning of the /// directory. -readdir: func() -> stream -``` - -## `seek` -```wit -/// Move the offset of a file descriptor. -/// -/// If the descriptor refers to a directory, this function fails with -/// `errno::spipe`. -/// -/// Returns new offset of the descriptor, relative to the start of the file. -/// -/// It is valid to seek past the end of a file. The file size is not modified -/// until a write is performed, at which time the file is extended to the -/// extent of the write, with bytes between the previous end and the start of -/// the write set to zero. -/// -/// Note: This is similar to `lseek` in POSIX. -seek: func( - /// The method to compute the new offset. - %from: seek-from, -) -> result +readdir: func(this: descriptor) -> stream ``` ## `sync` @@ -481,20 +438,7 @@ seek: func( /// Synchronize the data and metadata of a file to disk. /// /// Note: This is similar to `fsync` in POSIX. -sync: func() -> result<_, errno> -``` - -## `tell` -```wit -/// Return the current offset of a descriptor. -/// -/// If the descriptor refers to a directory, this function fails with -/// `errno::spipe`. -/// -/// Returns the current offset of the descriptor, relative to the start of the file. -/// -/// Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX. -tell: func() -> result +sync: func(this: descriptor) -> result<_, errno> ``` ## `create-directory-at` @@ -503,6 +447,7 @@ tell: func() -> result /// /// Note: This is similar to `mkdirat` in POSIX. create-directory-at: func( + this: descriptor, /// The relative path at which to create the directory. path: string, ) -> result<_, errno> @@ -515,7 +460,7 @@ create-directory-at: func( /// Note: This is similar to `fstat` in POSIX. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. -stat: func() -> result +stat: func(this: descriptor) -> result ``` ## `stat-at` @@ -526,6 +471,7 @@ stat: func() -> result /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. stat-at: func( + this: descriptor, /// Flags determining the method of how the path is resolved. at-flags: at-flags, /// The relative path of the file or directory to inspect. @@ -541,6 +487,7 @@ stat-at: func( /// /// Note: This was called `path_filestat_set_times` in earlier versions of WASI. set-times-at: func( + this: descriptor, /// Flags determining the method of how the path is resolved. at-flags: at-flags, /// The relative path of the file or directory to operate on. @@ -558,12 +505,13 @@ set-times-at: func( /// /// Note: This is similar to `linkat` in POSIX. link-at: func( + this: descriptor, /// Flags determining the method of how the path is resolved. old-at-flags: at-flags, /// The relative source path from which to link. old-path: string, /// The base directory for `new-path`. - new-descriptor: handle descriptor, + new-descriptor: descriptor, /// The relative destination path at which to create the hard link. new-path: string, ) -> result<_, errno> @@ -581,6 +529,7 @@ link-at: func( /// /// Note: This is similar to `openat` in POSIX. open-at: func( + this: descriptor, /// Flags determining the method of how the path is resolved. at-flags: at-flags, /// The relative path of the object to open. @@ -600,6 +549,7 @@ open-at: func( /// /// Note: This is similar to `readlinkat` in POSIX. readlink-at: func( + this: descriptor, /// The relative path of the symbolic link from which to read. path: string, ) -> result @@ -613,6 +563,7 @@ readlink-at: func( /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. remove-directory-at: func( + this: descriptor, /// The relative path to a directory to remove. path: string, ) -> result<_, errno> @@ -624,10 +575,11 @@ remove-directory-at: func( /// /// Note: This is similar to `renameat` in POSIX. rename-at: func( + this: descriptor, /// The relative source path of the file or directory to rename. old-path: string, /// The base directory for `new-path`. - new-descriptor: handle descriptor, + new-descriptor: descriptor, /// The relative destination path to which to rename the file or directory. new-path: string, ) -> result<_, errno> @@ -639,6 +591,7 @@ rename-at: func( /// /// Note: This is similar to `symlinkat` in POSIX. symlink-at: func( + this: descriptor, /// The contents of the symbolic link. old-path: string, /// The relative destination path at which to create the symbolic link. @@ -653,6 +606,7 @@ symlink-at: func( /// Return `errno::isdir` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. unlink-file-at: func( + this: descriptor, /// The relative path to a file to unlink. path: string, ) -> result<_, errno> @@ -667,6 +621,7 @@ unlink-file-at: func( /// /// Note: This is similar to `fchmodat` in POSIX. change-file-permissions-at: func( + this: descriptor, /// Flags determining the method of how the path is resolved. at-flags: at-flags, /// The relative path to operate on. @@ -689,6 +644,7 @@ change-file-permissions-at: func( /// /// Note: This is similar to `fchmodat` in POSIX. change-directory-permissions-at: func( + this: descriptor, /// Flags determining the method of how the path is resolved. at-flags: at-flags, /// The relative path to operate on. @@ -720,7 +676,7 @@ change-directory-permissions-at: func( /// locking, this function returns `errno::notsup`. /// /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. -lock-shared: func() -> result<_, errno> +lock-shared: func(this: descriptor) -> result<_, errno> ``` ## `lock-exclusive` @@ -731,7 +687,7 @@ lock-shared: func() -> result<_, errno> /// file while an exclusive lock is held. /// /// If the open file has a shared lock and there are no exclusive locks held -/// for the fhile, this function upgrades the lock to an exclusive lock. If the +/// for the file, this function upgrades the lock to an exclusive lock. If the /// open file already has an exclusive lock, this function has no effect. /// /// This requests an *advisory* lock, meaning that the file could be accessed @@ -747,7 +703,7 @@ lock-shared: func() -> result<_, errno> /// locking, this function returns `errno::notsup`. /// /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. -lock-exclusive: func() -> result<_, errno> +lock-exclusive: func(this: descriptor) -> result<_, errno> ``` ## `try-lock-shared` @@ -772,7 +728,7 @@ lock-exclusive: func() -> result<_, errno> /// locking, this function returns `errno::notsup`. /// /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. -try-lock-shared: func() -> result<_, errno> +try-lock-shared: func(this: descriptor) -> result<_, errno> ``` ## `try-lock-exclusive` @@ -783,7 +739,7 @@ try-lock-shared: func() -> result<_, errno> /// file while an exclusive lock is held. /// /// If the open file has a shared lock and there are no exclusive locks held -/// for the fhile, this function upgrades the lock to an exclusive lock. If the +/// for the file, this function upgrades the lock to an exclusive lock. If the /// open file already has an exclusive lock, this function has no effect. /// /// This requests an *advisory* lock, meaning that the file could be accessed @@ -799,7 +755,7 @@ try-lock-shared: func() -> result<_, errno> /// locking, this function returns `errno::notsup`. /// /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. -try-lock-exclusive: func() -> result<_, errno> +try-lock-exclusive: func(this: descriptor) -> result<_, errno> ``` ## `unlock` @@ -807,7 +763,37 @@ try-lock-exclusive: func() -> result<_, errno> /// Release a shared or exclusive lock on an open file. /// /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. -unlock: func() -> result<_, errno> +unlock: func(this: descriptor) -> result<_, errno> +``` + +# `drop-descriptor` +```wit +/// Dispose of the specified `descriptor`, after which it may no longer +/// be used. +// TODO(} /* resource descriptor */) +drop-descriptor: func(this: descriptor) +``` + +## `dir-entry-stream` +```wit +/// A stream of directory entries. +// TODO(resource dir-entry-stream {) +// TODO(stream) +type dir-entry-stream = u32 +``` + +## `read-dir-entry` +```wit +/// Read a single directory entry from a `dir-entry-stream`. +read-dir-entry: func(this: dir-entry-stream) -> result, errno> +``` + +# `drop-dir-entry-stream` +```wit +/// Dispose of the specified `dir-entry-stream`, after which it may no longer +/// be used. +// TODO(} /* resource dir-entry-stream */) +drop-dir-entry-stream: func(this: dir-entry-stream) ``` ```wit diff --git a/proposals/filesystem/wit/world.wit.md b/proposals/filesystem/wit/world.wit.md new file mode 100644 index 000000000..6689fafb9 --- /dev/null +++ b/proposals/filesystem/wit/world.wit.md @@ -0,0 +1,9 @@ +This file contains a world that imports all interfaces in this proposal. Its +primary purpose is to allow unified documentation to be easily generated for +the whole proposal. + +```wit +default world wasi-filesystem { + import wasi-filesystem: pkg.wasi-filesystem +} +``` From ffd6433c8214434ed12c540ca6bc568e620ec505 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 8 Feb 2023 04:30:42 -0800 Subject: [PATCH 1019/1772] Update to the latest wasi-proposal-repo format. (#33) This updates to the latest wasi-proposal-repo format, which includes updating to the latest wit-bindgen. That in turm includes temporarily removing resources, though I've left in comments making it clear where the resources will go. This also fixes #31 by splitting monotonic and wall clocks into their own interfaces. Fixes #31. --- proposals/clocks/.github/workflows/main.yml | 4 +- proposals/clocks/timezone.abi.md | 93 ------ proposals/clocks/wasi-clocks.abi.md | 127 -------- proposals/clocks/wasi-clocks.html | 223 +++++++++++++ proposals/clocks/wasi-clocks.md | 297 ++++++++++++++++++ proposals/clocks/wasi-clocks.wit.md | 122 ------- proposals/clocks/wasi-default-clocks.abi.md | 0 proposals/clocks/{ => wit}/timezone.wit.md | 22 +- .../{ => wit}/wasi-default-clocks.wit.md | 19 +- .../clocks/wit/wasi-monotonic-clock.wit.md | 54 ++++ proposals/clocks/wit/wasi-wall-clock.wit.md | 72 +++++ proposals/clocks/wit/world.wit.md | 12 + 12 files changed, 692 insertions(+), 353 deletions(-) delete mode 100644 proposals/clocks/timezone.abi.md delete mode 100644 proposals/clocks/wasi-clocks.abi.md create mode 100644 proposals/clocks/wasi-clocks.html create mode 100644 proposals/clocks/wasi-clocks.md delete mode 100644 proposals/clocks/wasi-clocks.wit.md delete mode 100644 proposals/clocks/wasi-default-clocks.abi.md rename proposals/clocks/{ => wit}/timezone.wit.md (84%) rename proposals/clocks/{ => wit}/wasi-default-clocks.wit.md (62%) create mode 100644 proposals/clocks/wit/wasi-monotonic-clock.wit.md create mode 100644 proposals/clocks/wit/wasi-wall-clock.wit.md create mode 100644 proposals/clocks/wit/world.wit.md diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index b05870f53..8ca235c4f 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v6 + - uses: WebAssembly/wit-abi-up-to-date@v10 with: - wit-abi-tag: wit-abi-0.5.0 + wit-abi-tag: wit-abi-0.8.0 diff --git a/proposals/clocks/timezone.abi.md b/proposals/clocks/timezone.abi.md deleted file mode 100644 index e3af485bd..000000000 --- a/proposals/clocks/timezone.abi.md +++ /dev/null @@ -1,93 +0,0 @@ -# Types - -## `datetime`: record - - A time and date in seconds plus nanoseconds. - - TODO: Use the definition from the monotonic clock API instead of defining our own copy. - -Size: 16, Alignment: 8 - -### Record Fields - -- [`seconds`](#datetime.seconds): `u64` - - -- [`nanoseconds`](#datetime.nanoseconds): `u32` - - -## `timezone-display`: record - - Information useful for displaying the timezone of a specific `datetime`. - - This information may vary within a single `timezone` to reflect daylight - saving time adjustments. - -Size: 16, Alignment: 4 - -### Record Fields - -- [`utc-offset`](#timezone_display.utc_offset): `u32` - - The number of seconds difference between UTC time and the local time of - the timezone. - - The returned value will always be less than 86400 which is the number of - seconds in a day (24*60*60). - - In implementations that do not expose an actual time zone, this should - return 0. - -- [`name`](#timezone_display.name): `string` - - The abbreviated name of the timezone to display to a user. The name `UTC` - indicates Coordinated Universal Time. Otherwise, this should reference - local standards for the name of the time zone. - - In implementations that do not expose an actual time zone, this should be - the string `UTC`. - - In time zones that do not have an applicable name, a formatted - representation of the UTC offset may be returned, such as `-04:00`. - -- [`in-daylight-saving-time`](#timezone_display.in_daylight_saving_time): `bool` - - Whether daylight saving time is active. - - In implementations that do not expose an actual time zone, this should - return false. - -# Functions - ----- - -#### `timezone::display` - - Return information needed to display the given `datetime`. This includes - the UTC offset, the time zone name, and a flag indicating whether - daylight saving time is active. - - If the timezone cannot be determined for the given `datetime`, return a - `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight - saving time. -##### Params - -- `self`: handle -- `when`: [`datetime`](#datetime) -##### Results - -- [`timezone-display`](#timezone_display) - ----- - -#### `timezone::utc-offset` - - The same as `display`, but only return the UTC offset. -##### Params - -- `self`: handle -- `when`: [`datetime`](#datetime) -##### Results - -- `u32` - diff --git a/proposals/clocks/wasi-clocks.abi.md b/proposals/clocks/wasi-clocks.abi.md deleted file mode 100644 index 0909eb4af..000000000 --- a/proposals/clocks/wasi-clocks.abi.md +++ /dev/null @@ -1,127 +0,0 @@ -# Types - -## `instant`: `u64` - - A timestamp in nanoseconds. - -Size: 8, Alignment: 8 - -## `datetime`: record - - A time and date in seconds plus nanoseconds. - -Size: 16, Alignment: 8 - -### Record Fields - -- [`seconds`](#datetime.seconds): `u64` - - -- [`nanoseconds`](#datetime.nanoseconds): `u32` - - -# Functions - ----- - -#### `monotonic-clock::now` - - Read the current value of the clock. - - The clock is monotonic, therefore calling this function repeatedly will produce - a sequence of non-decreasing values. -##### Params - -- `self`: handle -##### Results - -- [`instant`](#instant) - ----- - -#### `monotonic-clock::resolution` - - Query the resolution of the clock. -##### Params - -- `self`: handle -##### Results - -- [`instant`](#instant) - ----- - -#### `monotonic-clock::new-timer` - - This creates a new `monotonic-timer` with the given starting time. It will - count down from this time until it reaches zero. -##### Params - -- `self`: handle -- `initial`: [`instant`](#instant) -##### Results - -- handle - ----- - -#### `wall-clock::now` - - Read the current value of the clock. - - This clock is not monotonic, therefore calling this function repeatedly will - not necessarily produce a sequence of non-decreasing values. - - The returned timestamps represent the number of seconds since - 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], also - known as [Unix Time]. - - The nanoseconds field of the output is always less than 1000000000. - - [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 - [Unix Time]: https://en.wikipedia.org/wiki/Unix_time -##### Params - -- `self`: handle -##### Results - -- [`datetime`](#datetime) - ----- - -#### `wall-clock::resolution` - - Query the resolution of the clock. - - The nanoseconds field of the output is always less than 1000000000. -##### Params - -- `self`: handle -##### Results - -- [`datetime`](#datetime) - ----- - -#### `monotonic-timer::current` - - Returns the amount of time left before this timer reaches zero. -##### Params - -- `self`: handle -##### Results - -- [`instant`](#instant) - ----- - -#### `monotonic-timer::expiration` - - Returns a future that completes when the timer reaches zero. -##### Params - -- `self`: handle -##### Results - -- future - diff --git a/proposals/clocks/wasi-clocks.html b/proposals/clocks/wasi-clocks.html new file mode 100644 index 000000000..088d63130 --- /dev/null +++ b/proposals/clocks/wasi-clocks.html @@ -0,0 +1,223 @@ +

Import interface wasi-monotonic-clock

+

Types

+

monotonic-clock: u32

+

A monotonic clock is a clock which has an unspecified initial value, and +successive reads of the clock will produce non-decreasing values.

+

It is intended for measuring elapsed time.

+

Size: 4, Alignment: 4

+

instant: u64

+

A timestamp in nanoseconds.

+

Size: 8, Alignment: 8

+

Functions

+
+

now

+

Read the current value of the clock.

+

The clock is monotonic, therefore calling this function repeatedly will produce +a sequence of non-decreasing values.

+
Params
+ +
Results
+ +
+

resolution

+

Query the resolution of the clock.

+
Params
+ +
Results
+ +
+

drop-monotonic-clock

+

Dispose of the specified monotonic-clock, after which it may no longer +be used.

+
Params
+ +

Import interface wasi-wall-clock

+

Types

+

wall-clock: u32

+

A wall clock is a clock which measures the date and time according to some +external reference.

+

External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time.

+

It is intended for reporting the current date and time for humans.

+

Size: 4, Alignment: 4

+

datetime: record

+

A time and date in seconds plus nanoseconds.

+

Size: 16, Alignment: 8

+

Record Fields

+ +

Functions

+
+

now

+

Read the current value of the clock.

+

This clock is not monotonic, therefore calling this function repeatedly will +not necessarily produce a sequence of non-decreasing values.

+

The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, also +known as Unix Time.

+

The nanoseconds field of the output is always less than 1000000000.

+
Params
+ +
Results
+ +
+

resolution

+

Query the resolution of the clock.

+

The nanoseconds field of the output is always less than 1000000000.

+
Params
+ +
Results
+ +
+

drop-wall-clock

+

Dispose of the specified wall-clock, after which it may no longer +be used.

+
Params
+ +

Import interface wasi-timezone

+

Types

+

timezone-display: record

+

Information useful for displaying the timezone of a specific datetime.

+

This information may vary within a single timezone to reflect daylight +saving time adjustments.

+

Size: 16, Alignment: 4

+

Record Fields

+
    +
  • +

    utc-offset: u32

    +

    The number of seconds difference between UTC time and the local time of +the timezone.

    +

    The returned value will always be less than 86400 which is the number of +seconds in a day (246060).

    +

    In implementations that do not expose an actual time zone, this should +return 0.

    +
  • +
  • +

    name: string

    +

    The abbreviated name of the timezone to display to a user. The name UTC +indicates Coordinated Universal Time. Otherwise, this should reference +local standards for the name of the time zone.

    +

    In implementations that do not expose an actual time zone, this should be +the string UTC.

    +

    In time zones that do not have an applicable name, a formatted +representation of the UTC offset may be returned, such as -04:00.

    +
  • +
  • +

    in-daylight-saving-time: bool

    +

    Whether daylight saving time is active.

    +

    In implementations that do not expose an actual time zone, this should +return false.

    +
  • +
+

timezone: u32

+

A timezone.

+

In timezones that recognize daylight saving time, also known as daylight +time and summer time, the information returned from the functions varies +over time to reflect these adjustments.

+

Size: 4, Alignment: 4

+

datetime: record

+

A time and date in seconds plus nanoseconds.

+

TODO: Use the definition from the monotonic clock API instead of defining our own copy.

+

Size: 16, Alignment: 8

+

Record Fields

+ +

Functions

+
+

display

+

Return information needed to display the given datetime. This includes +the UTC offset, the time zone name, and a flag indicating whether +daylight saving time is active.

+

If the timezone cannot be determined for the given datetime, return a +timezone-display for UTC with a utc-offset of 0 and no daylight +saving time.

+
Params
+ +
Results
+ +
+

utc-offset

+

The same as display, but only return the UTC offset.

+
Params
+ +
Results
+
    +
  • result0: u32
  • +
+
+

drop-timezone

+

Dispose of the specified input-stream, after which it may no longer +be used.

+
Params
+ +

Import interface wasi-default-clocks

+

Types

+

monotonic-clock: monotonic-clock

+

Size: 4, Alignment: 4

+

wall-clock: wall-clock

+

Size: 4, Alignment: 4

+

Functions

+
+

default-monotonic-clock

+

Return a default monotonic clock, suitable for general-purpose application +needs.

+

This allocates a new handle, so applications with frequent need of a clock +handle should call this function once and reuse the handle instead of +calling this function each time.

+
Results
+ +
+

default-wall-clock

+

Return a default wall clock, suitable for general-purpose application +needs.

+

This allocates a new handle, so applications with frequent need of a clock +handle should call this function once and reuse the handle instead of +calling this function each time.

+
Results
+ diff --git a/proposals/clocks/wasi-clocks.md b/proposals/clocks/wasi-clocks.md new file mode 100644 index 000000000..cc357897d --- /dev/null +++ b/proposals/clocks/wasi-clocks.md @@ -0,0 +1,297 @@ +# Import interface `wasi-monotonic-clock` + +## Types + +## `monotonic-clock`: `u32` + +A monotonic clock is a clock which has an unspecified initial value, and +successive reads of the clock will produce non-decreasing values. + +It is intended for measuring elapsed time. + +Size: 4, Alignment: 4 + +## `instant`: `u64` + +A timestamp in nanoseconds. + +Size: 8, Alignment: 8 + +## Functions + +---- + +#### `now` + +Read the current value of the clock. + +The clock is monotonic, therefore calling this function repeatedly will produce +a sequence of non-decreasing values. +##### Params + +- `this`: [`monotonic-clock`](#monotonic_clock) +##### Results + +- `result0`: [`instant`](#instant) + +---- + +#### `resolution` + +Query the resolution of the clock. +##### Params + +- `this`: [`monotonic-clock`](#monotonic_clock) +##### Results + +- `result0`: [`instant`](#instant) + +---- + +#### `drop-monotonic-clock` + +Dispose of the specified `monotonic-clock`, after which it may no longer +be used. +##### Params + +- `this`: [`monotonic-clock`](#monotonic_clock) + +# Import interface `wasi-wall-clock` + +## Types + +## `wall-clock`: `u32` + +A wall clock is a clock which measures the date and time according to some +external reference. + +External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time. + +It is intended for reporting the current date and time for humans. + +Size: 4, Alignment: 4 + +## `datetime`: record + +A time and date in seconds plus nanoseconds. + +Size: 16, Alignment: 8 + +### Record Fields + +- [`seconds`](#datetime.seconds): `u64` + + +- [`nanoseconds`](#datetime.nanoseconds): `u32` + + +## Functions + +---- + +#### `now` + +Read the current value of the clock. + +This clock is not monotonic, therefore calling this function repeatedly will +not necessarily produce a sequence of non-decreasing values. + +The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], also +known as [Unix Time]. + +The nanoseconds field of the output is always less than 1000000000. + +[POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 +[Unix Time]: https://en.wikipedia.org/wiki/Unix_time +##### Params + +- `this`: [`wall-clock`](#wall_clock) +##### Results + +- `result0`: [`datetime`](#datetime) + +---- + +#### `resolution` + +Query the resolution of the clock. + +The nanoseconds field of the output is always less than 1000000000. +##### Params + +- `this`: [`wall-clock`](#wall_clock) +##### Results + +- `result0`: [`datetime`](#datetime) + +---- + +#### `drop-wall-clock` + +Dispose of the specified `wall-clock`, after which it may no longer +be used. +##### Params + +- `this`: [`wall-clock`](#wall_clock) + +# Import interface `wasi-timezone` + +## Types + +## `timezone-display`: record + +Information useful for displaying the timezone of a specific `datetime`. + +This information may vary within a single `timezone` to reflect daylight +saving time adjustments. + +Size: 16, Alignment: 4 + +### Record Fields + +- [`utc-offset`](#timezone_display.utc_offset): `u32` + + The number of seconds difference between UTC time and the local time of + the timezone. + + The returned value will always be less than 86400 which is the number of + seconds in a day (24*60*60). + + In implementations that do not expose an actual time zone, this should + return 0. + +- [`name`](#timezone_display.name): `string` + + The abbreviated name of the timezone to display to a user. The name `UTC` + indicates Coordinated Universal Time. Otherwise, this should reference + local standards for the name of the time zone. + + In implementations that do not expose an actual time zone, this should be + the string `UTC`. + + In time zones that do not have an applicable name, a formatted + representation of the UTC offset may be returned, such as `-04:00`. + +- [`in-daylight-saving-time`](#timezone_display.in_daylight_saving_time): `bool` + + Whether daylight saving time is active. + + In implementations that do not expose an actual time zone, this should + return false. + +## `timezone`: `u32` + +A timezone. + +In timezones that recognize daylight saving time, also known as daylight +time and summer time, the information returned from the functions varies +over time to reflect these adjustments. + +Size: 4, Alignment: 4 + +## `datetime`: record + +A time and date in seconds plus nanoseconds. + +TODO: Use the definition from the monotonic clock API instead of defining our own copy. + +Size: 16, Alignment: 8 + +### Record Fields + +- [`seconds`](#datetime.seconds): `u64` + + +- [`nanoseconds`](#datetime.nanoseconds): `u32` + + +## Functions + +---- + +#### `display` + +Return information needed to display the given `datetime`. This includes +the UTC offset, the time zone name, and a flag indicating whether +daylight saving time is active. + +If the timezone cannot be determined for the given `datetime`, return a +`timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight +saving time. +##### Params + +- `this`: [`timezone`](#timezone) +- `when`: [`datetime`](#datetime) +##### Results + +- `result0`: [`timezone-display`](#timezone_display) + +---- + +#### `utc-offset` + +The same as `display`, but only return the UTC offset. +##### Params + +- `this`: [`timezone`](#timezone) +- `when`: [`datetime`](#datetime) +##### Results + +- `result0`: `u32` + +---- + +#### `drop-timezone` + +Dispose of the specified input-stream, after which it may no longer +be used. +##### Params + +- `this`: [`timezone`](#timezone) + +# Import interface `wasi-default-clocks` + +## Types + +## `monotonic-clock`: [`monotonic-clock`](#monotonic_clock) + + +Size: 4, Alignment: 4 + +## `wall-clock`: [`wall-clock`](#wall_clock) + + +Size: 4, Alignment: 4 + +## Functions + +---- + +#### `default-monotonic-clock` + +Return a default monotonic clock, suitable for general-purpose application +needs. + +This allocates a new handle, so applications with frequent need of a clock +handle should call this function once and reuse the handle instead of +calling this function each time. +##### Results + +- `result0`: [`monotonic-clock`](#monotonic_clock) + +---- + +#### `default-wall-clock` + +Return a default wall clock, suitable for general-purpose application +needs. + +This allocates a new handle, so applications with frequent need of a clock +handle should call this function once and reuse the handle instead of +calling this function each time. +##### Results + +- `result0`: [`wall-clock`](#wall_clock) + diff --git a/proposals/clocks/wasi-clocks.wit.md b/proposals/clocks/wasi-clocks.wit.md deleted file mode 100644 index 5b3a93225..000000000 --- a/proposals/clocks/wasi-clocks.wit.md +++ /dev/null @@ -1,122 +0,0 @@ -# WASI Clocks API - -WASI Clocks is a clock API intended to let users query the current time and -to measure elapsed time. - -It is intended to be portable at least between Unix-family platforms and -Windows. - -## `instant` -```wit -/// A timestamp in nanoseconds. -type instant = u64 -``` - -## `datetime` -```wit -/// A time and date in seconds plus nanoseconds. -record datetime { - seconds: u64, - nanoseconds: u32, -} -``` - -## `monotonic-clock` -```wit -/// A monotonic clock is a clock which has an unspecified initial value, and -/// successive reads of the clock will produce non-decreasing values. -/// -/// It is intended for measuring elapsed time. -resource monotonic-clock { -``` - -## `now` -```wit -/// Read the current value of the clock. -/// -/// The clock is monotonic, therefore calling this function repeatedly will produce -/// a sequence of non-decreasing values. -now: func() -> instant -``` - -## `resolution` -```wit -/// Query the resolution of the clock. -resolution: func() -> instant -``` - -## `new-timer` -```wit -/// This creates a new `monotonic-timer` with the given starting time. It will -/// count down from this time until it reaches zero. -new-timer: func(initial: instant) -> handle monotonic-timer -``` - -```wit -} -``` - -## `wall-clock` -```wit -/// A wall clock is a clock which measures the date and time according to some -/// external reference. -/// -/// External references may be reset, so this clock is not necessarily -/// monotonic, making it unsuitable for measuring elapsed time. -/// -/// It is intended for reporting the current date and time for humans. -resource wall-clock { -``` - -## `now` -```wit -/// Read the current value of the clock. -/// -/// This clock is not monotonic, therefore calling this function repeatedly will -/// not necessarily produce a sequence of non-decreasing values. -/// -/// The returned timestamps represent the number of seconds since -/// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], also -/// known as [Unix Time]. -/// -/// The nanoseconds field of the output is always less than 1000000000. -/// -/// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 -/// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time -now: func() -> datetime -``` - -## `resolution` -```wit -/// Query the resolution of the clock. -/// -/// The nanoseconds field of the output is always less than 1000000000. -resolution: func() -> datetime -``` - -```wit -} -``` - -## `monotonic-timer` -```wit -/// This is a timer that counts down from a given starting time down to zero -/// on a monotonic clock. -resource monotonic-timer { -``` - -## `current` -```wit -/// Returns the amount of time left before this timer reaches zero. -current: func() -> instant -``` - -## `expiration` -```wit -/// Returns a future that completes when the timer reaches zero. -expiration: func() -> future -``` - -```wit -} -``` diff --git a/proposals/clocks/wasi-default-clocks.abi.md b/proposals/clocks/wasi-default-clocks.abi.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/proposals/clocks/timezone.wit.md b/proposals/clocks/wit/timezone.wit.md similarity index 84% rename from proposals/clocks/timezone.wit.md rename to proposals/clocks/wit/timezone.wit.md index af2c8680a..88d0cdac2 100644 --- a/proposals/clocks/timezone.wit.md +++ b/proposals/clocks/wit/timezone.wit.md @@ -1,5 +1,10 @@ # WASI Clocks Timezone API +# `wasi-timezone` +```wit +default interface wasi-timezone { +``` + ## `datetime` ```wit /// A time and date in seconds plus nanoseconds. @@ -18,7 +23,8 @@ record datetime { /// In timezones that recognize daylight saving time, also known as daylight /// time and summer time, the information returned from the functions varies /// over time to reflect these adjustments. -resource timezone { +// TODO(resource timezone {) +type timezone = u32 ``` ## `display` @@ -30,17 +36,21 @@ resource timezone { /// If the timezone cannot be determined for the given `datetime`, return a /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight /// saving time. - display: func(when: datetime) -> timezone-display + display: func(this: timezone, when: datetime) -> timezone-display ``` ## `utc-offset` ```wit /// The same as `display`, but only return the UTC offset. - utc-offset: func(when: datetime) -> u32 + utc-offset: func(this: timezone, when: datetime) -> u32 ``` +## `drop-timezone` ```wit -} +/// Dispose of the specified input-stream, after which it may no longer +/// be used. +// TODO(} /* resource timezone */) +drop-timezone: func(this: timezone) ``` ## `timezone-display` @@ -91,3 +101,7 @@ record timezone-display { ```wit } ``` + +```wit +} +``` diff --git a/proposals/clocks/wasi-default-clocks.wit.md b/proposals/clocks/wit/wasi-default-clocks.wit.md similarity index 62% rename from proposals/clocks/wasi-default-clocks.wit.md rename to proposals/clocks/wit/wasi-default-clocks.wit.md index 8c76bb905..dfeddcc4e 100644 --- a/proposals/clocks/wasi-default-clocks.wit.md +++ b/proposals/clocks/wit/wasi-default-clocks.wit.md @@ -1,11 +1,16 @@ # WASI Default Clocks API -WASI Default Clocks provides value-exports of clock handles for monotonic -and a wall-clock time, suitable for general-purpose application needs. +## `wasi-default-clocks` +```wit +/// WASI Default Clocks provides value-exports of clock handles for monotonic +/// and a wall-clock time, suitable for general-purpose application needs. +default interface wasi-default-clocks { +``` ## Imports ```wit -use { monotonic-clock, wall-clock } from wasi-clocks +use pkg.wasi-monotonic-clock.{monotonic-clock} +use pkg.wasi-wall-clock.{wall-clock} ``` ## `default-monotonic-clock` @@ -16,7 +21,7 @@ use { monotonic-clock, wall-clock } from wasi-clocks /// This allocates a new handle, so applications with frequent need of a clock /// handle should call this function once and reuse the handle instead of /// calling this function each time. -default-monotonic-clock: monotonic-clock +default-monotonic-clock: func() -> monotonic-clock ``` ## `default-wall-clock` @@ -27,5 +32,9 @@ default-monotonic-clock: monotonic-clock /// This allocates a new handle, so applications with frequent need of a clock /// handle should call this function once and reuse the handle instead of /// calling this function each time. -default-wall-clock: wall-clock +default-wall-clock: func() -> wall-clock +``` + +```wit +} ``` diff --git a/proposals/clocks/wit/wasi-monotonic-clock.wit.md b/proposals/clocks/wit/wasi-monotonic-clock.wit.md new file mode 100644 index 000000000..1cebb47c3 --- /dev/null +++ b/proposals/clocks/wit/wasi-monotonic-clock.wit.md @@ -0,0 +1,54 @@ +# WASI Monotonic Clock API + +## `wasi-clocks` +```wit +/// WASI Monotonic Clock is a clock API intended to let users measure elapsed +/// time. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface wasi-monotonic-clock { +``` + +## `instant` +```wit +/// A timestamp in nanoseconds. +type instant = u64 +``` + +## `monotonic-clock` +```wit +/// A monotonic clock is a clock which has an unspecified initial value, and +/// successive reads of the clock will produce non-decreasing values. +/// +/// It is intended for measuring elapsed time. +// TODO(resource monotonic-clock {) +type monotonic-clock = u32 +``` + +## `now` +```wit +/// Read the current value of the clock. +/// +/// The clock is monotonic, therefore calling this function repeatedly will produce +/// a sequence of non-decreasing values. +now: func(this: monotonic-clock) -> instant +``` + +## `resolution` +```wit +/// Query the resolution of the clock. +resolution: func(this: monotonic-clock) -> instant +``` + +## `drop-monotonic-clock` +```wit +/// Dispose of the specified `monotonic-clock`, after which it may no longer +/// be used. +// TODO(} /* resource monotonic-clock */) +drop-monotonic-clock: func(this: monotonic-clock) +``` + +```wit +} +``` diff --git a/proposals/clocks/wit/wasi-wall-clock.wit.md b/proposals/clocks/wit/wasi-wall-clock.wit.md new file mode 100644 index 000000000..84d5536ce --- /dev/null +++ b/proposals/clocks/wit/wasi-wall-clock.wit.md @@ -0,0 +1,72 @@ +# WASI Wall Clock API + +## `wasi-wall-clock` +```wit +/// WASI Wall Clock is a clock API intended to let users query the current +/// time. The name "wall" makes an analogy to a "clock on the wall", which +/// is not necessarily monotonic as it may be reset. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface wasi-wall-clock { +``` + +## `datetime` +```wit +/// A time and date in seconds plus nanoseconds. +record datetime { + seconds: u64, + nanoseconds: u32, +} +``` + +## `wall-clock` +```wit +/// A wall clock is a clock which measures the date and time according to some +/// external reference. +/// +/// External references may be reset, so this clock is not necessarily +/// monotonic, making it unsuitable for measuring elapsed time. +/// +/// It is intended for reporting the current date and time for humans. +// TODO(resource wall-clock {) +type wall-clock = u32 +``` + +## `now` +```wit +/// Read the current value of the clock. +/// +/// This clock is not monotonic, therefore calling this function repeatedly will +/// not necessarily produce a sequence of non-decreasing values. +/// +/// The returned timestamps represent the number of seconds since +/// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], also +/// known as [Unix Time]. +/// +/// The nanoseconds field of the output is always less than 1000000000. +/// +/// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 +/// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time +now: func(this: wall-clock) -> datetime +``` + +## `resolution` +```wit +/// Query the resolution of the clock. +/// +/// The nanoseconds field of the output is always less than 1000000000. +resolution: func(this: wall-clock) -> datetime +``` + +## `drop-wall-clock` +```wit +/// Dispose of the specified `wall-clock`, after which it may no longer +/// be used. +// TODO(} /* resource wall-clock */) +drop-wall-clock: func(this: wall-clock) +``` + +```wit +} +``` diff --git a/proposals/clocks/wit/world.wit.md b/proposals/clocks/wit/world.wit.md new file mode 100644 index 000000000..cb1243a89 --- /dev/null +++ b/proposals/clocks/wit/world.wit.md @@ -0,0 +1,12 @@ +This file contains a world that imports all interfaces in this proposal. Its +primary purpose is to allow unified documentation to be easily generated for +the whole proposal. + +```wit +default world wasi-clocks { + import wasi-monotonic-clock: pkg.wasi-monotonic-clock + import wasi-wall-clock: pkg.wasi-wall-clock + import wasi-timezone: pkg.timezone + import wasi-default-clocks: pkg.wasi-default-clocks +} +``` From 6da459c7a8427b3daca95eccb92d33e9d9d2a574 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 8 Feb 2023 04:31:11 -0800 Subject: [PATCH 1020/1772] Update to the latest wasi-proposal-repo format. (#19) This updates to the latest wasi-proposal-repo format, which includes updating to the latest wit-bindgen. That in turm includes temporarily removing resources, though I've left in comments making it clear where the resources will go. --- proposals/io/.github/workflows/main.yml | 4 +- proposals/io/wasi-io.abi.md | 116 ----------------- proposals/io/wasi-io.html | 128 ++++++++++++++++++ proposals/io/wasi-io.md | 164 ++++++++++++++++++++++++ proposals/io/{ => wit}/wasi-io.wit.md | 61 +++++++-- proposals/io/wit/world.wit.md | 9 ++ 6 files changed, 353 insertions(+), 129 deletions(-) delete mode 100644 proposals/io/wasi-io.abi.md create mode 100644 proposals/io/wasi-io.html create mode 100644 proposals/io/wasi-io.md rename proposals/io/{ => wit}/wasi-io.wit.md (64%) create mode 100644 proposals/io/wit/world.wit.md diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index a61809957..8ca235c4f 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v6 + - uses: WebAssembly/wit-abi-up-to-date@v10 with: - wit-abi-tag: wit-abi-0.6.0 + wit-abi-tag: wit-abi-0.8.0 diff --git a/proposals/io/wasi-io.abi.md b/proposals/io/wasi-io.abi.md deleted file mode 100644 index ec4076f87..000000000 --- a/proposals/io/wasi-io.abi.md +++ /dev/null @@ -1,116 +0,0 @@ -# Types - -## `stream-error`: record - - An error type returned from a stream operation. Currently this - doesn't provide any additional information. - -Size: 0, Alignment: 1 - -### Record Fields - -# Functions - ----- - -#### `input-stream::read` - - Read bytes from a stream. - - This function returns a list of bytes containing the data that was - read, along with a bool indicating whether the end of the stream - was reached. The returned list will contain up to `len` bytes; it - may return fewer than requested, but not more. - - Once a stream has reached the end, subsequent calls to read or - `skip` will always report end-of-stream rather than producing more - data. - - If `len` is 0, it represents a request to read 0 bytes, which should - always succeed, assuming the stream hasn't reached its end yet, and - return an empty list. - - The len here is a `u64`, but some callees may not be able to allocate - a buffer as large as that would imply. - FIXME: describe what happens if allocation fails. -##### Params - -- `self`: handle -- `len`: `u64` -##### Results - -- result<(list<`u8`>, `bool`), [`stream-error`](#stream_error)> - ----- - -#### `input-stream::skip` - - Skip bytes from a stream. - - This is similar to the `read` function, but avoids copying the - bytes into the instance. - - Once a stream has reached the end, subsequent calls to read or - `skip` will always report end-of-stream rather than producing more - data. - - This function returns the number of bytes skipped, along with a bool - indicating whether the end of the stream was reached. The returned - value will be at most `len`; it may be less. -##### Params - -- `self`: handle -- `len`: `u64` -##### Results - -- result<(`u64`, `bool`), [`stream-error`](#stream_error)> - ----- - -#### `output-stream::write` - - Write bytes to a stream. - - This function returns a `u64` indicating the number of bytes from - `buf` that were written; it may be less than the full list. -##### Params - -- `self`: handle -- `buf`: list<`u8`> -##### Results - -- result<`u64`, [`stream-error`](#stream_error)> - ----- - -#### `output-stream::write-zeroes` - - Write multiple zero bytes to a stream. - - This function returns a `u64` indicating the number of zero bytes - that were written; it may be less than `len`. -##### Params - -- `self`: handle -- `len`: `u64` -##### Results - -- result<`u64`, [`stream-error`](#stream_error)> - ----- - -#### `output-stream::splice` - - Read from one stream and write to another. - - This function returns the number of bytes transferred; it may be less - than `len`. -##### Params - -- `self`: handle -- `src`: handle -- `len`: `u64` -##### Results - -- result<(`u64`, `bool`), [`stream-error`](#stream_error)> - diff --git a/proposals/io/wasi-io.html b/proposals/io/wasi-io.html new file mode 100644 index 000000000..904bccd4f --- /dev/null +++ b/proposals/io/wasi-io.html @@ -0,0 +1,128 @@ +

Import interface wasi-io

+

Types

+

stream-error: record

+

An error type returned from a stream operation. Currently this +doesn't provide any additional information.

+

Size: 0, Alignment: 1

+

Record Fields

+

output-stream: u32

+

An output bytestream. In the future, this will be replaced by handle +types.

+

This conceptually represents a stream<u8, _>. It's temporary +scaffolding until component-model's async features are ready.

+

And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

+

Size: 4, Alignment: 4

+

input-stream: u32

+

An input bytestream. In the future, this will be replaced by handle +types.

+

This conceptually represents a stream<u8, _>. It's temporary +scaffolding until component-model's async features are ready.

+

And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

+

Size: 4, Alignment: 4

+

Functions

+
+

read

+

Read bytes from a stream.

+

This function returns a list of bytes containing the data that was +read, along with a bool indicating whether the end of the stream +was reached. The returned list will contain up to len bytes; it +may return fewer than requested, but not more.

+

Once a stream has reached the end, subsequent calls to read or +skip will always report end-of-stream rather than producing more +data.

+

If len is 0, it represents a request to read 0 bytes, which should +always succeed, assuming the stream hasn't reached its end yet, and +return an empty list.

+

The len here is a u64, but some callees may not be able to allocate +a buffer as large as that would imply. +FIXME: describe what happens if allocation fails.

+
Params
+ +
Results
+ +
+

skip

+

Skip bytes from a stream.

+

This is similar to the read function, but avoids copying the +bytes into the instance.

+

Once a stream has reached the end, subsequent calls to read or +skip will always report end-of-stream rather than producing more +data.

+

This function returns the number of bytes skipped, along with a bool +indicating whether the end of the stream was reached. The returned +value will be at most len; it may be less.

+
Params
+ +
Results
+ +
+

drop-input-stream

+

Dispose of the specified input-stream, after which it may no longer +be used.

+
Params
+ +
+

write

+

Write bytes to a stream.

+

This function returns a u64 indicating the number of bytes from +buf that were written; it may be less than the full list.

+
Params
+ +
Results
+ +
+

write-zeroes

+

Write multiple zero bytes to a stream.

+

This function returns a u64 indicating the number of zero bytes +that were written; it may be less than len.

+
Params
+ +
Results
+ +
+

splice

+

Read from one stream and write to another.

+

This function returns the number of bytes transferred; it may be less +than len.

+
Params
+ +
Results
+ +
+

drop-output-stream

+

Dispose of the specified output-stream, after which it may no longer +be used.

+
Params
+ diff --git a/proposals/io/wasi-io.md b/proposals/io/wasi-io.md new file mode 100644 index 000000000..6c09ae412 --- /dev/null +++ b/proposals/io/wasi-io.md @@ -0,0 +1,164 @@ +# Import interface `wasi-io` + +## Types + +## `stream-error`: record + +An error type returned from a stream operation. Currently this +doesn't provide any additional information. + +Size: 0, Alignment: 1 + +### Record Fields + +## `output-stream`: `u32` + +An output bytestream. In the future, this will be replaced by handle +types. + +This conceptually represents a `stream`. It's temporary +scaffolding until component-model's async features are ready. + +And at present, it is a `u32` instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready. + +Size: 4, Alignment: 4 + +## `input-stream`: `u32` + +An input bytestream. In the future, this will be replaced by handle +types. + +This conceptually represents a `stream`. It's temporary +scaffolding until component-model's async features are ready. + +And at present, it is a `u32` instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready. + +Size: 4, Alignment: 4 + +## Functions + +---- + +#### `read` + +Read bytes from a stream. + +This function returns a list of bytes containing the data that was +read, along with a bool indicating whether the end of the stream +was reached. The returned list will contain up to `len` bytes; it +may return fewer than requested, but not more. + +Once a stream has reached the end, subsequent calls to read or +`skip` will always report end-of-stream rather than producing more +data. + +If `len` is 0, it represents a request to read 0 bytes, which should +always succeed, assuming the stream hasn't reached its end yet, and +return an empty list. + +The len here is a `u64`, but some callees may not be able to allocate +a buffer as large as that would imply. +FIXME: describe what happens if allocation fails. +##### Params + +- `this`: [`input-stream`](#input_stream) +- `len`: `u64` +##### Results + +- `result0`: result<(list<`u8`>, `bool`), [`stream-error`](#stream_error)> + +---- + +#### `skip` + +Skip bytes from a stream. + +This is similar to the `read` function, but avoids copying the +bytes into the instance. + +Once a stream has reached the end, subsequent calls to read or +`skip` will always report end-of-stream rather than producing more +data. + +This function returns the number of bytes skipped, along with a bool +indicating whether the end of the stream was reached. The returned +value will be at most `len`; it may be less. +##### Params + +- `this`: [`input-stream`](#input_stream) +- `len`: `u64` +##### Results + +- `result0`: result<(`u64`, `bool`), [`stream-error`](#stream_error)> + +---- + +#### `drop-input-stream` + +Dispose of the specified `input-stream`, after which it may no longer +be used. +##### Params + +- `this`: [`input-stream`](#input_stream) + +---- + +#### `write` + +Write bytes to a stream. + +This function returns a `u64` indicating the number of bytes from +`buf` that were written; it may be less than the full list. +##### Params + +- `this`: [`output-stream`](#output_stream) +- `buf`: list<`u8`> +##### Results + +- `result0`: result<`u64`, [`stream-error`](#stream_error)> + +---- + +#### `write-zeroes` + +Write multiple zero bytes to a stream. + +This function returns a `u64` indicating the number of zero bytes +that were written; it may be less than `len`. +##### Params + +- `this`: [`output-stream`](#output_stream) +- `len`: `u64` +##### Results + +- `result0`: result<`u64`, [`stream-error`](#stream_error)> + +---- + +#### `splice` + +Read from one stream and write to another. + +This function returns the number of bytes transferred; it may be less +than `len`. +##### Params + +- `this`: [`output-stream`](#output_stream) +- `src`: [`input-stream`](#input_stream) +- `len`: `u64` +##### Results + +- `result0`: result<(`u64`, `bool`), [`stream-error`](#stream_error)> + +---- + +#### `drop-output-stream` + +Dispose of the specified `output-stream`, after which it may no longer +be used. +##### Params + +- `this`: [`output-stream`](#output_stream) + diff --git a/proposals/io/wasi-io.wit.md b/proposals/io/wit/wasi-io.wit.md similarity index 64% rename from proposals/io/wasi-io.wit.md rename to proposals/io/wit/wasi-io.wit.md index 950b48bc7..8eb089528 100644 --- a/proposals/io/wasi-io.wit.md +++ b/proposals/io/wit/wasi-io.wit.md @@ -1,10 +1,13 @@ # WASI I/O -WASI I/O is an I/O abstraction API which is currently focused on providing -stream types. - -In the future, the component model is expected to add built-in stream types; -when it does, they are expected to subsume this API. +```wit +/// WASI I/O is an I/O abstraction API which is currently focused on providing +/// stream types. +/// +/// In the future, the component model is expected to add built-in stream types; +/// when it does, they are expected to subsume this API. +default interface wasi-io { +``` ## `stream-error` ```wit @@ -15,7 +18,16 @@ record stream-error {} ## `input-stream` ```wit -resource input-stream { +/// An input bytestream. In the future, this will be replaced by handle +/// types. +/// +/// This conceptually represents a `stream`. It's temporary +/// scaffolding until component-model's async features are ready. +/// +/// And at present, it is a `u32` instead of being an actual handle, until +/// the wit-bindgen implementation of handles and resources is ready. +// TODO(resource input-stream {) +type input-stream = u32 ``` ## `read` @@ -39,6 +51,7 @@ resource input-stream { /// a buffer as large as that would imply. /// FIXME: describe what happens if allocation fails. read: func( + this: input-stream, /// The maximum number of bytes to read len: u64 ) -> result, bool>, stream-error> @@ -59,18 +72,32 @@ resource input-stream { /// indicating whether the end of the stream was reached. The returned /// value will be at most `len`; it may be less. skip: func( + this: input-stream, /// The maximum number of bytes to skip. len: u64, ) -> result, stream-error> ``` +# `drop-input-stream` ```wit -} +/// Dispose of the specified `input-stream`, after which it may no longer +/// be used. +// TODO(} /* resource input-stream */) +drop-input-stream: func(this: input-stream) ``` ## `output-stream` ```wit -resource output-stream { +/// An output bytestream. In the future, this will be replaced by handle +/// types. +/// +/// This conceptually represents a `stream`. It's temporary +/// scaffolding until component-model's async features are ready. +/// +/// And at present, it is a `u32` instead of being an actual handle, until +/// the wit-bindgen implementation of handles and resources is ready. +// TODO(resource output-stream {) +type output-stream = u32 ``` ## `write` @@ -80,6 +107,7 @@ resource output-stream { /// This function returns a `u64` indicating the number of bytes from /// `buf` that were written; it may be less than the full list. write: func( + this: output-stream, /// Data to write buf: list ) -> result @@ -92,6 +120,7 @@ resource output-stream { /// This function returns a `u64` indicating the number of zero bytes /// that were written; it may be less than `len`. write-zeroes: func( + this: output-stream, /// The number of zero bytes to write len: u64 ) -> result @@ -104,9 +133,10 @@ resource output-stream { /// This function returns the number of bytes transferred; it may be less /// than `len`. splice: func( - /// The stream to read from. + this: output-stream, + /// The stream to read from src: input-stream, - /// The number of bytes to splice. + /// The number of bytes to splice len: u64, ) -> result, stream-error> ``` @@ -121,11 +151,20 @@ resource output-stream { /// /// This function returns the number of bytes transferred. forward: func( - /// The stream to read from. + this: output-stream, + /// The stream to read from src: input-stream ) -> result ``` +# `drop-output-stream` +```wit +/// Dispose of the specified `output-stream`, after which it may no longer +/// be used. +// TODO(} /* resource output-stream */) +drop-output-stream: func(this: output-stream) +``` + ```wit } ``` diff --git a/proposals/io/wit/world.wit.md b/proposals/io/wit/world.wit.md new file mode 100644 index 000000000..e7b5d0db2 --- /dev/null +++ b/proposals/io/wit/world.wit.md @@ -0,0 +1,9 @@ +This file contains a world that imports all interfaces in this proposal. Its +primary purpose is to allow unified documentation to be easily generated for +the whole proposal. + +```wit +default world wasi-io { + import wasi-io: pkg.wasi-io +} +``` From a446ad7a67c2ac97a3a6d16a5d35bed115a57c61 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 8 Feb 2023 05:18:11 -0800 Subject: [PATCH 1021/1772] Add a polling interface for streams. (#20) The new wasi-poll API has a `pollable` type. Add subscribe methods to the stream types to allow polling for stream events. This adds a dependency on wasi-io, and is currently implemented in the repository in a low-tech way, which allows the generated documentation to work, though it's likely to evolve. --- proposals/io/.github/workflows/main.yml | 1 + proposals/io/wasi-io.html | 62 +++++++++++++++++++ proposals/io/wasi-io.md | 79 +++++++++++++++++++++++++ proposals/io/wit/wasi-io.wit.md | 19 ++++++ 4 files changed, 161 insertions(+) diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index 8ca235c4f..a46630a4e 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -11,6 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-poll/75ace039473c05928cfd8e6df0243fc47ee9e8c9/wit/wasi-poll.wit.md > wit/wasi-poll.wit.md - uses: WebAssembly/wit-abi-up-to-date@v10 with: wit-abi-tag: wit-abi-0.8.0 diff --git a/proposals/io/wasi-io.html b/proposals/io/wasi-io.html index 904bccd4f..380b1b234 100644 --- a/proposals/io/wasi-io.html +++ b/proposals/io/wasi-io.html @@ -1,5 +1,43 @@ +

Import interface wasi-poll

+

Types

+

pollable: u32

+

A "pollable" handle.

+

This is conceptually represents a stream<_, _>, or in other words, +a stream that one can wait on, repeatedly, but which does not itself +produce any data. It's temporary scaffolding until component-model's +async features are ready.

+

And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

+

pollable lifetimes are not automatically managed. Users must ensure +that they do not outlive the resource they reference.

+

Size: 4, Alignment: 4

+

Functions

+
+

poll-oneoff

+

Poll for completion on a set of pollables.

+

The "oneoff" in the name refers to the fact that this function must do a +linear scan through the entire list of subscriptions, which may be +inefficient if the number is large and the same subscriptions are used +many times. In the future, it may be accompanied by an API similar to +Linux's epoll which allows sets of subscriptions to be registered and +made efficiently reusable.

+

Note that the return type would ideally be list<bool>, but that would +be more difficult to polyfill given the current state of wit-bindgen. +See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 +for details. For now, we use zero to mean "not ready" and non-zero to +mean "ready".

+
Params
+ +
Results
+
    +
  • result0: list<u8>
  • +

Import interface wasi-io

Types

+

pollable: pollable

+

Size: 4, Alignment: 4

stream-error: record

An error type returned from a stream operation. Currently this doesn't provide any additional information.

@@ -68,6 +106,18 @@
Results
  • result0: result<(u64, bool), stream-error>

  • +

    subscribe-read

    +

    Create a pollable which will resolve once either the specified stream has bytes +available to read or the other end of the stream has been closed.

    +
    Params
    + +
    Results
    + +

    drop-input-stream

    Dispose of the specified input-stream, after which it may no longer be used.

    @@ -119,6 +169,18 @@
    Results
  • result0: result<(u64, bool), stream-error>

  • +

    subscribe

    +

    Create a pollable which will resolve once either the specified stream is ready +to accept bytes or the other end of the stream has been closed.

    +
    Params
    + +
    Results
    + +

    drop-output-stream

    Dispose of the specified output-stream, after which it may no longer be used.

    diff --git a/proposals/io/wasi-io.md b/proposals/io/wasi-io.md index 6c09ae412..602c22781 100644 --- a/proposals/io/wasi-io.md +++ b/proposals/io/wasi-io.md @@ -1,7 +1,60 @@ +# Import interface `wasi-poll` + +## Types + +## `pollable`: `u32` + +A "pollable" handle. + +This is conceptually represents a `stream<_, _>`, or in other words, +a stream that one can wait on, repeatedly, but which does not itself +produce any data. It's temporary scaffolding until component-model's +async features are ready. + +And at present, it is a `u32` instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready. + +`pollable` lifetimes are not automatically managed. Users must ensure +that they do not outlive the resource they reference. + +Size: 4, Alignment: 4 + +## Functions + +---- + +#### `poll-oneoff` + +Poll for completion on a set of pollables. + +The "oneoff" in the name refers to the fact that this function must do a +linear scan through the entire list of subscriptions, which may be +inefficient if the number is large and the same subscriptions are used +many times. In the future, it may be accompanied by an API similar to +Linux's `epoll` which allows sets of subscriptions to be registered and +made efficiently reusable. + +Note that the return type would ideally be `list`, but that would +be more difficult to polyfill given the current state of `wit-bindgen`. +See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 +for details. For now, we use zero to mean "not ready" and non-zero to +mean "ready". +##### Params + +- `in`: list<[`pollable`](#pollable)> +##### Results + +- `result0`: list<`u8`> + # Import interface `wasi-io` ## Types +## `pollable`: [`pollable`](#pollable) + + +Size: 4, Alignment: 4 + ## `stream-error`: record An error type returned from a stream operation. Currently this @@ -95,6 +148,19 @@ value will be at most `len`; it may be less. ---- +#### `subscribe-read` + +Create a `pollable` which will resolve once either the specified stream has bytes +available to read or the other end of the stream has been closed. +##### Params + +- `this`: [`input-stream`](#input_stream) +##### Results + +- `result0`: [`pollable`](#pollable) + +---- + #### `drop-input-stream` Dispose of the specified `input-stream`, after which it may no longer @@ -154,6 +220,19 @@ than `len`. ---- +#### `subscribe` + +Create a `pollable` which will resolve once either the specified stream is ready +to accept bytes or the other end of the stream has been closed. +##### Params + +- `this`: [`output-stream`](#output_stream) +##### Results + +- `result0`: [`pollable`](#pollable) + +---- + #### `drop-output-stream` Dispose of the specified `output-stream`, after which it may no longer diff --git a/proposals/io/wit/wasi-io.wit.md b/proposals/io/wit/wasi-io.wit.md index 8eb089528..eeee465e9 100644 --- a/proposals/io/wit/wasi-io.wit.md +++ b/proposals/io/wit/wasi-io.wit.md @@ -9,6 +9,11 @@ default interface wasi-io { ``` +## Imports +```wit +use pkg.wasi-poll.{pollable} +``` + ## `stream-error` ```wit /// An error type returned from a stream operation. Currently this @@ -78,6 +83,13 @@ type input-stream = u32 ) -> result, stream-error> ``` +## `subscribe` +```wit +/// Create a `pollable` which will resolve once either the specified stream has bytes +/// available to read or the other end of the stream has been closed. +subscribe-read: func(this: input-stream) -> pollable +``` + # `drop-input-stream` ```wit /// Dispose of the specified `input-stream`, after which it may no longer @@ -157,6 +169,13 @@ type output-stream = u32 ) -> result ``` +# `subscribe` +```wit +/// Create a `pollable` which will resolve once either the specified stream is ready +/// to accept bytes or the other end of the stream has been closed. +subscribe: func(this: output-stream) -> pollable +``` + # `drop-output-stream` ```wit /// Dispose of the specified `output-stream`, after which it may no longer From 10e9e7237a6342078e57c6aa695aabf2aef2831d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 8 Feb 2023 05:18:36 -0800 Subject: [PATCH 1022/1772] Add a polling interface for monotonic clocks. (#34) The new wasi-poll API has a `pollable` type. Add subscribe methods to the monotonic clock types to allow polling for timeouts. This adds a dependency on wasi-io, and is currently implemented in the repository in a low-tech way, which allows the generated documentation to work, though it's likely to evolve. --- proposals/clocks/.github/workflows/main.yml | 1 + proposals/clocks/wasi-clocks.html | 51 ++++++++++++++ proposals/clocks/wasi-clocks.md | 67 +++++++++++++++++++ .../clocks/wit/wasi-monotonic-clock.wit.md | 11 +++ 4 files changed, 130 insertions(+) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 8ca235c4f..a46630a4e 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -11,6 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-poll/75ace039473c05928cfd8e6df0243fc47ee9e8c9/wit/wasi-poll.wit.md > wit/wasi-poll.wit.md - uses: WebAssembly/wit-abi-up-to-date@v10 with: wit-abi-tag: wit-abi-0.8.0 diff --git a/proposals/clocks/wasi-clocks.html b/proposals/clocks/wasi-clocks.html index 088d63130..3c6b1950e 100644 --- a/proposals/clocks/wasi-clocks.html +++ b/proposals/clocks/wasi-clocks.html @@ -1,5 +1,43 @@ +

    Import interface wasi-poll

    +

    Types

    +

    pollable: u32

    +

    A "pollable" handle.

    +

    This is conceptually represents a stream<_, _>, or in other words, +a stream that one can wait on, repeatedly, but which does not itself +produce any data. It's temporary scaffolding until component-model's +async features are ready.

    +

    And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

    +

    pollable lifetimes are not automatically managed. Users must ensure +that they do not outlive the resource they reference.

    +

    Size: 4, Alignment: 4

    +

    Functions

    +
    +

    poll-oneoff

    +

    Poll for completion on a set of pollables.

    +

    The "oneoff" in the name refers to the fact that this function must do a +linear scan through the entire list of subscriptions, which may be +inefficient if the number is large and the same subscriptions are used +many times. In the future, it may be accompanied by an API similar to +Linux's epoll which allows sets of subscriptions to be registered and +made efficiently reusable.

    +

    Note that the return type would ideally be list<bool>, but that would +be more difficult to polyfill given the current state of wit-bindgen. +See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 +for details. For now, we use zero to mean "not ready" and non-zero to +mean "ready".

    +
    Params
    + +
    Results
    +
      +
    • result0: list<u8>
    • +

    Import interface wasi-monotonic-clock

    Types

    +

    pollable: pollable

    +

    Size: 4, Alignment: 4

    monotonic-clock: u32

    A monotonic clock is a clock which has an unspecified initial value, and successive reads of the clock will produce non-decreasing values.

    @@ -34,6 +72,19 @@
    Results
  • result0: instant

  • +

    subscribe

    +

    Create a pollable which will resolve once the specified time has been reached.

    +
    Params
    + +
    Results
    + +

    drop-monotonic-clock

    Dispose of the specified monotonic-clock, after which it may no longer be used.

    diff --git a/proposals/clocks/wasi-clocks.md b/proposals/clocks/wasi-clocks.md index cc357897d..5777462e6 100644 --- a/proposals/clocks/wasi-clocks.md +++ b/proposals/clocks/wasi-clocks.md @@ -1,7 +1,60 @@ +# Import interface `wasi-poll` + +## Types + +## `pollable`: `u32` + +A "pollable" handle. + +This is conceptually represents a `stream<_, _>`, or in other words, +a stream that one can wait on, repeatedly, but which does not itself +produce any data. It's temporary scaffolding until component-model's +async features are ready. + +And at present, it is a `u32` instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready. + +`pollable` lifetimes are not automatically managed. Users must ensure +that they do not outlive the resource they reference. + +Size: 4, Alignment: 4 + +## Functions + +---- + +#### `poll-oneoff` + +Poll for completion on a set of pollables. + +The "oneoff" in the name refers to the fact that this function must do a +linear scan through the entire list of subscriptions, which may be +inefficient if the number is large and the same subscriptions are used +many times. In the future, it may be accompanied by an API similar to +Linux's `epoll` which allows sets of subscriptions to be registered and +made efficiently reusable. + +Note that the return type would ideally be `list`, but that would +be more difficult to polyfill given the current state of `wit-bindgen`. +See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 +for details. For now, we use zero to mean "not ready" and non-zero to +mean "ready". +##### Params + +- `in`: list<[`pollable`](#pollable)> +##### Results + +- `result0`: list<`u8`> + # Import interface `wasi-monotonic-clock` ## Types +## `pollable`: [`pollable`](#pollable) + + +Size: 4, Alignment: 4 + ## `monotonic-clock`: `u32` A monotonic clock is a clock which has an unspecified initial value, and @@ -48,6 +101,20 @@ Query the resolution of the clock. ---- +#### `subscribe` + +Create a `pollable` which will resolve once the specified time has been reached. +##### Params + +- `this`: [`monotonic-clock`](#monotonic_clock) +- `when`: [`instant`](#instant) +- `absolute`: `bool` +##### Results + +- `result0`: [`pollable`](#pollable) + +---- + #### `drop-monotonic-clock` Dispose of the specified `monotonic-clock`, after which it may no longer diff --git a/proposals/clocks/wit/wasi-monotonic-clock.wit.md b/proposals/clocks/wit/wasi-monotonic-clock.wit.md index 1cebb47c3..0279e67c1 100644 --- a/proposals/clocks/wit/wasi-monotonic-clock.wit.md +++ b/proposals/clocks/wit/wasi-monotonic-clock.wit.md @@ -10,6 +10,11 @@ default interface wasi-monotonic-clock { ``` +## Imports +```wit +use pkg.wasi-poll.{pollable} +``` + ## `instant` ```wit /// A timestamp in nanoseconds. @@ -41,6 +46,12 @@ now: func(this: monotonic-clock) -> instant resolution: func(this: monotonic-clock) -> instant ``` +## `subscribe` +```wit +/// Create a `pollable` which will resolve once the specified time has been reached. +subscribe: func(this: monotonic-clock, when: instant, absolute: bool) -> pollable +``` + ## `drop-monotonic-clock` ```wit /// Dispose of the specified `monotonic-clock`, after which it may no longer From 284559fac93c038be356522cb9a0a16feb07e804 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 8 Feb 2023 11:03:57 -0800 Subject: [PATCH 1023/1772] Populate the table of contents in README.md. (#21) * Populate the table of contents in README.md. Fixes #16. --- proposals/io/README.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/proposals/io/README.md b/proposals/io/README.md index dc932796a..38ffbbcdb 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -24,14 +24,13 @@ We anticipate it will involve ensuring it works well for streaming files, socket - [Goals [or Motivating Use Cases, or Scenarios]](#goals-or-motivating-use-cases-or-scenarios) - [Non-goals](#non-goals) - [API walk-through](#api-walk-through) - - [Use case 1](#use-case-1) - - [Use case 2](#use-case-2) + - [Use case: Copying from input to output using `read`/`write`](#use-case-copying-from-input-to-output-using-readwrite) + - [Use case: copying from input to output using `splice`](#use-case-copying-from-input-to-output-using-splice) + - [Use case: copying from input to output using `forward`](#use-case-copying-from-input-to-output-using-forward) - [Detailed design discussion](#detailed-design-discussion) - - [[Tricky design choice 1]](#tricky-design-choice-1) - - [[Tricky design choice 2]](#tricky-design-choice-2) -- [Considered alternatives](#considered-alternatives) - - [[Alternative 1]](#alternative-1) - - [[Alternative 2]](#alternative-2) + - [Should we have support for non-blocking read/write?](#should-we-have-support-for-non-blocking-read-write) + - [Why do read/write use u64 sizes?[Tricky design choice 2]](#why-do-read-write-use-u64-sizes) + - [Why have a `forward` function when you can just `splice` in a loop?](#why-have-a-forward-function-when-you-can-just-splice-in-a-loop) - [Stakeholder Interest & Feedback](#stakeholder-interest--feedback) - [References & acknowledgements](#references--acknowledgements) @@ -56,7 +55,7 @@ types, `input-stream`, and `output-stream`, which support `read` and ### API walk-through -#### Copying from input to output using `read`/`write`: +#### Use Case: copying from input to output using `read`/`write` ```rust= fn copy_data(input: InputStream, output: OutputStream) -> Result<(), StreamError> { @@ -77,7 +76,7 @@ types, `input-stream`, and `output-stream`, which support `read` and } ``` -#### Copying from input to output using `splice`: +#### Use case: copying from input to output using `splice` ```rust= fn copy_data(input: InputStream, output: OutputStream) -> Result<(), StreamError> { @@ -92,7 +91,7 @@ types, `input-stream`, and `output-stream`, which support `read` and } ``` -#### Copying from input to output using `forward`: +#### Use case: opying from input to output using `forward` ```rust= fn copy_data(input: InputStream, output: OutputStream) -> Result<(), StreamError> { From 6a21b2bf6a59ca4e8cf320b9cfd401539dfe6bfc Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 8 Feb 2023 11:05:48 -0800 Subject: [PATCH 1024/1772] Fix typos in README.md. --- proposals/io/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/io/README.md b/proposals/io/README.md index 38ffbbcdb..b143bd69a 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -24,7 +24,7 @@ We anticipate it will involve ensuring it works well for streaming files, socket - [Goals [or Motivating Use Cases, or Scenarios]](#goals-or-motivating-use-cases-or-scenarios) - [Non-goals](#non-goals) - [API walk-through](#api-walk-through) - - [Use case: Copying from input to output using `read`/`write`](#use-case-copying-from-input-to-output-using-readwrite) + - [Use case: copying from input to output using `read`/`write`](#use-case-copying-from-input-to-output-using-readwrite) - [Use case: copying from input to output using `splice`](#use-case-copying-from-input-to-output-using-splice) - [Use case: copying from input to output using `forward`](#use-case-copying-from-input-to-output-using-forward) - [Detailed design discussion](#detailed-design-discussion) @@ -91,7 +91,7 @@ types, `input-stream`, and `output-stream`, which support `read` and } ``` -#### Use case: opying from input to output using `forward` +#### Use case: copying from input to output using `forward` ```rust= fn copy_data(input: InputStream, output: OutputStream) -> Result<(), StreamError> { From 944a87cf06744a9eb17531c8364437e5b7094be5 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 8 Feb 2023 11:23:04 -0800 Subject: [PATCH 1025/1772] Revise the documentation for `sync` etc. and `nonblock`. (#88) * Revise the documentation for `sync` etc. and `nonblock`. sync, dsync, and rsync refer to specific types of data integrity defined by POSIX, however at this time these guarantees have not been evaluated in the context of implementations on non-POSIX filesystem backends. Add caveats to these flags accorrdingly. Also, most Unix filesystems don't implement nonblock mode for files, so add wording mentioning that nonblock may not actually make things non-blocking. And update references to `wouldblock` to say `again`, as wasi-filesystem doesn't have a separate `wouldblock` error code. --- proposals/filesystem/wasi-filesystem.html | 41 +++++++++++------ proposals/filesystem/wasi-filesystem.md | 45 +++++++++++++------ .../filesystem/wit/wasi-filesystem.wit.md | 41 ++++++++++++----- 3 files changed, 90 insertions(+), 37 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.html b/proposals/filesystem/wasi-filesystem.html index d66fdc5bb..030d53ad9 100644 --- a/proposals/filesystem/wasi-filesystem.html +++ b/proposals/filesystem/wasi-filesystem.html @@ -366,26 +366,41 @@

    Record Fields

    Bit: 1

  • -

    dsync:

    -

    Write according to synchronized I/O data integrity completion. Only the -data stored in the file is synchronized. +

    nonblock:

    +

    Requests non-blocking operation.

    +

    When this flag is enabled, functions may return immediately with an +errno::again error code in situations where they would otherwise +block. However, this non-blocking behavior is not required. +Implementations are permitted to ignore this flag and block. Bit: 2

  • -

    nonblock:

    -

    Non-blocking mode. +

    sync:

    +

    Request that writes be performed according to synchronized I/O file +integrity completion. The data stored in the file and the file's +metadata are synchronized.

    +

    The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement. Bit: 3

  • -

    rsync:

    -

    Synchronized read I/O operations. +

    dsync:

    +

    Request that writes be performed according to synchronized I/O data +integrity completion. Only the data stored in the file is +synchronized.

    +

    The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement. Bit: 4

  • -

    sync:

    -

    Write according to synchronized I/O file integrity completion. In -addition to synchronizing the data stored in the file, the -implementation may also synchronously update the file's metadata. +

    rsync:

    +

    Requests that reads be performed at the same level of integrety +requested for writes.

    +

    The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement. Bit: 5

  • @@ -855,7 +870,7 @@

    errno::again if the lock cannot be acquired.

    Not all filesystems support locking; on filesystems which don't support locking, this function returns errno::notsup.

    Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

    @@ -880,7 +895,7 @@

    errno::again if the lock cannot be acquired.

    Not all filesystems support locking; on filesystems which don't support locking, this function returns errno::notsup.

    Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

    diff --git a/proposals/filesystem/wasi-filesystem.md b/proposals/filesystem/wasi-filesystem.md index 0363d70dd..8b9743ffc 100644 --- a/proposals/filesystem/wasi-filesystem.md +++ b/proposals/filesystem/wasi-filesystem.md @@ -403,27 +403,46 @@ Size: 1, Alignment: 1 Write mode: Data can be written to. Bit: 1 -- [`dsync`](#descriptor_flags.dsync): +- [`nonblock`](#descriptor_flags.nonblock): + + Requests non-blocking operation. - Write according to synchronized I/O data integrity completion. Only the - data stored in the file is synchronized. + When this flag is enabled, functions may return immediately with an + `errno::again` error code in situations where they would otherwise + block. However, this non-blocking behavior is not required. + Implementations are permitted to ignore this flag and block. Bit: 2 -- [`nonblock`](#descriptor_flags.nonblock): +- [`sync`](#descriptor_flags.sync): + + Request that writes be performed according to synchronized I/O file + integrity completion. The data stored in the file and the file's + metadata are synchronized. - Non-blocking mode. + The precise semantics of this operation have not yet been defined for + WASI. At this time, it should be interpreted as a request, and not a + requirement. Bit: 3 -- [`rsync`](#descriptor_flags.rsync): +- [`dsync`](#descriptor_flags.dsync): + + Request that writes be performed according to synchronized I/O data + integrity completion. Only the data stored in the file is + synchronized. - Synchronized read I/O operations. + The precise semantics of this operation have not yet been defined for + WASI. At this time, it should be interpreted as a request, and not a + requirement. Bit: 4 -- [`sync`](#descriptor_flags.sync): +- [`rsync`](#descriptor_flags.rsync): + + Requests that reads be performed at the same level of integrety + requested for writes. - Write according to synchronized I/O file integrity completion. In - addition to synchronizing the data stored in the file, the - implementation may also synchronously update the file's metadata. + The precise semantics of this operation have not yet been defined for + WASI. At this time, it should be interpreted as a request, and not a + requirement. Bit: 5 ## `descriptor`: `u32` @@ -985,7 +1004,7 @@ by other programs that don't hold the lock. It is unspecified how shared locks interact with locks acquired by non-WASI programs. -This function returns `errno::wouldblock` if the lock cannot be acquired. +This function returns `errno::again` if the lock cannot be acquired. Not all filesystems support locking; on filesystems which don't support locking, this function returns `errno::notsup`. @@ -1018,7 +1037,7 @@ It is unspecified whether this function succeeds if the file descriptor is not opened for writing. It is unspecified how exclusive locks interact with locks acquired by non-WASI programs. -This function returns `errno::wouldblock` if the lock cannot be acquired. +This function returns `errno::again` if the lock cannot be acquired. Not all filesystems support locking; on filesystems which don't support locking, this function returns `errno::notsup`. diff --git a/proposals/filesystem/wit/wasi-filesystem.wit.md b/proposals/filesystem/wit/wasi-filesystem.wit.md index 07420678a..34e3bd6b6 100644 --- a/proposals/filesystem/wit/wasi-filesystem.wit.md +++ b/proposals/filesystem/wit/wasi-filesystem.wit.md @@ -57,17 +57,36 @@ flags descriptor-flags { read, /// Write mode: Data can be written to. write, - /// Write according to synchronized I/O data integrity completion. Only the - /// data stored in the file is synchronized. - dsync, - /// Non-blocking mode. + /// Requests non-blocking operation. + /// + /// When this flag is enabled, functions may return immediately with an + /// `errno::again` error code in situations where they would otherwise + /// block. However, this non-blocking behavior is not required. + /// Implementations are permitted to ignore this flag and block. nonblock, - /// Synchronized read I/O operations. - rsync, - /// Write according to synchronized I/O file integrity completion. In - /// addition to synchronizing the data stored in the file, the - /// implementation may also synchronously update the file's metadata. + /// Request that writes be performed according to synchronized I/O file + /// integrity completion. The data stored in the file and the file's + /// metadata are synchronized. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. sync, + /// Request that writes be performed according to synchronized I/O data + /// integrity completion. Only the data stored in the file is + /// synchronized. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + dsync, + /// Requests that reads be performed at the same level of integrety + /// requested for writes. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + rsync, } ``` @@ -722,7 +741,7 @@ lock-exclusive: func(this: descriptor) -> result<_, errno> /// It is unspecified how shared locks interact with locks acquired by /// non-WASI programs. /// -/// This function returns `errno::wouldblock` if the lock cannot be acquired. +/// This function returns `errno::again` if the lock cannot be acquired. /// /// Not all filesystems support locking; on filesystems which don't support /// locking, this function returns `errno::notsup`. @@ -749,7 +768,7 @@ try-lock-shared: func(this: descriptor) -> result<_, errno> /// is not opened for writing. It is unspecified how exclusive locks interact /// with locks acquired by non-WASI programs. /// -/// This function returns `errno::wouldblock` if the lock cannot be acquired. +/// This function returns `errno::again` if the lock cannot be acquired. /// /// Not all filesystems support locking; on filesystems which don't support /// locking, this function returns `errno::notsup`. From 6a117dc01a2ab27bc0a51aa380587cd6966c7607 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 8 Feb 2023 12:18:13 -0800 Subject: [PATCH 1026/1772] Document that `fsync` on a readonly file succeeds. (#89) On POSIX platforms, `fsync` on a readonly file succeeds. On Windows, `FlushFileBuffers` fails on a readonly file, but implementations can be made to handle the error. --- proposals/filesystem/wasi-filesystem.html | 4 ++++ proposals/filesystem/wasi-filesystem.md | 6 ++++++ proposals/filesystem/wit/wasi-filesystem.wit.md | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/proposals/filesystem/wasi-filesystem.html b/proposals/filesystem/wasi-filesystem.html index 030d53ad9..ea3910c31 100644 --- a/proposals/filesystem/wasi-filesystem.html +++ b/proposals/filesystem/wasi-filesystem.html @@ -469,6 +469,8 @@
    Results

    datasync

    Synchronize the data of a file to disk.

    +

    This function succeeds with no effect if the file descriptor is not +opened for writing.

    Note: This is similar to fdatasync in POSIX.

    Params
      @@ -599,6 +601,8 @@
      Results

      sync

      Synchronize the data and metadata of a file to disk.

      +

      This function succeeds with no effect if the file descriptor is not +opened for writing.

      Note: This is similar to fsync in POSIX.

      Params
        diff --git a/proposals/filesystem/wasi-filesystem.md b/proposals/filesystem/wasi-filesystem.md index 8b9743ffc..dc354899c 100644 --- a/proposals/filesystem/wasi-filesystem.md +++ b/proposals/filesystem/wasi-filesystem.md @@ -523,6 +523,9 @@ This is similar to `posix_fadvise` in POSIX. Synchronize the data of a file to disk. +This function succeeds with no effect if the file descriptor is not +opened for writing. + Note: This is similar to `fdatasync` in POSIX. ##### Params @@ -677,6 +680,9 @@ directory. Synchronize the data and metadata of a file to disk. +This function succeeds with no effect if the file descriptor is not +opened for writing. + Note: This is similar to `fsync` in POSIX. ##### Params diff --git a/proposals/filesystem/wit/wasi-filesystem.wit.md b/proposals/filesystem/wit/wasi-filesystem.wit.md index 34e3bd6b6..7303b72f3 100644 --- a/proposals/filesystem/wit/wasi-filesystem.wit.md +++ b/proposals/filesystem/wit/wasi-filesystem.wit.md @@ -344,6 +344,9 @@ fadvise: func( ```wit /// Synchronize the data of a file to disk. /// +/// This function succeeds with no effect if the file descriptor is not +/// opened for writing. +/// /// Note: This is similar to `fdatasync` in POSIX. datasync: func(this: descriptor) -> result<_, errno> ``` @@ -456,6 +459,9 @@ readdir: func(this: descriptor) -> stream ```wit /// Synchronize the data and metadata of a file to disk. /// +/// This function succeeds with no effect if the file descriptor is not +/// opened for writing. +/// /// Note: This is similar to `fsync` in POSIX. sync: func(this: descriptor) -> result<_, errno> ``` From 5c0edc08cf6c0146da70d1e5c89d18d7f18e92f4 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Fri, 10 Feb 2023 11:43:17 -0600 Subject: [PATCH 1027/1772] initial placeholder commit --- proposals/http/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 proposals/http/README.md diff --git a/proposals/http/README.md b/proposals/http/README.md new file mode 100644 index 000000000..2d9e040ce --- /dev/null +++ b/proposals/http/README.md @@ -0,0 +1,3 @@ +# WASI HTTP + +(This is a placeholder so there can be a PR to fill in the contents.) From 6c4369d021f8bf143ab6fd54841ed076868f2d26 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 10 Feb 2023 14:04:58 -0800 Subject: [PATCH 1028/1772] Remove stale files. (#3) Delete files that I included by accident in #2. The real files are named `wasi-proposal-template.*`. --- proposals/sockets/proposal-template.html | 24 ------------------ proposals/sockets/proposal-template.md | 32 ------------------------ 2 files changed, 56 deletions(-) delete mode 100644 proposals/sockets/proposal-template.html delete mode 100644 proposals/sockets/proposal-template.md diff --git a/proposals/sockets/proposal-template.html b/proposals/sockets/proposal-template.html deleted file mode 100644 index 0db3b9a4e..000000000 --- a/proposals/sockets/proposal-template.html +++ /dev/null @@ -1,24 +0,0 @@ -

        Import interface proposal-interface-name

        -

        Types

        -

        api-type-one: record

        -

        Short description

        -

        Explanation for developers using the API.

        -

        Size: 16, Alignment: 8

        -

        Record Fields

        - -

        Functions

        -
        -

        api-function-one

        -

        Short description

        -

        Explanation for developers using the API.

        -
        Results
        - diff --git a/proposals/sockets/proposal-template.md b/proposals/sockets/proposal-template.md deleted file mode 100644 index da2d6ca21..000000000 --- a/proposals/sockets/proposal-template.md +++ /dev/null @@ -1,32 +0,0 @@ -# Import interface `proposal-interface-name` - -## Types - -## `api-type-one`: record - -Short description - -Explanation for developers using the API. - -Size: 16, Alignment: 8 - -### Record Fields - -- [`property1`](#api_type_one.property1): `u64` - - -- [`property2`](#api_type_one.property2): `string` - - -## Functions - ----- - -#### `api-function-one` - -Short description - -Explanation for developers using the API. -##### Results - -- [`api-type-one`](#api_type_one) From 539c581636e5f04128573bd4a12e10ddeef43fdc Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 10 Feb 2023 14:05:15 -0800 Subject: [PATCH 1029/1772] Update to the latest wit-abi tag (#4) This updates to the latest wit-bindgen, which contains fixes for no_std mode in Rust guests. --- proposals/sockets/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index 2f9000022..8ca235c4f 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -13,4 +13,4 @@ jobs: - uses: actions/checkout@v2 - uses: WebAssembly/wit-abi-up-to-date@v10 with: - wit-abi-tag: wit-abi-0.7.0 + wit-abi-tag: wit-abi-0.8.0 From 4fdc04d9f6e757f3833607ca6eada4801e6c71b6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 10 Feb 2023 14:05:28 -0800 Subject: [PATCH 1030/1772] Fix a typo in a comment. (#5) --- proposals/sockets/wit/world.wit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit/world.wit.md b/proposals/sockets/wit/world.wit.md index f0f8611a8..b2f0fb0ac 100644 --- a/proposals/sockets/wit/world.wit.md +++ b/proposals/sockets/wit/world.wit.md @@ -1,5 +1,5 @@ This file contains a world that imports all interfaces in this proposal. Its -primary purpose is to allow unified documentation to be easiy generated for +primary purpose is to allow unified documentation to be easily generated for the whole proposal. Proposals should edit replace the import below (and this sentence) with imports From 22c42a1ee34c440d033bf04f1249c1636a950c0a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 10 Feb 2023 14:09:26 -0800 Subject: [PATCH 1031/1772] Add support for readonly directories. (#91) Add a `mutate-directory` flag to `descriptor-flags`, and make it a requirement for any filesystem-mutating operation. POSIX compatibility may be provided by setting `mutate-directory` whenever performing a readonly `open-at`. When this flag is unset on a directory descriptor, the descriptor acts as a readonly directory view. This is the most notable use case that the "rights" system in preview1 was useful for. --- proposals/filesystem/wasi-filesystem.html | 21 ++++++++++++++- proposals/filesystem/wasi-filesystem.md | 26 ++++++++++++++++++- .../filesystem/wit/wasi-filesystem.wit.md | 23 +++++++++++++++- 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/wasi-filesystem.html b/proposals/filesystem/wasi-filesystem.html index ea3910c31..ceda7fcc6 100644 --- a/proposals/filesystem/wasi-filesystem.html +++ b/proposals/filesystem/wasi-filesystem.html @@ -403,6 +403,17 @@

        Record Fields

        requirement. Bit: 5

        +
      • +

        mutate-directory:

        +

        Mutating directories mode: Directory contents may be mutated.

        +

        When this flag is unset on a descriptor, operations using the +descriptor which would create, rename, delete, modify the data or +metadata of filesystem objects, or obtain another handle which +would permit any of those, shall fail with errno::rofs if +they would otherwise succeed.

        +

        This may only be set on directories. +Bit: 6

        +

      descriptor: u32

      A descriptor is a reference to a filesystem object, which may be a file, @@ -513,7 +524,8 @@

      Results

    set-flags

    -

    Set flags associated with a descriptor.

    +

    Set status flags associated with a descriptor.

    +

    This function may only change the append and nonblock flags.

    Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

    Note: This was called fd_fdstat_set_flags in earlier versions of WASI.

    Params
    @@ -694,6 +706,13 @@

    open-at +

    If flags contains descriptor-flags::mutate-directory, and the base +descriptor doesn't have descriptor-flags::mutate-directory set, +open-at fails with errno::rofs.

    +

    If flags contains write or append, or o-flags contains trunc +or create, and the base descriptor doesn't have +descriptor-flags::mutate-directory set, open-at fails with +errno::rofs.

    Note: This is similar to openat in POSIX.

    Params
      diff --git a/proposals/filesystem/wasi-filesystem.md b/proposals/filesystem/wasi-filesystem.md index dc354899c..7dc30acca 100644 --- a/proposals/filesystem/wasi-filesystem.md +++ b/proposals/filesystem/wasi-filesystem.md @@ -445,6 +445,19 @@ Size: 1, Alignment: 1 requirement. Bit: 5 +- [`mutate-directory`](#descriptor_flags.mutate_directory): + + Mutating directories mode: Directory contents may be mutated. + + When this flag is unset on a descriptor, operations using the + descriptor which would create, rename, delete, modify the data or + metadata of filesystem objects, or obtain another handle which + would permit any of those, shall fail with `errno::rofs` if + they would otherwise succeed. + + This may only be set on directories. + Bit: 6 + ## `descriptor`: `u32` A descriptor is a reference to a filesystem object, which may be a file, @@ -576,7 +589,9 @@ from `fdstat_get` in earlier versions of WASI. #### `set-flags` -Set flags associated with a descriptor. +Set status flags associated with a descriptor. + +This function may only change the `append` and `nonblock` flags. Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. @@ -790,6 +805,15 @@ from depending on making assumptions about indexes, since this is error-prone in multi-threaded contexts. The returned descriptor is guaranteed to be less than 2**31. +If `flags` contains `descriptor-flags::mutate-directory`, and the base +descriptor doesn't have `descriptor-flags::mutate-directory` set, +`open-at` fails with `errno::rofs`. + +If `flags` contains `write` or `append`, or `o-flags` contains `trunc` +or `create`, and the base descriptor doesn't have +`descriptor-flags::mutate-directory` set, `open-at` fails with +`errno::rofs`. + Note: This is similar to `openat` in POSIX. ##### Params diff --git a/proposals/filesystem/wit/wasi-filesystem.wit.md b/proposals/filesystem/wit/wasi-filesystem.wit.md index 7303b72f3..460cfb91a 100644 --- a/proposals/filesystem/wit/wasi-filesystem.wit.md +++ b/proposals/filesystem/wit/wasi-filesystem.wit.md @@ -87,6 +87,16 @@ flags descriptor-flags { /// WASI. At this time, it should be interpreted as a request, and not a /// requirement. rsync, + /// Mutating directories mode: Directory contents may be mutated. + /// + /// When this flag is unset on a descriptor, operations using the + /// descriptor which would create, rename, delete, modify the data or + /// metadata of filesystem objects, or obtain another handle which + /// would permit any of those, shall fail with `errno::rofs` if + /// they would otherwise succeed. + /// + /// This may only be set on directories. + mutate-directory, } ``` @@ -379,7 +389,9 @@ datasync: func(this: descriptor) -> result<_, errno> ## `set-flags` ```wit -/// Set flags associated with a descriptor. +/// Set status flags associated with a descriptor. +/// +/// This function may only change the `append` and `nonblock` flags. /// /// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. /// @@ -552,6 +564,15 @@ link-at: func( /// error-prone in multi-threaded contexts. The returned descriptor is /// guaranteed to be less than 2**31. /// +/// If `flags` contains `descriptor-flags::mutate-directory`, and the base +/// descriptor doesn't have `descriptor-flags::mutate-directory` set, +/// `open-at` fails with `errno::rofs`. +/// +/// If `flags` contains `write` or `append`, or `o-flags` contains `trunc` +/// or `create`, and the base descriptor doesn't have +/// `descriptor-flags::mutate-directory` set, `open-at` fails with +/// `errno::rofs`. +/// /// Note: This is similar to `openat` in POSIX. open-at: func( this: descriptor, From 3881bf1a65893a072bfcf795fb9c7bd2aeb7af67 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Feb 2023 13:46:31 -0800 Subject: [PATCH 1032/1772] Exclude `.` and `..` from directory iteration. (#93) Add text excluding `.` and `..` from `readdir` directory iteration. In most use cases, they act as navigational mechanisms rather than meaningful contents of directories. Wasi-libc will be expected to re-add `.` and `..` when implementing the POSIX `readdir` interface. Fixes #90. --- proposals/filesystem/wasi-filesystem.html | 3 +++ proposals/filesystem/wasi-filesystem.md | 4 ++++ proposals/filesystem/wit/wasi-filesystem.wit.md | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/proposals/filesystem/wasi-filesystem.html b/proposals/filesystem/wasi-filesystem.html index ceda7fcc6..1e1839bfa 100644 --- a/proposals/filesystem/wasi-filesystem.html +++ b/proposals/filesystem/wasi-filesystem.html @@ -600,6 +600,9 @@
      Results

      readdir

      Read directory entries from a directory.

      +

      On filesystems where directories contain entries referring to themselves +and their parents, often named . and .. respectively, these entries +are omitted.

      This always returns a new stream which starts at the beginning of the directory.

      Params
      diff --git a/proposals/filesystem/wasi-filesystem.md b/proposals/filesystem/wasi-filesystem.md index 7dc30acca..ead8b788f 100644 --- a/proposals/filesystem/wasi-filesystem.md +++ b/proposals/filesystem/wasi-filesystem.md @@ -680,6 +680,10 @@ Note: This is similar to `pwrite` in POSIX. Read directory entries from a directory. +On filesystems where directories contain entries referring to themselves +and their parents, often named `.` and `..` respectively, these entries +are omitted. + This always returns a new stream which starts at the beginning of the directory. ##### Params diff --git a/proposals/filesystem/wit/wasi-filesystem.wit.md b/proposals/filesystem/wit/wasi-filesystem.wit.md index 460cfb91a..9c704eb63 100644 --- a/proposals/filesystem/wit/wasi-filesystem.wit.md +++ b/proposals/filesystem/wit/wasi-filesystem.wit.md @@ -462,6 +462,10 @@ pwrite: func( ```wit /// Read directory entries from a directory. /// +/// On filesystems where directories contain entries referring to themselves +/// and their parents, often named `.` and `..` respectively, these entries +/// are omitted. +/// /// This always returns a new stream which starts at the beginning of the /// directory. readdir: func(this: descriptor) -> stream From 1eac1a95f5e10720ce18b9debe1657483af72015 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Feb 2023 13:47:03 -0800 Subject: [PATCH 1033/1772] Import `datetime` and the stream types from wasi-clocks and wasi-io. (#95) * Import `datetime` and the stream types from wasi-clocks and wasi-io. Add `read-via-stream`, `write-via-stream`, and `append-via-stream` methods to read from, write to, and append to files. And use the wasi-clocks datetime time for filesystem timestamps. This uses the same low-tech dependency mechanism as wasi-clocks and wasi-io are currently using to depend on wasi-poll, which will likely evolve. * Fix the return type of `readdir`. It will eventually be a `stream`, but for now we're using a `dir-entry-stream` resource as a pseudo-stream. --- .../filesystem/.github/workflows/main.yml | 3 + proposals/filesystem/wasi-filesystem.html | 421 +++++++++++--- proposals/filesystem/wasi-filesystem.md | 514 +++++++++++++++--- .../filesystem/wit/wasi-filesystem.wit.md | 53 +- 4 files changed, 858 insertions(+), 133 deletions(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index 8ca235c4f..29f8efee3 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -11,6 +11,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-poll/75ace039473c05928cfd8e6df0243fc47ee9e8c9/wit/wasi-poll.wit.md > wit/wasi-poll.wit.md + - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-io/078a05fdc786b7f4ca7217ac6c0dcfa694c31138/wit/wasi-io.wit.md > wit/wasi-io.wit.md + - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-clocks/c288ba066db7907028b92e8efa0fbd22f6f25cf7/wit/wasi-wall-clock.wit.md > wit/wasi-wall-clock.wit.md - uses: WebAssembly/wit-abi-up-to-date@v10 with: wit-abi-tag: wit-abi-0.8.0 diff --git a/proposals/filesystem/wasi-filesystem.html b/proposals/filesystem/wasi-filesystem.html index 1e1839bfa..2a319fe2e 100644 --- a/proposals/filesystem/wasi-filesystem.html +++ b/proposals/filesystem/wasi-filesystem.html @@ -1,5 +1,260 @@ +

      Import interface wasi-poll

      +

      Types

      +

      pollable: u32

      +

      A "pollable" handle.

      +

      This is conceptually represents a stream<_, _>, or in other words, +a stream that one can wait on, repeatedly, but which does not itself +produce any data. It's temporary scaffolding until component-model's +async features are ready.

      +

      And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

      +

      pollable lifetimes are not automatically managed. Users must ensure +that they do not outlive the resource they reference.

      +

      Size: 4, Alignment: 4

      +

      Functions

      +
      +

      poll-oneoff

      +

      Poll for completion on a set of pollables.

      +

      The "oneoff" in the name refers to the fact that this function must do a +linear scan through the entire list of subscriptions, which may be +inefficient if the number is large and the same subscriptions are used +many times. In the future, it may be accompanied by an API similar to +Linux's epoll which allows sets of subscriptions to be registered and +made efficiently reusable.

      +

      Note that the return type would ideally be list<bool>, but that would +be more difficult to polyfill given the current state of wit-bindgen. +See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 +for details. For now, we use zero to mean "not ready" and non-zero to +mean "ready".

      +
      Params
      + +
      Results
      +
        +
      • result0: list<u8>
      • +
      +

      Import interface wasi-io

      +

      Types

      +

      pollable: pollable

      +

      Size: 4, Alignment: 4

      +

      stream-error: record

      +

      An error type returned from a stream operation. Currently this +doesn't provide any additional information.

      +

      Size: 0, Alignment: 1

      +

      Record Fields

      +

      output-stream: u32

      +

      An output bytestream. In the future, this will be replaced by handle +types.

      +

      This conceptually represents a stream<u8, _>. It's temporary +scaffolding until component-model's async features are ready.

      +

      And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

      +

      Size: 4, Alignment: 4

      +

      input-stream: u32

      +

      An input bytestream. In the future, this will be replaced by handle +types.

      +

      This conceptually represents a stream<u8, _>. It's temporary +scaffolding until component-model's async features are ready.

      +

      And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

      +

      Size: 4, Alignment: 4

      +

      Functions

      +
      +

      read

      +

      Read bytes from a stream.

      +

      This function returns a list of bytes containing the data that was +read, along with a bool indicating whether the end of the stream +was reached. The returned list will contain up to len bytes; it +may return fewer than requested, but not more.

      +

      Once a stream has reached the end, subsequent calls to read or +skip will always report end-of-stream rather than producing more +data.

      +

      If len is 0, it represents a request to read 0 bytes, which should +always succeed, assuming the stream hasn't reached its end yet, and +return an empty list.

      +

      The len here is a u64, but some callees may not be able to allocate +a buffer as large as that would imply. +FIXME: describe what happens if allocation fails.

      +
      Params
      + +
      Results
      + +
      +

      skip

      +

      Skip bytes from a stream.

      +

      This is similar to the read function, but avoids copying the +bytes into the instance.

      +

      Once a stream has reached the end, subsequent calls to read or +skip will always report end-of-stream rather than producing more +data.

      +

      This function returns the number of bytes skipped, along with a bool +indicating whether the end of the stream was reached. The returned +value will be at most len; it may be less.

      +
      Params
      + +
      Results
      + +
      +

      subscribe-read

      +

      Create a pollable which will resolve once either the specified stream has bytes +available to read or the other end of the stream has been closed.

      +
      Params
      + +
      Results
      + +
      +

      drop-input-stream

      +

      Dispose of the specified input-stream, after which it may no longer +be used.

      +
      Params
      + +
      +

      write

      +

      Write bytes to a stream.

      +

      This function returns a u64 indicating the number of bytes from +buf that were written; it may be less than the full list.

      +
      Params
      + +
      Results
      + +
      +

      write-zeroes

      +

      Write multiple zero bytes to a stream.

      +

      This function returns a u64 indicating the number of zero bytes +that were written; it may be less than len.

      +
      Params
      + +
      Results
      + +
      +

      splice

      +

      Read from one stream and write to another.

      +

      This function returns the number of bytes transferred; it may be less +than len.

      +
      Params
      + +
      Results
      + +
      +

      subscribe

      +

      Create a pollable which will resolve once either the specified stream is ready +to accept bytes or the other end of the stream has been closed.

      +
      Params
      + +
      Results
      + +
      +

      drop-output-stream

      +

      Dispose of the specified output-stream, after which it may no longer +be used.

      +
      Params
      + +

      Import interface wasi-wall-clock

      +

      Types

      +

      wall-clock: u32

      +

      A wall clock is a clock which measures the date and time according to some +external reference.

      +

      External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time.

      +

      It is intended for reporting the current date and time for humans.

      +

      Size: 4, Alignment: 4

      +

      datetime: record

      +

      A time and date in seconds plus nanoseconds.

      +

      Size: 16, Alignment: 8

      +

      Record Fields

      + +

      Functions

      +
      +

      now

      +

      Read the current value of the clock.

      +

      This clock is not monotonic, therefore calling this function repeatedly will +not necessarily produce a sequence of non-decreasing values.

      +

      The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, also +known as Unix Time.

      +

      The nanoseconds field of the output is always less than 1000000000.

      +
      Params
      + +
      Results
      + +
      +

      resolution

      +

      Query the resolution of the clock.

      +

      The nanoseconds field of the output is always less than 1000000000.

      +
      Params
      + +
      Results
      + +
      +

      drop-wall-clock

      +

      Dispose of the specified wall-clock, after which it may no longer +be used.

      +
      Params
      +

      Import interface wasi-filesystem

      Types

      +

      input-stream: input-stream

      +

      Size: 4, Alignment: 4

      +

      output-stream: output-stream

      +

      Size: 4, Alignment: 4

      +

      datetime: datetime

      +

      Size: 16, Alignment: 8

      o-flags: record

      Open flags used by open-at.

      Size: 1, Alignment: 1

      @@ -26,25 +281,6 @@

      Record Fields

      Bit: 3

    -

    new-timestamp: variant

    -

    When setting a timestamp, this gives the value to set it to.

    -

    Size: 16, Alignment: 8

    -

    Variant Cases

    -
      -
    • -

      no-change

      -

      Leave the timestamp set to its previous value.

      -
    • -
    • -

      now

      -

      Set the timestamp to the current time of the system clock associated -with the filesystem.

      -
    • -
    • -

      timestamp: u64

      -

      Set the timestamp to the given value.

      -
    • -

    mode: record

    Permissions mode used by open-at, change-file-permissions-at, and similar.

    @@ -309,46 +545,6 @@

    Record Fields

    The name of the object.

    -

    descriptor-stat: record

    -

    File attributes.

    -

    Note: This was called filestat in earlier versions of WASI.

    -

    Size: 64, Alignment: 8

    -

    Record Fields

    -
      -
    • -

      dev: device

      -

      Device ID of device containing the file.

      -
    • -
    • -

      ino: inode

      -

      File serial number.

      -
    • -
    • -

      type: descriptor-type

      -

      File type.

      -
    • -
    • -

      nlink: linkcount

      -

      Number of hard links to the file.

      -
    • -
    • -

      size: filesize

      -

      For regular files, the file size in bytes. For symbolic links, the length -in bytes of the pathname contained in the symbolic link.

      -
    • -
    • -

      atim: u64

      -

      Last data access timestamp.

      -
    • -
    • -

      mtim: u64

      -

      Last data modification timestamp.

      -
    • -
    • -

      ctim: u64

      -

      Last file status change timestamp.

      -
    • -

    descriptor-flags: record

    Descriptor flags.

    Note: This was called fdflags in earlier versions of WASI.

    @@ -356,12 +552,12 @@

    read:

    +

    read:

    Read mode: Data can be read. Bit: 0

  • -

    write:

    +

    write:

    Write mode: Data can be written to. Bit: 1

  • @@ -420,6 +616,65 @@

    des directory, named pipe, special file, or other object on which filesystem calls may be made.

    Size: 4, Alignment: 4

    +

    new-timestamp: variant

    +

    When setting a timestamp, this gives the value to set it to.

    +

    Size: 24, Alignment: 8

    +

    Variant Cases

    +
      +
    • +

      no-change

      +

      Leave the timestamp set to its previous value.

      +
    • +
    • +

      now

      +

      Set the timestamp to the current time of the system clock associated +with the filesystem.

      +
    • +
    • +

      timestamp: datetime

      +

      Set the timestamp to the given value.

      +
    • +
    +

    descriptor-stat: record

    +

    File attributes.

    +

    Note: This was called filestat in earlier versions of WASI.

    +

    Size: 88, Alignment: 8

    +

    Record Fields

    +
      +
    • +

      dev: device

      +

      Device ID of device containing the file.

      +
    • +
    • +

      ino: inode

      +

      File serial number.

      +
    • +
    • +

      type: descriptor-type

      +

      File type.

      +
    • +
    • +

      nlink: linkcount

      +

      Number of hard links to the file.

      +
    • +
    • +

      size: filesize

      +

      For regular files, the file size in bytes. For symbolic links, the length +in bytes of the pathname contained in the symbolic link.

      +
    • +
    • +

      atim: datetime

      +

      Last data access timestamp.

      +
    • +
    • +

      mtim: datetime

      +

      Last data modification timestamp.

      +
    • +
    • +

      ctim: datetime

      +

      Last file status change timestamp.

      +
    • +

    at-flags: record

    Flags determining the method of how paths are resolved.

    Size: 1, Alignment: 1

    @@ -463,6 +718,46 @@

    Enum Cases

    Functions


    +

    read-via-stream

    +

    Return a stream for reading from a file.

    +

    Note: This allows using read-stream, which is similar to read in POSIX.

    +
    Params
    + +
    Results
    + +
    +

    write-via-stream

    +

    Return a stream for writing to a file.

    +

    Note: This allows using write-stream, which is similar to write in POSIX.

    +
    Params
    + +
    Results
    + +
    +

    append-via-stream

    +

    Return a stream for appending to a file.

    +

    Note: This allows using write-stream, which is similar to write with +O_APPEND in in POSIX.

    +
    Params
    + +
    Results
    + +

    fadvise

    Provide file advisory information on a descriptor.

    This is similar to posix_fadvise in POSIX.

    @@ -611,7 +906,7 @@
    Params
    Results

    sync

    @@ -823,7 +1118,7 @@

    read on a directory implies readability and searchability, and execute is not valid for directories.

    Note: This is similar to fchmodat in POSIX.

    Params
    diff --git a/proposals/filesystem/wasi-filesystem.md b/proposals/filesystem/wasi-filesystem.md index ead8b788f..16697c379 100644 --- a/proposals/filesystem/wasi-filesystem.md +++ b/proposals/filesystem/wasi-filesystem.md @@ -1,7 +1,345 @@ +# Import interface `wasi-poll` + +## Types + +## `pollable`: `u32` + +A "pollable" handle. + +This is conceptually represents a `stream<_, _>`, or in other words, +a stream that one can wait on, repeatedly, but which does not itself +produce any data. It's temporary scaffolding until component-model's +async features are ready. + +And at present, it is a `u32` instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready. + +`pollable` lifetimes are not automatically managed. Users must ensure +that they do not outlive the resource they reference. + +Size: 4, Alignment: 4 + +## Functions + +---- + +#### `poll-oneoff` + +Poll for completion on a set of pollables. + +The "oneoff" in the name refers to the fact that this function must do a +linear scan through the entire list of subscriptions, which may be +inefficient if the number is large and the same subscriptions are used +many times. In the future, it may be accompanied by an API similar to +Linux's `epoll` which allows sets of subscriptions to be registered and +made efficiently reusable. + +Note that the return type would ideally be `list`, but that would +be more difficult to polyfill given the current state of `wit-bindgen`. +See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 +for details. For now, we use zero to mean "not ready" and non-zero to +mean "ready". +##### Params + +- `in`: list<[`pollable`](#pollable)> +##### Results + +- `result0`: list<`u8`> + +# Import interface `wasi-io` + +## Types + +## `pollable`: [`pollable`](#pollable) + + +Size: 4, Alignment: 4 + +## `stream-error`: record + +An error type returned from a stream operation. Currently this +doesn't provide any additional information. + +Size: 0, Alignment: 1 + +### Record Fields + +## `output-stream`: `u32` + +An output bytestream. In the future, this will be replaced by handle +types. + +This conceptually represents a `stream`. It's temporary +scaffolding until component-model's async features are ready. + +And at present, it is a `u32` instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready. + +Size: 4, Alignment: 4 + +## `input-stream`: `u32` + +An input bytestream. In the future, this will be replaced by handle +types. + +This conceptually represents a `stream`. It's temporary +scaffolding until component-model's async features are ready. + +And at present, it is a `u32` instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready. + +Size: 4, Alignment: 4 + +## Functions + +---- + +#### `read` + +Read bytes from a stream. + +This function returns a list of bytes containing the data that was +read, along with a bool indicating whether the end of the stream +was reached. The returned list will contain up to `len` bytes; it +may return fewer than requested, but not more. + +Once a stream has reached the end, subsequent calls to read or +`skip` will always report end-of-stream rather than producing more +data. + +If `len` is 0, it represents a request to read 0 bytes, which should +always succeed, assuming the stream hasn't reached its end yet, and +return an empty list. + +The len here is a `u64`, but some callees may not be able to allocate +a buffer as large as that would imply. +FIXME: describe what happens if allocation fails. +##### Params + +- `this`: [`input-stream`](#input_stream) +- `len`: `u64` +##### Results + +- `result0`: result<(list<`u8`>, `bool`), [`stream-error`](#stream_error)> + +---- + +#### `skip` + +Skip bytes from a stream. + +This is similar to the `read` function, but avoids copying the +bytes into the instance. + +Once a stream has reached the end, subsequent calls to read or +`skip` will always report end-of-stream rather than producing more +data. + +This function returns the number of bytes skipped, along with a bool +indicating whether the end of the stream was reached. The returned +value will be at most `len`; it may be less. +##### Params + +- `this`: [`input-stream`](#input_stream) +- `len`: `u64` +##### Results + +- `result0`: result<(`u64`, `bool`), [`stream-error`](#stream_error)> + +---- + +#### `subscribe-read` + +Create a `pollable` which will resolve once either the specified stream has bytes +available to read or the other end of the stream has been closed. +##### Params + +- `this`: [`input-stream`](#input_stream) +##### Results + +- `result0`: [`pollable`](#pollable) + +---- + +#### `drop-input-stream` + +Dispose of the specified `input-stream`, after which it may no longer +be used. +##### Params + +- `this`: [`input-stream`](#input_stream) + +---- + +#### `write` + +Write bytes to a stream. + +This function returns a `u64` indicating the number of bytes from +`buf` that were written; it may be less than the full list. +##### Params + +- `this`: [`output-stream`](#output_stream) +- `buf`: list<`u8`> +##### Results + +- `result0`: result<`u64`, [`stream-error`](#stream_error)> + +---- + +#### `write-zeroes` + +Write multiple zero bytes to a stream. + +This function returns a `u64` indicating the number of zero bytes +that were written; it may be less than `len`. +##### Params + +- `this`: [`output-stream`](#output_stream) +- `len`: `u64` +##### Results + +- `result0`: result<`u64`, [`stream-error`](#stream_error)> + +---- + +#### `splice` + +Read from one stream and write to another. + +This function returns the number of bytes transferred; it may be less +than `len`. +##### Params + +- `this`: [`output-stream`](#output_stream) +- `src`: [`input-stream`](#input_stream) +- `len`: `u64` +##### Results + +- `result0`: result<(`u64`, `bool`), [`stream-error`](#stream_error)> + +---- + +#### `subscribe` + +Create a `pollable` which will resolve once either the specified stream is ready +to accept bytes or the other end of the stream has been closed. +##### Params + +- `this`: [`output-stream`](#output_stream) +##### Results + +- `result0`: [`pollable`](#pollable) + +---- + +#### `drop-output-stream` + +Dispose of the specified `output-stream`, after which it may no longer +be used. +##### Params + +- `this`: [`output-stream`](#output_stream) + +# Import interface `wasi-wall-clock` + +## Types + +## `wall-clock`: `u32` + +A wall clock is a clock which measures the date and time according to some +external reference. + +External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time. + +It is intended for reporting the current date and time for humans. + +Size: 4, Alignment: 4 + +## `datetime`: record + +A time and date in seconds plus nanoseconds. + +Size: 16, Alignment: 8 + +### Record Fields + +- [`seconds`](#datetime.seconds): `u64` + + +- [`nanoseconds`](#datetime.nanoseconds): `u32` + + +## Functions + +---- + +#### `now` + +Read the current value of the clock. + +This clock is not monotonic, therefore calling this function repeatedly will +not necessarily produce a sequence of non-decreasing values. + +The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], also +known as [Unix Time]. + +The nanoseconds field of the output is always less than 1000000000. + +[POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 +[Unix Time]: https://en.wikipedia.org/wiki/Unix_time +##### Params + +- `this`: [`wall-clock`](#wall_clock) +##### Results + +- `result0`: [`datetime`](#datetime) + +---- + +#### `resolution` + +Query the resolution of the clock. + +The nanoseconds field of the output is always less than 1000000000. +##### Params + +- `this`: [`wall-clock`](#wall_clock) +##### Results + +- `result0`: [`datetime`](#datetime) + +---- + +#### `drop-wall-clock` + +Dispose of the specified `wall-clock`, after which it may no longer +be used. +##### Params + +- `this`: [`wall-clock`](#wall_clock) + # Import interface `wasi-filesystem` ## Types +## `input-stream`: [`input-stream`](#input_stream) + + +Size: 4, Alignment: 4 + +## `output-stream`: [`output-stream`](#output_stream) + + +Size: 4, Alignment: 4 + +## `datetime`: [`datetime`](#datetime) + + +Size: 16, Alignment: 8 + ## `o-flags`: record Open flags used by `open-at`. @@ -30,27 +368,6 @@ Size: 1, Alignment: 1 Truncate file to size 0. Bit: 3 -## `new-timestamp`: variant - -When setting a timestamp, this gives the value to set it to. - -Size: 16, Alignment: 8 - -### Variant Cases - -- [`no-change`](#new_timestamp.no_change) - - Leave the timestamp set to its previous value. - -- [`now`](#new_timestamp.now) - - Set the timestamp to the current time of the system clock associated - with the filesystem. - -- [`timestamp`](#new_timestamp.timestamp): `u64` - - Set the timestamp to the given value. - ## `mode`: record Permissions mode used by `open-at`, `change-file-permissions-at`, and @@ -340,49 +657,6 @@ Size: 32, Alignment: 8 The name of the object. -## `descriptor-stat`: record - -File attributes. - -Note: This was called `filestat` in earlier versions of WASI. - -Size: 64, Alignment: 8 - -### Record Fields - -- [`dev`](#descriptor_stat.dev): [`device`](#device) - - Device ID of device containing the file. - -- [`ino`](#descriptor_stat.ino): [`inode`](#inode) - - File serial number. - -- [`type`](#descriptor_stat.type): [`descriptor-type`](#descriptor_type) - - File type. - -- [`nlink`](#descriptor_stat.nlink): [`linkcount`](#linkcount) - - Number of hard links to the file. - -- [`size`](#descriptor_stat.size): [`filesize`](#filesize) - - For regular files, the file size in bytes. For symbolic links, the length - in bytes of the pathname contained in the symbolic link. - -- [`atim`](#descriptor_stat.atim): `u64` - - Last data access timestamp. - -- [`mtim`](#descriptor_stat.mtim): `u64` - - Last data modification timestamp. - -- [`ctim`](#descriptor_stat.ctim): `u64` - - Last file status change timestamp. - ## `descriptor-flags`: record Descriptor flags. @@ -466,6 +740,70 @@ calls may be made. Size: 4, Alignment: 4 +## `new-timestamp`: variant + +When setting a timestamp, this gives the value to set it to. + +Size: 24, Alignment: 8 + +### Variant Cases + +- [`no-change`](#new_timestamp.no_change) + + Leave the timestamp set to its previous value. + +- [`now`](#new_timestamp.now) + + Set the timestamp to the current time of the system clock associated + with the filesystem. + +- [`timestamp`](#new_timestamp.timestamp): [`datetime`](#datetime) + + Set the timestamp to the given value. + +## `descriptor-stat`: record + +File attributes. + +Note: This was called `filestat` in earlier versions of WASI. + +Size: 88, Alignment: 8 + +### Record Fields + +- [`dev`](#descriptor_stat.dev): [`device`](#device) + + Device ID of device containing the file. + +- [`ino`](#descriptor_stat.ino): [`inode`](#inode) + + File serial number. + +- [`type`](#descriptor_stat.type): [`descriptor-type`](#descriptor_type) + + File type. + +- [`nlink`](#descriptor_stat.nlink): [`linkcount`](#linkcount) + + Number of hard links to the file. + +- [`size`](#descriptor_stat.size): [`filesize`](#filesize) + + For regular files, the file size in bytes. For symbolic links, the length + in bytes of the pathname contained in the symbolic link. + +- [`atim`](#descriptor_stat.atim): [`datetime`](#datetime) + + Last data access timestamp. + +- [`mtim`](#descriptor_stat.mtim): [`datetime`](#datetime) + + Last data modification timestamp. + +- [`ctim`](#descriptor_stat.ctim): [`datetime`](#datetime) + + Last file status change timestamp. + ## `at-flags`: record Flags determining the method of how paths are resolved. @@ -515,6 +853,52 @@ Size: 1, Alignment: 1 ---- +#### `read-via-stream` + +Return a stream for reading from a file. + +Note: This allows using `read-stream`, which is similar to `read` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `offset`: [`filesize`](#filesize) +##### Results + +- `result0`: result<[`input-stream`](#input_stream), [`errno`](#errno)> + +---- + +#### `write-via-stream` + +Return a stream for writing to a file. + +Note: This allows using `write-stream`, which is similar to `write` in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `offset`: [`filesize`](#filesize) +##### Results + +- `result0`: result<[`output-stream`](#output_stream), [`errno`](#errno)> + +---- + +#### `append-via-stream` + +Return a stream for appending to a file. + +Note: This allows using `write-stream`, which is similar to `write` with +`O_APPEND` in in POSIX. +##### Params + +- `this`: [`descriptor`](#descriptor) +- `fd`: [`descriptor`](#descriptor) +##### Results + +- `result0`: result<[`output-stream`](#output_stream), [`errno`](#errno)> + +---- + #### `fadvise` Provide file advisory information on a descriptor. @@ -691,7 +1075,7 @@ directory. - `this`: [`descriptor`](#descriptor) ##### Results -- `result0`: stream<[`dir-entry-stream`](#dir_entry_stream), [`errno`](#errno)> +- `result0`: result<[`dir-entry-stream`](#dir_entry_stream), [`errno`](#errno)> ---- diff --git a/proposals/filesystem/wit/wasi-filesystem.wit.md b/proposals/filesystem/wit/wasi-filesystem.wit.md index 9c704eb63..a014e91d6 100644 --- a/proposals/filesystem/wit/wasi-filesystem.wit.md +++ b/proposals/filesystem/wit/wasi-filesystem.wit.md @@ -15,6 +15,12 @@ default interface wasi-filesystem { ``` +# Imports +```wit +use pkg.wasi-io.{input-stream, output-stream} +use pkg.wasi-wall-clock.{datetime} +``` + ## `filesize` ```wit /// File size or length of a region within a file. @@ -118,11 +124,11 @@ record descriptor-stat { /// in bytes of the pathname contained in the symbolic link. size: filesize, /// Last data access timestamp. - atim: u64, + atim: datetime, /// Last data modification timestamp. - mtim: u64, + mtim: datetime, /// Last file status change timestamp. - ctim: u64, + ctim: datetime, } ``` @@ -196,7 +202,7 @@ variant new-timestamp { /// with the filesystem. now, /// Set the timestamp to the given value. - timestamp(u64), + timestamp(datetime), } ``` @@ -334,6 +340,43 @@ enum advice { type descriptor = u32 ``` +## `read-via-stream` +```wit +/// Return a stream for reading from a file. +/// +/// Note: This allows using `read-stream`, which is similar to `read` in POSIX. +read-via-stream: func( + this: descriptor, + /// The offset within the file at which to start reading. + offset: filesize, +) -> result +``` + +## `write-via-stream` +```wit +/// Return a stream for writing to a file. +/// +/// Note: This allows using `write-stream`, which is similar to `write` in POSIX. +write-via-stream: func( + this: descriptor, + /// The offset within the file at which to start writing. + offset: filesize, +) -> result +``` + +## `append-via-stream` +```wit +/// Return a stream for appending to a file. +/// +/// Note: This allows using `write-stream`, which is similar to `write` with +/// `O_APPEND` in in POSIX. +append-via-stream: func( + this: descriptor, + /// The resource to operate on. + fd: descriptor, +) -> result +``` + ## `fadvise` ```wit /// Provide file advisory information on a descriptor. @@ -468,7 +511,7 @@ pwrite: func( /// /// This always returns a new stream which starts at the beginning of the /// directory. -readdir: func(this: descriptor) -> stream +readdir: func(this: descriptor) -> result ``` ## `sync` From 12208d22c983a35995861683d638f6efce3d0d4c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Feb 2023 14:01:31 -0800 Subject: [PATCH 1034/1772] Regenerate wasi-filesystem.html. --- proposals/filesystem/wasi-filesystem.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/wasi-filesystem.html b/proposals/filesystem/wasi-filesystem.html index 2a319fe2e..80d8844b4 100644 --- a/proposals/filesystem/wasi-filesystem.html +++ b/proposals/filesystem/wasi-filesystem.html @@ -1007,7 +1007,7 @@

    open-atIf flags contains descriptor-flags::mutate-directory, and the base descriptor doesn't have descriptor-flags::mutate-directory set, open-at fails with errno::rofs.

    -

    If flags contains write or append, or o-flags contains trunc +

    If flags contains write or append, or o-flags contains trunc or create, and the base descriptor doesn't have descriptor-flags::mutate-directory set, open-at fails with errno::rofs.

    From 5e1bc792336be4b7d056e023e58e0fa3ef4c4d8b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Feb 2023 14:13:54 -0800 Subject: [PATCH 1035/1772] Rename timezone.wit.md to wasi-timezone.wit.md. (#35) It's not yet clear what the names for the wit files should be, but this at least makes it consistent with the other WASI interface filenames. --- proposals/clocks/wit/{timezone.wit.md => wasi-timezone.wit.md} | 0 proposals/clocks/wit/world.wit.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename proposals/clocks/wit/{timezone.wit.md => wasi-timezone.wit.md} (100%) diff --git a/proposals/clocks/wit/timezone.wit.md b/proposals/clocks/wit/wasi-timezone.wit.md similarity index 100% rename from proposals/clocks/wit/timezone.wit.md rename to proposals/clocks/wit/wasi-timezone.wit.md diff --git a/proposals/clocks/wit/world.wit.md b/proposals/clocks/wit/world.wit.md index cb1243a89..90e15cb33 100644 --- a/proposals/clocks/wit/world.wit.md +++ b/proposals/clocks/wit/world.wit.md @@ -6,7 +6,7 @@ the whole proposal. default world wasi-clocks { import wasi-monotonic-clock: pkg.wasi-monotonic-clock import wasi-wall-clock: pkg.wasi-wall-clock - import wasi-timezone: pkg.timezone + import wasi-timezone: pkg.wasi-timezone import wasi-default-clocks: pkg.wasi-default-clocks } ``` From 8458c25e32e0ce8454249805b66cf22fac6ad3a9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Feb 2023 14:17:12 -0800 Subject: [PATCH 1036/1772] Make `utc-offset` signed. (#36) It's common to work with negative UTC offsets so make the `utc-offset` field and function signed. --- proposals/clocks/wasi-clocks.html | 4 ++-- proposals/clocks/wasi-clocks.md | 4 ++-- proposals/clocks/wit/wasi-timezone.wit.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/clocks/wasi-clocks.html b/proposals/clocks/wasi-clocks.html index 3c6b1950e..bf3229cad 100644 --- a/proposals/clocks/wasi-clocks.html +++ b/proposals/clocks/wasi-clocks.html @@ -161,7 +161,7 @@

    utc-offset: u32

    +

    utc-offset: s32

    The number of seconds difference between UTC time and the local time of the timezone.

    The returned value will always be less than 86400 which is the number of @@ -233,7 +233,7 @@

    Params
    Results
      -
    • result0: u32
    • +
    • result0: s32

    drop-timezone

    diff --git a/proposals/clocks/wasi-clocks.md b/proposals/clocks/wasi-clocks.md index 5777462e6..785fe8ec2 100644 --- a/proposals/clocks/wasi-clocks.md +++ b/proposals/clocks/wasi-clocks.md @@ -218,7 +218,7 @@ Size: 16, Alignment: 4 ### Record Fields -- [`utc-offset`](#timezone_display.utc_offset): `u32` +- [`utc-offset`](#timezone_display.utc_offset): `s32` The number of seconds difference between UTC time and the local time of the timezone. @@ -306,7 +306,7 @@ The same as `display`, but only return the UTC offset. - `when`: [`datetime`](#datetime) ##### Results -- `result0`: `u32` +- `result0`: `s32` ---- diff --git a/proposals/clocks/wit/wasi-timezone.wit.md b/proposals/clocks/wit/wasi-timezone.wit.md index 88d0cdac2..ea0dfee26 100644 --- a/proposals/clocks/wit/wasi-timezone.wit.md +++ b/proposals/clocks/wit/wasi-timezone.wit.md @@ -42,7 +42,7 @@ type timezone = u32 ## `utc-offset` ```wit /// The same as `display`, but only return the UTC offset. - utc-offset: func(this: timezone, when: datetime) -> u32 + utc-offset: func(this: timezone, when: datetime) -> s32 ``` ## `drop-timezone` @@ -72,7 +72,7 @@ record timezone-display { /// /// In implementations that do not expose an actual time zone, this should /// return 0. - utc-offset: u32, + utc-offset: s32, ``` ## `name` From e1040c70f0be35a7dc42ea9aa97d4b182fcf14b0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Feb 2023 18:27:15 -0800 Subject: [PATCH 1037/1772] Update the wasi-clock revision. --- proposals/filesystem/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index 29f8efee3..a918a844b 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v2 - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-poll/75ace039473c05928cfd8e6df0243fc47ee9e8c9/wit/wasi-poll.wit.md > wit/wasi-poll.wit.md - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-io/078a05fdc786b7f4ca7217ac6c0dcfa694c31138/wit/wasi-io.wit.md > wit/wasi-io.wit.md - - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-clocks/c288ba066db7907028b92e8efa0fbd22f6f25cf7/wit/wasi-wall-clock.wit.md > wit/wasi-wall-clock.wit.md + - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-clocks/8e0b562acdd7821be63da61f52f42bf8f4586f5a/wit/wasi-wall-clock.wit.md > wit/wasi-wall-clock.wit.md - uses: WebAssembly/wit-abi-up-to-date@v10 with: wit-abi-tag: wit-abi-0.8.0 From e0c4bba128e2065bc929f355ad8c745796e0308d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 Feb 2023 07:18:41 -0800 Subject: [PATCH 1038/1772] Minor updates (#38) * Fix formatting. * Update to the latest wasi-poll. --- proposals/clocks/.github/workflows/main.yml | 2 +- proposals/clocks/README.md | 6 +++--- proposals/clocks/wasi-clocks.html | 13 ++++++++++--- proposals/clocks/wasi-clocks.md | 15 ++++++++++++--- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index a46630a4e..08bf17764 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-poll/75ace039473c05928cfd8e6df0243fc47ee9e8c9/wit/wasi-poll.wit.md > wit/wasi-poll.wit.md + - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-poll/b4a0db022ccddf763e3b91717886c8e39582de72/wit/wasi-poll.wit.md > wit/wasi-poll.wit.md - uses: WebAssembly/wit-abi-up-to-date@v10 with: wit-abi-tag: wit-abi-0.8.0 diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 682bebdba..063e315f1 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -61,11 +61,11 @@ formatting, or modifying the time of a clock. The monotonic clock APIs can be used to measure the elapsed time of a region of code: -```wit= +```wit default-monotonic-clock: monotonic-clock ``` -```rust= +```rust let clock: MonotonicClock = default_monotonic_clock(); let start: Instant = monotonic_clock_now(clock); @@ -80,7 +80,7 @@ default-monotonic-clock: monotonic-clock #### Telling the current human time: -```rust= +```rust let clock: WallClock = default_wall_clock(); let the_current_time = wall_clock_now(); diff --git a/proposals/clocks/wasi-clocks.html b/proposals/clocks/wasi-clocks.html index bf3229cad..2a1525aaf 100644 --- a/proposals/clocks/wasi-clocks.html +++ b/proposals/clocks/wasi-clocks.html @@ -13,14 +13,21 @@

    pollable<

    Size: 4, Alignment: 4

    Functions


    +

    drop-pollable

    +

    Dispose of the specified pollable, after which it may no longer be used.

    +
    Params
    + +

    poll-oneoff

    Poll for completion on a set of pollables.

    The "oneoff" in the name refers to the fact that this function must do a linear scan through the entire list of subscriptions, which may be inefficient if the number is large and the same subscriptions are used -many times. In the future, it may be accompanied by an API similar to -Linux's epoll which allows sets of subscriptions to be registered and -made efficiently reusable.

    +many times. In the future, this is expected to be obsoleted by the +component model async proposal, which will include a scalable waiting +facility.

    Note that the return type would ideally be list<bool>, but that would be more difficult to polyfill given the current state of wit-bindgen. See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 diff --git a/proposals/clocks/wasi-clocks.md b/proposals/clocks/wasi-clocks.md index 785fe8ec2..c30719457 100644 --- a/proposals/clocks/wasi-clocks.md +++ b/proposals/clocks/wasi-clocks.md @@ -23,6 +23,15 @@ Size: 4, Alignment: 4 ---- +#### `drop-pollable` + +Dispose of the specified `pollable`, after which it may no longer be used. +##### Params + +- `this`: [`pollable`](#pollable) + +---- + #### `poll-oneoff` Poll for completion on a set of pollables. @@ -30,9 +39,9 @@ Poll for completion on a set of pollables. The "oneoff" in the name refers to the fact that this function must do a linear scan through the entire list of subscriptions, which may be inefficient if the number is large and the same subscriptions are used -many times. In the future, it may be accompanied by an API similar to -Linux's `epoll` which allows sets of subscriptions to be registered and -made efficiently reusable. +many times. In the future, this is expected to be obsoleted by the +component model async proposal, which will include a scalable waiting +facility. Note that the return type would ideally be `list`, but that would be more difficult to polyfill given the current state of `wit-bindgen`. From 4511975c519d5524c9d3ed37e635335ed6709cb3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 Feb 2023 07:54:50 -0800 Subject: [PATCH 1039/1772] Fix formatting. --- proposals/random/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/README.md b/proposals/random/README.md index d050b6e65..7622c4294 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -90,7 +90,7 @@ used for debugging, and not production use. Return a list of cryptographically-secure pseudo-random bytes: -```rust= +```rust let len: u32 = your_own_code_to_decide_how_many_bytes_you_want(); let bytes: Vec = get_random_bytes(len); From 0383164f1d5091cf3f52aceedac5eaf37c0fe3be Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 Feb 2023 12:58:36 -0800 Subject: [PATCH 1040/1772] Rename the `subscribe` functions for consistency. (#22) Rename `subscribe`/`subscribe-read` to `subscribe-to-output-stream` and `subscribe-to-input-stream`, which makes them consistent and a little more self-explanatory. In the future with resources these both might become just `subscribe` but for now the longer names keep them separate in the same namespace. --- proposals/io/wasi-io.html | 12 ++++++------ proposals/io/wasi-io.md | 12 ++++++------ proposals/io/wit/wasi-io.wit.md | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/proposals/io/wasi-io.html b/proposals/io/wasi-io.html index 380b1b234..a6440667c 100644 --- a/proposals/io/wasi-io.html +++ b/proposals/io/wasi-io.html @@ -106,16 +106,16 @@

    Results
  • result0: result<(u64, bool), stream-error>

  • -

    subscribe-read

    +

    subscribe-to-input-stream

    Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed.

    Params
    Results

    drop-input-stream

    @@ -169,16 +169,16 @@
    Results
  • result0: result<(u64, bool), stream-error>

  • -

    subscribe

    +

    subscribe-to-output-stream

    Create a pollable which will resolve once either the specified stream is ready to accept bytes or the other end of the stream has been closed.

    Params
    Results

    drop-output-stream

    diff --git a/proposals/io/wasi-io.md b/proposals/io/wasi-io.md index 602c22781..a67d42121 100644 --- a/proposals/io/wasi-io.md +++ b/proposals/io/wasi-io.md @@ -148,16 +148,16 @@ value will be at most `len`; it may be less. ---- -#### `subscribe-read` +#### `subscribe-to-input-stream` Create a `pollable` which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. ##### Params -- `this`: [`input-stream`](#input_stream) +- `this`: [`input-stream`](#input_stream) ##### Results -- `result0`: [`pollable`](#pollable) +- `result0`: [`pollable`](#pollable) ---- @@ -220,16 +220,16 @@ than `len`. ---- -#### `subscribe` +#### `subscribe-to-output-stream` Create a `pollable` which will resolve once either the specified stream is ready to accept bytes or the other end of the stream has been closed. ##### Params -- `this`: [`output-stream`](#output_stream) +- `this`: [`output-stream`](#output_stream) ##### Results -- `result0`: [`pollable`](#pollable) +- `result0`: [`pollable`](#pollable) ---- diff --git a/proposals/io/wit/wasi-io.wit.md b/proposals/io/wit/wasi-io.wit.md index eeee465e9..bcd3f0074 100644 --- a/proposals/io/wit/wasi-io.wit.md +++ b/proposals/io/wit/wasi-io.wit.md @@ -83,11 +83,11 @@ type input-stream = u32 ) -> result, stream-error> ``` -## `subscribe` +## `subscribe-to-input-stream` ```wit /// Create a `pollable` which will resolve once either the specified stream has bytes /// available to read or the other end of the stream has been closed. -subscribe-read: func(this: input-stream) -> pollable +subscribe-to-input-stream: func(this: input-stream) -> pollable ``` # `drop-input-stream` @@ -169,11 +169,11 @@ type output-stream = u32 ) -> result ``` -# `subscribe` +# `subscribe-to-output-stream` ```wit /// Create a `pollable` which will resolve once either the specified stream is ready /// to accept bytes or the other end of the stream has been closed. -subscribe: func(this: output-stream) -> pollable +subscribe-to-output-stream: func(this: output-stream) -> pollable ``` # `drop-output-stream` From d9956a416e156c30a63f90f26259970fde067fa4 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 Feb 2023 13:46:05 -0800 Subject: [PATCH 1041/1772] Minor formatting cleanups. --- proposals/io/README.md | 6 +++--- proposals/io/wit/wasi-io.wit.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/io/README.md b/proposals/io/README.md index b143bd69a..11fb122f1 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -57,7 +57,7 @@ types, `input-stream`, and `output-stream`, which support `read` and #### Use Case: copying from input to output using `read`/`write` -```rust= +```rust fn copy_data(input: InputStream, output: OutputStream) -> Result<(), StreamError> { const BUFFER_LEN: usize = 4096; loop { @@ -78,7 +78,7 @@ types, `input-stream`, and `output-stream`, which support `read` and #### Use case: copying from input to output using `splice` -```rust= +```rust fn copy_data(input: InputStream, output: OutputStream) -> Result<(), StreamError> { loop { let (_num_copied, eos) = output.splice(input, u64::MAX)?; @@ -93,7 +93,7 @@ types, `input-stream`, and `output-stream`, which support `read` and #### Use case: copying from input to output using `forward` -```rust= +```rust fn copy_data(input: InputStream, output: OutputStream) -> Result<(), StreamError> { output.forward(input)?; Ok(()) diff --git a/proposals/io/wit/wasi-io.wit.md b/proposals/io/wit/wasi-io.wit.md index bcd3f0074..24566b803 100644 --- a/proposals/io/wit/wasi-io.wit.md +++ b/proposals/io/wit/wasi-io.wit.md @@ -154,7 +154,7 @@ type output-stream = u32 ``` ## `forward` -```wit= +```wit /// Forward the entire contents of an input stream to an output stream. /// /// This function repeatedly reads from the input stream and writes From 2a08a2f4dcefffacf3364bae01dec9be269dc60b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 Feb 2023 13:49:50 -0800 Subject: [PATCH 1042/1772] Update generated files. --- proposals/io/.github/workflows/main.yml | 2 +- proposals/io/wasi-io.html | 31 ++++++++++++++++++--- proposals/io/wasi-io.md | 36 ++++++++++++++++++++++--- 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index a46630a4e..d1a287fc4 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-poll/75ace039473c05928cfd8e6df0243fc47ee9e8c9/wit/wasi-poll.wit.md > wit/wasi-poll.wit.md + - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-poll/1bafe7b4a16848a61dd81595ac7f67733561112f/wit/wasi-poll.wit.md > wit/wasi-poll.wit.md - uses: WebAssembly/wit-abi-up-to-date@v10 with: wit-abi-tag: wit-abi-0.8.0 diff --git a/proposals/io/wasi-io.html b/proposals/io/wasi-io.html index a6440667c..3a33f0876 100644 --- a/proposals/io/wasi-io.html +++ b/proposals/io/wasi-io.html @@ -13,17 +13,24 @@

    pollable<

    Size: 4, Alignment: 4

    Functions


    +

    drop-pollable

    +

    Dispose of the specified pollable, after which it may no longer be used.

    +
    Params
    + +

    poll-oneoff

    Poll for completion on a set of pollables.

    The "oneoff" in the name refers to the fact that this function must do a linear scan through the entire list of subscriptions, which may be inefficient if the number is large and the same subscriptions are used -many times. In the future, it may be accompanied by an API similar to -Linux's epoll which allows sets of subscriptions to be registered and -made efficiently reusable.

    +many times. In the future, this is expected to be obsoleted by the +component model async proposal, which will include a scalable waiting +facility.

    Note that the return type would ideally be list<bool>, but that would be more difficult to polyfill given the current state of wit-bindgen. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 +See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 for details. For now, we use zero to mean "not ready" and non-zero to mean "ready".

    Params
    @@ -169,6 +176,22 @@
    Results
  • result0: result<(u64, bool), stream-error>

  • +

    forward

    +

    Forward the entire contents of an input stream to an output stream.

    +

    This function repeatedly reads from the input stream and writes +the data to the output stream, until the end of the input stream +is reached, or an error is encountered.

    +

    This function returns the number of bytes transferred.

    +
    Params
    + +
    Results
    + +

    subscribe-to-output-stream

    Create a pollable which will resolve once either the specified stream is ready to accept bytes or the other end of the stream has been closed.

    diff --git a/proposals/io/wasi-io.md b/proposals/io/wasi-io.md index a67d42121..4382dce7c 100644 --- a/proposals/io/wasi-io.md +++ b/proposals/io/wasi-io.md @@ -23,6 +23,15 @@ Size: 4, Alignment: 4 ---- +#### `drop-pollable` + +Dispose of the specified `pollable`, after which it may no longer be used. +##### Params + +- `this`: [`pollable`](#pollable) + +---- + #### `poll-oneoff` Poll for completion on a set of pollables. @@ -30,13 +39,13 @@ Poll for completion on a set of pollables. The "oneoff" in the name refers to the fact that this function must do a linear scan through the entire list of subscriptions, which may be inefficient if the number is large and the same subscriptions are used -many times. In the future, it may be accompanied by an API similar to -Linux's `epoll` which allows sets of subscriptions to be registered and -made efficiently reusable. +many times. In the future, this is expected to be obsoleted by the +component model async proposal, which will include a scalable waiting +facility. Note that the return type would ideally be `list`, but that would be more difficult to polyfill given the current state of `wit-bindgen`. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 +See for details. For now, we use zero to mean "not ready" and non-zero to mean "ready". ##### Params @@ -220,6 +229,25 @@ than `len`. ---- +#### `forward` + +Forward the entire contents of an input stream to an output stream. + +This function repeatedly reads from the input stream and writes +the data to the output stream, until the end of the input stream +is reached, or an error is encountered. + +This function returns the number of bytes transferred. +##### Params + +- `this`: [`output-stream`](#output_stream) +- `src`: [`input-stream`](#input_stream) +##### Results + +- `result0`: result<`u64`, [`stream-error`](#stream_error)> + +---- + #### `subscribe-to-output-stream` Create a `pollable` which will resolve once either the specified stream is ready From 4c148510ec74193a2f097c6b8dc5578250ed032f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 Feb 2023 13:50:28 -0800 Subject: [PATCH 1043/1772] Add an end-of-file return value to `pread`. (#101) * Add an end-of-file return value to `pread`. Add a way for `pread` to indicate whether it detected the end of the file. This allows users to distinguish the end of the file from a short read for some other reason. * Clarify the wording for `pread`'s end of file behavior. --- .../filesystem/.github/workflows/main.yml | 6 +- proposals/filesystem/wasi-filesystem.html | 50 +++++++++++++---- proposals/filesystem/wasi-filesystem.md | 56 +++++++++++++++---- .../filesystem/wit/wasi-filesystem.wit.md | 8 ++- 4 files changed, 94 insertions(+), 26 deletions(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index a918a844b..6f87604e9 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -11,9 +11,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-poll/75ace039473c05928cfd8e6df0243fc47ee9e8c9/wit/wasi-poll.wit.md > wit/wasi-poll.wit.md - - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-io/078a05fdc786b7f4ca7217ac6c0dcfa694c31138/wit/wasi-io.wit.md > wit/wasi-io.wit.md - - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-clocks/8e0b562acdd7821be63da61f52f42bf8f4586f5a/wit/wasi-wall-clock.wit.md > wit/wasi-wall-clock.wit.md + - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-poll/1bafe7b4a16848a61dd81595ac7f67733561112f/wit/wasi-poll.wit.md > wit/wasi-poll.wit.md + - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-io/32ad9a13480d591d1c094dcafdd4d19518e4de93/wit/wasi-io.wit.md > wit/wasi-io.wit.md + - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-clocks/778a8323dde9385be37e774558febd7576548984/wit/wasi-wall-clock.wit.md > wit/wasi-wall-clock.wit.md - uses: WebAssembly/wit-abi-up-to-date@v10 with: wit-abi-tag: wit-abi-0.8.0 diff --git a/proposals/filesystem/wasi-filesystem.html b/proposals/filesystem/wasi-filesystem.html index 80d8844b4..684052770 100644 --- a/proposals/filesystem/wasi-filesystem.html +++ b/proposals/filesystem/wasi-filesystem.html @@ -13,17 +13,24 @@

    pollable<

    Size: 4, Alignment: 4

    Functions


    +

    drop-pollable

    +

    Dispose of the specified pollable, after which it may no longer be used.

    +
    Params
    + +

    poll-oneoff

    Poll for completion on a set of pollables.

    The "oneoff" in the name refers to the fact that this function must do a linear scan through the entire list of subscriptions, which may be inefficient if the number is large and the same subscriptions are used -many times. In the future, it may be accompanied by an API similar to -Linux's epoll which allows sets of subscriptions to be registered and -made efficiently reusable.

    +many times. In the future, this is expected to be obsoleted by the +component model async proposal, which will include a scalable waiting +facility.

    Note that the return type would ideally be list<bool>, but that would be more difficult to polyfill given the current state of wit-bindgen. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 +See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 for details. For now, we use zero to mean "not ready" and non-zero to mean "ready".

    Params
    @@ -106,16 +113,16 @@
    Results
  • result0: result<(u64, bool), stream-error>

  • -

    subscribe-read

    +

    subscribe-to-input-stream

    Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed.

    Params
    Results

    drop-input-stream

    @@ -169,16 +176,32 @@
    Results
  • result0: result<(u64, bool), stream-error>

  • -

    subscribe

    +

    forward

    +

    Forward the entire contents of an input stream to an output stream.

    +

    This function repeatedly reads from the input stream and writes +the data to the output stream, until the end of the input stream +is reached, or an error is encountered.

    +

    This function returns the number of bytes transferred.

    +
    Params
    + +
    Results
    + +
    +

    subscribe-to-output-stream

    Create a pollable which will resolve once either the specified stream is ready to accept bytes or the other end of the stream has been closed.

    Params
    Results

    drop-output-stream

    @@ -864,6 +887,11 @@
    Results

    pread

    Read from a descriptor, without using and updating the descriptor's offset.

    +

    This function returns a list of bytes containing the data that was +read, along with a bool which, when true, indicates that the end of the +file was reached. The returned list will contain up to len bytes; it +may return fewer than requested, if the end of the file is reached or +if the I/O operation is interrupted.

    Note: This is similar to pread in POSIX.

    Params
      @@ -873,7 +901,7 @@
      Params
    Results
      -
    • result0: result<list<u8>, errno>
    • +
    • result0: result<(list<u8>, bool), errno>

    pwrite

    diff --git a/proposals/filesystem/wasi-filesystem.md b/proposals/filesystem/wasi-filesystem.md index 16697c379..eb8620703 100644 --- a/proposals/filesystem/wasi-filesystem.md +++ b/proposals/filesystem/wasi-filesystem.md @@ -23,6 +23,15 @@ Size: 4, Alignment: 4 ---- +#### `drop-pollable` + +Dispose of the specified `pollable`, after which it may no longer be used. +##### Params + +- `this`: [`pollable`](#pollable) + +---- + #### `poll-oneoff` Poll for completion on a set of pollables. @@ -30,13 +39,13 @@ Poll for completion on a set of pollables. The "oneoff" in the name refers to the fact that this function must do a linear scan through the entire list of subscriptions, which may be inefficient if the number is large and the same subscriptions are used -many times. In the future, it may be accompanied by an API similar to -Linux's `epoll` which allows sets of subscriptions to be registered and -made efficiently reusable. +many times. In the future, this is expected to be obsoleted by the +component model async proposal, which will include a scalable waiting +facility. Note that the return type would ideally be `list`, but that would be more difficult to polyfill given the current state of `wit-bindgen`. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 +See for details. For now, we use zero to mean "not ready" and non-zero to mean "ready". ##### Params @@ -148,16 +157,16 @@ value will be at most `len`; it may be less. ---- -#### `subscribe-read` +#### `subscribe-to-input-stream` Create a `pollable` which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. ##### Params -- `this`: [`input-stream`](#input_stream) +- `this`: [`input-stream`](#input_stream) ##### Results -- `result0`: [`pollable`](#pollable) +- `result0`: [`pollable`](#pollable) ---- @@ -220,16 +229,35 @@ than `len`. ---- -#### `subscribe` +#### `forward` + +Forward the entire contents of an input stream to an output stream. + +This function repeatedly reads from the input stream and writes +the data to the output stream, until the end of the input stream +is reached, or an error is encountered. + +This function returns the number of bytes transferred. +##### Params + +- `this`: [`output-stream`](#output_stream) +- `src`: [`input-stream`](#input_stream) +##### Results + +- `result0`: result<`u64`, [`stream-error`](#stream_error)> + +---- + +#### `subscribe-to-output-stream` Create a `pollable` which will resolve once either the specified stream is ready to accept bytes or the other end of the stream has been closed. ##### Params -- `this`: [`output-stream`](#output_stream) +- `this`: [`output-stream`](#output_stream) ##### Results -- `result0`: [`pollable`](#pollable) +- `result0`: [`pollable`](#pollable) ---- @@ -1028,6 +1056,12 @@ Note: This was called `fd_filestat_set_times` in earlier versions of WASI. Read from a descriptor, without using and updating the descriptor's offset. +This function returns a list of bytes containing the data that was +read, along with a bool which, when true, indicates that the end of the +file was reached. The returned list will contain up to `len` bytes; it +may return fewer than requested, if the end of the file is reached or +if the I/O operation is interrupted. + Note: This is similar to `pread` in POSIX. ##### Params @@ -1036,7 +1070,7 @@ Note: This is similar to `pread` in POSIX. - `offset`: [`filesize`](#filesize) ##### Results -- `result0`: result, [`errno`](#errno)> +- `result0`: result<(list<`u8`>, `bool`), [`errno`](#errno)> ---- diff --git a/proposals/filesystem/wit/wasi-filesystem.wit.md b/proposals/filesystem/wit/wasi-filesystem.wit.md index a014e91d6..308a3e2b6 100644 --- a/proposals/filesystem/wit/wasi-filesystem.wit.md +++ b/proposals/filesystem/wit/wasi-filesystem.wit.md @@ -471,6 +471,12 @@ set-times: func( ```wit /// Read from a descriptor, without using and updating the descriptor's offset. /// +/// This function returns a list of bytes containing the data that was +/// read, along with a bool which, when true, indicates that the end of the +/// file was reached. The returned list will contain up to `len` bytes; it +/// may return fewer than requested, if the end of the file is reached or +/// if the I/O operation is interrupted. +/// /// Note: This is similar to `pread` in POSIX. // TODO(stream) pread: func( @@ -479,7 +485,7 @@ pread: func( len: filesize, /// The offset within the file at which to read. offset: filesize, -) -> result, errno> +) -> result, bool>, errno> ``` ## `pwrite` From ede7faf6e5e05069af2375c85165b5a91f219a43 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 15 Feb 2023 23:38:37 +0100 Subject: [PATCH 1044/1772] Update proposal to match the current WIT abilities, and also to match the design direction of WASI preview 2. Notable changes: - Added `wasi-default-network` - Replaced `resource`s with plain handle indexes along with manually defined `drop-....` functions - Replaced `future<>` with `non-blocking/set-non-blocking/subscribe` functions - Replaced `stream<>` with `wasi-io.input/output-stream` in the TCP module. - Replaced `stream<>` with a custom `resolve-address-stream` in the name lookup module. - Added `shutdown` back in into the TCP module. --- proposals/sockets/common-types.wit | 37 ---- proposals/sockets/wasi-default-network.wit | 9 + proposals/sockets/wasi-ip-name-lookup.wit | 101 ++++++---- proposals/sockets/wasi-network.wit | 55 +++++- proposals/sockets/wasi-socket-ip.wit | 41 ---- proposals/sockets/wasi-socket-tcp.wit | 142 -------------- proposals/sockets/wasi-socket.wit | 4 - proposals/sockets/wasi-tcp.wit | 181 ++++++++++++++++++ .../{wasi-socket-udp.wit => wasi-udp.wit} | 98 +++++++--- 9 files changed, 381 insertions(+), 287 deletions(-) delete mode 100644 proposals/sockets/common-types.wit create mode 100644 proposals/sockets/wasi-default-network.wit delete mode 100644 proposals/sockets/wasi-socket-ip.wit delete mode 100644 proposals/sockets/wasi-socket-tcp.wit delete mode 100644 proposals/sockets/wasi-socket.wit create mode 100644 proposals/sockets/wasi-tcp.wit rename proposals/sockets/{wasi-socket-udp.wit => wasi-udp.wit} (55%) diff --git a/proposals/sockets/common-types.wit b/proposals/sockets/common-types.wit deleted file mode 100644 index 281d3898a..000000000 --- a/proposals/sockets/common-types.wit +++ /dev/null @@ -1,37 +0,0 @@ - -/// TO DISCUSS -type usize = u32 - -/// TODO -enum error { - /// TODO: https://github.com/WebAssembly/interface-types/issues/145 - unknown, -} - -enum ip-address-family { - /// Similar to `AF_INET` in POSIX. - ipv4, - - /// Similar to `AF_INET6` in POSIX. - ipv6, -} - -/// Single field record for symmetry with `ipv6-address`. -record ipv4-address { - /// The address in network order (big-endian). Note: WebAssembly is little-endian. - data: u32, -} - -/// Interface Types doesn't have either u128 or fixed length arrays. https://github.com/WebAssembly/interface-types/issues/146 -record ipv6-address { - /// Upper half of the address in network order (big-endian). Note: WebAssembly is little-endian. - data-msb: u64, - - /// Lower half of the address in network order (big-endian). Note: WebAssembly is little-endian. - data-lsb: u64, -} - -variant ip-address { - ipv4(ipv4-address), - ipv6(ipv6-address), -} diff --git a/proposals/sockets/wasi-default-network.wit b/proposals/sockets/wasi-default-network.wit new file mode 100644 index 000000000..c9cd3b0e4 --- /dev/null +++ b/proposals/sockets/wasi-default-network.wit @@ -0,0 +1,9 @@ + +/// This interface provides a value-export of the default network handle.. +default interface wasi-default-network { + use pkg.wasi-network.{network} + + /// Get a handle to the default network. + default-network: func() -> network + +} \ No newline at end of file diff --git a/proposals/sockets/wasi-ip-name-lookup.wit b/proposals/sockets/wasi-ip-name-lookup.wit index 153133156..67fa0a3df 100644 --- a/proposals/sockets/wasi-ip-name-lookup.wit +++ b/proposals/sockets/wasi-ip-name-lookup.wit @@ -1,32 +1,69 @@ -use { error, ip-address, ip-address-family } from common-types -use { network } from wasi-network - -/// Resolve an internet host name to a list of IP addresses. -/// -/// See the proposal README.md for a comparison with getaddrinfo. -/// -/// Parameters: -/// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted -/// to ASCII using IDNA encoding. -/// - `address-family`: If provided, limit the results to addresses of this specific address family. -/// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime -/// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on -/// systems without an active IPv6 interface. Notes: -/// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. -/// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. -/// -/// Results: -/// - When successful, there is always at least one result. -/// - The results are returned in the order the runtime thinks the application should try to connect to first. -/// - Never returns IPv4-mapped IPv6 addresses. -/// -/// Returns EAI_FAIL when `name` is: -/// - empty -/// - an IP address -/// - a syntactically invalid domain name in another way -/// -/// References: -/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html -/// - https://man7.org/linux/man-pages/man3/getaddrinfo.3.html -/// -resolve-addresses: func(name: string, address-family: option, include-unavailable: bool) -> future, error>> \ No newline at end of file + +default interface wasi-ip-name-lookup { + use pkg.wasi-poll.{pollable} + use pkg.wasi-network.{network, error, ip-address, ip-address-family} + + + /// Resolve an internet host name to a list of IP addresses. + /// + /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. + /// + /// Parameters: + /// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted + /// to ASCII using IDNA encoding. + /// - `address-family`: If provided, limit the results to addresses of this specific address family. + /// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime + /// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on + /// systems without an active IPv6 interface. Notes: + /// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. + /// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. + /// + /// This function never blocks. It either immediately returns successfully with a `resolve-address-stream` + /// that can be used to (asynchronously) fetch the results. + /// Or it immediately fails whenever `name` is: + /// - empty + /// - an IP address + /// - a syntactically invalid domain name in another way + /// + /// References: + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html + /// - https://man7.org/linux/man-pages/man3/getaddrinfo.3.html + /// + resolve-addresses: func(network: network, name: string, address-family: option, include-unavailable: bool) -> result + + + + type resolve-address-stream = u32 + + /// Returns the next address from the resolver. + /// + /// This function should be called multiple times. On each call, it will + /// return the next address in connection order preference. If all + /// addresses have been exhausted, this function returns `none`. + /// After which, you should release the stream with `drop-resolve-address-stream`. + /// + /// This function never returns IPv4-mapped IPv6 addresses. + resolve-next-address: func(this: resolve-address-stream) -> result, error> + + + + /// Dispose of the specified `resolve-address-stream`, after which it may no longer be used. + drop-resolve-address-stream: func(this: resolve-address-stream) + + /// Get/set the blocking mode of the stream. + /// + /// By default a stream is in "blocking" mode, meaning that any function blocks and waits for its completion. + /// When switched to "non-blocking" mode, operations that would block return an `again` error. After which + /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. + /// + /// Note: these functions are here for WASI Preview2 only. + /// They're planned to be removed when `async` is natively supported in Preview3. + non-blocking: func(this: resolve-address-stream) -> result + set-non-blocking: func(this: resolve-address-stream, value: bool) -> result<_, error> + + /// Create a `pollable` which will resolve once the stream is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `async` is natively supported in Preview3. + subscribe: func(this: resolve-address-stream) -> pollable +} diff --git a/proposals/sockets/wasi-network.wit b/proposals/sockets/wasi-network.wit index 1a06a6ae1..80fc56c2a 100644 --- a/proposals/sockets/wasi-network.wit +++ b/proposals/sockets/wasi-network.wit @@ -1,3 +1,54 @@ -/// Capability handle for accessing network-related functions. -resource network {} \ No newline at end of file +default interface wasi-network { + /// An opaque resource that represents access to (a subset of) the network. + /// This enables context-based security for networking. + /// There is no need for this to map 1:1 to a physical network interface. + /// + /// FYI, In the future this will be replaced by handle types. + type network = u32 + + /// Dispose of the specified `network`, after which it may no longer be used. + drop-network: func(this: network) + + + + enum error { + unknown, + again, + // TODO ... + } + + enum ip-address-family { + /// Similar to `AF_INET` in POSIX. + ipv4, + + /// Similar to `AF_INET6` in POSIX. + ipv6, + } + + type ipv4-address = tuple + type ipv6-address = tuple + + variant ip-address { + ipv4(ipv4-address), + ipv6(ipv6-address), + } + + record ipv4-socket-address { + port: u16, // sin_port + address: ipv4-address, // sin_addr + } + + record ipv6-socket-address { + port: u16, // sin6_port + flow-info: u32, // sin6_flowinfo + address: ipv6-address, // sin6_addr + scope-id: u32, // sin6_scope_id + } + + variant ip-socket-address { + ipv4(ipv4-socket-address), + ipv6(ipv6-socket-address), + } + +} \ No newline at end of file diff --git a/proposals/sockets/wasi-socket-ip.wit b/proposals/sockets/wasi-socket-ip.wit deleted file mode 100644 index a8dba0581..000000000 --- a/proposals/sockets/wasi-socket-ip.wit +++ /dev/null @@ -1,41 +0,0 @@ - -use { error, ipv4-address, ipv6-address, ip-address-family } from common-types -use { socket } from wasi-socket - -record ipv4-socket-address { - port: u16, // sin_port - address: ipv4-address, // sin_addr -} - -record ipv6-socket-address { - port: u16, // sin6_port - flow-info: u32, // sin6_flowinfo - address: ipv6-address, // sin6_addr - scope-id: u32, // sin6_scope_id -} - -variant ip-socket-address { - ipv4(ipv4-socket-address), - ipv6(ipv6-socket-address), -} - -resource ip-socket implements socket { - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func() -> ip-address-family - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - unicast-hop-limit: func() -> expected - set-unicast-hop-limit: func(value: u8) -> expected - - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// Implementations are not required to support dual-stack mode, so calling `set-ipv6-only(false)` might fail. - /// - /// Fails when called on an IPv4 socket. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - ipv6-only: func() -> expected - set-ipv6-only: func(value: bool) -> expected -} diff --git a/proposals/sockets/wasi-socket-tcp.wit b/proposals/sockets/wasi-socket-tcp.wit deleted file mode 100644 index 41b4e5367..000000000 --- a/proposals/sockets/wasi-socket-tcp.wit +++ /dev/null @@ -1,142 +0,0 @@ -use { error, ip-address-family, usize } from common-types -use { network } from wasi-network -use { ip-socket, ip-socket-address } from wasi-socket-ip - -resource tcp-socket implements ip-socket { - - /// Create a new TCP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, 0 or IPPROTO_TCP)` in POSIX. - /// - /// References: - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html - /// - https://man7.org/linux/man-pages/man2/socket.2.html - /// - static new: func(network: handle network, address-family: ip-address-family) -> future> - - /// Receive data on the socket. - /// - /// The returned stream can be used to continually read all data from the socket. The stream's final value will be - /// `Ok(())` when the stream reached end-of-file without errors. When the returned stream is closed by the consumer, - /// a `shutdown(this_socket, SHUT_RD)` syscall is executed. - /// - /// This function can only be called successfully _once_ on a socket. All subsequent calls will result in an EPIPE error. - /// - /// Fails when the socket is not in the Connection state. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html - /// - https://man7.org/linux/man-pages/man2/recv.2.html - /// - https://man7.org/linux/man-pages/man2/read.2.html - receive: func() -> stream> - - /// Send data on the socket. - /// - /// The input stream can be used to continually write data to the socket. - /// After the input stream is finalized by the producer, a `shutdown(this_socket, SHUT_WR)` syscall is executed. - /// - /// The returned future completes successfully after the input stream is drained completely. - /// If an error occurs during sending, the input stream is closed and the future completes with an error. - /// - /// This function can only be called successfully _once_ on a socket. All subsequent calls will result in an EPIPE error. - /// - /// Fails when the socket is not in the Connection state. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html - /// - https://man7.org/linux/man-pages/man2/send.2.html - /// - https://man7.org/linux/man-pages/man2/write.2.html - send: func(data: stream) -> future> - - /// Bind the socket to a specific IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will - /// implicitly bind the socket. - /// - /// Returns an error if the socket is already bound. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html - /// - https://man7.org/linux/man-pages/man2/bind.2.html - bind: func(local-address: ip-socket-address) -> future> - - /// Get the current bound address. - /// - /// Returns an error if the socket is not bound. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html - /// - https://man7.org/linux/man-pages/man2/getsockname.2.html - local-address: func() -> expected - - /// Connect to a remote endpoint. - /// - /// Transitions the socket into the Connection state. - /// Fails when the socket is already in the Connection or Listener state. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html - /// - https://man7.org/linux/man-pages/man2/connect.2.html - connect: func(remote-address: ip-socket-address) -> future> - - /// Start listening for new connections. - /// - /// Transitions the socket into the Listener state. - /// Fails when the socket is already in the Connection or Listener state. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html - /// - https://man7.org/linux/man-pages/man2/listen.2.html - listen: func(backlog-size-hint: option) -> future> - - /// Fails when the socket is not in the Connection state. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html - /// - https://man7.org/linux/man-pages/man2/getpeername.2.html - remote-address: func() -> expected - - /// Start accepting new client sockets. - /// - /// The returned sockets are bound and in the Connection state. - /// - /// This function can only be called successfully _once_ on a socket. All subsequent calls will result in an error. - /// - /// Fails when this socket is not in the Listening state. - /// - /// References: - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html - /// - https://man7.org/linux/man-pages/man2/accept.2.html - accept: func() -> stream> - - /// Equivalent to the SO_KEEPALIVE socket option. - keep-alive: func() -> expected - set-keep-alive: func(value: bool) -> expected - - /// Equivalent to the TCP_NODELAY socket option. - no-delay: func() -> expected - set-no-delay: func(value: bool) -> expected - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. - /// - /// Fails when this socket is in the Listening state. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - receive-buffer-size: func() -> expected - set-receive-buffer-size: func(value: usize) -> expected - send-buffer-size: func() -> expected - set-send-buffer-size: func(value: usize) -> expected -} \ No newline at end of file diff --git a/proposals/sockets/wasi-socket.wit b/proposals/sockets/wasi-socket.wit deleted file mode 100644 index e09b095ac..000000000 --- a/proposals/sockets/wasi-socket.wit +++ /dev/null @@ -1,4 +0,0 @@ - -resource socket { - -} diff --git a/proposals/sockets/wasi-tcp.wit b/proposals/sockets/wasi-tcp.wit new file mode 100644 index 000000000..53bb8ccf9 --- /dev/null +++ b/proposals/sockets/wasi-tcp.wit @@ -0,0 +1,181 @@ + +default interface wasi-tcp { + use pkg.wasi-io.{input-stream, output-stream} + use pkg.wasi-poll.{pollable} + use pkg.wasi-network.{network, error, ip-socket-address, ip-address-family} + + /// A TCP socket handle. + type tcp-socket = u32 + + + enum shutdown-type { + /// Similar to `SHUT_RD` in POSIX. + receive, + + /// Similar to `SHUT_WR` in POSIX. + send, + + /// Similar to `SHUT_RDWR` in POSIX. + both, + } + + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// + /// References: + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html + /// - https://man7.org/linux/man-pages/man2/socket.2.html + /// + create-tcp-socket: func(network: network, address-family: ip-address-family) -> result + + /// Dispose of the specified `tcp-socket`, after which it may no longer be used. + drop-tcp-socket: func(this: tcp-socket) + + /// Bind the socket to a specific IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will + /// implicitly bind the socket. + /// + /// Returns an error if the socket is already bound. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html + /// - https://man7.org/linux/man-pages/man2/bind.2.html + bind: func(this: tcp-socket, local-address: ip-socket-address) -> result<_, error> + + /// Get the current bound address. + /// + /// Returns an error if the socket is not bound. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html + /// - https://man7.org/linux/man-pages/man2/getsockname.2.html + local-address: func(this: tcp-socket) -> result + + /// Connect to a remote endpoint. + /// + /// Transitions the socket into the Connection state. + /// Fails when the socket is already in the Connection or Listener state. + /// + /// On success, this function returns a pair of streams that can be used to read & write to the connection. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html + /// - https://man7.org/linux/man-pages/man2/connect.2.html + connect: func(this: tcp-socket, remote-address: ip-socket-address) -> result, error> + + /// Gracefully shut down the connection. + /// + /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read + /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. + /// Any data still in the receive queue at time of calling `shutdown` will be discarded. + /// - send: the socket is not expecting to send any more data to the peer. All subsequent write + /// operations on the `output-stream` associated with this socket will return an error. + /// - both: same effect as receive & send combined. + /// + /// The shutdown function does not close the socket. + /// + /// Fails when the socket is not in the Connection state. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html + /// - https://man7.org/linux/man-pages/man2/shutdown.2.html + shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error> + + /// Start listening for new connections. + /// + /// Transitions the socket into the Listener state. + /// Fails when the socket is already in the Connection or Listener state. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html + /// - https://man7.org/linux/man-pages/man2/listen.2.html + listen: func(this: tcp-socket, backlog-size-hint: option) -> result<_, error> + + /// Fails when the socket is not in the Connection state. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html + /// - https://man7.org/linux/man-pages/man2/getpeername.2.html + remote-address: func(this: tcp-socket) -> result + + /// Accept a new client socket. + /// + /// The returned socket is bound and in the Connection state. + /// + /// On success, this function returns the newly accepted client socket along with + /// a pair of streams that can be used to read & write to the connection. + /// + /// Fails when this socket is not in the Listening state. + /// + /// References: + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html + /// - https://man7.org/linux/man-pages/man2/accept.2.html + accept: func(this: tcp-socket) -> result, error> + + /// Equivalent to the SO_KEEPALIVE socket option. + keep-alive: func(this: tcp-socket) -> result + set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error> + + /// Equivalent to the TCP_NODELAY socket option. + no-delay: func(this: tcp-socket) -> result + set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error> + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Fails when this socket is in the Listening state. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + receive-buffer-size: func(this: tcp-socket) -> result + set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error> + send-buffer-size: func(this: tcp-socket) -> result + set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error> + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func(this: tcp-socket) -> ip-address-family + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + unicast-hop-limit: func(this: tcp-socket) -> result + set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error> + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// Implementations are not required to support dual-stack mode, so calling `set-ipv6-only(false)` might fail. + /// + /// Fails when called on an IPv4 socket. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + ipv6-only: func(this: tcp-socket) -> result + set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error> + + + /// Get/set the blocking mode of the socket. + /// + /// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. + /// When switched to "non-blocking" mode, operations that would block return an `again` error. After which + /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. + /// + /// Note: these functions are here for WASI Preview2 only. + /// They're planned to be removed when `async` is natively supported in Preview3. + non-blocking: func(this: tcp-socket) -> result + set-non-blocking: func(this: tcp-socket, value: bool) -> result<_, error> + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `async` is natively supported in Preview3. + subscribe: func(this: tcp-socket) -> pollable +} diff --git a/proposals/sockets/wasi-socket-udp.wit b/proposals/sockets/wasi-udp.wit similarity index 55% rename from proposals/sockets/wasi-socket-udp.wit rename to proposals/sockets/wasi-udp.wit index bbb0d7bd3..5fe79a90b 100644 --- a/proposals/sockets/wasi-socket-udp.wit +++ b/proposals/sockets/wasi-udp.wit @@ -1,31 +1,35 @@ -use { error, ip-address-family, usize } from common-types -use { network } from wasi-network -use { ip-socket, ip-socket-address } from wasi-socket-ip - -record datagram { - data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. - remote-address: ip-socket-address, - - /// Possible future additions: - /// local-address: ip-socket-address, // IP_PKTINFO / IP_RECVDSTADDR / IPV6_PKTINFO - /// local-interface: u32, // IP_PKTINFO / IP_RECVIF - /// ttl: u8, // IP_RECVTTL - /// dscp: u6, // IP_RECVTOS - /// ecn: u2, // IP_RECVTOS -} +default interface wasi-udp { + use pkg.wasi-poll.{pollable} + use pkg.wasi-network.{network, error, ip-socket-address, ip-address-family} + + record datagram { + data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. + remote-address: ip-socket-address, + + /// Possible future additions: + /// local-address: ip-socket-address, // IP_PKTINFO / IP_RECVDSTADDR / IPV6_PKTINFO + /// local-interface: u32, // IP_PKTINFO / IP_RECVIF + /// ttl: u8, // IP_RECVTTL + /// dscp: u6, // IP_RECVTOS + /// ecn: u2, // IP_RECVTOS + } -resource udp-socket implements ip-socket { + /// A UDP socket handle. + type udp-socket = u32 /// Create a new UDP socket. /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, 0 or IPPROTO_UDP)` in POSIX. + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. /// /// References: /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html /// - https://man7.org/linux/man-pages/man2/socket.2.html /// - static new: func(network: handle network, address-family: ip-address-family) -> future> + create-udp-socket: func(network: network, address-family: ip-address-family) -> result + + /// Dispose of the specified `udp-socket`, after which it may no longer be used. + drop-udp-socket: func(this: udp-socket) /// Bind the socket to a specific IP address and port. /// @@ -45,7 +49,7 @@ resource udp-socket implements ip-socket { /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html /// - https://man7.org/linux/man-pages/man2/bind.2.html - bind: func(local-address: ip-socket-address) -> future> + bind: func(this: udp-socket, local-address: ip-socket-address) -> result<_, error> /// Get the current bound address. /// @@ -54,7 +58,7 @@ resource udp-socket implements ip-socket { /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html /// - https://man7.org/linux/man-pages/man2/getsockname.2.html - local-address: func() -> expected + local-address: func(this: udp-socket) -> result /// receive a message. /// @@ -68,7 +72,7 @@ resource udp-socket implements ip-socket { /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html /// - https://man7.org/linux/man-pages/man2/recv.2.html - receive: func() -> future> + receive: func(this: udp-socket) -> result /// send a message to a specific destination address. /// @@ -79,7 +83,7 @@ resource udp-socket implements ip-socket { /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html /// - https://man7.org/linux/man-pages/man2/send.2.html - send: func(datagram: datagram) -> future> + send: func(this: udp-socket, datagram: datagram) -> result<_, error> /// Set the destination address. /// @@ -100,14 +104,14 @@ resource udp-socket implements ip-socket { /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html /// - https://man7.org/linux/man-pages/man2/connect.2.html - connect: func(remote-address: ip-socket-address) -> future> + connect: func(this: udp-socket, remote-address: ip-socket-address) -> result<_, error> /// Get the address set with `connect`. /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html /// - https://man7.org/linux/man-pages/man2/getpeername.2.html - remote-address: func() -> expected + remote-address: func(this: udp-socket) -> result /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -121,8 +125,44 @@ resource udp-socket implements ip-socket { /// Fails when this socket is in the Listening state. /// /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - receive-buffer-size: func() -> expected - set-receive-buffer-size: func(value: usize) -> expected - send-buffer-size: func() -> expected - set-send-buffer-size: func(value: usize) -> expected -} \ No newline at end of file + receive-buffer-size: func(this: udp-socket) -> result + set-receive-buffer-size: func(this: udp-socket, value: u64) -> result<_, error> + send-buffer-size: func(this: udp-socket) -> result + set-send-buffer-size: func(this: udp-socket, value: u64) -> result<_, error> + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func(this: udp-socket) -> ip-address-family + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + unicast-hop-limit: func(this: udp-socket) -> result + set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error> + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// Implementations are not required to support dual-stack mode, so calling `set-ipv6-only(false)` might fail. + /// + /// Fails when called on an IPv4 socket. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + ipv6-only: func(this: udp-socket) -> result + set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error> + + + /// Get/set the blocking mode of the socket. + /// + /// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. + /// When switched to "non-blocking" mode, operations that would block return an `again` error. After which + /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. + /// + /// Note: these functions are here for WASI Preview2 only. + /// They're planned to be removed when `async` is natively supported in Preview3. + non-blocking: func(this: udp-socket) -> result + set-non-blocking: func(this: udp-socket, value: bool) -> result<_, error> + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `async` is natively supported in Preview3. + subscribe: func(this: udp-socket) -> pollable +} From 4704b4a0d417d7883200886eb179b3bbda87a847 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Feb 2023 23:11:04 +0100 Subject: [PATCH 1045/1772] Introduce the concept "attaching" a socket to a network. This enables libc to defer committing to a specific network handle up to the moment the actual local/remote addresses are known. Also rearranged the functions to be in a more logical order. --- proposals/sockets/wasi-ip-name-lookup.wit | 6 +- proposals/sockets/wasi-network.wit | 2 + proposals/sockets/wasi-tcp-create-socket.wit | 19 +++ proposals/sockets/wasi-tcp.wit | 161 ++++++++++--------- proposals/sockets/wasi-udp-create-socket.wit | 19 +++ proposals/sockets/wasi-udp.wit | 135 +++++++++------- 6 files changed, 204 insertions(+), 138 deletions(-) create mode 100644 proposals/sockets/wasi-tcp-create-socket.wit create mode 100644 proposals/sockets/wasi-udp-create-socket.wit diff --git a/proposals/sockets/wasi-ip-name-lookup.wit b/proposals/sockets/wasi-ip-name-lookup.wit index 67fa0a3df..face2d2cf 100644 --- a/proposals/sockets/wasi-ip-name-lookup.wit +++ b/proposals/sockets/wasi-ip-name-lookup.wit @@ -48,6 +48,8 @@ default interface wasi-ip-name-lookup { /// Dispose of the specified `resolve-address-stream`, after which it may no longer be used. + /// + /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. drop-resolve-address-stream: func(this: resolve-address-stream) /// Get/set the blocking mode of the stream. @@ -57,13 +59,13 @@ default interface wasi-ip-name-lookup { /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. /// /// Note: these functions are here for WASI Preview2 only. - /// They're planned to be removed when `async` is natively supported in Preview3. + /// They're planned to be removed when `future` is natively supported in Preview3. non-blocking: func(this: resolve-address-stream) -> result set-non-blocking: func(this: resolve-address-stream, value: bool) -> result<_, error> /// Create a `pollable` which will resolve once the stream is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `async` is natively supported in Preview3. + /// It's planned to be removed when `future` is natively supported in Preview3. subscribe: func(this: resolve-address-stream) -> pollable } diff --git a/proposals/sockets/wasi-network.wit b/proposals/sockets/wasi-network.wit index 80fc56c2a..e738a8286 100644 --- a/proposals/sockets/wasi-network.wit +++ b/proposals/sockets/wasi-network.wit @@ -8,6 +8,8 @@ default interface wasi-network { type network = u32 /// Dispose of the specified `network`, after which it may no longer be used. + /// + /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. drop-network: func(this: network) diff --git a/proposals/sockets/wasi-tcp-create-socket.wit b/proposals/sockets/wasi-tcp-create-socket.wit new file mode 100644 index 000000000..3bc91cc01 --- /dev/null +++ b/proposals/sockets/wasi-tcp-create-socket.wit @@ -0,0 +1,19 @@ + +default interface wasi-tcp-create-socket { + use pkg.wasi-network.{network, error, ip-address-family} + use pkg.wasi-tcp.{tcp-socket} + + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not "attached" to any `network` yet. Up to the moment `attach` is called, + /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// References: + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html + /// - https://man7.org/linux/man-pages/man2/socket.2.html + /// + create-tcp-socket: func(address-family: ip-address-family) -> result +} diff --git a/proposals/sockets/wasi-tcp.wit b/proposals/sockets/wasi-tcp.wit index 53bb8ccf9..cdfd2809a 100644 --- a/proposals/sockets/wasi-tcp.wit +++ b/proposals/sockets/wasi-tcp.wit @@ -5,7 +5,7 @@ default interface wasi-tcp { use pkg.wasi-network.{network, error, ip-socket-address, ip-address-family} /// A TCP socket handle. - type tcp-socket = u32 + type tcp-socket = u32 enum shutdown-type { @@ -19,18 +19,13 @@ default interface wasi-tcp { both, } - /// Create a new TCP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. - /// - /// References: - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html - /// - https://man7.org/linux/man-pages/man2/socket.2.html + + /// Attach the socket to a specific network. /// - create-tcp-socket: func(network: network, address-family: ip-address-family) -> result - - /// Dispose of the specified `tcp-socket`, after which it may no longer be used. - drop-tcp-socket: func(this: tcp-socket) + /// Only "attached" sockets can perform any I/O. + /// + /// Returns an error if the socket is already attached. + attach: func(this: tcp-socket, network: network) -> result<_, error> /// Bind the socket to a specific IP address and port. /// @@ -41,68 +36,43 @@ default interface wasi-tcp { /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will /// implicitly bind the socket. /// - /// Returns an error if the socket is already bound. + /// Fails when: + /// - the socket is not attached to a network. + /// - the socket is already bound. /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html /// - https://man7.org/linux/man-pages/man2/bind.2.html bind: func(this: tcp-socket, local-address: ip-socket-address) -> result<_, error> - /// Get the current bound address. + /// Connect to a remote endpoint. /// - /// Returns an error if the socket is not bound. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html - /// - https://man7.org/linux/man-pages/man2/getsockname.2.html - local-address: func(this: tcp-socket) -> result - - /// Connect to a remote endpoint. + /// On success: + /// - the socket is transitioned into the Connection state + /// - a pair of streams is returned that can be used to read & write to the connection /// - /// Transitions the socket into the Connection state. - /// Fails when the socket is already in the Connection or Listener state. - /// - /// On success, this function returns a pair of streams that can be used to read & write to the connection. + /// Fails when: + /// - the socket is not attached to a network. + /// - the socket is already in the Connection or Listener state. + /// - either the remote IP address or port is 0. /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html /// - https://man7.org/linux/man-pages/man2/connect.2.html connect: func(this: tcp-socket, remote-address: ip-socket-address) -> result, error> - /// Gracefully shut down the connection. - /// - /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read - /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. - /// Any data still in the receive queue at time of calling `shutdown` will be discarded. - /// - send: the socket is not expecting to send any more data to the peer. All subsequent write - /// operations on the `output-stream` associated with this socket will return an error. - /// - both: same effect as receive & send combined. - /// - /// The shutdown function does not close the socket. - /// - /// Fails when the socket is not in the Connection state. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html - /// - https://man7.org/linux/man-pages/man2/shutdown.2.html - shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error> - /// Start listening for new connections. /// /// Transitions the socket into the Listener state. - /// Fails when the socket is already in the Connection or Listener state. /// + /// Fails when: + /// - the socket is not attached to a network. + /// - the socket is already in the Connection or Listener state. + /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html /// - https://man7.org/linux/man-pages/man2/listen.2.html - listen: func(this: tcp-socket, backlog-size-hint: option) -> result<_, error> - - /// Fails when the socket is not in the Connection state. - /// - /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html - /// - https://man7.org/linux/man-pages/man2/getpeername.2.html - remote-address: func(this: tcp-socket) -> result + listen: func(this: tcp-socket) -> result<_, error> /// Accept a new client socket. /// @@ -118,6 +88,41 @@ default interface wasi-tcp { /// - https://man7.org/linux/man-pages/man2/accept.2.html accept: func(this: tcp-socket) -> result, error> + /// Get the bound local address. + /// + /// Returns an error if the socket is not bound. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html + /// - https://man7.org/linux/man-pages/man2/getsockname.2.html + local-address: func(this: tcp-socket) -> result + + /// Get the bound remote address. + /// + /// Fails when the socket is not in the Connection state. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html + /// - https://man7.org/linux/man-pages/man2/getpeername.2.html + remote-address: func(this: tcp-socket) -> result + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func(this: tcp-socket) -> result + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// Implementations are not required to support dual-stack mode. Calling `set-ipv6-only(false)` might fail. + /// + /// Fails when called on an IPv4 socket. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + ipv6-only: func(this: tcp-socket) -> result + set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error> + + /// Hints the desired listen queue size. Implementations are free to ignore this. + set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error> + /// Equivalent to the SO_KEEPALIVE socket option. keep-alive: func(this: tcp-socket) -> result set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error> @@ -125,6 +130,10 @@ default interface wasi-tcp { /// Equivalent to the TCP_NODELAY socket option. no-delay: func(this: tcp-socket) -> result set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error> + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + unicast-hop-limit: func(this: tcp-socket) -> result + set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error> /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -143,25 +152,6 @@ default interface wasi-tcp { send-buffer-size: func(this: tcp-socket) -> result set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error> - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: tcp-socket) -> ip-address-family - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - unicast-hop-limit: func(this: tcp-socket) -> result - set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error> - - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// Implementations are not required to support dual-stack mode, so calling `set-ipv6-only(false)` might fail. - /// - /// Fails when called on an IPv4 socket. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - ipv6-only: func(this: tcp-socket) -> result - set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error> - - /// Get/set the blocking mode of the socket. /// /// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. @@ -169,13 +159,36 @@ default interface wasi-tcp { /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. /// /// Note: these functions are here for WASI Preview2 only. - /// They're planned to be removed when `async` is natively supported in Preview3. + /// They're planned to be removed when `future` is natively supported in Preview3. non-blocking: func(this: tcp-socket) -> result set-non-blocking: func(this: tcp-socket, value: bool) -> result<_, error> /// Create a `pollable` which will resolve once the socket is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `async` is natively supported in Preview3. + /// It's planned to be removed when `future` is natively supported in Preview3. subscribe: func(this: tcp-socket) -> pollable + + /// Gracefully shut down the connection. + /// + /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read + /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. + /// Any data still in the receive queue at time of calling `shutdown` will be discarded. + /// - send: the socket is not expecting to send any more data to the peer. All subsequent write + /// operations on the `output-stream` associated with this socket will return an error. + /// - both: same effect as receive & send combined. + /// + /// The shutdown function does not close the socket. + /// + /// Fails when the socket is not in the Connection state. + /// + /// References + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html + /// - https://man7.org/linux/man-pages/man2/shutdown.2.html + shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error> + + /// Dispose of the specified `tcp-socket`, after which it may no longer be used. + /// + /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. + drop-tcp-socket: func(this: tcp-socket) } diff --git a/proposals/sockets/wasi-udp-create-socket.wit b/proposals/sockets/wasi-udp-create-socket.wit new file mode 100644 index 000000000..3fd14ed54 --- /dev/null +++ b/proposals/sockets/wasi-udp-create-socket.wit @@ -0,0 +1,19 @@ + +default interface wasi-udp-create-socket { + use pkg.wasi-network.{network, error, ip-address-family} + use pkg.wasi-udp.{udp-socket} + + /// Create a new UDP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not "attached" to any `network` yet. Up to the moment `attach` is called, + /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// References: + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html + /// - https://man7.org/linux/man-pages/man2/socket.2.html + /// + create-udp-socket: func(address-family: ip-address-family) -> result +} diff --git a/proposals/sockets/wasi-udp.wit b/proposals/sockets/wasi-udp.wit index 5fe79a90b..bd88e13a7 100644 --- a/proposals/sockets/wasi-udp.wit +++ b/proposals/sockets/wasi-udp.wit @@ -3,6 +3,11 @@ default interface wasi-udp { use pkg.wasi-poll.{pollable} use pkg.wasi-network.{network, error, ip-socket-address, ip-address-family} + + /// A UDP socket handle. + type udp-socket = u32 + + record datagram { data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. remote-address: ip-socket-address, @@ -15,21 +20,14 @@ default interface wasi-udp { /// ecn: u2, // IP_RECVTOS } - /// A UDP socket handle. - type udp-socket = u32 - /// Create a new UDP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. - /// - /// References: - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html - /// - https://man7.org/linux/man-pages/man2/socket.2.html + + /// Attach the socket to a specific network. /// - create-udp-socket: func(network: network, address-family: ip-address-family) -> result - - /// Dispose of the specified `udp-socket`, after which it may no longer be used. - drop-udp-socket: func(this: udp-socket) + /// Only "attached" sockets can perform any I/O. + /// + /// Returns an error if the socket is already attached. + attach: func(this: udp-socket, network: network) -> result<_, error> /// Bind the socket to a specific IP address and port. /// @@ -37,10 +35,12 @@ default interface wasi-udp { /// network interface(s) to bind to. /// If the TCP/UDP port is zero, the socket will be bound to a random free port. /// - /// When a socket is not explicitly bound, the first invocation to a send or receive operation will + /// When a socket is not explicitly bound, the first invocation to a connect, send or receive operation will /// implicitly bind the socket. /// - /// Returns an error if the socket is already bound. + /// Fails when: + /// - the socket is not attached to a network. + /// - the socket is already bound. /// /// TODO: disallow wildcard binds as long as there isn't a way to pass the local address to send & receive? /// - https://blog.cloudflare.com/everything-you-ever-wanted-to-know-about-udp-sockets-but-were-afraid-to-ask-part-1/#sourcing-packets-from-a-wildcard-socket @@ -51,22 +51,38 @@ default interface wasi-udp { /// - https://man7.org/linux/man-pages/man2/bind.2.html bind: func(this: udp-socket, local-address: ip-socket-address) -> result<_, error> - /// Get the current bound address. + /// Set the destination address. /// - /// Returns an error if the socket is not bound. + /// When a destination address is set: + /// - all receive operations will only return datagrams sent from the provided `remote-address`. + /// - the `send` function can still be used to send to any other destination, however you can't receive their response. + /// + /// Similar to `connect(sock, ...)` in POSIX. + /// + /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". + /// + /// Fails when: + /// - the socket is not attached to a network. + /// + /// TODO: "connect" is a rather odd name for this function because it doesn't reflect what's actually happening. + /// Feels like it was chosen just to shoehorn UDP into the existing Socket interface. + /// Do we have to keep this name? + /// + /// TODO: add unconnect ability. /// /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html - /// - https://man7.org/linux/man-pages/man2/getsockname.2.html - local-address: func(this: udp-socket) -> result + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html + /// - https://man7.org/linux/man-pages/man2/connect.2.html + connect: func(this: udp-socket, remote-address: ip-socket-address) -> result<_, error> - /// receive a message. + /// Receive a message. /// /// Returns: /// - The sender address of the datagram /// - The number of bytes read. - /// - When the received datagram is larger than the provided buffers, - /// the excess data is lost and the `truncated` flag will be set. + /// + /// Fails when: + /// - the socket is not attached to a network. /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html @@ -74,37 +90,28 @@ default interface wasi-udp { /// - https://man7.org/linux/man-pages/man2/recv.2.html receive: func(this: udp-socket) -> result - /// send a message to a specific destination address. + /// Send a message to a specific destination address. /// /// The remote address option is required. To send a message to the "connected" peer, /// call `remote-address` to get their address. /// + /// Fails when: + /// - the socket is not attached to a network. + /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html /// - https://man7.org/linux/man-pages/man2/send.2.html send: func(this: udp-socket, datagram: datagram) -> result<_, error> - /// Set the destination address. - /// - /// When a destination address is set: - /// - all receive operations will only return datagrams sent from the provided `remote-address`. - /// - the `send` function can still be used to send to any other destination, however you can't receive their response. - /// - /// Similar to `connect(sock, ...)` in POSIX. - /// - /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". - /// - /// TODO: "connect" is a rather odd name for this function because it doesn't reflect what's actually happening. - /// Feels like it was chosen just to shoehorn UDP into the existing Socket interface. - /// Do we have to keep this name? + /// Get the current bound address. /// - /// TODO: add unconnect ability. + /// Returns an error if the socket is not bound. /// /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html - /// - https://man7.org/linux/man-pages/man2/connect.2.html - connect: func(this: udp-socket, remote-address: ip-socket-address) -> result<_, error> + /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html + /// - https://man7.org/linux/man-pages/man2/getsockname.2.html + local-address: func(this: udp-socket) -> result /// Get the address set with `connect`. /// @@ -113,6 +120,24 @@ default interface wasi-udp { /// - https://man7.org/linux/man-pages/man2/getpeername.2.html remote-address: func(this: udp-socket) -> result + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func(this: udp-socket) -> result + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// Implementations are not required to support dual-stack mode, so calling `set-ipv6-only(false)` might fail. + /// + /// Fails when called on an IPv4 socket. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + ipv6-only: func(this: udp-socket) -> result + set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error> + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + unicast-hop-limit: func(this: udp-socket) -> result + set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error> + /// The kernel buffer space reserved for sends/receives on this socket. /// /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. @@ -130,25 +155,6 @@ default interface wasi-udp { send-buffer-size: func(this: udp-socket) -> result set-send-buffer-size: func(this: udp-socket, value: u64) -> result<_, error> - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: udp-socket) -> ip-address-family - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - unicast-hop-limit: func(this: udp-socket) -> result - set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error> - - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// Implementations are not required to support dual-stack mode, so calling `set-ipv6-only(false)` might fail. - /// - /// Fails when called on an IPv4 socket. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - ipv6-only: func(this: udp-socket) -> result - set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error> - - /// Get/set the blocking mode of the socket. /// /// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. @@ -156,13 +162,18 @@ default interface wasi-udp { /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. /// /// Note: these functions are here for WASI Preview2 only. - /// They're planned to be removed when `async` is natively supported in Preview3. + /// They're planned to be removed when `future` is natively supported in Preview3. non-blocking: func(this: udp-socket) -> result set-non-blocking: func(this: udp-socket, value: bool) -> result<_, error> /// Create a `pollable` which will resolve once the socket is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `async` is natively supported in Preview3. + /// It's planned to be removed when `future` is natively supported in Preview3. subscribe: func(this: udp-socket) -> pollable + + /// Dispose of the specified `udp-socket`, after which it may no longer be used. + /// + /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. + drop-udp-socket: func(this: udp-socket) } From 2dbc630885abdcc9d1f1fa6557032b3cc6aeb086 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Fri, 10 Feb 2023 11:45:34 -0600 Subject: [PATCH 1046/1772] add initial proposal contents --- proposals/http/README.md | 37 +++++- proposals/http/wit/deps/io/streams.wit | 128 ++++++++++++++++++++ proposals/http/wit/deps/logging/handler.wit | 31 +++++ proposals/http/wit/incoming-handler.wit | 21 ++++ proposals/http/wit/outgoing-handler.wit | 15 +++ proposals/http/wit/proxy.wit | 32 +++++ proposals/http/wit/types.wit | 128 ++++++++++++++++++++ 7 files changed, 391 insertions(+), 1 deletion(-) create mode 100644 proposals/http/wit/deps/io/streams.wit create mode 100644 proposals/http/wit/deps/logging/handler.wit create mode 100644 proposals/http/wit/incoming-handler.wit create mode 100644 proposals/http/wit/outgoing-handler.wit create mode 100644 proposals/http/wit/proxy.wit create mode 100644 proposals/http/wit/types.wit diff --git a/proposals/http/README.md b/proposals/http/README.md index 2d9e040ce..6c69289b7 100644 --- a/proposals/http/README.md +++ b/proposals/http/README.md @@ -1,3 +1,38 @@ # WASI HTTP -(This is a placeholder so there can be a PR to fill in the contents.) +A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. + +This proposal currently only contains the proposed Wit interfaces with light +explanation in comments; more work is necessary to fully document the proposal. +The Wit comments annotate where the proposed interface is expected to change in +the short term (for Preview2) once resources and handles are re-added to Wit, +and then after that (for Preview2) once native stream support is added to the +Component Model and Wit. + +The `wit` directory currently validates and can generate bindings with: +``` +wit-bindgen c wit/ --world proxy +``` +or can be manipulated in other ways with: +``` +wasm-tools component wit wit/ ... +``` + +The HTTP proposal depends on the WASI IO and Logging proposals. For simplicity, +the Wit files for these proposals are currently copied into the `wit/deps` +directory and will be updated periodically to match their respective proposals. +As the Wit tooling develops, we should be able to avoid this form of manual +vendoring. + +### Current Phase + +wasi-http is currently in [Phase 1](https://github.com/WebAssembly/WASI/blob/main/Proposals.md). + +### Champions + +Piotr Sikora, Jiaxiao Zhou, Dan Chiarlone, David Justice + +### TODO + +This readme needs to be expanded to cover a number of additional fields suggested in the +[WASI Proposal template](https://github.com/WebAssembly/wasi-proposal-template). diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit new file mode 100644 index 000000000..4e18e08c3 --- /dev/null +++ b/proposals/http/wit/deps/io/streams.wit @@ -0,0 +1,128 @@ +default interface streams { + /// An error type returned from a stream operation. Currently this + /// doesn't provide any additional information. + record stream-error {} + + /// An input bytestream. In the future, this will be replaced by handle + /// types. + /// + /// This conceptually represents a `stream`. It's temporary + /// scaffolding until component-model's async features are ready. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + type input-stream = u32 + + /// Read bytes from a stream. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a bool indicating whether the end of the stream + /// was reached. The returned list will contain up to `len` bytes; it + /// may return fewer than requested, but not more. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// If `len` is 0, it represents a request to read 0 bytes, which should + /// always succeed, assuming the stream hasn't reached its end yet, and + /// return an empty list. + /// + /// The len here is a `u64`, but some callees may not be able to allocate + /// a buffer as large as that would imply. + /// FIXME: describe what happens if allocation fails. + read: func( + /// The stream to read from + src: input-stream, + /// The maximum number of bytes to read + len: u64 + ) -> result, bool>, stream-error> + + /// Skip bytes from a stream. + /// + /// This is similar to the `read` function, but avoids copying the + /// bytes into the instance. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// This function returns the number of bytes skipped, along with a bool + /// indicating whether the end of the stream was reached. The returned + /// value will be at most `len`; it may be less. + skip: func( + /// The stream to skip in + src: input-stream, + /// The maximum number of bytes to skip. + len: u64, + ) -> result, stream-error> + + /// An output bytestream. In the future, this will be replaced by handle + /// types. + /// + /// This conceptually represents a `stream`. It's temporary + /// scaffolding until component-model's async features are ready. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + type output-stream = u32 + + /// Write bytes to a stream. + /// + /// This function returns a `u64` indicating the number of bytes from + /// `buf` that were written; it may be less than the full list. + write: func( + /// The stream to write to + dst: output-stream, + /// Data to write + buf: list + ) -> result + + /// Write a single byte multiple times to a stream. + /// + /// This function returns a `u64` indicating the number of copies of + /// `byte` that were written; it may be less than `len`. + write-repeated: func( + /// The stream to write to + dst: output-stream, + /// The byte to write + byte: u8, + /// The number of times to write it + len: u64 + ) -> result + + /// Read from one stream and write to another. + /// + /// This function returns the number of bytes transferred; it may be less + /// than `len`. + splice: func( + /// The stream to write to + dst: output-stream, + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result, stream-error> + + /// Forward the entire contents of an input stream to an output stream. + /// + /// This function repeatedly reads from the input stream and writes + /// the data to the output stream, until the end of the input stream + /// is reached, or an error is encountered. + /// + /// This function returns the number of bytes transferred. + forward: func( + /// The stream to write to + dst: output-stream, + /// The stream to read from + src: input-stream + ) -> result + + /// Dispose of the specified input-stream, after which it may no longer + /// be used. + drop-input-stream: func(f: input-stream) + + /// Dispose of the specified output-stream, after which it may no longer + /// be used. + drop-output-stream: func(f: output-stream) +} diff --git a/proposals/http/wit/deps/logging/handler.wit b/proposals/http/wit/deps/logging/handler.wit new file mode 100644 index 000000000..1f5cc125a --- /dev/null +++ b/proposals/http/wit/deps/logging/handler.wit @@ -0,0 +1,31 @@ +/// # WASI Logging API +/// +/// WASI Logging is a logging API intended to let users emit log messages with +/// simple priority levels and context values. +default interface handler { + /// A log level, describing a kind of message. + enum level { + /// Describes messages about the values of variables and the flow of control + /// within a program. + trace, + + /// Describes messages likely to be of interest to someone debugging a program. + debug, + + /// Describes messages likely to be of interest to someone monitoring a program. + info, + + /// Describes messages indicating hazardous situations. + warn, + + /// Describes messages indicating serious errors. + error, + } + + /// Emit a log message. + /// + /// A log message has a `level` describing what kind of message is being sent, + /// a context, which is an uninterpreted string meant to help consumers group + /// similar messages, and a string containing the message text. + log: func(level: level, context: string, message: string) +} diff --git a/proposals/http/wit/incoming-handler.wit b/proposals/http/wit/incoming-handler.wit new file mode 100644 index 000000000..47fbe89e2 --- /dev/null +++ b/proposals/http/wit/incoming-handler.wit @@ -0,0 +1,21 @@ +// The `wasi:http/incoming-handler` interface is meant to be exported by +// components and called by the host in response to a new incoming HTTP +// response. +// +// NOTE: in Preview3, this interface will be merged with +// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface +// that takes a `request` parameter and returns a `response` result. +// +default interface incoming-handler { + use pkg.types.{incoming-request, response-outparam} + + // The `handle` function takes an outparam instead of returning its response + // so that the component may stream its response while streaming any other + // request or response bodies. The callee MUST write a response to the + // `response-out` and then finish the response before returning. The `handle` + // function is allowed to continue execution after finishing the response's + // output stream. While this post-response execution is taken off the + // critical path, since there is no return value, there is no way to report + // its success or failure. + handle: func(request: incoming-request, response-out: response-outparam) +} diff --git a/proposals/http/wit/outgoing-handler.wit b/proposals/http/wit/outgoing-handler.wit new file mode 100644 index 000000000..b0d5738ec --- /dev/null +++ b/proposals/http/wit/outgoing-handler.wit @@ -0,0 +1,15 @@ +// The `wasi:http/outgoing-handler` interface is meant to be imported by +// components and implemented by the host. +// +// NOTE: in Preview3, this interface will be merged with +// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface +// that takes a `request` parameter and returns a `response` result. +// +default interface outgoing-handler { + use pkg.types.{outgoing-request, incoming-response, error} + + // The parameter and result types of the `handle` function allow the caller + // to concurrently stream the bodies of the outgoing request and the incoming + // response. + handle: func(request: outgoing-request) -> result +} diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit new file mode 100644 index 000000000..c9f17f6f2 --- /dev/null +++ b/proposals/http/wit/proxy.wit @@ -0,0 +1,32 @@ +// The `wasi:http/proxy` world captures a widely-implementable intersection of +// hosts that includes HTTP forward and reverse proxies. Components targeting +// this world may concurrently stream in and out any number of incoming and +// outgoing HTTP requests. +default world proxy { + + // This is the default logging handler to use when user code simply wants to + // log to a developer-facing console (e.g., via `console.log()`). + import console: logging.handler + + // TODO: add `import metrics: metrics.counters` + + // This is the default handler to use when user code simply wants to make an + // HTTP request (e.g., via `fetch()`) but doesn't otherwise specify a + // particular handler. + import default-upstream-HTTP: pkg.outgoing-handler + + // TODO: Once the underlying Wit template machinery is implemented, add: + // + // import upstreams: interface { + // *: pkg.outgoing-handler + // } + // + // which will allow a component to import any number of non-default backends + // that HTTP requests can be dispatched to. + + // The host delivers incoming HTTP requests to a component by calling the + // `handle` function of this exported interface. A host may arbitrarily reuse + // or not reuse component instance when delivering incoming HTTP requests and + // thus a component must be able to handle 0..N calls to `handle`. + export HTTP: pkg.incoming-handler +} diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit new file mode 100644 index 000000000..b0851357d --- /dev/null +++ b/proposals/http/wit/types.wit @@ -0,0 +1,128 @@ +// The `wasi:http/types` interface is meant to be imported by components to +// define the HTTP resource types and operations used by the component's +// imported and exported interfaces. +default interface types { + + // This type corresponds to HTTP standard Methods. + variant method { + get, + head, + post, + put, + delete, + connect, + options, + trace, + patch + } + + // This type corresponds to HTTP standard Related Schemes. + variant scheme { + HTTP, + HTTPS, + other(string) + } + + // This type enumerates the different kinds of errors that may occur when + // initially returning a response. + variant error { + invalid-url(string), + timeout-error(string), + protocol-error(string), + status-error(u16), + unexpected-error(string) + } + + // This following block defines the `fields` resource which corresponds to + // HTTP standard Fields. Soon, when resource types are added, the `type + // fields = u32` type alias can be replaced by a proper `resource fields` + // definition containing all the functions using the method syntactic sugar. + type fields = u32 + drop-fields: func(fields: fields) + new-fields: func(entries: list>) -> fields + fields-get: func(fields: fields, name: string) -> list + fields-set: func(fields: fields, name: string, value: list) + fields-delete: func(fields: fields, name: string) + fields-append: func(fields: fields, name: string, value: string) + fields-entries: func(fields: fields) -> list> + fields-clone: func(fields: fields) -> fields + + type headers = fields + type trailers = fields + + // The following block defines the `body` type which corresponds to the HTTP + // standard Contents. With Preview3, all of these fields can be replaced by a + // single type definition: + // + // type body = stream> + // + // In the interim, we need to use separate `input-stream` and `output-stream` + // resource types defined by `wasi:io/streams`. The `finish-` functions + // emulate the stream's result value and MUST be called exactly once after + // the final read/write from/to the stream before dropping the stream. + use io.streams.{input-stream, output-stream} + type incoming-body = input-stream + type outgoing-body = output-stream + finish-incoming-body: func(body: incoming-body) -> option + finish-outgoing-body: func(body: outgoing-body, trailers: option) + + // The following block defines the `incoming-request` and `outgoing-request` + // resource types that correspond to HTTP standard Requests. Soon, when + // resource types are added, the `u32` type aliases can be replaced by + // proper `resource` type definitions containing all the functions as + // methods. Later, Preview2 will allow both types to be merged together into + // a single `request` type (that uses the single `body` type mentioned + // above). The `consume` and `write-body` methods may only be called once + // (and return failure thereafter). + type incoming-request = u32 + type outgoing-request = u32 + drop-incoming-request: func(request: incoming-request) + drop-outgoing-request: func(request: outgoing-request) + incoming-request-method: func(request: incoming-request) -> method + incoming-request-path: func(request: incoming-request) -> string + incoming-request-scheme: func(request: incoming-request) -> option + incoming-request-authority: func(request: incoming-request) -> string + incoming-request-headers: func(request: incoming-request) -> headers + incoming-request-consume: func(request: incoming-request) -> result + new-outgoing-request: func( + method: method, + path: string, + scheme: option, + authority: string, + headers: headers + ) -> outgoing-request + outgoing-request-write-body: func(request: outgoing-request) -> result + + // The following block defines a special resource type used by the + // `wasi:http/outgoing-handler` interface. When resource types are added, this + // block can be replaced by a proper `resource response-outparam { ... }` + // definition. Later, with Preview3, the need for an outparam goes away entirely + // (the `wasi:http/handler` interface used for both incoming and outgoing can + // simply return a `body`). + type response-outparam = u32 + drop-response-outparam: func(response: response-outparam) + set-response-outparam: func(response: result) -> result + + // This type corresponds to the HTTP standard Status Code. + type status-code = u16 + + // The following block defines the `incoming-response` and `outgoing-response` + // resource types that correspond to HTTP standard Responses. Soon, when + // resource types are added, the `u32` type aliases can be replaced by proper + // `resource` type definitions containing all the functions as methods. Later, + // Preview2 will allow both types to be merged together into a single `response` + // type (that uses the single `body` type mentioned above). The `consume` and + // `write-body` methods may only be called once (and return failure thereafter). + type incoming-response = u32 + type outgoing-response = u32 + drop-incoming-response: func(response: incoming-response) + drop-outgoing-response: func(response: outgoing-response) + incoming-response-status: func(response: incoming-response) -> status-code + incoming-response-headers: func(response: incoming-response) -> headers + incoming-response-consume: func(response: incoming-response) -> result + new-outgoing-response: func( + status-code: status-code, + headers: headers + ) -> outgoing-response + outgoing-response-write-body: func(response: outgoing-response) -> result +} From c01ed59cc812b38d1a9debb8a2ce61c2958c13c7 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Sat, 18 Feb 2023 11:51:06 -0600 Subject: [PATCH 1047/1772] Add other(string) case to the 'method' variant --- proposals/http/wit/types.wit | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index b0851357d..1d610f9bc 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -13,7 +13,8 @@ default interface types { connect, options, trace, - patch + patch, + other(string) } // This type corresponds to HTTP standard Related Schemes. From f51411f5bf35faffa6ebe21932bd038e86cbb997 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 18 Feb 2023 10:00:43 -0800 Subject: [PATCH 1048/1772] Improve the proposal repo layout. (#7) * Improve the proposal repo layout. - Change from `.wit.md` files with wit-embedded-in-markdown-code-comments to just `.wit` files containing just Wit. Feedback from early users so far has been that people want to just maintain plain wit. - Use the new `--html-in-md` option to generate the prettier HTML output in the `.md` file, which is rendered on Github. The specifics here may evolve, but overall the idea is: - Don't check in `.html` files into the repo, as they can't be rendered and as such are confusing. - Do check in a generated `.md` file, with as much formatting and linkifying as we can get. The generated HTML has a *lot* of room for improvement. But at least with this PR the HTML is viewable from the Github UI and it has a table of contents and the formatting is a little tidier. * Add a `deps` directory example. Add an example dependency using a `deps` directory. And rename some things for clarity. * Update to wit-abi-0.10.0. This updates to the 0.3.0 release of wit-bindgen. --- proposals/sockets/.github/workflows/main.yml | 4 +- proposals/sockets/README.md | 2 + proposals/sockets/example-world.md | 72 +++++++++++++++++++ proposals/sockets/wasi-proposal-template.html | 24 ------- proposals/sockets/wasi-proposal-template.md | 33 --------- .../wit/deps/example-dep/example-api.wit | 6 ++ proposals/sockets/wit/example.wit | 59 +++++++++++++++ .../sockets/wit/proposal-template.wit.md | 45 ------------ proposals/sockets/wit/world.wit | 10 +++ proposals/sockets/wit/world.wit.md | 12 ---- 10 files changed, 151 insertions(+), 116 deletions(-) create mode 100644 proposals/sockets/example-world.md delete mode 100644 proposals/sockets/wasi-proposal-template.html delete mode 100644 proposals/sockets/wasi-proposal-template.md create mode 100644 proposals/sockets/wit/deps/example-dep/example-api.wit create mode 100644 proposals/sockets/wit/example.wit delete mode 100644 proposals/sockets/wit/proposal-template.wit.md create mode 100644 proposals/sockets/wit/world.wit delete mode 100644 proposals/sockets/wit/world.wit.md diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index 8ca235c4f..ad1997c51 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v10 + - uses: WebAssembly/wit-abi-up-to-date@v12 with: - wit-abi-tag: wit-abi-0.8.0 + wit-abi-tag: wit-abi-0.10.0 diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index e76604398..733036b3d 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -55,6 +55,8 @@ TODO before entering Phase 2. ### API walk-through +The full API documentation can be found [here](wasi-proposal-template.md). + [Walk through of how someone would use this API.] #### [Use case 1] diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md new file mode 100644 index 000000000..c58d36466 --- /dev/null +++ b/proposals/sockets/example-world.md @@ -0,0 +1,72 @@ +

    World example-world

    + +

    Import interface example-dep-interface

    +
    +

    Types

    +

    type example-dep-type

    +

    u32

    +

    +## Import interface example-interface +

    Short interface description.

    +

    Explanation for developers using the interface API. It should include an +overview of the API as a whole as well as call out notable items in it, +for example example-api-type and example-api-function.

    +
    +

    Types

    +

    type example-dep-type

    +

    example-dep-type

    +

    +#### `record example-api-type` +

    Short type description

    +

    Explanation for developers using this type. It may be useful to give +some examples of places in the API where the type is used, such as in +the arguments and return type of example-api-function.

    +
    +Detailed specification +More rigorous specification details for implementers go here, if needed. +The intention is to keep the developer-oriented docs focused on things that +most developers will need to be aware of, while putting bulkier descriptions +of precise behavior here. +
    +
    Record Fields
    +
      +
    • +

      field0: u64

      +

      A description of a field. +

    • +
    • +

      field1: string

      +

      A description of another field. +

    • +
    +
    +

    Functions

    +

    example-api-function: func

    +

    Short function description

    +

    Explanation for developers using the API. This should describe the +arguments which in this function are arg0, arg1, and arg2, and the +return value.

    +
    +Detailed specification +Similar to the details section above, this is meant for more rigorous +specification details for implementors. This may explain what a compliant +implementation MUST do, such as never returning an earlier result from a +later call, for example. +
    +
    Params
    + +
    Return values
    + diff --git a/proposals/sockets/wasi-proposal-template.html b/proposals/sockets/wasi-proposal-template.html deleted file mode 100644 index 0db3b9a4e..000000000 --- a/proposals/sockets/wasi-proposal-template.html +++ /dev/null @@ -1,24 +0,0 @@ -

    Import interface proposal-interface-name

    -

    Types

    -

    api-type-one: record

    -

    Short description

    -

    Explanation for developers using the API.

    -

    Size: 16, Alignment: 8

    -

    Record Fields

    - -

    Functions

    -
    -

    api-function-one

    -

    Short description

    -

    Explanation for developers using the API.

    -
    Results
    - diff --git a/proposals/sockets/wasi-proposal-template.md b/proposals/sockets/wasi-proposal-template.md deleted file mode 100644 index ee404c310..000000000 --- a/proposals/sockets/wasi-proposal-template.md +++ /dev/null @@ -1,33 +0,0 @@ -# Import interface `proposal-interface-name` - -## Types - -## `api-type-one`: record - -Short description - -Explanation for developers using the API. - -Size: 16, Alignment: 8 - -### Record Fields - -- [`property1`](#api_type_one.property1): `u64` - - -- [`property2`](#api_type_one.property2): `string` - - -## Functions - ----- - -#### `api-function-one` - -Short description - -Explanation for developers using the API. -##### Results - -- `result0`: [`api-type-one`](#api_type_one) - diff --git a/proposals/sockets/wit/deps/example-dep/example-api.wit b/proposals/sockets/wit/deps/example-dep/example-api.wit new file mode 100644 index 000000000..60da3235d --- /dev/null +++ b/proposals/sockets/wit/deps/example-dep/example-api.wit @@ -0,0 +1,6 @@ +// An example dependency, showing how these look. Actual proposals should +// delete this file and add their actual dependencies in the `deps` directory. + +interface example-dep-interface { + type example-dep-type = u32 +} diff --git a/proposals/sockets/wit/example.wit b/proposals/sockets/wit/example.wit new file mode 100644 index 000000000..04b038198 --- /dev/null +++ b/proposals/sockets/wit/example.wit @@ -0,0 +1,59 @@ +// Instructions for filling in this file: +// +// - Delete all these `//` comments, up to the first `///` comment. +// +// - Replace the remaining contents below with [Wit] code describing +// `interface`s and/or `world`s, using the same formatting style. +// +// If you want to include examples of the API in use, these should be in the +// README.md at the root of the repository and linked to from this file. +// +// [Wit]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md + +/// Short interface description. +/// +/// Explanation for developers using the interface API. It should include an +/// overview of the API as a whole as well as call out notable items in it, +/// for example `example-api-type` and `example-api-function`. +default interface example-interface { + use example-dep.example-api.example-dep-interface.{example-dep-type} + + /// Short type description + /// + /// Explanation for developers using this type. It may be useful to give + /// some examples of places in the API where the type is used, such as in + /// the arguments and return type of `example-api-function`. + /// + ///
    + /// Detailed specification + /// More rigorous specification details for implementers go here, if needed. + /// The intention is to keep the developer-oriented docs focused on things that + /// most developers will need to be aware of, while putting bulkier descriptions + /// of precise behavior here. + ///
    + record example-api-type { + /// A description of a field. + field0: u64, + /// A description of another field. + field1: string, + } + + /// Short function description + /// + /// Explanation for developers using the API. This should describe the + /// arguments which in this function are `arg0`, `arg1`, and `arg2`, and the + /// return value. + /// + ///
    + /// Detailed specification + /// Similar to the details section above, this is meant for more rigorous + /// specification details for implementors. This may explain what a compliant + /// implementation MUST do, such as never returning an earlier result from a + /// later call, for example. + ///
    + example-api-function: func( + arg0: example-api-type, + arg1: string, + arg2: example-dep-type, + ) -> result +} diff --git a/proposals/sockets/wit/proposal-template.wit.md b/proposals/sockets/wit/proposal-template.wit.md deleted file mode 100644 index c8f0c5bf1..000000000 --- a/proposals/sockets/wit/proposal-template.wit.md +++ /dev/null @@ -1,45 +0,0 @@ -# [Proposal Template] API - -[This document contains the actual specification. It should be written in the WIT interface definition format. You can find more documentation on the WIT syntax (coming soon!).] - -[Note that all comments inside of WIT code blocks will be included in the developer facing documentation for language bindings generated using this WIT file. If there is additional information that needs to be communicated to implementers of the API, then these should be captured in text directly below the code block.] - -[If you want to include examples of the API in use, these should be in the README and linked to from this file.] - -## `proposal-interface-name` - -```wit -/// Short interface description. -/// -/// Explanation for developers using the interface API. -default interface proposal-interface-name { -``` - -## `api_type_one` - -```wit -/// Short description -/// -/// Explanation for developers using the API. -record api-type-one { - property1: u64, - property2: string, -} -``` - -More rigorous specification details for the implementer go here, if needed. - -## `api_function_one` - -```wit -/// Short description -/// -/// Explanation for developers using the API. -api-function-one: func() -> api-type-one -``` - -If needed, this would explain what a compliant implementation MUST do, such as never returning an earlier result from a later call. - -```wit -} -``` diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit new file mode 100644 index 000000000..17821ee6e --- /dev/null +++ b/proposals/sockets/wit/world.wit @@ -0,0 +1,10 @@ +// If the repository defines `interface`s, this file can define a minimal world +// which contains those interfaces, to allow documentation to be generated for +// them. +// +// Proposals should remove these `//` commments, and edit the `world` name and +// imports below to pull in their own `interface`s. + +default world example-world { + import example-interface: pkg.example.example-interface +} diff --git a/proposals/sockets/wit/world.wit.md b/proposals/sockets/wit/world.wit.md deleted file mode 100644 index b2f0fb0ac..000000000 --- a/proposals/sockets/wit/world.wit.md +++ /dev/null @@ -1,12 +0,0 @@ -This file contains a world that imports all interfaces in this proposal. Its -primary purpose is to allow unified documentation to be easily generated for -the whole proposal. - -Proposals should edit replace the import below (and this sentence) with imports -of their own interfaces. - -```wit -default world wasi-proposal-template { - import proposal-interface-name: pkg.proposal-template.proposal-interface-name -} -``` From 802232e8c39840b6a008000eedf2758150e973ba Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 19 Feb 2023 12:22:55 +0100 Subject: [PATCH 1049/1772] Fold the "attaching" & "binding" concepts into one. That way, they become a single atomic operation. This allows POSIX compatibility layers to iterate over all candidate network handles and try the `bind/listen/connect` operation on each handle until one of them succeeds. --- proposals/sockets/wasi-tcp-create-socket.wit | 4 +-- proposals/sockets/wasi-tcp.wit | 22 +++++------- proposals/sockets/wasi-udp-create-socket.wit | 2 +- proposals/sockets/wasi-udp.wit | 37 ++++++-------------- 4 files changed, 21 insertions(+), 44 deletions(-) diff --git a/proposals/sockets/wasi-tcp-create-socket.wit b/proposals/sockets/wasi-tcp-create-socket.wit index 3bc91cc01..06074fb70 100644 --- a/proposals/sockets/wasi-tcp-create-socket.wit +++ b/proposals/sockets/wasi-tcp-create-socket.wit @@ -8,8 +8,8 @@ default interface wasi-tcp-create-socket { /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. /// /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not "attached" to any `network` yet. Up to the moment `attach` is called, - /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` + /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// /// References: /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html diff --git a/proposals/sockets/wasi-tcp.wit b/proposals/sockets/wasi-tcp.wit index cdfd2809a..62e99fc3b 100644 --- a/proposals/sockets/wasi-tcp.wit +++ b/proposals/sockets/wasi-tcp.wit @@ -19,15 +19,8 @@ default interface wasi-tcp { both, } - - /// Attach the socket to a specific network. - /// - /// Only "attached" sockets can perform any I/O. - /// - /// Returns an error if the socket is already attached. - attach: func(this: tcp-socket, network: network) -> result<_, error> - /// Bind the socket to a specific IP address and port. + /// Bind the socket to a specific network on the provided IP address and port. /// /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which /// network interface(s) to bind to. @@ -37,13 +30,12 @@ default interface wasi-tcp { /// implicitly bind the socket. /// /// Fails when: - /// - the socket is not attached to a network. /// - the socket is already bound. /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html /// - https://man7.org/linux/man-pages/man2/bind.2.html - bind: func(this: tcp-socket, local-address: ip-socket-address) -> result<_, error> + bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error> /// Connect to a remote endpoint. /// @@ -52,27 +44,29 @@ default interface wasi-tcp { /// - a pair of streams is returned that can be used to read & write to the connection /// /// Fails when: - /// - the socket is not attached to a network. + /// - the socket is already bound to a different network. + /// - the provided network does not allow connections to the specified endpoint. /// - the socket is already in the Connection or Listener state. /// - either the remote IP address or port is 0. /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html /// - https://man7.org/linux/man-pages/man2/connect.2.html - connect: func(this: tcp-socket, remote-address: ip-socket-address) -> result, error> + connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result, error> /// Start listening for new connections. /// /// Transitions the socket into the Listener state. /// /// Fails when: - /// - the socket is not attached to a network. + /// - the socket is already bound to a different network. + /// - the provided network does not allow listening on the specified address. /// - the socket is already in the Connection or Listener state. /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html /// - https://man7.org/linux/man-pages/man2/listen.2.html - listen: func(this: tcp-socket) -> result<_, error> + listen: func(this: tcp-socket, network: network) -> result<_, error> /// Accept a new client socket. /// diff --git a/proposals/sockets/wasi-udp-create-socket.wit b/proposals/sockets/wasi-udp-create-socket.wit index 3fd14ed54..1a5a17d2e 100644 --- a/proposals/sockets/wasi-udp-create-socket.wit +++ b/proposals/sockets/wasi-udp-create-socket.wit @@ -8,7 +8,7 @@ default interface wasi-udp-create-socket { /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. /// /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not "attached" to any `network` yet. Up to the moment `attach` is called, + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` is called, /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// /// References: diff --git a/proposals/sockets/wasi-udp.wit b/proposals/sockets/wasi-udp.wit index bd88e13a7..570f059d9 100644 --- a/proposals/sockets/wasi-udp.wit +++ b/proposals/sockets/wasi-udp.wit @@ -21,15 +21,8 @@ default interface wasi-udp { } - - /// Attach the socket to a specific network. - /// - /// Only "attached" sockets can perform any I/O. - /// - /// Returns an error if the socket is already attached. - attach: func(this: udp-socket, network: network) -> result<_, error> - /// Bind the socket to a specific IP address and port. + /// Bind the socket to a specific network on the provided IP address and port. /// /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which /// network interface(s) to bind to. @@ -39,41 +32,30 @@ default interface wasi-udp { /// implicitly bind the socket. /// /// Fails when: - /// - the socket is not attached to a network. /// - the socket is already bound. /// - /// TODO: disallow wildcard binds as long as there isn't a way to pass the local address to send & receive? - /// - https://blog.cloudflare.com/everything-you-ever-wanted-to-know-about-udp-sockets-but-were-afraid-to-ask-part-1/#sourcing-packets-from-a-wildcard-socket - /// - https://blog.powerdns.com/2012/10/08/on-binding-datagram-udp-sockets-to-the-any-addresses/ - /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html /// - https://man7.org/linux/man-pages/man2/bind.2.html - bind: func(this: udp-socket, local-address: ip-socket-address) -> result<_, error> + bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error> /// Set the destination address. /// + /// The local-address is updated based on the best network path to `remote-address`. + /// /// When a destination address is set: /// - all receive operations will only return datagrams sent from the provided `remote-address`. - /// - the `send` function can still be used to send to any other destination, however you can't receive their response. - /// - /// Similar to `connect(sock, ...)` in POSIX. + /// - the `send` function can only be used to send to this destination. /// /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". /// /// Fails when: - /// - the socket is not attached to a network. - /// - /// TODO: "connect" is a rather odd name for this function because it doesn't reflect what's actually happening. - /// Feels like it was chosen just to shoehorn UDP into the existing Socket interface. - /// Do we have to keep this name? - /// - /// TODO: add unconnect ability. + /// - the socket is already bound to a different network. /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html /// - https://man7.org/linux/man-pages/man2/connect.2.html - connect: func(this: udp-socket, remote-address: ip-socket-address) -> result<_, error> + connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error> /// Receive a message. /// @@ -82,7 +64,7 @@ default interface wasi-udp { /// - The number of bytes read. /// /// Fails when: - /// - the socket is not attached to a network. + /// - the socket is not bound. /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html @@ -96,7 +78,8 @@ default interface wasi-udp { /// call `remote-address` to get their address. /// /// Fails when: - /// - the socket is not attached to a network. + /// - the socket is not bound. Unlike POSIX, this function does not perform an implicit bind. + /// - the socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html From 9954d7f30ee0b5c540162e69c2711bddbec3d74a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Sun, 19 Feb 2023 21:48:12 +0100 Subject: [PATCH 1050/1772] Improve naming consistency and semantics (#102) * Improve naming consistency and semantics. (#99) The goal of the proposed changes are: * Make the API more consistent and predictable * Reduce the cognitive load involved by some inconsistencies * Allow better APIs for language bindings generated automatically The proposed changes below are: * Remove unneeded prefixes potentially not needed due to the namespaced nature of WIT interfaces * Expand meaningful prefix to their full name except for very long names ("synchronize" or "Synchronization" remain "sync") * Use - as a name separator consistently * Use singular for enums * Use plural for flags * Use more descriptive terms when relevant * Rename remaining short parameter names len -> length buf -> buffer --- .../filesystem/wit/wasi-filesystem.wit.md | 284 +++++++++--------- 1 file changed, 141 insertions(+), 143 deletions(-) diff --git a/proposals/filesystem/wit/wasi-filesystem.wit.md b/proposals/filesystem/wit/wasi-filesystem.wit.md index 308a3e2b6..a48fdb175 100644 --- a/proposals/filesystem/wit/wasi-filesystem.wit.md +++ b/proposals/filesystem/wit/wasi-filesystem.wit.md @@ -66,10 +66,10 @@ flags descriptor-flags { /// Requests non-blocking operation. /// /// When this flag is enabled, functions may return immediately with an - /// `errno::again` error code in situations where they would otherwise + /// `error-code::would-block` error code in situations where they would otherwise /// block. However, this non-blocking behavior is not required. /// Implementations are permitted to ignore this flag and block. - nonblock, + non-blocking, /// Request that writes be performed according to synchronized I/O file /// integrity completion. The data stored in the file and the file's /// metadata are synchronized. @@ -77,7 +77,7 @@ flags descriptor-flags { /// The precise semantics of this operation have not yet been defined for /// WASI. At this time, it should be interpreted as a request, and not a /// requirement. - sync, + file-integrity-sync, /// Request that writes be performed according to synchronized I/O data /// integrity completion. Only the data stored in the file is /// synchronized. @@ -85,20 +85,20 @@ flags descriptor-flags { /// The precise semantics of this operation have not yet been defined for /// WASI. At this time, it should be interpreted as a request, and not a /// requirement. - dsync, + data-integrity-sync, /// Requests that reads be performed at the same level of integrety /// requested for writes. /// /// The precise semantics of this operation have not yet been defined for /// WASI. At this time, it should be interpreted as a request, and not a /// requirement. - rsync, + requested-write-sync, /// Mutating directories mode: Directory contents may be mutated. /// /// When this flag is unset on a descriptor, operations using the /// descriptor which would create, rename, delete, modify the data or /// metadata of filesystem objects, or obtain another handle which - /// would permit any of those, shall fail with `errno::rofs` if + /// would permit any of those, shall fail with `error-code::read-only` if /// they would otherwise succeed. /// /// This may only be set on directories. @@ -113,54 +113,54 @@ flags descriptor-flags { /// Note: This was called `filestat` in earlier versions of WASI. record descriptor-stat { /// Device ID of device containing the file. - dev: device, + device: device, /// File serial number. - ino: inode, + inode: inode, /// File type. %type: descriptor-type, /// Number of hard links to the file. - nlink: linkcount, + link-count: link-count, /// For regular files, the file size in bytes. For symbolic links, the length /// in bytes of the pathname contained in the symbolic link. size: filesize, /// Last data access timestamp. - atim: datetime, + data-access-timestamp: datetime, /// Last data modification timestamp. - mtim: datetime, + data-modification-timestamp: datetime, /// Last file status change timestamp. - ctim: datetime, + status-change-timestamp: datetime, } ``` -## `at-flags` +## `path-flags` ```wit /// Flags determining the method of how paths are resolved. -flags at-flags { +flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is expanded. symlink-follow, } ``` -## `o-flags` +## `open-flags` ```wit /// Open flags used by `open-at`. -flags o-flags { +flags open-flags { /// Create file if it does not exist. create, /// Fail if not a directory. directory, /// Fail if file already exists. - excl, + exclusive, /// Truncate file to size 0. - trunc, + truncate, } ``` -## `mode` +## `modes` ```wit /// Permissions mode used by `open-at`, `change-file-permissions-at`, and /// similar. -flags mode { +flags modes { /// True if the resource is considered readable by the containing /// filesystem. readable, @@ -173,10 +173,10 @@ flags mode { } ``` -## `linkcount` +## `link-count` ```wit /// Number of hard links to an inode. -type linkcount = u64 +type link-count = u64 ``` ## `device` @@ -206,17 +206,17 @@ variant new-timestamp { } ``` -## `dir-entry` +## `directory-entry` ```wit /// A directory entry. -record dir-entry { +record directory-entry { /// The serial number of the object referred to by this directory entry. /// May be none if the inode value is not known. /// /// When this is none, libc implementations might do an extra `stat-at` /// call to retrieve the inode number to fill their `d_ino` fields, so /// implementations which can set this to a non-none value should do so. - ino: option, + inode: option, /// The type of the file referred to by this directory entry. %type: descriptor-type, @@ -226,89 +226,87 @@ record dir-entry { } ``` -## `errno` +## `error-code` ```wit /// Error codes returned by functions. /// Not all of these error codes are returned by the functions provided by this /// API; some are used in higher-level library layers, and others are provided /// merely for alignment with POSIX. -enum errno { +enum error-code { /// Permission denied. access, /// Resource unavailable, or operation would block. - again, + would-block, /// Connection already in progress. already, /// Bad descriptor. - badf, + bad-descriptor, /// Device or resource busy. busy, /// Resource deadlock would occur. - deadlk, + deadlock, /// Storage quota exceeded. - dquot, + quota, /// File exists. exist, /// File too large. - fbig, + file-too-large, /// Illegal byte sequence. - ilseq, + Illegal-byte-sequence, /// Operation in progress. - inprogress, + in-progress, /// Interrupted function. - intr, + interrupted, /// Invalid argument. - inval, + invalid, /// I/O error. io, /// Is a directory. - isdir, + is-directory, /// Too many levels of symbolic links. loop, /// Too many links. - mlink, + too-many-links, /// Message too large. - msgsize, + message-size, /// Filename too long. - nametoolong, + name-too-long, /// No such device. - nodev, + no-device, /// No such file or directory. - noent, + no-entry, /// No locks available. - nolck, + no-lock, /// Not enough space. - nomem, + insufficient-memory, /// No space left on device. - nospc, - /// Function not supported. - nosys, + insufficient-space, /// Not a directory or a symbolic link to a directory. - notdir, + not-directory, /// Directory not empty. - notempty, + not-empty, /// State not recoverable. - notrecoverable, - /// Not supported, or operation not supported on socket. - notsup, + not-recoverable, + /// Not supported + unsupported, /// Inappropriate I/O control operation. - notty, + no-tty, /// No such device or address. - nxio, + no-such-device, /// Value too large to be stored in data type. overflow, /// Operation not permitted. - perm, + not-permitted, /// Broken pipe. pipe, /// Read-only file system. - rofs, + read-only, /// Invalid seek. - spipe, + invalid-seek, /// Text file busy. - txtbsy, + text-file-busy, /// Cross-device link. - xdev, + cross-device, } ``` @@ -349,7 +347,7 @@ read-via-stream: func( this: descriptor, /// The offset within the file at which to start reading. offset: filesize, -) -> result +) -> result ``` ## `write-via-stream` @@ -361,7 +359,7 @@ write-via-stream: func( this: descriptor, /// The offset within the file at which to start writing. offset: filesize, -) -> result +) -> result ``` ## `append-via-stream` @@ -374,26 +372,26 @@ append-via-stream: func( this: descriptor, /// The resource to operate on. fd: descriptor, -) -> result +) -> result ``` -## `fadvise` +## `advise` ```wit /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. -fadvise: func( +advise: func( this: descriptor, /// The offset within the file to which the advisory applies. offset: filesize, /// The length of the region to which the advisory applies. - len: filesize, + length: filesize, /// The advice. advice: advice -) -> result<_, errno> +) -> result<_, error-code> ``` -## `datasync` +## `sync-data` ```wit /// Synchronize the data of a file to disk. /// @@ -401,10 +399,10 @@ fadvise: func( /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. -datasync: func(this: descriptor) -> result<_, errno> +sync-data: func(this: descriptor) -> result<_, error-code> ``` -## `flags` +## `get-flags` ```wit /// Get flags associated with a descriptor. /// @@ -412,10 +410,10 @@ datasync: func(this: descriptor) -> result<_, errno> /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. -%flags: func(this: descriptor) -> result +get-flags: func(this: descriptor) -> result ``` -## `type` +## `get-type` ```wit /// Get the dynamic type of a descriptor. /// @@ -427,19 +425,19 @@ datasync: func(this: descriptor) -> result<_, errno> /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. -%type: func(this: descriptor) -> result +get-type: func(this: descriptor) -> result ``` ## `set-flags` ```wit /// Set status flags associated with a descriptor. /// -/// This function may only change the `append` and `nonblock` flags. +/// This function may only change the `non-blocking` flag. /// /// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. /// /// Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. -set-flags: func(this: descriptor, %flags: descriptor-flags) -> result<_, errno> +set-flags: func(this: descriptor, %flags: descriptor-flags) -> result<_, error-code> ``` ## `set-size` @@ -448,7 +446,7 @@ set-flags: func(this: descriptor, %flags: descriptor-flags) -> result<_, errno> /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. -set-size: func(this: descriptor, size: filesize) -> result<_, errno> +set-size: func(this: descriptor, size: filesize) -> result<_, error-code> ``` ## `set-times` @@ -461,34 +459,34 @@ set-size: func(this: descriptor, size: filesize) -> result<_, errno> set-times: func( this: descriptor, /// The desired values of the data access timestamp. - atim: new-timestamp, + data-access-timestamp: new-timestamp, /// The desired values of the data modification timestamp. - mtim: new-timestamp, -) -> result<_, errno> + data-modification-timestamp: new-timestamp, +) -> result<_, error-code> ``` -## `pread` +## `read` ```wit /// Read from a descriptor, without using and updating the descriptor's offset. /// /// This function returns a list of bytes containing the data that was /// read, along with a bool which, when true, indicates that the end of the -/// file was reached. The returned list will contain up to `len` bytes; it +/// file was reached. The returned list will contain up to `length` bytes; it /// may return fewer than requested, if the end of the file is reached or /// if the I/O operation is interrupted. /// /// Note: This is similar to `pread` in POSIX. -// TODO(stream) -pread: func( +// TODO(stream) +read: func( this: descriptor, /// The maximum number of bytes to read. - len: filesize, + length: filesize, /// The offset within the file at which to read. offset: filesize, ) -> result, bool>, errno> ``` -## `pwrite` +## `write` ```wit /// Write to a descriptor, without using and updating the descriptor's offset. /// @@ -497,17 +495,17 @@ pread: func( /// the write set to zero. /// /// Note: This is similar to `pwrite` in POSIX. -// TODO(stream) -pwrite: func( +// TODO(stream) +write: func( this: descriptor, /// Data to write - buf: list, + buffer: list, /// The offset within the file at which to write. offset: filesize, -) -> result +) -> result ``` -## `readdir` +## `read-directory` ```wit /// Read directory entries from a directory. /// @@ -517,7 +515,7 @@ pwrite: func( /// /// This always returns a new stream which starts at the beginning of the /// directory. -readdir: func(this: descriptor) -> result +read-directory: func(this: descriptor) -> result ``` ## `sync` @@ -528,7 +526,7 @@ readdir: func(this: descriptor) -> result /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. -sync: func(this: descriptor) -> result<_, errno> +sync: func(this: descriptor) -> result<_, error-code> ``` ## `create-directory-at` @@ -540,7 +538,7 @@ create-directory-at: func( this: descriptor, /// The relative path at which to create the directory. path: string, -) -> result<_, errno> +) -> result<_, error-code> ``` ## `stat` @@ -550,7 +548,7 @@ create-directory-at: func( /// Note: This is similar to `fstat` in POSIX. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. -stat: func(this: descriptor) -> result +stat: func(this: descriptor) -> result ``` ## `stat-at` @@ -563,10 +561,10 @@ stat: func(this: descriptor) -> result stat-at: func( this: descriptor, /// Flags determining the method of how the path is resolved. - at-flags: at-flags, + path-flags: path-flags, /// The relative path of the file or directory to inspect. path: string, -) -> result +) -> result ``` ## `set-times-at` @@ -579,14 +577,14 @@ stat-at: func( set-times-at: func( this: descriptor, /// Flags determining the method of how the path is resolved. - at-flags: at-flags, + path-flags: path-flags, /// The relative path of the file or directory to operate on. path: string, /// The desired values of the data access timestamp. - atim: new-timestamp, + data-access-timestamp: new-timestamp, /// The desired values of the data modification timestamp. - mtim: new-timestamp, -) -> result<_, errno> + data-modification-timestamp: new-timestamp, +) -> result<_, error-code> ``` ## `link-at` @@ -597,14 +595,14 @@ set-times-at: func( link-at: func( this: descriptor, /// Flags determining the method of how the path is resolved. - old-at-flags: at-flags, + old-path-flags: path-flags, /// The relative source path from which to link. old-path: string, /// The base directory for `new-path`. new-descriptor: descriptor, /// The relative destination path at which to create the hard link. new-path: string, -) -> result<_, errno> +) -> result<_, error-code> ``` ## `open-at` @@ -619,27 +617,27 @@ link-at: func( /// /// If `flags` contains `descriptor-flags::mutate-directory`, and the base /// descriptor doesn't have `descriptor-flags::mutate-directory` set, -/// `open-at` fails with `errno::rofs`. +/// `open-at` fails with `error-code::read-only`. /// -/// If `flags` contains `write` or `append`, or `o-flags` contains `trunc` +/// If `flags` contains `write`, or `open-flags` contains `truncate` /// or `create`, and the base descriptor doesn't have /// `descriptor-flags::mutate-directory` set, `open-at` fails with -/// `errno::rofs`. +/// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. open-at: func( this: descriptor, /// Flags determining the method of how the path is resolved. - at-flags: at-flags, + path-flags: path-flags, /// The relative path of the object to open. path: string, /// The method by which to open the file. - o-flags: o-flags, + open-flags: open-flags, /// Flags to use for the resulting descriptor. %flags: descriptor-flags, /// Permissions to use when creating a new file. - mode: mode -) -> result + modes: modes +) -> result ``` ## `readlink-at` @@ -651,21 +649,21 @@ readlink-at: func( this: descriptor, /// The relative path of the symbolic link from which to read. path: string, -) -> result +) -> result ``` ## `remove-directory-at` ```wit /// Remove a directory. /// -/// Return `errno::notempty` if the directory is not empty. +/// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. remove-directory-at: func( this: descriptor, /// The relative path to a directory to remove. path: string, -) -> result<_, errno> +) -> result<_, error-code> ``` ## `rename-at` @@ -681,7 +679,7 @@ rename-at: func( new-descriptor: descriptor, /// The relative destination path to which to rename the file or directory. new-path: string, -) -> result<_, errno> +) -> result<_, error-code> ``` ## `symlink-at` @@ -695,20 +693,20 @@ symlink-at: func( old-path: string, /// The relative destination path at which to create the symbolic link. new-path: string, -) -> result<_, errno> +) -> result<_, error-code> ``` ## `unlink-file-at` ```wit /// Unlink a filesystem object that is not a directory. /// -/// Return `errno::isdir` if the path refers to a directory. +/// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. unlink-file-at: func( this: descriptor, /// The relative path to a file to unlink. path: string, -) -> result<_, errno> +) -> result<_, error-code> ``` ## `change-file-permissions-at` @@ -722,12 +720,12 @@ unlink-file-at: func( change-file-permissions-at: func( this: descriptor, /// Flags determining the method of how the path is resolved. - at-flags: at-flags, + path-flags: path-flags, /// The relative path to operate on. path: string, /// The new permissions for the filesystem object. - mode: mode, -) -> result<_, errno> + modes: modes, +) -> result<_, error-code> ``` ## `change-dir-permissions-at` @@ -745,12 +743,12 @@ change-file-permissions-at: func( change-directory-permissions-at: func( this: descriptor, /// Flags determining the method of how the path is resolved. - at-flags: at-flags, + path-flags: path-flags, /// The relative path to operate on. path: string, /// The new permissions for the directory. - mode: mode, -) -> result<_, errno> + modes: modes, +) -> result<_, error-code> ``` ## `lock-shared` @@ -772,10 +770,10 @@ change-directory-permissions-at: func( /// This function blocks until the lock can be acquired. /// /// Not all filesystems support locking; on filesystems which don't support -/// locking, this function returns `errno::notsup`. +/// locking, this function returns `error-code::unsupported`. /// /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. -lock-shared: func(this: descriptor) -> result<_, errno> +lock-shared: func(this: descriptor) -> result<_, error-code> ``` ## `lock-exclusive` @@ -799,10 +797,10 @@ lock-shared: func(this: descriptor) -> result<_, errno> /// This function blocks until the lock can be acquired. /// /// Not all filesystems support locking; on filesystems which don't support -/// locking, this function returns `errno::notsup`. +/// locking, this function returns `error-code::unsupported`. /// /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. -lock-exclusive: func(this: descriptor) -> result<_, errno> +lock-exclusive: func(this: descriptor) -> result<_, error-code> ``` ## `try-lock-shared` @@ -821,13 +819,13 @@ lock-exclusive: func(this: descriptor) -> result<_, errno> /// It is unspecified how shared locks interact with locks acquired by /// non-WASI programs. /// -/// This function returns `errno::again` if the lock cannot be acquired. +/// This function returns `error-code::would-block` if the lock cannot be acquired. /// /// Not all filesystems support locking; on filesystems which don't support -/// locking, this function returns `errno::notsup`. +/// locking, this function returns `error-code::unsupported`. /// /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. -try-lock-shared: func(this: descriptor) -> result<_, errno> +try-lock-shared: func(this: descriptor) -> result<_, error-code> ``` ## `try-lock-exclusive` @@ -848,13 +846,13 @@ try-lock-shared: func(this: descriptor) -> result<_, errno> /// is not opened for writing. It is unspecified how exclusive locks interact /// with locks acquired by non-WASI programs. /// -/// This function returns `errno::again` if the lock cannot be acquired. +/// This function returns `error-code::would-block` if the lock cannot be acquired. /// /// Not all filesystems support locking; on filesystems which don't support -/// locking, this function returns `errno::notsup`. +/// locking, this function returns `error-code::unsupported`. /// /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. -try-lock-exclusive: func(this: descriptor) -> result<_, errno> +try-lock-exclusive: func(this: descriptor) -> result<_, error-code> ``` ## `unlock` @@ -862,7 +860,7 @@ try-lock-exclusive: func(this: descriptor) -> result<_, errno> /// Release a shared or exclusive lock on an open file. /// /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. -unlock: func(this: descriptor) -> result<_, errno> +unlock: func(this: descriptor) -> result<_, error-code> ``` # `drop-descriptor` @@ -873,26 +871,26 @@ unlock: func(this: descriptor) -> result<_, errno> drop-descriptor: func(this: descriptor) ``` -## `dir-entry-stream` +## `directory-entry-stream` ```wit /// A stream of directory entries. -// TODO(resource dir-entry-stream {) -// TODO(stream) -type dir-entry-stream = u32 +// TODO(resource directory-entry-stream {) +// TODO(stream) +type directory-entry-stream = u32 ``` -## `read-dir-entry` +## `read-directory-entry` ```wit -/// Read a single directory entry from a `dir-entry-stream`. -read-dir-entry: func(this: dir-entry-stream) -> result, errno> +/// Read a single directory entry from a `directory-entry-stream`. +read-directory-entry: func(this: directory-entry-stream) -> result, error-code> ``` -# `drop-dir-entry-stream` +# `drop-directory-entry-stream` ```wit -/// Dispose of the specified `dir-entry-stream`, after which it may no longer +/// Dispose of the specified `directory-entry-stream`, after which it may no longer /// be used. -// TODO(} /* resource dir-entry-stream */) -drop-dir-entry-stream: func(this: dir-entry-stream) +// TODO(} /* resource directory-entry-stream */) +drop-directory-entry-stream: func(this: directory-entry-stream) ``` ```wit From 1431618558fa6b008715ae5ba936490367c0fc27 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 21 Feb 2023 13:38:55 -0600 Subject: [PATCH 1051/1772] Fix the extra argument to `append-via-stream`, and misc. doc updates (#100) * Fix the extra argument to `append-via-stream`, and misc. doc updates Fix a spurious extra argument to `append-via-stream`. Also, add some miscellaneous documentation updates, including: - Describing filesystem path separators and sandboxing behavior - Clarifying that streams are independent of each other. - Remove stale references to the `append` flag. * More minor formatting fixes. * Document that `symlink-at` can't create absolute-path symlinks. --- proposals/filesystem/README.md | 2 +- proposals/filesystem/wasi-filesystem.html | 358 +++++++++--------- proposals/filesystem/wasi-filesystem.md | 351 ++++++++--------- .../filesystem/wit/wasi-filesystem.wit.md | 34 +- 4 files changed, 385 insertions(+), 360 deletions(-) diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index ac2e3f0c2..f040ed1ef 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -78,7 +78,7 @@ defined behaviors, which would conflict with the goal of being efficient. #### Opening a file -```rust= +```rust /// Write "Hello, World" into a file called "greeting.txt" in `dir`. fn write_hello_world_to_a_file(dir: Descriptor) -> Result<(), Errno> { let at_flags = AtFlags::FollowSymlinks; diff --git a/proposals/filesystem/wasi-filesystem.html b/proposals/filesystem/wasi-filesystem.html index 684052770..49ebbd35e 100644 --- a/proposals/filesystem/wasi-filesystem.html +++ b/proposals/filesystem/wasi-filesystem.html @@ -278,58 +278,69 @@

    Size: 4, Alignment: 4

    datetime: datetime

    Size: 16, Alignment: 8

    -

    o-flags: record

    +

    path-flags: record

    +

    Flags determining the method of how paths are resolved.

    +

    Size: 1, Alignment: 1

    +

    Record Fields

    +
      +
    • +

      symlink-follow:

      +

      As long as the resolved path corresponds to a symbolic link, it is expanded. +Bit: 0

      +
    • +
    +

    open-flags: record

    Open flags used by open-at.

    Size: 1, Alignment: 1

    Record Fields

    -

    mode: record

    +

    modes: record

    Permissions mode used by open-at, change-file-permissions-at, and similar.

    Size: 1, Alignment: 1

    Record Fields

    • -

      readable:

      +

      readable:

      True if the resource is considered readable by the containing filesystem. Bit: 0

    • -

      writeable:

      +

      writeable:

      True if the resource is considered writeable by the containing filesystem. Bit: 1

    • -

      executable:

      +

      executable:

      True if the resource is considered executable by the containing filesystem. This does not apply to directories. Bit: 2

    -

    linkcount: u64

    +

    link-count: u64

    Number of hard links to an inode.

    Size: 8, Alignment: 8

    inode: u64

    @@ -338,7 +349,7 @@

    inode:

    filesize: u64

    File size or length of a region within a file.

    Size: 8, Alignment: 8

    -

    errno: enum

    +

    error-code: enum

    Error codes returned by functions. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -347,159 +358,155 @@

    errno:

    Enum Cases

    -

    dir-entry-stream: u32

    +

    directory-entry-stream: u32

    A stream of directory entries.

    Size: 4, Alignment: 4

    device: u64

    @@ -546,13 +553,13 @@

    Enum Cases

    The descriptor refers to a socket.

    -

    dir-entry: record

    +

    directory-entry: record

    A directory entry.

    Size: 32, Alignment: 8

    Record Fields

    • -

      ino: option<inode>

      +

      inode: option<inode>

      The serial number of the object referred to by this directory entry. May be none if the inode value is not known.

      When this is none, libc implementations might do an extra stat-at @@ -560,11 +567,11 @@

      Record Fields

      implementations which can set this to a non-none value should do so.

    • -

      type: descriptor-type

      +

      type: descriptor-type

      The type of the file referred to by this directory entry.

    • -

      name: string

      +

      name: string

      The name of the object.

    @@ -585,16 +592,16 @@

    Record Fields

    Bit: 1

  • -

    nonblock:

    +

    non-blocking:

    Requests non-blocking operation.

    When this flag is enabled, functions may return immediately with an -errno::again error code in situations where they would otherwise +error-code::would-block error code in situations where they would otherwise block. However, this non-blocking behavior is not required. Implementations are permitted to ignore this flag and block. Bit: 2

  • -

    sync:

    +

    file-integrity-sync:

    Request that writes be performed according to synchronized I/O file integrity completion. The data stored in the file and the file's metadata are synchronized.

    @@ -604,7 +611,7 @@

    Record Fields

    Bit: 3

  • -

    dsync:

    +

    data-integrity-sync:

    Request that writes be performed according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized.

    @@ -614,7 +621,7 @@

    Record Fields

    Bit: 4

  • -

    rsync:

    +

    requested-write-sync:

    Requests that reads be performed at the same level of integrety requested for writes.

    The precise semantics of this operation have not yet been defined for @@ -628,7 +635,7 @@

    Record Fields

    When this flag is unset on a descriptor, operations using the descriptor which would create, rename, delete, modify the data or metadata of filesystem objects, or obtain another handle which -would permit any of those, shall fail with errno::rofs if +would permit any of those, shall fail with error-code::read-only if they would otherwise succeed.

    This may only be set on directories. Bit: 6

    @@ -665,19 +672,19 @@

    dev: device

    +

    device: device

    Device ID of device containing the file.

  • -

    ino: inode

    +

    inode: inode

    File serial number.

  • -

    type: descriptor-type

    +

    type: descriptor-type

    File type.

  • -

    nlink: linkcount

    +

    link-count: link-count

    Number of hard links to the file.

  • @@ -686,29 +693,18 @@

    Record Fields

    in bytes of the pathname contained in the symbolic link.

  • -

    atim: datetime

    +

    data-access-timestamp: datetime

    Last data access timestamp.

  • -

    mtim: datetime

    +

    data-modification-timestamp: datetime

    Last data modification timestamp.

  • -

    ctim: datetime

    +

    status-change-timestamp: datetime

    Last file status change timestamp.

  • -

    at-flags: record

    -

    Flags determining the method of how paths are resolved.

    -

    Size: 1, Alignment: 1

    -

    Record Fields

    -
      -
    • -

      symlink-follow:

      -

      As long as the resolved path corresponds to a symbolic link, it is expanded. -Bit: 0

      -
    • -

    advice: enum

    File or memory access pattern advisory information.

    Size: 1, Alignment: 1

    @@ -743,6 +739,8 @@

    Functions


    read-via-stream

    Return a stream for reading from a file.

    +

    Multiple read, write, and append streams may be active on the same open +file and they do not interfere with each other.

    Note: This allows using read-stream, which is similar to read in POSIX.

    Params
      @@ -751,7 +749,7 @@
      Params
    Results

    write-via-stream

    @@ -764,7 +762,7 @@
    Params
    Results

    append-via-stream

    @@ -778,55 +776,55 @@
    Params
    Results

    -

    fadvise

    +

    advise

    Provide file advisory information on a descriptor.

    This is similar to posix_fadvise in POSIX.

    Params
    Results

    -

    datasync

    +

    sync-data

    Synchronize the data of a file to disk.

    This function succeeds with no effect if the file descriptor is not opened for writing.

    Note: This is similar to fdatasync in POSIX.

    Params
    Results

    -

    flags

    +

    get-flags

    Get flags associated with a descriptor.

    Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

    Note: This returns the value that was the fs_flags value returned from fdstat_get in earlier versions of WASI.

    Params
    Results

    -

    type

    +

    get-type

    Get the dynamic type of a descriptor.

    -

    Note: This returns the same value as the type field of the fd-stat +

    Note: This returns the same value as the type field of the fd-stat returned by stat, stat-at and similar.

    Note: This returns similar flags to the st_mode & S_IFMT value provided by fstat in POSIX.

    @@ -834,26 +832,26 @@

    type

    from fdstat_get in earlier versions of WASI.

    Params
    Results

    set-flags

    Set status flags associated with a descriptor.

    -

    This function may only change the append and nonblock flags.

    +

    This function may only change the non-blocking flag.

    Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

    Note: This was called fd_fdstat_set_flags in earlier versions of WASI.

    Params
    Results

    set-size

    @@ -867,7 +865,7 @@
    Params
    Results

    set-times

    @@ -877,64 +875,65 @@

    set-ti
    Params
    Results

    -

    pread

    +

    read

    Read from a descriptor, without using and updating the descriptor's offset.

    This function returns a list of bytes containing the data that was read, along with a bool which, when true, indicates that the end of the -file was reached. The returned list will contain up to len bytes; it +file was reached. The returned list will contain up to length bytes; it may return fewer than requested, if the end of the file is reached or if the I/O operation is interrupted.

    -

    Note: This is similar to pread in POSIX.

    +

    Note: This is similar to pread in POSIX.

    Params
    Results
      -
    • result0: result<(list<u8>, bool), errno>
    • +
    • result0: result<(list<u8>, bool), error-code>

    -

    pwrite

    +

    write

    Write to a descriptor, without using and updating the descriptor's offset.

    It is valid to write past the end of a file; the file is extended to the extent of the write, with bytes between the previous end and the start of the write set to zero.

    -

    Note: This is similar to pwrite in POSIX.

    +

    Note: This is similar to pwrite in POSIX.

    Params
    Results

    -

    readdir

    +

    read-directory

    Read directory entries from a directory.

    On filesystems where directories contain entries referring to themselves and their parents, often named . and .. respectively, these entries are omitted.

    This always returns a new stream which starts at the beginning of the -directory.

    +directory. Multiple streams may be active on the same directory, and they +do not interfere with each other.

    Params
    Results

    sync

    @@ -948,7 +947,7 @@
    Params
    Results

    create-directory-at

    @@ -961,7 +960,7 @@
    Params
    Results

    stat

    @@ -974,7 +973,7 @@
    Params
    Results

    stat-at

    @@ -984,12 +983,12 @@

    stat-atParams

    Results

    set-times-at

    @@ -999,14 +998,14 @@

    Params

    Results

    link-at

    @@ -1015,14 +1014,14 @@

    link-atParams

    Results

    open-at

    @@ -1032,30 +1031,32 @@

    open-at -

    If flags contains descriptor-flags::mutate-directory, and the base +

    If flags contains descriptor-flags::mutate-directory, and the base descriptor doesn't have descriptor-flags::mutate-directory set, -open-at fails with errno::rofs.

    -

    If flags contains write or append, or o-flags contains trunc -or create, and the base descriptor doesn't have +open-at fails with error-code::read-only.

    +

    If flags contains write or mutate-directory, or open-flags +contains truncate or create, and the base descriptor doesn't have descriptor-flags::mutate-directory set, open-at fails with -errno::rofs.

    +error-code::read-only.

    Note: This is similar to openat in POSIX.

    Params
    Results

    readlink-at

    Read the contents of a symbolic link.

    +

    If the contents contain an absolute or rooted path in the underlying +filesystem, this function fails with error-code::not-permitted.

    Note: This is similar to readlinkat in POSIX.

    Params
      @@ -1064,12 +1065,12 @@
      Params
    Results

    remove-directory-at

    Remove a directory.

    -

    Return errno::notempty if the directory is not empty.

    +

    Return error-code::not-empty if the directory is not empty.

    Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

    Params
      @@ -1078,7 +1079,7 @@
      Params
    Results

    rename-at

    @@ -1093,11 +1094,12 @@
    Params
    Results

    symlink-at

    -

    Create a symbolic link.

    +

    Create a symbolic link (also known as a "symlink").

    +

    If old-path starts with /, the function fails with error-code::not-permitted.

    Note: This is similar to symlinkat in POSIX.

    Params
      @@ -1107,12 +1109,12 @@
      Params
    Results

    unlink-file-at

    Unlink a filesystem object that is not a directory.

    -

    Return errno::isdir if the path refers to a directory. +

    Return error-code::is-directory if the path refers to a directory. Note: This is similar to unlinkat(fd, path, 0) in POSIX.

    Params
      @@ -1121,7 +1123,7 @@
      Params
    Results

    change-file-permissions-at

    @@ -1132,13 +1134,13 @@

    Params
    Results

    change-directory-permissions-at

    @@ -1152,13 +1154,13 @@

    this: descriptor -
  • at-flags: at-flags
  • +
  • path-flags: path-flags
  • path: string
  • -
  • mode: mode
  • +
  • modes: modes
  • Results

    lock-shared

    @@ -1173,7 +1175,7 @@

    non-WASI programs.

    This function blocks until the lock can be acquired.

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns errno::notsup.

    +locking, this function returns error-code::unsupported.

    Note: This is similar to flock(fd, LOCK_SH) in Unix.

    Params
      @@ -1181,7 +1183,7 @@
      Params
    Results

    lock-exclusive

    @@ -1198,7 +1200,7 @@

    errno::notsup.

    +locking, this function returns error-code::unsupported.

    Note: This is similar to flock(fd, LOCK_EX) in Unix.

    Params
      @@ -1206,7 +1208,7 @@
      Params
    Results

    try-lock-shared

    @@ -1219,9 +1221,9 @@

    errno::again if the lock cannot be acquired.

    +

    This function returns error-code::would-block if the lock cannot be acquired.

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns errno::notsup.

    +locking, this function returns error-code::unsupported.

    Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

    Params
      @@ -1229,7 +1231,7 @@
      Params
    Results

    try-lock-exclusive

    @@ -1244,9 +1246,9 @@

    errno::again if the lock cannot be acquired.

    +

    This function returns error-code::would-block if the lock cannot be acquired.

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns errno::notsup.

    +locking, this function returns error-code::unsupported.

    Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

    Params
      @@ -1254,7 +1256,7 @@
      Params
    Results

    unlock

    @@ -1266,7 +1268,7 @@
    Params
    Results

    drop-descriptor

    @@ -1277,21 +1279,21 @@
    Params
  • this: descriptor

  • -

    read-dir-entry

    -

    Read a single directory entry from a dir-entry-stream.

    +

    read-directory-entry

    +

    Read a single directory entry from a directory-entry-stream.

    Params
    Results

    -

    drop-dir-entry-stream

    -

    Dispose of the specified dir-entry-stream, after which it may no longer +

    drop-directory-entry-stream

    +

    Dispose of the specified directory-entry-stream, after which it may no longer be used.

    Params
    diff --git a/proposals/filesystem/wasi-filesystem.md b/proposals/filesystem/wasi-filesystem.md index eb8620703..ec605c875 100644 --- a/proposals/filesystem/wasi-filesystem.md +++ b/proposals/filesystem/wasi-filesystem.md @@ -368,7 +368,20 @@ Size: 4, Alignment: 4 Size: 16, Alignment: 8 -## `o-flags`: record +## `path-flags`: record + +Flags determining the method of how paths are resolved. + +Size: 1, Alignment: 1 + +### Record Fields + +- [`symlink-follow`](#path_flags.symlink_follow): + + As long as the resolved path corresponds to a symbolic link, it is expanded. + Bit: 0 + +## `open-flags`: record Open flags used by `open-at`. @@ -376,27 +389,27 @@ Size: 1, Alignment: 1 ### Record Fields -- [`create`](#o_flags.create): +- [`create`](#open_flags.create): Create file if it does not exist. Bit: 0 -- [`directory`](#o_flags.directory): +- [`directory`](#open_flags.directory): Fail if not a directory. Bit: 1 -- [`excl`](#o_flags.excl): +- [`exclusive`](#open_flags.exclusive): Fail if file already exists. Bit: 2 -- [`trunc`](#o_flags.trunc): +- [`truncate`](#open_flags.truncate): Truncate file to size 0. Bit: 3 -## `mode`: record +## `modes`: record Permissions mode used by `open-at`, `change-file-permissions-at`, and similar. @@ -405,25 +418,25 @@ Size: 1, Alignment: 1 ### Record Fields -- [`readable`](#mode.readable): +- [`readable`](#modes.readable): True if the resource is considered readable by the containing filesystem. Bit: 0 -- [`writeable`](#mode.writeable): +- [`writeable`](#modes.writeable): True if the resource is considered writeable by the containing filesystem. Bit: 1 -- [`executable`](#mode.executable): +- [`executable`](#modes.executable): True if the resource is considered executable by the containing filesystem. This does not apply to directories. Bit: 2 -## `linkcount`: `u64` +## `link-count`: `u64` Number of hard links to an inode. @@ -441,7 +454,7 @@ File size or length of a region within a file. Size: 8, Alignment: 8 -## `errno`: enum +## `error-code`: enum Error codes returned by functions. Not all of these error codes are returned by the functions provided by this @@ -452,159 +465,155 @@ Size: 1, Alignment: 1 ### Enum Cases -- [`access`](#errno.access) +- [`access`](#error_code.access) Permission denied. -- [`again`](#errno.again) +- [`would-block`](#error_code.would_block) Resource unavailable, or operation would block. -- [`already`](#errno.already) +- [`already`](#error_code.already) Connection already in progress. -- [`badf`](#errno.badf) +- [`bad-descriptor`](#error_code.bad_descriptor) Bad descriptor. -- [`busy`](#errno.busy) +- [`busy`](#error_code.busy) Device or resource busy. -- [`deadlk`](#errno.deadlk) +- [`deadlock`](#error_code.deadlock) Resource deadlock would occur. -- [`dquot`](#errno.dquot) +- [`quota`](#error_code.quota) Storage quota exceeded. -- [`exist`](#errno.exist) +- [`exist`](#error_code.exist) File exists. -- [`fbig`](#errno.fbig) +- [`file-too-large`](#error_code.file_too_large) File too large. -- [`ilseq`](#errno.ilseq) +- [`illegal-byte-sequence`](#error_code.illegal_byte_sequence) Illegal byte sequence. -- [`inprogress`](#errno.inprogress) +- [`in-progress`](#error_code.in_progress) Operation in progress. -- [`intr`](#errno.intr) +- [`interrupted`](#error_code.interrupted) Interrupted function. -- [`inval`](#errno.inval) +- [`invalid`](#error_code.invalid) Invalid argument. -- [`io`](#errno.io) +- [`io`](#error_code.io) I/O error. -- [`isdir`](#errno.isdir) +- [`is-directory`](#error_code.is_directory) Is a directory. -- [`loop`](#errno.loop) +- [`loop`](#error_code.loop) Too many levels of symbolic links. -- [`mlink`](#errno.mlink) +- [`too-many-links`](#error_code.too_many_links) Too many links. -- [`msgsize`](#errno.msgsize) +- [`message-size`](#error_code.message_size) Message too large. -- [`nametoolong`](#errno.nametoolong) +- [`name-too-long`](#error_code.name_too_long) Filename too long. -- [`nodev`](#errno.nodev) +- [`no-device`](#error_code.no_device) No such device. -- [`noent`](#errno.noent) +- [`no-entry`](#error_code.no_entry) No such file or directory. -- [`nolck`](#errno.nolck) +- [`no-lock`](#error_code.no_lock) No locks available. -- [`nomem`](#errno.nomem) +- [`insufficient-memory`](#error_code.insufficient_memory) Not enough space. -- [`nospc`](#errno.nospc) +- [`insufficient-space`](#error_code.insufficient_space) No space left on device. -- [`nosys`](#errno.nosys) - - Function not supported. - -- [`notdir`](#errno.notdir) +- [`not-directory`](#error_code.not_directory) Not a directory or a symbolic link to a directory. -- [`notempty`](#errno.notempty) +- [`not-empty`](#error_code.not_empty) Directory not empty. -- [`notrecoverable`](#errno.notrecoverable) +- [`not-recoverable`](#error_code.not_recoverable) State not recoverable. -- [`notsup`](#errno.notsup) +- [`unsupported`](#error_code.unsupported) - Not supported, or operation not supported on socket. + Not supported -- [`notty`](#errno.notty) +- [`no-tty`](#error_code.no_tty) Inappropriate I/O control operation. -- [`nxio`](#errno.nxio) +- [`no-such-device`](#error_code.no_such_device) No such device or address. -- [`overflow`](#errno.overflow) +- [`overflow`](#error_code.overflow) Value too large to be stored in data type. -- [`perm`](#errno.perm) +- [`not-permitted`](#error_code.not_permitted) Operation not permitted. -- [`pipe`](#errno.pipe) +- [`pipe`](#error_code.pipe) Broken pipe. -- [`rofs`](#errno.rofs) +- [`read-only`](#error_code.read_only) Read-only file system. -- [`spipe`](#errno.spipe) +- [`invalid-seek`](#error_code.invalid_seek) Invalid seek. -- [`txtbsy`](#errno.txtbsy) +- [`text-file-busy`](#error_code.text_file_busy) Text file busy. -- [`xdev`](#errno.xdev) +- [`cross-device`](#error_code.cross_device) Cross-device link. -## `dir-entry-stream`: `u32` +## `directory-entry-stream`: `u32` A stream of directory entries. @@ -660,7 +669,7 @@ Size: 1, Alignment: 1 The descriptor refers to a socket. -## `dir-entry`: record +## `directory-entry`: record A directory entry. @@ -668,7 +677,7 @@ Size: 32, Alignment: 8 ### Record Fields -- [`ino`](#dir_entry.ino): option<[`inode`](#inode)> +- [`inode`](#directory_entry.inode): option<[`inode`](#inode)> The serial number of the object referred to by this directory entry. May be none if the inode value is not known. @@ -677,11 +686,11 @@ Size: 32, Alignment: 8 call to retrieve the inode number to fill their `d_ino` fields, so implementations which can set this to a non-none value should do so. -- [`type`](#dir_entry.type): [`descriptor-type`](#descriptor_type) +- [`type`](#directory_entry.type): [`descriptor-type`](#descriptor_type) The type of the file referred to by this directory entry. -- [`name`](#dir_entry.name): `string` +- [`name`](#directory_entry.name): `string` The name of the object. @@ -705,17 +714,17 @@ Size: 1, Alignment: 1 Write mode: Data can be written to. Bit: 1 -- [`nonblock`](#descriptor_flags.nonblock): +- [`non-blocking`](#descriptor_flags.non_blocking): Requests non-blocking operation. When this flag is enabled, functions may return immediately with an - `errno::again` error code in situations where they would otherwise + `error-code::would-block` error code in situations where they would otherwise block. However, this non-blocking behavior is not required. Implementations are permitted to ignore this flag and block. Bit: 2 -- [`sync`](#descriptor_flags.sync): +- [`file-integrity-sync`](#descriptor_flags.file_integrity_sync): Request that writes be performed according to synchronized I/O file integrity completion. The data stored in the file and the file's @@ -726,7 +735,7 @@ Size: 1, Alignment: 1 requirement. Bit: 3 -- [`dsync`](#descriptor_flags.dsync): +- [`data-integrity-sync`](#descriptor_flags.data_integrity_sync): Request that writes be performed according to synchronized I/O data integrity completion. Only the data stored in the file is @@ -737,7 +746,7 @@ Size: 1, Alignment: 1 requirement. Bit: 4 -- [`rsync`](#descriptor_flags.rsync): +- [`requested-write-sync`](#descriptor_flags.requested_write_sync): Requests that reads be performed at the same level of integrety requested for writes. @@ -754,7 +763,7 @@ Size: 1, Alignment: 1 When this flag is unset on a descriptor, operations using the descriptor which would create, rename, delete, modify the data or metadata of filesystem objects, or obtain another handle which - would permit any of those, shall fail with `errno::rofs` if + would permit any of those, shall fail with `error-code::read-only` if they would otherwise succeed. This may only be set on directories. @@ -799,11 +808,11 @@ Size: 88, Alignment: 8 ### Record Fields -- [`dev`](#descriptor_stat.dev): [`device`](#device) +- [`device`](#descriptor_stat.device): [`device`](#device) Device ID of device containing the file. -- [`ino`](#descriptor_stat.ino): [`inode`](#inode) +- [`inode`](#descriptor_stat.inode): [`inode`](#inode) File serial number. @@ -811,7 +820,7 @@ Size: 88, Alignment: 8 File type. -- [`nlink`](#descriptor_stat.nlink): [`linkcount`](#linkcount) +- [`link-count`](#descriptor_stat.link_count): [`link-count`](#link_count) Number of hard links to the file. @@ -820,31 +829,18 @@ Size: 88, Alignment: 8 For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. -- [`atim`](#descriptor_stat.atim): [`datetime`](#datetime) +- [`data-access-timestamp`](#descriptor_stat.data_access_timestamp): [`datetime`](#datetime) Last data access timestamp. -- [`mtim`](#descriptor_stat.mtim): [`datetime`](#datetime) +- [`data-modification-timestamp`](#descriptor_stat.data_modification_timestamp): [`datetime`](#datetime) Last data modification timestamp. -- [`ctim`](#descriptor_stat.ctim): [`datetime`](#datetime) +- [`status-change-timestamp`](#descriptor_stat.status_change_timestamp): [`datetime`](#datetime) Last file status change timestamp. -## `at-flags`: record - -Flags determining the method of how paths are resolved. - -Size: 1, Alignment: 1 - -### Record Fields - -- [`symlink-follow`](#at_flags.symlink_follow): - - As long as the resolved path corresponds to a symbolic link, it is expanded. - Bit: 0 - ## `advice`: enum File or memory access pattern advisory information. @@ -885,6 +881,9 @@ Size: 1, Alignment: 1 Return a stream for reading from a file. +Multiple read, write, and append streams may be active on the same open +file and they do not interfere with each other. + Note: This allows using `read-stream`, which is similar to `read` in POSIX. ##### Params @@ -892,7 +891,7 @@ Note: This allows using `read-stream`, which is similar to `read` in POSIX. - `offset`: [`filesize`](#filesize) ##### Results -- `result0`: result<[`input-stream`](#input_stream), [`errno`](#errno)> +- `result0`: result<[`input-stream`](#input_stream), [`error-code`](#error_code)> ---- @@ -907,7 +906,7 @@ Note: This allows using `write-stream`, which is similar to `write` in POSIX. - `offset`: [`filesize`](#filesize) ##### Results -- `result0`: result<[`output-stream`](#output_stream), [`errno`](#errno)> +- `result0`: result<[`output-stream`](#output_stream), [`error-code`](#error_code)> ---- @@ -923,28 +922,28 @@ Note: This allows using `write-stream`, which is similar to `write` with - `fd`: [`descriptor`](#descriptor) ##### Results -- `result0`: result<[`output-stream`](#output_stream), [`errno`](#errno)> +- `result0`: result<[`output-stream`](#output_stream), [`error-code`](#error_code)> ---- -#### `fadvise` +#### `advise` Provide file advisory information on a descriptor. This is similar to `posix_fadvise` in POSIX. ##### Params -- `this`: [`descriptor`](#descriptor) -- `offset`: [`filesize`](#filesize) -- `len`: [`filesize`](#filesize) -- `advice`: [`advice`](#advice) +- `this`: [`descriptor`](#descriptor) +- `offset`: [`filesize`](#filesize) +- `length`: [`filesize`](#filesize) +- `advice`: [`advice`](#advice) ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- -#### `datasync` +#### `sync-data` Synchronize the data of a file to disk. @@ -954,14 +953,14 @@ opened for writing. Note: This is similar to `fdatasync` in POSIX. ##### Params -- `this`: [`descriptor`](#descriptor) +- `this`: [`descriptor`](#descriptor) ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- -#### `flags` +#### `get-flags` Get flags associated with a descriptor. @@ -971,14 +970,14 @@ Note: This returns the value that was the `fs_flags` value returned from `fdstat_get` in earlier versions of WASI. ##### Params -- `this`: [`descriptor`](#descriptor) +- `this`: [`descriptor`](#descriptor) ##### Results -- `result0`: result<[`descriptor-flags`](#descriptor_flags), [`errno`](#errno)> +- `result0`: result<[`descriptor-flags`](#descriptor_flags), [`error-code`](#error_code)> ---- -#### `type` +#### `get-type` Get the dynamic type of a descriptor. @@ -992,10 +991,10 @@ Note: This returns the value that was the `fs_filetype` value returned from `fdstat_get` in earlier versions of WASI. ##### Params -- `this`: [`descriptor`](#descriptor) +- `this`: [`descriptor`](#descriptor) ##### Results -- `result0`: result<[`descriptor-type`](#descriptor_type), [`errno`](#errno)> +- `result0`: result<[`descriptor-type`](#descriptor_type), [`error-code`](#error_code)> ---- @@ -1003,7 +1002,7 @@ from `fdstat_get` in earlier versions of WASI. Set status flags associated with a descriptor. -This function may only change the `append` and `nonblock` flags. +This function may only change the `non-blocking` flag. Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. @@ -1014,7 +1013,7 @@ Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. - `flags`: [`descriptor-flags`](#descriptor_flags) ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1030,7 +1029,7 @@ Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - `size`: [`filesize`](#filesize) ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1044,37 +1043,37 @@ Note: This was called `fd_filestat_set_times` in earlier versions of WASI. ##### Params - `this`: [`descriptor`](#descriptor) -- `atim`: [`new-timestamp`](#new_timestamp) -- `mtim`: [`new-timestamp`](#new_timestamp) +- `data-access-timestamp`: [`new-timestamp`](#new_timestamp) +- `data-modification-timestamp`: [`new-timestamp`](#new_timestamp) ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- -#### `pread` +#### `read` Read from a descriptor, without using and updating the descriptor's offset. This function returns a list of bytes containing the data that was read, along with a bool which, when true, indicates that the end of the -file was reached. The returned list will contain up to `len` bytes; it +file was reached. The returned list will contain up to `length` bytes; it may return fewer than requested, if the end of the file is reached or if the I/O operation is interrupted. Note: This is similar to `pread` in POSIX. ##### Params -- `this`: [`descriptor`](#descriptor) -- `len`: [`filesize`](#filesize) -- `offset`: [`filesize`](#filesize) +- `this`: [`descriptor`](#descriptor) +- `length`: [`filesize`](#filesize) +- `offset`: [`filesize`](#filesize) ##### Results -- `result0`: result<(list<`u8`>, `bool`), [`errno`](#errno)> +- `result0`: result<(list<`u8`>, `bool`), [`error-code`](#error_code)> ---- -#### `pwrite` +#### `write` Write to a descriptor, without using and updating the descriptor's offset. @@ -1085,16 +1084,16 @@ the write set to zero. Note: This is similar to `pwrite` in POSIX. ##### Params -- `this`: [`descriptor`](#descriptor) -- `buf`: list<`u8`> -- `offset`: [`filesize`](#filesize) +- `this`: [`descriptor`](#descriptor) +- `buffer`: list<`u8`> +- `offset`: [`filesize`](#filesize) ##### Results -- `result0`: result<[`filesize`](#filesize), [`errno`](#errno)> +- `result0`: result<[`filesize`](#filesize), [`error-code`](#error_code)> ---- -#### `readdir` +#### `read-directory` Read directory entries from a directory. @@ -1103,13 +1102,14 @@ and their parents, often named `.` and `..` respectively, these entries are omitted. This always returns a new stream which starts at the beginning of the -directory. +directory. Multiple streams may be active on the same directory, and they +do not interfere with each other. ##### Params -- `this`: [`descriptor`](#descriptor) +- `this`: [`descriptor`](#descriptor) ##### Results -- `result0`: result<[`dir-entry-stream`](#dir_entry_stream), [`errno`](#errno)> +- `result0`: result<[`directory-entry-stream`](#directory_entry_stream), [`error-code`](#error_code)> ---- @@ -1126,7 +1126,7 @@ Note: This is similar to `fsync` in POSIX. - `this`: [`descriptor`](#descriptor) ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1141,7 +1141,7 @@ Note: This is similar to `mkdirat` in POSIX. - `path`: `string` ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1157,7 +1157,7 @@ Note: This was called `fd_filestat_get` in earlier versions of WASI. - `this`: [`descriptor`](#descriptor) ##### Results -- `result0`: result<[`descriptor-stat`](#descriptor_stat), [`errno`](#errno)> +- `result0`: result<[`descriptor-stat`](#descriptor_stat), [`error-code`](#error_code)> ---- @@ -1171,11 +1171,11 @@ Note: This was called `path_filestat_get` in earlier versions of WASI. ##### Params - `this`: [`descriptor`](#descriptor) -- `at-flags`: [`at-flags`](#at_flags) +- `path-flags`: [`path-flags`](#path_flags) - `path`: `string` ##### Results -- `result0`: result<[`descriptor-stat`](#descriptor_stat), [`errno`](#errno)> +- `result0`: result<[`descriptor-stat`](#descriptor_stat), [`error-code`](#error_code)> ---- @@ -1189,13 +1189,13 @@ Note: This was called `path_filestat_set_times` in earlier versions of WASI. ##### Params - `this`: [`descriptor`](#descriptor) -- `at-flags`: [`at-flags`](#at_flags) +- `path-flags`: [`path-flags`](#path_flags) - `path`: `string` -- `atim`: [`new-timestamp`](#new_timestamp) -- `mtim`: [`new-timestamp`](#new_timestamp) +- `data-access-timestamp`: [`new-timestamp`](#new_timestamp) +- `data-modification-timestamp`: [`new-timestamp`](#new_timestamp) ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1207,13 +1207,13 @@ Note: This is similar to `linkat` in POSIX. ##### Params - `this`: [`descriptor`](#descriptor) -- `old-at-flags`: [`at-flags`](#at_flags) +- `old-path-flags`: [`path-flags`](#path_flags) - `old-path`: `string` - `new-descriptor`: [`descriptor`](#descriptor) - `new-path`: `string` ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1229,25 +1229,25 @@ guaranteed to be less than 2**31. If `flags` contains `descriptor-flags::mutate-directory`, and the base descriptor doesn't have `descriptor-flags::mutate-directory` set, -`open-at` fails with `errno::rofs`. +`open-at` fails with `error-code::read-only`. -If `flags` contains `write` or `append`, or `o-flags` contains `trunc` -or `create`, and the base descriptor doesn't have +If `flags` contains `write` or `mutate-directory`, or `open-flags` +contains `truncate` or `create`, and the base descriptor doesn't have `descriptor-flags::mutate-directory` set, `open-at` fails with -`errno::rofs`. +`error-code::read-only`. Note: This is similar to `openat` in POSIX. ##### Params - `this`: [`descriptor`](#descriptor) -- `at-flags`: [`at-flags`](#at_flags) +- `path-flags`: [`path-flags`](#path_flags) - `path`: `string` -- `o-flags`: [`o-flags`](#o_flags) +- `open-flags`: [`open-flags`](#open_flags) - `flags`: [`descriptor-flags`](#descriptor_flags) -- `mode`: [`mode`](#mode) +- `modes`: [`modes`](#modes) ##### Results -- `result0`: result<[`descriptor`](#descriptor), [`errno`](#errno)> +- `result0`: result<[`descriptor`](#descriptor), [`error-code`](#error_code)> ---- @@ -1255,6 +1255,9 @@ Note: This is similar to `openat` in POSIX. Read the contents of a symbolic link. +If the contents contain an absolute or rooted path in the underlying +filesystem, this function fails with `error-code::not-permitted`. + Note: This is similar to `readlinkat` in POSIX. ##### Params @@ -1262,7 +1265,7 @@ Note: This is similar to `readlinkat` in POSIX. - `path`: `string` ##### Results -- `result0`: result<`string`, [`errno`](#errno)> +- `result0`: result<`string`, [`error-code`](#error_code)> ---- @@ -1270,7 +1273,7 @@ Note: This is similar to `readlinkat` in POSIX. Remove a directory. -Return `errno::notempty` if the directory is not empty. +Return `error-code::not-empty` if the directory is not empty. Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. ##### Params @@ -1279,7 +1282,7 @@ Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - `path`: `string` ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1296,13 +1299,15 @@ Note: This is similar to `renameat` in POSIX. - `new-path`: `string` ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- #### `symlink-at` -Create a symbolic link. +Create a symbolic link (also known as a "symlink"). + +If `old-path` starts with `/`, the function fails with `error-code::not-permitted`. Note: This is similar to `symlinkat` in POSIX. ##### Params @@ -1312,7 +1317,7 @@ Note: This is similar to `symlinkat` in POSIX. - `new-path`: `string` ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1320,7 +1325,7 @@ Note: This is similar to `symlinkat` in POSIX. Unlink a filesystem object that is not a directory. -Return `errno::isdir` if the path refers to a directory. +Return `error-code::is-directory` if the path refers to a directory. Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. ##### Params @@ -1328,7 +1333,7 @@ Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - `path`: `string` ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1343,12 +1348,12 @@ Note: This is similar to `fchmodat` in POSIX. ##### Params - `this`: [`descriptor`](#descriptor) -- `at-flags`: [`at-flags`](#at_flags) +- `path-flags`: [`path-flags`](#path_flags) - `path`: `string` -- `mode`: [`mode`](#mode) +- `modes`: [`modes`](#modes) ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1367,12 +1372,12 @@ Note: This is similar to `fchmodat` in POSIX. ##### Params - `this`: [`descriptor`](#descriptor) -- `at-flags`: [`at-flags`](#at_flags) +- `path-flags`: [`path-flags`](#path_flags) - `path`: `string` -- `mode`: [`mode`](#mode) +- `modes`: [`modes`](#modes) ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1395,7 +1400,7 @@ non-WASI programs. This function blocks until the lock can be acquired. Not all filesystems support locking; on filesystems which don't support -locking, this function returns `errno::notsup`. +locking, this function returns `error-code::unsupported`. Note: This is similar to `flock(fd, LOCK_SH)` in Unix. ##### Params @@ -1403,7 +1408,7 @@ Note: This is similar to `flock(fd, LOCK_SH)` in Unix. - `this`: [`descriptor`](#descriptor) ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1428,7 +1433,7 @@ with locks acquired by non-WASI programs. This function blocks until the lock can be acquired. Not all filesystems support locking; on filesystems which don't support -locking, this function returns `errno::notsup`. +locking, this function returns `error-code::unsupported`. Note: This is similar to `flock(fd, LOCK_EX)` in Unix. ##### Params @@ -1436,7 +1441,7 @@ Note: This is similar to `flock(fd, LOCK_EX)` in Unix. - `this`: [`descriptor`](#descriptor) ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1456,10 +1461,10 @@ by other programs that don't hold the lock. It is unspecified how shared locks interact with locks acquired by non-WASI programs. -This function returns `errno::again` if the lock cannot be acquired. +This function returns `error-code::would-block` if the lock cannot be acquired. Not all filesystems support locking; on filesystems which don't support -locking, this function returns `errno::notsup`. +locking, this function returns `error-code::unsupported`. Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. ##### Params @@ -1467,7 +1472,7 @@ Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. - `this`: [`descriptor`](#descriptor) ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1489,10 +1494,10 @@ It is unspecified whether this function succeeds if the file descriptor is not opened for writing. It is unspecified how exclusive locks interact with locks acquired by non-WASI programs. -This function returns `errno::again` if the lock cannot be acquired. +This function returns `error-code::would-block` if the lock cannot be acquired. Not all filesystems support locking; on filesystems which don't support -locking, this function returns `errno::notsup`. +locking, this function returns `error-code::unsupported`. Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. ##### Params @@ -1500,7 +1505,7 @@ Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. - `this`: [`descriptor`](#descriptor) ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1514,7 +1519,7 @@ Note: This is similar to `flock(fd, LOCK_UN)` in Unix. - `this`: [`descriptor`](#descriptor) ##### Results -- `result0`: result<_, [`errno`](#errno)> +- `result0`: result<_, [`error-code`](#error_code)> ---- @@ -1528,23 +1533,23 @@ be used. ---- -#### `read-dir-entry` +#### `read-directory-entry` -Read a single directory entry from a `dir-entry-stream`. +Read a single directory entry from a `directory-entry-stream`. ##### Params -- `this`: [`dir-entry-stream`](#dir_entry_stream) +- `this`: [`directory-entry-stream`](#directory_entry_stream) ##### Results -- `result0`: result, [`errno`](#errno)> +- `result0`: result, [`error-code`](#error_code)> ---- -#### `drop-dir-entry-stream` +#### `drop-directory-entry-stream` -Dispose of the specified `dir-entry-stream`, after which it may no longer +Dispose of the specified `directory-entry-stream`, after which it may no longer be used. ##### Params -- `this`: [`dir-entry-stream`](#dir_entry_stream) +- `this`: [`directory-entry-stream`](#directory_entry_stream) diff --git a/proposals/filesystem/wit/wasi-filesystem.wit.md b/proposals/filesystem/wit/wasi-filesystem.wit.md index a48fdb175..875f4d44c 100644 --- a/proposals/filesystem/wit/wasi-filesystem.wit.md +++ b/proposals/filesystem/wit/wasi-filesystem.wit.md @@ -12,6 +12,15 @@ /// Paths are passed as interface-type `string`s, meaning they must consist of /// a sequence of Unicode Scalar Values (USVs). Some filesystems may contain paths /// which are not accessible by this API. +/// +/// The directory separator in WASI is always the forward-slash (`/`). +/// +/// All paths in WASI are relative paths, and are interpreted relative to a +/// `descriptor` referring to a base directory. If a `path` argument to any WASI +/// function starts with `/`, or if any step of resolving a `path`, including +/// `..` and symbolic link steps, reaches a directory outside of the base +/// directory, or reaches a symlink to an absolute or rooted path in the +/// underlying filesystem, the function fails with `error-code::not-permitted`. default interface wasi-filesystem { ``` @@ -109,7 +118,7 @@ flags descriptor-flags { ## `descriptor-stat` ```wit /// File attributes. -/// +/// /// Note: This was called `filestat` in earlier versions of WASI. record descriptor-stat { /// Device ID of device containing the file. @@ -208,7 +217,7 @@ variant new-timestamp { ## `directory-entry` ```wit -/// A directory entry. +/// A directory entry. record directory-entry { /// The serial number of the object referred to by this directory entry. /// May be none if the inode value is not known. @@ -252,7 +261,7 @@ enum error-code { /// File too large. file-too-large, /// Illegal byte sequence. - Illegal-byte-sequence, + illegal-byte-sequence, /// Operation in progress. in-progress, /// Interrupted function. @@ -342,6 +351,9 @@ type descriptor = u32 ```wit /// Return a stream for reading from a file. /// +/// Multiple read, write, and append streams may be active on the same open +/// file and they do not interfere with each other. +/// /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. read-via-stream: func( this: descriptor, @@ -483,7 +495,7 @@ read: func( length: filesize, /// The offset within the file at which to read. offset: filesize, -) -> result, bool>, errno> +) -> result, bool>, error-code> ``` ## `write` @@ -514,7 +526,8 @@ write: func( /// are omitted. /// /// This always returns a new stream which starts at the beginning of the -/// directory. +/// directory. Multiple streams may be active on the same directory, and they +/// do not interfere with each other. read-directory: func(this: descriptor) -> result ``` @@ -619,8 +632,8 @@ link-at: func( /// descriptor doesn't have `descriptor-flags::mutate-directory` set, /// `open-at` fails with `error-code::read-only`. /// -/// If `flags` contains `write`, or `open-flags` contains `truncate` -/// or `create`, and the base descriptor doesn't have +/// If `flags` contains `write` or `mutate-directory`, or `open-flags` +/// contains `truncate` or `create`, and the base descriptor doesn't have /// `descriptor-flags::mutate-directory` set, `open-at` fails with /// `error-code::read-only`. /// @@ -644,6 +657,9 @@ open-at: func( ```wit /// Read the contents of a symbolic link. /// +/// If the contents contain an absolute or rooted path in the underlying +/// filesystem, this function fails with `error-code::not-permitted`. +/// /// Note: This is similar to `readlinkat` in POSIX. readlink-at: func( this: descriptor, @@ -684,7 +700,9 @@ rename-at: func( ## `symlink-at` ```wit -/// Create a symbolic link. +/// Create a symbolic link (also known as a "symlink"). +/// +/// If `old-path` starts with `/`, the function fails with `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. symlink-at: func( From 5b85c66037110baca68d32dd80f8447dd769ef3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Tue, 21 Feb 2023 22:23:25 +0100 Subject: [PATCH 1052/1772] Document POSIX mapping (#104) In order to ease migration from Preview1 and POSIX implementations. Follow-up of #102 and #99. --- .../filesystem/wit/wasi-filesystem.wit.md | 91 ++++++++++--------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/proposals/filesystem/wit/wasi-filesystem.wit.md b/proposals/filesystem/wit/wasi-filesystem.wit.md index 875f4d44c..e9c84ae60 100644 --- a/proposals/filesystem/wit/wasi-filesystem.wit.md +++ b/proposals/filesystem/wit/wasi-filesystem.wit.md @@ -78,10 +78,11 @@ flags descriptor-flags { /// `error-code::would-block` error code in situations where they would otherwise /// block. However, this non-blocking behavior is not required. /// Implementations are permitted to ignore this flag and block. + /// This is similar to `O_NONBLOCK` in POSIX. non-blocking, /// Request that writes be performed according to synchronized I/O file /// integrity completion. The data stored in the file and the file's - /// metadata are synchronized. + /// metadata are synchronized. This is similar to `O_SYNC` in POSIX. /// /// The precise semantics of this operation have not yet been defined for /// WASI. At this time, it should be interpreted as a request, and not a @@ -89,14 +90,14 @@ flags descriptor-flags { file-integrity-sync, /// Request that writes be performed according to synchronized I/O data /// integrity completion. Only the data stored in the file is - /// synchronized. + /// synchronized. This is similar to `O_DSYNC` in POSIX. /// /// The precise semantics of this operation have not yet been defined for /// WASI. At this time, it should be interpreted as a request, and not a /// requirement. data-integrity-sync, /// Requests that reads be performed at the same level of integrety - /// requested for writes. + /// requested for writes. This is similar to `O_RSYNC` in POSIX. /// /// The precise semantics of this operation have not yet been defined for /// WASI. At this time, it should be interpreted as a request, and not a @@ -154,13 +155,13 @@ flags path-flags { ```wit /// Open flags used by `open-at`. flags open-flags { - /// Create file if it does not exist. + /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, - /// Fail if not a directory. + /// Fail if not a directory, similar to `O_DIRECTORY` in POSIX. directory, - /// Fail if file already exists. + /// Fail if file already exists, similar to `O_EXCL` in POSIX. exclusive, - /// Truncate file to size 0. + /// Truncate file to size 0, similar to `O_TRUNC` in POSIX. truncate, } ``` @@ -237,84 +238,84 @@ record directory-entry { ## `error-code` ```wit -/// Error codes returned by functions. +/// Error codes returned by functions, similar to `errno` in POSIX. /// Not all of these error codes are returned by the functions provided by this /// API; some are used in higher-level library layers, and others are provided /// merely for alignment with POSIX. enum error-code { - /// Permission denied. + /// Permission denied, similar to `EACCES` in POSIX. access, - /// Resource unavailable, or operation would block. + /// Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. would-block, - /// Connection already in progress. + /// Connection already in progress, similar to `EALREADY` in POSIX. already, - /// Bad descriptor. + /// Bad descriptor, similar to `EBADF` in POSIX. bad-descriptor, - /// Device or resource busy. + /// Device or resource busy, similar to `EBUSY` in POSIX. busy, - /// Resource deadlock would occur. + /// Resource deadlock would occur, similar to `EDEADLK` in POSIX. deadlock, - /// Storage quota exceeded. + /// Storage quota exceeded, similar to `EDQUOT` in POSIX. quota, - /// File exists. + /// File exists, similar to `EEXIST` in POSIX. exist, - /// File too large. + /// File too large, similar to `EFBIG` in POSIX. file-too-large, - /// Illegal byte sequence. + /// Illegal byte sequence, similar to `EILSEQ` in POSIX. illegal-byte-sequence, - /// Operation in progress. + /// Operation in progress, similar to `EINPROGRESS` in POSIX. in-progress, - /// Interrupted function. + /// Interrupted function, similar to `EINTR` in POSIX. interrupted, - /// Invalid argument. + /// Invalid argument, similar to `EINVAL` in POSIX. invalid, - /// I/O error. + /// I/O error, similar to `EIO` in POSIX. io, - /// Is a directory. + /// Is a directory, similar to `EISDIR` in POSIX. is-directory, - /// Too many levels of symbolic links. + /// Too many levels of symbolic links, similar to `ELOOP` in POSIX. loop, - /// Too many links. + /// Too many links, similar to `EMLINK` in POSIX. too-many-links, - /// Message too large. + /// Message too large, similar to `EMSGSIZE` in POSIX. message-size, - /// Filename too long. + /// Filename too long, similar to `ENAMETOOLONG` in POSIX. name-too-long, - /// No such device. + /// No such device, similar to `ENODEV` in POSIX. no-device, - /// No such file or directory. + /// No such file or directory, similar to `ENOENT` in POSIX. no-entry, - /// No locks available. + /// No locks available, similar to `ENOLCK` in POSIX. no-lock, - /// Not enough space. + /// Not enough space, similar to `ENOMEM` in POSIX. insufficient-memory, - /// No space left on device. + /// No space left on device, similar to `ENOSPC` in POSIX. insufficient-space, - /// Not a directory or a symbolic link to a directory. + /// Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. not-directory, - /// Directory not empty. + /// Directory not empty, similar to `ENOTEMPTY` in POSIX. not-empty, - /// State not recoverable. + /// State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. not-recoverable, - /// Not supported + /// Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. unsupported, - /// Inappropriate I/O control operation. + /// Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. no-tty, - /// No such device or address. + /// No such device or address, similar to `ENXIO` in POSIX. no-such-device, - /// Value too large to be stored in data type. + /// Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. overflow, - /// Operation not permitted. + /// Operation not permitted, similar to `EPERM` in POSIX. not-permitted, - /// Broken pipe. + /// Broken pipe, similar to `EPIPE` in POSIX. pipe, - /// Read-only file system. + /// Read-only file system, similar to `EROFS` in POSIX. read-only, - /// Invalid seek. + /// Invalid seek, similar to `ESPIPE` in POSIX. invalid-seek, - /// Text file busy. + /// Text file busy, similar to `ETXTBSY` in POSIX. text-file-busy, - /// Cross-device link. + /// Cross-device link, similar to `EXDEV` in POSIX. cross-device, } ``` From 4ab4c4b83a03a7011adf0cc75037fc4d3e02c230 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 21 Feb 2023 15:39:27 -0600 Subject: [PATCH 1053/1772] Update to the latest wasi-proposal-repo format. (#105) * Update to the latest wasi-proposal-repo format. This notably converts the `.wit.md` files to `.wit`. --- .../filesystem/.github/workflows/main.yml | 7 +- proposals/filesystem/example-world.md | 1285 ++++++++++++++ proposals/filesystem/wasi-filesystem.html | 1299 -------------- proposals/filesystem/wasi-filesystem.md | 1555 ----------------- .../filesystem/wit/deps/clocks/wall-clock.wit | 48 + proposals/filesystem/wit/deps/io/streams.wit | 134 ++ proposals/filesystem/wit/deps/poll/poll.wit | 39 + proposals/filesystem/wit/deps/wit | 134 ++ proposals/filesystem/wit/filesystem.wit | 770 ++++++++ .../filesystem/wit/wasi-filesystem.wit.md | 917 ---------- proposals/filesystem/wit/world.wit | 3 + proposals/filesystem/wit/world.wit.md | 9 - 12 files changed, 2415 insertions(+), 3785 deletions(-) create mode 100644 proposals/filesystem/example-world.md delete mode 100644 proposals/filesystem/wasi-filesystem.html delete mode 100644 proposals/filesystem/wasi-filesystem.md create mode 100644 proposals/filesystem/wit/deps/clocks/wall-clock.wit create mode 100644 proposals/filesystem/wit/deps/io/streams.wit create mode 100644 proposals/filesystem/wit/deps/poll/poll.wit create mode 100644 proposals/filesystem/wit/deps/wit create mode 100644 proposals/filesystem/wit/filesystem.wit delete mode 100644 proposals/filesystem/wit/wasi-filesystem.wit.md create mode 100644 proposals/filesystem/wit/world.wit delete mode 100644 proposals/filesystem/wit/world.wit.md diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index 6f87604e9..ad1997c51 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -11,9 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-poll/1bafe7b4a16848a61dd81595ac7f67733561112f/wit/wasi-poll.wit.md > wit/wasi-poll.wit.md - - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-io/32ad9a13480d591d1c094dcafdd4d19518e4de93/wit/wasi-io.wit.md > wit/wasi-io.wit.md - - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-clocks/778a8323dde9385be37e774558febd7576548984/wit/wasi-wall-clock.wit.md > wit/wasi-wall-clock.wit.md - - uses: WebAssembly/wit-abi-up-to-date@v10 + - uses: WebAssembly/wit-abi-up-to-date@v12 with: - wit-abi-tag: wit-abi-0.8.0 + wit-abi-tag: wit-abi-0.10.0 diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md new file mode 100644 index 000000000..c57bba06a --- /dev/null +++ b/proposals/filesystem/example-world.md @@ -0,0 +1,1285 @@ +

    World example-world

    + +

    Import interface poll

    +

    A poll API intended to let users wait for I/O events on multiple handles +at once.

    +
    +

    Types

    +

    type pollable

    +

    u32

    +

    A "pollable" handle. +

    This is conceptually represents a stream<_, _>, or in other words, +a stream that one can wait on, repeatedly, but which does not itself +produce any data. It's temporary scaffolding until component-model's +async features are ready.

    +

    And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

    +

    pollable lifetimes are not automatically managed. Users must ensure +that they do not outlive the resource they reference.

    +

    This represents a resource.

    +
    +

    Functions

    +

    drop-pollable: func

    +

    Dispose of the specified pollable, after which it may no longer +be used.

    +
    Params
    + +

    poll-oneoff: func

    +

    Poll for completion on a set of pollables.

    +

    The "oneoff" in the name refers to the fact that this function must do a +linear scan through the entire list of subscriptions, which may be +inefficient if the number is large and the same subscriptions are used +many times. In the future, this is expected to be obsoleted by the +component model async proposal, which will include a scalable waiting +facility.

    +

    Note that the return type would ideally be list<bool>, but that would +be more difficult to polyfill given the current state of wit-bindgen. +See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 +for details. For now, we use zero to mean "not ready" and non-zero to +mean "ready".

    +
    Params
    + +
    Return values
    +
      +
    • list<u8>
    • +
    +

    Import interface streams

    +

    WASI I/O is an I/O abstraction API which is currently focused on providing +stream types.

    +

    In the future, the component model is expected to add built-in stream types; +when it does, they are expected to subsume this API.

    +
    +

    Types

    +

    type pollable

    +

    pollable

    +

    +#### `record stream-error` +

    An error type returned from a stream operation. Currently this +doesn't provide any additional information.

    +
    Record Fields
    +

    type output-stream

    +

    u32

    +

    An output bytestream. In the future, this will be replaced by handle +types. +

    And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

    +

    This represents a resource.

    +

    type input-stream

    +

    u32

    +

    An input bytestream. In the future, this will be replaced by handle +types. +

    And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

    +

    This represents a resource.

    +
    +

    Functions

    +

    read: func

    +

    Read bytes from a stream.

    +

    This function returns a list of bytes containing the data that was +read, along with a bool indicating whether the end of the stream +was reached. The returned list will contain up to len bytes; it +may return fewer than requested, but not more.

    +

    Once a stream has reached the end, subsequent calls to read or +skip will always report end-of-stream rather than producing more +data.

    +

    If len is 0, it represents a request to read 0 bytes, which should +always succeed, assuming the stream hasn't reached its end yet, and +return an empty list.

    +

    The len here is a u64, but some callees may not be able to allocate +a buffer as large as that would imply. +FIXME: describe what happens if allocation fails.

    +
    Params
    + +
    Return values
    + +

    skip: func

    +

    Skip bytes from a stream.

    +

    This is similar to the read function, but avoids copying the +bytes into the instance.

    +

    Once a stream has reached the end, subsequent calls to read or +skip will always report end-of-stream rather than producing more +data.

    +

    This function returns the number of bytes skipped, along with a bool +indicating whether the end of the stream was reached. The returned +value will be at most len; it may be less.

    +
    Params
    + +
    Return values
    + +

    subscribe-to-input-stream: func

    +

    Create a pollable which will resolve once either the specified stream +has bytes available to read or the other end of the stream has been +closed.

    +
    Params
    + +
    Return values
    + +

    drop-input-stream: func

    +

    Dispose of the specified input-stream, after which it may no longer +be used.

    +
    Params
    + +

    write: func

    +

    Write bytes to a stream.

    +

    This function returns a u64 indicating the number of bytes from +buf that were written; it may be less than the full list.

    +
    Params
    + +
    Return values
    + +

    write-zeroes: func

    +

    Write multiple zero bytes to a stream.

    +

    This function returns a u64 indicating the number of zero bytes +that were written; it may be less than len.

    +
    Params
    + +
    Return values
    + +

    splice: func

    +

    Read from one stream and write to another.

    +

    This function returns the number of bytes transferred; it may be less +than len.

    +
    Params
    + +
    Return values
    + +

    forward: func

    +

    Forward the entire contents of an input stream to an output stream.

    +

    This function repeatedly reads from the input stream and writes +the data to the output stream, until the end of the input stream +is reached, or an error is encountered.

    +

    This function returns the number of bytes transferred.

    +
    Params
    + +
    Return values
    + +

    subscribe-to-output-stream: func

    +

    Create a pollable which will resolve once either the specified stream +is ready to accept bytes or the other end of the stream has been closed.

    +
    Params
    + +
    Return values
    + +

    drop-output-stream: func

    +

    Dispose of the specified output-stream, after which it may no longer +be used.

    +
    Params
    + +

    Import interface wall-clock

    +

    WASI Wall Clock is a clock API intended to let users query the current +time. The name "wall" makes an analogy to a "clock on the wall", which +is not necessarily monotonic as it may be reset.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +
    +

    Types

    +

    type wall-clock

    +

    u32

    +

    A wall clock is a clock which measures the date and time according to +some external reference. +

    External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time.

    +

    It is intended for reporting the current date and time for humans.

    +

    This represents a resource.

    +

    record datetime

    +

    A time and date in seconds plus nanoseconds.

    +
    Record Fields
    + +
    +

    Functions

    +

    now: func

    +

    Read the current value of the clock.

    +

    This clock is not monotonic, therefore calling this function repeatedly +will not necessarily produce a sequence of non-decreasing values.

    +

    The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, +also known as Unix Time.

    +

    The nanoseconds field of the output is always less than 1000000000.

    +
    Params
    + +
    Return values
    + +

    resolution: func

    +

    Query the resolution of the clock.

    +

    The nanoseconds field of the output is always less than 1000000000.

    +
    Params
    + +
    Return values
    + +

    drop-wall-clock: func

    +

    Dispose of the specified wall-clock, after which it may no longer +be used.

    +
    Params
    + +

    Import interface filesystem

    +

    WASI filesystem is a filesystem API primarily intended to let users run WASI +programs that access their files on their existing filesystems, without +significant overhead.

    +

    It is intended to be roughly portable between Unix-family platforms and +Windows, though it does not hide many of the major differences.

    +

    Paths are passed as interface-type strings, meaning they must consist of +a sequence of Unicode Scalar Values (USVs). Some filesystems may contain +paths which are not accessible by this API.

    +

    The directory separator in WASI is always the forward-slash (/).

    +

    All paths in WASI are relative paths, and are interpreted relative to a +descriptor referring to a base directory. If a path argument to any WASI +function starts with /, or if any step of resolving a path, including +.. and symbolic link steps, reaches a directory outside of the base +directory, or reaches a symlink to an absolute or rooted path in the +underlying filesystem, the function fails with error-code::not-permitted.

    +
    +

    Types

    +

    type input-stream

    +

    input-stream

    +

    +#### `type output-stream` +[`output-stream`](#output_stream) +

    +#### `type datetime` +[`datetime`](#datetime) +

    +#### `flags path-flags` +

    Flags determining the method of how paths are resolved.

    +
    Flags members
    +
      +
    • symlink-follow:

      As long as the resolved path corresponds to a symbolic link, it is +expanded. +

    • +
    +

    flags open-flags

    +

    Open flags used by open-at.

    +
    Flags members
    +
      +
    • +

      create:

      +

      Create file if it does not exist, similar to `O_CREAT` in POSIX. +

    • +
    • +

      directory:

      +

      Fail if not a directory, similar to `O_DIRECTORY` in POSIX. +

    • +
    • +

      exclusive:

      +

      Fail if file already exists, similar to `O_EXCL` in POSIX. +

    • +
    • +

      truncate:

      +

      Truncate file to size 0, similar to `O_TRUNC` in POSIX. +

    • +
    +

    flags modes

    +

    Permissions mode used by open-at, change-file-permissions-at, and +similar.

    +
    Flags members
    +
      +
    • +

      readable:

      +

      True if the resource is considered readable by the containing +filesystem. +

    • +
    • +

      writeable:

      +

      True if the resource is considered writeable by the containing +filesystem. +

    • +
    • +

      executable:

      +

      True if the resource is considered executable by the containing +filesystem. This does not apply to directories. +

    • +
    +

    type link-count

    +

    u64

    +

    Number of hard links to an inode. +

    type inode

    +

    u64

    +

    Filesystem object serial number that is unique within its file system. +

    type filesize

    +

    u64

    +

    File size or length of a region within a file. +

    enum error-code

    +

    Error codes returned by functions, similar to errno in POSIX. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX.

    +
    Enum Cases
    +
      +
    • +

      access

      +

      Permission denied, similar to `EACCES` in POSIX. +

    • +
    • +

      would-block

      +

      Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. +

    • +
    • +

      already

      +

      Connection already in progress, similar to `EALREADY` in POSIX. +

    • +
    • +

      bad-descriptor

      +

      Bad descriptor, similar to `EBADF` in POSIX. +

    • +
    • +

      busy

      +

      Device or resource busy, similar to `EBUSY` in POSIX. +

    • +
    • +

      deadlock

      +

      Resource deadlock would occur, similar to `EDEADLK` in POSIX. +

    • +
    • +

      quota

      +

      Storage quota exceeded, similar to `EDQUOT` in POSIX. +

    • +
    • +

      exist

      +

      File exists, similar to `EEXIST` in POSIX. +

    • +
    • +

      file-too-large

      +

      File too large, similar to `EFBIG` in POSIX. +

    • +
    • +

      illegal-byte-sequence

      +

      Illegal byte sequence, similar to `EILSEQ` in POSIX. +

    • +
    • +

      in-progress

      +

      Operation in progress, similar to `EINPROGRESS` in POSIX. +

    • +
    • +

      interrupted

      +

      Interrupted function, similar to `EINTR` in POSIX. +

    • +
    • +

      invalid

      +

      Invalid argument, similar to `EINVAL` in POSIX. +

    • +
    • +

      io

      +

      I/O error, similar to `EIO` in POSIX. +

    • +
    • +

      is-directory

      +

      Is a directory, similar to `EISDIR` in POSIX. +

    • +
    • +

      loop

      +

      Too many levels of symbolic links, similar to `ELOOP` in POSIX. +

    • +
    • +

      too-many-links

      +

      Too many links, similar to `EMLINK` in POSIX. +

    • +
    • +

      message-size

      +

      Message too large, similar to `EMSGSIZE` in POSIX. +

    • +
    • +

      name-too-long

      +

      Filename too long, similar to `ENAMETOOLONG` in POSIX. +

    • +
    • +

      no-device

      +

      No such device, similar to `ENODEV` in POSIX. +

    • +
    • +

      no-entry

      +

      No such file or directory, similar to `ENOENT` in POSIX. +

    • +
    • +

      no-lock

      +

      No locks available, similar to `ENOLCK` in POSIX. +

    • +
    • +

      insufficient-memory

      +

      Not enough space, similar to `ENOMEM` in POSIX. +

    • +
    • +

      insufficient-space

      +

      No space left on device, similar to `ENOSPC` in POSIX. +

    • +
    • +

      not-directory

      +

      Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. +

    • +
    • +

      not-empty

      +

      Directory not empty, similar to `ENOTEMPTY` in POSIX. +

    • +
    • +

      not-recoverable

      +

      State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. +

    • +
    • +

      unsupported

      +

      Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. +

    • +
    • +

      no-tty

      +

      Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. +

    • +
    • +

      no-such-device

      +

      No such device or address, similar to `ENXIO` in POSIX. +

    • +
    • +

      overflow

      +

      Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. +

    • +
    • +

      not-permitted

      +

      Operation not permitted, similar to `EPERM` in POSIX. +

    • +
    • +

      pipe

      +

      Broken pipe, similar to `EPIPE` in POSIX. +

    • +
    • +

      read-only

      +

      Read-only file system, similar to `EROFS` in POSIX. +

    • +
    • +

      invalid-seek

      +

      Invalid seek, similar to `ESPIPE` in POSIX. +

    • +
    • +

      text-file-busy

      +

      Text file busy, similar to `ETXTBSY` in POSIX. +

    • +
    • +

      cross-device

      +

      Cross-device link, similar to `EXDEV` in POSIX. +

    • +
    +

    type directory-entry-stream

    +

    u32

    +

    A stream of directory entries. +

    This represents a stream of dir-entry.

    +

    type device

    +

    u64

    +

    Identifier for a device containing a file system. Can be used in +combination with `inode` to uniquely identify a file or directory in +the filesystem. +

    enum descriptor-type

    +

    The type of a filesystem object referenced by a descriptor.

    +

    Note: This was called filetype in earlier versions of WASI.

    +
    Enum Cases
    +
      +
    • +

      unknown

      +

      The type of the descriptor or file is unknown or is different from +any of the other types specified. +

    • +
    • +

      block-device

      +

      The descriptor refers to a block device inode. +

    • +
    • +

      character-device

      +

      The descriptor refers to a character device inode. +

    • +
    • +

      directory

      +

      The descriptor refers to a directory inode. +

    • +
    • +

      fifo

      +

      The descriptor refers to a named pipe. +

    • +
    • +

      symbolic-link

      +

      The file refers to a symbolic link inode. +

    • +
    • +

      regular-file

      +

      The descriptor refers to a regular file inode. +

    • +
    • +

      socket

      +

      The descriptor refers to a socket. +

    • +
    +

    record directory-entry

    +

    A directory entry.

    +
    Record Fields
    +
      +
    • +

      inode: option<inode>

      +

      The serial number of the object referred to by this directory entry. +May be none if the inode value is not known. +

      When this is none, libc implementations might do an extra stat-at +call to retrieve the inode number to fill their d_ino fields, so +implementations which can set this to a non-none value should do so.

      +
    • +
    • +

      type: descriptor-type

      +

      The type of the file referred to by this directory entry. +

    • +
    • +

      name: string

      +

      The name of the object. +

    • +
    +

    flags descriptor-flags

    +

    Descriptor flags.

    +

    Note: This was called fdflags in earlier versions of WASI.

    +
    Flags members
    +
      +
    • +

      read:

      +

      Read mode: Data can be read. +

    • +
    • +

      write:

      +

      Write mode: Data can be written to. +

    • +
    • +

      non-blocking:

      +

      Requests non-blocking operation. +

      When this flag is enabled, functions may return immediately with an +error-code::would-block error code in situations where they would +otherwise block. However, this non-blocking behavior is not +required. Implementations are permitted to ignore this flag and +block. This is similar to O_NONBLOCK in POSIX.

      +
    • +
    • +

      file-integrity-sync:

      +

      Request that writes be performed according to synchronized I/O file +integrity completion. The data stored in the file and the file's +metadata are synchronized. This is similar to `O_SYNC` in POSIX. +

      The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

      +
    • +
    • +

      data-integrity-sync:

      +

      Request that writes be performed according to synchronized I/O data +integrity completion. Only the data stored in the file is +synchronized. This is similar to `O_DSYNC` in POSIX. +

      The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

      +
    • +
    • +

      requested-write-sync:

      +

      Requests that reads be performed at the same level of integrety +requested for writes. This is similar to `O_RSYNC` in POSIX. +

      The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

      +
    • +
    • +

      mutate-directory:

      +

      Mutating directories mode: Directory contents may be mutated. +

      When this flag is unset on a descriptor, operations using the +descriptor which would create, rename, delete, modify the data or +metadata of filesystem objects, or obtain another handle which +would permit any of those, shall fail with error-code::read-only if +they would otherwise succeed.

      +

      This may only be set on directories.

      +
    • +
    +

    type descriptor

    +

    u32

    +

    A descriptor is a reference to a filesystem object, which may be a file, +directory, named pipe, special file, or other object on which filesystem +calls may be made. +

    This represents a resource.

    +

    variant new-timestamp

    +

    When setting a timestamp, this gives the value to set it to.

    +
    Variant Cases
    +
      +
    • +

      no-change

      +

      Leave the timestamp set to its previous value. +

    • +
    • +

      now

      +

      Set the timestamp to the current time of the system clock associated +with the filesystem. +

    • +
    • +

      timestamp: datetime

      +

      Set the timestamp to the given value. +

    • +
    +

    record descriptor-stat

    +

    File attributes.

    +

    Note: This was called filestat in earlier versions of WASI.

    +
    Record Fields
    + +

    enum advice

    +

    File or memory access pattern advisory information.

    +
    Enum Cases
    +
      +
    • +

      normal

      +

      The application has no advice to give on its behavior with respect +to the specified data. +

    • +
    • +

      sequential

      +

      The application expects to access the specified data sequentially +from lower offsets to higher offsets. +

    • +
    • +

      random

      +

      The application expects to access the specified data in a random +order. +

    • +
    • +

      will-need

      +

      The application expects to access the specified data in the near +future. +

    • +
    • +

      dont-need

      +

      The application expects that it will not access the specified data +in the near future. +

    • +
    • +

      no-reuse

      +

      The application expects to access the specified data once and then +not reuse it thereafter. +

    • +
    +
    +

    Functions

    +

    read-via-stream: func

    +

    Return a stream for reading from a file.

    +

    Multiple read, write, and append streams may be active on the same open +file and they do not interfere with each other.

    +

    Note: This allows using read-stream, which is similar to read in POSIX.

    +
    Params
    + +
    Return values
    + +

    write-via-stream: func

    +

    Return a stream for writing to a file.

    +

    Note: This allows using write-stream, which is similar to write in +POSIX.

    +
    Params
    + +
    Return values
    + +

    append-via-stream: func

    +

    Return a stream for appending to a file.

    +

    Note: This allows using write-stream, which is similar to write with +O_APPEND in in POSIX.

    +
    Params
    + +
    Return values
    + +

    advise: func

    +

    Provide file advisory information on a descriptor.

    +

    This is similar to posix_fadvise in POSIX.

    +
    Params
    + +
    Return values
    + +

    sync-data: func

    +

    Synchronize the data of a file to disk.

    +

    This function succeeds with no effect if the file descriptor is not +opened for writing.

    +

    Note: This is similar to fdatasync in POSIX.

    +
    Params
    + +
    Return values
    + +

    get-flags: func

    +

    Get flags associated with a descriptor.

    +

    Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

    +

    Note: This returns the value that was the fs_flags value returned +from fdstat_get in earlier versions of WASI.

    +
    Params
    + +
    Return values
    + +

    get-type: func

    +

    Get the dynamic type of a descriptor.

    +

    Note: This returns the same value as the type field of the fd-stat +returned by stat, stat-at and similar.

    +

    Note: This returns similar flags to the st_mode & S_IFMT value provided +by fstat in POSIX.

    +

    Note: This returns the value that was the fs_filetype value returned +from fdstat_get in earlier versions of WASI.

    +
    Params
    + +
    Return values
    + +

    set-flags: func

    +

    Set status flags associated with a descriptor.

    +

    This function may only change the non-blocking flag.

    +

    Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

    +

    Note: This was called fd_fdstat_set_flags in earlier versions of WASI.

    +
    Params
    + +
    Return values
    + +

    set-size: func

    +

    Adjust the size of an open file. If this increases the file's size, the +extra bytes are filled with zeros.

    +

    Note: This was called fd_filestat_set_size in earlier versions of WASI.

    +
    Params
    + +
    Return values
    + +

    set-times: func

    +

    Adjust the timestamps of an open file or directory.

    +

    Note: This is similar to futimens in POSIX.

    +

    Note: This was called fd_filestat_set_times in earlier versions of WASI.

    +
    Params
    + +
    Return values
    + +

    read: func

    +

    Read from a descriptor, without using and updating the descriptor's offset.

    +

    This function returns a list of bytes containing the data that was +read, along with a bool which, when true, indicates that the end of the +file was reached. The returned list will contain up to length bytes; it +may return fewer than requested, if the end of the file is reached or +if the I/O operation is interrupted.

    +

    In the future, this may change to return a stream<u8, error-code>.

    +

    Note: This is similar to pread in POSIX.

    +
    Params
    + +
    Return values
    + +

    write: func

    +

    Write to a descriptor, without using and updating the descriptor's offset.

    +

    It is valid to write past the end of a file; the file is extended to the +extent of the write, with bytes between the previous end and the start of +the write set to zero.

    +

    In the future, this may change to take a stream<u8, error-code>.

    +

    Note: This is similar to pwrite in POSIX.

    +
    Params
    + +
    Return values
    + +

    read-directory: func

    +

    Read directory entries from a directory.

    +

    On filesystems where directories contain entries referring to themselves +and their parents, often named . and .. respectively, these entries +are omitted.

    +

    This always returns a new stream which starts at the beginning of the +directory. Multiple streams may be active on the same directory, and they +do not interfere with each other.

    +
    Params
    + +
    Return values
    + +

    sync: func

    +

    Synchronize the data and metadata of a file to disk.

    +

    This function succeeds with no effect if the file descriptor is not +opened for writing.

    +

    Note: This is similar to fsync in POSIX.

    +
    Params
    + +
    Return values
    + +

    create-directory-at: func

    +

    Create a directory.

    +

    Note: This is similar to mkdirat in POSIX.

    +
    Params
    + +
    Return values
    + +

    stat: func

    +

    Return the attributes of an open file or directory.

    +

    Note: This is similar to fstat in POSIX.

    +

    Note: This was called fd_filestat_get in earlier versions of WASI.

    +
    Params
    + +
    Return values
    + +

    stat-at: func

    +

    Return the attributes of a file or directory.

    +

    Note: This is similar to fstatat in POSIX.

    +

    Note: This was called path_filestat_get in earlier versions of WASI.

    +
    Params
    + +
    Return values
    + +

    set-times-at: func

    +

    Adjust the timestamps of a file or directory.

    +

    Note: This is similar to utimensat in POSIX.

    +

    Note: This was called path_filestat_set_times in earlier versions of +WASI.

    +
    Params
    + +
    Return values
    + +

    link-at: func

    +

    Create a hard link.

    +

    Note: This is similar to linkat in POSIX.

    +
    Params
    + +
    Return values
    + +

    open-at: func

    +

    Open a file or directory.

    +

    The returned descriptor is not guaranteed to be the lowest-numbered +descriptor not currently open/ it is randomized to prevent applications +from depending on making assumptions about indexes, since this is +error-prone in multi-threaded contexts. The returned descriptor is +guaranteed to be less than 2**31.

    +

    If flags contains descriptor-flags::mutate-directory, and the base +descriptor doesn't have descriptor-flags::mutate-directory set, +open-at fails with error-code::read-only.

    +

    If flags contains write or mutate-directory, or open-flags +contains truncate or create, and the base descriptor doesn't have +descriptor-flags::mutate-directory set, open-at fails with +error-code::read-only.

    +

    Note: This is similar to openat in POSIX.

    +
    Params
    + +
    Return values
    + +

    readlink-at: func

    +

    Read the contents of a symbolic link.

    +

    If the contents contain an absolute or rooted path in the underlying +filesystem, this function fails with error-code::not-permitted.

    +

    Note: This is similar to readlinkat in POSIX.

    +
    Params
    + +
    Return values
    + +

    remove-directory-at: func

    +

    Remove a directory.

    +

    Return error-code::not-empty if the directory is not empty.

    +

    Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

    +
    Params
    + +
    Return values
    + +

    rename-at: func

    +

    Rename a filesystem object.

    +

    Note: This is similar to renameat in POSIX.

    +
    Params
    + +
    Return values
    + +

    symlink-at: func

    +

    Create a symbolic link (also known as a "symlink").

    +

    If old-path starts with /, the function fails with +error-code::not-permitted.

    +

    Note: This is similar to symlinkat in POSIX.

    +
    Params
    + +
    Return values
    + +

    unlink-file-at: func

    +

    Unlink a filesystem object that is not a directory.

    +

    Return error-code::is-directory if the path refers to a directory. +Note: This is similar to unlinkat(fd, path, 0) in POSIX.

    +
    Params
    + +
    Return values
    + +

    change-file-permissions-at: func

    +

    Change the permissions of a filesystem object that is not a directory.

    +

    Note that the ultimate meanings of these permissions is +filesystem-specific.

    +

    Note: This is similar to fchmodat in POSIX.

    +
    Params
    + +
    Return values
    + +

    change-directory-permissions-at: func

    +

    Change the permissions of a directory.

    +

    Note that the ultimate meanings of these permissions is +filesystem-specific.

    +

    Unlike in POSIX, the executable flag is not reinterpreted as a "search" +flag. read on a directory implies readability and searchability, and +execute is not valid for directories.

    +

    Note: This is similar to fchmodat in POSIX.

    +
    Params
    + +
    Return values
    + +

    lock-shared: func

    +

    Request a shared advisory lock for an open file.

    +

    This requests a shared lock; more than one shared lock can be held for +a file at the same time.

    +

    If the open file has an exclusive lock, this function downgrades the lock +to a shared lock. If it has a shared lock, this function has no effect.

    +

    This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

    +

    It is unspecified how shared locks interact with locks acquired by +non-WASI programs.

    +

    This function blocks until the lock can be acquired.

    +

    Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

    +

    Note: This is similar to flock(fd, LOCK_SH) in Unix.

    +
    Params
    + +
    Return values
    + +

    lock-exclusive: func

    +

    Request an exclusive advisory lock for an open file.

    +

    This requests an exclusive lock; no other locks may be held for the +file while an exclusive lock is held.

    +

    If the open file has a shared lock and there are no exclusive locks held +for the file, this function upgrades the lock to an exclusive lock. If the +open file already has an exclusive lock, this function has no effect.

    +

    This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

    +

    It is unspecified whether this function succeeds if the file descriptor +is not opened for writing. It is unspecified how exclusive locks interact +with locks acquired by non-WASI programs.

    +

    This function blocks until the lock can be acquired.

    +

    Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

    +

    Note: This is similar to flock(fd, LOCK_EX) in Unix.

    +
    Params
    + +
    Return values
    + +

    try-lock-shared: func

    +

    Request a shared advisory lock for an open file.

    +

    This requests a shared lock; more than one shared lock can be held for +a file at the same time.

    +

    If the open file has an exclusive lock, this function downgrades the lock +to a shared lock. If it has a shared lock, this function has no effect.

    +

    This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

    +

    It is unspecified how shared locks interact with locks acquired by +non-WASI programs.

    +

    This function returns error-code::would-block if the lock cannot be +acquired.

    +

    Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

    +

    Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

    +
    Params
    + +
    Return values
    + +

    try-lock-exclusive: func

    +

    Request an exclusive advisory lock for an open file.

    +

    This requests an exclusive lock; no other locks may be held for the +file while an exclusive lock is held.

    +

    If the open file has a shared lock and there are no exclusive locks held +for the file, this function upgrades the lock to an exclusive lock. If the +open file already has an exclusive lock, this function has no effect.

    +

    This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

    +

    It is unspecified whether this function succeeds if the file descriptor +is not opened for writing. It is unspecified how exclusive locks interact +with locks acquired by non-WASI programs.

    +

    This function returns error-code::would-block if the lock cannot be +acquired.

    +

    Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

    +

    Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

    +
    Params
    + +
    Return values
    + +

    unlock: func

    +

    Release a shared or exclusive lock on an open file.

    +

    Note: This is similar to flock(fd, LOCK_UN) in Unix.

    +
    Params
    + +
    Return values
    + +

    drop-descriptor: func

    +

    Dispose of the specified descriptor, after which it may no longer +be used.

    +
    Params
    + +

    read-directory-entry: func

    +

    Read a single directory entry from a directory-entry-stream.

    +
    Params
    + +
    Return values
    + +

    drop-directory-entry-stream: func

    +

    Dispose of the specified directory-entry-stream, after which it may no longer +be used.

    +
    Params
    + diff --git a/proposals/filesystem/wasi-filesystem.html b/proposals/filesystem/wasi-filesystem.html deleted file mode 100644 index 49ebbd35e..000000000 --- a/proposals/filesystem/wasi-filesystem.html +++ /dev/null @@ -1,1299 +0,0 @@ -

    Import interface wasi-poll

    -

    Types

    -

    pollable: u32

    -

    A "pollable" handle.

    -

    This is conceptually represents a stream<_, _>, or in other words, -a stream that one can wait on, repeatedly, but which does not itself -produce any data. It's temporary scaffolding until component-model's -async features are ready.

    -

    And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

    -

    pollable lifetimes are not automatically managed. Users must ensure -that they do not outlive the resource they reference.

    -

    Size: 4, Alignment: 4

    -

    Functions

    -
    -

    drop-pollable

    -

    Dispose of the specified pollable, after which it may no longer be used.

    -
    Params
    - -
    -

    poll-oneoff

    -

    Poll for completion on a set of pollables.

    -

    The "oneoff" in the name refers to the fact that this function must do a -linear scan through the entire list of subscriptions, which may be -inefficient if the number is large and the same subscriptions are used -many times. In the future, this is expected to be obsoleted by the -component model async proposal, which will include a scalable waiting -facility.

    -

    Note that the return type would ideally be list<bool>, but that would -be more difficult to polyfill given the current state of wit-bindgen. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 -for details. For now, we use zero to mean "not ready" and non-zero to -mean "ready".

    -
    Params
    - -
    Results
    -
      -
    • result0: list<u8>
    • -
    -

    Import interface wasi-io

    -

    Types

    -

    pollable: pollable

    -

    Size: 4, Alignment: 4

    -

    stream-error: record

    -

    An error type returned from a stream operation. Currently this -doesn't provide any additional information.

    -

    Size: 0, Alignment: 1

    -

    Record Fields

    -

    output-stream: u32

    -

    An output bytestream. In the future, this will be replaced by handle -types.

    -

    This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

    -

    And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

    -

    Size: 4, Alignment: 4

    -

    input-stream: u32

    -

    An input bytestream. In the future, this will be replaced by handle -types.

    -

    This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

    -

    And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

    -

    Size: 4, Alignment: 4

    -

    Functions

    -
    -

    read

    -

    Read bytes from a stream.

    -

    This function returns a list of bytes containing the data that was -read, along with a bool indicating whether the end of the stream -was reached. The returned list will contain up to len bytes; it -may return fewer than requested, but not more.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

    -

    If len is 0, it represents a request to read 0 bytes, which should -always succeed, assuming the stream hasn't reached its end yet, and -return an empty list.

    -

    The len here is a u64, but some callees may not be able to allocate -a buffer as large as that would imply. -FIXME: describe what happens if allocation fails.

    -
    Params
    - -
    Results
    - -
    -

    skip

    -

    Skip bytes from a stream.

    -

    This is similar to the read function, but avoids copying the -bytes into the instance.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

    -

    This function returns the number of bytes skipped, along with a bool -indicating whether the end of the stream was reached. The returned -value will be at most len; it may be less.

    -
    Params
    - -
    Results
    - -
    -

    subscribe-to-input-stream

    -

    Create a pollable which will resolve once either the specified stream has bytes -available to read or the other end of the stream has been closed.

    -
    Params
    - -
    Results
    - -
    -

    drop-input-stream

    -

    Dispose of the specified input-stream, after which it may no longer -be used.

    -
    Params
    - -
    -

    write

    -

    Write bytes to a stream.

    -

    This function returns a u64 indicating the number of bytes from -buf that were written; it may be less than the full list.

    -
    Params
    - -
    Results
    - -
    -

    write-zeroes

    -

    Write multiple zero bytes to a stream.

    -

    This function returns a u64 indicating the number of zero bytes -that were written; it may be less than len.

    -
    Params
    - -
    Results
    - -
    -

    splice

    -

    Read from one stream and write to another.

    -

    This function returns the number of bytes transferred; it may be less -than len.

    -
    Params
    - -
    Results
    - -
    -

    forward

    -

    Forward the entire contents of an input stream to an output stream.

    -

    This function repeatedly reads from the input stream and writes -the data to the output stream, until the end of the input stream -is reached, or an error is encountered.

    -

    This function returns the number of bytes transferred.

    -
    Params
    - -
    Results
    - -
    -

    subscribe-to-output-stream

    -

    Create a pollable which will resolve once either the specified stream is ready -to accept bytes or the other end of the stream has been closed.

    -
    Params
    - -
    Results
    - -
    -

    drop-output-stream

    -

    Dispose of the specified output-stream, after which it may no longer -be used.

    -
    Params
    - -

    Import interface wasi-wall-clock

    -

    Types

    -

    wall-clock: u32

    -

    A wall clock is a clock which measures the date and time according to some -external reference.

    -

    External references may be reset, so this clock is not necessarily -monotonic, making it unsuitable for measuring elapsed time.

    -

    It is intended for reporting the current date and time for humans.

    -

    Size: 4, Alignment: 4

    -

    datetime: record

    -

    A time and date in seconds plus nanoseconds.

    -

    Size: 16, Alignment: 8

    -

    Record Fields

    - -

    Functions

    -
    -

    now

    -

    Read the current value of the clock.

    -

    This clock is not monotonic, therefore calling this function repeatedly will -not necessarily produce a sequence of non-decreasing values.

    -

    The returned timestamps represent the number of seconds since -1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, also -known as Unix Time.

    -

    The nanoseconds field of the output is always less than 1000000000.

    -
    Params
    - -
    Results
    - -
    -

    resolution

    -

    Query the resolution of the clock.

    -

    The nanoseconds field of the output is always less than 1000000000.

    -
    Params
    - -
    Results
    - -
    -

    drop-wall-clock

    -

    Dispose of the specified wall-clock, after which it may no longer -be used.

    -
    Params
    - -

    Import interface wasi-filesystem

    -

    Types

    -

    input-stream: input-stream

    -

    Size: 4, Alignment: 4

    -

    output-stream: output-stream

    -

    Size: 4, Alignment: 4

    -

    datetime: datetime

    -

    Size: 16, Alignment: 8

    -

    path-flags: record

    -

    Flags determining the method of how paths are resolved.

    -

    Size: 1, Alignment: 1

    -

    Record Fields

    -
      -
    • -

      symlink-follow:

      -

      As long as the resolved path corresponds to a symbolic link, it is expanded. -Bit: 0

      -
    • -
    -

    open-flags: record

    -

    Open flags used by open-at.

    -

    Size: 1, Alignment: 1

    -

    Record Fields

    -
      -
    • -

      create:

      -

      Create file if it does not exist. -Bit: 0

      -
    • -
    • -

      directory:

      -

      Fail if not a directory. -Bit: 1

      -
    • -
    • -

      exclusive:

      -

      Fail if file already exists. -Bit: 2

      -
    • -
    • -

      truncate:

      -

      Truncate file to size 0. -Bit: 3

      -
    • -
    -

    modes: record

    -

    Permissions mode used by open-at, change-file-permissions-at, and -similar.

    -

    Size: 1, Alignment: 1

    -

    Record Fields

    -
      -
    • -

      readable:

      -

      True if the resource is considered readable by the containing -filesystem. -Bit: 0

      -
    • -
    • -

      writeable:

      -

      True if the resource is considered writeable by the containing -filesystem. -Bit: 1

      -
    • -
    • -

      executable:

      -

      True if the resource is considered executable by the containing -filesystem. This does not apply to directories. -Bit: 2

      -
    • -
    -

    link-count: u64

    -

    Number of hard links to an inode.

    -

    Size: 8, Alignment: 8

    -

    inode: u64

    -

    Filesystem object serial number that is unique within its file system.

    -

    Size: 8, Alignment: 8

    -

    filesize: u64

    -

    File size or length of a region within a file.

    -

    Size: 8, Alignment: 8

    -

    error-code: enum

    -

    Error codes returned by functions. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX.

    -

    Size: 1, Alignment: 1

    -

    Enum Cases

    - -

    directory-entry-stream: u32

    -

    A stream of directory entries.

    -

    Size: 4, Alignment: 4

    -

    device: u64

    -

    Identifier for a device containing a file system. Can be used in combination -with inode to uniquely identify a file or directory in the filesystem.

    -

    Size: 8, Alignment: 8

    -

    descriptor-type: enum

    -

    The type of a filesystem object referenced by a descriptor.

    -

    Note: This was called filetype in earlier versions of WASI.

    -

    Size: 1, Alignment: 1

    -

    Enum Cases

    -
      -
    • -

      unknown

      -

      The type of the descriptor or file is unknown or is different from -any of the other types specified.

      -
    • -
    • -

      block-device

      -

      The descriptor refers to a block device inode.

      -
    • -
    • -

      character-device

      -

      The descriptor refers to a character device inode.

      -
    • -
    • -

      directory

      -

      The descriptor refers to a directory inode.

      -
    • -
    • -

      fifo

      -

      The descriptor refers to a named pipe.

      -
    • -
    • -

      symbolic-link

      -

      The file refers to a symbolic link inode.

      -
    • -
    • -

      regular-file

      -

      The descriptor refers to a regular file inode.

      -
    • -
    • -

      socket

      -

      The descriptor refers to a socket.

      -
    • -
    -

    directory-entry: record

    -

    A directory entry.

    -

    Size: 32, Alignment: 8

    -

    Record Fields

    -
      -
    • -

      inode: option<inode>

      -

      The serial number of the object referred to by this directory entry. -May be none if the inode value is not known.

      -

      When this is none, libc implementations might do an extra stat-at -call to retrieve the inode number to fill their d_ino fields, so -implementations which can set this to a non-none value should do so.

      -
    • -
    • -

      type: descriptor-type

      -

      The type of the file referred to by this directory entry.

      -
    • -
    • -

      name: string

      -

      The name of the object.

      -
    • -
    -

    descriptor-flags: record

    -

    Descriptor flags.

    -

    Note: This was called fdflags in earlier versions of WASI.

    -

    Size: 1, Alignment: 1

    -

    Record Fields

    -
      -
    • -

      read:

      -

      Read mode: Data can be read. -Bit: 0

      -
    • -
    • -

      write:

      -

      Write mode: Data can be written to. -Bit: 1

      -
    • -
    • -

      non-blocking:

      -

      Requests non-blocking operation.

      -

      When this flag is enabled, functions may return immediately with an -error-code::would-block error code in situations where they would otherwise -block. However, this non-blocking behavior is not required. -Implementations are permitted to ignore this flag and block. -Bit: 2

      -
    • -
    • -

      file-integrity-sync:

      -

      Request that writes be performed according to synchronized I/O file -integrity completion. The data stored in the file and the file's -metadata are synchronized.

      -

      The precise semantics of this operation have not yet been defined for -WASI. At this time, it should be interpreted as a request, and not a -requirement. -Bit: 3

      -
    • -
    • -

      data-integrity-sync:

      -

      Request that writes be performed according to synchronized I/O data -integrity completion. Only the data stored in the file is -synchronized.

      -

      The precise semantics of this operation have not yet been defined for -WASI. At this time, it should be interpreted as a request, and not a -requirement. -Bit: 4

      -
    • -
    • -

      requested-write-sync:

      -

      Requests that reads be performed at the same level of integrety -requested for writes.

      -

      The precise semantics of this operation have not yet been defined for -WASI. At this time, it should be interpreted as a request, and not a -requirement. -Bit: 5

      -
    • -
    • -

      mutate-directory:

      -

      Mutating directories mode: Directory contents may be mutated.

      -

      When this flag is unset on a descriptor, operations using the -descriptor which would create, rename, delete, modify the data or -metadata of filesystem objects, or obtain another handle which -would permit any of those, shall fail with error-code::read-only if -they would otherwise succeed.

      -

      This may only be set on directories. -Bit: 6

      -
    • -
    -

    descriptor: u32

    -

    A descriptor is a reference to a filesystem object, which may be a file, -directory, named pipe, special file, or other object on which filesystem -calls may be made.

    -

    Size: 4, Alignment: 4

    -

    new-timestamp: variant

    -

    When setting a timestamp, this gives the value to set it to.

    -

    Size: 24, Alignment: 8

    -

    Variant Cases

    -
      -
    • -

      no-change

      -

      Leave the timestamp set to its previous value.

      -
    • -
    • -

      now

      -

      Set the timestamp to the current time of the system clock associated -with the filesystem.

      -
    • -
    • -

      timestamp: datetime

      -

      Set the timestamp to the given value.

      -
    • -
    -

    descriptor-stat: record

    -

    File attributes.

    -

    Note: This was called filestat in earlier versions of WASI.

    -

    Size: 88, Alignment: 8

    -

    Record Fields

    - -

    advice: enum

    -

    File or memory access pattern advisory information.

    -

    Size: 1, Alignment: 1

    -

    Enum Cases

    -
      -
    • -

      normal

      -

      The application has no advice to give on its behavior with respect to the specified data.

      -
    • -
    • -

      sequential

      -

      The application expects to access the specified data sequentially from lower offsets to higher offsets.

      -
    • -
    • -

      random

      -

      The application expects to access the specified data in a random order.

      -
    • -
    • -

      will-need

      -

      The application expects to access the specified data in the near future.

      -
    • -
    • -

      dont-need

      -

      The application expects that it will not access the specified data in the near future.

      -
    • -
    • -

      no-reuse

      -

      The application expects to access the specified data once and then not reuse it thereafter.

      -
    • -
    -

    Functions

    -
    -

    read-via-stream

    -

    Return a stream for reading from a file.

    -

    Multiple read, write, and append streams may be active on the same open -file and they do not interfere with each other.

    -

    Note: This allows using read-stream, which is similar to read in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    write-via-stream

    -

    Return a stream for writing to a file.

    -

    Note: This allows using write-stream, which is similar to write in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    append-via-stream

    -

    Return a stream for appending to a file.

    -

    Note: This allows using write-stream, which is similar to write with -O_APPEND in in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    advise

    -

    Provide file advisory information on a descriptor.

    -

    This is similar to posix_fadvise in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    sync-data

    -

    Synchronize the data of a file to disk.

    -

    This function succeeds with no effect if the file descriptor is not -opened for writing.

    -

    Note: This is similar to fdatasync in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    get-flags

    -

    Get flags associated with a descriptor.

    -

    Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

    -

    Note: This returns the value that was the fs_flags value returned -from fdstat_get in earlier versions of WASI.

    -
    Params
    - -
    Results
    - -
    -

    get-type

    -

    Get the dynamic type of a descriptor.

    -

    Note: This returns the same value as the type field of the fd-stat -returned by stat, stat-at and similar.

    -

    Note: This returns similar flags to the st_mode & S_IFMT value provided -by fstat in POSIX.

    -

    Note: This returns the value that was the fs_filetype value returned -from fdstat_get in earlier versions of WASI.

    -
    Params
    - -
    Results
    - -
    -

    set-flags

    -

    Set status flags associated with a descriptor.

    -

    This function may only change the non-blocking flag.

    -

    Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

    -

    Note: This was called fd_fdstat_set_flags in earlier versions of WASI.

    -
    Params
    - -
    Results
    - -
    -

    set-size

    -

    Adjust the size of an open file. If this increases the file's size, the -extra bytes are filled with zeros.

    -

    Note: This was called fd_filestat_set_size in earlier versions of WASI.

    -
    Params
    - -
    Results
    - -
    -

    set-times

    -

    Adjust the timestamps of an open file or directory.

    -

    Note: This is similar to futimens in POSIX.

    -

    Note: This was called fd_filestat_set_times in earlier versions of WASI.

    -
    Params
    - -
    Results
    - -
    -

    read

    -

    Read from a descriptor, without using and updating the descriptor's offset.

    -

    This function returns a list of bytes containing the data that was -read, along with a bool which, when true, indicates that the end of the -file was reached. The returned list will contain up to length bytes; it -may return fewer than requested, if the end of the file is reached or -if the I/O operation is interrupted.

    -

    Note: This is similar to pread in POSIX.

    -
    Params
    - -
    Results
    -
      -
    • result0: result<(list<u8>, bool), error-code>
    • -
    -
    -

    write

    -

    Write to a descriptor, without using and updating the descriptor's offset.

    -

    It is valid to write past the end of a file; the file is extended to the -extent of the write, with bytes between the previous end and the start of -the write set to zero.

    -

    Note: This is similar to pwrite in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    read-directory

    -

    Read directory entries from a directory.

    -

    On filesystems where directories contain entries referring to themselves -and their parents, often named . and .. respectively, these entries -are omitted.

    -

    This always returns a new stream which starts at the beginning of the -directory. Multiple streams may be active on the same directory, and they -do not interfere with each other.

    -
    Params
    - -
    Results
    - -
    -

    sync

    -

    Synchronize the data and metadata of a file to disk.

    -

    This function succeeds with no effect if the file descriptor is not -opened for writing.

    -

    Note: This is similar to fsync in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    create-directory-at

    -

    Create a directory.

    -

    Note: This is similar to mkdirat in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    stat

    -

    Return the attributes of an open file or directory.

    -

    Note: This is similar to fstat in POSIX.

    -

    Note: This was called fd_filestat_get in earlier versions of WASI.

    -
    Params
    - -
    Results
    - -
    -

    stat-at

    -

    Return the attributes of a file or directory.

    -

    Note: This is similar to fstatat in POSIX.

    -

    Note: This was called path_filestat_get in earlier versions of WASI.

    -
    Params
    - -
    Results
    - -
    -

    set-times-at

    -

    Adjust the timestamps of a file or directory.

    -

    Note: This is similar to utimensat in POSIX.

    -

    Note: This was called path_filestat_set_times in earlier versions of WASI.

    -
    Params
    - -
    Results
    - -
    -

    link-at

    -

    Create a hard link.

    -

    Note: This is similar to linkat in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    open-at

    -

    Open a file or directory.

    -

    The returned descriptor is not guaranteed to be the lowest-numbered -descriptor not currently open/ it is randomized to prevent applications -from depending on making assumptions about indexes, since this is -error-prone in multi-threaded contexts. The returned descriptor is -guaranteed to be less than 2**31.

    -

    If flags contains descriptor-flags::mutate-directory, and the base -descriptor doesn't have descriptor-flags::mutate-directory set, -open-at fails with error-code::read-only.

    -

    If flags contains write or mutate-directory, or open-flags -contains truncate or create, and the base descriptor doesn't have -descriptor-flags::mutate-directory set, open-at fails with -error-code::read-only.

    -

    Note: This is similar to openat in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    readlink-at

    -

    Read the contents of a symbolic link.

    -

    If the contents contain an absolute or rooted path in the underlying -filesystem, this function fails with error-code::not-permitted.

    -

    Note: This is similar to readlinkat in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    remove-directory-at

    -

    Remove a directory.

    -

    Return error-code::not-empty if the directory is not empty.

    -

    Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    rename-at

    -

    Rename a filesystem object.

    -

    Note: This is similar to renameat in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    symlink-at

    -

    Create a symbolic link (also known as a "symlink").

    -

    If old-path starts with /, the function fails with error-code::not-permitted.

    -

    Note: This is similar to symlinkat in POSIX.

    -
    Params
    -
      -
    • this: descriptor
    • -
    • old-path: string
    • -
    • new-path: string
    • -
    -
    Results
    - -
    -

    unlink-file-at

    -

    Unlink a filesystem object that is not a directory.

    -

    Return error-code::is-directory if the path refers to a directory. -Note: This is similar to unlinkat(fd, path, 0) in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    change-file-permissions-at

    -

    Change the permissions of a filesystem object that is not a directory.

    -

    Note that the ultimate meanings of these permissions is -filesystem-specific.

    -

    Note: This is similar to fchmodat in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    change-directory-permissions-at

    -

    Change the permissions of a directory.

    -

    Note that the ultimate meanings of these permissions is -filesystem-specific.

    -

    Unlike in POSIX, the executable flag is not reinterpreted as a "search" -flag. read on a directory implies readability and searchability, and -execute is not valid for directories.

    -

    Note: This is similar to fchmodat in POSIX.

    -
    Params
    - -
    Results
    - -
    -

    lock-shared

    -

    Request a shared advisory lock for an open file.

    -

    This requests a shared lock; more than one shared lock can be held for -a file at the same time.

    -

    If the open file has an exclusive lock, this function downgrades the lock -to a shared lock. If it has a shared lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified how shared locks interact with locks acquired by -non-WASI programs.

    -

    This function blocks until the lock can be acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_SH) in Unix.

    -
    Params
    - -
    Results
    - -
    -

    lock-exclusive

    -

    Request an exclusive advisory lock for an open file.

    -

    This requests an exclusive lock; no other locks may be held for the -file while an exclusive lock is held.

    -

    If the open file has a shared lock and there are no exclusive locks held -for the file, this function upgrades the lock to an exclusive lock. If the -open file already has an exclusive lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified whether this function succeeds if the file descriptor -is not opened for writing. It is unspecified how exclusive locks interact -with locks acquired by non-WASI programs.

    -

    This function blocks until the lock can be acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_EX) in Unix.

    -
    Params
    - -
    Results
    - -
    -

    try-lock-shared

    -

    Request a shared advisory lock for an open file.

    -

    This requests a shared lock; more than one shared lock can be held for -a file at the same time.

    -

    If the open file has an exclusive lock, this function downgrades the lock -to a shared lock. If it has a shared lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified how shared locks interact with locks acquired by -non-WASI programs.

    -

    This function returns error-code::would-block if the lock cannot be acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

    -
    Params
    - -
    Results
    - -
    -

    try-lock-exclusive

    -

    Request an exclusive advisory lock for an open file.

    -

    This requests an exclusive lock; no other locks may be held for the -file while an exclusive lock is held.

    -

    If the open file has a shared lock and there are no exclusive locks held -for the file, this function upgrades the lock to an exclusive lock. If the -open file already has an exclusive lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified whether this function succeeds if the file descriptor -is not opened for writing. It is unspecified how exclusive locks interact -with locks acquired by non-WASI programs.

    -

    This function returns error-code::would-block if the lock cannot be acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

    -
    Params
    - -
    Results
    - -
    -

    unlock

    -

    Release a shared or exclusive lock on an open file.

    -

    Note: This is similar to flock(fd, LOCK_UN) in Unix.

    -
    Params
    - -
    Results
    - -
    -

    drop-descriptor

    -

    Dispose of the specified descriptor, after which it may no longer -be used.

    -
    Params
    - -
    -

    read-directory-entry

    -

    Read a single directory entry from a directory-entry-stream.

    -
    Params
    - -
    Results
    - -
    -

    drop-directory-entry-stream

    -

    Dispose of the specified directory-entry-stream, after which it may no longer -be used.

    -
    Params
    - diff --git a/proposals/filesystem/wasi-filesystem.md b/proposals/filesystem/wasi-filesystem.md deleted file mode 100644 index ec605c875..000000000 --- a/proposals/filesystem/wasi-filesystem.md +++ /dev/null @@ -1,1555 +0,0 @@ -# Import interface `wasi-poll` - -## Types - -## `pollable`: `u32` - -A "pollable" handle. - -This is conceptually represents a `stream<_, _>`, or in other words, -a stream that one can wait on, repeatedly, but which does not itself -produce any data. It's temporary scaffolding until component-model's -async features are ready. - -And at present, it is a `u32` instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready. - -`pollable` lifetimes are not automatically managed. Users must ensure -that they do not outlive the resource they reference. - -Size: 4, Alignment: 4 - -## Functions - ----- - -#### `drop-pollable` - -Dispose of the specified `pollable`, after which it may no longer be used. -##### Params - -- `this`: [`pollable`](#pollable) - ----- - -#### `poll-oneoff` - -Poll for completion on a set of pollables. - -The "oneoff" in the name refers to the fact that this function must do a -linear scan through the entire list of subscriptions, which may be -inefficient if the number is large and the same subscriptions are used -many times. In the future, this is expected to be obsoleted by the -component model async proposal, which will include a scalable waiting -facility. - -Note that the return type would ideally be `list`, but that would -be more difficult to polyfill given the current state of `wit-bindgen`. -See -for details. For now, we use zero to mean "not ready" and non-zero to -mean "ready". -##### Params - -- `in`: list<[`pollable`](#pollable)> -##### Results - -- `result0`: list<`u8`> - -# Import interface `wasi-io` - -## Types - -## `pollable`: [`pollable`](#pollable) - - -Size: 4, Alignment: 4 - -## `stream-error`: record - -An error type returned from a stream operation. Currently this -doesn't provide any additional information. - -Size: 0, Alignment: 1 - -### Record Fields - -## `output-stream`: `u32` - -An output bytestream. In the future, this will be replaced by handle -types. - -This conceptually represents a `stream`. It's temporary -scaffolding until component-model's async features are ready. - -And at present, it is a `u32` instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready. - -Size: 4, Alignment: 4 - -## `input-stream`: `u32` - -An input bytestream. In the future, this will be replaced by handle -types. - -This conceptually represents a `stream`. It's temporary -scaffolding until component-model's async features are ready. - -And at present, it is a `u32` instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready. - -Size: 4, Alignment: 4 - -## Functions - ----- - -#### `read` - -Read bytes from a stream. - -This function returns a list of bytes containing the data that was -read, along with a bool indicating whether the end of the stream -was reached. The returned list will contain up to `len` bytes; it -may return fewer than requested, but not more. - -Once a stream has reached the end, subsequent calls to read or -`skip` will always report end-of-stream rather than producing more -data. - -If `len` is 0, it represents a request to read 0 bytes, which should -always succeed, assuming the stream hasn't reached its end yet, and -return an empty list. - -The len here is a `u64`, but some callees may not be able to allocate -a buffer as large as that would imply. -FIXME: describe what happens if allocation fails. -##### Params - -- `this`: [`input-stream`](#input_stream) -- `len`: `u64` -##### Results - -- `result0`: result<(list<`u8`>, `bool`), [`stream-error`](#stream_error)> - ----- - -#### `skip` - -Skip bytes from a stream. - -This is similar to the `read` function, but avoids copying the -bytes into the instance. - -Once a stream has reached the end, subsequent calls to read or -`skip` will always report end-of-stream rather than producing more -data. - -This function returns the number of bytes skipped, along with a bool -indicating whether the end of the stream was reached. The returned -value will be at most `len`; it may be less. -##### Params - -- `this`: [`input-stream`](#input_stream) -- `len`: `u64` -##### Results - -- `result0`: result<(`u64`, `bool`), [`stream-error`](#stream_error)> - ----- - -#### `subscribe-to-input-stream` - -Create a `pollable` which will resolve once either the specified stream has bytes -available to read or the other end of the stream has been closed. -##### Params - -- `this`: [`input-stream`](#input_stream) -##### Results - -- `result0`: [`pollable`](#pollable) - ----- - -#### `drop-input-stream` - -Dispose of the specified `input-stream`, after which it may no longer -be used. -##### Params - -- `this`: [`input-stream`](#input_stream) - ----- - -#### `write` - -Write bytes to a stream. - -This function returns a `u64` indicating the number of bytes from -`buf` that were written; it may be less than the full list. -##### Params - -- `this`: [`output-stream`](#output_stream) -- `buf`: list<`u8`> -##### Results - -- `result0`: result<`u64`, [`stream-error`](#stream_error)> - ----- - -#### `write-zeroes` - -Write multiple zero bytes to a stream. - -This function returns a `u64` indicating the number of zero bytes -that were written; it may be less than `len`. -##### Params - -- `this`: [`output-stream`](#output_stream) -- `len`: `u64` -##### Results - -- `result0`: result<`u64`, [`stream-error`](#stream_error)> - ----- - -#### `splice` - -Read from one stream and write to another. - -This function returns the number of bytes transferred; it may be less -than `len`. -##### Params - -- `this`: [`output-stream`](#output_stream) -- `src`: [`input-stream`](#input_stream) -- `len`: `u64` -##### Results - -- `result0`: result<(`u64`, `bool`), [`stream-error`](#stream_error)> - ----- - -#### `forward` - -Forward the entire contents of an input stream to an output stream. - -This function repeatedly reads from the input stream and writes -the data to the output stream, until the end of the input stream -is reached, or an error is encountered. - -This function returns the number of bytes transferred. -##### Params - -- `this`: [`output-stream`](#output_stream) -- `src`: [`input-stream`](#input_stream) -##### Results - -- `result0`: result<`u64`, [`stream-error`](#stream_error)> - ----- - -#### `subscribe-to-output-stream` - -Create a `pollable` which will resolve once either the specified stream is ready -to accept bytes or the other end of the stream has been closed. -##### Params - -- `this`: [`output-stream`](#output_stream) -##### Results - -- `result0`: [`pollable`](#pollable) - ----- - -#### `drop-output-stream` - -Dispose of the specified `output-stream`, after which it may no longer -be used. -##### Params - -- `this`: [`output-stream`](#output_stream) - -# Import interface `wasi-wall-clock` - -## Types - -## `wall-clock`: `u32` - -A wall clock is a clock which measures the date and time according to some -external reference. - -External references may be reset, so this clock is not necessarily -monotonic, making it unsuitable for measuring elapsed time. - -It is intended for reporting the current date and time for humans. - -Size: 4, Alignment: 4 - -## `datetime`: record - -A time and date in seconds plus nanoseconds. - -Size: 16, Alignment: 8 - -### Record Fields - -- [`seconds`](#datetime.seconds): `u64` - - -- [`nanoseconds`](#datetime.nanoseconds): `u32` - - -## Functions - ----- - -#### `now` - -Read the current value of the clock. - -This clock is not monotonic, therefore calling this function repeatedly will -not necessarily produce a sequence of non-decreasing values. - -The returned timestamps represent the number of seconds since -1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], also -known as [Unix Time]. - -The nanoseconds field of the output is always less than 1000000000. - -[POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 -[Unix Time]: https://en.wikipedia.org/wiki/Unix_time -##### Params - -- `this`: [`wall-clock`](#wall_clock) -##### Results - -- `result0`: [`datetime`](#datetime) - ----- - -#### `resolution` - -Query the resolution of the clock. - -The nanoseconds field of the output is always less than 1000000000. -##### Params - -- `this`: [`wall-clock`](#wall_clock) -##### Results - -- `result0`: [`datetime`](#datetime) - ----- - -#### `drop-wall-clock` - -Dispose of the specified `wall-clock`, after which it may no longer -be used. -##### Params - -- `this`: [`wall-clock`](#wall_clock) - -# Import interface `wasi-filesystem` - -## Types - -## `input-stream`: [`input-stream`](#input_stream) - - -Size: 4, Alignment: 4 - -## `output-stream`: [`output-stream`](#output_stream) - - -Size: 4, Alignment: 4 - -## `datetime`: [`datetime`](#datetime) - - -Size: 16, Alignment: 8 - -## `path-flags`: record - -Flags determining the method of how paths are resolved. - -Size: 1, Alignment: 1 - -### Record Fields - -- [`symlink-follow`](#path_flags.symlink_follow): - - As long as the resolved path corresponds to a symbolic link, it is expanded. - Bit: 0 - -## `open-flags`: record - -Open flags used by `open-at`. - -Size: 1, Alignment: 1 - -### Record Fields - -- [`create`](#open_flags.create): - - Create file if it does not exist. - Bit: 0 - -- [`directory`](#open_flags.directory): - - Fail if not a directory. - Bit: 1 - -- [`exclusive`](#open_flags.exclusive): - - Fail if file already exists. - Bit: 2 - -- [`truncate`](#open_flags.truncate): - - Truncate file to size 0. - Bit: 3 - -## `modes`: record - -Permissions mode used by `open-at`, `change-file-permissions-at`, and -similar. - -Size: 1, Alignment: 1 - -### Record Fields - -- [`readable`](#modes.readable): - - True if the resource is considered readable by the containing - filesystem. - Bit: 0 - -- [`writeable`](#modes.writeable): - - True if the resource is considered writeable by the containing - filesystem. - Bit: 1 - -- [`executable`](#modes.executable): - - True if the resource is considered executable by the containing - filesystem. This does not apply to directories. - Bit: 2 - -## `link-count`: `u64` - -Number of hard links to an inode. - -Size: 8, Alignment: 8 - -## `inode`: `u64` - -Filesystem object serial number that is unique within its file system. - -Size: 8, Alignment: 8 - -## `filesize`: `u64` - -File size or length of a region within a file. - -Size: 8, Alignment: 8 - -## `error-code`: enum - -Error codes returned by functions. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX. - -Size: 1, Alignment: 1 - -### Enum Cases - -- [`access`](#error_code.access) - - Permission denied. - -- [`would-block`](#error_code.would_block) - - Resource unavailable, or operation would block. - -- [`already`](#error_code.already) - - Connection already in progress. - -- [`bad-descriptor`](#error_code.bad_descriptor) - - Bad descriptor. - -- [`busy`](#error_code.busy) - - Device or resource busy. - -- [`deadlock`](#error_code.deadlock) - - Resource deadlock would occur. - -- [`quota`](#error_code.quota) - - Storage quota exceeded. - -- [`exist`](#error_code.exist) - - File exists. - -- [`file-too-large`](#error_code.file_too_large) - - File too large. - -- [`illegal-byte-sequence`](#error_code.illegal_byte_sequence) - - Illegal byte sequence. - -- [`in-progress`](#error_code.in_progress) - - Operation in progress. - -- [`interrupted`](#error_code.interrupted) - - Interrupted function. - -- [`invalid`](#error_code.invalid) - - Invalid argument. - -- [`io`](#error_code.io) - - I/O error. - -- [`is-directory`](#error_code.is_directory) - - Is a directory. - -- [`loop`](#error_code.loop) - - Too many levels of symbolic links. - -- [`too-many-links`](#error_code.too_many_links) - - Too many links. - -- [`message-size`](#error_code.message_size) - - Message too large. - -- [`name-too-long`](#error_code.name_too_long) - - Filename too long. - -- [`no-device`](#error_code.no_device) - - No such device. - -- [`no-entry`](#error_code.no_entry) - - No such file or directory. - -- [`no-lock`](#error_code.no_lock) - - No locks available. - -- [`insufficient-memory`](#error_code.insufficient_memory) - - Not enough space. - -- [`insufficient-space`](#error_code.insufficient_space) - - No space left on device. - -- [`not-directory`](#error_code.not_directory) - - Not a directory or a symbolic link to a directory. - -- [`not-empty`](#error_code.not_empty) - - Directory not empty. - -- [`not-recoverable`](#error_code.not_recoverable) - - State not recoverable. - -- [`unsupported`](#error_code.unsupported) - - Not supported - -- [`no-tty`](#error_code.no_tty) - - Inappropriate I/O control operation. - -- [`no-such-device`](#error_code.no_such_device) - - No such device or address. - -- [`overflow`](#error_code.overflow) - - Value too large to be stored in data type. - -- [`not-permitted`](#error_code.not_permitted) - - Operation not permitted. - -- [`pipe`](#error_code.pipe) - - Broken pipe. - -- [`read-only`](#error_code.read_only) - - Read-only file system. - -- [`invalid-seek`](#error_code.invalid_seek) - - Invalid seek. - -- [`text-file-busy`](#error_code.text_file_busy) - - Text file busy. - -- [`cross-device`](#error_code.cross_device) - - Cross-device link. - -## `directory-entry-stream`: `u32` - -A stream of directory entries. - -Size: 4, Alignment: 4 - -## `device`: `u64` - -Identifier for a device containing a file system. Can be used in combination -with `inode` to uniquely identify a file or directory in the filesystem. - -Size: 8, Alignment: 8 - -## `descriptor-type`: enum - -The type of a filesystem object referenced by a descriptor. - -Note: This was called `filetype` in earlier versions of WASI. - -Size: 1, Alignment: 1 - -### Enum Cases - -- [`unknown`](#descriptor_type.unknown) - - The type of the descriptor or file is unknown or is different from - any of the other types specified. - -- [`block-device`](#descriptor_type.block_device) - - The descriptor refers to a block device inode. - -- [`character-device`](#descriptor_type.character_device) - - The descriptor refers to a character device inode. - -- [`directory`](#descriptor_type.directory) - - The descriptor refers to a directory inode. - -- [`fifo`](#descriptor_type.fifo) - - The descriptor refers to a named pipe. - -- [`symbolic-link`](#descriptor_type.symbolic_link) - - The file refers to a symbolic link inode. - -- [`regular-file`](#descriptor_type.regular_file) - - The descriptor refers to a regular file inode. - -- [`socket`](#descriptor_type.socket) - - The descriptor refers to a socket. - -## `directory-entry`: record - -A directory entry. - -Size: 32, Alignment: 8 - -### Record Fields - -- [`inode`](#directory_entry.inode): option<[`inode`](#inode)> - - The serial number of the object referred to by this directory entry. - May be none if the inode value is not known. - - When this is none, libc implementations might do an extra `stat-at` - call to retrieve the inode number to fill their `d_ino` fields, so - implementations which can set this to a non-none value should do so. - -- [`type`](#directory_entry.type): [`descriptor-type`](#descriptor_type) - - The type of the file referred to by this directory entry. - -- [`name`](#directory_entry.name): `string` - - The name of the object. - -## `descriptor-flags`: record - -Descriptor flags. - -Note: This was called `fdflags` in earlier versions of WASI. - -Size: 1, Alignment: 1 - -### Record Fields - -- [`read`](#descriptor_flags.read): - - Read mode: Data can be read. - Bit: 0 - -- [`write`](#descriptor_flags.write): - - Write mode: Data can be written to. - Bit: 1 - -- [`non-blocking`](#descriptor_flags.non_blocking): - - Requests non-blocking operation. - - When this flag is enabled, functions may return immediately with an - `error-code::would-block` error code in situations where they would otherwise - block. However, this non-blocking behavior is not required. - Implementations are permitted to ignore this flag and block. - Bit: 2 - -- [`file-integrity-sync`](#descriptor_flags.file_integrity_sync): - - Request that writes be performed according to synchronized I/O file - integrity completion. The data stored in the file and the file's - metadata are synchronized. - - The precise semantics of this operation have not yet been defined for - WASI. At this time, it should be interpreted as a request, and not a - requirement. - Bit: 3 - -- [`data-integrity-sync`](#descriptor_flags.data_integrity_sync): - - Request that writes be performed according to synchronized I/O data - integrity completion. Only the data stored in the file is - synchronized. - - The precise semantics of this operation have not yet been defined for - WASI. At this time, it should be interpreted as a request, and not a - requirement. - Bit: 4 - -- [`requested-write-sync`](#descriptor_flags.requested_write_sync): - - Requests that reads be performed at the same level of integrety - requested for writes. - - The precise semantics of this operation have not yet been defined for - WASI. At this time, it should be interpreted as a request, and not a - requirement. - Bit: 5 - -- [`mutate-directory`](#descriptor_flags.mutate_directory): - - Mutating directories mode: Directory contents may be mutated. - - When this flag is unset on a descriptor, operations using the - descriptor which would create, rename, delete, modify the data or - metadata of filesystem objects, or obtain another handle which - would permit any of those, shall fail with `error-code::read-only` if - they would otherwise succeed. - - This may only be set on directories. - Bit: 6 - -## `descriptor`: `u32` - -A descriptor is a reference to a filesystem object, which may be a file, -directory, named pipe, special file, or other object on which filesystem -calls may be made. - -Size: 4, Alignment: 4 - -## `new-timestamp`: variant - -When setting a timestamp, this gives the value to set it to. - -Size: 24, Alignment: 8 - -### Variant Cases - -- [`no-change`](#new_timestamp.no_change) - - Leave the timestamp set to its previous value. - -- [`now`](#new_timestamp.now) - - Set the timestamp to the current time of the system clock associated - with the filesystem. - -- [`timestamp`](#new_timestamp.timestamp): [`datetime`](#datetime) - - Set the timestamp to the given value. - -## `descriptor-stat`: record - -File attributes. - -Note: This was called `filestat` in earlier versions of WASI. - -Size: 88, Alignment: 8 - -### Record Fields - -- [`device`](#descriptor_stat.device): [`device`](#device) - - Device ID of device containing the file. - -- [`inode`](#descriptor_stat.inode): [`inode`](#inode) - - File serial number. - -- [`type`](#descriptor_stat.type): [`descriptor-type`](#descriptor_type) - - File type. - -- [`link-count`](#descriptor_stat.link_count): [`link-count`](#link_count) - - Number of hard links to the file. - -- [`size`](#descriptor_stat.size): [`filesize`](#filesize) - - For regular files, the file size in bytes. For symbolic links, the length - in bytes of the pathname contained in the symbolic link. - -- [`data-access-timestamp`](#descriptor_stat.data_access_timestamp): [`datetime`](#datetime) - - Last data access timestamp. - -- [`data-modification-timestamp`](#descriptor_stat.data_modification_timestamp): [`datetime`](#datetime) - - Last data modification timestamp. - -- [`status-change-timestamp`](#descriptor_stat.status_change_timestamp): [`datetime`](#datetime) - - Last file status change timestamp. - -## `advice`: enum - -File or memory access pattern advisory information. - -Size: 1, Alignment: 1 - -### Enum Cases - -- [`normal`](#advice.normal) - - The application has no advice to give on its behavior with respect to the specified data. - -- [`sequential`](#advice.sequential) - - The application expects to access the specified data sequentially from lower offsets to higher offsets. - -- [`random`](#advice.random) - - The application expects to access the specified data in a random order. - -- [`will-need`](#advice.will_need) - - The application expects to access the specified data in the near future. - -- [`dont-need`](#advice.dont_need) - - The application expects that it will not access the specified data in the near future. - -- [`no-reuse`](#advice.no_reuse) - - The application expects to access the specified data once and then not reuse it thereafter. - -## Functions - ----- - -#### `read-via-stream` - -Return a stream for reading from a file. - -Multiple read, write, and append streams may be active on the same open -file and they do not interfere with each other. - -Note: This allows using `read-stream`, which is similar to `read` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `offset`: [`filesize`](#filesize) -##### Results - -- `result0`: result<[`input-stream`](#input_stream), [`error-code`](#error_code)> - ----- - -#### `write-via-stream` - -Return a stream for writing to a file. - -Note: This allows using `write-stream`, which is similar to `write` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `offset`: [`filesize`](#filesize) -##### Results - -- `result0`: result<[`output-stream`](#output_stream), [`error-code`](#error_code)> - ----- - -#### `append-via-stream` - -Return a stream for appending to a file. - -Note: This allows using `write-stream`, which is similar to `write` with -`O_APPEND` in in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `fd`: [`descriptor`](#descriptor) -##### Results - -- `result0`: result<[`output-stream`](#output_stream), [`error-code`](#error_code)> - ----- - -#### `advise` - -Provide file advisory information on a descriptor. - -This is similar to `posix_fadvise` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `offset`: [`filesize`](#filesize) -- `length`: [`filesize`](#filesize) -- `advice`: [`advice`](#advice) -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `sync-data` - -Synchronize the data of a file to disk. - -This function succeeds with no effect if the file descriptor is not -opened for writing. - -Note: This is similar to `fdatasync` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `get-flags` - -Get flags associated with a descriptor. - -Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. - -Note: This returns the value that was the `fs_flags` value returned -from `fdstat_get` in earlier versions of WASI. -##### Params - -- `this`: [`descriptor`](#descriptor) -##### Results - -- `result0`: result<[`descriptor-flags`](#descriptor_flags), [`error-code`](#error_code)> - ----- - -#### `get-type` - -Get the dynamic type of a descriptor. - -Note: This returns the same value as the `type` field of the `fd-stat` -returned by `stat`, `stat-at` and similar. - -Note: This returns similar flags to the `st_mode & S_IFMT` value provided -by `fstat` in POSIX. - -Note: This returns the value that was the `fs_filetype` value returned -from `fdstat_get` in earlier versions of WASI. -##### Params - -- `this`: [`descriptor`](#descriptor) -##### Results - -- `result0`: result<[`descriptor-type`](#descriptor_type), [`error-code`](#error_code)> - ----- - -#### `set-flags` - -Set status flags associated with a descriptor. - -This function may only change the `non-blocking` flag. - -Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - -Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `flags`: [`descriptor-flags`](#descriptor_flags) -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `set-size` - -Adjust the size of an open file. If this increases the file's size, the -extra bytes are filled with zeros. - -Note: This was called `fd_filestat_set_size` in earlier versions of WASI. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `size`: [`filesize`](#filesize) -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `set-times` - -Adjust the timestamps of an open file or directory. - -Note: This is similar to `futimens` in POSIX. - -Note: This was called `fd_filestat_set_times` in earlier versions of WASI. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `data-access-timestamp`: [`new-timestamp`](#new_timestamp) -- `data-modification-timestamp`: [`new-timestamp`](#new_timestamp) -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `read` - -Read from a descriptor, without using and updating the descriptor's offset. - -This function returns a list of bytes containing the data that was -read, along with a bool which, when true, indicates that the end of the -file was reached. The returned list will contain up to `length` bytes; it -may return fewer than requested, if the end of the file is reached or -if the I/O operation is interrupted. - -Note: This is similar to `pread` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `length`: [`filesize`](#filesize) -- `offset`: [`filesize`](#filesize) -##### Results - -- `result0`: result<(list<`u8`>, `bool`), [`error-code`](#error_code)> - ----- - -#### `write` - -Write to a descriptor, without using and updating the descriptor's offset. - -It is valid to write past the end of a file; the file is extended to the -extent of the write, with bytes between the previous end and the start of -the write set to zero. - -Note: This is similar to `pwrite` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `buffer`: list<`u8`> -- `offset`: [`filesize`](#filesize) -##### Results - -- `result0`: result<[`filesize`](#filesize), [`error-code`](#error_code)> - ----- - -#### `read-directory` - -Read directory entries from a directory. - -On filesystems where directories contain entries referring to themselves -and their parents, often named `.` and `..` respectively, these entries -are omitted. - -This always returns a new stream which starts at the beginning of the -directory. Multiple streams may be active on the same directory, and they -do not interfere with each other. -##### Params - -- `this`: [`descriptor`](#descriptor) -##### Results - -- `result0`: result<[`directory-entry-stream`](#directory_entry_stream), [`error-code`](#error_code)> - ----- - -#### `sync` - -Synchronize the data and metadata of a file to disk. - -This function succeeds with no effect if the file descriptor is not -opened for writing. - -Note: This is similar to `fsync` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `create-directory-at` - -Create a directory. - -Note: This is similar to `mkdirat` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `path`: `string` -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `stat` - -Return the attributes of an open file or directory. - -Note: This is similar to `fstat` in POSIX. - -Note: This was called `fd_filestat_get` in earlier versions of WASI. -##### Params - -- `this`: [`descriptor`](#descriptor) -##### Results - -- `result0`: result<[`descriptor-stat`](#descriptor_stat), [`error-code`](#error_code)> - ----- - -#### `stat-at` - -Return the attributes of a file or directory. - -Note: This is similar to `fstatat` in POSIX. - -Note: This was called `path_filestat_get` in earlier versions of WASI. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `path-flags`: [`path-flags`](#path_flags) -- `path`: `string` -##### Results - -- `result0`: result<[`descriptor-stat`](#descriptor_stat), [`error-code`](#error_code)> - ----- - -#### `set-times-at` - -Adjust the timestamps of a file or directory. - -Note: This is similar to `utimensat` in POSIX. - -Note: This was called `path_filestat_set_times` in earlier versions of WASI. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `path-flags`: [`path-flags`](#path_flags) -- `path`: `string` -- `data-access-timestamp`: [`new-timestamp`](#new_timestamp) -- `data-modification-timestamp`: [`new-timestamp`](#new_timestamp) -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `link-at` - -Create a hard link. - -Note: This is similar to `linkat` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `old-path-flags`: [`path-flags`](#path_flags) -- `old-path`: `string` -- `new-descriptor`: [`descriptor`](#descriptor) -- `new-path`: `string` -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `open-at` - -Open a file or directory. - -The returned descriptor is not guaranteed to be the lowest-numbered -descriptor not currently open/ it is randomized to prevent applications -from depending on making assumptions about indexes, since this is -error-prone in multi-threaded contexts. The returned descriptor is -guaranteed to be less than 2**31. - -If `flags` contains `descriptor-flags::mutate-directory`, and the base -descriptor doesn't have `descriptor-flags::mutate-directory` set, -`open-at` fails with `error-code::read-only`. - -If `flags` contains `write` or `mutate-directory`, or `open-flags` -contains `truncate` or `create`, and the base descriptor doesn't have -`descriptor-flags::mutate-directory` set, `open-at` fails with -`error-code::read-only`. - -Note: This is similar to `openat` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `path-flags`: [`path-flags`](#path_flags) -- `path`: `string` -- `open-flags`: [`open-flags`](#open_flags) -- `flags`: [`descriptor-flags`](#descriptor_flags) -- `modes`: [`modes`](#modes) -##### Results - -- `result0`: result<[`descriptor`](#descriptor), [`error-code`](#error_code)> - ----- - -#### `readlink-at` - -Read the contents of a symbolic link. - -If the contents contain an absolute or rooted path in the underlying -filesystem, this function fails with `error-code::not-permitted`. - -Note: This is similar to `readlinkat` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `path`: `string` -##### Results - -- `result0`: result<`string`, [`error-code`](#error_code)> - ----- - -#### `remove-directory-at` - -Remove a directory. - -Return `error-code::not-empty` if the directory is not empty. - -Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `path`: `string` -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `rename-at` - -Rename a filesystem object. - -Note: This is similar to `renameat` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `old-path`: `string` -- `new-descriptor`: [`descriptor`](#descriptor) -- `new-path`: `string` -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `symlink-at` - -Create a symbolic link (also known as a "symlink"). - -If `old-path` starts with `/`, the function fails with `error-code::not-permitted`. - -Note: This is similar to `symlinkat` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `old-path`: `string` -- `new-path`: `string` -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `unlink-file-at` - -Unlink a filesystem object that is not a directory. - -Return `error-code::is-directory` if the path refers to a directory. -Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `path`: `string` -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `change-file-permissions-at` - -Change the permissions of a filesystem object that is not a directory. - -Note that the ultimate meanings of these permissions is -filesystem-specific. - -Note: This is similar to `fchmodat` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `path-flags`: [`path-flags`](#path_flags) -- `path`: `string` -- `modes`: [`modes`](#modes) -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `change-directory-permissions-at` - -Change the permissions of a directory. - -Note that the ultimate meanings of these permissions is -filesystem-specific. - -Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" -flag. `read` on a directory implies readability and searchability, and -`execute` is not valid for directories. - -Note: This is similar to `fchmodat` in POSIX. -##### Params - -- `this`: [`descriptor`](#descriptor) -- `path-flags`: [`path-flags`](#path_flags) -- `path`: `string` -- `modes`: [`modes`](#modes) -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `lock-shared` - -Request a shared advisory lock for an open file. - -This requests a *shared* lock; more than one shared lock can be held for -a file at the same time. - -If the open file has an exclusive lock, this function downgrades the lock -to a shared lock. If it has a shared lock, this function has no effect. - -This requests an *advisory* lock, meaning that the file could be accessed -by other programs that don't hold the lock. - -It is unspecified how shared locks interact with locks acquired by -non-WASI programs. - -This function blocks until the lock can be acquired. - -Not all filesystems support locking; on filesystems which don't support -locking, this function returns `error-code::unsupported`. - -Note: This is similar to `flock(fd, LOCK_SH)` in Unix. -##### Params - -- `this`: [`descriptor`](#descriptor) -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `lock-exclusive` - -Request an exclusive advisory lock for an open file. - -This requests an *exclusive* lock; no other locks may be held for the -file while an exclusive lock is held. - -If the open file has a shared lock and there are no exclusive locks held -for the file, this function upgrades the lock to an exclusive lock. If the -open file already has an exclusive lock, this function has no effect. - -This requests an *advisory* lock, meaning that the file could be accessed -by other programs that don't hold the lock. - -It is unspecified whether this function succeeds if the file descriptor -is not opened for writing. It is unspecified how exclusive locks interact -with locks acquired by non-WASI programs. - -This function blocks until the lock can be acquired. - -Not all filesystems support locking; on filesystems which don't support -locking, this function returns `error-code::unsupported`. - -Note: This is similar to `flock(fd, LOCK_EX)` in Unix. -##### Params - -- `this`: [`descriptor`](#descriptor) -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `try-lock-shared` - -Request a shared advisory lock for an open file. - -This requests a *shared* lock; more than one shared lock can be held for -a file at the same time. - -If the open file has an exclusive lock, this function downgrades the lock -to a shared lock. If it has a shared lock, this function has no effect. - -This requests an *advisory* lock, meaning that the file could be accessed -by other programs that don't hold the lock. - -It is unspecified how shared locks interact with locks acquired by -non-WASI programs. - -This function returns `error-code::would-block` if the lock cannot be acquired. - -Not all filesystems support locking; on filesystems which don't support -locking, this function returns `error-code::unsupported`. - -Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. -##### Params - -- `this`: [`descriptor`](#descriptor) -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `try-lock-exclusive` - -Request an exclusive advisory lock for an open file. - -This requests an *exclusive* lock; no other locks may be held for the -file while an exclusive lock is held. - -If the open file has a shared lock and there are no exclusive locks held -for the file, this function upgrades the lock to an exclusive lock. If the -open file already has an exclusive lock, this function has no effect. - -This requests an *advisory* lock, meaning that the file could be accessed -by other programs that don't hold the lock. - -It is unspecified whether this function succeeds if the file descriptor -is not opened for writing. It is unspecified how exclusive locks interact -with locks acquired by non-WASI programs. - -This function returns `error-code::would-block` if the lock cannot be acquired. - -Not all filesystems support locking; on filesystems which don't support -locking, this function returns `error-code::unsupported`. - -Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. -##### Params - -- `this`: [`descriptor`](#descriptor) -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `unlock` - -Release a shared or exclusive lock on an open file. - -Note: This is similar to `flock(fd, LOCK_UN)` in Unix. -##### Params - -- `this`: [`descriptor`](#descriptor) -##### Results - -- `result0`: result<_, [`error-code`](#error_code)> - ----- - -#### `drop-descriptor` - -Dispose of the specified `descriptor`, after which it may no longer -be used. -##### Params - -- `this`: [`descriptor`](#descriptor) - ----- - -#### `read-directory-entry` - -Read a single directory entry from a `directory-entry-stream`. -##### Params - -- `this`: [`directory-entry-stream`](#directory_entry_stream) -##### Results - -- `result0`: result, [`error-code`](#error_code)> - ----- - -#### `drop-directory-entry-stream` - -Dispose of the specified `directory-entry-stream`, after which it may no longer -be used. -##### Params - -- `this`: [`directory-entry-stream`](#directory_entry_stream) - diff --git a/proposals/filesystem/wit/deps/clocks/wall-clock.wit b/proposals/filesystem/wit/deps/clocks/wall-clock.wit new file mode 100644 index 000000000..c60861acd --- /dev/null +++ b/proposals/filesystem/wit/deps/clocks/wall-clock.wit @@ -0,0 +1,48 @@ +/// WASI Wall Clock is a clock API intended to let users query the current +/// time. The name "wall" makes an analogy to a "clock on the wall", which +/// is not necessarily monotonic as it may be reset. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface wall-clock { + /// A time and date in seconds plus nanoseconds. + record datetime { + seconds: u64, + nanoseconds: u32, + } + + /// A wall clock is a clock which measures the date and time according to + /// some external reference. + /// + /// External references may be reset, so this clock is not necessarily + /// monotonic, making it unsuitable for measuring elapsed time. + /// + /// It is intended for reporting the current date and time for humans. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type wall-clock = u32 + + /// Read the current value of the clock. + /// + /// This clock is not monotonic, therefore calling this function repeatedly + /// will not necessarily produce a sequence of non-decreasing values. + /// + /// The returned timestamps represent the number of seconds since + /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], + /// also known as [Unix Time]. + /// + /// The nanoseconds field of the output is always less than 1000000000. + /// + /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + now: func(this: wall-clock) -> datetime + + /// Query the resolution of the clock. + /// + /// The nanoseconds field of the output is always less than 1000000000. + resolution: func(this: wall-clock) -> datetime + + /// Dispose of the specified `wall-clock`, after which it may no longer + /// be used. + drop-wall-clock: func(this: wall-clock) +} diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit new file mode 100644 index 000000000..351006598 --- /dev/null +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -0,0 +1,134 @@ +/// WASI I/O is an I/O abstraction API which is currently focused on providing +/// stream types. +/// +/// In the future, the component model is expected to add built-in stream types; +/// when it does, they are expected to subsume this API. +default interface streams { + use poll.poll.{pollable} + + /// An error type returned from a stream operation. Currently this + /// doesn't provide any additional information. + record stream-error {} + + /// An input bytestream. In the future, this will be replaced by handle + /// types. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type input-stream = u32 + + /// Read bytes from a stream. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a bool indicating whether the end of the stream + /// was reached. The returned list will contain up to `len` bytes; it + /// may return fewer than requested, but not more. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// If `len` is 0, it represents a request to read 0 bytes, which should + /// always succeed, assuming the stream hasn't reached its end yet, and + /// return an empty list. + /// + /// The len here is a `u64`, but some callees may not be able to allocate + /// a buffer as large as that would imply. + /// FIXME: describe what happens if allocation fails. + read: func( + this: input-stream, + /// The maximum number of bytes to read + len: u64 + ) -> result, bool>, stream-error> + + /// Skip bytes from a stream. + /// + /// This is similar to the `read` function, but avoids copying the + /// bytes into the instance. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// This function returns the number of bytes skipped, along with a bool + /// indicating whether the end of the stream was reached. The returned + /// value will be at most `len`; it may be less. + skip: func( + this: input-stream, + /// The maximum number of bytes to skip. + len: u64, + ) -> result, stream-error> + + /// Create a `pollable` which will resolve once either the specified stream + /// has bytes available to read or the other end of the stream has been + /// closed. + subscribe-to-input-stream: func(this: input-stream) -> pollable + + /// Dispose of the specified `input-stream`, after which it may no longer + /// be used. + drop-input-stream: func(this: input-stream) + + /// An output bytestream. In the future, this will be replaced by handle + /// types. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type output-stream = u32 + + /// Write bytes to a stream. + /// + /// This function returns a `u64` indicating the number of bytes from + /// `buf` that were written; it may be less than the full list. + write: func( + this: output-stream, + /// Data to write + buf: list + ) -> result + + /// Write multiple zero bytes to a stream. + /// + /// This function returns a `u64` indicating the number of zero bytes + /// that were written; it may be less than `len`. + write-zeroes: func( + this: output-stream, + /// The number of zero bytes to write + len: u64 + ) -> result + + /// Read from one stream and write to another. + /// + /// This function returns the number of bytes transferred; it may be less + /// than `len`. + splice: func( + this: output-stream, + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result, stream-error> + + /// Forward the entire contents of an input stream to an output stream. + /// + /// This function repeatedly reads from the input stream and writes + /// the data to the output stream, until the end of the input stream + /// is reached, or an error is encountered. + /// + /// This function returns the number of bytes transferred. + forward: func( + this: output-stream, + /// The stream to read from + src: input-stream + ) -> result + + /// Create a `pollable` which will resolve once either the specified stream + /// is ready to accept bytes or the other end of the stream has been closed. + subscribe-to-output-stream: func(this: output-stream) -> pollable + + /// Dispose of the specified `output-stream`, after which it may no longer + /// be used. + drop-output-stream: func(this: output-stream) +} diff --git a/proposals/filesystem/wit/deps/poll/poll.wit b/proposals/filesystem/wit/deps/poll/poll.wit new file mode 100644 index 000000000..28f08e17d --- /dev/null +++ b/proposals/filesystem/wit/deps/poll/poll.wit @@ -0,0 +1,39 @@ +/// A poll API intended to let users wait for I/O events on multiple handles +/// at once. +default interface poll { + /// A "pollable" handle. + /// + /// This is conceptually represents a `stream<_, _>`, or in other words, + /// a stream that one can wait on, repeatedly, but which does not itself + /// produce any data. It's temporary scaffolding until component-model's + /// async features are ready. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// `pollable` lifetimes are not automatically managed. Users must ensure + /// that they do not outlive the resource they reference. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type pollable = u32 + + /// Dispose of the specified `pollable`, after which it may no longer + /// be used. + drop-pollable: func(this: pollable) + + /// Poll for completion on a set of pollables. + /// + /// The "oneoff" in the name refers to the fact that this function must do a + /// linear scan through the entire list of subscriptions, which may be + /// inefficient if the number is large and the same subscriptions are used + /// many times. In the future, this is expected to be obsoleted by the + /// component model async proposal, which will include a scalable waiting + /// facility. + /// + /// Note that the return type would ideally be `list`, but that would + /// be more difficult to polyfill given the current state of `wit-bindgen`. + /// See + /// for details. For now, we use zero to mean "not ready" and non-zero to + /// mean "ready". + poll-oneoff: func(in: list) -> list +} diff --git a/proposals/filesystem/wit/deps/wit b/proposals/filesystem/wit/deps/wit new file mode 100644 index 000000000..351006598 --- /dev/null +++ b/proposals/filesystem/wit/deps/wit @@ -0,0 +1,134 @@ +/// WASI I/O is an I/O abstraction API which is currently focused on providing +/// stream types. +/// +/// In the future, the component model is expected to add built-in stream types; +/// when it does, they are expected to subsume this API. +default interface streams { + use poll.poll.{pollable} + + /// An error type returned from a stream operation. Currently this + /// doesn't provide any additional information. + record stream-error {} + + /// An input bytestream. In the future, this will be replaced by handle + /// types. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type input-stream = u32 + + /// Read bytes from a stream. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a bool indicating whether the end of the stream + /// was reached. The returned list will contain up to `len` bytes; it + /// may return fewer than requested, but not more. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// If `len` is 0, it represents a request to read 0 bytes, which should + /// always succeed, assuming the stream hasn't reached its end yet, and + /// return an empty list. + /// + /// The len here is a `u64`, but some callees may not be able to allocate + /// a buffer as large as that would imply. + /// FIXME: describe what happens if allocation fails. + read: func( + this: input-stream, + /// The maximum number of bytes to read + len: u64 + ) -> result, bool>, stream-error> + + /// Skip bytes from a stream. + /// + /// This is similar to the `read` function, but avoids copying the + /// bytes into the instance. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// This function returns the number of bytes skipped, along with a bool + /// indicating whether the end of the stream was reached. The returned + /// value will be at most `len`; it may be less. + skip: func( + this: input-stream, + /// The maximum number of bytes to skip. + len: u64, + ) -> result, stream-error> + + /// Create a `pollable` which will resolve once either the specified stream + /// has bytes available to read or the other end of the stream has been + /// closed. + subscribe-to-input-stream: func(this: input-stream) -> pollable + + /// Dispose of the specified `input-stream`, after which it may no longer + /// be used. + drop-input-stream: func(this: input-stream) + + /// An output bytestream. In the future, this will be replaced by handle + /// types. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type output-stream = u32 + + /// Write bytes to a stream. + /// + /// This function returns a `u64` indicating the number of bytes from + /// `buf` that were written; it may be less than the full list. + write: func( + this: output-stream, + /// Data to write + buf: list + ) -> result + + /// Write multiple zero bytes to a stream. + /// + /// This function returns a `u64` indicating the number of zero bytes + /// that were written; it may be less than `len`. + write-zeroes: func( + this: output-stream, + /// The number of zero bytes to write + len: u64 + ) -> result + + /// Read from one stream and write to another. + /// + /// This function returns the number of bytes transferred; it may be less + /// than `len`. + splice: func( + this: output-stream, + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result, stream-error> + + /// Forward the entire contents of an input stream to an output stream. + /// + /// This function repeatedly reads from the input stream and writes + /// the data to the output stream, until the end of the input stream + /// is reached, or an error is encountered. + /// + /// This function returns the number of bytes transferred. + forward: func( + this: output-stream, + /// The stream to read from + src: input-stream + ) -> result + + /// Create a `pollable` which will resolve once either the specified stream + /// is ready to accept bytes or the other end of the stream has been closed. + subscribe-to-output-stream: func(this: output-stream) -> pollable + + /// Dispose of the specified `output-stream`, after which it may no longer + /// be used. + drop-output-stream: func(this: output-stream) +} diff --git a/proposals/filesystem/wit/filesystem.wit b/proposals/filesystem/wit/filesystem.wit new file mode 100644 index 000000000..08c7bff4d --- /dev/null +++ b/proposals/filesystem/wit/filesystem.wit @@ -0,0 +1,770 @@ +/// WASI filesystem is a filesystem API primarily intended to let users run WASI +/// programs that access their files on their existing filesystems, without +/// significant overhead. +/// +/// It is intended to be roughly portable between Unix-family platforms and +/// Windows, though it does not hide many of the major differences. +/// +/// Paths are passed as interface-type `string`s, meaning they must consist of +/// a sequence of Unicode Scalar Values (USVs). Some filesystems may contain +/// paths which are not accessible by this API. +/// +/// The directory separator in WASI is always the forward-slash (`/`). +/// +/// All paths in WASI are relative paths, and are interpreted relative to a +/// `descriptor` referring to a base directory. If a `path` argument to any WASI +/// function starts with `/`, or if any step of resolving a `path`, including +/// `..` and symbolic link steps, reaches a directory outside of the base +/// directory, or reaches a symlink to an absolute or rooted path in the +/// underlying filesystem, the function fails with `error-code::not-permitted`. +default interface wasi-filesystem { + use io.streams.{input-stream, output-stream} + use clocks.wall-clock.{datetime} + + /// File size or length of a region within a file. + type filesize = u64 + + /// The type of a filesystem object referenced by a descriptor. + /// + /// Note: This was called `filetype` in earlier versions of WASI. + enum descriptor-type { + /// The type of the descriptor or file is unknown or is different from + /// any of the other types specified. + unknown, + /// The descriptor refers to a block device inode. + block-device, + /// The descriptor refers to a character device inode. + character-device, + /// The descriptor refers to a directory inode. + directory, + /// The descriptor refers to a named pipe. + fifo, + /// The file refers to a symbolic link inode. + symbolic-link, + /// The descriptor refers to a regular file inode. + regular-file, + /// The descriptor refers to a socket. + socket, + } + + /// Descriptor flags. + /// + /// Note: This was called `fdflags` in earlier versions of WASI. + flags descriptor-flags { + /// Read mode: Data can be read. + read, + /// Write mode: Data can be written to. + write, + /// Requests non-blocking operation. + /// + /// When this flag is enabled, functions may return immediately with an + /// `error-code::would-block` error code in situations where they would + /// otherwise block. However, this non-blocking behavior is not + /// required. Implementations are permitted to ignore this flag and + /// block. This is similar to `O_NONBLOCK` in POSIX. + non-blocking, + /// Request that writes be performed according to synchronized I/O file + /// integrity completion. The data stored in the file and the file's + /// metadata are synchronized. This is similar to `O_SYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + file-integrity-sync, + /// Request that writes be performed according to synchronized I/O data + /// integrity completion. Only the data stored in the file is + /// synchronized. This is similar to `O_DSYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + data-integrity-sync, + /// Requests that reads be performed at the same level of integrety + /// requested for writes. This is similar to `O_RSYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + requested-write-sync, + /// Mutating directories mode: Directory contents may be mutated. + /// + /// When this flag is unset on a descriptor, operations using the + /// descriptor which would create, rename, delete, modify the data or + /// metadata of filesystem objects, or obtain another handle which + /// would permit any of those, shall fail with `error-code::read-only` if + /// they would otherwise succeed. + /// + /// This may only be set on directories. + mutate-directory, + } + + /// File attributes. + /// + /// Note: This was called `filestat` in earlier versions of WASI. + record descriptor-stat { + /// Device ID of device containing the file. + device: device, + /// File serial number. + inode: inode, + /// File type. + %type: descriptor-type, + /// Number of hard links to the file. + link-count: link-count, + /// For regular files, the file size in bytes. For symbolic links, the + /// length in bytes of the pathname contained in the symbolic link. + size: filesize, + /// Last data access timestamp. + data-access-timestamp: datetime, + /// Last data modification timestamp. + data-modification-timestamp: datetime, + /// Last file status change timestamp. + status-change-timestamp: datetime, + } + + /// Flags determining the method of how paths are resolved. + flags path-flags { + /// As long as the resolved path corresponds to a symbolic link, it is + /// expanded. + symlink-follow, + } + + /// Open flags used by `open-at`. + flags open-flags { + /// Create file if it does not exist, similar to `O_CREAT` in POSIX. + create, + /// Fail if not a directory, similar to `O_DIRECTORY` in POSIX. + directory, + /// Fail if file already exists, similar to `O_EXCL` in POSIX. + exclusive, + /// Truncate file to size 0, similar to `O_TRUNC` in POSIX. + truncate, + } + + /// Permissions mode used by `open-at`, `change-file-permissions-at`, and + /// similar. + flags modes { + /// True if the resource is considered readable by the containing + /// filesystem. + readable, + /// True if the resource is considered writeable by the containing + /// filesystem. + writeable, + /// True if the resource is considered executable by the containing + /// filesystem. This does not apply to directories. + executable, + } + + /// Number of hard links to an inode. + type link-count = u64 + + /// Identifier for a device containing a file system. Can be used in + /// combination with `inode` to uniquely identify a file or directory in + /// the filesystem. + type device = u64 + + /// Filesystem object serial number that is unique within its file system. + type inode = u64 + + /// When setting a timestamp, this gives the value to set it to. + variant new-timestamp { + /// Leave the timestamp set to its previous value. + no-change, + /// Set the timestamp to the current time of the system clock associated + /// with the filesystem. + now, + /// Set the timestamp to the given value. + timestamp(datetime), + } + + /// A directory entry. + record directory-entry { + /// The serial number of the object referred to by this directory entry. + /// May be none if the inode value is not known. + /// + /// When this is none, libc implementations might do an extra `stat-at` + /// call to retrieve the inode number to fill their `d_ino` fields, so + /// implementations which can set this to a non-none value should do so. + inode: option, + + /// The type of the file referred to by this directory entry. + %type: descriptor-type, + + /// The name of the object. + name: string, + } + + /// Error codes returned by functions, similar to `errno` in POSIX. + /// Not all of these error codes are returned by the functions provided by this + /// API; some are used in higher-level library layers, and others are provided + /// merely for alignment with POSIX. + enum error-code { + /// Permission denied, similar to `EACCES` in POSIX. + access, + /// Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. + would-block, + /// Connection already in progress, similar to `EALREADY` in POSIX. + already, + /// Bad descriptor, similar to `EBADF` in POSIX. + bad-descriptor, + /// Device or resource busy, similar to `EBUSY` in POSIX. + busy, + /// Resource deadlock would occur, similar to `EDEADLK` in POSIX. + deadlock, + /// Storage quota exceeded, similar to `EDQUOT` in POSIX. + quota, + /// File exists, similar to `EEXIST` in POSIX. + exist, + /// File too large, similar to `EFBIG` in POSIX. + file-too-large, + /// Illegal byte sequence, similar to `EILSEQ` in POSIX. + illegal-byte-sequence, + /// Operation in progress, similar to `EINPROGRESS` in POSIX. + in-progress, + /// Interrupted function, similar to `EINTR` in POSIX. + interrupted, + /// Invalid argument, similar to `EINVAL` in POSIX. + invalid, + /// I/O error, similar to `EIO` in POSIX. + io, + /// Is a directory, similar to `EISDIR` in POSIX. + is-directory, + /// Too many levels of symbolic links, similar to `ELOOP` in POSIX. + loop, + /// Too many links, similar to `EMLINK` in POSIX. + too-many-links, + /// Message too large, similar to `EMSGSIZE` in POSIX. + message-size, + /// Filename too long, similar to `ENAMETOOLONG` in POSIX. + name-too-long, + /// No such device, similar to `ENODEV` in POSIX. + no-device, + /// No such file or directory, similar to `ENOENT` in POSIX. + no-entry, + /// No locks available, similar to `ENOLCK` in POSIX. + no-lock, + /// Not enough space, similar to `ENOMEM` in POSIX. + insufficient-memory, + /// No space left on device, similar to `ENOSPC` in POSIX. + insufficient-space, + /// Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. + not-directory, + /// Directory not empty, similar to `ENOTEMPTY` in POSIX. + not-empty, + /// State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. + not-recoverable, + /// Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. + unsupported, + /// Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. + no-tty, + /// No such device or address, similar to `ENXIO` in POSIX. + no-such-device, + /// Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. + overflow, + /// Operation not permitted, similar to `EPERM` in POSIX. + not-permitted, + /// Broken pipe, similar to `EPIPE` in POSIX. + pipe, + /// Read-only file system, similar to `EROFS` in POSIX. + read-only, + /// Invalid seek, similar to `ESPIPE` in POSIX. + invalid-seek, + /// Text file busy, similar to `ETXTBSY` in POSIX. + text-file-busy, + /// Cross-device link, similar to `EXDEV` in POSIX. + cross-device, + } + + /// File or memory access pattern advisory information. + enum advice { + /// The application has no advice to give on its behavior with respect + /// to the specified data. + normal, + /// The application expects to access the specified data sequentially + /// from lower offsets to higher offsets. + sequential, + /// The application expects to access the specified data in a random + /// order. + random, + /// The application expects to access the specified data in the near + /// future. + will-need, + /// The application expects that it will not access the specified data + /// in the near future. + dont-need, + /// The application expects to access the specified data once and then + /// not reuse it thereafter. + no-reuse, + } + + /// A descriptor is a reference to a filesystem object, which may be a file, + /// directory, named pipe, special file, or other object on which filesystem + /// calls may be made. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type descriptor = u32 + + /// Return a stream for reading from a file. + /// + /// Multiple read, write, and append streams may be active on the same open + /// file and they do not interfere with each other. + /// + /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. + read-via-stream: func( + this: descriptor, + /// The offset within the file at which to start reading. + offset: filesize, + ) -> result + + /// Return a stream for writing to a file. + /// + /// Note: This allows using `write-stream`, which is similar to `write` in + /// POSIX. + write-via-stream: func( + this: descriptor, + /// The offset within the file at which to start writing. + offset: filesize, + ) -> result + + /// Return a stream for appending to a file. + /// + /// Note: This allows using `write-stream`, which is similar to `write` with + /// `O_APPEND` in in POSIX. + append-via-stream: func( + this: descriptor, + /// The resource to operate on. + fd: descriptor, + ) -> result + + /// Provide file advisory information on a descriptor. + /// + /// This is similar to `posix_fadvise` in POSIX. + advise: func( + this: descriptor, + /// The offset within the file to which the advisory applies. + offset: filesize, + /// The length of the region to which the advisory applies. + length: filesize, + /// The advice. + advice: advice + ) -> result<_, error-code> + + /// Synchronize the data of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fdatasync` in POSIX. + sync-data: func(this: descriptor) -> result<_, error-code> + + /// Get flags associated with a descriptor. + /// + /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. + /// + /// Note: This returns the value that was the `fs_flags` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-flags: func(this: descriptor) -> result + + /// Get the dynamic type of a descriptor. + /// + /// Note: This returns the same value as the `type` field of the `fd-stat` + /// returned by `stat`, `stat-at` and similar. + /// + /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided + /// by `fstat` in POSIX. + /// + /// Note: This returns the value that was the `fs_filetype` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-type: func(this: descriptor) -> result + + /// Set status flags associated with a descriptor. + /// + /// This function may only change the `non-blocking` flag. + /// + /// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + /// + /// Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. + set-flags: func(this: descriptor, %flags: descriptor-flags) -> result<_, error-code> + + /// Adjust the size of an open file. If this increases the file's size, the + /// extra bytes are filled with zeros. + /// + /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. + set-size: func(this: descriptor, size: filesize) -> result<_, error-code> + + /// Adjust the timestamps of an open file or directory. + /// + /// Note: This is similar to `futimens` in POSIX. + /// + /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. + set-times: func( + this: descriptor, + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code> + + /// Read from a descriptor, without using and updating the descriptor's offset. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a bool which, when true, indicates that the end of the + /// file was reached. The returned list will contain up to `length` bytes; it + /// may return fewer than requested, if the end of the file is reached or + /// if the I/O operation is interrupted. + /// + /// In the future, this may change to return a `stream`. + /// + /// Note: This is similar to `pread` in POSIX. + read: func( + this: descriptor, + /// The maximum number of bytes to read. + length: filesize, + /// The offset within the file at which to read. + offset: filesize, + ) -> result, bool>, error-code> + + /// Write to a descriptor, without using and updating the descriptor's offset. + /// + /// It is valid to write past the end of a file; the file is extended to the + /// extent of the write, with bytes between the previous end and the start of + /// the write set to zero. + /// + /// In the future, this may change to take a `stream`. + /// + /// Note: This is similar to `pwrite` in POSIX. + write: func( + this: descriptor, + /// Data to write + buffer: list, + /// The offset within the file at which to write. + offset: filesize, + ) -> result + + /// Read directory entries from a directory. + /// + /// On filesystems where directories contain entries referring to themselves + /// and their parents, often named `.` and `..` respectively, these entries + /// are omitted. + /// + /// This always returns a new stream which starts at the beginning of the + /// directory. Multiple streams may be active on the same directory, and they + /// do not interfere with each other. + read-directory: func( + this: descriptor + ) -> result + + /// Synchronize the data and metadata of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fsync` in POSIX. + sync: func(this: descriptor) -> result<_, error-code> + + /// Create a directory. + /// + /// Note: This is similar to `mkdirat` in POSIX. + create-directory-at: func( + this: descriptor, + /// The relative path at which to create the directory. + path: string, + ) -> result<_, error-code> + + /// Return the attributes of an open file or directory. + /// + /// Note: This is similar to `fstat` in POSIX. + /// + /// Note: This was called `fd_filestat_get` in earlier versions of WASI. + stat: func(this: descriptor) -> result + + /// Return the attributes of a file or directory. + /// + /// Note: This is similar to `fstatat` in POSIX. + /// + /// Note: This was called `path_filestat_get` in earlier versions of WASI. + stat-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result + + /// Adjust the timestamps of a file or directory. + /// + /// Note: This is similar to `utimensat` in POSIX. + /// + /// Note: This was called `path_filestat_set_times` in earlier versions of + /// WASI. + set-times-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to operate on. + path: string, + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code> + + /// Create a hard link. + /// + /// Note: This is similar to `linkat` in POSIX. + link-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + old-path-flags: path-flags, + /// The relative source path from which to link. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: descriptor, + /// The relative destination path at which to create the hard link. + new-path: string, + ) -> result<_, error-code> + + /// Open a file or directory. + /// + /// The returned descriptor is not guaranteed to be the lowest-numbered + /// descriptor not currently open/ it is randomized to prevent applications + /// from depending on making assumptions about indexes, since this is + /// error-prone in multi-threaded contexts. The returned descriptor is + /// guaranteed to be less than 2**31. + /// + /// If `flags` contains `descriptor-flags::mutate-directory`, and the base + /// descriptor doesn't have `descriptor-flags::mutate-directory` set, + /// `open-at` fails with `error-code::read-only`. + /// + /// If `flags` contains `write` or `mutate-directory`, or `open-flags` + /// contains `truncate` or `create`, and the base descriptor doesn't have + /// `descriptor-flags::mutate-directory` set, `open-at` fails with + /// `error-code::read-only`. + /// + /// Note: This is similar to `openat` in POSIX. + open-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the object to open. + path: string, + /// The method by which to open the file. + open-flags: open-flags, + /// Flags to use for the resulting descriptor. + %flags: descriptor-flags, + /// Permissions to use when creating a new file. + modes: modes + ) -> result + + /// Read the contents of a symbolic link. + /// + /// If the contents contain an absolute or rooted path in the underlying + /// filesystem, this function fails with `error-code::not-permitted`. + /// + /// Note: This is similar to `readlinkat` in POSIX. + readlink-at: func( + this: descriptor, + /// The relative path of the symbolic link from which to read. + path: string, + ) -> result + + /// Remove a directory. + /// + /// Return `error-code::not-empty` if the directory is not empty. + /// + /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + remove-directory-at: func( + this: descriptor, + /// The relative path to a directory to remove. + path: string, + ) -> result<_, error-code> + + /// Rename a filesystem object. + /// + /// Note: This is similar to `renameat` in POSIX. + rename-at: func( + this: descriptor, + /// The relative source path of the file or directory to rename. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: descriptor, + /// The relative destination path to which to rename the file or directory. + new-path: string, + ) -> result<_, error-code> + + /// Create a symbolic link (also known as a "symlink"). + /// + /// If `old-path` starts with `/`, the function fails with + /// `error-code::not-permitted`. + /// + /// Note: This is similar to `symlinkat` in POSIX. + symlink-at: func( + this: descriptor, + /// The contents of the symbolic link. + old-path: string, + /// The relative destination path at which to create the symbolic link. + new-path: string, + ) -> result<_, error-code> + + /// Unlink a filesystem object that is not a directory. + /// + /// Return `error-code::is-directory` if the path refers to a directory. + /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + unlink-file-at: func( + this: descriptor, + /// The relative path to a file to unlink. + path: string, + ) -> result<_, error-code> + + /// Change the permissions of a filesystem object that is not a directory. + /// + /// Note that the ultimate meanings of these permissions is + /// filesystem-specific. + /// + /// Note: This is similar to `fchmodat` in POSIX. + change-file-permissions-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to operate on. + path: string, + /// The new permissions for the filesystem object. + modes: modes, + ) -> result<_, error-code> + + /// Change the permissions of a directory. + /// + /// Note that the ultimate meanings of these permissions is + /// filesystem-specific. + /// + /// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" + /// flag. `read` on a directory implies readability and searchability, and + /// `execute` is not valid for directories. + /// + /// Note: This is similar to `fchmodat` in POSIX. + change-directory-permissions-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to operate on. + path: string, + /// The new permissions for the directory. + modes: modes, + ) -> result<_, error-code> + + /// Request a shared advisory lock for an open file. + /// + /// This requests a *shared* lock; more than one shared lock can be held for + /// a file at the same time. + /// + /// If the open file has an exclusive lock, this function downgrades the lock + /// to a shared lock. If it has a shared lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified how shared locks interact with locks acquired by + /// non-WASI programs. + /// + /// This function blocks until the lock can be acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. + lock-shared: func(this: descriptor) -> result<_, error-code> + + /// Request an exclusive advisory lock for an open file. + /// + /// This requests an *exclusive* lock; no other locks may be held for the + /// file while an exclusive lock is held. + /// + /// If the open file has a shared lock and there are no exclusive locks held + /// for the file, this function upgrades the lock to an exclusive lock. If the + /// open file already has an exclusive lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified whether this function succeeds if the file descriptor + /// is not opened for writing. It is unspecified how exclusive locks interact + /// with locks acquired by non-WASI programs. + /// + /// This function blocks until the lock can be acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. + lock-exclusive: func(this: descriptor) -> result<_, error-code> + + /// Request a shared advisory lock for an open file. + /// + /// This requests a *shared* lock; more than one shared lock can be held for + /// a file at the same time. + /// + /// If the open file has an exclusive lock, this function downgrades the lock + /// to a shared lock. If it has a shared lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified how shared locks interact with locks acquired by + /// non-WASI programs. + /// + /// This function returns `error-code::would-block` if the lock cannot be + /// acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. + try-lock-shared: func(this: descriptor) -> result<_, error-code> + + /// Request an exclusive advisory lock for an open file. + /// + /// This requests an *exclusive* lock; no other locks may be held for the + /// file while an exclusive lock is held. + /// + /// If the open file has a shared lock and there are no exclusive locks held + /// for the file, this function upgrades the lock to an exclusive lock. If the + /// open file already has an exclusive lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified whether this function succeeds if the file descriptor + /// is not opened for writing. It is unspecified how exclusive locks interact + /// with locks acquired by non-WASI programs. + /// + /// This function returns `error-code::would-block` if the lock cannot be + /// acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. + try-lock-exclusive: func(this: descriptor) -> result<_, error-code> + + /// Release a shared or exclusive lock on an open file. + /// + /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. + unlock: func(this: descriptor) -> result<_, error-code> + + /// Dispose of the specified `descriptor`, after which it may no longer + /// be used. + drop-descriptor: func(this: descriptor) + + /// A stream of directory entries. + /// + /// This [represents a stream of `dir-entry`](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Streams). + type directory-entry-stream = u32 + + /// Read a single directory entry from a `directory-entry-stream`. + read-directory-entry: func( + this: directory-entry-stream + ) -> result, error-code> + + /// Dispose of the specified `directory-entry-stream`, after which it may no longer + /// be used. + drop-directory-entry-stream: func(this: directory-entry-stream) +} diff --git a/proposals/filesystem/wit/wasi-filesystem.wit.md b/proposals/filesystem/wit/wasi-filesystem.wit.md deleted file mode 100644 index e9c84ae60..000000000 --- a/proposals/filesystem/wit/wasi-filesystem.wit.md +++ /dev/null @@ -1,917 +0,0 @@ -# WASI Filesystem API - -## `wasi-filesystem` -```wit -/// WASI filesystem is a filesystem API primarily intended to let users run WASI -/// programs that access their files on their existing filesystems, without -/// significant overhead. -/// -/// It is intended to be roughly portable between Unix-family platforms and -/// Windows, though it does not hide many of the major differences. -/// -/// Paths are passed as interface-type `string`s, meaning they must consist of -/// a sequence of Unicode Scalar Values (USVs). Some filesystems may contain paths -/// which are not accessible by this API. -/// -/// The directory separator in WASI is always the forward-slash (`/`). -/// -/// All paths in WASI are relative paths, and are interpreted relative to a -/// `descriptor` referring to a base directory. If a `path` argument to any WASI -/// function starts with `/`, or if any step of resolving a `path`, including -/// `..` and symbolic link steps, reaches a directory outside of the base -/// directory, or reaches a symlink to an absolute or rooted path in the -/// underlying filesystem, the function fails with `error-code::not-permitted`. -default interface wasi-filesystem { -``` - -# Imports -```wit -use pkg.wasi-io.{input-stream, output-stream} -use pkg.wasi-wall-clock.{datetime} -``` - -## `filesize` -```wit -/// File size or length of a region within a file. -type filesize = u64 -``` - -## `descriptor-type` -```wit -/// The type of a filesystem object referenced by a descriptor. -/// -/// Note: This was called `filetype` in earlier versions of WASI. -enum descriptor-type { - /// The type of the descriptor or file is unknown or is different from - /// any of the other types specified. - unknown, - /// The descriptor refers to a block device inode. - block-device, - /// The descriptor refers to a character device inode. - character-device, - /// The descriptor refers to a directory inode. - directory, - /// The descriptor refers to a named pipe. - fifo, - /// The file refers to a symbolic link inode. - symbolic-link, - /// The descriptor refers to a regular file inode. - regular-file, - /// The descriptor refers to a socket. - socket, -} -``` - -## `descriptor-flags` -```wit -/// Descriptor flags. -/// -/// Note: This was called `fdflags` in earlier versions of WASI. -flags descriptor-flags { - /// Read mode: Data can be read. - read, - /// Write mode: Data can be written to. - write, - /// Requests non-blocking operation. - /// - /// When this flag is enabled, functions may return immediately with an - /// `error-code::would-block` error code in situations where they would otherwise - /// block. However, this non-blocking behavior is not required. - /// Implementations are permitted to ignore this flag and block. - /// This is similar to `O_NONBLOCK` in POSIX. - non-blocking, - /// Request that writes be performed according to synchronized I/O file - /// integrity completion. The data stored in the file and the file's - /// metadata are synchronized. This is similar to `O_SYNC` in POSIX. - /// - /// The precise semantics of this operation have not yet been defined for - /// WASI. At this time, it should be interpreted as a request, and not a - /// requirement. - file-integrity-sync, - /// Request that writes be performed according to synchronized I/O data - /// integrity completion. Only the data stored in the file is - /// synchronized. This is similar to `O_DSYNC` in POSIX. - /// - /// The precise semantics of this operation have not yet been defined for - /// WASI. At this time, it should be interpreted as a request, and not a - /// requirement. - data-integrity-sync, - /// Requests that reads be performed at the same level of integrety - /// requested for writes. This is similar to `O_RSYNC` in POSIX. - /// - /// The precise semantics of this operation have not yet been defined for - /// WASI. At this time, it should be interpreted as a request, and not a - /// requirement. - requested-write-sync, - /// Mutating directories mode: Directory contents may be mutated. - /// - /// When this flag is unset on a descriptor, operations using the - /// descriptor which would create, rename, delete, modify the data or - /// metadata of filesystem objects, or obtain another handle which - /// would permit any of those, shall fail with `error-code::read-only` if - /// they would otherwise succeed. - /// - /// This may only be set on directories. - mutate-directory, -} -``` - -## `descriptor-stat` -```wit -/// File attributes. -/// -/// Note: This was called `filestat` in earlier versions of WASI. -record descriptor-stat { - /// Device ID of device containing the file. - device: device, - /// File serial number. - inode: inode, - /// File type. - %type: descriptor-type, - /// Number of hard links to the file. - link-count: link-count, - /// For regular files, the file size in bytes. For symbolic links, the length - /// in bytes of the pathname contained in the symbolic link. - size: filesize, - /// Last data access timestamp. - data-access-timestamp: datetime, - /// Last data modification timestamp. - data-modification-timestamp: datetime, - /// Last file status change timestamp. - status-change-timestamp: datetime, -} -``` - -## `path-flags` -```wit -/// Flags determining the method of how paths are resolved. -flags path-flags { - /// As long as the resolved path corresponds to a symbolic link, it is expanded. - symlink-follow, -} -``` - -## `open-flags` -```wit -/// Open flags used by `open-at`. -flags open-flags { - /// Create file if it does not exist, similar to `O_CREAT` in POSIX. - create, - /// Fail if not a directory, similar to `O_DIRECTORY` in POSIX. - directory, - /// Fail if file already exists, similar to `O_EXCL` in POSIX. - exclusive, - /// Truncate file to size 0, similar to `O_TRUNC` in POSIX. - truncate, -} -``` - -## `modes` -```wit -/// Permissions mode used by `open-at`, `change-file-permissions-at`, and -/// similar. -flags modes { - /// True if the resource is considered readable by the containing - /// filesystem. - readable, - /// True if the resource is considered writeable by the containing - /// filesystem. - writeable, - /// True if the resource is considered executable by the containing - /// filesystem. This does not apply to directories. - executable, -} -``` - -## `link-count` -```wit -/// Number of hard links to an inode. -type link-count = u64 -``` - -## `device` -```wit -/// Identifier for a device containing a file system. Can be used in combination -/// with `inode` to uniquely identify a file or directory in the filesystem. -type device = u64 -``` - -## `inode` -```wit -/// Filesystem object serial number that is unique within its file system. -type inode = u64 -``` - -## `new-timestamp` -```wit -/// When setting a timestamp, this gives the value to set it to. -variant new-timestamp { - /// Leave the timestamp set to its previous value. - no-change, - /// Set the timestamp to the current time of the system clock associated - /// with the filesystem. - now, - /// Set the timestamp to the given value. - timestamp(datetime), -} -``` - -## `directory-entry` -```wit -/// A directory entry. -record directory-entry { - /// The serial number of the object referred to by this directory entry. - /// May be none if the inode value is not known. - /// - /// When this is none, libc implementations might do an extra `stat-at` - /// call to retrieve the inode number to fill their `d_ino` fields, so - /// implementations which can set this to a non-none value should do so. - inode: option, - - /// The type of the file referred to by this directory entry. - %type: descriptor-type, - - /// The name of the object. - name: string, -} -``` - -## `error-code` -```wit -/// Error codes returned by functions, similar to `errno` in POSIX. -/// Not all of these error codes are returned by the functions provided by this -/// API; some are used in higher-level library layers, and others are provided -/// merely for alignment with POSIX. -enum error-code { - /// Permission denied, similar to `EACCES` in POSIX. - access, - /// Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. - would-block, - /// Connection already in progress, similar to `EALREADY` in POSIX. - already, - /// Bad descriptor, similar to `EBADF` in POSIX. - bad-descriptor, - /// Device or resource busy, similar to `EBUSY` in POSIX. - busy, - /// Resource deadlock would occur, similar to `EDEADLK` in POSIX. - deadlock, - /// Storage quota exceeded, similar to `EDQUOT` in POSIX. - quota, - /// File exists, similar to `EEXIST` in POSIX. - exist, - /// File too large, similar to `EFBIG` in POSIX. - file-too-large, - /// Illegal byte sequence, similar to `EILSEQ` in POSIX. - illegal-byte-sequence, - /// Operation in progress, similar to `EINPROGRESS` in POSIX. - in-progress, - /// Interrupted function, similar to `EINTR` in POSIX. - interrupted, - /// Invalid argument, similar to `EINVAL` in POSIX. - invalid, - /// I/O error, similar to `EIO` in POSIX. - io, - /// Is a directory, similar to `EISDIR` in POSIX. - is-directory, - /// Too many levels of symbolic links, similar to `ELOOP` in POSIX. - loop, - /// Too many links, similar to `EMLINK` in POSIX. - too-many-links, - /// Message too large, similar to `EMSGSIZE` in POSIX. - message-size, - /// Filename too long, similar to `ENAMETOOLONG` in POSIX. - name-too-long, - /// No such device, similar to `ENODEV` in POSIX. - no-device, - /// No such file or directory, similar to `ENOENT` in POSIX. - no-entry, - /// No locks available, similar to `ENOLCK` in POSIX. - no-lock, - /// Not enough space, similar to `ENOMEM` in POSIX. - insufficient-memory, - /// No space left on device, similar to `ENOSPC` in POSIX. - insufficient-space, - /// Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. - not-directory, - /// Directory not empty, similar to `ENOTEMPTY` in POSIX. - not-empty, - /// State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. - not-recoverable, - /// Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. - unsupported, - /// Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. - no-tty, - /// No such device or address, similar to `ENXIO` in POSIX. - no-such-device, - /// Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. - overflow, - /// Operation not permitted, similar to `EPERM` in POSIX. - not-permitted, - /// Broken pipe, similar to `EPIPE` in POSIX. - pipe, - /// Read-only file system, similar to `EROFS` in POSIX. - read-only, - /// Invalid seek, similar to `ESPIPE` in POSIX. - invalid-seek, - /// Text file busy, similar to `ETXTBSY` in POSIX. - text-file-busy, - /// Cross-device link, similar to `EXDEV` in POSIX. - cross-device, -} -``` - -## `advice` -```wit -/// File or memory access pattern advisory information. -enum advice { - /// The application has no advice to give on its behavior with respect to the specified data. - normal, - /// The application expects to access the specified data sequentially from lower offsets to higher offsets. - sequential, - /// The application expects to access the specified data in a random order. - random, - /// The application expects to access the specified data in the near future. - will-need, - /// The application expects that it will not access the specified data in the near future. - dont-need, - /// The application expects to access the specified data once and then not reuse it thereafter. - no-reuse, -} -``` - -## `descriptor` -```wit -/// A descriptor is a reference to a filesystem object, which may be a file, -/// directory, named pipe, special file, or other object on which filesystem -/// calls may be made. -// TODO(resource descriptor {) -type descriptor = u32 -``` - -## `read-via-stream` -```wit -/// Return a stream for reading from a file. -/// -/// Multiple read, write, and append streams may be active on the same open -/// file and they do not interfere with each other. -/// -/// Note: This allows using `read-stream`, which is similar to `read` in POSIX. -read-via-stream: func( - this: descriptor, - /// The offset within the file at which to start reading. - offset: filesize, -) -> result -``` - -## `write-via-stream` -```wit -/// Return a stream for writing to a file. -/// -/// Note: This allows using `write-stream`, which is similar to `write` in POSIX. -write-via-stream: func( - this: descriptor, - /// The offset within the file at which to start writing. - offset: filesize, -) -> result -``` - -## `append-via-stream` -```wit -/// Return a stream for appending to a file. -/// -/// Note: This allows using `write-stream`, which is similar to `write` with -/// `O_APPEND` in in POSIX. -append-via-stream: func( - this: descriptor, - /// The resource to operate on. - fd: descriptor, -) -> result -``` - -## `advise` -```wit -/// Provide file advisory information on a descriptor. -/// -/// This is similar to `posix_fadvise` in POSIX. -advise: func( - this: descriptor, - /// The offset within the file to which the advisory applies. - offset: filesize, - /// The length of the region to which the advisory applies. - length: filesize, - /// The advice. - advice: advice -) -> result<_, error-code> -``` - -## `sync-data` -```wit -/// Synchronize the data of a file to disk. -/// -/// This function succeeds with no effect if the file descriptor is not -/// opened for writing. -/// -/// Note: This is similar to `fdatasync` in POSIX. -sync-data: func(this: descriptor) -> result<_, error-code> -``` - -## `get-flags` -```wit -/// Get flags associated with a descriptor. -/// -/// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. -/// -/// Note: This returns the value that was the `fs_flags` value returned -/// from `fdstat_get` in earlier versions of WASI. -get-flags: func(this: descriptor) -> result -``` - -## `get-type` -```wit -/// Get the dynamic type of a descriptor. -/// -/// Note: This returns the same value as the `type` field of the `fd-stat` -/// returned by `stat`, `stat-at` and similar. -/// -/// Note: This returns similar flags to the `st_mode & S_IFMT` value provided -/// by `fstat` in POSIX. -/// -/// Note: This returns the value that was the `fs_filetype` value returned -/// from `fdstat_get` in earlier versions of WASI. -get-type: func(this: descriptor) -> result -``` - -## `set-flags` -```wit -/// Set status flags associated with a descriptor. -/// -/// This function may only change the `non-blocking` flag. -/// -/// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. -/// -/// Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. -set-flags: func(this: descriptor, %flags: descriptor-flags) -> result<_, error-code> -``` - -## `set-size` -```wit -/// Adjust the size of an open file. If this increases the file's size, the -/// extra bytes are filled with zeros. -/// -/// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. -set-size: func(this: descriptor, size: filesize) -> result<_, error-code> -``` - -## `set-times` -```wit -/// Adjust the timestamps of an open file or directory. -/// -/// Note: This is similar to `futimens` in POSIX. -/// -/// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. -set-times: func( - this: descriptor, - /// The desired values of the data access timestamp. - data-access-timestamp: new-timestamp, - /// The desired values of the data modification timestamp. - data-modification-timestamp: new-timestamp, -) -> result<_, error-code> -``` - -## `read` -```wit -/// Read from a descriptor, without using and updating the descriptor's offset. -/// -/// This function returns a list of bytes containing the data that was -/// read, along with a bool which, when true, indicates that the end of the -/// file was reached. The returned list will contain up to `length` bytes; it -/// may return fewer than requested, if the end of the file is reached or -/// if the I/O operation is interrupted. -/// -/// Note: This is similar to `pread` in POSIX. -// TODO(stream) -read: func( - this: descriptor, - /// The maximum number of bytes to read. - length: filesize, - /// The offset within the file at which to read. - offset: filesize, -) -> result, bool>, error-code> -``` - -## `write` -```wit -/// Write to a descriptor, without using and updating the descriptor's offset. -/// -/// It is valid to write past the end of a file; the file is extended to the -/// extent of the write, with bytes between the previous end and the start of -/// the write set to zero. -/// -/// Note: This is similar to `pwrite` in POSIX. -// TODO(stream) -write: func( - this: descriptor, - /// Data to write - buffer: list, - /// The offset within the file at which to write. - offset: filesize, -) -> result -``` - -## `read-directory` -```wit -/// Read directory entries from a directory. -/// -/// On filesystems where directories contain entries referring to themselves -/// and their parents, often named `.` and `..` respectively, these entries -/// are omitted. -/// -/// This always returns a new stream which starts at the beginning of the -/// directory. Multiple streams may be active on the same directory, and they -/// do not interfere with each other. -read-directory: func(this: descriptor) -> result -``` - -## `sync` -```wit -/// Synchronize the data and metadata of a file to disk. -/// -/// This function succeeds with no effect if the file descriptor is not -/// opened for writing. -/// -/// Note: This is similar to `fsync` in POSIX. -sync: func(this: descriptor) -> result<_, error-code> -``` - -## `create-directory-at` -```wit -/// Create a directory. -/// -/// Note: This is similar to `mkdirat` in POSIX. -create-directory-at: func( - this: descriptor, - /// The relative path at which to create the directory. - path: string, -) -> result<_, error-code> -``` - -## `stat` -```wit -/// Return the attributes of an open file or directory. -/// -/// Note: This is similar to `fstat` in POSIX. -/// -/// Note: This was called `fd_filestat_get` in earlier versions of WASI. -stat: func(this: descriptor) -> result -``` - -## `stat-at` -```wit -/// Return the attributes of a file or directory. -/// -/// Note: This is similar to `fstatat` in POSIX. -/// -/// Note: This was called `path_filestat_get` in earlier versions of WASI. -stat-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to inspect. - path: string, -) -> result -``` - -## `set-times-at` -```wit -/// Adjust the timestamps of a file or directory. -/// -/// Note: This is similar to `utimensat` in POSIX. -/// -/// Note: This was called `path_filestat_set_times` in earlier versions of WASI. -set-times-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to operate on. - path: string, - /// The desired values of the data access timestamp. - data-access-timestamp: new-timestamp, - /// The desired values of the data modification timestamp. - data-modification-timestamp: new-timestamp, -) -> result<_, error-code> -``` - -## `link-at` -```wit -/// Create a hard link. -/// -/// Note: This is similar to `linkat` in POSIX. -link-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - old-path-flags: path-flags, - /// The relative source path from which to link. - old-path: string, - /// The base directory for `new-path`. - new-descriptor: descriptor, - /// The relative destination path at which to create the hard link. - new-path: string, -) -> result<_, error-code> -``` - -## `open-at` -```wit -/// Open a file or directory. -/// -/// The returned descriptor is not guaranteed to be the lowest-numbered -/// descriptor not currently open/ it is randomized to prevent applications -/// from depending on making assumptions about indexes, since this is -/// error-prone in multi-threaded contexts. The returned descriptor is -/// guaranteed to be less than 2**31. -/// -/// If `flags` contains `descriptor-flags::mutate-directory`, and the base -/// descriptor doesn't have `descriptor-flags::mutate-directory` set, -/// `open-at` fails with `error-code::read-only`. -/// -/// If `flags` contains `write` or `mutate-directory`, or `open-flags` -/// contains `truncate` or `create`, and the base descriptor doesn't have -/// `descriptor-flags::mutate-directory` set, `open-at` fails with -/// `error-code::read-only`. -/// -/// Note: This is similar to `openat` in POSIX. -open-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the object to open. - path: string, - /// The method by which to open the file. - open-flags: open-flags, - /// Flags to use for the resulting descriptor. - %flags: descriptor-flags, - /// Permissions to use when creating a new file. - modes: modes -) -> result -``` - -## `readlink-at` -```wit -/// Read the contents of a symbolic link. -/// -/// If the contents contain an absolute or rooted path in the underlying -/// filesystem, this function fails with `error-code::not-permitted`. -/// -/// Note: This is similar to `readlinkat` in POSIX. -readlink-at: func( - this: descriptor, - /// The relative path of the symbolic link from which to read. - path: string, -) -> result -``` - -## `remove-directory-at` -```wit -/// Remove a directory. -/// -/// Return `error-code::not-empty` if the directory is not empty. -/// -/// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. -remove-directory-at: func( - this: descriptor, - /// The relative path to a directory to remove. - path: string, -) -> result<_, error-code> -``` - -## `rename-at` -```wit -/// Rename a filesystem object. -/// -/// Note: This is similar to `renameat` in POSIX. -rename-at: func( - this: descriptor, - /// The relative source path of the file or directory to rename. - old-path: string, - /// The base directory for `new-path`. - new-descriptor: descriptor, - /// The relative destination path to which to rename the file or directory. - new-path: string, -) -> result<_, error-code> -``` - -## `symlink-at` -```wit -/// Create a symbolic link (also known as a "symlink"). -/// -/// If `old-path` starts with `/`, the function fails with `error-code::not-permitted`. -/// -/// Note: This is similar to `symlinkat` in POSIX. -symlink-at: func( - this: descriptor, - /// The contents of the symbolic link. - old-path: string, - /// The relative destination path at which to create the symbolic link. - new-path: string, -) -> result<_, error-code> -``` - -## `unlink-file-at` -```wit -/// Unlink a filesystem object that is not a directory. -/// -/// Return `error-code::is-directory` if the path refers to a directory. -/// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. -unlink-file-at: func( - this: descriptor, - /// The relative path to a file to unlink. - path: string, -) -> result<_, error-code> -``` - -## `change-file-permissions-at` -```wit -/// Change the permissions of a filesystem object that is not a directory. -/// -/// Note that the ultimate meanings of these permissions is -/// filesystem-specific. -/// -/// Note: This is similar to `fchmodat` in POSIX. -change-file-permissions-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the filesystem object. - modes: modes, -) -> result<_, error-code> -``` - -## `change-dir-permissions-at` -```wit -/// Change the permissions of a directory. -/// -/// Note that the ultimate meanings of these permissions is -/// filesystem-specific. -/// -/// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" -/// flag. `read` on a directory implies readability and searchability, and -/// `execute` is not valid for directories. -/// -/// Note: This is similar to `fchmodat` in POSIX. -change-directory-permissions-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the directory. - modes: modes, -) -> result<_, error-code> -``` - -## `lock-shared` -```wit -/// Request a shared advisory lock for an open file. -/// -/// This requests a *shared* lock; more than one shared lock can be held for -/// a file at the same time. -/// -/// If the open file has an exclusive lock, this function downgrades the lock -/// to a shared lock. If it has a shared lock, this function has no effect. -/// -/// This requests an *advisory* lock, meaning that the file could be accessed -/// by other programs that don't hold the lock. -/// -/// It is unspecified how shared locks interact with locks acquired by -/// non-WASI programs. -/// -/// This function blocks until the lock can be acquired. -/// -/// Not all filesystems support locking; on filesystems which don't support -/// locking, this function returns `error-code::unsupported`. -/// -/// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. -lock-shared: func(this: descriptor) -> result<_, error-code> -``` - -## `lock-exclusive` -```wit -/// Request an exclusive advisory lock for an open file. -/// -/// This requests an *exclusive* lock; no other locks may be held for the -/// file while an exclusive lock is held. -/// -/// If the open file has a shared lock and there are no exclusive locks held -/// for the file, this function upgrades the lock to an exclusive lock. If the -/// open file already has an exclusive lock, this function has no effect. -/// -/// This requests an *advisory* lock, meaning that the file could be accessed -/// by other programs that don't hold the lock. -/// -/// It is unspecified whether this function succeeds if the file descriptor -/// is not opened for writing. It is unspecified how exclusive locks interact -/// with locks acquired by non-WASI programs. -/// -/// This function blocks until the lock can be acquired. -/// -/// Not all filesystems support locking; on filesystems which don't support -/// locking, this function returns `error-code::unsupported`. -/// -/// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. -lock-exclusive: func(this: descriptor) -> result<_, error-code> -``` - -## `try-lock-shared` -```wit -/// Request a shared advisory lock for an open file. -/// -/// This requests a *shared* lock; more than one shared lock can be held for -/// a file at the same time. -/// -/// If the open file has an exclusive lock, this function downgrades the lock -/// to a shared lock. If it has a shared lock, this function has no effect. -/// -/// This requests an *advisory* lock, meaning that the file could be accessed -/// by other programs that don't hold the lock. -/// -/// It is unspecified how shared locks interact with locks acquired by -/// non-WASI programs. -/// -/// This function returns `error-code::would-block` if the lock cannot be acquired. -/// -/// Not all filesystems support locking; on filesystems which don't support -/// locking, this function returns `error-code::unsupported`. -/// -/// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. -try-lock-shared: func(this: descriptor) -> result<_, error-code> -``` - -## `try-lock-exclusive` -```wit -/// Request an exclusive advisory lock for an open file. -/// -/// This requests an *exclusive* lock; no other locks may be held for the -/// file while an exclusive lock is held. -/// -/// If the open file has a shared lock and there are no exclusive locks held -/// for the file, this function upgrades the lock to an exclusive lock. If the -/// open file already has an exclusive lock, this function has no effect. -/// -/// This requests an *advisory* lock, meaning that the file could be accessed -/// by other programs that don't hold the lock. -/// -/// It is unspecified whether this function succeeds if the file descriptor -/// is not opened for writing. It is unspecified how exclusive locks interact -/// with locks acquired by non-WASI programs. -/// -/// This function returns `error-code::would-block` if the lock cannot be acquired. -/// -/// Not all filesystems support locking; on filesystems which don't support -/// locking, this function returns `error-code::unsupported`. -/// -/// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. -try-lock-exclusive: func(this: descriptor) -> result<_, error-code> -``` - -## `unlock` -```wit -/// Release a shared or exclusive lock on an open file. -/// -/// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. -unlock: func(this: descriptor) -> result<_, error-code> -``` - -# `drop-descriptor` -```wit -/// Dispose of the specified `descriptor`, after which it may no longer -/// be used. -// TODO(} /* resource descriptor */) -drop-descriptor: func(this: descriptor) -``` - -## `directory-entry-stream` -```wit -/// A stream of directory entries. -// TODO(resource directory-entry-stream {) -// TODO(stream) -type directory-entry-stream = u32 -``` - -## `read-directory-entry` -```wit -/// Read a single directory entry from a `directory-entry-stream`. -read-directory-entry: func(this: directory-entry-stream) -> result, error-code> -``` - -# `drop-directory-entry-stream` -```wit -/// Dispose of the specified `directory-entry-stream`, after which it may no longer -/// be used. -// TODO(} /* resource directory-entry-stream */) -drop-directory-entry-stream: func(this: directory-entry-stream) -``` - -```wit -} -``` diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit new file mode 100644 index 000000000..17cf06ac0 --- /dev/null +++ b/proposals/filesystem/wit/world.wit @@ -0,0 +1,3 @@ +default world example-world { + import filesystem: pkg.filesystem +} diff --git a/proposals/filesystem/wit/world.wit.md b/proposals/filesystem/wit/world.wit.md deleted file mode 100644 index 6689fafb9..000000000 --- a/proposals/filesystem/wit/world.wit.md +++ /dev/null @@ -1,9 +0,0 @@ -This file contains a world that imports all interfaces in this proposal. Its -primary purpose is to allow unified documentation to be easily generated for -the whole proposal. - -```wit -default world wasi-filesystem { - import wasi-filesystem: pkg.wasi-filesystem -} -``` From 888e60fe77834e6428907c2b4e080ad93856e6c0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 21 Feb 2023 15:40:29 -0600 Subject: [PATCH 1054/1772] Update to the latest wasi-proposal-repo format. (#40) This notably converts the `.wit.md` files to `.wit`. --- proposals/clocks/.github/workflows/main.yml | 5 +- proposals/clocks/example-world.md | 305 ++++++++++++++ proposals/clocks/wasi-clocks.html | 281 ------------- proposals/clocks/wasi-clocks.md | 373 ------------------ proposals/clocks/wit/deps/poll/poll.wit | 39 ++ .../clocks/wit/instance-monotonic-clock.wit | 15 + proposals/clocks/wit/instance-wall-clock.wit | 15 + proposals/clocks/wit/monotonic-clock.wit | 40 ++ proposals/clocks/wit/timezone.wit | 61 +++ proposals/clocks/wit/wall-clock.wit | 48 +++ .../clocks/wit/wasi-default-clocks.wit.md | 40 -- .../clocks/wit/wasi-monotonic-clock.wit.md | 65 --- proposals/clocks/wit/wasi-timezone.wit.md | 107 ----- proposals/clocks/wit/wasi-wall-clock.wit.md | 72 ---- proposals/clocks/wit/world.wit | 7 + proposals/clocks/wit/world.wit.md | 12 - 16 files changed, 532 insertions(+), 953 deletions(-) create mode 100644 proposals/clocks/example-world.md delete mode 100644 proposals/clocks/wasi-clocks.html delete mode 100644 proposals/clocks/wasi-clocks.md create mode 100644 proposals/clocks/wit/deps/poll/poll.wit create mode 100644 proposals/clocks/wit/instance-monotonic-clock.wit create mode 100644 proposals/clocks/wit/instance-wall-clock.wit create mode 100644 proposals/clocks/wit/monotonic-clock.wit create mode 100644 proposals/clocks/wit/timezone.wit create mode 100644 proposals/clocks/wit/wall-clock.wit delete mode 100644 proposals/clocks/wit/wasi-default-clocks.wit.md delete mode 100644 proposals/clocks/wit/wasi-monotonic-clock.wit.md delete mode 100644 proposals/clocks/wit/wasi-timezone.wit.md delete mode 100644 proposals/clocks/wit/wasi-wall-clock.wit.md create mode 100644 proposals/clocks/wit/world.wit delete mode 100644 proposals/clocks/wit/world.wit.md diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 08bf17764..ad1997c51 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -11,7 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-poll/b4a0db022ccddf763e3b91717886c8e39582de72/wit/wasi-poll.wit.md > wit/wasi-poll.wit.md - - uses: WebAssembly/wit-abi-up-to-date@v10 + - uses: WebAssembly/wit-abi-up-to-date@v12 with: - wit-abi-tag: wit-abi-0.8.0 + wit-abi-tag: wit-abi-0.10.0 diff --git a/proposals/clocks/example-world.md b/proposals/clocks/example-world.md new file mode 100644 index 000000000..a42fb0d21 --- /dev/null +++ b/proposals/clocks/example-world.md @@ -0,0 +1,305 @@ +

    World example-world

    + +

    Import interface poll

    +

    A poll API intended to let users wait for I/O events on multiple handles +at once.

    +
    +

    Types

    +

    type pollable

    +

    u32

    +

    A "pollable" handle. +

    This is conceptually represents a stream<_, _>, or in other words, +a stream that one can wait on, repeatedly, but which does not itself +produce any data. It's temporary scaffolding until component-model's +async features are ready.

    +

    And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

    +

    pollable lifetimes are not automatically managed. Users must ensure +that they do not outlive the resource they reference.

    +

    This represents a resource.

    +
    +

    Functions

    +

    drop-pollable: func

    +

    Dispose of the specified pollable, after which it may no longer +be used.

    +
    Params
    + +

    poll-oneoff: func

    +

    Poll for completion on a set of pollables.

    +

    The "oneoff" in the name refers to the fact that this function must do a +linear scan through the entire list of subscriptions, which may be +inefficient if the number is large and the same subscriptions are used +many times. In the future, this is expected to be obsoleted by the +component model async proposal, which will include a scalable waiting +facility.

    +

    Note that the return type would ideally be list<bool>, but that would +be more difficult to polyfill given the current state of wit-bindgen. +See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 +for details. For now, we use zero to mean "not ready" and non-zero to +mean "ready".

    +
    Params
    + +
    Return values
    +
      +
    • list<u8>
    • +
    +

    Import interface monotonic-clock

    +

    WASI Monotonic Clock is a clock API intended to let users measure elapsed +time.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +
    +

    Types

    +

    type pollable

    +

    pollable

    +

    +#### `type monotonic-clock` +`u32` +

    A monotonic clock is a clock which has an unspecified initial value, and +successive reads of the clock will produce non-decreasing values. +

    It is intended for measuring elapsed time.

    +

    This represents a resource.

    +

    type instant

    +

    u64

    +

    A timestamp in nanoseconds. +


    +

    Functions

    +

    now: func

    +

    Read the current value of the clock.

    +

    The clock is monotonic, therefore calling this function repeatedly will +produce a sequence of non-decreasing values.

    +
    Params
    + +
    Return values
    + +

    resolution: func

    +

    Query the resolution of the clock.

    +
    Params
    + +
    Return values
    + +

    subscribe: func

    +

    Create a pollable which will resolve once the specified time has been +reached.

    +
    Params
    + +
    Return values
    + +

    drop-monotonic-clock: func

    +

    Dispose of the specified monotonic-clock, after which it may no longer +be used.

    +
    Params
    + +

    Import interface wall-clock

    +

    WASI Wall Clock is a clock API intended to let users query the current +time. The name "wall" makes an analogy to a "clock on the wall", which +is not necessarily monotonic as it may be reset.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +
    +

    Types

    +

    type wall-clock

    +

    u32

    +

    A wall clock is a clock which measures the date and time according to +some external reference. +

    External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time.

    +

    It is intended for reporting the current date and time for humans.

    +

    This represents a resource.

    +

    record datetime

    +

    A time and date in seconds plus nanoseconds.

    +
    Record Fields
    + +
    +

    Functions

    +

    now: func

    +

    Read the current value of the clock.

    +

    This clock is not monotonic, therefore calling this function repeatedly +will not necessarily produce a sequence of non-decreasing values.

    +

    The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, +also known as Unix Time.

    +

    The nanoseconds field of the output is always less than 1000000000.

    +
    Params
    + +
    Return values
    + +

    resolution: func

    +

    Query the resolution of the clock.

    +

    The nanoseconds field of the output is always less than 1000000000.

    +
    Params
    + +
    Return values
    + +

    drop-wall-clock: func

    +

    Dispose of the specified wall-clock, after which it may no longer +be used.

    +
    Params
    + +

    Import interface timezone

    +
    +

    Types

    +

    type datetime

    +

    datetime

    +

    +#### `record timezone-display` +

    Information useful for displaying the timezone of a specific datetime.

    +

    This information may vary within a single timezone to reflect daylight +saving time adjustments.

    +
    Record Fields
    +
      +
    • +

      utc-offset: s32

      +

      The number of seconds difference between UTC time and the local +time of the timezone. +

      The returned value will always be less than 86400 which is the +number of seconds in a day (246060).

      +

      In implementations that do not expose an actual time zone, this +should return 0.

      +
    • +
    • +

      name: string

      +

      The abbreviated name of the timezone to display to a user. The name +`UTC` indicates Coordinated Universal Time. Otherwise, this should +reference local standards for the name of the time zone. +

      In implementations that do not expose an actual time zone, this +should be the string UTC.

      +

      In time zones that do not have an applicable name, a formatted +representation of the UTC offset may be returned, such as -04:00.

      +
    • +
    • +

      in-daylight-saving-time: bool

      +

      Whether daylight saving time is active. +

      In implementations that do not expose an actual time zone, this +should return false.

      +
    • +
    +

    type timezone

    +

    u32

    +

    A timezone. +

    In timezones that recognize daylight saving time, also known as daylight +time and summer time, the information returned from the functions varies +over time to reflect these adjustments.

    +

    This represents a resource.

    +
    +

    Functions

    +

    display: func

    +

    Return information needed to display the given datetime. This includes +the UTC offset, the time zone name, and a flag indicating whether +daylight saving time is active.

    +

    If the timezone cannot be determined for the given datetime, return a +timezone-display for UTC with a utc-offset of 0 and no daylight +saving time.

    +
    Params
    + +
    Return values
    + +

    utc-offset: func

    +

    The same as display, but only return the UTC offset.

    +
    Params
    + +
    Return values
    +
      +
    • s32
    • +
    +

    drop-timezone: func

    +

    Dispose of the specified input-stream, after which it may no longer +be used.

    +
    Params
    + +

    Import interface instance-monotonic-clock

    +

    This interfaces proves a clock handles for monotonic clock, suitable for +general-purpose application needs.

    +
    +

    Types

    +

    type monotonic-clock

    +

    monotonic-clock

    +

    +---- +

    Functions

    +

    instance-monotonic-clock: func

    +

    Return a handle to a monotonic clock, suitable for general-purpose +application needs.

    +

    This allocates a new handle, so applications with frequent need of a +clock handle should call this function once and reuse the handle +instead of calling this function each time.

    +

    This represents a value import.

    +
    Return values
    + +

    Import interface instance-wall-clock

    +

    This interfaces proves a clock handles for wall clock, suitable for +general-purpose application needs.

    +
    +

    Types

    +

    type wall-clock

    +

    wall-clock

    +

    +---- +

    Functions

    +

    instance-wall-clock: func

    +

    Return a handle to a wall clock, suitable for general-purpose +application needs.

    +

    This allocates a new handle, so applications with frequent need of a +clock handle should call this function once and reuse the handle +instead of calling this function each time.

    +

    This represents a value import.

    +
    Return values
    + diff --git a/proposals/clocks/wasi-clocks.html b/proposals/clocks/wasi-clocks.html deleted file mode 100644 index 2a1525aaf..000000000 --- a/proposals/clocks/wasi-clocks.html +++ /dev/null @@ -1,281 +0,0 @@ -

    Import interface wasi-poll

    -

    Types

    -

    pollable: u32

    -

    A "pollable" handle.

    -

    This is conceptually represents a stream<_, _>, or in other words, -a stream that one can wait on, repeatedly, but which does not itself -produce any data. It's temporary scaffolding until component-model's -async features are ready.

    -

    And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

    -

    pollable lifetimes are not automatically managed. Users must ensure -that they do not outlive the resource they reference.

    -

    Size: 4, Alignment: 4

    -

    Functions

    -
    -

    drop-pollable

    -

    Dispose of the specified pollable, after which it may no longer be used.

    -
    Params
    - -
    -

    poll-oneoff

    -

    Poll for completion on a set of pollables.

    -

    The "oneoff" in the name refers to the fact that this function must do a -linear scan through the entire list of subscriptions, which may be -inefficient if the number is large and the same subscriptions are used -many times. In the future, this is expected to be obsoleted by the -component model async proposal, which will include a scalable waiting -facility.

    -

    Note that the return type would ideally be list<bool>, but that would -be more difficult to polyfill given the current state of wit-bindgen. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 -for details. For now, we use zero to mean "not ready" and non-zero to -mean "ready".

    -
    Params
    - -
    Results
    -
      -
    • result0: list<u8>
    • -
    -

    Import interface wasi-monotonic-clock

    -

    Types

    -

    pollable: pollable

    -

    Size: 4, Alignment: 4

    -

    monotonic-clock: u32

    -

    A monotonic clock is a clock which has an unspecified initial value, and -successive reads of the clock will produce non-decreasing values.

    -

    It is intended for measuring elapsed time.

    -

    Size: 4, Alignment: 4

    -

    instant: u64

    -

    A timestamp in nanoseconds.

    -

    Size: 8, Alignment: 8

    -

    Functions

    -
    -

    now

    -

    Read the current value of the clock.

    -

    The clock is monotonic, therefore calling this function repeatedly will produce -a sequence of non-decreasing values.

    -
    Params
    - -
    Results
    - -
    -

    resolution

    -

    Query the resolution of the clock.

    -
    Params
    - -
    Results
    - -
    -

    subscribe

    -

    Create a pollable which will resolve once the specified time has been reached.

    -
    Params
    - -
    Results
    - -
    -

    drop-monotonic-clock

    -

    Dispose of the specified monotonic-clock, after which it may no longer -be used.

    -
    Params
    - -

    Import interface wasi-wall-clock

    -

    Types

    -

    wall-clock: u32

    -

    A wall clock is a clock which measures the date and time according to some -external reference.

    -

    External references may be reset, so this clock is not necessarily -monotonic, making it unsuitable for measuring elapsed time.

    -

    It is intended for reporting the current date and time for humans.

    -

    Size: 4, Alignment: 4

    -

    datetime: record

    -

    A time and date in seconds plus nanoseconds.

    -

    Size: 16, Alignment: 8

    -

    Record Fields

    - -

    Functions

    -
    -

    now

    -

    Read the current value of the clock.

    -

    This clock is not monotonic, therefore calling this function repeatedly will -not necessarily produce a sequence of non-decreasing values.

    -

    The returned timestamps represent the number of seconds since -1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, also -known as Unix Time.

    -

    The nanoseconds field of the output is always less than 1000000000.

    -
    Params
    - -
    Results
    - -
    -

    resolution

    -

    Query the resolution of the clock.

    -

    The nanoseconds field of the output is always less than 1000000000.

    -
    Params
    - -
    Results
    - -
    -

    drop-wall-clock

    -

    Dispose of the specified wall-clock, after which it may no longer -be used.

    -
    Params
    - -

    Import interface wasi-timezone

    -

    Types

    -

    timezone-display: record

    -

    Information useful for displaying the timezone of a specific datetime.

    -

    This information may vary within a single timezone to reflect daylight -saving time adjustments.

    -

    Size: 16, Alignment: 4

    -

    Record Fields

    -
      -
    • -

      utc-offset: s32

      -

      The number of seconds difference between UTC time and the local time of -the timezone.

      -

      The returned value will always be less than 86400 which is the number of -seconds in a day (246060).

      -

      In implementations that do not expose an actual time zone, this should -return 0.

      -
    • -
    • -

      name: string

      -

      The abbreviated name of the timezone to display to a user. The name UTC -indicates Coordinated Universal Time. Otherwise, this should reference -local standards for the name of the time zone.

      -

      In implementations that do not expose an actual time zone, this should be -the string UTC.

      -

      In time zones that do not have an applicable name, a formatted -representation of the UTC offset may be returned, such as -04:00.

      -
    • -
    • -

      in-daylight-saving-time: bool

      -

      Whether daylight saving time is active.

      -

      In implementations that do not expose an actual time zone, this should -return false.

      -
    • -
    -

    timezone: u32

    -

    A timezone.

    -

    In timezones that recognize daylight saving time, also known as daylight -time and summer time, the information returned from the functions varies -over time to reflect these adjustments.

    -

    Size: 4, Alignment: 4

    -

    datetime: record

    -

    A time and date in seconds plus nanoseconds.

    -

    TODO: Use the definition from the monotonic clock API instead of defining our own copy.

    -

    Size: 16, Alignment: 8

    -

    Record Fields

    - -

    Functions

    -
    -

    display

    -

    Return information needed to display the given datetime. This includes -the UTC offset, the time zone name, and a flag indicating whether -daylight saving time is active.

    -

    If the timezone cannot be determined for the given datetime, return a -timezone-display for UTC with a utc-offset of 0 and no daylight -saving time.

    -
    Params
    - -
    Results
    - -
    -

    utc-offset

    -

    The same as display, but only return the UTC offset.

    -
    Params
    - -
    Results
    -
      -
    • result0: s32
    • -
    -
    -

    drop-timezone

    -

    Dispose of the specified input-stream, after which it may no longer -be used.

    -
    Params
    - -

    Import interface wasi-default-clocks

    -

    Types

    -

    monotonic-clock: monotonic-clock

    -

    Size: 4, Alignment: 4

    -

    wall-clock: wall-clock

    -

    Size: 4, Alignment: 4

    -

    Functions

    -
    -

    default-monotonic-clock

    -

    Return a default monotonic clock, suitable for general-purpose application -needs.

    -

    This allocates a new handle, so applications with frequent need of a clock -handle should call this function once and reuse the handle instead of -calling this function each time.

    -
    Results
    - -
    -

    default-wall-clock

    -

    Return a default wall clock, suitable for general-purpose application -needs.

    -

    This allocates a new handle, so applications with frequent need of a clock -handle should call this function once and reuse the handle instead of -calling this function each time.

    -
    Results
    - diff --git a/proposals/clocks/wasi-clocks.md b/proposals/clocks/wasi-clocks.md deleted file mode 100644 index c30719457..000000000 --- a/proposals/clocks/wasi-clocks.md +++ /dev/null @@ -1,373 +0,0 @@ -# Import interface `wasi-poll` - -## Types - -## `pollable`: `u32` - -A "pollable" handle. - -This is conceptually represents a `stream<_, _>`, or in other words, -a stream that one can wait on, repeatedly, but which does not itself -produce any data. It's temporary scaffolding until component-model's -async features are ready. - -And at present, it is a `u32` instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready. - -`pollable` lifetimes are not automatically managed. Users must ensure -that they do not outlive the resource they reference. - -Size: 4, Alignment: 4 - -## Functions - ----- - -#### `drop-pollable` - -Dispose of the specified `pollable`, after which it may no longer be used. -##### Params - -- `this`: [`pollable`](#pollable) - ----- - -#### `poll-oneoff` - -Poll for completion on a set of pollables. - -The "oneoff" in the name refers to the fact that this function must do a -linear scan through the entire list of subscriptions, which may be -inefficient if the number is large and the same subscriptions are used -many times. In the future, this is expected to be obsoleted by the -component model async proposal, which will include a scalable waiting -facility. - -Note that the return type would ideally be `list`, but that would -be more difficult to polyfill given the current state of `wit-bindgen`. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 -for details. For now, we use zero to mean "not ready" and non-zero to -mean "ready". -##### Params - -- `in`: list<[`pollable`](#pollable)> -##### Results - -- `result0`: list<`u8`> - -# Import interface `wasi-monotonic-clock` - -## Types - -## `pollable`: [`pollable`](#pollable) - - -Size: 4, Alignment: 4 - -## `monotonic-clock`: `u32` - -A monotonic clock is a clock which has an unspecified initial value, and -successive reads of the clock will produce non-decreasing values. - -It is intended for measuring elapsed time. - -Size: 4, Alignment: 4 - -## `instant`: `u64` - -A timestamp in nanoseconds. - -Size: 8, Alignment: 8 - -## Functions - ----- - -#### `now` - -Read the current value of the clock. - -The clock is monotonic, therefore calling this function repeatedly will produce -a sequence of non-decreasing values. -##### Params - -- `this`: [`monotonic-clock`](#monotonic_clock) -##### Results - -- `result0`: [`instant`](#instant) - ----- - -#### `resolution` - -Query the resolution of the clock. -##### Params - -- `this`: [`monotonic-clock`](#monotonic_clock) -##### Results - -- `result0`: [`instant`](#instant) - ----- - -#### `subscribe` - -Create a `pollable` which will resolve once the specified time has been reached. -##### Params - -- `this`: [`monotonic-clock`](#monotonic_clock) -- `when`: [`instant`](#instant) -- `absolute`: `bool` -##### Results - -- `result0`: [`pollable`](#pollable) - ----- - -#### `drop-monotonic-clock` - -Dispose of the specified `monotonic-clock`, after which it may no longer -be used. -##### Params - -- `this`: [`monotonic-clock`](#monotonic_clock) - -# Import interface `wasi-wall-clock` - -## Types - -## `wall-clock`: `u32` - -A wall clock is a clock which measures the date and time according to some -external reference. - -External references may be reset, so this clock is not necessarily -monotonic, making it unsuitable for measuring elapsed time. - -It is intended for reporting the current date and time for humans. - -Size: 4, Alignment: 4 - -## `datetime`: record - -A time and date in seconds plus nanoseconds. - -Size: 16, Alignment: 8 - -### Record Fields - -- [`seconds`](#datetime.seconds): `u64` - - -- [`nanoseconds`](#datetime.nanoseconds): `u32` - - -## Functions - ----- - -#### `now` - -Read the current value of the clock. - -This clock is not monotonic, therefore calling this function repeatedly will -not necessarily produce a sequence of non-decreasing values. - -The returned timestamps represent the number of seconds since -1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], also -known as [Unix Time]. - -The nanoseconds field of the output is always less than 1000000000. - -[POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 -[Unix Time]: https://en.wikipedia.org/wiki/Unix_time -##### Params - -- `this`: [`wall-clock`](#wall_clock) -##### Results - -- `result0`: [`datetime`](#datetime) - ----- - -#### `resolution` - -Query the resolution of the clock. - -The nanoseconds field of the output is always less than 1000000000. -##### Params - -- `this`: [`wall-clock`](#wall_clock) -##### Results - -- `result0`: [`datetime`](#datetime) - ----- - -#### `drop-wall-clock` - -Dispose of the specified `wall-clock`, after which it may no longer -be used. -##### Params - -- `this`: [`wall-clock`](#wall_clock) - -# Import interface `wasi-timezone` - -## Types - -## `timezone-display`: record - -Information useful for displaying the timezone of a specific `datetime`. - -This information may vary within a single `timezone` to reflect daylight -saving time adjustments. - -Size: 16, Alignment: 4 - -### Record Fields - -- [`utc-offset`](#timezone_display.utc_offset): `s32` - - The number of seconds difference between UTC time and the local time of - the timezone. - - The returned value will always be less than 86400 which is the number of - seconds in a day (24*60*60). - - In implementations that do not expose an actual time zone, this should - return 0. - -- [`name`](#timezone_display.name): `string` - - The abbreviated name of the timezone to display to a user. The name `UTC` - indicates Coordinated Universal Time. Otherwise, this should reference - local standards for the name of the time zone. - - In implementations that do not expose an actual time zone, this should be - the string `UTC`. - - In time zones that do not have an applicable name, a formatted - representation of the UTC offset may be returned, such as `-04:00`. - -- [`in-daylight-saving-time`](#timezone_display.in_daylight_saving_time): `bool` - - Whether daylight saving time is active. - - In implementations that do not expose an actual time zone, this should - return false. - -## `timezone`: `u32` - -A timezone. - -In timezones that recognize daylight saving time, also known as daylight -time and summer time, the information returned from the functions varies -over time to reflect these adjustments. - -Size: 4, Alignment: 4 - -## `datetime`: record - -A time and date in seconds plus nanoseconds. - -TODO: Use the definition from the monotonic clock API instead of defining our own copy. - -Size: 16, Alignment: 8 - -### Record Fields - -- [`seconds`](#datetime.seconds): `u64` - - -- [`nanoseconds`](#datetime.nanoseconds): `u32` - - -## Functions - ----- - -#### `display` - -Return information needed to display the given `datetime`. This includes -the UTC offset, the time zone name, and a flag indicating whether -daylight saving time is active. - -If the timezone cannot be determined for the given `datetime`, return a -`timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight -saving time. -##### Params - -- `this`: [`timezone`](#timezone) -- `when`: [`datetime`](#datetime) -##### Results - -- `result0`: [`timezone-display`](#timezone_display) - ----- - -#### `utc-offset` - -The same as `display`, but only return the UTC offset. -##### Params - -- `this`: [`timezone`](#timezone) -- `when`: [`datetime`](#datetime) -##### Results - -- `result0`: `s32` - ----- - -#### `drop-timezone` - -Dispose of the specified input-stream, after which it may no longer -be used. -##### Params - -- `this`: [`timezone`](#timezone) - -# Import interface `wasi-default-clocks` - -## Types - -## `monotonic-clock`: [`monotonic-clock`](#monotonic_clock) - - -Size: 4, Alignment: 4 - -## `wall-clock`: [`wall-clock`](#wall_clock) - - -Size: 4, Alignment: 4 - -## Functions - ----- - -#### `default-monotonic-clock` - -Return a default monotonic clock, suitable for general-purpose application -needs. - -This allocates a new handle, so applications with frequent need of a clock -handle should call this function once and reuse the handle instead of -calling this function each time. -##### Results - -- `result0`: [`monotonic-clock`](#monotonic_clock) - ----- - -#### `default-wall-clock` - -Return a default wall clock, suitable for general-purpose application -needs. - -This allocates a new handle, so applications with frequent need of a clock -handle should call this function once and reuse the handle instead of -calling this function each time. -##### Results - -- `result0`: [`wall-clock`](#wall_clock) - diff --git a/proposals/clocks/wit/deps/poll/poll.wit b/proposals/clocks/wit/deps/poll/poll.wit new file mode 100644 index 000000000..28f08e17d --- /dev/null +++ b/proposals/clocks/wit/deps/poll/poll.wit @@ -0,0 +1,39 @@ +/// A poll API intended to let users wait for I/O events on multiple handles +/// at once. +default interface poll { + /// A "pollable" handle. + /// + /// This is conceptually represents a `stream<_, _>`, or in other words, + /// a stream that one can wait on, repeatedly, but which does not itself + /// produce any data. It's temporary scaffolding until component-model's + /// async features are ready. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// `pollable` lifetimes are not automatically managed. Users must ensure + /// that they do not outlive the resource they reference. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type pollable = u32 + + /// Dispose of the specified `pollable`, after which it may no longer + /// be used. + drop-pollable: func(this: pollable) + + /// Poll for completion on a set of pollables. + /// + /// The "oneoff" in the name refers to the fact that this function must do a + /// linear scan through the entire list of subscriptions, which may be + /// inefficient if the number is large and the same subscriptions are used + /// many times. In the future, this is expected to be obsoleted by the + /// component model async proposal, which will include a scalable waiting + /// facility. + /// + /// Note that the return type would ideally be `list`, but that would + /// be more difficult to polyfill given the current state of `wit-bindgen`. + /// See + /// for details. For now, we use zero to mean "not ready" and non-zero to + /// mean "ready". + poll-oneoff: func(in: list) -> list +} diff --git a/proposals/clocks/wit/instance-monotonic-clock.wit b/proposals/clocks/wit/instance-monotonic-clock.wit new file mode 100644 index 000000000..f92cd12a2 --- /dev/null +++ b/proposals/clocks/wit/instance-monotonic-clock.wit @@ -0,0 +1,15 @@ +/// This interfaces proves a clock handles for monotonic clock, suitable for +/// general-purpose application needs. +default interface instance-clocks { + use pkg.monotonic-clock.{monotonic-clock} + + /// Return a handle to a monotonic clock, suitable for general-purpose + /// application needs. + /// + /// This allocates a new handle, so applications with frequent need of a + /// clock handle should call this function once and reuse the handle + /// instead of calling this function each time. + /// + /// This [represents a value import](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Value_Imports). + instance-monotonic-clock: func() -> monotonic-clock +} diff --git a/proposals/clocks/wit/instance-wall-clock.wit b/proposals/clocks/wit/instance-wall-clock.wit new file mode 100644 index 000000000..a29729793 --- /dev/null +++ b/proposals/clocks/wit/instance-wall-clock.wit @@ -0,0 +1,15 @@ +/// This interfaces proves a clock handles for wall clock, suitable for +/// general-purpose application needs. +default interface instance-clocks { + use pkg.wall-clock.{wall-clock} + + /// Return a handle to a wall clock, suitable for general-purpose + /// application needs. + /// + /// This allocates a new handle, so applications with frequent need of a + /// clock handle should call this function once and reuse the handle + /// instead of calling this function each time. + /// + /// This [represents a value import](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Value_Imports). + instance-wall-clock: func() -> wall-clock +} diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit new file mode 100644 index 000000000..51c2203c9 --- /dev/null +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -0,0 +1,40 @@ +/// WASI Monotonic Clock is a clock API intended to let users measure elapsed +/// time. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface monotonic-clock { + use poll.poll.{pollable} + + /// A timestamp in nanoseconds. + type instant = u64 + + /// A monotonic clock is a clock which has an unspecified initial value, and + /// successive reads of the clock will produce non-decreasing values. + /// + /// It is intended for measuring elapsed time. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type monotonic-clock = u32 + + /// Read the current value of the clock. + /// + /// The clock is monotonic, therefore calling this function repeatedly will + /// produce a sequence of non-decreasing values. + now: func(this: monotonic-clock) -> instant + + /// Query the resolution of the clock. + resolution: func(this: monotonic-clock) -> instant + + /// Create a `pollable` which will resolve once the specified time has been + /// reached. + subscribe: func( + this: monotonic-clock, + when: instant, + absolute: bool + ) -> pollable + + /// Dispose of the specified `monotonic-clock`, after which it may no longer + /// be used. + drop-monotonic-clock: func(this: monotonic-clock) +} diff --git a/proposals/clocks/wit/timezone.wit b/proposals/clocks/wit/timezone.wit new file mode 100644 index 000000000..63f99cc40 --- /dev/null +++ b/proposals/clocks/wit/timezone.wit @@ -0,0 +1,61 @@ +default interface timezone { + use pkg.wall-clock.{datetime} + + /// A timezone. + /// + /// In timezones that recognize daylight saving time, also known as daylight + /// time and summer time, the information returned from the functions varies + /// over time to reflect these adjustments. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type timezone = u32 + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + display: func(this: timezone, when: datetime) -> timezone-display + + /// The same as `display`, but only return the UTC offset. + utc-offset: func(this: timezone, when: datetime) -> s32 + + /// Dispose of the specified input-stream, after which it may no longer + /// be used. + drop-timezone: func(this: timezone) + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/clocks/wit/wall-clock.wit b/proposals/clocks/wit/wall-clock.wit new file mode 100644 index 000000000..c60861acd --- /dev/null +++ b/proposals/clocks/wit/wall-clock.wit @@ -0,0 +1,48 @@ +/// WASI Wall Clock is a clock API intended to let users query the current +/// time. The name "wall" makes an analogy to a "clock on the wall", which +/// is not necessarily monotonic as it may be reset. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface wall-clock { + /// A time and date in seconds plus nanoseconds. + record datetime { + seconds: u64, + nanoseconds: u32, + } + + /// A wall clock is a clock which measures the date and time according to + /// some external reference. + /// + /// External references may be reset, so this clock is not necessarily + /// monotonic, making it unsuitable for measuring elapsed time. + /// + /// It is intended for reporting the current date and time for humans. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type wall-clock = u32 + + /// Read the current value of the clock. + /// + /// This clock is not monotonic, therefore calling this function repeatedly + /// will not necessarily produce a sequence of non-decreasing values. + /// + /// The returned timestamps represent the number of seconds since + /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], + /// also known as [Unix Time]. + /// + /// The nanoseconds field of the output is always less than 1000000000. + /// + /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + now: func(this: wall-clock) -> datetime + + /// Query the resolution of the clock. + /// + /// The nanoseconds field of the output is always less than 1000000000. + resolution: func(this: wall-clock) -> datetime + + /// Dispose of the specified `wall-clock`, after which it may no longer + /// be used. + drop-wall-clock: func(this: wall-clock) +} diff --git a/proposals/clocks/wit/wasi-default-clocks.wit.md b/proposals/clocks/wit/wasi-default-clocks.wit.md deleted file mode 100644 index dfeddcc4e..000000000 --- a/proposals/clocks/wit/wasi-default-clocks.wit.md +++ /dev/null @@ -1,40 +0,0 @@ -# WASI Default Clocks API - -## `wasi-default-clocks` -```wit -/// WASI Default Clocks provides value-exports of clock handles for monotonic -/// and a wall-clock time, suitable for general-purpose application needs. -default interface wasi-default-clocks { -``` - -## Imports -```wit -use pkg.wasi-monotonic-clock.{monotonic-clock} -use pkg.wasi-wall-clock.{wall-clock} -``` - -## `default-monotonic-clock` -```wit -/// Return a default monotonic clock, suitable for general-purpose application -/// needs. -/// -/// This allocates a new handle, so applications with frequent need of a clock -/// handle should call this function once and reuse the handle instead of -/// calling this function each time. -default-monotonic-clock: func() -> monotonic-clock -``` - -## `default-wall-clock` -```wit -/// Return a default wall clock, suitable for general-purpose application -/// needs. -/// -/// This allocates a new handle, so applications with frequent need of a clock -/// handle should call this function once and reuse the handle instead of -/// calling this function each time. -default-wall-clock: func() -> wall-clock -``` - -```wit -} -``` diff --git a/proposals/clocks/wit/wasi-monotonic-clock.wit.md b/proposals/clocks/wit/wasi-monotonic-clock.wit.md deleted file mode 100644 index 0279e67c1..000000000 --- a/proposals/clocks/wit/wasi-monotonic-clock.wit.md +++ /dev/null @@ -1,65 +0,0 @@ -# WASI Monotonic Clock API - -## `wasi-clocks` -```wit -/// WASI Monotonic Clock is a clock API intended to let users measure elapsed -/// time. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -default interface wasi-monotonic-clock { -``` - -## Imports -```wit -use pkg.wasi-poll.{pollable} -``` - -## `instant` -```wit -/// A timestamp in nanoseconds. -type instant = u64 -``` - -## `monotonic-clock` -```wit -/// A monotonic clock is a clock which has an unspecified initial value, and -/// successive reads of the clock will produce non-decreasing values. -/// -/// It is intended for measuring elapsed time. -// TODO(resource monotonic-clock {) -type monotonic-clock = u32 -``` - -## `now` -```wit -/// Read the current value of the clock. -/// -/// The clock is monotonic, therefore calling this function repeatedly will produce -/// a sequence of non-decreasing values. -now: func(this: monotonic-clock) -> instant -``` - -## `resolution` -```wit -/// Query the resolution of the clock. -resolution: func(this: monotonic-clock) -> instant -``` - -## `subscribe` -```wit -/// Create a `pollable` which will resolve once the specified time has been reached. -subscribe: func(this: monotonic-clock, when: instant, absolute: bool) -> pollable -``` - -## `drop-monotonic-clock` -```wit -/// Dispose of the specified `monotonic-clock`, after which it may no longer -/// be used. -// TODO(} /* resource monotonic-clock */) -drop-monotonic-clock: func(this: monotonic-clock) -``` - -```wit -} -``` diff --git a/proposals/clocks/wit/wasi-timezone.wit.md b/proposals/clocks/wit/wasi-timezone.wit.md deleted file mode 100644 index ea0dfee26..000000000 --- a/proposals/clocks/wit/wasi-timezone.wit.md +++ /dev/null @@ -1,107 +0,0 @@ -# WASI Clocks Timezone API - -# `wasi-timezone` -```wit -default interface wasi-timezone { -``` - -## `datetime` -```wit -/// A time and date in seconds plus nanoseconds. -/// -/// TODO: Use the definition from the monotonic clock API instead of defining our own copy. -record datetime { - seconds: u64, - nanoseconds: u32, -} -``` - -## `timezone` -```wit -/// A timezone. -/// -/// In timezones that recognize daylight saving time, also known as daylight -/// time and summer time, the information returned from the functions varies -/// over time to reflect these adjustments. -// TODO(resource timezone {) -type timezone = u32 -``` - -## `display` -```wit - /// Return information needed to display the given `datetime`. This includes - /// the UTC offset, the time zone name, and a flag indicating whether - /// daylight saving time is active. - /// - /// If the timezone cannot be determined for the given `datetime`, return a - /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight - /// saving time. - display: func(this: timezone, when: datetime) -> timezone-display -``` - -## `utc-offset` -```wit - /// The same as `display`, but only return the UTC offset. - utc-offset: func(this: timezone, when: datetime) -> s32 -``` - -## `drop-timezone` -```wit -/// Dispose of the specified input-stream, after which it may no longer -/// be used. -// TODO(} /* resource timezone */) -drop-timezone: func(this: timezone) -``` - -## `timezone-display` -```wit -/// Information useful for displaying the timezone of a specific `datetime`. -/// -/// This information may vary within a single `timezone` to reflect daylight -/// saving time adjustments. -record timezone-display { -``` - -## `utc-offset` -```wit - /// The number of seconds difference between UTC time and the local time of - /// the timezone. - /// - /// The returned value will always be less than 86400 which is the number of - /// seconds in a day (24*60*60). - /// - /// In implementations that do not expose an actual time zone, this should - /// return 0. - utc-offset: s32, -``` - -## `name` -```wit - /// The abbreviated name of the timezone to display to a user. The name `UTC` - /// indicates Coordinated Universal Time. Otherwise, this should reference - /// local standards for the name of the time zone. - /// - /// In implementations that do not expose an actual time zone, this should be - /// the string `UTC`. - /// - /// In time zones that do not have an applicable name, a formatted - /// representation of the UTC offset may be returned, such as `-04:00`. - name: string, -``` - -## `in-daylight-saving-time` -```wit - /// Whether daylight saving time is active. - /// - /// In implementations that do not expose an actual time zone, this should - /// return false. - in-daylight-saving-time: bool, -``` - -```wit -} -``` - -```wit -} -``` diff --git a/proposals/clocks/wit/wasi-wall-clock.wit.md b/proposals/clocks/wit/wasi-wall-clock.wit.md deleted file mode 100644 index 84d5536ce..000000000 --- a/proposals/clocks/wit/wasi-wall-clock.wit.md +++ /dev/null @@ -1,72 +0,0 @@ -# WASI Wall Clock API - -## `wasi-wall-clock` -```wit -/// WASI Wall Clock is a clock API intended to let users query the current -/// time. The name "wall" makes an analogy to a "clock on the wall", which -/// is not necessarily monotonic as it may be reset. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -default interface wasi-wall-clock { -``` - -## `datetime` -```wit -/// A time and date in seconds plus nanoseconds. -record datetime { - seconds: u64, - nanoseconds: u32, -} -``` - -## `wall-clock` -```wit -/// A wall clock is a clock which measures the date and time according to some -/// external reference. -/// -/// External references may be reset, so this clock is not necessarily -/// monotonic, making it unsuitable for measuring elapsed time. -/// -/// It is intended for reporting the current date and time for humans. -// TODO(resource wall-clock {) -type wall-clock = u32 -``` - -## `now` -```wit -/// Read the current value of the clock. -/// -/// This clock is not monotonic, therefore calling this function repeatedly will -/// not necessarily produce a sequence of non-decreasing values. -/// -/// The returned timestamps represent the number of seconds since -/// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], also -/// known as [Unix Time]. -/// -/// The nanoseconds field of the output is always less than 1000000000. -/// -/// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 -/// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time -now: func(this: wall-clock) -> datetime -``` - -## `resolution` -```wit -/// Query the resolution of the clock. -/// -/// The nanoseconds field of the output is always less than 1000000000. -resolution: func(this: wall-clock) -> datetime -``` - -## `drop-wall-clock` -```wit -/// Dispose of the specified `wall-clock`, after which it may no longer -/// be used. -// TODO(} /* resource wall-clock */) -drop-wall-clock: func(this: wall-clock) -``` - -```wit -} -``` diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit new file mode 100644 index 000000000..e0eb0835e --- /dev/null +++ b/proposals/clocks/wit/world.wit @@ -0,0 +1,7 @@ +default world example-world { + import monotonic-clock: pkg.monotonic-clock + import wall-clock: pkg.wall-clock + import timezone: pkg.timezone + import instance-monotonic-clock: pkg.instance-monotonic-clock + import instance-wall-clock: pkg.instance-wall-clock +} diff --git a/proposals/clocks/wit/world.wit.md b/proposals/clocks/wit/world.wit.md deleted file mode 100644 index 90e15cb33..000000000 --- a/proposals/clocks/wit/world.wit.md +++ /dev/null @@ -1,12 +0,0 @@ -This file contains a world that imports all interfaces in this proposal. Its -primary purpose is to allow unified documentation to be easily generated for -the whole proposal. - -```wit -default world wasi-clocks { - import wasi-monotonic-clock: pkg.wasi-monotonic-clock - import wasi-wall-clock: pkg.wasi-wall-clock - import wasi-timezone: pkg.wasi-timezone - import wasi-default-clocks: pkg.wasi-default-clocks -} -``` From 63fa25df957744eadedc0fa656509f6b5120c11b Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 23 Feb 2023 18:22:51 -0600 Subject: [PATCH 1055/1772] Update deps/io from wasm-io and make outgoing-handler's initial result async --- proposals/http/wit/deps/io/poll.wit | 39 +++++++++ proposals/http/wit/deps/io/streams.wit | 101 +++++++++++++----------- proposals/http/wit/outgoing-handler.wit | 4 +- proposals/http/wit/types.wit | 17 +++- 4 files changed, 112 insertions(+), 49 deletions(-) create mode 100644 proposals/http/wit/deps/io/poll.wit diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/io/poll.wit new file mode 100644 index 000000000..3b2c14f83 --- /dev/null +++ b/proposals/http/wit/deps/io/poll.wit @@ -0,0 +1,39 @@ +/// +/// WASI Poll is a poll API intended to let users wait for I/O events on +/// multiple handles at once. +default interface wasi-poll { + /// A "pollable" handle. + /// + /// This is conceptually represents a `stream<_, _>`, or in other words, + /// a stream that one can wait on, repeatedly, but which does not itself + /// produce any data. It's temporary scaffolding until component-model's + /// async features are ready. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// `pollable` lifetimes are not automatically managed. Users must ensure + /// that they do not outlive the resource they reference. + // TODO(resource pollable {) + type pollable = u32 + + /// Dispose of the specified `pollable`, after which it may no longer be used. + // TODO(} /* resource pollable */) + drop-pollable: func(this: pollable) + + /// Poll for completion on a set of pollables. + /// + /// The "oneoff" in the name refers to the fact that this function must do a + /// linear scan through the entire list of subscriptions, which may be + /// inefficient if the number is large and the same subscriptions are used + /// many times. In the future, this is expected to be obsoleted by the + /// component model async proposal, which will include a scalable waiting + /// facility. + /// + /// Note that the return type would ideally be `list`, but that would + /// be more difficult to polyfill given the current state of `wit-bindgen`. + /// See + /// for details. For now, we use zero to mean "not ready" and non-zero to + /// mean "ready". + poll-oneoff: func(in: list) -> list +} diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index 4e18e08c3..599645256 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -1,18 +1,26 @@ +/// WASI I/O is an I/O abstraction API which is currently focused on providing +/// stream types. +/// +/// In the future, the component model is expected to add built-in stream types; +/// when it does, they are expected to subsume this API. default interface streams { + use pkg.poll.{pollable} + /// An error type returned from a stream operation. Currently this /// doesn't provide any additional information. record stream-error {} - + /// An input bytestream. In the future, this will be replaced by handle /// types. - /// - /// This conceptually represents a `stream`. It's temporary - /// scaffolding until component-model's async features are ready. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. + /// + /// This conceptually represents a `stream`. It's temporary + /// scaffolding until component-model's async features are ready. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + // TODO(resource input-stream {) type input-stream = u32 - + /// Read bytes from a stream. /// /// This function returns a list of bytes containing the data that was @@ -32,12 +40,11 @@ default interface streams { /// a buffer as large as that would imply. /// FIXME: describe what happens if allocation fails. read: func( - /// The stream to read from - src: input-stream, + this: input-stream, /// The maximum number of bytes to read len: u64 ) -> result, bool>, stream-error> - + /// Skip bytes from a stream. /// /// This is similar to the `read` function, but avoids copying the @@ -51,59 +58,63 @@ default interface streams { /// indicating whether the end of the stream was reached. The returned /// value will be at most `len`; it may be less. skip: func( - /// The stream to skip in - src: input-stream, + this: input-stream, /// The maximum number of bytes to skip. len: u64, ) -> result, stream-error> - + + /// Create a `pollable` which will resolve once either the specified stream has bytes + /// available to read or the other end of the stream has been closed. + subscribe-to-input-stream: func(this: input-stream) -> pollable + + /// Dispose of the specified `input-stream`, after which it may no longer + /// be used. + // TODO(} /* resource input-stream */) + drop-input-stream: func(this: input-stream) + /// An output bytestream. In the future, this will be replaced by handle /// types. - /// - /// This conceptually represents a `stream`. It's temporary - /// scaffolding until component-model's async features are ready. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. + /// + /// This conceptually represents a `stream`. It's temporary + /// scaffolding until component-model's async features are ready. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + // TODO(resource output-stream {) type output-stream = u32 - + /// Write bytes to a stream. /// /// This function returns a `u64` indicating the number of bytes from /// `buf` that were written; it may be less than the full list. write: func( - /// The stream to write to - dst: output-stream, + this: output-stream, /// Data to write buf: list ) -> result - - /// Write a single byte multiple times to a stream. - /// - /// This function returns a `u64` indicating the number of copies of - /// `byte` that were written; it may be less than `len`. - write-repeated: func( - /// The stream to write to - dst: output-stream, - /// The byte to write - byte: u8, - /// The number of times to write it + + /// Write multiple zero bytes to a stream. + /// + /// This function returns a `u64` indicating the number of zero bytes + /// that were written; it may be less than `len`. + write-zeroes: func( + this: output-stream, + /// The number of zero bytes to write len: u64 ) -> result - + /// Read from one stream and write to another. /// /// This function returns the number of bytes transferred; it may be less /// than `len`. splice: func( - /// The stream to write to - dst: output-stream, + this: output-stream, /// The stream to read from src: input-stream, /// The number of bytes to splice len: u64, ) -> result, stream-error> - + /// Forward the entire contents of an input stream to an output stream. /// /// This function repeatedly reads from the input stream and writes @@ -112,17 +123,17 @@ default interface streams { /// /// This function returns the number of bytes transferred. forward: func( - /// The stream to write to - dst: output-stream, + this: output-stream, /// The stream to read from src: input-stream ) -> result - /// Dispose of the specified input-stream, after which it may no longer - /// be used. - drop-input-stream: func(f: input-stream) + /// Create a `pollable` which will resolve once either the specified stream is ready + /// to accept bytes or the other end of the stream has been closed. + subscribe-to-output-stream: func(this: output-stream) -> pollable - /// Dispose of the specified output-stream, after which it may no longer + /// Dispose of the specified `output-stream`, after which it may no longer /// be used. - drop-output-stream: func(f: output-stream) + // TODO(} /* resource output-stream */) + drop-output-stream: func(this: output-stream) } diff --git a/proposals/http/wit/outgoing-handler.wit b/proposals/http/wit/outgoing-handler.wit index b0d5738ec..b12481f28 100644 --- a/proposals/http/wit/outgoing-handler.wit +++ b/proposals/http/wit/outgoing-handler.wit @@ -6,10 +6,10 @@ // that takes a `request` parameter and returns a `response` result. // default interface outgoing-handler { - use pkg.types.{outgoing-request, incoming-response, error} + use pkg.types.{outgoing-request, future-incoming-response} // The parameter and result types of the `handle` function allow the caller // to concurrently stream the bodies of the outgoing request and the incoming // response. - handle: func(request: outgoing-request) -> result + handle: func(request: outgoing-request) -> future-incoming-response } diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 1d610f9bc..2448ea54e 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -2,6 +2,8 @@ // define the HTTP resource types and operations used by the component's // imported and exported interfaces. default interface types { + use io.streams.{input-stream, output-stream} + use io.poll.{pollable} // This type corresponds to HTTP standard Methods. variant method { @@ -61,7 +63,6 @@ default interface types { // resource types defined by `wasi:io/streams`. The `finish-` functions // emulate the stream's result value and MUST be called exactly once after // the final read/write from/to the stream before dropping the stream. - use io.streams.{input-stream, output-stream} type incoming-body = input-stream type outgoing-body = output-stream finish-incoming-body: func(body: incoming-body) -> option @@ -95,7 +96,7 @@ default interface types { outgoing-request-write-body: func(request: outgoing-request) -> result // The following block defines a special resource type used by the - // `wasi:http/outgoing-handler` interface. When resource types are added, this + // `wasi:http/incoming-handler` interface. When resource types are added, this // block can be replaced by a proper `resource response-outparam { ... }` // definition. Later, with Preview3, the need for an outparam goes away entirely // (the `wasi:http/handler` interface used for both incoming and outgoing can @@ -126,4 +127,16 @@ default interface types { headers: headers ) -> outgoing-response outgoing-response-write-body: func(response: outgoing-response) -> result + + // The following block defines a special resource type used by the + // `wasi:http/outgoing-handler` interface to emulate + // `future>` in advance of Preview3. Given a + // `future-incoming-response`, the client can call the non-blocking `get` + // method to get the result if it is available. If the result is not available, + // the client can call `listen` to get a `pollable` that can be passed to + // `io.poll.poll-oneoff`. + type future-incoming-response = u32 + drop-future-incoming-response: func(f: future-incoming-response) + future-incoming-response-get: func(f: future-incoming-response) -> option> + listen-to-future-incoming-response: func(f: future-incoming-response) -> pollable } From 5732254984483e10c49aa1ae8ad70b0ab331f418 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 23 Feb 2023 19:23:52 -0600 Subject: [PATCH 1056/1772] Add timeout options to the incoming and outgoing request interfaces --- proposals/http/wit/incoming-handler.wit | 8 ++++++-- proposals/http/wit/outgoing-handler.wit | 7 +++++-- proposals/http/wit/types.wit | 16 ++++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/proposals/http/wit/incoming-handler.wit b/proposals/http/wit/incoming-handler.wit index 47fbe89e2..210c2c4e3 100644 --- a/proposals/http/wit/incoming-handler.wit +++ b/proposals/http/wit/incoming-handler.wit @@ -7,7 +7,7 @@ // that takes a `request` parameter and returns a `response` result. // default interface incoming-handler { - use pkg.types.{incoming-request, response-outparam} + use pkg.types.{incoming-request, request-options, response-outparam} // The `handle` function takes an outparam instead of returning its response // so that the component may stream its response while streaming any other @@ -17,5 +17,9 @@ default interface incoming-handler { // output stream. While this post-response execution is taken off the // critical path, since there is no return value, there is no way to report // its success or failure. - handle: func(request: incoming-request, response-out: response-outparam) + handle: func( + request: incoming-request, + response-out: response-outparam, + options: option + ) } diff --git a/proposals/http/wit/outgoing-handler.wit b/proposals/http/wit/outgoing-handler.wit index b12481f28..abe812ffa 100644 --- a/proposals/http/wit/outgoing-handler.wit +++ b/proposals/http/wit/outgoing-handler.wit @@ -6,10 +6,13 @@ // that takes a `request` parameter and returns a `response` result. // default interface outgoing-handler { - use pkg.types.{outgoing-request, future-incoming-response} + use pkg.types.{outgoing-request, request-options, future-incoming-response} // The parameter and result types of the `handle` function allow the caller // to concurrently stream the bodies of the outgoing request and the incoming // response. - handle: func(request: outgoing-request) -> future-incoming-response + handle: func( + request: outgoing-request, + options: option + ) -> future-incoming-response } diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 2448ea54e..93add6205 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -95,6 +95,22 @@ default interface types { ) -> outgoing-request outgoing-request-write-body: func(request: outgoing-request) -> result + // Additional optional parameters that can be set when making a request. + record request-options { + // The following timeouts are specific to the HTTP protocol and work + // independently of the overall timeouts passed to `io.poll.poll-oneoff`. + + // The timeout for the initial connect. + connect-timeout-nanos: option, + + // The timeout for receiving the first byte of the response body. + first-byte-timeout-ns: option, + + // The timeout for receiving the next chunk of bytes in the response body + // stream. + between-bytes-timeout-ms: option + } + // The following block defines a special resource type used by the // `wasi:http/incoming-handler` interface. When resource types are added, this // block can be replaced by a proper `resource response-outparam { ... }` From 4b6146052c2d8598f9a47dad13787a7847f8bc20 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 23 Feb 2023 19:25:23 -0600 Subject: [PATCH 1057/1772] Remove request options from incoming-handler for now --- proposals/http/wit/incoming-handler.wit | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/proposals/http/wit/incoming-handler.wit b/proposals/http/wit/incoming-handler.wit index 210c2c4e3..1ecff0aa5 100644 --- a/proposals/http/wit/incoming-handler.wit +++ b/proposals/http/wit/incoming-handler.wit @@ -7,7 +7,7 @@ // that takes a `request` parameter and returns a `response` result. // default interface incoming-handler { - use pkg.types.{incoming-request, request-options, response-outparam} + use pkg.types.{incoming-request, response-outparam} // The `handle` function takes an outparam instead of returning its response // so that the component may stream its response while streaming any other @@ -19,7 +19,6 @@ default interface incoming-handler { // its success or failure. handle: func( request: incoming-request, - response-out: response-outparam, - options: option + response-out: response-outparam ) } From 54b27dbf7c29f2eeeebdb70f73548fd7e688154d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Feb 2023 12:59:22 -0600 Subject: [PATCH 1058/1772] Make input-stream and output-stream always non-blocking. (#24) Specify that reads and writes are always non-blocking, to the extent practical on underlying platforms. This is closer to how the future builtin `stream` type will work, and should be more convenient for users doing async I/O. To do blocking reads or writes, use a `poll_oneoff` to wait if an initial read or write didn't transmit any data. The first example in the README.md gives an example of how to do this. It also eliminates the need for a `would-block` error, as `would-block` can be translated to a result of 0 bytes being transmitted. As such, this is an alternative to #23. --- proposals/io/README.md | 31 ++++++++++++++++++++++++++++--- proposals/io/wasi-io.html | 17 +++++++++++++++++ proposals/io/wasi-io.md | 21 +++++++++++++++++++++ proposals/io/wit/wasi-io.wit.md | 21 +++++++++++++++++++++ 4 files changed, 87 insertions(+), 3 deletions(-) diff --git a/proposals/io/README.md b/proposals/io/README.md index 11fb122f1..40700bd54 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -60,11 +60,29 @@ types, `input-stream`, and `output-stream`, which support `read` and ```rust fn copy_data(input: InputStream, output: OutputStream) -> Result<(), StreamError> { const BUFFER_LEN: usize = 4096; + + let wait_input = [subscribe_to_input_stream(input)]; + let wait_output = [subscribe_to_output_stream(output)]; + loop { - let (data, eos) = input.read(BUFFER_LEN)?; + let (mut data, mut eos) = input.read(BUFFER_LEN)?; + + // If we didn't get any data promptly, wait for it. + if data.len() == 0 { + let _ = poll_oneoff(&wait_input[..]); + (data, eos) = input.read(BUFFER_LEN)?; + } + let mut remaining = &data[..]; while !remaining.is_empty() { - let num_written = output.write(remaining)?; + let mut num_written = output.write(remaining)?; + + // If we didn't put any data promptly, wait for it. + if num_written == 0 { + let _ = poll_oneoff(&wait_output[..]); + num_written = output.write(remaining)?; + } + remaining = &remaining[num_written..]; } if eos { @@ -80,11 +98,18 @@ types, `input-stream`, and `output-stream`, which support `read` and ```rust fn copy_data(input: InputStream, output: OutputStream) -> Result<(), StreamError> { + let wait_input = [subscribe_to_input_stream(input)]; + loop { - let (_num_copied, eos) = output.splice(input, u64::MAX)?; + let (num_copied, eos) = output.splice(input, u64::MAX)?; if eos { break; } + + // If we didn't get any data promptly, wait for it. + if num_copied == 0 { + let _ = poll_oneoff(&wait_input[..]); + } } Ok(()) } diff --git a/proposals/io/wasi-io.html b/proposals/io/wasi-io.html index 3a33f0876..1249bb03f 100644 --- a/proposals/io/wasi-io.html +++ b/proposals/io/wasi-io.html @@ -55,6 +55,12 @@

    types.

    This conceptually represents a stream<u8, _>. It's temporary scaffolding until component-model's async features are ready.

    +

    output-streams are non-blocking to the extent practical on +underlying platforms. Except where specified otherwise, I/O operations also +always return promptly, after the number of bytes that can be written +promptly, which could even be zero. To wait for the stream to be ready to +accept data, the subscribe-to-output-stream function to obtain a +pollable which can be polled for using wasi_poll.

    And at present, it is a u32 instead of being an actual handle, until the wit-bindgen implementation of handles and resources is ready.

    Size: 4, Alignment: 4

    @@ -63,6 +69,12 @@

    This conceptually represents a stream<u8, _>. It's temporary scaffolding until component-model's async features are ready.

    +

    input-streams are non-blocking to the extent practical on underlying +platforms. I/O operations always return promptly; if fewer bytes are +promptly available than requested, they return the number of bytes promptly +available, which could even be zero. To wait for data to be available, +use the subscribe-to-input-stream function to obtain a pollable which +can be polled for using wasi_poll.

    And at present, it is a u32 instead of being an actual handle, until the wit-bindgen implementation of handles and resources is ready.

    Size: 4, Alignment: 4

    @@ -165,6 +177,8 @@

    spliceRead from one stream and write to another.

    This function returns the number of bytes transferred; it may be less than len.

    +

    Unlike other I/O functions, this function blocks until all the data +read from the input stream has been written to the output stream.

    Params
    • this: output-stream
    • @@ -181,6 +195,9 @@

      forwardThis function repeatedly reads from the input stream and writes the data to the output stream, until the end of the input stream is reached, or an error is encountered.

      +

      Unlike other I/O functions, this function blocks until the end +of the input stream is seen and all the data has been written to +the output stream.

      This function returns the number of bytes transferred.

      Params
        diff --git a/proposals/io/wasi-io.md b/proposals/io/wasi-io.md index 4382dce7c..72f5a7204 100644 --- a/proposals/io/wasi-io.md +++ b/proposals/io/wasi-io.md @@ -81,6 +81,13 @@ types. This conceptually represents a `stream`. It's temporary scaffolding until component-model's async features are ready. +`output-stream`s are *non-blocking* to the extent practical on +underlying platforms. Except where specified otherwise, I/O operations also +always return promptly, after the number of bytes that can be written +promptly, which could even be zero. To wait for the stream to be ready to +accept data, the `subscribe-to-output-stream` function to obtain a +`pollable` which can be polled for using `wasi_poll`. + And at present, it is a `u32` instead of being an actual handle, until the wit-bindgen implementation of handles and resources is ready. @@ -94,6 +101,13 @@ types. This conceptually represents a `stream`. It's temporary scaffolding until component-model's async features are ready. +`input-stream`s are *non-blocking* to the extent practical on underlying +platforms. I/O operations always return promptly; if fewer bytes are +promptly available than requested, they return the number of bytes promptly +available, which could even be zero. To wait for data to be available, +use the `subscribe-to-input-stream` function to obtain a `pollable` which +can be polled for using `wasi_poll`. + And at present, it is a `u32` instead of being an actual handle, until the wit-bindgen implementation of handles and resources is ready. @@ -218,6 +232,9 @@ Read from one stream and write to another. This function returns the number of bytes transferred; it may be less than `len`. + +Unlike other I/O functions, this function blocks until all the data +read from the input stream has been written to the output stream. ##### Params - `this`: [`output-stream`](#output_stream) @@ -237,6 +254,10 @@ This function repeatedly reads from the input stream and writes the data to the output stream, until the end of the input stream is reached, or an error is encountered. +Unlike other I/O functions, this function blocks until the end +of the input stream is seen and all the data has been written to +the output stream. + This function returns the number of bytes transferred. ##### Params diff --git a/proposals/io/wit/wasi-io.wit.md b/proposals/io/wit/wasi-io.wit.md index 24566b803..9243a8285 100644 --- a/proposals/io/wit/wasi-io.wit.md +++ b/proposals/io/wit/wasi-io.wit.md @@ -29,6 +29,13 @@ record stream-error {} /// This conceptually represents a `stream`. It's temporary /// scaffolding until component-model's async features are ready. /// +/// `input-stream`s are *non-blocking* to the extent practical on underlying +/// platforms. I/O operations always return promptly; if fewer bytes are +/// promptly available than requested, they return the number of bytes promptly +/// available, which could even be zero. To wait for data to be available, +/// use the `subscribe-to-input-stream` function to obtain a `pollable` which +/// can be polled for using `wasi_poll`. +/// /// And at present, it is a `u32` instead of being an actual handle, until /// the wit-bindgen implementation of handles and resources is ready. // TODO(resource input-stream {) @@ -106,6 +113,13 @@ drop-input-stream: func(this: input-stream) /// This conceptually represents a `stream`. It's temporary /// scaffolding until component-model's async features are ready. /// +/// `output-stream`s are *non-blocking* to the extent practical on +/// underlying platforms. Except where specified otherwise, I/O operations also +/// always return promptly, after the number of bytes that can be written +/// promptly, which could even be zero. To wait for the stream to be ready to +/// accept data, the `subscribe-to-output-stream` function to obtain a +/// `pollable` which can be polled for using `wasi_poll`. +/// /// And at present, it is a `u32` instead of being an actual handle, until /// the wit-bindgen implementation of handles and resources is ready. // TODO(resource output-stream {) @@ -144,6 +158,9 @@ type output-stream = u32 /// /// This function returns the number of bytes transferred; it may be less /// than `len`. + /// + /// Unlike other I/O functions, this function blocks until all the data + /// read from the input stream has been written to the output stream. splice: func( this: output-stream, /// The stream to read from @@ -161,6 +178,10 @@ type output-stream = u32 /// the data to the output stream, until the end of the input stream /// is reached, or an error is encountered. /// + /// Unlike other I/O functions, this function blocks until the end + /// of the input stream is seen and all the data has been written to + /// the output stream. + /// /// This function returns the number of bytes transferred. forward: func( this: output-stream, From 7c6e32dc24c87b1c40f987a5f41d0ed60b54c31e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Feb 2023 11:16:23 -0800 Subject: [PATCH 1059/1772] Initial commit --- proposals/cli/.github/workflows/main.yml | 16 +++ proposals/cli/README.md | 112 ++++++++++++++++++ proposals/cli/example-world.md | 72 +++++++++++ proposals/cli/test/README.md | 11 ++ .../cli/wit/deps/example-dep/example-api.wit | 6 + proposals/cli/wit/example.wit | 59 +++++++++ proposals/cli/wit/world.wit | 10 ++ 7 files changed, 286 insertions(+) create mode 100644 proposals/cli/.github/workflows/main.yml create mode 100644 proposals/cli/README.md create mode 100644 proposals/cli/example-world.md create mode 100644 proposals/cli/test/README.md create mode 100644 proposals/cli/wit/deps/example-dep/example-api.wit create mode 100644 proposals/cli/wit/example.wit create mode 100644 proposals/cli/wit/world.wit diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml new file mode 100644 index 000000000..ad1997c51 --- /dev/null +++ b/proposals/cli/.github/workflows/main.yml @@ -0,0 +1,16 @@ +name: CI +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + abi-up-to-date: + name: Check ABI files are up-to-date + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: WebAssembly/wit-abi-up-to-date@v12 + with: + wit-abi-tag: wit-abi-0.10.0 diff --git a/proposals/cli/README.md b/proposals/cli/README.md new file mode 100644 index 000000000..733036b3d --- /dev/null +++ b/proposals/cli/README.md @@ -0,0 +1,112 @@ +# [Example WASI proposal] + +This template can be used to start a new proposal, which can then be proposed in the WASI Subgroup meetings. + +The sections below are recommended. However, every proposal is different, and the community can help you flesh out the proposal, so don't block on having something filled in for each one of them. + +Thank you to the W3C Privacy CG for the [inspiration](https://github.com/privacycg/template)! + +# [Title] + +A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. + +### Current Phase + +[Fill in the current phase, e.g. Phase 1] + +### Champions + +- [Champion 1] +- [Champion 2] +- [etc.] + +### Phase 4 Advancement Criteria + +TODO before entering Phase 2. + +## Table of Contents [if the explainer is longer than one printed page] + +- [Introduction](#introduction) +- [Goals [or Motivating Use Cases, or Scenarios]](#goals-or-motivating-use-cases-or-scenarios) +- [Non-goals](#non-goals) +- [API walk-through](#api-walk-through) + - [Use case 1](#use-case-1) + - [Use case 2](#use-case-2) +- [Detailed design discussion](#detailed-design-discussion) + - [[Tricky design choice 1]](#tricky-design-choice-1) + - [[Tricky design choice 2]](#tricky-design-choice-2) +- [Considered alternatives](#considered-alternatives) + - [[Alternative 1]](#alternative-1) + - [[Alternative 2]](#alternative-2) +- [Stakeholder Interest & Feedback](#stakeholder-interest--feedback) +- [References & acknowledgements](#references--acknowledgements) + +### Introduction + +[The "executive summary" or "abstract". Explain in a few sentences what the goals of the project are, and a brief overview of how the solution works. This should be no more than 1-2 paragraphs.] + +### Goals [or Motivating Use Cases, or Scenarios] + +[What is the end-user need which this project aims to address?] + +### Non-goals + +[If there are "adjacent" goals which may appear to be in scope but aren't, enumerate them here. This section may be fleshed out as your design progresses and you encounter necessary technical and other trade-offs.] + +### API walk-through + +The full API documentation can be found [here](wasi-proposal-template.md). + +[Walk through of how someone would use this API.] + +#### [Use case 1] + +[Provide example code snippets and diagrams explaining how the API would be used to solve the given problem] + +#### [Use case 2] + +[etc.] + +### Detailed design discussion + +[This section should mostly refer to the .wit.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] + +#### [Tricky design choice #1] + +[Talk through the tradeoffs in coming to the specific design point you want to make.] + +``` +// Illustrated with example code. +``` + +[This may be an open question, in which case you should link to any active discussion threads.] + +#### [Tricky design choice 2] + +[etc.] + +### Considered alternatives + +[This section is not required if you already covered considered alternatives in the design discussion above.] + +#### [Alternative 1] + +[Describe an alternative which was considered, and why you decided against it.] + +#### [Alternative 2] + +[etc.] + +### Stakeholder Interest & Feedback + +TODO before entering Phase 3. + +[This should include a list of implementers who have expressed interest in implementing the proposal] + +### References & acknowledgements + +Many thanks for valuable feedback and advice from: + +- [Person 1] +- [Person 2] +- [etc.] diff --git a/proposals/cli/example-world.md b/proposals/cli/example-world.md new file mode 100644 index 000000000..c58d36466 --- /dev/null +++ b/proposals/cli/example-world.md @@ -0,0 +1,72 @@ +

        World example-world

        + +

        Import interface example-dep-interface

        +
        +

        Types

        +

        type example-dep-type

        +

        u32

        +

        +## Import interface example-interface +

        Short interface description.

        +

        Explanation for developers using the interface API. It should include an +overview of the API as a whole as well as call out notable items in it, +for example example-api-type and example-api-function.

        +
        +

        Types

        +

        type example-dep-type

        +

        example-dep-type

        +

        +#### `record example-api-type` +

        Short type description

        +

        Explanation for developers using this type. It may be useful to give +some examples of places in the API where the type is used, such as in +the arguments and return type of example-api-function.

        +
        +Detailed specification +More rigorous specification details for implementers go here, if needed. +The intention is to keep the developer-oriented docs focused on things that +most developers will need to be aware of, while putting bulkier descriptions +of precise behavior here. +
        +
        Record Fields
        +
          +
        • +

          field0: u64

          +

          A description of a field. +

        • +
        • +

          field1: string

          +

          A description of another field. +

        • +
        +
        +

        Functions

        +

        example-api-function: func

        +

        Short function description

        +

        Explanation for developers using the API. This should describe the +arguments which in this function are arg0, arg1, and arg2, and the +return value.

        +
        +Detailed specification +Similar to the details section above, this is meant for more rigorous +specification details for implementors. This may explain what a compliant +implementation MUST do, such as never returning an earlier result from a +later call, for example. +
        +
        Params
        + +
        Return values
        + diff --git a/proposals/cli/test/README.md b/proposals/cli/test/README.md new file mode 100644 index 000000000..c274acd9d --- /dev/null +++ b/proposals/cli/test/README.md @@ -0,0 +1,11 @@ +# Testing guidelines + +TK fill in testing guidelines + +## Installing the tools + +TK fill in instructions + +## Running the tests + +TK fill in instructions diff --git a/proposals/cli/wit/deps/example-dep/example-api.wit b/proposals/cli/wit/deps/example-dep/example-api.wit new file mode 100644 index 000000000..60da3235d --- /dev/null +++ b/proposals/cli/wit/deps/example-dep/example-api.wit @@ -0,0 +1,6 @@ +// An example dependency, showing how these look. Actual proposals should +// delete this file and add their actual dependencies in the `deps` directory. + +interface example-dep-interface { + type example-dep-type = u32 +} diff --git a/proposals/cli/wit/example.wit b/proposals/cli/wit/example.wit new file mode 100644 index 000000000..04b038198 --- /dev/null +++ b/proposals/cli/wit/example.wit @@ -0,0 +1,59 @@ +// Instructions for filling in this file: +// +// - Delete all these `//` comments, up to the first `///` comment. +// +// - Replace the remaining contents below with [Wit] code describing +// `interface`s and/or `world`s, using the same formatting style. +// +// If you want to include examples of the API in use, these should be in the +// README.md at the root of the repository and linked to from this file. +// +// [Wit]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md + +/// Short interface description. +/// +/// Explanation for developers using the interface API. It should include an +/// overview of the API as a whole as well as call out notable items in it, +/// for example `example-api-type` and `example-api-function`. +default interface example-interface { + use example-dep.example-api.example-dep-interface.{example-dep-type} + + /// Short type description + /// + /// Explanation for developers using this type. It may be useful to give + /// some examples of places in the API where the type is used, such as in + /// the arguments and return type of `example-api-function`. + /// + ///
        + /// Detailed specification + /// More rigorous specification details for implementers go here, if needed. + /// The intention is to keep the developer-oriented docs focused on things that + /// most developers will need to be aware of, while putting bulkier descriptions + /// of precise behavior here. + ///
        + record example-api-type { + /// A description of a field. + field0: u64, + /// A description of another field. + field1: string, + } + + /// Short function description + /// + /// Explanation for developers using the API. This should describe the + /// arguments which in this function are `arg0`, `arg1`, and `arg2`, and the + /// return value. + /// + ///
        + /// Detailed specification + /// Similar to the details section above, this is meant for more rigorous + /// specification details for implementors. This may explain what a compliant + /// implementation MUST do, such as never returning an earlier result from a + /// later call, for example. + ///
        + example-api-function: func( + arg0: example-api-type, + arg1: string, + arg2: example-dep-type, + ) -> result +} diff --git a/proposals/cli/wit/world.wit b/proposals/cli/wit/world.wit new file mode 100644 index 000000000..17821ee6e --- /dev/null +++ b/proposals/cli/wit/world.wit @@ -0,0 +1,10 @@ +// If the repository defines `interface`s, this file can define a minimal world +// which contains those interfaces, to allow documentation to be generated for +// them. +// +// Proposals should remove these `//` commments, and edit the `world` name and +// imports below to pull in their own `interface`s. + +default world example-world { + import example-interface: pkg.example.example-interface +} From 40671b81b33e52f98f02d2544e893391a843b677 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Feb 2023 13:32:52 -0600 Subject: [PATCH 1060/1772] Update to the latest wasi-proposal-repo format. (#26) This notably converts the `.wit.md` files to `.wit`. --- proposals/io/.github/workflows/main.yml | 5 +- proposals/io/example-world.md | 242 +++++++++++++++ proposals/io/wasi-io.html | 230 -------------- proposals/io/wasi-io.md | 292 ------------------ proposals/io/wit/deps/poll/poll.wit | 39 +++ .../io/wit/{wasi-io.wit.md => streams.wit} | 157 ++++------ proposals/io/wit/world.wit | 3 + proposals/io/wit/world.wit.md | 9 - 8 files changed, 340 insertions(+), 637 deletions(-) create mode 100644 proposals/io/example-world.md delete mode 100644 proposals/io/wasi-io.html delete mode 100644 proposals/io/wasi-io.md create mode 100644 proposals/io/wit/deps/poll/poll.wit rename proposals/io/wit/{wasi-io.wit.md => streams.wit} (55%) create mode 100644 proposals/io/wit/world.wit delete mode 100644 proposals/io/wit/world.wit.md diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index d1a287fc4..ad1997c51 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -11,7 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - run: curl https://raw.githubusercontent.com/WebAssembly/wasi-poll/1bafe7b4a16848a61dd81595ac7f67733561112f/wit/wasi-poll.wit.md > wit/wasi-poll.wit.md - - uses: WebAssembly/wit-abi-up-to-date@v10 + - uses: WebAssembly/wit-abi-up-to-date@v12 with: - wit-abi-tag: wit-abi-0.8.0 + wit-abi-tag: wit-abi-0.10.0 diff --git a/proposals/io/example-world.md b/proposals/io/example-world.md new file mode 100644 index 000000000..a5e275ce5 --- /dev/null +++ b/proposals/io/example-world.md @@ -0,0 +1,242 @@ +

        World example-world

        + +

        Import interface poll

        +

        A poll API intended to let users wait for I/O events on multiple handles +at once.

        +
        +

        Types

        +

        type pollable

        +

        u32

        +

        A "pollable" handle. +

        This is conceptually represents a stream<_, _>, or in other words, +a stream that one can wait on, repeatedly, but which does not itself +produce any data. It's temporary scaffolding until component-model's +async features are ready.

        +

        And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

        +

        pollable lifetimes are not automatically managed. Users must ensure +that they do not outlive the resource they reference.

        +

        This represents a resource.

        +
        +

        Functions

        +

        drop-pollable: func

        +

        Dispose of the specified pollable, after which it may no longer +be used.

        +
        Params
        + +

        poll-oneoff: func

        +

        Poll for completion on a set of pollables.

        +

        The "oneoff" in the name refers to the fact that this function must do a +linear scan through the entire list of subscriptions, which may be +inefficient if the number is large and the same subscriptions are used +many times. In the future, this is expected to be obsoleted by the +component model async proposal, which will include a scalable waiting +facility.

        +

        Note that the return type would ideally be list<bool>, but that would +be more difficult to polyfill given the current state of wit-bindgen. +See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 +for details. For now, we use zero to mean "not ready" and non-zero to +mean "ready".

        +
        Params
        + +
        Return values
        +
          +
        • list<u8>
        • +
        +

        Import interface streams

        +

        WASI I/O is an I/O abstraction API which is currently focused on providing +stream types.

        +

        In the future, the component model is expected to add built-in stream types; +when it does, they are expected to subsume this API.

        +
        +

        Types

        +

        type pollable

        +

        pollable

        +

        +#### `record stream-error` +

        An error type returned from a stream operation. Currently this +doesn't provide any additional information.

        +
        Record Fields
        +

        type output-stream

        +

        u32

        +

        An output bytestream. In the future, this will be replaced by handle +types. +

        This conceptually represents a stream<u8, _>. It's temporary +scaffolding until component-model's async features are ready.

        +

        output-streams are non-blocking to the extent practical on +underlying platforms. Except where specified otherwise, I/O operations also +always return promptly, after the number of bytes that can be written +promptly, which could even be zero. To wait for the stream to be ready to +accept data, the subscribe-to-output-stream function to obtain a +pollable which can be polled for using wasi_poll.

        +

        And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

        +

        This represents a resource.

        +

        type input-stream

        +

        u32

        +

        An input bytestream. In the future, this will be replaced by handle +types. +

        This conceptually represents a stream<u8, _>. It's temporary +scaffolding until component-model's async features are ready.

        +

        input-streams are non-blocking to the extent practical on underlying +platforms. I/O operations always return promptly; if fewer bytes are +promptly available than requested, they return the number of bytes promptly +available, which could even be zero. To wait for data to be available, +use the subscribe-to-input-stream function to obtain a pollable which +can be polled for using wasi_poll.

        +

        And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

        +

        This represents a resource.

        +
        +

        Functions

        +

        read: func

        +

        Read bytes from a stream.

        +

        This function returns a list of bytes containing the data that was +read, along with a bool indicating whether the end of the stream +was reached. The returned list will contain up to len bytes; it +may return fewer than requested, but not more.

        +

        Once a stream has reached the end, subsequent calls to read or +skip will always report end-of-stream rather than producing more +data.

        +

        If len is 0, it represents a request to read 0 bytes, which should +always succeed, assuming the stream hasn't reached its end yet, and +return an empty list.

        +

        The len here is a u64, but some callees may not be able to allocate +a buffer as large as that would imply. +FIXME: describe what happens if allocation fails.

        +
        Params
        + +
        Return values
        + +

        skip: func

        +

        Skip bytes from a stream.

        +

        This is similar to the read function, but avoids copying the +bytes into the instance.

        +

        Once a stream has reached the end, subsequent calls to read or +skip will always report end-of-stream rather than producing more +data.

        +

        This function returns the number of bytes skipped, along with a bool +indicating whether the end of the stream was reached. The returned +value will be at most len; it may be less.

        +
        Params
        + +
        Return values
        + +

        subscribe-to-input-stream: func

        +

        Create a pollable which will resolve once either the specified stream +has bytes available to read or the other end of the stream has been +closed.

        +
        Params
        + +
        Return values
        + +

        drop-input-stream: func

        +

        Dispose of the specified input-stream, after which it may no longer +be used.

        +
        Params
        + +

        write: func

        +

        Write bytes to a stream.

        +

        This function returns a u64 indicating the number of bytes from +buf that were written; it may be less than the full list.

        +
        Params
        + +
        Return values
        + +

        write-zeroes: func

        +

        Write multiple zero bytes to a stream.

        +

        This function returns a u64 indicating the number of zero bytes +that were written; it may be less than len.

        +
        Params
        + +
        Return values
        + +

        splice: func

        +

        Read from one stream and write to another.

        +

        This function returns the number of bytes transferred; it may be less +than len.

        +

        Unlike other I/O functions, this function blocks until all the data +read from the input stream has been written to the output stream.

        +
        Params
        + +
        Return values
        + +

        forward: func

        +

        Forward the entire contents of an input stream to an output stream.

        +

        This function repeatedly reads from the input stream and writes +the data to the output stream, until the end of the input stream +is reached, or an error is encountered.

        +

        Unlike other I/O functions, this function blocks until the end +of the input stream is seen and all the data has been written to +the output stream.

        +

        This function returns the number of bytes transferred.

        +
        Params
        + +
        Return values
        + +

        subscribe-to-output-stream: func

        +

        Create a pollable which will resolve once either the specified stream +is ready to accept bytes or the other end of the stream has been closed.

        +
        Params
        + +
        Return values
        + +

        drop-output-stream: func

        +

        Dispose of the specified output-stream, after which it may no longer +be used.

        +
        Params
        + diff --git a/proposals/io/wasi-io.html b/proposals/io/wasi-io.html deleted file mode 100644 index 1249bb03f..000000000 --- a/proposals/io/wasi-io.html +++ /dev/null @@ -1,230 +0,0 @@ -

        Import interface wasi-poll

        -

        Types

        -

        pollable: u32

        -

        A "pollable" handle.

        -

        This is conceptually represents a stream<_, _>, or in other words, -a stream that one can wait on, repeatedly, but which does not itself -produce any data. It's temporary scaffolding until component-model's -async features are ready.

        -

        And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

        -

        pollable lifetimes are not automatically managed. Users must ensure -that they do not outlive the resource they reference.

        -

        Size: 4, Alignment: 4

        -

        Functions

        -
        -

        drop-pollable

        -

        Dispose of the specified pollable, after which it may no longer be used.

        -
        Params
        - -
        -

        poll-oneoff

        -

        Poll for completion on a set of pollables.

        -

        The "oneoff" in the name refers to the fact that this function must do a -linear scan through the entire list of subscriptions, which may be -inefficient if the number is large and the same subscriptions are used -many times. In the future, this is expected to be obsoleted by the -component model async proposal, which will include a scalable waiting -facility.

        -

        Note that the return type would ideally be list<bool>, but that would -be more difficult to polyfill given the current state of wit-bindgen. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 -for details. For now, we use zero to mean "not ready" and non-zero to -mean "ready".

        -
        Params
        - -
        Results
        -
          -
        • result0: list<u8>
        • -
        -

        Import interface wasi-io

        -

        Types

        -

        pollable: pollable

        -

        Size: 4, Alignment: 4

        -

        stream-error: record

        -

        An error type returned from a stream operation. Currently this -doesn't provide any additional information.

        -

        Size: 0, Alignment: 1

        -

        Record Fields

        -

        output-stream: u32

        -

        An output bytestream. In the future, this will be replaced by handle -types.

        -

        This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

        -

        output-streams are non-blocking to the extent practical on -underlying platforms. Except where specified otherwise, I/O operations also -always return promptly, after the number of bytes that can be written -promptly, which could even be zero. To wait for the stream to be ready to -accept data, the subscribe-to-output-stream function to obtain a -pollable which can be polled for using wasi_poll.

        -

        And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

        -

        Size: 4, Alignment: 4

        -

        input-stream: u32

        -

        An input bytestream. In the future, this will be replaced by handle -types.

        -

        This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

        -

        input-streams are non-blocking to the extent practical on underlying -platforms. I/O operations always return promptly; if fewer bytes are -promptly available than requested, they return the number of bytes promptly -available, which could even be zero. To wait for data to be available, -use the subscribe-to-input-stream function to obtain a pollable which -can be polled for using wasi_poll.

        -

        And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

        -

        Size: 4, Alignment: 4

        -

        Functions

        -
        -

        read

        -

        Read bytes from a stream.

        -

        This function returns a list of bytes containing the data that was -read, along with a bool indicating whether the end of the stream -was reached. The returned list will contain up to len bytes; it -may return fewer than requested, but not more.

        -

        Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

        -

        If len is 0, it represents a request to read 0 bytes, which should -always succeed, assuming the stream hasn't reached its end yet, and -return an empty list.

        -

        The len here is a u64, but some callees may not be able to allocate -a buffer as large as that would imply. -FIXME: describe what happens if allocation fails.

        -
        Params
        - -
        Results
        - -
        -

        skip

        -

        Skip bytes from a stream.

        -

        This is similar to the read function, but avoids copying the -bytes into the instance.

        -

        Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

        -

        This function returns the number of bytes skipped, along with a bool -indicating whether the end of the stream was reached. The returned -value will be at most len; it may be less.

        -
        Params
        - -
        Results
        - -
        -

        subscribe-to-input-stream

        -

        Create a pollable which will resolve once either the specified stream has bytes -available to read or the other end of the stream has been closed.

        -
        Params
        - -
        Results
        - -
        -

        drop-input-stream

        -

        Dispose of the specified input-stream, after which it may no longer -be used.

        -
        Params
        - -
        -

        write

        -

        Write bytes to a stream.

        -

        This function returns a u64 indicating the number of bytes from -buf that were written; it may be less than the full list.

        -
        Params
        - -
        Results
        - -
        -

        write-zeroes

        -

        Write multiple zero bytes to a stream.

        -

        This function returns a u64 indicating the number of zero bytes -that were written; it may be less than len.

        -
        Params
        - -
        Results
        - -
        -

        splice

        -

        Read from one stream and write to another.

        -

        This function returns the number of bytes transferred; it may be less -than len.

        -

        Unlike other I/O functions, this function blocks until all the data -read from the input stream has been written to the output stream.

        -
        Params
        - -
        Results
        - -
        -

        forward

        -

        Forward the entire contents of an input stream to an output stream.

        -

        This function repeatedly reads from the input stream and writes -the data to the output stream, until the end of the input stream -is reached, or an error is encountered.

        -

        Unlike other I/O functions, this function blocks until the end -of the input stream is seen and all the data has been written to -the output stream.

        -

        This function returns the number of bytes transferred.

        -
        Params
        - -
        Results
        - -
        -

        subscribe-to-output-stream

        -

        Create a pollable which will resolve once either the specified stream is ready -to accept bytes or the other end of the stream has been closed.

        -
        Params
        - -
        Results
        - -
        -

        drop-output-stream

        -

        Dispose of the specified output-stream, after which it may no longer -be used.

        -
        Params
        - diff --git a/proposals/io/wasi-io.md b/proposals/io/wasi-io.md deleted file mode 100644 index 72f5a7204..000000000 --- a/proposals/io/wasi-io.md +++ /dev/null @@ -1,292 +0,0 @@ -# Import interface `wasi-poll` - -## Types - -## `pollable`: `u32` - -A "pollable" handle. - -This is conceptually represents a `stream<_, _>`, or in other words, -a stream that one can wait on, repeatedly, but which does not itself -produce any data. It's temporary scaffolding until component-model's -async features are ready. - -And at present, it is a `u32` instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready. - -`pollable` lifetimes are not automatically managed. Users must ensure -that they do not outlive the resource they reference. - -Size: 4, Alignment: 4 - -## Functions - ----- - -#### `drop-pollable` - -Dispose of the specified `pollable`, after which it may no longer be used. -##### Params - -- `this`: [`pollable`](#pollable) - ----- - -#### `poll-oneoff` - -Poll for completion on a set of pollables. - -The "oneoff" in the name refers to the fact that this function must do a -linear scan through the entire list of subscriptions, which may be -inefficient if the number is large and the same subscriptions are used -many times. In the future, this is expected to be obsoleted by the -component model async proposal, which will include a scalable waiting -facility. - -Note that the return type would ideally be `list`, but that would -be more difficult to polyfill given the current state of `wit-bindgen`. -See -for details. For now, we use zero to mean "not ready" and non-zero to -mean "ready". -##### Params - -- `in`: list<[`pollable`](#pollable)> -##### Results - -- `result0`: list<`u8`> - -# Import interface `wasi-io` - -## Types - -## `pollable`: [`pollable`](#pollable) - - -Size: 4, Alignment: 4 - -## `stream-error`: record - -An error type returned from a stream operation. Currently this -doesn't provide any additional information. - -Size: 0, Alignment: 1 - -### Record Fields - -## `output-stream`: `u32` - -An output bytestream. In the future, this will be replaced by handle -types. - -This conceptually represents a `stream`. It's temporary -scaffolding until component-model's async features are ready. - -`output-stream`s are *non-blocking* to the extent practical on -underlying platforms. Except where specified otherwise, I/O operations also -always return promptly, after the number of bytes that can be written -promptly, which could even be zero. To wait for the stream to be ready to -accept data, the `subscribe-to-output-stream` function to obtain a -`pollable` which can be polled for using `wasi_poll`. - -And at present, it is a `u32` instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready. - -Size: 4, Alignment: 4 - -## `input-stream`: `u32` - -An input bytestream. In the future, this will be replaced by handle -types. - -This conceptually represents a `stream`. It's temporary -scaffolding until component-model's async features are ready. - -`input-stream`s are *non-blocking* to the extent practical on underlying -platforms. I/O operations always return promptly; if fewer bytes are -promptly available than requested, they return the number of bytes promptly -available, which could even be zero. To wait for data to be available, -use the `subscribe-to-input-stream` function to obtain a `pollable` which -can be polled for using `wasi_poll`. - -And at present, it is a `u32` instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready. - -Size: 4, Alignment: 4 - -## Functions - ----- - -#### `read` - -Read bytes from a stream. - -This function returns a list of bytes containing the data that was -read, along with a bool indicating whether the end of the stream -was reached. The returned list will contain up to `len` bytes; it -may return fewer than requested, but not more. - -Once a stream has reached the end, subsequent calls to read or -`skip` will always report end-of-stream rather than producing more -data. - -If `len` is 0, it represents a request to read 0 bytes, which should -always succeed, assuming the stream hasn't reached its end yet, and -return an empty list. - -The len here is a `u64`, but some callees may not be able to allocate -a buffer as large as that would imply. -FIXME: describe what happens if allocation fails. -##### Params - -- `this`: [`input-stream`](#input_stream) -- `len`: `u64` -##### Results - -- `result0`: result<(list<`u8`>, `bool`), [`stream-error`](#stream_error)> - ----- - -#### `skip` - -Skip bytes from a stream. - -This is similar to the `read` function, but avoids copying the -bytes into the instance. - -Once a stream has reached the end, subsequent calls to read or -`skip` will always report end-of-stream rather than producing more -data. - -This function returns the number of bytes skipped, along with a bool -indicating whether the end of the stream was reached. The returned -value will be at most `len`; it may be less. -##### Params - -- `this`: [`input-stream`](#input_stream) -- `len`: `u64` -##### Results - -- `result0`: result<(`u64`, `bool`), [`stream-error`](#stream_error)> - ----- - -#### `subscribe-to-input-stream` - -Create a `pollable` which will resolve once either the specified stream has bytes -available to read or the other end of the stream has been closed. -##### Params - -- `this`: [`input-stream`](#input_stream) -##### Results - -- `result0`: [`pollable`](#pollable) - ----- - -#### `drop-input-stream` - -Dispose of the specified `input-stream`, after which it may no longer -be used. -##### Params - -- `this`: [`input-stream`](#input_stream) - ----- - -#### `write` - -Write bytes to a stream. - -This function returns a `u64` indicating the number of bytes from -`buf` that were written; it may be less than the full list. -##### Params - -- `this`: [`output-stream`](#output_stream) -- `buf`: list<`u8`> -##### Results - -- `result0`: result<`u64`, [`stream-error`](#stream_error)> - ----- - -#### `write-zeroes` - -Write multiple zero bytes to a stream. - -This function returns a `u64` indicating the number of zero bytes -that were written; it may be less than `len`. -##### Params - -- `this`: [`output-stream`](#output_stream) -- `len`: `u64` -##### Results - -- `result0`: result<`u64`, [`stream-error`](#stream_error)> - ----- - -#### `splice` - -Read from one stream and write to another. - -This function returns the number of bytes transferred; it may be less -than `len`. - -Unlike other I/O functions, this function blocks until all the data -read from the input stream has been written to the output stream. -##### Params - -- `this`: [`output-stream`](#output_stream) -- `src`: [`input-stream`](#input_stream) -- `len`: `u64` -##### Results - -- `result0`: result<(`u64`, `bool`), [`stream-error`](#stream_error)> - ----- - -#### `forward` - -Forward the entire contents of an input stream to an output stream. - -This function repeatedly reads from the input stream and writes -the data to the output stream, until the end of the input stream -is reached, or an error is encountered. - -Unlike other I/O functions, this function blocks until the end -of the input stream is seen and all the data has been written to -the output stream. - -This function returns the number of bytes transferred. -##### Params - -- `this`: [`output-stream`](#output_stream) -- `src`: [`input-stream`](#input_stream) -##### Results - -- `result0`: result<`u64`, [`stream-error`](#stream_error)> - ----- - -#### `subscribe-to-output-stream` - -Create a `pollable` which will resolve once either the specified stream is ready -to accept bytes or the other end of the stream has been closed. -##### Params - -- `this`: [`output-stream`](#output_stream) -##### Results - -- `result0`: [`pollable`](#pollable) - ----- - -#### `drop-output-stream` - -Dispose of the specified `output-stream`, after which it may no longer -be used. -##### Params - -- `this`: [`output-stream`](#output_stream) - diff --git a/proposals/io/wit/deps/poll/poll.wit b/proposals/io/wit/deps/poll/poll.wit new file mode 100644 index 000000000..28f08e17d --- /dev/null +++ b/proposals/io/wit/deps/poll/poll.wit @@ -0,0 +1,39 @@ +/// A poll API intended to let users wait for I/O events on multiple handles +/// at once. +default interface poll { + /// A "pollable" handle. + /// + /// This is conceptually represents a `stream<_, _>`, or in other words, + /// a stream that one can wait on, repeatedly, but which does not itself + /// produce any data. It's temporary scaffolding until component-model's + /// async features are ready. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// `pollable` lifetimes are not automatically managed. Users must ensure + /// that they do not outlive the resource they reference. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type pollable = u32 + + /// Dispose of the specified `pollable`, after which it may no longer + /// be used. + drop-pollable: func(this: pollable) + + /// Poll for completion on a set of pollables. + /// + /// The "oneoff" in the name refers to the fact that this function must do a + /// linear scan through the entire list of subscriptions, which may be + /// inefficient if the number is large and the same subscriptions are used + /// many times. In the future, this is expected to be obsoleted by the + /// component model async proposal, which will include a scalable waiting + /// facility. + /// + /// Note that the return type would ideally be `list`, but that would + /// be more difficult to polyfill given the current state of `wit-bindgen`. + /// See + /// for details. For now, we use zero to mean "not ready" and non-zero to + /// mean "ready". + poll-oneoff: func(in: list) -> list +} diff --git a/proposals/io/wit/wasi-io.wit.md b/proposals/io/wit/streams.wit similarity index 55% rename from proposals/io/wit/wasi-io.wit.md rename to proposals/io/wit/streams.wit index 9243a8285..9fa533efe 100644 --- a/proposals/io/wit/wasi-io.wit.md +++ b/proposals/io/wit/streams.wit @@ -1,49 +1,34 @@ -# WASI I/O - -```wit /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. -default interface wasi-io { -``` - -## Imports -```wit -use pkg.wasi-poll.{pollable} -``` +default interface streams { + use poll.poll.{pollable} -## `stream-error` -```wit -/// An error type returned from a stream operation. Currently this -/// doesn't provide any additional information. -record stream-error {} -``` + /// An error type returned from a stream operation. Currently this + /// doesn't provide any additional information. + record stream-error {} -## `input-stream` -```wit -/// An input bytestream. In the future, this will be replaced by handle -/// types. -/// -/// This conceptually represents a `stream`. It's temporary -/// scaffolding until component-model's async features are ready. -/// -/// `input-stream`s are *non-blocking* to the extent practical on underlying -/// platforms. I/O operations always return promptly; if fewer bytes are -/// promptly available than requested, they return the number of bytes promptly -/// available, which could even be zero. To wait for data to be available, -/// use the `subscribe-to-input-stream` function to obtain a `pollable` which -/// can be polled for using `wasi_poll`. -/// -/// And at present, it is a `u32` instead of being an actual handle, until -/// the wit-bindgen implementation of handles and resources is ready. -// TODO(resource input-stream {) -type input-stream = u32 -``` + /// An input bytestream. In the future, this will be replaced by handle + /// types. + /// + /// This conceptually represents a `stream`. It's temporary + /// scaffolding until component-model's async features are ready. + /// + /// `input-stream`s are *non-blocking* to the extent practical on underlying + /// platforms. I/O operations always return promptly; if fewer bytes are + /// promptly available than requested, they return the number of bytes promptly + /// available, which could even be zero. To wait for data to be available, + /// use the `subscribe-to-input-stream` function to obtain a `pollable` which + /// can be polled for using `wasi_poll`. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type input-stream = u32 -## `read` -```wit /// Read bytes from a stream. /// /// This function returns a list of bytes containing the data that was @@ -67,10 +52,7 @@ type input-stream = u32 /// The maximum number of bytes to read len: u64 ) -> result, bool>, stream-error> -``` -## `skip` -```wit /// Skip bytes from a stream. /// /// This is similar to the `read` function, but avoids copying the @@ -88,46 +70,35 @@ type input-stream = u32 /// The maximum number of bytes to skip. len: u64, ) -> result, stream-error> -``` -## `subscribe-to-input-stream` -```wit -/// Create a `pollable` which will resolve once either the specified stream has bytes -/// available to read or the other end of the stream has been closed. -subscribe-to-input-stream: func(this: input-stream) -> pollable -``` + /// Create a `pollable` which will resolve once either the specified stream + /// has bytes available to read or the other end of the stream has been + /// closed. + subscribe-to-input-stream: func(this: input-stream) -> pollable -# `drop-input-stream` -```wit -/// Dispose of the specified `input-stream`, after which it may no longer -/// be used. -// TODO(} /* resource input-stream */) -drop-input-stream: func(this: input-stream) -``` + /// Dispose of the specified `input-stream`, after which it may no longer + /// be used. + drop-input-stream: func(this: input-stream) -## `output-stream` -```wit -/// An output bytestream. In the future, this will be replaced by handle -/// types. -/// -/// This conceptually represents a `stream`. It's temporary -/// scaffolding until component-model's async features are ready. -/// -/// `output-stream`s are *non-blocking* to the extent practical on -/// underlying platforms. Except where specified otherwise, I/O operations also -/// always return promptly, after the number of bytes that can be written -/// promptly, which could even be zero. To wait for the stream to be ready to -/// accept data, the `subscribe-to-output-stream` function to obtain a -/// `pollable` which can be polled for using `wasi_poll`. -/// -/// And at present, it is a `u32` instead of being an actual handle, until -/// the wit-bindgen implementation of handles and resources is ready. -// TODO(resource output-stream {) -type output-stream = u32 -``` + /// An output bytestream. In the future, this will be replaced by handle + /// types. + /// + /// This conceptually represents a `stream`. It's temporary + /// scaffolding until component-model's async features are ready. + /// + /// `output-stream`s are *non-blocking* to the extent practical on + /// underlying platforms. Except where specified otherwise, I/O operations also + /// always return promptly, after the number of bytes that can be written + /// promptly, which could even be zero. To wait for the stream to be ready to + /// accept data, the `subscribe-to-output-stream` function to obtain a + /// `pollable` which can be polled for using `wasi_poll`. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type output-stream = u32 -## `write` -```wit /// Write bytes to a stream. /// /// This function returns a `u64` indicating the number of bytes from @@ -137,10 +108,7 @@ type output-stream = u32 /// Data to write buf: list ) -> result -``` -## `write-zeroes` -```wit /// Write multiple zero bytes to a stream. /// /// This function returns a `u64` indicating the number of zero bytes @@ -150,10 +118,7 @@ type output-stream = u32 /// The number of zero bytes to write len: u64 ) -> result -``` -## `splice` -```wit /// Read from one stream and write to another. /// /// This function returns the number of bytes transferred; it may be less @@ -168,10 +133,7 @@ type output-stream = u32 /// The number of bytes to splice len: u64, ) -> result, stream-error> -``` -## `forward` -```wit /// Forward the entire contents of an input stream to an output stream. /// /// This function repeatedly reads from the input stream and writes @@ -188,23 +150,12 @@ type output-stream = u32 /// The stream to read from src: input-stream ) -> result -``` - -# `subscribe-to-output-stream` -```wit -/// Create a `pollable` which will resolve once either the specified stream is ready -/// to accept bytes or the other end of the stream has been closed. -subscribe-to-output-stream: func(this: output-stream) -> pollable -``` -# `drop-output-stream` -```wit -/// Dispose of the specified `output-stream`, after which it may no longer -/// be used. -// TODO(} /* resource output-stream */) -drop-output-stream: func(this: output-stream) -``` + /// Create a `pollable` which will resolve once either the specified stream + /// is ready to accept bytes or the other end of the stream has been closed. + subscribe-to-output-stream: func(this: output-stream) -> pollable -```wit + /// Dispose of the specified `output-stream`, after which it may no longer + /// be used. + drop-output-stream: func(this: output-stream) } -``` diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit new file mode 100644 index 000000000..bae7c92b3 --- /dev/null +++ b/proposals/io/wit/world.wit @@ -0,0 +1,3 @@ +default world example-world { + import streams: pkg.streams +} diff --git a/proposals/io/wit/world.wit.md b/proposals/io/wit/world.wit.md deleted file mode 100644 index e7b5d0db2..000000000 --- a/proposals/io/wit/world.wit.md +++ /dev/null @@ -1,9 +0,0 @@ -This file contains a world that imports all interfaces in this proposal. Its -primary purpose is to allow unified documentation to be easily generated for -the whole proposal. - -```wit -default world wasi-io { - import wasi-io: pkg.wasi-io -} -``` From 08102d24ebe1015b50b6e622aadac6be53358568 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Feb 2023 13:08:14 -0800 Subject: [PATCH 1061/1772] Update to the latest wasi-proposal-repo format. (#26) This notably converts the `.wit.md` files to `.wit`. --- proposals/random/.github/workflows/main.yml | 4 +- proposals/random/README.md | 4 +- .../{wasi-random.html => example-world.md} | 43 ++++++++----- proposals/random/wasi-random.md | 62 ------------------- proposals/random/wit/random.wit | 42 +++++++++++++ proposals/random/wit/wasi-random.wit.md | 60 ------------------ proposals/random/wit/world.wit | 3 + proposals/random/wit/world.wit.md | 9 --- 8 files changed, 75 insertions(+), 152 deletions(-) rename proposals/random/{wasi-random.html => example-world.md} (54%) delete mode 100644 proposals/random/wasi-random.md create mode 100644 proposals/random/wit/random.wit delete mode 100644 proposals/random/wit/wasi-random.wit.md create mode 100644 proposals/random/wit/world.wit delete mode 100644 proposals/random/wit/world.wit.md diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index 8ca235c4f..ad1997c51 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v10 + - uses: WebAssembly/wit-abi-up-to-date@v12 with: - wit-abi-tag: wit-abi-0.8.0 + wit-abi-tag: wit-abi-0.10.0 diff --git a/proposals/random/README.md b/proposals/random/README.md index 7622c4294..cca4e5b96 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -102,7 +102,7 @@ Sometimes the bindings for `list` can have some overhead, so another function is available which returns the same data but as a `u64`: -```rust= +```rust let data: u64 = get_random_u64(); ``` @@ -110,7 +110,7 @@ another function is available which returns the same data but as a Return a pair of u64's that can be used to initialize a hash implementation: -```rust= +```rust let init: (u64, u64) = insecure_random(); let combined: u128 = init.0 as u128 | (init.1 as u128 << 64); diff --git a/proposals/random/wasi-random.html b/proposals/random/example-world.md similarity index 54% rename from proposals/random/wasi-random.html rename to proposals/random/example-world.md index a6fe0f693..b98bb3d37 100644 --- a/proposals/random/wasi-random.html +++ b/proposals/random/example-world.md @@ -1,7 +1,18 @@ -

        Import interface wasi-random

        -

        Functions

        +

        World example-world

        +
          +
        • Imports: + +
        • +
        +

        Import interface random

        +

        WASI Random is a random data API.

        +

        It is intended to be portable at least between Unix-family platforms and +Windows.


        -

        get-random-bytes

        +

        Functions

        +

        get-random-bytes: func

        Return len cryptographically-secure pseudo-random bytes.

        This function must produce data from an adequately seeded cryptographically-secure pseudo-random number generator (CSPRNG), so it @@ -12,29 +23,27 @@

        len: u64 +
      • len: u64
      -
      Results
      +
      Return values
        -
      • result0: list<u8>
      • +
      • list<u8>
      -
      -

      get-random-u64

      +

      get-random-u64: func

      Return a cryptographically-secure pseudo-random u64 value.

      This function returns the same type of pseudo-random data as get-random-bytes, represented as a u64.

      -
      Results
      +
      Return values
        -
      • result0: u64
      • +
      • u64
      -
      -

      insecure-random

      +

      insecure-random: func

      Return a 128-bit value that may contain a pseudo-random value.

      The returned value is not required to be computed from a CSPRNG, and may even be entirely deterministic. Host implementations are encouraged to -provide pseudo-random values to any program exposed to attacker-controlled -content, to enable DoS protection built into many languages' hash-map -implementations.

      +provide pseudo-random values to any program exposed to +attacker-controlled content, to enable DoS protection built into many +languages' hash-map implementations.

      This function is intended to only be called once, by a source language to initialize Denial Of Service (DoS) protection in its hash-map implementation.

      @@ -42,7 +51,7 @@

      Expected future evolution

      This will likely be changed to a value import, to prevent it from being called multiple times and potentially used for purposes other than DoS protection.

      -
      Results
      +
      Return values
        -
      • result0: (u64, u64)
      • +
      • (u64, u64)
      diff --git a/proposals/random/wasi-random.md b/proposals/random/wasi-random.md deleted file mode 100644 index a772cd5dd..000000000 --- a/proposals/random/wasi-random.md +++ /dev/null @@ -1,62 +0,0 @@ -# Import interface `wasi-random` - -## Functions - ----- - -#### `get-random-bytes` - -Return `len` cryptographically-secure pseudo-random bytes. - -This function must produce data from an adequately seeded -cryptographically-secure pseudo-random number generator (CSPRNG), so it -must not block, from the perspective of the calling program, and the -returned data is always unpredictable. - -This function must always return fresh pseudo-random data. Deterministic -environments must omit this function, rather than implementing it with -deterministic data. -##### Params - -- `len`: `u64` -##### Results - -- `result0`: list<`u8`> - ----- - -#### `get-random-u64` - -Return a cryptographically-secure pseudo-random `u64` value. - -This function returns the same type of pseudo-random data as -`get-random-bytes`, represented as a `u64`. -##### Results - -- `result0`: `u64` - ----- - -#### `insecure-random` - -Return a 128-bit value that may contain a pseudo-random value. - -The returned value is not required to be computed from a CSPRNG, and may -even be entirely deterministic. Host implementations are encouraged to -provide pseudo-random values to any program exposed to attacker-controlled -content, to enable DoS protection built into many languages' hash-map -implementations. - -This function is intended to only be called once, by a source language -to initialize Denial Of Service (DoS) protection in its hash-map -implementation. - -# Expected future evolution - -This will likely be changed to a value import, to prevent it from being -called multiple times and potentially used for purposes other than DoS -protection. -##### Results - -- `result0`: (`u64`, `u64`) - diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit new file mode 100644 index 000000000..2080ddfde --- /dev/null +++ b/proposals/random/wit/random.wit @@ -0,0 +1,42 @@ +/// WASI Random is a random data API. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface random { + /// Return `len` cryptographically-secure pseudo-random bytes. + /// + /// This function must produce data from an adequately seeded + /// cryptographically-secure pseudo-random number generator (CSPRNG), so it + /// must not block, from the perspective of the calling program, and the + /// returned data is always unpredictable. + /// + /// This function must always return fresh pseudo-random data. Deterministic + /// environments must omit this function, rather than implementing it with + /// deterministic data. + get-random-bytes: func(len: u64) -> list + + /// Return a cryptographically-secure pseudo-random `u64` value. + /// + /// This function returns the same type of pseudo-random data as + /// `get-random-bytes`, represented as a `u64`. + get-random-u64: func() -> u64 + + /// Return a 128-bit value that may contain a pseudo-random value. + /// + /// The returned value is not required to be computed from a CSPRNG, and may + /// even be entirely deterministic. Host implementations are encouraged to + /// provide pseudo-random values to any program exposed to + /// attacker-controlled content, to enable DoS protection built into many + /// languages' hash-map implementations. + /// + /// This function is intended to only be called once, by a source language + /// to initialize Denial Of Service (DoS) protection in its hash-map + /// implementation. + /// + /// # Expected future evolution + /// + /// This will likely be changed to a value import, to prevent it from being + /// called multiple times and potentially used for purposes other than DoS + /// protection. + insecure-random: func() -> tuple +} diff --git a/proposals/random/wit/wasi-random.wit.md b/proposals/random/wit/wasi-random.wit.md deleted file mode 100644 index 1c0a5605e..000000000 --- a/proposals/random/wit/wasi-random.wit.md +++ /dev/null @@ -1,60 +0,0 @@ -# WASI Random API - -## `wasi-random` -```wit -/// WASI Random is a random data API. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -default interface wasi-random { -``` - -## `get-random-bytes` -```wit -/// Return `len` cryptographically-secure pseudo-random bytes. -/// -/// This function must produce data from an adequately seeded -/// cryptographically-secure pseudo-random number generator (CSPRNG), so it -/// must not block, from the perspective of the calling program, and the -/// returned data is always unpredictable. -/// -/// This function must always return fresh pseudo-random data. Deterministic -/// environments must omit this function, rather than implementing it with -/// deterministic data. -get-random-bytes: func(len: u64) -> list -``` - -## `get-random-u64` -```wit -/// Return a cryptographically-secure pseudo-random `u64` value. -/// -/// This function returns the same type of pseudo-random data as -/// `get-random-bytes`, represented as a `u64`. -get-random-u64: func() -> u64 -``` - -## `insecure-random` -```wit -/// Return a 128-bit value that may contain a pseudo-random value. -/// -/// The returned value is not required to be computed from a CSPRNG, and may -/// even be entirely deterministic. Host implementations are encouraged to -/// provide pseudo-random values to any program exposed to attacker-controlled -/// content, to enable DoS protection built into many languages' hash-map -/// implementations. -/// -/// This function is intended to only be called once, by a source language -/// to initialize Denial Of Service (DoS) protection in its hash-map -/// implementation. -/// -/// # Expected future evolution -/// -/// This will likely be changed to a value import, to prevent it from being -/// called multiple times and potentially used for purposes other than DoS -/// protection. -insecure-random: func() -> tuple -``` - -```wit -} -``` diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit new file mode 100644 index 000000000..8d54b3b2c --- /dev/null +++ b/proposals/random/wit/world.wit @@ -0,0 +1,3 @@ +default world example-world { + import random: pkg.random +} diff --git a/proposals/random/wit/world.wit.md b/proposals/random/wit/world.wit.md deleted file mode 100644 index 5078746d2..000000000 --- a/proposals/random/wit/world.wit.md +++ /dev/null @@ -1,9 +0,0 @@ -This file contains a world that imports all interfaces in this proposal. Its -primary purpose is to allow unified documentation to be easily generated for -the whole proposal. - -```wit -default world wasi-random { - import wasi-random: pkg.wasi-random -} -``` From 7b8bc9b7ff9357208ccfc151054c61a0f129f70d Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Fri, 24 Feb 2023 16:11:57 -0600 Subject: [PATCH 1062/1772] Fix typo in README --- proposals/http/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/README.md b/proposals/http/README.md index 6c69289b7..5acd566dd 100644 --- a/proposals/http/README.md +++ b/proposals/http/README.md @@ -6,7 +6,7 @@ This proposal currently only contains the proposed Wit interfaces with light explanation in comments; more work is necessary to fully document the proposal. The Wit comments annotate where the proposed interface is expected to change in the short term (for Preview2) once resources and handles are re-added to Wit, -and then after that (for Preview2) once native stream support is added to the +and then after that (for Preview3) once native stream support is added to the Component Model and Wit. The `wit` directory currently validates and can generate bindings with: From 223b652fc0ce5647244ecb63702982315ff4af58 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Feb 2023 14:25:19 -0800 Subject: [PATCH 1063/1772] Fix the interface names for the instance interfaces. (#41) Instance monotonic and wall clocks now have their own interfaces, so give them their own interface names. --- proposals/clocks/wit/instance-monotonic-clock.wit | 2 +- proposals/clocks/wit/instance-wall-clock.wit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/wit/instance-monotonic-clock.wit b/proposals/clocks/wit/instance-monotonic-clock.wit index f92cd12a2..4cffa4a57 100644 --- a/proposals/clocks/wit/instance-monotonic-clock.wit +++ b/proposals/clocks/wit/instance-monotonic-clock.wit @@ -1,6 +1,6 @@ /// This interfaces proves a clock handles for monotonic clock, suitable for /// general-purpose application needs. -default interface instance-clocks { +default interface instance-monotonic-clock { use pkg.monotonic-clock.{monotonic-clock} /// Return a handle to a monotonic clock, suitable for general-purpose diff --git a/proposals/clocks/wit/instance-wall-clock.wit b/proposals/clocks/wit/instance-wall-clock.wit index a29729793..3a55b5526 100644 --- a/proposals/clocks/wit/instance-wall-clock.wit +++ b/proposals/clocks/wit/instance-wall-clock.wit @@ -1,6 +1,6 @@ /// This interfaces proves a clock handles for wall clock, suitable for /// general-purpose application needs. -default interface instance-clocks { +default interface instance-wall-clock { use pkg.wall-clock.{wall-clock} /// Return a handle to a wall clock, suitable for general-purpose From 304b6fd21898a4c8279c9d6aa80cc292e0a22817 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 Feb 2023 09:55:53 -0800 Subject: [PATCH 1064/1772] Add initial wasi-cli content, following the wasi-proposal-repo format. Add initial wasi-cli content, following the wasi-proposal-repo format. Define a wit file, add the dependencies in a deps directory, and populate the README. For now, this wasi-cli repo defines an additional interface for exit.wit, which may go away when we can depend on exception-handling, but is useful for now. This world is presently missing a few things, notably sockets, but I'll integrate those once WebAssembly/wasi-sockets#16 lands. --- proposals/cli/README.md | 102 +- proposals/cli/cli.md | 1569 +++++++++++++++++ proposals/cli/wit/cli.wit | 23 + .../deps/clocks/instance-monotonic-clock.wit | 15 + .../wit/deps/clocks/instance-wall-clock.wit | 15 + .../cli/wit/deps/clocks/monotonic-clock.wit | 40 + proposals/cli/wit/deps/clocks/timezone.wit | 61 + proposals/cli/wit/deps/clocks/wall-clock.wit | 48 + .../cli/wit/deps/filesystem/filesystem.wit | 770 ++++++++ proposals/cli/wit/deps/io/streams.wit | 134 ++ proposals/cli/wit/deps/poll/poll.wit | 39 + proposals/cli/wit/deps/random/random.wit | 42 + proposals/cli/wit/deps/wit | 134 ++ proposals/cli/wit/exit.wit | 4 + 14 files changed, 2947 insertions(+), 49 deletions(-) create mode 100644 proposals/cli/cli.md create mode 100644 proposals/cli/wit/cli.wit create mode 100644 proposals/cli/wit/deps/clocks/instance-monotonic-clock.wit create mode 100644 proposals/cli/wit/deps/clocks/instance-wall-clock.wit create mode 100644 proposals/cli/wit/deps/clocks/monotonic-clock.wit create mode 100644 proposals/cli/wit/deps/clocks/timezone.wit create mode 100644 proposals/cli/wit/deps/clocks/wall-clock.wit create mode 100644 proposals/cli/wit/deps/filesystem/filesystem.wit create mode 100644 proposals/cli/wit/deps/io/streams.wit create mode 100644 proposals/cli/wit/deps/poll/poll.wit create mode 100644 proposals/cli/wit/deps/random/random.wit create mode 100644 proposals/cli/wit/deps/wit create mode 100644 proposals/cli/wit/exit.wit diff --git a/proposals/cli/README.md b/proposals/cli/README.md index 733036b3d..a300e70c4 100644 --- a/proposals/cli/README.md +++ b/proposals/cli/README.md @@ -1,30 +1,22 @@ -# [Example WASI proposal] - -This template can be used to start a new proposal, which can then be proposed in the WASI Subgroup meetings. - -The sections below are recommended. However, every proposal is different, and the community can help you flesh out the proposal, so don't block on having something filled in for each one of them. - -Thank you to the W3C Privacy CG for the [inspiration](https://github.com/privacycg/template)! - -# [Title] +# WASI CLI World A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. ### Current Phase -[Fill in the current phase, e.g. Phase 1] +wasi-cli is currently in [Phase 1]. + +[Phase 1]: https://github.com/WebAssembly/WASI/blob/42fe2a3ca159011b23099c3d10b5b1d9aff2140e/docs/Proposals.md#phase-1---feature-proposal-cg ### Champions -- [Champion 1] -- [Champion 2] -- [etc.] +- Dan Gohman ### Phase 4 Advancement Criteria TODO before entering Phase 2. -## Table of Contents [if the explainer is longer than one printed page] +## Table of Contents - [Introduction](#introduction) - [Goals [or Motivating Use Cases, or Scenarios]](#goals-or-motivating-use-cases-or-scenarios) @@ -33,31 +25,40 @@ TODO before entering Phase 2. - [Use case 1](#use-case-1) - [Use case 2](#use-case-2) - [Detailed design discussion](#detailed-design-discussion) - - [[Tricky design choice 1]](#tricky-design-choice-1) - - [[Tricky design choice 2]](#tricky-design-choice-2) -- [Considered alternatives](#considered-alternatives) - - [[Alternative 1]](#alternative-1) - - [[Alternative 2]](#alternative-2) + - [Should stdout be an `output-stream`?](#should-stdout-be-an-output-stream) + - [Should stderr be an `output-stream`?](#should-stderr-be-an-output-stream) + - [Should environment variables be arguments to `command`?](#should-environment-variables-be-arguments-to-command) - [Stakeholder Interest & Feedback](#stakeholder-interest--feedback) - [References & acknowledgements](#references--acknowledgements) ### Introduction -[The "executive summary" or "abstract". Explain in a few sentences what the goals of the project are, and a brief overview of how the solution works. This should be no more than 1-2 paragraphs.] +Wasi-cli a [World] proposal for a Command-Line Interface (CLI) environment. It provides APIs commonly available in such environments, such as filesystems and sockets, and also provides command-line facilities such as command-line arguments, environment variables, and stdio. + +[World]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#wit-worlds + +### Goals + +Wasi-cli aims to be useful for: + + - Interfactive command-line argument programs. -### Goals [or Motivating Use Cases, or Scenarios] + - Servers that use filesystems, sockets, and related APIs and expect to be started with + a CLI-style command-line. -[What is the end-user need which this project aims to address?] + - Stream filters that read from standard input and write to standard output. ### Non-goals -[If there are "adjacent" goals which may appear to be in scope but aren't, enumerate them here. This section may be fleshed out as your design progresses and you encounter necessary technical and other trade-offs.] +Wasi-cli is not aiming to significantly re-imagine the concept of command-line interface programs. While WASI as a whole is exploring ideas such as [Typed Main], wasi-cli sticks to the traditional list-of-strings style command-line arguments. + +[Typed Main]: https://sunfishcode.github.io/typed-main-wasi-presentation/ ### API walk-through -The full API documentation can be found [here](wasi-proposal-template.md). +The full API documentation can be found [here](cli.md). -[Walk through of how someone would use this API.] +TODO [Walk through of how someone would use this API.] #### [Use case 1] @@ -69,33 +70,35 @@ The full API documentation can be found [here](wasi-proposal-template.md). ### Detailed design discussion -[This section should mostly refer to the .wit.md file that specifies the API. This section is for any discussion of the choices made in the API which don't make sense to document in the spec file itself.] - -#### [Tricky design choice #1] - -[Talk through the tradeoffs in coming to the specific design point you want to make.] - -``` -// Illustrated with example code. -``` +#### Should stdout be an `output-stream`? -[This may be an open question, in which case you should link to any active discussion threads.] +For server use cases, standard output (stdout) is typically used as a log, +where it's typically not meaningfully blocking, async, or fallible. It's just +a place for the program to send messages to and forget about them. One option +would be to give such use cases a dedicated API, which would have a single +function to allow printing strings that doesn't return a `result`, meaning it +never fails. -#### [Tricky design choice 2] +However, it'd only be a minor simplification in practice, and dedicated cloud +or edge use cases should ideally migrate to more specialized worlds than the +wasi-cli world anyway, as they can result in much greater simplifications, so +this doesn't seem worthwhile. -[etc.] - -### Considered alternatives +#### Should stderr be an `output-stream`? -[This section is not required if you already covered considered alternatives in the design discussion above.] +This is similar to the question for stdout, but for standard error (stderr), +it's a little more tempting to do something like this because stderr is used +in this logging style by many kinds of applications. -#### [Alternative 1] +However, it seems better overall to keep stderr consistent with stdout, and +focus our desires for simplification toward other worlds, which can achieve +even greater simplifications. -[Describe an alternative which was considered, and why you decided against it.] +#### Should environment variables be arguments to `command`? -#### [Alternative 2] - -[etc.] +Environment variables are useful in some non-cli use cases, so leaving them +as separate imports means they can be used from worlds that don't have a +`command` entrypoint. ### Stakeholder Interest & Feedback @@ -105,8 +108,9 @@ TODO before entering Phase 3. ### References & acknowledgements -Many thanks for valuable feedback and advice from: +The concept of wasi-cli has been in development for over a year since the proposal is +posted here, and many people have contributed ideas that have influenced. Many thanks +for valuable feedback and advice in particular from: -- [Person 1] -- [Person 2] -- [etc.] +- Luke Wagner +- Pat Hickey diff --git a/proposals/cli/cli.md b/proposals/cli/cli.md new file mode 100644 index 000000000..10b800358 --- /dev/null +++ b/proposals/cli/cli.md @@ -0,0 +1,1569 @@ +

      World cli

      + +

      Import interface wall-clock

      +

      WASI Wall Clock is a clock API intended to let users query the current +time. The name "wall" makes an analogy to a "clock on the wall", which +is not necessarily monotonic as it may be reset.

      +

      It is intended to be portable at least between Unix-family platforms and +Windows.

      +
      +

      Types

      +

      type wall-clock

      +

      u32

      +

      A wall clock is a clock which measures the date and time according to +some external reference. +

      External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time.

      +

      It is intended for reporting the current date and time for humans.

      +

      This represents a resource.

      +

      record datetime

      +

      A time and date in seconds plus nanoseconds.

      +
      Record Fields
      + +
      +

      Functions

      +

      now: func

      +

      Read the current value of the clock.

      +

      This clock is not monotonic, therefore calling this function repeatedly +will not necessarily produce a sequence of non-decreasing values.

      +

      The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, +also known as Unix Time.

      +

      The nanoseconds field of the output is always less than 1000000000.

      +
      Params
      + +
      Return values
      + +

      resolution: func

      +

      Query the resolution of the clock.

      +

      The nanoseconds field of the output is always less than 1000000000.

      +
      Params
      + +
      Return values
      + +

      drop-wall-clock: func

      +

      Dispose of the specified wall-clock, after which it may no longer +be used.

      +
      Params
      + +

      Import interface poll

      +

      A poll API intended to let users wait for I/O events on multiple handles +at once.

      +
      +

      Types

      +

      type pollable

      +

      u32

      +

      A "pollable" handle. +

      This is conceptually represents a stream<_, _>, or in other words, +a stream that one can wait on, repeatedly, but which does not itself +produce any data. It's temporary scaffolding until component-model's +async features are ready.

      +

      And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

      +

      pollable lifetimes are not automatically managed. Users must ensure +that they do not outlive the resource they reference.

      +

      This represents a resource.

      +
      +

      Functions

      +

      drop-pollable: func

      +

      Dispose of the specified pollable, after which it may no longer +be used.

      +
      Params
      + +

      poll-oneoff: func

      +

      Poll for completion on a set of pollables.

      +

      The "oneoff" in the name refers to the fact that this function must do a +linear scan through the entire list of subscriptions, which may be +inefficient if the number is large and the same subscriptions are used +many times. In the future, this is expected to be obsoleted by the +component model async proposal, which will include a scalable waiting +facility.

      +

      Note that the return type would ideally be list<bool>, but that would +be more difficult to polyfill given the current state of wit-bindgen. +See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 +for details. For now, we use zero to mean "not ready" and non-zero to +mean "ready".

      +
      Params
      + +
      Return values
      +
        +
      • list<u8>
      • +
      +

      Import interface monotonic-clock

      +

      WASI Monotonic Clock is a clock API intended to let users measure elapsed +time.

      +

      It is intended to be portable at least between Unix-family platforms and +Windows.

      +
      +

      Types

      +

      type pollable

      +

      pollable

      +

      +#### `type monotonic-clock` +`u32` +

      A monotonic clock is a clock which has an unspecified initial value, and +successive reads of the clock will produce non-decreasing values. +

      It is intended for measuring elapsed time.

      +

      This represents a resource.

      +

      type instant

      +

      u64

      +

      A timestamp in nanoseconds. +


      +

      Functions

      +

      now: func

      +

      Read the current value of the clock.

      +

      The clock is monotonic, therefore calling this function repeatedly will +produce a sequence of non-decreasing values.

      +
      Params
      + +
      Return values
      + +

      resolution: func

      +

      Query the resolution of the clock.

      +
      Params
      + +
      Return values
      + +

      subscribe: func

      +

      Create a pollable which will resolve once the specified time has been +reached.

      +
      Params
      + +
      Return values
      + +

      drop-monotonic-clock: func

      +

      Dispose of the specified monotonic-clock, after which it may no longer +be used.

      +
      Params
      + +

      Import interface instance-wall-clock

      +

      This interfaces proves a clock handles for wall clock, suitable for +general-purpose application needs.

      +
      +

      Types

      +

      type wall-clock

      +

      wall-clock

      +

      +---- +

      Functions

      +

      instance-wall-clock: func

      +

      Return a handle to a wall clock, suitable for general-purpose +application needs.

      +

      This allocates a new handle, so applications with frequent need of a +clock handle should call this function once and reuse the handle +instead of calling this function each time.

      +

      This represents a value import.

      +
      Return values
      + +

      Import interface instance-monotonic-clock

      +

      This interfaces proves a clock handles for monotonic clock, suitable for +general-purpose application needs.

      +
      +

      Types

      +

      type monotonic-clock

      +

      monotonic-clock

      +

      +---- +

      Functions

      +

      instance-monotonic-clock: func

      +

      Return a handle to a monotonic clock, suitable for general-purpose +application needs.

      +

      This allocates a new handle, so applications with frequent need of a +clock handle should call this function once and reuse the handle +instead of calling this function each time.

      +

      This represents a value import.

      +
      Return values
      + +

      Import interface timezone

      +
      +

      Types

      +

      type datetime

      +

      datetime

      +

      +#### `record timezone-display` +

      Information useful for displaying the timezone of a specific datetime.

      +

      This information may vary within a single timezone to reflect daylight +saving time adjustments.

      +
      Record Fields
      +
        +
      • +

        utc-offset: s32

        +

        The number of seconds difference between UTC time and the local +time of the timezone. +

        The returned value will always be less than 86400 which is the +number of seconds in a day (246060).

        +

        In implementations that do not expose an actual time zone, this +should return 0.

        +
      • +
      • +

        name: string

        +

        The abbreviated name of the timezone to display to a user. The name +`UTC` indicates Coordinated Universal Time. Otherwise, this should +reference local standards for the name of the time zone. +

        In implementations that do not expose an actual time zone, this +should be the string UTC.

        +

        In time zones that do not have an applicable name, a formatted +representation of the UTC offset may be returned, such as -04:00.

        +
      • +
      • +

        in-daylight-saving-time: bool

        +

        Whether daylight saving time is active. +

        In implementations that do not expose an actual time zone, this +should return false.

        +
      • +
      +

      type timezone

      +

      u32

      +

      A timezone. +

      In timezones that recognize daylight saving time, also known as daylight +time and summer time, the information returned from the functions varies +over time to reflect these adjustments.

      +

      This represents a resource.

      +
      +

      Functions

      +

      display: func

      +

      Return information needed to display the given datetime. This includes +the UTC offset, the time zone name, and a flag indicating whether +daylight saving time is active.

      +

      If the timezone cannot be determined for the given datetime, return a +timezone-display for UTC with a utc-offset of 0 and no daylight +saving time.

      +
      Params
      + +
      Return values
      + +

      utc-offset: func

      +

      The same as display, but only return the UTC offset.

      +
      Params
      + +
      Return values
      +
        +
      • s32
      • +
      +

      drop-timezone: func

      +

      Dispose of the specified input-stream, after which it may no longer +be used.

      +
      Params
      + +

      Import interface io

      +

      WASI I/O is an I/O abstraction API which is currently focused on providing +stream types.

      +

      In the future, the component model is expected to add built-in stream types; +when it does, they are expected to subsume this API.

      +
      +

      Types

      +

      type pollable

      +

      pollable

      +

      +#### `record stream-error` +

      An error type returned from a stream operation. Currently this +doesn't provide any additional information.

      +
      Record Fields
      +

      type output-stream

      +

      u32

      +

      An output bytestream. In the future, this will be replaced by handle +types. +

      And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

      +

      This represents a resource.

      +

      type input-stream

      +

      u32

      +

      An input bytestream. In the future, this will be replaced by handle +types. +

      And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

      +

      This represents a resource.

      +
      +

      Functions

      +

      read: func

      +

      Read bytes from a stream.

      +

      This function returns a list of bytes containing the data that was +read, along with a bool indicating whether the end of the stream +was reached. The returned list will contain up to len bytes; it +may return fewer than requested, but not more.

      +

      Once a stream has reached the end, subsequent calls to read or +skip will always report end-of-stream rather than producing more +data.

      +

      If len is 0, it represents a request to read 0 bytes, which should +always succeed, assuming the stream hasn't reached its end yet, and +return an empty list.

      +

      The len here is a u64, but some callees may not be able to allocate +a buffer as large as that would imply. +FIXME: describe what happens if allocation fails.

      +
      Params
      + +
      Return values
      + +

      skip: func

      +

      Skip bytes from a stream.

      +

      This is similar to the read function, but avoids copying the +bytes into the instance.

      +

      Once a stream has reached the end, subsequent calls to read or +skip will always report end-of-stream rather than producing more +data.

      +

      This function returns the number of bytes skipped, along with a bool +indicating whether the end of the stream was reached. The returned +value will be at most len; it may be less.

      +
      Params
      + +
      Return values
      + +

      subscribe-to-input-stream: func

      +

      Create a pollable which will resolve once either the specified stream +has bytes available to read or the other end of the stream has been +closed.

      +
      Params
      + +
      Return values
      + +

      drop-input-stream: func

      +

      Dispose of the specified input-stream, after which it may no longer +be used.

      +
      Params
      + +

      write: func

      +

      Write bytes to a stream.

      +

      This function returns a u64 indicating the number of bytes from +buf that were written; it may be less than the full list.

      +
      Params
      + +
      Return values
      + +

      write-zeroes: func

      +

      Write multiple zero bytes to a stream.

      +

      This function returns a u64 indicating the number of zero bytes +that were written; it may be less than len.

      +
      Params
      + +
      Return values
      + +

      splice: func

      +

      Read from one stream and write to another.

      +

      This function returns the number of bytes transferred; it may be less +than len.

      +
      Params
      + +
      Return values
      + +

      forward: func

      +

      Forward the entire contents of an input stream to an output stream.

      +

      This function repeatedly reads from the input stream and writes +the data to the output stream, until the end of the input stream +is reached, or an error is encountered.

      +

      This function returns the number of bytes transferred.

      +
      Params
      + +
      Return values
      + +

      subscribe-to-output-stream: func

      +

      Create a pollable which will resolve once either the specified stream +is ready to accept bytes or the other end of the stream has been closed.

      +
      Params
      + +
      Return values
      + +

      drop-output-stream: func

      +

      Dispose of the specified output-stream, after which it may no longer +be used.

      +
      Params
      + +

      Import interface filesystem

      +

      WASI filesystem is a filesystem API primarily intended to let users run WASI +programs that access their files on their existing filesystems, without +significant overhead.

      +

      It is intended to be roughly portable between Unix-family platforms and +Windows, though it does not hide many of the major differences.

      +

      Paths are passed as interface-type strings, meaning they must consist of +a sequence of Unicode Scalar Values (USVs). Some filesystems may contain +paths which are not accessible by this API.

      +

      The directory separator in WASI is always the forward-slash (/).

      +

      All paths in WASI are relative paths, and are interpreted relative to a +descriptor referring to a base directory. If a path argument to any WASI +function starts with /, or if any step of resolving a path, including +.. and symbolic link steps, reaches a directory outside of the base +directory, or reaches a symlink to an absolute or rooted path in the +underlying filesystem, the function fails with error-code::not-permitted.

      +
      +

      Types

      +

      type input-stream

      +

      input-stream

      +

      +#### `type output-stream` +[`output-stream`](#output_stream) +

      +#### `type datetime` +[`datetime`](#datetime) +

      +#### `flags path-flags` +

      Flags determining the method of how paths are resolved.

      +
      Flags members
      +
        +
      • symlink-follow:

        As long as the resolved path corresponds to a symbolic link, it is +expanded. +

      • +
      +

      flags open-flags

      +

      Open flags used by open-at.

      +
      Flags members
      +
        +
      • +

        create:

        +

        Create file if it does not exist, similar to `O_CREAT` in POSIX. +

      • +
      • +

        directory:

        +

        Fail if not a directory, similar to `O_DIRECTORY` in POSIX. +

      • +
      • +

        exclusive:

        +

        Fail if file already exists, similar to `O_EXCL` in POSIX. +

      • +
      • +

        truncate:

        +

        Truncate file to size 0, similar to `O_TRUNC` in POSIX. +

      • +
      +

      flags modes

      +

      Permissions mode used by open-at, change-file-permissions-at, and +similar.

      +
      Flags members
      +
        +
      • +

        readable:

        +

        True if the resource is considered readable by the containing +filesystem. +

      • +
      • +

        writeable:

        +

        True if the resource is considered writeable by the containing +filesystem. +

      • +
      • +

        executable:

        +

        True if the resource is considered executable by the containing +filesystem. This does not apply to directories. +

      • +
      +

      type link-count

      +

      u64

      +

      Number of hard links to an inode. +

      type inode

      +

      u64

      +

      Filesystem object serial number that is unique within its file system. +

      type filesize

      +

      u64

      +

      File size or length of a region within a file. +

      enum error-code

      +

      Error codes returned by functions, similar to errno in POSIX. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX.

      +
      Enum Cases
      +
        +
      • +

        access

        +

        Permission denied, similar to `EACCES` in POSIX. +

      • +
      • +

        would-block

        +

        Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. +

      • +
      • +

        already

        +

        Connection already in progress, similar to `EALREADY` in POSIX. +

      • +
      • +

        bad-descriptor

        +

        Bad descriptor, similar to `EBADF` in POSIX. +

      • +
      • +

        busy

        +

        Device or resource busy, similar to `EBUSY` in POSIX. +

      • +
      • +

        deadlock

        +

        Resource deadlock would occur, similar to `EDEADLK` in POSIX. +

      • +
      • +

        quota

        +

        Storage quota exceeded, similar to `EDQUOT` in POSIX. +

      • +
      • +

        exist

        +

        File exists, similar to `EEXIST` in POSIX. +

      • +
      • +

        file-too-large

        +

        File too large, similar to `EFBIG` in POSIX. +

      • +
      • +

        illegal-byte-sequence

        +

        Illegal byte sequence, similar to `EILSEQ` in POSIX. +

      • +
      • +

        in-progress

        +

        Operation in progress, similar to `EINPROGRESS` in POSIX. +

      • +
      • +

        interrupted

        +

        Interrupted function, similar to `EINTR` in POSIX. +

      • +
      • +

        invalid

        +

        Invalid argument, similar to `EINVAL` in POSIX. +

      • +
      • +

        io

        +

        I/O error, similar to `EIO` in POSIX. +

      • +
      • +

        is-directory

        +

        Is a directory, similar to `EISDIR` in POSIX. +

      • +
      • +

        loop

        +

        Too many levels of symbolic links, similar to `ELOOP` in POSIX. +

      • +
      • +

        too-many-links

        +

        Too many links, similar to `EMLINK` in POSIX. +

      • +
      • +

        message-size

        +

        Message too large, similar to `EMSGSIZE` in POSIX. +

      • +
      • +

        name-too-long

        +

        Filename too long, similar to `ENAMETOOLONG` in POSIX. +

      • +
      • +

        no-device

        +

        No such device, similar to `ENODEV` in POSIX. +

      • +
      • +

        no-entry

        +

        No such file or directory, similar to `ENOENT` in POSIX. +

      • +
      • +

        no-lock

        +

        No locks available, similar to `ENOLCK` in POSIX. +

      • +
      • +

        insufficient-memory

        +

        Not enough space, similar to `ENOMEM` in POSIX. +

      • +
      • +

        insufficient-space

        +

        No space left on device, similar to `ENOSPC` in POSIX. +

      • +
      • +

        not-directory

        +

        Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. +

      • +
      • +

        not-empty

        +

        Directory not empty, similar to `ENOTEMPTY` in POSIX. +

      • +
      • +

        not-recoverable

        +

        State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. +

      • +
      • +

        unsupported

        +

        Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. +

      • +
      • +

        no-tty

        +

        Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. +

      • +
      • +

        no-such-device

        +

        No such device or address, similar to `ENXIO` in POSIX. +

      • +
      • +

        overflow

        +

        Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. +

      • +
      • +

        not-permitted

        +

        Operation not permitted, similar to `EPERM` in POSIX. +

      • +
      • +

        pipe

        +

        Broken pipe, similar to `EPIPE` in POSIX. +

      • +
      • +

        read-only

        +

        Read-only file system, similar to `EROFS` in POSIX. +

      • +
      • +

        invalid-seek

        +

        Invalid seek, similar to `ESPIPE` in POSIX. +

      • +
      • +

        text-file-busy

        +

        Text file busy, similar to `ETXTBSY` in POSIX. +

      • +
      • +

        cross-device

        +

        Cross-device link, similar to `EXDEV` in POSIX. +

      • +
      +

      type directory-entry-stream

      +

      u32

      +

      A stream of directory entries. +

      This represents a stream of dir-entry.

      +

      type device

      +

      u64

      +

      Identifier for a device containing a file system. Can be used in +combination with `inode` to uniquely identify a file or directory in +the filesystem. +

      enum descriptor-type

      +

      The type of a filesystem object referenced by a descriptor.

      +

      Note: This was called filetype in earlier versions of WASI.

      +
      Enum Cases
      +
        +
      • +

        unknown

        +

        The type of the descriptor or file is unknown or is different from +any of the other types specified. +

      • +
      • +

        block-device

        +

        The descriptor refers to a block device inode. +

      • +
      • +

        character-device

        +

        The descriptor refers to a character device inode. +

      • +
      • +

        directory

        +

        The descriptor refers to a directory inode. +

      • +
      • +

        fifo

        +

        The descriptor refers to a named pipe. +

      • +
      • +

        symbolic-link

        +

        The file refers to a symbolic link inode. +

      • +
      • +

        regular-file

        +

        The descriptor refers to a regular file inode. +

      • +
      • +

        socket

        +

        The descriptor refers to a socket. +

      • +
      +

      record directory-entry

      +

      A directory entry.

      +
      Record Fields
      +
        +
      • +

        inode: option<inode>

        +

        The serial number of the object referred to by this directory entry. +May be none if the inode value is not known. +

        When this is none, libc implementations might do an extra stat-at +call to retrieve the inode number to fill their d_ino fields, so +implementations which can set this to a non-none value should do so.

        +
      • +
      • +

        type: descriptor-type

        +

        The type of the file referred to by this directory entry. +

      • +
      • +

        name: string

        +

        The name of the object. +

      • +
      +

      flags descriptor-flags

      +

      Descriptor flags.

      +

      Note: This was called fdflags in earlier versions of WASI.

      +
      Flags members
      +
        +
      • +

        read:

        +

        Read mode: Data can be read. +

      • +
      • +

        write:

        +

        Write mode: Data can be written to. +

      • +
      • +

        non-blocking:

        +

        Requests non-blocking operation. +

        When this flag is enabled, functions may return immediately with an +error-code::would-block error code in situations where they would +otherwise block. However, this non-blocking behavior is not +required. Implementations are permitted to ignore this flag and +block. This is similar to O_NONBLOCK in POSIX.

        +
      • +
      • +

        file-integrity-sync:

        +

        Request that writes be performed according to synchronized I/O file +integrity completion. The data stored in the file and the file's +metadata are synchronized. This is similar to `O_SYNC` in POSIX. +

        The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

        +
      • +
      • +

        data-integrity-sync:

        +

        Request that writes be performed according to synchronized I/O data +integrity completion. Only the data stored in the file is +synchronized. This is similar to `O_DSYNC` in POSIX. +

        The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

        +
      • +
      • +

        requested-write-sync:

        +

        Requests that reads be performed at the same level of integrety +requested for writes. This is similar to `O_RSYNC` in POSIX. +

        The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

        +
      • +
      • +

        mutate-directory:

        +

        Mutating directories mode: Directory contents may be mutated. +

        When this flag is unset on a descriptor, operations using the +descriptor which would create, rename, delete, modify the data or +metadata of filesystem objects, or obtain another handle which +would permit any of those, shall fail with error-code::read-only if +they would otherwise succeed.

        +

        This may only be set on directories.

        +
      • +
      +

      type descriptor

      +

      u32

      +

      A descriptor is a reference to a filesystem object, which may be a file, +directory, named pipe, special file, or other object on which filesystem +calls may be made. +

      This represents a resource.

      +

      variant new-timestamp

      +

      When setting a timestamp, this gives the value to set it to.

      +
      Variant Cases
      +
        +
      • +

        no-change

        +

        Leave the timestamp set to its previous value. +

      • +
      • +

        now

        +

        Set the timestamp to the current time of the system clock associated +with the filesystem. +

      • +
      • +

        timestamp: datetime

        +

        Set the timestamp to the given value. +

      • +
      +

      record descriptor-stat

      +

      File attributes.

      +

      Note: This was called filestat in earlier versions of WASI.

      +
      Record Fields
      + +

      enum advice

      +

      File or memory access pattern advisory information.

      +
      Enum Cases
      +
        +
      • +

        normal

        +

        The application has no advice to give on its behavior with respect +to the specified data. +

      • +
      • +

        sequential

        +

        The application expects to access the specified data sequentially +from lower offsets to higher offsets. +

      • +
      • +

        random

        +

        The application expects to access the specified data in a random +order. +

      • +
      • +

        will-need

        +

        The application expects to access the specified data in the near +future. +

      • +
      • +

        dont-need

        +

        The application expects that it will not access the specified data +in the near future. +

      • +
      • +

        no-reuse

        +

        The application expects to access the specified data once and then +not reuse it thereafter. +

      • +
      +
      +

      Functions

      +

      read-via-stream: func

      +

      Return a stream for reading from a file.

      +

      Multiple read, write, and append streams may be active on the same open +file and they do not interfere with each other.

      +

      Note: This allows using read-stream, which is similar to read in POSIX.

      +
      Params
      + +
      Return values
      + +

      write-via-stream: func

      +

      Return a stream for writing to a file.

      +

      Note: This allows using write-stream, which is similar to write in +POSIX.

      +
      Params
      + +
      Return values
      + +

      append-via-stream: func

      +

      Return a stream for appending to a file.

      +

      Note: This allows using write-stream, which is similar to write with +O_APPEND in in POSIX.

      +
      Params
      + +
      Return values
      + +

      advise: func

      +

      Provide file advisory information on a descriptor.

      +

      This is similar to posix_fadvise in POSIX.

      +
      Params
      + +
      Return values
      + +

      sync-data: func

      +

      Synchronize the data of a file to disk.

      +

      This function succeeds with no effect if the file descriptor is not +opened for writing.

      +

      Note: This is similar to fdatasync in POSIX.

      +
      Params
      + +
      Return values
      + +

      get-flags: func

      +

      Get flags associated with a descriptor.

      +

      Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

      +

      Note: This returns the value that was the fs_flags value returned +from fdstat_get in earlier versions of WASI.

      +
      Params
      + +
      Return values
      + +

      get-type: func

      +

      Get the dynamic type of a descriptor.

      +

      Note: This returns the same value as the type field of the fd-stat +returned by stat, stat-at and similar.

      +

      Note: This returns similar flags to the st_mode & S_IFMT value provided +by fstat in POSIX.

      +

      Note: This returns the value that was the fs_filetype value returned +from fdstat_get in earlier versions of WASI.

      +
      Params
      + +
      Return values
      + +

      set-flags: func

      +

      Set status flags associated with a descriptor.

      +

      This function may only change the non-blocking flag.

      +

      Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

      +

      Note: This was called fd_fdstat_set_flags in earlier versions of WASI.

      +
      Params
      + +
      Return values
      + +

      set-size: func

      +

      Adjust the size of an open file. If this increases the file's size, the +extra bytes are filled with zeros.

      +

      Note: This was called fd_filestat_set_size in earlier versions of WASI.

      +
      Params
      + +
      Return values
      + +

      set-times: func

      +

      Adjust the timestamps of an open file or directory.

      +

      Note: This is similar to futimens in POSIX.

      +

      Note: This was called fd_filestat_set_times in earlier versions of WASI.

      +
      Params
      + +
      Return values
      + +

      read: func

      +

      Read from a descriptor, without using and updating the descriptor's offset.

      +

      This function returns a list of bytes containing the data that was +read, along with a bool which, when true, indicates that the end of the +file was reached. The returned list will contain up to length bytes; it +may return fewer than requested, if the end of the file is reached or +if the I/O operation is interrupted.

      +

      In the future, this may change to return a stream<u8, error-code>.

      +

      Note: This is similar to pread in POSIX.

      +
      Params
      + +
      Return values
      + +

      write: func

      +

      Write to a descriptor, without using and updating the descriptor's offset.

      +

      It is valid to write past the end of a file; the file is extended to the +extent of the write, with bytes between the previous end and the start of +the write set to zero.

      +

      In the future, this may change to take a stream<u8, error-code>.

      +

      Note: This is similar to pwrite in POSIX.

      +
      Params
      + +
      Return values
      + +

      read-directory: func

      +

      Read directory entries from a directory.

      +

      On filesystems where directories contain entries referring to themselves +and their parents, often named . and .. respectively, these entries +are omitted.

      +

      This always returns a new stream which starts at the beginning of the +directory. Multiple streams may be active on the same directory, and they +do not interfere with each other.

      +
      Params
      + +
      Return values
      + +

      sync: func

      +

      Synchronize the data and metadata of a file to disk.

      +

      This function succeeds with no effect if the file descriptor is not +opened for writing.

      +

      Note: This is similar to fsync in POSIX.

      +
      Params
      + +
      Return values
      + +

      create-directory-at: func

      +

      Create a directory.

      +

      Note: This is similar to mkdirat in POSIX.

      +
      Params
      + +
      Return values
      + +

      stat: func

      +

      Return the attributes of an open file or directory.

      +

      Note: This is similar to fstat in POSIX.

      +

      Note: This was called fd_filestat_get in earlier versions of WASI.

      +
      Params
      + +
      Return values
      + +

      stat-at: func

      +

      Return the attributes of a file or directory.

      +

      Note: This is similar to fstatat in POSIX.

      +

      Note: This was called path_filestat_get in earlier versions of WASI.

      +
      Params
      + +
      Return values
      + +

      set-times-at: func

      +

      Adjust the timestamps of a file or directory.

      +

      Note: This is similar to utimensat in POSIX.

      +

      Note: This was called path_filestat_set_times in earlier versions of +WASI.

      +
      Params
      + +
      Return values
      + +

      link-at: func

      +

      Create a hard link.

      +

      Note: This is similar to linkat in POSIX.

      +
      Params
      + +
      Return values
      + +

      open-at: func

      +

      Open a file or directory.

      +

      The returned descriptor is not guaranteed to be the lowest-numbered +descriptor not currently open/ it is randomized to prevent applications +from depending on making assumptions about indexes, since this is +error-prone in multi-threaded contexts. The returned descriptor is +guaranteed to be less than 2**31.

      +

      If flags contains descriptor-flags::mutate-directory, and the base +descriptor doesn't have descriptor-flags::mutate-directory set, +open-at fails with error-code::read-only.

      +

      If flags contains write or mutate-directory, or open-flags +contains truncate or create, and the base descriptor doesn't have +descriptor-flags::mutate-directory set, open-at fails with +error-code::read-only.

      +

      Note: This is similar to openat in POSIX.

      +
      Params
      + +
      Return values
      + +

      readlink-at: func

      +

      Read the contents of a symbolic link.

      +

      If the contents contain an absolute or rooted path in the underlying +filesystem, this function fails with error-code::not-permitted.

      +

      Note: This is similar to readlinkat in POSIX.

      +
      Params
      + +
      Return values
      + +

      remove-directory-at: func

      +

      Remove a directory.

      +

      Return error-code::not-empty if the directory is not empty.

      +

      Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

      +
      Params
      + +
      Return values
      + +

      rename-at: func

      +

      Rename a filesystem object.

      +

      Note: This is similar to renameat in POSIX.

      +
      Params
      + +
      Return values
      + +

      symlink-at: func

      +

      Create a symbolic link (also known as a "symlink").

      +

      If old-path starts with /, the function fails with +error-code::not-permitted.

      +

      Note: This is similar to symlinkat in POSIX.

      +
      Params
      + +
      Return values
      + +

      unlink-file-at: func

      +

      Unlink a filesystem object that is not a directory.

      +

      Return error-code::is-directory if the path refers to a directory. +Note: This is similar to unlinkat(fd, path, 0) in POSIX.

      +
      Params
      + +
      Return values
      + +

      change-file-permissions-at: func

      +

      Change the permissions of a filesystem object that is not a directory.

      +

      Note that the ultimate meanings of these permissions is +filesystem-specific.

      +

      Note: This is similar to fchmodat in POSIX.

      +
      Params
      + +
      Return values
      + +

      change-directory-permissions-at: func

      +

      Change the permissions of a directory.

      +

      Note that the ultimate meanings of these permissions is +filesystem-specific.

      +

      Unlike in POSIX, the executable flag is not reinterpreted as a "search" +flag. read on a directory implies readability and searchability, and +execute is not valid for directories.

      +

      Note: This is similar to fchmodat in POSIX.

      +
      Params
      + +
      Return values
      + +

      lock-shared: func

      +

      Request a shared advisory lock for an open file.

      +

      This requests a shared lock; more than one shared lock can be held for +a file at the same time.

      +

      If the open file has an exclusive lock, this function downgrades the lock +to a shared lock. If it has a shared lock, this function has no effect.

      +

      This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

      +

      It is unspecified how shared locks interact with locks acquired by +non-WASI programs.

      +

      This function blocks until the lock can be acquired.

      +

      Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

      +

      Note: This is similar to flock(fd, LOCK_SH) in Unix.

      +
      Params
      + +
      Return values
      + +

      lock-exclusive: func

      +

      Request an exclusive advisory lock for an open file.

      +

      This requests an exclusive lock; no other locks may be held for the +file while an exclusive lock is held.

      +

      If the open file has a shared lock and there are no exclusive locks held +for the file, this function upgrades the lock to an exclusive lock. If the +open file already has an exclusive lock, this function has no effect.

      +

      This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

      +

      It is unspecified whether this function succeeds if the file descriptor +is not opened for writing. It is unspecified how exclusive locks interact +with locks acquired by non-WASI programs.

      +

      This function blocks until the lock can be acquired.

      +

      Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

      +

      Note: This is similar to flock(fd, LOCK_EX) in Unix.

      +
      Params
      + +
      Return values
      + +

      try-lock-shared: func

      +

      Request a shared advisory lock for an open file.

      +

      This requests a shared lock; more than one shared lock can be held for +a file at the same time.

      +

      If the open file has an exclusive lock, this function downgrades the lock +to a shared lock. If it has a shared lock, this function has no effect.

      +

      This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

      +

      It is unspecified how shared locks interact with locks acquired by +non-WASI programs.

      +

      This function returns error-code::would-block if the lock cannot be +acquired.

      +

      Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

      +

      Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

      +
      Params
      + +
      Return values
      + +

      try-lock-exclusive: func

      +

      Request an exclusive advisory lock for an open file.

      +

      This requests an exclusive lock; no other locks may be held for the +file while an exclusive lock is held.

      +

      If the open file has a shared lock and there are no exclusive locks held +for the file, this function upgrades the lock to an exclusive lock. If the +open file already has an exclusive lock, this function has no effect.

      +

      This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

      +

      It is unspecified whether this function succeeds if the file descriptor +is not opened for writing. It is unspecified how exclusive locks interact +with locks acquired by non-WASI programs.

      +

      This function returns error-code::would-block if the lock cannot be +acquired.

      +

      Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

      +

      Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

      +
      Params
      + +
      Return values
      + +

      unlock: func

      +

      Release a shared or exclusive lock on an open file.

      +

      Note: This is similar to flock(fd, LOCK_UN) in Unix.

      +
      Params
      + +
      Return values
      + +

      drop-descriptor: func

      +

      Dispose of the specified descriptor, after which it may no longer +be used.

      +
      Params
      + +

      read-directory-entry: func

      +

      Read a single directory entry from a directory-entry-stream.

      +
      Params
      + +
      Return values
      + +

      drop-directory-entry-stream: func

      +

      Dispose of the specified directory-entry-stream, after which it may no longer +be used.

      +
      Params
      + +

      Import interface random

      +

      WASI Random is a random data API.

      +

      It is intended to be portable at least between Unix-family platforms and +Windows.

      +
      +

      Functions

      +

      get-random-bytes: func

      +

      Return len cryptographically-secure pseudo-random bytes.

      +

      This function must produce data from an adequately seeded +cryptographically-secure pseudo-random number generator (CSPRNG), so it +must not block, from the perspective of the calling program, and the +returned data is always unpredictable.

      +

      This function must always return fresh pseudo-random data. Deterministic +environments must omit this function, rather than implementing it with +deterministic data.

      +
      Params
      + +
      Return values
      +
        +
      • list<u8>
      • +
      +

      get-random-u64: func

      +

      Return a cryptographically-secure pseudo-random u64 value.

      +

      This function returns the same type of pseudo-random data as +get-random-bytes, represented as a u64.

      +
      Return values
      +
        +
      • u64
      • +
      +

      insecure-random: func

      +

      Return a 128-bit value that may contain a pseudo-random value.

      +

      The returned value is not required to be computed from a CSPRNG, and may +even be entirely deterministic. Host implementations are encouraged to +provide pseudo-random values to any program exposed to +attacker-controlled content, to enable DoS protection built into many +languages' hash-map implementations.

      +

      This function is intended to only be called once, by a source language +to initialize Denial Of Service (DoS) protection in its hash-map +implementation.

      +

      Expected future evolution

      +

      This will likely be changed to a value import, to prevent it from being +called multiple times and potentially used for purposes other than DoS +protection.

      +
      Return values
      +
        +
      • (u64, u64)
      • +
      +

      Import interface exit

      +
      +

      Functions

      +

      exit: func

      +

      Exit the curerent instance and any linked instances.

      +
      Params
      + +

      Exported types from world cli

      +
      +

      Types

      +

      type input-stream

      +

      input-stream

      +

      +#### `type output-stream` +[`output-stream`](#output_stream) +

      +#### `type descriptor` +[`descriptor`](#descriptor) +

      +## Exported functions from world `cli` +

      command: func

      +
      Params
      + +
      Return values
      +
        +
      • result
      • +
      diff --git a/proposals/cli/wit/cli.wit b/proposals/cli/wit/cli.wit new file mode 100644 index 000000000..3946023c6 --- /dev/null +++ b/proposals/cli/wit/cli.wit @@ -0,0 +1,23 @@ +default world cli { + import wall-clock: clocks.wall-clock + import monotonic-clock: clocks.monotonic-clock + import instance-wall-clock: clocks.instance-wall-clock + import instance-monotonic-clock: clocks.instance-monotonic-clock + import timezone: clocks.timezone + import filesystem: filesystem.filesystem + import random: random.random + import poll: poll.poll + import io: io.streams + import exit: pkg.exit + + use io.streams.{input-stream, output-stream} + use filesystem.filesystem.{descriptor} + + export command: func( + stdin: input-stream, + stdout: output-stream, + stderr: output-stream, + args: list, + preopens: list>, + ) -> result +} diff --git a/proposals/cli/wit/deps/clocks/instance-monotonic-clock.wit b/proposals/cli/wit/deps/clocks/instance-monotonic-clock.wit new file mode 100644 index 000000000..4cffa4a57 --- /dev/null +++ b/proposals/cli/wit/deps/clocks/instance-monotonic-clock.wit @@ -0,0 +1,15 @@ +/// This interfaces proves a clock handles for monotonic clock, suitable for +/// general-purpose application needs. +default interface instance-monotonic-clock { + use pkg.monotonic-clock.{monotonic-clock} + + /// Return a handle to a monotonic clock, suitable for general-purpose + /// application needs. + /// + /// This allocates a new handle, so applications with frequent need of a + /// clock handle should call this function once and reuse the handle + /// instead of calling this function each time. + /// + /// This [represents a value import](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Value_Imports). + instance-monotonic-clock: func() -> monotonic-clock +} diff --git a/proposals/cli/wit/deps/clocks/instance-wall-clock.wit b/proposals/cli/wit/deps/clocks/instance-wall-clock.wit new file mode 100644 index 000000000..3a55b5526 --- /dev/null +++ b/proposals/cli/wit/deps/clocks/instance-wall-clock.wit @@ -0,0 +1,15 @@ +/// This interfaces proves a clock handles for wall clock, suitable for +/// general-purpose application needs. +default interface instance-wall-clock { + use pkg.wall-clock.{wall-clock} + + /// Return a handle to a wall clock, suitable for general-purpose + /// application needs. + /// + /// This allocates a new handle, so applications with frequent need of a + /// clock handle should call this function once and reuse the handle + /// instead of calling this function each time. + /// + /// This [represents a value import](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Value_Imports). + instance-wall-clock: func() -> wall-clock +} diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit new file mode 100644 index 000000000..51c2203c9 --- /dev/null +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -0,0 +1,40 @@ +/// WASI Monotonic Clock is a clock API intended to let users measure elapsed +/// time. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface monotonic-clock { + use poll.poll.{pollable} + + /// A timestamp in nanoseconds. + type instant = u64 + + /// A monotonic clock is a clock which has an unspecified initial value, and + /// successive reads of the clock will produce non-decreasing values. + /// + /// It is intended for measuring elapsed time. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type monotonic-clock = u32 + + /// Read the current value of the clock. + /// + /// The clock is monotonic, therefore calling this function repeatedly will + /// produce a sequence of non-decreasing values. + now: func(this: monotonic-clock) -> instant + + /// Query the resolution of the clock. + resolution: func(this: monotonic-clock) -> instant + + /// Create a `pollable` which will resolve once the specified time has been + /// reached. + subscribe: func( + this: monotonic-clock, + when: instant, + absolute: bool + ) -> pollable + + /// Dispose of the specified `monotonic-clock`, after which it may no longer + /// be used. + drop-monotonic-clock: func(this: monotonic-clock) +} diff --git a/proposals/cli/wit/deps/clocks/timezone.wit b/proposals/cli/wit/deps/clocks/timezone.wit new file mode 100644 index 000000000..63f99cc40 --- /dev/null +++ b/proposals/cli/wit/deps/clocks/timezone.wit @@ -0,0 +1,61 @@ +default interface timezone { + use pkg.wall-clock.{datetime} + + /// A timezone. + /// + /// In timezones that recognize daylight saving time, also known as daylight + /// time and summer time, the information returned from the functions varies + /// over time to reflect these adjustments. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type timezone = u32 + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + display: func(this: timezone, when: datetime) -> timezone-display + + /// The same as `display`, but only return the UTC offset. + utc-offset: func(this: timezone, when: datetime) -> s32 + + /// Dispose of the specified input-stream, after which it may no longer + /// be used. + drop-timezone: func(this: timezone) + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit new file mode 100644 index 000000000..c60861acd --- /dev/null +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -0,0 +1,48 @@ +/// WASI Wall Clock is a clock API intended to let users query the current +/// time. The name "wall" makes an analogy to a "clock on the wall", which +/// is not necessarily monotonic as it may be reset. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface wall-clock { + /// A time and date in seconds plus nanoseconds. + record datetime { + seconds: u64, + nanoseconds: u32, + } + + /// A wall clock is a clock which measures the date and time according to + /// some external reference. + /// + /// External references may be reset, so this clock is not necessarily + /// monotonic, making it unsuitable for measuring elapsed time. + /// + /// It is intended for reporting the current date and time for humans. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type wall-clock = u32 + + /// Read the current value of the clock. + /// + /// This clock is not monotonic, therefore calling this function repeatedly + /// will not necessarily produce a sequence of non-decreasing values. + /// + /// The returned timestamps represent the number of seconds since + /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], + /// also known as [Unix Time]. + /// + /// The nanoseconds field of the output is always less than 1000000000. + /// + /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + now: func(this: wall-clock) -> datetime + + /// Query the resolution of the clock. + /// + /// The nanoseconds field of the output is always less than 1000000000. + resolution: func(this: wall-clock) -> datetime + + /// Dispose of the specified `wall-clock`, after which it may no longer + /// be used. + drop-wall-clock: func(this: wall-clock) +} diff --git a/proposals/cli/wit/deps/filesystem/filesystem.wit b/proposals/cli/wit/deps/filesystem/filesystem.wit new file mode 100644 index 000000000..fafd4b96f --- /dev/null +++ b/proposals/cli/wit/deps/filesystem/filesystem.wit @@ -0,0 +1,770 @@ +/// WASI filesystem is a filesystem API primarily intended to let users run WASI +/// programs that access their files on their existing filesystems, without +/// significant overhead. +/// +/// It is intended to be roughly portable between Unix-family platforms and +/// Windows, though it does not hide many of the major differences. +/// +/// Paths are passed as interface-type `string`s, meaning they must consist of +/// a sequence of Unicode Scalar Values (USVs). Some filesystems may contain +/// paths which are not accessible by this API. +/// +/// The directory separator in WASI is always the forward-slash (`/`). +/// +/// All paths in WASI are relative paths, and are interpreted relative to a +/// `descriptor` referring to a base directory. If a `path` argument to any WASI +/// function starts with `/`, or if any step of resolving a `path`, including +/// `..` and symbolic link steps, reaches a directory outside of the base +/// directory, or reaches a symlink to an absolute or rooted path in the +/// underlying filesystem, the function fails with `error-code::not-permitted`. +default interface filesystem { + use io.streams.{input-stream, output-stream} + use clocks.wall-clock.{datetime} + + /// File size or length of a region within a file. + type filesize = u64 + + /// The type of a filesystem object referenced by a descriptor. + /// + /// Note: This was called `filetype` in earlier versions of WASI. + enum descriptor-type { + /// The type of the descriptor or file is unknown or is different from + /// any of the other types specified. + unknown, + /// The descriptor refers to a block device inode. + block-device, + /// The descriptor refers to a character device inode. + character-device, + /// The descriptor refers to a directory inode. + directory, + /// The descriptor refers to a named pipe. + fifo, + /// The file refers to a symbolic link inode. + symbolic-link, + /// The descriptor refers to a regular file inode. + regular-file, + /// The descriptor refers to a socket. + socket, + } + + /// Descriptor flags. + /// + /// Note: This was called `fdflags` in earlier versions of WASI. + flags descriptor-flags { + /// Read mode: Data can be read. + read, + /// Write mode: Data can be written to. + write, + /// Requests non-blocking operation. + /// + /// When this flag is enabled, functions may return immediately with an + /// `error-code::would-block` error code in situations where they would + /// otherwise block. However, this non-blocking behavior is not + /// required. Implementations are permitted to ignore this flag and + /// block. This is similar to `O_NONBLOCK` in POSIX. + non-blocking, + /// Request that writes be performed according to synchronized I/O file + /// integrity completion. The data stored in the file and the file's + /// metadata are synchronized. This is similar to `O_SYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + file-integrity-sync, + /// Request that writes be performed according to synchronized I/O data + /// integrity completion. Only the data stored in the file is + /// synchronized. This is similar to `O_DSYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + data-integrity-sync, + /// Requests that reads be performed at the same level of integrety + /// requested for writes. This is similar to `O_RSYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + requested-write-sync, + /// Mutating directories mode: Directory contents may be mutated. + /// + /// When this flag is unset on a descriptor, operations using the + /// descriptor which would create, rename, delete, modify the data or + /// metadata of filesystem objects, or obtain another handle which + /// would permit any of those, shall fail with `error-code::read-only` if + /// they would otherwise succeed. + /// + /// This may only be set on directories. + mutate-directory, + } + + /// File attributes. + /// + /// Note: This was called `filestat` in earlier versions of WASI. + record descriptor-stat { + /// Device ID of device containing the file. + device: device, + /// File serial number. + inode: inode, + /// File type. + %type: descriptor-type, + /// Number of hard links to the file. + link-count: link-count, + /// For regular files, the file size in bytes. For symbolic links, the + /// length in bytes of the pathname contained in the symbolic link. + size: filesize, + /// Last data access timestamp. + data-access-timestamp: datetime, + /// Last data modification timestamp. + data-modification-timestamp: datetime, + /// Last file status change timestamp. + status-change-timestamp: datetime, + } + + /// Flags determining the method of how paths are resolved. + flags path-flags { + /// As long as the resolved path corresponds to a symbolic link, it is + /// expanded. + symlink-follow, + } + + /// Open flags used by `open-at`. + flags open-flags { + /// Create file if it does not exist, similar to `O_CREAT` in POSIX. + create, + /// Fail if not a directory, similar to `O_DIRECTORY` in POSIX. + directory, + /// Fail if file already exists, similar to `O_EXCL` in POSIX. + exclusive, + /// Truncate file to size 0, similar to `O_TRUNC` in POSIX. + truncate, + } + + /// Permissions mode used by `open-at`, `change-file-permissions-at`, and + /// similar. + flags modes { + /// True if the resource is considered readable by the containing + /// filesystem. + readable, + /// True if the resource is considered writeable by the containing + /// filesystem. + writeable, + /// True if the resource is considered executable by the containing + /// filesystem. This does not apply to directories. + executable, + } + + /// Number of hard links to an inode. + type link-count = u64 + + /// Identifier for a device containing a file system. Can be used in + /// combination with `inode` to uniquely identify a file or directory in + /// the filesystem. + type device = u64 + + /// Filesystem object serial number that is unique within its file system. + type inode = u64 + + /// When setting a timestamp, this gives the value to set it to. + variant new-timestamp { + /// Leave the timestamp set to its previous value. + no-change, + /// Set the timestamp to the current time of the system clock associated + /// with the filesystem. + now, + /// Set the timestamp to the given value. + timestamp(datetime), + } + + /// A directory entry. + record directory-entry { + /// The serial number of the object referred to by this directory entry. + /// May be none if the inode value is not known. + /// + /// When this is none, libc implementations might do an extra `stat-at` + /// call to retrieve the inode number to fill their `d_ino` fields, so + /// implementations which can set this to a non-none value should do so. + inode: option, + + /// The type of the file referred to by this directory entry. + %type: descriptor-type, + + /// The name of the object. + name: string, + } + + /// Error codes returned by functions, similar to `errno` in POSIX. + /// Not all of these error codes are returned by the functions provided by this + /// API; some are used in higher-level library layers, and others are provided + /// merely for alignment with POSIX. + enum error-code { + /// Permission denied, similar to `EACCES` in POSIX. + access, + /// Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. + would-block, + /// Connection already in progress, similar to `EALREADY` in POSIX. + already, + /// Bad descriptor, similar to `EBADF` in POSIX. + bad-descriptor, + /// Device or resource busy, similar to `EBUSY` in POSIX. + busy, + /// Resource deadlock would occur, similar to `EDEADLK` in POSIX. + deadlock, + /// Storage quota exceeded, similar to `EDQUOT` in POSIX. + quota, + /// File exists, similar to `EEXIST` in POSIX. + exist, + /// File too large, similar to `EFBIG` in POSIX. + file-too-large, + /// Illegal byte sequence, similar to `EILSEQ` in POSIX. + illegal-byte-sequence, + /// Operation in progress, similar to `EINPROGRESS` in POSIX. + in-progress, + /// Interrupted function, similar to `EINTR` in POSIX. + interrupted, + /// Invalid argument, similar to `EINVAL` in POSIX. + invalid, + /// I/O error, similar to `EIO` in POSIX. + io, + /// Is a directory, similar to `EISDIR` in POSIX. + is-directory, + /// Too many levels of symbolic links, similar to `ELOOP` in POSIX. + loop, + /// Too many links, similar to `EMLINK` in POSIX. + too-many-links, + /// Message too large, similar to `EMSGSIZE` in POSIX. + message-size, + /// Filename too long, similar to `ENAMETOOLONG` in POSIX. + name-too-long, + /// No such device, similar to `ENODEV` in POSIX. + no-device, + /// No such file or directory, similar to `ENOENT` in POSIX. + no-entry, + /// No locks available, similar to `ENOLCK` in POSIX. + no-lock, + /// Not enough space, similar to `ENOMEM` in POSIX. + insufficient-memory, + /// No space left on device, similar to `ENOSPC` in POSIX. + insufficient-space, + /// Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. + not-directory, + /// Directory not empty, similar to `ENOTEMPTY` in POSIX. + not-empty, + /// State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. + not-recoverable, + /// Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. + unsupported, + /// Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. + no-tty, + /// No such device or address, similar to `ENXIO` in POSIX. + no-such-device, + /// Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. + overflow, + /// Operation not permitted, similar to `EPERM` in POSIX. + not-permitted, + /// Broken pipe, similar to `EPIPE` in POSIX. + pipe, + /// Read-only file system, similar to `EROFS` in POSIX. + read-only, + /// Invalid seek, similar to `ESPIPE` in POSIX. + invalid-seek, + /// Text file busy, similar to `ETXTBSY` in POSIX. + text-file-busy, + /// Cross-device link, similar to `EXDEV` in POSIX. + cross-device, + } + + /// File or memory access pattern advisory information. + enum advice { + /// The application has no advice to give on its behavior with respect + /// to the specified data. + normal, + /// The application expects to access the specified data sequentially + /// from lower offsets to higher offsets. + sequential, + /// The application expects to access the specified data in a random + /// order. + random, + /// The application expects to access the specified data in the near + /// future. + will-need, + /// The application expects that it will not access the specified data + /// in the near future. + dont-need, + /// The application expects to access the specified data once and then + /// not reuse it thereafter. + no-reuse, + } + + /// A descriptor is a reference to a filesystem object, which may be a file, + /// directory, named pipe, special file, or other object on which filesystem + /// calls may be made. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type descriptor = u32 + + /// Return a stream for reading from a file. + /// + /// Multiple read, write, and append streams may be active on the same open + /// file and they do not interfere with each other. + /// + /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. + read-via-stream: func( + this: descriptor, + /// The offset within the file at which to start reading. + offset: filesize, + ) -> result + + /// Return a stream for writing to a file. + /// + /// Note: This allows using `write-stream`, which is similar to `write` in + /// POSIX. + write-via-stream: func( + this: descriptor, + /// The offset within the file at which to start writing. + offset: filesize, + ) -> result + + /// Return a stream for appending to a file. + /// + /// Note: This allows using `write-stream`, which is similar to `write` with + /// `O_APPEND` in in POSIX. + append-via-stream: func( + this: descriptor, + /// The resource to operate on. + fd: descriptor, + ) -> result + + /// Provide file advisory information on a descriptor. + /// + /// This is similar to `posix_fadvise` in POSIX. + advise: func( + this: descriptor, + /// The offset within the file to which the advisory applies. + offset: filesize, + /// The length of the region to which the advisory applies. + length: filesize, + /// The advice. + advice: advice + ) -> result<_, error-code> + + /// Synchronize the data of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fdatasync` in POSIX. + sync-data: func(this: descriptor) -> result<_, error-code> + + /// Get flags associated with a descriptor. + /// + /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. + /// + /// Note: This returns the value that was the `fs_flags` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-flags: func(this: descriptor) -> result + + /// Get the dynamic type of a descriptor. + /// + /// Note: This returns the same value as the `type` field of the `fd-stat` + /// returned by `stat`, `stat-at` and similar. + /// + /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided + /// by `fstat` in POSIX. + /// + /// Note: This returns the value that was the `fs_filetype` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-type: func(this: descriptor) -> result + + /// Set status flags associated with a descriptor. + /// + /// This function may only change the `non-blocking` flag. + /// + /// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + /// + /// Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. + set-flags: func(this: descriptor, %flags: descriptor-flags) -> result<_, error-code> + + /// Adjust the size of an open file. If this increases the file's size, the + /// extra bytes are filled with zeros. + /// + /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. + set-size: func(this: descriptor, size: filesize) -> result<_, error-code> + + /// Adjust the timestamps of an open file or directory. + /// + /// Note: This is similar to `futimens` in POSIX. + /// + /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. + set-times: func( + this: descriptor, + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code> + + /// Read from a descriptor, without using and updating the descriptor's offset. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a bool which, when true, indicates that the end of the + /// file was reached. The returned list will contain up to `length` bytes; it + /// may return fewer than requested, if the end of the file is reached or + /// if the I/O operation is interrupted. + /// + /// In the future, this may change to return a `stream`. + /// + /// Note: This is similar to `pread` in POSIX. + read: func( + this: descriptor, + /// The maximum number of bytes to read. + length: filesize, + /// The offset within the file at which to read. + offset: filesize, + ) -> result, bool>, error-code> + + /// Write to a descriptor, without using and updating the descriptor's offset. + /// + /// It is valid to write past the end of a file; the file is extended to the + /// extent of the write, with bytes between the previous end and the start of + /// the write set to zero. + /// + /// In the future, this may change to take a `stream`. + /// + /// Note: This is similar to `pwrite` in POSIX. + write: func( + this: descriptor, + /// Data to write + buffer: list, + /// The offset within the file at which to write. + offset: filesize, + ) -> result + + /// Read directory entries from a directory. + /// + /// On filesystems where directories contain entries referring to themselves + /// and their parents, often named `.` and `..` respectively, these entries + /// are omitted. + /// + /// This always returns a new stream which starts at the beginning of the + /// directory. Multiple streams may be active on the same directory, and they + /// do not interfere with each other. + read-directory: func( + this: descriptor + ) -> result + + /// Synchronize the data and metadata of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fsync` in POSIX. + sync: func(this: descriptor) -> result<_, error-code> + + /// Create a directory. + /// + /// Note: This is similar to `mkdirat` in POSIX. + create-directory-at: func( + this: descriptor, + /// The relative path at which to create the directory. + path: string, + ) -> result<_, error-code> + + /// Return the attributes of an open file or directory. + /// + /// Note: This is similar to `fstat` in POSIX. + /// + /// Note: This was called `fd_filestat_get` in earlier versions of WASI. + stat: func(this: descriptor) -> result + + /// Return the attributes of a file or directory. + /// + /// Note: This is similar to `fstatat` in POSIX. + /// + /// Note: This was called `path_filestat_get` in earlier versions of WASI. + stat-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result + + /// Adjust the timestamps of a file or directory. + /// + /// Note: This is similar to `utimensat` in POSIX. + /// + /// Note: This was called `path_filestat_set_times` in earlier versions of + /// WASI. + set-times-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to operate on. + path: string, + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code> + + /// Create a hard link. + /// + /// Note: This is similar to `linkat` in POSIX. + link-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + old-path-flags: path-flags, + /// The relative source path from which to link. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: descriptor, + /// The relative destination path at which to create the hard link. + new-path: string, + ) -> result<_, error-code> + + /// Open a file or directory. + /// + /// The returned descriptor is not guaranteed to be the lowest-numbered + /// descriptor not currently open/ it is randomized to prevent applications + /// from depending on making assumptions about indexes, since this is + /// error-prone in multi-threaded contexts. The returned descriptor is + /// guaranteed to be less than 2**31. + /// + /// If `flags` contains `descriptor-flags::mutate-directory`, and the base + /// descriptor doesn't have `descriptor-flags::mutate-directory` set, + /// `open-at` fails with `error-code::read-only`. + /// + /// If `flags` contains `write` or `mutate-directory`, or `open-flags` + /// contains `truncate` or `create`, and the base descriptor doesn't have + /// `descriptor-flags::mutate-directory` set, `open-at` fails with + /// `error-code::read-only`. + /// + /// Note: This is similar to `openat` in POSIX. + open-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the object to open. + path: string, + /// The method by which to open the file. + open-flags: open-flags, + /// Flags to use for the resulting descriptor. + %flags: descriptor-flags, + /// Permissions to use when creating a new file. + modes: modes + ) -> result + + /// Read the contents of a symbolic link. + /// + /// If the contents contain an absolute or rooted path in the underlying + /// filesystem, this function fails with `error-code::not-permitted`. + /// + /// Note: This is similar to `readlinkat` in POSIX. + readlink-at: func( + this: descriptor, + /// The relative path of the symbolic link from which to read. + path: string, + ) -> result + + /// Remove a directory. + /// + /// Return `error-code::not-empty` if the directory is not empty. + /// + /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + remove-directory-at: func( + this: descriptor, + /// The relative path to a directory to remove. + path: string, + ) -> result<_, error-code> + + /// Rename a filesystem object. + /// + /// Note: This is similar to `renameat` in POSIX. + rename-at: func( + this: descriptor, + /// The relative source path of the file or directory to rename. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: descriptor, + /// The relative destination path to which to rename the file or directory. + new-path: string, + ) -> result<_, error-code> + + /// Create a symbolic link (also known as a "symlink"). + /// + /// If `old-path` starts with `/`, the function fails with + /// `error-code::not-permitted`. + /// + /// Note: This is similar to `symlinkat` in POSIX. + symlink-at: func( + this: descriptor, + /// The contents of the symbolic link. + old-path: string, + /// The relative destination path at which to create the symbolic link. + new-path: string, + ) -> result<_, error-code> + + /// Unlink a filesystem object that is not a directory. + /// + /// Return `error-code::is-directory` if the path refers to a directory. + /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + unlink-file-at: func( + this: descriptor, + /// The relative path to a file to unlink. + path: string, + ) -> result<_, error-code> + + /// Change the permissions of a filesystem object that is not a directory. + /// + /// Note that the ultimate meanings of these permissions is + /// filesystem-specific. + /// + /// Note: This is similar to `fchmodat` in POSIX. + change-file-permissions-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to operate on. + path: string, + /// The new permissions for the filesystem object. + modes: modes, + ) -> result<_, error-code> + + /// Change the permissions of a directory. + /// + /// Note that the ultimate meanings of these permissions is + /// filesystem-specific. + /// + /// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" + /// flag. `read` on a directory implies readability and searchability, and + /// `execute` is not valid for directories. + /// + /// Note: This is similar to `fchmodat` in POSIX. + change-directory-permissions-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to operate on. + path: string, + /// The new permissions for the directory. + modes: modes, + ) -> result<_, error-code> + + /// Request a shared advisory lock for an open file. + /// + /// This requests a *shared* lock; more than one shared lock can be held for + /// a file at the same time. + /// + /// If the open file has an exclusive lock, this function downgrades the lock + /// to a shared lock. If it has a shared lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified how shared locks interact with locks acquired by + /// non-WASI programs. + /// + /// This function blocks until the lock can be acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. + lock-shared: func(this: descriptor) -> result<_, error-code> + + /// Request an exclusive advisory lock for an open file. + /// + /// This requests an *exclusive* lock; no other locks may be held for the + /// file while an exclusive lock is held. + /// + /// If the open file has a shared lock and there are no exclusive locks held + /// for the file, this function upgrades the lock to an exclusive lock. If the + /// open file already has an exclusive lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified whether this function succeeds if the file descriptor + /// is not opened for writing. It is unspecified how exclusive locks interact + /// with locks acquired by non-WASI programs. + /// + /// This function blocks until the lock can be acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. + lock-exclusive: func(this: descriptor) -> result<_, error-code> + + /// Request a shared advisory lock for an open file. + /// + /// This requests a *shared* lock; more than one shared lock can be held for + /// a file at the same time. + /// + /// If the open file has an exclusive lock, this function downgrades the lock + /// to a shared lock. If it has a shared lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified how shared locks interact with locks acquired by + /// non-WASI programs. + /// + /// This function returns `error-code::would-block` if the lock cannot be + /// acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. + try-lock-shared: func(this: descriptor) -> result<_, error-code> + + /// Request an exclusive advisory lock for an open file. + /// + /// This requests an *exclusive* lock; no other locks may be held for the + /// file while an exclusive lock is held. + /// + /// If the open file has a shared lock and there are no exclusive locks held + /// for the file, this function upgrades the lock to an exclusive lock. If the + /// open file already has an exclusive lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified whether this function succeeds if the file descriptor + /// is not opened for writing. It is unspecified how exclusive locks interact + /// with locks acquired by non-WASI programs. + /// + /// This function returns `error-code::would-block` if the lock cannot be + /// acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. + try-lock-exclusive: func(this: descriptor) -> result<_, error-code> + + /// Release a shared or exclusive lock on an open file. + /// + /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. + unlock: func(this: descriptor) -> result<_, error-code> + + /// Dispose of the specified `descriptor`, after which it may no longer + /// be used. + drop-descriptor: func(this: descriptor) + + /// A stream of directory entries. + /// + /// This [represents a stream of `dir-entry`](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Streams). + type directory-entry-stream = u32 + + /// Read a single directory entry from a `directory-entry-stream`. + read-directory-entry: func( + this: directory-entry-stream + ) -> result, error-code> + + /// Dispose of the specified `directory-entry-stream`, after which it may no longer + /// be used. + drop-directory-entry-stream: func(this: directory-entry-stream) +} diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit new file mode 100644 index 000000000..351006598 --- /dev/null +++ b/proposals/cli/wit/deps/io/streams.wit @@ -0,0 +1,134 @@ +/// WASI I/O is an I/O abstraction API which is currently focused on providing +/// stream types. +/// +/// In the future, the component model is expected to add built-in stream types; +/// when it does, they are expected to subsume this API. +default interface streams { + use poll.poll.{pollable} + + /// An error type returned from a stream operation. Currently this + /// doesn't provide any additional information. + record stream-error {} + + /// An input bytestream. In the future, this will be replaced by handle + /// types. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type input-stream = u32 + + /// Read bytes from a stream. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a bool indicating whether the end of the stream + /// was reached. The returned list will contain up to `len` bytes; it + /// may return fewer than requested, but not more. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// If `len` is 0, it represents a request to read 0 bytes, which should + /// always succeed, assuming the stream hasn't reached its end yet, and + /// return an empty list. + /// + /// The len here is a `u64`, but some callees may not be able to allocate + /// a buffer as large as that would imply. + /// FIXME: describe what happens if allocation fails. + read: func( + this: input-stream, + /// The maximum number of bytes to read + len: u64 + ) -> result, bool>, stream-error> + + /// Skip bytes from a stream. + /// + /// This is similar to the `read` function, but avoids copying the + /// bytes into the instance. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// This function returns the number of bytes skipped, along with a bool + /// indicating whether the end of the stream was reached. The returned + /// value will be at most `len`; it may be less. + skip: func( + this: input-stream, + /// The maximum number of bytes to skip. + len: u64, + ) -> result, stream-error> + + /// Create a `pollable` which will resolve once either the specified stream + /// has bytes available to read or the other end of the stream has been + /// closed. + subscribe-to-input-stream: func(this: input-stream) -> pollable + + /// Dispose of the specified `input-stream`, after which it may no longer + /// be used. + drop-input-stream: func(this: input-stream) + + /// An output bytestream. In the future, this will be replaced by handle + /// types. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type output-stream = u32 + + /// Write bytes to a stream. + /// + /// This function returns a `u64` indicating the number of bytes from + /// `buf` that were written; it may be less than the full list. + write: func( + this: output-stream, + /// Data to write + buf: list + ) -> result + + /// Write multiple zero bytes to a stream. + /// + /// This function returns a `u64` indicating the number of zero bytes + /// that were written; it may be less than `len`. + write-zeroes: func( + this: output-stream, + /// The number of zero bytes to write + len: u64 + ) -> result + + /// Read from one stream and write to another. + /// + /// This function returns the number of bytes transferred; it may be less + /// than `len`. + splice: func( + this: output-stream, + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result, stream-error> + + /// Forward the entire contents of an input stream to an output stream. + /// + /// This function repeatedly reads from the input stream and writes + /// the data to the output stream, until the end of the input stream + /// is reached, or an error is encountered. + /// + /// This function returns the number of bytes transferred. + forward: func( + this: output-stream, + /// The stream to read from + src: input-stream + ) -> result + + /// Create a `pollable` which will resolve once either the specified stream + /// is ready to accept bytes or the other end of the stream has been closed. + subscribe-to-output-stream: func(this: output-stream) -> pollable + + /// Dispose of the specified `output-stream`, after which it may no longer + /// be used. + drop-output-stream: func(this: output-stream) +} diff --git a/proposals/cli/wit/deps/poll/poll.wit b/proposals/cli/wit/deps/poll/poll.wit new file mode 100644 index 000000000..28f08e17d --- /dev/null +++ b/proposals/cli/wit/deps/poll/poll.wit @@ -0,0 +1,39 @@ +/// A poll API intended to let users wait for I/O events on multiple handles +/// at once. +default interface poll { + /// A "pollable" handle. + /// + /// This is conceptually represents a `stream<_, _>`, or in other words, + /// a stream that one can wait on, repeatedly, but which does not itself + /// produce any data. It's temporary scaffolding until component-model's + /// async features are ready. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// `pollable` lifetimes are not automatically managed. Users must ensure + /// that they do not outlive the resource they reference. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type pollable = u32 + + /// Dispose of the specified `pollable`, after which it may no longer + /// be used. + drop-pollable: func(this: pollable) + + /// Poll for completion on a set of pollables. + /// + /// The "oneoff" in the name refers to the fact that this function must do a + /// linear scan through the entire list of subscriptions, which may be + /// inefficient if the number is large and the same subscriptions are used + /// many times. In the future, this is expected to be obsoleted by the + /// component model async proposal, which will include a scalable waiting + /// facility. + /// + /// Note that the return type would ideally be `list`, but that would + /// be more difficult to polyfill given the current state of `wit-bindgen`. + /// See + /// for details. For now, we use zero to mean "not ready" and non-zero to + /// mean "ready". + poll-oneoff: func(in: list) -> list +} diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit new file mode 100644 index 000000000..2080ddfde --- /dev/null +++ b/proposals/cli/wit/deps/random/random.wit @@ -0,0 +1,42 @@ +/// WASI Random is a random data API. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface random { + /// Return `len` cryptographically-secure pseudo-random bytes. + /// + /// This function must produce data from an adequately seeded + /// cryptographically-secure pseudo-random number generator (CSPRNG), so it + /// must not block, from the perspective of the calling program, and the + /// returned data is always unpredictable. + /// + /// This function must always return fresh pseudo-random data. Deterministic + /// environments must omit this function, rather than implementing it with + /// deterministic data. + get-random-bytes: func(len: u64) -> list + + /// Return a cryptographically-secure pseudo-random `u64` value. + /// + /// This function returns the same type of pseudo-random data as + /// `get-random-bytes`, represented as a `u64`. + get-random-u64: func() -> u64 + + /// Return a 128-bit value that may contain a pseudo-random value. + /// + /// The returned value is not required to be computed from a CSPRNG, and may + /// even be entirely deterministic. Host implementations are encouraged to + /// provide pseudo-random values to any program exposed to + /// attacker-controlled content, to enable DoS protection built into many + /// languages' hash-map implementations. + /// + /// This function is intended to only be called once, by a source language + /// to initialize Denial Of Service (DoS) protection in its hash-map + /// implementation. + /// + /// # Expected future evolution + /// + /// This will likely be changed to a value import, to prevent it from being + /// called multiple times and potentially used for purposes other than DoS + /// protection. + insecure-random: func() -> tuple +} diff --git a/proposals/cli/wit/deps/wit b/proposals/cli/wit/deps/wit new file mode 100644 index 000000000..351006598 --- /dev/null +++ b/proposals/cli/wit/deps/wit @@ -0,0 +1,134 @@ +/// WASI I/O is an I/O abstraction API which is currently focused on providing +/// stream types. +/// +/// In the future, the component model is expected to add built-in stream types; +/// when it does, they are expected to subsume this API. +default interface streams { + use poll.poll.{pollable} + + /// An error type returned from a stream operation. Currently this + /// doesn't provide any additional information. + record stream-error {} + + /// An input bytestream. In the future, this will be replaced by handle + /// types. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type input-stream = u32 + + /// Read bytes from a stream. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a bool indicating whether the end of the stream + /// was reached. The returned list will contain up to `len` bytes; it + /// may return fewer than requested, but not more. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// If `len` is 0, it represents a request to read 0 bytes, which should + /// always succeed, assuming the stream hasn't reached its end yet, and + /// return an empty list. + /// + /// The len here is a `u64`, but some callees may not be able to allocate + /// a buffer as large as that would imply. + /// FIXME: describe what happens if allocation fails. + read: func( + this: input-stream, + /// The maximum number of bytes to read + len: u64 + ) -> result, bool>, stream-error> + + /// Skip bytes from a stream. + /// + /// This is similar to the `read` function, but avoids copying the + /// bytes into the instance. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// This function returns the number of bytes skipped, along with a bool + /// indicating whether the end of the stream was reached. The returned + /// value will be at most `len`; it may be less. + skip: func( + this: input-stream, + /// The maximum number of bytes to skip. + len: u64, + ) -> result, stream-error> + + /// Create a `pollable` which will resolve once either the specified stream + /// has bytes available to read or the other end of the stream has been + /// closed. + subscribe-to-input-stream: func(this: input-stream) -> pollable + + /// Dispose of the specified `input-stream`, after which it may no longer + /// be used. + drop-input-stream: func(this: input-stream) + + /// An output bytestream. In the future, this will be replaced by handle + /// types. + /// + /// And at present, it is a `u32` instead of being an actual handle, until + /// the wit-bindgen implementation of handles and resources is ready. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type output-stream = u32 + + /// Write bytes to a stream. + /// + /// This function returns a `u64` indicating the number of bytes from + /// `buf` that were written; it may be less than the full list. + write: func( + this: output-stream, + /// Data to write + buf: list + ) -> result + + /// Write multiple zero bytes to a stream. + /// + /// This function returns a `u64` indicating the number of zero bytes + /// that were written; it may be less than `len`. + write-zeroes: func( + this: output-stream, + /// The number of zero bytes to write + len: u64 + ) -> result + + /// Read from one stream and write to another. + /// + /// This function returns the number of bytes transferred; it may be less + /// than `len`. + splice: func( + this: output-stream, + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result, stream-error> + + /// Forward the entire contents of an input stream to an output stream. + /// + /// This function repeatedly reads from the input stream and writes + /// the data to the output stream, until the end of the input stream + /// is reached, or an error is encountered. + /// + /// This function returns the number of bytes transferred. + forward: func( + this: output-stream, + /// The stream to read from + src: input-stream + ) -> result + + /// Create a `pollable` which will resolve once either the specified stream + /// is ready to accept bytes or the other end of the stream has been closed. + subscribe-to-output-stream: func(this: output-stream) -> pollable + + /// Dispose of the specified `output-stream`, after which it may no longer + /// be used. + drop-output-stream: func(this: output-stream) +} diff --git a/proposals/cli/wit/exit.wit b/proposals/cli/wit/exit.wit new file mode 100644 index 000000000..2759e9dd9 --- /dev/null +++ b/proposals/cli/wit/exit.wit @@ -0,0 +1,4 @@ +default interface wasi-exit { + /// Exit the curerent instance and any linked instances. + exit: func(status: result) +} From 4eb48293baa3196a4fbf756b81bb05f09d282a89 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Feb 2023 15:09:19 -0800 Subject: [PATCH 1065/1772] Delete a stale file. --- proposals/cli/wit/world.wit | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 proposals/cli/wit/world.wit diff --git a/proposals/cli/wit/world.wit b/proposals/cli/wit/world.wit deleted file mode 100644 index 17821ee6e..000000000 --- a/proposals/cli/wit/world.wit +++ /dev/null @@ -1,10 +0,0 @@ -// If the repository defines `interface`s, this file can define a minimal world -// which contains those interfaces, to allow documentation to be generated for -// them. -// -// Proposals should remove these `//` commments, and edit the `world` name and -// imports below to pull in their own `interface`s. - -default world example-world { - import example-interface: pkg.example.example-interface -} From 3134bd92661822325c1ed0e6f4b2f84b057d3e25 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Feb 2023 15:22:14 -0800 Subject: [PATCH 1066/1772] Remove another stale file. --- proposals/cli/wit/deps/example-dep/example-api.wit | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 proposals/cli/wit/deps/example-dep/example-api.wit diff --git a/proposals/cli/wit/deps/example-dep/example-api.wit b/proposals/cli/wit/deps/example-dep/example-api.wit deleted file mode 100644 index 60da3235d..000000000 --- a/proposals/cli/wit/deps/example-dep/example-api.wit +++ /dev/null @@ -1,6 +0,0 @@ -// An example dependency, showing how these look. Actual proposals should -// delete this file and add their actual dependencies in the `deps` directory. - -interface example-dep-interface { - type example-dep-type = u32 -} From 8292ca370a26b25a2ad6c4e3a10f5ae85f12e1e8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Feb 2023 15:24:12 -0800 Subject: [PATCH 1067/1772] And another. --- proposals/cli/wit/example.wit | 59 ----------------------------------- 1 file changed, 59 deletions(-) delete mode 100644 proposals/cli/wit/example.wit diff --git a/proposals/cli/wit/example.wit b/proposals/cli/wit/example.wit deleted file mode 100644 index 04b038198..000000000 --- a/proposals/cli/wit/example.wit +++ /dev/null @@ -1,59 +0,0 @@ -// Instructions for filling in this file: -// -// - Delete all these `//` comments, up to the first `///` comment. -// -// - Replace the remaining contents below with [Wit] code describing -// `interface`s and/or `world`s, using the same formatting style. -// -// If you want to include examples of the API in use, these should be in the -// README.md at the root of the repository and linked to from this file. -// -// [Wit]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md - -/// Short interface description. -/// -/// Explanation for developers using the interface API. It should include an -/// overview of the API as a whole as well as call out notable items in it, -/// for example `example-api-type` and `example-api-function`. -default interface example-interface { - use example-dep.example-api.example-dep-interface.{example-dep-type} - - /// Short type description - /// - /// Explanation for developers using this type. It may be useful to give - /// some examples of places in the API where the type is used, such as in - /// the arguments and return type of `example-api-function`. - /// - ///
      - /// Detailed specification - /// More rigorous specification details for implementers go here, if needed. - /// The intention is to keep the developer-oriented docs focused on things that - /// most developers will need to be aware of, while putting bulkier descriptions - /// of precise behavior here. - ///
      - record example-api-type { - /// A description of a field. - field0: u64, - /// A description of another field. - field1: string, - } - - /// Short function description - /// - /// Explanation for developers using the API. This should describe the - /// arguments which in this function are `arg0`, `arg1`, and `arg2`, and the - /// return value. - /// - ///
      - /// Detailed specification - /// Similar to the details section above, this is meant for more rigorous - /// specification details for implementors. This may explain what a compliant - /// implementation MUST do, such as never returning an earlier result from a - /// later call, for example. - ///
      - example-api-function: func( - arg0: example-api-type, - arg1: string, - arg2: example-dep-type, - ) -> result -} From 1c2f56881840a699d526d01aadfab9ce62d8c7d9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Feb 2023 15:38:35 -0800 Subject: [PATCH 1068/1772] And another. --- proposals/cli/example-world.md | 72 ---------------------------------- 1 file changed, 72 deletions(-) delete mode 100644 proposals/cli/example-world.md diff --git a/proposals/cli/example-world.md b/proposals/cli/example-world.md deleted file mode 100644 index c58d36466..000000000 --- a/proposals/cli/example-world.md +++ /dev/null @@ -1,72 +0,0 @@ -

      World example-world

      - -

      Import interface example-dep-interface

      -
      -

      Types

      -

      type example-dep-type

      -

      u32

      -

      -## Import interface example-interface -

      Short interface description.

      -

      Explanation for developers using the interface API. It should include an -overview of the API as a whole as well as call out notable items in it, -for example example-api-type and example-api-function.

      -
      -

      Types

      -

      type example-dep-type

      -

      example-dep-type

      -

      -#### `record example-api-type` -

      Short type description

      -

      Explanation for developers using this type. It may be useful to give -some examples of places in the API where the type is used, such as in -the arguments and return type of example-api-function.

      -
      -Detailed specification -More rigorous specification details for implementers go here, if needed. -The intention is to keep the developer-oriented docs focused on things that -most developers will need to be aware of, while putting bulkier descriptions -of precise behavior here. -
      -
      Record Fields
      -
        -
      • -

        field0: u64

        -

        A description of a field. -

      • -
      • -

        field1: string

        -

        A description of another field. -

      • -
      -
      -

      Functions

      -

      example-api-function: func

      -

      Short function description

      -

      Explanation for developers using the API. This should describe the -arguments which in this function are arg0, arg1, and arg2, and the -return value.

      -
      -Detailed specification -Similar to the details section above, this is meant for more rigorous -specification details for implementors. This may explain what a compliant -implementation MUST do, such as never returning an earlier result from a -later call, for example. -
      -
      Params
      - -
      Return values
      - From 94939aaa2f709a2e4ac836d2c7c02d4fd8cbd6b1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Feb 2023 15:56:35 -0800 Subject: [PATCH 1069/1772] Rename the `io` module to `streams`. --- proposals/cli/cli.md | 6 +++--- proposals/cli/wit/cli.wit | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/cli/cli.md b/proposals/cli/cli.md index 10b800358..985b5b18c 100644 --- a/proposals/cli/cli.md +++ b/proposals/cli/cli.md @@ -8,7 +8,7 @@
    • interface instance-wall-clock
    • interface instance-monotonic-clock
    • interface timezone
    • -
    • interface io
    • +
    • interface streams
    • interface filesystem
    • interface random
    • interface exit
    • @@ -315,7 +315,7 @@ be used.

      -

      Import interface io

      +

      Import interface streams

      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

      In the future, the component model is expected to add built-in stream types; @@ -626,7 +626,7 @@ merely for alignment with POSIX.

      Invalid argument, similar to `EINVAL` in POSIX.

    • -

      io

      +

      io

      I/O error, similar to `EIO` in POSIX.

    • diff --git a/proposals/cli/wit/cli.wit b/proposals/cli/wit/cli.wit index 3946023c6..fc79e803a 100644 --- a/proposals/cli/wit/cli.wit +++ b/proposals/cli/wit/cli.wit @@ -7,7 +7,7 @@ default world cli { import filesystem: filesystem.filesystem import random: random.random import poll: poll.poll - import io: io.streams + import streams: io.streams import exit: pkg.exit use io.streams.{input-stream, output-stream} From 8dc0a6f7f994f34c4b5692a2bcf989c2e86c50d4 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Feb 2023 17:30:14 -0800 Subject: [PATCH 1070/1772] Update the interface name of wasi-filesystem. (#108) With the new wasi-proposal-repo format, interface names no longer include the `wasi-`. --- proposals/filesystem/wit/filesystem.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/wit/filesystem.wit b/proposals/filesystem/wit/filesystem.wit index 08c7bff4d..fafd4b96f 100644 --- a/proposals/filesystem/wit/filesystem.wit +++ b/proposals/filesystem/wit/filesystem.wit @@ -17,7 +17,7 @@ /// `..` and symbolic link steps, reaches a directory outside of the base /// directory, or reaches a symlink to an absolute or rooted path in the /// underlying filesystem, the function fails with `error-code::not-permitted`. -default interface wasi-filesystem { +default interface filesystem { use io.streams.{input-stream, output-stream} use clocks.wall-clock.{datetime} From daff8835f8c147396f0211562c69a76bcc45b2aa Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sat, 25 Feb 2023 10:54:22 +0100 Subject: [PATCH 1071/1772] Document TCP & UDP error codes. --- proposals/sockets/wasi-network.wit | 49 ++++++++- proposals/sockets/wasi-tcp-create-socket.wit | 5 +- proposals/sockets/wasi-tcp.wit | 105 +++++++++++++++---- proposals/sockets/wasi-udp-create-socket.wit | 5 +- proposals/sockets/wasi-udp.wit | 79 +++++++++++--- 5 files changed, 200 insertions(+), 43 deletions(-) diff --git a/proposals/sockets/wasi-network.wit b/proposals/sockets/wasi-network.wit index e738a8286..180a54b21 100644 --- a/proposals/sockets/wasi-network.wit +++ b/proposals/sockets/wasi-network.wit @@ -13,11 +13,54 @@ default interface wasi-network { drop-network: func(this: network) - + /// Error codes. + /// + /// In theory, every API can return any error code. + /// In practice, API's typically only return the errors documented per API + /// combined with a couple of errors that are always possible: + /// - `unknown` + /// - `access-denied` + /// - `not-supported` + /// - `resource-limit-reached` + /// - `out-of-memory` + /// + /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. enum error { + /// Unknown error unknown, - again, - // TODO ... + + /// POSIX equivalent: EACCES, EPERM + access-denied, + + /// POSIX equivalent: EOPNOTSUPP + not-supported, + + /// POSIX equivalent: EMFILE, ENFILE, ENOMEM, ENOBUFS, EAI_MEMORY + resource-limit-reached, + + /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY + out-of-memory, + + concurrency-conflict, + already-attached, + already-bound, + already-connected, + already-listening, + not-bound, + not-connected, + not-listening, + address-family-mismatch, + invalid-remote-address, + datagram-too-large, + address-not-bindable, + address-in-use, + ephemeral-ports-exhausted, + connection-refused, + connection-reset, + remote-unreachable, + timeout, + ipv4-only-operation, + ipv6-only-operation, } enum ip-address-family { diff --git a/proposals/sockets/wasi-tcp-create-socket.wit b/proposals/sockets/wasi-tcp-create-socket.wit index 06074fb70..4fa133f14 100644 --- a/proposals/sockets/wasi-tcp-create-socket.wit +++ b/proposals/sockets/wasi-tcp-create-socket.wit @@ -11,9 +11,12 @@ default interface wasi-tcp-create-socket { /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// + /// Typical errors: + /// - `not-supported`: The host does not support TCP sockets. + /// - `not-supported`: The specified `address-family` is not supported. + /// /// References: /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html /// - https://man7.org/linux/man-pages/man2/socket.2.html - /// create-tcp-socket: func(address-family: ip-address-family) -> result } diff --git a/proposals/sockets/wasi-tcp.wit b/proposals/sockets/wasi-tcp.wit index 62e99fc3b..ba5966127 100644 --- a/proposals/sockets/wasi-tcp.wit +++ b/proposals/sockets/wasi-tcp.wit @@ -29,12 +29,19 @@ default interface wasi-tcp { /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will /// implicitly bind the socket. /// - /// Fails when: - /// - the socket is already bound. + /// Typical errors: + /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) + /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html /// - https://man7.org/linux/man-pages/man2/bind.2.html + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-bind + /// - https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2&format=html bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error> /// Connect to a remote endpoint. @@ -43,29 +50,43 @@ default interface wasi-tcp { /// - the socket is transitioned into the Connection state /// - a pair of streams is returned that can be used to read & write to the connection /// - /// Fails when: - /// - the socket is already bound to a different network. - /// - the provided network does not allow connections to the specified endpoint. - /// - the socket is already in the Connection or Listener state. - /// - either the remote IP address or port is 0. + /// Typical errors: + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `already-connected`: The socket is already in the Connection state. (EISCONN) + /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html /// - https://man7.org/linux/man-pages/man2/connect.2.html + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect + /// - https://man.freebsd.org/cgi/man.cgi?connect connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result, error> /// Start listening for new connections. /// /// Transitions the socket into the Listener state. /// - /// Fails when: - /// - the socket is already bound to a different network. - /// - the provided network does not allow listening on the specified address. - /// - the socket is already in the Connection or Listener state. + /// Typical errors: + /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `listen` must be identical to the one passed to `bind`. + /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) + /// - `already-listening`: The socket is already in the Listener state. + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html /// - https://man7.org/linux/man-pages/man2/listen.2.html + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-listen + /// - https://man.freebsd.org/cgi/man.cgi?query=listen&sektion=2 listen: func(this: tcp-socket, network: network) -> result<_, error> /// Accept a new client socket. @@ -75,29 +96,40 @@ default interface wasi-tcp { /// On success, this function returns the newly accepted client socket along with /// a pair of streams that can be used to read & write to the connection. /// - /// Fails when this socket is not in the Listening state. + /// Typical errors: + /// - `not-listening`: Socket is not in the Listener state. (EINVAL) + /// + /// Host implementations must skip over transient errors returned by the native accept syscall. /// /// References: /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html /// - https://man7.org/linux/man-pages/man2/accept.2.html + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept + /// - https://man.freebsd.org/cgi/man.cgi?query=accept&sektion=2 accept: func(this: tcp-socket) -> result, error> /// Get the bound local address. /// - /// Returns an error if the socket is not bound. + /// Typical errors: + /// - `not-bound`: The socket is not bound to any local address. /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html /// - https://man7.org/linux/man-pages/man2/getsockname.2.html + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getsockname + /// - https://man.freebsd.org/cgi/man.cgi?getsockname local-address: func(this: tcp-socket) -> result /// Get the bound remote address. /// - /// Fails when the socket is not in the Connection state. + /// Typical errors: + /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html /// - https://man7.org/linux/man-pages/man2/getpeername.2.html + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getpeername + /// - https://man.freebsd.org/cgi/man.cgi?query=getpeername&sektion=2&n=1 remote-address: func(this: tcp-socket) -> result /// Whether this is a IPv4 or IPv6 socket. @@ -106,26 +138,44 @@ default interface wasi-tcp { address-family: func(this: tcp-socket) -> result /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// Implementations are not required to support dual-stack mode. Calling `set-ipv6-only(false)` might fail. - /// - /// Fails when called on an IPv4 socket. /// /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// Typical errors: + /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. + /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) ipv6-only: func(this: tcp-socket) -> result set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error> /// Hints the desired listen queue size. Implementations are free to ignore this. + /// + /// Typical errors: + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error> /// Equivalent to the SO_KEEPALIVE socket option. + /// + /// Typical errors: + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) keep-alive: func(this: tcp-socket) -> result set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error> /// Equivalent to the TCP_NODELAY socket option. + /// + /// Typical errors: + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) no-delay: func(this: tcp-socket) -> result set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error> /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// Typical errors: + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `already-listening`: (set) The socket is already in the Listener state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) unicast-hop-limit: func(this: tcp-socket) -> result set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error> @@ -138,9 +188,12 @@ default interface wasi-tcp { /// actual data to be sent/received by the application, because the kernel might also use the buffer space /// for internal metadata structures. /// - /// Fails when this socket is in the Listening state. - /// /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// Typical errors: + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `already-listening`: (set) The socket is already in the Listener state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) receive-buffer-size: func(this: tcp-socket) -> result set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error> send-buffer-size: func(this: tcp-socket) -> result @@ -149,11 +202,14 @@ default interface wasi-tcp { /// Get/set the blocking mode of the socket. /// /// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. - /// When switched to "non-blocking" mode, operations that would block return an `again` error. After which + /// When switched to "non-blocking" mode, operations that would block return an `would-block` error. After which /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. /// /// Note: these functions are here for WASI Preview2 only. /// They're planned to be removed when `future` is natively supported in Preview3. + /// + /// Typical errors: + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) non-blocking: func(this: tcp-socket) -> result set-non-blocking: func(this: tcp-socket, value: bool) -> result<_, error> @@ -172,17 +228,22 @@ default interface wasi-tcp { /// operations on the `output-stream` associated with this socket will return an error. /// - both: same effect as receive & send combined. /// - /// The shutdown function does not close the socket. + /// The shutdown function does not close (drop) the socket. /// - /// Fails when the socket is not in the Connection state. + /// Typical errors: + /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html /// - https://man7.org/linux/man-pages/man2/shutdown.2.html + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-shutdown + /// - https://man.freebsd.org/cgi/man.cgi?query=shutdown&sektion=2 shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error> /// Dispose of the specified `tcp-socket`, after which it may no longer be used. /// + /// Similar to the POSIX `close` function. + /// /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. drop-tcp-socket: func(this: tcp-socket) } diff --git a/proposals/sockets/wasi-udp-create-socket.wit b/proposals/sockets/wasi-udp-create-socket.wit index 1a5a17d2e..c38543909 100644 --- a/proposals/sockets/wasi-udp-create-socket.wit +++ b/proposals/sockets/wasi-udp-create-socket.wit @@ -11,9 +11,12 @@ default interface wasi-udp-create-socket { /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` is called, /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// + /// Typical errors: + /// - `not-supported`: The host does not support UDP sockets. + /// - `not-supported`: The specified `address-family` is not supported. + /// /// References: /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html /// - https://man7.org/linux/man-pages/man2/socket.2.html - /// create-udp-socket: func(address-family: ip-address-family) -> result } diff --git a/proposals/sockets/wasi-udp.wit b/proposals/sockets/wasi-udp.wit index 570f059d9..dfd552c83 100644 --- a/proposals/sockets/wasi-udp.wit +++ b/proposals/sockets/wasi-udp.wit @@ -28,15 +28,21 @@ default interface wasi-udp { /// network interface(s) to bind to. /// If the TCP/UDP port is zero, the socket will be bound to a random free port. /// - /// When a socket is not explicitly bound, the first invocation to a connect, send or receive operation will - /// implicitly bind the socket. + /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. /// - /// Fails when: - /// - the socket is already bound. + /// Typical errors: + /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) + /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html /// - https://man7.org/linux/man-pages/man2/bind.2.html + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-bind + /// - https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2&format=html bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error> /// Set the destination address. @@ -49,12 +55,19 @@ default interface wasi-udp { /// /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". /// - /// Fails when: - /// - the socket is already bound to a different network. + /// Typical errors: + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html /// - https://man7.org/linux/man-pages/man2/connect.2.html + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect + /// - https://man.freebsd.org/cgi/man.cgi?connect connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error> /// Receive a message. @@ -63,13 +76,18 @@ default interface wasi-udp { /// - The sender address of the datagram /// - The number of bytes read. /// - /// Fails when: - /// - the socket is not bound. + /// Typical errors: + /// - `not-bound`: The socket is not bound to any local address. (EINVAL) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html /// - https://man7.org/linux/man-pages/man2/recv.2.html + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recv + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recvfrom + /// - https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms741687(v=vs.85) + /// - https://man.freebsd.org/cgi/man.cgi?query=recv&sektion=2 receive: func(this: udp-socket) -> result /// Send a message to a specific destination address. @@ -77,30 +95,47 @@ default interface wasi-udp { /// The remote address option is required. To send a message to the "connected" peer, /// call `remote-address` to get their address. /// - /// Fails when: - /// - the socket is not bound. Unlike POSIX, this function does not perform an implicit bind. - /// - the socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. + /// Typical errors: + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN) + /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. + /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html /// - https://man7.org/linux/man-pages/man2/send.2.html + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-send + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasendmsg + /// - https://man.freebsd.org/cgi/man.cgi?query=send&sektion=2 send: func(this: udp-socket, datagram: datagram) -> result<_, error> /// Get the current bound address. /// - /// Returns an error if the socket is not bound. + /// Typical errors: + /// - `not-bound`: The socket is not bound to any local address. /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html /// - https://man7.org/linux/man-pages/man2/getsockname.2.html + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getsockname + /// - https://man.freebsd.org/cgi/man.cgi?getsockname local-address: func(this: udp-socket) -> result /// Get the address set with `connect`. /// + /// Typical errors: + /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) + /// /// References /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html /// - https://man7.org/linux/man-pages/man2/getpeername.2.html + /// - https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getpeername + /// - https://man.freebsd.org/cgi/man.cgi?query=getpeername&sektion=2&n=1 remote-address: func(this: udp-socket) -> result /// Whether this is a IPv4 or IPv6 socket. @@ -109,15 +144,21 @@ default interface wasi-udp { address-family: func(this: udp-socket) -> result /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// Implementations are not required to support dual-stack mode, so calling `set-ipv6-only(false)` might fail. - /// - /// Fails when called on an IPv4 socket. /// /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// Typical errors: + /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. + /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) ipv6-only: func(this: udp-socket) -> result set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error> /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// Typical errors: + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) unicast-hop-limit: func(this: udp-socket) -> result set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error> @@ -133,6 +174,9 @@ default interface wasi-udp { /// Fails when this socket is in the Listening state. /// /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// Typical errors: + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) receive-buffer-size: func(this: udp-socket) -> result set-receive-buffer-size: func(this: udp-socket, value: u64) -> result<_, error> send-buffer-size: func(this: udp-socket) -> result @@ -141,11 +185,14 @@ default interface wasi-udp { /// Get/set the blocking mode of the socket. /// /// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. - /// When switched to "non-blocking" mode, operations that would block return an `again` error. After which + /// When switched to "non-blocking" mode, operations that would block return an `would-block` error. After which /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. /// /// Note: these functions are here for WASI Preview2 only. /// They're planned to be removed when `future` is natively supported in Preview3. + /// + /// Typical errors: + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) non-blocking: func(this: udp-socket) -> result set-non-blocking: func(this: udp-socket, value: bool) -> result<_, error> From 96741f17b37465536804f8b30b41ff13cd8dec2b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 25 Feb 2023 06:31:14 -0800 Subject: [PATCH 1072/1772] Enclose URLs in angle brackets To ensure that markdown renderers properly handle bare URLs, enclose them them in [angle brackets]. [angle brackets]: https://www.markdownguide.org/basic-syntax/#urls-and-email-addresses --- proposals/sockets/wit/ip-name-lookup.wit | 4 +-- proposals/sockets/wit/tcp-create-socket.wit | 4 +-- proposals/sockets/wit/tcp.wit | 28 ++++++++++----------- proposals/sockets/wit/udp-create-socket.wit | 4 +-- proposals/sockets/wit/udp.wit | 28 ++++++++++----------- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index dd85d586c..b594598e0 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -26,8 +26,8 @@ default interface ip-name-lookup { /// - a syntactically invalid domain name in another way /// /// References: - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html - /// - https://man7.org/linux/man-pages/man3/getaddrinfo.3.html + /// - + /// - /// resolve-addresses: func(network: network, name: string, address-family: option, include-unavailable: bool) -> result diff --git a/proposals/sockets/wit/tcp-create-socket.wit b/proposals/sockets/wit/tcp-create-socket.wit index 11c41455b..571a0197a 100644 --- a/proposals/sockets/wit/tcp-create-socket.wit +++ b/proposals/sockets/wit/tcp-create-socket.wit @@ -12,8 +12,8 @@ default interface tcp-create-socket { /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// /// References: - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html - /// - https://man7.org/linux/man-pages/man2/socket.2.html + /// - + /// - /// create-tcp-socket: func(address-family: ip-address-family) -> result } diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index a21c480ca..b2f483368 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -33,8 +33,8 @@ default interface tcp { /// - the socket is already bound. /// /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html - /// - https://man7.org/linux/man-pages/man2/bind.2.html + /// - + /// - bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error> /// Connect to a remote endpoint. @@ -50,8 +50,8 @@ default interface tcp { /// - either the remote IP address or port is 0. /// /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html - /// - https://man7.org/linux/man-pages/man2/connect.2.html + /// - + /// - connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result, error> /// Start listening for new connections. @@ -64,8 +64,8 @@ default interface tcp { /// - the socket is already in the Connection or Listener state. /// /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html - /// - https://man7.org/linux/man-pages/man2/listen.2.html + /// - + /// - listen: func(this: tcp-socket, network: network) -> result<_, error> /// Accept a new client socket. @@ -78,8 +78,8 @@ default interface tcp { /// Fails when this socket is not in the Listening state. /// /// References: - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html - /// - https://man7.org/linux/man-pages/man2/accept.2.html + /// - + /// - accept: func(this: tcp-socket) -> result, error> /// Get the bound local address. @@ -87,8 +87,8 @@ default interface tcp { /// Returns an error if the socket is not bound. /// /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html - /// - https://man7.org/linux/man-pages/man2/getsockname.2.html + /// - + /// - local-address: func(this: tcp-socket) -> result /// Get the bound remote address. @@ -96,8 +96,8 @@ default interface tcp { /// Fails when the socket is not in the Connection state. /// /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html - /// - https://man7.org/linux/man-pages/man2/getpeername.2.html + /// - + /// - remote-address: func(this: tcp-socket) -> result /// Whether this is a IPv4 or IPv6 socket. @@ -177,8 +177,8 @@ default interface tcp { /// Fails when the socket is not in the Connection state. /// /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html - /// - https://man7.org/linux/man-pages/man2/shutdown.2.html + /// - + /// - shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error> /// Dispose of the specified `tcp-socket`, after which it may no longer be used. diff --git a/proposals/sockets/wit/udp-create-socket.wit b/proposals/sockets/wit/udp-create-socket.wit index 46d5012d1..169957c9f 100644 --- a/proposals/sockets/wit/udp-create-socket.wit +++ b/proposals/sockets/wit/udp-create-socket.wit @@ -12,8 +12,8 @@ default interface udp-create-socket { /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// /// References: - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html - /// - https://man7.org/linux/man-pages/man2/socket.2.html + /// - + /// - /// create-udp-socket: func(address-family: ip-address-family) -> result } diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index c867827d1..af8f873b9 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -35,8 +35,8 @@ default interface udp { /// - the socket is already bound. /// /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html - /// - https://man7.org/linux/man-pages/man2/bind.2.html + /// - + /// - bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error> /// Set the destination address. @@ -53,8 +53,8 @@ default interface udp { /// - the socket is already bound to a different network. /// /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html - /// - https://man7.org/linux/man-pages/man2/connect.2.html + /// - + /// - connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error> /// Receive a message. @@ -67,9 +67,9 @@ default interface udp { /// - the socket is not bound. /// /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html - /// - https://man7.org/linux/man-pages/man2/recv.2.html + /// - + /// - + /// - receive: func(this: udp-socket) -> result /// Send a message to a specific destination address. @@ -82,9 +82,9 @@ default interface udp { /// - the socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. /// /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html - /// - https://man7.org/linux/man-pages/man2/send.2.html + /// - + /// - + /// - send: func(this: udp-socket, datagram: datagram) -> result<_, error> /// Get the current bound address. @@ -92,15 +92,15 @@ default interface udp { /// Returns an error if the socket is not bound. /// /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html - /// - https://man7.org/linux/man-pages/man2/getsockname.2.html + /// - + /// - local-address: func(this: udp-socket) -> result /// Get the address set with `connect`. /// /// References - /// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html - /// - https://man7.org/linux/man-pages/man2/getpeername.2.html + /// - + /// - remote-address: func(this: udp-socket) -> result /// Whether this is a IPv4 or IPv6 socket. From ca11a98cb6812f469b8fe3eb1522f90cb0a816fc Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 25 Feb 2023 06:35:24 -0800 Subject: [PATCH 1073/1772] Update generated files. --- proposals/sockets/example-world.md | 68 +++++++++++++++--------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index 3fb3a85c5..882f9ea07 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -200,8 +200,8 @@ implicitly bind the socket.

    References

    Params
      @@ -228,8 +228,8 @@ implicitly bind the socket.

    References

    Params
      @@ -254,9 +254,9 @@ implicitly bind the socket.

    References

    Params

    References

    Params
      @@ -295,8 +295,8 @@ call remote-address to get their addr

      Returns an error if the socket is not bound.

      References

      Params
        @@ -310,8 +310,8 @@ call remote-address to get their addr

        Get the address set with connect.

        References

        Params
          @@ -490,8 +490,8 @@ at time of creation, the socket is not bound to any net the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

          References:

          Params
            @@ -745,8 +745,8 @@ implicitly bind the socket.

          References

          Params
            @@ -774,8 +774,8 @@ implicitly bind the socket.

          References

          Params
            @@ -798,8 +798,8 @@ implicitly bind the socket.

          References

          Params
            @@ -818,8 +818,8 @@ a pair of streams that can be used to read & write to the connection.

            Fails when this socket is not in the Listening state.

            References:

            Params
              @@ -834,8 +834,8 @@ a pair of streams that can be used to read & write to the connection.

              Returns an error if the socket is not bound.

              References

              Params
                @@ -850,8 +850,8 @@ a pair of streams that can be used to read & write to the connection.

                Fails when the socket is not in the Connection state.

                References

                Params
                  @@ -1063,8 +1063,8 @@ operations on the output-stream associ

                  Fails when the socket is not in the Connection state.

                  References

                  Params
                    @@ -1107,8 +1107,8 @@ at time of creation, the socket is not bound to any net is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                    References:

                    Params
                      @@ -1165,8 +1165,8 @@ Or it immediately fails whenever name is:

                    References:

                    Params
                      From af6f0ec16fde15d9b8c16f38c6d443d676d66a8d Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 26 Feb 2023 09:34:38 +0100 Subject: [PATCH 1074/1772] Formatting --- proposals/sockets/example-world.md | 84 ++++++++++----------- proposals/sockets/wit/ip-name-lookup.wit | 2 +- proposals/sockets/wit/tcp-create-socket.wit | 4 +- proposals/sockets/wit/tcp.wit | 42 +++++------ proposals/sockets/wit/udp-create-socket.wit | 4 +- proposals/sockets/wit/udp.wit | 32 ++++---- 6 files changed, 84 insertions(+), 84 deletions(-) diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index 37a547e9d..3f5b87fc0 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -283,7 +283,7 @@ mean "ready".

                      network interface(s) to bind to. If the TCP/UDP port is zero, the socket will be bound to a random free port.

                      When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket.

                      -

                      Typical errors:

                      +

                      Typical errors

                      • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
                      • already-bound: The socket is already bound. (EINVAL)
                      • @@ -292,7 +292,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                      • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
                      • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
                      -

                      References

                      +

                      References

                      Note that this function does not generate any network traffic and the peer is not aware of this "connection".

                      -

                      Typical errors:

                      +

                      Typical errors

                      • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
                      • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
                      • @@ -327,7 +327,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                      • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
                      • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
                      -

                      References

                      +

                      References

                      -

                      Typical errors:

                      +

                      Typical errors

                      • not-bound: The socket is not bound to any local address. (EINVAL)
                      • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
                      -

                      References

                      +

                      References

                      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html
                      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html
                      • @@ -378,7 +378,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                        Send a message to a specific destination address.

                        The remote address option is required. To send a message to the "connected" peer, call remote-address to get their address.

                        -

                        Typical errors:

                        +

                        Typical errors

                        • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
                        • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
                        • @@ -388,7 +388,7 @@ call remote-address to get their addr
                        • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
                        • datagram-too-large: The datagram is too large. (EMSGSIZE)
                        -

                        References

                        +

                        References

                        local-address: func

                        Get the current bound address.

                        -

                        Typical errors:

                        +

                        Typical errors

                        • not-bound: The socket is not bound to any local address.
                        -

                        References

                        +

                        References

                        remote-address: func

                        Get the address set with connect.

                        -

                        Typical errors:

                        +

                        Typical errors

                        • not-connected: The socket is not connected to a remote address. (ENOTCONN)
                        -

                        References

                        +

                        References

                        • https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html
                        • https://man7.org/linux/man-pages/man2/getpeername.2.html
                        • @@ -463,7 +463,7 @@ call remote-address to get their addr

                          ipv6-only: func

                          Whether IPv4 compatibility (dual-stack) mode is disabled or not.

                          Equivalent to the IPV6_V6ONLY socket option.

                          -

                          Typical errors:

                          +

                          Typical errors

                          • ipv6-only-operation: (get/set) this socket is an IPv4 socket.
                          • already-bound: (set) The socket is already bound.
                          • @@ -490,7 +490,7 @@ call remote-address to get their addr

                          unicast-hop-limit: func

                          Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                          -

                          Typical errors:

                          +

                          Typical errors

                          • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
                          @@ -521,7 +521,7 @@ actual data to be sent/received by the application, because the kernel might als for internal metadata structures.

                          Fails when this socket is in the Listening state.

                          Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

                          -

                          Typical errors:

                          +

                          Typical errors

                          • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
                          @@ -569,7 +569,7 @@ When switched to "non-blocking" mode, operations that would block retu the API consumer is expected to call subscribe and wait for completion using the wasi-poll module.

                          Note: these functions are here for WASI Preview2 only. They're planned to be removed when future is natively supported in Preview3.

                          -

                          Typical errors:

                          +

                          Typical errors

                          • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
                          @@ -633,12 +633,12 @@ It's planned to be removed when future is natively supported in Pre

                          This function does not require a network capability handle. This is considered to be safe because at time of creation, the socket is not bound to any network yet. Up to the moment bind/connect is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                          -

                          Typical errors:

                          +

                          Typical errors

                          • not-supported: The host does not support UDP sockets.
                          • not-supported: The specified address-family is not supported.
                          -

                          References:

                          +

                          References:

                          • https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html
                          • https://man7.org/linux/man-pages/man2/socket.2.html
                          • @@ -889,7 +889,7 @@ network interface(s) to bind to. If the TCP/UDP port is zero, the socket will be bound to a random free port.

                            When a socket is not explicitly bound, the first invocation to a listen or connect operation will implicitly bind the socket.

                            -

                            Typical errors:

                            +

                            Typical errors

                            • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
                            • already-bound: The socket is already bound. (EINVAL)
                            • @@ -898,7 +898,7 @@ implicitly bind the socket.

                            • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
                            • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
                            -

                            References

                            +

                            References

                            -

                            Typical errors:

                            +

                            Typical errors

                            • timeout: Connection timed out. (ETIMEDOUT)
                            • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
                            • @@ -937,7 +937,7 @@ implicitly bind the socket.

                            • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
                            • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
                            -

                            References

                            +

                            References

                            • https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
                            • https://man7.org/linux/man-pages/man2/connect.2.html
                            • @@ -957,7 +957,7 @@ implicitly bind the socket.

                              listen: func

                              Start listening for new connections.

                              Transitions the socket into the Listener state.

                              -

                              Typical errors:

                              +

                              Typical errors

                              • already-attached: The socket is already attached to a different network. The network passed to listen must be identical to the one passed to bind.
                              • already-connected: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
                              • @@ -965,7 +965,7 @@ implicitly bind the socket.

                              • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
                              • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EINVAL on BSD)
                              -

                              References

                              +

                              References

                              unicast-hop-limit: func

                              Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                              -

                              Typical errors:

                              +

                              Typical errors

                              • already-connected: (set) The socket is already in the Connection state.
                              • already-listening: (set) The socket is already in the Listener state.
                              • @@ -1185,7 +1185,7 @@ In other words, after setting a value, reading the same setting back may return actual data to be sent/received by the application, because the kernel might also use the buffer space for internal metadata structures.

                                Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

                                -

                                Typical errors:

                                +

                                Typical errors

                                • already-connected: (set) The socket is already in the Connection state.
                                • already-listening: (set) The socket is already in the Listener state.
                                • @@ -1235,7 +1235,7 @@ When switched to "non-blocking" mode, operations that would block retu the API consumer is expected to call subscribe and wait for completion using the wasi-poll module.

                                  Note: these functions are here for WASI Preview2 only. They're planned to be removed when future is natively supported in Preview3.

                                  -

                                  Typical errors:

                                  +

                                  Typical errors

                                  • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                                  @@ -1280,11 +1280,11 @@ operations on the output-stream associ
                                • both: same effect as receive & send combined.

                                The shutdown function does not close (drop) the socket.

                                -

                                Typical errors:

                                +

                                Typical errors

                                • not-connected: The socket is not in the Connection state. (ENOTCONN)
                                -

                                References

                                +

                                References

                                • https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html
                                • https://man7.org/linux/man-pages/man2/shutdown.2.html
                                • @@ -1331,12 +1331,12 @@ operations on the output-stream associ

                                  This function does not require a network capability handle. This is considered to be safe because at time of creation, the socket is not bound to any network yet. Up to the moment bind/listen/connect is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                                  -

                                  Typical errors:

                                  +

                                  Typical errors

                                  • not-supported: The host does not support TCP sockets.
                                  • not-supported: The specified address-family is not supported.
                                  -

                                  References:

                                  +

                                  References

                                  -

                                  References:

                                  +

                                  References

                                  • https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html
                                  • https://man7.org/linux/man-pages/man3/getaddrinfo.3.html
                                  • diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index b594598e0..61144e59f 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -25,7 +25,7 @@ default interface ip-name-lookup { /// - an IP address /// - a syntactically invalid domain name in another way /// - /// References: + /// # References /// - /// - /// diff --git a/proposals/sockets/wit/tcp-create-socket.wit b/proposals/sockets/wit/tcp-create-socket.wit index f3710c989..25c82006b 100644 --- a/proposals/sockets/wit/tcp-create-socket.wit +++ b/proposals/sockets/wit/tcp-create-socket.wit @@ -11,11 +11,11 @@ default interface tcp-create-socket { /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// - /// Typical errors: + /// # Typical errors /// - `not-supported`: The host does not support TCP sockets. /// - `not-supported`: The specified `address-family` is not supported. /// - /// References: + /// # References /// - /// - create-tcp-socket: func(address-family: ip-address-family) -> result diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 052887925..39b57d0ab 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -29,7 +29,7 @@ default interface tcp { /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will /// implicitly bind the socket. /// - /// Typical errors: + /// # Typical errors /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) /// - `already-bound`: The socket is already bound. (EINVAL) /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) @@ -37,7 +37,7 @@ default interface tcp { /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) /// - /// References + /// # References /// - /// - /// - @@ -50,7 +50,7 @@ default interface tcp { /// - the socket is transitioned into the Connection state /// - a pair of streams is returned that can be used to read & write to the connection /// - /// Typical errors: + /// # Typical errors /// - `timeout`: Connection timed out. (ETIMEDOUT) /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) /// - `connection-reset`: The connection was reset. (ECONNRESET) @@ -64,7 +64,7 @@ default interface tcp { /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) /// - /// References + /// # References /// - /// - /// - @@ -75,14 +75,14 @@ default interface tcp { /// /// Transitions the socket into the Listener state. /// - /// Typical errors: + /// # Typical errors /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `listen` must be identical to the one passed to `bind`. /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) /// - `already-listening`: The socket is already in the Listener state. /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) /// - /// References + /// # References /// - /// - /// - @@ -96,12 +96,12 @@ default interface tcp { /// On success, this function returns the newly accepted client socket along with /// a pair of streams that can be used to read & write to the connection. /// - /// Typical errors: + /// # Typical errors /// - `not-listening`: Socket is not in the Listener state. (EINVAL) /// /// Host implementations must skip over transient errors returned by the native accept syscall. /// - /// References: + /// # References /// - /// - /// - @@ -110,10 +110,10 @@ default interface tcp { /// Get the bound local address. /// - /// Typical errors: + /// # Typical errors /// - `not-bound`: The socket is not bound to any local address. /// - /// References + /// # References /// - /// - /// - @@ -122,10 +122,10 @@ default interface tcp { /// Get the bound remote address. /// - /// Typical errors: + /// # Typical errors /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) /// - /// References + /// # References /// - /// - /// - @@ -141,7 +141,7 @@ default interface tcp { /// /// Equivalent to the IPV6_V6ONLY socket option. /// - /// Typical errors: + /// # Typical errors /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. /// - `already-bound`: (set) The socket is already bound. /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) @@ -151,28 +151,28 @@ default interface tcp { /// Hints the desired listen queue size. Implementations are free to ignore this. /// - /// Typical errors: + /// # Typical errors /// - `already-connected`: (set) The socket is already in the Connection state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error> /// Equivalent to the SO_KEEPALIVE socket option. /// - /// Typical errors: + /// # Typical errors /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) keep-alive: func(this: tcp-socket) -> result set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error> /// Equivalent to the TCP_NODELAY socket option. /// - /// Typical errors: + /// # Typical errors /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) no-delay: func(this: tcp-socket) -> result set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error> /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// - /// Typical errors: + /// # Typical errors /// - `already-connected`: (set) The socket is already in the Connection state. /// - `already-listening`: (set) The socket is already in the Listener state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) @@ -190,7 +190,7 @@ default interface tcp { /// /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. /// - /// Typical errors: + /// # Typical errors /// - `already-connected`: (set) The socket is already in the Connection state. /// - `already-listening`: (set) The socket is already in the Listener state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) @@ -208,7 +208,7 @@ default interface tcp { /// Note: these functions are here for WASI Preview2 only. /// They're planned to be removed when `future` is natively supported in Preview3. /// - /// Typical errors: + /// # Typical errors /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) non-blocking: func(this: tcp-socket) -> result set-non-blocking: func(this: tcp-socket, value: bool) -> result<_, error> @@ -230,10 +230,10 @@ default interface tcp { /// /// The shutdown function does not close (drop) the socket. /// - /// Typical errors: + /// # Typical errors /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) /// - /// References + /// # References /// - /// - /// - diff --git a/proposals/sockets/wit/udp-create-socket.wit b/proposals/sockets/wit/udp-create-socket.wit index 4a4a16ac0..9445b6eb6 100644 --- a/proposals/sockets/wit/udp-create-socket.wit +++ b/proposals/sockets/wit/udp-create-socket.wit @@ -11,11 +11,11 @@ default interface udp-create-socket { /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` is called, /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// - /// Typical errors: + /// # Typical errors /// - `not-supported`: The host does not support UDP sockets. /// - `not-supported`: The specified `address-family` is not supported. /// - /// References: + /// # References: /// - /// - create-udp-socket: func(address-family: ip-address-family) -> result diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 9ed0046be..2edf5b154 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -30,7 +30,7 @@ default interface udp { /// /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. /// - /// Typical errors: + /// # Typical errors /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) /// - `already-bound`: The socket is already bound. (EINVAL) /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) @@ -38,7 +38,7 @@ default interface udp { /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) /// - /// References + /// # References /// - /// - /// - @@ -55,7 +55,7 @@ default interface udp { /// /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". /// - /// Typical errors: + /// # Typical errors /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) @@ -63,7 +63,7 @@ default interface udp { /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) /// - /// References + /// # References /// - /// - /// - @@ -76,11 +76,11 @@ default interface udp { /// - The sender address of the datagram /// - The number of bytes read. /// - /// Typical errors: + /// # Typical errors /// - `not-bound`: The socket is not bound to any local address. (EINVAL) /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) /// - /// References + /// # References /// - /// - /// - @@ -95,7 +95,7 @@ default interface udp { /// The remote address option is required. To send a message to the "connected" peer, /// call `remote-address` to get their address. /// - /// Typical errors: + /// # Typical errors /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) @@ -104,7 +104,7 @@ default interface udp { /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) /// - /// References + /// # References /// - /// - /// - @@ -116,10 +116,10 @@ default interface udp { /// Get the current bound address. /// - /// Typical errors: + /// # Typical errors /// - `not-bound`: The socket is not bound to any local address. /// - /// References + /// # References /// - /// - /// - @@ -128,10 +128,10 @@ default interface udp { /// Get the address set with `connect`. /// - /// Typical errors: + /// # Typical errors /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) /// - /// References + /// # References /// - /// - /// - @@ -147,7 +147,7 @@ default interface udp { /// /// Equivalent to the IPV6_V6ONLY socket option. /// - /// Typical errors: + /// # Typical errors /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. /// - `already-bound`: (set) The socket is already bound. /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) @@ -157,7 +157,7 @@ default interface udp { /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// - /// Typical errors: + /// # Typical errors /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) unicast-hop-limit: func(this: udp-socket) -> result set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error> @@ -175,7 +175,7 @@ default interface udp { /// /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. /// - /// Typical errors: + /// # Typical errors /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) receive-buffer-size: func(this: udp-socket) -> result set-receive-buffer-size: func(this: udp-socket, value: u64) -> result<_, error> @@ -191,7 +191,7 @@ default interface udp { /// Note: these functions are here for WASI Preview2 only. /// They're planned to be removed when `future` is natively supported in Preview3. /// - /// Typical errors: + /// # Typical errors /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) non-blocking: func(this: udp-socket) -> result set-non-blocking: func(this: udp-socket, value: bool) -> result<_, error> From 177ec6b9fee1aa91439b036871284efa6a2a30c6 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 26 Feb 2023 12:38:08 +0100 Subject: [PATCH 1075/1772] Document `resolve-addresses` errors. --- proposals/sockets/wit/ip-name-lookup.wit | 26 +++++++++---- proposals/sockets/wit/network.wit | 41 ++++++++++++++++----- proposals/sockets/wit/tcp-create-socket.wit | 4 +- proposals/sockets/wit/udp-create-socket.wit | 4 +- 4 files changed, 54 insertions(+), 21 deletions(-) diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index 61144e59f..bc413d83c 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -8,7 +8,7 @@ default interface ip-name-lookup { /// /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. /// - /// Parameters: + /// # Parameters /// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted /// to ASCII using IDNA encoding. /// - `address-family`: If provided, limit the results to addresses of this specific address family. @@ -18,17 +18,22 @@ default interface ip-name-lookup { /// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. /// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. /// - /// This function never blocks. It either immediately returns successfully with a `resolve-address-stream` + /// This function never blocks. It either immediately fails or immediately returns successfully with a `resolve-address-stream` /// that can be used to (asynchronously) fetch the results. - /// Or it immediately fails whenever `name` is: - /// - empty - /// - an IP address - /// - a syntactically invalid domain name in another way /// - /// # References + /// At the moment, the stream never completes successfully with 0 items. Ie. the first call + /// to `resolve-next-address` never returns `ok(none)`. This may change in the future. + /// + /// # Typical errors + /// - `invalid-name`: `name` is a syntactically invalid domain name. + /// - `invalid-name`: `name` is an IP address. + /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAI_FAMILY) + /// + /// # References: /// - /// - - /// + /// - + /// - resolve-addresses: func(network: network, name: string, address-family: option, include-unavailable: bool) -> result @@ -43,6 +48,11 @@ default interface ip-name-lookup { /// After which, you should release the stream with `drop-resolve-address-stream`. /// /// This function never returns IPv4-mapped IPv6 addresses. + /// + /// # Typical errors + /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) + /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) + /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) resolve-next-address: func(this: resolve-address-stream) -> result, error> diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 2b8e4e7c1..ad5f97171 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -26,6 +26,8 @@ default interface network { /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. enum error { + // ### GENERAL ERRORS ### + /// Unknown error unknown, @@ -41,26 +43,47 @@ default interface network { /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY out-of-memory, + timeout, concurrency-conflict, + + + // ### IP ERRORS ### + address-family-not-supported, + address-family-mismatch, + invalid-remote-address, + ipv4-only-operation, + ipv6-only-operation, + + + + // ### TCP & UDP SOCKET ERRORS ### already-attached, already-bound, already-connected, - already-listening, not-bound, not-connected, - not-listening, - address-family-mismatch, - invalid-remote-address, - datagram-too-large, address-not-bindable, address-in-use, ephemeral-ports-exhausted, + remote-unreachable, + + + // ### TCP SOCKET ERRORS ### + already-listening, + not-listening, connection-refused, connection-reset, - remote-unreachable, - timeout, - ipv4-only-operation, - ipv6-only-operation, + + + // ### UDP SOCKET ERRORS ### + datagram-too-large, + + + // ### NAME LOOKUP ERRORS ### + invalid-name, + name-unresolvable, + temporary-resolver-failure, + permanent-resolver-failure, } enum ip-address-family { diff --git a/proposals/sockets/wit/tcp-create-socket.wit b/proposals/sockets/wit/tcp-create-socket.wit index 25c82006b..a17e6f5e7 100644 --- a/proposals/sockets/wit/tcp-create-socket.wit +++ b/proposals/sockets/wit/tcp-create-socket.wit @@ -12,8 +12,8 @@ default interface tcp-create-socket { /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// /// # Typical errors - /// - `not-supported`: The host does not support TCP sockets. - /// - `not-supported`: The specified `address-family` is not supported. + /// - `not-supported`: The host does not support TCP sockets. + /// - `address-family-not-supported`: The specified `address-family` is not supported. /// /// # References /// - diff --git a/proposals/sockets/wit/udp-create-socket.wit b/proposals/sockets/wit/udp-create-socket.wit index 9445b6eb6..404722e01 100644 --- a/proposals/sockets/wit/udp-create-socket.wit +++ b/proposals/sockets/wit/udp-create-socket.wit @@ -12,8 +12,8 @@ default interface udp-create-socket { /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// /// # Typical errors - /// - `not-supported`: The host does not support UDP sockets. - /// - `not-supported`: The specified `address-family` is not supported. + /// - `not-supported`: The host does not support UDP sockets. + /// - `address-family-not-supported`: The specified `address-family` is not supported. /// /// # References: /// - From 90d3d1cfd95e7d69a1f3945bae2b47f5ab64ab07 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 26 Feb 2023 12:41:57 +0100 Subject: [PATCH 1076/1772] Update example-world.md --- proposals/sockets/example-world.md | 77 ++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index 3f5b87fc0..cdff24d60 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -117,37 +117,40 @@ combined with a couple of errors that are always possible:

                                    POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY

                                  • +

                                    timeout

                                    +
                                  • +
                                  • concurrency-conflict

                                  • -

                                    already-attached

                                    +

                                    address-family-not-supported

                                  • -

                                    already-bound

                                    +

                                    address-family-mismatch

                                  • -

                                    already-connected

                                    +

                                    invalid-remote-address

                                  • -

                                    already-listening

                                    +

                                    ipv4-only-operation

                                  • -

                                    not-bound

                                    +

                                    ipv6-only-operation

                                  • -

                                    not-connected

                                    +

                                    already-attached

                                  • -

                                    not-listening

                                    +

                                    already-bound

                                  • -

                                    address-family-mismatch

                                    +

                                    already-connected

                                  • -

                                    invalid-remote-address

                                    +

                                    not-bound

                                  • -

                                    datagram-too-large

                                    +

                                    not-connected

                                  • address-not-bindable

                                    @@ -159,22 +162,34 @@ combined with a couple of errors that are always possible:

                                    ephemeral-ports-exhausted

                                  • +

                                    remote-unreachable

                                    +
                                  • +
                                  • +

                                    already-listening

                                    +
                                  • +
                                  • +

                                    not-listening

                                    +
                                  • +
                                  • connection-refused

                                  • connection-reset

                                  • -

                                    remote-unreachable

                                    +

                                    datagram-too-large

                                  • -

                                    timeout

                                    +

                                    invalid-name

                                  • -

                                    ipv4-only-operation

                                    +

                                    name-unresolvable

                                  • -

                                    ipv6-only-operation

                                    +

                                    temporary-resolver-failure

                                    +
                                  • +
                                  • +

                                    permanent-resolver-failure


                                  @@ -635,8 +650,8 @@ at time of creation, the socket is not bound to any net the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                                  Typical errors

                                  References:

                                    @@ -1333,8 +1348,8 @@ at time of creation, the socket is not bound to any net is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                                    Typical errors

                                    References

                                      @@ -1375,7 +1390,7 @@ is called, the socket is effectively an in-memory configuration object, unable t

                                      resolve-addresses: func

                                      Resolve an internet host name to a list of IP addresses.

                                      See the wasi-socket proposal README.md for a comparison with getaddrinfo.

                                      -

                                      Parameters:

                                      +

                                      Parameters

                                      • name: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted to ASCII using IDNA encoding.
                                      • @@ -1386,18 +1401,22 @@ systems without an active IPv6 interface. Notes:
                                      • Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address.
                                      • Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged.
                                      -

                                      This function never blocks. It either immediately returns successfully with a resolve-address-stream -that can be used to (asynchronously) fetch the results. -Or it immediately fails whenever name is:

                                      +

                                      This function never blocks. It either immediately fails or immediately returns successfully with a resolve-address-stream +that can be used to (asynchronously) fetch the results.

                                      +

                                      At the moment, the stream never completes successfully with 0 items. Ie. the first call +to resolve-next-address never returns ok(none). This may change in the future.

                                      +

                                      Typical errors

                                        -
                                      • empty
                                      • -
                                      • an IP address
                                      • -
                                      • a syntactically invalid domain name in another way
                                      • +
                                      • invalid-name: name is a syntactically invalid domain name.
                                      • +
                                      • invalid-name: name is an IP address.
                                      • +
                                      • address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)
                                      -

                                      References

                                      +

                                      References:

                                      Params
                                        @@ -1417,6 +1436,12 @@ return the next address in connection order preference. If all addresses have been exhausted, this function returns none. After which, you should release the stream with drop-resolve-address-stream.

                                        This function never returns IPv4-mapped IPv6 addresses.

                                        +

                                        Typical errors

                                        +
                                          +
                                        • name-unresolvable: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY)
                                        • +
                                        • temporary-resolver-failure: A temporary failure in name resolution occurred. (EAI_AGAIN)
                                        • +
                                        • permanent-resolver-failure: A permanent failure in name resolution occurred. (EAI_FAIL)
                                        • +
                                        Params
                                        • this: resolve-address-stream
                                        • From 0fb59e6a45af1727944c2db36d91afde7f6898d1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Feb 2023 16:43:21 -0800 Subject: [PATCH 1077/1772] Add environment variables, based on the preview2-prototyping versions. --- proposals/cli/cli.md | 32 +++++++++++++++++++++- proposals/cli/wit/cli.wit | 2 ++ proposals/cli/wit/environment-preopens.wit | 6 ++++ proposals/cli/wit/environment.wit | 11 ++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 proposals/cli/wit/environment-preopens.wit create mode 100644 proposals/cli/wit/environment.wit diff --git a/proposals/cli/cli.md b/proposals/cli/cli.md index 985b5b18c..4e5bc36d1 100644 --- a/proposals/cli/cli.md +++ b/proposals/cli/cli.md @@ -11,6 +11,8 @@
                                        • interface streams
                                        • interface filesystem
                                        • interface random
                                        • +
                                        • interface environment
                                        • +
                                        • interface environment-preopens
                                        • interface exit
                                        • type input-stream
                                        • type output-stream
                                        • @@ -1532,6 +1534,34 @@ protection.

                                          • (u64, u64)
                                          +

                                          Import interface environment

                                          +
                                          +

                                          Functions

                                          +

                                          get-environment: func

                                          +

                                          Get the POSIX-style environment variables.

                                          +

                                          Each environment variable is provided as a pair of string variable names +and string value.

                                          +

                                          Morally, these are a value import, but until value imports are available +in the component model, this import function should return the same +values each time it is called.

                                          +
                                          Return values
                                          +
                                            +
                                          • list<(string, string)>
                                          • +
                                          +

                                          Import interface environment-preopens

                                          +
                                          +

                                          Types

                                          +

                                          type descriptor

                                          +

                                          descriptor

                                          +

                                          +---- +

                                          Functions

                                          +

                                          preopens: func

                                          +

                                          Return a list of preopens for use in interpreting environment variables.

                                          +
                                          Return values
                                          +

                                          Import interface exit


                                          Functions

                                          @@ -1561,7 +1591,7 @@ protection.

                                        • stdout: output-stream
                                        • stderr: output-stream
                                        • args: list<string>
                                        • -
                                        • preopens: list<(descriptor, string)>
                                        • +
                                        • preopens: list<(descriptor, string)>
                                        Return values
                                          diff --git a/proposals/cli/wit/cli.wit b/proposals/cli/wit/cli.wit index fc79e803a..4a4ad1f6e 100644 --- a/proposals/cli/wit/cli.wit +++ b/proposals/cli/wit/cli.wit @@ -8,6 +8,8 @@ default world cli { import random: random.random import poll: poll.poll import streams: io.streams + import environment: pkg.environment + import environment-preopens: pkg.environment-preopens import exit: pkg.exit use io.streams.{input-stream, output-stream} diff --git a/proposals/cli/wit/environment-preopens.wit b/proposals/cli/wit/environment-preopens.wit new file mode 100644 index 000000000..74f17d587 --- /dev/null +++ b/proposals/cli/wit/environment-preopens.wit @@ -0,0 +1,6 @@ +default interface environment-preopens { + use filesystem.filesystem.{descriptor} + + /// Return a list of preopens for use in interpreting environment variables. + preopens: func() -> list> +} diff --git a/proposals/cli/wit/environment.wit b/proposals/cli/wit/environment.wit new file mode 100644 index 000000000..f3ab7181b --- /dev/null +++ b/proposals/cli/wit/environment.wit @@ -0,0 +1,11 @@ +default interface environment { + /// Get the POSIX-style environment variables. + /// + /// Each environment variable is provided as a pair of string variable names + /// and string value. + /// + /// Morally, these are a value import, but until value imports are available + /// in the component model, this import function should return the same + /// values each time it is called. + get-environment: func() -> list> +} From 08c2df9fccf85ee21fbf3cdf13f478e351dd6fa6 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Sun, 26 Feb 2023 12:57:56 -0600 Subject: [PATCH 1078/1772] Add clocks/random to world, update deps/ on other wasi-* proposals --- proposals/http/wit/deps/io/streams.wit | 40 +++++++++++++---- proposals/http/wit/deps/logging/handler.wit | 45 ++++++++++--------- proposals/http/wit/deps/{io => poll}/poll.wit | 14 +++--- proposals/http/wit/deps/random/random.wit | 42 +++++++++++++++++ proposals/http/wit/proxy.wit | 13 ++++++ proposals/http/wit/types.wit | 2 +- 6 files changed, 117 insertions(+), 39 deletions(-) rename proposals/http/wit/deps/{io => poll}/poll.wit (86%) create mode 100644 proposals/http/wit/deps/random/random.wit diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index 599645256..9fa533efe 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -4,7 +4,7 @@ /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. default interface streams { - use pkg.poll.{pollable} + use poll.poll.{pollable} /// An error type returned from a stream operation. Currently this /// doesn't provide any additional information. @@ -16,9 +16,17 @@ default interface streams { /// This conceptually represents a `stream`. It's temporary /// scaffolding until component-model's async features are ready. /// + /// `input-stream`s are *non-blocking* to the extent practical on underlying + /// platforms. I/O operations always return promptly; if fewer bytes are + /// promptly available than requested, they return the number of bytes promptly + /// available, which could even be zero. To wait for data to be available, + /// use the `subscribe-to-input-stream` function to obtain a `pollable` which + /// can be polled for using `wasi_poll`. + /// /// And at present, it is a `u32` instead of being an actual handle, until /// the wit-bindgen implementation of handles and resources is ready. - // TODO(resource input-stream {) + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). type input-stream = u32 /// Read bytes from a stream. @@ -63,13 +71,13 @@ default interface streams { len: u64, ) -> result, stream-error> - /// Create a `pollable` which will resolve once either the specified stream has bytes - /// available to read or the other end of the stream has been closed. + /// Create a `pollable` which will resolve once either the specified stream + /// has bytes available to read or the other end of the stream has been + /// closed. subscribe-to-input-stream: func(this: input-stream) -> pollable /// Dispose of the specified `input-stream`, after which it may no longer /// be used. - // TODO(} /* resource input-stream */) drop-input-stream: func(this: input-stream) /// An output bytestream. In the future, this will be replaced by handle @@ -78,9 +86,17 @@ default interface streams { /// This conceptually represents a `stream`. It's temporary /// scaffolding until component-model's async features are ready. /// + /// `output-stream`s are *non-blocking* to the extent practical on + /// underlying platforms. Except where specified otherwise, I/O operations also + /// always return promptly, after the number of bytes that can be written + /// promptly, which could even be zero. To wait for the stream to be ready to + /// accept data, the `subscribe-to-output-stream` function to obtain a + /// `pollable` which can be polled for using `wasi_poll`. + /// /// And at present, it is a `u32` instead of being an actual handle, until /// the wit-bindgen implementation of handles and resources is ready. - // TODO(resource output-stream {) + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). type output-stream = u32 /// Write bytes to a stream. @@ -107,6 +123,9 @@ default interface streams { /// /// This function returns the number of bytes transferred; it may be less /// than `len`. + /// + /// Unlike other I/O functions, this function blocks until all the data + /// read from the input stream has been written to the output stream. splice: func( this: output-stream, /// The stream to read from @@ -121,6 +140,10 @@ default interface streams { /// the data to the output stream, until the end of the input stream /// is reached, or an error is encountered. /// + /// Unlike other I/O functions, this function blocks until the end + /// of the input stream is seen and all the data has been written to + /// the output stream. + /// /// This function returns the number of bytes transferred. forward: func( this: output-stream, @@ -128,12 +151,11 @@ default interface streams { src: input-stream ) -> result - /// Create a `pollable` which will resolve once either the specified stream is ready - /// to accept bytes or the other end of the stream has been closed. + /// Create a `pollable` which will resolve once either the specified stream + /// is ready to accept bytes or the other end of the stream has been closed. subscribe-to-output-stream: func(this: output-stream) -> pollable /// Dispose of the specified `output-stream`, after which it may no longer /// be used. - // TODO(} /* resource output-stream */) drop-output-stream: func(this: output-stream) } diff --git a/proposals/http/wit/deps/logging/handler.wit b/proposals/http/wit/deps/logging/handler.wit index 1f5cc125a..c9632b9cc 100644 --- a/proposals/http/wit/deps/logging/handler.wit +++ b/proposals/http/wit/deps/logging/handler.wit @@ -1,31 +1,32 @@ -/// # WASI Logging API -/// /// WASI Logging is a logging API intended to let users emit log messages with /// simple priority levels and context values. default interface handler { - /// A log level, describing a kind of message. - enum level { - /// Describes messages about the values of variables and the flow of control - /// within a program. - trace, + /// A log level, describing a kind of message. + enum level { + /// Describes messages about the values of variables and the flow of + /// control within a program. + trace, - /// Describes messages likely to be of interest to someone debugging a program. - debug, + /// Describes messages likely to be of interest to someone debugging a + /// program. + debug, - /// Describes messages likely to be of interest to someone monitoring a program. - info, + /// Describes messages likely to be of interest to someone monitoring a + /// program. + info, - /// Describes messages indicating hazardous situations. - warn, + /// Describes messages indicating hazardous situations. + warn, - /// Describes messages indicating serious errors. - error, - } + /// Describes messages indicating serious errors. + error, + } - /// Emit a log message. - /// - /// A log message has a `level` describing what kind of message is being sent, - /// a context, which is an uninterpreted string meant to help consumers group - /// similar messages, and a string containing the message text. - log: func(level: level, context: string, message: string) + /// Emit a log message. + /// + /// A log message has a `level` describing what kind of message is being + /// sent, a context, which is an uninterpreted string meant to help + /// consumers group similar messages, and a string containing the message + /// text. + log: func(level: level, context: string, message: string) } diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/poll/poll.wit similarity index 86% rename from proposals/http/wit/deps/io/poll.wit rename to proposals/http/wit/deps/poll/poll.wit index 3b2c14f83..28f08e17d 100644 --- a/proposals/http/wit/deps/io/poll.wit +++ b/proposals/http/wit/deps/poll/poll.wit @@ -1,7 +1,6 @@ -/// -/// WASI Poll is a poll API intended to let users wait for I/O events on -/// multiple handles at once. -default interface wasi-poll { +/// A poll API intended to let users wait for I/O events on multiple handles +/// at once. +default interface poll { /// A "pollable" handle. /// /// This is conceptually represents a `stream<_, _>`, or in other words, @@ -14,11 +13,12 @@ default interface wasi-poll { /// /// `pollable` lifetimes are not automatically managed. Users must ensure /// that they do not outlive the resource they reference. - // TODO(resource pollable {) + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). type pollable = u32 - /// Dispose of the specified `pollable`, after which it may no longer be used. - // TODO(} /* resource pollable */) + /// Dispose of the specified `pollable`, after which it may no longer + /// be used. drop-pollable: func(this: pollable) /// Poll for completion on a set of pollables. diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit new file mode 100644 index 000000000..2080ddfde --- /dev/null +++ b/proposals/http/wit/deps/random/random.wit @@ -0,0 +1,42 @@ +/// WASI Random is a random data API. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface random { + /// Return `len` cryptographically-secure pseudo-random bytes. + /// + /// This function must produce data from an adequately seeded + /// cryptographically-secure pseudo-random number generator (CSPRNG), so it + /// must not block, from the perspective of the calling program, and the + /// returned data is always unpredictable. + /// + /// This function must always return fresh pseudo-random data. Deterministic + /// environments must omit this function, rather than implementing it with + /// deterministic data. + get-random-bytes: func(len: u64) -> list + + /// Return a cryptographically-secure pseudo-random `u64` value. + /// + /// This function returns the same type of pseudo-random data as + /// `get-random-bytes`, represented as a `u64`. + get-random-u64: func() -> u64 + + /// Return a 128-bit value that may contain a pseudo-random value. + /// + /// The returned value is not required to be computed from a CSPRNG, and may + /// even be entirely deterministic. Host implementations are encouraged to + /// provide pseudo-random values to any program exposed to + /// attacker-controlled content, to enable DoS protection built into many + /// languages' hash-map implementations. + /// + /// This function is intended to only be called once, by a source language + /// to initialize Denial Of Service (DoS) protection in its hash-map + /// implementation. + /// + /// # Expected future evolution + /// + /// This will likely be changed to a value import, to prevent it from being + /// called multiple times and potentially used for purposes other than DoS + /// protection. + insecure-random: func() -> tuple +} diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index c9f17f6f2..d0092e9f4 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -3,11 +3,24 @@ // this world may concurrently stream in and out any number of incoming and // outgoing HTTP requests. default world proxy { + // HTTP proxies have access to time and randomness. + import random: random.random + // TODO: add `import wall-clock: clocks.wall-clock` + // TODO: add `import monotonic-clock: clocks.monotonic-clock` // This is the default logging handler to use when user code simply wants to // log to a developer-facing console (e.g., via `console.log()`). import console: logging.handler + // TODO: Once the underlying Wit template machinery is implemented, add: + // + // import loggers: interface { + // *: logging.handler + // } + // + // which will allow a component to import any number of non-default logging + // backends that different categories of log messages can be sent to. + // TODO: add `import metrics: metrics.counters` // This is the default handler to use when user code simply wants to make an diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 93add6205..fa315e298 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -3,7 +3,7 @@ // imported and exported interfaces. default interface types { use io.streams.{input-stream, output-stream} - use io.poll.{pollable} + use poll.poll.{pollable} // This type corresponds to HTTP standard Methods. variant method { From 65b6bbef7413adab105ea0ad710e53a61a3dbfa9 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 26 Feb 2023 21:54:33 +0100 Subject: [PATCH 1079/1772] Rename `error` -> `error-code` for consistency with wasi-filesystem. --- proposals/sockets/example-world.md | 174 ++++++++++---------- proposals/sockets/wit/ip-name-lookup.wit | 10 +- proposals/sockets/wit/network.wit | 4 +- proposals/sockets/wit/tcp-create-socket.wit | 4 +- proposals/sockets/wit/tcp.wit | 48 +++--- proposals/sockets/wit/udp-create-socket.wit | 4 +- proposals/sockets/wit/udp.wit | 36 ++-- 7 files changed, 140 insertions(+), 140 deletions(-) diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index cdff24d60..11c7a3410 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -81,7 +81,7 @@ There is no need for this to map 1:1 to a physical network interface.
                                        • ipv4: ipv4-address
                                        • ipv6: ipv6-address
                                        -

                                        enum error

                                        +

                                        enum error-code

                                        Error codes.

                                        In theory, every API can return any error code. In practice, API's typically only return the errors documented per API @@ -97,99 +97,99 @@ combined with a couple of errors that are always possible:

                                        Enum Cases

                                        @@ -272,8 +272,8 @@ mean "ready".

                                        #### `type network` [`network`](#network)

                                        -#### `type error` -[`error`](#error) +#### `type error-code` +[`error-code`](#error_code)

                                        #### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address) @@ -322,7 +322,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                                      Return values

                                      connect: func

                                      Set the destination address.

                                      @@ -357,7 +357,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                                    Return values

                                    receive: func

                                    Receive a message.

                                    @@ -387,7 +387,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                                  Return values

                                  send: func

                                  Send a message to a specific destination address.

                                  @@ -420,7 +420,7 @@ call remote-address to get their addr
                                Return values

                                local-address: func

                                Get the current bound address.

                                @@ -441,7 +441,7 @@ call remote-address to get their addr
                              Return values

                              remote-address: func

                              Get the address set with connect.

                              @@ -462,7 +462,7 @@ call remote-address to get their addr
                            Return values

                            address-family: func

                            Whether this is a IPv4 or IPv6 socket.

                            @@ -473,7 +473,7 @@ call remote-address to get their addr
                          Return values

                          ipv6-only: func

                          Whether IPv4 compatibility (dual-stack) mode is disabled or not.

                          @@ -491,7 +491,7 @@ call remote-address to get their addr
                        Return values

                        set-ipv6-only: func

                        Params
                        @@ -501,7 +501,7 @@ call remote-address to get their addr
                      Return values

                      unicast-hop-limit: func

                      Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                      @@ -515,7 +515,7 @@ call remote-address to get their addr
                    Return values

                    set-unicast-hop-limit: func

                    Params
                    @@ -525,7 +525,7 @@ call remote-address to get their addr
                  Return values

                  receive-buffer-size: func

                  The kernel buffer space reserved for sends/receives on this socket.

                  @@ -546,7 +546,7 @@ for internal metadata structures.

                Return values

                set-receive-buffer-size: func

                Params
                @@ -556,7 +556,7 @@ for internal metadata structures.

              Return values

              send-buffer-size: func

              Params
              @@ -565,7 +565,7 @@ for internal metadata structures.

            Return values

            set-send-buffer-size: func

            Params
            @@ -575,7 +575,7 @@ for internal metadata structures.

          Return values

          non-blocking: func

          Get/set the blocking mode of the socket.

          @@ -594,7 +594,7 @@ They're planned to be removed when future is natively supported in
        Return values

        set-non-blocking: func

        Params
        @@ -604,7 +604,7 @@ They're planned to be removed when future is natively supported in
      Return values

      subscribe: func

      Create a pollable which will resolve once the socket is ready for I/O.

      @@ -631,8 +631,8 @@ It's planned to be removed when future is natively supported in Pre

      type network

      network

      -#### `type error` -[`error`](#error) +#### `type error-code` +[`error-code`](#error_code)

      #### `type ip-address-family` [`ip-address-family`](#ip_address_family) @@ -664,7 +664,7 @@ the socket is effectively an in-memory configuration object, unable to communica

    Return values

    Import interface streams

    WASI I/O is an I/O abstraction API which is currently focused on providing @@ -867,8 +867,8 @@ be used.

    #### `type network` [`network`](#network)

    -#### `type error` -[`error`](#error) +#### `type error-code` +[`error-code`](#error_code)

    #### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address) @@ -928,7 +928,7 @@ implicitly bind the socket.

    Return values

    connect: func

    Connect to a remote endpoint.

    @@ -967,7 +967,7 @@ implicitly bind the socket.

    Return values

    listen: func

    Start listening for new connections.

    @@ -994,7 +994,7 @@ implicitly bind the socket.

    Return values

    accept: func

    Accept a new client socket.

    @@ -1019,7 +1019,7 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    local-address: func

    Get the bound local address.

    @@ -1040,7 +1040,7 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    remote-address: func

    Get the bound remote address.

    @@ -1061,7 +1061,7 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    address-family: func

    Whether this is a IPv4 or IPv6 socket.

    @@ -1072,7 +1072,7 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    ipv6-only: func

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    @@ -1090,7 +1090,7 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    set-ipv6-only: func

    Params
    @@ -1100,7 +1100,7 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    set-listen-backlog-size: func

    Hints the desired listen queue size. Implementations are free to ignore this.

    @@ -1116,7 +1116,7 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    keep-alive: func

    Equivalent to the SO_KEEPALIVE socket option.

    @@ -1130,7 +1130,7 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    set-keep-alive: func

    Params
    @@ -1140,7 +1140,7 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    no-delay: func

    Equivalent to the TCP_NODELAY socket option.

    @@ -1154,7 +1154,7 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    set-no-delay: func

    Params
    @@ -1164,7 +1164,7 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    unicast-hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    @@ -1180,7 +1180,7 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    set-unicast-hop-limit: func

    Params
    @@ -1190,7 +1190,7 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    @@ -1212,7 +1212,7 @@ for internal metadata structures.

    Return values

    set-receive-buffer-size: func

    Params
    @@ -1222,7 +1222,7 @@ for internal metadata structures.

    Return values

    send-buffer-size: func

    Params
    @@ -1231,7 +1231,7 @@ for internal metadata structures.

    Return values

    set-send-buffer-size: func

    Params
    @@ -1241,7 +1241,7 @@ for internal metadata structures.

    Return values

    non-blocking: func

    Get/set the blocking mode of the socket.

    @@ -1260,7 +1260,7 @@ They're planned to be removed when future is natively supported in
    Return values

    set-non-blocking: func

    Params
    @@ -1270,7 +1270,7 @@ They're planned to be removed when future is natively supported in
    Return values

    subscribe: func

    Create a pollable which will resolve once the socket is ready for I/O.

    @@ -1313,7 +1313,7 @@ operations on the output-stream associ
    Return values

    drop-tcp-socket: func

    Dispose of the specified tcp-socket, after which it may no longer be used.

    @@ -1329,8 +1329,8 @@ operations on the output-stream associ

    type network

    network

    -#### `type error` -[`error`](#error) +#### `type error-code` +[`error-code`](#error_code)

    #### `type ip-address-family` [`ip-address-family`](#ip_address_family) @@ -1362,7 +1362,7 @@ is called, the socket is effectively an in-memory configuration object, unable t

    Return values

    Import interface ip-name-lookup


    @@ -1373,8 +1373,8 @@ is called, the socket is effectively an in-memory configuration object, unable t #### `type network` [`network`](#network)

    -#### `type error` -[`error`](#error) +#### `type error-code` +[`error-code`](#error_code)

    #### `type ip-address` [`ip-address`](#ip_address) @@ -1427,7 +1427,7 @@ to resolve-next-address never r

    Return values

    resolve-next-address: func

    Returns the next address from the resolver.

    @@ -1448,7 +1448,7 @@ After which, you should release the stream with result<option<ip-address>, error> +
  • result<option<ip-address>, error-code>
  • drop-resolve-address-stream: func

    Dispose of the specified resolve-address-stream, after which it may no longer be used.

    @@ -1470,7 +1470,7 @@ They're planned to be removed when future is natively supported in
    Return values

    set-non-blocking: func

    Params
    @@ -1480,7 +1480,7 @@ They're planned to be removed when future is natively supported in
    Return values

    subscribe: func

    Create a pollable which will resolve once the stream is ready for I/O.

    diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index bc413d83c..574fff98a 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,7 +1,7 @@ default interface ip-name-lookup { use poll.poll.{pollable} - use pkg.network.{network, error, ip-address, ip-address-family} + use pkg.network.{network, error-code, ip-address, ip-address-family} /// Resolve an internet host name to a list of IP addresses. @@ -34,7 +34,7 @@ default interface ip-name-lookup { /// - /// - /// - - resolve-addresses: func(network: network, name: string, address-family: option, include-unavailable: bool) -> result + resolve-addresses: func(network: network, name: string, address-family: option, include-unavailable: bool) -> result @@ -53,7 +53,7 @@ default interface ip-name-lookup { /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) - resolve-next-address: func(this: resolve-address-stream) -> result, error> + resolve-next-address: func(this: resolve-address-stream) -> result, error-code> @@ -70,8 +70,8 @@ default interface ip-name-lookup { /// /// Note: these functions are here for WASI Preview2 only. /// They're planned to be removed when `future` is natively supported in Preview3. - non-blocking: func(this: resolve-address-stream) -> result - set-non-blocking: func(this: resolve-address-stream, value: bool) -> result<_, error> + non-blocking: func(this: resolve-address-stream) -> result + set-non-blocking: func(this: resolve-address-stream, value: bool) -> result<_, error-code> /// Create a `pollable` which will resolve once the stream is ready for I/O. /// diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index ad5f97171..09509dd92 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -25,7 +25,7 @@ default interface network { /// - `out-of-memory` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - enum error { + enum error-code { // ### GENERAL ERRORS ### /// Unknown error @@ -74,7 +74,7 @@ default interface network { connection-refused, connection-reset, - + // ### UDP SOCKET ERRORS ### datagram-too-large, diff --git a/proposals/sockets/wit/tcp-create-socket.wit b/proposals/sockets/wit/tcp-create-socket.wit index a17e6f5e7..64c9fa78e 100644 --- a/proposals/sockets/wit/tcp-create-socket.wit +++ b/proposals/sockets/wit/tcp-create-socket.wit @@ -1,6 +1,6 @@ default interface tcp-create-socket { - use pkg.network.{network, error, ip-address-family} + use pkg.network.{network, error-code, ip-address-family} use pkg.tcp.{tcp-socket} /// Create a new TCP socket. @@ -18,5 +18,5 @@ default interface tcp-create-socket { /// # References /// - /// - - create-tcp-socket: func(address-family: ip-address-family) -> result + create-tcp-socket: func(address-family: ip-address-family) -> result } diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 39b57d0ab..07763376c 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -2,7 +2,7 @@ default interface tcp { use io.streams.{input-stream, output-stream} use poll.poll.{pollable} - use pkg.network.{network, error, ip-socket-address, ip-address-family} + use pkg.network.{network, error-code, ip-socket-address, ip-address-family} /// A TCP socket handle. type tcp-socket = u32 @@ -42,7 +42,7 @@ default interface tcp { /// - /// - /// - - bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error> + bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> /// Connect to a remote endpoint. /// @@ -69,7 +69,7 @@ default interface tcp { /// - /// - /// - - connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result, error> + connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result, error-code> /// Start listening for new connections. /// @@ -87,7 +87,7 @@ default interface tcp { /// - /// - /// - - listen: func(this: tcp-socket, network: network) -> result<_, error> + listen: func(this: tcp-socket, network: network) -> result<_, error-code> /// Accept a new client socket. /// @@ -106,7 +106,7 @@ default interface tcp { /// - /// - /// - - accept: func(this: tcp-socket) -> result, error> + accept: func(this: tcp-socket) -> result, error-code> /// Get the bound local address. /// @@ -118,7 +118,7 @@ default interface tcp { /// - /// - /// - - local-address: func(this: tcp-socket) -> result + local-address: func(this: tcp-socket) -> result /// Get the bound remote address. /// @@ -130,12 +130,12 @@ default interface tcp { /// - /// - /// - - remote-address: func(this: tcp-socket) -> result + remote-address: func(this: tcp-socket) -> result /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: tcp-socket) -> result + address-family: func(this: tcp-socket) -> result /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. /// @@ -146,29 +146,29 @@ default interface tcp { /// - `already-bound`: (set) The socket is already bound. /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - ipv6-only: func(this: tcp-socket) -> result - set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error> + ipv6-only: func(this: tcp-socket) -> result + set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error-code> /// Hints the desired listen queue size. Implementations are free to ignore this. /// /// # Typical errors /// - `already-connected`: (set) The socket is already in the Connection state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error> + set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error-code> /// Equivalent to the SO_KEEPALIVE socket option. /// /// # Typical errors /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - keep-alive: func(this: tcp-socket) -> result - set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error> + keep-alive: func(this: tcp-socket) -> result + set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error-code> /// Equivalent to the TCP_NODELAY socket option. /// /// # Typical errors /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - no-delay: func(this: tcp-socket) -> result - set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error> + no-delay: func(this: tcp-socket) -> result + set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error-code> /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// @@ -176,8 +176,8 @@ default interface tcp { /// - `already-connected`: (set) The socket is already in the Connection state. /// - `already-listening`: (set) The socket is already in the Listener state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - unicast-hop-limit: func(this: tcp-socket) -> result - set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error> + unicast-hop-limit: func(this: tcp-socket) -> result + set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error-code> /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -194,10 +194,10 @@ default interface tcp { /// - `already-connected`: (set) The socket is already in the Connection state. /// - `already-listening`: (set) The socket is already in the Listener state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - receive-buffer-size: func(this: tcp-socket) -> result - set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error> - send-buffer-size: func(this: tcp-socket) -> result - set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error> + receive-buffer-size: func(this: tcp-socket) -> result + set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> + send-buffer-size: func(this: tcp-socket) -> result + set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> /// Get/set the blocking mode of the socket. /// @@ -210,8 +210,8 @@ default interface tcp { /// /// # Typical errors /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - non-blocking: func(this: tcp-socket) -> result - set-non-blocking: func(this: tcp-socket, value: bool) -> result<_, error> + non-blocking: func(this: tcp-socket) -> result + set-non-blocking: func(this: tcp-socket, value: bool) -> result<_, error-code> /// Create a `pollable` which will resolve once the socket is ready for I/O. /// @@ -238,7 +238,7 @@ default interface tcp { /// - /// - /// - - shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error> + shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error-code> /// Dispose of the specified `tcp-socket`, after which it may no longer be used. /// diff --git a/proposals/sockets/wit/udp-create-socket.wit b/proposals/sockets/wit/udp-create-socket.wit index 404722e01..ec44567da 100644 --- a/proposals/sockets/wit/udp-create-socket.wit +++ b/proposals/sockets/wit/udp-create-socket.wit @@ -1,6 +1,6 @@ default interface udp-create-socket { - use pkg.network.{network, error, ip-address-family} + use pkg.network.{network, error-code, ip-address-family} use pkg.udp.{udp-socket} /// Create a new UDP socket. @@ -18,5 +18,5 @@ default interface udp-create-socket { /// # References: /// - /// - - create-udp-socket: func(address-family: ip-address-family) -> result + create-udp-socket: func(address-family: ip-address-family) -> result } diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 2edf5b154..e48271486 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,7 +1,7 @@ default interface udp { use poll.poll.{pollable} - use pkg.network.{network, error, ip-socket-address, ip-address-family} + use pkg.network.{network, error-code, ip-socket-address, ip-address-family} /// A UDP socket handle. @@ -43,7 +43,7 @@ default interface udp { /// - /// - /// - - bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error> + bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> /// Set the destination address. /// @@ -68,7 +68,7 @@ default interface udp { /// - /// - /// - - connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error> + connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> /// Receive a message. /// @@ -88,7 +88,7 @@ default interface udp { /// - /// - /// - - receive: func(this: udp-socket) -> result + receive: func(this: udp-socket) -> result /// Send a message to a specific destination address. /// @@ -112,7 +112,7 @@ default interface udp { /// - /// - /// - - send: func(this: udp-socket, datagram: datagram) -> result<_, error> + send: func(this: udp-socket, datagram: datagram) -> result<_, error-code> /// Get the current bound address. /// @@ -124,7 +124,7 @@ default interface udp { /// - /// - /// - - local-address: func(this: udp-socket) -> result + local-address: func(this: udp-socket) -> result /// Get the address set with `connect`. /// @@ -136,12 +136,12 @@ default interface udp { /// - /// - /// - - remote-address: func(this: udp-socket) -> result + remote-address: func(this: udp-socket) -> result /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: udp-socket) -> result + address-family: func(this: udp-socket) -> result /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. /// @@ -152,15 +152,15 @@ default interface udp { /// - `already-bound`: (set) The socket is already bound. /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - ipv6-only: func(this: udp-socket) -> result - set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error> + ipv6-only: func(this: udp-socket) -> result + set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error-code> /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// /// # Typical errors /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - unicast-hop-limit: func(this: udp-socket) -> result - set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error> + unicast-hop-limit: func(this: udp-socket) -> result + set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error-code> /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -177,10 +177,10 @@ default interface udp { /// /// # Typical errors /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - receive-buffer-size: func(this: udp-socket) -> result - set-receive-buffer-size: func(this: udp-socket, value: u64) -> result<_, error> - send-buffer-size: func(this: udp-socket) -> result - set-send-buffer-size: func(this: udp-socket, value: u64) -> result<_, error> + receive-buffer-size: func(this: udp-socket) -> result + set-receive-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> + send-buffer-size: func(this: udp-socket) -> result + set-send-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> /// Get/set the blocking mode of the socket. /// @@ -193,8 +193,8 @@ default interface udp { /// /// # Typical errors /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - non-blocking: func(this: udp-socket) -> result - set-non-blocking: func(this: udp-socket, value: bool) -> result<_, error> + non-blocking: func(this: udp-socket) -> result + set-non-blocking: func(this: udp-socket, value: bool) -> result<_, error-code> /// Create a `pollable` which will resolve once the socket is ready for I/O. /// From 6215339a984862e804e63a316021cd3a5703e7d3 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 26 Feb 2023 22:26:23 +0100 Subject: [PATCH 1080/1772] Document the error-code enum cases themselvees. --- proposals/sockets/example-world.md | 35 ++++++++++++++++--- proposals/sockets/wit/network.wit | 55 +++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 5 deletions(-) diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index 11c7a3410..4ed13351e 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -102,94 +102,121 @@ combined with a couple of errors that are always possible:

  • access-denied

    -

    POSIX equivalent: EACCES, EPERM +

    Access denied. +

    POSIX equivalent: EACCES, EPERM

  • not-supported

    -

    POSIX equivalent: EOPNOTSUPP +

    The operation is not supported. +

    POSIX equivalent: EOPNOTSUPP

  • resource-limit-reached

    -

    POSIX equivalent: EMFILE, ENFILE, ENOMEM, ENOBUFS, EAI_MEMORY +

    Resource limit reached.

  • out-of-memory

    -

    POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY +

    Not enough memory to complete the operation. +

    POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY

  • timeout

    +

    The operation timed out before it could finish completely.

  • concurrency-conflict

    +

    This operation is incompatible with another asynchronous operation that is already in progress.

  • address-family-not-supported

    +

    The specified address-family is not supported.

  • address-family-mismatch

    +

    An IPv4 address was passed to an IPv6 resource, or vice versa.

  • invalid-remote-address

    +

    The socket address is not a valid remote address. E.g. the IP address is set to INADDR_ANY, or the port is set to 0.

  • ipv4-only-operation

    +

    The operation is only supported on IPv4 resources.

  • ipv6-only-operation

    +

    The operation is only supported on IPv6 resources.

  • already-attached

    +

    The socket is already attached to another network.

  • already-bound

    +

    The socket is already bound.

  • already-connected

    +

    The socket is already in the Connection state.

  • not-bound

    +

    The socket is not bound to any local address.

  • not-connected

    +

    The socket is not in the Connection state.

  • address-not-bindable

    +

    A bind operation failed because the provided address is not an address that the `network` can bind to.

  • address-in-use

    +

    A bind operation failed because the provided address is already in use.

  • ephemeral-ports-exhausted

    +

    A bind operation failed because there are no ephemeral ports available.

  • remote-unreachable

    +

    The remote address is not reachable

  • already-listening

    +

    The socket is already in the Listener state.

  • not-listening

    +

    The socket is already in the Listener state.

  • connection-refused

    +

    The connection was forcefully rejected

  • connection-reset

    +

    The connection was reset.

  • datagram-too-large

  • invalid-name

    +

    The provided name is a syntactically invalid domain name.

  • name-unresolvable

    +

    Name does not exist or has no suitable associated IP addresses.

  • temporary-resolver-failure

    +

    A temporary failure in name resolution occurred.

  • permanent-resolver-failure

    +

    A permanent failure in name resolution occurred.


  • diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 09509dd92..543976a65 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -31,47 +31,92 @@ default interface network { /// Unknown error unknown, + /// Access denied. + /// /// POSIX equivalent: EACCES, EPERM access-denied, + /// The operation is not supported. + /// /// POSIX equivalent: EOPNOTSUPP not-supported, - /// POSIX equivalent: EMFILE, ENFILE, ENOMEM, ENOBUFS, EAI_MEMORY + /// Resource limit reached. resource-limit-reached, + /// Not enough memory to complete the operation. + /// /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY out-of-memory, + /// The operation timed out before it could finish completely. timeout, + + /// This operation is incompatible with another asynchronous operation that is already in progress. concurrency-conflict, // ### IP ERRORS ### + + /// The specified address-family is not supported. address-family-not-supported, + + /// An IPv4 address was passed to an IPv6 resource, or vice versa. address-family-mismatch, + + /// The socket address is not a valid remote address. E.g. the IP address is set to INADDR_ANY, or the port is set to 0. invalid-remote-address, + + /// The operation is only supported on IPv4 resources. ipv4-only-operation, + + /// The operation is only supported on IPv6 resources. ipv6-only-operation, // ### TCP & UDP SOCKET ERRORS ### + + /// The socket is already attached to another network. already-attached, + + /// The socket is already bound. already-bound, + + /// The socket is already in the Connection state. already-connected, + + /// The socket is not bound to any local address. not-bound, + + /// The socket is not in the Connection state. not-connected, + + /// A bind operation failed because the provided address is not an address that the `network` can bind to. address-not-bindable, + + /// A bind operation failed because the provided address is already in use. address-in-use, + + /// A bind operation failed because there are no ephemeral ports available. ephemeral-ports-exhausted, + + /// The remote address is not reachable remote-unreachable, // ### TCP SOCKET ERRORS ### + + /// The socket is already in the Listener state. already-listening, + + /// The socket is already in the Listener state. not-listening, + + /// The connection was forcefully rejected connection-refused, + + /// The connection was reset. connection-reset, @@ -80,9 +125,17 @@ default interface network { // ### NAME LOOKUP ERRORS ### + + /// The provided name is a syntactically invalid domain name. invalid-name, + + /// Name does not exist or has no suitable associated IP addresses. name-unresolvable, + + /// A temporary failure in name resolution occurred. temporary-resolver-failure, + + /// A permanent failure in name resolution occurred. permanent-resolver-failure, } From c51a5320cf75abd265e696a7e179520dda6f7543 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 28 Feb 2023 10:20:12 -0800 Subject: [PATCH 1081/1772] Remove the spurious second argument in `append-via-stream`. (#110) Remove the spurious second argument in `append-via-stream`, which is an oversight from the conversion from resources to standalone functions. I meant to do this in #100 but apparently lost that part of the diff. This PR reinstatates it. --- proposals/filesystem/example-world.md | 1 - proposals/filesystem/wit/filesystem.wit | 2 -- 2 files changed, 3 deletions(-) diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md index c57bba06a..b6355f2a2 100644 --- a/proposals/filesystem/example-world.md +++ b/proposals/filesystem/example-world.md @@ -784,7 +784,6 @@ POSIX.

    Params
    Return values
      diff --git a/proposals/filesystem/wit/filesystem.wit b/proposals/filesystem/wit/filesystem.wit index fafd4b96f..90985e27e 100644 --- a/proposals/filesystem/wit/filesystem.wit +++ b/proposals/filesystem/wit/filesystem.wit @@ -331,8 +331,6 @@ default interface filesystem { /// `O_APPEND` in in POSIX. append-via-stream: func( this: descriptor, - /// The resource to operate on. - fd: descriptor, ) -> result /// Provide file advisory information on a descriptor. From ba5b5e0b4c3682981b1a07d741b8d48abc79e4d0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 28 Feb 2023 10:21:58 -0800 Subject: [PATCH 1082/1772] Update wasi-filesystem. Update wasi-filesystem to pull in WebAssembly/wasi-filesystem#110. --- proposals/cli/cli.md | 1 - proposals/cli/wit/deps/filesystem/filesystem.wit | 2 -- 2 files changed, 3 deletions(-) diff --git a/proposals/cli/cli.md b/proposals/cli/cli.md index 4e5bc36d1..a5e5232cb 100644 --- a/proposals/cli/cli.md +++ b/proposals/cli/cli.md @@ -986,7 +986,6 @@ POSIX.

      Params
      Return values
        diff --git a/proposals/cli/wit/deps/filesystem/filesystem.wit b/proposals/cli/wit/deps/filesystem/filesystem.wit index fafd4b96f..90985e27e 100644 --- a/proposals/cli/wit/deps/filesystem/filesystem.wit +++ b/proposals/cli/wit/deps/filesystem/filesystem.wit @@ -331,8 +331,6 @@ default interface filesystem { /// `O_APPEND` in in POSIX. append-via-stream: func( this: descriptor, - /// The resource to operate on. - fd: descriptor, ) -> result /// Provide file advisory information on a descriptor. From 2c589c9e4dc4eb1bf011cf976b6ea5fec1214d04 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Feb 2023 15:09:05 -0800 Subject: [PATCH 1083/1772] Add wasi-sockets. This uses the wit files from [wasi-sockets]. [wasi-sockets]: https://github.com/WebAssembly/wasi-sockets --- proposals/cli/cli.md | 1002 ++++++++++++++++- proposals/cli/wit/cli.wit | 7 + .../cli/wit/deps/sockets/instance-network.wit | 9 + .../cli/wit/deps/sockets/ip-name-lookup.wit | 71 ++ proposals/cli/wit/deps/sockets/network.wit | 56 + .../wit/deps/sockets/tcp-create-socket.wit | 19 + proposals/cli/wit/deps/sockets/tcp.wit | 188 ++++ .../wit/deps/sockets/udp-create-socket.wit | 19 + proposals/cli/wit/deps/sockets/udp.wit | 162 +++ 9 files changed, 1531 insertions(+), 2 deletions(-) create mode 100644 proposals/cli/wit/deps/sockets/instance-network.wit create mode 100644 proposals/cli/wit/deps/sockets/ip-name-lookup.wit create mode 100644 proposals/cli/wit/deps/sockets/network.wit create mode 100644 proposals/cli/wit/deps/sockets/tcp-create-socket.wit create mode 100644 proposals/cli/wit/deps/sockets/tcp.wit create mode 100644 proposals/cli/wit/deps/sockets/udp-create-socket.wit create mode 100644 proposals/cli/wit/deps/sockets/udp.wit diff --git a/proposals/cli/cli.md b/proposals/cli/cli.md index a5e5232cb..252c4fe67 100644 --- a/proposals/cli/cli.md +++ b/proposals/cli/cli.md @@ -10,6 +10,13 @@
      • interface timezone
      • interface streams
      • interface filesystem
      • +
      • interface network
      • +
      • interface instance-network
      • +
      • interface ip-name-lookup
      • +
      • interface tcp
      • +
      • interface tcp-create-socket
      • +
      • interface udp
      • +
      • interface udp-create-socket
      • interface random
      • interface environment
      • interface environment-preopens
      • @@ -807,7 +814,7 @@ implementations which can set this to a non-none value should do so.

        Write mode: Data can be written to.

      • -

        non-blocking:

        +

        non-blocking:

        Requests non-blocking operation.

        When this flag is enabled, functions may return immediately with an error-code::would-block error code in situations where they would @@ -1049,7 +1056,7 @@ from fdstat_get in earlier versions of WASI.

      set-flags: func

      Set status flags associated with a descriptor.

      -

      This function may only change the non-blocking flag.

      +

      This function may only change the non-blocking flag.

      Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

      Note: This was called fd_fdstat_set_flags in earlier versions of WASI.

      Params
      @@ -1484,6 +1491,997 @@ be used.

      +

      Import interface network

      +
      +

      Types

      +

      type network

      +

      u32

      +

      An opaque resource that represents access to (a subset of) the network. +This enables context-based security for networking. +There is no need for this to map 1:1 to a physical network interface. +

      FYI, In the future this will be replaced by handle types.

      +

      tuple ipv6-address

      +
      Tuple Fields
      +
        +
      • 0: u16
      • +
      • 1: u16
      • +
      • 2: u16
      • +
      • 3: u16
      • +
      • 4: u16
      • +
      • 5: u16
      • +
      • 6: u16
      • +
      • 7: u16
      • +
      +

      record ipv6-socket-address

      +
      Record Fields
      + +

      tuple ipv4-address

      +
      Tuple Fields
      +
        +
      • 0: u8
      • +
      • 1: u8
      • +
      • 2: u8
      • +
      • 3: u8
      • +
      +

      record ipv4-socket-address

      +
      Record Fields
      + +

      variant ip-socket-address

      +
      Variant Cases
      + +

      enum ip-address-family

      +
      Enum Cases
      +
        +
      • +

        ipv4

        +

        Similar to `AF_INET` in POSIX. +

      • +
      • +

        ipv6

        +

        Similar to `AF_INET6` in POSIX. +

      • +
      +

      variant ip-address

      +
      Variant Cases
      + +

      enum error

      +
      Enum Cases
      + +
      +

      Functions

      +

      drop-network: func

      +

      Dispose of the specified network, after which it may no longer be used.

      +

      Note: this function is scheduled to be removed when Resources are natively supported in Wit.

      +
      Params
      + +

      Import interface instance-network

      +

      This interface provides a value-export of the default network handle..

      +
      +

      Types

      +

      type network

      +

      network

      +

      +---- +

      Functions

      +

      instance-network: func

      +

      Get a handle to the default network.

      +
      Return values
      + +

      Import interface ip-name-lookup

      +
      +

      Types

      +

      type pollable

      +

      pollable

      +

      +#### `type network` +[`network`](#network) +

      +#### `type error` +[`error`](#error) +

      +#### `type ip-address` +[`ip-address`](#ip_address) +

      +#### `type ip-address-family` +[`ip-address-family`](#ip_address_family) +

      +#### `type resolve-address-stream` +`u32` +

      +---- +

      Functions

      +

      resolve-addresses: func

      +

      Resolve an internet host name to a list of IP addresses.

      +

      See the wasi-socket proposal README.md for a comparison with getaddrinfo.

      +

      Parameters:

      +
        +
      • name: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted +to ASCII using IDNA encoding.
      • +
      • address-family: If provided, limit the results to addresses of this specific address family.
      • +
      • include-unavailable: When set to true, this function will also return addresses of which the runtime +thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on +systems without an active IPv6 interface. Notes:
      • +
      • Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address.
      • +
      • Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged.
      • +
      +

      This function never blocks. It either immediately returns successfully with a resolve-address-stream +that can be used to (asynchronously) fetch the results. +Or it immediately fails whenever name is:

      +
        +
      • empty
      • +
      • an IP address
      • +
      • a syntactically invalid domain name in another way
      • +
      +

      References:

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html
      • +
      • https://man7.org/linux/man-pages/man3/getaddrinfo.3.html
      • +
      +
      Params
      + +
      Return values
      + +

      resolve-next-address: func

      +

      Returns the next address from the resolver.

      +

      This function should be called multiple times. On each call, it will +return the next address in connection order preference. If all +addresses have been exhausted, this function returns none. +After which, you should release the stream with drop-resolve-address-stream.

      +

      This function never returns IPv4-mapped IPv6 addresses.

      +
      Params
      + +
      Return values
      + +

      drop-resolve-address-stream: func

      +

      Dispose of the specified resolve-address-stream, after which it may no longer be used.

      +

      Note: this function is scheduled to be removed when Resources are natively supported in Wit.

      +
      Params
      + +

      non-blocking: func

      +

      Get/set the blocking mode of the stream.

      +

      By default a stream is in "blocking" mode, meaning that any function blocks and waits for its completion. +When switched to "non-blocking" mode, operations that would block return an again error. After which +the API consumer is expected to call subscribe and wait for completion using the wasi-poll module.

      +

      Note: these functions are here for WASI Preview2 only. +They're planned to be removed when future is natively supported in Preview3.

      +
      Params
      + +
      Return values
      + +

      set-non-blocking: func

      +
      Params
      + +
      Return values
      + +

      subscribe: func

      +

      Create a pollable which will resolve once the stream is ready for I/O.

      +

      Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

      +
      Params
      + +
      Return values
      + +

      Import interface tcp

      +
      +

      Types

      +

      type input-stream

      +

      input-stream

      +

      +#### `type output-stream` +[`output-stream`](#output_stream) +

      +#### `type pollable` +[`pollable`](#pollable) +

      +#### `type network` +[`network`](#network) +

      +#### `type error` +[`error`](#error) +

      +#### `type ip-socket-address` +[`ip-socket-address`](#ip_socket_address) +

      +#### `type ip-address-family` +[`ip-address-family`](#ip_address_family) +

      +#### `type tcp-socket` +`u32` +

      A TCP socket handle. +

      enum shutdown-type

      +
      Enum Cases
      +
        +
      • +

        receive

        +

        Similar to `SHUT_RD` in POSIX. +

      • +
      • +

        send

        +

        Similar to `SHUT_WR` in POSIX. +

      • +
      • +

        both

        +

        Similar to `SHUT_RDWR` in POSIX. +

      • +
      +
      +

      Functions

      +

      bind: func

      +

      Bind the socket to a specific network on the provided IP address and port.

      +

      If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which +network interface(s) to bind to. +If the TCP/UDP port is zero, the socket will be bound to a random free port.

      +

      When a socket is not explicitly bound, the first invocation to a listen or connect operation will +implicitly bind the socket.

      +

      Fails when:

      +
        +
      • the socket is already bound.
      • +
      +

      References

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
      • +
      • https://man7.org/linux/man-pages/man2/bind.2.html
      • +
      +
      Params
      + +
      Return values
      + +

      connect: func

      +

      Connect to a remote endpoint.

      +

      On success:

      +
        +
      • the socket is transitioned into the Connection state
      • +
      • a pair of streams is returned that can be used to read & write to the connection
      • +
      +

      Fails when:

      +
        +
      • the socket is already bound to a different network.
      • +
      • the provided network does not allow connections to the specified endpoint.
      • +
      • the socket is already in the Connection or Listener state.
      • +
      • either the remote IP address or port is 0.
      • +
      +

      References

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
      • +
      • https://man7.org/linux/man-pages/man2/connect.2.html
      • +
      +
      Params
      + +
      Return values
      + +

      listen: func

      +

      Start listening for new connections.

      +

      Transitions the socket into the Listener state.

      +

      Fails when:

      +
        +
      • the socket is already bound to a different network.
      • +
      • the provided network does not allow listening on the specified address.
      • +
      • the socket is already in the Connection or Listener state.
      • +
      +

      References

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html
      • +
      • https://man7.org/linux/man-pages/man2/listen.2.html
      • +
      +
      Params
      + +
      Return values
      + +

      accept: func

      +

      Accept a new client socket.

      +

      The returned socket is bound and in the Connection state.

      +

      On success, this function returns the newly accepted client socket along with +a pair of streams that can be used to read & write to the connection.

      +

      Fails when this socket is not in the Listening state.

      +

      References:

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html
      • +
      • https://man7.org/linux/man-pages/man2/accept.2.html
      • +
      +
      Params
      + +
      Return values
      + +

      local-address: func

      +

      Get the bound local address.

      +

      Returns an error if the socket is not bound.

      +

      References

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html
      • +
      • https://man7.org/linux/man-pages/man2/getsockname.2.html
      • +
      +
      Params
      + +
      Return values
      + +

      remote-address: func

      +

      Get the bound remote address.

      +

      Fails when the socket is not in the Connection state.

      +

      References

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html
      • +
      • https://man7.org/linux/man-pages/man2/getpeername.2.html
      • +
      +
      Params
      + +
      Return values
      + +

      address-family: func

      +

      Whether this is a IPv4 or IPv6 socket.

      +

      Equivalent to the SO_DOMAIN socket option.

      +
      Params
      + +
      Return values
      + +

      ipv6-only: func

      +

      Whether IPv4 compatibility (dual-stack) mode is disabled or not. +Implementations are not required to support dual-stack mode. Calling set-ipv6-only(false) might fail.

      +

      Fails when called on an IPv4 socket.

      +

      Equivalent to the IPV6_V6ONLY socket option.

      +
      Params
      + +
      Return values
      + +

      set-ipv6-only: func

      +
      Params
      + +
      Return values
      + +

      set-listen-backlog-size: func

      +

      Hints the desired listen queue size. Implementations are free to ignore this.

      +
      Params
      + +
      Return values
      + +

      keep-alive: func

      +

      Equivalent to the SO_KEEPALIVE socket option.

      +
      Params
      + +
      Return values
      + +

      set-keep-alive: func

      +
      Params
      + +
      Return values
      + +

      no-delay: func

      +

      Equivalent to the TCP_NODELAY socket option.

      +
      Params
      + +
      Return values
      + +

      set-no-delay: func

      +
      Params
      + +
      Return values
      + +

      unicast-hop-limit: func

      +

      Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

      +
      Params
      + +
      Return values
      + +

      set-unicast-hop-limit: func

      +
      Params
      + +
      Return values
      + +

      receive-buffer-size: func

      +

      The kernel buffer space reserved for sends/receives on this socket.

      +

      Note #1: an implementation may choose to cap or round the buffer size when setting the value. +In other words, after setting a value, reading the same setting back may return a different value.

      +

      Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of +actual data to be sent/received by the application, because the kernel might also use the buffer space +for internal metadata structures.

      +

      Fails when this socket is in the Listening state.

      +

      Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

      +
      Params
      + +
      Return values
      + +

      set-receive-buffer-size: func

      +
      Params
      + +
      Return values
      + +

      send-buffer-size: func

      +
      Params
      + +
      Return values
      + +

      set-send-buffer-size: func

      +
      Params
      + +
      Return values
      + +

      non-blocking: func

      +

      Get/set the blocking mode of the socket.

      +

      By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. +When switched to "non-blocking" mode, operations that would block return an again error. After which +the API consumer is expected to call subscribe and wait for completion using the wasi-poll module.

      +

      Note: these functions are here for WASI Preview2 only. +They're planned to be removed when future is natively supported in Preview3.

      +
      Params
      + +
      Return values
      + +

      set-non-blocking: func

      +
      Params
      + +
      Return values
      + +

      subscribe: func

      +

      Create a pollable which will resolve once the socket is ready for I/O.

      +

      Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

      +
      Params
      + +
      Return values
      + +

      shutdown: func

      +

      Gracefully shut down the connection.

      +
        +
      • receive: the socket is not expecting to receive any more data from the peer. All subsequent read +operations on the input-stream associated with this socket will return an End Of Stream indication. +Any data still in the receive queue at time of calling shutdown will be discarded.
      • +
      • send: the socket is not expecting to send any more data to the peer. All subsequent write +operations on the output-stream associated with this socket will return an error.
      • +
      • both: same effect as receive & send combined.
      • +
      +

      The shutdown function does not close the socket.

      +

      Fails when the socket is not in the Connection state.

      +

      References

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html
      • +
      • https://man7.org/linux/man-pages/man2/shutdown.2.html
      • +
      +
      Params
      + +
      Return values
      + +

      drop-tcp-socket: func

      +

      Dispose of the specified tcp-socket, after which it may no longer be used.

      +

      Note: this function is scheduled to be removed when Resources are natively supported in Wit.

      +
      Params
      + +

      Import interface tcp-create-socket

      +
      +

      Types

      +

      type network

      +

      network

      +

      +#### `type error` +[`error`](#error) +

      +#### `type ip-address-family` +[`ip-address-family`](#ip_address_family) +

      +#### `type tcp-socket` +[`tcp-socket`](#tcp_socket) +

      +---- +

      Functions

      +

      create-tcp-socket: func

      +

      Create a new TCP socket.

      +

      Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX.

      +

      This function does not require a network capability handle. This is considered to be safe because +at time of creation, the socket is not bound to any network yet. Up to the moment bind/listen/connect +is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

      +

      References:

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html
      • +
      • https://man7.org/linux/man-pages/man2/socket.2.html
      • +
      +
      Params
      + +
      Return values
      + +

      Import interface udp

      +
      +

      Types

      +

      type pollable

      +

      pollable

      +

      +#### `type network` +[`network`](#network) +

      +#### `type error` +[`error`](#error) +

      +#### `type ip-socket-address` +[`ip-socket-address`](#ip_socket_address) +

      +#### `type ip-address-family` +[`ip-address-family`](#ip_address_family) +

      +#### `type udp-socket` +`u32` +

      A UDP socket handle. +

      record datagram

      +
      Record Fields
      + +
      +

      Functions

      +

      bind: func

      +

      Bind the socket to a specific network on the provided IP address and port.

      +

      If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which +network interface(s) to bind to. +If the TCP/UDP port is zero, the socket will be bound to a random free port.

      +

      When a socket is not explicitly bound, the first invocation to a connect, send or receive operation will +implicitly bind the socket.

      +

      Fails when:

      +
        +
      • the socket is already bound.
      • +
      +

      References

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
      • +
      • https://man7.org/linux/man-pages/man2/bind.2.html
      • +
      +
      Params
      + +
      Return values
      + +

      connect: func

      +

      Set the destination address.

      +

      The local-address is updated based on the best network path to remote-address.

      +

      When a destination address is set:

      +
        +
      • all receive operations will only return datagrams sent from the provided remote-address.
      • +
      • the send function can only be used to send to this destination.
      • +
      +

      Note that this function does not generate any network traffic and the peer is not aware of this "connection".

      +

      Fails when:

      +
        +
      • the socket is already bound to a different network.
      • +
      +

      References

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
      • +
      • https://man7.org/linux/man-pages/man2/connect.2.html
      • +
      +
      Params
      + +
      Return values
      + +

      receive: func

      +

      Receive a message.

      +

      Returns:

      +
        +
      • The sender address of the datagram
      • +
      • The number of bytes read.
      • +
      +

      Fails when:

      +
        +
      • the socket is not bound.
      • +
      +

      References

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html
      • +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html
      • +
      • https://man7.org/linux/man-pages/man2/recv.2.html
      • +
      +
      Params
      + +
      Return values
      + +

      send: func

      +

      Send a message to a specific destination address.

      +

      The remote address option is required. To send a message to the "connected" peer, +call remote-address to get their address.

      +

      Fails when:

      +
        +
      • the socket is not bound. Unlike POSIX, this function does not perform an implicit bind.
      • +
      • the socket is in "connected" mode and the datagram.remote-address does not match the address passed to connect.
      • +
      +

      References

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html
      • +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html
      • +
      • https://man7.org/linux/man-pages/man2/send.2.html
      • +
      +
      Params
      + +
      Return values
      + +

      local-address: func

      +

      Get the current bound address.

      +

      Returns an error if the socket is not bound.

      +

      References

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html
      • +
      • https://man7.org/linux/man-pages/man2/getsockname.2.html
      • +
      +
      Params
      + +
      Return values
      + +

      remote-address: func

      +

      Get the address set with connect.

      +

      References

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html
      • +
      • https://man7.org/linux/man-pages/man2/getpeername.2.html
      • +
      +
      Params
      + +
      Return values
      + +

      address-family: func

      +

      Whether this is a IPv4 or IPv6 socket.

      +

      Equivalent to the SO_DOMAIN socket option.

      +
      Params
      + +
      Return values
      + +

      ipv6-only: func

      +

      Whether IPv4 compatibility (dual-stack) mode is disabled or not. +Implementations are not required to support dual-stack mode, so calling set-ipv6-only(false) might fail.

      +

      Fails when called on an IPv4 socket.

      +

      Equivalent to the IPV6_V6ONLY socket option.

      +
      Params
      + +
      Return values
      + +

      set-ipv6-only: func

      +
      Params
      + +
      Return values
      + +

      unicast-hop-limit: func

      +

      Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

      +
      Params
      + +
      Return values
      + +

      set-unicast-hop-limit: func

      +
      Params
      + +
      Return values
      + +

      receive-buffer-size: func

      +

      The kernel buffer space reserved for sends/receives on this socket.

      +

      Note #1: an implementation may choose to cap or round the buffer size when setting the value. +In other words, after setting a value, reading the same setting back may return a different value.

      +

      Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of +actual data to be sent/received by the application, because the kernel might also use the buffer space +for internal metadata structures.

      +

      Fails when this socket is in the Listening state.

      +

      Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

      +
      Params
      + +
      Return values
      + +

      set-receive-buffer-size: func

      +
      Params
      + +
      Return values
      + +

      send-buffer-size: func

      +
      Params
      + +
      Return values
      + +

      set-send-buffer-size: func

      +
      Params
      + +
      Return values
      + +

      non-blocking: func

      +

      Get/set the blocking mode of the socket.

      +

      By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. +When switched to "non-blocking" mode, operations that would block return an again error. After which +the API consumer is expected to call subscribe and wait for completion using the wasi-poll module.

      +

      Note: these functions are here for WASI Preview2 only. +They're planned to be removed when future is natively supported in Preview3.

      +
      Params
      + +
      Return values
      + +

      set-non-blocking: func

      +
      Params
      + +
      Return values
      + +

      subscribe: func

      +

      Create a pollable which will resolve once the socket is ready for I/O.

      +

      Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

      +
      Params
      + +
      Return values
      + +

      drop-udp-socket: func

      +

      Dispose of the specified udp-socket, after which it may no longer be used.

      +

      Note: this function is scheduled to be removed when Resources are natively supported in Wit.

      +
      Params
      + +

      Import interface udp-create-socket

      +
      +

      Types

      +

      type network

      +

      network

      +

      +#### `type error` +[`error`](#error) +

      +#### `type ip-address-family` +[`ip-address-family`](#ip_address_family) +

      +#### `type udp-socket` +[`udp-socket`](#udp_socket) +

      +---- +

      Functions

      +

      create-udp-socket: func

      +

      Create a new UDP socket.

      +

      Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.

      +

      This function does not require a network capability handle. This is considered to be safe because +at time of creation, the socket is not bound to any network yet. Up to the moment bind/connect is called, +the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

      +

      References:

      +
        +
      • https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html
      • +
      • https://man7.org/linux/man-pages/man2/socket.2.html
      • +
      +
      Params
      + +
      Return values
      +

      Import interface random

      WASI Random is a random data API.

      It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/cli.wit b/proposals/cli/wit/cli.wit index 4a4ad1f6e..78b654b2c 100644 --- a/proposals/cli/wit/cli.wit +++ b/proposals/cli/wit/cli.wit @@ -5,6 +5,13 @@ default world cli { import instance-monotonic-clock: clocks.instance-monotonic-clock import timezone: clocks.timezone import filesystem: filesystem.filesystem + import instance-network: sockets.instance-network + import ip-name-lookup: sockets.ip-name-lookup + import network: sockets.network + import tcp-create-socket: sockets.tcp-create-socket + import tcp: sockets.tcp + import udp-create-socket: sockets.udp-create-socket + import udp: sockets.udp import random: random.random import poll: poll.poll import streams: io.streams diff --git a/proposals/cli/wit/deps/sockets/instance-network.wit b/proposals/cli/wit/deps/sockets/instance-network.wit new file mode 100644 index 000000000..b1f5c982d --- /dev/null +++ b/proposals/cli/wit/deps/sockets/instance-network.wit @@ -0,0 +1,9 @@ + +/// This interface provides a value-export of the default network handle.. +default interface instance-network { + use pkg.network.{network} + + /// Get a handle to the default network. + instance-network: func() -> network + +} diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit new file mode 100644 index 000000000..b594598e0 --- /dev/null +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -0,0 +1,71 @@ + +default interface ip-name-lookup { + use poll.poll.{pollable} + use pkg.network.{network, error, ip-address, ip-address-family} + + + /// Resolve an internet host name to a list of IP addresses. + /// + /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. + /// + /// Parameters: + /// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted + /// to ASCII using IDNA encoding. + /// - `address-family`: If provided, limit the results to addresses of this specific address family. + /// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime + /// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on + /// systems without an active IPv6 interface. Notes: + /// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. + /// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. + /// + /// This function never blocks. It either immediately returns successfully with a `resolve-address-stream` + /// that can be used to (asynchronously) fetch the results. + /// Or it immediately fails whenever `name` is: + /// - empty + /// - an IP address + /// - a syntactically invalid domain name in another way + /// + /// References: + /// - + /// - + /// + resolve-addresses: func(network: network, name: string, address-family: option, include-unavailable: bool) -> result + + + + type resolve-address-stream = u32 + + /// Returns the next address from the resolver. + /// + /// This function should be called multiple times. On each call, it will + /// return the next address in connection order preference. If all + /// addresses have been exhausted, this function returns `none`. + /// After which, you should release the stream with `drop-resolve-address-stream`. + /// + /// This function never returns IPv4-mapped IPv6 addresses. + resolve-next-address: func(this: resolve-address-stream) -> result, error> + + + + /// Dispose of the specified `resolve-address-stream`, after which it may no longer be used. + /// + /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. + drop-resolve-address-stream: func(this: resolve-address-stream) + + /// Get/set the blocking mode of the stream. + /// + /// By default a stream is in "blocking" mode, meaning that any function blocks and waits for its completion. + /// When switched to "non-blocking" mode, operations that would block return an `again` error. After which + /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. + /// + /// Note: these functions are here for WASI Preview2 only. + /// They're planned to be removed when `future` is natively supported in Preview3. + non-blocking: func(this: resolve-address-stream) -> result + set-non-blocking: func(this: resolve-address-stream, value: bool) -> result<_, error> + + /// Create a `pollable` which will resolve once the stream is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func(this: resolve-address-stream) -> pollable +} diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit new file mode 100644 index 000000000..1f3a20d6b --- /dev/null +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -0,0 +1,56 @@ + +default interface network { + /// An opaque resource that represents access to (a subset of) the network. + /// This enables context-based security for networking. + /// There is no need for this to map 1:1 to a physical network interface. + /// + /// FYI, In the future this will be replaced by handle types. + type network = u32 + + /// Dispose of the specified `network`, after which it may no longer be used. + /// + /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. + drop-network: func(this: network) + + + + enum error { + unknown, + again, + // TODO ... + } + + enum ip-address-family { + /// Similar to `AF_INET` in POSIX. + ipv4, + + /// Similar to `AF_INET6` in POSIX. + ipv6, + } + + type ipv4-address = tuple + type ipv6-address = tuple + + variant ip-address { + ipv4(ipv4-address), + ipv6(ipv6-address), + } + + record ipv4-socket-address { + port: u16, // sin_port + address: ipv4-address, // sin_addr + } + + record ipv6-socket-address { + port: u16, // sin6_port + flow-info: u32, // sin6_flowinfo + address: ipv6-address, // sin6_addr + scope-id: u32, // sin6_scope_id + } + + variant ip-socket-address { + ipv4(ipv4-socket-address), + ipv6(ipv6-socket-address), + } + +} \ No newline at end of file diff --git a/proposals/cli/wit/deps/sockets/tcp-create-socket.wit b/proposals/cli/wit/deps/sockets/tcp-create-socket.wit new file mode 100644 index 000000000..571a0197a --- /dev/null +++ b/proposals/cli/wit/deps/sockets/tcp-create-socket.wit @@ -0,0 +1,19 @@ + +default interface tcp-create-socket { + use pkg.network.{network, error, ip-address-family} + use pkg.tcp.{tcp-socket} + + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` + /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// References: + /// - + /// - + /// + create-tcp-socket: func(address-family: ip-address-family) -> result +} diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit new file mode 100644 index 000000000..b2f483368 --- /dev/null +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -0,0 +1,188 @@ + +default interface tcp { + use io.streams.{input-stream, output-stream} + use poll.poll.{pollable} + use pkg.network.{network, error, ip-socket-address, ip-address-family} + + /// A TCP socket handle. + type tcp-socket = u32 + + + enum shutdown-type { + /// Similar to `SHUT_RD` in POSIX. + receive, + + /// Similar to `SHUT_WR` in POSIX. + send, + + /// Similar to `SHUT_RDWR` in POSIX. + both, + } + + + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will + /// implicitly bind the socket. + /// + /// Fails when: + /// - the socket is already bound. + /// + /// References + /// - + /// - + bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error> + + /// Connect to a remote endpoint. + /// + /// On success: + /// - the socket is transitioned into the Connection state + /// - a pair of streams is returned that can be used to read & write to the connection + /// + /// Fails when: + /// - the socket is already bound to a different network. + /// - the provided network does not allow connections to the specified endpoint. + /// - the socket is already in the Connection or Listener state. + /// - either the remote IP address or port is 0. + /// + /// References + /// - + /// - + connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result, error> + + /// Start listening for new connections. + /// + /// Transitions the socket into the Listener state. + /// + /// Fails when: + /// - the socket is already bound to a different network. + /// - the provided network does not allow listening on the specified address. + /// - the socket is already in the Connection or Listener state. + /// + /// References + /// - + /// - + listen: func(this: tcp-socket, network: network) -> result<_, error> + + /// Accept a new client socket. + /// + /// The returned socket is bound and in the Connection state. + /// + /// On success, this function returns the newly accepted client socket along with + /// a pair of streams that can be used to read & write to the connection. + /// + /// Fails when this socket is not in the Listening state. + /// + /// References: + /// - + /// - + accept: func(this: tcp-socket) -> result, error> + + /// Get the bound local address. + /// + /// Returns an error if the socket is not bound. + /// + /// References + /// - + /// - + local-address: func(this: tcp-socket) -> result + + /// Get the bound remote address. + /// + /// Fails when the socket is not in the Connection state. + /// + /// References + /// - + /// - + remote-address: func(this: tcp-socket) -> result + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func(this: tcp-socket) -> result + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// Implementations are not required to support dual-stack mode. Calling `set-ipv6-only(false)` might fail. + /// + /// Fails when called on an IPv4 socket. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + ipv6-only: func(this: tcp-socket) -> result + set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error> + + /// Hints the desired listen queue size. Implementations are free to ignore this. + set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error> + + /// Equivalent to the SO_KEEPALIVE socket option. + keep-alive: func(this: tcp-socket) -> result + set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error> + + /// Equivalent to the TCP_NODELAY socket option. + no-delay: func(this: tcp-socket) -> result + set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error> + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + unicast-hop-limit: func(this: tcp-socket) -> result + set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error> + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Fails when this socket is in the Listening state. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + receive-buffer-size: func(this: tcp-socket) -> result + set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error> + send-buffer-size: func(this: tcp-socket) -> result + set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error> + + /// Get/set the blocking mode of the socket. + /// + /// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. + /// When switched to "non-blocking" mode, operations that would block return an `again` error. After which + /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. + /// + /// Note: these functions are here for WASI Preview2 only. + /// They're planned to be removed when `future` is natively supported in Preview3. + non-blocking: func(this: tcp-socket) -> result + set-non-blocking: func(this: tcp-socket, value: bool) -> result<_, error> + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func(this: tcp-socket) -> pollable + + /// Gracefully shut down the connection. + /// + /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read + /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. + /// Any data still in the receive queue at time of calling `shutdown` will be discarded. + /// - send: the socket is not expecting to send any more data to the peer. All subsequent write + /// operations on the `output-stream` associated with this socket will return an error. + /// - both: same effect as receive & send combined. + /// + /// The shutdown function does not close the socket. + /// + /// Fails when the socket is not in the Connection state. + /// + /// References + /// - + /// - + shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error> + + /// Dispose of the specified `tcp-socket`, after which it may no longer be used. + /// + /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. + drop-tcp-socket: func(this: tcp-socket) +} diff --git a/proposals/cli/wit/deps/sockets/udp-create-socket.wit b/proposals/cli/wit/deps/sockets/udp-create-socket.wit new file mode 100644 index 000000000..169957c9f --- /dev/null +++ b/proposals/cli/wit/deps/sockets/udp-create-socket.wit @@ -0,0 +1,19 @@ + +default interface udp-create-socket { + use pkg.network.{network, error, ip-address-family} + use pkg.udp.{udp-socket} + + /// Create a new UDP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` is called, + /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// References: + /// - + /// - + /// + create-udp-socket: func(address-family: ip-address-family) -> result +} diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit new file mode 100644 index 000000000..af8f873b9 --- /dev/null +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -0,0 +1,162 @@ + +default interface udp { + use poll.poll.{pollable} + use pkg.network.{network, error, ip-socket-address, ip-address-family} + + + /// A UDP socket handle. + type udp-socket = u32 + + + record datagram { + data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. + remote-address: ip-socket-address, + + /// Possible future additions: + /// local-address: ip-socket-address, // IP_PKTINFO / IP_RECVDSTADDR / IPV6_PKTINFO + /// local-interface: u32, // IP_PKTINFO / IP_RECVIF + /// ttl: u8, // IP_RECVTTL + /// dscp: u6, // IP_RECVTOS + /// ecn: u2, // IP_RECVTOS + } + + + + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to a connect, send or receive operation will + /// implicitly bind the socket. + /// + /// Fails when: + /// - the socket is already bound. + /// + /// References + /// - + /// - + bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error> + + /// Set the destination address. + /// + /// The local-address is updated based on the best network path to `remote-address`. + /// + /// When a destination address is set: + /// - all receive operations will only return datagrams sent from the provided `remote-address`. + /// - the `send` function can only be used to send to this destination. + /// + /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". + /// + /// Fails when: + /// - the socket is already bound to a different network. + /// + /// References + /// - + /// - + connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error> + + /// Receive a message. + /// + /// Returns: + /// - The sender address of the datagram + /// - The number of bytes read. + /// + /// Fails when: + /// - the socket is not bound. + /// + /// References + /// - + /// - + /// - + receive: func(this: udp-socket) -> result + + /// Send a message to a specific destination address. + /// + /// The remote address option is required. To send a message to the "connected" peer, + /// call `remote-address` to get their address. + /// + /// Fails when: + /// - the socket is not bound. Unlike POSIX, this function does not perform an implicit bind. + /// - the socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. + /// + /// References + /// - + /// - + /// - + send: func(this: udp-socket, datagram: datagram) -> result<_, error> + + /// Get the current bound address. + /// + /// Returns an error if the socket is not bound. + /// + /// References + /// - + /// - + local-address: func(this: udp-socket) -> result + + /// Get the address set with `connect`. + /// + /// References + /// - + /// - + remote-address: func(this: udp-socket) -> result + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func(this: udp-socket) -> result + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// Implementations are not required to support dual-stack mode, so calling `set-ipv6-only(false)` might fail. + /// + /// Fails when called on an IPv4 socket. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + ipv6-only: func(this: udp-socket) -> result + set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error> + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + unicast-hop-limit: func(this: udp-socket) -> result + set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error> + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Fails when this socket is in the Listening state. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + receive-buffer-size: func(this: udp-socket) -> result + set-receive-buffer-size: func(this: udp-socket, value: u64) -> result<_, error> + send-buffer-size: func(this: udp-socket) -> result + set-send-buffer-size: func(this: udp-socket, value: u64) -> result<_, error> + + /// Get/set the blocking mode of the socket. + /// + /// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. + /// When switched to "non-blocking" mode, operations that would block return an `again` error. After which + /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. + /// + /// Note: these functions are here for WASI Preview2 only. + /// They're planned to be removed when `future` is natively supported in Preview3. + non-blocking: func(this: udp-socket) -> result + set-non-blocking: func(this: udp-socket, value: bool) -> result<_, error> + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func(this: udp-socket) -> pollable + + /// Dispose of the specified `udp-socket`, after which it may no longer be used. + /// + /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. + drop-udp-socket: func(this: udp-socket) +} From 506a315bb91dc07dd23535a62f772139bc352cce Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 1 Mar 2023 12:30:34 -0800 Subject: [PATCH 1084/1772] Rename `default-network` to `instance-network`. Rename `default-network` to `instance-network`. This follows the convention now being used in [wasi-clocks], which is following the theory that "instance" better conveys that this resembles what will be per-instance value imports in the future. [wasi-clocks]: https://github.com/WebAssembly/wasi-clocks/blob/main/wit/instance-monotonic-clock.wit --- proposals/sockets/example-world.md | 8 ++++---- .../wit/{default-network.wit => instance-network.wit} | 6 +++--- proposals/sockets/wit/world.wit | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) rename proposals/sockets/wit/{default-network.wit => instance-network.wit} (65%) diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index 882f9ea07..b9dccb7b1 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -3,7 +3,7 @@

    • Imports:
      • interface network
      • -
      • interface default-network
      • +
      • interface instance-network
      • interface poll
      • interface udp
      • interface udp-create-socket
      • @@ -96,7 +96,7 @@ There is no need for this to map 1:1 to a physical network interface. -

        Import interface default-network

        +

        Import interface instance-network

        This interface provides a value-export of the default network handle..


        Types

        @@ -105,11 +105,11 @@ There is no need for this to map 1:1 to a physical network interface.

        ----

        Functions

        -

        default-network: func

        +

        instance-network: func

        Get a handle to the default network.

        Return values

        Import interface poll

        A poll API intended to let users wait for I/O events on multiple handles diff --git a/proposals/sockets/wit/default-network.wit b/proposals/sockets/wit/instance-network.wit similarity index 65% rename from proposals/sockets/wit/default-network.wit rename to proposals/sockets/wit/instance-network.wit index 6cbc13cc9..b1f5c982d 100644 --- a/proposals/sockets/wit/default-network.wit +++ b/proposals/sockets/wit/instance-network.wit @@ -1,9 +1,9 @@ /// This interface provides a value-export of the default network handle.. -default interface default-network { +default interface instance-network { use pkg.network.{network} /// Get a handle to the default network. - default-network: func() -> network + instance-network: func() -> network -} \ No newline at end of file +} diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index e3d7d24de..854fac0ba 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,6 +1,6 @@ default world example-world { - import default-network: pkg.default-network + import instance-network: pkg.instance-network import network: pkg.network import udp: pkg.udp import udp-create-socket: pkg.udp-create-socket From 72187ba88d1cbd12f94661d0da0404a280407504 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 1 Mar 2023 12:39:34 -0800 Subject: [PATCH 1085/1772] Update generated files. --- proposals/cli/cli.md | 68 ++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/proposals/cli/cli.md b/proposals/cli/cli.md index 252c4fe67..30a01cfc4 100644 --- a/proposals/cli/cli.md +++ b/proposals/cli/cli.md @@ -1635,8 +1635,8 @@ Or it immediately fails whenever name is:

      References:

      Params
        @@ -1766,8 +1766,8 @@ implicitly bind the socket.

      References

      Params
        @@ -1795,8 +1795,8 @@ implicitly bind the socket.

      References

      Params
        @@ -1819,8 +1819,8 @@ implicitly bind the socket.

      References

      Params
        @@ -1839,8 +1839,8 @@ a pair of streams that can be used to read & write to the connection.

        Fails when this socket is not in the Listening state.

        References:

        Params
          @@ -1855,8 +1855,8 @@ a pair of streams that can be used to read & write to the connection.

          Returns an error if the socket is not bound.

          References

          Params
            @@ -1871,8 +1871,8 @@ a pair of streams that can be used to read & write to the connection.

            Fails when the socket is not in the Connection state.

            References

            Params
              @@ -2084,8 +2084,8 @@ operations on the output-stream associ

              Fails when the socket is not in the Connection state.

              References

              Params
                @@ -2128,8 +2128,8 @@ at time of creation, the socket is not bound to any net is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                References:

                Params
                  @@ -2181,8 +2181,8 @@ implicitly bind the socket.

                References

                Params
                  @@ -2209,8 +2209,8 @@ implicitly bind the socket.

                References

                Params
                  @@ -2235,9 +2235,9 @@ implicitly bind the socket.

                References

                Params

                References

                Params
                  @@ -2276,8 +2276,8 @@ call remote-address to get their addr

                  Returns an error if the socket is not bound.

                  References

                  Params
                    @@ -2291,8 +2291,8 @@ call remote-address to get their addr

                    Get the address set with connect.

                    References

                    Params
                      @@ -2471,8 +2471,8 @@ at time of creation, the socket is not bound to any net the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                      References:

                      Params
                        From ca514c1e7fcba2e3f6293aa0876021e57fbdf49c Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 1 Mar 2023 22:22:00 +0100 Subject: [PATCH 1086/1772] Replace `resource-limit-reached` with `new-socket-limit` --- proposals/sockets/wit/network.wit | 7 +++---- proposals/sockets/wit/tcp-create-socket.wit | 7 +++++-- proposals/sockets/wit/udp-create-socket.wit | 7 +++++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 543976a65..8e8fd0748 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -21,7 +21,6 @@ default interface network { /// - `unknown` /// - `access-denied` /// - `not-supported` - /// - `resource-limit-reached` /// - `out-of-memory` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. @@ -41,9 +40,6 @@ default interface network { /// POSIX equivalent: EOPNOTSUPP not-supported, - /// Resource limit reached. - resource-limit-reached, - /// Not enough memory to complete the operation. /// /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY @@ -76,6 +72,9 @@ default interface network { // ### TCP & UDP SOCKET ERRORS ### + + /// A new socket resource could not be created because of a system limit. + new-socket-limit, /// The socket is already attached to another network. already-attached, diff --git a/proposals/sockets/wit/tcp-create-socket.wit b/proposals/sockets/wit/tcp-create-socket.wit index 64c9fa78e..04e394329 100644 --- a/proposals/sockets/wit/tcp-create-socket.wit +++ b/proposals/sockets/wit/tcp-create-socket.wit @@ -12,11 +12,14 @@ default interface tcp-create-socket { /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// /// # Typical errors - /// - `not-supported`: The host does not support TCP sockets. - /// - `address-family-not-supported`: The specified `address-family` is not supported. + /// - `not-supported`: The host does not support TCP sockets. (EOPNOTSUPP) + /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) /// /// # References /// - /// - + /// - + /// - create-tcp-socket: func(address-family: ip-address-family) -> result } diff --git a/proposals/sockets/wit/udp-create-socket.wit b/proposals/sockets/wit/udp-create-socket.wit index ec44567da..0d24faf99 100644 --- a/proposals/sockets/wit/udp-create-socket.wit +++ b/proposals/sockets/wit/udp-create-socket.wit @@ -12,11 +12,14 @@ default interface udp-create-socket { /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// /// # Typical errors - /// - `not-supported`: The host does not support UDP sockets. - /// - `address-family-not-supported`: The specified `address-family` is not supported. + /// - `not-supported`: The host does not support UDP sockets. (EOPNOTSUPP) + /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) /// /// # References: /// - /// - + /// - + /// - create-udp-socket: func(address-family: ip-address-family) -> result } From 43144df9cdb99721cc5dddb38ce5de363a3939bf Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 1 Mar 2023 22:26:41 +0100 Subject: [PATCH 1087/1772] Regenerate example-world.md --- proposals/sockets/example-world.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index ea1a2050e..ded026559 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -90,7 +90,6 @@ combined with a couple of errors that are always possible:

                      • unknown
                      • access-denied
                      • not-supported
                      • -
                      • resource-limit-reached
                      • out-of-memory

                      See each individual API for what the POSIX equivalents are. They sometimes differ per API.

                      @@ -111,10 +110,6 @@ combined with a couple of errors that are always possible:

                      POSIX equivalent: EOPNOTSUPP

                    • -

                      resource-limit-reached

                      -

                      Resource limit reached. -

                    • -
                    • out-of-memory

                      Not enough memory to complete the operation.

                      POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY

                      @@ -148,6 +143,10 @@ combined with a couple of errors that are always possible:

                      The operation is only supported on IPv6 resources.

                    • +

                      new-socket-limit

                      +

                      A new socket resource could not be created because of a system limit. +

                    • +
                    • already-attached

                      The socket is already attached to another network.

                    • @@ -677,13 +676,16 @@ at time of creation, the socket is not bound to any net the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                      Typical errors

                      References:

                      Params
                        @@ -1375,13 +1377,16 @@ at time of creation, the socket is not bound to any net is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                        Typical errors

                        References

                        Params
                          From 3891206338d1c98f64558788e3cf4bc9c98462a0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 1 Mar 2023 20:29:14 -0800 Subject: [PATCH 1088/1772] Clarify the meaning of `read`'s end-of-stream return value. (#27) * Clarify the meaning of `read`'s end-of-stream return value. Similar to WebAssembly/wasi-filesystem#101, clarify that the bool returned from reading from a stream being false doesn't necessarily mean the end of the stream wasn't reached, just that it wasn't detected yet. * Update generated files. --- proposals/io/example-world.md | 4 ++-- proposals/io/wit/streams.wit | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/io/example-world.md b/proposals/io/example-world.md index a5e275ce5..6ff6f1347 100644 --- a/proposals/io/example-world.md +++ b/proposals/io/example-world.md @@ -103,8 +103,8 @@ the wit-bindgen implementation of handles and resources is ready.

                          read: func

                          Read bytes from a stream.

                          This function returns a list of bytes containing the data that was -read, along with a bool indicating whether the end of the stream -was reached. The returned list will contain up to len bytes; it +read, along with a bool which, when true, indicates that the end of the +stream was reached. The returned list will contain up to len bytes; it may return fewer than requested, but not more.

                          Once a stream has reached the end, subsequent calls to read or skip will always report end-of-stream rather than producing more diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index 9fa533efe..7f3d5eefc 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -32,8 +32,8 @@ default interface streams { /// Read bytes from a stream. /// /// This function returns a list of bytes containing the data that was - /// read, along with a bool indicating whether the end of the stream - /// was reached. The returned list will contain up to `len` bytes; it + /// read, along with a bool which, when true, indicates that the end of the + /// stream was reached. The returned list will contain up to `len` bytes; it /// may return fewer than requested, but not more. /// /// Once a stream has reached the end, subsequent calls to read or From c49ce8ebd884ef91ada00254495ce086a01217d9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 1 Mar 2023 20:30:20 -0800 Subject: [PATCH 1089/1772] Add explicit blocking functions. (#28) * Add explicit blocking functions. With #24 making streams always non-blocking, add functions to make it easy for users to use streams in blocking ways. This way, callers chose whether to block or not by calling the `blocking`- or regular non-blocking functions. Along with #24, this switches wasi-io streams from having blockingness as a dynamic flag associated with a stream, to being an API choice that callers make in their choice of which function to use. * Update generated files. --- proposals/io/example-world.md | 66 +++++++++++++++++++++++++++++++++++ proposals/io/wit/streams.wit | 52 +++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/proposals/io/example-world.md b/proposals/io/example-world.md index 6ff6f1347..4f1e3b4f0 100644 --- a/proposals/io/example-world.md +++ b/proposals/io/example-world.md @@ -124,6 +124,19 @@ FIXME: describe what happens if allocation fails.

                          +

                          blocking-read: func

                          +

                          Read bytes from a stream, with blocking.

                          +

                          This is similar to read, except that it blocks until at least one +byte can be read.

                          +
                          Params
                          + +
                          Return values
                          +

                          skip: func

                          Skip bytes from a stream.

                          This is similar to the read function, but avoids copying the @@ -143,6 +156,19 @@ value will be at most len; it may be less.

                          +

                          blocking-skip: func

                          +

                          Skip bytes from a stream, with blocking.

                          +

                          This is similar to skip, except that it blocks until at least one +byte can be consumed.

                          +
                          Params
                          + +
                          Return values
                          +

                          subscribe-to-input-stream: func

                          Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been @@ -175,6 +201,19 @@ be used.

                          +

                          blocking-write: func

                          +

                          Write bytes to a stream, with blocking.

                          +

                          This is similar to write, except that it blocks until at least one +byte can be written.

                          +
                          Params
                          + +
                          Return values
                          +

                          write-zeroes: func

                          Write multiple zero bytes to a stream.

                          This function returns a u64 indicating the number of zero bytes @@ -188,6 +227,19 @@ that were written; it may be less than len.

                          +

                          blocking-write-zeroes: func

                          +

                          Write multiple zero bytes to a stream, with blocking.

                          +

                          This is similar to write-zeroes, except that it blocks until at least +one byte can be written.

                          +
                          Params
                          + +
                          Return values
                          +

                          splice: func

                          Read from one stream and write to another.

                          This function returns the number of bytes transferred; it may be less @@ -204,6 +256,20 @@ read from the input stream has been written to the output stream.

                          +

                          blocking-splice: func

                          +

                          Read from one stream and write to another, with blocking.

                          +

                          This is similar to splice, except that it blocks until at least +one byte can be read.

                          +
                          Params
                          + +
                          Return values
                          +

                          forward: func

                          Forward the entire contents of an input stream to an output stream.

                          This function repeatedly reads from the input stream and writes diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index 7f3d5eefc..c1567fd4c 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -53,6 +53,16 @@ default interface streams { len: u64 ) -> result, bool>, stream-error> + /// Read bytes from a stream, with blocking. + /// + /// This is similar to `read`, except that it blocks until at least one + /// byte can be read. + blocking-read: func( + this: input-stream, + /// The maximum number of bytes to read + len: u64 + ) -> result, bool>, stream-error> + /// Skip bytes from a stream. /// /// This is similar to the `read` function, but avoids copying the @@ -71,6 +81,16 @@ default interface streams { len: u64, ) -> result, stream-error> + /// Skip bytes from a stream, with blocking. + /// + /// This is similar to `skip`, except that it blocks until at least one + /// byte can be consumed. + blocking-skip: func( + this: input-stream, + /// The maximum number of bytes to skip. + len: u64, + ) -> result, stream-error> + /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been /// closed. @@ -109,6 +129,16 @@ default interface streams { buf: list ) -> result + /// Write bytes to a stream, with blocking. + /// + /// This is similar to `write`, except that it blocks until at least one + /// byte can be written. + blocking-write: func( + this: output-stream, + /// Data to write + buf: list + ) -> result + /// Write multiple zero bytes to a stream. /// /// This function returns a `u64` indicating the number of zero bytes @@ -119,6 +149,16 @@ default interface streams { len: u64 ) -> result + /// Write multiple zero bytes to a stream, with blocking. + /// + /// This is similar to `write-zeroes`, except that it blocks until at least + /// one byte can be written. + blocking-write-zeroes: func( + this: output-stream, + /// The number of zero bytes to write + len: u64 + ) -> result + /// Read from one stream and write to another. /// /// This function returns the number of bytes transferred; it may be less @@ -134,6 +174,18 @@ default interface streams { len: u64, ) -> result, stream-error> + /// Read from one stream and write to another, with blocking. + /// + /// This is similar to `splice`, except that it blocks until at least + /// one byte can be read. + blocking-splice: func( + this: output-stream, + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result, stream-error> + /// Forward the entire contents of an input stream to an output stream. /// /// This function repeatedly reads from the input stream and writes From 8ac460e6bca43a886fa3e8354874e99f1c885982 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 2 Mar 2023 17:48:08 -0600 Subject: [PATCH 1090/1772] Remove 'body' type alias that includes trailers --- proposals/http/wit/types.wit | 45 +++++++++++++++++------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index fa315e298..79c736e87 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -53,29 +53,26 @@ default interface types { type headers = fields type trailers = fields - // The following block defines the `body` type which corresponds to the HTTP - // standard Contents. With Preview3, all of these fields can be replaced by a - // single type definition: - // - // type body = stream> - // - // In the interim, we need to use separate `input-stream` and `output-stream` - // resource types defined by `wasi:io/streams`. The `finish-` functions - // emulate the stream's result value and MUST be called exactly once after - // the final read/write from/to the stream before dropping the stream. - type incoming-body = input-stream - type outgoing-body = output-stream - finish-incoming-body: func(body: incoming-body) -> option - finish-outgoing-body: func(body: outgoing-body, trailers: option) + // The following block defines stream types which corresponds to the HTTP + // standard Contents and Trailers. With Preview3, all of these fields can be + // replaced by a stream>. In the interim, we need to + // build on separate resource types defined by `wasi:io/streams`. The + // `finish-` functions emulate the stream's result value and MUST be called + // exactly once after the final read/write from/to the stream before dropping + // the stream. + type incoming-stream = input-stream + type outgoing-stream = output-stream + finish-incoming-stream: func(s: incoming-stream) -> option + finish-outgoing-stream: func(s: outgoing-stream, trailers: option) // The following block defines the `incoming-request` and `outgoing-request` // resource types that correspond to HTTP standard Requests. Soon, when // resource types are added, the `u32` type aliases can be replaced by // proper `resource` type definitions containing all the functions as // methods. Later, Preview2 will allow both types to be merged together into - // a single `request` type (that uses the single `body` type mentioned - // above). The `consume` and `write-body` methods may only be called once - // (and return failure thereafter). + // a single `request` type (that uses the single `stream` type mentioned + // above). The `consume` and `write` methods may only be called once (and + // return failure thereafter). type incoming-request = u32 type outgoing-request = u32 drop-incoming-request: func(request: incoming-request) @@ -85,7 +82,7 @@ default interface types { incoming-request-scheme: func(request: incoming-request) -> option incoming-request-authority: func(request: incoming-request) -> string incoming-request-headers: func(request: incoming-request) -> headers - incoming-request-consume: func(request: incoming-request) -> result + incoming-request-consume: func(request: incoming-request) -> result new-outgoing-request: func( method: method, path: string, @@ -93,7 +90,7 @@ default interface types { authority: string, headers: headers ) -> outgoing-request - outgoing-request-write-body: func(request: outgoing-request) -> result + outgoing-request-write: func(request: outgoing-request) -> result // Additional optional parameters that can be set when making a request. record request-options { @@ -116,7 +113,7 @@ default interface types { // block can be replaced by a proper `resource response-outparam { ... }` // definition. Later, with Preview3, the need for an outparam goes away entirely // (the `wasi:http/handler` interface used for both incoming and outgoing can - // simply return a `body`). + // simply return a `stream`). type response-outparam = u32 drop-response-outparam: func(response: response-outparam) set-response-outparam: func(response: result) -> result @@ -129,20 +126,20 @@ default interface types { // resource types are added, the `u32` type aliases can be replaced by proper // `resource` type definitions containing all the functions as methods. Later, // Preview2 will allow both types to be merged together into a single `response` - // type (that uses the single `body` type mentioned above). The `consume` and - // `write-body` methods may only be called once (and return failure thereafter). + // type (that uses the single `stream` type mentioned above). The `consume` and + // `write` methods may only be called once (and return failure thereafter). type incoming-response = u32 type outgoing-response = u32 drop-incoming-response: func(response: incoming-response) drop-outgoing-response: func(response: outgoing-response) incoming-response-status: func(response: incoming-response) -> status-code incoming-response-headers: func(response: incoming-response) -> headers - incoming-response-consume: func(response: incoming-response) -> result + incoming-response-consume: func(response: incoming-response) -> result new-outgoing-response: func( status-code: status-code, headers: headers ) -> outgoing-response - outgoing-response-write-body: func(response: outgoing-response) -> result + outgoing-response-write: func(response: outgoing-response) -> result // The following block defines a special resource type used by the // `wasi:http/outgoing-handler` interface to emulate From f0016a6d303c98cb68ac1df15220f2b816e4c5bf Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 2 Mar 2023 17:54:06 -0600 Subject: [PATCH 1091/1772] Change 'upstream' to 'outgoing' in proxy world --- proposals/http/wit/proxy.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index d0092e9f4..ff8b53a8b 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -26,7 +26,7 @@ default world proxy { // This is the default handler to use when user code simply wants to make an // HTTP request (e.g., via `fetch()`) but doesn't otherwise specify a // particular handler. - import default-upstream-HTTP: pkg.outgoing-handler + import default-outgoing-HTTP: pkg.outgoing-handler // TODO: Once the underlying Wit template machinery is implemented, add: // From ad18620e8864500faeeb07d3ef3e6e4da6eca9f8 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 2 Mar 2023 17:56:36 -0600 Subject: [PATCH 1092/1772] Add TODO comment in error type --- proposals/http/wit/types.wit | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 79c736e87..beda0e5b8 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -26,6 +26,7 @@ default interface types { other(string) } + // TODO: perhaps better align with HTTP semantics? // This type enumerates the different kinds of errors that may occur when // initially returning a response. variant error { From af465a8381c449feb72aa107b4e537491c7b936c Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 2 Mar 2023 18:03:32 -0600 Subject: [PATCH 1093/1772] Align the 3 timeouts to have the same unit/suffix --- proposals/http/wit/types.wit | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index beda0e5b8..de1ab9645 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -99,10 +99,10 @@ default interface types { // independently of the overall timeouts passed to `io.poll.poll-oneoff`. // The timeout for the initial connect. - connect-timeout-nanos: option, + connect-timeout-ms: option, // The timeout for receiving the first byte of the response body. - first-byte-timeout-ns: option, + first-byte-timeout-ms: option, // The timeout for receiving the next chunk of bytes in the response body // stream. From eeeb5b856ea8b25b02ad5460ae2ad9b61c480683 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sat, 4 Mar 2023 08:21:29 +0100 Subject: [PATCH 1094/1772] Make `address-family` infallible --- proposals/sockets/example-world.md | 4 ++-- proposals/sockets/wit/tcp.wit | 2 +- proposals/sockets/wit/udp.wit | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index b9dccb7b1..f68c233a5 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -330,7 +330,7 @@ call remote-address to get their addr

                        Return values

                        ipv6-only: func

                        Whether IPv4 compatibility (dual-stack) mode is disabled or not. @@ -870,7 +870,7 @@ a pair of streams that can be used to read & write to the connection.

                      Return values

                      ipv6-only: func

                      Whether IPv4 compatibility (dual-stack) mode is disabled or not. diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index b2f483368..cc852b8ed 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -103,7 +103,7 @@ default interface tcp { /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: tcp-socket) -> result + address-family: func(this: tcp-socket) -> ip-address-family /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. /// Implementations are not required to support dual-stack mode. Calling `set-ipv6-only(false)` might fail. diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index af8f873b9..2dbbed5a8 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -106,7 +106,7 @@ default interface udp { /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: udp-socket) -> result + address-family: func(this: udp-socket) -> ip-address-family /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. /// Implementations are not required to support dual-stack mode, so calling `set-ipv6-only(false)` might fail. From ee05565f6aa811674161d4e620e9b160537f1042 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Sat, 4 Mar 2023 14:22:28 -0600 Subject: [PATCH 1095/1772] Remove status-error case --- proposals/http/wit/types.wit | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index de1ab9645..6a8b0dcf9 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -33,7 +33,6 @@ default interface types { invalid-url(string), timeout-error(string), protocol-error(string), - status-error(u16), unexpected-error(string) } From 54032cdcb74b0f1bc8f12cedde979eff8e12cbc4 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 5 Mar 2023 17:16:19 +0100 Subject: [PATCH 1096/1772] Remove the non-blocking toggle from sockets. They're now always non-blocking. --- proposals/sockets/wit/ip-name-lookup.wit | 14 +------------- proposals/sockets/wit/network.wit | 4 ++++ proposals/sockets/wit/tcp-create-socket.wit | 2 ++ proposals/sockets/wit/tcp.wit | 17 ++--------------- proposals/sockets/wit/udp-create-socket.wit | 2 ++ proposals/sockets/wit/udp.wit | 16 ++-------------- 6 files changed, 13 insertions(+), 42 deletions(-) diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index 574fff98a..c4cc72684 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -53,26 +53,14 @@ default interface ip-name-lookup { /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) + /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) resolve-next-address: func(this: resolve-address-stream) -> result, error-code> - - /// Dispose of the specified `resolve-address-stream`, after which it may no longer be used. /// /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. drop-resolve-address-stream: func(this: resolve-address-stream) - /// Get/set the blocking mode of the stream. - /// - /// By default a stream is in "blocking" mode, meaning that any function blocks and waits for its completion. - /// When switched to "non-blocking" mode, operations that would block return an `again` error. After which - /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. - /// - /// Note: these functions are here for WASI Preview2 only. - /// They're planned to be removed when `future` is natively supported in Preview3. - non-blocking: func(this: resolve-address-stream) -> result - set-non-blocking: func(this: resolve-address-stream, value: bool) -> result<_, error-code> - /// Create a `pollable` which will resolve once the stream is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 8e8fd0748..5e65a11d6 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -51,6 +51,10 @@ default interface network { /// This operation is incompatible with another asynchronous operation that is already in progress. concurrency-conflict, + /// The operation has been aborted because it could not be completed immediately. + /// + /// Note: this is scheduled to be removed when `future`s are natively supported. + would-block, // ### IP ERRORS ### diff --git a/proposals/sockets/wit/tcp-create-socket.wit b/proposals/sockets/wit/tcp-create-socket.wit index 04e394329..6e948fae0 100644 --- a/proposals/sockets/wit/tcp-create-socket.wit +++ b/proposals/sockets/wit/tcp-create-socket.wit @@ -11,6 +11,8 @@ default interface tcp-create-socket { /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// /// # Typical errors /// - `not-supported`: The host does not support TCP sockets. (EOPNOTSUPP) /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 07763376c..314964de2 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -98,6 +98,7 @@ default interface tcp { /// /// # Typical errors /// - `not-listening`: Socket is not in the Listener state. (EINVAL) + /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) /// /// Host implementations must skip over transient errors returned by the native accept syscall. /// @@ -199,27 +200,13 @@ default interface tcp { send-buffer-size: func(this: tcp-socket) -> result set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> - /// Get/set the blocking mode of the socket. - /// - /// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. - /// When switched to "non-blocking" mode, operations that would block return an `would-block` error. After which - /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. - /// - /// Note: these functions are here for WASI Preview2 only. - /// They're planned to be removed when `future` is natively supported in Preview3. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - non-blocking: func(this: tcp-socket) -> result - set-non-blocking: func(this: tcp-socket, value: bool) -> result<_, error-code> - /// Create a `pollable` which will resolve once the socket is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. subscribe: func(this: tcp-socket) -> pollable - /// Gracefully shut down the connection. + /// Initiate a graceful shutdown. /// /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. diff --git a/proposals/sockets/wit/udp-create-socket.wit b/proposals/sockets/wit/udp-create-socket.wit index 0d24faf99..2c987be08 100644 --- a/proposals/sockets/wit/udp-create-socket.wit +++ b/proposals/sockets/wit/udp-create-socket.wit @@ -11,6 +11,8 @@ default interface udp-create-socket { /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` is called, /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// /// # Typical errors /// - `not-supported`: The host does not support UDP sockets. (EOPNOTSUPP) /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index e48271486..7a74c5731 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -79,6 +79,7 @@ default interface udp { /// # Typical errors /// - `not-bound`: The socket is not bound to any local address. (EINVAL) /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN) /// /// # References /// - @@ -103,6 +104,7 @@ default interface udp { /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN) /// /// # References /// - @@ -182,20 +184,6 @@ default interface udp { send-buffer-size: func(this: udp-socket) -> result set-send-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> - /// Get/set the blocking mode of the socket. - /// - /// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. - /// When switched to "non-blocking" mode, operations that would block return an `would-block` error. After which - /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. - /// - /// Note: these functions are here for WASI Preview2 only. - /// They're planned to be removed when `future` is natively supported in Preview3. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - non-blocking: func(this: udp-socket) -> result - set-non-blocking: func(this: udp-socket, value: bool) -> result<_, error-code> - /// Create a `pollable` which will resolve once the socket is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. From 43ba07e1a9df69fb2b34fb06903ee55bb7e3c63b Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 5 Mar 2023 17:19:55 +0100 Subject: [PATCH 1097/1772] Made the following functions async: tcp::bind, tcp::listen, tcp::connect, udp::bind, udp::connect --- proposals/sockets/README.md | 73 +++++++++++++++++++++++++++++++ proposals/sockets/wit/network.wit | 8 ++++ proposals/sockets/wit/tcp.wit | 45 +++++++++++++------ proposals/sockets/wit/udp.wit | 26 ++++++++--- 4 files changed, 133 insertions(+), 19 deletions(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index d48bd9e57..0a45245e2 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -22,6 +22,7 @@ Phase 1 - [Goals](#goals) - [Non-goals](#non-goals) - [API walk-through](#api-walk-through) + - [Asynchronous APIs](#asynchronous-apis) - [Use case 1](#use-case-1) - [Use case 2](#use-case-2) - [Detailed design discussion](#detailed-design-discussion) @@ -29,6 +30,8 @@ Phase 1 - [Modularity](#modularity) - [POSIX compatibility](#posix-compatibility) - [Why not getaddrinfo?](#why-not-getaddrinfo) + - [Security](#security) + - [Deferred permission requests](#deferred-permission-requests) - [Considered alternatives](#considered-alternatives) - [[Alternative 1]](#alternative-1) - [[Alternative 2]](#alternative-2) @@ -65,6 +68,61 @@ This proposal introduces 4 new WASI modules: [Walk through of how someone would use this API.] +#### Asynchronous APIs + +At the moment, WIT has no built-in way of expressing asynchronous operations. To work around this limitation, we split up async functions into two parts: `start-*` and `finish-*`. + +Desired signature: + +``` +operation: func(this, the-inputs...) -> future> +``` + +Temporary workaround: + +``` +start-operation: func(this, the-inputs...) -> result<_, error-code> +finish-operation: func(this) -> result +``` + + +The semantics are as follows: +- When `start-*` completes successfully: + - The operation should be considered "in progress". + - This is the POSIX equivalent of EINPROGRESS. + - The socket can be polled for completion of the just started operation, using `wasi-poll`. + - Its corresponding `finish-*` function can be called until it returns something other than the `would-block` error code. +- When `finish-*` returns anything other than `would-block`: + - The asynchronous operation should be considered "finished" (either successful or failed) + - Future calls to `finish-*` return the `not-in-progress` error code. + +Runtimes that don't need asynchrony, can simply validate the arguments provided to the `start` function and stash them on their internal socket instance and perform the actual syscall in the `finish` function. Conveniently, sockets only allow one of these `start/finish` asynchronous operation to be active at a time. + + +Example of how to recover blocking semantics in guest code: +```rs +// Pseudo code: +fn blocking-connect(sock: tcp-socket, addr: ip-socket-address) -> result, error-code> { + + let pollable = tcp::subscribe(tcp-socket); + + let start-result = tcp::start-connect(sock, addr); + if (start-result is error) { + return error; + } + + while (true) { + poll::poll-oneoff([ pollable ]); + + let finish-result = tcp::finish-connect(sock); + if (finish-result is NOT error(would-block)) { + return finish-result; + } + } +} + +``` + #### Use case: Wasm module per connection Thanks to the low startup cost of Wasm modules, its feasible for server software with Wasm integration to spawn a Wasm module for each inbound connection. Each module instance is passed only the accepted client socket. This way, all connection handlers are completely isolated from each other. This resembles PHP's "shared nothing" architecture. @@ -152,6 +210,21 @@ This means Wasm modules will get a lot more EACCES errors compared to when runni At the moment there is no way for a Wasm modules to query which network access permissions it has. The only thing it can do, is to just call the WASI functions it needs and see if they fail. +#### Deferred permission requests + +This proposal does not specify how wasm runtimes should handle network permissions. One method could be to let end users declare on the command line which endpoints a wasm component may connect to. Another method could be to somehow let component authors distribute a manifest alongside the component itself, containing the set of permissions that it requires. + +Both of these examples depend on the network permissions being known and granted upfront. This is not always feasible and that's usually where dynamic permission requests come into play. + +The most likely contenders for permission prompt interception are: +- TCP: `connect` +- TCP: `bind` +- TCP: `listen` +- UDP: `bind` +- UDP: `connect` + +Now, again, this proposal does not specify if/how permission prompts should be implemented. However, it does at least facilitate the ability for runtimes to do so. Since waiting for user input takes an unknowable amount of time, the operations listed above have been made asynchronous. POSIX-compatibility layers can simply synchronously block on the returned `future`s. + ### Considered alternatives [This section is not required if you already covered considered alternatives in the design discussion above.] diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 5e65a11d6..9176e6ba6 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -51,11 +51,19 @@ default interface network { /// This operation is incompatible with another asynchronous operation that is already in progress. concurrency-conflict, + /// Trying to finish an asynchronous operation that: + /// - has not been started yet, or: + /// - was already finished by a previous `finish-*` call. + /// + /// Note: this is scheduled to be removed when `future`s are natively supported. + not-in-progress, + /// The operation has been aborted because it could not be completed immediately. /// /// Note: this is scheduled to be removed when `future`s are natively supported. would-block, + // ### IP ERRORS ### /// The specified address-family is not supported. diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 314964de2..b377e7269 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -29,20 +29,27 @@ default interface tcp { /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will /// implicitly bind the socket. /// - /// # Typical errors + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) /// - `address-in-use`: Address is already in use. (EADDRINUSE) /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) /// /// # References /// - /// - /// - /// - - bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> + start-bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> + finish-bind: func(this: tcp-socket) -> result<_, error-code> /// Connect to a remote endpoint. /// @@ -50,44 +57,56 @@ default interface tcp { /// - the socket is transitioned into the Connection state /// - a pair of streams is returned that can be used to read & write to the connection /// - /// # Typical errors - /// - `timeout`: Connection timed out. (ETIMEDOUT) - /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) - /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// # Typical `start` errors /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. /// - `already-connected`: The socket is already in the Connection state. (EISCONN) /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) /// + /// # Typical `finish` errors + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// /// # References /// - /// - /// - /// - - connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result, error-code> + start-connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> + finish-connect: func(this: tcp-socket) -> result, error-code> /// Start listening for new connections. /// /// Transitions the socket into the Listener state. /// - /// # Typical errors + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `listen` must be identical to the one passed to `bind`. /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) /// - `already-listening`: The socket is already in the Listener state. - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// - `not-in-progress`: A `listen` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// /// # References /// - /// - /// - /// - - listen: func(this: tcp-socket, network: network) -> result<_, error-code> + start-listen: func(this: tcp-socket, network: network) -> result<_, error-code> + finish-listen: func(this: tcp-socket) -> result<_, error-code> /// Accept a new client socket. /// diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 7a74c5731..82cade5f5 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -30,20 +30,27 @@ default interface udp { /// /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. /// - /// # Typical errors + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) /// - `address-in-use`: Address is already in use. (EADDRINUSE) /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) /// /// # References /// - /// - /// - /// - - bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> + start-bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> + finish-bind: func(this: udp-socket) -> result<_, error-code> /// Set the destination address. /// @@ -55,20 +62,27 @@ default interface udp { /// /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". /// - /// # Typical errors + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// /// # References /// - /// - /// - /// - - connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> + start-connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> + finish-connect: func(this: udp-socket) -> result<_, error-code> /// Receive a message. /// From be7ccadaee6bba6038451b8d95499e253e1253cc Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 5 Mar 2023 17:36:29 +0100 Subject: [PATCH 1098/1772] Update example-world.md --- proposals/sockets/example-world.md | 285 +++++++++++++++-------------- 1 file changed, 147 insertions(+), 138 deletions(-) diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index ded026559..969b63cdb 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -123,6 +123,18 @@ combined with a couple of errors that are always possible:

                      This operation is incompatible with another asynchronous operation that is already in progress.

                    • +

                      not-in-progress

                      +

                      Trying to finish an asynchronous operation that: +- has not been started yet, or: +- was already finished by a previous `finish-*` call. +

                      Note: this is scheduled to be removed when futures are natively supported.

                      +
                    • +
                    • +

                      would-block

                      +

                      The operation has been aborted because it could not be completed immediately. +

                      Note: this is scheduled to be removed when futures are natively supported.

                      +
                    • +
                    • address-family-not-supported

                      The specified address-family is not supported.

                    • @@ -318,20 +330,26 @@ mean "ready".


                    Functions

                    -

                    bind: func

                    +

                    start-bind: func

                    Bind the socket to a specific network on the provided IP address and port.

                    If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the TCP/UDP port is zero, the socket will be bound to a random free port.

                    When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket.

                    -

                    Typical errors

                    +

                    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                    +

                    Typical start errors

                    • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
                    • already-bound: The socket is already bound. (EINVAL)
                    • +
                    • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
                    • +
                    +

                    Typical finish errors

                    +
                    • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
                    • address-in-use: Address is already in use. (EADDRINUSE)
                    • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
                    • -
                    • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
                    • +
                    • not-in-progress: A bind operation is not in progress.
                    • +
                    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)

                    References

                      @@ -342,15 +360,24 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                    Params
                    +
                    Return values
                    + +

                    finish-bind: func

                    +
                    Params
                    +
                    Return values
                    -

                    connect: func

                    +

                    start-connect: func

                    Set the destination address.

                    The local-address is updated based on the best network path to remote-address.

                    When a destination address is set:

                    @@ -359,14 +386,20 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                  • the send function can only be used to send to this destination.

                  Note that this function does not generate any network traffic and the peer is not aware of this "connection".

                  -

                  Typical errors

                  +

                  Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                  +

                  Typical start errors

                  • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
                  • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
                  • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
                  • -
                  • already-attached: The socket is already bound to a different network. The network passed to connect must be identical to the one passed to bind.
                  • +
                  • already-attached: The socket is already bound to a different network. The network passed to connect must be identical to the one passed to bind.
                  • +
                  • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
                  • +
                  +

                  Typical finish errors

                  +
                  • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
                  • -
                  • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
                  • +
                  • not-in-progress: A connect operation is not in progress.
                  • +
                  • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)

                  References

                    @@ -377,13 +410,22 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                  Params
                  +
                  Return values
                  + +

                  finish-connect: func

                  +
                  Params
                  +
                  Return values

                  receive: func

                  Receive a message.

                  @@ -396,6 +438,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                  • not-bound: The socket is not bound to any local address. (EINVAL)
                  • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
                  • +
                  • would-block: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN)

                  References

                    @@ -424,10 +467,11 @@ call remote-address to get their addr
                  • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
                  • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
                  • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
                  • -
                  • already-connected: The socket is in "connected" mode and the datagram.remote-address does not match the address passed to connect. (EISCONN)
                  • +
                  • already-connected: The socket is in "connected" mode and the datagram.remote-address does not match the address passed to connect. (EISCONN)
                  • not-bound: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind.
                  • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
                  • datagram-too-large: The datagram is too large. (EMSGSIZE)
                  • +
                  • would-block: The send buffer is currently full. (EWOULDBLOCK, EAGAIN)

                  References

                  remote-address: func

                  -

                  Get the address set with connect.

                  +

                  Get the address set with connect.

                  Typical errors

                  • not-connected: The socket is not connected to a remote address. (ENOTCONN)
                  • @@ -509,7 +553,7 @@ call remote-address to get their addr
                  • ipv6-only-operation: (get/set) this socket is an IPv4 socket.
                  • already-bound: (set) The socket is already bound.
                  • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
                  • -
                  • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
                  • +
                  • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
                  Params
                    @@ -533,7 +577,7 @@ call remote-address to get their addr

                    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                    Typical errors

                      -
                    • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
                    • +
                    • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
                    Params
                      @@ -564,7 +608,7 @@ for internal metadata structures.

                      Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

                      Typical errors

                        -
                      • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
                      • +
                      • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
                      Params
                        @@ -603,35 +647,6 @@ for internal metadata structures.

                        -

                        non-blocking: func

                        -

                        Get/set the blocking mode of the socket.

                        -

                        By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. -When switched to "non-blocking" mode, operations that would block return an would-block error. After which -the API consumer is expected to call subscribe and wait for completion using the wasi-poll module.

                        -

                        Note: these functions are here for WASI Preview2 only. -They're planned to be removed when future is natively supported in Preview3.

                        -

                        Typical errors

                        -
                          -
                        • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
                        • -
                        -
                        Params
                        - -
                        Return values
                        - -

                        set-non-blocking: func

                        -
                        Params
                        - -
                        Return values
                        -

                        subscribe: func

                        Create a pollable which will resolve once the socket is ready for I/O.

                        Note: this function is here for WASI Preview2 only. @@ -672,8 +687,9 @@ It's planned to be removed when future is natively supported in Pre

                        Create a new UDP socket.

                        Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.

                        This function does not require a network capability handle. This is considered to be safe because -at time of creation, the socket is not bound to any network yet. Up to the moment bind/connect is called, +at time of creation, the socket is not bound to any network yet. Up to the moment bind/connect is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                        +

                        All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

                        Typical errors

                        • not-supported: The host does not support UDP sockets. (EOPNOTSUPP)
                        • @@ -926,21 +942,27 @@ be used.


                        Functions

                        -

                        bind: func

                        +

                        start-bind: func

                        Bind the socket to a specific network on the provided IP address and port.

                        If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the TCP/UDP port is zero, the socket will be bound to a random free port.

                        When a socket is not explicitly bound, the first invocation to a listen or connect operation will implicitly bind the socket.

                        -

                        Typical errors

                        +

                        Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                        +

                        Typical start errors

                        • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
                        • already-bound: The socket is already bound. (EINVAL)
                        • +
                        • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
                        • +
                        +

                        Typical finish errors

                        +
                        • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
                        • address-in-use: Address is already in use. (EADDRINUSE)
                        • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
                        • -
                        • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
                        • +
                        • not-in-progress: A bind operation is not in progress.
                        • +
                        • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)

                        References

                          @@ -951,35 +973,49 @@ implicitly bind the socket.

                        Params
                        +
                        Return values
                        + +

                        finish-bind: func

                        +
                        Params
                        +
                        Return values
                        -

                        connect: func

                        +

                        start-connect: func

                        Connect to a remote endpoint.

                        On success:

                        • the socket is transitioned into the Connection state
                        • a pair of streams is returned that can be used to read & write to the connection
                        -

                        Typical errors

                        +

                        Typical start errors

                          -
                        • timeout: Connection timed out. (ETIMEDOUT)
                        • -
                        • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
                        • -
                        • connection-reset: The connection was reset. (ECONNRESET)
                        • -
                        • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
                        • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
                        • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
                        • invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
                        • -
                        • already-attached: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
                        • +
                        • already-attached: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
                        • already-connected: The socket is already in the Connection state. (EISCONN)
                        • already-listening: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
                        • +
                        • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
                        • +
                        +

                        Typical finish errors

                        +
                          +
                        • timeout: Connection timed out. (ETIMEDOUT)
                        • +
                        • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
                        • +
                        • connection-reset: The connection was reset. (ECONNRESET)
                        • +
                        • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
                        • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
                        • -
                        • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
                        • +
                        • not-in-progress: A connect operation is not in progress.
                        • +
                        • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)

                        References

                          @@ -990,24 +1026,39 @@ implicitly bind the socket.

                        Params
                        +
                        Return values
                        + +

                        finish-connect: func

                        +
                        Params
                        +
                        Return values
                        -

                        listen: func

                        +

                        start-listen: func

                        Start listening for new connections.

                        Transitions the socket into the Listener state.

                        -

                        Typical errors

                        +

                        Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                        +

                        Typical start errors

                          -
                        • already-attached: The socket is already attached to a different network. The network passed to listen must be identical to the one passed to bind.
                        • +
                        • already-attached: The socket is already attached to a different network. The network passed to listen must be identical to the one passed to bind.
                        • already-connected: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
                        • already-listening: The socket is already in the Listener state.
                        • +
                        • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EINVAL on BSD)
                        • +
                        +

                        Typical finish errors

                        +
                        • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
                        • -
                        • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EINVAL on BSD)
                        • +
                        • not-in-progress: A listen operation is not in progress.
                        • +
                        • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)

                        References

                          @@ -1018,12 +1069,21 @@ implicitly bind the socket.

                        Params
                        +
                        Return values
                        + +

                        finish-listen: func

                        +
                        Params
                        +
                        Return values

                        accept: func

                        Accept a new client socket.

                        @@ -1033,6 +1093,7 @@ a pair of streams that can be used to read & write to the connection.

                        Typical errors

                        • not-listening: Socket is not in the Listener state. (EINVAL)
                        • +
                        • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)

                        Host implementations must skip over transient errors returned by the native accept syscall.

                        References

                        @@ -1111,7 +1172,7 @@ a pair of streams that can be used to read & write to the connection.

                      • ipv6-only-operation: (get/set) this socket is an IPv4 socket.
                      • already-bound: (set) The socket is already bound.
                      • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
                      • -
                      • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                      • +
                      • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                      Params
                        @@ -1136,7 +1197,7 @@ a pair of streams that can be used to read & write to the connection.

                        Typical errors

                        • already-connected: (set) The socket is already in the Connection state.
                        • -
                        • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                        • +
                        • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                        Params
                          @@ -1151,7 +1212,7 @@ a pair of streams that can be used to read & write to the connection.

                          Equivalent to the SO_KEEPALIVE socket option.

                          Typical errors

                            -
                          • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                          • +
                          • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                          Params
                            @@ -1175,7 +1236,7 @@ a pair of streams that can be used to read & write to the connection.

                            Equivalent to the TCP_NODELAY socket option.

                            Typical errors

                              -
                            • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                            • +
                            • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                            Params
                              @@ -1201,7 +1262,7 @@ a pair of streams that can be used to read & write to the connection.

                              • already-connected: (set) The socket is already in the Connection state.
                              • already-listening: (set) The socket is already in the Listener state.
                              • -
                              • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                              • +
                              • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                              Params
                                @@ -1233,7 +1294,7 @@ for internal metadata structures.

                                • already-connected: (set) The socket is already in the Connection state.
                                • already-listening: (set) The socket is already in the Listener state.
                                • -
                                • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                                • +
                                • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                                Params
                                  @@ -1272,35 +1333,6 @@ for internal metadata structures.

                                  -

                                  non-blocking: func

                                  -

                                  Get/set the blocking mode of the socket.

                                  -

                                  By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. -When switched to "non-blocking" mode, operations that would block return an would-block error. After which -the API consumer is expected to call subscribe and wait for completion using the wasi-poll module.

                                  -

                                  Note: these functions are here for WASI Preview2 only. -They're planned to be removed when future is natively supported in Preview3.

                                  -

                                  Typical errors

                                  -
                                    -
                                  • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                                  • -
                                  -
                                  Params
                                  - -
                                  Return values
                                  - -

                                  set-non-blocking: func

                                  -
                                  Params
                                  - -
                                  Return values
                                  -

                                  subscribe: func

                                  Create a pollable which will resolve once the socket is ready for I/O.

                                  Note: this function is here for WASI Preview2 only. @@ -1314,7 +1346,7 @@ It's planned to be removed when future is natively supported in Pre

                                • pollable

                                shutdown: func

                                -

                                Gracefully shut down the connection.

                                +

                                Initiate a graceful shutdown.

                                • receive: the socket is not expecting to receive any more data from the peer. All subsequent read operations on the input-stream associated with this socket will return an End Of Stream indication. @@ -1373,8 +1405,9 @@ operations on the output-stream associ

                                  Create a new TCP socket.

                                  Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX.

                                  This function does not require a network capability handle. This is considered to be safe because -at time of creation, the socket is not bound to any network yet. Up to the moment bind/listen/connect +at time of creation, the socket is not bound to any network yet. Up to the moment bind/listen/connect is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                                  +

                                  All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

                                  Typical errors

                                  • not-supported: The host does not support TCP sockets. (EOPNOTSUPP)
                                  • @@ -1473,6 +1506,7 @@ After which, you should release the stream with
                                  • this: resolve-address-stream
                                  -

                                  non-blocking: func

                                  -

                                  Get/set the blocking mode of the stream.

                                  -

                                  By default a stream is in "blocking" mode, meaning that any function blocks and waits for its completion. -When switched to "non-blocking" mode, operations that would block return an again error. After which -the API consumer is expected to call subscribe and wait for completion using the wasi-poll module.

                                  -

                                  Note: these functions are here for WASI Preview2 only. -They're planned to be removed when future is natively supported in Preview3.

                                  -
                                  Params
                                  - -
                                  Return values
                                  - -

                                  set-non-blocking: func

                                  -
                                  Params
                                  - -
                                  Return values
                                  -

                                  subscribe: func

                                  Create a pollable which will resolve once the stream is ready for I/O.

                                  Note: this function is here for WASI Preview2 only. From bdd5f6328543b66397f3828150efaafe054cc07b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 6 Mar 2023 10:23:44 -0800 Subject: [PATCH 1099/1772] Make `read-via-stream` etc. infallible. (#109) Make `read-via-stream`, `write-via-stream`, and `append-via-stream` infallible. They don't do any I/O themselves, so they shouldn't fail. And, this is closer to how streams will work in Preview3. --- proposals/filesystem/example-world.md | 6 +++--- proposals/filesystem/wit/filesystem.wit | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md index b6355f2a2..28f8d790e 100644 --- a/proposals/filesystem/example-world.md +++ b/proposals/filesystem/example-world.md @@ -762,7 +762,7 @@ file and they do not interfere with each other.

                                Return values

                                write-via-stream: func

                                Return a stream for writing to a file.

                                @@ -775,7 +775,7 @@ POSIX.

                              Return values

                              append-via-stream: func

                              Return a stream for appending to a file.

                              @@ -787,7 +787,7 @@ POSIX.

                            Return values

                            advise: func

                            Provide file advisory information on a descriptor.

                            diff --git a/proposals/filesystem/wit/filesystem.wit b/proposals/filesystem/wit/filesystem.wit index 90985e27e..8099337a5 100644 --- a/proposals/filesystem/wit/filesystem.wit +++ b/proposals/filesystem/wit/filesystem.wit @@ -313,7 +313,7 @@ default interface filesystem { this: descriptor, /// The offset within the file at which to start reading. offset: filesize, - ) -> result + ) -> input-stream /// Return a stream for writing to a file. /// @@ -323,7 +323,7 @@ default interface filesystem { this: descriptor, /// The offset within the file at which to start writing. offset: filesize, - ) -> result + ) -> output-stream /// Return a stream for appending to a file. /// @@ -331,7 +331,7 @@ default interface filesystem { /// `O_APPEND` in in POSIX. append-via-stream: func( this: descriptor, - ) -> result + ) -> output-stream /// Provide file advisory information on a descriptor. /// From 52963eb9faa6af375ae302e8cd1edf92d6046ef6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 6 Mar 2023 10:47:26 -0800 Subject: [PATCH 1100/1772] Rename things to clarify commands, and add a reactor interface. Renae the "cli" interface and wit file to "command". With the new deps layout, this means users see cli/command rather than cli/cli. Accompanying that change, rename the "command" function to "main". This is not the C/C++ or other language `main` function, but it is the component-model main function, and at that scope I think calling it "main" makes sense. Also, add a "reactor" interface, which is the same as the "command" interface, except without the "main" function. --- proposals/cli/{cli.md => command.md} | 22 +- proposals/cli/reactor.md | 2562 ++++++++++++++++++++ proposals/cli/wit/{cli.wit => command.wit} | 4 +- proposals/cli/wit/reactor.wit | 21 + 4 files changed, 2596 insertions(+), 13 deletions(-) rename proposals/cli/{cli.md => command.md} (99%) create mode 100644 proposals/cli/reactor.md rename proposals/cli/wit/{cli.wit => command.wit} (95%) create mode 100644 proposals/cli/wit/reactor.wit diff --git a/proposals/cli/cli.md b/proposals/cli/command.md similarity index 99% rename from proposals/cli/cli.md rename to proposals/cli/command.md index 30a01cfc4..006edb2c9 100644 --- a/proposals/cli/cli.md +++ b/proposals/cli/command.md @@ -1,4 +1,4 @@ -

                            World cli

                            +

                            World command

                          @@ -280,7 +280,7 @@ be used.

                          -

                          Import interface filesystem

                          +

                          Import interface types

                          WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                          diff --git a/proposals/filesystem/wit/filesystem.wit b/proposals/filesystem/wit/types.wit similarity index 99% rename from proposals/filesystem/wit/filesystem.wit rename to proposals/filesystem/wit/types.wit index 8099337a5..9530d6a63 100644 --- a/proposals/filesystem/wit/filesystem.wit +++ b/proposals/filesystem/wit/types.wit @@ -17,7 +17,7 @@ /// `..` and symbolic link steps, reaches a directory outside of the base /// directory, or reaches a symlink to an absolute or rooted path in the /// underlying filesystem, the function fails with `error-code::not-permitted`. -default interface filesystem { +default interface types { use io.streams.{input-stream, output-stream} use clocks.wall-clock.{datetime} diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index 17cf06ac0..209211029 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,3 +1,3 @@ default world example-world { - import filesystem: pkg.filesystem + import types: pkg.types } From 3092877a879b4dd401f5a4f4b8d000c260b9b61f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 Mar 2023 14:22:47 -0800 Subject: [PATCH 1102/1772] Update io/streams.wit to the latest version. --- proposals/sockets/example-world.md | 70 ++++++++++++++++++++++- proposals/sockets/wit/deps/io/streams.wit | 56 +++++++++++++++++- 2 files changed, 122 insertions(+), 4 deletions(-) diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index b9dccb7b1..0b2727fd4 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -550,8 +550,8 @@ the wit-bindgen implementation of handles and resources is ready.

                          read: func

                          Read bytes from a stream.

                          This function returns a list of bytes containing the data that was -read, along with a bool indicating whether the end of the stream -was reached. The returned list will contain up to len bytes; it +read, along with a bool which, when true, indicates that the end of the +stream was reached. The returned list will contain up to len bytes; it may return fewer than requested, but not more.

                          Once a stream has reached the end, subsequent calls to read or skip will always report end-of-stream rather than producing more @@ -571,6 +571,19 @@ FIXME: describe what happens if allocation fails.

                          +

                          blocking-read: func

                          +

                          Read bytes from a stream, with blocking.

                          +

                          This is similar to read, except that it blocks until at least one +byte can be read.

                          +
                          Params
                          + +
                          Return values
                          +

                          skip: func

                          Skip bytes from a stream.

                          This is similar to the read function, but avoids copying the @@ -590,6 +603,19 @@ value will be at most len; it may be less.

                          +

                          blocking-skip: func

                          +

                          Skip bytes from a stream, with blocking.

                          +

                          This is similar to skip, except that it blocks until at least one +byte can be consumed.

                          +
                          Params
                          + +
                          Return values
                          +

                          subscribe-to-input-stream: func

                          Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been @@ -622,6 +648,19 @@ be used.

                          +

                          blocking-write: func

                          +

                          Write bytes to a stream, with blocking.

                          +

                          This is similar to write, except that it blocks until at least one +byte can be written.

                          +
                          Params
                          + +
                          Return values
                          +

                          write-zeroes: func

                          Write multiple zero bytes to a stream.

                          This function returns a u64 indicating the number of zero bytes @@ -635,6 +674,19 @@ that were written; it may be less than len.

                          +

                          blocking-write-zeroes: func

                          +

                          Write multiple zero bytes to a stream, with blocking.

                          +

                          This is similar to write-zeroes, except that it blocks until at least +one byte can be written.

                          +
                          Params
                          + +
                          Return values
                          +

                          splice: func

                          Read from one stream and write to another.

                          This function returns the number of bytes transferred; it may be less @@ -651,6 +703,20 @@ read from the input stream has been written to the output stream.

                          +

                          blocking-splice: func

                          +

                          Read from one stream and write to another, with blocking.

                          +

                          This is similar to splice, except that it blocks until at least +one byte can be read.

                          +
                          Params
                          + +
                          Return values
                          +

                          forward: func

                          Forward the entire contents of an input stream to an output stream.

                          This function repeatedly reads from the input stream and writes diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index 9fa533efe..c1567fd4c 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -32,8 +32,8 @@ default interface streams { /// Read bytes from a stream. /// /// This function returns a list of bytes containing the data that was - /// read, along with a bool indicating whether the end of the stream - /// was reached. The returned list will contain up to `len` bytes; it + /// read, along with a bool which, when true, indicates that the end of the + /// stream was reached. The returned list will contain up to `len` bytes; it /// may return fewer than requested, but not more. /// /// Once a stream has reached the end, subsequent calls to read or @@ -53,6 +53,16 @@ default interface streams { len: u64 ) -> result, bool>, stream-error> + /// Read bytes from a stream, with blocking. + /// + /// This is similar to `read`, except that it blocks until at least one + /// byte can be read. + blocking-read: func( + this: input-stream, + /// The maximum number of bytes to read + len: u64 + ) -> result, bool>, stream-error> + /// Skip bytes from a stream. /// /// This is similar to the `read` function, but avoids copying the @@ -71,6 +81,16 @@ default interface streams { len: u64, ) -> result, stream-error> + /// Skip bytes from a stream, with blocking. + /// + /// This is similar to `skip`, except that it blocks until at least one + /// byte can be consumed. + blocking-skip: func( + this: input-stream, + /// The maximum number of bytes to skip. + len: u64, + ) -> result, stream-error> + /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been /// closed. @@ -109,6 +129,16 @@ default interface streams { buf: list ) -> result + /// Write bytes to a stream, with blocking. + /// + /// This is similar to `write`, except that it blocks until at least one + /// byte can be written. + blocking-write: func( + this: output-stream, + /// Data to write + buf: list + ) -> result + /// Write multiple zero bytes to a stream. /// /// This function returns a `u64` indicating the number of zero bytes @@ -119,6 +149,16 @@ default interface streams { len: u64 ) -> result + /// Write multiple zero bytes to a stream, with blocking. + /// + /// This is similar to `write-zeroes`, except that it blocks until at least + /// one byte can be written. + blocking-write-zeroes: func( + this: output-stream, + /// The number of zero bytes to write + len: u64 + ) -> result + /// Read from one stream and write to another. /// /// This function returns the number of bytes transferred; it may be less @@ -134,6 +174,18 @@ default interface streams { len: u64, ) -> result, stream-error> + /// Read from one stream and write to another, with blocking. + /// + /// This is similar to `splice`, except that it blocks until at least + /// one byte can be read. + blocking-splice: func( + this: output-stream, + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result, stream-error> + /// Forward the entire contents of an input stream to an output stream. /// /// This function repeatedly reads from the input stream and writes From 93a2b9651f2e069a983059614bc760188baf5a40 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 Mar 2023 14:30:02 -0800 Subject: [PATCH 1103/1772] Remove the reactor world for now. --- proposals/cli/reactor.md | 2562 --------------------------------- proposals/cli/wit/reactor.wit | 21 - 2 files changed, 2583 deletions(-) delete mode 100644 proposals/cli/reactor.md delete mode 100644 proposals/cli/wit/reactor.wit diff --git a/proposals/cli/reactor.md b/proposals/cli/reactor.md deleted file mode 100644 index 64a8a9c55..000000000 --- a/proposals/cli/reactor.md +++ /dev/null @@ -1,2562 +0,0 @@ -

                          World reactor

                          - -

                          Import interface wall-clock

                          -

                          WASI Wall Clock is a clock API intended to let users query the current -time. The name "wall" makes an analogy to a "clock on the wall", which -is not necessarily monotonic as it may be reset.

                          -

                          It is intended to be portable at least between Unix-family platforms and -Windows.

                          -
                          -

                          Types

                          -

                          type wall-clock

                          -

                          u32

                          -

                          A wall clock is a clock which measures the date and time according to -some external reference. -

                          External references may be reset, so this clock is not necessarily -monotonic, making it unsuitable for measuring elapsed time.

                          -

                          It is intended for reporting the current date and time for humans.

                          -

                          This represents a resource.

                          -

                          record datetime

                          -

                          A time and date in seconds plus nanoseconds.

                          -
                          Record Fields
                          - -
                          -

                          Functions

                          -

                          now: func

                          -

                          Read the current value of the clock.

                          -

                          This clock is not monotonic, therefore calling this function repeatedly -will not necessarily produce a sequence of non-decreasing values.

                          -

                          The returned timestamps represent the number of seconds since -1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, -also known as Unix Time.

                          -

                          The nanoseconds field of the output is always less than 1000000000.

                          -
                          Params
                          - -
                          Return values
                          - -

                          resolution: func

                          -

                          Query the resolution of the clock.

                          -

                          The nanoseconds field of the output is always less than 1000000000.

                          -
                          Params
                          - -
                          Return values
                          - -

                          drop-wall-clock: func

                          -

                          Dispose of the specified wall-clock, after which it may no longer -be used.

                          -
                          Params
                          - -

                          Import interface poll

                          -

                          A poll API intended to let users wait for I/O events on multiple handles -at once.

                          -
                          -

                          Types

                          -

                          type pollable

                          -

                          u32

                          -

                          A "pollable" handle. -

                          This is conceptually represents a stream<_, _>, or in other words, -a stream that one can wait on, repeatedly, but which does not itself -produce any data. It's temporary scaffolding until component-model's -async features are ready.

                          -

                          And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

                          -

                          pollable lifetimes are not automatically managed. Users must ensure -that they do not outlive the resource they reference.

                          -

                          This represents a resource.

                          -
                          -

                          Functions

                          -

                          drop-pollable: func

                          -

                          Dispose of the specified pollable, after which it may no longer -be used.

                          -
                          Params
                          - -

                          poll-oneoff: func

                          -

                          Poll for completion on a set of pollables.

                          -

                          The "oneoff" in the name refers to the fact that this function must do a -linear scan through the entire list of subscriptions, which may be -inefficient if the number is large and the same subscriptions are used -many times. In the future, this is expected to be obsoleted by the -component model async proposal, which will include a scalable waiting -facility.

                          -

                          Note that the return type would ideally be list<bool>, but that would -be more difficult to polyfill given the current state of wit-bindgen. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 -for details. For now, we use zero to mean "not ready" and non-zero to -mean "ready".

                          -
                          Params
                          - -
                          Return values
                          -
                            -
                          • list<u8>
                          • -
                          -

                          Import interface monotonic-clock

                          -

                          WASI Monotonic Clock is a clock API intended to let users measure elapsed -time.

                          -

                          It is intended to be portable at least between Unix-family platforms and -Windows.

                          -
                          -

                          Types

                          -

                          type pollable

                          -

                          pollable

                          -

                          -#### `type monotonic-clock` -`u32` -

                          A monotonic clock is a clock which has an unspecified initial value, and -successive reads of the clock will produce non-decreasing values. -

                          It is intended for measuring elapsed time.

                          -

                          This represents a resource.

                          -

                          type instant

                          -

                          u64

                          -

                          A timestamp in nanoseconds. -


                          -

                          Functions

                          -

                          now: func

                          -

                          Read the current value of the clock.

                          -

                          The clock is monotonic, therefore calling this function repeatedly will -produce a sequence of non-decreasing values.

                          -
                          Params
                          - -
                          Return values
                          - -

                          resolution: func

                          -

                          Query the resolution of the clock.

                          -
                          Params
                          - -
                          Return values
                          - -

                          subscribe: func

                          -

                          Create a pollable which will resolve once the specified time has been -reached.

                          -
                          Params
                          - -
                          Return values
                          - -

                          drop-monotonic-clock: func

                          -

                          Dispose of the specified monotonic-clock, after which it may no longer -be used.

                          -
                          Params
                          - -

                          Import interface instance-wall-clock

                          -

                          This interfaces proves a clock handles for wall clock, suitable for -general-purpose application needs.

                          -
                          -

                          Types

                          -

                          type wall-clock

                          -

                          wall-clock

                          -

                          ----- -

                          Functions

                          -

                          instance-wall-clock: func

                          -

                          Return a handle to a wall clock, suitable for general-purpose -application needs.

                          -

                          This allocates a new handle, so applications with frequent need of a -clock handle should call this function once and reuse the handle -instead of calling this function each time.

                          -

                          This represents a value import.

                          -
                          Return values
                          - -

                          Import interface instance-monotonic-clock

                          -

                          This interfaces proves a clock handles for monotonic clock, suitable for -general-purpose application needs.

                          -
                          -

                          Types

                          -

                          type monotonic-clock

                          -

                          monotonic-clock

                          -

                          ----- -

                          Functions

                          -

                          instance-monotonic-clock: func

                          -

                          Return a handle to a monotonic clock, suitable for general-purpose -application needs.

                          -

                          This allocates a new handle, so applications with frequent need of a -clock handle should call this function once and reuse the handle -instead of calling this function each time.

                          -

                          This represents a value import.

                          -
                          Return values
                          - -

                          Import interface timezone

                          -
                          -

                          Types

                          -

                          type datetime

                          -

                          datetime

                          -

                          -#### `record timezone-display` -

                          Information useful for displaying the timezone of a specific datetime.

                          -

                          This information may vary within a single timezone to reflect daylight -saving time adjustments.

                          -
                          Record Fields
                          -
                            -
                          • -

                            utc-offset: s32

                            -

                            The number of seconds difference between UTC time and the local -time of the timezone. -

                            The returned value will always be less than 86400 which is the -number of seconds in a day (246060).

                            -

                            In implementations that do not expose an actual time zone, this -should return 0.

                            -
                          • -
                          • -

                            name: string

                            -

                            The abbreviated name of the timezone to display to a user. The name -`UTC` indicates Coordinated Universal Time. Otherwise, this should -reference local standards for the name of the time zone. -

                            In implementations that do not expose an actual time zone, this -should be the string UTC.

                            -

                            In time zones that do not have an applicable name, a formatted -representation of the UTC offset may be returned, such as -04:00.

                            -
                          • -
                          • -

                            in-daylight-saving-time: bool

                            -

                            Whether daylight saving time is active. -

                            In implementations that do not expose an actual time zone, this -should return false.

                            -
                          • -
                          -

                          type timezone

                          -

                          u32

                          -

                          A timezone. -

                          In timezones that recognize daylight saving time, also known as daylight -time and summer time, the information returned from the functions varies -over time to reflect these adjustments.

                          -

                          This represents a resource.

                          -
                          -

                          Functions

                          -

                          display: func

                          -

                          Return information needed to display the given datetime. This includes -the UTC offset, the time zone name, and a flag indicating whether -daylight saving time is active.

                          -

                          If the timezone cannot be determined for the given datetime, return a -timezone-display for UTC with a utc-offset of 0 and no daylight -saving time.

                          -
                          Params
                          - -
                          Return values
                          - -

                          utc-offset: func

                          -

                          The same as display, but only return the UTC offset.

                          -
                          Params
                          - -
                          Return values
                          -
                            -
                          • s32
                          • -
                          -

                          drop-timezone: func

                          -

                          Dispose of the specified input-stream, after which it may no longer -be used.

                          -
                          Params
                          - -

                          Import interface streams

                          -

                          WASI I/O is an I/O abstraction API which is currently focused on providing -stream types.

                          -

                          In the future, the component model is expected to add built-in stream types; -when it does, they are expected to subsume this API.

                          -
                          -

                          Types

                          -

                          type pollable

                          -

                          pollable

                          -

                          -#### `record stream-error` -

                          An error type returned from a stream operation. Currently this -doesn't provide any additional information.

                          -
                          Record Fields
                          -

                          type output-stream

                          -

                          u32

                          -

                          An output bytestream. In the future, this will be replaced by handle -types. -

                          And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

                          -

                          This represents a resource.

                          -

                          type input-stream

                          -

                          u32

                          -

                          An input bytestream. In the future, this will be replaced by handle -types. -

                          And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

                          -

                          This represents a resource.

                          -
                          -

                          Functions

                          -

                          read: func

                          -

                          Read bytes from a stream.

                          -

                          This function returns a list of bytes containing the data that was -read, along with a bool indicating whether the end of the stream -was reached. The returned list will contain up to len bytes; it -may return fewer than requested, but not more.

                          -

                          Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

                          -

                          If len is 0, it represents a request to read 0 bytes, which should -always succeed, assuming the stream hasn't reached its end yet, and -return an empty list.

                          -

                          The len here is a u64, but some callees may not be able to allocate -a buffer as large as that would imply. -FIXME: describe what happens if allocation fails.

                          -
                          Params
                          - -
                          Return values
                          - -

                          skip: func

                          -

                          Skip bytes from a stream.

                          -

                          This is similar to the read function, but avoids copying the -bytes into the instance.

                          -

                          Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

                          -

                          This function returns the number of bytes skipped, along with a bool -indicating whether the end of the stream was reached. The returned -value will be at most len; it may be less.

                          -
                          Params
                          - -
                          Return values
                          - -

                          subscribe-to-input-stream: func

                          -

                          Create a pollable which will resolve once either the specified stream -has bytes available to read or the other end of the stream has been -closed.

                          -
                          Params
                          - -
                          Return values
                          - -

                          drop-input-stream: func

                          -

                          Dispose of the specified input-stream, after which it may no longer -be used.

                          -
                          Params
                          - -

                          write: func

                          -

                          Write bytes to a stream.

                          -

                          This function returns a u64 indicating the number of bytes from -buf that were written; it may be less than the full list.

                          -
                          Params
                          - -
                          Return values
                          - -

                          write-zeroes: func

                          -

                          Write multiple zero bytes to a stream.

                          -

                          This function returns a u64 indicating the number of zero bytes -that were written; it may be less than len.

                          -
                          Params
                          - -
                          Return values
                          - -

                          splice: func

                          -

                          Read from one stream and write to another.

                          -

                          This function returns the number of bytes transferred; it may be less -than len.

                          -
                          Params
                          - -
                          Return values
                          - -

                          forward: func

                          -

                          Forward the entire contents of an input stream to an output stream.

                          -

                          This function repeatedly reads from the input stream and writes -the data to the output stream, until the end of the input stream -is reached, or an error is encountered.

                          -

                          This function returns the number of bytes transferred.

                          -
                          Params
                          - -
                          Return values
                          - -

                          subscribe-to-output-stream: func

                          -

                          Create a pollable which will resolve once either the specified stream -is ready to accept bytes or the other end of the stream has been closed.

                          -
                          Params
                          - -
                          Return values
                          - -

                          drop-output-stream: func

                          -

                          Dispose of the specified output-stream, after which it may no longer -be used.

                          -
                          Params
                          - -

                          Import interface filesystem

                          -

                          WASI filesystem is a filesystem API primarily intended to let users run WASI -programs that access their files on their existing filesystems, without -significant overhead.

                          -

                          It is intended to be roughly portable between Unix-family platforms and -Windows, though it does not hide many of the major differences.

                          -

                          Paths are passed as interface-type strings, meaning they must consist of -a sequence of Unicode Scalar Values (USVs). Some filesystems may contain -paths which are not accessible by this API.

                          -

                          The directory separator in WASI is always the forward-slash (/).

                          -

                          All paths in WASI are relative paths, and are interpreted relative to a -descriptor referring to a base directory. If a path argument to any WASI -function starts with /, or if any step of resolving a path, including -.. and symbolic link steps, reaches a directory outside of the base -directory, or reaches a symlink to an absolute or rooted path in the -underlying filesystem, the function fails with error-code::not-permitted.

                          -
                          -

                          Types

                          -

                          type input-stream

                          -

                          input-stream

                          -

                          -#### `type output-stream` -[`output-stream`](#output_stream) -

                          -#### `type datetime` -[`datetime`](#datetime) -

                          -#### `flags path-flags` -

                          Flags determining the method of how paths are resolved.

                          -
                          Flags members
                          -
                            -
                          • symlink-follow:

                            As long as the resolved path corresponds to a symbolic link, it is -expanded. -

                          • -
                          -

                          flags open-flags

                          -

                          Open flags used by open-at.

                          -
                          Flags members
                          -
                            -
                          • -

                            create:

                            -

                            Create file if it does not exist, similar to `O_CREAT` in POSIX. -

                          • -
                          • -

                            directory:

                            -

                            Fail if not a directory, similar to `O_DIRECTORY` in POSIX. -

                          • -
                          • -

                            exclusive:

                            -

                            Fail if file already exists, similar to `O_EXCL` in POSIX. -

                          • -
                          • -

                            truncate:

                            -

                            Truncate file to size 0, similar to `O_TRUNC` in POSIX. -

                          • -
                          -

                          flags modes

                          -

                          Permissions mode used by open-at, change-file-permissions-at, and -similar.

                          -
                          Flags members
                          -
                            -
                          • -

                            readable:

                            -

                            True if the resource is considered readable by the containing -filesystem. -

                          • -
                          • -

                            writeable:

                            -

                            True if the resource is considered writeable by the containing -filesystem. -

                          • -
                          • -

                            executable:

                            -

                            True if the resource is considered executable by the containing -filesystem. This does not apply to directories. -

                          • -
                          -

                          type link-count

                          -

                          u64

                          -

                          Number of hard links to an inode. -

                          type inode

                          -

                          u64

                          -

                          Filesystem object serial number that is unique within its file system. -

                          type filesize

                          -

                          u64

                          -

                          File size or length of a region within a file. -

                          enum error-code

                          -

                          Error codes returned by functions, similar to errno in POSIX. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX.

                          -
                          Enum Cases
                          -
                            -
                          • -

                            access

                            -

                            Permission denied, similar to `EACCES` in POSIX. -

                          • -
                          • -

                            would-block

                            -

                            Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. -

                          • -
                          • -

                            already

                            -

                            Connection already in progress, similar to `EALREADY` in POSIX. -

                          • -
                          • -

                            bad-descriptor

                            -

                            Bad descriptor, similar to `EBADF` in POSIX. -

                          • -
                          • -

                            busy

                            -

                            Device or resource busy, similar to `EBUSY` in POSIX. -

                          • -
                          • -

                            deadlock

                            -

                            Resource deadlock would occur, similar to `EDEADLK` in POSIX. -

                          • -
                          • -

                            quota

                            -

                            Storage quota exceeded, similar to `EDQUOT` in POSIX. -

                          • -
                          • -

                            exist

                            -

                            File exists, similar to `EEXIST` in POSIX. -

                          • -
                          • -

                            file-too-large

                            -

                            File too large, similar to `EFBIG` in POSIX. -

                          • -
                          • -

                            illegal-byte-sequence

                            -

                            Illegal byte sequence, similar to `EILSEQ` in POSIX. -

                          • -
                          • -

                            in-progress

                            -

                            Operation in progress, similar to `EINPROGRESS` in POSIX. -

                          • -
                          • -

                            interrupted

                            -

                            Interrupted function, similar to `EINTR` in POSIX. -

                          • -
                          • -

                            invalid

                            -

                            Invalid argument, similar to `EINVAL` in POSIX. -

                          • -
                          • -

                            io

                            -

                            I/O error, similar to `EIO` in POSIX. -

                          • -
                          • -

                            is-directory

                            -

                            Is a directory, similar to `EISDIR` in POSIX. -

                          • -
                          • -

                            loop

                            -

                            Too many levels of symbolic links, similar to `ELOOP` in POSIX. -

                          • -
                          • -

                            too-many-links

                            -

                            Too many links, similar to `EMLINK` in POSIX. -

                          • -
                          • -

                            message-size

                            -

                            Message too large, similar to `EMSGSIZE` in POSIX. -

                          • -
                          • -

                            name-too-long

                            -

                            Filename too long, similar to `ENAMETOOLONG` in POSIX. -

                          • -
                          • -

                            no-device

                            -

                            No such device, similar to `ENODEV` in POSIX. -

                          • -
                          • -

                            no-entry

                            -

                            No such file or directory, similar to `ENOENT` in POSIX. -

                          • -
                          • -

                            no-lock

                            -

                            No locks available, similar to `ENOLCK` in POSIX. -

                          • -
                          • -

                            insufficient-memory

                            -

                            Not enough space, similar to `ENOMEM` in POSIX. -

                          • -
                          • -

                            insufficient-space

                            -

                            No space left on device, similar to `ENOSPC` in POSIX. -

                          • -
                          • -

                            not-directory

                            -

                            Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. -

                          • -
                          • -

                            not-empty

                            -

                            Directory not empty, similar to `ENOTEMPTY` in POSIX. -

                          • -
                          • -

                            not-recoverable

                            -

                            State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. -

                          • -
                          • -

                            unsupported

                            -

                            Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. -

                          • -
                          • -

                            no-tty

                            -

                            Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. -

                          • -
                          • -

                            no-such-device

                            -

                            No such device or address, similar to `ENXIO` in POSIX. -

                          • -
                          • -

                            overflow

                            -

                            Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. -

                          • -
                          • -

                            not-permitted

                            -

                            Operation not permitted, similar to `EPERM` in POSIX. -

                          • -
                          • -

                            pipe

                            -

                            Broken pipe, similar to `EPIPE` in POSIX. -

                          • -
                          • -

                            read-only

                            -

                            Read-only file system, similar to `EROFS` in POSIX. -

                          • -
                          • -

                            invalid-seek

                            -

                            Invalid seek, similar to `ESPIPE` in POSIX. -

                          • -
                          • -

                            text-file-busy

                            -

                            Text file busy, similar to `ETXTBSY` in POSIX. -

                          • -
                          • -

                            cross-device

                            -

                            Cross-device link, similar to `EXDEV` in POSIX. -

                          • -
                          -

                          type directory-entry-stream

                          -

                          u32

                          -

                          A stream of directory entries. -

                          This represents a stream of dir-entry.

                          -

                          type device

                          -

                          u64

                          -

                          Identifier for a device containing a file system. Can be used in -combination with `inode` to uniquely identify a file or directory in -the filesystem. -

                          enum descriptor-type

                          -

                          The type of a filesystem object referenced by a descriptor.

                          -

                          Note: This was called filetype in earlier versions of WASI.

                          -
                          Enum Cases
                          -
                            -
                          • -

                            unknown

                            -

                            The type of the descriptor or file is unknown or is different from -any of the other types specified. -

                          • -
                          • -

                            block-device

                            -

                            The descriptor refers to a block device inode. -

                          • -
                          • -

                            character-device

                            -

                            The descriptor refers to a character device inode. -

                          • -
                          • -

                            directory

                            -

                            The descriptor refers to a directory inode. -

                          • -
                          • -

                            fifo

                            -

                            The descriptor refers to a named pipe. -

                          • -
                          • -

                            symbolic-link

                            -

                            The file refers to a symbolic link inode. -

                          • -
                          • -

                            regular-file

                            -

                            The descriptor refers to a regular file inode. -

                          • -
                          • -

                            socket

                            -

                            The descriptor refers to a socket. -

                          • -
                          -

                          record directory-entry

                          -

                          A directory entry.

                          -
                          Record Fields
                          -
                            -
                          • -

                            inode: option<inode>

                            -

                            The serial number of the object referred to by this directory entry. -May be none if the inode value is not known. -

                            When this is none, libc implementations might do an extra stat-at -call to retrieve the inode number to fill their d_ino fields, so -implementations which can set this to a non-none value should do so.

                            -
                          • -
                          • -

                            type: descriptor-type

                            -

                            The type of the file referred to by this directory entry. -

                          • -
                          • -

                            name: string

                            -

                            The name of the object. -

                          • -
                          -

                          flags descriptor-flags

                          -

                          Descriptor flags.

                          -

                          Note: This was called fdflags in earlier versions of WASI.

                          -
                          Flags members
                          -
                            -
                          • -

                            read:

                            -

                            Read mode: Data can be read. -

                          • -
                          • -

                            write:

                            -

                            Write mode: Data can be written to. -

                          • -
                          • -

                            non-blocking:

                            -

                            Requests non-blocking operation. -

                            When this flag is enabled, functions may return immediately with an -error-code::would-block error code in situations where they would -otherwise block. However, this non-blocking behavior is not -required. Implementations are permitted to ignore this flag and -block. This is similar to O_NONBLOCK in POSIX.

                            -
                          • -
                          • -

                            file-integrity-sync:

                            -

                            Request that writes be performed according to synchronized I/O file -integrity completion. The data stored in the file and the file's -metadata are synchronized. This is similar to `O_SYNC` in POSIX. -

                            The precise semantics of this operation have not yet been defined for -WASI. At this time, it should be interpreted as a request, and not a -requirement.

                            -
                          • -
                          • -

                            data-integrity-sync:

                            -

                            Request that writes be performed according to synchronized I/O data -integrity completion. Only the data stored in the file is -synchronized. This is similar to `O_DSYNC` in POSIX. -

                            The precise semantics of this operation have not yet been defined for -WASI. At this time, it should be interpreted as a request, and not a -requirement.

                            -
                          • -
                          • -

                            requested-write-sync:

                            -

                            Requests that reads be performed at the same level of integrety -requested for writes. This is similar to `O_RSYNC` in POSIX. -

                            The precise semantics of this operation have not yet been defined for -WASI. At this time, it should be interpreted as a request, and not a -requirement.

                            -
                          • -
                          • -

                            mutate-directory:

                            -

                            Mutating directories mode: Directory contents may be mutated. -

                            When this flag is unset on a descriptor, operations using the -descriptor which would create, rename, delete, modify the data or -metadata of filesystem objects, or obtain another handle which -would permit any of those, shall fail with error-code::read-only if -they would otherwise succeed.

                            -

                            This may only be set on directories.

                            -
                          • -
                          -

                          type descriptor

                          -

                          u32

                          -

                          A descriptor is a reference to a filesystem object, which may be a file, -directory, named pipe, special file, or other object on which filesystem -calls may be made. -

                          This represents a resource.

                          -

                          variant new-timestamp

                          -

                          When setting a timestamp, this gives the value to set it to.

                          -
                          Variant Cases
                          -
                            -
                          • -

                            no-change

                            -

                            Leave the timestamp set to its previous value. -

                          • -
                          • -

                            now

                            -

                            Set the timestamp to the current time of the system clock associated -with the filesystem. -

                          • -
                          • -

                            timestamp: datetime

                            -

                            Set the timestamp to the given value. -

                          • -
                          -

                          record descriptor-stat

                          -

                          File attributes.

                          -

                          Note: This was called filestat in earlier versions of WASI.

                          -
                          Record Fields
                          - -

                          enum advice

                          -

                          File or memory access pattern advisory information.

                          -
                          Enum Cases
                          -
                            -
                          • -

                            normal

                            -

                            The application has no advice to give on its behavior with respect -to the specified data. -

                          • -
                          • -

                            sequential

                            -

                            The application expects to access the specified data sequentially -from lower offsets to higher offsets. -

                          • -
                          • -

                            random

                            -

                            The application expects to access the specified data in a random -order. -

                          • -
                          • -

                            will-need

                            -

                            The application expects to access the specified data in the near -future. -

                          • -
                          • -

                            dont-need

                            -

                            The application expects that it will not access the specified data -in the near future. -

                          • -
                          • -

                            no-reuse

                            -

                            The application expects to access the specified data once and then -not reuse it thereafter. -

                          • -
                          -
                          -

                          Functions

                          -

                          read-via-stream: func

                          -

                          Return a stream for reading from a file.

                          -

                          Multiple read, write, and append streams may be active on the same open -file and they do not interfere with each other.

                          -

                          Note: This allows using read-stream, which is similar to read in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          write-via-stream: func

                          -

                          Return a stream for writing to a file.

                          -

                          Note: This allows using write-stream, which is similar to write in -POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          append-via-stream: func

                          -

                          Return a stream for appending to a file.

                          -

                          Note: This allows using write-stream, which is similar to write with -O_APPEND in in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          advise: func

                          -

                          Provide file advisory information on a descriptor.

                          -

                          This is similar to posix_fadvise in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          sync-data: func

                          -

                          Synchronize the data of a file to disk.

                          -

                          This function succeeds with no effect if the file descriptor is not -opened for writing.

                          -

                          Note: This is similar to fdatasync in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          get-flags: func

                          -

                          Get flags associated with a descriptor.

                          -

                          Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

                          -

                          Note: This returns the value that was the fs_flags value returned -from fdstat_get in earlier versions of WASI.

                          -
                          Params
                          - -
                          Return values
                          - -

                          get-type: func

                          -

                          Get the dynamic type of a descriptor.

                          -

                          Note: This returns the same value as the type field of the fd-stat -returned by stat, stat-at and similar.

                          -

                          Note: This returns similar flags to the st_mode & S_IFMT value provided -by fstat in POSIX.

                          -

                          Note: This returns the value that was the fs_filetype value returned -from fdstat_get in earlier versions of WASI.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-flags: func

                          -

                          Set status flags associated with a descriptor.

                          -

                          This function may only change the non-blocking flag.

                          -

                          Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

                          -

                          Note: This was called fd_fdstat_set_flags in earlier versions of WASI.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-size: func

                          -

                          Adjust the size of an open file. If this increases the file's size, the -extra bytes are filled with zeros.

                          -

                          Note: This was called fd_filestat_set_size in earlier versions of WASI.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-times: func

                          -

                          Adjust the timestamps of an open file or directory.

                          -

                          Note: This is similar to futimens in POSIX.

                          -

                          Note: This was called fd_filestat_set_times in earlier versions of WASI.

                          -
                          Params
                          - -
                          Return values
                          - -

                          read: func

                          -

                          Read from a descriptor, without using and updating the descriptor's offset.

                          -

                          This function returns a list of bytes containing the data that was -read, along with a bool which, when true, indicates that the end of the -file was reached. The returned list will contain up to length bytes; it -may return fewer than requested, if the end of the file is reached or -if the I/O operation is interrupted.

                          -

                          In the future, this may change to return a stream<u8, error-code>.

                          -

                          Note: This is similar to pread in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          write: func

                          -

                          Write to a descriptor, without using and updating the descriptor's offset.

                          -

                          It is valid to write past the end of a file; the file is extended to the -extent of the write, with bytes between the previous end and the start of -the write set to zero.

                          -

                          In the future, this may change to take a stream<u8, error-code>.

                          -

                          Note: This is similar to pwrite in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          read-directory: func

                          -

                          Read directory entries from a directory.

                          -

                          On filesystems where directories contain entries referring to themselves -and their parents, often named . and .. respectively, these entries -are omitted.

                          -

                          This always returns a new stream which starts at the beginning of the -directory. Multiple streams may be active on the same directory, and they -do not interfere with each other.

                          -
                          Params
                          - -
                          Return values
                          - -

                          sync: func

                          -

                          Synchronize the data and metadata of a file to disk.

                          -

                          This function succeeds with no effect if the file descriptor is not -opened for writing.

                          -

                          Note: This is similar to fsync in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          create-directory-at: func

                          -

                          Create a directory.

                          -

                          Note: This is similar to mkdirat in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          stat: func

                          -

                          Return the attributes of an open file or directory.

                          -

                          Note: This is similar to fstat in POSIX.

                          -

                          Note: This was called fd_filestat_get in earlier versions of WASI.

                          -
                          Params
                          - -
                          Return values
                          - -

                          stat-at: func

                          -

                          Return the attributes of a file or directory.

                          -

                          Note: This is similar to fstatat in POSIX.

                          -

                          Note: This was called path_filestat_get in earlier versions of WASI.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-times-at: func

                          -

                          Adjust the timestamps of a file or directory.

                          -

                          Note: This is similar to utimensat in POSIX.

                          -

                          Note: This was called path_filestat_set_times in earlier versions of -WASI.

                          -
                          Params
                          - -
                          Return values
                          - -

                          link-at: func

                          -

                          Create a hard link.

                          -

                          Note: This is similar to linkat in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          open-at: func

                          -

                          Open a file or directory.

                          -

                          The returned descriptor is not guaranteed to be the lowest-numbered -descriptor not currently open/ it is randomized to prevent applications -from depending on making assumptions about indexes, since this is -error-prone in multi-threaded contexts. The returned descriptor is -guaranteed to be less than 2**31.

                          -

                          If flags contains descriptor-flags::mutate-directory, and the base -descriptor doesn't have descriptor-flags::mutate-directory set, -open-at fails with error-code::read-only.

                          -

                          If flags contains write or mutate-directory, or open-flags -contains truncate or create, and the base descriptor doesn't have -descriptor-flags::mutate-directory set, open-at fails with -error-code::read-only.

                          -

                          Note: This is similar to openat in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          readlink-at: func

                          -

                          Read the contents of a symbolic link.

                          -

                          If the contents contain an absolute or rooted path in the underlying -filesystem, this function fails with error-code::not-permitted.

                          -

                          Note: This is similar to readlinkat in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          remove-directory-at: func

                          -

                          Remove a directory.

                          -

                          Return error-code::not-empty if the directory is not empty.

                          -

                          Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          rename-at: func

                          -

                          Rename a filesystem object.

                          -

                          Note: This is similar to renameat in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          symlink-at: func

                          -

                          Create a symbolic link (also known as a "symlink").

                          -

                          If old-path starts with /, the function fails with -error-code::not-permitted.

                          -

                          Note: This is similar to symlinkat in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          unlink-file-at: func

                          -

                          Unlink a filesystem object that is not a directory.

                          -

                          Return error-code::is-directory if the path refers to a directory. -Note: This is similar to unlinkat(fd, path, 0) in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          change-file-permissions-at: func

                          -

                          Change the permissions of a filesystem object that is not a directory.

                          -

                          Note that the ultimate meanings of these permissions is -filesystem-specific.

                          -

                          Note: This is similar to fchmodat in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          change-directory-permissions-at: func

                          -

                          Change the permissions of a directory.

                          -

                          Note that the ultimate meanings of these permissions is -filesystem-specific.

                          -

                          Unlike in POSIX, the executable flag is not reinterpreted as a "search" -flag. read on a directory implies readability and searchability, and -execute is not valid for directories.

                          -

                          Note: This is similar to fchmodat in POSIX.

                          -
                          Params
                          - -
                          Return values
                          - -

                          lock-shared: func

                          -

                          Request a shared advisory lock for an open file.

                          -

                          This requests a shared lock; more than one shared lock can be held for -a file at the same time.

                          -

                          If the open file has an exclusive lock, this function downgrades the lock -to a shared lock. If it has a shared lock, this function has no effect.

                          -

                          This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

                          -

                          It is unspecified how shared locks interact with locks acquired by -non-WASI programs.

                          -

                          This function blocks until the lock can be acquired.

                          -

                          Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

                          -

                          Note: This is similar to flock(fd, LOCK_SH) in Unix.

                          -
                          Params
                          - -
                          Return values
                          - -

                          lock-exclusive: func

                          -

                          Request an exclusive advisory lock for an open file.

                          -

                          This requests an exclusive lock; no other locks may be held for the -file while an exclusive lock is held.

                          -

                          If the open file has a shared lock and there are no exclusive locks held -for the file, this function upgrades the lock to an exclusive lock. If the -open file already has an exclusive lock, this function has no effect.

                          -

                          This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

                          -

                          It is unspecified whether this function succeeds if the file descriptor -is not opened for writing. It is unspecified how exclusive locks interact -with locks acquired by non-WASI programs.

                          -

                          This function blocks until the lock can be acquired.

                          -

                          Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

                          -

                          Note: This is similar to flock(fd, LOCK_EX) in Unix.

                          -
                          Params
                          - -
                          Return values
                          - -

                          try-lock-shared: func

                          -

                          Request a shared advisory lock for an open file.

                          -

                          This requests a shared lock; more than one shared lock can be held for -a file at the same time.

                          -

                          If the open file has an exclusive lock, this function downgrades the lock -to a shared lock. If it has a shared lock, this function has no effect.

                          -

                          This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

                          -

                          It is unspecified how shared locks interact with locks acquired by -non-WASI programs.

                          -

                          This function returns error-code::would-block if the lock cannot be -acquired.

                          -

                          Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

                          -

                          Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

                          -
                          Params
                          - -
                          Return values
                          - -

                          try-lock-exclusive: func

                          -

                          Request an exclusive advisory lock for an open file.

                          -

                          This requests an exclusive lock; no other locks may be held for the -file while an exclusive lock is held.

                          -

                          If the open file has a shared lock and there are no exclusive locks held -for the file, this function upgrades the lock to an exclusive lock. If the -open file already has an exclusive lock, this function has no effect.

                          -

                          This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

                          -

                          It is unspecified whether this function succeeds if the file descriptor -is not opened for writing. It is unspecified how exclusive locks interact -with locks acquired by non-WASI programs.

                          -

                          This function returns error-code::would-block if the lock cannot be -acquired.

                          -

                          Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

                          -

                          Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

                          -
                          Params
                          - -
                          Return values
                          - -

                          unlock: func

                          -

                          Release a shared or exclusive lock on an open file.

                          -

                          Note: This is similar to flock(fd, LOCK_UN) in Unix.

                          -
                          Params
                          - -
                          Return values
                          - -

                          drop-descriptor: func

                          -

                          Dispose of the specified descriptor, after which it may no longer -be used.

                          -
                          Params
                          - -

                          read-directory-entry: func

                          -

                          Read a single directory entry from a directory-entry-stream.

                          -
                          Params
                          - -
                          Return values
                          - -

                          drop-directory-entry-stream: func

                          -

                          Dispose of the specified directory-entry-stream, after which it may no longer -be used.

                          -
                          Params
                          - -

                          Import interface network

                          -
                          -

                          Types

                          -

                          type network

                          -

                          u32

                          -

                          An opaque resource that represents access to (a subset of) the network. -This enables context-based security for networking. -There is no need for this to map 1:1 to a physical network interface. -

                          FYI, In the future this will be replaced by handle types.

                          -

                          tuple ipv6-address

                          -
                          Tuple Fields
                          -
                            -
                          • 0: u16
                          • -
                          • 1: u16
                          • -
                          • 2: u16
                          • -
                          • 3: u16
                          • -
                          • 4: u16
                          • -
                          • 5: u16
                          • -
                          • 6: u16
                          • -
                          • 7: u16
                          • -
                          -

                          record ipv6-socket-address

                          -
                          Record Fields
                          - -

                          tuple ipv4-address

                          -
                          Tuple Fields
                          -
                            -
                          • 0: u8
                          • -
                          • 1: u8
                          • -
                          • 2: u8
                          • -
                          • 3: u8
                          • -
                          -

                          record ipv4-socket-address

                          -
                          Record Fields
                          - -

                          variant ip-socket-address

                          -
                          Variant Cases
                          - -

                          enum ip-address-family

                          -
                          Enum Cases
                          -
                            -
                          • -

                            ipv4

                            -

                            Similar to `AF_INET` in POSIX. -

                          • -
                          • -

                            ipv6

                            -

                            Similar to `AF_INET6` in POSIX. -

                          • -
                          -

                          variant ip-address

                          -
                          Variant Cases
                          - -

                          enum error

                          -
                          Enum Cases
                          - -
                          -

                          Functions

                          -

                          drop-network: func

                          -

                          Dispose of the specified network, after which it may no longer be used.

                          -

                          Note: this function is scheduled to be removed when Resources are natively supported in Wit.

                          -
                          Params
                          - -

                          Import interface instance-network

                          -

                          This interface provides a value-export of the default network handle..

                          -
                          -

                          Types

                          -

                          type network

                          -

                          network

                          -

                          ----- -

                          Functions

                          -

                          instance-network: func

                          -

                          Get a handle to the default network.

                          -
                          Return values
                          - -

                          Import interface ip-name-lookup

                          -
                          -

                          Types

                          -

                          type pollable

                          -

                          pollable

                          -

                          -#### `type network` -[`network`](#network) -

                          -#### `type error` -[`error`](#error) -

                          -#### `type ip-address` -[`ip-address`](#ip_address) -

                          -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) -

                          -#### `type resolve-address-stream` -`u32` -

                          ----- -

                          Functions

                          -

                          resolve-addresses: func

                          -

                          Resolve an internet host name to a list of IP addresses.

                          -

                          See the wasi-socket proposal README.md for a comparison with getaddrinfo.

                          -

                          Parameters:

                          -
                            -
                          • name: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted -to ASCII using IDNA encoding.
                          • -
                          • address-family: If provided, limit the results to addresses of this specific address family.
                          • -
                          • include-unavailable: When set to true, this function will also return addresses of which the runtime -thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on -systems without an active IPv6 interface. Notes:
                          • -
                          • Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address.
                          • -
                          • Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged.
                          • -
                          -

                          This function never blocks. It either immediately returns successfully with a resolve-address-stream -that can be used to (asynchronously) fetch the results. -Or it immediately fails whenever name is:

                          -
                            -
                          • empty
                          • -
                          • an IP address
                          • -
                          • a syntactically invalid domain name in another way
                          • -
                          -

                          References:

                          - -
                          Params
                          - -
                          Return values
                          - -

                          resolve-next-address: func

                          -

                          Returns the next address from the resolver.

                          -

                          This function should be called multiple times. On each call, it will -return the next address in connection order preference. If all -addresses have been exhausted, this function returns none. -After which, you should release the stream with drop-resolve-address-stream.

                          -

                          This function never returns IPv4-mapped IPv6 addresses.

                          -
                          Params
                          - -
                          Return values
                          - -

                          drop-resolve-address-stream: func

                          -

                          Dispose of the specified resolve-address-stream, after which it may no longer be used.

                          -

                          Note: this function is scheduled to be removed when Resources are natively supported in Wit.

                          -
                          Params
                          - -

                          non-blocking: func

                          -

                          Get/set the blocking mode of the stream.

                          -

                          By default a stream is in "blocking" mode, meaning that any function blocks and waits for its completion. -When switched to "non-blocking" mode, operations that would block return an again error. After which -the API consumer is expected to call subscribe and wait for completion using the wasi-poll module.

                          -

                          Note: these functions are here for WASI Preview2 only. -They're planned to be removed when future is natively supported in Preview3.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-non-blocking: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          subscribe: func

                          -

                          Create a pollable which will resolve once the stream is ready for I/O.

                          -

                          Note: this function is here for WASI Preview2 only. -It's planned to be removed when future is natively supported in Preview3.

                          -
                          Params
                          - -
                          Return values
                          - -

                          Import interface tcp

                          -
                          -

                          Types

                          -

                          type input-stream

                          -

                          input-stream

                          -

                          -#### `type output-stream` -[`output-stream`](#output_stream) -

                          -#### `type pollable` -[`pollable`](#pollable) -

                          -#### `type network` -[`network`](#network) -

                          -#### `type error` -[`error`](#error) -

                          -#### `type ip-socket-address` -[`ip-socket-address`](#ip_socket_address) -

                          -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) -

                          -#### `type tcp-socket` -`u32` -

                          A TCP socket handle. -

                          enum shutdown-type

                          -
                          Enum Cases
                          -
                            -
                          • -

                            receive

                            -

                            Similar to `SHUT_RD` in POSIX. -

                          • -
                          • -

                            send

                            -

                            Similar to `SHUT_WR` in POSIX. -

                          • -
                          • -

                            both

                            -

                            Similar to `SHUT_RDWR` in POSIX. -

                          • -
                          -
                          -

                          Functions

                          -

                          bind: func

                          -

                          Bind the socket to a specific network on the provided IP address and port.

                          -

                          If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which -network interface(s) to bind to. -If the TCP/UDP port is zero, the socket will be bound to a random free port.

                          -

                          When a socket is not explicitly bound, the first invocation to a listen or connect operation will -implicitly bind the socket.

                          -

                          Fails when:

                          -
                            -
                          • the socket is already bound.
                          • -
                          -

                          References

                          - -
                          Params
                          - -
                          Return values
                          - -

                          connect: func

                          -

                          Connect to a remote endpoint.

                          -

                          On success:

                          -
                            -
                          • the socket is transitioned into the Connection state
                          • -
                          • a pair of streams is returned that can be used to read & write to the connection
                          • -
                          -

                          Fails when:

                          -
                            -
                          • the socket is already bound to a different network.
                          • -
                          • the provided network does not allow connections to the specified endpoint.
                          • -
                          • the socket is already in the Connection or Listener state.
                          • -
                          • either the remote IP address or port is 0.
                          • -
                          -

                          References

                          - -
                          Params
                          - -
                          Return values
                          - -

                          listen: func

                          -

                          Start listening for new connections.

                          -

                          Transitions the socket into the Listener state.

                          -

                          Fails when:

                          -
                            -
                          • the socket is already bound to a different network.
                          • -
                          • the provided network does not allow listening on the specified address.
                          • -
                          • the socket is already in the Connection or Listener state.
                          • -
                          -

                          References

                          - -
                          Params
                          - -
                          Return values
                          - -

                          accept: func

                          -

                          Accept a new client socket.

                          -

                          The returned socket is bound and in the Connection state.

                          -

                          On success, this function returns the newly accepted client socket along with -a pair of streams that can be used to read & write to the connection.

                          -

                          Fails when this socket is not in the Listening state.

                          -

                          References:

                          - -
                          Params
                          - -
                          Return values
                          - -

                          local-address: func

                          -

                          Get the bound local address.

                          -

                          Returns an error if the socket is not bound.

                          -

                          References

                          - -
                          Params
                          - -
                          Return values
                          - -

                          remote-address: func

                          -

                          Get the bound remote address.

                          -

                          Fails when the socket is not in the Connection state.

                          -

                          References

                          - -
                          Params
                          - -
                          Return values
                          - -

                          address-family: func

                          -

                          Whether this is a IPv4 or IPv6 socket.

                          -

                          Equivalent to the SO_DOMAIN socket option.

                          -
                          Params
                          - -
                          Return values
                          - -

                          ipv6-only: func

                          -

                          Whether IPv4 compatibility (dual-stack) mode is disabled or not. -Implementations are not required to support dual-stack mode. Calling set-ipv6-only(false) might fail.

                          -

                          Fails when called on an IPv4 socket.

                          -

                          Equivalent to the IPV6_V6ONLY socket option.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-ipv6-only: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-listen-backlog-size: func

                          -

                          Hints the desired listen queue size. Implementations are free to ignore this.

                          -
                          Params
                          - -
                          Return values
                          - -

                          keep-alive: func

                          -

                          Equivalent to the SO_KEEPALIVE socket option.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-keep-alive: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          no-delay: func

                          -

                          Equivalent to the TCP_NODELAY socket option.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-no-delay: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          unicast-hop-limit: func

                          -

                          Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-unicast-hop-limit: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          receive-buffer-size: func

                          -

                          The kernel buffer space reserved for sends/receives on this socket.

                          -

                          Note #1: an implementation may choose to cap or round the buffer size when setting the value. -In other words, after setting a value, reading the same setting back may return a different value.

                          -

                          Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of -actual data to be sent/received by the application, because the kernel might also use the buffer space -for internal metadata structures.

                          -

                          Fails when this socket is in the Listening state.

                          -

                          Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-receive-buffer-size: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          send-buffer-size: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-send-buffer-size: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          non-blocking: func

                          -

                          Get/set the blocking mode of the socket.

                          -

                          By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. -When switched to "non-blocking" mode, operations that would block return an again error. After which -the API consumer is expected to call subscribe and wait for completion using the wasi-poll module.

                          -

                          Note: these functions are here for WASI Preview2 only. -They're planned to be removed when future is natively supported in Preview3.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-non-blocking: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          subscribe: func

                          -

                          Create a pollable which will resolve once the socket is ready for I/O.

                          -

                          Note: this function is here for WASI Preview2 only. -It's planned to be removed when future is natively supported in Preview3.

                          -
                          Params
                          - -
                          Return values
                          - -

                          shutdown: func

                          -

                          Gracefully shut down the connection.

                          -
                            -
                          • receive: the socket is not expecting to receive any more data from the peer. All subsequent read -operations on the input-stream associated with this socket will return an End Of Stream indication. -Any data still in the receive queue at time of calling shutdown will be discarded.
                          • -
                          • send: the socket is not expecting to send any more data to the peer. All subsequent write -operations on the output-stream associated with this socket will return an error.
                          • -
                          • both: same effect as receive & send combined.
                          • -
                          -

                          The shutdown function does not close the socket.

                          -

                          Fails when the socket is not in the Connection state.

                          -

                          References

                          - -
                          Params
                          - -
                          Return values
                          - -

                          drop-tcp-socket: func

                          -

                          Dispose of the specified tcp-socket, after which it may no longer be used.

                          -

                          Note: this function is scheduled to be removed when Resources are natively supported in Wit.

                          -
                          Params
                          - -

                          Import interface tcp-create-socket

                          -
                          -

                          Types

                          -

                          type network

                          -

                          network

                          -

                          -#### `type error` -[`error`](#error) -

                          -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) -

                          -#### `type tcp-socket` -[`tcp-socket`](#tcp_socket) -

                          ----- -

                          Functions

                          -

                          create-tcp-socket: func

                          -

                          Create a new TCP socket.

                          -

                          Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX.

                          -

                          This function does not require a network capability handle. This is considered to be safe because -at time of creation, the socket is not bound to any network yet. Up to the moment bind/listen/connect -is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                          -

                          References:

                          - -
                          Params
                          - -
                          Return values
                          - -

                          Import interface udp

                          -
                          -

                          Types

                          -

                          type pollable

                          -

                          pollable

                          -

                          -#### `type network` -[`network`](#network) -

                          -#### `type error` -[`error`](#error) -

                          -#### `type ip-socket-address` -[`ip-socket-address`](#ip_socket_address) -

                          -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) -

                          -#### `type udp-socket` -`u32` -

                          A UDP socket handle. -

                          record datagram

                          -
                          Record Fields
                          - -
                          -

                          Functions

                          -

                          bind: func

                          -

                          Bind the socket to a specific network on the provided IP address and port.

                          -

                          If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which -network interface(s) to bind to. -If the TCP/UDP port is zero, the socket will be bound to a random free port.

                          -

                          When a socket is not explicitly bound, the first invocation to a connect, send or receive operation will -implicitly bind the socket.

                          -

                          Fails when:

                          -
                            -
                          • the socket is already bound.
                          • -
                          -

                          References

                          - -
                          Params
                          - -
                          Return values
                          - -

                          connect: func

                          -

                          Set the destination address.

                          -

                          The local-address is updated based on the best network path to remote-address.

                          -

                          When a destination address is set:

                          -
                            -
                          • all receive operations will only return datagrams sent from the provided remote-address.
                          • -
                          • the send function can only be used to send to this destination.
                          • -
                          -

                          Note that this function does not generate any network traffic and the peer is not aware of this "connection".

                          -

                          Fails when:

                          -
                            -
                          • the socket is already bound to a different network.
                          • -
                          -

                          References

                          - -
                          Params
                          - -
                          Return values
                          - -

                          receive: func

                          -

                          Receive a message.

                          -

                          Returns:

                          -
                            -
                          • The sender address of the datagram
                          • -
                          • The number of bytes read.
                          • -
                          -

                          Fails when:

                          -
                            -
                          • the socket is not bound.
                          • -
                          -

                          References

                          - -
                          Params
                          - -
                          Return values
                          - -

                          send: func

                          -

                          Send a message to a specific destination address.

                          -

                          The remote address option is required. To send a message to the "connected" peer, -call remote-address to get their address.

                          -

                          Fails when:

                          -
                            -
                          • the socket is not bound. Unlike POSIX, this function does not perform an implicit bind.
                          • -
                          • the socket is in "connected" mode and the datagram.remote-address does not match the address passed to connect.
                          • -
                          -

                          References

                          - -
                          Params
                          - -
                          Return values
                          - -

                          local-address: func

                          -

                          Get the current bound address.

                          -

                          Returns an error if the socket is not bound.

                          -

                          References

                          - -
                          Params
                          - -
                          Return values
                          - -

                          remote-address: func

                          -

                          Get the address set with connect.

                          -

                          References

                          - -
                          Params
                          - -
                          Return values
                          - -

                          address-family: func

                          -

                          Whether this is a IPv4 or IPv6 socket.

                          -

                          Equivalent to the SO_DOMAIN socket option.

                          -
                          Params
                          - -
                          Return values
                          - -

                          ipv6-only: func

                          -

                          Whether IPv4 compatibility (dual-stack) mode is disabled or not. -Implementations are not required to support dual-stack mode, so calling set-ipv6-only(false) might fail.

                          -

                          Fails when called on an IPv4 socket.

                          -

                          Equivalent to the IPV6_V6ONLY socket option.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-ipv6-only: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          unicast-hop-limit: func

                          -

                          Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-unicast-hop-limit: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          receive-buffer-size: func

                          -

                          The kernel buffer space reserved for sends/receives on this socket.

                          -

                          Note #1: an implementation may choose to cap or round the buffer size when setting the value. -In other words, after setting a value, reading the same setting back may return a different value.

                          -

                          Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of -actual data to be sent/received by the application, because the kernel might also use the buffer space -for internal metadata structures.

                          -

                          Fails when this socket is in the Listening state.

                          -

                          Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-receive-buffer-size: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          send-buffer-size: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-send-buffer-size: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          non-blocking: func

                          -

                          Get/set the blocking mode of the socket.

                          -

                          By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. -When switched to "non-blocking" mode, operations that would block return an again error. After which -the API consumer is expected to call subscribe and wait for completion using the wasi-poll module.

                          -

                          Note: these functions are here for WASI Preview2 only. -They're planned to be removed when future is natively supported in Preview3.

                          -
                          Params
                          - -
                          Return values
                          - -

                          set-non-blocking: func

                          -
                          Params
                          - -
                          Return values
                          - -

                          subscribe: func

                          -

                          Create a pollable which will resolve once the socket is ready for I/O.

                          -

                          Note: this function is here for WASI Preview2 only. -It's planned to be removed when future is natively supported in Preview3.

                          -
                          Params
                          - -
                          Return values
                          - -

                          drop-udp-socket: func

                          -

                          Dispose of the specified udp-socket, after which it may no longer be used.

                          -

                          Note: this function is scheduled to be removed when Resources are natively supported in Wit.

                          -
                          Params
                          - -

                          Import interface udp-create-socket

                          -
                          -

                          Types

                          -

                          type network

                          -

                          network

                          -

                          -#### `type error` -[`error`](#error) -

                          -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) -

                          -#### `type udp-socket` -[`udp-socket`](#udp_socket) -

                          ----- -

                          Functions

                          -

                          create-udp-socket: func

                          -

                          Create a new UDP socket.

                          -

                          Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.

                          -

                          This function does not require a network capability handle. This is considered to be safe because -at time of creation, the socket is not bound to any network yet. Up to the moment bind/connect is called, -the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                          -

                          References:

                          - -
                          Params
                          - -
                          Return values
                          - -

                          Import interface random

                          -

                          WASI Random is a random data API.

                          -

                          It is intended to be portable at least between Unix-family platforms and -Windows.

                          -
                          -

                          Functions

                          -

                          get-random-bytes: func

                          -

                          Return len cryptographically-secure pseudo-random bytes.

                          -

                          This function must produce data from an adequately seeded -cryptographically-secure pseudo-random number generator (CSPRNG), so it -must not block, from the perspective of the calling program, and the -returned data is always unpredictable.

                          -

                          This function must always return fresh pseudo-random data. Deterministic -environments must omit this function, rather than implementing it with -deterministic data.

                          -
                          Params
                          - -
                          Return values
                          -
                            -
                          • list<u8>
                          • -
                          -

                          get-random-u64: func

                          -

                          Return a cryptographically-secure pseudo-random u64 value.

                          -

                          This function returns the same type of pseudo-random data as -get-random-bytes, represented as a u64.

                          -
                          Return values
                          -
                            -
                          • u64
                          • -
                          -

                          insecure-random: func

                          -

                          Return a 128-bit value that may contain a pseudo-random value.

                          -

                          The returned value is not required to be computed from a CSPRNG, and may -even be entirely deterministic. Host implementations are encouraged to -provide pseudo-random values to any program exposed to -attacker-controlled content, to enable DoS protection built into many -languages' hash-map implementations.

                          -

                          This function is intended to only be called once, by a source language -to initialize Denial Of Service (DoS) protection in its hash-map -implementation.

                          -

                          Expected future evolution

                          -

                          This will likely be changed to a value import, to prevent it from being -called multiple times and potentially used for purposes other than DoS -protection.

                          -
                          Return values
                          -
                            -
                          • (u64, u64)
                          • -
                          -

                          Import interface environment

                          -
                          -

                          Functions

                          -

                          get-environment: func

                          -

                          Get the POSIX-style environment variables.

                          -

                          Each environment variable is provided as a pair of string variable names -and string value.

                          -

                          Morally, these are a value import, but until value imports are available -in the component model, this import function should return the same -values each time it is called.

                          -
                          Return values
                          -
                            -
                          • list<(string, string)>
                          • -
                          -

                          Import interface environment-preopens

                          -
                          -

                          Types

                          -

                          type descriptor

                          -

                          descriptor

                          -

                          ----- -

                          Functions

                          -

                          preopens: func

                          -

                          Return a list of preopens for use in interpreting environment variables.

                          -
                          Return values
                          - -

                          Import interface exit

                          -
                          -

                          Functions

                          -

                          exit: func

                          -

                          Exit the curerent instance and any linked instances.

                          -
                          Params
                          - diff --git a/proposals/cli/wit/reactor.wit b/proposals/cli/wit/reactor.wit deleted file mode 100644 index b3298ab3d..000000000 --- a/proposals/cli/wit/reactor.wit +++ /dev/null @@ -1,21 +0,0 @@ -default world reactor { - import wall-clock: clocks.wall-clock - import monotonic-clock: clocks.monotonic-clock - import instance-wall-clock: clocks.instance-wall-clock - import instance-monotonic-clock: clocks.instance-monotonic-clock - import timezone: clocks.timezone - import filesystem: filesystem.filesystem - import instance-network: sockets.instance-network - import ip-name-lookup: sockets.ip-name-lookup - import network: sockets.network - import tcp-create-socket: sockets.tcp-create-socket - import tcp: sockets.tcp - import udp-create-socket: sockets.udp-create-socket - import udp: sockets.udp - import random: random.random - import poll: poll.poll - import streams: io.streams - import environment: pkg.environment - import environment-preopens: pkg.environment-preopens - import exit: pkg.exit -} From eafac805d4a41710c694b9d15ab013f368e3be9e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 Mar 2023 14:12:49 -0800 Subject: [PATCH 1104/1772] Update deps. --- proposals/filesystem/example-world.md | 91 +++++++++++++++++++- proposals/filesystem/wit/deps/io/streams.wit | 83 +++++++++++++++++- 2 files changed, 170 insertions(+), 4 deletions(-) diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md index 9f948e1fa..0c0b65031 100644 --- a/proposals/filesystem/example-world.md +++ b/proposals/filesystem/example-world.md @@ -74,6 +74,14 @@ doesn't provide any additional information.

                          u32

                          An output bytestream. In the future, this will be replaced by handle types. +

                          This conceptually represents a stream<u8, _>. It's temporary +scaffolding until component-model's async features are ready.

                          +

                          output-streams are non-blocking to the extent practical on +underlying platforms. Except where specified otherwise, I/O operations also +always return promptly, after the number of bytes that can be written +promptly, which could even be zero. To wait for the stream to be ready to +accept data, the subscribe-to-output-stream function to obtain a +pollable which can be polled for using wasi_poll.

                          And at present, it is a u32 instead of being an actual handle, until the wit-bindgen implementation of handles and resources is ready.

                          This represents a resource.

                          @@ -81,6 +89,14 @@ the wit-bindgen implementation of handles and resources is ready.

                          u32

                          An input bytestream. In the future, this will be replaced by handle types. +

                          This conceptually represents a stream<u8, _>. It's temporary +scaffolding until component-model's async features are ready.

                          +

                          input-streams are non-blocking to the extent practical on underlying +platforms. I/O operations always return promptly; if fewer bytes are +promptly available than requested, they return the number of bytes promptly +available, which could even be zero. To wait for data to be available, +use the subscribe-to-input-stream function to obtain a pollable which +can be polled for using wasi_poll.

                          And at present, it is a u32 instead of being an actual handle, until the wit-bindgen implementation of handles and resources is ready.

                          This represents a resource.

                          @@ -89,8 +105,8 @@ the wit-bindgen implementation of handles and resources is ready.

                          read: func

                          Read bytes from a stream.

                          This function returns a list of bytes containing the data that was -read, along with a bool indicating whether the end of the stream -was reached. The returned list will contain up to len bytes; it +read, along with a bool which, when true, indicates that the end of the +stream was reached. The returned list will contain up to len bytes; it may return fewer than requested, but not more.

                          Once a stream has reached the end, subsequent calls to read or skip will always report end-of-stream rather than producing more @@ -110,6 +126,19 @@ FIXME: describe what happens if allocation fails.

                          +

                          blocking-read: func

                          +

                          Read bytes from a stream, with blocking.

                          +

                          This is similar to read, except that it blocks until at least one +byte can be read.

                          +
                          Params
                          + +
                          Return values
                          +

                          skip: func

                          Skip bytes from a stream.

                          This is similar to the read function, but avoids copying the @@ -129,6 +158,19 @@ value will be at most len; it may be less.

                          +

                          blocking-skip: func

                          +

                          Skip bytes from a stream, with blocking.

                          +

                          This is similar to skip, except that it blocks until at least one +byte can be consumed.

                          +
                          Params
                          + +
                          Return values
                          +

                          subscribe-to-input-stream: func

                          Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been @@ -161,6 +203,19 @@ be used.

                          +

                          blocking-write: func

                          +

                          Write bytes to a stream, with blocking.

                          +

                          This is similar to write, except that it blocks until at least one +byte can be written.

                          +
                          Params
                          + +
                          Return values
                          +

                          write-zeroes: func

                          Write multiple zero bytes to a stream.

                          This function returns a u64 indicating the number of zero bytes @@ -174,10 +229,25 @@ that were written; it may be less than len.

                          +

                          blocking-write-zeroes: func

                          +

                          Write multiple zero bytes to a stream, with blocking.

                          +

                          This is similar to write-zeroes, except that it blocks until at least +one byte can be written.

                          +
                          Params
                          + +
                          Return values
                          +

                          splice: func

                          Read from one stream and write to another.

                          This function returns the number of bytes transferred; it may be less than len.

                          +

                          Unlike other I/O functions, this function blocks until all the data +read from the input stream has been written to the output stream.

                          Params
                          • this: output-stream
                          • @@ -188,11 +258,28 @@ than len.

                            +

                            blocking-splice: func

                            +

                            Read from one stream and write to another, with blocking.

                            +

                            This is similar to splice, except that it blocks until at least +one byte can be read.

                            +
                            Params
                            + +
                            Return values
                            +

                            forward: func

                            Forward the entire contents of an input stream to an output stream.

                            This function repeatedly reads from the input stream and writes the data to the output stream, until the end of the input stream is reached, or an error is encountered.

                            +

                            Unlike other I/O functions, this function blocks until the end +of the input stream is seen and all the data has been written to +the output stream.

                            This function returns the number of bytes transferred.

                            Params
                              diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index 351006598..c1567fd4c 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -13,6 +13,16 @@ default interface streams { /// An input bytestream. In the future, this will be replaced by handle /// types. /// + /// This conceptually represents a `stream`. It's temporary + /// scaffolding until component-model's async features are ready. + /// + /// `input-stream`s are *non-blocking* to the extent practical on underlying + /// platforms. I/O operations always return promptly; if fewer bytes are + /// promptly available than requested, they return the number of bytes promptly + /// available, which could even be zero. To wait for data to be available, + /// use the `subscribe-to-input-stream` function to obtain a `pollable` which + /// can be polled for using `wasi_poll`. + /// /// And at present, it is a `u32` instead of being an actual handle, until /// the wit-bindgen implementation of handles and resources is ready. /// @@ -22,8 +32,8 @@ default interface streams { /// Read bytes from a stream. /// /// This function returns a list of bytes containing the data that was - /// read, along with a bool indicating whether the end of the stream - /// was reached. The returned list will contain up to `len` bytes; it + /// read, along with a bool which, when true, indicates that the end of the + /// stream was reached. The returned list will contain up to `len` bytes; it /// may return fewer than requested, but not more. /// /// Once a stream has reached the end, subsequent calls to read or @@ -43,6 +53,16 @@ default interface streams { len: u64 ) -> result, bool>, stream-error> + /// Read bytes from a stream, with blocking. + /// + /// This is similar to `read`, except that it blocks until at least one + /// byte can be read. + blocking-read: func( + this: input-stream, + /// The maximum number of bytes to read + len: u64 + ) -> result, bool>, stream-error> + /// Skip bytes from a stream. /// /// This is similar to the `read` function, but avoids copying the @@ -61,6 +81,16 @@ default interface streams { len: u64, ) -> result, stream-error> + /// Skip bytes from a stream, with blocking. + /// + /// This is similar to `skip`, except that it blocks until at least one + /// byte can be consumed. + blocking-skip: func( + this: input-stream, + /// The maximum number of bytes to skip. + len: u64, + ) -> result, stream-error> + /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been /// closed. @@ -73,6 +103,16 @@ default interface streams { /// An output bytestream. In the future, this will be replaced by handle /// types. /// + /// This conceptually represents a `stream`. It's temporary + /// scaffolding until component-model's async features are ready. + /// + /// `output-stream`s are *non-blocking* to the extent practical on + /// underlying platforms. Except where specified otherwise, I/O operations also + /// always return promptly, after the number of bytes that can be written + /// promptly, which could even be zero. To wait for the stream to be ready to + /// accept data, the `subscribe-to-output-stream` function to obtain a + /// `pollable` which can be polled for using `wasi_poll`. + /// /// And at present, it is a `u32` instead of being an actual handle, until /// the wit-bindgen implementation of handles and resources is ready. /// @@ -89,6 +129,16 @@ default interface streams { buf: list ) -> result + /// Write bytes to a stream, with blocking. + /// + /// This is similar to `write`, except that it blocks until at least one + /// byte can be written. + blocking-write: func( + this: output-stream, + /// Data to write + buf: list + ) -> result + /// Write multiple zero bytes to a stream. /// /// This function returns a `u64` indicating the number of zero bytes @@ -99,10 +149,23 @@ default interface streams { len: u64 ) -> result + /// Write multiple zero bytes to a stream, with blocking. + /// + /// This is similar to `write-zeroes`, except that it blocks until at least + /// one byte can be written. + blocking-write-zeroes: func( + this: output-stream, + /// The number of zero bytes to write + len: u64 + ) -> result + /// Read from one stream and write to another. /// /// This function returns the number of bytes transferred; it may be less /// than `len`. + /// + /// Unlike other I/O functions, this function blocks until all the data + /// read from the input stream has been written to the output stream. splice: func( this: output-stream, /// The stream to read from @@ -111,12 +174,28 @@ default interface streams { len: u64, ) -> result, stream-error> + /// Read from one stream and write to another, with blocking. + /// + /// This is similar to `splice`, except that it blocks until at least + /// one byte can be read. + blocking-splice: func( + this: output-stream, + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result, stream-error> + /// Forward the entire contents of an input stream to an output stream. /// /// This function repeatedly reads from the input stream and writes /// the data to the output stream, until the end of the input stream /// is reached, or an error is encountered. /// + /// Unlike other I/O functions, this function blocks until the end + /// of the input stream is seen and all the data has been written to + /// the output stream. + /// /// This function returns the number of bytes transferred. forward: func( this: output-stream, From 2c5bcdd31086a76e6dfdd7b000222f52bf2e2cef Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 Mar 2023 14:34:23 -0800 Subject: [PATCH 1105/1772] Delete a spurious file. --- proposals/filesystem/wit/deps/wit | 134 ------------------------------ 1 file changed, 134 deletions(-) delete mode 100644 proposals/filesystem/wit/deps/wit diff --git a/proposals/filesystem/wit/deps/wit b/proposals/filesystem/wit/deps/wit deleted file mode 100644 index 351006598..000000000 --- a/proposals/filesystem/wit/deps/wit +++ /dev/null @@ -1,134 +0,0 @@ -/// WASI I/O is an I/O abstraction API which is currently focused on providing -/// stream types. -/// -/// In the future, the component model is expected to add built-in stream types; -/// when it does, they are expected to subsume this API. -default interface streams { - use poll.poll.{pollable} - - /// An error type returned from a stream operation. Currently this - /// doesn't provide any additional information. - record stream-error {} - - /// An input bytestream. In the future, this will be replaced by handle - /// types. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type input-stream = u32 - - /// Read bytes from a stream. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a bool indicating whether the end of the stream - /// was reached. The returned list will contain up to `len` bytes; it - /// may return fewer than requested, but not more. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// If `len` is 0, it represents a request to read 0 bytes, which should - /// always succeed, assuming the stream hasn't reached its end yet, and - /// return an empty list. - /// - /// The len here is a `u64`, but some callees may not be able to allocate - /// a buffer as large as that would imply. - /// FIXME: describe what happens if allocation fails. - read: func( - this: input-stream, - /// The maximum number of bytes to read - len: u64 - ) -> result, bool>, stream-error> - - /// Skip bytes from a stream. - /// - /// This is similar to the `read` function, but avoids copying the - /// bytes into the instance. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// This function returns the number of bytes skipped, along with a bool - /// indicating whether the end of the stream was reached. The returned - /// value will be at most `len`; it may be less. - skip: func( - this: input-stream, - /// The maximum number of bytes to skip. - len: u64, - ) -> result, stream-error> - - /// Create a `pollable` which will resolve once either the specified stream - /// has bytes available to read or the other end of the stream has been - /// closed. - subscribe-to-input-stream: func(this: input-stream) -> pollable - - /// Dispose of the specified `input-stream`, after which it may no longer - /// be used. - drop-input-stream: func(this: input-stream) - - /// An output bytestream. In the future, this will be replaced by handle - /// types. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type output-stream = u32 - - /// Write bytes to a stream. - /// - /// This function returns a `u64` indicating the number of bytes from - /// `buf` that were written; it may be less than the full list. - write: func( - this: output-stream, - /// Data to write - buf: list - ) -> result - - /// Write multiple zero bytes to a stream. - /// - /// This function returns a `u64` indicating the number of zero bytes - /// that were written; it may be less than `len`. - write-zeroes: func( - this: output-stream, - /// The number of zero bytes to write - len: u64 - ) -> result - - /// Read from one stream and write to another. - /// - /// This function returns the number of bytes transferred; it may be less - /// than `len`. - splice: func( - this: output-stream, - /// The stream to read from - src: input-stream, - /// The number of bytes to splice - len: u64, - ) -> result, stream-error> - - /// Forward the entire contents of an input stream to an output stream. - /// - /// This function repeatedly reads from the input stream and writes - /// the data to the output stream, until the end of the input stream - /// is reached, or an error is encountered. - /// - /// This function returns the number of bytes transferred. - forward: func( - this: output-stream, - /// The stream to read from - src: input-stream - ) -> result - - /// Create a `pollable` which will resolve once either the specified stream - /// is ready to accept bytes or the other end of the stream has been closed. - subscribe-to-output-stream: func(this: output-stream) -> pollable - - /// Dispose of the specified `output-stream`, after which it may no longer - /// be used. - drop-output-stream: func(this: output-stream) -} From f924d6011f25dc220e1b136e290a278f010c85f2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 Mar 2023 14:41:15 -0800 Subject: [PATCH 1106/1772] Remove a spurious file. --- proposals/cli/wit/deps/wit | 134 ------------------------------------- 1 file changed, 134 deletions(-) delete mode 100644 proposals/cli/wit/deps/wit diff --git a/proposals/cli/wit/deps/wit b/proposals/cli/wit/deps/wit deleted file mode 100644 index 351006598..000000000 --- a/proposals/cli/wit/deps/wit +++ /dev/null @@ -1,134 +0,0 @@ -/// WASI I/O is an I/O abstraction API which is currently focused on providing -/// stream types. -/// -/// In the future, the component model is expected to add built-in stream types; -/// when it does, they are expected to subsume this API. -default interface streams { - use poll.poll.{pollable} - - /// An error type returned from a stream operation. Currently this - /// doesn't provide any additional information. - record stream-error {} - - /// An input bytestream. In the future, this will be replaced by handle - /// types. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type input-stream = u32 - - /// Read bytes from a stream. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a bool indicating whether the end of the stream - /// was reached. The returned list will contain up to `len` bytes; it - /// may return fewer than requested, but not more. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// If `len` is 0, it represents a request to read 0 bytes, which should - /// always succeed, assuming the stream hasn't reached its end yet, and - /// return an empty list. - /// - /// The len here is a `u64`, but some callees may not be able to allocate - /// a buffer as large as that would imply. - /// FIXME: describe what happens if allocation fails. - read: func( - this: input-stream, - /// The maximum number of bytes to read - len: u64 - ) -> result, bool>, stream-error> - - /// Skip bytes from a stream. - /// - /// This is similar to the `read` function, but avoids copying the - /// bytes into the instance. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// This function returns the number of bytes skipped, along with a bool - /// indicating whether the end of the stream was reached. The returned - /// value will be at most `len`; it may be less. - skip: func( - this: input-stream, - /// The maximum number of bytes to skip. - len: u64, - ) -> result, stream-error> - - /// Create a `pollable` which will resolve once either the specified stream - /// has bytes available to read or the other end of the stream has been - /// closed. - subscribe-to-input-stream: func(this: input-stream) -> pollable - - /// Dispose of the specified `input-stream`, after which it may no longer - /// be used. - drop-input-stream: func(this: input-stream) - - /// An output bytestream. In the future, this will be replaced by handle - /// types. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type output-stream = u32 - - /// Write bytes to a stream. - /// - /// This function returns a `u64` indicating the number of bytes from - /// `buf` that were written; it may be less than the full list. - write: func( - this: output-stream, - /// Data to write - buf: list - ) -> result - - /// Write multiple zero bytes to a stream. - /// - /// This function returns a `u64` indicating the number of zero bytes - /// that were written; it may be less than `len`. - write-zeroes: func( - this: output-stream, - /// The number of zero bytes to write - len: u64 - ) -> result - - /// Read from one stream and write to another. - /// - /// This function returns the number of bytes transferred; it may be less - /// than `len`. - splice: func( - this: output-stream, - /// The stream to read from - src: input-stream, - /// The number of bytes to splice - len: u64, - ) -> result, stream-error> - - /// Forward the entire contents of an input stream to an output stream. - /// - /// This function repeatedly reads from the input stream and writes - /// the data to the output stream, until the end of the input stream - /// is reached, or an error is encountered. - /// - /// This function returns the number of bytes transferred. - forward: func( - this: output-stream, - /// The stream to read from - src: input-stream - ) -> result - - /// Create a `pollable` which will resolve once either the specified stream - /// is ready to accept bytes or the other end of the stream has been closed. - subscribe-to-output-stream: func(this: output-stream) -> pollable - - /// Dispose of the specified `output-stream`, after which it may no longer - /// be used. - drop-output-stream: func(this: output-stream) -} From ecee520e7dfa4df80f7fa8e3632f8f50ef2ff031 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 Mar 2023 14:48:52 -0800 Subject: [PATCH 1107/1772] Update dependencies. --- .../filesystem/{filesystem.wit => types.wit} | 8 +- proposals/cli/wit/deps/io/streams.wit | 83 ++++++++++++++++++- 2 files changed, 85 insertions(+), 6 deletions(-) rename proposals/cli/wit/deps/filesystem/{filesystem.wit => types.wit} (99%) diff --git a/proposals/cli/wit/deps/filesystem/filesystem.wit b/proposals/cli/wit/deps/filesystem/types.wit similarity index 99% rename from proposals/cli/wit/deps/filesystem/filesystem.wit rename to proposals/cli/wit/deps/filesystem/types.wit index 90985e27e..9530d6a63 100644 --- a/proposals/cli/wit/deps/filesystem/filesystem.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -17,7 +17,7 @@ /// `..` and symbolic link steps, reaches a directory outside of the base /// directory, or reaches a symlink to an absolute or rooted path in the /// underlying filesystem, the function fails with `error-code::not-permitted`. -default interface filesystem { +default interface types { use io.streams.{input-stream, output-stream} use clocks.wall-clock.{datetime} @@ -313,7 +313,7 @@ default interface filesystem { this: descriptor, /// The offset within the file at which to start reading. offset: filesize, - ) -> result + ) -> input-stream /// Return a stream for writing to a file. /// @@ -323,7 +323,7 @@ default interface filesystem { this: descriptor, /// The offset within the file at which to start writing. offset: filesize, - ) -> result + ) -> output-stream /// Return a stream for appending to a file. /// @@ -331,7 +331,7 @@ default interface filesystem { /// `O_APPEND` in in POSIX. append-via-stream: func( this: descriptor, - ) -> result + ) -> output-stream /// Provide file advisory information on a descriptor. /// diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index 351006598..c1567fd4c 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -13,6 +13,16 @@ default interface streams { /// An input bytestream. In the future, this will be replaced by handle /// types. /// + /// This conceptually represents a `stream`. It's temporary + /// scaffolding until component-model's async features are ready. + /// + /// `input-stream`s are *non-blocking* to the extent practical on underlying + /// platforms. I/O operations always return promptly; if fewer bytes are + /// promptly available than requested, they return the number of bytes promptly + /// available, which could even be zero. To wait for data to be available, + /// use the `subscribe-to-input-stream` function to obtain a `pollable` which + /// can be polled for using `wasi_poll`. + /// /// And at present, it is a `u32` instead of being an actual handle, until /// the wit-bindgen implementation of handles and resources is ready. /// @@ -22,8 +32,8 @@ default interface streams { /// Read bytes from a stream. /// /// This function returns a list of bytes containing the data that was - /// read, along with a bool indicating whether the end of the stream - /// was reached. The returned list will contain up to `len` bytes; it + /// read, along with a bool which, when true, indicates that the end of the + /// stream was reached. The returned list will contain up to `len` bytes; it /// may return fewer than requested, but not more. /// /// Once a stream has reached the end, subsequent calls to read or @@ -43,6 +53,16 @@ default interface streams { len: u64 ) -> result, bool>, stream-error> + /// Read bytes from a stream, with blocking. + /// + /// This is similar to `read`, except that it blocks until at least one + /// byte can be read. + blocking-read: func( + this: input-stream, + /// The maximum number of bytes to read + len: u64 + ) -> result, bool>, stream-error> + /// Skip bytes from a stream. /// /// This is similar to the `read` function, but avoids copying the @@ -61,6 +81,16 @@ default interface streams { len: u64, ) -> result, stream-error> + /// Skip bytes from a stream, with blocking. + /// + /// This is similar to `skip`, except that it blocks until at least one + /// byte can be consumed. + blocking-skip: func( + this: input-stream, + /// The maximum number of bytes to skip. + len: u64, + ) -> result, stream-error> + /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been /// closed. @@ -73,6 +103,16 @@ default interface streams { /// An output bytestream. In the future, this will be replaced by handle /// types. /// + /// This conceptually represents a `stream`. It's temporary + /// scaffolding until component-model's async features are ready. + /// + /// `output-stream`s are *non-blocking* to the extent practical on + /// underlying platforms. Except where specified otherwise, I/O operations also + /// always return promptly, after the number of bytes that can be written + /// promptly, which could even be zero. To wait for the stream to be ready to + /// accept data, the `subscribe-to-output-stream` function to obtain a + /// `pollable` which can be polled for using `wasi_poll`. + /// /// And at present, it is a `u32` instead of being an actual handle, until /// the wit-bindgen implementation of handles and resources is ready. /// @@ -89,6 +129,16 @@ default interface streams { buf: list ) -> result + /// Write bytes to a stream, with blocking. + /// + /// This is similar to `write`, except that it blocks until at least one + /// byte can be written. + blocking-write: func( + this: output-stream, + /// Data to write + buf: list + ) -> result + /// Write multiple zero bytes to a stream. /// /// This function returns a `u64` indicating the number of zero bytes @@ -99,10 +149,23 @@ default interface streams { len: u64 ) -> result + /// Write multiple zero bytes to a stream, with blocking. + /// + /// This is similar to `write-zeroes`, except that it blocks until at least + /// one byte can be written. + blocking-write-zeroes: func( + this: output-stream, + /// The number of zero bytes to write + len: u64 + ) -> result + /// Read from one stream and write to another. /// /// This function returns the number of bytes transferred; it may be less /// than `len`. + /// + /// Unlike other I/O functions, this function blocks until all the data + /// read from the input stream has been written to the output stream. splice: func( this: output-stream, /// The stream to read from @@ -111,12 +174,28 @@ default interface streams { len: u64, ) -> result, stream-error> + /// Read from one stream and write to another, with blocking. + /// + /// This is similar to `splice`, except that it blocks until at least + /// one byte can be read. + blocking-splice: func( + this: output-stream, + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result, stream-error> + /// Forward the entire contents of an input stream to an output stream. /// /// This function repeatedly reads from the input stream and writes /// the data to the output stream, until the end of the input stream /// is reached, or an error is encountered. /// + /// Unlike other I/O functions, this function blocks until the end + /// of the input stream is seen and all the data has been written to + /// the output stream. + /// /// This function returns the number of bytes transferred. forward: func( this: output-stream, From 674d082dbb0ad02b60c6b2c092d8e67789599cd2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 7 Mar 2023 14:55:31 -0800 Subject: [PATCH 1108/1772] Update the world for the filesystem->types rename. --- proposals/cli/command.md | 97 ++++++++++++++++++++-- proposals/cli/wit/command.wit | 4 +- proposals/cli/wit/environment-preopens.wit | 2 +- 3 files changed, 95 insertions(+), 8 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 006edb2c9..149fdb792 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -342,6 +342,14 @@ doesn't provide any additional information.

                              u32

                              An output bytestream. In the future, this will be replaced by handle types. +

                              This conceptually represents a stream<u8, _>. It's temporary +scaffolding until component-model's async features are ready.

                              +

                              output-streams are non-blocking to the extent practical on +underlying platforms. Except where specified otherwise, I/O operations also +always return promptly, after the number of bytes that can be written +promptly, which could even be zero. To wait for the stream to be ready to +accept data, the subscribe-to-output-stream function to obtain a +pollable which can be polled for using wasi_poll.

                              And at present, it is a u32 instead of being an actual handle, until the wit-bindgen implementation of handles and resources is ready.

                              This represents a resource.

                              @@ -349,6 +357,14 @@ the wit-bindgen implementation of handles and resources is ready.

                              u32

                              An input bytestream. In the future, this will be replaced by handle types. +

                              This conceptually represents a stream<u8, _>. It's temporary +scaffolding until component-model's async features are ready.

                              +

                              input-streams are non-blocking to the extent practical on underlying +platforms. I/O operations always return promptly; if fewer bytes are +promptly available than requested, they return the number of bytes promptly +available, which could even be zero. To wait for data to be available, +use the subscribe-to-input-stream function to obtain a pollable which +can be polled for using wasi_poll.

                              And at present, it is a u32 instead of being an actual handle, until the wit-bindgen implementation of handles and resources is ready.

                              This represents a resource.

                              @@ -357,8 +373,8 @@ the wit-bindgen implementation of handles and resources is ready.

                              read: func

                              Read bytes from a stream.

                              This function returns a list of bytes containing the data that was -read, along with a bool indicating whether the end of the stream -was reached. The returned list will contain up to len bytes; it +read, along with a bool which, when true, indicates that the end of the +stream was reached. The returned list will contain up to len bytes; it may return fewer than requested, but not more.

                              Once a stream has reached the end, subsequent calls to read or skip will always report end-of-stream rather than producing more @@ -378,6 +394,19 @@ FIXME: describe what happens if allocation fails.

                              +

                              blocking-read: func

                              +

                              Read bytes from a stream, with blocking.

                              +

                              This is similar to read, except that it blocks until at least one +byte can be read.

                              +
                              Params
                              + +
                              Return values
                              +

                              skip: func

                              Skip bytes from a stream.

                              This is similar to the read function, but avoids copying the @@ -397,6 +426,19 @@ value will be at most len; it may be less.

                              +

                              blocking-skip: func

                              +

                              Skip bytes from a stream, with blocking.

                              +

                              This is similar to skip, except that it blocks until at least one +byte can be consumed.

                              +
                              Params
                              + +
                              Return values
                              +

                              subscribe-to-input-stream: func

                              Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been @@ -429,6 +471,19 @@ be used.

                              +

                              blocking-write: func

                              +

                              Write bytes to a stream, with blocking.

                              +

                              This is similar to write, except that it blocks until at least one +byte can be written.

                              +
                              Params
                              + +
                              Return values
                              +

                              write-zeroes: func

                              Write multiple zero bytes to a stream.

                              This function returns a u64 indicating the number of zero bytes @@ -442,10 +497,25 @@ that were written; it may be less than len.

                              +

                              blocking-write-zeroes: func

                              +

                              Write multiple zero bytes to a stream, with blocking.

                              +

                              This is similar to write-zeroes, except that it blocks until at least +one byte can be written.

                              +
                              Params
                              + +
                              Return values
                              +

                              splice: func

                              Read from one stream and write to another.

                              This function returns the number of bytes transferred; it may be less than len.

                              +

                              Unlike other I/O functions, this function blocks until all the data +read from the input stream has been written to the output stream.

                              Params
                              • this: output-stream
                              • @@ -456,11 +526,28 @@ than len.

                                +

                                blocking-splice: func

                                +

                                Read from one stream and write to another, with blocking.

                                +

                                This is similar to splice, except that it blocks until at least +one byte can be read.

                                +
                                Params
                                + +
                                Return values
                                +

                                forward: func

                                Forward the entire contents of an input stream to an output stream.

                                This function repeatedly reads from the input stream and writes the data to the output stream, until the end of the input stream is reached, or an error is encountered.

                                +

                                Unlike other I/O functions, this function blocks until the end +of the input stream is seen and all the data has been written to +the output stream.

                                This function returns the number of bytes transferred.

                                Params
                                  @@ -971,7 +1058,7 @@ file and they do not interfere with each other.

                                Return values

                                write-via-stream: func

                                Return a stream for writing to a file.

                                @@ -984,7 +1071,7 @@ POSIX.

                              Return values

                              append-via-stream: func

                              Return a stream for appending to a file.

                              @@ -996,7 +1083,7 @@ POSIX.

                            Return values

                            advise: func

                            Provide file advisory information on a descriptor.

                            diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index d56d61b01..d3b8b4614 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -4,7 +4,7 @@ default world command { import instance-wall-clock: clocks.instance-wall-clock import instance-monotonic-clock: clocks.instance-monotonic-clock import timezone: clocks.timezone - import filesystem: filesystem.filesystem + import filesystem: filesystem.types import instance-network: sockets.instance-network import ip-name-lookup: sockets.ip-name-lookup import network: sockets.network @@ -20,7 +20,7 @@ default world command { import exit: pkg.exit use io.streams.{input-stream, output-stream} - use filesystem.filesystem.{descriptor} + use filesystem.types.{descriptor} export main: func( stdin: input-stream, diff --git a/proposals/cli/wit/environment-preopens.wit b/proposals/cli/wit/environment-preopens.wit index 74f17d587..f8213ca6a 100644 --- a/proposals/cli/wit/environment-preopens.wit +++ b/proposals/cli/wit/environment-preopens.wit @@ -1,5 +1,5 @@ default interface environment-preopens { - use filesystem.filesystem.{descriptor} + use filesystem.types.{descriptor} /// Return a list of preopens for use in interpreting environment variables. preopens: func() -> list> From 3d840f7c28b699cf1b9cec9088478ce3cbef3226 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Wed, 8 Mar 2023 14:25:58 +0100 Subject: [PATCH 1109/1772] Add query field Resolves #10 --- proposals/http/wit/types.wit | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 6a8b0dcf9..bdcf79737 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -79,6 +79,7 @@ default interface types { drop-outgoing-request: func(request: outgoing-request) incoming-request-method: func(request: incoming-request) -> method incoming-request-path: func(request: incoming-request) -> string + incoming-request-query: func(request: incoming-request) -> string incoming-request-scheme: func(request: incoming-request) -> option incoming-request-authority: func(request: incoming-request) -> string incoming-request-headers: func(request: incoming-request) -> headers @@ -86,6 +87,7 @@ default interface types { new-outgoing-request: func( method: method, path: string, + query: string, scheme: option, authority: string, headers: headers From 787c9377af3e09dc0510244458f21f279c97a077 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Wed, 15 Mar 2023 09:22:11 +0100 Subject: [PATCH 1110/1772] Remove query, rename 'path' to 'path-and-query', optionalize path-and-query and authority --- proposals/http/wit/types.wit | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index bdcf79737..58771b806 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -78,18 +78,16 @@ default interface types { drop-incoming-request: func(request: incoming-request) drop-outgoing-request: func(request: outgoing-request) incoming-request-method: func(request: incoming-request) -> method - incoming-request-path: func(request: incoming-request) -> string - incoming-request-query: func(request: incoming-request) -> string + incoming-request-path-and-query: func(request: incoming-request) -> option incoming-request-scheme: func(request: incoming-request) -> option - incoming-request-authority: func(request: incoming-request) -> string + incoming-request-authority: func(request: incoming-request) -> option incoming-request-headers: func(request: incoming-request) -> headers incoming-request-consume: func(request: incoming-request) -> result new-outgoing-request: func( method: method, - path: string, - query: string, + path-and-query: option, scheme: option, - authority: string, + authority: option, headers: headers ) -> outgoing-request outgoing-request-write: func(request: outgoing-request) -> result From 862fbcd3cb036b6aaf8908543b89b8885ba9aff7 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 16 Mar 2023 17:29:08 +0100 Subject: [PATCH 1111/1772] s/and/with/ --- proposals/http/wit/types.wit | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 58771b806..3f799cac9 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -78,14 +78,14 @@ default interface types { drop-incoming-request: func(request: incoming-request) drop-outgoing-request: func(request: outgoing-request) incoming-request-method: func(request: incoming-request) -> method - incoming-request-path-and-query: func(request: incoming-request) -> option + incoming-request-path-with-query: func(request: incoming-request) -> option incoming-request-scheme: func(request: incoming-request) -> option incoming-request-authority: func(request: incoming-request) -> option incoming-request-headers: func(request: incoming-request) -> headers incoming-request-consume: func(request: incoming-request) -> result new-outgoing-request: func( method: method, - path-and-query: option, + path-with-query: option, scheme: option, authority: option, headers: headers From 611f947ae9d30f9167a15a01482cbd6d63be4745 Mon Sep 17 00:00:00 2001 From: Brendan Burns Date: Tue, 21 Mar 2023 14:19:26 -0700 Subject: [PATCH 1112/1772] Update types.wit Add the outparam to set-outparam-response --- proposals/http/wit/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index bdcf79737..5675ff5d7 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -118,7 +118,7 @@ default interface types { // simply return a `stream`). type response-outparam = u32 drop-response-outparam: func(response: response-outparam) - set-response-outparam: func(response: result) -> result + set-response-outparam: func(param: response-outparam, response: result) -> result // This type corresponds to the HTTP standard Status Code. type status-code = u16 From 6a6b17b9debee30ab356cadbf4249770ecd52b4e Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 27 Mar 2023 10:02:44 -0500 Subject: [PATCH 1113/1772] Add comment on how response streaming works Resolves #18 --- proposals/http/wit/incoming-handler.wit | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/proposals/http/wit/incoming-handler.wit b/proposals/http/wit/incoming-handler.wit index 1ecff0aa5..3b1c29aae 100644 --- a/proposals/http/wit/incoming-handler.wit +++ b/proposals/http/wit/incoming-handler.wit @@ -12,11 +12,13 @@ default interface incoming-handler { // The `handle` function takes an outparam instead of returning its response // so that the component may stream its response while streaming any other // request or response bodies. The callee MUST write a response to the - // `response-out` and then finish the response before returning. The `handle` - // function is allowed to continue execution after finishing the response's - // output stream. While this post-response execution is taken off the - // critical path, since there is no return value, there is no way to report - // its success or failure. + // `response-out` and then finish the response before returning. The caller + // is expected to start streaming the response once `set-response-outparam` + // is called and finish streaming the response when `drop-response-outparam` + // is called. The `handle` function is then allowed to continue executing + // any post-response logic before returning. While this post-response + // execution is taken off the critical path, since there is no return value, + // there is no way to report its success or failure. handle: func( request: incoming-request, response-out: response-outparam From 9e570d8cee50f2729cf9141b43ddc7897c942825 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Wed, 29 Mar 2023 15:55:03 -0500 Subject: [PATCH 1114/1772] Update wasi-io dep, remove some TODOs that might not happen that way --- proposals/http/wit/deps/io/streams.wit | 56 +++++++++++++++++++++++++- proposals/http/wit/proxy.wit | 23 +---------- 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index 9fa533efe..c1567fd4c 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -32,8 +32,8 @@ default interface streams { /// Read bytes from a stream. /// /// This function returns a list of bytes containing the data that was - /// read, along with a bool indicating whether the end of the stream - /// was reached. The returned list will contain up to `len` bytes; it + /// read, along with a bool which, when true, indicates that the end of the + /// stream was reached. The returned list will contain up to `len` bytes; it /// may return fewer than requested, but not more. /// /// Once a stream has reached the end, subsequent calls to read or @@ -53,6 +53,16 @@ default interface streams { len: u64 ) -> result, bool>, stream-error> + /// Read bytes from a stream, with blocking. + /// + /// This is similar to `read`, except that it blocks until at least one + /// byte can be read. + blocking-read: func( + this: input-stream, + /// The maximum number of bytes to read + len: u64 + ) -> result, bool>, stream-error> + /// Skip bytes from a stream. /// /// This is similar to the `read` function, but avoids copying the @@ -71,6 +81,16 @@ default interface streams { len: u64, ) -> result, stream-error> + /// Skip bytes from a stream, with blocking. + /// + /// This is similar to `skip`, except that it blocks until at least one + /// byte can be consumed. + blocking-skip: func( + this: input-stream, + /// The maximum number of bytes to skip. + len: u64, + ) -> result, stream-error> + /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been /// closed. @@ -109,6 +129,16 @@ default interface streams { buf: list ) -> result + /// Write bytes to a stream, with blocking. + /// + /// This is similar to `write`, except that it blocks until at least one + /// byte can be written. + blocking-write: func( + this: output-stream, + /// Data to write + buf: list + ) -> result + /// Write multiple zero bytes to a stream. /// /// This function returns a `u64` indicating the number of zero bytes @@ -119,6 +149,16 @@ default interface streams { len: u64 ) -> result + /// Write multiple zero bytes to a stream, with blocking. + /// + /// This is similar to `write-zeroes`, except that it blocks until at least + /// one byte can be written. + blocking-write-zeroes: func( + this: output-stream, + /// The number of zero bytes to write + len: u64 + ) -> result + /// Read from one stream and write to another. /// /// This function returns the number of bytes transferred; it may be less @@ -134,6 +174,18 @@ default interface streams { len: u64, ) -> result, stream-error> + /// Read from one stream and write to another, with blocking. + /// + /// This is similar to `splice`, except that it blocks until at least + /// one byte can be read. + blocking-splice: func( + this: output-stream, + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result, stream-error> + /// Forward the entire contents of an input stream to an output stream. /// /// This function repeatedly reads from the input stream and writes diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index ff8b53a8b..abf157fb3 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -12,31 +12,10 @@ default world proxy { // log to a developer-facing console (e.g., via `console.log()`). import console: logging.handler - // TODO: Once the underlying Wit template machinery is implemented, add: - // - // import loggers: interface { - // *: logging.handler - // } - // - // which will allow a component to import any number of non-default logging - // backends that different categories of log messages can be sent to. - - // TODO: add `import metrics: metrics.counters` - // This is the default handler to use when user code simply wants to make an - // HTTP request (e.g., via `fetch()`) but doesn't otherwise specify a - // particular handler. + // HTTP request (e.g., via `fetch()`). import default-outgoing-HTTP: pkg.outgoing-handler - // TODO: Once the underlying Wit template machinery is implemented, add: - // - // import upstreams: interface { - // *: pkg.outgoing-handler - // } - // - // which will allow a component to import any number of non-default backends - // that HTTP requests can be dispatched to. - // The host delivers incoming HTTP requests to a component by calling the // `handle` function of this exported interface. A host may arbitrarily reuse // or not reuse component instance when delivering incoming HTTP requests and From f910755d0987897bfab385ddd56485b09553ebfa Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 4 Apr 2023 16:48:24 +0200 Subject: [PATCH 1115/1772] chore: update `wasi-logging` Sync with https://github.com/WebAssembly/wasi-logging/commit/d106e59b25297d0496e6a5d221ad090e19c3aaa3 Signed-off-by: Roman Volosatovs --- proposals/http/wit/deps/logging/{handler.wit => logging.wit} | 2 +- proposals/http/wit/proxy.wit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename proposals/http/wit/deps/logging/{handler.wit => logging.wit} (97%) diff --git a/proposals/http/wit/deps/logging/handler.wit b/proposals/http/wit/deps/logging/logging.wit similarity index 97% rename from proposals/http/wit/deps/logging/handler.wit rename to proposals/http/wit/deps/logging/logging.wit index c9632b9cc..731716555 100644 --- a/proposals/http/wit/deps/logging/handler.wit +++ b/proposals/http/wit/deps/logging/logging.wit @@ -1,6 +1,6 @@ /// WASI Logging is a logging API intended to let users emit log messages with /// simple priority levels and context values. -default interface handler { +default interface logging { /// A log level, describing a kind of message. enum level { /// Describes messages about the values of variables and the flow of diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index abf157fb3..a46128709 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -10,7 +10,7 @@ default world proxy { // This is the default logging handler to use when user code simply wants to // log to a developer-facing console (e.g., via `console.log()`). - import console: logging.handler + import console: logging.logging // This is the default handler to use when user code simply wants to make an // HTTP request (e.g., via `fetch()`). From 28bca34fb34c47182dc437c11f42a7a00fb717dc Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 10 Apr 2023 13:09:47 -0500 Subject: [PATCH 1116/1772] Use depit tool to automatically manage dependency vendoring --- proposals/http/README.md | 10 +++++----- proposals/http/wit/deps.lock | 19 +++++++++++++++++++ proposals/http/wit/deps.toml | 4 ++++ proposals/http/wit/deps/io/world.wit | 3 +++ proposals/http/wit/deps/logging/world.wit | 3 +++ proposals/http/wit/deps/poll/world.wit | 3 +++ proposals/http/wit/deps/random/world.wit | 3 +++ 7 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 proposals/http/wit/deps.lock create mode 100644 proposals/http/wit/deps.toml create mode 100644 proposals/http/wit/deps/io/world.wit create mode 100644 proposals/http/wit/deps/logging/world.wit create mode 100644 proposals/http/wit/deps/poll/world.wit create mode 100644 proposals/http/wit/deps/random/world.wit diff --git a/proposals/http/README.md b/proposals/http/README.md index 5acd566dd..2fc9786bf 100644 --- a/proposals/http/README.md +++ b/proposals/http/README.md @@ -18,11 +18,11 @@ or can be manipulated in other ways with: wasm-tools component wit wit/ ... ``` -The HTTP proposal depends on the WASI IO and Logging proposals. For simplicity, -the Wit files for these proposals are currently copied into the `wit/deps` -directory and will be updated periodically to match their respective proposals. -As the Wit tooling develops, we should be able to avoid this form of manual -vendoring. +The `wit/deps` directory contains a live snapshot of the contents of several +other WASI proposals upon which this proposal depends. It is automatically +updated by running [`depit`](https://crates.io/crates/depit-cli) in the +root directory, which fetches the `main` branch of each proposal. As things +stablize, `wit/deps.toml` will be updated to refer to versioned releases. ### Current Phase diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock new file mode 100644 index 000000000..846adb42f --- /dev/null +++ b/proposals/http/wit/deps.lock @@ -0,0 +1,19 @@ +[io] +url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +sha256 = "7450142aeb3f1688ee2b12853344e262caf6aee0718dc0296316f7f6b3afd91f" +sha512 = "5cc0f60d190e16d6dd52a4ca2fc862f007465e7642e98061b41c90778e1f2b00aeb2543b6fadbb6a137dd548d86e9e55edcfb30388adcc6a160b4cdc29d378ec" + +[logging] +url = "https://github.com/WebAssembly/wasi-logging/archive/main.tar.gz" +sha256 = "f378a2b6a36af096528ec5e7031da474990cecaec1949c663befc5066d719f6f" +sha512 = "ba09307b12f5428c3058d878001c9fb15df21933c6203328f785d5009a4fc0cf304950271590d4146305a2d8b8988595f396d955961168cb6bfa7ea9af1cc362" + +[poll] +url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" +sha256 = "065422b0ea6ccb2a9facc6b87b902eef110c53d76fc31f341a6bc8d0b0285b6a" +sha512 = "19a55cd3072a19ae6a1774723a4962e7a155a5ce89a27175e8c76020efb4d00bc92ebb78427d92bcb8effd4f0d03ebf0a0daa747ecd981b8d31d5abc2ad86423" + +[random] +url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" +sha256 = "79b6417bb1ab3c82c241c56021e717f258e2a0b3ab94db93907ca11d7f92ed66" +sha512 = "1e657ac56420e65bde75eabea920a605a0ff4adc6f2ba8b7cf1c37a603710449bc1a29568dda2b61c04ae9889d2b1a82b9935d4b9d573eb48a83e0ecf9cad591" diff --git a/proposals/http/wit/deps.toml b/proposals/http/wit/deps.toml new file mode 100644 index 000000000..907c4acbd --- /dev/null +++ b/proposals/http/wit/deps.toml @@ -0,0 +1,4 @@ +io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +logging = "https://github.com/WebAssembly/wasi-logging/archive/main.tar.gz" +poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" +random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit new file mode 100644 index 000000000..bae7c92b3 --- /dev/null +++ b/proposals/http/wit/deps/io/world.wit @@ -0,0 +1,3 @@ +default world example-world { + import streams: pkg.streams +} diff --git a/proposals/http/wit/deps/logging/world.wit b/proposals/http/wit/deps/logging/world.wit new file mode 100644 index 000000000..b5af1514f --- /dev/null +++ b/proposals/http/wit/deps/logging/world.wit @@ -0,0 +1,3 @@ +default world example-world { + import logging: pkg.logging +} diff --git a/proposals/http/wit/deps/poll/world.wit b/proposals/http/wit/deps/poll/world.wit new file mode 100644 index 000000000..3a002e070 --- /dev/null +++ b/proposals/http/wit/deps/poll/world.wit @@ -0,0 +1,3 @@ +default world example-world { + import poll: pkg.poll +} diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit new file mode 100644 index 000000000..8d54b3b2c --- /dev/null +++ b/proposals/http/wit/deps/random/world.wit @@ -0,0 +1,3 @@ +default world example-world { + import random: pkg.random +} From 74f18031def1bf28b9f0067aef054079dd1a8c90 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 10 Apr 2023 13:10:18 -0500 Subject: [PATCH 1117/1772] Revert "Use depit tool to automatically manage dependency vendoring" This reverts commit 28bca34fb34c47182dc437c11f42a7a00fb717dc. --- proposals/http/README.md | 10 +++++----- proposals/http/wit/deps.lock | 19 ------------------- proposals/http/wit/deps.toml | 4 ---- proposals/http/wit/deps/io/world.wit | 3 --- proposals/http/wit/deps/logging/world.wit | 3 --- proposals/http/wit/deps/poll/world.wit | 3 --- proposals/http/wit/deps/random/world.wit | 3 --- 7 files changed, 5 insertions(+), 40 deletions(-) delete mode 100644 proposals/http/wit/deps.lock delete mode 100644 proposals/http/wit/deps.toml delete mode 100644 proposals/http/wit/deps/io/world.wit delete mode 100644 proposals/http/wit/deps/logging/world.wit delete mode 100644 proposals/http/wit/deps/poll/world.wit delete mode 100644 proposals/http/wit/deps/random/world.wit diff --git a/proposals/http/README.md b/proposals/http/README.md index 2fc9786bf..5acd566dd 100644 --- a/proposals/http/README.md +++ b/proposals/http/README.md @@ -18,11 +18,11 @@ or can be manipulated in other ways with: wasm-tools component wit wit/ ... ``` -The `wit/deps` directory contains a live snapshot of the contents of several -other WASI proposals upon which this proposal depends. It is automatically -updated by running [`depit`](https://crates.io/crates/depit-cli) in the -root directory, which fetches the `main` branch of each proposal. As things -stablize, `wit/deps.toml` will be updated to refer to versioned releases. +The HTTP proposal depends on the WASI IO and Logging proposals. For simplicity, +the Wit files for these proposals are currently copied into the `wit/deps` +directory and will be updated periodically to match their respective proposals. +As the Wit tooling develops, we should be able to avoid this form of manual +vendoring. ### Current Phase diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock deleted file mode 100644 index 846adb42f..000000000 --- a/proposals/http/wit/deps.lock +++ /dev/null @@ -1,19 +0,0 @@ -[io] -url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "7450142aeb3f1688ee2b12853344e262caf6aee0718dc0296316f7f6b3afd91f" -sha512 = "5cc0f60d190e16d6dd52a4ca2fc862f007465e7642e98061b41c90778e1f2b00aeb2543b6fadbb6a137dd548d86e9e55edcfb30388adcc6a160b4cdc29d378ec" - -[logging] -url = "https://github.com/WebAssembly/wasi-logging/archive/main.tar.gz" -sha256 = "f378a2b6a36af096528ec5e7031da474990cecaec1949c663befc5066d719f6f" -sha512 = "ba09307b12f5428c3058d878001c9fb15df21933c6203328f785d5009a4fc0cf304950271590d4146305a2d8b8988595f396d955961168cb6bfa7ea9af1cc362" - -[poll] -url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -sha256 = "065422b0ea6ccb2a9facc6b87b902eef110c53d76fc31f341a6bc8d0b0285b6a" -sha512 = "19a55cd3072a19ae6a1774723a4962e7a155a5ce89a27175e8c76020efb4d00bc92ebb78427d92bcb8effd4f0d03ebf0a0daa747ecd981b8d31d5abc2ad86423" - -[random] -url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "79b6417bb1ab3c82c241c56021e717f258e2a0b3ab94db93907ca11d7f92ed66" -sha512 = "1e657ac56420e65bde75eabea920a605a0ff4adc6f2ba8b7cf1c37a603710449bc1a29568dda2b61c04ae9889d2b1a82b9935d4b9d573eb48a83e0ecf9cad591" diff --git a/proposals/http/wit/deps.toml b/proposals/http/wit/deps.toml deleted file mode 100644 index 907c4acbd..000000000 --- a/proposals/http/wit/deps.toml +++ /dev/null @@ -1,4 +0,0 @@ -io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -logging = "https://github.com/WebAssembly/wasi-logging/archive/main.tar.gz" -poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit deleted file mode 100644 index bae7c92b3..000000000 --- a/proposals/http/wit/deps/io/world.wit +++ /dev/null @@ -1,3 +0,0 @@ -default world example-world { - import streams: pkg.streams -} diff --git a/proposals/http/wit/deps/logging/world.wit b/proposals/http/wit/deps/logging/world.wit deleted file mode 100644 index b5af1514f..000000000 --- a/proposals/http/wit/deps/logging/world.wit +++ /dev/null @@ -1,3 +0,0 @@ -default world example-world { - import logging: pkg.logging -} diff --git a/proposals/http/wit/deps/poll/world.wit b/proposals/http/wit/deps/poll/world.wit deleted file mode 100644 index 3a002e070..000000000 --- a/proposals/http/wit/deps/poll/world.wit +++ /dev/null @@ -1,3 +0,0 @@ -default world example-world { - import poll: pkg.poll -} diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit deleted file mode 100644 index 8d54b3b2c..000000000 --- a/proposals/http/wit/deps/random/world.wit +++ /dev/null @@ -1,3 +0,0 @@ -default world example-world { - import random: pkg.random -} From 3cb3bee83a2a3dd9e763c448da4c762511893fb2 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 10 Apr 2023 13:09:47 -0500 Subject: [PATCH 1118/1772] Use depit tool to automatically manage dependency vendoring Resolves #20 --- proposals/http/README.md | 10 +++++----- proposals/http/wit/deps.lock | 19 +++++++++++++++++++ proposals/http/wit/deps.toml | 4 ++++ proposals/http/wit/deps/io/world.wit | 3 +++ proposals/http/wit/deps/logging/world.wit | 3 +++ proposals/http/wit/deps/poll/world.wit | 3 +++ proposals/http/wit/deps/random/world.wit | 3 +++ 7 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 proposals/http/wit/deps.lock create mode 100644 proposals/http/wit/deps.toml create mode 100644 proposals/http/wit/deps/io/world.wit create mode 100644 proposals/http/wit/deps/logging/world.wit create mode 100644 proposals/http/wit/deps/poll/world.wit create mode 100644 proposals/http/wit/deps/random/world.wit diff --git a/proposals/http/README.md b/proposals/http/README.md index 5acd566dd..2fc9786bf 100644 --- a/proposals/http/README.md +++ b/proposals/http/README.md @@ -18,11 +18,11 @@ or can be manipulated in other ways with: wasm-tools component wit wit/ ... ``` -The HTTP proposal depends on the WASI IO and Logging proposals. For simplicity, -the Wit files for these proposals are currently copied into the `wit/deps` -directory and will be updated periodically to match their respective proposals. -As the Wit tooling develops, we should be able to avoid this form of manual -vendoring. +The `wit/deps` directory contains a live snapshot of the contents of several +other WASI proposals upon which this proposal depends. It is automatically +updated by running [`depit`](https://crates.io/crates/depit-cli) in the +root directory, which fetches the `main` branch of each proposal. As things +stablize, `wit/deps.toml` will be updated to refer to versioned releases. ### Current Phase diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock new file mode 100644 index 000000000..846adb42f --- /dev/null +++ b/proposals/http/wit/deps.lock @@ -0,0 +1,19 @@ +[io] +url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +sha256 = "7450142aeb3f1688ee2b12853344e262caf6aee0718dc0296316f7f6b3afd91f" +sha512 = "5cc0f60d190e16d6dd52a4ca2fc862f007465e7642e98061b41c90778e1f2b00aeb2543b6fadbb6a137dd548d86e9e55edcfb30388adcc6a160b4cdc29d378ec" + +[logging] +url = "https://github.com/WebAssembly/wasi-logging/archive/main.tar.gz" +sha256 = "f378a2b6a36af096528ec5e7031da474990cecaec1949c663befc5066d719f6f" +sha512 = "ba09307b12f5428c3058d878001c9fb15df21933c6203328f785d5009a4fc0cf304950271590d4146305a2d8b8988595f396d955961168cb6bfa7ea9af1cc362" + +[poll] +url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" +sha256 = "065422b0ea6ccb2a9facc6b87b902eef110c53d76fc31f341a6bc8d0b0285b6a" +sha512 = "19a55cd3072a19ae6a1774723a4962e7a155a5ce89a27175e8c76020efb4d00bc92ebb78427d92bcb8effd4f0d03ebf0a0daa747ecd981b8d31d5abc2ad86423" + +[random] +url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" +sha256 = "79b6417bb1ab3c82c241c56021e717f258e2a0b3ab94db93907ca11d7f92ed66" +sha512 = "1e657ac56420e65bde75eabea920a605a0ff4adc6f2ba8b7cf1c37a603710449bc1a29568dda2b61c04ae9889d2b1a82b9935d4b9d573eb48a83e0ecf9cad591" diff --git a/proposals/http/wit/deps.toml b/proposals/http/wit/deps.toml new file mode 100644 index 000000000..907c4acbd --- /dev/null +++ b/proposals/http/wit/deps.toml @@ -0,0 +1,4 @@ +io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +logging = "https://github.com/WebAssembly/wasi-logging/archive/main.tar.gz" +poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" +random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit new file mode 100644 index 000000000..bae7c92b3 --- /dev/null +++ b/proposals/http/wit/deps/io/world.wit @@ -0,0 +1,3 @@ +default world example-world { + import streams: pkg.streams +} diff --git a/proposals/http/wit/deps/logging/world.wit b/proposals/http/wit/deps/logging/world.wit new file mode 100644 index 000000000..b5af1514f --- /dev/null +++ b/proposals/http/wit/deps/logging/world.wit @@ -0,0 +1,3 @@ +default world example-world { + import logging: pkg.logging +} diff --git a/proposals/http/wit/deps/poll/world.wit b/proposals/http/wit/deps/poll/world.wit new file mode 100644 index 000000000..3a002e070 --- /dev/null +++ b/proposals/http/wit/deps/poll/world.wit @@ -0,0 +1,3 @@ +default world example-world { + import poll: pkg.poll +} diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit new file mode 100644 index 000000000..8d54b3b2c --- /dev/null +++ b/proposals/http/wit/deps/random/world.wit @@ -0,0 +1,3 @@ +default world example-world { + import random: pkg.random +} From 9441cb1995c10d8d0f16052aa050393a67a42dc5 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Tue, 11 Apr 2023 15:48:09 -0500 Subject: [PATCH 1119/1772] Update README.md to refer to 'depit update' --- proposals/http/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/proposals/http/README.md b/proposals/http/README.md index 2fc9786bf..1f2ca873e 100644 --- a/proposals/http/README.md +++ b/proposals/http/README.md @@ -20,9 +20,10 @@ wasm-tools component wit wit/ ... The `wit/deps` directory contains a live snapshot of the contents of several other WASI proposals upon which this proposal depends. It is automatically -updated by running [`depit`](https://crates.io/crates/depit-cli) in the -root directory, which fetches the `main` branch of each proposal. As things -stablize, `wit/deps.toml` will be updated to refer to versioned releases. +updated by running [`depit update`](https://crates.io/crates/depit-cli) in the +root directory, which fetches the live contents of the `main` branch of each +proposal. As things stablize, `wit/deps.toml` will be updated to refer to +versioned releases. ### Current Phase From 05d07a0fef936b1fc8550b7084b94cc696c9ef59 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Tue, 11 Apr 2023 18:17:12 -0500 Subject: [PATCH 1120/1772] Update depit to wit-deps in README.md --- proposals/http/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/http/README.md b/proposals/http/README.md index 1f2ca873e..7ae657b23 100644 --- a/proposals/http/README.md +++ b/proposals/http/README.md @@ -20,9 +20,9 @@ wasm-tools component wit wit/ ... The `wit/deps` directory contains a live snapshot of the contents of several other WASI proposals upon which this proposal depends. It is automatically -updated by running [`depit update`](https://crates.io/crates/depit-cli) in the -root directory, which fetches the live contents of the `main` branch of each -proposal. As things stablize, `wit/deps.toml` will be updated to refer to +updated by running [`wit-deps update`](https://crates.io/crates/wit-deps-cli) +in the root directory, which fetches the live contents of the `main` branch of +each proposal. As things stablize, `wit/deps.toml` will be updated to refer to versioned releases. ### Current Phase From 8fb0096d6d86b9fb675a351841bfa6e18ad85814 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 12 Apr 2023 08:36:50 -0700 Subject: [PATCH 1121/1772] Change the clocks API from pseudo-handles to link-time authority (#42) Remove the `wall-clock` and `monotonic-clock` pseudo-handle types, and change `now()` and similar functions to be callable without any arguments. For users that don't need multiple wall clocks or multiple monotonic clocks, this significantly simplifies the API. For users that do need multiple wall clocks or multiple monotonic clocks at runtime, the component model could be extended to allow instances to be used as resources, which would allow any link-time authority API to be used through a handle. This seems like a better overall approach for WASI, as it means that many APIs won't need to decide between using handles for theoretical flexibility or using link-time authority for immediate usability. We can just use link-time authority when the immediate use cases want it, and use instance handles when the need arises to use them dynamically. --- proposals/clocks/example-world.md | 97 ++----------------- .../clocks/wit/instance-monotonic-clock.wit | 15 --- proposals/clocks/wit/instance-wall-clock.wit | 15 --- proposals/clocks/wit/monotonic-clock.wit | 22 ++--- proposals/clocks/wit/wall-clock.wit | 27 ++---- proposals/clocks/wit/world.wit | 2 - 6 files changed, 25 insertions(+), 153 deletions(-) delete mode 100644 proposals/clocks/wit/instance-monotonic-clock.wit delete mode 100644 proposals/clocks/wit/instance-wall-clock.wit diff --git a/proposals/clocks/example-world.md b/proposals/clocks/example-world.md index a42fb0d21..a33878b4a 100644 --- a/proposals/clocks/example-world.md +++ b/proposals/clocks/example-world.md @@ -6,8 +6,6 @@
                          • interface monotonic-clock
                          • interface wall-clock
                          • interface timezone
                          • -
                          • interface instance-monotonic-clock
                          • -
                          • interface instance-wall-clock
                        @@ -63,19 +61,16 @@ mean "ready".

                        time.

                        It is intended to be portable at least between Unix-family platforms and Windows.

                        +

                        A monotonic clock is a clock which has an unspecified initial value, and +successive reads of the clock will produce non-decreasing values.

                        +

                        It is intended for measuring elapsed time.


                        Types

                        type pollable

                        pollable

                        -#### `type monotonic-clock` -`u32` -

                        A monotonic clock is a clock which has an unspecified initial value, and -successive reads of the clock will produce non-decreasing values. -

                        It is intended for measuring elapsed time.

                        -

                        This represents a resource.

                        -

                        type instant

                        -

                        u64

                        +#### `type instant` +`u64`

                        A timestamp in nanoseconds.


                        Functions

                        @@ -83,20 +78,12 @@ successive reads of the clock will produce non-decreasing values.

                        Read the current value of the clock.

                        The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

                        -
                        Params
                        -
                        Return values

                        resolution: func

                        Query the resolution of the clock.

                        -
                        Params
                        -
                        Return values
                        • instant
                        • @@ -106,7 +93,6 @@ produce a sequence of non-decreasing values.

                          reached.

                          Params
                          @@ -114,29 +100,19 @@ reached.

                          -

                          drop-monotonic-clock: func

                          -

                          Dispose of the specified monotonic-clock, after which it may no longer -be used.

                          -
                          Params
                          -

                          Import interface wall-clock

                          WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                          It is intended to be portable at least between Unix-family platforms and Windows.

                          -
                          -

                          Types

                          -

                          type wall-clock

                          -

                          u32

                          A wall clock is a clock which measures the date and time according to -some external reference. +some external reference.

                          External references may be reset, so this clock is not necessarily monotonic, making it unsuitable for measuring elapsed time.

                          It is intended for reporting the current date and time for humans.

                          -

                          This represents a resource.

                          +
                          +

                          Types

                          record datetime

                          A time and date in seconds plus nanoseconds.

                          Record Fields
                          @@ -154,10 +130,6 @@ will not necessarily produce a sequence of non-decreasing values.

                          1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, also known as Unix Time.

                          The nanoseconds field of the output is always less than 1000000000.

                          -
                          Params
                          -
                          Return values

    Query the resolution of the clock.

    The nanoseconds field of the output is always less than 1000000000.

    -
    Params
    -
    Return values
    -

    drop-wall-clock: func

    -

    Dispose of the specified wall-clock, after which it may no longer -be used.

    -
    Params
    -

    Import interface timezone


    Types

    @@ -261,45 +222,3 @@ be used.

    -

    Import interface instance-monotonic-clock

    -

    This interfaces proves a clock handles for monotonic clock, suitable for -general-purpose application needs.

    -
    -

    Types

    -

    type monotonic-clock

    -

    monotonic-clock

    -

    ----- -

    Functions

    -

    instance-monotonic-clock: func

    -

    Return a handle to a monotonic clock, suitable for general-purpose -application needs.

    -

    This allocates a new handle, so applications with frequent need of a -clock handle should call this function once and reuse the handle -instead of calling this function each time.

    -

    This represents a value import.

    -
    Return values
    - -

    Import interface instance-wall-clock

    -

    This interfaces proves a clock handles for wall clock, suitable for -general-purpose application needs.

    -
    -

    Types

    -

    type wall-clock

    -

    wall-clock

    -

    ----- -

    Functions

    -

    instance-wall-clock: func

    -

    Return a handle to a wall clock, suitable for general-purpose -application needs.

    -

    This allocates a new handle, so applications with frequent need of a -clock handle should call this function once and reuse the handle -instead of calling this function each time.

    -

    This represents a value import.

    -
    Return values
    - diff --git a/proposals/clocks/wit/instance-monotonic-clock.wit b/proposals/clocks/wit/instance-monotonic-clock.wit deleted file mode 100644 index 4cffa4a57..000000000 --- a/proposals/clocks/wit/instance-monotonic-clock.wit +++ /dev/null @@ -1,15 +0,0 @@ -/// This interfaces proves a clock handles for monotonic clock, suitable for -/// general-purpose application needs. -default interface instance-monotonic-clock { - use pkg.monotonic-clock.{monotonic-clock} - - /// Return a handle to a monotonic clock, suitable for general-purpose - /// application needs. - /// - /// This allocates a new handle, so applications with frequent need of a - /// clock handle should call this function once and reuse the handle - /// instead of calling this function each time. - /// - /// This [represents a value import](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Value_Imports). - instance-monotonic-clock: func() -> monotonic-clock -} diff --git a/proposals/clocks/wit/instance-wall-clock.wit b/proposals/clocks/wit/instance-wall-clock.wit deleted file mode 100644 index 3a55b5526..000000000 --- a/proposals/clocks/wit/instance-wall-clock.wit +++ /dev/null @@ -1,15 +0,0 @@ -/// This interfaces proves a clock handles for wall clock, suitable for -/// general-purpose application needs. -default interface instance-wall-clock { - use pkg.wall-clock.{wall-clock} - - /// Return a handle to a wall clock, suitable for general-purpose - /// application needs. - /// - /// This allocates a new handle, so applications with frequent need of a - /// clock handle should call this function once and reuse the handle - /// instead of calling this function each time. - /// - /// This [represents a value import](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Value_Imports). - instance-wall-clock: func() -> wall-clock -} diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index 51c2203c9..42e2981f5 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -3,38 +3,30 @@ /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +/// +/// A monotonic clock is a clock which has an unspecified initial value, and +/// successive reads of the clock will produce non-decreasing values. +/// +/// It is intended for measuring elapsed time. default interface monotonic-clock { use poll.poll.{pollable} /// A timestamp in nanoseconds. type instant = u64 - /// A monotonic clock is a clock which has an unspecified initial value, and - /// successive reads of the clock will produce non-decreasing values. - /// - /// It is intended for measuring elapsed time. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type monotonic-clock = u32 - /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - now: func(this: monotonic-clock) -> instant + now: func() -> instant /// Query the resolution of the clock. - resolution: func(this: monotonic-clock) -> instant + resolution: func() -> instant /// Create a `pollable` which will resolve once the specified time has been /// reached. subscribe: func( - this: monotonic-clock, when: instant, absolute: bool ) -> pollable - - /// Dispose of the specified `monotonic-clock`, after which it may no longer - /// be used. - drop-monotonic-clock: func(this: monotonic-clock) } diff --git a/proposals/clocks/wit/wall-clock.wit b/proposals/clocks/wit/wall-clock.wit index c60861acd..89c5a75da 100644 --- a/proposals/clocks/wit/wall-clock.wit +++ b/proposals/clocks/wit/wall-clock.wit @@ -4,6 +4,14 @@ /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +/// +/// A wall clock is a clock which measures the date and time according to +/// some external reference. +/// +/// External references may be reset, so this clock is not necessarily +/// monotonic, making it unsuitable for measuring elapsed time. +/// +/// It is intended for reporting the current date and time for humans. default interface wall-clock { /// A time and date in seconds plus nanoseconds. record datetime { @@ -11,17 +19,6 @@ default interface wall-clock { nanoseconds: u32, } - /// A wall clock is a clock which measures the date and time according to - /// some external reference. - /// - /// External references may be reset, so this clock is not necessarily - /// monotonic, making it unsuitable for measuring elapsed time. - /// - /// It is intended for reporting the current date and time for humans. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type wall-clock = u32 - /// Read the current value of the clock. /// /// This clock is not monotonic, therefore calling this function repeatedly @@ -35,14 +32,10 @@ default interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - now: func(this: wall-clock) -> datetime + now: func() -> datetime /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - resolution: func(this: wall-clock) -> datetime - - /// Dispose of the specified `wall-clock`, after which it may no longer - /// be used. - drop-wall-clock: func(this: wall-clock) + resolution: func() -> datetime } diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index e0eb0835e..8e3da6cc0 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -2,6 +2,4 @@ default world example-world { import monotonic-clock: pkg.monotonic-clock import wall-clock: pkg.wall-clock import timezone: pkg.timezone - import instance-monotonic-clock: pkg.instance-monotonic-clock - import instance-wall-clock: pkg.instance-wall-clock } From d69e2a03548365bffacc959b708dc7367c8b563e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 12 Apr 2023 09:15:05 -0700 Subject: [PATCH 1122/1772] Update to the latest wasi-clocks. --- proposals/cli/command.md | 97 ++----------------- proposals/cli/wit/command.wit | 2 - .../deps/clocks/instance-monotonic-clock.wit | 15 --- .../wit/deps/clocks/instance-wall-clock.wit | 15 --- .../cli/wit/deps/clocks/monotonic-clock.wit | 22 ++--- proposals/cli/wit/deps/clocks/wall-clock.wit | 27 ++---- 6 files changed, 25 insertions(+), 153 deletions(-) delete mode 100644 proposals/cli/wit/deps/clocks/instance-monotonic-clock.wit delete mode 100644 proposals/cli/wit/deps/clocks/instance-wall-clock.wit diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 149fdb792..10ee27d11 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -5,8 +5,6 @@
  • interface wall-clock
  • interface poll
  • interface monotonic-clock
  • -
  • interface instance-wall-clock
  • -
  • interface instance-monotonic-clock
  • interface timezone
  • interface streams
  • interface filesystem
  • @@ -38,16 +36,13 @@ time. The name "wall" makes an analogy to a "clock on the wall&qu is not necessarily monotonic as it may be reset.

    It is intended to be portable at least between Unix-family platforms and Windows.

    -
    -

    Types

    -

    type wall-clock

    -

    u32

    A wall clock is a clock which measures the date and time according to -some external reference. +some external reference.

    External references may be reset, so this clock is not necessarily monotonic, making it unsuitable for measuring elapsed time.

    It is intended for reporting the current date and time for humans.

    -

    This represents a resource.

    +
    +

    Types

    record datetime

    A time and date in seconds plus nanoseconds.

    Record Fields
    @@ -65,10 +60,6 @@ will not necessarily produce a sequence of non-decreasing values.

    1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, also known as Unix Time.

    The nanoseconds field of the output is always less than 1000000000.

    -
    Params
    -
    Return values

    Query the resolution of the clock.

    The nanoseconds field of the output is always less than 1000000000.

    -
    Params
    -
    Return values
    -

    drop-wall-clock: func

    -

    Dispose of the specified wall-clock, after which it may no longer -be used.

    -
    Params
    -

    Import interface poll

    A poll API intended to let users wait for I/O events on multiple handles at once.

    @@ -143,19 +123,16 @@ mean "ready".

    time.

    It is intended to be portable at least between Unix-family platforms and Windows.

    +

    A monotonic clock is a clock which has an unspecified initial value, and +successive reads of the clock will produce non-decreasing values.

    +

    It is intended for measuring elapsed time.


    Types

    type pollable

    pollable

    -#### `type monotonic-clock` -`u32` -

    A monotonic clock is a clock which has an unspecified initial value, and -successive reads of the clock will produce non-decreasing values. -

    It is intended for measuring elapsed time.

    -

    This represents a resource.

    -

    type instant

    -

    u64

    +#### `type instant` +`u64`

    A timestamp in nanoseconds.


    Functions

    @@ -163,20 +140,12 @@ successive reads of the clock will produce non-decreasing values.

    Read the current value of the clock.

    The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

    -
    Params
    -
    Return values

    resolution: func

    Query the resolution of the clock.

    -
    Params
    -
    Return values
    • instant
    • @@ -186,7 +155,6 @@ produce a sequence of non-decreasing values.

      reached.

      Params
      @@ -194,55 +162,6 @@ reached.

      -

      drop-monotonic-clock: func

      -

      Dispose of the specified monotonic-clock, after which it may no longer -be used.

      -
      Params
      - -

      Import interface instance-wall-clock

      -

      This interfaces proves a clock handles for wall clock, suitable for -general-purpose application needs.

      -
      -

      Types

      -

      type wall-clock

      -

      wall-clock

      -

      ----- -

      Functions

      -

      instance-wall-clock: func

      -

      Return a handle to a wall clock, suitable for general-purpose -application needs.

      -

      This allocates a new handle, so applications with frequent need of a -clock handle should call this function once and reuse the handle -instead of calling this function each time.

      -

      This represents a value import.

      -
      Return values
      - -

      Import interface instance-monotonic-clock

      -

      This interfaces proves a clock handles for monotonic clock, suitable for -general-purpose application needs.

      -
      -

      Types

      -

      type monotonic-clock

      -

      monotonic-clock

      -

      ----- -

      Functions

      -

      instance-monotonic-clock: func

      -

      Return a handle to a monotonic clock, suitable for general-purpose -application needs.

      -

      This allocates a new handle, so applications with frequent need of a -clock handle should call this function once and reuse the handle -instead of calling this function each time.

      -

      This represents a value import.

      -
      Return values
      -

      Import interface timezone


      Types

      diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index d3b8b4614..f00c5aabf 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,8 +1,6 @@ default world command { import wall-clock: clocks.wall-clock import monotonic-clock: clocks.monotonic-clock - import instance-wall-clock: clocks.instance-wall-clock - import instance-monotonic-clock: clocks.instance-monotonic-clock import timezone: clocks.timezone import filesystem: filesystem.types import instance-network: sockets.instance-network diff --git a/proposals/cli/wit/deps/clocks/instance-monotonic-clock.wit b/proposals/cli/wit/deps/clocks/instance-monotonic-clock.wit deleted file mode 100644 index 4cffa4a57..000000000 --- a/proposals/cli/wit/deps/clocks/instance-monotonic-clock.wit +++ /dev/null @@ -1,15 +0,0 @@ -/// This interfaces proves a clock handles for monotonic clock, suitable for -/// general-purpose application needs. -default interface instance-monotonic-clock { - use pkg.monotonic-clock.{monotonic-clock} - - /// Return a handle to a monotonic clock, suitable for general-purpose - /// application needs. - /// - /// This allocates a new handle, so applications with frequent need of a - /// clock handle should call this function once and reuse the handle - /// instead of calling this function each time. - /// - /// This [represents a value import](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Value_Imports). - instance-monotonic-clock: func() -> monotonic-clock -} diff --git a/proposals/cli/wit/deps/clocks/instance-wall-clock.wit b/proposals/cli/wit/deps/clocks/instance-wall-clock.wit deleted file mode 100644 index 3a55b5526..000000000 --- a/proposals/cli/wit/deps/clocks/instance-wall-clock.wit +++ /dev/null @@ -1,15 +0,0 @@ -/// This interfaces proves a clock handles for wall clock, suitable for -/// general-purpose application needs. -default interface instance-wall-clock { - use pkg.wall-clock.{wall-clock} - - /// Return a handle to a wall clock, suitable for general-purpose - /// application needs. - /// - /// This allocates a new handle, so applications with frequent need of a - /// clock handle should call this function once and reuse the handle - /// instead of calling this function each time. - /// - /// This [represents a value import](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Value_Imports). - instance-wall-clock: func() -> wall-clock -} diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index 51c2203c9..42e2981f5 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -3,38 +3,30 @@ /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +/// +/// A monotonic clock is a clock which has an unspecified initial value, and +/// successive reads of the clock will produce non-decreasing values. +/// +/// It is intended for measuring elapsed time. default interface monotonic-clock { use poll.poll.{pollable} /// A timestamp in nanoseconds. type instant = u64 - /// A monotonic clock is a clock which has an unspecified initial value, and - /// successive reads of the clock will produce non-decreasing values. - /// - /// It is intended for measuring elapsed time. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type monotonic-clock = u32 - /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - now: func(this: monotonic-clock) -> instant + now: func() -> instant /// Query the resolution of the clock. - resolution: func(this: monotonic-clock) -> instant + resolution: func() -> instant /// Create a `pollable` which will resolve once the specified time has been /// reached. subscribe: func( - this: monotonic-clock, when: instant, absolute: bool ) -> pollable - - /// Dispose of the specified `monotonic-clock`, after which it may no longer - /// be used. - drop-monotonic-clock: func(this: monotonic-clock) } diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit index c60861acd..89c5a75da 100644 --- a/proposals/cli/wit/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -4,6 +4,14 @@ /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +/// +/// A wall clock is a clock which measures the date and time according to +/// some external reference. +/// +/// External references may be reset, so this clock is not necessarily +/// monotonic, making it unsuitable for measuring elapsed time. +/// +/// It is intended for reporting the current date and time for humans. default interface wall-clock { /// A time and date in seconds plus nanoseconds. record datetime { @@ -11,17 +19,6 @@ default interface wall-clock { nanoseconds: u32, } - /// A wall clock is a clock which measures the date and time according to - /// some external reference. - /// - /// External references may be reset, so this clock is not necessarily - /// monotonic, making it unsuitable for measuring elapsed time. - /// - /// It is intended for reporting the current date and time for humans. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type wall-clock = u32 - /// Read the current value of the clock. /// /// This clock is not monotonic, therefore calling this function repeatedly @@ -35,14 +32,10 @@ default interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - now: func(this: wall-clock) -> datetime + now: func() -> datetime /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - resolution: func(this: wall-clock) -> datetime - - /// Dispose of the specified `wall-clock`, after which it may no longer - /// be used. - drop-wall-clock: func(this: wall-clock) + resolution: func() -> datetime } From 6a69dbc97a3c474230b5825d7b2bafc83cfa9876 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 12 Apr 2023 09:16:23 -0700 Subject: [PATCH 1123/1772] Update to the latest wasi-clocks. (#113) --- proposals/filesystem/example-world.md | 24 +++-------------- .../filesystem/wit/deps/clocks/wall-clock.wit | 27 +++++++------------ 2 files changed, 13 insertions(+), 38 deletions(-) diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md index 0c0b65031..8ce1d179f 100644 --- a/proposals/filesystem/example-world.md +++ b/proposals/filesystem/example-world.md @@ -314,16 +314,13 @@ time. The name "wall" makes an analogy to a "clock on the wall&qu is not necessarily monotonic as it may be reset.

      It is intended to be portable at least between Unix-family platforms and Windows.

      -
      -

      Types

      -

      type wall-clock

      -

      u32

      A wall clock is a clock which measures the date and time according to -some external reference. +some external reference.

      External references may be reset, so this clock is not necessarily monotonic, making it unsuitable for measuring elapsed time.

      It is intended for reporting the current date and time for humans.

      -

      This represents a resource.

      +
      +

      Types

      record datetime

      A time and date in seconds plus nanoseconds.

      Record Fields
      @@ -341,10 +338,6 @@ will not necessarily produce a sequence of non-decreasing values.

      1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, also known as Unix Time.

      The nanoseconds field of the output is always less than 1000000000.

      -
      Params
      -
      Return values

    Query the resolution of the clock.

    The nanoseconds field of the output is always less than 1000000000.

    -
    Params
    -
    Return values
    -

    drop-wall-clock: func

    -

    Dispose of the specified wall-clock, after which it may no longer -be used.

    -
    Params
    -

    Import interface types

    WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without diff --git a/proposals/filesystem/wit/deps/clocks/wall-clock.wit b/proposals/filesystem/wit/deps/clocks/wall-clock.wit index c60861acd..89c5a75da 100644 --- a/proposals/filesystem/wit/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/wall-clock.wit @@ -4,6 +4,14 @@ /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +/// +/// A wall clock is a clock which measures the date and time according to +/// some external reference. +/// +/// External references may be reset, so this clock is not necessarily +/// monotonic, making it unsuitable for measuring elapsed time. +/// +/// It is intended for reporting the current date and time for humans. default interface wall-clock { /// A time and date in seconds plus nanoseconds. record datetime { @@ -11,17 +19,6 @@ default interface wall-clock { nanoseconds: u32, } - /// A wall clock is a clock which measures the date and time according to - /// some external reference. - /// - /// External references may be reset, so this clock is not necessarily - /// monotonic, making it unsuitable for measuring elapsed time. - /// - /// It is intended for reporting the current date and time for humans. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type wall-clock = u32 - /// Read the current value of the clock. /// /// This clock is not monotonic, therefore calling this function repeatedly @@ -35,14 +32,10 @@ default interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - now: func(this: wall-clock) -> datetime + now: func() -> datetime /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - resolution: func(this: wall-clock) -> datetime - - /// Dispose of the specified `wall-clock`, after which it may no longer - /// be used. - drop-wall-clock: func(this: wall-clock) + resolution: func() -> datetime } From e98a39316f9503485069d567fb2b5276f8d1ce85 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Wed, 12 Apr 2023 17:23:28 -0500 Subject: [PATCH 1124/1772] include wasi-clocks in the proxy world --- proposals/http/wit/deps.lock | 5 ++ proposals/http/wit/deps.toml | 1 + .../http/wit/deps/clocks/monotonic-clock.wit | 32 ++++++++++ proposals/http/wit/deps/clocks/timezone.wit | 61 +++++++++++++++++++ proposals/http/wit/deps/clocks/wall-clock.wit | 41 +++++++++++++ proposals/http/wit/deps/clocks/world.wit | 5 ++ proposals/http/wit/proxy.wit | 5 +- 7 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 proposals/http/wit/deps/clocks/monotonic-clock.wit create mode 100644 proposals/http/wit/deps/clocks/timezone.wit create mode 100644 proposals/http/wit/deps/clocks/wall-clock.wit create mode 100644 proposals/http/wit/deps/clocks/world.wit diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 846adb42f..25ec5b7ef 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,3 +1,8 @@ +[clocks] +url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" +sha256 = "3fb1c6a5541b6288fe9b22210b610b89ebd97a4318bdc174fe256f5635b1c0ad" +sha512 = "e89cbfd4988f4299d1a9c7da484362df22e29550ee2d559cf82e20e0925e581f0df420818c6bae984df54e336b8eb747fc5171ddeccfe91ca25f48566a258ff6" + [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" sha256 = "7450142aeb3f1688ee2b12853344e262caf6aee0718dc0296316f7f6b3afd91f" diff --git a/proposals/http/wit/deps.toml b/proposals/http/wit/deps.toml index 907c4acbd..fa6040d13 100644 --- a/proposals/http/wit/deps.toml +++ b/proposals/http/wit/deps.toml @@ -2,3 +2,4 @@ io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" logging = "https://github.com/WebAssembly/wasi-logging/archive/main.tar.gz" poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" +clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit new file mode 100644 index 000000000..42e2981f5 --- /dev/null +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -0,0 +1,32 @@ +/// WASI Monotonic Clock is a clock API intended to let users measure elapsed +/// time. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A monotonic clock is a clock which has an unspecified initial value, and +/// successive reads of the clock will produce non-decreasing values. +/// +/// It is intended for measuring elapsed time. +default interface monotonic-clock { + use poll.poll.{pollable} + + /// A timestamp in nanoseconds. + type instant = u64 + + /// Read the current value of the clock. + /// + /// The clock is monotonic, therefore calling this function repeatedly will + /// produce a sequence of non-decreasing values. + now: func() -> instant + + /// Query the resolution of the clock. + resolution: func() -> instant + + /// Create a `pollable` which will resolve once the specified time has been + /// reached. + subscribe: func( + when: instant, + absolute: bool + ) -> pollable +} diff --git a/proposals/http/wit/deps/clocks/timezone.wit b/proposals/http/wit/deps/clocks/timezone.wit new file mode 100644 index 000000000..63f99cc40 --- /dev/null +++ b/proposals/http/wit/deps/clocks/timezone.wit @@ -0,0 +1,61 @@ +default interface timezone { + use pkg.wall-clock.{datetime} + + /// A timezone. + /// + /// In timezones that recognize daylight saving time, also known as daylight + /// time and summer time, the information returned from the functions varies + /// over time to reflect these adjustments. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type timezone = u32 + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + display: func(this: timezone, when: datetime) -> timezone-display + + /// The same as `display`, but only return the UTC offset. + utc-offset: func(this: timezone, when: datetime) -> s32 + + /// Dispose of the specified input-stream, after which it may no longer + /// be used. + drop-timezone: func(this: timezone) + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/http/wit/deps/clocks/wall-clock.wit b/proposals/http/wit/deps/clocks/wall-clock.wit new file mode 100644 index 000000000..89c5a75da --- /dev/null +++ b/proposals/http/wit/deps/clocks/wall-clock.wit @@ -0,0 +1,41 @@ +/// WASI Wall Clock is a clock API intended to let users query the current +/// time. The name "wall" makes an analogy to a "clock on the wall", which +/// is not necessarily monotonic as it may be reset. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A wall clock is a clock which measures the date and time according to +/// some external reference. +/// +/// External references may be reset, so this clock is not necessarily +/// monotonic, making it unsuitable for measuring elapsed time. +/// +/// It is intended for reporting the current date and time for humans. +default interface wall-clock { + /// A time and date in seconds plus nanoseconds. + record datetime { + seconds: u64, + nanoseconds: u32, + } + + /// Read the current value of the clock. + /// + /// This clock is not monotonic, therefore calling this function repeatedly + /// will not necessarily produce a sequence of non-decreasing values. + /// + /// The returned timestamps represent the number of seconds since + /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], + /// also known as [Unix Time]. + /// + /// The nanoseconds field of the output is always less than 1000000000. + /// + /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + now: func() -> datetime + + /// Query the resolution of the clock. + /// + /// The nanoseconds field of the output is always less than 1000000000. + resolution: func() -> datetime +} diff --git a/proposals/http/wit/deps/clocks/world.wit b/proposals/http/wit/deps/clocks/world.wit new file mode 100644 index 000000000..8e3da6cc0 --- /dev/null +++ b/proposals/http/wit/deps/clocks/world.wit @@ -0,0 +1,5 @@ +default world example-world { + import monotonic-clock: pkg.monotonic-clock + import wall-clock: pkg.wall-clock + import timezone: pkg.timezone +} diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index a46128709..944877a31 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -4,9 +4,10 @@ // outgoing HTTP requests. default world proxy { // HTTP proxies have access to time and randomness. + import wall-clock: clocks.wall-clock + import monotonic-clock: clocks.monotonic-clock + import timezone: clocks.timezone import random: random.random - // TODO: add `import wall-clock: clocks.wall-clock` - // TODO: add `import monotonic-clock: clocks.monotonic-clock` // This is the default logging handler to use when user code simply wants to // log to a developer-facing console (e.g., via `console.log()`). From 4bcd906ba904f2dd07ae293762527a105e267b16 Mon Sep 17 00:00:00 2001 From: Lann Martin Date: Wed, 19 Apr 2023 17:12:48 -0400 Subject: [PATCH 1125/1772] Change fields value type from string to list --- proposals/http/wit/types.wit | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index b45897b50..3a41a11d9 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -43,11 +43,11 @@ default interface types { type fields = u32 drop-fields: func(fields: fields) new-fields: func(entries: list>) -> fields - fields-get: func(fields: fields, name: string) -> list - fields-set: func(fields: fields, name: string, value: list) + fields-get: func(fields: fields, name: string) -> list> + fields-set: func(fields: fields, name: string, value: list>) fields-delete: func(fields: fields, name: string) - fields-append: func(fields: fields, name: string, value: string) - fields-entries: func(fields: fields) -> list> + fields-append: func(fields: fields, name: string, value: list) + fields-entries: func(fields: fields) -> list>> fields-clone: func(fields: fields) -> fields type headers = fields From 6dd94969245b34018718738d7f8885e468c2e16e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 27 Apr 2023 15:58:19 -0700 Subject: [PATCH 1126/1772] Add an `access-at` function. (#114) Adds an `access-at` function which checks for a filesystem path being readable, writeable, or executable, or whether it exists, without performing an actual access. This is similar to `faccessat` in POSIX, though it only supports the `AT_EACCESS` mode, where the effective user id is tested, as WASI doesn't otherwise expose the difference between the effective and real user IDs. --- proposals/filesystem/example-world.md | 32 +++++++++++++++++++++++++++ proposals/filesystem/wit/types.wit | 29 ++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md index 8ce1d179f..bb1d6d53d 100644 --- a/proposals/filesystem/example-world.md +++ b/proposals/filesystem/example-world.md @@ -817,6 +817,19 @@ in the near future. not reuse it thereafter. +

    variant access-type

    +

    Access type used by access-at.

    +
    Variant Cases
    +
      +
    • +

      access: modes

      +

      Test for readability, writeability, or executability. +

    • +
    • +

      exists

      +

      Test whether the path exists. +

    • +

    Functions

    read-via-stream: func

    @@ -1174,6 +1187,25 @@ filesystem, this function fails with e +

    access-at: func

    +

    Check accessibility of a filesystem path.

    +

    Check whether the given filesystem path names an object which is +readable, writeable, or executable, or whether it exists.

    +

    This does not a guarantee that subsequent accesses will succeed, as +filesystem permissions may be modified asynchronously by external +entities.

    +

    Note: This is similar to faccessat with the AT_EACCESS flag in POSIX.

    +
    Params
    + +
    Return values
    +

    unlink-file-at: func

    Unlink a filesystem object that is not a directory.

    Return error-code::is-directory if the path refers to a directory. diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 9530d6a63..c04f989bb 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -154,6 +154,15 @@ default interface types { executable, } + /// Access type used by `access-at`. + variant access-type { + /// Test for readability, writeability, or executability. + access(modes), + + /// Test whether the path exists. + exists, + } + /// Number of hard links to an inode. type link-count = u64 @@ -603,6 +612,26 @@ default interface types { new-path: string, ) -> result<_, error-code> + /// Check accessibility of a filesystem path. + /// + /// Check whether the given filesystem path names an object which is + /// readable, writeable, or executable, or whether it exists. + /// + /// This does not a guarantee that subsequent accesses will succeed, as + /// filesystem permissions may be modified asynchronously by external + /// entities. + /// + /// Note: This is similar to `faccessat` with the `AT_EACCESS` flag in POSIX. + access-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to check. + path: string, + /// The type of check to perform. + %ype: access-type + ) -> result<_, error-code> + /// Unlink a filesystem object that is not a directory. /// /// Return `error-code::is-directory` if the path refers to a directory. From e8527e5424a91daf08ea673bf8112c17a564907f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 4 May 2023 10:39:23 -0700 Subject: [PATCH 1127/1772] Add `isatty` support. This adds new terminal (pseudo-)resources, and new link-time authority functions which optionally return them. For now, these resources don't have any additional functions, and just support testing whether a terminal is present, supporting `isatty` functionality. In the future they could be extended to support querying terminal attributes and configuring terminal modes. --- proposals/cli/wit/terminal.wit | 59 ++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 proposals/cli/wit/terminal.wit diff --git a/proposals/cli/wit/terminal.wit b/proposals/cli/wit/terminal.wit new file mode 100644 index 000000000..988068af7 --- /dev/null +++ b/proposals/cli/wit/terminal.wit @@ -0,0 +1,59 @@ +interface terminal-input { + /// The input side of a terminal. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type terminal-input = u32 + + // In the future, this may include functions for disabling echoing, + // disabling input buffering so that keyboard events are sent through + // immediately, querying supported features, and so on. + + /// Dispose of the specified terminal-input after which it may no longer + /// be used. + drop-terminal-input: func(this: terminal-input) +} + +interface terminal-output { + /// The output side of a terminal. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type terminal-output = u32 + + // In the future, this may include functions for querying the terminal + // size, being notified of terminal size changes, querying supported + // features, and so on. + + /// Dispose of the specified terminal-output, after which it may no longer + /// be used. + drop-terminal-output: func(this: terminal-output) +} + +/// An interface providing an optional `terminal-input` for stdin as a +/// link-time authority. +interface terminal-stdin { + use self.terminal-input.{terminal-input} + + /// If stdin is connected to a terminal, return a `terminal-input` handle + /// allowing further interaction with it. + get-terminal-stdin: func() -> option +} + +/// An interface providing an optional `terminal-output` for stdout as a +/// link-time authority. +interface terminal-stdout { + use self.terminal-output.{terminal-output} + + /// If stdout is connected to a terminal, return a `terminal-output` handle + /// allowing further interaction with it. + get-terminal-stdout: func() -> option +} + +/// An interface providing an optional `terminal-output` for stderr as a +/// link-time authority. +interface terminal-stderr { + use self.terminal-output.{terminal-output} + + /// If stderr is connected to a terminal, return a `terminal-output` handle + /// allowing further interaction with it. + get-terminal-stderr: func() -> option +} From 00971b84a256f9f190099098e819397608f425b4 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 4 May 2023 11:49:24 -0700 Subject: [PATCH 1128/1772] Update to the latest wasi-filesystem. This pulls in WebAssembly/wasi-filesystem#114, which adds the `access-at` function. --- proposals/cli/command.md | 32 +++++++++++++++++++++ proposals/cli/wit/deps/filesystem/types.wit | 29 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 10ee27d11..f42d526b7 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -963,6 +963,19 @@ in the near future. not reuse it thereafter. +

    variant access-type

    +

    Access type used by access-at.

    +
    Variant Cases
    +
      +
    • +

      access: modes

      +

      Test for readability, writeability, or executability. +

    • +
    • +

      exists

      +

      Test whether the path exists. +

    • +

    Functions

    read-via-stream: func

    @@ -1320,6 +1333,25 @@ filesystem, this function fails with e +

    access-at: func

    +

    Check accessibility of a filesystem path.

    +

    Check whether the given filesystem path names an object which is +readable, writeable, or executable, or whether it exists.

    +

    This does not a guarantee that subsequent accesses will succeed, as +filesystem permissions may be modified asynchronously by external +entities.

    +

    Note: This is similar to faccessat with the AT_EACCESS flag in POSIX.

    +
    Params
    + +
    Return values
    +

    unlink-file-at: func

    Unlink a filesystem object that is not a directory.

    Return error-code::is-directory if the path refers to a directory. diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index 9530d6a63..c04f989bb 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -154,6 +154,15 @@ default interface types { executable, } + /// Access type used by `access-at`. + variant access-type { + /// Test for readability, writeability, or executability. + access(modes), + + /// Test whether the path exists. + exists, + } + /// Number of hard links to an inode. type link-count = u64 @@ -603,6 +612,26 @@ default interface types { new-path: string, ) -> result<_, error-code> + /// Check accessibility of a filesystem path. + /// + /// Check whether the given filesystem path names an object which is + /// readable, writeable, or executable, or whether it exists. + /// + /// This does not a guarantee that subsequent accesses will succeed, as + /// filesystem permissions may be modified asynchronously by external + /// entities. + /// + /// Note: This is similar to `faccessat` with the `AT_EACCESS` flag in POSIX. + access-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to check. + path: string, + /// The type of check to perform. + %ype: access-type + ) -> result<_, error-code> + /// Unlink a filesystem object that is not a directory. /// /// Return `error-code::is-directory` if the path refers to a directory. From ffa09049845bd75dfe2adae0ed57d15694981844 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 3 May 2023 14:47:19 -0700 Subject: [PATCH 1129/1772] Move `main`'s arguments out into separate imports. - Rename `main` to `run` to avoid colliding with language toolchains that assign special meaning to the name "main". - Move `run` to its own interface. - Instead of having the `run` function take stdio, command-line arguments, and preopens as arguments, have separate imports for those. This will make it easier to reuse the `run` interface in other worlds with other imports. --- proposals/cli/command.md | 50 +++++++++------------- proposals/cli/wit/command.wit | 12 +----- proposals/cli/wit/environment-preopens.wit | 5 ++- proposals/cli/wit/environment.wit | 3 ++ proposals/cli/wit/run.wit | 4 ++ proposals/cli/wit/stdio.wit | 14 ++++++ 6 files changed, 46 insertions(+), 42 deletions(-) create mode 100644 proposals/cli/wit/run.wit create mode 100644 proposals/cli/wit/stdio.wit diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 10ee27d11..f22709945 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -19,14 +19,11 @@

  • interface environment
  • interface environment-preopens
  • interface exit
  • -
  • type input-stream
  • -
  • type output-stream
  • -
  • type descriptor
  • Exports:
  • @@ -2551,19 +2548,31 @@ values each time it is called.

    • list<(string, string)>
    +

    get-arguments: func

    +

    Get the POSIX-style arguments to the program.

    +
    Return values
    +
      +
    • list<string>
    • +

    Import interface environment-preopens


    Types

    type descriptor

    descriptor

    +#### `type input-stream` +[`input-stream`](#input_stream) +

    +#### `type output-stream` +[`output-stream`](#output_stream) +

    ----

    Functions

    -

    preopens: func

    -

    Return a list of preopens for use in interpreting environment variables.

    +

    get-directories: func

    +

    Return the set of of preopened directories, and their path.

    Return values

    Import interface exit


    @@ -2574,29 +2583,12 @@ values each time it is called.

    -

    Exported types from world command

    +

    Export interface run


    -

    Types

    -

    type input-stream

    -

    input-stream

    -

    -#### `type output-stream` -[`output-stream`](#output_stream) -

    -#### `type descriptor` -[`descriptor`](#descriptor) -

    -## Exported functions from world `command` -

    main: func

    -
    Params
    - +

    Functions

    +

    run: func

    +

    Run the program.

    Return values
      -
    • result
    • +
    • result
    diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index f00c5aabf..93ac6e4ff 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -16,15 +16,5 @@ default world command { import environment: pkg.environment import environment-preopens: pkg.environment-preopens import exit: pkg.exit - - use io.streams.{input-stream, output-stream} - use filesystem.types.{descriptor} - - export main: func( - stdin: input-stream, - stdout: output-stream, - stderr: output-stream, - args: list, - preopens: list>, - ) -> result + export run: pkg.run } diff --git a/proposals/cli/wit/environment-preopens.wit b/proposals/cli/wit/environment-preopens.wit index f8213ca6a..e7ab89d75 100644 --- a/proposals/cli/wit/environment-preopens.wit +++ b/proposals/cli/wit/environment-preopens.wit @@ -1,6 +1,7 @@ default interface environment-preopens { use filesystem.types.{descriptor} + use io.streams.{input-stream, output-stream} - /// Return a list of preopens for use in interpreting environment variables. - preopens: func() -> list> + /// Return the set of of preopened directories, and their path. + get-directories: func() -> list> } diff --git a/proposals/cli/wit/environment.wit b/proposals/cli/wit/environment.wit index f3ab7181b..876ea3a0c 100644 --- a/proposals/cli/wit/environment.wit +++ b/proposals/cli/wit/environment.wit @@ -8,4 +8,7 @@ default interface environment { /// in the component model, this import function should return the same /// values each time it is called. get-environment: func() -> list> + + /// Get the POSIX-style arguments to the program. + get-arguments: func() -> list } diff --git a/proposals/cli/wit/run.wit b/proposals/cli/wit/run.wit new file mode 100644 index 000000000..2132e98e7 --- /dev/null +++ b/proposals/cli/wit/run.wit @@ -0,0 +1,4 @@ +default interface run { + /// Run the program. + run: func() -> result +} diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit new file mode 100644 index 000000000..9bdf5faec --- /dev/null +++ b/proposals/cli/wit/stdio.wit @@ -0,0 +1,14 @@ +default interface stdio { + use io.streams.{input-stream, output-stream} + + /// Stdio preopens: these are the resources that provide stdin, stdout, and + /// stderr. + record stdio-preopens { + stdin: input-stream, + stdout: output-stream, + stderr: output-stream, + } + + /// Return the set of stdio preopens. + get-stdio: func() -> stdio-preopens +} From 3d016ce8628e03e04af6ab606e4636c4fc6769ad Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 4 May 2023 10:42:36 -0700 Subject: [PATCH 1130/1772] Split the stdio interface into stdin, stdout, and stderr Put stdin, stdout, and stderr in their own interfaces to allow worlds to pick which ones they want. --- proposals/cli/command.md | 42 +++++++++++++++++++++++++++++++++++ proposals/cli/wit/command.wit | 3 +++ proposals/cli/wit/stdio.wit | 29 +++++++++++++----------- 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index f22709945..f66d4cb86 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -19,6 +19,9 @@
  • interface environment
  • interface environment-preopens
  • interface exit
  • +
  • interface stdin
  • +
  • interface stdout
  • +
  • interface stderr
  • Exports: @@ -2583,6 +2586,45 @@ values each time it is called.

    +

    Import interface stdin

    +
    +

    Types

    +

    type input-stream

    +

    input-stream

    +

    +---- +

    Functions

    +

    get-stdin: func

    +
    Return values
    + +

    Import interface stdout

    +
    +

    Types

    +

    type output-stream

    +

    output-stream

    +

    +---- +

    Functions

    +

    get-stdout: func

    +
    Return values
    + +

    Import interface stderr

    +
    +

    Types

    +

    type output-stream

    +

    output-stream

    +

    +---- +

    Functions

    +

    get-stderr: func

    +
    Return values
    +

    Export interface run


    Functions

    diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index 93ac6e4ff..e92bb6023 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -16,5 +16,8 @@ default world command { import environment: pkg.environment import environment-preopens: pkg.environment-preopens import exit: pkg.exit + import stdin: pkg.stdio.stdin + import stdout: pkg.stdio.stdout + import stderr: pkg.stdio.stderr export run: pkg.run } diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index 9bdf5faec..1f87e5485 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,14 +1,17 @@ -default interface stdio { - use io.streams.{input-stream, output-stream} - - /// Stdio preopens: these are the resources that provide stdin, stdout, and - /// stderr. - record stdio-preopens { - stdin: input-stream, - stdout: output-stream, - stderr: output-stream, - } - - /// Return the set of stdio preopens. - get-stdio: func() -> stdio-preopens +interface stdin { + use io.streams.{input-stream} + + get-stdin: func() -> input-stream +} + +interface stdout { + use io.streams.{output-stream} + + get-stdout: func() -> output-stream +} + +interface stderr { + use io.streams.{output-stream} + + get-stderr: func() -> output-stream } From 0f95f605813e565187326fd0c3c4c823336eec5c Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 10 May 2023 10:50:34 -0700 Subject: [PATCH 1131/1772] spelling: correct `writeable` to `writable` (#116) in both the modes flag, and documentation. --- proposals/filesystem/example-world.md | 6 +++--- proposals/filesystem/wit/types.wit | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md index bb1d6d53d..4d7c1e608 100644 --- a/proposals/filesystem/example-world.md +++ b/proposals/filesystem/example-world.md @@ -416,8 +416,8 @@ similar.

    filesystem.
  • -

    writeable:

    -

    True if the resource is considered writeable by the containing +

    writable:

    +

    True if the resource is considered writable by the containing filesystem.

  • @@ -1190,7 +1190,7 @@ filesystem, this function fails with e

    access-at: func

    Check accessibility of a filesystem path.

    Check whether the given filesystem path names an object which is -readable, writeable, or executable, or whether it exists.

    +readable, writable, or executable, or whether it exists.

    This does not a guarantee that subsequent accesses will succeed, as filesystem permissions may be modified asynchronously by external entities.

    diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index c04f989bb..e5729d909 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -146,9 +146,9 @@ default interface types { /// True if the resource is considered readable by the containing /// filesystem. readable, - /// True if the resource is considered writeable by the containing + /// True if the resource is considered writable by the containing /// filesystem. - writeable, + writable, /// True if the resource is considered executable by the containing /// filesystem. This does not apply to directories. executable, @@ -615,7 +615,7 @@ default interface types { /// Check accessibility of a filesystem path. /// /// Check whether the given filesystem path names an object which is - /// readable, writeable, or executable, or whether it exists. + /// readable, writable, or executable, or whether it exists. /// /// This does not a guarantee that subsequent accesses will succeed, as /// filesystem permissions may be modified asynchronously by external From 7b0c9aa39d1bb05cf77a5fb8de2024fc9d5ee1bf Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 10 May 2023 12:07:51 -0700 Subject: [PATCH 1132/1772] Fix a typo. (#115) Fix a typo in an argument name noticed by @codefromthecrypt. --- proposals/filesystem/example-world.md | 2 +- proposals/filesystem/wit/types.wit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md index 4d7c1e608..5c3eb642b 100644 --- a/proposals/filesystem/example-world.md +++ b/proposals/filesystem/example-world.md @@ -1200,7 +1200,7 @@ entities.

  • this: descriptor
  • path-flags: path-flags
  • path: string
  • -
  • ype: access-type
  • +
  • type: access-type
  • Return values
      diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index e5729d909..109c45099 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -629,7 +629,7 @@ default interface types { /// The relative path to check. path: string, /// The type of check to perform. - %ype: access-type + %type: access-type ) -> result<_, error-code> /// Unlink a filesystem object that is not a directory. From d7a4f276e038ed18a8a6bb067949094a71b0f85d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 10 May 2023 12:12:13 -0700 Subject: [PATCH 1133/1772] Add an `insecure` interface. (#29) Add an `insecure` interface, and split the seed function into its own interface, producing three interfaces: - `random`, for secure pseudo-random numbers - `insecure`, for pseudo-random numbers that are not secure - `insecure-seed`, for supporting hash-map DoS protection We've gone back and forth on whether such an API is desirable, but it's now motivated by the need to implement things like JavaScript's `Math.random`, which want to be random, don't want to run their own PRNG, and don't need to be secure. And in fact, they specifically don't want to be secure, because they want to allow hosts to make them deterministic if they wish to. --- proposals/random/example-world.md | 41 ++++++++++++++++++++++++-- proposals/random/wit/insecure-seed.wit | 24 +++++++++++++++ proposals/random/wit/insecure.wit | 21 +++++++++++++ proposals/random/wit/random.wit | 19 ------------ proposals/random/wit/world.wit | 2 ++ 5 files changed, 86 insertions(+), 21 deletions(-) create mode 100644 proposals/random/wit/insecure-seed.wit create mode 100644 proposals/random/wit/insecure.wit diff --git a/proposals/random/example-world.md b/proposals/random/example-world.md index b98bb3d37..53aa0a16f 100644 --- a/proposals/random/example-world.md +++ b/proposals/random/example-world.md @@ -3,6 +3,8 @@
    • Imports:
    @@ -37,7 +39,42 @@ deterministic data.

    • u64
    -

    insecure-random: func

    +

    Import interface insecure

    +

    The insecure interface for insecure pseudo-random numbers.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +
    +

    Functions

    +

    get-insecure-random-bytes: func

    +

    Return len insecure pseudo-random bytes.

    +

    This function is not cryptographically secure. Do not use it for +anything related to security.

    +

    There are no requirements on the values of the returned bytes, however +implementations are encouraged to return evenly distributed values with +a long period.

    +
    Params
    + +
    Return values
    +
      +
    • list<u8>
    • +
    +

    get-insecure-random-u64: func

    +

    Return an insecure pseudo-random u64 value.

    +

    This function returns the same type of pseudo-random data as +get-insecure-random-bytes, represented as a u64.

    +
    Return values
    +
      +
    • u64
    • +
    +

    Import interface insecure-seed

    +

    The insecure-seed interface for seeding hash-map DoS resistance.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +
    +

    Functions

    +

    insecure-seed: func

    Return a 128-bit value that may contain a pseudo-random value.

    The returned value is not required to be computed from a CSPRNG, and may even be entirely deterministic. Host implementations are encouraged to @@ -53,5 +90,5 @@ called multiple times and potentially used for purposes other than DoS protection.

    Return values
      -
    • (u64, u64)
    • +
    • (u64, u64)
    diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit new file mode 100644 index 000000000..93a2f17d4 --- /dev/null +++ b/proposals/random/wit/insecure-seed.wit @@ -0,0 +1,24 @@ +/// The insecure-seed interface for seeding hash-map DoS resistance. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface insecure-seed { + /// Return a 128-bit value that may contain a pseudo-random value. + /// + /// The returned value is not required to be computed from a CSPRNG, and may + /// even be entirely deterministic. Host implementations are encouraged to + /// provide pseudo-random values to any program exposed to + /// attacker-controlled content, to enable DoS protection built into many + /// languages' hash-map implementations. + /// + /// This function is intended to only be called once, by a source language + /// to initialize Denial Of Service (DoS) protection in its hash-map + /// implementation. + /// + /// # Expected future evolution + /// + /// This will likely be changed to a value import, to prevent it from being + /// called multiple times and potentially used for purposes other than DoS + /// protection. + insecure-seed: func() -> tuple +} diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit new file mode 100644 index 000000000..1ef020a09 --- /dev/null +++ b/proposals/random/wit/insecure.wit @@ -0,0 +1,21 @@ +/// The insecure interface for insecure pseudo-random numbers. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface insecure { + /// Return `len` insecure pseudo-random bytes. + /// + /// This function is not cryptographically secure. Do not use it for + /// anything related to security. + /// + /// There are no requirements on the values of the returned bytes, however + /// implementations are encouraged to return evenly distributed values with + /// a long period. + get-insecure-random-bytes: func(len: u64) -> list + + /// Return an insecure pseudo-random `u64` value. + /// + /// This function returns the same type of pseudo-random data as + /// `get-insecure-random-bytes`, represented as a `u64`. + get-insecure-random-u64: func() -> u64 +} diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 2080ddfde..8f7585788 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -20,23 +20,4 @@ default interface random { /// This function returns the same type of pseudo-random data as /// `get-random-bytes`, represented as a `u64`. get-random-u64: func() -> u64 - - /// Return a 128-bit value that may contain a pseudo-random value. - /// - /// The returned value is not required to be computed from a CSPRNG, and may - /// even be entirely deterministic. Host implementations are encouraged to - /// provide pseudo-random values to any program exposed to - /// attacker-controlled content, to enable DoS protection built into many - /// languages' hash-map implementations. - /// - /// This function is intended to only be called once, by a source language - /// to initialize Denial Of Service (DoS) protection in its hash-map - /// implementation. - /// - /// # Expected future evolution - /// - /// This will likely be changed to a value import, to prevent it from being - /// called multiple times and potentially used for purposes other than DoS - /// protection. - insecure-random: func() -> tuple } diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index 8d54b3b2c..b109e0b91 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,3 +1,5 @@ default world example-world { import random: pkg.random + import insecure: pkg.insecure + import insecure-seed: pkg.insecure-seed } From b1c89d693e73895b2472bfb2244453101f94c238 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Wed, 10 May 2023 15:43:42 -0500 Subject: [PATCH 1134/1772] Switch from wasi-logging to wasi-cli for console output --- proposals/http/wit/deps.lock | 24 +- proposals/http/wit/deps.toml | 5 +- proposals/http/wit/deps/cli/command.wit | 23 + .../wit/deps/cli/environment-preopens.wit | 7 + proposals/http/wit/deps/cli/environment.wit | 14 + proposals/http/wit/deps/cli/exit.wit | 4 + proposals/http/wit/deps/cli/run.wit | 4 + proposals/http/wit/deps/cli/stdio.wit | 17 + proposals/http/wit/deps/cli/terminal.wit | 59 ++ proposals/http/wit/deps/filesystem/types.wit | 797 ++++++++++++++++++ proposals/http/wit/deps/logging/logging.wit | 32 - proposals/http/wit/deps/logging/world.wit | 3 - .../http/wit/deps/random/insecure-seed.wit | 24 + proposals/http/wit/deps/random/insecure.wit | 21 + proposals/http/wit/deps/random/random.wit | 19 - proposals/http/wit/deps/random/world.wit | 2 + .../wit/deps/sockets/instance-network.wit | 9 + .../http/wit/deps/sockets/ip-name-lookup.wit | 69 ++ proposals/http/wit/deps/sockets/network.wit | 186 ++++ .../wit/deps/sockets/tcp-create-socket.wit | 27 + proposals/http/wit/deps/sockets/tcp.wit | 255 ++++++ .../wit/deps/sockets/udp-create-socket.wit | 27 + proposals/http/wit/deps/sockets/udp.wit | 211 +++++ proposals/http/wit/deps/sockets/world.wit | 10 + proposals/http/wit/proxy.wit | 7 +- 25 files changed, 1791 insertions(+), 65 deletions(-) create mode 100644 proposals/http/wit/deps/cli/command.wit create mode 100644 proposals/http/wit/deps/cli/environment-preopens.wit create mode 100644 proposals/http/wit/deps/cli/environment.wit create mode 100644 proposals/http/wit/deps/cli/exit.wit create mode 100644 proposals/http/wit/deps/cli/run.wit create mode 100644 proposals/http/wit/deps/cli/stdio.wit create mode 100644 proposals/http/wit/deps/cli/terminal.wit create mode 100644 proposals/http/wit/deps/filesystem/types.wit delete mode 100644 proposals/http/wit/deps/logging/logging.wit delete mode 100644 proposals/http/wit/deps/logging/world.wit create mode 100644 proposals/http/wit/deps/random/insecure-seed.wit create mode 100644 proposals/http/wit/deps/random/insecure.wit create mode 100644 proposals/http/wit/deps/sockets/instance-network.wit create mode 100644 proposals/http/wit/deps/sockets/ip-name-lookup.wit create mode 100644 proposals/http/wit/deps/sockets/network.wit create mode 100644 proposals/http/wit/deps/sockets/tcp-create-socket.wit create mode 100644 proposals/http/wit/deps/sockets/tcp.wit create mode 100644 proposals/http/wit/deps/sockets/udp-create-socket.wit create mode 100644 proposals/http/wit/deps/sockets/udp.wit create mode 100644 proposals/http/wit/deps/sockets/world.wit diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 25ec5b7ef..6e178b0fe 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,18 +1,23 @@ +[cli] +url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" +sha256 = "4ee7653b8d712808a129b8dedb24f8af09fe13c177c08fb017ba1726c0756147" +sha512 = "a7b43ab7dd1765ff6fc676ebd1fb28d1f24f20870deb1743485409ede90cdb7843358d6bfd3fcc0684d92d7bacc7dbf8c56f48156bae1c429e23e9c0a1567652" +deps = ["filesystem"] + [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" sha256 = "3fb1c6a5541b6288fe9b22210b610b89ebd97a4318bdc174fe256f5635b1c0ad" sha512 = "e89cbfd4988f4299d1a9c7da484362df22e29550ee2d559cf82e20e0925e581f0df420818c6bae984df54e336b8eb747fc5171ddeccfe91ca25f48566a258ff6" +[filesystem] +sha256 = "4c92964370d25209f1efb8273360070fce0901834c992bdfb32310587a00dfd7" +sha512 = "0152b5f5b1ab667fa422735b6296bbd5be699b5c526159ae43b7465b8ac69cf0cda8b6ca8773c352718de6d9a1b485a08be6f995b3ce3a8bf729fce5dcb4daac" + [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" sha256 = "7450142aeb3f1688ee2b12853344e262caf6aee0718dc0296316f7f6b3afd91f" sha512 = "5cc0f60d190e16d6dd52a4ca2fc862f007465e7642e98061b41c90778e1f2b00aeb2543b6fadbb6a137dd548d86e9e55edcfb30388adcc6a160b4cdc29d378ec" -[logging] -url = "https://github.com/WebAssembly/wasi-logging/archive/main.tar.gz" -sha256 = "f378a2b6a36af096528ec5e7031da474990cecaec1949c663befc5066d719f6f" -sha512 = "ba09307b12f5428c3058d878001c9fb15df21933c6203328f785d5009a4fc0cf304950271590d4146305a2d8b8988595f396d955961168cb6bfa7ea9af1cc362" - [poll] url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" sha256 = "065422b0ea6ccb2a9facc6b87b902eef110c53d76fc31f341a6bc8d0b0285b6a" @@ -20,5 +25,10 @@ sha512 = "19a55cd3072a19ae6a1774723a4962e7a155a5ce89a27175e8c76020efb4d00bc92ebb [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "79b6417bb1ab3c82c241c56021e717f258e2a0b3ab94db93907ca11d7f92ed66" -sha512 = "1e657ac56420e65bde75eabea920a605a0ff4adc6f2ba8b7cf1c37a603710449bc1a29568dda2b61c04ae9889d2b1a82b9935d4b9d573eb48a83e0ecf9cad591" +sha256 = "29ae189cd5b3fc4d16b955bd7c7bb158a75e8329363ea5ae141a32bee743ab19" +sha512 = "884d7c7dd167a93217166309d9e3e8befce9cff359cf8ff989b046dbaf15bb765b43c7746ceabdf64ea595873a588e4a6d1a3533f94732ab613e7ed3ee11a119" + +[sockets] +url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" +sha256 = "2a6158a0d7d6ac4d912f272c108d19b741a44566639191defaf8838e232417db" +sha512 = "d2ae6f7b9e1a33c1f3ca840f5a8f1c0f757c139569cee62027def2bbe43350795461e2fd6bae09ada1c6c94237eb03da65330169762121b036dad8cd430ba462" diff --git a/proposals/http/wit/deps.toml b/proposals/http/wit/deps.toml index fa6040d13..582faf4cf 100644 --- a/proposals/http/wit/deps.toml +++ b/proposals/http/wit/deps.toml @@ -1,5 +1,8 @@ io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -logging = "https://github.com/WebAssembly/wasi-logging/archive/main.tar.gz" +cli = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" + +# not used by http/proxy, but included to allow full contents of wasi-cli to validate +sockets = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit new file mode 100644 index 000000000..e92bb6023 --- /dev/null +++ b/proposals/http/wit/deps/cli/command.wit @@ -0,0 +1,23 @@ +default world command { + import wall-clock: clocks.wall-clock + import monotonic-clock: clocks.monotonic-clock + import timezone: clocks.timezone + import filesystem: filesystem.types + import instance-network: sockets.instance-network + import ip-name-lookup: sockets.ip-name-lookup + import network: sockets.network + import tcp-create-socket: sockets.tcp-create-socket + import tcp: sockets.tcp + import udp-create-socket: sockets.udp-create-socket + import udp: sockets.udp + import random: random.random + import poll: poll.poll + import streams: io.streams + import environment: pkg.environment + import environment-preopens: pkg.environment-preopens + import exit: pkg.exit + import stdin: pkg.stdio.stdin + import stdout: pkg.stdio.stdout + import stderr: pkg.stdio.stderr + export run: pkg.run +} diff --git a/proposals/http/wit/deps/cli/environment-preopens.wit b/proposals/http/wit/deps/cli/environment-preopens.wit new file mode 100644 index 000000000..e7ab89d75 --- /dev/null +++ b/proposals/http/wit/deps/cli/environment-preopens.wit @@ -0,0 +1,7 @@ +default interface environment-preopens { + use filesystem.types.{descriptor} + use io.streams.{input-stream, output-stream} + + /// Return the set of of preopened directories, and their path. + get-directories: func() -> list> +} diff --git a/proposals/http/wit/deps/cli/environment.wit b/proposals/http/wit/deps/cli/environment.wit new file mode 100644 index 000000000..876ea3a0c --- /dev/null +++ b/proposals/http/wit/deps/cli/environment.wit @@ -0,0 +1,14 @@ +default interface environment { + /// Get the POSIX-style environment variables. + /// + /// Each environment variable is provided as a pair of string variable names + /// and string value. + /// + /// Morally, these are a value import, but until value imports are available + /// in the component model, this import function should return the same + /// values each time it is called. + get-environment: func() -> list> + + /// Get the POSIX-style arguments to the program. + get-arguments: func() -> list +} diff --git a/proposals/http/wit/deps/cli/exit.wit b/proposals/http/wit/deps/cli/exit.wit new file mode 100644 index 000000000..2759e9dd9 --- /dev/null +++ b/proposals/http/wit/deps/cli/exit.wit @@ -0,0 +1,4 @@ +default interface wasi-exit { + /// Exit the curerent instance and any linked instances. + exit: func(status: result) +} diff --git a/proposals/http/wit/deps/cli/run.wit b/proposals/http/wit/deps/cli/run.wit new file mode 100644 index 000000000..2132e98e7 --- /dev/null +++ b/proposals/http/wit/deps/cli/run.wit @@ -0,0 +1,4 @@ +default interface run { + /// Run the program. + run: func() -> result +} diff --git a/proposals/http/wit/deps/cli/stdio.wit b/proposals/http/wit/deps/cli/stdio.wit new file mode 100644 index 000000000..1f87e5485 --- /dev/null +++ b/proposals/http/wit/deps/cli/stdio.wit @@ -0,0 +1,17 @@ +interface stdin { + use io.streams.{input-stream} + + get-stdin: func() -> input-stream +} + +interface stdout { + use io.streams.{output-stream} + + get-stdout: func() -> output-stream +} + +interface stderr { + use io.streams.{output-stream} + + get-stderr: func() -> output-stream +} diff --git a/proposals/http/wit/deps/cli/terminal.wit b/proposals/http/wit/deps/cli/terminal.wit new file mode 100644 index 000000000..988068af7 --- /dev/null +++ b/proposals/http/wit/deps/cli/terminal.wit @@ -0,0 +1,59 @@ +interface terminal-input { + /// The input side of a terminal. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type terminal-input = u32 + + // In the future, this may include functions for disabling echoing, + // disabling input buffering so that keyboard events are sent through + // immediately, querying supported features, and so on. + + /// Dispose of the specified terminal-input after which it may no longer + /// be used. + drop-terminal-input: func(this: terminal-input) +} + +interface terminal-output { + /// The output side of a terminal. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type terminal-output = u32 + + // In the future, this may include functions for querying the terminal + // size, being notified of terminal size changes, querying supported + // features, and so on. + + /// Dispose of the specified terminal-output, after which it may no longer + /// be used. + drop-terminal-output: func(this: terminal-output) +} + +/// An interface providing an optional `terminal-input` for stdin as a +/// link-time authority. +interface terminal-stdin { + use self.terminal-input.{terminal-input} + + /// If stdin is connected to a terminal, return a `terminal-input` handle + /// allowing further interaction with it. + get-terminal-stdin: func() -> option +} + +/// An interface providing an optional `terminal-output` for stdout as a +/// link-time authority. +interface terminal-stdout { + use self.terminal-output.{terminal-output} + + /// If stdout is connected to a terminal, return a `terminal-output` handle + /// allowing further interaction with it. + get-terminal-stdout: func() -> option +} + +/// An interface providing an optional `terminal-output` for stderr as a +/// link-time authority. +interface terminal-stderr { + use self.terminal-output.{terminal-output} + + /// If stderr is connected to a terminal, return a `terminal-output` handle + /// allowing further interaction with it. + get-terminal-stderr: func() -> option +} diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit new file mode 100644 index 000000000..c04f989bb --- /dev/null +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -0,0 +1,797 @@ +/// WASI filesystem is a filesystem API primarily intended to let users run WASI +/// programs that access their files on their existing filesystems, without +/// significant overhead. +/// +/// It is intended to be roughly portable between Unix-family platforms and +/// Windows, though it does not hide many of the major differences. +/// +/// Paths are passed as interface-type `string`s, meaning they must consist of +/// a sequence of Unicode Scalar Values (USVs). Some filesystems may contain +/// paths which are not accessible by this API. +/// +/// The directory separator in WASI is always the forward-slash (`/`). +/// +/// All paths in WASI are relative paths, and are interpreted relative to a +/// `descriptor` referring to a base directory. If a `path` argument to any WASI +/// function starts with `/`, or if any step of resolving a `path`, including +/// `..` and symbolic link steps, reaches a directory outside of the base +/// directory, or reaches a symlink to an absolute or rooted path in the +/// underlying filesystem, the function fails with `error-code::not-permitted`. +default interface types { + use io.streams.{input-stream, output-stream} + use clocks.wall-clock.{datetime} + + /// File size or length of a region within a file. + type filesize = u64 + + /// The type of a filesystem object referenced by a descriptor. + /// + /// Note: This was called `filetype` in earlier versions of WASI. + enum descriptor-type { + /// The type of the descriptor or file is unknown or is different from + /// any of the other types specified. + unknown, + /// The descriptor refers to a block device inode. + block-device, + /// The descriptor refers to a character device inode. + character-device, + /// The descriptor refers to a directory inode. + directory, + /// The descriptor refers to a named pipe. + fifo, + /// The file refers to a symbolic link inode. + symbolic-link, + /// The descriptor refers to a regular file inode. + regular-file, + /// The descriptor refers to a socket. + socket, + } + + /// Descriptor flags. + /// + /// Note: This was called `fdflags` in earlier versions of WASI. + flags descriptor-flags { + /// Read mode: Data can be read. + read, + /// Write mode: Data can be written to. + write, + /// Requests non-blocking operation. + /// + /// When this flag is enabled, functions may return immediately with an + /// `error-code::would-block` error code in situations where they would + /// otherwise block. However, this non-blocking behavior is not + /// required. Implementations are permitted to ignore this flag and + /// block. This is similar to `O_NONBLOCK` in POSIX. + non-blocking, + /// Request that writes be performed according to synchronized I/O file + /// integrity completion. The data stored in the file and the file's + /// metadata are synchronized. This is similar to `O_SYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + file-integrity-sync, + /// Request that writes be performed according to synchronized I/O data + /// integrity completion. Only the data stored in the file is + /// synchronized. This is similar to `O_DSYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + data-integrity-sync, + /// Requests that reads be performed at the same level of integrety + /// requested for writes. This is similar to `O_RSYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + requested-write-sync, + /// Mutating directories mode: Directory contents may be mutated. + /// + /// When this flag is unset on a descriptor, operations using the + /// descriptor which would create, rename, delete, modify the data or + /// metadata of filesystem objects, or obtain another handle which + /// would permit any of those, shall fail with `error-code::read-only` if + /// they would otherwise succeed. + /// + /// This may only be set on directories. + mutate-directory, + } + + /// File attributes. + /// + /// Note: This was called `filestat` in earlier versions of WASI. + record descriptor-stat { + /// Device ID of device containing the file. + device: device, + /// File serial number. + inode: inode, + /// File type. + %type: descriptor-type, + /// Number of hard links to the file. + link-count: link-count, + /// For regular files, the file size in bytes. For symbolic links, the + /// length in bytes of the pathname contained in the symbolic link. + size: filesize, + /// Last data access timestamp. + data-access-timestamp: datetime, + /// Last data modification timestamp. + data-modification-timestamp: datetime, + /// Last file status change timestamp. + status-change-timestamp: datetime, + } + + /// Flags determining the method of how paths are resolved. + flags path-flags { + /// As long as the resolved path corresponds to a symbolic link, it is + /// expanded. + symlink-follow, + } + + /// Open flags used by `open-at`. + flags open-flags { + /// Create file if it does not exist, similar to `O_CREAT` in POSIX. + create, + /// Fail if not a directory, similar to `O_DIRECTORY` in POSIX. + directory, + /// Fail if file already exists, similar to `O_EXCL` in POSIX. + exclusive, + /// Truncate file to size 0, similar to `O_TRUNC` in POSIX. + truncate, + } + + /// Permissions mode used by `open-at`, `change-file-permissions-at`, and + /// similar. + flags modes { + /// True if the resource is considered readable by the containing + /// filesystem. + readable, + /// True if the resource is considered writeable by the containing + /// filesystem. + writeable, + /// True if the resource is considered executable by the containing + /// filesystem. This does not apply to directories. + executable, + } + + /// Access type used by `access-at`. + variant access-type { + /// Test for readability, writeability, or executability. + access(modes), + + /// Test whether the path exists. + exists, + } + + /// Number of hard links to an inode. + type link-count = u64 + + /// Identifier for a device containing a file system. Can be used in + /// combination with `inode` to uniquely identify a file or directory in + /// the filesystem. + type device = u64 + + /// Filesystem object serial number that is unique within its file system. + type inode = u64 + + /// When setting a timestamp, this gives the value to set it to. + variant new-timestamp { + /// Leave the timestamp set to its previous value. + no-change, + /// Set the timestamp to the current time of the system clock associated + /// with the filesystem. + now, + /// Set the timestamp to the given value. + timestamp(datetime), + } + + /// A directory entry. + record directory-entry { + /// The serial number of the object referred to by this directory entry. + /// May be none if the inode value is not known. + /// + /// When this is none, libc implementations might do an extra `stat-at` + /// call to retrieve the inode number to fill their `d_ino` fields, so + /// implementations which can set this to a non-none value should do so. + inode: option, + + /// The type of the file referred to by this directory entry. + %type: descriptor-type, + + /// The name of the object. + name: string, + } + + /// Error codes returned by functions, similar to `errno` in POSIX. + /// Not all of these error codes are returned by the functions provided by this + /// API; some are used in higher-level library layers, and others are provided + /// merely for alignment with POSIX. + enum error-code { + /// Permission denied, similar to `EACCES` in POSIX. + access, + /// Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. + would-block, + /// Connection already in progress, similar to `EALREADY` in POSIX. + already, + /// Bad descriptor, similar to `EBADF` in POSIX. + bad-descriptor, + /// Device or resource busy, similar to `EBUSY` in POSIX. + busy, + /// Resource deadlock would occur, similar to `EDEADLK` in POSIX. + deadlock, + /// Storage quota exceeded, similar to `EDQUOT` in POSIX. + quota, + /// File exists, similar to `EEXIST` in POSIX. + exist, + /// File too large, similar to `EFBIG` in POSIX. + file-too-large, + /// Illegal byte sequence, similar to `EILSEQ` in POSIX. + illegal-byte-sequence, + /// Operation in progress, similar to `EINPROGRESS` in POSIX. + in-progress, + /// Interrupted function, similar to `EINTR` in POSIX. + interrupted, + /// Invalid argument, similar to `EINVAL` in POSIX. + invalid, + /// I/O error, similar to `EIO` in POSIX. + io, + /// Is a directory, similar to `EISDIR` in POSIX. + is-directory, + /// Too many levels of symbolic links, similar to `ELOOP` in POSIX. + loop, + /// Too many links, similar to `EMLINK` in POSIX. + too-many-links, + /// Message too large, similar to `EMSGSIZE` in POSIX. + message-size, + /// Filename too long, similar to `ENAMETOOLONG` in POSIX. + name-too-long, + /// No such device, similar to `ENODEV` in POSIX. + no-device, + /// No such file or directory, similar to `ENOENT` in POSIX. + no-entry, + /// No locks available, similar to `ENOLCK` in POSIX. + no-lock, + /// Not enough space, similar to `ENOMEM` in POSIX. + insufficient-memory, + /// No space left on device, similar to `ENOSPC` in POSIX. + insufficient-space, + /// Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. + not-directory, + /// Directory not empty, similar to `ENOTEMPTY` in POSIX. + not-empty, + /// State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. + not-recoverable, + /// Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. + unsupported, + /// Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. + no-tty, + /// No such device or address, similar to `ENXIO` in POSIX. + no-such-device, + /// Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. + overflow, + /// Operation not permitted, similar to `EPERM` in POSIX. + not-permitted, + /// Broken pipe, similar to `EPIPE` in POSIX. + pipe, + /// Read-only file system, similar to `EROFS` in POSIX. + read-only, + /// Invalid seek, similar to `ESPIPE` in POSIX. + invalid-seek, + /// Text file busy, similar to `ETXTBSY` in POSIX. + text-file-busy, + /// Cross-device link, similar to `EXDEV` in POSIX. + cross-device, + } + + /// File or memory access pattern advisory information. + enum advice { + /// The application has no advice to give on its behavior with respect + /// to the specified data. + normal, + /// The application expects to access the specified data sequentially + /// from lower offsets to higher offsets. + sequential, + /// The application expects to access the specified data in a random + /// order. + random, + /// The application expects to access the specified data in the near + /// future. + will-need, + /// The application expects that it will not access the specified data + /// in the near future. + dont-need, + /// The application expects to access the specified data once and then + /// not reuse it thereafter. + no-reuse, + } + + /// A descriptor is a reference to a filesystem object, which may be a file, + /// directory, named pipe, special file, or other object on which filesystem + /// calls may be made. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type descriptor = u32 + + /// Return a stream for reading from a file. + /// + /// Multiple read, write, and append streams may be active on the same open + /// file and they do not interfere with each other. + /// + /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. + read-via-stream: func( + this: descriptor, + /// The offset within the file at which to start reading. + offset: filesize, + ) -> input-stream + + /// Return a stream for writing to a file. + /// + /// Note: This allows using `write-stream`, which is similar to `write` in + /// POSIX. + write-via-stream: func( + this: descriptor, + /// The offset within the file at which to start writing. + offset: filesize, + ) -> output-stream + + /// Return a stream for appending to a file. + /// + /// Note: This allows using `write-stream`, which is similar to `write` with + /// `O_APPEND` in in POSIX. + append-via-stream: func( + this: descriptor, + ) -> output-stream + + /// Provide file advisory information on a descriptor. + /// + /// This is similar to `posix_fadvise` in POSIX. + advise: func( + this: descriptor, + /// The offset within the file to which the advisory applies. + offset: filesize, + /// The length of the region to which the advisory applies. + length: filesize, + /// The advice. + advice: advice + ) -> result<_, error-code> + + /// Synchronize the data of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fdatasync` in POSIX. + sync-data: func(this: descriptor) -> result<_, error-code> + + /// Get flags associated with a descriptor. + /// + /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. + /// + /// Note: This returns the value that was the `fs_flags` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-flags: func(this: descriptor) -> result + + /// Get the dynamic type of a descriptor. + /// + /// Note: This returns the same value as the `type` field of the `fd-stat` + /// returned by `stat`, `stat-at` and similar. + /// + /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided + /// by `fstat` in POSIX. + /// + /// Note: This returns the value that was the `fs_filetype` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-type: func(this: descriptor) -> result + + /// Set status flags associated with a descriptor. + /// + /// This function may only change the `non-blocking` flag. + /// + /// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + /// + /// Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. + set-flags: func(this: descriptor, %flags: descriptor-flags) -> result<_, error-code> + + /// Adjust the size of an open file. If this increases the file's size, the + /// extra bytes are filled with zeros. + /// + /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. + set-size: func(this: descriptor, size: filesize) -> result<_, error-code> + + /// Adjust the timestamps of an open file or directory. + /// + /// Note: This is similar to `futimens` in POSIX. + /// + /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. + set-times: func( + this: descriptor, + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code> + + /// Read from a descriptor, without using and updating the descriptor's offset. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a bool which, when true, indicates that the end of the + /// file was reached. The returned list will contain up to `length` bytes; it + /// may return fewer than requested, if the end of the file is reached or + /// if the I/O operation is interrupted. + /// + /// In the future, this may change to return a `stream`. + /// + /// Note: This is similar to `pread` in POSIX. + read: func( + this: descriptor, + /// The maximum number of bytes to read. + length: filesize, + /// The offset within the file at which to read. + offset: filesize, + ) -> result, bool>, error-code> + + /// Write to a descriptor, without using and updating the descriptor's offset. + /// + /// It is valid to write past the end of a file; the file is extended to the + /// extent of the write, with bytes between the previous end and the start of + /// the write set to zero. + /// + /// In the future, this may change to take a `stream`. + /// + /// Note: This is similar to `pwrite` in POSIX. + write: func( + this: descriptor, + /// Data to write + buffer: list, + /// The offset within the file at which to write. + offset: filesize, + ) -> result + + /// Read directory entries from a directory. + /// + /// On filesystems where directories contain entries referring to themselves + /// and their parents, often named `.` and `..` respectively, these entries + /// are omitted. + /// + /// This always returns a new stream which starts at the beginning of the + /// directory. Multiple streams may be active on the same directory, and they + /// do not interfere with each other. + read-directory: func( + this: descriptor + ) -> result + + /// Synchronize the data and metadata of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fsync` in POSIX. + sync: func(this: descriptor) -> result<_, error-code> + + /// Create a directory. + /// + /// Note: This is similar to `mkdirat` in POSIX. + create-directory-at: func( + this: descriptor, + /// The relative path at which to create the directory. + path: string, + ) -> result<_, error-code> + + /// Return the attributes of an open file or directory. + /// + /// Note: This is similar to `fstat` in POSIX. + /// + /// Note: This was called `fd_filestat_get` in earlier versions of WASI. + stat: func(this: descriptor) -> result + + /// Return the attributes of a file or directory. + /// + /// Note: This is similar to `fstatat` in POSIX. + /// + /// Note: This was called `path_filestat_get` in earlier versions of WASI. + stat-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result + + /// Adjust the timestamps of a file or directory. + /// + /// Note: This is similar to `utimensat` in POSIX. + /// + /// Note: This was called `path_filestat_set_times` in earlier versions of + /// WASI. + set-times-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to operate on. + path: string, + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code> + + /// Create a hard link. + /// + /// Note: This is similar to `linkat` in POSIX. + link-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + old-path-flags: path-flags, + /// The relative source path from which to link. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: descriptor, + /// The relative destination path at which to create the hard link. + new-path: string, + ) -> result<_, error-code> + + /// Open a file or directory. + /// + /// The returned descriptor is not guaranteed to be the lowest-numbered + /// descriptor not currently open/ it is randomized to prevent applications + /// from depending on making assumptions about indexes, since this is + /// error-prone in multi-threaded contexts. The returned descriptor is + /// guaranteed to be less than 2**31. + /// + /// If `flags` contains `descriptor-flags::mutate-directory`, and the base + /// descriptor doesn't have `descriptor-flags::mutate-directory` set, + /// `open-at` fails with `error-code::read-only`. + /// + /// If `flags` contains `write` or `mutate-directory`, or `open-flags` + /// contains `truncate` or `create`, and the base descriptor doesn't have + /// `descriptor-flags::mutate-directory` set, `open-at` fails with + /// `error-code::read-only`. + /// + /// Note: This is similar to `openat` in POSIX. + open-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the object to open. + path: string, + /// The method by which to open the file. + open-flags: open-flags, + /// Flags to use for the resulting descriptor. + %flags: descriptor-flags, + /// Permissions to use when creating a new file. + modes: modes + ) -> result + + /// Read the contents of a symbolic link. + /// + /// If the contents contain an absolute or rooted path in the underlying + /// filesystem, this function fails with `error-code::not-permitted`. + /// + /// Note: This is similar to `readlinkat` in POSIX. + readlink-at: func( + this: descriptor, + /// The relative path of the symbolic link from which to read. + path: string, + ) -> result + + /// Remove a directory. + /// + /// Return `error-code::not-empty` if the directory is not empty. + /// + /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + remove-directory-at: func( + this: descriptor, + /// The relative path to a directory to remove. + path: string, + ) -> result<_, error-code> + + /// Rename a filesystem object. + /// + /// Note: This is similar to `renameat` in POSIX. + rename-at: func( + this: descriptor, + /// The relative source path of the file or directory to rename. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: descriptor, + /// The relative destination path to which to rename the file or directory. + new-path: string, + ) -> result<_, error-code> + + /// Create a symbolic link (also known as a "symlink"). + /// + /// If `old-path` starts with `/`, the function fails with + /// `error-code::not-permitted`. + /// + /// Note: This is similar to `symlinkat` in POSIX. + symlink-at: func( + this: descriptor, + /// The contents of the symbolic link. + old-path: string, + /// The relative destination path at which to create the symbolic link. + new-path: string, + ) -> result<_, error-code> + + /// Check accessibility of a filesystem path. + /// + /// Check whether the given filesystem path names an object which is + /// readable, writeable, or executable, or whether it exists. + /// + /// This does not a guarantee that subsequent accesses will succeed, as + /// filesystem permissions may be modified asynchronously by external + /// entities. + /// + /// Note: This is similar to `faccessat` with the `AT_EACCESS` flag in POSIX. + access-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to check. + path: string, + /// The type of check to perform. + %ype: access-type + ) -> result<_, error-code> + + /// Unlink a filesystem object that is not a directory. + /// + /// Return `error-code::is-directory` if the path refers to a directory. + /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + unlink-file-at: func( + this: descriptor, + /// The relative path to a file to unlink. + path: string, + ) -> result<_, error-code> + + /// Change the permissions of a filesystem object that is not a directory. + /// + /// Note that the ultimate meanings of these permissions is + /// filesystem-specific. + /// + /// Note: This is similar to `fchmodat` in POSIX. + change-file-permissions-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to operate on. + path: string, + /// The new permissions for the filesystem object. + modes: modes, + ) -> result<_, error-code> + + /// Change the permissions of a directory. + /// + /// Note that the ultimate meanings of these permissions is + /// filesystem-specific. + /// + /// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" + /// flag. `read` on a directory implies readability and searchability, and + /// `execute` is not valid for directories. + /// + /// Note: This is similar to `fchmodat` in POSIX. + change-directory-permissions-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to operate on. + path: string, + /// The new permissions for the directory. + modes: modes, + ) -> result<_, error-code> + + /// Request a shared advisory lock for an open file. + /// + /// This requests a *shared* lock; more than one shared lock can be held for + /// a file at the same time. + /// + /// If the open file has an exclusive lock, this function downgrades the lock + /// to a shared lock. If it has a shared lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified how shared locks interact with locks acquired by + /// non-WASI programs. + /// + /// This function blocks until the lock can be acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. + lock-shared: func(this: descriptor) -> result<_, error-code> + + /// Request an exclusive advisory lock for an open file. + /// + /// This requests an *exclusive* lock; no other locks may be held for the + /// file while an exclusive lock is held. + /// + /// If the open file has a shared lock and there are no exclusive locks held + /// for the file, this function upgrades the lock to an exclusive lock. If the + /// open file already has an exclusive lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified whether this function succeeds if the file descriptor + /// is not opened for writing. It is unspecified how exclusive locks interact + /// with locks acquired by non-WASI programs. + /// + /// This function blocks until the lock can be acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. + lock-exclusive: func(this: descriptor) -> result<_, error-code> + + /// Request a shared advisory lock for an open file. + /// + /// This requests a *shared* lock; more than one shared lock can be held for + /// a file at the same time. + /// + /// If the open file has an exclusive lock, this function downgrades the lock + /// to a shared lock. If it has a shared lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified how shared locks interact with locks acquired by + /// non-WASI programs. + /// + /// This function returns `error-code::would-block` if the lock cannot be + /// acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. + try-lock-shared: func(this: descriptor) -> result<_, error-code> + + /// Request an exclusive advisory lock for an open file. + /// + /// This requests an *exclusive* lock; no other locks may be held for the + /// file while an exclusive lock is held. + /// + /// If the open file has a shared lock and there are no exclusive locks held + /// for the file, this function upgrades the lock to an exclusive lock. If the + /// open file already has an exclusive lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified whether this function succeeds if the file descriptor + /// is not opened for writing. It is unspecified how exclusive locks interact + /// with locks acquired by non-WASI programs. + /// + /// This function returns `error-code::would-block` if the lock cannot be + /// acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. + try-lock-exclusive: func(this: descriptor) -> result<_, error-code> + + /// Release a shared or exclusive lock on an open file. + /// + /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. + unlock: func(this: descriptor) -> result<_, error-code> + + /// Dispose of the specified `descriptor`, after which it may no longer + /// be used. + drop-descriptor: func(this: descriptor) + + /// A stream of directory entries. + /// + /// This [represents a stream of `dir-entry`](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Streams). + type directory-entry-stream = u32 + + /// Read a single directory entry from a `directory-entry-stream`. + read-directory-entry: func( + this: directory-entry-stream + ) -> result, error-code> + + /// Dispose of the specified `directory-entry-stream`, after which it may no longer + /// be used. + drop-directory-entry-stream: func(this: directory-entry-stream) +} diff --git a/proposals/http/wit/deps/logging/logging.wit b/proposals/http/wit/deps/logging/logging.wit deleted file mode 100644 index 731716555..000000000 --- a/proposals/http/wit/deps/logging/logging.wit +++ /dev/null @@ -1,32 +0,0 @@ -/// WASI Logging is a logging API intended to let users emit log messages with -/// simple priority levels and context values. -default interface logging { - /// A log level, describing a kind of message. - enum level { - /// Describes messages about the values of variables and the flow of - /// control within a program. - trace, - - /// Describes messages likely to be of interest to someone debugging a - /// program. - debug, - - /// Describes messages likely to be of interest to someone monitoring a - /// program. - info, - - /// Describes messages indicating hazardous situations. - warn, - - /// Describes messages indicating serious errors. - error, - } - - /// Emit a log message. - /// - /// A log message has a `level` describing what kind of message is being - /// sent, a context, which is an uninterpreted string meant to help - /// consumers group similar messages, and a string containing the message - /// text. - log: func(level: level, context: string, message: string) -} diff --git a/proposals/http/wit/deps/logging/world.wit b/proposals/http/wit/deps/logging/world.wit deleted file mode 100644 index b5af1514f..000000000 --- a/proposals/http/wit/deps/logging/world.wit +++ /dev/null @@ -1,3 +0,0 @@ -default world example-world { - import logging: pkg.logging -} diff --git a/proposals/http/wit/deps/random/insecure-seed.wit b/proposals/http/wit/deps/random/insecure-seed.wit new file mode 100644 index 000000000..93a2f17d4 --- /dev/null +++ b/proposals/http/wit/deps/random/insecure-seed.wit @@ -0,0 +1,24 @@ +/// The insecure-seed interface for seeding hash-map DoS resistance. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface insecure-seed { + /// Return a 128-bit value that may contain a pseudo-random value. + /// + /// The returned value is not required to be computed from a CSPRNG, and may + /// even be entirely deterministic. Host implementations are encouraged to + /// provide pseudo-random values to any program exposed to + /// attacker-controlled content, to enable DoS protection built into many + /// languages' hash-map implementations. + /// + /// This function is intended to only be called once, by a source language + /// to initialize Denial Of Service (DoS) protection in its hash-map + /// implementation. + /// + /// # Expected future evolution + /// + /// This will likely be changed to a value import, to prevent it from being + /// called multiple times and potentially used for purposes other than DoS + /// protection. + insecure-seed: func() -> tuple +} diff --git a/proposals/http/wit/deps/random/insecure.wit b/proposals/http/wit/deps/random/insecure.wit new file mode 100644 index 000000000..1ef020a09 --- /dev/null +++ b/proposals/http/wit/deps/random/insecure.wit @@ -0,0 +1,21 @@ +/// The insecure interface for insecure pseudo-random numbers. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface insecure { + /// Return `len` insecure pseudo-random bytes. + /// + /// This function is not cryptographically secure. Do not use it for + /// anything related to security. + /// + /// There are no requirements on the values of the returned bytes, however + /// implementations are encouraged to return evenly distributed values with + /// a long period. + get-insecure-random-bytes: func(len: u64) -> list + + /// Return an insecure pseudo-random `u64` value. + /// + /// This function returns the same type of pseudo-random data as + /// `get-insecure-random-bytes`, represented as a `u64`. + get-insecure-random-u64: func() -> u64 +} diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index 2080ddfde..8f7585788 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -20,23 +20,4 @@ default interface random { /// This function returns the same type of pseudo-random data as /// `get-random-bytes`, represented as a `u64`. get-random-u64: func() -> u64 - - /// Return a 128-bit value that may contain a pseudo-random value. - /// - /// The returned value is not required to be computed from a CSPRNG, and may - /// even be entirely deterministic. Host implementations are encouraged to - /// provide pseudo-random values to any program exposed to - /// attacker-controlled content, to enable DoS protection built into many - /// languages' hash-map implementations. - /// - /// This function is intended to only be called once, by a source language - /// to initialize Denial Of Service (DoS) protection in its hash-map - /// implementation. - /// - /// # Expected future evolution - /// - /// This will likely be changed to a value import, to prevent it from being - /// called multiple times and potentially used for purposes other than DoS - /// protection. - insecure-random: func() -> tuple } diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit index 8d54b3b2c..b109e0b91 100644 --- a/proposals/http/wit/deps/random/world.wit +++ b/proposals/http/wit/deps/random/world.wit @@ -1,3 +1,5 @@ default world example-world { import random: pkg.random + import insecure: pkg.insecure + import insecure-seed: pkg.insecure-seed } diff --git a/proposals/http/wit/deps/sockets/instance-network.wit b/proposals/http/wit/deps/sockets/instance-network.wit new file mode 100644 index 000000000..b1f5c982d --- /dev/null +++ b/proposals/http/wit/deps/sockets/instance-network.wit @@ -0,0 +1,9 @@ + +/// This interface provides a value-export of the default network handle.. +default interface instance-network { + use pkg.network.{network} + + /// Get a handle to the default network. + instance-network: func() -> network + +} diff --git a/proposals/http/wit/deps/sockets/ip-name-lookup.wit b/proposals/http/wit/deps/sockets/ip-name-lookup.wit new file mode 100644 index 000000000..c4cc72684 --- /dev/null +++ b/proposals/http/wit/deps/sockets/ip-name-lookup.wit @@ -0,0 +1,69 @@ + +default interface ip-name-lookup { + use poll.poll.{pollable} + use pkg.network.{network, error-code, ip-address, ip-address-family} + + + /// Resolve an internet host name to a list of IP addresses. + /// + /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. + /// + /// # Parameters + /// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted + /// to ASCII using IDNA encoding. + /// - `address-family`: If provided, limit the results to addresses of this specific address family. + /// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime + /// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on + /// systems without an active IPv6 interface. Notes: + /// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. + /// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. + /// + /// This function never blocks. It either immediately fails or immediately returns successfully with a `resolve-address-stream` + /// that can be used to (asynchronously) fetch the results. + /// + /// At the moment, the stream never completes successfully with 0 items. Ie. the first call + /// to `resolve-next-address` never returns `ok(none)`. This may change in the future. + /// + /// # Typical errors + /// - `invalid-name`: `name` is a syntactically invalid domain name. + /// - `invalid-name`: `name` is an IP address. + /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAI_FAMILY) + /// + /// # References: + /// - + /// - + /// - + /// - + resolve-addresses: func(network: network, name: string, address-family: option, include-unavailable: bool) -> result + + + + type resolve-address-stream = u32 + + /// Returns the next address from the resolver. + /// + /// This function should be called multiple times. On each call, it will + /// return the next address in connection order preference. If all + /// addresses have been exhausted, this function returns `none`. + /// After which, you should release the stream with `drop-resolve-address-stream`. + /// + /// This function never returns IPv4-mapped IPv6 addresses. + /// + /// # Typical errors + /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) + /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) + /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) + /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) + resolve-next-address: func(this: resolve-address-stream) -> result, error-code> + + /// Dispose of the specified `resolve-address-stream`, after which it may no longer be used. + /// + /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. + drop-resolve-address-stream: func(this: resolve-address-stream) + + /// Create a `pollable` which will resolve once the stream is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func(this: resolve-address-stream) -> pollable +} diff --git a/proposals/http/wit/deps/sockets/network.wit b/proposals/http/wit/deps/sockets/network.wit new file mode 100644 index 000000000..9176e6ba6 --- /dev/null +++ b/proposals/http/wit/deps/sockets/network.wit @@ -0,0 +1,186 @@ + +default interface network { + /// An opaque resource that represents access to (a subset of) the network. + /// This enables context-based security for networking. + /// There is no need for this to map 1:1 to a physical network interface. + /// + /// FYI, In the future this will be replaced by handle types. + type network = u32 + + /// Dispose of the specified `network`, after which it may no longer be used. + /// + /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. + drop-network: func(this: network) + + + /// Error codes. + /// + /// In theory, every API can return any error code. + /// In practice, API's typically only return the errors documented per API + /// combined with a couple of errors that are always possible: + /// - `unknown` + /// - `access-denied` + /// - `not-supported` + /// - `out-of-memory` + /// + /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. + enum error-code { + // ### GENERAL ERRORS ### + + /// Unknown error + unknown, + + /// Access denied. + /// + /// POSIX equivalent: EACCES, EPERM + access-denied, + + /// The operation is not supported. + /// + /// POSIX equivalent: EOPNOTSUPP + not-supported, + + /// Not enough memory to complete the operation. + /// + /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY + out-of-memory, + + /// The operation timed out before it could finish completely. + timeout, + + /// This operation is incompatible with another asynchronous operation that is already in progress. + concurrency-conflict, + + /// Trying to finish an asynchronous operation that: + /// - has not been started yet, or: + /// - was already finished by a previous `finish-*` call. + /// + /// Note: this is scheduled to be removed when `future`s are natively supported. + not-in-progress, + + /// The operation has been aborted because it could not be completed immediately. + /// + /// Note: this is scheduled to be removed when `future`s are natively supported. + would-block, + + + // ### IP ERRORS ### + + /// The specified address-family is not supported. + address-family-not-supported, + + /// An IPv4 address was passed to an IPv6 resource, or vice versa. + address-family-mismatch, + + /// The socket address is not a valid remote address. E.g. the IP address is set to INADDR_ANY, or the port is set to 0. + invalid-remote-address, + + /// The operation is only supported on IPv4 resources. + ipv4-only-operation, + + /// The operation is only supported on IPv6 resources. + ipv6-only-operation, + + + + // ### TCP & UDP SOCKET ERRORS ### + + /// A new socket resource could not be created because of a system limit. + new-socket-limit, + + /// The socket is already attached to another network. + already-attached, + + /// The socket is already bound. + already-bound, + + /// The socket is already in the Connection state. + already-connected, + + /// The socket is not bound to any local address. + not-bound, + + /// The socket is not in the Connection state. + not-connected, + + /// A bind operation failed because the provided address is not an address that the `network` can bind to. + address-not-bindable, + + /// A bind operation failed because the provided address is already in use. + address-in-use, + + /// A bind operation failed because there are no ephemeral ports available. + ephemeral-ports-exhausted, + + /// The remote address is not reachable + remote-unreachable, + + + // ### TCP SOCKET ERRORS ### + + /// The socket is already in the Listener state. + already-listening, + + /// The socket is already in the Listener state. + not-listening, + + /// The connection was forcefully rejected + connection-refused, + + /// The connection was reset. + connection-reset, + + + // ### UDP SOCKET ERRORS ### + datagram-too-large, + + + // ### NAME LOOKUP ERRORS ### + + /// The provided name is a syntactically invalid domain name. + invalid-name, + + /// Name does not exist or has no suitable associated IP addresses. + name-unresolvable, + + /// A temporary failure in name resolution occurred. + temporary-resolver-failure, + + /// A permanent failure in name resolution occurred. + permanent-resolver-failure, + } + + enum ip-address-family { + /// Similar to `AF_INET` in POSIX. + ipv4, + + /// Similar to `AF_INET6` in POSIX. + ipv6, + } + + type ipv4-address = tuple + type ipv6-address = tuple + + variant ip-address { + ipv4(ipv4-address), + ipv6(ipv6-address), + } + + record ipv4-socket-address { + port: u16, // sin_port + address: ipv4-address, // sin_addr + } + + record ipv6-socket-address { + port: u16, // sin6_port + flow-info: u32, // sin6_flowinfo + address: ipv6-address, // sin6_addr + scope-id: u32, // sin6_scope_id + } + + variant ip-socket-address { + ipv4(ipv4-socket-address), + ipv6(ipv6-socket-address), + } + +} \ No newline at end of file diff --git a/proposals/http/wit/deps/sockets/tcp-create-socket.wit b/proposals/http/wit/deps/sockets/tcp-create-socket.wit new file mode 100644 index 000000000..6e948fae0 --- /dev/null +++ b/proposals/http/wit/deps/sockets/tcp-create-socket.wit @@ -0,0 +1,27 @@ + +default interface tcp-create-socket { + use pkg.network.{network, error-code, ip-address-family} + use pkg.tcp.{tcp-socket} + + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` + /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # Typical errors + /// - `not-supported`: The host does not support TCP sockets. (EOPNOTSUPP) + /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References + /// - + /// - + /// - + /// - + create-tcp-socket: func(address-family: ip-address-family) -> result +} diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit new file mode 100644 index 000000000..b87153243 --- /dev/null +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -0,0 +1,255 @@ + +default interface tcp { + use io.streams.{input-stream, output-stream} + use poll.poll.{pollable} + use pkg.network.{network, error-code, ip-socket-address, ip-address-family} + + /// A TCP socket handle. + type tcp-socket = u32 + + + enum shutdown-type { + /// Similar to `SHUT_RD` in POSIX. + receive, + + /// Similar to `SHUT_WR` in POSIX. + send, + + /// Similar to `SHUT_RDWR` in POSIX. + both, + } + + + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will + /// implicitly bind the socket. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) + /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> + finish-bind: func(this: tcp-socket) -> result<_, error-code> + + /// Connect to a remote endpoint. + /// + /// On success: + /// - the socket is transitioned into the Connection state + /// - a pair of streams is returned that can be used to read & write to the connection + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `already-connected`: The socket is already in the Connection state. (EISCONN) + /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> + finish-connect: func(this: tcp-socket) -> result, error-code> + + /// Start listening for new connections. + /// + /// Transitions the socket into the Listener state. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `listen` must be identical to the one passed to `bind`. + /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) + /// - `already-listening`: The socket is already in the Listener state. + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// - `not-in-progress`: A `listen` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-listen: func(this: tcp-socket, network: network) -> result<_, error-code> + finish-listen: func(this: tcp-socket) -> result<_, error-code> + + /// Accept a new client socket. + /// + /// The returned socket is bound and in the Connection state. + /// + /// On success, this function returns the newly accepted client socket along with + /// a pair of streams that can be used to read & write to the connection. + /// + /// # Typical errors + /// - `not-listening`: Socket is not in the Listener state. (EINVAL) + /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) + /// + /// Host implementations must skip over transient errors returned by the native accept syscall. + /// + /// # References + /// - + /// - + /// - + /// - + accept: func(this: tcp-socket) -> result, error-code> + + /// Get the bound local address. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func(this: tcp-socket) -> result + + /// Get the bound remote address. + /// + /// # Typical errors + /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func(this: tcp-socket) -> result + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func(this: tcp-socket) -> ip-address-family + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// # Typical errors + /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. + /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + ipv6-only: func(this: tcp-socket) -> result + set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error-code> + + /// Hints the desired listen queue size. Implementations are free to ignore this. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error-code> + + /// Equivalent to the SO_KEEPALIVE socket option. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + keep-alive: func(this: tcp-socket) -> result + set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error-code> + + /// Equivalent to the TCP_NODELAY socket option. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + no-delay: func(this: tcp-socket) -> result + set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error-code> + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `already-listening`: (set) The socket is already in the Listener state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + unicast-hop-limit: func(this: tcp-socket) -> result + set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error-code> + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `already-listening`: (set) The socket is already in the Listener state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + receive-buffer-size: func(this: tcp-socket) -> result + set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> + send-buffer-size: func(this: tcp-socket) -> result + set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func(this: tcp-socket) -> pollable + + /// Initiate a graceful shutdown. + /// + /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read + /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. + /// Any data still in the receive queue at time of calling `shutdown` will be discarded. + /// - send: the socket is not expecting to send any more data to the peer. All subsequent write + /// operations on the `output-stream` associated with this socket will return an error. + /// - both: same effect as receive & send combined. + /// + /// The shutdown function does not close (drop) the socket. + /// + /// # Typical errors + /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error-code> + + /// Dispose of the specified `tcp-socket`, after which it may no longer be used. + /// + /// Similar to the POSIX `close` function. + /// + /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. + drop-tcp-socket: func(this: tcp-socket) +} diff --git a/proposals/http/wit/deps/sockets/udp-create-socket.wit b/proposals/http/wit/deps/sockets/udp-create-socket.wit new file mode 100644 index 000000000..2c987be08 --- /dev/null +++ b/proposals/http/wit/deps/sockets/udp-create-socket.wit @@ -0,0 +1,27 @@ + +default interface udp-create-socket { + use pkg.network.{network, error-code, ip-address-family} + use pkg.udp.{udp-socket} + + /// Create a new UDP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` is called, + /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # Typical errors + /// - `not-supported`: The host does not support UDP sockets. (EOPNOTSUPP) + /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References: + /// - + /// - + /// - + /// - + create-udp-socket: func(address-family: ip-address-family) -> result +} diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit new file mode 100644 index 000000000..271a2cb9f --- /dev/null +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -0,0 +1,211 @@ + +default interface udp { + use poll.poll.{pollable} + use pkg.network.{network, error-code, ip-socket-address, ip-address-family} + + + /// A UDP socket handle. + type udp-socket = u32 + + + record datagram { + data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. + remote-address: ip-socket-address, + + /// Possible future additions: + /// local-address: ip-socket-address, // IP_PKTINFO / IP_RECVDSTADDR / IPV6_PKTINFO + /// local-interface: u32, // IP_PKTINFO / IP_RECVIF + /// ttl: u8, // IP_RECVTTL + /// dscp: u6, // IP_RECVTOS + /// ecn: u2, // IP_RECVTOS + } + + + + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) + /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> + finish-bind: func(this: udp-socket) -> result<_, error-code> + + /// Set the destination address. + /// + /// The local-address is updated based on the best network path to `remote-address`. + /// + /// When a destination address is set: + /// - all receive operations will only return datagrams sent from the provided `remote-address`. + /// - the `send` function can only be used to send to this destination. + /// + /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> + finish-connect: func(this: udp-socket) -> result<_, error-code> + + /// Receive a message. + /// + /// Returns: + /// - The sender address of the datagram + /// - The number of bytes read. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. (EINVAL) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + receive: func(this: udp-socket) -> result + + /// Send a message to a specific destination address. + /// + /// The remote address option is required. To send a message to the "connected" peer, + /// call `remote-address` to get their address. + /// + /// # Typical errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN) + /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. + /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + send: func(this: udp-socket, datagram: datagram) -> result<_, error-code> + + /// Get the current bound address. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func(this: udp-socket) -> result + + /// Get the address set with `connect`. + /// + /// # Typical errors + /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func(this: udp-socket) -> result + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func(this: udp-socket) -> ip-address-family + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// # Typical errors + /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. + /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + ipv6-only: func(this: udp-socket) -> result + set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error-code> + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + unicast-hop-limit: func(this: udp-socket) -> result + set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error-code> + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Fails when this socket is in the Listening state. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + receive-buffer-size: func(this: udp-socket) -> result + set-receive-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> + send-buffer-size: func(this: udp-socket) -> result + set-send-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func(this: udp-socket) -> pollable + + /// Dispose of the specified `udp-socket`, after which it may no longer be used. + /// + /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. + drop-udp-socket: func(this: udp-socket) +} diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit new file mode 100644 index 000000000..854fac0ba --- /dev/null +++ b/proposals/http/wit/deps/sockets/world.wit @@ -0,0 +1,10 @@ + +default world example-world { + import instance-network: pkg.instance-network + import network: pkg.network + import udp: pkg.udp + import udp-create-socket: pkg.udp-create-socket + import tcp: pkg.tcp + import tcp-create-socket: pkg.tcp-create-socket + import ip-name-lookup: pkg.ip-name-lookup +} diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 944877a31..397463456 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -9,9 +9,10 @@ default world proxy { import timezone: clocks.timezone import random: random.random - // This is the default logging handler to use when user code simply wants to - // log to a developer-facing console (e.g., via `console.log()`). - import console: logging.logging + // Proxies have standard output and error streams which are expected to + // terminate in a developer-facing console provided by the host. + import stdout: cli.stdio.stdout + import stderr: cli.stdio.stderr // This is the default handler to use when user code simply wants to make an // HTTP request (e.g., via `fetch()`). From 3ecbecbf3a106e581d801aca31bba282a9dd34e4 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 10 May 2023 16:02:53 -0700 Subject: [PATCH 1135/1772] Update filesystem, random, and sockets dependencies. (#12) Update wasi-filesystem, wasi-random, and wasi-sockets dependencies: - random: Add the insecure-random and insecure-random-seed APIs. - sockets: Make several socket APIs non-blocking. - sockets: Improved error reporting and documentation for bb - filesystem: Fix some typos --- proposals/cli/command.md | 768 +++++++++++++----- proposals/cli/wit/command.wit | 2 + proposals/cli/wit/deps/filesystem/types.wit | 8 +- .../cli/wit/deps/random/insecure-seed.wit | 24 + proposals/cli/wit/deps/random/insecure.wit | 21 + proposals/cli/wit/deps/random/random.wit | 19 - .../cli/wit/deps/sockets/ip-name-lookup.wit | 46 +- proposals/cli/wit/deps/sockets/network.wit | 136 +++- .../wit/deps/sockets/tcp-create-socket.wit | 16 +- proposals/cli/wit/deps/sockets/tcp.wit | 191 +++-- .../wit/deps/sockets/udp-create-socket.wit | 16 +- proposals/cli/wit/deps/sockets/udp.wit | 145 ++-- 12 files changed, 1007 insertions(+), 385 deletions(-) create mode 100644 proposals/cli/wit/deps/random/insecure-seed.wit create mode 100644 proposals/cli/wit/deps/random/insecure.wit diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 33de32268..4e44ae4e4 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -16,6 +16,8 @@
  • interface udp
  • interface udp-create-socket
  • interface random
  • +
  • interface insecure-random
  • +
  • interface insecure-random-seed
  • interface environment
  • interface environment-preopens
  • interface exit
  • @@ -562,8 +564,8 @@ similar.

    filesystem.
  • -

    writeable:

    -

    True if the resource is considered writeable by the containing +

    writable:

    +

    True if the resource is considered writable by the containing filesystem.

  • @@ -820,7 +822,7 @@ implementations which can set this to a non-none value should do so.

    Write mode: Data can be written to.

  • -

    non-blocking:

    +

    non-blocking:

    Requests non-blocking operation.

    When this flag is enabled, functions may return immediately with an error-code::would-block error code in situations where they would @@ -1075,7 +1077,7 @@ from fdstat_get in earlier versions of WASI.

    set-flags: func

    Set status flags associated with a descriptor.

    -

    This function may only change the non-blocking flag.

    +

    This function may only change the non-blocking flag.

    Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

    Note: This was called fd_fdstat_set_flags in earlier versions of WASI.

    Params
    @@ -1336,7 +1338,7 @@ filesystem, this function fails with e

    access-at: func

    Check accessibility of a filesystem path.

    Check whether the given filesystem path names an object which is -readable, writeable, or executable, or whether it exists.

    +readable, writable, or executable, or whether it exists.

    This does not a guarantee that subsequent accesses will succeed, as filesystem permissions may be modified asynchronously by external entities.

    @@ -1346,7 +1348,7 @@ entities.

  • this: descriptor
  • path-flags: path-flags
  • path: string
  • -
  • ype: access-type
  • +
  • type: access-type
  • Return values
    -

    enum error

    +

    enum error-code

    +

    Error codes.

    +

    In theory, every API can return any error code. +In practice, API's typically only return the errors documented per API +combined with a couple of errors that are always possible:

    +
      +
    • unknown
    • +
    • access-denied
    • +
    • not-supported
    • +
    • out-of-memory
    • +
    +

    See each individual API for what the POSIX equivalents are. They sometimes differ per API.

    Enum Cases
      -
    • unknown
    • -
    • again
    • +
    • +

      unknown

      +

      Unknown error +

    • +
    • +

      access-denied

      +

      Access denied. +

      POSIX equivalent: EACCES, EPERM

      +
    • +
    • +

      not-supported

      +

      The operation is not supported. +

      POSIX equivalent: EOPNOTSUPP

      +
    • +
    • +

      out-of-memory

      +

      Not enough memory to complete the operation. +

      POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY

      +
    • +
    • +

      timeout

      +

      The operation timed out before it could finish completely. +

    • +
    • +

      concurrency-conflict

      +

      This operation is incompatible with another asynchronous operation that is already in progress. +

    • +
    • +

      not-in-progress

      +

      Trying to finish an asynchronous operation that: +- has not been started yet, or: +- was already finished by a previous `finish-*` call. +

      Note: this is scheduled to be removed when futures are natively supported.

      +
    • +
    • +

      would-block

      +

      The operation has been aborted because it could not be completed immediately. +

      Note: this is scheduled to be removed when futures are natively supported.

      +
    • +
    • +

      address-family-not-supported

      +

      The specified address-family is not supported. +

    • +
    • +

      address-family-mismatch

      +

      An IPv4 address was passed to an IPv6 resource, or vice versa. +

    • +
    • +

      invalid-remote-address

      +

      The socket address is not a valid remote address. E.g. the IP address is set to INADDR_ANY, or the port is set to 0. +

    • +
    • +

      ipv4-only-operation

      +

      The operation is only supported on IPv4 resources. +

    • +
    • +

      ipv6-only-operation

      +

      The operation is only supported on IPv6 resources. +

    • +
    • +

      new-socket-limit

      +

      A new socket resource could not be created because of a system limit. +

    • +
    • +

      already-attached

      +

      The socket is already attached to another network. +

    • +
    • +

      already-bound

      +

      The socket is already bound. +

    • +
    • +

      already-connected

      +

      The socket is already in the Connection state. +

    • +
    • +

      not-bound

      +

      The socket is not bound to any local address. +

    • +
    • +

      not-connected

      +

      The socket is not in the Connection state. +

    • +
    • +

      address-not-bindable

      +

      A bind operation failed because the provided address is not an address that the `network` can bind to. +

    • +
    • +

      address-in-use

      +

      A bind operation failed because the provided address is already in use. +

    • +
    • +

      ephemeral-ports-exhausted

      +

      A bind operation failed because there are no ephemeral ports available. +

    • +
    • +

      remote-unreachable

      +

      The remote address is not reachable +

    • +
    • +

      already-listening

      +

      The socket is already in the Listener state. +

    • +
    • +

      not-listening

      +

      The socket is already in the Listener state. +

    • +
    • +

      connection-refused

      +

      The connection was forcefully rejected +

    • +
    • +

      connection-reset

      +

      The connection was reset. +

    • +
    • +

      datagram-too-large

      +
    • +
    • +

      invalid-name

      +

      The provided name is a syntactically invalid domain name. +

    • +
    • +

      name-unresolvable

      +

      Name does not exist or has no suitable associated IP addresses. +

    • +
    • +

      temporary-resolver-failure

      +

      A temporary failure in name resolution occurred. +

    • +
    • +

      permanent-resolver-failure

      +

      A permanent failure in name resolution occurred. +


    Functions

    @@ -1635,8 +1780,8 @@ There is no need for this to map 1:1 to a physical network interface. #### `type network` [`network`](#network)

    -#### `type error` -[`error`](#error) +#### `type error-code` +[`error-code`](#error_code)

    #### `type ip-address` [`ip-address`](#ip_address) @@ -1652,7 +1797,7 @@ There is no need for this to map 1:1 to a physical network interface.

    resolve-addresses: func

    Resolve an internet host name to a list of IP addresses.

    See the wasi-socket proposal README.md for a comparison with getaddrinfo.

    -

    Parameters:

    +

    Parameters

    • name: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted to ASCII using IDNA encoding.
    • @@ -1663,18 +1808,22 @@ systems without an active IPv6 interface. Notes:
    • Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address.
    • Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged.
    -

    This function never blocks. It either immediately returns successfully with a resolve-address-stream -that can be used to (asynchronously) fetch the results. -Or it immediately fails whenever name is:

    +

    This function never blocks. It either immediately fails or immediately returns successfully with a resolve-address-stream +that can be used to (asynchronously) fetch the results.

    +

    At the moment, the stream never completes successfully with 0 items. Ie. the first call +to resolve-next-address never returns ok(none). This may change in the future.

    +

    Typical errors

      -
    • empty
    • -
    • an IP address
    • -
    • a syntactically invalid domain name in another way
    • +
    • invalid-name: name is a syntactically invalid domain name.
    • +
    • invalid-name: name is an IP address.
    • +
    • address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)
    -

    References:

    +

    References:

    Params
      @@ -1685,7 +1834,7 @@ Or it immediately fails whenever name is:

    Return values

    resolve-next-address: func

    Returns the next address from the resolver.

    @@ -1694,13 +1843,20 @@ return the next address in connection order preference. If all addresses have been exhausted, this function returns none. After which, you should release the stream with drop-resolve-address-stream.

    This function never returns IPv4-mapped IPv6 addresses.

    +

    Typical errors

    +
      +
    • name-unresolvable: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY)
    • +
    • temporary-resolver-failure: A temporary failure in name resolution occurred. (EAI_AGAIN)
    • +
    • permanent-resolver-failure: A permanent failure in name resolution occurred. (EAI_FAIL)
    • +
    • would-block: A result is not available yet. (EWOULDBLOCK, EAGAIN)
    • +
    Params
    Return values

    drop-resolve-address-stream: func

    Dispose of the specified resolve-address-stream, after which it may no longer be used.

    @@ -1709,31 +1865,6 @@ After which, you should release the stream with this: resolve-address-stream -

    non-blocking: func

    -

    Get/set the blocking mode of the stream.

    -

    By default a stream is in "blocking" mode, meaning that any function blocks and waits for its completion. -When switched to "non-blocking" mode, operations that would block return an again error. After which -the API consumer is expected to call subscribe and wait for completion using the wasi-poll module.

    -

    Note: these functions are here for WASI Preview2 only. -They're planned to be removed when future is natively supported in Preview3.

    -
    Params
    - -
    Return values
    - -

    set-non-blocking: func

    -
    Params
    - -
    Return values
    -

    subscribe: func

    Create a pollable which will resolve once the stream is ready for I/O.

    Note: this function is here for WASI Preview2 only. @@ -1761,8 +1892,8 @@ It's planned to be removed when future is natively supported in Pre #### `type network` [`network`](#network)

    -#### `type error` -[`error`](#error) +#### `type error-code` +[`error-code`](#error_code)

    #### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address) @@ -1791,94 +1922,166 @@ It's planned to be removed when future is natively supported in Pre


    Functions

    -

    bind: func

    +

    start-bind: func

    Bind the socket to a specific network on the provided IP address and port.

    If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the TCP/UDP port is zero, the socket will be bound to a random free port.

    When a socket is not explicitly bound, the first invocation to a listen or connect operation will implicitly bind the socket.

    -

    Fails when:

    +

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    +

    Typical start errors

      -
    • the socket is already bound.
    • +
    • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
    • +
    • already-bound: The socket is already bound. (EINVAL)
    • +
    • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
    -

    References

    +

    Typical finish errors

    +
      +
    • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
    • +
    • address-in-use: Address is already in use. (EADDRINUSE)
    • +
    • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
    • +
    • not-in-progress: A bind operation is not in progress.
    • +
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    • +
    +

    References

    Params
    Return values
    +

    finish-bind: func

    +
    Params
    + -

    connect: func

    +
    Return values
    + +

    start-connect: func

    Connect to a remote endpoint.

    On success:

    • the socket is transitioned into the Connection state
    • a pair of streams is returned that can be used to read & write to the connection
    -

    Fails when:

    +

    Typical start errors

    +
      +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
    • +
    • already-attached: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
    • +
    • already-connected: The socket is already in the Connection state. (EISCONN)
    • +
    • already-listening: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
    • +
    • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
    • +
    +

    Typical finish errors

      -
    • the socket is already bound to a different network.
    • -
    • the provided network does not allow connections to the specified endpoint.
    • -
    • the socket is already in the Connection or Listener state.
    • -
    • either the remote IP address or port is 0.
    • +
    • timeout: Connection timed out. (ETIMEDOUT)
    • +
    • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
    • +
    • connection-reset: The connection was reset. (ECONNRESET)
    • +
    • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
    • +
    • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
    • +
    • not-in-progress: A connect operation is not in progress.
    • +
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    -

    References

    +

    References

    +
    Params
    + +
    Return values
    + +

    finish-connect: func

    Params
    Return values
    -

    listen: func

    +

    start-listen: func

    Start listening for new connections.

    Transitions the socket into the Listener state.

    -

    Fails when:

    +

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    +

    Typical start errors

    +
      +
    • already-attached: The socket is already attached to a different network. The network passed to listen must be identical to the one passed to bind.
    • +
    • already-connected: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
    • +
    • already-listening: The socket is already in the Listener state.
    • +
    • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EINVAL on BSD)
    • +
    +

    Typical finish errors

      -
    • the socket is already bound to a different network.
    • -
    • the provided network does not allow listening on the specified address.
    • -
    • the socket is already in the Connection or Listener state.
    • +
    • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
    • +
    • not-in-progress: A listen operation is not in progress.
    • +
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    -

    References

    +

    References

    Params
    Return values
    +

    finish-listen: func

    +
    Params
    + +
    Return values
    +

    accept: func

    Accept a new client socket.

    The returned socket is bound and in the Connection state.

    On success, this function returns the newly accepted client socket along with a pair of streams that can be used to read & write to the connection.

    -

    Fails when this socket is not in the Listening state.

    -

    References:

    +

    Typical errors

    +
      +
    • not-listening: Socket is not in the Listener state. (EINVAL)
    • +
    • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
    • +
    +

    Host implementations must skip over transient errors returned by the native accept syscall.

    +

    References

    Params
      @@ -1886,15 +2089,20 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    local-address: func

    Get the bound local address.

    -

    Returns an error if the socket is not bound.

    -

    References

    +

    Typical errors

    +
      +
    • not-bound: The socket is not bound to any local address.
    • +
    +

    References

    Params
      @@ -1902,15 +2110,20 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    remote-address: func

    Get the bound remote address.

    -

    Fails when the socket is not in the Connection state.

    -

    References

    +

    Typical errors

    +
      +
    • not-connected: The socket is not connected to a remote address. (ENOTCONN)
    • +
    +

    References

    Params
      @@ -1918,7 +2131,7 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    address-family: func

    Whether this is a IPv4 or IPv6 socket.

    @@ -1929,20 +2142,25 @@ a pair of streams that can be used to read & write to the connection.

    Return values

    ipv6-only: func

    -

    Whether IPv4 compatibility (dual-stack) mode is disabled or not. -Implementations are not required to support dual-stack mode. Calling set-ipv6-only(false) might fail.

    -

    Fails when called on an IPv4 socket.

    +

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    Equivalent to the IPV6_V6ONLY socket option.

    +

    Typical errors

    +
      +
    • ipv6-only-operation: (get/set) this socket is an IPv4 socket.
    • +
    • already-bound: (set) The socket is already bound.
    • +
    • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
    • +
    • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
    • +
    Params
    Return values

    set-ipv6-only: func

    Params
    @@ -1952,10 +2170,15 @@ Implementations are not required to support dual-stack mode. Calling set-i
    Return values

    set-listen-backlog-size: func

    Hints the desired listen queue size. Implementations are free to ignore this.

    +

    Typical errors

    +
      +
    • already-connected: (set) The socket is already in the Connection state.
    • +
    • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
    • +
    Params
    • this: tcp-socket
    • @@ -1963,17 +2186,21 @@ Implementations are not required to support dual-stack mode. Calling set-i
    Return values

    keep-alive: func

    Equivalent to the SO_KEEPALIVE socket option.

    +

    Typical errors

    +
      +
    • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
    • +
    Params
    Return values

    set-keep-alive: func

    Params
    @@ -1983,17 +2210,21 @@ Implementations are not required to support dual-stack mode. Calling set-i
    Return values

    no-delay: func

    Equivalent to the TCP_NODELAY socket option.

    +

    Typical errors

    +
      +
    • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
    • +
    Params
    Return values

    set-no-delay: func

    Params
    @@ -2003,17 +2234,23 @@ Implementations are not required to support dual-stack mode. Calling set-i
    Return values

    unicast-hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    +

    Typical errors

    +
      +
    • already-connected: (set) The socket is already in the Connection state.
    • +
    • already-listening: (set) The socket is already in the Listener state.
    • +
    • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
    • +
    Params
    Return values

    set-unicast-hop-limit: func

    Params
    @@ -2023,7 +2260,7 @@ Implementations are not required to support dual-stack mode. Calling set-i
    Return values

    receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    @@ -2032,15 +2269,20 @@ In other words, after setting a value, reading the same setting back may return

    Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of actual data to be sent/received by the application, because the kernel might also use the buffer space for internal metadata structures.

    -

    Fails when this socket is in the Listening state.

    Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

    +

    Typical errors

    +
      +
    • already-connected: (set) The socket is already in the Connection state.
    • +
    • already-listening: (set) The socket is already in the Listener state.
    • +
    • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
    • +
    Params
    Return values

    set-receive-buffer-size: func

    Params
    @@ -2050,7 +2292,7 @@ for internal metadata structures.

    Return values

    send-buffer-size: func

    Params
    @@ -2059,7 +2301,7 @@ for internal metadata structures.

    Return values

    set-send-buffer-size: func

    Params
    @@ -2069,32 +2311,7 @@ for internal metadata structures.

    Return values
    -

    non-blocking: func

    -

    Get/set the blocking mode of the socket.

    -

    By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. -When switched to "non-blocking" mode, operations that would block return an again error. After which -the API consumer is expected to call subscribe and wait for completion using the wasi-poll module.

    -

    Note: these functions are here for WASI Preview2 only. -They're planned to be removed when future is natively supported in Preview3.

    -
    Params
    - -
    Return values
    - -

    set-non-blocking: func

    -
    Params
    - -
    Return values
    -

    subscribe: func

    Create a pollable which will resolve once the socket is ready for I/O.

    @@ -2109,7 +2326,7 @@ It's planned to be removed when future is natively supported in Pre
  • pollable
  • shutdown: func

    -

    Gracefully shut down the connection.

    +

    Initiate a graceful shutdown.

    • receive: the socket is not expecting to receive any more data from the peer. All subsequent read operations on the input-stream associated with this socket will return an End Of Stream indication. @@ -2118,12 +2335,17 @@ Any data still in the receive queue at time of calling output-stream associated with this socket will return an error.
    • both: same effect as receive & send combined.
    -

    The shutdown function does not close the socket.

    -

    Fails when the socket is not in the Connection state.

    -

    References

    +

    The shutdown function does not close (drop) the socket.

    +

    Typical errors

    +
      +
    • not-connected: The socket is not in the Connection state. (ENOTCONN)
    • +
    +

    References

    Params
    Return values

    drop-tcp-socket: func

    Dispose of the specified tcp-socket, after which it may no longer be used.

    +

    Similar to the POSIX close function.

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    Params

    Functions

    -

    bind: func

    +

    start-bind: func

    Bind the socket to a specific network on the provided IP address and port.

    If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the TCP/UDP port is zero, the socket will be bound to a random free port.

    -

    When a socket is not explicitly bound, the first invocation to a connect, send or receive operation will -implicitly bind the socket.

    -

    Fails when:

    +

    When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket.

    +

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    +

    Typical start errors

    +
      +
    • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
    • +
    • already-bound: The socket is already bound. (EINVAL)
    • +
    • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
    • +
    +

    Typical finish errors

      -
    • the socket is already bound.
    • +
    • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
    • +
    • address-in-use: Address is already in use. (EADDRINUSE)
    • +
    • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
    • +
    • not-in-progress: A bind operation is not in progress.
    • +
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    -

    References

    +

    References

    +
    Params
    + +
    Return values
    + +

    finish-bind: func

    Params
    Return values
    -

    connect: func

    +

    start-connect: func

    Set the destination address.

    The local-address is updated based on the best network path to remote-address.

    When a destination address is set:

    @@ -2241,24 +2494,46 @@ implicitly bind the socket.

  • the send function can only be used to send to this destination.
  • Note that this function does not generate any network traffic and the peer is not aware of this "connection".

    -

    Fails when:

    +

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    +

    Typical start errors

      -
    • the socket is already bound to a different network.
    • +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • already-attached: The socket is already bound to a different network. The network passed to connect must be identical to the one passed to bind.
    • +
    • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
    -

    References

    +

    Typical finish errors

    +
      +
    • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
    • +
    • not-in-progress: A connect operation is not in progress.
    • +
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    • +
    +

    References

    Params
    Return values
    +

    finish-connect: func

    +
    Params
    + +
    Return values
    +

    receive: func

    Receive a message.

    @@ -2267,15 +2542,21 @@ implicitly bind the socket.

  • The sender address of the datagram
  • The number of bytes read.
  • -

    Fails when:

    +

    Typical errors

      -
    • the socket is not bound.
    • +
    • not-bound: The socket is not bound to any local address. (EINVAL)
    • +
    • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
    • +
    • would-block: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN)
    -

    References

    +

    References

    Params
      @@ -2283,22 +2564,32 @@ implicitly bind the socket.

    Return values

    send: func

    Send a message to a specific destination address.

    The remote address option is required. To send a message to the "connected" peer, call remote-address to get their address.

    -

    Fails when:

    +

    Typical errors

      -
    • the socket is not bound. Unlike POSIX, this function does not perform an implicit bind.
    • -
    • the socket is in "connected" mode and the datagram.remote-address does not match the address passed to connect.
    • +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • already-connected: The socket is in "connected" mode and the datagram.remote-address does not match the address passed to connect. (EISCONN)
    • +
    • not-bound: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind.
    • +
    • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
    • +
    • datagram-too-large: The datagram is too large. (EMSGSIZE)
    • +
    • would-block: The send buffer is currently full. (EWOULDBLOCK, EAGAIN)
    -

    References

    +

    References

    Params
    Return values

    local-address: func

    Get the current bound address.

    -

    Returns an error if the socket is not bound.

    -

    References

    +

    Typical errors

    +
      +
    • not-bound: The socket is not bound to any local address.
    • +
    +

    References

    Params
    Return values

    remote-address: func

    -

    Get the address set with connect.

    -

    References

    +

    Get the address set with connect.

    +

    Typical errors

    +
      +
    • not-connected: The socket is not connected to a remote address. (ENOTCONN)
    • +
    +

    References

    Params
    Return values

    address-family: func

    Whether this is a IPv4 or IPv6 socket.

    @@ -2349,20 +2651,25 @@ call remote-address to get their addr
    Return values

    ipv6-only: func

    -

    Whether IPv4 compatibility (dual-stack) mode is disabled or not. -Implementations are not required to support dual-stack mode, so calling set-ipv6-only(false) might fail.

    -

    Fails when called on an IPv4 socket.

    +

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    Equivalent to the IPV6_V6ONLY socket option.

    +

    Typical errors

    +
      +
    • ipv6-only-operation: (get/set) this socket is an IPv4 socket.
    • +
    • already-bound: (set) The socket is already bound.
    • +
    • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
    • +
    • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
    • +
    Params
    Return values

    set-ipv6-only: func

    Params
    @@ -2372,17 +2679,21 @@ Implementations are not required to support dual-stack mode, so calling se
    Return values

    unicast-hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    +

    Typical errors

    +
      +
    • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
    • +
    Params
    Return values

    set-unicast-hop-limit: func

    Params
    @@ -2392,7 +2703,7 @@ Implementations are not required to support dual-stack mode, so calling se
    Return values

    receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    @@ -2403,13 +2714,17 @@ actual data to be sent/received by the application, because the kernel might als for internal metadata structures.

    Fails when this socket is in the Listening state.

    Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

    +

    Typical errors

    +
      +
    • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
    • +
    Params
    Return values

    set-receive-buffer-size: func

    Params
    @@ -2419,7 +2734,7 @@ for internal metadata structures.

    Return values

    send-buffer-size: func

    Params
    @@ -2428,7 +2743,7 @@ for internal metadata structures.

    Return values

    set-send-buffer-size: func

    Params
    @@ -2438,32 +2753,7 @@ for internal metadata structures.

    Return values
    -

    non-blocking: func

    -

    Get/set the blocking mode of the socket.

    -

    By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. -When switched to "non-blocking" mode, operations that would block return an again error. After which -the API consumer is expected to call subscribe and wait for completion using the wasi-poll module.

    -

    Note: these functions are here for WASI Preview2 only. -They're planned to be removed when future is natively supported in Preview3.

    -
    Params
    - -
    Return values
    - -

    set-non-blocking: func

    -
    Params
    - -
    Return values
    -

    subscribe: func

    Create a pollable which will resolve once the socket is ready for I/O.

    @@ -2490,8 +2780,8 @@ It's planned to be removed when future is natively supported in Pre

    type network

    network

    -#### `type error` -[`error`](#error) +#### `type error-code` +[`error-code`](#error_code)

    #### `type ip-address-family` [`ip-address-family`](#ip_address_family) @@ -2505,12 +2795,21 @@ It's planned to be removed when future is natively supported in Pre

    Create a new UDP socket.

    Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.

    This function does not require a network capability handle. This is considered to be safe because -at time of creation, the socket is not bound to any network yet. Up to the moment bind/connect is called, +at time of creation, the socket is not bound to any network yet. Up to the moment bind/connect is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

    -

    References:

    +

    All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

    +

    Typical errors

    +
      +
    • not-supported: The host does not support UDP sockets. (EOPNOTSUPP)
    • +
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • +
    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
    • +
    +

    References:

    Params
      @@ -2518,7 +2817,7 @@ the socket is effectively an in-memory configuration object, unable to communica
    Return values

    Import interface random

    WASI Random is a random data API.

    @@ -2551,7 +2850,42 @@ deterministic data.

    • u64
    -

    insecure-random: func

    +

    Import interface insecure-random

    +

    The insecure interface for insecure pseudo-random numbers.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +
    +

    Functions

    +

    get-insecure-random-bytes: func

    +

    Return len insecure pseudo-random bytes.

    +

    This function is not cryptographically secure. Do not use it for +anything related to security.

    +

    There are no requirements on the values of the returned bytes, however +implementations are encouraged to return evenly distributed values with +a long period.

    +
    Params
    + +
    Return values
    +
      +
    • list<u8>
    • +
    +

    get-insecure-random-u64: func

    +

    Return an insecure pseudo-random u64 value.

    +

    This function returns the same type of pseudo-random data as +get-insecure-random-bytes, represented as a u64.

    +
    Return values
    +
      +
    • u64
    • +
    +

    Import interface insecure-random-seed

    +

    The insecure-seed interface for seeding hash-map DoS resistance.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +
    +

    Functions

    +

    insecure-seed: func

    Return a 128-bit value that may contain a pseudo-random value.

    The returned value is not required to be computed from a CSPRNG, and may even be entirely deterministic. Host implementations are encouraged to @@ -2567,7 +2901,7 @@ called multiple times and potentially used for purposes other than DoS protection.

    Return values
      -
    • (u64, u64)
    • +
    • (u64, u64)

    Import interface environment


    diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index e92bb6023..79ec64924 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -11,6 +11,8 @@ default world command { import udp-create-socket: sockets.udp-create-socket import udp: sockets.udp import random: random.random + import insecure-random: random.insecure + import insecure-random-seed: random.insecure-seed import poll: poll.poll import streams: io.streams import environment: pkg.environment diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index c04f989bb..109c45099 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -146,9 +146,9 @@ default interface types { /// True if the resource is considered readable by the containing /// filesystem. readable, - /// True if the resource is considered writeable by the containing + /// True if the resource is considered writable by the containing /// filesystem. - writeable, + writable, /// True if the resource is considered executable by the containing /// filesystem. This does not apply to directories. executable, @@ -615,7 +615,7 @@ default interface types { /// Check accessibility of a filesystem path. /// /// Check whether the given filesystem path names an object which is - /// readable, writeable, or executable, or whether it exists. + /// readable, writable, or executable, or whether it exists. /// /// This does not a guarantee that subsequent accesses will succeed, as /// filesystem permissions may be modified asynchronously by external @@ -629,7 +629,7 @@ default interface types { /// The relative path to check. path: string, /// The type of check to perform. - %ype: access-type + %type: access-type ) -> result<_, error-code> /// Unlink a filesystem object that is not a directory. diff --git a/proposals/cli/wit/deps/random/insecure-seed.wit b/proposals/cli/wit/deps/random/insecure-seed.wit new file mode 100644 index 000000000..93a2f17d4 --- /dev/null +++ b/proposals/cli/wit/deps/random/insecure-seed.wit @@ -0,0 +1,24 @@ +/// The insecure-seed interface for seeding hash-map DoS resistance. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface insecure-seed { + /// Return a 128-bit value that may contain a pseudo-random value. + /// + /// The returned value is not required to be computed from a CSPRNG, and may + /// even be entirely deterministic. Host implementations are encouraged to + /// provide pseudo-random values to any program exposed to + /// attacker-controlled content, to enable DoS protection built into many + /// languages' hash-map implementations. + /// + /// This function is intended to only be called once, by a source language + /// to initialize Denial Of Service (DoS) protection in its hash-map + /// implementation. + /// + /// # Expected future evolution + /// + /// This will likely be changed to a value import, to prevent it from being + /// called multiple times and potentially used for purposes other than DoS + /// protection. + insecure-seed: func() -> tuple +} diff --git a/proposals/cli/wit/deps/random/insecure.wit b/proposals/cli/wit/deps/random/insecure.wit new file mode 100644 index 000000000..1ef020a09 --- /dev/null +++ b/proposals/cli/wit/deps/random/insecure.wit @@ -0,0 +1,21 @@ +/// The insecure interface for insecure pseudo-random numbers. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +default interface insecure { + /// Return `len` insecure pseudo-random bytes. + /// + /// This function is not cryptographically secure. Do not use it for + /// anything related to security. + /// + /// There are no requirements on the values of the returned bytes, however + /// implementations are encouraged to return evenly distributed values with + /// a long period. + get-insecure-random-bytes: func(len: u64) -> list + + /// Return an insecure pseudo-random `u64` value. + /// + /// This function returns the same type of pseudo-random data as + /// `get-insecure-random-bytes`, represented as a `u64`. + get-insecure-random-u64: func() -> u64 +} diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index 2080ddfde..8f7585788 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -20,23 +20,4 @@ default interface random { /// This function returns the same type of pseudo-random data as /// `get-random-bytes`, represented as a `u64`. get-random-u64: func() -> u64 - - /// Return a 128-bit value that may contain a pseudo-random value. - /// - /// The returned value is not required to be computed from a CSPRNG, and may - /// even be entirely deterministic. Host implementations are encouraged to - /// provide pseudo-random values to any program exposed to - /// attacker-controlled content, to enable DoS protection built into many - /// languages' hash-map implementations. - /// - /// This function is intended to only be called once, by a source language - /// to initialize Denial Of Service (DoS) protection in its hash-map - /// implementation. - /// - /// # Expected future evolution - /// - /// This will likely be changed to a value import, to prevent it from being - /// called multiple times and potentially used for purposes other than DoS - /// protection. - insecure-random: func() -> tuple } diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index b594598e0..c4cc72684 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,14 +1,14 @@ default interface ip-name-lookup { use poll.poll.{pollable} - use pkg.network.{network, error, ip-address, ip-address-family} + use pkg.network.{network, error-code, ip-address, ip-address-family} /// Resolve an internet host name to a list of IP addresses. /// /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. /// - /// Parameters: + /// # Parameters /// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted /// to ASCII using IDNA encoding. /// - `address-family`: If provided, limit the results to addresses of this specific address family. @@ -18,18 +18,23 @@ default interface ip-name-lookup { /// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. /// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. /// - /// This function never blocks. It either immediately returns successfully with a `resolve-address-stream` + /// This function never blocks. It either immediately fails or immediately returns successfully with a `resolve-address-stream` /// that can be used to (asynchronously) fetch the results. - /// Or it immediately fails whenever `name` is: - /// - empty - /// - an IP address - /// - a syntactically invalid domain name in another way /// - /// References: + /// At the moment, the stream never completes successfully with 0 items. Ie. the first call + /// to `resolve-next-address` never returns `ok(none)`. This may change in the future. + /// + /// # Typical errors + /// - `invalid-name`: `name` is a syntactically invalid domain name. + /// - `invalid-name`: `name` is an IP address. + /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAI_FAMILY) + /// + /// # References: /// - /// - - /// - resolve-addresses: func(network: network, name: string, address-family: option, include-unavailable: bool) -> result + /// - + /// - + resolve-addresses: func(network: network, name: string, address-family: option, include-unavailable: bool) -> result @@ -43,26 +48,19 @@ default interface ip-name-lookup { /// After which, you should release the stream with `drop-resolve-address-stream`. /// /// This function never returns IPv4-mapped IPv6 addresses. - resolve-next-address: func(this: resolve-address-stream) -> result, error> - - + /// + /// # Typical errors + /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) + /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) + /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) + /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) + resolve-next-address: func(this: resolve-address-stream) -> result, error-code> /// Dispose of the specified `resolve-address-stream`, after which it may no longer be used. /// /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. drop-resolve-address-stream: func(this: resolve-address-stream) - /// Get/set the blocking mode of the stream. - /// - /// By default a stream is in "blocking" mode, meaning that any function blocks and waits for its completion. - /// When switched to "non-blocking" mode, operations that would block return an `again` error. After which - /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. - /// - /// Note: these functions are here for WASI Preview2 only. - /// They're planned to be removed when `future` is natively supported in Preview3. - non-blocking: func(this: resolve-address-stream) -> result - set-non-blocking: func(this: resolve-address-stream, value: bool) -> result<_, error> - /// Create a `pollable` which will resolve once the stream is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit index 1f3a20d6b..9176e6ba6 100644 --- a/proposals/cli/wit/deps/sockets/network.wit +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -13,11 +13,141 @@ default interface network { drop-network: func(this: network) + /// Error codes. + /// + /// In theory, every API can return any error code. + /// In practice, API's typically only return the errors documented per API + /// combined with a couple of errors that are always possible: + /// - `unknown` + /// - `access-denied` + /// - `not-supported` + /// - `out-of-memory` + /// + /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. + enum error-code { + // ### GENERAL ERRORS ### - enum error { + /// Unknown error unknown, - again, - // TODO ... + + /// Access denied. + /// + /// POSIX equivalent: EACCES, EPERM + access-denied, + + /// The operation is not supported. + /// + /// POSIX equivalent: EOPNOTSUPP + not-supported, + + /// Not enough memory to complete the operation. + /// + /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY + out-of-memory, + + /// The operation timed out before it could finish completely. + timeout, + + /// This operation is incompatible with another asynchronous operation that is already in progress. + concurrency-conflict, + + /// Trying to finish an asynchronous operation that: + /// - has not been started yet, or: + /// - was already finished by a previous `finish-*` call. + /// + /// Note: this is scheduled to be removed when `future`s are natively supported. + not-in-progress, + + /// The operation has been aborted because it could not be completed immediately. + /// + /// Note: this is scheduled to be removed when `future`s are natively supported. + would-block, + + + // ### IP ERRORS ### + + /// The specified address-family is not supported. + address-family-not-supported, + + /// An IPv4 address was passed to an IPv6 resource, or vice versa. + address-family-mismatch, + + /// The socket address is not a valid remote address. E.g. the IP address is set to INADDR_ANY, or the port is set to 0. + invalid-remote-address, + + /// The operation is only supported on IPv4 resources. + ipv4-only-operation, + + /// The operation is only supported on IPv6 resources. + ipv6-only-operation, + + + + // ### TCP & UDP SOCKET ERRORS ### + + /// A new socket resource could not be created because of a system limit. + new-socket-limit, + + /// The socket is already attached to another network. + already-attached, + + /// The socket is already bound. + already-bound, + + /// The socket is already in the Connection state. + already-connected, + + /// The socket is not bound to any local address. + not-bound, + + /// The socket is not in the Connection state. + not-connected, + + /// A bind operation failed because the provided address is not an address that the `network` can bind to. + address-not-bindable, + + /// A bind operation failed because the provided address is already in use. + address-in-use, + + /// A bind operation failed because there are no ephemeral ports available. + ephemeral-ports-exhausted, + + /// The remote address is not reachable + remote-unreachable, + + + // ### TCP SOCKET ERRORS ### + + /// The socket is already in the Listener state. + already-listening, + + /// The socket is already in the Listener state. + not-listening, + + /// The connection was forcefully rejected + connection-refused, + + /// The connection was reset. + connection-reset, + + + // ### UDP SOCKET ERRORS ### + datagram-too-large, + + + // ### NAME LOOKUP ERRORS ### + + /// The provided name is a syntactically invalid domain name. + invalid-name, + + /// Name does not exist or has no suitable associated IP addresses. + name-unresolvable, + + /// A temporary failure in name resolution occurred. + temporary-resolver-failure, + + /// A permanent failure in name resolution occurred. + permanent-resolver-failure, } enum ip-address-family { diff --git a/proposals/cli/wit/deps/sockets/tcp-create-socket.wit b/proposals/cli/wit/deps/sockets/tcp-create-socket.wit index 571a0197a..6e948fae0 100644 --- a/proposals/cli/wit/deps/sockets/tcp-create-socket.wit +++ b/proposals/cli/wit/deps/sockets/tcp-create-socket.wit @@ -1,6 +1,6 @@ default interface tcp-create-socket { - use pkg.network.{network, error, ip-address-family} + use pkg.network.{network, error-code, ip-address-family} use pkg.tcp.{tcp-socket} /// Create a new TCP socket. @@ -11,9 +11,17 @@ default interface tcp-create-socket { /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// - /// References: + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # Typical errors + /// - `not-supported`: The host does not support TCP sockets. (EOPNOTSUPP) + /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References /// - /// - - /// - create-tcp-socket: func(address-family: ip-address-family) -> result + /// - + /// - + create-tcp-socket: func(address-family: ip-address-family) -> result } diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index b2f483368..b87153243 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -2,7 +2,7 @@ default interface tcp { use io.streams.{input-stream, output-stream} use poll.poll.{pollable} - use pkg.network.{network, error, ip-socket-address, ip-address-family} + use pkg.network.{network, error-code, ip-socket-address, ip-address-family} /// A TCP socket handle. type tcp-socket = u32 @@ -29,13 +29,27 @@ default interface tcp { /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will /// implicitly bind the socket. /// - /// Fails when: - /// - the socket is already bound. + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. /// - /// References + /// # Typical `start` errors + /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) + /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References /// - /// - - bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error> + /// - + /// - + start-bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> + finish-bind: func(this: tcp-socket) -> result<_, error-code> /// Connect to a remote endpoint. /// @@ -43,30 +57,56 @@ default interface tcp { /// - the socket is transitioned into the Connection state /// - a pair of streams is returned that can be used to read & write to the connection /// - /// Fails when: - /// - the socket is already bound to a different network. - /// - the provided network does not allow connections to the specified endpoint. - /// - the socket is already in the Connection or Listener state. - /// - either the remote IP address or port is 0. - /// - /// References + /// # Typical `start` errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `already-connected`: The socket is already in the Connection state. (EISCONN) + /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References /// - /// - - connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result, error> + /// - + /// - + start-connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> + finish-connect: func(this: tcp-socket) -> result, error-code> /// Start listening for new connections. /// /// Transitions the socket into the Listener state. /// - /// Fails when: - /// - the socket is already bound to a different network. - /// - the provided network does not allow listening on the specified address. - /// - the socket is already in the Connection or Listener state. + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `listen` must be identical to the one passed to `bind`. + /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) + /// - `already-listening`: The socket is already in the Listener state. + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) /// - /// References + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// - `not-in-progress`: A `listen` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References /// - /// - - listen: func(this: tcp-socket, network: network) -> result<_, error> + /// - + /// - + start-listen: func(this: tcp-socket, network: network) -> result<_, error-code> + finish-listen: func(this: tcp-socket) -> result<_, error-code> /// Accept a new client socket. /// @@ -75,59 +115,89 @@ default interface tcp { /// On success, this function returns the newly accepted client socket along with /// a pair of streams that can be used to read & write to the connection. /// - /// Fails when this socket is not in the Listening state. + /// # Typical errors + /// - `not-listening`: Socket is not in the Listener state. (EINVAL) + /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) + /// + /// Host implementations must skip over transient errors returned by the native accept syscall. /// - /// References: + /// # References /// - /// - - accept: func(this: tcp-socket) -> result, error> + /// - + /// - + accept: func(this: tcp-socket) -> result, error-code> /// Get the bound local address. /// - /// Returns an error if the socket is not bound. + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. /// - /// References + /// # References /// - /// - - local-address: func(this: tcp-socket) -> result + /// - + /// - + local-address: func(this: tcp-socket) -> result /// Get the bound remote address. /// - /// Fails when the socket is not in the Connection state. + /// # Typical errors + /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) /// - /// References + /// # References /// - /// - - remote-address: func(this: tcp-socket) -> result + /// - + /// - + remote-address: func(this: tcp-socket) -> result /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: tcp-socket) -> result + address-family: func(this: tcp-socket) -> ip-address-family /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// Implementations are not required to support dual-stack mode. Calling `set-ipv6-only(false)` might fail. - /// - /// Fails when called on an IPv4 socket. /// /// Equivalent to the IPV6_V6ONLY socket option. - ipv6-only: func(this: tcp-socket) -> result - set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error> + /// + /// # Typical errors + /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. + /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + ipv6-only: func(this: tcp-socket) -> result + set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error-code> /// Hints the desired listen queue size. Implementations are free to ignore this. - set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error> + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error-code> /// Equivalent to the SO_KEEPALIVE socket option. - keep-alive: func(this: tcp-socket) -> result - set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error> + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + keep-alive: func(this: tcp-socket) -> result + set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error-code> /// Equivalent to the TCP_NODELAY socket option. - no-delay: func(this: tcp-socket) -> result - set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error> + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + no-delay: func(this: tcp-socket) -> result + set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error-code> /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - unicast-hop-limit: func(this: tcp-socket) -> result - set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error> + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `already-listening`: (set) The socket is already in the Listener state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + unicast-hop-limit: func(this: tcp-socket) -> result + set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error-code> /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -138,24 +208,16 @@ default interface tcp { /// actual data to be sent/received by the application, because the kernel might also use the buffer space /// for internal metadata structures. /// - /// Fails when this socket is in the Listening state. - /// /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - receive-buffer-size: func(this: tcp-socket) -> result - set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error> - send-buffer-size: func(this: tcp-socket) -> result - set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error> - - /// Get/set the blocking mode of the socket. /// - /// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. - /// When switched to "non-blocking" mode, operations that would block return an `again` error. After which - /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. - /// - /// Note: these functions are here for WASI Preview2 only. - /// They're planned to be removed when `future` is natively supported in Preview3. - non-blocking: func(this: tcp-socket) -> result - set-non-blocking: func(this: tcp-socket, value: bool) -> result<_, error> + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `already-listening`: (set) The socket is already in the Listener state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + receive-buffer-size: func(this: tcp-socket) -> result + set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> + send-buffer-size: func(this: tcp-socket) -> result + set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> /// Create a `pollable` which will resolve once the socket is ready for I/O. /// @@ -163,7 +225,7 @@ default interface tcp { /// It's planned to be removed when `future` is natively supported in Preview3. subscribe: func(this: tcp-socket) -> pollable - /// Gracefully shut down the connection. + /// Initiate a graceful shutdown. /// /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. @@ -172,17 +234,22 @@ default interface tcp { /// operations on the `output-stream` associated with this socket will return an error. /// - both: same effect as receive & send combined. /// - /// The shutdown function does not close the socket. + /// The shutdown function does not close (drop) the socket. /// - /// Fails when the socket is not in the Connection state. + /// # Typical errors + /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) /// - /// References + /// # References /// - /// - - shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error> + /// - + /// - + shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error-code> /// Dispose of the specified `tcp-socket`, after which it may no longer be used. /// + /// Similar to the POSIX `close` function. + /// /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. drop-tcp-socket: func(this: tcp-socket) } diff --git a/proposals/cli/wit/deps/sockets/udp-create-socket.wit b/proposals/cli/wit/deps/sockets/udp-create-socket.wit index 169957c9f..2c987be08 100644 --- a/proposals/cli/wit/deps/sockets/udp-create-socket.wit +++ b/proposals/cli/wit/deps/sockets/udp-create-socket.wit @@ -1,6 +1,6 @@ default interface udp-create-socket { - use pkg.network.{network, error, ip-address-family} + use pkg.network.{network, error-code, ip-address-family} use pkg.udp.{udp-socket} /// Create a new UDP socket. @@ -11,9 +11,17 @@ default interface udp-create-socket { /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` is called, /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// - /// References: + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # Typical errors + /// - `not-supported`: The host does not support UDP sockets. (EOPNOTSUPP) + /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References: /// - /// - - /// - create-udp-socket: func(address-family: ip-address-family) -> result + /// - + /// - + create-udp-socket: func(address-family: ip-address-family) -> result } diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index af8f873b9..271a2cb9f 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ default interface udp { use poll.poll.{pollable} - use pkg.network.{network, error, ip-socket-address, ip-address-family} + use pkg.network.{network, error-code, ip-socket-address, ip-address-family} /// A UDP socket handle. @@ -28,16 +28,29 @@ default interface udp { /// network interface(s) to bind to. /// If the TCP/UDP port is zero, the socket will be bound to a random free port. /// - /// When a socket is not explicitly bound, the first invocation to a connect, send or receive operation will - /// implicitly bind the socket. + /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. /// - /// Fails when: - /// - the socket is already bound. + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. /// - /// References + /// # Typical `start` errors + /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) + /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References /// - /// - - bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error> + /// - + /// - + start-bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> + finish-bind: func(this: udp-socket) -> result<_, error-code> /// Set the destination address. /// @@ -49,13 +62,27 @@ default interface udp { /// /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". /// - /// Fails when: - /// - the socket is already bound to a different network. + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) /// - /// References + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References /// - /// - - connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error> + /// - + /// - + start-connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> + finish-connect: func(this: udp-socket) -> result<_, error-code> /// Receive a message. /// @@ -63,63 +90,93 @@ default interface udp { /// - The sender address of the datagram /// - The number of bytes read. /// - /// Fails when: - /// - the socket is not bound. + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. (EINVAL) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN) /// - /// References + /// # References /// - /// - /// - - receive: func(this: udp-socket) -> result + /// - + /// - + /// - + /// - + receive: func(this: udp-socket) -> result /// Send a message to a specific destination address. /// /// The remote address option is required. To send a message to the "connected" peer, /// call `remote-address` to get their address. /// - /// Fails when: - /// - the socket is not bound. Unlike POSIX, this function does not perform an implicit bind. - /// - the socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. - /// - /// References + /// # Typical errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN) + /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. + /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN) + /// + /// # References /// - /// - /// - - send: func(this: udp-socket, datagram: datagram) -> result<_, error> + /// - + /// - + /// - + /// - + send: func(this: udp-socket, datagram: datagram) -> result<_, error-code> /// Get the current bound address. /// - /// Returns an error if the socket is not bound. + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. /// - /// References + /// # References /// - /// - - local-address: func(this: udp-socket) -> result + /// - + /// - + local-address: func(this: udp-socket) -> result /// Get the address set with `connect`. /// - /// References + /// # Typical errors + /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References /// - /// - - remote-address: func(this: udp-socket) -> result + /// - + /// - + remote-address: func(this: udp-socket) -> result /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: udp-socket) -> result + address-family: func(this: udp-socket) -> ip-address-family /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// Implementations are not required to support dual-stack mode, so calling `set-ipv6-only(false)` might fail. - /// - /// Fails when called on an IPv4 socket. /// /// Equivalent to the IPV6_V6ONLY socket option. - ipv6-only: func(this: udp-socket) -> result - set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error> + /// + /// # Typical errors + /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. + /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + ipv6-only: func(this: udp-socket) -> result + set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error-code> /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - unicast-hop-limit: func(this: udp-socket) -> result - set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error> + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + unicast-hop-limit: func(this: udp-socket) -> result + set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error-code> /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -133,21 +190,13 @@ default interface udp { /// Fails when this socket is in the Listening state. /// /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - receive-buffer-size: func(this: udp-socket) -> result - set-receive-buffer-size: func(this: udp-socket, value: u64) -> result<_, error> - send-buffer-size: func(this: udp-socket) -> result - set-send-buffer-size: func(this: udp-socket, value: u64) -> result<_, error> - - /// Get/set the blocking mode of the socket. - /// - /// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. - /// When switched to "non-blocking" mode, operations that would block return an `again` error. After which - /// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. /// - /// Note: these functions are here for WASI Preview2 only. - /// They're planned to be removed when `future` is natively supported in Preview3. - non-blocking: func(this: udp-socket) -> result - set-non-blocking: func(this: udp-socket, value: bool) -> result<_, error> + /// # Typical errors + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + receive-buffer-size: func(this: udp-socket) -> result + set-receive-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> + send-buffer-size: func(this: udp-socket) -> result + set-send-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> /// Create a `pollable` which will resolve once the socket is ready for I/O. /// From 6ba784047b1dd8feed44252290aa0003f188021c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 12 May 2023 05:36:09 -0700 Subject: [PATCH 1136/1772] Remove the `network` parameter from `start-listen`. As discussed in #28, remove the network parameter from the `start-listen` function. Also, document that `start-listen` fails if the socket is not bound. This ensures the the address is checked against the network before starting to listen. --- proposals/sockets/example-world.md | 3 +-- proposals/sockets/wit/tcp.wit | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index 913a62967..838a42d2a 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -1115,7 +1115,7 @@ implicitly bind the socket.

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    Typical start errors

      -
    • already-attached: The socket is already attached to a different network. The network passed to listen must be identical to the one passed to bind.
    • +
    • not-bound: The socket is not bound to any local address.
    • already-connected: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
    • already-listening: The socket is already in the Listener state.
    • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EINVAL on BSD)
    • @@ -1136,7 +1136,6 @@ implicitly bind the socket.

      Params
      Return values
        diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index b87153243..956b0c2f4 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -90,7 +90,7 @@ default interface tcp { /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. /// /// # Typical `start` errors - /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `listen` must be identical to the one passed to `bind`. + /// - `not-bound`: The socket is not bound to any local address. /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) /// - `already-listening`: The socket is already in the Listener state. /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) @@ -105,7 +105,7 @@ default interface tcp { /// - /// - /// - - start-listen: func(this: tcp-socket, network: network) -> result<_, error-code> + start-listen: func(this: tcp-socket) -> result<_, error-code> finish-listen: func(this: tcp-socket) -> result<_, error-code> /// Accept a new client socket. From f9dc6bf702fe8ae1daa55f151067e344d44e012f Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 15 May 2023 19:23:57 -0500 Subject: [PATCH 1137/1772] Add workaround to help wasi-libc handle the lack of stdin --- proposals/http/wit/proxy.wit | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 397463456..724884537 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -14,6 +14,12 @@ default world proxy { import stdout: cli.stdio.stdout import stderr: cli.stdio.stderr + // TODO: this is a temporary workaround until component tooling is able to + // gracefully handle the absence of stdin. Hosts must return an eof stream + // for this import, which is what wasi-libc + tooling will do automatically + // when this import is properly removed. + import stdin: cli.stdio.stdin + // This is the default handler to use when user code simply wants to make an // HTTP request (e.g., via `fetch()`). import default-outgoing-HTTP: pkg.outgoing-handler From 45a63bb15959b951d455665d0dd209d9671d573e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 18 May 2023 14:47:41 -0700 Subject: [PATCH 1138/1772] Add an initial current working directory API. (#8) * Add an initial current working directory API. Add a function for returning an initial current working directory. * Remove the descriptor from initial-cwd. --- proposals/cli/command.md | 7 +++++++ proposals/cli/wit/environment-preopens.wit | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 4e44ae4e4..99075054a 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -2943,6 +2943,13 @@ values each time it is called.

        +

        initial-cwd: func

        +

        Return a path that programs should use as their initial current working +directory, interpreting . as shorthand for this.

        +
        Return values
        +
          +
        • option<string>
        • +

        Import interface exit


        Functions

        diff --git a/proposals/cli/wit/environment-preopens.wit b/proposals/cli/wit/environment-preopens.wit index e7ab89d75..f2337800c 100644 --- a/proposals/cli/wit/environment-preopens.wit +++ b/proposals/cli/wit/environment-preopens.wit @@ -4,4 +4,8 @@ default interface environment-preopens { /// Return the set of of preopened directories, and their path. get-directories: func() -> list> + + /// Return a path that programs should use as their initial current working + /// directory, interpreting `.` as shorthand for this. + initial-cwd: func() -> option } From c1dbfe6089fb9a3d56bf3bc86db4c66e956e8df0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 19 May 2023 12:52:02 -0700 Subject: [PATCH 1139/1772] Update wit/tcp.wit Co-authored-by: Dave Bakker --- proposals/sockets/wit/tcp.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 956b0c2f4..346d4bdb5 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -90,7 +90,7 @@ default interface tcp { /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. /// /// # Typical `start` errors - /// - `not-bound`: The socket is not bound to any local address. + /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) /// - `already-listening`: The socket is already in the Listener state. /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) From 63a8e038de5677e955d685400d7ca4a15c0a34d8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 19 May 2023 12:52:24 -0700 Subject: [PATCH 1140/1772] Update wit/tcp.wit Co-authored-by: Dave Bakker --- proposals/sockets/wit/tcp.wit | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 346d4bdb5..b56a2544b 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -87,7 +87,9 @@ default interface tcp { /// /// Transitions the socket into the Listener state. /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// Unlike POSIX: + /// - this function is async. This enables interactive WASI hosts to inject permission prompts. + /// - the socket must already be explicitly bound. /// /// # Typical `start` errors /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) From 37e93cc85f6d6fec623f771edc9866659410e5bb Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 19 May 2023 12:58:10 -0700 Subject: [PATCH 1141/1772] Update example-world.md --- proposals/sockets/example-world.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index 838a42d2a..ce13bb3be 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -1112,10 +1112,14 @@ implicitly bind the socket.

        start-listen: func

        Start listening for new connections.

        Transitions the socket into the Listener state.

        -

        Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

        +

        Unlike POSIX:

        +
          +
        • this function is async. This enables interactive WASI hosts to inject permission prompts.
        • +
        • the socket must already be explicitly bound.
        • +

        Typical start errors

          -
        • not-bound: The socket is not bound to any local address.
        • +
        • not-bound: The socket is not bound to any local address. (EDESTADDRREQ)
        • already-connected: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
        • already-listening: The socket is already in the Listener state.
        • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EINVAL on BSD)
        • From a643073063e69eac9dfb3df3be30656b77bc587e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 24 May 2023 20:13:30 -0700 Subject: [PATCH 1142/1772] Rename environment-preopens to just preopens for now. (#13) Environment variables and arguments are currently in the same interface, so we don't need to qualify that the preopens are for environment variables, as they're for both. --- proposals/cli/command.md | 4 ++-- proposals/cli/wit/command.wit | 2 +- proposals/cli/wit/{environment-preopens.wit => preopens.wit} | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename proposals/cli/wit/{environment-preopens.wit => preopens.wit} (90%) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 99075054a..cdd7b8b95 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -19,7 +19,7 @@
        • interface insecure-random
        • interface insecure-random-seed
        • interface environment
        • -
        • interface environment-preopens
        • +
        • interface preopens
        • interface exit
        • interface stdin
        • interface stdout
        • @@ -2923,7 +2923,7 @@ values each time it is called.

          • list<string>
          -

          Import interface environment-preopens

          +

          Import interface preopens


          Types

          type descriptor

          diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index 79ec64924..ef4ec05c2 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -16,7 +16,7 @@ default world command { import poll: poll.poll import streams: io.streams import environment: pkg.environment - import environment-preopens: pkg.environment-preopens + import preopens: pkg.preopens import exit: pkg.exit import stdin: pkg.stdio.stdin import stdout: pkg.stdio.stdout diff --git a/proposals/cli/wit/environment-preopens.wit b/proposals/cli/wit/preopens.wit similarity index 90% rename from proposals/cli/wit/environment-preopens.wit rename to proposals/cli/wit/preopens.wit index f2337800c..2871ee2c9 100644 --- a/proposals/cli/wit/environment-preopens.wit +++ b/proposals/cli/wit/preopens.wit @@ -1,4 +1,4 @@ -default interface environment-preopens { +default interface preopens { use filesystem.types.{descriptor} use io.streams.{input-stream, output-stream} From 217d583af8110aa42277ec77a5042ebf5330434d Mon Sep 17 00:00:00 2001 From: "Jiaxiao Zhou (Mossaka)" Date: Thu, 25 May 2023 17:23:22 -0700 Subject: [PATCH 1143/1772] Update to the newest WITs Signed-off-by: Jiaxiao Zhou (Mossaka) --- .../sockets/wit/deps/io/deps/poll/poll.wit | 39 ------------------- proposals/sockets/wit/deps/io/streams.wit | 4 +- proposals/sockets/wit/deps/io/world.wit | 5 +++ proposals/sockets/wit/deps/poll/poll.wit | 2 +- proposals/sockets/wit/deps/poll/world.wit | 5 +++ proposals/sockets/wit/instance-network.wit | 4 +- proposals/sockets/wit/ip-name-lookup.wit | 6 +-- proposals/sockets/wit/network.wit | 2 +- proposals/sockets/wit/tcp-create-socket.wit | 6 +-- proposals/sockets/wit/tcp.wit | 8 ++-- proposals/sockets/wit/udp-create-socket.wit | 6 +-- proposals/sockets/wit/udp.wit | 6 +-- proposals/sockets/wit/world.wit | 17 ++++---- 13 files changed, 41 insertions(+), 69 deletions(-) delete mode 100644 proposals/sockets/wit/deps/io/deps/poll/poll.wit create mode 100644 proposals/sockets/wit/deps/io/world.wit create mode 100644 proposals/sockets/wit/deps/poll/world.wit diff --git a/proposals/sockets/wit/deps/io/deps/poll/poll.wit b/proposals/sockets/wit/deps/io/deps/poll/poll.wit deleted file mode 100644 index 28f08e17d..000000000 --- a/proposals/sockets/wit/deps/io/deps/poll/poll.wit +++ /dev/null @@ -1,39 +0,0 @@ -/// A poll API intended to let users wait for I/O events on multiple handles -/// at once. -default interface poll { - /// A "pollable" handle. - /// - /// This is conceptually represents a `stream<_, _>`, or in other words, - /// a stream that one can wait on, repeatedly, but which does not itself - /// produce any data. It's temporary scaffolding until component-model's - /// async features are ready. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// `pollable` lifetimes are not automatically managed. Users must ensure - /// that they do not outlive the resource they reference. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type pollable = u32 - - /// Dispose of the specified `pollable`, after which it may no longer - /// be used. - drop-pollable: func(this: pollable) - - /// Poll for completion on a set of pollables. - /// - /// The "oneoff" in the name refers to the fact that this function must do a - /// linear scan through the entire list of subscriptions, which may be - /// inefficient if the number is large and the same subscriptions are used - /// many times. In the future, this is expected to be obsoleted by the - /// component model async proposal, which will include a scalable waiting - /// facility. - /// - /// Note that the return type would ideally be `list`, but that would - /// be more difficult to polyfill given the current state of `wit-bindgen`. - /// See - /// for details. For now, we use zero to mean "not ready" and non-zero to - /// mean "ready". - poll-oneoff: func(in: list) -> list -} diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index c1567fd4c..430c1d441 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -3,8 +3,8 @@ /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. -default interface streams { - use poll.poll.{pollable} +interface streams { + use wasi:poll/poll.{pollable} /// An error type returned from a stream operation. Currently this /// doesn't provide any additional information. diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit new file mode 100644 index 000000000..b7f625334 --- /dev/null +++ b/proposals/sockets/wit/deps/io/world.wit @@ -0,0 +1,5 @@ +package wasi:io + +world example-world { + import streams +} diff --git a/proposals/sockets/wit/deps/poll/poll.wit b/proposals/sockets/wit/deps/poll/poll.wit index 28f08e17d..55eee0029 100644 --- a/proposals/sockets/wit/deps/poll/poll.wit +++ b/proposals/sockets/wit/deps/poll/poll.wit @@ -1,6 +1,6 @@ /// A poll API intended to let users wait for I/O events on multiple handles /// at once. -default interface poll { +interface poll { /// A "pollable" handle. /// /// This is conceptually represents a `stream<_, _>`, or in other words, diff --git a/proposals/sockets/wit/deps/poll/world.wit b/proposals/sockets/wit/deps/poll/world.wit new file mode 100644 index 000000000..d08cadc05 --- /dev/null +++ b/proposals/sockets/wit/deps/poll/world.wit @@ -0,0 +1,5 @@ +package wasi:poll + +world example-world { + import poll +} diff --git a/proposals/sockets/wit/instance-network.wit b/proposals/sockets/wit/instance-network.wit index b1f5c982d..d911a29cc 100644 --- a/proposals/sockets/wit/instance-network.wit +++ b/proposals/sockets/wit/instance-network.wit @@ -1,7 +1,7 @@ /// This interface provides a value-export of the default network handle.. -default interface instance-network { - use pkg.network.{network} +interface instance-network { + use network.{network} /// Get a handle to the default network. instance-network: func() -> network diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index c4cc72684..f15d19d03 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,7 +1,7 @@ -default interface ip-name-lookup { - use poll.poll.{pollable} - use pkg.network.{network, error-code, ip-address, ip-address-family} +interface ip-name-lookup { + use wasi:poll/poll.{pollable} + use network.{network, error-code, ip-address, ip-address-family} /// Resolve an internet host name to a list of IP addresses. diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 9176e6ba6..2d09bcbdc 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -1,5 +1,5 @@ -default interface network { +interface network { /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. diff --git a/proposals/sockets/wit/tcp-create-socket.wit b/proposals/sockets/wit/tcp-create-socket.wit index 6e948fae0..f43bc8979 100644 --- a/proposals/sockets/wit/tcp-create-socket.wit +++ b/proposals/sockets/wit/tcp-create-socket.wit @@ -1,7 +1,7 @@ -default interface tcp-create-socket { - use pkg.network.{network, error-code, ip-address-family} - use pkg.tcp.{tcp-socket} +interface tcp-create-socket { + use network.{network, error-code, ip-address-family} + use tcp.{tcp-socket} /// Create a new TCP socket. /// diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index b56a2544b..4edb1db7f 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,8 +1,8 @@ -default interface tcp { - use io.streams.{input-stream, output-stream} - use poll.poll.{pollable} - use pkg.network.{network, error-code, ip-socket-address, ip-address-family} +interface tcp { + use wasi:io/streams.{input-stream, output-stream} + use wasi:poll/poll.{pollable} + use network.{network, error-code, ip-socket-address, ip-address-family} /// A TCP socket handle. type tcp-socket = u32 diff --git a/proposals/sockets/wit/udp-create-socket.wit b/proposals/sockets/wit/udp-create-socket.wit index 2c987be08..cd4c08fb1 100644 --- a/proposals/sockets/wit/udp-create-socket.wit +++ b/proposals/sockets/wit/udp-create-socket.wit @@ -1,7 +1,7 @@ -default interface udp-create-socket { - use pkg.network.{network, error-code, ip-address-family} - use pkg.udp.{udp-socket} +interface udp-create-socket { + use network.{network, error-code, ip-address-family} + use udp.{udp-socket} /// Create a new UDP socket. /// diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 271a2cb9f..3a0c1bd14 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,7 +1,7 @@ -default interface udp { - use poll.poll.{pollable} - use pkg.network.{network, error-code, ip-socket-address, ip-address-family} +interface udp { + use wasi:poll/poll.{pollable} + use network.{network, error-code, ip-socket-address, ip-address-family} /// A UDP socket handle. diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index 854fac0ba..ca23d8698 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,10 +1,11 @@ +package wasi:sockets -default world example-world { - import instance-network: pkg.instance-network - import network: pkg.network - import udp: pkg.udp - import udp-create-socket: pkg.udp-create-socket - import tcp: pkg.tcp - import tcp-create-socket: pkg.tcp-create-socket - import ip-name-lookup: pkg.ip-name-lookup +world example-world { + import instance-network + import network + import udp + import udp-create-socket + import tcp + import tcp-create-socket + import ip-name-lookup } From 1c98e02947fb9db1f78180d6dabfb1feda28eb56 Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Fri, 26 May 2023 16:27:28 -0700 Subject: [PATCH 1144/1772] Update to the newest WITs (#32) Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/io/wit/deps/poll/poll.wit | 2 +- proposals/io/wit/deps/poll/world.wit | 5 +++++ proposals/io/wit/streams.wit | 4 ++-- proposals/io/wit/world.wit | 6 ++++-- 4 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 proposals/io/wit/deps/poll/world.wit diff --git a/proposals/io/wit/deps/poll/poll.wit b/proposals/io/wit/deps/poll/poll.wit index 28f08e17d..55eee0029 100644 --- a/proposals/io/wit/deps/poll/poll.wit +++ b/proposals/io/wit/deps/poll/poll.wit @@ -1,6 +1,6 @@ /// A poll API intended to let users wait for I/O events on multiple handles /// at once. -default interface poll { +interface poll { /// A "pollable" handle. /// /// This is conceptually represents a `stream<_, _>`, or in other words, diff --git a/proposals/io/wit/deps/poll/world.wit b/proposals/io/wit/deps/poll/world.wit new file mode 100644 index 000000000..d08cadc05 --- /dev/null +++ b/proposals/io/wit/deps/poll/world.wit @@ -0,0 +1,5 @@ +package wasi:poll + +world example-world { + import poll +} diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index c1567fd4c..430c1d441 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -3,8 +3,8 @@ /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. -default interface streams { - use poll.poll.{pollable} +interface streams { + use wasi:poll/poll.{pollable} /// An error type returned from a stream operation. Currently this /// doesn't provide any additional information. diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index bae7c92b3..b7f625334 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -1,3 +1,5 @@ -default world example-world { - import streams: pkg.streams +package wasi:io + +world example-world { + import streams } From 06c13b1aa2bff0e3164b73367009242ce065648a Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Fri, 26 May 2023 16:28:26 -0700 Subject: [PATCH 1145/1772] Update to the newest WITs (#43) Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/clocks/wit/deps/poll/poll.wit | 2 +- proposals/clocks/wit/deps/poll/world.wit | 5 +++++ proposals/clocks/wit/monotonic-clock.wit | 4 ++-- proposals/clocks/wit/timezone.wit | 4 ++-- proposals/clocks/wit/wall-clock.wit | 2 +- proposals/clocks/wit/world.wit | 10 ++++++---- 6 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 proposals/clocks/wit/deps/poll/world.wit diff --git a/proposals/clocks/wit/deps/poll/poll.wit b/proposals/clocks/wit/deps/poll/poll.wit index 28f08e17d..55eee0029 100644 --- a/proposals/clocks/wit/deps/poll/poll.wit +++ b/proposals/clocks/wit/deps/poll/poll.wit @@ -1,6 +1,6 @@ /// A poll API intended to let users wait for I/O events on multiple handles /// at once. -default interface poll { +interface poll { /// A "pollable" handle. /// /// This is conceptually represents a `stream<_, _>`, or in other words, diff --git a/proposals/clocks/wit/deps/poll/world.wit b/proposals/clocks/wit/deps/poll/world.wit new file mode 100644 index 000000000..d08cadc05 --- /dev/null +++ b/proposals/clocks/wit/deps/poll/world.wit @@ -0,0 +1,5 @@ +package wasi:poll + +world example-world { + import poll +} diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index 42e2981f5..fb8424eb0 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -8,8 +8,8 @@ /// successive reads of the clock will produce non-decreasing values. /// /// It is intended for measuring elapsed time. -default interface monotonic-clock { - use poll.poll.{pollable} +interface monotonic-clock { + use wasi:poll/poll.{pollable} /// A timestamp in nanoseconds. type instant = u64 diff --git a/proposals/clocks/wit/timezone.wit b/proposals/clocks/wit/timezone.wit index 63f99cc40..662830871 100644 --- a/proposals/clocks/wit/timezone.wit +++ b/proposals/clocks/wit/timezone.wit @@ -1,5 +1,5 @@ -default interface timezone { - use pkg.wall-clock.{datetime} +interface timezone { + use wall-clock.{datetime} /// A timezone. /// diff --git a/proposals/clocks/wit/wall-clock.wit b/proposals/clocks/wit/wall-clock.wit index 89c5a75da..dae44a730 100644 --- a/proposals/clocks/wit/wall-clock.wit +++ b/proposals/clocks/wit/wall-clock.wit @@ -12,7 +12,7 @@ /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -default interface wall-clock { +interface wall-clock { /// A time and date in seconds plus nanoseconds. record datetime { seconds: u64, diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index 8e3da6cc0..291a9c75e 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -1,5 +1,7 @@ -default world example-world { - import monotonic-clock: pkg.monotonic-clock - import wall-clock: pkg.wall-clock - import timezone: pkg.timezone +package wasi:clocks + +world example-world { + import monotonic-clock + import wall-clock + import timezone } From d957e3ab99a8de87dceb7dfbb4509d9efc7b8b2c Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Fri, 26 May 2023 16:28:52 -0700 Subject: [PATCH 1146/1772] Update to the newest WITs (#118) Signed-off-by: Jiaxiao Zhou (Mossaka) --- .../wit/deps/clocks/monotonic-clock.wit | 32 ++++++++++ .../filesystem/wit/deps/clocks/timezone.wit | 61 +++++++++++++++++++ .../filesystem/wit/deps/clocks/wall-clock.wit | 2 +- .../filesystem/wit/deps/clocks/world.wit | 7 +++ proposals/filesystem/wit/deps/io/streams.wit | 4 +- proposals/filesystem/wit/deps/io/world.wit | 5 ++ proposals/filesystem/wit/deps/poll/poll.wit | 2 +- proposals/filesystem/wit/deps/poll/world.wit | 5 ++ proposals/filesystem/wit/types.wit | 6 +- proposals/filesystem/wit/world.wit | 6 +- 10 files changed, 121 insertions(+), 9 deletions(-) create mode 100644 proposals/filesystem/wit/deps/clocks/monotonic-clock.wit create mode 100644 proposals/filesystem/wit/deps/clocks/timezone.wit create mode 100644 proposals/filesystem/wit/deps/clocks/world.wit create mode 100644 proposals/filesystem/wit/deps/io/world.wit create mode 100644 proposals/filesystem/wit/deps/poll/world.wit diff --git a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit new file mode 100644 index 000000000..fb8424eb0 --- /dev/null +++ b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit @@ -0,0 +1,32 @@ +/// WASI Monotonic Clock is a clock API intended to let users measure elapsed +/// time. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A monotonic clock is a clock which has an unspecified initial value, and +/// successive reads of the clock will produce non-decreasing values. +/// +/// It is intended for measuring elapsed time. +interface monotonic-clock { + use wasi:poll/poll.{pollable} + + /// A timestamp in nanoseconds. + type instant = u64 + + /// Read the current value of the clock. + /// + /// The clock is monotonic, therefore calling this function repeatedly will + /// produce a sequence of non-decreasing values. + now: func() -> instant + + /// Query the resolution of the clock. + resolution: func() -> instant + + /// Create a `pollable` which will resolve once the specified time has been + /// reached. + subscribe: func( + when: instant, + absolute: bool + ) -> pollable +} diff --git a/proposals/filesystem/wit/deps/clocks/timezone.wit b/proposals/filesystem/wit/deps/clocks/timezone.wit new file mode 100644 index 000000000..662830871 --- /dev/null +++ b/proposals/filesystem/wit/deps/clocks/timezone.wit @@ -0,0 +1,61 @@ +interface timezone { + use wall-clock.{datetime} + + /// A timezone. + /// + /// In timezones that recognize daylight saving time, also known as daylight + /// time and summer time, the information returned from the functions varies + /// over time to reflect these adjustments. + /// + /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). + type timezone = u32 + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + display: func(this: timezone, when: datetime) -> timezone-display + + /// The same as `display`, but only return the UTC offset. + utc-offset: func(this: timezone, when: datetime) -> s32 + + /// Dispose of the specified input-stream, after which it may no longer + /// be used. + drop-timezone: func(this: timezone) + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/filesystem/wit/deps/clocks/wall-clock.wit b/proposals/filesystem/wit/deps/clocks/wall-clock.wit index 89c5a75da..dae44a730 100644 --- a/proposals/filesystem/wit/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/wall-clock.wit @@ -12,7 +12,7 @@ /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -default interface wall-clock { +interface wall-clock { /// A time and date in seconds plus nanoseconds. record datetime { seconds: u64, diff --git a/proposals/filesystem/wit/deps/clocks/world.wit b/proposals/filesystem/wit/deps/clocks/world.wit new file mode 100644 index 000000000..291a9c75e --- /dev/null +++ b/proposals/filesystem/wit/deps/clocks/world.wit @@ -0,0 +1,7 @@ +package wasi:clocks + +world example-world { + import monotonic-clock + import wall-clock + import timezone +} diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index c1567fd4c..430c1d441 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -3,8 +3,8 @@ /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. -default interface streams { - use poll.poll.{pollable} +interface streams { + use wasi:poll/poll.{pollable} /// An error type returned from a stream operation. Currently this /// doesn't provide any additional information. diff --git a/proposals/filesystem/wit/deps/io/world.wit b/proposals/filesystem/wit/deps/io/world.wit new file mode 100644 index 000000000..b7f625334 --- /dev/null +++ b/proposals/filesystem/wit/deps/io/world.wit @@ -0,0 +1,5 @@ +package wasi:io + +world example-world { + import streams +} diff --git a/proposals/filesystem/wit/deps/poll/poll.wit b/proposals/filesystem/wit/deps/poll/poll.wit index 28f08e17d..55eee0029 100644 --- a/proposals/filesystem/wit/deps/poll/poll.wit +++ b/proposals/filesystem/wit/deps/poll/poll.wit @@ -1,6 +1,6 @@ /// A poll API intended to let users wait for I/O events on multiple handles /// at once. -default interface poll { +interface poll { /// A "pollable" handle. /// /// This is conceptually represents a `stream<_, _>`, or in other words, diff --git a/proposals/filesystem/wit/deps/poll/world.wit b/proposals/filesystem/wit/deps/poll/world.wit new file mode 100644 index 000000000..d08cadc05 --- /dev/null +++ b/proposals/filesystem/wit/deps/poll/world.wit @@ -0,0 +1,5 @@ +package wasi:poll + +world example-world { + import poll +} diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 109c45099..627b638ef 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -17,9 +17,9 @@ /// `..` and symbolic link steps, reaches a directory outside of the base /// directory, or reaches a symlink to an absolute or rooted path in the /// underlying filesystem, the function fails with `error-code::not-permitted`. -default interface types { - use io.streams.{input-stream, output-stream} - use clocks.wall-clock.{datetime} +interface types { + use wasi:io/streams.{input-stream, output-stream} + use wasi:clocks/wall-clock.{datetime} /// File size or length of a region within a file. type filesize = u64 diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index 209211029..f2ef782f4 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,3 +1,5 @@ -default world example-world { - import types: pkg.types +package wasi:filesystem + +world example-world { + import types } From 384c6f3ff19667db29487b6260cf561e7ceaf892 Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Fri, 26 May 2023 16:29:14 -0700 Subject: [PATCH 1147/1772] Update to the newest WITs (#31) Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/random/wit/insecure-seed.wit | 2 +- proposals/random/wit/insecure.wit | 2 +- proposals/random/wit/random.wit | 2 +- proposals/random/wit/world.wit | 10 ++++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index 93a2f17d4..ff2ff65d0 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -2,7 +2,7 @@ /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -default interface insecure-seed { +interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// /// The returned value is not required to be computed from a CSPRNG, and may diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index 1ef020a09..ff0826822 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -2,7 +2,7 @@ /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -default interface insecure { +interface insecure { /// Return `len` insecure pseudo-random bytes. /// /// This function is not cryptographically secure. Do not use it for diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 8f7585788..e4238621e 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -2,7 +2,7 @@ /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -default interface random { +interface random { /// Return `len` cryptographically-secure pseudo-random bytes. /// /// This function must produce data from an adequately seeded diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index b109e0b91..3c3d16554 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,5 +1,7 @@ -default world example-world { - import random: pkg.random - import insecure: pkg.insecure - import insecure-seed: pkg.insecure-seed +package wasi:random + +world example-world { + import random + import insecure + import insecure-seed } From 14ac22378abc634f858d922be80b0404077422ea Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Fri, 26 May 2023 16:31:47 -0700 Subject: [PATCH 1148/1772] Update to the newest WITs (#14) Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/cli/wit/command.wit | 50 ++++++++++--------- .../cli/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/cli/wit/deps/clocks/timezone.wit | 4 +- proposals/cli/wit/deps/clocks/wall-clock.wit | 2 +- proposals/cli/wit/deps/clocks/world.wit | 7 +++ proposals/cli/wit/deps/filesystem/types.wit | 6 +-- proposals/cli/wit/deps/filesystem/world.wit | 5 ++ proposals/cli/wit/deps/io/streams.wit | 4 +- proposals/cli/wit/deps/io/world.wit | 5 ++ proposals/cli/wit/deps/poll/poll.wit | 2 +- proposals/cli/wit/deps/poll/world.wit | 5 ++ .../cli/wit/deps/random/insecure-seed.wit | 2 +- proposals/cli/wit/deps/random/insecure.wit | 2 +- proposals/cli/wit/deps/random/random.wit | 2 +- proposals/cli/wit/deps/random/world.wit | 7 +++ .../cli/wit/deps/sockets/instance-network.wit | 4 +- .../cli/wit/deps/sockets/ip-name-lookup.wit | 6 +-- proposals/cli/wit/deps/sockets/network.wit | 2 +- .../wit/deps/sockets/tcp-create-socket.wit | 6 +-- proposals/cli/wit/deps/sockets/tcp.wit | 16 +++--- .../wit/deps/sockets/udp-create-socket.wit | 6 +-- proposals/cli/wit/deps/sockets/udp.wit | 6 +-- proposals/cli/wit/deps/sockets/world.wit | 11 ++++ proposals/cli/wit/environment.wit | 2 +- proposals/cli/wit/exit.wit | 2 +- proposals/cli/wit/preopens.wit | 6 +-- proposals/cli/wit/run.wit | 2 +- proposals/cli/wit/stdio.wit | 6 +-- proposals/cli/wit/terminal.wit | 6 +-- 29 files changed, 116 insertions(+), 72 deletions(-) create mode 100644 proposals/cli/wit/deps/clocks/world.wit create mode 100644 proposals/cli/wit/deps/filesystem/world.wit create mode 100644 proposals/cli/wit/deps/io/world.wit create mode 100644 proposals/cli/wit/deps/poll/world.wit create mode 100644 proposals/cli/wit/deps/random/world.wit create mode 100644 proposals/cli/wit/deps/sockets/world.wit diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index ef4ec05c2..13675f180 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,25 +1,27 @@ -default world command { - import wall-clock: clocks.wall-clock - import monotonic-clock: clocks.monotonic-clock - import timezone: clocks.timezone - import filesystem: filesystem.types - import instance-network: sockets.instance-network - import ip-name-lookup: sockets.ip-name-lookup - import network: sockets.network - import tcp-create-socket: sockets.tcp-create-socket - import tcp: sockets.tcp - import udp-create-socket: sockets.udp-create-socket - import udp: sockets.udp - import random: random.random - import insecure-random: random.insecure - import insecure-random-seed: random.insecure-seed - import poll: poll.poll - import streams: io.streams - import environment: pkg.environment - import preopens: pkg.preopens - import exit: pkg.exit - import stdin: pkg.stdio.stdin - import stdout: pkg.stdio.stdout - import stderr: pkg.stdio.stderr - export run: pkg.run +package wasi:cli + +world command { + import wasi:clocks/wall-clock + import wasi:clocks/monotonic-clock + import wasi:clocks/timezone + import wasi:filesystem/types + import wasi:sockets/instance-network + import wasi:sockets/ip-name-lookup + import wasi:sockets/network + import wasi:sockets/tcp-create-socket + import wasi:sockets/tcp + import wasi:sockets/udp-create-socket + import wasi:sockets/udp + import wasi:random/random + import wasi:random/insecure + import wasi:random/insecure-seed + import wasi:poll/poll + import wasi:io/streams + import environment + import preopens + import exit + import stdin + import stdout + import stderr + export run } diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index 42e2981f5..fb8424eb0 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -8,8 +8,8 @@ /// successive reads of the clock will produce non-decreasing values. /// /// It is intended for measuring elapsed time. -default interface monotonic-clock { - use poll.poll.{pollable} +interface monotonic-clock { + use wasi:poll/poll.{pollable} /// A timestamp in nanoseconds. type instant = u64 diff --git a/proposals/cli/wit/deps/clocks/timezone.wit b/proposals/cli/wit/deps/clocks/timezone.wit index 63f99cc40..662830871 100644 --- a/proposals/cli/wit/deps/clocks/timezone.wit +++ b/proposals/cli/wit/deps/clocks/timezone.wit @@ -1,5 +1,5 @@ -default interface timezone { - use pkg.wall-clock.{datetime} +interface timezone { + use wall-clock.{datetime} /// A timezone. /// diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit index 89c5a75da..dae44a730 100644 --- a/proposals/cli/wit/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -12,7 +12,7 @@ /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -default interface wall-clock { +interface wall-clock { /// A time and date in seconds plus nanoseconds. record datetime { seconds: u64, diff --git a/proposals/cli/wit/deps/clocks/world.wit b/proposals/cli/wit/deps/clocks/world.wit new file mode 100644 index 000000000..291a9c75e --- /dev/null +++ b/proposals/cli/wit/deps/clocks/world.wit @@ -0,0 +1,7 @@ +package wasi:clocks + +world example-world { + import monotonic-clock + import wall-clock + import timezone +} diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index 109c45099..627b638ef 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -17,9 +17,9 @@ /// `..` and symbolic link steps, reaches a directory outside of the base /// directory, or reaches a symlink to an absolute or rooted path in the /// underlying filesystem, the function fails with `error-code::not-permitted`. -default interface types { - use io.streams.{input-stream, output-stream} - use clocks.wall-clock.{datetime} +interface types { + use wasi:io/streams.{input-stream, output-stream} + use wasi:clocks/wall-clock.{datetime} /// File size or length of a region within a file. type filesize = u64 diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit new file mode 100644 index 000000000..f2ef782f4 --- /dev/null +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -0,0 +1,5 @@ +package wasi:filesystem + +world example-world { + import types +} diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index c1567fd4c..430c1d441 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -3,8 +3,8 @@ /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. -default interface streams { - use poll.poll.{pollable} +interface streams { + use wasi:poll/poll.{pollable} /// An error type returned from a stream operation. Currently this /// doesn't provide any additional information. diff --git a/proposals/cli/wit/deps/io/world.wit b/proposals/cli/wit/deps/io/world.wit new file mode 100644 index 000000000..b7f625334 --- /dev/null +++ b/proposals/cli/wit/deps/io/world.wit @@ -0,0 +1,5 @@ +package wasi:io + +world example-world { + import streams +} diff --git a/proposals/cli/wit/deps/poll/poll.wit b/proposals/cli/wit/deps/poll/poll.wit index 28f08e17d..55eee0029 100644 --- a/proposals/cli/wit/deps/poll/poll.wit +++ b/proposals/cli/wit/deps/poll/poll.wit @@ -1,6 +1,6 @@ /// A poll API intended to let users wait for I/O events on multiple handles /// at once. -default interface poll { +interface poll { /// A "pollable" handle. /// /// This is conceptually represents a `stream<_, _>`, or in other words, diff --git a/proposals/cli/wit/deps/poll/world.wit b/proposals/cli/wit/deps/poll/world.wit new file mode 100644 index 000000000..d08cadc05 --- /dev/null +++ b/proposals/cli/wit/deps/poll/world.wit @@ -0,0 +1,5 @@ +package wasi:poll + +world example-world { + import poll +} diff --git a/proposals/cli/wit/deps/random/insecure-seed.wit b/proposals/cli/wit/deps/random/insecure-seed.wit index 93a2f17d4..ff2ff65d0 100644 --- a/proposals/cli/wit/deps/random/insecure-seed.wit +++ b/proposals/cli/wit/deps/random/insecure-seed.wit @@ -2,7 +2,7 @@ /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -default interface insecure-seed { +interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// /// The returned value is not required to be computed from a CSPRNG, and may diff --git a/proposals/cli/wit/deps/random/insecure.wit b/proposals/cli/wit/deps/random/insecure.wit index 1ef020a09..ff0826822 100644 --- a/proposals/cli/wit/deps/random/insecure.wit +++ b/proposals/cli/wit/deps/random/insecure.wit @@ -2,7 +2,7 @@ /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -default interface insecure { +interface insecure { /// Return `len` insecure pseudo-random bytes. /// /// This function is not cryptographically secure. Do not use it for diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index 8f7585788..e4238621e 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -2,7 +2,7 @@ /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -default interface random { +interface random { /// Return `len` cryptographically-secure pseudo-random bytes. /// /// This function must produce data from an adequately seeded diff --git a/proposals/cli/wit/deps/random/world.wit b/proposals/cli/wit/deps/random/world.wit new file mode 100644 index 000000000..3c3d16554 --- /dev/null +++ b/proposals/cli/wit/deps/random/world.wit @@ -0,0 +1,7 @@ +package wasi:random + +world example-world { + import random + import insecure + import insecure-seed +} diff --git a/proposals/cli/wit/deps/sockets/instance-network.wit b/proposals/cli/wit/deps/sockets/instance-network.wit index b1f5c982d..d911a29cc 100644 --- a/proposals/cli/wit/deps/sockets/instance-network.wit +++ b/proposals/cli/wit/deps/sockets/instance-network.wit @@ -1,7 +1,7 @@ /// This interface provides a value-export of the default network handle.. -default interface instance-network { - use pkg.network.{network} +interface instance-network { + use network.{network} /// Get a handle to the default network. instance-network: func() -> network diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index c4cc72684..f15d19d03 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ -default interface ip-name-lookup { - use poll.poll.{pollable} - use pkg.network.{network, error-code, ip-address, ip-address-family} +interface ip-name-lookup { + use wasi:poll/poll.{pollable} + use network.{network, error-code, ip-address, ip-address-family} /// Resolve an internet host name to a list of IP addresses. diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit index 9176e6ba6..2d09bcbdc 100644 --- a/proposals/cli/wit/deps/sockets/network.wit +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -1,5 +1,5 @@ -default interface network { +interface network { /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. diff --git a/proposals/cli/wit/deps/sockets/tcp-create-socket.wit b/proposals/cli/wit/deps/sockets/tcp-create-socket.wit index 6e948fae0..f43bc8979 100644 --- a/proposals/cli/wit/deps/sockets/tcp-create-socket.wit +++ b/proposals/cli/wit/deps/sockets/tcp-create-socket.wit @@ -1,7 +1,7 @@ -default interface tcp-create-socket { - use pkg.network.{network, error-code, ip-address-family} - use pkg.tcp.{tcp-socket} +interface tcp-create-socket { + use network.{network, error-code, ip-address-family} + use tcp.{tcp-socket} /// Create a new TCP socket. /// diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index b87153243..4edb1db7f 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -1,8 +1,8 @@ -default interface tcp { - use io.streams.{input-stream, output-stream} - use poll.poll.{pollable} - use pkg.network.{network, error-code, ip-socket-address, ip-address-family} +interface tcp { + use wasi:io/streams.{input-stream, output-stream} + use wasi:poll/poll.{pollable} + use network.{network, error-code, ip-socket-address, ip-address-family} /// A TCP socket handle. type tcp-socket = u32 @@ -87,10 +87,12 @@ default interface tcp { /// /// Transitions the socket into the Listener state. /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// Unlike POSIX: + /// - this function is async. This enables interactive WASI hosts to inject permission prompts. + /// - the socket must already be explicitly bound. /// /// # Typical `start` errors - /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `listen` must be identical to the one passed to `bind`. + /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) /// - `already-listening`: The socket is already in the Listener state. /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) @@ -105,7 +107,7 @@ default interface tcp { /// - /// - /// - - start-listen: func(this: tcp-socket, network: network) -> result<_, error-code> + start-listen: func(this: tcp-socket) -> result<_, error-code> finish-listen: func(this: tcp-socket) -> result<_, error-code> /// Accept a new client socket. diff --git a/proposals/cli/wit/deps/sockets/udp-create-socket.wit b/proposals/cli/wit/deps/sockets/udp-create-socket.wit index 2c987be08..cd4c08fb1 100644 --- a/proposals/cli/wit/deps/sockets/udp-create-socket.wit +++ b/proposals/cli/wit/deps/sockets/udp-create-socket.wit @@ -1,7 +1,7 @@ -default interface udp-create-socket { - use pkg.network.{network, error-code, ip-address-family} - use pkg.udp.{udp-socket} +interface udp-create-socket { + use network.{network, error-code, ip-address-family} + use udp.{udp-socket} /// Create a new UDP socket. /// diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index 271a2cb9f..3a0c1bd14 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ -default interface udp { - use poll.poll.{pollable} - use pkg.network.{network, error-code, ip-socket-address, ip-address-family} +interface udp { + use wasi:poll/poll.{pollable} + use network.{network, error-code, ip-socket-address, ip-address-family} /// A UDP socket handle. diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit new file mode 100644 index 000000000..ca23d8698 --- /dev/null +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -0,0 +1,11 @@ +package wasi:sockets + +world example-world { + import instance-network + import network + import udp + import udp-create-socket + import tcp + import tcp-create-socket + import ip-name-lookup +} diff --git a/proposals/cli/wit/environment.wit b/proposals/cli/wit/environment.wit index 876ea3a0c..65471e86d 100644 --- a/proposals/cli/wit/environment.wit +++ b/proposals/cli/wit/environment.wit @@ -1,4 +1,4 @@ -default interface environment { +interface environment { /// Get the POSIX-style environment variables. /// /// Each environment variable is provided as a pair of string variable names diff --git a/proposals/cli/wit/exit.wit b/proposals/cli/wit/exit.wit index 2759e9dd9..66835aa70 100644 --- a/proposals/cli/wit/exit.wit +++ b/proposals/cli/wit/exit.wit @@ -1,4 +1,4 @@ -default interface wasi-exit { +interface exit { /// Exit the curerent instance and any linked instances. exit: func(status: result) } diff --git a/proposals/cli/wit/preopens.wit b/proposals/cli/wit/preopens.wit index 2871ee2c9..637102878 100644 --- a/proposals/cli/wit/preopens.wit +++ b/proposals/cli/wit/preopens.wit @@ -1,6 +1,6 @@ -default interface preopens { - use filesystem.types.{descriptor} - use io.streams.{input-stream, output-stream} +interface preopens { + use wasi:filesystem/types.{descriptor} + use wasi:io/streams.{input-stream, output-stream} /// Return the set of of preopened directories, and their path. get-directories: func() -> list> diff --git a/proposals/cli/wit/run.wit b/proposals/cli/wit/run.wit index 2132e98e7..45a1ca533 100644 --- a/proposals/cli/wit/run.wit +++ b/proposals/cli/wit/run.wit @@ -1,4 +1,4 @@ -default interface run { +interface run { /// Run the program. run: func() -> result } diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index 1f87e5485..6c9d4a41a 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,17 +1,17 @@ interface stdin { - use io.streams.{input-stream} + use wasi:io/streams.{input-stream} get-stdin: func() -> input-stream } interface stdout { - use io.streams.{output-stream} + use wasi:io/streams.{output-stream} get-stdout: func() -> output-stream } interface stderr { - use io.streams.{output-stream} + use wasi:io/streams.{output-stream} get-stderr: func() -> output-stream } diff --git a/proposals/cli/wit/terminal.wit b/proposals/cli/wit/terminal.wit index 988068af7..f32e74437 100644 --- a/proposals/cli/wit/terminal.wit +++ b/proposals/cli/wit/terminal.wit @@ -31,7 +31,7 @@ interface terminal-output { /// An interface providing an optional `terminal-input` for stdin as a /// link-time authority. interface terminal-stdin { - use self.terminal-input.{terminal-input} + use terminal-input.{terminal-input} /// If stdin is connected to a terminal, return a `terminal-input` handle /// allowing further interaction with it. @@ -41,7 +41,7 @@ interface terminal-stdin { /// An interface providing an optional `terminal-output` for stdout as a /// link-time authority. interface terminal-stdout { - use self.terminal-output.{terminal-output} + use terminal-output.{terminal-output} /// If stdout is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. @@ -51,7 +51,7 @@ interface terminal-stdout { /// An interface providing an optional `terminal-output` for stderr as a /// link-time authority. interface terminal-stderr { - use self.terminal-output.{terminal-output} + use terminal-output.{terminal-output} /// If stderr is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. From 49de5ad74d7bdcc08d8177821b30366000d20c16 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Mon, 29 May 2023 10:55:01 +0200 Subject: [PATCH 1149/1772] Update example-world.md --- proposals/sockets/example-world.md | 36 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index ce13bb3be..736792b1f 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -2,19 +2,19 @@ -

          Import interface network

          +

          Import interface wasi:sockets/network


          Types

          type network

          @@ -239,7 +239,7 @@ combined with a couple of errors that are always possible:

          -

          Import interface instance-network

          +

          Import interface wasi:sockets/instance-network

          This interface provides a value-export of the default network handle..


          Types

          @@ -254,7 +254,7 @@ combined with a couple of errors that are always possible:

          -

          Import interface poll

          +

          Import interface wasi:poll/poll

          A poll API intended to let users wait for I/O events on multiple handles at once.


          @@ -301,7 +301,7 @@ mean "ready".

          • list<u8>
          -

          Import interface udp

          +

          Import interface wasi:sockets/udp


          Types

          type pollable

          @@ -666,7 +666,7 @@ It's planned to be removed when future is natively supported in Pre -

          Import interface udp-create-socket

          +

          Import interface wasi:sockets/udp-create-socket


          Types

          type network

          @@ -711,7 +711,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

          Import interface streams

          +

          Import interface wasi:io/streams

          WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

          In the future, the component model is expected to add built-in stream types; @@ -963,7 +963,7 @@ be used.

          -

          Import interface tcp

          +

          Import interface wasi:sockets/tcp


          Types

          type input-stream

          @@ -1453,7 +1453,7 @@ operations on the output-stream associ -

          Import interface tcp-create-socket

          +

          Import interface wasi:sockets/tcp-create-socket


          Types

          type network

          @@ -1498,7 +1498,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

          Import interface ip-name-lookup

          +

          Import interface wasi:sockets/ip-name-lookup


          Types

          type pollable

          From d256388b802c6e312b6ced3b81797d60d8194c8b Mon Sep 17 00:00:00 2001 From: "Jiaxiao Zhou (Mossaka)" Date: Mon, 29 May 2023 05:55:13 -0700 Subject: [PATCH 1150/1772] Update to the newest WITs Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/http/wit/deps.lock | 30 ++++++------ proposals/http/wit/deps.toml | 1 + proposals/http/wit/deps/cli/command.wit | 48 ++++++++++--------- .../wit/deps/cli/environment-preopens.wit | 7 --- proposals/http/wit/deps/cli/environment.wit | 2 +- proposals/http/wit/deps/cli/exit.wit | 2 +- proposals/http/wit/deps/cli/preopens.wit | 11 +++++ proposals/http/wit/deps/cli/run.wit | 2 +- proposals/http/wit/deps/cli/stdio.wit | 6 +-- proposals/http/wit/deps/cli/terminal.wit | 6 +-- .../http/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/http/wit/deps/clocks/timezone.wit | 4 +- proposals/http/wit/deps/clocks/wall-clock.wit | 2 +- proposals/http/wit/deps/clocks/world.wit | 10 ++-- proposals/http/wit/deps/filesystem/types.wit | 14 +++--- proposals/http/wit/deps/filesystem/world.wit | 5 ++ proposals/http/wit/deps/io/streams.wit | 4 +- proposals/http/wit/deps/io/world.wit | 6 ++- proposals/http/wit/deps/poll/poll.wit | 2 +- proposals/http/wit/deps/poll/world.wit | 6 ++- .../http/wit/deps/random/insecure-seed.wit | 2 +- proposals/http/wit/deps/random/insecure.wit | 2 +- proposals/http/wit/deps/random/random.wit | 2 +- proposals/http/wit/deps/random/world.wit | 10 ++-- .../wit/deps/sockets/instance-network.wit | 4 +- .../http/wit/deps/sockets/ip-name-lookup.wit | 6 +-- proposals/http/wit/deps/sockets/network.wit | 2 +- .../wit/deps/sockets/tcp-create-socket.wit | 6 +-- proposals/http/wit/deps/sockets/tcp.wit | 16 ++++--- .../wit/deps/sockets/udp-create-socket.wit | 6 +-- proposals/http/wit/deps/sockets/udp.wit | 6 +-- proposals/http/wit/deps/sockets/world.wit | 17 +++---- proposals/http/wit/incoming-handler.wit | 4 +- proposals/http/wit/outgoing-handler.wit | 4 +- proposals/http/wit/proxy.wit | 22 +++++---- proposals/http/wit/types.wit | 6 +-- 36 files changed, 157 insertions(+), 130 deletions(-) delete mode 100644 proposals/http/wit/deps/cli/environment-preopens.wit create mode 100644 proposals/http/wit/deps/cli/preopens.wit create mode 100644 proposals/http/wit/deps/filesystem/world.wit diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 6e178b0fe..13b4b247e 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,34 +1,34 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -sha256 = "4ee7653b8d712808a129b8dedb24f8af09fe13c177c08fb017ba1726c0756147" -sha512 = "a7b43ab7dd1765ff6fc676ebd1fb28d1f24f20870deb1743485409ede90cdb7843358d6bfd3fcc0684d92d7bacc7dbf8c56f48156bae1c429e23e9c0a1567652" -deps = ["filesystem"] +sha256 = "ce53bedad0aa34bbcde6ffd8f98348e03fa170e191aaf6bb6ca57b4915ade435" +sha512 = "489ed4e04603df4763e75d4d2d056cf363922c4865052348993febfd2c9bd10ab864fb4b72090df58dcb60d5676148a7a1e7de3a8513073afd37b4d9027ca7e7" [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "3fb1c6a5541b6288fe9b22210b610b89ebd97a4318bdc174fe256f5635b1c0ad" -sha512 = "e89cbfd4988f4299d1a9c7da484362df22e29550ee2d559cf82e20e0925e581f0df420818c6bae984df54e336b8eb747fc5171ddeccfe91ca25f48566a258ff6" +sha256 = "1ed7e35b3f9738663854f0dd92a95bfadc410ea07170501f5c2fec0cc24e3d57" +sha512 = "ef1e23704a8a8436fd3718593d4c4d8b6d1c64dad3595b7496c0888ca14b725046f2900109800faca1bc8c14f237cdcaca791dba8284e1ad50105ab2d036825b" [filesystem] -sha256 = "4c92964370d25209f1efb8273360070fce0901834c992bdfb32310587a00dfd7" -sha512 = "0152b5f5b1ab667fa422735b6296bbd5be699b5c526159ae43b7465b8ac69cf0cda8b6ca8773c352718de6d9a1b485a08be6f995b3ce3a8bf729fce5dcb4daac" +url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" +sha256 = "a19dbd57208ef649980bb4088b96606fe3549e580574dc88dafed6f8a8537b01" +sha512 = "49a798126feeb1a714162a20d282e554c70d36cbfa827dfb54685577b13d584fa15e02fd653fbb940a4fa52cece6c0ca4d7cd85f27c041a5cc99a98392d03e50" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "7450142aeb3f1688ee2b12853344e262caf6aee0718dc0296316f7f6b3afd91f" -sha512 = "5cc0f60d190e16d6dd52a4ca2fc862f007465e7642e98061b41c90778e1f2b00aeb2543b6fadbb6a137dd548d86e9e55edcfb30388adcc6a160b4cdc29d378ec" +sha256 = "eeb4701c2becafa40a7ee3bf0d2c94e2170e15806b25abdcd1de1ed94f2c1036" +sha512 = "89be853b2acae211570cd6ad0ec9d8132881dafbdea83ac7b4cad600f0627003c61f310427379bf47ecf862724367bd5d6e976db70069f6f90a3c2d9c20dbfb7" [poll] url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -sha256 = "065422b0ea6ccb2a9facc6b87b902eef110c53d76fc31f341a6bc8d0b0285b6a" -sha512 = "19a55cd3072a19ae6a1774723a4962e7a155a5ce89a27175e8c76020efb4d00bc92ebb78427d92bcb8effd4f0d03ebf0a0daa747ecd981b8d31d5abc2ad86423" +sha256 = "9f8bb4d9994e9b0684859bb1e8bee2a8b873e04d40695f260446760fc44d0c58" +sha512 = "aa8da395ba6e189ec113296996da5abf28bdc4460e4eb2aacc786698ced892e08f7054fb590fc8809c05554d5c83a11494d4ab68c755746f57d151e212415cfb" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "29ae189cd5b3fc4d16b955bd7c7bb158a75e8329363ea5ae141a32bee743ab19" -sha512 = "884d7c7dd167a93217166309d9e3e8befce9cff359cf8ff989b046dbaf15bb765b43c7746ceabdf64ea595873a588e4a6d1a3533f94732ab613e7ed3ee11a119" +sha256 = "30731531ec3453813d08765b428f34aec34ac343cbeafd9885e4e348d187ae04" +sha512 = "6656089f9297ee56cf58c2f95c466e3a22c371925404e6eb9cb5adcb37c1b92f27aaf8c2f9e690ac53ef12f90bd31ac64a84d5f5e06d3f06e24997478275327f" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "2a6158a0d7d6ac4d912f272c108d19b741a44566639191defaf8838e232417db" -sha512 = "d2ae6f7b9e1a33c1f3ca840f5a8f1c0f757c139569cee62027def2bbe43350795461e2fd6bae09ada1c6c94237eb03da65330169762121b036dad8cd430ba462" +sha256 = "30c07587eda24676185f175323d5195817b5678815a3f6b64b8152a5b7532493" +sha512 = "8965e112c323e4535786361d864d3b5020791ce7e48da20a6a6b9a1fbec1f78bc10e0830c640f704bd8132fada56cd8a19b48e11e60ec6d9191c08e00550c91c" diff --git a/proposals/http/wit/deps.toml b/proposals/http/wit/deps.toml index 582faf4cf..5062efa50 100644 --- a/proposals/http/wit/deps.toml +++ b/proposals/http/wit/deps.toml @@ -3,6 +3,7 @@ cli = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" +filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" # not used by http/proxy, but included to allow full contents of wasi-cli to validate sockets = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit index e92bb6023..13675f180 100644 --- a/proposals/http/wit/deps/cli/command.wit +++ b/proposals/http/wit/deps/cli/command.wit @@ -1,23 +1,27 @@ -default world command { - import wall-clock: clocks.wall-clock - import monotonic-clock: clocks.monotonic-clock - import timezone: clocks.timezone - import filesystem: filesystem.types - import instance-network: sockets.instance-network - import ip-name-lookup: sockets.ip-name-lookup - import network: sockets.network - import tcp-create-socket: sockets.tcp-create-socket - import tcp: sockets.tcp - import udp-create-socket: sockets.udp-create-socket - import udp: sockets.udp - import random: random.random - import poll: poll.poll - import streams: io.streams - import environment: pkg.environment - import environment-preopens: pkg.environment-preopens - import exit: pkg.exit - import stdin: pkg.stdio.stdin - import stdout: pkg.stdio.stdout - import stderr: pkg.stdio.stderr - export run: pkg.run +package wasi:cli + +world command { + import wasi:clocks/wall-clock + import wasi:clocks/monotonic-clock + import wasi:clocks/timezone + import wasi:filesystem/types + import wasi:sockets/instance-network + import wasi:sockets/ip-name-lookup + import wasi:sockets/network + import wasi:sockets/tcp-create-socket + import wasi:sockets/tcp + import wasi:sockets/udp-create-socket + import wasi:sockets/udp + import wasi:random/random + import wasi:random/insecure + import wasi:random/insecure-seed + import wasi:poll/poll + import wasi:io/streams + import environment + import preopens + import exit + import stdin + import stdout + import stderr + export run } diff --git a/proposals/http/wit/deps/cli/environment-preopens.wit b/proposals/http/wit/deps/cli/environment-preopens.wit deleted file mode 100644 index e7ab89d75..000000000 --- a/proposals/http/wit/deps/cli/environment-preopens.wit +++ /dev/null @@ -1,7 +0,0 @@ -default interface environment-preopens { - use filesystem.types.{descriptor} - use io.streams.{input-stream, output-stream} - - /// Return the set of of preopened directories, and their path. - get-directories: func() -> list> -} diff --git a/proposals/http/wit/deps/cli/environment.wit b/proposals/http/wit/deps/cli/environment.wit index 876ea3a0c..65471e86d 100644 --- a/proposals/http/wit/deps/cli/environment.wit +++ b/proposals/http/wit/deps/cli/environment.wit @@ -1,4 +1,4 @@ -default interface environment { +interface environment { /// Get the POSIX-style environment variables. /// /// Each environment variable is provided as a pair of string variable names diff --git a/proposals/http/wit/deps/cli/exit.wit b/proposals/http/wit/deps/cli/exit.wit index 2759e9dd9..66835aa70 100644 --- a/proposals/http/wit/deps/cli/exit.wit +++ b/proposals/http/wit/deps/cli/exit.wit @@ -1,4 +1,4 @@ -default interface wasi-exit { +interface exit { /// Exit the curerent instance and any linked instances. exit: func(status: result) } diff --git a/proposals/http/wit/deps/cli/preopens.wit b/proposals/http/wit/deps/cli/preopens.wit new file mode 100644 index 000000000..637102878 --- /dev/null +++ b/proposals/http/wit/deps/cli/preopens.wit @@ -0,0 +1,11 @@ +interface preopens { + use wasi:filesystem/types.{descriptor} + use wasi:io/streams.{input-stream, output-stream} + + /// Return the set of of preopened directories, and their path. + get-directories: func() -> list> + + /// Return a path that programs should use as their initial current working + /// directory, interpreting `.` as shorthand for this. + initial-cwd: func() -> option +} diff --git a/proposals/http/wit/deps/cli/run.wit b/proposals/http/wit/deps/cli/run.wit index 2132e98e7..45a1ca533 100644 --- a/proposals/http/wit/deps/cli/run.wit +++ b/proposals/http/wit/deps/cli/run.wit @@ -1,4 +1,4 @@ -default interface run { +interface run { /// Run the program. run: func() -> result } diff --git a/proposals/http/wit/deps/cli/stdio.wit b/proposals/http/wit/deps/cli/stdio.wit index 1f87e5485..6c9d4a41a 100644 --- a/proposals/http/wit/deps/cli/stdio.wit +++ b/proposals/http/wit/deps/cli/stdio.wit @@ -1,17 +1,17 @@ interface stdin { - use io.streams.{input-stream} + use wasi:io/streams.{input-stream} get-stdin: func() -> input-stream } interface stdout { - use io.streams.{output-stream} + use wasi:io/streams.{output-stream} get-stdout: func() -> output-stream } interface stderr { - use io.streams.{output-stream} + use wasi:io/streams.{output-stream} get-stderr: func() -> output-stream } diff --git a/proposals/http/wit/deps/cli/terminal.wit b/proposals/http/wit/deps/cli/terminal.wit index 988068af7..f32e74437 100644 --- a/proposals/http/wit/deps/cli/terminal.wit +++ b/proposals/http/wit/deps/cli/terminal.wit @@ -31,7 +31,7 @@ interface terminal-output { /// An interface providing an optional `terminal-input` for stdin as a /// link-time authority. interface terminal-stdin { - use self.terminal-input.{terminal-input} + use terminal-input.{terminal-input} /// If stdin is connected to a terminal, return a `terminal-input` handle /// allowing further interaction with it. @@ -41,7 +41,7 @@ interface terminal-stdin { /// An interface providing an optional `terminal-output` for stdout as a /// link-time authority. interface terminal-stdout { - use self.terminal-output.{terminal-output} + use terminal-output.{terminal-output} /// If stdout is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. @@ -51,7 +51,7 @@ interface terminal-stdout { /// An interface providing an optional `terminal-output` for stderr as a /// link-time authority. interface terminal-stderr { - use self.terminal-output.{terminal-output} + use terminal-output.{terminal-output} /// If stderr is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index 42e2981f5..fb8424eb0 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -8,8 +8,8 @@ /// successive reads of the clock will produce non-decreasing values. /// /// It is intended for measuring elapsed time. -default interface monotonic-clock { - use poll.poll.{pollable} +interface monotonic-clock { + use wasi:poll/poll.{pollable} /// A timestamp in nanoseconds. type instant = u64 diff --git a/proposals/http/wit/deps/clocks/timezone.wit b/proposals/http/wit/deps/clocks/timezone.wit index 63f99cc40..662830871 100644 --- a/proposals/http/wit/deps/clocks/timezone.wit +++ b/proposals/http/wit/deps/clocks/timezone.wit @@ -1,5 +1,5 @@ -default interface timezone { - use pkg.wall-clock.{datetime} +interface timezone { + use wall-clock.{datetime} /// A timezone. /// diff --git a/proposals/http/wit/deps/clocks/wall-clock.wit b/proposals/http/wit/deps/clocks/wall-clock.wit index 89c5a75da..dae44a730 100644 --- a/proposals/http/wit/deps/clocks/wall-clock.wit +++ b/proposals/http/wit/deps/clocks/wall-clock.wit @@ -12,7 +12,7 @@ /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -default interface wall-clock { +interface wall-clock { /// A time and date in seconds plus nanoseconds. record datetime { seconds: u64, diff --git a/proposals/http/wit/deps/clocks/world.wit b/proposals/http/wit/deps/clocks/world.wit index 8e3da6cc0..291a9c75e 100644 --- a/proposals/http/wit/deps/clocks/world.wit +++ b/proposals/http/wit/deps/clocks/world.wit @@ -1,5 +1,7 @@ -default world example-world { - import monotonic-clock: pkg.monotonic-clock - import wall-clock: pkg.wall-clock - import timezone: pkg.timezone +package wasi:clocks + +world example-world { + import monotonic-clock + import wall-clock + import timezone } diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index c04f989bb..627b638ef 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -17,9 +17,9 @@ /// `..` and symbolic link steps, reaches a directory outside of the base /// directory, or reaches a symlink to an absolute or rooted path in the /// underlying filesystem, the function fails with `error-code::not-permitted`. -default interface types { - use io.streams.{input-stream, output-stream} - use clocks.wall-clock.{datetime} +interface types { + use wasi:io/streams.{input-stream, output-stream} + use wasi:clocks/wall-clock.{datetime} /// File size or length of a region within a file. type filesize = u64 @@ -146,9 +146,9 @@ default interface types { /// True if the resource is considered readable by the containing /// filesystem. readable, - /// True if the resource is considered writeable by the containing + /// True if the resource is considered writable by the containing /// filesystem. - writeable, + writable, /// True if the resource is considered executable by the containing /// filesystem. This does not apply to directories. executable, @@ -615,7 +615,7 @@ default interface types { /// Check accessibility of a filesystem path. /// /// Check whether the given filesystem path names an object which is - /// readable, writeable, or executable, or whether it exists. + /// readable, writable, or executable, or whether it exists. /// /// This does not a guarantee that subsequent accesses will succeed, as /// filesystem permissions may be modified asynchronously by external @@ -629,7 +629,7 @@ default interface types { /// The relative path to check. path: string, /// The type of check to perform. - %ype: access-type + %type: access-type ) -> result<_, error-code> /// Unlink a filesystem object that is not a directory. diff --git a/proposals/http/wit/deps/filesystem/world.wit b/proposals/http/wit/deps/filesystem/world.wit new file mode 100644 index 000000000..f2ef782f4 --- /dev/null +++ b/proposals/http/wit/deps/filesystem/world.wit @@ -0,0 +1,5 @@ +package wasi:filesystem + +world example-world { + import types +} diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index c1567fd4c..430c1d441 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -3,8 +3,8 @@ /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. -default interface streams { - use poll.poll.{pollable} +interface streams { + use wasi:poll/poll.{pollable} /// An error type returned from a stream operation. Currently this /// doesn't provide any additional information. diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit index bae7c92b3..b7f625334 100644 --- a/proposals/http/wit/deps/io/world.wit +++ b/proposals/http/wit/deps/io/world.wit @@ -1,3 +1,5 @@ -default world example-world { - import streams: pkg.streams +package wasi:io + +world example-world { + import streams } diff --git a/proposals/http/wit/deps/poll/poll.wit b/proposals/http/wit/deps/poll/poll.wit index 28f08e17d..55eee0029 100644 --- a/proposals/http/wit/deps/poll/poll.wit +++ b/proposals/http/wit/deps/poll/poll.wit @@ -1,6 +1,6 @@ /// A poll API intended to let users wait for I/O events on multiple handles /// at once. -default interface poll { +interface poll { /// A "pollable" handle. /// /// This is conceptually represents a `stream<_, _>`, or in other words, diff --git a/proposals/http/wit/deps/poll/world.wit b/proposals/http/wit/deps/poll/world.wit index 3a002e070..d08cadc05 100644 --- a/proposals/http/wit/deps/poll/world.wit +++ b/proposals/http/wit/deps/poll/world.wit @@ -1,3 +1,5 @@ -default world example-world { - import poll: pkg.poll +package wasi:poll + +world example-world { + import poll } diff --git a/proposals/http/wit/deps/random/insecure-seed.wit b/proposals/http/wit/deps/random/insecure-seed.wit index 93a2f17d4..ff2ff65d0 100644 --- a/proposals/http/wit/deps/random/insecure-seed.wit +++ b/proposals/http/wit/deps/random/insecure-seed.wit @@ -2,7 +2,7 @@ /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -default interface insecure-seed { +interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// /// The returned value is not required to be computed from a CSPRNG, and may diff --git a/proposals/http/wit/deps/random/insecure.wit b/proposals/http/wit/deps/random/insecure.wit index 1ef020a09..ff0826822 100644 --- a/proposals/http/wit/deps/random/insecure.wit +++ b/proposals/http/wit/deps/random/insecure.wit @@ -2,7 +2,7 @@ /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -default interface insecure { +interface insecure { /// Return `len` insecure pseudo-random bytes. /// /// This function is not cryptographically secure. Do not use it for diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index 8f7585788..e4238621e 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -2,7 +2,7 @@ /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -default interface random { +interface random { /// Return `len` cryptographically-secure pseudo-random bytes. /// /// This function must produce data from an adequately seeded diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit index b109e0b91..3c3d16554 100644 --- a/proposals/http/wit/deps/random/world.wit +++ b/proposals/http/wit/deps/random/world.wit @@ -1,5 +1,7 @@ -default world example-world { - import random: pkg.random - import insecure: pkg.insecure - import insecure-seed: pkg.insecure-seed +package wasi:random + +world example-world { + import random + import insecure + import insecure-seed } diff --git a/proposals/http/wit/deps/sockets/instance-network.wit b/proposals/http/wit/deps/sockets/instance-network.wit index b1f5c982d..d911a29cc 100644 --- a/proposals/http/wit/deps/sockets/instance-network.wit +++ b/proposals/http/wit/deps/sockets/instance-network.wit @@ -1,7 +1,7 @@ /// This interface provides a value-export of the default network handle.. -default interface instance-network { - use pkg.network.{network} +interface instance-network { + use network.{network} /// Get a handle to the default network. instance-network: func() -> network diff --git a/proposals/http/wit/deps/sockets/ip-name-lookup.wit b/proposals/http/wit/deps/sockets/ip-name-lookup.wit index c4cc72684..f15d19d03 100644 --- a/proposals/http/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ -default interface ip-name-lookup { - use poll.poll.{pollable} - use pkg.network.{network, error-code, ip-address, ip-address-family} +interface ip-name-lookup { + use wasi:poll/poll.{pollable} + use network.{network, error-code, ip-address, ip-address-family} /// Resolve an internet host name to a list of IP addresses. diff --git a/proposals/http/wit/deps/sockets/network.wit b/proposals/http/wit/deps/sockets/network.wit index 9176e6ba6..2d09bcbdc 100644 --- a/proposals/http/wit/deps/sockets/network.wit +++ b/proposals/http/wit/deps/sockets/network.wit @@ -1,5 +1,5 @@ -default interface network { +interface network { /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. diff --git a/proposals/http/wit/deps/sockets/tcp-create-socket.wit b/proposals/http/wit/deps/sockets/tcp-create-socket.wit index 6e948fae0..f43bc8979 100644 --- a/proposals/http/wit/deps/sockets/tcp-create-socket.wit +++ b/proposals/http/wit/deps/sockets/tcp-create-socket.wit @@ -1,7 +1,7 @@ -default interface tcp-create-socket { - use pkg.network.{network, error-code, ip-address-family} - use pkg.tcp.{tcp-socket} +interface tcp-create-socket { + use network.{network, error-code, ip-address-family} + use tcp.{tcp-socket} /// Create a new TCP socket. /// diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index b87153243..4edb1db7f 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -1,8 +1,8 @@ -default interface tcp { - use io.streams.{input-stream, output-stream} - use poll.poll.{pollable} - use pkg.network.{network, error-code, ip-socket-address, ip-address-family} +interface tcp { + use wasi:io/streams.{input-stream, output-stream} + use wasi:poll/poll.{pollable} + use network.{network, error-code, ip-socket-address, ip-address-family} /// A TCP socket handle. type tcp-socket = u32 @@ -87,10 +87,12 @@ default interface tcp { /// /// Transitions the socket into the Listener state. /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// Unlike POSIX: + /// - this function is async. This enables interactive WASI hosts to inject permission prompts. + /// - the socket must already be explicitly bound. /// /// # Typical `start` errors - /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `listen` must be identical to the one passed to `bind`. + /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) /// - `already-listening`: The socket is already in the Listener state. /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) @@ -105,7 +107,7 @@ default interface tcp { /// - /// - /// - - start-listen: func(this: tcp-socket, network: network) -> result<_, error-code> + start-listen: func(this: tcp-socket) -> result<_, error-code> finish-listen: func(this: tcp-socket) -> result<_, error-code> /// Accept a new client socket. diff --git a/proposals/http/wit/deps/sockets/udp-create-socket.wit b/proposals/http/wit/deps/sockets/udp-create-socket.wit index 2c987be08..cd4c08fb1 100644 --- a/proposals/http/wit/deps/sockets/udp-create-socket.wit +++ b/proposals/http/wit/deps/sockets/udp-create-socket.wit @@ -1,7 +1,7 @@ -default interface udp-create-socket { - use pkg.network.{network, error-code, ip-address-family} - use pkg.udp.{udp-socket} +interface udp-create-socket { + use network.{network, error-code, ip-address-family} + use udp.{udp-socket} /// Create a new UDP socket. /// diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index 271a2cb9f..3a0c1bd14 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ -default interface udp { - use poll.poll.{pollable} - use pkg.network.{network, error-code, ip-socket-address, ip-address-family} +interface udp { + use wasi:poll/poll.{pollable} + use network.{network, error-code, ip-socket-address, ip-address-family} /// A UDP socket handle. diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit index 854fac0ba..ca23d8698 100644 --- a/proposals/http/wit/deps/sockets/world.wit +++ b/proposals/http/wit/deps/sockets/world.wit @@ -1,10 +1,11 @@ +package wasi:sockets -default world example-world { - import instance-network: pkg.instance-network - import network: pkg.network - import udp: pkg.udp - import udp-create-socket: pkg.udp-create-socket - import tcp: pkg.tcp - import tcp-create-socket: pkg.tcp-create-socket - import ip-name-lookup: pkg.ip-name-lookup +world example-world { + import instance-network + import network + import udp + import udp-create-socket + import tcp + import tcp-create-socket + import ip-name-lookup } diff --git a/proposals/http/wit/incoming-handler.wit b/proposals/http/wit/incoming-handler.wit index 3b1c29aae..f98429fed 100644 --- a/proposals/http/wit/incoming-handler.wit +++ b/proposals/http/wit/incoming-handler.wit @@ -6,8 +6,8 @@ // `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface // that takes a `request` parameter and returns a `response` result. // -default interface incoming-handler { - use pkg.types.{incoming-request, response-outparam} +interface incoming-handler { + use types.{incoming-request, response-outparam} // The `handle` function takes an outparam instead of returning its response // so that the component may stream its response while streaming any other diff --git a/proposals/http/wit/outgoing-handler.wit b/proposals/http/wit/outgoing-handler.wit index abe812ffa..06c8e469f 100644 --- a/proposals/http/wit/outgoing-handler.wit +++ b/proposals/http/wit/outgoing-handler.wit @@ -5,8 +5,8 @@ // `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface // that takes a `request` parameter and returns a `response` result. // -default interface outgoing-handler { - use pkg.types.{outgoing-request, request-options, future-incoming-response} +interface outgoing-handler { + use types.{outgoing-request, request-options, future-incoming-response} // The parameter and result types of the `handle` function allow the caller // to concurrently stream the bodies of the outgoing request and the incoming diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 724884537..162ab32b2 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,32 +1,34 @@ +package wasi:http + // The `wasi:http/proxy` world captures a widely-implementable intersection of // hosts that includes HTTP forward and reverse proxies. Components targeting // this world may concurrently stream in and out any number of incoming and // outgoing HTTP requests. -default world proxy { +world proxy { // HTTP proxies have access to time and randomness. - import wall-clock: clocks.wall-clock - import monotonic-clock: clocks.monotonic-clock - import timezone: clocks.timezone - import random: random.random + import wasi:clocks/wall-clock + import wasi:clocks/monotonic-clock + import wasi:clocks/timezone + import wasi:random/random // Proxies have standard output and error streams which are expected to // terminate in a developer-facing console provided by the host. - import stdout: cli.stdio.stdout - import stderr: cli.stdio.stderr + import wasi:cli/stdout + import wasi:cli/stderr // TODO: this is a temporary workaround until component tooling is able to // gracefully handle the absence of stdin. Hosts must return an eof stream // for this import, which is what wasi-libc + tooling will do automatically // when this import is properly removed. - import stdin: cli.stdio.stdin + import wasi:cli/stdin // This is the default handler to use when user code simply wants to make an // HTTP request (e.g., via `fetch()`). - import default-outgoing-HTTP: pkg.outgoing-handler + import outgoing-handler // The host delivers incoming HTTP requests to a component by calling the // `handle` function of this exported interface. A host may arbitrarily reuse // or not reuse component instance when delivering incoming HTTP requests and // thus a component must be able to handle 0..N calls to `handle`. - export HTTP: pkg.incoming-handler + export incoming-handler } diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 3a41a11d9..a4df4f899 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -1,9 +1,9 @@ // The `wasi:http/types` interface is meant to be imported by components to // define the HTTP resource types and operations used by the component's // imported and exported interfaces. -default interface types { - use io.streams.{input-stream, output-stream} - use poll.poll.{pollable} +interface types { + use wasi:io/streams.{input-stream, output-stream} + use wasi:poll/poll.{pollable} // This type corresponds to HTTP standard Methods. variant method { From c8412728e85ac0a542672f0041d0cc230e0c5687 Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Tue, 30 May 2023 12:39:25 -0700 Subject: [PATCH 1151/1772] Update wit/deps.toml Co-authored-by: Luke Wagner --- proposals/http/wit/deps.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/http/wit/deps.toml b/proposals/http/wit/deps.toml index 5062efa50..11f43c153 100644 --- a/proposals/http/wit/deps.toml +++ b/proposals/http/wit/deps.toml @@ -3,7 +3,6 @@ cli = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" - # not used by http/proxy, but included to allow full contents of wasi-cli to validate +filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" sockets = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" From 68f9256b8980e5a541aec79e37700c551c2413c1 Mon Sep 17 00:00:00 2001 From: "Jiaxiao Zhou (Mossaka)" Date: Tue, 30 May 2023 12:47:17 -0700 Subject: [PATCH 1152/1772] Add wit-deps.toml Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/sockets/wit/deps.lock | 9 +++++++++ proposals/sockets/wit/deps.toml | 2 ++ 2 files changed, 11 insertions(+) create mode 100644 proposals/sockets/wit/deps.lock create mode 100644 proposals/sockets/wit/deps.toml diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock new file mode 100644 index 000000000..3f5f5aced --- /dev/null +++ b/proposals/sockets/wit/deps.lock @@ -0,0 +1,9 @@ +[io] +url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +sha256 = "eeb4701c2becafa40a7ee3bf0d2c94e2170e15806b25abdcd1de1ed94f2c1036" +sha512 = "89be853b2acae211570cd6ad0ec9d8132881dafbdea83ac7b4cad600f0627003c61f310427379bf47ecf862724367bd5d6e976db70069f6f90a3c2d9c20dbfb7" + +[poll] +url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" +sha256 = "9f8bb4d9994e9b0684859bb1e8bee2a8b873e04d40695f260446760fc44d0c58" +sha512 = "aa8da395ba6e189ec113296996da5abf28bdc4460e4eb2aacc786698ced892e08f7054fb590fc8809c05554d5c83a11494d4ab68c755746f57d151e212415cfb" diff --git a/proposals/sockets/wit/deps.toml b/proposals/sockets/wit/deps.toml new file mode 100644 index 000000000..2616e30df --- /dev/null +++ b/proposals/sockets/wit/deps.toml @@ -0,0 +1,2 @@ +io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" From 8900891c399d522b44c6fc5e5599510d4ef5de6f Mon Sep 17 00:00:00 2001 From: "Jiaxiao Zhou (Mossaka)" Date: Tue, 30 May 2023 14:40:33 -0700 Subject: [PATCH 1153/1772] add wit-deps to CI check Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/sockets/.github/workflows/main.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index ad1997c51..cb083f2a8 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -11,6 +11,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - name: ensure `./wit/deps` are in sync + run: | + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.0/wit-deps-x86_64-unknown-linux-musl + chmod +x wit-deps + ./wit-deps lock + git add -N wit/deps + git diff --exit-code - uses: WebAssembly/wit-abi-up-to-date@v12 with: wit-abi-tag: wit-abi-0.10.0 From 09f8f8887737806056a3d8b3ef0e280d894fa387 Mon Sep 17 00:00:00 2001 From: "Jiaxiao Zhou (Mossaka)" Date: Tue, 30 May 2023 14:42:31 -0700 Subject: [PATCH 1154/1772] Add CI check to veirfy deps are up-to-date Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/http/.github/workflows/main.yml | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 proposals/http/.github/workflows/main.yml diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml new file mode 100644 index 000000000..9c5dc6c1f --- /dev/null +++ b/proposals/http/.github/workflows/main.yml @@ -0,0 +1,26 @@ +name: CI +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + abi-up-to-date: + name: Check ABI files are up-to-date + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: ensure `./wit/deps` are in sync + run: | + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.0/wit-deps-x86_64-unknown-linux-musl + chmod +x wit-deps + ./wit-deps lock + git add -N wit/deps + git diff --exit-code + + # wit-abi needs to be updated in order to verify the newest wit package syntax + + # - uses: WebAssembly/wit-abi-up-to-date@v6 + # with: + # wit-abi-tag: wit-abi-0.6.0 From 13215185ec82a7e58e05ed3a7652b2d7fc55c622 Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Thu, 1 Jun 2023 06:05:42 -0700 Subject: [PATCH 1155/1772] Add wit-deps.toml (#44) * Add wit-deps.toml Signed-off-by: Jiaxiao Zhou (Mossaka) * add wit-deps to CI check Signed-off-by: Jiaxiao Zhou (Mossaka) --------- Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/clocks/.github/workflows/main.yml | 7 +++++++ proposals/clocks/wit/deps.lock | 4 ++++ proposals/clocks/wit/deps.toml | 1 + 3 files changed, 12 insertions(+) create mode 100644 proposals/clocks/wit/deps.lock create mode 100644 proposals/clocks/wit/deps.toml diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index ad1997c51..cb083f2a8 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -11,6 +11,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - name: ensure `./wit/deps` are in sync + run: | + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.0/wit-deps-x86_64-unknown-linux-musl + chmod +x wit-deps + ./wit-deps lock + git add -N wit/deps + git diff --exit-code - uses: WebAssembly/wit-abi-up-to-date@v12 with: wit-abi-tag: wit-abi-0.10.0 diff --git a/proposals/clocks/wit/deps.lock b/proposals/clocks/wit/deps.lock new file mode 100644 index 000000000..9d2f1d0c2 --- /dev/null +++ b/proposals/clocks/wit/deps.lock @@ -0,0 +1,4 @@ +[poll] +url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" +sha256 = "9f8bb4d9994e9b0684859bb1e8bee2a8b873e04d40695f260446760fc44d0c58" +sha512 = "aa8da395ba6e189ec113296996da5abf28bdc4460e4eb2aacc786698ced892e08f7054fb590fc8809c05554d5c83a11494d4ab68c755746f57d151e212415cfb" diff --git a/proposals/clocks/wit/deps.toml b/proposals/clocks/wit/deps.toml new file mode 100644 index 000000000..cefc393fa --- /dev/null +++ b/proposals/clocks/wit/deps.toml @@ -0,0 +1 @@ +poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" From 58b30513aae6282b4e384b99deb8a729715ec55d Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Thu, 1 Jun 2023 06:05:59 -0700 Subject: [PATCH 1156/1772] Add wit-deps.toml (#119) * Add wit-deps.toml Signed-off-by: Jiaxiao Zhou (Mossaka) * add wit-deps to CI check Signed-off-by: Jiaxiao Zhou (Mossaka) --------- Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/filesystem/.github/workflows/main.yml | 7 +++++++ proposals/filesystem/wit/deps.lock | 14 ++++++++++++++ proposals/filesystem/wit/deps.toml | 3 +++ 3 files changed, 24 insertions(+) create mode 100644 proposals/filesystem/wit/deps.lock create mode 100644 proposals/filesystem/wit/deps.toml diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index ad1997c51..cb083f2a8 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -11,6 +11,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - name: ensure `./wit/deps` are in sync + run: | + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.0/wit-deps-x86_64-unknown-linux-musl + chmod +x wit-deps + ./wit-deps lock + git add -N wit/deps + git diff --exit-code - uses: WebAssembly/wit-abi-up-to-date@v12 with: wit-abi-tag: wit-abi-0.10.0 diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock new file mode 100644 index 000000000..cf11adc18 --- /dev/null +++ b/proposals/filesystem/wit/deps.lock @@ -0,0 +1,14 @@ +[clocks] +url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" +sha256 = "1ed7e35b3f9738663854f0dd92a95bfadc410ea07170501f5c2fec0cc24e3d57" +sha512 = "ef1e23704a8a8436fd3718593d4c4d8b6d1c64dad3595b7496c0888ca14b725046f2900109800faca1bc8c14f237cdcaca791dba8284e1ad50105ab2d036825b" + +[io] +url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +sha256 = "eeb4701c2becafa40a7ee3bf0d2c94e2170e15806b25abdcd1de1ed94f2c1036" +sha512 = "89be853b2acae211570cd6ad0ec9d8132881dafbdea83ac7b4cad600f0627003c61f310427379bf47ecf862724367bd5d6e976db70069f6f90a3c2d9c20dbfb7" + +[poll] +url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" +sha256 = "9f8bb4d9994e9b0684859bb1e8bee2a8b873e04d40695f260446760fc44d0c58" +sha512 = "aa8da395ba6e189ec113296996da5abf28bdc4460e4eb2aacc786698ced892e08f7054fb590fc8809c05554d5c83a11494d4ab68c755746f57d151e212415cfb" diff --git a/proposals/filesystem/wit/deps.toml b/proposals/filesystem/wit/deps.toml new file mode 100644 index 000000000..4e40837d5 --- /dev/null +++ b/proposals/filesystem/wit/deps.toml @@ -0,0 +1,3 @@ +io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" +clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" \ No newline at end of file From ddd132b6fd0c91c503c8a7bb73a1bbaf169958cf Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Thu, 1 Jun 2023 06:23:49 -0700 Subject: [PATCH 1157/1772] Add wit-deps.toml (#33) * Add wit-deps.toml Signed-off-by: Jiaxiao Zhou (Mossaka) * add wit-deps to CI check Signed-off-by: Jiaxiao Zhou (Mossaka) --------- Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/io/.github/workflows/main.yml | 7 +++++++ proposals/io/wit/deps.lock | 4 ++++ proposals/io/wit/deps.toml | 1 + 3 files changed, 12 insertions(+) create mode 100644 proposals/io/wit/deps.lock create mode 100644 proposals/io/wit/deps.toml diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index ad1997c51..cb083f2a8 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -11,6 +11,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - name: ensure `./wit/deps` are in sync + run: | + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.0/wit-deps-x86_64-unknown-linux-musl + chmod +x wit-deps + ./wit-deps lock + git add -N wit/deps + git diff --exit-code - uses: WebAssembly/wit-abi-up-to-date@v12 with: wit-abi-tag: wit-abi-0.10.0 diff --git a/proposals/io/wit/deps.lock b/proposals/io/wit/deps.lock new file mode 100644 index 000000000..9d2f1d0c2 --- /dev/null +++ b/proposals/io/wit/deps.lock @@ -0,0 +1,4 @@ +[poll] +url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" +sha256 = "9f8bb4d9994e9b0684859bb1e8bee2a8b873e04d40695f260446760fc44d0c58" +sha512 = "aa8da395ba6e189ec113296996da5abf28bdc4460e4eb2aacc786698ced892e08f7054fb590fc8809c05554d5c83a11494d4ab68c755746f57d151e212415cfb" diff --git a/proposals/io/wit/deps.toml b/proposals/io/wit/deps.toml new file mode 100644 index 000000000..cefc393fa --- /dev/null +++ b/proposals/io/wit/deps.toml @@ -0,0 +1 @@ +poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" From 55d4bfe1ea0c643d6745a5af073bca3d5ff449b5 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 1 Jun 2023 06:33:32 -0700 Subject: [PATCH 1158/1772] Document that random must be "at least" as good as a CSPRNG. (#30) Document that the random API doesn't necessarily need to be a CSPRNG; it need only be at least as good as a CSPRNG in both security and performance. This theoretically allows hardware random devices to be used directly, provided they're able to produce cryptographically-secure data with sufficient performance. Fixes #28. --- proposals/random/example-world.md | 24 +++++++++++++----------- proposals/random/wit/random.wit | 24 +++++++++++++----------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/proposals/random/example-world.md b/proposals/random/example-world.md index 53aa0a16f..47ce4002d 100644 --- a/proposals/random/example-world.md +++ b/proposals/random/example-world.md @@ -15,14 +15,16 @@ Windows.


          Functions

          get-random-bytes: func

          -

          Return len cryptographically-secure pseudo-random bytes.

          -

          This function must produce data from an adequately seeded -cryptographically-secure pseudo-random number generator (CSPRNG), so it -must not block, from the perspective of the calling program, and the -returned data is always unpredictable.

          -

          This function must always return fresh pseudo-random data. Deterministic -environments must omit this function, rather than implementing it with -deterministic data.

          +

          Return len cryptographically-secure random or pseudo-random bytes.

          +

          This function must produce data at least as cryptographically secure and +fast as an adequately seeded cryptographically-secure pseudo-random +number generator (CSPRNG). It must not block, from the perspective of +the calling program, under any circumstances, including on the first +request and on requests for numbers of bytes. The returned data must +always be unpredictable.

          +

          This function must always return fresh data. Deterministic environments +must omit this function, rather than implementing it with deterministic +data.

          Params
          • len: u64
          • @@ -32,9 +34,9 @@ deterministic data.

          • list<u8>

          get-random-u64: func

          -

          Return a cryptographically-secure pseudo-random u64 value.

          -

          This function returns the same type of pseudo-random data as -get-random-bytes, represented as a u64.

          +

          Return a cryptographically-secure random or pseudo-random u64 value.

          +

          This function returns the same type of data as get-random-bytes, +represented as a u64.

          Return values
          • u64
          • diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index e4238621e..2a282dab7 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -3,21 +3,23 @@ /// It is intended to be portable at least between Unix-family platforms and /// Windows. interface random { - /// Return `len` cryptographically-secure pseudo-random bytes. + /// Return `len` cryptographically-secure random or pseudo-random bytes. /// - /// This function must produce data from an adequately seeded - /// cryptographically-secure pseudo-random number generator (CSPRNG), so it - /// must not block, from the perspective of the calling program, and the - /// returned data is always unpredictable. + /// This function must produce data at least as cryptographically secure and + /// fast as an adequately seeded cryptographically-secure pseudo-random + /// number generator (CSPRNG). It must not block, from the perspective of + /// the calling program, under any circumstances, including on the first + /// request and on requests for numbers of bytes. The returned data must + /// always be unpredictable. /// - /// This function must always return fresh pseudo-random data. Deterministic - /// environments must omit this function, rather than implementing it with - /// deterministic data. + /// This function must always return fresh data. Deterministic environments + /// must omit this function, rather than implementing it with deterministic + /// data. get-random-bytes: func(len: u64) -> list - /// Return a cryptographically-secure pseudo-random `u64` value. + /// Return a cryptographically-secure random or pseudo-random `u64` value. /// - /// This function returns the same type of pseudo-random data as - /// `get-random-bytes`, represented as a `u64`. + /// This function returns the same type of data as `get-random-bytes`, + /// represented as a `u64`. get-random-u64: func() -> u64 } From 23096f5c1685da455d9a97d5b1b15524007871fc Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Thu, 1 Jun 2023 06:34:17 -0700 Subject: [PATCH 1159/1772] Add wit-deps.toml (#15) * Add wit-deps.toml Signed-off-by: Jiaxiao Zhou (Mossaka) * add wit-deps to CI check Signed-off-by: Jiaxiao Zhou (Mossaka) --------- Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/cli/.github/workflows/main.yml | 7 ++++++ proposals/cli/wit/deps.lock | 29 ++++++++++++++++++++++++ proposals/cli/wit/deps.toml | 6 +++++ 3 files changed, 42 insertions(+) create mode 100644 proposals/cli/wit/deps.lock create mode 100644 proposals/cli/wit/deps.toml diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml index ad1997c51..cb083f2a8 100644 --- a/proposals/cli/.github/workflows/main.yml +++ b/proposals/cli/.github/workflows/main.yml @@ -11,6 +11,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - name: ensure `./wit/deps` are in sync + run: | + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.0/wit-deps-x86_64-unknown-linux-musl + chmod +x wit-deps + ./wit-deps lock + git add -N wit/deps + git diff --exit-code - uses: WebAssembly/wit-abi-up-to-date@v12 with: wit-abi-tag: wit-abi-0.10.0 diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock new file mode 100644 index 000000000..25030d173 --- /dev/null +++ b/proposals/cli/wit/deps.lock @@ -0,0 +1,29 @@ +[clocks] +url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" +sha256 = "1ed7e35b3f9738663854f0dd92a95bfadc410ea07170501f5c2fec0cc24e3d57" +sha512 = "ef1e23704a8a8436fd3718593d4c4d8b6d1c64dad3595b7496c0888ca14b725046f2900109800faca1bc8c14f237cdcaca791dba8284e1ad50105ab2d036825b" + +[filesystem] +url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" +sha256 = "a19dbd57208ef649980bb4088b96606fe3549e580574dc88dafed6f8a8537b01" +sha512 = "49a798126feeb1a714162a20d282e554c70d36cbfa827dfb54685577b13d584fa15e02fd653fbb940a4fa52cece6c0ca4d7cd85f27c041a5cc99a98392d03e50" + +[io] +url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +sha256 = "eeb4701c2becafa40a7ee3bf0d2c94e2170e15806b25abdcd1de1ed94f2c1036" +sha512 = "89be853b2acae211570cd6ad0ec9d8132881dafbdea83ac7b4cad600f0627003c61f310427379bf47ecf862724367bd5d6e976db70069f6f90a3c2d9c20dbfb7" + +[poll] +url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" +sha256 = "9f8bb4d9994e9b0684859bb1e8bee2a8b873e04d40695f260446760fc44d0c58" +sha512 = "aa8da395ba6e189ec113296996da5abf28bdc4460e4eb2aacc786698ced892e08f7054fb590fc8809c05554d5c83a11494d4ab68c755746f57d151e212415cfb" + +[random] +url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" +sha256 = "30731531ec3453813d08765b428f34aec34ac343cbeafd9885e4e348d187ae04" +sha512 = "6656089f9297ee56cf58c2f95c466e3a22c371925404e6eb9cb5adcb37c1b92f27aaf8c2f9e690ac53ef12f90bd31ac64a84d5f5e06d3f06e24997478275327f" + +[sockets] +url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" +sha256 = "30c07587eda24676185f175323d5195817b5678815a3f6b64b8152a5b7532493" +sha512 = "8965e112c323e4535786361d864d3b5020791ce7e48da20a6a6b9a1fbec1f78bc10e0830c640f704bd8132fada56cd8a19b48e11e60ec6d9191c08e00550c91c" diff --git a/proposals/cli/wit/deps.toml b/proposals/cli/wit/deps.toml new file mode 100644 index 000000000..351e8c3b2 --- /dev/null +++ b/proposals/cli/wit/deps.toml @@ -0,0 +1,6 @@ +io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" +random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" +clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" +filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" +sockets = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" \ No newline at end of file From 01325e719c6da153430452579db5a7f94794a33e Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 2 Jun 2023 16:19:14 +0200 Subject: [PATCH 1160/1772] build: update `wit-deps` Signed-off-by: Roman Volosatovs --- proposals/http/.github/workflows/main.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index 9c5dc6c1f..517752b7a 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -13,11 +13,9 @@ jobs: - uses: actions/checkout@v2 - name: ensure `./wit/deps` are in sync run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.0/wit-deps-x86_64-unknown-linux-musl - chmod +x wit-deps - ./wit-deps lock - git add -N wit/deps - git diff --exit-code + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.2/wit-deps-x86_64-unknown-linux-musl + chmod +x ./wit-deps + ./wit-deps lock --check # wit-abi needs to be updated in order to verify the newest wit package syntax From 7d6f5236d3f49801fa6e9de706391936f519afd5 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 2 Jun 2023 21:23:29 +0200 Subject: [PATCH 1161/1772] ci: update `wit-deps` (#34) Signed-off-by: Roman Volosatovs --- proposals/io/.github/workflows/main.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index cb083f2a8..45c41ec1e 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -13,11 +13,9 @@ jobs: - uses: actions/checkout@v2 - name: ensure `./wit/deps` are in sync run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.0/wit-deps-x86_64-unknown-linux-musl + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.2/wit-deps-x86_64-unknown-linux-musl chmod +x wit-deps - ./wit-deps lock - git add -N wit/deps - git diff --exit-code + ./wit-deps lock --check - uses: WebAssembly/wit-abi-up-to-date@v12 with: wit-abi-tag: wit-abi-0.10.0 From f7b26e47f5ce4a3d3ad3d04ecc713df85ab9ff93 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Sat, 10 Jun 2023 07:05:42 -0700 Subject: [PATCH 1162/1772] Update wit-abi to 0.11.0 (#122) * CI: update wit-abi check * generate example-world.md with wit-abi 0.11.0 --- proposals/filesystem/.github/workflows/main.yml | 4 ++-- proposals/filesystem/example-world.md | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index cb083f2a8..3cba299bc 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -18,6 +18,6 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v12 + - uses: WebAssembly/wit-abi-up-to-date@v13 with: - wit-abi-tag: wit-abi-0.10.0 + wit-abi-tag: wit-abi-0.11.0 diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md index 5c3eb642b..8cd610233 100644 --- a/proposals/filesystem/example-world.md +++ b/proposals/filesystem/example-world.md @@ -2,14 +2,14 @@ -

            Import interface poll

            +

            Import interface wasi:poll/poll

            A poll API intended to let users wait for I/O events on multiple handles at once.


            @@ -56,7 +56,7 @@ mean "ready".

            • list<u8>
            -

            Import interface streams

            +

            Import interface wasi:io/streams

            WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

            In the future, the component model is expected to add built-in stream types; @@ -308,7 +308,7 @@ be used.

            -

            Import interface wall-clock

            +

            Import interface wasi:clocks/wall-clock

            WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

            @@ -349,7 +349,7 @@ also known as Unix Time.
          • datetime
          -

          Import interface types

          +

          Import interface wasi:filesystem/types

          WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

          From b6aa244759320fbe6cbefc5f8b6df858effc2b39 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Sat, 10 Jun 2023 07:37:45 -0700 Subject: [PATCH 1163/1772] Update wit-abi to 0.11.0 (#35) * CI: latest wit-abi check * generate example-world.md with wit-abi 0.11.0 --- proposals/io/.github/workflows/main.yml | 4 ++-- proposals/io/example-world.md | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index 45c41ec1e..cc3bf6573 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -16,6 +16,6 @@ jobs: curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.2/wit-deps-x86_64-unknown-linux-musl chmod +x wit-deps ./wit-deps lock --check - - uses: WebAssembly/wit-abi-up-to-date@v12 + - uses: WebAssembly/wit-abi-up-to-date@v13 with: - wit-abi-tag: wit-abi-0.10.0 + wit-abi-tag: wit-abi-0.11.0 diff --git a/proposals/io/example-world.md b/proposals/io/example-world.md index 4f1e3b4f0..5033a563b 100644 --- a/proposals/io/example-world.md +++ b/proposals/io/example-world.md @@ -2,12 +2,12 @@ -

          Import interface poll

          +

          Import interface wasi:poll/poll

          A poll API intended to let users wait for I/O events on multiple handles at once.


          @@ -54,7 +54,7 @@ mean "ready".

          • list<u8>
          -

          Import interface streams

          +

          Import interface wasi:io/streams

          WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

          In the future, the component model is expected to add built-in stream types; From c47767578630fd64fc9120b7e833d1a1209cc712 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 10 Jun 2023 07:42:50 -0700 Subject: [PATCH 1164/1772] Update wit-abi to 0.11.0 (#32) --- proposals/random/.github/workflows/main.yml | 2 +- proposals/random/example-world.md | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index ad1997c51..861e81c22 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -13,4 +13,4 @@ jobs: - uses: actions/checkout@v2 - uses: WebAssembly/wit-abi-up-to-date@v12 with: - wit-abi-tag: wit-abi-0.10.0 + wit-abi-tag: wit-abi-0.11.0 diff --git a/proposals/random/example-world.md b/proposals/random/example-world.md index 47ce4002d..fc15a04a4 100644 --- a/proposals/random/example-world.md +++ b/proposals/random/example-world.md @@ -2,13 +2,13 @@

          -

          Import interface random

          +

          Import interface wasi:random/random

          WASI Random is a random data API.

          It is intended to be portable at least between Unix-family platforms and Windows.

          @@ -41,7 +41,7 @@ represented as a u64.

          • u64
          -

          Import interface insecure

          +

          Import interface wasi:random/insecure

          The insecure interface for insecure pseudo-random numbers.

          It is intended to be portable at least between Unix-family platforms and Windows.

          @@ -70,7 +70,7 @@ a long period.

          • u64
          -

          Import interface insecure-seed

          +

          Import interface wasi:random/insecure-seed

          The insecure-seed interface for seeding hash-map DoS resistance.

          It is intended to be portable at least between Unix-family platforms and Windows.

          From 1013286e178df364ec20f0f7090c8001e0b8d49e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 10 Jun 2023 07:53:53 -0700 Subject: [PATCH 1165/1772] Update wit-abi to 0.11.0 (#45) --- proposals/clocks/.github/workflows/main.yml | 4 ++-- proposals/clocks/example-world.md | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index cb083f2a8..3cba299bc 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -18,6 +18,6 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v12 + - uses: WebAssembly/wit-abi-up-to-date@v13 with: - wit-abi-tag: wit-abi-0.10.0 + wit-abi-tag: wit-abi-0.11.0 diff --git a/proposals/clocks/example-world.md b/proposals/clocks/example-world.md index a33878b4a..4587ddd6e 100644 --- a/proposals/clocks/example-world.md +++ b/proposals/clocks/example-world.md @@ -2,14 +2,14 @@ -

          Import interface poll

          +

          Import interface wasi:poll/poll

          A poll API intended to let users wait for I/O events on multiple handles at once.


          @@ -56,7 +56,7 @@ mean "ready".

          • list<u8>
          -

          Import interface monotonic-clock

          +

          Import interface wasi:clocks/monotonic-clock

          WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

          It is intended to be portable at least between Unix-family platforms and @@ -100,7 +100,7 @@ reached.

          -

          Import interface wall-clock

          +

          Import interface wasi:clocks/wall-clock

          WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

          @@ -141,7 +141,7 @@ also known as Unix Time.
        • datetime
        -

        Import interface timezone

        +

        Import interface wasi:clocks/timezone


        Types

        type datetime

        From 587adcbd0f4d71241da4d78238f6bf1a85fca1fb Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 10 Jun 2023 07:54:57 -0700 Subject: [PATCH 1166/1772] Update to wit-abi 0.11.0. (#16) --- proposals/cli/.github/workflows/main.yml | 4 +- proposals/cli/command.md | 103 ++++++++++++----------- 2 files changed, 55 insertions(+), 52 deletions(-) diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml index cb083f2a8..3cba299bc 100644 --- a/proposals/cli/.github/workflows/main.yml +++ b/proposals/cli/.github/workflows/main.yml @@ -18,6 +18,6 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v12 + - uses: WebAssembly/wit-abi-up-to-date@v13 with: - wit-abi-tag: wit-abi-0.10.0 + wit-abi-tag: wit-abi-0.11.0 diff --git a/proposals/cli/command.md b/proposals/cli/command.md index cdd7b8b95..646c04917 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -2,37 +2,37 @@ -

        Import interface wall-clock

        +

        Import interface wasi:clocks/wall-clock

        WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

        @@ -73,7 +73,7 @@ also known as Unix Time.
      • datetime
      -

      Import interface poll

      +

      Import interface wasi:poll/poll

      A poll API intended to let users wait for I/O events on multiple handles at once.


      @@ -120,7 +120,7 @@ mean "ready".

      • list<u8>
      -

      Import interface monotonic-clock

      +

      Import interface wasi:clocks/monotonic-clock

      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

      It is intended to be portable at least between Unix-family platforms and @@ -164,7 +164,7 @@ reached.

      -

      Import interface timezone

      +

      Import interface wasi:clocks/timezone


      Types

      type datetime

      @@ -245,7 +245,7 @@ be used.

      -

      Import interface streams

      +

      Import interface wasi:io/streams

      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

      In the future, the component model is expected to add built-in stream types; @@ -497,7 +497,7 @@ be used.

      -

      Import interface filesystem

      +

      Import interface wasi:filesystem/types

      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

      @@ -945,7 +945,7 @@ to the specified data. from lower offsets to higher offsets.
    • -

      random

      +

      random

      The application expects to access the specified data in a random order.

    • @@ -1531,7 +1531,7 @@ be used.

      -

      Import interface network

      +

      Import interface wasi:sockets/network


      Types

      type network

      @@ -1756,7 +1756,7 @@ combined with a couple of errors that are always possible:

      -

      Import interface instance-network

      +

      Import interface wasi:sockets/instance-network

      This interface provides a value-export of the default network handle..


      Types

      @@ -1771,7 +1771,7 @@ combined with a couple of errors that are always possible:

      -

      Import interface ip-name-lookup

      +

      Import interface wasi:sockets/ip-name-lookup


      Types

      type pollable

      @@ -1877,7 +1877,7 @@ It's planned to be removed when future is natively supported in Pre -

      Import interface tcp

      +

      Import interface wasi:sockets/tcp


      Types

      type input-stream

      @@ -2026,10 +2026,14 @@ implicitly bind the socket.

      start-listen: func

      Start listening for new connections.

      Transitions the socket into the Listener state.

      -

      Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

      +

      Unlike POSIX:

      +
        +
      • this function is async. This enables interactive WASI hosts to inject permission prompts.
      • +
      • the socket must already be explicitly bound.
      • +

      Typical start errors

      @@ -1383,3 +1384,17 @@ be used.

      +

      Import interface wasi:filesystem/preopens

      +
      +

      Types

      +

      type descriptor

      +

      descriptor

      +

      +---- +

      Functions

      +

      get-directories: func

      +

      Return the set of preopened directories, and their path.

      +
      Return values
      + diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit new file mode 100644 index 000000000..f45661b8a --- /dev/null +++ b/proposals/filesystem/wit/preopens.wit @@ -0,0 +1,6 @@ +interface preopens { + use types.{descriptor} + + /// Return the set of preopened directories, and their path. + get-directories: func() -> list> +} diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index f2ef782f4..b51f484f8 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -2,4 +2,5 @@ package wasi:filesystem world example-world { import types + import preopens } From cf8c3a7aed275bc5f826b830a2e60f54cf2f7e80 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 7 Jun 2023 15:34:48 -0700 Subject: [PATCH 1170/1772] make {read,write,append}-via-stream fallible stream creation is an appropriate place to return an error-code indicating the file cannot be read, written, or appended to. --- proposals/filesystem/example-world.md | 15 +++++++++------ proposals/filesystem/wit/types.wit | 18 ++++++++++++------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md index 8cd610233..3e44c98bf 100644 --- a/proposals/filesystem/example-world.md +++ b/proposals/filesystem/example-world.md @@ -833,7 +833,8 @@ not reuse it thereafter.

      Functions

      read-via-stream: func

      -

      Return a stream for reading from a file.

      +

      Return a stream for reading from a file, if available.

      +

      May fail with an error-code describing why the file cannot be read.

      Multiple read, write, and append streams may be active on the same open file and they do not interfere with each other.

      Note: This allows using read-stream, which is similar to read in POSIX.

      @@ -844,10 +845,11 @@ file and they do not interfere with each other.

    Return values

    write-via-stream: func

    -

    Return a stream for writing to a file.

    +

    Return a stream for writing to a file, if available.

    +

    May fail with an error-code describing why the file cannot be written.

    Note: This allows using write-stream, which is similar to write in POSIX.

    Params
    @@ -857,10 +859,11 @@ POSIX.

    Return values

    append-via-stream: func

    -

    Return a stream for appending to a file.

    +

    Return a stream for appending to a file, if available.

    +

    May fail with an error-code describing why the file cannot be appended.

    Note: This allows using write-stream, which is similar to write with O_APPEND in in POSIX.

    Params
    @@ -869,7 +872,7 @@ POSIX.

    Return values

    advise: func

    Provide file advisory information on a descriptor.

    diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 627b638ef..0f7d96e18 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -312,7 +312,9 @@ interface types { /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). type descriptor = u32 - /// Return a stream for reading from a file. + /// Return a stream for reading from a file, if available. + /// + /// May fail with an error-code describing why the file cannot be read. /// /// Multiple read, write, and append streams may be active on the same open /// file and they do not interfere with each other. @@ -322,9 +324,11 @@ interface types { this: descriptor, /// The offset within the file at which to start reading. offset: filesize, - ) -> input-stream + ) -> result - /// Return a stream for writing to a file. + /// Return a stream for writing to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be written. /// /// Note: This allows using `write-stream`, which is similar to `write` in /// POSIX. @@ -332,15 +336,17 @@ interface types { this: descriptor, /// The offset within the file at which to start writing. offset: filesize, - ) -> output-stream + ) -> result - /// Return a stream for appending to a file. + /// Return a stream for appending to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be appended. /// /// Note: This allows using `write-stream`, which is similar to `write` with /// `O_APPEND` in in POSIX. append-via-stream: func( this: descriptor, - ) -> output-stream + ) -> result /// Provide file advisory information on a descriptor. /// From c49c189493a38ee306d284b2444fa2a875ca432e Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 12 Jun 2023 12:45:49 -0500 Subject: [PATCH 1171/1772] Make reading and writing trailers properly async Resolves #37 --- proposals/http/wit/types.wit | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index a4df4f899..278f27ca9 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -59,11 +59,30 @@ interface types { // build on separate resource types defined by `wasi:io/streams`. The // `finish-` functions emulate the stream's result value and MUST be called // exactly once after the final read/write from/to the stream before dropping - // the stream. + // the stream. The optional `future-` types describe the asynchronous result of + // reading/writing the optional HTTP trailers and MUST be waited on and dropped + // to complete streaming the request/response. type incoming-stream = input-stream type outgoing-stream = output-stream - finish-incoming-stream: func(s: incoming-stream) -> option - finish-outgoing-stream: func(s: outgoing-stream, trailers: option) + finish-incoming-stream: func(s: incoming-stream) -> option + finish-outgoing-stream: func(s: outgoing-stream) + finish-outgoing-stream-with-trailers: func(s: outgoing-stream, trailers: trailers) -> future-write-trailers-result + + // The following block defines the `future-trailers` resource, which is + // returned when finishing an `incoming-stream` to asychronously produce the + // final trailers. + type future-trailers = u32 + drop-future-trailers: func(f: future-trailers) + future-trailers-get: func(f: future-trailers) -> option> + listen-to-future-trailers: func(f: future-trailers) -> pollable + + // The following block defines the `future-write-trailers-result` resource, + // which is returned when finishing an `outgoing-stream` and asychronously + // indicates the success or failure of writing the trailers. + type future-write-trailers-result = u32 + drop-future-write-trailers-result: func(f: future-write-trailers-result) + future-write-trailers-result-get: func(f: future-write-trailers-result) -> option> + listen-to-future-write-trailers-result: func(f: future-write-trailers-result) -> pollable // The following block defines the `incoming-request` and `outgoing-request` // resource types that correspond to HTTP standard Requests. Soon, when From a1d7fbbd83ab69c3242d477c045aacecd50854e0 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 12 Jun 2023 12:52:19 -0500 Subject: [PATCH 1172/1772] Sync new-fields with fields-get by taking a list --- proposals/http/wit/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index a4df4f899..6a4b3b27a 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -42,7 +42,7 @@ interface types { // definition containing all the functions using the method syntactic sugar. type fields = u32 drop-fields: func(fields: fields) - new-fields: func(entries: list>) -> fields + new-fields: func(entries: list>>) -> fields fields-get: func(fields: fields, name: string) -> list> fields-set: func(fields: fields, name: string, value: list>) fields-delete: func(fields: fields, name: string) From 3da929c1b47a1447ae5f0a591f1b06ec0ed9d2e9 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 12 Jun 2023 16:31:00 -0500 Subject: [PATCH 1173/1772] Update proxy.md to match wit changes --- proposals/http/proxy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 7709c5a24..cd650d6db 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -650,7 +650,7 @@ be used.

    new-fields: func

    Params
    Return values
      From 2238bec04e94e98f15ad3c9492e69fb37aca2133 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 12 Jun 2023 16:31:27 -0500 Subject: [PATCH 1174/1772] Update proxy.md to match wit changes --- proposals/http/proxy.md | 65 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 7709c5a24..c4076cb66 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -620,6 +620,12 @@ be used.

      #### `type incoming-request` `u32`

      +#### `type future-write-trailers-result` +`u32` +

      +#### `type future-trailers` +`u32` +

      #### `type future-incoming-response` `u32`

      @@ -711,13 +717,68 @@ be used.

    Return values

    finish-outgoing-stream: func

    Params
    +

    finish-outgoing-stream-with-trailers: func

    +
    Params
    + +
    Return values
    + +

    drop-future-trailers: func

    +
    Params
    + +

    future-trailers-get: func

    +
    Params
    + +
    Return values
    + +

    listen-to-future-trailers: func

    +
    Params
    + +
    Return values
    + +

    drop-future-write-trailers-result: func

    +
    Params
    + +

    future-write-trailers-result-get: func

    +
    Params
    + +
    Return values
    +
      +
    • option<result<_, error>>
    • +
    +

    listen-to-future-write-trailers-result: func

    +
    Params
    + +
    Return values
    +

    drop-incoming-request: func

    Params
    From 9525808534d6792d01e9cbb9b8a22241fc0b85a7 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 12 Jun 2023 16:56:34 -0500 Subject: [PATCH 1175/1772] Add comment regarding header/trailer sharing Resolves #38 --- proposals/http/wit/types.wit | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index a4df4f899..1116d1b6c 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -67,12 +67,15 @@ interface types { // The following block defines the `incoming-request` and `outgoing-request` // resource types that correspond to HTTP standard Requests. Soon, when - // resource types are added, the `u32` type aliases can be replaced by - // proper `resource` type definitions containing all the functions as - // methods. Later, Preview2 will allow both types to be merged together into - // a single `request` type (that uses the single `stream` type mentioned - // above). The `consume` and `write` methods may only be called once (and - // return failure thereafter). + // resource types are added, the `u32` type aliases can be replaced by proper + // `resource` type definitions containing all the functions as methods. + // Later, Preview2 will allow both types to be merged together into a single + // `request` type (that uses the single `stream` type mentioned above). The + // `consume` and `write` methods may only be called once (and return failure + // thereafter). The `headers` and `trailers` passed into and out of requests + // are shared with the request, with all mutations visible to all uses. + // Components MUST avoid updating `headers` and `trailers` after passing a + // request that points to them to the outside world. type incoming-request = u32 type outgoing-request = u32 drop-incoming-request: func(request: incoming-request) @@ -128,6 +131,10 @@ interface types { // Preview2 will allow both types to be merged together into a single `response` // type (that uses the single `stream` type mentioned above). The `consume` and // `write` methods may only be called once (and return failure thereafter). + // The `headers` and `trailers` passed into and out of responses are shared + // with the response, with all mutations visible to all uses. Components MUST + // avoid updating `headers` and `trailers` after passing a response that + // points to them to the outside world. type incoming-response = u32 type outgoing-response = u32 drop-incoming-response: func(response: incoming-response) From 5317e1e7e2952c9bc4a29f1caf85fd39066c4307 Mon Sep 17 00:00:00 2001 From: Matheus Cardoso Date: Tue, 13 Jun 2023 18:50:18 -0300 Subject: [PATCH 1176/1772] fix typo in exit comment --- proposals/cli/wit/exit.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/cli/wit/exit.wit b/proposals/cli/wit/exit.wit index 66835aa70..4831d5078 100644 --- a/proposals/cli/wit/exit.wit +++ b/proposals/cli/wit/exit.wit @@ -1,4 +1,4 @@ interface exit { - /// Exit the curerent instance and any linked instances. + /// Exit the current instance and any linked instances. exit: func(status: result) } From 96b6ca1bb75fa7719a8973723220736fafdeb2f1 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Tue, 20 Jun 2023 14:07:56 -0500 Subject: [PATCH 1177/1772] Make new request/response functions fallible Resolves #44 --- proposals/http/wit/types.wit | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 1aaf04d23..7bb3a1eaa 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -111,7 +111,7 @@ interface types { scheme: option, authority: option, headers: headers - ) -> outgoing-request + ) -> result outgoing-request-write: func(request: outgoing-request) -> result // Additional optional parameters that can be set when making a request. @@ -164,7 +164,7 @@ interface types { new-outgoing-response: func( status-code: status-code, headers: headers - ) -> outgoing-response + ) -> result outgoing-response-write: func(response: outgoing-response) -> result // The following block defines a special resource type used by the From c78304998ea2a10476840b3e0231e714d332747e Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Tue, 20 Jun 2023 14:12:28 -0500 Subject: [PATCH 1178/1772] Update proxy.md to match wit changes --- proposals/http/proxy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index c3b19dd4a..c27334200 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -855,7 +855,7 @@ be used.

    Return values

    outgoing-request-write: func

    Params
    @@ -926,7 +926,7 @@ be used.

    Return values

    outgoing-response-write: func

    Params
    From e466d0a28ec72992f4e80aa9d1558398789a58de Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Mon, 26 Jun 2023 21:30:41 +0200 Subject: [PATCH 1179/1772] Document POSIX compatibility. --- proposals/sockets/Posix-compatibility.md | 586 +++++++++++++++++++++++ proposals/sockets/README.md | 32 +- 2 files changed, 587 insertions(+), 31 deletions(-) create mode 100644 proposals/sockets/Posix-compatibility.md diff --git a/proposals/sockets/Posix-compatibility.md b/proposals/sockets/Posix-compatibility.md new file mode 100644 index 000000000..8cd15d988 --- /dev/null +++ b/proposals/sockets/Posix-compatibility.md @@ -0,0 +1,586 @@ +# POSIX Compatibility + +This document provides an overview of the POSIX interface along with common non-standard extensions and their mapping to functionalities provided by this proposal. + + +## General + +### I/O completion polling (`poll`, `select`, `pselect`, `epoll_*` (non-standard), `kqueue` (non-standard)) +Use [`tcp::subscribe`](tcp)/[`udp::subscribe`](udp) to obtain a `pollable` handle. Then use that to wait for IO events using the [wasi-poll](poll) interface. + +### Non-blocking mode (`FIONBIO`, `SOCK_NONBLOCK`, `O_NONBLOCK`) +All WASI sockets are non-blocking and can not be configured to block. +Blocking behaviour can be recreated in userland (or in wasi-libc) by repeatedly calling [`poll::poll-oneoff`](poll) until the operation is complete. + +### TCP urgent data (`sockatmark`, `MSG_OOB`, `SO_OOBINLINE`, `SIOCATMARK`) +Out-of-band (OOB) data is currently not included in this proposal. Application-level usage of the TCP "urgent" flag is rare in practice and discouraged in general. Including it in WASI would probably interfere with the ability to use WASI/ComponentModel `stream`s. + +### Peeking (`MSG_PEEK`) +Peeking support is not provided by this proposal directly. Including it in WASI would probably interfere with the ability to use WASI/ComponentModel `stream`s. + +Support for it might be able to be recreated in userland (or in wasi-libc). + +### Writing to closed streams (`SIGPIPE`, `SO_NOSIGPIPE`) +WASI has no concept of 'signals'. Implementations that require it are encouraged to set the `SO_NOSIGPIPE` option to `true`, to increase cross-platform consistency. +Writing to a closed stream in WASI returns a regular error. + +### Close-on-exec (`FD_CLOEXEC`, `SOCK_CLOEXEC`, `O_CLOEXEC`) +Not included in proposal. WASI has no concept of UNIX-style processes. + + +## Functions + +### `socket` +- TCP: [`create-tcp-socket`](tcp-create-socket) +- UDP: [`create-udp-socket`](udp-create-socket) + +### `connect` +- TCP: [`tcp::start-connect`](tcp) & [`tcp::finish-connect`](tcp) +- UDP: [`udp::start-connect`](udp) & [`udp::finish-connect`](udp) + +### `bind` +- TCP: [`tcp::start-bind`](tcp) & [`tcp::finish-bind`](tcp) +- UDP: [`udp::start-bind`](udp) & [`udp::finish-bind`](udp) + +### `listen` +- TCP: [`tcp::start-listen`](tcp) & [`tcp::finish-listen`](tcp). The `backlog` parameter has been split out into a distinct function [`tcp::set-listen-backlog-size`](tcp) ([See #34](https://github.com/WebAssembly/wasi-sockets/issues/34)). +- UDP: N/A + +### `accept`, `accept4` (non-standard) +- TCP: [`tcp::accept`](tcp) +- UDP: N/A + +To collect the remote address, call [`tcp::remote-address`](tcp) on the newly accepted client socket. + +Some platforms provide an `accept4` variant with additional flags. None of these flags make sense in the context of this proposal. See [SOCK_NONBLOCK](#nonblock) & [SOCK_CLOEXEC](#cloexec). + +### `getsockname`, `getpeername` +- TCP: [`tcp::local-address`](tcp) & [`tcp::remote-address`](tcp) +- UDP: [`udp::local-address`](udp) & [`udp::remote-address`](udp) + +### `read`, `readv`, `recv`, `recvfrom`, `recvmsg`, `recvmmsg` (non-standard) + +TCP sockets can be read using [`streams::(blocking-)read`](streams). UDP sockets can be read using [`udp::receive`](udp). + +The various POSIX functions should be implementable on top of these two functions. + +None of the flags are directly present in WASI Sockets: +- `MSG_DONTWAIT`: This is [always the case](#nonblock). +- `MSG_OOB` (TCP): [Not supported](#oob) +- `MSG_OOB` (UDP): N/A +- `MSG_PEEK`: [No direct support](#peek) +- `MSG_TRUNC` (TCP): N/A +- `MSG_TRUNC` (UDP): Not needed, the returned data array always has the exact perfect size. +- `MSG_WAITALL` (TCP): Emulatable in userspace. +- `MSG_WAITALL` (UDP): N/A +- `MSG_EOR`: N/A (not supported on TCP & UDP sockets) +- `MSG_CMSG_CLOEXEC`: N/A (only used on Unix domain sockets) + +### `write`, `writev`, `send`, `sendto`, `sendmsg`, `sendmmsg` (non-standard) + +TCP sockets can be written to using [`streams::(blocking-)write`](streams). UDP sockets can be written to using [`udp::send`](udp). + +The various POSIX functions should be implementable on top of these two functions. + +None of the flags are directly present in WASI Sockets: +- `MSG_DONTROUTE`: Not included in proposal at the moment. +- `MSG_DONTWAIT`: This is [always the case](#nonblock). +- `MSG_NOSIGNAL`: This is [always the case](#sigpipe). +- `MSG_OOB` (TCP): [Not supported](#oob) +- `MSG_OOB` (UDP): N/A +- `MSG_EOR`: N/A (not supported on TCP & UDP sockets) + + +### `sendfile` (non-standard) +- TCP: Part of the WASI Streams proposal as [`output-stream::forward`](streams) +- UDP: N/A + +### `shutdown` +- TCP: [`tcp::shutdown`](tcp) +- UDP: N/A + +### `sockatmark` +- TCP: Not supported, see [OOB](#oob). +- UDP: N/A + +### `close` +- TCP: [`tcp::drop-tcp-socket`](tcp) +- UDP: [`udp::drop-udp-socket`](udp) + +### `socketpair`, `connectat` (non-standard), `bindat` (non-standard) +Specifically for UNIX domain sockets. Out of scope for this proposal. + +### `fcntl` +- `F_GETFL`/`F_SETFL` > `O_NONBLOCK`: [Not needed](#nonblock). +- `F_SETFD`/`F_GETFD` > `FD_CLOEXEC`: [Not included](#cloexec). + +### `ioctl` +- `SIOCATMARK`: [Not included](#oob). +- `FIONREAD`: Currently not included. See [#17](https://github.com/WebAssembly/wasi-sockets/issues/17). + +### `getsockopt`, `setsockopt` +Socket options have been split out into distinct functions. See table below. + + + + +## Socket options + +POSIX defines the signatures of the `getsockopt` & `setsockopt` functions, but does not provide much guidance on the individual socket options themselves. +Because of this lack of a central authority, a list has been compiled of the options that are used "in the wild". + +The results are not intended to be an exhaustive overview of all possible network applications, but rather to provide input on which options are worth standardizing in WASI. + +Additionally, most columns have been populated semi-automatically by grepping through the respective codebases. The results have not been manually verified and therefore may not be 100% correct. + +Columns: +- "Socket option": The native option constant. +- "WASI": + - ✅ = Included in proposal. + - ⛔ = Consciously decided _not_ to include in WASI. See notes for explanation. + - ❔ = Not included (yet), for no particular reason. +- The rest: + - ✅ = Option is provided by the platform / depended upon by the application. + - ❌ = Option is not provided / not used. + + +| Option | WASI | POSIX | Linux | Windows | MacOS | FreeBSD | JVM | .NET | Rust | Node.js | Go | OpenSSL | nginx | curl | msquic | exim | Notes | +|---------------------------------|-----------|--------|--------|---------|---------|---------|-------|--------|-------|---------|-----|----------|-------|-------|--------|-------|-| +| SO_ERROR | ⛔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | Not necessary. WIT has (or will have) native support for asynchronous results. | +| SO_DOMAIN | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | [`tcp::address-family`](tcp)
    [`udp::address-family`](udp)

    SO_PROTOCOL_INFO on Windows. | +| SO_TYPE | ✅* | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | * indirectly through the type of the socket resource. | +| SO_PROTOCOL | ✅* | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | * indirectly through the type of the socket resource. SO_PROTOCOL_INFO on Windows. | +| SO_ACCEPTCONN | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_V6ONLY | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | [`tcp::(set-)ipv6-only`](tcp)
    [`udp::(set-)ipv6-only`](udp) | +| IP_HDRINCL | ⛔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Out of scope. Raw sockets only. | +| IPV6_HDRINCL | ⛔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Out of scope. Raw sockets only. | +| IP_TTL | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | [`tcp::(set-)unicast-hop-limit`](tcp)
    [`udp::(set-)unicast-hop-limit`](udp) | +| IPV6_UNICAST_HOPS | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | [`tcp::(set-)unicast-hop-limit`](tcp)
    [`udp::(set-)unicast-hop-limit`](udp) | +| IP_RECVTTL | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RECVHOPLIMIT | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_TOS | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | +| IPV6_TCLASS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | +| IP_RECVTOS | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | +| IPV6_RECVTCLASS | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | +| IP_RECVPKTINFO | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | IP_PKTINFO on Linux & Windows, IP_RECVDSTADDR+IP_RECVIF on MacOS & FreeBSD. | +| IPV6_RECVPKTINFO | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | IPV6_PKTINFO on Windows. | +| IP_DONTFRAG | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | IP_DONTFRAGMENT on Windows, implementable using IP_MTU_DISCOVER on Linux. | +| IPV6_DONTFRAG | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | | +| IP_MTU_DISCOVER | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | | +| IPV6_MTU_DISCOVER | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | | +| SO_RCVBUF | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | [`tcp::(set-)receive-buffer-size`](tcp)
    [`udp::(set-)receive-buffer-size`](udp) | +| SO_SNDBUF | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | [`tcp::(set-)send-buffer-size`](tcp)
    [`udp::(set-)send-buffer-size`](udp) | +| SO_RCVLOWAT | ❔ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_SNDLOWAT | ❔ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| SO_RCVTIMEO | ⛔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | WASI sockets are always non-blocking. Timeouts can be recreated in libc. | +| SO_SNDTIMEO | ⛔ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | WASI sockets are always non-blocking. Timeouts can be recreated in libc. | +| SO_KEEPALIVE | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | [`tcp::(set-)keep-alive`](tcp) | +| TCP_KEEPCNT | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| TCP_KEEPIDLE | ❔ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | | +| TCP_KEEPINTVL | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | | +| TCP_KEEPALIVE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | | +| TCP_NODELAY | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | [`tcp::(set-)no-delay`](tcp) | +| TCP_CORK | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ | TCP_NOPUSH on MacOS & FreeBSD | +| IP_OPTIONS | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | +| SO_LINGER | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | | +| SO_OOBINLINE | ⛔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_DEBUG | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_DONTROUTE | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_REUSEADDR | ❔ | ✅ | ✅ | ✅* | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | Roughly equivalent to the inverse of SO_EXCLUSIVEADDRUSE on Windows. | +| SO_REUSEPORT | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | | +| SO_REUSEPORT_LB | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| SO_BROADCAST | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_ADD_MEMBERSHIP | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_JOIN_GROUP | +| IPV6_JOIN_GROUP | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_JOIN_GROUP, alias of IPV6_ADD_MEMBERSHIP | +| IP_ADD_SOURCE_MEMBERSHIP | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_JOIN_SOURCE_GROUP | +| IP_DROP_MEMBERSHIP | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_LEAVE_GROUP | +| IPV6_LEAVE_GROUP | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_LEAVE_GROUP, alias of IPV6_DROP_MEMBERSHIP | +| IP_DROP_SOURCE_MEMBERSHIP | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_LEAVE_SOURCE_GROUP | +| IP_MULTICAST_IF | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_MULTICAST_IF | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_MULTICAST_LOOP | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_MULTICAST_LOOP | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_MULTICAST_TTL | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_MULTICAST_HOPS | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_BLOCK_SOURCE | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_BLOCK_SOURCE | +| IP_UNBLOCK_SOURCE | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_UNBLOCK_SOURCE | +| IP_MSFILTER | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_INFO | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ | | +| TCP_FASTOPEN | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | | +| TCP_FASTOPEN_CONNECT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ✅ | | +| TCP_FASTOPEN_KEY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_FASTOPEN_NO_COOKIE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_FASTOPEN_FORCE_HEURISTICS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_IPSEC_POLICY | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_MINTTL | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_MTU | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | | +| IP_RECVOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RECVORIGDSTADDR | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | IP_ORIGDSTADDR on FreeBSD | +| IP_RECVRETOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RETOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_UNICAST_IF | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | +| IPV6_2292DSTOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_2292HOPLIMIT | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_2292HOPOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_2292PKTINFO | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_2292PKTOPTIONS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_2292RTHDR | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_AUTOFLOWLABEL | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_CHECKSUM | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_DSTOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_HOPOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_IPSEC_POLICY | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_MTU | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_NEXTHOP | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_PATHMTU | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RECVDSTOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RECVHOPOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RECVORIGDSTADDR | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | IPV6_ORIGDSTADDR on FreeBSD | +| IPV6_RECVPATHMTU | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RECVRTHDR | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RTHDR | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RTHDRDSTOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_UNICAST_IF | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | +| IPV6_USE_MIN_MTU | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TIMESTAMP | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_CONGESTION | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_MAXSEG | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_MD5SIG | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_NOTSENT_LOWAT | ❔ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| UDP_ENCAP | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_BIND_ADDRESS_NO_PORT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | | +| IP_CHECKSUM | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_FREEBIND | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_MULTICAST_ALL | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_NODEFRAG | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_PASSSEC | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_PKTOPTIONS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RECVERR | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RECVERR_RFC4884 | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RECVFRAGSIZE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_ROUTER_ALERT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_TRANSPARENT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| IP_XFRM_POLICY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_ADDR_PREFERENCES | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_ADDRFORM | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_AUTHHDR | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_FLOWINFO | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_FLOWINFO_SEND | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_FLOWLABEL_MGR | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_FREEBIND | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_JOIN_ANYCAST | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_LEAVE_ANYCAST | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_MINHOPCOUNT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_MULTICAST_ALL | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RECVERR | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RECVERR_RFC4884 | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RECVFRAGSIZE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_ROUTER_ALERT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_ROUTER_ALERT_ISOLATE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_TRANSPARENT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| IPV6_XFRM_POLICY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_ATTACH_FILTER | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_ATTACH_REUSEPORT_CBPF | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | +| SO_ATTACH_REUSEPORT_EBPF | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| SO_BINDTODEVICE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | | +| SO_BSDCOMPAT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_BUSY_POLL | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_COOKIE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| SO_DETACH_FILTER | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_INCOMING_CPU | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_INCOMING_NAPI_ID | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_LOCK_FILTER | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_MARK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_PASSCRED | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_PASSSEC | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_PEEK_OFF | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_PEERCRED | ⛔ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Out of scope; UNIX domain sockets only. | +| SO_PEERSEC | ⛔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Out of scope; UNIX domain sockets only. | +| SO_PRIORITY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_RCVBUFFORCE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_RXQ_OVFL | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_SELECT_ERR_QUEUE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_SNDBUFFORCE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TIMESTAMPNS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_CC_INFO | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_CM_INQ | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_DEFER_ACCEPT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| TCP_INQ | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_LINGER2 | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_MD5SIG_EXT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_QUEUE_SEQ | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_QUICKACK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | +| TCP_REPAIR | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_REPAIR_OPTIONS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_REPAIR_QUEUE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_REPAIR_WINDOW | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_SAVE_SYN | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_SAVED_SYN | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_SYNCNT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_THIN_DUPACK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_THIN_LINEAR_TIMEOUTS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_TIMESTAMP | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_TX_DELAY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_ULP | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_USER_TIMEOUT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_WINDOW_CLAMP | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_ZEROCOPY_RECEIVE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| UDP_CORK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| UDP_GRO | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | +| UDP_NO_CHECK6_RX | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| UDP_NO_CHECK6_TX | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| UDP_SEGMENT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| IP_ADD_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_DEL_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_GET_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_ORIGINAL_ARRIVAL_IF | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_ORIGINAL_ARRIVAL_IF | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RECEIVE_BROADCAST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_USER_MTU | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_WFP_REDIRECT_CONTEXT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_WFP_REDIRECT_RECORDS | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_ADD_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_DEL_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_GET_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_PROTECTION_LEVEL | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RECVIF | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_USER_MTU | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_BSP_STATE | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_CONDITIONAL_ACCEPT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_CONNDATA | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_CONNDATALEN | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_CONNECT_TIME | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_CONNOPT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_CONNOPTLEN | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_DISCDATA | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_DISCDATALEN | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_DISCOPT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_DISCOPTLEN | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_GROUP_ID | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_GROUP_PRIORITY | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_MAX_MSG_SIZE | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_MAXDG | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_MAXPATHDG | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_OPENTYPE | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_PAUSE_ACCEPT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_PORT_SCALABILITY | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_PROTOCOL_INFO | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_PROTOCOL_INFOA | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_PROTOCOL_INFOW | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_RANDOMIZE_PORT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_REUSE_MULTICASTPORT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_REUSE_UNICASTPORT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_UPDATE_ACCEPT_CONTEXT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_UPDATE_CONNECT_CONTEXT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_BSDURGENT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_EXPEDITED_1122 | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_FAIL_CONNECT_ON_ICMP_ERROR | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_ICMP_ERROR_INFO | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_MAXRT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_TIMESTAMPS | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| UDP_CHECKSUM_COVERAGE | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| UDP_NOCHECKSUM | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| UDP_RECV_MAX_COALESCED_SIZE | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | +| UDP_SEND_MSG_SIZE | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | +| IP_BOUND_IF | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_FAITH | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_MULTICAST_IFINDEX | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_NAT__XXX | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_STRIPHDR | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_TRAFFIC_MGT_BACKGROUND | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_3542DSTOPTS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_3542HOPLIMIT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_3542HOPOPTS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_3542NEXTHOP | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_3542PKTINFO | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_3542RTHDR | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_BOUND_IF | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RTHDR_LOOSE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RTHDR_STRICT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RTHDR_TYPE_0 | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_AWDL_UNRESTRICTED | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_CFIL_SOCK_ID | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_DELEGATED | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_DELEGATED_UUID | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_DONTTRUNC | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_EXECPATH | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_EXTENDED_BK_IDLE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_FLOW_DIVERT_TOKEN | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_FLUSH | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_INTCOPROC_ALLOW | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_LINGER_SEC | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_MARK_CELLFALLBACK | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_MPKL_SEND_INFO | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NECP_ATTRIBUTES | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NECP_CLIENTUUID | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NECP_LISTENUUID | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NET_SERVICE_TYPE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NETSVC_MARKING_LEVEL | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NKE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NOADDRERR | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NOAPNFALLBK | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NOTIFYCONFLICT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NOWAKEFROMSLEEP | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NP_EXTENSIONS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NREAD | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NUMRCVPKT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NWRITE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_OPPORTUNISTIC | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_QOSMARKING_POLICY_OVERRIDE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_RANDOMPORT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_RECV_ANYIF | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_RESTRICTIONS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_REUSESHAREUID | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_STATISTICS_EVENT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TC_NET_SERVICE_OFFSET | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TC_NETSVC_SIG | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TIMESTAMP_CONTINUOUS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TIMESTAMP_MONOTONIC | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TRAFFIC_MGT_BACKGROUND | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_UPCALLCLOSEWAIT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_WANT_KEV_SOCKET_CLOSED | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_WANTMORE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_WANTOOBFLAG | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_ADAPTIVE_READ_TIMEOUT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_ADAPTIVE_WRITE_TIMEOUT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_CONNECTION_INFO | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_CONNECTIONTIMEOUT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_DISABLE_BLACKHOLE_DETECTION | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_ECN_MODE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_ENABLE_ECN | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_KEEPALIVE_OFFLOAD | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_MAX_NOTIFY_ACK | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_MEASURE_BW_BURST | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_MEASURE_SND_BW | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_NOTIFY_ACKNOWLEDGEMENT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_NOTIMEWAIT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_OPTION_UNUSED_0 | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_PEER_PID | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_RXT_CONNDROPTIME | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_RXT_FINDROP | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_SENDMOREACKS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| UDP_KEEPALIVE_OFFLOAD | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| UDP_NOCKSUM | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| ICMP6_FILTER | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_MULTICAST_VIF | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_PORTRANGE | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RSVP_OFF | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RSVP_ON | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RSVP_VIF_OFF | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RSVP_VIF_ON | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_2292NEXTHOP | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_BINDV6ONLY | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_FAITH | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_MSFILTER | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_PKTOPTIONS | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_PORTRANGE | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_PREFER_TEMPADDR | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RECVRTHDRDSTOPTS | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_ACCEPTFILTER | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| SO_LABEL | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NOSIGPIPE | ⛔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | [Not supported, see SIGPIPE](#sigpipe) | +| SO_PEERLABEL | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_USELOOPBACK | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_NOOPT | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_BINDANY | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| IP_BINDMULTI | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_FLOWID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_FLOWTYPE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_MAX_MEMBERSHIPS | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_ONESBCAST | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RECVFLOWID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RECVRSSBUCKETID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RSS_LISTEN_BUCKET | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RSSBUCKETID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_SENDSRCADDR | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| IP_VLAN_PCP | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_AUTH_LEVEL | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_BINDANY | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| IPV6_BINDMULTI | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_ESP_NETWORK_LEVEL | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_ESP_TRANS_LEVEL | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_FLOWID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_FLOWTYPE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_IPCOMP_LEVEL | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RECVFLOWID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RECVRSSBUCKETID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RSS_LISTEN_BUCKET | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RSSBUCKETID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_VLAN_PCP | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_BINTIME | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_LISTENINCQLEN | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_LISTENQLEN | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | +| SO_LISTENQLIMIT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_MAX_PACING_RATE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NO_DDP | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NO_OFFLOAD | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_RERROR | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_SETFIB | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| SO_TS_BINTIME | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TS_CLOCK | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TS_CLOCK_MAX | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TS_DEFAULT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TS_MONOTONIC | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TS_REALTIME | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TS_REALTIME_MICRO | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_USER_COOKIE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_CCALGOOPT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_DATA_AFTER_CLOSE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_DEFER_OPTIONS | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_DELACK | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_FAST_RSM_HACK | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_FIN_IS_RST | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_FUNCTION_ALIAS | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_FUNCTION_BLK | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_HDWR_RATE_CAP | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_HDWR_UP_ONLY | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_IDLE_REDUCE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_IWND_NB | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_IWND_NSEG | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_KEEPINIT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_LOG | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_LOG_LIMIT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_LOG_TAG | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_LOGBUF | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_LOGDUMP | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_LOGDUMPID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_LOGID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_LOGID_CNT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_LRD | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_MAXPEAKRATE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_MAXUNACKTIME | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_NO_PRR | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_PACING_RATE_CAP | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_PCAP_IN | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_PCAP_OUT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_PERF_INFO | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_PROC_ACCOUNTING | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_REC_ABC_VAL | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_REMOTE_UDP_ENCAPS_PORT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_REUSPORT_LB_NUMA | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_RXTLS_ENABLE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_RXTLS_MODE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_SHARED_CWND_ALLOWED | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_SHARED_CWND_ENABLE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_SHARED_CWND_TIME_LIMIT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_STATS | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_TIMELY_DYN_ADJ | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_TXTLS_ENABLE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_TXTLS_MODE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_USE_CMP_ACKS | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_USER_LOG | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | + + + + + + +[ip-name-lookup]: https://github.com/WebAssembly/wasi-sockets/blob/main/wit/ip-name-lookup.wit +[tcp-create-socket]: https://github.com/WebAssembly/wasi-sockets/blob/main/wit/tcp-create-socket.wit +[tcp]: https://github.com/WebAssembly/wasi-sockets/blob/main/wit/tcp.wit +[udp-create-socket]: https://github.com/WebAssembly/wasi-sockets/blob/main/wit/udp-create-socket.wit +[udp]: https://github.com/WebAssembly/wasi-sockets/blob/main/wit/udp.wit +[poll]: https://github.com/WebAssembly/wasi-poll/blob/main/wit/poll.wit +[streams]: https://github.com/WebAssembly/wasi-io/blob/main/wit/streams.wit \ No newline at end of file diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 0a45245e2..98a50205a 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -153,37 +153,7 @@ A downside of this approach is that functions that do *not* differ per protocol #### POSIX compatibility -The [wasi-socket](./wasi-socket.wit) module exports a `kind` function that can be called on any kind of socket. -The return value can be used to dispatch calls to the correct WASI module. - -In pseudo code: - -```rs -fn socket(address_family: i32, socket_type: i32, protocol: i32) { - - let ambient_network_capability = // Pluck it out of thin air. - - match (socket_type, protocol) { - (SOCK_STREAM, 0) => wasi_socket_tcp::create_tcp_socket(ambient_network_capability, address_family), - (SOCK_DGRAM, 0) => wasi_socket_udp::create_udp_socket(ambient_network_capability, address_family), - _ => EINVAL, - } -} - -fn recvfrom(socket: i32, flags: i32) { - - let kind = wasi_socket::kind(socket); - let peek = flags & MSG_PEEK; - - match (kind, peek) { - (Udp, false) => wasi_socket_udp::receive_from(socket), - (Udp, true) => wasi_socket_udp::peek_from(socket), - (Tcp, false) => (wasi_io_streams::read(socket), address: 0, truncated: false), - (Tcp, true) => (wasi_socket_tcp::peek(socket), address: 0, truncated: false), - _ => EBADF, - } -} -``` +See [Posix-compatibility.md](./Posix-compatibility.md). #### Why not getaddrinfo? From 07872c00e071e87b8574ee6b359dce0128451ad7 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Mon, 26 Jun 2023 21:37:04 +0200 Subject: [PATCH 1180/1772] PSA --- proposals/sockets/Posix-compatibility.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/sockets/Posix-compatibility.md b/proposals/sockets/Posix-compatibility.md index 8cd15d988..7f3331f92 100644 --- a/proposals/sockets/Posix-compatibility.md +++ b/proposals/sockets/Posix-compatibility.md @@ -143,6 +143,7 @@ Columns: - ✅ = Option is provided by the platform / depended upon by the application. - ❌ = Option is not provided / not used. +> Note: GitHub clips the table content. Scroll left and right to see all columns, or use the Code View. | Option | WASI | POSIX | Linux | Windows | MacOS | FreeBSD | JVM | .NET | Rust | Node.js | Go | OpenSSL | nginx | curl | msquic | exim | Notes | |---------------------------------|-----------|--------|--------|---------|---------|---------|-------|--------|-------|---------|-----|----------|-------|-------|--------|-------|-| From 8c062a815aef561869f7a00773431de5f9e979ac Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Tue, 27 Jun 2023 17:49:18 +0200 Subject: [PATCH 1181/1772] Enable batch receive & send. --- proposals/sockets/example-world.md | 27 +++++++++++++++++---------- proposals/sockets/wit/udp.wit | 25 ++++++++++++++++++------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index 736792b1f..300ceb1a7 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -428,12 +428,10 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

  • result<_, error-code>
  • receive: func

    -

    Receive a message.

    -

    Returns:

    -
      -
    • The sender address of the datagram
    • -
    • The number of bytes read.
    • -
    +

    Receive messages on the socket.

    +

    This function attempts to receive up to max-results datagrams on the socket without blocking. +The returned list may contain fewer elements than requested, but never more. +If max-results is 0, this function returns successfully with an empty list.

    Typical errors

    • not-bound: The socket is not bound to any local address. (EINVAL)
    • @@ -445,6 +443,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    • https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html
    • https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html
    • https://man7.org/linux/man-pages/man2/recv.2.html
    • +
    • https://man7.org/linux/man-pages/man2/recvmmsg.2.html
    • https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recv
    • https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recvfrom
    • https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms741687(v=vs.85)
    • @@ -453,13 +452,20 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

      Params
      Return values

      send: func

      -

      Send a message to a specific destination address.

      +

      Send messages on the socket.

      +

      This function attempts to send all provided datagrams on the socket without blocking and +returns how many messages were actually sent (or queued for sending).

      +

      This function semantically behaves the same as iterating the datagrams list and sequentially +sending each individual datagram until either the end of the list has been reached or the first error occurred. +If at least one datagram has been sent successfully, this function never returns an error.

      +

      If the input list is empty, the function returns ok(0).

      The remote address option is required. To send a message to the "connected" peer, call remote-address to get their address.

      Typical errors

      @@ -478,6 +484,7 @@ call remote-address to get their addr
    • https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html
    • https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html
    • https://man7.org/linux/man-pages/man2/send.2.html
    • +
    • https://man7.org/linux/man-pages/man2/sendmmsg.2.html
    • https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-send
    • https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto
    • https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasendmsg
    • @@ -486,11 +493,11 @@ call remote-address to get their addr
      Params
      Return values

      local-address: func

      Get the current bound address.

      diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 3a0c1bd14..948ed581a 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -84,11 +84,11 @@ interface udp { start-connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> finish-connect: func(this: udp-socket) -> result<_, error-code> - /// Receive a message. + /// Receive messages on the socket. /// - /// Returns: - /// - The sender address of the datagram - /// - The number of bytes read. + /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. + /// The returned list may contain fewer elements than requested, but never more. + /// If `max-results` is 0, this function returns successfully with an empty list. /// /// # Typical errors /// - `not-bound`: The socket is not bound to any local address. (EINVAL) @@ -99,13 +99,23 @@ interface udp { /// - /// - /// - + /// - /// - /// - /// - /// - - receive: func(this: udp-socket) -> result + receive: func(this: udp-socket, max-results: u64) -> result, error-code> - /// Send a message to a specific destination address. + /// Send messages on the socket. + /// + /// This function attempts to send all provided `datagrams` on the socket without blocking and + /// returns how many messages were actually sent (or queued for sending). + /// + /// This function semantically behaves the same as iterating the `datagrams` list and sequentially + /// sending each individual datagram until either the end of the list has been reached or the first error occurred. + /// If at least one datagram has been sent successfully, this function never returns an error. + /// + /// If the input list is empty, the function returns `ok(0)`. /// /// The remote address option is required. To send a message to the "connected" peer, /// call `remote-address` to get their address. @@ -124,11 +134,12 @@ interface udp { /// - /// - /// - + /// - /// - /// - /// - /// - - send: func(this: udp-socket, datagram: datagram) -> result<_, error-code> + send: func(this: udp-socket, datagrams: list) -> result /// Get the current bound address. /// From 967779349f9a3745eeffae5b0ea1e8b1ba134caa Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Jun 2023 14:15:09 -0700 Subject: [PATCH 1182/1772] Use a `stream-status` type instead of `bool` for end-of-stream. (#36) Define and use a dedicated `stream-status` enum type for indicating the end-of-stream condition instead of using a `bool`. This makes the API more self-describing. --- proposals/io/example-world.md | 43 ++++++++++++++++++++++++----------- proposals/io/wit/streams.wit | 37 ++++++++++++++++++++---------- 2 files changed, 55 insertions(+), 25 deletions(-) diff --git a/proposals/io/example-world.md b/proposals/io/example-world.md index 5033a563b..31b0d76a3 100644 --- a/proposals/io/example-world.md +++ b/proposals/io/example-world.md @@ -64,7 +64,24 @@ when it does, they are expected to subsume this API.

      type pollable

      pollable

      -#### `record stream-error` +#### `enum stream-status` +

      Streams provide a sequence of data and then end; once they end, they +no longer provide any further data.

      +

      For example, a stream reading from a file ends when the stream reaches +the end of the file. For another example, a stream reading from a +socket ends when the socket is closed.

      +
      Enum Cases
      +
        +
      • +

        open

        +

        The stream is open and may produce further data. +

      • +
      • +

        ended

        +

        The stream has ended and will not produce any further data. +

      • +
      +

      record stream-error

      An error type returned from a stream operation. Currently this doesn't provide any additional information.

      Record Fields
      @@ -103,9 +120,9 @@ the wit-bindgen implementation of handles and resources is ready.

      read: func

      Read bytes from a stream.

      This function returns a list of bytes containing the data that was -read, along with a bool which, when true, indicates that the end of the -stream was reached. The returned list will contain up to len bytes; it -may return fewer than requested, but not more.

      +read, along with a stream-status which indicates whether the end of +the stream was reached. The returned list will contain up to len +bytes; it may return fewer than requested, but not more.

      Once a stream has reached the end, subsequent calls to read or skip will always report end-of-stream rather than producing more data.

      @@ -122,7 +139,7 @@ FIXME: describe what happens if allocation fails.

    Return values

    blocking-read: func

    Read bytes from a stream, with blocking.

    @@ -135,7 +152,7 @@ byte can be read.

    Return values

    skip: func

    Skip bytes from a stream.

    @@ -144,9 +161,9 @@ bytes into the instance.

    Once a stream has reached the end, subsequent calls to read or skip will always report end-of-stream rather than producing more data.

    -

    This function returns the number of bytes skipped, along with a bool -indicating whether the end of the stream was reached. The returned -value will be at most len; it may be less.

    +

    This function returns the number of bytes skipped, along with a +stream-status indicating whether the end of the stream was +reached. The returned value will be at most len; it may be less.

    Params
    • this: input-stream
    • @@ -154,7 +171,7 @@ value will be at most len; it may be less.

    Return values

    blocking-skip: func

    Skip bytes from a stream, with blocking.

    @@ -167,7 +184,7 @@ byte can be consumed.

    Return values

    subscribe-to-input-stream: func

    Create a pollable which will resolve once either the specified stream @@ -254,7 +271,7 @@ read from the input stream has been written to the output stream.

    Return values

    blocking-splice: func

    Read from one stream and write to another, with blocking.

    @@ -268,7 +285,7 @@ one byte can be read.

    Return values

    forward: func

    Forward the entire contents of an input stream to an output stream.

    diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index 430c1d441..de8694bda 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -10,6 +10,19 @@ interface streams { /// doesn't provide any additional information. record stream-error {} + /// Streams provide a sequence of data and then end; once they end, they + /// no longer provide any further data. + /// + /// For example, a stream reading from a file ends when the stream reaches + /// the end of the file. For another example, a stream reading from a + /// socket ends when the socket is closed. + enum stream-status { + /// The stream is open and may produce further data. + open, + /// The stream has ended and will not produce any further data. + ended, + } + /// An input bytestream. In the future, this will be replaced by handle /// types. /// @@ -32,9 +45,9 @@ interface streams { /// Read bytes from a stream. /// /// This function returns a list of bytes containing the data that was - /// read, along with a bool which, when true, indicates that the end of the - /// stream was reached. The returned list will contain up to `len` bytes; it - /// may return fewer than requested, but not more. + /// read, along with a `stream-status` which indicates whether the end of + /// the stream was reached. The returned list will contain up to `len` + /// bytes; it may return fewer than requested, but not more. /// /// Once a stream has reached the end, subsequent calls to read or /// `skip` will always report end-of-stream rather than producing more @@ -51,7 +64,7 @@ interface streams { this: input-stream, /// The maximum number of bytes to read len: u64 - ) -> result, bool>, stream-error> + ) -> result, stream-status>, stream-error> /// Read bytes from a stream, with blocking. /// @@ -61,7 +74,7 @@ interface streams { this: input-stream, /// The maximum number of bytes to read len: u64 - ) -> result, bool>, stream-error> + ) -> result, stream-status>, stream-error> /// Skip bytes from a stream. /// @@ -72,14 +85,14 @@ interface streams { /// `skip` will always report end-of-stream rather than producing more /// data. /// - /// This function returns the number of bytes skipped, along with a bool - /// indicating whether the end of the stream was reached. The returned - /// value will be at most `len`; it may be less. + /// This function returns the number of bytes skipped, along with a + /// `stream-status` indicating whether the end of the stream was + /// reached. The returned value will be at most `len`; it may be less. skip: func( this: input-stream, /// The maximum number of bytes to skip. len: u64, - ) -> result, stream-error> + ) -> result, stream-error> /// Skip bytes from a stream, with blocking. /// @@ -89,7 +102,7 @@ interface streams { this: input-stream, /// The maximum number of bytes to skip. len: u64, - ) -> result, stream-error> + ) -> result, stream-error> /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been @@ -172,7 +185,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result, stream-error> + ) -> result, stream-error> /// Read from one stream and write to another, with blocking. /// @@ -184,7 +197,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result, stream-error> + ) -> result, stream-error> /// Forward the entire contents of an input stream to an output stream. /// From d9aebda0c5c51f95d534b6088f7c1bf903a831c0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 20 Jul 2023 11:29:24 -0700 Subject: [PATCH 1183/1772] Remove the device and inode numbers from the API. (#81) * Remove the device and inode numbers from the API. As discussed [here], remove the fields which correspond to `st_dev`, `st_ino`, and `d_ino` in POSIX from the stat and directory entry structs. - Device numbers assume the existence of a global device number space, which creates implicit relationships between otherwise unrelated components. - Not all filesystem implementations have these numbers. And some that do have these numbers require extra implementation cost to retrieve them. - These numbers leak potentially sensitive or identifying information from the underlying filesystem implementation. In their place, provide some functions, `is-same-object`, `metadata-hash`, and `metadata-hash-at`, for explicitly testing whether two handles are the same file or have the same metadata, respectively. This doesn't cover all possible use cases for device and inode numbers, but we can add more functions as need arises. [here]: #65 (comment) * Remove the device and inode numbers from the API. As discussed [here], remove the fields which correspond to `st_dev`, `st_ino`, and `d_ino` in POSIX from the stat and directory entry structs. - Device numbers assume the existence of a global device number space, which creates implicit relationships between otherwise unrelated components. - Not all filesystem implementations have these numbers. And some that do have these numbers require extra implementation cost to retrieve them. - These numbers leak potentially sensitive or identifying information from the underlying filesystem implementation. In their place, provide some functions, `is-same-object`, `metadata-hash`, and `metadata-hash-at`, for explicitly testing whether two handles are the same file or have the same metadata, respectively. This doesn't cover all possible use cases for device and inode numbers, but we can add more functions as need arises. [here]: #65 (comment) * Explicitly document that the hash can contain a secret value. * Use a named `record` type instead of a `tuple` for hash values. --- proposals/filesystem/example-world.md | 97 ++++++++++++++++++++------- proposals/filesystem/wit/types.wit | 79 ++++++++++++++++------ 2 files changed, 128 insertions(+), 48 deletions(-) diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md index 9920763d1..b4d9d2347 100644 --- a/proposals/filesystem/example-world.md +++ b/proposals/filesystem/example-world.md @@ -427,12 +427,23 @@ filesystem. filesystem. This does not apply to directories. +

    record metadata-hash-value

    +

    A 128-bit hash value, split into parts because wasm doesn't have a +128-bit integer type.

    +
    Record Fields
    +
      +
    • +

      lower: u64

      +

      64 bits of a 128-bit hash value. +

    • +
    • +

      upper: u64

      +

      Another 64 bits of a 128-bit hash value. +

    • +

    type link-count

    u64

    Number of hard links to an inode. -

    type inode

    -

    u64

    -

    Filesystem object serial number that is unique within its file system.

    type filesize

    u64

    File size or length of a region within a file. @@ -596,11 +607,6 @@ merely for alignment with POSIX.

    u32

    A stream of directory entries.

    This represents a stream of dir-entry.

    -

    type device

    -

    u64

    -

    Identifier for a device containing a file system. Can be used in -combination with `inode` to uniquely identify a file or directory in -the filesystem.

    enum descriptor-type

    The type of a filesystem object referenced by a descriptor.

    Note: This was called filetype in earlier versions of WASI.

    @@ -645,14 +651,6 @@ any of the other types specified.
    Record Fields
    • -

      inode: option<inode>

      -

      The serial number of the object referred to by this directory entry. -May be none if the inode value is not known. -

      When this is none, libc implementations might do an extra stat-at -call to retrieve the inode number to fill their d_ino fields, so -implementations which can set this to a non-none value should do so.

      -
    • -
    • type: descriptor-type

      The type of the file referred to by this directory entry.

    • @@ -750,14 +748,6 @@ with the filesystem.
      Record Fields

      stat: func

      Return the attributes of an open file or directory.

      -

      Note: This is similar to fstat in POSIX.

      +

      Note: This is similar to fstat in POSIX, except that it does not return +device and inode information. For testing whether two descriptors refer to +the same underlying filesystem object, use is-same-object. To obtain +additional data that can be used do determine whether a file has been +modified, use metadata-hash.

      Note: This was called fd_filestat_get in earlier versions of WASI.

      Params
        @@ -1063,7 +1057,9 @@ opened for writing.

      stat-at: func

      Return the attributes of a file or directory.

      -

      Note: This is similar to fstatat in POSIX.

      +

      Note: This is similar to fstatat in POSIX, except that it does not +return device and inode information. See the stat description for a +discussion of alternatives.

      Note: This was called path_filestat_get in earlier versions of WASI.

      Params
        @@ -1387,6 +1383,55 @@ be used.

        +

        is-same-object: func

        +

        Test whether two descriptors refer to the same filesystem object.

        +

        In POSIX, this corresponds to testing whether the two descriptors have the +same device (st_dev) and inode (st_ino or d_ino) numbers. +wasi-filesystem does not expose device and inode numbers, so this function +may be used instead.

        +
        Params
        + +
        Return values
        +
          +
        • bool
        • +
        +

        metadata-hash: func

        +

        Return a hash of the metadata associated with a filesystem object referred +to by a descriptor.

        +

        This returns a hash of the last-modification timestamp and file size, and +may also include the inode number, device number, birth timestamp, and +other metadata fields that may change when the file is modified or +replaced. It may also include a secret value chosen by the +implementation and not otherwise exposed.

        +

        Implementations are encourated to provide the following properties:

        +
          +
        • If the file is not modified or replaced, the computed hash value should +usually not change.
        • +
        • If the object is modified or replaced, the computed hash value should +usually change.
        • +
        • The inputs to the hash should not be easily computable from the +computed hash.
        • +
        +

        However, none of these is required.

        +
        Return values
        + +

        metadata-hash-at: func

        +

        Return a hash of the metadata associated with a filesystem object referred +to by a directory descriptor and a relative path.

        +

        This performs the same hash computation as metadata-hash.

        +
        Params
        + +
        Return values
        +

        Import interface wasi:filesystem/preopens


        Types

        diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 0f7d96e18..9a1bc12df 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -102,10 +102,6 @@ interface types { /// /// Note: This was called `filestat` in earlier versions of WASI. record descriptor-stat { - /// Device ID of device containing the file. - device: device, - /// File serial number. - inode: inode, /// File type. %type: descriptor-type, /// Number of hard links to the file. @@ -166,14 +162,6 @@ interface types { /// Number of hard links to an inode. type link-count = u64 - /// Identifier for a device containing a file system. Can be used in - /// combination with `inode` to uniquely identify a file or directory in - /// the filesystem. - type device = u64 - - /// Filesystem object serial number that is unique within its file system. - type inode = u64 - /// When setting a timestamp, this gives the value to set it to. variant new-timestamp { /// Leave the timestamp set to its previous value. @@ -187,14 +175,6 @@ interface types { /// A directory entry. record directory-entry { - /// The serial number of the object referred to by this directory entry. - /// May be none if the inode value is not known. - /// - /// When this is none, libc implementations might do an extra `stat-at` - /// call to retrieve the inode number to fill their `d_ino` fields, so - /// implementations which can set this to a non-none value should do so. - inode: option, - /// The type of the file referred to by this directory entry. %type: descriptor-type, @@ -312,6 +292,15 @@ interface types { /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). type descriptor = u32 + /// A 128-bit hash value, split into parts because wasm doesn't have a + /// 128-bit integer type. + record metadata-hash-value { + /// 64 bits of a 128-bit hash value. + lower: u64, + /// Another 64 bits of a 128-bit hash value. + upper: u64, + } + /// Return a stream for reading from a file, if available. /// /// May fail with an error-code describing why the file cannot be read. @@ -485,14 +474,20 @@ interface types { /// Return the attributes of an open file or directory. /// - /// Note: This is similar to `fstat` in POSIX. + /// Note: This is similar to `fstat` in POSIX, except that it does not return + /// device and inode information. For testing whether two descriptors refer to + /// the same underlying filesystem object, use `is-same-object`. To obtain + /// additional data that can be used do determine whether a file has been + /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. stat: func(this: descriptor) -> result /// Return the attributes of a file or directory. /// - /// Note: This is similar to `fstatat` in POSIX. + /// Note: This is similar to `fstatat` in POSIX, except that it does not + /// return device and inode information. See the `stat` description for a + /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. stat-at: func( @@ -800,4 +795,44 @@ interface types { /// Dispose of the specified `directory-entry-stream`, after which it may no longer /// be used. drop-directory-entry-stream: func(this: directory-entry-stream) + + /// Test whether two descriptors refer to the same filesystem object. + /// + /// In POSIX, this corresponds to testing whether the two descriptors have the + /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. + /// wasi-filesystem does not expose device and inode numbers, so this function + /// may be used instead. + is-same-object: func(other: descriptor) -> bool + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a descriptor. + /// + /// This returns a hash of the last-modification timestamp and file size, and + /// may also include the inode number, device number, birth timestamp, and + /// other metadata fields that may change when the file is modified or + /// replaced. It may also include a secret value chosen by the + /// implementation and not otherwise exposed. + /// + /// Implementations are encourated to provide the following properties: + /// + /// - If the file is not modified or replaced, the computed hash value should + /// usually not change. + /// - If the object is modified or replaced, the computed hash value should + /// usually change. + /// - The inputs to the hash should not be easily computable from the + /// computed hash. + /// + /// However, none of these is required. + metadata-hash: func() -> result + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a directory descriptor and a relative path. + /// + /// This performs the same hash computation as `metadata-hash`. + metadata-hash-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result } From 950ab21fbd75043138b655f8057f6470a11f7a5b Mon Sep 17 00:00:00 2001 From: John Edmonds Date: Mon, 24 Jul 2023 09:08:59 -0400 Subject: [PATCH 1184/1772] Update phase to 2 According to https://github.com/WebAssembly/meetings/blob/771f0f9404b6274c640fd0ac97492f6b258a9a34/wasi/2023/WASI-06-29.md?plain=1#L85, wasi-sockets is in phase 2 --- proposals/sockets/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 0a45245e2..9b3c27349 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -4,7 +4,7 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Current Phase -Phase 1 +Phase 2 ### Champions From c3a4b8f57f712715cfdf1d1eeb95adea2e00cb3b Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 27 Jul 2023 12:29:37 +0200 Subject: [PATCH 1185/1772] Update list of socket options. --- proposals/sockets/Posix-compatibility.md | 77 ++++++++++++++---------- 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/proposals/sockets/Posix-compatibility.md b/proposals/sockets/Posix-compatibility.md index 7f3331f92..a2ba1c628 100644 --- a/proposals/sockets/Posix-compatibility.md +++ b/proposals/sockets/Posix-compatibility.md @@ -177,19 +177,22 @@ Columns: | SO_SNDTIMEO | ⛔ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | WASI sockets are always non-blocking. Timeouts can be recreated in libc. | | SO_KEEPALIVE | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | [`tcp::(set-)keep-alive`](tcp) | | TCP_KEEPCNT | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| TCP_KEEPIDLE | ❔ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | | +| TCP_KEEPIDLE | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | TCP_KEEPALIVE on MacOS | | TCP_KEEPINTVL | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | | -| TCP_KEEPALIVE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | | | TCP_NODELAY | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | [`tcp::(set-)no-delay`](tcp) | | TCP_CORK | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ | TCP_NOPUSH on MacOS & FreeBSD | -| IP_OPTIONS | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | | SO_LINGER | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | | -| SO_OOBINLINE | ⛔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_OOBINLINE | ⛔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Not supported, see [OOB](#oob) | | SO_DEBUG | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_DONTROUTE | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_REUSEADDR | ❔ | ✅ | ✅ | ✅* | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | Roughly equivalent to the inverse of SO_EXCLUSIVEADDRUSE on Windows. | | SO_REUSEPORT | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | | | SO_REUSEPORT_LB | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| IP_BIND_ADDRESS_NO_PORT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | | +| SO_ATTACH_REUSEPORT_CBPF | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | +| SO_ATTACH_REUSEPORT_EBPF | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | +| SO_DETACH_REUSEPORT_BPF | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_REUSPORT_LB_NUMA | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_BROADCAST | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IP_ADD_MEMBERSHIP | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_JOIN_GROUP | | IPV6_JOIN_GROUP | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_JOIN_GROUP, alias of IPV6_ADD_MEMBERSHIP | @@ -205,21 +208,32 @@ Columns: | IPV6_MULTICAST_HOPS | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IP_BLOCK_SOURCE | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_BLOCK_SOURCE | | IP_UNBLOCK_SOURCE | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_UNBLOCK_SOURCE | -| IP_MSFILTER | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_MSFILTER | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_INFO | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ | | | TCP_FASTOPEN | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | | | TCP_FASTOPEN_CONNECT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ✅ | | | TCP_FASTOPEN_KEY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_FASTOPEN_NO_COOKIE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_FASTOPEN_FORCE_ENABLE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_FASTOPEN_FORCE_HEURISTICS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_BINDTODEVICE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | | +| SO_BINDTOIFINDEX | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_BOUND_IF | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_BOUND_IF | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IP_IPSEC_POLICY | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IP_MINTTL | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_MINHOPCOUNT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IP_MTU | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_MTU | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_PATHMTU | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_RECVPATHMTU | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IPV6_USE_MIN_MTU | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_OPTIONS | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | | IP_RECVOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IP_RECVORIGDSTADDR | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | IP_ORIGDSTADDR on FreeBSD | -| IP_RECVRETOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_RETOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| IP_RECVRETOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Alias of IP_RETOPTS | | IP_UNICAST_IF | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | +| IPV6_UNICAST_IF | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | | IPV6_2292DSTOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_2292HOPLIMIT | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_2292HOPOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | @@ -231,25 +245,19 @@ Columns: | IPV6_DSTOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_HOPOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_IPSEC_POLICY | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_MTU | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | | | IPV6_NEXTHOP | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_PATHMTU | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_RECVDSTOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_RECVHOPOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_RECVORIGDSTADDR | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | IPV6_ORIGDSTADDR on FreeBSD | -| IPV6_RECVPATHMTU | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_RECVRTHDR | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_RTHDR | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_RTHDRDSTOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_UNICAST_IF | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | -| IPV6_USE_MIN_MTU | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_TIMESTAMP | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_CONGESTION | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_MAXSEG | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_MD5SIG | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_NOTSENT_LOWAT | ❔ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | UDP_ENCAP | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_BIND_ADDRESS_NO_PORT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | | | IP_CHECKSUM | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IP_FREEBIND | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IP_MULTICAST_ALL | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | @@ -271,7 +279,6 @@ Columns: | IPV6_FREEBIND | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_JOIN_ANYCAST | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_LEAVE_ANYCAST | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_MINHOPCOUNT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_MULTICAST_ALL | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_RECVERR | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_RECVERR_RFC4884 | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | @@ -281,28 +288,42 @@ Columns: | IPV6_TRANSPARENT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | | IPV6_XFRM_POLICY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_ATTACH_FILTER | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_ATTACH_REUSEPORT_CBPF | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | -| SO_ATTACH_REUSEPORT_EBPF | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| SO_BINDTODEVICE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | | +| SO_BPF_EXTENSIONS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_BSDCOMPAT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_BUF_LOCK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_BUSY_POLL | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_BUSY_POLL_BUDGET | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_CNX_ADVICE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_COOKIE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | | SO_DETACH_FILTER | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_INCOMING_CPU | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_INCOMING_NAPI_ID | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_LOCK_FILTER | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_MARK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_MEMINFO | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NETNS_COOKIE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NO_CHECK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_NOFCS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_PASSCRED | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_PASSSEC | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_PEEK_OFF | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_PEERCRED | ⛔ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Out of scope; UNIX domain sockets only. | +| SO_PEERNAME | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_PEERSEC | ⛔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Out of scope; UNIX domain sockets only. | +| SO_PREFER_BUSY_POLL | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_PRIORITY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_RCVBUFFORCE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_RCVMARK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_RESERVE_MEM | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_RXQ_OVFL | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_SELECT_ERR_QUEUE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_SNDBUFFORCE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TIMESTAMPING | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_TIMESTAMPNS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TXREHASH | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_TXTIME | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_WIFI_STATUS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| SO_ZEROCOPY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_CC_INFO | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_CM_INQ | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_DEFER_ACCEPT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | @@ -385,7 +406,6 @@ Columns: | UDP_NOCHECKSUM | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | UDP_RECV_MAX_COALESCED_SIZE | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | | UDP_SEND_MSG_SIZE | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | -| IP_BOUND_IF | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IP_FAITH | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IP_MULTICAST_IFINDEX | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IP_NAT__XXX | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | @@ -397,7 +417,6 @@ Columns: | IPV6_3542NEXTHOP | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_3542PKTINFO | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_3542RTHDR | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_BOUND_IF | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_RTHDR_LOOSE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_RTHDR_STRICT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_RTHDR_TYPE_0 | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | @@ -444,6 +463,12 @@ Columns: | SO_WANT_KEV_SOCKET_CLOSED | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_WANTMORE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_WANTOOBFLAG | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| MPTCP_ALTERNATE_PORT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| MPTCP_EXPECTED_PROGRESS_TARGET | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| MPTCP_FORCE_ENABLE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| MPTCP_FORCE_VERSION | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| MPTCP_SERVICE_TYPE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| PERSIST_TIMEOUT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_ADAPTIVE_READ_TIMEOUT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_ADAPTIVE_WRITE_TIMEOUT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_CONNECTION_INFO | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | @@ -452,15 +477,14 @@ Columns: | TCP_ECN_MODE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_ENABLE_ECN | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_KEEPALIVE_OFFLOAD | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_MAX_NOTIFY_ACK | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_MEASURE_BW_BURST | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_MEASURE_SND_BW | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_NOTIFY_ACKNOWLEDGEMENT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_NOTIMEWAIT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_OPTION_UNUSED_0 | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_PEER_PID | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_RXT_CONNDROPTIME | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_RXT_FINDROP | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| TCP_RXT_MINIMUM_TIMEOUT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_SENDMOREACKS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | UDP_KEEPALIVE_OFFLOAD | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | UDP_NOCKSUM | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | @@ -481,7 +505,7 @@ Columns: | IPV6_RECVRTHDRDSTOPTS | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_ACCEPTFILTER | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | | SO_LABEL | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NOSIGPIPE | ⛔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | [Not supported, see SIGPIPE](#sigpipe) | +| SO_NOSIGPIPE | ⛔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | Not supported, see [SIGPIPE](#sigpipe) | | SO_PEERLABEL | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_USELOOPBACK | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_NOOPT | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | @@ -528,7 +552,6 @@ Columns: | SO_TS_REALTIME_MICRO | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_USER_COOKIE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_CCALGOOPT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_DATA_AFTER_CLOSE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_DEFER_OPTIONS | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_DELACK | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_FAST_RSM_HACK | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | @@ -552,22 +575,14 @@ Columns: | TCP_LRD | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_MAXPEAKRATE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_MAXUNACKTIME | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_NO_PRR | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_PACING_RATE_CAP | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_PCAP_IN | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_PCAP_OUT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_PERF_INFO | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_PROC_ACCOUNTING | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_REC_ABC_VAL | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_REMOTE_UDP_ENCAPS_PORT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_REUSPORT_LB_NUMA | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_RXTLS_ENABLE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_RXTLS_MODE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_SHARED_CWND_ALLOWED | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_SHARED_CWND_ENABLE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_SHARED_CWND_TIME_LIMIT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_STATS | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_TIMELY_DYN_ADJ | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_TXTLS_ENABLE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_TXTLS_MODE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | TCP_USE_CMP_ACKS | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | From 8d37695d4a990a3ee669fdbe0e1d38a50dc69b15 Mon Sep 17 00:00:00 2001 From: Brendan Burns Date: Fri, 28 Jul 2023 12:09:08 -0700 Subject: [PATCH 1186/1772] Update types.wit with some documentation improvements. (#26) * Update types.wit with some documentation improvements. * Update types.wit * Update wit/types.wit Co-authored-by: Luke Wagner --------- Co-authored-by: Luke Wagner --- proposals/http/wit/types.wit | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 7bb3a1eaa..6d92a8879 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -95,6 +95,12 @@ interface types { // are shared with the request, with all mutations visible to all uses. // Components MUST avoid updating `headers` and `trailers` after passing a // request that points to them to the outside world. + // The streams returned by `consume` and `write` are owned by the request and + // response objects. The streams are destroyed when the request/response is + // dropped, thus a client MUST drop any handle referring to a request/response stream + // before dropping the request/response or passing ownership of the request/response + // to the outside world. The caller can also call drop on the stream before the + // request/response is dropped if they want to release resources earlier. type incoming-request = u32 type outgoing-request = u32 drop-incoming-request: func(request: incoming-request) From e285000bc829f081413d33c0c7c36f9895944a2a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 31 Jul 2023 16:30:23 -0700 Subject: [PATCH 1187/1772] descriptor-flags: eliminate non-blocking flag, and therefore set-flags A blocking or non-blocking read/write is a determined by which method is used on a read/write stream created from a file. Each of these stream methods must be implemened for all files. Therefore, it does not make sense to specify non-blocking at the file level. The set-flags method was only to be used to set or clear the non-blocking flag, so this entire method may now be eliminated. --- proposals/filesystem/example-world.md | 23 ----------------------- proposals/filesystem/wit/types.wit | 17 ----------------- 2 files changed, 40 deletions(-) diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md index b4d9d2347..10e1a157c 100644 --- a/proposals/filesystem/example-world.md +++ b/proposals/filesystem/example-world.md @@ -673,15 +673,6 @@ any of the other types specified.

        Write mode: Data can be written to.

      • -

        non-blocking:

        -

        Requests non-blocking operation. -

        When this flag is enabled, functions may return immediately with an -error-code::would-block error code in situations where they would -otherwise block. However, this non-blocking behavior is not -required. Implementations are permitted to ignore this flag and -block. This is similar to O_NONBLOCK in POSIX.

        -
      • -
      • file-integrity-sync:

        Request that writes be performed according to synchronized I/O file integrity completion. The data stored in the file and the file's @@ -921,20 +912,6 @@ from fdstat_get in earlier versions of WASI.

        -

        set-flags: func

        -

        Set status flags associated with a descriptor.

        -

        This function may only change the non-blocking flag.

        -

        Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

        -

        Note: This was called fd_fdstat_set_flags in earlier versions of WASI.

        -
        Params
        - -
        Return values
        -

        set-size: func

        Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.

        diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 9a1bc12df..0772012bb 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -55,14 +55,6 @@ interface types { read, /// Write mode: Data can be written to. write, - /// Requests non-blocking operation. - /// - /// When this flag is enabled, functions may return immediately with an - /// `error-code::would-block` error code in situations where they would - /// otherwise block. However, this non-blocking behavior is not - /// required. Implementations are permitted to ignore this flag and - /// block. This is similar to `O_NONBLOCK` in POSIX. - non-blocking, /// Request that writes be performed according to synchronized I/O file /// integrity completion. The data stored in the file and the file's /// metadata are synchronized. This is similar to `O_SYNC` in POSIX. @@ -378,15 +370,6 @@ interface types { /// from `fdstat_get` in earlier versions of WASI. get-type: func(this: descriptor) -> result - /// Set status flags associated with a descriptor. - /// - /// This function may only change the `non-blocking` flag. - /// - /// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - /// - /// Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. - set-flags: func(this: descriptor, %flags: descriptor-flags) -> result<_, error-code> - /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// From d02a3dc58a801fc4e823bdae8b46cea9999b2c54 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 1 Aug 2023 11:20:02 -0700 Subject: [PATCH 1188/1772] is-same-object, metadata-hash and metadata-hash-at: add missing this: descriptor argument (#126) * metadata-hash and metadata-hash-at: add missing this: descriptor argument * is-same-object: also needs this: descriptor --- proposals/filesystem/example-world.md | 6 ++++++ proposals/filesystem/wit/types.wit | 7 +++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md index b4d9d2347..eb663f4ec 100644 --- a/proposals/filesystem/example-world.md +++ b/proposals/filesystem/example-world.md @@ -1391,6 +1391,7 @@ wasi-filesystem does not expose device and inode numbers, so this function may be used instead.

        Params
        Return values
        @@ -1415,6 +1416,10 @@ usually change.
      • computed hash.

      However, none of these is required.

      +
      Params
      +
      Return values
      • result<metadata-hash-value, error-code>
      • @@ -1425,6 +1430,7 @@ to by a directory descriptor and a relative path.

        This performs the same hash computation as metadata-hash.

        Params
        diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 9a1bc12df..a437f22ae 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -802,7 +802,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - is-same-object: func(other: descriptor) -> bool + is-same-object: func(this: descriptor, other: descriptor) -> bool /// Return a hash of the metadata associated with a filesystem object referred /// to by a descriptor. @@ -823,13 +823,16 @@ interface types { /// computed hash. /// /// However, none of these is required. - metadata-hash: func() -> result + metadata-hash: func( + this: descriptor, + ) -> result /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. metadata-hash-at: func( + this: descriptor, /// Flags determining the method of how the path is resolved. path-flags: path-flags, /// The relative path of the file or directory to inspect. From 6fc03d70cd23efff1e14978ea4bea40e7ee79602 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 3 Aug 2023 14:53:56 -0700 Subject: [PATCH 1189/1772] wit-deps update --- proposals/cli/wit/deps.lock | 20 ++-- .../cli/wit/deps/filesystem/preopens.wit | 6 ++ proposals/cli/wit/deps/filesystem/types.wit | 100 +++++++++++++----- proposals/cli/wit/deps/filesystem/world.wit | 1 + proposals/cli/wit/deps/io/streams.wit | 37 ++++--- proposals/cli/wit/deps/poll/poll.wit | 24 +++-- proposals/cli/wit/deps/random/random.wit | 24 +++-- proposals/cli/wit/deps/sockets/udp.wit | 25 +++-- 8 files changed, 162 insertions(+), 75 deletions(-) create mode 100644 proposals/cli/wit/deps/filesystem/preopens.wit diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index 25030d173..2ee3e4983 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -5,25 +5,25 @@ sha512 = "ef1e23704a8a8436fd3718593d4c4d8b6d1c64dad3595b7496c0888ca14b725046f290 [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "a19dbd57208ef649980bb4088b96606fe3549e580574dc88dafed6f8a8537b01" -sha512 = "49a798126feeb1a714162a20d282e554c70d36cbfa827dfb54685577b13d584fa15e02fd653fbb940a4fa52cece6c0ca4d7cd85f27c041a5cc99a98392d03e50" +sha256 = "dc170645d8aa52f2f94ab8f71093fa0c101e509ed1a07318995dc0395e9d6cf2" +sha512 = "3195a3e0f9ec52c3a91c4b4fde0547694236c7b29bceecb7f38634894fafd809c69ed1c1c9acbf225b2d5d00f5036d70371c9fed121d85028162b202035cabef" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "eeb4701c2becafa40a7ee3bf0d2c94e2170e15806b25abdcd1de1ed94f2c1036" -sha512 = "89be853b2acae211570cd6ad0ec9d8132881dafbdea83ac7b4cad600f0627003c61f310427379bf47ecf862724367bd5d6e976db70069f6f90a3c2d9c20dbfb7" +sha256 = "6e18239b0e20d1a3e6343cb961ebfd2c663ba7feb4c1aa3744b756fbdd1fb5b8" +sha512 = "53169b6e4fba0b2cf5fcf808f76e7fbb7cabb6ed66ab53f77d0966e7448312ccbe8571880ef4fc2ee86fbd6ba19bc48d46e10d22dcac6c51d217e8d7127c32db" [poll] url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -sha256 = "9f8bb4d9994e9b0684859bb1e8bee2a8b873e04d40695f260446760fc44d0c58" -sha512 = "aa8da395ba6e189ec113296996da5abf28bdc4460e4eb2aacc786698ced892e08f7054fb590fc8809c05554d5c83a11494d4ab68c755746f57d151e212415cfb" +sha256 = "d4c27124f4c137eb538b5c92ba5858ed9042e11b24a2eef85d14becd0b7f55de" +sha512 = "422c01b273b4b1377ece6f2e4ba0dfc609ca8ef30a3e0be0e172e1303fcf7b3ca4c470f4dea6c51bdf114b0f5c871ebc4934dfe3bf217d66ea689748df2b1e55" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "30731531ec3453813d08765b428f34aec34ac343cbeafd9885e4e348d187ae04" -sha512 = "6656089f9297ee56cf58c2f95c466e3a22c371925404e6eb9cb5adcb37c1b92f27aaf8c2f9e690ac53ef12f90bd31ac64a84d5f5e06d3f06e24997478275327f" +sha256 = "9b622463e597b9ca94f41e4eaae589a77be38f71b4723142b60246ffed8eaae4" +sha512 = "21f03ca1e595b80d7ced522de1a47446526b49b900e2fb26fcbf410ce6aa267dbf247aebf3fbfa8123b46fc1a828e2fd64fb1e0198b40161a3257e8d86fd4546" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "30c07587eda24676185f175323d5195817b5678815a3f6b64b8152a5b7532493" -sha512 = "8965e112c323e4535786361d864d3b5020791ce7e48da20a6a6b9a1fbec1f78bc10e0830c640f704bd8132fada56cd8a19b48e11e60ec6d9191c08e00550c91c" +sha256 = "871c211b12d87a5da87c42353338b652260840897efcd37e2afba3b9290058fc" +sha512 = "e436a5ff3145ca85d702a086499c03488523483dd3addc8d71e4946e9c186355291551bb6d38b157173836fcc318182403e6dba970de4512f6cfb3374ccad6b9" diff --git a/proposals/cli/wit/deps/filesystem/preopens.wit b/proposals/cli/wit/deps/filesystem/preopens.wit new file mode 100644 index 000000000..f45661b8a --- /dev/null +++ b/proposals/cli/wit/deps/filesystem/preopens.wit @@ -0,0 +1,6 @@ +interface preopens { + use types.{descriptor} + + /// Return the set of preopened directories, and their path. + get-directories: func() -> list> +} diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index 627b638ef..a437f22ae 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -102,10 +102,6 @@ interface types { /// /// Note: This was called `filestat` in earlier versions of WASI. record descriptor-stat { - /// Device ID of device containing the file. - device: device, - /// File serial number. - inode: inode, /// File type. %type: descriptor-type, /// Number of hard links to the file. @@ -166,14 +162,6 @@ interface types { /// Number of hard links to an inode. type link-count = u64 - /// Identifier for a device containing a file system. Can be used in - /// combination with `inode` to uniquely identify a file or directory in - /// the filesystem. - type device = u64 - - /// Filesystem object serial number that is unique within its file system. - type inode = u64 - /// When setting a timestamp, this gives the value to set it to. variant new-timestamp { /// Leave the timestamp set to its previous value. @@ -187,14 +175,6 @@ interface types { /// A directory entry. record directory-entry { - /// The serial number of the object referred to by this directory entry. - /// May be none if the inode value is not known. - /// - /// When this is none, libc implementations might do an extra `stat-at` - /// call to retrieve the inode number to fill their `d_ino` fields, so - /// implementations which can set this to a non-none value should do so. - inode: option, - /// The type of the file referred to by this directory entry. %type: descriptor-type, @@ -312,7 +292,18 @@ interface types { /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). type descriptor = u32 - /// Return a stream for reading from a file. + /// A 128-bit hash value, split into parts because wasm doesn't have a + /// 128-bit integer type. + record metadata-hash-value { + /// 64 bits of a 128-bit hash value. + lower: u64, + /// Another 64 bits of a 128-bit hash value. + upper: u64, + } + + /// Return a stream for reading from a file, if available. + /// + /// May fail with an error-code describing why the file cannot be read. /// /// Multiple read, write, and append streams may be active on the same open /// file and they do not interfere with each other. @@ -322,9 +313,11 @@ interface types { this: descriptor, /// The offset within the file at which to start reading. offset: filesize, - ) -> input-stream + ) -> result - /// Return a stream for writing to a file. + /// Return a stream for writing to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be written. /// /// Note: This allows using `write-stream`, which is similar to `write` in /// POSIX. @@ -332,15 +325,17 @@ interface types { this: descriptor, /// The offset within the file at which to start writing. offset: filesize, - ) -> output-stream + ) -> result - /// Return a stream for appending to a file. + /// Return a stream for appending to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be appended. /// /// Note: This allows using `write-stream`, which is similar to `write` with /// `O_APPEND` in in POSIX. append-via-stream: func( this: descriptor, - ) -> output-stream + ) -> result /// Provide file advisory information on a descriptor. /// @@ -479,14 +474,20 @@ interface types { /// Return the attributes of an open file or directory. /// - /// Note: This is similar to `fstat` in POSIX. + /// Note: This is similar to `fstat` in POSIX, except that it does not return + /// device and inode information. For testing whether two descriptors refer to + /// the same underlying filesystem object, use `is-same-object`. To obtain + /// additional data that can be used do determine whether a file has been + /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. stat: func(this: descriptor) -> result /// Return the attributes of a file or directory. /// - /// Note: This is similar to `fstatat` in POSIX. + /// Note: This is similar to `fstatat` in POSIX, except that it does not + /// return device and inode information. See the `stat` description for a + /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. stat-at: func( @@ -794,4 +795,47 @@ interface types { /// Dispose of the specified `directory-entry-stream`, after which it may no longer /// be used. drop-directory-entry-stream: func(this: directory-entry-stream) + + /// Test whether two descriptors refer to the same filesystem object. + /// + /// In POSIX, this corresponds to testing whether the two descriptors have the + /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. + /// wasi-filesystem does not expose device and inode numbers, so this function + /// may be used instead. + is-same-object: func(this: descriptor, other: descriptor) -> bool + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a descriptor. + /// + /// This returns a hash of the last-modification timestamp and file size, and + /// may also include the inode number, device number, birth timestamp, and + /// other metadata fields that may change when the file is modified or + /// replaced. It may also include a secret value chosen by the + /// implementation and not otherwise exposed. + /// + /// Implementations are encourated to provide the following properties: + /// + /// - If the file is not modified or replaced, the computed hash value should + /// usually not change. + /// - If the object is modified or replaced, the computed hash value should + /// usually change. + /// - The inputs to the hash should not be easily computable from the + /// computed hash. + /// + /// However, none of these is required. + metadata-hash: func( + this: descriptor, + ) -> result + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a directory descriptor and a relative path. + /// + /// This performs the same hash computation as `metadata-hash`. + metadata-hash-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result } diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit index f2ef782f4..b51f484f8 100644 --- a/proposals/cli/wit/deps/filesystem/world.wit +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -2,4 +2,5 @@ package wasi:filesystem world example-world { import types + import preopens } diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index 430c1d441..de8694bda 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -10,6 +10,19 @@ interface streams { /// doesn't provide any additional information. record stream-error {} + /// Streams provide a sequence of data and then end; once they end, they + /// no longer provide any further data. + /// + /// For example, a stream reading from a file ends when the stream reaches + /// the end of the file. For another example, a stream reading from a + /// socket ends when the socket is closed. + enum stream-status { + /// The stream is open and may produce further data. + open, + /// The stream has ended and will not produce any further data. + ended, + } + /// An input bytestream. In the future, this will be replaced by handle /// types. /// @@ -32,9 +45,9 @@ interface streams { /// Read bytes from a stream. /// /// This function returns a list of bytes containing the data that was - /// read, along with a bool which, when true, indicates that the end of the - /// stream was reached. The returned list will contain up to `len` bytes; it - /// may return fewer than requested, but not more. + /// read, along with a `stream-status` which indicates whether the end of + /// the stream was reached. The returned list will contain up to `len` + /// bytes; it may return fewer than requested, but not more. /// /// Once a stream has reached the end, subsequent calls to read or /// `skip` will always report end-of-stream rather than producing more @@ -51,7 +64,7 @@ interface streams { this: input-stream, /// The maximum number of bytes to read len: u64 - ) -> result, bool>, stream-error> + ) -> result, stream-status>, stream-error> /// Read bytes from a stream, with blocking. /// @@ -61,7 +74,7 @@ interface streams { this: input-stream, /// The maximum number of bytes to read len: u64 - ) -> result, bool>, stream-error> + ) -> result, stream-status>, stream-error> /// Skip bytes from a stream. /// @@ -72,14 +85,14 @@ interface streams { /// `skip` will always report end-of-stream rather than producing more /// data. /// - /// This function returns the number of bytes skipped, along with a bool - /// indicating whether the end of the stream was reached. The returned - /// value will be at most `len`; it may be less. + /// This function returns the number of bytes skipped, along with a + /// `stream-status` indicating whether the end of the stream was + /// reached. The returned value will be at most `len`; it may be less. skip: func( this: input-stream, /// The maximum number of bytes to skip. len: u64, - ) -> result, stream-error> + ) -> result, stream-error> /// Skip bytes from a stream, with blocking. /// @@ -89,7 +102,7 @@ interface streams { this: input-stream, /// The maximum number of bytes to skip. len: u64, - ) -> result, stream-error> + ) -> result, stream-error> /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been @@ -172,7 +185,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result, stream-error> + ) -> result, stream-error> /// Read from one stream and write to another, with blocking. /// @@ -184,7 +197,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result, stream-error> + ) -> result, stream-error> /// Forward the entire contents of an input stream to an output stream. /// diff --git a/proposals/cli/wit/deps/poll/poll.wit b/proposals/cli/wit/deps/poll/poll.wit index 55eee0029..fa82b6063 100644 --- a/proposals/cli/wit/deps/poll/poll.wit +++ b/proposals/cli/wit/deps/poll/poll.wit @@ -23,17 +23,27 @@ interface poll { /// Poll for completion on a set of pollables. /// + /// This function takes a list of pollables, which identify I/O sources of + /// interest, and waits until one or more of the events is ready for I/O. + /// + /// The result `list` is the same length as the argument + /// `list`, and indicates the readiness of each corresponding + /// element in that list, with true indicating ready. A single call can + /// return multiple true elements. + /// + /// A timeout can be implemented by adding a pollable from the + /// wasi-clocks API to the list. + /// + /// This function does not return a `result`; polling in itself does not + /// do any I/O so it doesn't fail. If any of the I/O sources identified by + /// the pollables has an error, it is indicated by marking the source as + /// ready in the `list`. + /// /// The "oneoff" in the name refers to the fact that this function must do a /// linear scan through the entire list of subscriptions, which may be /// inefficient if the number is large and the same subscriptions are used /// many times. In the future, this is expected to be obsoleted by the /// component model async proposal, which will include a scalable waiting /// facility. - /// - /// Note that the return type would ideally be `list`, but that would - /// be more difficult to polyfill given the current state of `wit-bindgen`. - /// See - /// for details. For now, we use zero to mean "not ready" and non-zero to - /// mean "ready". - poll-oneoff: func(in: list) -> list + poll-oneoff: func(in: list) -> list } diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index e4238621e..2a282dab7 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -3,21 +3,23 @@ /// It is intended to be portable at least between Unix-family platforms and /// Windows. interface random { - /// Return `len` cryptographically-secure pseudo-random bytes. + /// Return `len` cryptographically-secure random or pseudo-random bytes. /// - /// This function must produce data from an adequately seeded - /// cryptographically-secure pseudo-random number generator (CSPRNG), so it - /// must not block, from the perspective of the calling program, and the - /// returned data is always unpredictable. + /// This function must produce data at least as cryptographically secure and + /// fast as an adequately seeded cryptographically-secure pseudo-random + /// number generator (CSPRNG). It must not block, from the perspective of + /// the calling program, under any circumstances, including on the first + /// request and on requests for numbers of bytes. The returned data must + /// always be unpredictable. /// - /// This function must always return fresh pseudo-random data. Deterministic - /// environments must omit this function, rather than implementing it with - /// deterministic data. + /// This function must always return fresh data. Deterministic environments + /// must omit this function, rather than implementing it with deterministic + /// data. get-random-bytes: func(len: u64) -> list - /// Return a cryptographically-secure pseudo-random `u64` value. + /// Return a cryptographically-secure random or pseudo-random `u64` value. /// - /// This function returns the same type of pseudo-random data as - /// `get-random-bytes`, represented as a `u64`. + /// This function returns the same type of data as `get-random-bytes`, + /// represented as a `u64`. get-random-u64: func() -> u64 } diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index 3a0c1bd14..948ed581a 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -84,11 +84,11 @@ interface udp { start-connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> finish-connect: func(this: udp-socket) -> result<_, error-code> - /// Receive a message. + /// Receive messages on the socket. /// - /// Returns: - /// - The sender address of the datagram - /// - The number of bytes read. + /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. + /// The returned list may contain fewer elements than requested, but never more. + /// If `max-results` is 0, this function returns successfully with an empty list. /// /// # Typical errors /// - `not-bound`: The socket is not bound to any local address. (EINVAL) @@ -99,13 +99,23 @@ interface udp { /// - /// - /// - + /// - /// - /// - /// - /// - - receive: func(this: udp-socket) -> result + receive: func(this: udp-socket, max-results: u64) -> result, error-code> - /// Send a message to a specific destination address. + /// Send messages on the socket. + /// + /// This function attempts to send all provided `datagrams` on the socket without blocking and + /// returns how many messages were actually sent (or queued for sending). + /// + /// This function semantically behaves the same as iterating the `datagrams` list and sequentially + /// sending each individual datagram until either the end of the list has been reached or the first error occurred. + /// If at least one datagram has been sent successfully, this function never returns an error. + /// + /// If the input list is empty, the function returns `ok(0)`. /// /// The remote address option is required. To send a message to the "connected" peer, /// call `remote-address` to get their address. @@ -124,11 +134,12 @@ interface udp { /// - /// - /// - + /// - /// - /// - /// - /// - - send: func(this: udp-socket, datagram: datagram) -> result<_, error-code> + send: func(this: udp-socket, datagrams: list) -> result /// Get the current bound address. /// From 8b43de28f1ed302959a660c9c7ae5812761c8e49 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 3 Aug 2023 14:56:02 -0700 Subject: [PATCH 1190/1772] delete preopens interface, replace with wasi:filesystem/preopens wasi:filesystem/preopens is where the get-directories part of preopens has moved to. the initial-cwd function in preopens needed a new home, so I put it in environment, because it seems morally similar enough. --- proposals/cli/command.md | 269 +++++++++++++++++++----------- proposals/cli/wit/command.wit | 2 +- proposals/cli/wit/environment.wit | 4 + proposals/cli/wit/preopens.wit | 11 -- 4 files changed, 180 insertions(+), 106 deletions(-) delete mode 100644 proposals/cli/wit/preopens.wit diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 646c04917..e918f51ad 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -8,6 +8,7 @@
      • interface wasi:clocks/timezone
      • interface wasi:io/streams
      • interface wasi:filesystem/types
      • +
      • interface wasi:filesystem/preopens
      • interface wasi:sockets/network
      • interface wasi:sockets/instance-network
      • interface wasi:sockets/ip-name-lookup
      • @@ -19,7 +20,6 @@
      • interface wasi:random/insecure
      • interface wasi:random/insecure-seed
      • interface wasi:cli/environment
      • -
      • interface wasi:cli/preopens
      • interface wasi:cli/exit
      • interface wasi:cli/stdin
      • interface wasi:cli/stdout
      • @@ -101,24 +101,31 @@ be used.

      poll-oneoff: func

      Poll for completion on a set of pollables.

      +

      This function takes a list of pollables, which identify I/O sources of +interest, and waits until one or more of the events is ready for I/O.

      +

      The result list<bool> is the same length as the argument +list<pollable>, and indicates the readiness of each corresponding +element in that list, with true indicating ready. A single call can +return multiple true elements.

      +

      A timeout can be implemented by adding a pollable from the +wasi-clocks API to the list.

      +

      This function does not return a result; polling in itself does not +do any I/O so it doesn't fail. If any of the I/O sources identified by +the pollables has an error, it is indicated by marking the source as +ready in the list<bool>.

      The "oneoff" in the name refers to the fact that this function must do a linear scan through the entire list of subscriptions, which may be inefficient if the number is large and the same subscriptions are used many times. In the future, this is expected to be obsoleted by the component model async proposal, which will include a scalable waiting facility.

      -

      Note that the return type would ideally be list<bool>, but that would -be more difficult to polyfill given the current state of wit-bindgen. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 -for details. For now, we use zero to mean "not ready" and non-zero to -mean "ready".

      Params
      Return values
        -
      • list<u8>
      • +
      • list<bool>

      Import interface wasi:clocks/monotonic-clock

      WASI Monotonic Clock is a clock API intended to let users measure elapsed @@ -255,7 +262,24 @@ when it does, they are expected to subsume this API.

      type pollable

      pollable

      -#### `record stream-error` +#### `enum stream-status` +

      Streams provide a sequence of data and then end; once they end, they +no longer provide any further data.

      +

      For example, a stream reading from a file ends when the stream reaches +the end of the file. For another example, a stream reading from a +socket ends when the socket is closed.

      +
      Enum Cases
      +
        +
      • +

        open

        +

        The stream is open and may produce further data. +

      • +
      • +

        ended

        +

        The stream has ended and will not produce any further data. +

      • +
      +

      record stream-error

      An error type returned from a stream operation. Currently this doesn't provide any additional information.

      Record Fields
      @@ -294,9 +318,9 @@ the wit-bindgen implementation of handles and resources is ready.

      read: func

      Read bytes from a stream.

      This function returns a list of bytes containing the data that was -read, along with a bool which, when true, indicates that the end of the -stream was reached. The returned list will contain up to len bytes; it -may return fewer than requested, but not more.

      +read, along with a stream-status which indicates whether the end of +the stream was reached. The returned list will contain up to len +bytes; it may return fewer than requested, but not more.

      Once a stream has reached the end, subsequent calls to read or skip will always report end-of-stream rather than producing more data.

      @@ -313,7 +337,7 @@ FIXME: describe what happens if allocation fails.

    Return values

    blocking-read: func

    Read bytes from a stream, with blocking.

    @@ -326,7 +350,7 @@ byte can be read.

    Return values

    skip: func

    Skip bytes from a stream.

    @@ -335,9 +359,9 @@ bytes into the instance.

    Once a stream has reached the end, subsequent calls to read or skip will always report end-of-stream rather than producing more data.

    -

    This function returns the number of bytes skipped, along with a bool -indicating whether the end of the stream was reached. The returned -value will be at most len; it may be less.

    +

    This function returns the number of bytes skipped, along with a +stream-status indicating whether the end of the stream was +reached. The returned value will be at most len; it may be less.

    Params
    • this: input-stream
    • @@ -345,7 +369,7 @@ value will be at most len; it may be less.

    Return values

    blocking-skip: func

    Skip bytes from a stream, with blocking.

    @@ -358,7 +382,7 @@ byte can be consumed.

    Return values

    subscribe-to-input-stream: func

    Create a pollable which will resolve once either the specified stream @@ -445,7 +469,7 @@ read from the input stream has been written to the output stream.

    Return values

    blocking-splice: func

    Read from one stream and write to another, with blocking.

    @@ -459,7 +483,7 @@ one byte can be read.

    Return values

    forward: func

    Forward the entire contents of an input stream to an output stream.

    @@ -574,12 +598,23 @@ filesystem. filesystem. This does not apply to directories. +

    record metadata-hash-value

    +

    A 128-bit hash value, split into parts because wasm doesn't have a +128-bit integer type.

    +
    Record Fields
    +
      +
    • +

      lower: u64

      +

      64 bits of a 128-bit hash value. +

    • +
    • +

      upper: u64

      +

      Another 64 bits of a 128-bit hash value. +

    • +

    type link-count

    u64

    Number of hard links to an inode. -

    type inode

    -

    u64

    -

    Filesystem object serial number that is unique within its file system.

    type filesize

    u64

    File size or length of a region within a file. @@ -743,11 +778,6 @@ merely for alignment with POSIX.

    u32

    A stream of directory entries.

    This represents a stream of dir-entry.

    -

    type device

    -

    u64

    -

    Identifier for a device containing a file system. Can be used in -combination with `inode` to uniquely identify a file or directory in -the filesystem.

    enum descriptor-type

    The type of a filesystem object referenced by a descriptor.

    Note: This was called filetype in earlier versions of WASI.

    @@ -792,14 +822,6 @@ any of the other types specified.
    Record Fields
    • -

      inode: option<inode>

      -

      The serial number of the object referred to by this directory entry. -May be none if the inode value is not known. -

      When this is none, libc implementations might do an extra stat-at -call to retrieve the inode number to fill their d_ino fields, so -implementations which can set this to a non-none value should do so.

      -
    • -
    • type: descriptor-type

      The type of the file referred to by this directory entry.

    • @@ -897,14 +919,6 @@ with the filesystem.
      Record Fields
      • -

        device: device

        -

        Device ID of device containing the file. -

      • -
      • -

        inode: inode

        -

        File serial number. -

      • -
      • type: descriptor-type

        File type.

      • @@ -981,7 +995,8 @@ not reuse it thereafter.

        Functions

        read-via-stream: func

        -

        Return a stream for reading from a file.

        +

        Return a stream for reading from a file, if available.

        +

        May fail with an error-code describing why the file cannot be read.

        Multiple read, write, and append streams may be active on the same open file and they do not interfere with each other.

        Note: This allows using read-stream, which is similar to read in POSIX.

        @@ -992,10 +1007,11 @@ file and they do not interfere with each other.

      Return values

      write-via-stream: func

      -

      Return a stream for writing to a file.

      +

      Return a stream for writing to a file, if available.

      +

      May fail with an error-code describing why the file cannot be written.

      Note: This allows using write-stream, which is similar to write in POSIX.

      Params
      @@ -1005,10 +1021,11 @@ POSIX.

    Return values

    append-via-stream: func

    -

    Return a stream for appending to a file.

    +

    Return a stream for appending to a file, if available.

    +

    May fail with an error-code describing why the file cannot be appended.

    Note: This allows using write-stream, which is similar to write with O_APPEND in in POSIX.

    Params
    @@ -1017,7 +1034,7 @@ POSIX.

    Return values

    advise: func

    Provide file advisory information on a descriptor.

    @@ -1195,7 +1212,11 @@ opened for writing.

    stat: func

    Return the attributes of an open file or directory.

    -

    Note: This is similar to fstat in POSIX.

    +

    Note: This is similar to fstat in POSIX, except that it does not return +device and inode information. For testing whether two descriptors refer to +the same underlying filesystem object, use is-same-object. To obtain +additional data that can be used do determine whether a file has been +modified, use metadata-hash.

    Note: This was called fd_filestat_get in earlier versions of WASI.

    Params
      @@ -1207,7 +1228,9 @@ opened for writing.

    stat-at: func

    Return the attributes of a file or directory.

    -

    Note: This is similar to fstatat in POSIX.

    +

    Note: This is similar to fstatat in POSIX, except that it does not +return device and inode information. See the stat description for a +discussion of alternatives.

    Note: This was called path_filestat_get in earlier versions of WASI.

    Params
      @@ -1531,6 +1554,75 @@ be used.

      +

      is-same-object: func

      +

      Test whether two descriptors refer to the same filesystem object.

      +

      In POSIX, this corresponds to testing whether the two descriptors have the +same device (st_dev) and inode (st_ino or d_ino) numbers. +wasi-filesystem does not expose device and inode numbers, so this function +may be used instead.

      +
      Params
      + +
      Return values
      +
        +
      • bool
      • +
      +

      metadata-hash: func

      +

      Return a hash of the metadata associated with a filesystem object referred +to by a descriptor.

      +

      This returns a hash of the last-modification timestamp and file size, and +may also include the inode number, device number, birth timestamp, and +other metadata fields that may change when the file is modified or +replaced. It may also include a secret value chosen by the +implementation and not otherwise exposed.

      +

      Implementations are encourated to provide the following properties:

      +
        +
      • If the file is not modified or replaced, the computed hash value should +usually not change.
      • +
      • If the object is modified or replaced, the computed hash value should +usually change.
      • +
      • The inputs to the hash should not be easily computable from the +computed hash.
      • +
      +

      However, none of these is required.

      +
      Params
      + +
      Return values
      + +

      metadata-hash-at: func

      +

      Return a hash of the metadata associated with a filesystem object referred +to by a directory descriptor and a relative path.

      +

      This performs the same hash computation as metadata-hash.

      +
      Params
      + +
      Return values
      + +

      Import interface wasi:filesystem/preopens

      +
      +

      Types

      +

      type descriptor

      +

      descriptor

      +

      +---- +

      Functions

      +

      get-directories: func

      +

      Return the set of preopened directories, and their path.

      +
      Return values
      +

      Import interface wasi:sockets/network


      Types

      @@ -2539,12 +2631,10 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    • result<_, error-code>

    receive: func

    -

    Receive a message.

    -

    Returns:

    -
      -
    • The sender address of the datagram
    • -
    • The number of bytes read.
    • -
    +

    Receive messages on the socket.

    +

    This function attempts to receive up to max-results datagrams on the socket without blocking. +The returned list may contain fewer elements than requested, but never more. +If max-results is 0, this function returns successfully with an empty list.

    Typical errors

    • not-bound: The socket is not bound to any local address. (EINVAL)
    • @@ -2556,6 +2646,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    • https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html
    • https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html
    • https://man7.org/linux/man-pages/man2/recv.2.html
    • +
    • https://man7.org/linux/man-pages/man2/recvmmsg.2.html
    • https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recv
    • https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recvfrom
    • https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms741687(v=vs.85)
    • @@ -2564,13 +2655,20 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

      Params
      Return values

      send: func

      -

      Send a message to a specific destination address.

      +

      Send messages on the socket.

      +

      This function attempts to send all provided datagrams on the socket without blocking and +returns how many messages were actually sent (or queued for sending).

      +

      This function semantically behaves the same as iterating the datagrams list and sequentially +sending each individual datagram until either the end of the list has been reached or the first error occurred. +If at least one datagram has been sent successfully, this function never returns an error.

      +

      If the input list is empty, the function returns ok(0).

      The remote address option is required. To send a message to the "connected" peer, call remote-address to get their address.

      Typical errors

      @@ -2589,6 +2687,7 @@ call remote-address to get their addr
    • https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html
    • https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html
    • https://man7.org/linux/man-pages/man2/send.2.html
    • +
    • https://man7.org/linux/man-pages/man2/sendmmsg.2.html
    • https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-send
    • https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto
    • https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasendmsg
    • @@ -2597,11 +2696,11 @@ call remote-address to get their addr
      Params
      Return values

      local-address: func

      Get the current bound address.

      @@ -2829,14 +2928,16 @@ Windows.


      Functions

      get-random-bytes: func

      -

      Return len cryptographically-secure pseudo-random bytes.

      -

      This function must produce data from an adequately seeded -cryptographically-secure pseudo-random number generator (CSPRNG), so it -must not block, from the perspective of the calling program, and the -returned data is always unpredictable.

      -

      This function must always return fresh pseudo-random data. Deterministic -environments must omit this function, rather than implementing it with -deterministic data.

      +

      Return len cryptographically-secure random or pseudo-random bytes.

      +

      This function must produce data at least as cryptographically secure and +fast as an adequately seeded cryptographically-secure pseudo-random +number generator (CSPRNG). It must not block, from the perspective of +the calling program, under any circumstances, including on the first +request and on requests for numbers of bytes. The returned data must +always be unpredictable.

      +

      This function must always return fresh data. Deterministic environments +must omit this function, rather than implementing it with deterministic +data.

      Params
      • len: u64
      • @@ -2846,9 +2947,9 @@ deterministic data.

      • list<u8>

      get-random-u64: func

      -

      Return a cryptographically-secure pseudo-random u64 value.

      -

      This function returns the same type of pseudo-random data as -get-random-bytes, represented as a u64.

      +

      Return a cryptographically-secure random or pseudo-random u64 value.

      +

      This function returns the same type of data as get-random-bytes, +represented as a u64.

      Return values
      • u64
      • @@ -2926,26 +3027,6 @@ values each time it is called.

        • list<string>
        -

        Import interface wasi:cli/preopens

        -
        -

        Types

        -

        type descriptor

        -

        descriptor

        -

        -#### `type input-stream` -[`input-stream`](#input_stream) -

        -#### `type output-stream` -[`output-stream`](#output_stream) -

        ----- -

        Functions

        -

        get-directories: func

        -

        Return the set of of preopened directories, and their path.

        -
        Return values
        -

        initial-cwd: func

        Return a path that programs should use as their initial current working directory, interpreting . as shorthand for this.

        @@ -2957,7 +3038,7 @@ directory, interpreting . as shorthand for this.


        Functions

        exit: func

        -

        Exit the curerent instance and any linked instances.

        +

        Exit the current instance and any linked instances.

        Params
        • status: result
        • diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index 13675f180..a791b6bea 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -5,6 +5,7 @@ world command { import wasi:clocks/monotonic-clock import wasi:clocks/timezone import wasi:filesystem/types + import wasi:filesystem/preopens import wasi:sockets/instance-network import wasi:sockets/ip-name-lookup import wasi:sockets/network @@ -18,7 +19,6 @@ world command { import wasi:poll/poll import wasi:io/streams import environment - import preopens import exit import stdin import stdout diff --git a/proposals/cli/wit/environment.wit b/proposals/cli/wit/environment.wit index 65471e86d..36790fe71 100644 --- a/proposals/cli/wit/environment.wit +++ b/proposals/cli/wit/environment.wit @@ -11,4 +11,8 @@ interface environment { /// Get the POSIX-style arguments to the program. get-arguments: func() -> list + + /// Return a path that programs should use as their initial current working + /// directory, interpreting `.` as shorthand for this. + initial-cwd: func() -> option } diff --git a/proposals/cli/wit/preopens.wit b/proposals/cli/wit/preopens.wit deleted file mode 100644 index 637102878..000000000 --- a/proposals/cli/wit/preopens.wit +++ /dev/null @@ -1,11 +0,0 @@ -interface preopens { - use wasi:filesystem/types.{descriptor} - use wasi:io/streams.{input-stream, output-stream} - - /// Return the set of of preopened directories, and their path. - get-directories: func() -> list> - - /// Return a path that programs should use as their initial current working - /// directory, interpreting `.` as shorthand for this. - initial-cwd: func() -> option -} From fea6c2c1fda55b891f07179f300f8f11fd449814 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 3 Aug 2023 16:08:25 -0700 Subject: [PATCH 1191/1772] command world: provide imports of terminal-std{in, out, err} (#20) these interfaces were added to the package as part of https://github.com/WebAssembly/wasi-cli/pull/9, but they aren't exposed as imports in the command world. This PR adds them to the command world. --- proposals/cli/command.md | 90 ++++++++++++++++++++++++++++++++++- proposals/cli/wit/command.wit | 5 ++ 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 646c04917..99cd18637 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -24,6 +24,11 @@
        • interface wasi:cli/stdin
        • interface wasi:cli/stdout
        • interface wasi:cli/stderr
        • +
        • interface wasi:cli/terminal-input
        • +
        • interface wasi:cli/terminal-output
        • +
        • interface wasi:cli/terminal-stdin
        • +
        • interface wasi:cli/terminal-stdout
        • +
        • interface wasi:cli/terminal-stderr
      • Exports: @@ -2957,7 +2962,7 @@ directory, interpreting . as shorthand for this.


        Functions

        exit: func

        -

        Exit the curerent instance and any linked instances.

        +

        Exit the current instance and any linked instances.

        Params

        poll-oneoff: func

        Poll for completion on a set of pollables.

        +

        This function takes a list of pollables, which identify I/O sources of +interest, and waits until one or more of the events is ready for I/O.

        +

        The result list<bool> is the same length as the argument +list<pollable>, and indicates the readiness of each corresponding +element in that list, with true indicating ready. A single call can +return multiple true elements.

        +

        A timeout can be implemented by adding a pollable from the +wasi-clocks API to the list.

        +

        This function does not return a result; polling in itself does not +do any I/O so it doesn't fail. If any of the I/O sources identified by +the pollables has an error, it is indicated by marking the source as +ready in the list<bool>.

        The "oneoff" in the name refers to the fact that this function must do a linear scan through the entire list of subscriptions, which may be inefficient if the number is large and the same subscriptions are used many times. In the future, this is expected to be obsoleted by the component model async proposal, which will include a scalable waiting facility.

        -

        Note that the return type would ideally be list<bool>, but that would -be more difficult to polyfill given the current state of wit-bindgen. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 -for details. For now, we use zero to mean "not ready" and non-zero to -mean "ready".

        Params
        Return values
          -
        • list<u8>
        • +
        • list<bool>

        Import interface wasi:clocks/monotonic-clock

        WASI Monotonic Clock is a clock API intended to let users measure elapsed @@ -241,14 +248,16 @@ Windows.


        Functions

        get-random-bytes: func

        -

        Return len cryptographically-secure pseudo-random bytes.

        -

        This function must produce data from an adequately seeded -cryptographically-secure pseudo-random number generator (CSPRNG), so it -must not block, from the perspective of the calling program, and the -returned data is always unpredictable.

        -

        This function must always return fresh pseudo-random data. Deterministic -environments must omit this function, rather than implementing it with -deterministic data.

        +

        Return len cryptographically-secure random or pseudo-random bytes.

        +

        This function must produce data at least as cryptographically secure and +fast as an adequately seeded cryptographically-secure pseudo-random +number generator (CSPRNG). It must not block, from the perspective of +the calling program, under any circumstances, including on the first +request and on requests for numbers of bytes. The returned data must +always be unpredictable.

        +

        This function must always return fresh data. Deterministic environments +must omit this function, rather than implementing it with deterministic +data.

        Params
        • len: u64
        • @@ -258,9 +267,9 @@ deterministic data.

        • list<u8>

        get-random-u64: func

        -

        Return a cryptographically-secure pseudo-random u64 value.

        -

        This function returns the same type of pseudo-random data as -get-random-bytes, represented as a u64.

        +

        Return a cryptographically-secure random or pseudo-random u64 value.

        +

        This function returns the same type of data as get-random-bytes, +represented as a u64.

        Return values
        • u64
        • @@ -275,7 +284,24 @@ when it does, they are expected to subsume this API.

          type pollable

          pollable

          -#### `record stream-error` +#### `enum stream-status` +

          Streams provide a sequence of data and then end; once they end, they +no longer provide any further data.

          +

          For example, a stream reading from a file ends when the stream reaches +the end of the file. For another example, a stream reading from a +socket ends when the socket is closed.

          +
          Enum Cases
          +
            +
          • +

            open

            +

            The stream is open and may produce further data. +

          • +
          • +

            ended

            +

            The stream has ended and will not produce any further data. +

          • +
          +

          record stream-error

          An error type returned from a stream operation. Currently this doesn't provide any additional information.

          Record Fields
          @@ -314,9 +340,9 @@ the wit-bindgen implementation of handles and resources is ready.

          read: func

          Read bytes from a stream.

          This function returns a list of bytes containing the data that was -read, along with a bool which, when true, indicates that the end of the -stream was reached. The returned list will contain up to len bytes; it -may return fewer than requested, but not more.

          +read, along with a stream-status which indicates whether the end of +the stream was reached. The returned list will contain up to len +bytes; it may return fewer than requested, but not more.

          Once a stream has reached the end, subsequent calls to read or skip will always report end-of-stream rather than producing more data.

          @@ -333,7 +359,7 @@ FIXME: describe what happens if allocation fails.

        Return values

        blocking-read: func

        Read bytes from a stream, with blocking.

        @@ -346,7 +372,7 @@ byte can be read.

      Return values

      skip: func

      Skip bytes from a stream.

      @@ -355,9 +381,9 @@ bytes into the instance.

      Once a stream has reached the end, subsequent calls to read or skip will always report end-of-stream rather than producing more data.

      -

      This function returns the number of bytes skipped, along with a bool -indicating whether the end of the stream was reached. The returned -value will be at most len; it may be less.

      +

      This function returns the number of bytes skipped, along with a +stream-status indicating whether the end of the stream was +reached. The returned value will be at most len; it may be less.

      Params
      • this: input-stream
      • @@ -365,7 +391,7 @@ value will be at most len; it may be less.

      Return values

      blocking-skip: func

      Skip bytes from a stream, with blocking.

      @@ -378,7 +404,7 @@ byte can be consumed.

    Return values

    subscribe-to-input-stream: func

    Create a pollable which will resolve once either the specified stream @@ -465,7 +491,7 @@ read from the input stream has been written to the output stream.

    Return values

    blocking-splice: func

    Read from one stream and write to another, with blocking.

    @@ -479,7 +505,7 @@ one byte can be read.

    Return values

    forward: func

    Forward the entire contents of an input stream to an output stream.

    diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 13b4b247e..5cf8421ce 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,7 +1,7 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -sha256 = "ce53bedad0aa34bbcde6ffd8f98348e03fa170e191aaf6bb6ca57b4915ade435" -sha512 = "489ed4e04603df4763e75d4d2d056cf363922c4865052348993febfd2c9bd10ab864fb4b72090df58dcb60d5676148a7a1e7de3a8513073afd37b4d9027ca7e7" +sha256 = "f21b7722b9225b7ff4f040a67daacd4e412fe2c53c982568a2c25b97fc85d2a2" +sha512 = "ceec4b906f94ba53731dd9428e7e62b964de2284d6aa7cb3436cb856ca89405b0ca8b02e8a8d4575204b9e72dac0e3b29690221ca438324b89e0084117f1700f" [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" @@ -10,25 +10,25 @@ sha512 = "ef1e23704a8a8436fd3718593d4c4d8b6d1c64dad3595b7496c0888ca14b725046f290 [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "a19dbd57208ef649980bb4088b96606fe3549e580574dc88dafed6f8a8537b01" -sha512 = "49a798126feeb1a714162a20d282e554c70d36cbfa827dfb54685577b13d584fa15e02fd653fbb940a4fa52cece6c0ca4d7cd85f27c041a5cc99a98392d03e50" +sha256 = "dc170645d8aa52f2f94ab8f71093fa0c101e509ed1a07318995dc0395e9d6cf2" +sha512 = "3195a3e0f9ec52c3a91c4b4fde0547694236c7b29bceecb7f38634894fafd809c69ed1c1c9acbf225b2d5d00f5036d70371c9fed121d85028162b202035cabef" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "eeb4701c2becafa40a7ee3bf0d2c94e2170e15806b25abdcd1de1ed94f2c1036" -sha512 = "89be853b2acae211570cd6ad0ec9d8132881dafbdea83ac7b4cad600f0627003c61f310427379bf47ecf862724367bd5d6e976db70069f6f90a3c2d9c20dbfb7" +sha256 = "6e18239b0e20d1a3e6343cb961ebfd2c663ba7feb4c1aa3744b756fbdd1fb5b8" +sha512 = "53169b6e4fba0b2cf5fcf808f76e7fbb7cabb6ed66ab53f77d0966e7448312ccbe8571880ef4fc2ee86fbd6ba19bc48d46e10d22dcac6c51d217e8d7127c32db" [poll] url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -sha256 = "9f8bb4d9994e9b0684859bb1e8bee2a8b873e04d40695f260446760fc44d0c58" -sha512 = "aa8da395ba6e189ec113296996da5abf28bdc4460e4eb2aacc786698ced892e08f7054fb590fc8809c05554d5c83a11494d4ab68c755746f57d151e212415cfb" +sha256 = "d4c27124f4c137eb538b5c92ba5858ed9042e11b24a2eef85d14becd0b7f55de" +sha512 = "422c01b273b4b1377ece6f2e4ba0dfc609ca8ef30a3e0be0e172e1303fcf7b3ca4c470f4dea6c51bdf114b0f5c871ebc4934dfe3bf217d66ea689748df2b1e55" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "30731531ec3453813d08765b428f34aec34ac343cbeafd9885e4e348d187ae04" -sha512 = "6656089f9297ee56cf58c2f95c466e3a22c371925404e6eb9cb5adcb37c1b92f27aaf8c2f9e690ac53ef12f90bd31ac64a84d5f5e06d3f06e24997478275327f" +sha256 = "9b622463e597b9ca94f41e4eaae589a77be38f71b4723142b60246ffed8eaae4" +sha512 = "21f03ca1e595b80d7ced522de1a47446526b49b900e2fb26fcbf410ce6aa267dbf247aebf3fbfa8123b46fc1a828e2fd64fb1e0198b40161a3257e8d86fd4546" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "30c07587eda24676185f175323d5195817b5678815a3f6b64b8152a5b7532493" -sha512 = "8965e112c323e4535786361d864d3b5020791ce7e48da20a6a6b9a1fbec1f78bc10e0830c640f704bd8132fada56cd8a19b48e11e60ec6d9191c08e00550c91c" +sha256 = "871c211b12d87a5da87c42353338b652260840897efcd37e2afba3b9290058fc" +sha512 = "e436a5ff3145ca85d702a086499c03488523483dd3addc8d71e4946e9c186355291551bb6d38b157173836fcc318182403e6dba970de4512f6cfb3374ccad6b9" diff --git a/proposals/http/wit/deps/cli/exit.wit b/proposals/http/wit/deps/cli/exit.wit index 66835aa70..4831d5078 100644 --- a/proposals/http/wit/deps/cli/exit.wit +++ b/proposals/http/wit/deps/cli/exit.wit @@ -1,4 +1,4 @@ interface exit { - /// Exit the curerent instance and any linked instances. + /// Exit the current instance and any linked instances. exit: func(status: result) } diff --git a/proposals/http/wit/deps/filesystem/preopens.wit b/proposals/http/wit/deps/filesystem/preopens.wit new file mode 100644 index 000000000..f45661b8a --- /dev/null +++ b/proposals/http/wit/deps/filesystem/preopens.wit @@ -0,0 +1,6 @@ +interface preopens { + use types.{descriptor} + + /// Return the set of preopened directories, and their path. + get-directories: func() -> list> +} diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index 627b638ef..a437f22ae 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -102,10 +102,6 @@ interface types { /// /// Note: This was called `filestat` in earlier versions of WASI. record descriptor-stat { - /// Device ID of device containing the file. - device: device, - /// File serial number. - inode: inode, /// File type. %type: descriptor-type, /// Number of hard links to the file. @@ -166,14 +162,6 @@ interface types { /// Number of hard links to an inode. type link-count = u64 - /// Identifier for a device containing a file system. Can be used in - /// combination with `inode` to uniquely identify a file or directory in - /// the filesystem. - type device = u64 - - /// Filesystem object serial number that is unique within its file system. - type inode = u64 - /// When setting a timestamp, this gives the value to set it to. variant new-timestamp { /// Leave the timestamp set to its previous value. @@ -187,14 +175,6 @@ interface types { /// A directory entry. record directory-entry { - /// The serial number of the object referred to by this directory entry. - /// May be none if the inode value is not known. - /// - /// When this is none, libc implementations might do an extra `stat-at` - /// call to retrieve the inode number to fill their `d_ino` fields, so - /// implementations which can set this to a non-none value should do so. - inode: option, - /// The type of the file referred to by this directory entry. %type: descriptor-type, @@ -312,7 +292,18 @@ interface types { /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). type descriptor = u32 - /// Return a stream for reading from a file. + /// A 128-bit hash value, split into parts because wasm doesn't have a + /// 128-bit integer type. + record metadata-hash-value { + /// 64 bits of a 128-bit hash value. + lower: u64, + /// Another 64 bits of a 128-bit hash value. + upper: u64, + } + + /// Return a stream for reading from a file, if available. + /// + /// May fail with an error-code describing why the file cannot be read. /// /// Multiple read, write, and append streams may be active on the same open /// file and they do not interfere with each other. @@ -322,9 +313,11 @@ interface types { this: descriptor, /// The offset within the file at which to start reading. offset: filesize, - ) -> input-stream + ) -> result - /// Return a stream for writing to a file. + /// Return a stream for writing to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be written. /// /// Note: This allows using `write-stream`, which is similar to `write` in /// POSIX. @@ -332,15 +325,17 @@ interface types { this: descriptor, /// The offset within the file at which to start writing. offset: filesize, - ) -> output-stream + ) -> result - /// Return a stream for appending to a file. + /// Return a stream for appending to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be appended. /// /// Note: This allows using `write-stream`, which is similar to `write` with /// `O_APPEND` in in POSIX. append-via-stream: func( this: descriptor, - ) -> output-stream + ) -> result /// Provide file advisory information on a descriptor. /// @@ -479,14 +474,20 @@ interface types { /// Return the attributes of an open file or directory. /// - /// Note: This is similar to `fstat` in POSIX. + /// Note: This is similar to `fstat` in POSIX, except that it does not return + /// device and inode information. For testing whether two descriptors refer to + /// the same underlying filesystem object, use `is-same-object`. To obtain + /// additional data that can be used do determine whether a file has been + /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. stat: func(this: descriptor) -> result /// Return the attributes of a file or directory. /// - /// Note: This is similar to `fstatat` in POSIX. + /// Note: This is similar to `fstatat` in POSIX, except that it does not + /// return device and inode information. See the `stat` description for a + /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. stat-at: func( @@ -794,4 +795,47 @@ interface types { /// Dispose of the specified `directory-entry-stream`, after which it may no longer /// be used. drop-directory-entry-stream: func(this: directory-entry-stream) + + /// Test whether two descriptors refer to the same filesystem object. + /// + /// In POSIX, this corresponds to testing whether the two descriptors have the + /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. + /// wasi-filesystem does not expose device and inode numbers, so this function + /// may be used instead. + is-same-object: func(this: descriptor, other: descriptor) -> bool + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a descriptor. + /// + /// This returns a hash of the last-modification timestamp and file size, and + /// may also include the inode number, device number, birth timestamp, and + /// other metadata fields that may change when the file is modified or + /// replaced. It may also include a secret value chosen by the + /// implementation and not otherwise exposed. + /// + /// Implementations are encourated to provide the following properties: + /// + /// - If the file is not modified or replaced, the computed hash value should + /// usually not change. + /// - If the object is modified or replaced, the computed hash value should + /// usually change. + /// - The inputs to the hash should not be easily computable from the + /// computed hash. + /// + /// However, none of these is required. + metadata-hash: func( + this: descriptor, + ) -> result + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a directory descriptor and a relative path. + /// + /// This performs the same hash computation as `metadata-hash`. + metadata-hash-at: func( + this: descriptor, + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result } diff --git a/proposals/http/wit/deps/filesystem/world.wit b/proposals/http/wit/deps/filesystem/world.wit index f2ef782f4..b51f484f8 100644 --- a/proposals/http/wit/deps/filesystem/world.wit +++ b/proposals/http/wit/deps/filesystem/world.wit @@ -2,4 +2,5 @@ package wasi:filesystem world example-world { import types + import preopens } diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index 430c1d441..de8694bda 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -10,6 +10,19 @@ interface streams { /// doesn't provide any additional information. record stream-error {} + /// Streams provide a sequence of data and then end; once they end, they + /// no longer provide any further data. + /// + /// For example, a stream reading from a file ends when the stream reaches + /// the end of the file. For another example, a stream reading from a + /// socket ends when the socket is closed. + enum stream-status { + /// The stream is open and may produce further data. + open, + /// The stream has ended and will not produce any further data. + ended, + } + /// An input bytestream. In the future, this will be replaced by handle /// types. /// @@ -32,9 +45,9 @@ interface streams { /// Read bytes from a stream. /// /// This function returns a list of bytes containing the data that was - /// read, along with a bool which, when true, indicates that the end of the - /// stream was reached. The returned list will contain up to `len` bytes; it - /// may return fewer than requested, but not more. + /// read, along with a `stream-status` which indicates whether the end of + /// the stream was reached. The returned list will contain up to `len` + /// bytes; it may return fewer than requested, but not more. /// /// Once a stream has reached the end, subsequent calls to read or /// `skip` will always report end-of-stream rather than producing more @@ -51,7 +64,7 @@ interface streams { this: input-stream, /// The maximum number of bytes to read len: u64 - ) -> result, bool>, stream-error> + ) -> result, stream-status>, stream-error> /// Read bytes from a stream, with blocking. /// @@ -61,7 +74,7 @@ interface streams { this: input-stream, /// The maximum number of bytes to read len: u64 - ) -> result, bool>, stream-error> + ) -> result, stream-status>, stream-error> /// Skip bytes from a stream. /// @@ -72,14 +85,14 @@ interface streams { /// `skip` will always report end-of-stream rather than producing more /// data. /// - /// This function returns the number of bytes skipped, along with a bool - /// indicating whether the end of the stream was reached. The returned - /// value will be at most `len`; it may be less. + /// This function returns the number of bytes skipped, along with a + /// `stream-status` indicating whether the end of the stream was + /// reached. The returned value will be at most `len`; it may be less. skip: func( this: input-stream, /// The maximum number of bytes to skip. len: u64, - ) -> result, stream-error> + ) -> result, stream-error> /// Skip bytes from a stream, with blocking. /// @@ -89,7 +102,7 @@ interface streams { this: input-stream, /// The maximum number of bytes to skip. len: u64, - ) -> result, stream-error> + ) -> result, stream-error> /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been @@ -172,7 +185,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result, stream-error> + ) -> result, stream-error> /// Read from one stream and write to another, with blocking. /// @@ -184,7 +197,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result, stream-error> + ) -> result, stream-error> /// Forward the entire contents of an input stream to an output stream. /// diff --git a/proposals/http/wit/deps/poll/poll.wit b/proposals/http/wit/deps/poll/poll.wit index 55eee0029..fa82b6063 100644 --- a/proposals/http/wit/deps/poll/poll.wit +++ b/proposals/http/wit/deps/poll/poll.wit @@ -23,17 +23,27 @@ interface poll { /// Poll for completion on a set of pollables. /// + /// This function takes a list of pollables, which identify I/O sources of + /// interest, and waits until one or more of the events is ready for I/O. + /// + /// The result `list` is the same length as the argument + /// `list`, and indicates the readiness of each corresponding + /// element in that list, with true indicating ready. A single call can + /// return multiple true elements. + /// + /// A timeout can be implemented by adding a pollable from the + /// wasi-clocks API to the list. + /// + /// This function does not return a `result`; polling in itself does not + /// do any I/O so it doesn't fail. If any of the I/O sources identified by + /// the pollables has an error, it is indicated by marking the source as + /// ready in the `list`. + /// /// The "oneoff" in the name refers to the fact that this function must do a /// linear scan through the entire list of subscriptions, which may be /// inefficient if the number is large and the same subscriptions are used /// many times. In the future, this is expected to be obsoleted by the /// component model async proposal, which will include a scalable waiting /// facility. - /// - /// Note that the return type would ideally be `list`, but that would - /// be more difficult to polyfill given the current state of `wit-bindgen`. - /// See - /// for details. For now, we use zero to mean "not ready" and non-zero to - /// mean "ready". - poll-oneoff: func(in: list) -> list + poll-oneoff: func(in: list) -> list } diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index e4238621e..2a282dab7 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -3,21 +3,23 @@ /// It is intended to be portable at least between Unix-family platforms and /// Windows. interface random { - /// Return `len` cryptographically-secure pseudo-random bytes. + /// Return `len` cryptographically-secure random or pseudo-random bytes. /// - /// This function must produce data from an adequately seeded - /// cryptographically-secure pseudo-random number generator (CSPRNG), so it - /// must not block, from the perspective of the calling program, and the - /// returned data is always unpredictable. + /// This function must produce data at least as cryptographically secure and + /// fast as an adequately seeded cryptographically-secure pseudo-random + /// number generator (CSPRNG). It must not block, from the perspective of + /// the calling program, under any circumstances, including on the first + /// request and on requests for numbers of bytes. The returned data must + /// always be unpredictable. /// - /// This function must always return fresh pseudo-random data. Deterministic - /// environments must omit this function, rather than implementing it with - /// deterministic data. + /// This function must always return fresh data. Deterministic environments + /// must omit this function, rather than implementing it with deterministic + /// data. get-random-bytes: func(len: u64) -> list - /// Return a cryptographically-secure pseudo-random `u64` value. + /// Return a cryptographically-secure random or pseudo-random `u64` value. /// - /// This function returns the same type of pseudo-random data as - /// `get-random-bytes`, represented as a `u64`. + /// This function returns the same type of data as `get-random-bytes`, + /// represented as a `u64`. get-random-u64: func() -> u64 } diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index 3a0c1bd14..948ed581a 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -84,11 +84,11 @@ interface udp { start-connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> finish-connect: func(this: udp-socket) -> result<_, error-code> - /// Receive a message. + /// Receive messages on the socket. /// - /// Returns: - /// - The sender address of the datagram - /// - The number of bytes read. + /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. + /// The returned list may contain fewer elements than requested, but never more. + /// If `max-results` is 0, this function returns successfully with an empty list. /// /// # Typical errors /// - `not-bound`: The socket is not bound to any local address. (EINVAL) @@ -99,13 +99,23 @@ interface udp { /// - /// - /// - + /// - /// - /// - /// - /// - - receive: func(this: udp-socket) -> result + receive: func(this: udp-socket, max-results: u64) -> result, error-code> - /// Send a message to a specific destination address. + /// Send messages on the socket. + /// + /// This function attempts to send all provided `datagrams` on the socket without blocking and + /// returns how many messages were actually sent (or queued for sending). + /// + /// This function semantically behaves the same as iterating the `datagrams` list and sequentially + /// sending each individual datagram until either the end of the list has been reached or the first error occurred. + /// If at least one datagram has been sent successfully, this function never returns an error. + /// + /// If the input list is empty, the function returns `ok(0)`. /// /// The remote address option is required. To send a message to the "connected" peer, /// call `remote-address` to get their address. @@ -124,11 +134,12 @@ interface udp { /// - /// - /// - + /// - /// - /// - /// - /// - - send: func(this: udp-socket, datagram: datagram) -> result<_, error-code> + send: func(this: udp-socket, datagrams: list) -> result /// Get the current bound address. /// From 873df5c7d0d451d2a3da0be5ee21390b6e271873 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Mon, 7 Aug 2023 16:29:52 +0200 Subject: [PATCH 1193/1772] build: update `wasi-poll` (#39) Signed-off-by: Roman Volosatovs --- proposals/io/example-world.md | 19 +++++++++++++------ proposals/io/wit/deps.lock | 4 ++-- proposals/io/wit/deps/poll/poll.wit | 24 +++++++++++++++++------- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/proposals/io/example-world.md b/proposals/io/example-world.md index 31b0d76a3..9ddbef0e6 100644 --- a/proposals/io/example-world.md +++ b/proposals/io/example-world.md @@ -35,24 +35,31 @@ be used.

    poll-oneoff: func

    Poll for completion on a set of pollables.

    +

    This function takes a list of pollables, which identify I/O sources of +interest, and waits until one or more of the events is ready for I/O.

    +

    The result list<bool> is the same length as the argument +list<pollable>, and indicates the readiness of each corresponding +element in that list, with true indicating ready. A single call can +return multiple true elements.

    +

    A timeout can be implemented by adding a pollable from the +wasi-clocks API to the list.

    +

    This function does not return a result; polling in itself does not +do any I/O so it doesn't fail. If any of the I/O sources identified by +the pollables has an error, it is indicated by marking the source as +ready in the list<bool>.

    The "oneoff" in the name refers to the fact that this function must do a linear scan through the entire list of subscriptions, which may be inefficient if the number is large and the same subscriptions are used many times. In the future, this is expected to be obsoleted by the component model async proposal, which will include a scalable waiting facility.

    -

    Note that the return type would ideally be list<bool>, but that would -be more difficult to polyfill given the current state of wit-bindgen. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 -for details. For now, we use zero to mean "not ready" and non-zero to -mean "ready".

    Params
    Return values
      -
    • list<u8>
    • +
    • list<bool>

    Import interface wasi:io/streams

    WASI I/O is an I/O abstraction API which is currently focused on providing diff --git a/proposals/io/wit/deps.lock b/proposals/io/wit/deps.lock index 9d2f1d0c2..6babe9f1e 100644 --- a/proposals/io/wit/deps.lock +++ b/proposals/io/wit/deps.lock @@ -1,4 +1,4 @@ [poll] url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -sha256 = "9f8bb4d9994e9b0684859bb1e8bee2a8b873e04d40695f260446760fc44d0c58" -sha512 = "aa8da395ba6e189ec113296996da5abf28bdc4460e4eb2aacc786698ced892e08f7054fb590fc8809c05554d5c83a11494d4ab68c755746f57d151e212415cfb" +sha256 = "d4c27124f4c137eb538b5c92ba5858ed9042e11b24a2eef85d14becd0b7f55de" +sha512 = "422c01b273b4b1377ece6f2e4ba0dfc609ca8ef30a3e0be0e172e1303fcf7b3ca4c470f4dea6c51bdf114b0f5c871ebc4934dfe3bf217d66ea689748df2b1e55" diff --git a/proposals/io/wit/deps/poll/poll.wit b/proposals/io/wit/deps/poll/poll.wit index 55eee0029..fa82b6063 100644 --- a/proposals/io/wit/deps/poll/poll.wit +++ b/proposals/io/wit/deps/poll/poll.wit @@ -23,17 +23,27 @@ interface poll { /// Poll for completion on a set of pollables. /// + /// This function takes a list of pollables, which identify I/O sources of + /// interest, and waits until one or more of the events is ready for I/O. + /// + /// The result `list` is the same length as the argument + /// `list`, and indicates the readiness of each corresponding + /// element in that list, with true indicating ready. A single call can + /// return multiple true elements. + /// + /// A timeout can be implemented by adding a pollable from the + /// wasi-clocks API to the list. + /// + /// This function does not return a `result`; polling in itself does not + /// do any I/O so it doesn't fail. If any of the I/O sources identified by + /// the pollables has an error, it is indicated by marking the source as + /// ready in the `list`. + /// /// The "oneoff" in the name refers to the fact that this function must do a /// linear scan through the entire list of subscriptions, which may be /// inefficient if the number is large and the same subscriptions are used /// many times. In the future, this is expected to be obsoleted by the /// component model async proposal, which will include a scalable waiting /// facility. - /// - /// Note that the return type would ideally be `list`, but that would - /// be more difficult to polyfill given the current state of `wit-bindgen`. - /// See - /// for details. For now, we use zero to mean "not ready" and non-zero to - /// mean "ready". - poll-oneoff: func(in: list) -> list + poll-oneoff: func(in: list) -> list } From 62acbb1e2d084f86fdd8c9723173eadd68261b47 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 16 Aug 2023 13:49:02 -0700 Subject: [PATCH 1194/1772] fix typo --- proposals/cli/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/cli/README.md b/proposals/cli/README.md index a300e70c4..4ec9bea64 100644 --- a/proposals/cli/README.md +++ b/proposals/cli/README.md @@ -41,7 +41,7 @@ Wasi-cli a [World] proposal for a Command-Line Interface (CLI) environment. It p Wasi-cli aims to be useful for: - - Interfactive command-line argument programs. + - Interactive command-line argument programs. - Servers that use filesystems, sockets, and related APIs and expect to be started with a CLI-style command-line. From 181ce866e94a288d9b4dd052d7fec48b60e35ca8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 17 Aug 2023 05:44:43 -0700 Subject: [PATCH 1195/1772] Remove a mention of the Listening state from udp.wit. UDP doesn't have Listening state, so remove a mention of it from udp.wit. --- proposals/sockets/wit/udp.wit | 2 -- 1 file changed, 2 deletions(-) diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 948ed581a..700b9e247 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -198,8 +198,6 @@ interface udp { /// actual data to be sent/received by the application, because the kernel might also use the buffer space /// for internal metadata structures. /// - /// Fails when this socket is in the Listening state. - /// /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. /// /// # Typical errors From 78084a3b0c39508844d4755011db07da88b69ead Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 17 Aug 2023 10:19:27 -0700 Subject: [PATCH 1196/1772] Update CI to the latest wit-abi version. --- proposals/sockets/.github/workflows/main.yml | 4 ++-- proposals/sockets/example-world.md | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index cb083f2a8..3cba299bc 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -18,6 +18,6 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v12 + - uses: WebAssembly/wit-abi-up-to-date@v13 with: - wit-abi-tag: wit-abi-0.10.0 + wit-abi-tag: wit-abi-0.11.0 diff --git a/proposals/sockets/example-world.md b/proposals/sockets/example-world.md index 300ceb1a7..8c7452022 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/example-world.md @@ -611,7 +611,6 @@ In other words, after setting a value, reading the same setting back may return

    Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of actual data to be sent/received by the application, because the kernel might also use the buffer space for internal metadata structures.

    -

    Fails when this socket is in the Listening state.

    Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

    Typical errors

      From af39daaaf24278d59b72fc01d42786ff64582b2a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 22 Aug 2023 08:04:07 -0700 Subject: [PATCH 1197/1772] Describe wasi-filesystem's path sandboxing behavior (#127) * Describe wasi-filesystem's path sandboxing behavior Add a new path-resolution.md document describing CloudABI-style path resolution behavior. wit/types.wit previously had a brief description of this behavior, however this new document presents it in much more detail, with a description of the sandboxing properties and a discussion of implementation techniques. * Mention the stance on external filesystem accesses. * Update path-resolution.md Co-authored-by: Guy Bedford * Move host concerns into their own section, and add more context about optimizations. --------- Co-authored-by: Guy Bedford --- proposals/filesystem/README.md | 3 +- proposals/filesystem/example-world.md | 2 + proposals/filesystem/path-resolution.md | 91 +++++++++++++++++++++++++ proposals/filesystem/wit/types.wit | 5 ++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 proposals/filesystem/path-resolution.md diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index f040ed1ef..c5d6e6bfc 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -46,7 +46,8 @@ Unlike many filesystem APIs, WASI filesystem is capability-oriented. Instead of having functions that implicitly reference a filesystem namespace, WASI filesystems' APIs are passed a directory handle along with a path, and the path is looked up relative to the given handle, and sandboxed to be -resolved within that directory. +resolved within that directory. For more information about sandbox, see +[WASI filesystem path resolution](path-resolution.md). WASI filesystem hides some of the surface differences between Windows and Unix-style filesystems, however much of its behavior, indluding the diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md index 8a7fe8d7f..7805cf870 100644 --- a/proposals/filesystem/example-world.md +++ b/proposals/filesystem/example-world.md @@ -366,6 +366,8 @@ function starts with /, or if any step of resolving a path.. and symbolic link steps, reaches a directory outside of the base directory, or reaches a symlink to an absolute or rooted path in the underlying filesystem, the function fails with error-code::not-permitted.

      +

      For more information about WASI path resolution and sandboxing, see +WASI filesystem path resolution.


      Types

      type input-stream

      diff --git a/proposals/filesystem/path-resolution.md b/proposals/filesystem/path-resolution.md new file mode 100644 index 000000000..45f20b1b5 --- /dev/null +++ b/proposals/filesystem/path-resolution.md @@ -0,0 +1,91 @@ +# WASI filesystem path resolution + +wasi-filesystem uses a filesystem path sandboxing scheme modeled after the +system used in [CloudABI], which is also similar to the system used in +[Capsicum]. + +On Linux, it corresponds to the `RESOLVE_BENEATH` behavior in +[Linux's `openat2`]. In FreeBSD, it corresponds to the `O_RESOLVE_BENEATH` +behavior in [FreeBSD's `open`]. However, path resolution can also be +implemented manually using `openat` and `readlinkat` or similar primitives. + +## Sandboxing overview + +All functions in wasi-filesystem which operate on filesystem paths take +a pair of values: a base directory handle, and a relative path. Absolute +paths are not permitted, and there is no global namespace. All path +accesses are relative to a base directory handle. + +Path resolution is constrained to occur within the sub-filesystem referenced +by the base handle. Information about the filesystem outside of the base +directory handles is not visible. In particular, it's not permitted to use +paths that temporarily step outside the sandbox with something like +"../../../stuff/here", even if the final resolved path is back inside the +sandbox, because that would leak information about the existence of +directories outside the sandbox. + +Importantly, the sandboxing is designed to be implementable even in the presence +of outside processes accessing the same filesystem, including renaming, +unlinking, and creating new files and directories. + +## Symlinks + +Creating a symlink with an absolute path string fails with a "not permitted" +error. + +Other than that, symlinks may be created with any string, provided the +underlying filesystem implementation supports it. + +Sandboxing for symlink strings is performed at the time of an access, when a +path is being resolved, and not at the time that the symlink is created or +moved. This ensures that the sandbox is respected even if there are symlinks +created or renamed by other entities with access to the filesystem. + +## Host Implementation + +### Implementing path resolution manually + +Plain `openat` doesn't perform any sandboxing; it will readily open paths +containing ".." or starting with "/", or symlinks to paths containing ".." +or starting with "/". It has an `O_NOFOLLOW` flag, however this flag only +applies to the last component of the path (eg. the "c" in "a/b/c"). So +the strategy for using `openat` to implement sandboxing is to split paths +into components (eg. "a", "b", "c") and open them one component at a time, +so that each component can be opened with `O_NOFOLLOW`. + +If the `openat` call fails, and the OS error code indicates that it *was* +a symlink (eg. `ELOOP`), then call `readlinkat` to read the link contents, +split the contents into components, and prepend these new components to the +component list. If it starts with an absolute path, that's an attempt to +jump outside the sandbox, so path resolution should fail with an +"access denied" error message. + +If a path component is "..", instead of opening it, pop an item off of the +component list. If the list was empty, that represents an attempt to use +".." to step outside the sandbox, so path resolution should fail with an +"access denied" error message. + +### Implementation notes + +On Linux, `openat2` with `RESOLVE_BENEATH` may be used as an optimization to +implement many system calls other than just "open" by utilizing Linux's +`O_PATH` and "/proc/self/fd" features. + +On Windows, the [`NtCreateFile`] function can accept a directory handle and +can behave like an `openat` function, which can be used in the +[manual algorithm](implementing-path-resolution-manually). + +The Rust library [cap-std] implements WASI's filesystem sandboxing semantics, +but is otherwise independent of WASI or Wasm, so it can be reused in other +settings. It uses `openat2` and `NtCreateFile` and other optimizations. + +cloudabi-utils has an [implementation of the manual technique in C], though +that repository is no longer maintained. + +[implementation of the manual technique in C]: https://github.com/NuxiNL/cloudabi-utils/blob/master/src/libemulator/posix.c#L1205 +[cap-std]: https://github.com/bytecodealliance/cap-std +[Linux's `openat2`]: https://man7.org/linux/man-pages/man2/openat2.2.html +[CloudABI]: https://github.com/NuxiNL/cloudabi +[Capsicum]: https://wiki.freebsd.org/Capsicum +[FreeBSD's `open`]: https://man.freebsd.org/cgi/man.cgi?sektion=2&query=open +[`NtCreateFile`]: https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntcreatefile diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index e72a742de..9b1412d6d 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -17,6 +17,11 @@ /// `..` and symbolic link steps, reaches a directory outside of the base /// directory, or reaches a symlink to an absolute or rooted path in the /// underlying filesystem, the function fails with `error-code::not-permitted`. +/// +/// For more information about WASI path resolution and sandboxing, see +/// [WASI filesystem path resolution]. +/// +/// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { use wasi:io/streams.{input-stream, output-stream} use wasi:clocks/wall-clock.{datetime} From d0aa1195d9f2fa93216ef009f07428a9b317bd26 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 24 Aug 2023 20:32:17 -0700 Subject: [PATCH 1198/1772] Add stream-status to stream write return values, and expand documentation (#38) * Add stream-status to stream write return values, and expand documentation Documentation focuses on how the non-blocking read and write functions respond when not ready for reading/writing, and how that maps to pollable. stream-error is now a record with a dummy member, to follow the new component model excluding zero-sized types. * PR feedback from @sunfishcode: remove redundant and reword docs * eliminate stream-error, change interface to always return result with no error type * Update wit/streams.wit Co-authored-by: Dave Bakker --------- Co-authored-by: Dave Bakker --- proposals/io/example-world.md | 131 +++++++++++++++++++------------- proposals/io/wit/streams.wit | 139 ++++++++++++++++++++-------------- 2 files changed, 161 insertions(+), 109 deletions(-) diff --git a/proposals/io/example-world.md b/proposals/io/example-world.md index 9ddbef0e6..694fc1558 100644 --- a/proposals/io/example-world.md +++ b/proposals/io/example-world.md @@ -85,25 +85,22 @@ socket ends when the socket is closed.

    • ended

      -

      The stream has ended and will not produce any further data. +

      When reading, this indicates that the stream will not produce +further data. +When writing, this indicates that the stream will no longer be read. +Further writes are still permitted.

    -

    record stream-error

    -

    An error type returned from a stream operation. Currently this -doesn't provide any additional information.

    -
    Record Fields

    type output-stream

    u32

    An output bytestream. In the future, this will be replaced by handle types. -

    This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

    output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also always return promptly, after the number of bytes that can be written promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe-to-output-stream function to obtain a -pollable which can be polled for using wasi_poll.

    +pollable which can be polled for using wasi:poll.

    And at present, it is a u32 instead of being an actual handle, until the wit-bindgen implementation of handles and resources is ready.

    This represents a resource.

    @@ -111,34 +108,36 @@ the wit-bindgen implementation of handles and resources is ready.

    u32

    An input bytestream. In the future, this will be replaced by handle types. -

    This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

    input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe-to-input-stream function to obtain a pollable which -can be polled for using wasi_poll.

    +can be polled for using wasi:poll/poll.poll_oneoff.

    And at present, it is a u32 instead of being an actual handle, until the wit-bindgen implementation of handles and resources is ready.

    This represents a resource.


    Functions

    read: func

    -

    Read bytes from a stream.

    +

    Perform a non-blocking read from the stream.

    This function returns a list of bytes containing the data that was -read, along with a stream-status which indicates whether the end of -the stream was reached. The returned list will contain up to len -bytes; it may return fewer than requested, but not more.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more +read, along with a stream-status which, indicates whether further +reads are expected to produce data. The returned list will contain up to +len bytes; it may return fewer than requested, but not more. An +empty list and stream-status:open indicates no more data is +available at this time, and that the pollable given by +subscribe-to-input-stream will be ready when more data is available.

    +

    Once a stream has reached the end, subsequent calls to read or +skip will always report stream-status:ended rather than producing more data.

    -

    If len is 0, it represents a request to read 0 bytes, which should -always succeed, assuming the stream hasn't reached its end yet, and -return an empty list.

    -

    The len here is a u64, but some callees may not be able to allocate -a buffer as large as that would imply. -FIXME: describe what happens if allocation fails.

    +

    When the caller gives a len of 0, it represents a request to read 0 +bytes. This read should always succeed and return an empty list and +the current stream-status.

    +

    The len parameter is a u64, which could represent a list of u8 which +is not possible to allocate in wasm32, or not desirable to allocate as +as a return value by the callee. The callee may return a list of bytes +less than len in size while more bytes are available for reading.

    Params
    • this: input-stream
    • @@ -146,12 +145,11 @@ FIXME: describe what happens if allocation fails.

    Return values

    blocking-read: func

    -

    Read bytes from a stream, with blocking.

    -

    This is similar to read, except that it blocks until at least one -byte can be read.

    +

    Read bytes from a stream, after blocking until at least one byte can +be read. Except for blocking, identical to read.

    Params
    Return values

    skip: func

    Skip bytes from a stream.

    @@ -178,12 +176,11 @@ reached. The returned value will be at most len; it may be less.

    Return values

    blocking-skip: func

    -

    Skip bytes from a stream, with blocking.

    -

    This is similar to skip, except that it blocks until at least one -byte can be consumed.

    +

    Skip bytes from a stream, after blocking until at least one byte +can be skipped. Except for blocking behavior, identical to skip.

    Params
    Return values

    subscribe-to-input-stream: func

    Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been -closed.

    +closed. +The created pollable is a child resource of the input-stream. +Implementations may trap if the input-stream is dropped before +all derived pollables created with this function are dropped.

    Params

    drop-input-stream: func

    Dispose of the specified input-stream, after which it may no longer -be used.

    +be used. +Implementations may trap if this input-stream is dropped while child +pollable resources are still alive. +After this input-stream is dropped, implementations may report any +corresponding output-stream has stream-state.closed.

    Params

    write: func

    -

    Write bytes to a stream.

    -

    This function returns a u64 indicating the number of bytes from -buf that were written; it may be less than the full list.

    +

    Perform a non-blocking write of bytes to a stream.

    +

    This function returns a u64 and a stream-status. The u64 indicates +the number of bytes from buf that were written, which may be less than +the length of buf. The stream-status indicates if further writes to +the stream are expected to be read.

    +

    When the returned stream-status is open, the u64 return value may +be less than the length of buf. This indicates that no more bytes may +be written to the stream promptly. In that case the +subscribe-to-output-stream pollable will indicate when additional bytes +may be promptly written.

    +

    Writing an empty list must return a non-error result with 0 for the +u64 return value, and the current stream-status.

    Params
    Return values

    blocking-write: func

    -

    Write bytes to a stream, with blocking.

    +

    Blocking write of bytes to a stream.

    This is similar to write, except that it blocks until at least one byte can be written.

    Params
    @@ -236,12 +249,13 @@ byte can be written.

    Return values

    write-zeroes: func

    -

    Write multiple zero bytes to a stream.

    -

    This function returns a u64 indicating the number of zero bytes -that were written; it may be less than len.

    +

    Write multiple zero-bytes to a stream.

    +

    This function returns a u64 indicating the number of zero-bytes +that were written; it may be less than len. Equivelant to a call to +write with a list of zeroes of the given length.

    Params
    • this: output-stream
    • @@ -249,12 +263,13 @@ that were written; it may be less than len.

    Return values

    blocking-write-zeroes: func

    Write multiple zero bytes to a stream, with blocking.

    This is similar to write-zeroes, except that it blocks until at least -one byte can be written.

    +one byte can be written. Equivelant to a call to blocking-write with +a list of zeroes of the given length.

    Params
    Return values

    splice: func

    Read from one stream and write to another.

    @@ -278,7 +293,7 @@ read from the input stream has been written to the output stream.

    Return values

    blocking-splice: func

    Read from one stream and write to another, with blocking.

    @@ -292,7 +307,7 @@ one byte can be read.

    Return values

    forward: func

    Forward the entire contents of an input stream to an output stream.

    @@ -302,7 +317,8 @@ is reached, or an error is encountered.

    Unlike other I/O functions, this function blocks until the end of the input stream is seen and all the data has been written to the output stream.

    -

    This function returns the number of bytes transferred.

    +

    This function returns the number of bytes transferred, and the status of +the output stream.

    Params
    Return values

    subscribe-to-output-stream: func

    Create a pollable which will resolve once either the specified stream -is ready to accept bytes or the other end of the stream has been closed.

    +is ready to accept bytes or the stream-state has become closed.

    +

    Once the stream-state is closed, this pollable is always ready +immediately.

    +

    The created pollable is a child resource of the output-stream. +Implementations may trap if the output-stream is dropped before +all derived pollables created with this function are dropped.

    Params
    • this: output-stream
    • @@ -325,7 +346,11 @@ is ready to accept bytes or the other end of the stream has been closed.

    drop-output-stream: func

    Dispose of the specified output-stream, after which it may no longer -be used.

    +be used. +Implementations may trap if this output-stream is dropped while +child pollable resources are still alive. +After this output-stream is dropped, implementations may report any +corresponding input-stream has stream-state.closed.

    Params
    • this: output-stream
    • diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index de8694bda..98df181c1 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -1,3 +1,5 @@ +package wasi:io + /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. /// @@ -6,10 +8,6 @@ interface streams { use wasi:poll/poll.{pollable} - /// An error type returned from a stream operation. Currently this - /// doesn't provide any additional information. - record stream-error {} - /// Streams provide a sequence of data and then end; once they end, they /// no longer provide any further data. /// @@ -19,22 +17,22 @@ interface streams { enum stream-status { /// The stream is open and may produce further data. open, - /// The stream has ended and will not produce any further data. + /// When reading, this indicates that the stream will not produce + /// further data. + /// When writing, this indicates that the stream will no longer be read. + /// Further writes are still permitted. ended, } /// An input bytestream. In the future, this will be replaced by handle /// types. /// - /// This conceptually represents a `stream`. It's temporary - /// scaffolding until component-model's async features are ready. - /// /// `input-stream`s are *non-blocking* to the extent practical on underlying /// platforms. I/O operations always return promptly; if fewer bytes are /// promptly available than requested, they return the number of bytes promptly /// available, which could even be zero. To wait for data to be available, /// use the `subscribe-to-input-stream` function to obtain a `pollable` which - /// can be polled for using `wasi_poll`. + /// can be polled for using `wasi:poll/poll.poll_oneoff`. /// /// And at present, it is a `u32` instead of being an actual handle, until /// the wit-bindgen implementation of handles and resources is ready. @@ -42,39 +40,41 @@ interface streams { /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). type input-stream = u32 - /// Read bytes from a stream. + /// Perform a non-blocking read from the stream. /// /// This function returns a list of bytes containing the data that was - /// read, along with a `stream-status` which indicates whether the end of - /// the stream was reached. The returned list will contain up to `len` - /// bytes; it may return fewer than requested, but not more. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more + /// read, along with a `stream-status` which, indicates whether further + /// reads are expected to produce data. The returned list will contain up to + /// `len` bytes; it may return fewer than requested, but not more. An + /// empty list and `stream-status:open` indicates no more data is + /// available at this time, and that the pollable given by + /// `subscribe-to-input-stream` will be ready when more data is available. + /// + /// Once a stream has reached the end, subsequent calls to `read` or + /// `skip` will always report `stream-status:ended` rather than producing more /// data. /// - /// If `len` is 0, it represents a request to read 0 bytes, which should - /// always succeed, assuming the stream hasn't reached its end yet, and - /// return an empty list. + /// When the caller gives a `len` of 0, it represents a request to read 0 + /// bytes. This read should always succeed and return an empty list and + /// the current `stream-status`. /// - /// The len here is a `u64`, but some callees may not be able to allocate - /// a buffer as large as that would imply. - /// FIXME: describe what happens if allocation fails. + /// The `len` parameter is a `u64`, which could represent a list of u8 which + /// is not possible to allocate in wasm32, or not desirable to allocate as + /// as a return value by the callee. The callee may return a list of bytes + /// less than `len` in size while more bytes are available for reading. read: func( this: input-stream, /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>, stream-error> + ) -> result, stream-status>> - /// Read bytes from a stream, with blocking. - /// - /// This is similar to `read`, except that it blocks until at least one - /// byte can be read. + /// Read bytes from a stream, after blocking until at least one byte can + /// be read. Except for blocking, identical to `read`. blocking-read: func( this: input-stream, /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>, stream-error> + ) -> result, stream-status>> /// Skip bytes from a stream. /// @@ -92,39 +92,41 @@ interface streams { this: input-stream, /// The maximum number of bytes to skip. len: u64, - ) -> result, stream-error> + ) -> result> - /// Skip bytes from a stream, with blocking. - /// - /// This is similar to `skip`, except that it blocks until at least one - /// byte can be consumed. + /// Skip bytes from a stream, after blocking until at least one byte + /// can be skipped. Except for blocking behavior, identical to `skip`. blocking-skip: func( this: input-stream, /// The maximum number of bytes to skip. len: u64, - ) -> result, stream-error> + ) -> result> /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been /// closed. + /// The created `pollable` is a child resource of the `input-stream`. + /// Implementations may trap if the `input-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. subscribe-to-input-stream: func(this: input-stream) -> pollable /// Dispose of the specified `input-stream`, after which it may no longer /// be used. + /// Implementations may trap if this `input-stream` is dropped while child + /// `pollable` resources are still alive. + /// After this `input-stream` is dropped, implementations may report any + /// corresponding `output-stream` has `stream-state.closed`. drop-input-stream: func(this: input-stream) /// An output bytestream. In the future, this will be replaced by handle /// types. /// - /// This conceptually represents a `stream`. It's temporary - /// scaffolding until component-model's async features are ready. - /// /// `output-stream`s are *non-blocking* to the extent practical on /// underlying platforms. Except where specified otherwise, I/O operations also /// always return promptly, after the number of bytes that can be written /// promptly, which could even be zero. To wait for the stream to be ready to /// accept data, the `subscribe-to-output-stream` function to obtain a - /// `pollable` which can be polled for using `wasi_poll`. + /// `pollable` which can be polled for using `wasi:poll`. /// /// And at present, it is a `u32` instead of being an actual handle, until /// the wit-bindgen implementation of handles and resources is ready. @@ -132,17 +134,28 @@ interface streams { /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). type output-stream = u32 - /// Write bytes to a stream. + /// Perform a non-blocking write of bytes to a stream. + /// + /// This function returns a `u64` and a `stream-status`. The `u64` indicates + /// the number of bytes from `buf` that were written, which may be less than + /// the length of `buf`. The `stream-status` indicates if further writes to + /// the stream are expected to be read. /// - /// This function returns a `u64` indicating the number of bytes from - /// `buf` that were written; it may be less than the full list. + /// When the returned `stream-status` is `open`, the `u64` return value may + /// be less than the length of `buf`. This indicates that no more bytes may + /// be written to the stream promptly. In that case the + /// `subscribe-to-output-stream` pollable will indicate when additional bytes + /// may be promptly written. + /// + /// Writing an empty list must return a non-error result with `0` for the + /// `u64` return value, and the current `stream-status`. write: func( this: output-stream, /// Data to write buf: list - ) -> result + ) -> result> - /// Write bytes to a stream, with blocking. + /// Blocking write of bytes to a stream. /// /// This is similar to `write`, except that it blocks until at least one /// byte can be written. @@ -150,27 +163,29 @@ interface streams { this: output-stream, /// Data to write buf: list - ) -> result + ) -> result> - /// Write multiple zero bytes to a stream. + /// Write multiple zero-bytes to a stream. /// - /// This function returns a `u64` indicating the number of zero bytes - /// that were written; it may be less than `len`. + /// This function returns a `u64` indicating the number of zero-bytes + /// that were written; it may be less than `len`. Equivelant to a call to + /// `write` with a list of zeroes of the given length. write-zeroes: func( this: output-stream, - /// The number of zero bytes to write + /// The number of zero-bytes to write len: u64 - ) -> result + ) -> result> /// Write multiple zero bytes to a stream, with blocking. /// /// This is similar to `write-zeroes`, except that it blocks until at least - /// one byte can be written. + /// one byte can be written. Equivelant to a call to `blocking-write` with + /// a list of zeroes of the given length. blocking-write-zeroes: func( this: output-stream, /// The number of zero bytes to write len: u64 - ) -> result + ) -> result> /// Read from one stream and write to another. /// @@ -185,7 +200,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result, stream-error> + ) -> result> /// Read from one stream and write to another, with blocking. /// @@ -197,7 +212,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result, stream-error> + ) -> result> /// Forward the entire contents of an input stream to an output stream. /// @@ -209,18 +224,30 @@ interface streams { /// of the input stream is seen and all the data has been written to /// the output stream. /// - /// This function returns the number of bytes transferred. + /// This function returns the number of bytes transferred, and the status of + /// the output stream. forward: func( this: output-stream, /// The stream to read from src: input-stream - ) -> result + ) -> result> /// Create a `pollable` which will resolve once either the specified stream - /// is ready to accept bytes or the other end of the stream has been closed. + /// is ready to accept bytes or the `stream-state` has become closed. + /// + /// Once the stream-state is closed, this pollable is always ready + /// immediately. + /// + /// The created `pollable` is a child resource of the `output-stream`. + /// Implementations may trap if the `output-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. subscribe-to-output-stream: func(this: output-stream) -> pollable /// Dispose of the specified `output-stream`, after which it may no longer /// be used. + /// Implementations may trap if this `output-stream` is dropped while + /// child `pollable` resources are still alive. + /// After this `output-stream` is dropped, implementations may report any + /// corresponding `input-stream` has `stream-state.closed`. drop-output-stream: func(this: output-stream) } From 4c24c4b1035011e734af9db9cc6c96832c403ff6 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Tue, 12 Sep 2023 16:27:01 -0500 Subject: [PATCH 1199/1772] Fill in README.md, at Luke to list of champions --- proposals/http/README.md | 96 +++++++++++++++---- .../wit/{incoming-handler.wit => handler.wit} | 19 ++++ proposals/http/wit/outgoing-handler.wit | 18 ---- 3 files changed, 96 insertions(+), 37 deletions(-) rename proposals/http/wit/{incoming-handler.wit => handler.wit} (63%) delete mode 100644 proposals/http/wit/outgoing-handler.wit diff --git a/proposals/http/README.md b/proposals/http/README.md index 7ae657b23..528995ca1 100644 --- a/proposals/http/README.md +++ b/proposals/http/README.md @@ -2,18 +2,83 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API. -This proposal currently only contains the proposed Wit interfaces with light -explanation in comments; more work is necessary to fully document the proposal. -The Wit comments annotate where the proposed interface is expected to change in -the short term (for Preview2) once resources and handles are re-added to Wit, -and then after that (for Preview3) once native stream support is added to the -Component Model and Wit. - -The `wit` directory currently validates and can generate bindings with: +### Current Phase + +wasi-http is currently in [Phase 1](https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-1---feature-proposal-cg). + +### Champions + +* Piotr Sikora +* Jiaxiao Zhou +* Dan Chiarlone +* David Justice +* Luke Wagner + +### Phase 4 Advancement Criteria + +TODO + +### Introduction + +The WASI-http proposal defines a collection of [interfaces] for sending and +receiving HTTP requests and responses. WASI-http additionally defines a +[world], `wasi:http/proxy`, that circumscribes a minimal execution environment +for wasm HTTP [proxies]. + +[Interfaces]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#wit-interfaces +[World]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#wit-worlds +[Proxies]: https://httpwg.org/http-core/draft-ietf-httpbis-semantics-latest.html#intermediaries + +### Goals + +The proposal intends to abstract over HTTP version and transport protocol +choices (such as HTTP/1.1, HTTP/2 or HTTP/3) by mapping directly to the +abstract [HTTP Semantics], allowing hosts to (mostly) transparently use any of +these. + +The `wasi:http/proxy` world is meant to be implementable by a wide variety of +hosts including Web [service workers], forward- and reverse-[proxies] and +[origin servers] by requiring a minimal set of additional runtime support. + +The `wasi:http/proxy` world is meant to support flexible auto-scaling +("serverless") execution by moving the core `accept()` loop into the host and +allowing the host to dynamically spin up wasm instances in response to arriving +requests. + +The `wasi:http/proxy` world is meant to allow the chaining of HTTP +intermediaries to be implemented directly in terms of [Component Model] linking. +(Fully realizing this goal will require additional features only available in +the [Preview 3] timeframe.) + +[HTTP Semantics]: https://httpwg.org/http-core/draft-ietf-httpbis-semantics-latest.html +[Service Workers]: https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API +[Origin Servers]: https://httpwg.org/http-core/draft-ietf-httpbis-semantics-latest.html#origin.server +[Component Model]: https://github.com/WebAssembly/component-model/ +[Preview 3]: https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#streams + +### Non-goals + +WASI-http does not intend to define a more fully-featured cloud execution +environment (for this, see the [wasi-cloud-core] proposal). + +[wasi-cloud-core]: https://github.com/WebAssembly/wasi-cloud-core + +### API walk-through + +The proposal can be understood by first reading the comments of [`proxy.wit`], +then [`handler.wit`] and finally [`types.wit`]. + +[`proxy.wit`]: ./wit/proxy.wit +[`handler.wit`]: ./wit/handler.wit +[`types.wit`]: ./wit/types.wit + +### Working with the WIT + +Bindings can be generated from the `wit` directory via: ``` wit-bindgen c wit/ --world proxy ``` -or can be manipulated in other ways with: +and can be validated and otherwise manipulated via: ``` wasm-tools component wit wit/ ... ``` @@ -25,15 +90,8 @@ in the root directory, which fetches the live contents of the `main` branch of each proposal. As things stablize, `wit/deps.toml` will be updated to refer to versioned releases. -### Current Phase - -wasi-http is currently in [Phase 1](https://github.com/WebAssembly/WASI/blob/main/Proposals.md). - -### Champions - -Piotr Sikora, Jiaxiao Zhou, Dan Chiarlone, David Justice +### References & acknowledgements -### TODO +* This proposal was seeded by and developed in consultation with + [proxy-wasm](https://github.com/proxy-wasm/spec). -This readme needs to be expanded to cover a number of additional fields suggested in the -[WASI Proposal template](https://github.com/WebAssembly/wasi-proposal-template). diff --git a/proposals/http/wit/incoming-handler.wit b/proposals/http/wit/handler.wit similarity index 63% rename from proposals/http/wit/incoming-handler.wit rename to proposals/http/wit/handler.wit index f98429fed..e547a955c 100644 --- a/proposals/http/wit/incoming-handler.wit +++ b/proposals/http/wit/handler.wit @@ -24,3 +24,22 @@ interface incoming-handler { response-out: response-outparam ) } + +// The `wasi:http/outgoing-handler` interface is meant to be imported by +// components and implemented by the host. +// +// NOTE: in Preview3, this interface will be merged with +// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface +// that takes a `request` parameter and returns a `response` result. +// +interface outgoing-handler { + use types.{outgoing-request, request-options, future-incoming-response} + + // The parameter and result types of the `handle` function allow the caller + // to concurrently stream the bodies of the outgoing request and the incoming + // response. + handle: func( + request: outgoing-request, + options: option + ) -> future-incoming-response +} diff --git a/proposals/http/wit/outgoing-handler.wit b/proposals/http/wit/outgoing-handler.wit deleted file mode 100644 index 06c8e469f..000000000 --- a/proposals/http/wit/outgoing-handler.wit +++ /dev/null @@ -1,18 +0,0 @@ -// The `wasi:http/outgoing-handler` interface is meant to be imported by -// components and implemented by the host. -// -// NOTE: in Preview3, this interface will be merged with -// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface -// that takes a `request` parameter and returns a `response` result. -// -interface outgoing-handler { - use types.{outgoing-request, request-options, future-incoming-response} - - // The parameter and result types of the `handle` function allow the caller - // to concurrently stream the bodies of the outgoing request and the incoming - // response. - handle: func( - request: outgoing-request, - options: option - ) -> future-incoming-response -} From f6ef00bf8b7f9171bf04a154ef947a970ed4ac81 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 12 Sep 2023 14:39:26 -0700 Subject: [PATCH 1200/1772] New backpressure and flushing scheme for output-stream (#45) * New backpressure and flushing scheme for output-stream * markdown --- proposals/io/example-world.md | 168 +++++++++++++++++++++++----------- proposals/io/wit/streams.wit | 143 +++++++++++++++++++---------- 2 files changed, 209 insertions(+), 102 deletions(-) diff --git a/proposals/io/example-world.md b/proposals/io/example-world.md index 694fc1558..cef732d3c 100644 --- a/proposals/io/example-world.md +++ b/proposals/io/example-world.md @@ -71,7 +71,24 @@ when it does, they are expected to subsume this API.

      type pollable

      pollable

      -#### `enum stream-status` +#### `enum write-error` +

      An error for output-stream operations.

      +

      Contrary to input-streams, a closed output-stream is reported using +an error.

      +
      Enum Cases
      +
        +
      • +

        last-operation-failed

        +

        The last operation (a write or flush) failed before completion. +

      • +
      • +

        closed

        +

        The stream is closed: no more input will be accepted by the +stream. A closed output-stream will return this error on all +future operations. +

      • +
      +

      enum stream-status

      Streams provide a sequence of data and then end; once they end, they no longer provide any further data.

      For example, a stream reading from a file ends when the stream reaches @@ -216,68 +233,127 @@ corresponding output-stream has

      +

      check-write: func

      +

      Check readiness for writing. This function never blocks.

      +

      Returns the number of bytes permitted for the next call to write, +or an error. Calling write with more bytes than this function has +permitted will trap.

      +

      When this function returns 0 bytes, the subscribe-to-output-stream +pollable will become ready when this function will report at least +1 byte, or an error.

      +
      Params
      + +
      Return values
      +

      write: func

      -

      Perform a non-blocking write of bytes to a stream.

      -

      This function returns a u64 and a stream-status. The u64 indicates -the number of bytes from buf that were written, which may be less than -the length of buf. The stream-status indicates if further writes to -the stream are expected to be read.

      -

      When the returned stream-status is open, the u64 return value may -be less than the length of buf. This indicates that no more bytes may -be written to the stream promptly. In that case the -subscribe-to-output-stream pollable will indicate when additional bytes -may be promptly written.

      -

      Writing an empty list must return a non-error result with 0 for the -u64 return value, and the current stream-status.

      +

      Perform a write. This function never blocks.

      +

      Precondition: check-write gave permit of Ok(n) and contents has a +length of less than or equal to n. Otherwise, this function will trap.

      +

      returns Err(closed) without writing if the stream has closed since +the last call to check-write provided a permit.

      Params
      Return values
      +

      blocking-write-and-flush: func

      +

      Perform a write of up to 4096 bytes, and then flush the stream. Block +until all of these operations are complete, or an error occurs.

      +

      This is a convenience wrapper around the use of check-write, +subscribe-to-output-stream, write, and flush, and is implemented +with the following pseudo-code:

      +
      let pollable = subscribe-to-output-stream(this);
      +while !contents.is_empty() {
      +  // Wait for the stream to become writable
      +  poll-oneoff(pollable);
      +  let Ok(n) = check-write(this); // eliding error handling
      +  let len = min(n, contents.len());
      +  let (chunk, rest) = contents.split_at(len);
      +  write(this, chunk);            // eliding error handling
      +  contents = rest;
      +}
      +flush(this);
      +// Wait for completion of `flush`
      +poll-oneoff(pollable);
      +// Check for any errors that arose during `flush`
      +let _ = check-write(this);       // eliding error handling
      +
      +
      Params
      + -

      blocking-write: func

      -

      Blocking write of bytes to a stream.

      -

      This is similar to write, except that it blocks until at least one -byte can be written.

      +
      Return values
      + +

      flush: func

      +

      Request to flush buffered output. This function never blocks.

      +

      This tells the output-stream that the caller intends any buffered +output to be flushed. the output which is expected to be flushed +is all that has been passed to write prior to this call.

      +

      Upon calling this function, the output-stream will not accept any +writes (check-write will return ok(0)) until the flush has +completed. The subscribe-to-output-stream pollable will become ready +when the flush has completed and the stream can accept more writes.

      Params
      Return values
      -

      write-zeroes: func

      -

      Write multiple zero-bytes to a stream.

      -

      This function returns a u64 indicating the number of zero-bytes -that were written; it may be less than len. Equivelant to a call to -write with a list of zeroes of the given length.

      +

      blocking-flush: func

      +

      Request to flush buffered output, and block until flush completes +and stream is ready for writing again.

      Params
      +
      Return values
      + +

      subscribe-to-output-stream: func

      +

      Create a pollable which will resolve once the output-stream +is ready for more writing, or an error has occured. When this +pollable is ready, check-write will return ok(n) with n>0, or an +error.

      +

      If the stream is closed, this pollable is always ready immediately.

      +

      The created pollable is a child resource of the output-stream. +Implementations may trap if the output-stream is dropped before +all derived pollables created with this function are dropped.

      +
      Params
      +
      Return values
      -

      blocking-write-zeroes: func

      -

      Write multiple zero bytes to a stream, with blocking.

      -

      This is similar to write-zeroes, except that it blocks until at least -one byte can be written. Equivelant to a call to blocking-write with -a list of zeroes of the given length.

      +

      write-zeroes: func

      +

      Write zeroes to a stream.

      +

      this should be used precisely like write with the exact same +preconditions (must use check-write first), but instead of +passing a list of bytes, you simply pass the number of zero-bytes +that should be written.

      Params
      Return values

      splice: func

      Read from one stream and write to another.

      @@ -328,22 +404,6 @@ the output stream.

      -

      subscribe-to-output-stream: func

      -

      Create a pollable which will resolve once either the specified stream -is ready to accept bytes or the stream-state has become closed.

      -

      Once the stream-state is closed, this pollable is always ready -immediately.

      -

      The created pollable is a child resource of the output-stream. -Implementations may trap if the output-stream is dropped before -all derived pollables created with this function are dropped.

      -
      Params
      - -
      Return values
      -

      drop-output-stream: func

      Dispose of the specified output-stream, after which it may no longer be used. diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index 98df181c1..e2631f66a 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -134,58 +134,115 @@ interface streams { /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). type output-stream = u32 - /// Perform a non-blocking write of bytes to a stream. + /// An error for output-stream operations. /// - /// This function returns a `u64` and a `stream-status`. The `u64` indicates - /// the number of bytes from `buf` that were written, which may be less than - /// the length of `buf`. The `stream-status` indicates if further writes to - /// the stream are expected to be read. + /// Contrary to input-streams, a closed output-stream is reported using + /// an error. + enum write-error { + /// The last operation (a write or flush) failed before completion. + last-operation-failed, + /// The stream is closed: no more input will be accepted by the + /// stream. A closed output-stream will return this error on all + /// future operations. + closed + } + /// Check readiness for writing. This function never blocks. + /// + /// Returns the number of bytes permitted for the next call to `write`, + /// or an error. Calling `write` with more bytes than this function has + /// permitted will trap. + /// + /// When this function returns 0 bytes, the `subscribe-to-output-stream` + /// pollable will become ready when this function will report at least + /// 1 byte, or an error. + check-write: func( + this: output-stream + ) -> result + + /// Perform a write. This function never blocks. /// - /// When the returned `stream-status` is `open`, the `u64` return value may - /// be less than the length of `buf`. This indicates that no more bytes may - /// be written to the stream promptly. In that case the - /// `subscribe-to-output-stream` pollable will indicate when additional bytes - /// may be promptly written. + /// Precondition: check-write gave permit of Ok(n) and contents has a + /// length of less than or equal to n. Otherwise, this function will trap. /// - /// Writing an empty list must return a non-error result with `0` for the - /// `u64` return value, and the current `stream-status`. + /// returns Err(closed) without writing if the stream has closed since + /// the last call to check-write provided a permit. write: func( this: output-stream, - /// Data to write - buf: list - ) -> result> + contents: list + ) -> result<_, write-error> - /// Blocking write of bytes to a stream. + /// Perform a write of up to 4096 bytes, and then flush the stream. Block + /// until all of these operations are complete, or an error occurs. /// - /// This is similar to `write`, except that it blocks until at least one - /// byte can be written. - blocking-write: func( - this: output-stream, - /// Data to write - buf: list - ) -> result> + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe-to-output-stream`, `write`, and `flush`, and is implemented + /// with the following pseudo-code: + /// + /// ```text + /// let pollable = subscribe-to-output-stream(this); + /// while !contents.is_empty() { + /// // Wait for the stream to become writable + /// poll-oneoff(pollable); + /// let Ok(n) = check-write(this); // eliding error handling + /// let len = min(n, contents.len()); + /// let (chunk, rest) = contents.split_at(len); + /// write(this, chunk); // eliding error handling + /// contents = rest; + /// } + /// flush(this); + /// // Wait for completion of `flush` + /// poll-oneoff(pollable); + /// // Check for any errors that arose during `flush` + /// let _ = check-write(this); // eliding error handling + /// ``` + blocking-write-and-flush: func( + this: output-stream, + contents: list + ) -> result<_, write-error> - /// Write multiple zero-bytes to a stream. + /// Request to flush buffered output. This function never blocks. /// - /// This function returns a `u64` indicating the number of zero-bytes - /// that were written; it may be less than `len`. Equivelant to a call to - /// `write` with a list of zeroes of the given length. - write-zeroes: func( + /// This tells the output-stream that the caller intends any buffered + /// output to be flushed. the output which is expected to be flushed + /// is all that has been passed to `write` prior to this call. + /// + /// Upon calling this function, the `output-stream` will not accept any + /// writes (`check-write` will return `ok(0)`) until the flush has + /// completed. The `subscribe-to-output-stream` pollable will become ready + /// when the flush has completed and the stream can accept more writes. + flush: func( this: output-stream, - /// The number of zero-bytes to write - len: u64 - ) -> result> + ) -> result<_, write-error> + + /// Request to flush buffered output, and block until flush completes + /// and stream is ready for writing again. + blocking-flush: func( + this: output-stream, + ) -> result<_, write-error> + + /// Create a `pollable` which will resolve once the output-stream + /// is ready for more writing, or an error has occured. When this + /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an + /// error. + /// + /// If the stream is closed, this pollable is always ready immediately. + /// + /// The created `pollable` is a child resource of the `output-stream`. + /// Implementations may trap if the `output-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe-to-output-stream: func(this: output-stream) -> pollable - /// Write multiple zero bytes to a stream, with blocking. + /// Write zeroes to a stream. /// - /// This is similar to `write-zeroes`, except that it blocks until at least - /// one byte can be written. Equivelant to a call to `blocking-write` with - /// a list of zeroes of the given length. - blocking-write-zeroes: func( + /// this should be used precisely like `write` with the exact same + /// preconditions (must use check-write first), but instead of + /// passing a list of bytes, you simply pass the number of zero-bytes + /// that should be written. + write-zeroes: func( this: output-stream, - /// The number of zero bytes to write + /// The number of zero-bytes to write len: u64 - ) -> result> + ) -> result<_, write-error> /// Read from one stream and write to another. /// @@ -232,16 +289,6 @@ interface streams { src: input-stream ) -> result> - /// Create a `pollable` which will resolve once either the specified stream - /// is ready to accept bytes or the `stream-state` has become closed. - /// - /// Once the stream-state is closed, this pollable is always ready - /// immediately. - /// - /// The created `pollable` is a child resource of the `output-stream`. - /// Implementations may trap if the `output-stream` is dropped before - /// all derived `pollable`s created with this function are dropped. - subscribe-to-output-stream: func(this: output-stream) -> pollable /// Dispose of the specified `output-stream`, after which it may no longer /// be used. From e99cb86aaa76c358cd3c9d64fed6b515c0aaf338 Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Tue, 12 Sep 2023 14:39:52 -0700 Subject: [PATCH 1201/1772] chore: update example-world to imports (#42) Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/io/wit/world.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index b7f625334..e9ca233da 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -1,5 +1,5 @@ package wasi:io -world example-world { +world imports { import streams } From b86c537dcec06c89191f7605c904f65b2f633f8f Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Wed, 13 Sep 2023 11:18:19 -0700 Subject: [PATCH 1202/1772] chore: change example-world to imports (#33) Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/random/wit/world.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index 3c3d16554..41dc9ed10 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,6 +1,6 @@ package wasi:random -world example-world { +world imports { import random import insecure import insecure-seed From 684a323ec64455f7095ac3871557517bd78f401d Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Wed, 13 Sep 2023 11:19:35 -0700 Subject: [PATCH 1203/1772] rename example-world to imports world (#49) * rename example-world to imports world Signed-off-by: Jiaxiao Zhou (Mossaka) * chore: update wit deps Signed-off-by: Jiaxiao Zhou (Mossaka) --------- Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/clocks/wit/deps.lock | 4 ++-- proposals/clocks/wit/deps/poll/poll.wit | 24 +++++++++++++++++------- proposals/clocks/wit/world.wit | 2 +- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/proposals/clocks/wit/deps.lock b/proposals/clocks/wit/deps.lock index 9d2f1d0c2..6babe9f1e 100644 --- a/proposals/clocks/wit/deps.lock +++ b/proposals/clocks/wit/deps.lock @@ -1,4 +1,4 @@ [poll] url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -sha256 = "9f8bb4d9994e9b0684859bb1e8bee2a8b873e04d40695f260446760fc44d0c58" -sha512 = "aa8da395ba6e189ec113296996da5abf28bdc4460e4eb2aacc786698ced892e08f7054fb590fc8809c05554d5c83a11494d4ab68c755746f57d151e212415cfb" +sha256 = "d4c27124f4c137eb538b5c92ba5858ed9042e11b24a2eef85d14becd0b7f55de" +sha512 = "422c01b273b4b1377ece6f2e4ba0dfc609ca8ef30a3e0be0e172e1303fcf7b3ca4c470f4dea6c51bdf114b0f5c871ebc4934dfe3bf217d66ea689748df2b1e55" diff --git a/proposals/clocks/wit/deps/poll/poll.wit b/proposals/clocks/wit/deps/poll/poll.wit index 55eee0029..fa82b6063 100644 --- a/proposals/clocks/wit/deps/poll/poll.wit +++ b/proposals/clocks/wit/deps/poll/poll.wit @@ -23,17 +23,27 @@ interface poll { /// Poll for completion on a set of pollables. /// + /// This function takes a list of pollables, which identify I/O sources of + /// interest, and waits until one or more of the events is ready for I/O. + /// + /// The result `list` is the same length as the argument + /// `list`, and indicates the readiness of each corresponding + /// element in that list, with true indicating ready. A single call can + /// return multiple true elements. + /// + /// A timeout can be implemented by adding a pollable from the + /// wasi-clocks API to the list. + /// + /// This function does not return a `result`; polling in itself does not + /// do any I/O so it doesn't fail. If any of the I/O sources identified by + /// the pollables has an error, it is indicated by marking the source as + /// ready in the `list`. + /// /// The "oneoff" in the name refers to the fact that this function must do a /// linear scan through the entire list of subscriptions, which may be /// inefficient if the number is large and the same subscriptions are used /// many times. In the future, this is expected to be obsoleted by the /// component model async proposal, which will include a scalable waiting /// facility. - /// - /// Note that the return type would ideally be `list`, but that would - /// be more difficult to polyfill given the current state of `wit-bindgen`. - /// See - /// for details. For now, we use zero to mean "not ready" and non-zero to - /// mean "ready". - poll-oneoff: func(in: list) -> list + poll-oneoff: func(in: list) -> list } diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index 291a9c75e..5c2dd411d 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -1,6 +1,6 @@ package wasi:clocks -world example-world { +world imports { import monotonic-clock import wall-clock import timezone From 2fa7da326b437a5c1f64ba475606bdf8aaf5b9dd Mon Sep 17 00:00:00 2001 From: Colin D Murphy Date: Wed, 13 Sep 2023 14:20:34 -0400 Subject: [PATCH 1204/1772] Make timezone a per-instance value (#48) * Add constructor for timezone. Add example to README. * Update md. * Make timezone a per-instance value. Timezone and clock should be handled similarly. If clocks are switched back to resources, then timezones could be switched back as well. --- proposals/clocks/README.md | 23 ++++++++++++++--------- proposals/clocks/example-world.md | 18 +----------------- proposals/clocks/wit/timezone.wit | 17 ++--------------- 3 files changed, 17 insertions(+), 41 deletions(-) diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 063e315f1..d91dd8e2a 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -52,8 +52,7 @@ read the current time and to measure elapsed time. ### Non-goals -WASI Clocks is not aiming to cover timezones, daylight savings time, date -formatting, or modifying the time of a clock. +WASI Clocks is not aiming to cover date formatting, or modifying the time of a clock. ### API walk-through @@ -66,13 +65,11 @@ default-monotonic-clock: monotonic-clock ``` ```rust - let clock: MonotonicClock = default_monotonic_clock(); - - let start: Instant = monotonic_clock_now(clock); + let start: Instant = monotonic_clock::now(clock); // some stuff - let stop: Instant = monotonic_clock_now(clock); + let stop: Instant = monotonic_clock::now(clock); let elapsed: Instant = stop - start; ``` @@ -81,13 +78,21 @@ default-monotonic-clock: monotonic-clock #### Telling the current human time: ```rust - let clock: WallClock = default_wall_clock(); - - let the_current_time = wall_clock_now(); + let the_current_time = wall_clock::now(); println!("it has been {} seconds and {} nanoseconds since the Unix epoch!", the_current_time.seconds, the_current_time.nanoseconds); ``` +#### Retrieving the timezone: + +```rust + let datetime: Datetime = wall_clock::now(); + + let timezone_display: TimezoneDisplay = timezone::display(datetime); + + println!("the timezone is {}", timezone_display.name); +``` + ### Detailed design discussion ### What should the type of a timestamp be? diff --git a/proposals/clocks/example-world.md b/proposals/clocks/example-world.md index 4587ddd6e..f716f899f 100644 --- a/proposals/clocks/example-world.md +++ b/proposals/clocks/example-world.md @@ -149,7 +149,7 @@ also known as Unix Time. #### `record timezone-display`

      Information useful for displaying the timezone of a specific datetime.

      -

      This information may vary within a single timezone to reflect daylight +

      This information may vary within a single timezone to reflect daylight saving time adjustments.

      Record Fields
        @@ -179,13 +179,6 @@ representation of the UTC offset may be returned, such as -04:00.
      -

      type timezone

      -

      u32

      -

      A timezone. -

      In timezones that recognize daylight saving time, also known as daylight -time and summer time, the information returned from the functions varies -over time to reflect these adjustments.

      -

      This represents a resource.


      Functions

      display: func

      @@ -197,7 +190,6 @@ daylight saving time is active.

      saving time.

      Params
      Return values
      @@ -208,17 +200,9 @@ saving time.

      The same as display, but only return the UTC offset.

      Params
      Return values
      • s32
      -

      drop-timezone: func

      -

      Dispose of the specified input-stream, after which it may no longer -be used.

      -
      Params
      - diff --git a/proposals/clocks/wit/timezone.wit b/proposals/clocks/wit/timezone.wit index 662830871..a872bffc7 100644 --- a/proposals/clocks/wit/timezone.wit +++ b/proposals/clocks/wit/timezone.wit @@ -1,15 +1,6 @@ interface timezone { use wall-clock.{datetime} - /// A timezone. - /// - /// In timezones that recognize daylight saving time, also known as daylight - /// time and summer time, the information returned from the functions varies - /// over time to reflect these adjustments. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type timezone = u32 - /// Return information needed to display the given `datetime`. This includes /// the UTC offset, the time zone name, and a flag indicating whether /// daylight saving time is active. @@ -17,14 +8,10 @@ interface timezone { /// If the timezone cannot be determined for the given `datetime`, return a /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight /// saving time. - display: func(this: timezone, when: datetime) -> timezone-display + display: func(when: datetime) -> timezone-display /// The same as `display`, but only return the UTC offset. - utc-offset: func(this: timezone, when: datetime) -> s32 - - /// Dispose of the specified input-stream, after which it may no longer - /// be used. - drop-timezone: func(this: timezone) + utc-offset: func(when: datetime) -> s32 /// Information useful for displaying the timezone of a specific `datetime`. /// From b8e782a4503ab177d76aa2956a9346a72d26d66b Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Wed, 13 Sep 2023 12:05:31 -0700 Subject: [PATCH 1205/1772] chore: update deps and rename example-world to imports (#130) Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/filesystem/wit/deps.lock | 8 +- proposals/filesystem/wit/deps/io/streams.wit | 154 ++++++++++++------- proposals/filesystem/wit/deps/poll/poll.wit | 24 ++- proposals/filesystem/wit/world.wit | 2 +- 4 files changed, 119 insertions(+), 69 deletions(-) diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index cf11adc18..a89146803 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -5,10 +5,10 @@ sha512 = "ef1e23704a8a8436fd3718593d4c4d8b6d1c64dad3595b7496c0888ca14b725046f290 [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "eeb4701c2becafa40a7ee3bf0d2c94e2170e15806b25abdcd1de1ed94f2c1036" -sha512 = "89be853b2acae211570cd6ad0ec9d8132881dafbdea83ac7b4cad600f0627003c61f310427379bf47ecf862724367bd5d6e976db70069f6f90a3c2d9c20dbfb7" +sha256 = "a47690f7d4dba1683a42897cc65fe813409827d72cc93afe03b127ee81763e13" +sha512 = "661aa9cf9c67d7d712caccfbb3c317da01b033764892623c8902d9dcfdb67f3088889102b036d3ed19d818a5c2d151247b25d9f6fd145cdf433f325605a5a747" [poll] url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -sha256 = "9f8bb4d9994e9b0684859bb1e8bee2a8b873e04d40695f260446760fc44d0c58" -sha512 = "aa8da395ba6e189ec113296996da5abf28bdc4460e4eb2aacc786698ced892e08f7054fb590fc8809c05554d5c83a11494d4ab68c755746f57d151e212415cfb" +sha256 = "d4c27124f4c137eb538b5c92ba5858ed9042e11b24a2eef85d14becd0b7f55de" +sha512 = "422c01b273b4b1377ece6f2e4ba0dfc609ca8ef30a3e0be0e172e1303fcf7b3ca4c470f4dea6c51bdf114b0f5c871ebc4934dfe3bf217d66ea689748df2b1e55" diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index 430c1d441..98df181c1 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -1,3 +1,5 @@ +package wasi:io + /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. /// @@ -6,22 +8,31 @@ interface streams { use wasi:poll/poll.{pollable} - /// An error type returned from a stream operation. Currently this - /// doesn't provide any additional information. - record stream-error {} + /// Streams provide a sequence of data and then end; once they end, they + /// no longer provide any further data. + /// + /// For example, a stream reading from a file ends when the stream reaches + /// the end of the file. For another example, a stream reading from a + /// socket ends when the socket is closed. + enum stream-status { + /// The stream is open and may produce further data. + open, + /// When reading, this indicates that the stream will not produce + /// further data. + /// When writing, this indicates that the stream will no longer be read. + /// Further writes are still permitted. + ended, + } /// An input bytestream. In the future, this will be replaced by handle /// types. /// - /// This conceptually represents a `stream`. It's temporary - /// scaffolding until component-model's async features are ready. - /// /// `input-stream`s are *non-blocking* to the extent practical on underlying /// platforms. I/O operations always return promptly; if fewer bytes are /// promptly available than requested, they return the number of bytes promptly /// available, which could even be zero. To wait for data to be available, /// use the `subscribe-to-input-stream` function to obtain a `pollable` which - /// can be polled for using `wasi_poll`. + /// can be polled for using `wasi:poll/poll.poll_oneoff`. /// /// And at present, it is a `u32` instead of being an actual handle, until /// the wit-bindgen implementation of handles and resources is ready. @@ -29,39 +40,41 @@ interface streams { /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). type input-stream = u32 - /// Read bytes from a stream. + /// Perform a non-blocking read from the stream. /// /// This function returns a list of bytes containing the data that was - /// read, along with a bool which, when true, indicates that the end of the - /// stream was reached. The returned list will contain up to `len` bytes; it - /// may return fewer than requested, but not more. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more + /// read, along with a `stream-status` which, indicates whether further + /// reads are expected to produce data. The returned list will contain up to + /// `len` bytes; it may return fewer than requested, but not more. An + /// empty list and `stream-status:open` indicates no more data is + /// available at this time, and that the pollable given by + /// `subscribe-to-input-stream` will be ready when more data is available. + /// + /// Once a stream has reached the end, subsequent calls to `read` or + /// `skip` will always report `stream-status:ended` rather than producing more /// data. /// - /// If `len` is 0, it represents a request to read 0 bytes, which should - /// always succeed, assuming the stream hasn't reached its end yet, and - /// return an empty list. + /// When the caller gives a `len` of 0, it represents a request to read 0 + /// bytes. This read should always succeed and return an empty list and + /// the current `stream-status`. /// - /// The len here is a `u64`, but some callees may not be able to allocate - /// a buffer as large as that would imply. - /// FIXME: describe what happens if allocation fails. + /// The `len` parameter is a `u64`, which could represent a list of u8 which + /// is not possible to allocate in wasm32, or not desirable to allocate as + /// as a return value by the callee. The callee may return a list of bytes + /// less than `len` in size while more bytes are available for reading. read: func( this: input-stream, /// The maximum number of bytes to read len: u64 - ) -> result, bool>, stream-error> + ) -> result, stream-status>> - /// Read bytes from a stream, with blocking. - /// - /// This is similar to `read`, except that it blocks until at least one - /// byte can be read. + /// Read bytes from a stream, after blocking until at least one byte can + /// be read. Except for blocking, identical to `read`. blocking-read: func( this: input-stream, /// The maximum number of bytes to read len: u64 - ) -> result, bool>, stream-error> + ) -> result, stream-status>> /// Skip bytes from a stream. /// @@ -72,46 +85,48 @@ interface streams { /// `skip` will always report end-of-stream rather than producing more /// data. /// - /// This function returns the number of bytes skipped, along with a bool - /// indicating whether the end of the stream was reached. The returned - /// value will be at most `len`; it may be less. + /// This function returns the number of bytes skipped, along with a + /// `stream-status` indicating whether the end of the stream was + /// reached. The returned value will be at most `len`; it may be less. skip: func( this: input-stream, /// The maximum number of bytes to skip. len: u64, - ) -> result, stream-error> + ) -> result> - /// Skip bytes from a stream, with blocking. - /// - /// This is similar to `skip`, except that it blocks until at least one - /// byte can be consumed. + /// Skip bytes from a stream, after blocking until at least one byte + /// can be skipped. Except for blocking behavior, identical to `skip`. blocking-skip: func( this: input-stream, /// The maximum number of bytes to skip. len: u64, - ) -> result, stream-error> + ) -> result> /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been /// closed. + /// The created `pollable` is a child resource of the `input-stream`. + /// Implementations may trap if the `input-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. subscribe-to-input-stream: func(this: input-stream) -> pollable /// Dispose of the specified `input-stream`, after which it may no longer /// be used. + /// Implementations may trap if this `input-stream` is dropped while child + /// `pollable` resources are still alive. + /// After this `input-stream` is dropped, implementations may report any + /// corresponding `output-stream` has `stream-state.closed`. drop-input-stream: func(this: input-stream) /// An output bytestream. In the future, this will be replaced by handle /// types. /// - /// This conceptually represents a `stream`. It's temporary - /// scaffolding until component-model's async features are ready. - /// /// `output-stream`s are *non-blocking* to the extent practical on /// underlying platforms. Except where specified otherwise, I/O operations also /// always return promptly, after the number of bytes that can be written /// promptly, which could even be zero. To wait for the stream to be ready to /// accept data, the `subscribe-to-output-stream` function to obtain a - /// `pollable` which can be polled for using `wasi_poll`. + /// `pollable` which can be polled for using `wasi:poll`. /// /// And at present, it is a `u32` instead of being an actual handle, until /// the wit-bindgen implementation of handles and resources is ready. @@ -119,17 +134,28 @@ interface streams { /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). type output-stream = u32 - /// Write bytes to a stream. + /// Perform a non-blocking write of bytes to a stream. + /// + /// This function returns a `u64` and a `stream-status`. The `u64` indicates + /// the number of bytes from `buf` that were written, which may be less than + /// the length of `buf`. The `stream-status` indicates if further writes to + /// the stream are expected to be read. /// - /// This function returns a `u64` indicating the number of bytes from - /// `buf` that were written; it may be less than the full list. + /// When the returned `stream-status` is `open`, the `u64` return value may + /// be less than the length of `buf`. This indicates that no more bytes may + /// be written to the stream promptly. In that case the + /// `subscribe-to-output-stream` pollable will indicate when additional bytes + /// may be promptly written. + /// + /// Writing an empty list must return a non-error result with `0` for the + /// `u64` return value, and the current `stream-status`. write: func( this: output-stream, /// Data to write buf: list - ) -> result + ) -> result> - /// Write bytes to a stream, with blocking. + /// Blocking write of bytes to a stream. /// /// This is similar to `write`, except that it blocks until at least one /// byte can be written. @@ -137,27 +163,29 @@ interface streams { this: output-stream, /// Data to write buf: list - ) -> result + ) -> result> - /// Write multiple zero bytes to a stream. + /// Write multiple zero-bytes to a stream. /// - /// This function returns a `u64` indicating the number of zero bytes - /// that were written; it may be less than `len`. + /// This function returns a `u64` indicating the number of zero-bytes + /// that were written; it may be less than `len`. Equivelant to a call to + /// `write` with a list of zeroes of the given length. write-zeroes: func( this: output-stream, - /// The number of zero bytes to write + /// The number of zero-bytes to write len: u64 - ) -> result + ) -> result> /// Write multiple zero bytes to a stream, with blocking. /// /// This is similar to `write-zeroes`, except that it blocks until at least - /// one byte can be written. + /// one byte can be written. Equivelant to a call to `blocking-write` with + /// a list of zeroes of the given length. blocking-write-zeroes: func( this: output-stream, /// The number of zero bytes to write len: u64 - ) -> result + ) -> result> /// Read from one stream and write to another. /// @@ -172,7 +200,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result, stream-error> + ) -> result> /// Read from one stream and write to another, with blocking. /// @@ -184,7 +212,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result, stream-error> + ) -> result> /// Forward the entire contents of an input stream to an output stream. /// @@ -196,18 +224,30 @@ interface streams { /// of the input stream is seen and all the data has been written to /// the output stream. /// - /// This function returns the number of bytes transferred. + /// This function returns the number of bytes transferred, and the status of + /// the output stream. forward: func( this: output-stream, /// The stream to read from src: input-stream - ) -> result + ) -> result> /// Create a `pollable` which will resolve once either the specified stream - /// is ready to accept bytes or the other end of the stream has been closed. + /// is ready to accept bytes or the `stream-state` has become closed. + /// + /// Once the stream-state is closed, this pollable is always ready + /// immediately. + /// + /// The created `pollable` is a child resource of the `output-stream`. + /// Implementations may trap if the `output-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. subscribe-to-output-stream: func(this: output-stream) -> pollable /// Dispose of the specified `output-stream`, after which it may no longer /// be used. + /// Implementations may trap if this `output-stream` is dropped while + /// child `pollable` resources are still alive. + /// After this `output-stream` is dropped, implementations may report any + /// corresponding `input-stream` has `stream-state.closed`. drop-output-stream: func(this: output-stream) } diff --git a/proposals/filesystem/wit/deps/poll/poll.wit b/proposals/filesystem/wit/deps/poll/poll.wit index 55eee0029..fa82b6063 100644 --- a/proposals/filesystem/wit/deps/poll/poll.wit +++ b/proposals/filesystem/wit/deps/poll/poll.wit @@ -23,17 +23,27 @@ interface poll { /// Poll for completion on a set of pollables. /// + /// This function takes a list of pollables, which identify I/O sources of + /// interest, and waits until one or more of the events is ready for I/O. + /// + /// The result `list` is the same length as the argument + /// `list`, and indicates the readiness of each corresponding + /// element in that list, with true indicating ready. A single call can + /// return multiple true elements. + /// + /// A timeout can be implemented by adding a pollable from the + /// wasi-clocks API to the list. + /// + /// This function does not return a `result`; polling in itself does not + /// do any I/O so it doesn't fail. If any of the I/O sources identified by + /// the pollables has an error, it is indicated by marking the source as + /// ready in the `list`. + /// /// The "oneoff" in the name refers to the fact that this function must do a /// linear scan through the entire list of subscriptions, which may be /// inefficient if the number is large and the same subscriptions are used /// many times. In the future, this is expected to be obsoleted by the /// component model async proposal, which will include a scalable waiting /// facility. - /// - /// Note that the return type would ideally be `list`, but that would - /// be more difficult to polyfill given the current state of `wit-bindgen`. - /// See - /// for details. For now, we use zero to mean "not ready" and non-zero to - /// mean "ready". - poll-oneoff: func(in: list) -> list + poll-oneoff: func(in: list) -> list } diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index b51f484f8..5fa7eafdb 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,6 +1,6 @@ package wasi:filesystem -world example-world { +world imports { import types import preopens } From 753203821889490c222240c489bdda64e1c82806 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 13 Sep 2023 12:05:57 -0700 Subject: [PATCH 1206/1772] Document that filesystem timestamps can be 0. (#124) * Document that filesystem timestamps can be 0. A value of 0 in a timestamp indicates the time is unknown. This ports #531 from Preview 1 to Preview 2. * Fix a copy+pasto. * Regenerate example-world.md. * Switch to `option` instead of special-casing 0. --- proposals/filesystem/example-world.md | 14 ++++++++++---- proposals/filesystem/wit/types.wit | 17 +++++++++++++---- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md index 7805cf870..533ff39f5 100644 --- a/proposals/filesystem/example-world.md +++ b/proposals/filesystem/example-world.md @@ -754,16 +754,22 @@ with the filesystem. length in bytes of the pathname contained in the symbolic link.
    • -

      data-access-timestamp: datetime

      +

      data-access-timestamp: option<datetime>

      Last data access timestamp. +

      If the option is none, the platform doesn't maintain an access +timestamp for this file.

    • -

      data-modification-timestamp: datetime

      +

      data-modification-timestamp: option<datetime>

      Last data modification timestamp. +

      If the option is none, the platform doesn't maintain a +modification timestamp for this file.

    • -

      status-change-timestamp: datetime

      -

      Last file status change timestamp. +

      status-change-timestamp: option<datetime>

      +

      Last file status-change timestamp. +

      If the option is none, the platform doesn't maintain a +status-change timestamp for this file.

    enum advice

    diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 9b1412d6d..c7e817d45 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -107,11 +107,20 @@ interface types { /// length in bytes of the pathname contained in the symbolic link. size: filesize, /// Last data access timestamp. - data-access-timestamp: datetime, + /// + /// If the `option` is none, the platform doesn't maintain an access + /// timestamp for this file. + data-access-timestamp: option, /// Last data modification timestamp. - data-modification-timestamp: datetime, - /// Last file status change timestamp. - status-change-timestamp: datetime, + /// + /// If the `option` is none, the platform doesn't maintain a + /// modification timestamp for this file. + data-modification-timestamp: option, + /// Last file status-change timestamp. + /// + /// If the `option` is none, the platform doesn't maintain a + /// status-change timestamp for this file. + status-change-timestamp: option, } /// Flags determining the method of how paths are resolved. From 90f951f4e0a6f9be083cf9cd5a28268dcba6f49f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 13 Sep 2023 12:53:32 -0700 Subject: [PATCH 1207/1772] Update to resources. Convert `tcp-socket`, `udp-socket`, `network`, and `resolve-address-stream` to resources. This also updates the dependencies to account for the changes in WebAssembly/wasi-io#46. --- proposals/sockets/.github/workflows/main.yml | 6 +- .../sockets/{example-world.md => imports.md} | 993 +++++++++--------- proposals/sockets/wit/deps.lock | 11 +- proposals/sockets/wit/deps.toml | 5 +- proposals/sockets/wit/deps/io/poll.wit | 34 + proposals/sockets/wit/deps/io/streams.wit | 454 ++++---- proposals/sockets/wit/deps/io/world.wit | 3 +- proposals/sockets/wit/deps/poll/poll.wit | 39 - proposals/sockets/wit/deps/poll/world.wit | 5 - proposals/sockets/wit/ip-name-lookup.wit | 58 +- proposals/sockets/wit/network.wit | 14 +- proposals/sockets/wit/tcp.wit | 466 ++++---- proposals/sockets/wit/udp.wit | 394 ++++--- proposals/sockets/wit/world.wit | 2 +- 14 files changed, 1273 insertions(+), 1211 deletions(-) rename proposals/sockets/{example-world.md => imports.md} (54%) create mode 100644 proposals/sockets/wit/deps/io/poll.wit delete mode 100644 proposals/sockets/wit/deps/poll/poll.wit delete mode 100644 proposals/sockets/wit/deps/poll/world.wit diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index 3cba299bc..cb345171f 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: ensure `./wit/deps` are in sync run: | curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.0/wit-deps-x86_64-unknown-linux-musl @@ -18,6 +18,4 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v13 - with: - wit-abi-tag: wit-abi-0.11.0 + - uses: WebAssembly/wit-abi-up-to-date@v14 diff --git a/proposals/sockets/example-world.md b/proposals/sockets/imports.md similarity index 54% rename from proposals/sockets/example-world.md rename to proposals/sockets/imports.md index 8c7452022..e6adfb36d 100644 --- a/proposals/sockets/example-world.md +++ b/proposals/sockets/imports.md @@ -1,10 +1,10 @@ -

    World example-world

    +

    World imports

    Params
    Return values
    -

    finish-connect: func

    +

    [method]udp-socket.finish-connect: func

    Params
    Return values
    -

    receive: func

    +

    [method]udp-socket.receive: func

    Receive messages on the socket.

    This function attempts to receive up to max-results datagrams on the socket without blocking. The returned list may contain fewer elements than requested, but never more. @@ -451,14 +426,14 @@ If max-results is 0, this function returns successfully with an emp

    Params
    Return values
    -

    send: func

    +

    [method]udp-socket.send: func

    Send messages on the socket.

    This function attempts to send all provided datagrams on the socket without blocking and returns how many messages were actually sent (or queued for sending).

    @@ -467,12 +442,12 @@ sending each individual datagram until either the end of the list has been reach If at least one datagram has been sent successfully, this function never returns an error.

    If the input list is empty, the function returns ok(0).

    The remote address option is required. To send a message to the "connected" peer, -call remote-address to get their address.

    +call remote-address to get their address.

    Typical errors

      -
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • -
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • -
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • already-connected: The socket is in "connected" mode and the datagram.remote-address does not match the address passed to connect. (EISCONN)
    • not-bound: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind.
    • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
    • @@ -492,14 +467,14 @@ call remote-address to get their addr
    Params
    Return values
    -

    local-address: func

    +

    [method]udp-socket.local-address: func

    Get the current bound address.

    Typical errors

    Params
    Return values
    -

    remote-address: func

    +

    [method]udp-socket.remote-address: func

    Get the address set with connect.

    Typical errors

    Params
    Return values
    -

    address-family: func

    +

    [method]udp-socket.address-family: func

    Whether this is a IPv4 or IPv6 socket.

    Equivalent to the SO_DOMAIN socket option.

    Params
    Return values
    -

    ipv6-only: func

    +

    [method]udp-socket.ipv6-only: func

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    Equivalent to the IPV6_V6ONLY socket option.

    Typical errors

    @@ -564,23 +539,23 @@ call remote-address to get their addr
    Params
    Return values
    -

    set-ipv6-only: func

    +

    [method]udp-socket.set-ipv6-only: func

    Params
    Return values
    -

    unicast-hop-limit: func

    +

    [method]udp-socket.unicast-hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    Typical errors

    Params
    Return values
    -

    set-unicast-hop-limit: func

    +

    [method]udp-socket.set-unicast-hop-limit: func

    Params
    Return values
    -

    receive-buffer-size: func

    +

    [method]udp-socket.receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    Note #1: an implementation may choose to cap or round the buffer size when setting the value. In other words, after setting a value, reading the same setting back may return a different value.

    @@ -618,59 +593,52 @@ for internal metadata structures.

    Params
    Return values
    -

    set-receive-buffer-size: func

    +

    [method]udp-socket.set-receive-buffer-size: func

    Params
    Return values
    -

    send-buffer-size: func

    +

    [method]udp-socket.send-buffer-size: func

    Params
    Return values
    -

    set-send-buffer-size: func

    +

    [method]udp-socket.set-send-buffer-size: func

    Params
    Return values
    -

    subscribe: func

    +

    [method]udp-socket.subscribe: func

    Create a pollable which will resolve once the socket is ready for I/O.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    drop-udp-socket: func

    -

    Dispose of the specified udp-socket, after which it may no longer be used.

    -

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    -
    Params
    -

    Import interface wasi:sockets/udp-create-socket


    @@ -699,7 +667,7 @@ the socket is effectively an in-memory configuration object, unable to communica

    Typical errors

    • not-supported: The host does not support UDP sockets. (EOPNOTSUPP)
    • -
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • +
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)

    References:

    @@ -711,11 +679,11 @@ the socket is effectively an in-memory configuration object, unable to communica
    Params
    Return values

    Import interface wasi:io/streams

    WASI I/O is an I/O abstraction API which is currently focused on providing @@ -727,183 +695,287 @@ when it does, they are expected to subsume this API.

    type pollable

    pollable

    -#### `record stream-error` -

    An error type returned from a stream operation. Currently this -doesn't provide any additional information.

    -
    Record Fields
    -

    type output-stream

    -

    u32

    -

    An output bytestream. In the future, this will be replaced by handle -types. -

    This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

    -

    output-streams are non-blocking to the extent practical on -underlying platforms. Except where specified otherwise, I/O operations also -always return promptly, after the number of bytes that can be written -promptly, which could even be zero. To wait for the stream to be ready to -accept data, the subscribe-to-output-stream function to obtain a -pollable which can be polled for using wasi_poll.

    -

    And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

    -

    This represents a resource.

    -

    type input-stream

    -

    u32

    -

    An input bytestream. In the future, this will be replaced by handle -types. -

    This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

    -

    input-streams are non-blocking to the extent practical on underlying -platforms. I/O operations always return promptly; if fewer bytes are -promptly available than requested, they return the number of bytes promptly -available, which could even be zero. To wait for data to be available, -use the subscribe-to-input-stream function to obtain a pollable which -can be polled for using wasi_poll.

    -

    And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

    -

    This represents a resource.

    +#### `enum stream-status` +

    Streams provide a sequence of data and then end; once they end, they +no longer provide any further data.

    +

    For example, a stream reading from a file ends when the stream reaches +the end of the file. For another example, a stream reading from a +socket ends when the socket is closed.

    +
    Enum Cases
    +
      +
    • +

      open

      +

      The stream is open and may produce further data. +

    • +
    • +

      ended

      +

      When reading, this indicates that the stream will not produce +further data. +When writing, this indicates that the stream will no longer be read. +Further writes are still permitted. +

    • +
    +

    resource input-stream

    +

    enum write-error

    +

    An error for output-stream operations.

    +

    Contrary to input-streams, a closed output-stream is reported using +an error.

    +
    Enum Cases
    +
      +
    • +

      last-operation-failed

      +

      The last operation (a write or flush) failed before completion. +

    • +
    • +

      closed

      +

      The stream is closed: no more input will be accepted by the +stream. A closed output-stream will return this error on all +future operations. +

    • +
    +

    resource output-stream


    Functions

    -

    read: func

    -

    Read bytes from a stream.

    +

    [method]input-stream.read: func

    +

    Perform a non-blocking read from the stream.

    This function returns a list of bytes containing the data that was -read, along with a bool which, when true, indicates that the end of the -stream was reached. The returned list will contain up to len bytes; it -may return fewer than requested, but not more.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more +read, along with a stream-status which, indicates whether further +reads are expected to produce data. The returned list will contain up to +len bytes; it may return fewer than requested, but not more. An +empty list and stream-status:open indicates no more data is +available at this time, and that the pollable given by subscribe +will be ready when more data is available.

    +

    Once a stream has reached the end, subsequent calls to read or +skip will always report stream-status:ended rather than producing more data.

    -

    If len is 0, it represents a request to read 0 bytes, which should -always succeed, assuming the stream hasn't reached its end yet, and -return an empty list.

    -

    The len here is a u64, but some callees may not be able to allocate -a buffer as large as that would imply. -FIXME: describe what happens if allocation fails.

    +

    When the caller gives a len of 0, it represents a request to read 0 +bytes. This read should always succeed and return an empty list and +the current stream-status.

    +

    The len parameter is a u64, which could represent a list of u8 which +is not possible to allocate in wasm32, or not desirable to allocate as +as a return value by the callee. The callee may return a list of bytes +less than len in size while more bytes are available for reading.

    Params
    Return values
    -

    blocking-read: func

    -

    Read bytes from a stream, with blocking.

    -

    This is similar to read, except that it blocks until at least one -byte can be read.

    +

    [method]input-stream.blocking-read: func

    +

    Read bytes from a stream, after blocking until at least one byte can +be read. Except for blocking, identical to read.

    Params
    Return values
    -

    skip: func

    +

    [method]input-stream.skip: func

    Skip bytes from a stream.

    -

    This is similar to the read function, but avoids copying the +

    This is similar to the read function, but avoids copying the bytes into the instance.

    Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more +skip will always report end-of-stream rather than producing more data.

    -

    This function returns the number of bytes skipped, along with a bool -indicating whether the end of the stream was reached. The returned -value will be at most len; it may be less.

    +

    This function returns the number of bytes skipped, along with a +stream-status indicating whether the end of the stream was +reached. The returned value will be at most len; it may be less.

    Params
    Return values
    -

    blocking-skip: func

    -

    Skip bytes from a stream, with blocking.

    -

    This is similar to skip, except that it blocks until at least one -byte can be consumed.

    +

    [method]input-stream.blocking-skip: func

    +

    Skip bytes from a stream, after blocking until at least one byte +can be skipped. Except for blocking behavior, identical to skip.

    Params
    Return values
    -

    subscribe-to-input-stream: func

    +

    [method]input-stream.subscribe: func

    Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been -closed.

    +closed. +The created pollable is a child resource of the input-stream. +Implementations may trap if the input-stream is dropped before +all derived pollables created with this function are dropped.

    Params
    Return values
    -

    drop-input-stream: func

    -

    Dispose of the specified input-stream, after which it may no longer -be used.

    +

    [method]output-stream.check-write: func

    +

    Check readiness for writing. This function never blocks.

    +

    Returns the number of bytes permitted for the next call to write, +or an error. Calling write with more bytes than this function has +permitted will trap.

    +

    When this function returns 0 bytes, the subscribe pollable will +become ready when this function will report at least 1 byte, or an +error.

    Params
    -

    write: func

    -

    Write bytes to a stream.

    -

    This function returns a u64 indicating the number of bytes from -buf that were written; it may be less than the full list.

    +
    Return values
    + +

    [method]output-stream.write: func

    +

    Perform a write. This function never blocks.

    +

    Precondition: check-write gave permit of Ok(n) and contents has a +length of less than or equal to n. Otherwise, this function will trap.

    +

    returns Err(closed) without writing if the stream has closed since +the last call to check-write provided a permit.

    Params
    +
    Return values
    + +

    [method]output-stream.blocking-write-and-flush: func

    +

    Perform a write of up to 4096 bytes, and then flush the stream. Block +until all of these operations are complete, or an error occurs.

    +

    This is a convenience wrapper around the use of check-write, +subscribe, write, and flush, and is implemented with the +following pseudo-code:

    +
    let pollable = this.subscribe();
    +while !contents.is_empty() {
    +  // Wait for the stream to become writable
    +  poll-one(pollable);
    +  let Ok(n) = this.check-write(); // eliding error handling
    +  let len = min(n, contents.len());
    +  let (chunk, rest) = contents.split_at(len);
    +  this.write(chunk  );            // eliding error handling
    +  contents = rest;
    +}
    +this.flush();
    +// Wait for completion of `flush`
    +poll-one(pollable);
    +// Check for any errors that arose during `flush`
    +let _ = this.check-write();         // eliding error handling
    +
    +
    Params
    +
    Return values
    -

    blocking-write: func

    -

    Write bytes to a stream, with blocking.

    -

    This is similar to write, except that it blocks until at least one -byte can be written.

    +

    [method]output-stream.flush: func

    +

    Request to flush buffered output. This function never blocks.

    +

    This tells the output-stream that the caller intends any buffered +output to be flushed. the output which is expected to be flushed +is all that has been passed to write prior to this call.

    +

    Upon calling this function, the output-stream will not accept any +writes (check-write will return ok(0)) until the flush has +completed. The subscribe pollable will become ready when the +flush has completed and the stream can accept more writes.

    Params
    Return values
    -

    write-zeroes: func

    -

    Write multiple zero bytes to a stream.

    -

    This function returns a u64 indicating the number of zero bytes -that were written; it may be less than len.

    +

    [method]output-stream.blocking-flush: func

    +

    Request to flush buffered output, and block until flush completes +and stream is ready for writing again.

    Params
    Return values
    -

    blocking-write-zeroes: func

    -

    Write multiple zero bytes to a stream, with blocking.

    -

    This is similar to write-zeroes, except that it blocks until at least -one byte can be written.

    +

    [method]output-stream.subscribe: func

    +

    Create a pollable which will resolve once the output-stream +is ready for more writing, or an error has occured. When this +pollable is ready, check-write will return ok(n) with n>0, or an +error.

    +

    If the stream is closed, this pollable is always ready immediately.

    +

    The created pollable is a child resource of the output-stream. +Implementations may trap if the output-stream is dropped before +all derived pollables created with this function are dropped.

    Params
    +
    Return values
    + +

    [method]output-stream.write-zeroes: func

    +

    Write zeroes to a stream.

    +

    this should be used precisely like write with the exact same +preconditions (must use check-write first), but instead of +passing a list of bytes, you simply pass the number of zero-bytes +that should be written.

    +
    Params
    + +
    Return values
    + +

    [method]output-stream.blocking-write-zeroes-and-flush: func

    +

    Perform a write of up to 4096 zeroes, and then flush the stream. +Block until all of these operations are complete, or an error +occurs.

    +

    This is a convenience wrapper around the use of check-write, +subscribe, write-zeroes, and flush, and is implemented with +the following pseudo-code:

    +
    let pollable = this.subscribe();
    +while num_zeroes != 0 {
    +  // Wait for the stream to become writable
    +  poll-one(pollable);
    +  let Ok(n) = this.check-write(); // eliding error handling
    +  let len = min(n, num_zeroes);
    +  this.write-zeroes(len);         // eliding error handling
    +  num_zeroes -= len;
    +}
    +this.flush();
    +// Wait for completion of `flush`
    +poll-one(pollable);
    +// Check for any errors that arose during `flush`
    +let _ = this.check-write();         // eliding error handling
    +
    +
    Params
    +
    Return values
    -

    splice: func

    +

    [method]output-stream.splice: func

    Read from one stream and write to another.

    This function returns the number of bytes transferred; it may be less than len.

    @@ -911,29 +983,29 @@ than len.

    read from the input stream has been written to the output stream.

    Params
    Return values
    -

    blocking-splice: func

    +

    [method]output-stream.blocking-splice: func

    Read from one stream and write to another, with blocking.

    -

    This is similar to splice, except that it blocks until at least +

    This is similar to splice, except that it blocks until at least one byte can be read.

    Params
    Return values
    -

    forward: func

    +

    [method]output-stream.forward: func

    Forward the entire contents of an input stream to an output stream.

    This function repeatedly reads from the input stream and writes the data to the output stream, until the end of the input stream @@ -941,33 +1013,16 @@ is reached, or an error is encountered.

    Unlike other I/O functions, this function blocks until the end of the input stream is seen and all the data has been written to the output stream.

    -

    This function returns the number of bytes transferred.

    -
    Params
    - -
    Return values
    - -

    subscribe-to-output-stream: func

    -

    Create a pollable which will resolve once either the specified stream -is ready to accept bytes or the other end of the stream has been closed.

    +

    This function returns the number of bytes transferred, and the status of +the output stream.

    Params
    Return values
    -

    drop-output-stream: func

    -

    Dispose of the specified output-stream, after which it may no longer -be used.

    -
    Params
    -

    Import interface wasi:sockets/tcp


    @@ -993,18 +1048,15 @@ be used.

    #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `type tcp-socket` -`u32` -

    A TCP socket handle. -

    enum shutdown-type

    +#### `enum shutdown-type`
    Enum Cases
    • -

      receive

      +

      receive

      Similar to `SHUT_RD` in POSIX.

    • -

      send

      +

      send

      Similar to `SHUT_WR` in POSIX.

    • @@ -1012,9 +1064,10 @@ be used.

      Similar to `SHUT_RDWR` in POSIX.

    +

    resource tcp-socket


    Functions

    -

    start-bind: func

    +

    [method]tcp-socket.start-bind: func

    Bind the socket to a specific network on the provided IP address and port.

    If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -1024,7 +1077,7 @@ implicitly bind the socket.

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    Typical start errors

      -
    • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
    • +
    • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
    • already-bound: The socket is already bound. (EINVAL)
    • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
    @@ -1032,7 +1085,7 @@ implicitly bind the socket.

    • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
    • address-in-use: Address is already in use. (EADDRINUSE)
    • -
    • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
    • +
    • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
    • not-in-progress: A bind operation is not in progress.
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    @@ -1045,24 +1098,24 @@ implicitly bind the socket.

    Params
    Return values
    -

    finish-bind: func

    +

    [method]tcp-socket.finish-bind: func

    Params
    Return values
    -

    start-connect: func

    +

    [method]tcp-socket.start-connect: func

    Connect to a remote endpoint.

    On success:

      @@ -1071,9 +1124,9 @@ implicitly bind the socket.

    Typical start errors

      -
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • -
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
    • -
    • invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
    • +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
    • already-attached: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
    • already-connected: The socket is already in the Connection state. (EISCONN)
    • already-listening: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
    • @@ -1098,24 +1151,24 @@ implicitly bind the socket.

    Params
    Return values
    -

    finish-connect: func

    +

    [method]tcp-socket.finish-connect: func

    Params
    Return values
    -

    start-listen: func

    +

    [method]tcp-socket.start-listen: func

    Start listening for new connections.

    Transitions the socket into the Listener state.

    Unlike POSIX:

    @@ -1145,22 +1198,22 @@ implicitly bind the socket.

    Params
    Return values
    -

    finish-listen: func

    +

    [method]tcp-socket.finish-listen: func

    Params
    Return values
    -

    accept: func

    +

    [method]tcp-socket.accept: func

    Accept a new client socket.

    The returned socket is bound and in the Connection state.

    On success, this function returns the newly accepted client socket along with @@ -1180,13 +1233,13 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    local-address: func

    +

    [method]tcp-socket.local-address: func

    Get the bound local address.

    Typical errors

      @@ -1201,13 +1254,13 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    remote-address: func

    +

    [method]tcp-socket.remote-address: func

    Get the bound remote address.

    Typical errors

      @@ -1222,24 +1275,24 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    address-family: func

    +

    [method]tcp-socket.address-family: func

    Whether this is a IPv4 or IPv6 socket.

    Equivalent to the SO_DOMAIN socket option.

    Params
    Return values
    -

    ipv6-only: func

    +

    [method]tcp-socket.ipv6-only: func

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    Equivalent to the IPV6_V6ONLY socket option.

    Typical errors

    @@ -1251,23 +1304,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-ipv6-only: func

    +

    [method]tcp-socket.set-ipv6-only: func

    Params
    Return values
    -

    set-listen-backlog-size: func

    +

    [method]tcp-socket.set-listen-backlog-size: func

    Hints the desired listen queue size. Implementations are free to ignore this.

    Typical errors

      @@ -1276,14 +1329,14 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    keep-alive: func

    +

    [method]tcp-socket.keep-alive: func

    Equivalent to the SO_KEEPALIVE socket option.

    Typical errors

      @@ -1291,23 +1344,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-keep-alive: func

    +

    [method]tcp-socket.set-keep-alive: func

    Params
    Return values
    -

    no-delay: func

    +

    [method]tcp-socket.no-delay: func

    Equivalent to the TCP_NODELAY socket option.

    Typical errors

      @@ -1315,23 +1368,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-no-delay: func

    +

    [method]tcp-socket.set-no-delay: func

    Params
    Return values
    -

    unicast-hop-limit: func

    +

    [method]tcp-socket.unicast-hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    Typical errors

      @@ -1341,23 +1394,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-unicast-hop-limit: func

    +

    [method]tcp-socket.set-unicast-hop-limit: func

    Params
    Return values
    -

    receive-buffer-size: func

    +

    [method]tcp-socket.receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    Note #1: an implementation may choose to cap or round the buffer size when setting the value. In other words, after setting a value, reading the same setting back may return a different value.

    @@ -1373,59 +1426,59 @@ for internal metadata structures.

    Params
    Return values
    -

    set-receive-buffer-size: func

    +

    [method]tcp-socket.set-receive-buffer-size: func

    Params
    Return values
    -

    send-buffer-size: func

    +

    [method]tcp-socket.send-buffer-size: func

    Params
    Return values
    -

    set-send-buffer-size: func

    +

    [method]tcp-socket.set-send-buffer-size: func

    Params
    Return values
    -

    subscribe: func

    +

    [method]tcp-socket.subscribe: func

    Create a pollable which will resolve once the socket is ready for I/O.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    shutdown: func

    +

    [method]tcp-socket.shutdown: func

    Initiate a graceful shutdown.

    • receive: the socket is not expecting to receive any more data from the peer. All subsequent read operations on the input-stream associated with this socket will return an End Of Stream indication. -Any data still in the receive queue at time of calling shutdown will be discarded.
    • +Any data still in the receive queue at time of calling shutdown will be discarded.
    • send: the socket is not expecting to send any more data to the peer. All subsequent write operations on the output-stream associated with this socket will return an error.
    • both: same effect as receive & send combined.
    • @@ -1444,20 +1497,12 @@ operations on the output-stream associ
    Params
    Return values
    -

    drop-tcp-socket: func

    -

    Dispose of the specified tcp-socket, after which it may no longer be used.

    -

    Similar to the POSIX close function.

    -

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    -
    Params
    -

    Import interface wasi:sockets/tcp-create-socket


    @@ -1486,7 +1531,7 @@ is called, the socket is effectively an in-memory configuration object, unable t

    Typical errors

    • not-supported: The host does not support TCP sockets. (EOPNOTSUPP)
    • -
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • +
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)

    References

    @@ -1498,11 +1543,11 @@ is called, the socket is effectively an in-memory configuration object, unable t
    Params
    Return values

    Import interface wasi:sockets/ip-name-lookup


    @@ -1522,10 +1567,8 @@ is called, the socket is effectively an in-memory configuration object, unable t #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `type resolve-address-stream` -`u32` -

    ----- +#### `resource resolve-address-stream` +


    Functions

    resolve-addresses: func

    Resolve an internet host name to a list of IP addresses.

    @@ -1534,7 +1577,7 @@ is called, the socket is effectively an in-memory configuration object, unable t
    • name: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted to ASCII using IDNA encoding.
    • -
    • address-family: If provided, limit the results to addresses of this specific address family.
    • +
    • address-family: If provided, limit the results to addresses of this specific address family.
    • include-unavailable: When set to true, this function will also return addresses of which the runtime thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on systems without an active IPv6 interface. Notes:
    • @@ -1544,12 +1587,12 @@ systems without an active IPv6 interface. Notes:

      This function never blocks. It either immediately fails or immediately returns successfully with a resolve-address-stream that can be used to (asynchronously) fetch the results.

      At the moment, the stream never completes successfully with 0 items. Ie. the first call -to resolve-next-address never returns ok(none). This may change in the future.

      +to resolve-next-address never returns ok(none). This may change in the future.

      Typical errors

      • invalid-name: name is a syntactically invalid domain name.
      • invalid-name: name is an IP address.
      • -
      • address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)
      • +
      • address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)

      References:

      Params
      Return values
      -

      resolve-next-address: func

      +

      [method]resolve-address-stream.resolve-next-address: func

      Returns the next address from the resolver.

      This function should be called multiple times. On each call, it will return the next address in connection order preference. If all -addresses have been exhausted, this function returns none. -After which, you should release the stream with drop-resolve-address-stream.

      +addresses have been exhausted, this function returns none.

      This function never returns IPv4-mapped IPv6 addresses.

      Typical errors

      Return values
      -

      drop-resolve-address-stream: func

      -

      Dispose of the specified resolve-address-stream, after which it may no longer be used.

      -

      Note: this function is scheduled to be removed when Resources are natively supported in Wit.

      -
      Params
      - -

      subscribe: func

      +

      [method]resolve-address-stream.subscribe: func

      Create a pollable which will resolve once the stream is ready for I/O.

      Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

      Params
      Return values
      diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index 3f5f5aced..3d68907bc 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,9 +1,4 @@ [io] -url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "eeb4701c2becafa40a7ee3bf0d2c94e2170e15806b25abdcd1de1ed94f2c1036" -sha512 = "89be853b2acae211570cd6ad0ec9d8132881dafbdea83ac7b4cad600f0627003c61f310427379bf47ecf862724367bd5d6e976db70069f6f90a3c2d9c20dbfb7" - -[poll] -url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -sha256 = "9f8bb4d9994e9b0684859bb1e8bee2a8b873e04d40695f260446760fc44d0c58" -sha512 = "aa8da395ba6e189ec113296996da5abf28bdc4460e4eb2aacc786698ced892e08f7054fb590fc8809c05554d5c83a11494d4ab68c755746f57d151e212415cfb" +url = "https://github.com/sunfishcode/wasi-io/archive/resources.tar.gz" +sha256 = "6e20bcf4d4f5466b60c05ea8da7289ca361a7febdd22ab1a531e5ef7e394ab8d" +sha512 = "21f6689bce6ed6d9e3bd96372e5c7ed003a7aefbf8d49b4eea949dfbd265cf57a0d7dc67aa71e3de75d48fcc2c0cfe5f06f7e9e7959a23bc98f77da85f4161b9" diff --git a/proposals/sockets/wit/deps.toml b/proposals/sockets/wit/deps.toml index 2616e30df..671c3f141 100644 --- a/proposals/sockets/wit/deps.toml +++ b/proposals/sockets/wit/deps.toml @@ -1,2 +1,3 @@ -io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" +# Temporarily use the resources branches. +#io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +io = "https://github.com/sunfishcode/wasi-io/archive/resources.tar.gz" diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit new file mode 100644 index 000000000..e95762b91 --- /dev/null +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -0,0 +1,34 @@ +package wasi:io + +/// A poll API intended to let users wait for I/O events on multiple handles +/// at once. +interface poll { + /// A "pollable" handle. + resource pollable + + /// Poll for completion on a set of pollables. + /// + /// This function takes a list of pollables, which identify I/O sources of + /// interest, and waits until one or more of the events is ready for I/O. + /// + /// The result `list` contains one or more indices of handles in the + /// argument list that is ready for I/O. + /// + /// If the list contains more elements than can be indexed with a `u32` + /// value, this function traps. + /// + /// A timeout can be implemented by adding a pollable from the + /// wasi-clocks API to the list. + /// + /// This function does not return a `result`; polling in itself does not + /// do any I/O so it doesn't fail. If any of the I/O sources identified by + /// the pollables has an error, it is indicated by marking the source as + /// being reaedy for I/O. + poll-list: func(in: list>) -> list + + /// Poll for completion on a single pollable. + /// + /// This function is similar to `poll-list`, but operates on only a single + /// pollable. When it returns, the handle is ready for I/O. + poll-one: func(in: borrow) +} diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index 430c1d441..eeeff5058 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -1,213 +1,285 @@ +package wasi:io + /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { - use wasi:poll/poll.{pollable} - - /// An error type returned from a stream operation. Currently this - /// doesn't provide any additional information. - record stream-error {} + use poll.{pollable} - /// An input bytestream. In the future, this will be replaced by handle - /// types. + /// Streams provide a sequence of data and then end; once they end, they + /// no longer provide any further data. /// - /// This conceptually represents a `stream`. It's temporary - /// scaffolding until component-model's async features are ready. + /// For example, a stream reading from a file ends when the stream reaches + /// the end of the file. For another example, a stream reading from a + /// socket ends when the socket is closed. + enum stream-status { + /// The stream is open and may produce further data. + open, + /// When reading, this indicates that the stream will not produce + /// further data. + /// When writing, this indicates that the stream will no longer be read. + /// Further writes are still permitted. + ended, + } + + /// An input bytestream. /// /// `input-stream`s are *non-blocking* to the extent practical on underlying /// platforms. I/O operations always return promptly; if fewer bytes are /// promptly available than requested, they return the number of bytes promptly /// available, which could even be zero. To wait for data to be available, - /// use the `subscribe-to-input-stream` function to obtain a `pollable` which - /// can be polled for using `wasi_poll`. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type input-stream = u32 + /// use the `subscribe` function to obtain a `pollable` which can be polled + /// for using `wasi:io/poll`. + resource input-stream { + /// Perform a non-blocking read from the stream. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a `stream-status` which, indicates whether further + /// reads are expected to produce data. The returned list will contain up to + /// `len` bytes; it may return fewer than requested, but not more. An + /// empty list and `stream-status:open` indicates no more data is + /// available at this time, and that the pollable given by `subscribe` + /// will be ready when more data is available. + /// + /// Once a stream has reached the end, subsequent calls to `read` or + /// `skip` will always report `stream-status:ended` rather than producing more + /// data. + /// + /// When the caller gives a `len` of 0, it represents a request to read 0 + /// bytes. This read should always succeed and return an empty list and + /// the current `stream-status`. + /// + /// The `len` parameter is a `u64`, which could represent a list of u8 which + /// is not possible to allocate in wasm32, or not desirable to allocate as + /// as a return value by the callee. The callee may return a list of bytes + /// less than `len` in size while more bytes are available for reading. + read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-status>> - /// Read bytes from a stream. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a bool which, when true, indicates that the end of the - /// stream was reached. The returned list will contain up to `len` bytes; it - /// may return fewer than requested, but not more. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// If `len` is 0, it represents a request to read 0 bytes, which should - /// always succeed, assuming the stream hasn't reached its end yet, and - /// return an empty list. - /// - /// The len here is a `u64`, but some callees may not be able to allocate - /// a buffer as large as that would imply. - /// FIXME: describe what happens if allocation fails. - read: func( - this: input-stream, - /// The maximum number of bytes to read - len: u64 - ) -> result, bool>, stream-error> - - /// Read bytes from a stream, with blocking. - /// - /// This is similar to `read`, except that it blocks until at least one - /// byte can be read. - blocking-read: func( - this: input-stream, - /// The maximum number of bytes to read - len: u64 - ) -> result, bool>, stream-error> - - /// Skip bytes from a stream. - /// - /// This is similar to the `read` function, but avoids copying the - /// bytes into the instance. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// This function returns the number of bytes skipped, along with a bool - /// indicating whether the end of the stream was reached. The returned - /// value will be at most `len`; it may be less. - skip: func( - this: input-stream, - /// The maximum number of bytes to skip. - len: u64, - ) -> result, stream-error> - - /// Skip bytes from a stream, with blocking. - /// - /// This is similar to `skip`, except that it blocks until at least one - /// byte can be consumed. - blocking-skip: func( - this: input-stream, - /// The maximum number of bytes to skip. - len: u64, - ) -> result, stream-error> - - /// Create a `pollable` which will resolve once either the specified stream - /// has bytes available to read or the other end of the stream has been - /// closed. - subscribe-to-input-stream: func(this: input-stream) -> pollable - - /// Dispose of the specified `input-stream`, after which it may no longer - /// be used. - drop-input-stream: func(this: input-stream) - - /// An output bytestream. In the future, this will be replaced by handle - /// types. + /// Read bytes from a stream, after blocking until at least one byte can + /// be read. Except for blocking, identical to `read`. + blocking-read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-status>> + + /// Skip bytes from a stream. + /// + /// This is similar to the `read` function, but avoids copying the + /// bytes into the instance. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// This function returns the number of bytes skipped, along with a + /// `stream-status` indicating whether the end of the stream was + /// reached. The returned value will be at most `len`; it may be less. + skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result> + + /// Skip bytes from a stream, after blocking until at least one byte + /// can be skipped. Except for blocking behavior, identical to `skip`. + blocking-skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result> + + /// Create a `pollable` which will resolve once either the specified stream + /// has bytes available to read or the other end of the stream has been + /// closed. + /// The created `pollable` is a child resource of the `input-stream`. + /// Implementations may trap if the `input-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe: func() -> pollable + } + + /// An error for output-stream operations. /// - /// This conceptually represents a `stream`. It's temporary - /// scaffolding until component-model's async features are ready. + /// Contrary to input-streams, a closed output-stream is reported using + /// an error. + enum write-error { + /// The last operation (a write or flush) failed before completion. + last-operation-failed, + /// The stream is closed: no more input will be accepted by the + /// stream. A closed output-stream will return this error on all + /// future operations. + closed + } + + /// An output bytestream. /// /// `output-stream`s are *non-blocking* to the extent practical on /// underlying platforms. Except where specified otherwise, I/O operations also /// always return promptly, after the number of bytes that can be written /// promptly, which could even be zero. To wait for the stream to be ready to - /// accept data, the `subscribe-to-output-stream` function to obtain a - /// `pollable` which can be polled for using `wasi_poll`. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type output-stream = u32 + /// accept data, the `subscribe` function to obtain a `pollable` which can be + /// polled for using `wasi:io/poll`. + resource output-stream { + /// Check readiness for writing. This function never blocks. + /// + /// Returns the number of bytes permitted for the next call to `write`, + /// or an error. Calling `write` with more bytes than this function has + /// permitted will trap. + /// + /// When this function returns 0 bytes, the `subscribe` pollable will + /// become ready when this function will report at least 1 byte, or an + /// error. + check-write: func() -> result - /// Write bytes to a stream. - /// - /// This function returns a `u64` indicating the number of bytes from - /// `buf` that were written; it may be less than the full list. - write: func( - this: output-stream, - /// Data to write - buf: list - ) -> result - - /// Write bytes to a stream, with blocking. - /// - /// This is similar to `write`, except that it blocks until at least one - /// byte can be written. - blocking-write: func( - this: output-stream, - /// Data to write - buf: list - ) -> result - - /// Write multiple zero bytes to a stream. - /// - /// This function returns a `u64` indicating the number of zero bytes - /// that were written; it may be less than `len`. - write-zeroes: func( - this: output-stream, - /// The number of zero bytes to write - len: u64 - ) -> result - - /// Write multiple zero bytes to a stream, with blocking. - /// - /// This is similar to `write-zeroes`, except that it blocks until at least - /// one byte can be written. - blocking-write-zeroes: func( - this: output-stream, - /// The number of zero bytes to write - len: u64 - ) -> result - - /// Read from one stream and write to another. - /// - /// This function returns the number of bytes transferred; it may be less - /// than `len`. - /// - /// Unlike other I/O functions, this function blocks until all the data - /// read from the input stream has been written to the output stream. - splice: func( - this: output-stream, - /// The stream to read from - src: input-stream, - /// The number of bytes to splice - len: u64, - ) -> result, stream-error> - - /// Read from one stream and write to another, with blocking. - /// - /// This is similar to `splice`, except that it blocks until at least - /// one byte can be read. - blocking-splice: func( - this: output-stream, - /// The stream to read from - src: input-stream, - /// The number of bytes to splice - len: u64, - ) -> result, stream-error> - - /// Forward the entire contents of an input stream to an output stream. - /// - /// This function repeatedly reads from the input stream and writes - /// the data to the output stream, until the end of the input stream - /// is reached, or an error is encountered. - /// - /// Unlike other I/O functions, this function blocks until the end - /// of the input stream is seen and all the data has been written to - /// the output stream. - /// - /// This function returns the number of bytes transferred. - forward: func( - this: output-stream, - /// The stream to read from - src: input-stream - ) -> result - - /// Create a `pollable` which will resolve once either the specified stream - /// is ready to accept bytes or the other end of the stream has been closed. - subscribe-to-output-stream: func(this: output-stream) -> pollable - - /// Dispose of the specified `output-stream`, after which it may no longer - /// be used. - drop-output-stream: func(this: output-stream) + /// Perform a write. This function never blocks. + /// + /// Precondition: check-write gave permit of Ok(n) and contents has a + /// length of less than or equal to n. Otherwise, this function will trap. + /// + /// returns Err(closed) without writing if the stream has closed since + /// the last call to check-write provided a permit. + write: func( + contents: list + ) -> result<_, write-error> + + /// Perform a write of up to 4096 bytes, and then flush the stream. Block + /// until all of these operations are complete, or an error occurs. + /// + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe`, `write`, and `flush`, and is implemented with the + /// following pseudo-code: + /// + /// ```text + /// let pollable = this.subscribe(); + /// while !contents.is_empty() { + /// // Wait for the stream to become writable + /// poll-one(pollable); + /// let Ok(n) = this.check-write(); // eliding error handling + /// let len = min(n, contents.len()); + /// let (chunk, rest) = contents.split_at(len); + /// this.write(chunk ); // eliding error handling + /// contents = rest; + /// } + /// this.flush(); + /// // Wait for completion of `flush` + /// poll-one(pollable); + /// // Check for any errors that arose during `flush` + /// let _ = this.check-write(); // eliding error handling + /// ``` + blocking-write-and-flush: func( + contents: list + ) -> result<_, write-error> + + /// Request to flush buffered output. This function never blocks. + /// + /// This tells the output-stream that the caller intends any buffered + /// output to be flushed. the output which is expected to be flushed + /// is all that has been passed to `write` prior to this call. + /// + /// Upon calling this function, the `output-stream` will not accept any + /// writes (`check-write` will return `ok(0)`) until the flush has + /// completed. The `subscribe` pollable will become ready when the + /// flush has completed and the stream can accept more writes. + flush: func() -> result<_, write-error> + + /// Request to flush buffered output, and block until flush completes + /// and stream is ready for writing again. + blocking-flush: func() -> result<_, write-error> + + /// Create a `pollable` which will resolve once the output-stream + /// is ready for more writing, or an error has occured. When this + /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an + /// error. + /// + /// If the stream is closed, this pollable is always ready immediately. + /// + /// The created `pollable` is a child resource of the `output-stream`. + /// Implementations may trap if the `output-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe: func() -> pollable + + /// Write zeroes to a stream. + /// + /// this should be used precisely like `write` with the exact same + /// preconditions (must use check-write first), but instead of + /// passing a list of bytes, you simply pass the number of zero-bytes + /// that should be written. + write-zeroes: func( + /// The number of zero-bytes to write + len: u64 + ) -> result<_, write-error> + + /// Perform a write of up to 4096 zeroes, and then flush the stream. + /// Block until all of these operations are complete, or an error + /// occurs. + /// + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with + /// the following pseudo-code: + /// + /// ```text + /// let pollable = this.subscribe(); + /// while num_zeroes != 0 { + /// // Wait for the stream to become writable + /// poll-one(pollable); + /// let Ok(n) = this.check-write(); // eliding error handling + /// let len = min(n, num_zeroes); + /// this.write-zeroes(len); // eliding error handling + /// num_zeroes -= len; + /// } + /// this.flush(); + /// // Wait for completion of `flush` + /// poll-one(pollable); + /// // Check for any errors that arose during `flush` + /// let _ = this.check-write(); // eliding error handling + /// ``` + blocking-write-zeroes-and-flush: func( + /// The number of zero-bytes to write + len: u64 + ) -> result<_, write-error> + + /// Read from one stream and write to another. + /// + /// This function returns the number of bytes transferred; it may be less + /// than `len`. + /// + /// Unlike other I/O functions, this function blocks until all the data + /// read from the input stream has been written to the output stream. + splice: func( + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result> + + /// Read from one stream and write to another, with blocking. + /// + /// This is similar to `splice`, except that it blocks until at least + /// one byte can be read. + blocking-splice: func( + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result> + + /// Forward the entire contents of an input stream to an output stream. + /// + /// This function repeatedly reads from the input stream and writes + /// the data to the output stream, until the end of the input stream + /// is reached, or an error is encountered. + /// + /// Unlike other I/O functions, this function blocks until the end + /// of the input stream is seen and all the data has been written to + /// the output stream. + /// + /// This function returns the number of bytes transferred, and the status of + /// the output stream. + forward: func( + /// The stream to read from + src: input-stream + ) -> result> + } } diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit index b7f625334..8738dba75 100644 --- a/proposals/sockets/wit/deps/io/world.wit +++ b/proposals/sockets/wit/deps/io/world.wit @@ -1,5 +1,6 @@ package wasi:io -world example-world { +world imports { import streams + import poll } diff --git a/proposals/sockets/wit/deps/poll/poll.wit b/proposals/sockets/wit/deps/poll/poll.wit deleted file mode 100644 index 55eee0029..000000000 --- a/proposals/sockets/wit/deps/poll/poll.wit +++ /dev/null @@ -1,39 +0,0 @@ -/// A poll API intended to let users wait for I/O events on multiple handles -/// at once. -interface poll { - /// A "pollable" handle. - /// - /// This is conceptually represents a `stream<_, _>`, or in other words, - /// a stream that one can wait on, repeatedly, but which does not itself - /// produce any data. It's temporary scaffolding until component-model's - /// async features are ready. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// `pollable` lifetimes are not automatically managed. Users must ensure - /// that they do not outlive the resource they reference. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type pollable = u32 - - /// Dispose of the specified `pollable`, after which it may no longer - /// be used. - drop-pollable: func(this: pollable) - - /// Poll for completion on a set of pollables. - /// - /// The "oneoff" in the name refers to the fact that this function must do a - /// linear scan through the entire list of subscriptions, which may be - /// inefficient if the number is large and the same subscriptions are used - /// many times. In the future, this is expected to be obsoleted by the - /// component model async proposal, which will include a scalable waiting - /// facility. - /// - /// Note that the return type would ideally be `list`, but that would - /// be more difficult to polyfill given the current state of `wit-bindgen`. - /// See - /// for details. For now, we use zero to mean "not ready" and non-zero to - /// mean "ready". - poll-oneoff: func(in: list) -> list -} diff --git a/proposals/sockets/wit/deps/poll/world.wit b/proposals/sockets/wit/deps/poll/world.wit deleted file mode 100644 index d08cadc05..000000000 --- a/proposals/sockets/wit/deps/poll/world.wit +++ /dev/null @@ -1,5 +0,0 @@ -package wasi:poll - -world example-world { - import poll -} diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index f15d19d03..f998aae14 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,6 +1,6 @@ interface ip-name-lookup { - use wasi:poll/poll.{pollable} + use wasi:io/poll.{pollable} use network.{network, error-code, ip-address, ip-address-family} @@ -34,36 +34,28 @@ interface ip-name-lookup { /// - /// - /// - - resolve-addresses: func(network: network, name: string, address-family: option, include-unavailable: bool) -> result - - - - type resolve-address-stream = u32 - - /// Returns the next address from the resolver. - /// - /// This function should be called multiple times. On each call, it will - /// return the next address in connection order preference. If all - /// addresses have been exhausted, this function returns `none`. - /// After which, you should release the stream with `drop-resolve-address-stream`. - /// - /// This function never returns IPv4-mapped IPv6 addresses. - /// - /// # Typical errors - /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) - /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) - /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) - /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) - resolve-next-address: func(this: resolve-address-stream) -> result, error-code> - - /// Dispose of the specified `resolve-address-stream`, after which it may no longer be used. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-resolve-address-stream: func(this: resolve-address-stream) - - /// Create a `pollable` which will resolve once the stream is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func(this: resolve-address-stream) -> pollable + resolve-addresses: func(network: borrow, name: string, address-family: option, include-unavailable: bool) -> result + + resource resolve-address-stream { + /// Returns the next address from the resolver. + /// + /// This function should be called multiple times. On each call, it will + /// return the next address in connection order preference. If all + /// addresses have been exhausted, this function returns `none`. + /// + /// This function never returns IPv4-mapped IPv6 addresses. + /// + /// # Typical errors + /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) + /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) + /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) + /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) + resolve-next-address: func() -> result, error-code> + + /// Create a `pollable` which will resolve once the stream is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable + } } diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 2d09bcbdc..8214eaaf7 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -1,17 +1,9 @@ interface network { - /// An opaque resource that represents access to (a subset of) the network. + /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. - /// - /// FYI, In the future this will be replaced by handle types. - type network = u32 - - /// Dispose of the specified `network`, after which it may no longer be used. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-network: func(this: network) - + resource network /// Error codes. /// @@ -183,4 +175,4 @@ interface network { ipv6(ipv6-socket-address), } -} \ No newline at end of file +} diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 4edb1db7f..175626cc7 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,13 +1,9 @@ interface tcp { use wasi:io/streams.{input-stream, output-stream} - use wasi:poll/poll.{pollable} + use wasi:io/poll.{pollable} use network.{network, error-code, ip-socket-address, ip-address-family} - /// A TCP socket handle. - type tcp-socket = u32 - - enum shutdown-type { /// Similar to `SHUT_RD` in POSIX. receive, @@ -20,238 +16,234 @@ interface tcp { } - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will - /// implicitly bind the socket. - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) - /// - `already-bound`: The socket is already bound. (EINVAL) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> - finish-bind: func(this: tcp-socket) -> result<_, error-code> - - /// Connect to a remote endpoint. - /// - /// On success: - /// - the socket is transitioned into the Connection state - /// - a pair of streams is returned that can be used to read & write to the connection - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) - /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `already-connected`: The socket is already in the Connection state. (EISCONN) - /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `timeout`: Connection timed out. (ETIMEDOUT) - /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) - /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> - finish-connect: func(this: tcp-socket) -> result, error-code> - - /// Start listening for new connections. - /// - /// Transitions the socket into the Listener state. - /// - /// Unlike POSIX: - /// - this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - the socket must already be explicitly bound. - /// - /// # Typical `start` errors - /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) - /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) - /// - `already-listening`: The socket is already in the Listener state. - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - `not-in-progress`: A `listen` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-listen: func(this: tcp-socket) -> result<_, error-code> - finish-listen: func(this: tcp-socket) -> result<_, error-code> - - /// Accept a new client socket. - /// - /// The returned socket is bound and in the Connection state. - /// - /// On success, this function returns the newly accepted client socket along with - /// a pair of streams that can be used to read & write to the connection. - /// - /// # Typical errors - /// - `not-listening`: Socket is not in the Listener state. (EINVAL) - /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) - /// - /// Host implementations must skip over transient errors returned by the native accept syscall. - /// - /// # References - /// - - /// - - /// - - /// - - accept: func(this: tcp-socket) -> result, error-code> - - /// Get the bound local address. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - local-address: func(this: tcp-socket) -> result - - /// Get the bound remote address. - /// - /// # Typical errors - /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - remote-address: func(this: tcp-socket) -> result - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: tcp-socket) -> ip-address-family + /// A TCP socket handle. + resource tcp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will + /// implicitly bind the socket. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) + /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code> + finish-bind: func() -> result<_, error-code> + + /// Connect to a remote endpoint. + /// + /// On success: + /// - the socket is transitioned into the Connection state + /// - a pair of streams is returned that can be used to read & write to the connection + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `already-connected`: The socket is already in the Connection state. (EISCONN) + /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code> + finish-connect: func() -> result, error-code> + + /// Start listening for new connections. + /// + /// Transitions the socket into the Listener state. + /// + /// Unlike POSIX: + /// - this function is async. This enables interactive WASI hosts to inject permission prompts. + /// - the socket must already be explicitly bound. + /// + /// # Typical `start` errors + /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) + /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) + /// - `already-listening`: The socket is already in the Listener state. + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// - `not-in-progress`: A `listen` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-listen: func() -> result<_, error-code> + finish-listen: func() -> result<_, error-code> + + /// Accept a new client socket. + /// + /// The returned socket is bound and in the Connection state. + /// + /// On success, this function returns the newly accepted client socket along with + /// a pair of streams that can be used to read & write to the connection. + /// + /// # Typical errors + /// - `not-listening`: Socket is not in the Listener state. (EINVAL) + /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) + /// + /// Host implementations must skip over transient errors returned by the native accept syscall. + /// + /// # References + /// - + /// - + /// - + /// - + accept: func() -> result, error-code> + + /// Get the bound local address. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func() -> result + + /// Get the bound remote address. + /// + /// # Typical errors + /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func() -> result + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. - /// - `already-bound`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - ipv6-only: func(this: tcp-socket) -> result - set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error-code> - - /// Hints the desired listen queue size. Implementations are free to ignore this. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error-code> - - /// Equivalent to the SO_KEEPALIVE socket option. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - keep-alive: func(this: tcp-socket) -> result - set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error-code> - - /// Equivalent to the TCP_NODELAY socket option. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - no-delay: func(this: tcp-socket) -> result - set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error-code> + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// # Typical errors + /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. + /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + ipv6-only: func() -> result + set-ipv6-only: func(value: bool) -> result<_, error-code> + + /// Hints the desired listen queue size. Implementations are free to ignore this. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + set-listen-backlog-size: func(value: u64) -> result<_, error-code> + + /// Equivalent to the SO_KEEPALIVE socket option. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + keep-alive: func() -> result + set-keep-alive: func(value: bool) -> result<_, error-code> + + /// Equivalent to the TCP_NODELAY socket option. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + no-delay: func() -> result + set-no-delay: func(value: bool) -> result<_, error-code> - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `already-listening`: (set) The socket is already in the Listener state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - unicast-hop-limit: func(this: tcp-socket) -> result - set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error-code> - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `already-listening`: (set) The socket is already in the Listener state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - receive-buffer-size: func(this: tcp-socket) -> result - set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> - send-buffer-size: func(this: tcp-socket) -> result - set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> - - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func(this: tcp-socket) -> pollable - - /// Initiate a graceful shutdown. - /// - /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read - /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. - /// Any data still in the receive queue at time of calling `shutdown` will be discarded. - /// - send: the socket is not expecting to send any more data to the peer. All subsequent write - /// operations on the `output-stream` associated with this socket will return an error. - /// - both: same effect as receive & send combined. - /// - /// The shutdown function does not close (drop) the socket. - /// - /// # Typical errors - /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error-code> - - /// Dispose of the specified `tcp-socket`, after which it may no longer be used. - /// - /// Similar to the POSIX `close` function. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-tcp-socket: func(this: tcp-socket) + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `already-listening`: (set) The socket is already in the Listener state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + unicast-hop-limit: func() -> result + set-unicast-hop-limit: func(value: u8) -> result<_, error-code> + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `already-listening`: (set) The socket is already in the Listener state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + receive-buffer-size: func() -> result + set-receive-buffer-size: func(value: u64) -> result<_, error-code> + send-buffer-size: func() -> result + set-send-buffer-size: func(value: u64) -> result<_, error-code> + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable + + /// Initiate a graceful shutdown. + /// + /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read + /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. + /// Any data still in the receive queue at time of calling `shutdown` will be discarded. + /// - send: the socket is not expecting to send any more data to the peer. All subsequent write + /// operations on the `output-stream` associated with this socket will return an error. + /// - both: same effect as receive & send combined. + /// + /// The shutdown function does not close (drop) the socket. + /// + /// # Typical errors + /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code> + } } diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 700b9e247..01e5b95b9 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,13 +1,9 @@ interface udp { - use wasi:poll/poll.{pollable} + use wasi:io/poll.{pollable} use network.{network, error-code, ip-socket-address, ip-address-family} - /// A UDP socket handle. - type udp-socket = u32 - - record datagram { data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. remote-address: ip-socket-address, @@ -22,199 +18,197 @@ interface udp { - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) - /// - `already-bound`: The socket is already bound. (EINVAL) - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> - finish-bind: func(this: udp-socket) -> result<_, error-code> - - /// Set the destination address. - /// - /// The local-address is updated based on the best network path to `remote-address`. - /// - /// When a destination address is set: - /// - all receive operations will only return datagrams sent from the provided `remote-address`. - /// - the `send` function can only be used to send to this destination. - /// - /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> - finish-connect: func(this: udp-socket) -> result<_, error-code> - - /// Receive messages on the socket. - /// - /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. - /// The returned list may contain fewer elements than requested, but never more. - /// If `max-results` is 0, this function returns successfully with an empty list. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. (EINVAL) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - receive: func(this: udp-socket, max-results: u64) -> result, error-code> - - /// Send messages on the socket. - /// - /// This function attempts to send all provided `datagrams` on the socket without blocking and - /// returns how many messages were actually sent (or queued for sending). - /// - /// This function semantically behaves the same as iterating the `datagrams` list and sequentially - /// sending each individual datagram until either the end of the list has been reached or the first error occurred. - /// If at least one datagram has been sent successfully, this function never returns an error. - /// - /// If the input list is empty, the function returns `ok(0)`. - /// - /// The remote address option is required. To send a message to the "connected" peer, - /// call `remote-address` to get their address. - /// - /// # Typical errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN) - /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. - /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) - /// - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - send: func(this: udp-socket, datagrams: list) -> result - - /// Get the current bound address. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - local-address: func(this: udp-socket) -> result - - /// Get the address set with `connect`. - /// - /// # Typical errors - /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - remote-address: func(this: udp-socket) -> result - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: udp-socket) -> ip-address-family - - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. - /// - `already-bound`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - ipv6-only: func(this: udp-socket) -> result - set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error-code> - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - unicast-hop-limit: func(this: udp-socket) -> result - set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error-code> - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - receive-buffer-size: func(this: udp-socket) -> result - set-receive-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> - send-buffer-size: func(this: udp-socket) -> result - set-send-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> - - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func(this: udp-socket) -> pollable - - /// Dispose of the specified `udp-socket`, after which it may no longer be used. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-udp-socket: func(this: udp-socket) + /// A UDP socket handle. + resource udp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) + /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code> + finish-bind: func() -> result<_, error-code> + + /// Set the destination address. + /// + /// The local-address is updated based on the best network path to `remote-address`. + /// + /// When a destination address is set: + /// - all receive operations will only return datagrams sent from the provided `remote-address`. + /// - the `send` function can only be used to send to this destination. + /// + /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code> + finish-connect: func() -> result<_, error-code> + + /// Receive messages on the socket. + /// + /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. + /// The returned list may contain fewer elements than requested, but never more. + /// If `max-results` is 0, this function returns successfully with an empty list. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. (EINVAL) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + receive: func(max-results: u64) -> result, error-code> + + /// Send messages on the socket. + /// + /// This function attempts to send all provided `datagrams` on the socket without blocking and + /// returns how many messages were actually sent (or queued for sending). + /// + /// This function semantically behaves the same as iterating the `datagrams` list and sequentially + /// sending each individual datagram until either the end of the list has been reached or the first error occurred. + /// If at least one datagram has been sent successfully, this function never returns an error. + /// + /// If the input list is empty, the function returns `ok(0)`. + /// + /// The remote address option is required. To send a message to the "connected" peer, + /// call `remote-address` to get their address. + /// + /// # Typical errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN) + /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. + /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + send: func(datagrams: list) -> result + + /// Get the current bound address. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func() -> result + + /// Get the address set with `connect`. + /// + /// # Typical errors + /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func() -> result + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// # Typical errors + /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. + /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + ipv6-only: func() -> result + set-ipv6-only: func(value: bool) -> result<_, error-code> + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + unicast-hop-limit: func() -> result + set-unicast-hop-limit: func(value: u8) -> result<_, error-code> + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + receive-buffer-size: func() -> result + set-receive-buffer-size: func(value: u64) -> result<_, error-code> + send-buffer-size: func() -> result + set-send-buffer-size: func(value: u64) -> result<_, error-code> + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable + } } diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index ca23d8698..12f3c2868 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,6 +1,6 @@ package wasi:sockets -world example-world { +world imports { import instance-network import network import udp From 991de825141edd73da39e218d9edbf0de0d2831c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 13 Sep 2023 14:58:35 -0500 Subject: [PATCH 1208/1772] Add a `reactor` world (#23) * Add a `reactor` world Similar to how there exists a `command` world this commit adds a `reactor` world which has everything that a `command` does except for the export of the `run` interface. This mirrors the `preview1-adapter-reactor` that Wasmtime currently has and is intended to make this available for other WIT-based projects as well. This commit additionally refactors the preexisting `command` world to replace all of its `import`s with a single `include` of this new `reactor` world. * Update ABI files * Fix repo name * Switch to official action --- proposals/cli/.github/workflows/main.yml | 4 +- proposals/cli/command.md | 616 ++--- proposals/cli/reactor.md | 3167 ++++++++++++++++++++++ proposals/cli/wit/command.wit | 29 +- proposals/cli/wit/reactor.wit | 30 + 5 files changed, 3509 insertions(+), 337 deletions(-) create mode 100644 proposals/cli/reactor.md create mode 100644 proposals/cli/wit/reactor.wit diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml index 3cba299bc..edf66129e 100644 --- a/proposals/cli/.github/workflows/main.yml +++ b/proposals/cli/.github/workflows/main.yml @@ -18,6 +18,6 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v13 + - uses: WebAssembly/wit-abi-up-to-date@v14 with: - wit-abi-tag: wit-abi-0.11.0 + worlds: "command reactor" diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 336dd4335..6634d0a06 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -182,7 +182,14 @@ reached.

      type datetime

      datetime

      -#### `record timezone-display` +#### `type timezone` +`u32` +

      A timezone. +

      In timezones that recognize daylight saving time, also known as daylight +time and summer time, the information returned from the functions varies +over time to reflect these adjustments.

      +

      This represents a resource.

      +

      record timezone-display

      Information useful for displaying the timezone of a specific datetime.

      This information may vary within a single timezone to reflect daylight saving time adjustments.

      @@ -214,13 +221,6 @@ representation of the UTC offset may be returned, such as -04:00.
    -

    type timezone

    -

    u32

    -

    A timezone. -

    In timezones that recognize daylight saving time, also known as daylight -time and summer time, the information returned from the functions varies -over time to reflect these adjustments.

    -

    This represents a resource.


    Functions

    display: func

    @@ -267,7 +267,11 @@ when it does, they are expected to subsume this API.

    type pollable

    pollable

    -#### `enum stream-status` +#### `record stream-error` +

    An error type returned from a stream operation. Currently this +doesn't provide any additional information.

    +
    Record Fields
    +

    enum stream-status

    Streams provide a sequence of data and then end; once they end, they no longer provide any further data.

    For example, a stream reading from a file ends when the stream reaches @@ -284,25 +288,6 @@ socket ends when the socket is closed.

    The stream has ended and will not produce any further data. -

    record stream-error

    -

    An error type returned from a stream operation. Currently this -doesn't provide any additional information.

    -
    Record Fields
    -

    type output-stream

    -

    u32

    -

    An output bytestream. In the future, this will be replaced by handle -types. -

    This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

    -

    output-streams are non-blocking to the extent practical on -underlying platforms. Except where specified otherwise, I/O operations also -always return promptly, after the number of bytes that can be written -promptly, which could even be zero. To wait for the stream to be ready to -accept data, the subscribe-to-output-stream function to obtain a -pollable which can be polled for using wasi_poll.

    -

    And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

    -

    This represents a resource.

    type input-stream

    u32

    An input bytestream. In the future, this will be replaced by handle @@ -318,6 +303,21 @@ can be polled for using wasi_poll.

    And at present, it is a u32 instead of being an actual handle, until the wit-bindgen implementation of handles and resources is ready.

    This represents a resource.

    +

    type output-stream

    +

    u32

    +

    An output bytestream. In the future, this will be replaced by handle +types. +

    This conceptually represents a stream<u8, _>. It's temporary +scaffolding until component-model's async features are ready.

    +

    output-streams are non-blocking to the extent practical on +underlying platforms. Except where specified otherwise, I/O operations also +always return promptly, after the number of bytes that can be written +promptly, which could even be zero. To wait for the stream to be ready to +accept data, the subscribe-to-output-stream function to obtain a +pollable which can be polled for using wasi_poll.

    +

    And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

    +

    This represents a resource.


    Functions

    read: func

    @@ -553,7 +553,108 @@ underlying filesystem, the function fails with `type datetime` [`datetime`](#datetime)

    -#### `flags path-flags` +#### `type filesize` +`u64` +

    File size or length of a region within a file. +

    enum descriptor-type

    +

    The type of a filesystem object referenced by a descriptor.

    +

    Note: This was called filetype in earlier versions of WASI.

    +
    Enum Cases
    +
      +
    • +

      unknown

      +

      The type of the descriptor or file is unknown or is different from +any of the other types specified. +

    • +
    • +

      block-device

      +

      The descriptor refers to a block device inode. +

    • +
    • +

      character-device

      +

      The descriptor refers to a character device inode. +

    • +
    • +

      directory

      +

      The descriptor refers to a directory inode. +

    • +
    • +

      fifo

      +

      The descriptor refers to a named pipe. +

    • +
    • +

      symbolic-link

      +

      The file refers to a symbolic link inode. +

    • +
    • +

      regular-file

      +

      The descriptor refers to a regular file inode. +

    • +
    • +

      socket

      +

      The descriptor refers to a socket. +

    • +
    +

    flags descriptor-flags

    +

    Descriptor flags.

    +

    Note: This was called fdflags in earlier versions of WASI.

    +
    Flags members
    +
      +
    • +

      read:

      +

      Read mode: Data can be read. +

    • +
    • +

      write:

      +

      Write mode: Data can be written to. +

    • +
    • +

      non-blocking:

      +

      Requests non-blocking operation. +

      When this flag is enabled, functions may return immediately with an +error-code::would-block error code in situations where they would +otherwise block. However, this non-blocking behavior is not +required. Implementations are permitted to ignore this flag and +block. This is similar to O_NONBLOCK in POSIX.

      +
    • +
    • +

      file-integrity-sync:

      +

      Request that writes be performed according to synchronized I/O file +integrity completion. The data stored in the file and the file's +metadata are synchronized. This is similar to `O_SYNC` in POSIX. +

      The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

      +
    • +
    • +

      data-integrity-sync:

      +

      Request that writes be performed according to synchronized I/O data +integrity completion. Only the data stored in the file is +synchronized. This is similar to `O_DSYNC` in POSIX. +

      The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

      +
    • +
    • +

      requested-write-sync:

      +

      Requests that reads be performed at the same level of integrety +requested for writes. This is similar to `O_RSYNC` in POSIX. +

      The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

      +
    • +
    • +

      mutate-directory:

      +

      Mutating directories mode: Directory contents may be mutated. +

      When this flag is unset on a descriptor, operations using the +descriptor which would create, rename, delete, modify the data or +metadata of filesystem objects, or obtain another handle which +would permit any of those, shall fail with error-code::read-only if +they would otherwise succeed.

      +

      This may only be set on directories.

      +
    • +
    +

    flags path-flags

    Flags determining the method of how paths are resolved.

    Flags members
      @@ -603,26 +704,84 @@ filesystem. filesystem. This does not apply to directories.
    -

    record metadata-hash-value

    -

    A 128-bit hash value, split into parts because wasm doesn't have a -128-bit integer type.

    -
    Record Fields
    +

    variant access-type

    +

    Access type used by access-at.

    +
    Variant Cases
    • -

      lower: u64

      -

      64 bits of a 128-bit hash value. +

      access: modes

      +

      Test for readability, writeability, or executability.

    • -

      upper: u64

      -

      Another 64 bits of a 128-bit hash value. +

      exists

      +

      Test whether the path exists.

    type link-count

    u64

    Number of hard links to an inode. -

    type filesize

    -

    u64

    -

    File size or length of a region within a file. +

    record descriptor-stat

    +

    File attributes.

    +

    Note: This was called filestat in earlier versions of WASI.

    +
    Record Fields
    + +

    variant new-timestamp

    +

    When setting a timestamp, this gives the value to set it to.

    +
    Variant Cases
    +
      +
    • +

      no-change

      +

      Leave the timestamp set to its previous value. +

    • +
    • +

      now

      +

      Set the timestamp to the current time of the system clock associated +with the filesystem. +

    • +
    • +

      timestamp: datetime

      +

      Set the timestamp to the given value. +

    • +
    +

    record directory-entry

    +

    A directory entry.

    +
    Record Fields
    +
      +
    • +

      type: descriptor-type

      +

      The type of the file referred to by this directory entry. +

    • +
    • +

      name: string

      +

      The name of the object. +

    • +

    enum error-code

    Error codes returned by functions, similar to errno in POSIX. Not all of these error codes are returned by the functions provided by this @@ -712,241 +871,71 @@ merely for alignment with POSIX.

  • no-entry

    -

    No such file or directory, similar to `ENOENT` in POSIX. -

  • -
  • -

    no-lock

    -

    No locks available, similar to `ENOLCK` in POSIX. -

  • -
  • -

    insufficient-memory

    -

    Not enough space, similar to `ENOMEM` in POSIX. -

  • -
  • -

    insufficient-space

    -

    No space left on device, similar to `ENOSPC` in POSIX. -

  • -
  • -

    not-directory

    -

    Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. -

  • -
  • -

    not-empty

    -

    Directory not empty, similar to `ENOTEMPTY` in POSIX. -

  • -
  • -

    not-recoverable

    -

    State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. -

  • -
  • -

    unsupported

    -

    Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. -

  • -
  • -

    no-tty

    -

    Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. -

  • -
  • -

    no-such-device

    -

    No such device or address, similar to `ENXIO` in POSIX. -

  • -
  • -

    overflow

    -

    Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. -

  • -
  • -

    not-permitted

    -

    Operation not permitted, similar to `EPERM` in POSIX. -

  • -
  • -

    pipe

    -

    Broken pipe, similar to `EPIPE` in POSIX. -

  • -
  • -

    read-only

    -

    Read-only file system, similar to `EROFS` in POSIX. -

  • -
  • -

    invalid-seek

    -

    Invalid seek, similar to `ESPIPE` in POSIX. -

  • -
  • -

    text-file-busy

    -

    Text file busy, similar to `ETXTBSY` in POSIX. -

  • -
  • -

    cross-device

    -

    Cross-device link, similar to `EXDEV` in POSIX. -

  • - -

    type directory-entry-stream

    -

    u32

    -

    A stream of directory entries. -

    This represents a stream of dir-entry.

    -

    enum descriptor-type

    -

    The type of a filesystem object referenced by a descriptor.

    -

    Note: This was called filetype in earlier versions of WASI.

    -
    Enum Cases
    -
      -
    • -

      unknown

      -

      The type of the descriptor or file is unknown or is different from -any of the other types specified. -

    • -
    • -

      block-device

      -

      The descriptor refers to a block device inode. -

    • -
    • -

      character-device

      -

      The descriptor refers to a character device inode. -

    • -
    • -

      directory

      -

      The descriptor refers to a directory inode. -

    • -
    • -

      fifo

      -

      The descriptor refers to a named pipe. -

    • -
    • -

      symbolic-link

      -

      The file refers to a symbolic link inode. -

    • -
    • -

      regular-file

      -

      The descriptor refers to a regular file inode. -

    • -
    • -

      socket

      -

      The descriptor refers to a socket. -

    • -
    -

    record directory-entry

    -

    A directory entry.

    -
    Record Fields
    -
      -
    • -

      type: descriptor-type

      -

      The type of the file referred to by this directory entry. -

    • -
    • -

      name: string

      -

      The name of the object. +

      No such file or directory, similar to `ENOENT` in POSIX.

    • -
    -

    flags descriptor-flags

    -

    Descriptor flags.

    -

    Note: This was called fdflags in earlier versions of WASI.

    -
    Flags members
    -
    • -

      read:

      -

      Read mode: Data can be read. +

      no-lock

      +

      No locks available, similar to `ENOLCK` in POSIX.

    • -

      write:

      -

      Write mode: Data can be written to. +

      insufficient-memory

      +

      Not enough space, similar to `ENOMEM` in POSIX.

    • -

      non-blocking:

      -

      Requests non-blocking operation. -

      When this flag is enabled, functions may return immediately with an -error-code::would-block error code in situations where they would -otherwise block. However, this non-blocking behavior is not -required. Implementations are permitted to ignore this flag and -block. This is similar to O_NONBLOCK in POSIX.

      +

      insufficient-space

      +

      No space left on device, similar to `ENOSPC` in POSIX.

    • -

      file-integrity-sync:

      -

      Request that writes be performed according to synchronized I/O file -integrity completion. The data stored in the file and the file's -metadata are synchronized. This is similar to `O_SYNC` in POSIX. -

      The precise semantics of this operation have not yet been defined for -WASI. At this time, it should be interpreted as a request, and not a -requirement.

      +

      not-directory

      +

      Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX.

    • -

      data-integrity-sync:

      -

      Request that writes be performed according to synchronized I/O data -integrity completion. Only the data stored in the file is -synchronized. This is similar to `O_DSYNC` in POSIX. -

      The precise semantics of this operation have not yet been defined for -WASI. At this time, it should be interpreted as a request, and not a -requirement.

      +

      not-empty

      +

      Directory not empty, similar to `ENOTEMPTY` in POSIX.

    • -

      requested-write-sync:

      -

      Requests that reads be performed at the same level of integrety -requested for writes. This is similar to `O_RSYNC` in POSIX. -

      The precise semantics of this operation have not yet been defined for -WASI. At this time, it should be interpreted as a request, and not a -requirement.

      +

      not-recoverable

      +

      State not recoverable, similar to `ENOTRECOVERABLE` in POSIX.

    • -

      mutate-directory:

      -

      Mutating directories mode: Directory contents may be mutated. -

      When this flag is unset on a descriptor, operations using the -descriptor which would create, rename, delete, modify the data or -metadata of filesystem objects, or obtain another handle which -would permit any of those, shall fail with error-code::read-only if -they would otherwise succeed.

      -

      This may only be set on directories.

      +

      unsupported

      +

      Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX.

    • -
    -

    type descriptor

    -

    u32

    -

    A descriptor is a reference to a filesystem object, which may be a file, -directory, named pipe, special file, or other object on which filesystem -calls may be made. -

    This represents a resource.

    -

    variant new-timestamp

    -

    When setting a timestamp, this gives the value to set it to.

    -
    Variant Cases
    -
    • -

      no-change

      -

      Leave the timestamp set to its previous value. +

      no-tty

      +

      Inappropriate I/O control operation, similar to `ENOTTY` in POSIX.

    • -

      now

      -

      Set the timestamp to the current time of the system clock associated -with the filesystem. +

      no-such-device

      +

      No such device or address, similar to `ENXIO` in POSIX.

    • -

      timestamp: datetime

      -

      Set the timestamp to the given value. +

      overflow

      +

      Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX.

    • -
    -

    record descriptor-stat

    -

    File attributes.

    -

    Note: This was called filestat in earlier versions of WASI.

    -
    Record Fields
    -

    enum advice

    @@ -984,19 +973,30 @@ in the near future. not reuse it thereafter. -

    variant access-type

    -

    Access type used by access-at.

    -
    Variant Cases
    +

    type descriptor

    +

    u32

    +

    A descriptor is a reference to a filesystem object, which may be a file, +directory, named pipe, special file, or other object on which filesystem +calls may be made. +

    This represents a resource.

    +

    record metadata-hash-value

    +

    A 128-bit hash value, split into parts because wasm doesn't have a +128-bit integer type.

    +
    Record Fields
    • -

      access: modes

      -

      Test for readability, writeability, or executability. +

      lower: u64

      +

      64 bits of a 128-bit hash value.

    • -

      exists

      -

      Test whether the path exists. +

      upper: u64

      +

      Another 64 bits of a 128-bit hash value.

    +

    type directory-entry-stream

    +

    u32

    +

    A stream of directory entries. +

    This represents a stream of dir-entry.


    Functions

    read-via-stream: func

    @@ -1637,64 +1637,6 @@ to by a directory descriptor and a relative path.

    This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

    FYI, In the future this will be replaced by handle types.

    -

    tuple ipv6-address

    -
    Tuple Fields
    -
      -
    • 0: u16
    • -
    • 1: u16
    • -
    • 2: u16
    • -
    • 3: u16
    • -
    • 4: u16
    • -
    • 5: u16
    • -
    • 6: u16
    • -
    • 7: u16
    • -
    -

    record ipv6-socket-address

    -
    Record Fields
    - -

    tuple ipv4-address

    -
    Tuple Fields
    -
      -
    • 0: u8
    • -
    • 1: u8
    • -
    • 2: u8
    • -
    • 3: u8
    • -
    -

    record ipv4-socket-address

    -
    Record Fields
    - -

    variant ip-socket-address

    -
    Variant Cases
    - -

    enum ip-address-family

    -
    Enum Cases
    -
      -
    • -

      ipv4

      -

      Similar to `AF_INET` in POSIX. -

    • -
    • -

      ipv6

      -

      Similar to `AF_INET6` in POSIX. -

    • -
    -

    variant ip-address

    -
    Variant Cases
    -

    enum error-code

    Error codes.

    In theory, every API can return any error code. @@ -1844,6 +1786,64 @@ combined with a couple of errors that are always possible:

    A permanent failure in name resolution occurred. +

    enum ip-address-family

    +
    Enum Cases
    +
      +
    • +

      ipv4

      +

      Similar to `AF_INET` in POSIX. +

    • +
    • +

      ipv6

      +

      Similar to `AF_INET6` in POSIX. +

    • +
    +

    tuple ipv4-address

    +
    Tuple Fields
    +
      +
    • 0: u8
    • +
    • 1: u8
    • +
    • 2: u8
    • +
    • 3: u8
    • +
    +

    tuple ipv6-address

    +
    Tuple Fields
    +
      +
    • 0: u16
    • +
    • 1: u16
    • +
    • 2: u16
    • +
    • 3: u16
    • +
    • 4: u16
    • +
    • 5: u16
    • +
    • 6: u16
    • +
    • 7: u16
    • +
    +

    variant ip-address

    +
    Variant Cases
    + +

    record ipv4-socket-address

    +
    Record Fields
    + +

    record ipv6-socket-address

    +
    Record Fields
    + +

    variant ip-socket-address

    +
    Variant Cases
    +

    Functions

    drop-network: func

    diff --git a/proposals/cli/reactor.md b/proposals/cli/reactor.md new file mode 100644 index 000000000..6e0f5b7fd --- /dev/null +++ b/proposals/cli/reactor.md @@ -0,0 +1,3167 @@ +

    World reactor

    + +

    Import interface wasi:clocks/wall-clock

    +

    WASI Wall Clock is a clock API intended to let users query the current +time. The name "wall" makes an analogy to a "clock on the wall", which +is not necessarily monotonic as it may be reset.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +

    A wall clock is a clock which measures the date and time according to +some external reference.

    +

    External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time.

    +

    It is intended for reporting the current date and time for humans.

    +
    +

    Types

    +

    record datetime

    +

    A time and date in seconds plus nanoseconds.

    +
    Record Fields
    + +
    +

    Functions

    +

    now: func

    +

    Read the current value of the clock.

    +

    This clock is not monotonic, therefore calling this function repeatedly +will not necessarily produce a sequence of non-decreasing values.

    +

    The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, +also known as Unix Time.

    +

    The nanoseconds field of the output is always less than 1000000000.

    +
    Return values
    + +

    resolution: func

    +

    Query the resolution of the clock.

    +

    The nanoseconds field of the output is always less than 1000000000.

    +
    Return values
    + +

    Import interface wasi:poll/poll

    +

    A poll API intended to let users wait for I/O events on multiple handles +at once.

    +
    +

    Types

    +

    type pollable

    +

    u32

    +

    A "pollable" handle. +

    This is conceptually represents a stream<_, _>, or in other words, +a stream that one can wait on, repeatedly, but which does not itself +produce any data. It's temporary scaffolding until component-model's +async features are ready.

    +

    And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

    +

    pollable lifetimes are not automatically managed. Users must ensure +that they do not outlive the resource they reference.

    +

    This represents a resource.

    +
    +

    Functions

    +

    drop-pollable: func

    +

    Dispose of the specified pollable, after which it may no longer +be used.

    +
    Params
    + +

    poll-oneoff: func

    +

    Poll for completion on a set of pollables.

    +

    This function takes a list of pollables, which identify I/O sources of +interest, and waits until one or more of the events is ready for I/O.

    +

    The result list<bool> is the same length as the argument +list<pollable>, and indicates the readiness of each corresponding +element in that list, with true indicating ready. A single call can +return multiple true elements.

    +

    A timeout can be implemented by adding a pollable from the +wasi-clocks API to the list.

    +

    This function does not return a result; polling in itself does not +do any I/O so it doesn't fail. If any of the I/O sources identified by +the pollables has an error, it is indicated by marking the source as +ready in the list<bool>.

    +

    The "oneoff" in the name refers to the fact that this function must do a +linear scan through the entire list of subscriptions, which may be +inefficient if the number is large and the same subscriptions are used +many times. In the future, this is expected to be obsoleted by the +component model async proposal, which will include a scalable waiting +facility.

    +
    Params
    + +
    Return values
    +
      +
    • list<bool>
    • +
    +

    Import interface wasi:clocks/monotonic-clock

    +

    WASI Monotonic Clock is a clock API intended to let users measure elapsed +time.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +

    A monotonic clock is a clock which has an unspecified initial value, and +successive reads of the clock will produce non-decreasing values.

    +

    It is intended for measuring elapsed time.

    +
    +

    Types

    +

    type pollable

    +

    pollable

    +

    +#### `type instant` +`u64` +

    A timestamp in nanoseconds. +


    +

    Functions

    +

    now: func

    +

    Read the current value of the clock.

    +

    The clock is monotonic, therefore calling this function repeatedly will +produce a sequence of non-decreasing values.

    +
    Return values
    + +

    resolution: func

    +

    Query the resolution of the clock.

    +
    Return values
    + +

    subscribe: func

    +

    Create a pollable which will resolve once the specified time has been +reached.

    +
    Params
    + +
    Return values
    + +

    Import interface wasi:clocks/timezone

    +
    +

    Types

    +

    type datetime

    +

    datetime

    +

    +#### `type timezone` +`u32` +

    A timezone. +

    In timezones that recognize daylight saving time, also known as daylight +time and summer time, the information returned from the functions varies +over time to reflect these adjustments.

    +

    This represents a resource.

    +

    record timezone-display

    +

    Information useful for displaying the timezone of a specific datetime.

    +

    This information may vary within a single timezone to reflect daylight +saving time adjustments.

    +
    Record Fields
    +
      +
    • +

      utc-offset: s32

      +

      The number of seconds difference between UTC time and the local +time of the timezone. +

      The returned value will always be less than 86400 which is the +number of seconds in a day (246060).

      +

      In implementations that do not expose an actual time zone, this +should return 0.

      +
    • +
    • +

      name: string

      +

      The abbreviated name of the timezone to display to a user. The name +`UTC` indicates Coordinated Universal Time. Otherwise, this should +reference local standards for the name of the time zone. +

      In implementations that do not expose an actual time zone, this +should be the string UTC.

      +

      In time zones that do not have an applicable name, a formatted +representation of the UTC offset may be returned, such as -04:00.

      +
    • +
    • +

      in-daylight-saving-time: bool

      +

      Whether daylight saving time is active. +

      In implementations that do not expose an actual time zone, this +should return false.

      +
    • +
    +
    +

    Functions

    +

    display: func

    +

    Return information needed to display the given datetime. This includes +the UTC offset, the time zone name, and a flag indicating whether +daylight saving time is active.

    +

    If the timezone cannot be determined for the given datetime, return a +timezone-display for UTC with a utc-offset of 0 and no daylight +saving time.

    +
    Params
    + +
    Return values
    + +

    utc-offset: func

    +

    The same as display, but only return the UTC offset.

    +
    Params
    + +
    Return values
    +
      +
    • s32
    • +
    +

    drop-timezone: func

    +

    Dispose of the specified input-stream, after which it may no longer +be used.

    +
    Params
    + +

    Import interface wasi:io/streams

    +

    WASI I/O is an I/O abstraction API which is currently focused on providing +stream types.

    +

    In the future, the component model is expected to add built-in stream types; +when it does, they are expected to subsume this API.

    +
    +

    Types

    +

    type pollable

    +

    pollable

    +

    +#### `record stream-error` +

    An error type returned from a stream operation. Currently this +doesn't provide any additional information.

    +
    Record Fields
    +

    enum stream-status

    +

    Streams provide a sequence of data and then end; once they end, they +no longer provide any further data.

    +

    For example, a stream reading from a file ends when the stream reaches +the end of the file. For another example, a stream reading from a +socket ends when the socket is closed.

    +
    Enum Cases
    +
      +
    • +

      open

      +

      The stream is open and may produce further data. +

    • +
    • +

      ended

      +

      The stream has ended and will not produce any further data. +

    • +
    +

    type input-stream

    +

    u32

    +

    An input bytestream. In the future, this will be replaced by handle +types. +

    This conceptually represents a stream<u8, _>. It's temporary +scaffolding until component-model's async features are ready.

    +

    input-streams are non-blocking to the extent practical on underlying +platforms. I/O operations always return promptly; if fewer bytes are +promptly available than requested, they return the number of bytes promptly +available, which could even be zero. To wait for data to be available, +use the subscribe-to-input-stream function to obtain a pollable which +can be polled for using wasi_poll.

    +

    And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

    +

    This represents a resource.

    +

    type output-stream

    +

    u32

    +

    An output bytestream. In the future, this will be replaced by handle +types. +

    This conceptually represents a stream<u8, _>. It's temporary +scaffolding until component-model's async features are ready.

    +

    output-streams are non-blocking to the extent practical on +underlying platforms. Except where specified otherwise, I/O operations also +always return promptly, after the number of bytes that can be written +promptly, which could even be zero. To wait for the stream to be ready to +accept data, the subscribe-to-output-stream function to obtain a +pollable which can be polled for using wasi_poll.

    +

    And at present, it is a u32 instead of being an actual handle, until +the wit-bindgen implementation of handles and resources is ready.

    +

    This represents a resource.

    +
    +

    Functions

    +

    read: func

    +

    Read bytes from a stream.

    +

    This function returns a list of bytes containing the data that was +read, along with a stream-status which indicates whether the end of +the stream was reached. The returned list will contain up to len +bytes; it may return fewer than requested, but not more.

    +

    Once a stream has reached the end, subsequent calls to read or +skip will always report end-of-stream rather than producing more +data.

    +

    If len is 0, it represents a request to read 0 bytes, which should +always succeed, assuming the stream hasn't reached its end yet, and +return an empty list.

    +

    The len here is a u64, but some callees may not be able to allocate +a buffer as large as that would imply. +FIXME: describe what happens if allocation fails.

    +
    Params
    + +
    Return values
    + +

    blocking-read: func

    +

    Read bytes from a stream, with blocking.

    +

    This is similar to read, except that it blocks until at least one +byte can be read.

    +
    Params
    + +
    Return values
    + +

    skip: func

    +

    Skip bytes from a stream.

    +

    This is similar to the read function, but avoids copying the +bytes into the instance.

    +

    Once a stream has reached the end, subsequent calls to read or +skip will always report end-of-stream rather than producing more +data.

    +

    This function returns the number of bytes skipped, along with a +stream-status indicating whether the end of the stream was +reached. The returned value will be at most len; it may be less.

    +
    Params
    + +
    Return values
    + +

    blocking-skip: func

    +

    Skip bytes from a stream, with blocking.

    +

    This is similar to skip, except that it blocks until at least one +byte can be consumed.

    +
    Params
    + +
    Return values
    + +

    subscribe-to-input-stream: func

    +

    Create a pollable which will resolve once either the specified stream +has bytes available to read or the other end of the stream has been +closed.

    +
    Params
    + +
    Return values
    + +

    drop-input-stream: func

    +

    Dispose of the specified input-stream, after which it may no longer +be used.

    +
    Params
    + +

    write: func

    +

    Write bytes to a stream.

    +

    This function returns a u64 indicating the number of bytes from +buf that were written; it may be less than the full list.

    +
    Params
    + +
    Return values
    + +

    blocking-write: func

    +

    Write bytes to a stream, with blocking.

    +

    This is similar to write, except that it blocks until at least one +byte can be written.

    +
    Params
    + +
    Return values
    + +

    write-zeroes: func

    +

    Write multiple zero bytes to a stream.

    +

    This function returns a u64 indicating the number of zero bytes +that were written; it may be less than len.

    +
    Params
    + +
    Return values
    + +

    blocking-write-zeroes: func

    +

    Write multiple zero bytes to a stream, with blocking.

    +

    This is similar to write-zeroes, except that it blocks until at least +one byte can be written.

    +
    Params
    + +
    Return values
    + +

    splice: func

    +

    Read from one stream and write to another.

    +

    This function returns the number of bytes transferred; it may be less +than len.

    +

    Unlike other I/O functions, this function blocks until all the data +read from the input stream has been written to the output stream.

    +
    Params
    + +
    Return values
    + +

    blocking-splice: func

    +

    Read from one stream and write to another, with blocking.

    +

    This is similar to splice, except that it blocks until at least +one byte can be read.

    +
    Params
    + +
    Return values
    + +

    forward: func

    +

    Forward the entire contents of an input stream to an output stream.

    +

    This function repeatedly reads from the input stream and writes +the data to the output stream, until the end of the input stream +is reached, or an error is encountered.

    +

    Unlike other I/O functions, this function blocks until the end +of the input stream is seen and all the data has been written to +the output stream.

    +

    This function returns the number of bytes transferred.

    +
    Params
    + +
    Return values
    + +

    subscribe-to-output-stream: func

    +

    Create a pollable which will resolve once either the specified stream +is ready to accept bytes or the other end of the stream has been closed.

    +
    Params
    + +
    Return values
    + +

    drop-output-stream: func

    +

    Dispose of the specified output-stream, after which it may no longer +be used.

    +
    Params
    + +

    Import interface wasi:filesystem/types

    +

    WASI filesystem is a filesystem API primarily intended to let users run WASI +programs that access their files on their existing filesystems, without +significant overhead.

    +

    It is intended to be roughly portable between Unix-family platforms and +Windows, though it does not hide many of the major differences.

    +

    Paths are passed as interface-type strings, meaning they must consist of +a sequence of Unicode Scalar Values (USVs). Some filesystems may contain +paths which are not accessible by this API.

    +

    The directory separator in WASI is always the forward-slash (/).

    +

    All paths in WASI are relative paths, and are interpreted relative to a +descriptor referring to a base directory. If a path argument to any WASI +function starts with /, or if any step of resolving a path, including +.. and symbolic link steps, reaches a directory outside of the base +directory, or reaches a symlink to an absolute or rooted path in the +underlying filesystem, the function fails with error-code::not-permitted.

    +
    +

    Types

    +

    type input-stream

    +

    input-stream

    +

    +#### `type output-stream` +[`output-stream`](#output_stream) +

    +#### `type datetime` +[`datetime`](#datetime) +

    +#### `type filesize` +`u64` +

    File size or length of a region within a file. +

    enum descriptor-type

    +

    The type of a filesystem object referenced by a descriptor.

    +

    Note: This was called filetype in earlier versions of WASI.

    +
    Enum Cases
    +
      +
    • +

      unknown

      +

      The type of the descriptor or file is unknown or is different from +any of the other types specified. +

    • +
    • +

      block-device

      +

      The descriptor refers to a block device inode. +

    • +
    • +

      character-device

      +

      The descriptor refers to a character device inode. +

    • +
    • +

      directory

      +

      The descriptor refers to a directory inode. +

    • +
    • +

      fifo

      +

      The descriptor refers to a named pipe. +

    • +
    • +

      symbolic-link

      +

      The file refers to a symbolic link inode. +

    • +
    • +

      regular-file

      +

      The descriptor refers to a regular file inode. +

    • +
    • +

      socket

      +

      The descriptor refers to a socket. +

    • +
    +

    flags descriptor-flags

    +

    Descriptor flags.

    +

    Note: This was called fdflags in earlier versions of WASI.

    +
    Flags members
    +
      +
    • +

      read:

      +

      Read mode: Data can be read. +

    • +
    • +

      write:

      +

      Write mode: Data can be written to. +

    • +
    • +

      non-blocking:

      +

      Requests non-blocking operation. +

      When this flag is enabled, functions may return immediately with an +error-code::would-block error code in situations where they would +otherwise block. However, this non-blocking behavior is not +required. Implementations are permitted to ignore this flag and +block. This is similar to O_NONBLOCK in POSIX.

      +
    • +
    • +

      file-integrity-sync:

      +

      Request that writes be performed according to synchronized I/O file +integrity completion. The data stored in the file and the file's +metadata are synchronized. This is similar to `O_SYNC` in POSIX. +

      The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

      +
    • +
    • +

      data-integrity-sync:

      +

      Request that writes be performed according to synchronized I/O data +integrity completion. Only the data stored in the file is +synchronized. This is similar to `O_DSYNC` in POSIX. +

      The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

      +
    • +
    • +

      requested-write-sync:

      +

      Requests that reads be performed at the same level of integrety +requested for writes. This is similar to `O_RSYNC` in POSIX. +

      The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

      +
    • +
    • +

      mutate-directory:

      +

      Mutating directories mode: Directory contents may be mutated. +

      When this flag is unset on a descriptor, operations using the +descriptor which would create, rename, delete, modify the data or +metadata of filesystem objects, or obtain another handle which +would permit any of those, shall fail with error-code::read-only if +they would otherwise succeed.

      +

      This may only be set on directories.

      +
    • +
    +

    flags path-flags

    +

    Flags determining the method of how paths are resolved.

    +
    Flags members
    +
      +
    • symlink-follow:

      As long as the resolved path corresponds to a symbolic link, it is +expanded. +

    • +
    +

    flags open-flags

    +

    Open flags used by open-at.

    +
    Flags members
    +
      +
    • +

      create:

      +

      Create file if it does not exist, similar to `O_CREAT` in POSIX. +

    • +
    • +

      directory:

      +

      Fail if not a directory, similar to `O_DIRECTORY` in POSIX. +

    • +
    • +

      exclusive:

      +

      Fail if file already exists, similar to `O_EXCL` in POSIX. +

    • +
    • +

      truncate:

      +

      Truncate file to size 0, similar to `O_TRUNC` in POSIX. +

    • +
    +

    flags modes

    +

    Permissions mode used by open-at, change-file-permissions-at, and +similar.

    +
    Flags members
    +
      +
    • +

      readable:

      +

      True if the resource is considered readable by the containing +filesystem. +

    • +
    • +

      writable:

      +

      True if the resource is considered writable by the containing +filesystem. +

    • +
    • +

      executable:

      +

      True if the resource is considered executable by the containing +filesystem. This does not apply to directories. +

    • +
    +

    variant access-type

    +

    Access type used by access-at.

    +
    Variant Cases
    +
      +
    • +

      access: modes

      +

      Test for readability, writeability, or executability. +

    • +
    • +

      exists

      +

      Test whether the path exists. +

    • +
    +

    type link-count

    +

    u64

    +

    Number of hard links to an inode. +

    record descriptor-stat

    +

    File attributes.

    +

    Note: This was called filestat in earlier versions of WASI.

    +
    Record Fields
    + +

    variant new-timestamp

    +

    When setting a timestamp, this gives the value to set it to.

    +
    Variant Cases
    +
      +
    • +

      no-change

      +

      Leave the timestamp set to its previous value. +

    • +
    • +

      now

      +

      Set the timestamp to the current time of the system clock associated +with the filesystem. +

    • +
    • +

      timestamp: datetime

      +

      Set the timestamp to the given value. +

    • +
    +

    record directory-entry

    +

    A directory entry.

    +
    Record Fields
    +
      +
    • +

      type: descriptor-type

      +

      The type of the file referred to by this directory entry. +

    • +
    • +

      name: string

      +

      The name of the object. +

    • +
    +

    enum error-code

    +

    Error codes returned by functions, similar to errno in POSIX. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX.

    +
    Enum Cases
    +
      +
    • +

      access

      +

      Permission denied, similar to `EACCES` in POSIX. +

    • +
    • +

      would-block

      +

      Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. +

    • +
    • +

      already

      +

      Connection already in progress, similar to `EALREADY` in POSIX. +

    • +
    • +

      bad-descriptor

      +

      Bad descriptor, similar to `EBADF` in POSIX. +

    • +
    • +

      busy

      +

      Device or resource busy, similar to `EBUSY` in POSIX. +

    • +
    • +

      deadlock

      +

      Resource deadlock would occur, similar to `EDEADLK` in POSIX. +

    • +
    • +

      quota

      +

      Storage quota exceeded, similar to `EDQUOT` in POSIX. +

    • +
    • +

      exist

      +

      File exists, similar to `EEXIST` in POSIX. +

    • +
    • +

      file-too-large

      +

      File too large, similar to `EFBIG` in POSIX. +

    • +
    • +

      illegal-byte-sequence

      +

      Illegal byte sequence, similar to `EILSEQ` in POSIX. +

    • +
    • +

      in-progress

      +

      Operation in progress, similar to `EINPROGRESS` in POSIX. +

    • +
    • +

      interrupted

      +

      Interrupted function, similar to `EINTR` in POSIX. +

    • +
    • +

      invalid

      +

      Invalid argument, similar to `EINVAL` in POSIX. +

    • +
    • +

      io

      +

      I/O error, similar to `EIO` in POSIX. +

    • +
    • +

      is-directory

      +

      Is a directory, similar to `EISDIR` in POSIX. +

    • +
    • +

      loop

      +

      Too many levels of symbolic links, similar to `ELOOP` in POSIX. +

    • +
    • +

      too-many-links

      +

      Too many links, similar to `EMLINK` in POSIX. +

    • +
    • +

      message-size

      +

      Message too large, similar to `EMSGSIZE` in POSIX. +

    • +
    • +

      name-too-long

      +

      Filename too long, similar to `ENAMETOOLONG` in POSIX. +

    • +
    • +

      no-device

      +

      No such device, similar to `ENODEV` in POSIX. +

    • +
    • +

      no-entry

      +

      No such file or directory, similar to `ENOENT` in POSIX. +

    • +
    • +

      no-lock

      +

      No locks available, similar to `ENOLCK` in POSIX. +

    • +
    • +

      insufficient-memory

      +

      Not enough space, similar to `ENOMEM` in POSIX. +

    • +
    • +

      insufficient-space

      +

      No space left on device, similar to `ENOSPC` in POSIX. +

    • +
    • +

      not-directory

      +

      Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. +

    • +
    • +

      not-empty

      +

      Directory not empty, similar to `ENOTEMPTY` in POSIX. +

    • +
    • +

      not-recoverable

      +

      State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. +

    • +
    • +

      unsupported

      +

      Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. +

    • +
    • +

      no-tty

      +

      Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. +

    • +
    • +

      no-such-device

      +

      No such device or address, similar to `ENXIO` in POSIX. +

    • +
    • +

      overflow

      +

      Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. +

    • +
    • +

      not-permitted

      +

      Operation not permitted, similar to `EPERM` in POSIX. +

    • +
    • +

      pipe

      +

      Broken pipe, similar to `EPIPE` in POSIX. +

    • +
    • +

      read-only

      +

      Read-only file system, similar to `EROFS` in POSIX. +

    • +
    • +

      invalid-seek

      +

      Invalid seek, similar to `ESPIPE` in POSIX. +

    • +
    • +

      text-file-busy

      +

      Text file busy, similar to `ETXTBSY` in POSIX. +

    • +
    • +

      cross-device

      +

      Cross-device link, similar to `EXDEV` in POSIX. +

    • +
    +

    enum advice

    +

    File or memory access pattern advisory information.

    +
    Enum Cases
    +
      +
    • +

      normal

      +

      The application has no advice to give on its behavior with respect +to the specified data. +

    • +
    • +

      sequential

      +

      The application expects to access the specified data sequentially +from lower offsets to higher offsets. +

    • +
    • +

      random

      +

      The application expects to access the specified data in a random +order. +

    • +
    • +

      will-need

      +

      The application expects to access the specified data in the near +future. +

    • +
    • +

      dont-need

      +

      The application expects that it will not access the specified data +in the near future. +

    • +
    • +

      no-reuse

      +

      The application expects to access the specified data once and then +not reuse it thereafter. +

    • +
    +

    type descriptor

    +

    u32

    +

    A descriptor is a reference to a filesystem object, which may be a file, +directory, named pipe, special file, or other object on which filesystem +calls may be made. +

    This represents a resource.

    +

    record metadata-hash-value

    +

    A 128-bit hash value, split into parts because wasm doesn't have a +128-bit integer type.

    +
    Record Fields
    +
      +
    • +

      lower: u64

      +

      64 bits of a 128-bit hash value. +

    • +
    • +

      upper: u64

      +

      Another 64 bits of a 128-bit hash value. +

    • +
    +

    type directory-entry-stream

    +

    u32

    +

    A stream of directory entries. +

    This represents a stream of dir-entry.

    +
    +

    Functions

    +

    read-via-stream: func

    +

    Return a stream for reading from a file, if available.

    +

    May fail with an error-code describing why the file cannot be read.

    +

    Multiple read, write, and append streams may be active on the same open +file and they do not interfere with each other.

    +

    Note: This allows using read-stream, which is similar to read in POSIX.

    +
    Params
    + +
    Return values
    + +

    write-via-stream: func

    +

    Return a stream for writing to a file, if available.

    +

    May fail with an error-code describing why the file cannot be written.

    +

    Note: This allows using write-stream, which is similar to write in +POSIX.

    +
    Params
    + +
    Return values
    + +

    append-via-stream: func

    +

    Return a stream for appending to a file, if available.

    +

    May fail with an error-code describing why the file cannot be appended.

    +

    Note: This allows using write-stream, which is similar to write with +O_APPEND in in POSIX.

    +
    Params
    + +
    Return values
    + +

    advise: func

    +

    Provide file advisory information on a descriptor.

    +

    This is similar to posix_fadvise in POSIX.

    +
    Params
    + +
    Return values
    + +

    sync-data: func

    +

    Synchronize the data of a file to disk.

    +

    This function succeeds with no effect if the file descriptor is not +opened for writing.

    +

    Note: This is similar to fdatasync in POSIX.

    +
    Params
    + +
    Return values
    + +

    get-flags: func

    +

    Get flags associated with a descriptor.

    +

    Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

    +

    Note: This returns the value that was the fs_flags value returned +from fdstat_get in earlier versions of WASI.

    +
    Params
    + +
    Return values
    + +

    get-type: func

    +

    Get the dynamic type of a descriptor.

    +

    Note: This returns the same value as the type field of the fd-stat +returned by stat, stat-at and similar.

    +

    Note: This returns similar flags to the st_mode & S_IFMT value provided +by fstat in POSIX.

    +

    Note: This returns the value that was the fs_filetype value returned +from fdstat_get in earlier versions of WASI.

    +
    Params
    + +
    Return values
    + +

    set-flags: func

    +

    Set status flags associated with a descriptor.

    +

    This function may only change the non-blocking flag.

    +

    Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

    +

    Note: This was called fd_fdstat_set_flags in earlier versions of WASI.

    +
    Params
    + +
    Return values
    + +

    set-size: func

    +

    Adjust the size of an open file. If this increases the file's size, the +extra bytes are filled with zeros.

    +

    Note: This was called fd_filestat_set_size in earlier versions of WASI.

    +
    Params
    + +
    Return values
    + +

    set-times: func

    +

    Adjust the timestamps of an open file or directory.

    +

    Note: This is similar to futimens in POSIX.

    +

    Note: This was called fd_filestat_set_times in earlier versions of WASI.

    +
    Params
    + +
    Return values
    + +

    read: func

    +

    Read from a descriptor, without using and updating the descriptor's offset.

    +

    This function returns a list of bytes containing the data that was +read, along with a bool which, when true, indicates that the end of the +file was reached. The returned list will contain up to length bytes; it +may return fewer than requested, if the end of the file is reached or +if the I/O operation is interrupted.

    +

    In the future, this may change to return a stream<u8, error-code>.

    +

    Note: This is similar to pread in POSIX.

    +
    Params
    + +
    Return values
    + +

    write: func

    +

    Write to a descriptor, without using and updating the descriptor's offset.

    +

    It is valid to write past the end of a file; the file is extended to the +extent of the write, with bytes between the previous end and the start of +the write set to zero.

    +

    In the future, this may change to take a stream<u8, error-code>.

    +

    Note: This is similar to pwrite in POSIX.

    +
    Params
    + +
    Return values
    + +

    read-directory: func

    +

    Read directory entries from a directory.

    +

    On filesystems where directories contain entries referring to themselves +and their parents, often named . and .. respectively, these entries +are omitted.

    +

    This always returns a new stream which starts at the beginning of the +directory. Multiple streams may be active on the same directory, and they +do not interfere with each other.

    +
    Params
    + +
    Return values
    + +

    sync: func

    +

    Synchronize the data and metadata of a file to disk.

    +

    This function succeeds with no effect if the file descriptor is not +opened for writing.

    +

    Note: This is similar to fsync in POSIX.

    +
    Params
    + +
    Return values
    + +

    create-directory-at: func

    +

    Create a directory.

    +

    Note: This is similar to mkdirat in POSIX.

    +
    Params
    + +
    Return values
    + +

    stat: func

    +

    Return the attributes of an open file or directory.

    +

    Note: This is similar to fstat in POSIX, except that it does not return +device and inode information. For testing whether two descriptors refer to +the same underlying filesystem object, use is-same-object. To obtain +additional data that can be used do determine whether a file has been +modified, use metadata-hash.

    +

    Note: This was called fd_filestat_get in earlier versions of WASI.

    +
    Params
    + +
    Return values
    + +

    stat-at: func

    +

    Return the attributes of a file or directory.

    +

    Note: This is similar to fstatat in POSIX, except that it does not +return device and inode information. See the stat description for a +discussion of alternatives.

    +

    Note: This was called path_filestat_get in earlier versions of WASI.

    +
    Params
    + +
    Return values
    + +

    set-times-at: func

    +

    Adjust the timestamps of a file or directory.

    +

    Note: This is similar to utimensat in POSIX.

    +

    Note: This was called path_filestat_set_times in earlier versions of +WASI.

    +
    Params
    + +
    Return values
    + +

    link-at: func

    +

    Create a hard link.

    +

    Note: This is similar to linkat in POSIX.

    +
    Params
    + +
    Return values
    + +

    open-at: func

    +

    Open a file or directory.

    +

    The returned descriptor is not guaranteed to be the lowest-numbered +descriptor not currently open/ it is randomized to prevent applications +from depending on making assumptions about indexes, since this is +error-prone in multi-threaded contexts. The returned descriptor is +guaranteed to be less than 2**31.

    +

    If flags contains descriptor-flags::mutate-directory, and the base +descriptor doesn't have descriptor-flags::mutate-directory set, +open-at fails with error-code::read-only.

    +

    If flags contains write or mutate-directory, or open-flags +contains truncate or create, and the base descriptor doesn't have +descriptor-flags::mutate-directory set, open-at fails with +error-code::read-only.

    +

    Note: This is similar to openat in POSIX.

    +
    Params
    + +
    Return values
    + +

    readlink-at: func

    +

    Read the contents of a symbolic link.

    +

    If the contents contain an absolute or rooted path in the underlying +filesystem, this function fails with error-code::not-permitted.

    +

    Note: This is similar to readlinkat in POSIX.

    +
    Params
    + +
    Return values
    + +

    remove-directory-at: func

    +

    Remove a directory.

    +

    Return error-code::not-empty if the directory is not empty.

    +

    Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

    +
    Params
    + +
    Return values
    + +

    rename-at: func

    +

    Rename a filesystem object.

    +

    Note: This is similar to renameat in POSIX.

    +
    Params
    + +
    Return values
    + +

    symlink-at: func

    +

    Create a symbolic link (also known as a "symlink").

    +

    If old-path starts with /, the function fails with +error-code::not-permitted.

    +

    Note: This is similar to symlinkat in POSIX.

    +
    Params
    + +
    Return values
    + +

    access-at: func

    +

    Check accessibility of a filesystem path.

    +

    Check whether the given filesystem path names an object which is +readable, writable, or executable, or whether it exists.

    +

    This does not a guarantee that subsequent accesses will succeed, as +filesystem permissions may be modified asynchronously by external +entities.

    +

    Note: This is similar to faccessat with the AT_EACCESS flag in POSIX.

    +
    Params
    + +
    Return values
    + +

    unlink-file-at: func

    +

    Unlink a filesystem object that is not a directory.

    +

    Return error-code::is-directory if the path refers to a directory. +Note: This is similar to unlinkat(fd, path, 0) in POSIX.

    +
    Params
    + +
    Return values
    + +

    change-file-permissions-at: func

    +

    Change the permissions of a filesystem object that is not a directory.

    +

    Note that the ultimate meanings of these permissions is +filesystem-specific.

    +

    Note: This is similar to fchmodat in POSIX.

    +
    Params
    + +
    Return values
    + +

    change-directory-permissions-at: func

    +

    Change the permissions of a directory.

    +

    Note that the ultimate meanings of these permissions is +filesystem-specific.

    +

    Unlike in POSIX, the executable flag is not reinterpreted as a "search" +flag. read on a directory implies readability and searchability, and +execute is not valid for directories.

    +

    Note: This is similar to fchmodat in POSIX.

    +
    Params
    + +
    Return values
    + +

    lock-shared: func

    +

    Request a shared advisory lock for an open file.

    +

    This requests a shared lock; more than one shared lock can be held for +a file at the same time.

    +

    If the open file has an exclusive lock, this function downgrades the lock +to a shared lock. If it has a shared lock, this function has no effect.

    +

    This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

    +

    It is unspecified how shared locks interact with locks acquired by +non-WASI programs.

    +

    This function blocks until the lock can be acquired.

    +

    Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

    +

    Note: This is similar to flock(fd, LOCK_SH) in Unix.

    +
    Params
    + +
    Return values
    + +

    lock-exclusive: func

    +

    Request an exclusive advisory lock for an open file.

    +

    This requests an exclusive lock; no other locks may be held for the +file while an exclusive lock is held.

    +

    If the open file has a shared lock and there are no exclusive locks held +for the file, this function upgrades the lock to an exclusive lock. If the +open file already has an exclusive lock, this function has no effect.

    +

    This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

    +

    It is unspecified whether this function succeeds if the file descriptor +is not opened for writing. It is unspecified how exclusive locks interact +with locks acquired by non-WASI programs.

    +

    This function blocks until the lock can be acquired.

    +

    Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

    +

    Note: This is similar to flock(fd, LOCK_EX) in Unix.

    +
    Params
    + +
    Return values
    + +

    try-lock-shared: func

    +

    Request a shared advisory lock for an open file.

    +

    This requests a shared lock; more than one shared lock can be held for +a file at the same time.

    +

    If the open file has an exclusive lock, this function downgrades the lock +to a shared lock. If it has a shared lock, this function has no effect.

    +

    This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

    +

    It is unspecified how shared locks interact with locks acquired by +non-WASI programs.

    +

    This function returns error-code::would-block if the lock cannot be +acquired.

    +

    Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

    +

    Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

    +
    Params
    + +
    Return values
    + +

    try-lock-exclusive: func

    +

    Request an exclusive advisory lock for an open file.

    +

    This requests an exclusive lock; no other locks may be held for the +file while an exclusive lock is held.

    +

    If the open file has a shared lock and there are no exclusive locks held +for the file, this function upgrades the lock to an exclusive lock. If the +open file already has an exclusive lock, this function has no effect.

    +

    This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

    +

    It is unspecified whether this function succeeds if the file descriptor +is not opened for writing. It is unspecified how exclusive locks interact +with locks acquired by non-WASI programs.

    +

    This function returns error-code::would-block if the lock cannot be +acquired.

    +

    Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

    +

    Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

    +
    Params
    + +
    Return values
    + +

    unlock: func

    +

    Release a shared or exclusive lock on an open file.

    +

    Note: This is similar to flock(fd, LOCK_UN) in Unix.

    +
    Params
    + +
    Return values
    + +

    drop-descriptor: func

    +

    Dispose of the specified descriptor, after which it may no longer +be used.

    +
    Params
    + +

    read-directory-entry: func

    +

    Read a single directory entry from a directory-entry-stream.

    +
    Params
    + +
    Return values
    + +

    drop-directory-entry-stream: func

    +

    Dispose of the specified directory-entry-stream, after which it may no longer +be used.

    +
    Params
    + +

    is-same-object: func

    +

    Test whether two descriptors refer to the same filesystem object.

    +

    In POSIX, this corresponds to testing whether the two descriptors have the +same device (st_dev) and inode (st_ino or d_ino) numbers. +wasi-filesystem does not expose device and inode numbers, so this function +may be used instead.

    +
    Params
    + +
    Return values
    +
      +
    • bool
    • +
    +

    metadata-hash: func

    +

    Return a hash of the metadata associated with a filesystem object referred +to by a descriptor.

    +

    This returns a hash of the last-modification timestamp and file size, and +may also include the inode number, device number, birth timestamp, and +other metadata fields that may change when the file is modified or +replaced. It may also include a secret value chosen by the +implementation and not otherwise exposed.

    +

    Implementations are encourated to provide the following properties:

    +
      +
    • If the file is not modified or replaced, the computed hash value should +usually not change.
    • +
    • If the object is modified or replaced, the computed hash value should +usually change.
    • +
    • The inputs to the hash should not be easily computable from the +computed hash.
    • +
    +

    However, none of these is required.

    +
    Params
    + +
    Return values
    + +

    metadata-hash-at: func

    +

    Return a hash of the metadata associated with a filesystem object referred +to by a directory descriptor and a relative path.

    +

    This performs the same hash computation as metadata-hash.

    +
    Params
    + +
    Return values
    + +

    Import interface wasi:filesystem/preopens

    +
    +

    Types

    +

    type descriptor

    +

    descriptor

    +

    +---- +

    Functions

    +

    get-directories: func

    +

    Return the set of preopened directories, and their path.

    +
    Return values
    + +

    Import interface wasi:sockets/network

    +
    +

    Types

    +

    type network

    +

    u32

    +

    An opaque resource that represents access to (a subset of) the network. +This enables context-based security for networking. +There is no need for this to map 1:1 to a physical network interface. +

    FYI, In the future this will be replaced by handle types.

    +

    enum error-code

    +

    Error codes.

    +

    In theory, every API can return any error code. +In practice, API's typically only return the errors documented per API +combined with a couple of errors that are always possible:

    +
      +
    • unknown
    • +
    • access-denied
    • +
    • not-supported
    • +
    • out-of-memory
    • +
    +

    See each individual API for what the POSIX equivalents are. They sometimes differ per API.

    +
    Enum Cases
    +
      +
    • +

      unknown

      +

      Unknown error +

    • +
    • +

      access-denied

      +

      Access denied. +

      POSIX equivalent: EACCES, EPERM

      +
    • +
    • +

      not-supported

      +

      The operation is not supported. +

      POSIX equivalent: EOPNOTSUPP

      +
    • +
    • +

      out-of-memory

      +

      Not enough memory to complete the operation. +

      POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY

      +
    • +
    • +

      timeout

      +

      The operation timed out before it could finish completely. +

    • +
    • +

      concurrency-conflict

      +

      This operation is incompatible with another asynchronous operation that is already in progress. +

    • +
    • +

      not-in-progress

      +

      Trying to finish an asynchronous operation that: +- has not been started yet, or: +- was already finished by a previous `finish-*` call. +

      Note: this is scheduled to be removed when futures are natively supported.

      +
    • +
    • +

      would-block

      +

      The operation has been aborted because it could not be completed immediately. +

      Note: this is scheduled to be removed when futures are natively supported.

      +
    • +
    • +

      address-family-not-supported

      +

      The specified address-family is not supported. +

    • +
    • +

      address-family-mismatch

      +

      An IPv4 address was passed to an IPv6 resource, or vice versa. +

    • +
    • +

      invalid-remote-address

      +

      The socket address is not a valid remote address. E.g. the IP address is set to INADDR_ANY, or the port is set to 0. +

    • +
    • +

      ipv4-only-operation

      +

      The operation is only supported on IPv4 resources. +

    • +
    • +

      ipv6-only-operation

      +

      The operation is only supported on IPv6 resources. +

    • +
    • +

      new-socket-limit

      +

      A new socket resource could not be created because of a system limit. +

    • +
    • +

      already-attached

      +

      The socket is already attached to another network. +

    • +
    • +

      already-bound

      +

      The socket is already bound. +

    • +
    • +

      already-connected

      +

      The socket is already in the Connection state. +

    • +
    • +

      not-bound

      +

      The socket is not bound to any local address. +

    • +
    • +

      not-connected

      +

      The socket is not in the Connection state. +

    • +
    • +

      address-not-bindable

      +

      A bind operation failed because the provided address is not an address that the `network` can bind to. +

    • +
    • +

      address-in-use

      +

      A bind operation failed because the provided address is already in use. +

    • +
    • +

      ephemeral-ports-exhausted

      +

      A bind operation failed because there are no ephemeral ports available. +

    • +
    • +

      remote-unreachable

      +

      The remote address is not reachable +

    • +
    • +

      already-listening

      +

      The socket is already in the Listener state. +

    • +
    • +

      not-listening

      +

      The socket is already in the Listener state. +

    • +
    • +

      connection-refused

      +

      The connection was forcefully rejected +

    • +
    • +

      connection-reset

      +

      The connection was reset. +

    • +
    • +

      datagram-too-large

      +
    • +
    • +

      invalid-name

      +

      The provided name is a syntactically invalid domain name. +

    • +
    • +

      name-unresolvable

      +

      Name does not exist or has no suitable associated IP addresses. +

    • +
    • +

      temporary-resolver-failure

      +

      A temporary failure in name resolution occurred. +

    • +
    • +

      permanent-resolver-failure

      +

      A permanent failure in name resolution occurred. +

    • +
    +

    enum ip-address-family

    +
    Enum Cases
    +
      +
    • +

      ipv4

      +

      Similar to `AF_INET` in POSIX. +

    • +
    • +

      ipv6

      +

      Similar to `AF_INET6` in POSIX. +

    • +
    +

    tuple ipv4-address

    +
    Tuple Fields
    +
      +
    • 0: u8
    • +
    • 1: u8
    • +
    • 2: u8
    • +
    • 3: u8
    • +
    +

    tuple ipv6-address

    +
    Tuple Fields
    +
      +
    • 0: u16
    • +
    • 1: u16
    • +
    • 2: u16
    • +
    • 3: u16
    • +
    • 4: u16
    • +
    • 5: u16
    • +
    • 6: u16
    • +
    • 7: u16
    • +
    +

    variant ip-address

    +
    Variant Cases
    + +

    record ipv4-socket-address

    +
    Record Fields
    + +

    record ipv6-socket-address

    +
    Record Fields
    + +

    variant ip-socket-address

    +
    Variant Cases
    + +
    +

    Functions

    +

    drop-network: func

    +

    Dispose of the specified network, after which it may no longer be used.

    +

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    +
    Params
    + +

    Import interface wasi:sockets/instance-network

    +

    This interface provides a value-export of the default network handle..

    +
    +

    Types

    +

    type network

    +

    network

    +

    +---- +

    Functions

    +

    instance-network: func

    +

    Get a handle to the default network.

    +
    Return values
    + +

    Import interface wasi:sockets/ip-name-lookup

    +
    +

    Types

    +

    type pollable

    +

    pollable

    +

    +#### `type network` +[`network`](#network) +

    +#### `type error-code` +[`error-code`](#error_code) +

    +#### `type ip-address` +[`ip-address`](#ip_address) +

    +#### `type ip-address-family` +[`ip-address-family`](#ip_address_family) +

    +#### `type resolve-address-stream` +`u32` +

    +---- +

    Functions

    +

    resolve-addresses: func

    +

    Resolve an internet host name to a list of IP addresses.

    +

    See the wasi-socket proposal README.md for a comparison with getaddrinfo.

    +

    Parameters

    +
      +
    • name: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted +to ASCII using IDNA encoding.
    • +
    • address-family: If provided, limit the results to addresses of this specific address family.
    • +
    • include-unavailable: When set to true, this function will also return addresses of which the runtime +thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on +systems without an active IPv6 interface. Notes:
    • +
    • Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address.
    • +
    • Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged.
    • +
    +

    This function never blocks. It either immediately fails or immediately returns successfully with a resolve-address-stream +that can be used to (asynchronously) fetch the results.

    +

    At the moment, the stream never completes successfully with 0 items. Ie. the first call +to resolve-next-address never returns ok(none). This may change in the future.

    +

    Typical errors

    +
      +
    • invalid-name: name is a syntactically invalid domain name.
    • +
    • invalid-name: name is an IP address.
    • +
    • address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)
    • +
    +

    References:

    + +
    Params
    + +
    Return values
    + +

    resolve-next-address: func

    +

    Returns the next address from the resolver.

    +

    This function should be called multiple times. On each call, it will +return the next address in connection order preference. If all +addresses have been exhausted, this function returns none. +After which, you should release the stream with drop-resolve-address-stream.

    +

    This function never returns IPv4-mapped IPv6 addresses.

    +

    Typical errors

    +
      +
    • name-unresolvable: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY)
    • +
    • temporary-resolver-failure: A temporary failure in name resolution occurred. (EAI_AGAIN)
    • +
    • permanent-resolver-failure: A permanent failure in name resolution occurred. (EAI_FAIL)
    • +
    • would-block: A result is not available yet. (EWOULDBLOCK, EAGAIN)
    • +
    +
    Params
    + +
    Return values
    + +

    drop-resolve-address-stream: func

    +

    Dispose of the specified resolve-address-stream, after which it may no longer be used.

    +

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    +
    Params
    + +

    subscribe: func

    +

    Create a pollable which will resolve once the stream is ready for I/O.

    +

    Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

    +
    Params
    + +
    Return values
    + +

    Import interface wasi:sockets/tcp

    +
    +

    Types

    +

    type input-stream

    +

    input-stream

    +

    +#### `type output-stream` +[`output-stream`](#output_stream) +

    +#### `type pollable` +[`pollable`](#pollable) +

    +#### `type network` +[`network`](#network) +

    +#### `type error-code` +[`error-code`](#error_code) +

    +#### `type ip-socket-address` +[`ip-socket-address`](#ip_socket_address) +

    +#### `type ip-address-family` +[`ip-address-family`](#ip_address_family) +

    +#### `type tcp-socket` +`u32` +

    A TCP socket handle. +

    enum shutdown-type

    +
    Enum Cases
    +
      +
    • +

      receive

      +

      Similar to `SHUT_RD` in POSIX. +

    • +
    • +

      send

      +

      Similar to `SHUT_WR` in POSIX. +

    • +
    • +

      both

      +

      Similar to `SHUT_RDWR` in POSIX. +

    • +
    +
    +

    Functions

    +

    start-bind: func

    +

    Bind the socket to a specific network on the provided IP address and port.

    +

    If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which +network interface(s) to bind to. +If the TCP/UDP port is zero, the socket will be bound to a random free port.

    +

    When a socket is not explicitly bound, the first invocation to a listen or connect operation will +implicitly bind the socket.

    +

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    +

    Typical start errors

    +
      +
    • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
    • +
    • already-bound: The socket is already bound. (EINVAL)
    • +
    • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
    • +
    +

    Typical finish errors

    +
      +
    • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
    • +
    • address-in-use: Address is already in use. (EADDRINUSE)
    • +
    • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
    • +
    • not-in-progress: A bind operation is not in progress.
    • +
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    finish-bind: func

    +
    Params
    + +
    Return values
    + +

    start-connect: func

    +

    Connect to a remote endpoint.

    +

    On success:

    +
      +
    • the socket is transitioned into the Connection state
    • +
    • a pair of streams is returned that can be used to read & write to the connection
    • +
    +

    Typical start errors

    +
      +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
    • +
    • already-attached: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
    • +
    • already-connected: The socket is already in the Connection state. (EISCONN)
    • +
    • already-listening: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
    • +
    • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
    • +
    +

    Typical finish errors

    +
      +
    • timeout: Connection timed out. (ETIMEDOUT)
    • +
    • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
    • +
    • connection-reset: The connection was reset. (ECONNRESET)
    • +
    • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
    • +
    • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
    • +
    • not-in-progress: A connect operation is not in progress.
    • +
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    finish-connect: func

    +
    Params
    + +
    Return values
    + +

    start-listen: func

    +

    Start listening for new connections.

    +

    Transitions the socket into the Listener state.

    +

    Unlike POSIX:

    +
      +
    • this function is async. This enables interactive WASI hosts to inject permission prompts.
    • +
    • the socket must already be explicitly bound.
    • +
    +

    Typical start errors

    +
      +
    • not-bound: The socket is not bound to any local address. (EDESTADDRREQ)
    • +
    • already-connected: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
    • +
    • already-listening: The socket is already in the Listener state.
    • +
    • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EINVAL on BSD)
    • +
    +

    Typical finish errors

    +
      +
    • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
    • +
    • not-in-progress: A listen operation is not in progress.
    • +
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    finish-listen: func

    +
    Params
    + +
    Return values
    + +

    accept: func

    +

    Accept a new client socket.

    +

    The returned socket is bound and in the Connection state.

    +

    On success, this function returns the newly accepted client socket along with +a pair of streams that can be used to read & write to the connection.

    +

    Typical errors

    +
      +
    • not-listening: Socket is not in the Listener state. (EINVAL)
    • +
    • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
    • +
    +

    Host implementations must skip over transient errors returned by the native accept syscall.

    +

    References

    + +
    Params
    + +
    Return values
    + +

    local-address: func

    +

    Get the bound local address.

    +

    Typical errors

    +
      +
    • not-bound: The socket is not bound to any local address.
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    remote-address: func

    +

    Get the bound remote address.

    +

    Typical errors

    +
      +
    • not-connected: The socket is not connected to a remote address. (ENOTCONN)
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    address-family: func

    +

    Whether this is a IPv4 or IPv6 socket.

    +

    Equivalent to the SO_DOMAIN socket option.

    +
    Params
    + +
    Return values
    + +

    ipv6-only: func

    +

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    +

    Equivalent to the IPV6_V6ONLY socket option.

    +

    Typical errors

    +
      +
    • ipv6-only-operation: (get/set) this socket is an IPv4 socket.
    • +
    • already-bound: (set) The socket is already bound.
    • +
    • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
    • +
    • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
    • +
    +
    Params
    + +
    Return values
    + +

    set-ipv6-only: func

    +
    Params
    + +
    Return values
    + +

    set-listen-backlog-size: func

    +

    Hints the desired listen queue size. Implementations are free to ignore this.

    +

    Typical errors

    +
      +
    • already-connected: (set) The socket is already in the Connection state.
    • +
    • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
    • +
    +
    Params
    + +
    Return values
    + +

    keep-alive: func

    +

    Equivalent to the SO_KEEPALIVE socket option.

    +

    Typical errors

    +
      +
    • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
    • +
    +
    Params
    + +
    Return values
    + +

    set-keep-alive: func

    +
    Params
    + +
    Return values
    + +

    no-delay: func

    +

    Equivalent to the TCP_NODELAY socket option.

    +

    Typical errors

    +
      +
    • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
    • +
    +
    Params
    + +
    Return values
    + +

    set-no-delay: func

    +
    Params
    + +
    Return values
    + +

    unicast-hop-limit: func

    +

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    +

    Typical errors

    +
      +
    • already-connected: (set) The socket is already in the Connection state.
    • +
    • already-listening: (set) The socket is already in the Listener state.
    • +
    • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
    • +
    +
    Params
    + +
    Return values
    + +

    set-unicast-hop-limit: func

    +
    Params
    + +
    Return values
    + +

    receive-buffer-size: func

    +

    The kernel buffer space reserved for sends/receives on this socket.

    +

    Note #1: an implementation may choose to cap or round the buffer size when setting the value. +In other words, after setting a value, reading the same setting back may return a different value.

    +

    Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of +actual data to be sent/received by the application, because the kernel might also use the buffer space +for internal metadata structures.

    +

    Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

    +

    Typical errors

    +
      +
    • already-connected: (set) The socket is already in the Connection state.
    • +
    • already-listening: (set) The socket is already in the Listener state.
    • +
    • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
    • +
    +
    Params
    + +
    Return values
    + +

    set-receive-buffer-size: func

    +
    Params
    + +
    Return values
    + +

    send-buffer-size: func

    +
    Params
    + +
    Return values
    + +

    set-send-buffer-size: func

    +
    Params
    + +
    Return values
    + +

    subscribe: func

    +

    Create a pollable which will resolve once the socket is ready for I/O.

    +

    Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

    +
    Params
    + +
    Return values
    + +

    shutdown: func

    +

    Initiate a graceful shutdown.

    +
      +
    • receive: the socket is not expecting to receive any more data from the peer. All subsequent read +operations on the input-stream associated with this socket will return an End Of Stream indication. +Any data still in the receive queue at time of calling shutdown will be discarded.
    • +
    • send: the socket is not expecting to send any more data to the peer. All subsequent write +operations on the output-stream associated with this socket will return an error.
    • +
    • both: same effect as receive & send combined.
    • +
    +

    The shutdown function does not close (drop) the socket.

    +

    Typical errors

    +
      +
    • not-connected: The socket is not in the Connection state. (ENOTCONN)
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    drop-tcp-socket: func

    +

    Dispose of the specified tcp-socket, after which it may no longer be used.

    +

    Similar to the POSIX close function.

    +

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    +
    Params
    + +

    Import interface wasi:sockets/tcp-create-socket

    +
    +

    Types

    +

    type network

    +

    network

    +

    +#### `type error-code` +[`error-code`](#error_code) +

    +#### `type ip-address-family` +[`ip-address-family`](#ip_address_family) +

    +#### `type tcp-socket` +[`tcp-socket`](#tcp_socket) +

    +---- +

    Functions

    +

    create-tcp-socket: func

    +

    Create a new TCP socket.

    +

    Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX.

    +

    This function does not require a network capability handle. This is considered to be safe because +at time of creation, the socket is not bound to any network yet. Up to the moment bind/listen/connect +is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

    +

    All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

    +

    Typical errors

    +
      +
    • not-supported: The host does not support TCP sockets. (EOPNOTSUPP)
    • +
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • +
    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    Import interface wasi:sockets/udp

    +
    +

    Types

    +

    type pollable

    +

    pollable

    +

    +#### `type network` +[`network`](#network) +

    +#### `type error-code` +[`error-code`](#error_code) +

    +#### `type ip-socket-address` +[`ip-socket-address`](#ip_socket_address) +

    +#### `type ip-address-family` +[`ip-address-family`](#ip_address_family) +

    +#### `type udp-socket` +`u32` +

    A UDP socket handle. +

    record datagram

    +
    Record Fields
    + +
    +

    Functions

    +

    start-bind: func

    +

    Bind the socket to a specific network on the provided IP address and port.

    +

    If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which +network interface(s) to bind to. +If the TCP/UDP port is zero, the socket will be bound to a random free port.

    +

    When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket.

    +

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    +

    Typical start errors

    +
      +
    • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
    • +
    • already-bound: The socket is already bound. (EINVAL)
    • +
    • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
    • +
    +

    Typical finish errors

    +
      +
    • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
    • +
    • address-in-use: Address is already in use. (EADDRINUSE)
    • +
    • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
    • +
    • not-in-progress: A bind operation is not in progress.
    • +
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    finish-bind: func

    +
    Params
    + +
    Return values
    + +

    start-connect: func

    +

    Set the destination address.

    +

    The local-address is updated based on the best network path to remote-address.

    +

    When a destination address is set:

    +
      +
    • all receive operations will only return datagrams sent from the provided remote-address.
    • +
    • the send function can only be used to send to this destination.
    • +
    +

    Note that this function does not generate any network traffic and the peer is not aware of this "connection".

    +

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    +

    Typical start errors

    +
      +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • already-attached: The socket is already bound to a different network. The network passed to connect must be identical to the one passed to bind.
    • +
    • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
    • +
    +

    Typical finish errors

    +
      +
    • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
    • +
    • not-in-progress: A connect operation is not in progress.
    • +
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    finish-connect: func

    +
    Params
    + +
    Return values
    + +

    receive: func

    +

    Receive messages on the socket.

    +

    This function attempts to receive up to max-results datagrams on the socket without blocking. +The returned list may contain fewer elements than requested, but never more. +If max-results is 0, this function returns successfully with an empty list.

    +

    Typical errors

    +
      +
    • not-bound: The socket is not bound to any local address. (EINVAL)
    • +
    • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
    • +
    • would-block: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN)
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    send: func

    +

    Send messages on the socket.

    +

    This function attempts to send all provided datagrams on the socket without blocking and +returns how many messages were actually sent (or queued for sending).

    +

    This function semantically behaves the same as iterating the datagrams list and sequentially +sending each individual datagram until either the end of the list has been reached or the first error occurred. +If at least one datagram has been sent successfully, this function never returns an error.

    +

    If the input list is empty, the function returns ok(0).

    +

    The remote address option is required. To send a message to the "connected" peer, +call remote-address to get their address.

    +

    Typical errors

    +
      +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • already-connected: The socket is in "connected" mode and the datagram.remote-address does not match the address passed to connect. (EISCONN)
    • +
    • not-bound: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind.
    • +
    • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
    • +
    • datagram-too-large: The datagram is too large. (EMSGSIZE)
    • +
    • would-block: The send buffer is currently full. (EWOULDBLOCK, EAGAIN)
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    local-address: func

    +

    Get the current bound address.

    +

    Typical errors

    +
      +
    • not-bound: The socket is not bound to any local address.
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    remote-address: func

    +

    Get the address set with connect.

    +

    Typical errors

    +
      +
    • not-connected: The socket is not connected to a remote address. (ENOTCONN)
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    address-family: func

    +

    Whether this is a IPv4 or IPv6 socket.

    +

    Equivalent to the SO_DOMAIN socket option.

    +
    Params
    + +
    Return values
    + +

    ipv6-only: func

    +

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    +

    Equivalent to the IPV6_V6ONLY socket option.

    +

    Typical errors

    +
      +
    • ipv6-only-operation: (get/set) this socket is an IPv4 socket.
    • +
    • already-bound: (set) The socket is already bound.
    • +
    • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
    • +
    • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
    • +
    +
    Params
    + +
    Return values
    + +

    set-ipv6-only: func

    +
    Params
    + +
    Return values
    + +

    unicast-hop-limit: func

    +

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    +

    Typical errors

    +
      +
    • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
    • +
    +
    Params
    + +
    Return values
    + +

    set-unicast-hop-limit: func

    +
    Params
    + +
    Return values
    + +

    receive-buffer-size: func

    +

    The kernel buffer space reserved for sends/receives on this socket.

    +

    Note #1: an implementation may choose to cap or round the buffer size when setting the value. +In other words, after setting a value, reading the same setting back may return a different value.

    +

    Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of +actual data to be sent/received by the application, because the kernel might also use the buffer space +for internal metadata structures.

    +

    Fails when this socket is in the Listening state.

    +

    Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

    +

    Typical errors

    +
      +
    • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
    • +
    +
    Params
    + +
    Return values
    + +

    set-receive-buffer-size: func

    +
    Params
    + +
    Return values
    + +

    send-buffer-size: func

    +
    Params
    + +
    Return values
    + +

    set-send-buffer-size: func

    +
    Params
    + +
    Return values
    + +

    subscribe: func

    +

    Create a pollable which will resolve once the socket is ready for I/O.

    +

    Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

    +
    Params
    + +
    Return values
    + +

    drop-udp-socket: func

    +

    Dispose of the specified udp-socket, after which it may no longer be used.

    +

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    +
    Params
    + +

    Import interface wasi:sockets/udp-create-socket

    +
    +

    Types

    +

    type network

    +

    network

    +

    +#### `type error-code` +[`error-code`](#error_code) +

    +#### `type ip-address-family` +[`ip-address-family`](#ip_address_family) +

    +#### `type udp-socket` +[`udp-socket`](#udp_socket) +

    +---- +

    Functions

    +

    create-udp-socket: func

    +

    Create a new UDP socket.

    +

    Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.

    +

    This function does not require a network capability handle. This is considered to be safe because +at time of creation, the socket is not bound to any network yet. Up to the moment bind/connect is called, +the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

    +

    All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

    +

    Typical errors

    +
      +
    • not-supported: The host does not support UDP sockets. (EOPNOTSUPP)
    • +
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • +
    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
    • +
    +

    References:

    + +
    Params
    + +
    Return values
    + +

    Import interface wasi:random/random

    +

    WASI Random is a random data API.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +
    +

    Functions

    +

    get-random-bytes: func

    +

    Return len cryptographically-secure random or pseudo-random bytes.

    +

    This function must produce data at least as cryptographically secure and +fast as an adequately seeded cryptographically-secure pseudo-random +number generator (CSPRNG). It must not block, from the perspective of +the calling program, under any circumstances, including on the first +request and on requests for numbers of bytes. The returned data must +always be unpredictable.

    +

    This function must always return fresh data. Deterministic environments +must omit this function, rather than implementing it with deterministic +data.

    +
    Params
    + +
    Return values
    +
      +
    • list<u8>
    • +
    +

    get-random-u64: func

    +

    Return a cryptographically-secure random or pseudo-random u64 value.

    +

    This function returns the same type of data as get-random-bytes, +represented as a u64.

    +
    Return values
    +
      +
    • u64
    • +
    +

    Import interface wasi:random/insecure

    +

    The insecure interface for insecure pseudo-random numbers.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +
    +

    Functions

    +

    get-insecure-random-bytes: func

    +

    Return len insecure pseudo-random bytes.

    +

    This function is not cryptographically secure. Do not use it for +anything related to security.

    +

    There are no requirements on the values of the returned bytes, however +implementations are encouraged to return evenly distributed values with +a long period.

    +
    Params
    + +
    Return values
    +
      +
    • list<u8>
    • +
    +

    get-insecure-random-u64: func

    +

    Return an insecure pseudo-random u64 value.

    +

    This function returns the same type of pseudo-random data as +get-insecure-random-bytes, represented as a u64.

    +
    Return values
    +
      +
    • u64
    • +
    +

    Import interface wasi:random/insecure-seed

    +

    The insecure-seed interface for seeding hash-map DoS resistance.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +
    +

    Functions

    +

    insecure-seed: func

    +

    Return a 128-bit value that may contain a pseudo-random value.

    +

    The returned value is not required to be computed from a CSPRNG, and may +even be entirely deterministic. Host implementations are encouraged to +provide pseudo-random values to any program exposed to +attacker-controlled content, to enable DoS protection built into many +languages' hash-map implementations.

    +

    This function is intended to only be called once, by a source language +to initialize Denial Of Service (DoS) protection in its hash-map +implementation.

    +

    Expected future evolution

    +

    This will likely be changed to a value import, to prevent it from being +called multiple times and potentially used for purposes other than DoS +protection.

    +
    Return values
    +
      +
    • (u64, u64)
    • +
    +

    Import interface wasi:cli/environment

    +
    +

    Functions

    +

    get-environment: func

    +

    Get the POSIX-style environment variables.

    +

    Each environment variable is provided as a pair of string variable names +and string value.

    +

    Morally, these are a value import, but until value imports are available +in the component model, this import function should return the same +values each time it is called.

    +
    Return values
    +
      +
    • list<(string, string)>
    • +
    +

    get-arguments: func

    +

    Get the POSIX-style arguments to the program.

    +
    Return values
    +
      +
    • list<string>
    • +
    +

    initial-cwd: func

    +

    Return a path that programs should use as their initial current working +directory, interpreting . as shorthand for this.

    +
    Return values
    +
      +
    • option<string>
    • +
    +

    Import interface wasi:cli/exit

    +
    +

    Functions

    +

    exit: func

    +

    Exit the current instance and any linked instances.

    +
    Params
    + +

    Import interface wasi:cli/stdin

    +
    +

    Types

    +

    type input-stream

    +

    input-stream

    +

    +---- +

    Functions

    +

    get-stdin: func

    +
    Return values
    + +

    Import interface wasi:cli/stdout

    +
    +

    Types

    +

    type output-stream

    +

    output-stream

    +

    +---- +

    Functions

    +

    get-stdout: func

    +
    Return values
    + +

    Import interface wasi:cli/stderr

    +
    +

    Types

    +

    type output-stream

    +

    output-stream

    +

    +---- +

    Functions

    +

    get-stderr: func

    +
    Return values
    + +

    Import interface wasi:cli/terminal-input

    +
    +

    Types

    +

    type terminal-input

    +

    u32

    +

    The input side of a terminal. +

    This represents a resource.

    +
    +

    Functions

    +

    drop-terminal-input: func

    +

    Dispose of the specified terminal-input after which it may no longer +be used.

    +
    Params
    + +

    Import interface wasi:cli/terminal-output

    +
    +

    Types

    +

    type terminal-output

    +

    u32

    +

    The output side of a terminal. +

    This represents a resource.

    +
    +

    Functions

    +

    drop-terminal-output: func

    +

    Dispose of the specified terminal-output, after which it may no longer +be used.

    +
    Params
    + +

    Import interface wasi:cli/terminal-stdin

    +

    An interface providing an optional terminal-input for stdin as a +link-time authority.

    +
    +

    Types

    +

    type terminal-input

    +

    terminal-input

    +

    +---- +

    Functions

    +

    get-terminal-stdin: func

    +

    If stdin is connected to a terminal, return a terminal-input handle +allowing further interaction with it.

    +
    Return values
    + +

    Import interface wasi:cli/terminal-stdout

    +

    An interface providing an optional terminal-output for stdout as a +link-time authority.

    +
    +

    Types

    +

    type terminal-output

    +

    terminal-output

    +

    +---- +

    Functions

    +

    get-terminal-stdout: func

    +

    If stdout is connected to a terminal, return a terminal-output handle +allowing further interaction with it.

    +
    Return values
    + +

    Import interface wasi:cli/terminal-stderr

    +

    An interface providing an optional terminal-output for stderr as a +link-time authority.

    +
    +

    Types

    +

    type terminal-output

    +

    terminal-output

    +

    +---- +

    Functions

    +

    get-terminal-stderr: func

    +

    If stderr is connected to a terminal, return a terminal-output handle +allowing further interaction with it.

    +
    Return values
    + diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index c29b4a61f..d28f5f628 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,32 +1,7 @@ package wasi:cli world command { - import wasi:clocks/wall-clock - import wasi:clocks/monotonic-clock - import wasi:clocks/timezone - import wasi:filesystem/types - import wasi:filesystem/preopens - import wasi:sockets/instance-network - import wasi:sockets/ip-name-lookup - import wasi:sockets/network - import wasi:sockets/tcp-create-socket - import wasi:sockets/tcp - import wasi:sockets/udp-create-socket - import wasi:sockets/udp - import wasi:random/random - import wasi:random/insecure - import wasi:random/insecure-seed - import wasi:poll/poll - import wasi:io/streams - import environment - import exit - import stdin - import stdout - import stderr - import terminal-input - import terminal-output - import terminal-stdin - import terminal-stdout - import terminal-stderr + include reactor + export run } diff --git a/proposals/cli/wit/reactor.wit b/proposals/cli/wit/reactor.wit new file mode 100644 index 000000000..30ff96293 --- /dev/null +++ b/proposals/cli/wit/reactor.wit @@ -0,0 +1,30 @@ +world reactor { + import wasi:clocks/wall-clock + import wasi:clocks/monotonic-clock + import wasi:clocks/timezone + import wasi:filesystem/types + import wasi:filesystem/preopens + import wasi:sockets/instance-network + import wasi:sockets/ip-name-lookup + import wasi:sockets/network + import wasi:sockets/tcp-create-socket + import wasi:sockets/tcp + import wasi:sockets/udp-create-socket + import wasi:sockets/udp + import wasi:random/random + import wasi:random/insecure + import wasi:random/insecure-seed + import wasi:poll/poll + import wasi:io/streams + import environment + import exit + import stdin + import stdout + import stderr + import terminal-input + import terminal-output + import terminal-stdin + import terminal-stdout + import terminal-stderr +} + From b7126e517644387a26ac41d6cda6babca0cb0c61 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 13 Sep 2023 13:00:02 -0700 Subject: [PATCH 1209/1772] Add Phase 4 Advancement Criteria (#21) Add Phase 4 Advancement Criteria to wasi-cli. This uses the same criteria as wasi-filesystem: support Windows, macOS, and Linux, and have at least two implementations. --- proposals/cli/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/proposals/cli/README.md b/proposals/cli/README.md index 4ec9bea64..31376e12b 100644 --- a/proposals/cli/README.md +++ b/proposals/cli/README.md @@ -14,7 +14,10 @@ wasi-cli is currently in [Phase 1]. ### Phase 4 Advancement Criteria -TODO before entering Phase 2. +WASI CLI must have host implementations which can pass the testsuite +on at least Windows, macOS, and Linux. + +WASI CLI must have at least two complete independent implementations. ## Table of Contents From 7b1f73b8d2b1c62ffa21f79ac1188f0626c83375 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 13 Sep 2023 13:04:55 -0700 Subject: [PATCH 1210/1772] Remove references to `drop-` functions. --- proposals/sockets/Posix-compatibility.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/proposals/sockets/Posix-compatibility.md b/proposals/sockets/Posix-compatibility.md index a2ba1c628..b96cceafb 100644 --- a/proposals/sockets/Posix-compatibility.md +++ b/proposals/sockets/Posix-compatibility.md @@ -104,8 +104,7 @@ None of the flags are directly present in WASI Sockets: - UDP: N/A ### `close` -- TCP: [`tcp::drop-tcp-socket`](tcp) -- UDP: [`udp::drop-udp-socket`](udp) +Dropping a handle performs an effective `close`. ### `socketpair`, `connectat` (non-standard), `bindat` (non-standard) Specifically for UNIX domain sockets. Out of scope for this proposal. @@ -599,4 +598,4 @@ Columns: [udp-create-socket]: https://github.com/WebAssembly/wasi-sockets/blob/main/wit/udp-create-socket.wit [udp]: https://github.com/WebAssembly/wasi-sockets/blob/main/wit/udp.wit [poll]: https://github.com/WebAssembly/wasi-poll/blob/main/wit/poll.wit -[streams]: https://github.com/WebAssembly/wasi-io/blob/main/wit/streams.wit \ No newline at end of file +[streams]: https://github.com/WebAssembly/wasi-io/blob/main/wit/streams.wit From d9a296ae7fa013deee91ee731074fe31189d64ca Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Wed, 13 Sep 2023 15:14:59 -0500 Subject: [PATCH 1211/1772] Add Phase 4 Advancement Criteria --- proposals/http/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/proposals/http/README.md b/proposals/http/README.md index 528995ca1..c6ff638ab 100644 --- a/proposals/http/README.md +++ b/proposals/http/README.md @@ -16,7 +16,13 @@ wasi-http is currently in [Phase 1](https://github.com/WebAssembly/WASI/blob/mai ### Phase 4 Advancement Criteria -TODO +WASI-http must have at least two complete independent implementations. One +implementation must execute in a browser and may be implemented in terms of the +[Fetch API] using JavaScript. The other implementation must be implemented +in a non-browser WebAssembly runtime and demonstrate embeddability in a +Web server. + +[Fetch API]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API ### Introduction From 8931fbe36578993085010f3a5f4523952167657f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 19 Sep 2023 18:23:26 -0700 Subject: [PATCH 1212/1772] Update CI dependencies and generated markdown files. (#34) --- proposals/random/.github/workflows/main.yml | 6 ++---- proposals/random/{example-world.md => imports.md} | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) rename proposals/random/{example-world.md => imports.md} (98%) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index 90e28a115..9b91f42cb 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -10,7 +10,5 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: WebAssembly/wit-abi-up-to-date@v13 - with: - wit-abi-tag: wit-abi-0.11.0 + - uses: actions/checkout@v3 + - uses: WebAssembly/wit-abi-up-to-date@v14 diff --git a/proposals/random/example-world.md b/proposals/random/imports.md similarity index 98% rename from proposals/random/example-world.md rename to proposals/random/imports.md index fc15a04a4..b8b1608c4 100644 --- a/proposals/random/example-world.md +++ b/proposals/random/imports.md @@ -1,4 +1,4 @@ -

    World example-world

    +

    World imports

    • Imports:
        From ea88085d5dbc1b9a11e3567d0ac928d9202d713b Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 21 Sep 2023 11:33:01 -0500 Subject: [PATCH 1213/1772] The proposal is now at Phase 2 (#54) --- proposals/http/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/README.md b/proposals/http/README.md index c6ff638ab..f5b1996f9 100644 --- a/proposals/http/README.md +++ b/proposals/http/README.md @@ -4,7 +4,7 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Current Phase -wasi-http is currently in [Phase 1](https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-1---feature-proposal-cg). +wasi-http is currently in [Phase 2](https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-2---proposed-spec-text-available-cg--wg). ### Champions From 2f08b9c03709a0ad6eae0714e3b49e84411b64a9 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 28 Sep 2023 10:07:24 -0500 Subject: [PATCH 1214/1772] Document fields-get return value when the key is not present Resolves #56 --- proposals/http/wit/types.wit | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 6d92a8879..4f77f238c 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -43,6 +43,7 @@ interface types { type fields = u32 drop-fields: func(fields: fields) new-fields: func(entries: list>>) -> fields + // Returns an empty list if `name` is not present. fields-get: func(fields: fields, name: string) -> list> fields-set: func(fields: fields, name: string, value: list>) fields-delete: func(fields: fields, name: string) From ed6a7e912896f8532a071820c8f9b0043613bc35 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 29 Sep 2023 15:20:33 -0700 Subject: [PATCH 1215/1772] Update to wit-abi-up-to-date@v15. This fixes a bug in the handling of `poll-list`'s signature. --- proposals/sockets/.github/workflows/main.yml | 4 ++-- proposals/sockets/imports.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index cb345171f..5df3460af 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -13,9 +13,9 @@ jobs: - uses: actions/checkout@v3 - name: ensure `./wit/deps` are in sync run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.0/wit-deps-x86_64-unknown-linux-musl + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.3/wit-deps-x86_64-unknown-linux-musl chmod +x wit-deps ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v14 + - uses: WebAssembly/wit-abi-up-to-date@v15 diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index e6adfb36d..c7c28400b 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -264,7 +264,7 @@ the pollables has an error, it is indicated by marking the source as being reaedy for I/O.

        Params
        Return values
          @@ -276,7 +276,7 @@ being reaedy for I/O.

          pollable. When it returns, the handle is ready for I/O.

          Params

          Import interface wasi:sockets/udp


          From c910026f0c677c9f99ec7b1d40e155992b59b864 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 29 Sep 2023 15:25:19 -0700 Subject: [PATCH 1216/1772] Convert to Resources, and other API cleanups. (#46) * Convert to Resources, and other API cleanups. - Convert to resources. Use resources instead of `u32`s, remove drop functions, `this` arguments, and rename `subscribe-to-*` to just `subscribe`, as discussed in WebAssembly/wasi-poll#21. - Merge wasi-poll into wasi-io. These two proposals are closely related to each other, so it makes sense to have them together. - While here, tidy up the poll API, incorporating ideas discussed in WebAssembly/wasi-poll#22: - Rename `poll-oneoff` to `poll-list`, and add a `poll-one`. - Change `poll-oneoff`'s return type from `list` to `list`, because in the common case, this should allow it to create much smaller allocations. * Update to WebAssembly/wit-abi-up-to-date@v14. * Remove the wit-deps check now that we have no dependencies. * Fix more references to `poll-oneoff`. * Mark `poll` arguments as borrowed. * Update to wit-abi-up-to-date@v15. --- proposals/io/.github/workflows/main.yml | 11 +- proposals/io/README.md | 6 +- proposals/io/example-world.md | 417 --------------------- proposals/io/imports.md | 386 ++++++++++++++++++++ proposals/io/wit/deps.lock | 4 - proposals/io/wit/deps.toml | 1 - proposals/io/wit/deps/poll/poll.wit | 49 --- proposals/io/wit/deps/poll/world.wit | 5 - proposals/io/wit/poll.wit | 34 ++ proposals/io/wit/streams.wit | 465 ++++++++++++------------ proposals/io/wit/world.wit | 1 + 11 files changed, 651 insertions(+), 728 deletions(-) delete mode 100644 proposals/io/example-world.md create mode 100644 proposals/io/imports.md delete mode 100644 proposals/io/wit/deps.lock delete mode 100644 proposals/io/wit/deps.toml delete mode 100644 proposals/io/wit/deps/poll/poll.wit delete mode 100644 proposals/io/wit/deps/poll/world.wit create mode 100644 proposals/io/wit/poll.wit diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index cc3bf6573..e210671f2 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -10,12 +10,5 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: ensure `./wit/deps` are in sync - run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.2/wit-deps-x86_64-unknown-linux-musl - chmod +x wit-deps - ./wit-deps lock --check - - uses: WebAssembly/wit-abi-up-to-date@v13 - with: - wit-abi-tag: wit-abi-0.11.0 + - uses: actions/checkout@v3 + - uses: WebAssembly/wit-abi-up-to-date@v15 diff --git a/proposals/io/README.md b/proposals/io/README.md index 40700bd54..71e23ceff 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -69,7 +69,7 @@ types, `input-stream`, and `output-stream`, which support `read` and // If we didn't get any data promptly, wait for it. if data.len() == 0 { - let _ = poll_oneoff(&wait_input[..]); + let _ = poll_list(&wait_input[..]); (data, eos) = input.read(BUFFER_LEN)?; } @@ -79,7 +79,7 @@ types, `input-stream`, and `output-stream`, which support `read` and // If we didn't put any data promptly, wait for it. if num_written == 0 { - let _ = poll_oneoff(&wait_output[..]); + let _ = poll_list(&wait_output[..]); num_written = output.write(remaining)?; } @@ -108,7 +108,7 @@ types, `input-stream`, and `output-stream`, which support `read` and // If we didn't get any data promptly, wait for it. if num_copied == 0 { - let _ = poll_oneoff(&wait_input[..]); + let _ = poll_list(&wait_input[..]); } } Ok(()) diff --git a/proposals/io/example-world.md b/proposals/io/example-world.md deleted file mode 100644 index cef732d3c..000000000 --- a/proposals/io/example-world.md +++ /dev/null @@ -1,417 +0,0 @@ -

          World example-world

          - -

          Import interface wasi:poll/poll

          -

          A poll API intended to let users wait for I/O events on multiple handles -at once.

          -
          -

          Types

          -

          type pollable

          -

          u32

          -

          A "pollable" handle. -

          This is conceptually represents a stream<_, _>, or in other words, -a stream that one can wait on, repeatedly, but which does not itself -produce any data. It's temporary scaffolding until component-model's -async features are ready.

          -

          And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

          -

          pollable lifetimes are not automatically managed. Users must ensure -that they do not outlive the resource they reference.

          -

          This represents a resource.

          -
          -

          Functions

          -

          drop-pollable: func

          -

          Dispose of the specified pollable, after which it may no longer -be used.

          -
          Params
          - -

          poll-oneoff: func

          -

          Poll for completion on a set of pollables.

          -

          This function takes a list of pollables, which identify I/O sources of -interest, and waits until one or more of the events is ready for I/O.

          -

          The result list<bool> is the same length as the argument -list<pollable>, and indicates the readiness of each corresponding -element in that list, with true indicating ready. A single call can -return multiple true elements.

          -

          A timeout can be implemented by adding a pollable from the -wasi-clocks API to the list.

          -

          This function does not return a result; polling in itself does not -do any I/O so it doesn't fail. If any of the I/O sources identified by -the pollables has an error, it is indicated by marking the source as -ready in the list<bool>.

          -

          The "oneoff" in the name refers to the fact that this function must do a -linear scan through the entire list of subscriptions, which may be -inefficient if the number is large and the same subscriptions are used -many times. In the future, this is expected to be obsoleted by the -component model async proposal, which will include a scalable waiting -facility.

          -
          Params
          - -
          Return values
          -
            -
          • list<bool>
          • -
          -

          Import interface wasi:io/streams

          -

          WASI I/O is an I/O abstraction API which is currently focused on providing -stream types.

          -

          In the future, the component model is expected to add built-in stream types; -when it does, they are expected to subsume this API.

          -
          -

          Types

          -

          type pollable

          -

          pollable

          -

          -#### `enum write-error` -

          An error for output-stream operations.

          -

          Contrary to input-streams, a closed output-stream is reported using -an error.

          -
          Enum Cases
          -
            -
          • -

            last-operation-failed

            -

            The last operation (a write or flush) failed before completion. -

          • -
          • -

            closed

            -

            The stream is closed: no more input will be accepted by the -stream. A closed output-stream will return this error on all -future operations. -

          • -
          -

          enum stream-status

          -

          Streams provide a sequence of data and then end; once they end, they -no longer provide any further data.

          -

          For example, a stream reading from a file ends when the stream reaches -the end of the file. For another example, a stream reading from a -socket ends when the socket is closed.

          -
          Enum Cases
          -
            -
          • -

            open

            -

            The stream is open and may produce further data. -

          • -
          • -

            ended

            -

            When reading, this indicates that the stream will not produce -further data. -When writing, this indicates that the stream will no longer be read. -Further writes are still permitted. -

          • -
          -

          type output-stream

          -

          u32

          -

          An output bytestream. In the future, this will be replaced by handle -types. -

          output-streams are non-blocking to the extent practical on -underlying platforms. Except where specified otherwise, I/O operations also -always return promptly, after the number of bytes that can be written -promptly, which could even be zero. To wait for the stream to be ready to -accept data, the subscribe-to-output-stream function to obtain a -pollable which can be polled for using wasi:poll.

          -

          And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

          -

          This represents a resource.

          -

          type input-stream

          -

          u32

          -

          An input bytestream. In the future, this will be replaced by handle -types. -

          input-streams are non-blocking to the extent practical on underlying -platforms. I/O operations always return promptly; if fewer bytes are -promptly available than requested, they return the number of bytes promptly -available, which could even be zero. To wait for data to be available, -use the subscribe-to-input-stream function to obtain a pollable which -can be polled for using wasi:poll/poll.poll_oneoff.

          -

          And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

          -

          This represents a resource.

          -
          -

          Functions

          -

          read: func

          -

          Perform a non-blocking read from the stream.

          -

          This function returns a list of bytes containing the data that was -read, along with a stream-status which, indicates whether further -reads are expected to produce data. The returned list will contain up to -len bytes; it may return fewer than requested, but not more. An -empty list and stream-status:open indicates no more data is -available at this time, and that the pollable given by -subscribe-to-input-stream will be ready when more data is available.

          -

          Once a stream has reached the end, subsequent calls to read or -skip will always report stream-status:ended rather than producing more -data.

          -

          When the caller gives a len of 0, it represents a request to read 0 -bytes. This read should always succeed and return an empty list and -the current stream-status.

          -

          The len parameter is a u64, which could represent a list of u8 which -is not possible to allocate in wasm32, or not desirable to allocate as -as a return value by the callee. The callee may return a list of bytes -less than len in size while more bytes are available for reading.

          -
          Params
          - -
          Return values
          - -

          blocking-read: func

          -

          Read bytes from a stream, after blocking until at least one byte can -be read. Except for blocking, identical to read.

          -
          Params
          - -
          Return values
          - -

          skip: func

          -

          Skip bytes from a stream.

          -

          This is similar to the read function, but avoids copying the -bytes into the instance.

          -

          Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

          -

          This function returns the number of bytes skipped, along with a -stream-status indicating whether the end of the stream was -reached. The returned value will be at most len; it may be less.

          -
          Params
          - -
          Return values
          - -

          blocking-skip: func

          -

          Skip bytes from a stream, after blocking until at least one byte -can be skipped. Except for blocking behavior, identical to skip.

          -
          Params
          - -
          Return values
          - -

          subscribe-to-input-stream: func

          -

          Create a pollable which will resolve once either the specified stream -has bytes available to read or the other end of the stream has been -closed. -The created pollable is a child resource of the input-stream. -Implementations may trap if the input-stream is dropped before -all derived pollables created with this function are dropped.

          -
          Params
          - -
          Return values
          - -

          drop-input-stream: func

          -

          Dispose of the specified input-stream, after which it may no longer -be used. -Implementations may trap if this input-stream is dropped while child -pollable resources are still alive. -After this input-stream is dropped, implementations may report any -corresponding output-stream has stream-state.closed.

          -
          Params
          - -

          check-write: func

          -

          Check readiness for writing. This function never blocks.

          -

          Returns the number of bytes permitted for the next call to write, -or an error. Calling write with more bytes than this function has -permitted will trap.

          -

          When this function returns 0 bytes, the subscribe-to-output-stream -pollable will become ready when this function will report at least -1 byte, or an error.

          -
          Params
          - -
          Return values
          - -

          write: func

          -

          Perform a write. This function never blocks.

          -

          Precondition: check-write gave permit of Ok(n) and contents has a -length of less than or equal to n. Otherwise, this function will trap.

          -

          returns Err(closed) without writing if the stream has closed since -the last call to check-write provided a permit.

          -
          Params
          - -
          Return values
          - -

          blocking-write-and-flush: func

          -

          Perform a write of up to 4096 bytes, and then flush the stream. Block -until all of these operations are complete, or an error occurs.

          -

          This is a convenience wrapper around the use of check-write, -subscribe-to-output-stream, write, and flush, and is implemented -with the following pseudo-code:

          -
          let pollable = subscribe-to-output-stream(this);
          -while !contents.is_empty() {
          -  // Wait for the stream to become writable
          -  poll-oneoff(pollable);
          -  let Ok(n) = check-write(this); // eliding error handling
          -  let len = min(n, contents.len());
          -  let (chunk, rest) = contents.split_at(len);
          -  write(this, chunk);            // eliding error handling
          -  contents = rest;
          -}
          -flush(this);
          -// Wait for completion of `flush`
          -poll-oneoff(pollable);
          -// Check for any errors that arose during `flush`
          -let _ = check-write(this);       // eliding error handling
          -
          -
          Params
          - -
          Return values
          - -

          flush: func

          -

          Request to flush buffered output. This function never blocks.

          -

          This tells the output-stream that the caller intends any buffered -output to be flushed. the output which is expected to be flushed -is all that has been passed to write prior to this call.

          -

          Upon calling this function, the output-stream will not accept any -writes (check-write will return ok(0)) until the flush has -completed. The subscribe-to-output-stream pollable will become ready -when the flush has completed and the stream can accept more writes.

          -
          Params
          - -
          Return values
          - -

          blocking-flush: func

          -

          Request to flush buffered output, and block until flush completes -and stream is ready for writing again.

          -
          Params
          - -
          Return values
          - -

          subscribe-to-output-stream: func

          -

          Create a pollable which will resolve once the output-stream -is ready for more writing, or an error has occured. When this -pollable is ready, check-write will return ok(n) with n>0, or an -error.

          -

          If the stream is closed, this pollable is always ready immediately.

          -

          The created pollable is a child resource of the output-stream. -Implementations may trap if the output-stream is dropped before -all derived pollables created with this function are dropped.

          -
          Params
          - -
          Return values
          - -

          write-zeroes: func

          -

          Write zeroes to a stream.

          -

          this should be used precisely like write with the exact same -preconditions (must use check-write first), but instead of -passing a list of bytes, you simply pass the number of zero-bytes -that should be written.

          -
          Params
          - -
          Return values
          - -

          splice: func

          -

          Read from one stream and write to another.

          -

          This function returns the number of bytes transferred; it may be less -than len.

          -

          Unlike other I/O functions, this function blocks until all the data -read from the input stream has been written to the output stream.

          -
          Params
          - -
          Return values
          - -

          blocking-splice: func

          -

          Read from one stream and write to another, with blocking.

          -

          This is similar to splice, except that it blocks until at least -one byte can be read.

          -
          Params
          - -
          Return values
          - -

          forward: func

          -

          Forward the entire contents of an input stream to an output stream.

          -

          This function repeatedly reads from the input stream and writes -the data to the output stream, until the end of the input stream -is reached, or an error is encountered.

          -

          Unlike other I/O functions, this function blocks until the end -of the input stream is seen and all the data has been written to -the output stream.

          -

          This function returns the number of bytes transferred, and the status of -the output stream.

          -
          Params
          - -
          Return values
          - -

          drop-output-stream: func

          -

          Dispose of the specified output-stream, after which it may no longer -be used. -Implementations may trap if this output-stream is dropped while -child pollable resources are still alive. -After this output-stream is dropped, implementations may report any -corresponding input-stream has stream-state.closed.

          -
          Params
          - diff --git a/proposals/io/imports.md b/proposals/io/imports.md new file mode 100644 index 000000000..c4e8b5354 --- /dev/null +++ b/proposals/io/imports.md @@ -0,0 +1,386 @@ +

          World imports

          + +

          Import interface wasi:io/poll

          +

          A poll API intended to let users wait for I/O events on multiple handles +at once.

          +
          +

          Types

          +

          resource pollable

          +
          +

          Functions

          +

          poll-list: func

          +

          Poll for completion on a set of pollables.

          +

          This function takes a list of pollables, which identify I/O sources of +interest, and waits until one or more of the events is ready for I/O.

          +

          The result list<u32> contains one or more indices of handles in the +argument list that is ready for I/O.

          +

          If the list contains more elements than can be indexed with a u32 +value, this function traps.

          +

          A timeout can be implemented by adding a pollable from the +wasi-clocks API to the list.

          +

          This function does not return a result; polling in itself does not +do any I/O so it doesn't fail. If any of the I/O sources identified by +the pollables has an error, it is indicated by marking the source as +being reaedy for I/O.

          +
          Params
          + +
          Return values
          +
            +
          • list<u32>
          • +
          +

          poll-one: func

          +

          Poll for completion on a single pollable.

          +

          This function is similar to poll-list, but operates on only a single +pollable. When it returns, the handle is ready for I/O.

          +
          Params
          + +

          Import interface wasi:io/streams

          +

          WASI I/O is an I/O abstraction API which is currently focused on providing +stream types.

          +

          In the future, the component model is expected to add built-in stream types; +when it does, they are expected to subsume this API.

          +
          +

          Types

          +

          type pollable

          +

          pollable

          +

          +#### `enum stream-status` +

          Streams provide a sequence of data and then end; once they end, they +no longer provide any further data.

          +

          For example, a stream reading from a file ends when the stream reaches +the end of the file. For another example, a stream reading from a +socket ends when the socket is closed.

          +
          Enum Cases
          +
            +
          • +

            open

            +

            The stream is open and may produce further data. +

          • +
          • +

            ended

            +

            When reading, this indicates that the stream will not produce +further data. +When writing, this indicates that the stream will no longer be read. +Further writes are still permitted. +

          • +
          +

          resource input-stream

          +

          enum write-error

          +

          An error for output-stream operations.

          +

          Contrary to input-streams, a closed output-stream is reported using +an error.

          +
          Enum Cases
          +
            +
          • +

            last-operation-failed

            +

            The last operation (a write or flush) failed before completion. +

          • +
          • +

            closed

            +

            The stream is closed: no more input will be accepted by the +stream. A closed output-stream will return this error on all +future operations. +

          • +
          +

          resource output-stream

          +
          +

          Functions

          +

          [method]input-stream.read: func

          +

          Perform a non-blocking read from the stream.

          +

          This function returns a list of bytes containing the data that was +read, along with a stream-status which, indicates whether further +reads are expected to produce data. The returned list will contain up to +len bytes; it may return fewer than requested, but not more. An +empty list and stream-status:open indicates no more data is +available at this time, and that the pollable given by subscribe +will be ready when more data is available.

          +

          Once a stream has reached the end, subsequent calls to read or +skip will always report stream-status:ended rather than producing more +data.

          +

          When the caller gives a len of 0, it represents a request to read 0 +bytes. This read should always succeed and return an empty list and +the current stream-status.

          +

          The len parameter is a u64, which could represent a list of u8 which +is not possible to allocate in wasm32, or not desirable to allocate as +as a return value by the callee. The callee may return a list of bytes +less than len in size while more bytes are available for reading.

          +
          Params
          + +
          Return values
          + +

          [method]input-stream.blocking-read: func

          +

          Read bytes from a stream, after blocking until at least one byte can +be read. Except for blocking, identical to read.

          +
          Params
          + +
          Return values
          + +

          [method]input-stream.skip: func

          +

          Skip bytes from a stream.

          +

          This is similar to the read function, but avoids copying the +bytes into the instance.

          +

          Once a stream has reached the end, subsequent calls to read or +skip will always report end-of-stream rather than producing more +data.

          +

          This function returns the number of bytes skipped, along with a +stream-status indicating whether the end of the stream was +reached. The returned value will be at most len; it may be less.

          +
          Params
          + +
          Return values
          + +

          [method]input-stream.blocking-skip: func

          +

          Skip bytes from a stream, after blocking until at least one byte +can be skipped. Except for blocking behavior, identical to skip.

          +
          Params
          + +
          Return values
          + +

          [method]input-stream.subscribe: func

          +

          Create a pollable which will resolve once either the specified stream +has bytes available to read or the other end of the stream has been +closed. +The created pollable is a child resource of the input-stream. +Implementations may trap if the input-stream is dropped before +all derived pollables created with this function are dropped.

          +
          Params
          + +
          Return values
          + +

          [method]output-stream.check-write: func

          +

          Check readiness for writing. This function never blocks.

          +

          Returns the number of bytes permitted for the next call to write, +or an error. Calling write with more bytes than this function has +permitted will trap.

          +

          When this function returns 0 bytes, the subscribe pollable will +become ready when this function will report at least 1 byte, or an +error.

          +
          Params
          + +
          Return values
          + +

          [method]output-stream.write: func

          +

          Perform a write. This function never blocks.

          +

          Precondition: check-write gave permit of Ok(n) and contents has a +length of less than or equal to n. Otherwise, this function will trap.

          +

          returns Err(closed) without writing if the stream has closed since +the last call to check-write provided a permit.

          +
          Params
          + +
          Return values
          + +

          [method]output-stream.blocking-write-and-flush: func

          +

          Perform a write of up to 4096 bytes, and then flush the stream. Block +until all of these operations are complete, or an error occurs.

          +

          This is a convenience wrapper around the use of check-write, +subscribe, write, and flush, and is implemented with the +following pseudo-code:

          +
          let pollable = this.subscribe();
          +while !contents.is_empty() {
          +  // Wait for the stream to become writable
          +  poll-one(pollable);
          +  let Ok(n) = this.check-write(); // eliding error handling
          +  let len = min(n, contents.len());
          +  let (chunk, rest) = contents.split_at(len);
          +  this.write(chunk  );            // eliding error handling
          +  contents = rest;
          +}
          +this.flush();
          +// Wait for completion of `flush`
          +poll-one(pollable);
          +// Check for any errors that arose during `flush`
          +let _ = this.check-write();         // eliding error handling
          +
          +
          Params
          + +
          Return values
          + +

          [method]output-stream.flush: func

          +

          Request to flush buffered output. This function never blocks.

          +

          This tells the output-stream that the caller intends any buffered +output to be flushed. the output which is expected to be flushed +is all that has been passed to write prior to this call.

          +

          Upon calling this function, the output-stream will not accept any +writes (check-write will return ok(0)) until the flush has +completed. The subscribe pollable will become ready when the +flush has completed and the stream can accept more writes.

          +
          Params
          + +
          Return values
          + +

          [method]output-stream.blocking-flush: func

          +

          Request to flush buffered output, and block until flush completes +and stream is ready for writing again.

          +
          Params
          + +
          Return values
          + +

          [method]output-stream.subscribe: func

          +

          Create a pollable which will resolve once the output-stream +is ready for more writing, or an error has occured. When this +pollable is ready, check-write will return ok(n) with n>0, or an +error.

          +

          If the stream is closed, this pollable is always ready immediately.

          +

          The created pollable is a child resource of the output-stream. +Implementations may trap if the output-stream is dropped before +all derived pollables created with this function are dropped.

          +
          Params
          + +
          Return values
          + +

          [method]output-stream.write-zeroes: func

          +

          Write zeroes to a stream.

          +

          this should be used precisely like write with the exact same +preconditions (must use check-write first), but instead of +passing a list of bytes, you simply pass the number of zero-bytes +that should be written.

          +
          Params
          + +
          Return values
          + +

          [method]output-stream.blocking-write-zeroes-and-flush: func

          +

          Perform a write of up to 4096 zeroes, and then flush the stream. +Block until all of these operations are complete, or an error +occurs.

          +

          This is a convenience wrapper around the use of check-write, +subscribe, write-zeroes, and flush, and is implemented with +the following pseudo-code:

          +
          let pollable = this.subscribe();
          +while num_zeroes != 0 {
          +  // Wait for the stream to become writable
          +  poll-one(pollable);
          +  let Ok(n) = this.check-write(); // eliding error handling
          +  let len = min(n, num_zeroes);
          +  this.write-zeroes(len);         // eliding error handling
          +  num_zeroes -= len;
          +}
          +this.flush();
          +// Wait for completion of `flush`
          +poll-one(pollable);
          +// Check for any errors that arose during `flush`
          +let _ = this.check-write();         // eliding error handling
          +
          +
          Params
          + +
          Return values
          + +

          [method]output-stream.splice: func

          +

          Read from one stream and write to another.

          +

          This function returns the number of bytes transferred; it may be less +than len.

          +

          Unlike other I/O functions, this function blocks until all the data +read from the input stream has been written to the output stream.

          +
          Params
          + +
          Return values
          + +

          [method]output-stream.blocking-splice: func

          +

          Read from one stream and write to another, with blocking.

          +

          This is similar to splice, except that it blocks until at least +one byte can be read.

          +
          Params
          + +
          Return values
          + +

          [method]output-stream.forward: func

          +

          Forward the entire contents of an input stream to an output stream.

          +

          This function repeatedly reads from the input stream and writes +the data to the output stream, until the end of the input stream +is reached, or an error is encountered.

          +

          Unlike other I/O functions, this function blocks until the end +of the input stream is seen and all the data has been written to +the output stream.

          +

          This function returns the number of bytes transferred, and the status of +the output stream.

          +
          Params
          + +
          Return values
          + diff --git a/proposals/io/wit/deps.lock b/proposals/io/wit/deps.lock deleted file mode 100644 index 6babe9f1e..000000000 --- a/proposals/io/wit/deps.lock +++ /dev/null @@ -1,4 +0,0 @@ -[poll] -url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -sha256 = "d4c27124f4c137eb538b5c92ba5858ed9042e11b24a2eef85d14becd0b7f55de" -sha512 = "422c01b273b4b1377ece6f2e4ba0dfc609ca8ef30a3e0be0e172e1303fcf7b3ca4c470f4dea6c51bdf114b0f5c871ebc4934dfe3bf217d66ea689748df2b1e55" diff --git a/proposals/io/wit/deps.toml b/proposals/io/wit/deps.toml deleted file mode 100644 index cefc393fa..000000000 --- a/proposals/io/wit/deps.toml +++ /dev/null @@ -1 +0,0 @@ -poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" diff --git a/proposals/io/wit/deps/poll/poll.wit b/proposals/io/wit/deps/poll/poll.wit deleted file mode 100644 index fa82b6063..000000000 --- a/proposals/io/wit/deps/poll/poll.wit +++ /dev/null @@ -1,49 +0,0 @@ -/// A poll API intended to let users wait for I/O events on multiple handles -/// at once. -interface poll { - /// A "pollable" handle. - /// - /// This is conceptually represents a `stream<_, _>`, or in other words, - /// a stream that one can wait on, repeatedly, but which does not itself - /// produce any data. It's temporary scaffolding until component-model's - /// async features are ready. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// `pollable` lifetimes are not automatically managed. Users must ensure - /// that they do not outlive the resource they reference. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type pollable = u32 - - /// Dispose of the specified `pollable`, after which it may no longer - /// be used. - drop-pollable: func(this: pollable) - - /// Poll for completion on a set of pollables. - /// - /// This function takes a list of pollables, which identify I/O sources of - /// interest, and waits until one or more of the events is ready for I/O. - /// - /// The result `list` is the same length as the argument - /// `list`, and indicates the readiness of each corresponding - /// element in that list, with true indicating ready. A single call can - /// return multiple true elements. - /// - /// A timeout can be implemented by adding a pollable from the - /// wasi-clocks API to the list. - /// - /// This function does not return a `result`; polling in itself does not - /// do any I/O so it doesn't fail. If any of the I/O sources identified by - /// the pollables has an error, it is indicated by marking the source as - /// ready in the `list`. - /// - /// The "oneoff" in the name refers to the fact that this function must do a - /// linear scan through the entire list of subscriptions, which may be - /// inefficient if the number is large and the same subscriptions are used - /// many times. In the future, this is expected to be obsoleted by the - /// component model async proposal, which will include a scalable waiting - /// facility. - poll-oneoff: func(in: list) -> list -} diff --git a/proposals/io/wit/deps/poll/world.wit b/proposals/io/wit/deps/poll/world.wit deleted file mode 100644 index d08cadc05..000000000 --- a/proposals/io/wit/deps/poll/world.wit +++ /dev/null @@ -1,5 +0,0 @@ -package wasi:poll - -world example-world { - import poll -} diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit new file mode 100644 index 000000000..e95762b91 --- /dev/null +++ b/proposals/io/wit/poll.wit @@ -0,0 +1,34 @@ +package wasi:io + +/// A poll API intended to let users wait for I/O events on multiple handles +/// at once. +interface poll { + /// A "pollable" handle. + resource pollable + + /// Poll for completion on a set of pollables. + /// + /// This function takes a list of pollables, which identify I/O sources of + /// interest, and waits until one or more of the events is ready for I/O. + /// + /// The result `list` contains one or more indices of handles in the + /// argument list that is ready for I/O. + /// + /// If the list contains more elements than can be indexed with a `u32` + /// value, this function traps. + /// + /// A timeout can be implemented by adding a pollable from the + /// wasi-clocks API to the list. + /// + /// This function does not return a `result`; polling in itself does not + /// do any I/O so it doesn't fail. If any of the I/O sources identified by + /// the pollables has an error, it is indicated by marking the source as + /// being reaedy for I/O. + poll-list: func(in: list>) -> list + + /// Poll for completion on a single pollable. + /// + /// This function is similar to `poll-list`, but operates on only a single + /// pollable. When it returns, the handle is ready for I/O. + poll-one: func(in: borrow) +} diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index e2631f66a..eeeff5058 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -6,7 +6,7 @@ package wasi:io /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { - use wasi:poll/poll.{pollable} + use poll.{pollable} /// Streams provide a sequence of data and then end; once they end, they /// no longer provide any further data. @@ -24,115 +24,81 @@ interface streams { ended, } - /// An input bytestream. In the future, this will be replaced by handle - /// types. + /// An input bytestream. /// /// `input-stream`s are *non-blocking* to the extent practical on underlying /// platforms. I/O operations always return promptly; if fewer bytes are /// promptly available than requested, they return the number of bytes promptly /// available, which could even be zero. To wait for data to be available, - /// use the `subscribe-to-input-stream` function to obtain a `pollable` which - /// can be polled for using `wasi:poll/poll.poll_oneoff`. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type input-stream = u32 - - /// Perform a non-blocking read from the stream. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a `stream-status` which, indicates whether further - /// reads are expected to produce data. The returned list will contain up to - /// `len` bytes; it may return fewer than requested, but not more. An - /// empty list and `stream-status:open` indicates no more data is - /// available at this time, and that the pollable given by - /// `subscribe-to-input-stream` will be ready when more data is available. - /// - /// Once a stream has reached the end, subsequent calls to `read` or - /// `skip` will always report `stream-status:ended` rather than producing more - /// data. - /// - /// When the caller gives a `len` of 0, it represents a request to read 0 - /// bytes. This read should always succeed and return an empty list and - /// the current `stream-status`. - /// - /// The `len` parameter is a `u64`, which could represent a list of u8 which - /// is not possible to allocate in wasm32, or not desirable to allocate as - /// as a return value by the callee. The callee may return a list of bytes - /// less than `len` in size while more bytes are available for reading. - read: func( - this: input-stream, - /// The maximum number of bytes to read - len: u64 - ) -> result, stream-status>> - - /// Read bytes from a stream, after blocking until at least one byte can - /// be read. Except for blocking, identical to `read`. - blocking-read: func( - this: input-stream, - /// The maximum number of bytes to read - len: u64 - ) -> result, stream-status>> - - /// Skip bytes from a stream. - /// - /// This is similar to the `read` function, but avoids copying the - /// bytes into the instance. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// This function returns the number of bytes skipped, along with a - /// `stream-status` indicating whether the end of the stream was - /// reached. The returned value will be at most `len`; it may be less. - skip: func( - this: input-stream, - /// The maximum number of bytes to skip. - len: u64, - ) -> result> + /// use the `subscribe` function to obtain a `pollable` which can be polled + /// for using `wasi:io/poll`. + resource input-stream { + /// Perform a non-blocking read from the stream. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a `stream-status` which, indicates whether further + /// reads are expected to produce data. The returned list will contain up to + /// `len` bytes; it may return fewer than requested, but not more. An + /// empty list and `stream-status:open` indicates no more data is + /// available at this time, and that the pollable given by `subscribe` + /// will be ready when more data is available. + /// + /// Once a stream has reached the end, subsequent calls to `read` or + /// `skip` will always report `stream-status:ended` rather than producing more + /// data. + /// + /// When the caller gives a `len` of 0, it represents a request to read 0 + /// bytes. This read should always succeed and return an empty list and + /// the current `stream-status`. + /// + /// The `len` parameter is a `u64`, which could represent a list of u8 which + /// is not possible to allocate in wasm32, or not desirable to allocate as + /// as a return value by the callee. The callee may return a list of bytes + /// less than `len` in size while more bytes are available for reading. + read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-status>> - /// Skip bytes from a stream, after blocking until at least one byte - /// can be skipped. Except for blocking behavior, identical to `skip`. - blocking-skip: func( - this: input-stream, - /// The maximum number of bytes to skip. - len: u64, - ) -> result> + /// Read bytes from a stream, after blocking until at least one byte can + /// be read. Except for blocking, identical to `read`. + blocking-read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-status>> - /// Create a `pollable` which will resolve once either the specified stream - /// has bytes available to read or the other end of the stream has been - /// closed. - /// The created `pollable` is a child resource of the `input-stream`. - /// Implementations may trap if the `input-stream` is dropped before - /// all derived `pollable`s created with this function are dropped. - subscribe-to-input-stream: func(this: input-stream) -> pollable + /// Skip bytes from a stream. + /// + /// This is similar to the `read` function, but avoids copying the + /// bytes into the instance. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// This function returns the number of bytes skipped, along with a + /// `stream-status` indicating whether the end of the stream was + /// reached. The returned value will be at most `len`; it may be less. + skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result> - /// Dispose of the specified `input-stream`, after which it may no longer - /// be used. - /// Implementations may trap if this `input-stream` is dropped while child - /// `pollable` resources are still alive. - /// After this `input-stream` is dropped, implementations may report any - /// corresponding `output-stream` has `stream-state.closed`. - drop-input-stream: func(this: input-stream) + /// Skip bytes from a stream, after blocking until at least one byte + /// can be skipped. Except for blocking behavior, identical to `skip`. + blocking-skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result> - /// An output bytestream. In the future, this will be replaced by handle - /// types. - /// - /// `output-stream`s are *non-blocking* to the extent practical on - /// underlying platforms. Except where specified otherwise, I/O operations also - /// always return promptly, after the number of bytes that can be written - /// promptly, which could even be zero. To wait for the stream to be ready to - /// accept data, the `subscribe-to-output-stream` function to obtain a - /// `pollable` which can be polled for using `wasi:poll`. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type output-stream = u32 + /// Create a `pollable` which will resolve once either the specified stream + /// has bytes available to read or the other end of the stream has been + /// closed. + /// The created `pollable` is a child resource of the `input-stream`. + /// Implementations may trap if the `input-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe: func() -> pollable + } /// An error for output-stream operations. /// @@ -146,155 +112,174 @@ interface streams { /// future operations. closed } - /// Check readiness for writing. This function never blocks. - /// - /// Returns the number of bytes permitted for the next call to `write`, - /// or an error. Calling `write` with more bytes than this function has - /// permitted will trap. - /// - /// When this function returns 0 bytes, the `subscribe-to-output-stream` - /// pollable will become ready when this function will report at least - /// 1 byte, or an error. - check-write: func( - this: output-stream - ) -> result - /// Perform a write. This function never blocks. - /// - /// Precondition: check-write gave permit of Ok(n) and contents has a - /// length of less than or equal to n. Otherwise, this function will trap. + /// An output bytestream. /// - /// returns Err(closed) without writing if the stream has closed since - /// the last call to check-write provided a permit. - write: func( - this: output-stream, - contents: list - ) -> result<_, write-error> + /// `output-stream`s are *non-blocking* to the extent practical on + /// underlying platforms. Except where specified otherwise, I/O operations also + /// always return promptly, after the number of bytes that can be written + /// promptly, which could even be zero. To wait for the stream to be ready to + /// accept data, the `subscribe` function to obtain a `pollable` which can be + /// polled for using `wasi:io/poll`. + resource output-stream { + /// Check readiness for writing. This function never blocks. + /// + /// Returns the number of bytes permitted for the next call to `write`, + /// or an error. Calling `write` with more bytes than this function has + /// permitted will trap. + /// + /// When this function returns 0 bytes, the `subscribe` pollable will + /// become ready when this function will report at least 1 byte, or an + /// error. + check-write: func() -> result - /// Perform a write of up to 4096 bytes, and then flush the stream. Block - /// until all of these operations are complete, or an error occurs. - /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe-to-output-stream`, `write`, and `flush`, and is implemented - /// with the following pseudo-code: - /// - /// ```text - /// let pollable = subscribe-to-output-stream(this); - /// while !contents.is_empty() { - /// // Wait for the stream to become writable - /// poll-oneoff(pollable); - /// let Ok(n) = check-write(this); // eliding error handling - /// let len = min(n, contents.len()); - /// let (chunk, rest) = contents.split_at(len); - /// write(this, chunk); // eliding error handling - /// contents = rest; - /// } - /// flush(this); - /// // Wait for completion of `flush` - /// poll-oneoff(pollable); - /// // Check for any errors that arose during `flush` - /// let _ = check-write(this); // eliding error handling - /// ``` - blocking-write-and-flush: func( - this: output-stream, - contents: list - ) -> result<_, write-error> + /// Perform a write. This function never blocks. + /// + /// Precondition: check-write gave permit of Ok(n) and contents has a + /// length of less than or equal to n. Otherwise, this function will trap. + /// + /// returns Err(closed) without writing if the stream has closed since + /// the last call to check-write provided a permit. + write: func( + contents: list + ) -> result<_, write-error> - /// Request to flush buffered output. This function never blocks. - /// - /// This tells the output-stream that the caller intends any buffered - /// output to be flushed. the output which is expected to be flushed - /// is all that has been passed to `write` prior to this call. - /// - /// Upon calling this function, the `output-stream` will not accept any - /// writes (`check-write` will return `ok(0)`) until the flush has - /// completed. The `subscribe-to-output-stream` pollable will become ready - /// when the flush has completed and the stream can accept more writes. - flush: func( - this: output-stream, - ) -> result<_, write-error> + /// Perform a write of up to 4096 bytes, and then flush the stream. Block + /// until all of these operations are complete, or an error occurs. + /// + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe`, `write`, and `flush`, and is implemented with the + /// following pseudo-code: + /// + /// ```text + /// let pollable = this.subscribe(); + /// while !contents.is_empty() { + /// // Wait for the stream to become writable + /// poll-one(pollable); + /// let Ok(n) = this.check-write(); // eliding error handling + /// let len = min(n, contents.len()); + /// let (chunk, rest) = contents.split_at(len); + /// this.write(chunk ); // eliding error handling + /// contents = rest; + /// } + /// this.flush(); + /// // Wait for completion of `flush` + /// poll-one(pollable); + /// // Check for any errors that arose during `flush` + /// let _ = this.check-write(); // eliding error handling + /// ``` + blocking-write-and-flush: func( + contents: list + ) -> result<_, write-error> - /// Request to flush buffered output, and block until flush completes - /// and stream is ready for writing again. - blocking-flush: func( - this: output-stream, - ) -> result<_, write-error> + /// Request to flush buffered output. This function never blocks. + /// + /// This tells the output-stream that the caller intends any buffered + /// output to be flushed. the output which is expected to be flushed + /// is all that has been passed to `write` prior to this call. + /// + /// Upon calling this function, the `output-stream` will not accept any + /// writes (`check-write` will return `ok(0)`) until the flush has + /// completed. The `subscribe` pollable will become ready when the + /// flush has completed and the stream can accept more writes. + flush: func() -> result<_, write-error> - /// Create a `pollable` which will resolve once the output-stream - /// is ready for more writing, or an error has occured. When this - /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an - /// error. - /// - /// If the stream is closed, this pollable is always ready immediately. - /// - /// The created `pollable` is a child resource of the `output-stream`. - /// Implementations may trap if the `output-stream` is dropped before - /// all derived `pollable`s created with this function are dropped. - subscribe-to-output-stream: func(this: output-stream) -> pollable + /// Request to flush buffered output, and block until flush completes + /// and stream is ready for writing again. + blocking-flush: func() -> result<_, write-error> - /// Write zeroes to a stream. - /// - /// this should be used precisely like `write` with the exact same - /// preconditions (must use check-write first), but instead of - /// passing a list of bytes, you simply pass the number of zero-bytes - /// that should be written. - write-zeroes: func( - this: output-stream, - /// The number of zero-bytes to write - len: u64 - ) -> result<_, write-error> + /// Create a `pollable` which will resolve once the output-stream + /// is ready for more writing, or an error has occured. When this + /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an + /// error. + /// + /// If the stream is closed, this pollable is always ready immediately. + /// + /// The created `pollable` is a child resource of the `output-stream`. + /// Implementations may trap if the `output-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe: func() -> pollable - /// Read from one stream and write to another. - /// - /// This function returns the number of bytes transferred; it may be less - /// than `len`. - /// - /// Unlike other I/O functions, this function blocks until all the data - /// read from the input stream has been written to the output stream. - splice: func( - this: output-stream, - /// The stream to read from - src: input-stream, - /// The number of bytes to splice - len: u64, - ) -> result> + /// Write zeroes to a stream. + /// + /// this should be used precisely like `write` with the exact same + /// preconditions (must use check-write first), but instead of + /// passing a list of bytes, you simply pass the number of zero-bytes + /// that should be written. + write-zeroes: func( + /// The number of zero-bytes to write + len: u64 + ) -> result<_, write-error> - /// Read from one stream and write to another, with blocking. - /// - /// This is similar to `splice`, except that it blocks until at least - /// one byte can be read. - blocking-splice: func( - this: output-stream, - /// The stream to read from - src: input-stream, - /// The number of bytes to splice - len: u64, - ) -> result> + /// Perform a write of up to 4096 zeroes, and then flush the stream. + /// Block until all of these operations are complete, or an error + /// occurs. + /// + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with + /// the following pseudo-code: + /// + /// ```text + /// let pollable = this.subscribe(); + /// while num_zeroes != 0 { + /// // Wait for the stream to become writable + /// poll-one(pollable); + /// let Ok(n) = this.check-write(); // eliding error handling + /// let len = min(n, num_zeroes); + /// this.write-zeroes(len); // eliding error handling + /// num_zeroes -= len; + /// } + /// this.flush(); + /// // Wait for completion of `flush` + /// poll-one(pollable); + /// // Check for any errors that arose during `flush` + /// let _ = this.check-write(); // eliding error handling + /// ``` + blocking-write-zeroes-and-flush: func( + /// The number of zero-bytes to write + len: u64 + ) -> result<_, write-error> - /// Forward the entire contents of an input stream to an output stream. - /// - /// This function repeatedly reads from the input stream and writes - /// the data to the output stream, until the end of the input stream - /// is reached, or an error is encountered. - /// - /// Unlike other I/O functions, this function blocks until the end - /// of the input stream is seen and all the data has been written to - /// the output stream. - /// - /// This function returns the number of bytes transferred, and the status of - /// the output stream. - forward: func( - this: output-stream, - /// The stream to read from - src: input-stream - ) -> result> + /// Read from one stream and write to another. + /// + /// This function returns the number of bytes transferred; it may be less + /// than `len`. + /// + /// Unlike other I/O functions, this function blocks until all the data + /// read from the input stream has been written to the output stream. + splice: func( + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result> + /// Read from one stream and write to another, with blocking. + /// + /// This is similar to `splice`, except that it blocks until at least + /// one byte can be read. + blocking-splice: func( + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result> - /// Dispose of the specified `output-stream`, after which it may no longer - /// be used. - /// Implementations may trap if this `output-stream` is dropped while - /// child `pollable` resources are still alive. - /// After this `output-stream` is dropped, implementations may report any - /// corresponding `input-stream` has `stream-state.closed`. - drop-output-stream: func(this: output-stream) + /// Forward the entire contents of an input stream to an output stream. + /// + /// This function repeatedly reads from the input stream and writes + /// the data to the output stream, until the end of the input stream + /// is reached, or an error is encountered. + /// + /// Unlike other I/O functions, this function blocks until the end + /// of the input stream is seen and all the data has been written to + /// the output stream. + /// + /// This function returns the number of bytes transferred, and the status of + /// the output stream. + forward: func( + /// The stream to read from + src: input-stream + ) -> result> + } } diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index e9ca233da..8738dba75 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -2,4 +2,5 @@ package wasi:io world imports { import streams + import poll } From fa4727fd5ee5d061cd5560c8c9ef05613ed9cc65 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 29 Sep 2023 15:40:42 -0700 Subject: [PATCH 1217/1772] Convert to resources. (#50) * Convert to resources. wasi-clocks no longer has any pseudo-resources, so this just updates the poll dependency to account for the changes in WebAssembly/wasi-io#46. * git add poll.wit * Update to wit-abi-up-to-date@v14. * Update to actions/checkout@v3. * Update to the latest wasi-io changes. * Update to wit-abi-up-to-date@v15 and wit-deps 0.3.3. * wasi-io is now updated --- proposals/clocks/.github/workflows/main.yml | 8 +- .../clocks/{example-world.md => imports.md} | 65 ++-- proposals/clocks/wit/deps.lock | 8 +- proposals/clocks/wit/deps.toml | 3 +- proposals/clocks/wit/deps/io/poll.wit | 34 +++ proposals/clocks/wit/deps/io/streams.wit | 285 ++++++++++++++++++ proposals/clocks/wit/deps/io/world.wit | 6 + proposals/clocks/wit/deps/poll/poll.wit | 49 --- proposals/clocks/wit/deps/poll/world.wit | 5 - proposals/clocks/wit/monotonic-clock.wit | 2 +- 10 files changed, 363 insertions(+), 102 deletions(-) rename proposals/clocks/{example-world.md => imports.md} (74%) create mode 100644 proposals/clocks/wit/deps/io/poll.wit create mode 100644 proposals/clocks/wit/deps/io/streams.wit create mode 100644 proposals/clocks/wit/deps/io/world.wit delete mode 100644 proposals/clocks/wit/deps/poll/poll.wit delete mode 100644 proposals/clocks/wit/deps/poll/world.wit diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 3cba299bc..5df3460af 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -10,14 +10,12 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: ensure `./wit/deps` are in sync run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.0/wit-deps-x86_64-unknown-linux-musl + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.3/wit-deps-x86_64-unknown-linux-musl chmod +x wit-deps ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v13 - with: - wit-abi-tag: wit-abi-0.11.0 + - uses: WebAssembly/wit-abi-up-to-date@v15 diff --git a/proposals/clocks/example-world.md b/proposals/clocks/imports.md similarity index 74% rename from proposals/clocks/example-world.md rename to proposals/clocks/imports.md index f716f899f..f82d3c1bb 100644 --- a/proposals/clocks/example-world.md +++ b/proposals/clocks/imports.md @@ -1,60 +1,51 @@ -

          World example-world

          +

          World imports

          -

          Import interface wasi:poll/poll

          +

          Import interface wasi:io/poll

          A poll API intended to let users wait for I/O events on multiple handles at once.


          Types

          -

          type pollable

          -

          u32

          -

          A "pollable" handle. -

          This is conceptually represents a stream<_, _>, or in other words, -a stream that one can wait on, repeatedly, but which does not itself -produce any data. It's temporary scaffolding until component-model's -async features are ready.

          -

          And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

          -

          pollable lifetimes are not automatically managed. Users must ensure -that they do not outlive the resource they reference.

          -

          This represents a resource.

          +

          resource pollable


          Functions

          -

          drop-pollable: func

          -

          Dispose of the specified pollable, after which it may no longer -be used.

          -
          Params
          - -

          poll-oneoff: func

          +

          poll-list: func

          Poll for completion on a set of pollables.

          -

          The "oneoff" in the name refers to the fact that this function must do a -linear scan through the entire list of subscriptions, which may be -inefficient if the number is large and the same subscriptions are used -many times. In the future, this is expected to be obsoleted by the -component model async proposal, which will include a scalable waiting -facility.

          -

          Note that the return type would ideally be list<bool>, but that would -be more difficult to polyfill given the current state of wit-bindgen. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 -for details. For now, we use zero to mean "not ready" and non-zero to -mean "ready".

          +

          This function takes a list of pollables, which identify I/O sources of +interest, and waits until one or more of the events is ready for I/O.

          +

          The result list<u32> contains one or more indices of handles in the +argument list that is ready for I/O.

          +

          If the list contains more elements than can be indexed with a u32 +value, this function traps.

          +

          A timeout can be implemented by adding a pollable from the +wasi-clocks API to the list.

          +

          This function does not return a result; polling in itself does not +do any I/O so it doesn't fail. If any of the I/O sources identified by +the pollables has an error, it is indicated by marking the source as +being reaedy for I/O.

          Params
          Return values
            -
          • list<u8>
          • +
          • list<u32>
          • +
          +

          poll-one: func

          +

          Poll for completion on a single pollable.

          +

          This function is similar to poll-list, but operates on only a single +pollable. When it returns, the handle is ready for I/O.

          +
          Params
          +

          Import interface wasi:clocks/monotonic-clock

          WASI Monotonic Clock is a clock API intended to let users measure elapsed @@ -98,7 +89,7 @@ reached.

        Return values

        Import interface wasi:clocks/wall-clock

        WASI Wall Clock is a clock API intended to let users query the current diff --git a/proposals/clocks/wit/deps.lock b/proposals/clocks/wit/deps.lock index 6babe9f1e..41d5cbb11 100644 --- a/proposals/clocks/wit/deps.lock +++ b/proposals/clocks/wit/deps.lock @@ -1,4 +1,4 @@ -[poll] -url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -sha256 = "d4c27124f4c137eb538b5c92ba5858ed9042e11b24a2eef85d14becd0b7f55de" -sha512 = "422c01b273b4b1377ece6f2e4ba0dfc609ca8ef30a3e0be0e172e1303fcf7b3ca4c470f4dea6c51bdf114b0f5c871ebc4934dfe3bf217d66ea689748df2b1e55" +[io] +url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +sha256 = "6e20bcf4d4f5466b60c05ea8da7289ca361a7febdd22ab1a531e5ef7e394ab8d" +sha512 = "21f6689bce6ed6d9e3bd96372e5c7ed003a7aefbf8d49b4eea949dfbd265cf57a0d7dc67aa71e3de75d48fcc2c0cfe5f06f7e9e7959a23bc98f77da85f4161b9" diff --git a/proposals/clocks/wit/deps.toml b/proposals/clocks/wit/deps.toml index cefc393fa..f29c61c1a 100644 --- a/proposals/clocks/wit/deps.toml +++ b/proposals/clocks/wit/deps.toml @@ -1 +1,2 @@ -poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" +# Temporarily use the resources branch. +io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" diff --git a/proposals/clocks/wit/deps/io/poll.wit b/proposals/clocks/wit/deps/io/poll.wit new file mode 100644 index 000000000..e95762b91 --- /dev/null +++ b/proposals/clocks/wit/deps/io/poll.wit @@ -0,0 +1,34 @@ +package wasi:io + +/// A poll API intended to let users wait for I/O events on multiple handles +/// at once. +interface poll { + /// A "pollable" handle. + resource pollable + + /// Poll for completion on a set of pollables. + /// + /// This function takes a list of pollables, which identify I/O sources of + /// interest, and waits until one or more of the events is ready for I/O. + /// + /// The result `list` contains one or more indices of handles in the + /// argument list that is ready for I/O. + /// + /// If the list contains more elements than can be indexed with a `u32` + /// value, this function traps. + /// + /// A timeout can be implemented by adding a pollable from the + /// wasi-clocks API to the list. + /// + /// This function does not return a `result`; polling in itself does not + /// do any I/O so it doesn't fail. If any of the I/O sources identified by + /// the pollables has an error, it is indicated by marking the source as + /// being reaedy for I/O. + poll-list: func(in: list>) -> list + + /// Poll for completion on a single pollable. + /// + /// This function is similar to `poll-list`, but operates on only a single + /// pollable. When it returns, the handle is ready for I/O. + poll-one: func(in: borrow) +} diff --git a/proposals/clocks/wit/deps/io/streams.wit b/proposals/clocks/wit/deps/io/streams.wit new file mode 100644 index 000000000..eeeff5058 --- /dev/null +++ b/proposals/clocks/wit/deps/io/streams.wit @@ -0,0 +1,285 @@ +package wasi:io + +/// WASI I/O is an I/O abstraction API which is currently focused on providing +/// stream types. +/// +/// In the future, the component model is expected to add built-in stream types; +/// when it does, they are expected to subsume this API. +interface streams { + use poll.{pollable} + + /// Streams provide a sequence of data and then end; once they end, they + /// no longer provide any further data. + /// + /// For example, a stream reading from a file ends when the stream reaches + /// the end of the file. For another example, a stream reading from a + /// socket ends when the socket is closed. + enum stream-status { + /// The stream is open and may produce further data. + open, + /// When reading, this indicates that the stream will not produce + /// further data. + /// When writing, this indicates that the stream will no longer be read. + /// Further writes are still permitted. + ended, + } + + /// An input bytestream. + /// + /// `input-stream`s are *non-blocking* to the extent practical on underlying + /// platforms. I/O operations always return promptly; if fewer bytes are + /// promptly available than requested, they return the number of bytes promptly + /// available, which could even be zero. To wait for data to be available, + /// use the `subscribe` function to obtain a `pollable` which can be polled + /// for using `wasi:io/poll`. + resource input-stream { + /// Perform a non-blocking read from the stream. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a `stream-status` which, indicates whether further + /// reads are expected to produce data. The returned list will contain up to + /// `len` bytes; it may return fewer than requested, but not more. An + /// empty list and `stream-status:open` indicates no more data is + /// available at this time, and that the pollable given by `subscribe` + /// will be ready when more data is available. + /// + /// Once a stream has reached the end, subsequent calls to `read` or + /// `skip` will always report `stream-status:ended` rather than producing more + /// data. + /// + /// When the caller gives a `len` of 0, it represents a request to read 0 + /// bytes. This read should always succeed and return an empty list and + /// the current `stream-status`. + /// + /// The `len` parameter is a `u64`, which could represent a list of u8 which + /// is not possible to allocate in wasm32, or not desirable to allocate as + /// as a return value by the callee. The callee may return a list of bytes + /// less than `len` in size while more bytes are available for reading. + read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-status>> + + /// Read bytes from a stream, after blocking until at least one byte can + /// be read. Except for blocking, identical to `read`. + blocking-read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-status>> + + /// Skip bytes from a stream. + /// + /// This is similar to the `read` function, but avoids copying the + /// bytes into the instance. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// This function returns the number of bytes skipped, along with a + /// `stream-status` indicating whether the end of the stream was + /// reached. The returned value will be at most `len`; it may be less. + skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result> + + /// Skip bytes from a stream, after blocking until at least one byte + /// can be skipped. Except for blocking behavior, identical to `skip`. + blocking-skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result> + + /// Create a `pollable` which will resolve once either the specified stream + /// has bytes available to read or the other end of the stream has been + /// closed. + /// The created `pollable` is a child resource of the `input-stream`. + /// Implementations may trap if the `input-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe: func() -> pollable + } + + /// An error for output-stream operations. + /// + /// Contrary to input-streams, a closed output-stream is reported using + /// an error. + enum write-error { + /// The last operation (a write or flush) failed before completion. + last-operation-failed, + /// The stream is closed: no more input will be accepted by the + /// stream. A closed output-stream will return this error on all + /// future operations. + closed + } + + /// An output bytestream. + /// + /// `output-stream`s are *non-blocking* to the extent practical on + /// underlying platforms. Except where specified otherwise, I/O operations also + /// always return promptly, after the number of bytes that can be written + /// promptly, which could even be zero. To wait for the stream to be ready to + /// accept data, the `subscribe` function to obtain a `pollable` which can be + /// polled for using `wasi:io/poll`. + resource output-stream { + /// Check readiness for writing. This function never blocks. + /// + /// Returns the number of bytes permitted for the next call to `write`, + /// or an error. Calling `write` with more bytes than this function has + /// permitted will trap. + /// + /// When this function returns 0 bytes, the `subscribe` pollable will + /// become ready when this function will report at least 1 byte, or an + /// error. + check-write: func() -> result + + /// Perform a write. This function never blocks. + /// + /// Precondition: check-write gave permit of Ok(n) and contents has a + /// length of less than or equal to n. Otherwise, this function will trap. + /// + /// returns Err(closed) without writing if the stream has closed since + /// the last call to check-write provided a permit. + write: func( + contents: list + ) -> result<_, write-error> + + /// Perform a write of up to 4096 bytes, and then flush the stream. Block + /// until all of these operations are complete, or an error occurs. + /// + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe`, `write`, and `flush`, and is implemented with the + /// following pseudo-code: + /// + /// ```text + /// let pollable = this.subscribe(); + /// while !contents.is_empty() { + /// // Wait for the stream to become writable + /// poll-one(pollable); + /// let Ok(n) = this.check-write(); // eliding error handling + /// let len = min(n, contents.len()); + /// let (chunk, rest) = contents.split_at(len); + /// this.write(chunk ); // eliding error handling + /// contents = rest; + /// } + /// this.flush(); + /// // Wait for completion of `flush` + /// poll-one(pollable); + /// // Check for any errors that arose during `flush` + /// let _ = this.check-write(); // eliding error handling + /// ``` + blocking-write-and-flush: func( + contents: list + ) -> result<_, write-error> + + /// Request to flush buffered output. This function never blocks. + /// + /// This tells the output-stream that the caller intends any buffered + /// output to be flushed. the output which is expected to be flushed + /// is all that has been passed to `write` prior to this call. + /// + /// Upon calling this function, the `output-stream` will not accept any + /// writes (`check-write` will return `ok(0)`) until the flush has + /// completed. The `subscribe` pollable will become ready when the + /// flush has completed and the stream can accept more writes. + flush: func() -> result<_, write-error> + + /// Request to flush buffered output, and block until flush completes + /// and stream is ready for writing again. + blocking-flush: func() -> result<_, write-error> + + /// Create a `pollable` which will resolve once the output-stream + /// is ready for more writing, or an error has occured. When this + /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an + /// error. + /// + /// If the stream is closed, this pollable is always ready immediately. + /// + /// The created `pollable` is a child resource of the `output-stream`. + /// Implementations may trap if the `output-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe: func() -> pollable + + /// Write zeroes to a stream. + /// + /// this should be used precisely like `write` with the exact same + /// preconditions (must use check-write first), but instead of + /// passing a list of bytes, you simply pass the number of zero-bytes + /// that should be written. + write-zeroes: func( + /// The number of zero-bytes to write + len: u64 + ) -> result<_, write-error> + + /// Perform a write of up to 4096 zeroes, and then flush the stream. + /// Block until all of these operations are complete, or an error + /// occurs. + /// + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with + /// the following pseudo-code: + /// + /// ```text + /// let pollable = this.subscribe(); + /// while num_zeroes != 0 { + /// // Wait for the stream to become writable + /// poll-one(pollable); + /// let Ok(n) = this.check-write(); // eliding error handling + /// let len = min(n, num_zeroes); + /// this.write-zeroes(len); // eliding error handling + /// num_zeroes -= len; + /// } + /// this.flush(); + /// // Wait for completion of `flush` + /// poll-one(pollable); + /// // Check for any errors that arose during `flush` + /// let _ = this.check-write(); // eliding error handling + /// ``` + blocking-write-zeroes-and-flush: func( + /// The number of zero-bytes to write + len: u64 + ) -> result<_, write-error> + + /// Read from one stream and write to another. + /// + /// This function returns the number of bytes transferred; it may be less + /// than `len`. + /// + /// Unlike other I/O functions, this function blocks until all the data + /// read from the input stream has been written to the output stream. + splice: func( + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result> + + /// Read from one stream and write to another, with blocking. + /// + /// This is similar to `splice`, except that it blocks until at least + /// one byte can be read. + blocking-splice: func( + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result> + + /// Forward the entire contents of an input stream to an output stream. + /// + /// This function repeatedly reads from the input stream and writes + /// the data to the output stream, until the end of the input stream + /// is reached, or an error is encountered. + /// + /// Unlike other I/O functions, this function blocks until the end + /// of the input stream is seen and all the data has been written to + /// the output stream. + /// + /// This function returns the number of bytes transferred, and the status of + /// the output stream. + forward: func( + /// The stream to read from + src: input-stream + ) -> result> + } +} diff --git a/proposals/clocks/wit/deps/io/world.wit b/proposals/clocks/wit/deps/io/world.wit new file mode 100644 index 000000000..8738dba75 --- /dev/null +++ b/proposals/clocks/wit/deps/io/world.wit @@ -0,0 +1,6 @@ +package wasi:io + +world imports { + import streams + import poll +} diff --git a/proposals/clocks/wit/deps/poll/poll.wit b/proposals/clocks/wit/deps/poll/poll.wit deleted file mode 100644 index fa82b6063..000000000 --- a/proposals/clocks/wit/deps/poll/poll.wit +++ /dev/null @@ -1,49 +0,0 @@ -/// A poll API intended to let users wait for I/O events on multiple handles -/// at once. -interface poll { - /// A "pollable" handle. - /// - /// This is conceptually represents a `stream<_, _>`, or in other words, - /// a stream that one can wait on, repeatedly, but which does not itself - /// produce any data. It's temporary scaffolding until component-model's - /// async features are ready. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// `pollable` lifetimes are not automatically managed. Users must ensure - /// that they do not outlive the resource they reference. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type pollable = u32 - - /// Dispose of the specified `pollable`, after which it may no longer - /// be used. - drop-pollable: func(this: pollable) - - /// Poll for completion on a set of pollables. - /// - /// This function takes a list of pollables, which identify I/O sources of - /// interest, and waits until one or more of the events is ready for I/O. - /// - /// The result `list` is the same length as the argument - /// `list`, and indicates the readiness of each corresponding - /// element in that list, with true indicating ready. A single call can - /// return multiple true elements. - /// - /// A timeout can be implemented by adding a pollable from the - /// wasi-clocks API to the list. - /// - /// This function does not return a `result`; polling in itself does not - /// do any I/O so it doesn't fail. If any of the I/O sources identified by - /// the pollables has an error, it is indicated by marking the source as - /// ready in the `list`. - /// - /// The "oneoff" in the name refers to the fact that this function must do a - /// linear scan through the entire list of subscriptions, which may be - /// inefficient if the number is large and the same subscriptions are used - /// many times. In the future, this is expected to be obsoleted by the - /// component model async proposal, which will include a scalable waiting - /// facility. - poll-oneoff: func(in: list) -> list -} diff --git a/proposals/clocks/wit/deps/poll/world.wit b/proposals/clocks/wit/deps/poll/world.wit deleted file mode 100644 index d08cadc05..000000000 --- a/proposals/clocks/wit/deps/poll/world.wit +++ /dev/null @@ -1,5 +0,0 @@ -package wasi:poll - -world example-world { - import poll -} diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index fb8424eb0..703a5fb7a 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -9,7 +9,7 @@ /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:poll/poll.{pollable} + use wasi:io/poll.{pollable} /// A timestamp in nanoseconds. type instant = u64 From 666f9018896e0ddd02830f2a4cdab74608f91597 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 29 Sep 2023 15:44:22 -0700 Subject: [PATCH 1218/1772] Update to the main wasi-io branch. --- proposals/sockets/wit/deps.lock | 2 +- proposals/sockets/wit/deps.toml | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index 3d68907bc..41d5cbb11 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,4 +1,4 @@ [io] -url = "https://github.com/sunfishcode/wasi-io/archive/resources.tar.gz" +url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" sha256 = "6e20bcf4d4f5466b60c05ea8da7289ca361a7febdd22ab1a531e5ef7e394ab8d" sha512 = "21f6689bce6ed6d9e3bd96372e5c7ed003a7aefbf8d49b4eea949dfbd265cf57a0d7dc67aa71e3de75d48fcc2c0cfe5f06f7e9e7959a23bc98f77da85f4161b9" diff --git a/proposals/sockets/wit/deps.toml b/proposals/sockets/wit/deps.toml index 671c3f141..b178cb257 100644 --- a/proposals/sockets/wit/deps.toml +++ b/proposals/sockets/wit/deps.toml @@ -1,3 +1 @@ -# Temporarily use the resources branches. -#io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -io = "https://github.com/sunfishcode/wasi-io/archive/resources.tar.gz" +io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" From 8473782b97a89086ed8ca0db4533b131d4a04dbe Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 29 Sep 2023 15:45:39 -0700 Subject: [PATCH 1219/1772] Delete an obsolete comment. --- proposals/clocks/wit/deps.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/clocks/wit/deps.toml b/proposals/clocks/wit/deps.toml index f29c61c1a..b178cb257 100644 --- a/proposals/clocks/wit/deps.toml +++ b/proposals/clocks/wit/deps.toml @@ -1,2 +1 @@ -# Temporarily use the resources branch. io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" From 56a54eb1ce45ac7fab5a791f566a6e87d5596d6b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 29 Sep 2023 15:57:20 -0700 Subject: [PATCH 1220/1772] Update to wit-abi-up-to-date@v15. (#35) --- proposals/random/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index 9b91f42cb..e210671f2 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -11,4 +11,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: WebAssembly/wit-abi-up-to-date@v14 + - uses: WebAssembly/wit-abi-up-to-date@v15 From b0dcd47898cf226010f660d7bf6dc90c64d9b390 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 29 Sep 2023 16:01:19 -0700 Subject: [PATCH 1221/1772] Convert to resources. (#132) * Convert to resources. Convert `descriptor` and `directory-entry-stream` to resources, and update the dependencies to account for the changes in WebAssembly/wasi-io#46 and WebAssembly/wasi-clocks#50. * Update CI dependencies. * Update generated files. * Remove `this` arguments. * Remove the old `poll` wit files, which are now in wasi:io. * Update to the latest wasi-io changes. * Fix descriptor arguments to be borrows. * Update to wit-abi-up-to-date@v15 and wit-deps 0.3.3. * Update to the main io and clocks branches. --- .../filesystem/.github/workflows/main.yml | 8 +- proposals/filesystem/example-world.md | 1439 ---------------- proposals/filesystem/imports.md | 1495 +++++++++++++++++ proposals/filesystem/wit/deps.lock | 13 +- proposals/filesystem/wit/deps.toml | 4 +- .../wit/deps/clocks/monotonic-clock.wit | 2 +- .../filesystem/wit/deps/clocks/timezone.wit | 17 +- .../filesystem/wit/deps/clocks/world.wit | 2 +- proposals/filesystem/wit/deps/io/poll.wit | 34 + proposals/filesystem/wit/deps/io/streams.wit | 460 ++--- proposals/filesystem/wit/deps/io/world.wit | 3 +- proposals/filesystem/wit/deps/poll/poll.wit | 49 - proposals/filesystem/wit/deps/poll/world.wit | 5 - proposals/filesystem/wit/types.wit | 996 ++++++----- 14 files changed, 2268 insertions(+), 2259 deletions(-) delete mode 100644 proposals/filesystem/example-world.md create mode 100644 proposals/filesystem/imports.md create mode 100644 proposals/filesystem/wit/deps/io/poll.wit delete mode 100644 proposals/filesystem/wit/deps/poll/poll.wit delete mode 100644 proposals/filesystem/wit/deps/poll/world.wit diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index 3cba299bc..5df3460af 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -10,14 +10,12 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: ensure `./wit/deps` are in sync run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.0/wit-deps-x86_64-unknown-linux-musl + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.3/wit-deps-x86_64-unknown-linux-musl chmod +x wit-deps ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v13 - with: - wit-abi-tag: wit-abi-0.11.0 + - uses: WebAssembly/wit-abi-up-to-date@v15 diff --git a/proposals/filesystem/example-world.md b/proposals/filesystem/example-world.md deleted file mode 100644 index 533ff39f5..000000000 --- a/proposals/filesystem/example-world.md +++ /dev/null @@ -1,1439 +0,0 @@ -

        World example-world

        - -

        Import interface wasi:poll/poll

        -

        A poll API intended to let users wait for I/O events on multiple handles -at once.

        -
        -

        Types

        -

        type pollable

        -

        u32

        -

        A "pollable" handle. -

        This is conceptually represents a stream<_, _>, or in other words, -a stream that one can wait on, repeatedly, but which does not itself -produce any data. It's temporary scaffolding until component-model's -async features are ready.

        -

        And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

        -

        pollable lifetimes are not automatically managed. Users must ensure -that they do not outlive the resource they reference.

        -

        This represents a resource.

        -
        -

        Functions

        -

        drop-pollable: func

        -

        Dispose of the specified pollable, after which it may no longer -be used.

        -
        Params
        - -

        poll-oneoff: func

        -

        Poll for completion on a set of pollables.

        -

        The "oneoff" in the name refers to the fact that this function must do a -linear scan through the entire list of subscriptions, which may be -inefficient if the number is large and the same subscriptions are used -many times. In the future, this is expected to be obsoleted by the -component model async proposal, which will include a scalable waiting -facility.

        -

        Note that the return type would ideally be list<bool>, but that would -be more difficult to polyfill given the current state of wit-bindgen. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 -for details. For now, we use zero to mean "not ready" and non-zero to -mean "ready".

        -
        Params
        - -
        Return values
        -
          -
        • list<u8>
        • -
        -

        Import interface wasi:io/streams

        -

        WASI I/O is an I/O abstraction API which is currently focused on providing -stream types.

        -

        In the future, the component model is expected to add built-in stream types; -when it does, they are expected to subsume this API.

        -
        -

        Types

        -

        type pollable

        -

        pollable

        -

        -#### `record stream-error` -

        An error type returned from a stream operation. Currently this -doesn't provide any additional information.

        -
        Record Fields
        -

        type output-stream

        -

        u32

        -

        An output bytestream. In the future, this will be replaced by handle -types. -

        This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

        -

        output-streams are non-blocking to the extent practical on -underlying platforms. Except where specified otherwise, I/O operations also -always return promptly, after the number of bytes that can be written -promptly, which could even be zero. To wait for the stream to be ready to -accept data, the subscribe-to-output-stream function to obtain a -pollable which can be polled for using wasi_poll.

        -

        And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

        -

        This represents a resource.

        -

        type input-stream

        -

        u32

        -

        An input bytestream. In the future, this will be replaced by handle -types. -

        This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

        -

        input-streams are non-blocking to the extent practical on underlying -platforms. I/O operations always return promptly; if fewer bytes are -promptly available than requested, they return the number of bytes promptly -available, which could even be zero. To wait for data to be available, -use the subscribe-to-input-stream function to obtain a pollable which -can be polled for using wasi_poll.

        -

        And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

        -

        This represents a resource.

        -
        -

        Functions

        -

        read: func

        -

        Read bytes from a stream.

        -

        This function returns a list of bytes containing the data that was -read, along with a bool which, when true, indicates that the end of the -stream was reached. The returned list will contain up to len bytes; it -may return fewer than requested, but not more.

        -

        Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

        -

        If len is 0, it represents a request to read 0 bytes, which should -always succeed, assuming the stream hasn't reached its end yet, and -return an empty list.

        -

        The len here is a u64, but some callees may not be able to allocate -a buffer as large as that would imply. -FIXME: describe what happens if allocation fails.

        -
        Params
        - -
        Return values
        - -

        blocking-read: func

        -

        Read bytes from a stream, with blocking.

        -

        This is similar to read, except that it blocks until at least one -byte can be read.

        -
        Params
        - -
        Return values
        - -

        skip: func

        -

        Skip bytes from a stream.

        -

        This is similar to the read function, but avoids copying the -bytes into the instance.

        -

        Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

        -

        This function returns the number of bytes skipped, along with a bool -indicating whether the end of the stream was reached. The returned -value will be at most len; it may be less.

        -
        Params
        - -
        Return values
        - -

        blocking-skip: func

        -

        Skip bytes from a stream, with blocking.

        -

        This is similar to skip, except that it blocks until at least one -byte can be consumed.

        -
        Params
        - -
        Return values
        - -

        subscribe-to-input-stream: func

        -

        Create a pollable which will resolve once either the specified stream -has bytes available to read or the other end of the stream has been -closed.

        -
        Params
        - -
        Return values
        - -

        drop-input-stream: func

        -

        Dispose of the specified input-stream, after which it may no longer -be used.

        -
        Params
        - -

        write: func

        -

        Write bytes to a stream.

        -

        This function returns a u64 indicating the number of bytes from -buf that were written; it may be less than the full list.

        -
        Params
        - -
        Return values
        - -

        blocking-write: func

        -

        Write bytes to a stream, with blocking.

        -

        This is similar to write, except that it blocks until at least one -byte can be written.

        -
        Params
        - -
        Return values
        - -

        write-zeroes: func

        -

        Write multiple zero bytes to a stream.

        -

        This function returns a u64 indicating the number of zero bytes -that were written; it may be less than len.

        -
        Params
        - -
        Return values
        - -

        blocking-write-zeroes: func

        -

        Write multiple zero bytes to a stream, with blocking.

        -

        This is similar to write-zeroes, except that it blocks until at least -one byte can be written.

        -
        Params
        - -
        Return values
        - -

        splice: func

        -

        Read from one stream and write to another.

        -

        This function returns the number of bytes transferred; it may be less -than len.

        -

        Unlike other I/O functions, this function blocks until all the data -read from the input stream has been written to the output stream.

        -
        Params
        - -
        Return values
        - -

        blocking-splice: func

        -

        Read from one stream and write to another, with blocking.

        -

        This is similar to splice, except that it blocks until at least -one byte can be read.

        -
        Params
        - -
        Return values
        - -

        forward: func

        -

        Forward the entire contents of an input stream to an output stream.

        -

        This function repeatedly reads from the input stream and writes -the data to the output stream, until the end of the input stream -is reached, or an error is encountered.

        -

        Unlike other I/O functions, this function blocks until the end -of the input stream is seen and all the data has been written to -the output stream.

        -

        This function returns the number of bytes transferred.

        -
        Params
        - -
        Return values
        - -

        subscribe-to-output-stream: func

        -

        Create a pollable which will resolve once either the specified stream -is ready to accept bytes or the other end of the stream has been closed.

        -
        Params
        - -
        Return values
        - -

        drop-output-stream: func

        -

        Dispose of the specified output-stream, after which it may no longer -be used.

        -
        Params
        - -

        Import interface wasi:clocks/wall-clock

        -

        WASI Wall Clock is a clock API intended to let users query the current -time. The name "wall" makes an analogy to a "clock on the wall", which -is not necessarily monotonic as it may be reset.

        -

        It is intended to be portable at least between Unix-family platforms and -Windows.

        -

        A wall clock is a clock which measures the date and time according to -some external reference.

        -

        External references may be reset, so this clock is not necessarily -monotonic, making it unsuitable for measuring elapsed time.

        -

        It is intended for reporting the current date and time for humans.

        -
        -

        Types

        -

        record datetime

        -

        A time and date in seconds plus nanoseconds.

        -
        Record Fields
        - -
        -

        Functions

        -

        now: func

        -

        Read the current value of the clock.

        -

        This clock is not monotonic, therefore calling this function repeatedly -will not necessarily produce a sequence of non-decreasing values.

        -

        The returned timestamps represent the number of seconds since -1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, -also known as Unix Time.

        -

        The nanoseconds field of the output is always less than 1000000000.

        -
        Return values
        - -

        resolution: func

        -

        Query the resolution of the clock.

        -

        The nanoseconds field of the output is always less than 1000000000.

        -
        Return values
        - -

        Import interface wasi:filesystem/types

        -

        WASI filesystem is a filesystem API primarily intended to let users run WASI -programs that access their files on their existing filesystems, without -significant overhead.

        -

        It is intended to be roughly portable between Unix-family platforms and -Windows, though it does not hide many of the major differences.

        -

        Paths are passed as interface-type strings, meaning they must consist of -a sequence of Unicode Scalar Values (USVs). Some filesystems may contain -paths which are not accessible by this API.

        -

        The directory separator in WASI is always the forward-slash (/).

        -

        All paths in WASI are relative paths, and are interpreted relative to a -descriptor referring to a base directory. If a path argument to any WASI -function starts with /, or if any step of resolving a path, including -.. and symbolic link steps, reaches a directory outside of the base -directory, or reaches a symlink to an absolute or rooted path in the -underlying filesystem, the function fails with error-code::not-permitted.

        -

        For more information about WASI path resolution and sandboxing, see -WASI filesystem path resolution.

        -
        -

        Types

        -

        type input-stream

        -

        input-stream

        -

        -#### `type output-stream` -[`output-stream`](#output_stream) -

        -#### `type datetime` -[`datetime`](#datetime) -

        -#### `flags path-flags` -

        Flags determining the method of how paths are resolved.

        -
        Flags members
        -
          -
        • symlink-follow:

          As long as the resolved path corresponds to a symbolic link, it is -expanded. -

        • -
        -

        flags open-flags

        -

        Open flags used by open-at.

        -
        Flags members
        -
          -
        • -

          create:

          -

          Create file if it does not exist, similar to `O_CREAT` in POSIX. -

        • -
        • -

          directory:

          -

          Fail if not a directory, similar to `O_DIRECTORY` in POSIX. -

        • -
        • -

          exclusive:

          -

          Fail if file already exists, similar to `O_EXCL` in POSIX. -

        • -
        • -

          truncate:

          -

          Truncate file to size 0, similar to `O_TRUNC` in POSIX. -

        • -
        -

        flags modes

        -

        Permissions mode used by open-at, change-file-permissions-at, and -similar.

        -
        Flags members
        -
          -
        • -

          readable:

          -

          True if the resource is considered readable by the containing -filesystem. -

        • -
        • -

          writable:

          -

          True if the resource is considered writable by the containing -filesystem. -

        • -
        • -

          executable:

          -

          True if the resource is considered executable by the containing -filesystem. This does not apply to directories. -

        • -
        -

        record metadata-hash-value

        -

        A 128-bit hash value, split into parts because wasm doesn't have a -128-bit integer type.

        -
        Record Fields
        -
          -
        • -

          lower: u64

          -

          64 bits of a 128-bit hash value. -

        • -
        • -

          upper: u64

          -

          Another 64 bits of a 128-bit hash value. -

        • -
        -

        type link-count

        -

        u64

        -

        Number of hard links to an inode. -

        type filesize

        -

        u64

        -

        File size or length of a region within a file. -

        enum error-code

        -

        Error codes returned by functions, similar to errno in POSIX. -Not all of these error codes are returned by the functions provided by this -API; some are used in higher-level library layers, and others are provided -merely for alignment with POSIX.

        -
        Enum Cases
        -
          -
        • -

          access

          -

          Permission denied, similar to `EACCES` in POSIX. -

        • -
        • -

          would-block

          -

          Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. -

        • -
        • -

          already

          -

          Connection already in progress, similar to `EALREADY` in POSIX. -

        • -
        • -

          bad-descriptor

          -

          Bad descriptor, similar to `EBADF` in POSIX. -

        • -
        • -

          busy

          -

          Device or resource busy, similar to `EBUSY` in POSIX. -

        • -
        • -

          deadlock

          -

          Resource deadlock would occur, similar to `EDEADLK` in POSIX. -

        • -
        • -

          quota

          -

          Storage quota exceeded, similar to `EDQUOT` in POSIX. -

        • -
        • -

          exist

          -

          File exists, similar to `EEXIST` in POSIX. -

        • -
        • -

          file-too-large

          -

          File too large, similar to `EFBIG` in POSIX. -

        • -
        • -

          illegal-byte-sequence

          -

          Illegal byte sequence, similar to `EILSEQ` in POSIX. -

        • -
        • -

          in-progress

          -

          Operation in progress, similar to `EINPROGRESS` in POSIX. -

        • -
        • -

          interrupted

          -

          Interrupted function, similar to `EINTR` in POSIX. -

        • -
        • -

          invalid

          -

          Invalid argument, similar to `EINVAL` in POSIX. -

        • -
        • -

          io

          -

          I/O error, similar to `EIO` in POSIX. -

        • -
        • -

          is-directory

          -

          Is a directory, similar to `EISDIR` in POSIX. -

        • -
        • -

          loop

          -

          Too many levels of symbolic links, similar to `ELOOP` in POSIX. -

        • -
        • -

          too-many-links

          -

          Too many links, similar to `EMLINK` in POSIX. -

        • -
        • -

          message-size

          -

          Message too large, similar to `EMSGSIZE` in POSIX. -

        • -
        • -

          name-too-long

          -

          Filename too long, similar to `ENAMETOOLONG` in POSIX. -

        • -
        • -

          no-device

          -

          No such device, similar to `ENODEV` in POSIX. -

        • -
        • -

          no-entry

          -

          No such file or directory, similar to `ENOENT` in POSIX. -

        • -
        • -

          no-lock

          -

          No locks available, similar to `ENOLCK` in POSIX. -

        • -
        • -

          insufficient-memory

          -

          Not enough space, similar to `ENOMEM` in POSIX. -

        • -
        • -

          insufficient-space

          -

          No space left on device, similar to `ENOSPC` in POSIX. -

        • -
        • -

          not-directory

          -

          Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. -

        • -
        • -

          not-empty

          -

          Directory not empty, similar to `ENOTEMPTY` in POSIX. -

        • -
        • -

          not-recoverable

          -

          State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. -

        • -
        • -

          unsupported

          -

          Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. -

        • -
        • -

          no-tty

          -

          Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. -

        • -
        • -

          no-such-device

          -

          No such device or address, similar to `ENXIO` in POSIX. -

        • -
        • -

          overflow

          -

          Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. -

        • -
        • -

          not-permitted

          -

          Operation not permitted, similar to `EPERM` in POSIX. -

        • -
        • -

          pipe

          -

          Broken pipe, similar to `EPIPE` in POSIX. -

        • -
        • -

          read-only

          -

          Read-only file system, similar to `EROFS` in POSIX. -

        • -
        • -

          invalid-seek

          -

          Invalid seek, similar to `ESPIPE` in POSIX. -

        • -
        • -

          text-file-busy

          -

          Text file busy, similar to `ETXTBSY` in POSIX. -

        • -
        • -

          cross-device

          -

          Cross-device link, similar to `EXDEV` in POSIX. -

        • -
        -

        type directory-entry-stream

        -

        u32

        -

        A stream of directory entries. -

        This represents a stream of dir-entry.

        -

        enum descriptor-type

        -

        The type of a filesystem object referenced by a descriptor.

        -

        Note: This was called filetype in earlier versions of WASI.

        -
        Enum Cases
        -
          -
        • -

          unknown

          -

          The type of the descriptor or file is unknown or is different from -any of the other types specified. -

        • -
        • -

          block-device

          -

          The descriptor refers to a block device inode. -

        • -
        • -

          character-device

          -

          The descriptor refers to a character device inode. -

        • -
        • -

          directory

          -

          The descriptor refers to a directory inode. -

        • -
        • -

          fifo

          -

          The descriptor refers to a named pipe. -

        • -
        • -

          symbolic-link

          -

          The file refers to a symbolic link inode. -

        • -
        • -

          regular-file

          -

          The descriptor refers to a regular file inode. -

        • -
        • -

          socket

          -

          The descriptor refers to a socket. -

        • -
        -

        record directory-entry

        -

        A directory entry.

        -
        Record Fields
        -
          -
        • -

          type: descriptor-type

          -

          The type of the file referred to by this directory entry. -

        • -
        • -

          name: string

          -

          The name of the object. -

        • -
        -

        flags descriptor-flags

        -

        Descriptor flags.

        -

        Note: This was called fdflags in earlier versions of WASI.

        -
        Flags members
        -
          -
        • -

          read:

          -

          Read mode: Data can be read. -

        • -
        • -

          write:

          -

          Write mode: Data can be written to. -

        • -
        • -

          file-integrity-sync:

          -

          Request that writes be performed according to synchronized I/O file -integrity completion. The data stored in the file and the file's -metadata are synchronized. This is similar to `O_SYNC` in POSIX. -

          The precise semantics of this operation have not yet been defined for -WASI. At this time, it should be interpreted as a request, and not a -requirement.

          -
        • -
        • -

          data-integrity-sync:

          -

          Request that writes be performed according to synchronized I/O data -integrity completion. Only the data stored in the file is -synchronized. This is similar to `O_DSYNC` in POSIX. -

          The precise semantics of this operation have not yet been defined for -WASI. At this time, it should be interpreted as a request, and not a -requirement.

          -
        • -
        • -

          requested-write-sync:

          -

          Requests that reads be performed at the same level of integrety -requested for writes. This is similar to `O_RSYNC` in POSIX. -

          The precise semantics of this operation have not yet been defined for -WASI. At this time, it should be interpreted as a request, and not a -requirement.

          -
        • -
        • -

          mutate-directory:

          -

          Mutating directories mode: Directory contents may be mutated. -

          When this flag is unset on a descriptor, operations using the -descriptor which would create, rename, delete, modify the data or -metadata of filesystem objects, or obtain another handle which -would permit any of those, shall fail with error-code::read-only if -they would otherwise succeed.

          -

          This may only be set on directories.

          -
        • -
        -

        type descriptor

        -

        u32

        -

        A descriptor is a reference to a filesystem object, which may be a file, -directory, named pipe, special file, or other object on which filesystem -calls may be made. -

        This represents a resource.

        -

        variant new-timestamp

        -

        When setting a timestamp, this gives the value to set it to.

        -
        Variant Cases
        -
          -
        • -

          no-change

          -

          Leave the timestamp set to its previous value. -

        • -
        • -

          now

          -

          Set the timestamp to the current time of the system clock associated -with the filesystem. -

        • -
        • -

          timestamp: datetime

          -

          Set the timestamp to the given value. -

        • -
        -

        record descriptor-stat

        -

        File attributes.

        -

        Note: This was called filestat in earlier versions of WASI.

        -
        Record Fields
        -
          -
        • -

          type: descriptor-type

          -

          File type. -

        • -
        • -

          link-count: link-count

          -

          Number of hard links to the file. -

        • -
        • -

          size: filesize

          -

          For regular files, the file size in bytes. For symbolic links, the -length in bytes of the pathname contained in the symbolic link. -

        • -
        • -

          data-access-timestamp: option<datetime>

          -

          Last data access timestamp. -

          If the option is none, the platform doesn't maintain an access -timestamp for this file.

          -
        • -
        • -

          data-modification-timestamp: option<datetime>

          -

          Last data modification timestamp. -

          If the option is none, the platform doesn't maintain a -modification timestamp for this file.

          -
        • -
        • -

          status-change-timestamp: option<datetime>

          -

          Last file status-change timestamp. -

          If the option is none, the platform doesn't maintain a -status-change timestamp for this file.

          -
        • -
        -

        enum advice

        -

        File or memory access pattern advisory information.

        -
        Enum Cases
        -
          -
        • -

          normal

          -

          The application has no advice to give on its behavior with respect -to the specified data. -

        • -
        • -

          sequential

          -

          The application expects to access the specified data sequentially -from lower offsets to higher offsets. -

        • -
        • -

          random

          -

          The application expects to access the specified data in a random -order. -

        • -
        • -

          will-need

          -

          The application expects to access the specified data in the near -future. -

        • -
        • -

          dont-need

          -

          The application expects that it will not access the specified data -in the near future. -

        • -
        • -

          no-reuse

          -

          The application expects to access the specified data once and then -not reuse it thereafter. -

        • -
        -

        variant access-type

        -

        Access type used by access-at.

        -
        Variant Cases
        -
          -
        • -

          access: modes

          -

          Test for readability, writeability, or executability. -

        • -
        • -

          exists

          -

          Test whether the path exists. -

        • -
        -
        -

        Functions

        -

        read-via-stream: func

        -

        Return a stream for reading from a file, if available.

        -

        May fail with an error-code describing why the file cannot be read.

        -

        Multiple read, write, and append streams may be active on the same open -file and they do not interfere with each other.

        -

        Note: This allows using read-stream, which is similar to read in POSIX.

        -
        Params
        - -
        Return values
        - -

        write-via-stream: func

        -

        Return a stream for writing to a file, if available.

        -

        May fail with an error-code describing why the file cannot be written.

        -

        Note: This allows using write-stream, which is similar to write in -POSIX.

        -
        Params
        - -
        Return values
        - -

        append-via-stream: func

        -

        Return a stream for appending to a file, if available.

        -

        May fail with an error-code describing why the file cannot be appended.

        -

        Note: This allows using write-stream, which is similar to write with -O_APPEND in in POSIX.

        -
        Params
        - -
        Return values
        - -

        advise: func

        -

        Provide file advisory information on a descriptor.

        -

        This is similar to posix_fadvise in POSIX.

        -
        Params
        - -
        Return values
        - -

        sync-data: func

        -

        Synchronize the data of a file to disk.

        -

        This function succeeds with no effect if the file descriptor is not -opened for writing.

        -

        Note: This is similar to fdatasync in POSIX.

        -
        Params
        - -
        Return values
        - -

        get-flags: func

        -

        Get flags associated with a descriptor.

        -

        Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

        -

        Note: This returns the value that was the fs_flags value returned -from fdstat_get in earlier versions of WASI.

        -
        Params
        - -
        Return values
        - -

        get-type: func

        -

        Get the dynamic type of a descriptor.

        -

        Note: This returns the same value as the type field of the fd-stat -returned by stat, stat-at and similar.

        -

        Note: This returns similar flags to the st_mode & S_IFMT value provided -by fstat in POSIX.

        -

        Note: This returns the value that was the fs_filetype value returned -from fdstat_get in earlier versions of WASI.

        -
        Params
        - -
        Return values
        - -

        set-size: func

        -

        Adjust the size of an open file. If this increases the file's size, the -extra bytes are filled with zeros.

        -

        Note: This was called fd_filestat_set_size in earlier versions of WASI.

        -
        Params
        - -
        Return values
        - -

        set-times: func

        -

        Adjust the timestamps of an open file or directory.

        -

        Note: This is similar to futimens in POSIX.

        -

        Note: This was called fd_filestat_set_times in earlier versions of WASI.

        -
        Params
        - -
        Return values
        - -

        read: func

        -

        Read from a descriptor, without using and updating the descriptor's offset.

        -

        This function returns a list of bytes containing the data that was -read, along with a bool which, when true, indicates that the end of the -file was reached. The returned list will contain up to length bytes; it -may return fewer than requested, if the end of the file is reached or -if the I/O operation is interrupted.

        -

        In the future, this may change to return a stream<u8, error-code>.

        -

        Note: This is similar to pread in POSIX.

        -
        Params
        - -
        Return values
        - -

        write: func

        -

        Write to a descriptor, without using and updating the descriptor's offset.

        -

        It is valid to write past the end of a file; the file is extended to the -extent of the write, with bytes between the previous end and the start of -the write set to zero.

        -

        In the future, this may change to take a stream<u8, error-code>.

        -

        Note: This is similar to pwrite in POSIX.

        -
        Params
        - -
        Return values
        - -

        read-directory: func

        -

        Read directory entries from a directory.

        -

        On filesystems where directories contain entries referring to themselves -and their parents, often named . and .. respectively, these entries -are omitted.

        -

        This always returns a new stream which starts at the beginning of the -directory. Multiple streams may be active on the same directory, and they -do not interfere with each other.

        -
        Params
        - -
        Return values
        - -

        sync: func

        -

        Synchronize the data and metadata of a file to disk.

        -

        This function succeeds with no effect if the file descriptor is not -opened for writing.

        -

        Note: This is similar to fsync in POSIX.

        -
        Params
        - -
        Return values
        - -

        create-directory-at: func

        -

        Create a directory.

        -

        Note: This is similar to mkdirat in POSIX.

        -
        Params
        - -
        Return values
        - -

        stat: func

        -

        Return the attributes of an open file or directory.

        -

        Note: This is similar to fstat in POSIX, except that it does not return -device and inode information. For testing whether two descriptors refer to -the same underlying filesystem object, use is-same-object. To obtain -additional data that can be used do determine whether a file has been -modified, use metadata-hash.

        -

        Note: This was called fd_filestat_get in earlier versions of WASI.

        -
        Params
        - -
        Return values
        - -

        stat-at: func

        -

        Return the attributes of a file or directory.

        -

        Note: This is similar to fstatat in POSIX, except that it does not -return device and inode information. See the stat description for a -discussion of alternatives.

        -

        Note: This was called path_filestat_get in earlier versions of WASI.

        -
        Params
        - -
        Return values
        - -

        set-times-at: func

        -

        Adjust the timestamps of a file or directory.

        -

        Note: This is similar to utimensat in POSIX.

        -

        Note: This was called path_filestat_set_times in earlier versions of -WASI.

        -
        Params
        - -
        Return values
        - -

        link-at: func

        -

        Create a hard link.

        -

        Note: This is similar to linkat in POSIX.

        -
        Params
        - -
        Return values
        - -

        open-at: func

        -

        Open a file or directory.

        -

        The returned descriptor is not guaranteed to be the lowest-numbered -descriptor not currently open/ it is randomized to prevent applications -from depending on making assumptions about indexes, since this is -error-prone in multi-threaded contexts. The returned descriptor is -guaranteed to be less than 2**31.

        -

        If flags contains descriptor-flags::mutate-directory, and the base -descriptor doesn't have descriptor-flags::mutate-directory set, -open-at fails with error-code::read-only.

        -

        If flags contains write or mutate-directory, or open-flags -contains truncate or create, and the base descriptor doesn't have -descriptor-flags::mutate-directory set, open-at fails with -error-code::read-only.

        -

        Note: This is similar to openat in POSIX.

        -
        Params
        - -
        Return values
        - -

        readlink-at: func

        -

        Read the contents of a symbolic link.

        -

        If the contents contain an absolute or rooted path in the underlying -filesystem, this function fails with error-code::not-permitted.

        -

        Note: This is similar to readlinkat in POSIX.

        -
        Params
        - -
        Return values
        - -

        remove-directory-at: func

        -

        Remove a directory.

        -

        Return error-code::not-empty if the directory is not empty.

        -

        Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

        -
        Params
        - -
        Return values
        - -

        rename-at: func

        -

        Rename a filesystem object.

        -

        Note: This is similar to renameat in POSIX.

        -
        Params
        - -
        Return values
        - -

        symlink-at: func

        -

        Create a symbolic link (also known as a "symlink").

        -

        If old-path starts with /, the function fails with -error-code::not-permitted.

        -

        Note: This is similar to symlinkat in POSIX.

        -
        Params
        - -
        Return values
        - -

        access-at: func

        -

        Check accessibility of a filesystem path.

        -

        Check whether the given filesystem path names an object which is -readable, writable, or executable, or whether it exists.

        -

        This does not a guarantee that subsequent accesses will succeed, as -filesystem permissions may be modified asynchronously by external -entities.

        -

        Note: This is similar to faccessat with the AT_EACCESS flag in POSIX.

        -
        Params
        - -
        Return values
        - -

        unlink-file-at: func

        -

        Unlink a filesystem object that is not a directory.

        -

        Return error-code::is-directory if the path refers to a directory. -Note: This is similar to unlinkat(fd, path, 0) in POSIX.

        -
        Params
        - -
        Return values
        - -

        change-file-permissions-at: func

        -

        Change the permissions of a filesystem object that is not a directory.

        -

        Note that the ultimate meanings of these permissions is -filesystem-specific.

        -

        Note: This is similar to fchmodat in POSIX.

        -
        Params
        - -
        Return values
        - -

        change-directory-permissions-at: func

        -

        Change the permissions of a directory.

        -

        Note that the ultimate meanings of these permissions is -filesystem-specific.

        -

        Unlike in POSIX, the executable flag is not reinterpreted as a "search" -flag. read on a directory implies readability and searchability, and -execute is not valid for directories.

        -

        Note: This is similar to fchmodat in POSIX.

        -
        Params
        - -
        Return values
        - -

        lock-shared: func

        -

        Request a shared advisory lock for an open file.

        -

        This requests a shared lock; more than one shared lock can be held for -a file at the same time.

        -

        If the open file has an exclusive lock, this function downgrades the lock -to a shared lock. If it has a shared lock, this function has no effect.

        -

        This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

        -

        It is unspecified how shared locks interact with locks acquired by -non-WASI programs.

        -

        This function blocks until the lock can be acquired.

        -

        Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

        -

        Note: This is similar to flock(fd, LOCK_SH) in Unix.

        -
        Params
        - -
        Return values
        - -

        lock-exclusive: func

        -

        Request an exclusive advisory lock for an open file.

        -

        This requests an exclusive lock; no other locks may be held for the -file while an exclusive lock is held.

        -

        If the open file has a shared lock and there are no exclusive locks held -for the file, this function upgrades the lock to an exclusive lock. If the -open file already has an exclusive lock, this function has no effect.

        -

        This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

        -

        It is unspecified whether this function succeeds if the file descriptor -is not opened for writing. It is unspecified how exclusive locks interact -with locks acquired by non-WASI programs.

        -

        This function blocks until the lock can be acquired.

        -

        Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

        -

        Note: This is similar to flock(fd, LOCK_EX) in Unix.

        -
        Params
        - -
        Return values
        - -

        try-lock-shared: func

        -

        Request a shared advisory lock for an open file.

        -

        This requests a shared lock; more than one shared lock can be held for -a file at the same time.

        -

        If the open file has an exclusive lock, this function downgrades the lock -to a shared lock. If it has a shared lock, this function has no effect.

        -

        This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

        -

        It is unspecified how shared locks interact with locks acquired by -non-WASI programs.

        -

        This function returns error-code::would-block if the lock cannot be -acquired.

        -

        Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

        -

        Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

        -
        Params
        - -
        Return values
        - -

        try-lock-exclusive: func

        -

        Request an exclusive advisory lock for an open file.

        -

        This requests an exclusive lock; no other locks may be held for the -file while an exclusive lock is held.

        -

        If the open file has a shared lock and there are no exclusive locks held -for the file, this function upgrades the lock to an exclusive lock. If the -open file already has an exclusive lock, this function has no effect.

        -

        This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

        -

        It is unspecified whether this function succeeds if the file descriptor -is not opened for writing. It is unspecified how exclusive locks interact -with locks acquired by non-WASI programs.

        -

        This function returns error-code::would-block if the lock cannot be -acquired.

        -

        Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

        -

        Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

        -
        Params
        - -
        Return values
        - -

        unlock: func

        -

        Release a shared or exclusive lock on an open file.

        -

        Note: This is similar to flock(fd, LOCK_UN) in Unix.

        -
        Params
        - -
        Return values
        - -

        drop-descriptor: func

        -

        Dispose of the specified descriptor, after which it may no longer -be used.

        -
        Params
        - -

        read-directory-entry: func

        -

        Read a single directory entry from a directory-entry-stream.

        -
        Params
        - -
        Return values
        - -

        drop-directory-entry-stream: func

        -

        Dispose of the specified directory-entry-stream, after which it may no longer -be used.

        -
        Params
        - -

        is-same-object: func

        -

        Test whether two descriptors refer to the same filesystem object.

        -

        In POSIX, this corresponds to testing whether the two descriptors have the -same device (st_dev) and inode (st_ino or d_ino) numbers. -wasi-filesystem does not expose device and inode numbers, so this function -may be used instead.

        -
        Params
        - -
        Return values
        -
          -
        • bool
        • -
        -

        metadata-hash: func

        -

        Return a hash of the metadata associated with a filesystem object referred -to by a descriptor.

        -

        This returns a hash of the last-modification timestamp and file size, and -may also include the inode number, device number, birth timestamp, and -other metadata fields that may change when the file is modified or -replaced. It may also include a secret value chosen by the -implementation and not otherwise exposed.

        -

        Implementations are encourated to provide the following properties:

        -
          -
        • If the file is not modified or replaced, the computed hash value should -usually not change.
        • -
        • If the object is modified or replaced, the computed hash value should -usually change.
        • -
        • The inputs to the hash should not be easily computable from the -computed hash.
        • -
        -

        However, none of these is required.

        -
        Params
        - -
        Return values
        - -

        metadata-hash-at: func

        -

        Return a hash of the metadata associated with a filesystem object referred -to by a directory descriptor and a relative path.

        -

        This performs the same hash computation as metadata-hash.

        -
        Params
        - -
        Return values
        - -

        Import interface wasi:filesystem/preopens

        -
        -

        Types

        -

        type descriptor

        -

        descriptor

        -

        ----- -

        Functions

        -

        get-directories: func

        -

        Return the set of preopened directories, and their path.

        -
        Return values
        - diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md new file mode 100644 index 000000000..d5aab02e7 --- /dev/null +++ b/proposals/filesystem/imports.md @@ -0,0 +1,1495 @@ +

        World imports

        + +

        Import interface wasi:io/poll

        +

        A poll API intended to let users wait for I/O events on multiple handles +at once.

        +
        +

        Types

        +

        resource pollable

        +
        +

        Functions

        +

        poll-list: func

        +

        Poll for completion on a set of pollables.

        +

        This function takes a list of pollables, which identify I/O sources of +interest, and waits until one or more of the events is ready for I/O.

        +

        The result list<u32> contains one or more indices of handles in the +argument list that is ready for I/O.

        +

        If the list contains more elements than can be indexed with a u32 +value, this function traps.

        +

        A timeout can be implemented by adding a pollable from the +wasi-clocks API to the list.

        +

        This function does not return a result; polling in itself does not +do any I/O so it doesn't fail. If any of the I/O sources identified by +the pollables has an error, it is indicated by marking the source as +being reaedy for I/O.

        +
        Params
        + +
        Return values
        +
          +
        • list<u32>
        • +
        +

        poll-one: func

        +

        Poll for completion on a single pollable.

        +

        This function is similar to poll-list, but operates on only a single +pollable. When it returns, the handle is ready for I/O.

        +
        Params
        + +

        Import interface wasi:io/streams

        +

        WASI I/O is an I/O abstraction API which is currently focused on providing +stream types.

        +

        In the future, the component model is expected to add built-in stream types; +when it does, they are expected to subsume this API.

        +
        +

        Types

        +

        type pollable

        +

        pollable

        +

        +#### `enum stream-status` +

        Streams provide a sequence of data and then end; once they end, they +no longer provide any further data.

        +

        For example, a stream reading from a file ends when the stream reaches +the end of the file. For another example, a stream reading from a +socket ends when the socket is closed.

        +
        Enum Cases
        +
          +
        • +

          open

          +

          The stream is open and may produce further data. +

        • +
        • +

          ended

          +

          When reading, this indicates that the stream will not produce +further data. +When writing, this indicates that the stream will no longer be read. +Further writes are still permitted. +

        • +
        +

        resource input-stream

        +

        enum write-error

        +

        An error for output-stream operations.

        +

        Contrary to input-streams, a closed output-stream is reported using +an error.

        +
        Enum Cases
        +
          +
        • +

          last-operation-failed

          +

          The last operation (a write or flush) failed before completion. +

        • +
        • +

          closed

          +

          The stream is closed: no more input will be accepted by the +stream. A closed output-stream will return this error on all +future operations. +

        • +
        +

        resource output-stream

        +
        +

        Functions

        +

        [method]input-stream.read: func

        +

        Perform a non-blocking read from the stream.

        +

        This function returns a list of bytes containing the data that was +read, along with a stream-status which, indicates whether further +reads are expected to produce data. The returned list will contain up to +len bytes; it may return fewer than requested, but not more. An +empty list and stream-status:open indicates no more data is +available at this time, and that the pollable given by subscribe +will be ready when more data is available.

        +

        Once a stream has reached the end, subsequent calls to read or +skip will always report stream-status:ended rather than producing more +data.

        +

        When the caller gives a len of 0, it represents a request to read 0 +bytes. This read should always succeed and return an empty list and +the current stream-status.

        +

        The len parameter is a u64, which could represent a list of u8 which +is not possible to allocate in wasm32, or not desirable to allocate as +as a return value by the callee. The callee may return a list of bytes +less than len in size while more bytes are available for reading.

        +
        Params
        + +
        Return values
        + +

        [method]input-stream.blocking-read: func

        +

        Read bytes from a stream, after blocking until at least one byte can +be read. Except for blocking, identical to read.

        +
        Params
        + +
        Return values
        + +

        [method]input-stream.skip: func

        +

        Skip bytes from a stream.

        +

        This is similar to the read function, but avoids copying the +bytes into the instance.

        +

        Once a stream has reached the end, subsequent calls to read or +skip will always report end-of-stream rather than producing more +data.

        +

        This function returns the number of bytes skipped, along with a +stream-status indicating whether the end of the stream was +reached. The returned value will be at most len; it may be less.

        +
        Params
        + +
        Return values
        + +

        [method]input-stream.blocking-skip: func

        +

        Skip bytes from a stream, after blocking until at least one byte +can be skipped. Except for blocking behavior, identical to skip.

        +
        Params
        + +
        Return values
        + +

        [method]input-stream.subscribe: func

        +

        Create a pollable which will resolve once either the specified stream +has bytes available to read or the other end of the stream has been +closed. +The created pollable is a child resource of the input-stream. +Implementations may trap if the input-stream is dropped before +all derived pollables created with this function are dropped.

        +
        Params
        + +
        Return values
        + +

        [method]output-stream.check-write: func

        +

        Check readiness for writing. This function never blocks.

        +

        Returns the number of bytes permitted for the next call to write, +or an error. Calling write with more bytes than this function has +permitted will trap.

        +

        When this function returns 0 bytes, the subscribe pollable will +become ready when this function will report at least 1 byte, or an +error.

        +
        Params
        + +
        Return values
        + +

        [method]output-stream.write: func

        +

        Perform a write. This function never blocks.

        +

        Precondition: check-write gave permit of Ok(n) and contents has a +length of less than or equal to n. Otherwise, this function will trap.

        +

        returns Err(closed) without writing if the stream has closed since +the last call to check-write provided a permit.

        +
        Params
        + +
        Return values
        + +

        [method]output-stream.blocking-write-and-flush: func

        +

        Perform a write of up to 4096 bytes, and then flush the stream. Block +until all of these operations are complete, or an error occurs.

        +

        This is a convenience wrapper around the use of check-write, +subscribe, write, and flush, and is implemented with the +following pseudo-code:

        +
        let pollable = this.subscribe();
        +while !contents.is_empty() {
        +  // Wait for the stream to become writable
        +  poll-one(pollable);
        +  let Ok(n) = this.check-write(); // eliding error handling
        +  let len = min(n, contents.len());
        +  let (chunk, rest) = contents.split_at(len);
        +  this.write(chunk  );            // eliding error handling
        +  contents = rest;
        +}
        +this.flush();
        +// Wait for completion of `flush`
        +poll-one(pollable);
        +// Check for any errors that arose during `flush`
        +let _ = this.check-write();         // eliding error handling
        +
        +
        Params
        + +
        Return values
        + +

        [method]output-stream.flush: func

        +

        Request to flush buffered output. This function never blocks.

        +

        This tells the output-stream that the caller intends any buffered +output to be flushed. the output which is expected to be flushed +is all that has been passed to write prior to this call.

        +

        Upon calling this function, the output-stream will not accept any +writes (check-write will return ok(0)) until the flush has +completed. The subscribe pollable will become ready when the +flush has completed and the stream can accept more writes.

        +
        Params
        + +
        Return values
        + +

        [method]output-stream.blocking-flush: func

        +

        Request to flush buffered output, and block until flush completes +and stream is ready for writing again.

        +
        Params
        + +
        Return values
        + +

        [method]output-stream.subscribe: func

        +

        Create a pollable which will resolve once the output-stream +is ready for more writing, or an error has occured. When this +pollable is ready, check-write will return ok(n) with n>0, or an +error.

        +

        If the stream is closed, this pollable is always ready immediately.

        +

        The created pollable is a child resource of the output-stream. +Implementations may trap if the output-stream is dropped before +all derived pollables created with this function are dropped.

        +
        Params
        + +
        Return values
        + +

        [method]output-stream.write-zeroes: func

        +

        Write zeroes to a stream.

        +

        this should be used precisely like write with the exact same +preconditions (must use check-write first), but instead of +passing a list of bytes, you simply pass the number of zero-bytes +that should be written.

        +
        Params
        + +
        Return values
        + +

        [method]output-stream.blocking-write-zeroes-and-flush: func

        +

        Perform a write of up to 4096 zeroes, and then flush the stream. +Block until all of these operations are complete, or an error +occurs.

        +

        This is a convenience wrapper around the use of check-write, +subscribe, write-zeroes, and flush, and is implemented with +the following pseudo-code:

        +
        let pollable = this.subscribe();
        +while num_zeroes != 0 {
        +  // Wait for the stream to become writable
        +  poll-one(pollable);
        +  let Ok(n) = this.check-write(); // eliding error handling
        +  let len = min(n, num_zeroes);
        +  this.write-zeroes(len);         // eliding error handling
        +  num_zeroes -= len;
        +}
        +this.flush();
        +// Wait for completion of `flush`
        +poll-one(pollable);
        +// Check for any errors that arose during `flush`
        +let _ = this.check-write();         // eliding error handling
        +
        +
        Params
        + +
        Return values
        + +

        [method]output-stream.splice: func

        +

        Read from one stream and write to another.

        +

        This function returns the number of bytes transferred; it may be less +than len.

        +

        Unlike other I/O functions, this function blocks until all the data +read from the input stream has been written to the output stream.

        +
        Params
        + +
        Return values
        + +

        [method]output-stream.blocking-splice: func

        +

        Read from one stream and write to another, with blocking.

        +

        This is similar to splice, except that it blocks until at least +one byte can be read.

        +
        Params
        + +
        Return values
        + +

        [method]output-stream.forward: func

        +

        Forward the entire contents of an input stream to an output stream.

        +

        This function repeatedly reads from the input stream and writes +the data to the output stream, until the end of the input stream +is reached, or an error is encountered.

        +

        Unlike other I/O functions, this function blocks until the end +of the input stream is seen and all the data has been written to +the output stream.

        +

        This function returns the number of bytes transferred, and the status of +the output stream.

        +
        Params
        + +
        Return values
        + +

        Import interface wasi:clocks/wall-clock

        +

        WASI Wall Clock is a clock API intended to let users query the current +time. The name "wall" makes an analogy to a "clock on the wall", which +is not necessarily monotonic as it may be reset.

        +

        It is intended to be portable at least between Unix-family platforms and +Windows.

        +

        A wall clock is a clock which measures the date and time according to +some external reference.

        +

        External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time.

        +

        It is intended for reporting the current date and time for humans.

        +
        +

        Types

        +

        record datetime

        +

        A time and date in seconds plus nanoseconds.

        +
        Record Fields
        + +
        +

        Functions

        +

        now: func

        +

        Read the current value of the clock.

        +

        This clock is not monotonic, therefore calling this function repeatedly +will not necessarily produce a sequence of non-decreasing values.

        +

        The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, +also known as Unix Time.

        +

        The nanoseconds field of the output is always less than 1000000000.

        +
        Return values
        + +

        resolution: func

        +

        Query the resolution of the clock.

        +

        The nanoseconds field of the output is always less than 1000000000.

        +
        Return values
        + +

        Import interface wasi:filesystem/types

        +

        WASI filesystem is a filesystem API primarily intended to let users run WASI +programs that access their files on their existing filesystems, without +significant overhead.

        +

        It is intended to be roughly portable between Unix-family platforms and +Windows, though it does not hide many of the major differences.

        +

        Paths are passed as interface-type strings, meaning they must consist of +a sequence of Unicode Scalar Values (USVs). Some filesystems may contain +paths which are not accessible by this API.

        +

        The directory separator in WASI is always the forward-slash (/).

        +

        All paths in WASI are relative paths, and are interpreted relative to a +descriptor referring to a base directory. If a path argument to any WASI +function starts with /, or if any step of resolving a path, including +.. and symbolic link steps, reaches a directory outside of the base +directory, or reaches a symlink to an absolute or rooted path in the +underlying filesystem, the function fails with error-code::not-permitted.

        +

        For more information about WASI path resolution and sandboxing, see +WASI filesystem path resolution.

        +
        +

        Types

        +

        type input-stream

        +

        input-stream

        +

        +#### `type output-stream` +[`output-stream`](#output_stream) +

        +#### `type datetime` +[`datetime`](#datetime) +

        +#### `type filesize` +`u64` +

        File size or length of a region within a file. +

        enum descriptor-type

        +

        The type of a filesystem object referenced by a descriptor.

        +

        Note: This was called filetype in earlier versions of WASI.

        +
        Enum Cases
        +
          +
        • +

          unknown

          +

          The type of the descriptor or file is unknown or is different from +any of the other types specified. +

        • +
        • +

          block-device

          +

          The descriptor refers to a block device inode. +

        • +
        • +

          character-device

          +

          The descriptor refers to a character device inode. +

        • +
        • +

          directory

          +

          The descriptor refers to a directory inode. +

        • +
        • +

          fifo

          +

          The descriptor refers to a named pipe. +

        • +
        • +

          symbolic-link

          +

          The file refers to a symbolic link inode. +

        • +
        • +

          regular-file

          +

          The descriptor refers to a regular file inode. +

        • +
        • +

          socket

          +

          The descriptor refers to a socket. +

        • +
        +

        flags descriptor-flags

        +

        Descriptor flags.

        +

        Note: This was called fdflags in earlier versions of WASI.

        +
        Flags members
        +
          +
        • +

          read:

          +

          Read mode: Data can be read. +

        • +
        • +

          write:

          +

          Write mode: Data can be written to. +

        • +
        • +

          file-integrity-sync:

          +

          Request that writes be performed according to synchronized I/O file +integrity completion. The data stored in the file and the file's +metadata are synchronized. This is similar to `O_SYNC` in POSIX. +

          The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

          +
        • +
        • +

          data-integrity-sync:

          +

          Request that writes be performed according to synchronized I/O data +integrity completion. Only the data stored in the file is +synchronized. This is similar to `O_DSYNC` in POSIX. +

          The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

          +
        • +
        • +

          requested-write-sync:

          +

          Requests that reads be performed at the same level of integrety +requested for writes. This is similar to `O_RSYNC` in POSIX. +

          The precise semantics of this operation have not yet been defined for +WASI. At this time, it should be interpreted as a request, and not a +requirement.

          +
        • +
        • +

          mutate-directory:

          +

          Mutating directories mode: Directory contents may be mutated. +

          When this flag is unset on a descriptor, operations using the +descriptor which would create, rename, delete, modify the data or +metadata of filesystem objects, or obtain another handle which +would permit any of those, shall fail with error-code::read-only if +they would otherwise succeed.

          +

          This may only be set on directories.

          +
        • +
        +

        flags path-flags

        +

        Flags determining the method of how paths are resolved.

        +
        Flags members
        +
          +
        • symlink-follow:

          As long as the resolved path corresponds to a symbolic link, it is +expanded. +

        • +
        +

        flags open-flags

        +

        Open flags used by open-at.

        +
        Flags members
        +
          +
        • +

          create:

          +

          Create file if it does not exist, similar to `O_CREAT` in POSIX. +

        • +
        • +

          directory:

          +

          Fail if not a directory, similar to `O_DIRECTORY` in POSIX. +

        • +
        • +

          exclusive:

          +

          Fail if file already exists, similar to `O_EXCL` in POSIX. +

        • +
        • +

          truncate:

          +

          Truncate file to size 0, similar to `O_TRUNC` in POSIX. +

        • +
        +

        flags modes

        +

        Permissions mode used by open-at, change-file-permissions-at, and +similar.

        +
        Flags members
        +
          +
        • +

          readable:

          +

          True if the resource is considered readable by the containing +filesystem. +

        • +
        • +

          writable:

          +

          True if the resource is considered writable by the containing +filesystem. +

        • +
        • +

          executable:

          +

          True if the resource is considered executable by the containing +filesystem. This does not apply to directories. +

        • +
        +

        variant access-type

        +

        Access type used by access-at.

        +
        Variant Cases
        +
          +
        • +

          access: modes

          +

          Test for readability, writeability, or executability. +

        • +
        • +

          exists

          +

          Test whether the path exists. +

        • +
        +

        type link-count

        +

        u64

        +

        Number of hard links to an inode. +

        record descriptor-stat

        +

        File attributes.

        +

        Note: This was called filestat in earlier versions of WASI.

        +
        Record Fields
        +
          +
        • +

          type: descriptor-type

          +

          File type. +

        • +
        • +

          link-count: link-count

          +

          Number of hard links to the file. +

        • +
        • +

          size: filesize

          +

          For regular files, the file size in bytes. For symbolic links, the +length in bytes of the pathname contained in the symbolic link. +

        • +
        • +

          data-access-timestamp: option<datetime>

          +

          Last data access timestamp. +

          If the option is none, the platform doesn't maintain an access +timestamp for this file.

          +
        • +
        • +

          data-modification-timestamp: option<datetime>

          +

          Last data modification timestamp. +

          If the option is none, the platform doesn't maintain a +modification timestamp for this file.

          +
        • +
        • +

          status-change-timestamp: option<datetime>

          +

          Last file status-change timestamp. +

          If the option is none, the platform doesn't maintain a +status-change timestamp for this file.

          +
        • +
        +

        variant new-timestamp

        +

        When setting a timestamp, this gives the value to set it to.

        +
        Variant Cases
        +
          +
        • +

          no-change

          +

          Leave the timestamp set to its previous value. +

        • +
        • +

          now

          +

          Set the timestamp to the current time of the system clock associated +with the filesystem. +

        • +
        • +

          timestamp: datetime

          +

          Set the timestamp to the given value. +

        • +
        +

        record directory-entry

        +

        A directory entry.

        +
        Record Fields
        +
          +
        • +

          type: descriptor-type

          +

          The type of the file referred to by this directory entry. +

        • +
        • +

          name: string

          +

          The name of the object. +

        • +
        +

        enum error-code

        +

        Error codes returned by functions, similar to errno in POSIX. +Not all of these error codes are returned by the functions provided by this +API; some are used in higher-level library layers, and others are provided +merely for alignment with POSIX.

        +
        Enum Cases
        +
          +
        • +

          access

          +

          Permission denied, similar to `EACCES` in POSIX. +

        • +
        • +

          would-block

          +

          Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. +

        • +
        • +

          already

          +

          Connection already in progress, similar to `EALREADY` in POSIX. +

        • +
        • +

          bad-descriptor

          +

          Bad descriptor, similar to `EBADF` in POSIX. +

        • +
        • +

          busy

          +

          Device or resource busy, similar to `EBUSY` in POSIX. +

        • +
        • +

          deadlock

          +

          Resource deadlock would occur, similar to `EDEADLK` in POSIX. +

        • +
        • +

          quota

          +

          Storage quota exceeded, similar to `EDQUOT` in POSIX. +

        • +
        • +

          exist

          +

          File exists, similar to `EEXIST` in POSIX. +

        • +
        • +

          file-too-large

          +

          File too large, similar to `EFBIG` in POSIX. +

        • +
        • +

          illegal-byte-sequence

          +

          Illegal byte sequence, similar to `EILSEQ` in POSIX. +

        • +
        • +

          in-progress

          +

          Operation in progress, similar to `EINPROGRESS` in POSIX. +

        • +
        • +

          interrupted

          +

          Interrupted function, similar to `EINTR` in POSIX. +

        • +
        • +

          invalid

          +

          Invalid argument, similar to `EINVAL` in POSIX. +

        • +
        • +

          io

          +

          I/O error, similar to `EIO` in POSIX. +

        • +
        • +

          is-directory

          +

          Is a directory, similar to `EISDIR` in POSIX. +

        • +
        • +

          loop

          +

          Too many levels of symbolic links, similar to `ELOOP` in POSIX. +

        • +
        • +

          too-many-links

          +

          Too many links, similar to `EMLINK` in POSIX. +

        • +
        • +

          message-size

          +

          Message too large, similar to `EMSGSIZE` in POSIX. +

        • +
        • +

          name-too-long

          +

          Filename too long, similar to `ENAMETOOLONG` in POSIX. +

        • +
        • +

          no-device

          +

          No such device, similar to `ENODEV` in POSIX. +

        • +
        • +

          no-entry

          +

          No such file or directory, similar to `ENOENT` in POSIX. +

        • +
        • +

          no-lock

          +

          No locks available, similar to `ENOLCK` in POSIX. +

        • +
        • +

          insufficient-memory

          +

          Not enough space, similar to `ENOMEM` in POSIX. +

        • +
        • +

          insufficient-space

          +

          No space left on device, similar to `ENOSPC` in POSIX. +

        • +
        • +

          not-directory

          +

          Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. +

        • +
        • +

          not-empty

          +

          Directory not empty, similar to `ENOTEMPTY` in POSIX. +

        • +
        • +

          not-recoverable

          +

          State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. +

        • +
        • +

          unsupported

          +

          Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. +

        • +
        • +

          no-tty

          +

          Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. +

        • +
        • +

          no-such-device

          +

          No such device or address, similar to `ENXIO` in POSIX. +

        • +
        • +

          overflow

          +

          Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. +

        • +
        • +

          not-permitted

          +

          Operation not permitted, similar to `EPERM` in POSIX. +

        • +
        • +

          pipe

          +

          Broken pipe, similar to `EPIPE` in POSIX. +

        • +
        • +

          read-only

          +

          Read-only file system, similar to `EROFS` in POSIX. +

        • +
        • +

          invalid-seek

          +

          Invalid seek, similar to `ESPIPE` in POSIX. +

        • +
        • +

          text-file-busy

          +

          Text file busy, similar to `ETXTBSY` in POSIX. +

        • +
        • +

          cross-device

          +

          Cross-device link, similar to `EXDEV` in POSIX. +

        • +
        +

        enum advice

        +

        File or memory access pattern advisory information.

        +
        Enum Cases
        +
          +
        • +

          normal

          +

          The application has no advice to give on its behavior with respect +to the specified data. +

        • +
        • +

          sequential

          +

          The application expects to access the specified data sequentially +from lower offsets to higher offsets. +

        • +
        • +

          random

          +

          The application expects to access the specified data in a random +order. +

        • +
        • +

          will-need

          +

          The application expects to access the specified data in the near +future. +

        • +
        • +

          dont-need

          +

          The application expects that it will not access the specified data +in the near future. +

        • +
        • +

          no-reuse

          +

          The application expects to access the specified data once and then +not reuse it thereafter. +

        • +
        +

        record metadata-hash-value

        +

        A 128-bit hash value, split into parts because wasm doesn't have a +128-bit integer type.

        +
        Record Fields
        +
          +
        • +

          lower: u64

          +

          64 bits of a 128-bit hash value. +

        • +
        • +

          upper: u64

          +

          Another 64 bits of a 128-bit hash value. +

        • +
        +

        resource descriptor

        +

        resource directory-entry-stream

        +
        +

        Functions

        +

        [method]descriptor.read-via-stream: func

        +

        Return a stream for reading from a file, if available.

        +

        May fail with an error-code describing why the file cannot be read.

        +

        Multiple read, write, and append streams may be active on the same open +file and they do not interfere with each other.

        +

        Note: This allows using read-stream, which is similar to read in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.write-via-stream: func

        +

        Return a stream for writing to a file, if available.

        +

        May fail with an error-code describing why the file cannot be written.

        +

        Note: This allows using write-stream, which is similar to write in +POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.append-via-stream: func

        +

        Return a stream for appending to a file, if available.

        +

        May fail with an error-code describing why the file cannot be appended.

        +

        Note: This allows using write-stream, which is similar to write with +O_APPEND in in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.advise: func

        +

        Provide file advisory information on a descriptor.

        +

        This is similar to posix_fadvise in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.sync-data: func

        +

        Synchronize the data of a file to disk.

        +

        This function succeeds with no effect if the file descriptor is not +opened for writing.

        +

        Note: This is similar to fdatasync in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.get-flags: func

        +

        Get flags associated with a descriptor.

        +

        Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

        +

        Note: This returns the value that was the fs_flags value returned +from fdstat_get in earlier versions of WASI.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.get-type: func

        +

        Get the dynamic type of a descriptor.

        +

        Note: This returns the same value as the type field of the fd-stat +returned by stat, stat-at and similar.

        +

        Note: This returns similar flags to the st_mode & S_IFMT value provided +by fstat in POSIX.

        +

        Note: This returns the value that was the fs_filetype value returned +from fdstat_get in earlier versions of WASI.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.set-size: func

        +

        Adjust the size of an open file. If this increases the file's size, the +extra bytes are filled with zeros.

        +

        Note: This was called fd_filestat_set_size in earlier versions of WASI.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.set-times: func

        +

        Adjust the timestamps of an open file or directory.

        +

        Note: This is similar to futimens in POSIX.

        +

        Note: This was called fd_filestat_set_times in earlier versions of WASI.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.read: func

        +

        Read from a descriptor, without using and updating the descriptor's offset.

        +

        This function returns a list of bytes containing the data that was +read, along with a bool which, when true, indicates that the end of the +file was reached. The returned list will contain up to length bytes; it +may return fewer than requested, if the end of the file is reached or +if the I/O operation is interrupted.

        +

        In the future, this may change to return a stream<u8, error-code>.

        +

        Note: This is similar to pread in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.write: func

        +

        Write to a descriptor, without using and updating the descriptor's offset.

        +

        It is valid to write past the end of a file; the file is extended to the +extent of the write, with bytes between the previous end and the start of +the write set to zero.

        +

        In the future, this may change to take a stream<u8, error-code>.

        +

        Note: This is similar to pwrite in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.read-directory: func

        +

        Read directory entries from a directory.

        +

        On filesystems where directories contain entries referring to themselves +and their parents, often named . and .. respectively, these entries +are omitted.

        +

        This always returns a new stream which starts at the beginning of the +directory. Multiple streams may be active on the same directory, and they +do not interfere with each other.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.sync: func

        +

        Synchronize the data and metadata of a file to disk.

        +

        This function succeeds with no effect if the file descriptor is not +opened for writing.

        +

        Note: This is similar to fsync in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.create-directory-at: func

        +

        Create a directory.

        +

        Note: This is similar to mkdirat in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.stat: func

        +

        Return the attributes of an open file or directory.

        +

        Note: This is similar to fstat in POSIX, except that it does not return +device and inode information. For testing whether two descriptors refer to +the same underlying filesystem object, use is-same-object. To obtain +additional data that can be used do determine whether a file has been +modified, use metadata-hash.

        +

        Note: This was called fd_filestat_get in earlier versions of WASI.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.stat-at: func

        +

        Return the attributes of a file or directory.

        +

        Note: This is similar to fstatat in POSIX, except that it does not +return device and inode information. See the stat description for a +discussion of alternatives.

        +

        Note: This was called path_filestat_get in earlier versions of WASI.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.set-times-at: func

        +

        Adjust the timestamps of a file or directory.

        +

        Note: This is similar to utimensat in POSIX.

        +

        Note: This was called path_filestat_set_times in earlier versions of +WASI.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.link-at: func

        +

        Create a hard link.

        +

        Note: This is similar to linkat in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.open-at: func

        +

        Open a file or directory.

        +

        The returned descriptor is not guaranteed to be the lowest-numbered +descriptor not currently open/ it is randomized to prevent applications +from depending on making assumptions about indexes, since this is +error-prone in multi-threaded contexts. The returned descriptor is +guaranteed to be less than 2**31.

        +

        If flags contains descriptor-flags::mutate-directory, and the base +descriptor doesn't have descriptor-flags::mutate-directory set, +open-at fails with error-code::read-only.

        +

        If flags contains write or mutate-directory, or open-flags +contains truncate or create, and the base descriptor doesn't have +descriptor-flags::mutate-directory set, open-at fails with +error-code::read-only.

        +

        Note: This is similar to openat in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.readlink-at: func

        +

        Read the contents of a symbolic link.

        +

        If the contents contain an absolute or rooted path in the underlying +filesystem, this function fails with error-code::not-permitted.

        +

        Note: This is similar to readlinkat in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.remove-directory-at: func

        +

        Remove a directory.

        +

        Return error-code::not-empty if the directory is not empty.

        +

        Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.rename-at: func

        +

        Rename a filesystem object.

        +

        Note: This is similar to renameat in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.symlink-at: func

        +

        Create a symbolic link (also known as a "symlink").

        +

        If old-path starts with /, the function fails with +error-code::not-permitted.

        +

        Note: This is similar to symlinkat in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.access-at: func

        +

        Check accessibility of a filesystem path.

        +

        Check whether the given filesystem path names an object which is +readable, writable, or executable, or whether it exists.

        +

        This does not a guarantee that subsequent accesses will succeed, as +filesystem permissions may be modified asynchronously by external +entities.

        +

        Note: This is similar to faccessat with the AT_EACCESS flag in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.unlink-file-at: func

        +

        Unlink a filesystem object that is not a directory.

        +

        Return error-code::is-directory if the path refers to a directory. +Note: This is similar to unlinkat(fd, path, 0) in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.change-file-permissions-at: func

        +

        Change the permissions of a filesystem object that is not a directory.

        +

        Note that the ultimate meanings of these permissions is +filesystem-specific.

        +

        Note: This is similar to fchmodat in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.change-directory-permissions-at: func

        +

        Change the permissions of a directory.

        +

        Note that the ultimate meanings of these permissions is +filesystem-specific.

        +

        Unlike in POSIX, the executable flag is not reinterpreted as a "search" +flag. read on a directory implies readability and searchability, and +execute is not valid for directories.

        +

        Note: This is similar to fchmodat in POSIX.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.lock-shared: func

        +

        Request a shared advisory lock for an open file.

        +

        This requests a shared lock; more than one shared lock can be held for +a file at the same time.

        +

        If the open file has an exclusive lock, this function downgrades the lock +to a shared lock. If it has a shared lock, this function has no effect.

        +

        This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

        +

        It is unspecified how shared locks interact with locks acquired by +non-WASI programs.

        +

        This function blocks until the lock can be acquired.

        +

        Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

        +

        Note: This is similar to flock(fd, LOCK_SH) in Unix.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.lock-exclusive: func

        +

        Request an exclusive advisory lock for an open file.

        +

        This requests an exclusive lock; no other locks may be held for the +file while an exclusive lock is held.

        +

        If the open file has a shared lock and there are no exclusive locks held +for the file, this function upgrades the lock to an exclusive lock. If the +open file already has an exclusive lock, this function has no effect.

        +

        This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

        +

        It is unspecified whether this function succeeds if the file descriptor +is not opened for writing. It is unspecified how exclusive locks interact +with locks acquired by non-WASI programs.

        +

        This function blocks until the lock can be acquired.

        +

        Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

        +

        Note: This is similar to flock(fd, LOCK_EX) in Unix.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.try-lock-shared: func

        +

        Request a shared advisory lock for an open file.

        +

        This requests a shared lock; more than one shared lock can be held for +a file at the same time.

        +

        If the open file has an exclusive lock, this function downgrades the lock +to a shared lock. If it has a shared lock, this function has no effect.

        +

        This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

        +

        It is unspecified how shared locks interact with locks acquired by +non-WASI programs.

        +

        This function returns error-code::would-block if the lock cannot be +acquired.

        +

        Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

        +

        Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.try-lock-exclusive: func

        +

        Request an exclusive advisory lock for an open file.

        +

        This requests an exclusive lock; no other locks may be held for the +file while an exclusive lock is held.

        +

        If the open file has a shared lock and there are no exclusive locks held +for the file, this function upgrades the lock to an exclusive lock. If the +open file already has an exclusive lock, this function has no effect.

        +

        This requests an advisory lock, meaning that the file could be accessed +by other programs that don't hold the lock.

        +

        It is unspecified whether this function succeeds if the file descriptor +is not opened for writing. It is unspecified how exclusive locks interact +with locks acquired by non-WASI programs.

        +

        This function returns error-code::would-block if the lock cannot be +acquired.

        +

        Not all filesystems support locking; on filesystems which don't support +locking, this function returns error-code::unsupported.

        +

        Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.unlock: func

        +

        Release a shared or exclusive lock on an open file.

        +

        Note: This is similar to flock(fd, LOCK_UN) in Unix.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.is-same-object: func

        +

        Test whether two descriptors refer to the same filesystem object.

        +

        In POSIX, this corresponds to testing whether the two descriptors have the +same device (st_dev) and inode (st_ino or d_ino) numbers. +wasi-filesystem does not expose device and inode numbers, so this function +may be used instead.

        +
        Params
        + +
        Return values
        +
          +
        • bool
        • +
        +

        [method]descriptor.metadata-hash: func

        +

        Return a hash of the metadata associated with a filesystem object referred +to by a descriptor.

        +

        This returns a hash of the last-modification timestamp and file size, and +may also include the inode number, device number, birth timestamp, and +other metadata fields that may change when the file is modified or +replaced. It may also include a secret value chosen by the +implementation and not otherwise exposed.

        +

        Implementations are encourated to provide the following properties:

        +
          +
        • If the file is not modified or replaced, the computed hash value should +usually not change.
        • +
        • If the object is modified or replaced, the computed hash value should +usually change.
        • +
        • The inputs to the hash should not be easily computable from the +computed hash.
        • +
        +

        However, none of these is required.

        +
        Params
        + +
        Return values
        + +

        [method]descriptor.metadata-hash-at: func

        +

        Return a hash of the metadata associated with a filesystem object referred +to by a directory descriptor and a relative path.

        +

        This performs the same hash computation as metadata-hash.

        +
        Params
        + +
        Return values
        + +

        [method]directory-entry-stream.read-directory-entry: func

        +

        Read a single directory entry from a directory-entry-stream.

        +
        Params
        + +
        Return values
        + +

        Import interface wasi:filesystem/preopens

        +
        +

        Types

        +

        type descriptor

        +

        descriptor

        +

        +---- +

        Functions

        +

        get-directories: func

        +

        Return the set of preopened directories, and their path.

        +
        Return values
        + diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index a89146803..319608225 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -1,14 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "1ed7e35b3f9738663854f0dd92a95bfadc410ea07170501f5c2fec0cc24e3d57" -sha512 = "ef1e23704a8a8436fd3718593d4c4d8b6d1c64dad3595b7496c0888ca14b725046f2900109800faca1bc8c14f237cdcaca791dba8284e1ad50105ab2d036825b" +sha256 = "ea955af7a152f85941b651c5b07345c4f077ae7f9e996c909ab8cc0a68c0120e" +sha512 = "114bc4f583a487cf1ccfdd6efa25c4c60cf637d4501a189eebd4b1d52aec2c8eb63ae14ce494db53dfd25bc20f6c4b533dc6f2143537e5cd14ca80d5d4b6a49d" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "a47690f7d4dba1683a42897cc65fe813409827d72cc93afe03b127ee81763e13" -sha512 = "661aa9cf9c67d7d712caccfbb3c317da01b033764892623c8902d9dcfdb67f3088889102b036d3ed19d818a5c2d151247b25d9f6fd145cdf433f325605a5a747" - -[poll] -url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -sha256 = "d4c27124f4c137eb538b5c92ba5858ed9042e11b24a2eef85d14becd0b7f55de" -sha512 = "422c01b273b4b1377ece6f2e4ba0dfc609ca8ef30a3e0be0e172e1303fcf7b3ca4c470f4dea6c51bdf114b0f5c871ebc4934dfe3bf217d66ea689748df2b1e55" +sha256 = "6e20bcf4d4f5466b60c05ea8da7289ca361a7febdd22ab1a531e5ef7e394ab8d" +sha512 = "21f6689bce6ed6d9e3bd96372e5c7ed003a7aefbf8d49b4eea949dfbd265cf57a0d7dc67aa71e3de75d48fcc2c0cfe5f06f7e9e7959a23bc98f77da85f4161b9" diff --git a/proposals/filesystem/wit/deps.toml b/proposals/filesystem/wit/deps.toml index 4e40837d5..6da3b6487 100644 --- a/proposals/filesystem/wit/deps.toml +++ b/proposals/filesystem/wit/deps.toml @@ -1,3 +1,3 @@ +# Temporarily use the resources branches. io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" \ No newline at end of file +clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" diff --git a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit index fb8424eb0..703a5fb7a 100644 --- a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit @@ -9,7 +9,7 @@ /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:poll/poll.{pollable} + use wasi:io/poll.{pollable} /// A timestamp in nanoseconds. type instant = u64 diff --git a/proposals/filesystem/wit/deps/clocks/timezone.wit b/proposals/filesystem/wit/deps/clocks/timezone.wit index 662830871..a872bffc7 100644 --- a/proposals/filesystem/wit/deps/clocks/timezone.wit +++ b/proposals/filesystem/wit/deps/clocks/timezone.wit @@ -1,15 +1,6 @@ interface timezone { use wall-clock.{datetime} - /// A timezone. - /// - /// In timezones that recognize daylight saving time, also known as daylight - /// time and summer time, the information returned from the functions varies - /// over time to reflect these adjustments. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type timezone = u32 - /// Return information needed to display the given `datetime`. This includes /// the UTC offset, the time zone name, and a flag indicating whether /// daylight saving time is active. @@ -17,14 +8,10 @@ interface timezone { /// If the timezone cannot be determined for the given `datetime`, return a /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight /// saving time. - display: func(this: timezone, when: datetime) -> timezone-display + display: func(when: datetime) -> timezone-display /// The same as `display`, but only return the UTC offset. - utc-offset: func(this: timezone, when: datetime) -> s32 - - /// Dispose of the specified input-stream, after which it may no longer - /// be used. - drop-timezone: func(this: timezone) + utc-offset: func(when: datetime) -> s32 /// Information useful for displaying the timezone of a specific `datetime`. /// diff --git a/proposals/filesystem/wit/deps/clocks/world.wit b/proposals/filesystem/wit/deps/clocks/world.wit index 291a9c75e..5c2dd411d 100644 --- a/proposals/filesystem/wit/deps/clocks/world.wit +++ b/proposals/filesystem/wit/deps/clocks/world.wit @@ -1,6 +1,6 @@ package wasi:clocks -world example-world { +world imports { import monotonic-clock import wall-clock import timezone diff --git a/proposals/filesystem/wit/deps/io/poll.wit b/proposals/filesystem/wit/deps/io/poll.wit new file mode 100644 index 000000000..e95762b91 --- /dev/null +++ b/proposals/filesystem/wit/deps/io/poll.wit @@ -0,0 +1,34 @@ +package wasi:io + +/// A poll API intended to let users wait for I/O events on multiple handles +/// at once. +interface poll { + /// A "pollable" handle. + resource pollable + + /// Poll for completion on a set of pollables. + /// + /// This function takes a list of pollables, which identify I/O sources of + /// interest, and waits until one or more of the events is ready for I/O. + /// + /// The result `list` contains one or more indices of handles in the + /// argument list that is ready for I/O. + /// + /// If the list contains more elements than can be indexed with a `u32` + /// value, this function traps. + /// + /// A timeout can be implemented by adding a pollable from the + /// wasi-clocks API to the list. + /// + /// This function does not return a `result`; polling in itself does not + /// do any I/O so it doesn't fail. If any of the I/O sources identified by + /// the pollables has an error, it is indicated by marking the source as + /// being reaedy for I/O. + poll-list: func(in: list>) -> list + + /// Poll for completion on a single pollable. + /// + /// This function is similar to `poll-list`, but operates on only a single + /// pollable. When it returns, the handle is ready for I/O. + poll-one: func(in: borrow) +} diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index 98df181c1..eeeff5058 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -6,7 +6,7 @@ package wasi:io /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { - use wasi:poll/poll.{pollable} + use poll.{pollable} /// Streams provide a sequence of data and then end; once they end, they /// no longer provide any further data. @@ -24,230 +24,262 @@ interface streams { ended, } - /// An input bytestream. In the future, this will be replaced by handle - /// types. + /// An input bytestream. /// /// `input-stream`s are *non-blocking* to the extent practical on underlying /// platforms. I/O operations always return promptly; if fewer bytes are /// promptly available than requested, they return the number of bytes promptly /// available, which could even be zero. To wait for data to be available, - /// use the `subscribe-to-input-stream` function to obtain a `pollable` which - /// can be polled for using `wasi:poll/poll.poll_oneoff`. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type input-stream = u32 + /// use the `subscribe` function to obtain a `pollable` which can be polled + /// for using `wasi:io/poll`. + resource input-stream { + /// Perform a non-blocking read from the stream. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a `stream-status` which, indicates whether further + /// reads are expected to produce data. The returned list will contain up to + /// `len` bytes; it may return fewer than requested, but not more. An + /// empty list and `stream-status:open` indicates no more data is + /// available at this time, and that the pollable given by `subscribe` + /// will be ready when more data is available. + /// + /// Once a stream has reached the end, subsequent calls to `read` or + /// `skip` will always report `stream-status:ended` rather than producing more + /// data. + /// + /// When the caller gives a `len` of 0, it represents a request to read 0 + /// bytes. This read should always succeed and return an empty list and + /// the current `stream-status`. + /// + /// The `len` parameter is a `u64`, which could represent a list of u8 which + /// is not possible to allocate in wasm32, or not desirable to allocate as + /// as a return value by the callee. The callee may return a list of bytes + /// less than `len` in size while more bytes are available for reading. + read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-status>> - /// Perform a non-blocking read from the stream. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a `stream-status` which, indicates whether further - /// reads are expected to produce data. The returned list will contain up to - /// `len` bytes; it may return fewer than requested, but not more. An - /// empty list and `stream-status:open` indicates no more data is - /// available at this time, and that the pollable given by - /// `subscribe-to-input-stream` will be ready when more data is available. - /// - /// Once a stream has reached the end, subsequent calls to `read` or - /// `skip` will always report `stream-status:ended` rather than producing more - /// data. - /// - /// When the caller gives a `len` of 0, it represents a request to read 0 - /// bytes. This read should always succeed and return an empty list and - /// the current `stream-status`. - /// - /// The `len` parameter is a `u64`, which could represent a list of u8 which - /// is not possible to allocate in wasm32, or not desirable to allocate as - /// as a return value by the callee. The callee may return a list of bytes - /// less than `len` in size while more bytes are available for reading. - read: func( - this: input-stream, - /// The maximum number of bytes to read - len: u64 - ) -> result, stream-status>> - - /// Read bytes from a stream, after blocking until at least one byte can - /// be read. Except for blocking, identical to `read`. - blocking-read: func( - this: input-stream, - /// The maximum number of bytes to read - len: u64 - ) -> result, stream-status>> - - /// Skip bytes from a stream. - /// - /// This is similar to the `read` function, but avoids copying the - /// bytes into the instance. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. + /// Read bytes from a stream, after blocking until at least one byte can + /// be read. Except for blocking, identical to `read`. + blocking-read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-status>> + + /// Skip bytes from a stream. + /// + /// This is similar to the `read` function, but avoids copying the + /// bytes into the instance. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// This function returns the number of bytes skipped, along with a + /// `stream-status` indicating whether the end of the stream was + /// reached. The returned value will be at most `len`; it may be less. + skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result> + + /// Skip bytes from a stream, after blocking until at least one byte + /// can be skipped. Except for blocking behavior, identical to `skip`. + blocking-skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result> + + /// Create a `pollable` which will resolve once either the specified stream + /// has bytes available to read or the other end of the stream has been + /// closed. + /// The created `pollable` is a child resource of the `input-stream`. + /// Implementations may trap if the `input-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe: func() -> pollable + } + + /// An error for output-stream operations. /// - /// This function returns the number of bytes skipped, along with a - /// `stream-status` indicating whether the end of the stream was - /// reached. The returned value will be at most `len`; it may be less. - skip: func( - this: input-stream, - /// The maximum number of bytes to skip. - len: u64, - ) -> result> - - /// Skip bytes from a stream, after blocking until at least one byte - /// can be skipped. Except for blocking behavior, identical to `skip`. - blocking-skip: func( - this: input-stream, - /// The maximum number of bytes to skip. - len: u64, - ) -> result> - - /// Create a `pollable` which will resolve once either the specified stream - /// has bytes available to read or the other end of the stream has been - /// closed. - /// The created `pollable` is a child resource of the `input-stream`. - /// Implementations may trap if the `input-stream` is dropped before - /// all derived `pollable`s created with this function are dropped. - subscribe-to-input-stream: func(this: input-stream) -> pollable - - /// Dispose of the specified `input-stream`, after which it may no longer - /// be used. - /// Implementations may trap if this `input-stream` is dropped while child - /// `pollable` resources are still alive. - /// After this `input-stream` is dropped, implementations may report any - /// corresponding `output-stream` has `stream-state.closed`. - drop-input-stream: func(this: input-stream) - - /// An output bytestream. In the future, this will be replaced by handle - /// types. + /// Contrary to input-streams, a closed output-stream is reported using + /// an error. + enum write-error { + /// The last operation (a write or flush) failed before completion. + last-operation-failed, + /// The stream is closed: no more input will be accepted by the + /// stream. A closed output-stream will return this error on all + /// future operations. + closed + } + + /// An output bytestream. /// /// `output-stream`s are *non-blocking* to the extent practical on /// underlying platforms. Except where specified otherwise, I/O operations also /// always return promptly, after the number of bytes that can be written /// promptly, which could even be zero. To wait for the stream to be ready to - /// accept data, the `subscribe-to-output-stream` function to obtain a - /// `pollable` which can be polled for using `wasi:poll`. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type output-stream = u32 + /// accept data, the `subscribe` function to obtain a `pollable` which can be + /// polled for using `wasi:io/poll`. + resource output-stream { + /// Check readiness for writing. This function never blocks. + /// + /// Returns the number of bytes permitted for the next call to `write`, + /// or an error. Calling `write` with more bytes than this function has + /// permitted will trap. + /// + /// When this function returns 0 bytes, the `subscribe` pollable will + /// become ready when this function will report at least 1 byte, or an + /// error. + check-write: func() -> result - /// Perform a non-blocking write of bytes to a stream. - /// - /// This function returns a `u64` and a `stream-status`. The `u64` indicates - /// the number of bytes from `buf` that were written, which may be less than - /// the length of `buf`. The `stream-status` indicates if further writes to - /// the stream are expected to be read. - /// - /// When the returned `stream-status` is `open`, the `u64` return value may - /// be less than the length of `buf`. This indicates that no more bytes may - /// be written to the stream promptly. In that case the - /// `subscribe-to-output-stream` pollable will indicate when additional bytes - /// may be promptly written. - /// - /// Writing an empty list must return a non-error result with `0` for the - /// `u64` return value, and the current `stream-status`. - write: func( - this: output-stream, - /// Data to write - buf: list - ) -> result> - - /// Blocking write of bytes to a stream. - /// - /// This is similar to `write`, except that it blocks until at least one - /// byte can be written. - blocking-write: func( - this: output-stream, - /// Data to write - buf: list - ) -> result> - - /// Write multiple zero-bytes to a stream. - /// - /// This function returns a `u64` indicating the number of zero-bytes - /// that were written; it may be less than `len`. Equivelant to a call to - /// `write` with a list of zeroes of the given length. - write-zeroes: func( - this: output-stream, - /// The number of zero-bytes to write - len: u64 - ) -> result> - - /// Write multiple zero bytes to a stream, with blocking. - /// - /// This is similar to `write-zeroes`, except that it blocks until at least - /// one byte can be written. Equivelant to a call to `blocking-write` with - /// a list of zeroes of the given length. - blocking-write-zeroes: func( - this: output-stream, - /// The number of zero bytes to write - len: u64 - ) -> result> - - /// Read from one stream and write to another. - /// - /// This function returns the number of bytes transferred; it may be less - /// than `len`. - /// - /// Unlike other I/O functions, this function blocks until all the data - /// read from the input stream has been written to the output stream. - splice: func( - this: output-stream, - /// The stream to read from - src: input-stream, - /// The number of bytes to splice - len: u64, - ) -> result> - - /// Read from one stream and write to another, with blocking. - /// - /// This is similar to `splice`, except that it blocks until at least - /// one byte can be read. - blocking-splice: func( - this: output-stream, - /// The stream to read from - src: input-stream, - /// The number of bytes to splice - len: u64, - ) -> result> - - /// Forward the entire contents of an input stream to an output stream. - /// - /// This function repeatedly reads from the input stream and writes - /// the data to the output stream, until the end of the input stream - /// is reached, or an error is encountered. - /// - /// Unlike other I/O functions, this function blocks until the end - /// of the input stream is seen and all the data has been written to - /// the output stream. - /// - /// This function returns the number of bytes transferred, and the status of - /// the output stream. - forward: func( - this: output-stream, - /// The stream to read from - src: input-stream - ) -> result> - - /// Create a `pollable` which will resolve once either the specified stream - /// is ready to accept bytes or the `stream-state` has become closed. - /// - /// Once the stream-state is closed, this pollable is always ready - /// immediately. - /// - /// The created `pollable` is a child resource of the `output-stream`. - /// Implementations may trap if the `output-stream` is dropped before - /// all derived `pollable`s created with this function are dropped. - subscribe-to-output-stream: func(this: output-stream) -> pollable - - /// Dispose of the specified `output-stream`, after which it may no longer - /// be used. - /// Implementations may trap if this `output-stream` is dropped while - /// child `pollable` resources are still alive. - /// After this `output-stream` is dropped, implementations may report any - /// corresponding `input-stream` has `stream-state.closed`. - drop-output-stream: func(this: output-stream) + /// Perform a write. This function never blocks. + /// + /// Precondition: check-write gave permit of Ok(n) and contents has a + /// length of less than or equal to n. Otherwise, this function will trap. + /// + /// returns Err(closed) without writing if the stream has closed since + /// the last call to check-write provided a permit. + write: func( + contents: list + ) -> result<_, write-error> + + /// Perform a write of up to 4096 bytes, and then flush the stream. Block + /// until all of these operations are complete, or an error occurs. + /// + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe`, `write`, and `flush`, and is implemented with the + /// following pseudo-code: + /// + /// ```text + /// let pollable = this.subscribe(); + /// while !contents.is_empty() { + /// // Wait for the stream to become writable + /// poll-one(pollable); + /// let Ok(n) = this.check-write(); // eliding error handling + /// let len = min(n, contents.len()); + /// let (chunk, rest) = contents.split_at(len); + /// this.write(chunk ); // eliding error handling + /// contents = rest; + /// } + /// this.flush(); + /// // Wait for completion of `flush` + /// poll-one(pollable); + /// // Check for any errors that arose during `flush` + /// let _ = this.check-write(); // eliding error handling + /// ``` + blocking-write-and-flush: func( + contents: list + ) -> result<_, write-error> + + /// Request to flush buffered output. This function never blocks. + /// + /// This tells the output-stream that the caller intends any buffered + /// output to be flushed. the output which is expected to be flushed + /// is all that has been passed to `write` prior to this call. + /// + /// Upon calling this function, the `output-stream` will not accept any + /// writes (`check-write` will return `ok(0)`) until the flush has + /// completed. The `subscribe` pollable will become ready when the + /// flush has completed and the stream can accept more writes. + flush: func() -> result<_, write-error> + + /// Request to flush buffered output, and block until flush completes + /// and stream is ready for writing again. + blocking-flush: func() -> result<_, write-error> + + /// Create a `pollable` which will resolve once the output-stream + /// is ready for more writing, or an error has occured. When this + /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an + /// error. + /// + /// If the stream is closed, this pollable is always ready immediately. + /// + /// The created `pollable` is a child resource of the `output-stream`. + /// Implementations may trap if the `output-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe: func() -> pollable + + /// Write zeroes to a stream. + /// + /// this should be used precisely like `write` with the exact same + /// preconditions (must use check-write first), but instead of + /// passing a list of bytes, you simply pass the number of zero-bytes + /// that should be written. + write-zeroes: func( + /// The number of zero-bytes to write + len: u64 + ) -> result<_, write-error> + + /// Perform a write of up to 4096 zeroes, and then flush the stream. + /// Block until all of these operations are complete, or an error + /// occurs. + /// + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with + /// the following pseudo-code: + /// + /// ```text + /// let pollable = this.subscribe(); + /// while num_zeroes != 0 { + /// // Wait for the stream to become writable + /// poll-one(pollable); + /// let Ok(n) = this.check-write(); // eliding error handling + /// let len = min(n, num_zeroes); + /// this.write-zeroes(len); // eliding error handling + /// num_zeroes -= len; + /// } + /// this.flush(); + /// // Wait for completion of `flush` + /// poll-one(pollable); + /// // Check for any errors that arose during `flush` + /// let _ = this.check-write(); // eliding error handling + /// ``` + blocking-write-zeroes-and-flush: func( + /// The number of zero-bytes to write + len: u64 + ) -> result<_, write-error> + + /// Read from one stream and write to another. + /// + /// This function returns the number of bytes transferred; it may be less + /// than `len`. + /// + /// Unlike other I/O functions, this function blocks until all the data + /// read from the input stream has been written to the output stream. + splice: func( + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result> + + /// Read from one stream and write to another, with blocking. + /// + /// This is similar to `splice`, except that it blocks until at least + /// one byte can be read. + blocking-splice: func( + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result> + + /// Forward the entire contents of an input stream to an output stream. + /// + /// This function repeatedly reads from the input stream and writes + /// the data to the output stream, until the end of the input stream + /// is reached, or an error is encountered. + /// + /// Unlike other I/O functions, this function blocks until the end + /// of the input stream is seen and all the data has been written to + /// the output stream. + /// + /// This function returns the number of bytes transferred, and the status of + /// the output stream. + forward: func( + /// The stream to read from + src: input-stream + ) -> result> + } } diff --git a/proposals/filesystem/wit/deps/io/world.wit b/proposals/filesystem/wit/deps/io/world.wit index b7f625334..8738dba75 100644 --- a/proposals/filesystem/wit/deps/io/world.wit +++ b/proposals/filesystem/wit/deps/io/world.wit @@ -1,5 +1,6 @@ package wasi:io -world example-world { +world imports { import streams + import poll } diff --git a/proposals/filesystem/wit/deps/poll/poll.wit b/proposals/filesystem/wit/deps/poll/poll.wit deleted file mode 100644 index fa82b6063..000000000 --- a/proposals/filesystem/wit/deps/poll/poll.wit +++ /dev/null @@ -1,49 +0,0 @@ -/// A poll API intended to let users wait for I/O events on multiple handles -/// at once. -interface poll { - /// A "pollable" handle. - /// - /// This is conceptually represents a `stream<_, _>`, or in other words, - /// a stream that one can wait on, repeatedly, but which does not itself - /// produce any data. It's temporary scaffolding until component-model's - /// async features are ready. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// `pollable` lifetimes are not automatically managed. Users must ensure - /// that they do not outlive the resource they reference. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type pollable = u32 - - /// Dispose of the specified `pollable`, after which it may no longer - /// be used. - drop-pollable: func(this: pollable) - - /// Poll for completion on a set of pollables. - /// - /// This function takes a list of pollables, which identify I/O sources of - /// interest, and waits until one or more of the events is ready for I/O. - /// - /// The result `list` is the same length as the argument - /// `list`, and indicates the readiness of each corresponding - /// element in that list, with true indicating ready. A single call can - /// return multiple true elements. - /// - /// A timeout can be implemented by adding a pollable from the - /// wasi-clocks API to the list. - /// - /// This function does not return a `result`; polling in itself does not - /// do any I/O so it doesn't fail. If any of the I/O sources identified by - /// the pollables has an error, it is indicated by marking the source as - /// ready in the `list`. - /// - /// The "oneoff" in the name refers to the fact that this function must do a - /// linear scan through the entire list of subscriptions, which may be - /// inefficient if the number is large and the same subscriptions are used - /// many times. In the future, this is expected to be obsoleted by the - /// component model async proposal, which will include a scalable waiting - /// facility. - poll-oneoff: func(in: list) -> list -} diff --git a/proposals/filesystem/wit/deps/poll/world.wit b/proposals/filesystem/wit/deps/poll/world.wit deleted file mode 100644 index d08cadc05..000000000 --- a/proposals/filesystem/wit/deps/poll/world.wit +++ /dev/null @@ -1,5 +0,0 @@ -package wasi:poll - -world example-world { - import poll -} diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index c7e817d45..3f69bf997 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -291,13 +291,6 @@ interface types { no-reuse, } - /// A descriptor is a reference to a filesystem object, which may be a file, - /// directory, named pipe, special file, or other object on which filesystem - /// calls may be made. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type descriptor = u32 - /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. record metadata-hash-value { @@ -307,532 +300,499 @@ interface types { upper: u64, } - /// Return a stream for reading from a file, if available. - /// - /// May fail with an error-code describing why the file cannot be read. - /// - /// Multiple read, write, and append streams may be active on the same open - /// file and they do not interfere with each other. - /// - /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. - read-via-stream: func( - this: descriptor, - /// The offset within the file at which to start reading. - offset: filesize, - ) -> result - - /// Return a stream for writing to a file, if available. - /// - /// May fail with an error-code describing why the file cannot be written. - /// - /// Note: This allows using `write-stream`, which is similar to `write` in - /// POSIX. - write-via-stream: func( - this: descriptor, - /// The offset within the file at which to start writing. - offset: filesize, - ) -> result - - /// Return a stream for appending to a file, if available. - /// - /// May fail with an error-code describing why the file cannot be appended. - /// - /// Note: This allows using `write-stream`, which is similar to `write` with - /// `O_APPEND` in in POSIX. - append-via-stream: func( - this: descriptor, - ) -> result + /// A descriptor is a reference to a filesystem object, which may be a file, + /// directory, named pipe, special file, or other object on which filesystem + /// calls may be made. + resource descriptor { + /// Return a stream for reading from a file, if available. + /// + /// May fail with an error-code describing why the file cannot be read. + /// + /// Multiple read, write, and append streams may be active on the same open + /// file and they do not interfere with each other. + /// + /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. + read-via-stream: func( + /// The offset within the file at which to start reading. + offset: filesize, + ) -> result - /// Provide file advisory information on a descriptor. - /// - /// This is similar to `posix_fadvise` in POSIX. - advise: func( - this: descriptor, - /// The offset within the file to which the advisory applies. - offset: filesize, - /// The length of the region to which the advisory applies. - length: filesize, - /// The advice. - advice: advice - ) -> result<_, error-code> - - /// Synchronize the data of a file to disk. - /// - /// This function succeeds with no effect if the file descriptor is not - /// opened for writing. - /// - /// Note: This is similar to `fdatasync` in POSIX. - sync-data: func(this: descriptor) -> result<_, error-code> + /// Return a stream for writing to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be written. + /// + /// Note: This allows using `write-stream`, which is similar to `write` in + /// POSIX. + write-via-stream: func( + /// The offset within the file at which to start writing. + offset: filesize, + ) -> result + + /// Return a stream for appending to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be appended. + /// + /// Note: This allows using `write-stream`, which is similar to `write` with + /// `O_APPEND` in in POSIX. + append-via-stream: func() -> result - /// Get flags associated with a descriptor. - /// - /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. - /// - /// Note: This returns the value that was the `fs_flags` value returned - /// from `fdstat_get` in earlier versions of WASI. - get-flags: func(this: descriptor) -> result + /// Provide file advisory information on a descriptor. + /// + /// This is similar to `posix_fadvise` in POSIX. + advise: func( + /// The offset within the file to which the advisory applies. + offset: filesize, + /// The length of the region to which the advisory applies. + length: filesize, + /// The advice. + advice: advice + ) -> result<_, error-code> + + /// Synchronize the data of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fdatasync` in POSIX. + sync-data: func() -> result<_, error-code> - /// Get the dynamic type of a descriptor. - /// - /// Note: This returns the same value as the `type` field of the `fd-stat` - /// returned by `stat`, `stat-at` and similar. - /// - /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided - /// by `fstat` in POSIX. - /// - /// Note: This returns the value that was the `fs_filetype` value returned - /// from `fdstat_get` in earlier versions of WASI. - get-type: func(this: descriptor) -> result + /// Get flags associated with a descriptor. + /// + /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. + /// + /// Note: This returns the value that was the `fs_flags` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-flags: func() -> result - /// Adjust the size of an open file. If this increases the file's size, the - /// extra bytes are filled with zeros. - /// - /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - set-size: func(this: descriptor, size: filesize) -> result<_, error-code> + /// Get the dynamic type of a descriptor. + /// + /// Note: This returns the same value as the `type` field of the `fd-stat` + /// returned by `stat`, `stat-at` and similar. + /// + /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided + /// by `fstat` in POSIX. + /// + /// Note: This returns the value that was the `fs_filetype` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-type: func() -> result - /// Adjust the timestamps of an open file or directory. - /// - /// Note: This is similar to `futimens` in POSIX. - /// - /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - set-times: func( - this: descriptor, - /// The desired values of the data access timestamp. - data-access-timestamp: new-timestamp, - /// The desired values of the data modification timestamp. - data-modification-timestamp: new-timestamp, - ) -> result<_, error-code> - - /// Read from a descriptor, without using and updating the descriptor's offset. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a bool which, when true, indicates that the end of the - /// file was reached. The returned list will contain up to `length` bytes; it - /// may return fewer than requested, if the end of the file is reached or - /// if the I/O operation is interrupted. - /// - /// In the future, this may change to return a `stream`. - /// - /// Note: This is similar to `pread` in POSIX. - read: func( - this: descriptor, - /// The maximum number of bytes to read. - length: filesize, - /// The offset within the file at which to read. - offset: filesize, - ) -> result, bool>, error-code> - - /// Write to a descriptor, without using and updating the descriptor's offset. - /// - /// It is valid to write past the end of a file; the file is extended to the - /// extent of the write, with bytes between the previous end and the start of - /// the write set to zero. - /// - /// In the future, this may change to take a `stream`. - /// - /// Note: This is similar to `pwrite` in POSIX. - write: func( - this: descriptor, - /// Data to write - buffer: list, - /// The offset within the file at which to write. - offset: filesize, - ) -> result - - /// Read directory entries from a directory. - /// - /// On filesystems where directories contain entries referring to themselves - /// and their parents, often named `.` and `..` respectively, these entries - /// are omitted. - /// - /// This always returns a new stream which starts at the beginning of the - /// directory. Multiple streams may be active on the same directory, and they - /// do not interfere with each other. - read-directory: func( - this: descriptor - ) -> result - - /// Synchronize the data and metadata of a file to disk. - /// - /// This function succeeds with no effect if the file descriptor is not - /// opened for writing. - /// - /// Note: This is similar to `fsync` in POSIX. - sync: func(this: descriptor) -> result<_, error-code> + /// Adjust the size of an open file. If this increases the file's size, the + /// extra bytes are filled with zeros. + /// + /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. + set-size: func(size: filesize) -> result<_, error-code> - /// Create a directory. - /// - /// Note: This is similar to `mkdirat` in POSIX. - create-directory-at: func( - this: descriptor, - /// The relative path at which to create the directory. - path: string, - ) -> result<_, error-code> - - /// Return the attributes of an open file or directory. - /// - /// Note: This is similar to `fstat` in POSIX, except that it does not return - /// device and inode information. For testing whether two descriptors refer to - /// the same underlying filesystem object, use `is-same-object`. To obtain - /// additional data that can be used do determine whether a file has been - /// modified, use `metadata-hash`. - /// - /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - stat: func(this: descriptor) -> result + /// Adjust the timestamps of an open file or directory. + /// + /// Note: This is similar to `futimens` in POSIX. + /// + /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. + set-times: func( + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code> + + /// Read from a descriptor, without using and updating the descriptor's offset. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a bool which, when true, indicates that the end of the + /// file was reached. The returned list will contain up to `length` bytes; it + /// may return fewer than requested, if the end of the file is reached or + /// if the I/O operation is interrupted. + /// + /// In the future, this may change to return a `stream`. + /// + /// Note: This is similar to `pread` in POSIX. + read: func( + /// The maximum number of bytes to read. + length: filesize, + /// The offset within the file at which to read. + offset: filesize, + ) -> result, bool>, error-code> + + /// Write to a descriptor, without using and updating the descriptor's offset. + /// + /// It is valid to write past the end of a file; the file is extended to the + /// extent of the write, with bytes between the previous end and the start of + /// the write set to zero. + /// + /// In the future, this may change to take a `stream`. + /// + /// Note: This is similar to `pwrite` in POSIX. + write: func( + /// Data to write + buffer: list, + /// The offset within the file at which to write. + offset: filesize, + ) -> result + + /// Read directory entries from a directory. + /// + /// On filesystems where directories contain entries referring to themselves + /// and their parents, often named `.` and `..` respectively, these entries + /// are omitted. + /// + /// This always returns a new stream which starts at the beginning of the + /// directory. Multiple streams may be active on the same directory, and they + /// do not interfere with each other. + read-directory: func() -> result - /// Return the attributes of a file or directory. - /// - /// Note: This is similar to `fstatat` in POSIX, except that it does not - /// return device and inode information. See the `stat` description for a - /// discussion of alternatives. - /// - /// Note: This was called `path_filestat_get` in earlier versions of WASI. - stat-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to inspect. - path: string, - ) -> result - - /// Adjust the timestamps of a file or directory. - /// - /// Note: This is similar to `utimensat` in POSIX. - /// - /// Note: This was called `path_filestat_set_times` in earlier versions of - /// WASI. - set-times-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to operate on. - path: string, - /// The desired values of the data access timestamp. - data-access-timestamp: new-timestamp, - /// The desired values of the data modification timestamp. - data-modification-timestamp: new-timestamp, - ) -> result<_, error-code> - - /// Create a hard link. - /// - /// Note: This is similar to `linkat` in POSIX. - link-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - old-path-flags: path-flags, - /// The relative source path from which to link. - old-path: string, - /// The base directory for `new-path`. - new-descriptor: descriptor, - /// The relative destination path at which to create the hard link. - new-path: string, - ) -> result<_, error-code> - - /// Open a file or directory. - /// - /// The returned descriptor is not guaranteed to be the lowest-numbered - /// descriptor not currently open/ it is randomized to prevent applications - /// from depending on making assumptions about indexes, since this is - /// error-prone in multi-threaded contexts. The returned descriptor is - /// guaranteed to be less than 2**31. - /// - /// If `flags` contains `descriptor-flags::mutate-directory`, and the base - /// descriptor doesn't have `descriptor-flags::mutate-directory` set, - /// `open-at` fails with `error-code::read-only`. - /// - /// If `flags` contains `write` or `mutate-directory`, or `open-flags` - /// contains `truncate` or `create`, and the base descriptor doesn't have - /// `descriptor-flags::mutate-directory` set, `open-at` fails with - /// `error-code::read-only`. - /// - /// Note: This is similar to `openat` in POSIX. - open-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the object to open. - path: string, - /// The method by which to open the file. - open-flags: open-flags, - /// Flags to use for the resulting descriptor. - %flags: descriptor-flags, - /// Permissions to use when creating a new file. - modes: modes - ) -> result - - /// Read the contents of a symbolic link. - /// - /// If the contents contain an absolute or rooted path in the underlying - /// filesystem, this function fails with `error-code::not-permitted`. - /// - /// Note: This is similar to `readlinkat` in POSIX. - readlink-at: func( - this: descriptor, - /// The relative path of the symbolic link from which to read. - path: string, - ) -> result - - /// Remove a directory. - /// - /// Return `error-code::not-empty` if the directory is not empty. - /// - /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - remove-directory-at: func( - this: descriptor, - /// The relative path to a directory to remove. - path: string, - ) -> result<_, error-code> - - /// Rename a filesystem object. - /// - /// Note: This is similar to `renameat` in POSIX. - rename-at: func( - this: descriptor, - /// The relative source path of the file or directory to rename. - old-path: string, - /// The base directory for `new-path`. - new-descriptor: descriptor, - /// The relative destination path to which to rename the file or directory. - new-path: string, - ) -> result<_, error-code> - - /// Create a symbolic link (also known as a "symlink"). - /// - /// If `old-path` starts with `/`, the function fails with - /// `error-code::not-permitted`. - /// - /// Note: This is similar to `symlinkat` in POSIX. - symlink-at: func( - this: descriptor, - /// The contents of the symbolic link. - old-path: string, - /// The relative destination path at which to create the symbolic link. - new-path: string, - ) -> result<_, error-code> - - /// Check accessibility of a filesystem path. - /// - /// Check whether the given filesystem path names an object which is - /// readable, writable, or executable, or whether it exists. - /// - /// This does not a guarantee that subsequent accesses will succeed, as - /// filesystem permissions may be modified asynchronously by external - /// entities. - /// - /// Note: This is similar to `faccessat` with the `AT_EACCESS` flag in POSIX. - access-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to check. - path: string, - /// The type of check to perform. - %type: access-type - ) -> result<_, error-code> - - /// Unlink a filesystem object that is not a directory. - /// - /// Return `error-code::is-directory` if the path refers to a directory. - /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - unlink-file-at: func( - this: descriptor, - /// The relative path to a file to unlink. - path: string, - ) -> result<_, error-code> - - /// Change the permissions of a filesystem object that is not a directory. - /// - /// Note that the ultimate meanings of these permissions is - /// filesystem-specific. - /// - /// Note: This is similar to `fchmodat` in POSIX. - change-file-permissions-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the filesystem object. - modes: modes, - ) -> result<_, error-code> - - /// Change the permissions of a directory. - /// - /// Note that the ultimate meanings of these permissions is - /// filesystem-specific. - /// - /// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" - /// flag. `read` on a directory implies readability and searchability, and - /// `execute` is not valid for directories. - /// - /// Note: This is similar to `fchmodat` in POSIX. - change-directory-permissions-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the directory. - modes: modes, - ) -> result<_, error-code> - - /// Request a shared advisory lock for an open file. - /// - /// This requests a *shared* lock; more than one shared lock can be held for - /// a file at the same time. - /// - /// If the open file has an exclusive lock, this function downgrades the lock - /// to a shared lock. If it has a shared lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified how shared locks interact with locks acquired by - /// non-WASI programs. - /// - /// This function blocks until the lock can be acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. - lock-shared: func(this: descriptor) -> result<_, error-code> + /// Synchronize the data and metadata of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fsync` in POSIX. + sync: func() -> result<_, error-code> - /// Request an exclusive advisory lock for an open file. - /// - /// This requests an *exclusive* lock; no other locks may be held for the - /// file while an exclusive lock is held. - /// - /// If the open file has a shared lock and there are no exclusive locks held - /// for the file, this function upgrades the lock to an exclusive lock. If the - /// open file already has an exclusive lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified whether this function succeeds if the file descriptor - /// is not opened for writing. It is unspecified how exclusive locks interact - /// with locks acquired by non-WASI programs. - /// - /// This function blocks until the lock can be acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. - lock-exclusive: func(this: descriptor) -> result<_, error-code> + /// Create a directory. + /// + /// Note: This is similar to `mkdirat` in POSIX. + create-directory-at: func( + /// The relative path at which to create the directory. + path: string, + ) -> result<_, error-code> - /// Request a shared advisory lock for an open file. - /// - /// This requests a *shared* lock; more than one shared lock can be held for - /// a file at the same time. - /// - /// If the open file has an exclusive lock, this function downgrades the lock - /// to a shared lock. If it has a shared lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified how shared locks interact with locks acquired by - /// non-WASI programs. - /// - /// This function returns `error-code::would-block` if the lock cannot be - /// acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. - try-lock-shared: func(this: descriptor) -> result<_, error-code> + /// Return the attributes of an open file or directory. + /// + /// Note: This is similar to `fstat` in POSIX, except that it does not return + /// device and inode information. For testing whether two descriptors refer to + /// the same underlying filesystem object, use `is-same-object`. To obtain + /// additional data that can be used do determine whether a file has been + /// modified, use `metadata-hash`. + /// + /// Note: This was called `fd_filestat_get` in earlier versions of WASI. + stat: func() -> result - /// Request an exclusive advisory lock for an open file. - /// - /// This requests an *exclusive* lock; no other locks may be held for the - /// file while an exclusive lock is held. - /// - /// If the open file has a shared lock and there are no exclusive locks held - /// for the file, this function upgrades the lock to an exclusive lock. If the - /// open file already has an exclusive lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified whether this function succeeds if the file descriptor - /// is not opened for writing. It is unspecified how exclusive locks interact - /// with locks acquired by non-WASI programs. - /// - /// This function returns `error-code::would-block` if the lock cannot be - /// acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. - try-lock-exclusive: func(this: descriptor) -> result<_, error-code> + /// Return the attributes of a file or directory. + /// + /// Note: This is similar to `fstatat` in POSIX, except that it does not + /// return device and inode information. See the `stat` description for a + /// discussion of alternatives. + /// + /// Note: This was called `path_filestat_get` in earlier versions of WASI. + stat-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result + + /// Adjust the timestamps of a file or directory. + /// + /// Note: This is similar to `utimensat` in POSIX. + /// + /// Note: This was called `path_filestat_set_times` in earlier versions of + /// WASI. + set-times-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to operate on. + path: string, + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code> + + /// Create a hard link. + /// + /// Note: This is similar to `linkat` in POSIX. + link-at: func( + /// Flags determining the method of how the path is resolved. + old-path-flags: path-flags, + /// The relative source path from which to link. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: borrow, + /// The relative destination path at which to create the hard link. + new-path: string, + ) -> result<_, error-code> + + /// Open a file or directory. + /// + /// The returned descriptor is not guaranteed to be the lowest-numbered + /// descriptor not currently open/ it is randomized to prevent applications + /// from depending on making assumptions about indexes, since this is + /// error-prone in multi-threaded contexts. The returned descriptor is + /// guaranteed to be less than 2**31. + /// + /// If `flags` contains `descriptor-flags::mutate-directory`, and the base + /// descriptor doesn't have `descriptor-flags::mutate-directory` set, + /// `open-at` fails with `error-code::read-only`. + /// + /// If `flags` contains `write` or `mutate-directory`, or `open-flags` + /// contains `truncate` or `create`, and the base descriptor doesn't have + /// `descriptor-flags::mutate-directory` set, `open-at` fails with + /// `error-code::read-only`. + /// + /// Note: This is similar to `openat` in POSIX. + open-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the object to open. + path: string, + /// The method by which to open the file. + open-flags: open-flags, + /// Flags to use for the resulting descriptor. + %flags: descriptor-flags, + /// Permissions to use when creating a new file. + modes: modes + ) -> result + + /// Read the contents of a symbolic link. + /// + /// If the contents contain an absolute or rooted path in the underlying + /// filesystem, this function fails with `error-code::not-permitted`. + /// + /// Note: This is similar to `readlinkat` in POSIX. + readlink-at: func( + /// The relative path of the symbolic link from which to read. + path: string, + ) -> result - /// Release a shared or exclusive lock on an open file. - /// - /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. - unlock: func(this: descriptor) -> result<_, error-code> + /// Remove a directory. + /// + /// Return `error-code::not-empty` if the directory is not empty. + /// + /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + remove-directory-at: func( + /// The relative path to a directory to remove. + path: string, + ) -> result<_, error-code> + + /// Rename a filesystem object. + /// + /// Note: This is similar to `renameat` in POSIX. + rename-at: func( + /// The relative source path of the file or directory to rename. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: borrow, + /// The relative destination path to which to rename the file or directory. + new-path: string, + ) -> result<_, error-code> + + /// Create a symbolic link (also known as a "symlink"). + /// + /// If `old-path` starts with `/`, the function fails with + /// `error-code::not-permitted`. + /// + /// Note: This is similar to `symlinkat` in POSIX. + symlink-at: func( + /// The contents of the symbolic link. + old-path: string, + /// The relative destination path at which to create the symbolic link. + new-path: string, + ) -> result<_, error-code> + + /// Check accessibility of a filesystem path. + /// + /// Check whether the given filesystem path names an object which is + /// readable, writable, or executable, or whether it exists. + /// + /// This does not a guarantee that subsequent accesses will succeed, as + /// filesystem permissions may be modified asynchronously by external + /// entities. + /// + /// Note: This is similar to `faccessat` with the `AT_EACCESS` flag in POSIX. + access-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to check. + path: string, + /// The type of check to perform. + %type: access-type + ) -> result<_, error-code> + + /// Unlink a filesystem object that is not a directory. + /// + /// Return `error-code::is-directory` if the path refers to a directory. + /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + unlink-file-at: func( + /// The relative path to a file to unlink. + path: string, + ) -> result<_, error-code> + + /// Change the permissions of a filesystem object that is not a directory. + /// + /// Note that the ultimate meanings of these permissions is + /// filesystem-specific. + /// + /// Note: This is similar to `fchmodat` in POSIX. + change-file-permissions-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to operate on. + path: string, + /// The new permissions for the filesystem object. + modes: modes, + ) -> result<_, error-code> + + /// Change the permissions of a directory. + /// + /// Note that the ultimate meanings of these permissions is + /// filesystem-specific. + /// + /// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" + /// flag. `read` on a directory implies readability and searchability, and + /// `execute` is not valid for directories. + /// + /// Note: This is similar to `fchmodat` in POSIX. + change-directory-permissions-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to operate on. + path: string, + /// The new permissions for the directory. + modes: modes, + ) -> result<_, error-code> + + /// Request a shared advisory lock for an open file. + /// + /// This requests a *shared* lock; more than one shared lock can be held for + /// a file at the same time. + /// + /// If the open file has an exclusive lock, this function downgrades the lock + /// to a shared lock. If it has a shared lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified how shared locks interact with locks acquired by + /// non-WASI programs. + /// + /// This function blocks until the lock can be acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. + lock-shared: func() -> result<_, error-code> - /// Dispose of the specified `descriptor`, after which it may no longer - /// be used. - drop-descriptor: func(this: descriptor) + /// Request an exclusive advisory lock for an open file. + /// + /// This requests an *exclusive* lock; no other locks may be held for the + /// file while an exclusive lock is held. + /// + /// If the open file has a shared lock and there are no exclusive locks held + /// for the file, this function upgrades the lock to an exclusive lock. If the + /// open file already has an exclusive lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified whether this function succeeds if the file descriptor + /// is not opened for writing. It is unspecified how exclusive locks interact + /// with locks acquired by non-WASI programs. + /// + /// This function blocks until the lock can be acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. + lock-exclusive: func() -> result<_, error-code> - /// A stream of directory entries. - /// - /// This [represents a stream of `dir-entry`](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Streams). - type directory-entry-stream = u32 + /// Request a shared advisory lock for an open file. + /// + /// This requests a *shared* lock; more than one shared lock can be held for + /// a file at the same time. + /// + /// If the open file has an exclusive lock, this function downgrades the lock + /// to a shared lock. If it has a shared lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified how shared locks interact with locks acquired by + /// non-WASI programs. + /// + /// This function returns `error-code::would-block` if the lock cannot be + /// acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. + try-lock-shared: func() -> result<_, error-code> - /// Read a single directory entry from a `directory-entry-stream`. - read-directory-entry: func( - this: directory-entry-stream - ) -> result, error-code> + /// Request an exclusive advisory lock for an open file. + /// + /// This requests an *exclusive* lock; no other locks may be held for the + /// file while an exclusive lock is held. + /// + /// If the open file has a shared lock and there are no exclusive locks held + /// for the file, this function upgrades the lock to an exclusive lock. If the + /// open file already has an exclusive lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified whether this function succeeds if the file descriptor + /// is not opened for writing. It is unspecified how exclusive locks interact + /// with locks acquired by non-WASI programs. + /// + /// This function returns `error-code::would-block` if the lock cannot be + /// acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. + try-lock-exclusive: func() -> result<_, error-code> - /// Dispose of the specified `directory-entry-stream`, after which it may no longer - /// be used. - drop-directory-entry-stream: func(this: directory-entry-stream) + /// Release a shared or exclusive lock on an open file. + /// + /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. + unlock: func() -> result<_, error-code> - /// Test whether two descriptors refer to the same filesystem object. - /// - /// In POSIX, this corresponds to testing whether the two descriptors have the - /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. - /// wasi-filesystem does not expose device and inode numbers, so this function - /// may be used instead. - is-same-object: func(this: descriptor, other: descriptor) -> bool - - /// Return a hash of the metadata associated with a filesystem object referred - /// to by a descriptor. - /// - /// This returns a hash of the last-modification timestamp and file size, and - /// may also include the inode number, device number, birth timestamp, and - /// other metadata fields that may change when the file is modified or - /// replaced. It may also include a secret value chosen by the - /// implementation and not otherwise exposed. - /// - /// Implementations are encourated to provide the following properties: - /// - /// - If the file is not modified or replaced, the computed hash value should - /// usually not change. - /// - If the object is modified or replaced, the computed hash value should - /// usually change. - /// - The inputs to the hash should not be easily computable from the - /// computed hash. - /// - /// However, none of these is required. - metadata-hash: func( - this: descriptor, - ) -> result + /// Test whether two descriptors refer to the same filesystem object. + /// + /// In POSIX, this corresponds to testing whether the two descriptors have the + /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. + /// wasi-filesystem does not expose device and inode numbers, so this function + /// may be used instead. + is-same-object: func(other: borrow) -> bool + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a descriptor. + /// + /// This returns a hash of the last-modification timestamp and file size, and + /// may also include the inode number, device number, birth timestamp, and + /// other metadata fields that may change when the file is modified or + /// replaced. It may also include a secret value chosen by the + /// implementation and not otherwise exposed. + /// + /// Implementations are encourated to provide the following properties: + /// + /// - If the file is not modified or replaced, the computed hash value should + /// usually not change. + /// - If the object is modified or replaced, the computed hash value should + /// usually change. + /// - The inputs to the hash should not be easily computable from the + /// computed hash. + /// + /// However, none of these is required. + metadata-hash: func() -> result - /// Return a hash of the metadata associated with a filesystem object referred - /// to by a directory descriptor and a relative path. - /// - /// This performs the same hash computation as `metadata-hash`. - metadata-hash-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to inspect. - path: string, - ) -> result + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a directory descriptor and a relative path. + /// + /// This performs the same hash computation as `metadata-hash`. + metadata-hash-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result + } + + /// A stream of directory entries. + resource directory-entry-stream { + /// Read a single directory entry from a `directory-entry-stream`. + read-directory-entry: func() -> result, error-code> + } } From 28e37ee288301d8369030e2625c659359578e0de Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 29 Sep 2023 16:03:18 -0700 Subject: [PATCH 1222/1772] Remove an obsolete comment. --- proposals/filesystem/wit/deps.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/filesystem/wit/deps.toml b/proposals/filesystem/wit/deps.toml index 6da3b6487..23c019844 100644 --- a/proposals/filesystem/wit/deps.toml +++ b/proposals/filesystem/wit/deps.toml @@ -1,3 +1,2 @@ -# Temporarily use the resources branches. io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" From 752de8cc26a2d8d195f2a29cb6fb1ee9d793ce9c Mon Sep 17 00:00:00 2001 From: Dylan Thacker-Smith Date: Fri, 29 Sep 2023 19:04:19 -0400 Subject: [PATCH 1223/1772] Fix a couple of typos in README.md (#133) --- proposals/filesystem/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index c5d6e6bfc..0d5800a3a 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -50,7 +50,7 @@ resolved within that directory. For more information about sandbox, see [WASI filesystem path resolution](path-resolution.md). WASI filesystem hides some of the surface differences between Windows and -Unix-style filesystems, however much of its behavior, indluding the +Unix-style filesystems, however much of its behavior, including the semantics of path lookup, and the semantics of files, directories, and symlinks, and the constraints on filesystem paths, is host-dependent. @@ -102,7 +102,7 @@ fn write_hello_world_to_a_file(dir: Descriptor) -> Result<(), Errno> { Perhaps the biggest change from the preview1 version of openat, called `path_open`, is the removal of the *rights* flags. Preview1 associates -a set of flags with every file descriptor enumerating which operatings +a set of flags with every file descriptor enumerating which operations may be performed on it, such as reading, writing, appending, truncating, and many other operations. In practice, this created a lot of ambiguity about how it mapped to POSIX semantics, as it doesn't directly correspond From 3c4f9e8df326ddc658802f8b29e277de284c221a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 29 Sep 2023 16:11:41 -0700 Subject: [PATCH 1224/1772] Convert to resources. (#24) * Convert to resources. Convert terminal-input and terminal-output to resources, and update the dependencies to account for: - WebAssembly/wasi-io#46 - WebAssembly/wasi-clocks#50 - WebAssembly/wasi-filesystem#132 - WebAssembly/wasi-random#34 - WebAssembly/wasi-sockets#61 * Update to the latest filesystem/types.wit. * Update to wit-abi-up-to-date@v15 and wit-deps 0.3.3. * Update to the latest main branches of the upstream repos. * Update to the latest dependencies. --- proposals/cli/.github/workflows/main.yml | 6 +- proposals/cli/command.md | 1339 ++++++++--------- proposals/cli/reactor.md | 1339 ++++++++--------- proposals/cli/wit/deps.lock | 25 +- proposals/cli/wit/deps.toml | 5 +- .../cli/wit/deps/clocks/monotonic-clock.wit | 2 +- proposals/cli/wit/deps/clocks/timezone.wit | 17 +- proposals/cli/wit/deps/clocks/world.wit | 2 +- proposals/cli/wit/deps/filesystem/types.wit | 1033 ++++++------- proposals/cli/wit/deps/filesystem/world.wit | 2 +- proposals/cli/wit/deps/io/poll.wit | 34 + proposals/cli/wit/deps/io/streams.wit | 445 +++--- proposals/cli/wit/deps/io/world.wit | 3 +- proposals/cli/wit/deps/poll/poll.wit | 49 - proposals/cli/wit/deps/poll/world.wit | 5 - proposals/cli/wit/deps/random/world.wit | 2 +- .../cli/wit/deps/sockets/ip-name-lookup.wit | 58 +- proposals/cli/wit/deps/sockets/network.wit | 14 +- proposals/cli/wit/deps/sockets/tcp.wit | 466 +++--- proposals/cli/wit/deps/sockets/udp.wit | 396 +++-- proposals/cli/wit/deps/sockets/world.wit | 2 +- proposals/cli/wit/reactor.wit | 2 +- proposals/cli/wit/terminal.wit | 16 +- 23 files changed, 2531 insertions(+), 2731 deletions(-) create mode 100644 proposals/cli/wit/deps/io/poll.wit delete mode 100644 proposals/cli/wit/deps/poll/poll.wit delete mode 100644 proposals/cli/wit/deps/poll/world.wit diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml index edf66129e..1d47b5817 100644 --- a/proposals/cli/.github/workflows/main.yml +++ b/proposals/cli/.github/workflows/main.yml @@ -10,14 +10,14 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: ensure `./wit/deps` are in sync run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.0/wit-deps-x86_64-unknown-linux-musl + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.3/wit-deps-x86_64-unknown-linux-musl chmod +x wit-deps ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v14 + - uses: WebAssembly/wit-abi-up-to-date@v15 with: worlds: "command reactor" diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 6634d0a06..d72a3fc06 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -3,7 +3,7 @@
      • Imports: -

        Import interface wasi:poll/poll

        +

        Import interface wasi:io/poll

        A poll API intended to let users wait for I/O events on multiple handles at once.


        Types

        -

        type pollable

        -

        u32

        -

        A "pollable" handle. -

        This is conceptually represents a stream<_, _>, or in other words, -a stream that one can wait on, repeatedly, but which does not itself -produce any data. It's temporary scaffolding until component-model's -async features are ready.

        -

        And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

        -

        pollable lifetimes are not automatically managed. Users must ensure -that they do not outlive the resource they reference.

        -

        This represents a resource.

        +

        resource pollable


        Functions

        -

        drop-pollable: func

        -

        Dispose of the specified pollable, after which it may no longer -be used.

        -
        Params
        - -

        poll-oneoff: func

        +

        poll-list: func

        Poll for completion on a set of pollables.

        This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

        -

        The result list<bool> is the same length as the argument -list<pollable>, and indicates the readiness of each corresponding -element in that list, with true indicating ready. A single call can -return multiple true elements.

        +

        The result list<u32> contains one or more indices of handles in the +argument list that is ready for I/O.

        +

        If the list contains more elements than can be indexed with a u32 +value, this function traps.

        A timeout can be implemented by adding a pollable from the wasi-clocks API to the list.

        This function does not return a result; polling in itself does not do any I/O so it doesn't fail. If any of the I/O sources identified by the pollables has an error, it is indicated by marking the source as -ready in the list<bool>.

        -

        The "oneoff" in the name refers to the fact that this function must do a -linear scan through the entire list of subscriptions, which may be -inefficient if the number is large and the same subscriptions are used -many times. In the future, this is expected to be obsoleted by the -component model async proposal, which will include a scalable waiting -facility.

        +being reaedy for I/O.

        Params
        Return values
          -
        • list<bool>
        • +
        • list<u32>
        • +
        +

        poll-one: func

        +

        Poll for completion on a single pollable.

        +

        This function is similar to poll-list, but operates on only a single +pollable. When it returns, the handle is ready for I/O.

        +
        Params
        +

        Import interface wasi:clocks/monotonic-clock

        WASI Monotonic Clock is a clock API intended to let users measure elapsed @@ -174,7 +158,7 @@ reached.

      Return values

      Import interface wasi:clocks/timezone


      @@ -182,16 +166,9 @@ reached.

      type datetime

      datetime

      -#### `type timezone` -`u32` -

      A timezone. -

      In timezones that recognize daylight saving time, also known as daylight -time and summer time, the information returned from the functions varies -over time to reflect these adjustments.

      -

      This represents a resource.

      -

      record timezone-display

      +#### `record timezone-display`

      Information useful for displaying the timezone of a specific datetime.

      -

      This information may vary within a single timezone to reflect daylight +

      This information may vary within a single timezone to reflect daylight saving time adjustments.

      Record Fields
        @@ -232,7 +209,6 @@ daylight saving time is active.

        saving time.

        Params
        Return values
        @@ -243,20 +219,12 @@ saving time.

        The same as display, but only return the UTC offset.

        Params
        Return values
        • s32
        -

        drop-timezone: func

        -

        Dispose of the specified input-stream, after which it may no longer -be used.

        -
        Params
        -

        Import interface wasi:io/streams

        WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

        @@ -267,11 +235,7 @@ when it does, they are expected to subsume this API.

        type pollable

        pollable

        -#### `record stream-error` -

        An error type returned from a stream operation. Currently this -doesn't provide any additional information.

        -
        Record Fields
        -

        enum stream-status

        +#### `enum stream-status`

        Streams provide a sequence of data and then end; once they end, they no longer provide any further data.

        For example, a stream reading from a file ends when the stream reaches @@ -285,182 +249,273 @@ socket ends when the socket is closed.

      • ended

        -

        The stream has ended and will not produce any further data. +

        When reading, this indicates that the stream will not produce +further data. +When writing, this indicates that the stream will no longer be read. +Further writes are still permitted.

      -

      type input-stream

      -

      u32

      -

      An input bytestream. In the future, this will be replaced by handle -types. -

      This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

      -

      input-streams are non-blocking to the extent practical on underlying -platforms. I/O operations always return promptly; if fewer bytes are -promptly available than requested, they return the number of bytes promptly -available, which could even be zero. To wait for data to be available, -use the subscribe-to-input-stream function to obtain a pollable which -can be polled for using wasi_poll.

      -

      And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

      -

      This represents a resource.

      -

      type output-stream

      -

      u32

      -

      An output bytestream. In the future, this will be replaced by handle -types. -

      This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

      -

      output-streams are non-blocking to the extent practical on -underlying platforms. Except where specified otherwise, I/O operations also -always return promptly, after the number of bytes that can be written -promptly, which could even be zero. To wait for the stream to be ready to -accept data, the subscribe-to-output-stream function to obtain a -pollable which can be polled for using wasi_poll.

      -

      And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

      -

      This represents a resource.

      +

      resource input-stream

      +

      enum write-error

      +

      An error for output-stream operations.

      +

      Contrary to input-streams, a closed output-stream is reported using +an error.

      +
      Enum Cases
      +
        +
      • +

        last-operation-failed

        +

        The last operation (a write or flush) failed before completion. +

      • +
      • +

        closed

        +

        The stream is closed: no more input will be accepted by the +stream. A closed output-stream will return this error on all +future operations. +

      • +
      +

      resource output-stream


      Functions

      -

      read: func

      -

      Read bytes from a stream.

      +

      [method]input-stream.read: func

      +

      Perform a non-blocking read from the stream.

      This function returns a list of bytes containing the data that was -read, along with a stream-status which indicates whether the end of -the stream was reached. The returned list will contain up to len -bytes; it may return fewer than requested, but not more.

      -

      Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more +read, along with a stream-status which, indicates whether further +reads are expected to produce data. The returned list will contain up to +len bytes; it may return fewer than requested, but not more. An +empty list and stream-status:open indicates no more data is +available at this time, and that the pollable given by subscribe +will be ready when more data is available.

      +

      Once a stream has reached the end, subsequent calls to read or +skip will always report stream-status:ended rather than producing more data.

      -

      If len is 0, it represents a request to read 0 bytes, which should -always succeed, assuming the stream hasn't reached its end yet, and -return an empty list.

      -

      The len here is a u64, but some callees may not be able to allocate -a buffer as large as that would imply. -FIXME: describe what happens if allocation fails.

      +

      When the caller gives a len of 0, it represents a request to read 0 +bytes. This read should always succeed and return an empty list and +the current stream-status.

      +

      The len parameter is a u64, which could represent a list of u8 which +is not possible to allocate in wasm32, or not desirable to allocate as +as a return value by the callee. The callee may return a list of bytes +less than len in size while more bytes are available for reading.

      Params
      Return values
      -

      blocking-read: func

      -

      Read bytes from a stream, with blocking.

      -

      This is similar to read, except that it blocks until at least one -byte can be read.

      +

      [method]input-stream.blocking-read: func

      +

      Read bytes from a stream, after blocking until at least one byte can +be read. Except for blocking, identical to read.

      Params
      Return values
      -

      skip: func

      +

      [method]input-stream.skip: func

      Skip bytes from a stream.

      -

      This is similar to the read function, but avoids copying the +

      This is similar to the read function, but avoids copying the bytes into the instance.

      Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more +skip will always report end-of-stream rather than producing more data.

      This function returns the number of bytes skipped, along with a stream-status indicating whether the end of the stream was reached. The returned value will be at most len; it may be less.

      Params
      Return values
      -

      blocking-skip: func

      -

      Skip bytes from a stream, with blocking.

      -

      This is similar to skip, except that it blocks until at least one -byte can be consumed.

      +

      [method]input-stream.blocking-skip: func

      +

      Skip bytes from a stream, after blocking until at least one byte +can be skipped. Except for blocking behavior, identical to skip.

      Params
      Return values
      -

      subscribe-to-input-stream: func

      +

      [method]input-stream.subscribe: func

      Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been -closed.

      +closed. +The created pollable is a child resource of the input-stream. +Implementations may trap if the input-stream is dropped before +all derived pollables created with this function are dropped.

      Params
      Return values
      -

      drop-input-stream: func

      -

      Dispose of the specified input-stream, after which it may no longer -be used.

      +

      [method]output-stream.check-write: func

      +

      Check readiness for writing. This function never blocks.

      +

      Returns the number of bytes permitted for the next call to write, +or an error. Calling write with more bytes than this function has +permitted will trap.

      +

      When this function returns 0 bytes, the subscribe pollable will +become ready when this function will report at least 1 byte, or an +error.

      Params
      +
      Return values
      + +

      [method]output-stream.write: func

      +

      Perform a write. This function never blocks.

      +

      Precondition: check-write gave permit of Ok(n) and contents has a +length of less than or equal to n. Otherwise, this function will trap.

      +

      returns Err(closed) without writing if the stream has closed since +the last call to check-write provided a permit.

      +
      Params
      + +
      Return values
      + -

      write: func

      -

      Write bytes to a stream.

      -

      This function returns a u64 indicating the number of bytes from -buf that were written; it may be less than the full list.

      +

      [method]output-stream.blocking-write-and-flush: func

      +

      Perform a write of up to 4096 bytes, and then flush the stream. Block +until all of these operations are complete, or an error occurs.

      +

      This is a convenience wrapper around the use of check-write, +subscribe, write, and flush, and is implemented with the +following pseudo-code:

      +
      let pollable = this.subscribe();
      +while !contents.is_empty() {
      +  // Wait for the stream to become writable
      +  poll-one(pollable);
      +  let Ok(n) = this.check-write(); // eliding error handling
      +  let len = min(n, contents.len());
      +  let (chunk, rest) = contents.split_at(len);
      +  this.write(chunk  );            // eliding error handling
      +  contents = rest;
      +}
      +this.flush();
      +// Wait for completion of `flush`
      +poll-one(pollable);
      +// Check for any errors that arose during `flush`
      +let _ = this.check-write();         // eliding error handling
      +
      Params
      Return values
      -

      blocking-write: func

      -

      Write bytes to a stream, with blocking.

      -

      This is similar to write, except that it blocks until at least one -byte can be written.

      +

      [method]output-stream.flush: func

      +

      Request to flush buffered output. This function never blocks.

      +

      This tells the output-stream that the caller intends any buffered +output to be flushed. the output which is expected to be flushed +is all that has been passed to write prior to this call.

      +

      Upon calling this function, the output-stream will not accept any +writes (check-write will return ok(0)) until the flush has +completed. The subscribe pollable will become ready when the +flush has completed and the stream can accept more writes.

      Params
      Return values
      -

      write-zeroes: func

      -

      Write multiple zero bytes to a stream.

      -

      This function returns a u64 indicating the number of zero bytes -that were written; it may be less than len.

      +

      [method]output-stream.blocking-flush: func

      +

      Request to flush buffered output, and block until flush completes +and stream is ready for writing again.

      Params
      Return values
      -

      blocking-write-zeroes: func

      -

      Write multiple zero bytes to a stream, with blocking.

      -

      This is similar to write-zeroes, except that it blocks until at least -one byte can be written.

      +

      [method]output-stream.subscribe: func

      +

      Create a pollable which will resolve once the output-stream +is ready for more writing, or an error has occured. When this +pollable is ready, check-write will return ok(n) with n>0, or an +error.

      +

      If the stream is closed, this pollable is always ready immediately.

      +

      The created pollable is a child resource of the output-stream. +Implementations may trap if the output-stream is dropped before +all derived pollables created with this function are dropped.

      Params
      Return values
      -

      splice: func

      +

      [method]output-stream.write-zeroes: func

      +

      Write zeroes to a stream.

      +

      this should be used precisely like write with the exact same +preconditions (must use check-write first), but instead of +passing a list of bytes, you simply pass the number of zero-bytes +that should be written.

      +
      Params
      + +
      Return values
      + +

      [method]output-stream.blocking-write-zeroes-and-flush: func

      +

      Perform a write of up to 4096 zeroes, and then flush the stream. +Block until all of these operations are complete, or an error +occurs.

      +

      This is a convenience wrapper around the use of check-write, +subscribe, write-zeroes, and flush, and is implemented with +the following pseudo-code:

      +
      let pollable = this.subscribe();
      +while num_zeroes != 0 {
      +  // Wait for the stream to become writable
      +  poll-one(pollable);
      +  let Ok(n) = this.check-write(); // eliding error handling
      +  let len = min(n, num_zeroes);
      +  this.write-zeroes(len);         // eliding error handling
      +  num_zeroes -= len;
      +}
      +this.flush();
      +// Wait for completion of `flush`
      +poll-one(pollable);
      +// Check for any errors that arose during `flush`
      +let _ = this.check-write();         // eliding error handling
      +
      +
      Params
      + +
      Return values
      + +

      [method]output-stream.splice: func

      Read from one stream and write to another.

      This function returns the number of bytes transferred; it may be less than len.

      @@ -468,29 +523,29 @@ than len.

      read from the input stream has been written to the output stream.

      Params
      Return values
      -

      blocking-splice: func

      +

      [method]output-stream.blocking-splice: func

      Read from one stream and write to another, with blocking.

      -

      This is similar to splice, except that it blocks until at least +

      This is similar to splice, except that it blocks until at least one byte can be read.

      Params
      Return values
      -

      forward: func

      +

      [method]output-stream.forward: func

      Forward the entire contents of an input stream to an output stream.

      This function repeatedly reads from the input stream and writes the data to the output stream, until the end of the input stream @@ -498,33 +553,16 @@ is reached, or an error is encountered.

      Unlike other I/O functions, this function blocks until the end of the input stream is seen and all the data has been written to the output stream.

      -

      This function returns the number of bytes transferred.

      -
      Params
      - -
      Return values
      - -

      subscribe-to-output-stream: func

      -

      Create a pollable which will resolve once either the specified stream -is ready to accept bytes or the other end of the stream has been closed.

      +

      This function returns the number of bytes transferred, and the status of +the output stream.

      Params
      Return values
      -

      drop-output-stream: func

      -

      Dispose of the specified output-stream, after which it may no longer -be used.

      -
      Params
      -

      Import interface wasi:filesystem/types

      WASI filesystem is a filesystem API primarily intended to let users run WASI @@ -542,6 +580,8 @@ function starts with /, or if any step of resolving a path.. and symbolic link steps, reaches a directory outside of the base directory, or reaches a symlink to an absolute or rooted path in the underlying filesystem, the function fails with error-code::not-permitted.

      +

      For more information about WASI path resolution and sandboxing, see +WASI filesystem path resolution.


      Types

      type input-stream

      @@ -601,23 +641,14 @@ any of the other types specified.
      Flags members
      • -

        read:

        +

        read:

        Read mode: Data can be read.

      • -

        write:

        +

        write:

        Write mode: Data can be written to.

      • -

        non-blocking:

        -

        Requests non-blocking operation. -

        When this flag is enabled, functions may return immediately with an -error-code::would-block error code in situations where they would -otherwise block. However, this non-blocking behavior is not -required. Implementations are permitted to ignore this flag and -block. This is similar to O_NONBLOCK in POSIX.

        -
      • -
      • file-integrity-sync:

        Request that writes be performed according to synchronized I/O file integrity completion. The data stored in the file and the file's @@ -663,7 +694,7 @@ expanded.

      flags open-flags

      -

      Open flags used by open-at.

      +

      Open flags used by open-at.

      Flags members
      • @@ -684,7 +715,7 @@ expanded.

      flags modes

      -

      Permissions mode used by open-at, change-file-permissions-at, and +

      Permissions mode used by open-at, change-file-permissions-at, and similar.

      Flags members
        @@ -705,7 +736,7 @@ filesystem. This does not apply to directories.

      variant access-type

      -

      Access type used by access-at.

      +

      Access type used by access-at.

      Variant Cases

      variant new-timestamp

      @@ -973,12 +1010,6 @@ in the near future. not reuse it thereafter.
    -

    type descriptor

    -

    u32

    -

    A descriptor is a reference to a filesystem object, which may be a file, -directory, named pipe, special file, or other object on which filesystem -calls may be made. -

    This represents a resource.

    record metadata-hash-value

    A 128-bit hash value, split into parts because wasm doesn't have a 128-bit integer type.

    @@ -993,152 +1024,136 @@ calls may be made.

    Another 64 bits of a 128-bit hash value. -

    type directory-entry-stream

    -

    u32

    -

    A stream of directory entries. -

    This represents a stream of dir-entry.

    +

    resource descriptor

    +

    resource directory-entry-stream


    Functions

    -

    read-via-stream: func

    +

    [method]descriptor.read-via-stream: func

    Return a stream for reading from a file, if available.

    May fail with an error-code describing why the file cannot be read.

    Multiple read, write, and append streams may be active on the same open file and they do not interfere with each other.

    -

    Note: This allows using read-stream, which is similar to read in POSIX.

    +

    Note: This allows using read-stream, which is similar to read in POSIX.

    Params
    Return values
    -

    write-via-stream: func

    +

    [method]descriptor.write-via-stream: func

    Return a stream for writing to a file, if available.

    May fail with an error-code describing why the file cannot be written.

    -

    Note: This allows using write-stream, which is similar to write in +

    Note: This allows using write-stream, which is similar to write in POSIX.

    Params
    Return values
    -

    append-via-stream: func

    +

    [method]descriptor.append-via-stream: func

    Return a stream for appending to a file, if available.

    May fail with an error-code describing why the file cannot be appended.

    -

    Note: This allows using write-stream, which is similar to write with +

    Note: This allows using write-stream, which is similar to write with O_APPEND in in POSIX.

    Params
    Return values
    -

    advise: func

    +

    [method]descriptor.advise: func

    Provide file advisory information on a descriptor.

    This is similar to posix_fadvise in POSIX.

    Params
    Return values
    -

    sync-data: func

    +

    [method]descriptor.sync-data: func

    Synchronize the data of a file to disk.

    This function succeeds with no effect if the file descriptor is not opened for writing.

    Note: This is similar to fdatasync in POSIX.

    Params
    Return values
    -

    get-flags: func

    +

    [method]descriptor.get-flags: func

    Get flags associated with a descriptor.

    Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

    Note: This returns the value that was the fs_flags value returned from fdstat_get in earlier versions of WASI.

    Params
    Return values
    -

    get-type: func

    +

    [method]descriptor.get-type: func

    Get the dynamic type of a descriptor.

    Note: This returns the same value as the type field of the fd-stat -returned by stat, stat-at and similar.

    +returned by stat, stat-at and similar.

    Note: This returns similar flags to the st_mode & S_IFMT value provided by fstat in POSIX.

    Note: This returns the value that was the fs_filetype value returned from fdstat_get in earlier versions of WASI.

    Params
    Return values
    -

    set-flags: func

    -

    Set status flags associated with a descriptor.

    -

    This function may only change the non-blocking flag.

    -

    Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

    -

    Note: This was called fd_fdstat_set_flags in earlier versions of WASI.

    -
    Params
    - -
    Return values
    - -

    set-size: func

    +

    [method]descriptor.set-size: func

    Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.

    Note: This was called fd_filestat_set_size in earlier versions of WASI.

    Params
    Return values
    -

    set-times: func

    +

    [method]descriptor.set-times: func

    Adjust the timestamps of an open file or directory.

    Note: This is similar to futimens in POSIX.

    Note: This was called fd_filestat_set_times in earlier versions of WASI.

    Params
    Return values
    -

    read: func

    +

    [method]descriptor.read: func

    Read from a descriptor, without using and updating the descriptor's offset.

    This function returns a list of bytes containing the data that was read, along with a bool which, when true, indicates that the end of the @@ -1149,15 +1164,15 @@ if the I/O operation is interrupted.

    Note: This is similar to pread in POSIX.

    Params
    Return values
    -

    write: func

    +

    [method]descriptor.write: func

    Write to a descriptor, without using and updating the descriptor's offset.

    It is valid to write past the end of a file; the file is extended to the extent of the write, with bytes between the previous end and the start of @@ -1166,15 +1181,15 @@ the write set to zero.

    Note: This is similar to pwrite in POSIX.

    Params
    Return values
    -

    read-directory: func

    +

    [method]descriptor.read-directory: func

    Read directory entries from a directory.

    On filesystems where directories contain entries referring to themselves and their parents, often named . and .. respectively, these entries @@ -1184,102 +1199,102 @@ directory. Multiple streams may be active on the same directory, and they do not interfere with each other.

    Params
    Return values
    -

    sync: func

    +

    [method]descriptor.sync: func

    Synchronize the data and metadata of a file to disk.

    This function succeeds with no effect if the file descriptor is not opened for writing.

    Note: This is similar to fsync in POSIX.

    Params
    Return values
    -

    create-directory-at: func

    +

    [method]descriptor.create-directory-at: func

    Create a directory.

    Note: This is similar to mkdirat in POSIX.

    Params
    Return values
    -

    stat: func

    +

    [method]descriptor.stat: func

    Return the attributes of an open file or directory.

    Note: This is similar to fstat in POSIX, except that it does not return device and inode information. For testing whether two descriptors refer to -the same underlying filesystem object, use is-same-object. To obtain +the same underlying filesystem object, use is-same-object. To obtain additional data that can be used do determine whether a file has been -modified, use metadata-hash.

    +modified, use metadata-hash.

    Note: This was called fd_filestat_get in earlier versions of WASI.

    Params
    Return values
    -

    stat-at: func

    +

    [method]descriptor.stat-at: func

    Return the attributes of a file or directory.

    Note: This is similar to fstatat in POSIX, except that it does not -return device and inode information. See the stat description for a +return device and inode information. See the stat description for a discussion of alternatives.

    Note: This was called path_filestat_get in earlier versions of WASI.

    Params
    Return values
    -

    set-times-at: func

    +

    [method]descriptor.set-times-at: func

    Adjust the timestamps of a file or directory.

    Note: This is similar to utimensat in POSIX.

    Note: This was called path_filestat_set_times in earlier versions of WASI.

    Params
    Return values
    -

    link-at: func

    +

    [method]descriptor.link-at: func

    Create a hard link.

    Note: This is similar to linkat in POSIX.

    Params
    Return values
    -

    open-at: func

    +

    [method]descriptor.open-at: func

    Open a file or directory.

    The returned descriptor is not guaranteed to be the lowest-numbered descriptor not currently open/ it is randomized to prevent applications @@ -1288,82 +1303,82 @@ error-prone in multi-threaded contexts. The returned descriptor is guaranteed to be less than 2**31.

    If flags contains descriptor-flags::mutate-directory, and the base descriptor doesn't have descriptor-flags::mutate-directory set, -open-at fails with error-code::read-only.

    -

    If flags contains write or mutate-directory, or open-flags +open-at fails with error-code::read-only.

    +

    If flags contains write or mutate-directory, or open-flags contains truncate or create, and the base descriptor doesn't have -descriptor-flags::mutate-directory set, open-at fails with +descriptor-flags::mutate-directory set, open-at fails with error-code::read-only.

    Note: This is similar to openat in POSIX.

    Params
    Return values
    -

    readlink-at: func

    +

    [method]descriptor.readlink-at: func

    Read the contents of a symbolic link.

    If the contents contain an absolute or rooted path in the underlying filesystem, this function fails with error-code::not-permitted.

    Note: This is similar to readlinkat in POSIX.

    Params
    Return values
    -

    remove-directory-at: func

    +

    [method]descriptor.remove-directory-at: func

    Remove a directory.

    Return error-code::not-empty if the directory is not empty.

    Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

    Params
    Return values
    -

    rename-at: func

    +

    [method]descriptor.rename-at: func

    Rename a filesystem object.

    Note: This is similar to renameat in POSIX.

    Params
    Return values
    -

    symlink-at: func

    +

    [method]descriptor.symlink-at: func

    Create a symbolic link (also known as a "symlink").

    If old-path starts with /, the function fails with error-code::not-permitted.

    Note: This is similar to symlinkat in POSIX.

    Params
    Return values
    -

    access-at: func

    +

    [method]descriptor.access-at: func

    Check accessibility of a filesystem path.

    Check whether the given filesystem path names an object which is readable, writable, or executable, or whether it exists.

    @@ -1373,64 +1388,64 @@ entities.

    Note: This is similar to faccessat with the AT_EACCESS flag in POSIX.

    Params
    Return values
    -

    unlink-file-at: func

    +

    [method]descriptor.unlink-file-at: func

    Unlink a filesystem object that is not a directory.

    Return error-code::is-directory if the path refers to a directory. Note: This is similar to unlinkat(fd, path, 0) in POSIX.

    Params
    Return values
    -

    change-file-permissions-at: func

    +

    [method]descriptor.change-file-permissions-at: func

    Change the permissions of a filesystem object that is not a directory.

    Note that the ultimate meanings of these permissions is filesystem-specific.

    Note: This is similar to fchmodat in POSIX.

    Params
    Return values
    -

    change-directory-permissions-at: func

    +

    [method]descriptor.change-directory-permissions-at: func

    Change the permissions of a directory.

    Note that the ultimate meanings of these permissions is filesystem-specific.

    Unlike in POSIX, the executable flag is not reinterpreted as a "search" -flag. read on a directory implies readability and searchability, and +flag. read on a directory implies readability and searchability, and execute is not valid for directories.

    Note: This is similar to fchmodat in POSIX.

    Params
    Return values
    -

    lock-shared: func

    +

    [method]descriptor.lock-shared: func

    Request a shared advisory lock for an open file.

    This requests a shared lock; more than one shared lock can be held for a file at the same time.

    @@ -1446,13 +1461,13 @@ locking, this function returns error-cod

    Note: This is similar to flock(fd, LOCK_SH) in Unix.

    Params
    Return values
    -

    lock-exclusive: func

    +

    [method]descriptor.lock-exclusive: func

    Request an exclusive advisory lock for an open file.

    This requests an exclusive lock; no other locks may be held for the file while an exclusive lock is held.

    @@ -1470,13 +1485,13 @@ locking, this function returns error-cod

    Note: This is similar to flock(fd, LOCK_EX) in Unix.

    Params
    Return values
    -

    try-lock-shared: func

    +

    [method]descriptor.try-lock-shared: func

    Request a shared advisory lock for an open file.

    This requests a shared lock; more than one shared lock can be held for a file at the same time.

    @@ -1493,13 +1508,13 @@ locking, this function returns error-cod

    Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

    Params
    Return values
    -

    try-lock-exclusive: func

    +

    [method]descriptor.try-lock-exclusive: func

    Request an exclusive advisory lock for an open file.

    This requests an exclusive lock; no other locks may be held for the file while an exclusive lock is held.

    @@ -1518,48 +1533,24 @@ locking, this function returns error-cod

    Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

    Params
    Return values
    -

    unlock: func

    +

    [method]descriptor.unlock: func

    Release a shared or exclusive lock on an open file.

    Note: This is similar to flock(fd, LOCK_UN) in Unix.

    Params
    Return values
    -

    drop-descriptor: func

    -

    Dispose of the specified descriptor, after which it may no longer -be used.

    -
    Params
    - -

    read-directory-entry: func

    -

    Read a single directory entry from a directory-entry-stream.

    -
    Params
    - -
    Return values
    - -

    drop-directory-entry-stream: func

    -

    Dispose of the specified directory-entry-stream, after which it may no longer -be used.

    -
    Params
    - -

    is-same-object: func

    +

    [method]descriptor.is-same-object: func

    Test whether two descriptors refer to the same filesystem object.

    In POSIX, this corresponds to testing whether the two descriptors have the same device (st_dev) and inode (st_ino or d_ino) numbers. @@ -1567,14 +1558,14 @@ wasi-filesystem does not expose device and inode numbers, so this function may be used instead.

    Params
    Return values
      -
    • bool
    • +
    • bool
    -

    metadata-hash: func

    +

    [method]descriptor.metadata-hash: func

    Return a hash of the metadata associated with a filesystem object referred to by a descriptor.

    This returns a hash of the last-modification timestamp and file size, and @@ -1594,25 +1585,35 @@ computed hash.

    However, none of these is required.

    Params
    Return values
    -

    metadata-hash-at: func

    +

    [method]descriptor.metadata-hash-at: func

    Return a hash of the metadata associated with a filesystem object referred to by a directory descriptor and a relative path.

    -

    This performs the same hash computation as metadata-hash.

    +

    This performs the same hash computation as metadata-hash.

    +
    Params
    + +
    Return values
    + +

    [method]directory-entry-stream.read-directory-entry: func

    +

    Read a single directory entry from a directory-entry-stream.

    Params
    Return values

    Import interface wasi:filesystem/preopens


    @@ -1626,17 +1627,12 @@ to by a directory descriptor and a relative path.

    Return the set of preopened directories, and their path.

    Return values

    Import interface wasi:sockets/network


    Types

    -

    type network

    -

    u32

    -

    An opaque resource that represents access to (a subset of) the network. -This enables context-based security for networking. -There is no need for this to map 1:1 to a physical network interface. -

    FYI, In the future this will be replaced by handle types.

    +

    resource network

    enum error-code

    Error codes.

    In theory, every API can return any error code. @@ -1844,15 +1840,6 @@ combined with a couple of errors that are always possible:

  • ipv4: ipv4-socket-address
  • ipv6: ipv6-socket-address
  • -
    -

    Functions

    -

    drop-network: func

    -

    Dispose of the specified network, after which it may no longer be used.

    -

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    -
    Params
    -

    Import interface wasi:sockets/instance-network

    This interface provides a value-export of the default network handle..


    @@ -1866,7 +1853,7 @@ combined with a couple of errors that are always possible:

    Get a handle to the default network.

    Return values

    Import interface wasi:sockets/ip-name-lookup


    @@ -1886,10 +1873,8 @@ combined with a couple of errors that are always possible:

    #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `type resolve-address-stream` -`u32` -

    ----- +#### `resource resolve-address-stream` +


    Functions

    resolve-addresses: func

    Resolve an internet host name to a list of IP addresses.

    @@ -1898,7 +1883,7 @@ combined with a couple of errors that are always possible:

    • name: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted to ASCII using IDNA encoding.
    • -
    • address-family: If provided, limit the results to addresses of this specific address family.
    • +
    • address-family: If provided, limit the results to addresses of this specific address family.
    • include-unavailable: When set to true, this function will also return addresses of which the runtime thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on systems without an active IPv6 interface. Notes:
    • @@ -1908,12 +1893,12 @@ systems without an active IPv6 interface. Notes:

      This function never blocks. It either immediately fails or immediately returns successfully with a resolve-address-stream that can be used to (asynchronously) fetch the results.

      At the moment, the stream never completes successfully with 0 items. Ie. the first call -to resolve-next-address never returns ok(none). This may change in the future.

      +to resolve-next-address never returns ok(none). This may change in the future.

      Typical errors

      • invalid-name: name is a syntactically invalid domain name.
      • invalid-name: name is an IP address.
      • -
      • address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)
      • +
      • address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)

      References:

      Params
      Return values
      -

      resolve-next-address: func

      +

      [method]resolve-address-stream.resolve-next-address: func

      Returns the next address from the resolver.

      This function should be called multiple times. On each call, it will return the next address in connection order preference. If all -addresses have been exhausted, this function returns none. -After which, you should release the stream with drop-resolve-address-stream.

      +addresses have been exhausted, this function returns none.

      This function never returns IPv4-mapped IPv6 addresses.

      Typical errors

      Return values
      -

      drop-resolve-address-stream: func

      -

      Dispose of the specified resolve-address-stream, after which it may no longer be used.

      -

      Note: this function is scheduled to be removed when Resources are natively supported in Wit.

      -
      Params
      - -

      subscribe: func

      +

      [method]resolve-address-stream.subscribe: func

      Create a pollable which will resolve once the stream is ready for I/O.

      Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

      Params
      Return values

      Import interface wasi:sockets/tcp


      @@ -1998,18 +1975,15 @@ It's planned to be removed when future is natively supported in Pre #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

      -#### `type tcp-socket` -`u32` -

      A TCP socket handle. -

      enum shutdown-type

      +#### `enum shutdown-type`
      Enum Cases
      • -

        receive

        +

        receive

        Similar to `SHUT_RD` in POSIX.

      • -

        send

        +

        send

        Similar to `SHUT_WR` in POSIX.

      • @@ -2017,9 +1991,10 @@ It's planned to be removed when future is natively supported in Pre

        Similar to `SHUT_RDWR` in POSIX.

      +

      resource tcp-socket


      Functions

      -

      start-bind: func

      +

      [method]tcp-socket.start-bind: func

      Bind the socket to a specific network on the provided IP address and port.

      If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -2029,7 +2004,7 @@ implicitly bind the socket.

      Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

      Typical start errors

        -
      • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
      • +
      • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
      • already-bound: The socket is already bound. (EINVAL)
      • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
      @@ -2037,7 +2012,7 @@ implicitly bind the socket.

      • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
      • address-in-use: Address is already in use. (EADDRINUSE)
      • -
      • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
      • +
      • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
      • not-in-progress: A bind operation is not in progress.
      • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
      @@ -2050,24 +2025,24 @@ implicitly bind the socket.

    Params
    Return values
    -

    finish-bind: func

    +

    [method]tcp-socket.finish-bind: func

    Params
    Return values
    -

    start-connect: func

    +

    [method]tcp-socket.start-connect: func

    Connect to a remote endpoint.

    On success:

      @@ -2076,9 +2051,9 @@ implicitly bind the socket.

    Typical start errors

      -
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • -
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
    • -
    • invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
    • +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
    • already-attached: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
    • already-connected: The socket is already in the Connection state. (EISCONN)
    • already-listening: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
    • @@ -2103,24 +2078,24 @@ implicitly bind the socket.

    Params
    Return values
    -

    finish-connect: func

    +

    [method]tcp-socket.finish-connect: func

    Params
    Return values
    -

    start-listen: func

    +

    [method]tcp-socket.start-listen: func

    Start listening for new connections.

    Transitions the socket into the Listener state.

    Unlike POSIX:

    @@ -2150,22 +2125,22 @@ implicitly bind the socket.

    Params
    Return values
    -

    finish-listen: func

    +

    [method]tcp-socket.finish-listen: func

    Params
    Return values
    -

    accept: func

    +

    [method]tcp-socket.accept: func

    Accept a new client socket.

    The returned socket is bound and in the Connection state.

    On success, this function returns the newly accepted client socket along with @@ -2185,13 +2160,13 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    local-address: func

    +

    [method]tcp-socket.local-address: func

    Get the bound local address.

    Typical errors

      @@ -2206,13 +2181,13 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    remote-address: func

    +

    [method]tcp-socket.remote-address: func

    Get the bound remote address.

    Typical errors

      @@ -2227,24 +2202,24 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    address-family: func

    +

    [method]tcp-socket.address-family: func

    Whether this is a IPv4 or IPv6 socket.

    Equivalent to the SO_DOMAIN socket option.

    Params
    Return values
    -

    ipv6-only: func

    +

    [method]tcp-socket.ipv6-only: func

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    Equivalent to the IPV6_V6ONLY socket option.

    Typical errors

    @@ -2256,23 +2231,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-ipv6-only: func

    +

    [method]tcp-socket.set-ipv6-only: func

    Params
    Return values
    -

    set-listen-backlog-size: func

    +

    [method]tcp-socket.set-listen-backlog-size: func

    Hints the desired listen queue size. Implementations are free to ignore this.

    Typical errors

      @@ -2281,14 +2256,14 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    keep-alive: func

    +

    [method]tcp-socket.keep-alive: func

    Equivalent to the SO_KEEPALIVE socket option.

    Typical errors

      @@ -2296,23 +2271,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-keep-alive: func

    +

    [method]tcp-socket.set-keep-alive: func

    Params
    Return values
    -

    no-delay: func

    +

    [method]tcp-socket.no-delay: func

    Equivalent to the TCP_NODELAY socket option.

    Typical errors

      @@ -2320,23 +2295,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-no-delay: func

    +

    [method]tcp-socket.set-no-delay: func

    Params
    Return values
    -

    unicast-hop-limit: func

    +

    [method]tcp-socket.unicast-hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    Typical errors

      @@ -2346,23 +2321,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-unicast-hop-limit: func

    +

    [method]tcp-socket.set-unicast-hop-limit: func

    Params
    Return values
    -

    receive-buffer-size: func

    +

    [method]tcp-socket.receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    Note #1: an implementation may choose to cap or round the buffer size when setting the value. In other words, after setting a value, reading the same setting back may return a different value.

    @@ -2378,59 +2353,59 @@ for internal metadata structures.

    Params
    Return values
    -

    set-receive-buffer-size: func

    +

    [method]tcp-socket.set-receive-buffer-size: func

    Params
    Return values
    -

    send-buffer-size: func

    +

    [method]tcp-socket.send-buffer-size: func

    Params
    Return values
    -

    set-send-buffer-size: func

    +

    [method]tcp-socket.set-send-buffer-size: func

    Params
    Return values
    -

    subscribe: func

    +

    [method]tcp-socket.subscribe: func

    Create a pollable which will resolve once the socket is ready for I/O.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    shutdown: func

    +

    [method]tcp-socket.shutdown: func

    Initiate a graceful shutdown.

    • receive: the socket is not expecting to receive any more data from the peer. All subsequent read operations on the input-stream associated with this socket will return an End Of Stream indication. -Any data still in the receive queue at time of calling shutdown will be discarded.
    • +Any data still in the receive queue at time of calling shutdown will be discarded.
    • send: the socket is not expecting to send any more data to the peer. All subsequent write operations on the output-stream associated with this socket will return an error.
    • both: same effect as receive & send combined.
    • @@ -2449,20 +2424,12 @@ operations on the output-stream associ
    Params
    Return values
    -

    drop-tcp-socket: func

    -

    Dispose of the specified tcp-socket, after which it may no longer be used.

    -

    Similar to the POSIX close function.

    -

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    -
    Params
    -

    Import interface wasi:sockets/tcp-create-socket


    @@ -2491,7 +2458,7 @@ is called, the socket is effectively an in-memory configuration object, unable t

    Typical errors

    • not-supported: The host does not support TCP sockets. (EOPNOTSUPP)
    • -
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • +
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)

    References

    @@ -2503,11 +2470,11 @@ is called, the socket is effectively an in-memory configuration object, unable t
    Params
    Return values

    Import interface wasi:sockets/udp


    @@ -2527,18 +2494,16 @@ is called, the socket is effectively an in-memory configuration object, unable t #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `type udp-socket` -`u32` -

    A UDP socket handle. -

    record datagram

    +#### `record datagram`
    Record Fields
    +

    resource udp-socket


    Functions

    -

    start-bind: func

    +

    [method]udp-socket.start-bind: func

    Bind the socket to a specific network on the provided IP address and port.

    If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -2547,7 +2512,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    Typical start errors

      -
    • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
    • +
    • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
    • already-bound: The socket is already bound. (EINVAL)
    • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
    @@ -2555,7 +2520,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
    • address-in-use: Address is already in use. (EADDRINUSE)
    • -
    • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
    • +
    • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
    • not-in-progress: A bind operation is not in progress.
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    @@ -2568,38 +2533,38 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    Params
    Return values
    -

    finish-bind: func

    +

    [method]udp-socket.finish-bind: func

    Params
    Return values
    -

    start-connect: func

    +

    [method]udp-socket.start-connect: func

    Set the destination address.

    -

    The local-address is updated based on the best network path to remote-address.

    +

    The local-address is updated based on the best network path to remote-address.

    When a destination address is set:

      -
    • all receive operations will only return datagrams sent from the provided remote-address.
    • -
    • the send function can only be used to send to this destination.
    • +
    • all receive operations will only return datagrams sent from the provided remote-address.
    • +
    • the send function can only be used to send to this destination.

    Note that this function does not generate any network traffic and the peer is not aware of this "connection".

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    Typical start errors

      -
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • -
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • -
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • already-attached: The socket is already bound to a different network. The network passed to connect must be identical to the one passed to bind.
    • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
    @@ -2618,24 +2583,24 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    Params
    Return values
    -

    finish-connect: func

    +

    [method]udp-socket.finish-connect: func

    Params
    Return values
    -

    receive: func

    +

    [method]udp-socket.receive: func

    Receive messages on the socket.

    This function attempts to receive up to max-results datagrams on the socket without blocking. The returned list may contain fewer elements than requested, but never more. @@ -2659,14 +2624,14 @@ If max-results is 0, this function returns successfully with an emp

    Params
    Return values
    -

    send: func

    +

    [method]udp-socket.send: func

    Send messages on the socket.

    This function attempts to send all provided datagrams on the socket without blocking and returns how many messages were actually sent (or queued for sending).

    @@ -2675,12 +2640,12 @@ sending each individual datagram until either the end of the list has been reach If at least one datagram has been sent successfully, this function never returns an error.

    If the input list is empty, the function returns ok(0).

    The remote address option is required. To send a message to the "connected" peer, -call remote-address to get their address.

    +call remote-address to get their address.

    Typical errors

      -
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • -
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • -
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • already-connected: The socket is in "connected" mode and the datagram.remote-address does not match the address passed to connect. (EISCONN)
    • not-bound: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind.
    • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
    • @@ -2700,14 +2665,14 @@ call remote-address to get their addr
    Params
    Return values
    -

    local-address: func

    +

    [method]udp-socket.local-address: func

    Get the current bound address.

    Typical errors

    Params
    Return values
    -

    remote-address: func

    +

    [method]udp-socket.remote-address: func

    Get the address set with connect.

    Typical errors

    Params
    Return values
    -

    address-family: func

    +

    [method]udp-socket.address-family: func

    Whether this is a IPv4 or IPv6 socket.

    Equivalent to the SO_DOMAIN socket option.

    Params
    Return values
    -

    ipv6-only: func

    +

    [method]udp-socket.ipv6-only: func

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    Equivalent to the IPV6_V6ONLY socket option.

    Typical errors

    @@ -2772,23 +2737,23 @@ call remote-address to get their addr
    Params
    Return values
    -

    set-ipv6-only: func

    +

    [method]udp-socket.set-ipv6-only: func

    Params
    Return values
    -

    unicast-hop-limit: func

    +

    [method]udp-socket.unicast-hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    Typical errors

    Params
    Return values
    -

    set-unicast-hop-limit: func

    +

    [method]udp-socket.set-unicast-hop-limit: func

    Params
    Return values
    -

    receive-buffer-size: func

    +

    [method]udp-socket.receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    Note #1: an implementation may choose to cap or round the buffer size when setting the value. In other words, after setting a value, reading the same setting back may return a different value.

    Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of actual data to be sent/received by the application, because the kernel might also use the buffer space for internal metadata structures.

    -

    Fails when this socket is in the Listening state.

    Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

    Typical errors

      @@ -2827,59 +2791,52 @@ for internal metadata structures.

    Params
    Return values
    -

    set-receive-buffer-size: func

    +

    [method]udp-socket.set-receive-buffer-size: func

    Params
    Return values
    -

    send-buffer-size: func

    +

    [method]udp-socket.send-buffer-size: func

    Params
    Return values
    -

    set-send-buffer-size: func

    +

    [method]udp-socket.set-send-buffer-size: func

    Params
    Return values
    -

    subscribe: func

    +

    [method]udp-socket.subscribe: func

    Create a pollable which will resolve once the socket is ready for I/O.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    drop-udp-socket: func

    -

    Dispose of the specified udp-socket, after which it may no longer be used.

    -

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    -
    Params
    -

    Import interface wasi:sockets/udp-create-socket


    @@ -2908,7 +2865,7 @@ the socket is effectively an in-memory configuration object, unable to communica

    Typical errors

    • not-supported: The host does not support UDP sockets. (EOPNOTSUPP)
    • -
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • +
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)

    References:

    @@ -2920,11 +2877,11 @@ the socket is effectively an in-memory configuration object, unable to communica
    Params
    Return values

    Import interface wasi:random/random

    WASI Random is a random data API.

    @@ -3059,7 +3016,7 @@ directory, interpreting . as shorthand for this.

    get-stdin: func

    Return values

    Import interface wasi:cli/stdout


    @@ -3072,7 +3029,7 @@ directory, interpreting . as shorthand for this.

    get-stdout: func

    Return values

    Import interface wasi:cli/stderr


    @@ -3085,40 +3042,16 @@ directory, interpreting . as shorthand for this.

    get-stderr: func

    Return values

    Import interface wasi:cli/terminal-input


    Types

    -

    type terminal-input

    -

    u32

    -

    The input side of a terminal. -

    This represents a resource.

    -
    -

    Functions

    -

    drop-terminal-input: func

    -

    Dispose of the specified terminal-input after which it may no longer -be used.

    -
    Params
    - +

    resource terminal-input

    Import interface wasi:cli/terminal-output


    Types

    -

    type terminal-output

    -

    u32

    -

    The output side of a terminal. -

    This represents a resource.

    -
    -

    Functions

    -

    drop-terminal-output: func

    -

    Dispose of the specified terminal-output, after which it may no longer -be used.

    -
    Params
    - +

    resource terminal-output

    Import interface wasi:cli/terminal-stdin

    An interface providing an optional terminal-input for stdin as a link-time authority.

    @@ -3134,7 +3067,7 @@ link-time authority.

    allowing further interaction with it.

    Return values

    Import interface wasi:cli/terminal-stdout

    An interface providing an optional terminal-output for stdout as a @@ -3151,7 +3084,7 @@ link-time authority.

    allowing further interaction with it.

    Return values

    Import interface wasi:cli/terminal-stderr

    An interface providing an optional terminal-output for stderr as a @@ -3168,7 +3101,7 @@ link-time authority.

    allowing further interaction with it.

    Return values

    Export interface wasi:cli/run


    diff --git a/proposals/cli/reactor.md b/proposals/cli/reactor.md index 6e0f5b7fd..ccba58da4 100644 --- a/proposals/cli/reactor.md +++ b/proposals/cli/reactor.md @@ -3,7 +3,7 @@
  • Imports: -

    Import interface wasi:poll/poll

    +

    Import interface wasi:io/poll

    A poll API intended to let users wait for I/O events on multiple handles at once.


    Types

    -

    type pollable

    -

    u32

    -

    A "pollable" handle. -

    This is conceptually represents a stream<_, _>, or in other words, -a stream that one can wait on, repeatedly, but which does not itself -produce any data. It's temporary scaffolding until component-model's -async features are ready.

    -

    And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

    -

    pollable lifetimes are not automatically managed. Users must ensure -that they do not outlive the resource they reference.

    -

    This represents a resource.

    +

    resource pollable


    Functions

    -

    drop-pollable: func

    -

    Dispose of the specified pollable, after which it may no longer -be used.

    -
    Params
    - -

    poll-oneoff: func

    +

    poll-list: func

    Poll for completion on a set of pollables.

    This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

    -

    The result list<bool> is the same length as the argument -list<pollable>, and indicates the readiness of each corresponding -element in that list, with true indicating ready. A single call can -return multiple true elements.

    +

    The result list<u32> contains one or more indices of handles in the +argument list that is ready for I/O.

    +

    If the list contains more elements than can be indexed with a u32 +value, this function traps.

    A timeout can be implemented by adding a pollable from the wasi-clocks API to the list.

    This function does not return a result; polling in itself does not do any I/O so it doesn't fail. If any of the I/O sources identified by the pollables has an error, it is indicated by marking the source as -ready in the list<bool>.

    -

    The "oneoff" in the name refers to the fact that this function must do a -linear scan through the entire list of subscriptions, which may be -inefficient if the number is large and the same subscriptions are used -many times. In the future, this is expected to be obsoleted by the -component model async proposal, which will include a scalable waiting -facility.

    +being reaedy for I/O.

    Params
    Return values
      -
    • list<bool>
    • +
    • list<u32>
    • +
    +

    poll-one: func

    +

    Poll for completion on a single pollable.

    +

    This function is similar to poll-list, but operates on only a single +pollable. When it returns, the handle is ready for I/O.

    +
    Params
    +

    Import interface wasi:clocks/monotonic-clock

    WASI Monotonic Clock is a clock API intended to let users measure elapsed @@ -169,7 +153,7 @@ reached.

    Return values

    Import interface wasi:clocks/timezone


    @@ -177,16 +161,9 @@ reached.

    type datetime

    datetime

    -#### `type timezone` -`u32` -

    A timezone. -

    In timezones that recognize daylight saving time, also known as daylight -time and summer time, the information returned from the functions varies -over time to reflect these adjustments.

    -

    This represents a resource.

    -

    record timezone-display

    +#### `record timezone-display`

    Information useful for displaying the timezone of a specific datetime.

    -

    This information may vary within a single timezone to reflect daylight +

    This information may vary within a single timezone to reflect daylight saving time adjustments.

    Record Fields
      @@ -227,7 +204,6 @@ daylight saving time is active.

      saving time.

      Params
      Return values
      @@ -238,20 +214,12 @@ saving time.

      The same as display, but only return the UTC offset.

      Params
      Return values
      • s32
      -

      drop-timezone: func

      -

      Dispose of the specified input-stream, after which it may no longer -be used.

      -
      Params
      -

      Import interface wasi:io/streams

      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

      @@ -262,11 +230,7 @@ when it does, they are expected to subsume this API.

      type pollable

      pollable

      -#### `record stream-error` -

      An error type returned from a stream operation. Currently this -doesn't provide any additional information.

      -
      Record Fields
      -

      enum stream-status

      +#### `enum stream-status`

      Streams provide a sequence of data and then end; once they end, they no longer provide any further data.

      For example, a stream reading from a file ends when the stream reaches @@ -280,182 +244,273 @@ socket ends when the socket is closed.

    • ended

      -

      The stream has ended and will not produce any further data. +

      When reading, this indicates that the stream will not produce +further data. +When writing, this indicates that the stream will no longer be read. +Further writes are still permitted.

    -

    type input-stream

    -

    u32

    -

    An input bytestream. In the future, this will be replaced by handle -types. -

    This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

    -

    input-streams are non-blocking to the extent practical on underlying -platforms. I/O operations always return promptly; if fewer bytes are -promptly available than requested, they return the number of bytes promptly -available, which could even be zero. To wait for data to be available, -use the subscribe-to-input-stream function to obtain a pollable which -can be polled for using wasi_poll.

    -

    And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

    -

    This represents a resource.

    -

    type output-stream

    -

    u32

    -

    An output bytestream. In the future, this will be replaced by handle -types. -

    This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

    -

    output-streams are non-blocking to the extent practical on -underlying platforms. Except where specified otherwise, I/O operations also -always return promptly, after the number of bytes that can be written -promptly, which could even be zero. To wait for the stream to be ready to -accept data, the subscribe-to-output-stream function to obtain a -pollable which can be polled for using wasi_poll.

    -

    And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

    -

    This represents a resource.

    +

    resource input-stream

    +

    enum write-error

    +

    An error for output-stream operations.

    +

    Contrary to input-streams, a closed output-stream is reported using +an error.

    +
    Enum Cases
    +
      +
    • +

      last-operation-failed

      +

      The last operation (a write or flush) failed before completion. +

    • +
    • +

      closed

      +

      The stream is closed: no more input will be accepted by the +stream. A closed output-stream will return this error on all +future operations. +

    • +
    +

    resource output-stream


    Functions

    -

    read: func

    -

    Read bytes from a stream.

    +

    [method]input-stream.read: func

    +

    Perform a non-blocking read from the stream.

    This function returns a list of bytes containing the data that was -read, along with a stream-status which indicates whether the end of -the stream was reached. The returned list will contain up to len -bytes; it may return fewer than requested, but not more.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more +read, along with a stream-status which, indicates whether further +reads are expected to produce data. The returned list will contain up to +len bytes; it may return fewer than requested, but not more. An +empty list and stream-status:open indicates no more data is +available at this time, and that the pollable given by subscribe +will be ready when more data is available.

    +

    Once a stream has reached the end, subsequent calls to read or +skip will always report stream-status:ended rather than producing more data.

    -

    If len is 0, it represents a request to read 0 bytes, which should -always succeed, assuming the stream hasn't reached its end yet, and -return an empty list.

    -

    The len here is a u64, but some callees may not be able to allocate -a buffer as large as that would imply. -FIXME: describe what happens if allocation fails.

    +

    When the caller gives a len of 0, it represents a request to read 0 +bytes. This read should always succeed and return an empty list and +the current stream-status.

    +

    The len parameter is a u64, which could represent a list of u8 which +is not possible to allocate in wasm32, or not desirable to allocate as +as a return value by the callee. The callee may return a list of bytes +less than len in size while more bytes are available for reading.

    Params
    Return values
    -

    blocking-read: func

    -

    Read bytes from a stream, with blocking.

    -

    This is similar to read, except that it blocks until at least one -byte can be read.

    +

    [method]input-stream.blocking-read: func

    +

    Read bytes from a stream, after blocking until at least one byte can +be read. Except for blocking, identical to read.

    Params
    Return values
    -

    skip: func

    +

    [method]input-stream.skip: func

    Skip bytes from a stream.

    -

    This is similar to the read function, but avoids copying the +

    This is similar to the read function, but avoids copying the bytes into the instance.

    Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more +skip will always report end-of-stream rather than producing more data.

    This function returns the number of bytes skipped, along with a stream-status indicating whether the end of the stream was reached. The returned value will be at most len; it may be less.

    Params
    Return values
    -

    blocking-skip: func

    -

    Skip bytes from a stream, with blocking.

    -

    This is similar to skip, except that it blocks until at least one -byte can be consumed.

    +

    [method]input-stream.blocking-skip: func

    +

    Skip bytes from a stream, after blocking until at least one byte +can be skipped. Except for blocking behavior, identical to skip.

    Params
    Return values
    -

    subscribe-to-input-stream: func

    +

    [method]input-stream.subscribe: func

    Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been -closed.

    +closed. +The created pollable is a child resource of the input-stream. +Implementations may trap if the input-stream is dropped before +all derived pollables created with this function are dropped.

    Params
    Return values
    -

    drop-input-stream: func

    -

    Dispose of the specified input-stream, after which it may no longer -be used.

    +

    [method]output-stream.check-write: func

    +

    Check readiness for writing. This function never blocks.

    +

    Returns the number of bytes permitted for the next call to write, +or an error. Calling write with more bytes than this function has +permitted will trap.

    +

    When this function returns 0 bytes, the subscribe pollable will +become ready when this function will report at least 1 byte, or an +error.

    Params
    +
    Return values
    + +

    [method]output-stream.write: func

    +

    Perform a write. This function never blocks.

    +

    Precondition: check-write gave permit of Ok(n) and contents has a +length of less than or equal to n. Otherwise, this function will trap.

    +

    returns Err(closed) without writing if the stream has closed since +the last call to check-write provided a permit.

    +
    Params
    + +
    Return values
    + -

    write: func

    -

    Write bytes to a stream.

    -

    This function returns a u64 indicating the number of bytes from -buf that were written; it may be less than the full list.

    +

    [method]output-stream.blocking-write-and-flush: func

    +

    Perform a write of up to 4096 bytes, and then flush the stream. Block +until all of these operations are complete, or an error occurs.

    +

    This is a convenience wrapper around the use of check-write, +subscribe, write, and flush, and is implemented with the +following pseudo-code:

    +
    let pollable = this.subscribe();
    +while !contents.is_empty() {
    +  // Wait for the stream to become writable
    +  poll-one(pollable);
    +  let Ok(n) = this.check-write(); // eliding error handling
    +  let len = min(n, contents.len());
    +  let (chunk, rest) = contents.split_at(len);
    +  this.write(chunk  );            // eliding error handling
    +  contents = rest;
    +}
    +this.flush();
    +// Wait for completion of `flush`
    +poll-one(pollable);
    +// Check for any errors that arose during `flush`
    +let _ = this.check-write();         // eliding error handling
    +
    Params
    Return values
    -

    blocking-write: func

    -

    Write bytes to a stream, with blocking.

    -

    This is similar to write, except that it blocks until at least one -byte can be written.

    +

    [method]output-stream.flush: func

    +

    Request to flush buffered output. This function never blocks.

    +

    This tells the output-stream that the caller intends any buffered +output to be flushed. the output which is expected to be flushed +is all that has been passed to write prior to this call.

    +

    Upon calling this function, the output-stream will not accept any +writes (check-write will return ok(0)) until the flush has +completed. The subscribe pollable will become ready when the +flush has completed and the stream can accept more writes.

    Params
    Return values
    -

    write-zeroes: func

    -

    Write multiple zero bytes to a stream.

    -

    This function returns a u64 indicating the number of zero bytes -that were written; it may be less than len.

    +

    [method]output-stream.blocking-flush: func

    +

    Request to flush buffered output, and block until flush completes +and stream is ready for writing again.

    Params
    Return values
    -

    blocking-write-zeroes: func

    -

    Write multiple zero bytes to a stream, with blocking.

    -

    This is similar to write-zeroes, except that it blocks until at least -one byte can be written.

    +

    [method]output-stream.subscribe: func

    +

    Create a pollable which will resolve once the output-stream +is ready for more writing, or an error has occured. When this +pollable is ready, check-write will return ok(n) with n>0, or an +error.

    +

    If the stream is closed, this pollable is always ready immediately.

    +

    The created pollable is a child resource of the output-stream. +Implementations may trap if the output-stream is dropped before +all derived pollables created with this function are dropped.

    Params
    Return values
    -

    splice: func

    +

    [method]output-stream.write-zeroes: func

    +

    Write zeroes to a stream.

    +

    this should be used precisely like write with the exact same +preconditions (must use check-write first), but instead of +passing a list of bytes, you simply pass the number of zero-bytes +that should be written.

    +
    Params
    + +
    Return values
    + +

    [method]output-stream.blocking-write-zeroes-and-flush: func

    +

    Perform a write of up to 4096 zeroes, and then flush the stream. +Block until all of these operations are complete, or an error +occurs.

    +

    This is a convenience wrapper around the use of check-write, +subscribe, write-zeroes, and flush, and is implemented with +the following pseudo-code:

    +
    let pollable = this.subscribe();
    +while num_zeroes != 0 {
    +  // Wait for the stream to become writable
    +  poll-one(pollable);
    +  let Ok(n) = this.check-write(); // eliding error handling
    +  let len = min(n, num_zeroes);
    +  this.write-zeroes(len);         // eliding error handling
    +  num_zeroes -= len;
    +}
    +this.flush();
    +// Wait for completion of `flush`
    +poll-one(pollable);
    +// Check for any errors that arose during `flush`
    +let _ = this.check-write();         // eliding error handling
    +
    +
    Params
    + +
    Return values
    + +

    [method]output-stream.splice: func

    Read from one stream and write to another.

    This function returns the number of bytes transferred; it may be less than len.

    @@ -463,29 +518,29 @@ than len.

    read from the input stream has been written to the output stream.

    Params
    Return values
    -

    blocking-splice: func

    +

    [method]output-stream.blocking-splice: func

    Read from one stream and write to another, with blocking.

    -

    This is similar to splice, except that it blocks until at least +

    This is similar to splice, except that it blocks until at least one byte can be read.

    Params
    Return values
    -

    forward: func

    +

    [method]output-stream.forward: func

    Forward the entire contents of an input stream to an output stream.

    This function repeatedly reads from the input stream and writes the data to the output stream, until the end of the input stream @@ -493,33 +548,16 @@ is reached, or an error is encountered.

    Unlike other I/O functions, this function blocks until the end of the input stream is seen and all the data has been written to the output stream.

    -

    This function returns the number of bytes transferred.

    -
    Params
    - -
    Return values
    - -

    subscribe-to-output-stream: func

    -

    Create a pollable which will resolve once either the specified stream -is ready to accept bytes or the other end of the stream has been closed.

    +

    This function returns the number of bytes transferred, and the status of +the output stream.

    Params
    Return values
    -

    drop-output-stream: func

    -

    Dispose of the specified output-stream, after which it may no longer -be used.

    -
    Params
    -

    Import interface wasi:filesystem/types

    WASI filesystem is a filesystem API primarily intended to let users run WASI @@ -537,6 +575,8 @@ function starts with /, or if any step of resolving a path.. and symbolic link steps, reaches a directory outside of the base directory, or reaches a symlink to an absolute or rooted path in the underlying filesystem, the function fails with error-code::not-permitted.

    +

    For more information about WASI path resolution and sandboxing, see +WASI filesystem path resolution.


    Types

    type input-stream

    @@ -596,23 +636,14 @@ any of the other types specified.
    Flags members
    • -

      read:

      +

      read:

      Read mode: Data can be read.

    • -

      write:

      +

      write:

      Write mode: Data can be written to.

    • -

      non-blocking:

      -

      Requests non-blocking operation. -

      When this flag is enabled, functions may return immediately with an -error-code::would-block error code in situations where they would -otherwise block. However, this non-blocking behavior is not -required. Implementations are permitted to ignore this flag and -block. This is similar to O_NONBLOCK in POSIX.

      -
    • -
    • file-integrity-sync:

      Request that writes be performed according to synchronized I/O file integrity completion. The data stored in the file and the file's @@ -658,7 +689,7 @@ expanded.

    flags open-flags

    -

    Open flags used by open-at.

    +

    Open flags used by open-at.

    Flags members
    • @@ -679,7 +710,7 @@ expanded.

    flags modes

    -

    Permissions mode used by open-at, change-file-permissions-at, and +

    Permissions mode used by open-at, change-file-permissions-at, and similar.

    Flags members
      @@ -700,7 +731,7 @@ filesystem. This does not apply to directories.

    variant access-type

    -

    Access type used by access-at.

    +

    Access type used by access-at.

    Variant Cases

    variant new-timestamp

    @@ -968,12 +1005,6 @@ in the near future. not reuse it thereafter.
  • -

    type descriptor

    -

    u32

    -

    A descriptor is a reference to a filesystem object, which may be a file, -directory, named pipe, special file, or other object on which filesystem -calls may be made. -

    This represents a resource.

    record metadata-hash-value

    A 128-bit hash value, split into parts because wasm doesn't have a 128-bit integer type.

    @@ -988,152 +1019,136 @@ calls may be made.

    Another 64 bits of a 128-bit hash value. -

    type directory-entry-stream

    -

    u32

    -

    A stream of directory entries. -

    This represents a stream of dir-entry.

    +

    resource descriptor

    +

    resource directory-entry-stream


    Functions

    -

    read-via-stream: func

    +

    [method]descriptor.read-via-stream: func

    Return a stream for reading from a file, if available.

    May fail with an error-code describing why the file cannot be read.

    Multiple read, write, and append streams may be active on the same open file and they do not interfere with each other.

    -

    Note: This allows using read-stream, which is similar to read in POSIX.

    +

    Note: This allows using read-stream, which is similar to read in POSIX.

    Params
    Return values
    -

    write-via-stream: func

    +

    [method]descriptor.write-via-stream: func

    Return a stream for writing to a file, if available.

    May fail with an error-code describing why the file cannot be written.

    -

    Note: This allows using write-stream, which is similar to write in +

    Note: This allows using write-stream, which is similar to write in POSIX.

    Params
    Return values
    -

    append-via-stream: func

    +

    [method]descriptor.append-via-stream: func

    Return a stream for appending to a file, if available.

    May fail with an error-code describing why the file cannot be appended.

    -

    Note: This allows using write-stream, which is similar to write with +

    Note: This allows using write-stream, which is similar to write with O_APPEND in in POSIX.

    Params
    Return values
    -

    advise: func

    +

    [method]descriptor.advise: func

    Provide file advisory information on a descriptor.

    This is similar to posix_fadvise in POSIX.

    Params
    Return values
    -

    sync-data: func

    +

    [method]descriptor.sync-data: func

    Synchronize the data of a file to disk.

    This function succeeds with no effect if the file descriptor is not opened for writing.

    Note: This is similar to fdatasync in POSIX.

    Params
    Return values
    -

    get-flags: func

    +

    [method]descriptor.get-flags: func

    Get flags associated with a descriptor.

    Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

    Note: This returns the value that was the fs_flags value returned from fdstat_get in earlier versions of WASI.

    Params
    Return values
    -

    get-type: func

    +

    [method]descriptor.get-type: func

    Get the dynamic type of a descriptor.

    Note: This returns the same value as the type field of the fd-stat -returned by stat, stat-at and similar.

    +returned by stat, stat-at and similar.

    Note: This returns similar flags to the st_mode & S_IFMT value provided by fstat in POSIX.

    Note: This returns the value that was the fs_filetype value returned from fdstat_get in earlier versions of WASI.

    Params
    Return values
    -

    set-flags: func

    -

    Set status flags associated with a descriptor.

    -

    This function may only change the non-blocking flag.

    -

    Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

    -

    Note: This was called fd_fdstat_set_flags in earlier versions of WASI.

    -
    Params
    - -
    Return values
    - -

    set-size: func

    +

    [method]descriptor.set-size: func

    Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.

    Note: This was called fd_filestat_set_size in earlier versions of WASI.

    Params
    Return values
    -

    set-times: func

    +

    [method]descriptor.set-times: func

    Adjust the timestamps of an open file or directory.

    Note: This is similar to futimens in POSIX.

    Note: This was called fd_filestat_set_times in earlier versions of WASI.

    Params
    Return values
    -

    read: func

    +

    [method]descriptor.read: func

    Read from a descriptor, without using and updating the descriptor's offset.

    This function returns a list of bytes containing the data that was read, along with a bool which, when true, indicates that the end of the @@ -1144,15 +1159,15 @@ if the I/O operation is interrupted.

    Note: This is similar to pread in POSIX.

    Params
    Return values
    -

    write: func

    +

    [method]descriptor.write: func

    Write to a descriptor, without using and updating the descriptor's offset.

    It is valid to write past the end of a file; the file is extended to the extent of the write, with bytes between the previous end and the start of @@ -1161,15 +1176,15 @@ the write set to zero.

    Note: This is similar to pwrite in POSIX.

    Params
    Return values
    -

    read-directory: func

    +

    [method]descriptor.read-directory: func

    Read directory entries from a directory.

    On filesystems where directories contain entries referring to themselves and their parents, often named . and .. respectively, these entries @@ -1179,102 +1194,102 @@ directory. Multiple streams may be active on the same directory, and they do not interfere with each other.

    Params
    Return values
    -

    sync: func

    +

    [method]descriptor.sync: func

    Synchronize the data and metadata of a file to disk.

    This function succeeds with no effect if the file descriptor is not opened for writing.

    Note: This is similar to fsync in POSIX.

    Params
    Return values
    -

    create-directory-at: func

    +

    [method]descriptor.create-directory-at: func

    Create a directory.

    Note: This is similar to mkdirat in POSIX.

    Params
    Return values
    -

    stat: func

    +

    [method]descriptor.stat: func

    Return the attributes of an open file or directory.

    Note: This is similar to fstat in POSIX, except that it does not return device and inode information. For testing whether two descriptors refer to -the same underlying filesystem object, use is-same-object. To obtain +the same underlying filesystem object, use is-same-object. To obtain additional data that can be used do determine whether a file has been -modified, use metadata-hash.

    +modified, use metadata-hash.

    Note: This was called fd_filestat_get in earlier versions of WASI.

    Params
    Return values
    -

    stat-at: func

    +

    [method]descriptor.stat-at: func

    Return the attributes of a file or directory.

    Note: This is similar to fstatat in POSIX, except that it does not -return device and inode information. See the stat description for a +return device and inode information. See the stat description for a discussion of alternatives.

    Note: This was called path_filestat_get in earlier versions of WASI.

    Params
    Return values
    -

    set-times-at: func

    +

    [method]descriptor.set-times-at: func

    Adjust the timestamps of a file or directory.

    Note: This is similar to utimensat in POSIX.

    Note: This was called path_filestat_set_times in earlier versions of WASI.

    Params
    Return values
    -

    link-at: func

    +

    [method]descriptor.link-at: func

    Create a hard link.

    Note: This is similar to linkat in POSIX.

    Params
    Return values
    -

    open-at: func

    +

    [method]descriptor.open-at: func

    Open a file or directory.

    The returned descriptor is not guaranteed to be the lowest-numbered descriptor not currently open/ it is randomized to prevent applications @@ -1283,82 +1298,82 @@ error-prone in multi-threaded contexts. The returned descriptor is guaranteed to be less than 2**31.

    If flags contains descriptor-flags::mutate-directory, and the base descriptor doesn't have descriptor-flags::mutate-directory set, -open-at fails with error-code::read-only.

    -

    If flags contains write or mutate-directory, or open-flags +open-at fails with error-code::read-only.

    +

    If flags contains write or mutate-directory, or open-flags contains truncate or create, and the base descriptor doesn't have -descriptor-flags::mutate-directory set, open-at fails with +descriptor-flags::mutate-directory set, open-at fails with error-code::read-only.

    Note: This is similar to openat in POSIX.

    Params
    Return values
    -

    readlink-at: func

    +

    [method]descriptor.readlink-at: func

    Read the contents of a symbolic link.

    If the contents contain an absolute or rooted path in the underlying filesystem, this function fails with error-code::not-permitted.

    Note: This is similar to readlinkat in POSIX.

    Params
    Return values
    -

    remove-directory-at: func

    +

    [method]descriptor.remove-directory-at: func

    Remove a directory.

    Return error-code::not-empty if the directory is not empty.

    Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

    Params
    Return values
    -

    rename-at: func

    +

    [method]descriptor.rename-at: func

    Rename a filesystem object.

    Note: This is similar to renameat in POSIX.

    Params
    Return values
    -

    symlink-at: func

    +

    [method]descriptor.symlink-at: func

    Create a symbolic link (also known as a "symlink").

    If old-path starts with /, the function fails with error-code::not-permitted.

    Note: This is similar to symlinkat in POSIX.

    Params
    Return values
    -

    access-at: func

    +

    [method]descriptor.access-at: func

    Check accessibility of a filesystem path.

    Check whether the given filesystem path names an object which is readable, writable, or executable, or whether it exists.

    @@ -1368,64 +1383,64 @@ entities.

    Note: This is similar to faccessat with the AT_EACCESS flag in POSIX.

    Params
    Return values
    -

    unlink-file-at: func

    +

    [method]descriptor.unlink-file-at: func

    Unlink a filesystem object that is not a directory.

    Return error-code::is-directory if the path refers to a directory. Note: This is similar to unlinkat(fd, path, 0) in POSIX.

    Params
    Return values
    -

    change-file-permissions-at: func

    +

    [method]descriptor.change-file-permissions-at: func

    Change the permissions of a filesystem object that is not a directory.

    Note that the ultimate meanings of these permissions is filesystem-specific.

    Note: This is similar to fchmodat in POSIX.

    Params
    Return values
    -

    change-directory-permissions-at: func

    +

    [method]descriptor.change-directory-permissions-at: func

    Change the permissions of a directory.

    Note that the ultimate meanings of these permissions is filesystem-specific.

    Unlike in POSIX, the executable flag is not reinterpreted as a "search" -flag. read on a directory implies readability and searchability, and +flag. read on a directory implies readability and searchability, and execute is not valid for directories.

    Note: This is similar to fchmodat in POSIX.

    Params
    Return values
    -

    lock-shared: func

    +

    [method]descriptor.lock-shared: func

    Request a shared advisory lock for an open file.

    This requests a shared lock; more than one shared lock can be held for a file at the same time.

    @@ -1441,13 +1456,13 @@ locking, this function returns error-cod

    Note: This is similar to flock(fd, LOCK_SH) in Unix.

    Params
    Return values
    -

    lock-exclusive: func

    +

    [method]descriptor.lock-exclusive: func

    Request an exclusive advisory lock for an open file.

    This requests an exclusive lock; no other locks may be held for the file while an exclusive lock is held.

    @@ -1465,13 +1480,13 @@ locking, this function returns error-cod

    Note: This is similar to flock(fd, LOCK_EX) in Unix.

    Params
    Return values
    -

    try-lock-shared: func

    +

    [method]descriptor.try-lock-shared: func

    Request a shared advisory lock for an open file.

    This requests a shared lock; more than one shared lock can be held for a file at the same time.

    @@ -1488,13 +1503,13 @@ locking, this function returns error-cod

    Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

    Params
    Return values
    -

    try-lock-exclusive: func

    +

    [method]descriptor.try-lock-exclusive: func

    Request an exclusive advisory lock for an open file.

    This requests an exclusive lock; no other locks may be held for the file while an exclusive lock is held.

    @@ -1513,48 +1528,24 @@ locking, this function returns error-cod

    Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

    Params
    Return values
    -

    unlock: func

    +

    [method]descriptor.unlock: func

    Release a shared or exclusive lock on an open file.

    Note: This is similar to flock(fd, LOCK_UN) in Unix.

    Params
    Return values
    -

    drop-descriptor: func

    -

    Dispose of the specified descriptor, after which it may no longer -be used.

    -
    Params
    - -

    read-directory-entry: func

    -

    Read a single directory entry from a directory-entry-stream.

    -
    Params
    - -
    Return values
    - -

    drop-directory-entry-stream: func

    -

    Dispose of the specified directory-entry-stream, after which it may no longer -be used.

    -
    Params
    - -

    is-same-object: func

    +

    [method]descriptor.is-same-object: func

    Test whether two descriptors refer to the same filesystem object.

    In POSIX, this corresponds to testing whether the two descriptors have the same device (st_dev) and inode (st_ino or d_ino) numbers. @@ -1562,14 +1553,14 @@ wasi-filesystem does not expose device and inode numbers, so this function may be used instead.

    Params
    Return values
      -
    • bool
    • +
    • bool
    -

    metadata-hash: func

    +

    [method]descriptor.metadata-hash: func

    Return a hash of the metadata associated with a filesystem object referred to by a descriptor.

    This returns a hash of the last-modification timestamp and file size, and @@ -1589,25 +1580,35 @@ computed hash.

    However, none of these is required.

    Params
    Return values
    -

    metadata-hash-at: func

    +

    [method]descriptor.metadata-hash-at: func

    Return a hash of the metadata associated with a filesystem object referred to by a directory descriptor and a relative path.

    -

    This performs the same hash computation as metadata-hash.

    +

    This performs the same hash computation as metadata-hash.

    +
    Params
    + +
    Return values
    + +

    [method]directory-entry-stream.read-directory-entry: func

    +

    Read a single directory entry from a directory-entry-stream.

    Params
    Return values

    Import interface wasi:filesystem/preopens


    @@ -1621,17 +1622,12 @@ to by a directory descriptor and a relative path.

    Return the set of preopened directories, and their path.

    Return values

    Import interface wasi:sockets/network


    Types

    -

    type network

    -

    u32

    -

    An opaque resource that represents access to (a subset of) the network. -This enables context-based security for networking. -There is no need for this to map 1:1 to a physical network interface. -

    FYI, In the future this will be replaced by handle types.

    +

    resource network

    enum error-code

    Error codes.

    In theory, every API can return any error code. @@ -1839,15 +1835,6 @@ combined with a couple of errors that are always possible:

  • ipv4: ipv4-socket-address
  • ipv6: ipv6-socket-address
  • -
    -

    Functions

    -

    drop-network: func

    -

    Dispose of the specified network, after which it may no longer be used.

    -

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    -
    Params
    -

    Import interface wasi:sockets/instance-network

    This interface provides a value-export of the default network handle..


    @@ -1861,7 +1848,7 @@ combined with a couple of errors that are always possible:

    Get a handle to the default network.

    Return values

    Import interface wasi:sockets/ip-name-lookup


    @@ -1881,10 +1868,8 @@ combined with a couple of errors that are always possible:

    #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `type resolve-address-stream` -`u32` -

    ----- +#### `resource resolve-address-stream` +


    Functions

    resolve-addresses: func

    Resolve an internet host name to a list of IP addresses.

    @@ -1893,7 +1878,7 @@ combined with a couple of errors that are always possible:

    • name: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted to ASCII using IDNA encoding.
    • -
    • address-family: If provided, limit the results to addresses of this specific address family.
    • +
    • address-family: If provided, limit the results to addresses of this specific address family.
    • include-unavailable: When set to true, this function will also return addresses of which the runtime thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on systems without an active IPv6 interface. Notes:
    • @@ -1903,12 +1888,12 @@ systems without an active IPv6 interface. Notes:

      This function never blocks. It either immediately fails or immediately returns successfully with a resolve-address-stream that can be used to (asynchronously) fetch the results.

      At the moment, the stream never completes successfully with 0 items. Ie. the first call -to resolve-next-address never returns ok(none). This may change in the future.

      +to resolve-next-address never returns ok(none). This may change in the future.

      Typical errors

      • invalid-name: name is a syntactically invalid domain name.
      • invalid-name: name is an IP address.
      • -
      • address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)
      • +
      • address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)

      References:

      Params
      Return values
      -

      resolve-next-address: func

      +

      [method]resolve-address-stream.resolve-next-address: func

      Returns the next address from the resolver.

      This function should be called multiple times. On each call, it will return the next address in connection order preference. If all -addresses have been exhausted, this function returns none. -After which, you should release the stream with drop-resolve-address-stream.

      +addresses have been exhausted, this function returns none.

      This function never returns IPv4-mapped IPv6 addresses.

      Typical errors

      Return values
      -

      drop-resolve-address-stream: func

      -

      Dispose of the specified resolve-address-stream, after which it may no longer be used.

      -

      Note: this function is scheduled to be removed when Resources are natively supported in Wit.

      -
      Params
      - -

      subscribe: func

      +

      [method]resolve-address-stream.subscribe: func

      Create a pollable which will resolve once the stream is ready for I/O.

      Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

      Params
      Return values

      Import interface wasi:sockets/tcp


      @@ -1993,18 +1970,15 @@ It's planned to be removed when future is natively supported in Pre #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

      -#### `type tcp-socket` -`u32` -

      A TCP socket handle. -

      enum shutdown-type

      +#### `enum shutdown-type`
      Enum Cases
      • -

        receive

        +

        receive

        Similar to `SHUT_RD` in POSIX.

      • -

        send

        +

        send

        Similar to `SHUT_WR` in POSIX.

      • @@ -2012,9 +1986,10 @@ It's planned to be removed when future is natively supported in Pre

        Similar to `SHUT_RDWR` in POSIX.

      +

      resource tcp-socket


      Functions

      -

      start-bind: func

      +

      [method]tcp-socket.start-bind: func

      Bind the socket to a specific network on the provided IP address and port.

      If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -2024,7 +1999,7 @@ implicitly bind the socket.

      Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

      Typical start errors

        -
      • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
      • +
      • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
      • already-bound: The socket is already bound. (EINVAL)
      • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
      @@ -2032,7 +2007,7 @@ implicitly bind the socket.

      • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
      • address-in-use: Address is already in use. (EADDRINUSE)
      • -
      • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
      • +
      • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
      • not-in-progress: A bind operation is not in progress.
      • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
      @@ -2045,24 +2020,24 @@ implicitly bind the socket.

    Params
    Return values
    -

    finish-bind: func

    +

    [method]tcp-socket.finish-bind: func

    Params
    Return values
    -

    start-connect: func

    +

    [method]tcp-socket.start-connect: func

    Connect to a remote endpoint.

    On success:

      @@ -2071,9 +2046,9 @@ implicitly bind the socket.

    Typical start errors

      -
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • -
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
    • -
    • invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
    • +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
    • already-attached: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
    • already-connected: The socket is already in the Connection state. (EISCONN)
    • already-listening: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
    • @@ -2098,24 +2073,24 @@ implicitly bind the socket.

    Params
    Return values
    -

    finish-connect: func

    +

    [method]tcp-socket.finish-connect: func

    Params
    Return values
    -

    start-listen: func

    +

    [method]tcp-socket.start-listen: func

    Start listening for new connections.

    Transitions the socket into the Listener state.

    Unlike POSIX:

    @@ -2145,22 +2120,22 @@ implicitly bind the socket.

    Params
    Return values
    -

    finish-listen: func

    +

    [method]tcp-socket.finish-listen: func

    Params
    Return values
    -

    accept: func

    +

    [method]tcp-socket.accept: func

    Accept a new client socket.

    The returned socket is bound and in the Connection state.

    On success, this function returns the newly accepted client socket along with @@ -2180,13 +2155,13 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    local-address: func

    +

    [method]tcp-socket.local-address: func

    Get the bound local address.

    Typical errors

      @@ -2201,13 +2176,13 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    remote-address: func

    +

    [method]tcp-socket.remote-address: func

    Get the bound remote address.

    Typical errors

      @@ -2222,24 +2197,24 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    address-family: func

    +

    [method]tcp-socket.address-family: func

    Whether this is a IPv4 or IPv6 socket.

    Equivalent to the SO_DOMAIN socket option.

    Params
    Return values
    -

    ipv6-only: func

    +

    [method]tcp-socket.ipv6-only: func

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    Equivalent to the IPV6_V6ONLY socket option.

    Typical errors

    @@ -2251,23 +2226,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-ipv6-only: func

    +

    [method]tcp-socket.set-ipv6-only: func

    Params
    Return values
    -

    set-listen-backlog-size: func

    +

    [method]tcp-socket.set-listen-backlog-size: func

    Hints the desired listen queue size. Implementations are free to ignore this.

    Typical errors

      @@ -2276,14 +2251,14 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    keep-alive: func

    +

    [method]tcp-socket.keep-alive: func

    Equivalent to the SO_KEEPALIVE socket option.

    Typical errors

      @@ -2291,23 +2266,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-keep-alive: func

    +

    [method]tcp-socket.set-keep-alive: func

    Params
    Return values
    -

    no-delay: func

    +

    [method]tcp-socket.no-delay: func

    Equivalent to the TCP_NODELAY socket option.

    Typical errors

      @@ -2315,23 +2290,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-no-delay: func

    +

    [method]tcp-socket.set-no-delay: func

    Params
    Return values
    -

    unicast-hop-limit: func

    +

    [method]tcp-socket.unicast-hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    Typical errors

      @@ -2341,23 +2316,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-unicast-hop-limit: func

    +

    [method]tcp-socket.set-unicast-hop-limit: func

    Params
    Return values
    -

    receive-buffer-size: func

    +

    [method]tcp-socket.receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    Note #1: an implementation may choose to cap or round the buffer size when setting the value. In other words, after setting a value, reading the same setting back may return a different value.

    @@ -2373,59 +2348,59 @@ for internal metadata structures.

    Params
    Return values
    -

    set-receive-buffer-size: func

    +

    [method]tcp-socket.set-receive-buffer-size: func

    Params
    Return values
    -

    send-buffer-size: func

    +

    [method]tcp-socket.send-buffer-size: func

    Params
    Return values
    -

    set-send-buffer-size: func

    +

    [method]tcp-socket.set-send-buffer-size: func

    Params
    Return values
    -

    subscribe: func

    +

    [method]tcp-socket.subscribe: func

    Create a pollable which will resolve once the socket is ready for I/O.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    shutdown: func

    +

    [method]tcp-socket.shutdown: func

    Initiate a graceful shutdown.

    • receive: the socket is not expecting to receive any more data from the peer. All subsequent read operations on the input-stream associated with this socket will return an End Of Stream indication. -Any data still in the receive queue at time of calling shutdown will be discarded.
    • +Any data still in the receive queue at time of calling shutdown will be discarded.
    • send: the socket is not expecting to send any more data to the peer. All subsequent write operations on the output-stream associated with this socket will return an error.
    • both: same effect as receive & send combined.
    • @@ -2444,20 +2419,12 @@ operations on the output-stream associ
    Params
    Return values
    -

    drop-tcp-socket: func

    -

    Dispose of the specified tcp-socket, after which it may no longer be used.

    -

    Similar to the POSIX close function.

    -

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    -
    Params
    -

    Import interface wasi:sockets/tcp-create-socket


    @@ -2486,7 +2453,7 @@ is called, the socket is effectively an in-memory configuration object, unable t

    Typical errors

    • not-supported: The host does not support TCP sockets. (EOPNOTSUPP)
    • -
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • +
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)

    References

    @@ -2498,11 +2465,11 @@ is called, the socket is effectively an in-memory configuration object, unable t
    Params
    Return values

    Import interface wasi:sockets/udp


    @@ -2522,18 +2489,16 @@ is called, the socket is effectively an in-memory configuration object, unable t #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `type udp-socket` -`u32` -

    A UDP socket handle. -

    record datagram

    +#### `record datagram`
    Record Fields
    +

    resource udp-socket


    Functions

    -

    start-bind: func

    +

    [method]udp-socket.start-bind: func

    Bind the socket to a specific network on the provided IP address and port.

    If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -2542,7 +2507,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    Typical start errors

      -
    • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
    • +
    • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
    • already-bound: The socket is already bound. (EINVAL)
    • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
    @@ -2550,7 +2515,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
    • address-in-use: Address is already in use. (EADDRINUSE)
    • -
    • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
    • +
    • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
    • not-in-progress: A bind operation is not in progress.
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    @@ -2563,38 +2528,38 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    Params
    Return values
    -

    finish-bind: func

    +

    [method]udp-socket.finish-bind: func

    Params
    Return values
    -

    start-connect: func

    +

    [method]udp-socket.start-connect: func

    Set the destination address.

    -

    The local-address is updated based on the best network path to remote-address.

    +

    The local-address is updated based on the best network path to remote-address.

    When a destination address is set:

      -
    • all receive operations will only return datagrams sent from the provided remote-address.
    • -
    • the send function can only be used to send to this destination.
    • +
    • all receive operations will only return datagrams sent from the provided remote-address.
    • +
    • the send function can only be used to send to this destination.

    Note that this function does not generate any network traffic and the peer is not aware of this "connection".

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    Typical start errors

      -
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • -
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • -
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • already-attached: The socket is already bound to a different network. The network passed to connect must be identical to the one passed to bind.
    • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
    @@ -2613,24 +2578,24 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    Params
    Return values
    -

    finish-connect: func

    +

    [method]udp-socket.finish-connect: func

    Params
    Return values
    -

    receive: func

    +

    [method]udp-socket.receive: func

    Receive messages on the socket.

    This function attempts to receive up to max-results datagrams on the socket without blocking. The returned list may contain fewer elements than requested, but never more. @@ -2654,14 +2619,14 @@ If max-results is 0, this function returns successfully with an emp

    Params
    Return values
    -

    send: func

    +

    [method]udp-socket.send: func

    Send messages on the socket.

    This function attempts to send all provided datagrams on the socket without blocking and returns how many messages were actually sent (or queued for sending).

    @@ -2670,12 +2635,12 @@ sending each individual datagram until either the end of the list has been reach If at least one datagram has been sent successfully, this function never returns an error.

    If the input list is empty, the function returns ok(0).

    The remote address option is required. To send a message to the "connected" peer, -call remote-address to get their address.

    +call remote-address to get their address.

    Typical errors

      -
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • -
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • -
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • already-connected: The socket is in "connected" mode and the datagram.remote-address does not match the address passed to connect. (EISCONN)
    • not-bound: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind.
    • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
    • @@ -2695,14 +2660,14 @@ call remote-address to get their addr
    Params
    Return values
    -

    local-address: func

    +

    [method]udp-socket.local-address: func

    Get the current bound address.

    Typical errors

    Params
    Return values
    -

    remote-address: func

    +

    [method]udp-socket.remote-address: func

    Get the address set with connect.

    Typical errors

    Params
    Return values
    -

    address-family: func

    +

    [method]udp-socket.address-family: func

    Whether this is a IPv4 or IPv6 socket.

    Equivalent to the SO_DOMAIN socket option.

    Params
    Return values
    -

    ipv6-only: func

    +

    [method]udp-socket.ipv6-only: func

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    Equivalent to the IPV6_V6ONLY socket option.

    Typical errors

    @@ -2767,23 +2732,23 @@ call remote-address to get their addr
    Params
    Return values
    -

    set-ipv6-only: func

    +

    [method]udp-socket.set-ipv6-only: func

    Params
    Return values
    -

    unicast-hop-limit: func

    +

    [method]udp-socket.unicast-hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    Typical errors

    Params
    Return values
    -

    set-unicast-hop-limit: func

    +

    [method]udp-socket.set-unicast-hop-limit: func

    Params
    Return values
    -

    receive-buffer-size: func

    +

    [method]udp-socket.receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    Note #1: an implementation may choose to cap or round the buffer size when setting the value. In other words, after setting a value, reading the same setting back may return a different value.

    Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of actual data to be sent/received by the application, because the kernel might also use the buffer space for internal metadata structures.

    -

    Fails when this socket is in the Listening state.

    Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

    Typical errors

      @@ -2822,59 +2786,52 @@ for internal metadata structures.

    Params
    Return values
    -

    set-receive-buffer-size: func

    +

    [method]udp-socket.set-receive-buffer-size: func

    Params
    Return values
    -

    send-buffer-size: func

    +

    [method]udp-socket.send-buffer-size: func

    Params
    Return values
    -

    set-send-buffer-size: func

    +

    [method]udp-socket.set-send-buffer-size: func

    Params
    Return values
    -

    subscribe: func

    +

    [method]udp-socket.subscribe: func

    Create a pollable which will resolve once the socket is ready for I/O.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    drop-udp-socket: func

    -

    Dispose of the specified udp-socket, after which it may no longer be used.

    -

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    -
    Params
    -

    Import interface wasi:sockets/udp-create-socket


    @@ -2903,7 +2860,7 @@ the socket is effectively an in-memory configuration object, unable to communica

    Typical errors

    • not-supported: The host does not support UDP sockets. (EOPNOTSUPP)
    • -
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • +
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)

    References:

    @@ -2915,11 +2872,11 @@ the socket is effectively an in-memory configuration object, unable to communica
    Params
    Return values

    Import interface wasi:random/random

    WASI Random is a random data API.

    @@ -3054,7 +3011,7 @@ directory, interpreting . as shorthand for this.

    get-stdin: func

    Return values

    Import interface wasi:cli/stdout


    @@ -3067,7 +3024,7 @@ directory, interpreting . as shorthand for this.

    get-stdout: func

    Return values

    Import interface wasi:cli/stderr


    @@ -3080,40 +3037,16 @@ directory, interpreting . as shorthand for this.

    get-stderr: func

    Return values

    Import interface wasi:cli/terminal-input


    Types

    -

    type terminal-input

    -

    u32

    -

    The input side of a terminal. -

    This represents a resource.

    -
    -

    Functions

    -

    drop-terminal-input: func

    -

    Dispose of the specified terminal-input after which it may no longer -be used.

    -
    Params
    - +

    resource terminal-input

    Import interface wasi:cli/terminal-output


    Types

    -

    type terminal-output

    -

    u32

    -

    The output side of a terminal. -

    This represents a resource.

    -
    -

    Functions

    -

    drop-terminal-output: func

    -

    Dispose of the specified terminal-output, after which it may no longer -be used.

    -
    Params
    - +

    resource terminal-output

    Import interface wasi:cli/terminal-stdin

    An interface providing an optional terminal-input for stdin as a link-time authority.

    @@ -3129,7 +3062,7 @@ link-time authority.

    allowing further interaction with it.

    Return values

    Import interface wasi:cli/terminal-stdout

    An interface providing an optional terminal-output for stdout as a @@ -3146,7 +3079,7 @@ link-time authority.

    allowing further interaction with it.

    Return values

    Import interface wasi:cli/terminal-stderr

    An interface providing an optional terminal-output for stderr as a @@ -3163,5 +3096,5 @@ link-time authority.

    allowing further interaction with it.

    Return values
    diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index 2ee3e4983..ae5020731 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,29 +1,24 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "1ed7e35b3f9738663854f0dd92a95bfadc410ea07170501f5c2fec0cc24e3d57" -sha512 = "ef1e23704a8a8436fd3718593d4c4d8b6d1c64dad3595b7496c0888ca14b725046f2900109800faca1bc8c14f237cdcaca791dba8284e1ad50105ab2d036825b" +sha256 = "ea955af7a152f85941b651c5b07345c4f077ae7f9e996c909ab8cc0a68c0120e" +sha512 = "114bc4f583a487cf1ccfdd6efa25c4c60cf637d4501a189eebd4b1d52aec2c8eb63ae14ce494db53dfd25bc20f6c4b533dc6f2143537e5cd14ca80d5d4b6a49d" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "dc170645d8aa52f2f94ab8f71093fa0c101e509ed1a07318995dc0395e9d6cf2" -sha512 = "3195a3e0f9ec52c3a91c4b4fde0547694236c7b29bceecb7f38634894fafd809c69ed1c1c9acbf225b2d5d00f5036d70371c9fed121d85028162b202035cabef" +sha256 = "f8602f2929fe149b0e2e904fe53b98e3a0ba0a42089253c9a738caf9ccb06c1d" +sha512 = "53f3d7c494ea6ad0687f91994f3af8c5f55bdddeb14cc47b30ff263cdb1ee6c7893ad425d1dc75a8da72d9bb5f82a46fcd566e0c2463fda102a22529e2d83f19" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "6e18239b0e20d1a3e6343cb961ebfd2c663ba7feb4c1aa3744b756fbdd1fb5b8" -sha512 = "53169b6e4fba0b2cf5fcf808f76e7fbb7cabb6ed66ab53f77d0966e7448312ccbe8571880ef4fc2ee86fbd6ba19bc48d46e10d22dcac6c51d217e8d7127c32db" - -[poll] -url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -sha256 = "d4c27124f4c137eb538b5c92ba5858ed9042e11b24a2eef85d14becd0b7f55de" -sha512 = "422c01b273b4b1377ece6f2e4ba0dfc609ca8ef30a3e0be0e172e1303fcf7b3ca4c470f4dea6c51bdf114b0f5c871ebc4934dfe3bf217d66ea689748df2b1e55" +sha256 = "6e20bcf4d4f5466b60c05ea8da7289ca361a7febdd22ab1a531e5ef7e394ab8d" +sha512 = "21f6689bce6ed6d9e3bd96372e5c7ed003a7aefbf8d49b4eea949dfbd265cf57a0d7dc67aa71e3de75d48fcc2c0cfe5f06f7e9e7959a23bc98f77da85f4161b9" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "9b622463e597b9ca94f41e4eaae589a77be38f71b4723142b60246ffed8eaae4" -sha512 = "21f03ca1e595b80d7ced522de1a47446526b49b900e2fb26fcbf410ce6aa267dbf247aebf3fbfa8123b46fc1a828e2fd64fb1e0198b40161a3257e8d86fd4546" +sha256 = "2f718c9909fcc95dc8d7f9fc3a17a30d7da715eaa9fa70af3c89f0f9439abc8a" +sha512 = "7580d79d0f01d4fb65ff85f76d52d420fdbc7406959a34c2b1cad4398dc34d2610f8b6b4e22bcea9db2f3d70242d356e961d843bfc4d2c4956c4f5e5ca3811f9" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "871c211b12d87a5da87c42353338b652260840897efcd37e2afba3b9290058fc" -sha512 = "e436a5ff3145ca85d702a086499c03488523483dd3addc8d71e4946e9c186355291551bb6d38b157173836fcc318182403e6dba970de4512f6cfb3374ccad6b9" +sha256 = "85b872b5af12d3010c20a5f4bf6d334a09c1a42ef7f7703c2949c0598ed8ebee" +sha512 = "238bbeea140eba0774cf5ce5abfdc93f03617a2fc30b497e104cc6a23fdf7bd496c61d3c962ca6718255ea5c96a9277bddae1fc4a6b6f7544de2be2649752eac" diff --git a/proposals/cli/wit/deps.toml b/proposals/cli/wit/deps.toml index 351e8c3b2..bb1b2ab1b 100644 --- a/proposals/cli/wit/deps.toml +++ b/proposals/cli/wit/deps.toml @@ -1,6 +1,5 @@ io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" +random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sockets = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" \ No newline at end of file +sockets = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index fb8424eb0..703a5fb7a 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -9,7 +9,7 @@ /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:poll/poll.{pollable} + use wasi:io/poll.{pollable} /// A timestamp in nanoseconds. type instant = u64 diff --git a/proposals/cli/wit/deps/clocks/timezone.wit b/proposals/cli/wit/deps/clocks/timezone.wit index 662830871..a872bffc7 100644 --- a/proposals/cli/wit/deps/clocks/timezone.wit +++ b/proposals/cli/wit/deps/clocks/timezone.wit @@ -1,15 +1,6 @@ interface timezone { use wall-clock.{datetime} - /// A timezone. - /// - /// In timezones that recognize daylight saving time, also known as daylight - /// time and summer time, the information returned from the functions varies - /// over time to reflect these adjustments. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type timezone = u32 - /// Return information needed to display the given `datetime`. This includes /// the UTC offset, the time zone name, and a flag indicating whether /// daylight saving time is active. @@ -17,14 +8,10 @@ interface timezone { /// If the timezone cannot be determined for the given `datetime`, return a /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight /// saving time. - display: func(this: timezone, when: datetime) -> timezone-display + display: func(when: datetime) -> timezone-display /// The same as `display`, but only return the UTC offset. - utc-offset: func(this: timezone, when: datetime) -> s32 - - /// Dispose of the specified input-stream, after which it may no longer - /// be used. - drop-timezone: func(this: timezone) + utc-offset: func(when: datetime) -> s32 /// Information useful for displaying the timezone of a specific `datetime`. /// diff --git a/proposals/cli/wit/deps/clocks/world.wit b/proposals/cli/wit/deps/clocks/world.wit index 291a9c75e..5c2dd411d 100644 --- a/proposals/cli/wit/deps/clocks/world.wit +++ b/proposals/cli/wit/deps/clocks/world.wit @@ -1,6 +1,6 @@ package wasi:clocks -world example-world { +world imports { import monotonic-clock import wall-clock import timezone diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index a437f22ae..3f69bf997 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -17,6 +17,11 @@ /// `..` and symbolic link steps, reaches a directory outside of the base /// directory, or reaches a symlink to an absolute or rooted path in the /// underlying filesystem, the function fails with `error-code::not-permitted`. +/// +/// For more information about WASI path resolution and sandboxing, see +/// [WASI filesystem path resolution]. +/// +/// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { use wasi:io/streams.{input-stream, output-stream} use wasi:clocks/wall-clock.{datetime} @@ -55,14 +60,6 @@ interface types { read, /// Write mode: Data can be written to. write, - /// Requests non-blocking operation. - /// - /// When this flag is enabled, functions may return immediately with an - /// `error-code::would-block` error code in situations where they would - /// otherwise block. However, this non-blocking behavior is not - /// required. Implementations are permitted to ignore this flag and - /// block. This is similar to `O_NONBLOCK` in POSIX. - non-blocking, /// Request that writes be performed according to synchronized I/O file /// integrity completion. The data stored in the file and the file's /// metadata are synchronized. This is similar to `O_SYNC` in POSIX. @@ -110,11 +107,20 @@ interface types { /// length in bytes of the pathname contained in the symbolic link. size: filesize, /// Last data access timestamp. - data-access-timestamp: datetime, + /// + /// If the `option` is none, the platform doesn't maintain an access + /// timestamp for this file. + data-access-timestamp: option, /// Last data modification timestamp. - data-modification-timestamp: datetime, - /// Last file status change timestamp. - status-change-timestamp: datetime, + /// + /// If the `option` is none, the platform doesn't maintain a + /// modification timestamp for this file. + data-modification-timestamp: option, + /// Last file status-change timestamp. + /// + /// If the `option` is none, the platform doesn't maintain a + /// status-change timestamp for this file. + status-change-timestamp: option, } /// Flags determining the method of how paths are resolved. @@ -285,13 +291,6 @@ interface types { no-reuse, } - /// A descriptor is a reference to a filesystem object, which may be a file, - /// directory, named pipe, special file, or other object on which filesystem - /// calls may be made. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type descriptor = u32 - /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. record metadata-hash-value { @@ -301,541 +300,499 @@ interface types { upper: u64, } - /// Return a stream for reading from a file, if available. - /// - /// May fail with an error-code describing why the file cannot be read. - /// - /// Multiple read, write, and append streams may be active on the same open - /// file and they do not interfere with each other. - /// - /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. - read-via-stream: func( - this: descriptor, - /// The offset within the file at which to start reading. - offset: filesize, - ) -> result - - /// Return a stream for writing to a file, if available. - /// - /// May fail with an error-code describing why the file cannot be written. - /// - /// Note: This allows using `write-stream`, which is similar to `write` in - /// POSIX. - write-via-stream: func( - this: descriptor, - /// The offset within the file at which to start writing. - offset: filesize, - ) -> result - - /// Return a stream for appending to a file, if available. - /// - /// May fail with an error-code describing why the file cannot be appended. - /// - /// Note: This allows using `write-stream`, which is similar to `write` with - /// `O_APPEND` in in POSIX. - append-via-stream: func( - this: descriptor, - ) -> result + /// A descriptor is a reference to a filesystem object, which may be a file, + /// directory, named pipe, special file, or other object on which filesystem + /// calls may be made. + resource descriptor { + /// Return a stream for reading from a file, if available. + /// + /// May fail with an error-code describing why the file cannot be read. + /// + /// Multiple read, write, and append streams may be active on the same open + /// file and they do not interfere with each other. + /// + /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. + read-via-stream: func( + /// The offset within the file at which to start reading. + offset: filesize, + ) -> result - /// Provide file advisory information on a descriptor. - /// - /// This is similar to `posix_fadvise` in POSIX. - advise: func( - this: descriptor, - /// The offset within the file to which the advisory applies. - offset: filesize, - /// The length of the region to which the advisory applies. - length: filesize, - /// The advice. - advice: advice - ) -> result<_, error-code> - - /// Synchronize the data of a file to disk. - /// - /// This function succeeds with no effect if the file descriptor is not - /// opened for writing. - /// - /// Note: This is similar to `fdatasync` in POSIX. - sync-data: func(this: descriptor) -> result<_, error-code> + /// Return a stream for writing to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be written. + /// + /// Note: This allows using `write-stream`, which is similar to `write` in + /// POSIX. + write-via-stream: func( + /// The offset within the file at which to start writing. + offset: filesize, + ) -> result + + /// Return a stream for appending to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be appended. + /// + /// Note: This allows using `write-stream`, which is similar to `write` with + /// `O_APPEND` in in POSIX. + append-via-stream: func() -> result - /// Get flags associated with a descriptor. - /// - /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. - /// - /// Note: This returns the value that was the `fs_flags` value returned - /// from `fdstat_get` in earlier versions of WASI. - get-flags: func(this: descriptor) -> result + /// Provide file advisory information on a descriptor. + /// + /// This is similar to `posix_fadvise` in POSIX. + advise: func( + /// The offset within the file to which the advisory applies. + offset: filesize, + /// The length of the region to which the advisory applies. + length: filesize, + /// The advice. + advice: advice + ) -> result<_, error-code> + + /// Synchronize the data of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fdatasync` in POSIX. + sync-data: func() -> result<_, error-code> - /// Get the dynamic type of a descriptor. - /// - /// Note: This returns the same value as the `type` field of the `fd-stat` - /// returned by `stat`, `stat-at` and similar. - /// - /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided - /// by `fstat` in POSIX. - /// - /// Note: This returns the value that was the `fs_filetype` value returned - /// from `fdstat_get` in earlier versions of WASI. - get-type: func(this: descriptor) -> result + /// Get flags associated with a descriptor. + /// + /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. + /// + /// Note: This returns the value that was the `fs_flags` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-flags: func() -> result - /// Set status flags associated with a descriptor. - /// - /// This function may only change the `non-blocking` flag. - /// - /// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - /// - /// Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. - set-flags: func(this: descriptor, %flags: descriptor-flags) -> result<_, error-code> + /// Get the dynamic type of a descriptor. + /// + /// Note: This returns the same value as the `type` field of the `fd-stat` + /// returned by `stat`, `stat-at` and similar. + /// + /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided + /// by `fstat` in POSIX. + /// + /// Note: This returns the value that was the `fs_filetype` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-type: func() -> result - /// Adjust the size of an open file. If this increases the file's size, the - /// extra bytes are filled with zeros. - /// - /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - set-size: func(this: descriptor, size: filesize) -> result<_, error-code> + /// Adjust the size of an open file. If this increases the file's size, the + /// extra bytes are filled with zeros. + /// + /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. + set-size: func(size: filesize) -> result<_, error-code> - /// Adjust the timestamps of an open file or directory. - /// - /// Note: This is similar to `futimens` in POSIX. - /// - /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - set-times: func( - this: descriptor, - /// The desired values of the data access timestamp. - data-access-timestamp: new-timestamp, - /// The desired values of the data modification timestamp. - data-modification-timestamp: new-timestamp, - ) -> result<_, error-code> - - /// Read from a descriptor, without using and updating the descriptor's offset. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a bool which, when true, indicates that the end of the - /// file was reached. The returned list will contain up to `length` bytes; it - /// may return fewer than requested, if the end of the file is reached or - /// if the I/O operation is interrupted. - /// - /// In the future, this may change to return a `stream`. - /// - /// Note: This is similar to `pread` in POSIX. - read: func( - this: descriptor, - /// The maximum number of bytes to read. - length: filesize, - /// The offset within the file at which to read. - offset: filesize, - ) -> result, bool>, error-code> - - /// Write to a descriptor, without using and updating the descriptor's offset. - /// - /// It is valid to write past the end of a file; the file is extended to the - /// extent of the write, with bytes between the previous end and the start of - /// the write set to zero. - /// - /// In the future, this may change to take a `stream`. - /// - /// Note: This is similar to `pwrite` in POSIX. - write: func( - this: descriptor, - /// Data to write - buffer: list, - /// The offset within the file at which to write. - offset: filesize, - ) -> result - - /// Read directory entries from a directory. - /// - /// On filesystems where directories contain entries referring to themselves - /// and their parents, often named `.` and `..` respectively, these entries - /// are omitted. - /// - /// This always returns a new stream which starts at the beginning of the - /// directory. Multiple streams may be active on the same directory, and they - /// do not interfere with each other. - read-directory: func( - this: descriptor - ) -> result - - /// Synchronize the data and metadata of a file to disk. - /// - /// This function succeeds with no effect if the file descriptor is not - /// opened for writing. - /// - /// Note: This is similar to `fsync` in POSIX. - sync: func(this: descriptor) -> result<_, error-code> + /// Adjust the timestamps of an open file or directory. + /// + /// Note: This is similar to `futimens` in POSIX. + /// + /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. + set-times: func( + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code> + + /// Read from a descriptor, without using and updating the descriptor's offset. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a bool which, when true, indicates that the end of the + /// file was reached. The returned list will contain up to `length` bytes; it + /// may return fewer than requested, if the end of the file is reached or + /// if the I/O operation is interrupted. + /// + /// In the future, this may change to return a `stream`. + /// + /// Note: This is similar to `pread` in POSIX. + read: func( + /// The maximum number of bytes to read. + length: filesize, + /// The offset within the file at which to read. + offset: filesize, + ) -> result, bool>, error-code> + + /// Write to a descriptor, without using and updating the descriptor's offset. + /// + /// It is valid to write past the end of a file; the file is extended to the + /// extent of the write, with bytes between the previous end and the start of + /// the write set to zero. + /// + /// In the future, this may change to take a `stream`. + /// + /// Note: This is similar to `pwrite` in POSIX. + write: func( + /// Data to write + buffer: list, + /// The offset within the file at which to write. + offset: filesize, + ) -> result + + /// Read directory entries from a directory. + /// + /// On filesystems where directories contain entries referring to themselves + /// and their parents, often named `.` and `..` respectively, these entries + /// are omitted. + /// + /// This always returns a new stream which starts at the beginning of the + /// directory. Multiple streams may be active on the same directory, and they + /// do not interfere with each other. + read-directory: func() -> result - /// Create a directory. - /// - /// Note: This is similar to `mkdirat` in POSIX. - create-directory-at: func( - this: descriptor, - /// The relative path at which to create the directory. - path: string, - ) -> result<_, error-code> - - /// Return the attributes of an open file or directory. - /// - /// Note: This is similar to `fstat` in POSIX, except that it does not return - /// device and inode information. For testing whether two descriptors refer to - /// the same underlying filesystem object, use `is-same-object`. To obtain - /// additional data that can be used do determine whether a file has been - /// modified, use `metadata-hash`. - /// - /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - stat: func(this: descriptor) -> result + /// Synchronize the data and metadata of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fsync` in POSIX. + sync: func() -> result<_, error-code> - /// Return the attributes of a file or directory. - /// - /// Note: This is similar to `fstatat` in POSIX, except that it does not - /// return device and inode information. See the `stat` description for a - /// discussion of alternatives. - /// - /// Note: This was called `path_filestat_get` in earlier versions of WASI. - stat-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to inspect. - path: string, - ) -> result - - /// Adjust the timestamps of a file or directory. - /// - /// Note: This is similar to `utimensat` in POSIX. - /// - /// Note: This was called `path_filestat_set_times` in earlier versions of - /// WASI. - set-times-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to operate on. - path: string, - /// The desired values of the data access timestamp. - data-access-timestamp: new-timestamp, - /// The desired values of the data modification timestamp. - data-modification-timestamp: new-timestamp, - ) -> result<_, error-code> - - /// Create a hard link. - /// - /// Note: This is similar to `linkat` in POSIX. - link-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - old-path-flags: path-flags, - /// The relative source path from which to link. - old-path: string, - /// The base directory for `new-path`. - new-descriptor: descriptor, - /// The relative destination path at which to create the hard link. - new-path: string, - ) -> result<_, error-code> - - /// Open a file or directory. - /// - /// The returned descriptor is not guaranteed to be the lowest-numbered - /// descriptor not currently open/ it is randomized to prevent applications - /// from depending on making assumptions about indexes, since this is - /// error-prone in multi-threaded contexts. The returned descriptor is - /// guaranteed to be less than 2**31. - /// - /// If `flags` contains `descriptor-flags::mutate-directory`, and the base - /// descriptor doesn't have `descriptor-flags::mutate-directory` set, - /// `open-at` fails with `error-code::read-only`. - /// - /// If `flags` contains `write` or `mutate-directory`, or `open-flags` - /// contains `truncate` or `create`, and the base descriptor doesn't have - /// `descriptor-flags::mutate-directory` set, `open-at` fails with - /// `error-code::read-only`. - /// - /// Note: This is similar to `openat` in POSIX. - open-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the object to open. - path: string, - /// The method by which to open the file. - open-flags: open-flags, - /// Flags to use for the resulting descriptor. - %flags: descriptor-flags, - /// Permissions to use when creating a new file. - modes: modes - ) -> result - - /// Read the contents of a symbolic link. - /// - /// If the contents contain an absolute or rooted path in the underlying - /// filesystem, this function fails with `error-code::not-permitted`. - /// - /// Note: This is similar to `readlinkat` in POSIX. - readlink-at: func( - this: descriptor, - /// The relative path of the symbolic link from which to read. - path: string, - ) -> result - - /// Remove a directory. - /// - /// Return `error-code::not-empty` if the directory is not empty. - /// - /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - remove-directory-at: func( - this: descriptor, - /// The relative path to a directory to remove. - path: string, - ) -> result<_, error-code> - - /// Rename a filesystem object. - /// - /// Note: This is similar to `renameat` in POSIX. - rename-at: func( - this: descriptor, - /// The relative source path of the file or directory to rename. - old-path: string, - /// The base directory for `new-path`. - new-descriptor: descriptor, - /// The relative destination path to which to rename the file or directory. - new-path: string, - ) -> result<_, error-code> - - /// Create a symbolic link (also known as a "symlink"). - /// - /// If `old-path` starts with `/`, the function fails with - /// `error-code::not-permitted`. - /// - /// Note: This is similar to `symlinkat` in POSIX. - symlink-at: func( - this: descriptor, - /// The contents of the symbolic link. - old-path: string, - /// The relative destination path at which to create the symbolic link. - new-path: string, - ) -> result<_, error-code> - - /// Check accessibility of a filesystem path. - /// - /// Check whether the given filesystem path names an object which is - /// readable, writable, or executable, or whether it exists. - /// - /// This does not a guarantee that subsequent accesses will succeed, as - /// filesystem permissions may be modified asynchronously by external - /// entities. - /// - /// Note: This is similar to `faccessat` with the `AT_EACCESS` flag in POSIX. - access-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to check. - path: string, - /// The type of check to perform. - %type: access-type - ) -> result<_, error-code> - - /// Unlink a filesystem object that is not a directory. - /// - /// Return `error-code::is-directory` if the path refers to a directory. - /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - unlink-file-at: func( - this: descriptor, - /// The relative path to a file to unlink. - path: string, - ) -> result<_, error-code> - - /// Change the permissions of a filesystem object that is not a directory. - /// - /// Note that the ultimate meanings of these permissions is - /// filesystem-specific. - /// - /// Note: This is similar to `fchmodat` in POSIX. - change-file-permissions-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the filesystem object. - modes: modes, - ) -> result<_, error-code> - - /// Change the permissions of a directory. - /// - /// Note that the ultimate meanings of these permissions is - /// filesystem-specific. - /// - /// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" - /// flag. `read` on a directory implies readability and searchability, and - /// `execute` is not valid for directories. - /// - /// Note: This is similar to `fchmodat` in POSIX. - change-directory-permissions-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the directory. - modes: modes, - ) -> result<_, error-code> - - /// Request a shared advisory lock for an open file. - /// - /// This requests a *shared* lock; more than one shared lock can be held for - /// a file at the same time. - /// - /// If the open file has an exclusive lock, this function downgrades the lock - /// to a shared lock. If it has a shared lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified how shared locks interact with locks acquired by - /// non-WASI programs. - /// - /// This function blocks until the lock can be acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. - lock-shared: func(this: descriptor) -> result<_, error-code> + /// Create a directory. + /// + /// Note: This is similar to `mkdirat` in POSIX. + create-directory-at: func( + /// The relative path at which to create the directory. + path: string, + ) -> result<_, error-code> - /// Request an exclusive advisory lock for an open file. - /// - /// This requests an *exclusive* lock; no other locks may be held for the - /// file while an exclusive lock is held. - /// - /// If the open file has a shared lock and there are no exclusive locks held - /// for the file, this function upgrades the lock to an exclusive lock. If the - /// open file already has an exclusive lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified whether this function succeeds if the file descriptor - /// is not opened for writing. It is unspecified how exclusive locks interact - /// with locks acquired by non-WASI programs. - /// - /// This function blocks until the lock can be acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. - lock-exclusive: func(this: descriptor) -> result<_, error-code> + /// Return the attributes of an open file or directory. + /// + /// Note: This is similar to `fstat` in POSIX, except that it does not return + /// device and inode information. For testing whether two descriptors refer to + /// the same underlying filesystem object, use `is-same-object`. To obtain + /// additional data that can be used do determine whether a file has been + /// modified, use `metadata-hash`. + /// + /// Note: This was called `fd_filestat_get` in earlier versions of WASI. + stat: func() -> result - /// Request a shared advisory lock for an open file. - /// - /// This requests a *shared* lock; more than one shared lock can be held for - /// a file at the same time. - /// - /// If the open file has an exclusive lock, this function downgrades the lock - /// to a shared lock. If it has a shared lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified how shared locks interact with locks acquired by - /// non-WASI programs. - /// - /// This function returns `error-code::would-block` if the lock cannot be - /// acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. - try-lock-shared: func(this: descriptor) -> result<_, error-code> + /// Return the attributes of a file or directory. + /// + /// Note: This is similar to `fstatat` in POSIX, except that it does not + /// return device and inode information. See the `stat` description for a + /// discussion of alternatives. + /// + /// Note: This was called `path_filestat_get` in earlier versions of WASI. + stat-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result + + /// Adjust the timestamps of a file or directory. + /// + /// Note: This is similar to `utimensat` in POSIX. + /// + /// Note: This was called `path_filestat_set_times` in earlier versions of + /// WASI. + set-times-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to operate on. + path: string, + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code> + + /// Create a hard link. + /// + /// Note: This is similar to `linkat` in POSIX. + link-at: func( + /// Flags determining the method of how the path is resolved. + old-path-flags: path-flags, + /// The relative source path from which to link. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: borrow, + /// The relative destination path at which to create the hard link. + new-path: string, + ) -> result<_, error-code> + + /// Open a file or directory. + /// + /// The returned descriptor is not guaranteed to be the lowest-numbered + /// descriptor not currently open/ it is randomized to prevent applications + /// from depending on making assumptions about indexes, since this is + /// error-prone in multi-threaded contexts. The returned descriptor is + /// guaranteed to be less than 2**31. + /// + /// If `flags` contains `descriptor-flags::mutate-directory`, and the base + /// descriptor doesn't have `descriptor-flags::mutate-directory` set, + /// `open-at` fails with `error-code::read-only`. + /// + /// If `flags` contains `write` or `mutate-directory`, or `open-flags` + /// contains `truncate` or `create`, and the base descriptor doesn't have + /// `descriptor-flags::mutate-directory` set, `open-at` fails with + /// `error-code::read-only`. + /// + /// Note: This is similar to `openat` in POSIX. + open-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the object to open. + path: string, + /// The method by which to open the file. + open-flags: open-flags, + /// Flags to use for the resulting descriptor. + %flags: descriptor-flags, + /// Permissions to use when creating a new file. + modes: modes + ) -> result + + /// Read the contents of a symbolic link. + /// + /// If the contents contain an absolute or rooted path in the underlying + /// filesystem, this function fails with `error-code::not-permitted`. + /// + /// Note: This is similar to `readlinkat` in POSIX. + readlink-at: func( + /// The relative path of the symbolic link from which to read. + path: string, + ) -> result - /// Request an exclusive advisory lock for an open file. - /// - /// This requests an *exclusive* lock; no other locks may be held for the - /// file while an exclusive lock is held. - /// - /// If the open file has a shared lock and there are no exclusive locks held - /// for the file, this function upgrades the lock to an exclusive lock. If the - /// open file already has an exclusive lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified whether this function succeeds if the file descriptor - /// is not opened for writing. It is unspecified how exclusive locks interact - /// with locks acquired by non-WASI programs. - /// - /// This function returns `error-code::would-block` if the lock cannot be - /// acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. - try-lock-exclusive: func(this: descriptor) -> result<_, error-code> + /// Remove a directory. + /// + /// Return `error-code::not-empty` if the directory is not empty. + /// + /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + remove-directory-at: func( + /// The relative path to a directory to remove. + path: string, + ) -> result<_, error-code> - /// Release a shared or exclusive lock on an open file. - /// - /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. - unlock: func(this: descriptor) -> result<_, error-code> + /// Rename a filesystem object. + /// + /// Note: This is similar to `renameat` in POSIX. + rename-at: func( + /// The relative source path of the file or directory to rename. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: borrow, + /// The relative destination path to which to rename the file or directory. + new-path: string, + ) -> result<_, error-code> + + /// Create a symbolic link (also known as a "symlink"). + /// + /// If `old-path` starts with `/`, the function fails with + /// `error-code::not-permitted`. + /// + /// Note: This is similar to `symlinkat` in POSIX. + symlink-at: func( + /// The contents of the symbolic link. + old-path: string, + /// The relative destination path at which to create the symbolic link. + new-path: string, + ) -> result<_, error-code> + + /// Check accessibility of a filesystem path. + /// + /// Check whether the given filesystem path names an object which is + /// readable, writable, or executable, or whether it exists. + /// + /// This does not a guarantee that subsequent accesses will succeed, as + /// filesystem permissions may be modified asynchronously by external + /// entities. + /// + /// Note: This is similar to `faccessat` with the `AT_EACCESS` flag in POSIX. + access-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to check. + path: string, + /// The type of check to perform. + %type: access-type + ) -> result<_, error-code> + + /// Unlink a filesystem object that is not a directory. + /// + /// Return `error-code::is-directory` if the path refers to a directory. + /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + unlink-file-at: func( + /// The relative path to a file to unlink. + path: string, + ) -> result<_, error-code> + + /// Change the permissions of a filesystem object that is not a directory. + /// + /// Note that the ultimate meanings of these permissions is + /// filesystem-specific. + /// + /// Note: This is similar to `fchmodat` in POSIX. + change-file-permissions-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to operate on. + path: string, + /// The new permissions for the filesystem object. + modes: modes, + ) -> result<_, error-code> + + /// Change the permissions of a directory. + /// + /// Note that the ultimate meanings of these permissions is + /// filesystem-specific. + /// + /// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" + /// flag. `read` on a directory implies readability and searchability, and + /// `execute` is not valid for directories. + /// + /// Note: This is similar to `fchmodat` in POSIX. + change-directory-permissions-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to operate on. + path: string, + /// The new permissions for the directory. + modes: modes, + ) -> result<_, error-code> + + /// Request a shared advisory lock for an open file. + /// + /// This requests a *shared* lock; more than one shared lock can be held for + /// a file at the same time. + /// + /// If the open file has an exclusive lock, this function downgrades the lock + /// to a shared lock. If it has a shared lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified how shared locks interact with locks acquired by + /// non-WASI programs. + /// + /// This function blocks until the lock can be acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. + lock-shared: func() -> result<_, error-code> - /// Dispose of the specified `descriptor`, after which it may no longer - /// be used. - drop-descriptor: func(this: descriptor) + /// Request an exclusive advisory lock for an open file. + /// + /// This requests an *exclusive* lock; no other locks may be held for the + /// file while an exclusive lock is held. + /// + /// If the open file has a shared lock and there are no exclusive locks held + /// for the file, this function upgrades the lock to an exclusive lock. If the + /// open file already has an exclusive lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified whether this function succeeds if the file descriptor + /// is not opened for writing. It is unspecified how exclusive locks interact + /// with locks acquired by non-WASI programs. + /// + /// This function blocks until the lock can be acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. + lock-exclusive: func() -> result<_, error-code> - /// A stream of directory entries. - /// - /// This [represents a stream of `dir-entry`](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Streams). - type directory-entry-stream = u32 + /// Request a shared advisory lock for an open file. + /// + /// This requests a *shared* lock; more than one shared lock can be held for + /// a file at the same time. + /// + /// If the open file has an exclusive lock, this function downgrades the lock + /// to a shared lock. If it has a shared lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified how shared locks interact with locks acquired by + /// non-WASI programs. + /// + /// This function returns `error-code::would-block` if the lock cannot be + /// acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. + try-lock-shared: func() -> result<_, error-code> - /// Read a single directory entry from a `directory-entry-stream`. - read-directory-entry: func( - this: directory-entry-stream - ) -> result, error-code> + /// Request an exclusive advisory lock for an open file. + /// + /// This requests an *exclusive* lock; no other locks may be held for the + /// file while an exclusive lock is held. + /// + /// If the open file has a shared lock and there are no exclusive locks held + /// for the file, this function upgrades the lock to an exclusive lock. If the + /// open file already has an exclusive lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified whether this function succeeds if the file descriptor + /// is not opened for writing. It is unspecified how exclusive locks interact + /// with locks acquired by non-WASI programs. + /// + /// This function returns `error-code::would-block` if the lock cannot be + /// acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. + try-lock-exclusive: func() -> result<_, error-code> - /// Dispose of the specified `directory-entry-stream`, after which it may no longer - /// be used. - drop-directory-entry-stream: func(this: directory-entry-stream) + /// Release a shared or exclusive lock on an open file. + /// + /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. + unlock: func() -> result<_, error-code> - /// Test whether two descriptors refer to the same filesystem object. - /// - /// In POSIX, this corresponds to testing whether the two descriptors have the - /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. - /// wasi-filesystem does not expose device and inode numbers, so this function - /// may be used instead. - is-same-object: func(this: descriptor, other: descriptor) -> bool - - /// Return a hash of the metadata associated with a filesystem object referred - /// to by a descriptor. - /// - /// This returns a hash of the last-modification timestamp and file size, and - /// may also include the inode number, device number, birth timestamp, and - /// other metadata fields that may change when the file is modified or - /// replaced. It may also include a secret value chosen by the - /// implementation and not otherwise exposed. - /// - /// Implementations are encourated to provide the following properties: - /// - /// - If the file is not modified or replaced, the computed hash value should - /// usually not change. - /// - If the object is modified or replaced, the computed hash value should - /// usually change. - /// - The inputs to the hash should not be easily computable from the - /// computed hash. - /// - /// However, none of these is required. - metadata-hash: func( - this: descriptor, - ) -> result + /// Test whether two descriptors refer to the same filesystem object. + /// + /// In POSIX, this corresponds to testing whether the two descriptors have the + /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. + /// wasi-filesystem does not expose device and inode numbers, so this function + /// may be used instead. + is-same-object: func(other: borrow) -> bool + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a descriptor. + /// + /// This returns a hash of the last-modification timestamp and file size, and + /// may also include the inode number, device number, birth timestamp, and + /// other metadata fields that may change when the file is modified or + /// replaced. It may also include a secret value chosen by the + /// implementation and not otherwise exposed. + /// + /// Implementations are encourated to provide the following properties: + /// + /// - If the file is not modified or replaced, the computed hash value should + /// usually not change. + /// - If the object is modified or replaced, the computed hash value should + /// usually change. + /// - The inputs to the hash should not be easily computable from the + /// computed hash. + /// + /// However, none of these is required. + metadata-hash: func() -> result - /// Return a hash of the metadata associated with a filesystem object referred - /// to by a directory descriptor and a relative path. - /// - /// This performs the same hash computation as `metadata-hash`. - metadata-hash-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to inspect. - path: string, - ) -> result + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a directory descriptor and a relative path. + /// + /// This performs the same hash computation as `metadata-hash`. + metadata-hash-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result + } + + /// A stream of directory entries. + resource directory-entry-stream { + /// Read a single directory entry from a `directory-entry-stream`. + read-directory-entry: func() -> result, error-code> + } } diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit index b51f484f8..5fa7eafdb 100644 --- a/proposals/cli/wit/deps/filesystem/world.wit +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -1,6 +1,6 @@ package wasi:filesystem -world example-world { +world imports { import types import preopens } diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit new file mode 100644 index 000000000..e95762b91 --- /dev/null +++ b/proposals/cli/wit/deps/io/poll.wit @@ -0,0 +1,34 @@ +package wasi:io + +/// A poll API intended to let users wait for I/O events on multiple handles +/// at once. +interface poll { + /// A "pollable" handle. + resource pollable + + /// Poll for completion on a set of pollables. + /// + /// This function takes a list of pollables, which identify I/O sources of + /// interest, and waits until one or more of the events is ready for I/O. + /// + /// The result `list` contains one or more indices of handles in the + /// argument list that is ready for I/O. + /// + /// If the list contains more elements than can be indexed with a `u32` + /// value, this function traps. + /// + /// A timeout can be implemented by adding a pollable from the + /// wasi-clocks API to the list. + /// + /// This function does not return a `result`; polling in itself does not + /// do any I/O so it doesn't fail. If any of the I/O sources identified by + /// the pollables has an error, it is indicated by marking the source as + /// being reaedy for I/O. + poll-list: func(in: list>) -> list + + /// Poll for completion on a single pollable. + /// + /// This function is similar to `poll-list`, but operates on only a single + /// pollable. When it returns, the handle is ready for I/O. + poll-one: func(in: borrow) +} diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index de8694bda..eeeff5058 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -1,14 +1,12 @@ +package wasi:io + /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { - use wasi:poll/poll.{pollable} - - /// An error type returned from a stream operation. Currently this - /// doesn't provide any additional information. - record stream-error {} + use poll.{pollable} /// Streams provide a sequence of data and then end; once they end, they /// no longer provide any further data. @@ -19,208 +17,269 @@ interface streams { enum stream-status { /// The stream is open and may produce further data. open, - /// The stream has ended and will not produce any further data. + /// When reading, this indicates that the stream will not produce + /// further data. + /// When writing, this indicates that the stream will no longer be read. + /// Further writes are still permitted. ended, } - /// An input bytestream. In the future, this will be replaced by handle - /// types. - /// - /// This conceptually represents a `stream`. It's temporary - /// scaffolding until component-model's async features are ready. + /// An input bytestream. /// /// `input-stream`s are *non-blocking* to the extent practical on underlying /// platforms. I/O operations always return promptly; if fewer bytes are /// promptly available than requested, they return the number of bytes promptly /// available, which could even be zero. To wait for data to be available, - /// use the `subscribe-to-input-stream` function to obtain a `pollable` which - /// can be polled for using `wasi_poll`. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type input-stream = u32 + /// use the `subscribe` function to obtain a `pollable` which can be polled + /// for using `wasi:io/poll`. + resource input-stream { + /// Perform a non-blocking read from the stream. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a `stream-status` which, indicates whether further + /// reads are expected to produce data. The returned list will contain up to + /// `len` bytes; it may return fewer than requested, but not more. An + /// empty list and `stream-status:open` indicates no more data is + /// available at this time, and that the pollable given by `subscribe` + /// will be ready when more data is available. + /// + /// Once a stream has reached the end, subsequent calls to `read` or + /// `skip` will always report `stream-status:ended` rather than producing more + /// data. + /// + /// When the caller gives a `len` of 0, it represents a request to read 0 + /// bytes. This read should always succeed and return an empty list and + /// the current `stream-status`. + /// + /// The `len` parameter is a `u64`, which could represent a list of u8 which + /// is not possible to allocate in wasm32, or not desirable to allocate as + /// as a return value by the callee. The callee may return a list of bytes + /// less than `len` in size while more bytes are available for reading. + read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-status>> - /// Read bytes from a stream. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a `stream-status` which indicates whether the end of - /// the stream was reached. The returned list will contain up to `len` - /// bytes; it may return fewer than requested, but not more. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// If `len` is 0, it represents a request to read 0 bytes, which should - /// always succeed, assuming the stream hasn't reached its end yet, and - /// return an empty list. - /// - /// The len here is a `u64`, but some callees may not be able to allocate - /// a buffer as large as that would imply. - /// FIXME: describe what happens if allocation fails. - read: func( - this: input-stream, - /// The maximum number of bytes to read - len: u64 - ) -> result, stream-status>, stream-error> - - /// Read bytes from a stream, with blocking. - /// - /// This is similar to `read`, except that it blocks until at least one - /// byte can be read. - blocking-read: func( - this: input-stream, - /// The maximum number of bytes to read - len: u64 - ) -> result, stream-status>, stream-error> - - /// Skip bytes from a stream. - /// - /// This is similar to the `read` function, but avoids copying the - /// bytes into the instance. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// This function returns the number of bytes skipped, along with a - /// `stream-status` indicating whether the end of the stream was - /// reached. The returned value will be at most `len`; it may be less. - skip: func( - this: input-stream, - /// The maximum number of bytes to skip. - len: u64, - ) -> result, stream-error> - - /// Skip bytes from a stream, with blocking. - /// - /// This is similar to `skip`, except that it blocks until at least one - /// byte can be consumed. - blocking-skip: func( - this: input-stream, - /// The maximum number of bytes to skip. - len: u64, - ) -> result, stream-error> - - /// Create a `pollable` which will resolve once either the specified stream - /// has bytes available to read or the other end of the stream has been - /// closed. - subscribe-to-input-stream: func(this: input-stream) -> pollable - - /// Dispose of the specified `input-stream`, after which it may no longer - /// be used. - drop-input-stream: func(this: input-stream) - - /// An output bytestream. In the future, this will be replaced by handle - /// types. + /// Read bytes from a stream, after blocking until at least one byte can + /// be read. Except for blocking, identical to `read`. + blocking-read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-status>> + + /// Skip bytes from a stream. + /// + /// This is similar to the `read` function, but avoids copying the + /// bytes into the instance. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// This function returns the number of bytes skipped, along with a + /// `stream-status` indicating whether the end of the stream was + /// reached. The returned value will be at most `len`; it may be less. + skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result> + + /// Skip bytes from a stream, after blocking until at least one byte + /// can be skipped. Except for blocking behavior, identical to `skip`. + blocking-skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result> + + /// Create a `pollable` which will resolve once either the specified stream + /// has bytes available to read or the other end of the stream has been + /// closed. + /// The created `pollable` is a child resource of the `input-stream`. + /// Implementations may trap if the `input-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe: func() -> pollable + } + + /// An error for output-stream operations. /// - /// This conceptually represents a `stream`. It's temporary - /// scaffolding until component-model's async features are ready. + /// Contrary to input-streams, a closed output-stream is reported using + /// an error. + enum write-error { + /// The last operation (a write or flush) failed before completion. + last-operation-failed, + /// The stream is closed: no more input will be accepted by the + /// stream. A closed output-stream will return this error on all + /// future operations. + closed + } + + /// An output bytestream. /// /// `output-stream`s are *non-blocking* to the extent practical on /// underlying platforms. Except where specified otherwise, I/O operations also /// always return promptly, after the number of bytes that can be written /// promptly, which could even be zero. To wait for the stream to be ready to - /// accept data, the `subscribe-to-output-stream` function to obtain a - /// `pollable` which can be polled for using `wasi_poll`. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type output-stream = u32 + /// accept data, the `subscribe` function to obtain a `pollable` which can be + /// polled for using `wasi:io/poll`. + resource output-stream { + /// Check readiness for writing. This function never blocks. + /// + /// Returns the number of bytes permitted for the next call to `write`, + /// or an error. Calling `write` with more bytes than this function has + /// permitted will trap. + /// + /// When this function returns 0 bytes, the `subscribe` pollable will + /// become ready when this function will report at least 1 byte, or an + /// error. + check-write: func() -> result - /// Write bytes to a stream. - /// - /// This function returns a `u64` indicating the number of bytes from - /// `buf` that were written; it may be less than the full list. - write: func( - this: output-stream, - /// Data to write - buf: list - ) -> result - - /// Write bytes to a stream, with blocking. - /// - /// This is similar to `write`, except that it blocks until at least one - /// byte can be written. - blocking-write: func( - this: output-stream, - /// Data to write - buf: list - ) -> result - - /// Write multiple zero bytes to a stream. - /// - /// This function returns a `u64` indicating the number of zero bytes - /// that were written; it may be less than `len`. - write-zeroes: func( - this: output-stream, - /// The number of zero bytes to write - len: u64 - ) -> result - - /// Write multiple zero bytes to a stream, with blocking. - /// - /// This is similar to `write-zeroes`, except that it blocks until at least - /// one byte can be written. - blocking-write-zeroes: func( - this: output-stream, - /// The number of zero bytes to write - len: u64 - ) -> result - - /// Read from one stream and write to another. - /// - /// This function returns the number of bytes transferred; it may be less - /// than `len`. - /// - /// Unlike other I/O functions, this function blocks until all the data - /// read from the input stream has been written to the output stream. - splice: func( - this: output-stream, - /// The stream to read from - src: input-stream, - /// The number of bytes to splice - len: u64, - ) -> result, stream-error> - - /// Read from one stream and write to another, with blocking. - /// - /// This is similar to `splice`, except that it blocks until at least - /// one byte can be read. - blocking-splice: func( - this: output-stream, - /// The stream to read from - src: input-stream, - /// The number of bytes to splice - len: u64, - ) -> result, stream-error> - - /// Forward the entire contents of an input stream to an output stream. - /// - /// This function repeatedly reads from the input stream and writes - /// the data to the output stream, until the end of the input stream - /// is reached, or an error is encountered. - /// - /// Unlike other I/O functions, this function blocks until the end - /// of the input stream is seen and all the data has been written to - /// the output stream. - /// - /// This function returns the number of bytes transferred. - forward: func( - this: output-stream, - /// The stream to read from - src: input-stream - ) -> result - - /// Create a `pollable` which will resolve once either the specified stream - /// is ready to accept bytes or the other end of the stream has been closed. - subscribe-to-output-stream: func(this: output-stream) -> pollable - - /// Dispose of the specified `output-stream`, after which it may no longer - /// be used. - drop-output-stream: func(this: output-stream) + /// Perform a write. This function never blocks. + /// + /// Precondition: check-write gave permit of Ok(n) and contents has a + /// length of less than or equal to n. Otherwise, this function will trap. + /// + /// returns Err(closed) without writing if the stream has closed since + /// the last call to check-write provided a permit. + write: func( + contents: list + ) -> result<_, write-error> + + /// Perform a write of up to 4096 bytes, and then flush the stream. Block + /// until all of these operations are complete, or an error occurs. + /// + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe`, `write`, and `flush`, and is implemented with the + /// following pseudo-code: + /// + /// ```text + /// let pollable = this.subscribe(); + /// while !contents.is_empty() { + /// // Wait for the stream to become writable + /// poll-one(pollable); + /// let Ok(n) = this.check-write(); // eliding error handling + /// let len = min(n, contents.len()); + /// let (chunk, rest) = contents.split_at(len); + /// this.write(chunk ); // eliding error handling + /// contents = rest; + /// } + /// this.flush(); + /// // Wait for completion of `flush` + /// poll-one(pollable); + /// // Check for any errors that arose during `flush` + /// let _ = this.check-write(); // eliding error handling + /// ``` + blocking-write-and-flush: func( + contents: list + ) -> result<_, write-error> + + /// Request to flush buffered output. This function never blocks. + /// + /// This tells the output-stream that the caller intends any buffered + /// output to be flushed. the output which is expected to be flushed + /// is all that has been passed to `write` prior to this call. + /// + /// Upon calling this function, the `output-stream` will not accept any + /// writes (`check-write` will return `ok(0)`) until the flush has + /// completed. The `subscribe` pollable will become ready when the + /// flush has completed and the stream can accept more writes. + flush: func() -> result<_, write-error> + + /// Request to flush buffered output, and block until flush completes + /// and stream is ready for writing again. + blocking-flush: func() -> result<_, write-error> + + /// Create a `pollable` which will resolve once the output-stream + /// is ready for more writing, or an error has occured. When this + /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an + /// error. + /// + /// If the stream is closed, this pollable is always ready immediately. + /// + /// The created `pollable` is a child resource of the `output-stream`. + /// Implementations may trap if the `output-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe: func() -> pollable + + /// Write zeroes to a stream. + /// + /// this should be used precisely like `write` with the exact same + /// preconditions (must use check-write first), but instead of + /// passing a list of bytes, you simply pass the number of zero-bytes + /// that should be written. + write-zeroes: func( + /// The number of zero-bytes to write + len: u64 + ) -> result<_, write-error> + + /// Perform a write of up to 4096 zeroes, and then flush the stream. + /// Block until all of these operations are complete, or an error + /// occurs. + /// + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with + /// the following pseudo-code: + /// + /// ```text + /// let pollable = this.subscribe(); + /// while num_zeroes != 0 { + /// // Wait for the stream to become writable + /// poll-one(pollable); + /// let Ok(n) = this.check-write(); // eliding error handling + /// let len = min(n, num_zeroes); + /// this.write-zeroes(len); // eliding error handling + /// num_zeroes -= len; + /// } + /// this.flush(); + /// // Wait for completion of `flush` + /// poll-one(pollable); + /// // Check for any errors that arose during `flush` + /// let _ = this.check-write(); // eliding error handling + /// ``` + blocking-write-zeroes-and-flush: func( + /// The number of zero-bytes to write + len: u64 + ) -> result<_, write-error> + + /// Read from one stream and write to another. + /// + /// This function returns the number of bytes transferred; it may be less + /// than `len`. + /// + /// Unlike other I/O functions, this function blocks until all the data + /// read from the input stream has been written to the output stream. + splice: func( + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result> + + /// Read from one stream and write to another, with blocking. + /// + /// This is similar to `splice`, except that it blocks until at least + /// one byte can be read. + blocking-splice: func( + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result> + + /// Forward the entire contents of an input stream to an output stream. + /// + /// This function repeatedly reads from the input stream and writes + /// the data to the output stream, until the end of the input stream + /// is reached, or an error is encountered. + /// + /// Unlike other I/O functions, this function blocks until the end + /// of the input stream is seen and all the data has been written to + /// the output stream. + /// + /// This function returns the number of bytes transferred, and the status of + /// the output stream. + forward: func( + /// The stream to read from + src: input-stream + ) -> result> + } } diff --git a/proposals/cli/wit/deps/io/world.wit b/proposals/cli/wit/deps/io/world.wit index b7f625334..8738dba75 100644 --- a/proposals/cli/wit/deps/io/world.wit +++ b/proposals/cli/wit/deps/io/world.wit @@ -1,5 +1,6 @@ package wasi:io -world example-world { +world imports { import streams + import poll } diff --git a/proposals/cli/wit/deps/poll/poll.wit b/proposals/cli/wit/deps/poll/poll.wit deleted file mode 100644 index fa82b6063..000000000 --- a/proposals/cli/wit/deps/poll/poll.wit +++ /dev/null @@ -1,49 +0,0 @@ -/// A poll API intended to let users wait for I/O events on multiple handles -/// at once. -interface poll { - /// A "pollable" handle. - /// - /// This is conceptually represents a `stream<_, _>`, or in other words, - /// a stream that one can wait on, repeatedly, but which does not itself - /// produce any data. It's temporary scaffolding until component-model's - /// async features are ready. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// `pollable` lifetimes are not automatically managed. Users must ensure - /// that they do not outlive the resource they reference. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type pollable = u32 - - /// Dispose of the specified `pollable`, after which it may no longer - /// be used. - drop-pollable: func(this: pollable) - - /// Poll for completion on a set of pollables. - /// - /// This function takes a list of pollables, which identify I/O sources of - /// interest, and waits until one or more of the events is ready for I/O. - /// - /// The result `list` is the same length as the argument - /// `list`, and indicates the readiness of each corresponding - /// element in that list, with true indicating ready. A single call can - /// return multiple true elements. - /// - /// A timeout can be implemented by adding a pollable from the - /// wasi-clocks API to the list. - /// - /// This function does not return a `result`; polling in itself does not - /// do any I/O so it doesn't fail. If any of the I/O sources identified by - /// the pollables has an error, it is indicated by marking the source as - /// ready in the `list`. - /// - /// The "oneoff" in the name refers to the fact that this function must do a - /// linear scan through the entire list of subscriptions, which may be - /// inefficient if the number is large and the same subscriptions are used - /// many times. In the future, this is expected to be obsoleted by the - /// component model async proposal, which will include a scalable waiting - /// facility. - poll-oneoff: func(in: list) -> list -} diff --git a/proposals/cli/wit/deps/poll/world.wit b/proposals/cli/wit/deps/poll/world.wit deleted file mode 100644 index d08cadc05..000000000 --- a/proposals/cli/wit/deps/poll/world.wit +++ /dev/null @@ -1,5 +0,0 @@ -package wasi:poll - -world example-world { - import poll -} diff --git a/proposals/cli/wit/deps/random/world.wit b/proposals/cli/wit/deps/random/world.wit index 3c3d16554..41dc9ed10 100644 --- a/proposals/cli/wit/deps/random/world.wit +++ b/proposals/cli/wit/deps/random/world.wit @@ -1,6 +1,6 @@ package wasi:random -world example-world { +world imports { import random import insecure import insecure-seed diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index f15d19d03..f998aae14 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,6 +1,6 @@ interface ip-name-lookup { - use wasi:poll/poll.{pollable} + use wasi:io/poll.{pollable} use network.{network, error-code, ip-address, ip-address-family} @@ -34,36 +34,28 @@ interface ip-name-lookup { /// - /// - /// - - resolve-addresses: func(network: network, name: string, address-family: option, include-unavailable: bool) -> result - - - - type resolve-address-stream = u32 - - /// Returns the next address from the resolver. - /// - /// This function should be called multiple times. On each call, it will - /// return the next address in connection order preference. If all - /// addresses have been exhausted, this function returns `none`. - /// After which, you should release the stream with `drop-resolve-address-stream`. - /// - /// This function never returns IPv4-mapped IPv6 addresses. - /// - /// # Typical errors - /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) - /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) - /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) - /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) - resolve-next-address: func(this: resolve-address-stream) -> result, error-code> - - /// Dispose of the specified `resolve-address-stream`, after which it may no longer be used. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-resolve-address-stream: func(this: resolve-address-stream) - - /// Create a `pollable` which will resolve once the stream is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func(this: resolve-address-stream) -> pollable + resolve-addresses: func(network: borrow, name: string, address-family: option, include-unavailable: bool) -> result + + resource resolve-address-stream { + /// Returns the next address from the resolver. + /// + /// This function should be called multiple times. On each call, it will + /// return the next address in connection order preference. If all + /// addresses have been exhausted, this function returns `none`. + /// + /// This function never returns IPv4-mapped IPv6 addresses. + /// + /// # Typical errors + /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) + /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) + /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) + /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) + resolve-next-address: func() -> result, error-code> + + /// Create a `pollable` which will resolve once the stream is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable + } } diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit index 2d09bcbdc..8214eaaf7 100644 --- a/proposals/cli/wit/deps/sockets/network.wit +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -1,17 +1,9 @@ interface network { - /// An opaque resource that represents access to (a subset of) the network. + /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. - /// - /// FYI, In the future this will be replaced by handle types. - type network = u32 - - /// Dispose of the specified `network`, after which it may no longer be used. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-network: func(this: network) - + resource network /// Error codes. /// @@ -183,4 +175,4 @@ interface network { ipv6(ipv6-socket-address), } -} \ No newline at end of file +} diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index 4edb1db7f..175626cc7 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -1,13 +1,9 @@ interface tcp { use wasi:io/streams.{input-stream, output-stream} - use wasi:poll/poll.{pollable} + use wasi:io/poll.{pollable} use network.{network, error-code, ip-socket-address, ip-address-family} - /// A TCP socket handle. - type tcp-socket = u32 - - enum shutdown-type { /// Similar to `SHUT_RD` in POSIX. receive, @@ -20,238 +16,234 @@ interface tcp { } - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will - /// implicitly bind the socket. - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) - /// - `already-bound`: The socket is already bound. (EINVAL) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> - finish-bind: func(this: tcp-socket) -> result<_, error-code> - - /// Connect to a remote endpoint. - /// - /// On success: - /// - the socket is transitioned into the Connection state - /// - a pair of streams is returned that can be used to read & write to the connection - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) - /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `already-connected`: The socket is already in the Connection state. (EISCONN) - /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `timeout`: Connection timed out. (ETIMEDOUT) - /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) - /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> - finish-connect: func(this: tcp-socket) -> result, error-code> - - /// Start listening for new connections. - /// - /// Transitions the socket into the Listener state. - /// - /// Unlike POSIX: - /// - this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - the socket must already be explicitly bound. - /// - /// # Typical `start` errors - /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) - /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) - /// - `already-listening`: The socket is already in the Listener state. - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - `not-in-progress`: A `listen` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-listen: func(this: tcp-socket) -> result<_, error-code> - finish-listen: func(this: tcp-socket) -> result<_, error-code> - - /// Accept a new client socket. - /// - /// The returned socket is bound and in the Connection state. - /// - /// On success, this function returns the newly accepted client socket along with - /// a pair of streams that can be used to read & write to the connection. - /// - /// # Typical errors - /// - `not-listening`: Socket is not in the Listener state. (EINVAL) - /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) - /// - /// Host implementations must skip over transient errors returned by the native accept syscall. - /// - /// # References - /// - - /// - - /// - - /// - - accept: func(this: tcp-socket) -> result, error-code> - - /// Get the bound local address. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - local-address: func(this: tcp-socket) -> result - - /// Get the bound remote address. - /// - /// # Typical errors - /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - remote-address: func(this: tcp-socket) -> result - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: tcp-socket) -> ip-address-family + /// A TCP socket handle. + resource tcp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will + /// implicitly bind the socket. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) + /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code> + finish-bind: func() -> result<_, error-code> + + /// Connect to a remote endpoint. + /// + /// On success: + /// - the socket is transitioned into the Connection state + /// - a pair of streams is returned that can be used to read & write to the connection + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `already-connected`: The socket is already in the Connection state. (EISCONN) + /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code> + finish-connect: func() -> result, error-code> + + /// Start listening for new connections. + /// + /// Transitions the socket into the Listener state. + /// + /// Unlike POSIX: + /// - this function is async. This enables interactive WASI hosts to inject permission prompts. + /// - the socket must already be explicitly bound. + /// + /// # Typical `start` errors + /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) + /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) + /// - `already-listening`: The socket is already in the Listener state. + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// - `not-in-progress`: A `listen` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-listen: func() -> result<_, error-code> + finish-listen: func() -> result<_, error-code> + + /// Accept a new client socket. + /// + /// The returned socket is bound and in the Connection state. + /// + /// On success, this function returns the newly accepted client socket along with + /// a pair of streams that can be used to read & write to the connection. + /// + /// # Typical errors + /// - `not-listening`: Socket is not in the Listener state. (EINVAL) + /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) + /// + /// Host implementations must skip over transient errors returned by the native accept syscall. + /// + /// # References + /// - + /// - + /// - + /// - + accept: func() -> result, error-code> + + /// Get the bound local address. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func() -> result + + /// Get the bound remote address. + /// + /// # Typical errors + /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func() -> result + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. - /// - `already-bound`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - ipv6-only: func(this: tcp-socket) -> result - set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error-code> - - /// Hints the desired listen queue size. Implementations are free to ignore this. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error-code> - - /// Equivalent to the SO_KEEPALIVE socket option. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - keep-alive: func(this: tcp-socket) -> result - set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error-code> - - /// Equivalent to the TCP_NODELAY socket option. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - no-delay: func(this: tcp-socket) -> result - set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error-code> + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// # Typical errors + /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. + /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + ipv6-only: func() -> result + set-ipv6-only: func(value: bool) -> result<_, error-code> + + /// Hints the desired listen queue size. Implementations are free to ignore this. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + set-listen-backlog-size: func(value: u64) -> result<_, error-code> + + /// Equivalent to the SO_KEEPALIVE socket option. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + keep-alive: func() -> result + set-keep-alive: func(value: bool) -> result<_, error-code> + + /// Equivalent to the TCP_NODELAY socket option. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + no-delay: func() -> result + set-no-delay: func(value: bool) -> result<_, error-code> - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `already-listening`: (set) The socket is already in the Listener state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - unicast-hop-limit: func(this: tcp-socket) -> result - set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error-code> - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `already-listening`: (set) The socket is already in the Listener state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - receive-buffer-size: func(this: tcp-socket) -> result - set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> - send-buffer-size: func(this: tcp-socket) -> result - set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> - - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func(this: tcp-socket) -> pollable - - /// Initiate a graceful shutdown. - /// - /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read - /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. - /// Any data still in the receive queue at time of calling `shutdown` will be discarded. - /// - send: the socket is not expecting to send any more data to the peer. All subsequent write - /// operations on the `output-stream` associated with this socket will return an error. - /// - both: same effect as receive & send combined. - /// - /// The shutdown function does not close (drop) the socket. - /// - /// # Typical errors - /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error-code> - - /// Dispose of the specified `tcp-socket`, after which it may no longer be used. - /// - /// Similar to the POSIX `close` function. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-tcp-socket: func(this: tcp-socket) + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `already-listening`: (set) The socket is already in the Listener state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + unicast-hop-limit: func() -> result + set-unicast-hop-limit: func(value: u8) -> result<_, error-code> + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `already-listening`: (set) The socket is already in the Listener state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + receive-buffer-size: func() -> result + set-receive-buffer-size: func(value: u64) -> result<_, error-code> + send-buffer-size: func() -> result + set-send-buffer-size: func(value: u64) -> result<_, error-code> + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable + + /// Initiate a graceful shutdown. + /// + /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read + /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. + /// Any data still in the receive queue at time of calling `shutdown` will be discarded. + /// - send: the socket is not expecting to send any more data to the peer. All subsequent write + /// operations on the `output-stream` associated with this socket will return an error. + /// - both: same effect as receive & send combined. + /// + /// The shutdown function does not close (drop) the socket. + /// + /// # Typical errors + /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code> + } } diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index 948ed581a..01e5b95b9 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,13 +1,9 @@ interface udp { - use wasi:poll/poll.{pollable} + use wasi:io/poll.{pollable} use network.{network, error-code, ip-socket-address, ip-address-family} - /// A UDP socket handle. - type udp-socket = u32 - - record datagram { data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. remote-address: ip-socket-address, @@ -22,201 +18,197 @@ interface udp { - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) - /// - `already-bound`: The socket is already bound. (EINVAL) - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> - finish-bind: func(this: udp-socket) -> result<_, error-code> - - /// Set the destination address. - /// - /// The local-address is updated based on the best network path to `remote-address`. - /// - /// When a destination address is set: - /// - all receive operations will only return datagrams sent from the provided `remote-address`. - /// - the `send` function can only be used to send to this destination. - /// - /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> - finish-connect: func(this: udp-socket) -> result<_, error-code> - - /// Receive messages on the socket. - /// - /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. - /// The returned list may contain fewer elements than requested, but never more. - /// If `max-results` is 0, this function returns successfully with an empty list. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. (EINVAL) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - receive: func(this: udp-socket, max-results: u64) -> result, error-code> - - /// Send messages on the socket. - /// - /// This function attempts to send all provided `datagrams` on the socket without blocking and - /// returns how many messages were actually sent (or queued for sending). - /// - /// This function semantically behaves the same as iterating the `datagrams` list and sequentially - /// sending each individual datagram until either the end of the list has been reached or the first error occurred. - /// If at least one datagram has been sent successfully, this function never returns an error. - /// - /// If the input list is empty, the function returns `ok(0)`. - /// - /// The remote address option is required. To send a message to the "connected" peer, - /// call `remote-address` to get their address. - /// - /// # Typical errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN) - /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. - /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) - /// - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - send: func(this: udp-socket, datagrams: list) -> result - - /// Get the current bound address. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - local-address: func(this: udp-socket) -> result - - /// Get the address set with `connect`. - /// - /// # Typical errors - /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - remote-address: func(this: udp-socket) -> result - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: udp-socket) -> ip-address-family - - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. - /// - `already-bound`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - ipv6-only: func(this: udp-socket) -> result - set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error-code> - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - unicast-hop-limit: func(this: udp-socket) -> result - set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error-code> - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. - /// - /// Fails when this socket is in the Listening state. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - receive-buffer-size: func(this: udp-socket) -> result - set-receive-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> - send-buffer-size: func(this: udp-socket) -> result - set-send-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> - - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func(this: udp-socket) -> pollable - - /// Dispose of the specified `udp-socket`, after which it may no longer be used. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-udp-socket: func(this: udp-socket) + /// A UDP socket handle. + resource udp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) + /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code> + finish-bind: func() -> result<_, error-code> + + /// Set the destination address. + /// + /// The local-address is updated based on the best network path to `remote-address`. + /// + /// When a destination address is set: + /// - all receive operations will only return datagrams sent from the provided `remote-address`. + /// - the `send` function can only be used to send to this destination. + /// + /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code> + finish-connect: func() -> result<_, error-code> + + /// Receive messages on the socket. + /// + /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. + /// The returned list may contain fewer elements than requested, but never more. + /// If `max-results` is 0, this function returns successfully with an empty list. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. (EINVAL) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + receive: func(max-results: u64) -> result, error-code> + + /// Send messages on the socket. + /// + /// This function attempts to send all provided `datagrams` on the socket without blocking and + /// returns how many messages were actually sent (or queued for sending). + /// + /// This function semantically behaves the same as iterating the `datagrams` list and sequentially + /// sending each individual datagram until either the end of the list has been reached or the first error occurred. + /// If at least one datagram has been sent successfully, this function never returns an error. + /// + /// If the input list is empty, the function returns `ok(0)`. + /// + /// The remote address option is required. To send a message to the "connected" peer, + /// call `remote-address` to get their address. + /// + /// # Typical errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN) + /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. + /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + send: func(datagrams: list) -> result + + /// Get the current bound address. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func() -> result + + /// Get the address set with `connect`. + /// + /// # Typical errors + /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func() -> result + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// # Typical errors + /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. + /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + ipv6-only: func() -> result + set-ipv6-only: func(value: bool) -> result<_, error-code> + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + unicast-hop-limit: func() -> result + set-unicast-hop-limit: func(value: u8) -> result<_, error-code> + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + receive-buffer-size: func() -> result + set-receive-buffer-size: func(value: u64) -> result<_, error-code> + send-buffer-size: func() -> result + set-send-buffer-size: func(value: u64) -> result<_, error-code> + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable + } } diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit index ca23d8698..12f3c2868 100644 --- a/proposals/cli/wit/deps/sockets/world.wit +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -1,6 +1,6 @@ package wasi:sockets -world example-world { +world imports { import instance-network import network import udp diff --git a/proposals/cli/wit/reactor.wit b/proposals/cli/wit/reactor.wit index 30ff96293..13da405e0 100644 --- a/proposals/cli/wit/reactor.wit +++ b/proposals/cli/wit/reactor.wit @@ -14,7 +14,7 @@ world reactor { import wasi:random/random import wasi:random/insecure import wasi:random/insecure-seed - import wasi:poll/poll + import wasi:io/poll import wasi:io/streams import environment import exit diff --git a/proposals/cli/wit/terminal.wit b/proposals/cli/wit/terminal.wit index f32e74437..b0a5bec2a 100644 --- a/proposals/cli/wit/terminal.wit +++ b/proposals/cli/wit/terminal.wit @@ -1,31 +1,19 @@ interface terminal-input { /// The input side of a terminal. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type terminal-input = u32 + resource terminal-input // In the future, this may include functions for disabling echoing, // disabling input buffering so that keyboard events are sent through // immediately, querying supported features, and so on. - - /// Dispose of the specified terminal-input after which it may no longer - /// be used. - drop-terminal-input: func(this: terminal-input) } interface terminal-output { /// The output side of a terminal. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type terminal-output = u32 + resource terminal-output // In the future, this may include functions for querying the terminal // size, being notified of terminal size changes, querying supported // features, and so on. - - /// Dispose of the specified terminal-output, after which it may no longer - /// be used. - drop-terminal-output: func(this: terminal-output) } /// An interface providing an optional `terminal-input` for stdin as a From 78f10244e26192b6b32073e0e235f73838680950 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 6 Oct 2023 14:29:58 -0500 Subject: [PATCH 1225/1772] Add semicolons in WIT files (#49) For more information see WebAssembly/component-model#249. --- proposals/io/.github/workflows/main.yml | 2 +- proposals/io/wit/poll.wit | 8 +++--- proposals/io/wit/streams.wit | 36 ++++++++++++------------- proposals/io/wit/world.wit | 6 ++--- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index e210671f2..b45623289 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -11,4 +11,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: WebAssembly/wit-abi-up-to-date@v15 + - uses: WebAssembly/wit-abi-up-to-date@v16 diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index e95762b91..254f53418 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -1,10 +1,10 @@ -package wasi:io +package wasi:io; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { /// A "pollable" handle. - resource pollable + resource pollable; /// Poll for completion on a set of pollables. /// @@ -24,11 +24,11 @@ interface poll { /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as /// being reaedy for I/O. - poll-list: func(in: list>) -> list + poll-list: func(in: list>) -> list; /// Poll for completion on a single pollable. /// /// This function is similar to `poll-list`, but operates on only a single /// pollable. When it returns, the handle is ready for I/O. - poll-one: func(in: borrow) + poll-one: func(in: borrow); } diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index eeeff5058..cfeab0da1 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -1,4 +1,4 @@ -package wasi:io +package wasi:io; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -6,7 +6,7 @@ package wasi:io /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { - use poll.{pollable} + use poll.{pollable}; /// Streams provide a sequence of data and then end; once they end, they /// no longer provide any further data. @@ -58,14 +58,14 @@ interface streams { read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>> + ) -> result, stream-status>>; /// Read bytes from a stream, after blocking until at least one byte can /// be read. Except for blocking, identical to `read`. blocking-read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>> + ) -> result, stream-status>>; /// Skip bytes from a stream. /// @@ -82,14 +82,14 @@ interface streams { skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result> + ) -> result>; /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. blocking-skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result> + ) -> result>; /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been @@ -97,7 +97,7 @@ interface streams { /// The created `pollable` is a child resource of the `input-stream`. /// Implementations may trap if the `input-stream` is dropped before /// all derived `pollable`s created with this function are dropped. - subscribe: func() -> pollable + subscribe: func() -> pollable; } /// An error for output-stream operations. @@ -131,7 +131,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. - check-write: func() -> result + check-write: func() -> result; /// Perform a write. This function never blocks. /// @@ -142,7 +142,7 @@ interface streams { /// the last call to check-write provided a permit. write: func( contents: list - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. @@ -170,7 +170,7 @@ interface streams { /// ``` blocking-write-and-flush: func( contents: list - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Request to flush buffered output. This function never blocks. /// @@ -182,11 +182,11 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. - flush: func() -> result<_, write-error> + flush: func() -> result<_, write-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. - blocking-flush: func() -> result<_, write-error> + blocking-flush: func() -> result<_, write-error>; /// Create a `pollable` which will resolve once the output-stream /// is ready for more writing, or an error has occured. When this @@ -198,7 +198,7 @@ interface streams { /// The created `pollable` is a child resource of the `output-stream`. /// Implementations may trap if the `output-stream` is dropped before /// all derived `pollable`s created with this function are dropped. - subscribe: func() -> pollable + subscribe: func() -> pollable; /// Write zeroes to a stream. /// @@ -209,7 +209,7 @@ interface streams { write-zeroes: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Perform a write of up to 4096 zeroes, and then flush the stream. /// Block until all of these operations are complete, or an error @@ -238,7 +238,7 @@ interface streams { blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Read from one stream and write to another. /// @@ -252,7 +252,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result> + ) -> result>; /// Read from one stream and write to another, with blocking. /// @@ -263,7 +263,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result> + ) -> result>; /// Forward the entire contents of an input stream to an output stream. /// @@ -280,6 +280,6 @@ interface streams { forward: func( /// The stream to read from src: input-stream - ) -> result> + ) -> result>; } } diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index 8738dba75..05244a965 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -1,6 +1,6 @@ -package wasi:io +package wasi:io; world imports { - import streams - import poll + import streams; + import poll; } From 9606b43aa9331940480f07715d866e34bfbb549c Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:09:17 -0700 Subject: [PATCH 1226/1772] wit syntax: require semicolons (#51) * wit-deps update no functional changes, just adding semicolons * wits: add semicolons as statement separator * CI: use wit-abi-up-to-date@v16, which requires semicolons --- proposals/clocks/.github/workflows/main.yml | 2 +- proposals/clocks/wit/deps.lock | 4 +-- proposals/clocks/wit/deps/io/poll.wit | 8 ++--- proposals/clocks/wit/deps/io/streams.wit | 36 ++++++++++----------- proposals/clocks/wit/deps/io/world.wit | 6 ++-- proposals/clocks/wit/monotonic-clock.wit | 10 +++--- proposals/clocks/wit/timezone.wit | 6 ++-- proposals/clocks/wit/wall-clock.wit | 4 +-- proposals/clocks/wit/world.wit | 8 ++--- 9 files changed, 42 insertions(+), 42 deletions(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 5df3460af..af3c079b1 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -18,4 +18,4 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v15 + - uses: WebAssembly/wit-abi-up-to-date@v16 diff --git a/proposals/clocks/wit/deps.lock b/proposals/clocks/wit/deps.lock index 41d5cbb11..e73913ba0 100644 --- a/proposals/clocks/wit/deps.lock +++ b/proposals/clocks/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "6e20bcf4d4f5466b60c05ea8da7289ca361a7febdd22ab1a531e5ef7e394ab8d" -sha512 = "21f6689bce6ed6d9e3bd96372e5c7ed003a7aefbf8d49b4eea949dfbd265cf57a0d7dc67aa71e3de75d48fcc2c0cfe5f06f7e9e7959a23bc98f77da85f4161b9" +sha256 = "a00c29dd57dc224e8ce28b793b19c1b1001dcdbdc229ed451c3df1db91841b34" +sha512 = "8558085eeb5689209101cdfbc9782953d559ad14ce77260fe2f7cc472482d568f65cad9e6a688d40c634c6c54c608f27e27e481633446114d6fdead93d4e34c5" diff --git a/proposals/clocks/wit/deps/io/poll.wit b/proposals/clocks/wit/deps/io/poll.wit index e95762b91..254f53418 100644 --- a/proposals/clocks/wit/deps/io/poll.wit +++ b/proposals/clocks/wit/deps/io/poll.wit @@ -1,10 +1,10 @@ -package wasi:io +package wasi:io; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { /// A "pollable" handle. - resource pollable + resource pollable; /// Poll for completion on a set of pollables. /// @@ -24,11 +24,11 @@ interface poll { /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as /// being reaedy for I/O. - poll-list: func(in: list>) -> list + poll-list: func(in: list>) -> list; /// Poll for completion on a single pollable. /// /// This function is similar to `poll-list`, but operates on only a single /// pollable. When it returns, the handle is ready for I/O. - poll-one: func(in: borrow) + poll-one: func(in: borrow); } diff --git a/proposals/clocks/wit/deps/io/streams.wit b/proposals/clocks/wit/deps/io/streams.wit index eeeff5058..cfeab0da1 100644 --- a/proposals/clocks/wit/deps/io/streams.wit +++ b/proposals/clocks/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io +package wasi:io; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -6,7 +6,7 @@ package wasi:io /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { - use poll.{pollable} + use poll.{pollable}; /// Streams provide a sequence of data and then end; once they end, they /// no longer provide any further data. @@ -58,14 +58,14 @@ interface streams { read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>> + ) -> result, stream-status>>; /// Read bytes from a stream, after blocking until at least one byte can /// be read. Except for blocking, identical to `read`. blocking-read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>> + ) -> result, stream-status>>; /// Skip bytes from a stream. /// @@ -82,14 +82,14 @@ interface streams { skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result> + ) -> result>; /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. blocking-skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result> + ) -> result>; /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been @@ -97,7 +97,7 @@ interface streams { /// The created `pollable` is a child resource of the `input-stream`. /// Implementations may trap if the `input-stream` is dropped before /// all derived `pollable`s created with this function are dropped. - subscribe: func() -> pollable + subscribe: func() -> pollable; } /// An error for output-stream operations. @@ -131,7 +131,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. - check-write: func() -> result + check-write: func() -> result; /// Perform a write. This function never blocks. /// @@ -142,7 +142,7 @@ interface streams { /// the last call to check-write provided a permit. write: func( contents: list - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. @@ -170,7 +170,7 @@ interface streams { /// ``` blocking-write-and-flush: func( contents: list - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Request to flush buffered output. This function never blocks. /// @@ -182,11 +182,11 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. - flush: func() -> result<_, write-error> + flush: func() -> result<_, write-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. - blocking-flush: func() -> result<_, write-error> + blocking-flush: func() -> result<_, write-error>; /// Create a `pollable` which will resolve once the output-stream /// is ready for more writing, or an error has occured. When this @@ -198,7 +198,7 @@ interface streams { /// The created `pollable` is a child resource of the `output-stream`. /// Implementations may trap if the `output-stream` is dropped before /// all derived `pollable`s created with this function are dropped. - subscribe: func() -> pollable + subscribe: func() -> pollable; /// Write zeroes to a stream. /// @@ -209,7 +209,7 @@ interface streams { write-zeroes: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Perform a write of up to 4096 zeroes, and then flush the stream. /// Block until all of these operations are complete, or an error @@ -238,7 +238,7 @@ interface streams { blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Read from one stream and write to another. /// @@ -252,7 +252,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result> + ) -> result>; /// Read from one stream and write to another, with blocking. /// @@ -263,7 +263,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result> + ) -> result>; /// Forward the entire contents of an input stream to an output stream. /// @@ -280,6 +280,6 @@ interface streams { forward: func( /// The stream to read from src: input-stream - ) -> result> + ) -> result>; } } diff --git a/proposals/clocks/wit/deps/io/world.wit b/proposals/clocks/wit/deps/io/world.wit index 8738dba75..05244a965 100644 --- a/proposals/clocks/wit/deps/io/world.wit +++ b/proposals/clocks/wit/deps/io/world.wit @@ -1,6 +1,6 @@ -package wasi:io +package wasi:io; world imports { - import streams - import poll + import streams; + import poll; } diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index 703a5fb7a..d9ac7cb3f 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -9,24 +9,24 @@ /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:io/poll.{pollable} + use wasi:io/poll.{pollable}; /// A timestamp in nanoseconds. - type instant = u64 + type instant = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - now: func() -> instant + now: func() -> instant; /// Query the resolution of the clock. - resolution: func() -> instant + resolution: func() -> instant; /// Create a `pollable` which will resolve once the specified time has been /// reached. subscribe: func( when: instant, absolute: bool - ) -> pollable + ) -> pollable; } diff --git a/proposals/clocks/wit/timezone.wit b/proposals/clocks/wit/timezone.wit index a872bffc7..e717e7b8d 100644 --- a/proposals/clocks/wit/timezone.wit +++ b/proposals/clocks/wit/timezone.wit @@ -1,5 +1,5 @@ interface timezone { - use wall-clock.{datetime} + use wall-clock.{datetime}; /// Return information needed to display the given `datetime`. This includes /// the UTC offset, the time zone name, and a flag indicating whether @@ -8,10 +8,10 @@ interface timezone { /// If the timezone cannot be determined for the given `datetime`, return a /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight /// saving time. - display: func(when: datetime) -> timezone-display + display: func(when: datetime) -> timezone-display; /// The same as `display`, but only return the UTC offset. - utc-offset: func(when: datetime) -> s32 + utc-offset: func(when: datetime) -> s32; /// Information useful for displaying the timezone of a specific `datetime`. /// diff --git a/proposals/clocks/wit/wall-clock.wit b/proposals/clocks/wit/wall-clock.wit index dae44a730..c39564967 100644 --- a/proposals/clocks/wit/wall-clock.wit +++ b/proposals/clocks/wit/wall-clock.wit @@ -32,10 +32,10 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - now: func() -> datetime + now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - resolution: func() -> datetime + resolution: func() -> datetime; } diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index 5c2dd411d..3295ba8d9 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -1,7 +1,7 @@ -package wasi:clocks +package wasi:clocks; world imports { - import monotonic-clock - import wall-clock - import timezone + import monotonic-clock; + import wall-clock; + import timezone; } From d29aaa0f434eb72944fad40e785c27dce693395e Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 11:57:31 -0700 Subject: [PATCH 1227/1772] wit-deps update --- proposals/filesystem/wit/deps.lock | 8 ++--- .../wit/deps/clocks/monotonic-clock.wit | 10 +++--- .../filesystem/wit/deps/clocks/timezone.wit | 6 ++-- .../filesystem/wit/deps/clocks/wall-clock.wit | 4 +-- .../filesystem/wit/deps/clocks/world.wit | 8 ++--- proposals/filesystem/wit/deps/io/poll.wit | 8 ++--- proposals/filesystem/wit/deps/io/streams.wit | 36 +++++++++---------- proposals/filesystem/wit/deps/io/world.wit | 6 ++-- 8 files changed, 43 insertions(+), 43 deletions(-) diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index 319608225..d8f03223a 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "ea955af7a152f85941b651c5b07345c4f077ae7f9e996c909ab8cc0a68c0120e" -sha512 = "114bc4f583a487cf1ccfdd6efa25c4c60cf637d4501a189eebd4b1d52aec2c8eb63ae14ce494db53dfd25bc20f6c4b533dc6f2143537e5cd14ca80d5d4b6a49d" +sha256 = "74844f8bf1d356bb44aab64a2f917d7a3bcb6d6924662d2e3909aeabda01bea6" +sha512 = "ef21339a60a3f4a37eb48ab81b411c1f2ed11c9b23da04d1e384c07dd4cc75f1a433ce7b46201c693b7a59b51c73d888bc41c78ad204fe32d8a312a9f9a48eb0" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "6e20bcf4d4f5466b60c05ea8da7289ca361a7febdd22ab1a531e5ef7e394ab8d" -sha512 = "21f6689bce6ed6d9e3bd96372e5c7ed003a7aefbf8d49b4eea949dfbd265cf57a0d7dc67aa71e3de75d48fcc2c0cfe5f06f7e9e7959a23bc98f77da85f4161b9" +sha256 = "a00c29dd57dc224e8ce28b793b19c1b1001dcdbdc229ed451c3df1db91841b34" +sha512 = "8558085eeb5689209101cdfbc9782953d559ad14ce77260fe2f7cc472482d568f65cad9e6a688d40c634c6c54c608f27e27e481633446114d6fdead93d4e34c5" diff --git a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit index 703a5fb7a..d9ac7cb3f 100644 --- a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit @@ -9,24 +9,24 @@ /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:io/poll.{pollable} + use wasi:io/poll.{pollable}; /// A timestamp in nanoseconds. - type instant = u64 + type instant = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - now: func() -> instant + now: func() -> instant; /// Query the resolution of the clock. - resolution: func() -> instant + resolution: func() -> instant; /// Create a `pollable` which will resolve once the specified time has been /// reached. subscribe: func( when: instant, absolute: bool - ) -> pollable + ) -> pollable; } diff --git a/proposals/filesystem/wit/deps/clocks/timezone.wit b/proposals/filesystem/wit/deps/clocks/timezone.wit index a872bffc7..e717e7b8d 100644 --- a/proposals/filesystem/wit/deps/clocks/timezone.wit +++ b/proposals/filesystem/wit/deps/clocks/timezone.wit @@ -1,5 +1,5 @@ interface timezone { - use wall-clock.{datetime} + use wall-clock.{datetime}; /// Return information needed to display the given `datetime`. This includes /// the UTC offset, the time zone name, and a flag indicating whether @@ -8,10 +8,10 @@ interface timezone { /// If the timezone cannot be determined for the given `datetime`, return a /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight /// saving time. - display: func(when: datetime) -> timezone-display + display: func(when: datetime) -> timezone-display; /// The same as `display`, but only return the UTC offset. - utc-offset: func(when: datetime) -> s32 + utc-offset: func(when: datetime) -> s32; /// Information useful for displaying the timezone of a specific `datetime`. /// diff --git a/proposals/filesystem/wit/deps/clocks/wall-clock.wit b/proposals/filesystem/wit/deps/clocks/wall-clock.wit index dae44a730..c39564967 100644 --- a/proposals/filesystem/wit/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/wall-clock.wit @@ -32,10 +32,10 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - now: func() -> datetime + now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - resolution: func() -> datetime + resolution: func() -> datetime; } diff --git a/proposals/filesystem/wit/deps/clocks/world.wit b/proposals/filesystem/wit/deps/clocks/world.wit index 5c2dd411d..3295ba8d9 100644 --- a/proposals/filesystem/wit/deps/clocks/world.wit +++ b/proposals/filesystem/wit/deps/clocks/world.wit @@ -1,7 +1,7 @@ -package wasi:clocks +package wasi:clocks; world imports { - import monotonic-clock - import wall-clock - import timezone + import monotonic-clock; + import wall-clock; + import timezone; } diff --git a/proposals/filesystem/wit/deps/io/poll.wit b/proposals/filesystem/wit/deps/io/poll.wit index e95762b91..254f53418 100644 --- a/proposals/filesystem/wit/deps/io/poll.wit +++ b/proposals/filesystem/wit/deps/io/poll.wit @@ -1,10 +1,10 @@ -package wasi:io +package wasi:io; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { /// A "pollable" handle. - resource pollable + resource pollable; /// Poll for completion on a set of pollables. /// @@ -24,11 +24,11 @@ interface poll { /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as /// being reaedy for I/O. - poll-list: func(in: list>) -> list + poll-list: func(in: list>) -> list; /// Poll for completion on a single pollable. /// /// This function is similar to `poll-list`, but operates on only a single /// pollable. When it returns, the handle is ready for I/O. - poll-one: func(in: borrow) + poll-one: func(in: borrow); } diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index eeeff5058..cfeab0da1 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io +package wasi:io; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -6,7 +6,7 @@ package wasi:io /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { - use poll.{pollable} + use poll.{pollable}; /// Streams provide a sequence of data and then end; once they end, they /// no longer provide any further data. @@ -58,14 +58,14 @@ interface streams { read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>> + ) -> result, stream-status>>; /// Read bytes from a stream, after blocking until at least one byte can /// be read. Except for blocking, identical to `read`. blocking-read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>> + ) -> result, stream-status>>; /// Skip bytes from a stream. /// @@ -82,14 +82,14 @@ interface streams { skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result> + ) -> result>; /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. blocking-skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result> + ) -> result>; /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been @@ -97,7 +97,7 @@ interface streams { /// The created `pollable` is a child resource of the `input-stream`. /// Implementations may trap if the `input-stream` is dropped before /// all derived `pollable`s created with this function are dropped. - subscribe: func() -> pollable + subscribe: func() -> pollable; } /// An error for output-stream operations. @@ -131,7 +131,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. - check-write: func() -> result + check-write: func() -> result; /// Perform a write. This function never blocks. /// @@ -142,7 +142,7 @@ interface streams { /// the last call to check-write provided a permit. write: func( contents: list - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. @@ -170,7 +170,7 @@ interface streams { /// ``` blocking-write-and-flush: func( contents: list - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Request to flush buffered output. This function never blocks. /// @@ -182,11 +182,11 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. - flush: func() -> result<_, write-error> + flush: func() -> result<_, write-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. - blocking-flush: func() -> result<_, write-error> + blocking-flush: func() -> result<_, write-error>; /// Create a `pollable` which will resolve once the output-stream /// is ready for more writing, or an error has occured. When this @@ -198,7 +198,7 @@ interface streams { /// The created `pollable` is a child resource of the `output-stream`. /// Implementations may trap if the `output-stream` is dropped before /// all derived `pollable`s created with this function are dropped. - subscribe: func() -> pollable + subscribe: func() -> pollable; /// Write zeroes to a stream. /// @@ -209,7 +209,7 @@ interface streams { write-zeroes: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Perform a write of up to 4096 zeroes, and then flush the stream. /// Block until all of these operations are complete, or an error @@ -238,7 +238,7 @@ interface streams { blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Read from one stream and write to another. /// @@ -252,7 +252,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result> + ) -> result>; /// Read from one stream and write to another, with blocking. /// @@ -263,7 +263,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result> + ) -> result>; /// Forward the entire contents of an input stream to an output stream. /// @@ -280,6 +280,6 @@ interface streams { forward: func( /// The stream to read from src: input-stream - ) -> result> + ) -> result>; } } diff --git a/proposals/filesystem/wit/deps/io/world.wit b/proposals/filesystem/wit/deps/io/world.wit index 8738dba75..05244a965 100644 --- a/proposals/filesystem/wit/deps/io/world.wit +++ b/proposals/filesystem/wit/deps/io/world.wit @@ -1,6 +1,6 @@ -package wasi:io +package wasi:io; world imports { - import streams - import poll + import streams; + import poll; } From b02779ad9f940bece5935e04648260f1467bd268 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:10:37 -0700 Subject: [PATCH 1228/1772] wit: use semicolons as statement separator --- proposals/filesystem/wit/preopens.wit | 4 +- proposals/filesystem/wit/types.wit | 92 +++++++++++++++------------ proposals/filesystem/wit/world.wit | 6 +- 3 files changed, 57 insertions(+), 45 deletions(-) diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit index f45661b8a..3f787ac3f 100644 --- a/proposals/filesystem/wit/preopens.wit +++ b/proposals/filesystem/wit/preopens.wit @@ -1,6 +1,6 @@ interface preopens { - use types.{descriptor} + use types.{descriptor}; /// Return the set of preopened directories, and their path. - get-directories: func() -> list> + get-directories: func() -> list>; } diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 3f69bf997..73b93c0b0 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -23,11 +23,11 @@ /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { - use wasi:io/streams.{input-stream, output-stream} - use wasi:clocks/wall-clock.{datetime} + use wasi:io/streams.{input-stream, output-stream, error}; + use wasi:clocks/wall-clock.{datetime}; /// File size or length of a region within a file. - type filesize = u64 + type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// @@ -166,7 +166,7 @@ interface types { } /// Number of hard links to an inode. - type link-count = u64 + type link-count = u64; /// When setting a timestamp, this gives the value to set it to. variant new-timestamp { @@ -315,7 +315,7 @@ interface types { read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, - ) -> result + ) -> result; /// Return a stream for writing to a file, if available. /// @@ -326,7 +326,7 @@ interface types { write-via-stream: func( /// The offset within the file at which to start writing. offset: filesize, - ) -> result + ) -> result; /// Return a stream for appending to a file, if available. /// @@ -334,7 +334,7 @@ interface types { /// /// Note: This allows using `write-stream`, which is similar to `write` with /// `O_APPEND` in in POSIX. - append-via-stream: func() -> result + append-via-stream: func() -> result; /// Provide file advisory information on a descriptor. /// @@ -346,7 +346,7 @@ interface types { length: filesize, /// The advice. advice: advice - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Synchronize the data of a file to disk. /// @@ -354,7 +354,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - sync-data: func() -> result<_, error-code> + sync-data: func() -> result<_, error-code>; /// Get flags associated with a descriptor. /// @@ -362,7 +362,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - get-flags: func() -> result + get-flags: func() -> result; /// Get the dynamic type of a descriptor. /// @@ -374,13 +374,13 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - get-type: func() -> result + get-type: func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - set-size: func(size: filesize) -> result<_, error-code> + set-size: func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. /// @@ -392,7 +392,7 @@ interface types { data-access-timestamp: new-timestamp, /// The desired values of the data modification timestamp. data-modification-timestamp: new-timestamp, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Read from a descriptor, without using and updating the descriptor's offset. /// @@ -410,7 +410,7 @@ interface types { length: filesize, /// The offset within the file at which to read. offset: filesize, - ) -> result, bool>, error-code> + ) -> result, bool>, error-code>; /// Write to a descriptor, without using and updating the descriptor's offset. /// @@ -426,7 +426,7 @@ interface types { buffer: list, /// The offset within the file at which to write. offset: filesize, - ) -> result + ) -> result; /// Read directory entries from a directory. /// @@ -437,7 +437,7 @@ interface types { /// This always returns a new stream which starts at the beginning of the /// directory. Multiple streams may be active on the same directory, and they /// do not interfere with each other. - read-directory: func() -> result + read-directory: func() -> result; /// Synchronize the data and metadata of a file to disk. /// @@ -445,7 +445,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - sync: func() -> result<_, error-code> + sync: func() -> result<_, error-code>; /// Create a directory. /// @@ -453,7 +453,7 @@ interface types { create-directory-at: func( /// The relative path at which to create the directory. path: string, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Return the attributes of an open file or directory. /// @@ -464,7 +464,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - stat: func() -> result + stat: func() -> result; /// Return the attributes of a file or directory. /// @@ -478,7 +478,7 @@ interface types { path-flags: path-flags, /// The relative path of the file or directory to inspect. path: string, - ) -> result + ) -> result; /// Adjust the timestamps of a file or directory. /// @@ -495,7 +495,7 @@ interface types { data-access-timestamp: new-timestamp, /// The desired values of the data modification timestamp. data-modification-timestamp: new-timestamp, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Create a hard link. /// @@ -509,7 +509,7 @@ interface types { new-descriptor: borrow, /// The relative destination path at which to create the hard link. new-path: string, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Open a file or directory. /// @@ -540,7 +540,7 @@ interface types { %flags: descriptor-flags, /// Permissions to use when creating a new file. modes: modes - ) -> result + ) -> result; /// Read the contents of a symbolic link. /// @@ -551,7 +551,7 @@ interface types { readlink-at: func( /// The relative path of the symbolic link from which to read. path: string, - ) -> result + ) -> result; /// Remove a directory. /// @@ -561,7 +561,7 @@ interface types { remove-directory-at: func( /// The relative path to a directory to remove. path: string, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Rename a filesystem object. /// @@ -573,7 +573,7 @@ interface types { new-descriptor: borrow, /// The relative destination path to which to rename the file or directory. new-path: string, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Create a symbolic link (also known as a "symlink"). /// @@ -586,7 +586,7 @@ interface types { old-path: string, /// The relative destination path at which to create the symbolic link. new-path: string, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Check accessibility of a filesystem path. /// @@ -605,7 +605,7 @@ interface types { path: string, /// The type of check to perform. %type: access-type - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Unlink a filesystem object that is not a directory. /// @@ -614,7 +614,7 @@ interface types { unlink-file-at: func( /// The relative path to a file to unlink. path: string, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Change the permissions of a filesystem object that is not a directory. /// @@ -629,7 +629,7 @@ interface types { path: string, /// The new permissions for the filesystem object. modes: modes, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Change the permissions of a directory. /// @@ -648,7 +648,7 @@ interface types { path: string, /// The new permissions for the directory. modes: modes, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Request a shared advisory lock for an open file. /// @@ -670,7 +670,7 @@ interface types { /// locking, this function returns `error-code::unsupported`. /// /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. - lock-shared: func() -> result<_, error-code> + lock-shared: func() -> result<_, error-code>; /// Request an exclusive advisory lock for an open file. /// @@ -694,7 +694,7 @@ interface types { /// locking, this function returns `error-code::unsupported`. /// /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. - lock-exclusive: func() -> result<_, error-code> + lock-exclusive: func() -> result<_, error-code>; /// Request a shared advisory lock for an open file. /// @@ -717,7 +717,7 @@ interface types { /// locking, this function returns `error-code::unsupported`. /// /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. - try-lock-shared: func() -> result<_, error-code> + try-lock-shared: func() -> result<_, error-code>; /// Request an exclusive advisory lock for an open file. /// @@ -742,12 +742,12 @@ interface types { /// locking, this function returns `error-code::unsupported`. /// /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. - try-lock-exclusive: func() -> result<_, error-code> + try-lock-exclusive: func() -> result<_, error-code>; /// Release a shared or exclusive lock on an open file. /// /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. - unlock: func() -> result<_, error-code> + unlock: func() -> result<_, error-code>; /// Test whether two descriptors refer to the same filesystem object. /// @@ -755,7 +755,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - is-same-object: func(other: borrow) -> bool + is-same-object: func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred /// to by a descriptor. @@ -776,7 +776,7 @@ interface types { /// computed hash. /// /// However, none of these is required. - metadata-hash: func() -> result + metadata-hash: func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. @@ -787,12 +787,24 @@ interface types { path-flags: path-flags, /// The relative path of the file or directory to inspect. path: string, - ) -> result + ) -> result; } /// A stream of directory entries. resource directory-entry-stream { /// Read a single directory entry from a `directory-entry-stream`. - read-directory-entry: func() -> result, error-code> + read-directory-entry: func() -> result, error-code>; } + + /// Attempts to extract a filesystem-related `error-code` from the stream + /// `error` provided. + /// + /// Stream operations which return `stream-error::last-operation-failed` + /// have a payload with more information about the operation that failed. + /// This payload can be passed through to this function to see if there's + /// filesystem-related information about the error to return. + /// + /// Note that this function is fallible because not all stream-related + /// errors are filesystem-related errors. + filesystem-error-code: func(err: borrow) -> option; } diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index 5fa7eafdb..bd472942d 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,6 +1,6 @@ -package wasi:filesystem +package wasi:filesystem; world imports { - import types - import preopens + import types; + import preopens; } From 2f61d1acb233a9ca4f34227f9dc1b6eeb6029625 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:10:48 -0700 Subject: [PATCH 1229/1772] CI: use wit-abi-up-to-date@v16, which requires semicolons --- proposals/filesystem/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index 5df3460af..af3c079b1 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -18,4 +18,4 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v15 + - uses: WebAssembly/wit-abi-up-to-date@v16 From ee34b42a0c8570d44f3187806a875cc62b8e5e6c Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:15:16 -0700 Subject: [PATCH 1230/1772] back out addition of stream error to error-code elaboration --- proposals/filesystem/wit/types.wit | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 73b93c0b0..2050fb928 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -23,7 +23,7 @@ /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { - use wasi:io/streams.{input-stream, output-stream, error}; + use wasi:io/streams.{input-stream, output-stream}; use wasi:clocks/wall-clock.{datetime}; /// File size or length of a region within a file. @@ -795,16 +795,4 @@ interface types { /// Read a single directory entry from a `directory-entry-stream`. read-directory-entry: func() -> result, error-code>; } - - /// Attempts to extract a filesystem-related `error-code` from the stream - /// `error` provided. - /// - /// Stream operations which return `stream-error::last-operation-failed` - /// have a payload with more information about the operation that failed. - /// This payload can be passed through to this function to see if there's - /// filesystem-related information about the error to return. - /// - /// Note that this function is fallible because not all stream-related - /// errors are filesystem-related errors. - filesystem-error-code: func(err: borrow) -> option; } From 6e733daeb07f1419e2a98785956d6cf3a933949b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:18:05 -0700 Subject: [PATCH 1231/1772] wit: use semicolons as statement separator --- proposals/random/wit/insecure-seed.wit | 2 +- proposals/random/wit/insecure.wit | 4 ++-- proposals/random/wit/random.wit | 4 ++-- proposals/random/wit/world.wit | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index ff2ff65d0..139aed159 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -20,5 +20,5 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - insecure-seed: func() -> tuple + insecure-seed: func() -> tuple; } diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index ff0826822..2ffd223cb 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -11,11 +11,11 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - get-insecure-random-bytes: func(len: u64) -> list + get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - get-insecure-random-u64: func() -> u64 + get-insecure-random-u64: func() -> u64; } diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 2a282dab7..2c3c6a859 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -15,11 +15,11 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - get-random-bytes: func(len: u64) -> list + get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - get-random-u64: func() -> u64 + get-random-u64: func() -> u64; } diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index 41dc9ed10..bb1dd7b59 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,7 +1,7 @@ -package wasi:random +package wasi:random; world imports { - import random - import insecure - import insecure-seed + import random; + import insecure; + import insecure-seed; } From 45af872015a26056e02e0a6b31adc69db61a0ecd Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:18:20 -0700 Subject: [PATCH 1232/1772] CI: use wit-abi-up-to-date@v16, which requires semicolons --- proposals/random/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index e210671f2..b45623289 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -11,4 +11,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: WebAssembly/wit-abi-up-to-date@v15 + - uses: WebAssembly/wit-abi-up-to-date@v16 From c007deae81186b704f1e88b496f9a853b57bfce9 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:26:25 -0700 Subject: [PATCH 1233/1772] wit-deps update just semicolon changes being pulled in --- proposals/sockets/wit/deps.lock | 4 +-- proposals/sockets/wit/deps/io/poll.wit | 8 ++--- proposals/sockets/wit/deps/io/streams.wit | 36 +++++++++++------------ proposals/sockets/wit/deps/io/world.wit | 6 ++-- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index 41d5cbb11..e73913ba0 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "6e20bcf4d4f5466b60c05ea8da7289ca361a7febdd22ab1a531e5ef7e394ab8d" -sha512 = "21f6689bce6ed6d9e3bd96372e5c7ed003a7aefbf8d49b4eea949dfbd265cf57a0d7dc67aa71e3de75d48fcc2c0cfe5f06f7e9e7959a23bc98f77da85f4161b9" +sha256 = "a00c29dd57dc224e8ce28b793b19c1b1001dcdbdc229ed451c3df1db91841b34" +sha512 = "8558085eeb5689209101cdfbc9782953d559ad14ce77260fe2f7cc472482d568f65cad9e6a688d40c634c6c54c608f27e27e481633446114d6fdead93d4e34c5" diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit index e95762b91..254f53418 100644 --- a/proposals/sockets/wit/deps/io/poll.wit +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -1,10 +1,10 @@ -package wasi:io +package wasi:io; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { /// A "pollable" handle. - resource pollable + resource pollable; /// Poll for completion on a set of pollables. /// @@ -24,11 +24,11 @@ interface poll { /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as /// being reaedy for I/O. - poll-list: func(in: list>) -> list + poll-list: func(in: list>) -> list; /// Poll for completion on a single pollable. /// /// This function is similar to `poll-list`, but operates on only a single /// pollable. When it returns, the handle is ready for I/O. - poll-one: func(in: borrow) + poll-one: func(in: borrow); } diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index eeeff5058..cfeab0da1 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io +package wasi:io; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -6,7 +6,7 @@ package wasi:io /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { - use poll.{pollable} + use poll.{pollable}; /// Streams provide a sequence of data and then end; once they end, they /// no longer provide any further data. @@ -58,14 +58,14 @@ interface streams { read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>> + ) -> result, stream-status>>; /// Read bytes from a stream, after blocking until at least one byte can /// be read. Except for blocking, identical to `read`. blocking-read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>> + ) -> result, stream-status>>; /// Skip bytes from a stream. /// @@ -82,14 +82,14 @@ interface streams { skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result> + ) -> result>; /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. blocking-skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result> + ) -> result>; /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been @@ -97,7 +97,7 @@ interface streams { /// The created `pollable` is a child resource of the `input-stream`. /// Implementations may trap if the `input-stream` is dropped before /// all derived `pollable`s created with this function are dropped. - subscribe: func() -> pollable + subscribe: func() -> pollable; } /// An error for output-stream operations. @@ -131,7 +131,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. - check-write: func() -> result + check-write: func() -> result; /// Perform a write. This function never blocks. /// @@ -142,7 +142,7 @@ interface streams { /// the last call to check-write provided a permit. write: func( contents: list - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. @@ -170,7 +170,7 @@ interface streams { /// ``` blocking-write-and-flush: func( contents: list - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Request to flush buffered output. This function never blocks. /// @@ -182,11 +182,11 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. - flush: func() -> result<_, write-error> + flush: func() -> result<_, write-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. - blocking-flush: func() -> result<_, write-error> + blocking-flush: func() -> result<_, write-error>; /// Create a `pollable` which will resolve once the output-stream /// is ready for more writing, or an error has occured. When this @@ -198,7 +198,7 @@ interface streams { /// The created `pollable` is a child resource of the `output-stream`. /// Implementations may trap if the `output-stream` is dropped before /// all derived `pollable`s created with this function are dropped. - subscribe: func() -> pollable + subscribe: func() -> pollable; /// Write zeroes to a stream. /// @@ -209,7 +209,7 @@ interface streams { write-zeroes: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Perform a write of up to 4096 zeroes, and then flush the stream. /// Block until all of these operations are complete, or an error @@ -238,7 +238,7 @@ interface streams { blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Read from one stream and write to another. /// @@ -252,7 +252,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result> + ) -> result>; /// Read from one stream and write to another, with blocking. /// @@ -263,7 +263,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result> + ) -> result>; /// Forward the entire contents of an input stream to an output stream. /// @@ -280,6 +280,6 @@ interface streams { forward: func( /// The stream to read from src: input-stream - ) -> result> + ) -> result>; } } diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit index 8738dba75..05244a965 100644 --- a/proposals/sockets/wit/deps/io/world.wit +++ b/proposals/sockets/wit/deps/io/world.wit @@ -1,6 +1,6 @@ -package wasi:io +package wasi:io; world imports { - import streams - import poll + import streams; + import poll; } From 34a1baafbe95afe002100be75a3b818d9439bcc4 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:26:34 -0700 Subject: [PATCH 1234/1772] wit: use semicolons as separator --- proposals/sockets/wit/instance-network.wit | 4 +- proposals/sockets/wit/ip-name-lookup.wit | 10 ++-- proposals/sockets/wit/network.wit | 6 +-- proposals/sockets/wit/tcp-create-socket.wit | 6 +-- proposals/sockets/wit/tcp.wit | 56 ++++++++++----------- proposals/sockets/wit/udp-create-socket.wit | 6 +-- proposals/sockets/wit/udp.wit | 40 +++++++-------- proposals/sockets/wit/world.wit | 16 +++--- 8 files changed, 72 insertions(+), 72 deletions(-) diff --git a/proposals/sockets/wit/instance-network.wit b/proposals/sockets/wit/instance-network.wit index d911a29cc..14e4479e6 100644 --- a/proposals/sockets/wit/instance-network.wit +++ b/proposals/sockets/wit/instance-network.wit @@ -1,9 +1,9 @@ /// This interface provides a value-export of the default network handle.. interface instance-network { - use network.{network} + use network.{network}; /// Get a handle to the default network. - instance-network: func() -> network + instance-network: func() -> network; } diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index f998aae14..b51fe05e5 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,7 +1,7 @@ interface ip-name-lookup { - use wasi:io/poll.{pollable} - use network.{network, error-code, ip-address, ip-address-family} + use wasi:io/poll.{pollable}; + use network.{network, error-code, ip-address, ip-address-family}; /// Resolve an internet host name to a list of IP addresses. @@ -34,7 +34,7 @@ interface ip-name-lookup { /// - /// - /// - - resolve-addresses: func(network: borrow, name: string, address-family: option, include-unavailable: bool) -> result + resolve-addresses: func(network: borrow, name: string, address-family: option, include-unavailable: bool) -> result; resource resolve-address-stream { /// Returns the next address from the resolver. @@ -50,12 +50,12 @@ interface ip-name-lookup { /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) - resolve-next-address: func() -> result, error-code> + resolve-next-address: func() -> result, error-code>; /// Create a `pollable` which will resolve once the stream is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable + subscribe: func() -> pollable; } } diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 8214eaaf7..e2695954b 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -3,7 +3,7 @@ interface network { /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. - resource network + resource network; /// Error codes. /// @@ -150,8 +150,8 @@ interface network { ipv6, } - type ipv4-address = tuple - type ipv6-address = tuple + type ipv4-address = tuple; + type ipv6-address = tuple; variant ip-address { ipv4(ipv4-address), diff --git a/proposals/sockets/wit/tcp-create-socket.wit b/proposals/sockets/wit/tcp-create-socket.wit index f43bc8979..056bbef33 100644 --- a/proposals/sockets/wit/tcp-create-socket.wit +++ b/proposals/sockets/wit/tcp-create-socket.wit @@ -1,7 +1,7 @@ interface tcp-create-socket { - use network.{network, error-code, ip-address-family} - use tcp.{tcp-socket} + use network.{network, error-code, ip-address-family}; + use tcp.{tcp-socket}; /// Create a new TCP socket. /// @@ -23,5 +23,5 @@ interface tcp-create-socket { /// - /// - /// - - create-tcp-socket: func(address-family: ip-address-family) -> result + create-tcp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 175626cc7..fea44380d 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,8 +1,8 @@ interface tcp { - use wasi:io/streams.{input-stream, output-stream} - use wasi:io/poll.{pollable} - use network.{network, error-code, ip-socket-address, ip-address-family} + use wasi:io/streams.{input-stream, output-stream}; + use wasi:io/poll.{pollable}; + use network.{network, error-code, ip-socket-address, ip-address-family}; enum shutdown-type { /// Similar to `SHUT_RD` in POSIX. @@ -46,8 +46,8 @@ interface tcp { /// - /// - /// - - start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code> - finish-bind: func() -> result<_, error-code> + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + finish-bind: func() -> result<_, error-code>; /// Connect to a remote endpoint. /// @@ -78,8 +78,8 @@ interface tcp { /// - /// - /// - - start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code> - finish-connect: func() -> result, error-code> + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + finish-connect: func() -> result, error-code>; /// Start listening for new connections. /// @@ -105,8 +105,8 @@ interface tcp { /// - /// - /// - - start-listen: func() -> result<_, error-code> - finish-listen: func() -> result<_, error-code> + start-listen: func() -> result<_, error-code>; + finish-listen: func() -> result<_, error-code>; /// Accept a new client socket. /// @@ -126,7 +126,7 @@ interface tcp { /// - /// - /// - - accept: func() -> result, error-code> + accept: func() -> result, error-code>; /// Get the bound local address. /// @@ -138,7 +138,7 @@ interface tcp { /// - /// - /// - - local-address: func() -> result + local-address: func() -> result; /// Get the bound remote address. /// @@ -150,12 +150,12 @@ interface tcp { /// - /// - /// - - remote-address: func() -> result + remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. - address-family: func() -> ip-address-family + address-family: func() -> ip-address-family; /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. /// @@ -166,29 +166,29 @@ interface tcp { /// - `already-bound`: (set) The socket is already bound. /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - ipv6-only: func() -> result - set-ipv6-only: func(value: bool) -> result<_, error-code> + ipv6-only: func() -> result; + set-ipv6-only: func(value: bool) -> result<_, error-code>; /// Hints the desired listen queue size. Implementations are free to ignore this. /// /// # Typical errors /// - `already-connected`: (set) The socket is already in the Connection state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - set-listen-backlog-size: func(value: u64) -> result<_, error-code> + set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Equivalent to the SO_KEEPALIVE socket option. /// /// # Typical errors /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - keep-alive: func() -> result - set-keep-alive: func(value: bool) -> result<_, error-code> + keep-alive: func() -> result; + set-keep-alive: func(value: bool) -> result<_, error-code>; /// Equivalent to the TCP_NODELAY socket option. /// /// # Typical errors /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - no-delay: func() -> result - set-no-delay: func(value: bool) -> result<_, error-code> + no-delay: func() -> result; + set-no-delay: func(value: bool) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// @@ -196,8 +196,8 @@ interface tcp { /// - `already-connected`: (set) The socket is already in the Connection state. /// - `already-listening`: (set) The socket is already in the Listener state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - unicast-hop-limit: func() -> result - set-unicast-hop-limit: func(value: u8) -> result<_, error-code> + unicast-hop-limit: func() -> result; + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -214,16 +214,16 @@ interface tcp { /// - `already-connected`: (set) The socket is already in the Connection state. /// - `already-listening`: (set) The socket is already in the Listener state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - receive-buffer-size: func() -> result - set-receive-buffer-size: func(value: u64) -> result<_, error-code> - send-buffer-size: func() -> result - set-send-buffer-size: func(value: u64) -> result<_, error-code> + receive-buffer-size: func() -> result; + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + send-buffer-size: func() -> result; + set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Create a `pollable` which will resolve once the socket is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable + subscribe: func() -> pollable; /// Initiate a graceful shutdown. /// @@ -244,6 +244,6 @@ interface tcp { /// - /// - /// - - shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code> + shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; } } diff --git a/proposals/sockets/wit/udp-create-socket.wit b/proposals/sockets/wit/udp-create-socket.wit index cd4c08fb1..66f948226 100644 --- a/proposals/sockets/wit/udp-create-socket.wit +++ b/proposals/sockets/wit/udp-create-socket.wit @@ -1,7 +1,7 @@ interface udp-create-socket { - use network.{network, error-code, ip-address-family} - use udp.{udp-socket} + use network.{network, error-code, ip-address-family}; + use udp.{udp-socket}; /// Create a new UDP socket. /// @@ -23,5 +23,5 @@ interface udp-create-socket { /// - /// - /// - - create-udp-socket: func(address-family: ip-address-family) -> result + create-udp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 01e5b95b9..e20b57e7e 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,7 +1,7 @@ interface udp { - use wasi:io/poll.{pollable} - use network.{network, error-code, ip-socket-address, ip-address-family} + use wasi:io/poll.{pollable}; + use network.{network, error-code, ip-socket-address, ip-address-family}; record datagram { @@ -47,8 +47,8 @@ interface udp { /// - /// - /// - - start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code> - finish-bind: func() -> result<_, error-code> + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + finish-bind: func() -> result<_, error-code>; /// Set the destination address. /// @@ -79,8 +79,8 @@ interface udp { /// - /// - /// - - start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code> - finish-connect: func() -> result<_, error-code> + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + finish-connect: func() -> result<_, error-code>; /// Receive messages on the socket. /// @@ -102,7 +102,7 @@ interface udp { /// - /// - /// - - receive: func(max-results: u64) -> result, error-code> + receive: func(max-results: u64) -> result, error-code>; /// Send messages on the socket. /// @@ -137,7 +137,7 @@ interface udp { /// - /// - /// - - send: func(datagrams: list) -> result + send: func(datagrams: list) -> result; /// Get the current bound address. /// @@ -149,7 +149,7 @@ interface udp { /// - /// - /// - - local-address: func() -> result + local-address: func() -> result; /// Get the address set with `connect`. /// @@ -161,12 +161,12 @@ interface udp { /// - /// - /// - - remote-address: func() -> result + remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. - address-family: func() -> ip-address-family + address-family: func() -> ip-address-family; /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. /// @@ -177,15 +177,15 @@ interface udp { /// - `already-bound`: (set) The socket is already bound. /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - ipv6-only: func() -> result - set-ipv6-only: func(value: bool) -> result<_, error-code> + ipv6-only: func() -> result; + set-ipv6-only: func(value: bool) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// /// # Typical errors /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - unicast-hop-limit: func() -> result - set-unicast-hop-limit: func(value: u8) -> result<_, error-code> + unicast-hop-limit: func() -> result; + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -200,15 +200,15 @@ interface udp { /// /// # Typical errors /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - receive-buffer-size: func() -> result - set-receive-buffer-size: func(value: u64) -> result<_, error-code> - send-buffer-size: func() -> result - set-send-buffer-size: func(value: u64) -> result<_, error-code> + receive-buffer-size: func() -> result; + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + send-buffer-size: func() -> result; + set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Create a `pollable` which will resolve once the socket is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable + subscribe: func() -> pollable; } } diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index 12f3c2868..432b0dc99 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,11 +1,11 @@ -package wasi:sockets +package wasi:sockets; world imports { - import instance-network - import network - import udp - import udp-create-socket - import tcp - import tcp-create-socket - import ip-name-lookup + import instance-network; + import network; + import udp; + import udp-create-socket; + import tcp; + import tcp-create-socket; + import ip-name-lookup; } From 10754ae0d35765f6015456e651c6baf61145c37b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:26:51 -0700 Subject: [PATCH 1235/1772] CI: use wit-abi-up-to-date@v16, which requires semicolons --- proposals/sockets/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index 5df3460af..af3c079b1 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -18,4 +18,4 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v15 + - uses: WebAssembly/wit-abi-up-to-date@v16 From 981dbf723528db360519d5db885c18d9d84eb56a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:38:00 -0700 Subject: [PATCH 1236/1772] wit-deps update these are entirely changes to add semicolons --- proposals/cli/wit/deps.lock | 20 ++--- .../cli/wit/deps/clocks/monotonic-clock.wit | 10 +-- proposals/cli/wit/deps/clocks/timezone.wit | 6 +- proposals/cli/wit/deps/clocks/wall-clock.wit | 4 +- proposals/cli/wit/deps/clocks/world.wit | 8 +- .../cli/wit/deps/filesystem/preopens.wit | 4 +- proposals/cli/wit/deps/filesystem/types.wit | 80 +++++++++---------- proposals/cli/wit/deps/filesystem/world.wit | 6 +- proposals/cli/wit/deps/io/poll.wit | 8 +- proposals/cli/wit/deps/io/streams.wit | 36 ++++----- proposals/cli/wit/deps/io/world.wit | 6 +- .../cli/wit/deps/random/insecure-seed.wit | 2 +- proposals/cli/wit/deps/random/insecure.wit | 4 +- proposals/cli/wit/deps/random/random.wit | 4 +- proposals/cli/wit/deps/random/world.wit | 8 +- .../cli/wit/deps/sockets/instance-network.wit | 4 +- .../cli/wit/deps/sockets/ip-name-lookup.wit | 10 +-- proposals/cli/wit/deps/sockets/network.wit | 6 +- .../wit/deps/sockets/tcp-create-socket.wit | 6 +- proposals/cli/wit/deps/sockets/tcp.wit | 56 ++++++------- .../wit/deps/sockets/udp-create-socket.wit | 6 +- proposals/cli/wit/deps/sockets/udp.wit | 40 +++++----- proposals/cli/wit/deps/sockets/world.wit | 16 ++-- 23 files changed, 175 insertions(+), 175 deletions(-) diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index ae5020731..45f1c5795 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,24 +1,24 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "ea955af7a152f85941b651c5b07345c4f077ae7f9e996c909ab8cc0a68c0120e" -sha512 = "114bc4f583a487cf1ccfdd6efa25c4c60cf637d4501a189eebd4b1d52aec2c8eb63ae14ce494db53dfd25bc20f6c4b533dc6f2143537e5cd14ca80d5d4b6a49d" +sha256 = "74844f8bf1d356bb44aab64a2f917d7a3bcb6d6924662d2e3909aeabda01bea6" +sha512 = "ef21339a60a3f4a37eb48ab81b411c1f2ed11c9b23da04d1e384c07dd4cc75f1a433ce7b46201c693b7a59b51c73d888bc41c78ad204fe32d8a312a9f9a48eb0" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "f8602f2929fe149b0e2e904fe53b98e3a0ba0a42089253c9a738caf9ccb06c1d" -sha512 = "53f3d7c494ea6ad0687f91994f3af8c5f55bdddeb14cc47b30ff263cdb1ee6c7893ad425d1dc75a8da72d9bb5f82a46fcd566e0c2463fda102a22529e2d83f19" +sha256 = "ca8364780922eddd53ec77f9152c77486db3d7052f6a5902ccc1648d5494050c" +sha512 = "ef05d9d7d5c08bc6a701a65c5af1981f30b2eb5b1c3dc5ca39a69248be8ab7cb3b17c5d181a010149dd491846fa5a7ac4f9165b06e628f31227e02dbdd8b86f5" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "6e20bcf4d4f5466b60c05ea8da7289ca361a7febdd22ab1a531e5ef7e394ab8d" -sha512 = "21f6689bce6ed6d9e3bd96372e5c7ed003a7aefbf8d49b4eea949dfbd265cf57a0d7dc67aa71e3de75d48fcc2c0cfe5f06f7e9e7959a23bc98f77da85f4161b9" +sha256 = "a00c29dd57dc224e8ce28b793b19c1b1001dcdbdc229ed451c3df1db91841b34" +sha512 = "8558085eeb5689209101cdfbc9782953d559ad14ce77260fe2f7cc472482d568f65cad9e6a688d40c634c6c54c608f27e27e481633446114d6fdead93d4e34c5" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "2f718c9909fcc95dc8d7f9fc3a17a30d7da715eaa9fa70af3c89f0f9439abc8a" -sha512 = "7580d79d0f01d4fb65ff85f76d52d420fdbc7406959a34c2b1cad4398dc34d2610f8b6b4e22bcea9db2f3d70242d356e961d843bfc4d2c4956c4f5e5ca3811f9" +sha256 = "7d7c882d50baeb054a754b5766d46f5eed35a4470d887fc8b45121bfc7ac8701" +sha512 = "4b8aad54da50aa44d35f6e5eea87c67bbcedd610650500ffe350c8c8d26f7ee14c49c4c4cc51ebd0ae607459095092625f27a451e52232c575b460334b5a0606" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "85b872b5af12d3010c20a5f4bf6d334a09c1a42ef7f7703c2949c0598ed8ebee" -sha512 = "238bbeea140eba0774cf5ce5abfdc93f03617a2fc30b497e104cc6a23fdf7bd496c61d3c962ca6718255ea5c96a9277bddae1fc4a6b6f7544de2be2649752eac" +sha256 = "e9cc9bf3e809c17f7a100f9498056e435eea133bcb0f1abd8833261f3e5ff067" +sha512 = "1917e06807dc5f9f0993fbffbb9a6c8c36ab25a14ba775ffee939aca458ecd52ee796764708381f7f4166665cfcf11a5d47dc756a1e38f291b270678455b3a02" diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index 703a5fb7a..d9ac7cb3f 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -9,24 +9,24 @@ /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:io/poll.{pollable} + use wasi:io/poll.{pollable}; /// A timestamp in nanoseconds. - type instant = u64 + type instant = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - now: func() -> instant + now: func() -> instant; /// Query the resolution of the clock. - resolution: func() -> instant + resolution: func() -> instant; /// Create a `pollable` which will resolve once the specified time has been /// reached. subscribe: func( when: instant, absolute: bool - ) -> pollable + ) -> pollable; } diff --git a/proposals/cli/wit/deps/clocks/timezone.wit b/proposals/cli/wit/deps/clocks/timezone.wit index a872bffc7..e717e7b8d 100644 --- a/proposals/cli/wit/deps/clocks/timezone.wit +++ b/proposals/cli/wit/deps/clocks/timezone.wit @@ -1,5 +1,5 @@ interface timezone { - use wall-clock.{datetime} + use wall-clock.{datetime}; /// Return information needed to display the given `datetime`. This includes /// the UTC offset, the time zone name, and a flag indicating whether @@ -8,10 +8,10 @@ interface timezone { /// If the timezone cannot be determined for the given `datetime`, return a /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight /// saving time. - display: func(when: datetime) -> timezone-display + display: func(when: datetime) -> timezone-display; /// The same as `display`, but only return the UTC offset. - utc-offset: func(when: datetime) -> s32 + utc-offset: func(when: datetime) -> s32; /// Information useful for displaying the timezone of a specific `datetime`. /// diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit index dae44a730..c39564967 100644 --- a/proposals/cli/wit/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -32,10 +32,10 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - now: func() -> datetime + now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - resolution: func() -> datetime + resolution: func() -> datetime; } diff --git a/proposals/cli/wit/deps/clocks/world.wit b/proposals/cli/wit/deps/clocks/world.wit index 5c2dd411d..3295ba8d9 100644 --- a/proposals/cli/wit/deps/clocks/world.wit +++ b/proposals/cli/wit/deps/clocks/world.wit @@ -1,7 +1,7 @@ -package wasi:clocks +package wasi:clocks; world imports { - import monotonic-clock - import wall-clock - import timezone + import monotonic-clock; + import wall-clock; + import timezone; } diff --git a/proposals/cli/wit/deps/filesystem/preopens.wit b/proposals/cli/wit/deps/filesystem/preopens.wit index f45661b8a..3f787ac3f 100644 --- a/proposals/cli/wit/deps/filesystem/preopens.wit +++ b/proposals/cli/wit/deps/filesystem/preopens.wit @@ -1,6 +1,6 @@ interface preopens { - use types.{descriptor} + use types.{descriptor}; /// Return the set of preopened directories, and their path. - get-directories: func() -> list> + get-directories: func() -> list>; } diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index 3f69bf997..2050fb928 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -23,11 +23,11 @@ /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { - use wasi:io/streams.{input-stream, output-stream} - use wasi:clocks/wall-clock.{datetime} + use wasi:io/streams.{input-stream, output-stream}; + use wasi:clocks/wall-clock.{datetime}; /// File size or length of a region within a file. - type filesize = u64 + type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// @@ -166,7 +166,7 @@ interface types { } /// Number of hard links to an inode. - type link-count = u64 + type link-count = u64; /// When setting a timestamp, this gives the value to set it to. variant new-timestamp { @@ -315,7 +315,7 @@ interface types { read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, - ) -> result + ) -> result; /// Return a stream for writing to a file, if available. /// @@ -326,7 +326,7 @@ interface types { write-via-stream: func( /// The offset within the file at which to start writing. offset: filesize, - ) -> result + ) -> result; /// Return a stream for appending to a file, if available. /// @@ -334,7 +334,7 @@ interface types { /// /// Note: This allows using `write-stream`, which is similar to `write` with /// `O_APPEND` in in POSIX. - append-via-stream: func() -> result + append-via-stream: func() -> result; /// Provide file advisory information on a descriptor. /// @@ -346,7 +346,7 @@ interface types { length: filesize, /// The advice. advice: advice - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Synchronize the data of a file to disk. /// @@ -354,7 +354,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - sync-data: func() -> result<_, error-code> + sync-data: func() -> result<_, error-code>; /// Get flags associated with a descriptor. /// @@ -362,7 +362,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - get-flags: func() -> result + get-flags: func() -> result; /// Get the dynamic type of a descriptor. /// @@ -374,13 +374,13 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - get-type: func() -> result + get-type: func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - set-size: func(size: filesize) -> result<_, error-code> + set-size: func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. /// @@ -392,7 +392,7 @@ interface types { data-access-timestamp: new-timestamp, /// The desired values of the data modification timestamp. data-modification-timestamp: new-timestamp, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Read from a descriptor, without using and updating the descriptor's offset. /// @@ -410,7 +410,7 @@ interface types { length: filesize, /// The offset within the file at which to read. offset: filesize, - ) -> result, bool>, error-code> + ) -> result, bool>, error-code>; /// Write to a descriptor, without using and updating the descriptor's offset. /// @@ -426,7 +426,7 @@ interface types { buffer: list, /// The offset within the file at which to write. offset: filesize, - ) -> result + ) -> result; /// Read directory entries from a directory. /// @@ -437,7 +437,7 @@ interface types { /// This always returns a new stream which starts at the beginning of the /// directory. Multiple streams may be active on the same directory, and they /// do not interfere with each other. - read-directory: func() -> result + read-directory: func() -> result; /// Synchronize the data and metadata of a file to disk. /// @@ -445,7 +445,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - sync: func() -> result<_, error-code> + sync: func() -> result<_, error-code>; /// Create a directory. /// @@ -453,7 +453,7 @@ interface types { create-directory-at: func( /// The relative path at which to create the directory. path: string, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Return the attributes of an open file or directory. /// @@ -464,7 +464,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - stat: func() -> result + stat: func() -> result; /// Return the attributes of a file or directory. /// @@ -478,7 +478,7 @@ interface types { path-flags: path-flags, /// The relative path of the file or directory to inspect. path: string, - ) -> result + ) -> result; /// Adjust the timestamps of a file or directory. /// @@ -495,7 +495,7 @@ interface types { data-access-timestamp: new-timestamp, /// The desired values of the data modification timestamp. data-modification-timestamp: new-timestamp, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Create a hard link. /// @@ -509,7 +509,7 @@ interface types { new-descriptor: borrow, /// The relative destination path at which to create the hard link. new-path: string, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Open a file or directory. /// @@ -540,7 +540,7 @@ interface types { %flags: descriptor-flags, /// Permissions to use when creating a new file. modes: modes - ) -> result + ) -> result; /// Read the contents of a symbolic link. /// @@ -551,7 +551,7 @@ interface types { readlink-at: func( /// The relative path of the symbolic link from which to read. path: string, - ) -> result + ) -> result; /// Remove a directory. /// @@ -561,7 +561,7 @@ interface types { remove-directory-at: func( /// The relative path to a directory to remove. path: string, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Rename a filesystem object. /// @@ -573,7 +573,7 @@ interface types { new-descriptor: borrow, /// The relative destination path to which to rename the file or directory. new-path: string, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Create a symbolic link (also known as a "symlink"). /// @@ -586,7 +586,7 @@ interface types { old-path: string, /// The relative destination path at which to create the symbolic link. new-path: string, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Check accessibility of a filesystem path. /// @@ -605,7 +605,7 @@ interface types { path: string, /// The type of check to perform. %type: access-type - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Unlink a filesystem object that is not a directory. /// @@ -614,7 +614,7 @@ interface types { unlink-file-at: func( /// The relative path to a file to unlink. path: string, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Change the permissions of a filesystem object that is not a directory. /// @@ -629,7 +629,7 @@ interface types { path: string, /// The new permissions for the filesystem object. modes: modes, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Change the permissions of a directory. /// @@ -648,7 +648,7 @@ interface types { path: string, /// The new permissions for the directory. modes: modes, - ) -> result<_, error-code> + ) -> result<_, error-code>; /// Request a shared advisory lock for an open file. /// @@ -670,7 +670,7 @@ interface types { /// locking, this function returns `error-code::unsupported`. /// /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. - lock-shared: func() -> result<_, error-code> + lock-shared: func() -> result<_, error-code>; /// Request an exclusive advisory lock for an open file. /// @@ -694,7 +694,7 @@ interface types { /// locking, this function returns `error-code::unsupported`. /// /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. - lock-exclusive: func() -> result<_, error-code> + lock-exclusive: func() -> result<_, error-code>; /// Request a shared advisory lock for an open file. /// @@ -717,7 +717,7 @@ interface types { /// locking, this function returns `error-code::unsupported`. /// /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. - try-lock-shared: func() -> result<_, error-code> + try-lock-shared: func() -> result<_, error-code>; /// Request an exclusive advisory lock for an open file. /// @@ -742,12 +742,12 @@ interface types { /// locking, this function returns `error-code::unsupported`. /// /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. - try-lock-exclusive: func() -> result<_, error-code> + try-lock-exclusive: func() -> result<_, error-code>; /// Release a shared or exclusive lock on an open file. /// /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. - unlock: func() -> result<_, error-code> + unlock: func() -> result<_, error-code>; /// Test whether two descriptors refer to the same filesystem object. /// @@ -755,7 +755,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - is-same-object: func(other: borrow) -> bool + is-same-object: func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred /// to by a descriptor. @@ -776,7 +776,7 @@ interface types { /// computed hash. /// /// However, none of these is required. - metadata-hash: func() -> result + metadata-hash: func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. @@ -787,12 +787,12 @@ interface types { path-flags: path-flags, /// The relative path of the file or directory to inspect. path: string, - ) -> result + ) -> result; } /// A stream of directory entries. resource directory-entry-stream { /// Read a single directory entry from a `directory-entry-stream`. - read-directory-entry: func() -> result, error-code> + read-directory-entry: func() -> result, error-code>; } } diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit index 5fa7eafdb..bd472942d 100644 --- a/proposals/cli/wit/deps/filesystem/world.wit +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -1,6 +1,6 @@ -package wasi:filesystem +package wasi:filesystem; world imports { - import types - import preopens + import types; + import preopens; } diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit index e95762b91..254f53418 100644 --- a/proposals/cli/wit/deps/io/poll.wit +++ b/proposals/cli/wit/deps/io/poll.wit @@ -1,10 +1,10 @@ -package wasi:io +package wasi:io; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { /// A "pollable" handle. - resource pollable + resource pollable; /// Poll for completion on a set of pollables. /// @@ -24,11 +24,11 @@ interface poll { /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as /// being reaedy for I/O. - poll-list: func(in: list>) -> list + poll-list: func(in: list>) -> list; /// Poll for completion on a single pollable. /// /// This function is similar to `poll-list`, but operates on only a single /// pollable. When it returns, the handle is ready for I/O. - poll-one: func(in: borrow) + poll-one: func(in: borrow); } diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index eeeff5058..cfeab0da1 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io +package wasi:io; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -6,7 +6,7 @@ package wasi:io /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { - use poll.{pollable} + use poll.{pollable}; /// Streams provide a sequence of data and then end; once they end, they /// no longer provide any further data. @@ -58,14 +58,14 @@ interface streams { read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>> + ) -> result, stream-status>>; /// Read bytes from a stream, after blocking until at least one byte can /// be read. Except for blocking, identical to `read`. blocking-read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>> + ) -> result, stream-status>>; /// Skip bytes from a stream. /// @@ -82,14 +82,14 @@ interface streams { skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result> + ) -> result>; /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. blocking-skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result> + ) -> result>; /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been @@ -97,7 +97,7 @@ interface streams { /// The created `pollable` is a child resource of the `input-stream`. /// Implementations may trap if the `input-stream` is dropped before /// all derived `pollable`s created with this function are dropped. - subscribe: func() -> pollable + subscribe: func() -> pollable; } /// An error for output-stream operations. @@ -131,7 +131,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. - check-write: func() -> result + check-write: func() -> result; /// Perform a write. This function never blocks. /// @@ -142,7 +142,7 @@ interface streams { /// the last call to check-write provided a permit. write: func( contents: list - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. @@ -170,7 +170,7 @@ interface streams { /// ``` blocking-write-and-flush: func( contents: list - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Request to flush buffered output. This function never blocks. /// @@ -182,11 +182,11 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. - flush: func() -> result<_, write-error> + flush: func() -> result<_, write-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. - blocking-flush: func() -> result<_, write-error> + blocking-flush: func() -> result<_, write-error>; /// Create a `pollable` which will resolve once the output-stream /// is ready for more writing, or an error has occured. When this @@ -198,7 +198,7 @@ interface streams { /// The created `pollable` is a child resource of the `output-stream`. /// Implementations may trap if the `output-stream` is dropped before /// all derived `pollable`s created with this function are dropped. - subscribe: func() -> pollable + subscribe: func() -> pollable; /// Write zeroes to a stream. /// @@ -209,7 +209,7 @@ interface streams { write-zeroes: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Perform a write of up to 4096 zeroes, and then flush the stream. /// Block until all of these operations are complete, or an error @@ -238,7 +238,7 @@ interface streams { blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error> + ) -> result<_, write-error>; /// Read from one stream and write to another. /// @@ -252,7 +252,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result> + ) -> result>; /// Read from one stream and write to another, with blocking. /// @@ -263,7 +263,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result> + ) -> result>; /// Forward the entire contents of an input stream to an output stream. /// @@ -280,6 +280,6 @@ interface streams { forward: func( /// The stream to read from src: input-stream - ) -> result> + ) -> result>; } } diff --git a/proposals/cli/wit/deps/io/world.wit b/proposals/cli/wit/deps/io/world.wit index 8738dba75..05244a965 100644 --- a/proposals/cli/wit/deps/io/world.wit +++ b/proposals/cli/wit/deps/io/world.wit @@ -1,6 +1,6 @@ -package wasi:io +package wasi:io; world imports { - import streams - import poll + import streams; + import poll; } diff --git a/proposals/cli/wit/deps/random/insecure-seed.wit b/proposals/cli/wit/deps/random/insecure-seed.wit index ff2ff65d0..139aed159 100644 --- a/proposals/cli/wit/deps/random/insecure-seed.wit +++ b/proposals/cli/wit/deps/random/insecure-seed.wit @@ -20,5 +20,5 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - insecure-seed: func() -> tuple + insecure-seed: func() -> tuple; } diff --git a/proposals/cli/wit/deps/random/insecure.wit b/proposals/cli/wit/deps/random/insecure.wit index ff0826822..2ffd223cb 100644 --- a/proposals/cli/wit/deps/random/insecure.wit +++ b/proposals/cli/wit/deps/random/insecure.wit @@ -11,11 +11,11 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - get-insecure-random-bytes: func(len: u64) -> list + get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - get-insecure-random-u64: func() -> u64 + get-insecure-random-u64: func() -> u64; } diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index 2a282dab7..2c3c6a859 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -15,11 +15,11 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - get-random-bytes: func(len: u64) -> list + get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - get-random-u64: func() -> u64 + get-random-u64: func() -> u64; } diff --git a/proposals/cli/wit/deps/random/world.wit b/proposals/cli/wit/deps/random/world.wit index 41dc9ed10..bb1dd7b59 100644 --- a/proposals/cli/wit/deps/random/world.wit +++ b/proposals/cli/wit/deps/random/world.wit @@ -1,7 +1,7 @@ -package wasi:random +package wasi:random; world imports { - import random - import insecure - import insecure-seed + import random; + import insecure; + import insecure-seed; } diff --git a/proposals/cli/wit/deps/sockets/instance-network.wit b/proposals/cli/wit/deps/sockets/instance-network.wit index d911a29cc..14e4479e6 100644 --- a/proposals/cli/wit/deps/sockets/instance-network.wit +++ b/proposals/cli/wit/deps/sockets/instance-network.wit @@ -1,9 +1,9 @@ /// This interface provides a value-export of the default network handle.. interface instance-network { - use network.{network} + use network.{network}; /// Get a handle to the default network. - instance-network: func() -> network + instance-network: func() -> network; } diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index f998aae14..b51fe05e5 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ interface ip-name-lookup { - use wasi:io/poll.{pollable} - use network.{network, error-code, ip-address, ip-address-family} + use wasi:io/poll.{pollable}; + use network.{network, error-code, ip-address, ip-address-family}; /// Resolve an internet host name to a list of IP addresses. @@ -34,7 +34,7 @@ interface ip-name-lookup { /// - /// - /// - - resolve-addresses: func(network: borrow, name: string, address-family: option, include-unavailable: bool) -> result + resolve-addresses: func(network: borrow, name: string, address-family: option, include-unavailable: bool) -> result; resource resolve-address-stream { /// Returns the next address from the resolver. @@ -50,12 +50,12 @@ interface ip-name-lookup { /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) - resolve-next-address: func() -> result, error-code> + resolve-next-address: func() -> result, error-code>; /// Create a `pollable` which will resolve once the stream is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable + subscribe: func() -> pollable; } } diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit index 8214eaaf7..e2695954b 100644 --- a/proposals/cli/wit/deps/sockets/network.wit +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -3,7 +3,7 @@ interface network { /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. - resource network + resource network; /// Error codes. /// @@ -150,8 +150,8 @@ interface network { ipv6, } - type ipv4-address = tuple - type ipv6-address = tuple + type ipv4-address = tuple; + type ipv6-address = tuple; variant ip-address { ipv4(ipv4-address), diff --git a/proposals/cli/wit/deps/sockets/tcp-create-socket.wit b/proposals/cli/wit/deps/sockets/tcp-create-socket.wit index f43bc8979..056bbef33 100644 --- a/proposals/cli/wit/deps/sockets/tcp-create-socket.wit +++ b/proposals/cli/wit/deps/sockets/tcp-create-socket.wit @@ -1,7 +1,7 @@ interface tcp-create-socket { - use network.{network, error-code, ip-address-family} - use tcp.{tcp-socket} + use network.{network, error-code, ip-address-family}; + use tcp.{tcp-socket}; /// Create a new TCP socket. /// @@ -23,5 +23,5 @@ interface tcp-create-socket { /// - /// - /// - - create-tcp-socket: func(address-family: ip-address-family) -> result + create-tcp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index 175626cc7..fea44380d 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -1,8 +1,8 @@ interface tcp { - use wasi:io/streams.{input-stream, output-stream} - use wasi:io/poll.{pollable} - use network.{network, error-code, ip-socket-address, ip-address-family} + use wasi:io/streams.{input-stream, output-stream}; + use wasi:io/poll.{pollable}; + use network.{network, error-code, ip-socket-address, ip-address-family}; enum shutdown-type { /// Similar to `SHUT_RD` in POSIX. @@ -46,8 +46,8 @@ interface tcp { /// - /// - /// - - start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code> - finish-bind: func() -> result<_, error-code> + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + finish-bind: func() -> result<_, error-code>; /// Connect to a remote endpoint. /// @@ -78,8 +78,8 @@ interface tcp { /// - /// - /// - - start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code> - finish-connect: func() -> result, error-code> + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + finish-connect: func() -> result, error-code>; /// Start listening for new connections. /// @@ -105,8 +105,8 @@ interface tcp { /// - /// - /// - - start-listen: func() -> result<_, error-code> - finish-listen: func() -> result<_, error-code> + start-listen: func() -> result<_, error-code>; + finish-listen: func() -> result<_, error-code>; /// Accept a new client socket. /// @@ -126,7 +126,7 @@ interface tcp { /// - /// - /// - - accept: func() -> result, error-code> + accept: func() -> result, error-code>; /// Get the bound local address. /// @@ -138,7 +138,7 @@ interface tcp { /// - /// - /// - - local-address: func() -> result + local-address: func() -> result; /// Get the bound remote address. /// @@ -150,12 +150,12 @@ interface tcp { /// - /// - /// - - remote-address: func() -> result + remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. - address-family: func() -> ip-address-family + address-family: func() -> ip-address-family; /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. /// @@ -166,29 +166,29 @@ interface tcp { /// - `already-bound`: (set) The socket is already bound. /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - ipv6-only: func() -> result - set-ipv6-only: func(value: bool) -> result<_, error-code> + ipv6-only: func() -> result; + set-ipv6-only: func(value: bool) -> result<_, error-code>; /// Hints the desired listen queue size. Implementations are free to ignore this. /// /// # Typical errors /// - `already-connected`: (set) The socket is already in the Connection state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - set-listen-backlog-size: func(value: u64) -> result<_, error-code> + set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Equivalent to the SO_KEEPALIVE socket option. /// /// # Typical errors /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - keep-alive: func() -> result - set-keep-alive: func(value: bool) -> result<_, error-code> + keep-alive: func() -> result; + set-keep-alive: func(value: bool) -> result<_, error-code>; /// Equivalent to the TCP_NODELAY socket option. /// /// # Typical errors /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - no-delay: func() -> result - set-no-delay: func(value: bool) -> result<_, error-code> + no-delay: func() -> result; + set-no-delay: func(value: bool) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// @@ -196,8 +196,8 @@ interface tcp { /// - `already-connected`: (set) The socket is already in the Connection state. /// - `already-listening`: (set) The socket is already in the Listener state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - unicast-hop-limit: func() -> result - set-unicast-hop-limit: func(value: u8) -> result<_, error-code> + unicast-hop-limit: func() -> result; + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -214,16 +214,16 @@ interface tcp { /// - `already-connected`: (set) The socket is already in the Connection state. /// - `already-listening`: (set) The socket is already in the Listener state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - receive-buffer-size: func() -> result - set-receive-buffer-size: func(value: u64) -> result<_, error-code> - send-buffer-size: func() -> result - set-send-buffer-size: func(value: u64) -> result<_, error-code> + receive-buffer-size: func() -> result; + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + send-buffer-size: func() -> result; + set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Create a `pollable` which will resolve once the socket is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable + subscribe: func() -> pollable; /// Initiate a graceful shutdown. /// @@ -244,6 +244,6 @@ interface tcp { /// - /// - /// - - shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code> + shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; } } diff --git a/proposals/cli/wit/deps/sockets/udp-create-socket.wit b/proposals/cli/wit/deps/sockets/udp-create-socket.wit index cd4c08fb1..66f948226 100644 --- a/proposals/cli/wit/deps/sockets/udp-create-socket.wit +++ b/proposals/cli/wit/deps/sockets/udp-create-socket.wit @@ -1,7 +1,7 @@ interface udp-create-socket { - use network.{network, error-code, ip-address-family} - use udp.{udp-socket} + use network.{network, error-code, ip-address-family}; + use udp.{udp-socket}; /// Create a new UDP socket. /// @@ -23,5 +23,5 @@ interface udp-create-socket { /// - /// - /// - - create-udp-socket: func(address-family: ip-address-family) -> result + create-udp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index 01e5b95b9..e20b57e7e 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ interface udp { - use wasi:io/poll.{pollable} - use network.{network, error-code, ip-socket-address, ip-address-family} + use wasi:io/poll.{pollable}; + use network.{network, error-code, ip-socket-address, ip-address-family}; record datagram { @@ -47,8 +47,8 @@ interface udp { /// - /// - /// - - start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code> - finish-bind: func() -> result<_, error-code> + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + finish-bind: func() -> result<_, error-code>; /// Set the destination address. /// @@ -79,8 +79,8 @@ interface udp { /// - /// - /// - - start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code> - finish-connect: func() -> result<_, error-code> + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + finish-connect: func() -> result<_, error-code>; /// Receive messages on the socket. /// @@ -102,7 +102,7 @@ interface udp { /// - /// - /// - - receive: func(max-results: u64) -> result, error-code> + receive: func(max-results: u64) -> result, error-code>; /// Send messages on the socket. /// @@ -137,7 +137,7 @@ interface udp { /// - /// - /// - - send: func(datagrams: list) -> result + send: func(datagrams: list) -> result; /// Get the current bound address. /// @@ -149,7 +149,7 @@ interface udp { /// - /// - /// - - local-address: func() -> result + local-address: func() -> result; /// Get the address set with `connect`. /// @@ -161,12 +161,12 @@ interface udp { /// - /// - /// - - remote-address: func() -> result + remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. - address-family: func() -> ip-address-family + address-family: func() -> ip-address-family; /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. /// @@ -177,15 +177,15 @@ interface udp { /// - `already-bound`: (set) The socket is already bound. /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - ipv6-only: func() -> result - set-ipv6-only: func(value: bool) -> result<_, error-code> + ipv6-only: func() -> result; + set-ipv6-only: func(value: bool) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// /// # Typical errors /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - unicast-hop-limit: func() -> result - set-unicast-hop-limit: func(value: u8) -> result<_, error-code> + unicast-hop-limit: func() -> result; + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -200,15 +200,15 @@ interface udp { /// /// # Typical errors /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - receive-buffer-size: func() -> result - set-receive-buffer-size: func(value: u64) -> result<_, error-code> - send-buffer-size: func() -> result - set-send-buffer-size: func(value: u64) -> result<_, error-code> + receive-buffer-size: func() -> result; + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + send-buffer-size: func() -> result; + set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Create a `pollable` which will resolve once the socket is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable + subscribe: func() -> pollable; } } diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit index 12f3c2868..432b0dc99 100644 --- a/proposals/cli/wit/deps/sockets/world.wit +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -1,11 +1,11 @@ -package wasi:sockets +package wasi:sockets; world imports { - import instance-network - import network - import udp - import udp-create-socket - import tcp - import tcp-create-socket - import ip-name-lookup + import instance-network; + import network; + import udp; + import udp-create-socket; + import tcp; + import tcp-create-socket; + import ip-name-lookup; } From 53527243797e0d881e0fa401948c052bcdd4bff2 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:43:34 -0700 Subject: [PATCH 1237/1772] wit: use semicolons as statement separator --- proposals/cli/wit/command.wit | 6 ++-- proposals/cli/wit/environment.wit | 6 ++-- proposals/cli/wit/exit.wit | 2 +- proposals/cli/wit/reactor.wit | 58 ++++++++++++++++--------------- proposals/cli/wit/run.wit | 2 +- proposals/cli/wit/stdio.wit | 12 +++---- proposals/cli/wit/terminal.wit | 16 ++++----- 7 files changed, 52 insertions(+), 50 deletions(-) diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index d28f5f628..86c9c73b7 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,7 +1,7 @@ -package wasi:cli +package wasi:cli; world command { - include reactor + include reactor; - export run + export run; } diff --git a/proposals/cli/wit/environment.wit b/proposals/cli/wit/environment.wit index 36790fe71..70065233e 100644 --- a/proposals/cli/wit/environment.wit +++ b/proposals/cli/wit/environment.wit @@ -7,12 +7,12 @@ interface environment { /// Morally, these are a value import, but until value imports are available /// in the component model, this import function should return the same /// values each time it is called. - get-environment: func() -> list> + get-environment: func() -> list>; /// Get the POSIX-style arguments to the program. - get-arguments: func() -> list + get-arguments: func() -> list; /// Return a path that programs should use as their initial current working /// directory, interpreting `.` as shorthand for this. - initial-cwd: func() -> option + initial-cwd: func() -> option; } diff --git a/proposals/cli/wit/exit.wit b/proposals/cli/wit/exit.wit index 4831d5078..d0c2b82ae 100644 --- a/proposals/cli/wit/exit.wit +++ b/proposals/cli/wit/exit.wit @@ -1,4 +1,4 @@ interface exit { /// Exit the current instance and any linked instances. - exit: func(status: result) + exit: func(status: result); } diff --git a/proposals/cli/wit/reactor.wit b/proposals/cli/wit/reactor.wit index 13da405e0..6bd780e76 100644 --- a/proposals/cli/wit/reactor.wit +++ b/proposals/cli/wit/reactor.wit @@ -1,30 +1,32 @@ +package wasi:cli; + world reactor { - import wasi:clocks/wall-clock - import wasi:clocks/monotonic-clock - import wasi:clocks/timezone - import wasi:filesystem/types - import wasi:filesystem/preopens - import wasi:sockets/instance-network - import wasi:sockets/ip-name-lookup - import wasi:sockets/network - import wasi:sockets/tcp-create-socket - import wasi:sockets/tcp - import wasi:sockets/udp-create-socket - import wasi:sockets/udp - import wasi:random/random - import wasi:random/insecure - import wasi:random/insecure-seed - import wasi:io/poll - import wasi:io/streams - import environment - import exit - import stdin - import stdout - import stderr - import terminal-input - import terminal-output - import terminal-stdin - import terminal-stdout - import terminal-stderr -} + import wasi:clocks/wall-clock; + import wasi:clocks/monotonic-clock; + import wasi:clocks/timezone; + import wasi:filesystem/types; + import wasi:filesystem/preopens; + import wasi:sockets/instance-network; + import wasi:sockets/ip-name-lookup; + import wasi:sockets/network; + import wasi:sockets/tcp-create-socket; + import wasi:sockets/tcp; + import wasi:sockets/udp-create-socket; + import wasi:sockets/udp; + import wasi:random/random; + import wasi:random/insecure; + import wasi:random/insecure-seed; + import wasi:io/poll; + import wasi:io/streams; + import environment; + import exit; + import stdin; + import stdout; + import stderr; + import terminal-input; + import terminal-output; + import terminal-stdin; + import terminal-stdout; + import terminal-stderr; +} diff --git a/proposals/cli/wit/run.wit b/proposals/cli/wit/run.wit index 45a1ca533..a70ee8c03 100644 --- a/proposals/cli/wit/run.wit +++ b/proposals/cli/wit/run.wit @@ -1,4 +1,4 @@ interface run { /// Run the program. - run: func() -> result + run: func() -> result; } diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index 6c9d4a41a..1bb6c5583 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,17 +1,17 @@ interface stdin { - use wasi:io/streams.{input-stream} + use wasi:io/streams.{input-stream}; - get-stdin: func() -> input-stream + get-stdin: func() -> input-stream; } interface stdout { - use wasi:io/streams.{output-stream} + use wasi:io/streams.{output-stream}; - get-stdout: func() -> output-stream + get-stdout: func() -> output-stream; } interface stderr { - use wasi:io/streams.{output-stream} + use wasi:io/streams.{output-stream}; - get-stderr: func() -> output-stream + get-stderr: func() -> output-stream; } diff --git a/proposals/cli/wit/terminal.wit b/proposals/cli/wit/terminal.wit index b0a5bec2a..47495769b 100644 --- a/proposals/cli/wit/terminal.wit +++ b/proposals/cli/wit/terminal.wit @@ -1,6 +1,6 @@ interface terminal-input { /// The input side of a terminal. - resource terminal-input + resource terminal-input; // In the future, this may include functions for disabling echoing, // disabling input buffering so that keyboard events are sent through @@ -9,7 +9,7 @@ interface terminal-input { interface terminal-output { /// The output side of a terminal. - resource terminal-output + resource terminal-output; // In the future, this may include functions for querying the terminal // size, being notified of terminal size changes, querying supported @@ -19,29 +19,29 @@ interface terminal-output { /// An interface providing an optional `terminal-input` for stdin as a /// link-time authority. interface terminal-stdin { - use terminal-input.{terminal-input} + use terminal-input.{terminal-input}; /// If stdin is connected to a terminal, return a `terminal-input` handle /// allowing further interaction with it. - get-terminal-stdin: func() -> option + get-terminal-stdin: func() -> option; } /// An interface providing an optional `terminal-output` for stdout as a /// link-time authority. interface terminal-stdout { - use terminal-output.{terminal-output} + use terminal-output.{terminal-output}; /// If stdout is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - get-terminal-stdout: func() -> option + get-terminal-stdout: func() -> option; } /// An interface providing an optional `terminal-output` for stderr as a /// link-time authority. interface terminal-stderr { - use terminal-output.{terminal-output} + use terminal-output.{terminal-output}; /// If stderr is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - get-terminal-stderr: func() -> option + get-terminal-stderr: func() -> option; } From 8c1d858b536d327b46515d4da82701c46df9f698 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:43:59 -0700 Subject: [PATCH 1238/1772] CI: use wit-abi-up-to-date@v16, which requires semicolons --- proposals/cli/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml index 1d47b5817..89f7521d9 100644 --- a/proposals/cli/.github/workflows/main.yml +++ b/proposals/cli/.github/workflows/main.yml @@ -18,6 +18,6 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v15 + - uses: WebAssembly/wit-abi-up-to-date@v16 with: worlds: "command reactor" From 134308f1308318362336990639becaf79d6469cf Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:50:43 -0700 Subject: [PATCH 1239/1772] wit-deps update these had gotten pretty out-of-date so its more than just the semicolons changes --- proposals/http/wit/deps.lock | 29 +- proposals/http/wit/deps.toml | 1 - proposals/http/wit/deps/cli/command.wit | 28 +- proposals/http/wit/deps/cli/environment.wit | 8 +- proposals/http/wit/deps/cli/exit.wit | 2 +- proposals/http/wit/deps/cli/preopens.wit | 11 - proposals/http/wit/deps/cli/reactor.wit | 32 + proposals/http/wit/deps/cli/run.wit | 2 +- proposals/http/wit/deps/cli/stdio.wit | 12 +- proposals/http/wit/deps/cli/terminal.wit | 28 +- .../http/wit/deps/clocks/monotonic-clock.wit | 10 +- proposals/http/wit/deps/clocks/timezone.wit | 19 +- proposals/http/wit/deps/clocks/wall-clock.wit | 4 +- proposals/http/wit/deps/clocks/world.wit | 10 +- .../http/wit/deps/filesystem/preopens.wit | 4 +- proposals/http/wit/deps/filesystem/types.wit | 1041 ++++++++--------- proposals/http/wit/deps/filesystem/world.wit | 8 +- proposals/http/wit/deps/io/poll.wit | 34 + proposals/http/wit/deps/io/streams.wit | 445 ++++--- proposals/http/wit/deps/io/world.wit | 7 +- proposals/http/wit/deps/poll/poll.wit | 49 - proposals/http/wit/deps/poll/world.wit | 5 - .../http/wit/deps/random/insecure-seed.wit | 2 +- proposals/http/wit/deps/random/insecure.wit | 4 +- proposals/http/wit/deps/random/random.wit | 4 +- proposals/http/wit/deps/random/world.wit | 10 +- .../wit/deps/sockets/instance-network.wit | 4 +- .../http/wit/deps/sockets/ip-name-lookup.wit | 60 +- proposals/http/wit/deps/sockets/network.wit | 18 +- .../wit/deps/sockets/tcp-create-socket.wit | 6 +- proposals/http/wit/deps/sockets/tcp.wit | 470 ++++---- .../wit/deps/sockets/udp-create-socket.wit | 6 +- proposals/http/wit/deps/sockets/udp.wit | 398 +++---- proposals/http/wit/deps/sockets/world.wit | 18 +- 34 files changed, 1364 insertions(+), 1425 deletions(-) delete mode 100644 proposals/http/wit/deps/cli/preopens.wit create mode 100644 proposals/http/wit/deps/cli/reactor.wit create mode 100644 proposals/http/wit/deps/io/poll.wit delete mode 100644 proposals/http/wit/deps/poll/poll.wit delete mode 100644 proposals/http/wit/deps/poll/world.wit diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 5cf8421ce..44c92bbfe 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,34 +1,29 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -sha256 = "f21b7722b9225b7ff4f040a67daacd4e412fe2c53c982568a2c25b97fc85d2a2" -sha512 = "ceec4b906f94ba53731dd9428e7e62b964de2284d6aa7cb3436cb856ca89405b0ca8b02e8a8d4575204b9e72dac0e3b29690221ca438324b89e0084117f1700f" +sha256 = "bf57bb59e137f1dea6521409137e46dbdcd0a78d419ac2313b59fb21332718cd" +sha512 = "36a793525eba4921f0bd55bc445465e86fc7ff8fcf3e5bb61108d35e4d791950b107b456ccadf65897a0a5cd201a5955741c9c1fecb533fca99e8bae478a2dbf" [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "1ed7e35b3f9738663854f0dd92a95bfadc410ea07170501f5c2fec0cc24e3d57" -sha512 = "ef1e23704a8a8436fd3718593d4c4d8b6d1c64dad3595b7496c0888ca14b725046f2900109800faca1bc8c14f237cdcaca791dba8284e1ad50105ab2d036825b" +sha256 = "74844f8bf1d356bb44aab64a2f917d7a3bcb6d6924662d2e3909aeabda01bea6" +sha512 = "ef21339a60a3f4a37eb48ab81b411c1f2ed11c9b23da04d1e384c07dd4cc75f1a433ce7b46201c693b7a59b51c73d888bc41c78ad204fe32d8a312a9f9a48eb0" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "dc170645d8aa52f2f94ab8f71093fa0c101e509ed1a07318995dc0395e9d6cf2" -sha512 = "3195a3e0f9ec52c3a91c4b4fde0547694236c7b29bceecb7f38634894fafd809c69ed1c1c9acbf225b2d5d00f5036d70371c9fed121d85028162b202035cabef" +sha256 = "ca8364780922eddd53ec77f9152c77486db3d7052f6a5902ccc1648d5494050c" +sha512 = "ef05d9d7d5c08bc6a701a65c5af1981f30b2eb5b1c3dc5ca39a69248be8ab7cb3b17c5d181a010149dd491846fa5a7ac4f9165b06e628f31227e02dbdd8b86f5" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "6e18239b0e20d1a3e6343cb961ebfd2c663ba7feb4c1aa3744b756fbdd1fb5b8" -sha512 = "53169b6e4fba0b2cf5fcf808f76e7fbb7cabb6ed66ab53f77d0966e7448312ccbe8571880ef4fc2ee86fbd6ba19bc48d46e10d22dcac6c51d217e8d7127c32db" - -[poll] -url = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" -sha256 = "d4c27124f4c137eb538b5c92ba5858ed9042e11b24a2eef85d14becd0b7f55de" -sha512 = "422c01b273b4b1377ece6f2e4ba0dfc609ca8ef30a3e0be0e172e1303fcf7b3ca4c470f4dea6c51bdf114b0f5c871ebc4934dfe3bf217d66ea689748df2b1e55" +sha256 = "a00c29dd57dc224e8ce28b793b19c1b1001dcdbdc229ed451c3df1db91841b34" +sha512 = "8558085eeb5689209101cdfbc9782953d559ad14ce77260fe2f7cc472482d568f65cad9e6a688d40c634c6c54c608f27e27e481633446114d6fdead93d4e34c5" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "9b622463e597b9ca94f41e4eaae589a77be38f71b4723142b60246ffed8eaae4" -sha512 = "21f03ca1e595b80d7ced522de1a47446526b49b900e2fb26fcbf410ce6aa267dbf247aebf3fbfa8123b46fc1a828e2fd64fb1e0198b40161a3257e8d86fd4546" +sha256 = "7d7c882d50baeb054a754b5766d46f5eed35a4470d887fc8b45121bfc7ac8701" +sha512 = "4b8aad54da50aa44d35f6e5eea87c67bbcedd610650500ffe350c8c8d26f7ee14c49c4c4cc51ebd0ae607459095092625f27a451e52232c575b460334b5a0606" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "871c211b12d87a5da87c42353338b652260840897efcd37e2afba3b9290058fc" -sha512 = "e436a5ff3145ca85d702a086499c03488523483dd3addc8d71e4946e9c186355291551bb6d38b157173836fcc318182403e6dba970de4512f6cfb3374ccad6b9" +sha256 = "e9cc9bf3e809c17f7a100f9498056e435eea133bcb0f1abd8833261f3e5ff067" +sha512 = "1917e06807dc5f9f0993fbffbb9a6c8c36ab25a14ba775ffee939aca458ecd52ee796764708381f7f4166665cfcf11a5d47dc756a1e38f291b270678455b3a02" diff --git a/proposals/http/wit/deps.toml b/proposals/http/wit/deps.toml index 11f43c153..dd738ac4c 100644 --- a/proposals/http/wit/deps.toml +++ b/proposals/http/wit/deps.toml @@ -1,6 +1,5 @@ io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" cli = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -poll = "https://github.com/WebAssembly/wasi-poll/archive/main.tar.gz" random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" # not used by http/proxy, but included to allow full contents of wasi-cli to validate diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit index 13675f180..86c9c73b7 100644 --- a/proposals/http/wit/deps/cli/command.wit +++ b/proposals/http/wit/deps/cli/command.wit @@ -1,27 +1,7 @@ -package wasi:cli +package wasi:cli; world command { - import wasi:clocks/wall-clock - import wasi:clocks/monotonic-clock - import wasi:clocks/timezone - import wasi:filesystem/types - import wasi:sockets/instance-network - import wasi:sockets/ip-name-lookup - import wasi:sockets/network - import wasi:sockets/tcp-create-socket - import wasi:sockets/tcp - import wasi:sockets/udp-create-socket - import wasi:sockets/udp - import wasi:random/random - import wasi:random/insecure - import wasi:random/insecure-seed - import wasi:poll/poll - import wasi:io/streams - import environment - import preopens - import exit - import stdin - import stdout - import stderr - export run + include reactor; + + export run; } diff --git a/proposals/http/wit/deps/cli/environment.wit b/proposals/http/wit/deps/cli/environment.wit index 65471e86d..70065233e 100644 --- a/proposals/http/wit/deps/cli/environment.wit +++ b/proposals/http/wit/deps/cli/environment.wit @@ -7,8 +7,12 @@ interface environment { /// Morally, these are a value import, but until value imports are available /// in the component model, this import function should return the same /// values each time it is called. - get-environment: func() -> list> + get-environment: func() -> list>; /// Get the POSIX-style arguments to the program. - get-arguments: func() -> list + get-arguments: func() -> list; + + /// Return a path that programs should use as their initial current working + /// directory, interpreting `.` as shorthand for this. + initial-cwd: func() -> option; } diff --git a/proposals/http/wit/deps/cli/exit.wit b/proposals/http/wit/deps/cli/exit.wit index 4831d5078..d0c2b82ae 100644 --- a/proposals/http/wit/deps/cli/exit.wit +++ b/proposals/http/wit/deps/cli/exit.wit @@ -1,4 +1,4 @@ interface exit { /// Exit the current instance and any linked instances. - exit: func(status: result) + exit: func(status: result); } diff --git a/proposals/http/wit/deps/cli/preopens.wit b/proposals/http/wit/deps/cli/preopens.wit deleted file mode 100644 index 637102878..000000000 --- a/proposals/http/wit/deps/cli/preopens.wit +++ /dev/null @@ -1,11 +0,0 @@ -interface preopens { - use wasi:filesystem/types.{descriptor} - use wasi:io/streams.{input-stream, output-stream} - - /// Return the set of of preopened directories, and their path. - get-directories: func() -> list> - - /// Return a path that programs should use as their initial current working - /// directory, interpreting `.` as shorthand for this. - initial-cwd: func() -> option -} diff --git a/proposals/http/wit/deps/cli/reactor.wit b/proposals/http/wit/deps/cli/reactor.wit new file mode 100644 index 000000000..6bd780e76 --- /dev/null +++ b/proposals/http/wit/deps/cli/reactor.wit @@ -0,0 +1,32 @@ +package wasi:cli; + +world reactor { + import wasi:clocks/wall-clock; + import wasi:clocks/monotonic-clock; + import wasi:clocks/timezone; + import wasi:filesystem/types; + import wasi:filesystem/preopens; + import wasi:sockets/instance-network; + import wasi:sockets/ip-name-lookup; + import wasi:sockets/network; + import wasi:sockets/tcp-create-socket; + import wasi:sockets/tcp; + import wasi:sockets/udp-create-socket; + import wasi:sockets/udp; + import wasi:random/random; + import wasi:random/insecure; + import wasi:random/insecure-seed; + import wasi:io/poll; + import wasi:io/streams; + + import environment; + import exit; + import stdin; + import stdout; + import stderr; + import terminal-input; + import terminal-output; + import terminal-stdin; + import terminal-stdout; + import terminal-stderr; +} diff --git a/proposals/http/wit/deps/cli/run.wit b/proposals/http/wit/deps/cli/run.wit index 45a1ca533..a70ee8c03 100644 --- a/proposals/http/wit/deps/cli/run.wit +++ b/proposals/http/wit/deps/cli/run.wit @@ -1,4 +1,4 @@ interface run { /// Run the program. - run: func() -> result + run: func() -> result; } diff --git a/proposals/http/wit/deps/cli/stdio.wit b/proposals/http/wit/deps/cli/stdio.wit index 6c9d4a41a..1bb6c5583 100644 --- a/proposals/http/wit/deps/cli/stdio.wit +++ b/proposals/http/wit/deps/cli/stdio.wit @@ -1,17 +1,17 @@ interface stdin { - use wasi:io/streams.{input-stream} + use wasi:io/streams.{input-stream}; - get-stdin: func() -> input-stream + get-stdin: func() -> input-stream; } interface stdout { - use wasi:io/streams.{output-stream} + use wasi:io/streams.{output-stream}; - get-stdout: func() -> output-stream + get-stdout: func() -> output-stream; } interface stderr { - use wasi:io/streams.{output-stream} + use wasi:io/streams.{output-stream}; - get-stderr: func() -> output-stream + get-stderr: func() -> output-stream; } diff --git a/proposals/http/wit/deps/cli/terminal.wit b/proposals/http/wit/deps/cli/terminal.wit index f32e74437..47495769b 100644 --- a/proposals/http/wit/deps/cli/terminal.wit +++ b/proposals/http/wit/deps/cli/terminal.wit @@ -1,59 +1,47 @@ interface terminal-input { /// The input side of a terminal. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type terminal-input = u32 + resource terminal-input; // In the future, this may include functions for disabling echoing, // disabling input buffering so that keyboard events are sent through // immediately, querying supported features, and so on. - - /// Dispose of the specified terminal-input after which it may no longer - /// be used. - drop-terminal-input: func(this: terminal-input) } interface terminal-output { /// The output side of a terminal. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type terminal-output = u32 + resource terminal-output; // In the future, this may include functions for querying the terminal // size, being notified of terminal size changes, querying supported // features, and so on. - - /// Dispose of the specified terminal-output, after which it may no longer - /// be used. - drop-terminal-output: func(this: terminal-output) } /// An interface providing an optional `terminal-input` for stdin as a /// link-time authority. interface terminal-stdin { - use terminal-input.{terminal-input} + use terminal-input.{terminal-input}; /// If stdin is connected to a terminal, return a `terminal-input` handle /// allowing further interaction with it. - get-terminal-stdin: func() -> option + get-terminal-stdin: func() -> option; } /// An interface providing an optional `terminal-output` for stdout as a /// link-time authority. interface terminal-stdout { - use terminal-output.{terminal-output} + use terminal-output.{terminal-output}; /// If stdout is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - get-terminal-stdout: func() -> option + get-terminal-stdout: func() -> option; } /// An interface providing an optional `terminal-output` for stderr as a /// link-time authority. interface terminal-stderr { - use terminal-output.{terminal-output} + use terminal-output.{terminal-output}; /// If stderr is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - get-terminal-stderr: func() -> option + get-terminal-stderr: func() -> option; } diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index fb8424eb0..d9ac7cb3f 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -9,24 +9,24 @@ /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:poll/poll.{pollable} + use wasi:io/poll.{pollable}; /// A timestamp in nanoseconds. - type instant = u64 + type instant = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - now: func() -> instant + now: func() -> instant; /// Query the resolution of the clock. - resolution: func() -> instant + resolution: func() -> instant; /// Create a `pollable` which will resolve once the specified time has been /// reached. subscribe: func( when: instant, absolute: bool - ) -> pollable + ) -> pollable; } diff --git a/proposals/http/wit/deps/clocks/timezone.wit b/proposals/http/wit/deps/clocks/timezone.wit index 662830871..e717e7b8d 100644 --- a/proposals/http/wit/deps/clocks/timezone.wit +++ b/proposals/http/wit/deps/clocks/timezone.wit @@ -1,14 +1,5 @@ interface timezone { - use wall-clock.{datetime} - - /// A timezone. - /// - /// In timezones that recognize daylight saving time, also known as daylight - /// time and summer time, the information returned from the functions varies - /// over time to reflect these adjustments. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type timezone = u32 + use wall-clock.{datetime}; /// Return information needed to display the given `datetime`. This includes /// the UTC offset, the time zone name, and a flag indicating whether @@ -17,14 +8,10 @@ interface timezone { /// If the timezone cannot be determined for the given `datetime`, return a /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight /// saving time. - display: func(this: timezone, when: datetime) -> timezone-display + display: func(when: datetime) -> timezone-display; /// The same as `display`, but only return the UTC offset. - utc-offset: func(this: timezone, when: datetime) -> s32 - - /// Dispose of the specified input-stream, after which it may no longer - /// be used. - drop-timezone: func(this: timezone) + utc-offset: func(when: datetime) -> s32; /// Information useful for displaying the timezone of a specific `datetime`. /// diff --git a/proposals/http/wit/deps/clocks/wall-clock.wit b/proposals/http/wit/deps/clocks/wall-clock.wit index dae44a730..c39564967 100644 --- a/proposals/http/wit/deps/clocks/wall-clock.wit +++ b/proposals/http/wit/deps/clocks/wall-clock.wit @@ -32,10 +32,10 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - now: func() -> datetime + now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - resolution: func() -> datetime + resolution: func() -> datetime; } diff --git a/proposals/http/wit/deps/clocks/world.wit b/proposals/http/wit/deps/clocks/world.wit index 291a9c75e..3295ba8d9 100644 --- a/proposals/http/wit/deps/clocks/world.wit +++ b/proposals/http/wit/deps/clocks/world.wit @@ -1,7 +1,7 @@ -package wasi:clocks +package wasi:clocks; -world example-world { - import monotonic-clock - import wall-clock - import timezone +world imports { + import monotonic-clock; + import wall-clock; + import timezone; } diff --git a/proposals/http/wit/deps/filesystem/preopens.wit b/proposals/http/wit/deps/filesystem/preopens.wit index f45661b8a..3f787ac3f 100644 --- a/proposals/http/wit/deps/filesystem/preopens.wit +++ b/proposals/http/wit/deps/filesystem/preopens.wit @@ -1,6 +1,6 @@ interface preopens { - use types.{descriptor} + use types.{descriptor}; /// Return the set of preopened directories, and their path. - get-directories: func() -> list> + get-directories: func() -> list>; } diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index a437f22ae..2050fb928 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -17,12 +17,17 @@ /// `..` and symbolic link steps, reaches a directory outside of the base /// directory, or reaches a symlink to an absolute or rooted path in the /// underlying filesystem, the function fails with `error-code::not-permitted`. +/// +/// For more information about WASI path resolution and sandboxing, see +/// [WASI filesystem path resolution]. +/// +/// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { - use wasi:io/streams.{input-stream, output-stream} - use wasi:clocks/wall-clock.{datetime} + use wasi:io/streams.{input-stream, output-stream}; + use wasi:clocks/wall-clock.{datetime}; /// File size or length of a region within a file. - type filesize = u64 + type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// @@ -55,14 +60,6 @@ interface types { read, /// Write mode: Data can be written to. write, - /// Requests non-blocking operation. - /// - /// When this flag is enabled, functions may return immediately with an - /// `error-code::would-block` error code in situations where they would - /// otherwise block. However, this non-blocking behavior is not - /// required. Implementations are permitted to ignore this flag and - /// block. This is similar to `O_NONBLOCK` in POSIX. - non-blocking, /// Request that writes be performed according to synchronized I/O file /// integrity completion. The data stored in the file and the file's /// metadata are synchronized. This is similar to `O_SYNC` in POSIX. @@ -110,11 +107,20 @@ interface types { /// length in bytes of the pathname contained in the symbolic link. size: filesize, /// Last data access timestamp. - data-access-timestamp: datetime, + /// + /// If the `option` is none, the platform doesn't maintain an access + /// timestamp for this file. + data-access-timestamp: option, /// Last data modification timestamp. - data-modification-timestamp: datetime, - /// Last file status change timestamp. - status-change-timestamp: datetime, + /// + /// If the `option` is none, the platform doesn't maintain a + /// modification timestamp for this file. + data-modification-timestamp: option, + /// Last file status-change timestamp. + /// + /// If the `option` is none, the platform doesn't maintain a + /// status-change timestamp for this file. + status-change-timestamp: option, } /// Flags determining the method of how paths are resolved. @@ -160,7 +166,7 @@ interface types { } /// Number of hard links to an inode. - type link-count = u64 + type link-count = u64; /// When setting a timestamp, this gives the value to set it to. variant new-timestamp { @@ -285,13 +291,6 @@ interface types { no-reuse, } - /// A descriptor is a reference to a filesystem object, which may be a file, - /// directory, named pipe, special file, or other object on which filesystem - /// calls may be made. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type descriptor = u32 - /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. record metadata-hash-value { @@ -301,541 +300,499 @@ interface types { upper: u64, } - /// Return a stream for reading from a file, if available. - /// - /// May fail with an error-code describing why the file cannot be read. - /// - /// Multiple read, write, and append streams may be active on the same open - /// file and they do not interfere with each other. - /// - /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. - read-via-stream: func( - this: descriptor, - /// The offset within the file at which to start reading. - offset: filesize, - ) -> result - - /// Return a stream for writing to a file, if available. - /// - /// May fail with an error-code describing why the file cannot be written. - /// - /// Note: This allows using `write-stream`, which is similar to `write` in - /// POSIX. - write-via-stream: func( - this: descriptor, - /// The offset within the file at which to start writing. - offset: filesize, - ) -> result - - /// Return a stream for appending to a file, if available. - /// - /// May fail with an error-code describing why the file cannot be appended. - /// - /// Note: This allows using `write-stream`, which is similar to `write` with - /// `O_APPEND` in in POSIX. - append-via-stream: func( - this: descriptor, - ) -> result + /// A descriptor is a reference to a filesystem object, which may be a file, + /// directory, named pipe, special file, or other object on which filesystem + /// calls may be made. + resource descriptor { + /// Return a stream for reading from a file, if available. + /// + /// May fail with an error-code describing why the file cannot be read. + /// + /// Multiple read, write, and append streams may be active on the same open + /// file and they do not interfere with each other. + /// + /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. + read-via-stream: func( + /// The offset within the file at which to start reading. + offset: filesize, + ) -> result; - /// Provide file advisory information on a descriptor. - /// - /// This is similar to `posix_fadvise` in POSIX. - advise: func( - this: descriptor, - /// The offset within the file to which the advisory applies. - offset: filesize, - /// The length of the region to which the advisory applies. - length: filesize, - /// The advice. - advice: advice - ) -> result<_, error-code> - - /// Synchronize the data of a file to disk. - /// - /// This function succeeds with no effect if the file descriptor is not - /// opened for writing. - /// - /// Note: This is similar to `fdatasync` in POSIX. - sync-data: func(this: descriptor) -> result<_, error-code> + /// Return a stream for writing to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be written. + /// + /// Note: This allows using `write-stream`, which is similar to `write` in + /// POSIX. + write-via-stream: func( + /// The offset within the file at which to start writing. + offset: filesize, + ) -> result; + + /// Return a stream for appending to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be appended. + /// + /// Note: This allows using `write-stream`, which is similar to `write` with + /// `O_APPEND` in in POSIX. + append-via-stream: func() -> result; - /// Get flags associated with a descriptor. - /// - /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. - /// - /// Note: This returns the value that was the `fs_flags` value returned - /// from `fdstat_get` in earlier versions of WASI. - get-flags: func(this: descriptor) -> result + /// Provide file advisory information on a descriptor. + /// + /// This is similar to `posix_fadvise` in POSIX. + advise: func( + /// The offset within the file to which the advisory applies. + offset: filesize, + /// The length of the region to which the advisory applies. + length: filesize, + /// The advice. + advice: advice + ) -> result<_, error-code>; + + /// Synchronize the data of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fdatasync` in POSIX. + sync-data: func() -> result<_, error-code>; - /// Get the dynamic type of a descriptor. - /// - /// Note: This returns the same value as the `type` field of the `fd-stat` - /// returned by `stat`, `stat-at` and similar. - /// - /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided - /// by `fstat` in POSIX. - /// - /// Note: This returns the value that was the `fs_filetype` value returned - /// from `fdstat_get` in earlier versions of WASI. - get-type: func(this: descriptor) -> result + /// Get flags associated with a descriptor. + /// + /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. + /// + /// Note: This returns the value that was the `fs_flags` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-flags: func() -> result; - /// Set status flags associated with a descriptor. - /// - /// This function may only change the `non-blocking` flag. - /// - /// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - /// - /// Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. - set-flags: func(this: descriptor, %flags: descriptor-flags) -> result<_, error-code> + /// Get the dynamic type of a descriptor. + /// + /// Note: This returns the same value as the `type` field of the `fd-stat` + /// returned by `stat`, `stat-at` and similar. + /// + /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided + /// by `fstat` in POSIX. + /// + /// Note: This returns the value that was the `fs_filetype` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-type: func() -> result; - /// Adjust the size of an open file. If this increases the file's size, the - /// extra bytes are filled with zeros. - /// - /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - set-size: func(this: descriptor, size: filesize) -> result<_, error-code> + /// Adjust the size of an open file. If this increases the file's size, the + /// extra bytes are filled with zeros. + /// + /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. + set-size: func(size: filesize) -> result<_, error-code>; - /// Adjust the timestamps of an open file or directory. - /// - /// Note: This is similar to `futimens` in POSIX. - /// - /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - set-times: func( - this: descriptor, - /// The desired values of the data access timestamp. - data-access-timestamp: new-timestamp, - /// The desired values of the data modification timestamp. - data-modification-timestamp: new-timestamp, - ) -> result<_, error-code> - - /// Read from a descriptor, without using and updating the descriptor's offset. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a bool which, when true, indicates that the end of the - /// file was reached. The returned list will contain up to `length` bytes; it - /// may return fewer than requested, if the end of the file is reached or - /// if the I/O operation is interrupted. - /// - /// In the future, this may change to return a `stream`. - /// - /// Note: This is similar to `pread` in POSIX. - read: func( - this: descriptor, - /// The maximum number of bytes to read. - length: filesize, - /// The offset within the file at which to read. - offset: filesize, - ) -> result, bool>, error-code> - - /// Write to a descriptor, without using and updating the descriptor's offset. - /// - /// It is valid to write past the end of a file; the file is extended to the - /// extent of the write, with bytes between the previous end and the start of - /// the write set to zero. - /// - /// In the future, this may change to take a `stream`. - /// - /// Note: This is similar to `pwrite` in POSIX. - write: func( - this: descriptor, - /// Data to write - buffer: list, - /// The offset within the file at which to write. - offset: filesize, - ) -> result - - /// Read directory entries from a directory. - /// - /// On filesystems where directories contain entries referring to themselves - /// and their parents, often named `.` and `..` respectively, these entries - /// are omitted. - /// - /// This always returns a new stream which starts at the beginning of the - /// directory. Multiple streams may be active on the same directory, and they - /// do not interfere with each other. - read-directory: func( - this: descriptor - ) -> result - - /// Synchronize the data and metadata of a file to disk. - /// - /// This function succeeds with no effect if the file descriptor is not - /// opened for writing. - /// - /// Note: This is similar to `fsync` in POSIX. - sync: func(this: descriptor) -> result<_, error-code> + /// Adjust the timestamps of an open file or directory. + /// + /// Note: This is similar to `futimens` in POSIX. + /// + /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. + set-times: func( + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code>; + + /// Read from a descriptor, without using and updating the descriptor's offset. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a bool which, when true, indicates that the end of the + /// file was reached. The returned list will contain up to `length` bytes; it + /// may return fewer than requested, if the end of the file is reached or + /// if the I/O operation is interrupted. + /// + /// In the future, this may change to return a `stream`. + /// + /// Note: This is similar to `pread` in POSIX. + read: func( + /// The maximum number of bytes to read. + length: filesize, + /// The offset within the file at which to read. + offset: filesize, + ) -> result, bool>, error-code>; + + /// Write to a descriptor, without using and updating the descriptor's offset. + /// + /// It is valid to write past the end of a file; the file is extended to the + /// extent of the write, with bytes between the previous end and the start of + /// the write set to zero. + /// + /// In the future, this may change to take a `stream`. + /// + /// Note: This is similar to `pwrite` in POSIX. + write: func( + /// Data to write + buffer: list, + /// The offset within the file at which to write. + offset: filesize, + ) -> result; + + /// Read directory entries from a directory. + /// + /// On filesystems where directories contain entries referring to themselves + /// and their parents, often named `.` and `..` respectively, these entries + /// are omitted. + /// + /// This always returns a new stream which starts at the beginning of the + /// directory. Multiple streams may be active on the same directory, and they + /// do not interfere with each other. + read-directory: func() -> result; - /// Create a directory. - /// - /// Note: This is similar to `mkdirat` in POSIX. - create-directory-at: func( - this: descriptor, - /// The relative path at which to create the directory. - path: string, - ) -> result<_, error-code> - - /// Return the attributes of an open file or directory. - /// - /// Note: This is similar to `fstat` in POSIX, except that it does not return - /// device and inode information. For testing whether two descriptors refer to - /// the same underlying filesystem object, use `is-same-object`. To obtain - /// additional data that can be used do determine whether a file has been - /// modified, use `metadata-hash`. - /// - /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - stat: func(this: descriptor) -> result + /// Synchronize the data and metadata of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fsync` in POSIX. + sync: func() -> result<_, error-code>; - /// Return the attributes of a file or directory. - /// - /// Note: This is similar to `fstatat` in POSIX, except that it does not - /// return device and inode information. See the `stat` description for a - /// discussion of alternatives. - /// - /// Note: This was called `path_filestat_get` in earlier versions of WASI. - stat-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to inspect. - path: string, - ) -> result - - /// Adjust the timestamps of a file or directory. - /// - /// Note: This is similar to `utimensat` in POSIX. - /// - /// Note: This was called `path_filestat_set_times` in earlier versions of - /// WASI. - set-times-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to operate on. - path: string, - /// The desired values of the data access timestamp. - data-access-timestamp: new-timestamp, - /// The desired values of the data modification timestamp. - data-modification-timestamp: new-timestamp, - ) -> result<_, error-code> - - /// Create a hard link. - /// - /// Note: This is similar to `linkat` in POSIX. - link-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - old-path-flags: path-flags, - /// The relative source path from which to link. - old-path: string, - /// The base directory for `new-path`. - new-descriptor: descriptor, - /// The relative destination path at which to create the hard link. - new-path: string, - ) -> result<_, error-code> - - /// Open a file or directory. - /// - /// The returned descriptor is not guaranteed to be the lowest-numbered - /// descriptor not currently open/ it is randomized to prevent applications - /// from depending on making assumptions about indexes, since this is - /// error-prone in multi-threaded contexts. The returned descriptor is - /// guaranteed to be less than 2**31. - /// - /// If `flags` contains `descriptor-flags::mutate-directory`, and the base - /// descriptor doesn't have `descriptor-flags::mutate-directory` set, - /// `open-at` fails with `error-code::read-only`. - /// - /// If `flags` contains `write` or `mutate-directory`, or `open-flags` - /// contains `truncate` or `create`, and the base descriptor doesn't have - /// `descriptor-flags::mutate-directory` set, `open-at` fails with - /// `error-code::read-only`. - /// - /// Note: This is similar to `openat` in POSIX. - open-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the object to open. - path: string, - /// The method by which to open the file. - open-flags: open-flags, - /// Flags to use for the resulting descriptor. - %flags: descriptor-flags, - /// Permissions to use when creating a new file. - modes: modes - ) -> result - - /// Read the contents of a symbolic link. - /// - /// If the contents contain an absolute or rooted path in the underlying - /// filesystem, this function fails with `error-code::not-permitted`. - /// - /// Note: This is similar to `readlinkat` in POSIX. - readlink-at: func( - this: descriptor, - /// The relative path of the symbolic link from which to read. - path: string, - ) -> result - - /// Remove a directory. - /// - /// Return `error-code::not-empty` if the directory is not empty. - /// - /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - remove-directory-at: func( - this: descriptor, - /// The relative path to a directory to remove. - path: string, - ) -> result<_, error-code> - - /// Rename a filesystem object. - /// - /// Note: This is similar to `renameat` in POSIX. - rename-at: func( - this: descriptor, - /// The relative source path of the file or directory to rename. - old-path: string, - /// The base directory for `new-path`. - new-descriptor: descriptor, - /// The relative destination path to which to rename the file or directory. - new-path: string, - ) -> result<_, error-code> - - /// Create a symbolic link (also known as a "symlink"). - /// - /// If `old-path` starts with `/`, the function fails with - /// `error-code::not-permitted`. - /// - /// Note: This is similar to `symlinkat` in POSIX. - symlink-at: func( - this: descriptor, - /// The contents of the symbolic link. - old-path: string, - /// The relative destination path at which to create the symbolic link. - new-path: string, - ) -> result<_, error-code> - - /// Check accessibility of a filesystem path. - /// - /// Check whether the given filesystem path names an object which is - /// readable, writable, or executable, or whether it exists. - /// - /// This does not a guarantee that subsequent accesses will succeed, as - /// filesystem permissions may be modified asynchronously by external - /// entities. - /// - /// Note: This is similar to `faccessat` with the `AT_EACCESS` flag in POSIX. - access-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to check. - path: string, - /// The type of check to perform. - %type: access-type - ) -> result<_, error-code> - - /// Unlink a filesystem object that is not a directory. - /// - /// Return `error-code::is-directory` if the path refers to a directory. - /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - unlink-file-at: func( - this: descriptor, - /// The relative path to a file to unlink. - path: string, - ) -> result<_, error-code> - - /// Change the permissions of a filesystem object that is not a directory. - /// - /// Note that the ultimate meanings of these permissions is - /// filesystem-specific. - /// - /// Note: This is similar to `fchmodat` in POSIX. - change-file-permissions-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the filesystem object. - modes: modes, - ) -> result<_, error-code> - - /// Change the permissions of a directory. - /// - /// Note that the ultimate meanings of these permissions is - /// filesystem-specific. - /// - /// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" - /// flag. `read` on a directory implies readability and searchability, and - /// `execute` is not valid for directories. - /// - /// Note: This is similar to `fchmodat` in POSIX. - change-directory-permissions-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the directory. - modes: modes, - ) -> result<_, error-code> - - /// Request a shared advisory lock for an open file. - /// - /// This requests a *shared* lock; more than one shared lock can be held for - /// a file at the same time. - /// - /// If the open file has an exclusive lock, this function downgrades the lock - /// to a shared lock. If it has a shared lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified how shared locks interact with locks acquired by - /// non-WASI programs. - /// - /// This function blocks until the lock can be acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. - lock-shared: func(this: descriptor) -> result<_, error-code> + /// Create a directory. + /// + /// Note: This is similar to `mkdirat` in POSIX. + create-directory-at: func( + /// The relative path at which to create the directory. + path: string, + ) -> result<_, error-code>; - /// Request an exclusive advisory lock for an open file. - /// - /// This requests an *exclusive* lock; no other locks may be held for the - /// file while an exclusive lock is held. - /// - /// If the open file has a shared lock and there are no exclusive locks held - /// for the file, this function upgrades the lock to an exclusive lock. If the - /// open file already has an exclusive lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified whether this function succeeds if the file descriptor - /// is not opened for writing. It is unspecified how exclusive locks interact - /// with locks acquired by non-WASI programs. - /// - /// This function blocks until the lock can be acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. - lock-exclusive: func(this: descriptor) -> result<_, error-code> + /// Return the attributes of an open file or directory. + /// + /// Note: This is similar to `fstat` in POSIX, except that it does not return + /// device and inode information. For testing whether two descriptors refer to + /// the same underlying filesystem object, use `is-same-object`. To obtain + /// additional data that can be used do determine whether a file has been + /// modified, use `metadata-hash`. + /// + /// Note: This was called `fd_filestat_get` in earlier versions of WASI. + stat: func() -> result; - /// Request a shared advisory lock for an open file. - /// - /// This requests a *shared* lock; more than one shared lock can be held for - /// a file at the same time. - /// - /// If the open file has an exclusive lock, this function downgrades the lock - /// to a shared lock. If it has a shared lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified how shared locks interact with locks acquired by - /// non-WASI programs. - /// - /// This function returns `error-code::would-block` if the lock cannot be - /// acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. - try-lock-shared: func(this: descriptor) -> result<_, error-code> + /// Return the attributes of a file or directory. + /// + /// Note: This is similar to `fstatat` in POSIX, except that it does not + /// return device and inode information. See the `stat` description for a + /// discussion of alternatives. + /// + /// Note: This was called `path_filestat_get` in earlier versions of WASI. + stat-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result; + + /// Adjust the timestamps of a file or directory. + /// + /// Note: This is similar to `utimensat` in POSIX. + /// + /// Note: This was called `path_filestat_set_times` in earlier versions of + /// WASI. + set-times-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to operate on. + path: string, + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code>; + + /// Create a hard link. + /// + /// Note: This is similar to `linkat` in POSIX. + link-at: func( + /// Flags determining the method of how the path is resolved. + old-path-flags: path-flags, + /// The relative source path from which to link. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: borrow, + /// The relative destination path at which to create the hard link. + new-path: string, + ) -> result<_, error-code>; + + /// Open a file or directory. + /// + /// The returned descriptor is not guaranteed to be the lowest-numbered + /// descriptor not currently open/ it is randomized to prevent applications + /// from depending on making assumptions about indexes, since this is + /// error-prone in multi-threaded contexts. The returned descriptor is + /// guaranteed to be less than 2**31. + /// + /// If `flags` contains `descriptor-flags::mutate-directory`, and the base + /// descriptor doesn't have `descriptor-flags::mutate-directory` set, + /// `open-at` fails with `error-code::read-only`. + /// + /// If `flags` contains `write` or `mutate-directory`, or `open-flags` + /// contains `truncate` or `create`, and the base descriptor doesn't have + /// `descriptor-flags::mutate-directory` set, `open-at` fails with + /// `error-code::read-only`. + /// + /// Note: This is similar to `openat` in POSIX. + open-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the object to open. + path: string, + /// The method by which to open the file. + open-flags: open-flags, + /// Flags to use for the resulting descriptor. + %flags: descriptor-flags, + /// Permissions to use when creating a new file. + modes: modes + ) -> result; + + /// Read the contents of a symbolic link. + /// + /// If the contents contain an absolute or rooted path in the underlying + /// filesystem, this function fails with `error-code::not-permitted`. + /// + /// Note: This is similar to `readlinkat` in POSIX. + readlink-at: func( + /// The relative path of the symbolic link from which to read. + path: string, + ) -> result; - /// Request an exclusive advisory lock for an open file. - /// - /// This requests an *exclusive* lock; no other locks may be held for the - /// file while an exclusive lock is held. - /// - /// If the open file has a shared lock and there are no exclusive locks held - /// for the file, this function upgrades the lock to an exclusive lock. If the - /// open file already has an exclusive lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified whether this function succeeds if the file descriptor - /// is not opened for writing. It is unspecified how exclusive locks interact - /// with locks acquired by non-WASI programs. - /// - /// This function returns `error-code::would-block` if the lock cannot be - /// acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. - try-lock-exclusive: func(this: descriptor) -> result<_, error-code> + /// Remove a directory. + /// + /// Return `error-code::not-empty` if the directory is not empty. + /// + /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + remove-directory-at: func( + /// The relative path to a directory to remove. + path: string, + ) -> result<_, error-code>; - /// Release a shared or exclusive lock on an open file. - /// - /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. - unlock: func(this: descriptor) -> result<_, error-code> + /// Rename a filesystem object. + /// + /// Note: This is similar to `renameat` in POSIX. + rename-at: func( + /// The relative source path of the file or directory to rename. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: borrow, + /// The relative destination path to which to rename the file or directory. + new-path: string, + ) -> result<_, error-code>; + + /// Create a symbolic link (also known as a "symlink"). + /// + /// If `old-path` starts with `/`, the function fails with + /// `error-code::not-permitted`. + /// + /// Note: This is similar to `symlinkat` in POSIX. + symlink-at: func( + /// The contents of the symbolic link. + old-path: string, + /// The relative destination path at which to create the symbolic link. + new-path: string, + ) -> result<_, error-code>; + + /// Check accessibility of a filesystem path. + /// + /// Check whether the given filesystem path names an object which is + /// readable, writable, or executable, or whether it exists. + /// + /// This does not a guarantee that subsequent accesses will succeed, as + /// filesystem permissions may be modified asynchronously by external + /// entities. + /// + /// Note: This is similar to `faccessat` with the `AT_EACCESS` flag in POSIX. + access-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to check. + path: string, + /// The type of check to perform. + %type: access-type + ) -> result<_, error-code>; + + /// Unlink a filesystem object that is not a directory. + /// + /// Return `error-code::is-directory` if the path refers to a directory. + /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + unlink-file-at: func( + /// The relative path to a file to unlink. + path: string, + ) -> result<_, error-code>; + + /// Change the permissions of a filesystem object that is not a directory. + /// + /// Note that the ultimate meanings of these permissions is + /// filesystem-specific. + /// + /// Note: This is similar to `fchmodat` in POSIX. + change-file-permissions-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to operate on. + path: string, + /// The new permissions for the filesystem object. + modes: modes, + ) -> result<_, error-code>; + + /// Change the permissions of a directory. + /// + /// Note that the ultimate meanings of these permissions is + /// filesystem-specific. + /// + /// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" + /// flag. `read` on a directory implies readability and searchability, and + /// `execute` is not valid for directories. + /// + /// Note: This is similar to `fchmodat` in POSIX. + change-directory-permissions-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to operate on. + path: string, + /// The new permissions for the directory. + modes: modes, + ) -> result<_, error-code>; + + /// Request a shared advisory lock for an open file. + /// + /// This requests a *shared* lock; more than one shared lock can be held for + /// a file at the same time. + /// + /// If the open file has an exclusive lock, this function downgrades the lock + /// to a shared lock. If it has a shared lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified how shared locks interact with locks acquired by + /// non-WASI programs. + /// + /// This function blocks until the lock can be acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. + lock-shared: func() -> result<_, error-code>; - /// Dispose of the specified `descriptor`, after which it may no longer - /// be used. - drop-descriptor: func(this: descriptor) + /// Request an exclusive advisory lock for an open file. + /// + /// This requests an *exclusive* lock; no other locks may be held for the + /// file while an exclusive lock is held. + /// + /// If the open file has a shared lock and there are no exclusive locks held + /// for the file, this function upgrades the lock to an exclusive lock. If the + /// open file already has an exclusive lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified whether this function succeeds if the file descriptor + /// is not opened for writing. It is unspecified how exclusive locks interact + /// with locks acquired by non-WASI programs. + /// + /// This function blocks until the lock can be acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. + lock-exclusive: func() -> result<_, error-code>; - /// A stream of directory entries. - /// - /// This [represents a stream of `dir-entry`](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Streams). - type directory-entry-stream = u32 + /// Request a shared advisory lock for an open file. + /// + /// This requests a *shared* lock; more than one shared lock can be held for + /// a file at the same time. + /// + /// If the open file has an exclusive lock, this function downgrades the lock + /// to a shared lock. If it has a shared lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified how shared locks interact with locks acquired by + /// non-WASI programs. + /// + /// This function returns `error-code::would-block` if the lock cannot be + /// acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. + try-lock-shared: func() -> result<_, error-code>; - /// Read a single directory entry from a `directory-entry-stream`. - read-directory-entry: func( - this: directory-entry-stream - ) -> result, error-code> + /// Request an exclusive advisory lock for an open file. + /// + /// This requests an *exclusive* lock; no other locks may be held for the + /// file while an exclusive lock is held. + /// + /// If the open file has a shared lock and there are no exclusive locks held + /// for the file, this function upgrades the lock to an exclusive lock. If the + /// open file already has an exclusive lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified whether this function succeeds if the file descriptor + /// is not opened for writing. It is unspecified how exclusive locks interact + /// with locks acquired by non-WASI programs. + /// + /// This function returns `error-code::would-block` if the lock cannot be + /// acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. + try-lock-exclusive: func() -> result<_, error-code>; - /// Dispose of the specified `directory-entry-stream`, after which it may no longer - /// be used. - drop-directory-entry-stream: func(this: directory-entry-stream) + /// Release a shared or exclusive lock on an open file. + /// + /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. + unlock: func() -> result<_, error-code>; - /// Test whether two descriptors refer to the same filesystem object. - /// - /// In POSIX, this corresponds to testing whether the two descriptors have the - /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. - /// wasi-filesystem does not expose device and inode numbers, so this function - /// may be used instead. - is-same-object: func(this: descriptor, other: descriptor) -> bool - - /// Return a hash of the metadata associated with a filesystem object referred - /// to by a descriptor. - /// - /// This returns a hash of the last-modification timestamp and file size, and - /// may also include the inode number, device number, birth timestamp, and - /// other metadata fields that may change when the file is modified or - /// replaced. It may also include a secret value chosen by the - /// implementation and not otherwise exposed. - /// - /// Implementations are encourated to provide the following properties: - /// - /// - If the file is not modified or replaced, the computed hash value should - /// usually not change. - /// - If the object is modified or replaced, the computed hash value should - /// usually change. - /// - The inputs to the hash should not be easily computable from the - /// computed hash. - /// - /// However, none of these is required. - metadata-hash: func( - this: descriptor, - ) -> result + /// Test whether two descriptors refer to the same filesystem object. + /// + /// In POSIX, this corresponds to testing whether the two descriptors have the + /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. + /// wasi-filesystem does not expose device and inode numbers, so this function + /// may be used instead. + is-same-object: func(other: borrow) -> bool; + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a descriptor. + /// + /// This returns a hash of the last-modification timestamp and file size, and + /// may also include the inode number, device number, birth timestamp, and + /// other metadata fields that may change when the file is modified or + /// replaced. It may also include a secret value chosen by the + /// implementation and not otherwise exposed. + /// + /// Implementations are encourated to provide the following properties: + /// + /// - If the file is not modified or replaced, the computed hash value should + /// usually not change. + /// - If the object is modified or replaced, the computed hash value should + /// usually change. + /// - The inputs to the hash should not be easily computable from the + /// computed hash. + /// + /// However, none of these is required. + metadata-hash: func() -> result; - /// Return a hash of the metadata associated with a filesystem object referred - /// to by a directory descriptor and a relative path. - /// - /// This performs the same hash computation as `metadata-hash`. - metadata-hash-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to inspect. - path: string, - ) -> result + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a directory descriptor and a relative path. + /// + /// This performs the same hash computation as `metadata-hash`. + metadata-hash-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result; + } + + /// A stream of directory entries. + resource directory-entry-stream { + /// Read a single directory entry from a `directory-entry-stream`. + read-directory-entry: func() -> result, error-code>; + } } diff --git a/proposals/http/wit/deps/filesystem/world.wit b/proposals/http/wit/deps/filesystem/world.wit index b51f484f8..bd472942d 100644 --- a/proposals/http/wit/deps/filesystem/world.wit +++ b/proposals/http/wit/deps/filesystem/world.wit @@ -1,6 +1,6 @@ -package wasi:filesystem +package wasi:filesystem; -world example-world { - import types - import preopens +world imports { + import types; + import preopens; } diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/io/poll.wit new file mode 100644 index 000000000..254f53418 --- /dev/null +++ b/proposals/http/wit/deps/io/poll.wit @@ -0,0 +1,34 @@ +package wasi:io; + +/// A poll API intended to let users wait for I/O events on multiple handles +/// at once. +interface poll { + /// A "pollable" handle. + resource pollable; + + /// Poll for completion on a set of pollables. + /// + /// This function takes a list of pollables, which identify I/O sources of + /// interest, and waits until one or more of the events is ready for I/O. + /// + /// The result `list` contains one or more indices of handles in the + /// argument list that is ready for I/O. + /// + /// If the list contains more elements than can be indexed with a `u32` + /// value, this function traps. + /// + /// A timeout can be implemented by adding a pollable from the + /// wasi-clocks API to the list. + /// + /// This function does not return a `result`; polling in itself does not + /// do any I/O so it doesn't fail. If any of the I/O sources identified by + /// the pollables has an error, it is indicated by marking the source as + /// being reaedy for I/O. + poll-list: func(in: list>) -> list; + + /// Poll for completion on a single pollable. + /// + /// This function is similar to `poll-list`, but operates on only a single + /// pollable. When it returns, the handle is ready for I/O. + poll-one: func(in: borrow); +} diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index de8694bda..cfeab0da1 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -1,14 +1,12 @@ +package wasi:io; + /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { - use wasi:poll/poll.{pollable} - - /// An error type returned from a stream operation. Currently this - /// doesn't provide any additional information. - record stream-error {} + use poll.{pollable}; /// Streams provide a sequence of data and then end; once they end, they /// no longer provide any further data. @@ -19,208 +17,269 @@ interface streams { enum stream-status { /// The stream is open and may produce further data. open, - /// The stream has ended and will not produce any further data. + /// When reading, this indicates that the stream will not produce + /// further data. + /// When writing, this indicates that the stream will no longer be read. + /// Further writes are still permitted. ended, } - /// An input bytestream. In the future, this will be replaced by handle - /// types. - /// - /// This conceptually represents a `stream`. It's temporary - /// scaffolding until component-model's async features are ready. + /// An input bytestream. /// /// `input-stream`s are *non-blocking* to the extent practical on underlying /// platforms. I/O operations always return promptly; if fewer bytes are /// promptly available than requested, they return the number of bytes promptly /// available, which could even be zero. To wait for data to be available, - /// use the `subscribe-to-input-stream` function to obtain a `pollable` which - /// can be polled for using `wasi_poll`. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type input-stream = u32 + /// use the `subscribe` function to obtain a `pollable` which can be polled + /// for using `wasi:io/poll`. + resource input-stream { + /// Perform a non-blocking read from the stream. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a `stream-status` which, indicates whether further + /// reads are expected to produce data. The returned list will contain up to + /// `len` bytes; it may return fewer than requested, but not more. An + /// empty list and `stream-status:open` indicates no more data is + /// available at this time, and that the pollable given by `subscribe` + /// will be ready when more data is available. + /// + /// Once a stream has reached the end, subsequent calls to `read` or + /// `skip` will always report `stream-status:ended` rather than producing more + /// data. + /// + /// When the caller gives a `len` of 0, it represents a request to read 0 + /// bytes. This read should always succeed and return an empty list and + /// the current `stream-status`. + /// + /// The `len` parameter is a `u64`, which could represent a list of u8 which + /// is not possible to allocate in wasm32, or not desirable to allocate as + /// as a return value by the callee. The callee may return a list of bytes + /// less than `len` in size while more bytes are available for reading. + read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-status>>; - /// Read bytes from a stream. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a `stream-status` which indicates whether the end of - /// the stream was reached. The returned list will contain up to `len` - /// bytes; it may return fewer than requested, but not more. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// If `len` is 0, it represents a request to read 0 bytes, which should - /// always succeed, assuming the stream hasn't reached its end yet, and - /// return an empty list. - /// - /// The len here is a `u64`, but some callees may not be able to allocate - /// a buffer as large as that would imply. - /// FIXME: describe what happens if allocation fails. - read: func( - this: input-stream, - /// The maximum number of bytes to read - len: u64 - ) -> result, stream-status>, stream-error> - - /// Read bytes from a stream, with blocking. - /// - /// This is similar to `read`, except that it blocks until at least one - /// byte can be read. - blocking-read: func( - this: input-stream, - /// The maximum number of bytes to read - len: u64 - ) -> result, stream-status>, stream-error> - - /// Skip bytes from a stream. - /// - /// This is similar to the `read` function, but avoids copying the - /// bytes into the instance. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// This function returns the number of bytes skipped, along with a - /// `stream-status` indicating whether the end of the stream was - /// reached. The returned value will be at most `len`; it may be less. - skip: func( - this: input-stream, - /// The maximum number of bytes to skip. - len: u64, - ) -> result, stream-error> - - /// Skip bytes from a stream, with blocking. - /// - /// This is similar to `skip`, except that it blocks until at least one - /// byte can be consumed. - blocking-skip: func( - this: input-stream, - /// The maximum number of bytes to skip. - len: u64, - ) -> result, stream-error> - - /// Create a `pollable` which will resolve once either the specified stream - /// has bytes available to read or the other end of the stream has been - /// closed. - subscribe-to-input-stream: func(this: input-stream) -> pollable - - /// Dispose of the specified `input-stream`, after which it may no longer - /// be used. - drop-input-stream: func(this: input-stream) - - /// An output bytestream. In the future, this will be replaced by handle - /// types. + /// Read bytes from a stream, after blocking until at least one byte can + /// be read. Except for blocking, identical to `read`. + blocking-read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-status>>; + + /// Skip bytes from a stream. + /// + /// This is similar to the `read` function, but avoids copying the + /// bytes into the instance. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// This function returns the number of bytes skipped, along with a + /// `stream-status` indicating whether the end of the stream was + /// reached. The returned value will be at most `len`; it may be less. + skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result>; + + /// Skip bytes from a stream, after blocking until at least one byte + /// can be skipped. Except for blocking behavior, identical to `skip`. + blocking-skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result>; + + /// Create a `pollable` which will resolve once either the specified stream + /// has bytes available to read or the other end of the stream has been + /// closed. + /// The created `pollable` is a child resource of the `input-stream`. + /// Implementations may trap if the `input-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe: func() -> pollable; + } + + /// An error for output-stream operations. /// - /// This conceptually represents a `stream`. It's temporary - /// scaffolding until component-model's async features are ready. + /// Contrary to input-streams, a closed output-stream is reported using + /// an error. + enum write-error { + /// The last operation (a write or flush) failed before completion. + last-operation-failed, + /// The stream is closed: no more input will be accepted by the + /// stream. A closed output-stream will return this error on all + /// future operations. + closed + } + + /// An output bytestream. /// /// `output-stream`s are *non-blocking* to the extent practical on /// underlying platforms. Except where specified otherwise, I/O operations also /// always return promptly, after the number of bytes that can be written /// promptly, which could even be zero. To wait for the stream to be ready to - /// accept data, the `subscribe-to-output-stream` function to obtain a - /// `pollable` which can be polled for using `wasi_poll`. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type output-stream = u32 + /// accept data, the `subscribe` function to obtain a `pollable` which can be + /// polled for using `wasi:io/poll`. + resource output-stream { + /// Check readiness for writing. This function never blocks. + /// + /// Returns the number of bytes permitted for the next call to `write`, + /// or an error. Calling `write` with more bytes than this function has + /// permitted will trap. + /// + /// When this function returns 0 bytes, the `subscribe` pollable will + /// become ready when this function will report at least 1 byte, or an + /// error. + check-write: func() -> result; - /// Write bytes to a stream. - /// - /// This function returns a `u64` indicating the number of bytes from - /// `buf` that were written; it may be less than the full list. - write: func( - this: output-stream, - /// Data to write - buf: list - ) -> result - - /// Write bytes to a stream, with blocking. - /// - /// This is similar to `write`, except that it blocks until at least one - /// byte can be written. - blocking-write: func( - this: output-stream, - /// Data to write - buf: list - ) -> result - - /// Write multiple zero bytes to a stream. - /// - /// This function returns a `u64` indicating the number of zero bytes - /// that were written; it may be less than `len`. - write-zeroes: func( - this: output-stream, - /// The number of zero bytes to write - len: u64 - ) -> result - - /// Write multiple zero bytes to a stream, with blocking. - /// - /// This is similar to `write-zeroes`, except that it blocks until at least - /// one byte can be written. - blocking-write-zeroes: func( - this: output-stream, - /// The number of zero bytes to write - len: u64 - ) -> result - - /// Read from one stream and write to another. - /// - /// This function returns the number of bytes transferred; it may be less - /// than `len`. - /// - /// Unlike other I/O functions, this function blocks until all the data - /// read from the input stream has been written to the output stream. - splice: func( - this: output-stream, - /// The stream to read from - src: input-stream, - /// The number of bytes to splice - len: u64, - ) -> result, stream-error> - - /// Read from one stream and write to another, with blocking. - /// - /// This is similar to `splice`, except that it blocks until at least - /// one byte can be read. - blocking-splice: func( - this: output-stream, - /// The stream to read from - src: input-stream, - /// The number of bytes to splice - len: u64, - ) -> result, stream-error> - - /// Forward the entire contents of an input stream to an output stream. - /// - /// This function repeatedly reads from the input stream and writes - /// the data to the output stream, until the end of the input stream - /// is reached, or an error is encountered. - /// - /// Unlike other I/O functions, this function blocks until the end - /// of the input stream is seen and all the data has been written to - /// the output stream. - /// - /// This function returns the number of bytes transferred. - forward: func( - this: output-stream, - /// The stream to read from - src: input-stream - ) -> result - - /// Create a `pollable` which will resolve once either the specified stream - /// is ready to accept bytes or the other end of the stream has been closed. - subscribe-to-output-stream: func(this: output-stream) -> pollable - - /// Dispose of the specified `output-stream`, after which it may no longer - /// be used. - drop-output-stream: func(this: output-stream) + /// Perform a write. This function never blocks. + /// + /// Precondition: check-write gave permit of Ok(n) and contents has a + /// length of less than or equal to n. Otherwise, this function will trap. + /// + /// returns Err(closed) without writing if the stream has closed since + /// the last call to check-write provided a permit. + write: func( + contents: list + ) -> result<_, write-error>; + + /// Perform a write of up to 4096 bytes, and then flush the stream. Block + /// until all of these operations are complete, or an error occurs. + /// + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe`, `write`, and `flush`, and is implemented with the + /// following pseudo-code: + /// + /// ```text + /// let pollable = this.subscribe(); + /// while !contents.is_empty() { + /// // Wait for the stream to become writable + /// poll-one(pollable); + /// let Ok(n) = this.check-write(); // eliding error handling + /// let len = min(n, contents.len()); + /// let (chunk, rest) = contents.split_at(len); + /// this.write(chunk ); // eliding error handling + /// contents = rest; + /// } + /// this.flush(); + /// // Wait for completion of `flush` + /// poll-one(pollable); + /// // Check for any errors that arose during `flush` + /// let _ = this.check-write(); // eliding error handling + /// ``` + blocking-write-and-flush: func( + contents: list + ) -> result<_, write-error>; + + /// Request to flush buffered output. This function never blocks. + /// + /// This tells the output-stream that the caller intends any buffered + /// output to be flushed. the output which is expected to be flushed + /// is all that has been passed to `write` prior to this call. + /// + /// Upon calling this function, the `output-stream` will not accept any + /// writes (`check-write` will return `ok(0)`) until the flush has + /// completed. The `subscribe` pollable will become ready when the + /// flush has completed and the stream can accept more writes. + flush: func() -> result<_, write-error>; + + /// Request to flush buffered output, and block until flush completes + /// and stream is ready for writing again. + blocking-flush: func() -> result<_, write-error>; + + /// Create a `pollable` which will resolve once the output-stream + /// is ready for more writing, or an error has occured. When this + /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an + /// error. + /// + /// If the stream is closed, this pollable is always ready immediately. + /// + /// The created `pollable` is a child resource of the `output-stream`. + /// Implementations may trap if the `output-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe: func() -> pollable; + + /// Write zeroes to a stream. + /// + /// this should be used precisely like `write` with the exact same + /// preconditions (must use check-write first), but instead of + /// passing a list of bytes, you simply pass the number of zero-bytes + /// that should be written. + write-zeroes: func( + /// The number of zero-bytes to write + len: u64 + ) -> result<_, write-error>; + + /// Perform a write of up to 4096 zeroes, and then flush the stream. + /// Block until all of these operations are complete, or an error + /// occurs. + /// + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with + /// the following pseudo-code: + /// + /// ```text + /// let pollable = this.subscribe(); + /// while num_zeroes != 0 { + /// // Wait for the stream to become writable + /// poll-one(pollable); + /// let Ok(n) = this.check-write(); // eliding error handling + /// let len = min(n, num_zeroes); + /// this.write-zeroes(len); // eliding error handling + /// num_zeroes -= len; + /// } + /// this.flush(); + /// // Wait for completion of `flush` + /// poll-one(pollable); + /// // Check for any errors that arose during `flush` + /// let _ = this.check-write(); // eliding error handling + /// ``` + blocking-write-zeroes-and-flush: func( + /// The number of zero-bytes to write + len: u64 + ) -> result<_, write-error>; + + /// Read from one stream and write to another. + /// + /// This function returns the number of bytes transferred; it may be less + /// than `len`. + /// + /// Unlike other I/O functions, this function blocks until all the data + /// read from the input stream has been written to the output stream. + splice: func( + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result>; + + /// Read from one stream and write to another, with blocking. + /// + /// This is similar to `splice`, except that it blocks until at least + /// one byte can be read. + blocking-splice: func( + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result>; + + /// Forward the entire contents of an input stream to an output stream. + /// + /// This function repeatedly reads from the input stream and writes + /// the data to the output stream, until the end of the input stream + /// is reached, or an error is encountered. + /// + /// Unlike other I/O functions, this function blocks until the end + /// of the input stream is seen and all the data has been written to + /// the output stream. + /// + /// This function returns the number of bytes transferred, and the status of + /// the output stream. + forward: func( + /// The stream to read from + src: input-stream + ) -> result>; + } } diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit index b7f625334..05244a965 100644 --- a/proposals/http/wit/deps/io/world.wit +++ b/proposals/http/wit/deps/io/world.wit @@ -1,5 +1,6 @@ -package wasi:io +package wasi:io; -world example-world { - import streams +world imports { + import streams; + import poll; } diff --git a/proposals/http/wit/deps/poll/poll.wit b/proposals/http/wit/deps/poll/poll.wit deleted file mode 100644 index fa82b6063..000000000 --- a/proposals/http/wit/deps/poll/poll.wit +++ /dev/null @@ -1,49 +0,0 @@ -/// A poll API intended to let users wait for I/O events on multiple handles -/// at once. -interface poll { - /// A "pollable" handle. - /// - /// This is conceptually represents a `stream<_, _>`, or in other words, - /// a stream that one can wait on, repeatedly, but which does not itself - /// produce any data. It's temporary scaffolding until component-model's - /// async features are ready. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// `pollable` lifetimes are not automatically managed. Users must ensure - /// that they do not outlive the resource they reference. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type pollable = u32 - - /// Dispose of the specified `pollable`, after which it may no longer - /// be used. - drop-pollable: func(this: pollable) - - /// Poll for completion on a set of pollables. - /// - /// This function takes a list of pollables, which identify I/O sources of - /// interest, and waits until one or more of the events is ready for I/O. - /// - /// The result `list` is the same length as the argument - /// `list`, and indicates the readiness of each corresponding - /// element in that list, with true indicating ready. A single call can - /// return multiple true elements. - /// - /// A timeout can be implemented by adding a pollable from the - /// wasi-clocks API to the list. - /// - /// This function does not return a `result`; polling in itself does not - /// do any I/O so it doesn't fail. If any of the I/O sources identified by - /// the pollables has an error, it is indicated by marking the source as - /// ready in the `list`. - /// - /// The "oneoff" in the name refers to the fact that this function must do a - /// linear scan through the entire list of subscriptions, which may be - /// inefficient if the number is large and the same subscriptions are used - /// many times. In the future, this is expected to be obsoleted by the - /// component model async proposal, which will include a scalable waiting - /// facility. - poll-oneoff: func(in: list) -> list -} diff --git a/proposals/http/wit/deps/poll/world.wit b/proposals/http/wit/deps/poll/world.wit deleted file mode 100644 index d08cadc05..000000000 --- a/proposals/http/wit/deps/poll/world.wit +++ /dev/null @@ -1,5 +0,0 @@ -package wasi:poll - -world example-world { - import poll -} diff --git a/proposals/http/wit/deps/random/insecure-seed.wit b/proposals/http/wit/deps/random/insecure-seed.wit index ff2ff65d0..139aed159 100644 --- a/proposals/http/wit/deps/random/insecure-seed.wit +++ b/proposals/http/wit/deps/random/insecure-seed.wit @@ -20,5 +20,5 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - insecure-seed: func() -> tuple + insecure-seed: func() -> tuple; } diff --git a/proposals/http/wit/deps/random/insecure.wit b/proposals/http/wit/deps/random/insecure.wit index ff0826822..2ffd223cb 100644 --- a/proposals/http/wit/deps/random/insecure.wit +++ b/proposals/http/wit/deps/random/insecure.wit @@ -11,11 +11,11 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - get-insecure-random-bytes: func(len: u64) -> list + get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - get-insecure-random-u64: func() -> u64 + get-insecure-random-u64: func() -> u64; } diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index 2a282dab7..2c3c6a859 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -15,11 +15,11 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - get-random-bytes: func(len: u64) -> list + get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - get-random-u64: func() -> u64 + get-random-u64: func() -> u64; } diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit index 3c3d16554..bb1dd7b59 100644 --- a/proposals/http/wit/deps/random/world.wit +++ b/proposals/http/wit/deps/random/world.wit @@ -1,7 +1,7 @@ -package wasi:random +package wasi:random; -world example-world { - import random - import insecure - import insecure-seed +world imports { + import random; + import insecure; + import insecure-seed; } diff --git a/proposals/http/wit/deps/sockets/instance-network.wit b/proposals/http/wit/deps/sockets/instance-network.wit index d911a29cc..14e4479e6 100644 --- a/proposals/http/wit/deps/sockets/instance-network.wit +++ b/proposals/http/wit/deps/sockets/instance-network.wit @@ -1,9 +1,9 @@ /// This interface provides a value-export of the default network handle.. interface instance-network { - use network.{network} + use network.{network}; /// Get a handle to the default network. - instance-network: func() -> network + instance-network: func() -> network; } diff --git a/proposals/http/wit/deps/sockets/ip-name-lookup.wit b/proposals/http/wit/deps/sockets/ip-name-lookup.wit index f15d19d03..b51fe05e5 100644 --- a/proposals/http/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ interface ip-name-lookup { - use wasi:poll/poll.{pollable} - use network.{network, error-code, ip-address, ip-address-family} + use wasi:io/poll.{pollable}; + use network.{network, error-code, ip-address, ip-address-family}; /// Resolve an internet host name to a list of IP addresses. @@ -34,36 +34,28 @@ interface ip-name-lookup { /// - /// - /// - - resolve-addresses: func(network: network, name: string, address-family: option, include-unavailable: bool) -> result - - - - type resolve-address-stream = u32 - - /// Returns the next address from the resolver. - /// - /// This function should be called multiple times. On each call, it will - /// return the next address in connection order preference. If all - /// addresses have been exhausted, this function returns `none`. - /// After which, you should release the stream with `drop-resolve-address-stream`. - /// - /// This function never returns IPv4-mapped IPv6 addresses. - /// - /// # Typical errors - /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) - /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) - /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) - /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) - resolve-next-address: func(this: resolve-address-stream) -> result, error-code> - - /// Dispose of the specified `resolve-address-stream`, after which it may no longer be used. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-resolve-address-stream: func(this: resolve-address-stream) - - /// Create a `pollable` which will resolve once the stream is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func(this: resolve-address-stream) -> pollable + resolve-addresses: func(network: borrow, name: string, address-family: option, include-unavailable: bool) -> result; + + resource resolve-address-stream { + /// Returns the next address from the resolver. + /// + /// This function should be called multiple times. On each call, it will + /// return the next address in connection order preference. If all + /// addresses have been exhausted, this function returns `none`. + /// + /// This function never returns IPv4-mapped IPv6 addresses. + /// + /// # Typical errors + /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) + /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) + /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) + /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) + resolve-next-address: func() -> result, error-code>; + + /// Create a `pollable` which will resolve once the stream is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } } diff --git a/proposals/http/wit/deps/sockets/network.wit b/proposals/http/wit/deps/sockets/network.wit index 2d09bcbdc..e2695954b 100644 --- a/proposals/http/wit/deps/sockets/network.wit +++ b/proposals/http/wit/deps/sockets/network.wit @@ -1,17 +1,9 @@ interface network { - /// An opaque resource that represents access to (a subset of) the network. + /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. - /// - /// FYI, In the future this will be replaced by handle types. - type network = u32 - - /// Dispose of the specified `network`, after which it may no longer be used. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-network: func(this: network) - + resource network; /// Error codes. /// @@ -158,8 +150,8 @@ interface network { ipv6, } - type ipv4-address = tuple - type ipv6-address = tuple + type ipv4-address = tuple; + type ipv6-address = tuple; variant ip-address { ipv4(ipv4-address), @@ -183,4 +175,4 @@ interface network { ipv6(ipv6-socket-address), } -} \ No newline at end of file +} diff --git a/proposals/http/wit/deps/sockets/tcp-create-socket.wit b/proposals/http/wit/deps/sockets/tcp-create-socket.wit index f43bc8979..056bbef33 100644 --- a/proposals/http/wit/deps/sockets/tcp-create-socket.wit +++ b/proposals/http/wit/deps/sockets/tcp-create-socket.wit @@ -1,7 +1,7 @@ interface tcp-create-socket { - use network.{network, error-code, ip-address-family} - use tcp.{tcp-socket} + use network.{network, error-code, ip-address-family}; + use tcp.{tcp-socket}; /// Create a new TCP socket. /// @@ -23,5 +23,5 @@ interface tcp-create-socket { /// - /// - /// - - create-tcp-socket: func(address-family: ip-address-family) -> result + create-tcp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index 4edb1db7f..fea44380d 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -1,12 +1,8 @@ interface tcp { - use wasi:io/streams.{input-stream, output-stream} - use wasi:poll/poll.{pollable} - use network.{network, error-code, ip-socket-address, ip-address-family} - - /// A TCP socket handle. - type tcp-socket = u32 - + use wasi:io/streams.{input-stream, output-stream}; + use wasi:io/poll.{pollable}; + use network.{network, error-code, ip-socket-address, ip-address-family}; enum shutdown-type { /// Similar to `SHUT_RD` in POSIX. @@ -20,238 +16,234 @@ interface tcp { } - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will - /// implicitly bind the socket. - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) - /// - `already-bound`: The socket is already bound. (EINVAL) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> - finish-bind: func(this: tcp-socket) -> result<_, error-code> - - /// Connect to a remote endpoint. - /// - /// On success: - /// - the socket is transitioned into the Connection state - /// - a pair of streams is returned that can be used to read & write to the connection - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) - /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `already-connected`: The socket is already in the Connection state. (EISCONN) - /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `timeout`: Connection timed out. (ETIMEDOUT) - /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) - /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> - finish-connect: func(this: tcp-socket) -> result, error-code> - - /// Start listening for new connections. - /// - /// Transitions the socket into the Listener state. - /// - /// Unlike POSIX: - /// - this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - the socket must already be explicitly bound. - /// - /// # Typical `start` errors - /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) - /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) - /// - `already-listening`: The socket is already in the Listener state. - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - `not-in-progress`: A `listen` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-listen: func(this: tcp-socket) -> result<_, error-code> - finish-listen: func(this: tcp-socket) -> result<_, error-code> - - /// Accept a new client socket. - /// - /// The returned socket is bound and in the Connection state. - /// - /// On success, this function returns the newly accepted client socket along with - /// a pair of streams that can be used to read & write to the connection. - /// - /// # Typical errors - /// - `not-listening`: Socket is not in the Listener state. (EINVAL) - /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) - /// - /// Host implementations must skip over transient errors returned by the native accept syscall. - /// - /// # References - /// - - /// - - /// - - /// - - accept: func(this: tcp-socket) -> result, error-code> - - /// Get the bound local address. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - local-address: func(this: tcp-socket) -> result - - /// Get the bound remote address. - /// - /// # Typical errors - /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - remote-address: func(this: tcp-socket) -> result - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: tcp-socket) -> ip-address-family + /// A TCP socket handle. + resource tcp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will + /// implicitly bind the socket. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) + /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + finish-bind: func() -> result<_, error-code>; + + /// Connect to a remote endpoint. + /// + /// On success: + /// - the socket is transitioned into the Connection state + /// - a pair of streams is returned that can be used to read & write to the connection + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `already-connected`: The socket is already in the Connection state. (EISCONN) + /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + finish-connect: func() -> result, error-code>; + + /// Start listening for new connections. + /// + /// Transitions the socket into the Listener state. + /// + /// Unlike POSIX: + /// - this function is async. This enables interactive WASI hosts to inject permission prompts. + /// - the socket must already be explicitly bound. + /// + /// # Typical `start` errors + /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) + /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) + /// - `already-listening`: The socket is already in the Listener state. + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// - `not-in-progress`: A `listen` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-listen: func() -> result<_, error-code>; + finish-listen: func() -> result<_, error-code>; + + /// Accept a new client socket. + /// + /// The returned socket is bound and in the Connection state. + /// + /// On success, this function returns the newly accepted client socket along with + /// a pair of streams that can be used to read & write to the connection. + /// + /// # Typical errors + /// - `not-listening`: Socket is not in the Listener state. (EINVAL) + /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) + /// + /// Host implementations must skip over transient errors returned by the native accept syscall. + /// + /// # References + /// - + /// - + /// - + /// - + accept: func() -> result, error-code>; + + /// Get the bound local address. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func() -> result; + + /// Get the bound remote address. + /// + /// # Typical errors + /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func() -> result; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family; - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. - /// - `already-bound`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - ipv6-only: func(this: tcp-socket) -> result - set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error-code> - - /// Hints the desired listen queue size. Implementations are free to ignore this. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error-code> - - /// Equivalent to the SO_KEEPALIVE socket option. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - keep-alive: func(this: tcp-socket) -> result - set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error-code> - - /// Equivalent to the TCP_NODELAY socket option. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - no-delay: func(this: tcp-socket) -> result - set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error-code> + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// # Typical errors + /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. + /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + ipv6-only: func() -> result; + set-ipv6-only: func(value: bool) -> result<_, error-code>; + + /// Hints the desired listen queue size. Implementations are free to ignore this. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + set-listen-backlog-size: func(value: u64) -> result<_, error-code>; + + /// Equivalent to the SO_KEEPALIVE socket option. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + keep-alive: func() -> result; + set-keep-alive: func(value: bool) -> result<_, error-code>; + + /// Equivalent to the TCP_NODELAY socket option. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + no-delay: func() -> result; + set-no-delay: func(value: bool) -> result<_, error-code>; - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `already-listening`: (set) The socket is already in the Listener state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - unicast-hop-limit: func(this: tcp-socket) -> result - set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error-code> - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `already-listening`: (set) The socket is already in the Listener state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - receive-buffer-size: func(this: tcp-socket) -> result - set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> - send-buffer-size: func(this: tcp-socket) -> result - set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> - - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func(this: tcp-socket) -> pollable - - /// Initiate a graceful shutdown. - /// - /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read - /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. - /// Any data still in the receive queue at time of calling `shutdown` will be discarded. - /// - send: the socket is not expecting to send any more data to the peer. All subsequent write - /// operations on the `output-stream` associated with this socket will return an error. - /// - both: same effect as receive & send combined. - /// - /// The shutdown function does not close (drop) the socket. - /// - /// # Typical errors - /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error-code> - - /// Dispose of the specified `tcp-socket`, after which it may no longer be used. - /// - /// Similar to the POSIX `close` function. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-tcp-socket: func(this: tcp-socket) + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `already-listening`: (set) The socket is already in the Listener state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + unicast-hop-limit: func() -> result; + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `already-listening`: (set) The socket is already in the Listener state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + receive-buffer-size: func() -> result; + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + send-buffer-size: func() -> result; + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + + /// Initiate a graceful shutdown. + /// + /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read + /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. + /// Any data still in the receive queue at time of calling `shutdown` will be discarded. + /// - send: the socket is not expecting to send any more data to the peer. All subsequent write + /// operations on the `output-stream` associated with this socket will return an error. + /// - both: same effect as receive & send combined. + /// + /// The shutdown function does not close (drop) the socket. + /// + /// # Typical errors + /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; + } } diff --git a/proposals/http/wit/deps/sockets/udp-create-socket.wit b/proposals/http/wit/deps/sockets/udp-create-socket.wit index cd4c08fb1..66f948226 100644 --- a/proposals/http/wit/deps/sockets/udp-create-socket.wit +++ b/proposals/http/wit/deps/sockets/udp-create-socket.wit @@ -1,7 +1,7 @@ interface udp-create-socket { - use network.{network, error-code, ip-address-family} - use udp.{udp-socket} + use network.{network, error-code, ip-address-family}; + use udp.{udp-socket}; /// Create a new UDP socket. /// @@ -23,5 +23,5 @@ interface udp-create-socket { /// - /// - /// - - create-udp-socket: func(address-family: ip-address-family) -> result + create-udp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index 948ed581a..e20b57e7e 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -1,11 +1,7 @@ interface udp { - use wasi:poll/poll.{pollable} - use network.{network, error-code, ip-socket-address, ip-address-family} - - - /// A UDP socket handle. - type udp-socket = u32 + use wasi:io/poll.{pollable}; + use network.{network, error-code, ip-socket-address, ip-address-family}; record datagram { @@ -22,201 +18,197 @@ interface udp { - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) - /// - `already-bound`: The socket is already bound. (EINVAL) - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> - finish-bind: func(this: udp-socket) -> result<_, error-code> - - /// Set the destination address. - /// - /// The local-address is updated based on the best network path to `remote-address`. - /// - /// When a destination address is set: - /// - all receive operations will only return datagrams sent from the provided `remote-address`. - /// - the `send` function can only be used to send to this destination. - /// - /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> - finish-connect: func(this: udp-socket) -> result<_, error-code> - - /// Receive messages on the socket. - /// - /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. - /// The returned list may contain fewer elements than requested, but never more. - /// If `max-results` is 0, this function returns successfully with an empty list. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. (EINVAL) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - receive: func(this: udp-socket, max-results: u64) -> result, error-code> - - /// Send messages on the socket. - /// - /// This function attempts to send all provided `datagrams` on the socket without blocking and - /// returns how many messages were actually sent (or queued for sending). - /// - /// This function semantically behaves the same as iterating the `datagrams` list and sequentially - /// sending each individual datagram until either the end of the list has been reached or the first error occurred. - /// If at least one datagram has been sent successfully, this function never returns an error. - /// - /// If the input list is empty, the function returns `ok(0)`. - /// - /// The remote address option is required. To send a message to the "connected" peer, - /// call `remote-address` to get their address. - /// - /// # Typical errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN) - /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. - /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) - /// - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - send: func(this: udp-socket, datagrams: list) -> result - - /// Get the current bound address. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - local-address: func(this: udp-socket) -> result - - /// Get the address set with `connect`. - /// - /// # Typical errors - /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - remote-address: func(this: udp-socket) -> result - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: udp-socket) -> ip-address-family - - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. - /// - `already-bound`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - ipv6-only: func(this: udp-socket) -> result - set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error-code> - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - unicast-hop-limit: func(this: udp-socket) -> result - set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error-code> - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. - /// - /// Fails when this socket is in the Listening state. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - receive-buffer-size: func(this: udp-socket) -> result - set-receive-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> - send-buffer-size: func(this: udp-socket) -> result - set-send-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> - - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func(this: udp-socket) -> pollable - - /// Dispose of the specified `udp-socket`, after which it may no longer be used. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-udp-socket: func(this: udp-socket) + /// A UDP socket handle. + resource udp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) + /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + finish-bind: func() -> result<_, error-code>; + + /// Set the destination address. + /// + /// The local-address is updated based on the best network path to `remote-address`. + /// + /// When a destination address is set: + /// - all receive operations will only return datagrams sent from the provided `remote-address`. + /// - the `send` function can only be used to send to this destination. + /// + /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + finish-connect: func() -> result<_, error-code>; + + /// Receive messages on the socket. + /// + /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. + /// The returned list may contain fewer elements than requested, but never more. + /// If `max-results` is 0, this function returns successfully with an empty list. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. (EINVAL) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + receive: func(max-results: u64) -> result, error-code>; + + /// Send messages on the socket. + /// + /// This function attempts to send all provided `datagrams` on the socket without blocking and + /// returns how many messages were actually sent (or queued for sending). + /// + /// This function semantically behaves the same as iterating the `datagrams` list and sequentially + /// sending each individual datagram until either the end of the list has been reached or the first error occurred. + /// If at least one datagram has been sent successfully, this function never returns an error. + /// + /// If the input list is empty, the function returns `ok(0)`. + /// + /// The remote address option is required. To send a message to the "connected" peer, + /// call `remote-address` to get their address. + /// + /// # Typical errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN) + /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. + /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + send: func(datagrams: list) -> result; + + /// Get the current bound address. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func() -> result; + + /// Get the address set with `connect`. + /// + /// # Typical errors + /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func() -> result; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family; + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// # Typical errors + /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. + /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + ipv6-only: func() -> result; + set-ipv6-only: func(value: bool) -> result<_, error-code>; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + unicast-hop-limit: func() -> result; + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + receive-buffer-size: func() -> result; + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + send-buffer-size: func() -> result; + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } } diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit index ca23d8698..432b0dc99 100644 --- a/proposals/http/wit/deps/sockets/world.wit +++ b/proposals/http/wit/deps/sockets/world.wit @@ -1,11 +1,11 @@ -package wasi:sockets +package wasi:sockets; -world example-world { - import instance-network - import network - import udp - import udp-create-socket - import tcp - import tcp-create-socket - import ip-name-lookup +world imports { + import instance-network; + import network; + import udp; + import udp-create-socket; + import tcp; + import tcp-create-socket; + import ip-name-lookup; } From baa83133c312ef47e9272dd3a77f07a66076b3dd Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:51:29 -0700 Subject: [PATCH 1240/1772] CI: require wit-abi-up-to-date@v16 --- proposals/http/.github/workflows/main.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index e460515f8..cb189df77 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -16,7 +16,4 @@ jobs: curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.2/wit-deps-x86_64-unknown-linux-musl chmod +x ./wit-deps ./wit-deps lock --check - - - uses: WebAssembly/wit-abi-up-to-date@v13 - with: - wit-abi-tag: wit-abi-0.11.0 + - uses: WebAssembly/wit-abi-up-to-date@v16 From 2d52ead95b6bd5e2b63152472099d1b42af967e9 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:53:55 -0700 Subject: [PATCH 1241/1772] wit: add semicolons as statement separators --- proposals/http/wit/handler.wit | 8 +-- proposals/http/wit/proxy.wit | 20 +++--- proposals/http/wit/types.wit | 110 ++++++++++++++++----------------- 3 files changed, 69 insertions(+), 69 deletions(-) diff --git a/proposals/http/wit/handler.wit b/proposals/http/wit/handler.wit index e547a955c..372921ecd 100644 --- a/proposals/http/wit/handler.wit +++ b/proposals/http/wit/handler.wit @@ -7,7 +7,7 @@ // that takes a `request` parameter and returns a `response` result. // interface incoming-handler { - use types.{incoming-request, response-outparam} + use types.{incoming-request, response-outparam}; // The `handle` function takes an outparam instead of returning its response // so that the component may stream its response while streaming any other @@ -22,7 +22,7 @@ interface incoming-handler { handle: func( request: incoming-request, response-out: response-outparam - ) + ); } // The `wasi:http/outgoing-handler` interface is meant to be imported by @@ -33,7 +33,7 @@ interface incoming-handler { // that takes a `request` parameter and returns a `response` result. // interface outgoing-handler { - use types.{outgoing-request, request-options, future-incoming-response} + use types.{outgoing-request, request-options, future-incoming-response}; // The parameter and result types of the `handle` function allow the caller // to concurrently stream the bodies of the outgoing request and the incoming @@ -41,5 +41,5 @@ interface outgoing-handler { handle: func( request: outgoing-request, options: option - ) -> future-incoming-response + ) -> future-incoming-response; } diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 162ab32b2..8ee589207 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,4 +1,4 @@ -package wasi:http +package wasi:http; // The `wasi:http/proxy` world captures a widely-implementable intersection of // hosts that includes HTTP forward and reverse proxies. Components targeting @@ -6,29 +6,29 @@ package wasi:http // outgoing HTTP requests. world proxy { // HTTP proxies have access to time and randomness. - import wasi:clocks/wall-clock - import wasi:clocks/monotonic-clock - import wasi:clocks/timezone - import wasi:random/random + import wasi:clocks/wall-clock; + import wasi:clocks/monotonic-clock; + import wasi:clocks/timezone; + import wasi:random/random; // Proxies have standard output and error streams which are expected to // terminate in a developer-facing console provided by the host. - import wasi:cli/stdout - import wasi:cli/stderr + import wasi:cli/stdout; + import wasi:cli/stderr; // TODO: this is a temporary workaround until component tooling is able to // gracefully handle the absence of stdin. Hosts must return an eof stream // for this import, which is what wasi-libc + tooling will do automatically // when this import is properly removed. - import wasi:cli/stdin + import wasi:cli/stdin; // This is the default handler to use when user code simply wants to make an // HTTP request (e.g., via `fetch()`). - import outgoing-handler + import outgoing-handler; // The host delivers incoming HTTP requests to a component by calling the // `handle` function of this exported interface. A host may arbitrarily reuse // or not reuse component instance when delivering incoming HTTP requests and // thus a component must be able to handle 0..N calls to `handle`. - export incoming-handler + export incoming-handler; } diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 4f77f238c..36702333c 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -2,8 +2,8 @@ // define the HTTP resource types and operations used by the component's // imported and exported interfaces. interface types { - use wasi:io/streams.{input-stream, output-stream} - use wasi:poll/poll.{pollable} + use wasi:io/streams.{input-stream, output-stream}; + use wasi:io/poll.{pollable}; // This type corresponds to HTTP standard Methods. variant method { @@ -40,19 +40,19 @@ interface types { // HTTP standard Fields. Soon, when resource types are added, the `type // fields = u32` type alias can be replaced by a proper `resource fields` // definition containing all the functions using the method syntactic sugar. - type fields = u32 - drop-fields: func(fields: fields) - new-fields: func(entries: list>>) -> fields + type fields = u32; + drop-fields: func(fields: fields); + new-fields: func(entries: list>>) -> fields; // Returns an empty list if `name` is not present. - fields-get: func(fields: fields, name: string) -> list> - fields-set: func(fields: fields, name: string, value: list>) - fields-delete: func(fields: fields, name: string) - fields-append: func(fields: fields, name: string, value: list) - fields-entries: func(fields: fields) -> list>> - fields-clone: func(fields: fields) -> fields + fields-get: func(fields: fields, name: string) -> list>; + fields-set: func(fields: fields, name: string, value: list>); + fields-delete: func(fields: fields, name: string); + fields-append: func(fields: fields, name: string, value: list); + fields-entries: func(fields: fields) -> list>>; + fields-clone: func(fields: fields) -> fields; - type headers = fields - type trailers = fields + type headers = fields; + type trailers = fields; // The following block defines stream types which corresponds to the HTTP // standard Contents and Trailers. With Preview3, all of these fields can be @@ -63,27 +63,27 @@ interface types { // the stream. The optional `future-` types describe the asynchronous result of // reading/writing the optional HTTP trailers and MUST be waited on and dropped // to complete streaming the request/response. - type incoming-stream = input-stream - type outgoing-stream = output-stream - finish-incoming-stream: func(s: incoming-stream) -> option - finish-outgoing-stream: func(s: outgoing-stream) - finish-outgoing-stream-with-trailers: func(s: outgoing-stream, trailers: trailers) -> future-write-trailers-result + type incoming-stream = input-stream; + type outgoing-stream = output-stream; + finish-incoming-stream: func(s: incoming-stream) -> option; + finish-outgoing-stream: func(s: outgoing-stream); + finish-outgoing-stream-with-trailers: func(s: outgoing-stream, trailers: trailers) -> future-write-trailers-result; // The following block defines the `future-trailers` resource, which is // returned when finishing an `incoming-stream` to asychronously produce the // final trailers. - type future-trailers = u32 - drop-future-trailers: func(f: future-trailers) - future-trailers-get: func(f: future-trailers) -> option> - listen-to-future-trailers: func(f: future-trailers) -> pollable + type future-trailers = u32; + drop-future-trailers: func(f: future-trailers); + future-trailers-get: func(f: future-trailers) -> option>; + listen-to-future-trailers: func(f: future-trailers) -> pollable; // The following block defines the `future-write-trailers-result` resource, // which is returned when finishing an `outgoing-stream` and asychronously // indicates the success or failure of writing the trailers. - type future-write-trailers-result = u32 - drop-future-write-trailers-result: func(f: future-write-trailers-result) - future-write-trailers-result-get: func(f: future-write-trailers-result) -> option> - listen-to-future-write-trailers-result: func(f: future-write-trailers-result) -> pollable + type future-write-trailers-result = u32; + drop-future-write-trailers-result: func(f: future-write-trailers-result); + future-write-trailers-result-get: func(f: future-write-trailers-result) -> option>; + listen-to-future-write-trailers-result: func(f: future-write-trailers-result) -> pollable; // The following block defines the `incoming-request` and `outgoing-request` // resource types that correspond to HTTP standard Requests. Soon, when @@ -102,24 +102,24 @@ interface types { // before dropping the request/response or passing ownership of the request/response // to the outside world. The caller can also call drop on the stream before the // request/response is dropped if they want to release resources earlier. - type incoming-request = u32 - type outgoing-request = u32 - drop-incoming-request: func(request: incoming-request) - drop-outgoing-request: func(request: outgoing-request) - incoming-request-method: func(request: incoming-request) -> method - incoming-request-path-with-query: func(request: incoming-request) -> option - incoming-request-scheme: func(request: incoming-request) -> option - incoming-request-authority: func(request: incoming-request) -> option - incoming-request-headers: func(request: incoming-request) -> headers - incoming-request-consume: func(request: incoming-request) -> result + type incoming-request = u32; + type outgoing-request = u32; + drop-incoming-request: func(request: incoming-request); + drop-outgoing-request: func(request: outgoing-request); + incoming-request-method: func(request: incoming-request) -> method; + incoming-request-path-with-query: func(request: incoming-request) -> option; + incoming-request-scheme: func(request: incoming-request) -> option; + incoming-request-authority: func(request: incoming-request) -> option; + incoming-request-headers: func(request: incoming-request) -> headers; + incoming-request-consume: func(request: incoming-request) -> result; new-outgoing-request: func( method: method, path-with-query: option, scheme: option, authority: option, headers: headers - ) -> result - outgoing-request-write: func(request: outgoing-request) -> result + ) -> result; + outgoing-request-write: func(request: outgoing-request) -> result; // Additional optional parameters that can be set when making a request. record request-options { @@ -143,12 +143,12 @@ interface types { // definition. Later, with Preview3, the need for an outparam goes away entirely // (the `wasi:http/handler` interface used for both incoming and outgoing can // simply return a `stream`). - type response-outparam = u32 - drop-response-outparam: func(response: response-outparam) - set-response-outparam: func(param: response-outparam, response: result) -> result + type response-outparam = u32; + drop-response-outparam: func(response: response-outparam); + set-response-outparam: func(param: response-outparam, response: result) -> result; // This type corresponds to the HTTP standard Status Code. - type status-code = u16 + type status-code = u16; // The following block defines the `incoming-response` and `outgoing-response` // resource types that correspond to HTTP standard Responses. Soon, when @@ -161,18 +161,18 @@ interface types { // with the response, with all mutations visible to all uses. Components MUST // avoid updating `headers` and `trailers` after passing a response that // points to them to the outside world. - type incoming-response = u32 - type outgoing-response = u32 - drop-incoming-response: func(response: incoming-response) - drop-outgoing-response: func(response: outgoing-response) - incoming-response-status: func(response: incoming-response) -> status-code - incoming-response-headers: func(response: incoming-response) -> headers - incoming-response-consume: func(response: incoming-response) -> result + type incoming-response = u32; + type outgoing-response = u32; + drop-incoming-response: func(response: incoming-response); + drop-outgoing-response: func(response: outgoing-response); + incoming-response-status: func(response: incoming-response) -> status-code; + incoming-response-headers: func(response: incoming-response) -> headers; + incoming-response-consume: func(response: incoming-response) -> result; new-outgoing-response: func( status-code: status-code, headers: headers - ) -> result - outgoing-response-write: func(response: outgoing-response) -> result + ) -> result; + outgoing-response-write: func(response: outgoing-response) -> result; // The following block defines a special resource type used by the // `wasi:http/outgoing-handler` interface to emulate @@ -181,8 +181,8 @@ interface types { // method to get the result if it is available. If the result is not available, // the client can call `listen` to get a `pollable` that can be passed to // `io.poll.poll-oneoff`. - type future-incoming-response = u32 - drop-future-incoming-response: func(f: future-incoming-response) - future-incoming-response-get: func(f: future-incoming-response) -> option> - listen-to-future-incoming-response: func(f: future-incoming-response) -> pollable + type future-incoming-response = u32; + drop-future-incoming-response: func(f: future-incoming-response); + future-incoming-response-get: func(f: future-incoming-response) -> option>; + listen-to-future-incoming-response: func(f: future-incoming-response) -> pollable; } From 01b7ba1d2e3ae1ca198146f96fd36925a6674cbd Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 16 Oct 2023 12:54:06 -0700 Subject: [PATCH 1242/1772] regenerate markdown --- proposals/http/proxy.md | 552 +++++++++++++++++++++------------------- 1 file changed, 295 insertions(+), 257 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index e0d0288d8..f1a14b01b 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -3,7 +3,7 @@
  • Imports: -

    Import interface wasi:poll/poll

    +

    Import interface wasi:io/poll

    A poll API intended to let users wait for I/O events on multiple handles at once.


    Types

    -

    type pollable

    -

    u32

    -

    A "pollable" handle. -

    This is conceptually represents a stream<_, _>, or in other words, -a stream that one can wait on, repeatedly, but which does not itself -produce any data. It's temporary scaffolding until component-model's -async features are ready.

    -

    And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

    -

    pollable lifetimes are not automatically managed. Users must ensure -that they do not outlive the resource they reference.

    -

    This represents a resource.

    +

    resource pollable


    Functions

    -

    drop-pollable: func

    -

    Dispose of the specified pollable, after which it may no longer -be used.

    -
    Params
    - -

    poll-oneoff: func

    +

    poll-list: func

    Poll for completion on a set of pollables.

    This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

    -

    The result list<bool> is the same length as the argument -list<pollable>, and indicates the readiness of each corresponding -element in that list, with true indicating ready. A single call can -return multiple true elements.

    +

    The result list<u32> contains one or more indices of handles in the +argument list that is ready for I/O.

    +

    If the list contains more elements than can be indexed with a u32 +value, this function traps.

    A timeout can be implemented by adding a pollable from the wasi-clocks API to the list.

    This function does not return a result; polling in itself does not do any I/O so it doesn't fail. If any of the I/O sources identified by the pollables has an error, it is indicated by marking the source as -ready in the list<bool>.

    -

    The "oneoff" in the name refers to the fact that this function must do a -linear scan through the entire list of subscriptions, which may be -inefficient if the number is large and the same subscriptions are used -many times. In the future, this is expected to be obsoleted by the -component model async proposal, which will include a scalable waiting -facility.

    +being reaedy for I/O.

    Params
    Return values
      -
    • list<bool>
    • +
    • list<u32>
    • +
    +

    poll-one: func

    +

    Poll for completion on a single pollable.

    +

    This function is similar to poll-list, but operates on only a single +pollable. When it returns, the handle is ready for I/O.

    +
    Params
    +

    Import interface wasi:clocks/monotonic-clock

    WASI Monotonic Clock is a clock API intended to let users measure elapsed @@ -158,7 +142,7 @@ reached.

    Return values

    Import interface wasi:clocks/timezone


    @@ -168,7 +152,7 @@ reached.

    #### `record timezone-display`

    Information useful for displaying the timezone of a specific datetime.

    -

    This information may vary within a single timezone to reflect daylight +

    This information may vary within a single timezone to reflect daylight saving time adjustments.

    Record Fields
      @@ -198,13 +182,6 @@ representation of the UTC offset may be returned, such as -04:00.
    -

    type timezone

    -

    u32

    -

    A timezone. -

    In timezones that recognize daylight saving time, also known as daylight -time and summer time, the information returned from the functions varies -over time to reflect these adjustments.

    -

    This represents a resource.


    Functions

    display: func

    @@ -216,7 +193,6 @@ daylight saving time is active.

    saving time.

    Params
    Return values
    @@ -227,20 +203,12 @@ saving time.

    The same as display, but only return the UTC offset.

    Params
    Return values
    • s32
    -

    drop-timezone: func

    -

    Dispose of the specified input-stream, after which it may no longer -be used.

    -
    Params
    -

    Import interface wasi:random/random

    WASI Random is a random data API.

    It is intended to be portable at least between Unix-family platforms and @@ -298,186 +266,273 @@ socket ends when the socket is closed.

  • ended

    -

    The stream has ended and will not produce any further data. +

    When reading, this indicates that the stream will not produce +further data. +When writing, this indicates that the stream will no longer be read. +Further writes are still permitted.

  • -

    record stream-error

    -

    An error type returned from a stream operation. Currently this -doesn't provide any additional information.

    -
    Record Fields
    -

    type output-stream

    -

    u32

    -

    An output bytestream. In the future, this will be replaced by handle -types. -

    This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

    -

    output-streams are non-blocking to the extent practical on -underlying platforms. Except where specified otherwise, I/O operations also -always return promptly, after the number of bytes that can be written -promptly, which could even be zero. To wait for the stream to be ready to -accept data, the subscribe-to-output-stream function to obtain a -pollable which can be polled for using wasi_poll.

    -

    And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

    -

    This represents a resource.

    -

    type input-stream

    -

    u32

    -

    An input bytestream. In the future, this will be replaced by handle -types. -

    This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

    -

    input-streams are non-blocking to the extent practical on underlying -platforms. I/O operations always return promptly; if fewer bytes are -promptly available than requested, they return the number of bytes promptly -available, which could even be zero. To wait for data to be available, -use the subscribe-to-input-stream function to obtain a pollable which -can be polled for using wasi_poll.

    -

    And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

    -

    This represents a resource.

    +

    resource input-stream

    +

    enum write-error

    +

    An error for output-stream operations.

    +

    Contrary to input-streams, a closed output-stream is reported using +an error.

    +
    Enum Cases
    +
      +
    • +

      last-operation-failed

      +

      The last operation (a write or flush) failed before completion. +

    • +
    • +

      closed

      +

      The stream is closed: no more input will be accepted by the +stream. A closed output-stream will return this error on all +future operations. +

    • +
    +

    resource output-stream


    Functions

    -

    read: func

    -

    Read bytes from a stream.

    +

    [method]input-stream.read: func

    +

    Perform a non-blocking read from the stream.

    This function returns a list of bytes containing the data that was -read, along with a stream-status which indicates whether the end of -the stream was reached. The returned list will contain up to len -bytes; it may return fewer than requested, but not more.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more +read, along with a stream-status which, indicates whether further +reads are expected to produce data. The returned list will contain up to +len bytes; it may return fewer than requested, but not more. An +empty list and stream-status:open indicates no more data is +available at this time, and that the pollable given by subscribe +will be ready when more data is available.

    +

    Once a stream has reached the end, subsequent calls to read or +skip will always report stream-status:ended rather than producing more data.

    -

    If len is 0, it represents a request to read 0 bytes, which should -always succeed, assuming the stream hasn't reached its end yet, and -return an empty list.

    -

    The len here is a u64, but some callees may not be able to allocate -a buffer as large as that would imply. -FIXME: describe what happens if allocation fails.

    +

    When the caller gives a len of 0, it represents a request to read 0 +bytes. This read should always succeed and return an empty list and +the current stream-status.

    +

    The len parameter is a u64, which could represent a list of u8 which +is not possible to allocate in wasm32, or not desirable to allocate as +as a return value by the callee. The callee may return a list of bytes +less than len in size while more bytes are available for reading.

    Params
    Return values
    -

    blocking-read: func

    -

    Read bytes from a stream, with blocking.

    -

    This is similar to read, except that it blocks until at least one -byte can be read.

    +

    [method]input-stream.blocking-read: func

    +

    Read bytes from a stream, after blocking until at least one byte can +be read. Except for blocking, identical to read.

    Params
    Return values
    -

    skip: func

    +

    [method]input-stream.skip: func

    Skip bytes from a stream.

    -

    This is similar to the read function, but avoids copying the +

    This is similar to the read function, but avoids copying the bytes into the instance.

    Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more +skip will always report end-of-stream rather than producing more data.

    This function returns the number of bytes skipped, along with a stream-status indicating whether the end of the stream was reached. The returned value will be at most len; it may be less.

    Params
    Return values
    -

    blocking-skip: func

    -

    Skip bytes from a stream, with blocking.

    -

    This is similar to skip, except that it blocks until at least one -byte can be consumed.

    +

    [method]input-stream.blocking-skip: func

    +

    Skip bytes from a stream, after blocking until at least one byte +can be skipped. Except for blocking behavior, identical to skip.

    Params
    Return values
    -

    subscribe-to-input-stream: func

    +

    [method]input-stream.subscribe: func

    Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been -closed.

    +closed. +The created pollable is a child resource of the input-stream. +Implementations may trap if the input-stream is dropped before +all derived pollables created with this function are dropped.

    Params
    Return values
    -

    drop-input-stream: func

    -

    Dispose of the specified input-stream, after which it may no longer -be used.

    +

    [method]output-stream.check-write: func

    +

    Check readiness for writing. This function never blocks.

    +

    Returns the number of bytes permitted for the next call to write, +or an error. Calling write with more bytes than this function has +permitted will trap.

    +

    When this function returns 0 bytes, the subscribe pollable will +become ready when this function will report at least 1 byte, or an +error.

    Params
    +
    Return values
    + -

    write: func

    -

    Write bytes to a stream.

    -

    This function returns a u64 indicating the number of bytes from -buf that were written; it may be less than the full list.

    +

    [method]output-stream.write: func

    +

    Perform a write. This function never blocks.

    +

    Precondition: check-write gave permit of Ok(n) and contents has a +length of less than or equal to n. Otherwise, this function will trap.

    +

    returns Err(closed) without writing if the stream has closed since +the last call to check-write provided a permit.

    Params
    Return values
    +

    [method]output-stream.blocking-write-and-flush: func

    +

    Perform a write of up to 4096 bytes, and then flush the stream. Block +until all of these operations are complete, or an error occurs.

    +

    This is a convenience wrapper around the use of check-write, +subscribe, write, and flush, and is implemented with the +following pseudo-code:

    +
    let pollable = this.subscribe();
    +while !contents.is_empty() {
    +  // Wait for the stream to become writable
    +  poll-one(pollable);
    +  let Ok(n) = this.check-write(); // eliding error handling
    +  let len = min(n, contents.len());
    +  let (chunk, rest) = contents.split_at(len);
    +  this.write(chunk  );            // eliding error handling
    +  contents = rest;
    +}
    +this.flush();
    +// Wait for completion of `flush`
    +poll-one(pollable);
    +// Check for any errors that arose during `flush`
    +let _ = this.check-write();         // eliding error handling
    +
    +
    Params
    + -

    blocking-write: func

    -

    Write bytes to a stream, with blocking.

    -

    This is similar to write, except that it blocks until at least one -byte can be written.

    +
    Return values
    + +

    [method]output-stream.flush: func

    +

    Request to flush buffered output. This function never blocks.

    +

    This tells the output-stream that the caller intends any buffered +output to be flushed. the output which is expected to be flushed +is all that has been passed to write prior to this call.

    +

    Upon calling this function, the output-stream will not accept any +writes (check-write will return ok(0)) until the flush has +completed. The subscribe pollable will become ready when the +flush has completed and the stream can accept more writes.

    Params
    Return values
    -

    write-zeroes: func

    -

    Write multiple zero bytes to a stream.

    -

    This function returns a u64 indicating the number of zero bytes -that were written; it may be less than len.

    +

    [method]output-stream.blocking-flush: func

    +

    Request to flush buffered output, and block until flush completes +and stream is ready for writing again.

    Params
    Return values
    +

    [method]output-stream.subscribe: func

    +

    Create a pollable which will resolve once the output-stream +is ready for more writing, or an error has occured. When this +pollable is ready, check-write will return ok(n) with n>0, or an +error.

    +

    If the stream is closed, this pollable is always ready immediately.

    +

    The created pollable is a child resource of the output-stream. +Implementations may trap if the output-stream is dropped before +all derived pollables created with this function are dropped.

    +
    Params
    + -

    blocking-write-zeroes: func

    -

    Write multiple zero bytes to a stream, with blocking.

    -

    This is similar to write-zeroes, except that it blocks until at least -one byte can be written.

    +
    Return values
    + +

    [method]output-stream.write-zeroes: func

    +

    Write zeroes to a stream.

    +

    this should be used precisely like write with the exact same +preconditions (must use check-write first), but instead of +passing a list of bytes, you simply pass the number of zero-bytes +that should be written.

    Params
    Return values
    +

    [method]output-stream.blocking-write-zeroes-and-flush: func

    +

    Perform a write of up to 4096 zeroes, and then flush the stream. +Block until all of these operations are complete, or an error +occurs.

    +

    This is a convenience wrapper around the use of check-write, +subscribe, write-zeroes, and flush, and is implemented with +the following pseudo-code:

    +
    let pollable = this.subscribe();
    +while num_zeroes != 0 {
    +  // Wait for the stream to become writable
    +  poll-one(pollable);
    +  let Ok(n) = this.check-write(); // eliding error handling
    +  let len = min(n, num_zeroes);
    +  this.write-zeroes(len);         // eliding error handling
    +  num_zeroes -= len;
    +}
    +this.flush();
    +// Wait for completion of `flush`
    +poll-one(pollable);
    +// Check for any errors that arose during `flush`
    +let _ = this.check-write();         // eliding error handling
    +
    +
    Params
    + -

    splice: func

    +
    Return values
    + +

    [method]output-stream.splice: func

    Read from one stream and write to another.

    This function returns the number of bytes transferred; it may be less than len.

    @@ -485,29 +540,29 @@ than len.

    read from the input stream has been written to the output stream.

    Params
    Return values
    -

    blocking-splice: func

    +

    [method]output-stream.blocking-splice: func

    Read from one stream and write to another, with blocking.

    -

    This is similar to splice, except that it blocks until at least +

    This is similar to splice, except that it blocks until at least one byte can be read.

    Params
    Return values
    -

    forward: func

    +

    [method]output-stream.forward: func

    Forward the entire contents of an input stream to an output stream.

    This function repeatedly reads from the input stream and writes the data to the output stream, until the end of the input stream @@ -515,33 +570,16 @@ is reached, or an error is encountered.

    Unlike other I/O functions, this function blocks until the end of the input stream is seen and all the data has been written to the output stream.

    -

    This function returns the number of bytes transferred.

    -
    Params
    - -
    Return values
    - -

    subscribe-to-output-stream: func

    -

    Create a pollable which will resolve once either the specified stream -is ready to accept bytes or the other end of the stream has been closed.

    +

    This function returns the number of bytes transferred, and the status of +the output stream.

    Params
    Return values
    -

    drop-output-stream: func

    -

    Dispose of the specified output-stream, after which it may no longer -be used.

    -
    Params
    -

    Import interface wasi:cli/stdout


    @@ -554,7 +592,7 @@ be used.

    get-stdout: func

    Return values

    Import interface wasi:cli/stderr


    @@ -567,7 +605,7 @@ be used.

    get-stderr: func

    Return values

    Import interface wasi:cli/stdin


    @@ -580,7 +618,7 @@ be used.

    get-stdin: func

    Return values

    Import interface wasi:http/types


    @@ -594,35 +632,6 @@ be used.

    #### `type pollable` [`pollable`](#pollable)

    -#### `type status-code` -`u16` -

    -#### `variant scheme` -

    Variant Cases
    - -

    type response-outparam

    -

    u32

    -

    -#### `record request-options` -

    Record Fields
    - -

    type outgoing-stream

    -

    output-stream

    -

    -#### `type outgoing-response` -`u32` -

    -#### `type outgoing-request` -`u32` -

    #### `variant method`

    Variant Cases
      @@ -637,42 +646,71 @@ be used.

    • patch
    • other: string
    -

    type incoming-stream

    -

    input-stream

    +

    variant scheme

    +
    Variant Cases
    + +

    variant error

    +
    Variant Cases
    + +

    type fields

    +

    u32

    -#### `type incoming-response` -`u32` +#### `type headers` +[`fields`](#fields)

    -#### `type incoming-request` +#### `type trailers` +[`fields`](#fields) +

    +#### `type incoming-stream` +[`input-stream`](#input_stream) +

    +#### `type outgoing-stream` +[`output-stream`](#output_stream) +

    +#### `type future-trailers` `u32`

    #### `type future-write-trailers-result` `u32`

    -#### `type future-trailers` +#### `type incoming-request` `u32`

    -#### `type future-incoming-response` +#### `type outgoing-request` `u32`

    -#### `type fields` +#### `record request-options` +

    Record Fields
    + +

    type response-outparam

    +

    u32

    +

    +#### `type status-code` +`u16` +

    +#### `type incoming-response` `u32`

    -#### `type trailers` -[`fields`](#fields) +#### `type outgoing-response` +`u32`

    -#### `type headers` -[`fields`](#fields) +#### `type future-incoming-response` +`u32`

    -#### `variant error` -

    Variant Cases
    - -
    +----

    Functions

    drop-fields: func

    Params
    @@ -739,7 +777,7 @@ be used.

    finish-incoming-stream: func

    Params
    Return values
    Return values

    drop-future-write-trailers-result: func

    Params
    @@ -804,7 +842,7 @@ be used.

    Return values

    drop-incoming-request: func

    Params
    @@ -868,7 +906,7 @@ be used.

    Return values

    new-outgoing-request: func

    Params
    @@ -890,7 +928,7 @@ be used.

    Return values

    drop-response-outparam: func

    Params
    @@ -942,7 +980,7 @@ be used.

    Return values

    new-outgoing-response: func

    Params
    @@ -961,7 +999,7 @@ be used.

    Return values

    drop-future-incoming-response: func

    Params
    @@ -984,7 +1022,7 @@ be used.

    Return values

    Import interface wasi:http/outgoing-handler


    From b591a003d7a2de6c718a699bef797a361b8e4ed2 Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Fri, 6 Oct 2023 15:40:41 -0700 Subject: [PATCH 1243/1772] Use resources, and restructure body handling --- proposals/http/wit/handler.wit | 18 +-- proposals/http/wit/types.wit | 245 ++++++++++++++++++--------------- 2 files changed, 144 insertions(+), 119 deletions(-) diff --git a/proposals/http/wit/handler.wit b/proposals/http/wit/handler.wit index 372921ecd..3140d8c86 100644 --- a/proposals/http/wit/handler.wit +++ b/proposals/http/wit/handler.wit @@ -12,13 +12,11 @@ interface incoming-handler { // The `handle` function takes an outparam instead of returning its response // so that the component may stream its response while streaming any other // request or response bodies. The callee MUST write a response to the - // `response-out` and then finish the response before returning. The caller - // is expected to start streaming the response once `set-response-outparam` - // is called and finish streaming the response when `drop-response-outparam` - // is called. The `handle` function is then allowed to continue executing - // any post-response logic before returning. While this post-response - // execution is taken off the critical path, since there is no return value, - // there is no way to report its success or failure. + // `response-outparam` and then finish the response before returning. The `handle` + // function is allowed to continue execution after finishing the response's + // output stream. While this post-response execution is taken off the + // critical path, since there is no return value, there is no way to report + // its success or failure. handle: func( request: incoming-request, response-out: response-outparam @@ -33,13 +31,15 @@ interface incoming-handler { // that takes a `request` parameter and returns a `response` result. // interface outgoing-handler { - use types.{outgoing-request, request-options, future-incoming-response}; + use types.{outgoing-request, request-options, future-incoming-response, error}; // The parameter and result types of the `handle` function allow the caller // to concurrently stream the bodies of the outgoing request and the incoming // response. + // Consumes the outgoing-request. Gives an error if the outgoing-request + // is invalid or cannot be satisfied by this handler. handle: func( request: outgoing-request, options: option - ) -> future-incoming-response; + ) -> result; } diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 36702333c..c1e4ae14f 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -4,7 +4,7 @@ interface types { use wasi:io/streams.{input-stream, output-stream}; use wasi:io/poll.{pollable}; - + // This type corresponds to HTTP standard Methods. variant method { get, @@ -30,101 +30,84 @@ interface types { // This type enumerates the different kinds of errors that may occur when // initially returning a response. variant error { - invalid-url(string), - timeout-error(string), - protocol-error(string), - unexpected-error(string) + invalid-url(string), + timeout-error(string), + protocol-error(string), + unexpected-error(string) } // This following block defines the `fields` resource which corresponds to // HTTP standard Fields. Soon, when resource types are added, the `type // fields = u32` type alias can be replaced by a proper `resource fields` // definition containing all the functions using the method syntactic sugar. - type fields = u32; - drop-fields: func(fields: fields); - new-fields: func(entries: list>>) -> fields; - // Returns an empty list if `name` is not present. - fields-get: func(fields: fields, name: string) -> list>; - fields-set: func(fields: fields, name: string, value: list>); - fields-delete: func(fields: fields, name: string); - fields-append: func(fields: fields, name: string, value: list); - fields-entries: func(fields: fields) -> list>>; - fields-clone: func(fields: fields) -> fields; + resource fields { + // Multiple values for a header are multiple entries in the list with the + // same key. + constructor(entries: list>>); + + // Values off wire are not necessarily well formed, so they are given by + // list instead of string. + get: func(name: string) -> list>; + + // Values off wire are not necessarily well formed, so they are given by + // list instead of string. + set: func(name: string, value: list>); + delete: func(name: string); + append: func(name: string, value: list); + + // Values off wire are not necessarily well formed, so they are given by + // list instead of string. + entries: func() -> list>>; + + // Deep copy of all contents in a fields. + clone: func() -> fields; + } type headers = fields; type trailers = fields; - // The following block defines stream types which corresponds to the HTTP - // standard Contents and Trailers. With Preview3, all of these fields can be - // replaced by a stream>. In the interim, we need to - // build on separate resource types defined by `wasi:io/streams`. The - // `finish-` functions emulate the stream's result value and MUST be called - // exactly once after the final read/write from/to the stream before dropping - // the stream. The optional `future-` types describe the asynchronous result of - // reading/writing the optional HTTP trailers and MUST be waited on and dropped - // to complete streaming the request/response. - type incoming-stream = input-stream; - type outgoing-stream = output-stream; - finish-incoming-stream: func(s: incoming-stream) -> option; - finish-outgoing-stream: func(s: outgoing-stream); - finish-outgoing-stream-with-trailers: func(s: outgoing-stream, trailers: trailers) -> future-write-trailers-result; - - // The following block defines the `future-trailers` resource, which is - // returned when finishing an `incoming-stream` to asychronously produce the - // final trailers. - type future-trailers = u32; - drop-future-trailers: func(f: future-trailers); - future-trailers-get: func(f: future-trailers) -> option>; - listen-to-future-trailers: func(f: future-trailers) -> pollable; - - // The following block defines the `future-write-trailers-result` resource, - // which is returned when finishing an `outgoing-stream` and asychronously - // indicates the success or failure of writing the trailers. - type future-write-trailers-result = u32; - drop-future-write-trailers-result: func(f: future-write-trailers-result); - future-write-trailers-result-get: func(f: future-write-trailers-result) -> option>; - listen-to-future-write-trailers-result: func(f: future-write-trailers-result) -> pollable; - // The following block defines the `incoming-request` and `outgoing-request` // resource types that correspond to HTTP standard Requests. Soon, when - // resource types are added, the `u32` type aliases can be replaced by proper - // `resource` type definitions containing all the functions as methods. - // Later, Preview2 will allow both types to be merged together into a single - // `request` type (that uses the single `stream` type mentioned above). The - // `consume` and `write` methods may only be called once (and return failure - // thereafter). The `headers` and `trailers` passed into and out of requests - // are shared with the request, with all mutations visible to all uses. - // Components MUST avoid updating `headers` and `trailers` after passing a - // request that points to them to the outside world. - // The streams returned by `consume` and `write` are owned by the request and - // response objects. The streams are destroyed when the request/response is - // dropped, thus a client MUST drop any handle referring to a request/response stream - // before dropping the request/response or passing ownership of the request/response - // to the outside world. The caller can also call drop on the stream before the - // request/response is dropped if they want to release resources earlier. - type incoming-request = u32; - type outgoing-request = u32; - drop-incoming-request: func(request: incoming-request); - drop-outgoing-request: func(request: outgoing-request); - incoming-request-method: func(request: incoming-request) -> method; - incoming-request-path-with-query: func(request: incoming-request) -> option; - incoming-request-scheme: func(request: incoming-request) -> option; - incoming-request-authority: func(request: incoming-request) -> option; - incoming-request-headers: func(request: incoming-request) -> headers; - incoming-request-consume: func(request: incoming-request) -> result; - new-outgoing-request: func( - method: method, - path-with-query: option, - scheme: option, - authority: option, - headers: headers - ) -> result; - outgoing-request-write: func(request: outgoing-request) -> result; + // resource types are added, the `u32` type aliases can be replaced by + // proper `resource` type definitions containing all the functions as + // methods. Later, Preview2 will allow both types to be merged together into + // a single `request` type (that uses the single `stream` type mentioned + // above). The `consume` and `write` methods may only be called once (and + // return failure thereafter). + resource incoming-request { + method: func() -> method; + + path-with-query: func() -> option; + + scheme: func() -> option; + + authority: func() -> option; + + headers: func() -> headers; + + // Will return the incoming-body child at most once. If called more than + // once, subsequent calls will return error. + consume: func() -> result; + } + + resource outgoing-request { + constructor( + method: method, + path-with-query: option, + scheme: option, + authority: option, + headers: borrow + ); + + // Will return the outgoing-body child at most once. If called more than + // once, subsequent calls will return error. + write: func() -> result; + } // Additional optional parameters that can be set when making a request. record request-options { // The following timeouts are specific to the HTTP protocol and work - // independently of the overall timeouts passed to `io.poll.poll-oneoff`. + // independently of the overall timeouts passed to `io.poll.poll-list`. // The timeout for the initial connect. connect-timeout-ms: option, @@ -143,9 +126,9 @@ interface types { // definition. Later, with Preview3, the need for an outparam goes away entirely // (the `wasi:http/handler` interface used for both incoming and outgoing can // simply return a `stream`). - type response-outparam = u32; - drop-response-outparam: func(response: response-outparam); - set-response-outparam: func(param: response-outparam, response: result) -> result; + resource response-outparam { + set: static func(param: response-outparam, response: result); + } // This type corresponds to the HTTP standard Status Code. type status-code = u16; @@ -157,32 +140,74 @@ interface types { // Preview2 will allow both types to be merged together into a single `response` // type (that uses the single `stream` type mentioned above). The `consume` and // `write` methods may only be called once (and return failure thereafter). - // The `headers` and `trailers` passed into and out of responses are shared - // with the response, with all mutations visible to all uses. Components MUST - // avoid updating `headers` and `trailers` after passing a response that - // points to them to the outside world. - type incoming-response = u32; - type outgoing-response = u32; - drop-incoming-response: func(response: incoming-response); - drop-outgoing-response: func(response: outgoing-response); - incoming-response-status: func(response: incoming-response) -> status-code; - incoming-response-headers: func(response: incoming-response) -> headers; - incoming-response-consume: func(response: incoming-response) -> result; - new-outgoing-response: func( - status-code: status-code, - headers: headers - ) -> result; - outgoing-response-write: func(response: outgoing-response) -> result; + resource incoming-response { + status: func() -> status-code; - // The following block defines a special resource type used by the - // `wasi:http/outgoing-handler` interface to emulate - // `future>` in advance of Preview3. Given a - // `future-incoming-response`, the client can call the non-blocking `get` - // method to get the result if it is available. If the result is not available, - // the client can call `listen` to get a `pollable` that can be passed to - // `io.poll.poll-oneoff`. - type future-incoming-response = u32; - drop-future-incoming-response: func(f: future-incoming-response); - future-incoming-response-get: func(f: future-incoming-response) -> option>; - listen-to-future-incoming-response: func(f: future-incoming-response) -> pollable; + headers: func() -> headers; + + // May be called at most once. returns error if called additional times. + // TODO: make incoming-request-consume work the same way, giving a child + // incoming-body. + consume: func() -> result; + } + + resource incoming-body { + // returned input-stream is a child - the implementation may trap if + // incoming-body is dropped (or consumed by call to + // incoming-body-finish) before the input-stream is dropped. + // May be called at most once. returns error if called additional times. + %stream: func() -> result; + + // takes ownership of incoming-body. this will trap if the + // incoming-body-stream child is still alive! + finish: static func(this: incoming-body) -> future-trailers; + } + + resource future-trailers { + /// Pollable that resolves when the body has been fully read, and the trailers + /// are ready to be consumed. + subscribe: func() -> pollable; + + /// Retrieve reference to trailers, if they are ready. + get: func() -> option>; + } + + resource outgoing-response { + constructor(status-code: status-code, headers: borrow); + + /// Will give the child outgoing-response at most once. subsequent calls will + /// return an error. + write: func() -> result; + } + + resource outgoing-body { + /// Will give the child output-stream at most once. subsequent calls will + /// return an error. + write: func() -> result; + + /// Finalize an outgoing body, optionally providing trailers. This must be + /// called to signal that the response is complete. If the `outgoing-body` is + /// dropped without calling `outgoing-body-finalize`, the implementation + /// should treat the body as corrupted. + finish: static func(this: outgoing-body, trailers: option); + } + + /// The following block defines a special resource type used by the + /// `wasi:http/outgoing-handler` interface to emulate + /// `future>` in advance of Preview3. Given a + /// `future-incoming-response`, the client can call the non-blocking `get` + /// method to get the result if it is available. If the result is not available, + /// the client can call `listen` to get a `pollable` that can be passed to + /// `wasi:io/poll.poll-list`. + resource future-incoming-response { + /// option indicates readiness. + /// outer result indicates you are allowed to get the + /// incoming-response-or-error at most once. subsequent calls after ready + /// will return an error here. + /// inner result indicates whether the incoming-response was available, or an + /// error occured. + get: func() -> option>>; + + subscribe: func() -> pollable; + } } From cf90351cdb8a45fced172ba9a2bd3cfae69287e7 Mon Sep 17 00:00:00 2001 From: Eduardo de Moura Rodrigues <16357187+eduardomourar@users.noreply.github.com> Date: Mon, 16 Oct 2023 23:40:40 +0200 Subject: [PATCH 1244/1772] chore: add w3c license to repository (#29) * chore: add apache 2.0 license to repository * chore: add w3c license to repository * chore: update license based on template --------- Co-authored-by: Eduardo Rodrigues --- proposals/io/LICENSE.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 proposals/io/LICENSE.md diff --git a/proposals/io/LICENSE.md b/proposals/io/LICENSE.md new file mode 100644 index 000000000..475309577 --- /dev/null +++ b/proposals/io/LICENSE.md @@ -0,0 +1,8 @@ +Copyright © 2019-2023 the Contributors to the WASI Specification, published +by the [WebAssembly Community Group][cg] under the +[W3C Community Contributor License Agreement (CLA)][cla]. A human-readable +[summary][summary] is available. + +[cg]: https://www.w3.org/community/webassembly/ +[cla]: https://www.w3.org/community/about/agreements/cla/ +[summary]: https://www.w3.org/community/about/agreements/cla-deed/ From c463fd52859fc284421461d76fb72c05e237a6bb Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Mon, 16 Oct 2023 15:34:06 -0700 Subject: [PATCH 1245/1772] Update markdown --- proposals/http/proxy.md | 331 ++++++++++++++++------------------------ 1 file changed, 135 insertions(+), 196 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index f1a14b01b..b32e44ae8 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -661,368 +661,304 @@ the output stream.

  • protocol-error: string
  • unexpected-error: string
  • -

    type fields

    -

    u32

    -

    -#### `type headers` -[`fields`](#fields) +

    resource fields

    +

    type headers

    +

    fields

    #### `type trailers` [`fields`](#fields)

    -#### `type incoming-stream` -[`input-stream`](#input_stream) -

    -#### `type outgoing-stream` -[`output-stream`](#output_stream) -

    -#### `type future-trailers` -`u32` -

    -#### `type future-write-trailers-result` -`u32` -

    -#### `type incoming-request` -`u32` -

    -#### `type outgoing-request` -`u32` -

    -#### `record request-options` +#### `resource incoming-request` +

    resource outgoing-request

    +

    record request-options

    Record Fields
    -

    type response-outparam

    -

    u32

    -

    -#### `type status-code` -`u16` -

    -#### `type incoming-response` -`u32` -

    -#### `type outgoing-response` -`u32` -

    -#### `type future-incoming-response` -`u32` +

    resource response-outparam

    +

    type status-code

    +

    u16

    ----- +#### `resource incoming-response` +

    resource incoming-body

    +

    resource future-trailers

    +

    resource outgoing-response

    +

    resource outgoing-body

    +

    resource future-incoming-response

    +

    Functions

    -

    drop-fields: func

    +

    [constructor]fields: func

    Params
    -

    new-fields: func

    -
    Params
    -
      -
    • entries: list<(string, list<u8>)>
    • +
    • entries: list<(string, list<u8>)>
    Return values
    -

    fields-get: func

    +

    [method]fields.get: func

    Params
    Return values
      -
    • list<list<u8>>
    • +
    • list<list<u8>>
    -

    fields-set: func

    +

    [method]fields.set: func

    Params
    -

    fields-delete: func

    +

    [method]fields.delete: func

    Params
    -

    fields-append: func

    +

    [method]fields.append: func

    Params
    -

    fields-entries: func

    +

    [method]fields.entries: func

    Params
    Return values
      -
    • list<(string, list<u8>)>
    • +
    • list<(string, list<u8>)>
    -

    fields-clone: func

    +

    [method]fields.clone: func

    Params
    Return values
    -

    finish-incoming-stream: func

    +

    [method]incoming-request.method: func

    Params
    Return values
    -

    finish-outgoing-stream: func

    +

    [method]incoming-request.path-with-query: func

    Params
    -

    finish-outgoing-stream-with-trailers: func

    -
    Params
    -
    Return values
    -

    drop-future-trailers: func

    -
    Params
    - -

    future-trailers-get: func

    +

    [method]incoming-request.scheme: func

    Params
    Return values
    -

    listen-to-future-trailers: func

    +

    [method]incoming-request.authority: func

    Params
    Return values
    -

    drop-future-write-trailers-result: func

    +

    [method]incoming-request.headers: func

    Params
    -

    future-write-trailers-result-get: func

    -
    Params
    - -
    Return values
    -
      -
    • option<result<_, error>>
    • -
    -

    listen-to-future-write-trailers-result: func

    -
    Params
    -
    Return values
    -

    drop-incoming-request: func

    -
    Params
    - -

    drop-outgoing-request: func

    -
    Params
    - -

    incoming-request-method: func

    +

    [method]incoming-request.consume: func

    Params
    Return values
    -

    incoming-request-path-with-query: func

    +

    [constructor]outgoing-request: func

    Params
    Return values
    -

    incoming-request-scheme: func

    +

    [method]outgoing-request.write: func

    Params
    Return values
    -

    incoming-request-authority: func

    +

    [static]response-outparam.set: func

    Params
    -
    Return values
    -
      -
    • option<string>
    • -
    -

    incoming-request-headers: func

    +

    [method]incoming-response.status: func

    Params
    Return values
    -

    incoming-request-consume: func

    +

    [method]incoming-response.headers: func

    Params
    Return values
    -

    new-outgoing-request: func

    +

    [method]incoming-response.consume: func

    Params
    Return values
    -

    outgoing-request-write: func

    +

    [method]incoming-body.stream: func

    Params
    Return values
    -

    drop-response-outparam: func

    +

    [static]incoming-body.finish: func

    Params
    -

    set-response-outparam: func

    -
    Params
    -
    Return values
    -

    drop-incoming-response: func

    +

    [method]future-trailers.subscribe: func

    +

    Pollable that resolves when the body has been fully read, and the trailers +are ready to be consumed.

    Params
    -

    drop-outgoing-response: func

    -
    Params
    - -

    incoming-response-status: func

    -
    Params
    -
    Return values
    -

    incoming-response-headers: func

    +

    [method]future-trailers.get: func

    +

    Retrieve reference to trailers, if they are ready.

    Params
    Return values
    -

    incoming-response-consume: func

    +

    [constructor]outgoing-response: func

    Params
    Return values
    -

    new-outgoing-response: func

    +

    [method]outgoing-response.write: func

    +

    Will give the child outgoing-response at most once. subsequent calls will +return an error.

    Params
    Return values
    -

    outgoing-response-write: func

    +

    [method]outgoing-body.write: func

    +

    Will give the child output-stream at most once. subsequent calls will +return an error.

    Params
    Return values
    -

    drop-future-incoming-response: func

    +

    [static]outgoing-body.finish: func

    +

    Finalize an outgoing body, optionally providing trailers. This must be +called to signal that the response is complete. If the outgoing-body is +dropped without calling outgoing-body-finalize, the implementation +should treat the body as corrupted.

    Params
    -

    future-incoming-response-get: func

    +

    [method]future-incoming-response.get: func

    +

    option indicates readiness. +outer result indicates you are allowed to get the +incoming-response-or-error at most once. subsequent calls after ready +will return an error here. +inner result indicates whether the incoming-response was available, or an +error occured.

    Params
    Return values
    -

    listen-to-future-incoming-response: func

    +

    [method]future-incoming-response.subscribe: func

    Params
    Return values

    Import interface wasi:http/outgoing-handler


    @@ -1036,17 +972,20 @@ the output stream.

    #### `type future-incoming-response` [`future-incoming-response`](#future_incoming_response)

    +#### `type error` +[`error`](#error) +

    ----

    Functions

    handle: func

    Params
    Return values

    Export interface wasi:http/incoming-handler


    @@ -1062,6 +1001,6 @@ the output stream.

    handle: func

    Params
    From b345ff3583d944f1cd9f515b0ddd5e57a88243fd Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Tue, 17 Oct 2023 10:15:53 -0700 Subject: [PATCH 1246/1772] Apply suggestions from code review Co-authored-by: Luke Wagner --- proposals/http/wit/types.wit | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index c1e4ae14f..c851ffe16 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -154,18 +154,17 @@ interface types { resource incoming-body { // returned input-stream is a child - the implementation may trap if // incoming-body is dropped (or consumed by call to - // incoming-body-finish) before the input-stream is dropped. - // May be called at most once. returns error if called additional times. + // incoming-body.finish) before the input-stream is dropped. + // May be called at most once. Returns error if called additional times. %stream: func() -> result; - // takes ownership of incoming-body. this will trap if the - // incoming-body-stream child is still alive! + // Takes ownership of incoming-body and will trap if the + // input-stream child is still alive. finish: static func(this: incoming-body) -> future-trailers; } resource future-trailers { - /// Pollable that resolves when the body has been fully read, and the trailers - /// are ready to be consumed. + /// Pollable that resolves when the the trailers are ready to be consumed. subscribe: func() -> pollable; /// Retrieve reference to trailers, if they are ready. @@ -187,7 +186,7 @@ interface types { /// Finalize an outgoing body, optionally providing trailers. This must be /// called to signal that the response is complete. If the `outgoing-body` is - /// dropped without calling `outgoing-body-finalize`, the implementation + /// dropped without calling `outgoing-body.finalize`, the implementation /// should treat the body as corrupted. finish: static func(this: outgoing-body, trailers: option); } @@ -200,12 +199,9 @@ interface types { /// the client can call `listen` to get a `pollable` that can be passed to /// `wasi:io/poll.poll-list`. resource future-incoming-response { - /// option indicates readiness. - /// outer result indicates you are allowed to get the - /// incoming-response-or-error at most once. subsequent calls after ready - /// will return an error here. - /// inner result indicates whether the incoming-response was available, or an - /// error occured. + /// The option indicates readiness. The outer result must return failure if `get` + /// is called after returning a non-empty result. The inner result indicates whether + /// the incoming response successfully started. get: func() -> option>>; subscribe: func() -> pollable; From 22adbb26319f20b441a328e658fdd74362604acb Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Tue, 17 Oct 2023 10:19:14 -0700 Subject: [PATCH 1247/1772] Make all comments into doc comments --- proposals/http/wit/types.wit | 118 ++++++++++++++++------------------- 1 file changed, 55 insertions(+), 63 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index c851ffe16..4d5a8e4b9 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -1,11 +1,11 @@ -// The `wasi:http/types` interface is meant to be imported by components to -// define the HTTP resource types and operations used by the component's -// imported and exported interfaces. +/// The `wasi:http/types` interface is meant to be imported by components to +/// define the HTTP resource types and operations used by the component's +/// imported and exported interfaces. interface types { use wasi:io/streams.{input-stream, output-stream}; use wasi:io/poll.{pollable}; - // This type corresponds to HTTP standard Methods. + /// This type corresponds to HTTP standard Methods. variant method { get, head, @@ -19,16 +19,16 @@ interface types { other(string) } - // This type corresponds to HTTP standard Related Schemes. + /// This type corresponds to HTTP standard Related Schemes. variant scheme { HTTP, HTTPS, other(string) } - // TODO: perhaps better align with HTTP semantics? - // This type enumerates the different kinds of errors that may occur when - // initially returning a response. + /// TODO: perhaps better align with HTTP semantics? + /// This type enumerates the different kinds of errors that may occur when + /// initially returning a response. variant error { invalid-url(string), timeout-error(string), @@ -36,44 +36,42 @@ interface types { unexpected-error(string) } - // This following block defines the `fields` resource which corresponds to - // HTTP standard Fields. Soon, when resource types are added, the `type - // fields = u32` type alias can be replaced by a proper `resource fields` - // definition containing all the functions using the method syntactic sugar. + /// This following block defines the `fields` resource which corresponds to + /// HTTP standard Fields. resource fields { - // Multiple values for a header are multiple entries in the list with the - // same key. + /// Multiple values for a header are multiple entries in the list with the + /// same key. constructor(entries: list>>); - // Values off wire are not necessarily well formed, so they are given by - // list instead of string. + /// Values off wire are not necessarily well formed, so they are given by + /// list instead of string. get: func(name: string) -> list>; - // Values off wire are not necessarily well formed, so they are given by - // list instead of string. + /// Values off wire are not necessarily well formed, so they are given by + /// list instead of string. set: func(name: string, value: list>); delete: func(name: string); append: func(name: string, value: list); - // Values off wire are not necessarily well formed, so they are given by - // list instead of string. + /// Values off wire are not necessarily well formed, so they are given by + /// list instead of string. entries: func() -> list>>; - // Deep copy of all contents in a fields. + /// Deep copy of all contents in a fields. clone: func() -> fields; } type headers = fields; type trailers = fields; - // The following block defines the `incoming-request` and `outgoing-request` - // resource types that correspond to HTTP standard Requests. Soon, when - // resource types are added, the `u32` type aliases can be replaced by - // proper `resource` type definitions containing all the functions as - // methods. Later, Preview2 will allow both types to be merged together into - // a single `request` type (that uses the single `stream` type mentioned - // above). The `consume` and `write` methods may only be called once (and - // return failure thereafter). + /// The following block defines the `incoming-request` and `outgoing-request` + /// resource types that correspond to HTTP standard Requests. Soon, when + /// resource types are added, the `u32` type aliases can be replaced by + /// proper `resource` type definitions containing all the functions as + /// methods. Later, Preview2 will allow both types to be merged together into + /// a single `request` type (that uses the single `stream` type mentioned + /// above). The `consume` and `write` methods may only be called once (and + /// return failure thereafter). resource incoming-request { method: func() -> method; @@ -85,8 +83,8 @@ interface types { headers: func() -> headers; - // Will return the incoming-body child at most once. If called more than - // once, subsequent calls will return error. + /// Will return the incoming-body child at most once. If called more than + /// once, subsequent calls will return error. consume: func() -> result; } @@ -99,67 +97,61 @@ interface types { headers: borrow ); - // Will return the outgoing-body child at most once. If called more than - // once, subsequent calls will return error. + /// Will return the outgoing-body child at most once. If called more than + /// once, subsequent calls will return error. write: func() -> result; } - // Additional optional parameters that can be set when making a request. + /// Additional optional parameters that can be set when making a request. record request-options { - // The following timeouts are specific to the HTTP protocol and work - // independently of the overall timeouts passed to `io.poll.poll-list`. + /// The following timeouts are specific to the HTTP protocol and work + /// independently of the overall timeouts passed to `io.poll.poll-list`. - // The timeout for the initial connect. + /// The timeout for the initial connect. connect-timeout-ms: option, - // The timeout for receiving the first byte of the response body. + /// The timeout for receiving the first byte of the response body. first-byte-timeout-ms: option, - // The timeout for receiving the next chunk of bytes in the response body - // stream. + /// The timeout for receiving the next chunk of bytes in the response body + /// stream. between-bytes-timeout-ms: option } - // The following block defines a special resource type used by the - // `wasi:http/incoming-handler` interface. When resource types are added, this - // block can be replaced by a proper `resource response-outparam { ... }` - // definition. Later, with Preview3, the need for an outparam goes away entirely - // (the `wasi:http/handler` interface used for both incoming and outgoing can - // simply return a `stream`). + /// The following block defines a special resource type used by the + /// `wasi:http/incoming-handler` interface. Later, with Preview3, the need for + /// an outparam goes away entirely (the `wasi:http/handler` interface used for + /// both incoming and outgoing can simply return a `stream`). resource response-outparam { set: static func(param: response-outparam, response: result); } - // This type corresponds to the HTTP standard Status Code. + /// This type corresponds to the HTTP standard Status Code. type status-code = u16; - // The following block defines the `incoming-response` and `outgoing-response` - // resource types that correspond to HTTP standard Responses. Soon, when - // resource types are added, the `u32` type aliases can be replaced by proper - // `resource` type definitions containing all the functions as methods. Later, - // Preview2 will allow both types to be merged together into a single `response` - // type (that uses the single `stream` type mentioned above). The `consume` and - // `write` methods may only be called once (and return failure thereafter). + /// The following block defines the `incoming-response` and `outgoing-response` + /// resource types that correspond to HTTP standard Responses. Later, Preview3 + /// will allow both types to be merged together into a single `response` type + /// (that uses the single `stream` type mentioned above). The `consume` and + /// `write` methods may only be called once (and return failure thereafter). resource incoming-response { status: func() -> status-code; headers: func() -> headers; - // May be called at most once. returns error if called additional times. - // TODO: make incoming-request-consume work the same way, giving a child - // incoming-body. + /// May be called at most once. returns error if called additional times. consume: func() -> result; } resource incoming-body { - // returned input-stream is a child - the implementation may trap if - // incoming-body is dropped (or consumed by call to - // incoming-body.finish) before the input-stream is dropped. - // May be called at most once. Returns error if called additional times. + /// returned input-stream is a child - the implementation may trap if + /// incoming-body is dropped (or consumed by call to + /// incoming-body.finish) before the input-stream is dropped. + /// May be called at most once. Returns error if called additional times. %stream: func() -> result; - // Takes ownership of incoming-body and will trap if the - // input-stream child is still alive. + /// Takes ownership of incoming-body and will trap if the + /// input-stream child is still alive. finish: static func(this: incoming-body) -> future-trailers; } From fb06e743eca3264a30c819718dc134f77067a16f Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Tue, 17 Oct 2023 10:20:35 -0700 Subject: [PATCH 1248/1772] Reflow lines to 80 cols --- proposals/http/proxy.md | 71 +++++++++++++++++++++++++++--------- proposals/http/wit/types.wit | 41 +++++++++++---------- 2 files changed, 76 insertions(+), 36 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index b32e44ae8..048821f48 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -621,6 +621,9 @@ the output stream.

  • own<input-stream>
  • Import interface wasi:http/types

    +

    The wasi:http/types interface is meant to be imported by components to +define the HTTP resource types and operations used by the component's +imported and exported interfaces.


    Types

    type input-stream

    @@ -633,6 +636,7 @@ the output stream.

    [`pollable`](#pollable)

    #### `variant method` +

    This type corresponds to HTTP standard Methods.

    Variant Cases
    • get
    • @@ -647,6 +651,7 @@ the output stream.

    • other: string

    variant scheme

    +

    This type corresponds to HTTP standard Related Schemes.

    Variant Cases
    • HTTP
    • @@ -654,6 +659,9 @@ the output stream.

    • other: string

    variant error

    +

    TODO: perhaps better align with HTTP semantics? +This type enumerates the different kinds of errors that may occur when +initially returning a response.

    Variant Cases
    • invalid-url: string
    • @@ -671,17 +679,30 @@ the output stream.

      #### `resource incoming-request`

      resource outgoing-request

      record request-options

      +

      Additional optional parameters that can be set when making a request.

      Record Fields

      resource response-outparam

      type status-code

      u16

      -

      -#### `resource incoming-response` +

      This type corresponds to the HTTP standard Status Code. +

      resource incoming-response

      resource incoming-body

      resource future-trailers

      resource outgoing-response

      @@ -690,6 +711,8 @@ the output stream.


      Functions

      [constructor]fields: func

      +

      Multiple values for a header are multiple entries in the list with the +same key.

      Params
      • entries: list<(string, list<u8>)>
      • @@ -699,6 +722,8 @@ the output stream.

      • own<fields>

      [method]fields.get: func

      +

      Values off wire are not necessarily well formed, so they are given by +list instead of string.

      Params
      • self: borrow<fields>
      • @@ -709,6 +734,8 @@ the output stream.

      • list<list<u8>>

      [method]fields.set: func

      +

      Values off wire are not necessarily well formed, so they are given by +list instead of string.

      Params
      • self: borrow<fields>
      • @@ -729,6 +756,8 @@ the output stream.

      • value: list<u8>

      [method]fields.entries: func

      +

      Values off wire are not necessarily well formed, so they are given by +list instead of string.

      Params
      • self: borrow<fields>
      • @@ -738,6 +767,7 @@ the output stream.

      • list<(string, list<u8>)>

      [method]fields.clone: func

      +

      Deep copy of all contents in a fields.

      Params

      [method]incoming-request.consume: func

      +

      Will return the incoming-body child at most once. If called more than +once, subsequent calls will return error.

      Params

      [method]outgoing-request.write: func

      +

      Will return the outgoing-body child at most once. If called more than +once, subsequent calls will return error.

      Params

      [method]incoming-response.consume: func

      +

      May be called at most once. returns error if called additional times.

      Params

      [method]incoming-body.stream: func

      +

      returned input-stream is a child - the implementation may trap if +incoming-body is dropped (or consumed by call to +incoming-body.finish) before the input-stream is dropped. +May be called at most once. Returns error if called additional times.

      Params

      [static]incoming-body.finish: func

      +

      Takes ownership of incoming-body and will trap if the +input-stream child is still alive.

      Params

      [method]future-trailers.subscribe: func

      -

      Pollable that resolves when the body has been fully read, and the trailers -are ready to be consumed.

      +

      Pollable that resolves when the the trailers are ready to be consumed.

      Params

      [method]outgoing-response.write: func

      -

      Will give the child outgoing-response at most once. subsequent calls will -return an error.

      +

      Will give the child outgoing-response at most once. subsequent calls +will return an error.

      Params

      [static]outgoing-body.finish: func

      Finalize an outgoing body, optionally providing trailers. This must be -called to signal that the response is complete. If the outgoing-body is -dropped without calling outgoing-body-finalize, the implementation +called to signal that the response is complete. If the outgoing-body +is dropped without calling outgoing-body.finalize, the implementation should treat the body as corrupted.

      Params
        @@ -937,12 +977,9 @@ should treat the body as corrupted.

      • trailers: option<own<trailers>>

      [method]future-incoming-response.get: func

      -

      option indicates readiness. -outer result indicates you are allowed to get the -incoming-response-or-error at most once. subsequent calls after ready -will return an error here. -inner result indicates whether the incoming-response was available, or an -error occured.

      +

      The option indicates readiness. The outer result must return failure if +get is called after returning a non-empty result. The inner result +indicates whether the incoming response successfully started.

      Params
      • self: borrow<future-incoming-response>
      • diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 4d5a8e4b9..b028fce17 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -123,17 +123,21 @@ interface types { /// an outparam goes away entirely (the `wasi:http/handler` interface used for /// both incoming and outgoing can simply return a `stream`). resource response-outparam { - set: static func(param: response-outparam, response: result); + set: static func( + param: response-outparam, + response: result, + ); } /// This type corresponds to the HTTP standard Status Code. type status-code = u16; - /// The following block defines the `incoming-response` and `outgoing-response` - /// resource types that correspond to HTTP standard Responses. Later, Preview3 - /// will allow both types to be merged together into a single `response` type - /// (that uses the single `stream` type mentioned above). The `consume` and - /// `write` methods may only be called once (and return failure thereafter). + /// The following block defines the `incoming-response` and + /// `outgoing-response` resource types that correspond to HTTP standard + /// Responses. Later, Preview3 will allow both types to be merged together + /// into a single `response` type (that uses the single `stream` type + /// mentioned above). The `consume` and `write` methods may only be called + /// once (and return failure thereafter). resource incoming-response { status: func() -> status-code; @@ -166,8 +170,8 @@ interface types { resource outgoing-response { constructor(status-code: status-code, headers: borrow); - /// Will give the child outgoing-response at most once. subsequent calls will - /// return an error. + /// Will give the child outgoing-response at most once. subsequent calls + /// will return an error. write: func() -> result; } @@ -177,23 +181,22 @@ interface types { write: func() -> result; /// Finalize an outgoing body, optionally providing trailers. This must be - /// called to signal that the response is complete. If the `outgoing-body` is - /// dropped without calling `outgoing-body.finalize`, the implementation + /// called to signal that the response is complete. If the `outgoing-body` + /// is dropped without calling `outgoing-body.finalize`, the implementation /// should treat the body as corrupted. finish: static func(this: outgoing-body, trailers: option); } /// The following block defines a special resource type used by the - /// `wasi:http/outgoing-handler` interface to emulate - /// `future>` in advance of Preview3. Given a - /// `future-incoming-response`, the client can call the non-blocking `get` - /// method to get the result if it is available. If the result is not available, - /// the client can call `listen` to get a `pollable` that can be passed to - /// `wasi:io/poll.poll-list`. + /// `wasi:http/outgoing-handler` interface to emulate `future>` in advance of Preview3. Given a `future-incoming-response`, the + /// client can call the non-blocking `get` method to get the result if it is + /// available. If the result is not available, the client can call `listen` to + /// get a `pollable` that can be passed to `wasi:io/poll.poll-list`. resource future-incoming-response { - /// The option indicates readiness. The outer result must return failure if `get` - /// is called after returning a non-empty result. The inner result indicates whether - /// the incoming response successfully started. + /// The option indicates readiness. The outer result must return failure if + /// `get` is called after returning a non-empty result. The inner result + /// indicates whether the incoming response successfully started. get: func() -> option>>; subscribe: func() -> pollable; From a2730daf83df90722a0294d11bd69beaccce6486 Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Tue, 17 Oct 2023 10:26:48 -0700 Subject: [PATCH 1249/1772] Fill out missing docs --- proposals/http/proxy.md | 13 +++++++++++++ proposals/http/wit/types.wit | 24 +++++++++++++++++------- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 048821f48..b3693b30a 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -777,6 +777,7 @@ list instead of string.

      • own<fields>

      [method]incoming-request.method: func

      +

      Returns the method of the incoming request.

      Params

      [method]incoming-request.path-with-query: func

      +

      Returns the path with query parameters from the request, as a string.

      Params

      [method]incoming-request.scheme: func

      +

      Returns the protocol scheme from the request.

      Params

      [method]incoming-request.authority: func

      +

      Returns the authority from the request, if it was present.

      Params

      [method]incoming-request.headers: func

      +

      Returns the headers from the request.

      Params

      [constructor]outgoing-request: func

      +

      Construct a new outgoing-request.

      Params

      [static]response-outparam.set: func

      +

      Set the value of the response-outparam to indicate either a response, +or an error.

      Params

      [method]incoming-response.status: func

      +

      Returns the status code from the incoming-response.

      Params

      [method]incoming-response.headers: func

      +

      Returns the headers from the incoming-response.

      Params

      [constructor]outgoing-response: func

      +

      Construct an outgoing-response.

      Params

      [method]future-incoming-response.subscribe: func

      +

      Pollable that resolves when the get method will resolve to a Some +result.

      Params
      • self: borrow<future-incoming-response>
      • diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index b028fce17..e58946421 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -65,22 +65,24 @@ interface types { type trailers = fields; /// The following block defines the `incoming-request` and `outgoing-request` - /// resource types that correspond to HTTP standard Requests. Soon, when - /// resource types are added, the `u32` type aliases can be replaced by - /// proper `resource` type definitions containing all the functions as - /// methods. Later, Preview2 will allow both types to be merged together into - /// a single `request` type (that uses the single `stream` type mentioned - /// above). The `consume` and `write` methods may only be called once (and - /// return failure thereafter). + /// resource types that correspond to HTTP standard Requests. Later, Preview3 + /// will allow both types to be merged together into a single `request` type + /// (that uses the single `stream` type mentioned above). The `consume` and + /// `write` methods may only be called once (and return failure thereafter). resource incoming-request { + /// Returns the method of the incoming request. method: func() -> method; + /// Returns the path with query parameters from the request, as a string. path-with-query: func() -> option; + /// Returns the protocol scheme from the request. scheme: func() -> option; + /// Returns the authority from the request, if it was present. authority: func() -> option; + /// Returns the headers from the request. headers: func() -> headers; /// Will return the incoming-body child at most once. If called more than @@ -89,6 +91,7 @@ interface types { } resource outgoing-request { + /// Construct a new `outgoing-request`. constructor( method: method, path-with-query: option, @@ -123,6 +126,8 @@ interface types { /// an outparam goes away entirely (the `wasi:http/handler` interface used for /// both incoming and outgoing can simply return a `stream`). resource response-outparam { + /// Set the value of the `response-outparam` to indicate either a response, + /// or an error. set: static func( param: response-outparam, response: result, @@ -139,8 +144,10 @@ interface types { /// mentioned above). The `consume` and `write` methods may only be called /// once (and return failure thereafter). resource incoming-response { + /// Returns the status code from the `incoming-response`. status: func() -> status-code; + /// Returns the headers from the `incoming-response`. headers: func() -> headers; /// May be called at most once. returns error if called additional times. @@ -168,6 +175,7 @@ interface types { } resource outgoing-response { + /// Construct an `outgoing-response`. constructor(status-code: status-code, headers: borrow); /// Will give the child outgoing-response at most once. subsequent calls @@ -199,6 +207,8 @@ interface types { /// indicates whether the incoming response successfully started. get: func() -> option>>; + /// Pollable that resolves when the `get` method will resolve to a `Some` + /// result. subscribe: func() -> pollable; } } From 5179e416b684df1f36a7990add015df0534a0240 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Oct 2023 14:03:26 -0700 Subject: [PATCH 1250/1772] handler.wit: convert all comments to doc-comments --- proposals/http/wit/handler.wit | 56 +++++++++++++++++----------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/proposals/http/wit/handler.wit b/proposals/http/wit/handler.wit index 3140d8c86..bdec50ea3 100644 --- a/proposals/http/wit/handler.wit +++ b/proposals/http/wit/handler.wit @@ -1,43 +1,43 @@ -// The `wasi:http/incoming-handler` interface is meant to be exported by -// components and called by the host in response to a new incoming HTTP -// response. -// -// NOTE: in Preview3, this interface will be merged with -// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface -// that takes a `request` parameter and returns a `response` result. -// +/// The `wasi:http/incoming-handler` interface is meant to be exported by +/// components and called by the host in response to a new incoming HTTP +/// response. +/// +/// NOTE: in Preview3, this interface will be merged with +/// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface +/// that takes a `request` parameter and returns a `response` result. +/// interface incoming-handler { use types.{incoming-request, response-outparam}; - // The `handle` function takes an outparam instead of returning its response - // so that the component may stream its response while streaming any other - // request or response bodies. The callee MUST write a response to the - // `response-outparam` and then finish the response before returning. The `handle` - // function is allowed to continue execution after finishing the response's - // output stream. While this post-response execution is taken off the - // critical path, since there is no return value, there is no way to report - // its success or failure. + /// The `handle` function takes an outparam instead of returning its response + /// so that the component may stream its response while streaming any other + /// request or response bodies. The callee MUST write a response to the + /// `response-out` and then finish the response before returning. The caller + /// is expected to start streaming the response once `set-response-outparam` + /// is called and finish streaming the response when `drop-response-outparam` + /// is called. The `handle` function is then allowed to continue executing + /// any post-response logic before returning. While this post-response + /// execution is taken off the critical path, since there is no return value, + /// there is no way to report its success or failure. handle: func( request: incoming-request, response-out: response-outparam ); } -// The `wasi:http/outgoing-handler` interface is meant to be imported by -// components and implemented by the host. -// -// NOTE: in Preview3, this interface will be merged with -// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface -// that takes a `request` parameter and returns a `response` result. -// +/// The `wasi:http/outgoing-handler` interface is meant to be imported by +/// components and implemented by the host. +/// +/// NOTE: in Preview3, this interface will be merged with +/// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface +/// that takes a `request` parameter and returns a `response` result. +/// interface outgoing-handler { use types.{outgoing-request, request-options, future-incoming-response, error}; - // The parameter and result types of the `handle` function allow the caller - // to concurrently stream the bodies of the outgoing request and the incoming - // response. - // Consumes the outgoing-request. Gives an error if the outgoing-request - // is invalid or cannot be satisfied by this handler. + /// The parameter and result types of the `handle` function allow the caller + /// to concurrently stream the bodies of the outgoing request and the incoming + /// response. handle: func( request: outgoing-request, options: option From 3b9c7100d5c76dcf3cab720ff2a05fd2f99d08d2 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Oct 2023 14:04:06 -0700 Subject: [PATCH 1251/1772] proxy.wit: make all comments doc comments --- proposals/http/wit/proxy.wit | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 8ee589207..557ab4597 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,34 +1,34 @@ package wasi:http; -// The `wasi:http/proxy` world captures a widely-implementable intersection of -// hosts that includes HTTP forward and reverse proxies. Components targeting -// this world may concurrently stream in and out any number of incoming and -// outgoing HTTP requests. +/// The `wasi:http/proxy` world captures a widely-implementable intersection of +/// hosts that includes HTTP forward and reverse proxies. Components targeting +/// this world may concurrently stream in and out any number of incoming and +/// outgoing HTTP requests. world proxy { - // HTTP proxies have access to time and randomness. + /// HTTP proxies have access to time and randomness. import wasi:clocks/wall-clock; import wasi:clocks/monotonic-clock; import wasi:clocks/timezone; import wasi:random/random; - // Proxies have standard output and error streams which are expected to - // terminate in a developer-facing console provided by the host. + /// Proxies have standard output and error streams which are expected to + /// terminate in a developer-facing console provided by the host. import wasi:cli/stdout; import wasi:cli/stderr; - // TODO: this is a temporary workaround until component tooling is able to - // gracefully handle the absence of stdin. Hosts must return an eof stream - // for this import, which is what wasi-libc + tooling will do automatically - // when this import is properly removed. + /// TODO: this is a temporary workaround until component tooling is able to + /// gracefully handle the absence of stdin. Hosts must return an eof stream + /// for this import, which is what wasi-libc + tooling will do automatically + /// when this import is properly removed. import wasi:cli/stdin; - // This is the default handler to use when user code simply wants to make an - // HTTP request (e.g., via `fetch()`). + /// This is the default handler to use when user code simply wants to make an + /// HTTP request (e.g., via `fetch()`). import outgoing-handler; - // The host delivers incoming HTTP requests to a component by calling the - // `handle` function of this exported interface. A host may arbitrarily reuse - // or not reuse component instance when delivering incoming HTTP requests and - // thus a component must be able to handle 0..N calls to `handle`. + /// The host delivers incoming HTTP requests to a component by calling the + /// `handle` function of this exported interface. A host may arbitrarily reuse + /// or not reuse component instance when delivering incoming HTTP requests and + /// thus a component must be able to handle 0..N calls to `handle`. export incoming-handler; } From 93059e7e750cac064af87a383b8d9c4c97abdeaf Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 17 Oct 2023 16:42:07 -0700 Subject: [PATCH 1252/1772] http types: elaborate takes the liberty of defining new type-aliases field-key and field-value, which make writing the docs a lot clearer Co-authored-by: Trevor Elliott --- proposals/http/wit/handler.wit | 52 +++---- proposals/http/wit/types.wit | 276 ++++++++++++++++++++++++--------- 2 files changed, 224 insertions(+), 104 deletions(-) diff --git a/proposals/http/wit/handler.wit b/proposals/http/wit/handler.wit index bdec50ea3..21b97a354 100644 --- a/proposals/http/wit/handler.wit +++ b/proposals/http/wit/handler.wit @@ -1,43 +1,39 @@ -/// The `wasi:http/incoming-handler` interface is meant to be exported by -/// components and called by the host in response to a new incoming HTTP -/// response. -/// -/// NOTE: in Preview3, this interface will be merged with -/// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface -/// that takes a `request` parameter and returns a `response` result. -/// +/// This interface defines a handler of incoming HTTP Requests. It should +/// be exported by components which can respond to HTTP Requests. interface incoming-handler { use types.{incoming-request, response-outparam}; - /// The `handle` function takes an outparam instead of returning its response - /// so that the component may stream its response while streaming any other - /// request or response bodies. The callee MUST write a response to the - /// `response-out` and then finish the response before returning. The caller - /// is expected to start streaming the response once `set-response-outparam` - /// is called and finish streaming the response when `drop-response-outparam` - /// is called. The `handle` function is then allowed to continue executing - /// any post-response logic before returning. While this post-response - /// execution is taken off the critical path, since there is no return value, - /// there is no way to report its success or failure. + /// This function is invoked with an incoming HTTP Request, and a resource + /// `response-outparam` which provides the capability to reply with an HTTP + /// Response. The response is sent by calling the `response-outparam.set` + /// method, which allows execution to continue after the response has been + /// sent. This enables both streaming to the response body, and performing other + /// work. + /// + /// The implementor of this function must write a response to the + /// `response-outparam` before returning, or else the caller will respond + /// with an error on its behalf. handle: func( request: incoming-request, response-out: response-outparam ); } -/// The `wasi:http/outgoing-handler` interface is meant to be imported by -/// components and implemented by the host. -/// -/// NOTE: in Preview3, this interface will be merged with -/// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface -/// that takes a `request` parameter and returns a `response` result. -/// +/// This interface defines a handler of outgoing HTTP Requests. It should be +/// imported by components which wish to make HTTP Requests. interface outgoing-handler { use types.{outgoing-request, request-options, future-incoming-response, error}; - /// The parameter and result types of the `handle` function allow the caller - /// to concurrently stream the bodies of the outgoing request and the incoming - /// response. + /// This function is invoked with an outgoing HTTP Request, and it returns + /// a resource `future-incoming-response` which represents an HTTP Response + /// which may arrive in the future. + /// + /// The `options` argument accepts optional parameters for the HTTP + /// protocol's transport layer. + /// + /// This function may return an error if the `outgoing-request` is invalid + /// or not allowed to be made. Otherwise, protocol errors are reported + /// through the `future-incoming-response`. handle: func( request: outgoing-request, options: option diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index e58946421..2a4b67d0c 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -1,6 +1,6 @@ -/// The `wasi:http/types` interface is meant to be imported by components to -/// define the HTTP resource types and operations used by the component's -/// imported and exported interfaces. +/// This interface defines all of the types and methods for implementing +/// HTTP Requests and Responses, both incoming and outgoing, as well as +/// their headers, trailers, and bodies. interface types { use wasi:io/streams.{input-stream, output-stream}; use wasi:io/poll.{pollable}; @@ -36,40 +36,69 @@ interface types { unexpected-error(string) } - /// This following block defines the `fields` resource which corresponds to - /// HTTP standard Fields. - resource fields { - /// Multiple values for a header are multiple entries in the list with the - /// same key. - constructor(entries: list>>); - - /// Values off wire are not necessarily well formed, so they are given by - /// list instead of string. - get: func(name: string) -> list>; + /// Field keys are always strings. + type field-key = string; - /// Values off wire are not necessarily well formed, so they are given by - /// list instead of string. - set: func(name: string, value: list>); - delete: func(name: string); - append: func(name: string, value: list); + /// Field values should always be UTF-8 encoded strings. However, in + /// reality, HTTP implementations often have to interpret malformed values, + /// so they are provided as a list of bytes. + type field-value = list; - /// Values off wire are not necessarily well formed, so they are given by - /// list instead of string. - entries: func() -> list>>; + /// This following block defines the `fields` resource which corresponds to + /// HTTP standard Fields. Fields are a common representation used for both + /// Headers and Trailers. + resource fields { - /// Deep copy of all contents in a fields. + /// Construct an HTTP Fields. + /// + /// The list represents each key-value pair in the Fields. Keys + /// which have multiple values are represented by multiple entries in this + /// list with the same key. + /// + /// The tuple is a pair of the field key, represented as a string, and + /// Value, represented as a list of bytes. In a valid Fields, all keys + /// and values are valid UTF-8 strings. However, values are not always + /// well-formed, so they are represented as a raw list of bytes. + constructor(entries: list>); + + /// Get all of the values corresponding to a key. + get: func(name: field-key) -> list; + + /// Set all of the values for a key. Clears any existing values for that + /// key, if they have been set. + set: func(name: field-key, value: list); + + /// Delete all values for a key. Does nothing if no values for the key + /// exist. + delete: func(name: field-key); + + /// Append a value for a key. Does not change or delete any existing + /// values for that key. + append: func(name: field-key, value: field-value); + + + /// Retrieve the full set of keys and values in the Fields. Like the + /// constructor, the list represents each key-value pair. + /// + /// The outer list represents each key-value pair in the Fields. Keys + /// which have multiple values are represented by multiple entries in this + /// list with the same key. + entries: func() -> list>; + + /// Make a deep copy of the Fields. Equivelant in behavior to calling the + /// `fields` constructor on the return value of `entries` clone: func() -> fields; } + /// Headers is an alias for Fields. type headers = fields; + + /// Trailers is an alias for Fields. type trailers = fields; - /// The following block defines the `incoming-request` and `outgoing-request` - /// resource types that correspond to HTTP standard Requests. Later, Preview3 - /// will allow both types to be merged together into a single `request` type - /// (that uses the single `stream` type mentioned above). The `consume` and - /// `write` methods may only be called once (and return failure thereafter). + /// Represents an incoming HTTP Request. resource incoming-request { + /// Returns the method of the incoming request. method: func() -> method; @@ -82,15 +111,21 @@ interface types { /// Returns the authority from the request, if it was present. authority: func() -> option; - /// Returns the headers from the request. + /// Returns the `headers` from the request. + /// + /// The `headers` returned are a child resource: it must be dropped before + /// the parent `incoming-request` is dropped. Dropping this + /// `incoming-request` before all children are dropped will trap. headers: func() -> headers; - /// Will return the incoming-body child at most once. If called more than - /// once, subsequent calls will return error. + /// Gives the `incoming-body` associated with this request. Will only + /// return success at most once, and subsequent calls will return error. consume: func() -> result; } + /// Represents an outgoing HTTP Request. resource outgoing-request { + /// Construct a new `outgoing-request`. constructor( method: method, @@ -105,29 +140,42 @@ interface types { write: func() -> result; } - /// Additional optional parameters that can be set when making a request. + /// Parameters for making an HTTP Request. Each of these parameters is an + /// optional timeout, with the unit in milliseconds, applicable to the + /// transport layer of the HTTP protocol. + /// + /// These timeouts are separate from any the user may use to bound a + /// blocking call to `wasi:io/poll.poll-list`. + /// + /// FIXME: Make this a resource to allow it to be optionally extended by + /// future evolution of the standard and/or other interfaces at some later + /// date? record request-options { - /// The following timeouts are specific to the HTTP protocol and work - /// independently of the overall timeouts passed to `io.poll.poll-list`. - /// The timeout for the initial connect. + /// The timeout for the initial connect to the HTTP Server. connect-timeout-ms: option, - /// The timeout for receiving the first byte of the response body. + /// The timeout for receiving the first byte of the Response body. first-byte-timeout-ms: option, - /// The timeout for receiving the next chunk of bytes in the response body - /// stream. + /// The timeout for receiving subsequent chunks of bytes in the Response + /// body stream. between-bytes-timeout-ms: option } - /// The following block defines a special resource type used by the - /// `wasi:http/incoming-handler` interface. Later, with Preview3, the need for - /// an outparam goes away entirely (the `wasi:http/handler` interface used for - /// both incoming and outgoing can simply return a `stream`). + /// Represents the ability to send an HTTP Response. + /// + /// This resource is used by the `wasi:http/incoming-handler` interface to + /// allow a Response to be sent corresponding to the Request provided as the + /// other argument to `incoming-handler.handle`. resource response-outparam { - /// Set the value of the `response-outparam` to indicate either a response, - /// or an error. + + /// Set the value of the `response-outparam` to either send a response, + /// or indicate an error. + /// + /// This method consumes the `response-outparam` to ensure that it is + /// called at most once. If it is never called, the implementation + /// will respond with an error. set: static func( param: response-outparam, response: result, @@ -137,55 +185,119 @@ interface types { /// This type corresponds to the HTTP standard Status Code. type status-code = u16; - /// The following block defines the `incoming-response` and - /// `outgoing-response` resource types that correspond to HTTP standard - /// Responses. Later, Preview3 will allow both types to be merged together - /// into a single `response` type (that uses the single `stream` type - /// mentioned above). The `consume` and `write` methods may only be called - /// once (and return failure thereafter). + /// Represents an incoming HTTP Response. resource incoming-response { - /// Returns the status code from the `incoming-response`. + + /// Returns the status code from the incoming response. status: func() -> status-code; - /// Returns the headers from the `incoming-response`. + /// Returns the headers from the incoming response. headers: func() -> headers; - /// May be called at most once. returns error if called additional times. + /// Returns the incoming body. May be called at most once. returns error + /// if called additional times. consume: func() -> result; } + /// Represents an incoming HTTP Request or Response's Body. + /// + /// A body has both its contents - a stream of bytes - and a (possibly + /// empty) set of trailers, indicating that the full contents of the + /// body have been received. This resource represents the contents as + /// an `input-stream` and the delivery of trailers as a `future-trailers`, + /// and ensures that the user of this interface may only be consuming either + /// the body contents or waiting on trailers at any given time. resource incoming-body { - /// returned input-stream is a child - the implementation may trap if - /// incoming-body is dropped (or consumed by call to - /// incoming-body.finish) before the input-stream is dropped. - /// May be called at most once. Returns error if called additional times. + + /// Returns the contents of the body, as a stream of bytes. + /// + /// Returns success on first call: the stream representing the contents + /// can be retrieved at most once. Subsequent calls will return error. + /// + /// The returned `input-stream` resource is a child: it must be dropped + /// before the parent `incoming-body` is dropped, or consumed by + /// `incoming-body.finish`. + /// + /// This invariant ensures that the implementation can determine whether + /// the user is consuming the contents of the body, waiting on the + /// `future-trailers` to be ready, or neither. This allows for network + /// backpressure is to be applied when the user is consuming the body, + /// and for that backpressure to not inhibit delivery of the trailers if + /// the user does not read the entire body. %stream: func() -> result; - /// Takes ownership of incoming-body and will trap if the - /// input-stream child is still alive. + /// Takes ownership of `incoming-body`, and returns a `future-trailers`. + /// This function will trap if the `input-stream` child is still alive. finish: static func(this: incoming-body) -> future-trailers; } + /// Represents a future which may eventaully return trailers, or an error. + /// + /// In the case that the incoming HTTP Request or Response did not have any + /// trailers, this future will resolve to the empty set of trailers once the + /// complete Request or Response body has been received. resource future-trailers { - /// Pollable that resolves when the the trailers are ready to be consumed. + + /// Returns a pollable which becomes ready when either the trailers have + /// been received, or an error has occured. When this pollable is ready, + /// the `get` method will return `some`. subscribe: func() -> pollable; - /// Retrieve reference to trailers, if they are ready. + /// Returns the contents of the trailers, or an error which occured, + /// once the future is ready. + /// + /// The outer `option` represents future readiness. Users can wait on this + /// `option` to become `some` using the `subscribe` method. + /// + /// The `result` represents that either the HTTP Request or Response body, + /// as well as any trailers, were received successfully, or that an error + /// occured receiving them. get: func() -> option>; } + /// Represents an outgoing HTTP Response. resource outgoing-response { + /// Construct an `outgoing-response`. constructor(status-code: status-code, headers: borrow); - /// Will give the child outgoing-response at most once. subsequent calls - /// will return an error. + /// Returns the resource corresponding to the outgoing Body for this Response. + /// + /// Returns success on the first call: the `outgoing-body` resource for + /// this `outgoing-response` can be retrieved at most once. Sunsequent + /// calls will return error. + /// + /// FIXME: rename this method to `body`. write: func() -> result; } + /// Represents an outgoing HTTP Request or Response's Body. + /// + /// A body has both its contents - a stream of bytes - and a (possibly + /// empty) set of trailers, inducating the full contents of the body + /// have been sent. This resource represents the contents as an + /// `output-stream` child resource, and the completion of the body (with + /// optional trailers) with a static function that consumes the + /// `outgoing-body` resource, and ensures that the user of this interface + /// may not write to the body contents after the body has been finished. + /// + /// If the user code drops this resource, as opposed to calling the static + /// method `finish`, the implementation should treat the body as incomplete, + /// and that an error has occured. The implementation should propogate this + /// error to the HTTP protocol by whatever means it has available, + /// including: corrupting the body on the wire, aborting the associated + /// Request, or sending a late status code for the Response. resource outgoing-body { - /// Will give the child output-stream at most once. subsequent calls will - /// return an error. + + /// Returns a stream for writing the body contents. + /// + /// The returned `output-stream` is a child resource: it must be dropped + /// before the parent `outgoing-body` resource is dropped (or finished), + /// otherwise the `outgoing-body` drop or `finish` will trap. + /// + /// Returns success on the first call: the `output-stream` resource for + /// this `outgoing-body` may be retrieved at most once. Subsequent calls + /// will return error. write: func() -> result; /// Finalize an outgoing body, optionally providing trailers. This must be @@ -195,20 +307,32 @@ interface types { finish: static func(this: outgoing-body, trailers: option); } - /// The following block defines a special resource type used by the - /// `wasi:http/outgoing-handler` interface to emulate `future>` in advance of Preview3. Given a `future-incoming-response`, the - /// client can call the non-blocking `get` method to get the result if it is - /// available. If the result is not available, the client can call `listen` to - /// get a `pollable` that can be passed to `wasi:io/poll.poll-list`. + /// Represents a future which may eventaully return an incoming HTTP + /// Response, or an error. + /// + /// This resource is returned by the `wasi:http/outgoing-handler` interface to + /// provide the HTTP Response corresponding to the sent Request. resource future-incoming-response { - /// The option indicates readiness. The outer result must return failure if - /// `get` is called after returning a non-empty result. The inner result - /// indicates whether the incoming response successfully started. + /// Returns a pollable which becomes ready when either the Response has + /// been received, or an error has occured. When this pollable is ready, + /// the `get` method will return `some`. + subscribe: func() -> pollable; + + /// Returns the incoming HTTP Response, or an error, once one is ready. + /// + /// The outer `option` represents future readiness. Users can wait on this + /// `option` to become `some` using the `subscribe` method. + /// + /// The outer `result` is used to retrieve the response or error at most + /// once. It will be success on the first call in which the outer option + /// is `some`, and error on subsequent calls. + /// + /// The inner `result` represents that either the incoming HTTP Response + /// status and headers have recieved successfully, or that an error + /// occured. Errors may also occur while consuming the response body, + /// but those will be reported by the `incoming-body` and its + /// `output-stream` child. get: func() -> option>>; - /// Pollable that resolves when the `get` method will resolve to a `Some` - /// result. - subscribe: func() -> pollable; } } From 3202417e23421acf17e54e8bde025bbd7ae1449d Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Oct 2023 09:39:30 -0700 Subject: [PATCH 1253/1772] Update wit/types.wit Co-authored-by: Luke Wagner --- proposals/http/wit/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 2a4b67d0c..70731f9cc 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -39,7 +39,7 @@ interface types { /// Field keys are always strings. type field-key = string; - /// Field values should always be UTF-8 encoded strings. However, in + /// Field values should always be ASCII strings. However, in /// reality, HTTP implementations often have to interpret malformed values, /// so they are provided as a list of bytes. type field-value = list; From 1013f4c07dcc822080ed99fc695c261f8ef432a1 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Oct 2023 09:39:36 -0700 Subject: [PATCH 1254/1772] Update wit/types.wit Co-authored-by: Luke Wagner --- proposals/http/wit/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 70731f9cc..a903f512b 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -194,7 +194,7 @@ interface types { /// Returns the headers from the incoming response. headers: func() -> headers; - /// Returns the incoming body. May be called at most once. returns error + /// Returns the incoming body. May be called at most once. Returns error /// if called additional times. consume: func() -> result; } From c1e4a6ba6e5fef21b5415c2aa1f0a90e7bc238a2 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 18 Oct 2023 09:40:20 -0700 Subject: [PATCH 1255/1772] markdown generated --- proposals/http/proxy.md | 217 ++++++++++++++++++++++++++++------------ 1 file changed, 153 insertions(+), 64 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index b3693b30a..203c9ccbb 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -1,4 +1,8 @@

        World proxy

        +

        The wasi:http/proxy world captures a widely-implementable intersection of +hosts that includes HTTP forward and reverse proxies. Components targeting +this world may concurrently stream in and out any number of incoming and +outgoing HTTP requests.

        • Imports:

          Import interface wasi:http/types

          -

          The wasi:http/types interface is meant to be imported by components to -define the HTTP resource types and operations used by the component's -imported and exported interfaces.

          +

          This interface defines all of the types and methods for implementing +HTTP Requests and Responses, both incoming and outgoing, as well as +their headers, trailers, and bodies.


          Types

          type input-stream

          @@ -669,33 +673,46 @@ initially returning a response.

        • protocol-error: string
        • unexpected-error: string
        +

        type field-key

        +

        string

        +

        Field keys are always strings. +

        type field-value

        +

        field-value

        +

        Field values should always be ASCII strings. However, in +reality, HTTP implementations often have to interpret malformed values, +so they are provided as a list of bytes.

        resource fields

        type headers

        fields

        -

        -#### `type trailers` -[`fields`](#fields) -

        -#### `resource incoming-request` +

        Headers is an alias for Fields. +

        type trailers

        +

        fields

        +

        Trailers is an alias for Fields. +

        resource incoming-request

        resource outgoing-request

        record request-options

        -

        Additional optional parameters that can be set when making a request.

        +

        Parameters for making an HTTP Request. Each of these parameters is an +optional timeout, with the unit in milliseconds, applicable to the +transport layer of the HTTP protocol.

        +

        These timeouts are separate from any the user may use to bound a +blocking call to wasi:io/poll.poll-list.

        +

        FIXME: Make this a resource to allow it to be optionally extended by +future evolution of the standard and/or other interfaces at some later +date?

        Record Fields
        • connect-timeout-ms: option<u32>

          -

          The following timeouts are specific to the HTTP protocol and work -independently of the overall timeouts passed to `io.poll.poll-list`. -The timeout for the initial connect. +

          The timeout for the initial connect to the HTTP Server.

        • first-byte-timeout-ms: option<u32>

          -

          The timeout for receiving the first byte of the response body. +

          The timeout for receiving the first byte of the Response body.

        • between-bytes-timeout-ms: option<u32>

          -

          The timeout for receiving the next chunk of bytes in the response body -stream. +

          The timeout for receiving subsequent chunks of bytes in the Response +body stream.

        resource response-outparam

        @@ -711,63 +728,76 @@ stream.

        Functions

        [constructor]fields: func

        -

        Multiple values for a header are multiple entries in the list with the -same key.

        +

        Construct an HTTP Fields.

        +

        The list represents each key-value pair in the Fields. Keys +which have multiple values are represented by multiple entries in this +list with the same key.

        +

        The tuple is a pair of the field key, represented as a string, and +Value, represented as a list of bytes. In a valid Fields, all keys +and values are valid UTF-8 strings. However, values are not always +well-formed, so they are represented as a raw list of bytes.

        Params
        Return values

        [method]fields.get: func

        -

        Values off wire are not necessarily well formed, so they are given by -list instead of string.

        +

        Get all of the values corresponding to a key.

        Params
        Return values

        [method]fields.set: func

        -

        Values off wire are not necessarily well formed, so they are given by -list instead of string.

        +

        Set all of the values for a key. Clears any existing values for that +key, if they have been set.

        Params

        [method]fields.delete: func

        +

        Delete all values for a key. Does nothing if no values for the key +exist.

        Params

        [method]fields.append: func

        +

        Append a value for a key. Does not change or delete any existing +values for that key.

        Params

        [method]fields.entries: func

        -

        Values off wire are not necessarily well formed, so they are given by -list instead of string.

        +

        Retrieve the full set of keys and values in the Fields. Like the +constructor, the list represents each key-value pair.

        +

        The outer list represents each key-value pair in the Fields. Keys +which have multiple values are represented by multiple entries in this +list with the same key.

        Params
        Return values

        [method]fields.clone: func

        -

        Deep copy of all contents in a fields.

        +

        Make a deep copy of the Fields. Equivelant in behavior to calling the +fields constructor on the return value of entries

        Params
        • self: borrow<fields>
        • @@ -817,7 +847,10 @@ list instead of string.

        • option<string>

        [method]incoming-request.headers: func

        -

        Returns the headers from the request.

        +

        Returns the headers from the request.

        +

        The headers returned are a child resource: it must be dropped before +the parent incoming-request is dropped. Dropping this +incoming-request before all children are dropped will trap.

        Params

        [method]incoming-request.consume: func

        -

        Will return the incoming-body child at most once. If called more than -once, subsequent calls will return error.

        +

        Gives the incoming-body associated with this request. Will only +return success at most once, and subsequent calls will return error.

        Params

        [static]response-outparam.set: func

        -

        Set the value of the response-outparam to indicate either a response, -or an error.

        +

        Set the value of the response-outparam to either send a response, +or indicate an error.

        +

        This method consumes the response-outparam to ensure that it is +called at most once. If it is never called, the implementation +will respond with an error.

        Params

        [method]incoming-response.status: func

        -

        Returns the status code from the incoming-response.

        +

        Returns the status code from the incoming response.

        Params

        [method]incoming-response.headers: func

        -

        Returns the headers from the incoming-response.

        +

        Returns the headers from the incoming response.

        Params

        [method]incoming-response.consume: func

        -

        May be called at most once. returns error if called additional times.

        +

        Returns the incoming body. May be called at most once. Returns error +if called additional times.

        Params

        [method]incoming-body.stream: func

        -

        returned input-stream is a child - the implementation may trap if -incoming-body is dropped (or consumed by call to -incoming-body.finish) before the input-stream is dropped. -May be called at most once. Returns error if called additional times.

        +

        Returns the contents of the body, as a stream of bytes.

        +

        Returns success on first call: the stream representing the contents +can be retrieved at most once. Subsequent calls will return error.

        +

        The returned input-stream resource is a child: it must be dropped +before the parent incoming-body is dropped, or consumed by +incoming-body.finish.

        +

        This invariant ensures that the implementation can determine whether +the user is consuming the contents of the body, waiting on the +future-trailers to be ready, or neither. This allows for network +backpressure is to be applied when the user is consuming the body, +and for that backpressure to not inhibit delivery of the trailers if +the user does not read the entire body.

        Params
        • self: borrow<incoming-body>
        • @@ -914,8 +959,8 @@ May be called at most once. Returns error if called additional times.

        • result<own<input-stream>>

        [static]incoming-body.finish: func

        -

        Takes ownership of incoming-body and will trap if the -input-stream child is still alive.

        +

        Takes ownership of incoming-body, and returns a future-trailers. +This function will trap if the input-stream child is still alive.

        Params

        [method]future-trailers.subscribe: func

        -

        Pollable that resolves when the the trailers are ready to be consumed.

        +

        Returns a pollable which becomes ready when either the trailers have +been received, or an error has occured. When this pollable is ready, +the get method will return some.

        Params

        [method]future-trailers.get: func

        -

        Retrieve reference to trailers, if they are ready.

        +

        Returns the contents of the trailers, or an error which occured, +once the future is ready.

        +

        The outer option represents future readiness. Users can wait on this +option to become some using the subscribe method.

        +

        The result represents that either the HTTP Request or Response body, +as well as any trailers, were received successfully, or that an error +occured receiving them.

        Params

        [method]outgoing-response.write: func

        -

        Will give the child outgoing-response at most once. subsequent calls -will return an error.

        +

        Returns the resource corresponding to the outgoing Body for this Response.

        +

        Returns success on the first call: the outgoing-body resource for +this outgoing-response can be retrieved at most once. Sunsequent +calls will return error.

        +

        FIXME: rename this method to body.

        Params

        [method]outgoing-body.write: func

        -

        Will give the child output-stream at most once. subsequent calls will -return an error.

        +

        Returns a stream for writing the body contents.

        +

        The returned output-stream is a child resource: it must be dropped +before the parent outgoing-body resource is dropped (or finished), +otherwise the outgoing-body drop or finish will trap.

        +

        Returns success on the first call: the output-stream resource for +this outgoing-body may be retrieved at most once. Subsequent calls +will return error.

        Params
        -

        [method]future-incoming-response.get: func

        -

        The option indicates readiness. The outer result must return failure if -get is called after returning a non-empty result. The inner result -indicates whether the incoming response successfully started.

        +

        [method]future-incoming-response.subscribe: func

        +

        Returns a pollable which becomes ready when either the Response has +been received, or an error has occured. When this pollable is ready, +the get method will return some.

        Params
        Return values
        -

        [method]future-incoming-response.subscribe: func

        -

        Pollable that resolves when the get method will resolve to a Some -result.

        +

        [method]future-incoming-response.get: func

        +

        Returns the incoming HTTP Response, or an error, once one is ready.

        +

        The outer option represents future readiness. Users can wait on this +option to become some using the subscribe method.

        +

        The outer result is used to retrieve the response or error at most +once. It will be success on the first call in which the outer option +is some, and error on subsequent calls.

        +

        The inner result represents that either the incoming HTTP Response +status and headers have recieved successfully, or that an error +occured. Errors may also occur while consuming the response body, +but those will be reported by the incoming-body and its +output-stream child.

        Params
        Return values

        Import interface wasi:http/outgoing-handler

        +

        This interface defines a handler of outgoing HTTP Requests. It should be +imported by components which wish to make HTTP Requests.


        Types

        type outgoing-request

        @@ -1028,6 +1100,14 @@ result.

        ----

        Functions

        handle: func

        +

        This function is invoked with an outgoing HTTP Request, and it returns +a resource future-incoming-response which represents an HTTP Response +which may arrive in the future.

        +

        The options argument accepts optional parameters for the HTTP +protocol's transport layer.

        +

        This function may return an error if the outgoing-request is invalid +or not allowed to be made. Otherwise, protocol errors are reported +through the future-incoming-response.

        Params
        • request: own<outgoing-request>
        • @@ -1049,6 +1129,15 @@ result.

          ----

          Functions

          handle: func

          +

          This function is invoked with an incoming HTTP Request, and a resource +response-outparam which provides the capability to reply with an HTTP +Response. The response is sent by calling the response-outparam.set +method, which allows execution to continue after the response has been +sent. This enables both streaming to the response body, and performing other +work.

          +

          The implementor of this function must write a response to the +response-outparam before returning, or else the caller will respond +with an error on its behalf.

          Params
          • request: own<incoming-request>
          • From d142bf9ff19821192c91f66e9c91939084e9ce1f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 23 Oct 2023 12:05:17 -0700 Subject: [PATCH 1256/1772] input-stream uses result type like output-stream; single stream-error definition has error resource (#52) * chore: sync with Wasmtime Signed-off-by: Roman Volosatovs * generate markdown * update doc comments for changes to interface --------- Signed-off-by: Roman Volosatovs Co-authored-by: Roman Volosatovs --- proposals/io/imports.md | 142 ++++++++++++++++++----------------- proposals/io/wit/streams.wit | 123 +++++++++++++++--------------- 2 files changed, 134 insertions(+), 131 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index c4e8b5354..75e48343e 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -13,7 +13,7 @@ at once.


            Types

            resource pollable

            -
            +

            A "pollable" handle.

            Functions

            poll-list: func

            Poll for completion on a set of pollables.

            @@ -55,62 +55,76 @@ when it does, they are expected to subsume this API.

            type pollable

            pollable

            -#### `enum stream-status` -

            Streams provide a sequence of data and then end; once they end, they -no longer provide any further data.

            -

            For example, a stream reading from a file ends when the stream reaches -the end of the file. For another example, a stream reading from a -socket ends when the socket is closed.

            -
            Enum Cases
            +#### `resource error` +

            Contextual error information about the last failure that happened on +a read, write, or flush from an input-stream or output-stream.

            +

            This type is returned through the stream-error type whenever an +operation on a stream directly fails or an error is discovered +after-the-fact, for example when a write's failure shows up through a +later flush or check-write.

            +

            Interfaces such as wasi:filesystem/types provide functionality to +further "downcast" this error into interface-specific error information.

            +

            variant stream-error

            +

            An error for input-stream and output-stream operations.

            +
            Variant Cases
            • -

              open

              -

              The stream is open and may produce further data. -

            • -
            • -

              ended

              -

              When reading, this indicates that the stream will not produce -further data. -When writing, this indicates that the stream will no longer be read. -Further writes are still permitted. -

            • -
            -

            resource input-stream

            -

            enum write-error

            -

            An error for output-stream operations.

            -

            Contrary to input-streams, a closed output-stream is reported using -an error.

            -
            Enum Cases
            -
              -
            • -

              last-operation-failed

              +

              last-operation-failed: own<error>

              The last operation (a write or flush) failed before completion. +

              More information is available in the error payload.

            • -

              closed

              +

              closed

              The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

            +

            resource input-stream

            +

            An input bytestream.

            +

            input-streams are non-blocking to the extent practical on underlying +platforms. I/O operations always return promptly; if fewer bytes are +promptly available than requested, they return the number of bytes promptly +available, which could even be zero. To wait for data to be available, +use the subscribe function to obtain a pollable which can be polled +for using wasi:io/poll.

            resource output-stream

            -
            +

            An output bytestream.

            +

            output-streams are non-blocking to the extent practical on +underlying platforms. Except where specified otherwise, I/O operations also +always return promptly, after the number of bytes that can be written +promptly, which could even be zero. To wait for the stream to be ready to +accept data, the subscribe function to obtain a pollable which can be +polled for using wasi:io/poll.

            Functions

            +

            [method]error.to-debug-string: func

            +

            Returns a string that's suitable to assist humans in debugging this +error.

            +

            The returned string will change across platforms and hosts which +means that parsing it, for example, would be a +platform-compatibility hazard.

            +
            Params
            + +
            Return values
            +
              +
            • string
            • +

            [method]input-stream.read: func

            Perform a non-blocking read from the stream.

            -

            This function returns a list of bytes containing the data that was -read, along with a stream-status which, indicates whether further -reads are expected to produce data. The returned list will contain up to -len bytes; it may return fewer than requested, but not more. An -empty list and stream-status:open indicates no more data is -available at this time, and that the pollable given by subscribe -will be ready when more data is available.

            -

            Once a stream has reached the end, subsequent calls to read or -skip will always report stream-status:ended rather than producing more -data.

            -

            When the caller gives a len of 0, it represents a request to read 0 -bytes. This read should always succeed and return an empty list and -the current stream-status.

            +

            This function returns a list of bytes containing the read data, +when successful. The returned list will contain up to len bytes; +it may return fewer than requested, but not more. The list is +empty when no bytes are available for reading at this time. The +pollable given by subscribe will be ready when more bytes are +available.

            +

            This function fails with a stream-error when the operation +encounters an error, giving last-operation-failed, or when the +stream is closed, giving closed.

            +

            When the caller gives a len of 0, it represents a request to +read 0 bytes. If the stream is still open, this call should +succeed and return an empty list, or otherwise fail with closed.

            The len parameter is a u64, which could represent a list of u8 which is not possible to allocate in wasm32, or not desirable to allocate as as a return value by the callee. The callee may return a list of bytes @@ -122,11 +136,11 @@ less than len in size while more bytes are available for reading.

            Return values

            [method]input-stream.blocking-read: func

            Read bytes from a stream, after blocking until at least one byte can -be read. Except for blocking, identical to read.

            +be read. Except for blocking, behavior is identical to read.

            Params
            • self: borrow<input-stream>
            • @@ -134,18 +148,12 @@ be read. Except for blocking, identical to read.

            Return values

            [method]input-stream.skip: func

            -

            Skip bytes from a stream.

            -

            This is similar to the read function, but avoids copying the -bytes into the instance.

            -

            Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

            -

            This function returns the number of bytes skipped, along with a -stream-status indicating whether the end of the stream was -reached. The returned value will be at most len; it may be less.

            +

            Skip bytes from a stream. Returns number of bytes skipped.

            +

            Behaves identical to read, except instead of returning a list +of bytes, returns the number of bytes consumed from the stream.

            Params
            Return values

            [method]output-stream.write: func

            Perform a write. This function never blocks.

            @@ -211,7 +219,7 @@ the last call to check-write provided a permit.

          Return values

          [method]output-stream.blocking-write-and-flush: func

          Perform a write of up to 4096 bytes, and then flush the stream. Block @@ -242,7 +250,7 @@ let _ = this.check-write(); // eliding error handling

        Return values

        [method]output-stream.flush: func

        Request to flush buffered output. This function never blocks.

        @@ -259,7 +267,7 @@ flush has completed and the stream can accept more writes.

      Return values

      [method]output-stream.blocking-flush: func

      Request to flush buffered output, and block until flush completes @@ -270,7 +278,7 @@ and stream is ready for writing again.

    Return values

    [method]output-stream.subscribe: func

    Create a pollable which will resolve once the output-stream @@ -302,7 +310,7 @@ that should be written.

    Return values

    [method]output-stream.blocking-write-zeroes-and-flush: func

    Perform a write of up to 4096 zeroes, and then flush the stream. @@ -333,7 +341,7 @@ let _ = this.check-write(); // eliding error handling

    Return values

    [method]output-stream.splice: func

    Read from one stream and write to another.

    @@ -349,7 +357,7 @@ read from the input stream has been written to the output stream.

    Return values

    [method]output-stream.blocking-splice: func

    Read from one stream and write to another, with blocking.

    @@ -363,7 +371,7 @@ one byte can be read.

    Return values

    [method]output-stream.forward: func

    Forward the entire contents of an input stream to an output stream.

    @@ -382,5 +390,5 @@ the output stream.

    Return values
    diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index cfeab0da1..da87d67ff 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -8,20 +8,36 @@ package wasi:io; interface streams { use poll.{pollable}; - /// Streams provide a sequence of data and then end; once they end, they - /// no longer provide any further data. + /// An error for input-stream and output-stream operations. + variant stream-error { + /// The last operation (a write or flush) failed before completion. + /// + /// More information is available in the `error` payload. + last-operation-failed(error), + /// The stream is closed: no more input will be accepted by the + /// stream. A closed output-stream will return this error on all + /// future operations. + closed + } + + /// Contextual error information about the last failure that happened on + /// a read, write, or flush from an `input-stream` or `output-stream`. /// - /// For example, a stream reading from a file ends when the stream reaches - /// the end of the file. For another example, a stream reading from a - /// socket ends when the socket is closed. - enum stream-status { - /// The stream is open and may produce further data. - open, - /// When reading, this indicates that the stream will not produce - /// further data. - /// When writing, this indicates that the stream will no longer be read. - /// Further writes are still permitted. - ended, + /// This type is returned through the `stream-error` type whenever an + /// operation on a stream directly fails or an error is discovered + /// after-the-fact, for example when a write's failure shows up through a + /// later `flush` or `check-write`. + /// + /// Interfaces such as `wasi:filesystem/types` provide functionality to + /// further "downcast" this error into interface-specific error information. + resource error { + /// Returns a string that's suitable to assist humans in debugging this + /// error. + /// + /// The returned string will change across platforms and hosts which + /// means that parsing it, for example, would be a + /// platform-compatibility hazard. + to-debug-string: func() -> string; } /// An input bytestream. @@ -35,21 +51,20 @@ interface streams { resource input-stream { /// Perform a non-blocking read from the stream. /// - /// This function returns a list of bytes containing the data that was - /// read, along with a `stream-status` which, indicates whether further - /// reads are expected to produce data. The returned list will contain up to - /// `len` bytes; it may return fewer than requested, but not more. An - /// empty list and `stream-status:open` indicates no more data is - /// available at this time, and that the pollable given by `subscribe` - /// will be ready when more data is available. + /// This function returns a list of bytes containing the read data, + /// when successful. The returned list will contain up to `len` bytes; + /// it may return fewer than requested, but not more. The list is + /// empty when no bytes are available for reading at this time. The + /// pollable given by `subscribe` will be ready when more bytes are + /// available. /// - /// Once a stream has reached the end, subsequent calls to `read` or - /// `skip` will always report `stream-status:ended` rather than producing more - /// data. + /// This function fails with a `stream-error` when the operation + /// encounters an error, giving `last-operation-failed`, or when the + /// stream is closed, giving `closed`. /// - /// When the caller gives a `len` of 0, it represents a request to read 0 - /// bytes. This read should always succeed and return an empty list and - /// the current `stream-status`. + /// When the caller gives a `len` of 0, it represents a request to + /// read 0 bytes. If the stream is still open, this call should + /// succeed and return an empty list, or otherwise fail with `closed`. /// /// The `len` parameter is a `u64`, which could represent a list of u8 which /// is not possible to allocate in wasm32, or not desirable to allocate as @@ -58,38 +73,30 @@ interface streams { read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>>; + ) -> result, stream-error>; /// Read bytes from a stream, after blocking until at least one byte can - /// be read. Except for blocking, identical to `read`. + /// be read. Except for blocking, behavior is identical to `read`. blocking-read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>>; + ) -> result, stream-error>; - /// Skip bytes from a stream. - /// - /// This is similar to the `read` function, but avoids copying the - /// bytes into the instance. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. + /// Skip bytes from a stream. Returns number of bytes skipped. /// - /// This function returns the number of bytes skipped, along with a - /// `stream-status` indicating whether the end of the stream was - /// reached. The returned value will be at most `len`; it may be less. + /// Behaves identical to `read`, except instead of returning a list + /// of bytes, returns the number of bytes consumed from the stream. skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result>; + ) -> result; /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. blocking-skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result>; + ) -> result; /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been @@ -100,18 +107,6 @@ interface streams { subscribe: func() -> pollable; } - /// An error for output-stream operations. - /// - /// Contrary to input-streams, a closed output-stream is reported using - /// an error. - enum write-error { - /// The last operation (a write or flush) failed before completion. - last-operation-failed, - /// The stream is closed: no more input will be accepted by the - /// stream. A closed output-stream will return this error on all - /// future operations. - closed - } /// An output bytestream. /// @@ -131,7 +126,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. - check-write: func() -> result; + check-write: func() -> result; /// Perform a write. This function never blocks. /// @@ -142,7 +137,7 @@ interface streams { /// the last call to check-write provided a permit. write: func( contents: list - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. @@ -170,7 +165,7 @@ interface streams { /// ``` blocking-write-and-flush: func( contents: list - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Request to flush buffered output. This function never blocks. /// @@ -182,11 +177,11 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. - flush: func() -> result<_, write-error>; + flush: func() -> result<_, stream-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. - blocking-flush: func() -> result<_, write-error>; + blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream /// is ready for more writing, or an error has occured. When this @@ -209,7 +204,7 @@ interface streams { write-zeroes: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Perform a write of up to 4096 zeroes, and then flush the stream. /// Block until all of these operations are complete, or an error @@ -238,7 +233,7 @@ interface streams { blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Read from one stream and write to another. /// @@ -252,7 +247,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result>; + ) -> result; /// Read from one stream and write to another, with blocking. /// @@ -263,7 +258,7 @@ interface streams { src: input-stream, /// The number of bytes to splice len: u64, - ) -> result>; + ) -> result; /// Forward the entire contents of an input stream to an output stream. /// @@ -280,6 +275,6 @@ interface streams { forward: func( /// The stream to read from src: input-stream - ) -> result>; + ) -> result; } } From 6e813544905d0cf5d2a62dbbb8d85b82cc21fcb6 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 24 Oct 2023 14:35:47 -0700 Subject: [PATCH 1257/1772] Fixes for output-stream.splice, and delete forward (#53) * output-stream: changes to splice and blocking-splice, and delete forward * update markdown --- proposals/io/imports.md | 64 +++++++++--------------------------- proposals/io/wit/streams.wit | 38 ++++++++------------- 2 files changed, 30 insertions(+), 72 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index 75e48343e..3f3866136 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -13,7 +13,7 @@ at once.


    Types

    resource pollable

    -

    A "pollable" handle.

    +

    Functions

    poll-list: func

    Poll for completion on a set of pollables.

    @@ -56,14 +56,6 @@ when it does, they are expected to subsume this API.

    pollable

    #### `resource error` -

    Contextual error information about the last failure that happened on -a read, write, or flush from an input-stream or output-stream.

    -

    This type is returned through the stream-error type whenever an -operation on a stream directly fails or an error is discovered -after-the-fact, for example when a write's failure shows up through a -later flush or check-write.

    -

    Interfaces such as wasi:filesystem/types provide functionality to -further "downcast" this error into interface-specific error information.

    variant stream-error

    An error for input-stream and output-stream operations.

    Variant Cases
    @@ -81,21 +73,8 @@ future operations.

    resource input-stream

    -

    An input bytestream.

    -

    input-streams are non-blocking to the extent practical on underlying -platforms. I/O operations always return promptly; if fewer bytes are -promptly available than requested, they return the number of bytes promptly -available, which could even be zero. To wait for data to be available, -use the subscribe function to obtain a pollable which can be polled -for using wasi:io/poll.

    resource output-stream

    -

    An output bytestream.

    -

    output-streams are non-blocking to the extent practical on -underlying platforms. Except where specified otherwise, I/O operations also -always return promptly, after the number of bytes that can be written -promptly, which could even be zero. To wait for the stream to be ready to -accept data, the subscribe function to obtain a pollable which can be -polled for using wasi:io/poll.

    +

    Functions

    [method]error.to-debug-string: func

    Returns a string that's suitable to assist humans in debugging this @@ -345,14 +324,21 @@ let _ = this.check-write(); // eliding error handling

    [method]output-stream.splice: func

    Read from one stream and write to another.

    +

    The behavior of splice is equivelant to:

    +
      +
    1. calling check-write on the output-stream
    2. +
    3. calling read on the input-stream with the smaller of the +check-write permitted length and the len provided to splice
    4. +
    5. calling write on the output-stream with that read data.
    6. +
    +

    Any error reported by the call to check-write, read, or +write ends the splice and reports that error.

    This function returns the number of bytes transferred; it may be less than len.

    -

    Unlike other I/O functions, this function blocks until all the data -read from the input stream has been written to the output stream.

    Params
    Return values
    @@ -361,34 +347,16 @@ read from the input stream has been written to the output stream.

    [method]output-stream.blocking-splice: func

    Read from one stream and write to another, with blocking.

    -

    This is similar to splice, except that it blocks until at least -one byte can be read.

    +

    This is similar to splice, except that it blocks until the +output-stream is ready for writing, and the input-stream +is ready for reading, before performing the splice.

    Params
    Return values
    -

    [method]output-stream.forward: func

    -

    Forward the entire contents of an input stream to an output stream.

    -

    This function repeatedly reads from the input stream and writes -the data to the output stream, until the end of the input stream -is reached, or an error is encountered.

    -

    Unlike other I/O functions, this function blocks until the end -of the input stream is seen and all the data has been written to -the output stream.

    -

    This function returns the number of bytes transferred, and the status of -the output stream.

    -
    Params
    - -
    Return values
    - diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index da87d67ff..8999b28d2 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -237,44 +237,34 @@ interface streams { /// Read from one stream and write to another. /// + /// The behavior of splice is equivelant to: + /// 1. calling `check-write` on the `output-stream` + /// 2. calling `read` on the `input-stream` with the smaller of the + /// `check-write` permitted length and the `len` provided to `splice` + /// 3. calling `write` on the `output-stream` with that read data. + /// + /// Any error reported by the call to `check-write`, `read`, or + /// `write` ends the splice and reports that error. + /// /// This function returns the number of bytes transferred; it may be less /// than `len`. - /// - /// Unlike other I/O functions, this function blocks until all the data - /// read from the input stream has been written to the output stream. splice: func( /// The stream to read from - src: input-stream, + src: borrow, /// The number of bytes to splice len: u64, ) -> result; /// Read from one stream and write to another, with blocking. /// - /// This is similar to `splice`, except that it blocks until at least - /// one byte can be read. + /// This is similar to `splice`, except that it blocks until the + /// `output-stream` is ready for writing, and the `input-stream` + /// is ready for reading, before performing the `splice`. blocking-splice: func( /// The stream to read from - src: input-stream, + src: borrow, /// The number of bytes to splice len: u64, ) -> result; - - /// Forward the entire contents of an input stream to an output stream. - /// - /// This function repeatedly reads from the input stream and writes - /// the data to the output stream, until the end of the input stream - /// is reached, or an error is encountered. - /// - /// Unlike other I/O functions, this function blocks until the end - /// of the input stream is seen and all the data has been written to - /// the output stream. - /// - /// This function returns the number of bytes transferred, and the status of - /// the output stream. - forward: func( - /// The stream to read from - src: input-stream - ) -> result; } } From e8816abf3f329612ba0137ff139fbce25d13b175 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 24 Oct 2023 14:26:23 -0700 Subject: [PATCH 1258/1772] outgoing-request and -response: rename `write` to `body`, and fix docs `body` is a better name than `write` - it makes it explicit this is about access to the body. the `outgoing-body` resource itself has a method `write` which gives the body contents as a stream. Changing this method name makes this distinction more clear. The docs for `outgoing-request.write` were incorrect - the outgoing-body is not a child of the outgoing-request (or outgoing-response), otherwise outgoing body streaming (i.e. writing to the body after the request or response has been initiated) would not be possible. --- proposals/http/wit/types.wit | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index a903f512b..a94aea3b8 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -135,9 +135,13 @@ interface types { headers: borrow ); - /// Will return the outgoing-body child at most once. If called more than - /// once, subsequent calls will return error. - write: func() -> result; + /// Returns the resource corresponding to the outgoing Body for this + /// Request. + /// + /// Returns success on the first call: the `outgoing-body` resource for + /// this `outgoing-response` can be retrieved at most once. Subsequent + /// calls will return error. + body: func() -> result; } /// Parameters for making an HTTP Request. Each of these parameters is an @@ -264,11 +268,9 @@ interface types { /// Returns the resource corresponding to the outgoing Body for this Response. /// /// Returns success on the first call: the `outgoing-body` resource for - /// this `outgoing-response` can be retrieved at most once. Sunsequent + /// this `outgoing-response` can be retrieved at most once. Subsequent /// calls will return error. - /// - /// FIXME: rename this method to `body`. - write: func() -> result; + body: func() -> result; } /// Represents an outgoing HTTP Request or Response's Body. From 76347b6d01147b2656ff264e0b51c900e8d41367 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 24 Oct 2023 15:04:12 -0700 Subject: [PATCH 1259/1772] generate markdown --- proposals/http/proxy.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 203c9ccbb..5d27bd24d 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -884,16 +884,19 @@ return success at most once, and subsequent calls will return error.

    -

    [method]outgoing-request.write: func

    -

    Will return the outgoing-body child at most once. If called more than -once, subsequent calls will return error.

    +

    [method]outgoing-request.body: func

    +

    Returns the resource corresponding to the outgoing Body for this +Request.

    +

    Returns success on the first call: the outgoing-body resource for +this outgoing-response can be retrieved at most once. Subsequent +calls will return error.

    Params
    Return values

    [static]response-outparam.set: func

    Set the value of the response-outparam to either send a response, @@ -1008,19 +1011,18 @@ occured receiving them.

    -

    [method]outgoing-response.write: func

    +

    [method]outgoing-response.body: func

    Returns the resource corresponding to the outgoing Body for this Response.

    Returns success on the first call: the outgoing-body resource for -this outgoing-response can be retrieved at most once. Sunsequent +this outgoing-response can be retrieved at most once. Subsequent calls will return error.

    -

    FIXME: rename this method to body.

    Params
    Return values

    [method]outgoing-body.write: func

    Returns a stream for writing the body contents.

    From d0aebfd55e8dae4eee886614c486296ed9bca9bc Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 24 Oct 2023 14:38:43 -0700 Subject: [PATCH 1260/1772] add accessor methods to outgoing-request and outgoing-response Taken from wasmtime b663ccf9e1eef4b0a1e5637cd6f86d8d42783403 This change has two purposes: 1. adding the accessors enables treating the resource's representation of all state as canonical, instead of requiring a component to retain a copy of all state contained in the resource. 1. Adding mutators for all state supports use cases where it's required to change a request's/response's state after writing to its body. This is in particular the case when implementing preexisting systems or specifications, such as the WHATWG fetch spec used in JavaScript environments. Co-authored-by: Till Schneidereit --- proposals/http/wit/types.wit | 80 ++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index a94aea3b8..b7625a13f 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -127,12 +127,29 @@ interface types { resource outgoing-request { /// Construct a new `outgoing-request`. + /// + /// * `method` represents the HTTP Method for the Request. + /// * `path-with-query` is the combination of the HTTP Path and Query for + /// the Request. When `none`, this represents an empty Path and empty + /// Query. + /// * `scheme` is the HTTP Related Scheme for the Request. When `none`, + /// the implementation may choose an appropriate default scheme. + /// * `authority` is the HTTP Authority for the Request. A value of `none` + /// may be used with Related Schemes which do not require an Authority. + /// The HTTP and HTTPS schemes always require an authority. + /// * `headers` is the HTTP Headers for the Request. + /// + /// It is possible to construct, or manipulate with the accessor functions + /// below, an `outgoing-request` with an invalid combination of `scheme` + /// and `authority`, or `headers` which are not permitted to be sent. + /// It is the obligation of the `outgoing-handler.handle` implementation + /// to reject invalid constructions of `outgoing-request`. constructor( method: method, path-with-query: option, scheme: option, authority: option, - headers: borrow + headers: headers ); /// Returns the resource corresponding to the outgoing Body for this @@ -142,6 +159,41 @@ interface types { /// this `outgoing-response` can be retrieved at most once. Subsequent /// calls will return error. body: func() -> result; + + /// Get the Method for the Request. + method: func() -> method; + /// Set the Method for the Request. + set-method: func(method: method); + + /// Get the combination of the HTTP Path and Query for the Request. + /// When `none`, this represents an empty Path and empty Query. + path-with-query: func() -> option; + /// Set the combination of the HTTP Path and Query for the Request. + /// When `none`, this represents an empty Path and empty Query. + set-path-with-query: func(path-with-query: option); + + /// Get the HTTP Related Scheme for the Request. When `none`, the + /// implementation may choose an appropriate default scheme. + scheme: func() -> option; + /// Set the HTTP Related Scheme for the Request. When `none`, the + /// implementation may choose an appropriate default scheme. + set-scheme: func(scheme: option); + + /// Get the HTTP Authority for the Request. A value of `none` may be used + /// with Related Schemes which do not require an Authority. The HTTP and + /// HTTPS schemes always require an authority. + authority: func() -> option; + /// Set the HTTP Authority for the Request. A value of `none` may be used + /// with Related Schemes which do not require an Authority. The HTTP and + /// HTTPS schemes always require an authority. + set-authority: func(authority: option); + + /// Get the headers associated with the Request. + /// + /// This headers resource is a child: it must be dropped before the parent + /// `outgoing-request` is dropped, or its ownership is transfered to + /// another component by e.g. `outgoing-handler.handle`. + headers: func() -> headers; } /// Parameters for making an HTTP Request. Each of these parameters is an @@ -180,10 +232,17 @@ interface types { /// This method consumes the `response-outparam` to ensure that it is /// called at most once. If it is never called, the implementation /// will respond with an error. + /// + /// The user may provide an `error` to `response` to allow the + /// implementation determine how to respond with an HTTP error response. + /// + /// This method may return an error when the `outgoing-response` contains + /// a `status-code` or anything else the implementation does not permit or + /// support. set: static func( param: response-outparam, response: result, - ); + ) -> result<_, error>; } /// This type corresponds to the HTTP standard Status Code. @@ -263,7 +322,22 @@ interface types { resource outgoing-response { /// Construct an `outgoing-response`. - constructor(status-code: status-code, headers: borrow); + /// + /// * `status-code` is the HTTP Status Code for the Response. + /// * `headers` is the HTTP Headers for the Response. + constructor(status-code: status-code, headers: headers); + + /// Get the HTTP Status Code for the Response. + status-code: func() -> status-code; + /// Set the HTTP Status Code for the Response. + set-status-code: func(status-code: status-code); + + /// Get the headers associated with the Request. + /// + /// This headers resource is a child: it must be dropped before the parent + /// `outgoing-request` is dropped, or its ownership is transfered to + /// another component by e.g. `outgoing-handler.handle`. + headers: func() -> headers; /// Returns the resource corresponding to the outgoing Body for this Response. /// From 9bee0786db6decdebf3280af3ec6d0022bbc7765 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 26 Oct 2023 16:43:48 -0700 Subject: [PATCH 1261/1772] update markdown --- proposals/http/proxy.md | 153 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 151 insertions(+), 2 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 5d27bd24d..748f8f872 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -872,13 +872,30 @@ return success at most once, and subsequent calls will return error.

    [constructor]outgoing-request: func

    Construct a new outgoing-request.

    +
      +
    • method represents the HTTP Method for the Request.
    • +
    • path-with-query is the combination of the HTTP Path and Query for +the Request. When none, this represents an empty Path and empty +Query.
    • +
    • scheme is the HTTP Related Scheme for the Request. When none, +the implementation may choose an appropriate default scheme.
    • +
    • authority is the HTTP Authority for the Request. A value of none +may be used with Related Schemes which do not require an Authority. +The HTTP and HTTPS schemes always require an authority.
    • +
    • headers is the HTTP Headers for the Request.
    • +
    +

    It is possible to construct, or manipulate with the accessor functions +below, an outgoing-request with an invalid combination of scheme +and authority, or headers which are not permitted to be sent. +It is the obligation of the outgoing-handler.handle implementation +to reject invalid constructions of outgoing-request.

    Params
    Return values

    [constructor]outgoing-response: func

    Construct an outgoing-response.

    +
      +
    • status-code is the HTTP Status Code for the Response.
    • +
    • headers is the HTTP Headers for the Response.
    • +
    Params
    Return values
    +

    [method]outgoing-response.status-code: func

    +

    Get the HTTP Status Code for the Response.

    +
    Params
    + +
    Return values
    + +

    [method]outgoing-response.set-status-code: func

    +

    Set the HTTP Status Code for the Response.

    +
    Params
    + +

    [method]outgoing-response.headers: func

    +

    Get the headers associated with the Request.

    +

    This headers resource is a child: it must be dropped before the parent +outgoing-request is dropped, or its ownership is transfered to +another component by e.g. outgoing-handler.handle.

    +
    Params
    + +
    Return values
    +

    [method]outgoing-response.body: func

    Returns the resource corresponding to the outgoing Body for this Response.

    Returns success on the first call: the outgoing-body resource for From f03fea670dd43f6b534e33a7421038abfa9046d6 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 31 Oct 2023 11:59:10 -0700 Subject: [PATCH 1262/1772] Introduce monotonic-clock duration (#53) * monotonic clock: introduce `duration` type, split `subscribe` We are introducing a `duration` type because it has a distinct meaning from `instant`: an `instant` can only be compared to other `instant`s from the exact same `monotonic-clock`, whereas a `duration` represents a duration of time which can be compared to any other duration of time. The `duration` type is motivated, in part, by a desire to reuse it to specify durations such as timeouts in other WASI proposals. Instead of taking a boolean specifying whether the u64 is an absolute or relative time, `subscribe-instant` takes an `instant` type and `subscribe-duration` takes a `duration` type. * generate markdown --- proposals/clocks/imports.md | 35 ++++++++++++++++++------ proposals/clocks/wit/monotonic-clock.wit | 26 +++++++++++++----- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index f82d3c1bb..1ec1fbeaa 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -62,7 +62,12 @@ successive reads of the clock will produce non-decreasing values.

    #### `type instant` `u64` -

    A timestamp in nanoseconds. +

    An instant in time, in nanoseconds. An instant is relative to an +unspecified initial value, and can only be compared to instances from +the same monotonic-clock. +

    type duration

    +

    u64

    +

    A duration of time, in nanoseconds.


    Functions

    now: func

    @@ -74,22 +79,34 @@ produce a sequence of non-decreasing values.

  • instant
  • resolution: func

    -

    Query the resolution of the clock.

    +

    Query the resolution of the clock. Returns the duration of time +corresponding to a clock tick.

    +
    Return values
    + +

    subscribe-instant: func

    +

    Create a pollable which will resolve once the specified instant +occured.

    +
    Params
    +
    Return values
    -

    subscribe: func

    -

    Create a pollable which will resolve once the specified time has been -reached.

    +

    subscribe-duration: func

    +

    Create a pollable which will resolve once the given duration has +elapsed, starting at the time at which this function was called. +occured.

    Params
    Return values

    Import interface wasi:clocks/wall-clock

    WASI Wall Clock is a clock API intended to let users query the current diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index d9ac7cb3f..afacdbb61 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -11,22 +11,34 @@ interface monotonic-clock { use wasi:io/poll.{pollable}; - /// A timestamp in nanoseconds. + /// An instant in time, in nanoseconds. An instant is relative to an + /// unspecified initial value, and can only be compared to instances from + /// the same monotonic-clock. type instant = u64; + /// A duration of time, in nanoseconds. + type duration = u64; + /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. now: func() -> instant; - /// Query the resolution of the clock. - resolution: func() -> instant; + /// Query the resolution of the clock. Returns the duration of time + /// corresponding to a clock tick. + resolution: func() -> duration; - /// Create a `pollable` which will resolve once the specified time has been - /// reached. - subscribe: func( + /// Create a `pollable` which will resolve once the specified instant + /// occured. + subscribe-instant: func( when: instant, - absolute: bool + ) -> pollable; + + /// Create a `pollable` which will resolve once the given duration has + /// elapsed, starting at the time at which this function was called. + /// occured. + subscribe-duration: func( + when: duration, ) -> pollable; } From ed5906f7e05299ff019532f1e5e57051d7f5bcd5 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 31 Oct 2023 12:53:57 -0700 Subject: [PATCH 1263/1772] pollable: add methods block & ready, rename poll-list to poll (#54) * rename `poll-one` to `pollable.block`, and add `ready` method The name `poll-one` is very easily confused with `poll-oneoff`, the previous name of `poll-list` during WASI preview 1 and much of the development of Preview 2. Inspecting if a poll is ready without blocking was requested in https://github.com/WebAssembly/wasi-io/issues/51 * rename `poll-list` to `poll` With `poll-one` renamed to `pollable.block`, there is no longer a distinction required between `poll-list` and `poll-one`, so change this name to the simplest name that can possibly work. --- proposals/io/imports.md | 34 +++++++++++++++++++++++----------- proposals/io/wit/poll.wit | 25 ++++++++++++++++--------- 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index 3f3866136..e08b326ad 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -15,7 +15,27 @@ at once.

    resource pollable


    Functions

    -

    poll-list: func

    +

    [method]pollable.ready: func

    +

    Return the readiness of a pollable. This function never blocks.

    +

    Returns true when the pollable is ready, and false otherwise.

    +
    Params
    + +
    Return values
    +
      +
    • bool
    • +
    +

    [method]pollable.block: func

    +

    block returns immediately if the pollable is ready, and otherwise +blocks until ready.

    +

    This function is equivalent to calling poll.poll on a list +containing only this pollable.

    +
    Params
    + +

    poll: func

    Poll for completion on a set of pollables.

    This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

    @@ -31,19 +51,11 @@ the pollables has an error, it is indicated by marking the source as being reaedy for I/O.

    Params
    Return values
      -
    • list<u32>
    • -
    -

    poll-one: func

    -

    Poll for completion on a single pollable.

    -

    This function is similar to poll-list, but operates on only a single -pollable. When it returns, the handle is ready for I/O.

    -
    Params
    -

    Import interface wasi:io/streams

    WASI I/O is an I/O abstraction API which is currently focused on providing diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index 254f53418..0829a7d08 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -3,8 +3,21 @@ package wasi:io; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { - /// A "pollable" handle. - resource pollable; + /// `pollable` epresents a single I/O event which may be ready, or not. + resource pollable { + + /// Return the readiness of a pollable. This function never blocks. + /// + /// Returns `true` when the pollable is ready, and `false` otherwise. + ready: func() -> bool; + + /// `block` returns immediately if the pollable is ready, and otherwise + /// blocks until ready. + /// + /// This function is equivalent to calling `poll.poll` on a list + /// containing only this pollable. + block: func(); + } /// Poll for completion on a set of pollables. /// @@ -24,11 +37,5 @@ interface poll { /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as /// being reaedy for I/O. - poll-list: func(in: list>) -> list; - - /// Poll for completion on a single pollable. - /// - /// This function is similar to `poll-list`, but operates on only a single - /// pollable. When it returns, the handle is ready for I/O. - poll-one: func(in: borrow); + poll: func(in: list>) -> list; } From 3fdaf3d3c955c26bc3ec4a0614ea574eb46a618f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 31 Oct 2023 16:04:02 -0700 Subject: [PATCH 1264/1772] Delete file locking methods from interface (#136) * types.wit: delete file locking methods We believe there is value in these lock methods for some applications (e.g. sqlite), but for the sake of shipping Preview 2, we don't have time to make and test a a cross platform implementation of these in two separate engines at this time. This is in part because some additional design work is required to integrate the blocking lock functions with pollable. These functions may come back as part of an additional filesystem interface in a post Preview 2 patch version 0.2.n, or in Preview 3 or beyond. Until then, their design is still in the git history. * generate markdown --- proposals/filesystem/imports.md | 105 ----------------------------- proposals/filesystem/wit/types.wit | 99 --------------------------- 2 files changed, 204 deletions(-) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index d5aab02e7..1ecf8e2db 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -1309,111 +1309,6 @@ flag. read on a directory implies readability and searchability, an

    -

    [method]descriptor.lock-shared: func

    -

    Request a shared advisory lock for an open file.

    -

    This requests a shared lock; more than one shared lock can be held for -a file at the same time.

    -

    If the open file has an exclusive lock, this function downgrades the lock -to a shared lock. If it has a shared lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified how shared locks interact with locks acquired by -non-WASI programs.

    -

    This function blocks until the lock can be acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_SH) in Unix.

    -
    Params
    - -
    Return values
    - -

    [method]descriptor.lock-exclusive: func

    -

    Request an exclusive advisory lock for an open file.

    -

    This requests an exclusive lock; no other locks may be held for the -file while an exclusive lock is held.

    -

    If the open file has a shared lock and there are no exclusive locks held -for the file, this function upgrades the lock to an exclusive lock. If the -open file already has an exclusive lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified whether this function succeeds if the file descriptor -is not opened for writing. It is unspecified how exclusive locks interact -with locks acquired by non-WASI programs.

    -

    This function blocks until the lock can be acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_EX) in Unix.

    -
    Params
    - -
    Return values
    - -

    [method]descriptor.try-lock-shared: func

    -

    Request a shared advisory lock for an open file.

    -

    This requests a shared lock; more than one shared lock can be held for -a file at the same time.

    -

    If the open file has an exclusive lock, this function downgrades the lock -to a shared lock. If it has a shared lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified how shared locks interact with locks acquired by -non-WASI programs.

    -

    This function returns error-code::would-block if the lock cannot be -acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

    -
    Params
    - -
    Return values
    - -

    [method]descriptor.try-lock-exclusive: func

    -

    Request an exclusive advisory lock for an open file.

    -

    This requests an exclusive lock; no other locks may be held for the -file while an exclusive lock is held.

    -

    If the open file has a shared lock and there are no exclusive locks held -for the file, this function upgrades the lock to an exclusive lock. If the -open file already has an exclusive lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified whether this function succeeds if the file descriptor -is not opened for writing. It is unspecified how exclusive locks interact -with locks acquired by non-WASI programs.

    -

    This function returns error-code::would-block if the lock cannot be -acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

    -
    Params
    - -
    Return values
    - -

    [method]descriptor.unlock: func

    -

    Release a shared or exclusive lock on an open file.

    -

    Note: This is similar to flock(fd, LOCK_UN) in Unix.

    -
    Params
    - -
    Return values
    -

    [method]descriptor.is-same-object: func

    Test whether two descriptors refer to the same filesystem object.

    In POSIX, this corresponds to testing whether the two descriptors have the diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 2050fb928..95afa3f28 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -650,105 +650,6 @@ interface types { modes: modes, ) -> result<_, error-code>; - /// Request a shared advisory lock for an open file. - /// - /// This requests a *shared* lock; more than one shared lock can be held for - /// a file at the same time. - /// - /// If the open file has an exclusive lock, this function downgrades the lock - /// to a shared lock. If it has a shared lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified how shared locks interact with locks acquired by - /// non-WASI programs. - /// - /// This function blocks until the lock can be acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. - lock-shared: func() -> result<_, error-code>; - - /// Request an exclusive advisory lock for an open file. - /// - /// This requests an *exclusive* lock; no other locks may be held for the - /// file while an exclusive lock is held. - /// - /// If the open file has a shared lock and there are no exclusive locks held - /// for the file, this function upgrades the lock to an exclusive lock. If the - /// open file already has an exclusive lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified whether this function succeeds if the file descriptor - /// is not opened for writing. It is unspecified how exclusive locks interact - /// with locks acquired by non-WASI programs. - /// - /// This function blocks until the lock can be acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. - lock-exclusive: func() -> result<_, error-code>; - - /// Request a shared advisory lock for an open file. - /// - /// This requests a *shared* lock; more than one shared lock can be held for - /// a file at the same time. - /// - /// If the open file has an exclusive lock, this function downgrades the lock - /// to a shared lock. If it has a shared lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified how shared locks interact with locks acquired by - /// non-WASI programs. - /// - /// This function returns `error-code::would-block` if the lock cannot be - /// acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. - try-lock-shared: func() -> result<_, error-code>; - - /// Request an exclusive advisory lock for an open file. - /// - /// This requests an *exclusive* lock; no other locks may be held for the - /// file while an exclusive lock is held. - /// - /// If the open file has a shared lock and there are no exclusive locks held - /// for the file, this function upgrades the lock to an exclusive lock. If the - /// open file already has an exclusive lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified whether this function succeeds if the file descriptor - /// is not opened for writing. It is unspecified how exclusive locks interact - /// with locks acquired by non-WASI programs. - /// - /// This function returns `error-code::would-block` if the lock cannot be - /// acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. - try-lock-exclusive: func() -> result<_, error-code>; - - /// Release a shared or exclusive lock on an open file. - /// - /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. - unlock: func() -> result<_, error-code>; - /// Test whether two descriptors refer to the same filesystem object. /// /// In POSIX, this corresponds to testing whether the two descriptors have the From d9091f07788b9d5a6e7622d5f71bb7914507c020 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 31 Oct 2023 16:04:15 -0700 Subject: [PATCH 1265/1772] Add `filesystem-error-code` for elaborating `stream.error` (#137) * wit-deps update to latest io streams.wit, which exposes `error` * add `filesystem-error-code`, for elaborating `stream.error` * generate markdown --- proposals/filesystem/imports.md | 174 +++++++++---------- proposals/filesystem/wit/deps.lock | 4 +- proposals/filesystem/wit/deps/io/streams.wit | 159 ++++++++--------- proposals/filesystem/wit/types.wit | 14 +- 4 files changed, 172 insertions(+), 179 deletions(-) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index 1ecf8e2db..a222bf84a 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -58,62 +58,55 @@ when it does, they are expected to subsume this API.

    type pollable

    pollable

    -#### `enum stream-status` -

    Streams provide a sequence of data and then end; once they end, they -no longer provide any further data.

    -

    For example, a stream reading from a file ends when the stream reaches -the end of the file. For another example, a stream reading from a -socket ends when the socket is closed.

    -
    Enum Cases
    -
      -
    • -

      open

      -

      The stream is open and may produce further data. -

    • -
    • -

      ended

      -

      When reading, this indicates that the stream will not produce -further data. -When writing, this indicates that the stream will no longer be read. -Further writes are still permitted. -

    • -
    -

    resource input-stream

    -

    enum write-error

    -

    An error for output-stream operations.

    -

    Contrary to input-streams, a closed output-stream is reported using -an error.

    -
    Enum Cases
    +#### `resource error` +

    variant stream-error

    +

    An error for input-stream and output-stream operations.

    +
    Variant Cases
    • -

      last-operation-failed

      +

      last-operation-failed: own<error>

      The last operation (a write or flush) failed before completion. +

      More information is available in the error payload.

    • -

      closed

      +

      closed

      The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

    +

    resource input-stream

    resource output-stream


    Functions

    +

    [method]error.to-debug-string: func

    +

    Returns a string that's suitable to assist humans in debugging this +error.

    +

    The returned string will change across platforms and hosts which +means that parsing it, for example, would be a +platform-compatibility hazard.

    +
    Params
    + +
    Return values
    +
      +
    • string
    • +

    [method]input-stream.read: func

    Perform a non-blocking read from the stream.

    -

    This function returns a list of bytes containing the data that was -read, along with a stream-status which, indicates whether further -reads are expected to produce data. The returned list will contain up to -len bytes; it may return fewer than requested, but not more. An -empty list and stream-status:open indicates no more data is -available at this time, and that the pollable given by subscribe -will be ready when more data is available.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report stream-status:ended rather than producing more -data.

    -

    When the caller gives a len of 0, it represents a request to read 0 -bytes. This read should always succeed and return an empty list and -the current stream-status.

    +

    This function returns a list of bytes containing the read data, +when successful. The returned list will contain up to len bytes; +it may return fewer than requested, but not more. The list is +empty when no bytes are available for reading at this time. The +pollable given by subscribe will be ready when more bytes are +available.

    +

    This function fails with a stream-error when the operation +encounters an error, giving last-operation-failed, or when the +stream is closed, giving closed.

    +

    When the caller gives a len of 0, it represents a request to +read 0 bytes. If the stream is still open, this call should +succeed and return an empty list, or otherwise fail with closed.

    The len parameter is a u64, which could represent a list of u8 which is not possible to allocate in wasm32, or not desirable to allocate as as a return value by the callee. The callee may return a list of bytes @@ -125,11 +118,11 @@ less than len in size while more bytes are available for reading.

    Return values

    [method]input-stream.blocking-read: func

    Read bytes from a stream, after blocking until at least one byte can -be read. Except for blocking, identical to read.

    +be read. Except for blocking, behavior is identical to read.

    Params
    • self: borrow<input-stream>
    • @@ -137,18 +130,12 @@ be read. Except for blocking, identical to read.

    Return values

    [method]input-stream.skip: func

    -

    Skip bytes from a stream.

    -

    This is similar to the read function, but avoids copying the -bytes into the instance.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

    -

    This function returns the number of bytes skipped, along with a -stream-status indicating whether the end of the stream was -reached. The returned value will be at most len; it may be less.

    +

    Skip bytes from a stream. Returns number of bytes skipped.

    +

    Behaves identical to read, except instead of returning a list +of bytes, returns the number of bytes consumed from the stream.

    Params
    Return values

    [method]output-stream.write: func

    Perform a write. This function never blocks.

    @@ -214,7 +201,7 @@ the last call to check-write provided a permit.

    Return values

    [method]output-stream.blocking-write-and-flush: func

    Perform a write of up to 4096 bytes, and then flush the stream. Block @@ -245,7 +232,7 @@ let _ = this.check-write(); // eliding error handling

    Return values

    [method]output-stream.flush: func

    Request to flush buffered output. This function never blocks.

    @@ -262,7 +249,7 @@ flush has completed and the stream can accept more writes.

    Return values

    [method]output-stream.blocking-flush: func

    Request to flush buffered output, and block until flush completes @@ -273,7 +260,7 @@ and stream is ready for writing again.

    Return values

    [method]output-stream.subscribe: func

    Create a pollable which will resolve once the output-stream @@ -305,7 +292,7 @@ that should be written.

    Return values

    [method]output-stream.blocking-write-zeroes-and-flush: func

    Perform a write of up to 4096 zeroes, and then flush the stream. @@ -336,56 +323,45 @@ let _ = this.check-write(); // eliding error handling

    Return values

    [method]output-stream.splice: func

    Read from one stream and write to another.

    +

    The behavior of splice is equivelant to:

    +
      +
    1. calling check-write on the output-stream
    2. +
    3. calling read on the input-stream with the smaller of the +check-write permitted length and the len provided to splice
    4. +
    5. calling write on the output-stream with that read data.
    6. +
    +

    Any error reported by the call to check-write, read, or +write ends the splice and reports that error.

    This function returns the number of bytes transferred; it may be less than len.

    -

    Unlike other I/O functions, this function blocks until all the data -read from the input stream has been written to the output stream.

    Params
    Return values

    [method]output-stream.blocking-splice: func

    Read from one stream and write to another, with blocking.

    -

    This is similar to splice, except that it blocks until at least -one byte can be read.

    +

    This is similar to splice, except that it blocks until the +output-stream is ready for writing, and the input-stream +is ready for reading, before performing the splice.

    Params
    Return values
    -

    [method]output-stream.forward: func

    -

    Forward the entire contents of an input stream to an output stream.

    -

    This function repeatedly reads from the input stream and writes -the data to the output stream, until the end of the input stream -is reached, or an error is encountered.

    -

    Unlike other I/O functions, this function blocks until the end -of the input stream is seen and all the data has been written to -the output stream.

    -

    This function returns the number of bytes transferred, and the status of -the output stream.

    -
    Params
    - -
    Return values
    -

    Import interface wasi:clocks/wall-clock

    WASI Wall Clock is a clock API intended to let users query the current @@ -454,6 +430,9 @@ underlying filesystem, the function fails with `type output-stream` [`output-stream`](#output_stream)

    +#### `type error` +[`error`](#error) +

    #### `type datetime` [`datetime`](#datetime)

    @@ -1374,6 +1353,23 @@ to by a directory descriptor and a relative path.

    +

    filesystem-error-code: func

    +

    Attempts to extract a filesystem-related error-code from the stream +error provided.

    +

    Stream operations which return stream-error::last-operation-failed +have a payload with more information about the operation that failed. +This payload can be passed through to this function to see if there's +filesystem-related information about the error to return.

    +

    Note that this function is fallible because not all stream-related +errors are filesystem-related errors.

    +
    Params
    + +
    Return values
    +

    Import interface wasi:filesystem/preopens


    Types

    diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index d8f03223a..7c506be5e 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -5,5 +5,5 @@ sha512 = "ef21339a60a3f4a37eb48ab81b411c1f2ed11c9b23da04d1e384c07dd4cc75f1a433ce [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "a00c29dd57dc224e8ce28b793b19c1b1001dcdbdc229ed451c3df1db91841b34" -sha512 = "8558085eeb5689209101cdfbc9782953d559ad14ce77260fe2f7cc472482d568f65cad9e6a688d40c634c6c54c608f27e27e481633446114d6fdead93d4e34c5" +sha256 = "027671996ef6e3bedd160a6ca6631184cf68d7b36497225316c1726a5d0eb078" +sha512 = "2a3fee2c5acc2091dec45a929ff3d857e75a1970fd64d2f3ce5faad2a0d5fb3df0ad8c5f09a97c1ade8c5986317993058d141a5922b19dfbdaf97041a9bde7aa" diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index cfeab0da1..8999b28d2 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -8,20 +8,36 @@ package wasi:io; interface streams { use poll.{pollable}; - /// Streams provide a sequence of data and then end; once they end, they - /// no longer provide any further data. + /// An error for input-stream and output-stream operations. + variant stream-error { + /// The last operation (a write or flush) failed before completion. + /// + /// More information is available in the `error` payload. + last-operation-failed(error), + /// The stream is closed: no more input will be accepted by the + /// stream. A closed output-stream will return this error on all + /// future operations. + closed + } + + /// Contextual error information about the last failure that happened on + /// a read, write, or flush from an `input-stream` or `output-stream`. + /// + /// This type is returned through the `stream-error` type whenever an + /// operation on a stream directly fails or an error is discovered + /// after-the-fact, for example when a write's failure shows up through a + /// later `flush` or `check-write`. /// - /// For example, a stream reading from a file ends when the stream reaches - /// the end of the file. For another example, a stream reading from a - /// socket ends when the socket is closed. - enum stream-status { - /// The stream is open and may produce further data. - open, - /// When reading, this indicates that the stream will not produce - /// further data. - /// When writing, this indicates that the stream will no longer be read. - /// Further writes are still permitted. - ended, + /// Interfaces such as `wasi:filesystem/types` provide functionality to + /// further "downcast" this error into interface-specific error information. + resource error { + /// Returns a string that's suitable to assist humans in debugging this + /// error. + /// + /// The returned string will change across platforms and hosts which + /// means that parsing it, for example, would be a + /// platform-compatibility hazard. + to-debug-string: func() -> string; } /// An input bytestream. @@ -35,21 +51,20 @@ interface streams { resource input-stream { /// Perform a non-blocking read from the stream. /// - /// This function returns a list of bytes containing the data that was - /// read, along with a `stream-status` which, indicates whether further - /// reads are expected to produce data. The returned list will contain up to - /// `len` bytes; it may return fewer than requested, but not more. An - /// empty list and `stream-status:open` indicates no more data is - /// available at this time, and that the pollable given by `subscribe` - /// will be ready when more data is available. + /// This function returns a list of bytes containing the read data, + /// when successful. The returned list will contain up to `len` bytes; + /// it may return fewer than requested, but not more. The list is + /// empty when no bytes are available for reading at this time. The + /// pollable given by `subscribe` will be ready when more bytes are + /// available. /// - /// Once a stream has reached the end, subsequent calls to `read` or - /// `skip` will always report `stream-status:ended` rather than producing more - /// data. + /// This function fails with a `stream-error` when the operation + /// encounters an error, giving `last-operation-failed`, or when the + /// stream is closed, giving `closed`. /// - /// When the caller gives a `len` of 0, it represents a request to read 0 - /// bytes. This read should always succeed and return an empty list and - /// the current `stream-status`. + /// When the caller gives a `len` of 0, it represents a request to + /// read 0 bytes. If the stream is still open, this call should + /// succeed and return an empty list, or otherwise fail with `closed`. /// /// The `len` parameter is a `u64`, which could represent a list of u8 which /// is not possible to allocate in wasm32, or not desirable to allocate as @@ -58,38 +73,30 @@ interface streams { read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>>; + ) -> result, stream-error>; /// Read bytes from a stream, after blocking until at least one byte can - /// be read. Except for blocking, identical to `read`. + /// be read. Except for blocking, behavior is identical to `read`. blocking-read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>>; + ) -> result, stream-error>; - /// Skip bytes from a stream. + /// Skip bytes from a stream. Returns number of bytes skipped. /// - /// This is similar to the `read` function, but avoids copying the - /// bytes into the instance. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// This function returns the number of bytes skipped, along with a - /// `stream-status` indicating whether the end of the stream was - /// reached. The returned value will be at most `len`; it may be less. + /// Behaves identical to `read`, except instead of returning a list + /// of bytes, returns the number of bytes consumed from the stream. skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result>; + ) -> result; /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. blocking-skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result>; + ) -> result; /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been @@ -100,18 +107,6 @@ interface streams { subscribe: func() -> pollable; } - /// An error for output-stream operations. - /// - /// Contrary to input-streams, a closed output-stream is reported using - /// an error. - enum write-error { - /// The last operation (a write or flush) failed before completion. - last-operation-failed, - /// The stream is closed: no more input will be accepted by the - /// stream. A closed output-stream will return this error on all - /// future operations. - closed - } /// An output bytestream. /// @@ -131,7 +126,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. - check-write: func() -> result; + check-write: func() -> result; /// Perform a write. This function never blocks. /// @@ -142,7 +137,7 @@ interface streams { /// the last call to check-write provided a permit. write: func( contents: list - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. @@ -170,7 +165,7 @@ interface streams { /// ``` blocking-write-and-flush: func( contents: list - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Request to flush buffered output. This function never blocks. /// @@ -182,11 +177,11 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. - flush: func() -> result<_, write-error>; + flush: func() -> result<_, stream-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. - blocking-flush: func() -> result<_, write-error>; + blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream /// is ready for more writing, or an error has occured. When this @@ -209,7 +204,7 @@ interface streams { write-zeroes: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Perform a write of up to 4096 zeroes, and then flush the stream. /// Block until all of these operations are complete, or an error @@ -238,48 +233,38 @@ interface streams { blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Read from one stream and write to another. /// + /// The behavior of splice is equivelant to: + /// 1. calling `check-write` on the `output-stream` + /// 2. calling `read` on the `input-stream` with the smaller of the + /// `check-write` permitted length and the `len` provided to `splice` + /// 3. calling `write` on the `output-stream` with that read data. + /// + /// Any error reported by the call to `check-write`, `read`, or + /// `write` ends the splice and reports that error. + /// /// This function returns the number of bytes transferred; it may be less /// than `len`. - /// - /// Unlike other I/O functions, this function blocks until all the data - /// read from the input stream has been written to the output stream. splice: func( /// The stream to read from - src: input-stream, + src: borrow, /// The number of bytes to splice len: u64, - ) -> result>; + ) -> result; /// Read from one stream and write to another, with blocking. /// - /// This is similar to `splice`, except that it blocks until at least - /// one byte can be read. + /// This is similar to `splice`, except that it blocks until the + /// `output-stream` is ready for writing, and the `input-stream` + /// is ready for reading, before performing the `splice`. blocking-splice: func( /// The stream to read from - src: input-stream, + src: borrow, /// The number of bytes to splice len: u64, - ) -> result>; - - /// Forward the entire contents of an input stream to an output stream. - /// - /// This function repeatedly reads from the input stream and writes - /// the data to the output stream, until the end of the input stream - /// is reached, or an error is encountered. - /// - /// Unlike other I/O functions, this function blocks until the end - /// of the input stream is seen and all the data has been written to - /// the output stream. - /// - /// This function returns the number of bytes transferred, and the status of - /// the output stream. - forward: func( - /// The stream to read from - src: input-stream - ) -> result>; + ) -> result; } } diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 95afa3f28..7ac147f66 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -23,7 +23,7 @@ /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { - use wasi:io/streams.{input-stream, output-stream}; + use wasi:io/streams.{input-stream, output-stream, error}; use wasi:clocks/wall-clock.{datetime}; /// File size or length of a region within a file. @@ -696,4 +696,16 @@ interface types { /// Read a single directory entry from a `directory-entry-stream`. read-directory-entry: func() -> result, error-code>; } + + /// Attempts to extract a filesystem-related `error-code` from the stream + /// `error` provided. + /// + /// Stream operations which return `stream-error::last-operation-failed` + /// have a payload with more information about the operation that failed. + /// This payload can be passed through to this function to see if there's + /// filesystem-related information about the error to return. + /// + /// Note that this function is fallible because not all stream-related + /// errors are filesystem-related errors. + filesystem-error-code: func(err: borrow) -> option; } From 53e31242c942d67094b11927971741531d66f2f5 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 31 Oct 2023 19:05:15 -0700 Subject: [PATCH 1266/1772] wit-deps update latest clocks and io --- proposals/filesystem/wit/deps.lock | 8 +++--- .../wit/deps/clocks/monotonic-clock.wit | 26 ++++++++++++++----- proposals/filesystem/wit/deps/io/poll.wit | 25 +++++++++++------- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index 7c506be5e..1c063bc54 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "74844f8bf1d356bb44aab64a2f917d7a3bcb6d6924662d2e3909aeabda01bea6" -sha512 = "ef21339a60a3f4a37eb48ab81b411c1f2ed11c9b23da04d1e384c07dd4cc75f1a433ce7b46201c693b7a59b51c73d888bc41c78ad204fe32d8a312a9f9a48eb0" +sha256 = "8d6b9f7a8bf9466bdc68043c33e054878fdf09c1cc69c19c99eeadd3bb257a90" +sha512 = "21b65d911930c4512bb3caa08459283fc70b1ccc5159313092334cffd6662fb92cfe90577b51829ef363e2d02530802c88f2a1f82db43964d1f8bff7ecbc794b" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "027671996ef6e3bedd160a6ca6631184cf68d7b36497225316c1726a5d0eb078" -sha512 = "2a3fee2c5acc2091dec45a929ff3d857e75a1970fd64d2f3ce5faad2a0d5fb3df0ad8c5f09a97c1ade8c5986317993058d141a5922b19dfbdaf97041a9bde7aa" +sha256 = "fb76f4449eea54d06b56fc6a7ca988da51bd84a54d2021cf18da67b5e2c7ebcf" +sha512 = "c005e2a91522958a9537827a49ae344e1cb39d66e85492901a86bcc7e322ba8d0a7f1a02c9b9f840c123b4ad97e297355fac98d4822536d1426d1096dd1d73ac" diff --git a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit index d9ac7cb3f..afacdbb61 100644 --- a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit @@ -11,22 +11,34 @@ interface monotonic-clock { use wasi:io/poll.{pollable}; - /// A timestamp in nanoseconds. + /// An instant in time, in nanoseconds. An instant is relative to an + /// unspecified initial value, and can only be compared to instances from + /// the same monotonic-clock. type instant = u64; + /// A duration of time, in nanoseconds. + type duration = u64; + /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. now: func() -> instant; - /// Query the resolution of the clock. - resolution: func() -> instant; + /// Query the resolution of the clock. Returns the duration of time + /// corresponding to a clock tick. + resolution: func() -> duration; - /// Create a `pollable` which will resolve once the specified time has been - /// reached. - subscribe: func( + /// Create a `pollable` which will resolve once the specified instant + /// occured. + subscribe-instant: func( when: instant, - absolute: bool + ) -> pollable; + + /// Create a `pollable` which will resolve once the given duration has + /// elapsed, starting at the time at which this function was called. + /// occured. + subscribe-duration: func( + when: duration, ) -> pollable; } diff --git a/proposals/filesystem/wit/deps/io/poll.wit b/proposals/filesystem/wit/deps/io/poll.wit index 254f53418..0829a7d08 100644 --- a/proposals/filesystem/wit/deps/io/poll.wit +++ b/proposals/filesystem/wit/deps/io/poll.wit @@ -3,8 +3,21 @@ package wasi:io; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { - /// A "pollable" handle. - resource pollable; + /// `pollable` epresents a single I/O event which may be ready, or not. + resource pollable { + + /// Return the readiness of a pollable. This function never blocks. + /// + /// Returns `true` when the pollable is ready, and `false` otherwise. + ready: func() -> bool; + + /// `block` returns immediately if the pollable is ready, and otherwise + /// blocks until ready. + /// + /// This function is equivalent to calling `poll.poll` on a list + /// containing only this pollable. + block: func(); + } /// Poll for completion on a set of pollables. /// @@ -24,11 +37,5 @@ interface poll { /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as /// being reaedy for I/O. - poll-list: func(in: list>) -> list; - - /// Poll for completion on a single pollable. - /// - /// This function is similar to `poll-list`, but operates on only a single - /// pollable. When it returns, the handle is ready for I/O. - poll-one: func(in: borrow); + poll: func(in: list>) -> list; } From b661531c2cde824da90b39ef3d478fe7fdaeaa4c Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 31 Oct 2023 19:05:30 -0700 Subject: [PATCH 1267/1772] generate markdown --- proposals/filesystem/imports.md | 34 ++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index a222bf84a..2cbf69054 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -18,7 +18,27 @@ at once.

    resource pollable


    Functions

    -

    poll-list: func

    +

    [method]pollable.ready: func

    +

    Return the readiness of a pollable. This function never blocks.

    +

    Returns true when the pollable is ready, and false otherwise.

    +
    Params
    + +
    Return values
    +
      +
    • bool
    • +
    +

    [method]pollable.block: func

    +

    block returns immediately if the pollable is ready, and otherwise +blocks until ready.

    +

    This function is equivalent to calling poll.poll on a list +containing only this pollable.

    +
    Params
    + +

    poll: func

    Poll for completion on a set of pollables.

    This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

    @@ -34,19 +54,11 @@ the pollables has an error, it is indicated by marking the source as being reaedy for I/O.

    Params
    Return values
      -
    • list<u32>
    • -
    -

    poll-one: func

    -

    Poll for completion on a single pollable.

    -

    This function is similar to poll-list, but operates on only a single -pollable. When it returns, the handle is ready for I/O.

    -
    Params
    -

    Import interface wasi:io/streams

    WASI I/O is an I/O abstraction API which is currently focused on providing From ebdf39451dbc08121f564a091395bba010f00e00 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 31 Oct 2023 19:06:47 -0700 Subject: [PATCH 1268/1772] wit-deps update latest io --- proposals/sockets/wit/deps.lock | 4 +- proposals/sockets/wit/deps/io/poll.wit | 25 ++-- proposals/sockets/wit/deps/io/streams.wit | 159 ++++++++++------------ 3 files changed, 90 insertions(+), 98 deletions(-) diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index e73913ba0..472b87f14 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "a00c29dd57dc224e8ce28b793b19c1b1001dcdbdc229ed451c3df1db91841b34" -sha512 = "8558085eeb5689209101cdfbc9782953d559ad14ce77260fe2f7cc472482d568f65cad9e6a688d40c634c6c54c608f27e27e481633446114d6fdead93d4e34c5" +sha256 = "fb76f4449eea54d06b56fc6a7ca988da51bd84a54d2021cf18da67b5e2c7ebcf" +sha512 = "c005e2a91522958a9537827a49ae344e1cb39d66e85492901a86bcc7e322ba8d0a7f1a02c9b9f840c123b4ad97e297355fac98d4822536d1426d1096dd1d73ac" diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit index 254f53418..0829a7d08 100644 --- a/proposals/sockets/wit/deps/io/poll.wit +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -3,8 +3,21 @@ package wasi:io; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { - /// A "pollable" handle. - resource pollable; + /// `pollable` epresents a single I/O event which may be ready, or not. + resource pollable { + + /// Return the readiness of a pollable. This function never blocks. + /// + /// Returns `true` when the pollable is ready, and `false` otherwise. + ready: func() -> bool; + + /// `block` returns immediately if the pollable is ready, and otherwise + /// blocks until ready. + /// + /// This function is equivalent to calling `poll.poll` on a list + /// containing only this pollable. + block: func(); + } /// Poll for completion on a set of pollables. /// @@ -24,11 +37,5 @@ interface poll { /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as /// being reaedy for I/O. - poll-list: func(in: list>) -> list; - - /// Poll for completion on a single pollable. - /// - /// This function is similar to `poll-list`, but operates on only a single - /// pollable. When it returns, the handle is ready for I/O. - poll-one: func(in: borrow); + poll: func(in: list>) -> list; } diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index cfeab0da1..8999b28d2 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -8,20 +8,36 @@ package wasi:io; interface streams { use poll.{pollable}; - /// Streams provide a sequence of data and then end; once they end, they - /// no longer provide any further data. + /// An error for input-stream and output-stream operations. + variant stream-error { + /// The last operation (a write or flush) failed before completion. + /// + /// More information is available in the `error` payload. + last-operation-failed(error), + /// The stream is closed: no more input will be accepted by the + /// stream. A closed output-stream will return this error on all + /// future operations. + closed + } + + /// Contextual error information about the last failure that happened on + /// a read, write, or flush from an `input-stream` or `output-stream`. + /// + /// This type is returned through the `stream-error` type whenever an + /// operation on a stream directly fails or an error is discovered + /// after-the-fact, for example when a write's failure shows up through a + /// later `flush` or `check-write`. /// - /// For example, a stream reading from a file ends when the stream reaches - /// the end of the file. For another example, a stream reading from a - /// socket ends when the socket is closed. - enum stream-status { - /// The stream is open and may produce further data. - open, - /// When reading, this indicates that the stream will not produce - /// further data. - /// When writing, this indicates that the stream will no longer be read. - /// Further writes are still permitted. - ended, + /// Interfaces such as `wasi:filesystem/types` provide functionality to + /// further "downcast" this error into interface-specific error information. + resource error { + /// Returns a string that's suitable to assist humans in debugging this + /// error. + /// + /// The returned string will change across platforms and hosts which + /// means that parsing it, for example, would be a + /// platform-compatibility hazard. + to-debug-string: func() -> string; } /// An input bytestream. @@ -35,21 +51,20 @@ interface streams { resource input-stream { /// Perform a non-blocking read from the stream. /// - /// This function returns a list of bytes containing the data that was - /// read, along with a `stream-status` which, indicates whether further - /// reads are expected to produce data. The returned list will contain up to - /// `len` bytes; it may return fewer than requested, but not more. An - /// empty list and `stream-status:open` indicates no more data is - /// available at this time, and that the pollable given by `subscribe` - /// will be ready when more data is available. + /// This function returns a list of bytes containing the read data, + /// when successful. The returned list will contain up to `len` bytes; + /// it may return fewer than requested, but not more. The list is + /// empty when no bytes are available for reading at this time. The + /// pollable given by `subscribe` will be ready when more bytes are + /// available. /// - /// Once a stream has reached the end, subsequent calls to `read` or - /// `skip` will always report `stream-status:ended` rather than producing more - /// data. + /// This function fails with a `stream-error` when the operation + /// encounters an error, giving `last-operation-failed`, or when the + /// stream is closed, giving `closed`. /// - /// When the caller gives a `len` of 0, it represents a request to read 0 - /// bytes. This read should always succeed and return an empty list and - /// the current `stream-status`. + /// When the caller gives a `len` of 0, it represents a request to + /// read 0 bytes. If the stream is still open, this call should + /// succeed and return an empty list, or otherwise fail with `closed`. /// /// The `len` parameter is a `u64`, which could represent a list of u8 which /// is not possible to allocate in wasm32, or not desirable to allocate as @@ -58,38 +73,30 @@ interface streams { read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>>; + ) -> result, stream-error>; /// Read bytes from a stream, after blocking until at least one byte can - /// be read. Except for blocking, identical to `read`. + /// be read. Except for blocking, behavior is identical to `read`. blocking-read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>>; + ) -> result, stream-error>; - /// Skip bytes from a stream. + /// Skip bytes from a stream. Returns number of bytes skipped. /// - /// This is similar to the `read` function, but avoids copying the - /// bytes into the instance. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// This function returns the number of bytes skipped, along with a - /// `stream-status` indicating whether the end of the stream was - /// reached. The returned value will be at most `len`; it may be less. + /// Behaves identical to `read`, except instead of returning a list + /// of bytes, returns the number of bytes consumed from the stream. skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result>; + ) -> result; /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. blocking-skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result>; + ) -> result; /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been @@ -100,18 +107,6 @@ interface streams { subscribe: func() -> pollable; } - /// An error for output-stream operations. - /// - /// Contrary to input-streams, a closed output-stream is reported using - /// an error. - enum write-error { - /// The last operation (a write or flush) failed before completion. - last-operation-failed, - /// The stream is closed: no more input will be accepted by the - /// stream. A closed output-stream will return this error on all - /// future operations. - closed - } /// An output bytestream. /// @@ -131,7 +126,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. - check-write: func() -> result; + check-write: func() -> result; /// Perform a write. This function never blocks. /// @@ -142,7 +137,7 @@ interface streams { /// the last call to check-write provided a permit. write: func( contents: list - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. @@ -170,7 +165,7 @@ interface streams { /// ``` blocking-write-and-flush: func( contents: list - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Request to flush buffered output. This function never blocks. /// @@ -182,11 +177,11 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. - flush: func() -> result<_, write-error>; + flush: func() -> result<_, stream-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. - blocking-flush: func() -> result<_, write-error>; + blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream /// is ready for more writing, or an error has occured. When this @@ -209,7 +204,7 @@ interface streams { write-zeroes: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Perform a write of up to 4096 zeroes, and then flush the stream. /// Block until all of these operations are complete, or an error @@ -238,48 +233,38 @@ interface streams { blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Read from one stream and write to another. /// + /// The behavior of splice is equivelant to: + /// 1. calling `check-write` on the `output-stream` + /// 2. calling `read` on the `input-stream` with the smaller of the + /// `check-write` permitted length and the `len` provided to `splice` + /// 3. calling `write` on the `output-stream` with that read data. + /// + /// Any error reported by the call to `check-write`, `read`, or + /// `write` ends the splice and reports that error. + /// /// This function returns the number of bytes transferred; it may be less /// than `len`. - /// - /// Unlike other I/O functions, this function blocks until all the data - /// read from the input stream has been written to the output stream. splice: func( /// The stream to read from - src: input-stream, + src: borrow, /// The number of bytes to splice len: u64, - ) -> result>; + ) -> result; /// Read from one stream and write to another, with blocking. /// - /// This is similar to `splice`, except that it blocks until at least - /// one byte can be read. + /// This is similar to `splice`, except that it blocks until the + /// `output-stream` is ready for writing, and the `input-stream` + /// is ready for reading, before performing the `splice`. blocking-splice: func( /// The stream to read from - src: input-stream, + src: borrow, /// The number of bytes to splice len: u64, - ) -> result>; - - /// Forward the entire contents of an input stream to an output stream. - /// - /// This function repeatedly reads from the input stream and writes - /// the data to the output stream, until the end of the input stream - /// is reached, or an error is encountered. - /// - /// Unlike other I/O functions, this function blocks until the end - /// of the input stream is seen and all the data has been written to - /// the output stream. - /// - /// This function returns the number of bytes transferred, and the status of - /// the output stream. - forward: func( - /// The stream to read from - src: input-stream - ) -> result>; + ) -> result; } } From 1446bdcd4c6f79250d2cf596d85472b4c0aeb470 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 31 Oct 2023 19:06:55 -0700 Subject: [PATCH 1269/1772] generate markdown --- proposals/sockets/imports.md | 188 ++++++++++++++++------------------- 1 file changed, 88 insertions(+), 100 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index c7c28400b..755596317 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -248,7 +248,27 @@ at once.

    resource pollable


    Functions

    -

    poll-list: func

    +

    [method]pollable.ready: func

    +

    Return the readiness of a pollable. This function never blocks.

    +

    Returns true when the pollable is ready, and false otherwise.

    +
    Params
    + +
    Return values
    +
      +
    • bool
    • +
    +

    [method]pollable.block: func

    +

    block returns immediately if the pollable is ready, and otherwise +blocks until ready.

    +

    This function is equivalent to calling poll.poll on a list +containing only this pollable.

    +
    Params
    + +

    poll: func

    Poll for completion on a set of pollables.

    This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

    @@ -264,19 +284,11 @@ the pollables has an error, it is indicated by marking the source as being reaedy for I/O.

    Params
    Return values
      -
    • list<u32>
    • -
    -

    poll-one: func

    -

    Poll for completion on a single pollable.

    -

    This function is similar to poll-list, but operates on only a single -pollable. When it returns, the handle is ready for I/O.

    -
    Params
    -

    Import interface wasi:sockets/udp


    @@ -695,62 +707,55 @@ when it does, they are expected to subsume this API.

    type pollable

    pollable

    -#### `enum stream-status` -

    Streams provide a sequence of data and then end; once they end, they -no longer provide any further data.

    -

    For example, a stream reading from a file ends when the stream reaches -the end of the file. For another example, a stream reading from a -socket ends when the socket is closed.

    -
    Enum Cases
    -
      -
    • -

      open

      -

      The stream is open and may produce further data. -

    • -
    • -

      ended

      -

      When reading, this indicates that the stream will not produce -further data. -When writing, this indicates that the stream will no longer be read. -Further writes are still permitted. -

    • -
    -

    resource input-stream

    -

    enum write-error

    -

    An error for output-stream operations.

    -

    Contrary to input-streams, a closed output-stream is reported using -an error.

    -
    Enum Cases
    +#### `resource error` +

    variant stream-error

    +

    An error for input-stream and output-stream operations.

    +
    Variant Cases
    • -

      last-operation-failed

      +

      last-operation-failed: own<error>

      The last operation (a write or flush) failed before completion. +

      More information is available in the error payload.

    • -

      closed

      +

      closed

      The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

    +

    resource input-stream

    resource output-stream


    Functions

    +

    [method]error.to-debug-string: func

    +

    Returns a string that's suitable to assist humans in debugging this +error.

    +

    The returned string will change across platforms and hosts which +means that parsing it, for example, would be a +platform-compatibility hazard.

    +
    Params
    + +
    Return values
    +
      +
    • string
    • +

    [method]input-stream.read: func

    Perform a non-blocking read from the stream.

    -

    This function returns a list of bytes containing the data that was -read, along with a stream-status which, indicates whether further -reads are expected to produce data. The returned list will contain up to -len bytes; it may return fewer than requested, but not more. An -empty list and stream-status:open indicates no more data is -available at this time, and that the pollable given by subscribe -will be ready when more data is available.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report stream-status:ended rather than producing more -data.

    -

    When the caller gives a len of 0, it represents a request to read 0 -bytes. This read should always succeed and return an empty list and -the current stream-status.

    +

    This function returns a list of bytes containing the read data, +when successful. The returned list will contain up to len bytes; +it may return fewer than requested, but not more. The list is +empty when no bytes are available for reading at this time. The +pollable given by subscribe will be ready when more bytes are +available.

    +

    This function fails with a stream-error when the operation +encounters an error, giving last-operation-failed, or when the +stream is closed, giving closed.

    +

    When the caller gives a len of 0, it represents a request to +read 0 bytes. If the stream is still open, this call should +succeed and return an empty list, or otherwise fail with closed.

    The len parameter is a u64, which could represent a list of u8 which is not possible to allocate in wasm32, or not desirable to allocate as as a return value by the callee. The callee may return a list of bytes @@ -762,11 +767,11 @@ less than len in size while more bytes are available for reading.

    Return values

    [method]input-stream.blocking-read: func

    Read bytes from a stream, after blocking until at least one byte can -be read. Except for blocking, identical to read.

    +be read. Except for blocking, behavior is identical to read.

    Params
    • self: borrow<input-stream>
    • @@ -774,18 +779,12 @@ be read. Except for blocking, identical to read.

    Return values

    [method]input-stream.skip: func

    -

    Skip bytes from a stream.

    -

    This is similar to the read function, but avoids copying the -bytes into the instance.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

    -

    This function returns the number of bytes skipped, along with a -stream-status indicating whether the end of the stream was -reached. The returned value will be at most len; it may be less.

    +

    Skip bytes from a stream. Returns number of bytes skipped.

    +

    Behaves identical to read, except instead of returning a list +of bytes, returns the number of bytes consumed from the stream.

    Params
    Return values

    [method]output-stream.write: func

    Perform a write. This function never blocks.

    @@ -851,7 +850,7 @@ the last call to check-write provided a permit.

    Return values

    [method]output-stream.blocking-write-and-flush: func

    Perform a write of up to 4096 bytes, and then flush the stream. Block @@ -882,7 +881,7 @@ let _ = this.check-write(); // eliding error handling

    Return values

    [method]output-stream.flush: func

    Request to flush buffered output. This function never blocks.

    @@ -899,7 +898,7 @@ flush has completed and the stream can accept more writes.

    Return values

    [method]output-stream.blocking-flush: func

    Request to flush buffered output, and block until flush completes @@ -910,7 +909,7 @@ and stream is ready for writing again.

    Return values

    [method]output-stream.subscribe: func

    Create a pollable which will resolve once the output-stream @@ -942,7 +941,7 @@ that should be written.

    Return values

    [method]output-stream.blocking-write-zeroes-and-flush: func

    Perform a write of up to 4096 zeroes, and then flush the stream. @@ -973,56 +972,45 @@ let _ = this.check-write(); // eliding error handling

    Return values

    [method]output-stream.splice: func

    Read from one stream and write to another.

    +

    The behavior of splice is equivelant to:

    +
      +
    1. calling check-write on the output-stream
    2. +
    3. calling read on the input-stream with the smaller of the +check-write permitted length and the len provided to splice
    4. +
    5. calling write on the output-stream with that read data.
    6. +
    +

    Any error reported by the call to check-write, read, or +write ends the splice and reports that error.

    This function returns the number of bytes transferred; it may be less than len.

    -

    Unlike other I/O functions, this function blocks until all the data -read from the input stream has been written to the output stream.

    Params
    Return values

    [method]output-stream.blocking-splice: func

    Read from one stream and write to another, with blocking.

    -

    This is similar to splice, except that it blocks until at least -one byte can be read.

    +

    This is similar to splice, except that it blocks until the +output-stream is ready for writing, and the input-stream +is ready for reading, before performing the splice.

    Params
    Return values
    -

    [method]output-stream.forward: func

    -

    Forward the entire contents of an input stream to an output stream.

    -

    This function repeatedly reads from the input stream and writes -the data to the output stream, until the end of the input stream -is reached, or an error is encountered.

    -

    Unlike other I/O functions, this function blocks until the end -of the input stream is seen and all the data has been written to -the output stream.

    -

    This function returns the number of bytes transferred, and the status of -the output stream.

    -
    Params
    - -
    Return values
    -

    Import interface wasi:sockets/tcp


    From e71713301d0d952c87822bafcbd788445b306917 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 31 Oct 2023 19:07:37 -0700 Subject: [PATCH 1270/1772] wit-deps update (#54) * wit-deps update * generate markdown --- proposals/clocks/imports.md | 34 +++-- proposals/clocks/wit/deps.lock | 4 +- proposals/clocks/wit/deps/io/poll.wit | 25 ++-- proposals/clocks/wit/deps/io/streams.wit | 159 ++++++++++------------- 4 files changed, 113 insertions(+), 109 deletions(-) diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index 1ec1fbeaa..0581792fd 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -17,7 +17,27 @@ at once.

    resource pollable


    Functions

    -

    poll-list: func

    +

    [method]pollable.ready: func

    +

    Return the readiness of a pollable. This function never blocks.

    +

    Returns true when the pollable is ready, and false otherwise.

    +
    Params
    + +
    Return values
    +
      +
    • bool
    • +
    +

    [method]pollable.block: func

    +

    block returns immediately if the pollable is ready, and otherwise +blocks until ready.

    +

    This function is equivalent to calling poll.poll on a list +containing only this pollable.

    +
    Params
    + +

    poll: func

    Poll for completion on a set of pollables.

    This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

    @@ -33,19 +53,11 @@ the pollables has an error, it is indicated by marking the source as being reaedy for I/O.

    Params
    Return values
      -
    • list<u32>
    • -
    -

    poll-one: func

    -

    Poll for completion on a single pollable.

    -

    This function is similar to poll-list, but operates on only a single -pollable. When it returns, the handle is ready for I/O.

    -
    Params
    -

    Import interface wasi:clocks/monotonic-clock

    WASI Monotonic Clock is a clock API intended to let users measure elapsed diff --git a/proposals/clocks/wit/deps.lock b/proposals/clocks/wit/deps.lock index e73913ba0..472b87f14 100644 --- a/proposals/clocks/wit/deps.lock +++ b/proposals/clocks/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "a00c29dd57dc224e8ce28b793b19c1b1001dcdbdc229ed451c3df1db91841b34" -sha512 = "8558085eeb5689209101cdfbc9782953d559ad14ce77260fe2f7cc472482d568f65cad9e6a688d40c634c6c54c608f27e27e481633446114d6fdead93d4e34c5" +sha256 = "fb76f4449eea54d06b56fc6a7ca988da51bd84a54d2021cf18da67b5e2c7ebcf" +sha512 = "c005e2a91522958a9537827a49ae344e1cb39d66e85492901a86bcc7e322ba8d0a7f1a02c9b9f840c123b4ad97e297355fac98d4822536d1426d1096dd1d73ac" diff --git a/proposals/clocks/wit/deps/io/poll.wit b/proposals/clocks/wit/deps/io/poll.wit index 254f53418..0829a7d08 100644 --- a/proposals/clocks/wit/deps/io/poll.wit +++ b/proposals/clocks/wit/deps/io/poll.wit @@ -3,8 +3,21 @@ package wasi:io; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { - /// A "pollable" handle. - resource pollable; + /// `pollable` epresents a single I/O event which may be ready, or not. + resource pollable { + + /// Return the readiness of a pollable. This function never blocks. + /// + /// Returns `true` when the pollable is ready, and `false` otherwise. + ready: func() -> bool; + + /// `block` returns immediately if the pollable is ready, and otherwise + /// blocks until ready. + /// + /// This function is equivalent to calling `poll.poll` on a list + /// containing only this pollable. + block: func(); + } /// Poll for completion on a set of pollables. /// @@ -24,11 +37,5 @@ interface poll { /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as /// being reaedy for I/O. - poll-list: func(in: list>) -> list; - - /// Poll for completion on a single pollable. - /// - /// This function is similar to `poll-list`, but operates on only a single - /// pollable. When it returns, the handle is ready for I/O. - poll-one: func(in: borrow); + poll: func(in: list>) -> list; } diff --git a/proposals/clocks/wit/deps/io/streams.wit b/proposals/clocks/wit/deps/io/streams.wit index cfeab0da1..8999b28d2 100644 --- a/proposals/clocks/wit/deps/io/streams.wit +++ b/proposals/clocks/wit/deps/io/streams.wit @@ -8,20 +8,36 @@ package wasi:io; interface streams { use poll.{pollable}; - /// Streams provide a sequence of data and then end; once they end, they - /// no longer provide any further data. + /// An error for input-stream and output-stream operations. + variant stream-error { + /// The last operation (a write or flush) failed before completion. + /// + /// More information is available in the `error` payload. + last-operation-failed(error), + /// The stream is closed: no more input will be accepted by the + /// stream. A closed output-stream will return this error on all + /// future operations. + closed + } + + /// Contextual error information about the last failure that happened on + /// a read, write, or flush from an `input-stream` or `output-stream`. + /// + /// This type is returned through the `stream-error` type whenever an + /// operation on a stream directly fails or an error is discovered + /// after-the-fact, for example when a write's failure shows up through a + /// later `flush` or `check-write`. /// - /// For example, a stream reading from a file ends when the stream reaches - /// the end of the file. For another example, a stream reading from a - /// socket ends when the socket is closed. - enum stream-status { - /// The stream is open and may produce further data. - open, - /// When reading, this indicates that the stream will not produce - /// further data. - /// When writing, this indicates that the stream will no longer be read. - /// Further writes are still permitted. - ended, + /// Interfaces such as `wasi:filesystem/types` provide functionality to + /// further "downcast" this error into interface-specific error information. + resource error { + /// Returns a string that's suitable to assist humans in debugging this + /// error. + /// + /// The returned string will change across platforms and hosts which + /// means that parsing it, for example, would be a + /// platform-compatibility hazard. + to-debug-string: func() -> string; } /// An input bytestream. @@ -35,21 +51,20 @@ interface streams { resource input-stream { /// Perform a non-blocking read from the stream. /// - /// This function returns a list of bytes containing the data that was - /// read, along with a `stream-status` which, indicates whether further - /// reads are expected to produce data. The returned list will contain up to - /// `len` bytes; it may return fewer than requested, but not more. An - /// empty list and `stream-status:open` indicates no more data is - /// available at this time, and that the pollable given by `subscribe` - /// will be ready when more data is available. + /// This function returns a list of bytes containing the read data, + /// when successful. The returned list will contain up to `len` bytes; + /// it may return fewer than requested, but not more. The list is + /// empty when no bytes are available for reading at this time. The + /// pollable given by `subscribe` will be ready when more bytes are + /// available. /// - /// Once a stream has reached the end, subsequent calls to `read` or - /// `skip` will always report `stream-status:ended` rather than producing more - /// data. + /// This function fails with a `stream-error` when the operation + /// encounters an error, giving `last-operation-failed`, or when the + /// stream is closed, giving `closed`. /// - /// When the caller gives a `len` of 0, it represents a request to read 0 - /// bytes. This read should always succeed and return an empty list and - /// the current `stream-status`. + /// When the caller gives a `len` of 0, it represents a request to + /// read 0 bytes. If the stream is still open, this call should + /// succeed and return an empty list, or otherwise fail with `closed`. /// /// The `len` parameter is a `u64`, which could represent a list of u8 which /// is not possible to allocate in wasm32, or not desirable to allocate as @@ -58,38 +73,30 @@ interface streams { read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>>; + ) -> result, stream-error>; /// Read bytes from a stream, after blocking until at least one byte can - /// be read. Except for blocking, identical to `read`. + /// be read. Except for blocking, behavior is identical to `read`. blocking-read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>>; + ) -> result, stream-error>; - /// Skip bytes from a stream. + /// Skip bytes from a stream. Returns number of bytes skipped. /// - /// This is similar to the `read` function, but avoids copying the - /// bytes into the instance. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// This function returns the number of bytes skipped, along with a - /// `stream-status` indicating whether the end of the stream was - /// reached. The returned value will be at most `len`; it may be less. + /// Behaves identical to `read`, except instead of returning a list + /// of bytes, returns the number of bytes consumed from the stream. skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result>; + ) -> result; /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. blocking-skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result>; + ) -> result; /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been @@ -100,18 +107,6 @@ interface streams { subscribe: func() -> pollable; } - /// An error for output-stream operations. - /// - /// Contrary to input-streams, a closed output-stream is reported using - /// an error. - enum write-error { - /// The last operation (a write or flush) failed before completion. - last-operation-failed, - /// The stream is closed: no more input will be accepted by the - /// stream. A closed output-stream will return this error on all - /// future operations. - closed - } /// An output bytestream. /// @@ -131,7 +126,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. - check-write: func() -> result; + check-write: func() -> result; /// Perform a write. This function never blocks. /// @@ -142,7 +137,7 @@ interface streams { /// the last call to check-write provided a permit. write: func( contents: list - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. @@ -170,7 +165,7 @@ interface streams { /// ``` blocking-write-and-flush: func( contents: list - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Request to flush buffered output. This function never blocks. /// @@ -182,11 +177,11 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. - flush: func() -> result<_, write-error>; + flush: func() -> result<_, stream-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. - blocking-flush: func() -> result<_, write-error>; + blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream /// is ready for more writing, or an error has occured. When this @@ -209,7 +204,7 @@ interface streams { write-zeroes: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Perform a write of up to 4096 zeroes, and then flush the stream. /// Block until all of these operations are complete, or an error @@ -238,48 +233,38 @@ interface streams { blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Read from one stream and write to another. /// + /// The behavior of splice is equivelant to: + /// 1. calling `check-write` on the `output-stream` + /// 2. calling `read` on the `input-stream` with the smaller of the + /// `check-write` permitted length and the `len` provided to `splice` + /// 3. calling `write` on the `output-stream` with that read data. + /// + /// Any error reported by the call to `check-write`, `read`, or + /// `write` ends the splice and reports that error. + /// /// This function returns the number of bytes transferred; it may be less /// than `len`. - /// - /// Unlike other I/O functions, this function blocks until all the data - /// read from the input stream has been written to the output stream. splice: func( /// The stream to read from - src: input-stream, + src: borrow, /// The number of bytes to splice len: u64, - ) -> result>; + ) -> result; /// Read from one stream and write to another, with blocking. /// - /// This is similar to `splice`, except that it blocks until at least - /// one byte can be read. + /// This is similar to `splice`, except that it blocks until the + /// `output-stream` is ready for writing, and the `input-stream` + /// is ready for reading, before performing the `splice`. blocking-splice: func( /// The stream to read from - src: input-stream, + src: borrow, /// The number of bytes to splice len: u64, - ) -> result>; - - /// Forward the entire contents of an input stream to an output stream. - /// - /// This function repeatedly reads from the input stream and writes - /// the data to the output stream, until the end of the input stream - /// is reached, or an error is encountered. - /// - /// Unlike other I/O functions, this function blocks until the end - /// of the input stream is seen and all the data has been written to - /// the output stream. - /// - /// This function returns the number of bytes transferred, and the status of - /// the output stream. - forward: func( - /// The stream to read from - src: input-stream - ) -> result>; + ) -> result; } } From 5121491e0276b970c793b0a17880663f54f9fda2 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 31 Oct 2023 19:10:52 -0700 Subject: [PATCH 1271/1772] wit-deps update --- proposals/cli/wit/deps.lock | 12 +- .../cli/wit/deps/clocks/monotonic-clock.wit | 26 ++- proposals/cli/wit/deps/filesystem/types.wit | 113 ++----------- proposals/cli/wit/deps/io/poll.wit | 25 ++- proposals/cli/wit/deps/io/streams.wit | 159 ++++++++---------- 5 files changed, 126 insertions(+), 209 deletions(-) diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index 45f1c5795..9996e3d03 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,17 +1,17 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "74844f8bf1d356bb44aab64a2f917d7a3bcb6d6924662d2e3909aeabda01bea6" -sha512 = "ef21339a60a3f4a37eb48ab81b411c1f2ed11c9b23da04d1e384c07dd4cc75f1a433ce7b46201c693b7a59b51c73d888bc41c78ad204fe32d8a312a9f9a48eb0" +sha256 = "8d6b9f7a8bf9466bdc68043c33e054878fdf09c1cc69c19c99eeadd3bb257a90" +sha512 = "21b65d911930c4512bb3caa08459283fc70b1ccc5159313092334cffd6662fb92cfe90577b51829ef363e2d02530802c88f2a1f82db43964d1f8bff7ecbc794b" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "ca8364780922eddd53ec77f9152c77486db3d7052f6a5902ccc1648d5494050c" -sha512 = "ef05d9d7d5c08bc6a701a65c5af1981f30b2eb5b1c3dc5ca39a69248be8ab7cb3b17c5d181a010149dd491846fa5a7ac4f9165b06e628f31227e02dbdd8b86f5" +sha256 = "c05155f44cf5798d15a16eaf9cdfb065d05914ed4710421a7448bb61c6decf3a" +sha512 = "fb30ea13678d3f3d2002b2cc1f6dae99ee6a06eae7c408c0d558f21e5039979dd80c8ced46b1a7629ce8b050820d81462093f7b4a733ff706d0258bf5dea5657" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "a00c29dd57dc224e8ce28b793b19c1b1001dcdbdc229ed451c3df1db91841b34" -sha512 = "8558085eeb5689209101cdfbc9782953d559ad14ce77260fe2f7cc472482d568f65cad9e6a688d40c634c6c54c608f27e27e481633446114d6fdead93d4e34c5" +sha256 = "fb76f4449eea54d06b56fc6a7ca988da51bd84a54d2021cf18da67b5e2c7ebcf" +sha512 = "c005e2a91522958a9537827a49ae344e1cb39d66e85492901a86bcc7e322ba8d0a7f1a02c9b9f840c123b4ad97e297355fac98d4822536d1426d1096dd1d73ac" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index d9ac7cb3f..afacdbb61 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -11,22 +11,34 @@ interface monotonic-clock { use wasi:io/poll.{pollable}; - /// A timestamp in nanoseconds. + /// An instant in time, in nanoseconds. An instant is relative to an + /// unspecified initial value, and can only be compared to instances from + /// the same monotonic-clock. type instant = u64; + /// A duration of time, in nanoseconds. + type duration = u64; + /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. now: func() -> instant; - /// Query the resolution of the clock. - resolution: func() -> instant; + /// Query the resolution of the clock. Returns the duration of time + /// corresponding to a clock tick. + resolution: func() -> duration; - /// Create a `pollable` which will resolve once the specified time has been - /// reached. - subscribe: func( + /// Create a `pollable` which will resolve once the specified instant + /// occured. + subscribe-instant: func( when: instant, - absolute: bool + ) -> pollable; + + /// Create a `pollable` which will resolve once the given duration has + /// elapsed, starting at the time at which this function was called. + /// occured. + subscribe-duration: func( + when: duration, ) -> pollable; } diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index 2050fb928..7ac147f66 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -23,7 +23,7 @@ /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { - use wasi:io/streams.{input-stream, output-stream}; + use wasi:io/streams.{input-stream, output-stream, error}; use wasi:clocks/wall-clock.{datetime}; /// File size or length of a region within a file. @@ -650,105 +650,6 @@ interface types { modes: modes, ) -> result<_, error-code>; - /// Request a shared advisory lock for an open file. - /// - /// This requests a *shared* lock; more than one shared lock can be held for - /// a file at the same time. - /// - /// If the open file has an exclusive lock, this function downgrades the lock - /// to a shared lock. If it has a shared lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified how shared locks interact with locks acquired by - /// non-WASI programs. - /// - /// This function blocks until the lock can be acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. - lock-shared: func() -> result<_, error-code>; - - /// Request an exclusive advisory lock for an open file. - /// - /// This requests an *exclusive* lock; no other locks may be held for the - /// file while an exclusive lock is held. - /// - /// If the open file has a shared lock and there are no exclusive locks held - /// for the file, this function upgrades the lock to an exclusive lock. If the - /// open file already has an exclusive lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified whether this function succeeds if the file descriptor - /// is not opened for writing. It is unspecified how exclusive locks interact - /// with locks acquired by non-WASI programs. - /// - /// This function blocks until the lock can be acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. - lock-exclusive: func() -> result<_, error-code>; - - /// Request a shared advisory lock for an open file. - /// - /// This requests a *shared* lock; more than one shared lock can be held for - /// a file at the same time. - /// - /// If the open file has an exclusive lock, this function downgrades the lock - /// to a shared lock. If it has a shared lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified how shared locks interact with locks acquired by - /// non-WASI programs. - /// - /// This function returns `error-code::would-block` if the lock cannot be - /// acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. - try-lock-shared: func() -> result<_, error-code>; - - /// Request an exclusive advisory lock for an open file. - /// - /// This requests an *exclusive* lock; no other locks may be held for the - /// file while an exclusive lock is held. - /// - /// If the open file has a shared lock and there are no exclusive locks held - /// for the file, this function upgrades the lock to an exclusive lock. If the - /// open file already has an exclusive lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified whether this function succeeds if the file descriptor - /// is not opened for writing. It is unspecified how exclusive locks interact - /// with locks acquired by non-WASI programs. - /// - /// This function returns `error-code::would-block` if the lock cannot be - /// acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. - try-lock-exclusive: func() -> result<_, error-code>; - - /// Release a shared or exclusive lock on an open file. - /// - /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. - unlock: func() -> result<_, error-code>; - /// Test whether two descriptors refer to the same filesystem object. /// /// In POSIX, this corresponds to testing whether the two descriptors have the @@ -795,4 +696,16 @@ interface types { /// Read a single directory entry from a `directory-entry-stream`. read-directory-entry: func() -> result, error-code>; } + + /// Attempts to extract a filesystem-related `error-code` from the stream + /// `error` provided. + /// + /// Stream operations which return `stream-error::last-operation-failed` + /// have a payload with more information about the operation that failed. + /// This payload can be passed through to this function to see if there's + /// filesystem-related information about the error to return. + /// + /// Note that this function is fallible because not all stream-related + /// errors are filesystem-related errors. + filesystem-error-code: func(err: borrow) -> option; } diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit index 254f53418..0829a7d08 100644 --- a/proposals/cli/wit/deps/io/poll.wit +++ b/proposals/cli/wit/deps/io/poll.wit @@ -3,8 +3,21 @@ package wasi:io; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { - /// A "pollable" handle. - resource pollable; + /// `pollable` epresents a single I/O event which may be ready, or not. + resource pollable { + + /// Return the readiness of a pollable. This function never blocks. + /// + /// Returns `true` when the pollable is ready, and `false` otherwise. + ready: func() -> bool; + + /// `block` returns immediately if the pollable is ready, and otherwise + /// blocks until ready. + /// + /// This function is equivalent to calling `poll.poll` on a list + /// containing only this pollable. + block: func(); + } /// Poll for completion on a set of pollables. /// @@ -24,11 +37,5 @@ interface poll { /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as /// being reaedy for I/O. - poll-list: func(in: list>) -> list; - - /// Poll for completion on a single pollable. - /// - /// This function is similar to `poll-list`, but operates on only a single - /// pollable. When it returns, the handle is ready for I/O. - poll-one: func(in: borrow); + poll: func(in: list>) -> list; } diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index cfeab0da1..8999b28d2 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -8,20 +8,36 @@ package wasi:io; interface streams { use poll.{pollable}; - /// Streams provide a sequence of data and then end; once they end, they - /// no longer provide any further data. + /// An error for input-stream and output-stream operations. + variant stream-error { + /// The last operation (a write or flush) failed before completion. + /// + /// More information is available in the `error` payload. + last-operation-failed(error), + /// The stream is closed: no more input will be accepted by the + /// stream. A closed output-stream will return this error on all + /// future operations. + closed + } + + /// Contextual error information about the last failure that happened on + /// a read, write, or flush from an `input-stream` or `output-stream`. + /// + /// This type is returned through the `stream-error` type whenever an + /// operation on a stream directly fails or an error is discovered + /// after-the-fact, for example when a write's failure shows up through a + /// later `flush` or `check-write`. /// - /// For example, a stream reading from a file ends when the stream reaches - /// the end of the file. For another example, a stream reading from a - /// socket ends when the socket is closed. - enum stream-status { - /// The stream is open and may produce further data. - open, - /// When reading, this indicates that the stream will not produce - /// further data. - /// When writing, this indicates that the stream will no longer be read. - /// Further writes are still permitted. - ended, + /// Interfaces such as `wasi:filesystem/types` provide functionality to + /// further "downcast" this error into interface-specific error information. + resource error { + /// Returns a string that's suitable to assist humans in debugging this + /// error. + /// + /// The returned string will change across platforms and hosts which + /// means that parsing it, for example, would be a + /// platform-compatibility hazard. + to-debug-string: func() -> string; } /// An input bytestream. @@ -35,21 +51,20 @@ interface streams { resource input-stream { /// Perform a non-blocking read from the stream. /// - /// This function returns a list of bytes containing the data that was - /// read, along with a `stream-status` which, indicates whether further - /// reads are expected to produce data. The returned list will contain up to - /// `len` bytes; it may return fewer than requested, but not more. An - /// empty list and `stream-status:open` indicates no more data is - /// available at this time, and that the pollable given by `subscribe` - /// will be ready when more data is available. + /// This function returns a list of bytes containing the read data, + /// when successful. The returned list will contain up to `len` bytes; + /// it may return fewer than requested, but not more. The list is + /// empty when no bytes are available for reading at this time. The + /// pollable given by `subscribe` will be ready when more bytes are + /// available. /// - /// Once a stream has reached the end, subsequent calls to `read` or - /// `skip` will always report `stream-status:ended` rather than producing more - /// data. + /// This function fails with a `stream-error` when the operation + /// encounters an error, giving `last-operation-failed`, or when the + /// stream is closed, giving `closed`. /// - /// When the caller gives a `len` of 0, it represents a request to read 0 - /// bytes. This read should always succeed and return an empty list and - /// the current `stream-status`. + /// When the caller gives a `len` of 0, it represents a request to + /// read 0 bytes. If the stream is still open, this call should + /// succeed and return an empty list, or otherwise fail with `closed`. /// /// The `len` parameter is a `u64`, which could represent a list of u8 which /// is not possible to allocate in wasm32, or not desirable to allocate as @@ -58,38 +73,30 @@ interface streams { read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>>; + ) -> result, stream-error>; /// Read bytes from a stream, after blocking until at least one byte can - /// be read. Except for blocking, identical to `read`. + /// be read. Except for blocking, behavior is identical to `read`. blocking-read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>>; + ) -> result, stream-error>; - /// Skip bytes from a stream. + /// Skip bytes from a stream. Returns number of bytes skipped. /// - /// This is similar to the `read` function, but avoids copying the - /// bytes into the instance. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// This function returns the number of bytes skipped, along with a - /// `stream-status` indicating whether the end of the stream was - /// reached. The returned value will be at most `len`; it may be less. + /// Behaves identical to `read`, except instead of returning a list + /// of bytes, returns the number of bytes consumed from the stream. skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result>; + ) -> result; /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. blocking-skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result>; + ) -> result; /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been @@ -100,18 +107,6 @@ interface streams { subscribe: func() -> pollable; } - /// An error for output-stream operations. - /// - /// Contrary to input-streams, a closed output-stream is reported using - /// an error. - enum write-error { - /// The last operation (a write or flush) failed before completion. - last-operation-failed, - /// The stream is closed: no more input will be accepted by the - /// stream. A closed output-stream will return this error on all - /// future operations. - closed - } /// An output bytestream. /// @@ -131,7 +126,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. - check-write: func() -> result; + check-write: func() -> result; /// Perform a write. This function never blocks. /// @@ -142,7 +137,7 @@ interface streams { /// the last call to check-write provided a permit. write: func( contents: list - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. @@ -170,7 +165,7 @@ interface streams { /// ``` blocking-write-and-flush: func( contents: list - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Request to flush buffered output. This function never blocks. /// @@ -182,11 +177,11 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. - flush: func() -> result<_, write-error>; + flush: func() -> result<_, stream-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. - blocking-flush: func() -> result<_, write-error>; + blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream /// is ready for more writing, or an error has occured. When this @@ -209,7 +204,7 @@ interface streams { write-zeroes: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Perform a write of up to 4096 zeroes, and then flush the stream. /// Block until all of these operations are complete, or an error @@ -238,48 +233,38 @@ interface streams { blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Read from one stream and write to another. /// + /// The behavior of splice is equivelant to: + /// 1. calling `check-write` on the `output-stream` + /// 2. calling `read` on the `input-stream` with the smaller of the + /// `check-write` permitted length and the `len` provided to `splice` + /// 3. calling `write` on the `output-stream` with that read data. + /// + /// Any error reported by the call to `check-write`, `read`, or + /// `write` ends the splice and reports that error. + /// /// This function returns the number of bytes transferred; it may be less /// than `len`. - /// - /// Unlike other I/O functions, this function blocks until all the data - /// read from the input stream has been written to the output stream. splice: func( /// The stream to read from - src: input-stream, + src: borrow, /// The number of bytes to splice len: u64, - ) -> result>; + ) -> result; /// Read from one stream and write to another, with blocking. /// - /// This is similar to `splice`, except that it blocks until at least - /// one byte can be read. + /// This is similar to `splice`, except that it blocks until the + /// `output-stream` is ready for writing, and the `input-stream` + /// is ready for reading, before performing the `splice`. blocking-splice: func( /// The stream to read from - src: input-stream, + src: borrow, /// The number of bytes to splice len: u64, - ) -> result>; - - /// Forward the entire contents of an input stream to an output stream. - /// - /// This function repeatedly reads from the input stream and writes - /// the data to the output stream, until the end of the input stream - /// is reached, or an error is encountered. - /// - /// Unlike other I/O functions, this function blocks until the end - /// of the input stream is seen and all the data has been written to - /// the output stream. - /// - /// This function returns the number of bytes transferred, and the status of - /// the output stream. - forward: func( - /// The stream to read from - src: input-stream - ) -> result>; + ) -> result; } } From 126c0fcda9b40be3a1fb961bfe517bf296d5ad35 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 31 Oct 2023 19:11:48 -0700 Subject: [PATCH 1272/1772] generate markdown --- proposals/cli/command.md | 356 +++++++++++++++------------------------ proposals/cli/reactor.md | 356 +++++++++++++++------------------------ 2 files changed, 276 insertions(+), 436 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index d72a3fc06..4c9ead44c 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -86,7 +86,27 @@ at once.

    resource pollable


    Functions

    -

    poll-list: func

    +

    [method]pollable.ready: func

    +

    Return the readiness of a pollable. This function never blocks.

    +

    Returns true when the pollable is ready, and false otherwise.

    +
    Params
    + +
    Return values
    +
      +
    • bool
    • +
    +

    [method]pollable.block: func

    +

    block returns immediately if the pollable is ready, and otherwise +blocks until ready.

    +

    This function is equivalent to calling poll.poll on a list +containing only this pollable.

    +
    Params
    + +

    poll: func

    Poll for completion on a set of pollables.

    This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

    @@ -102,19 +122,11 @@ the pollables has an error, it is indicated by marking the source as being reaedy for I/O.

    Params
    Return values
      -
    • list<u32>
    • -
    -

    poll-one: func

    -

    Poll for completion on a single pollable.

    -

    This function is similar to poll-list, but operates on only a single -pollable. When it returns, the handle is ready for I/O.

    -
    Params
    -

    Import interface wasi:clocks/monotonic-clock

    WASI Monotonic Clock is a clock API intended to let users measure elapsed @@ -131,7 +143,12 @@ successive reads of the clock will produce non-decreasing values.

    #### `type instant` `u64` -

    A timestamp in nanoseconds. +

    An instant in time, in nanoseconds. An instant is relative to an +unspecified initial value, and can only be compared to instances from +the same monotonic-clock. +

    type duration

    +

    u64

    +

    A duration of time, in nanoseconds.


    Functions

    now: func

    @@ -143,22 +160,34 @@ produce a sequence of non-decreasing values.

  • instant
  • resolution: func

    -

    Query the resolution of the clock.

    +

    Query the resolution of the clock. Returns the duration of time +corresponding to a clock tick.

    +
    Return values
    + +

    subscribe-instant: func

    +

    Create a pollable which will resolve once the specified instant +occured.

    +
    Params
    +
    Return values
    -

    subscribe: func

    -

    Create a pollable which will resolve once the specified time has been -reached.

    +

    subscribe-duration: func

    +

    Create a pollable which will resolve once the given duration has +elapsed, starting at the time at which this function was called. +occured.

    Params
    Return values

    Import interface wasi:clocks/timezone


    @@ -235,62 +264,55 @@ when it does, they are expected to subsume this API.

    type pollable

    pollable

    -#### `enum stream-status` -

    Streams provide a sequence of data and then end; once they end, they -no longer provide any further data.

    -

    For example, a stream reading from a file ends when the stream reaches -the end of the file. For another example, a stream reading from a -socket ends when the socket is closed.

    -
    Enum Cases
    -
      -
    • -

      open

      -

      The stream is open and may produce further data. -

    • -
    • -

      ended

      -

      When reading, this indicates that the stream will not produce -further data. -When writing, this indicates that the stream will no longer be read. -Further writes are still permitted. -

    • -
    -

    resource input-stream

    -

    enum write-error

    -

    An error for output-stream operations.

    -

    Contrary to input-streams, a closed output-stream is reported using -an error.

    -
    Enum Cases
    +#### `resource error` +

    variant stream-error

    +

    An error for input-stream and output-stream operations.

    +
    Variant Cases
    • -

      last-operation-failed

      +

      last-operation-failed: own<error>

      The last operation (a write or flush) failed before completion. +

      More information is available in the error payload.

    • -

      closed

      +

      closed

      The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

    +

    resource input-stream

    resource output-stream


    Functions

    +

    [method]error.to-debug-string: func

    +

    Returns a string that's suitable to assist humans in debugging this +error.

    +

    The returned string will change across platforms and hosts which +means that parsing it, for example, would be a +platform-compatibility hazard.

    +
    Params
    + +
    Return values
    +
      +
    • string
    • +

    [method]input-stream.read: func

    Perform a non-blocking read from the stream.

    -

    This function returns a list of bytes containing the data that was -read, along with a stream-status which, indicates whether further -reads are expected to produce data. The returned list will contain up to -len bytes; it may return fewer than requested, but not more. An -empty list and stream-status:open indicates no more data is -available at this time, and that the pollable given by subscribe -will be ready when more data is available.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report stream-status:ended rather than producing more -data.

    -

    When the caller gives a len of 0, it represents a request to read 0 -bytes. This read should always succeed and return an empty list and -the current stream-status.

    +

    This function returns a list of bytes containing the read data, +when successful. The returned list will contain up to len bytes; +it may return fewer than requested, but not more. The list is +empty when no bytes are available for reading at this time. The +pollable given by subscribe will be ready when more bytes are +available.

    +

    This function fails with a stream-error when the operation +encounters an error, giving last-operation-failed, or when the +stream is closed, giving closed.

    +

    When the caller gives a len of 0, it represents a request to +read 0 bytes. If the stream is still open, this call should +succeed and return an empty list, or otherwise fail with closed.

    The len parameter is a u64, which could represent a list of u8 which is not possible to allocate in wasm32, or not desirable to allocate as as a return value by the callee. The callee may return a list of bytes @@ -302,11 +324,11 @@ less than len in size while more bytes are available for reading.

    Return values

    [method]input-stream.blocking-read: func

    Read bytes from a stream, after blocking until at least one byte can -be read. Except for blocking, identical to read.

    +be read. Except for blocking, behavior is identical to read.

    Params
    • self: borrow<input-stream>
    • @@ -314,18 +336,12 @@ be read. Except for blocking, identical to read.

    Return values

    [method]input-stream.skip: func

    -

    Skip bytes from a stream.

    -

    This is similar to the read function, but avoids copying the -bytes into the instance.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

    -

    This function returns the number of bytes skipped, along with a -stream-status indicating whether the end of the stream was -reached. The returned value will be at most len; it may be less.

    +

    Skip bytes from a stream. Returns number of bytes skipped.

    +

    Behaves identical to read, except instead of returning a list +of bytes, returns the number of bytes consumed from the stream.

    Params
    • self: borrow<input-stream>
    • @@ -333,7 +349,7 @@ reached. The returned value will be at most len; it may be less.

      Return values

      [method]input-stream.blocking-skip: func

      Skip bytes from a stream, after blocking until at least one byte @@ -345,7 +361,7 @@ can be skipped. Except for blocking behavior, identical to skip.

      Return values

      [method]input-stream.subscribe: func

      Create a pollable which will resolve once either the specified stream @@ -367,7 +383,7 @@ all derived pollables created with this fun

      Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has permitted will trap.

      -

      When this function returns 0 bytes, the subscribe pollable will +

      When this function returns 0 bytes, the subscribe pollable will become ready when this function will report at least 1 byte, or an error.

      Params
      @@ -376,7 +392,7 @@ error.

    Return values

    [method]output-stream.write: func

    Perform a write. This function never blocks.

    @@ -391,13 +407,13 @@ the last call to check-write provided a permit.

    Return values

    [method]output-stream.blocking-write-and-flush: func

    Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

    This is a convenience wrapper around the use of check-write, -subscribe, write, and flush, and is implemented with the +subscribe, write, and flush, and is implemented with the following pseudo-code:

    let pollable = this.subscribe();
     while !contents.is_empty() {
    @@ -422,7 +438,7 @@ let _ = this.check-write();         // eliding error handling
     
     
    Return values

    [method]output-stream.flush: func

    Request to flush buffered output. This function never blocks.

    @@ -431,7 +447,7 @@ output to be flushed. the output which is expected to be flushed is all that has been passed to write prior to this call.

    Upon calling this function, the output-stream will not accept any writes (check-write will return ok(0)) until the flush has -completed. The subscribe pollable will become ready when the +completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

    Params
      @@ -439,7 +455,7 @@ flush has completed and the stream can accept more writes.

    Return values

    [method]output-stream.blocking-flush: func

    Request to flush buffered output, and block until flush completes @@ -450,7 +466,7 @@ and stream is ready for writing again.

    Return values

    [method]output-stream.subscribe: func

    Create a pollable which will resolve once the output-stream @@ -482,14 +498,14 @@ that should be written.

    Return values

    [method]output-stream.blocking-write-zeroes-and-flush: func

    Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

    This is a convenience wrapper around the use of check-write, -subscribe, write-zeroes, and flush, and is implemented with +subscribe, write-zeroes, and flush, and is implemented with the following pseudo-code:

    let pollable = this.subscribe();
     while num_zeroes != 0 {
    @@ -513,56 +529,45 @@ let _ = this.check-write();         // eliding error handling
     
     
    Return values

    [method]output-stream.splice: func

    Read from one stream and write to another.

    +

    The behavior of splice is equivelant to:

    +
      +
    1. calling check-write on the output-stream
    2. +
    3. calling read on the input-stream with the smaller of the +check-write permitted length and the len provided to splice
    4. +
    5. calling write on the output-stream with that read data.
    6. +
    +

    Any error reported by the call to check-write, read, or +write ends the splice and reports that error.

    This function returns the number of bytes transferred; it may be less than len.

    -

    Unlike other I/O functions, this function blocks until all the data -read from the input stream has been written to the output stream.

    Params
    Return values

    [method]output-stream.blocking-splice: func

    Read from one stream and write to another, with blocking.

    -

    This is similar to splice, except that it blocks until at least -one byte can be read.

    +

    This is similar to splice, except that it blocks until the +output-stream is ready for writing, and the input-stream +is ready for reading, before performing the splice.

    Params
    Return values
    -

    [method]output-stream.forward: func

    -

    Forward the entire contents of an input stream to an output stream.

    -

    This function repeatedly reads from the input stream and writes -the data to the output stream, until the end of the input stream -is reached, or an error is encountered.

    -

    Unlike other I/O functions, this function blocks until the end -of the input stream is seen and all the data has been written to -the output stream.

    -

    This function returns the number of bytes transferred, and the status of -the output stream.

    -
    Params
    - -
    Return values
    -

    Import interface wasi:filesystem/types

    WASI filesystem is a filesystem API primarily intended to let users run WASI @@ -590,6 +595,9 @@ underlying filesystem, the function fails with `type output-stream` [`output-stream`](#output_stream)

    +#### `type error` +[`error`](#error) +

    #### `type datetime` [`datetime`](#datetime)

    @@ -1445,111 +1453,6 @@ flag. read on a directory implies readability and searchability, an

    -

    [method]descriptor.lock-shared: func

    -

    Request a shared advisory lock for an open file.

    -

    This requests a shared lock; more than one shared lock can be held for -a file at the same time.

    -

    If the open file has an exclusive lock, this function downgrades the lock -to a shared lock. If it has a shared lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified how shared locks interact with locks acquired by -non-WASI programs.

    -

    This function blocks until the lock can be acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_SH) in Unix.

    -
    Params
    - -
    Return values
    - -

    [method]descriptor.lock-exclusive: func

    -

    Request an exclusive advisory lock for an open file.

    -

    This requests an exclusive lock; no other locks may be held for the -file while an exclusive lock is held.

    -

    If the open file has a shared lock and there are no exclusive locks held -for the file, this function upgrades the lock to an exclusive lock. If the -open file already has an exclusive lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified whether this function succeeds if the file descriptor -is not opened for writing. It is unspecified how exclusive locks interact -with locks acquired by non-WASI programs.

    -

    This function blocks until the lock can be acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_EX) in Unix.

    -
    Params
    - -
    Return values
    - -

    [method]descriptor.try-lock-shared: func

    -

    Request a shared advisory lock for an open file.

    -

    This requests a shared lock; more than one shared lock can be held for -a file at the same time.

    -

    If the open file has an exclusive lock, this function downgrades the lock -to a shared lock. If it has a shared lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified how shared locks interact with locks acquired by -non-WASI programs.

    -

    This function returns error-code::would-block if the lock cannot be -acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

    -
    Params
    - -
    Return values
    - -

    [method]descriptor.try-lock-exclusive: func

    -

    Request an exclusive advisory lock for an open file.

    -

    This requests an exclusive lock; no other locks may be held for the -file while an exclusive lock is held.

    -

    If the open file has a shared lock and there are no exclusive locks held -for the file, this function upgrades the lock to an exclusive lock. If the -open file already has an exclusive lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified whether this function succeeds if the file descriptor -is not opened for writing. It is unspecified how exclusive locks interact -with locks acquired by non-WASI programs.

    -

    This function returns error-code::would-block if the lock cannot be -acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

    -
    Params
    - -
    Return values
    - -

    [method]descriptor.unlock: func

    -

    Release a shared or exclusive lock on an open file.

    -

    Note: This is similar to flock(fd, LOCK_UN) in Unix.

    -
    Params
    - -
    Return values
    -

    [method]descriptor.is-same-object: func

    Test whether two descriptors refer to the same filesystem object.

    In POSIX, this corresponds to testing whether the two descriptors have the @@ -1615,6 +1518,23 @@ to by a directory descriptor and a relative path.

    +

    filesystem-error-code: func

    +

    Attempts to extract a filesystem-related error-code from the stream +error provided.

    +

    Stream operations which return stream-error::last-operation-failed +have a payload with more information about the operation that failed. +This payload can be passed through to this function to see if there's +filesystem-related information about the error to return.

    +

    Note that this function is fallible because not all stream-related +errors are filesystem-related errors.

    +
    Params
    + +
    Return values
    +

    Import interface wasi:filesystem/preopens


    Types

    diff --git a/proposals/cli/reactor.md b/proposals/cli/reactor.md index ccba58da4..d85c0efaf 100644 --- a/proposals/cli/reactor.md +++ b/proposals/cli/reactor.md @@ -81,7 +81,27 @@ at once.

    resource pollable


    Functions

    -

    poll-list: func

    +

    [method]pollable.ready: func

    +

    Return the readiness of a pollable. This function never blocks.

    +

    Returns true when the pollable is ready, and false otherwise.

    +
    Params
    + +
    Return values
    +
      +
    • bool
    • +
    +

    [method]pollable.block: func

    +

    block returns immediately if the pollable is ready, and otherwise +blocks until ready.

    +

    This function is equivalent to calling poll.poll on a list +containing only this pollable.

    +
    Params
    + +

    poll: func

    Poll for completion on a set of pollables.

    This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

    @@ -97,19 +117,11 @@ the pollables has an error, it is indicated by marking the source as being reaedy for I/O.

    Params
    Return values
      -
    • list<u32>
    • -
    -

    poll-one: func

    -

    Poll for completion on a single pollable.

    -

    This function is similar to poll-list, but operates on only a single -pollable. When it returns, the handle is ready for I/O.

    -
    Params
    -

    Import interface wasi:clocks/monotonic-clock

    WASI Monotonic Clock is a clock API intended to let users measure elapsed @@ -126,7 +138,12 @@ successive reads of the clock will produce non-decreasing values.

    #### `type instant` `u64` -

    A timestamp in nanoseconds. +

    An instant in time, in nanoseconds. An instant is relative to an +unspecified initial value, and can only be compared to instances from +the same monotonic-clock. +

    type duration

    +

    u64

    +

    A duration of time, in nanoseconds.


    Functions

    now: func

    @@ -138,22 +155,34 @@ produce a sequence of non-decreasing values.

  • instant
  • resolution: func

    -

    Query the resolution of the clock.

    +

    Query the resolution of the clock. Returns the duration of time +corresponding to a clock tick.

    +
    Return values
    + +

    subscribe-instant: func

    +

    Create a pollable which will resolve once the specified instant +occured.

    +
    Params
    +
    Return values
    -

    subscribe: func

    -

    Create a pollable which will resolve once the specified time has been -reached.

    +

    subscribe-duration: func

    +

    Create a pollable which will resolve once the given duration has +elapsed, starting at the time at which this function was called. +occured.

    Params
    Return values

    Import interface wasi:clocks/timezone


    @@ -230,62 +259,55 @@ when it does, they are expected to subsume this API.

    type pollable

    pollable

    -#### `enum stream-status` -

    Streams provide a sequence of data and then end; once they end, they -no longer provide any further data.

    -

    For example, a stream reading from a file ends when the stream reaches -the end of the file. For another example, a stream reading from a -socket ends when the socket is closed.

    -
    Enum Cases
    -
      -
    • -

      open

      -

      The stream is open and may produce further data. -

    • -
    • -

      ended

      -

      When reading, this indicates that the stream will not produce -further data. -When writing, this indicates that the stream will no longer be read. -Further writes are still permitted. -

    • -
    -

    resource input-stream

    -

    enum write-error

    -

    An error for output-stream operations.

    -

    Contrary to input-streams, a closed output-stream is reported using -an error.

    -
    Enum Cases
    +#### `resource error` +

    variant stream-error

    +

    An error for input-stream and output-stream operations.

    +
    Variant Cases
    • -

      last-operation-failed

      +

      last-operation-failed: own<error>

      The last operation (a write or flush) failed before completion. +

      More information is available in the error payload.

    • -

      closed

      +

      closed

      The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

    +

    resource input-stream

    resource output-stream


    Functions

    +

    [method]error.to-debug-string: func

    +

    Returns a string that's suitable to assist humans in debugging this +error.

    +

    The returned string will change across platforms and hosts which +means that parsing it, for example, would be a +platform-compatibility hazard.

    +
    Params
    + +
    Return values
    +
      +
    • string
    • +

    [method]input-stream.read: func

    Perform a non-blocking read from the stream.

    -

    This function returns a list of bytes containing the data that was -read, along with a stream-status which, indicates whether further -reads are expected to produce data. The returned list will contain up to -len bytes; it may return fewer than requested, but not more. An -empty list and stream-status:open indicates no more data is -available at this time, and that the pollable given by subscribe -will be ready when more data is available.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report stream-status:ended rather than producing more -data.

    -

    When the caller gives a len of 0, it represents a request to read 0 -bytes. This read should always succeed and return an empty list and -the current stream-status.

    +

    This function returns a list of bytes containing the read data, +when successful. The returned list will contain up to len bytes; +it may return fewer than requested, but not more. The list is +empty when no bytes are available for reading at this time. The +pollable given by subscribe will be ready when more bytes are +available.

    +

    This function fails with a stream-error when the operation +encounters an error, giving last-operation-failed, or when the +stream is closed, giving closed.

    +

    When the caller gives a len of 0, it represents a request to +read 0 bytes. If the stream is still open, this call should +succeed and return an empty list, or otherwise fail with closed.

    The len parameter is a u64, which could represent a list of u8 which is not possible to allocate in wasm32, or not desirable to allocate as as a return value by the callee. The callee may return a list of bytes @@ -297,11 +319,11 @@ less than len in size while more bytes are available for reading.

    Return values

    [method]input-stream.blocking-read: func

    Read bytes from a stream, after blocking until at least one byte can -be read. Except for blocking, identical to read.

    +be read. Except for blocking, behavior is identical to read.

    Params
    • self: borrow<input-stream>
    • @@ -309,18 +331,12 @@ be read. Except for blocking, identical to read.

    Return values

    [method]input-stream.skip: func

    -

    Skip bytes from a stream.

    -

    This is similar to the read function, but avoids copying the -bytes into the instance.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

    -

    This function returns the number of bytes skipped, along with a -stream-status indicating whether the end of the stream was -reached. The returned value will be at most len; it may be less.

    +

    Skip bytes from a stream. Returns number of bytes skipped.

    +

    Behaves identical to read, except instead of returning a list +of bytes, returns the number of bytes consumed from the stream.

    Params
    • self: borrow<input-stream>
    • @@ -328,7 +344,7 @@ reached. The returned value will be at most len; it may be less.

      Return values

      [method]input-stream.blocking-skip: func

      Skip bytes from a stream, after blocking until at least one byte @@ -340,7 +356,7 @@ can be skipped. Except for blocking behavior, identical to skip.

      Return values

      [method]input-stream.subscribe: func

      Create a pollable which will resolve once either the specified stream @@ -362,7 +378,7 @@ all derived pollables created with this fun

      Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has permitted will trap.

      -

      When this function returns 0 bytes, the subscribe pollable will +

      When this function returns 0 bytes, the subscribe pollable will become ready when this function will report at least 1 byte, or an error.

      Params
      @@ -371,7 +387,7 @@ error.

    Return values

    [method]output-stream.write: func

    Perform a write. This function never blocks.

    @@ -386,13 +402,13 @@ the last call to check-write provided a permit.

    Return values

    [method]output-stream.blocking-write-and-flush: func

    Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

    This is a convenience wrapper around the use of check-write, -subscribe, write, and flush, and is implemented with the +subscribe, write, and flush, and is implemented with the following pseudo-code:

    let pollable = this.subscribe();
     while !contents.is_empty() {
    @@ -417,7 +433,7 @@ let _ = this.check-write();         // eliding error handling
     
     
    Return values

    [method]output-stream.flush: func

    Request to flush buffered output. This function never blocks.

    @@ -426,7 +442,7 @@ output to be flushed. the output which is expected to be flushed is all that has been passed to write prior to this call.

    Upon calling this function, the output-stream will not accept any writes (check-write will return ok(0)) until the flush has -completed. The subscribe pollable will become ready when the +completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

    Params
      @@ -434,7 +450,7 @@ flush has completed and the stream can accept more writes.

    Return values

    [method]output-stream.blocking-flush: func

    Request to flush buffered output, and block until flush completes @@ -445,7 +461,7 @@ and stream is ready for writing again.

    Return values

    [method]output-stream.subscribe: func

    Create a pollable which will resolve once the output-stream @@ -477,14 +493,14 @@ that should be written.

    Return values

    [method]output-stream.blocking-write-zeroes-and-flush: func

    Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

    This is a convenience wrapper around the use of check-write, -subscribe, write-zeroes, and flush, and is implemented with +subscribe, write-zeroes, and flush, and is implemented with the following pseudo-code:

    let pollable = this.subscribe();
     while num_zeroes != 0 {
    @@ -508,56 +524,45 @@ let _ = this.check-write();         // eliding error handling
     
     
    Return values

    [method]output-stream.splice: func

    Read from one stream and write to another.

    +

    The behavior of splice is equivelant to:

    +
      +
    1. calling check-write on the output-stream
    2. +
    3. calling read on the input-stream with the smaller of the +check-write permitted length and the len provided to splice
    4. +
    5. calling write on the output-stream with that read data.
    6. +
    +

    Any error reported by the call to check-write, read, or +write ends the splice and reports that error.

    This function returns the number of bytes transferred; it may be less than len.

    -

    Unlike other I/O functions, this function blocks until all the data -read from the input stream has been written to the output stream.

    Params
    Return values

    [method]output-stream.blocking-splice: func

    Read from one stream and write to another, with blocking.

    -

    This is similar to splice, except that it blocks until at least -one byte can be read.

    +

    This is similar to splice, except that it blocks until the +output-stream is ready for writing, and the input-stream +is ready for reading, before performing the splice.

    Params
    Return values
    -

    [method]output-stream.forward: func

    -

    Forward the entire contents of an input stream to an output stream.

    -

    This function repeatedly reads from the input stream and writes -the data to the output stream, until the end of the input stream -is reached, or an error is encountered.

    -

    Unlike other I/O functions, this function blocks until the end -of the input stream is seen and all the data has been written to -the output stream.

    -

    This function returns the number of bytes transferred, and the status of -the output stream.

    -
    Params
    - -
    Return values
    -

    Import interface wasi:filesystem/types

    WASI filesystem is a filesystem API primarily intended to let users run WASI @@ -585,6 +590,9 @@ underlying filesystem, the function fails with `type output-stream` [`output-stream`](#output_stream)

    +#### `type error` +[`error`](#error) +

    #### `type datetime` [`datetime`](#datetime)

    @@ -1440,111 +1448,6 @@ flag. read on a directory implies readability and searchability, an

    -

    [method]descriptor.lock-shared: func

    -

    Request a shared advisory lock for an open file.

    -

    This requests a shared lock; more than one shared lock can be held for -a file at the same time.

    -

    If the open file has an exclusive lock, this function downgrades the lock -to a shared lock. If it has a shared lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified how shared locks interact with locks acquired by -non-WASI programs.

    -

    This function blocks until the lock can be acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_SH) in Unix.

    -
    Params
    - -
    Return values
    - -

    [method]descriptor.lock-exclusive: func

    -

    Request an exclusive advisory lock for an open file.

    -

    This requests an exclusive lock; no other locks may be held for the -file while an exclusive lock is held.

    -

    If the open file has a shared lock and there are no exclusive locks held -for the file, this function upgrades the lock to an exclusive lock. If the -open file already has an exclusive lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified whether this function succeeds if the file descriptor -is not opened for writing. It is unspecified how exclusive locks interact -with locks acquired by non-WASI programs.

    -

    This function blocks until the lock can be acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_EX) in Unix.

    -
    Params
    - -
    Return values
    - -

    [method]descriptor.try-lock-shared: func

    -

    Request a shared advisory lock for an open file.

    -

    This requests a shared lock; more than one shared lock can be held for -a file at the same time.

    -

    If the open file has an exclusive lock, this function downgrades the lock -to a shared lock. If it has a shared lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified how shared locks interact with locks acquired by -non-WASI programs.

    -

    This function returns error-code::would-block if the lock cannot be -acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

    -
    Params
    - -
    Return values
    - -

    [method]descriptor.try-lock-exclusive: func

    -

    Request an exclusive advisory lock for an open file.

    -

    This requests an exclusive lock; no other locks may be held for the -file while an exclusive lock is held.

    -

    If the open file has a shared lock and there are no exclusive locks held -for the file, this function upgrades the lock to an exclusive lock. If the -open file already has an exclusive lock, this function has no effect.

    -

    This requests an advisory lock, meaning that the file could be accessed -by other programs that don't hold the lock.

    -

    It is unspecified whether this function succeeds if the file descriptor -is not opened for writing. It is unspecified how exclusive locks interact -with locks acquired by non-WASI programs.

    -

    This function returns error-code::would-block if the lock cannot be -acquired.

    -

    Not all filesystems support locking; on filesystems which don't support -locking, this function returns error-code::unsupported.

    -

    Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

    -
    Params
    - -
    Return values
    - -

    [method]descriptor.unlock: func

    -

    Release a shared or exclusive lock on an open file.

    -

    Note: This is similar to flock(fd, LOCK_UN) in Unix.

    -
    Params
    - -
    Return values
    -

    [method]descriptor.is-same-object: func

    Test whether two descriptors refer to the same filesystem object.

    In POSIX, this corresponds to testing whether the two descriptors have the @@ -1610,6 +1513,23 @@ to by a directory descriptor and a relative path.

    +

    filesystem-error-code: func

    +

    Attempts to extract a filesystem-related error-code from the stream +error provided.

    +

    Stream operations which return stream-error::last-operation-failed +have a payload with more information about the operation that failed. +This payload can be passed through to this function to see if there's +filesystem-related information about the error to return.

    +

    Note that this function is fallible because not all stream-related +errors are filesystem-related errors.

    +
    Params
    + +
    Return values
    +

    Import interface wasi:filesystem/preopens


    Types

    From af093440638a4cd920f3aa18f995064247aef9f3 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 31 Oct 2023 19:12:59 -0700 Subject: [PATCH 1273/1772] wit-deps update --- proposals/http/wit/deps.lock | 12 +- .../http/wit/deps/clocks/monotonic-clock.wit | 26 ++- proposals/http/wit/deps/filesystem/types.wit | 113 ++----------- proposals/http/wit/deps/io/poll.wit | 25 ++- proposals/http/wit/deps/io/streams.wit | 159 ++++++++---------- 5 files changed, 126 insertions(+), 209 deletions(-) diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 44c92bbfe..f55de7c52 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -5,18 +5,18 @@ sha512 = "36a793525eba4921f0bd55bc445465e86fc7ff8fcf3e5bb61108d35e4d791950b107b4 [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "74844f8bf1d356bb44aab64a2f917d7a3bcb6d6924662d2e3909aeabda01bea6" -sha512 = "ef21339a60a3f4a37eb48ab81b411c1f2ed11c9b23da04d1e384c07dd4cc75f1a433ce7b46201c693b7a59b51c73d888bc41c78ad204fe32d8a312a9f9a48eb0" +sha256 = "8d6b9f7a8bf9466bdc68043c33e054878fdf09c1cc69c19c99eeadd3bb257a90" +sha512 = "21b65d911930c4512bb3caa08459283fc70b1ccc5159313092334cffd6662fb92cfe90577b51829ef363e2d02530802c88f2a1f82db43964d1f8bff7ecbc794b" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "ca8364780922eddd53ec77f9152c77486db3d7052f6a5902ccc1648d5494050c" -sha512 = "ef05d9d7d5c08bc6a701a65c5af1981f30b2eb5b1c3dc5ca39a69248be8ab7cb3b17c5d181a010149dd491846fa5a7ac4f9165b06e628f31227e02dbdd8b86f5" +sha256 = "c05155f44cf5798d15a16eaf9cdfb065d05914ed4710421a7448bb61c6decf3a" +sha512 = "fb30ea13678d3f3d2002b2cc1f6dae99ee6a06eae7c408c0d558f21e5039979dd80c8ced46b1a7629ce8b050820d81462093f7b4a733ff706d0258bf5dea5657" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "a00c29dd57dc224e8ce28b793b19c1b1001dcdbdc229ed451c3df1db91841b34" -sha512 = "8558085eeb5689209101cdfbc9782953d559ad14ce77260fe2f7cc472482d568f65cad9e6a688d40c634c6c54c608f27e27e481633446114d6fdead93d4e34c5" +sha256 = "fb76f4449eea54d06b56fc6a7ca988da51bd84a54d2021cf18da67b5e2c7ebcf" +sha512 = "c005e2a91522958a9537827a49ae344e1cb39d66e85492901a86bcc7e322ba8d0a7f1a02c9b9f840c123b4ad97e297355fac98d4822536d1426d1096dd1d73ac" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index d9ac7cb3f..afacdbb61 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -11,22 +11,34 @@ interface monotonic-clock { use wasi:io/poll.{pollable}; - /// A timestamp in nanoseconds. + /// An instant in time, in nanoseconds. An instant is relative to an + /// unspecified initial value, and can only be compared to instances from + /// the same monotonic-clock. type instant = u64; + /// A duration of time, in nanoseconds. + type duration = u64; + /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. now: func() -> instant; - /// Query the resolution of the clock. - resolution: func() -> instant; + /// Query the resolution of the clock. Returns the duration of time + /// corresponding to a clock tick. + resolution: func() -> duration; - /// Create a `pollable` which will resolve once the specified time has been - /// reached. - subscribe: func( + /// Create a `pollable` which will resolve once the specified instant + /// occured. + subscribe-instant: func( when: instant, - absolute: bool + ) -> pollable; + + /// Create a `pollable` which will resolve once the given duration has + /// elapsed, starting at the time at which this function was called. + /// occured. + subscribe-duration: func( + when: duration, ) -> pollable; } diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index 2050fb928..7ac147f66 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -23,7 +23,7 @@ /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { - use wasi:io/streams.{input-stream, output-stream}; + use wasi:io/streams.{input-stream, output-stream, error}; use wasi:clocks/wall-clock.{datetime}; /// File size or length of a region within a file. @@ -650,105 +650,6 @@ interface types { modes: modes, ) -> result<_, error-code>; - /// Request a shared advisory lock for an open file. - /// - /// This requests a *shared* lock; more than one shared lock can be held for - /// a file at the same time. - /// - /// If the open file has an exclusive lock, this function downgrades the lock - /// to a shared lock. If it has a shared lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified how shared locks interact with locks acquired by - /// non-WASI programs. - /// - /// This function blocks until the lock can be acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. - lock-shared: func() -> result<_, error-code>; - - /// Request an exclusive advisory lock for an open file. - /// - /// This requests an *exclusive* lock; no other locks may be held for the - /// file while an exclusive lock is held. - /// - /// If the open file has a shared lock and there are no exclusive locks held - /// for the file, this function upgrades the lock to an exclusive lock. If the - /// open file already has an exclusive lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified whether this function succeeds if the file descriptor - /// is not opened for writing. It is unspecified how exclusive locks interact - /// with locks acquired by non-WASI programs. - /// - /// This function blocks until the lock can be acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. - lock-exclusive: func() -> result<_, error-code>; - - /// Request a shared advisory lock for an open file. - /// - /// This requests a *shared* lock; more than one shared lock can be held for - /// a file at the same time. - /// - /// If the open file has an exclusive lock, this function downgrades the lock - /// to a shared lock. If it has a shared lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified how shared locks interact with locks acquired by - /// non-WASI programs. - /// - /// This function returns `error-code::would-block` if the lock cannot be - /// acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. - try-lock-shared: func() -> result<_, error-code>; - - /// Request an exclusive advisory lock for an open file. - /// - /// This requests an *exclusive* lock; no other locks may be held for the - /// file while an exclusive lock is held. - /// - /// If the open file has a shared lock and there are no exclusive locks held - /// for the file, this function upgrades the lock to an exclusive lock. If the - /// open file already has an exclusive lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified whether this function succeeds if the file descriptor - /// is not opened for writing. It is unspecified how exclusive locks interact - /// with locks acquired by non-WASI programs. - /// - /// This function returns `error-code::would-block` if the lock cannot be - /// acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. - try-lock-exclusive: func() -> result<_, error-code>; - - /// Release a shared or exclusive lock on an open file. - /// - /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. - unlock: func() -> result<_, error-code>; - /// Test whether two descriptors refer to the same filesystem object. /// /// In POSIX, this corresponds to testing whether the two descriptors have the @@ -795,4 +696,16 @@ interface types { /// Read a single directory entry from a `directory-entry-stream`. read-directory-entry: func() -> result, error-code>; } + + /// Attempts to extract a filesystem-related `error-code` from the stream + /// `error` provided. + /// + /// Stream operations which return `stream-error::last-operation-failed` + /// have a payload with more information about the operation that failed. + /// This payload can be passed through to this function to see if there's + /// filesystem-related information about the error to return. + /// + /// Note that this function is fallible because not all stream-related + /// errors are filesystem-related errors. + filesystem-error-code: func(err: borrow) -> option; } diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/io/poll.wit index 254f53418..0829a7d08 100644 --- a/proposals/http/wit/deps/io/poll.wit +++ b/proposals/http/wit/deps/io/poll.wit @@ -3,8 +3,21 @@ package wasi:io; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { - /// A "pollable" handle. - resource pollable; + /// `pollable` epresents a single I/O event which may be ready, or not. + resource pollable { + + /// Return the readiness of a pollable. This function never blocks. + /// + /// Returns `true` when the pollable is ready, and `false` otherwise. + ready: func() -> bool; + + /// `block` returns immediately if the pollable is ready, and otherwise + /// blocks until ready. + /// + /// This function is equivalent to calling `poll.poll` on a list + /// containing only this pollable. + block: func(); + } /// Poll for completion on a set of pollables. /// @@ -24,11 +37,5 @@ interface poll { /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as /// being reaedy for I/O. - poll-list: func(in: list>) -> list; - - /// Poll for completion on a single pollable. - /// - /// This function is similar to `poll-list`, but operates on only a single - /// pollable. When it returns, the handle is ready for I/O. - poll-one: func(in: borrow); + poll: func(in: list>) -> list; } diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index cfeab0da1..8999b28d2 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -8,20 +8,36 @@ package wasi:io; interface streams { use poll.{pollable}; - /// Streams provide a sequence of data and then end; once they end, they - /// no longer provide any further data. + /// An error for input-stream and output-stream operations. + variant stream-error { + /// The last operation (a write or flush) failed before completion. + /// + /// More information is available in the `error` payload. + last-operation-failed(error), + /// The stream is closed: no more input will be accepted by the + /// stream. A closed output-stream will return this error on all + /// future operations. + closed + } + + /// Contextual error information about the last failure that happened on + /// a read, write, or flush from an `input-stream` or `output-stream`. + /// + /// This type is returned through the `stream-error` type whenever an + /// operation on a stream directly fails or an error is discovered + /// after-the-fact, for example when a write's failure shows up through a + /// later `flush` or `check-write`. /// - /// For example, a stream reading from a file ends when the stream reaches - /// the end of the file. For another example, a stream reading from a - /// socket ends when the socket is closed. - enum stream-status { - /// The stream is open and may produce further data. - open, - /// When reading, this indicates that the stream will not produce - /// further data. - /// When writing, this indicates that the stream will no longer be read. - /// Further writes are still permitted. - ended, + /// Interfaces such as `wasi:filesystem/types` provide functionality to + /// further "downcast" this error into interface-specific error information. + resource error { + /// Returns a string that's suitable to assist humans in debugging this + /// error. + /// + /// The returned string will change across platforms and hosts which + /// means that parsing it, for example, would be a + /// platform-compatibility hazard. + to-debug-string: func() -> string; } /// An input bytestream. @@ -35,21 +51,20 @@ interface streams { resource input-stream { /// Perform a non-blocking read from the stream. /// - /// This function returns a list of bytes containing the data that was - /// read, along with a `stream-status` which, indicates whether further - /// reads are expected to produce data. The returned list will contain up to - /// `len` bytes; it may return fewer than requested, but not more. An - /// empty list and `stream-status:open` indicates no more data is - /// available at this time, and that the pollable given by `subscribe` - /// will be ready when more data is available. + /// This function returns a list of bytes containing the read data, + /// when successful. The returned list will contain up to `len` bytes; + /// it may return fewer than requested, but not more. The list is + /// empty when no bytes are available for reading at this time. The + /// pollable given by `subscribe` will be ready when more bytes are + /// available. /// - /// Once a stream has reached the end, subsequent calls to `read` or - /// `skip` will always report `stream-status:ended` rather than producing more - /// data. + /// This function fails with a `stream-error` when the operation + /// encounters an error, giving `last-operation-failed`, or when the + /// stream is closed, giving `closed`. /// - /// When the caller gives a `len` of 0, it represents a request to read 0 - /// bytes. This read should always succeed and return an empty list and - /// the current `stream-status`. + /// When the caller gives a `len` of 0, it represents a request to + /// read 0 bytes. If the stream is still open, this call should + /// succeed and return an empty list, or otherwise fail with `closed`. /// /// The `len` parameter is a `u64`, which could represent a list of u8 which /// is not possible to allocate in wasm32, or not desirable to allocate as @@ -58,38 +73,30 @@ interface streams { read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>>; + ) -> result, stream-error>; /// Read bytes from a stream, after blocking until at least one byte can - /// be read. Except for blocking, identical to `read`. + /// be read. Except for blocking, behavior is identical to `read`. blocking-read: func( /// The maximum number of bytes to read len: u64 - ) -> result, stream-status>>; + ) -> result, stream-error>; - /// Skip bytes from a stream. + /// Skip bytes from a stream. Returns number of bytes skipped. /// - /// This is similar to the `read` function, but avoids copying the - /// bytes into the instance. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// This function returns the number of bytes skipped, along with a - /// `stream-status` indicating whether the end of the stream was - /// reached. The returned value will be at most `len`; it may be less. + /// Behaves identical to `read`, except instead of returning a list + /// of bytes, returns the number of bytes consumed from the stream. skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result>; + ) -> result; /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. blocking-skip: func( /// The maximum number of bytes to skip. len: u64, - ) -> result>; + ) -> result; /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been @@ -100,18 +107,6 @@ interface streams { subscribe: func() -> pollable; } - /// An error for output-stream operations. - /// - /// Contrary to input-streams, a closed output-stream is reported using - /// an error. - enum write-error { - /// The last operation (a write or flush) failed before completion. - last-operation-failed, - /// The stream is closed: no more input will be accepted by the - /// stream. A closed output-stream will return this error on all - /// future operations. - closed - } /// An output bytestream. /// @@ -131,7 +126,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. - check-write: func() -> result; + check-write: func() -> result; /// Perform a write. This function never blocks. /// @@ -142,7 +137,7 @@ interface streams { /// the last call to check-write provided a permit. write: func( contents: list - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. @@ -170,7 +165,7 @@ interface streams { /// ``` blocking-write-and-flush: func( contents: list - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Request to flush buffered output. This function never blocks. /// @@ -182,11 +177,11 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. - flush: func() -> result<_, write-error>; + flush: func() -> result<_, stream-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. - blocking-flush: func() -> result<_, write-error>; + blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream /// is ready for more writing, or an error has occured. When this @@ -209,7 +204,7 @@ interface streams { write-zeroes: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Perform a write of up to 4096 zeroes, and then flush the stream. /// Block until all of these operations are complete, or an error @@ -238,48 +233,38 @@ interface streams { blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 - ) -> result<_, write-error>; + ) -> result<_, stream-error>; /// Read from one stream and write to another. /// + /// The behavior of splice is equivelant to: + /// 1. calling `check-write` on the `output-stream` + /// 2. calling `read` on the `input-stream` with the smaller of the + /// `check-write` permitted length and the `len` provided to `splice` + /// 3. calling `write` on the `output-stream` with that read data. + /// + /// Any error reported by the call to `check-write`, `read`, or + /// `write` ends the splice and reports that error. + /// /// This function returns the number of bytes transferred; it may be less /// than `len`. - /// - /// Unlike other I/O functions, this function blocks until all the data - /// read from the input stream has been written to the output stream. splice: func( /// The stream to read from - src: input-stream, + src: borrow, /// The number of bytes to splice len: u64, - ) -> result>; + ) -> result; /// Read from one stream and write to another, with blocking. /// - /// This is similar to `splice`, except that it blocks until at least - /// one byte can be read. + /// This is similar to `splice`, except that it blocks until the + /// `output-stream` is ready for writing, and the `input-stream` + /// is ready for reading, before performing the `splice`. blocking-splice: func( /// The stream to read from - src: input-stream, + src: borrow, /// The number of bytes to splice len: u64, - ) -> result>; - - /// Forward the entire contents of an input stream to an output stream. - /// - /// This function repeatedly reads from the input stream and writes - /// the data to the output stream, until the end of the input stream - /// is reached, or an error is encountered. - /// - /// Unlike other I/O functions, this function blocks until the end - /// of the input stream is seen and all the data has been written to - /// the output stream. - /// - /// This function returns the number of bytes transferred, and the status of - /// the output stream. - forward: func( - /// The stream to read from - src: input-stream - ) -> result>; + ) -> result; } } From 9c081c064898767112b530960e1d355c79564170 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 31 Oct 2023 19:17:03 -0700 Subject: [PATCH 1274/1772] generate markdown --- proposals/http/proxy.md | 235 ++++++++++++++++++++-------------------- 1 file changed, 120 insertions(+), 115 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 748f8f872..b2e71b2e3 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -74,7 +74,27 @@ at once.

    resource pollable


    Functions

    -

    poll-list: func

    +

    [method]pollable.ready: func

    +

    Return the readiness of a pollable. This function never blocks.

    +

    Returns true when the pollable is ready, and false otherwise.

    +
    Params
    + +
    Return values
    +
      +
    • bool
    • +
    +

    [method]pollable.block: func

    +

    block returns immediately if the pollable is ready, and otherwise +blocks until ready.

    +

    This function is equivalent to calling poll.poll on a list +containing only this pollable.

    +
    Params
    + +

    poll: func

    Poll for completion on a set of pollables.

    This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

    @@ -90,19 +110,11 @@ the pollables has an error, it is indicated by marking the source as being reaedy for I/O.

    Params
    Return values
      -
    • list<u32>
    • -
    -

    poll-one: func

    -

    Poll for completion on a single pollable.

    -

    This function is similar to poll-list, but operates on only a single -pollable. When it returns, the handle is ready for I/O.

    -
    Params
    -

    Import interface wasi:clocks/monotonic-clock

    WASI Monotonic Clock is a clock API intended to let users measure elapsed @@ -119,7 +131,12 @@ successive reads of the clock will produce non-decreasing values.

    #### `type instant` `u64` -

    A timestamp in nanoseconds. +

    An instant in time, in nanoseconds. An instant is relative to an +unspecified initial value, and can only be compared to instances from +the same monotonic-clock. +

    type duration

    +

    u64

    +

    A duration of time, in nanoseconds.


    Functions

    now: func

    @@ -131,22 +148,34 @@ produce a sequence of non-decreasing values.

  • instant
  • resolution: func

    -

    Query the resolution of the clock.

    +

    Query the resolution of the clock. Returns the duration of time +corresponding to a clock tick.

    Return values
    -

    subscribe: func

    -

    Create a pollable which will resolve once the specified time has been -reached.

    +

    subscribe-instant: func

    +

    Create a pollable which will resolve once the specified instant +occured.

    Params
    Return values
    +

    subscribe-duration: func

    +

    Create a pollable which will resolve once the given duration has +elapsed, starting at the time at which this function was called. +occured.

    +
    Params
    + +
    Return values
    +

    Import interface wasi:clocks/timezone


    @@ -256,62 +285,55 @@ when it does, they are expected to subsume this API.

    type pollable

    pollable

    -#### `enum stream-status` -

    Streams provide a sequence of data and then end; once they end, they -no longer provide any further data.

    -

    For example, a stream reading from a file ends when the stream reaches -the end of the file. For another example, a stream reading from a -socket ends when the socket is closed.

    -
    Enum Cases
    -
      -
    • -

      open

      -

      The stream is open and may produce further data. -

    • -
    • -

      ended

      -

      When reading, this indicates that the stream will not produce -further data. -When writing, this indicates that the stream will no longer be read. -Further writes are still permitted. -

    • -
    -

    resource input-stream

    -

    enum write-error

    -

    An error for output-stream operations.

    -

    Contrary to input-streams, a closed output-stream is reported using -an error.

    -
    Enum Cases
    +#### `resource error` +

    variant stream-error

    +

    An error for input-stream and output-stream operations.

    +
    Variant Cases
    • -

      last-operation-failed

      +

      last-operation-failed: own<error>

      The last operation (a write or flush) failed before completion. +

      More information is available in the error payload.

    • -

      closed

      +

      closed

      The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

    +

    resource input-stream

    resource output-stream


    Functions

    +

    [method]error.to-debug-string: func

    +

    Returns a string that's suitable to assist humans in debugging this +error.

    +

    The returned string will change across platforms and hosts which +means that parsing it, for example, would be a +platform-compatibility hazard.

    +
    Params
    + +
    Return values
    +
      +
    • string
    • +

    [method]input-stream.read: func

    Perform a non-blocking read from the stream.

    -

    This function returns a list of bytes containing the data that was -read, along with a stream-status which, indicates whether further -reads are expected to produce data. The returned list will contain up to -len bytes; it may return fewer than requested, but not more. An -empty list and stream-status:open indicates no more data is -available at this time, and that the pollable given by subscribe -will be ready when more data is available.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report stream-status:ended rather than producing more -data.

    -

    When the caller gives a len of 0, it represents a request to read 0 -bytes. This read should always succeed and return an empty list and -the current stream-status.

    +

    This function returns a list of bytes containing the read data, +when successful. The returned list will contain up to len bytes; +it may return fewer than requested, but not more. The list is +empty when no bytes are available for reading at this time. The +pollable given by subscribe will be ready when more bytes are +available.

    +

    This function fails with a stream-error when the operation +encounters an error, giving last-operation-failed, or when the +stream is closed, giving closed.

    +

    When the caller gives a len of 0, it represents a request to +read 0 bytes. If the stream is still open, this call should +succeed and return an empty list, or otherwise fail with closed.

    The len parameter is a u64, which could represent a list of u8 which is not possible to allocate in wasm32, or not desirable to allocate as as a return value by the callee. The callee may return a list of bytes @@ -323,11 +345,11 @@ less than len in size while more bytes are available for reading.

    Return values

    [method]input-stream.blocking-read: func

    Read bytes from a stream, after blocking until at least one byte can -be read. Except for blocking, identical to read.

    +be read. Except for blocking, behavior is identical to read.

    Params
    • self: borrow<input-stream>
    • @@ -335,18 +357,12 @@ be read. Except for blocking, identical to read.

    Return values

    [method]input-stream.skip: func

    -

    Skip bytes from a stream.

    -

    This is similar to the read function, but avoids copying the -bytes into the instance.

    -

    Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more -data.

    -

    This function returns the number of bytes skipped, along with a -stream-status indicating whether the end of the stream was -reached. The returned value will be at most len; it may be less.

    +

    Skip bytes from a stream. Returns number of bytes skipped.

    +

    Behaves identical to read, except instead of returning a list +of bytes, returns the number of bytes consumed from the stream.

    Params
    • self: borrow<input-stream>
    • @@ -354,7 +370,7 @@ reached. The returned value will be at most len; it may be less.

      Return values

      [method]input-stream.blocking-skip: func

      Skip bytes from a stream, after blocking until at least one byte @@ -366,7 +382,7 @@ can be skipped. Except for blocking behavior, identical to skip.

      Return values

      [method]input-stream.subscribe: func

      Create a pollable which will resolve once either the specified stream @@ -388,7 +404,7 @@ all derived pollables created with this fun

      Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has permitted will trap.

      -

      When this function returns 0 bytes, the subscribe pollable will +

      When this function returns 0 bytes, the subscribe pollable will become ready when this function will report at least 1 byte, or an error.

      Params
      @@ -397,7 +413,7 @@ error.

    Return values

    [method]output-stream.write: func

    Perform a write. This function never blocks.

    @@ -412,13 +428,13 @@ the last call to check-write provided a permit.

    Return values

    [method]output-stream.blocking-write-and-flush: func

    Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

    This is a convenience wrapper around the use of check-write, -subscribe, write, and flush, and is implemented with the +subscribe, write, and flush, and is implemented with the following pseudo-code:

    let pollable = this.subscribe();
     while !contents.is_empty() {
    @@ -443,7 +459,7 @@ let _ = this.check-write();         // eliding error handling
     
     
    Return values

    [method]output-stream.flush: func

    Request to flush buffered output. This function never blocks.

    @@ -452,7 +468,7 @@ output to be flushed. the output which is expected to be flushed is all that has been passed to write prior to this call.

    Upon calling this function, the output-stream will not accept any writes (check-write will return ok(0)) until the flush has -completed. The subscribe pollable will become ready when the +completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

    Params
      @@ -460,7 +476,7 @@ flush has completed and the stream can accept more writes.

    Return values

    [method]output-stream.blocking-flush: func

    Request to flush buffered output, and block until flush completes @@ -471,7 +487,7 @@ and stream is ready for writing again.

    Return values

    [method]output-stream.subscribe: func

    Create a pollable which will resolve once the output-stream @@ -503,14 +519,14 @@ that should be written.

    Return values

    [method]output-stream.blocking-write-zeroes-and-flush: func

    Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

    This is a convenience wrapper around the use of check-write, -subscribe, write-zeroes, and flush, and is implemented with +subscribe, write-zeroes, and flush, and is implemented with the following pseudo-code:

    let pollable = this.subscribe();
     while num_zeroes != 0 {
    @@ -534,56 +550,45 @@ let _ = this.check-write();         // eliding error handling
     
     
    Return values

    [method]output-stream.splice: func

    Read from one stream and write to another.

    +

    The behavior of splice is equivelant to:

    +
      +
    1. calling check-write on the output-stream
    2. +
    3. calling read on the input-stream with the smaller of the +check-write permitted length and the len provided to splice
    4. +
    5. calling write on the output-stream with that read data.
    6. +
    +

    Any error reported by the call to check-write, read, or +write ends the splice and reports that error.

    This function returns the number of bytes transferred; it may be less than len.

    -

    Unlike other I/O functions, this function blocks until all the data -read from the input stream has been written to the output stream.

    Params
    Return values

    [method]output-stream.blocking-splice: func

    Read from one stream and write to another, with blocking.

    -

    This is similar to splice, except that it blocks until at least -one byte can be read.

    +

    This is similar to splice, except that it blocks until the +output-stream is ready for writing, and the input-stream +is ready for reading, before performing the splice.

    Params
    Return values
    -

    [method]output-stream.forward: func

    -

    Forward the entire contents of an input stream to an output stream.

    -

    This function repeatedly reads from the input stream and writes -the data to the output stream, until the end of the input stream -is reached, or an error is encountered.

    -

    Unlike other I/O functions, this function blocks until the end -of the input stream is seen and all the data has been written to -the output stream.

    -

    This function returns the number of bytes transferred, and the status of -the output stream.

    -
    Params
    - -
    Return values
    -

    Import interface wasi:cli/stdout


    @@ -1103,7 +1108,7 @@ the get method will return some.

    Returns the contents of the trailers, or an error which occured, once the future is ready.

    The outer option represents future readiness. Users can wait on this -option to become some using the subscribe method.

    +option to become some using the subscribe method.

    The result represents that either the HTTP Request or Response body, as well as any trailers, were received successfully, or that an error occured receiving them.

    @@ -1214,7 +1219,7 @@ the get method will return some.

    [method]future-incoming-response.get: func

    Returns the incoming HTTP Response, or an error, once one is ready.

    The outer option represents future readiness. Users can wait on this -option to become some using the subscribe method.

    +option to become some using the subscribe method.

    The outer result is used to retrieve the response or error at most once. It will be success on the first call in which the outer option is some, and error on subsequent calls.

    From d4720c1e5988a7a18baa0c9a8ec749eef31f2500 Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Tue, 31 Oct 2023 11:30:27 -0700 Subject: [PATCH 1275/1772] Update some signatures --- proposals/http/wit/types.wit | 66 ++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index b7625a13f..5a6f43cad 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -2,6 +2,7 @@ /// HTTP Requests and Responses, both incoming and outgoing, as well as /// their headers, trailers, and bodies. interface types { + use wasi:clocks/monotonic-clock.{duration}; use wasi:io/streams.{input-stream, output-stream}; use wasi:io/poll.{pollable}; @@ -36,6 +37,13 @@ interface types { unexpected-error(string) } + /// This tyep enumerates the different kinds of errors that may occur when + /// setting or appending to a `fields` resource. + variant header-error { + invalid-syntax, + forbidden, + } + /// Field keys are always strings. type field-key = string; @@ -49,6 +57,9 @@ interface types { /// Headers and Trailers. resource fields { + /// Construct an empty HTTP Fields. + constructor(); + /// Construct an HTTP Fields. /// /// The list represents each key-value pair in the Fields. Keys @@ -59,14 +70,22 @@ interface types { /// Value, represented as a list of bytes. In a valid Fields, all keys /// and values are valid UTF-8 strings. However, values are not always /// well-formed, so they are represented as a raw list of bytes. - constructor(entries: list>); + /// + /// An error result will be returned if any header or value was + /// syntactically invalid, or if a header was forbidden. + from-list: static func( + entries: list> + ) -> result; /// Get all of the values corresponding to a key. get: func(name: field-key) -> list; /// Set all of the values for a key. Clears any existing values for that /// key, if they have been set. - set: func(name: field-key, value: list); + /// + /// The operation can fail if the name or value arguments are invalid, or if + /// the name is forbidden. + set: func(name: field-key, value: list) -> result<_, header-error>; /// Delete all values for a key. Does nothing if no values for the key /// exist. @@ -74,7 +93,10 @@ interface types { /// Append a value for a key. Does not change or delete any existing /// values for that key. - append: func(name: field-key, value: field-value); + /// + /// The operation can fail if the name or value arguments are invalid, or if + /// the name is forbidden. + append: func(name: field-key, value: field-value) -> result<_, header-error>; /// Retrieve the full set of keys and values in the Fields. Like the @@ -202,21 +224,32 @@ interface types { /// /// These timeouts are separate from any the user may use to bound a /// blocking call to `wasi:io/poll.poll-list`. - /// - /// FIXME: Make this a resource to allow it to be optionally extended by - /// future evolution of the standard and/or other interfaces at some later - /// date? - record request-options { + resource request-options { + /// Construct a default `request-options` value. + constructor(); /// The timeout for the initial connect to the HTTP Server. - connect-timeout-ms: option, + connect-timeout-ms: func() -> option; + + /// Set the timeout for the initial connect to the HTTP Server. An error + /// return value indicates that this timeout is not supported. + set-connect-timeout-ms: func(ms: option) -> result; /// The timeout for receiving the first byte of the Response body. - first-byte-timeout-ms: option, + first-byte-timeout-ms: func() -> option; + + /// Set the timeout for receiving the first byte of the Response body. An + /// error return value indicates that this timeout is not supported. + set-first-byte-timeout-ms: func(ms: option) -> result; /// The timeout for receiving subsequent chunks of bytes in the Response /// body stream. - between-bytes-timeout-ms: option + between-bytes-timeout-ms: func() -> option; + + /// Set the timeout for receiving subsequent chunks of bytes in the Response + /// body stream. An error return value indicates that this timeout is not + /// supported. + set-between-bytes-timeout-ms: func(ms: option) -> result; } /// Represents the ability to send an HTTP Response. @@ -235,14 +268,10 @@ interface types { /// /// The user may provide an `error` to `response` to allow the /// implementation determine how to respond with an HTTP error response. - /// - /// This method may return an error when the `outgoing-response` contains - /// a `status-code` or anything else the implementation does not permit or - /// support. set: static func( param: response-outparam, response: result, - ) -> result<_, error>; + ); } /// This type corresponds to the HTTP standard Status Code. @@ -314,8 +343,9 @@ interface types { /// /// The `result` represents that either the HTTP Request or Response body, /// as well as any trailers, were received successfully, or that an error - /// occured receiving them. - get: func() -> option>; + /// occured receiving them. The optional `trailers` indicates whether or not + /// trailers were present in the body. + get: func() -> option, error>>; } /// Represents an outgoing HTTP Response. From 03ba0f81491bca214c04e973a6a6697754f13954 Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Tue, 31 Oct 2023 13:24:02 -0700 Subject: [PATCH 1276/1772] Comment refactoring --- proposals/http/wit/types.wit | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 5a6f43cad..953ebda80 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -37,10 +37,16 @@ interface types { unexpected-error(string) } - /// This tyep enumerates the different kinds of errors that may occur when + /// This type enumerates the different kinds of errors that may occur when /// setting or appending to a `fields` resource. variant header-error { + /// This error indicates that a `field-key` or `field-value` was + /// syntactically invalid when used with an operation that sets headers in a + /// `fields`. invalid-syntax, + + /// This error indicates that a forbidden `field-key` was used when trying + /// to set a header in a `fields`. forbidden, } @@ -82,9 +88,6 @@ interface types { /// Set all of the values for a key. Clears any existing values for that /// key, if they have been set. - /// - /// The operation can fail if the name or value arguments are invalid, or if - /// the name is forbidden. set: func(name: field-key, value: list) -> result<_, header-error>; /// Delete all values for a key. Does nothing if no values for the key @@ -93,9 +96,6 @@ interface types { /// Append a value for a key. Does not change or delete any existing /// values for that key. - /// - /// The operation can fail if the name or value arguments are invalid, or if - /// the name is forbidden. append: func(name: field-key, value: field-value) -> result<_, header-error>; From 065a751592c94856ff2ac158be9fd6298617c6f5 Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Tue, 31 Oct 2023 20:08:20 -0700 Subject: [PATCH 1277/1772] Update proxy.md --- proposals/http/proxy.md | 158 ++++++++++++++++++++++++++++++---------- 1 file changed, 119 insertions(+), 39 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index b2e71b2e3..8754a3919 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -635,8 +635,11 @@ HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.


    Types

    -

    type input-stream

    -

    input-stream

    +

    type duration

    +

    duration

    +

    +#### `type input-stream` +[`input-stream`](#input_stream)

    #### `type output-stream` [`output-stream`](#output_stream) @@ -678,6 +681,23 @@ initially returning a response.

  • protocol-error: string
  • unexpected-error: string
  • +

    variant header-error

    +

    This type enumerates the different kinds of errors that may occur when +setting or appending to a fields resource.

    +
    Variant Cases
    +
      +
    • +

      invalid-syntax

      +

      This error indicates that a `field-key` or `field-value` was +syntactically invalid when used with an operation that sets headers in a +`fields`. +

    • +
    • +

      forbidden

      +

      This error indicates that a forbidden `field-key` was used when trying +to set a header in a `fields`. +

    • +

    type field-key

    string

    Field keys are always strings. @@ -695,31 +715,7 @@ so they are provided as a list of bytes.

    Trailers is an alias for Fields.

    resource incoming-request

    resource outgoing-request

    -

    record request-options

    -

    Parameters for making an HTTP Request. Each of these parameters is an -optional timeout, with the unit in milliseconds, applicable to the -transport layer of the HTTP protocol.

    -

    These timeouts are separate from any the user may use to bound a -blocking call to wasi:io/poll.poll-list.

    -

    FIXME: Make this a resource to allow it to be optionally extended by -future evolution of the standard and/or other interfaces at some later -date?

    -
    Record Fields
    -
      -
    • -

      connect-timeout-ms: option<u32>

      -

      The timeout for the initial connect to the HTTP Server. -

    • -
    • -

      first-byte-timeout-ms: option<u32>

      -

      The timeout for receiving the first byte of the Response body. -

    • -
    • -

      between-bytes-timeout-ms: option<u32>

      -

      The timeout for receiving subsequent chunks of bytes in the Response -body stream. -

    • -
    +

    resource request-options

    resource response-outparam

    type status-code

    u16

    @@ -733,6 +729,12 @@ body stream.

    Functions

    [constructor]fields: func

    +

    Construct an empty HTTP Fields.

    +
    Return values
    + +

    [static]fields.from-list: func

    Construct an HTTP Fields.

    The list represents each key-value pair in the Fields. Keys which have multiple values are represented by multiple entries in this @@ -741,13 +743,15 @@ list with the same key.

    Value, represented as a list of bytes. In a valid Fields, all keys and values are valid UTF-8 strings. However, values are not always well-formed, so they are represented as a raw list of bytes.

    +

    An error result will be returned if any header or value was +syntactically invalid, or if a header was forbidden.

    Params
    Return values

    [method]fields.get: func

    Get all of the values corresponding to a key.

    @@ -769,6 +773,10 @@ key, if they have been set.

  • name: field-key
  • value: list<field-value>
  • +
    Return values
    +

    [method]fields.delete: func

    Delete all values for a key. Does nothing if no values for the key exist.

    @@ -786,6 +794,10 @@ values for that key.

  • name: field-key
  • value: field-value
  • +
    Return values
    +

    [method]fields.entries: func

    Retrieve the full set of keys and values in the Fields. Like the constructor, the list represents each key-value pair.

    @@ -1009,6 +1021,80 @@ another component by e.g. outgoing-handler.handle.

    +

    [constructor]request-options: func

    +

    Construct a default request-options value.

    +
    Return values
    + +

    [method]request-options.connect-timeout-ms: func

    +

    The timeout for the initial connect to the HTTP Server.

    +
    Params
    + +
    Return values
    + +

    [method]request-options.set-connect-timeout-ms: func

    +

    Set the timeout for the initial connect to the HTTP Server. An error +return value indicates that this timeout is not supported.

    +
    Params
    + +
    Return values
    +
      +
    • result
    • +
    +

    [method]request-options.first-byte-timeout-ms: func

    +

    The timeout for receiving the first byte of the Response body.

    +
    Params
    + +
    Return values
    + +

    [method]request-options.set-first-byte-timeout-ms: func

    +

    Set the timeout for receiving the first byte of the Response body. An +error return value indicates that this timeout is not supported.

    +
    Params
    + +
    Return values
    +
      +
    • result
    • +
    +

    [method]request-options.between-bytes-timeout-ms: func

    +

    The timeout for receiving subsequent chunks of bytes in the Response +body stream.

    +
    Params
    + +
    Return values
    + +

    [method]request-options.set-between-bytes-timeout-ms: func

    +

    Set the timeout for receiving subsequent chunks of bytes in the Response +body stream. An error return value indicates that this timeout is not +supported.

    +
    Params
    + +
    Return values
    +
      +
    • result
    • +

    [static]response-outparam.set: func

    Set the value of the response-outparam to either send a response, or indicate an error.

    @@ -1017,18 +1103,11 @@ called at most once. If it is never called, the implementation will respond with an error.

    The user may provide an error to response to allow the implementation determine how to respond with an HTTP error response.

    -

    This method may return an error when the outgoing-response contains -a status-code or anything else the implementation does not permit or -support.

    Params
    -
    Return values
    -

    [method]incoming-response.status: func

    Returns the status code from the incoming response.

    Params
    @@ -1111,14 +1190,15 @@ once the future is ready.

    option to become some using the subscribe method.

    The result represents that either the HTTP Request or Response body, as well as any trailers, were received successfully, or that an error -occured receiving them.

    +occured receiving them. The optional trailers indicates whether or not +trailers were present in the body.

    Params
    Return values

    [constructor]outgoing-response: func

    Construct an outgoing-response.

    @@ -1267,7 +1347,7 @@ through the future-incoming-responseParams

    Return values
      From a6b82b9eaab0d466a3bc9acf445df4a3c4f26a8d Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Mon, 6 Nov 2023 20:11:22 +0100 Subject: [PATCH 1278/1772] Convert tabs to whitespaces --- proposals/sockets/Posix-compatibility.md | 10 +- proposals/sockets/README.md | 44 +- proposals/sockets/wit/instance-network.wit | 6 +- proposals/sockets/wit/ip-name-lookup.wit | 108 ++--- proposals/sockets/wit/network.wit | 258 +++++----- proposals/sockets/wit/tcp-create-socket.wit | 46 +- proposals/sockets/wit/tcp.wit | 492 ++++++++++---------- proposals/sockets/wit/udp-create-socket.wit | 46 +- proposals/sockets/wit/udp.wit | 422 ++++++++--------- 9 files changed, 716 insertions(+), 716 deletions(-) diff --git a/proposals/sockets/Posix-compatibility.md b/proposals/sockets/Posix-compatibility.md index b96cceafb..ea56793c8 100644 --- a/proposals/sockets/Posix-compatibility.md +++ b/proposals/sockets/Posix-compatibility.md @@ -135,12 +135,12 @@ Additionally, most columns have been populated semi-automatically by grepping th Columns: - "Socket option": The native option constant. - "WASI": - - ✅ = Included in proposal. - - ⛔ = Consciously decided _not_ to include in WASI. See notes for explanation. - - ❔ = Not included (yet), for no particular reason. + - ✅ = Included in proposal. + - ⛔ = Consciously decided _not_ to include in WASI. See notes for explanation. + - ❔ = Not included (yet), for no particular reason. - The rest: - - ✅ = Option is provided by the platform / depended upon by the application. - - ❌ = Option is not provided / not used. + - ✅ = Option is provided by the platform / depended upon by the application. + - ❌ = Option is not provided / not used. > Note: GitHub clips the table content. Scroll left and right to see all columns, or use the Code View. diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index c5b9623e8..99d5109a1 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -88,13 +88,13 @@ finish-operation: func(this) -> result The semantics are as follows: - When `start-*` completes successfully: - - The operation should be considered "in progress". - - This is the POSIX equivalent of EINPROGRESS. - - The socket can be polled for completion of the just started operation, using `wasi-poll`. - - Its corresponding `finish-*` function can be called until it returns something other than the `would-block` error code. + - The operation should be considered "in progress". + - This is the POSIX equivalent of EINPROGRESS. + - The socket can be polled for completion of the just started operation, using `wasi-poll`. + - Its corresponding `finish-*` function can be called until it returns something other than the `would-block` error code. - When `finish-*` returns anything other than `would-block`: - - The asynchronous operation should be considered "finished" (either successful or failed) - - Future calls to `finish-*` return the `not-in-progress` error code. + - The asynchronous operation should be considered "finished" (either successful or failed) + - Future calls to `finish-*` return the `not-in-progress` error code. Runtimes that don't need asynchrony, can simply validate the arguments provided to the `start` function and stash them on their internal socket instance and perform the actual syscall in the `finish` function. Conveniently, sockets only allow one of these `start/finish` asynchronous operation to be active at a time. @@ -103,22 +103,22 @@ Example of how to recover blocking semantics in guest code: ```rs // Pseudo code: fn blocking-connect(sock: tcp-socket, addr: ip-socket-address) -> result, error-code> { - - let pollable = tcp::subscribe(tcp-socket); - - let start-result = tcp::start-connect(sock, addr); - if (start-result is error) { - return error; - } - - while (true) { - poll::poll-oneoff([ pollable ]); - - let finish-result = tcp::finish-connect(sock); - if (finish-result is NOT error(would-block)) { - return finish-result; - } - } + + let pollable = tcp::subscribe(tcp-socket); + + let start-result = tcp::start-connect(sock, addr); + if (start-result is error) { + return error; + } + + while (true) { + poll::poll-oneoff([ pollable ]); + + let finish-result = tcp::finish-connect(sock); + if (finish-result is NOT error(would-block)) { + return finish-result; + } + } } ``` diff --git a/proposals/sockets/wit/instance-network.wit b/proposals/sockets/wit/instance-network.wit index 14e4479e6..e455d0ff7 100644 --- a/proposals/sockets/wit/instance-network.wit +++ b/proposals/sockets/wit/instance-network.wit @@ -1,9 +1,9 @@ /// This interface provides a value-export of the default network handle.. interface instance-network { - use network.{network}; + use network.{network}; - /// Get a handle to the default network. - instance-network: func() -> network; + /// Get a handle to the default network. + instance-network: func() -> network; } diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index b51fe05e5..22113ae4c 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,61 +1,61 @@ interface ip-name-lookup { - use wasi:io/poll.{pollable}; - use network.{network, error-code, ip-address, ip-address-family}; + use wasi:io/poll.{pollable}; + use network.{network, error-code, ip-address, ip-address-family}; - /// Resolve an internet host name to a list of IP addresses. - /// - /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. - /// - /// # Parameters - /// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted - /// to ASCII using IDNA encoding. - /// - `address-family`: If provided, limit the results to addresses of this specific address family. - /// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime - /// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on - /// systems without an active IPv6 interface. Notes: - /// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. - /// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. - /// - /// This function never blocks. It either immediately fails or immediately returns successfully with a `resolve-address-stream` - /// that can be used to (asynchronously) fetch the results. - /// - /// At the moment, the stream never completes successfully with 0 items. Ie. the first call - /// to `resolve-next-address` never returns `ok(none)`. This may change in the future. - /// - /// # Typical errors - /// - `invalid-name`: `name` is a syntactically invalid domain name. - /// - `invalid-name`: `name` is an IP address. - /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAI_FAMILY) - /// - /// # References: - /// - - /// - - /// - - /// - - resolve-addresses: func(network: borrow, name: string, address-family: option, include-unavailable: bool) -> result; + /// Resolve an internet host name to a list of IP addresses. + /// + /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. + /// + /// # Parameters + /// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted + /// to ASCII using IDNA encoding. + /// - `address-family`: If provided, limit the results to addresses of this specific address family. + /// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime + /// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on + /// systems without an active IPv6 interface. Notes: + /// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. + /// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. + /// + /// This function never blocks. It either immediately fails or immediately returns successfully with a `resolve-address-stream` + /// that can be used to (asynchronously) fetch the results. + /// + /// At the moment, the stream never completes successfully with 0 items. Ie. the first call + /// to `resolve-next-address` never returns `ok(none)`. This may change in the future. + /// + /// # Typical errors + /// - `invalid-name`: `name` is a syntactically invalid domain name. + /// - `invalid-name`: `name` is an IP address. + /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAI_FAMILY) + /// + /// # References: + /// - + /// - + /// - + /// - + resolve-addresses: func(network: borrow, name: string, address-family: option, include-unavailable: bool) -> result; - resource resolve-address-stream { - /// Returns the next address from the resolver. - /// - /// This function should be called multiple times. On each call, it will - /// return the next address in connection order preference. If all - /// addresses have been exhausted, this function returns `none`. - /// - /// This function never returns IPv4-mapped IPv6 addresses. - /// - /// # Typical errors - /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) - /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) - /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) - /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) - resolve-next-address: func() -> result, error-code>; + resource resolve-address-stream { + /// Returns the next address from the resolver. + /// + /// This function should be called multiple times. On each call, it will + /// return the next address in connection order preference. If all + /// addresses have been exhausted, this function returns `none`. + /// + /// This function never returns IPv4-mapped IPv6 addresses. + /// + /// # Typical errors + /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) + /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) + /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) + /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) + resolve-next-address: func() -> result, error-code>; - /// Create a `pollable` which will resolve once the stream is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable; - } + /// Create a `pollable` which will resolve once the stream is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } } diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index e2695954b..901a4a88c 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -1,178 +1,178 @@ interface network { - /// An opaque resource that represents access to (a subset of) the network. - /// This enables context-based security for networking. - /// There is no need for this to map 1:1 to a physical network interface. - resource network; + /// An opaque resource that represents access to (a subset of) the network. + /// This enables context-based security for networking. + /// There is no need for this to map 1:1 to a physical network interface. + resource network; - /// Error codes. - /// - /// In theory, every API can return any error code. - /// In practice, API's typically only return the errors documented per API - /// combined with a couple of errors that are always possible: - /// - `unknown` - /// - `access-denied` - /// - `not-supported` - /// - `out-of-memory` - /// - /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - enum error-code { - // ### GENERAL ERRORS ### + /// Error codes. + /// + /// In theory, every API can return any error code. + /// In practice, API's typically only return the errors documented per API + /// combined with a couple of errors that are always possible: + /// - `unknown` + /// - `access-denied` + /// - `not-supported` + /// - `out-of-memory` + /// + /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. + enum error-code { + // ### GENERAL ERRORS ### - /// Unknown error - unknown, + /// Unknown error + unknown, - /// Access denied. - /// - /// POSIX equivalent: EACCES, EPERM - access-denied, + /// Access denied. + /// + /// POSIX equivalent: EACCES, EPERM + access-denied, - /// The operation is not supported. - /// - /// POSIX equivalent: EOPNOTSUPP - not-supported, + /// The operation is not supported. + /// + /// POSIX equivalent: EOPNOTSUPP + not-supported, - /// Not enough memory to complete the operation. - /// - /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY - out-of-memory, + /// Not enough memory to complete the operation. + /// + /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY + out-of-memory, - /// The operation timed out before it could finish completely. - timeout, + /// The operation timed out before it could finish completely. + timeout, - /// This operation is incompatible with another asynchronous operation that is already in progress. - concurrency-conflict, + /// This operation is incompatible with another asynchronous operation that is already in progress. + concurrency-conflict, - /// Trying to finish an asynchronous operation that: - /// - has not been started yet, or: - /// - was already finished by a previous `finish-*` call. - /// - /// Note: this is scheduled to be removed when `future`s are natively supported. - not-in-progress, + /// Trying to finish an asynchronous operation that: + /// - has not been started yet, or: + /// - was already finished by a previous `finish-*` call. + /// + /// Note: this is scheduled to be removed when `future`s are natively supported. + not-in-progress, - /// The operation has been aborted because it could not be completed immediately. - /// - /// Note: this is scheduled to be removed when `future`s are natively supported. - would-block, + /// The operation has been aborted because it could not be completed immediately. + /// + /// Note: this is scheduled to be removed when `future`s are natively supported. + would-block, - // ### IP ERRORS ### + // ### IP ERRORS ### - /// The specified address-family is not supported. - address-family-not-supported, + /// The specified address-family is not supported. + address-family-not-supported, - /// An IPv4 address was passed to an IPv6 resource, or vice versa. - address-family-mismatch, + /// An IPv4 address was passed to an IPv6 resource, or vice versa. + address-family-mismatch, - /// The socket address is not a valid remote address. E.g. the IP address is set to INADDR_ANY, or the port is set to 0. - invalid-remote-address, + /// The socket address is not a valid remote address. E.g. the IP address is set to INADDR_ANY, or the port is set to 0. + invalid-remote-address, - /// The operation is only supported on IPv4 resources. - ipv4-only-operation, + /// The operation is only supported on IPv4 resources. + ipv4-only-operation, - /// The operation is only supported on IPv6 resources. - ipv6-only-operation, + /// The operation is only supported on IPv6 resources. + ipv6-only-operation, - // ### TCP & UDP SOCKET ERRORS ### + // ### TCP & UDP SOCKET ERRORS ### - /// A new socket resource could not be created because of a system limit. - new-socket-limit, - - /// The socket is already attached to another network. - already-attached, + /// A new socket resource could not be created because of a system limit. + new-socket-limit, + + /// The socket is already attached to another network. + already-attached, - /// The socket is already bound. - already-bound, + /// The socket is already bound. + already-bound, - /// The socket is already in the Connection state. - already-connected, + /// The socket is already in the Connection state. + already-connected, - /// The socket is not bound to any local address. - not-bound, + /// The socket is not bound to any local address. + not-bound, - /// The socket is not in the Connection state. - not-connected, + /// The socket is not in the Connection state. + not-connected, - /// A bind operation failed because the provided address is not an address that the `network` can bind to. - address-not-bindable, + /// A bind operation failed because the provided address is not an address that the `network` can bind to. + address-not-bindable, - /// A bind operation failed because the provided address is already in use. - address-in-use, + /// A bind operation failed because the provided address is already in use. + address-in-use, - /// A bind operation failed because there are no ephemeral ports available. - ephemeral-ports-exhausted, + /// A bind operation failed because there are no ephemeral ports available. + ephemeral-ports-exhausted, - /// The remote address is not reachable - remote-unreachable, - + /// The remote address is not reachable + remote-unreachable, + - // ### TCP SOCKET ERRORS ### - - /// The socket is already in the Listener state. - already-listening, + // ### TCP SOCKET ERRORS ### + + /// The socket is already in the Listener state. + already-listening, - /// The socket is already in the Listener state. - not-listening, + /// The socket is already in the Listener state. + not-listening, - /// The connection was forcefully rejected - connection-refused, + /// The connection was forcefully rejected + connection-refused, - /// The connection was reset. - connection-reset, - + /// The connection was reset. + connection-reset, + - // ### UDP SOCKET ERRORS ### - datagram-too-large, + // ### UDP SOCKET ERRORS ### + datagram-too-large, - // ### NAME LOOKUP ERRORS ### - - /// The provided name is a syntactically invalid domain name. - invalid-name, + // ### NAME LOOKUP ERRORS ### + + /// The provided name is a syntactically invalid domain name. + invalid-name, - /// Name does not exist or has no suitable associated IP addresses. - name-unresolvable, + /// Name does not exist or has no suitable associated IP addresses. + name-unresolvable, - /// A temporary failure in name resolution occurred. - temporary-resolver-failure, + /// A temporary failure in name resolution occurred. + temporary-resolver-failure, - /// A permanent failure in name resolution occurred. - permanent-resolver-failure, - } + /// A permanent failure in name resolution occurred. + permanent-resolver-failure, + } - enum ip-address-family { - /// Similar to `AF_INET` in POSIX. - ipv4, + enum ip-address-family { + /// Similar to `AF_INET` in POSIX. + ipv4, - /// Similar to `AF_INET6` in POSIX. - ipv6, - } + /// Similar to `AF_INET6` in POSIX. + ipv6, + } - type ipv4-address = tuple; - type ipv6-address = tuple; + type ipv4-address = tuple; + type ipv6-address = tuple; - variant ip-address { - ipv4(ipv4-address), - ipv6(ipv6-address), - } + variant ip-address { + ipv4(ipv4-address), + ipv6(ipv6-address), + } - record ipv4-socket-address { - port: u16, // sin_port - address: ipv4-address, // sin_addr - } + record ipv4-socket-address { + port: u16, // sin_port + address: ipv4-address, // sin_addr + } - record ipv6-socket-address { - port: u16, // sin6_port - flow-info: u32, // sin6_flowinfo - address: ipv6-address, // sin6_addr - scope-id: u32, // sin6_scope_id - } + record ipv6-socket-address { + port: u16, // sin6_port + flow-info: u32, // sin6_flowinfo + address: ipv6-address, // sin6_addr + scope-id: u32, // sin6_scope_id + } - variant ip-socket-address { - ipv4(ipv4-socket-address), - ipv6(ipv6-socket-address), - } + variant ip-socket-address { + ipv4(ipv4-socket-address), + ipv6(ipv6-socket-address), + } } diff --git a/proposals/sockets/wit/tcp-create-socket.wit b/proposals/sockets/wit/tcp-create-socket.wit index 056bbef33..cc4c6fa32 100644 --- a/proposals/sockets/wit/tcp-create-socket.wit +++ b/proposals/sockets/wit/tcp-create-socket.wit @@ -1,27 +1,27 @@ interface tcp-create-socket { - use network.{network, error-code, ip-address-family}; - use tcp.{tcp-socket}; + use network.{network, error-code, ip-address-family}; + use tcp.{tcp-socket}; - /// Create a new TCP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. - /// - /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` - /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// - /// # Typical errors - /// - `not-supported`: The host does not support TCP sockets. (EOPNOTSUPP) - /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References - /// - - /// - - /// - - /// - - create-tcp-socket: func(address-family: ip-address-family) -> result; + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` + /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # Typical errors + /// - `not-supported`: The host does not support TCP sockets. (EOPNOTSUPP) + /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References + /// - + /// - + /// - + /// - + create-tcp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index fea44380d..1de68a7f5 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,249 +1,249 @@ interface tcp { - use wasi:io/streams.{input-stream, output-stream}; - use wasi:io/poll.{pollable}; - use network.{network, error-code, ip-socket-address, ip-address-family}; - - enum shutdown-type { - /// Similar to `SHUT_RD` in POSIX. - receive, - - /// Similar to `SHUT_WR` in POSIX. - send, - - /// Similar to `SHUT_RDWR` in POSIX. - both, - } - - - /// A TCP socket handle. - resource tcp-socket { - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will - /// implicitly bind the socket. - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) - /// - `already-bound`: The socket is already bound. (EINVAL) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; - finish-bind: func() -> result<_, error-code>; - - /// Connect to a remote endpoint. - /// - /// On success: - /// - the socket is transitioned into the Connection state - /// - a pair of streams is returned that can be used to read & write to the connection - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) - /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `already-connected`: The socket is already in the Connection state. (EISCONN) - /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `timeout`: Connection timed out. (ETIMEDOUT) - /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) - /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; - finish-connect: func() -> result, error-code>; - - /// Start listening for new connections. - /// - /// Transitions the socket into the Listener state. - /// - /// Unlike POSIX: - /// - this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - the socket must already be explicitly bound. - /// - /// # Typical `start` errors - /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) - /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) - /// - `already-listening`: The socket is already in the Listener state. - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - `not-in-progress`: A `listen` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-listen: func() -> result<_, error-code>; - finish-listen: func() -> result<_, error-code>; - - /// Accept a new client socket. - /// - /// The returned socket is bound and in the Connection state. - /// - /// On success, this function returns the newly accepted client socket along with - /// a pair of streams that can be used to read & write to the connection. - /// - /// # Typical errors - /// - `not-listening`: Socket is not in the Listener state. (EINVAL) - /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) - /// - /// Host implementations must skip over transient errors returned by the native accept syscall. - /// - /// # References - /// - - /// - - /// - - /// - - accept: func() -> result, error-code>; - - /// Get the bound local address. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - local-address: func() -> result; - - /// Get the bound remote address. - /// - /// # Typical errors - /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - remote-address: func() -> result; - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func() -> ip-address-family; - - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. - /// - `already-bound`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - ipv6-only: func() -> result; - set-ipv6-only: func(value: bool) -> result<_, error-code>; - - /// Hints the desired listen queue size. Implementations are free to ignore this. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - set-listen-backlog-size: func(value: u64) -> result<_, error-code>; - - /// Equivalent to the SO_KEEPALIVE socket option. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - keep-alive: func() -> result; - set-keep-alive: func(value: bool) -> result<_, error-code>; - - /// Equivalent to the TCP_NODELAY socket option. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - no-delay: func() -> result; - set-no-delay: func(value: bool) -> result<_, error-code>; - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `already-listening`: (set) The socket is already in the Listener state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - unicast-hop-limit: func() -> result; - set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `already-listening`: (set) The socket is already in the Listener state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - receive-buffer-size: func() -> result; - set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - send-buffer-size: func() -> result; - set-send-buffer-size: func(value: u64) -> result<_, error-code>; - - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable; - - /// Initiate a graceful shutdown. - /// - /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read - /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. - /// Any data still in the receive queue at time of calling `shutdown` will be discarded. - /// - send: the socket is not expecting to send any more data to the peer. All subsequent write - /// operations on the `output-stream` associated with this socket will return an error. - /// - both: same effect as receive & send combined. - /// - /// The shutdown function does not close (drop) the socket. - /// - /// # Typical errors - /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; - } + use wasi:io/streams.{input-stream, output-stream}; + use wasi:io/poll.{pollable}; + use network.{network, error-code, ip-socket-address, ip-address-family}; + + enum shutdown-type { + /// Similar to `SHUT_RD` in POSIX. + receive, + + /// Similar to `SHUT_WR` in POSIX. + send, + + /// Similar to `SHUT_RDWR` in POSIX. + both, + } + + + /// A TCP socket handle. + resource tcp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will + /// implicitly bind the socket. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) + /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + finish-bind: func() -> result<_, error-code>; + + /// Connect to a remote endpoint. + /// + /// On success: + /// - the socket is transitioned into the Connection state + /// - a pair of streams is returned that can be used to read & write to the connection + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `already-connected`: The socket is already in the Connection state. (EISCONN) + /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + finish-connect: func() -> result, error-code>; + + /// Start listening for new connections. + /// + /// Transitions the socket into the Listener state. + /// + /// Unlike POSIX: + /// - this function is async. This enables interactive WASI hosts to inject permission prompts. + /// - the socket must already be explicitly bound. + /// + /// # Typical `start` errors + /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) + /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) + /// - `already-listening`: The socket is already in the Listener state. + /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// - `not-in-progress`: A `listen` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-listen: func() -> result<_, error-code>; + finish-listen: func() -> result<_, error-code>; + + /// Accept a new client socket. + /// + /// The returned socket is bound and in the Connection state. + /// + /// On success, this function returns the newly accepted client socket along with + /// a pair of streams that can be used to read & write to the connection. + /// + /// # Typical errors + /// - `not-listening`: Socket is not in the Listener state. (EINVAL) + /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) + /// + /// Host implementations must skip over transient errors returned by the native accept syscall. + /// + /// # References + /// - + /// - + /// - + /// - + accept: func() -> result, error-code>; + + /// Get the bound local address. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func() -> result; + + /// Get the bound remote address. + /// + /// # Typical errors + /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func() -> result; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family; + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// # Typical errors + /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. + /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + ipv6-only: func() -> result; + set-ipv6-only: func(value: bool) -> result<_, error-code>; + + /// Hints the desired listen queue size. Implementations are free to ignore this. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + set-listen-backlog-size: func(value: u64) -> result<_, error-code>; + + /// Equivalent to the SO_KEEPALIVE socket option. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + keep-alive: func() -> result; + set-keep-alive: func(value: bool) -> result<_, error-code>; + + /// Equivalent to the TCP_NODELAY socket option. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + no-delay: func() -> result; + set-no-delay: func(value: bool) -> result<_, error-code>; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `already-listening`: (set) The socket is already in the Listener state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + unicast-hop-limit: func() -> result; + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `already-connected`: (set) The socket is already in the Connection state. + /// - `already-listening`: (set) The socket is already in the Listener state. + /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + receive-buffer-size: func() -> result; + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + send-buffer-size: func() -> result; + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + + /// Initiate a graceful shutdown. + /// + /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read + /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. + /// Any data still in the receive queue at time of calling `shutdown` will be discarded. + /// - send: the socket is not expecting to send any more data to the peer. All subsequent write + /// operations on the `output-stream` associated with this socket will return an error. + /// - both: same effect as receive & send combined. + /// + /// The shutdown function does not close (drop) the socket. + /// + /// # Typical errors + /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; + } } diff --git a/proposals/sockets/wit/udp-create-socket.wit b/proposals/sockets/wit/udp-create-socket.wit index 66f948226..3358e2c48 100644 --- a/proposals/sockets/wit/udp-create-socket.wit +++ b/proposals/sockets/wit/udp-create-socket.wit @@ -1,27 +1,27 @@ interface udp-create-socket { - use network.{network, error-code, ip-address-family}; - use udp.{udp-socket}; + use network.{network, error-code, ip-address-family}; + use udp.{udp-socket}; - /// Create a new UDP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. - /// - /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` is called, - /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// - /// # Typical errors - /// - `not-supported`: The host does not support UDP sockets. (EOPNOTSUPP) - /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References: - /// - - /// - - /// - - /// - - create-udp-socket: func(address-family: ip-address-family) -> result; + /// Create a new UDP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` is called, + /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # Typical errors + /// - `not-supported`: The host does not support UDP sockets. (EOPNOTSUPP) + /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References: + /// - + /// - + /// - + /// - + create-udp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index e20b57e7e..ca497b3a4 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,214 +1,214 @@ interface udp { - use wasi:io/poll.{pollable}; - use network.{network, error-code, ip-socket-address, ip-address-family}; - - - record datagram { - data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. - remote-address: ip-socket-address, - - /// Possible future additions: - /// local-address: ip-socket-address, // IP_PKTINFO / IP_RECVDSTADDR / IPV6_PKTINFO - /// local-interface: u32, // IP_PKTINFO / IP_RECVIF - /// ttl: u8, // IP_RECVTTL - /// dscp: u6, // IP_RECVTOS - /// ecn: u2, // IP_RECVTOS - } - - - - /// A UDP socket handle. - resource udp-socket { - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) - /// - `already-bound`: The socket is already bound. (EINVAL) - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; - finish-bind: func() -> result<_, error-code>; - - /// Set the destination address. - /// - /// The local-address is updated based on the best network path to `remote-address`. - /// - /// When a destination address is set: - /// - all receive operations will only return datagrams sent from the provided `remote-address`. - /// - the `send` function can only be used to send to this destination. - /// - /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; - finish-connect: func() -> result<_, error-code>; - - /// Receive messages on the socket. - /// - /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. - /// The returned list may contain fewer elements than requested, but never more. - /// If `max-results` is 0, this function returns successfully with an empty list. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. (EINVAL) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - receive: func(max-results: u64) -> result, error-code>; - - /// Send messages on the socket. - /// - /// This function attempts to send all provided `datagrams` on the socket without blocking and - /// returns how many messages were actually sent (or queued for sending). - /// - /// This function semantically behaves the same as iterating the `datagrams` list and sequentially - /// sending each individual datagram until either the end of the list has been reached or the first error occurred. - /// If at least one datagram has been sent successfully, this function never returns an error. - /// - /// If the input list is empty, the function returns `ok(0)`. - /// - /// The remote address option is required. To send a message to the "connected" peer, - /// call `remote-address` to get their address. - /// - /// # Typical errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN) - /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. - /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) - /// - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - send: func(datagrams: list) -> result; - - /// Get the current bound address. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - local-address: func() -> result; - - /// Get the address set with `connect`. - /// - /// # Typical errors - /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - remote-address: func() -> result; - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func() -> ip-address-family; - - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. - /// - `already-bound`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - ipv6-only: func() -> result; - set-ipv6-only: func(value: bool) -> result<_, error-code>; - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - unicast-hop-limit: func() -> result; - set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - receive-buffer-size: func() -> result; - set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - send-buffer-size: func() -> result; - set-send-buffer-size: func(value: u64) -> result<_, error-code>; - - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable; - } + use wasi:io/poll.{pollable}; + use network.{network, error-code, ip-socket-address, ip-address-family}; + + + record datagram { + data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. + remote-address: ip-socket-address, + + /// Possible future additions: + /// local-address: ip-socket-address, // IP_PKTINFO / IP_RECVDSTADDR / IPV6_PKTINFO + /// local-interface: u32, // IP_PKTINFO / IP_RECVIF + /// ttl: u8, // IP_RECVTTL + /// dscp: u6, // IP_RECVTOS + /// ecn: u2, // IP_RECVTOS + } + + + + /// A UDP socket handle. + resource udp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) + /// - `already-bound`: The socket is already bound. (EINVAL) + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + finish-bind: func() -> result<_, error-code>; + + /// Set the destination address. + /// + /// The local-address is updated based on the best network path to `remote-address`. + /// + /// When a destination address is set: + /// - all receive operations will only return datagrams sent from the provided `remote-address`. + /// - the `send` function can only be used to send to this destination. + /// + /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) + /// + /// # Typical `finish` errors + /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + finish-connect: func() -> result<_, error-code>; + + /// Receive messages on the socket. + /// + /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. + /// The returned list may contain fewer elements than requested, but never more. + /// If `max-results` is 0, this function returns successfully with an empty list. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. (EINVAL) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + receive: func(max-results: u64) -> result, error-code>; + + /// Send messages on the socket. + /// + /// This function attempts to send all provided `datagrams` on the socket without blocking and + /// returns how many messages were actually sent (or queued for sending). + /// + /// This function semantically behaves the same as iterating the `datagrams` list and sequentially + /// sending each individual datagram until either the end of the list has been reached or the first error occurred. + /// If at least one datagram has been sent successfully, this function never returns an error. + /// + /// If the input list is empty, the function returns `ok(0)`. + /// + /// The remote address option is required. To send a message to the "connected" peer, + /// call `remote-address` to get their address. + /// + /// # Typical errors + /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN) + /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. + /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + send: func(datagrams: list) -> result; + + /// Get the current bound address. + /// + /// # Typical errors + /// - `not-bound`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func() -> result; + + /// Get the address set with `connect`. + /// + /// # Typical errors + /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func() -> result; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family; + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// # Typical errors + /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. + /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + ipv6-only: func() -> result; + set-ipv6-only: func(value: bool) -> result<_, error-code>; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + unicast-hop-limit: func() -> result; + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. + /// In other words, after setting a value, reading the same setting back may return a different value. + /// + /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) + receive-buffer-size: func() -> result; + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + send-buffer-size: func() -> result; + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } } From b6f67da9ede139e967332c6eff0a992c5e70fd58 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 7 Nov 2023 17:20:43 -0800 Subject: [PATCH 1279/1772] fix: documentation link --- proposals/cli/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/cli/README.md b/proposals/cli/README.md index 31376e12b..287a5d7e6 100644 --- a/proposals/cli/README.md +++ b/proposals/cli/README.md @@ -59,7 +59,7 @@ Wasi-cli is not aiming to significantly re-imagine the concept of command-line i ### API walk-through -The full API documentation can be found [here](cli.md). +The full API documentation can be found [here](command.md). TODO [Walk through of how someone would use this API.] From 9be30dfdc68d35107f1d4408dafc13f4d72b27ab Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 8 Nov 2023 15:41:48 +0100 Subject: [PATCH 1280/1772] Sync changes from wasmtime: - Allow `accept()` to return transient errors. The original provision was added to align with preview3 streams that may only fail once. However, after discussing with Dan Gohman, we came to the conclusion that a `stream` of `result<>` could do the trick fine too. Fixes: https://github.com/WebAssembly/wasi-sockets/issues/22 - Fold `ephemeral-ports-exhausted` into `address-in-use`. There is no cross-platform way to know the distinction between them. - Remove `concurrency-conflict` clutter, and just document it to be always possible. - Simplify "not supported", "invalid argument" and "invalid state" error cases. There is a myriad of reasons why an argument might be invalid or an operation might be not supported. But there is few cross platform consistency in which of those error cases result in which error codes. Many wasi-sockets codes were unnecessarily detailed and had no standardized equivalent in POSIX, so wasi-libc will probably just map them all back into a single EOPNOTSUPP or EINVAL or ... - Remove create-tcp/udp-socket not supported errors. These stem from back when the entire wasi-sockets proposal was one big single thing. In this day and age, when an implementation doesn't want to support TCP and/or UDP, it can simply _not_ implement that interface, rather than returning an error at runtime. - Document that `connect` may return ECONNABORTED - Document the set of socket options that are inherited through `accept` - Clarify `connect` failure state: ```md POSIX mentions: > If connect() fails, the state of the socket is unspecified. Conforming applications should > close the file descriptor and create a new socket before attempting to reconnect. WASI prescribes the following behavior: - If `connect` fails because an input/state validation error, the socket should remain usable. - If a connection was actually attempted but failed, the socket should become unusable for further network communication. ``` - Clarify `local-address` behavior on unbound socket: ```md POSIX mentions: > If the socket has not been bound to a local name, the value > stored in the object pointed to by `address` is unspecified. WASI is stricter and requires `local-address` to return `not-bound` when the socket hasn't been bound yet. ``` - Remove TCP_NODELAY for the time being. The semantics of TCP_NODELAY (and TCP_CORK for that matter) and its effects on the output-stream needs to investigated and specified. I don't expect there to be anything insurmountable. Its just that I haven't had the time to do so yet and I can't promise to have it done before the stabilization Preview2. So, in order to get wasi-sockets ready for Preview2, it was discussed to temporarily remove `no-delay` and reevaluate its inclusion before Preview3. - Introduce new `incoming-datagram-stream` and `outgoing-datagram-stream` types and moved `receive` and `send` methods to those respectively. These streams are returned by `stream` and can be individually subscribed to. This resolves a design issue where a UDP server would end up in a spin loop because `receive` returned EWOULDBLOCK but poll_* always returned immediately because the socket was ready for sending. In this new setup, users can poll each direction separately. Fixes https://github.com/WebAssembly/wasi-sockets/issues/64 - Dropped the `network` parameter from the `connect` call, because `bind` is now _required_ to perform IO. - Enable send-like behaviour by making `outgoing-datagram::remote-address` optional. Fixes https://github.com/WebAssembly/wasi-sockets/pull/57 - Remove the non-essential parameters for now. Post-preview2 these can be reevaluated again. - Lift the restriction against parsing IP addresses. Before, implementations still needed to parse IP addresses to decide whether or not to return an error. --- proposals/sockets/imports.md | 570 ++++++++++---------- proposals/sockets/wit/ip-name-lookup.wit | 46 +- proposals/sockets/wit/network.wit | 81 +-- proposals/sockets/wit/tcp-create-socket.wit | 15 +- proposals/sockets/wit/tcp.wit | 184 ++++--- proposals/sockets/wit/udp-create-socket.wit | 17 +- proposals/sockets/wit/udp.wit | 302 ++++++----- 7 files changed, 627 insertions(+), 588 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 755596317..c59a6a285 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -28,6 +28,7 @@ combined with a couple of errors that are always possible:

    • access-denied
    • not-supported
    • out-of-memory
    • +
    • concurrency-conflict

    See each individual API for what the POSIX equivalents are. They sometimes differ per API.

    Enum Cases
    @@ -47,6 +48,11 @@ combined with a couple of errors that are always possible:

    POSIX equivalent: EOPNOTSUPP

  • +

    invalid-argument

    +

    One of the arguments is invalid. +

    POSIX equivalent: EINVAL

    +
  • +
  • out-of-memory

    Not enough memory to complete the operation.

    POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY

    @@ -58,6 +64,7 @@ combined with a couple of errors that are always possible:

  • concurrency-conflict

    This operation is incompatible with another asynchronous operation that is already in progress. +

    POSIX equivalent: EALREADY

  • not-in-progress

    @@ -72,74 +79,26 @@ combined with a couple of errors that are always possible:

    Note: this is scheduled to be removed when futures are natively supported.

  • -

    address-family-not-supported

    -

    The specified address-family is not supported. -

  • -
  • -

    address-family-mismatch

    -

    An IPv4 address was passed to an IPv6 resource, or vice versa. -

  • -
  • -

    invalid-remote-address

    -

    The socket address is not a valid remote address. E.g. the IP address is set to INADDR_ANY, or the port is set to 0. -

  • -
  • -

    ipv4-only-operation

    -

    The operation is only supported on IPv4 resources. -

  • -
  • -

    ipv6-only-operation

    -

    The operation is only supported on IPv6 resources. +

    invalid-state

    +

    The operation is not valid in the socket's current state.

  • new-socket-limit

    A new socket resource could not be created because of a system limit.

  • -

    already-attached

    -

    The socket is already attached to another network. -

  • -
  • -

    already-bound

    -

    The socket is already bound. -

  • -
  • -

    already-connected

    -

    The socket is already in the Connection state. -

  • -
  • -

    not-bound

    -

    The socket is not bound to any local address. -

  • -
  • -

    not-connected

    -

    The socket is not in the Connection state. -

  • -
  • address-not-bindable

    A bind operation failed because the provided address is not an address that the `network` can bind to.

  • address-in-use

    -

    A bind operation failed because the provided address is already in use. -

  • -
  • -

    ephemeral-ports-exhausted

    -

    A bind operation failed because there are no ephemeral ports available. +

    A bind operation failed because the provided address is already in use or because there are no ephemeral ports available.

  • remote-unreachable

    The remote address is not reachable

  • -

    already-listening

    -

    The socket is already in the Listener state. -

  • -
  • -

    not-listening

    -

    The socket is already in the Listener state. -

  • -
  • connection-refused

    The connection was forcefully rejected

  • @@ -148,11 +107,11 @@ combined with a couple of errors that are always possible:

    The connection was reset.

  • -

    datagram-too-large

    +

    connection-aborted

    +

    A connection was aborted.

  • -

    invalid-name

    -

    The provided name is a syntactically invalid domain name. +

    datagram-too-large

  • name-unresolvable

    @@ -308,31 +267,60 @@ being reaedy for I/O.

    #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `record datagram` +#### `record incoming-datagram` +

    A received datagram.

    +
    Record Fields
    +
      +
    • +

      data: list<u8>

      +

      The payload. +

      Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes.

      +
    • +
    • +

      remote-address: ip-socket-address

      +

      The source address. +

      This field is guaranteed to match the remote address the stream was initialized with, if any.

      +

      Equivalent to the src_addr out parameter of recvfrom.

      +
    • +
    +

    record outgoing-datagram

    +

    A datagram to be sent out.

    Record Fields
      -
    • data: list<u8>
    • -
    • remote-address: ip-socket-address
    • +
    • +

      data: list<u8>

      +

      The payload. +

    • +
    • +

      remote-address: option<ip-socket-address>

      +

      The destination address. +

      The requirements on this field depend on how the stream was initialized:

      +
        +
      • with a remote address: this field must be None or match the stream's remote address exactly.
      • +
      • without a remote address: this field is required.
      • +
      +

      If this value is None, the send operation is equivalent to send in POSIX. Otherwise it is equivalent to sendto.

      +

    resource udp-socket

    +

    resource incoming-datagram-stream

    +

    resource outgoing-datagram-stream


    Functions

    [method]udp-socket.start-bind: func

    Bind the socket to a specific network on the provided IP address and port.

    If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. -If the TCP/UDP port is zero, the socket will be bound to a random free port.

    -

    When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket.

    +If the port is zero, the socket will be bound to a random free port.

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    Typical start errors

      -
    • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
    • -
    • already-bound: The socket is already bound. (EINVAL)
    • -
    • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
    • +
    • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
    • +
    • invalid-state: The socket is already bound. (EINVAL)

    Typical finish errors

      -
    • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
    • +
    • address-in-use: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
    • address-in-use: Address is already in use. (EADDRINUSE)
    • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
    • not-in-progress: A bind operation is not in progress.
    • @@ -364,29 +352,38 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

      -

      [method]udp-socket.start-connect: func

      -

      Set the destination address.

      -

      The local-address is updated based on the best network path to remote-address.

      -

      When a destination address is set:

      -
        -
      • all receive operations will only return datagrams sent from the provided remote-address.
      • -
      • the send function can only be used to send to this destination.
      • -
      -

      Note that this function does not generate any network traffic and the peer is not aware of this "connection".

      -

      Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

      -

      Typical start errors

      -
        -
      • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
      • -
      • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
      • -
      • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
      • -
      • already-attached: The socket is already bound to a different network. The network passed to connect must be identical to the one passed to bind.
      • -
      • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
      • -
      -

      Typical finish errors

      +

      [method]udp-socket.stream: func

      +

      Set up inbound & outbound communication channels, optionally to a specific peer.

      +

      This function only changes the local socket configuration and does not generate any network traffic. +On success, the remote-address of the socket is updated. The local-address may be updated as well, +based on the best network path to remote-address.

      +

      When a remote-address is provided, the returned streams are limited to communicating with that specific peer:

      +
        +
      • send can only be used to send to this destination.
      • +
      • receive will only return datagrams sent from the provided remote-address.
      • +
      +

      This method may be called multiple times on the same socket to change its association, but +only the most recently returned pair of streams will be operational. Implementations may trap if +the streams returned by a previous invocation haven't been dropped yet before calling stream again.

      +

      The POSIX equivalent in pseudo-code is:

      +
      if (was previously connected) {
      +  connect(s, AF_UNSPEC)
      +}
      +if (remote_address is Some) {
      +  connect(s, remote_address)
      +}
      +
      +

      Unlike in POSIX, the socket must already be explicitly bound.

      +

      Typical errors

        -
      • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
      • -
      • not-in-progress: A connect operation is not in progress.
      • -
      • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
      • +
      • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
      • +
      • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
      • +
      • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
      • +
      • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
      • +
      • invalid-state: The socket is not bound.
      • +
      • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
      • +
      • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
      • +
      • connection-refused: The connection was refused. (ECONNREFUSED)

      References

        @@ -397,100 +394,24 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

      Params
      -
      Return values
      - -

      [method]udp-socket.finish-connect: func

      -
      Params
      - -
      Return values
      - -

      [method]udp-socket.receive: func

      -

      Receive messages on the socket.

      -

      This function attempts to receive up to max-results datagrams on the socket without blocking. -The returned list may contain fewer elements than requested, but never more. -If max-results is 0, this function returns successfully with an empty list.

      -

      Typical errors

      -
        -
      • not-bound: The socket is not bound to any local address. (EINVAL)
      • -
      • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
      • -
      • would-block: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN)
      • -
      -

      References

      - -
      Params
      - -
      Return values
      - -

      [method]udp-socket.send: func

      -

      Send messages on the socket.

      -

      This function attempts to send all provided datagrams on the socket without blocking and -returns how many messages were actually sent (or queued for sending).

      -

      This function semantically behaves the same as iterating the datagrams list and sequentially -sending each individual datagram until either the end of the list has been reached or the first error occurred. -If at least one datagram has been sent successfully, this function never returns an error.

      -

      If the input list is empty, the function returns ok(0).

      -

      The remote address option is required. To send a message to the "connected" peer, -call remote-address to get their address.

      -

      Typical errors

      -
        -
      • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
      • -
      • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
      • -
      • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
      • -
      • already-connected: The socket is in "connected" mode and the datagram.remote-address does not match the address passed to connect. (EISCONN)
      • -
      • not-bound: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind.
      • -
      • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
      • -
      • datagram-too-large: The datagram is too large. (EMSGSIZE)
      • -
      • would-block: The send buffer is currently full. (EWOULDBLOCK, EAGAIN)
      • -
      -

      References

      - -
      Params
      -
      Return values

      [method]udp-socket.local-address: func

      Get the current bound address.

      +

      POSIX mentions:

      +
      +

      If the socket has not been bound to a local name, the value +stored in the object pointed to by address is unspecified.

      +
      +

      WASI is stricter and requires local-address to return invalid-state when the socket hasn't been bound yet.

      Typical errors

        -
      • not-bound: The socket is not bound to any local address.
      • +
      • invalid-state: The socket is not bound to any local address.

      References

      [method]udp-socket.remote-address: func

      -

      Get the address set with connect.

      +

      Get the address the socket is currently streaming to.

      Typical errors

        -
      • not-connected: The socket is not connected to a remote address. (ENOTCONN)
      • +
      • invalid-state: The socket is not streaming to a specific remote address. (ENOTCONN)

      References

        @@ -544,10 +465,9 @@ call remote-address to get their address.

        Equivalent to the IPV6_V6ONLY socket option.

        Typical errors

          -
        • ipv6-only-operation: (get/set) this socket is an IPv4 socket.
        • -
        • already-bound: (set) The socket is already bound.
        • +
        • not-supported: (get/set) this socket is an IPv4 socket.
        • +
        • invalid-state: (set) The socket is already bound.
        • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
        • -
        • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
        Params
          @@ -569,10 +489,6 @@ call remote-address to get their address.

        [method]udp-socket.unicast-hop-limit: func

        Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

        -

        Typical errors

        -
          -
        • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
        • -
        Params
        • self: borrow<udp-socket>
        • @@ -599,10 +515,6 @@ In other words, after setting a value, reading the same setting back may return actual data to be sent/received by the application, because the kernel might also use the buffer space for internal metadata structures.

          Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

          -

          Typical errors

          -
            -
          • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
          • -
          Params
          • self: borrow<udp-socket>
          • @@ -652,6 +564,125 @@ It's planned to be removed when future is natively supported in Pre +

            [method]incoming-datagram-stream.receive: func

            +

            Receive messages on the socket.

            +

            This function attempts to receive up to max-results datagrams on the socket without blocking. +The returned list may contain fewer elements than requested, but never more.

            +

            This function returns successfully with an empty list when either:

            +
              +
            • max-results is 0, or:
            • +
            • max-results is greater than 0, but no results are immediately available. +This function never returns error(would-block).
            • +
            +

            Typical errors

            +
              +
            • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
            • +
            • connection-refused: The connection was refused. (ECONNREFUSED)
            • +
            +

            References

            + +
            Params
            + +
            Return values
            + +

            [method]incoming-datagram-stream.subscribe: func

            +

            Create a pollable which will resolve once the stream is ready to receive again.

            +

            Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

            +
            Params
            + +
            Return values
            + +

            [method]outgoing-datagram-stream.check-send: func

            +

            Check readiness for sending. This function never blocks.

            +

            Returns the number of datagrams permitted for the next call to send, +or an error. Calling send with more datagrams than this function has +permitted will trap.

            +

            When this function returns ok(0), the subscribe pollable will +become ready when this function will report at least ok(1), or an +error.

            +

            Never returns would-block.

            +
            Params
            + +
            Return values
            + +

            [method]outgoing-datagram-stream.send: func

            +

            Send messages on the socket.

            +

            This function attempts to send all provided datagrams on the socket without blocking and +returns how many messages were actually sent (or queued for sending). This function never +returns error(would-block). If none of the datagrams were able to be sent, ok(0) is returned.

            +

            This function semantically behaves the same as iterating the datagrams list and sequentially +sending each individual datagram until either the end of the list has been reached or the first error occurred. +If at least one datagram has been sent successfully, this function never returns an error.

            +

            If the input list is empty, the function returns ok(0).

            +

            Each call to send must be permitted by a preceding check-send. Implementations must trap if +either check-send was not called or datagrams contains more items than check-send permitted.

            +

            Typical errors

            +
              +
            • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
            • +
            • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
            • +
            • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
            • +
            • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
            • +
            • invalid-argument: The socket is in "connected" mode and remote-address is some value that does not match the address passed to stream. (EISCONN)
            • +
            • invalid-argument: The socket is not "connected" and no value for remote-address was provided. (EDESTADDRREQ)
            • +
            • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
            • +
            • connection-refused: The connection was refused. (ECONNREFUSED)
            • +
            • datagram-too-large: The datagram is too large. (EMSGSIZE)
            • +
            +

            References

            + +
            Params
            + +
            Return values
            + +

            [method]outgoing-datagram-stream.subscribe: func

            +

            Create a pollable which will resolve once the stream is ready to send again.

            +

            Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

            +
            Params
            + +
            Return values
            +

            Import interface wasi:sockets/udp-create-socket


            Types

            @@ -673,14 +704,13 @@ It's planned to be removed when future is natively supported in Pre

            Create a new UDP socket.

            Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.

            This function does not require a network capability handle. This is considered to be safe because -at time of creation, the socket is not bound to any network yet. Up to the moment bind/connect is called, +at time of creation, the socket is not bound to any network yet. Up to the moment bind is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

            All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

            Typical errors

              -
            • not-supported: The host does not support UDP sockets. (EOPNOTSUPP)
            • -
            • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
            • -
            • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
            • +
            • not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
            • +
            • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)

            References:

              @@ -1065,13 +1095,14 @@ implicitly bind the socket.

              Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

              Typical start errors

                -
              • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
              • -
              • already-bound: The socket is already bound. (EINVAL)
              • -
              • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
              • +
              • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
              • +
              • invalid-argument: local-address is not a unicast address. (EINVAL)
              • +
              • invalid-argument: local-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL)
              • +
              • invalid-state: The socket is already bound. (EINVAL)

              Typical finish errors

                -
              • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
              • +
              • address-in-use: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
              • address-in-use: Address is already in use. (EADDRINUSE)
              • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
              • not-in-progress: A bind operation is not in progress.
              • @@ -1110,23 +1141,37 @@ implicitly bind the socket.

              • the socket is transitioned into the Connection state
              • a pair of streams is returned that can be used to read & write to the connection
              +

              POSIX mentions:

              +
              +

              If connect() fails, the state of the socket is unspecified. Conforming applications should +close the file descriptor and create a new socket before attempting to reconnect.

              +
              +

              WASI prescribes the following behavior:

              +
                +
              • If connect fails because an input/state validation error, the socket should remain usable.
              • +
              • If a connection was actually attempted but failed, the socket should become unusable for further network communication. +Besides drop, any method after such a failure may return an error.
              • +

              Typical start errors

                -
              • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
              • -
              • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
              • -
              • invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
              • -
              • already-attached: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
              • -
              • already-connected: The socket is already in the Connection state. (EISCONN)
              • -
              • already-listening: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
              • -
              • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
              • +
              • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
              • +
              • invalid-argument: remote-address is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
              • +
              • invalid-argument: remote-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL, EADDRNOTAVAIL on Illumos)
              • +
              • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
              • +
              • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
              • +
              • invalid-argument: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
              • +
              • invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
              • +
              • invalid-state: The socket is already in the Connection state. (EISCONN)
              • +
              • invalid-state: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)

              Typical finish errors

              • timeout: Connection timed out. (ETIMEDOUT)
              • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
              • connection-reset: The connection was reset. (ECONNRESET)
              • -
              • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
              • -
              • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
              • +
              • connection-aborted: The connection was aborted. (ECONNABORTED)
              • +
              • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
              • +
              • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
              • not-in-progress: A connect operation is not in progress.
              • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
              @@ -1166,14 +1211,13 @@ implicitly bind the socket.

            Typical start errors

              -
            • not-bound: The socket is not bound to any local address. (EDESTADDRREQ)
            • -
            • already-connected: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
            • -
            • already-listening: The socket is already in the Listener state.
            • -
            • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EINVAL on BSD)
            • +
            • invalid-state: The socket is not bound to any local address. (EDESTADDRREQ)
            • +
            • invalid-state: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
            • +
            • invalid-state: The socket is already in the Listener state.

            Typical finish errors

              -
            • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
            • +
            • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
            • not-in-progress: A listen operation is not in progress.
            • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
            @@ -1203,15 +1247,24 @@ implicitly bind the socket.

          [method]tcp-socket.accept: func

          Accept a new client socket.

          -

          The returned socket is bound and in the Connection state.

          +

          The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket:

          +
            +
          • address-family
          • +
          • ipv6-only
          • +
          • keep-alive
          • +
          • unicast-hop-limit
          • +
          • receive-buffer-size
          • +
          • send-buffer-size
          • +

          On success, this function returns the newly accepted client socket along with a pair of streams that can be used to read & write to the connection.

          Typical errors

            -
          • not-listening: Socket is not in the Listener state. (EINVAL)
          • -
          • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
          • +
          • invalid-state: Socket is not in the Listener state. (EINVAL)
          • +
          • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
          • +
          • connection-aborted: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED)
          • +
          • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
          -

          Host implementations must skip over transient errors returned by the native accept syscall.

          References

          [method]tcp-socket.local-address: func

          Get the bound local address.

          +

          POSIX mentions:

          +
          +

          If the socket has not been bound to a local name, the value +stored in the object pointed to by address is unspecified.

          +
          +

          WASI is stricter and requires local-address to return invalid-state when the socket hasn't been bound yet.

          Typical errors

            -
          • not-bound: The socket is not bound to any local address.
          • +
          • invalid-state: The socket is not bound to any local address.

          References

          [method]tcp-socket.remote-address: func

          -

          Get the bound remote address.

          +

          Get the remote address.

          Typical errors

            -
          • not-connected: The socket is not connected to a remote address. (ENOTCONN)
          • +
          • invalid-state: The socket is not connected to a remote address. (ENOTCONN)

          References

            @@ -1285,10 +1344,9 @@ a pair of streams that can be used to read & write to the connection.

            Equivalent to the IPV6_V6ONLY socket option.

            Typical errors

              -
            • ipv6-only-operation: (get/set) this socket is an IPv4 socket.
            • -
            • already-bound: (set) The socket is already bound.
            • +
            • invalid-state: (set) The socket is already bound.
            • +
            • not-supported: (get/set) this socket is an IPv4 socket.
            • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
            • -
            • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
            Params
              @@ -1312,8 +1370,8 @@ a pair of streams that can be used to read & write to the connection.

              Hints the desired listen queue size. Implementations are free to ignore this.

              Typical errors

                -
              • already-connected: (set) The socket is already in the Connection state.
              • -
              • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
              • +
              • not-supported: (set) The platform does not support changing the backlog size after the initial listen.
              • +
              • invalid-state: (set) The socket is already in the Connection state.
              Params
                @@ -1326,10 +1384,6 @@ a pair of streams that can be used to read & write to the connection.

              [method]tcp-socket.keep-alive: func

              Equivalent to the SO_KEEPALIVE socket option.

              -

              Typical errors

              -
                -
              • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
              • -
              Params
              • self: borrow<tcp-socket>
              • @@ -1348,37 +1402,13 @@ a pair of streams that can be used to read & write to the connection.

                -

                [method]tcp-socket.no-delay: func

                -

                Equivalent to the TCP_NODELAY socket option.

                -

                Typical errors

                -
                  -
                • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                • -
                -
                Params
                - -
                Return values
                - -

                [method]tcp-socket.set-no-delay: func

                -
                Params
                - -
                Return values
                -

                [method]tcp-socket.unicast-hop-limit: func

                Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                Typical errors

                  -
                • already-connected: (set) The socket is already in the Connection state.
                • -
                • already-listening: (set) The socket is already in the Listener state.
                • -
                • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                • +
                • invalid-argument: (set) The TTL value must be 1 or higher.
                • +
                • invalid-state: (set) The socket is already in the Connection state.
                • +
                • invalid-state: (set) The socket is already in the Listener state.
                Params
                  @@ -1408,9 +1438,8 @@ for internal metadata structures.

                  Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

                  Typical errors

                    -
                  • already-connected: (set) The socket is already in the Connection state.
                  • -
                  • already-listening: (set) The socket is already in the Listener state.
                  • -
                  • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                  • +
                  • invalid-state: (set) The socket is already in the Connection state.
                  • +
                  • invalid-state: (set) The socket is already in the Listener state.
                  Params
                    @@ -1474,7 +1503,7 @@ operations on the output-stream associ

                    The shutdown function does not close (drop) the socket.

                    Typical errors

                      -
                    • not-connected: The socket is not in the Connection state. (ENOTCONN)
                    • +
                    • invalid-state: The socket is not in the Connection state. (ENOTCONN)

                    References

                      @@ -1518,9 +1547,8 @@ is called, the socket is effectively an in-memory configuration object, unable t

                      All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

                      Typical errors

                        -
                      • not-supported: The host does not support TCP sockets. (EOPNOTSUPP)
                      • -
                      • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
                      • -
                      • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
                      • +
                      • not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
                      • +
                      • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)

                      References

                        @@ -1552,35 +1580,21 @@ is called, the socket is effectively an in-memory configuration object, unable t #### `type ip-address` [`ip-address`](#ip_address)

                        -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) -

                        #### `resource resolve-address-stream`


                        Functions

                        resolve-addresses: func

                        Resolve an internet host name to a list of IP addresses.

                        +

                        Unicode domain names are automatically converted to ASCII using IDNA encoding. +If the input is an IP address string, the address is parsed and returned +as-is without making any external requests.

                        See the wasi-socket proposal README.md for a comparison with getaddrinfo.

                        -

                        Parameters

                        -
                          -
                        • name: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted -to ASCII using IDNA encoding.
                        • -
                        • address-family: If provided, limit the results to addresses of this specific address family.
                        • -
                        • include-unavailable: When set to true, this function will also return addresses of which the runtime -thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on -systems without an active IPv6 interface. Notes:
                        • -
                        • Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address.
                        • -
                        • Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged.
                        • -
                        -

                        This function never blocks. It either immediately fails or immediately returns successfully with a resolve-address-stream -that can be used to (asynchronously) fetch the results.

                        -

                        At the moment, the stream never completes successfully with 0 items. Ie. the first call -to resolve-next-address never returns ok(none). This may change in the future.

                        +

                        This function never blocks. It either immediately fails or immediately +returns successfully with a resolve-address-stream that can be used +to (asynchronously) fetch the results.

                        Typical errors

                          -
                        • invalid-name: name is a syntactically invalid domain name.
                        • -
                        • invalid-name: name is an IP address.
                        • -
                        • address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)
                        • +
                        • invalid-argument: name is a syntactically invalid domain name or IP address.

                        References:

                          @@ -1593,8 +1607,6 @@ to resolve-next-address never returns ok(none). This m
                          Return values
                            diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index 22113ae4c..cd8d5c4c7 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,50 +1,40 @@ interface ip-name-lookup { use wasi:io/poll.{pollable}; - use network.{network, error-code, ip-address, ip-address-family}; + use network.{network, error-code, ip-address}; /// Resolve an internet host name to a list of IP addresses. - /// + /// + /// Unicode domain names are automatically converted to ASCII using IDNA encoding. + /// If the input is an IP address string, the address is parsed and returned + /// as-is without making any external requests. + /// /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. - /// - /// # Parameters - /// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted - /// to ASCII using IDNA encoding. - /// - `address-family`: If provided, limit the results to addresses of this specific address family. - /// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime - /// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on - /// systems without an active IPv6 interface. Notes: - /// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. - /// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. - /// - /// This function never blocks. It either immediately fails or immediately returns successfully with a `resolve-address-stream` - /// that can be used to (asynchronously) fetch the results. - /// - /// At the moment, the stream never completes successfully with 0 items. Ie. the first call - /// to `resolve-next-address` never returns `ok(none)`. This may change in the future. - /// + /// + /// This function never blocks. It either immediately fails or immediately + /// returns successfully with a `resolve-address-stream` that can be used + /// to (asynchronously) fetch the results. + /// /// # Typical errors - /// - `invalid-name`: `name` is a syntactically invalid domain name. - /// - `invalid-name`: `name` is an IP address. - /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAI_FAMILY) - /// + /// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address. + /// /// # References: /// - /// - /// - /// - - resolve-addresses: func(network: borrow, name: string, address-family: option, include-unavailable: bool) -> result; + resolve-addresses: func(network: borrow, name: string) -> result; resource resolve-address-stream { /// Returns the next address from the resolver. - /// + /// /// This function should be called multiple times. On each call, it will /// return the next address in connection order preference. If all /// addresses have been exhausted, this function returns `none`. - /// + /// /// This function never returns IPv4-mapped IPv6 addresses. - /// + /// /// # Typical errors /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) @@ -53,7 +43,7 @@ interface ip-name-lookup { resolve-next-address: func() -> result, error-code>; /// Create a `pollable` which will resolve once the stream is ready for I/O. - /// + /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. subscribe: func() -> pollable; diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 901a4a88c..6bb07cd6f 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -6,7 +6,7 @@ interface network { resource network; /// Error codes. - /// + /// /// In theory, every API can return any error code. /// In practice, API's typically only return the errors documented per API /// combined with a couple of errors that are always possible: @@ -14,7 +14,8 @@ interface network { /// - `access-denied` /// - `not-supported` /// - `out-of-memory` - /// + /// - `concurrency-conflict` + /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. enum error-code { // ### GENERAL ERRORS ### @@ -23,17 +24,22 @@ interface network { unknown, /// Access denied. - /// + /// /// POSIX equivalent: EACCES, EPERM access-denied, /// The operation is not supported. - /// + /// /// POSIX equivalent: EOPNOTSUPP not-supported, + /// One of the arguments is invalid. + /// + /// POSIX equivalent: EINVAL + invalid-argument, + /// Not enough memory to complete the operation. - /// + /// /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY out-of-memory, @@ -41,96 +47,59 @@ interface network { timeout, /// This operation is incompatible with another asynchronous operation that is already in progress. + /// + /// POSIX equivalent: EALREADY concurrency-conflict, /// Trying to finish an asynchronous operation that: /// - has not been started yet, or: /// - was already finished by a previous `finish-*` call. - /// + /// /// Note: this is scheduled to be removed when `future`s are natively supported. not-in-progress, /// The operation has been aborted because it could not be completed immediately. - /// + /// /// Note: this is scheduled to be removed when `future`s are natively supported. would-block, - // ### IP ERRORS ### - - /// The specified address-family is not supported. - address-family-not-supported, - - /// An IPv4 address was passed to an IPv6 resource, or vice versa. - address-family-mismatch, - - /// The socket address is not a valid remote address. E.g. the IP address is set to INADDR_ANY, or the port is set to 0. - invalid-remote-address, - - /// The operation is only supported on IPv4 resources. - ipv4-only-operation, - - /// The operation is only supported on IPv6 resources. - ipv6-only-operation, - - // ### TCP & UDP SOCKET ERRORS ### + /// The operation is not valid in the socket's current state. + invalid-state, + /// A new socket resource could not be created because of a system limit. new-socket-limit, - - /// The socket is already attached to another network. - already-attached, - - /// The socket is already bound. - already-bound, - - /// The socket is already in the Connection state. - already-connected, - - /// The socket is not bound to any local address. - not-bound, - - /// The socket is not in the Connection state. - not-connected, /// A bind operation failed because the provided address is not an address that the `network` can bind to. address-not-bindable, - /// A bind operation failed because the provided address is already in use. + /// A bind operation failed because the provided address is already in use or because there are no ephemeral ports available. address-in-use, - /// A bind operation failed because there are no ephemeral ports available. - ephemeral-ports-exhausted, - /// The remote address is not reachable remote-unreachable, - - // ### TCP SOCKET ERRORS ### - - /// The socket is already in the Listener state. - already-listening, - /// The socket is already in the Listener state. - not-listening, + // ### TCP SOCKET ERRORS ### /// The connection was forcefully rejected connection-refused, /// The connection was reset. connection-reset, - + + /// A connection was aborted. + connection-aborted, + // ### UDP SOCKET ERRORS ### datagram-too-large, // ### NAME LOOKUP ERRORS ### - - /// The provided name is a syntactically invalid domain name. - invalid-name, /// Name does not exist or has no suitable associated IP addresses. name-unresolvable, @@ -144,7 +113,7 @@ interface network { enum ip-address-family { /// Similar to `AF_INET` in POSIX. - ipv4, + ipv4, /// Similar to `AF_INET6` in POSIX. ipv6, diff --git a/proposals/sockets/wit/tcp-create-socket.wit b/proposals/sockets/wit/tcp-create-socket.wit index cc4c6fa32..768a07c85 100644 --- a/proposals/sockets/wit/tcp-create-socket.wit +++ b/proposals/sockets/wit/tcp-create-socket.wit @@ -4,20 +4,19 @@ interface tcp-create-socket { use tcp.{tcp-socket}; /// Create a new TCP socket. - /// + /// /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. - /// + /// /// This function does not require a network capability handle. This is considered to be safe because /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// + /// /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// + /// /// # Typical errors - /// - `not-supported`: The host does not support TCP sockets. (EOPNOTSUPP) - /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// + /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// /// # References /// - /// - diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 1de68a7f5..836b0a8fe 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -23,24 +23,25 @@ interface tcp { /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which /// network interface(s) to bind to. /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// + /// /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will /// implicitly bind the socket. - /// + /// /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// + /// /// # Typical `start` errors - /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) - /// - `already-bound`: The socket is already bound. (EINVAL) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - /// + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) + /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address, but the socket has `ipv6-only` enabled. (EINVAL) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) /// - `address-in-use`: Address is already in use. (EADDRINUSE) /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) /// - `not-in-progress`: A `bind` operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// + /// /// # References /// - /// - @@ -50,29 +51,41 @@ interface tcp { finish-bind: func() -> result<_, error-code>; /// Connect to a remote endpoint. - /// + /// /// On success: /// - the socket is transitioned into the Connection state /// - a pair of streams is returned that can be used to read & write to the connection - /// + /// + /// POSIX mentions: + /// > If connect() fails, the state of the socket is unspecified. Conforming applications should + /// > close the file descriptor and create a new socket before attempting to reconnect. + /// + /// WASI prescribes the following behavior: + /// - If `connect` fails because an input/state validation error, the socket should remain usable. + /// - If a connection was actually attempted but failed, the socket should become unusable for further network communication. + /// Besides `drop`, any method after such a failure may return an error. + /// /// # Typical `start` errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) - /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `already-connected`: The socket is already in the Connection state. (EISCONN) - /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - /// + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) + /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address, but the socket has `ipv6-only` enabled. (EINVAL, EADDRNOTAVAIL on Illumos) + /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `invalid-state`: The socket is already in the Connection state. (EISCONN) + /// - `invalid-state`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) + /// /// # Typical `finish` errors /// - `timeout`: Connection timed out. (ETIMEDOUT) /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) /// - `not-in-progress`: A `connect` operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// + /// /// # References /// - /// - @@ -82,21 +95,20 @@ interface tcp { finish-connect: func() -> result, error-code>; /// Start listening for new connections. - /// + /// /// Transitions the socket into the Listener state. - /// + /// /// Unlike POSIX: /// - this function is async. This enables interactive WASI hosts to inject permission prompts. /// - the socket must already be explicitly bound. - /// + /// /// # Typical `start` errors - /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) - /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) - /// - `already-listening`: The socket is already in the Listener state. - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) + /// - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ) + /// - `invalid-state`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) + /// - `invalid-state`: The socket is already in the Listener state. /// /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) /// - `not-in-progress`: A `listen` operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) /// @@ -109,18 +121,24 @@ interface tcp { finish-listen: func() -> result<_, error-code>; /// Accept a new client socket. - /// - /// The returned socket is bound and in the Connection state. - /// + /// + /// The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket: + /// - `address-family` + /// - `ipv6-only` + /// - `keep-alive` + /// - `unicast-hop-limit` + /// - `receive-buffer-size` + /// - `send-buffer-size` + /// /// On success, this function returns the newly accepted client socket along with /// a pair of streams that can be used to read & write to the connection. - /// + /// /// # Typical errors - /// - `not-listening`: Socket is not in the Listener state. (EINVAL) - /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) - /// - /// Host implementations must skip over transient errors returned by the native accept syscall. - /// + /// - `invalid-state`: Socket is not in the Listener state. (EINVAL) + /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) + /// - `connection-aborted`: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// /// # References /// - /// - @@ -129,10 +147,16 @@ interface tcp { accept: func() -> result, error-code>; /// Get the bound local address. - /// + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. - /// + /// - `invalid-state`: The socket is not bound to any local address. + /// /// # References /// - /// - @@ -140,11 +164,11 @@ interface tcp { /// - local-address: func() -> result; - /// Get the bound remote address. - /// + /// Get the remote address. + /// /// # Typical errors - /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) - /// + /// - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN) + /// /// # References /// - /// - @@ -153,92 +177,80 @@ interface tcp { remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. - /// + /// /// Equivalent to the SO_DOMAIN socket option. address-family: func() -> ip-address-family; - + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// + /// /// Equivalent to the IPV6_V6ONLY socket option. - /// + /// /// # Typical errors - /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. - /// - `already-bound`: (set) The socket is already bound. + /// - `invalid-state`: (set) The socket is already bound. + /// - `not-supported`: (get/set) `this` socket is an IPv4 socket. /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) ipv6-only: func() -> result; set-ipv6-only: func(value: bool) -> result<_, error-code>; /// Hints the desired listen queue size. Implementations are free to ignore this. - /// + /// /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. + /// - `invalid-state`: (set) The socket is already in the Connection state. set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Equivalent to the SO_KEEPALIVE socket option. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) keep-alive: func() -> result; set-keep-alive: func(value: bool) -> result<_, error-code>; - /// Equivalent to the TCP_NODELAY socket option. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - no-delay: func() -> result; - set-no-delay: func(value: bool) -> result<_, error-code>; - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// + /// /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `already-listening`: (set) The socket is already in the Listener state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + /// - `invalid-state`: (set) The socket is already in the Connection state. + /// - `invalid-state`: (set) The socket is already in the Listener state. unicast-hop-limit: func() -> result; set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. - /// + /// /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// + /// In other words, after setting a value, reading the same setting back may return a different value. + /// /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. - /// + /// actual data to be sent/received by the application, because the kernel might also use the buffer space + /// for internal metadata structures. + /// /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// + /// /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `already-listening`: (set) The socket is already in the Listener state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) + /// - `invalid-state`: (set) The socket is already in the Connection state. + /// - `invalid-state`: (set) The socket is already in the Listener state. receive-buffer-size: func() -> result; set-receive-buffer-size: func(value: u64) -> result<_, error-code>; send-buffer-size: func() -> result; set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// + /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. subscribe: func() -> pollable; /// Initiate a graceful shutdown. - /// + /// /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. /// Any data still in the receive queue at time of calling `shutdown` will be discarded. /// - send: the socket is not expecting to send any more data to the peer. All subsequent write /// operations on the `output-stream` associated with this socket will return an error. /// - both: same effect as receive & send combined. - /// + /// /// The shutdown function does not close (drop) the socket. - /// + /// /// # Typical errors - /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) - /// + /// - `invalid-state`: The socket is not in the Connection state. (ENOTCONN) + /// /// # References /// - /// - diff --git a/proposals/sockets/wit/udp-create-socket.wit b/proposals/sockets/wit/udp-create-socket.wit index 3358e2c48..cc58234d8 100644 --- a/proposals/sockets/wit/udp-create-socket.wit +++ b/proposals/sockets/wit/udp-create-socket.wit @@ -4,20 +4,19 @@ interface udp-create-socket { use udp.{udp-socket}; /// Create a new UDP socket. - /// + /// /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. - /// + /// /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` is called, + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind` is called, /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// + /// /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// + /// /// # Typical errors - /// - `not-supported`: The host does not support UDP sockets. (EOPNOTSUPP) - /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// + /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// /// # References: /// - /// - diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index ca497b3a4..aa3783ab5 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -3,17 +3,34 @@ interface udp { use wasi:io/poll.{pollable}; use network.{network, error-code, ip-socket-address, ip-address-family}; + /// A received datagram. + record incoming-datagram { + /// The payload. + /// + /// Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. + data: list, - record datagram { - data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. + /// The source address. + /// + /// This field is guaranteed to match the remote address the stream was initialized with, if any. + /// + /// Equivalent to the `src_addr` out parameter of `recvfrom`. remote-address: ip-socket-address, + } + + /// A datagram to be sent out. + record outgoing-datagram { + /// The payload. + data: list, - /// Possible future additions: - /// local-address: ip-socket-address, // IP_PKTINFO / IP_RECVDSTADDR / IPV6_PKTINFO - /// local-interface: u32, // IP_PKTINFO / IP_RECVIF - /// ttl: u8, // IP_RECVTTL - /// dscp: u6, // IP_RECVTOS - /// ecn: u2, // IP_RECVTOS + /// The destination address. + /// + /// The requirements on this field depend on how the stream was initialized: + /// - with a remote address: this field must be None or match the stream's remote address exactly. + /// - without a remote address: this field is required. + /// + /// If this value is None, the send operation is equivalent to `send` in POSIX. Otherwise it is equivalent to `sendto`. + remote-address: option, } @@ -24,24 +41,21 @@ interface udp { /// /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. - /// + /// If the port is zero, the socket will be bound to a random free port. + /// /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// + /// /// # Typical `start` errors - /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) - /// - `already-bound`: The socket is already bound. (EINVAL) - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) - /// + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) /// - `address-in-use`: Address is already in use. (EADDRINUSE) /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) /// - `not-in-progress`: A `bind` operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// + /// /// # References /// - /// - @@ -50,100 +64,60 @@ interface udp { start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; finish-bind: func() -> result<_, error-code>; - /// Set the destination address. - /// - /// The local-address is updated based on the best network path to `remote-address`. - /// - /// When a destination address is set: - /// - all receive operations will only return datagrams sent from the provided `remote-address`. - /// - the `send` function can only be used to send to this destination. - /// - /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// Set up inbound & outbound communication channels, optionally to a specific peer. + /// + /// This function only changes the local socket configuration and does not generate any network traffic. + /// On success, the `remote-address` of the socket is updated. The `local-address` may be updated as well, + /// based on the best network path to `remote-address`. + /// + /// When a `remote-address` is provided, the returned streams are limited to communicating with that specific peer: + /// - `send` can only be used to send to this destination. + /// - `receive` will only return datagrams sent from the provided `remote-address`. + /// + /// This method may be called multiple times on the same socket to change its association, but + /// only the most recently returned pair of streams will be operational. Implementations may trap if + /// the streams returned by a previous invocation haven't been dropped yet before calling `stream` again. + /// + /// The POSIX equivalent in pseudo-code is: + /// ```text + /// if (was previously connected) { + /// connect(s, AF_UNSPEC) + /// } + /// if (remote_address is Some) { + /// connect(s, remote_address) + /// } + /// ``` + /// + /// Unlike in POSIX, the socket must already be explicitly bound. /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-state`: The socket is not bound. + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// /// # References /// - /// - /// - /// - - start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; - finish-connect: func() -> result<_, error-code>; - - /// Receive messages on the socket. - /// - /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. - /// The returned list may contain fewer elements than requested, but never more. - /// If `max-results` is 0, this function returns successfully with an empty list. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. (EINVAL) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - receive: func(max-results: u64) -> result, error-code>; - - /// Send messages on the socket. - /// - /// This function attempts to send all provided `datagrams` on the socket without blocking and - /// returns how many messages were actually sent (or queued for sending). - /// - /// This function semantically behaves the same as iterating the `datagrams` list and sequentially - /// sending each individual datagram until either the end of the list has been reached or the first error occurred. - /// If at least one datagram has been sent successfully, this function never returns an error. - /// - /// If the input list is empty, the function returns `ok(0)`. - /// - /// The remote address option is required. To send a message to the "connected" peer, - /// call `remote-address` to get their address. - /// - /// # Typical errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN) - /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. - /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) - /// - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - send: func(datagrams: list) -> result; + %stream: func(remote-address: option) -> result, error-code>; /// Get the current bound address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. /// /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. - /// + /// - `invalid-state`: The socket is not bound to any local address. + /// /// # References /// - /// - @@ -151,11 +125,11 @@ interface udp { /// - local-address: func() -> result; - /// Get the address set with `connect`. - /// + /// Get the address the socket is currently streaming to. + /// /// # Typical errors - /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) - /// + /// - `invalid-state`: The socket is not streaming to a specific remote address. (ENOTCONN) + /// /// # References /// - /// - @@ -164,49 +138,133 @@ interface udp { remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. - /// + /// /// Equivalent to the SO_DOMAIN socket option. address-family: func() -> ip-address-family; /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// + /// /// Equivalent to the IPV6_V6ONLY socket option. - /// + /// /// # Typical errors - /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. - /// - `already-bound`: (set) The socket is already bound. + /// - `not-supported`: (get/set) `this` socket is an IPv4 socket. + /// - `invalid-state`: (set) The socket is already bound. /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) ipv6-only: func() -> result; set-ipv6-only: func(value: bool) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) unicast-hop-limit: func() -> result; set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. - /// + /// /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. /// In other words, after setting a value, reading the same setting back may return a different value. - /// + /// /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of /// actual data to be sent/received by the application, because the kernel might also use the buffer space /// for internal metadata structures. - /// + /// /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) receive-buffer-size: func() -> result; set-receive-buffer-size: func(value: u64) -> result<_, error-code>; send-buffer-size: func() -> result; set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } + + resource incoming-datagram-stream { + /// Receive messages on the socket. + /// + /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. + /// The returned list may contain fewer elements than requested, but never more. + /// + /// This function returns successfully with an empty list when either: + /// - `max-results` is 0, or: + /// - `max-results` is greater than 0, but no results are immediately available. + /// This function never returns `error(would-block)`. + /// + /// # Typical errors + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + receive: func(max-results: u64) -> result, error-code>; + + /// Create a `pollable` which will resolve once the stream is ready to receive again. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } + + resource outgoing-datagram-stream { + /// Check readiness for sending. This function never blocks. + /// + /// Returns the number of datagrams permitted for the next call to `send`, + /// or an error. Calling `send` with more datagrams than this function has + /// permitted will trap. + /// + /// When this function returns ok(0), the `subscribe` pollable will + /// become ready when this function will report at least ok(1), or an + /// error. /// + /// Never returns `would-block`. + check-send: func() -> result; + + /// Send messages on the socket. + /// + /// This function attempts to send all provided `datagrams` on the socket without blocking and + /// returns how many messages were actually sent (or queued for sending). This function never + /// returns `error(would-block)`. If none of the datagrams were able to be sent, `ok(0)` is returned. + /// + /// This function semantically behaves the same as iterating the `datagrams` list and sequentially + /// sending each individual datagram until either the end of the list has been reached or the first error occurred. + /// If at least one datagram has been sent successfully, this function never returns an error. + /// + /// If the input list is empty, the function returns `ok(0)`. + /// + /// Each call to `send` must be permitted by a preceding `check-send`. Implementations must trap if + /// either `check-send` was not called or `datagrams` contains more items than `check-send` permitted. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `stream`. (EISCONN) + /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + send: func(datagrams: list) -> result; + + /// Create a `pollable` which will resolve once the stream is ready to send again. + /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. subscribe: func() -> pollable; From b8b93327a6079c46c5b545f0109d333a82f90625 Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Wed, 8 Nov 2023 10:58:23 -0800 Subject: [PATCH 1281/1772] Fallible setters, and fields.delete method (#69) * Make the `fields.delete` method fallible * Make setters fallible * Regenerate proxy.md --- proposals/http/proxy.md | 63 +++++++++++++++++++++++------------- proposals/http/wit/types.wit | 54 ++++++++++++++----------------- 2 files changed, 64 insertions(+), 53 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 8754a3919..4194b5ee3 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -785,6 +785,10 @@ exist.

                          • self: borrow<fields>
                          • name: field-key
                          +
                          Return values
                          +

                          [method]fields.append: func

                          Append a value for a key. Does not change or delete any existing values for that key.

                          @@ -888,17 +892,9 @@ return success at most once, and subsequent calls will return error.

                        • result<own<incoming-body>>

                        [constructor]outgoing-request: func

                        -

                        Construct a new outgoing-request.

                        -
                          -
                        • method represents the HTTP Method for the Request.
                        • -
                        • path-with-query is the combination of the HTTP Path and Query for -the Request. When none, this represents an empty Path and empty -Query.
                        • -
                        • scheme is the HTTP Related Scheme for the Request. When none, -the implementation may choose an appropriate default scheme.
                        • -
                        • authority is the HTTP Authority for the Request. A value of none -may be used with Related Schemes which do not require an Authority. -The HTTP and HTTPS schemes always require an authority.
                        • +

                          Construct a new outgoing-request with a default method of GET, and +none values for path-with-query, scheme, and authority.

                          +
                          • headers is the HTTP Headers for the Request.

                          It is possible to construct, or manipulate with the accessor functions @@ -908,10 +904,6 @@ It is the obligation of the outgoing-handler.handle implementation to reject invalid constructions of outgoing-request.

                          Params
                          Return values
                          @@ -943,12 +935,17 @@ calls will return error.

                        • method

                        [method]outgoing-request.set-method: func

                        -

                        Set the Method for the Request.

                        +

                        Set the Method for the Request. Fails if the string present in a +method.other argument is not a syntactically valid method.

                        Params
                        +
                        Return values
                        +
                          +
                        • result
                        • +

                        [method]outgoing-request.path-with-query: func

                        Get the combination of the HTTP Path and Query for the Request. When none, this represents an empty Path and empty Query.

                        @@ -962,12 +959,17 @@ When none, this represents an empty Path and empty Query.

                      [method]outgoing-request.set-path-with-query: func

                      Set the combination of the HTTP Path and Query for the Request. -When none, this represents an empty Path and empty Query.

                      +When none, this represents an empty Path and empty Query. Fails is the +string given is not a syntactically valid path and query uri component.

                      Params
                      +
                      Return values
                      +
                        +
                      • result
                      • +

                      [method]outgoing-request.scheme: func

                      Get the HTTP Related Scheme for the Request. When none, the implementation may choose an appropriate default scheme.

                      @@ -981,12 +983,17 @@ implementation may choose an appropriate default scheme.

                    [method]outgoing-request.set-scheme: func

                    Set the HTTP Related Scheme for the Request. When none, the -implementation may choose an appropriate default scheme.

                    +implementation may choose an appropriate default scheme. Fails if the +string given is not a syntactically valid uri scheme.

                    Params
                    +
                    Return values
                    +
                      +
                    • result
                    • +

                    [method]outgoing-request.authority: func

                    Get the HTTP Authority for the Request. A value of none may be used with Related Schemes which do not require an Authority. The HTTP and @@ -1002,12 +1009,17 @@ HTTPS schemes always require an authority.

                    [method]outgoing-request.set-authority: func

                    Set the HTTP Authority for the Request. A value of none may be used with Related Schemes which do not require an Authority. The HTTP and -HTTPS schemes always require an authority.

                    +HTTPS schemes always require an authority. Fails if the string given is +not a syntactically valid uri authority.

                    Params
                    +
                    Return values
                    +
                      +
                    • result
                    • +

                    [method]outgoing-request.headers: func

                    Get the headers associated with the Request.

                    This headers resource is a child: it must be dropped before the parent @@ -1201,14 +1213,14 @@ trailers were present in the body.

                  • option<result<option<own<trailers>>, error>>

                  [constructor]outgoing-response: func

                  -

                  Construct an outgoing-response.

                  +

                  Construct an outgoing-response, with a default status-code of 200. +If a different status-code is needed, it must be set via the +set-status-code method.

                    -
                  • status-code is the HTTP Status Code for the Response.
                  • headers is the HTTP Headers for the Response.
                  Params
                  Return values
                  @@ -1226,12 +1238,17 @@ trailers were present in the body.

                • status-code

                [method]outgoing-response.set-status-code: func

                -

                Set the HTTP Status Code for the Response.

                +

                Set the HTTP Status Code for the Response. Fails if the status-code +given is not a valid http status code.

                Params
                +
                Return values
                +
                  +
                • result
                • +

                [method]outgoing-response.headers: func

                Get the headers associated with the Request.

                This headers resource is a child: it must be dropped before the parent diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 953ebda80..0f3dba437 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -92,13 +92,12 @@ interface types { /// Delete all values for a key. Does nothing if no values for the key /// exist. - delete: func(name: field-key); + delete: func(name: field-key) -> result<_, header-error>; /// Append a value for a key. Does not change or delete any existing /// values for that key. append: func(name: field-key, value: field-value) -> result<_, header-error>; - /// Retrieve the full set of keys and values in the Fields. Like the /// constructor, the list represents each key-value pair. /// @@ -148,17 +147,9 @@ interface types { /// Represents an outgoing HTTP Request. resource outgoing-request { - /// Construct a new `outgoing-request`. + /// Construct a new `outgoing-request` with a default `method` of `GET`, and + /// `none` values for `path-with-query`, `scheme`, and `authority`. /// - /// * `method` represents the HTTP Method for the Request. - /// * `path-with-query` is the combination of the HTTP Path and Query for - /// the Request. When `none`, this represents an empty Path and empty - /// Query. - /// * `scheme` is the HTTP Related Scheme for the Request. When `none`, - /// the implementation may choose an appropriate default scheme. - /// * `authority` is the HTTP Authority for the Request. A value of `none` - /// may be used with Related Schemes which do not require an Authority. - /// The HTTP and HTTPS schemes always require an authority. /// * `headers` is the HTTP Headers for the Request. /// /// It is possible to construct, or manipulate with the accessor functions @@ -167,10 +158,6 @@ interface types { /// It is the obligation of the `outgoing-handler.handle` implementation /// to reject invalid constructions of `outgoing-request`. constructor( - method: method, - path-with-query: option, - scheme: option, - authority: option, headers: headers ); @@ -184,22 +171,25 @@ interface types { /// Get the Method for the Request. method: func() -> method; - /// Set the Method for the Request. - set-method: func(method: method); + /// Set the Method for the Request. Fails if the string present in a + /// `method.other` argument is not a syntactically valid method. + set-method: func(method: method) -> result; /// Get the combination of the HTTP Path and Query for the Request. /// When `none`, this represents an empty Path and empty Query. path-with-query: func() -> option; /// Set the combination of the HTTP Path and Query for the Request. - /// When `none`, this represents an empty Path and empty Query. - set-path-with-query: func(path-with-query: option); + /// When `none`, this represents an empty Path and empty Query. Fails is the + /// string given is not a syntactically valid path and query uri component. + set-path-with-query: func(path-with-query: option) -> result; /// Get the HTTP Related Scheme for the Request. When `none`, the /// implementation may choose an appropriate default scheme. scheme: func() -> option; /// Set the HTTP Related Scheme for the Request. When `none`, the - /// implementation may choose an appropriate default scheme. - set-scheme: func(scheme: option); + /// implementation may choose an appropriate default scheme. Fails if the + /// string given is not a syntactically valid uri scheme. + set-scheme: func(scheme: option) -> result; /// Get the HTTP Authority for the Request. A value of `none` may be used /// with Related Schemes which do not require an Authority. The HTTP and @@ -207,8 +197,9 @@ interface types { authority: func() -> option; /// Set the HTTP Authority for the Request. A value of `none` may be used /// with Related Schemes which do not require an Authority. The HTTP and - /// HTTPS schemes always require an authority. - set-authority: func(authority: option); + /// HTTPS schemes always require an authority. Fails if the string given is + /// not a syntactically valid uri authority. + set-authority: func(authority: option) -> result; /// Get the headers associated with the Request. /// @@ -223,7 +214,7 @@ interface types { /// transport layer of the HTTP protocol. /// /// These timeouts are separate from any the user may use to bound a - /// blocking call to `wasi:io/poll.poll-list`. + /// blocking call to `wasi:io/poll.poll`. resource request-options { /// Construct a default `request-options` value. constructor(); @@ -351,16 +342,19 @@ interface types { /// Represents an outgoing HTTP Response. resource outgoing-response { - /// Construct an `outgoing-response`. + /// Construct an `outgoing-response`, with a default `status-code` of `200`. + /// If a different `status-code` is needed, it must be set via the + /// `set-status-code` method. /// - /// * `status-code` is the HTTP Status Code for the Response. /// * `headers` is the HTTP Headers for the Response. - constructor(status-code: status-code, headers: headers); + constructor(headers: headers); /// Get the HTTP Status Code for the Response. status-code: func() -> status-code; - /// Set the HTTP Status Code for the Response. - set-status-code: func(status-code: status-code); + + /// Set the HTTP Status Code for the Response. Fails if the status-code + /// given is not a valid http status code. + set-status-code: func(status-code: status-code) -> result; /// Get the headers associated with the Request. /// From c82631a84efddb71df32587c5cab38e689f17e89 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 8 Nov 2023 11:39:38 -0800 Subject: [PATCH 1282/1772] types.wit: delete file mode accessors and setters We believe there is value in supporting file modes for many applications, but for the sake of shipping Preview 2, we are out of time to implement these methods and test a a cross platform implementation of these in two separate engines. These functions may come back as part of an additional filesystem interface in a post Preview 2 patch version 0.2.n, or in Preview 3 or beyond. Until then, their design is still in the git history. --- proposals/filesystem/wit/types.wit | 78 ------------------------------ 1 file changed, 78 deletions(-) diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 7ac147f66..3bd8dc7e8 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -142,29 +142,6 @@ interface types { truncate, } - /// Permissions mode used by `open-at`, `change-file-permissions-at`, and - /// similar. - flags modes { - /// True if the resource is considered readable by the containing - /// filesystem. - readable, - /// True if the resource is considered writable by the containing - /// filesystem. - writable, - /// True if the resource is considered executable by the containing - /// filesystem. This does not apply to directories. - executable, - } - - /// Access type used by `access-at`. - variant access-type { - /// Test for readability, writeability, or executability. - access(modes), - - /// Test whether the path exists. - exists, - } - /// Number of hard links to an inode. type link-count = u64; @@ -538,8 +515,6 @@ interface types { open-flags: open-flags, /// Flags to use for the resulting descriptor. %flags: descriptor-flags, - /// Permissions to use when creating a new file. - modes: modes ) -> result; /// Read the contents of a symbolic link. @@ -588,25 +563,6 @@ interface types { new-path: string, ) -> result<_, error-code>; - /// Check accessibility of a filesystem path. - /// - /// Check whether the given filesystem path names an object which is - /// readable, writable, or executable, or whether it exists. - /// - /// This does not a guarantee that subsequent accesses will succeed, as - /// filesystem permissions may be modified asynchronously by external - /// entities. - /// - /// Note: This is similar to `faccessat` with the `AT_EACCESS` flag in POSIX. - access-at: func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to check. - path: string, - /// The type of check to perform. - %type: access-type - ) -> result<_, error-code>; - /// Unlink a filesystem object that is not a directory. /// /// Return `error-code::is-directory` if the path refers to a directory. @@ -616,40 +572,6 @@ interface types { path: string, ) -> result<_, error-code>; - /// Change the permissions of a filesystem object that is not a directory. - /// - /// Note that the ultimate meanings of these permissions is - /// filesystem-specific. - /// - /// Note: This is similar to `fchmodat` in POSIX. - change-file-permissions-at: func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the filesystem object. - modes: modes, - ) -> result<_, error-code>; - - /// Change the permissions of a directory. - /// - /// Note that the ultimate meanings of these permissions is - /// filesystem-specific. - /// - /// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" - /// flag. `read` on a directory implies readability and searchability, and - /// `execute` is not valid for directories. - /// - /// Note: This is similar to `fchmodat` in POSIX. - change-directory-permissions-at: func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the directory. - modes: modes, - ) -> result<_, error-code>; - /// Test whether two descriptors refer to the same filesystem object. /// /// In POSIX, this corresponds to testing whether the two descriptors have the From 72e2ad626e8666a38a13e406a35683de1fd16c24 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 8 Nov 2023 11:40:58 -0800 Subject: [PATCH 1283/1772] generate markdown --- proposals/filesystem/imports.md | 89 --------------------------------- 1 file changed, 89 deletions(-) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index 2cbf69054..c5c7d17fb 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -569,40 +569,6 @@ expanded.

                Truncate file to size 0, similar to `O_TRUNC` in POSIX.

              -

              flags modes

              -

              Permissions mode used by open-at, change-file-permissions-at, and -similar.

              -
              Flags members
              -
                -
              • -

                readable:

                -

                True if the resource is considered readable by the containing -filesystem. -

              • -
              • -

                writable:

                -

                True if the resource is considered writable by the containing -filesystem. -

              • -
              • -

                executable:

                -

                True if the resource is considered executable by the containing -filesystem. This does not apply to directories. -

              • -
              -

              variant access-type

              -

              Access type used by access-at.

              -
              Variant Cases
              -
                -
              • -

                access: modes

                -

                Test for readability, writeability, or executability. -

              • -
              • -

                exists

                -

                Test whether the path exists. -

              • -

              type link-count

              u64

              Number of hard links to an inode. @@ -1171,7 +1137,6 @@ contains truncate or create, and the base descriptor d

            • path: string
            • open-flags: open-flags
            • flags: descriptor-flags
            • -
            • modes: modes
            Return values
              @@ -1233,25 +1198,6 @@ filesystem, this function fails with e -

              [method]descriptor.access-at: func

              -

              Check accessibility of a filesystem path.

              -

              Check whether the given filesystem path names an object which is -readable, writable, or executable, or whether it exists.

              -

              This does not a guarantee that subsequent accesses will succeed, as -filesystem permissions may be modified asynchronously by external -entities.

              -

              Note: This is similar to faccessat with the AT_EACCESS flag in POSIX.

              -
              Params
              - -
              Return values
              -

              [method]descriptor.unlink-file-at: func

              Unlink a filesystem object that is not a directory.

              Return error-code::is-directory if the path refers to a directory. @@ -1265,41 +1211,6 @@ Note: This is similar to unlinkat(fd, path, 0) in POSIX.

              -

              [method]descriptor.change-file-permissions-at: func

              -

              Change the permissions of a filesystem object that is not a directory.

              -

              Note that the ultimate meanings of these permissions is -filesystem-specific.

              -

              Note: This is similar to fchmodat in POSIX.

              -
              Params
              - -
              Return values
              - -

              [method]descriptor.change-directory-permissions-at: func

              -

              Change the permissions of a directory.

              -

              Note that the ultimate meanings of these permissions is -filesystem-specific.

              -

              Unlike in POSIX, the executable flag is not reinterpreted as a "search" -flag. read on a directory implies readability and searchability, and -execute is not valid for directories.

              -

              Note: This is similar to fchmodat in POSIX.

              -
              Params
              - -
              Return values
              -

              [method]descriptor.is-same-object: func

              Test whether two descriptors refer to the same filesystem object.

              In POSIX, this corresponds to testing whether the two descriptors have the From 8159fbdd9702fe64a5eaf1eaa0a0d9a1f4587ad7 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 9 Nov 2023 18:18:59 -0600 Subject: [PATCH 1284/1772] Fill in the 'error' variant (#52) * Fill in the 'error' variant Resolves #49 * Switch to doc comments, make all variant fields optional * Rename error to error-code, and add the http-error-code downcast * Remove http-client-error, and add specializations * Address remaining comments * Regenerate proxy.md --------- Co-authored-by: Trevor Elliott Co-authored-by: Luke Wagner Co-authored-by: Pat Hickey Co-authored-by: Adam Foltzer Co-authored-by: Piotr Sikora --- proposals/http/proxy.md | 108 ++++++++++++++++++++++++++++----- proposals/http/wit/handler.wit | 6 +- proposals/http/wit/types.wit | 93 ++++++++++++++++++++++++---- 3 files changed, 179 insertions(+), 28 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 4194b5ee3..cef8d2a06 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -644,6 +644,9 @@ their headers, trailers, and bodies.

              #### `type output-stream` [`output-stream`](#output_stream)

              +#### `type stream-error` +[`error`](#error) +

              #### `type pollable` [`pollable`](#pollable)

              @@ -670,16 +673,76 @@ their headers, trailers, and bodies.

            • HTTPS
            • other: string
            -

            variant error

            -

            TODO: perhaps better align with HTTP semantics? -This type enumerates the different kinds of errors that may occur when -initially returning a response.

            +

            record DNS-error-payload

            +

            Defines the case payload type for DNS-error above:

            +
            Record Fields
            + +

            record TLS-alert-received-payload

            +

            Defines the case payload type for TLS-alert-received above:

            +
            Record Fields
            + +

            record field-size-payload

            +

            Defines the case payload type for HTTP-response-{header,trailer}-size above:

            +
            Record Fields
            + +

            variant error-code

            +

            These cases are inspired by the IANA HTTP Proxy Error Types: +https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types

            Variant Cases

            variant header-error

            This type enumerates the different kinds of errors that may occur when @@ -728,6 +791,23 @@ so they are provided as a list of bytes.

            resource future-incoming-response


            Functions

            +

            http-error-code: func

            +

            Attempts to extract a http-related error from the stream error +provided.

            +

            Stream operations which return stream-error::last-operation-failed have +a payload with more information about the operation that failed. This +payload can be passed through to this function to see if there's +http-related information about the error to return.

            +

            Note that this function is fallible because not all stream-related errors +are http-related errors.

            +
            Params
            + +
            Return values
            +

            [constructor]fields: func

            Construct an empty HTTP Fields.

            Return values
            @@ -1118,7 +1198,7 @@ implementation determine how to respond with an HTTP error response.

            Params

            [method]incoming-response.status: func

            Returns the status code from the incoming response.

            @@ -1210,7 +1290,7 @@ trailers were present in the body.

          Return values

          [constructor]outgoing-response: func

          Construct an outgoing-response, with a default status-code of 200. @@ -1331,7 +1411,7 @@ but those will be reported by the incoming-body

          Return values

          Import interface wasi:http/outgoing-handler

          This interface defines a handler of outgoing HTTP Requests. It should be @@ -1347,8 +1427,8 @@ imported by components which wish to make HTTP Requests.

          #### `type future-incoming-response` [`future-incoming-response`](#future_incoming_response)

          -#### `type error` -[`error`](#error) +#### `type error-code` +[`error-code`](#error_code)

          ----

          Functions

          @@ -1368,7 +1448,7 @@ through the future-incoming-response
          Return values

          Export interface wasi:http/incoming-handler


          diff --git a/proposals/http/wit/handler.wit b/proposals/http/wit/handler.wit index 21b97a354..a34a0649d 100644 --- a/proposals/http/wit/handler.wit +++ b/proposals/http/wit/handler.wit @@ -22,7 +22,9 @@ interface incoming-handler { /// This interface defines a handler of outgoing HTTP Requests. It should be /// imported by components which wish to make HTTP Requests. interface outgoing-handler { - use types.{outgoing-request, request-options, future-incoming-response, error}; + use types.{ + outgoing-request, request-options, future-incoming-response, error-code + }; /// This function is invoked with an outgoing HTTP Request, and it returns /// a resource `future-incoming-response` which represents an HTTP Response @@ -37,5 +39,5 @@ interface outgoing-handler { handle: func( request: outgoing-request, options: option - ) -> result; + ) -> result; } diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 0f3dba437..f24c09478 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -3,7 +3,7 @@ /// their headers, trailers, and bodies. interface types { use wasi:clocks/monotonic-clock.{duration}; - use wasi:io/streams.{input-stream, output-stream}; + use wasi:io/streams.{input-stream, output-stream, error as stream-error}; use wasi:io/poll.{pollable}; /// This type corresponds to HTTP standard Methods. @@ -27,16 +27,85 @@ interface types { other(string) } - /// TODO: perhaps better align with HTTP semantics? - /// This type enumerates the different kinds of errors that may occur when - /// initially returning a response. - variant error { - invalid-url(string), - timeout-error(string), - protocol-error(string), - unexpected-error(string) + /// These cases are inspired by the IANA HTTP Proxy Error Types: + /// https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types + variant error-code { + DNS-timeout, + DNS-error(DNS-error-payload), + destination-not-found, + destination-unavailable, + destination-IP-prohibited, + destination-IP-unroutable, + connection-refused, + connection-terminated, + connection-timeout, + connection-read-timeout, + connection-write-timeout, + connection-limit-reached, + TLS-protocol-error, + TLS-certificate-error, + TLS-alert-received(TLS-alert-received-payload), + HTTP-request-denied, + HTTP-request-length-required, + HTTP-request-body-size(option), + HTTP-request-method-invalid, + HTTP-request-URI-invalid, + HTTP-request-URI-too-long, + HTTP-request-header-section-size(option), + HTTP-request-header-size(option), + HTTP-request-trailer-section-size(option), + HTTP-request-trailer-size(field-size-payload), + HTTP-response-incomplete, + HTTP-response-header-section-size(option), + HTTP-response-header-size(field-size-payload), + HTTP-response-body-size(option), + HTTP-response-trailer-section-size(option), + HTTP-response-trailer-size(field-size-payload), + HTTP-response-transfer-coding(option), + HTTP-response-content-coding(option), + HTTP-response-timeout, + HTTP-upgrade-failed, + HTTP-protocol-error, + loop-detected, + configuration-error, + /// This is a catch-all error for anything that doesn't fit cleanly into a + /// more specific case. It also includes an optional string for an + /// unstructured description of the error. Users should not depend on the + /// string for diagnosing errors, as it's not required to be consistent + /// between implementations. + internal-error(option) + } + + /// Defines the case payload type for `DNS-error` above: + record DNS-error-payload { + rcode: option, + info-code: option + } + + /// Defines the case payload type for `TLS-alert-received` above: + record TLS-alert-received-payload { + alert-id: option, + alert-message: option } + /// Defines the case payload type for `HTTP-response-{header,trailer}-size` above: + record field-size-payload { + field-name: option, + field-size: option + } + + /// Attempts to extract a http-related `error` from the stream `error` + /// provided. + /// + /// Stream operations which return `stream-error::last-operation-failed` have + /// a payload with more information about the operation that failed. This + /// payload can be passed through to this function to see if there's + /// http-related information about the error to return. + /// + /// Note that this function is fallible because not all stream-related errors + /// are http-related errors. + http-error-code: func(err: borrow) -> option; + /// This type enumerates the different kinds of errors that may occur when /// setting or appending to a `fields` resource. variant header-error { @@ -261,7 +330,7 @@ interface types { /// implementation determine how to respond with an HTTP error response. set: static func( param: response-outparam, - response: result, + response: result, ); } @@ -336,7 +405,7 @@ interface types { /// as well as any trailers, were received successfully, or that an error /// occured receiving them. The optional `trailers` indicates whether or not /// trailers were present in the body. - get: func() -> option, error>>; + get: func() -> option, error-code>>; } /// Represents an outgoing HTTP Response. @@ -432,7 +501,7 @@ interface types { /// occured. Errors may also occur while consuming the response body, /// but those will be reported by the `incoming-body` and its /// `output-stream` child. - get: func() -> option>>; + get: func() -> option>>; } } From 7ddf980a1e67dfc5768ccc45d98251f406e95f0d Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 11:54:22 -0800 Subject: [PATCH 1285/1772] all child fields are immutable, add header-error.immutable error and update the doc strings throughout to specify which give a mutable fields and which give an immutable fields. also, add missed text that a future-trailers gives a child resource fields Co-authored-by: Trevor Elliott --- proposals/http/wit/types.wit | 46 ++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index f24c09478..639ab27ac 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -117,6 +117,10 @@ interface types { /// This error indicates that a forbidden `field-key` was used when trying /// to set a header in a `fields`. forbidden, + + /// This error indicates that the operation on the `fields` was not + /// permitted because the fields are immutable. + immutable, } /// Field keys are always strings. @@ -130,13 +134,24 @@ interface types { /// This following block defines the `fields` resource which corresponds to /// HTTP standard Fields. Fields are a common representation used for both /// Headers and Trailers. + /// + /// A `fields` may be mutable or immutable. A `fields` created using the + /// constructor, `from-list`, or `clone` will be mutable, but a `fields` + /// resource given by other means (including, but not limited to, + /// `incoming-request.headers`, `outgoing-request.headers`) might be be + /// immutable. In an immutable fields, the `set`, `append`, and `delete` + /// operations will fail with `header-error.immutable`. resource fields { /// Construct an empty HTTP Fields. + /// + /// The resulting `fields` is mutable. constructor(); /// Construct an HTTP Fields. /// + /// The resulting `fields` is mutable. + /// /// The list represents each key-value pair in the Fields. Keys /// which have multiple values are represented by multiple entries in this /// list with the same key. @@ -157,14 +172,20 @@ interface types { /// Set all of the values for a key. Clears any existing values for that /// key, if they have been set. + /// + /// Fails with `header-error.immutable` if the `fields` are immutable. set: func(name: field-key, value: list) -> result<_, header-error>; /// Delete all values for a key. Does nothing if no values for the key /// exist. + /// + /// Fails with `header-error.immutable` if the `fields` are immutable. delete: func(name: field-key) -> result<_, header-error>; /// Append a value for a key. Does not change or delete any existing /// values for that key. + /// + /// Fails with `header-error.immutable` if the `fields` are immutable. append: func(name: field-key, value: field-value) -> result<_, header-error>; /// Retrieve the full set of keys and values in the Fields. Like the @@ -176,7 +197,8 @@ interface types { entries: func() -> list>; /// Make a deep copy of the Fields. Equivelant in behavior to calling the - /// `fields` constructor on the return value of `entries` + /// `fields` constructor on the return value of `entries`. The resulting + /// `fields` is mutable. clone: func() -> fields; } @@ -201,7 +223,10 @@ interface types { /// Returns the authority from the request, if it was present. authority: func() -> option; - /// Returns the `headers` from the request. + /// Get the `headers` associated with the request. + /// + /// The returned `headers` resource is immutable: `set`, `append`, and + /// `delete` operations will fail with `header-error.immutable`. /// /// The `headers` returned are a child resource: it must be dropped before /// the parent `incoming-request` is dropped. Dropping this @@ -272,6 +297,9 @@ interface types { /// Get the headers associated with the Request. /// + /// The returned `headers` resource is immutable: `set`, `append`, and + /// `delete` operations will fail with `header-error.immutable`. + /// /// This headers resource is a child: it must be dropped before the parent /// `outgoing-request` is dropped, or its ownership is transfered to /// another component by e.g. `outgoing-handler.handle`. @@ -344,6 +372,12 @@ interface types { status: func() -> status-code; /// Returns the headers from the incoming response. + /// + /// The returned `headers` resource is immutable: `set`, `append`, and + /// `delete` operations will fail with `header-error.immutable`. + /// + /// This headers resource is a child: it must be dropped before the parent + /// `incoming-response` is dropped. headers: func() -> headers; /// Returns the incoming body. May be called at most once. Returns error @@ -405,6 +439,11 @@ interface types { /// as well as any trailers, were received successfully, or that an error /// occured receiving them. The optional `trailers` indicates whether or not /// trailers were present in the body. + /// + /// When some `trailers` are returned by this method, the `trailers` + /// resource is immutable, and a child. Use of the `set`, `append`, or + /// `delete` methods will return an error, and the resource must be + /// dropped before the parent `future-trailers` is dropped. get: func() -> option, error-code>>; } @@ -427,6 +466,9 @@ interface types { /// Get the headers associated with the Request. /// + /// The returned `headers` resource is immutable: `set`, `append`, and + /// `delete` operations will fail with `header-error.immutable`. + /// /// This headers resource is a child: it must be dropped before the parent /// `outgoing-request` is dropped, or its ownership is transfered to /// another component by e.g. `outgoing-handler.handle`. From 5714e6500e92e76b4ea489dc5ce75a00ea305153 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 14:29:33 -0800 Subject: [PATCH 1286/1772] generate markdown --- proposals/http/proxy.md | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index cef8d2a06..b55028ca7 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -760,6 +760,11 @@ syntactically invalid when used with an operation that sets headers in a

          This error indicates that a forbidden `field-key` was used when trying to set a header in a `fields`. +

        • +

          immutable

          +

          This error indicates that the operation on the `fields` was not +permitted because the fields are immutable. +

        type field-key

        string

        @@ -810,12 +815,14 @@ are http-related errors.

      [constructor]fields: func

      Construct an empty HTTP Fields.

      +

      The resulting fields is mutable.

      Return values

      [static]fields.from-list: func

      Construct an HTTP Fields.

      +

      The resulting fields is mutable.

      The list represents each key-value pair in the Fields. Keys which have multiple values are represented by multiple entries in this list with the same key.

      @@ -847,6 +854,7 @@ syntactically invalid, or if a header was forbidden.

      [method]fields.set: func

      Set all of the values for a key. Clears any existing values for that key, if they have been set.

      +

      Fails with header-error.immutable if the fields are immutable.

      Params
      • self: borrow<fields>
      • @@ -860,6 +868,7 @@ key, if they have been set.

        [method]fields.delete: func

        Delete all values for a key. Does nothing if no values for the key exist.

        +

        Fails with header-error.immutable if the fields are immutable.

        Params
        • self: borrow<fields>
        • @@ -872,6 +881,7 @@ exist.

          [method]fields.append: func

          Append a value for a key. Does not change or delete any existing values for that key.

          +

          Fails with header-error.immutable if the fields are immutable.

          Params
          • self: borrow<fields>
          • @@ -898,7 +908,8 @@ list with the same key.

          [method]fields.clone: func

          Make a deep copy of the Fields. Equivelant in behavior to calling the -fields constructor on the return value of entries

          +fields constructor on the return value of entries. The resulting +fields is mutable.

          Params
          • self: borrow<fields>
          • @@ -948,7 +959,9 @@ list with the same key.

          • option<string>

          [method]incoming-request.headers: func

          -

          Returns the headers from the request.

          +

          Get the headers associated with the request.

          +

          The returned headers resource is immutable: set, append, and +delete operations will fail with header-error.immutable.

          The headers returned are a child resource: it must be dropped before the parent incoming-request is dropped. Dropping this incoming-request before all children are dropped will trap.

          @@ -1102,6 +1115,8 @@ not a syntactically valid uri authority.

        [method]outgoing-request.headers: func

        Get the headers associated with the Request.

        +

        The returned headers resource is immutable: set, append, and +delete operations will fail with header-error.immutable.

        This headers resource is a child: it must be dropped before the parent outgoing-request is dropped, or its ownership is transfered to another component by e.g. outgoing-handler.handle.

        @@ -1212,6 +1227,10 @@ implementation determine how to respond with an HTTP error response.

      [method]incoming-response.headers: func

      Returns the headers from the incoming response.

      +

      The returned headers resource is immutable: set, append, and +delete operations will fail with header-error.immutable.

      +

      This headers resource is a child: it must be dropped before the parent +incoming-response is dropped.

      Params
      • self: borrow<incoming-response>
      • @@ -1284,6 +1303,10 @@ once the future is ready.

        as well as any trailers, were received successfully, or that an error occured receiving them. The optional trailers indicates whether or not trailers were present in the body.

        +

        When some trailers are returned by this method, the trailers +resource is immutable, and a child. Use of the set, append, or +delete methods will return an error, and the resource must be +dropped before the parent future-trailers is dropped.

        Params

        [method]outgoing-response.headers: func

        Get the headers associated with the Request.

        +

        The returned headers resource is immutable: set, append, and +delete operations will fail with header-error.immutable.

        This headers resource is a child: it must be dropped before the parent outgoing-request is dropped, or its ownership is transfered to another component by e.g. outgoing-handler.handle.

        From 83ea3ac7b147b149d1310a4503cdb57464e8ad13 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 14:32:05 -0800 Subject: [PATCH 1287/1772] move error resource to its own interface. (#56) * Move error resource to its own interface Two reasons for this design change: it is confusing having one type named stream/stream-error and another named stream/error. this error resource seems useful outside of just streams. Therefore, we are moving it to a separate interface error in the same package. There are no functional changes to this type. The doc comments are now more general. * generate markdown --- proposals/io/imports.md | 46 ++++++++++++++++++++++-------------- proposals/io/wit/error.wit | 34 ++++++++++++++++++++++++++ proposals/io/wit/streams.wit | 21 +--------------- 3 files changed, 63 insertions(+), 38 deletions(-) create mode 100644 proposals/io/wit/error.wit diff --git a/proposals/io/imports.md b/proposals/io/imports.md index e08b326ad..dbca06ea7 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -2,11 +2,33 @@ +

        Import interface wasi:io/error

        +
        +

        Types

        +

        resource error

        +
        +

        Functions

        +

        [method]error.to-debug-string: func

        +

        Returns a string that is suitable to assist humans in debugging +this error.

        +

        WARNING: The returned string should not be consumed mechanically! +It may change across platforms, hosts, or other implementation +details. Parsing this string is a major platform-compatibility +hazard.

        +
        Params
        + +
        Return values
        +
          +
        • string
        • +

        Import interface wasi:io/poll

        A poll API intended to let users wait for I/O events on multiple handles at once.

        @@ -64,11 +86,13 @@ stream types.

        when it does, they are expected to subsume this API.


        Types

        -

        type pollable

        -

        pollable

        +

        type error

        +

        error

        +

        +#### `type pollable` +[`pollable`](#pollable)

        -#### `resource error` -

        variant stream-error

        +#### `variant stream-error`

        An error for input-stream and output-stream operations.

        Variant Cases
          @@ -88,20 +112,6 @@ future operations.

          resource output-stream


          Functions

          -

          [method]error.to-debug-string: func

          -

          Returns a string that's suitable to assist humans in debugging this -error.

          -

          The returned string will change across platforms and hosts which -means that parsing it, for example, would be a -platform-compatibility hazard.

          -
          Params
          - -
          Return values
          -
            -
          • string
          • -

          [method]input-stream.read: func

          Perform a non-blocking read from the stream.

          This function returns a list of bytes containing the read data, diff --git a/proposals/io/wit/error.wit b/proposals/io/wit/error.wit new file mode 100644 index 000000000..66519efa6 --- /dev/null +++ b/proposals/io/wit/error.wit @@ -0,0 +1,34 @@ +package wasi:io; + + +interface error { + /// A resource which represents some error information. + /// + /// The only method provided by this resource is `to-debug-string`, + /// which provides some human-readable information about the error. + /// + /// In the `wasi:io` package, this resource is returned through the + /// `wasi:io/streams/stream-error` type. + /// + /// To provide more specific error information, other interfaces may + /// provide functions to further "downcast" this error into more specific + /// error information. For example, `error`s returned in streams derived + /// from filesystem types to be described using the filesystem's own + /// error-code type, using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter + /// `borrow` and returns + /// `option`. + /// + /// The set of functions which can "downcast" an `error` into a more + /// concrete type is open. + resource error { + /// Returns a string that is suitable to assist humans in debugging + /// this error. + /// + /// WARNING: The returned string should not be consumed mechanically! + /// It may change across platforms, hosts, or other implementation + /// details. Parsing this string is a major platform-compatibility + /// hazard. + to-debug-string: func() -> string; + } +} diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index 8999b28d2..643d7b775 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -6,6 +6,7 @@ package wasi:io; /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { + use error.{error}; use poll.{pollable}; /// An error for input-stream and output-stream operations. @@ -20,26 +21,6 @@ interface streams { closed } - /// Contextual error information about the last failure that happened on - /// a read, write, or flush from an `input-stream` or `output-stream`. - /// - /// This type is returned through the `stream-error` type whenever an - /// operation on a stream directly fails or an error is discovered - /// after-the-fact, for example when a write's failure shows up through a - /// later `flush` or `check-write`. - /// - /// Interfaces such as `wasi:filesystem/types` provide functionality to - /// further "downcast" this error into interface-specific error information. - resource error { - /// Returns a string that's suitable to assist humans in debugging this - /// error. - /// - /// The returned string will change across platforms and hosts which - /// means that parsing it, for example, would be a - /// platform-compatibility hazard. - to-debug-string: func() -> string; - } - /// An input bytestream. /// /// `input-stream`s are *non-blocking* to the extent practical on underlying From 7186c627f0af6010456e4f1db1960ddf6de8dcce Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 14:38:19 -0800 Subject: [PATCH 1288/1772] Remove timezone interface from the proposal for shipping Preview 2 (#55) * remove timezone interface from the proposal We believe there is value in providing timezone support in this package, but for the sake of shipping Preview 2, we are out of time to implement these methods and test a a cross platform implementation of these in two separate engines. We intend for this interface to return to the wasi:clocks package and be made in a post-Preview 2 patch version 0.2.n. Re-introducing this interface may be done with a revert of this commit once we have shipped Preview 2 and figured out the process for shipping patch versions. * generate markdown --- proposals/clocks/imports.md | 66 ------------------------------- proposals/clocks/wit/timezone.wit | 48 ---------------------- proposals/clocks/wit/world.wit | 1 - 3 files changed, 115 deletions(-) delete mode 100644 proposals/clocks/wit/timezone.wit diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index 0581792fd..e498f78e8 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -5,7 +5,6 @@

        • interface wasi:io/poll
        • interface wasi:clocks/monotonic-clock
        • interface wasi:clocks/wall-clock
        • -
        • interface wasi:clocks/timezone
      @@ -161,68 +160,3 @@ also known as Unix Time.
    • datetime
    -

    Import interface wasi:clocks/timezone

    -
    -

    Types

    -

    type datetime

    -

    datetime

    -

    -#### `record timezone-display` -

    Information useful for displaying the timezone of a specific datetime.

    -

    This information may vary within a single timezone to reflect daylight -saving time adjustments.

    -
    Record Fields
    -
      -
    • -

      utc-offset: s32

      -

      The number of seconds difference between UTC time and the local -time of the timezone. -

      The returned value will always be less than 86400 which is the -number of seconds in a day (246060).

      -

      In implementations that do not expose an actual time zone, this -should return 0.

      -
    • -
    • -

      name: string

      -

      The abbreviated name of the timezone to display to a user. The name -`UTC` indicates Coordinated Universal Time. Otherwise, this should -reference local standards for the name of the time zone. -

      In implementations that do not expose an actual time zone, this -should be the string UTC.

      -

      In time zones that do not have an applicable name, a formatted -representation of the UTC offset may be returned, such as -04:00.

      -
    • -
    • -

      in-daylight-saving-time: bool

      -

      Whether daylight saving time is active. -

      In implementations that do not expose an actual time zone, this -should return false.

      -
    • -
    -
    -

    Functions

    -

    display: func

    -

    Return information needed to display the given datetime. This includes -the UTC offset, the time zone name, and a flag indicating whether -daylight saving time is active.

    -

    If the timezone cannot be determined for the given datetime, return a -timezone-display for UTC with a utc-offset of 0 and no daylight -saving time.

    -
    Params
    - -
    Return values
    - -

    utc-offset: func

    -

    The same as display, but only return the UTC offset.

    -
    Params
    - -
    Return values
    -
      -
    • s32
    • -
    diff --git a/proposals/clocks/wit/timezone.wit b/proposals/clocks/wit/timezone.wit deleted file mode 100644 index e717e7b8d..000000000 --- a/proposals/clocks/wit/timezone.wit +++ /dev/null @@ -1,48 +0,0 @@ -interface timezone { - use wall-clock.{datetime}; - - /// Return information needed to display the given `datetime`. This includes - /// the UTC offset, the time zone name, and a flag indicating whether - /// daylight saving time is active. - /// - /// If the timezone cannot be determined for the given `datetime`, return a - /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight - /// saving time. - display: func(when: datetime) -> timezone-display; - - /// The same as `display`, but only return the UTC offset. - utc-offset: func(when: datetime) -> s32; - - /// Information useful for displaying the timezone of a specific `datetime`. - /// - /// This information may vary within a single `timezone` to reflect daylight - /// saving time adjustments. - record timezone-display { - /// The number of seconds difference between UTC time and the local - /// time of the timezone. - /// - /// The returned value will always be less than 86400 which is the - /// number of seconds in a day (24*60*60). - /// - /// In implementations that do not expose an actual time zone, this - /// should return 0. - utc-offset: s32, - - /// The abbreviated name of the timezone to display to a user. The name - /// `UTC` indicates Coordinated Universal Time. Otherwise, this should - /// reference local standards for the name of the time zone. - /// - /// In implementations that do not expose an actual time zone, this - /// should be the string `UTC`. - /// - /// In time zones that do not have an applicable name, a formatted - /// representation of the UTC offset may be returned, such as `-04:00`. - name: string, - - /// Whether daylight saving time is active. - /// - /// In implementations that do not expose an actual time zone, this - /// should return false. - in-daylight-saving-time: bool, - } -} diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index 3295ba8d9..888b9c26e 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -3,5 +3,4 @@ package wasi:clocks; world imports { import monotonic-clock; import wall-clock; - import timezone; } From d5097e4f28ff8dbc88772a709296c251adc12f26 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 14:47:14 -0800 Subject: [PATCH 1289/1772] make outgoing-body.finish fallible in case of a Content-Length mismatch --- proposals/http/wit/types.wit | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 639ab27ac..0dcfc3174 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -515,7 +515,15 @@ interface types { /// called to signal that the response is complete. If the `outgoing-body` /// is dropped without calling `outgoing-body.finalize`, the implementation /// should treat the body as corrupted. - finish: static func(this: outgoing-body, trailers: option); + /// + /// Fails if the body's `outgoing-request` or `outgoing-response` was + /// constructed with a Content-Length header, and the contents written + /// to the body (via `write`) does not match the value given in the + /// Content-Length. + finish: static func( + this: outgoing-body, + trailers: option + ) -> result<_, error-code>; } /// Represents a future which may eventaully return an incoming HTTP From ea06ce684ca05add49001b33c0cbdcaf4bd1952c Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 14:52:41 -0800 Subject: [PATCH 1290/1772] generate markdown --- proposals/http/proxy.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index b55028ca7..3011130db 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -1401,11 +1401,19 @@ will return error.

    called to signal that the response is complete. If the outgoing-body is dropped without calling outgoing-body.finalize, the implementation should treat the body as corrupted.

    +

    Fails if the body's outgoing-request or outgoing-response was +constructed with a Content-Length header, and the contents written +to the body (via write) does not match the value given in the +Content-Length.

    Params
    +
    Return values
    +

    [method]future-incoming-response.subscribe: func

    Returns a pollable which becomes ready when either the Response has been received, or an error has occured. When this pollable is ready, From 01d38bb3eb1eb76ac065b8c71475247038bfc36a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 15:00:24 -0800 Subject: [PATCH 1291/1772] set package version to 0.2.0-rc-2023-11-10 and put a `package` statement at the top of every wit, instead of just world.wit. --- proposals/random/wit/insecure-seed.wit | 1 + proposals/random/wit/insecure.wit | 1 + proposals/random/wit/random.wit | 1 + proposals/random/wit/world.wit | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index 139aed159..f76e87dad 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -1,3 +1,4 @@ +package wasi:random@0.2.0-rc-2023-11-10; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index 2ffd223cb..ec7b99737 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -1,3 +1,4 @@ +package wasi:random@0.2.0-rc-2023-11-10; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 2c3c6a859..7a7dfa27a 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -1,3 +1,4 @@ +package wasi:random@0.2.0-rc-2023-11-10; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index bb1dd7b59..49e5743b4 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:random; +package wasi:random@0.2.0-rc-2023-11-10; world imports { import random; From 42d2e8fa5062d970aa2a361bc371d7c809675484 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 15:01:12 -0800 Subject: [PATCH 1292/1772] generate markdown --- proposals/random/imports.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/random/imports.md b/proposals/random/imports.md index b8b1608c4..4bd886c5d 100644 --- a/proposals/random/imports.md +++ b/proposals/random/imports.md @@ -2,13 +2,13 @@

    -

    Import interface wasi:random/random

    +

    Import interface wasi:random/random@0.2.0-rc-2023-11-10

    WASI Random is a random data API.

    It is intended to be portable at least between Unix-family platforms and Windows.

    @@ -41,7 +41,7 @@ represented as a u64.

    • u64
    -

    Import interface wasi:random/insecure

    +

    Import interface wasi:random/insecure@0.2.0-rc-2023-11-10

    The insecure interface for insecure pseudo-random numbers.

    It is intended to be portable at least between Unix-family platforms and Windows.

    @@ -70,7 +70,7 @@ a long period.

    • u64
    -

    Import interface wasi:random/insecure-seed

    +

    Import interface wasi:random/insecure-seed@0.2.0-rc-2023-11-10

    The insecure-seed interface for seeding hash-map DoS resistance.

    It is intended to be portable at least between Unix-family platforms and Windows.

    From b30142ef9df12aafd230f0f982aad0bcd64181b4 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 15:38:51 -0800 Subject: [PATCH 1293/1772] set package version to 0.2.0-rc-2023-11-10 (#57) * set package version to 0.2.0-rc-2023-11-10 * generate markdown --- proposals/io/imports.md | 12 ++++++------ proposals/io/wit/error.wit | 2 +- proposals/io/wit/poll.wit | 2 +- proposals/io/wit/streams.wit | 2 +- proposals/io/wit/world.wit | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index dbca06ea7..6900a8840 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -2,13 +2,13 @@ -

    Import interface wasi:io/error

    +

    Import interface wasi:io/error@0.2.0-rc-2023-11-10


    Types

    resource error

    @@ -29,7 +29,7 @@ hazard.

    • string
    -

    Import interface wasi:io/poll

    +

    Import interface wasi:io/poll@0.2.0-rc-2023-11-10

    A poll API intended to let users wait for I/O events on multiple handles at once.


    @@ -79,7 +79,7 @@ being reaedy for I/O.

    • list<u32>
    -

    Import interface wasi:io/streams

    +

    Import interface wasi:io/streams@0.2.0-rc-2023-11-10

    WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

    In the future, the component model is expected to add built-in stream types; diff --git a/proposals/io/wit/error.wit b/proposals/io/wit/error.wit index 66519efa6..31918acbb 100644 --- a/proposals/io/wit/error.wit +++ b/proposals/io/wit/error.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; interface error { diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index 0829a7d08..bddde3c19 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index 643d7b775..e7e1b689a 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index 05244a965..8243da2ee 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; world imports { import streams; From 95bb25b3364f424b6f0f59f6141feaf179f6fff6 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 15:49:13 -0800 Subject: [PATCH 1294/1772] set wasi:clocks package version to 0.2.0-rc-2023-11-10 (#56) * wit-deps update wasi:io@0.2.0-rc-2023-11-10 * dependency on wasi-io uses explicit version tag * set wasi:clocks package version to 0.2.0-rc-2023-11-10 * generate markdown --- proposals/clocks/imports.md | 12 ++++----- proposals/clocks/wit/deps.lock | 4 +-- proposals/clocks/wit/deps/io/error.wit | 34 ++++++++++++++++++++++++ proposals/clocks/wit/deps/io/poll.wit | 2 +- proposals/clocks/wit/deps/io/streams.wit | 23 ++-------------- proposals/clocks/wit/deps/io/world.wit | 2 +- proposals/clocks/wit/monotonic-clock.wit | 3 ++- proposals/clocks/wit/wall-clock.wit | 1 + proposals/clocks/wit/world.wit | 2 +- 9 files changed, 50 insertions(+), 33 deletions(-) create mode 100644 proposals/clocks/wit/deps/io/error.wit diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index e498f78e8..54b0ed639 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -2,13 +2,13 @@

    -

    Import interface wasi:io/poll

    +

    Import interface wasi:io/poll@0.2.0-rc-2023-11-10

    A poll API intended to let users wait for I/O events on multiple handles at once.


    @@ -58,7 +58,7 @@ being reaedy for I/O.

    • list<u32>
    -

    Import interface wasi:clocks/monotonic-clock

    +

    Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

    WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

    It is intended to be portable at least between Unix-family platforms and @@ -119,7 +119,7 @@ occured.

    -

    Import interface wasi:clocks/wall-clock

    +

    Import interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10

    WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

    diff --git a/proposals/clocks/wit/deps.lock b/proposals/clocks/wit/deps.lock index 472b87f14..48ee47f75 100644 --- a/proposals/clocks/wit/deps.lock +++ b/proposals/clocks/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "fb76f4449eea54d06b56fc6a7ca988da51bd84a54d2021cf18da67b5e2c7ebcf" -sha512 = "c005e2a91522958a9537827a49ae344e1cb39d66e85492901a86bcc7e322ba8d0a7f1a02c9b9f840c123b4ad97e297355fac98d4822536d1426d1096dd1d73ac" +sha256 = "f2e6127b235c37c06be675a904d6acf08db953ea688d78c42892c6ad3bd194e4" +sha512 = "32feefbc115c34bf6968cb6e9dc15e755698ee90648e5a5d84448917c36a318bd61b401195eb64330e2475e1d098bfb8dee1440d594a68e0797748762bd84ae5" diff --git a/proposals/clocks/wit/deps/io/error.wit b/proposals/clocks/wit/deps/io/error.wit new file mode 100644 index 000000000..31918acbb --- /dev/null +++ b/proposals/clocks/wit/deps/io/error.wit @@ -0,0 +1,34 @@ +package wasi:io@0.2.0-rc-2023-11-10; + + +interface error { + /// A resource which represents some error information. + /// + /// The only method provided by this resource is `to-debug-string`, + /// which provides some human-readable information about the error. + /// + /// In the `wasi:io` package, this resource is returned through the + /// `wasi:io/streams/stream-error` type. + /// + /// To provide more specific error information, other interfaces may + /// provide functions to further "downcast" this error into more specific + /// error information. For example, `error`s returned in streams derived + /// from filesystem types to be described using the filesystem's own + /// error-code type, using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter + /// `borrow` and returns + /// `option`. + /// + /// The set of functions which can "downcast" an `error` into a more + /// concrete type is open. + resource error { + /// Returns a string that is suitable to assist humans in debugging + /// this error. + /// + /// WARNING: The returned string should not be consumed mechanically! + /// It may change across platforms, hosts, or other implementation + /// details. Parsing this string is a major platform-compatibility + /// hazard. + to-debug-string: func() -> string; + } +} diff --git a/proposals/clocks/wit/deps/io/poll.wit b/proposals/clocks/wit/deps/io/poll.wit index 0829a7d08..bddde3c19 100644 --- a/proposals/clocks/wit/deps/io/poll.wit +++ b/proposals/clocks/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/clocks/wit/deps/io/streams.wit b/proposals/clocks/wit/deps/io/streams.wit index 8999b28d2..e7e1b689a 100644 --- a/proposals/clocks/wit/deps/io/streams.wit +++ b/proposals/clocks/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -6,6 +6,7 @@ package wasi:io; /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { + use error.{error}; use poll.{pollable}; /// An error for input-stream and output-stream operations. @@ -20,26 +21,6 @@ interface streams { closed } - /// Contextual error information about the last failure that happened on - /// a read, write, or flush from an `input-stream` or `output-stream`. - /// - /// This type is returned through the `stream-error` type whenever an - /// operation on a stream directly fails or an error is discovered - /// after-the-fact, for example when a write's failure shows up through a - /// later `flush` or `check-write`. - /// - /// Interfaces such as `wasi:filesystem/types` provide functionality to - /// further "downcast" this error into interface-specific error information. - resource error { - /// Returns a string that's suitable to assist humans in debugging this - /// error. - /// - /// The returned string will change across platforms and hosts which - /// means that parsing it, for example, would be a - /// platform-compatibility hazard. - to-debug-string: func() -> string; - } - /// An input bytestream. /// /// `input-stream`s are *non-blocking* to the extent practical on underlying diff --git a/proposals/clocks/wit/deps/io/world.wit b/proposals/clocks/wit/deps/io/world.wit index 05244a965..8243da2ee 100644 --- a/proposals/clocks/wit/deps/io/world.wit +++ b/proposals/clocks/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; world imports { import streams; diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index afacdbb61..09ef32c36 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -1,3 +1,4 @@ +package wasi:clocks@0.2.0-rc-2023-11-10; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -9,7 +10,7 @@ /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:io/poll.{pollable}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/clocks/wit/wall-clock.wit b/proposals/clocks/wit/wall-clock.wit index c39564967..8abb9a0c0 100644 --- a/proposals/clocks/wit/wall-clock.wit +++ b/proposals/clocks/wit/wall-clock.wit @@ -1,3 +1,4 @@ +package wasi:clocks@0.2.0-rc-2023-11-10; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index 888b9c26e..8fa080f0e 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks; +package wasi:clocks@0.2.0-rc-2023-11-10; world imports { import monotonic-clock; From d74a3660d0697cb7232d9b444657a2c195b12152 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 15:52:14 -0800 Subject: [PATCH 1295/1772] wit-deps update --- proposals/filesystem/wit/deps.lock | 8 ++-- .../wit/deps/clocks/monotonic-clock.wit | 3 +- .../filesystem/wit/deps/clocks/timezone.wit | 48 ------------------- .../filesystem/wit/deps/clocks/wall-clock.wit | 1 + .../filesystem/wit/deps/clocks/world.wit | 3 +- proposals/filesystem/wit/deps/io/error.wit | 34 +++++++++++++ proposals/filesystem/wit/deps/io/poll.wit | 2 +- proposals/filesystem/wit/deps/io/streams.wit | 23 +-------- proposals/filesystem/wit/deps/io/world.wit | 2 +- 9 files changed, 46 insertions(+), 78 deletions(-) delete mode 100644 proposals/filesystem/wit/deps/clocks/timezone.wit create mode 100644 proposals/filesystem/wit/deps/io/error.wit diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index 1c063bc54..be53c765e 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "8d6b9f7a8bf9466bdc68043c33e054878fdf09c1cc69c19c99eeadd3bb257a90" -sha512 = "21b65d911930c4512bb3caa08459283fc70b1ccc5159313092334cffd6662fb92cfe90577b51829ef363e2d02530802c88f2a1f82db43964d1f8bff7ecbc794b" +sha256 = "89da8eca4cd195516574c89c5b3c24a7b5af3ff2565c16753d20d3bdbc5fc60f" +sha512 = "244079b3f592d58478a97adbd0bee8d49ae9dd1a3e435651ee40997b50da9fe62cfaba7e3ec7f7406d7d0288d278a43a3a0bc5150226ba40ce0f8ac6d33f7ddb" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "fb76f4449eea54d06b56fc6a7ca988da51bd84a54d2021cf18da67b5e2c7ebcf" -sha512 = "c005e2a91522958a9537827a49ae344e1cb39d66e85492901a86bcc7e322ba8d0a7f1a02c9b9f840c123b4ad97e297355fac98d4822536d1426d1096dd1d73ac" +sha256 = "f2e6127b235c37c06be675a904d6acf08db953ea688d78c42892c6ad3bd194e4" +sha512 = "32feefbc115c34bf6968cb6e9dc15e755698ee90648e5a5d84448917c36a318bd61b401195eb64330e2475e1d098bfb8dee1440d594a68e0797748762bd84ae5" diff --git a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit index afacdbb61..09ef32c36 100644 --- a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit @@ -1,3 +1,4 @@ +package wasi:clocks@0.2.0-rc-2023-11-10; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -9,7 +10,7 @@ /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:io/poll.{pollable}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/filesystem/wit/deps/clocks/timezone.wit b/proposals/filesystem/wit/deps/clocks/timezone.wit deleted file mode 100644 index e717e7b8d..000000000 --- a/proposals/filesystem/wit/deps/clocks/timezone.wit +++ /dev/null @@ -1,48 +0,0 @@ -interface timezone { - use wall-clock.{datetime}; - - /// Return information needed to display the given `datetime`. This includes - /// the UTC offset, the time zone name, and a flag indicating whether - /// daylight saving time is active. - /// - /// If the timezone cannot be determined for the given `datetime`, return a - /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight - /// saving time. - display: func(when: datetime) -> timezone-display; - - /// The same as `display`, but only return the UTC offset. - utc-offset: func(when: datetime) -> s32; - - /// Information useful for displaying the timezone of a specific `datetime`. - /// - /// This information may vary within a single `timezone` to reflect daylight - /// saving time adjustments. - record timezone-display { - /// The number of seconds difference between UTC time and the local - /// time of the timezone. - /// - /// The returned value will always be less than 86400 which is the - /// number of seconds in a day (24*60*60). - /// - /// In implementations that do not expose an actual time zone, this - /// should return 0. - utc-offset: s32, - - /// The abbreviated name of the timezone to display to a user. The name - /// `UTC` indicates Coordinated Universal Time. Otherwise, this should - /// reference local standards for the name of the time zone. - /// - /// In implementations that do not expose an actual time zone, this - /// should be the string `UTC`. - /// - /// In time zones that do not have an applicable name, a formatted - /// representation of the UTC offset may be returned, such as `-04:00`. - name: string, - - /// Whether daylight saving time is active. - /// - /// In implementations that do not expose an actual time zone, this - /// should return false. - in-daylight-saving-time: bool, - } -} diff --git a/proposals/filesystem/wit/deps/clocks/wall-clock.wit b/proposals/filesystem/wit/deps/clocks/wall-clock.wit index c39564967..8abb9a0c0 100644 --- a/proposals/filesystem/wit/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/wall-clock.wit @@ -1,3 +1,4 @@ +package wasi:clocks@0.2.0-rc-2023-11-10; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/filesystem/wit/deps/clocks/world.wit b/proposals/filesystem/wit/deps/clocks/world.wit index 3295ba8d9..8fa080f0e 100644 --- a/proposals/filesystem/wit/deps/clocks/world.wit +++ b/proposals/filesystem/wit/deps/clocks/world.wit @@ -1,7 +1,6 @@ -package wasi:clocks; +package wasi:clocks@0.2.0-rc-2023-11-10; world imports { import monotonic-clock; import wall-clock; - import timezone; } diff --git a/proposals/filesystem/wit/deps/io/error.wit b/proposals/filesystem/wit/deps/io/error.wit new file mode 100644 index 000000000..31918acbb --- /dev/null +++ b/proposals/filesystem/wit/deps/io/error.wit @@ -0,0 +1,34 @@ +package wasi:io@0.2.0-rc-2023-11-10; + + +interface error { + /// A resource which represents some error information. + /// + /// The only method provided by this resource is `to-debug-string`, + /// which provides some human-readable information about the error. + /// + /// In the `wasi:io` package, this resource is returned through the + /// `wasi:io/streams/stream-error` type. + /// + /// To provide more specific error information, other interfaces may + /// provide functions to further "downcast" this error into more specific + /// error information. For example, `error`s returned in streams derived + /// from filesystem types to be described using the filesystem's own + /// error-code type, using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter + /// `borrow` and returns + /// `option`. + /// + /// The set of functions which can "downcast" an `error` into a more + /// concrete type is open. + resource error { + /// Returns a string that is suitable to assist humans in debugging + /// this error. + /// + /// WARNING: The returned string should not be consumed mechanically! + /// It may change across platforms, hosts, or other implementation + /// details. Parsing this string is a major platform-compatibility + /// hazard. + to-debug-string: func() -> string; + } +} diff --git a/proposals/filesystem/wit/deps/io/poll.wit b/proposals/filesystem/wit/deps/io/poll.wit index 0829a7d08..bddde3c19 100644 --- a/proposals/filesystem/wit/deps/io/poll.wit +++ b/proposals/filesystem/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index 8999b28d2..e7e1b689a 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -6,6 +6,7 @@ package wasi:io; /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { + use error.{error}; use poll.{pollable}; /// An error for input-stream and output-stream operations. @@ -20,26 +21,6 @@ interface streams { closed } - /// Contextual error information about the last failure that happened on - /// a read, write, or flush from an `input-stream` or `output-stream`. - /// - /// This type is returned through the `stream-error` type whenever an - /// operation on a stream directly fails or an error is discovered - /// after-the-fact, for example when a write's failure shows up through a - /// later `flush` or `check-write`. - /// - /// Interfaces such as `wasi:filesystem/types` provide functionality to - /// further "downcast" this error into interface-specific error information. - resource error { - /// Returns a string that's suitable to assist humans in debugging this - /// error. - /// - /// The returned string will change across platforms and hosts which - /// means that parsing it, for example, would be a - /// platform-compatibility hazard. - to-debug-string: func() -> string; - } - /// An input bytestream. /// /// `input-stream`s are *non-blocking* to the extent practical on underlying diff --git a/proposals/filesystem/wit/deps/io/world.wit b/proposals/filesystem/wit/deps/io/world.wit index 05244a965..8243da2ee 100644 --- a/proposals/filesystem/wit/deps/io/world.wit +++ b/proposals/filesystem/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; world imports { import streams; From 4320d796b1dd86d80d6b23c19e68da78767a464b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 15:52:23 -0800 Subject: [PATCH 1296/1772] update use of wasi:io and wasi:clocks to use version tag --- proposals/filesystem/wit/types.wit | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 3bd8dc7e8..ab0fd2988 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -23,8 +23,8 @@ /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { - use wasi:io/streams.{input-stream, output-stream, error}; - use wasi:clocks/wall-clock.{datetime}; + use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream, error}; + use wasi:clocks/wall-clock@0.2.0-rc-2023-11-10.{datetime}; /// File size or length of a region within a file. type filesize = u64; From eb636d0b03fb7fc9e7f94753a1a4a025905c866f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 15:53:27 -0800 Subject: [PATCH 1297/1772] set wasi:filesystem version to 0.2.0-rc-2023-11-10 --- proposals/filesystem/wit/preopens.wit | 2 ++ proposals/filesystem/wit/types.wit | 1 + proposals/filesystem/wit/world.wit | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit index 3f787ac3f..95ec67843 100644 --- a/proposals/filesystem/wit/preopens.wit +++ b/proposals/filesystem/wit/preopens.wit @@ -1,3 +1,5 @@ +package wasi:filesystem@0.2.0-rc-2023-11-10; + interface preopens { use types.{descriptor}; diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index ab0fd2988..059722ab8 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -1,3 +1,4 @@ +package wasi:filesystem@0.2.0-rc-2023-11-10; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index bd472942d..285e0bae9 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem; +package wasi:filesystem@0.2.0-rc-2023-11-10; world imports { import types; From 87761bc5944273052bb2b5c904c8875563b93b55 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 15:56:10 -0800 Subject: [PATCH 1298/1772] wit-deps update --- proposals/sockets/wit/deps.lock | 4 +-- proposals/sockets/wit/deps/io/error.wit | 34 +++++++++++++++++++++++ proposals/sockets/wit/deps/io/poll.wit | 2 +- proposals/sockets/wit/deps/io/streams.wit | 23 ++------------- proposals/sockets/wit/deps/io/world.wit | 2 +- 5 files changed, 40 insertions(+), 25 deletions(-) create mode 100644 proposals/sockets/wit/deps/io/error.wit diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index 472b87f14..48ee47f75 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "fb76f4449eea54d06b56fc6a7ca988da51bd84a54d2021cf18da67b5e2c7ebcf" -sha512 = "c005e2a91522958a9537827a49ae344e1cb39d66e85492901a86bcc7e322ba8d0a7f1a02c9b9f840c123b4ad97e297355fac98d4822536d1426d1096dd1d73ac" +sha256 = "f2e6127b235c37c06be675a904d6acf08db953ea688d78c42892c6ad3bd194e4" +sha512 = "32feefbc115c34bf6968cb6e9dc15e755698ee90648e5a5d84448917c36a318bd61b401195eb64330e2475e1d098bfb8dee1440d594a68e0797748762bd84ae5" diff --git a/proposals/sockets/wit/deps/io/error.wit b/proposals/sockets/wit/deps/io/error.wit new file mode 100644 index 000000000..31918acbb --- /dev/null +++ b/proposals/sockets/wit/deps/io/error.wit @@ -0,0 +1,34 @@ +package wasi:io@0.2.0-rc-2023-11-10; + + +interface error { + /// A resource which represents some error information. + /// + /// The only method provided by this resource is `to-debug-string`, + /// which provides some human-readable information about the error. + /// + /// In the `wasi:io` package, this resource is returned through the + /// `wasi:io/streams/stream-error` type. + /// + /// To provide more specific error information, other interfaces may + /// provide functions to further "downcast" this error into more specific + /// error information. For example, `error`s returned in streams derived + /// from filesystem types to be described using the filesystem's own + /// error-code type, using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter + /// `borrow` and returns + /// `option`. + /// + /// The set of functions which can "downcast" an `error` into a more + /// concrete type is open. + resource error { + /// Returns a string that is suitable to assist humans in debugging + /// this error. + /// + /// WARNING: The returned string should not be consumed mechanically! + /// It may change across platforms, hosts, or other implementation + /// details. Parsing this string is a major platform-compatibility + /// hazard. + to-debug-string: func() -> string; + } +} diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit index 0829a7d08..bddde3c19 100644 --- a/proposals/sockets/wit/deps/io/poll.wit +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index 8999b28d2..e7e1b689a 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -6,6 +6,7 @@ package wasi:io; /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { + use error.{error}; use poll.{pollable}; /// An error for input-stream and output-stream operations. @@ -20,26 +21,6 @@ interface streams { closed } - /// Contextual error information about the last failure that happened on - /// a read, write, or flush from an `input-stream` or `output-stream`. - /// - /// This type is returned through the `stream-error` type whenever an - /// operation on a stream directly fails or an error is discovered - /// after-the-fact, for example when a write's failure shows up through a - /// later `flush` or `check-write`. - /// - /// Interfaces such as `wasi:filesystem/types` provide functionality to - /// further "downcast" this error into interface-specific error information. - resource error { - /// Returns a string that's suitable to assist humans in debugging this - /// error. - /// - /// The returned string will change across platforms and hosts which - /// means that parsing it, for example, would be a - /// platform-compatibility hazard. - to-debug-string: func() -> string; - } - /// An input bytestream. /// /// `input-stream`s are *non-blocking* to the extent practical on underlying diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit index 05244a965..8243da2ee 100644 --- a/proposals/sockets/wit/deps/io/world.wit +++ b/proposals/sockets/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; world imports { import streams; From 068ab0f00ced9f830a37c8c5d377d07409ab1639 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 15:57:22 -0800 Subject: [PATCH 1299/1772] update use of wasi:io to use rc version --- proposals/sockets/wit/ip-name-lookup.wit | 2 +- proposals/sockets/wit/tcp.wit | 4 ++-- proposals/sockets/wit/udp.wit | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index 22113ae4c..12f86b5de 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,6 +1,6 @@ interface ip-name-lookup { - use wasi:io/poll.{pollable}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; use network.{network, error-code, ip-address, ip-address-family}; diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 1de68a7f5..d44e1c227 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,7 +1,7 @@ interface tcp { - use wasi:io/streams.{input-stream, output-stream}; - use wasi:io/poll.{pollable}; + use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; use network.{network, error-code, ip-socket-address, ip-address-family}; enum shutdown-type { diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index ca497b3a4..0f5db53e3 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,6 +1,6 @@ interface udp { - use wasi:io/poll.{pollable}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; use network.{network, error-code, ip-socket-address, ip-address-family}; From fea3485903b062827ee6377022bdb06fa58cf816 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 15:57:55 -0800 Subject: [PATCH 1300/1772] set wasi:sockets package version to 0.2.0-rc-2023-11-10 --- proposals/sockets/wit/world.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index 432b0dc99..49ad8d3d9 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets; +package wasi:sockets@0.2.0-rc-2023-11-10; world imports { import instance-network; From 27be7011d5265ebaa34540e4f8e13fab359cb21f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 15:58:36 -0800 Subject: [PATCH 1301/1772] generate markdown --- proposals/sockets/imports.md | 82 ++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 755596317..3f35ee118 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -2,19 +2,20 @@ -

    Import interface wasi:sockets/network

    +

    Import interface wasi:sockets/network@0.2.0-rc-2023-11-10


    Types

    resource network

    @@ -225,7 +226,7 @@ combined with a couple of errors that are always possible:

  • ipv4: ipv4-socket-address
  • ipv6: ipv6-socket-address
  • -

    Import interface wasi:sockets/instance-network

    +

    Import interface wasi:sockets/instance-network@0.2.0-rc-2023-11-10

    This interface provides a value-export of the default network handle..


    Types

    @@ -240,7 +241,7 @@ combined with a couple of errors that are always possible:

    -

    Import interface wasi:io/poll

    +

    Import interface wasi:io/poll@0.2.0-rc-2023-11-10

    A poll API intended to let users wait for I/O events on multiple handles at once.


    @@ -290,7 +291,7 @@ being reaedy for I/O.

    • list<u32>
    -

    Import interface wasi:sockets/udp

    +

    Import interface wasi:sockets/udp@0.2.0-rc-2023-11-10


    Types

    type pollable

    @@ -652,7 +653,7 @@ It's planned to be removed when future is natively supported in Pre -

    Import interface wasi:sockets/udp-create-socket

    +

    Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2023-11-10


    Types

    type network

    @@ -697,18 +698,41 @@ the socket is effectively an in-memory configuration object, unable to communica -

    Import interface wasi:io/streams

    +

    Import interface wasi:io/error@0.2.0-rc-2023-11-10

    +
    +

    Types

    +

    resource error

    +
    +

    Functions

    +

    [method]error.to-debug-string: func

    +

    Returns a string that is suitable to assist humans in debugging +this error.

    +

    WARNING: The returned string should not be consumed mechanically! +It may change across platforms, hosts, or other implementation +details. Parsing this string is a major platform-compatibility +hazard.

    +
    Params
    + +
    Return values
    +
      +
    • string
    • +
    +

    Import interface wasi:io/streams@0.2.0-rc-2023-11-10

    WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

    In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


    Types

    -

    type pollable

    -

    pollable

    +

    type error

    +

    error

    +

    +#### `type pollable` +[`pollable`](#pollable)

    -#### `resource error` -

    variant stream-error

    +#### `variant stream-error`

    An error for input-stream and output-stream operations.

    Variant Cases
    -

    Import interface wasi:sockets/instance-network@0.2.0-rc-2023-11-10

    +

    Import interface wasi:sockets/instance-network

    This interface provides a value-export of the default network handle..


    Types

    @@ -241,7 +240,7 @@ combined with a couple of errors that are always possible:

    -

    Import interface wasi:io/poll@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/poll

    A poll API intended to let users wait for I/O events on multiple handles at once.


    @@ -291,7 +290,7 @@ being reaedy for I/O.

    • list<u32>
    -

    Import interface wasi:sockets/udp@0.2.0-rc-2023-11-10

    +

    Import interface wasi:sockets/udp


    Types

    type pollable

    @@ -653,7 +652,7 @@ It's planned to be removed when future is natively supported in Pre -

    Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2023-11-10

    +

    Import interface wasi:sockets/udp-create-socket


    Types

    type network

    @@ -698,41 +697,18 @@ the socket is effectively an in-memory configuration object, unable to communica -

    Import interface wasi:io/error@0.2.0-rc-2023-11-10

    -
    -

    Types

    -

    resource error

    -
    -

    Functions

    -

    [method]error.to-debug-string: func

    -

    Returns a string that is suitable to assist humans in debugging -this error.

    -

    WARNING: The returned string should not be consumed mechanically! -It may change across platforms, hosts, or other implementation -details. Parsing this string is a major platform-compatibility -hazard.

    -
    Params
    - -
    Return values
    -
      -
    • string
    • -
    -

    Import interface wasi:io/streams@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/streams

    WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

    In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


    Types

    -

    type error

    -

    error

    -

    -#### `type pollable` -[`pollable`](#pollable) +

    type pollable

    +

    pollable

    -#### `variant stream-error` +#### `resource error` +

    variant stream-error

    An error for input-stream and output-stream operations.

    Variant Cases
      @@ -752,6 +728,20 @@ future operations.

      resource output-stream


      Functions

      +

      [method]error.to-debug-string: func

      +

      Returns a string that's suitable to assist humans in debugging this +error.

      +

      The returned string will change across platforms and hosts which +means that parsing it, for example, would be a +platform-compatibility hazard.

      +
      Params
      + +
      Return values
      +
        +
      • string
      • +

      [method]input-stream.read: func

      Perform a non-blocking read from the stream.

      This function returns a list of bytes containing the read data, @@ -1022,7 +1012,7 @@ is ready for reading, before performing the splice.

      -

      Import interface wasi:sockets/tcp@0.2.0-rc-2023-11-10

      +

      Import interface wasi:sockets/tcp


      Types

      type input-stream

      @@ -1502,7 +1492,7 @@ operations on the output-stream associ -

      Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2023-11-10

      +

      Import interface wasi:sockets/tcp-create-socket


      Types

      type network

      @@ -1547,7 +1537,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

      Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2023-11-10

      +

      Import interface wasi:sockets/ip-name-lookup


      Types

      type pollable

      diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index 48ee47f75..472b87f14 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "f2e6127b235c37c06be675a904d6acf08db953ea688d78c42892c6ad3bd194e4" -sha512 = "32feefbc115c34bf6968cb6e9dc15e755698ee90648e5a5d84448917c36a318bd61b401195eb64330e2475e1d098bfb8dee1440d594a68e0797748762bd84ae5" +sha256 = "fb76f4449eea54d06b56fc6a7ca988da51bd84a54d2021cf18da67b5e2c7ebcf" +sha512 = "c005e2a91522958a9537827a49ae344e1cb39d66e85492901a86bcc7e322ba8d0a7f1a02c9b9f840c123b4ad97e297355fac98d4822536d1426d1096dd1d73ac" diff --git a/proposals/sockets/wit/deps/io/error.wit b/proposals/sockets/wit/deps/io/error.wit deleted file mode 100644 index 31918acbb..000000000 --- a/proposals/sockets/wit/deps/io/error.wit +++ /dev/null @@ -1,34 +0,0 @@ -package wasi:io@0.2.0-rc-2023-11-10; - - -interface error { - /// A resource which represents some error information. - /// - /// The only method provided by this resource is `to-debug-string`, - /// which provides some human-readable information about the error. - /// - /// In the `wasi:io` package, this resource is returned through the - /// `wasi:io/streams/stream-error` type. - /// - /// To provide more specific error information, other interfaces may - /// provide functions to further "downcast" this error into more specific - /// error information. For example, `error`s returned in streams derived - /// from filesystem types to be described using the filesystem's own - /// error-code type, using the function - /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter - /// `borrow` and returns - /// `option`. - /// - /// The set of functions which can "downcast" an `error` into a more - /// concrete type is open. - resource error { - /// Returns a string that is suitable to assist humans in debugging - /// this error. - /// - /// WARNING: The returned string should not be consumed mechanically! - /// It may change across platforms, hosts, or other implementation - /// details. Parsing this string is a major platform-compatibility - /// hazard. - to-debug-string: func() -> string; - } -} diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit index bddde3c19..0829a7d08 100644 --- a/proposals/sockets/wit/deps/io/poll.wit +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index e7e1b689a..8999b28d2 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -6,7 +6,6 @@ package wasi:io@0.2.0-rc-2023-11-10; /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { - use error.{error}; use poll.{pollable}; /// An error for input-stream and output-stream operations. @@ -21,6 +20,26 @@ interface streams { closed } + /// Contextual error information about the last failure that happened on + /// a read, write, or flush from an `input-stream` or `output-stream`. + /// + /// This type is returned through the `stream-error` type whenever an + /// operation on a stream directly fails or an error is discovered + /// after-the-fact, for example when a write's failure shows up through a + /// later `flush` or `check-write`. + /// + /// Interfaces such as `wasi:filesystem/types` provide functionality to + /// further "downcast" this error into interface-specific error information. + resource error { + /// Returns a string that's suitable to assist humans in debugging this + /// error. + /// + /// The returned string will change across platforms and hosts which + /// means that parsing it, for example, would be a + /// platform-compatibility hazard. + to-debug-string: func() -> string; + } + /// An input bytestream. /// /// `input-stream`s are *non-blocking* to the extent practical on underlying diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit index 8243da2ee..05244a965 100644 --- a/proposals/sockets/wit/deps/io/world.wit +++ b/proposals/sockets/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io; world imports { import streams; diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index 12f86b5de..22113ae4c 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,6 +1,6 @@ interface ip-name-lookup { - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:io/poll.{pollable}; use network.{network, error-code, ip-address, ip-address-family}; diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index d44e1c227..1de68a7f5 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,7 +1,7 @@ interface tcp { - use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream}; - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:io/streams.{input-stream, output-stream}; + use wasi:io/poll.{pollable}; use network.{network, error-code, ip-socket-address, ip-address-family}; enum shutdown-type { diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 0f5db53e3..ca497b3a4 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,6 +1,6 @@ interface udp { - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:io/poll.{pollable}; use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index 49ad8d3d9..432b0dc99 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.0-rc-2023-11-10; +package wasi:sockets; world imports { import instance-network; From 5a77b22e1a3b43aeae873cd585f9c5600d6d64db Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sat, 11 Nov 2023 09:44:19 +0100 Subject: [PATCH 1304/1772] Update dependencies --- proposals/sockets/wit/deps.lock | 4 +-- proposals/sockets/wit/deps/io/error.wit | 34 +++++++++++++++++++++++ proposals/sockets/wit/deps/io/poll.wit | 2 +- proposals/sockets/wit/deps/io/streams.wit | 23 ++------------- proposals/sockets/wit/deps/io/world.wit | 2 +- proposals/sockets/wit/ip-name-lookup.wit | 2 +- proposals/sockets/wit/tcp.wit | 4 +-- proposals/sockets/wit/udp.wit | 2 +- proposals/sockets/wit/world.wit | 2 +- 9 files changed, 45 insertions(+), 30 deletions(-) create mode 100644 proposals/sockets/wit/deps/io/error.wit diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index 472b87f14..48ee47f75 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "fb76f4449eea54d06b56fc6a7ca988da51bd84a54d2021cf18da67b5e2c7ebcf" -sha512 = "c005e2a91522958a9537827a49ae344e1cb39d66e85492901a86bcc7e322ba8d0a7f1a02c9b9f840c123b4ad97e297355fac98d4822536d1426d1096dd1d73ac" +sha256 = "f2e6127b235c37c06be675a904d6acf08db953ea688d78c42892c6ad3bd194e4" +sha512 = "32feefbc115c34bf6968cb6e9dc15e755698ee90648e5a5d84448917c36a318bd61b401195eb64330e2475e1d098bfb8dee1440d594a68e0797748762bd84ae5" diff --git a/proposals/sockets/wit/deps/io/error.wit b/proposals/sockets/wit/deps/io/error.wit new file mode 100644 index 000000000..31918acbb --- /dev/null +++ b/proposals/sockets/wit/deps/io/error.wit @@ -0,0 +1,34 @@ +package wasi:io@0.2.0-rc-2023-11-10; + + +interface error { + /// A resource which represents some error information. + /// + /// The only method provided by this resource is `to-debug-string`, + /// which provides some human-readable information about the error. + /// + /// In the `wasi:io` package, this resource is returned through the + /// `wasi:io/streams/stream-error` type. + /// + /// To provide more specific error information, other interfaces may + /// provide functions to further "downcast" this error into more specific + /// error information. For example, `error`s returned in streams derived + /// from filesystem types to be described using the filesystem's own + /// error-code type, using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter + /// `borrow` and returns + /// `option`. + /// + /// The set of functions which can "downcast" an `error` into a more + /// concrete type is open. + resource error { + /// Returns a string that is suitable to assist humans in debugging + /// this error. + /// + /// WARNING: The returned string should not be consumed mechanically! + /// It may change across platforms, hosts, or other implementation + /// details. Parsing this string is a major platform-compatibility + /// hazard. + to-debug-string: func() -> string; + } +} diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit index 0829a7d08..bddde3c19 100644 --- a/proposals/sockets/wit/deps/io/poll.wit +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index 8999b28d2..e7e1b689a 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -6,6 +6,7 @@ package wasi:io; /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { + use error.{error}; use poll.{pollable}; /// An error for input-stream and output-stream operations. @@ -20,26 +21,6 @@ interface streams { closed } - /// Contextual error information about the last failure that happened on - /// a read, write, or flush from an `input-stream` or `output-stream`. - /// - /// This type is returned through the `stream-error` type whenever an - /// operation on a stream directly fails or an error is discovered - /// after-the-fact, for example when a write's failure shows up through a - /// later `flush` or `check-write`. - /// - /// Interfaces such as `wasi:filesystem/types` provide functionality to - /// further "downcast" this error into interface-specific error information. - resource error { - /// Returns a string that's suitable to assist humans in debugging this - /// error. - /// - /// The returned string will change across platforms and hosts which - /// means that parsing it, for example, would be a - /// platform-compatibility hazard. - to-debug-string: func() -> string; - } - /// An input bytestream. /// /// `input-stream`s are *non-blocking* to the extent practical on underlying diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit index 05244a965..8243da2ee 100644 --- a/proposals/sockets/wit/deps/io/world.wit +++ b/proposals/sockets/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; world imports { import streams; diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index cd8d5c4c7..931ccf7e0 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,6 +1,6 @@ interface ip-name-lookup { - use wasi:io/poll.{pollable}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; use network.{network, error-code, ip-address}; diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 836b0a8fe..ac1274660 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,7 +1,7 @@ interface tcp { - use wasi:io/streams.{input-stream, output-stream}; - use wasi:io/poll.{pollable}; + use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; use network.{network, error-code, ip-socket-address, ip-address-family}; enum shutdown-type { diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index aa3783ab5..88176863b 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,6 +1,6 @@ interface udp { - use wasi:io/poll.{pollable}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; use network.{network, error-code, ip-socket-address, ip-address-family}; /// A received datagram. diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index 432b0dc99..49ad8d3d9 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets; +package wasi:sockets@0.2.0-rc-2023-11-10; world imports { import instance-network; From 532ed6b41f494edd5915bb1e5cf4fd74ae41baf9 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sat, 11 Nov 2023 09:46:39 +0100 Subject: [PATCH 1305/1772] Add & refine socket options. (SO_ACCEPTCONN, TCP_KEEPIDLE/INTVL/CNT) - Add support for the socket options: - `is-listening` (`SO_ACCEPTCONN`) - `keep-alive-count` (`TCP_KEEPCNT`) - `keep-alive-idle-time` (`TCP_KEEPIDLE`) - `keep-alive-interval` (`TCP_KEEPINTVL`) - Tweak existing socket options: - Rename `keep-alive` to `keep-alive-enabled`, since it is no longer the only "keep-alive"-related option. - Rename `(set-)unicast-hop-limit` to `(set-)hop-limit`, because the "unicast" qualifier is redundant for TCP. - Be stricter in that `0` is not a valid value for: - `set-listen-backlog-size` - `set-hop-limit` - `set-receive-buffer-size` - `set-send-buffer-size` --- proposals/sockets/imports.md | 315 ++++++++++++++---- proposals/sockets/wit/deps.lock | 5 + proposals/sockets/wit/deps.toml | 1 + .../wit/deps/clocks/monotonic-clock.wit | 45 +++ .../sockets/wit/deps/clocks/wall-clock.wit | 42 +++ proposals/sockets/wit/deps/clocks/world.wit | 6 + proposals/sockets/wit/tcp.wit | 84 ++++- proposals/sockets/wit/udp.wit | 17 +- 8 files changed, 435 insertions(+), 80 deletions(-) create mode 100644 proposals/sockets/wit/deps/clocks/monotonic-clock.wit create mode 100644 proposals/sockets/wit/deps/clocks/wall-clock.wit create mode 100644 proposals/sockets/wit/deps/clocks/world.wit diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index c59a6a285..497f48d03 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -2,19 +2,21 @@ -

      Import interface wasi:sockets/network

      +

      Import interface wasi:sockets/network@0.2.0-rc-2023-11-10


      Types

      resource network

      @@ -184,7 +186,7 @@ combined with a couple of errors that are always possible:

    • ipv4: ipv4-socket-address
    • ipv6: ipv6-socket-address
    -

    Import interface wasi:sockets/instance-network

    +

    Import interface wasi:sockets/instance-network@0.2.0-rc-2023-11-10

    This interface provides a value-export of the default network handle..


    Types

    @@ -199,7 +201,7 @@ combined with a couple of errors that are always possible:

    -

    Import interface wasi:io/poll

    +

    Import interface wasi:io/poll@0.2.0-rc-2023-11-10

    A poll API intended to let users wait for I/O events on multiple handles at once.


    @@ -249,7 +251,7 @@ being reaedy for I/O.

    • list<u32>
    -

    Import interface wasi:sockets/udp

    +

    Import interface wasi:sockets/udp@0.2.0-rc-2023-11-10


    Types

    type pollable

    @@ -489,6 +491,11 @@ stored in the object pointed to by address is unspecified.

    [method]udp-socket.unicast-hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    +

    If the provided value is 0, an invalid-argument error is returned.

    +

    Typical errors

    +
      +
    • invalid-argument: (set) The TTL value must be 1 or higher.
    • +
    Params
    • self: borrow<udp-socket>
    • @@ -509,12 +516,14 @@ stored in the object pointed to by address is unspecified.

    [method]udp-socket.receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    -

    Note #1: an implementation may choose to cap or round the buffer size when setting the value. -In other words, after setting a value, reading the same setting back may return a different value.

    -

    Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of -actual data to be sent/received by the application, because the kernel might also use the buffer space -for internal metadata structures.

    +

    If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

    Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

    +

    Typical errors

    +
      +
    • invalid-argument: (set) The provided value was 0.
    • +
    Params
    • self: borrow<udp-socket>
    • @@ -683,7 +692,7 @@ It's planned to be removed when future is natively supported in Pre -

      Import interface wasi:sockets/udp-create-socket

      +

      Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2023-11-10


      Types

      type network

      @@ -727,18 +736,41 @@ the socket is effectively an in-memory configuration object, unable to communica -

      Import interface wasi:io/streams

      +

      Import interface wasi:io/error@0.2.0-rc-2023-11-10

      +
      +

      Types

      +

      resource error

      +
      +

      Functions

      +

      [method]error.to-debug-string: func

      +

      Returns a string that is suitable to assist humans in debugging +this error.

      +

      WARNING: The returned string should not be consumed mechanically! +It may change across platforms, hosts, or other implementation +details. Parsing this string is a major platform-compatibility +hazard.

      +
      Params
      + +
      Return values
      +
        +
      • string
      • +
      +

      Import interface wasi:io/streams@0.2.0-rc-2023-11-10

      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

      In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


      Types

      -

      type pollable

      -

      pollable

      +

      type error

      +

      error

      -#### `resource error` -

      variant stream-error

      +#### `type pollable` +[`pollable`](#pollable) +

      +#### `variant stream-error`

      An error for input-stream and output-stream operations.

      Variant Cases
        @@ -758,20 +790,6 @@ future operations.

        resource output-stream


        Functions

        -

        [method]error.to-debug-string: func

        -

        Returns a string that's suitable to assist humans in debugging this -error.

        -

        The returned string will change across platforms and hosts which -means that parsing it, for example, would be a -platform-compatibility hazard.

        -
        Params
        - -
        Return values
        -
          -
        • string
        • -

        [method]input-stream.read: func

        Perform a non-blocking read from the stream.

        This function returns a list of bytes containing the read data, @@ -1042,7 +1060,68 @@ is ready for reading, before performing the splice.

        -

        Import interface wasi:sockets/tcp

        +

        Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

        +

        WASI Monotonic Clock is a clock API intended to let users measure elapsed +time.

        +

        It is intended to be portable at least between Unix-family platforms and +Windows.

        +

        A monotonic clock is a clock which has an unspecified initial value, and +successive reads of the clock will produce non-decreasing values.

        +

        It is intended for measuring elapsed time.

        +
        +

        Types

        +

        type pollable

        +

        pollable

        +

        +#### `type instant` +`u64` +

        An instant in time, in nanoseconds. An instant is relative to an +unspecified initial value, and can only be compared to instances from +the same monotonic-clock. +

        type duration

        +

        u64

        +

        A duration of time, in nanoseconds. +


        +

        Functions

        +

        now: func

        +

        Read the current value of the clock.

        +

        The clock is monotonic, therefore calling this function repeatedly will +produce a sequence of non-decreasing values.

        +
        Return values
        + +

        resolution: func

        +

        Query the resolution of the clock. Returns the duration of time +corresponding to a clock tick.

        +
        Return values
        + +

        subscribe-instant: func

        +

        Create a pollable which will resolve once the specified instant +occured.

        +
        Params
        + +
        Return values
        + +

        subscribe-duration: func

        +

        Create a pollable which will resolve once the given duration has +elapsed, starting at the time at which this function was called. +occured.

        +
        Params
        + +
        Return values
        + +

        Import interface wasi:sockets/tcp@0.2.0-rc-2023-11-10


        Types

        type input-stream

        @@ -1054,6 +1133,9 @@ is ready for reading, before performing the splice.

        #### `type pollable` [`pollable`](#pollable)

        +#### `type duration` +[`duration`](#duration) +

        #### `type network` [`network`](#network)

        @@ -1251,8 +1333,11 @@ Besides drop, any method after such a failure may return an error.<

        • address-family
        • ipv6-only
        • -
        • keep-alive
        • -
        • unicast-hop-limit
        • +
        • keep-alive-enabled
        • +
        • keep-alive-idle-time
        • +
        • keep-alive-interval
        • +
        • keep-alive-count
        • +
        • hop-limit
        • receive-buffer-size
        • send-buffer-size
        @@ -1328,6 +1413,17 @@ stored in the object pointed to by address is unspecified.

        +

        [method]tcp-socket.is-listening: func

        +

        Whether the socket is listening for new connections.

        +

        Equivalent to the SO_ACCEPTCONN socket option.

        +
        Params
        + +
        Return values
        +
          +
        • bool
        • +

        [method]tcp-socket.address-family: func

        Whether this is a IPv4 or IPv6 socket.

        Equivalent to the SO_DOMAIN socket option.

        @@ -1368,9 +1464,12 @@ stored in the object pointed to by address is unspecified.

      [method]tcp-socket.set-listen-backlog-size: func

      Hints the desired listen queue size. Implementations are free to ignore this.

      +

      If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded.

      Typical errors

      • not-supported: (set) The platform does not support changing the backlog size after the initial listen.
      • +
      • invalid-argument: (set) The provided value was 0.
      • invalid-state: (set) The socket is already in the Connection state.
      Params
      @@ -1382,28 +1481,121 @@ stored in the object pointed to by address is unspecified.

      -

      [method]tcp-socket.keep-alive: func

      +

      [method]tcp-socket.keep-alive-enabled: func

      +

      Enables or disables keepalive.

      +

      The keepalive behavior can be adjusted using:

      +
        +
      • keep-alive-idle-time
      • +
      • keep-alive-interval
      • +
      • keep-alive-count +These properties can be configured while keep-alive-enabled is false, but only come into effect when keep-alive-enabled is true.
      • +

      Equivalent to the SO_KEEPALIVE socket option.

      Params
      +
      Return values
      + +

      [method]tcp-socket.set-keep-alive-enabled: func

      +
      Params
      + +
      Return values
      + +

      [method]tcp-socket.keep-alive-idle-time: func

      +

      Amount of time the connection has to be idle before TCP starts sending keepalive packets.

      +

      If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

      +

      Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS)

      +

      Typical errors

      +
        +
      • invalid-argument: (set) The provided value was 0.
      • +
      +
      Params
      + +
      Return values
      + +

      [method]tcp-socket.set-keep-alive-idle-time: func

      +
      Params
      + +
      Return values
      + +

      [method]tcp-socket.keep-alive-interval: func

      +

      The time between keepalive packets.

      +

      If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

      +

      Equivalent to the TCP_KEEPINTVL socket option.

      +

      Typical errors

      +
        +
      • invalid-argument: (set) The provided value was 0.
      • +
      +
      Params
      + +
      Return values
      + +

      [method]tcp-socket.set-keep-alive-interval: func

      +
      Params
      + +
      Return values
      + +

      [method]tcp-socket.keep-alive-count: func

      +

      The maximum amount of keepalive packets TCP should send before aborting the connection.

      +

      If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

      +

      Equivalent to the TCP_KEEPCNT socket option.

      +

      Typical errors

      +
        +
      • invalid-argument: (set) The provided value was 0.
      • +
      +
      Params
      +
      Return values
      -

      [method]tcp-socket.set-keep-alive: func

      +

      [method]tcp-socket.set-keep-alive-count: func

      Params
      Return values
      -

      [method]tcp-socket.unicast-hop-limit: func

      +

      [method]tcp-socket.hop-limit: func

      Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

      +

      If the provided value is 0, an invalid-argument error is returned.

      Typical errors

      • invalid-argument: (set) The TTL value must be 1 or higher.
      • @@ -1412,32 +1604,31 @@ stored in the object pointed to by address is unspecified.

      Params
      Return values
      -

      [method]tcp-socket.set-unicast-hop-limit: func

      +

      [method]tcp-socket.set-hop-limit: func

      Params
      Return values

      [method]tcp-socket.receive-buffer-size: func

      The kernel buffer space reserved for sends/receives on this socket.

      -

      Note #1: an implementation may choose to cap or round the buffer size when setting the value. -In other words, after setting a value, reading the same setting back may return a different value.

      -

      Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of -actual data to be sent/received by the application, because the kernel might also use the buffer space -for internal metadata structures.

      +

      If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

      Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

      Typical errors

        +
      • invalid-argument: (set) The provided value was 0.
      • invalid-state: (set) The socket is already in the Connection state.
      • invalid-state: (set) The socket is already in the Listener state.
      @@ -1521,7 +1712,7 @@ operations on the output-stream associ -

      Import interface wasi:sockets/tcp-create-socket

      +

      Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2023-11-10


      Types

      type network

      @@ -1565,7 +1756,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

      Import interface wasi:sockets/ip-name-lookup

      +

      Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2023-11-10


      Types

      type pollable

      diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index 48ee47f75..be53c765e 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,3 +1,8 @@ +[clocks] +url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" +sha256 = "89da8eca4cd195516574c89c5b3c24a7b5af3ff2565c16753d20d3bdbc5fc60f" +sha512 = "244079b3f592d58478a97adbd0bee8d49ae9dd1a3e435651ee40997b50da9fe62cfaba7e3ec7f7406d7d0288d278a43a3a0bc5150226ba40ce0f8ac6d33f7ddb" + [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" sha256 = "f2e6127b235c37c06be675a904d6acf08db953ea688d78c42892c6ad3bd194e4" diff --git a/proposals/sockets/wit/deps.toml b/proposals/sockets/wit/deps.toml index b178cb257..c07efafd6 100644 --- a/proposals/sockets/wit/deps.toml +++ b/proposals/sockets/wit/deps.toml @@ -1 +1,2 @@ +clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" diff --git a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit new file mode 100644 index 000000000..09ef32c36 --- /dev/null +++ b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit @@ -0,0 +1,45 @@ +package wasi:clocks@0.2.0-rc-2023-11-10; +/// WASI Monotonic Clock is a clock API intended to let users measure elapsed +/// time. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A monotonic clock is a clock which has an unspecified initial value, and +/// successive reads of the clock will produce non-decreasing values. +/// +/// It is intended for measuring elapsed time. +interface monotonic-clock { + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + + /// An instant in time, in nanoseconds. An instant is relative to an + /// unspecified initial value, and can only be compared to instances from + /// the same monotonic-clock. + type instant = u64; + + /// A duration of time, in nanoseconds. + type duration = u64; + + /// Read the current value of the clock. + /// + /// The clock is monotonic, therefore calling this function repeatedly will + /// produce a sequence of non-decreasing values. + now: func() -> instant; + + /// Query the resolution of the clock. Returns the duration of time + /// corresponding to a clock tick. + resolution: func() -> duration; + + /// Create a `pollable` which will resolve once the specified instant + /// occured. + subscribe-instant: func( + when: instant, + ) -> pollable; + + /// Create a `pollable` which will resolve once the given duration has + /// elapsed, starting at the time at which this function was called. + /// occured. + subscribe-duration: func( + when: duration, + ) -> pollable; +} diff --git a/proposals/sockets/wit/deps/clocks/wall-clock.wit b/proposals/sockets/wit/deps/clocks/wall-clock.wit new file mode 100644 index 000000000..8abb9a0c0 --- /dev/null +++ b/proposals/sockets/wit/deps/clocks/wall-clock.wit @@ -0,0 +1,42 @@ +package wasi:clocks@0.2.0-rc-2023-11-10; +/// WASI Wall Clock is a clock API intended to let users query the current +/// time. The name "wall" makes an analogy to a "clock on the wall", which +/// is not necessarily monotonic as it may be reset. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A wall clock is a clock which measures the date and time according to +/// some external reference. +/// +/// External references may be reset, so this clock is not necessarily +/// monotonic, making it unsuitable for measuring elapsed time. +/// +/// It is intended for reporting the current date and time for humans. +interface wall-clock { + /// A time and date in seconds plus nanoseconds. + record datetime { + seconds: u64, + nanoseconds: u32, + } + + /// Read the current value of the clock. + /// + /// This clock is not monotonic, therefore calling this function repeatedly + /// will not necessarily produce a sequence of non-decreasing values. + /// + /// The returned timestamps represent the number of seconds since + /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], + /// also known as [Unix Time]. + /// + /// The nanoseconds field of the output is always less than 1000000000. + /// + /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + now: func() -> datetime; + + /// Query the resolution of the clock. + /// + /// The nanoseconds field of the output is always less than 1000000000. + resolution: func() -> datetime; +} diff --git a/proposals/sockets/wit/deps/clocks/world.wit b/proposals/sockets/wit/deps/clocks/world.wit new file mode 100644 index 000000000..8fa080f0e --- /dev/null +++ b/proposals/sockets/wit/deps/clocks/world.wit @@ -0,0 +1,6 @@ +package wasi:clocks@0.2.0-rc-2023-11-10; + +world imports { + import monotonic-clock; + import wall-clock; +} diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index ac1274660..b01b65e6c 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -2,6 +2,7 @@ interface tcp { use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream}; use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10.{duration}; use network.{network, error-code, ip-socket-address, ip-address-family}; enum shutdown-type { @@ -125,8 +126,11 @@ interface tcp { /// The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket: /// - `address-family` /// - `ipv6-only` - /// - `keep-alive` - /// - `unicast-hop-limit` + /// - `keep-alive-enabled` + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// - `hop-limit` /// - `receive-buffer-size` /// - `send-buffer-size` /// @@ -176,6 +180,11 @@ interface tcp { /// - remote-address: func() -> result; + /// Whether the socket is listening for new connections. + /// + /// Equivalent to the SO_ACCEPTCONN socket option. + is-listening: func() -> bool; + /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. @@ -194,36 +203,87 @@ interface tcp { /// Hints the desired listen queue size. Implementations are free to ignore this. /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// /// # Typical errors /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. + /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is already in the Connection state. set-listen-backlog-size: func(value: u64) -> result<_, error-code>; + /// Enables or disables keepalive. + /// + /// The keepalive behavior can be adjusted using: + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. + /// /// Equivalent to the SO_KEEPALIVE socket option. - keep-alive: func() -> result; - set-keep-alive: func(value: bool) -> result<_, error-code>; + keep-alive-enabled: func() -> result; + set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; + + /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS) + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + keep-alive-idle-time: func() -> result; + set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; + + /// The time between keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPINTVL socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + keep-alive-interval: func() -> result; + set-keep-alive-interval: func(value: duration) -> result<_, error-code>; + + /// The maximum amount of keepalive packets TCP should send before aborting the connection. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPCNT socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + keep-alive-count: func() -> result; + set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. /// - `invalid-state`: (set) The socket is already in the Connection state. /// - `invalid-state`: (set) The socket is already in the Listener state. - unicast-hop-limit: func() -> result; - set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; + hop-limit: func() -> result; + set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. /// /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. /// /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is already in the Connection state. /// - `invalid-state`: (set) The socket is already in the Listener state. receive-buffer-size: func() -> result; diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 88176863b..c8dafadfc 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -154,19 +154,24 @@ interface udp { set-ipv6-only: func(value: bool) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. unicast-hop-limit: func() -> result; set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. /// /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. receive-buffer-size: func() -> result; set-receive-buffer-size: func(value: u64) -> result<_, error-code>; send-buffer-size: func() -> result; From da7d4f37040afda91098fa684f62c85f7f16338d Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 16:11:18 -0800 Subject: [PATCH 1306/1772] wit-deps update clocks, filesystem, io, random, and sockets, all at 0.2.0-rc-2023-11-10 --- proposals/cli/wit/deps.lock | 20 +- .../cli/wit/deps/clocks/monotonic-clock.wit | 3 +- proposals/cli/wit/deps/clocks/timezone.wit | 48 -- proposals/cli/wit/deps/clocks/wall-clock.wit | 1 + proposals/cli/wit/deps/clocks/world.wit | 3 +- .../cli/wit/deps/filesystem/preopens.wit | 2 + proposals/cli/wit/deps/filesystem/types.wit | 83 +-- proposals/cli/wit/deps/filesystem/world.wit | 2 +- proposals/cli/wit/deps/io/error.wit | 34 ++ proposals/cli/wit/deps/io/poll.wit | 2 +- proposals/cli/wit/deps/io/streams.wit | 23 +- proposals/cli/wit/deps/io/world.wit | 2 +- .../cli/wit/deps/random/insecure-seed.wit | 1 + proposals/cli/wit/deps/random/insecure.wit | 1 + proposals/cli/wit/deps/random/random.wit | 1 + proposals/cli/wit/deps/random/world.wit | 2 +- .../cli/wit/deps/sockets/instance-network.wit | 6 +- .../cli/wit/deps/sockets/ip-name-lookup.wit | 98 ++- proposals/cli/wit/deps/sockets/network.wit | 243 ++++---- .../wit/deps/sockets/tcp-create-socket.wit | 45 +- proposals/cli/wit/deps/sockets/tcp.wit | 564 ++++++++++-------- .../wit/deps/sockets/udp-create-socket.wit | 45 +- proposals/cli/wit/deps/sockets/udp.wit | 485 ++++++++------- proposals/cli/wit/deps/sockets/world.wit | 2 +- 24 files changed, 852 insertions(+), 864 deletions(-) delete mode 100644 proposals/cli/wit/deps/clocks/timezone.wit create mode 100644 proposals/cli/wit/deps/io/error.wit diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index 9996e3d03..cbaafcb73 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,24 +1,24 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "8d6b9f7a8bf9466bdc68043c33e054878fdf09c1cc69c19c99eeadd3bb257a90" -sha512 = "21b65d911930c4512bb3caa08459283fc70b1ccc5159313092334cffd6662fb92cfe90577b51829ef363e2d02530802c88f2a1f82db43964d1f8bff7ecbc794b" +sha256 = "89da8eca4cd195516574c89c5b3c24a7b5af3ff2565c16753d20d3bdbc5fc60f" +sha512 = "244079b3f592d58478a97adbd0bee8d49ae9dd1a3e435651ee40997b50da9fe62cfaba7e3ec7f7406d7d0288d278a43a3a0bc5150226ba40ce0f8ac6d33f7ddb" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "c05155f44cf5798d15a16eaf9cdfb065d05914ed4710421a7448bb61c6decf3a" -sha512 = "fb30ea13678d3f3d2002b2cc1f6dae99ee6a06eae7c408c0d558f21e5039979dd80c8ced46b1a7629ce8b050820d81462093f7b4a733ff706d0258bf5dea5657" +sha256 = "05952bbc98895aa3aeda6c765a3e521016de59f993f3b60394c724640935c09c" +sha512 = "2c242489801a75466986fe014d730fb3aa7b5c6e56a230c8735e6672711b58bcbe92ba78a341b78fc3ac69339e55d3859d8bb14410230f0371ee30dbd83add64" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "fb76f4449eea54d06b56fc6a7ca988da51bd84a54d2021cf18da67b5e2c7ebcf" -sha512 = "c005e2a91522958a9537827a49ae344e1cb39d66e85492901a86bcc7e322ba8d0a7f1a02c9b9f840c123b4ad97e297355fac98d4822536d1426d1096dd1d73ac" +sha256 = "f2e6127b235c37c06be675a904d6acf08db953ea688d78c42892c6ad3bd194e4" +sha512 = "32feefbc115c34bf6968cb6e9dc15e755698ee90648e5a5d84448917c36a318bd61b401195eb64330e2475e1d098bfb8dee1440d594a68e0797748762bd84ae5" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "7d7c882d50baeb054a754b5766d46f5eed35a4470d887fc8b45121bfc7ac8701" -sha512 = "4b8aad54da50aa44d35f6e5eea87c67bbcedd610650500ffe350c8c8d26f7ee14c49c4c4cc51ebd0ae607459095092625f27a451e52232c575b460334b5a0606" +sha256 = "11afcbff9920f5f1f72b6764d01e59a5faa2c671f0c59f0c9b405778f3708745" +sha512 = "cc4fa3d178559a89d9d6a376e3359b892158d1e73317c5db1f797ebc6b0b57abf2422797648d5b2b494c50cf9360720bc451cc27e15def7d278ba875805ccbf5" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "e9cc9bf3e809c17f7a100f9498056e435eea133bcb0f1abd8833261f3e5ff067" -sha512 = "1917e06807dc5f9f0993fbffbb9a6c8c36ab25a14ba775ffee939aca458ecd52ee796764708381f7f4166665cfcf11a5d47dc756a1e38f291b270678455b3a02" +sha256 = "b5c2e9cc87cefbaef06bbe9978f9bc336da9feee2d51747bc28e10164fc46c39" +sha512 = "3aea6fe0c768b27d5c5cb3adab5e60dc936198f8b677c2cf6c4d57a0460db87eb779e0b577f1240fb2a6bf3ade49919fbffe39b0137bce3242343e6091cc7510" diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index afacdbb61..09ef32c36 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -1,3 +1,4 @@ +package wasi:clocks@0.2.0-rc-2023-11-10; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -9,7 +10,7 @@ /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:io/poll.{pollable}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/cli/wit/deps/clocks/timezone.wit b/proposals/cli/wit/deps/clocks/timezone.wit deleted file mode 100644 index e717e7b8d..000000000 --- a/proposals/cli/wit/deps/clocks/timezone.wit +++ /dev/null @@ -1,48 +0,0 @@ -interface timezone { - use wall-clock.{datetime}; - - /// Return information needed to display the given `datetime`. This includes - /// the UTC offset, the time zone name, and a flag indicating whether - /// daylight saving time is active. - /// - /// If the timezone cannot be determined for the given `datetime`, return a - /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight - /// saving time. - display: func(when: datetime) -> timezone-display; - - /// The same as `display`, but only return the UTC offset. - utc-offset: func(when: datetime) -> s32; - - /// Information useful for displaying the timezone of a specific `datetime`. - /// - /// This information may vary within a single `timezone` to reflect daylight - /// saving time adjustments. - record timezone-display { - /// The number of seconds difference between UTC time and the local - /// time of the timezone. - /// - /// The returned value will always be less than 86400 which is the - /// number of seconds in a day (24*60*60). - /// - /// In implementations that do not expose an actual time zone, this - /// should return 0. - utc-offset: s32, - - /// The abbreviated name of the timezone to display to a user. The name - /// `UTC` indicates Coordinated Universal Time. Otherwise, this should - /// reference local standards for the name of the time zone. - /// - /// In implementations that do not expose an actual time zone, this - /// should be the string `UTC`. - /// - /// In time zones that do not have an applicable name, a formatted - /// representation of the UTC offset may be returned, such as `-04:00`. - name: string, - - /// Whether daylight saving time is active. - /// - /// In implementations that do not expose an actual time zone, this - /// should return false. - in-daylight-saving-time: bool, - } -} diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit index c39564967..8abb9a0c0 100644 --- a/proposals/cli/wit/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -1,3 +1,4 @@ +package wasi:clocks@0.2.0-rc-2023-11-10; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/cli/wit/deps/clocks/world.wit b/proposals/cli/wit/deps/clocks/world.wit index 3295ba8d9..8fa080f0e 100644 --- a/proposals/cli/wit/deps/clocks/world.wit +++ b/proposals/cli/wit/deps/clocks/world.wit @@ -1,7 +1,6 @@ -package wasi:clocks; +package wasi:clocks@0.2.0-rc-2023-11-10; world imports { import monotonic-clock; import wall-clock; - import timezone; } diff --git a/proposals/cli/wit/deps/filesystem/preopens.wit b/proposals/cli/wit/deps/filesystem/preopens.wit index 3f787ac3f..95ec67843 100644 --- a/proposals/cli/wit/deps/filesystem/preopens.wit +++ b/proposals/cli/wit/deps/filesystem/preopens.wit @@ -1,3 +1,5 @@ +package wasi:filesystem@0.2.0-rc-2023-11-10; + interface preopens { use types.{descriptor}; diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index 7ac147f66..059722ab8 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -1,3 +1,4 @@ +package wasi:filesystem@0.2.0-rc-2023-11-10; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -23,8 +24,8 @@ /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { - use wasi:io/streams.{input-stream, output-stream, error}; - use wasi:clocks/wall-clock.{datetime}; + use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream, error}; + use wasi:clocks/wall-clock@0.2.0-rc-2023-11-10.{datetime}; /// File size or length of a region within a file. type filesize = u64; @@ -142,29 +143,6 @@ interface types { truncate, } - /// Permissions mode used by `open-at`, `change-file-permissions-at`, and - /// similar. - flags modes { - /// True if the resource is considered readable by the containing - /// filesystem. - readable, - /// True if the resource is considered writable by the containing - /// filesystem. - writable, - /// True if the resource is considered executable by the containing - /// filesystem. This does not apply to directories. - executable, - } - - /// Access type used by `access-at`. - variant access-type { - /// Test for readability, writeability, or executability. - access(modes), - - /// Test whether the path exists. - exists, - } - /// Number of hard links to an inode. type link-count = u64; @@ -538,8 +516,6 @@ interface types { open-flags: open-flags, /// Flags to use for the resulting descriptor. %flags: descriptor-flags, - /// Permissions to use when creating a new file. - modes: modes ) -> result; /// Read the contents of a symbolic link. @@ -588,25 +564,6 @@ interface types { new-path: string, ) -> result<_, error-code>; - /// Check accessibility of a filesystem path. - /// - /// Check whether the given filesystem path names an object which is - /// readable, writable, or executable, or whether it exists. - /// - /// This does not a guarantee that subsequent accesses will succeed, as - /// filesystem permissions may be modified asynchronously by external - /// entities. - /// - /// Note: This is similar to `faccessat` with the `AT_EACCESS` flag in POSIX. - access-at: func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to check. - path: string, - /// The type of check to perform. - %type: access-type - ) -> result<_, error-code>; - /// Unlink a filesystem object that is not a directory. /// /// Return `error-code::is-directory` if the path refers to a directory. @@ -616,40 +573,6 @@ interface types { path: string, ) -> result<_, error-code>; - /// Change the permissions of a filesystem object that is not a directory. - /// - /// Note that the ultimate meanings of these permissions is - /// filesystem-specific. - /// - /// Note: This is similar to `fchmodat` in POSIX. - change-file-permissions-at: func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the filesystem object. - modes: modes, - ) -> result<_, error-code>; - - /// Change the permissions of a directory. - /// - /// Note that the ultimate meanings of these permissions is - /// filesystem-specific. - /// - /// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" - /// flag. `read` on a directory implies readability and searchability, and - /// `execute` is not valid for directories. - /// - /// Note: This is similar to `fchmodat` in POSIX. - change-directory-permissions-at: func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the directory. - modes: modes, - ) -> result<_, error-code>; - /// Test whether two descriptors refer to the same filesystem object. /// /// In POSIX, this corresponds to testing whether the two descriptors have the diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit index bd472942d..285e0bae9 100644 --- a/proposals/cli/wit/deps/filesystem/world.wit +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem; +package wasi:filesystem@0.2.0-rc-2023-11-10; world imports { import types; diff --git a/proposals/cli/wit/deps/io/error.wit b/proposals/cli/wit/deps/io/error.wit new file mode 100644 index 000000000..31918acbb --- /dev/null +++ b/proposals/cli/wit/deps/io/error.wit @@ -0,0 +1,34 @@ +package wasi:io@0.2.0-rc-2023-11-10; + + +interface error { + /// A resource which represents some error information. + /// + /// The only method provided by this resource is `to-debug-string`, + /// which provides some human-readable information about the error. + /// + /// In the `wasi:io` package, this resource is returned through the + /// `wasi:io/streams/stream-error` type. + /// + /// To provide more specific error information, other interfaces may + /// provide functions to further "downcast" this error into more specific + /// error information. For example, `error`s returned in streams derived + /// from filesystem types to be described using the filesystem's own + /// error-code type, using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter + /// `borrow` and returns + /// `option`. + /// + /// The set of functions which can "downcast" an `error` into a more + /// concrete type is open. + resource error { + /// Returns a string that is suitable to assist humans in debugging + /// this error. + /// + /// WARNING: The returned string should not be consumed mechanically! + /// It may change across platforms, hosts, or other implementation + /// details. Parsing this string is a major platform-compatibility + /// hazard. + to-debug-string: func() -> string; + } +} diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit index 0829a7d08..bddde3c19 100644 --- a/proposals/cli/wit/deps/io/poll.wit +++ b/proposals/cli/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index 8999b28d2..e7e1b689a 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -6,6 +6,7 @@ package wasi:io; /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { + use error.{error}; use poll.{pollable}; /// An error for input-stream and output-stream operations. @@ -20,26 +21,6 @@ interface streams { closed } - /// Contextual error information about the last failure that happened on - /// a read, write, or flush from an `input-stream` or `output-stream`. - /// - /// This type is returned through the `stream-error` type whenever an - /// operation on a stream directly fails or an error is discovered - /// after-the-fact, for example when a write's failure shows up through a - /// later `flush` or `check-write`. - /// - /// Interfaces such as `wasi:filesystem/types` provide functionality to - /// further "downcast" this error into interface-specific error information. - resource error { - /// Returns a string that's suitable to assist humans in debugging this - /// error. - /// - /// The returned string will change across platforms and hosts which - /// means that parsing it, for example, would be a - /// platform-compatibility hazard. - to-debug-string: func() -> string; - } - /// An input bytestream. /// /// `input-stream`s are *non-blocking* to the extent practical on underlying diff --git a/proposals/cli/wit/deps/io/world.wit b/proposals/cli/wit/deps/io/world.wit index 05244a965..8243da2ee 100644 --- a/proposals/cli/wit/deps/io/world.wit +++ b/proposals/cli/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; world imports { import streams; diff --git a/proposals/cli/wit/deps/random/insecure-seed.wit b/proposals/cli/wit/deps/random/insecure-seed.wit index 139aed159..f76e87dad 100644 --- a/proposals/cli/wit/deps/random/insecure-seed.wit +++ b/proposals/cli/wit/deps/random/insecure-seed.wit @@ -1,3 +1,4 @@ +package wasi:random@0.2.0-rc-2023-11-10; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/insecure.wit b/proposals/cli/wit/deps/random/insecure.wit index 2ffd223cb..ec7b99737 100644 --- a/proposals/cli/wit/deps/random/insecure.wit +++ b/proposals/cli/wit/deps/random/insecure.wit @@ -1,3 +1,4 @@ +package wasi:random@0.2.0-rc-2023-11-10; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index 2c3c6a859..7a7dfa27a 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -1,3 +1,4 @@ +package wasi:random@0.2.0-rc-2023-11-10; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/world.wit b/proposals/cli/wit/deps/random/world.wit index bb1dd7b59..49e5743b4 100644 --- a/proposals/cli/wit/deps/random/world.wit +++ b/proposals/cli/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random; +package wasi:random@0.2.0-rc-2023-11-10; world imports { import random; diff --git a/proposals/cli/wit/deps/sockets/instance-network.wit b/proposals/cli/wit/deps/sockets/instance-network.wit index 14e4479e6..e455d0ff7 100644 --- a/proposals/cli/wit/deps/sockets/instance-network.wit +++ b/proposals/cli/wit/deps/sockets/instance-network.wit @@ -1,9 +1,9 @@ /// This interface provides a value-export of the default network handle.. interface instance-network { - use network.{network}; + use network.{network}; - /// Get a handle to the default network. - instance-network: func() -> network; + /// Get a handle to the default network. + instance-network: func() -> network; } diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index b51fe05e5..931ccf7e0 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,61 +1,51 @@ interface ip-name-lookup { - use wasi:io/poll.{pollable}; - use network.{network, error-code, ip-address, ip-address-family}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use network.{network, error-code, ip-address}; - /// Resolve an internet host name to a list of IP addresses. - /// - /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. - /// - /// # Parameters - /// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted - /// to ASCII using IDNA encoding. - /// - `address-family`: If provided, limit the results to addresses of this specific address family. - /// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime - /// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on - /// systems without an active IPv6 interface. Notes: - /// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. - /// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. - /// - /// This function never blocks. It either immediately fails or immediately returns successfully with a `resolve-address-stream` - /// that can be used to (asynchronously) fetch the results. - /// - /// At the moment, the stream never completes successfully with 0 items. Ie. the first call - /// to `resolve-next-address` never returns `ok(none)`. This may change in the future. - /// - /// # Typical errors - /// - `invalid-name`: `name` is a syntactically invalid domain name. - /// - `invalid-name`: `name` is an IP address. - /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAI_FAMILY) - /// - /// # References: - /// - - /// - - /// - - /// - - resolve-addresses: func(network: borrow, name: string, address-family: option, include-unavailable: bool) -> result; + /// Resolve an internet host name to a list of IP addresses. + /// + /// Unicode domain names are automatically converted to ASCII using IDNA encoding. + /// If the input is an IP address string, the address is parsed and returned + /// as-is without making any external requests. + /// + /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. + /// + /// This function never blocks. It either immediately fails or immediately + /// returns successfully with a `resolve-address-stream` that can be used + /// to (asynchronously) fetch the results. + /// + /// # Typical errors + /// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address. + /// + /// # References: + /// - + /// - + /// - + /// - + resolve-addresses: func(network: borrow, name: string) -> result; - resource resolve-address-stream { - /// Returns the next address from the resolver. - /// - /// This function should be called multiple times. On each call, it will - /// return the next address in connection order preference. If all - /// addresses have been exhausted, this function returns `none`. - /// - /// This function never returns IPv4-mapped IPv6 addresses. - /// - /// # Typical errors - /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) - /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) - /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) - /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) - resolve-next-address: func() -> result, error-code>; + resource resolve-address-stream { + /// Returns the next address from the resolver. + /// + /// This function should be called multiple times. On each call, it will + /// return the next address in connection order preference. If all + /// addresses have been exhausted, this function returns `none`. + /// + /// This function never returns IPv4-mapped IPv6 addresses. + /// + /// # Typical errors + /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) + /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) + /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) + /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) + resolve-next-address: func() -> result, error-code>; - /// Create a `pollable` which will resolve once the stream is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable; - } + /// Create a `pollable` which will resolve once the stream is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } } diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit index e2695954b..6bb07cd6f 100644 --- a/proposals/cli/wit/deps/sockets/network.wit +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -1,178 +1,147 @@ interface network { - /// An opaque resource that represents access to (a subset of) the network. - /// This enables context-based security for networking. - /// There is no need for this to map 1:1 to a physical network interface. - resource network; + /// An opaque resource that represents access to (a subset of) the network. + /// This enables context-based security for networking. + /// There is no need for this to map 1:1 to a physical network interface. + resource network; - /// Error codes. - /// - /// In theory, every API can return any error code. - /// In practice, API's typically only return the errors documented per API - /// combined with a couple of errors that are always possible: - /// - `unknown` - /// - `access-denied` - /// - `not-supported` - /// - `out-of-memory` - /// - /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - enum error-code { - // ### GENERAL ERRORS ### + /// Error codes. + /// + /// In theory, every API can return any error code. + /// In practice, API's typically only return the errors documented per API + /// combined with a couple of errors that are always possible: + /// - `unknown` + /// - `access-denied` + /// - `not-supported` + /// - `out-of-memory` + /// - `concurrency-conflict` + /// + /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. + enum error-code { + // ### GENERAL ERRORS ### - /// Unknown error - unknown, + /// Unknown error + unknown, - /// Access denied. - /// - /// POSIX equivalent: EACCES, EPERM - access-denied, + /// Access denied. + /// + /// POSIX equivalent: EACCES, EPERM + access-denied, - /// The operation is not supported. - /// - /// POSIX equivalent: EOPNOTSUPP - not-supported, + /// The operation is not supported. + /// + /// POSIX equivalent: EOPNOTSUPP + not-supported, - /// Not enough memory to complete the operation. - /// - /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY - out-of-memory, + /// One of the arguments is invalid. + /// + /// POSIX equivalent: EINVAL + invalid-argument, - /// The operation timed out before it could finish completely. - timeout, + /// Not enough memory to complete the operation. + /// + /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY + out-of-memory, - /// This operation is incompatible with another asynchronous operation that is already in progress. - concurrency-conflict, + /// The operation timed out before it could finish completely. + timeout, - /// Trying to finish an asynchronous operation that: - /// - has not been started yet, or: - /// - was already finished by a previous `finish-*` call. - /// - /// Note: this is scheduled to be removed when `future`s are natively supported. - not-in-progress, + /// This operation is incompatible with another asynchronous operation that is already in progress. + /// + /// POSIX equivalent: EALREADY + concurrency-conflict, - /// The operation has been aborted because it could not be completed immediately. - /// - /// Note: this is scheduled to be removed when `future`s are natively supported. - would-block, + /// Trying to finish an asynchronous operation that: + /// - has not been started yet, or: + /// - was already finished by a previous `finish-*` call. + /// + /// Note: this is scheduled to be removed when `future`s are natively supported. + not-in-progress, + /// The operation has been aborted because it could not be completed immediately. + /// + /// Note: this is scheduled to be removed when `future`s are natively supported. + would-block, - // ### IP ERRORS ### - /// The specified address-family is not supported. - address-family-not-supported, - /// An IPv4 address was passed to an IPv6 resource, or vice versa. - address-family-mismatch, + // ### TCP & UDP SOCKET ERRORS ### - /// The socket address is not a valid remote address. E.g. the IP address is set to INADDR_ANY, or the port is set to 0. - invalid-remote-address, + /// The operation is not valid in the socket's current state. + invalid-state, - /// The operation is only supported on IPv4 resources. - ipv4-only-operation, + /// A new socket resource could not be created because of a system limit. + new-socket-limit, - /// The operation is only supported on IPv6 resources. - ipv6-only-operation, + /// A bind operation failed because the provided address is not an address that the `network` can bind to. + address-not-bindable, + /// A bind operation failed because the provided address is already in use or because there are no ephemeral ports available. + address-in-use, + /// The remote address is not reachable + remote-unreachable, - // ### TCP & UDP SOCKET ERRORS ### - /// A new socket resource could not be created because of a system limit. - new-socket-limit, - - /// The socket is already attached to another network. - already-attached, + // ### TCP SOCKET ERRORS ### - /// The socket is already bound. - already-bound, + /// The connection was forcefully rejected + connection-refused, - /// The socket is already in the Connection state. - already-connected, + /// The connection was reset. + connection-reset, - /// The socket is not bound to any local address. - not-bound, + /// A connection was aborted. + connection-aborted, - /// The socket is not in the Connection state. - not-connected, - /// A bind operation failed because the provided address is not an address that the `network` can bind to. - address-not-bindable, + // ### UDP SOCKET ERRORS ### + datagram-too-large, - /// A bind operation failed because the provided address is already in use. - address-in-use, - /// A bind operation failed because there are no ephemeral ports available. - ephemeral-ports-exhausted, + // ### NAME LOOKUP ERRORS ### - /// The remote address is not reachable - remote-unreachable, - + /// Name does not exist or has no suitable associated IP addresses. + name-unresolvable, - // ### TCP SOCKET ERRORS ### - - /// The socket is already in the Listener state. - already-listening, + /// A temporary failure in name resolution occurred. + temporary-resolver-failure, - /// The socket is already in the Listener state. - not-listening, + /// A permanent failure in name resolution occurred. + permanent-resolver-failure, + } - /// The connection was forcefully rejected - connection-refused, + enum ip-address-family { + /// Similar to `AF_INET` in POSIX. + ipv4, - /// The connection was reset. - connection-reset, - + /// Similar to `AF_INET6` in POSIX. + ipv6, + } - // ### UDP SOCKET ERRORS ### - datagram-too-large, + type ipv4-address = tuple; + type ipv6-address = tuple; + variant ip-address { + ipv4(ipv4-address), + ipv6(ipv6-address), + } - // ### NAME LOOKUP ERRORS ### - - /// The provided name is a syntactically invalid domain name. - invalid-name, + record ipv4-socket-address { + port: u16, // sin_port + address: ipv4-address, // sin_addr + } - /// Name does not exist or has no suitable associated IP addresses. - name-unresolvable, + record ipv6-socket-address { + port: u16, // sin6_port + flow-info: u32, // sin6_flowinfo + address: ipv6-address, // sin6_addr + scope-id: u32, // sin6_scope_id + } - /// A temporary failure in name resolution occurred. - temporary-resolver-failure, - - /// A permanent failure in name resolution occurred. - permanent-resolver-failure, - } - - enum ip-address-family { - /// Similar to `AF_INET` in POSIX. - ipv4, - - /// Similar to `AF_INET6` in POSIX. - ipv6, - } - - type ipv4-address = tuple; - type ipv6-address = tuple; - - variant ip-address { - ipv4(ipv4-address), - ipv6(ipv6-address), - } - - record ipv4-socket-address { - port: u16, // sin_port - address: ipv4-address, // sin_addr - } - - record ipv6-socket-address { - port: u16, // sin6_port - flow-info: u32, // sin6_flowinfo - address: ipv6-address, // sin6_addr - scope-id: u32, // sin6_scope_id - } - - variant ip-socket-address { - ipv4(ipv4-socket-address), - ipv6(ipv6-socket-address), - } + variant ip-socket-address { + ipv4(ipv4-socket-address), + ipv6(ipv6-socket-address), + } } diff --git a/proposals/cli/wit/deps/sockets/tcp-create-socket.wit b/proposals/cli/wit/deps/sockets/tcp-create-socket.wit index 056bbef33..768a07c85 100644 --- a/proposals/cli/wit/deps/sockets/tcp-create-socket.wit +++ b/proposals/cli/wit/deps/sockets/tcp-create-socket.wit @@ -1,27 +1,26 @@ interface tcp-create-socket { - use network.{network, error-code, ip-address-family}; - use tcp.{tcp-socket}; + use network.{network, error-code, ip-address-family}; + use tcp.{tcp-socket}; - /// Create a new TCP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. - /// - /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` - /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// - /// # Typical errors - /// - `not-supported`: The host does not support TCP sockets. (EOPNOTSUPP) - /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References - /// - - /// - - /// - - /// - - create-tcp-socket: func(address-family: ip-address-family) -> result; + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` + /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # Typical errors + /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References + /// - + /// - + /// - + /// - + create-tcp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index fea44380d..b01b65e6c 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -1,249 +1,321 @@ interface tcp { - use wasi:io/streams.{input-stream, output-stream}; - use wasi:io/poll.{pollable}; - use network.{network, error-code, ip-socket-address, ip-address-family}; - - enum shutdown-type { - /// Similar to `SHUT_RD` in POSIX. - receive, - - /// Similar to `SHUT_WR` in POSIX. - send, - - /// Similar to `SHUT_RDWR` in POSIX. - both, - } - - - /// A TCP socket handle. - resource tcp-socket { - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will - /// implicitly bind the socket. - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) - /// - `already-bound`: The socket is already bound. (EINVAL) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; - finish-bind: func() -> result<_, error-code>; - - /// Connect to a remote endpoint. - /// - /// On success: - /// - the socket is transitioned into the Connection state - /// - a pair of streams is returned that can be used to read & write to the connection - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) - /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `already-connected`: The socket is already in the Connection state. (EISCONN) - /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `timeout`: Connection timed out. (ETIMEDOUT) - /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) - /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; - finish-connect: func() -> result, error-code>; - - /// Start listening for new connections. - /// - /// Transitions the socket into the Listener state. - /// - /// Unlike POSIX: - /// - this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - the socket must already be explicitly bound. - /// - /// # Typical `start` errors - /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) - /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) - /// - `already-listening`: The socket is already in the Listener state. - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - `not-in-progress`: A `listen` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-listen: func() -> result<_, error-code>; - finish-listen: func() -> result<_, error-code>; - - /// Accept a new client socket. - /// - /// The returned socket is bound and in the Connection state. - /// - /// On success, this function returns the newly accepted client socket along with - /// a pair of streams that can be used to read & write to the connection. - /// - /// # Typical errors - /// - `not-listening`: Socket is not in the Listener state. (EINVAL) - /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) - /// - /// Host implementations must skip over transient errors returned by the native accept syscall. - /// - /// # References - /// - - /// - - /// - - /// - - accept: func() -> result, error-code>; - - /// Get the bound local address. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - local-address: func() -> result; - - /// Get the bound remote address. - /// - /// # Typical errors - /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - remote-address: func() -> result; - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func() -> ip-address-family; - - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. - /// - `already-bound`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - ipv6-only: func() -> result; - set-ipv6-only: func(value: bool) -> result<_, error-code>; - - /// Hints the desired listen queue size. Implementations are free to ignore this. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - set-listen-backlog-size: func(value: u64) -> result<_, error-code>; - - /// Equivalent to the SO_KEEPALIVE socket option. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - keep-alive: func() -> result; - set-keep-alive: func(value: bool) -> result<_, error-code>; - - /// Equivalent to the TCP_NODELAY socket option. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - no-delay: func() -> result; - set-no-delay: func(value: bool) -> result<_, error-code>; - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `already-listening`: (set) The socket is already in the Listener state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - unicast-hop-limit: func() -> result; - set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `already-listening`: (set) The socket is already in the Listener state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - receive-buffer-size: func() -> result; - set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - send-buffer-size: func() -> result; - set-send-buffer-size: func(value: u64) -> result<_, error-code>; - - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable; - - /// Initiate a graceful shutdown. - /// - /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read - /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. - /// Any data still in the receive queue at time of calling `shutdown` will be discarded. - /// - send: the socket is not expecting to send any more data to the peer. All subsequent write - /// operations on the `output-stream` associated with this socket will return an error. - /// - both: same effect as receive & send combined. - /// - /// The shutdown function does not close (drop) the socket. - /// - /// # Typical errors - /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; - } + use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10.{duration}; + use network.{network, error-code, ip-socket-address, ip-address-family}; + + enum shutdown-type { + /// Similar to `SHUT_RD` in POSIX. + receive, + + /// Similar to `SHUT_WR` in POSIX. + send, + + /// Similar to `SHUT_RDWR` in POSIX. + both, + } + + + /// A TCP socket handle. + resource tcp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will + /// implicitly bind the socket. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) + /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address, but the socket has `ipv6-only` enabled. (EINVAL) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// + /// # Typical `finish` errors + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + finish-bind: func() -> result<_, error-code>; + + /// Connect to a remote endpoint. + /// + /// On success: + /// - the socket is transitioned into the Connection state + /// - a pair of streams is returned that can be used to read & write to the connection + /// + /// POSIX mentions: + /// > If connect() fails, the state of the socket is unspecified. Conforming applications should + /// > close the file descriptor and create a new socket before attempting to reconnect. + /// + /// WASI prescribes the following behavior: + /// - If `connect` fails because an input/state validation error, the socket should remain usable. + /// - If a connection was actually attempted but failed, the socket should become unusable for further network communication. + /// Besides `drop`, any method after such a failure may return an error. + /// + /// # Typical `start` errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) + /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address, but the socket has `ipv6-only` enabled. (EINVAL, EADDRNOTAVAIL on Illumos) + /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `invalid-state`: The socket is already in the Connection state. (EISCONN) + /// - `invalid-state`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) + /// + /// # Typical `finish` errors + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + finish-connect: func() -> result, error-code>; + + /// Start listening for new connections. + /// + /// Transitions the socket into the Listener state. + /// + /// Unlike POSIX: + /// - this function is async. This enables interactive WASI hosts to inject permission prompts. + /// - the socket must already be explicitly bound. + /// + /// # Typical `start` errors + /// - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ) + /// - `invalid-state`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) + /// - `invalid-state`: The socket is already in the Listener state. + /// + /// # Typical `finish` errors + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// - `not-in-progress`: A `listen` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-listen: func() -> result<_, error-code>; + finish-listen: func() -> result<_, error-code>; + + /// Accept a new client socket. + /// + /// The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket: + /// - `address-family` + /// - `ipv6-only` + /// - `keep-alive-enabled` + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// - `hop-limit` + /// - `receive-buffer-size` + /// - `send-buffer-size` + /// + /// On success, this function returns the newly accepted client socket along with + /// a pair of streams that can be used to read & write to the connection. + /// + /// # Typical errors + /// - `invalid-state`: Socket is not in the Listener state. (EINVAL) + /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) + /// - `connection-aborted`: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References + /// - + /// - + /// - + /// - + accept: func() -> result, error-code>; + + /// Get the bound local address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func() -> result; + + /// Get the remote address. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func() -> result; + + /// Whether the socket is listening for new connections. + /// + /// Equivalent to the SO_ACCEPTCONN socket option. + is-listening: func() -> bool; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family; + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// # Typical errors + /// - `invalid-state`: (set) The socket is already bound. + /// - `not-supported`: (get/set) `this` socket is an IPv4 socket. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + ipv6-only: func() -> result; + set-ipv6-only: func(value: bool) -> result<_, error-code>; + + /// Hints the desired listen queue size. Implementations are free to ignore this. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// + /// # Typical errors + /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. + /// - `invalid-argument`: (set) The provided value was 0. + /// - `invalid-state`: (set) The socket is already in the Connection state. + set-listen-backlog-size: func(value: u64) -> result<_, error-code>; + + /// Enables or disables keepalive. + /// + /// The keepalive behavior can be adjusted using: + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. + /// + /// Equivalent to the SO_KEEPALIVE socket option. + keep-alive-enabled: func() -> result; + set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; + + /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS) + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + keep-alive-idle-time: func() -> result; + set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; + + /// The time between keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPINTVL socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + keep-alive-interval: func() -> result; + set-keep-alive-interval: func(value: duration) -> result<_, error-code>; + + /// The maximum amount of keepalive packets TCP should send before aborting the connection. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPCNT socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + keep-alive-count: func() -> result; + set-keep-alive-count: func(value: u32) -> result<_, error-code>; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + /// - `invalid-state`: (set) The socket is already in the Connection state. + /// - `invalid-state`: (set) The socket is already in the Listener state. + hop-limit: func() -> result; + set-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + /// - `invalid-state`: (set) The socket is already in the Connection state. + /// - `invalid-state`: (set) The socket is already in the Listener state. + receive-buffer-size: func() -> result; + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + send-buffer-size: func() -> result; + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + + /// Initiate a graceful shutdown. + /// + /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read + /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. + /// Any data still in the receive queue at time of calling `shutdown` will be discarded. + /// - send: the socket is not expecting to send any more data to the peer. All subsequent write + /// operations on the `output-stream` associated with this socket will return an error. + /// - both: same effect as receive & send combined. + /// + /// The shutdown function does not close (drop) the socket. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not in the Connection state. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; + } } diff --git a/proposals/cli/wit/deps/sockets/udp-create-socket.wit b/proposals/cli/wit/deps/sockets/udp-create-socket.wit index 66f948226..cc58234d8 100644 --- a/proposals/cli/wit/deps/sockets/udp-create-socket.wit +++ b/proposals/cli/wit/deps/sockets/udp-create-socket.wit @@ -1,27 +1,26 @@ interface udp-create-socket { - use network.{network, error-code, ip-address-family}; - use udp.{udp-socket}; + use network.{network, error-code, ip-address-family}; + use udp.{udp-socket}; - /// Create a new UDP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. - /// - /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` is called, - /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// - /// # Typical errors - /// - `not-supported`: The host does not support UDP sockets. (EOPNOTSUPP) - /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References: - /// - - /// - - /// - - /// - - create-udp-socket: func(address-family: ip-address-family) -> result; + /// Create a new UDP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind` is called, + /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # Typical errors + /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References: + /// - + /// - + /// - + /// - + create-udp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index e20b57e7e..c8dafadfc 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,214 +1,277 @@ interface udp { - use wasi:io/poll.{pollable}; - use network.{network, error-code, ip-socket-address, ip-address-family}; - - - record datagram { - data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. - remote-address: ip-socket-address, - - /// Possible future additions: - /// local-address: ip-socket-address, // IP_PKTINFO / IP_RECVDSTADDR / IPV6_PKTINFO - /// local-interface: u32, // IP_PKTINFO / IP_RECVIF - /// ttl: u8, // IP_RECVTTL - /// dscp: u6, // IP_RECVTOS - /// ecn: u2, // IP_RECVTOS - } - - - - /// A UDP socket handle. - resource udp-socket { - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) - /// - `already-bound`: The socket is already bound. (EINVAL) - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; - finish-bind: func() -> result<_, error-code>; - - /// Set the destination address. - /// - /// The local-address is updated based on the best network path to `remote-address`. - /// - /// When a destination address is set: - /// - all receive operations will only return datagrams sent from the provided `remote-address`. - /// - the `send` function can only be used to send to this destination. - /// - /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; - finish-connect: func() -> result<_, error-code>; - - /// Receive messages on the socket. - /// - /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. - /// The returned list may contain fewer elements than requested, but never more. - /// If `max-results` is 0, this function returns successfully with an empty list. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. (EINVAL) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - receive: func(max-results: u64) -> result, error-code>; - - /// Send messages on the socket. - /// - /// This function attempts to send all provided `datagrams` on the socket without blocking and - /// returns how many messages were actually sent (or queued for sending). - /// - /// This function semantically behaves the same as iterating the `datagrams` list and sequentially - /// sending each individual datagram until either the end of the list has been reached or the first error occurred. - /// If at least one datagram has been sent successfully, this function never returns an error. - /// - /// If the input list is empty, the function returns `ok(0)`. - /// - /// The remote address option is required. To send a message to the "connected" peer, - /// call `remote-address` to get their address. - /// - /// # Typical errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN) - /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. - /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) - /// - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - send: func(datagrams: list) -> result; - - /// Get the current bound address. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - local-address: func() -> result; - - /// Get the address set with `connect`. - /// - /// # Typical errors - /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - remote-address: func() -> result; - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func() -> ip-address-family; - - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. - /// - `already-bound`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - ipv6-only: func() -> result; - set-ipv6-only: func(value: bool) -> result<_, error-code>; - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - unicast-hop-limit: func() -> result; - set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - receive-buffer-size: func() -> result; - set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - send-buffer-size: func() -> result; - set-send-buffer-size: func(value: u64) -> result<_, error-code>; - - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable; - } + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use network.{network, error-code, ip-socket-address, ip-address-family}; + + /// A received datagram. + record incoming-datagram { + /// The payload. + /// + /// Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. + data: list, + + /// The source address. + /// + /// This field is guaranteed to match the remote address the stream was initialized with, if any. + /// + /// Equivalent to the `src_addr` out parameter of `recvfrom`. + remote-address: ip-socket-address, + } + + /// A datagram to be sent out. + record outgoing-datagram { + /// The payload. + data: list, + + /// The destination address. + /// + /// The requirements on this field depend on how the stream was initialized: + /// - with a remote address: this field must be None or match the stream's remote address exactly. + /// - without a remote address: this field is required. + /// + /// If this value is None, the send operation is equivalent to `send` in POSIX. Otherwise it is equivalent to `sendto`. + remote-address: option, + } + + + + /// A UDP socket handle. + resource udp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the port is zero, the socket will be bound to a random free port. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// + /// # Typical `finish` errors + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + finish-bind: func() -> result<_, error-code>; + + /// Set up inbound & outbound communication channels, optionally to a specific peer. + /// + /// This function only changes the local socket configuration and does not generate any network traffic. + /// On success, the `remote-address` of the socket is updated. The `local-address` may be updated as well, + /// based on the best network path to `remote-address`. + /// + /// When a `remote-address` is provided, the returned streams are limited to communicating with that specific peer: + /// - `send` can only be used to send to this destination. + /// - `receive` will only return datagrams sent from the provided `remote-address`. + /// + /// This method may be called multiple times on the same socket to change its association, but + /// only the most recently returned pair of streams will be operational. Implementations may trap if + /// the streams returned by a previous invocation haven't been dropped yet before calling `stream` again. + /// + /// The POSIX equivalent in pseudo-code is: + /// ```text + /// if (was previously connected) { + /// connect(s, AF_UNSPEC) + /// } + /// if (remote_address is Some) { + /// connect(s, remote_address) + /// } + /// ``` + /// + /// Unlike in POSIX, the socket must already be explicitly bound. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-state`: The socket is not bound. + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// + /// # References + /// - + /// - + /// - + /// - + %stream: func(remote-address: option) -> result, error-code>; + + /// Get the current bound address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func() -> result; + + /// Get the address the socket is currently streaming to. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not streaming to a specific remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func() -> result; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family; + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// # Typical errors + /// - `not-supported`: (get/set) `this` socket is an IPv4 socket. + /// - `invalid-state`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + ipv6-only: func() -> result; + set-ipv6-only: func(value: bool) -> result<_, error-code>; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + unicast-hop-limit: func() -> result; + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + receive-buffer-size: func() -> result; + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + send-buffer-size: func() -> result; + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } + + resource incoming-datagram-stream { + /// Receive messages on the socket. + /// + /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. + /// The returned list may contain fewer elements than requested, but never more. + /// + /// This function returns successfully with an empty list when either: + /// - `max-results` is 0, or: + /// - `max-results` is greater than 0, but no results are immediately available. + /// This function never returns `error(would-block)`. + /// + /// # Typical errors + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + receive: func(max-results: u64) -> result, error-code>; + + /// Create a `pollable` which will resolve once the stream is ready to receive again. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } + + resource outgoing-datagram-stream { + /// Check readiness for sending. This function never blocks. + /// + /// Returns the number of datagrams permitted for the next call to `send`, + /// or an error. Calling `send` with more datagrams than this function has + /// permitted will trap. + /// + /// When this function returns ok(0), the `subscribe` pollable will + /// become ready when this function will report at least ok(1), or an + /// error. + /// + /// Never returns `would-block`. + check-send: func() -> result; + + /// Send messages on the socket. + /// + /// This function attempts to send all provided `datagrams` on the socket without blocking and + /// returns how many messages were actually sent (or queued for sending). This function never + /// returns `error(would-block)`. If none of the datagrams were able to be sent, `ok(0)` is returned. + /// + /// This function semantically behaves the same as iterating the `datagrams` list and sequentially + /// sending each individual datagram until either the end of the list has been reached or the first error occurred. + /// If at least one datagram has been sent successfully, this function never returns an error. + /// + /// If the input list is empty, the function returns `ok(0)`. + /// + /// Each call to `send` must be permitted by a preceding `check-send`. Implementations must trap if + /// either `check-send` was not called or `datagrams` contains more items than `check-send` permitted. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `stream`. (EISCONN) + /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + send: func(datagrams: list) -> result; + + /// Create a `pollable` which will resolve once the stream is ready to send again. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } } diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit index 432b0dc99..49ad8d3d9 100644 --- a/proposals/cli/wit/deps/sockets/world.wit +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets; +package wasi:sockets@0.2.0-rc-2023-11-10; world imports { import instance-network; From 77008bd2529068ef1194715a2b8db7ef7c455135 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 16:13:06 -0800 Subject: [PATCH 1307/1772] imports and uses point to 0.2.0-rc-2023-11-10 versions --- proposals/cli/wit/reactor.wit | 33 ++++++++++++++++----------------- proposals/cli/wit/stdio.wit | 6 +++--- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/proposals/cli/wit/reactor.wit b/proposals/cli/wit/reactor.wit index 6bd780e76..01eb78484 100644 --- a/proposals/cli/wit/reactor.wit +++ b/proposals/cli/wit/reactor.wit @@ -1,23 +1,22 @@ package wasi:cli; world reactor { - import wasi:clocks/wall-clock; - import wasi:clocks/monotonic-clock; - import wasi:clocks/timezone; - import wasi:filesystem/types; - import wasi:filesystem/preopens; - import wasi:sockets/instance-network; - import wasi:sockets/ip-name-lookup; - import wasi:sockets/network; - import wasi:sockets/tcp-create-socket; - import wasi:sockets/tcp; - import wasi:sockets/udp-create-socket; - import wasi:sockets/udp; - import wasi:random/random; - import wasi:random/insecure; - import wasi:random/insecure-seed; - import wasi:io/poll; - import wasi:io/streams; + import wasi:clocks/wall-clock@0.2.0-rc-2023-11-10; + import wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10; + import wasi:filesystem/types@0.2.0-rc-2023-11-10; + import wasi:filesystem/preopens@0.2.0-rc-2023-11-10; + import wasi:sockets/instance-network@0.2.0-rc-2023-11-10; + import wasi:sockets/ip-name-lookup@0.2.0-rc-2023-11-10; + import wasi:sockets/network@0.2.0-rc-2023-11-10; + import wasi:sockets/tcp-create-socket@0.2.0-rc-2023-11-10; + import wasi:sockets/tcp@0.2.0-rc-2023-11-10; + import wasi:sockets/udp-create-socket@0.2.0-rc-2023-11-10; + import wasi:sockets/udp@0.2.0-rc-2023-11-10; + import wasi:random/random@0.2.0-rc-2023-11-10; + import wasi:random/insecure@0.2.0-rc-2023-11-10; + import wasi:random/insecure-seed@0.2.0-rc-2023-11-10; + import wasi:io/poll@0.2.0-rc-2023-11-10; + import wasi:io/streams@0.2.0-rc-2023-11-10; import environment; import exit; diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index 1bb6c5583..1b653b6e2 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,17 +1,17 @@ interface stdin { - use wasi:io/streams.{input-stream}; + use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream}; get-stdin: func() -> input-stream; } interface stdout { - use wasi:io/streams.{output-stream}; + use wasi:io/streams@0.2.0-rc-2023-11-10.{output-stream}; get-stdout: func() -> output-stream; } interface stderr { - use wasi:io/streams.{output-stream}; + use wasi:io/streams@0.2.0-rc-2023-11-10.{output-stream}; get-stderr: func() -> output-stream; } From 9d405593a3d80a25b377c7459423e17ca8367ebf Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 16:14:41 -0800 Subject: [PATCH 1308/1772] set wasi:cli package version to 0.2.0-rc-2023-11-10 --- proposals/cli/wit/command.wit | 2 +- proposals/cli/wit/reactor.wit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index 86c9c73b7..74811d327 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,4 +1,4 @@ -package wasi:cli; +package wasi:cli@0.2.0-rc-2023-11-10; world command { include reactor; diff --git a/proposals/cli/wit/reactor.wit b/proposals/cli/wit/reactor.wit index 01eb78484..eafa2fd49 100644 --- a/proposals/cli/wit/reactor.wit +++ b/proposals/cli/wit/reactor.wit @@ -1,4 +1,4 @@ -package wasi:cli; +package wasi:cli@0.2.0-rc-2023-11-10; world reactor { import wasi:clocks/wall-clock@0.2.0-rc-2023-11-10; From 9bc1d2b2b2558fe1c5e9a0a33fa09573106fe3ef Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 10 Nov 2023 16:14:53 -0800 Subject: [PATCH 1309/1772] generate markdown --- proposals/cli/command.md | 978 +++++++++++++++++++------------------- proposals/cli/reactor.md | 980 +++++++++++++++++++-------------------- 2 files changed, 965 insertions(+), 993 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 4c9ead44c..dda65a875 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -2,42 +2,42 @@ -

      Import interface wasi:clocks/wall-clock

      +

      Import interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10

      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

      @@ -78,7 +78,7 @@ also known as Unix Time.
    • datetime
    -

    Import interface wasi:io/poll

    +

    Import interface wasi:io/poll@0.2.0-rc-2023-11-10

    A poll API intended to let users wait for I/O events on multiple handles at once.


    @@ -128,7 +128,7 @@ being reaedy for I/O.

    • list<u32>
    -

    Import interface wasi:clocks/monotonic-clock

    +

    Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

    WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

    It is intended to be portable at least between Unix-family platforms and @@ -189,83 +189,41 @@ occured.

    -

    Import interface wasi:clocks/timezone

    +

    Import interface wasi:io/error@0.2.0-rc-2023-11-10


    Types

    -

    type datetime

    -

    datetime

    -

    -#### `record timezone-display` -

    Information useful for displaying the timezone of a specific datetime.

    -

    This information may vary within a single timezone to reflect daylight -saving time adjustments.

    -
    Record Fields
    -
      -
    • -

      utc-offset: s32

      -

      The number of seconds difference between UTC time and the local -time of the timezone. -

      The returned value will always be less than 86400 which is the -number of seconds in a day (246060).

      -

      In implementations that do not expose an actual time zone, this -should return 0.

      -
    • -
    • -

      name: string

      -

      The abbreviated name of the timezone to display to a user. The name -`UTC` indicates Coordinated Universal Time. Otherwise, this should -reference local standards for the name of the time zone. -

      In implementations that do not expose an actual time zone, this -should be the string UTC.

      -

      In time zones that do not have an applicable name, a formatted -representation of the UTC offset may be returned, such as -04:00.

      -
    • -
    • -

      in-daylight-saving-time: bool

      -

      Whether daylight saving time is active. -

      In implementations that do not expose an actual time zone, this -should return false.

      -
    • -
    +

    resource error


    Functions

    -

    display: func

    -

    Return information needed to display the given datetime. This includes -the UTC offset, the time zone name, and a flag indicating whether -daylight saving time is active.

    -

    If the timezone cannot be determined for the given datetime, return a -timezone-display for UTC with a utc-offset of 0 and no daylight -saving time.

    -
    Params
    - -
    Return values
    - -

    utc-offset: func

    -

    The same as display, but only return the UTC offset.

    +

    [method]error.to-debug-string: func

    +

    Returns a string that is suitable to assist humans in debugging +this error.

    +

    WARNING: The returned string should not be consumed mechanically! +It may change across platforms, hosts, or other implementation +details. Parsing this string is a major platform-compatibility +hazard.

    Params
    Return values
      -
    • s32
    • +
    • string
    -

    Import interface wasi:io/streams

    +

    Import interface wasi:io/streams@0.2.0-rc-2023-11-10

    WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

    In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


    Types

    -

    type pollable

    -

    pollable

    +

    type error

    +

    error

    +

    +#### `type pollable` +[`pollable`](#pollable)

    -#### `resource error` -

    variant stream-error

    +#### `variant stream-error`

    An error for input-stream and output-stream operations.

    Variant Cases
    -

    flags modes

    -

    Permissions mode used by open-at, change-file-permissions-at, and -similar.

    -
    Flags members
    -
      -
    • -

      readable:

      -

      True if the resource is considered readable by the containing -filesystem. -

    • -
    • -

      writable:

      -

      True if the resource is considered writable by the containing -filesystem. -

    • -
    • -

      executable:

      -

      True if the resource is considered executable by the containing -filesystem. This does not apply to directories. -

    • -
    -

    variant access-type

    -

    Access type used by access-at.

    -
    Variant Cases
    -
      -
    • -

      access: modes

      -

      Test for readability, writeability, or executability. -

    • -
    • -

      exists

      -

      Test whether the path exists. -

    • -

    type link-count

    u64

    Number of hard links to an inode. @@ -1324,7 +1234,6 @@ contains truncate or create, and the base descriptor d

  • path: string
  • open-flags: open-flags
  • flags: descriptor-flags
  • -
  • modes: modes
  • Return values

    See each individual API for what the POSIX equivalents are. They sometimes differ per API.

    Enum Cases
    @@ -1582,6 +1438,11 @@ combined with a couple of errors that are always possible:

    POSIX equivalent: EOPNOTSUPP

  • +

    invalid-argument

    +

    One of the arguments is invalid. +

    POSIX equivalent: EINVAL

    +
  • +
  • out-of-memory

    Not enough memory to complete the operation.

    POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY

    @@ -1593,6 +1454,7 @@ combined with a couple of errors that are always possible:

  • concurrency-conflict

    This operation is incompatible with another asynchronous operation that is already in progress. +

    POSIX equivalent: EALREADY

  • not-in-progress

    @@ -1607,74 +1469,26 @@ combined with a couple of errors that are always possible:

    Note: this is scheduled to be removed when futures are natively supported.

  • -

    address-family-not-supported

    -

    The specified address-family is not supported. -

  • -
  • -

    address-family-mismatch

    -

    An IPv4 address was passed to an IPv6 resource, or vice versa. -

  • -
  • -

    invalid-remote-address

    -

    The socket address is not a valid remote address. E.g. the IP address is set to INADDR_ANY, or the port is set to 0. -

  • -
  • -

    ipv4-only-operation

    -

    The operation is only supported on IPv4 resources. -

  • -
  • -

    ipv6-only-operation

    -

    The operation is only supported on IPv6 resources. +

    invalid-state

    +

    The operation is not valid in the socket's current state.

  • new-socket-limit

    A new socket resource could not be created because of a system limit.

  • -

    already-attached

    -

    The socket is already attached to another network. -

  • -
  • -

    already-bound

    -

    The socket is already bound. -

  • -
  • -

    already-connected

    -

    The socket is already in the Connection state. -

  • -
  • -

    not-bound

    -

    The socket is not bound to any local address. -

  • -
  • -

    not-connected

    -

    The socket is not in the Connection state. -

  • -
  • address-not-bindable

    A bind operation failed because the provided address is not an address that the `network` can bind to.

  • address-in-use

    -

    A bind operation failed because the provided address is already in use. -

  • -
  • -

    ephemeral-ports-exhausted

    -

    A bind operation failed because there are no ephemeral ports available. +

    A bind operation failed because the provided address is already in use or because there are no ephemeral ports available.

  • remote-unreachable

    The remote address is not reachable

  • -

    already-listening

    -

    The socket is already in the Listener state. -

  • -
  • -

    not-listening

    -

    The socket is already in the Listener state. -

  • -
  • connection-refused

    The connection was forcefully rejected

  • @@ -1683,11 +1497,11 @@ combined with a couple of errors that are always possible:

    The connection was reset.

  • -

    datagram-too-large

    +

    connection-aborted

    +

    A connection was aborted.

  • -

    invalid-name

    -

    The provided name is a syntactically invalid domain name. +

    datagram-too-large

  • name-unresolvable

    @@ -1760,7 +1574,7 @@ combined with a couple of errors that are always possible:

  • ipv4: ipv4-socket-address
  • ipv6: ipv6-socket-address
  • -

    Import interface wasi:sockets/instance-network

    +

    Import interface wasi:sockets/instance-network@0.2.0-rc-2023-11-10

    This interface provides a value-export of the default network handle..


    Types

    @@ -1775,7 +1589,7 @@ combined with a couple of errors that are always possible:

    -

    Import interface wasi:sockets/ip-name-lookup

    +

    Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2023-11-10


    Types

    type pollable

    @@ -1790,35 +1604,21 @@ combined with a couple of errors that are always possible:

    #### `type ip-address` [`ip-address`](#ip_address)

    -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) -

    #### `resource resolve-address-stream`


    Functions

    resolve-addresses: func

    Resolve an internet host name to a list of IP addresses.

    +

    Unicode domain names are automatically converted to ASCII using IDNA encoding. +If the input is an IP address string, the address is parsed and returned +as-is without making any external requests.

    See the wasi-socket proposal README.md for a comparison with getaddrinfo.

    -

    Parameters

    -
      -
    • name: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted -to ASCII using IDNA encoding.
    • -
    • address-family: If provided, limit the results to addresses of this specific address family.
    • -
    • include-unavailable: When set to true, this function will also return addresses of which the runtime -thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on -systems without an active IPv6 interface. Notes:
    • -
    • Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address.
    • -
    • Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged.
    • -
    -

    This function never blocks. It either immediately fails or immediately returns successfully with a resolve-address-stream -that can be used to (asynchronously) fetch the results.

    -

    At the moment, the stream never completes successfully with 0 items. Ie. the first call -to resolve-next-address never returns ok(none). This may change in the future.

    +

    This function never blocks. It either immediately fails or immediately +returns successfully with a resolve-address-stream that can be used +to (asynchronously) fetch the results.

    Typical errors

      -
    • invalid-name: name is a syntactically invalid domain name.
    • -
    • invalid-name: name is an IP address.
    • -
    • address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)
    • +
    • invalid-argument: name is a syntactically invalid domain name or IP address.

    References:

      @@ -1831,8 +1631,6 @@ to resolve-next-address never returns ok(none). This m
      Return values
        @@ -1871,7 +1669,7 @@ It's planned to be removed when future is natively supported in Pre -

        Import interface wasi:sockets/tcp

        +

        Import interface wasi:sockets/tcp@0.2.0-rc-2023-11-10


        Types

        type input-stream

        @@ -1883,6 +1681,9 @@ It's planned to be removed when future is natively supported in Pre #### `type pollable` [`pollable`](#pollable)

        +#### `type duration` +[`duration`](#duration) +

        #### `type network` [`network`](#network)

        @@ -1924,13 +1725,14 @@ implicitly bind the socket.

        Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

        Typical start errors

          -
        • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
        • -
        • already-bound: The socket is already bound. (EINVAL)
        • -
        • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
        • +
        • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
        • +
        • invalid-argument: local-address is not a unicast address. (EINVAL)
        • +
        • invalid-argument: local-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL)
        • +
        • invalid-state: The socket is already bound. (EINVAL)

        Typical finish errors

          -
        • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
        • +
        • address-in-use: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
        • address-in-use: Address is already in use. (EADDRINUSE)
        • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
        • not-in-progress: A bind operation is not in progress.
        • @@ -1969,23 +1771,37 @@ implicitly bind the socket.

        • the socket is transitioned into the Connection state
        • a pair of streams is returned that can be used to read & write to the connection
        +

        POSIX mentions:

        +
        +

        If connect() fails, the state of the socket is unspecified. Conforming applications should +close the file descriptor and create a new socket before attempting to reconnect.

        +
        +

        WASI prescribes the following behavior:

        +
          +
        • If connect fails because an input/state validation error, the socket should remain usable.
        • +
        • If a connection was actually attempted but failed, the socket should become unusable for further network communication. +Besides drop, any method after such a failure may return an error.
        • +

        Typical start errors

          -
        • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
        • -
        • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
        • -
        • invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
        • -
        • already-attached: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
        • -
        • already-connected: The socket is already in the Connection state. (EISCONN)
        • -
        • already-listening: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
        • -
        • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
        • +
        • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
        • +
        • invalid-argument: remote-address is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
        • +
        • invalid-argument: remote-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL, EADDRNOTAVAIL on Illumos)
        • +
        • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
        • +
        • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
        • +
        • invalid-argument: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
        • +
        • invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
        • +
        • invalid-state: The socket is already in the Connection state. (EISCONN)
        • +
        • invalid-state: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)

        Typical finish errors

        • timeout: Connection timed out. (ETIMEDOUT)
        • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
        • connection-reset: The connection was reset. (ECONNRESET)
        • -
        • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
        • -
        • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
        • +
        • connection-aborted: The connection was aborted. (ECONNABORTED)
        • +
        • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
        • +
        • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
        • not-in-progress: A connect operation is not in progress.
        • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
        @@ -2025,14 +1841,13 @@ implicitly bind the socket.

      Typical start errors

        -
      • not-bound: The socket is not bound to any local address. (EDESTADDRREQ)
      • -
      • already-connected: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
      • -
      • already-listening: The socket is already in the Listener state.
      • -
      • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EINVAL on BSD)
      • +
      • invalid-state: The socket is not bound to any local address. (EDESTADDRREQ)
      • +
      • invalid-state: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
      • +
      • invalid-state: The socket is already in the Listener state.

      Typical finish errors

        -
      • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
      • +
      • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
      • not-in-progress: A listen operation is not in progress.
      • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
      @@ -2062,15 +1877,27 @@ implicitly bind the socket.

    [method]tcp-socket.accept: func

    Accept a new client socket.

    -

    The returned socket is bound and in the Connection state.

    +

    The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket:

    +
      +
    • address-family
    • +
    • ipv6-only
    • +
    • keep-alive-enabled
    • +
    • keep-alive-idle-time
    • +
    • keep-alive-interval
    • +
    • keep-alive-count
    • +
    • hop-limit
    • +
    • receive-buffer-size
    • +
    • send-buffer-size
    • +

    On success, this function returns the newly accepted client socket along with a pair of streams that can be used to read & write to the connection.

    Typical errors

      -
    • not-listening: Socket is not in the Listener state. (EINVAL)
    • -
    • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
    • +
    • invalid-state: Socket is not in the Listener state. (EINVAL)
    • +
    • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
    • +
    • connection-aborted: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED)
    • +
    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
    -

    Host implementations must skip over transient errors returned by the native accept syscall.

    References

    [method]tcp-socket.local-address: func

    Get the bound local address.

    +

    POSIX mentions:

    +
    +

    If the socket has not been bound to a local name, the value +stored in the object pointed to by address is unspecified.

    +
    +

    WASI is stricter and requires local-address to return invalid-state when the socket hasn't been bound yet.

    Typical errors

      -
    • not-bound: The socket is not bound to any local address.
    • +
    • invalid-state: The socket is not bound to any local address.

    References

    [method]tcp-socket.remote-address: func

    -

    Get the bound remote address.

    +

    Get the remote address.

    Typical errors

      -
    • not-connected: The socket is not connected to a remote address. (ENOTCONN)
    • +
    • invalid-state: The socket is not connected to a remote address. (ENOTCONN)

    References

      @@ -2128,6 +1961,17 @@ a pair of streams that can be used to read & write to the connection.

      +

      [method]tcp-socket.is-listening: func

      +

      Whether the socket is listening for new connections.

      +

      Equivalent to the SO_ACCEPTCONN socket option.

      +
      Params
      + +
      Return values
      +
        +
      • bool
      • +

      [method]tcp-socket.address-family: func

      Whether this is a IPv4 or IPv6 socket.

      Equivalent to the SO_DOMAIN socket option.

      @@ -2144,10 +1988,9 @@ a pair of streams that can be used to read & write to the connection.

      Equivalent to the IPV6_V6ONLY socket option.

      Typical errors

        -
      • ipv6-only-operation: (get/set) this socket is an IPv4 socket.
      • -
      • already-bound: (set) The socket is already bound.
      • +
      • invalid-state: (set) The socket is already bound.
      • +
      • not-supported: (get/set) this socket is an IPv4 socket.
      • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
      • -
      • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
      Params
        @@ -2169,10 +2012,13 @@ a pair of streams that can be used to read & write to the connection.

      [method]tcp-socket.set-listen-backlog-size: func

      Hints the desired listen queue size. Implementations are free to ignore this.

      +

      If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded.

      Typical errors

        -
      • already-connected: (set) The socket is already in the Connection state.
      • -
      • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
      • +
      • not-supported: (set) The platform does not support changing the backlog size after the initial listen.
      • +
      • invalid-argument: (set) The provided value was 0.
      • +
      • invalid-state: (set) The socket is already in the Connection state.
      Params
        @@ -2183,93 +2029,156 @@ a pair of streams that can be used to read & write to the connection.

        -

        [method]tcp-socket.keep-alive: func

        +

        [method]tcp-socket.keep-alive-enabled: func

        +

        Enables or disables keepalive.

        +

        The keepalive behavior can be adjusted using:

        +
          +
        • keep-alive-idle-time
        • +
        • keep-alive-interval
        • +
        • keep-alive-count +These properties can be configured while keep-alive-enabled is false, but only come into effect when keep-alive-enabled is true.
        • +

        Equivalent to the SO_KEEPALIVE socket option.

        +
        Params
        + +
        Return values
        + +

        [method]tcp-socket.set-keep-alive-enabled: func

        +
        Params
        + +
        Return values
        + +

        [method]tcp-socket.keep-alive-idle-time: func

        +

        Amount of time the connection has to be idle before TCP starts sending keepalive packets.

        +

        If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

        +

        Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS)

        Typical errors

          -
        • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
        • +
        • invalid-argument: (set) The provided value was 0.
        Params
        Return values
        -

        [method]tcp-socket.set-keep-alive: func

        +

        [method]tcp-socket.set-keep-alive-idle-time: func

        Params
        Return values
        -

        [method]tcp-socket.no-delay: func

        -

        Equivalent to the TCP_NODELAY socket option.

        +

        [method]tcp-socket.keep-alive-interval: func

        +

        The time between keepalive packets.

        +

        If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

        +

        Equivalent to the TCP_KEEPINTVL socket option.

        Typical errors

          -
        • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
        • +
        • invalid-argument: (set) The provided value was 0.
        Params
        Return values
        -

        [method]tcp-socket.set-no-delay: func

        +

        [method]tcp-socket.set-keep-alive-interval: func

        Params
        Return values
        +

        [method]tcp-socket.keep-alive-count: func

        +

        The maximum amount of keepalive packets TCP should send before aborting the connection.

        +

        If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

        +

        Equivalent to the TCP_KEEPCNT socket option.

        +

        Typical errors

        +
          +
        • invalid-argument: (set) The provided value was 0.
        -

        [method]tcp-socket.unicast-hop-limit: func

        +
        Params
        + +
        Return values
        + +

        [method]tcp-socket.set-keep-alive-count: func

        +
        Params
        + +
        Return values
        + +

        [method]tcp-socket.hop-limit: func

        Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

        +

        If the provided value is 0, an invalid-argument error is returned.

        Typical errors

          -
        • already-connected: (set) The socket is already in the Connection state.
        • -
        • already-listening: (set) The socket is already in the Listener state.
        • -
        • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
        • +
        • invalid-argument: (set) The TTL value must be 1 or higher.
        • +
        • invalid-state: (set) The socket is already in the Connection state.
        • +
        • invalid-state: (set) The socket is already in the Listener state.
        Params
        Return values
        -

        [method]tcp-socket.set-unicast-hop-limit: func

        +

        [method]tcp-socket.set-hop-limit: func

        Params
        Return values

        [method]tcp-socket.receive-buffer-size: func

        The kernel buffer space reserved for sends/receives on this socket.

        -

        Note #1: an implementation may choose to cap or round the buffer size when setting the value. -In other words, after setting a value, reading the same setting back may return a different value.

        -

        Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of -actual data to be sent/received by the application, because the kernel might also use the buffer space -for internal metadata structures.

        +

        If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

        Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

        Typical errors

          -
        • already-connected: (set) The socket is already in the Connection state.
        • -
        • already-listening: (set) The socket is already in the Listener state.
        • -
        • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
        • +
        • invalid-argument: (set) The provided value was 0.
        • +
        • invalid-state: (set) The socket is already in the Connection state.
        • +
        • invalid-state: (set) The socket is already in the Listener state.
        Params
          @@ -2333,7 +2242,7 @@ operations on the output-stream associ

          The shutdown function does not close (drop) the socket.

          Typical errors

            -
          • not-connected: The socket is not in the Connection state. (ENOTCONN)
          • +
          • invalid-state: The socket is not in the Connection state. (ENOTCONN)

          References

            @@ -2351,7 +2260,7 @@ operations on the output-stream associ -

            Import interface wasi:sockets/tcp-create-socket

            +

            Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2023-11-10


            Types

            type network

            @@ -2377,9 +2286,8 @@ is called, the socket is effectively an in-memory configuration object, unable t

            All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

            Typical errors

              -
            • not-supported: The host does not support TCP sockets. (EOPNOTSUPP)
            • -
            • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
            • -
            • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
            • +
            • not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
            • +
            • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)

            References

            -

            Import interface wasi:sockets/instance-network

            +

            Import interface wasi:sockets/instance-network@0.2.0-rc-2023-11-10

            This interface provides a value-export of the default network handle..


            Types

            @@ -1770,7 +1584,7 @@ combined with a couple of errors that are always possible:

            -

            Import interface wasi:sockets/ip-name-lookup

            +

            Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2023-11-10


            Types

            type pollable

            @@ -1785,35 +1599,21 @@ combined with a couple of errors that are always possible:

            #### `type ip-address` [`ip-address`](#ip_address)

            -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) -

            #### `resource resolve-address-stream`


            Functions

            resolve-addresses: func

            Resolve an internet host name to a list of IP addresses.

            +

            Unicode domain names are automatically converted to ASCII using IDNA encoding. +If the input is an IP address string, the address is parsed and returned +as-is without making any external requests.

            See the wasi-socket proposal README.md for a comparison with getaddrinfo.

            -

            Parameters

            -
              -
            • name: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted -to ASCII using IDNA encoding.
            • -
            • address-family: If provided, limit the results to addresses of this specific address family.
            • -
            • include-unavailable: When set to true, this function will also return addresses of which the runtime -thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on -systems without an active IPv6 interface. Notes:
            • -
            • Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address.
            • -
            • Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged.
            • -
            -

            This function never blocks. It either immediately fails or immediately returns successfully with a resolve-address-stream -that can be used to (asynchronously) fetch the results.

            -

            At the moment, the stream never completes successfully with 0 items. Ie. the first call -to resolve-next-address never returns ok(none). This may change in the future.

            +

            This function never blocks. It either immediately fails or immediately +returns successfully with a resolve-address-stream that can be used +to (asynchronously) fetch the results.

            Typical errors

              -
            • invalid-name: name is a syntactically invalid domain name.
            • -
            • invalid-name: name is an IP address.
            • -
            • address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)
            • +
            • invalid-argument: name is a syntactically invalid domain name or IP address.

            References:

              @@ -1826,8 +1626,6 @@ to resolve-next-address never returns ok(none). This m
              Return values
                @@ -1866,7 +1664,7 @@ It's planned to be removed when future is natively supported in Pre -

                Import interface wasi:sockets/tcp

                +

                Import interface wasi:sockets/tcp@0.2.0-rc-2023-11-10


                Types

                type input-stream

                @@ -1878,6 +1676,9 @@ It's planned to be removed when future is natively supported in Pre #### `type pollable` [`pollable`](#pollable)

                +#### `type duration` +[`duration`](#duration) +

                #### `type network` [`network`](#network)

                @@ -1919,13 +1720,14 @@ implicitly bind the socket.

                Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                Typical start errors

                  -
                • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
                • -
                • already-bound: The socket is already bound. (EINVAL)
                • -
                • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
                • +
                • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
                • +
                • invalid-argument: local-address is not a unicast address. (EINVAL)
                • +
                • invalid-argument: local-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL)
                • +
                • invalid-state: The socket is already bound. (EINVAL)

                Typical finish errors

                  -
                • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
                • +
                • address-in-use: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
                • address-in-use: Address is already in use. (EADDRINUSE)
                • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
                • not-in-progress: A bind operation is not in progress.
                • @@ -1964,23 +1766,37 @@ implicitly bind the socket.

                • the socket is transitioned into the Connection state
                • a pair of streams is returned that can be used to read & write to the connection
                +

                POSIX mentions:

                +
                +

                If connect() fails, the state of the socket is unspecified. Conforming applications should +close the file descriptor and create a new socket before attempting to reconnect.

                +
                +

                WASI prescribes the following behavior:

                +
                  +
                • If connect fails because an input/state validation error, the socket should remain usable.
                • +
                • If a connection was actually attempted but failed, the socket should become unusable for further network communication. +Besides drop, any method after such a failure may return an error.
                • +

                Typical start errors

                  -
                • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
                • -
                • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
                • -
                • invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
                • -
                • already-attached: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
                • -
                • already-connected: The socket is already in the Connection state. (EISCONN)
                • -
                • already-listening: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
                • -
                • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
                • +
                • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
                • +
                • invalid-argument: remote-address is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
                • +
                • invalid-argument: remote-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL, EADDRNOTAVAIL on Illumos)
                • +
                • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
                • +
                • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
                • +
                • invalid-argument: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
                • +
                • invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
                • +
                • invalid-state: The socket is already in the Connection state. (EISCONN)
                • +
                • invalid-state: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)

                Typical finish errors

                • timeout: Connection timed out. (ETIMEDOUT)
                • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
                • connection-reset: The connection was reset. (ECONNRESET)
                • -
                • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
                • -
                • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
                • +
                • connection-aborted: The connection was aborted. (ECONNABORTED)
                • +
                • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
                • +
                • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
                • not-in-progress: A connect operation is not in progress.
                • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
                @@ -2020,14 +1836,13 @@ implicitly bind the socket.

              Typical start errors

                -
              • not-bound: The socket is not bound to any local address. (EDESTADDRREQ)
              • -
              • already-connected: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
              • -
              • already-listening: The socket is already in the Listener state.
              • -
              • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EINVAL on BSD)
              • +
              • invalid-state: The socket is not bound to any local address. (EDESTADDRREQ)
              • +
              • invalid-state: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
              • +
              • invalid-state: The socket is already in the Listener state.

              Typical finish errors

                -
              • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
              • +
              • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
              • not-in-progress: A listen operation is not in progress.
              • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
              @@ -2057,15 +1872,27 @@ implicitly bind the socket.

            [method]tcp-socket.accept: func

            Accept a new client socket.

            -

            The returned socket is bound and in the Connection state.

            +

            The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket:

            +
              +
            • address-family
            • +
            • ipv6-only
            • +
            • keep-alive-enabled
            • +
            • keep-alive-idle-time
            • +
            • keep-alive-interval
            • +
            • keep-alive-count
            • +
            • hop-limit
            • +
            • receive-buffer-size
            • +
            • send-buffer-size
            • +

            On success, this function returns the newly accepted client socket along with a pair of streams that can be used to read & write to the connection.

            Typical errors

              -
            • not-listening: Socket is not in the Listener state. (EINVAL)
            • -
            • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
            • +
            • invalid-state: Socket is not in the Listener state. (EINVAL)
            • +
            • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
            • +
            • connection-aborted: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED)
            • +
            • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
            -

            Host implementations must skip over transient errors returned by the native accept syscall.

            References

            [method]tcp-socket.local-address: func

            Get the bound local address.

            +

            POSIX mentions:

            +
            +

            If the socket has not been bound to a local name, the value +stored in the object pointed to by address is unspecified.

            +
            +

            WASI is stricter and requires local-address to return invalid-state when the socket hasn't been bound yet.

            Typical errors

              -
            • not-bound: The socket is not bound to any local address.
            • +
            • invalid-state: The socket is not bound to any local address.

            References

            [method]tcp-socket.remote-address: func

            -

            Get the bound remote address.

            +

            Get the remote address.

            Typical errors

              -
            • not-connected: The socket is not connected to a remote address. (ENOTCONN)
            • +
            • invalid-state: The socket is not connected to a remote address. (ENOTCONN)

            References

              @@ -2123,6 +1956,17 @@ a pair of streams that can be used to read & write to the connection.

              +

              [method]tcp-socket.is-listening: func

              +

              Whether the socket is listening for new connections.

              +

              Equivalent to the SO_ACCEPTCONN socket option.

              +
              Params
              + +
              Return values
              +
                +
              • bool
              • +

              [method]tcp-socket.address-family: func

              Whether this is a IPv4 or IPv6 socket.

              Equivalent to the SO_DOMAIN socket option.

              @@ -2139,10 +1983,9 @@ a pair of streams that can be used to read & write to the connection.

              Equivalent to the IPV6_V6ONLY socket option.

              Typical errors

                -
              • ipv6-only-operation: (get/set) this socket is an IPv4 socket.
              • -
              • already-bound: (set) The socket is already bound.
              • +
              • invalid-state: (set) The socket is already bound.
              • +
              • not-supported: (get/set) this socket is an IPv4 socket.
              • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
              • -
              • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
              Params
                @@ -2164,10 +2007,13 @@ a pair of streams that can be used to read & write to the connection.

              [method]tcp-socket.set-listen-backlog-size: func

              Hints the desired listen queue size. Implementations are free to ignore this.

              +

              If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded.

              Typical errors

                -
              • already-connected: (set) The socket is already in the Connection state.
              • -
              • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
              • +
              • not-supported: (set) The platform does not support changing the backlog size after the initial listen.
              • +
              • invalid-argument: (set) The provided value was 0.
              • +
              • invalid-state: (set) The socket is already in the Connection state.
              Params
                @@ -2178,93 +2024,156 @@ a pair of streams that can be used to read & write to the connection.

                -

                [method]tcp-socket.keep-alive: func

                +

                [method]tcp-socket.keep-alive-enabled: func

                +

                Enables or disables keepalive.

                +

                The keepalive behavior can be adjusted using:

                +
                  +
                • keep-alive-idle-time
                • +
                • keep-alive-interval
                • +
                • keep-alive-count +These properties can be configured while keep-alive-enabled is false, but only come into effect when keep-alive-enabled is true.
                • +

                Equivalent to the SO_KEEPALIVE socket option.

                +
                Params
                + +
                Return values
                + +

                [method]tcp-socket.set-keep-alive-enabled: func

                +
                Params
                + +
                Return values
                + +

                [method]tcp-socket.keep-alive-idle-time: func

                +

                Amount of time the connection has to be idle before TCP starts sending keepalive packets.

                +

                If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

                +

                Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS)

                Typical errors

                  -
                • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                • +
                • invalid-argument: (set) The provided value was 0.
                Params
                Return values
                -

                [method]tcp-socket.set-keep-alive: func

                +

                [method]tcp-socket.set-keep-alive-idle-time: func

                Params
                Return values
                -

                [method]tcp-socket.no-delay: func

                -

                Equivalent to the TCP_NODELAY socket option.

                +

                [method]tcp-socket.keep-alive-interval: func

                +

                The time between keepalive packets.

                +

                If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

                +

                Equivalent to the TCP_KEEPINTVL socket option.

                Typical errors

                  -
                • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                • +
                • invalid-argument: (set) The provided value was 0.
                Params
                Return values
                -

                [method]tcp-socket.set-no-delay: func

                +

                [method]tcp-socket.set-keep-alive-interval: func

                Params
                Return values
                +

                [method]tcp-socket.keep-alive-count: func

                +

                The maximum amount of keepalive packets TCP should send before aborting the connection.

                +

                If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

                +

                Equivalent to the TCP_KEEPCNT socket option.

                +

                Typical errors

                +
                  +
                • invalid-argument: (set) The provided value was 0.
                -

                [method]tcp-socket.unicast-hop-limit: func

                +
                Params
                + +
                Return values
                + +

                [method]tcp-socket.set-keep-alive-count: func

                +
                Params
                + +
                Return values
                + +

                [method]tcp-socket.hop-limit: func

                Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                +

                If the provided value is 0, an invalid-argument error is returned.

                Typical errors

                  -
                • already-connected: (set) The socket is already in the Connection state.
                • -
                • already-listening: (set) The socket is already in the Listener state.
                • -
                • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                • +
                • invalid-argument: (set) The TTL value must be 1 or higher.
                • +
                • invalid-state: (set) The socket is already in the Connection state.
                • +
                • invalid-state: (set) The socket is already in the Listener state.
                Params
                Return values
                -

                [method]tcp-socket.set-unicast-hop-limit: func

                +

                [method]tcp-socket.set-hop-limit: func

                Params
                Return values

                [method]tcp-socket.receive-buffer-size: func

                The kernel buffer space reserved for sends/receives on this socket.

                -

                Note #1: an implementation may choose to cap or round the buffer size when setting the value. -In other words, after setting a value, reading the same setting back may return a different value.

                -

                Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of -actual data to be sent/received by the application, because the kernel might also use the buffer space -for internal metadata structures.

                +

                If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

                Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

                Typical errors

                  -
                • already-connected: (set) The socket is already in the Connection state.
                • -
                • already-listening: (set) The socket is already in the Listener state.
                • -
                • concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
                • +
                • invalid-argument: (set) The provided value was 0.
                • +
                • invalid-state: (set) The socket is already in the Connection state.
                • +
                • invalid-state: (set) The socket is already in the Listener state.
                Params
                  @@ -2328,7 +2237,7 @@ operations on the output-stream associ

                  The shutdown function does not close (drop) the socket.

                  Typical errors

                    -
                  • not-connected: The socket is not in the Connection state. (ENOTCONN)
                  • +
                  • invalid-state: The socket is not in the Connection state. (ENOTCONN)

                  References

                    @@ -2346,7 +2255,7 @@ operations on the output-stream associ -

                    Import interface wasi:sockets/tcp-create-socket

                    +

                    Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2023-11-10


                    Types

                    type network

                    @@ -2372,9 +2281,8 @@ is called, the socket is effectively an in-memory configuration object, unable t

                    All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

                    Typical errors

                      -
                    • not-supported: The host does not support TCP sockets. (EOPNOTSUPP)
                    • -
                    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
                    • -
                    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
                    • +
                    • not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
                    • +
                    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)

                    References

                      @@ -2391,7 +2299,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                      Import interface wasi:sockets/udp

                      +

                      Import interface wasi:sockets/udp@0.2.0-rc-2023-11-10


                      Types

                      type pollable

                      @@ -2409,31 +2317,60 @@ is called, the socket is effectively an in-memory configuration object, unable t #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                      -#### `record datagram` +#### `record incoming-datagram` +

                      A received datagram.

                      Record Fields
                        -
                      • data: list<u8>
                      • -
                      • remote-address: ip-socket-address
                      • +
                      • +

                        data: list<u8>

                        +

                        The payload. +

                        Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes.

                        +
                      • +
                      • +

                        remote-address: ip-socket-address

                        +

                        The source address. +

                        This field is guaranteed to match the remote address the stream was initialized with, if any.

                        +

                        Equivalent to the src_addr out parameter of recvfrom.

                        +
                      • +
                      +

                      record outgoing-datagram

                      +

                      A datagram to be sent out.

                      +
                      Record Fields
                      +
                        +
                      • +

                        data: list<u8>

                        +

                        The payload. +

                      • +
                      • +

                        remote-address: option<ip-socket-address>

                        +

                        The destination address. +

                        The requirements on this field depend on how the stream was initialized:

                        +
                          +
                        • with a remote address: this field must be None or match the stream's remote address exactly.
                        • +
                        • without a remote address: this field is required.
                        • +
                        +

                        If this value is None, the send operation is equivalent to send in POSIX. Otherwise it is equivalent to sendto.

                        +

                      resource udp-socket

                      +

                      resource incoming-datagram-stream

                      +

                      resource outgoing-datagram-stream


                      Functions

                      [method]udp-socket.start-bind: func

                      Bind the socket to a specific network on the provided IP address and port.

                      If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. -If the TCP/UDP port is zero, the socket will be bound to a random free port.

                      -

                      When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket.

                      +If the port is zero, the socket will be bound to a random free port.

                      Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                      Typical start errors

                        -
                      • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
                      • -
                      • already-bound: The socket is already bound. (EINVAL)
                      • -
                      • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
                      • +
                      • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
                      • +
                      • invalid-state: The socket is already bound. (EINVAL)

                      Typical finish errors

                        -
                      • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
                      • +
                      • address-in-use: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
                      • address-in-use: Address is already in use. (EADDRINUSE)
                      • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
                      • not-in-progress: A bind operation is not in progress.
                      • @@ -2465,29 +2402,38 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                        -

                        [method]udp-socket.start-connect: func

                        -

                        Set the destination address.

                        -

                        The local-address is updated based on the best network path to remote-address.

                        -

                        When a destination address is set:

                        -
                          -
                        • all receive operations will only return datagrams sent from the provided remote-address.
                        • -
                        • the send function can only be used to send to this destination.
                        • -
                        -

                        Note that this function does not generate any network traffic and the peer is not aware of this "connection".

                        -

                        Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                        -

                        Typical start errors

                        -
                          -
                        • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
                        • -
                        • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
                        • -
                        • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
                        • -
                        • already-attached: The socket is already bound to a different network. The network passed to connect must be identical to the one passed to bind.
                        • -
                        • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
                        • -
                        -

                        Typical finish errors

                        +

                        [method]udp-socket.stream: func

                        +

                        Set up inbound & outbound communication channels, optionally to a specific peer.

                        +

                        This function only changes the local socket configuration and does not generate any network traffic. +On success, the remote-address of the socket is updated. The local-address may be updated as well, +based on the best network path to remote-address.

                        +

                        When a remote-address is provided, the returned streams are limited to communicating with that specific peer:

                        +
                          +
                        • send can only be used to send to this destination.
                        • +
                        • receive will only return datagrams sent from the provided remote-address.
                        • +
                        +

                        This method may be called multiple times on the same socket to change its association, but +only the most recently returned pair of streams will be operational. Implementations may trap if +the streams returned by a previous invocation haven't been dropped yet before calling stream again.

                        +

                        The POSIX equivalent in pseudo-code is:

                        +
                        if (was previously connected) {
                        +  connect(s, AF_UNSPEC)
                        +}
                        +if (remote_address is Some) {
                        +  connect(s, remote_address)
                        +}
                        +
                        +

                        Unlike in POSIX, the socket must already be explicitly bound.

                        +

                        Typical errors

                          -
                        • ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
                        • -
                        • not-in-progress: A connect operation is not in progress.
                        • -
                        • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
                        • +
                        • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
                        • +
                        • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
                        • +
                        • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
                        • +
                        • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
                        • +
                        • invalid-state: The socket is not bound.
                        • +
                        • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
                        • +
                        • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
                        • +
                        • connection-refused: The connection was refused. (ECONNREFUSED)

                        References

                          @@ -2498,100 +2444,24 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                        Params
                        -
                        Return values
                        - -

                        [method]udp-socket.finish-connect: func

                        -
                        Params
                        - -
                        Return values
                        - -

                        [method]udp-socket.receive: func

                        -

                        Receive messages on the socket.

                        -

                        This function attempts to receive up to max-results datagrams on the socket without blocking. -The returned list may contain fewer elements than requested, but never more. -If max-results is 0, this function returns successfully with an empty list.

                        -

                        Typical errors

                        -
                          -
                        • not-bound: The socket is not bound to any local address. (EINVAL)
                        • -
                        • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
                        • -
                        • would-block: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN)
                        • -
                        -

                        References

                        - -
                        Params
                        -
                        Return values
                        -

                        [method]udp-socket.send: func

                        -

                        Send messages on the socket.

                        -

                        This function attempts to send all provided datagrams on the socket without blocking and -returns how many messages were actually sent (or queued for sending).

                        -

                        This function semantically behaves the same as iterating the datagrams list and sequentially -sending each individual datagram until either the end of the list has been reached or the first error occurred. -If at least one datagram has been sent successfully, this function never returns an error.

                        -

                        If the input list is empty, the function returns ok(0).

                        -

                        The remote address option is required. To send a message to the "connected" peer, -call remote-address to get their address.

                        -

                        Typical errors

                        -
                          -
                        • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
                        • -
                        • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
                        • -
                        • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
                        • -
                        • already-connected: The socket is in "connected" mode and the datagram.remote-address does not match the address passed to connect. (EISCONN)
                        • -
                        • not-bound: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind.
                        • -
                        • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
                        • -
                        • datagram-too-large: The datagram is too large. (EMSGSIZE)
                        • -
                        • would-block: The send buffer is currently full. (EWOULDBLOCK, EAGAIN)
                        • -
                        -

                        References

                        - -
                        Params
                        - -
                        Return values
                        -

                        [method]udp-socket.local-address: func

                        Get the current bound address.

                        +

                        POSIX mentions:

                        +
                        +

                        If the socket has not been bound to a local name, the value +stored in the object pointed to by address is unspecified.

                        +
                        +

                        WASI is stricter and requires local-address to return invalid-state when the socket hasn't been bound yet.

                        Typical errors

                          -
                        • not-bound: The socket is not bound to any local address.
                        • +
                        • invalid-state: The socket is not bound to any local address.

                        References

                        [method]udp-socket.remote-address: func

                        -

                        Get the address set with connect.

                        +

                        Get the address the socket is currently streaming to.

                        Typical errors

                          -
                        • not-connected: The socket is not connected to a remote address. (ENOTCONN)
                        • +
                        • invalid-state: The socket is not streaming to a specific remote address. (ENOTCONN)

                        References

                          @@ -2645,10 +2515,9 @@ call remote-address to get their address.

                          Equivalent to the IPV6_V6ONLY socket option.

                          Typical errors

                            -
                          • ipv6-only-operation: (get/set) this socket is an IPv4 socket.
                          • -
                          • already-bound: (set) The socket is already bound.
                          • +
                          • not-supported: (get/set) this socket is an IPv4 socket.
                          • +
                          • invalid-state: (set) The socket is already bound.
                          • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
                          • -
                          • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
                          Params
                            @@ -2670,9 +2539,10 @@ call remote-address to get their address.

                          [method]udp-socket.unicast-hop-limit: func

                          Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                          +

                          If the provided value is 0, an invalid-argument error is returned.

                          Typical errors

                            -
                          • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
                          • +
                          • invalid-argument: (set) The TTL value must be 1 or higher.
                          Params
                            @@ -2694,15 +2564,13 @@ call remote-address to get their address.

                          [method]udp-socket.receive-buffer-size: func

                          The kernel buffer space reserved for sends/receives on this socket.

                          -

                          Note #1: an implementation may choose to cap or round the buffer size when setting the value. -In other words, after setting a value, reading the same setting back may return a different value.

                          -

                          Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of -actual data to be sent/received by the application, because the kernel might also use the buffer space -for internal metadata structures.

                          +

                          If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

                          Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

                          Typical errors

                            -
                          • concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
                          • +
                          • invalid-argument: (set) The provided value was 0.
                          Params
                            @@ -2753,7 +2621,126 @@ It's planned to be removed when future is natively supported in Pre -

                            Import interface wasi:sockets/udp-create-socket

                            +

                            [method]incoming-datagram-stream.receive: func

                            +

                            Receive messages on the socket.

                            +

                            This function attempts to receive up to max-results datagrams on the socket without blocking. +The returned list may contain fewer elements than requested, but never more.

                            +

                            This function returns successfully with an empty list when either:

                            +
                              +
                            • max-results is 0, or:
                            • +
                            • max-results is greater than 0, but no results are immediately available. +This function never returns error(would-block).
                            • +
                            +

                            Typical errors

                            +
                              +
                            • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
                            • +
                            • connection-refused: The connection was refused. (ECONNREFUSED)
                            • +
                            +

                            References

                            + +
                            Params
                            + +
                            Return values
                            + +

                            [method]incoming-datagram-stream.subscribe: func

                            +

                            Create a pollable which will resolve once the stream is ready to receive again.

                            +

                            Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

                            +
                            Params
                            + +
                            Return values
                            + +

                            [method]outgoing-datagram-stream.check-send: func

                            +

                            Check readiness for sending. This function never blocks.

                            +

                            Returns the number of datagrams permitted for the next call to send, +or an error. Calling send with more datagrams than this function has +permitted will trap.

                            +

                            When this function returns ok(0), the subscribe pollable will +become ready when this function will report at least ok(1), or an +error.

                            +

                            Never returns would-block.

                            +
                            Params
                            + +
                            Return values
                            + +

                            [method]outgoing-datagram-stream.send: func

                            +

                            Send messages on the socket.

                            +

                            This function attempts to send all provided datagrams on the socket without blocking and +returns how many messages were actually sent (or queued for sending). This function never +returns error(would-block). If none of the datagrams were able to be sent, ok(0) is returned.

                            +

                            This function semantically behaves the same as iterating the datagrams list and sequentially +sending each individual datagram until either the end of the list has been reached or the first error occurred. +If at least one datagram has been sent successfully, this function never returns an error.

                            +

                            If the input list is empty, the function returns ok(0).

                            +

                            Each call to send must be permitted by a preceding check-send. Implementations must trap if +either check-send was not called or datagrams contains more items than check-send permitted.

                            +

                            Typical errors

                            +
                              +
                            • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
                            • +
                            • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
                            • +
                            • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
                            • +
                            • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
                            • +
                            • invalid-argument: The socket is in "connected" mode and remote-address is some value that does not match the address passed to stream. (EISCONN)
                            • +
                            • invalid-argument: The socket is not "connected" and no value for remote-address was provided. (EDESTADDRREQ)
                            • +
                            • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
                            • +
                            • connection-refused: The connection was refused. (ECONNREFUSED)
                            • +
                            • datagram-too-large: The datagram is too large. (EMSGSIZE)
                            • +
                            +

                            References

                            + +
                            Params
                            + +
                            Return values
                            + +

                            [method]outgoing-datagram-stream.subscribe: func

                            +

                            Create a pollable which will resolve once the stream is ready to send again.

                            +

                            Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

                            +
                            Params
                            + +
                            Return values
                            + +

                            Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2023-11-10


                            Types

                            type network

                            @@ -2774,14 +2761,13 @@ It's planned to be removed when future is natively supported in Pre

                            Create a new UDP socket.

                            Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.

                            This function does not require a network capability handle. This is considered to be safe because -at time of creation, the socket is not bound to any network yet. Up to the moment bind/connect is called, +at time of creation, the socket is not bound to any network yet. Up to the moment bind is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                            All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

                            Typical errors

                              -
                            • not-supported: The host does not support UDP sockets. (EOPNOTSUPP)
                            • -
                            • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
                            • -
                            • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
                            • +
                            • not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
                            • +
                            • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)

                            References:

                              @@ -2798,7 +2784,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                              Import interface wasi:random/random

                              +

                              Import interface wasi:random/random@0.2.0-rc-2023-11-10

                              WASI Random is a random data API.

                              It is intended to be portable at least between Unix-family platforms and Windows.

                              @@ -2831,7 +2817,7 @@ represented as a u64.

                              • u64
                              -

                              Import interface wasi:random/insecure

                              +

                              Import interface wasi:random/insecure@0.2.0-rc-2023-11-10

                              The insecure interface for insecure pseudo-random numbers.

                              It is intended to be portable at least between Unix-family platforms and Windows.

                              @@ -2860,7 +2846,7 @@ a long period.

                              • u64
                              -

                              Import interface wasi:random/insecure-seed

                              +

                              Import interface wasi:random/insecure-seed@0.2.0-rc-2023-11-10

                              The insecure-seed interface for seeding hash-map DoS resistance.

                              It is intended to be portable at least between Unix-family platforms and Windows.

                              @@ -2884,7 +2870,7 @@ protection.

                              • (u64, u64)
                              -

                              Import interface wasi:cli/environment

                              +

                              Import interface wasi:cli/environment@0.2.0-rc-2023-11-10


                              Functions

                              get-environment: func

                              @@ -2911,7 +2897,7 @@ directory, interpreting . as shorthand for this.

                              • option<string>
                              -

                              Import interface wasi:cli/exit

                              +

                              Import interface wasi:cli/exit@0.2.0-rc-2023-11-10


                              Functions

                              exit: func

                              @@ -2920,7 +2906,7 @@ directory, interpreting . as shorthand for this.

                              -

                              Import interface wasi:cli/stdin

                              +

                              Import interface wasi:cli/stdin@0.2.0-rc-2023-11-10


                              Types

                              type input-stream

                              @@ -2933,7 +2919,7 @@ directory, interpreting . as shorthand for this.

                              -

                              Import interface wasi:cli/stdout

                              +

                              Import interface wasi:cli/stdout@0.2.0-rc-2023-11-10


                              Types

                              type output-stream

                              @@ -2946,7 +2932,7 @@ directory, interpreting . as shorthand for this.

                              -

                              Import interface wasi:cli/stderr

                              +

                              Import interface wasi:cli/stderr@0.2.0-rc-2023-11-10


                              Types

                              type output-stream

                              @@ -2959,15 +2945,15 @@ directory, interpreting . as shorthand for this.

                              -

                              Import interface wasi:cli/terminal-input

                              +

                              Import interface wasi:cli/terminal-input@0.2.0-rc-2023-11-10


                              Types

                              resource terminal-input

                              -

                              Import interface wasi:cli/terminal-output

                              +

                              Import interface wasi:cli/terminal-output@0.2.0-rc-2023-11-10


                              Types

                              resource terminal-output

                              -

                              Import interface wasi:cli/terminal-stdin

                              +

                              Import interface wasi:cli/terminal-stdin@0.2.0-rc-2023-11-10

                              An interface providing an optional terminal-input for stdin as a link-time authority.


                              @@ -2984,7 +2970,7 @@ allowing further interaction with it.

                              -

                              Import interface wasi:cli/terminal-stdout

                              +

                              Import interface wasi:cli/terminal-stdout@0.2.0-rc-2023-11-10

                              An interface providing an optional terminal-output for stdout as a link-time authority.


                              @@ -3001,7 +2987,7 @@ allowing further interaction with it.

                              -

                              Import interface wasi:cli/terminal-stderr

                              +

                              Import interface wasi:cli/terminal-stderr@0.2.0-rc-2023-11-10

                              An interface providing an optional terminal-output for stderr as a link-time authority.


                              From 7a9b440b887a2a5140a4471f0cf464993b127330 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Mon, 13 Nov 2023 14:24:31 -0800 Subject: [PATCH 1310/1772] typo --- proposals/http/wit/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 0dcfc3174..c43c2e3a1 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -259,7 +259,7 @@ interface types { /// Request. /// /// Returns success on the first call: the `outgoing-body` resource for - /// this `outgoing-response` can be retrieved at most once. Subsequent + /// this `outgoing-request` can be retrieved at most once. Subsequent /// calls will return error. body: func() -> result; From 2ec830e6b49aec8f5f0d972cff7056ebb8f0acd8 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 13 Nov 2023 14:04:20 -0800 Subject: [PATCH 1311/1772] wit-deps update --- proposals/http/wit/deps.lock | 24 +- proposals/http/wit/deps/cli/command.wit | 2 +- proposals/http/wit/deps/cli/reactor.wit | 35 +- proposals/http/wit/deps/cli/stdio.wit | 6 +- .../http/wit/deps/clocks/monotonic-clock.wit | 3 +- proposals/http/wit/deps/clocks/timezone.wit | 48 -- proposals/http/wit/deps/clocks/wall-clock.wit | 1 + proposals/http/wit/deps/clocks/world.wit | 3 +- .../http/wit/deps/filesystem/preopens.wit | 2 + proposals/http/wit/deps/filesystem/types.wit | 83 +-- proposals/http/wit/deps/filesystem/world.wit | 2 +- proposals/http/wit/deps/io/error.wit | 34 ++ proposals/http/wit/deps/io/poll.wit | 2 +- proposals/http/wit/deps/io/streams.wit | 23 +- proposals/http/wit/deps/io/world.wit | 2 +- .../http/wit/deps/random/insecure-seed.wit | 1 + proposals/http/wit/deps/random/insecure.wit | 1 + proposals/http/wit/deps/random/random.wit | 1 + proposals/http/wit/deps/random/world.wit | 2 +- .../wit/deps/sockets/instance-network.wit | 6 +- .../http/wit/deps/sockets/ip-name-lookup.wit | 98 ++- proposals/http/wit/deps/sockets/network.wit | 243 ++++---- .../wit/deps/sockets/tcp-create-socket.wit | 45 +- proposals/http/wit/deps/sockets/tcp.wit | 564 ++++++++++-------- .../wit/deps/sockets/udp-create-socket.wit | 45 +- proposals/http/wit/deps/sockets/udp.wit | 485 ++++++++------- proposals/http/wit/deps/sockets/world.wit | 2 +- 27 files changed, 875 insertions(+), 888 deletions(-) delete mode 100644 proposals/http/wit/deps/clocks/timezone.wit create mode 100644 proposals/http/wit/deps/io/error.wit diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index f55de7c52..661a351c7 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,29 +1,29 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -sha256 = "bf57bb59e137f1dea6521409137e46dbdcd0a78d419ac2313b59fb21332718cd" -sha512 = "36a793525eba4921f0bd55bc445465e86fc7ff8fcf3e5bb61108d35e4d791950b107b456ccadf65897a0a5cd201a5955741c9c1fecb533fca99e8bae478a2dbf" +sha256 = "fb029d0f9468fcb404a079a58fafd9265ef99c0ee1350835348da7b6e105c597" +sha512 = "8602e881281adc67b1ac5a4eb0888636d6f50d15bd14e36dcc446a51551f3f9bb3e9eabb776d723bb113bf1e26a702c5042de095e66e897c3d3cf689e0b7d4f9" [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "8d6b9f7a8bf9466bdc68043c33e054878fdf09c1cc69c19c99eeadd3bb257a90" -sha512 = "21b65d911930c4512bb3caa08459283fc70b1ccc5159313092334cffd6662fb92cfe90577b51829ef363e2d02530802c88f2a1f82db43964d1f8bff7ecbc794b" +sha256 = "89da8eca4cd195516574c89c5b3c24a7b5af3ff2565c16753d20d3bdbc5fc60f" +sha512 = "244079b3f592d58478a97adbd0bee8d49ae9dd1a3e435651ee40997b50da9fe62cfaba7e3ec7f7406d7d0288d278a43a3a0bc5150226ba40ce0f8ac6d33f7ddb" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "c05155f44cf5798d15a16eaf9cdfb065d05914ed4710421a7448bb61c6decf3a" -sha512 = "fb30ea13678d3f3d2002b2cc1f6dae99ee6a06eae7c408c0d558f21e5039979dd80c8ced46b1a7629ce8b050820d81462093f7b4a733ff706d0258bf5dea5657" +sha256 = "05952bbc98895aa3aeda6c765a3e521016de59f993f3b60394c724640935c09c" +sha512 = "2c242489801a75466986fe014d730fb3aa7b5c6e56a230c8735e6672711b58bcbe92ba78a341b78fc3ac69339e55d3859d8bb14410230f0371ee30dbd83add64" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "fb76f4449eea54d06b56fc6a7ca988da51bd84a54d2021cf18da67b5e2c7ebcf" -sha512 = "c005e2a91522958a9537827a49ae344e1cb39d66e85492901a86bcc7e322ba8d0a7f1a02c9b9f840c123b4ad97e297355fac98d4822536d1426d1096dd1d73ac" +sha256 = "f2e6127b235c37c06be675a904d6acf08db953ea688d78c42892c6ad3bd194e4" +sha512 = "32feefbc115c34bf6968cb6e9dc15e755698ee90648e5a5d84448917c36a318bd61b401195eb64330e2475e1d098bfb8dee1440d594a68e0797748762bd84ae5" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "7d7c882d50baeb054a754b5766d46f5eed35a4470d887fc8b45121bfc7ac8701" -sha512 = "4b8aad54da50aa44d35f6e5eea87c67bbcedd610650500ffe350c8c8d26f7ee14c49c4c4cc51ebd0ae607459095092625f27a451e52232c575b460334b5a0606" +sha256 = "11afcbff9920f5f1f72b6764d01e59a5faa2c671f0c59f0c9b405778f3708745" +sha512 = "cc4fa3d178559a89d9d6a376e3359b892158d1e73317c5db1f797ebc6b0b57abf2422797648d5b2b494c50cf9360720bc451cc27e15def7d278ba875805ccbf5" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "e9cc9bf3e809c17f7a100f9498056e435eea133bcb0f1abd8833261f3e5ff067" -sha512 = "1917e06807dc5f9f0993fbffbb9a6c8c36ab25a14ba775ffee939aca458ecd52ee796764708381f7f4166665cfcf11a5d47dc756a1e38f291b270678455b3a02" +sha256 = "b5c2e9cc87cefbaef06bbe9978f9bc336da9feee2d51747bc28e10164fc46c39" +sha512 = "3aea6fe0c768b27d5c5cb3adab5e60dc936198f8b677c2cf6c4d57a0460db87eb779e0b577f1240fb2a6bf3ade49919fbffe39b0137bce3242343e6091cc7510" diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit index 86c9c73b7..74811d327 100644 --- a/proposals/http/wit/deps/cli/command.wit +++ b/proposals/http/wit/deps/cli/command.wit @@ -1,4 +1,4 @@ -package wasi:cli; +package wasi:cli@0.2.0-rc-2023-11-10; world command { include reactor; diff --git a/proposals/http/wit/deps/cli/reactor.wit b/proposals/http/wit/deps/cli/reactor.wit index 6bd780e76..eafa2fd49 100644 --- a/proposals/http/wit/deps/cli/reactor.wit +++ b/proposals/http/wit/deps/cli/reactor.wit @@ -1,23 +1,22 @@ -package wasi:cli; +package wasi:cli@0.2.0-rc-2023-11-10; world reactor { - import wasi:clocks/wall-clock; - import wasi:clocks/monotonic-clock; - import wasi:clocks/timezone; - import wasi:filesystem/types; - import wasi:filesystem/preopens; - import wasi:sockets/instance-network; - import wasi:sockets/ip-name-lookup; - import wasi:sockets/network; - import wasi:sockets/tcp-create-socket; - import wasi:sockets/tcp; - import wasi:sockets/udp-create-socket; - import wasi:sockets/udp; - import wasi:random/random; - import wasi:random/insecure; - import wasi:random/insecure-seed; - import wasi:io/poll; - import wasi:io/streams; + import wasi:clocks/wall-clock@0.2.0-rc-2023-11-10; + import wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10; + import wasi:filesystem/types@0.2.0-rc-2023-11-10; + import wasi:filesystem/preopens@0.2.0-rc-2023-11-10; + import wasi:sockets/instance-network@0.2.0-rc-2023-11-10; + import wasi:sockets/ip-name-lookup@0.2.0-rc-2023-11-10; + import wasi:sockets/network@0.2.0-rc-2023-11-10; + import wasi:sockets/tcp-create-socket@0.2.0-rc-2023-11-10; + import wasi:sockets/tcp@0.2.0-rc-2023-11-10; + import wasi:sockets/udp-create-socket@0.2.0-rc-2023-11-10; + import wasi:sockets/udp@0.2.0-rc-2023-11-10; + import wasi:random/random@0.2.0-rc-2023-11-10; + import wasi:random/insecure@0.2.0-rc-2023-11-10; + import wasi:random/insecure-seed@0.2.0-rc-2023-11-10; + import wasi:io/poll@0.2.0-rc-2023-11-10; + import wasi:io/streams@0.2.0-rc-2023-11-10; import environment; import exit; diff --git a/proposals/http/wit/deps/cli/stdio.wit b/proposals/http/wit/deps/cli/stdio.wit index 1bb6c5583..1b653b6e2 100644 --- a/proposals/http/wit/deps/cli/stdio.wit +++ b/proposals/http/wit/deps/cli/stdio.wit @@ -1,17 +1,17 @@ interface stdin { - use wasi:io/streams.{input-stream}; + use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream}; get-stdin: func() -> input-stream; } interface stdout { - use wasi:io/streams.{output-stream}; + use wasi:io/streams@0.2.0-rc-2023-11-10.{output-stream}; get-stdout: func() -> output-stream; } interface stderr { - use wasi:io/streams.{output-stream}; + use wasi:io/streams@0.2.0-rc-2023-11-10.{output-stream}; get-stderr: func() -> output-stream; } diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index afacdbb61..09ef32c36 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -1,3 +1,4 @@ +package wasi:clocks@0.2.0-rc-2023-11-10; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -9,7 +10,7 @@ /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:io/poll.{pollable}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/http/wit/deps/clocks/timezone.wit b/proposals/http/wit/deps/clocks/timezone.wit deleted file mode 100644 index e717e7b8d..000000000 --- a/proposals/http/wit/deps/clocks/timezone.wit +++ /dev/null @@ -1,48 +0,0 @@ -interface timezone { - use wall-clock.{datetime}; - - /// Return information needed to display the given `datetime`. This includes - /// the UTC offset, the time zone name, and a flag indicating whether - /// daylight saving time is active. - /// - /// If the timezone cannot be determined for the given `datetime`, return a - /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight - /// saving time. - display: func(when: datetime) -> timezone-display; - - /// The same as `display`, but only return the UTC offset. - utc-offset: func(when: datetime) -> s32; - - /// Information useful for displaying the timezone of a specific `datetime`. - /// - /// This information may vary within a single `timezone` to reflect daylight - /// saving time adjustments. - record timezone-display { - /// The number of seconds difference between UTC time and the local - /// time of the timezone. - /// - /// The returned value will always be less than 86400 which is the - /// number of seconds in a day (24*60*60). - /// - /// In implementations that do not expose an actual time zone, this - /// should return 0. - utc-offset: s32, - - /// The abbreviated name of the timezone to display to a user. The name - /// `UTC` indicates Coordinated Universal Time. Otherwise, this should - /// reference local standards for the name of the time zone. - /// - /// In implementations that do not expose an actual time zone, this - /// should be the string `UTC`. - /// - /// In time zones that do not have an applicable name, a formatted - /// representation of the UTC offset may be returned, such as `-04:00`. - name: string, - - /// Whether daylight saving time is active. - /// - /// In implementations that do not expose an actual time zone, this - /// should return false. - in-daylight-saving-time: bool, - } -} diff --git a/proposals/http/wit/deps/clocks/wall-clock.wit b/proposals/http/wit/deps/clocks/wall-clock.wit index c39564967..8abb9a0c0 100644 --- a/proposals/http/wit/deps/clocks/wall-clock.wit +++ b/proposals/http/wit/deps/clocks/wall-clock.wit @@ -1,3 +1,4 @@ +package wasi:clocks@0.2.0-rc-2023-11-10; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/http/wit/deps/clocks/world.wit b/proposals/http/wit/deps/clocks/world.wit index 3295ba8d9..8fa080f0e 100644 --- a/proposals/http/wit/deps/clocks/world.wit +++ b/proposals/http/wit/deps/clocks/world.wit @@ -1,7 +1,6 @@ -package wasi:clocks; +package wasi:clocks@0.2.0-rc-2023-11-10; world imports { import monotonic-clock; import wall-clock; - import timezone; } diff --git a/proposals/http/wit/deps/filesystem/preopens.wit b/proposals/http/wit/deps/filesystem/preopens.wit index 3f787ac3f..95ec67843 100644 --- a/proposals/http/wit/deps/filesystem/preopens.wit +++ b/proposals/http/wit/deps/filesystem/preopens.wit @@ -1,3 +1,5 @@ +package wasi:filesystem@0.2.0-rc-2023-11-10; + interface preopens { use types.{descriptor}; diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index 7ac147f66..059722ab8 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -1,3 +1,4 @@ +package wasi:filesystem@0.2.0-rc-2023-11-10; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -23,8 +24,8 @@ /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { - use wasi:io/streams.{input-stream, output-stream, error}; - use wasi:clocks/wall-clock.{datetime}; + use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream, error}; + use wasi:clocks/wall-clock@0.2.0-rc-2023-11-10.{datetime}; /// File size or length of a region within a file. type filesize = u64; @@ -142,29 +143,6 @@ interface types { truncate, } - /// Permissions mode used by `open-at`, `change-file-permissions-at`, and - /// similar. - flags modes { - /// True if the resource is considered readable by the containing - /// filesystem. - readable, - /// True if the resource is considered writable by the containing - /// filesystem. - writable, - /// True if the resource is considered executable by the containing - /// filesystem. This does not apply to directories. - executable, - } - - /// Access type used by `access-at`. - variant access-type { - /// Test for readability, writeability, or executability. - access(modes), - - /// Test whether the path exists. - exists, - } - /// Number of hard links to an inode. type link-count = u64; @@ -538,8 +516,6 @@ interface types { open-flags: open-flags, /// Flags to use for the resulting descriptor. %flags: descriptor-flags, - /// Permissions to use when creating a new file. - modes: modes ) -> result; /// Read the contents of a symbolic link. @@ -588,25 +564,6 @@ interface types { new-path: string, ) -> result<_, error-code>; - /// Check accessibility of a filesystem path. - /// - /// Check whether the given filesystem path names an object which is - /// readable, writable, or executable, or whether it exists. - /// - /// This does not a guarantee that subsequent accesses will succeed, as - /// filesystem permissions may be modified asynchronously by external - /// entities. - /// - /// Note: This is similar to `faccessat` with the `AT_EACCESS` flag in POSIX. - access-at: func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to check. - path: string, - /// The type of check to perform. - %type: access-type - ) -> result<_, error-code>; - /// Unlink a filesystem object that is not a directory. /// /// Return `error-code::is-directory` if the path refers to a directory. @@ -616,40 +573,6 @@ interface types { path: string, ) -> result<_, error-code>; - /// Change the permissions of a filesystem object that is not a directory. - /// - /// Note that the ultimate meanings of these permissions is - /// filesystem-specific. - /// - /// Note: This is similar to `fchmodat` in POSIX. - change-file-permissions-at: func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the filesystem object. - modes: modes, - ) -> result<_, error-code>; - - /// Change the permissions of a directory. - /// - /// Note that the ultimate meanings of these permissions is - /// filesystem-specific. - /// - /// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" - /// flag. `read` on a directory implies readability and searchability, and - /// `execute` is not valid for directories. - /// - /// Note: This is similar to `fchmodat` in POSIX. - change-directory-permissions-at: func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the directory. - modes: modes, - ) -> result<_, error-code>; - /// Test whether two descriptors refer to the same filesystem object. /// /// In POSIX, this corresponds to testing whether the two descriptors have the diff --git a/proposals/http/wit/deps/filesystem/world.wit b/proposals/http/wit/deps/filesystem/world.wit index bd472942d..285e0bae9 100644 --- a/proposals/http/wit/deps/filesystem/world.wit +++ b/proposals/http/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem; +package wasi:filesystem@0.2.0-rc-2023-11-10; world imports { import types; diff --git a/proposals/http/wit/deps/io/error.wit b/proposals/http/wit/deps/io/error.wit new file mode 100644 index 000000000..31918acbb --- /dev/null +++ b/proposals/http/wit/deps/io/error.wit @@ -0,0 +1,34 @@ +package wasi:io@0.2.0-rc-2023-11-10; + + +interface error { + /// A resource which represents some error information. + /// + /// The only method provided by this resource is `to-debug-string`, + /// which provides some human-readable information about the error. + /// + /// In the `wasi:io` package, this resource is returned through the + /// `wasi:io/streams/stream-error` type. + /// + /// To provide more specific error information, other interfaces may + /// provide functions to further "downcast" this error into more specific + /// error information. For example, `error`s returned in streams derived + /// from filesystem types to be described using the filesystem's own + /// error-code type, using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter + /// `borrow` and returns + /// `option`. + /// + /// The set of functions which can "downcast" an `error` into a more + /// concrete type is open. + resource error { + /// Returns a string that is suitable to assist humans in debugging + /// this error. + /// + /// WARNING: The returned string should not be consumed mechanically! + /// It may change across platforms, hosts, or other implementation + /// details. Parsing this string is a major platform-compatibility + /// hazard. + to-debug-string: func() -> string; + } +} diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/io/poll.wit index 0829a7d08..bddde3c19 100644 --- a/proposals/http/wit/deps/io/poll.wit +++ b/proposals/http/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index 8999b28d2..e7e1b689a 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -6,6 +6,7 @@ package wasi:io; /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { + use error.{error}; use poll.{pollable}; /// An error for input-stream and output-stream operations. @@ -20,26 +21,6 @@ interface streams { closed } - /// Contextual error information about the last failure that happened on - /// a read, write, or flush from an `input-stream` or `output-stream`. - /// - /// This type is returned through the `stream-error` type whenever an - /// operation on a stream directly fails or an error is discovered - /// after-the-fact, for example when a write's failure shows up through a - /// later `flush` or `check-write`. - /// - /// Interfaces such as `wasi:filesystem/types` provide functionality to - /// further "downcast" this error into interface-specific error information. - resource error { - /// Returns a string that's suitable to assist humans in debugging this - /// error. - /// - /// The returned string will change across platforms and hosts which - /// means that parsing it, for example, would be a - /// platform-compatibility hazard. - to-debug-string: func() -> string; - } - /// An input bytestream. /// /// `input-stream`s are *non-blocking* to the extent practical on underlying diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit index 05244a965..8243da2ee 100644 --- a/proposals/http/wit/deps/io/world.wit +++ b/proposals/http/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io; +package wasi:io@0.2.0-rc-2023-11-10; world imports { import streams; diff --git a/proposals/http/wit/deps/random/insecure-seed.wit b/proposals/http/wit/deps/random/insecure-seed.wit index 139aed159..f76e87dad 100644 --- a/proposals/http/wit/deps/random/insecure-seed.wit +++ b/proposals/http/wit/deps/random/insecure-seed.wit @@ -1,3 +1,4 @@ +package wasi:random@0.2.0-rc-2023-11-10; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/insecure.wit b/proposals/http/wit/deps/random/insecure.wit index 2ffd223cb..ec7b99737 100644 --- a/proposals/http/wit/deps/random/insecure.wit +++ b/proposals/http/wit/deps/random/insecure.wit @@ -1,3 +1,4 @@ +package wasi:random@0.2.0-rc-2023-11-10; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index 2c3c6a859..7a7dfa27a 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -1,3 +1,4 @@ +package wasi:random@0.2.0-rc-2023-11-10; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit index bb1dd7b59..49e5743b4 100644 --- a/proposals/http/wit/deps/random/world.wit +++ b/proposals/http/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random; +package wasi:random@0.2.0-rc-2023-11-10; world imports { import random; diff --git a/proposals/http/wit/deps/sockets/instance-network.wit b/proposals/http/wit/deps/sockets/instance-network.wit index 14e4479e6..e455d0ff7 100644 --- a/proposals/http/wit/deps/sockets/instance-network.wit +++ b/proposals/http/wit/deps/sockets/instance-network.wit @@ -1,9 +1,9 @@ /// This interface provides a value-export of the default network handle.. interface instance-network { - use network.{network}; + use network.{network}; - /// Get a handle to the default network. - instance-network: func() -> network; + /// Get a handle to the default network. + instance-network: func() -> network; } diff --git a/proposals/http/wit/deps/sockets/ip-name-lookup.wit b/proposals/http/wit/deps/sockets/ip-name-lookup.wit index b51fe05e5..931ccf7e0 100644 --- a/proposals/http/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit/deps/sockets/ip-name-lookup.wit @@ -1,61 +1,51 @@ interface ip-name-lookup { - use wasi:io/poll.{pollable}; - use network.{network, error-code, ip-address, ip-address-family}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use network.{network, error-code, ip-address}; - /// Resolve an internet host name to a list of IP addresses. - /// - /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. - /// - /// # Parameters - /// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted - /// to ASCII using IDNA encoding. - /// - `address-family`: If provided, limit the results to addresses of this specific address family. - /// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime - /// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on - /// systems without an active IPv6 interface. Notes: - /// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. - /// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. - /// - /// This function never blocks. It either immediately fails or immediately returns successfully with a `resolve-address-stream` - /// that can be used to (asynchronously) fetch the results. - /// - /// At the moment, the stream never completes successfully with 0 items. Ie. the first call - /// to `resolve-next-address` never returns `ok(none)`. This may change in the future. - /// - /// # Typical errors - /// - `invalid-name`: `name` is a syntactically invalid domain name. - /// - `invalid-name`: `name` is an IP address. - /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAI_FAMILY) - /// - /// # References: - /// - - /// - - /// - - /// - - resolve-addresses: func(network: borrow, name: string, address-family: option, include-unavailable: bool) -> result; + /// Resolve an internet host name to a list of IP addresses. + /// + /// Unicode domain names are automatically converted to ASCII using IDNA encoding. + /// If the input is an IP address string, the address is parsed and returned + /// as-is without making any external requests. + /// + /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. + /// + /// This function never blocks. It either immediately fails or immediately + /// returns successfully with a `resolve-address-stream` that can be used + /// to (asynchronously) fetch the results. + /// + /// # Typical errors + /// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address. + /// + /// # References: + /// - + /// - + /// - + /// - + resolve-addresses: func(network: borrow, name: string) -> result; - resource resolve-address-stream { - /// Returns the next address from the resolver. - /// - /// This function should be called multiple times. On each call, it will - /// return the next address in connection order preference. If all - /// addresses have been exhausted, this function returns `none`. - /// - /// This function never returns IPv4-mapped IPv6 addresses. - /// - /// # Typical errors - /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) - /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) - /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) - /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) - resolve-next-address: func() -> result, error-code>; + resource resolve-address-stream { + /// Returns the next address from the resolver. + /// + /// This function should be called multiple times. On each call, it will + /// return the next address in connection order preference. If all + /// addresses have been exhausted, this function returns `none`. + /// + /// This function never returns IPv4-mapped IPv6 addresses. + /// + /// # Typical errors + /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) + /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) + /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) + /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) + resolve-next-address: func() -> result, error-code>; - /// Create a `pollable` which will resolve once the stream is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable; - } + /// Create a `pollable` which will resolve once the stream is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } } diff --git a/proposals/http/wit/deps/sockets/network.wit b/proposals/http/wit/deps/sockets/network.wit index e2695954b..6bb07cd6f 100644 --- a/proposals/http/wit/deps/sockets/network.wit +++ b/proposals/http/wit/deps/sockets/network.wit @@ -1,178 +1,147 @@ interface network { - /// An opaque resource that represents access to (a subset of) the network. - /// This enables context-based security for networking. - /// There is no need for this to map 1:1 to a physical network interface. - resource network; + /// An opaque resource that represents access to (a subset of) the network. + /// This enables context-based security for networking. + /// There is no need for this to map 1:1 to a physical network interface. + resource network; - /// Error codes. - /// - /// In theory, every API can return any error code. - /// In practice, API's typically only return the errors documented per API - /// combined with a couple of errors that are always possible: - /// - `unknown` - /// - `access-denied` - /// - `not-supported` - /// - `out-of-memory` - /// - /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - enum error-code { - // ### GENERAL ERRORS ### + /// Error codes. + /// + /// In theory, every API can return any error code. + /// In practice, API's typically only return the errors documented per API + /// combined with a couple of errors that are always possible: + /// - `unknown` + /// - `access-denied` + /// - `not-supported` + /// - `out-of-memory` + /// - `concurrency-conflict` + /// + /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. + enum error-code { + // ### GENERAL ERRORS ### - /// Unknown error - unknown, + /// Unknown error + unknown, - /// Access denied. - /// - /// POSIX equivalent: EACCES, EPERM - access-denied, + /// Access denied. + /// + /// POSIX equivalent: EACCES, EPERM + access-denied, - /// The operation is not supported. - /// - /// POSIX equivalent: EOPNOTSUPP - not-supported, + /// The operation is not supported. + /// + /// POSIX equivalent: EOPNOTSUPP + not-supported, - /// Not enough memory to complete the operation. - /// - /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY - out-of-memory, + /// One of the arguments is invalid. + /// + /// POSIX equivalent: EINVAL + invalid-argument, - /// The operation timed out before it could finish completely. - timeout, + /// Not enough memory to complete the operation. + /// + /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY + out-of-memory, - /// This operation is incompatible with another asynchronous operation that is already in progress. - concurrency-conflict, + /// The operation timed out before it could finish completely. + timeout, - /// Trying to finish an asynchronous operation that: - /// - has not been started yet, or: - /// - was already finished by a previous `finish-*` call. - /// - /// Note: this is scheduled to be removed when `future`s are natively supported. - not-in-progress, + /// This operation is incompatible with another asynchronous operation that is already in progress. + /// + /// POSIX equivalent: EALREADY + concurrency-conflict, - /// The operation has been aborted because it could not be completed immediately. - /// - /// Note: this is scheduled to be removed when `future`s are natively supported. - would-block, + /// Trying to finish an asynchronous operation that: + /// - has not been started yet, or: + /// - was already finished by a previous `finish-*` call. + /// + /// Note: this is scheduled to be removed when `future`s are natively supported. + not-in-progress, + /// The operation has been aborted because it could not be completed immediately. + /// + /// Note: this is scheduled to be removed when `future`s are natively supported. + would-block, - // ### IP ERRORS ### - /// The specified address-family is not supported. - address-family-not-supported, - /// An IPv4 address was passed to an IPv6 resource, or vice versa. - address-family-mismatch, + // ### TCP & UDP SOCKET ERRORS ### - /// The socket address is not a valid remote address. E.g. the IP address is set to INADDR_ANY, or the port is set to 0. - invalid-remote-address, + /// The operation is not valid in the socket's current state. + invalid-state, - /// The operation is only supported on IPv4 resources. - ipv4-only-operation, + /// A new socket resource could not be created because of a system limit. + new-socket-limit, - /// The operation is only supported on IPv6 resources. - ipv6-only-operation, + /// A bind operation failed because the provided address is not an address that the `network` can bind to. + address-not-bindable, + /// A bind operation failed because the provided address is already in use or because there are no ephemeral ports available. + address-in-use, + /// The remote address is not reachable + remote-unreachable, - // ### TCP & UDP SOCKET ERRORS ### - /// A new socket resource could not be created because of a system limit. - new-socket-limit, - - /// The socket is already attached to another network. - already-attached, + // ### TCP SOCKET ERRORS ### - /// The socket is already bound. - already-bound, + /// The connection was forcefully rejected + connection-refused, - /// The socket is already in the Connection state. - already-connected, + /// The connection was reset. + connection-reset, - /// The socket is not bound to any local address. - not-bound, + /// A connection was aborted. + connection-aborted, - /// The socket is not in the Connection state. - not-connected, - /// A bind operation failed because the provided address is not an address that the `network` can bind to. - address-not-bindable, + // ### UDP SOCKET ERRORS ### + datagram-too-large, - /// A bind operation failed because the provided address is already in use. - address-in-use, - /// A bind operation failed because there are no ephemeral ports available. - ephemeral-ports-exhausted, + // ### NAME LOOKUP ERRORS ### - /// The remote address is not reachable - remote-unreachable, - + /// Name does not exist or has no suitable associated IP addresses. + name-unresolvable, - // ### TCP SOCKET ERRORS ### - - /// The socket is already in the Listener state. - already-listening, + /// A temporary failure in name resolution occurred. + temporary-resolver-failure, - /// The socket is already in the Listener state. - not-listening, + /// A permanent failure in name resolution occurred. + permanent-resolver-failure, + } - /// The connection was forcefully rejected - connection-refused, + enum ip-address-family { + /// Similar to `AF_INET` in POSIX. + ipv4, - /// The connection was reset. - connection-reset, - + /// Similar to `AF_INET6` in POSIX. + ipv6, + } - // ### UDP SOCKET ERRORS ### - datagram-too-large, + type ipv4-address = tuple; + type ipv6-address = tuple; + variant ip-address { + ipv4(ipv4-address), + ipv6(ipv6-address), + } - // ### NAME LOOKUP ERRORS ### - - /// The provided name is a syntactically invalid domain name. - invalid-name, + record ipv4-socket-address { + port: u16, // sin_port + address: ipv4-address, // sin_addr + } - /// Name does not exist or has no suitable associated IP addresses. - name-unresolvable, + record ipv6-socket-address { + port: u16, // sin6_port + flow-info: u32, // sin6_flowinfo + address: ipv6-address, // sin6_addr + scope-id: u32, // sin6_scope_id + } - /// A temporary failure in name resolution occurred. - temporary-resolver-failure, - - /// A permanent failure in name resolution occurred. - permanent-resolver-failure, - } - - enum ip-address-family { - /// Similar to `AF_INET` in POSIX. - ipv4, - - /// Similar to `AF_INET6` in POSIX. - ipv6, - } - - type ipv4-address = tuple; - type ipv6-address = tuple; - - variant ip-address { - ipv4(ipv4-address), - ipv6(ipv6-address), - } - - record ipv4-socket-address { - port: u16, // sin_port - address: ipv4-address, // sin_addr - } - - record ipv6-socket-address { - port: u16, // sin6_port - flow-info: u32, // sin6_flowinfo - address: ipv6-address, // sin6_addr - scope-id: u32, // sin6_scope_id - } - - variant ip-socket-address { - ipv4(ipv4-socket-address), - ipv6(ipv6-socket-address), - } + variant ip-socket-address { + ipv4(ipv4-socket-address), + ipv6(ipv6-socket-address), + } } diff --git a/proposals/http/wit/deps/sockets/tcp-create-socket.wit b/proposals/http/wit/deps/sockets/tcp-create-socket.wit index 056bbef33..768a07c85 100644 --- a/proposals/http/wit/deps/sockets/tcp-create-socket.wit +++ b/proposals/http/wit/deps/sockets/tcp-create-socket.wit @@ -1,27 +1,26 @@ interface tcp-create-socket { - use network.{network, error-code, ip-address-family}; - use tcp.{tcp-socket}; + use network.{network, error-code, ip-address-family}; + use tcp.{tcp-socket}; - /// Create a new TCP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. - /// - /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` - /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// - /// # Typical errors - /// - `not-supported`: The host does not support TCP sockets. (EOPNOTSUPP) - /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References - /// - - /// - - /// - - /// - - create-tcp-socket: func(address-family: ip-address-family) -> result; + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` + /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # Typical errors + /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References + /// - + /// - + /// - + /// - + create-tcp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index fea44380d..b01b65e6c 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -1,249 +1,321 @@ interface tcp { - use wasi:io/streams.{input-stream, output-stream}; - use wasi:io/poll.{pollable}; - use network.{network, error-code, ip-socket-address, ip-address-family}; - - enum shutdown-type { - /// Similar to `SHUT_RD` in POSIX. - receive, - - /// Similar to `SHUT_WR` in POSIX. - send, - - /// Similar to `SHUT_RDWR` in POSIX. - both, - } - - - /// A TCP socket handle. - resource tcp-socket { - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will - /// implicitly bind the socket. - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) - /// - `already-bound`: The socket is already bound. (EINVAL) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; - finish-bind: func() -> result<_, error-code>; - - /// Connect to a remote endpoint. - /// - /// On success: - /// - the socket is transitioned into the Connection state - /// - a pair of streams is returned that can be used to read & write to the connection - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) - /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `already-connected`: The socket is already in the Connection state. (EISCONN) - /// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `timeout`: Connection timed out. (ETIMEDOUT) - /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) - /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; - finish-connect: func() -> result, error-code>; - - /// Start listening for new connections. - /// - /// Transitions the socket into the Listener state. - /// - /// Unlike POSIX: - /// - this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - the socket must already be explicitly bound. - /// - /// # Typical `start` errors - /// - `not-bound`: The socket is not bound to any local address. (EDESTADDRREQ) - /// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) - /// - `already-listening`: The socket is already in the Listener state. - /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - `not-in-progress`: A `listen` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-listen: func() -> result<_, error-code>; - finish-listen: func() -> result<_, error-code>; - - /// Accept a new client socket. - /// - /// The returned socket is bound and in the Connection state. - /// - /// On success, this function returns the newly accepted client socket along with - /// a pair of streams that can be used to read & write to the connection. - /// - /// # Typical errors - /// - `not-listening`: Socket is not in the Listener state. (EINVAL) - /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) - /// - /// Host implementations must skip over transient errors returned by the native accept syscall. - /// - /// # References - /// - - /// - - /// - - /// - - accept: func() -> result, error-code>; - - /// Get the bound local address. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - local-address: func() -> result; - - /// Get the bound remote address. - /// - /// # Typical errors - /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - remote-address: func() -> result; - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func() -> ip-address-family; - - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. - /// - `already-bound`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - ipv6-only: func() -> result; - set-ipv6-only: func(value: bool) -> result<_, error-code>; - - /// Hints the desired listen queue size. Implementations are free to ignore this. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - set-listen-backlog-size: func(value: u64) -> result<_, error-code>; - - /// Equivalent to the SO_KEEPALIVE socket option. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - keep-alive: func() -> result; - set-keep-alive: func(value: bool) -> result<_, error-code>; - - /// Equivalent to the TCP_NODELAY socket option. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - no-delay: func() -> result; - set-no-delay: func(value: bool) -> result<_, error-code>; - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `already-listening`: (set) The socket is already in the Listener state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - unicast-hop-limit: func() -> result; - set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `already-connected`: (set) The socket is already in the Connection state. - /// - `already-listening`: (set) The socket is already in the Listener state. - /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - receive-buffer-size: func() -> result; - set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - send-buffer-size: func() -> result; - set-send-buffer-size: func(value: u64) -> result<_, error-code>; - - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable; - - /// Initiate a graceful shutdown. - /// - /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read - /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. - /// Any data still in the receive queue at time of calling `shutdown` will be discarded. - /// - send: the socket is not expecting to send any more data to the peer. All subsequent write - /// operations on the `output-stream` associated with this socket will return an error. - /// - both: same effect as receive & send combined. - /// - /// The shutdown function does not close (drop) the socket. - /// - /// # Typical errors - /// - `not-connected`: The socket is not in the Connection state. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; - } + use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10.{duration}; + use network.{network, error-code, ip-socket-address, ip-address-family}; + + enum shutdown-type { + /// Similar to `SHUT_RD` in POSIX. + receive, + + /// Similar to `SHUT_WR` in POSIX. + send, + + /// Similar to `SHUT_RDWR` in POSIX. + both, + } + + + /// A TCP socket handle. + resource tcp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will + /// implicitly bind the socket. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) + /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address, but the socket has `ipv6-only` enabled. (EINVAL) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// + /// # Typical `finish` errors + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + finish-bind: func() -> result<_, error-code>; + + /// Connect to a remote endpoint. + /// + /// On success: + /// - the socket is transitioned into the Connection state + /// - a pair of streams is returned that can be used to read & write to the connection + /// + /// POSIX mentions: + /// > If connect() fails, the state of the socket is unspecified. Conforming applications should + /// > close the file descriptor and create a new socket before attempting to reconnect. + /// + /// WASI prescribes the following behavior: + /// - If `connect` fails because an input/state validation error, the socket should remain usable. + /// - If a connection was actually attempted but failed, the socket should become unusable for further network communication. + /// Besides `drop`, any method after such a failure may return an error. + /// + /// # Typical `start` errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) + /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address, but the socket has `ipv6-only` enabled. (EINVAL, EADDRNOTAVAIL on Illumos) + /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `invalid-state`: The socket is already in the Connection state. (EISCONN) + /// - `invalid-state`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) + /// + /// # Typical `finish` errors + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + finish-connect: func() -> result, error-code>; + + /// Start listening for new connections. + /// + /// Transitions the socket into the Listener state. + /// + /// Unlike POSIX: + /// - this function is async. This enables interactive WASI hosts to inject permission prompts. + /// - the socket must already be explicitly bound. + /// + /// # Typical `start` errors + /// - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ) + /// - `invalid-state`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) + /// - `invalid-state`: The socket is already in the Listener state. + /// + /// # Typical `finish` errors + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// - `not-in-progress`: A `listen` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-listen: func() -> result<_, error-code>; + finish-listen: func() -> result<_, error-code>; + + /// Accept a new client socket. + /// + /// The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket: + /// - `address-family` + /// - `ipv6-only` + /// - `keep-alive-enabled` + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// - `hop-limit` + /// - `receive-buffer-size` + /// - `send-buffer-size` + /// + /// On success, this function returns the newly accepted client socket along with + /// a pair of streams that can be used to read & write to the connection. + /// + /// # Typical errors + /// - `invalid-state`: Socket is not in the Listener state. (EINVAL) + /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) + /// - `connection-aborted`: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References + /// - + /// - + /// - + /// - + accept: func() -> result, error-code>; + + /// Get the bound local address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func() -> result; + + /// Get the remote address. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func() -> result; + + /// Whether the socket is listening for new connections. + /// + /// Equivalent to the SO_ACCEPTCONN socket option. + is-listening: func() -> bool; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family; + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// # Typical errors + /// - `invalid-state`: (set) The socket is already bound. + /// - `not-supported`: (get/set) `this` socket is an IPv4 socket. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + ipv6-only: func() -> result; + set-ipv6-only: func(value: bool) -> result<_, error-code>; + + /// Hints the desired listen queue size. Implementations are free to ignore this. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// + /// # Typical errors + /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. + /// - `invalid-argument`: (set) The provided value was 0. + /// - `invalid-state`: (set) The socket is already in the Connection state. + set-listen-backlog-size: func(value: u64) -> result<_, error-code>; + + /// Enables or disables keepalive. + /// + /// The keepalive behavior can be adjusted using: + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. + /// + /// Equivalent to the SO_KEEPALIVE socket option. + keep-alive-enabled: func() -> result; + set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; + + /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS) + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + keep-alive-idle-time: func() -> result; + set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; + + /// The time between keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPINTVL socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + keep-alive-interval: func() -> result; + set-keep-alive-interval: func(value: duration) -> result<_, error-code>; + + /// The maximum amount of keepalive packets TCP should send before aborting the connection. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPCNT socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + keep-alive-count: func() -> result; + set-keep-alive-count: func(value: u32) -> result<_, error-code>; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + /// - `invalid-state`: (set) The socket is already in the Connection state. + /// - `invalid-state`: (set) The socket is already in the Listener state. + hop-limit: func() -> result; + set-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + /// - `invalid-state`: (set) The socket is already in the Connection state. + /// - `invalid-state`: (set) The socket is already in the Listener state. + receive-buffer-size: func() -> result; + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + send-buffer-size: func() -> result; + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + + /// Initiate a graceful shutdown. + /// + /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read + /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. + /// Any data still in the receive queue at time of calling `shutdown` will be discarded. + /// - send: the socket is not expecting to send any more data to the peer. All subsequent write + /// operations on the `output-stream` associated with this socket will return an error. + /// - both: same effect as receive & send combined. + /// + /// The shutdown function does not close (drop) the socket. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not in the Connection state. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; + } } diff --git a/proposals/http/wit/deps/sockets/udp-create-socket.wit b/proposals/http/wit/deps/sockets/udp-create-socket.wit index 66f948226..cc58234d8 100644 --- a/proposals/http/wit/deps/sockets/udp-create-socket.wit +++ b/proposals/http/wit/deps/sockets/udp-create-socket.wit @@ -1,27 +1,26 @@ interface udp-create-socket { - use network.{network, error-code, ip-address-family}; - use udp.{udp-socket}; + use network.{network, error-code, ip-address-family}; + use udp.{udp-socket}; - /// Create a new UDP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. - /// - /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` is called, - /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// - /// # Typical errors - /// - `not-supported`: The host does not support UDP sockets. (EOPNOTSUPP) - /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References: - /// - - /// - - /// - - /// - - create-udp-socket: func(address-family: ip-address-family) -> result; + /// Create a new UDP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind` is called, + /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # Typical errors + /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References: + /// - + /// - + /// - + /// - + create-udp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index e20b57e7e..c8dafadfc 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -1,214 +1,277 @@ interface udp { - use wasi:io/poll.{pollable}; - use network.{network, error-code, ip-socket-address, ip-address-family}; - - - record datagram { - data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. - remote-address: ip-socket-address, - - /// Possible future additions: - /// local-address: ip-socket-address, // IP_PKTINFO / IP_RECVDSTADDR / IPV6_PKTINFO - /// local-interface: u32, // IP_PKTINFO / IP_RECVIF - /// ttl: u8, // IP_RECVTTL - /// dscp: u6, // IP_RECVTOS - /// ecn: u2, // IP_RECVTOS - } - - - - /// A UDP socket handle. - resource udp-socket { - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket. - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL) - /// - `already-bound`: The socket is already bound. (EINVAL) - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; - finish-bind: func() -> result<_, error-code>; - - /// Set the destination address. - /// - /// The local-address is updated based on the best network path to `remote-address`. - /// - /// When a destination address is set: - /// - all receive operations will only return datagrams sent from the provided `remote-address`. - /// - the `send` function can only be used to send to this destination. - /// - /// Note that this function does not generate any network traffic and the peer is not aware of this "connection". - /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `already-attached`: The socket is already bound to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `concurrency-conflict`: Another `bind` or `connect` operation is already in progress. (EALREADY) - /// - /// # Typical `finish` errors - /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; - finish-connect: func() -> result<_, error-code>; - - /// Receive messages on the socket. - /// - /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. - /// The returned list may contain fewer elements than requested, but never more. - /// If `max-results` is 0, this function returns successfully with an empty list. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. (EINVAL) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `would-block`: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - receive: func(max-results: u64) -> result, error-code>; - - /// Send messages on the socket. - /// - /// This function attempts to send all provided `datagrams` on the socket without blocking and - /// returns how many messages were actually sent (or queued for sending). - /// - /// This function semantically behaves the same as iterating the `datagrams` list and sequentially - /// sending each individual datagram until either the end of the list has been reached or the first error occurred. - /// If at least one datagram has been sent successfully, this function never returns an error. - /// - /// If the input list is empty, the function returns `ok(0)`. - /// - /// The remote address option is required. To send a message to the "connected" peer, - /// call `remote-address` to get their address. - /// - /// # Typical errors - /// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `already-connected`: The socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. (EISCONN) - /// - `not-bound`: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind. - /// - `remote-unreachable`: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN) - /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) - /// - `would-block`: The send buffer is currently full. (EWOULDBLOCK, EAGAIN) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - send: func(datagrams: list) -> result; - - /// Get the current bound address. - /// - /// # Typical errors - /// - `not-bound`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - local-address: func() -> result; - - /// Get the address set with `connect`. - /// - /// # Typical errors - /// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - remote-address: func() -> result; - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func() -> ip-address-family; - - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket. - /// - `already-bound`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - ipv6-only: func() -> result; - set-ipv6-only: func(value: bool) -> result<_, error-code>; - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - unicast-hop-limit: func() -> result; - set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// Note #1: an implementation may choose to cap or round the buffer size when setting the value. - /// In other words, after setting a value, reading the same setting back may return a different value. - /// - /// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of - /// actual data to be sent/received by the application, because the kernel might also use the buffer space - /// for internal metadata structures. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - receive-buffer-size: func() -> result; - set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - send-buffer-size: func() -> result; - set-send-buffer-size: func(value: u64) -> result<_, error-code>; - - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable; - } + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use network.{network, error-code, ip-socket-address, ip-address-family}; + + /// A received datagram. + record incoming-datagram { + /// The payload. + /// + /// Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. + data: list, + + /// The source address. + /// + /// This field is guaranteed to match the remote address the stream was initialized with, if any. + /// + /// Equivalent to the `src_addr` out parameter of `recvfrom`. + remote-address: ip-socket-address, + } + + /// A datagram to be sent out. + record outgoing-datagram { + /// The payload. + data: list, + + /// The destination address. + /// + /// The requirements on this field depend on how the stream was initialized: + /// - with a remote address: this field must be None or match the stream's remote address exactly. + /// - without a remote address: this field is required. + /// + /// If this value is None, the send operation is equivalent to `send` in POSIX. Otherwise it is equivalent to `sendto`. + remote-address: option, + } + + + + /// A UDP socket handle. + resource udp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the port is zero, the socket will be bound to a random free port. + /// + /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// + /// # Typical `start` errors + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// + /// # Typical `finish` errors + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + finish-bind: func() -> result<_, error-code>; + + /// Set up inbound & outbound communication channels, optionally to a specific peer. + /// + /// This function only changes the local socket configuration and does not generate any network traffic. + /// On success, the `remote-address` of the socket is updated. The `local-address` may be updated as well, + /// based on the best network path to `remote-address`. + /// + /// When a `remote-address` is provided, the returned streams are limited to communicating with that specific peer: + /// - `send` can only be used to send to this destination. + /// - `receive` will only return datagrams sent from the provided `remote-address`. + /// + /// This method may be called multiple times on the same socket to change its association, but + /// only the most recently returned pair of streams will be operational. Implementations may trap if + /// the streams returned by a previous invocation haven't been dropped yet before calling `stream` again. + /// + /// The POSIX equivalent in pseudo-code is: + /// ```text + /// if (was previously connected) { + /// connect(s, AF_UNSPEC) + /// } + /// if (remote_address is Some) { + /// connect(s, remote_address) + /// } + /// ``` + /// + /// Unlike in POSIX, the socket must already be explicitly bound. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-state`: The socket is not bound. + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// + /// # References + /// - + /// - + /// - + /// - + %stream: func(remote-address: option) -> result, error-code>; + + /// Get the current bound address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func() -> result; + + /// Get the address the socket is currently streaming to. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not streaming to a specific remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func() -> result; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family; + + /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. + /// + /// Equivalent to the IPV6_V6ONLY socket option. + /// + /// # Typical errors + /// - `not-supported`: (get/set) `this` socket is an IPv4 socket. + /// - `invalid-state`: (set) The socket is already bound. + /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) + ipv6-only: func() -> result; + set-ipv6-only: func(value: bool) -> result<_, error-code>; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + unicast-hop-limit: func() -> result; + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + receive-buffer-size: func() -> result; + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + send-buffer-size: func() -> result; + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } + + resource incoming-datagram-stream { + /// Receive messages on the socket. + /// + /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. + /// The returned list may contain fewer elements than requested, but never more. + /// + /// This function returns successfully with an empty list when either: + /// - `max-results` is 0, or: + /// - `max-results` is greater than 0, but no results are immediately available. + /// This function never returns `error(would-block)`. + /// + /// # Typical errors + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + receive: func(max-results: u64) -> result, error-code>; + + /// Create a `pollable` which will resolve once the stream is ready to receive again. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } + + resource outgoing-datagram-stream { + /// Check readiness for sending. This function never blocks. + /// + /// Returns the number of datagrams permitted for the next call to `send`, + /// or an error. Calling `send` with more datagrams than this function has + /// permitted will trap. + /// + /// When this function returns ok(0), the `subscribe` pollable will + /// become ready when this function will report at least ok(1), or an + /// error. + /// + /// Never returns `would-block`. + check-send: func() -> result; + + /// Send messages on the socket. + /// + /// This function attempts to send all provided `datagrams` on the socket without blocking and + /// returns how many messages were actually sent (or queued for sending). This function never + /// returns `error(would-block)`. If none of the datagrams were able to be sent, `ok(0)` is returned. + /// + /// This function semantically behaves the same as iterating the `datagrams` list and sequentially + /// sending each individual datagram until either the end of the list has been reached or the first error occurred. + /// If at least one datagram has been sent successfully, this function never returns an error. + /// + /// If the input list is empty, the function returns `ok(0)`. + /// + /// Each call to `send` must be permitted by a preceding `check-send`. Implementations must trap if + /// either `check-send` was not called or `datagrams` contains more items than `check-send` permitted. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `stream`. (EISCONN) + /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + send: func(datagrams: list) -> result; + + /// Create a `pollable` which will resolve once the stream is ready to send again. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } } diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit index 432b0dc99..49ad8d3d9 100644 --- a/proposals/http/wit/deps/sockets/world.wit +++ b/proposals/http/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets; +package wasi:sockets@0.2.0-rc-2023-11-10; world imports { import instance-network; From ca27a51ae1964e9223b3cf536cb985d5b727e64b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 13 Nov 2023 14:11:15 -0800 Subject: [PATCH 1312/1772] update dependencies on clocks, random, cli, and io to @0.2.0-rc-2023-11-10 --- proposals/http/wit/proxy.wit | 13 ++++++------- proposals/http/wit/types.wit | 6 +++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 557ab4597..770e3f88f 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -6,21 +6,20 @@ package wasi:http; /// outgoing HTTP requests. world proxy { /// HTTP proxies have access to time and randomness. - import wasi:clocks/wall-clock; - import wasi:clocks/monotonic-clock; - import wasi:clocks/timezone; - import wasi:random/random; + import wasi:clocks/wall-clock@0.2.0-rc-2023-11-10; + import wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10; + import wasi:random/random@0.2.0-rc-2023-11-10; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout; - import wasi:cli/stderr; + import wasi:cli/stdout@0.2.0-rc-2023-11-10; + import wasi:cli/stderr@0.2.0-rc-2023-11-10; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. - import wasi:cli/stdin; + import wasi:cli/stdin@0.2.0-rc-2023-11-10; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index c43c2e3a1..163d580aa 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -2,9 +2,9 @@ /// HTTP Requests and Responses, both incoming and outgoing, as well as /// their headers, trailers, and bodies. interface types { - use wasi:clocks/monotonic-clock.{duration}; - use wasi:io/streams.{input-stream, output-stream, error as stream-error}; - use wasi:io/poll.{pollable}; + use wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10.{duration}; + use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream, error as stream-error}; + use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; /// This type corresponds to HTTP standard Methods. variant method { From 6ea0962ffd4a2e4e7eaead8c347b76344c3e3db4 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 13 Nov 2023 14:11:58 -0800 Subject: [PATCH 1313/1772] set wasi:http package version to 0.2.0-rc-2023-11-10 --- proposals/http/wit/proxy.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 770e3f88f..453f59051 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,4 +1,4 @@ -package wasi:http; +package wasi:http@0.2.0-rc-2023-11-10; /// The `wasi:http/proxy` world captures a widely-implementable intersection of /// hosts that includes HTTP forward and reverse proxies. Components targeting From 80cf3912c05524035039a3a21edf85e3e6df537e Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 13 Nov 2023 14:20:26 -0800 Subject: [PATCH 1314/1772] the wasi:io/streams/error is canonically wasi:io/error/error now --- proposals/http/wit/types.wit | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 163d580aa..1dd4214cd 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -3,7 +3,8 @@ /// their headers, trailers, and bodies. interface types { use wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10.{duration}; - use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream, error as stream-error}; + use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream}; + use wasi:io/error@0.2.0-rc-2023-11-10.{error as io-error}; use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; /// This type corresponds to HTTP standard Methods. @@ -94,17 +95,18 @@ interface types { field-size: option } - /// Attempts to extract a http-related `error` from the stream `error` + /// Attempts to extract a http-related `error` from the wasi:io `error` /// provided. /// - /// Stream operations which return `stream-error::last-operation-failed` have - /// a payload with more information about the operation that failed. This - /// payload can be passed through to this function to see if there's - /// http-related information about the error to return. + /// Stream operations which return + /// `wasi:io/stream/stream-error::last-operation-failed` have a payload of + /// type `wasi:io/error/error` with more information about the operation + /// that failed. This payload can be passed through to this function to see + /// if there's http-related information about the error to return. /// - /// Note that this function is fallible because not all stream-related errors - /// are http-related errors. - http-error-code: func(err: borrow) -> option; + /// Note that this function is fallible because not all io-errors are + /// http-related errors. + http-error-code: func(err: borrow) -> option; /// This type enumerates the different kinds of errors that may occur when /// setting or appending to a `fields` resource. From 49475f7a9b26d0413573c830ccd098b86fdd3aca Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 13 Nov 2023 14:12:16 -0800 Subject: [PATCH 1315/1772] generate markdown --- proposals/http/proxy.md | 177 ++++++++++++++-------------------------- 1 file changed, 61 insertions(+), 116 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 3011130db..c9fd1033c 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -6,26 +6,26 @@ outgoing HTTP requests.

                              -

                              Import interface wasi:clocks/wall-clock

                              +

                              Import interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10

                              WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                              @@ -66,7 +66,7 @@ also known as Unix Time.
                            • datetime
                            -

                            Import interface wasi:io/poll

                            +

                            Import interface wasi:io/poll@0.2.0-rc-2023-11-10

                            A poll API intended to let users wait for I/O events on multiple handles at once.


                            @@ -116,7 +116,7 @@ being reaedy for I/O.

                            • list<u32>
                            -

                            Import interface wasi:clocks/monotonic-clock

                            +

                            Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

                            WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                            It is intended to be portable at least between Unix-family platforms and @@ -177,72 +177,7 @@ occured.

                            -

                            Import interface wasi:clocks/timezone

                            -
                            -

                            Types

                            -

                            type datetime

                            -

                            datetime

                            -

                            -#### `record timezone-display` -

                            Information useful for displaying the timezone of a specific datetime.

                            -

                            This information may vary within a single timezone to reflect daylight -saving time adjustments.

                            -
                            Record Fields
                            -
                              -
                            • -

                              utc-offset: s32

                              -

                              The number of seconds difference between UTC time and the local -time of the timezone. -

                              The returned value will always be less than 86400 which is the -number of seconds in a day (246060).

                              -

                              In implementations that do not expose an actual time zone, this -should return 0.

                              -
                            • -
                            • -

                              name: string

                              -

                              The abbreviated name of the timezone to display to a user. The name -`UTC` indicates Coordinated Universal Time. Otherwise, this should -reference local standards for the name of the time zone. -

                              In implementations that do not expose an actual time zone, this -should be the string UTC.

                              -

                              In time zones that do not have an applicable name, a formatted -representation of the UTC offset may be returned, such as -04:00.

                              -
                            • -
                            • -

                              in-daylight-saving-time: bool

                              -

                              Whether daylight saving time is active. -

                              In implementations that do not expose an actual time zone, this -should return false.

                              -
                            • -
                            -
                            -

                            Functions

                            -

                            display: func

                            -

                            Return information needed to display the given datetime. This includes -the UTC offset, the time zone name, and a flag indicating whether -daylight saving time is active.

                            -

                            If the timezone cannot be determined for the given datetime, return a -timezone-display for UTC with a utc-offset of 0 and no daylight -saving time.

                            -
                            Params
                            - -
                            Return values
                            - -

                            utc-offset: func

                            -

                            The same as display, but only return the UTC offset.

                            -
                            Params
                            - -
                            Return values
                            -
                              -
                            • s32
                            • -
                            -

                            Import interface wasi:random/random

                            +

                            Import interface wasi:random/random@0.2.0-rc-2023-11-10

                            WASI Random is a random data API.

                            It is intended to be portable at least between Unix-family platforms and Windows.

                            @@ -275,18 +210,41 @@ represented as a u64.

                            • u64
                            -

                            Import interface wasi:io/streams

                            +

                            Import interface wasi:io/error@0.2.0-rc-2023-11-10

                            +
                            +

                            Types

                            +

                            resource error

                            +
                            +

                            Functions

                            +

                            [method]error.to-debug-string: func

                            +

                            Returns a string that is suitable to assist humans in debugging +this error.

                            +

                            WARNING: The returned string should not be consumed mechanically! +It may change across platforms, hosts, or other implementation +details. Parsing this string is a major platform-compatibility +hazard.

                            +
                            Params
                            + +
                            Return values
                            +
                              +
                            • string
                            • +
                            +

                            Import interface wasi:io/streams@0.2.0-rc-2023-11-10

                            WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                            In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


                            Types

                            -

                            type pollable

                            -

                            pollable

                            +

                            type error

                            +

                            error

                            -#### `resource error` -

                            variant stream-error

                            +#### `type pollable` +[`pollable`](#pollable) +

                            +#### `variant stream-error`

                            An error for input-stream and output-stream operations.

                            Variant Cases
                              @@ -306,20 +264,6 @@ future operations.

                              resource output-stream


                              Functions

                              -

                              [method]error.to-debug-string: func

                              -

                              Returns a string that's suitable to assist humans in debugging this -error.

                              -

                              The returned string will change across platforms and hosts which -means that parsing it, for example, would be a -platform-compatibility hazard.

                              -
                              Params
                              - -
                              Return values
                              -
                                -
                              • string
                              • -

                              [method]input-stream.read: func

                              Perform a non-blocking read from the stream.

                              This function returns a list of bytes containing the read data, @@ -590,7 +534,7 @@ is ready for reading, before performing the splice.

                              -

                              Import interface wasi:cli/stdout

                              +

                              Import interface wasi:cli/stdout@0.2.0-rc-2023-11-10


                              Types

                              type output-stream

                              @@ -603,7 +547,7 @@ is ready for reading, before performing the splice.

                              -

                              Import interface wasi:cli/stderr

                              +

                              Import interface wasi:cli/stderr@0.2.0-rc-2023-11-10


                              Types

                              type output-stream

                              @@ -616,7 +560,7 @@ is ready for reading, before performing the splice.

                              -

                              Import interface wasi:cli/stdin

                              +

                              Import interface wasi:cli/stdin@0.2.0-rc-2023-11-10


                              Types

                              type input-stream

                              @@ -629,7 +573,7 @@ is ready for reading, before performing the splice.

                              -

                              Import interface wasi:http/types

                              +

                              Import interface wasi:http/types@0.2.0-rc-2023-11-10

                              This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                              @@ -644,7 +588,7 @@ their headers, trailers, and bodies.

                              #### `type output-stream` [`output-stream`](#output_stream)

                              -#### `type stream-error` +#### `type io-error` [`error`](#error)

                              #### `type pollable` @@ -797,17 +741,18 @@ so they are provided as a list of bytes.


                              Functions

                              http-error-code: func

                              -

                              Attempts to extract a http-related error from the stream error +

                              Attempts to extract a http-related error from the wasi:io error provided.

                              -

                              Stream operations which return stream-error::last-operation-failed have -a payload with more information about the operation that failed. This -payload can be passed through to this function to see if there's -http-related information about the error to return.

                              -

                              Note that this function is fallible because not all stream-related errors -are http-related errors.

                              +

                              Stream operations which return +wasi:io/stream/stream-error::last-operation-failed have a payload of +type wasi:io/error/error with more information about the operation +that failed. This payload can be passed through to this function to see +if there's http-related information about the error to return.

                              +

                              Note that this function is fallible because not all io-errors are +http-related errors.

                              Params
                              Return values
                              -

                              Export interface wasi:http/incoming-handler

                              +

                              Export interface wasi:http/incoming-handler@0.2.0-rc-2023-11-10


                              Types

                              type incoming-request

                              From 9ff30e62e93200f5ccb9df9b153bbb690ecd104b Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 16 Nov 2023 11:26:02 -0600 Subject: [PATCH 1316/1772] Change the portability criteria (#68) --- proposals/http/README.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/proposals/http/README.md b/proposals/http/README.md index f5b1996f9..2ffc1699c 100644 --- a/proposals/http/README.md +++ b/proposals/http/README.md @@ -14,15 +14,10 @@ wasi-http is currently in [Phase 2](https://github.com/WebAssembly/WASI/blob/mai * David Justice * Luke Wagner -### Phase 4 Advancement Criteria +### Portability Criteria for Phase 4 -WASI-http must have at least two complete independent implementations. One -implementation must execute in a browser and may be implemented in terms of the -[Fetch API] using JavaScript. The other implementation must be implemented -in a non-browser WebAssembly runtime and demonstrate embeddability in a -Web server. - -[Fetch API]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API +WASI-http must have at least two complete independent implementations +demonstrating embeddability in a production HTTP server context. ### Introduction From 10149cb732ac0ed5b3cb0844776705a81384fe4b Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 22 Nov 2023 19:17:26 +0100 Subject: [PATCH 1317/1772] Documentation fix (#59) * Update docs after https://github.com/WebAssembly/wasi-io/pull/54 * Fix typo. --- proposals/io/imports.md | 10 +++++----- proposals/io/wit/poll.wit | 2 +- proposals/io/wit/streams.wit | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index 6900a8840..55647e883 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -231,7 +231,7 @@ following pseudo-code:

                              let pollable = this.subscribe();
                               while !contents.is_empty() {
                                 // Wait for the stream to become writable
                              -  poll-one(pollable);
                              +  pollable.block();
                                 let Ok(n) = this.check-write(); // eliding error handling
                                 let len = min(n, contents.len());
                                 let (chunk, rest) = contents.split_at(len);
                              @@ -240,7 +240,7 @@ while !contents.is_empty() {
                               }
                               this.flush();
                               // Wait for completion of `flush`
                              -poll-one(pollable);
                              +pollable.block();
                               // Check for any errors that arose during `flush`
                               let _ = this.check-write();         // eliding error handling
                               
                              @@ -300,7 +300,7 @@ all derived pollables created with this fun

                            [method]output-stream.write-zeroes: func

                            Write zeroes to a stream.

                            -

                            this should be used precisely like write with the exact same +

                            This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of passing a list of bytes, you simply pass the number of zero-bytes that should be written.

                            @@ -323,7 +323,7 @@ the following pseudo-code:

                            let pollable = this.subscribe();
                             while num_zeroes != 0 {
                               // Wait for the stream to become writable
                            -  poll-one(pollable);
                            +  pollable.block();
                               let Ok(n) = this.check-write(); // eliding error handling
                               let len = min(n, num_zeroes);
                               this.write-zeroes(len);         // eliding error handling
                            @@ -331,7 +331,7 @@ while num_zeroes != 0 {
                             }
                             this.flush();
                             // Wait for completion of `flush`
                            -poll-one(pollable);
                            +pollable.block();
                             // Check for any errors that arose during `flush`
                             let _ = this.check-write();         // eliding error handling
                             
                            diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index bddde3c19..81b1cab99 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -3,7 +3,7 @@ package wasi:io@0.2.0-rc-2023-11-10; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { - /// `pollable` epresents a single I/O event which may be ready, or not. + /// `pollable` represents a single I/O event which may be ready, or not. resource pollable { /// Return the readiness of a pollable. This function never blocks. diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index e7e1b689a..f6f7fe0e8 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -131,7 +131,7 @@ interface streams { /// let pollable = this.subscribe(); /// while !contents.is_empty() { /// // Wait for the stream to become writable - /// poll-one(pollable); + /// pollable.block(); /// let Ok(n) = this.check-write(); // eliding error handling /// let len = min(n, contents.len()); /// let (chunk, rest) = contents.split_at(len); @@ -140,7 +140,7 @@ interface streams { /// } /// this.flush(); /// // Wait for completion of `flush` - /// poll-one(pollable); + /// pollable.block(); /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` @@ -178,7 +178,7 @@ interface streams { /// Write zeroes to a stream. /// - /// this should be used precisely like `write` with the exact same + /// This should be used precisely like `write` with the exact same /// preconditions (must use check-write first), but instead of /// passing a list of bytes, you simply pass the number of zero-bytes /// that should be written. @@ -199,7 +199,7 @@ interface streams { /// let pollable = this.subscribe(); /// while num_zeroes != 0 { /// // Wait for the stream to become writable - /// poll-one(pollable); + /// pollable.block(); /// let Ok(n) = this.check-write(); // eliding error handling /// let len = min(n, num_zeroes); /// this.write-zeroes(len); // eliding error handling @@ -207,7 +207,7 @@ interface streams { /// } /// this.flush(); /// // Wait for completion of `flush` - /// poll-one(pollable); + /// pollable.block(); /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` From de66a4409c28acd0f99ff51dda9c2d1762563486 Mon Sep 17 00:00:00 2001 From: Wassim Chegham Date: Mon, 27 Nov 2023 14:28:46 +0100 Subject: [PATCH 1318/1772] docs: fix Posix-compatibility links --- proposals/sockets/Posix-compatibility.md | 67 ++++++++++++------------ 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/proposals/sockets/Posix-compatibility.md b/proposals/sockets/Posix-compatibility.md index ea56793c8..d7f08cb05 100644 --- a/proposals/sockets/Posix-compatibility.md +++ b/proposals/sockets/Posix-compatibility.md @@ -6,11 +6,11 @@ This document provides an overview of the POSIX interface along with common non- ## General ### I/O completion polling (`poll`, `select`, `pselect`, `epoll_*` (non-standard), `kqueue` (non-standard)) -Use [`tcp::subscribe`](tcp)/[`udp::subscribe`](udp) to obtain a `pollable` handle. Then use that to wait for IO events using the [wasi-poll](poll) interface. +Use [`tcp::subscribe`][tcp]/[`udp::subscribe`][udp] to obtain a `pollable` handle. Then use that to wait for IO events using the [wasi-poll][poll] interface. ### Non-blocking mode (`FIONBIO`, `SOCK_NONBLOCK`, `O_NONBLOCK`) All WASI sockets are non-blocking and can not be configured to block. -Blocking behaviour can be recreated in userland (or in wasi-libc) by repeatedly calling [`poll::poll-oneoff`](poll) until the operation is complete. +Blocking behaviour can be recreated in userland (or in wasi-libc) by repeatedly calling [`poll::poll-oneoff`][poll] until the operation is complete. ### TCP urgent data (`sockatmark`, `MSG_OOB`, `SO_OOBINLINE`, `SIOCATMARK`) Out-of-band (OOB) data is currently not included in this proposal. Application-level usage of the TCP "urgent" flag is rare in practice and discouraged in general. Including it in WASI would probably interfere with the ability to use WASI/ComponentModel `stream`s. @@ -31,54 +31,54 @@ Not included in proposal. WASI has no concept of UNIX-style processes. ## Functions ### `socket` -- TCP: [`create-tcp-socket`](tcp-create-socket) -- UDP: [`create-udp-socket`](udp-create-socket) +- TCP: [`create-tcp-socket`][tcp-create-socket] +- UDP: [`create-udp-socket`][udp-create-socket] ### `connect` -- TCP: [`tcp::start-connect`](tcp) & [`tcp::finish-connect`](tcp) -- UDP: [`udp::start-connect`](udp) & [`udp::finish-connect`](udp) +- TCP: [`tcp::start-connect`][tcp] & [`tcp::finish-connect`][tcp] +- UDP: [`udp::start-connect`][udp] & [`udp::finish-connect`][udp] ### `bind` -- TCP: [`tcp::start-bind`](tcp) & [`tcp::finish-bind`](tcp) -- UDP: [`udp::start-bind`](udp) & [`udp::finish-bind`](udp) +- TCP: [`tcp::start-bind`][tcp] & [`tcp::finish-bind`][tcp] +- UDP: [`udp::start-bind`][udp] & [`udp::finish-bind`][udp] ### `listen` -- TCP: [`tcp::start-listen`](tcp) & [`tcp::finish-listen`](tcp). The `backlog` parameter has been split out into a distinct function [`tcp::set-listen-backlog-size`](tcp) ([See #34](https://github.com/WebAssembly/wasi-sockets/issues/34)). +- TCP: [`tcp::start-listen`][tcp] & [`tcp::finish-listen`][tcp]. The `backlog` parameter has been split out into a distinct function [`tcp::set-listen-backlog-size`][tcp] ([See #34](https://github.com/WebAssembly/wasi-sockets/issues/34)). - UDP: N/A ### `accept`, `accept4` (non-standard) -- TCP: [`tcp::accept`](tcp) +- TCP: [`tcp::accept`][tcp] - UDP: N/A -To collect the remote address, call [`tcp::remote-address`](tcp) on the newly accepted client socket. +To collect the remote address, call [`tcp::remote-address`][tcp] on the newly accepted client socket. Some platforms provide an `accept4` variant with additional flags. None of these flags make sense in the context of this proposal. See [SOCK_NONBLOCK](#nonblock) & [SOCK_CLOEXEC](#cloexec). ### `getsockname`, `getpeername` -- TCP: [`tcp::local-address`](tcp) & [`tcp::remote-address`](tcp) -- UDP: [`udp::local-address`](udp) & [`udp::remote-address`](udp) +- TCP: [`tcp::local-address`][tcp] & [`tcp::remote-address`][tcp] +- UDP: [`udp::local-address`][udp] & [`udp::remote-address`][udp] ### `read`, `readv`, `recv`, `recvfrom`, `recvmsg`, `recvmmsg` (non-standard) -TCP sockets can be read using [`streams::(blocking-)read`](streams). UDP sockets can be read using [`udp::receive`](udp). +TCP sockets can be read using [`streams::(blocking-)read`][streams]. UDP sockets can be read using [`udp::receive`][udp]. The various POSIX functions should be implementable on top of these two functions. None of the flags are directly present in WASI Sockets: - `MSG_DONTWAIT`: This is [always the case](#nonblock). -- `MSG_OOB` (TCP): [Not supported](#oob) -- `MSG_OOB` (UDP): N/A +- `MSG_OOB` [TCP]: [Not supported](#oob) +- `MSG_OOB` [udp]: N/A - `MSG_PEEK`: [No direct support](#peek) -- `MSG_TRUNC` (TCP): N/A -- `MSG_TRUNC` (UDP): Not needed, the returned data array always has the exact perfect size. -- `MSG_WAITALL` (TCP): Emulatable in userspace. -- `MSG_WAITALL` (UDP): N/A +- `MSG_TRUNC` [TCP]: N/A +- `MSG_TRUNC` [udp]: Not needed, the returned data array always has the exact perfect size. +- `MSG_WAITALL` [TCP]: Emulatable in userspace. +- `MSG_WAITALL` [udp]: N/A - `MSG_EOR`: N/A (not supported on TCP & UDP sockets) - `MSG_CMSG_CLOEXEC`: N/A (only used on Unix domain sockets) ### `write`, `writev`, `send`, `sendto`, `sendmsg`, `sendmmsg` (non-standard) -TCP sockets can be written to using [`streams::(blocking-)write`](streams). UDP sockets can be written to using [`udp::send`](udp). +TCP sockets can be written to using [`streams::(blocking-)write`][streams]. UDP sockets can be written to using [`udp::send`][udp]. The various POSIX functions should be implementable on top of these two functions. @@ -86,17 +86,17 @@ None of the flags are directly present in WASI Sockets: - `MSG_DONTROUTE`: Not included in proposal at the moment. - `MSG_DONTWAIT`: This is [always the case](#nonblock). - `MSG_NOSIGNAL`: This is [always the case](#sigpipe). -- `MSG_OOB` (TCP): [Not supported](#oob) -- `MSG_OOB` (UDP): N/A +- `MSG_OOB` [TCP]: [Not supported](#oob) +- `MSG_OOB` [udp]: N/A - `MSG_EOR`: N/A (not supported on TCP & UDP sockets) ### `sendfile` (non-standard) -- TCP: Part of the WASI Streams proposal as [`output-stream::forward`](streams) +- TCP: Part of the WASI Streams proposal as [`output-stream::forward`][streams] - UDP: N/A ### `shutdown` -- TCP: [`tcp::shutdown`](tcp) +- TCP: [`tcp::shutdown`][tcp] - UDP: N/A ### `sockatmark` @@ -147,15 +147,15 @@ Columns: | Option | WASI | POSIX | Linux | Windows | MacOS | FreeBSD | JVM | .NET | Rust | Node.js | Go | OpenSSL | nginx | curl | msquic | exim | Notes | |---------------------------------|-----------|--------|--------|---------|---------|---------|-------|--------|-------|---------|-----|----------|-------|-------|--------|-------|-| | SO_ERROR | ⛔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | Not necessary. WIT has (or will have) native support for asynchronous results. | -| SO_DOMAIN | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | [`tcp::address-family`](tcp)
                            [`udp::address-family`](udp)

                            SO_PROTOCOL_INFO on Windows. | +| SO_DOMAIN | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | [`tcp::address-family`][tcp]
                            [`udp::address-family`][udp]

                            SO_PROTOCOL_INFO on Windows. | | SO_TYPE | ✅* | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | * indirectly through the type of the socket resource. | | SO_PROTOCOL | ✅* | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | * indirectly through the type of the socket resource. SO_PROTOCOL_INFO on Windows. | | SO_ACCEPTCONN | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_V6ONLY | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | [`tcp::(set-)ipv6-only`](tcp)
                            [`udp::(set-)ipv6-only`](udp) | +| IPV6_V6ONLY | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | [`tcp::(set-)ipv6-only`][tcp]
                            [`udp::(set-)ipv6-only`][udp] | | IP_HDRINCL | ⛔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Out of scope. Raw sockets only. | | IPV6_HDRINCL | ⛔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Out of scope. Raw sockets only. | -| IP_TTL | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | [`tcp::(set-)unicast-hop-limit`](tcp)
                            [`udp::(set-)unicast-hop-limit`](udp) | -| IPV6_UNICAST_HOPS | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | [`tcp::(set-)unicast-hop-limit`](tcp)
                            [`udp::(set-)unicast-hop-limit`](udp) | +| IP_TTL | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | [`tcp::(set-)unicast-hop-limit`][tcp]
                            [`udp::(set-)unicast-hop-limit`][udp] | +| IPV6_UNICAST_HOPS | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | [`tcp::(set-)unicast-hop-limit`][tcp]
                            [`udp::(set-)unicast-hop-limit`][udp] | | IP_RECVTTL | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IPV6_RECVHOPLIMIT | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | IP_TOS | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | @@ -168,17 +168,17 @@ Columns: | IPV6_DONTFRAG | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | | | IP_MTU_DISCOVER | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | | | IPV6_MTU_DISCOVER | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | | -| SO_RCVBUF | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | [`tcp::(set-)receive-buffer-size`](tcp)
                            [`udp::(set-)receive-buffer-size`](udp) | -| SO_SNDBUF | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | [`tcp::(set-)send-buffer-size`](tcp)
                            [`udp::(set-)send-buffer-size`](udp) | +| SO_RCVBUF | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | [`tcp::(set-)receive-buffer-size`][tcp]
                            [`udp::(set-)receive-buffer-size`][udp] | +| SO_SNDBUF | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | [`tcp::(set-)send-buffer-size`][tcp]
                            [`udp::(set-)send-buffer-size`][udp] | | SO_RCVLOWAT | ❔ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | | SO_SNDLOWAT | ❔ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | | SO_RCVTIMEO | ⛔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | WASI sockets are always non-blocking. Timeouts can be recreated in libc. | | SO_SNDTIMEO | ⛔ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | WASI sockets are always non-blocking. Timeouts can be recreated in libc. | -| SO_KEEPALIVE | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | [`tcp::(set-)keep-alive`](tcp) | +| SO_KEEPALIVE | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | [`tcp::(set-)keep-alive`][tcp] | | TCP_KEEPCNT | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | | TCP_KEEPIDLE | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | TCP_KEEPALIVE on MacOS | | TCP_KEEPINTVL | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | | -| TCP_NODELAY | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | [`tcp::(set-)no-delay`](tcp) | +| TCP_NODELAY | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | [`tcp::(set-)no-delay`][tcp] | | TCP_CORK | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ | TCP_NOPUSH on MacOS & FreeBSD | | SO_LINGER | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | | | SO_OOBINLINE | ⛔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Not supported, see [OOB](#oob) | @@ -599,3 +599,4 @@ Columns: [udp]: https://github.com/WebAssembly/wasi-sockets/blob/main/wit/udp.wit [poll]: https://github.com/WebAssembly/wasi-poll/blob/main/wit/poll.wit [streams]: https://github.com/WebAssembly/wasi-io/blob/main/wit/streams.wit +**** From 366067035e5d14f14429738a933bbbf4ffe78c4e Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Mon, 27 Nov 2023 19:28:17 +0100 Subject: [PATCH 1319/1772] Update Posix-compatibility.md --- proposals/sockets/Posix-compatibility.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/proposals/sockets/Posix-compatibility.md b/proposals/sockets/Posix-compatibility.md index d7f08cb05..4e4f202ae 100644 --- a/proposals/sockets/Posix-compatibility.md +++ b/proposals/sockets/Posix-compatibility.md @@ -66,13 +66,13 @@ The various POSIX functions should be implementable on top of these two function None of the flags are directly present in WASI Sockets: - `MSG_DONTWAIT`: This is [always the case](#nonblock). -- `MSG_OOB` [TCP]: [Not supported](#oob) -- `MSG_OOB` [udp]: N/A +- `MSG_OOB` on TCP sockets: [Not supported](#oob) +- `MSG_OOB` on UDP sockets: N/A - `MSG_PEEK`: [No direct support](#peek) -- `MSG_TRUNC` [TCP]: N/A -- `MSG_TRUNC` [udp]: Not needed, the returned data array always has the exact perfect size. -- `MSG_WAITALL` [TCP]: Emulatable in userspace. -- `MSG_WAITALL` [udp]: N/A +- `MSG_TRUNC on TCP sockets: N/A +- `MSG_TRUNC` on UDP sockets: Not needed, the returned data array always has the exact perfect size. +- `MSG_WAITALL` on TCP sockets: Emulatable in userspace. +- `MSG_WAITALL` on UDP sockets: N/A - `MSG_EOR`: N/A (not supported on TCP & UDP sockets) - `MSG_CMSG_CLOEXEC`: N/A (only used on Unix domain sockets) @@ -86,8 +86,8 @@ None of the flags are directly present in WASI Sockets: - `MSG_DONTROUTE`: Not included in proposal at the moment. - `MSG_DONTWAIT`: This is [always the case](#nonblock). - `MSG_NOSIGNAL`: This is [always the case](#sigpipe). -- `MSG_OOB` [TCP]: [Not supported](#oob) -- `MSG_OOB` [udp]: N/A +- `MSG_OOB` on TCP sockets: [Not supported](#oob) +- `MSG_OOB` on UDP sockets: N/A - `MSG_EOR`: N/A (not supported on TCP & UDP sockets) From 805a31daec6f32a5e220983577f121631d3adb54 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 27 Nov 2023 13:42:18 -0800 Subject: [PATCH 1320/1772] Drop `-ms` suffix for request options This is a leftover artifact from recent refactorings but now that it's using a `duration` type which holds its value in nanoseconds the `-ms` suffix is no longer required. Closes #78 --- proposals/http/wit/types.wit | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 1dd4214cd..62f736529 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -191,7 +191,7 @@ interface types { append: func(name: field-key, value: field-value) -> result<_, header-error>; /// Retrieve the full set of keys and values in the Fields. Like the - /// constructor, the list represents each key-value pair. + /// constructor, the list represents each key-value pair. /// /// The outer list represents each key-value pair in the Fields. Keys /// which have multiple values are represented by multiple entries in this @@ -319,27 +319,27 @@ interface types { constructor(); /// The timeout for the initial connect to the HTTP Server. - connect-timeout-ms: func() -> option; + connect-timeout: func() -> option; /// Set the timeout for the initial connect to the HTTP Server. An error /// return value indicates that this timeout is not supported. - set-connect-timeout-ms: func(ms: option) -> result; + set-connect-timeout: func(ms: option) -> result; /// The timeout for receiving the first byte of the Response body. - first-byte-timeout-ms: func() -> option; + first-byte-timeout: func() -> option; /// Set the timeout for receiving the first byte of the Response body. An /// error return value indicates that this timeout is not supported. - set-first-byte-timeout-ms: func(ms: option) -> result; + set-first-byte-timeout: func(ms: option) -> result; /// The timeout for receiving subsequent chunks of bytes in the Response /// body stream. - between-bytes-timeout-ms: func() -> option; + between-bytes-timeout: func() -> option; /// Set the timeout for receiving subsequent chunks of bytes in the Response /// body stream. An error return value indicates that this timeout is not /// supported. - set-between-bytes-timeout-ms: func(ms: option) -> result; + set-between-bytes-timeout: func(ms: option) -> result; } /// Represents the ability to send an HTTP Response. From 3e529ae077030f95a4d340b3d70b0d05f5b2b857 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 27 Nov 2023 13:47:26 -0800 Subject: [PATCH 1321/1772] Update generated documentation --- proposals/http/proxy.md | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index c9fd1033c..77624d04b 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -1079,73 +1079,73 @@ another component by e.g. outgoing-handler.handle.

                            -

                            [method]request-options.connect-timeout-ms: func

                            +

                            [method]request-options.connect-timeout: func

                            The timeout for the initial connect to the HTTP Server.

                            Params
                            Return values
                            -

                            [method]request-options.set-connect-timeout-ms: func

                            +

                            [method]request-options.set-connect-timeout: func

                            Set the timeout for the initial connect to the HTTP Server. An error return value indicates that this timeout is not supported.

                            Params
                            Return values
                              -
                            • result
                            • +
                            • result
                            -

                            [method]request-options.first-byte-timeout-ms: func

                            +

                            [method]request-options.first-byte-timeout: func

                            The timeout for receiving the first byte of the Response body.

                            Params
                            Return values
                            -

                            [method]request-options.set-first-byte-timeout-ms: func

                            +

                            [method]request-options.set-first-byte-timeout: func

                            Set the timeout for receiving the first byte of the Response body. An error return value indicates that this timeout is not supported.

                            Params
                            Return values
                              -
                            • result
                            • +
                            • result
                            -

                            [method]request-options.between-bytes-timeout-ms: func

                            +

                            [method]request-options.between-bytes-timeout: func

                            The timeout for receiving subsequent chunks of bytes in the Response body stream.

                            Params
                            Return values
                            -

                            [method]request-options.set-between-bytes-timeout-ms: func

                            +

                            [method]request-options.set-between-bytes-timeout: func

                            Set the timeout for receiving subsequent chunks of bytes in the Response body stream. An error return value indicates that this timeout is not supported.

                            Params
                            Return values
                              -
                            • result
                            • +
                            • result

                            [static]response-outparam.set: func

                            Set the value of the response-outparam to either send a response, From 19707e336afa1aa98737649177805e2637681c7c Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Mon, 27 Nov 2023 15:07:15 -0800 Subject: [PATCH 1322/1772] Change `future-trailers.get` to return successfully at most once. --- proposals/http/wit/types.wit | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 1dd4214cd..9c0bfb470 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -437,16 +437,20 @@ interface types { /// The outer `option` represents future readiness. Users can wait on this /// `option` to become `some` using the `subscribe` method. /// - /// The `result` represents that either the HTTP Request or Response body, - /// as well as any trailers, were received successfully, or that an error - /// occured receiving them. The optional `trailers` indicates whether or not - /// trailers were present in the body. + /// The outer `result` is used to retrieve the trailers or error at most + /// once. It will be success on the first call in which the outer option + /// is `some`, and error on subsequent calls. + /// + /// The inner `result` represents that either the HTTP Request or Response + /// body, as well as any trailers, were received successfully, or that an + /// error occured receiving them. The optional `trailers` indicates whether + /// or not trailers were present in the body. /// /// When some `trailers` are returned by this method, the `trailers` /// resource is immutable, and a child. Use of the `set`, `append`, or /// `delete` methods will return an error, and the resource must be /// dropped before the parent `future-trailers` is dropped. - get: func() -> option, error-code>>; + get: func() -> option, error-code>>>; } /// Represents an outgoing HTTP Response. From 19e59deba47d4bfbf91cfa3bf89a4d8fc0c51d4f Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Mon, 27 Nov 2023 15:07:37 -0800 Subject: [PATCH 1323/1772] Regenerate proxy.md --- proposals/http/proxy.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index c9fd1033c..bf2f496a2 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -1244,10 +1244,13 @@ the get method will return some.

                            once the future is ready.

                            The outer option represents future readiness. Users can wait on this option to become some using the subscribe method.

                            -

                            The result represents that either the HTTP Request or Response body, -as well as any trailers, were received successfully, or that an error -occured receiving them. The optional trailers indicates whether or not -trailers were present in the body.

                            +

                            The outer result is used to retrieve the trailers or error at most +once. It will be success on the first call in which the outer option +is some, and error on subsequent calls.

                            +

                            The inner result represents that either the HTTP Request or Response +body, as well as any trailers, were received successfully, or that an +error occured receiving them. The optional trailers indicates whether +or not trailers were present in the body.

                            When some trailers are returned by this method, the trailers resource is immutable, and a child. Use of the set, append, or delete methods will return an error, and the resource must be @@ -1258,7 +1261,7 @@ dropped before the parent future-trailers

                            Return values

                            [constructor]outgoing-response: func

                            Construct an outgoing-response, with a default status-code of 200. From 0ae25804f2a946db2790966edcabb56773dae633 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 28 Nov 2023 07:12:09 -0800 Subject: [PATCH 1324/1772] Update docs --- proposals/http/wit/types.wit | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 62f736529..2a7abf2c8 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -308,9 +308,9 @@ interface types { headers: func() -> headers; } - /// Parameters for making an HTTP Request. Each of these parameters is an - /// optional timeout, with the unit in milliseconds, applicable to the - /// transport layer of the HTTP protocol. + /// Parameters for making an HTTP Request. Each of these parameters is + /// currently an optional timeout applicable to the transport layer of the + /// HTTP protocol. /// /// These timeouts are separate from any the user may use to bound a /// blocking call to `wasi:io/poll.poll`. From edb0b7749e75002a6d0b95758881a8d783a92e52 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Wed, 29 Nov 2023 16:50:18 -0500 Subject: [PATCH 1325/1772] docs: fix language for portability criteria This is to align language in the WASI phase process with all pre-existing WASI repos. https://github.com/WebAssembly/WASI/blob/main/Contributing.md#2-feature-description-available-wasi-subgroup --- proposals/sockets/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 99d5109a1..960b77ee3 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -10,7 +10,7 @@ Phase 2 - Dave Bakker (@badeend) -### Phase 4 Advancement Criteria +### Portability Criteria - At least two independent production implementations. - Implementations available for at least Windows, Linux & MacOS. From 85962d9556a84de5e7c07e83cd593c3d0c237092 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Wed, 29 Nov 2023 16:54:15 -0500 Subject: [PATCH 1326/1772] docs: fix language for portability criteria This is to align language in the WASI phase process with all pre-existing WASI repos. Phase 4 Advancement Criteria was renamed to Portability Criteria in WebAssembly/WASI#549, so rename it in this document. --- proposals/random/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/README.md b/proposals/random/README.md index cca4e5b96..c3a258de2 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -12,7 +12,7 @@ WASI-random is currently in [Phase 2]. - Dan Gohman -### Phase 4 Advancement Criteria +### Portability Criteria WASI random must have host implementations which can pass the testsuite on at least Windows, macOS, and Linux. From eba739304daf2ecf645dcfc479ea1202c40f94fd Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Wed, 29 Nov 2023 16:55:49 -0500 Subject: [PATCH 1327/1772] docs: fix language for portability criteria This is to align language in the WASI phase process with all pre-existing WASI repos. Phase 4 Advancement Criteria was renamed to Portability Criteria in WebAssembly/WASI#549, so rename it in this document. --- proposals/filesystem/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index 0d5800a3a..78a8c6b4c 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -12,7 +12,7 @@ WASI-filesystem is currently in [Phase 2]. - Dan Gohman -### Phase 4 Advancement Criteria +### Portability Criteria WASI filesystem must have host implementations which can pass the testsuite on at least Windows, macOS, and Linux. From d9d32c51eb2dd6cbb35c32950a3742bc222bd3f6 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Wed, 29 Nov 2023 16:56:58 -0500 Subject: [PATCH 1328/1772] docs: fix language for portability criteria (#58) This is to align language in the WASI phase process with all pre-existing WASI repos. Phase 4 Advancement Criteria was renamed to Portability Criteria in WebAssembly/WASI#549, so rename it in this document. --- proposals/clocks/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index d91dd8e2a..650f50a2e 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -12,7 +12,7 @@ WASI-clocks is currently in [Phase 2]. - Dan Gohman -### Phase 4 Advancement Criteria +### Portability Criteria WASI clocks must have host implementations which can pass the testsuite on at least Windows, macOS, and Linux. From 24a98bb28ed7426924d4034dff451020ee4362e3 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Wed, 29 Nov 2023 16:57:04 -0500 Subject: [PATCH 1329/1772] docs: fix language for portability criteria This is to align language in the WASI phase process with all pre-existing WASI repos. Phase 4 Advancement Criteria was renamed to Portability Criteria in WebAssembly/WASI#549, so rename it in this document. --- proposals/cli/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/cli/README.md b/proposals/cli/README.md index 287a5d7e6..e112f6217 100644 --- a/proposals/cli/README.md +++ b/proposals/cli/README.md @@ -12,7 +12,7 @@ wasi-cli is currently in [Phase 1]. - Dan Gohman -### Phase 4 Advancement Criteria +### Portability Criteria WASI CLI must have host implementations which can pass the testsuite on at least Windows, macOS, and Linux. From a1d85c87a12238f856236ff081a764f163720e75 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Wed, 29 Nov 2023 16:59:26 -0500 Subject: [PATCH 1330/1772] docs: fix language for portability criteria This is to align language in the WASI phase process with all pre-existing WASI repos. We're aligning the header text across repos, and we've opted to remove the phase 4 mention to keep proposals consistent. --- proposals/http/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/README.md b/proposals/http/README.md index 2ffc1699c..171ef12c8 100644 --- a/proposals/http/README.md +++ b/proposals/http/README.md @@ -14,7 +14,7 @@ wasi-http is currently in [Phase 2](https://github.com/WebAssembly/WASI/blob/mai * David Justice * Luke Wagner -### Portability Criteria for Phase 4 +### Portability Criteria WASI-http must have at least two complete independent implementations demonstrating embeddability in a production HTTP server context. From 2caac1fd7c542309207f1db69173d7d6d82dd925 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 29 Nov 2023 14:20:12 -0800 Subject: [PATCH 1331/1772] wasi-cli advanced to phase 2 with a consensus vote in 10/5/2023 meeting https://github.com/WebAssembly/WASI/pull/561 https://github.com/WebAssembly/meetings/pull/1400 --- proposals/cli/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/cli/README.md b/proposals/cli/README.md index e112f6217..30f20d0dd 100644 --- a/proposals/cli/README.md +++ b/proposals/cli/README.md @@ -4,9 +4,9 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Current Phase -wasi-cli is currently in [Phase 1]. +wasi-cli is currently in [Phase 2]. -[Phase 1]: https://github.com/WebAssembly/WASI/blob/42fe2a3ca159011b23099c3d10b5b1d9aff2140e/docs/Proposals.md#phase-1---feature-proposal-cg +[Phase 2]: https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-2---proposed-spec-text-available-cg--wg ### Champions From 33976b1105cc473a422e58fe6fe1d431478b954a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 29 Nov 2023 14:38:32 -0800 Subject: [PATCH 1332/1772] Update README.md: fill in Portability Criteria (#61) * Update README.md Phase 4 Advancement Criteria got renamed to Portability Criteria in https://github.com/WebAssembly/WASI/pull/549, so rename it in this document. Also, this document never got the portability criteria filled in, but we have assigned it the same criteria as was filled in for wasi-poll, which got merged with this package in https://github.com/WebAssembly/wasi-io/pull/46 * Update README.md * Update README.md --- proposals/io/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/io/README.md b/proposals/io/README.md index 71e23ceff..c6afab557 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -12,11 +12,11 @@ WASI-io is currently in [Phase 2]. - Dan Gohman -### Phase 4 Advancement Criteria +### Portability Criteria -WASI I/O has not yet proposed its phase-4 advancement criteria. +WASI I/O must have host implementations which can pass the testsuite on at least Windows, macOS, and Linux. -We anticipate it will involve ensuring it works well for streaming files, sockets, and pipes, and is usable from wasi-libc for implementing POSIX APIs. +WASI I/O must have at least two complete independent implementations. ## Table of Contents From c5c48f962cdae6be164e8488b81677b1a15558e0 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 30 Nov 2023 11:27:56 -0800 Subject: [PATCH 1333/1772] wasi-http has advanced to phase 3 --- proposals/http/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/README.md b/proposals/http/README.md index 171ef12c8..54035f7ee 100644 --- a/proposals/http/README.md +++ b/proposals/http/README.md @@ -4,7 +4,7 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Current Phase -wasi-http is currently in [Phase 2](https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-2---proposed-spec-text-available-cg--wg). +wasi-http is currently in [Phase 3](https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-3---implementation-phase-cg--wg) ### Champions From 7513c6bf49759439dd6e8e07974008706487bc0d Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 30 Nov 2023 11:26:25 -0800 Subject: [PATCH 1334/1772] wasi-cli has advanced to phase 3 --- proposals/cli/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/cli/README.md b/proposals/cli/README.md index 30f20d0dd..7df15996a 100644 --- a/proposals/cli/README.md +++ b/proposals/cli/README.md @@ -4,9 +4,9 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Current Phase -wasi-cli is currently in [Phase 2]. +wasi-cli is currently in [Phase 3]. -[Phase 2]: https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-2---proposed-spec-text-available-cg--wg +[Phase 3]: https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-3---implementation-phase-cg--wg ### Champions From 6002bd7dd432547f51e8ae851a0463cffdb5a50d Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 30 Nov 2023 11:24:47 -0800 Subject: [PATCH 1335/1772] wasi-filesystem has advanced to phase 3 --- proposals/filesystem/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index 78a8c6b4c..9780c6c3b 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -4,9 +4,9 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Current Phase -WASI-filesystem is currently in [Phase 2]. +WASI-filesystem is currently in [Phase 3]. -[Phase 2]: https://github.com/WebAssembly/WASI/blob/42fe2a3ca159011b23099c3d10b5b1d9aff2140e/docs/Proposals.md#phase-2---proposed-spec-text-available-cg--wg +[Phase 3]: https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-3---implementation-phase-cg--wg ### Champions From 9d3f05b752b81d079c7504427b5ee5b2cfb0ee09 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 30 Nov 2023 11:21:38 -0800 Subject: [PATCH 1336/1772] wasi-random has advanced to phase 3 --- proposals/random/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/README.md b/proposals/random/README.md index c3a258de2..44fca0824 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -4,9 +4,9 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Current Phase -WASI-random is currently in [Phase 2]. +WASI-random is currently in [Phase 3]. -[Phase 2]: https://github.com/WebAssembly/WASI/blob/42fe2a3ca159011b23099c3d10b5b1d9aff2140e/docs/Proposals.md#phase-2---proposed-spec-text-available-cg--wg +[Phase 3]: https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-3---implementation-phase-cg--wg ### Champions From 141b208a06480b3e40af3644ea42b70f7e65e6fe Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 30 Nov 2023 11:21:03 -0800 Subject: [PATCH 1337/1772] wasi-clocks has advanced to phase 3 --- proposals/clocks/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 650f50a2e..919f6cb7e 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -4,9 +4,9 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Current Phase -WASI-clocks is currently in [Phase 2]. +WASI-clocks is currently in [Phase 3]. -[Phase 2]: https://github.com/WebAssembly/WASI/blob/42fe2a3ca159011b23099c3d10b5b1d9aff2140e/docs/Proposals.md#phase-2---proposed-spec-text-available-cg--wg +[Phase 3]: https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-3---implementation-phase-cg--wg ### Champions From 551d8c42aff4d466ef8a44f5ddffa4fd31c84bf8 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 30 Nov 2023 11:20:18 -0800 Subject: [PATCH 1338/1772] wasi-io has advanced to phase 3 --- proposals/io/README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/proposals/io/README.md b/proposals/io/README.md index c6afab557..999de2a07 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -4,9 +4,9 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Current Phase -WASI-io is currently in [Phase 2]. +WASI I/O is currently in [Phase 3]. -[Phase 2]: https://github.com/WebAssembly/WASI/blob/42fe2a3ca159011b23099c3d10b5b1d9aff2140e/docs/Proposals.md#phase-2---proposed-spec-text-available-cg--wg +[Phase 3]: https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-3---implementation-phase-cg--wg ### Champions @@ -147,11 +147,8 @@ addresses it in a very simple way. ### Stakeholder Interest & Feedback -TODO before entering Phase 3. - -Wasi-io is being proposed to be a dependency of wasi-filesystem and -wasi-sockets, and is expected to be a foundational piece of WASI -preview2. +Wasi-io is a dependency of wasi-filesystem, wasi-sockets, and wasi-http, and +is a foundational piece of WASI Preview 2. ### References & acknowledgements From 6fc282a76bb5f08a38249357536402fcd379c50b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 30 Nov 2023 11:25:49 -0800 Subject: [PATCH 1339/1772] wasi-sockets has advanced to phase 3 --- proposals/sockets/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 960b77ee3..4f94d6229 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -4,7 +4,7 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A ### Current Phase -Phase 2 +[Phase 3](https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-3---implementation-phase-cg--wg) ### Champions From c6f82c46b9cfb69898ca189e0c17db545d3bbb33 Mon Sep 17 00:00:00 2001 From: "Jiaxiao Zhou (Mossaka)" Date: Sat, 21 Oct 2023 00:09:45 -0700 Subject: [PATCH 1340/1772] refactor: use include syntax for wasi:clocks This commit uses `include` syntax to simplify the proxy world by hiding the interfaces from wasi:clock package Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/http/wit/proxy.wit | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 453f59051..47a87954b 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -5,9 +5,8 @@ package wasi:http@0.2.0-rc-2023-11-10; /// this world may concurrently stream in and out any number of incoming and /// outgoing HTTP requests. world proxy { - /// HTTP proxies have access to time and randomness. - import wasi:clocks/wall-clock@0.2.0-rc-2023-11-10; - import wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10; + // HTTP proxies have access to time and randomness. + include wasi:clocks/imports@0.2.0-rc-2023-11-10; import wasi:random/random@0.2.0-rc-2023-11-10; /// Proxies have standard output and error streams which are expected to From 363cb16046aa984f653e428abd7a2a6ffda254b8 Mon Sep 17 00:00:00 2001 From: "Jiaxiao Zhou (Mossaka)" Date: Thu, 30 Nov 2023 11:58:16 -0800 Subject: [PATCH 1341/1772] update proxy.md Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/http/proxy.md | 294 ++++++++++++++++++++-------------------- 1 file changed, 147 insertions(+), 147 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 80d0fd2d2..cf8856da6 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -6,17 +6,17 @@ outgoing HTTP requests.

                          -

                          Import interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10

                          -

                          WASI Wall Clock is a clock API intended to let users query the current -time. The name "wall" makes an analogy to a "clock on the wall", which -is not necessarily monotonic as it may be reset.

                          +

                          Import interface wasi:random/random@0.2.0-rc-2023-11-10

                          +

                          WASI Random is a random data API.

                          It is intended to be portable at least between Unix-family platforms and Windows.

                          -

                          A wall clock is a clock which measures the date and time according to -some external reference.

                          -

                          External references may be reset, so this clock is not necessarily -monotonic, making it unsuitable for measuring elapsed time.

                          -

                          It is intended for reporting the current date and time for humans.


                          -

                          Types

                          -

                          record datetime

                          -

                          A time and date in seconds plus nanoseconds.

                          -
                          Record Fields
                          +

                          Functions

                          +

                          get-random-bytes: func

                          +

                          Return len cryptographically-secure random or pseudo-random bytes.

                          +

                          This function must produce data at least as cryptographically secure and +fast as an adequately seeded cryptographically-secure pseudo-random +number generator (CSPRNG). It must not block, from the perspective of +the calling program, under any circumstances, including on the first +request and on requests for numbers of bytes. The returned data must +always be unpredictable.

                          +

                          This function must always return fresh data. Deterministic environments +must omit this function, rather than implementing it with deterministic +data.

                          +
                          Params
                          +
                          Return values
                          +
                            +
                          • list<u8>
                          • +
                          +

                          get-random-u64: func

                          +

                          Return a cryptographically-secure random or pseudo-random u64 value.

                          +

                          This function returns the same type of data as get-random-bytes, +represented as a u64.

                          +
                          Return values
                          +
                            +
                          • u64
                          • +
                          +

                          Import interface wasi:io/error@0.2.0-rc-2023-11-10

                          +
                          +

                          Types

                          +

                          resource error


                          Functions

                          -

                          now: func

                          -

                          Read the current value of the clock.

                          -

                          This clock is not monotonic, therefore calling this function repeatedly -will not necessarily produce a sequence of non-decreasing values.

                          -

                          The returned timestamps represent the number of seconds since -1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, -also known as Unix Time.

                          -

                          The nanoseconds field of the output is always less than 1000000000.

                          -
                          Return values
                          +

                          [method]error.to-debug-string: func

                          +

                          Returns a string that is suitable to assist humans in debugging +this error.

                          +

                          WARNING: The returned string should not be consumed mechanically! +It may change across platforms, hosts, or other implementation +details. Parsing this string is a major platform-compatibility +hazard.

                          +
                          Params
                          -

                          resolution: func

                          -

                          Query the resolution of the clock.

                          -

                          The nanoseconds field of the output is always less than 1000000000.

                          Return values

                          Import interface wasi:io/poll@0.2.0-rc-2023-11-10

                          A poll API intended to let users wait for I/O events on multiple handles @@ -116,121 +129,6 @@ being reaedy for I/O.

                          • list<u32>
                          -

                          Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

                          -

                          WASI Monotonic Clock is a clock API intended to let users measure elapsed -time.

                          -

                          It is intended to be portable at least between Unix-family platforms and -Windows.

                          -

                          A monotonic clock is a clock which has an unspecified initial value, and -successive reads of the clock will produce non-decreasing values.

                          -

                          It is intended for measuring elapsed time.

                          -
                          -

                          Types

                          -

                          type pollable

                          -

                          pollable

                          -

                          -#### `type instant` -`u64` -

                          An instant in time, in nanoseconds. An instant is relative to an -unspecified initial value, and can only be compared to instances from -the same monotonic-clock. -

                          type duration

                          -

                          u64

                          -

                          A duration of time, in nanoseconds. -


                          -

                          Functions

                          -

                          now: func

                          -

                          Read the current value of the clock.

                          -

                          The clock is monotonic, therefore calling this function repeatedly will -produce a sequence of non-decreasing values.

                          -
                          Return values
                          - -

                          resolution: func

                          -

                          Query the resolution of the clock. Returns the duration of time -corresponding to a clock tick.

                          -
                          Return values
                          - -

                          subscribe-instant: func

                          -

                          Create a pollable which will resolve once the specified instant -occured.

                          -
                          Params
                          - -
                          Return values
                          - -

                          subscribe-duration: func

                          -

                          Create a pollable which will resolve once the given duration has -elapsed, starting at the time at which this function was called. -occured.

                          -
                          Params
                          - -
                          Return values
                          - -

                          Import interface wasi:random/random@0.2.0-rc-2023-11-10

                          -

                          WASI Random is a random data API.

                          -

                          It is intended to be portable at least between Unix-family platforms and -Windows.

                          -
                          -

                          Functions

                          -

                          get-random-bytes: func

                          -

                          Return len cryptographically-secure random or pseudo-random bytes.

                          -

                          This function must produce data at least as cryptographically secure and -fast as an adequately seeded cryptographically-secure pseudo-random -number generator (CSPRNG). It must not block, from the perspective of -the calling program, under any circumstances, including on the first -request and on requests for numbers of bytes. The returned data must -always be unpredictable.

                          -

                          This function must always return fresh data. Deterministic environments -must omit this function, rather than implementing it with deterministic -data.

                          -
                          Params
                          - -
                          Return values
                          -
                            -
                          • list<u8>
                          • -
                          -

                          get-random-u64: func

                          -

                          Return a cryptographically-secure random or pseudo-random u64 value.

                          -

                          This function returns the same type of data as get-random-bytes, -represented as a u64.

                          -
                          Return values
                          -
                            -
                          • u64
                          • -
                          -

                          Import interface wasi:io/error@0.2.0-rc-2023-11-10

                          -
                          -

                          Types

                          -

                          resource error

                          -
                          -

                          Functions

                          -

                          [method]error.to-debug-string: func

                          -

                          Returns a string that is suitable to assist humans in debugging -this error.

                          -

                          WARNING: The returned string should not be consumed mechanically! -It may change across platforms, hosts, or other implementation -details. Parsing this string is a major platform-compatibility -hazard.

                          -
                          Params
                          - -
                          Return values
                          -
                            -
                          • string
                          • -

                          Import interface wasi:io/streams@0.2.0-rc-2023-11-10

                          WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                          @@ -573,6 +471,67 @@ is ready for reading, before performing the splice.

                          +

                          Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

                          +

                          WASI Monotonic Clock is a clock API intended to let users measure elapsed +time.

                          +

                          It is intended to be portable at least between Unix-family platforms and +Windows.

                          +

                          A monotonic clock is a clock which has an unspecified initial value, and +successive reads of the clock will produce non-decreasing values.

                          +

                          It is intended for measuring elapsed time.

                          +
                          +

                          Types

                          +

                          type pollable

                          +

                          pollable

                          +

                          +#### `type instant` +`u64` +

                          An instant in time, in nanoseconds. An instant is relative to an +unspecified initial value, and can only be compared to instances from +the same monotonic-clock. +

                          type duration

                          +

                          u64

                          +

                          A duration of time, in nanoseconds. +


                          +

                          Functions

                          +

                          now: func

                          +

                          Read the current value of the clock.

                          +

                          The clock is monotonic, therefore calling this function repeatedly will +produce a sequence of non-decreasing values.

                          +
                          Return values
                          + +

                          resolution: func

                          +

                          Query the resolution of the clock. Returns the duration of time +corresponding to a clock tick.

                          +
                          Return values
                          + +

                          subscribe-instant: func

                          +

                          Create a pollable which will resolve once the specified instant +occured.

                          +
                          Params
                          + +
                          Return values
                          + +

                          subscribe-duration: func

                          +

                          Create a pollable which will resolve once the given duration has +elapsed, starting at the time at which this function was called. +occured.

                          +
                          Params
                          + +
                          Return values
                          +

                          Import interface wasi:http/types@0.2.0-rc-2023-11-10

                          This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as @@ -1431,6 +1390,47 @@ through the future-incoming-response

                        • result<own<future-incoming-response>, error-code>
                        +

                        Import interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10

                        +

                        WASI Wall Clock is a clock API intended to let users query the current +time. The name "wall" makes an analogy to a "clock on the wall", which +is not necessarily monotonic as it may be reset.

                        +

                        It is intended to be portable at least between Unix-family platforms and +Windows.

                        +

                        A wall clock is a clock which measures the date and time according to +some external reference.

                        +

                        External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time.

                        +

                        It is intended for reporting the current date and time for humans.

                        +
                        +

                        Types

                        +

                        record datetime

                        +

                        A time and date in seconds plus nanoseconds.

                        +
                        Record Fields
                        + +
                        +

                        Functions

                        +

                        now: func

                        +

                        Read the current value of the clock.

                        +

                        This clock is not monotonic, therefore calling this function repeatedly +will not necessarily produce a sequence of non-decreasing values.

                        +

                        The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, +also known as Unix Time.

                        +

                        The nanoseconds field of the output is always less than 1000000000.

                        +
                        Return values
                        + +

                        resolution: func

                        +

                        Query the resolution of the clock.

                        +

                        The nanoseconds field of the output is always less than 1000000000.

                        +
                        Return values
                        +

                        Export interface wasi:http/incoming-handler@0.2.0-rc-2023-11-10


                        Types

                        From 4a35dcb16a4c091fdb3af8b216384160aeab2d0e Mon Sep 17 00:00:00 2001 From: "Jiaxiao Zhou (Mossaka)" Date: Thu, 30 Nov 2023 12:03:45 -0800 Subject: [PATCH 1342/1772] one minor change to the comment Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/http/wit/proxy.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 47a87954b..ee4ff33fc 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -5,7 +5,7 @@ package wasi:http@0.2.0-rc-2023-11-10; /// this world may concurrently stream in and out any number of incoming and /// outgoing HTTP requests. world proxy { - // HTTP proxies have access to time and randomness. + /// HTTP proxies have access to time and randomness. include wasi:clocks/imports@0.2.0-rc-2023-11-10; import wasi:random/random@0.2.0-rc-2023-11-10; From a579ddc94055fad3f7d38ee3d333203eaa83c207 Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Mon, 4 Dec 2023 15:54:39 -0800 Subject: [PATCH 1343/1772] Add `fields.has` (#91) * Revert changes to `fields.get`, and add `fields.has` * Clarify the return value of `fields.get` --------- Co-authored-by: Pat Hickey --- proposals/http/proxy.md | 17 ++++++++++++++++- proposals/http/wit/types.wit | 9 ++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index cf8856da6..1f6941764 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -745,7 +745,10 @@ syntactically invalid, or if a header was forbidden.

                      • result<own<fields>, header-error>

                      [method]fields.get: func

                      -

                      Get all of the values corresponding to a key.

                      +

                      Get all of the values corresponding to a key. If the key is not present +in this fields, an empty list is returned. However, if the key is +present but empty, this is represented by a list with one or more +empty field-values present.

                      Params
                      -

                      Import interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10

                      -

                      WASI Wall Clock is a clock API intended to let users query the current -time. The name "wall" makes an analogy to a "clock on the wall", which -is not necessarily monotonic as it may be reset.

                      -

                      It is intended to be portable at least between Unix-family platforms and -Windows.

                      -

                      A wall clock is a clock which measures the date and time according to -some external reference.

                      -

                      External references may be reset, so this clock is not necessarily -monotonic, making it unsuitable for measuring elapsed time.

                      -

                      It is intended for reporting the current date and time for humans.

                      +

                      Import interface wasi:cli/environment@0.2.0-rc-2023-11-10


                      -

                      Types

                      -

                      record datetime

                      -

                      A time and date in seconds plus nanoseconds.

                      -
                      Record Fields
                      +

                      Functions

                      +

                      get-environment: func

                      +

                      Get the POSIX-style environment variables.

                      +

                      Each environment variable is provided as a pair of string variable names +and string value.

                      +

                      Morally, these are a value import, but until value imports are available +in the component model, this import function should return the same +values each time it is called.

                      +
                      Return values
                      +

                      get-arguments: func

                      +

                      Get the POSIX-style arguments to the program.

                      +
                      Return values
                      +
                        +
                      • list<string>
                      • +
                      +

                      initial-cwd: func

                      +

                      Return a path that programs should use as their initial current working +directory, interpreting . as shorthand for this.

                      +
                      Return values
                      +
                        +
                      • option<string>
                      +

                      Import interface wasi:cli/exit@0.2.0-rc-2023-11-10


                      Functions

                      -

                      now: func

                      -

                      Read the current value of the clock.

                      -

                      This clock is not monotonic, therefore calling this function repeatedly -will not necessarily produce a sequence of non-decreasing values.

                      -

                      The returned timestamps represent the number of seconds since -1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, -also known as Unix Time.

                      -

                      The nanoseconds field of the output is always less than 1000000000.

                      -
                      Return values
                      +

                      exit: func

                      +

                      Exit the current instance and any linked instances.

                      +
                      Params
                      +

                      Import interface wasi:io/error@0.2.0-rc-2023-11-10

                      +
                      +

                      Types

                      +

                      resource error

                      +

                      A resource which represents some error information.

                      +

                      The only method provided by this resource is to-debug-string, +which provides some human-readable information about the error.

                      +

                      In the wasi:io package, this resource is returned through the +wasi:io/streams/stream-error type.

                      +

                      To provide more specific error information, other interfaces may +provide functions to further "downcast" this error into more specific +error information. For example, errors returned in streams derived +from filesystem types to be described using the filesystem's own +error-code type, using the function +wasi:filesystem/types/filesystem-error-code, which takes a parameter +borrow<error> and returns +option<wasi:filesystem/types/error-code>.

                      +

                      The set of functions which can "downcast" an error into a more +concrete type is open.

                      +

                      Functions

                      +

                      [method]error.to-debug-string: func

                      +

                      Returns a string that is suitable to assist humans in debugging +this error.

                      +

                      WARNING: The returned string should not be consumed mechanically! +It may change across platforms, hosts, or other implementation +details. Parsing this string is a major platform-compatibility +hazard.

                      +
                      Params
                      + -

                      resolution: func

                      -

                      Query the resolution of the clock.

                      -

                      The nanoseconds field of the output is always less than 1000000000.

                      Return values

                      Import interface wasi:io/poll@0.2.0-rc-2023-11-10

                      A poll API intended to let users wait for I/O events on multiple handles @@ -84,7 +114,7 @@ at once.


                      Types

                      resource pollable

                      -
                      +

                      pollable represents a single I/O event which may be ready, or not.

                      Functions

                      [method]pollable.ready: func

                      Return the readiness of a pollable. This function never blocks.

                      @@ -128,88 +158,6 @@ being reaedy for I/O.

                      • list<u32>
                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

                      -

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed -time.

                      -

                      It is intended to be portable at least between Unix-family platforms and -Windows.

                      -

                      A monotonic clock is a clock which has an unspecified initial value, and -successive reads of the clock will produce non-decreasing values.

                      -

                      It is intended for measuring elapsed time.

                      -
                      -

                      Types

                      -

                      type pollable

                      -

                      pollable

                      -

                      -#### `type instant` -`u64` -

                      An instant in time, in nanoseconds. An instant is relative to an -unspecified initial value, and can only be compared to instances from -the same monotonic-clock. -

                      type duration

                      -

                      u64

                      -

                      A duration of time, in nanoseconds. -


                      -

                      Functions

                      -

                      now: func

                      -

                      Read the current value of the clock.

                      -

                      The clock is monotonic, therefore calling this function repeatedly will -produce a sequence of non-decreasing values.

                      -
                      Return values
                      - -

                      resolution: func

                      -

                      Query the resolution of the clock. Returns the duration of time -corresponding to a clock tick.

                      -
                      Return values
                      - -

                      subscribe-instant: func

                      -

                      Create a pollable which will resolve once the specified instant -occured.

                      -
                      Params
                      - -
                      Return values
                      - -

                      subscribe-duration: func

                      -

                      Create a pollable which will resolve once the given duration has -elapsed, starting at the time at which this function was called. -occured.

                      -
                      Params
                      - -
                      Return values
                      - -

                      Import interface wasi:io/error@0.2.0-rc-2023-11-10

                      -
                      -

                      Types

                      -

                      resource error

                      -
                      -

                      Functions

                      -

                      [method]error.to-debug-string: func

                      -

                      Returns a string that is suitable to assist humans in debugging -this error.

                      -

                      WARNING: The returned string should not be consumed mechanically! -It may change across platforms, hosts, or other implementation -details. Parsing this string is a major platform-compatibility -hazard.

                      -
                      Params
                      - -
                      Return values
                      -
                        -
                      • string
                      • -

                      Import interface wasi:io/streams@0.2.0-rc-2023-11-10

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      @@ -240,8 +188,21 @@ future operations.

                    resource input-stream

                    +

                    An input bytestream.

                    +

                    input-streams are non-blocking to the extent practical on underlying +platforms. I/O operations always return promptly; if fewer bytes are +promptly available than requested, they return the number of bytes promptly +available, which could even be zero. To wait for data to be available, +use the subscribe function to obtain a pollable which can be polled +for using wasi:io/poll.

                    resource output-stream

                    -
                    +

                    An output bytestream.

                    +

                    output-streams are non-blocking to the extent practical on +underlying platforms. Except where specified otherwise, I/O operations also +always return promptly, after the number of bytes that can be written +promptly, which could even be zero. To wait for the stream to be ready to +accept data, the subscribe function to obtain a pollable which can be +polled for using wasi:io/poll.

                    Functions

                    [method]input-stream.read: func

                    Perform a non-blocking read from the stream.

                    @@ -362,7 +323,7 @@ following pseudo-code:

                    let pollable = this.subscribe();
                     while !contents.is_empty() {
                       // Wait for the stream to become writable
                    -  poll-one(pollable);
                    +  pollable.block();
                       let Ok(n) = this.check-write(); // eliding error handling
                       let len = min(n, contents.len());
                       let (chunk, rest) = contents.split_at(len);
                    @@ -371,7 +332,7 @@ while !contents.is_empty() {
                     }
                     this.flush();
                     // Wait for completion of `flush`
                    -poll-one(pollable);
                    +pollable.block();
                     // Check for any errors that arose during `flush`
                     let _ = this.check-write();         // eliding error handling
                     
                    @@ -431,7 +392,7 @@ all derived pollables created with this fun

                  [method]output-stream.write-zeroes: func

                  Write zeroes to a stream.

                  -

                  this should be used precisely like write with the exact same +

                  This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of passing a list of bytes, you simply pass the number of zero-bytes that should be written.

                  @@ -454,7 +415,7 @@ the following pseudo-code:

                  let pollable = this.subscribe();
                   while num_zeroes != 0 {
                     // Wait for the stream to become writable
                  -  poll-one(pollable);
                  +  pollable.block();
                     let Ok(n) = this.check-write(); // eliding error handling
                     let len = min(n, num_zeroes);
                     this.write-zeroes(len);         // eliding error handling
                  @@ -462,7 +423,7 @@ while num_zeroes != 0 {
                   }
                   this.flush();
                   // Wait for completion of `flush`
                  -poll-one(pollable);
                  +pollable.block();
                   // Check for any errors that arose during `flush`
                   let _ = this.check-write();         // eliding error handling
                   
                  @@ -513,48 +474,250 @@ is ready for reading, before performing the splice.

                  -

                  Import interface wasi:filesystem/types@0.2.0-rc-2023-11-10

                  -

                  WASI filesystem is a filesystem API primarily intended to let users run WASI -programs that access their files on their existing filesystems, without -significant overhead.

                  -

                  It is intended to be roughly portable between Unix-family platforms and -Windows, though it does not hide many of the major differences.

                  -

                  Paths are passed as interface-type strings, meaning they must consist of -a sequence of Unicode Scalar Values (USVs). Some filesystems may contain -paths which are not accessible by this API.

                  -

                  The directory separator in WASI is always the forward-slash (/).

                  -

                  All paths in WASI are relative paths, and are interpreted relative to a -descriptor referring to a base directory. If a path argument to any WASI -function starts with /, or if any step of resolving a path, including -.. and symbolic link steps, reaches a directory outside of the base -directory, or reaches a symlink to an absolute or rooted path in the -underlying filesystem, the function fails with error-code::not-permitted.

                  -

                  For more information about WASI path resolution and sandboxing, see -WASI filesystem path resolution.

                  +

                  Import interface wasi:cli/stdin@0.2.0-rc-2023-11-10


                  Types

                  type input-stream

                  input-stream

                  -#### `type output-stream` -[`output-stream`](#output_stream) -

                  -#### `type error` -[`error`](#error) +---- +

                  Functions

                  +

                  get-stdin: func

                  +
                  Return values
                  + +

                  Import interface wasi:cli/stdout@0.2.0-rc-2023-11-10

                  +
                  +

                  Types

                  +

                  type output-stream

                  +

                  output-stream

                  -#### `type datetime` -[`datetime`](#datetime) +---- +

                  Functions

                  +

                  get-stdout: func

                  +
                  Return values
                  + +

                  Import interface wasi:cli/stderr@0.2.0-rc-2023-11-10

                  +
                  +

                  Types

                  +

                  type output-stream

                  +

                  output-stream

                  -#### `type filesize` -`u64` -

                  File size or length of a region within a file. -

                  enum descriptor-type

                  -

                  The type of a filesystem object referenced by a descriptor.

                  -

                  Note: This was called filetype in earlier versions of WASI.

                  -
                  Enum Cases
                  +---- +

                  Functions

                  +

                  get-stderr: func

                  +
                  Return values
                  +

                  Import interface wasi:cli/terminal-input@0.2.0-rc-2023-11-10

                  +
                  +

                  Types

                  +

                  resource terminal-input

                  +

                  The input side of a terminal.

                  +

                  Import interface wasi:cli/terminal-output@0.2.0-rc-2023-11-10

                  +
                  +

                  Types

                  +

                  resource terminal-output

                  +

                  The output side of a terminal.

                  +

                  Import interface wasi:cli/terminal-stdin@0.2.0-rc-2023-11-10

                  +

                  An interface providing an optional terminal-input for stdin as a +link-time authority.

                  +
                  +

                  Types

                  +

                  type terminal-input

                  +

                  terminal-input

                  +

                  +---- +

                  Functions

                  +

                  get-terminal-stdin: func

                  +

                  If stdin is connected to a terminal, return a terminal-input handle +allowing further interaction with it.

                  +
                  Return values
                  + +

                  Import interface wasi:cli/terminal-stdout@0.2.0-rc-2023-11-10

                  +

                  An interface providing an optional terminal-output for stdout as a +link-time authority.

                  +
                  +

                  Types

                  +

                  type terminal-output

                  +

                  terminal-output

                  +

                  +---- +

                  Functions

                  +

                  get-terminal-stdout: func

                  +

                  If stdout is connected to a terminal, return a terminal-output handle +allowing further interaction with it.

                  +
                  Return values
                  + +

                  Import interface wasi:cli/terminal-stderr@0.2.0-rc-2023-11-10

                  +

                  An interface providing an optional terminal-output for stderr as a +link-time authority.

                  +
                  +

                  Types

                  +

                  type terminal-output

                  +

                  terminal-output

                  +

                  +---- +

                  Functions

                  +

                  get-terminal-stderr: func

                  +

                  If stderr is connected to a terminal, return a terminal-output handle +allowing further interaction with it.

                  +
                  Return values
                  + +

                  Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

                  +

                  WASI Monotonic Clock is a clock API intended to let users measure elapsed +time.

                  +

                  It is intended to be portable at least between Unix-family platforms and +Windows.

                  +

                  A monotonic clock is a clock which has an unspecified initial value, and +successive reads of the clock will produce non-decreasing values.

                  +

                  It is intended for measuring elapsed time.

                  +
                  +

                  Types

                  +

                  type pollable

                  +

                  pollable

                  +

                  +#### `type instant` +`u64` +

                  An instant in time, in nanoseconds. An instant is relative to an +unspecified initial value, and can only be compared to instances from +the same monotonic-clock. +

                  type duration

                  +

                  u64

                  +

                  A duration of time, in nanoseconds. +


                  +

                  Functions

                  +

                  now: func

                  +

                  Read the current value of the clock.

                  +

                  The clock is monotonic, therefore calling this function repeatedly will +produce a sequence of non-decreasing values.

                  +
                  Return values
                  + +

                  resolution: func

                  +

                  Query the resolution of the clock. Returns the duration of time +corresponding to a clock tick.

                  +
                  Return values
                  + +

                  subscribe-instant: func

                  +

                  Create a pollable which will resolve once the specified instant +occured.

                  +
                  Params
                  + +
                  Return values
                  + +

                  subscribe-duration: func

                  +

                  Create a pollable which will resolve once the given duration has +elapsed, starting at the time at which this function was called. +occured.

                  +
                  Params
                  + +
                  Return values
                  + +

                  Import interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10

                  +

                  WASI Wall Clock is a clock API intended to let users query the current +time. The name "wall" makes an analogy to a "clock on the wall", which +is not necessarily monotonic as it may be reset.

                  +

                  It is intended to be portable at least between Unix-family platforms and +Windows.

                  +

                  A wall clock is a clock which measures the date and time according to +some external reference.

                  +

                  External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time.

                  +

                  It is intended for reporting the current date and time for humans.

                  +
                  +

                  Types

                  +

                  record datetime

                  +

                  A time and date in seconds plus nanoseconds.

                  +
                  Record Fields
                  + +
                  +

                  Functions

                  +

                  now: func

                  +

                  Read the current value of the clock.

                  +

                  This clock is not monotonic, therefore calling this function repeatedly +will not necessarily produce a sequence of non-decreasing values.

                  +

                  The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, +also known as Unix Time.

                  +

                  The nanoseconds field of the output is always less than 1000000000.

                  +
                  Return values
                  + +

                  resolution: func

                  +

                  Query the resolution of the clock.

                  +

                  The nanoseconds field of the output is always less than 1000000000.

                  +
                  Return values
                  + +

                  Import interface wasi:filesystem/types@0.2.0-rc-2023-11-10

                  +

                  WASI filesystem is a filesystem API primarily intended to let users run WASI +programs that access their files on their existing filesystems, without +significant overhead.

                  +

                  It is intended to be roughly portable between Unix-family platforms and +Windows, though it does not hide many of the major differences.

                  +

                  Paths are passed as interface-type strings, meaning they must consist of +a sequence of Unicode Scalar Values (USVs). Some filesystems may contain +paths which are not accessible by this API.

                  +

                  The directory separator in WASI is always the forward-slash (/).

                  +

                  All paths in WASI are relative paths, and are interpreted relative to a +descriptor referring to a base directory. If a path argument to any WASI +function starts with /, or if any step of resolving a path, including +.. and symbolic link steps, reaches a directory outside of the base +directory, or reaches a symlink to an absolute or rooted path in the +underlying filesystem, the function fails with error-code::not-permitted.

                  +

                  For more information about WASI path resolution and sandboxing, see +WASI filesystem path resolution.

                  +
                  +

                  Types

                  +

                  type input-stream

                  +

                  input-stream

                  +

                  +#### `type output-stream` +[`output-stream`](#output_stream) +

                  +#### `type error` +[`error`](#error) +

                  +#### `type datetime` +[`datetime`](#datetime) +

                  +#### `type filesize` +`u64` +

                  File size or length of a region within a file. +

                  enum descriptor-type

                  +

                  The type of a filesystem object referenced by a descriptor.

                  +

                  Note: This was called filetype in earlier versions of WASI.

                  +
                  Enum Cases
                  +
                    +
                  • +

                    unknown

                    The type of the descriptor or file is unknown or is different from any of the other types specified.

                  • @@ -943,8 +1106,11 @@ not reuse it thereafter.

                  resource descriptor

                  +

                  A descriptor is a reference to a filesystem object, which may be a file, +directory, named pipe, special file, or other object on which filesystem +calls may be made.

                  resource directory-entry-stream

                  -
                  +

                  A stream of directory entries.

                  Functions

                  [method]descriptor.read-via-stream: func

                  Return a stream for reading from a file, if available.

                  @@ -1408,6 +1574,9 @@ errors are filesystem-related errors.


                  Types

                  resource network

                  +

                  An opaque resource that represents access to (a subset of) the network. +This enables context-based security for networking. +There is no need for this to map 1:1 to a physical network interface.

                  enum error-code

                  Error codes.

                  In theory, every API can return any error code. @@ -1589,7 +1758,7 @@ combined with a couple of errors that are always possible:

                  -

                  Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2023-11-10

                  +

                  Import interface wasi:sockets/udp@0.2.0-rc-2023-11-10


                  Types

                  type pollable

                  @@ -1601,133 +1770,62 @@ combined with a couple of errors that are always possible:

                  #### `type error-code` [`error-code`](#error_code)

                  -#### `type ip-address` -[`ip-address`](#ip_address) +#### `type ip-socket-address` +[`ip-socket-address`](#ip_socket_address)

                  -#### `resource resolve-address-stream` -


                  -

                  Functions

                  -

                  resolve-addresses: func

                  -

                  Resolve an internet host name to a list of IP addresses.

                  -

                  Unicode domain names are automatically converted to ASCII using IDNA encoding. -If the input is an IP address string, the address is parsed and returned -as-is without making any external requests.

                  -

                  See the wasi-socket proposal README.md for a comparison with getaddrinfo.

                  -

                  This function never blocks. It either immediately fails or immediately -returns successfully with a resolve-address-stream that can be used -to (asynchronously) fetch the results.

                  -

                  Typical errors

                  -
                    -
                  • invalid-argument: name is a syntactically invalid domain name or IP address.
                  • -
                  -

                  References:

                  +#### `type ip-address-family` +[`ip-address-family`](#ip_address_family) +

                  +#### `record incoming-datagram` +

                  A received datagram.

                  +
                  Record Fields
                  -
                  Params
                  +

                  record outgoing-datagram

                  +

                  A datagram to be sent out.

                  +
                  Record Fields
                  -
                  Return values
                  - -

                  [method]resolve-address-stream.resolve-next-address: func

                  -

                  Returns the next address from the resolver.

                  -

                  This function should be called multiple times. On each call, it will -return the next address in connection order preference. If all -addresses have been exhausted, this function returns none.

                  -

                  This function never returns IPv4-mapped IPv6 addresses.

                  -

                  Typical errors

                  -
                    -
                  • name-unresolvable: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY)
                  • -
                  • temporary-resolver-failure: A temporary failure in name resolution occurred. (EAI_AGAIN)
                  • -
                  • permanent-resolver-failure: A permanent failure in name resolution occurred. (EAI_FAIL)
                  • -
                  • would-block: A result is not available yet. (EWOULDBLOCK, EAGAIN)
                  • -
                  -
                  Params
                  - -
                  Return values
                  - -

                  [method]resolve-address-stream.subscribe: func

                  -

                  Create a pollable which will resolve once the stream is ready for I/O.

                  -

                  Note: this function is here for WASI Preview2 only. -It's planned to be removed when future is natively supported in Preview3.

                  -
                  Params
                  - -
                  Return values
                  - -

                  Import interface wasi:sockets/tcp@0.2.0-rc-2023-11-10

                  -
                  -

                  Types

                  -

                  type input-stream

                  -

                  input-stream

                  -

                  -#### `type output-stream` -[`output-stream`](#output_stream) -

                  -#### `type pollable` -[`pollable`](#pollable) -

                  -#### `type duration` -[`duration`](#duration) -

                  -#### `type network` -[`network`](#network) -

                  -#### `type error-code` -[`error-code`](#error_code) -

                  -#### `type ip-socket-address` -[`ip-socket-address`](#ip_socket_address) -

                  -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) -

                  -#### `enum shutdown-type` -

                  Enum Cases
                  -
                    -
                  • -

                    receive

                    -

                    Similar to `SHUT_RD` in POSIX. -

                  • -

                    send

                    -

                    Similar to `SHUT_WR` in POSIX. +

                    data: list<u8>

                    +

                    The payload.

                  • -

                    both

                    -

                    Similar to `SHUT_RDWR` in POSIX. +

                    remote-address: option<ip-socket-address>

                    +

                    The destination address. +

                    The requirements on this field depend on how the stream was initialized:

                    +
                      +
                    • with a remote address: this field must be None or match the stream's remote address exactly.
                    • +
                    • without a remote address: this field is required.
                    • +
                    +

                    If this value is None, the send operation is equivalent to send in POSIX. Otherwise it is equivalent to sendto.

                  -

                  resource tcp-socket

                  +

                  resource udp-socket

                  +

                  A UDP socket handle.

                  +

                  resource incoming-datagram-stream

                  +

                  resource outgoing-datagram-stream


                  Functions

                  -

                  [method]tcp-socket.start-bind: func

                  +

                  [method]udp-socket.start-bind: func

                  Bind the socket to a specific network on the provided IP address and port.

                  If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. -If the TCP/UDP port is zero, the socket will be bound to a random free port.

                  -

                  When a socket is not explicitly bound, the first invocation to a listen or connect operation will -implicitly bind the socket.

                  +If the port is zero, the socket will be bound to a random free port.

                  Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                  Typical start errors

                  • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
                  • -
                  • invalid-argument: local-address is not a unicast address. (EINVAL)
                  • -
                  • invalid-argument: local-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL)
                  • invalid-state: The socket is already bound. (EINVAL)

                  Typical finish errors

                  @@ -1747,63 +1845,55 @@ implicitly bind the socket.

                Params
                Return values
                -

                [method]tcp-socket.finish-bind: func

                +

                [method]udp-socket.finish-bind: func

                Params
                Return values
                -

                [method]tcp-socket.start-connect: func

                -

                Connect to a remote endpoint.

                -

                On success:

                -
                  -
                • the socket is transitioned into the Connection state
                • -
                • a pair of streams is returned that can be used to read & write to the connection
                • +
                • result<_, error-code>
                -

                POSIX mentions:

                -
                -

                If connect() fails, the state of the socket is unspecified. Conforming applications should -close the file descriptor and create a new socket before attempting to reconnect.

                -
                -

                WASI prescribes the following behavior:

                +

                [method]udp-socket.stream: func

                +

                Set up inbound & outbound communication channels, optionally to a specific peer.

                +

                This function only changes the local socket configuration and does not generate any network traffic. +On success, the remote-address of the socket is updated. The local-address may be updated as well, +based on the best network path to remote-address.

                +

                When a remote-address is provided, the returned streams are limited to communicating with that specific peer:

                  -
                • If connect fails because an input/state validation error, the socket should remain usable.
                • -
                • If a connection was actually attempted but failed, the socket should become unusable for further network communication. -Besides drop, any method after such a failure may return an error.
                • +
                • send can only be used to send to this destination.
                • +
                • receive will only return datagrams sent from the provided remote-address.
                -

                Typical start errors

                +

                This method may be called multiple times on the same socket to change its association, but +only the most recently returned pair of streams will be operational. Implementations may trap if +the streams returned by a previous invocation haven't been dropped yet before calling stream again.

                +

                The POSIX equivalent in pseudo-code is:

                +
                if (was previously connected) {
                +  connect(s, AF_UNSPEC)
                +}
                +if (remote_address is Some) {
                +  connect(s, remote_address)
                +}
                +
                +

                Unlike in POSIX, the socket must already be explicitly bound.

                +

                Typical errors

                • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
                • -
                • invalid-argument: remote-address is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
                • -
                • invalid-argument: remote-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL, EADDRNOTAVAIL on Illumos)
                • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
                • -
                • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
                • -
                • invalid-argument: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
                • -
                • invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
                • -
                • invalid-state: The socket is already in the Connection state. (EISCONN)
                • -
                • invalid-state: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
                • -
                -

                Typical finish errors

                -
                  -
                • timeout: Connection timed out. (ETIMEDOUT)
                • -
                • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
                • -
                • connection-reset: The connection was reset. (ECONNRESET)
                • -
                • connection-aborted: The connection was aborted. (ECONNABORTED)
                • -
                • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
                • +
                • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
                • +
                • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
                • +
                • invalid-state: The socket is not bound.
                • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
                • -
                • not-in-progress: A connect operation is not in progress.
                • -
                • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
                • +
                • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
                • +
                • connection-refused: The connection was refused. (ECONNREFUSED)

                References

                  @@ -1814,453 +1904,303 @@ Besides drop, any method after such a failure may return an error.<
                Params
                Return values
                -

                [method]tcp-socket.finish-connect: func

                -
                Params
                +

                [method]udp-socket.local-address: func

                +

                Get the current bound address.

                +

                POSIX mentions:

                +
                +

                If the socket has not been bound to a local name, the value +stored in the object pointed to by address is unspecified.

                +
                +

                WASI is stricter and requires local-address to return invalid-state when the socket hasn't been bound yet.

                +

                Typical errors

                  -
                • self: borrow<tcp-socket>
                • +
                • invalid-state: The socket is not bound to any local address.
                -
                Return values
                +

                References

                -

                [method]tcp-socket.start-listen: func

                -

                Start listening for new connections.

                -

                Transitions the socket into the Listener state.

                -

                Unlike POSIX:

                +
                Params
                  -
                • this function is async. This enables interactive WASI hosts to inject permission prompts.
                • -
                • the socket must already be explicitly bound.
                • +
                • self: borrow<udp-socket>
                -

                Typical start errors

                +
                Return values
                  -
                • invalid-state: The socket is not bound to any local address. (EDESTADDRREQ)
                • -
                • invalid-state: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
                • -
                • invalid-state: The socket is already in the Listener state.
                • +
                • result<ip-socket-address, error-code>
                -

                Typical finish errors

                +

                [method]udp-socket.remote-address: func

                +

                Get the address the socket is currently streaming to.

                +

                Typical errors

                  -
                • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
                • -
                • not-in-progress: A listen operation is not in progress.
                • -
                • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
                • +
                • invalid-state: The socket is not streaming to a specific remote address. (ENOTCONN)

                References

                Params
                Return values
                -

                [method]tcp-socket.finish-listen: func

                +

                [method]udp-socket.address-family: func

                +

                Whether this is a IPv4 or IPv6 socket.

                +

                Equivalent to the SO_DOMAIN socket option.

                Params
                Return values
                -

                [method]tcp-socket.accept: func

                -

                Accept a new client socket.

                -

                The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket:

                +

                [method]udp-socket.ipv6-only: func

                +

                Whether IPv4 compatibility (dual-stack) mode is disabled or not.

                +

                Equivalent to the IPV6_V6ONLY socket option.

                +

                Typical errors

                  -
                • address-family
                • -
                • ipv6-only
                • -
                • keep-alive-enabled
                • -
                • keep-alive-idle-time
                • -
                • keep-alive-interval
                • -
                • keep-alive-count
                • -
                • hop-limit
                • -
                • receive-buffer-size
                • -
                • send-buffer-size
                • +
                • not-supported: (get/set) this socket is an IPv4 socket.
                • +
                • invalid-state: (set) The socket is already bound.
                • +
                • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
                -

                On success, this function returns the newly accepted client socket along with -a pair of streams that can be used to read & write to the connection.

                -

                Typical errors

                +
                Params
                  -
                • invalid-state: Socket is not in the Listener state. (EINVAL)
                • -
                • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
                • -
                • connection-aborted: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED)
                • -
                • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
                • +
                • self: borrow<udp-socket>
                -

                References

                +
                Return values
                +

                [method]udp-socket.set-ipv6-only: func

                Params
                Return values
                -

                [method]tcp-socket.local-address: func

                -

                Get the bound local address.

                -

                POSIX mentions:

                -
                -

                If the socket has not been bound to a local name, the value -stored in the object pointed to by address is unspecified.

                -
                -

                WASI is stricter and requires local-address to return invalid-state when the socket hasn't been bound yet.

                +

                [method]udp-socket.unicast-hop-limit: func

                +

                Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                +

                If the provided value is 0, an invalid-argument error is returned.

                Typical errors

                  -
                • invalid-state: The socket is not bound to any local address.
                • +
                • invalid-argument: (set) The TTL value must be 1 or higher.
                -

                References

                +
                Params
                +
                Return values
                + +

                [method]udp-socket.set-unicast-hop-limit: func

                Params
                Return values
                -

                [method]tcp-socket.remote-address: func

                -

                Get the remote address.

                +

                [method]udp-socket.receive-buffer-size: func

                +

                The kernel buffer space reserved for sends/receives on this socket.

                +

                If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

                +

                Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

                Typical errors

                  -
                • invalid-state: The socket is not connected to a remote address. (ENOTCONN)
                • -
                -

                References

                -
                Params
                Return values
                -

                [method]tcp-socket.is-listening: func

                -

                Whether the socket is listening for new connections.

                -

                Equivalent to the SO_ACCEPTCONN socket option.

                +

                [method]udp-socket.set-receive-buffer-size: func

                Params
                Return values
                -

                [method]tcp-socket.address-family: func

                -

                Whether this is a IPv4 or IPv6 socket.

                -

                Equivalent to the SO_DOMAIN socket option.

                +

                [method]udp-socket.send-buffer-size: func

                Params
                Return values
                -

                [method]tcp-socket.ipv6-only: func

                -

                Whether IPv4 compatibility (dual-stack) mode is disabled or not.

                -

                Equivalent to the IPV6_V6ONLY socket option.

                -

                Typical errors

                -
                  -
                • invalid-state: (set) The socket is already bound.
                • -
                • not-supported: (get/set) this socket is an IPv4 socket.
                • -
                • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
                • +
                • result<u64, error-code>
                +

                [method]udp-socket.set-send-buffer-size: func

                Params
                Return values
                -

                [method]tcp-socket.set-ipv6-only: func

                +

                [method]udp-socket.subscribe: func

                +

                Create a pollable which will resolve once the socket is ready for I/O.

                +

                Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

                Params
                Return values
                +

                [method]incoming-datagram-stream.receive: func

                +

                Receive messages on the socket.

                +

                This function attempts to receive up to max-results datagrams on the socket without blocking. +The returned list may contain fewer elements than requested, but never more.

                +

                This function returns successfully with an empty list when either:

                +
                  +
                • max-results is 0, or:
                • +
                • max-results is greater than 0, but no results are immediately available. +This function never returns error(would-block).
                -

                [method]tcp-socket.set-listen-backlog-size: func

                -

                Hints the desired listen queue size. Implementations are free to ignore this.

                -

                If the provided value is 0, an invalid-argument error is returned. -Any other value will never cause an error, but it might be silently clamped and/or rounded.

                Typical errors

                  -
                • not-supported: (set) The platform does not support changing the backlog size after the initial listen.
                • -
                • invalid-argument: (set) The provided value was 0.
                • -
                • invalid-state: (set) The socket is already in the Connection state.
                • +
                • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
                • +
                • connection-refused: The connection was refused. (ECONNREFUSED)
                -
                Params
                +

                References

                -
                Return values
                +
                Params
                -

                [method]tcp-socket.keep-alive-enabled: func

                -

                Enables or disables keepalive.

                -

                The keepalive behavior can be adjusted using:

                +
                Return values
                  -
                • keep-alive-idle-time
                • -
                • keep-alive-interval
                • -
                • keep-alive-count -These properties can be configured while keep-alive-enabled is false, but only come into effect when keep-alive-enabled is true.
                • +
                • result<list<incoming-datagram>, error-code>
                -

                Equivalent to the SO_KEEPALIVE socket option.

                +

                [method]incoming-datagram-stream.subscribe: func

                +

                Create a pollable which will resolve once the stream is ready to receive again.

                +

                Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

                Params
                Return values
                -

                [method]tcp-socket.set-keep-alive-enabled: func

                +

                [method]outgoing-datagram-stream.check-send: func

                +

                Check readiness for sending. This function never blocks.

                +

                Returns the number of datagrams permitted for the next call to send, +or an error. Calling send with more datagrams than this function has +permitted will trap.

                +

                When this function returns ok(0), the subscribe pollable will +become ready when this function will report at least ok(1), or an +error.

                +

                Never returns would-block.

                Params
                Return values
                -

                [method]tcp-socket.keep-alive-idle-time: func

                -

                Amount of time the connection has to be idle before TCP starts sending keepalive packets.

                -

                If the provided value is 0, an invalid-argument error is returned. -Any other value will never cause an error, but it might be silently clamped and/or rounded. -I.e. after setting a value, reading the same setting back may return a different value.

                -

                Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS)

                +

                [method]outgoing-datagram-stream.send: func

                +

                Send messages on the socket.

                +

                This function attempts to send all provided datagrams on the socket without blocking and +returns how many messages were actually sent (or queued for sending). This function never +returns error(would-block). If none of the datagrams were able to be sent, ok(0) is returned.

                +

                This function semantically behaves the same as iterating the datagrams list and sequentially +sending each individual datagram until either the end of the list has been reached or the first error occurred. +If at least one datagram has been sent successfully, this function never returns an error.

                +

                If the input list is empty, the function returns ok(0).

                +

                Each call to send must be permitted by a preceding check-send. Implementations must trap if +either check-send was not called or datagrams contains more items than check-send permitted.

                Typical errors

                  -
                • invalid-argument: (set) The provided value was 0.
                • -
                -
                Params
                -
                  -
                • self: borrow<tcp-socket>
                • +
                • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
                • +
                • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
                • +
                • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
                • +
                • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
                • +
                • invalid-argument: The socket is in "connected" mode and remote-address is some value that does not match the address passed to stream. (EISCONN)
                • +
                • invalid-argument: The socket is not "connected" and no value for remote-address was provided. (EDESTADDRREQ)
                • +
                • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
                • +
                • connection-refused: The connection was refused. (ECONNREFUSED)
                • +
                • datagram-too-large: The datagram is too large. (EMSGSIZE)
                -
                Return values
                +

                References

                -

                [method]tcp-socket.set-keep-alive-idle-time: func

                Params
                Return values
                -

                [method]tcp-socket.keep-alive-interval: func

                -

                The time between keepalive packets.

                -

                If the provided value is 0, an invalid-argument error is returned. -Any other value will never cause an error, but it might be silently clamped and/or rounded. -I.e. after setting a value, reading the same setting back may return a different value.

                -

                Equivalent to the TCP_KEEPINTVL socket option.

                -

                Typical errors

                -
                  -
                • invalid-argument: (set) The provided value was 0.
                • +
                • result<u64, error-code>
                +

                [method]outgoing-datagram-stream.subscribe: func

                +

                Create a pollable which will resolve once the stream is ready to send again.

                +

                Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

                Params
                Return values
                -

                [method]tcp-socket.set-keep-alive-interval: func

                -
                Params
                - -
                Return values
                - -

                [method]tcp-socket.keep-alive-count: func

                -

                The maximum amount of keepalive packets TCP should send before aborting the connection.

                -

                If the provided value is 0, an invalid-argument error is returned. -Any other value will never cause an error, but it might be silently clamped and/or rounded. -I.e. after setting a value, reading the same setting back may return a different value.

                -

                Equivalent to the TCP_KEEPCNT socket option.

                -

                Typical errors

                -
                  -
                • invalid-argument: (set) The provided value was 0.
                • -
                -
                Params
                - -
                Return values
                - -

                [method]tcp-socket.set-keep-alive-count: func

                -
                Params
                - -
                Return values
                - -

                [method]tcp-socket.hop-limit: func

                -

                Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                -

                If the provided value is 0, an invalid-argument error is returned.

                -

                Typical errors

                -
                  -
                • invalid-argument: (set) The TTL value must be 1 or higher.
                • -
                • invalid-state: (set) The socket is already in the Connection state.
                • -
                • invalid-state: (set) The socket is already in the Listener state.
                • -
                -
                Params
                - -
                Return values
                - -

                [method]tcp-socket.set-hop-limit: func

                -
                Params
                - -
                Return values
                - -

                [method]tcp-socket.receive-buffer-size: func

                -

                The kernel buffer space reserved for sends/receives on this socket.

                -

                If the provided value is 0, an invalid-argument error is returned. -Any other value will never cause an error, but it might be silently clamped and/or rounded. -I.e. after setting a value, reading the same setting back may return a different value.

                -

                Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

                -

                Typical errors

                -
                  -
                • invalid-argument: (set) The provided value was 0.
                • -
                • invalid-state: (set) The socket is already in the Connection state.
                • -
                • invalid-state: (set) The socket is already in the Listener state.
                • -
                -
                Params
                - -
                Return values
                - -

                [method]tcp-socket.set-receive-buffer-size: func

                -
                Params
                - -
                Return values
                - -

                [method]tcp-socket.send-buffer-size: func

                -
                Params
                - -
                Return values
                - -

                [method]tcp-socket.set-send-buffer-size: func

                -
                Params
                - -
                Return values
                - -

                [method]tcp-socket.subscribe: func

                -

                Create a pollable which will resolve once the socket is ready for I/O.

                -

                Note: this function is here for WASI Preview2 only. -It's planned to be removed when future is natively supported in Preview3.

                -
                Params
                - -
                Return values
                - -

                [method]tcp-socket.shutdown: func

                -

                Initiate a graceful shutdown.

                -
                  -
                • receive: the socket is not expecting to receive any more data from the peer. All subsequent read -operations on the input-stream associated with this socket will return an End Of Stream indication. -Any data still in the receive queue at time of calling shutdown will be discarded.
                • -
                • send: the socket is not expecting to send any more data to the peer. All subsequent write -operations on the output-stream associated with this socket will return an error.
                • -
                • both: same effect as receive & send combined.
                • -
                -

                The shutdown function does not close (drop) the socket.

                -

                Typical errors

                -
                  -
                • invalid-state: The socket is not in the Connection state. (ENOTCONN)
                • -
                -

                References

                - -
                Params
                - -
                Return values
                - -

                Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2023-11-10

                +

                Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2023-11-10


                Types

                type network

                @@ -2272,24 +2212,24 @@ operations on the output-stream associ #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                -#### `type tcp-socket` -[`tcp-socket`](#tcp_socket) +#### `type udp-socket` +[`udp-socket`](#udp_socket)

                ----

                Functions

                -

                create-tcp-socket: func

                -

                Create a new TCP socket.

                -

                Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX.

                +

                create-udp-socket: func

                +

                Create a new UDP socket.

                +

                Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.

                This function does not require a network capability handle. This is considered to be safe because -at time of creation, the socket is not bound to any network yet. Up to the moment bind/listen/connect -is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                +at time of creation, the socket is not bound to any network yet. Up to the moment bind is called, +the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

                Typical errors

                • not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
                • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
                -

                References

                +

                References:

                Params
                Return values
                -

                Import interface wasi:sockets/udp@0.2.0-rc-2023-11-10

                +

                Import interface wasi:sockets/tcp@0.2.0-rc-2023-11-10


                Types

                -

                type pollable

                -

                pollable

                +

                type input-stream

                +

                input-stream

                +

                +#### `type output-stream` +[`output-stream`](#output_stream) +

                +#### `type pollable` +[`pollable`](#pollable) +

                +#### `type duration` +[`duration`](#duration)

                #### `type network` [`network`](#network) @@ -2322,55 +2271,38 @@ is called, the socket is effectively an in-memory configuration object, unable t #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                -#### `record incoming-datagram` -

                A received datagram.

                -
                Record Fields
                +#### `enum shutdown-type` +
                Enum Cases
                • -

                  data: list<u8>

                  -

                  The payload. -

                  Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes.

                  -
                • -
                • -

                  remote-address: ip-socket-address

                  -

                  The source address. -

                  This field is guaranteed to match the remote address the stream was initialized with, if any.

                  -

                  Equivalent to the src_addr out parameter of recvfrom.

                  +

                  receive

                  +

                  Similar to `SHUT_RD` in POSIX.

                • -
                -

                record outgoing-datagram

                -

                A datagram to be sent out.

                -
                Record Fields
                -
                • -

                  data: list<u8>

                  -

                  The payload. +

                  send

                  +

                  Similar to `SHUT_WR` in POSIX.

                • -

                  remote-address: option<ip-socket-address>

                  -

                  The destination address. -

                  The requirements on this field depend on how the stream was initialized:

                  -
                    -
                  • with a remote address: this field must be None or match the stream's remote address exactly.
                  • -
                  • without a remote address: this field is required.
                  • -
                  -

                  If this value is None, the send operation is equivalent to send in POSIX. Otherwise it is equivalent to sendto.

                  +

                  both

                  +

                  Similar to `SHUT_RDWR` in POSIX.

                -

                resource udp-socket

                -

                resource incoming-datagram-stream

                -

                resource outgoing-datagram-stream

                -
                +

                resource tcp-socket

                +

                A TCP socket handle.

                Functions

                -

                [method]udp-socket.start-bind: func

                +

                [method]tcp-socket.start-bind: func

                Bind the socket to a specific network on the provided IP address and port.

                If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. -If the port is zero, the socket will be bound to a random free port.

                +If the TCP/UDP port is zero, the socket will be bound to a random free port.

                +

                When a socket is not explicitly bound, the first invocation to a listen or connect operation will +implicitly bind the socket.

                Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                Typical start errors

                • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
                • +
                • invalid-argument: local-address is not a unicast address. (EINVAL)
                • +
                • invalid-argument: local-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL)
                • invalid-state: The socket is already bound. (EINVAL)

                Typical finish errors

                @@ -2390,55 +2322,63 @@ If the port is zero, the socket will be bound to a random free port.

              Params
              Return values
              -

              [method]udp-socket.finish-bind: func

              +

              [method]tcp-socket.finish-bind: func

              Params
              Return values
              -

              [method]udp-socket.stream: func

              -

              Set up inbound & outbound communication channels, optionally to a specific peer.

              -

              This function only changes the local socket configuration and does not generate any network traffic. -On success, the remote-address of the socket is updated. The local-address may be updated as well, -based on the best network path to remote-address.

              -

              When a remote-address is provided, the returned streams are limited to communicating with that specific peer:

              +

              [method]tcp-socket.start-connect: func

              +

              Connect to a remote endpoint.

              +

              On success:

                -
              • send can only be used to send to this destination.
              • -
              • receive will only return datagrams sent from the provided remote-address.
              • +
              • the socket is transitioned into the Connection state
              • +
              • a pair of streams is returned that can be used to read & write to the connection
              -

              This method may be called multiple times on the same socket to change its association, but -only the most recently returned pair of streams will be operational. Implementations may trap if -the streams returned by a previous invocation haven't been dropped yet before calling stream again.

              -

              The POSIX equivalent in pseudo-code is:

              -
              if (was previously connected) {
              -  connect(s, AF_UNSPEC)
              -}
              -if (remote_address is Some) {
              -  connect(s, remote_address)
              -}
              -
              -

              Unlike in POSIX, the socket must already be explicitly bound.

              -

              Typical errors

              +

              POSIX mentions:

              +
              +

              If connect() fails, the state of the socket is unspecified. Conforming applications should +close the file descriptor and create a new socket before attempting to reconnect.

              +
              +

              WASI prescribes the following behavior:

              +
                +
              • If connect fails because an input/state validation error, the socket should remain usable.
              • +
              • If a connection was actually attempted but failed, the socket should become unusable for further network communication. +Besides drop, any method after such a failure may return an error.
              • +
              +

              Typical start errors

              • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
              • +
              • invalid-argument: remote-address is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
              • +
              • invalid-argument: remote-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL, EADDRNOTAVAIL on Illumos)
              • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
              • -
              • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
              • -
              • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
              • -
              • invalid-state: The socket is not bound.
              • +
              • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
              • +
              • invalid-argument: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
              • +
              • invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
              • +
              • invalid-state: The socket is already in the Connection state. (EISCONN)
              • +
              • invalid-state: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
              • +
              +

              Typical finish errors

              +
                +
              • timeout: Connection timed out. (ETIMEDOUT)
              • +
              • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
              • +
              • connection-reset: The connection was reset. (ECONNRESET)
              • +
              • connection-aborted: The connection was aborted. (ECONNABORTED)
              • +
              • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
              • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
              • -
              • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
              • -
              • connection-refused: The connection was refused. (ECONNREFUSED)
              • +
              • not-in-progress: A connect operation is not in progress.
              • +
              • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)

              References

                @@ -2449,15 +2389,107 @@ if (remote_address is Some) {
              Params
              Return values
              -

              [method]udp-socket.local-address: func

              -

              Get the current bound address.

              +

              [method]tcp-socket.finish-connect: func

              +
              Params
              + +
              Return values
              + +

              [method]tcp-socket.start-listen: func

              +

              Start listening for new connections.

              +

              Transitions the socket into the Listener state.

              +

              Unlike POSIX:

              +
                +
              • this function is async. This enables interactive WASI hosts to inject permission prompts.
              • +
              • the socket must already be explicitly bound.
              • +
              +

              Typical start errors

              +
                +
              • invalid-state: The socket is not bound to any local address. (EDESTADDRREQ)
              • +
              • invalid-state: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
              • +
              • invalid-state: The socket is already in the Listener state.
              • +
              +

              Typical finish errors

              +
                +
              • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
              • +
              • not-in-progress: A listen operation is not in progress.
              • +
              • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
              • +
              +

              References

              + +
              Params
              + +
              Return values
              + +

              [method]tcp-socket.finish-listen: func

              +
              Params
              + +
              Return values
              + +

              [method]tcp-socket.accept: func

              +

              Accept a new client socket.

              +

              The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket:

              +
                +
              • address-family
              • +
              • ipv6-only
              • +
              • keep-alive-enabled
              • +
              • keep-alive-idle-time
              • +
              • keep-alive-interval
              • +
              • keep-alive-count
              • +
              • hop-limit
              • +
              • receive-buffer-size
              • +
              • send-buffer-size
              • +
              +

              On success, this function returns the newly accepted client socket along with +a pair of streams that can be used to read & write to the connection.

              +

              Typical errors

              +
                +
              • invalid-state: Socket is not in the Listener state. (EINVAL)
              • +
              • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
              • +
              • connection-aborted: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED)
              • +
              • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
              • +
              +

              References

              + +
              Params
              + +
              Return values
              + +

              [method]tcp-socket.local-address: func

              +

              Get the bound local address.

              POSIX mentions:

              If the socket has not been bound to a local name, the value @@ -2470,282 +2502,340 @@ stored in the object pointed to by address is unspecified.

            References

            +
            Params
            + +
            Return values
            + +

            [method]tcp-socket.remote-address: func

            +

            Get the remote address.

            +

            Typical errors

            +
              +
            • invalid-state: The socket is not connected to a remote address. (ENOTCONN)
            • +
            +

            References

            + +
            Params
            + +
            Return values
            + +

            [method]tcp-socket.is-listening: func

            +

            Whether the socket is listening for new connections.

            +

            Equivalent to the SO_ACCEPTCONN socket option.

            +
            Params
            + +
            Return values
            +
              +
            • bool
            • +
            +

            [method]tcp-socket.address-family: func

            +

            Whether this is a IPv4 or IPv6 socket.

            +

            Equivalent to the SO_DOMAIN socket option.

            +
            Params
            + +
            Return values
            + +

            [method]tcp-socket.ipv6-only: func

            +

            Whether IPv4 compatibility (dual-stack) mode is disabled or not.

            +

            Equivalent to the IPV6_V6ONLY socket option.

            +

            Typical errors

            +
              +
            • invalid-state: (set) The socket is already bound.
            • +
            • not-supported: (get/set) this socket is an IPv4 socket.
            • +
            • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
            • +
            +
            Params
            + +
            Return values
            + +

            [method]tcp-socket.set-ipv6-only: func

            +
            Params
            + +
            Return values
            + +

            [method]tcp-socket.set-listen-backlog-size: func

            +

            Hints the desired listen queue size. Implementations are free to ignore this.

            +

            If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded.

            +

            Typical errors

            +
              +
            • not-supported: (set) The platform does not support changing the backlog size after the initial listen.
            • +
            • invalid-argument: (set) The provided value was 0.
            • +
            • invalid-state: (set) The socket is already in the Connection state.
            Params
            Return values
            -

            [method]udp-socket.remote-address: func

            -

            Get the address the socket is currently streaming to.

            -

            Typical errors

            -
              -
            • invalid-state: The socket is not streaming to a specific remote address. (ENOTCONN)
            • +
            • result<_, error-code>
            -

            References

            +

            [method]tcp-socket.keep-alive-enabled: func

            +

            Enables or disables keepalive.

            +

            The keepalive behavior can be adjusted using:

            +

            Equivalent to the SO_KEEPALIVE socket option.

            Params
            Return values
            -

            [method]udp-socket.address-family: func

            -

            Whether this is a IPv4 or IPv6 socket.

            -

            Equivalent to the SO_DOMAIN socket option.

            +

            [method]tcp-socket.set-keep-alive-enabled: func

            Params
            Return values
            -

            [method]udp-socket.ipv6-only: func

            -

            Whether IPv4 compatibility (dual-stack) mode is disabled or not.

            -

            Equivalent to the IPV6_V6ONLY socket option.

            +

            [method]tcp-socket.keep-alive-idle-time: func

            +

            Amount of time the connection has to be idle before TCP starts sending keepalive packets.

            +

            If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

            +

            Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS)

            Typical errors

              -
            • not-supported: (get/set) this socket is an IPv4 socket.
            • -
            • invalid-state: (set) The socket is already bound.
            • -
            • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
            • +
            • invalid-argument: (set) The provided value was 0.
            Params
            Return values
            -

            [method]udp-socket.set-ipv6-only: func

            +

            [method]tcp-socket.set-keep-alive-idle-time: func

            Params
            Return values
            -

            [method]udp-socket.unicast-hop-limit: func

            -

            Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

            -

            If the provided value is 0, an invalid-argument error is returned.

            +

            [method]tcp-socket.keep-alive-interval: func

            +

            The time between keepalive packets.

            +

            If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

            +

            Equivalent to the TCP_KEEPINTVL socket option.

            Typical errors

              -
            • invalid-argument: (set) The TTL value must be 1 or higher.
            • +
            • invalid-argument: (set) The provided value was 0.
            Params
            Return values
            -

            [method]udp-socket.set-unicast-hop-limit: func

            +

            [method]tcp-socket.set-keep-alive-interval: func

            Params
            Return values
            -

            [method]udp-socket.receive-buffer-size: func

            -

            The kernel buffer space reserved for sends/receives on this socket.

            +

            [method]tcp-socket.keep-alive-count: func

            +

            The maximum amount of keepalive packets TCP should send before aborting the connection.

            If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. I.e. after setting a value, reading the same setting back may return a different value.

            -

            Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

            +

            Equivalent to the TCP_KEEPCNT socket option.

            Typical errors

            • invalid-argument: (set) The provided value was 0.
            Params
            Return values
            -

            [method]udp-socket.set-receive-buffer-size: func

            +

            [method]tcp-socket.set-keep-alive-count: func

            Params
            Return values
            -

            [method]udp-socket.send-buffer-size: func

            -
            Params
            - -
            Return values
            +

            [method]tcp-socket.hop-limit: func

            +

            Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

            +

            If the provided value is 0, an invalid-argument error is returned.

            +

            Typical errors

              -
            • result<u64, error-code>
            • +
            • invalid-argument: (set) The TTL value must be 1 or higher.
            • +
            • invalid-state: (set) The socket is already in the Connection state.
            • +
            • invalid-state: (set) The socket is already in the Listener state.
            -

            [method]udp-socket.set-send-buffer-size: func

            Params
            Return values
            -

            [method]udp-socket.subscribe: func

            -

            Create a pollable which will resolve once the socket is ready for I/O.

            -

            Note: this function is here for WASI Preview2 only. -It's planned to be removed when future is natively supported in Preview3.

            +

            [method]tcp-socket.set-hop-limit: func

            Params
            Return values
            -

            [method]incoming-datagram-stream.receive: func

            -

            Receive messages on the socket.

            -

            This function attempts to receive up to max-results datagrams on the socket without blocking. -The returned list may contain fewer elements than requested, but never more.

            -

            This function returns successfully with an empty list when either:

            +

            [method]tcp-socket.receive-buffer-size: func

            +

            The kernel buffer space reserved for sends/receives on this socket.

            +

            If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

            +

            Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

            +

            Typical errors

              -
            • max-results is 0, or:
            • -
            • max-results is greater than 0, but no results are immediately available. -This function never returns error(would-block).
            • +
            • invalid-argument: (set) The provided value was 0.
            • +
            • invalid-state: (set) The socket is already in the Connection state.
            • +
            • invalid-state: (set) The socket is already in the Listener state.
            -

            Typical errors

            +
            Params
              -
            • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
            • -
            • connection-refused: The connection was refused. (ECONNREFUSED)
            • +
            • self: borrow<tcp-socket>
            -

            References

            +
            Return values
            +

            [method]tcp-socket.set-receive-buffer-size: func

            Params
            Return values
            -

            [method]incoming-datagram-stream.subscribe: func

            -

            Create a pollable which will resolve once the stream is ready to receive again.

            -

            Note: this function is here for WASI Preview2 only. -It's planned to be removed when future is natively supported in Preview3.

            +

            [method]tcp-socket.send-buffer-size: func

            Params
            Return values
            -

            [method]outgoing-datagram-stream.check-send: func

            -

            Check readiness for sending. This function never blocks.

            -

            Returns the number of datagrams permitted for the next call to send, -or an error. Calling send with more datagrams than this function has -permitted will trap.

            -

            When this function returns ok(0), the subscribe pollable will -become ready when this function will report at least ok(1), or an -error.

            -

            Never returns would-block.

            +

            [method]tcp-socket.set-send-buffer-size: func

            Params
            Return values
            -

            [method]outgoing-datagram-stream.send: func

            -

            Send messages on the socket.

            -

            This function attempts to send all provided datagrams on the socket without blocking and -returns how many messages were actually sent (or queued for sending). This function never -returns error(would-block). If none of the datagrams were able to be sent, ok(0) is returned.

            -

            This function semantically behaves the same as iterating the datagrams list and sequentially -sending each individual datagram until either the end of the list has been reached or the first error occurred. -If at least one datagram has been sent successfully, this function never returns an error.

            -

            If the input list is empty, the function returns ok(0).

            -

            Each call to send must be permitted by a preceding check-send. Implementations must trap if -either check-send was not called or datagrams contains more items than check-send permitted.

            -

            Typical errors

            +

            [method]tcp-socket.subscribe: func

            +

            Create a pollable which will resolve once the socket is ready for I/O.

            +

            Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

            +
            Params
              -
            • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
            • -
            • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
            • -
            • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
            • -
            • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
            • -
            • invalid-argument: The socket is in "connected" mode and remote-address is some value that does not match the address passed to stream. (EISCONN)
            • -
            • invalid-argument: The socket is not "connected" and no value for remote-address was provided. (EDESTADDRREQ)
            • -
            • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
            • -
            • connection-refused: The connection was refused. (ECONNREFUSED)
            • -
            • datagram-too-large: The datagram is too large. (EMSGSIZE)
            • +
            • self: borrow<tcp-socket>
            -

            References

            +
            Return values
            -
            Params
            +

            [method]tcp-socket.shutdown: func

            +

            Initiate a graceful shutdown.

            +
              +
            • receive: the socket is not expecting to receive any more data from the peer. All subsequent read +operations on the input-stream associated with this socket will return an End Of Stream indication. +Any data still in the receive queue at time of calling shutdown will be discarded.
            • +
            • send: the socket is not expecting to send any more data to the peer. All subsequent write +operations on the output-stream associated with this socket will return an error.
            • +
            • both: same effect as receive & send combined.
            • +
            +

            The shutdown function does not close (drop) the socket.

            +

            Typical errors

            -
            Return values
            +

            References

            -

            [method]outgoing-datagram-stream.subscribe: func

            -

            Create a pollable which will resolve once the stream is ready to send again.

            -

            Note: this function is here for WASI Preview2 only. -It's planned to be removed when future is natively supported in Preview3.

            Params
            Return values
            -

            Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2023-11-10

            +

            Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2023-11-10


            Types

            type network

            @@ -2757,24 +2847,24 @@ It's planned to be removed when future is natively supported in Pre #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

            -#### `type udp-socket` -[`udp-socket`](#udp_socket) +#### `type tcp-socket` +[`tcp-socket`](#tcp_socket)

            ----

            Functions

            -

            create-udp-socket: func

            -

            Create a new UDP socket.

            -

            Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.

            +

            create-tcp-socket: func

            +

            Create a new TCP socket.

            +

            Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX.

            This function does not require a network capability handle. This is considered to be safe because -at time of creation, the socket is not bound to any network yet. Up to the moment bind is called, -the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

            +at time of creation, the socket is not bound to any network yet. Up to the moment bind/listen/connect +is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

            All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

            Typical errors

            • not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
            • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
            -

            References:

            +

            References

            Params
            Return values
            +

            Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2023-11-10

            +
            +

            Types

            +

            type pollable

            +

            pollable

            +

            +#### `type network` +[`network`](#network) +

            +#### `type error-code` +[`error-code`](#error_code) +

            +#### `type ip-address` +[`ip-address`](#ip_address) +

            +#### `resource resolve-address-stream` +


            +

            Functions

            +

            resolve-addresses: func

            +

            Resolve an internet host name to a list of IP addresses.

            +

            Unicode domain names are automatically converted to ASCII using IDNA encoding. +If the input is an IP address string, the address is parsed and returned +as-is without making any external requests.

            +

            See the wasi-socket proposal README.md for a comparison with getaddrinfo.

            +

            This function never blocks. It either immediately fails or immediately +returns successfully with a resolve-address-stream that can be used +to (asynchronously) fetch the results.

            +

            Typical errors

            +
              +
            • invalid-argument: name is a syntactically invalid domain name or IP address.
            • +
            +

            References:

            + +
            Params
            + +
            Return values
            + +

            [method]resolve-address-stream.resolve-next-address: func

            +

            Returns the next address from the resolver.

            +

            This function should be called multiple times. On each call, it will +return the next address in connection order preference. If all +addresses have been exhausted, this function returns none.

            +

            This function never returns IPv4-mapped IPv6 addresses.

            +

            Typical errors

            +
              +
            • name-unresolvable: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY)
            • +
            • temporary-resolver-failure: A temporary failure in name resolution occurred. (EAI_AGAIN)
            • +
            • permanent-resolver-failure: A permanent failure in name resolution occurred. (EAI_FAIL)
            • +
            • would-block: A result is not available yet. (EWOULDBLOCK, EAGAIN)
            • +
            +
            Params
            + +
            Return values
            + +

            [method]resolve-address-stream.subscribe: func

            +

            Create a pollable which will resolve once the stream is ready for I/O.

            +

            Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

            +
            Params
            + +
            Return values
            +

            Import interface wasi:random/random@0.2.0-rc-2023-11-10

            WASI Random is a random data API.

            @@ -2875,140 +3045,6 @@ protection.

            • (u64, u64)
            -

            Import interface wasi:cli/environment@0.2.0-rc-2023-11-10

            -
            -

            Functions

            -

            get-environment: func

            -

            Get the POSIX-style environment variables.

            -

            Each environment variable is provided as a pair of string variable names -and string value.

            -

            Morally, these are a value import, but until value imports are available -in the component model, this import function should return the same -values each time it is called.

            -
            Return values
            -
              -
            • list<(string, string)>
            • -
            -

            get-arguments: func

            -

            Get the POSIX-style arguments to the program.

            -
            Return values
            -
              -
            • list<string>
            • -
            -

            initial-cwd: func

            -

            Return a path that programs should use as their initial current working -directory, interpreting . as shorthand for this.

            -
            Return values
            -
              -
            • option<string>
            • -
            -

            Import interface wasi:cli/exit@0.2.0-rc-2023-11-10

            -
            -

            Functions

            -

            exit: func

            -

            Exit the current instance and any linked instances.

            -
            Params
            - -

            Import interface wasi:cli/stdin@0.2.0-rc-2023-11-10

            -
            -

            Types

            -

            type input-stream

            -

            input-stream

            -

            ----- -

            Functions

            -

            get-stdin: func

            -
            Return values
            - -

            Import interface wasi:cli/stdout@0.2.0-rc-2023-11-10

            -
            -

            Types

            -

            type output-stream

            -

            output-stream

            -

            ----- -

            Functions

            -

            get-stdout: func

            -
            Return values
            - -

            Import interface wasi:cli/stderr@0.2.0-rc-2023-11-10

            -
            -

            Types

            -

            type output-stream

            -

            output-stream

            -

            ----- -

            Functions

            -

            get-stderr: func

            -
            Return values
            - -

            Import interface wasi:cli/terminal-input@0.2.0-rc-2023-11-10

            -
            -

            Types

            -

            resource terminal-input

            -

            Import interface wasi:cli/terminal-output@0.2.0-rc-2023-11-10

            -
            -

            Types

            -

            resource terminal-output

            -

            Import interface wasi:cli/terminal-stdin@0.2.0-rc-2023-11-10

            -

            An interface providing an optional terminal-input for stdin as a -link-time authority.

            -
            -

            Types

            -

            type terminal-input

            -

            terminal-input

            -

            ----- -

            Functions

            -

            get-terminal-stdin: func

            -

            If stdin is connected to a terminal, return a terminal-input handle -allowing further interaction with it.

            -
            Return values
            - -

            Import interface wasi:cli/terminal-stdout@0.2.0-rc-2023-11-10

            -

            An interface providing an optional terminal-output for stdout as a -link-time authority.

            -
            -

            Types

            -

            type terminal-output

            -

            terminal-output

            -

            ----- -

            Functions

            -

            get-terminal-stdout: func

            -

            If stdout is connected to a terminal, return a terminal-output handle -allowing further interaction with it.

            -
            Return values
            - -

            Import interface wasi:cli/terminal-stderr@0.2.0-rc-2023-11-10

            -

            An interface providing an optional terminal-output for stderr as a -link-time authority.

            -
            -

            Types

            -

            type terminal-output

            -

            terminal-output

            -

            ----- -

            Functions

            -

            get-terminal-stderr: func

            -

            If stderr is connected to a terminal, return a terminal-output handle -allowing further interaction with it.

            -
            Return values
            -

            Export interface wasi:cli/run@0.2.0-rc-2023-11-10


            Functions

            diff --git a/proposals/cli/reactor.md b/proposals/cli/imports.md similarity index 98% rename from proposals/cli/reactor.md rename to proposals/cli/imports.md index 1115e35d9..74a7c7a98 100644 --- a/proposals/cli/reactor.md +++ b/proposals/cli/imports.md @@ -1,77 +1,107 @@ -

            World reactor

            +

            World imports

            -

            Import interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10

            -

            WASI Wall Clock is a clock API intended to let users query the current -time. The name "wall" makes an analogy to a "clock on the wall", which -is not necessarily monotonic as it may be reset.

            -

            It is intended to be portable at least between Unix-family platforms and -Windows.

            -

            A wall clock is a clock which measures the date and time according to -some external reference.

            -

            External references may be reset, so this clock is not necessarily -monotonic, making it unsuitable for measuring elapsed time.

            -

            It is intended for reporting the current date and time for humans.

            +

            Import interface wasi:cli/environment@0.2.0-rc-2023-11-10


            -

            Types

            -

            record datetime

            -

            A time and date in seconds plus nanoseconds.

            -
            Record Fields
            +

            Functions

            +

            get-environment: func

            +

            Get the POSIX-style environment variables.

            +

            Each environment variable is provided as a pair of string variable names +and string value.

            +

            Morally, these are a value import, but until value imports are available +in the component model, this import function should return the same +values each time it is called.

            +
            Return values
            +

            get-arguments: func

            +

            Get the POSIX-style arguments to the program.

            +
            Return values
            +
              +
            • list<string>
            • +
            +

            initial-cwd: func

            +

            Return a path that programs should use as their initial current working +directory, interpreting . as shorthand for this.

            +
            Return values
            +
              +
            • option<string>
            +

            Import interface wasi:cli/exit@0.2.0-rc-2023-11-10


            Functions

            -

            now: func

            -

            Read the current value of the clock.

            -

            This clock is not monotonic, therefore calling this function repeatedly -will not necessarily produce a sequence of non-decreasing values.

            -

            The returned timestamps represent the number of seconds since -1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, -also known as Unix Time.

            -

            The nanoseconds field of the output is always less than 1000000000.

            -
            Return values
            +

            exit: func

            +

            Exit the current instance and any linked instances.

            +
            Params
            +

            Import interface wasi:io/error@0.2.0-rc-2023-11-10

            +
            +

            Types

            +

            resource error

            +

            A resource which represents some error information.

            +

            The only method provided by this resource is to-debug-string, +which provides some human-readable information about the error.

            +

            In the wasi:io package, this resource is returned through the +wasi:io/streams/stream-error type.

            +

            To provide more specific error information, other interfaces may +provide functions to further "downcast" this error into more specific +error information. For example, errors returned in streams derived +from filesystem types to be described using the filesystem's own +error-code type, using the function +wasi:filesystem/types/filesystem-error-code, which takes a parameter +borrow<error> and returns +option<wasi:filesystem/types/error-code>.

            +

            The set of functions which can "downcast" an error into a more +concrete type is open.

            +

            Functions

            +

            [method]error.to-debug-string: func

            +

            Returns a string that is suitable to assist humans in debugging +this error.

            +

            WARNING: The returned string should not be consumed mechanically! +It may change across platforms, hosts, or other implementation +details. Parsing this string is a major platform-compatibility +hazard.

            +
            Params
            + -

            resolution: func

            -

            Query the resolution of the clock.

            -

            The nanoseconds field of the output is always less than 1000000000.

            Return values

            Import interface wasi:io/poll@0.2.0-rc-2023-11-10

            A poll API intended to let users wait for I/O events on multiple handles @@ -79,7 +109,7 @@ at once.


            Types

            resource pollable

            -
            +

            pollable represents a single I/O event which may be ready, or not.

            Functions

            [method]pollable.ready: func

            Return the readiness of a pollable. This function never blocks.

            @@ -123,88 +153,6 @@ being reaedy for I/O.

            • list<u32>
            -

            Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

            -

            WASI Monotonic Clock is a clock API intended to let users measure elapsed -time.

            -

            It is intended to be portable at least between Unix-family platforms and -Windows.

            -

            A monotonic clock is a clock which has an unspecified initial value, and -successive reads of the clock will produce non-decreasing values.

            -

            It is intended for measuring elapsed time.

            -
            -

            Types

            -

            type pollable

            -

            pollable

            -

            -#### `type instant` -`u64` -

            An instant in time, in nanoseconds. An instant is relative to an -unspecified initial value, and can only be compared to instances from -the same monotonic-clock. -

            type duration

            -

            u64

            -

            A duration of time, in nanoseconds. -


            -

            Functions

            -

            now: func

            -

            Read the current value of the clock.

            -

            The clock is monotonic, therefore calling this function repeatedly will -produce a sequence of non-decreasing values.

            -
            Return values
            - -

            resolution: func

            -

            Query the resolution of the clock. Returns the duration of time -corresponding to a clock tick.

            -
            Return values
            - -

            subscribe-instant: func

            -

            Create a pollable which will resolve once the specified instant -occured.

            -
            Params
            - -
            Return values
            - -

            subscribe-duration: func

            -

            Create a pollable which will resolve once the given duration has -elapsed, starting at the time at which this function was called. -occured.

            -
            Params
            - -
            Return values
            - -

            Import interface wasi:io/error@0.2.0-rc-2023-11-10

            -
            -

            Types

            -

            resource error

            -
            -

            Functions

            -

            [method]error.to-debug-string: func

            -

            Returns a string that is suitable to assist humans in debugging -this error.

            -

            WARNING: The returned string should not be consumed mechanically! -It may change across platforms, hosts, or other implementation -details. Parsing this string is a major platform-compatibility -hazard.

            -
            Params
            - -
            Return values
            -
              -
            • string
            • -

            Import interface wasi:io/streams@0.2.0-rc-2023-11-10

            WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

            @@ -235,8 +183,21 @@ future operations.

          resource input-stream

          +

          An input bytestream.

          +

          input-streams are non-blocking to the extent practical on underlying +platforms. I/O operations always return promptly; if fewer bytes are +promptly available than requested, they return the number of bytes promptly +available, which could even be zero. To wait for data to be available, +use the subscribe function to obtain a pollable which can be polled +for using wasi:io/poll.

          resource output-stream

          -
          +

          An output bytestream.

          +

          output-streams are non-blocking to the extent practical on +underlying platforms. Except where specified otherwise, I/O operations also +always return promptly, after the number of bytes that can be written +promptly, which could even be zero. To wait for the stream to be ready to +accept data, the subscribe function to obtain a pollable which can be +polled for using wasi:io/poll.

          Functions

          [method]input-stream.read: func

          Perform a non-blocking read from the stream.

          @@ -357,7 +318,7 @@ following pseudo-code:

          let pollable = this.subscribe();
           while !contents.is_empty() {
             // Wait for the stream to become writable
          -  poll-one(pollable);
          +  pollable.block();
             let Ok(n) = this.check-write(); // eliding error handling
             let len = min(n, contents.len());
             let (chunk, rest) = contents.split_at(len);
          @@ -366,7 +327,7 @@ while !contents.is_empty() {
           }
           this.flush();
           // Wait for completion of `flush`
          -poll-one(pollable);
          +pollable.block();
           // Check for any errors that arose during `flush`
           let _ = this.check-write();         // eliding error handling
           
          @@ -426,7 +387,7 @@ all derived pollables created with this fun

        [method]output-stream.write-zeroes: func

        Write zeroes to a stream.

        -

        this should be used precisely like write with the exact same +

        This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of passing a list of bytes, you simply pass the number of zero-bytes that should be written.

        @@ -449,7 +410,7 @@ the following pseudo-code:

        let pollable = this.subscribe();
         while num_zeroes != 0 {
           // Wait for the stream to become writable
        -  poll-one(pollable);
        +  pollable.block();
           let Ok(n) = this.check-write(); // eliding error handling
           let len = min(n, num_zeroes);
           this.write-zeroes(len);         // eliding error handling
        @@ -457,7 +418,7 @@ while num_zeroes != 0 {
         }
         this.flush();
         // Wait for completion of `flush`
        -poll-one(pollable);
        +pollable.block();
         // Check for any errors that arose during `flush`
         let _ = this.check-write();         // eliding error handling
         
        @@ -508,48 +469,250 @@ is ready for reading, before performing the splice.

        -

        Import interface wasi:filesystem/types@0.2.0-rc-2023-11-10

        -

        WASI filesystem is a filesystem API primarily intended to let users run WASI -programs that access their files on their existing filesystems, without -significant overhead.

        -

        It is intended to be roughly portable between Unix-family platforms and -Windows, though it does not hide many of the major differences.

        -

        Paths are passed as interface-type strings, meaning they must consist of -a sequence of Unicode Scalar Values (USVs). Some filesystems may contain -paths which are not accessible by this API.

        -

        The directory separator in WASI is always the forward-slash (/).

        -

        All paths in WASI are relative paths, and are interpreted relative to a -descriptor referring to a base directory. If a path argument to any WASI -function starts with /, or if any step of resolving a path, including -.. and symbolic link steps, reaches a directory outside of the base -directory, or reaches a symlink to an absolute or rooted path in the -underlying filesystem, the function fails with error-code::not-permitted.

        -

        For more information about WASI path resolution and sandboxing, see -WASI filesystem path resolution.

        +

        Import interface wasi:cli/stdin@0.2.0-rc-2023-11-10


        Types

        type input-stream

        input-stream

        -#### `type output-stream` -[`output-stream`](#output_stream) -

        -#### `type error` -[`error`](#error) +---- +

        Functions

        +

        get-stdin: func

        +
        Return values
        + +

        Import interface wasi:cli/stdout@0.2.0-rc-2023-11-10

        +
        +

        Types

        +

        type output-stream

        +

        output-stream

        -#### `type datetime` -[`datetime`](#datetime) +---- +

        Functions

        +

        get-stdout: func

        +
        Return values
        + +

        Import interface wasi:cli/stderr@0.2.0-rc-2023-11-10

        +
        +

        Types

        +

        type output-stream

        +

        output-stream

        -#### `type filesize` -`u64` -

        File size or length of a region within a file. -

        enum descriptor-type

        -

        The type of a filesystem object referenced by a descriptor.

        -

        Note: This was called filetype in earlier versions of WASI.

        -
        Enum Cases
        +---- +

        Functions

        +

        get-stderr: func

        +
        Return values
        +

        Import interface wasi:cli/terminal-input@0.2.0-rc-2023-11-10

        +
        +

        Types

        +

        resource terminal-input

        +

        The input side of a terminal.

        +

        Import interface wasi:cli/terminal-output@0.2.0-rc-2023-11-10

        +
        +

        Types

        +

        resource terminal-output

        +

        The output side of a terminal.

        +

        Import interface wasi:cli/terminal-stdin@0.2.0-rc-2023-11-10

        +

        An interface providing an optional terminal-input for stdin as a +link-time authority.

        +
        +

        Types

        +

        type terminal-input

        +

        terminal-input

        +

        +---- +

        Functions

        +

        get-terminal-stdin: func

        +

        If stdin is connected to a terminal, return a terminal-input handle +allowing further interaction with it.

        +
        Return values
        + +

        Import interface wasi:cli/terminal-stdout@0.2.0-rc-2023-11-10

        +

        An interface providing an optional terminal-output for stdout as a +link-time authority.

        +
        +

        Types

        +

        type terminal-output

        +

        terminal-output

        +

        +---- +

        Functions

        +

        get-terminal-stdout: func

        +

        If stdout is connected to a terminal, return a terminal-output handle +allowing further interaction with it.

        +
        Return values
        + +

        Import interface wasi:cli/terminal-stderr@0.2.0-rc-2023-11-10

        +

        An interface providing an optional terminal-output for stderr as a +link-time authority.

        +
        +

        Types

        +

        type terminal-output

        +

        terminal-output

        +

        +---- +

        Functions

        +

        get-terminal-stderr: func

        +

        If stderr is connected to a terminal, return a terminal-output handle +allowing further interaction with it.

        +
        Return values
        + +

        Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

        +

        WASI Monotonic Clock is a clock API intended to let users measure elapsed +time.

        +

        It is intended to be portable at least between Unix-family platforms and +Windows.

        +

        A monotonic clock is a clock which has an unspecified initial value, and +successive reads of the clock will produce non-decreasing values.

        +

        It is intended for measuring elapsed time.

        +
        +

        Types

        +

        type pollable

        +

        pollable

        +

        +#### `type instant` +`u64` +

        An instant in time, in nanoseconds. An instant is relative to an +unspecified initial value, and can only be compared to instances from +the same monotonic-clock. +

        type duration

        +

        u64

        +

        A duration of time, in nanoseconds. +


        +

        Functions

        +

        now: func

        +

        Read the current value of the clock.

        +

        The clock is monotonic, therefore calling this function repeatedly will +produce a sequence of non-decreasing values.

        +
        Return values
        + +

        resolution: func

        +

        Query the resolution of the clock. Returns the duration of time +corresponding to a clock tick.

        +
        Return values
        + +

        subscribe-instant: func

        +

        Create a pollable which will resolve once the specified instant +occured.

        +
        Params
        + +
        Return values
        + +

        subscribe-duration: func

        +

        Create a pollable which will resolve once the given duration has +elapsed, starting at the time at which this function was called. +occured.

        +
        Params
        + +
        Return values
        + +

        Import interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10

        +

        WASI Wall Clock is a clock API intended to let users query the current +time. The name "wall" makes an analogy to a "clock on the wall", which +is not necessarily monotonic as it may be reset.

        +

        It is intended to be portable at least between Unix-family platforms and +Windows.

        +

        A wall clock is a clock which measures the date and time according to +some external reference.

        +

        External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time.

        +

        It is intended for reporting the current date and time for humans.

        +
        +

        Types

        +

        record datetime

        +

        A time and date in seconds plus nanoseconds.

        +
        Record Fields
        + +
        +

        Functions

        +

        now: func

        +

        Read the current value of the clock.

        +

        This clock is not monotonic, therefore calling this function repeatedly +will not necessarily produce a sequence of non-decreasing values.

        +

        The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, +also known as Unix Time.

        +

        The nanoseconds field of the output is always less than 1000000000.

        +
        Return values
        + +

        resolution: func

        +

        Query the resolution of the clock.

        +

        The nanoseconds field of the output is always less than 1000000000.

        +
        Return values
        + +

        Import interface wasi:filesystem/types@0.2.0-rc-2023-11-10

        +

        WASI filesystem is a filesystem API primarily intended to let users run WASI +programs that access their files on their existing filesystems, without +significant overhead.

        +

        It is intended to be roughly portable between Unix-family platforms and +Windows, though it does not hide many of the major differences.

        +

        Paths are passed as interface-type strings, meaning they must consist of +a sequence of Unicode Scalar Values (USVs). Some filesystems may contain +paths which are not accessible by this API.

        +

        The directory separator in WASI is always the forward-slash (/).

        +

        All paths in WASI are relative paths, and are interpreted relative to a +descriptor referring to a base directory. If a path argument to any WASI +function starts with /, or if any step of resolving a path, including +.. and symbolic link steps, reaches a directory outside of the base +directory, or reaches a symlink to an absolute or rooted path in the +underlying filesystem, the function fails with error-code::not-permitted.

        +

        For more information about WASI path resolution and sandboxing, see +WASI filesystem path resolution.

        +
        +

        Types

        +

        type input-stream

        +

        input-stream

        +

        +#### `type output-stream` +[`output-stream`](#output_stream) +

        +#### `type error` +[`error`](#error) +

        +#### `type datetime` +[`datetime`](#datetime) +

        +#### `type filesize` +`u64` +

        File size or length of a region within a file. +

        enum descriptor-type

        +

        The type of a filesystem object referenced by a descriptor.

        +

        Note: This was called filetype in earlier versions of WASI.

        +
        Enum Cases
        +
          +
        • +

          unknown

          The type of the descriptor or file is unknown or is different from any of the other types specified.

        • @@ -938,8 +1101,11 @@ not reuse it thereafter.

        resource descriptor

        +

        A descriptor is a reference to a filesystem object, which may be a file, +directory, named pipe, special file, or other object on which filesystem +calls may be made.

        resource directory-entry-stream

        -
        +

        A stream of directory entries.

        Functions

        [method]descriptor.read-via-stream: func

        Return a stream for reading from a file, if available.

        @@ -1403,6 +1569,9 @@ errors are filesystem-related errors.


        Types

        resource network

        +

        An opaque resource that represents access to (a subset of) the network. +This enables context-based security for networking. +There is no need for this to map 1:1 to a physical network interface.

        enum error-code

        Error codes.

        In theory, every API can return any error code. @@ -1584,7 +1753,7 @@ combined with a couple of errors that are always possible:

        -

        Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2023-11-10

        +

        Import interface wasi:sockets/udp@0.2.0-rc-2023-11-10


        Types

        type pollable

        @@ -1596,133 +1765,62 @@ combined with a couple of errors that are always possible:

        #### `type error-code` [`error-code`](#error_code)

        -#### `type ip-address` -[`ip-address`](#ip_address) +#### `type ip-socket-address` +[`ip-socket-address`](#ip_socket_address)

        -#### `resource resolve-address-stream` -


        -

        Functions

        -

        resolve-addresses: func

        -

        Resolve an internet host name to a list of IP addresses.

        -

        Unicode domain names are automatically converted to ASCII using IDNA encoding. -If the input is an IP address string, the address is parsed and returned -as-is without making any external requests.

        -

        See the wasi-socket proposal README.md for a comparison with getaddrinfo.

        -

        This function never blocks. It either immediately fails or immediately -returns successfully with a resolve-address-stream that can be used -to (asynchronously) fetch the results.

        -

        Typical errors

        -
          -
        • invalid-argument: name is a syntactically invalid domain name or IP address.
        • -
        -

        References:

        +#### `type ip-address-family` +[`ip-address-family`](#ip_address_family) +

        +#### `record incoming-datagram` +

        A received datagram.

        +
        Record Fields
        -
        Params
        +

        record outgoing-datagram

        +

        A datagram to be sent out.

        +
        Record Fields
        -
        Return values
        - -

        [method]resolve-address-stream.resolve-next-address: func

        -

        Returns the next address from the resolver.

        -

        This function should be called multiple times. On each call, it will -return the next address in connection order preference. If all -addresses have been exhausted, this function returns none.

        -

        This function never returns IPv4-mapped IPv6 addresses.

        -

        Typical errors

        -
          -
        • name-unresolvable: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY)
        • -
        • temporary-resolver-failure: A temporary failure in name resolution occurred. (EAI_AGAIN)
        • -
        • permanent-resolver-failure: A permanent failure in name resolution occurred. (EAI_FAIL)
        • -
        • would-block: A result is not available yet. (EWOULDBLOCK, EAGAIN)
        • -
        -
        Params
        - -
        Return values
        - -

        [method]resolve-address-stream.subscribe: func

        -

        Create a pollable which will resolve once the stream is ready for I/O.

        -

        Note: this function is here for WASI Preview2 only. -It's planned to be removed when future is natively supported in Preview3.

        -
        Params
        - -
        Return values
        - -

        Import interface wasi:sockets/tcp@0.2.0-rc-2023-11-10

        -
        -

        Types

        -

        type input-stream

        -

        input-stream

        -

        -#### `type output-stream` -[`output-stream`](#output_stream) -

        -#### `type pollable` -[`pollable`](#pollable) -

        -#### `type duration` -[`duration`](#duration) -

        -#### `type network` -[`network`](#network) -

        -#### `type error-code` -[`error-code`](#error_code) -

        -#### `type ip-socket-address` -[`ip-socket-address`](#ip_socket_address) -

        -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) -

        -#### `enum shutdown-type` -

        Enum Cases
        -
          -
        • -

          receive

          -

          Similar to `SHUT_RD` in POSIX. -

        • -

          send

          -

          Similar to `SHUT_WR` in POSIX. +

          data: list<u8>

          +

          The payload.

        • -

          both

          -

          Similar to `SHUT_RDWR` in POSIX. +

          remote-address: option<ip-socket-address>

          +

          The destination address. +

          The requirements on this field depend on how the stream was initialized:

          +
            +
          • with a remote address: this field must be None or match the stream's remote address exactly.
          • +
          • without a remote address: this field is required.
          • +
          +

          If this value is None, the send operation is equivalent to send in POSIX. Otherwise it is equivalent to sendto.

        -

        resource tcp-socket

        +

        resource udp-socket

        +

        A UDP socket handle.

        +

        resource incoming-datagram-stream

        +

        resource outgoing-datagram-stream


        Functions

        -

        [method]tcp-socket.start-bind: func

        +

        [method]udp-socket.start-bind: func

        Bind the socket to a specific network on the provided IP address and port.

        If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. -If the TCP/UDP port is zero, the socket will be bound to a random free port.

        -

        When a socket is not explicitly bound, the first invocation to a listen or connect operation will -implicitly bind the socket.

        +If the port is zero, the socket will be bound to a random free port.

        Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

        Typical start errors

        • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
        • -
        • invalid-argument: local-address is not a unicast address. (EINVAL)
        • -
        • invalid-argument: local-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL)
        • invalid-state: The socket is already bound. (EINVAL)

        Typical finish errors

        @@ -1742,63 +1840,55 @@ implicitly bind the socket.

      Params
      Return values
      -

      [method]tcp-socket.finish-bind: func

      +

      [method]udp-socket.finish-bind: func

      Params
      Return values
      -

      [method]tcp-socket.start-connect: func

      -

      Connect to a remote endpoint.

      -

      On success:

      -
        -
      • the socket is transitioned into the Connection state
      • -
      • a pair of streams is returned that can be used to read & write to the connection
      • +
      • result<_, error-code>
      -

      POSIX mentions:

      -
      -

      If connect() fails, the state of the socket is unspecified. Conforming applications should -close the file descriptor and create a new socket before attempting to reconnect.

      -
      -

      WASI prescribes the following behavior:

      +

      [method]udp-socket.stream: func

      +

      Set up inbound & outbound communication channels, optionally to a specific peer.

      +

      This function only changes the local socket configuration and does not generate any network traffic. +On success, the remote-address of the socket is updated. The local-address may be updated as well, +based on the best network path to remote-address.

      +

      When a remote-address is provided, the returned streams are limited to communicating with that specific peer:

        -
      • If connect fails because an input/state validation error, the socket should remain usable.
      • -
      • If a connection was actually attempted but failed, the socket should become unusable for further network communication. -Besides drop, any method after such a failure may return an error.
      • +
      • send can only be used to send to this destination.
      • +
      • receive will only return datagrams sent from the provided remote-address.
      -

      Typical start errors

      +

      This method may be called multiple times on the same socket to change its association, but +only the most recently returned pair of streams will be operational. Implementations may trap if +the streams returned by a previous invocation haven't been dropped yet before calling stream again.

      +

      The POSIX equivalent in pseudo-code is:

      +
      if (was previously connected) {
      +  connect(s, AF_UNSPEC)
      +}
      +if (remote_address is Some) {
      +  connect(s, remote_address)
      +}
      +
      +

      Unlike in POSIX, the socket must already be explicitly bound.

      +

      Typical errors

      • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
      • -
      • invalid-argument: remote-address is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
      • -
      • invalid-argument: remote-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL, EADDRNOTAVAIL on Illumos)
      • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
      • -
      • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
      • -
      • invalid-argument: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
      • -
      • invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
      • -
      • invalid-state: The socket is already in the Connection state. (EISCONN)
      • -
      • invalid-state: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
      • -
      -

      Typical finish errors

      -
        -
      • timeout: Connection timed out. (ETIMEDOUT)
      • -
      • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
      • -
      • connection-reset: The connection was reset. (ECONNRESET)
      • -
      • connection-aborted: The connection was aborted. (ECONNABORTED)
      • -
      • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
      • +
      • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
      • +
      • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
      • +
      • invalid-state: The socket is not bound.
      • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
      • -
      • not-in-progress: A connect operation is not in progress.
      • -
      • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
      • +
      • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
      • +
      • connection-refused: The connection was refused. (ECONNREFUSED)

      References

        @@ -1809,453 +1899,303 @@ Besides drop, any method after such a failure may return an error.<
      Params
      Return values
      -

      [method]tcp-socket.finish-connect: func

      -
      Params
      +

      [method]udp-socket.local-address: func

      +

      Get the current bound address.

      +

      POSIX mentions:

      +
      +

      If the socket has not been bound to a local name, the value +stored in the object pointed to by address is unspecified.

      +
      +

      WASI is stricter and requires local-address to return invalid-state when the socket hasn't been bound yet.

      +

      Typical errors

        -
      • self: borrow<tcp-socket>
      • +
      • invalid-state: The socket is not bound to any local address.
      -
      Return values
      +

      References

      -

      [method]tcp-socket.start-listen: func

      -

      Start listening for new connections.

      -

      Transitions the socket into the Listener state.

      -

      Unlike POSIX:

      +
      Params
        -
      • this function is async. This enables interactive WASI hosts to inject permission prompts.
      • -
      • the socket must already be explicitly bound.
      • +
      • self: borrow<udp-socket>
      -

      Typical start errors

      +
      Return values
        -
      • invalid-state: The socket is not bound to any local address. (EDESTADDRREQ)
      • -
      • invalid-state: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
      • -
      • invalid-state: The socket is already in the Listener state.
      • +
      • result<ip-socket-address, error-code>
      -

      Typical finish errors

      +

      [method]udp-socket.remote-address: func

      +

      Get the address the socket is currently streaming to.

      +

      Typical errors

        -
      • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
      • -
      • not-in-progress: A listen operation is not in progress.
      • -
      • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
      • +
      • invalid-state: The socket is not streaming to a specific remote address. (ENOTCONN)

      References

      Params
      Return values
      -

      [method]tcp-socket.finish-listen: func

      +

      [method]udp-socket.address-family: func

      +

      Whether this is a IPv4 or IPv6 socket.

      +

      Equivalent to the SO_DOMAIN socket option.

      Params
      Return values
      -

      [method]tcp-socket.accept: func

      -

      Accept a new client socket.

      -

      The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket:

      +

      [method]udp-socket.ipv6-only: func

      +

      Whether IPv4 compatibility (dual-stack) mode is disabled or not.

      +

      Equivalent to the IPV6_V6ONLY socket option.

      +

      Typical errors

        -
      • address-family
      • -
      • ipv6-only
      • -
      • keep-alive-enabled
      • -
      • keep-alive-idle-time
      • -
      • keep-alive-interval
      • -
      • keep-alive-count
      • -
      • hop-limit
      • -
      • receive-buffer-size
      • -
      • send-buffer-size
      • +
      • not-supported: (get/set) this socket is an IPv4 socket.
      • +
      • invalid-state: (set) The socket is already bound.
      • +
      • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
      -

      On success, this function returns the newly accepted client socket along with -a pair of streams that can be used to read & write to the connection.

      -

      Typical errors

      +
      Params
        -
      • invalid-state: Socket is not in the Listener state. (EINVAL)
      • -
      • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
      • -
      • connection-aborted: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED)
      • -
      • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
      • +
      • self: borrow<udp-socket>
      -

      References

      +
      Return values
      +

      [method]udp-socket.set-ipv6-only: func

      Params
      Return values
      -

      [method]tcp-socket.local-address: func

      -

      Get the bound local address.

      -

      POSIX mentions:

      -
      -

      If the socket has not been bound to a local name, the value -stored in the object pointed to by address is unspecified.

      -
      -

      WASI is stricter and requires local-address to return invalid-state when the socket hasn't been bound yet.

      +

      [method]udp-socket.unicast-hop-limit: func

      +

      Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

      +

      If the provided value is 0, an invalid-argument error is returned.

      Typical errors

        -
      • invalid-state: The socket is not bound to any local address.
      • +
      • invalid-argument: (set) The TTL value must be 1 or higher.
      -

      References

      +
      Params
      +
      Return values
      + +

      [method]udp-socket.set-unicast-hop-limit: func

      Params
      Return values
      -

      [method]tcp-socket.remote-address: func

      -

      Get the remote address.

      +

      [method]udp-socket.receive-buffer-size: func

      +

      The kernel buffer space reserved for sends/receives on this socket.

      +

      If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

      +

      Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

      Typical errors

        -
      • invalid-state: The socket is not connected to a remote address. (ENOTCONN)
      • -
      -

      References

      -
      Params
      Return values
      -

      [method]tcp-socket.is-listening: func

      -

      Whether the socket is listening for new connections.

      -

      Equivalent to the SO_ACCEPTCONN socket option.

      +

      [method]udp-socket.set-receive-buffer-size: func

      Params
      Return values
      -

      [method]tcp-socket.address-family: func

      -

      Whether this is a IPv4 or IPv6 socket.

      -

      Equivalent to the SO_DOMAIN socket option.

      +

      [method]udp-socket.send-buffer-size: func

      Params
      Return values
      -

      [method]tcp-socket.ipv6-only: func

      -

      Whether IPv4 compatibility (dual-stack) mode is disabled or not.

      -

      Equivalent to the IPV6_V6ONLY socket option.

      -

      Typical errors

      -
        -
      • invalid-state: (set) The socket is already bound.
      • -
      • not-supported: (get/set) this socket is an IPv4 socket.
      • -
      • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
      • +
      • result<u64, error-code>
      +

      [method]udp-socket.set-send-buffer-size: func

      Params
      Return values
      -

      [method]tcp-socket.set-ipv6-only: func

      +

      [method]udp-socket.subscribe: func

      +

      Create a pollable which will resolve once the socket is ready for I/O.

      +

      Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

      Params
      Return values
      +

      [method]incoming-datagram-stream.receive: func

      +

      Receive messages on the socket.

      +

      This function attempts to receive up to max-results datagrams on the socket without blocking. +The returned list may contain fewer elements than requested, but never more.

      +

      This function returns successfully with an empty list when either:

      +
        +
      • max-results is 0, or:
      • +
      • max-results is greater than 0, but no results are immediately available. +This function never returns error(would-block).
      -

      [method]tcp-socket.set-listen-backlog-size: func

      -

      Hints the desired listen queue size. Implementations are free to ignore this.

      -

      If the provided value is 0, an invalid-argument error is returned. -Any other value will never cause an error, but it might be silently clamped and/or rounded.

      Typical errors

        -
      • not-supported: (set) The platform does not support changing the backlog size after the initial listen.
      • -
      • invalid-argument: (set) The provided value was 0.
      • -
      • invalid-state: (set) The socket is already in the Connection state.
      • +
      • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
      • +
      • connection-refused: The connection was refused. (ECONNREFUSED)
      -
      Params
      +

      References

      -
      Return values
      +
      Params
      -

      [method]tcp-socket.keep-alive-enabled: func

      -

      Enables or disables keepalive.

      -

      The keepalive behavior can be adjusted using:

      +
      Return values
        -
      • keep-alive-idle-time
      • -
      • keep-alive-interval
      • -
      • keep-alive-count -These properties can be configured while keep-alive-enabled is false, but only come into effect when keep-alive-enabled is true.
      • +
      • result<list<incoming-datagram>, error-code>
      -

      Equivalent to the SO_KEEPALIVE socket option.

      +

      [method]incoming-datagram-stream.subscribe: func

      +

      Create a pollable which will resolve once the stream is ready to receive again.

      +

      Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

      Params
      Return values
      -

      [method]tcp-socket.set-keep-alive-enabled: func

      +

      [method]outgoing-datagram-stream.check-send: func

      +

      Check readiness for sending. This function never blocks.

      +

      Returns the number of datagrams permitted for the next call to send, +or an error. Calling send with more datagrams than this function has +permitted will trap.

      +

      When this function returns ok(0), the subscribe pollable will +become ready when this function will report at least ok(1), or an +error.

      +

      Never returns would-block.

      Params
      Return values
      -

      [method]tcp-socket.keep-alive-idle-time: func

      -

      Amount of time the connection has to be idle before TCP starts sending keepalive packets.

      -

      If the provided value is 0, an invalid-argument error is returned. -Any other value will never cause an error, but it might be silently clamped and/or rounded. -I.e. after setting a value, reading the same setting back may return a different value.

      -

      Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS)

      +

      [method]outgoing-datagram-stream.send: func

      +

      Send messages on the socket.

      +

      This function attempts to send all provided datagrams on the socket without blocking and +returns how many messages were actually sent (or queued for sending). This function never +returns error(would-block). If none of the datagrams were able to be sent, ok(0) is returned.

      +

      This function semantically behaves the same as iterating the datagrams list and sequentially +sending each individual datagram until either the end of the list has been reached or the first error occurred. +If at least one datagram has been sent successfully, this function never returns an error.

      +

      If the input list is empty, the function returns ok(0).

      +

      Each call to send must be permitted by a preceding check-send. Implementations must trap if +either check-send was not called or datagrams contains more items than check-send permitted.

      Typical errors

        -
      • invalid-argument: (set) The provided value was 0.
      • -
      -
      Params
      -
        -
      • self: borrow<tcp-socket>
      • +
      • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
      • +
      • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
      • +
      • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
      • +
      • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
      • +
      • invalid-argument: The socket is in "connected" mode and remote-address is some value that does not match the address passed to stream. (EISCONN)
      • +
      • invalid-argument: The socket is not "connected" and no value for remote-address was provided. (EDESTADDRREQ)
      • +
      • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
      • +
      • connection-refused: The connection was refused. (ECONNREFUSED)
      • +
      • datagram-too-large: The datagram is too large. (EMSGSIZE)
      -
      Return values
      +

      References

      -

      [method]tcp-socket.set-keep-alive-idle-time: func

      Params
      Return values
      -

      [method]tcp-socket.keep-alive-interval: func

      -

      The time between keepalive packets.

      -

      If the provided value is 0, an invalid-argument error is returned. -Any other value will never cause an error, but it might be silently clamped and/or rounded. -I.e. after setting a value, reading the same setting back may return a different value.

      -

      Equivalent to the TCP_KEEPINTVL socket option.

      -

      Typical errors

      -
        -
      • invalid-argument: (set) The provided value was 0.
      • +
      • result<u64, error-code>
      +

      [method]outgoing-datagram-stream.subscribe: func

      +

      Create a pollable which will resolve once the stream is ready to send again.

      +

      Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

      Params
      Return values
      -

      [method]tcp-socket.set-keep-alive-interval: func

      -
      Params
      - -
      Return values
      - -

      [method]tcp-socket.keep-alive-count: func

      -

      The maximum amount of keepalive packets TCP should send before aborting the connection.

      -

      If the provided value is 0, an invalid-argument error is returned. -Any other value will never cause an error, but it might be silently clamped and/or rounded. -I.e. after setting a value, reading the same setting back may return a different value.

      -

      Equivalent to the TCP_KEEPCNT socket option.

      -

      Typical errors

      -
        -
      • invalid-argument: (set) The provided value was 0.
      • -
      -
      Params
      - -
      Return values
      - -

      [method]tcp-socket.set-keep-alive-count: func

      -
      Params
      - -
      Return values
      - -

      [method]tcp-socket.hop-limit: func

      -

      Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

      -

      If the provided value is 0, an invalid-argument error is returned.

      -

      Typical errors

      -
        -
      • invalid-argument: (set) The TTL value must be 1 or higher.
      • -
      • invalid-state: (set) The socket is already in the Connection state.
      • -
      • invalid-state: (set) The socket is already in the Listener state.
      • -
      -
      Params
      - -
      Return values
      - -

      [method]tcp-socket.set-hop-limit: func

      -
      Params
      - -
      Return values
      - -

      [method]tcp-socket.receive-buffer-size: func

      -

      The kernel buffer space reserved for sends/receives on this socket.

      -

      If the provided value is 0, an invalid-argument error is returned. -Any other value will never cause an error, but it might be silently clamped and/or rounded. -I.e. after setting a value, reading the same setting back may return a different value.

      -

      Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

      -

      Typical errors

      -
        -
      • invalid-argument: (set) The provided value was 0.
      • -
      • invalid-state: (set) The socket is already in the Connection state.
      • -
      • invalid-state: (set) The socket is already in the Listener state.
      • -
      -
      Params
      - -
      Return values
      - -

      [method]tcp-socket.set-receive-buffer-size: func

      -
      Params
      - -
      Return values
      - -

      [method]tcp-socket.send-buffer-size: func

      -
      Params
      - -
      Return values
      - -

      [method]tcp-socket.set-send-buffer-size: func

      -
      Params
      - -
      Return values
      - -

      [method]tcp-socket.subscribe: func

      -

      Create a pollable which will resolve once the socket is ready for I/O.

      -

      Note: this function is here for WASI Preview2 only. -It's planned to be removed when future is natively supported in Preview3.

      -
      Params
      - -
      Return values
      - -

      [method]tcp-socket.shutdown: func

      -

      Initiate a graceful shutdown.

      -
        -
      • receive: the socket is not expecting to receive any more data from the peer. All subsequent read -operations on the input-stream associated with this socket will return an End Of Stream indication. -Any data still in the receive queue at time of calling shutdown will be discarded.
      • -
      • send: the socket is not expecting to send any more data to the peer. All subsequent write -operations on the output-stream associated with this socket will return an error.
      • -
      • both: same effect as receive & send combined.
      • -
      -

      The shutdown function does not close (drop) the socket.

      -

      Typical errors

      -
        -
      • invalid-state: The socket is not in the Connection state. (ENOTCONN)
      • -
      -

      References

      - -
      Params
      - -
      Return values
      - -

      Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2023-11-10

      +

      Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2023-11-10


      Types

      type network

      @@ -2267,24 +2207,24 @@ operations on the output-stream associ #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

      -#### `type tcp-socket` -[`tcp-socket`](#tcp_socket) +#### `type udp-socket` +[`udp-socket`](#udp_socket)

      ----

      Functions

      -

      create-tcp-socket: func

      -

      Create a new TCP socket.

      -

      Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX.

      +

      create-udp-socket: func

      +

      Create a new UDP socket.

      +

      Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.

      This function does not require a network capability handle. This is considered to be safe because -at time of creation, the socket is not bound to any network yet. Up to the moment bind/listen/connect -is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

      +at time of creation, the socket is not bound to any network yet. Up to the moment bind is called, +the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

      All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

      Typical errors

      • not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
      • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
      -

      References

      +

      References:

      Params
      Return values
      -

      Import interface wasi:sockets/udp@0.2.0-rc-2023-11-10

      +

      Import interface wasi:sockets/tcp@0.2.0-rc-2023-11-10


      Types

      -

      type pollable

      -

      pollable

      +

      type input-stream

      +

      input-stream

      +

      +#### `type output-stream` +[`output-stream`](#output_stream) +

      +#### `type pollable` +[`pollable`](#pollable) +

      +#### `type duration` +[`duration`](#duration)

      #### `type network` [`network`](#network) @@ -2317,55 +2266,38 @@ is called, the socket is effectively an in-memory configuration object, unable t #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

      -#### `record incoming-datagram` -

      A received datagram.

      -
      Record Fields
      +#### `enum shutdown-type` +
      Enum Cases
      • -

        data: list<u8>

        -

        The payload. -

        Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes.

        -
      • -
      • -

        remote-address: ip-socket-address

        -

        The source address. -

        This field is guaranteed to match the remote address the stream was initialized with, if any.

        -

        Equivalent to the src_addr out parameter of recvfrom.

        +

        receive

        +

        Similar to `SHUT_RD` in POSIX.

      • -
      -

      record outgoing-datagram

      -

      A datagram to be sent out.

      -
      Record Fields
      -
      • -

        data: list<u8>

        -

        The payload. +

        send

        +

        Similar to `SHUT_WR` in POSIX.

      • -

        remote-address: option<ip-socket-address>

        -

        The destination address. -

        The requirements on this field depend on how the stream was initialized:

        -
          -
        • with a remote address: this field must be None or match the stream's remote address exactly.
        • -
        • without a remote address: this field is required.
        • -
        -

        If this value is None, the send operation is equivalent to send in POSIX. Otherwise it is equivalent to sendto.

        +

        both

        +

        Similar to `SHUT_RDWR` in POSIX.

      -

      resource udp-socket

      -

      resource incoming-datagram-stream

      -

      resource outgoing-datagram-stream

      -
      +

      resource tcp-socket

      +

      A TCP socket handle.

      Functions

      -

      [method]udp-socket.start-bind: func

      +

      [method]tcp-socket.start-bind: func

      Bind the socket to a specific network on the provided IP address and port.

      If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. -If the port is zero, the socket will be bound to a random free port.

      +If the TCP/UDP port is zero, the socket will be bound to a random free port.

      +

      When a socket is not explicitly bound, the first invocation to a listen or connect operation will +implicitly bind the socket.

      Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

      Typical start errors

      • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
      • +
      • invalid-argument: local-address is not a unicast address. (EINVAL)
      • +
      • invalid-argument: local-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL)
      • invalid-state: The socket is already bound. (EINVAL)

      Typical finish errors

      @@ -2385,55 +2317,63 @@ If the port is zero, the socket will be bound to a random free port.

    Params
    Return values
    -

    [method]udp-socket.finish-bind: func

    +

    [method]tcp-socket.finish-bind: func

    Params
    Return values
    -

    [method]udp-socket.stream: func

    -

    Set up inbound & outbound communication channels, optionally to a specific peer.

    -

    This function only changes the local socket configuration and does not generate any network traffic. -On success, the remote-address of the socket is updated. The local-address may be updated as well, -based on the best network path to remote-address.

    -

    When a remote-address is provided, the returned streams are limited to communicating with that specific peer:

    +

    [method]tcp-socket.start-connect: func

    +

    Connect to a remote endpoint.

    +

    On success:

      -
    • send can only be used to send to this destination.
    • -
    • receive will only return datagrams sent from the provided remote-address.
    • +
    • the socket is transitioned into the Connection state
    • +
    • a pair of streams is returned that can be used to read & write to the connection
    -

    This method may be called multiple times on the same socket to change its association, but -only the most recently returned pair of streams will be operational. Implementations may trap if -the streams returned by a previous invocation haven't been dropped yet before calling stream again.

    -

    The POSIX equivalent in pseudo-code is:

    -
    if (was previously connected) {
    -  connect(s, AF_UNSPEC)
    -}
    -if (remote_address is Some) {
    -  connect(s, remote_address)
    -}
    -
    -

    Unlike in POSIX, the socket must already be explicitly bound.

    -

    Typical errors

    +

    POSIX mentions:

    +
    +

    If connect() fails, the state of the socket is unspecified. Conforming applications should +close the file descriptor and create a new socket before attempting to reconnect.

    +
    +

    WASI prescribes the following behavior:

    +
      +
    • If connect fails because an input/state validation error, the socket should remain usable.
    • +
    • If a connection was actually attempted but failed, the socket should become unusable for further network communication. +Besides drop, any method after such a failure may return an error.
    • +
    +

    Typical start errors

    • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-argument: remote-address is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
    • +
    • invalid-argument: remote-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL, EADDRNOTAVAIL on Illumos)
    • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
    • -
    • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • -
    • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • -
    • invalid-state: The socket is not bound.
    • +
    • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
    • +
    • invalid-argument: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
    • +
    • invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
    • +
    • invalid-state: The socket is already in the Connection state. (EISCONN)
    • +
    • invalid-state: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
    • +
    +

    Typical finish errors

    +
      +
    • timeout: Connection timed out. (ETIMEDOUT)
    • +
    • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
    • +
    • connection-reset: The connection was reset. (ECONNRESET)
    • +
    • connection-aborted: The connection was aborted. (ECONNABORTED)
    • +
    • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
    • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
    • -
    • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
    • -
    • connection-refused: The connection was refused. (ECONNREFUSED)
    • +
    • not-in-progress: A connect operation is not in progress.
    • +
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)

    References

      @@ -2444,15 +2384,107 @@ if (remote_address is Some) {
    Params
    Return values
    -

    [method]udp-socket.local-address: func

    -

    Get the current bound address.

    +

    [method]tcp-socket.finish-connect: func

    +
    Params
    + +
    Return values
    + +

    [method]tcp-socket.start-listen: func

    +

    Start listening for new connections.

    +

    Transitions the socket into the Listener state.

    +

    Unlike POSIX:

    +
      +
    • this function is async. This enables interactive WASI hosts to inject permission prompts.
    • +
    • the socket must already be explicitly bound.
    • +
    +

    Typical start errors

    +
      +
    • invalid-state: The socket is not bound to any local address. (EDESTADDRREQ)
    • +
    • invalid-state: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
    • +
    • invalid-state: The socket is already in the Listener state.
    • +
    +

    Typical finish errors

    +
      +
    • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
    • +
    • not-in-progress: A listen operation is not in progress.
    • +
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    [method]tcp-socket.finish-listen: func

    +
    Params
    + +
    Return values
    + +

    [method]tcp-socket.accept: func

    +

    Accept a new client socket.

    +

    The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket:

    +
      +
    • address-family
    • +
    • ipv6-only
    • +
    • keep-alive-enabled
    • +
    • keep-alive-idle-time
    • +
    • keep-alive-interval
    • +
    • keep-alive-count
    • +
    • hop-limit
    • +
    • receive-buffer-size
    • +
    • send-buffer-size
    • +
    +

    On success, this function returns the newly accepted client socket along with +a pair of streams that can be used to read & write to the connection.

    +

    Typical errors

    +
      +
    • invalid-state: Socket is not in the Listener state. (EINVAL)
    • +
    • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
    • +
    • connection-aborted: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED)
    • +
    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    [method]tcp-socket.local-address: func

    +

    Get the bound local address.

    POSIX mentions:

    If the socket has not been bound to a local name, the value @@ -2465,282 +2497,340 @@ stored in the object pointed to by address is unspecified.

    References

    +
    Params
    + +
    Return values
    + +

    [method]tcp-socket.remote-address: func

    +

    Get the remote address.

    +

    Typical errors

    +
      +
    • invalid-state: The socket is not connected to a remote address. (ENOTCONN)
    • +
    +

    References

    + +
    Params
    + +
    Return values
    + +

    [method]tcp-socket.is-listening: func

    +

    Whether the socket is listening for new connections.

    +

    Equivalent to the SO_ACCEPTCONN socket option.

    +
    Params
    + +
    Return values
    +
      +
    • bool
    • +
    +

    [method]tcp-socket.address-family: func

    +

    Whether this is a IPv4 or IPv6 socket.

    +

    Equivalent to the SO_DOMAIN socket option.

    +
    Params
    + +
    Return values
    + +

    [method]tcp-socket.ipv6-only: func

    +

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    +

    Equivalent to the IPV6_V6ONLY socket option.

    +

    Typical errors

    +
      +
    • invalid-state: (set) The socket is already bound.
    • +
    • not-supported: (get/set) this socket is an IPv4 socket.
    • +
    • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
    • +
    +
    Params
    + +
    Return values
    + +

    [method]tcp-socket.set-ipv6-only: func

    +
    Params
    + +
    Return values
    + +

    [method]tcp-socket.set-listen-backlog-size: func

    +

    Hints the desired listen queue size. Implementations are free to ignore this.

    +

    If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded.

    +

    Typical errors

    +
      +
    • not-supported: (set) The platform does not support changing the backlog size after the initial listen.
    • +
    • invalid-argument: (set) The provided value was 0.
    • +
    • invalid-state: (set) The socket is already in the Connection state.
    Params
    Return values
    -

    [method]udp-socket.remote-address: func

    -

    Get the address the socket is currently streaming to.

    -

    Typical errors

    -
      -
    • invalid-state: The socket is not streaming to a specific remote address. (ENOTCONN)
    • +
    • result<_, error-code>
    -

    References

    +

    [method]tcp-socket.keep-alive-enabled: func

    +

    Enables or disables keepalive.

    +

    The keepalive behavior can be adjusted using:

    +

    Equivalent to the SO_KEEPALIVE socket option.

    Params
    Return values
    -

    [method]udp-socket.address-family: func

    -

    Whether this is a IPv4 or IPv6 socket.

    -

    Equivalent to the SO_DOMAIN socket option.

    +

    [method]tcp-socket.set-keep-alive-enabled: func

    Params
    Return values
    -

    [method]udp-socket.ipv6-only: func

    -

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    -

    Equivalent to the IPV6_V6ONLY socket option.

    +

    [method]tcp-socket.keep-alive-idle-time: func

    +

    Amount of time the connection has to be idle before TCP starts sending keepalive packets.

    +

    If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

    +

    Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS)

    Typical errors

      -
    • not-supported: (get/set) this socket is an IPv4 socket.
    • -
    • invalid-state: (set) The socket is already bound.
    • -
    • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
    • +
    • invalid-argument: (set) The provided value was 0.
    Params
    Return values
    -

    [method]udp-socket.set-ipv6-only: func

    +

    [method]tcp-socket.set-keep-alive-idle-time: func

    Params
    Return values
    -

    [method]udp-socket.unicast-hop-limit: func

    -

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    -

    If the provided value is 0, an invalid-argument error is returned.

    +

    [method]tcp-socket.keep-alive-interval: func

    +

    The time between keepalive packets.

    +

    If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

    +

    Equivalent to the TCP_KEEPINTVL socket option.

    Typical errors

      -
    • invalid-argument: (set) The TTL value must be 1 or higher.
    • +
    • invalid-argument: (set) The provided value was 0.
    Params
    Return values
    -

    [method]udp-socket.set-unicast-hop-limit: func

    +

    [method]tcp-socket.set-keep-alive-interval: func

    Params
    Return values
    -

    [method]udp-socket.receive-buffer-size: func

    -

    The kernel buffer space reserved for sends/receives on this socket.

    +

    [method]tcp-socket.keep-alive-count: func

    +

    The maximum amount of keepalive packets TCP should send before aborting the connection.

    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. I.e. after setting a value, reading the same setting back may return a different value.

    -

    Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

    +

    Equivalent to the TCP_KEEPCNT socket option.

    Typical errors

    • invalid-argument: (set) The provided value was 0.
    Params
    Return values
    -

    [method]udp-socket.set-receive-buffer-size: func

    +

    [method]tcp-socket.set-keep-alive-count: func

    Params
    Return values
    -

    [method]udp-socket.send-buffer-size: func

    -
    Params
    - -
    Return values
    +

    [method]tcp-socket.hop-limit: func

    +

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    +

    If the provided value is 0, an invalid-argument error is returned.

    +

    Typical errors

      -
    • result<u64, error-code>
    • +
    • invalid-argument: (set) The TTL value must be 1 or higher.
    • +
    • invalid-state: (set) The socket is already in the Connection state.
    • +
    • invalid-state: (set) The socket is already in the Listener state.
    -

    [method]udp-socket.set-send-buffer-size: func

    Params
    Return values
    -

    [method]udp-socket.subscribe: func

    -

    Create a pollable which will resolve once the socket is ready for I/O.

    -

    Note: this function is here for WASI Preview2 only. -It's planned to be removed when future is natively supported in Preview3.

    +

    [method]tcp-socket.set-hop-limit: func

    Params
    Return values
    -

    [method]incoming-datagram-stream.receive: func

    -

    Receive messages on the socket.

    -

    This function attempts to receive up to max-results datagrams on the socket without blocking. -The returned list may contain fewer elements than requested, but never more.

    -

    This function returns successfully with an empty list when either:

    +

    [method]tcp-socket.receive-buffer-size: func

    +

    The kernel buffer space reserved for sends/receives on this socket.

    +

    If the provided value is 0, an invalid-argument error is returned. +Any other value will never cause an error, but it might be silently clamped and/or rounded. +I.e. after setting a value, reading the same setting back may return a different value.

    +

    Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.

    +

    Typical errors

      -
    • max-results is 0, or:
    • -
    • max-results is greater than 0, but no results are immediately available. -This function never returns error(would-block).
    • +
    • invalid-argument: (set) The provided value was 0.
    • +
    • invalid-state: (set) The socket is already in the Connection state.
    • +
    • invalid-state: (set) The socket is already in the Listener state.
    -

    Typical errors

    +
    Params
      -
    • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
    • -
    • connection-refused: The connection was refused. (ECONNREFUSED)
    • +
    • self: borrow<tcp-socket>
    -

    References

    +
    Return values
    +

    [method]tcp-socket.set-receive-buffer-size: func

    Params
    Return values
    -

    [method]incoming-datagram-stream.subscribe: func

    -

    Create a pollable which will resolve once the stream is ready to receive again.

    -

    Note: this function is here for WASI Preview2 only. -It's planned to be removed when future is natively supported in Preview3.

    +

    [method]tcp-socket.send-buffer-size: func

    Params
    Return values
    -

    [method]outgoing-datagram-stream.check-send: func

    -

    Check readiness for sending. This function never blocks.

    -

    Returns the number of datagrams permitted for the next call to send, -or an error. Calling send with more datagrams than this function has -permitted will trap.

    -

    When this function returns ok(0), the subscribe pollable will -become ready when this function will report at least ok(1), or an -error.

    -

    Never returns would-block.

    +

    [method]tcp-socket.set-send-buffer-size: func

    Params
    Return values
    -

    [method]outgoing-datagram-stream.send: func

    -

    Send messages on the socket.

    -

    This function attempts to send all provided datagrams on the socket without blocking and -returns how many messages were actually sent (or queued for sending). This function never -returns error(would-block). If none of the datagrams were able to be sent, ok(0) is returned.

    -

    This function semantically behaves the same as iterating the datagrams list and sequentially -sending each individual datagram until either the end of the list has been reached or the first error occurred. -If at least one datagram has been sent successfully, this function never returns an error.

    -

    If the input list is empty, the function returns ok(0).

    -

    Each call to send must be permitted by a preceding check-send. Implementations must trap if -either check-send was not called or datagrams contains more items than check-send permitted.

    -

    Typical errors

    +

    [method]tcp-socket.subscribe: func

    +

    Create a pollable which will resolve once the socket is ready for I/O.

    +

    Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

    +
    Params
      -
    • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • -
    • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
    • -
    • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • -
    • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • -
    • invalid-argument: The socket is in "connected" mode and remote-address is some value that does not match the address passed to stream. (EISCONN)
    • -
    • invalid-argument: The socket is not "connected" and no value for remote-address was provided. (EDESTADDRREQ)
    • -
    • remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
    • -
    • connection-refused: The connection was refused. (ECONNREFUSED)
    • -
    • datagram-too-large: The datagram is too large. (EMSGSIZE)
    • +
    • self: borrow<tcp-socket>
    -

    References

    +
    Return values
    -
    Params
    +

    [method]tcp-socket.shutdown: func

    +

    Initiate a graceful shutdown.

    +
      +
    • receive: the socket is not expecting to receive any more data from the peer. All subsequent read +operations on the input-stream associated with this socket will return an End Of Stream indication. +Any data still in the receive queue at time of calling shutdown will be discarded.
    • +
    • send: the socket is not expecting to send any more data to the peer. All subsequent write +operations on the output-stream associated with this socket will return an error.
    • +
    • both: same effect as receive & send combined.
    • +
    +

    The shutdown function does not close (drop) the socket.

    +

    Typical errors

    -
    Return values
    +

    References

    -

    [method]outgoing-datagram-stream.subscribe: func

    -

    Create a pollable which will resolve once the stream is ready to send again.

    -

    Note: this function is here for WASI Preview2 only. -It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2023-11-10

    +

    Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2023-11-10


    Types

    type network

    @@ -2752,24 +2842,24 @@ It's planned to be removed when future is natively supported in Pre #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `type udp-socket` -[`udp-socket`](#udp_socket) +#### `type tcp-socket` +[`tcp-socket`](#tcp_socket)

    ----

    Functions

    -

    create-udp-socket: func

    -

    Create a new UDP socket.

    -

    Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.

    +

    create-tcp-socket: func

    +

    Create a new TCP socket.

    +

    Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX.

    This function does not require a network capability handle. This is considered to be safe because -at time of creation, the socket is not bound to any network yet. Up to the moment bind is called, -the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

    +at time of creation, the socket is not bound to any network yet. Up to the moment bind/listen/connect +is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

    All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

    Typical errors

    • not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
    -

    References:

    +

    References

    Params
    Return values
    +

    Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2023-11-10

    +
    +

    Types

    +

    type pollable

    +

    pollable

    +

    +#### `type network` +[`network`](#network) +

    +#### `type error-code` +[`error-code`](#error_code) +

    +#### `type ip-address` +[`ip-address`](#ip_address) +

    +#### `resource resolve-address-stream` +


    +

    Functions

    +

    resolve-addresses: func

    +

    Resolve an internet host name to a list of IP addresses.

    +

    Unicode domain names are automatically converted to ASCII using IDNA encoding. +If the input is an IP address string, the address is parsed and returned +as-is without making any external requests.

    +

    See the wasi-socket proposal README.md for a comparison with getaddrinfo.

    +

    This function never blocks. It either immediately fails or immediately +returns successfully with a resolve-address-stream that can be used +to (asynchronously) fetch the results.

    +

    Typical errors

    +
      +
    • invalid-argument: name is a syntactically invalid domain name or IP address.
    • +
    +

    References:

    + +
    Params
    + +
    Return values
    + +

    [method]resolve-address-stream.resolve-next-address: func

    +

    Returns the next address from the resolver.

    +

    This function should be called multiple times. On each call, it will +return the next address in connection order preference. If all +addresses have been exhausted, this function returns none.

    +

    This function never returns IPv4-mapped IPv6 addresses.

    +

    Typical errors

    +
      +
    • name-unresolvable: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY)
    • +
    • temporary-resolver-failure: A temporary failure in name resolution occurred. (EAI_AGAIN)
    • +
    • permanent-resolver-failure: A permanent failure in name resolution occurred. (EAI_FAIL)
    • +
    • would-block: A result is not available yet. (EWOULDBLOCK, EAGAIN)
    • +
    +
    Params
    + +
    Return values
    + +

    [method]resolve-address-stream.subscribe: func

    +

    Create a pollable which will resolve once the stream is ready for I/O.

    +

    Note: this function is here for WASI Preview2 only. +It's planned to be removed when future is natively supported in Preview3.

    +
    Params
    + +
    Return values
    +

    Import interface wasi:random/random@0.2.0-rc-2023-11-10

    WASI Random is a random data API.

    @@ -2870,137 +3040,3 @@ protection.

    • (u64, u64)
    -

    Import interface wasi:cli/environment@0.2.0-rc-2023-11-10

    -
    -

    Functions

    -

    get-environment: func

    -

    Get the POSIX-style environment variables.

    -

    Each environment variable is provided as a pair of string variable names -and string value.

    -

    Morally, these are a value import, but until value imports are available -in the component model, this import function should return the same -values each time it is called.

    -
    Return values
    -
      -
    • list<(string, string)>
    • -
    -

    get-arguments: func

    -

    Get the POSIX-style arguments to the program.

    -
    Return values
    -
      -
    • list<string>
    • -
    -

    initial-cwd: func

    -

    Return a path that programs should use as their initial current working -directory, interpreting . as shorthand for this.

    -
    Return values
    -
      -
    • option<string>
    • -
    -

    Import interface wasi:cli/exit@0.2.0-rc-2023-11-10

    -
    -

    Functions

    -

    exit: func

    -

    Exit the current instance and any linked instances.

    -
    Params
    - -

    Import interface wasi:cli/stdin@0.2.0-rc-2023-11-10

    -
    -

    Types

    -

    type input-stream

    -

    input-stream

    -

    ----- -

    Functions

    -

    get-stdin: func

    -
    Return values
    - -

    Import interface wasi:cli/stdout@0.2.0-rc-2023-11-10

    -
    -

    Types

    -

    type output-stream

    -

    output-stream

    -

    ----- -

    Functions

    -

    get-stdout: func

    -
    Return values
    - -

    Import interface wasi:cli/stderr@0.2.0-rc-2023-11-10

    -
    -

    Types

    -

    type output-stream

    -

    output-stream

    -

    ----- -

    Functions

    -

    get-stderr: func

    -
    Return values
    - -

    Import interface wasi:cli/terminal-input@0.2.0-rc-2023-11-10

    -
    -

    Types

    -

    resource terminal-input

    -

    Import interface wasi:cli/terminal-output@0.2.0-rc-2023-11-10

    -
    -

    Types

    -

    resource terminal-output

    -

    Import interface wasi:cli/terminal-stdin@0.2.0-rc-2023-11-10

    -

    An interface providing an optional terminal-input for stdin as a -link-time authority.

    -
    -

    Types

    -

    type terminal-input

    -

    terminal-input

    -

    ----- -

    Functions

    -

    get-terminal-stdin: func

    -

    If stdin is connected to a terminal, return a terminal-input handle -allowing further interaction with it.

    -
    Return values
    - -

    Import interface wasi:cli/terminal-stdout@0.2.0-rc-2023-11-10

    -

    An interface providing an optional terminal-output for stdout as a -link-time authority.

    -
    -

    Types

    -

    type terminal-output

    -

    terminal-output

    -

    ----- -

    Functions

    -

    get-terminal-stdout: func

    -

    If stdout is connected to a terminal, return a terminal-output handle -allowing further interaction with it.

    -
    Return values
    - -

    Import interface wasi:cli/terminal-stderr@0.2.0-rc-2023-11-10

    -

    An interface providing an optional terminal-output for stderr as a -link-time authority.

    -
    -

    Types

    -

    type terminal-output

    -

    terminal-output

    -

    ----- -

    Functions

    -

    get-terminal-stderr: func

    -

    If stderr is connected to a terminal, return a terminal-output handle -allowing further interaction with it.

    -
    Return values
    - diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index 74811d327..a46274bf5 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,7 +1,7 @@ package wasi:cli@0.2.0-rc-2023-11-10; world command { - include reactor; + include imports; export run; } diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index cbaafcb73..d8a765383 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -10,8 +10,8 @@ sha512 = "2c242489801a75466986fe014d730fb3aa7b5c6e56a230c8735e6672711b58bcbe92ba [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "f2e6127b235c37c06be675a904d6acf08db953ea688d78c42892c6ad3bd194e4" -sha512 = "32feefbc115c34bf6968cb6e9dc15e755698ee90648e5a5d84448917c36a318bd61b401195eb64330e2475e1d098bfb8dee1440d594a68e0797748762bd84ae5" +sha256 = "b622db2755978a49d18d35d84d75f66b2b1ed23d7bf413e5c9e152e190cc7d4b" +sha512 = "d19c9004e75bf3ebe3e34cff498c3d7fee04cd57a7fba7ed12a0c5ad842ba5715c009de77a152c57da0500f6ca0986b6791b6f022829bdd5a024f7bc114c2ff6" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit index bddde3c19..81b1cab99 100644 --- a/proposals/cli/wit/deps/io/poll.wit +++ b/proposals/cli/wit/deps/io/poll.wit @@ -3,7 +3,7 @@ package wasi:io@0.2.0-rc-2023-11-10; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { - /// `pollable` epresents a single I/O event which may be ready, or not. + /// `pollable` represents a single I/O event which may be ready, or not. resource pollable { /// Return the readiness of a pollable. This function never blocks. diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index e7e1b689a..f6f7fe0e8 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -131,7 +131,7 @@ interface streams { /// let pollable = this.subscribe(); /// while !contents.is_empty() { /// // Wait for the stream to become writable - /// poll-one(pollable); + /// pollable.block(); /// let Ok(n) = this.check-write(); // eliding error handling /// let len = min(n, contents.len()); /// let (chunk, rest) = contents.split_at(len); @@ -140,7 +140,7 @@ interface streams { /// } /// this.flush(); /// // Wait for completion of `flush` - /// poll-one(pollable); + /// pollable.block(); /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` @@ -178,7 +178,7 @@ interface streams { /// Write zeroes to a stream. /// - /// this should be used precisely like `write` with the exact same + /// This should be used precisely like `write` with the exact same /// preconditions (must use check-write first), but instead of /// passing a list of bytes, you simply pass the number of zero-bytes /// that should be written. @@ -199,7 +199,7 @@ interface streams { /// let pollable = this.subscribe(); /// while num_zeroes != 0 { /// // Wait for the stream to become writable - /// poll-one(pollable); + /// pollable.block(); /// let Ok(n) = this.check-write(); // eliding error handling /// let len = min(n, num_zeroes); /// this.write-zeroes(len); // eliding error handling @@ -207,7 +207,7 @@ interface streams { /// } /// this.flush(); /// // Wait for completion of `flush` - /// poll-one(pollable); + /// pollable.block(); /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` diff --git a/proposals/cli/wit/imports.wit b/proposals/cli/wit/imports.wit new file mode 100644 index 000000000..63dabfc37 --- /dev/null +++ b/proposals/cli/wit/imports.wit @@ -0,0 +1,20 @@ +package wasi:cli@0.2.0-rc-2023-11-10; + +world imports { + include wasi:clocks/imports@0.2.0-rc-2023-11-10; + include wasi:filesystem/imports@0.2.0-rc-2023-11-10; + include wasi:sockets/imports@0.2.0-rc-2023-11-10; + include wasi:random/imports@0.2.0-rc-2023-11-10; + include wasi:io/imports@0.2.0-rc-2023-11-10; + + import environment; + import exit; + import stdin; + import stdout; + import stderr; + import terminal-input; + import terminal-output; + import terminal-stdin; + import terminal-stdout; + import terminal-stderr; +} diff --git a/proposals/cli/wit/reactor.wit b/proposals/cli/wit/reactor.wit deleted file mode 100644 index eafa2fd49..000000000 --- a/proposals/cli/wit/reactor.wit +++ /dev/null @@ -1,31 +0,0 @@ -package wasi:cli@0.2.0-rc-2023-11-10; - -world reactor { - import wasi:clocks/wall-clock@0.2.0-rc-2023-11-10; - import wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10; - import wasi:filesystem/types@0.2.0-rc-2023-11-10; - import wasi:filesystem/preopens@0.2.0-rc-2023-11-10; - import wasi:sockets/instance-network@0.2.0-rc-2023-11-10; - import wasi:sockets/ip-name-lookup@0.2.0-rc-2023-11-10; - import wasi:sockets/network@0.2.0-rc-2023-11-10; - import wasi:sockets/tcp-create-socket@0.2.0-rc-2023-11-10; - import wasi:sockets/tcp@0.2.0-rc-2023-11-10; - import wasi:sockets/udp-create-socket@0.2.0-rc-2023-11-10; - import wasi:sockets/udp@0.2.0-rc-2023-11-10; - import wasi:random/random@0.2.0-rc-2023-11-10; - import wasi:random/insecure@0.2.0-rc-2023-11-10; - import wasi:random/insecure-seed@0.2.0-rc-2023-11-10; - import wasi:io/poll@0.2.0-rc-2023-11-10; - import wasi:io/streams@0.2.0-rc-2023-11-10; - - import environment; - import exit; - import stdin; - import stdout; - import stderr; - import terminal-input; - import terminal-output; - import terminal-stdin; - import terminal-stdout; - import terminal-stderr; -} From 7e94d37d538429c60c17626772c4eacd7102d155 Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Tue, 5 Dec 2023 10:13:32 -0800 Subject: [PATCH 1345/1772] Change `ms` params to `duration` --- proposals/http/wit/types.wit | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 00219e2c1..0f698e769 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -330,14 +330,14 @@ interface types { /// Set the timeout for the initial connect to the HTTP Server. An error /// return value indicates that this timeout is not supported. - set-connect-timeout: func(ms: option) -> result; + set-connect-timeout: func(duration: option) -> result; /// The timeout for receiving the first byte of the Response body. first-byte-timeout: func() -> option; /// Set the timeout for receiving the first byte of the Response body. An /// error return value indicates that this timeout is not supported. - set-first-byte-timeout: func(ms: option) -> result; + set-first-byte-timeout: func(duration: option) -> result; /// The timeout for receiving subsequent chunks of bytes in the Response /// body stream. @@ -346,7 +346,7 @@ interface types { /// Set the timeout for receiving subsequent chunks of bytes in the Response /// body stream. An error return value indicates that this timeout is not /// supported. - set-between-bytes-timeout: func(ms: option) -> result; + set-between-bytes-timeout: func(duration: option) -> result; } /// Represents the ability to send an HTTP Response. From 213f33dc6a066c8f3e63c1ad1c956efeef1eac41 Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Tue, 5 Dec 2023 10:42:28 -0800 Subject: [PATCH 1346/1772] Regenerate proxy.md --- proposals/http/proxy.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 1f6941764..b05200c27 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -1069,7 +1069,7 @@ return value indicates that this timeout is not supported.

    Params
    Return values

    [method]output-stream.write-zeroes: func

    Write zeroes to a stream.

    -

    this should be used precisely like write with the exact same +

    This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of passing a list of bytes, you simply pass the number of zero-bytes that should be written.

    @@ -373,7 +400,7 @@ the following pseudo-code:

    let pollable = this.subscribe();
     while num_zeroes != 0 {
       // Wait for the stream to become writable
    -  poll-one(pollable);
    +  pollable.block();
       let Ok(n) = this.check-write(); // eliding error handling
       let len = min(n, num_zeroes);
       this.write-zeroes(len);         // eliding error handling
    @@ -381,7 +408,7 @@ while num_zeroes != 0 {
     }
     this.flush();
     // Wait for completion of `flush`
    -poll-one(pollable);
    +pollable.block();
     // Check for any errors that arose during `flush`
     let _ = this.check-write();         // eliding error handling
     
    @@ -432,7 +459,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stdout@0.2.0-rc-2023-11-10

    +

    Import interface wasi:cli/stdout@0.2.0-rc-2023-12-05


    Types

    type output-stream

    @@ -445,7 +472,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stderr@0.2.0-rc-2023-11-10

    +

    Import interface wasi:cli/stderr@0.2.0-rc-2023-12-05


    Types

    type output-stream

    @@ -458,7 +485,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stdin@0.2.0-rc-2023-11-10

    +

    Import interface wasi:cli/stdin@0.2.0-rc-2023-12-05


    Types

    type input-stream

    @@ -532,7 +559,7 @@ occured.

    -

    Import interface wasi:http/types@0.2.0-rc-2023-11-10

    +

    Import interface wasi:http/types@0.2.0-rc-2023-12-05

    This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

    @@ -678,6 +705,15 @@ permitted because the fields are immutable. reality, HTTP implementations often have to interpret malformed values, so they are provided as a list of bytes.

    resource fields

    +

    This following block defines the fields resource which corresponds to +HTTP standard Fields. Fields are a common representation used for both +Headers and Trailers.

    +

    A fields may be mutable or immutable. A fields created using the +constructor, from-list, or clone will be mutable, but a fields +resource given by other means (including, but not limited to, +incoming-request.headers, outgoing-request.headers) might be be +immutable. In an immutable fields, the set, append, and delete +operations will fail with header-error.immutable.

    type headers

    fields

    Headers is an alias for Fields. @@ -685,19 +721,60 @@ so they are provided as a list of bytes.

    fields

    Trailers is an alias for Fields.

    resource incoming-request

    +

    Represents an incoming HTTP Request.

    resource outgoing-request

    +

    Represents an outgoing HTTP Request.

    resource request-options

    +

    Parameters for making an HTTP Request. Each of these parameters is +currently an optional timeout applicable to the transport layer of the +HTTP protocol.

    +

    These timeouts are separate from any the user may use to bound a +blocking call to wasi:io/poll.poll.

    resource response-outparam

    +

    Represents the ability to send an HTTP Response.

    +

    This resource is used by the wasi:http/incoming-handler interface to +allow a Response to be sent corresponding to the Request provided as the +other argument to incoming-handler.handle.

    type status-code

    u16

    This type corresponds to the HTTP standard Status Code.

    resource incoming-response

    +

    Represents an incoming HTTP Response.

    resource incoming-body

    +

    Represents an incoming HTTP Request or Response's Body.

    +

    A body has both its contents - a stream of bytes - and a (possibly +empty) set of trailers, indicating that the full contents of the +body have been received. This resource represents the contents as +an input-stream and the delivery of trailers as a future-trailers, +and ensures that the user of this interface may only be consuming either +the body contents or waiting on trailers at any given time.

    resource future-trailers

    +

    Represents a future which may eventaully return trailers, or an error.

    +

    In the case that the incoming HTTP Request or Response did not have any +trailers, this future will resolve to the empty set of trailers once the +complete Request or Response body has been received.

    resource outgoing-response

    +

    Represents an outgoing HTTP Response.

    resource outgoing-body

    +

    Represents an outgoing HTTP Request or Response's Body.

    +

    A body has both its contents - a stream of bytes - and a (possibly +empty) set of trailers, inducating the full contents of the body +have been sent. This resource represents the contents as an +output-stream child resource, and the completion of the body (with +optional trailers) with a static function that consumes the +outgoing-body resource, and ensures that the user of this interface +may not write to the body contents after the body has been finished.

    +

    If the user code drops this resource, as opposed to calling the static +method finish, the implementation should treat the body as incomplete, +and that an error has occured. The implementation should propogate this +error to the HTTP protocol by whatever means it has available, +including: corrupting the body on the wire, aborting the associated +Request, or sending a late status code for the Response.

    resource future-incoming-response

    -
    +

    Represents a future which may eventaully return an incoming HTTP +Response, or an error.

    +

    This resource is returned by the wasi:http/outgoing-handler interface to +provide the HTTP Response corresponding to the sent Request.

    Functions

    http-error-code: func

    Attempts to extract a http-related error from the wasi:io error @@ -1368,7 +1445,7 @@ but those will be reported by the incoming-body

  • option<result<result<own<incoming-response>, error-code>>>
  • -

    Import interface wasi:http/outgoing-handler@0.2.0-rc-2023-11-10

    +

    Import interface wasi:http/outgoing-handler@0.2.0-rc-2023-12-05

    This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


    @@ -1446,7 +1523,7 @@ also known as Unix Time.
  • datetime
  • -

    Export interface wasi:http/incoming-handler@0.2.0-rc-2023-11-10

    +

    Export interface wasi:http/incoming-handler@0.2.0-rc-2023-12-05


    Types

    type incoming-request

    From 6321140f2d66ff1e1bcb3dfcd60ded31112e96bd Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 5 Dec 2023 14:33:34 -0800 Subject: [PATCH 1353/1772] CI: upgrade to using wit-bindgen 0.15.0 --- proposals/http/.github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index cb189df77..ed406c5c4 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -17,3 +17,5 @@ jobs: chmod +x ./wit-deps ./wit-deps lock --check - uses: WebAssembly/wit-abi-up-to-date@v16 + with: + wit-bindgen: '0.15.0' From 6e192947da586b560795450217b0e7ff6e7f3462 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 3 Jan 2024 10:49:05 +0100 Subject: [PATCH 1354/1772] Make SO_REUSEADDR the default for TCP sockets --- proposals/sockets/imports.md | 4 ++++ proposals/sockets/wit/tcp.wit | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 497f48d03..f0fa5c369 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -1190,6 +1190,10 @@ implicitly bind the socket.

  • not-in-progress: A bind operation is not in progress.
  • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
  • +

    Implementors note

    +

    When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT +state of a recently closed socket on the same local address (i.e. the SO_REUSEADDR socket +option should be set implicitly on platforms that require it).

    References

    • https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
    • diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index b01b65e6c..976b272c0 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -42,6 +42,11 @@ interface tcp { /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) /// - `not-in-progress`: A `bind` operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # Implementors note + /// When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT + /// state of a recently closed socket on the same local address (i.e. the SO_REUSEADDR socket + /// option should be set implicitly on platforms that require it). /// /// # References /// - From 09092d06b206422897858e760a74d3cd7ec6e0b8 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 3 Jan 2024 13:06:58 +0100 Subject: [PATCH 1355/1772] Update Posix-compatibility.md: - Reformat socket option table layout to eliminate horizontal scrolling. - Update socket option support checkboxes. - Added tracking issue numbers for socket options that on the surface seem reasonable to add to WASI. - Updated methods&interfaces to their current names - Minor clarifications --- proposals/sockets/Posix-compatibility.md | 963 ++++++++++++----------- 1 file changed, 483 insertions(+), 480 deletions(-) diff --git a/proposals/sockets/Posix-compatibility.md b/proposals/sockets/Posix-compatibility.md index 4e4f202ae..2c0330047 100644 --- a/proposals/sockets/Posix-compatibility.md +++ b/proposals/sockets/Posix-compatibility.md @@ -6,11 +6,11 @@ This document provides an overview of the POSIX interface along with common non- ## General ### I/O completion polling (`poll`, `select`, `pselect`, `epoll_*` (non-standard), `kqueue` (non-standard)) -Use [`tcp::subscribe`][tcp]/[`udp::subscribe`][udp] to obtain a `pollable` handle. Then use that to wait for IO events using the [wasi-poll][poll] interface. +Use the various `subscribe` methods to obtain a `pollable` handle. Then use that to wait for IO events using the [wasi:io/poll][poll] interface. ### Non-blocking mode (`FIONBIO`, `SOCK_NONBLOCK`, `O_NONBLOCK`) All WASI sockets are non-blocking and can not be configured to block. -Blocking behaviour can be recreated in userland (or in wasi-libc) by repeatedly calling [`poll::poll-oneoff`][poll] until the operation is complete. +Blocking behaviour can be recreated in userland (or in wasi-libc) by calling [pollable::block][poll] on the relevant pollable. ### TCP urgent data (`sockatmark`, `MSG_OOB`, `SO_OOBINLINE`, `SIOCATMARK`) Out-of-band (OOB) data is currently not included in this proposal. Application-level usage of the TCP "urgent" flag is rare in practice and discouraged in general. Including it in WASI would probably interfere with the ability to use WASI/ComponentModel `stream`s. @@ -35,52 +35,56 @@ Not included in proposal. WASI has no concept of UNIX-style processes. - UDP: [`create-udp-socket`][udp-create-socket] ### `connect` -- TCP: [`tcp::start-connect`][tcp] & [`tcp::finish-connect`][tcp] -- UDP: [`udp::start-connect`][udp] & [`udp::finish-connect`][udp] +- TCP: [`tcp-socket::start-connect`][tcp] & [`tcp-socket::finish-connect`][tcp] +- UDP: [`udp-socket::start-connect`][udp] & [`udp-socket::finish-connect`][udp] ### `bind` -- TCP: [`tcp::start-bind`][tcp] & [`tcp::finish-bind`][tcp] -- UDP: [`udp::start-bind`][udp] & [`udp::finish-bind`][udp] +- TCP: [`tcp-socket::start-bind`][tcp] & [`tcp-socket::finish-bind`][tcp] +- UDP: [`udp-socket::start-bind`][udp] & [`udp-socket::finish-bind`][udp] ### `listen` -- TCP: [`tcp::start-listen`][tcp] & [`tcp::finish-listen`][tcp]. The `backlog` parameter has been split out into a distinct function [`tcp::set-listen-backlog-size`][tcp] ([See #34](https://github.com/WebAssembly/wasi-sockets/issues/34)). +- TCP: [`tcp-socket::start-listen`][tcp] & [`tcp-socket::finish-listen`][tcp]. The `backlog` parameter has been split out into a distinct function [`tcp-socket::set-listen-backlog-size`][tcp] ([See #34][34]). - UDP: N/A ### `accept`, `accept4` (non-standard) -- TCP: [`tcp::accept`][tcp] +- TCP: [`tcp-socket::accept`][tcp] - UDP: N/A -To collect the remote address, call [`tcp::remote-address`][tcp] on the newly accepted client socket. +To collect the remote address, call `tcp-socket::remote-address` on the newly accepted client socket. Some platforms provide an `accept4` variant with additional flags. None of these flags make sense in the context of this proposal. See [SOCK_NONBLOCK](#nonblock) & [SOCK_CLOEXEC](#cloexec). ### `getsockname`, `getpeername` -- TCP: [`tcp::local-address`][tcp] & [`tcp::remote-address`][tcp] -- UDP: [`udp::local-address`][udp] & [`udp::remote-address`][udp] +- TCP: [`tcp-socket::local-address`][tcp] & [`tcp-socket::remote-address`][tcp] +- UDP: [`udp-socket::local-address`][udp] & [`udp-socket::remote-address`][udp] ### `read`, `readv`, `recv`, `recvfrom`, `recvmsg`, `recvmmsg` (non-standard) -TCP sockets can be read using [`streams::(blocking-)read`][streams]. UDP sockets can be read using [`udp::receive`][udp]. +TCP sockets can be read using the `input-stream` returned by connect or accept. +UDP sockets can be read using the `incoming-datagram-stream` returned by `udp-socket::stream`. -The various POSIX functions should be implementable on top of these two functions. +The various POSIX functions should be implementable on top of these two resources. None of the flags are directly present in WASI Sockets: - `MSG_DONTWAIT`: This is [always the case](#nonblock). - `MSG_OOB` on TCP sockets: [Not supported](#oob) - `MSG_OOB` on UDP sockets: N/A - `MSG_PEEK`: [No direct support](#peek) -- `MSG_TRUNC on TCP sockets: N/A +- `MSG_TRUNC` on TCP sockets: N/A - `MSG_TRUNC` on UDP sockets: Not needed, the returned data array always has the exact perfect size. - `MSG_WAITALL` on TCP sockets: Emulatable in userspace. - `MSG_WAITALL` on UDP sockets: N/A - `MSG_EOR`: N/A (not supported on TCP & UDP sockets) - `MSG_CMSG_CLOEXEC`: N/A (only used on Unix domain sockets) +Receiving ancillary messages: None supported as of yet. But see the various "RECV" socket options below. + ### `write`, `writev`, `send`, `sendto`, `sendmsg`, `sendmmsg` (non-standard) -TCP sockets can be written to using [`streams::(blocking-)write`][streams]. UDP sockets can be written to using [`udp::send`][udp]. +TCP sockets can be written to using the `output-stream` returned by connect or accept. +UDP sockets can be written to using the `outgoing-datagram-stream` returned by `udp-socket::stream`. -The various POSIX functions should be implementable on top of these two functions. +The various POSIX functions should be implementable on top of these two resources. None of the flags are directly present in WASI Sockets: - `MSG_DONTROUTE`: Not included in proposal at the moment. @@ -90,13 +94,14 @@ None of the flags are directly present in WASI Sockets: - `MSG_OOB` on UDP sockets: N/A - `MSG_EOR`: N/A (not supported on TCP & UDP sockets) +Sending ancillary messages: None supported as of yet. ### `sendfile` (non-standard) -- TCP: Part of the WASI Streams proposal as [`output-stream::forward`][streams] +- TCP: Part of the [wasi:io/streams][streams] proposal as `output-stream::splice` - UDP: N/A ### `shutdown` -- TCP: [`tcp::shutdown`][tcp] +- TCP: [`tcp-socket::shutdown`][tcp] - UDP: N/A ### `sockatmark` @@ -104,7 +109,7 @@ None of the flags are directly present in WASI Sockets: - UDP: N/A ### `close` -Dropping a handle performs an effective `close`. +Dropping the socket resource effectively performs a `close`. ### `socketpair`, `connectat` (non-standard), `bindat` (non-standard) Specifically for UNIX domain sockets. Out of scope for this proposal. @@ -115,7 +120,7 @@ Specifically for UNIX domain sockets. Out of scope for this proposal. ### `ioctl` - `SIOCATMARK`: [Not included](#oob). -- `FIONREAD`: Currently not included. See [#17](https://github.com/WebAssembly/wasi-sockets/issues/17). +- `FIONREAD`: Currently not included. See [#17][17]. ### `getsockopt`, `setsockopt` Socket options have been split out into distinct functions. See table below. @@ -132,466 +137,464 @@ The results are not intended to be an exhaustive overview of all possible networ Additionally, most columns have been populated semi-automatically by grepping through the respective codebases. The results have not been manually verified and therefore may not be 100% correct. -Columns: -- "Socket option": The native option constant. -- "WASI": - - ✅ = Included in proposal. - - ⛔ = Consciously decided _not_ to include in WASI. See notes for explanation. - - ❔ = Not included (yet), for no particular reason. -- The rest: - - ✅ = Option is provided by the platform / depended upon by the application. - - ❌ = Option is not provided / not used. - -> Note: GitHub clips the table content. Scroll left and right to see all columns, or use the Code View. - -| Option | WASI | POSIX | Linux | Windows | MacOS | FreeBSD | JVM | .NET | Rust | Node.js | Go | OpenSSL | nginx | curl | msquic | exim | Notes | -|---------------------------------|-----------|--------|--------|---------|---------|---------|-------|--------|-------|---------|-----|----------|-------|-------|--------|-------|-| -| SO_ERROR | ⛔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | Not necessary. WIT has (or will have) native support for asynchronous results. | -| SO_DOMAIN | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | [`tcp::address-family`][tcp]
      [`udp::address-family`][udp]

      SO_PROTOCOL_INFO on Windows. | -| SO_TYPE | ✅* | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | * indirectly through the type of the socket resource. | -| SO_PROTOCOL | ✅* | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | * indirectly through the type of the socket resource. SO_PROTOCOL_INFO on Windows. | -| SO_ACCEPTCONN | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_V6ONLY | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | [`tcp::(set-)ipv6-only`][tcp]
      [`udp::(set-)ipv6-only`][udp] | -| IP_HDRINCL | ⛔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Out of scope. Raw sockets only. | -| IPV6_HDRINCL | ⛔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Out of scope. Raw sockets only. | -| IP_TTL | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | [`tcp::(set-)unicast-hop-limit`][tcp]
      [`udp::(set-)unicast-hop-limit`][udp] | -| IPV6_UNICAST_HOPS | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | [`tcp::(set-)unicast-hop-limit`][tcp]
      [`udp::(set-)unicast-hop-limit`][udp] | -| IP_RECVTTL | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RECVHOPLIMIT | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_TOS | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | -| IPV6_TCLASS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | -| IP_RECVTOS | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | -| IPV6_RECVTCLASS | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | -| IP_RECVPKTINFO | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | IP_PKTINFO on Linux & Windows, IP_RECVDSTADDR+IP_RECVIF on MacOS & FreeBSD. | -| IPV6_RECVPKTINFO | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | IPV6_PKTINFO on Windows. | -| IP_DONTFRAG | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | IP_DONTFRAGMENT on Windows, implementable using IP_MTU_DISCOVER on Linux. | -| IPV6_DONTFRAG | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | | -| IP_MTU_DISCOVER | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | | -| IPV6_MTU_DISCOVER | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | | -| SO_RCVBUF | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | [`tcp::(set-)receive-buffer-size`][tcp]
      [`udp::(set-)receive-buffer-size`][udp] | -| SO_SNDBUF | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | [`tcp::(set-)send-buffer-size`][tcp]
      [`udp::(set-)send-buffer-size`][udp] | -| SO_RCVLOWAT | ❔ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_SNDLOWAT | ❔ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| SO_RCVTIMEO | ⛔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | WASI sockets are always non-blocking. Timeouts can be recreated in libc. | -| SO_SNDTIMEO | ⛔ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | WASI sockets are always non-blocking. Timeouts can be recreated in libc. | -| SO_KEEPALIVE | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | [`tcp::(set-)keep-alive`][tcp] | -| TCP_KEEPCNT | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| TCP_KEEPIDLE | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | TCP_KEEPALIVE on MacOS | -| TCP_KEEPINTVL | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | | -| TCP_NODELAY | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | [`tcp::(set-)no-delay`][tcp] | -| TCP_CORK | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ | TCP_NOPUSH on MacOS & FreeBSD | -| SO_LINGER | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | | -| SO_OOBINLINE | ⛔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Not supported, see [OOB](#oob) | -| SO_DEBUG | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_DONTROUTE | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_REUSEADDR | ❔ | ✅ | ✅ | ✅* | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | Roughly equivalent to the inverse of SO_EXCLUSIVEADDRUSE on Windows. | -| SO_REUSEPORT | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | | -| SO_REUSEPORT_LB | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| IP_BIND_ADDRESS_NO_PORT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | | -| SO_ATTACH_REUSEPORT_CBPF | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | -| SO_ATTACH_REUSEPORT_EBPF | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| SO_DETACH_REUSEPORT_BPF | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_REUSPORT_LB_NUMA | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_BROADCAST | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_ADD_MEMBERSHIP | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_JOIN_GROUP | -| IPV6_JOIN_GROUP | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_JOIN_GROUP, alias of IPV6_ADD_MEMBERSHIP | -| IP_ADD_SOURCE_MEMBERSHIP | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_JOIN_SOURCE_GROUP | -| IP_DROP_MEMBERSHIP | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_LEAVE_GROUP | -| IPV6_LEAVE_GROUP | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_LEAVE_GROUP, alias of IPV6_DROP_MEMBERSHIP | -| IP_DROP_SOURCE_MEMBERSHIP | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_LEAVE_SOURCE_GROUP | -| IP_MULTICAST_IF | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_MULTICAST_IF | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_MULTICAST_LOOP | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_MULTICAST_LOOP | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_MULTICAST_TTL | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_MULTICAST_HOPS | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_BLOCK_SOURCE | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_BLOCK_SOURCE | -| IP_UNBLOCK_SOURCE | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Equivalent to MCAST_UNBLOCK_SOURCE | -| IP_MSFILTER | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_INFO | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ | | -| TCP_FASTOPEN | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | | -| TCP_FASTOPEN_CONNECT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ✅ | | -| TCP_FASTOPEN_KEY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_FASTOPEN_NO_COOKIE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_FASTOPEN_FORCE_ENABLE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_FASTOPEN_FORCE_HEURISTICS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_BINDTODEVICE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | | -| SO_BINDTOIFINDEX | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_BOUND_IF | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_BOUND_IF | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_IPSEC_POLICY | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_MINTTL | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_MINHOPCOUNT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_MTU | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_MTU | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_PATHMTU | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RECVPATHMTU | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_USE_MIN_MTU | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_OPTIONS | ❔ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | -| IP_RECVOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_RECVORIGDSTADDR | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | IP_ORIGDSTADDR on FreeBSD | -| IP_RECVRETOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Alias of IP_RETOPTS | -| IP_UNICAST_IF | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | -| IPV6_UNICAST_IF | ❔ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | -| IPV6_2292DSTOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_2292HOPLIMIT | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_2292HOPOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_2292PKTINFO | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_2292PKTOPTIONS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_2292RTHDR | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_AUTOFLOWLABEL | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_CHECKSUM | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_DSTOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_HOPOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_IPSEC_POLICY | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_NEXTHOP | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RECVDSTOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RECVHOPOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RECVORIGDSTADDR | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | IPV6_ORIGDSTADDR on FreeBSD | -| IPV6_RECVRTHDR | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RTHDR | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RTHDRDSTOPTS | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TIMESTAMP | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_CONGESTION | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_MAXSEG | ❔ | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_MD5SIG | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_NOTSENT_LOWAT | ❔ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| UDP_ENCAP | ❔ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_CHECKSUM | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_FREEBIND | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_MULTICAST_ALL | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_NODEFRAG | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_PASSSEC | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_PKTOPTIONS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_RECVERR | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_RECVERR_RFC4884 | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_RECVFRAGSIZE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_ROUTER_ALERT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_TRANSPARENT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| IP_XFRM_POLICY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_ADDR_PREFERENCES | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_ADDRFORM | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_AUTHHDR | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_FLOWINFO | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_FLOWINFO_SEND | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_FLOWLABEL_MGR | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_FREEBIND | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_JOIN_ANYCAST | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_LEAVE_ANYCAST | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_MULTICAST_ALL | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RECVERR | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RECVERR_RFC4884 | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RECVFRAGSIZE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_ROUTER_ALERT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_ROUTER_ALERT_ISOLATE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_TRANSPARENT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| IPV6_XFRM_POLICY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_ATTACH_FILTER | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_BPF_EXTENSIONS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_BSDCOMPAT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_BUF_LOCK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_BUSY_POLL | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_BUSY_POLL_BUDGET | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_CNX_ADVICE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_COOKIE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| SO_DETACH_FILTER | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_INCOMING_CPU | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_INCOMING_NAPI_ID | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_LOCK_FILTER | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_MARK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_MEMINFO | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NETNS_COOKIE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NO_CHECK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NOFCS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_PASSCRED | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_PASSSEC | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_PEEK_OFF | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_PEERCRED | ⛔ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Out of scope; UNIX domain sockets only. | -| SO_PEERNAME | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_PEERSEC | ⛔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | Out of scope; UNIX domain sockets only. | -| SO_PREFER_BUSY_POLL | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_PRIORITY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_RCVBUFFORCE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_RCVMARK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_RESERVE_MEM | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_RXQ_OVFL | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_SELECT_ERR_QUEUE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_SNDBUFFORCE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TIMESTAMPING | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TIMESTAMPNS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TXREHASH | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TXTIME | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_WIFI_STATUS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_ZEROCOPY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_CC_INFO | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_CM_INQ | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_DEFER_ACCEPT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| TCP_INQ | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_LINGER2 | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_MD5SIG_EXT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_QUEUE_SEQ | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_QUICKACK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | -| TCP_REPAIR | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_REPAIR_OPTIONS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_REPAIR_QUEUE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_REPAIR_WINDOW | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_SAVE_SYN | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_SAVED_SYN | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_SYNCNT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_THIN_DUPACK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_THIN_LINEAR_TIMEOUTS | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_TIMESTAMP | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_TX_DELAY | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_ULP | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_USER_TIMEOUT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_WINDOW_CLAMP | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_ZEROCOPY_RECEIVE | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| UDP_CORK | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| UDP_GRO | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | -| UDP_NO_CHECK6_RX | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| UDP_NO_CHECK6_TX | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| UDP_SEGMENT | ❔ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| IP_ADD_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_DEL_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_GET_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_ORIGINAL_ARRIVAL_IF | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_ORIGINAL_ARRIVAL_IF | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_RECEIVE_BROADCAST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_USER_MTU | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_WFP_REDIRECT_CONTEXT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_WFP_REDIRECT_RECORDS | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_ADD_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_DEL_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_GET_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_IFLIST | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_PROTECTION_LEVEL | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RECVIF | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_USER_MTU | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_BSP_STATE | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_CONDITIONAL_ACCEPT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_CONNDATA | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_CONNDATALEN | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_CONNECT_TIME | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_CONNOPT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_CONNOPTLEN | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_DISCDATA | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_DISCDATALEN | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_DISCOPT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_DISCOPTLEN | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_GROUP_ID | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_GROUP_PRIORITY | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_MAX_MSG_SIZE | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_MAXDG | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_MAXPATHDG | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_OPENTYPE | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_PAUSE_ACCEPT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_PORT_SCALABILITY | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_PROTOCOL_INFO | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_PROTOCOL_INFOA | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_PROTOCOL_INFOW | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_RANDOMIZE_PORT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_REUSE_MULTICASTPORT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_REUSE_UNICASTPORT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_UPDATE_ACCEPT_CONTEXT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_UPDATE_CONNECT_CONTEXT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_BSDURGENT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_EXPEDITED_1122 | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_FAIL_CONNECT_ON_ICMP_ERROR | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_ICMP_ERROR_INFO | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_MAXRT | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_TIMESTAMPS | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| UDP_CHECKSUM_COVERAGE | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| UDP_NOCHECKSUM | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| UDP_RECV_MAX_COALESCED_SIZE | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | -| UDP_SEND_MSG_SIZE | ❔ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | -| IP_FAITH | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_MULTICAST_IFINDEX | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_NAT__XXX | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_STRIPHDR | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_TRAFFIC_MGT_BACKGROUND | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_3542DSTOPTS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_3542HOPLIMIT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_3542HOPOPTS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_3542NEXTHOP | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_3542PKTINFO | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_3542RTHDR | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RTHDR_LOOSE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RTHDR_STRICT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RTHDR_TYPE_0 | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_AWDL_UNRESTRICTED | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_CFIL_SOCK_ID | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_DELEGATED | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_DELEGATED_UUID | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_DONTTRUNC | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_EXECPATH | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_EXTENDED_BK_IDLE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_FLOW_DIVERT_TOKEN | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_FLUSH | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_INTCOPROC_ALLOW | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_LINGER_SEC | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_MARK_CELLFALLBACK | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_MPKL_SEND_INFO | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NECP_ATTRIBUTES | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NECP_CLIENTUUID | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NECP_LISTENUUID | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NET_SERVICE_TYPE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NETSVC_MARKING_LEVEL | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NKE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NOADDRERR | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NOAPNFALLBK | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NOTIFYCONFLICT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NOWAKEFROMSLEEP | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NP_EXTENSIONS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NREAD | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NUMRCVPKT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NWRITE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_OPPORTUNISTIC | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_QOSMARKING_POLICY_OVERRIDE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_RANDOMPORT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_RECV_ANYIF | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_RESTRICTIONS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_REUSESHAREUID | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_STATISTICS_EVENT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TC_NET_SERVICE_OFFSET | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TC_NETSVC_SIG | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TIMESTAMP_CONTINUOUS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TIMESTAMP_MONOTONIC | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TRAFFIC_MGT_BACKGROUND | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_UPCALLCLOSEWAIT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_WANT_KEV_SOCKET_CLOSED | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_WANTMORE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_WANTOOBFLAG | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| MPTCP_ALTERNATE_PORT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| MPTCP_EXPECTED_PROGRESS_TARGET | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| MPTCP_FORCE_ENABLE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| MPTCP_FORCE_VERSION | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| MPTCP_SERVICE_TYPE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| PERSIST_TIMEOUT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_ADAPTIVE_READ_TIMEOUT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_ADAPTIVE_WRITE_TIMEOUT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_CONNECTION_INFO | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_CONNECTIONTIMEOUT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_DISABLE_BLACKHOLE_DETECTION | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_ECN_MODE | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_ENABLE_ECN | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_KEEPALIVE_OFFLOAD | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_MEASURE_BW_BURST | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_MEASURE_SND_BW | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_NOTIFY_ACKNOWLEDGEMENT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_NOTIMEWAIT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_PEER_PID | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_RXT_CONNDROPTIME | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_RXT_FINDROP | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_RXT_MINIMUM_TIMEOUT | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_SENDMOREACKS | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| UDP_KEEPALIVE_OFFLOAD | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| UDP_NOCKSUM | ❔ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| ICMP6_FILTER | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_MULTICAST_VIF | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_PORTRANGE | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_RSVP_OFF | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_RSVP_ON | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_RSVP_VIF_OFF | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_RSVP_VIF_ON | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_2292NEXTHOP | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_BINDV6ONLY | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_FAITH | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_MSFILTER | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_PKTOPTIONS | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_PORTRANGE | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_PREFER_TEMPADDR | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RECVRTHDRDSTOPTS | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_ACCEPTFILTER | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| SO_LABEL | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NOSIGPIPE | ⛔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | Not supported, see [SIGPIPE](#sigpipe) | -| SO_PEERLABEL | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_USELOOPBACK | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_NOOPT | ❔ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_BINDANY | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| IP_BINDMULTI | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_FLOWID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_FLOWTYPE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_MAX_MEMBERSHIPS | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_ONESBCAST | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_RECVFLOWID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_RECVRSSBUCKETID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_RSS_LISTEN_BUCKET | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_RSSBUCKETID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IP_SENDSRCADDR | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| IP_VLAN_PCP | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_AUTH_LEVEL | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_BINDANY | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| IPV6_BINDMULTI | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_ESP_NETWORK_LEVEL | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_ESP_TRANS_LEVEL | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_FLOWID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_FLOWTYPE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_IPCOMP_LEVEL | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RECVFLOWID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RECVRSSBUCKETID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RSS_LISTEN_BUCKET | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_RSSBUCKETID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| IPV6_VLAN_PCP | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_BINTIME | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_LISTENINCQLEN | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_LISTENQLEN | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | -| SO_LISTENQLIMIT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_MAX_PACING_RATE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NO_DDP | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_NO_OFFLOAD | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_RERROR | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_SETFIB | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | -| SO_TS_BINTIME | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TS_CLOCK | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TS_CLOCK_MAX | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TS_DEFAULT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TS_MONOTONIC | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TS_REALTIME | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_TS_REALTIME_MICRO | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| SO_USER_COOKIE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_CCALGOOPT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_DEFER_OPTIONS | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_DELACK | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_FAST_RSM_HACK | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_FIN_IS_RST | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_FUNCTION_ALIAS | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_FUNCTION_BLK | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_HDWR_RATE_CAP | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_HDWR_UP_ONLY | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_IDLE_REDUCE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_IWND_NB | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_IWND_NSEG | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_KEEPINIT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_LOG | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_LOG_LIMIT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_LOG_TAG | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_LOGBUF | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_LOGDUMP | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_LOGDUMPID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_LOGID | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_LOGID_CNT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_LRD | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_MAXPEAKRATE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_MAXUNACKTIME | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_PCAP_IN | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_PCAP_OUT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_PERF_INFO | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_PROC_ACCOUNTING | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_REMOTE_UDP_ENCAPS_PORT | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_RXTLS_ENABLE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_RXTLS_MODE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_STATS | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_TXTLS_ENABLE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_TXTLS_MODE | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_USE_CMP_ACKS | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| TCP_USER_LOG | ❔ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | - - - - - - +Legend: +- ✅ = Included in proposal. +- ⛔ = Consciously decided _not_ to include in WASI. See notes for explanation. +- ❔ = Not included (yet), for no particular reason. + + +| | Option | Notes | Used/implemented by | +|----| ---------------------------------|-----------------------------------------|---------------------| +| ✅ | SO_DOMAIN
      SO_PROTOCOL_INFO on Windows | [`tcp-socket::address-family`][tcp]
      [`udp-socket::address-family`][udp] | linux, windows, freebsd, .net | +| ✅ | SO_ACCEPTCONN | [`tcp-socket::is-listening`][tcp] | posix, linux, windows, macos, freebsd, .net | +| ✅ | IPV6_V6ONLY | [`tcp-socket::(set-)ipv6-only`][tcp]
      [`udp-socket::(set-)ipv6-only`][udp] | posix, linux, windows, macos, freebsd, jvm, .net, libuv, go, openssl, curl, msquic, exim | +| ✅ | IP_TTL | [`tcp-socket::(set-)hop-limit`][tcp]
      [`udp-socket::(set-)unicast-hop-limit`][udp] | linux, windows, macos, freebsd, jvm, .net, rust, libuv | +| ✅ | IPV6_UNICAST_HOPS | [`tcp-socket::(set-)hop-limit`][tcp]
      [`udp-socket::(set-)unicast-hop-limit`][udp] | posix, linux, windows, macos, freebsd, jvm, .net, libuv | +| ✅ | SO_RCVBUF | [`tcp-socket::(set-)receive-buffer-size`][tcp]
      [`udp-socket::(set-)receive-buffer-size`][udp] | posix, linux, windows, macos, freebsd, jvm, .net, libuv, go, nginx, msquic | +| ✅ | SO_SNDBUF | [`tcp-socket::(set-)send-buffer-size`][tcp]
      [`udp-socket::(set-)send-buffer-size`][udp] | posix, linux, windows, macos, freebsd, jvm, .net, libuv, go, nginx, curl | +| ✅ | SO_KEEPALIVE | [`tcp-socket::(set-)keep-alive-enabled`][tcp] | posix, linux, windows, macos, freebsd, jvm, .net, libuv, go, openssl, nginx, curl, exim | +| ✅ | TCP_KEEPIDLE
      TCP_KEEPALIVE on MacOS | [`tcp-socket::(set-)keep-alive-idle-time`][tcp] | linux, windows, macos, freebsd, jvm, .net, libuv, go, nginx, curl | +| ✅ | TCP_KEEPINTVL | [`tcp-socket::(set-)keep-alive-interval`][tcp] | linux, windows, macos, freebsd, jvm, .net, libuv, go, nginx, curl | +| ✅ | TCP_KEEPCNT | [`tcp-socket::(set-)keep-alive-count`][tcp] | linux, windows, macos, freebsd, jvm, .net, libuv, nginx | +| ⛔ | SO_ERROR | Not necessary. WIT has (or will have) native support for asynchronous results. | posix, linux, windows, macos, freebsd, jvm, .net, rust, libuv, go, openssl, nginx, curl, msquic | +| ⛔ | SO_TYPE | Can be inferred from the socket resource type. | posix, linux, windows, macos, freebsd, jvm, .net, go, openssl, nginx, curl, exim | +| ⛔ | SO_PROTOCOL
      SO_PROTOCOL_INFO on Windows | Can be inferred from the socket resource type. | linux, windows, freebsd, .net, exim | +| ⛔ | IP_HDRINCL | Out of scope. Raw sockets only. | linux, windows, macos, freebsd, .net | +| ⛔ | IPV6_HDRINCL | Out of scope. Raw sockets only. | linux, windows, .net | +| ⛔ | SO_RCVTIMEO | WASI sockets are always non-blocking. Timeouts can be recreated in libc. | posix, linux, windows, macos, freebsd, jvm, .net, rust, openssl, curl | +| ⛔ | SO_SNDTIMEO | WASI sockets are always non-blocking. Timeouts can be recreated in libc. | posix, windows, macos, freebsd, .net, rust, openssl | +| ⛔ | SO_OOBINLINE | Not supported, see [OOB](#oob) | posix, linux, windows, macos, freebsd, jvm, .net | +| ⛔ | SO_PEERCRED | Out of scope; UNIX domain sockets only. | linux, jvm, .net | +| ⛔ | SO_PEERSEC | Out of scope; UNIX domain sockets only. | linux | +| ⛔ | SO_NOSIGPIPE | Not supported, see [SIGPIPE](#sigpipe) | macos, freebsd, libuv, curl | +| ❔ | IP_RECVPKTINFO
      IP_PKTINFO on Linux & Windows
      IP_RECVDSTADDR+IP_RECVIF on MacOS & FreeBSD | [#77][77] | linux, windows, macos, freebsd, .net, openssl, nginx, msquic | +| ❔ | IPV6_RECVPKTINFO
      IPV6_PKTINFO on Windows | [#77][77] | linux, windows, macos, freebsd, .net, openssl, nginx, msquic | +| ❔ | IP_RECVTOS | [#78][78] | linux, windows, macos, freebsd, msquic | +| ❔ | IPV6_RECVTCLASS | [#78][78] | linux, windows, macos, freebsd, msquic | +| ❔ | IP_TOS | [#78][78] | linux, windows, macos, freebsd, jvm, .net, exim | +| ❔ | IPV6_TCLASS | [#78][78] | linux, macos, freebsd, jvm, .net, exim | +| ❔ | TCP_ECN_MODE | [#78][78] | macos | +| ❔ | TCP_ENABLE_ECN | [#78][78] | macos | +| ❔ | SO_LINGER | [#80][80] | posix, linux, windows, macos, freebsd, jvm, .net, rust, libuv, go, openssl, nginx | +| ❔ | IP_DONTFRAG
      IP_DONTFRAGMENT on Windows | [#79][79] | linux, windows, macos, freebsd, jvm, .net, openssl, nginx, msquic | +| ❔ | IPV6_DONTFRAG | [#79][79] | linux, windows, macos, freebsd, jvm, .net, openssl, nginx, msquic | +| ❔ | IP_MTU_DISCOVER | [#79][79] | linux, windows, openssl, nginx, curl, msquic | +| ❔ | IPV6_MTU_DISCOVER | [#79][79] | linux, windows, openssl, nginx, curl, msquic | +| ❔ | TCP_NODELAY | [#75][75] | posix, linux, windows, macos, freebsd, jvm, .net, rust, libuv, go, openssl, nginx, curl, exim | +| ❔ | TCP_CORK
      TCP_NOPUSH on MacOS & FreeBSD | [#75][75] | linux, macos, freebsd, nginx, exim | +| ❔ | SO_REUSEADDR | [#74][74] | posix, linux, windows, macos, freebsd, jvm, .net, libuv, go, openssl, nginx, curl, exim | +| ❔ | SO_EXCLUSIVEADDRUSE | [#74][74] | windows | +| ❔ | SO_RANDOMIZE_PORT | [#74][74] | windows | +| ❔ | SO_RANDOMPORT | [#74][74] | macos | +| ❔ | IP_BIND_ADDRESS_NO_PORT | [#74][74] | linux, nginx, curl | +| ❔ | SO_PORT_SCALABILITY | [#74][74] | windows | +| ❔ | SO_REUSE_UNICASTPORT | [#74][74] | windows, .net | +| ❔ | SO_REUSEPORT | [#74][74] | linux, macos, freebsd, .net, libuv, go, nginx, msquic | +| ❔ | SO_REUSEPORT_LB | [#74][74] | freebsd, nginx | +| ❔ | SO_ATTACH_REUSEPORT_CBPF | [#74][74] | linux, msquic | +| ❔ | SO_ATTACH_REUSEPORT_EBPF | [#74][74] | linux, nginx | +| ❔ | SO_DETACH_REUSEPORT_BPF | [#74][74] | linux | +| ❔ | TCP_REUSPORT_LB_NUMA | [#74][74] | freebsd | +| ❔ | SO_INCOMING_CPU | [#74][74] | linux | +| ❔ | SO_INCOMING_NAPI_ID | [#74][74] | linux, jvm | +| ❔ | SO_BINDTODEVICE | [#74][74] | linux, libuv, go, curl | +| ❔ | SO_BINDTOIFINDEX | [#74][74] | linux | +| ❔ | IP_UNICAST_IF | [#74][74] | linux, windows, msquic | +| ❔ | IPV6_UNICAST_IF | [#74][74] | linux, windows, msquic | +| ❔ | IP_BOUND_IF | [#74][74] | macos | +| ❔ | IPV6_BOUND_IF | [#74][74] | macos | +| ❔ | IP_FREEBIND | [#74][74] | linux | +| ❔ | IPV6_FREEBIND | [#74][74] | linux | +| ❔ | IP_TRANSPARENT | [#74][74] | linux, nginx | +| ❔ | IPV6_TRANSPARENT | [#74][74] | linux, nginx | +| ❔ | IP_BINDANY | [#74][74] | freebsd, nginx | +| ❔ | IPV6_BINDANY | [#74][74] | freebsd, nginx | +| ❔ | SO_REUSE_MULTICASTPORT | [#74][74], [#73][73] | windows | +| ❔ | SO_BROADCAST | [#73][73] | posix, linux, windows, macos, freebsd, jvm, .net, rust, libuv, go | +| ❔ | MCAST_JOIN_GROUP
      Supersedes: IP_ADD_MEMBERSHIP
      Supersedes: IPV6_JOIN_GROUP
      Supersedes: IPV6_ADD_MEMBERSHIP | [#73][73] | posix, linux, windows, macos, freebsd, jvm, .net, rust, libuv, go | +| ❔ | MCAST_LEAVE_GROUP
      Supersedes: IP_DROP_MEMBERSHIP
      Supersedes: IPV6_LEAVE_GROUP
      Supersedes: IPV6_DROP_MEMBERSHIP | [#73][73] | posix, linux, windows, macos, freebsd, jvm, .net, rust, libuv | +| ❔ | MCAST_JOIN_SOURCE_GROUP
      Supersedes: IP_ADD_SOURCE_MEMBERSHIP | [#73][73] | linux, windows, macos, freebsd, jvm, .net, libuv | +| ❔ | MCAST_LEAVE_SOURCE_GROUP
      Supersedes: IP_DROP_SOURCE_MEMBERSHIP | [#73][73] | linux, windows, macos, freebsd, jvm, .net, libuv | +| ❔ | MCAST_BLOCK_SOURCE
      Supersedes: IP_BLOCK_SOURCE | [#73][73] | linux, windows, macos, freebsd, jvm, .net | +| ❔ | MCAST_UNBLOCK_SOURCE
      Supersedes: IP_UNBLOCK_SOURCE | [#73][73] | linux, windows, macos, freebsd, jvm, .net | +| ❔ | IP_MSFILTER | [#73][73] | linux, windows, macos, freebsd | +| ❔ | IPV6_MSFILTER | [#73][73] | macos, freebsd | +| ❔ | IP_MULTICAST_IF | [#73][73] | linux, windows, macos, freebsd, jvm, .net, libuv, go | +| ❔ | IPV6_MULTICAST_IF | [#73][73] | posix, linux, windows, macos, freebsd, jvm, .net, libuv, go | +| ❔ | IP_MULTICAST_LOOP | [#73][73] | linux, windows, macos, freebsd, jvm, .net, rust, libuv, go | +| ❔ | IPV6_MULTICAST_LOOP | [#73][73] | posix, linux, windows, macos, freebsd, jvm, .net, rust, libuv, go | +| ❔ | IP_MULTICAST_TTL | [#73][73] | linux, windows, macos, freebsd, jvm, .net, rust, libuv | +| ❔ | IPV6_MULTICAST_HOPS | [#73][73] | posix, linux, windows, macos, freebsd, jvm, .net, libuv | +| ❔ | IP_MULTICAST_ALL | [#73][73] | linux | +| ❔ | IPV6_MULTICAST_ALL | [#73][73] | linux | +| ❔ | IP_MULTICAST_IFINDEX | [#73][73] | macos | +| ❔ | TCP_FASTOPEN | [#81][81] | linux, windows, macos, freebsd, openssl, nginx, exim | +| ❔ | TCP_FASTOPEN_CONNECT | [#81][81] | linux, openssl, curl, exim | +| ❔ | TCP_FASTOPEN_KEY | [#81][81] | linux | +| ❔ | TCP_FASTOPEN_NO_COOKIE | [#81][81] | linux | +| ❔ | TCP_FASTOPEN_FORCE_ENABLE | [#81][81] | macos | +| ❔ | TCP_FASTOPEN_FORCE_HEURISTICS | [#81][81] | macos | +| ❔ | SO_SNDLOWAT | Not usefully implemented on Linux & Windows. | posix, linux, macos, freebsd, .net, nginx | +| ❔ | SO_RCVLOWAT | | posix, linux, macos, freebsd, .net | +| ❔ | IP_RECVTTL | | linux, windows, macos, freebsd | +| ❔ | IPV6_RECVHOPLIMIT | | linux, macos, freebsd | +| ❔ | SO_DEBUG | | posix, linux, windows, macos, freebsd, .net | +| ❔ | SO_DONTROUTE | | posix, linux, windows, macos, freebsd, .net | +| ❔ | TCP_INFO
      via ioctl on Windows | | linux, windows, macos, freebsd, nginx, exim | +| ❔ | IP_IPSEC_POLICY | | linux, macos, freebsd | +| ❔ | IP_MINTTL | | linux, freebsd | +| ❔ | IPV6_MINHOPCOUNT | | linux | +| ❔ | IP_MTU | | linux, windows, openssl | +| ❔ | IPV6_MTU | | linux, windows, openssl | +| ❔ | IPV6_PATHMTU | | linux, macos, freebsd | +| ❔ | IPV6_RECVPATHMTU | | linux, macos, freebsd | +| ❔ | IPV6_USE_MIN_MTU | | linux, macos, freebsd | +| ❔ | IP_OPTIONS | | linux, windows, macos, freebsd, .net, exim | +| ❔ | IP_RECVOPTS | | linux, macos, freebsd | +| ❔ | IP_RECVORIGDSTADDR
      IP_ORIGDSTADDR on FreeBSD | | linux, freebsd | +| ❔ | IP_RECVRETOPTS
      Alias: IP_RETOPTS | | linux, macos, freebsd | +| ❔ | IPV6_2292DSTOPTS | | linux, macos, freebsd | +| ❔ | IPV6_2292HOPLIMIT | | linux, macos, freebsd | +| ❔ | IPV6_2292HOPOPTS | | linux, macos, freebsd | +| ❔ | IPV6_2292PKTINFO | | linux, macos, freebsd | +| ❔ | IPV6_2292PKTOPTIONS | | linux, macos, freebsd | +| ❔ | IPV6_2292RTHDR | | linux, macos, freebsd | +| ❔ | IPV6_AUTOFLOWLABEL | | linux, macos, freebsd | +| ❔ | IPV6_CHECKSUM | | linux, macos, freebsd | +| ❔ | IPV6_DSTOPTS | | linux, macos, freebsd | +| ❔ | IPV6_HOPOPTS | | linux, macos, freebsd | +| ❔ | IPV6_IPSEC_POLICY | | linux, macos, freebsd | +| ❔ | IPV6_NEXTHOP | | linux, macos, freebsd | +| ❔ | IPV6_RECVDSTOPTS | | linux, macos, freebsd | +| ❔ | IPV6_RECVHOPOPTS | | linux, macos, freebsd | +| ❔ | IPV6_RECVORIGDSTADDR
      IPV6_ORIGDSTADDR on FreeBSD | | linux, freebsd | +| ❔ | IPV6_RECVRTHDR | | linux, macos, freebsd | +| ❔ | IPV6_RTHDR | | linux, macos, freebsd | +| ❔ | IPV6_RTHDRDSTOPTS | | linux, macos, freebsd | +| ❔ | SO_TIMESTAMP | | linux, macos, freebsd | +| ❔ | TCP_CONGESTION | | linux, freebsd | +| ❔ | TCP_MAXSEG | | linux, macos, freebsd | +| ❔ | TCP_MD5SIG | | linux, freebsd | +| ❔ | TCP_NOTSENT_LOWAT | | linux, macos | +| ❔ | UDP_ENCAP | | linux, freebsd | +| ❔ | IP_CHECKSUM | | linux | +| ❔ | IP_NODEFRAG | | linux | +| ❔ | IP_PASSSEC | | linux | +| ❔ | IP_PKTOPTIONS | | linux | +| ❔ | IP_RECVERR | | linux, libuv | +| ❔ | IP_RECVERR_RFC4884 | | linux | +| ❔ | IP_RECVFRAGSIZE | | linux | +| ❔ | IP_ROUTER_ALERT | | linux | +| ❔ | IP_XFRM_POLICY | | linux | +| ❔ | IPV6_ADDR_PREFERENCES | | linux | +| ❔ | IPV6_ADDRFORM | | linux | +| ❔ | IPV6_AUTHHDR | | linux | +| ❔ | IPV6_FLOWINFO | | linux | +| ❔ | IPV6_FLOWINFO_SEND | | linux | +| ❔ | IPV6_FLOWLABEL_MGR | | linux | +| ❔ | IPV6_JOIN_ANYCAST | | linux | +| ❔ | IPV6_LEAVE_ANYCAST | | linux | +| ❔ | IPV6_RECVERR | | linux, libuv | +| ❔ | IPV6_RECVERR_RFC4884 | | linux | +| ❔ | IPV6_RECVFRAGSIZE | | linux | +| ❔ | IPV6_ROUTER_ALERT | | linux | +| ❔ | IPV6_ROUTER_ALERT_ISOLATE | | linux | +| ❔ | IPV6_XFRM_POLICY | | linux | +| ❔ | SO_ATTACH_FILTER | | linux | +| ❔ | SO_BPF_EXTENSIONS | | linux | +| ❔ | SO_BSDCOMPAT | | linux | +| ❔ | SO_BUF_LOCK | | linux | +| ❔ | SO_BUSY_POLL | | linux | +| ❔ | SO_BUSY_POLL_BUDGET | | linux | +| ❔ | SO_CNX_ADVICE | | linux | +| ❔ | SO_COOKIE | | linux, nginx | +| ❔ | SO_DETACH_FILTER | | linux | +| ❔ | SO_LOCK_FILTER | | linux | +| ❔ | SO_MARK | | linux | +| ❔ | SO_MEMINFO | | linux | +| ❔ | SO_NETNS_COOKIE | | linux | +| ❔ | SO_NO_CHECK | | linux | +| ❔ | SO_NOFCS | | linux | +| ❔ | SO_PASSCRED | | linux | +| ❔ | SO_PASSSEC | | linux | +| ❔ | SO_PEEK_OFF | | linux | +| ❔ | SO_PEERNAME | | linux | +| ❔ | SO_PREFER_BUSY_POLL | | linux | +| ❔ | SO_PRIORITY | | linux | +| ❔ | SO_RCVBUFFORCE | | linux | +| ❔ | SO_RCVMARK | | linux | +| ❔ | SO_RESERVE_MEM | | linux | +| ❔ | SO_RXQ_OVFL | | linux | +| ❔ | SO_SELECT_ERR_QUEUE | | linux | +| ❔ | SO_SNDBUFFORCE | | linux | +| ❔ | SO_TIMESTAMPING | | linux | +| ❔ | SO_TIMESTAMPNS | | linux | +| ❔ | SO_TXREHASH | | linux | +| ❔ | SO_TXTIME | | linux | +| ❔ | SO_WIFI_STATUS | | linux | +| ❔ | SO_ZEROCOPY | | linux | +| ❔ | TCP_CC_INFO | | linux | +| ❔ | TCP_CM_INQ | | linux | +| ❔ | TCP_DEFER_ACCEPT | | linux, nginx | +| ❔ | TCP_INQ | | linux | +| ❔ | TCP_LINGER2 | | linux | +| ❔ | TCP_MD5SIG_EXT | | linux | +| ❔ | TCP_QUEUE_SEQ | | linux | +| ❔ | TCP_QUICKACK | | linux, jvm, exim | +| ❔ | TCP_REPAIR | | linux | +| ❔ | TCP_REPAIR_OPTIONS | | linux | +| ❔ | TCP_REPAIR_QUEUE | | linux | +| ❔ | TCP_REPAIR_WINDOW | | linux | +| ❔ | TCP_SAVE_SYN | | linux | +| ❔ | TCP_SAVED_SYN | | linux | +| ❔ | TCP_SYNCNT | | linux | +| ❔ | TCP_THIN_DUPACK | | linux | +| ❔ | TCP_THIN_LINEAR_TIMEOUTS | | linux | +| ❔ | TCP_TIMESTAMP | | linux | +| ❔ | TCP_TX_DELAY | | linux | +| ❔ | TCP_ULP | | linux | +| ❔ | TCP_USER_TIMEOUT | | linux | +| ❔ | TCP_WINDOW_CLAMP | | linux | +| ❔ | TCP_ZEROCOPY_RECEIVE | | linux | +| ❔ | UDP_CORK | | linux | +| ❔ | UDP_GRO | | linux, msquic | +| ❔ | UDP_NO_CHECK6_RX | | linux | +| ❔ | UDP_NO_CHECK6_TX | | linux | +| ❔ | UDP_SEGMENT | | linux, nginx | +| ❔ | IP_ADD_IFLIST | | windows | +| ❔ | IP_DEL_IFLIST | | windows | +| ❔ | IP_GET_IFLIST | | windows | +| ❔ | IP_IFLIST | | windows | +| ❔ | IP_ORIGINAL_ARRIVAL_IF | | windows | +| ❔ | IP_ORIGINAL_ARRIVAL_IF | | windows | +| ❔ | IP_RECEIVE_BROADCAST | | windows | +| ❔ | IP_USER_MTU | | windows | +| ❔ | IP_WFP_REDIRECT_CONTEXT | | windows | +| ❔ | IP_WFP_REDIRECT_RECORDS | | windows | +| ❔ | IPV6_ADD_IFLIST | | windows | +| ❔ | IPV6_DEL_IFLIST | | windows | +| ❔ | IPV6_GET_IFLIST | | windows | +| ❔ | IPV6_IFLIST | | windows | +| ❔ | IPV6_PROTECTION_LEVEL | | windows | +| ❔ | IPV6_RECVIF | | windows | +| ❔ | IPV6_USER_MTU | | windows | +| ❔ | SO_BSP_STATE | | windows | +| ❔ | SO_CONDITIONAL_ACCEPT | | windows | +| ❔ | SO_CONNDATA | | windows | +| ❔ | SO_CONNDATALEN | | windows | +| ❔ | SO_CONNECT_TIME | | windows | +| ❔ | SO_CONNOPT | | windows | +| ❔ | SO_CONNOPTLEN | | windows | +| ❔ | SO_DISCDATA | | windows | +| ❔ | SO_DISCDATALEN | | windows | +| ❔ | SO_DISCOPT | | windows | +| ❔ | SO_DISCOPTLEN | | windows | +| ❔ | SO_GROUP_ID | | windows | +| ❔ | SO_GROUP_PRIORITY | | windows | +| ❔ | SO_MAX_MSG_SIZE | | windows | +| ❔ | SO_MAXDG | | windows | +| ❔ | SO_MAXPATHDG | | windows | +| ❔ | SO_OPENTYPE | | windows | +| ❔ | SO_PAUSE_ACCEPT | | windows | +| ❔ | SO_PROTOCOL_INFO | | windows | +| ❔ | SO_PROTOCOL_INFOA | | windows | +| ❔ | SO_PROTOCOL_INFOW | | windows | +| ❔ | SO_UPDATE_ACCEPT_CONTEXT | | windows | +| ❔ | SO_UPDATE_CONNECT_CONTEXT | | windows | +| ❔ | TCP_BSDURGENT | | windows | +| ❔ | TCP_EXPEDITED_1122 | | windows | +| ❔ | TCP_FAIL_CONNECT_ON_ICMP_ERROR | | windows | +| ❔ | TCP_ICMP_ERROR_INFO | | windows | +| ❔ | TCP_MAXRT | | windows | +| ❔ | TCP_TIMESTAMPS | | windows | +| ❔ | UDP_CHECKSUM_COVERAGE | | windows | +| ❔ | UDP_NOCHECKSUM | | windows | +| ❔ | UDP_RECV_MAX_COALESCED_SIZE | | windows, msquic | +| ❔ | UDP_SEND_MSG_SIZE | | windows, msquic | +| ❔ | IP_FAITH | | macos | +| ❔ | IP_NAT__XXX | | macos | +| ❔ | IP_STRIPHDR | | macos | +| ❔ | IP_TRAFFIC_MGT_BACKGROUND | | macos | +| ❔ | IPV6_3542DSTOPTS | | macos | +| ❔ | IPV6_3542HOPLIMIT | | macos | +| ❔ | IPV6_3542HOPOPTS | | macos | +| ❔ | IPV6_3542NEXTHOP | | macos | +| ❔ | IPV6_3542PKTINFO | | macos | +| ❔ | IPV6_3542RTHDR | | macos | +| ❔ | IPV6_RTHDR_LOOSE | | macos | +| ❔ | IPV6_RTHDR_STRICT | | macos | +| ❔ | IPV6_RTHDR_TYPE_0 | | macos | +| ❔ | SO_AWDL_UNRESTRICTED | | macos | +| ❔ | SO_CFIL_SOCK_ID | | macos | +| ❔ | SO_DELEGATED | | macos | +| ❔ | SO_DELEGATED_UUID | | macos | +| ❔ | SO_DONTTRUNC | | macos | +| ❔ | SO_EXECPATH | | macos | +| ❔ | SO_EXTENDED_BK_IDLE | | macos | +| ❔ | SO_FLOW_DIVERT_TOKEN | | macos | +| ❔ | SO_FLUSH | | macos | +| ❔ | SO_INTCOPROC_ALLOW | | macos | +| ❔ | SO_LINGER_SEC | | macos | +| ❔ | SO_MARK_CELLFALLBACK | | macos | +| ❔ | SO_MPKL_SEND_INFO | | macos | +| ❔ | SO_NECP_ATTRIBUTES | | macos | +| ❔ | SO_NECP_CLIENTUUID | | macos | +| ❔ | SO_NECP_LISTENUUID | | macos | +| ❔ | SO_NET_SERVICE_TYPE | | macos | +| ❔ | SO_NETSVC_MARKING_LEVEL | | macos | +| ❔ | SO_NKE | | macos | +| ❔ | SO_NOADDRERR | | macos | +| ❔ | SO_NOAPNFALLBK | | macos | +| ❔ | SO_NOTIFYCONFLICT | | macos | +| ❔ | SO_NOWAKEFROMSLEEP | | macos | +| ❔ | SO_NP_EXTENSIONS | | macos | +| ❔ | SO_NREAD | | macos | +| ❔ | SO_NUMRCVPKT | | macos | +| ❔ | SO_NWRITE | | macos | +| ❔ | SO_OPPORTUNISTIC | | macos | +| ❔ | SO_QOSMARKING_POLICY_OVERRIDE | | macos | +| ❔ | SO_RECV_ANYIF | | macos | +| ❔ | SO_RESTRICTIONS | | macos | +| ❔ | SO_REUSESHAREUID | | macos | +| ❔ | SO_STATISTICS_EVENT | | macos | +| ❔ | SO_TC_NET_SERVICE_OFFSET | | macos | +| ❔ | SO_TC_NETSVC_SIG | | macos | +| ❔ | SO_TIMESTAMP_CONTINUOUS | | macos | +| ❔ | SO_TIMESTAMP_MONOTONIC | | macos | +| ❔ | SO_TRAFFIC_MGT_BACKGROUND | | macos | +| ❔ | SO_UPCALLCLOSEWAIT | | macos | +| ❔ | SO_WANT_KEV_SOCKET_CLOSED | | macos | +| ❔ | SO_WANTMORE | | macos | +| ❔ | SO_WANTOOBFLAG | | macos | +| ❔ | MPTCP_ALTERNATE_PORT | | macos | +| ❔ | MPTCP_EXPECTED_PROGRESS_TARGET | | macos | +| ❔ | MPTCP_FORCE_ENABLE | | macos | +| ❔ | MPTCP_FORCE_VERSION | | macos | +| ❔ | MPTCP_SERVICE_TYPE | | macos | +| ❔ | PERSIST_TIMEOUT | | macos | +| ❔ | TCP_ADAPTIVE_READ_TIMEOUT | | macos | +| ❔ | TCP_ADAPTIVE_WRITE_TIMEOUT | | macos | +| ❔ | TCP_CONNECTION_INFO | | macos | +| ❔ | TCP_CONNECTIONTIMEOUT | | macos | +| ❔ | TCP_DISABLE_BLACKHOLE_DETECTION | | macos | +| ❔ | TCP_KEEPALIVE_OFFLOAD | | macos | +| ❔ | TCP_MEASURE_BW_BURST | | macos | +| ❔ | TCP_MEASURE_SND_BW | | macos | +| ❔ | TCP_NOTIFY_ACKNOWLEDGEMENT | | macos | +| ❔ | TCP_NOTIMEWAIT | | macos | +| ❔ | TCP_PEER_PID | | macos | +| ❔ | TCP_RXT_CONNDROPTIME | | macos | +| ❔ | TCP_RXT_FINDROP | | macos | +| ❔ | TCP_RXT_MINIMUM_TIMEOUT | | macos | +| ❔ | TCP_SENDMOREACKS | | macos | +| ❔ | UDP_KEEPALIVE_OFFLOAD | | macos | +| ❔ | UDP_NOCKSUM | | macos | +| ❔ | ICMP6_FILTER | | macos, freebsd | +| ❔ | IP_MULTICAST_VIF | | macos, freebsd | +| ❔ | IP_PORTRANGE | | macos, freebsd, go | +| ❔ | IP_RSVP_OFF | | macos, freebsd | +| ❔ | IP_RSVP_ON | | macos, freebsd | +| ❔ | IP_RSVP_VIF_OFF | | macos, freebsd | +| ❔ | IP_RSVP_VIF_ON | | macos, freebsd | +| ❔ | IPV6_2292NEXTHOP | | macos, freebsd | +| ❔ | IPV6_BINDV6ONLY | | macos, freebsd | +| ❔ | IPV6_FAITH | | macos, freebsd | +| ❔ | IPV6_PKTOPTIONS | | macos, freebsd | +| ❔ | IPV6_PORTRANGE | | macos, freebsd, go | +| ❔ | IPV6_PREFER_TEMPADDR | | macos, freebsd | +| ❔ | IPV6_RECVRTHDRDSTOPTS | | macos, freebsd | +| ❔ | SO_ACCEPTFILTER | | macos, freebsd, nginx | +| ❔ | SO_LABEL | | macos, freebsd | +| ❔ | SO_PEERLABEL | | macos, freebsd | +| ❔ | SO_USELOOPBACK | | macos, freebsd | +| ❔ | TCP_NOOPT | | macos, freebsd | +| ❔ | IP_BINDMULTI | | freebsd | +| ❔ | IP_FLOWID | | freebsd | +| ❔ | IP_FLOWTYPE | | freebsd | +| ❔ | IP_MAX_MEMBERSHIPS | | freebsd | +| ❔ | IP_ONESBCAST | | freebsd | +| ❔ | IP_RECVFLOWID | | freebsd | +| ❔ | IP_RECVRSSBUCKETID | | freebsd | +| ❔ | IP_RSS_LISTEN_BUCKET | | freebsd | +| ❔ | IP_RSSBUCKETID | | freebsd | +| ❔ | IP_SENDSRCADDR | | freebsd, nginx | +| ❔ | IP_VLAN_PCP | | freebsd | +| ❔ | IPV6_AUTH_LEVEL | | freebsd | +| ❔ | IPV6_BINDMULTI | | freebsd | +| ❔ | IPV6_ESP_NETWORK_LEVEL | | freebsd | +| ❔ | IPV6_ESP_TRANS_LEVEL | | freebsd | +| ❔ | IPV6_FLOWID | | freebsd | +| ❔ | IPV6_FLOWTYPE | | freebsd | +| ❔ | IPV6_IPCOMP_LEVEL | | freebsd | +| ❔ | IPV6_RECVFLOWID | | freebsd | +| ❔ | IPV6_RECVRSSBUCKETID | | freebsd | +| ❔ | IPV6_RSS_LISTEN_BUCKET | | freebsd | +| ❔ | IPV6_RSSBUCKETID | | freebsd | +| ❔ | IPV6_VLAN_PCP | | freebsd | +| ❔ | SO_BINTIME | | freebsd | +| ❔ | SO_LISTENINCQLEN | | freebsd | +| ❔ | SO_LISTENQLEN | | freebsd, exim | +| ❔ | SO_LISTENQLIMIT | | freebsd | +| ❔ | SO_MAX_PACING_RATE | | freebsd | +| ❔ | SO_NO_DDP | | freebsd | +| ❔ | SO_NO_OFFLOAD | | freebsd | +| ❔ | SO_RERROR | | freebsd | +| ❔ | SO_SETFIB | | freebsd, nginx | +| ❔ | SO_TS_BINTIME | | freebsd | +| ❔ | SO_TS_CLOCK | | freebsd | +| ❔ | SO_TS_CLOCK_MAX | | freebsd | +| ❔ | SO_TS_DEFAULT | | freebsd | +| ❔ | SO_TS_MONOTONIC | | freebsd | +| ❔ | SO_TS_REALTIME | | freebsd | +| ❔ | SO_TS_REALTIME_MICRO | | freebsd | +| ❔ | SO_USER_COOKIE | | freebsd | +| ❔ | TCP_CCALGOOPT | | freebsd | +| ❔ | TCP_DEFER_OPTIONS | | freebsd | +| ❔ | TCP_DELACK | | freebsd | +| ❔ | TCP_FAST_RSM_HACK | | freebsd | +| ❔ | TCP_FIN_IS_RST | | freebsd | +| ❔ | TCP_FUNCTION_ALIAS | | freebsd | +| ❔ | TCP_FUNCTION_BLK | | freebsd | +| ❔ | TCP_HDWR_RATE_CAP | | freebsd | +| ❔ | TCP_HDWR_UP_ONLY | | freebsd | +| ❔ | TCP_IDLE_REDUCE | | freebsd | +| ❔ | TCP_IWND_NB | | freebsd | +| ❔ | TCP_IWND_NSEG | | freebsd | +| ❔ | TCP_KEEPINIT | | freebsd | +| ❔ | TCP_LOG | | freebsd | +| ❔ | TCP_LOG_LIMIT | | freebsd | +| ❔ | TCP_LOG_TAG | | freebsd | +| ❔ | TCP_LOGBUF | | freebsd | +| ❔ | TCP_LOGDUMP | | freebsd | +| ❔ | TCP_LOGDUMPID | | freebsd | +| ❔ | TCP_LOGID | | freebsd | +| ❔ | TCP_LOGID_CNT | | freebsd | +| ❔ | TCP_LRD | | freebsd | +| ❔ | TCP_MAXPEAKRATE | | freebsd | +| ❔ | TCP_MAXUNACKTIME | | freebsd | +| ❔ | TCP_PCAP_IN | | freebsd | +| ❔ | TCP_PCAP_OUT | | freebsd | +| ❔ | TCP_PERF_INFO | | freebsd | +| ❔ | TCP_PROC_ACCOUNTING | | freebsd | +| ❔ | TCP_REMOTE_UDP_ENCAPS_PORT | | freebsd | +| ❔ | TCP_RXTLS_ENABLE | | freebsd | +| ❔ | TCP_RXTLS_MODE | | freebsd | +| ❔ | TCP_STATS | | freebsd | +| ❔ | TCP_TXTLS_ENABLE | | freebsd | +| ❔ | TCP_TXTLS_MODE | | freebsd | +| ❔ | TCP_USE_CMP_ACKS | | freebsd | +| ❔ | TCP_USER_LOG | | freebsd | + +[17]: https://github.com/WebAssembly/wasi-sockets/issues/17 +[34]: https://github.com/WebAssembly/wasi-sockets/issues/34 +[73]: https://github.com/WebAssembly/wasi-sockets/issues/73 +[74]: https://github.com/WebAssembly/wasi-sockets/issues/74 +[75]: https://github.com/WebAssembly/wasi-sockets/issues/75 +[77]: https://github.com/WebAssembly/wasi-sockets/issues/77 +[78]: https://github.com/WebAssembly/wasi-sockets/issues/78 +[79]: https://github.com/WebAssembly/wasi-sockets/issues/79 +[80]: https://github.com/WebAssembly/wasi-sockets/issues/80 +[81]: https://github.com/WebAssembly/wasi-sockets/issues/81 [ip-name-lookup]: https://github.com/WebAssembly/wasi-sockets/blob/main/wit/ip-name-lookup.wit [tcp-create-socket]: https://github.com/WebAssembly/wasi-sockets/blob/main/wit/tcp-create-socket.wit [tcp]: https://github.com/WebAssembly/wasi-sockets/blob/main/wit/tcp.wit From ea13d01fde1924c33d84c69ae1fd77c9b9b51081 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 3 Jan 2024 16:45:18 +0100 Subject: [PATCH 1356/1772] Add note about the Windows behavior --- proposals/sockets/imports.md | 5 +++-- proposals/sockets/wit/tcp.wit | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index f0fa5c369..cdbe6e6f0 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -1192,8 +1192,9 @@ implicitly bind the socket.

    Implementors note

    When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT -state of a recently closed socket on the same local address (i.e. the SO_REUSEADDR socket -option should be set implicitly on platforms that require it).

    +state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR +socket option should be set implicitly on all platforms, except on Windows where this is the default behavior +and SO_REUSEADDR performs something different entirely.

    References

    • https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
    • diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 976b272c0..337d606d8 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -45,8 +45,9 @@ interface tcp { /// /// # Implementors note /// When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT - /// state of a recently closed socket on the same local address (i.e. the SO_REUSEADDR socket - /// option should be set implicitly on platforms that require it). + /// state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR + /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior + /// and SO_REUSEADDR performs something different entirely. /// /// # References /// - From 4eaa62d7c416aaea59f4d981fcbb688a01eda074 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 8 Jan 2024 17:49:55 -0800 Subject: [PATCH 1357/1772] Specify that text in streams is transmitted in UTF-8. (#66) * Specify that text in streams is transmitted in UTF-8. The wasi-io stream types are byte streams capable of transmitting any data encoding, including any text encoding. However, sometimes an implementation knows the a particular data source or destination uses text data of a particular encoding, for example in an implementation of the stdio streams on Windows. In these cases, it's useful to have the implementation transcode the data, so that guest code doesn't need to be aware of where the data is coming from or going to, and have extra code for performing transcoding itself. Specify UTF-8 as the encoding to use, when transmitting data from sources or to destinations where the implementation knows the data is in a text format. * Update imports.md. --- proposals/io/.github/workflows/main.yml | 4 +-- proposals/io/imports.md | 42 +++++++++++++++++++++++-- proposals/io/wit/streams.wit | 11 +++++++ 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index b45623289..b944a0ddb 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -10,5 +10,5 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: WebAssembly/wit-abi-up-to-date@v16 + - uses: actions/checkout@v4 + - uses: WebAssembly/wit-abi-up-to-date@v17 diff --git a/proposals/io/imports.md b/proposals/io/imports.md index 55647e883..0d295ccb2 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -12,7 +12,21 @@

      Types

      resource error

      -
      +

      A resource which represents some error information.

      +

      The only method provided by this resource is to-debug-string, +which provides some human-readable information about the error.

      +

      In the wasi:io package, this resource is returned through the +wasi:io/streams/stream-error type.

      +

      To provide more specific error information, other interfaces may +provide functions to further "downcast" this error into more specific +error information. For example, errors returned in streams derived +from filesystem types to be described using the filesystem's own +error-code type, using the function +wasi:filesystem/types/filesystem-error-code, which takes a parameter +borrow<error> and returns +option<wasi:filesystem/types/error-code>.

      +

      The set of functions which can "downcast" an error into a more +concrete type is open.

      Functions

      [method]error.to-debug-string: func

      Returns a string that is suitable to assist humans in debugging @@ -35,7 +49,7 @@ at once.


      Types

      resource pollable

      -
      +

      pollable represents a single I/O event which may be ready, or not.

      Functions

      [method]pollable.ready: func

      Return the readiness of a pollable. This function never blocks.

      @@ -109,11 +123,28 @@ future operations.

    resource input-stream

    +

    An input bytestream.

    +

    input-streams are non-blocking to the extent practical on underlying +platforms. I/O operations always return promptly; if fewer bytes are +promptly available than requested, they return the number of bytes promptly +available, which could even be zero. To wait for data to be available, +use the subscribe function to obtain a pollable which can be polled +for using wasi:io/poll.

    resource output-stream

    -
    +

    An output bytestream.

    +

    output-streams are non-blocking to the extent practical on +underlying platforms. Except where specified otherwise, I/O operations also +always return promptly, after the number of bytes that can be written +promptly, which could even be zero. To wait for the stream to be ready to +accept data, the subscribe function to obtain a pollable which can be +polled for using wasi:io/poll.

    Functions

    [method]input-stream.read: func

    Perform a non-blocking read from the stream.

    +

    When the source of a read is binary data, the bytes from the source +are returned verbatim. When the source of a read is known to the +implementation to be text, bytes containing the UTF-8 encoding of the +text are returned.

    This function returns a list of bytes containing the read data, when successful. The returned list will contain up to len bytes; it may return fewer than requested, but not more. The list is @@ -209,6 +240,11 @@ error.

    [method]output-stream.write: func

    Perform a write. This function never blocks.

    +

    When the destination of a write is binary data, the bytes from +contents are written verbatim. When the destination of a write is +known to the implementation to be text, the bytes of contents are +transcoded from UTF-8 into the encoding of the destination and then +written.

    Precondition: check-write gave permit of Ok(n) and contents has a length of less than or equal to n. Otherwise, this function will trap.

    returns Err(closed) without writing if the stream has closed since diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index f6f7fe0e8..82e6e073e 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -32,6 +32,11 @@ interface streams { resource input-stream { /// Perform a non-blocking read from the stream. /// + /// When the source of a `read` is binary data, the bytes from the source + /// are returned verbatim. When the source of a `read` is known to the + /// implementation to be text, bytes containing the UTF-8 encoding of the + /// text are returned. + /// /// This function returns a list of bytes containing the read data, /// when successful. The returned list will contain up to `len` bytes; /// it may return fewer than requested, but not more. The list is @@ -111,6 +116,12 @@ interface streams { /// Perform a write. This function never blocks. /// + /// When the destination of a `write` is binary data, the bytes from + /// `contents` are written verbatim. When the destination of a `write` is + /// known to the implementation to be text, the bytes of `contents` are + /// transcoded from UTF-8 into the encoding of the destination and then + /// written. + /// /// Precondition: check-write gave permit of Ok(n) and contents has a /// length of less than or equal to n. Otherwise, this function will trap. /// From c83838d1eb18449d9c90f879d2175a3be24eeb4b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 8 Jan 2024 18:05:05 -0800 Subject: [PATCH 1358/1772] Convert `//`-style comments to `///`. Per the discussion in WebAssembly/component-model#273, the Wit format is moving to only have documentation comments. A as of WebAssembly/component-model#286, the syntax for documentation commments is `///`. This patch converts a few of the remaining `//` comments in network.wit to `///` comments. --- proposals/sockets/wit/network.wit | 36 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 6bb07cd6f..9cadf0650 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -18,8 +18,6 @@ interface network { /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. enum error-code { - // ### GENERAL ERRORS ### - /// Unknown error unknown, @@ -64,9 +62,6 @@ interface network { would-block, - - // ### TCP & UDP SOCKET ERRORS ### - /// The operation is not valid in the socket's current state. invalid-state, @@ -83,24 +78,21 @@ interface network { remote-unreachable, - // ### TCP SOCKET ERRORS ### - - /// The connection was forcefully rejected + /// The TCP connection was forcefully rejected connection-refused, - /// The connection was reset. + /// The TCP connection was reset. connection-reset, - /// A connection was aborted. + /// A TCP connection was aborted. connection-aborted, - // ### UDP SOCKET ERRORS ### + /// The size of a datagram sent to a UDP socket exceeded the maximum + /// supported size. datagram-too-large, - // ### NAME LOOKUP ERRORS ### - /// Name does not exist or has no suitable associated IP addresses. name-unresolvable, @@ -128,15 +120,21 @@ interface network { } record ipv4-socket-address { - port: u16, // sin_port - address: ipv4-address, // sin_addr + /// sin_port + port: u16, + /// sin_addr + address: ipv4-address, } record ipv6-socket-address { - port: u16, // sin6_port - flow-info: u32, // sin6_flowinfo - address: ipv6-address, // sin6_addr - scope-id: u32, // sin6_scope_id + /// sin6_port + port: u16, + /// sin6_flowinfo + flow-info: u32, + /// sin6_addr + address: ipv6-address, + /// sin6_scope_id + scope-id: u32, } variant ip-socket-address { From d3a0e86da596f2fb9d0c669a1e86b74292aec311 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 8 Jan 2024 18:09:49 -0800 Subject: [PATCH 1359/1772] Update imports.md. --- proposals/sockets/imports.md | 77 ++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index cdbe6e6f0..4cc6c2cd7 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -20,6 +20,9 @@


    Types

    resource network

    +

    An opaque resource that represents access to (a subset of) the network. +This enables context-based security for networking. +There is no need for this to map 1:1 to a physical network interface.

    enum error-code

    Error codes.

    In theory, every API can return any error code. @@ -102,18 +105,20 @@ combined with a couple of errors that are always possible:

  • connection-refused

    -

    The connection was forcefully rejected +

    The TCP connection was forcefully rejected

  • connection-reset

    -

    The connection was reset. +

    The TCP connection was reset.

  • connection-aborted

    -

    A connection was aborted. +

    A TCP connection was aborted.

  • datagram-too-large

    +

    The size of a datagram sent to a UDP socket exceeded the maximum +supported size.

  • name-unresolvable

    @@ -169,16 +174,34 @@ combined with a couple of errors that are always possible:

    record ipv4-socket-address

    Record Fields

    record ipv6-socket-address

    Record Fields

    variant ip-socket-address

    Variant Cases
    @@ -207,7 +230,7 @@ at once.


    Types

    resource pollable

    -
    +

    pollable epresents a single I/O event which may be ready, or not.

    Functions

    [method]pollable.ready: func

    Return the readiness of a pollable. This function never blocks.

    @@ -305,6 +328,7 @@ being reaedy for I/O.

  • resource udp-socket

    +

    A UDP socket handle.

    resource incoming-datagram-stream

    resource outgoing-datagram-stream


    @@ -740,7 +764,21 @@ the socket is effectively an in-memory configuration object, unable to communica

    Types

    resource error

    -
    +

    A resource which represents some error information.

    +

    The only method provided by this resource is to-debug-string, +which provides some human-readable information about the error.

    +

    In the wasi:io package, this resource is returned through the +wasi:io/streams/stream-error type.

    +

    To provide more specific error information, other interfaces may +provide functions to further "downcast" this error into more specific +error information. For example, errors returned in streams derived +from filesystem types to be described using the filesystem's own +error-code type, using the function +wasi:filesystem/types/filesystem-error-code, which takes a parameter +borrow<error> and returns +option<wasi:filesystem/types/error-code>.

    +

    The set of functions which can "downcast" an error into a more +concrete type is open.

    Functions

    [method]error.to-debug-string: func

    Returns a string that is suitable to assist humans in debugging @@ -787,8 +825,21 @@ future operations.

    resource input-stream

    +

    An input bytestream.

    +

    input-streams are non-blocking to the extent practical on underlying +platforms. I/O operations always return promptly; if fewer bytes are +promptly available than requested, they return the number of bytes promptly +available, which could even be zero. To wait for data to be available, +use the subscribe function to obtain a pollable which can be polled +for using wasi:io/poll.

    resource output-stream

    -
    +

    An output bytestream.

    +

    output-streams are non-blocking to the extent practical on +underlying platforms. Except where specified otherwise, I/O operations also +always return promptly, after the number of bytes that can be written +promptly, which could even be zero. To wait for the stream to be ready to +accept data, the subscribe function to obtain a pollable which can be +polled for using wasi:io/poll.

    Functions

    [method]input-stream.read: func

    Perform a non-blocking read from the stream.

    @@ -1165,7 +1216,7 @@ occured.

    resource tcp-socket

    -
    +

    A TCP socket handle.

    Functions

    [method]tcp-socket.start-bind: func

    Bind the socket to a specific network on the provided IP address and port.

    From 0d8c6ce8119793ce3609b9ec95731be79c8ac46e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 8 Jan 2024 18:14:25 -0800 Subject: [PATCH 1360/1772] Update CI dependencies. --- proposals/sockets/.github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index af3c079b1..185f6a10f 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: ensure `./wit/deps` are in sync run: | curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.3/wit-deps-x86_64-unknown-linux-musl @@ -18,4 +18,4 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v16 + - uses: WebAssembly/wit-abi-up-to-date@v17 From 11fd3ff5df5e78069fecda477e834cf7e7418f03 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 12 Jan 2024 14:51:05 -0800 Subject: [PATCH 1361/1772] Switch to `///` comments. (#38) * Switch to `///` comments. Per the discussion in WebAssembly/component-model#286, remove some `//` comments which had been intended as non-documentation comments to `///` documentation comments. * Update to the latest wasi-sockets and wasi-io. Update to the latest wasi-sockets and wasi-io. The only changes are the addition of some comments, and changing some comments from `//` to `///`. --- proposals/cli/.github/workflows/main.yml | 8 +-- proposals/cli/command.md | 60 ++++++++++++++++++---- proposals/cli/imports.md | 60 ++++++++++++++++++---- proposals/cli/wit/deps.lock | 8 +-- proposals/cli/wit/deps/io/streams.wit | 11 ++++ proposals/cli/wit/deps/sockets/network.wit | 36 ++++++------- proposals/cli/wit/deps/sockets/tcp.wit | 6 +++ proposals/cli/wit/terminal.wit | 18 ++++--- 8 files changed, 154 insertions(+), 53 deletions(-) diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml index 6f479825f..767e09199 100644 --- a/proposals/cli/.github/workflows/main.yml +++ b/proposals/cli/.github/workflows/main.yml @@ -10,15 +10,15 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: ensure `./wit/deps` are in sync run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.3/wit-deps-x86_64-unknown-linux-musl + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.5/wit-deps-x86_64-unknown-linux-musl chmod +x wit-deps ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v16 + - uses: WebAssembly/wit-abi-up-to-date@v17 with: - wit-bindgen: '0.15.0' + wit-bindgen: '0.16.0' worlds: "command imports" diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 928f2f19c..2159bd3c1 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -206,6 +206,10 @@ polled for using wasi:io/poll.

    Functions

    [method]input-stream.read: func

    Perform a non-blocking read from the stream.

    +

    When the source of a read is binary data, the bytes from the source +are returned verbatim. When the source of a read is known to the +implementation to be text, bytes containing the UTF-8 encoding of the +text are returned.

    This function returns a list of bytes containing the read data, when successful. The returned list will contain up to len bytes; it may return fewer than requested, but not more. The list is @@ -301,6 +305,11 @@ error.

    [method]output-stream.write: func

    Perform a write. This function never blocks.

    +

    When the destination of a write is binary data, the bytes from +contents are written verbatim. When the destination of a write is +known to the implementation to be text, the bytes of contents are +transcoded from UTF-8 into the encoding of the destination and then +written.

    Precondition: check-write gave permit of Ok(n) and contents has a length of less than or equal to n. Otherwise, this function will trap.

    returns Err(closed) without writing if the stream has closed since @@ -514,11 +523,19 @@ is ready for reading, before performing the splice.

  • own<output-stream>
  • Import interface wasi:cli/terminal-input@0.2.0-rc-2023-12-05

    +

    Terminal input.

    +

    In the future, this may include functions for disabling echoing, +disabling input buffering so that keyboard events are sent through +immediately, querying supported features, and so on.


    Types

    resource terminal-input

    The input side of a terminal.

    Import interface wasi:cli/terminal-output@0.2.0-rc-2023-12-05

    +

    Terminal output.

    +

    In the future, this may include functions for querying the terminal +size, being notified of terminal size changes, querying supported +features, and so on.


    Types

    resource terminal-output

    @@ -1659,18 +1676,20 @@ combined with a couple of errors that are always possible:

  • connection-refused

    -

    The connection was forcefully rejected +

    The TCP connection was forcefully rejected

  • connection-reset

    -

    The connection was reset. +

    The TCP connection was reset.

  • connection-aborted

    -

    A connection was aborted. +

    A TCP connection was aborted.

  • datagram-too-large

    +

    The size of a datagram sent to a UDP socket exceeded the maximum +supported size.

  • name-unresolvable

    @@ -1726,16 +1745,34 @@ combined with a couple of errors that are always possible:

    record ipv4-socket-address

    Record Fields

    record ipv6-socket-address

    Record Fields

    variant ip-socket-address

    Variant Cases
    @@ -2313,6 +2350,11 @@ implicitly bind the socket.

  • not-in-progress: A bind operation is not in progress.
  • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
  • +

    Implementors note

    +

    When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT +state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR +socket option should be set implicitly on all platforms, except on Windows where this is the default behavior +and SO_REUSEADDR performs something different entirely.

    References

    Functions

    [method]input-stream.read: func

    Perform a non-blocking read from the stream.

    +

    When the source of a read is binary data, the bytes from the source +are returned verbatim. When the source of a read is known to the +implementation to be text, bytes containing the UTF-8 encoding of the +text are returned.

    This function returns a list of bytes containing the read data, when successful. The returned list will contain up to len bytes; it may return fewer than requested, but not more. The list is @@ -296,6 +300,11 @@ error.

    [method]output-stream.write: func

    Perform a write. This function never blocks.

    +

    When the destination of a write is binary data, the bytes from +contents are written verbatim. When the destination of a write is +known to the implementation to be text, the bytes of contents are +transcoded from UTF-8 into the encoding of the destination and then +written.

    Precondition: check-write gave permit of Ok(n) and contents has a length of less than or equal to n. Otherwise, this function will trap.

    returns Err(closed) without writing if the stream has closed since @@ -509,11 +518,19 @@ is ready for reading, before performing the splice.

  • own<output-stream>
  • Import interface wasi:cli/terminal-input@0.2.0-rc-2023-12-05

    +

    Terminal input.

    +

    In the future, this may include functions for disabling echoing, +disabling input buffering so that keyboard events are sent through +immediately, querying supported features, and so on.


    Types

    resource terminal-input

    The input side of a terminal.

    Import interface wasi:cli/terminal-output@0.2.0-rc-2023-12-05

    +

    Terminal output.

    +

    In the future, this may include functions for querying the terminal +size, being notified of terminal size changes, querying supported +features, and so on.


    Types

    resource terminal-output

    @@ -1654,18 +1671,20 @@ combined with a couple of errors that are always possible:

  • connection-refused

    -

    The connection was forcefully rejected +

    The TCP connection was forcefully rejected

  • connection-reset

    -

    The connection was reset. +

    The TCP connection was reset.

  • connection-aborted

    -

    A connection was aborted. +

    A TCP connection was aborted.

  • datagram-too-large

    +

    The size of a datagram sent to a UDP socket exceeded the maximum +supported size.

  • name-unresolvable

    @@ -1721,16 +1740,34 @@ combined with a couple of errors that are always possible:

    record ipv4-socket-address

    Record Fields

    record ipv6-socket-address

    Record Fields

    variant ip-socket-address

    Variant Cases
    @@ -2308,6 +2345,11 @@ implicitly bind the socket.

  • not-in-progress: A bind operation is not in progress.
  • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
  • +

    Implementors note

    +

    When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT +state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR +socket option should be set implicitly on all platforms, except on Windows where this is the default behavior +and SO_REUSEADDR performs something different entirely.

    References

    • https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
    • diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index d8a765383..96a49927e 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -10,8 +10,8 @@ sha512 = "2c242489801a75466986fe014d730fb3aa7b5c6e56a230c8735e6672711b58bcbe92ba [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "b622db2755978a49d18d35d84d75f66b2b1ed23d7bf413e5c9e152e190cc7d4b" -sha512 = "d19c9004e75bf3ebe3e34cff498c3d7fee04cd57a7fba7ed12a0c5ad842ba5715c009de77a152c57da0500f6ca0986b6791b6f022829bdd5a024f7bc114c2ff6" +sha256 = "7a3c644dfd434f77fdf3f3d3b3caaca9538a0ade785167a3cce0321609f9d4e1" +sha512 = "2888f12b91359d630b4270f60e3c78855d9b305274ebf8a5decaef8698a74cc85c426823dc708b393f461b85ad991711d7400c2b2a24795001db5aee3ae19c70" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" @@ -20,5 +20,5 @@ sha512 = "cc4fa3d178559a89d9d6a376e3359b892158d1e73317c5db1f797ebc6b0b57abf24227 [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "b5c2e9cc87cefbaef06bbe9978f9bc336da9feee2d51747bc28e10164fc46c39" -sha512 = "3aea6fe0c768b27d5c5cb3adab5e60dc936198f8b677c2cf6c4d57a0460db87eb779e0b577f1240fb2a6bf3ade49919fbffe39b0137bce3242343e6091cc7510" +sha256 = "8bcfc6838515714d4bd6cbfb81bb2dd25c6d509c34d593fe6398a08ae825a0be" +sha512 = "85d23ff1478cd2bee5023c11ed75edaa918f14ad3f0d1142de88b3145a25189c40f4194421f1e234cc893091255c68e5b157e16682bcc5ae0993f78bed606504" diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index f6f7fe0e8..82e6e073e 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -32,6 +32,11 @@ interface streams { resource input-stream { /// Perform a non-blocking read from the stream. /// + /// When the source of a `read` is binary data, the bytes from the source + /// are returned verbatim. When the source of a `read` is known to the + /// implementation to be text, bytes containing the UTF-8 encoding of the + /// text are returned. + /// /// This function returns a list of bytes containing the read data, /// when successful. The returned list will contain up to `len` bytes; /// it may return fewer than requested, but not more. The list is @@ -111,6 +116,12 @@ interface streams { /// Perform a write. This function never blocks. /// + /// When the destination of a `write` is binary data, the bytes from + /// `contents` are written verbatim. When the destination of a `write` is + /// known to the implementation to be text, the bytes of `contents` are + /// transcoded from UTF-8 into the encoding of the destination and then + /// written. + /// /// Precondition: check-write gave permit of Ok(n) and contents has a /// length of less than or equal to n. Otherwise, this function will trap. /// diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit index 6bb07cd6f..9cadf0650 100644 --- a/proposals/cli/wit/deps/sockets/network.wit +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -18,8 +18,6 @@ interface network { /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. enum error-code { - // ### GENERAL ERRORS ### - /// Unknown error unknown, @@ -64,9 +62,6 @@ interface network { would-block, - - // ### TCP & UDP SOCKET ERRORS ### - /// The operation is not valid in the socket's current state. invalid-state, @@ -83,24 +78,21 @@ interface network { remote-unreachable, - // ### TCP SOCKET ERRORS ### - - /// The connection was forcefully rejected + /// The TCP connection was forcefully rejected connection-refused, - /// The connection was reset. + /// The TCP connection was reset. connection-reset, - /// A connection was aborted. + /// A TCP connection was aborted. connection-aborted, - // ### UDP SOCKET ERRORS ### + /// The size of a datagram sent to a UDP socket exceeded the maximum + /// supported size. datagram-too-large, - // ### NAME LOOKUP ERRORS ### - /// Name does not exist or has no suitable associated IP addresses. name-unresolvable, @@ -128,15 +120,21 @@ interface network { } record ipv4-socket-address { - port: u16, // sin_port - address: ipv4-address, // sin_addr + /// sin_port + port: u16, + /// sin_addr + address: ipv4-address, } record ipv6-socket-address { - port: u16, // sin6_port - flow-info: u32, // sin6_flowinfo - address: ipv6-address, // sin6_addr - scope-id: u32, // sin6_scope_id + /// sin6_port + port: u16, + /// sin6_flowinfo + flow-info: u32, + /// sin6_addr + address: ipv6-address, + /// sin6_scope_id + scope-id: u32, } variant ip-socket-address { diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index b01b65e6c..337d606d8 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -42,6 +42,12 @@ interface tcp { /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) /// - `not-in-progress`: A `bind` operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # Implementors note + /// When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT + /// state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR + /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior + /// and SO_REUSEADDR performs something different entirely. /// /// # References /// - diff --git a/proposals/cli/wit/terminal.wit b/proposals/cli/wit/terminal.wit index 47495769b..38c724efc 100644 --- a/proposals/cli/wit/terminal.wit +++ b/proposals/cli/wit/terminal.wit @@ -1,19 +1,21 @@ +/// Terminal input. +/// +/// In the future, this may include functions for disabling echoing, +/// disabling input buffering so that keyboard events are sent through +/// immediately, querying supported features, and so on. interface terminal-input { /// The input side of a terminal. resource terminal-input; - - // In the future, this may include functions for disabling echoing, - // disabling input buffering so that keyboard events are sent through - // immediately, querying supported features, and so on. } +/// Terminal output. +/// +/// In the future, this may include functions for querying the terminal +/// size, being notified of terminal size changes, querying supported +/// features, and so on. interface terminal-output { /// The output side of a terminal. resource terminal-output; - - // In the future, this may include functions for querying the terminal - // size, being notified of terminal size changes, querying supported - // features, and so on. } /// An interface providing an optional `terminal-input` for stdin as a From 4f4dcfc8a7ef246d1619accb9277d2b4d501040a Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Mon, 15 Jan 2024 21:23:51 +0100 Subject: [PATCH 1362/1772] Fix outdated docs --- proposals/sockets/wit/tcp-create-socket.wit | 2 +- proposals/sockets/wit/tcp.wit | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/proposals/sockets/wit/tcp-create-socket.wit b/proposals/sockets/wit/tcp-create-socket.wit index 768a07c85..852055cf0 100644 --- a/proposals/sockets/wit/tcp-create-socket.wit +++ b/proposals/sockets/wit/tcp-create-socket.wit @@ -8,7 +8,7 @@ interface tcp-create-socket { /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. /// /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 337d606d8..26badacf3 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -25,9 +25,6 @@ interface tcp { /// network interface(s) to bind to. /// If the TCP/UDP port is zero, the socket will be bound to a random free port. /// - /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will - /// implicitly bind the socket. - /// /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. /// /// # Typical `start` errors @@ -305,12 +302,13 @@ interface tcp { /// Initiate a graceful shutdown. /// - /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read - /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. - /// Any data still in the receive queue at time of calling `shutdown` will be discarded. - /// - send: the socket is not expecting to send any more data to the peer. All subsequent write - /// operations on the `output-stream` associated with this socket will return an error. - /// - both: same effect as receive & send combined. + /// - `receive`: The socket is not expecting to receive any data from + /// the peer. The `input-stream` associated with this socket will be + /// closed. Any data still in the receive queue at time of calling + /// this method will be discarded. + /// - `send`: The socket has no more data to send to the peer. The `output-stream` + /// associated with this socket will be closed and a FIN packet will be sent. + /// - `both`: Same effect as `receive` & `send` combined. /// /// The shutdown function does not close (drop) the socket. /// From 0e533a41fda339c997650343f68260a13eb56dbe Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Mon, 15 Jan 2024 21:46:34 +0100 Subject: [PATCH 1363/1772] Simplify `connect` error modes --- proposals/sockets/wit/tcp.wit | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 26badacf3..5c577d019 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -60,14 +60,8 @@ interface tcp { /// - the socket is transitioned into the Connection state /// - a pair of streams is returned that can be used to read & write to the connection /// - /// POSIX mentions: - /// > If connect() fails, the state of the socket is unspecified. Conforming applications should - /// > close the file descriptor and create a new socket before attempting to reconnect. - /// - /// WASI prescribes the following behavior: - /// - If `connect` fails because an input/state validation error, the socket should remain usable. - /// - If a connection was actually attempted but failed, the socket should become unusable for further network communication. - /// Besides `drop`, any method after such a failure may return an error. + /// After a failed connection attempt, the only valid action left is to + /// `drop` the socket. A single socket can not be used to connect more than once. /// /// # Typical `start` errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) From e8836c49ff6f433df30baeac084b4ade29ef6937 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Mon, 15 Jan 2024 22:05:11 +0100 Subject: [PATCH 1364/1772] Clarify behavior of calling `shutdown` multiple times. --- proposals/sockets/wit/tcp.wit | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 5c577d019..5ab74abb1 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -304,6 +304,9 @@ interface tcp { /// associated with this socket will be closed and a FIN packet will be sent. /// - `both`: Same effect as `receive` & `send` combined. /// + /// This function is idempotent. Shutting a down a direction more than once + /// has no effect and returns `ok`. + /// /// The shutdown function does not close (drop) the socket. /// /// # Typical errors From 431356fb2251d52d187584eb71cad4bc2edb83bb Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Mon, 15 Jan 2024 22:10:14 +0100 Subject: [PATCH 1365/1772] Update imports.md --- proposals/sockets/imports.md | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 4cc6c2cd7..a90b6aad3 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -1223,8 +1223,6 @@ occured.

      If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the TCP/UDP port is zero, the socket will be bound to a random free port.

      -

      When a socket is not explicitly bound, the first invocation to a listen or connect operation will -implicitly bind the socket.

      Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

      Typical start errors

        @@ -1279,17 +1277,8 @@ and SO_REUSEADDR performs something different entirely.

      • the socket is transitioned into the Connection state
      • a pair of streams is returned that can be used to read & write to the connection
      -

      POSIX mentions:

      -
      -

      If connect() fails, the state of the socket is unspecified. Conforming applications should -close the file descriptor and create a new socket before attempting to reconnect.

      -
      -

      WASI prescribes the following behavior:

      -
        -
      • If connect fails because an input/state validation error, the socket should remain usable.
      • -
      • If a connection was actually attempted but failed, the socket should become unusable for further network communication. -Besides drop, any method after such a failure may return an error.
      • -
      +

      After a failed connection attempt, the only valid action left is to +drop the socket. A single socket can not be used to connect more than once.

      Typical start errors

      • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
      • @@ -1740,13 +1729,16 @@ It's planned to be removed when future is natively supported in Pre

        [method]tcp-socket.shutdown: func

        Initiate a graceful shutdown.

          -
        • receive: the socket is not expecting to receive any more data from the peer. All subsequent read -operations on the input-stream associated with this socket will return an End Of Stream indication. -Any data still in the receive queue at time of calling shutdown will be discarded.
        • -
        • send: the socket is not expecting to send any more data to the peer. All subsequent write -operations on the output-stream associated with this socket will return an error.
        • -
        • both: same effect as receive & send combined.
        • +
        • receive: The socket is not expecting to receive any data from +the peer. The input-stream associated with this socket will be +closed. Any data still in the receive queue at time of calling +this method will be discarded.
        • +
        • send: The socket has no more data to send to the peer. The output-stream +associated with this socket will be closed and a FIN packet will be sent.
        • +
        • both: Same effect as receive & send combined.
        +

        This function is idempotent. Shutting a down a direction more than once +has no effect and returns ok.

        The shutdown function does not close (drop) the socket.

        Typical errors

          @@ -1789,7 +1781,7 @@ operations on the output-stream associ

          Create a new TCP socket.

          Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX.

          This function does not require a network capability handle. This is considered to be safe because -at time of creation, the socket is not bound to any network yet. Up to the moment bind/listen/connect +at time of creation, the socket is not bound to any network yet. Up to the moment bind/connect is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

          All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

          Typical errors

          From 35fa1dd14808289a136bd3cd2caf7ce8b04743eb Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Mon, 15 Jan 2024 23:12:52 +0100 Subject: [PATCH 1366/1772] Make `ipv6-only` the default and remove the ability to configure it. --- proposals/sockets/Posix-compatibility.md | 4 +- proposals/sockets/imports.md | 68 ++------------------- proposals/sockets/wit/tcp-create-socket.wit | 1 + proposals/sockets/wit/tcp.wit | 17 +----- proposals/sockets/wit/udp-create-socket.wit | 1 + proposals/sockets/wit/udp.wit | 13 ---- 6 files changed, 13 insertions(+), 91 deletions(-) diff --git a/proposals/sockets/Posix-compatibility.md b/proposals/sockets/Posix-compatibility.md index 26dfa2cdf..ae8853a02 100644 --- a/proposals/sockets/Posix-compatibility.md +++ b/proposals/sockets/Posix-compatibility.md @@ -139,6 +139,7 @@ Additionally, most columns have been populated semi-automatically by grepping th Legend: - ✅ = Included in proposal. +- ⚠️ = Partially supported. - ⛔ = Consciously decided _not_ to include in WASI. See notes for explanation. - ❔ = Not included (yet), for no particular reason. @@ -147,7 +148,6 @@ Legend: |----| ---------------------------------|-----------------------------------------|---------------------| | ✅ | SO_DOMAIN
          SO_PROTOCOL_INFO on Windows | [`tcp-socket::address-family`][tcp]
          [`udp-socket::address-family`][udp] | linux, windows, freebsd, .net | | ✅ | SO_ACCEPTCONN | [`tcp-socket::is-listening`][tcp] | posix, linux, windows, macos, freebsd, .net | -| ✅ | IPV6_V6ONLY | [`tcp-socket::(set-)ipv6-only`][tcp]
          [`udp-socket::(set-)ipv6-only`][udp] | posix, linux, windows, macos, freebsd, jvm, .net, libuv, go, openssl, curl, msquic, exim | | ✅ | IP_TTL | [`tcp-socket::(set-)hop-limit`][tcp]
          [`udp-socket::(set-)unicast-hop-limit`][udp] | linux, windows, macos, freebsd, jvm, .net, rust, libuv | | ✅ | IPV6_UNICAST_HOPS | [`tcp-socket::(set-)hop-limit`][tcp]
          [`udp-socket::(set-)unicast-hop-limit`][udp] | posix, linux, windows, macos, freebsd, jvm, .net, libuv | | ✅ | SO_RCVBUF | [`tcp-socket::(set-)receive-buffer-size`][tcp]
          [`udp-socket::(set-)receive-buffer-size`][udp] | posix, linux, windows, macos, freebsd, jvm, .net, libuv, go, nginx, msquic | @@ -157,6 +157,7 @@ Legend: | ✅ | TCP_KEEPINTVL | [`tcp-socket::(set-)keep-alive-interval`][tcp] | linux, windows, macos, freebsd, jvm, .net, libuv, go, nginx, curl | | ✅ | TCP_KEEPCNT | [`tcp-socket::(set-)keep-alive-count`][tcp] | linux, windows, macos, freebsd, jvm, .net, libuv, nginx | | ✅ | SO_REUSEADDR for TCP | Enabled by default. See [`tcp-socket::bind`][tcp] | posix, linux, windows, macos, freebsd, jvm, .net, libuv, go, openssl, nginx, curl, exim | +| ⚠️ | IPV6_V6ONLY | In WASI this always `true`. [#1][1] | posix, linux, windows, macos, freebsd, jvm, .net, libuv, go, openssl, curl, msquic, exim | | ⛔ | SO_ERROR | Not necessary. WIT has (or will have) native support for asynchronous results. | posix, linux, windows, macos, freebsd, jvm, .net, rust, libuv, go, openssl, nginx, curl, msquic | | ⛔ | SO_TYPE | Can be inferred from the socket resource type. | posix, linux, windows, macos, freebsd, jvm, .net, go, openssl, nginx, curl, exim | | ⛔ | SO_PROTOCOL
          SO_PROTOCOL_INFO on Windows | Can be inferred from the socket resource type. | linux, windows, freebsd, .net, exim | @@ -586,6 +587,7 @@ Legend: | ❔ | TCP_USE_CMP_ACKS | | freebsd | | ❔ | TCP_USER_LOG | | freebsd | +[1]: https://github.com/WebAssembly/wasi-sockets/issues/1 [17]: https://github.com/WebAssembly/wasi-sockets/issues/17 [34]: https://github.com/WebAssembly/wasi-sockets/issues/34 [73]: https://github.com/WebAssembly/wasi-sockets/issues/73 diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 4cc6c2cd7..940ffef26 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -403,7 +403,6 @@ if (remote_address is Some) {

          Typical errors

          • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
          • -
          • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
          • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
          • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
          • invalid-state: The socket is not bound.
          • @@ -486,33 +485,6 @@ stored in the object pointed to by address is unspecified.

            -

            [method]udp-socket.ipv6-only: func

            -

            Whether IPv4 compatibility (dual-stack) mode is disabled or not.

            -

            Equivalent to the IPV6_V6ONLY socket option.

            -

            Typical errors

            -
              -
            • not-supported: (get/set) this socket is an IPv4 socket.
            • -
            • invalid-state: (set) The socket is already bound.
            • -
            • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
            • -
            -
            Params
            - -
            Return values
            - -

            [method]udp-socket.set-ipv6-only: func

            -
            Params
            - -
            Return values
            -

            [method]udp-socket.unicast-hop-limit: func

            Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

            If the provided value is 0, an invalid-argument error is returned.

            @@ -675,7 +647,6 @@ either check-send was not called or datagrams contains

            Typical errors

            • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
            • -
            • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
            • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
            • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
            • invalid-argument: The socket is in "connected" mode and remote-address is some value that does not match the address passed to stream. (EISCONN)
            • @@ -735,7 +706,8 @@ It's planned to be removed when future is natively supported in Pre

              Functions

              create-udp-socket: func

              Create a new UDP socket.

              -

              Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.

              +

              Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX. +On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

              This function does not require a network capability handle. This is considered to be safe because at time of creation, the socket is not bound to any network yet. Up to the moment bind is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

              @@ -1230,7 +1202,7 @@ implicitly bind the socket.

              • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
              • invalid-argument: local-address is not a unicast address. (EINVAL)
              • -
              • invalid-argument: local-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL)
              • +
              • invalid-argument: local-address is an IPv4-mapped IPv6 address. (EINVAL)
              • invalid-state: The socket is already bound. (EINVAL)

              Typical finish errors

              @@ -1294,8 +1266,7 @@ Besides drop, any method after such a failure may return an error.<
              • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
              • invalid-argument: remote-address is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
              • -
              • invalid-argument: remote-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL, EADDRNOTAVAIL on Illumos)
              • -
              • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
              • +
              • invalid-argument: remote-address is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos)
              • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
              • invalid-argument: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
              • invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
              • @@ -1388,7 +1359,6 @@ Besides drop, any method after such a failure may return an error.<

                The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket:

                • address-family
                • -
                • ipv6-only
                • keep-alive-enabled
                • keep-alive-idle-time
                • keep-alive-interval
                • @@ -1491,33 +1461,6 @@ stored in the object pointed to by address is unspecified.

                  -

                  [method]tcp-socket.ipv6-only: func

                  -

                  Whether IPv4 compatibility (dual-stack) mode is disabled or not.

                  -

                  Equivalent to the IPV6_V6ONLY socket option.

                  -

                  Typical errors

                  -
                    -
                  • invalid-state: (set) The socket is already bound.
                  • -
                  • not-supported: (get/set) this socket is an IPv4 socket.
                  • -
                  • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
                  • -
                  -
                  Params
                  - -
                  Return values
                  - -

                  [method]tcp-socket.set-ipv6-only: func

                  -
                  Params
                  - -
                  Return values
                  -

                  [method]tcp-socket.set-listen-backlog-size: func

                  Hints the desired listen queue size. Implementations are free to ignore this.

                  If the provided value is 0, an invalid-argument error is returned. @@ -1787,7 +1730,8 @@ operations on the output-stream associ

                  Functions

                  create-tcp-socket: func

                  Create a new TCP socket.

                  -

                  Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX.

                  +

                  Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX. +On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

                  This function does not require a network capability handle. This is considered to be safe because at time of creation, the socket is not bound to any network yet. Up to the moment bind/listen/connect is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                  diff --git a/proposals/sockets/wit/tcp-create-socket.wit b/proposals/sockets/wit/tcp-create-socket.wit index 768a07c85..2dd937973 100644 --- a/proposals/sockets/wit/tcp-create-socket.wit +++ b/proposals/sockets/wit/tcp-create-socket.wit @@ -6,6 +6,7 @@ interface tcp-create-socket { /// Create a new TCP socket. /// /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. /// /// This function does not require a network capability handle. This is considered to be safe because /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 337d606d8..c543adb44 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -33,7 +33,7 @@ interface tcp { /// # Typical `start` errors /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) - /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address, but the socket has `ipv6-only` enabled. (EINVAL) + /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) /// - `invalid-state`: The socket is already bound. (EINVAL) /// /// # Typical `finish` errors @@ -75,8 +75,7 @@ interface tcp { /// # Typical `start` errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) - /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address, but the socket has `ipv6-only` enabled. (EINVAL, EADDRNOTAVAIL on Illumos) - /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) + /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. @@ -131,7 +130,6 @@ interface tcp { /// /// The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket: /// - `address-family` - /// - `ipv6-only` /// - `keep-alive-enabled` /// - `keep-alive-idle-time` /// - `keep-alive-interval` @@ -196,17 +194,6 @@ interface tcp { /// Equivalent to the SO_DOMAIN socket option. address-family: func() -> ip-address-family; - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `invalid-state`: (set) The socket is already bound. - /// - `not-supported`: (get/set) `this` socket is an IPv4 socket. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - ipv6-only: func() -> result; - set-ipv6-only: func(value: bool) -> result<_, error-code>; - /// Hints the desired listen queue size. Implementations are free to ignore this. /// /// If the provided value is 0, an `invalid-argument` error is returned. diff --git a/proposals/sockets/wit/udp-create-socket.wit b/proposals/sockets/wit/udp-create-socket.wit index cc58234d8..0482d1fe7 100644 --- a/proposals/sockets/wit/udp-create-socket.wit +++ b/proposals/sockets/wit/udp-create-socket.wit @@ -6,6 +6,7 @@ interface udp-create-socket { /// Create a new UDP socket. /// /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. /// /// This function does not require a network capability handle. This is considered to be safe because /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind` is called, diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index c8dafadfc..ae82b97fc 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -92,7 +92,6 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-state`: The socket is not bound. @@ -142,17 +141,6 @@ interface udp { /// Equivalent to the SO_DOMAIN socket option. address-family: func() -> ip-address-family; - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `not-supported`: (get/set) `this` socket is an IPv4 socket. - /// - `invalid-state`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - ipv6-only: func() -> result; - set-ipv6-only: func(value: bool) -> result<_, error-code>; - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// /// If the provided value is 0, an `invalid-argument` error is returned. @@ -248,7 +236,6 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `stream`. (EISCONN) From 5da7efe974b37829057437b6a450da681e99f85a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 16 Jan 2024 12:41:28 -0800 Subject: [PATCH 1367/1772] wasi-sockets package: set version to 0.2.0-rc-2024-01-16 --- proposals/sockets/wit/world.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index 49ad8d3d9..8588cc6c1 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.0-rc-2023-11-10; +package wasi:sockets@0.2.0-rc-2024-01-16; world imports { import instance-network; From c9987e33309f9c0d84936dfad9bf7cb28eba7498 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 16 Jan 2024 12:42:01 -0800 Subject: [PATCH 1368/1772] generate markdown --- proposals/sockets/imports.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index ae8c700ca..d764c0080 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -2,21 +2,21 @@ -

                  Import interface wasi:sockets/network@0.2.0-rc-2023-11-10

                  +

                  Import interface wasi:sockets/network@0.2.0-rc-2024-01-16


                  Types

                  resource network

                  @@ -209,7 +209,7 @@ supported size.
                • ipv4: ipv4-socket-address
                • ipv6: ipv6-socket-address
                -

                Import interface wasi:sockets/instance-network@0.2.0-rc-2023-11-10

                +

                Import interface wasi:sockets/instance-network@0.2.0-rc-2024-01-16

                This interface provides a value-export of the default network handle..


                Types

                @@ -274,7 +274,7 @@ being reaedy for I/O.

                • list<u32>
                -

                Import interface wasi:sockets/udp@0.2.0-rc-2023-11-10

                +

                Import interface wasi:sockets/udp@0.2.0-rc-2024-01-16


                Types

                type pollable

                @@ -687,7 +687,7 @@ It's planned to be removed when future is natively supported in Pre -

                Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2023-11-10

                +

                Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2024-01-16


                Types

                type network

                @@ -1144,7 +1144,7 @@ occured.

                -

                Import interface wasi:sockets/tcp@0.2.0-rc-2023-11-10

                +

                Import interface wasi:sockets/tcp@0.2.0-rc-2024-01-16


                Types

                type input-stream

                @@ -1703,7 +1703,7 @@ has no effect and returns ok.

                -

                Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2023-11-10

                +

                Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2024-01-16


                Types

                type network

                @@ -1748,7 +1748,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2023-11-10

                +

                Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2024-01-16


                Types

                type pollable

                From 7baec6b832fc05b5bc59e23f3816464fbc3a610c Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 16 Jan 2024 12:52:13 -0800 Subject: [PATCH 1369/1772] wit-deps update --- proposals/cli/wit/deps.lock | 4 +- .../wit/deps/sockets/tcp-create-socket.wit | 3 +- proposals/cli/wit/deps/sockets/tcp.wit | 46 ++++++------------- .../wit/deps/sockets/udp-create-socket.wit | 1 + proposals/cli/wit/deps/sockets/udp.wit | 13 ------ proposals/cli/wit/deps/sockets/world.wit | 2 +- 6 files changed, 20 insertions(+), 49 deletions(-) diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index 96a49927e..c891d86cc 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -20,5 +20,5 @@ sha512 = "cc4fa3d178559a89d9d6a376e3359b892158d1e73317c5db1f797ebc6b0b57abf24227 [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "8bcfc6838515714d4bd6cbfb81bb2dd25c6d509c34d593fe6398a08ae825a0be" -sha512 = "85d23ff1478cd2bee5023c11ed75edaa918f14ad3f0d1142de88b3145a25189c40f4194421f1e234cc893091255c68e5b157e16682bcc5ae0993f78bed606504" +sha256 = "40863017f355ac90c57630cc00b94518804e8e2c5694a7870b7a54dbdcda0e08" +sha512 = "2d6a919247430e869bf85a06a6a1d198f04368951e76c1fec7961b2b07af381c58c8e8b9079c91925dfbf80976971213329be57d59a90bae6e4e6460b073dc88" diff --git a/proposals/cli/wit/deps/sockets/tcp-create-socket.wit b/proposals/cli/wit/deps/sockets/tcp-create-socket.wit index 768a07c85..c7ddf1f22 100644 --- a/proposals/cli/wit/deps/sockets/tcp-create-socket.wit +++ b/proposals/cli/wit/deps/sockets/tcp-create-socket.wit @@ -6,9 +6,10 @@ interface tcp-create-socket { /// Create a new TCP socket. /// /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. /// /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index 337d606d8..e045a436a 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -25,15 +25,12 @@ interface tcp { /// network interface(s) to bind to. /// If the TCP/UDP port is zero, the socket will be bound to a random free port. /// - /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will - /// implicitly bind the socket. - /// /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. /// /// # Typical `start` errors /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) - /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address, but the socket has `ipv6-only` enabled. (EINVAL) + /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) /// - `invalid-state`: The socket is already bound. (EINVAL) /// /// # Typical `finish` errors @@ -63,20 +60,13 @@ interface tcp { /// - the socket is transitioned into the Connection state /// - a pair of streams is returned that can be used to read & write to the connection /// - /// POSIX mentions: - /// > If connect() fails, the state of the socket is unspecified. Conforming applications should - /// > close the file descriptor and create a new socket before attempting to reconnect. - /// - /// WASI prescribes the following behavior: - /// - If `connect` fails because an input/state validation error, the socket should remain usable. - /// - If a connection was actually attempted but failed, the socket should become unusable for further network communication. - /// Besides `drop`, any method after such a failure may return an error. + /// After a failed connection attempt, the only valid action left is to + /// `drop` the socket. A single socket can not be used to connect more than once. /// /// # Typical `start` errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) - /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address, but the socket has `ipv6-only` enabled. (EINVAL, EADDRNOTAVAIL on Illumos) - /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) + /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. @@ -131,7 +121,6 @@ interface tcp { /// /// The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket: /// - `address-family` - /// - `ipv6-only` /// - `keep-alive-enabled` /// - `keep-alive-idle-time` /// - `keep-alive-interval` @@ -196,17 +185,6 @@ interface tcp { /// Equivalent to the SO_DOMAIN socket option. address-family: func() -> ip-address-family; - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `invalid-state`: (set) The socket is already bound. - /// - `not-supported`: (get/set) `this` socket is an IPv4 socket. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - ipv6-only: func() -> result; - set-ipv6-only: func(value: bool) -> result<_, error-code>; - /// Hints the desired listen queue size. Implementations are free to ignore this. /// /// If the provided value is 0, an `invalid-argument` error is returned. @@ -305,12 +283,16 @@ interface tcp { /// Initiate a graceful shutdown. /// - /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read - /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. - /// Any data still in the receive queue at time of calling `shutdown` will be discarded. - /// - send: the socket is not expecting to send any more data to the peer. All subsequent write - /// operations on the `output-stream` associated with this socket will return an error. - /// - both: same effect as receive & send combined. + /// - `receive`: The socket is not expecting to receive any data from + /// the peer. The `input-stream` associated with this socket will be + /// closed. Any data still in the receive queue at time of calling + /// this method will be discarded. + /// - `send`: The socket has no more data to send to the peer. The `output-stream` + /// associated with this socket will be closed and a FIN packet will be sent. + /// - `both`: Same effect as `receive` & `send` combined. + /// + /// This function is idempotent. Shutting a down a direction more than once + /// has no effect and returns `ok`. /// /// The shutdown function does not close (drop) the socket. /// diff --git a/proposals/cli/wit/deps/sockets/udp-create-socket.wit b/proposals/cli/wit/deps/sockets/udp-create-socket.wit index cc58234d8..0482d1fe7 100644 --- a/proposals/cli/wit/deps/sockets/udp-create-socket.wit +++ b/proposals/cli/wit/deps/sockets/udp-create-socket.wit @@ -6,6 +6,7 @@ interface udp-create-socket { /// Create a new UDP socket. /// /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. /// /// This function does not require a network capability handle. This is considered to be safe because /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind` is called, diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index c8dafadfc..ae82b97fc 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -92,7 +92,6 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-state`: The socket is not bound. @@ -142,17 +141,6 @@ interface udp { /// Equivalent to the SO_DOMAIN socket option. address-family: func() -> ip-address-family; - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `not-supported`: (get/set) `this` socket is an IPv4 socket. - /// - `invalid-state`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - ipv6-only: func() -> result; - set-ipv6-only: func(value: bool) -> result<_, error-code>; - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// /// If the provided value is 0, an `invalid-argument` error is returned. @@ -248,7 +236,6 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `stream`. (EISCONN) diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit index 49ad8d3d9..8588cc6c1 100644 --- a/proposals/cli/wit/deps/sockets/world.wit +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.0-rc-2023-11-10; +package wasi:sockets@0.2.0-rc-2024-01-16; world imports { import instance-network; From 023531fa8a4f9d29d8edfa99ea1e5c4efc639141 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 16 Jan 2024 12:53:44 -0800 Subject: [PATCH 1370/1772] update import of sockets to rc-2024-01-16 --- proposals/cli/wit/imports.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/cli/wit/imports.wit b/proposals/cli/wit/imports.wit index 9965ea35e..3606a995c 100644 --- a/proposals/cli/wit/imports.wit +++ b/proposals/cli/wit/imports.wit @@ -3,7 +3,7 @@ package wasi:cli@0.2.0-rc-2023-12-05; world imports { include wasi:clocks/imports@0.2.0-rc-2023-11-10; include wasi:filesystem/imports@0.2.0-rc-2023-11-10; - include wasi:sockets/imports@0.2.0-rc-2023-11-10; + include wasi:sockets/imports@0.2.0-rc-2024-01-16; include wasi:random/imports@0.2.0-rc-2023-11-10; include wasi:io/imports@0.2.0-rc-2023-11-10; From aa083008ce869635d929335e01eebb407b2e59d2 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 16 Jan 2024 12:54:49 -0800 Subject: [PATCH 1371/1772] set wasi-cli package version to 0.2.0-rc-2024-01-16 --- proposals/cli/wit/command.wit | 2 +- proposals/cli/wit/imports.wit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index cc82ae5dc..a9889164f 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.0-rc-2023-12-05; +package wasi:cli@0.2.0-rc-2024-01-16; world command { include imports; diff --git a/proposals/cli/wit/imports.wit b/proposals/cli/wit/imports.wit index 3606a995c..8ce1abec3 100644 --- a/proposals/cli/wit/imports.wit +++ b/proposals/cli/wit/imports.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.0-rc-2023-12-05; +package wasi:cli@0.2.0-rc-2024-01-16; world imports { include wasi:clocks/imports@0.2.0-rc-2023-11-10; From 9919d4e2ec82c644ba48672587757fd704d9d7a6 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 16 Jan 2024 12:58:03 -0800 Subject: [PATCH 1372/1772] generate markdown --- proposals/cli/command.md | 172 ++++++++++++--------------------------- proposals/cli/imports.md | 168 ++++++++++++-------------------------- 2 files changed, 106 insertions(+), 234 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 2159bd3c1..263c2ac06 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -2,30 +2,30 @@ -

                Import interface wasi:sockets/instance-network@0.2.0-rc-2023-11-10

                +

                Import interface wasi:sockets/instance-network@0.2.0-rc-2024-01-16

                This interface provides a value-export of the default network handle..


                Types

                @@ -1795,7 +1795,7 @@ supported size. -

                Import interface wasi:sockets/udp@0.2.0-rc-2023-11-10

                +

                Import interface wasi:sockets/udp@0.2.0-rc-2024-01-16


                Types

                type pollable

                @@ -1924,7 +1924,6 @@ if (remote_address is Some) {

                Typical errors

                • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
                • -
                • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
                • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
                • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
                • invalid-state: The socket is not bound.
                • @@ -2007,33 +2006,6 @@ stored in the object pointed to by address is unspecified.

                  -

                  [method]udp-socket.ipv6-only: func

                  -

                  Whether IPv4 compatibility (dual-stack) mode is disabled or not.

                  -

                  Equivalent to the IPV6_V6ONLY socket option.

                  -

                  Typical errors

                  -
                    -
                  • not-supported: (get/set) this socket is an IPv4 socket.
                  • -
                  • invalid-state: (set) The socket is already bound.
                  • -
                  • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
                  • -
                  -
                  Params
                  - -
                  Return values
                  - -

                  [method]udp-socket.set-ipv6-only: func

                  -
                  Params
                  - -
                  Return values
                  -

                  [method]udp-socket.unicast-hop-limit: func

                  Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                  If the provided value is 0, an invalid-argument error is returned.

                  @@ -2196,7 +2168,6 @@ either check-send was not called or datagrams contains

                  Typical errors

                  • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
                  • -
                  • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
                  • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
                  • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
                  • invalid-argument: The socket is in "connected" mode and remote-address is some value that does not match the address passed to stream. (EISCONN)
                  • @@ -2237,7 +2208,7 @@ It's planned to be removed when future is natively supported in Pre -

                    Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2023-11-10

                    +

                    Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2024-01-16


                    Types

                    type network

                    @@ -2256,7 +2227,8 @@ It's planned to be removed when future is natively supported in Pre

                    Functions

                    create-udp-socket: func

                    Create a new UDP socket.

                    -

                    Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.

                    +

                    Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX. +On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

                    This function does not require a network capability handle. This is considered to be safe because at time of creation, the socket is not bound to any network yet. Up to the moment bind is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                    @@ -2281,7 +2253,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                    Import interface wasi:sockets/tcp@0.2.0-rc-2023-11-10

                    +

                    Import interface wasi:sockets/tcp@0.2.0-rc-2024-01-16


                    Types

                    type input-stream

                    @@ -2332,14 +2304,12 @@ the socket is effectively an in-memory configuration object, unable to communica

                    If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the TCP/UDP port is zero, the socket will be bound to a random free port.

                    -

                    When a socket is not explicitly bound, the first invocation to a listen or connect operation will -implicitly bind the socket.

                    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                    Typical start errors

                    • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
                    • invalid-argument: local-address is not a unicast address. (EINVAL)
                    • -
                    • invalid-argument: local-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL)
                    • +
                    • invalid-argument: local-address is an IPv4-mapped IPv6 address. (EINVAL)
                    • invalid-state: The socket is already bound. (EINVAL)

                    Typical finish errors

                    @@ -2388,23 +2358,13 @@ and SO_REUSEADDR performs something different entirely.

                  • the socket is transitioned into the Connection state
                  • a pair of streams is returned that can be used to read & write to the connection
                  -

                  POSIX mentions:

                  -
                  -

                  If connect() fails, the state of the socket is unspecified. Conforming applications should -close the file descriptor and create a new socket before attempting to reconnect.

                  -
                  -

                  WASI prescribes the following behavior:

                  -
                    -
                  • If connect fails because an input/state validation error, the socket should remain usable.
                  • -
                  • If a connection was actually attempted but failed, the socket should become unusable for further network communication. -Besides drop, any method after such a failure may return an error.
                  • -
                  +

                  After a failed connection attempt, the only valid action left is to +drop the socket. A single socket can not be used to connect more than once.

                  Typical start errors

                  • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
                  • invalid-argument: remote-address is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
                  • -
                  • invalid-argument: remote-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL, EADDRNOTAVAIL on Illumos)
                  • -
                  • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
                  • +
                  • invalid-argument: remote-address is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos)
                  • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
                  • invalid-argument: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
                  • invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
                  • @@ -2497,7 +2457,6 @@ Besides drop, any method after such a failure may return an error.<

                    The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket:

                    • address-family
                    • -
                    • ipv6-only
                    • keep-alive-enabled
                    • keep-alive-idle-time
                    • keep-alive-interval
                    • @@ -2600,33 +2559,6 @@ stored in the object pointed to by address is unspecified.

                      -

                      [method]tcp-socket.ipv6-only: func

                      -

                      Whether IPv4 compatibility (dual-stack) mode is disabled or not.

                      -

                      Equivalent to the IPV6_V6ONLY socket option.

                      -

                      Typical errors

                      -
                        -
                      • invalid-state: (set) The socket is already bound.
                      • -
                      • not-supported: (get/set) this socket is an IPv4 socket.
                      • -
                      • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
                      • -
                      -
                      Params
                      - -
                      Return values
                      - -

                      [method]tcp-socket.set-ipv6-only: func

                      -
                      Params
                      - -
                      Return values
                      -

                      [method]tcp-socket.set-listen-backlog-size: func

                      Hints the desired listen queue size. Implementations are free to ignore this.

                      If the provided value is 0, an invalid-argument error is returned. @@ -2849,13 +2781,16 @@ It's planned to be removed when future is natively supported in Pre

                      [method]tcp-socket.shutdown: func

                      Initiate a graceful shutdown.

                        -
                      • receive: the socket is not expecting to receive any more data from the peer. All subsequent read -operations on the input-stream associated with this socket will return an End Of Stream indication. -Any data still in the receive queue at time of calling shutdown will be discarded.
                      • -
                      • send: the socket is not expecting to send any more data to the peer. All subsequent write -operations on the output-stream associated with this socket will return an error.
                      • -
                      • both: same effect as receive & send combined.
                      • +
                      • receive: The socket is not expecting to receive any data from +the peer. The input-stream associated with this socket will be +closed. Any data still in the receive queue at time of calling +this method will be discarded.
                      • +
                      • send: The socket has no more data to send to the peer. The output-stream +associated with this socket will be closed and a FIN packet will be sent.
                      • +
                      • both: Same effect as receive & send combined.
                      +

                      This function is idempotent. Shutting a down a direction more than once +has no effect and returns ok.

                      The shutdown function does not close (drop) the socket.

                      Typical errors

                      -

                      Import interface wasi:sockets/instance-network@0.2.0-rc-2023-11-10

                      +

                      Import interface wasi:sockets/instance-network@0.2.0-rc-2024-01-16

                      This interface provides a value-export of the default network handle..


                      Types

                      @@ -1790,7 +1790,7 @@ supported size. -

                      Import interface wasi:sockets/udp@0.2.0-rc-2023-11-10

                      +

                      Import interface wasi:sockets/udp@0.2.0-rc-2024-01-16


                      Types

                      type pollable

                      @@ -1919,7 +1919,6 @@ if (remote_address is Some) {

                      Typical errors

                      • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
                      • -
                      • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
                      • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
                      • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
                      • invalid-state: The socket is not bound.
                      • @@ -2002,33 +2001,6 @@ stored in the object pointed to by address is unspecified.

                        -

                        [method]udp-socket.ipv6-only: func

                        -

                        Whether IPv4 compatibility (dual-stack) mode is disabled or not.

                        -

                        Equivalent to the IPV6_V6ONLY socket option.

                        -

                        Typical errors

                        -
                          -
                        • not-supported: (get/set) this socket is an IPv4 socket.
                        • -
                        • invalid-state: (set) The socket is already bound.
                        • -
                        • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
                        • -
                        -
                        Params
                        - -
                        Return values
                        - -

                        [method]udp-socket.set-ipv6-only: func

                        -
                        Params
                        - -
                        Return values
                        -

                        [method]udp-socket.unicast-hop-limit: func

                        Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                        If the provided value is 0, an invalid-argument error is returned.

                        @@ -2191,7 +2163,6 @@ either check-send was not called or datagrams contains

                        Typical errors

                        • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
                        • -
                        • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
                        • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
                        • invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
                        • invalid-argument: The socket is in "connected" mode and remote-address is some value that does not match the address passed to stream. (EISCONN)
                        • @@ -2232,7 +2203,7 @@ It's planned to be removed when future is natively supported in Pre -

                          Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2023-11-10

                          +

                          Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2024-01-16


                          Types

                          type network

                          @@ -2251,7 +2222,8 @@ It's planned to be removed when future is natively supported in Pre

                          Functions

                          create-udp-socket: func

                          Create a new UDP socket.

                          -

                          Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.

                          +

                          Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX. +On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

                          This function does not require a network capability handle. This is considered to be safe because at time of creation, the socket is not bound to any network yet. Up to the moment bind is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                          @@ -2276,7 +2248,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                          Import interface wasi:sockets/tcp@0.2.0-rc-2023-11-10

                          +

                          Import interface wasi:sockets/tcp@0.2.0-rc-2024-01-16


                          Types

                          type input-stream

                          @@ -2327,14 +2299,12 @@ the socket is effectively an in-memory configuration object, unable to communica

                          If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the TCP/UDP port is zero, the socket will be bound to a random free port.

                          -

                          When a socket is not explicitly bound, the first invocation to a listen or connect operation will -implicitly bind the socket.

                          Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                          Typical start errors

                          • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
                          • invalid-argument: local-address is not a unicast address. (EINVAL)
                          • -
                          • invalid-argument: local-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL)
                          • +
                          • invalid-argument: local-address is an IPv4-mapped IPv6 address. (EINVAL)
                          • invalid-state: The socket is already bound. (EINVAL)

                          Typical finish errors

                          @@ -2383,23 +2353,13 @@ and SO_REUSEADDR performs something different entirely.

                        • the socket is transitioned into the Connection state
                        • a pair of streams is returned that can be used to read & write to the connection
                        -

                        POSIX mentions:

                        -
                        -

                        If connect() fails, the state of the socket is unspecified. Conforming applications should -close the file descriptor and create a new socket before attempting to reconnect.

                        -
                        -

                        WASI prescribes the following behavior:

                        -
                          -
                        • If connect fails because an input/state validation error, the socket should remain usable.
                        • -
                        • If a connection was actually attempted but failed, the socket should become unusable for further network communication. -Besides drop, any method after such a failure may return an error.
                        • -
                        +

                        After a failed connection attempt, the only valid action left is to +drop the socket. A single socket can not be used to connect more than once.

                        Typical start errors

                        • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
                        • invalid-argument: remote-address is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
                        • -
                        • invalid-argument: remote-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL, EADDRNOTAVAIL on Illumos)
                        • -
                        • invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
                        • +
                        • invalid-argument: remote-address is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos)
                        • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
                        • invalid-argument: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
                        • invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
                        • @@ -2492,7 +2452,6 @@ Besides drop, any method after such a failure may return an error.<

                          The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket:

                          • address-family
                          • -
                          • ipv6-only
                          • keep-alive-enabled
                          • keep-alive-idle-time
                          • keep-alive-interval
                          • @@ -2595,33 +2554,6 @@ stored in the object pointed to by address is unspecified.

                            -

                            [method]tcp-socket.ipv6-only: func

                            -

                            Whether IPv4 compatibility (dual-stack) mode is disabled or not.

                            -

                            Equivalent to the IPV6_V6ONLY socket option.

                            -

                            Typical errors

                            -
                              -
                            • invalid-state: (set) The socket is already bound.
                            • -
                            • not-supported: (get/set) this socket is an IPv4 socket.
                            • -
                            • not-supported: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
                            • -
                            -
                            Params
                            - -
                            Return values
                            - -

                            [method]tcp-socket.set-ipv6-only: func

                            -
                            Params
                            - -
                            Return values
                            -

                            [method]tcp-socket.set-listen-backlog-size: func

                            Hints the desired listen queue size. Implementations are free to ignore this.

                            If the provided value is 0, an invalid-argument error is returned. @@ -2844,13 +2776,16 @@ It's planned to be removed when future is natively supported in Pre

                            [method]tcp-socket.shutdown: func

                            Initiate a graceful shutdown.

                              -
                            • receive: the socket is not expecting to receive any more data from the peer. All subsequent read -operations on the input-stream associated with this socket will return an End Of Stream indication. -Any data still in the receive queue at time of calling shutdown will be discarded.
                            • -
                            • send: the socket is not expecting to send any more data to the peer. All subsequent write -operations on the output-stream associated with this socket will return an error.
                            • -
                            • both: same effect as receive & send combined.
                            • +
                            • receive: The socket is not expecting to receive any data from +the peer. The input-stream associated with this socket will be +closed. Any data still in the receive queue at time of calling +this method will be discarded.
                            • +
                            • send: The socket has no more data to send to the peer. The output-stream +associated with this socket will be closed and a FIN packet will be sent.
                            • +
                            • both: Same effect as receive & send combined.
                            +

                            This function is idempotent. Shutting a down a direction more than once +has no effect and returns ok.

                            The shutdown function does not close (drop) the socket.

                            Typical errors

                              @@ -2872,7 +2807,7 @@ operations on the output-stream associ -

                              Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2023-11-10

                              +

                              Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2024-01-16


                              Types

                              type network

                              @@ -2891,9 +2826,10 @@ operations on the output-stream associ

                              Functions

                              create-tcp-socket: func

                              Create a new TCP socket.

                              -

                              Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX.

                              +

                              Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX. +On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

                              This function does not require a network capability handle. This is considered to be safe because -at time of creation, the socket is not bound to any network yet. Up to the moment bind/listen/connect +at time of creation, the socket is not bound to any network yet. Up to the moment bind/connect is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.

                              All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.

                              Typical errors

                              @@ -2916,7 +2852,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                              Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2023-11-10

                              +

                              Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2024-01-16


                              Types

                              type pollable

                              From aafdb3c7cdb4f6d4d88163f066e823d532798461 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 16 Jan 2024 13:37:37 -0800 Subject: [PATCH 1373/1772] TCP state machine --- proposals/sockets/README.md | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 4f94d6229..6d9a25eeb 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -195,6 +195,44 @@ The most likely contenders for permission prompt interception are: Now, again, this proposal does not specify if/how permission prompts should be implemented. However, it does at least facilitate the ability for runtimes to do so. Since waiting for user input takes an unknowable amount of time, the operations listed above have been made asynchronous. POSIX-compatibility layers can simply synchronously block on the returned `future`s. +### TCP State Machine + +The TCP valid states can be described by the following diagram: + +```mermaid +stateDiagram-v2 + [*] --> TCP_INIT: tcpSocketCreate() [RESOLVED] + [*] --> TCP_CONNECTION: accept() [RESOLVED] + TCP_INIT --> TCP_BIND: startBind() [WAIT] + TCP_BIND --> TCP_BIND_READY: permission granted [RESOLVED] + TCP_BIND --> TCP_INIT: permission denied [RESOLVED] + TCP_BIND_READY --> TCP_BOUND: finishBind() [RESOLVED] + TCP_BIND_READY --> TCP_ERROR: finishBind() error [RESOLVED] + TCP_INIT --> TCP_CONNECT: startConnect() [WAIT] + TCP_BOUND --> TCP_CONNECT: startConnect() [WAIT] + TCP_CONNECT --> TCP_CONNECT_READY: permission granted [RESOLVED] + TCP_CONNECT --> TCP_ERROR: permission denied [RESOLVED] + TCP_CONNECT_READY --> TCP_CONNECTION: finishConnect() [RESOLVED] + TCP_CONNECT_READY --> TCP_ERROR: finishConnect() error [RESOLVED] + TCP_BOUND --> TCP_LISTEN: startListen() [WAIT] + TCP_LISTEN --> TCP_LISTEN_READY: permission granted [RESOLVED] + TCP_LISTEN --> TCP_ERROR: permission denied [RESOLVED] + TCP_LISTEN_READY --> TCP_LISTENER: finishListen() [RESOLVED] + TCP_LISTEN_READY --> TCP_ERROR: finishListen() error [RESOLVED] + TCP_CONNECTION --> TCP_CLOSED: shutdown() [RESOLVED] + TCP_LISTENER --> TCP_CLOSED: shutdown() [RESOLVED] + + +``` + +where the given methods synchronously transition the state when they are called. All method calls not on these state transition paths throw `invalid-state`. + +The state of the pollable for the TCP state machine is provided as `[RESOLVED]` or `[WAIT]` in the above, where a transition from `[WAIT] -> [RESOLVED]` in the above state diagram corresponds to an event that can be polled on for the subscription. + +Once the TCP state machine is in the `TCP_CONNECTION` or `TCP_LISTENER` state, the pollable state is instantaneously updated to the state of the underlying socket IO - `[RESOLVED]` if there is pending IO, and `[UNRESOLVED]` otherwise. This means it is possible for the `finishConnect()` call to instantaneously transition the pollable to resolved and then back to unresolved if there is no data ready on the underlying socket. + +The TCP socket can be dropped in all states, performing the necessary cleanup. There are no traps associated with any state transitions. + ### Considered alternatives [This section is not required if you already covered considered alternatives in the design discussion above.] From 508f3b104a6389fc7dc1e05c462c726b80ba0bfe Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 16 Jan 2024 13:45:05 -0800 Subject: [PATCH 1374/1772] permission denied is recoverable --- proposals/sockets/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 6d9a25eeb..eccdac0ec 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -211,12 +211,13 @@ stateDiagram-v2 TCP_INIT --> TCP_CONNECT: startConnect() [WAIT] TCP_BOUND --> TCP_CONNECT: startConnect() [WAIT] TCP_CONNECT --> TCP_CONNECT_READY: permission granted [RESOLVED] - TCP_CONNECT --> TCP_ERROR: permission denied [RESOLVED] + TCP_CONNECT --> TCP_INIT: permission denied [RESOLVED] + TCP_CONNECT --> TCP_BOUND: permission denied [RESOLVED] TCP_CONNECT_READY --> TCP_CONNECTION: finishConnect() [RESOLVED] TCP_CONNECT_READY --> TCP_ERROR: finishConnect() error [RESOLVED] TCP_BOUND --> TCP_LISTEN: startListen() [WAIT] TCP_LISTEN --> TCP_LISTEN_READY: permission granted [RESOLVED] - TCP_LISTEN --> TCP_ERROR: permission denied [RESOLVED] + TCP_LISTEN --> TCP_BOUND: permission denied [RESOLVED] TCP_LISTEN_READY --> TCP_LISTENER: finishListen() [RESOLVED] TCP_LISTEN_READY --> TCP_ERROR: finishListen() error [RESOLVED] TCP_CONNECTION --> TCP_CLOSED: shutdown() [RESOLVED] @@ -227,7 +228,7 @@ stateDiagram-v2 where the given methods synchronously transition the state when they are called. All method calls not on these state transition paths throw `invalid-state`. -The state of the pollable for the TCP state machine is provided as `[RESOLVED]` or `[WAIT]` in the above, where a transition from `[WAIT] -> [RESOLVED]` in the above state diagram corresponds to an event that can be polled on for the subscription. +The state of the pollable for the TCP state machine is provided as `[RESOLVED]` or `[WAIT]` in the above, where a transition from `[WAIT] -> [RESOLVED]` in the above state diagram corresponds to an event that can be polled on for the subscription. Permission denied errors are recoverable if the permissions dynamically change. Once the TCP state machine is in the `TCP_CONNECTION` or `TCP_LISTENER` state, the pollable state is instantaneously updated to the state of the underlying socket IO - `[RESOLVED]` if there is pending IO, and `[UNRESOLVED]` otherwise. This means it is possible for the `finishConnect()` call to instantaneously transition the pollable to resolved and then back to unresolved if there is no data ready on the underlying socket. From a77b0629f062b8dd56e394e3fd655389afb5cbf3 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 16 Jan 2024 13:47:05 -0800 Subject: [PATCH 1375/1772] note invalid state recoverability --- proposals/sockets/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index eccdac0ec..ca2f18d99 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -226,7 +226,7 @@ stateDiagram-v2 ``` -where the given methods synchronously transition the state when they are called. All method calls not on these state transition paths throw `invalid-state`. +where the given methods synchronously transition the state when they are called. All method calls not on these state transition paths throw `invalid-state` while remaining in the current state (therefore always being recoverable). The state of the pollable for the TCP state machine is provided as `[RESOLVED]` or `[WAIT]` in the above, where a transition from `[WAIT] -> [RESOLVED]` in the above state diagram corresponds to an event that can be polled on for the subscription. Permission denied errors are recoverable if the permissions dynamically change. From ea7bdff048b89549d1236f4ae537c26f2633df6b Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 16 Jan 2024 13:51:25 -0800 Subject: [PATCH 1376/1772] adjustments around recoverable wording --- proposals/sockets/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index ca2f18d99..bad6b6920 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -226,9 +226,9 @@ stateDiagram-v2 ``` -where the given methods synchronously transition the state when they are called. All method calls not on these state transition paths throw `invalid-state` while remaining in the current state (therefore always being recoverable). +where the given methods synchronously transition the state when they are called. All method calls not on these state transition paths throw `invalid-state` while remaining in the current state, therefore always being recoverable by not transitioning the socket into the error state. -The state of the pollable for the TCP state machine is provided as `[RESOLVED]` or `[WAIT]` in the above, where a transition from `[WAIT] -> [RESOLVED]` in the above state diagram corresponds to an event that can be polled on for the subscription. Permission denied errors are recoverable if the permissions dynamically change. +The state of the pollable for the TCP state machine is provided as `[RESOLVED]` or `[WAIT]` in the above, where a transition from `[WAIT] -> [RESOLVED]` in the above state diagram corresponds to an event that can be polled on for the subscription. Permission denied errors are retriable if the permissions dynamically change, and do not transition into the socket error state. Once the TCP state machine is in the `TCP_CONNECTION` or `TCP_LISTENER` state, the pollable state is instantaneously updated to the state of the underlying socket IO - `[RESOLVED]` if there is pending IO, and `[UNRESOLVED]` otherwise. This means it is possible for the `finishConnect()` call to instantaneously transition the pollable to resolved and then back to unresolved if there is no data ready on the underlying socket. From 3904b8406f3cf2f90c94add6f5fb671790c36565 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 16 Jan 2024 14:09:18 -0800 Subject: [PATCH 1377/1772] wit-deps update --- proposals/http/wit/deps.lock | 12 ++--- proposals/http/wit/deps/cli/command.wit | 2 +- proposals/http/wit/deps/cli/imports.wit | 4 +- proposals/http/wit/deps/cli/terminal.wit | 18 ++++--- proposals/http/wit/deps/io/streams.wit | 11 ++++ proposals/http/wit/deps/sockets/network.wit | 36 ++++++------- .../wit/deps/sockets/tcp-create-socket.wit | 3 +- proposals/http/wit/deps/sockets/tcp.wit | 52 +++++++------------ .../wit/deps/sockets/udp-create-socket.wit | 1 + proposals/http/wit/deps/sockets/udp.wit | 13 ----- proposals/http/wit/deps/sockets/world.wit | 2 +- 11 files changed, 71 insertions(+), 83 deletions(-) diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 01efeefbc..500fe9d51 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,7 +1,7 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -sha256 = "6894203a2ac50a68f6b91f2174826c2987cc0efc94ad1f8f14f8460e262fc103" -sha512 = "349776db1b1455e176ca61a1a8ec653f77b888d291e948feded3b6b46350c65973e9e75cc0bf8649256654001af2408eacc585c31454008c86ff53b301da5c32" +sha256 = "754f9d1de112e106cc7131b79b1efd29340f9d6191699f224835fd41521ba386" +sha512 = "908a67492c05f752b0152646e5acdccdde89d8b303db254bf462d2e6714c420d80ebebc46ab75b8953c060a06ea06d99d55b523f6aa09e2f4f16d5e63649f0ea" [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" @@ -15,8 +15,8 @@ sha512 = "2c242489801a75466986fe014d730fb3aa7b5c6e56a230c8735e6672711b58bcbe92ba [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "b622db2755978a49d18d35d84d75f66b2b1ed23d7bf413e5c9e152e190cc7d4b" -sha512 = "d19c9004e75bf3ebe3e34cff498c3d7fee04cd57a7fba7ed12a0c5ad842ba5715c009de77a152c57da0500f6ca0986b6791b6f022829bdd5a024f7bc114c2ff6" +sha256 = "7a3c644dfd434f77fdf3f3d3b3caaca9538a0ade785167a3cce0321609f9d4e1" +sha512 = "2888f12b91359d630b4270f60e3c78855d9b305274ebf8a5decaef8698a74cc85c426823dc708b393f461b85ad991711d7400c2b2a24795001db5aee3ae19c70" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" @@ -25,5 +25,5 @@ sha512 = "cc4fa3d178559a89d9d6a376e3359b892158d1e73317c5db1f797ebc6b0b57abf24227 [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "b5c2e9cc87cefbaef06bbe9978f9bc336da9feee2d51747bc28e10164fc46c39" -sha512 = "3aea6fe0c768b27d5c5cb3adab5e60dc936198f8b677c2cf6c4d57a0460db87eb779e0b577f1240fb2a6bf3ade49919fbffe39b0137bce3242343e6091cc7510" +sha256 = "40863017f355ac90c57630cc00b94518804e8e2c5694a7870b7a54dbdcda0e08" +sha512 = "2d6a919247430e869bf85a06a6a1d198f04368951e76c1fec7961b2b07af381c58c8e8b9079c91925dfbf80976971213329be57d59a90bae6e4e6460b073dc88" diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit index cc82ae5dc..a9889164f 100644 --- a/proposals/http/wit/deps/cli/command.wit +++ b/proposals/http/wit/deps/cli/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.0-rc-2023-12-05; +package wasi:cli@0.2.0-rc-2024-01-16; world command { include imports; diff --git a/proposals/http/wit/deps/cli/imports.wit b/proposals/http/wit/deps/cli/imports.wit index 9965ea35e..8ce1abec3 100644 --- a/proposals/http/wit/deps/cli/imports.wit +++ b/proposals/http/wit/deps/cli/imports.wit @@ -1,9 +1,9 @@ -package wasi:cli@0.2.0-rc-2023-12-05; +package wasi:cli@0.2.0-rc-2024-01-16; world imports { include wasi:clocks/imports@0.2.0-rc-2023-11-10; include wasi:filesystem/imports@0.2.0-rc-2023-11-10; - include wasi:sockets/imports@0.2.0-rc-2023-11-10; + include wasi:sockets/imports@0.2.0-rc-2024-01-16; include wasi:random/imports@0.2.0-rc-2023-11-10; include wasi:io/imports@0.2.0-rc-2023-11-10; diff --git a/proposals/http/wit/deps/cli/terminal.wit b/proposals/http/wit/deps/cli/terminal.wit index 47495769b..38c724efc 100644 --- a/proposals/http/wit/deps/cli/terminal.wit +++ b/proposals/http/wit/deps/cli/terminal.wit @@ -1,19 +1,21 @@ +/// Terminal input. +/// +/// In the future, this may include functions for disabling echoing, +/// disabling input buffering so that keyboard events are sent through +/// immediately, querying supported features, and so on. interface terminal-input { /// The input side of a terminal. resource terminal-input; - - // In the future, this may include functions for disabling echoing, - // disabling input buffering so that keyboard events are sent through - // immediately, querying supported features, and so on. } +/// Terminal output. +/// +/// In the future, this may include functions for querying the terminal +/// size, being notified of terminal size changes, querying supported +/// features, and so on. interface terminal-output { /// The output side of a terminal. resource terminal-output; - - // In the future, this may include functions for querying the terminal - // size, being notified of terminal size changes, querying supported - // features, and so on. } /// An interface providing an optional `terminal-input` for stdin as a diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index f6f7fe0e8..82e6e073e 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -32,6 +32,11 @@ interface streams { resource input-stream { /// Perform a non-blocking read from the stream. /// + /// When the source of a `read` is binary data, the bytes from the source + /// are returned verbatim. When the source of a `read` is known to the + /// implementation to be text, bytes containing the UTF-8 encoding of the + /// text are returned. + /// /// This function returns a list of bytes containing the read data, /// when successful. The returned list will contain up to `len` bytes; /// it may return fewer than requested, but not more. The list is @@ -111,6 +116,12 @@ interface streams { /// Perform a write. This function never blocks. /// + /// When the destination of a `write` is binary data, the bytes from + /// `contents` are written verbatim. When the destination of a `write` is + /// known to the implementation to be text, the bytes of `contents` are + /// transcoded from UTF-8 into the encoding of the destination and then + /// written. + /// /// Precondition: check-write gave permit of Ok(n) and contents has a /// length of less than or equal to n. Otherwise, this function will trap. /// diff --git a/proposals/http/wit/deps/sockets/network.wit b/proposals/http/wit/deps/sockets/network.wit index 6bb07cd6f..9cadf0650 100644 --- a/proposals/http/wit/deps/sockets/network.wit +++ b/proposals/http/wit/deps/sockets/network.wit @@ -18,8 +18,6 @@ interface network { /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. enum error-code { - // ### GENERAL ERRORS ### - /// Unknown error unknown, @@ -64,9 +62,6 @@ interface network { would-block, - - // ### TCP & UDP SOCKET ERRORS ### - /// The operation is not valid in the socket's current state. invalid-state, @@ -83,24 +78,21 @@ interface network { remote-unreachable, - // ### TCP SOCKET ERRORS ### - - /// The connection was forcefully rejected + /// The TCP connection was forcefully rejected connection-refused, - /// The connection was reset. + /// The TCP connection was reset. connection-reset, - /// A connection was aborted. + /// A TCP connection was aborted. connection-aborted, - // ### UDP SOCKET ERRORS ### + /// The size of a datagram sent to a UDP socket exceeded the maximum + /// supported size. datagram-too-large, - // ### NAME LOOKUP ERRORS ### - /// Name does not exist or has no suitable associated IP addresses. name-unresolvable, @@ -128,15 +120,21 @@ interface network { } record ipv4-socket-address { - port: u16, // sin_port - address: ipv4-address, // sin_addr + /// sin_port + port: u16, + /// sin_addr + address: ipv4-address, } record ipv6-socket-address { - port: u16, // sin6_port - flow-info: u32, // sin6_flowinfo - address: ipv6-address, // sin6_addr - scope-id: u32, // sin6_scope_id + /// sin6_port + port: u16, + /// sin6_flowinfo + flow-info: u32, + /// sin6_addr + address: ipv6-address, + /// sin6_scope_id + scope-id: u32, } variant ip-socket-address { diff --git a/proposals/http/wit/deps/sockets/tcp-create-socket.wit b/proposals/http/wit/deps/sockets/tcp-create-socket.wit index 768a07c85..c7ddf1f22 100644 --- a/proposals/http/wit/deps/sockets/tcp-create-socket.wit +++ b/proposals/http/wit/deps/sockets/tcp-create-socket.wit @@ -6,9 +6,10 @@ interface tcp-create-socket { /// Create a new TCP socket. /// /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. /// /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. /// /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index b01b65e6c..e045a436a 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -25,15 +25,12 @@ interface tcp { /// network interface(s) to bind to. /// If the TCP/UDP port is zero, the socket will be bound to a random free port. /// - /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will - /// implicitly bind the socket. - /// /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. /// /// # Typical `start` errors /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) - /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address, but the socket has `ipv6-only` enabled. (EINVAL) + /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) /// - `invalid-state`: The socket is already bound. (EINVAL) /// /// # Typical `finish` errors @@ -42,6 +39,12 @@ interface tcp { /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) /// - `not-in-progress`: A `bind` operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # Implementors note + /// When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT + /// state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR + /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior + /// and SO_REUSEADDR performs something different entirely. /// /// # References /// - @@ -57,20 +60,13 @@ interface tcp { /// - the socket is transitioned into the Connection state /// - a pair of streams is returned that can be used to read & write to the connection /// - /// POSIX mentions: - /// > If connect() fails, the state of the socket is unspecified. Conforming applications should - /// > close the file descriptor and create a new socket before attempting to reconnect. - /// - /// WASI prescribes the following behavior: - /// - If `connect` fails because an input/state validation error, the socket should remain usable. - /// - If a connection was actually attempted but failed, the socket should become unusable for further network communication. - /// Besides `drop`, any method after such a failure may return an error. + /// After a failed connection attempt, the only valid action left is to + /// `drop` the socket. A single socket can not be used to connect more than once. /// /// # Typical `start` errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) - /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address, but the socket has `ipv6-only` enabled. (EINVAL, EADDRNOTAVAIL on Illumos) - /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) + /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. @@ -125,7 +121,6 @@ interface tcp { /// /// The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket: /// - `address-family` - /// - `ipv6-only` /// - `keep-alive-enabled` /// - `keep-alive-idle-time` /// - `keep-alive-interval` @@ -190,17 +185,6 @@ interface tcp { /// Equivalent to the SO_DOMAIN socket option. address-family: func() -> ip-address-family; - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `invalid-state`: (set) The socket is already bound. - /// - `not-supported`: (get/set) `this` socket is an IPv4 socket. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - ipv6-only: func() -> result; - set-ipv6-only: func(value: bool) -> result<_, error-code>; - /// Hints the desired listen queue size. Implementations are free to ignore this. /// /// If the provided value is 0, an `invalid-argument` error is returned. @@ -299,12 +283,16 @@ interface tcp { /// Initiate a graceful shutdown. /// - /// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read - /// operations on the `input-stream` associated with this socket will return an End Of Stream indication. - /// Any data still in the receive queue at time of calling `shutdown` will be discarded. - /// - send: the socket is not expecting to send any more data to the peer. All subsequent write - /// operations on the `output-stream` associated with this socket will return an error. - /// - both: same effect as receive & send combined. + /// - `receive`: The socket is not expecting to receive any data from + /// the peer. The `input-stream` associated with this socket will be + /// closed. Any data still in the receive queue at time of calling + /// this method will be discarded. + /// - `send`: The socket has no more data to send to the peer. The `output-stream` + /// associated with this socket will be closed and a FIN packet will be sent. + /// - `both`: Same effect as `receive` & `send` combined. + /// + /// This function is idempotent. Shutting a down a direction more than once + /// has no effect and returns `ok`. /// /// The shutdown function does not close (drop) the socket. /// diff --git a/proposals/http/wit/deps/sockets/udp-create-socket.wit b/proposals/http/wit/deps/sockets/udp-create-socket.wit index cc58234d8..0482d1fe7 100644 --- a/proposals/http/wit/deps/sockets/udp-create-socket.wit +++ b/proposals/http/wit/deps/sockets/udp-create-socket.wit @@ -6,6 +6,7 @@ interface udp-create-socket { /// Create a new UDP socket. /// /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. /// /// This function does not require a network capability handle. This is considered to be safe because /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind` is called, diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index c8dafadfc..ae82b97fc 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -92,7 +92,6 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-state`: The socket is not bound. @@ -142,17 +141,6 @@ interface udp { /// Equivalent to the SO_DOMAIN socket option. address-family: func() -> ip-address-family; - /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. - /// - /// Equivalent to the IPV6_V6ONLY socket option. - /// - /// # Typical errors - /// - `not-supported`: (get/set) `this` socket is an IPv4 socket. - /// - `invalid-state`: (set) The socket is already bound. - /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) - ipv6-only: func() -> result; - set-ipv6-only: func(value: bool) -> result<_, error-code>; - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// /// If the provided value is 0, an `invalid-argument` error is returned. @@ -248,7 +236,6 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: `remote-address` is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `stream`. (EISCONN) diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit index 49ad8d3d9..8588cc6c1 100644 --- a/proposals/http/wit/deps/sockets/world.wit +++ b/proposals/http/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.0-rc-2023-11-10; +package wasi:sockets@0.2.0-rc-2024-01-16; world imports { import instance-network; From 450ba382a76250adc6282dc091e812c07bbdfd04 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 16 Jan 2024 14:10:54 -0800 Subject: [PATCH 1378/1772] update imports of wasi:cli to 0.2.0-rc-2024-01-16 --- proposals/http/wit/proxy.wit | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 0f466c93c..df9707b35 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -11,14 +11,14 @@ world proxy { /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.2.0-rc-2023-12-05; - import wasi:cli/stderr@0.2.0-rc-2023-12-05; + import wasi:cli/stdout@0.2.0-rc-2024-01-16; + import wasi:cli/stderr@0.2.0-rc-2024-01-16; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. - import wasi:cli/stdin@0.2.0-rc-2023-12-05; + import wasi:cli/stdin@0.2.0-rc-2024-01-16; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). From cd37586364270c2be2e33bc1e3fb37cb9af0e257 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 16 Jan 2024 14:11:39 -0800 Subject: [PATCH 1379/1772] update wasi:http package version to 0.2.0-rc-2024-01-16 --- proposals/http/wit/proxy.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index df9707b35..2b0ce4b8a 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,4 +1,4 @@ -package wasi:http@0.2.0-rc-2023-12-05; +package wasi:http@0.2.0-rc-2024-01-16; /// The `wasi:http/proxy` world captures a widely-implementable intersection of /// hosts that includes HTTP forward and reverse proxies. Components targeting From fc2aa42a4c21a07ae738132402606b3d9034dd9f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 16 Jan 2024 14:11:54 -0800 Subject: [PATCH 1380/1772] generate markdown --- proposals/http/proxy.md | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 2aa0c46aa..7781e3b3b 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -10,18 +10,18 @@ outgoing HTTP requests.

                            • interface wasi:io/error@0.2.0-rc-2023-11-10
                            • interface wasi:io/poll@0.2.0-rc-2023-11-10
                            • interface wasi:io/streams@0.2.0-rc-2023-11-10
                            • -
                            • interface wasi:cli/stdout@0.2.0-rc-2023-12-05
                            • -
                            • interface wasi:cli/stderr@0.2.0-rc-2023-12-05
                            • -
                            • interface wasi:cli/stdin@0.2.0-rc-2023-12-05
                            • +
                            • interface wasi:cli/stdout@0.2.0-rc-2024-01-16
                            • +
                            • interface wasi:cli/stderr@0.2.0-rc-2024-01-16
                            • +
                            • interface wasi:cli/stdin@0.2.0-rc-2024-01-16
                            • interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10
                            • -
                            • interface wasi:http/types@0.2.0-rc-2023-12-05
                            • -
                            • interface wasi:http/outgoing-handler@0.2.0-rc-2023-12-05
                            • +
                            • interface wasi:http/types@0.2.0-rc-2024-01-16
                            • +
                            • interface wasi:http/outgoing-handler@0.2.0-rc-2024-01-16
                            • interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10
                          • Exports:
                          @@ -191,6 +191,10 @@ polled for using wasi:io/poll.

    Functions

    [method]input-stream.read: func

    Perform a non-blocking read from the stream.

    +

    When the source of a read is binary data, the bytes from the source +are returned verbatim. When the source of a read is known to the +implementation to be text, bytes containing the UTF-8 encoding of the +text are returned.

    This function returns a list of bytes containing the read data, when successful. The returned list will contain up to len bytes; it may return fewer than requested, but not more. The list is @@ -286,6 +290,11 @@ error.

    [method]output-stream.write: func

    Perform a write. This function never blocks.

    +

    When the destination of a write is binary data, the bytes from +contents are written verbatim. When the destination of a write is +known to the implementation to be text, the bytes of contents are +transcoded from UTF-8 into the encoding of the destination and then +written.

    Precondition: check-write gave permit of Ok(n) and contents has a length of less than or equal to n. Otherwise, this function will trap.

    returns Err(closed) without writing if the stream has closed since @@ -459,7 +468,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stdout@0.2.0-rc-2023-12-05

    +

    Import interface wasi:cli/stdout@0.2.0-rc-2024-01-16


    Types

    type output-stream

    @@ -472,7 +481,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stderr@0.2.0-rc-2023-12-05

    +

    Import interface wasi:cli/stderr@0.2.0-rc-2024-01-16


    Types

    type output-stream

    @@ -485,7 +494,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stdin@0.2.0-rc-2023-12-05

    +

    Import interface wasi:cli/stdin@0.2.0-rc-2024-01-16


    Types

    type input-stream

    @@ -559,7 +568,7 @@ occured.

    -

    Import interface wasi:http/types@0.2.0-rc-2023-12-05

    +

    Import interface wasi:http/types@0.2.0-rc-2024-01-16

    This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

    @@ -1445,7 +1454,7 @@ but those will be reported by the incoming-body
  • option<result<result<own<incoming-response>, error-code>>>
  • -

    Import interface wasi:http/outgoing-handler@0.2.0-rc-2023-12-05

    +

    Import interface wasi:http/outgoing-handler@0.2.0-rc-2024-01-16

    This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


    @@ -1523,7 +1532,7 @@ also known as Unix Time.
  • datetime
  • -

    Export interface wasi:http/incoming-handler@0.2.0-rc-2023-12-05

    +

    Export interface wasi:http/incoming-handler@0.2.0-rc-2024-01-16


    Types

    type incoming-request

    From c21f7ce66891479482cf6ad7597add224262e414 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 16 Jan 2024 14:13:40 -0800 Subject: [PATCH 1381/1772] further clarifications --- proposals/sockets/README.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index bad6b6920..20481c754 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -218,19 +218,25 @@ stateDiagram-v2 TCP_BOUND --> TCP_LISTEN: startListen() [WAIT] TCP_LISTEN --> TCP_LISTEN_READY: permission granted [RESOLVED] TCP_LISTEN --> TCP_BOUND: permission denied [RESOLVED] - TCP_LISTEN_READY --> TCP_LISTENER: finishListen() [RESOLVED] + TCP_LISTEN_READY --> TCP_LISTENER: finishListen() [WAIT] TCP_LISTEN_READY --> TCP_ERROR: finishListen() error [RESOLVED] - TCP_CONNECTION --> TCP_CLOSED: shutdown() [RESOLVED] - TCP_LISTENER --> TCP_CLOSED: shutdown() [RESOLVED] - - + TCP_CONNECTION --> TCP_CONNECTION: shutdown() [RESOLVED] + TCP_CONNECTION --> TCP_ERROR: socket error [RESOLVED] + TCP_CONNECTION --> TCP_CLOSED: socket close [RESOLVED] + TCP_LISTENER --> TCP_ERROR: socket error [RESOLVED] + TCP_LISTENER --> TCP_CLOSED: socket close [RESOLVED] ``` where the given methods synchronously transition the state when they are called. All method calls not on these state transition paths throw `invalid-state` while remaining in the current state, therefore always being recoverable by not transitioning the socket into the error state. The state of the pollable for the TCP state machine is provided as `[RESOLVED]` or `[WAIT]` in the above, where a transition from `[WAIT] -> [RESOLVED]` in the above state diagram corresponds to an event that can be polled on for the subscription. Permission denied errors are retriable if the permissions dynamically change, and do not transition into the socket error state. -Once the TCP state machine is in the `TCP_CONNECTION` or `TCP_LISTENER` state, the pollable state is instantaneously updated to the state of the underlying socket IO - `[RESOLVED]` if there is pending IO, and `[UNRESOLVED]` otherwise. This means it is possible for the `finishConnect()` call to instantaneously transition the pollable to resolved and then back to unresolved if there is no data ready on the underlying socket. +In the `TCP_CONECTION` state, data IO on the socket streams do not affect the pollable state on the socket resource. + +In the `TCP_LISTENER` state, the pollable state is set to the state of the underlying socket IO - `[RESOLVED]` if there is a pending backlog, and `[WAIT]` otherwise. This means it is possible for the `finishListen()` call to instantaneously transition the pollable to resolved. + +The `TCP_CONNECT_READY` and `TCP_LISTEN_READY` states should eagerly handle socket connection and socket listen calls respectively, so that +the finish calls represent completion of the asynchronous operation. Implementations may perform blocking connect and listen in the `connectFinish` and `listenFinish` calls, but this is discouraged. The TCP socket can be dropped in all states, performing the necessary cleanup. There are no traps associated with any state transitions. From e788cf143f8f8696b892f64b73845dfb9a019731 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 16 Jan 2024 16:39:32 -0800 Subject: [PATCH 1382/1772] lr direction --- proposals/sockets/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 20481c754..8e2976163 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -201,6 +201,7 @@ The TCP valid states can be described by the following diagram: ```mermaid stateDiagram-v2 + direction LR [*] --> TCP_INIT: tcpSocketCreate() [RESOLVED] [*] --> TCP_CONNECTION: accept() [RESOLVED] TCP_INIT --> TCP_BIND: startBind() [WAIT] From c491548e7ca3cdbdf540601175e8a4f5e272cc73 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 16 Jan 2024 16:45:44 -0800 Subject: [PATCH 1383/1772] less text in diagram --- proposals/sockets/README.md | 55 ++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 8e2976163..ae0054cbc 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -202,35 +202,40 @@ The TCP valid states can be described by the following diagram: ```mermaid stateDiagram-v2 direction LR - [*] --> TCP_INIT: tcpSocketCreate() [RESOLVED] - [*] --> TCP_CONNECTION: accept() [RESOLVED] - TCP_INIT --> TCP_BIND: startBind() [WAIT] - TCP_BIND --> TCP_BIND_READY: permission granted [RESOLVED] - TCP_BIND --> TCP_INIT: permission denied [RESOLVED] - TCP_BIND_READY --> TCP_BOUND: finishBind() [RESOLVED] - TCP_BIND_READY --> TCP_ERROR: finishBind() error [RESOLVED] - TCP_INIT --> TCP_CONNECT: startConnect() [WAIT] - TCP_BOUND --> TCP_CONNECT: startConnect() [WAIT] - TCP_CONNECT --> TCP_CONNECT_READY: permission granted [RESOLVED] - TCP_CONNECT --> TCP_INIT: permission denied [RESOLVED] - TCP_CONNECT --> TCP_BOUND: permission denied [RESOLVED] - TCP_CONNECT_READY --> TCP_CONNECTION: finishConnect() [RESOLVED] - TCP_CONNECT_READY --> TCP_ERROR: finishConnect() error [RESOLVED] - TCP_BOUND --> TCP_LISTEN: startListen() [WAIT] - TCP_LISTEN --> TCP_LISTEN_READY: permission granted [RESOLVED] - TCP_LISTEN --> TCP_BOUND: permission denied [RESOLVED] - TCP_LISTEN_READY --> TCP_LISTENER: finishListen() [WAIT] - TCP_LISTEN_READY --> TCP_ERROR: finishListen() error [RESOLVED] - TCP_CONNECTION --> TCP_CONNECTION: shutdown() [RESOLVED] - TCP_CONNECTION --> TCP_ERROR: socket error [RESOLVED] - TCP_CONNECTION --> TCP_CLOSED: socket close [RESOLVED] - TCP_LISTENER --> TCP_ERROR: socket error [RESOLVED] - TCP_LISTENER --> TCP_CLOSED: socket close [RESOLVED] + [*] --> TCP_INIT: tcpSocketCreate() + [*] --> TCP_CONNECTION: accept() + TCP_INIT --> TCP_BIND: startBind() + TCP_BIND --> TCP_BIND_READY: granted + TCP_BIND --> TCP_INIT: denied + TCP_BIND_READY --> TCP_BOUND: finishBind() + TCP_BIND_READY --> TCP_ERROR: finishBind() error + TCP_INIT --> TCP_CONNECT: startConnect() + TCP_BOUND --> TCP_CONNECT: startConnect() + TCP_CONNECT --> TCP_CONNECT_READY: granted + TCP_CONNECT --> TCP_INIT: denied + TCP_CONNECT --> TCP_BOUND: denied + TCP_CONNECT_READY --> TCP_CONNECTION: finishConnect() + TCP_CONNECT_READY --> TCP_ERROR: finishConnect() error + TCP_BOUND --> TCP_LISTEN: startListen() + TCP_LISTEN --> TCP_LISTEN_READY: granted + TCP_LISTEN --> TCP_BOUND: denied + TCP_LISTEN_READY --> TCP_LISTENER: finishListen() + TCP_LISTEN_READY --> TCP_ERROR: finishListen() error + TCP_CONNECTION --> TCP_CONNECTION: shutdown() + TCP_CONNECTION --> TCP_ERROR: socket error + TCP_CONNECTION --> TCP_CLOSED: socket close + TCP_LISTENER --> TCP_ERROR: socket error + TCP_LISTENER --> TCP_CLOSED: socket close + + TCP_BIND: TCP_BIND [WAIT] + TCP_CONNECT: TCP_CONNECT [WAIT] + TCP_LISTEN: TCP_LISTEN [WAIT] + TCP_LISTENER: TCP_LISTENER [WAIT] ``` where the given methods synchronously transition the state when they are called. All method calls not on these state transition paths throw `invalid-state` while remaining in the current state, therefore always being recoverable by not transitioning the socket into the error state. -The state of the pollable for the TCP state machine is provided as `[RESOLVED]` or `[WAIT]` in the above, where a transition from `[WAIT] -> [RESOLVED]` in the above state diagram corresponds to an event that can be polled on for the subscription. Permission denied errors are retriable if the permissions dynamically change, and do not transition into the socket error state. +The state of the pollable for the TCP state machine is `RESOLVED` in every state, except for when transitioning into those states with `[WAIT]` on them - `TCP_BIND`, `TCP_CONNECT`, `TCP_LISTEN` and `TCP_LISTENER`. These correspond to events that can be polled on for the subscription. Permission denied errors are retriable if the permissions dynamically change, and do not transition into the socket error state. In the `TCP_CONECTION` state, data IO on the socket streams do not affect the pollable state on the socket resource. From 686f47f8459b730021875e682a06e0fa323c5784 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 16 Jan 2024 16:48:04 -0800 Subject: [PATCH 1384/1772] further rewording --- proposals/sockets/README.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index ae0054cbc..7f85f4076 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -233,16 +233,11 @@ stateDiagram-v2 TCP_LISTENER: TCP_LISTENER [WAIT] ``` -where the given methods synchronously transition the state when they are called. All method calls not on these state transition paths throw `invalid-state` while remaining in the current state, therefore always being recoverable by not transitioning the socket into the error state. +where the given methods synchronously transition the state when they are called. All method calls not on these state transition paths throw `invalid-state` while remaining in the current state, therefore always being recoverable by not transitioning the socket into the error state. Permission denied errors are retriable if the permissions dynamically change, and do not transition into the socket error state. -The state of the pollable for the TCP state machine is `RESOLVED` in every state, except for when transitioning into those states with `[WAIT]` on them - `TCP_BIND`, `TCP_CONNECT`, `TCP_LISTEN` and `TCP_LISTENER`. These correspond to events that can be polled on for the subscription. Permission denied errors are retriable if the permissions dynamically change, and do not transition into the socket error state. +The `TCP_CONNECT_READY` and `TCP_LISTEN_READY` states should eagerly handle socket connection and socket listen calls respectively, so that the finish calls represent completion of the asynchronous operation. Implementations may perform blocking connect and listen in the `connectFinish` and `listenFinish` calls, but this is discouraged. -In the `TCP_CONECTION` state, data IO on the socket streams do not affect the pollable state on the socket resource. - -In the `TCP_LISTENER` state, the pollable state is set to the state of the underlying socket IO - `[RESOLVED]` if there is a pending backlog, and `[WAIT]` otherwise. This means it is possible for the `finishListen()` call to instantaneously transition the pollable to resolved. - -The `TCP_CONNECT_READY` and `TCP_LISTEN_READY` states should eagerly handle socket connection and socket listen calls respectively, so that -the finish calls represent completion of the asynchronous operation. Implementations may perform blocking connect and listen in the `connectFinish` and `listenFinish` calls, but this is discouraged. +The state of the pollable for the TCP state machine is `RESOLVED` in every state, except for when transitioning into those states with `[WAIT]` on them - `TCP_BIND`, `TCP_CONNECT`, `TCP_LISTEN` and `TCP_LISTENER`. These correspond to states that can be polled on for their transition into another state that is resolved. The `TCP_LISTENER` state is the only one where the state of the pollable is the state of the underlying socket. It will be `RESOLVED` if there is a pending backlog, and `WAIT` otherwise. This means it is possible for the `finishListen()` call to instantaneously transition the pollable to resolved.the subscription. In the `TCP_CONECTION` state, data IO on the socket streams do not affect the pollable state on the socket resource. The TCP socket can be dropped in all states, performing the necessary cleanup. There are no traps associated with any state transitions. From 63e051629ee3a541ee304d321216a772e2ba3c53 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 16 Jan 2024 16:49:44 -0800 Subject: [PATCH 1385/1772] back to top to bottom --- proposals/sockets/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 7f85f4076..ffcce3069 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -201,7 +201,6 @@ The TCP valid states can be described by the following diagram: ```mermaid stateDiagram-v2 - direction LR [*] --> TCP_INIT: tcpSocketCreate() [*] --> TCP_CONNECTION: accept() TCP_INIT --> TCP_BIND: startBind() From 7e4043fa0eb29317b53b61f2a9ab258dc36dc9e6 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 16 Jan 2024 17:31:11 -0800 Subject: [PATCH 1386/1772] further clarifications --- proposals/sockets/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index ffcce3069..afadc09b2 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -236,7 +236,7 @@ where the given methods synchronously transition the state when they are called. The `TCP_CONNECT_READY` and `TCP_LISTEN_READY` states should eagerly handle socket connection and socket listen calls respectively, so that the finish calls represent completion of the asynchronous operation. Implementations may perform blocking connect and listen in the `connectFinish` and `listenFinish` calls, but this is discouraged. -The state of the pollable for the TCP state machine is `RESOLVED` in every state, except for when transitioning into those states with `[WAIT]` on them - `TCP_BIND`, `TCP_CONNECT`, `TCP_LISTEN` and `TCP_LISTENER`. These correspond to states that can be polled on for their transition into another state that is resolved. The `TCP_LISTENER` state is the only one where the state of the pollable is the state of the underlying socket. It will be `RESOLVED` if there is a pending backlog, and `WAIT` otherwise. This means it is possible for the `finishListen()` call to instantaneously transition the pollable to resolved.the subscription. In the `TCP_CONECTION` state, data IO on the socket streams do not affect the pollable state on the socket resource. +The state of the pollable for the TCP state machine is `RESOLVED` in every state, except for when transitioning into those states with `[WAIT]` on them - `TCP_BIND`, `TCP_CONNECT`, `TCP_LISTEN` and `TCP_LISTENER`. These correspond to states that can be polled on for their transition into another state that is resolved. The `TCP_LISTENER` state is the only one where the state of the pollable is the state of the underlying socket. It will be `RESOLVED` if there is a pending backlog, and `WAIT` otherwise. This means it is possible for the `finishListen()` call to instantaneously transition the pollable back to resolved from the initial wait state of resolving into `TCP_LISTENER`. In the `TCP_CONECTION` state, data IO on the socket streams does not affect the pollable state on the socket resource, unless there is a socket error or the socket is closed. The TCP socket can be dropped in all states, performing the necessary cleanup. There are no traps associated with any state transitions. From ea340e9328bbdc02328d7f3fa74c226239a34980 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 16 Jan 2024 17:31:56 -0800 Subject: [PATCH 1387/1772] correction --- proposals/sockets/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index afadc09b2..254069d7b 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -236,7 +236,7 @@ where the given methods synchronously transition the state when they are called. The `TCP_CONNECT_READY` and `TCP_LISTEN_READY` states should eagerly handle socket connection and socket listen calls respectively, so that the finish calls represent completion of the asynchronous operation. Implementations may perform blocking connect and listen in the `connectFinish` and `listenFinish` calls, but this is discouraged. -The state of the pollable for the TCP state machine is `RESOLVED` in every state, except for when transitioning into those states with `[WAIT]` on them - `TCP_BIND`, `TCP_CONNECT`, `TCP_LISTEN` and `TCP_LISTENER`. These correspond to states that can be polled on for their transition into another state that is resolved. The `TCP_LISTENER` state is the only one where the state of the pollable is the state of the underlying socket. It will be `RESOLVED` if there is a pending backlog, and `WAIT` otherwise. This means it is possible for the `finishListen()` call to instantaneously transition the pollable back to resolved from the initial wait state of resolving into `TCP_LISTENER`. In the `TCP_CONECTION` state, data IO on the socket streams does not affect the pollable state on the socket resource, unless there is a socket error or the socket is closed. +The state of the pollable for the TCP state machine is `RESOLVED` in every state, except for when transitioning into those states with `[WAIT]` on them - `TCP_BIND`, `TCP_CONNECT`, `TCP_LISTEN` and `TCP_LISTENER`. These correspond to states that can be polled on for their transition into another state that is resolved. The `TCP_LISTENER` state is the only one where the state of the pollable is the state of the underlying socket. It will be `RESOLVED` if there is a pending backlog, and `WAIT` otherwise. This means it is possible for the `finishListen()` call to instantaneously transition the pollable back to resolved from the initial wait state of resolving into `TCP_LISTENER`. In the `TCP_CONECTION` state, data IO on the socket streams does not affect the pollable state on the socket resource. Because the pollable is resolved in this state, the socket close and error events are not pollable. The TCP socket can be dropped in all states, performing the necessary cleanup. There are no traps associated with any state transitions. From 5a183ece6ecb9fa449722964057a1b953bd55e75 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 16 Jan 2024 17:32:35 -0800 Subject: [PATCH 1388/1772] join sentence --- proposals/sockets/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 254069d7b..4623fbcdf 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -236,7 +236,7 @@ where the given methods synchronously transition the state when they are called. The `TCP_CONNECT_READY` and `TCP_LISTEN_READY` states should eagerly handle socket connection and socket listen calls respectively, so that the finish calls represent completion of the asynchronous operation. Implementations may perform blocking connect and listen in the `connectFinish` and `listenFinish` calls, but this is discouraged. -The state of the pollable for the TCP state machine is `RESOLVED` in every state, except for when transitioning into those states with `[WAIT]` on them - `TCP_BIND`, `TCP_CONNECT`, `TCP_LISTEN` and `TCP_LISTENER`. These correspond to states that can be polled on for their transition into another state that is resolved. The `TCP_LISTENER` state is the only one where the state of the pollable is the state of the underlying socket. It will be `RESOLVED` if there is a pending backlog, and `WAIT` otherwise. This means it is possible for the `finishListen()` call to instantaneously transition the pollable back to resolved from the initial wait state of resolving into `TCP_LISTENER`. In the `TCP_CONECTION` state, data IO on the socket streams does not affect the pollable state on the socket resource. Because the pollable is resolved in this state, the socket close and error events are not pollable. +The state of the pollable for the TCP state machine is `RESOLVED` in every state, except for when transitioning into those states with `[WAIT]` on them - `TCP_BIND`, `TCP_CONNECT`, `TCP_LISTEN` and `TCP_LISTENER`. These correspond to states that can be polled on for their transition into another state that is resolved. The `TCP_LISTENER` state is the only one where the state of the pollable is the state of the underlying socket. It will be `RESOLVED` if there is a pending backlog, and `WAIT` otherwise. This means it is possible for the `finishListen()` call to instantaneously transition the pollable back to resolved from the initial wait state of resolving into `TCP_LISTENER`. In the `TCP_CONECTION` state, data IO on the socket streams does not affect the pollable state on the socket resource, and because the pollable is resolved in this state, the socket close and error events are not pollable. The TCP socket can be dropped in all states, performing the necessary cleanup. There are no traps associated with any state transitions. From 1fdf5304a34e3526b8193459680a0d57dfbea4e5 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 17 Jan 2024 16:55:44 +0100 Subject: [PATCH 1389/1772] Move state machine to separate file and expand documentation --- proposals/sockets/README.md | 43 +------ .../sockets/TcpSocketOperationalSemantics.md | 111 ++++++++++++++++++ proposals/sockets/imports.md | 68 +++++++---- proposals/sockets/wit/tcp.wit | 75 ++++++++---- 4 files changed, 211 insertions(+), 86 deletions(-) create mode 100644 proposals/sockets/TcpSocketOperationalSemantics.md diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 4623fbcdf..5b800b5b4 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -197,48 +197,7 @@ Now, again, this proposal does not specify if/how permission prompts should be i ### TCP State Machine -The TCP valid states can be described by the following diagram: - -```mermaid -stateDiagram-v2 - [*] --> TCP_INIT: tcpSocketCreate() - [*] --> TCP_CONNECTION: accept() - TCP_INIT --> TCP_BIND: startBind() - TCP_BIND --> TCP_BIND_READY: granted - TCP_BIND --> TCP_INIT: denied - TCP_BIND_READY --> TCP_BOUND: finishBind() - TCP_BIND_READY --> TCP_ERROR: finishBind() error - TCP_INIT --> TCP_CONNECT: startConnect() - TCP_BOUND --> TCP_CONNECT: startConnect() - TCP_CONNECT --> TCP_CONNECT_READY: granted - TCP_CONNECT --> TCP_INIT: denied - TCP_CONNECT --> TCP_BOUND: denied - TCP_CONNECT_READY --> TCP_CONNECTION: finishConnect() - TCP_CONNECT_READY --> TCP_ERROR: finishConnect() error - TCP_BOUND --> TCP_LISTEN: startListen() - TCP_LISTEN --> TCP_LISTEN_READY: granted - TCP_LISTEN --> TCP_BOUND: denied - TCP_LISTEN_READY --> TCP_LISTENER: finishListen() - TCP_LISTEN_READY --> TCP_ERROR: finishListen() error - TCP_CONNECTION --> TCP_CONNECTION: shutdown() - TCP_CONNECTION --> TCP_ERROR: socket error - TCP_CONNECTION --> TCP_CLOSED: socket close - TCP_LISTENER --> TCP_ERROR: socket error - TCP_LISTENER --> TCP_CLOSED: socket close - - TCP_BIND: TCP_BIND [WAIT] - TCP_CONNECT: TCP_CONNECT [WAIT] - TCP_LISTEN: TCP_LISTEN [WAIT] - TCP_LISTENER: TCP_LISTENER [WAIT] -``` - -where the given methods synchronously transition the state when they are called. All method calls not on these state transition paths throw `invalid-state` while remaining in the current state, therefore always being recoverable by not transitioning the socket into the error state. Permission denied errors are retriable if the permissions dynamically change, and do not transition into the socket error state. - -The `TCP_CONNECT_READY` and `TCP_LISTEN_READY` states should eagerly handle socket connection and socket listen calls respectively, so that the finish calls represent completion of the asynchronous operation. Implementations may perform blocking connect and listen in the `connectFinish` and `listenFinish` calls, but this is discouraged. - -The state of the pollable for the TCP state machine is `RESOLVED` in every state, except for when transitioning into those states with `[WAIT]` on them - `TCP_BIND`, `TCP_CONNECT`, `TCP_LISTEN` and `TCP_LISTENER`. These correspond to states that can be polled on for their transition into another state that is resolved. The `TCP_LISTENER` state is the only one where the state of the pollable is the state of the underlying socket. It will be `RESOLVED` if there is a pending backlog, and `WAIT` otherwise. This means it is possible for the `finishListen()` call to instantaneously transition the pollable back to resolved from the initial wait state of resolving into `TCP_LISTENER`. In the `TCP_CONECTION` state, data IO on the socket streams does not affect the pollable state on the socket resource, and because the pollable is resolved in this state, the socket close and error events are not pollable. - -The TCP socket can be dropped in all states, performing the necessary cleanup. There are no traps associated with any state transitions. +See [Operational Semantics](./TcpSocketOperationalSemantics.md). ### Considered alternatives diff --git a/proposals/sockets/TcpSocketOperationalSemantics.md b/proposals/sockets/TcpSocketOperationalSemantics.md new file mode 100644 index 000000000..7be51cf7b --- /dev/null +++ b/proposals/sockets/TcpSocketOperationalSemantics.md @@ -0,0 +1,111 @@ +# Operational semantics of WASI TCP sockets + +WASI TCP sockets must behave [as-if](https://en.wikipedia.org/wiki/As-if_rule) they are implemented using the state machine described in this document. + +## States +> Note: These refer to the states of the TCP socket, not the [TCP connection](https://datatracker.ietf.org/doc/html/rfc9293#name-state-machine-overview) + +In pseudo code: + +```wit +interface tcp { + variant state { + unbound, + bind-in-progress(bind-future), + bound, + listen-in-progress(listen-future), + listening(accept-stream), + connect-in-progress(connect-future), + connected, + closed, + } + + type bind-future = future>; + type listen-future = future>; + type connect-future = future, error-code>>; + type accept-stream = stream, error-code>>; +} +``` + +## Pollable readiness +As seen above, there can be at most one asynchronous operation in progress at any time. The socket's pollable ready state can therefore be unambiguously derived as follows: + +```rs +fn ready() -> bool { + match state { + unbound => true, + bound => true, + connected => true, // To poll for I/O readiness, subscribe to the input and output streams. + closed => true, + + // Assuming that `f.is-resolved` returns true when the + // future has completed, either successfully or with failure. + bind-in-progress(f) => f.is-resolved, + listen-in-progress(f) => f.is-resolved, + connect-in-progress(f) => f.is-resolved, + + // Assuming that `s.has-pending-items` returns true when + // there is an item ready to be read from the stream. + listening(s) => s.has-pending-items, + } +} +``` + +## Transitions +The following diagram describes the exhaustive set of all possible state transitions: + +```mermaid +stateDiagram-v2 + state "unbound" as Unbound + state "bind-in-progress" as BindInProgress + state "bound" as Bound + state "listen-in-progress" as ListenInProgress + state "listening" as Listening + state "connect-in-progress" as ConnectInProgress + state "connected" as Connected + state "closed" as Closed + + [*] --> Unbound: create-tcp-socket()\n#ok + + Unbound --> BindInProgress: start-bind()\n#ok + Unbound --> Unbound: start-bind()\n#error + Unbound --> ConnectInProgress: start-connect()\n#ok + Unbound --> Closed: start-connect()\n#error + + ConnectInProgress --> ConnectInProgress: finish-connect()\n#error(would-block) + ConnectInProgress --> Closed: finish-connect()\n#error(NOT would-block) + ConnectInProgress --> Connected: finish-connect()\n#ok + + Connected --> Connected: shutdown() + Connected --> Closed: «connection terminated» + + BindInProgress --> BindInProgress: finish-bind()\n#error(would-block) + BindInProgress --> Unbound: finish-bind()\n#error(NOT would-block) + BindInProgress --> Bound: finish-bind()\n#ok + + Bound --> ListenInProgress: start-listen()\n#ok + Bound --> Closed: start-listen()\n#error + Bound --> ConnectInProgress: start-connect()\n#ok + Bound --> Closed: start-connect()\n#error + + ListenInProgress --> ListenInProgress: finish-listen()\n#error(would-block) + ListenInProgress --> Closed: finish-listen()\n#error(NOT would-block) + ListenInProgress --> Listening: finish-listen()\n#ok + + Listening --> Listening: accept() +``` + +Most transitions are dependent on the result of the method. Legend: +- `#ok`: this transition only applies when the method returns successfully. +- `#error`: this transition only applies when the method returns a failure. +- `#error(would-block)`: this transition only applies when the method returns the `would-block` error specifically. +- `#error(NOT would-block)`: this transition only applies when the method returns an error other than `would-block`. +- _(no annotation)_: Transition in unconditional. + +#### Not shown in the diagram: +- All state transitions shown above are driven by the caller and occur synchronously during the method invocations. There's one exception: the `«connection terminated»` transition from `connected` to `closed`. This can happen when: the peer closed the connection, a network failure occurred, the connection timed out, etc. +- While `shutdown` immediately closes the input and/or output streams associated with the socket, it does not affect the socket's own state as it just _initiates_ a shutdown. Only after the full shutdown sequence has been completed will the `«connection terminated»` transition be activated. (See previous item) +- Calling a method from the wrong state returns `error(invalid-state)` and does not affect the state of the socket. A special case are the `finish-*` methods; those return `error(not-in-progress)` when the socket is not in the corresponding `*-in-progress` state. +- This diagram only includes the methods that impact the socket's state. For an overview of all methods and their required states, see [tcp.wit](./wit/tcp.wit) +- Client sockets returned by `accept()` are in immediately in the `connected` state. +- A socket resource can be dropped in any state. diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index d764c0080..459f2bf9f 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -1188,7 +1188,26 @@ occured.

    resource tcp-socket

    -

    A TCP socket handle.

    +

    A TCP socket resource.

    +

    The socket can be in one of the following states:

    + +

    Note: Except where explicitly mentioned, whenever this documentation uses +the term "bound" without backticks it actually means: in the bound state or higher. +(i.e. bound, listen-in-progress, listening, connect-in-progress or connected)

    +

    In addition to the general error codes documented on the +network::error-code type, TCP socket methods may always return +error(invalid-state) when in the closed state.

    Functions

    [method]tcp-socket.start-bind: func

    Bind the socket to a specific network on the provided IP address and port.

    @@ -1246,11 +1265,12 @@ and SO_REUSEADDR performs something different entirely.

    Connect to a remote endpoint.

    On success:

      -
    • the socket is transitioned into the Connection state
    • +
    • the socket is transitioned into the connection state.
    • a pair of streams is returned that can be used to read & write to the connection
    -

    After a failed connection attempt, the only valid action left is to -drop the socket. A single socket can not be used to connect more than once.

    +

    After a failed connection attempt, the socket will be in the closed +state and the only valid action left is to drop the socket. A single +socket can not be used to connect more than once.

    Typical start errors

    • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • @@ -1259,8 +1279,8 @@ and SO_REUSEADDR performs something different entirely.

    • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
    • invalid-argument: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
    • invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
    • -
    • invalid-state: The socket is already in the Connection state. (EISCONN)
    • -
    • invalid-state: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
    • +
    • invalid-state: The socket is already in the connected state. (EISCONN)
    • +
    • invalid-state: The socket is already in the listening state. (EOPNOTSUPP, EINVAL on Windows)

    Typical finish errors

      @@ -1270,7 +1290,7 @@ and SO_REUSEADDR performs something different entirely.

    • connection-aborted: The connection was aborted. (ECONNABORTED)
    • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
    • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
    • -
    • not-in-progress: A connect operation is not in progress.
    • +
    • not-in-progress: A connect operation is not in progress.
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)

    References

    @@ -1301,7 +1321,7 @@ and SO_REUSEADDR performs something different entirely.

    [method]tcp-socket.start-listen: func

    Start listening for new connections.

    -

    Transitions the socket into the Listener state.

    +

    Transitions the socket into the listening state.

    Unlike POSIX:

    • this function is async. This enables interactive WASI hosts to inject permission prompts.
    • @@ -1310,13 +1330,13 @@ and SO_REUSEADDR performs something different entirely.

      Typical start errors

      • invalid-state: The socket is not bound to any local address. (EDESTADDRREQ)
      • -
      • invalid-state: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
      • -
      • invalid-state: The socket is already in the Listener state.
      • +
      • invalid-state: The socket is already in the connected state. (EISCONN, EINVAL on BSD)
      • +
      • invalid-state: The socket is already in the listening state.

      Typical finish errors

      • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
      • -
      • not-in-progress: A listen operation is not in progress.
      • +
      • not-in-progress: A listen operation is not in progress.
      • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)

      References

      @@ -1345,7 +1365,7 @@ and SO_REUSEADDR performs something different entirely.

    [method]tcp-socket.accept: func

    Accept a new client socket.

    -

    The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket:

    +

    The returned socket is bound and in the connected state. The following properties are inherited from the listener socket:

    • address-family
    • keep-alive-enabled
    • @@ -1360,7 +1380,7 @@ and SO_REUSEADDR performs something different entirely.

      a pair of streams that can be used to read & write to the connection.

      Typical errors

        -
      • invalid-state: Socket is not in the Listener state. (EINVAL)
      • +
      • invalid-state: Socket is not in the listening state. (EINVAL)
      • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
      • connection-aborted: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED)
      • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
      • @@ -1429,7 +1449,7 @@ stored in the object pointed to by address is unspecified.

      • result<ip-socket-address, error-code>

      [method]tcp-socket.is-listening: func

      -

      Whether the socket is listening for new connections.

      +

      Whether the socket is in the listening state.

      Equivalent to the SO_ACCEPTCONN socket option.

      Params
        @@ -1458,7 +1478,7 @@ Any other value will never cause an error, but it might be silently clamped and/
        • not-supported: (set) The platform does not support changing the backlog size after the initial listen.
        • invalid-argument: (set) The provided value was 0.
        • -
        • invalid-state: (set) The socket is already in the Connection state.
        • +
        • invalid-state: (set) The socket is in the connect-in-progress or connected state.
        Params
          @@ -1587,8 +1607,6 @@ I.e. after setting a value, reading the same setting back may return a different

          Typical errors

          • invalid-argument: (set) The TTL value must be 1 or higher.
          • -
          • invalid-state: (set) The socket is already in the Connection state.
          • -
          • invalid-state: (set) The socket is already in the Listener state.
          Params
            @@ -1617,8 +1635,6 @@ I.e. after setting a value, reading the same setting back may return a different

            Typical errors

            • invalid-argument: (set) The provided value was 0.
            • -
            • invalid-state: (set) The socket is already in the Connection state.
            • -
            • invalid-state: (set) The socket is already in the Listener state.
            Params
              @@ -1658,7 +1674,17 @@ I.e. after setting a value, reading the same setting back may return a different
            • result<_, error-code>

            [method]tcp-socket.subscribe: func

            -

            Create a pollable which will resolve once the socket is ready for I/O.

            +

            Create a pollable which can be used to poll for, or block on, +completion of any of the asynchronous operations of this socket.

            +

            When finish-bind, finish-listen, finish-connect or accept +return error(would-block), this pollable can be used to wait for +their success or failure, after which the method can be retried.

            +

            The pollable is not limited to the async operation that happens to be +in progress at the time of calling subscribe (if any). Theoretically, +subscribe only has to be called once per socket and can then be +(re)used for the remainder of the socket's lifetime.

            +

            See https://github.com/WebAssembly/wasi-sockets/TcpSocketOperationalSemantics.md#Pollable-readiness +for a more information.

            Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

            Params
            @@ -1685,7 +1711,7 @@ has no effect and returns ok.

            The shutdown function does not close (drop) the socket.

            Typical errors

              -
            • invalid-state: The socket is not in the Connection state. (ENOTCONN)
            • +
            • invalid-state: The socket is not in the connected state. (ENOTCONN)

            References

              diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index e045a436a..e54f06f32 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -15,9 +15,28 @@ interface tcp { /// Similar to `SHUT_RDWR` in POSIX. both, } - - - /// A TCP socket handle. + + /// A TCP socket resource. + /// + /// The socket can be in one of the following states: + /// - `unbound` + /// - `bind-in-progress` + /// - `bound` (See note below) + /// - `listen-in-progress` + /// - `listening` + /// - `connect-in-progress` + /// - `connected` + /// - `closed` + /// See + /// for a more information. + /// + /// Note: Except where explicitly mentioned, whenever this documentation uses + /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. + /// (i.e. `bound`, `listen-in-progress`, `listening`, `connect-in-progress` or `connected`) + /// + /// In addition to the general error codes documented on the + /// `network::error-code` type, TCP socket methods may always return + /// `error(invalid-state)` when in the `closed` state. resource tcp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -57,11 +76,12 @@ interface tcp { /// Connect to a remote endpoint. /// /// On success: - /// - the socket is transitioned into the Connection state + /// - the socket is transitioned into the `connection` state. /// - a pair of streams is returned that can be used to read & write to the connection /// - /// After a failed connection attempt, the only valid action left is to - /// `drop` the socket. A single socket can not be used to connect more than once. + /// After a failed connection attempt, the socket will be in the `closed` + /// state and the only valid action left is to `drop` the socket. A single + /// socket can not be used to connect more than once. /// /// # Typical `start` errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) @@ -70,8 +90,8 @@ interface tcp { /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `invalid-state`: The socket is already in the Connection state. (EISCONN) - /// - `invalid-state`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) + /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) /// /// # Typical `finish` errors /// - `timeout`: Connection timed out. (ETIMEDOUT) @@ -80,7 +100,7 @@ interface tcp { /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `not-in-progress`: A connect operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) /// /// # References @@ -93,7 +113,7 @@ interface tcp { /// Start listening for new connections. /// - /// Transitions the socket into the Listener state. + /// Transitions the socket into the `listening` state. /// /// Unlike POSIX: /// - this function is async. This enables interactive WASI hosts to inject permission prompts. @@ -101,12 +121,12 @@ interface tcp { /// /// # Typical `start` errors /// - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ) - /// - `invalid-state`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) - /// - `invalid-state`: The socket is already in the Listener state. + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) + /// - `invalid-state`: The socket is already in the `listening` state. /// /// # Typical `finish` errors /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - `not-in-progress`: A `listen` operation is not in progress. + /// - `not-in-progress`: A listen operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) /// /// # References @@ -119,7 +139,7 @@ interface tcp { /// Accept a new client socket. /// - /// The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket: + /// The returned socket is bound and in the `connected` state. The following properties are inherited from the listener socket: /// - `address-family` /// - `keep-alive-enabled` /// - `keep-alive-idle-time` @@ -133,7 +153,7 @@ interface tcp { /// a pair of streams that can be used to read & write to the connection. /// /// # Typical errors - /// - `invalid-state`: Socket is not in the Listener state. (EINVAL) + /// - `invalid-state`: Socket is not in the `listening` state. (EINVAL) /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) /// - `connection-aborted`: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED) /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) @@ -175,7 +195,7 @@ interface tcp { /// - remote-address: func() -> result; - /// Whether the socket is listening for new connections. + /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. is-listening: func() -> bool; @@ -193,7 +213,7 @@ interface tcp { /// # Typical errors /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. - /// - `invalid-state`: (set) The socket is already in the Connection state. + /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -253,8 +273,6 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - /// - `invalid-state`: (set) The socket is already in the Connection state. - /// - `invalid-state`: (set) The socket is already in the Listener state. hop-limit: func() -> result; set-hop-limit: func(value: u8) -> result<_, error-code>; @@ -268,14 +286,25 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - /// - `invalid-state`: (set) The socket is already in the Connection state. - /// - `invalid-state`: (set) The socket is already in the Listener state. receive-buffer-size: func() -> result; set-receive-buffer-size: func(value: u64) -> result<_, error-code>; send-buffer-size: func() -> result; set-send-buffer-size: func(value: u64) -> result<_, error-code>; - /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// Create a `pollable` which can be used to poll for, or block on, + /// completion of any of the asynchronous operations of this socket. + /// + /// When `finish-bind`, `finish-listen`, `finish-connect` or `accept` + /// return `error(would-block)`, this pollable can be used to wait for + /// their success or failure, after which the method can be retried. + /// + /// The pollable is not limited to the async operation that happens to be + /// in progress at the time of calling `subscribe` (if any). Theoretically, + /// `subscribe` only has to be called once per socket and can then be + /// (re)used for the remainder of the socket's lifetime. + /// + /// See + /// for a more information. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @@ -297,7 +326,7 @@ interface tcp { /// The shutdown function does not close (drop) the socket. /// /// # Typical errors - /// - `invalid-state`: The socket is not in the Connection state. (ENOTCONN) + /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) /// /// # References /// - From 55346c1ebfb732d090858fab88ddd9735e4dad07 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 17 Jan 2024 22:09:13 +0100 Subject: [PATCH 1390/1772] Clarify how the async operations can be implemented --- proposals/sockets/imports.md | 29 ++++++++++++++++++++++------- proposals/sockets/wit/tcp.wit | 26 +++++++++++++++++++++----- proposals/sockets/wit/udp.wit | 8 ++++++-- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 459f2bf9f..1be248efe 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -338,7 +338,6 @@ being reaedy for I/O.

              If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the port is zero, the socket will be bound to a random free port.

              -

              Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

              Typical start errors

              • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
              • @@ -352,6 +351,11 @@ If the port is zero, the socket will be bound to a random free port.

              • not-in-progress: A bind operation is not in progress.
              • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
              +

              Implementors note

              +

              Unlike in POSIX, in WASI the bind operation is async. This enables +interactive WASI hosts to inject permission prompts. Runtimes that +don't want to make use of this ability can simply call the native +bind as part of either start-bind or finish-bind.

              References

              • https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
              • @@ -1214,7 +1218,6 @@ the term "bound" without backticks it actually means: in the bou

                If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the TCP/UDP port is zero, the socket will be bound to a random free port.

                -

                Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                Typical start errors

                • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
                • @@ -1235,6 +1238,10 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                  state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR socket option should be set implicitly on all platforms, except on Windows where this is the default behavior and SO_REUSEADDR performs something different entirely.

                  +

                  Unlike in POSIX, in WASI the bind operation is async. This enables +interactive WASI hosts to inject permission prompts. Runtimes that +don't want to make use of this ability can simply call the native +bind as part of either start-bind or finish-bind.

                  References

                  +

                  Implementors note

                  +

                  The POSIX equivalent of start-connect is the regular connect syscall. +Because all WASI sockets are non-blocking this is expected to return +EINPROGRESS, which should be translated to ok() in WASI.

                  +

                  The POSIX equivalent of finish-connect is a poll for event POLLOUT +with a timeout of 0 on the socket descriptor. Followed by a check for +the SO_ERROR socket option, in case the poll signaled readiness.

                  References

                  • https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
                  • @@ -1322,11 +1336,7 @@ socket can not be used to connect more than once.

                    [method]tcp-socket.start-listen: func

                    Start listening for new connections.

                    Transitions the socket into the listening state.

                    -

                    Unlike POSIX:

                    -
                      -
                    • this function is async. This enables interactive WASI hosts to inject permission prompts.
                    • -
                    • the socket must already be explicitly bound.
                    • -
                    +

                    Unlike POSIX, the socket must already be explicitly bound.

                    Typical start errors

                    • invalid-state: The socket is not bound to any local address. (EDESTADDRREQ)
                    • @@ -1339,6 +1349,11 @@ socket can not be used to connect more than once.

                    • not-in-progress: A listen operation is not in progress.
                    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
                    +

                    Implementors note

                    +

                    Unlike in POSIX, in WASI the listen operation is async. This enables +interactive WASI hosts to inject permission prompts. Runtimes that +don't want to make use of this ability can simply call the native +listen as part of either start-listen or finish-listen.

                    References

                    • https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html
                    • diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index e54f06f32..1f5f1664e 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -44,8 +44,6 @@ interface tcp { /// network interface(s) to bind to. /// If the TCP/UDP port is zero, the socket will be bound to a random free port. /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// /// # Typical `start` errors /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) @@ -65,6 +63,11 @@ interface tcp { /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior /// and SO_REUSEADDR performs something different entirely. /// + /// Unlike in POSIX, in WASI the bind operation is async. This enables + /// interactive WASI hosts to inject permission prompts. Runtimes that + /// don't want to make use of this ability can simply call the native + /// `bind` as part of either `start-bind` or `finish-bind`. + /// /// # References /// - /// - @@ -103,6 +106,15 @@ interface tcp { /// - `not-in-progress`: A connect operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) /// + /// # Implementors note + /// The POSIX equivalent of `start-connect` is the regular `connect` syscall. + /// Because all WASI sockets are non-blocking this is expected to return + /// EINPROGRESS, which should be translated to `ok()` in WASI. + /// + /// The POSIX equivalent of `finish-connect` is a `poll` for event `POLLOUT` + /// with a timeout of 0 on the socket descriptor. Followed by a check for + /// the `SO_ERROR` socket option, in case the poll signaled readiness. + /// /// # References /// - /// - @@ -115,9 +127,7 @@ interface tcp { /// /// Transitions the socket into the `listening` state. /// - /// Unlike POSIX: - /// - this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - the socket must already be explicitly bound. + /// Unlike POSIX, the socket must already be explicitly bound. /// /// # Typical `start` errors /// - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ) @@ -129,6 +139,12 @@ interface tcp { /// - `not-in-progress`: A listen operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) /// + /// # Implementors note + /// Unlike in POSIX, in WASI the listen operation is async. This enables + /// interactive WASI hosts to inject permission prompts. Runtimes that + /// don't want to make use of this ability can simply call the native + /// `listen` as part of either `start-listen` or `finish-listen`. + /// /// # References /// - /// - diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index ae82b97fc..64ef4c483 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -43,8 +43,6 @@ interface udp { /// network interface(s) to bind to. /// If the port is zero, the socket will be bound to a random free port. /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// /// # Typical `start` errors /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) /// - `invalid-state`: The socket is already bound. (EINVAL) @@ -56,6 +54,12 @@ interface udp { /// - `not-in-progress`: A `bind` operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) /// + /// # Implementors note + /// Unlike in POSIX, in WASI the bind operation is async. This enables + /// interactive WASI hosts to inject permission prompts. Runtimes that + /// don't want to make use of this ability can simply call the native + /// `bind` as part of either `start-bind` or `finish-bind`. + /// /// # References /// - /// - From ab587b9470717210a90d45b1361928d15a2557a9 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 17 Jan 2024 23:45:43 +0100 Subject: [PATCH 1391/1772] Reorder transitions --- proposals/sockets/TcpSocketOperationalSemantics.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/sockets/TcpSocketOperationalSemantics.md b/proposals/sockets/TcpSocketOperationalSemantics.md index 7be51cf7b..dd66880b2 100644 --- a/proposals/sockets/TcpSocketOperationalSemantics.md +++ b/proposals/sockets/TcpSocketOperationalSemantics.md @@ -83,10 +83,10 @@ stateDiagram-v2 BindInProgress --> Unbound: finish-bind()\n#error(NOT would-block) BindInProgress --> Bound: finish-bind()\n#ok - Bound --> ListenInProgress: start-listen()\n#ok - Bound --> Closed: start-listen()\n#error Bound --> ConnectInProgress: start-connect()\n#ok Bound --> Closed: start-connect()\n#error + Bound --> ListenInProgress: start-listen()\n#ok + Bound --> Closed: start-listen()\n#error ListenInProgress --> ListenInProgress: finish-listen()\n#error(would-block) ListenInProgress --> Closed: finish-listen()\n#error(NOT would-block) From e6582892f52f5cb8ed0d5499f40489d20aa6088b Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 18 Jan 2024 00:18:55 +0100 Subject: [PATCH 1392/1772] Clarify that `bind` can be attempted more than once. --- proposals/sockets/imports.md | 4 ++++ proposals/sockets/wit/tcp.wit | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 1be248efe..60a2b3e93 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -1218,6 +1218,10 @@ the term "bound" without backticks it actually means: in the bou

                      If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the TCP/UDP port is zero, the socket will be bound to a random free port.

                      +

                      Bind can be attempted multiple times on the same socket, even with +different arguments on each iteration. But never concurrently and +only as long as the previous bind failed. Once a bind succeeds, the +binding can't be changed anymore.

                      Typical start errors

                      • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
                      • diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 1f5f1664e..8986a4c25 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -44,6 +44,11 @@ interface tcp { /// network interface(s) to bind to. /// If the TCP/UDP port is zero, the socket will be bound to a random free port. /// + /// Bind can be attempted multiple times on the same socket, even with + /// different arguments on each iteration. But never concurrently and + /// only as long as the previous bind failed. Once a bind succeeds, the + /// binding can't be changed anymore. + /// /// # Typical `start` errors /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) From 9bc493dcae81badd6274c8ebf35c441c65d235f6 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 18 Jan 2024 00:38:11 +0100 Subject: [PATCH 1393/1772] Remove distinction between Start and Finish errors, as this won't exist anymore in preview3. --- proposals/sockets/README.md | 1 + proposals/sockets/imports.md | 20 ++++---------------- proposals/sockets/wit/tcp.wit | 12 +++--------- proposals/sockets/wit/udp.wit | 4 +--- 4 files changed, 9 insertions(+), 28 deletions(-) diff --git a/proposals/sockets/README.md b/proposals/sockets/README.md index 5b800b5b4..bc2f088b9 100644 --- a/proposals/sockets/README.md +++ b/proposals/sockets/README.md @@ -95,6 +95,7 @@ The semantics are as follows: - When `finish-*` returns anything other than `would-block`: - The asynchronous operation should be considered "finished" (either successful or failed) - Future calls to `finish-*` return the `not-in-progress` error code. +- The documented error codes can be returned from either the `start-*` function or the `finish-*` function. Both are equally correct. Runtimes that don't need asynchrony, can simply validate the arguments provided to the `start` function and stash them on their internal socket instance and perform the actual syscall in the `finish` function. Conveniently, sockets only allow one of these `start/finish` asynchronous operation to be active at a time. diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 60a2b3e93..8f73f27f2 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -338,13 +338,10 @@ being reaedy for I/O.

                        If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the port is zero, the socket will be bound to a random free port.

                        -

                        Typical start errors

                        +

                        Typical errors

                        • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
                        • invalid-state: The socket is already bound. (EINVAL)
                        • -
                        -

                        Typical finish errors

                        -
                        • address-in-use: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
                        • address-in-use: Address is already in use. (EADDRINUSE)
                        • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
                        • @@ -1222,15 +1219,12 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                          different arguments on each iteration. But never concurrently and only as long as the previous bind failed. Once a bind succeeds, the binding can't be changed anymore.

                          -

                          Typical start errors

                          +

                          Typical errors

                          • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
                          • invalid-argument: local-address is not a unicast address. (EINVAL)
                          • invalid-argument: local-address is an IPv4-mapped IPv6 address. (EINVAL)
                          • invalid-state: The socket is already bound. (EINVAL)
                          • -
                          -

                          Typical finish errors

                          -
                          • address-in-use: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
                          • address-in-use: Address is already in use. (EADDRINUSE)
                          • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
                          • @@ -1282,7 +1276,7 @@ don't want to make use of this ability can simply call the native

                            After a failed connection attempt, the socket will be in the closed state and the only valid action left is to drop the socket. A single socket can not be used to connect more than once.

                            -

                            Typical start errors

                            +

                            Typical errors

                            • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
                            • invalid-argument: remote-address is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
                            • @@ -1292,9 +1286,6 @@ socket can not be used to connect more than once.

                            • invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
                            • invalid-state: The socket is already in the connected state. (EISCONN)
                            • invalid-state: The socket is already in the listening state. (EOPNOTSUPP, EINVAL on Windows)
                            • -
                            -

                            Typical finish errors

                            -
                            • timeout: Connection timed out. (ETIMEDOUT)
                            • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
                            • connection-reset: The connection was reset. (ECONNRESET)
                            • @@ -1341,14 +1332,11 @@ the SO_ERROR socket option, in case the poll signaled readiness.

                              Start listening for new connections.

                              Transitions the socket into the listening state.

                              Unlike POSIX, the socket must already be explicitly bound.

                              -

                              Typical start errors

                              +

                              Typical errors

                              • invalid-state: The socket is not bound to any local address. (EDESTADDRREQ)
                              • invalid-state: The socket is already in the connected state. (EISCONN, EINVAL on BSD)
                              • invalid-state: The socket is already in the listening state.
                              • -
                              -

                              Typical finish errors

                              -
                              • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
                              • not-in-progress: A listen operation is not in progress.
                              • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
                              • diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 8986a4c25..9f12b8212 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -49,13 +49,11 @@ interface tcp { /// only as long as the previous bind failed. Once a bind succeeds, the /// binding can't be changed anymore. /// - /// # Typical `start` errors + /// # Typical errors /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - /// # Typical `finish` errors /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) /// - `address-in-use`: Address is already in use. (EADDRINUSE) /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) @@ -91,7 +89,7 @@ interface tcp { /// state and the only valid action left is to `drop` the socket. A single /// socket can not be used to connect more than once. /// - /// # Typical `start` errors + /// # Typical errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) @@ -100,8 +98,6 @@ interface tcp { /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) - /// - /// # Typical `finish` errors /// - `timeout`: Connection timed out. (ETIMEDOUT) /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) /// - `connection-reset`: The connection was reset. (ECONNRESET) @@ -134,12 +130,10 @@ interface tcp { /// /// Unlike POSIX, the socket must already be explicitly bound. /// - /// # Typical `start` errors + /// # Typical errors /// - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ) /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) /// - `invalid-state`: The socket is already in the `listening` state. - /// - /// # Typical `finish` errors /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) /// - `not-in-progress`: A listen operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 64ef4c483..6ba380ff7 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -43,11 +43,9 @@ interface udp { /// network interface(s) to bind to. /// If the port is zero, the socket will be bound to a random free port. /// - /// # Typical `start` errors + /// # Typical errors /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - /// # Typical `finish` errors /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) /// - `address-in-use`: Address is already in use. (EADDRINUSE) /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) From 342fbcc51cc6940c181e471ee247dd2c26382597 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 22 Jan 2024 16:40:26 -0800 Subject: [PATCH 1394/1772] Update to the latest wasi-sockets. Update to the latest wasi-sockets. This just contains documentation changes, and no interface changes. --- proposals/http/wit/deps.lock | 4 +- proposals/http/wit/deps/sockets/tcp.wit | 116 ++++++++++++++++-------- proposals/http/wit/deps/sockets/udp.wit | 12 ++- 3 files changed, 89 insertions(+), 43 deletions(-) diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 500fe9d51..fa5d5682b 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -25,5 +25,5 @@ sha512 = "cc4fa3d178559a89d9d6a376e3359b892158d1e73317c5db1f797ebc6b0b57abf24227 [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "40863017f355ac90c57630cc00b94518804e8e2c5694a7870b7a54dbdcda0e08" -sha512 = "2d6a919247430e869bf85a06a6a1d198f04368951e76c1fec7961b2b07af381c58c8e8b9079c91925dfbf80976971213329be57d59a90bae6e4e6460b073dc88" +sha256 = "9a3816bfa5a8b0673e5651024d8f9a1540f169f6d70f2bde6ee0e8240cd177ee" +sha512 = "bfcce89127510e16e9e7d7ac058ba3108953067e2d53f05cb1020dadf552738753b7fc9d10797236f2ced089063de7ac853fd9526079758fab1419d9b58a5212" diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index e045a436a..9f12b8212 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -15,9 +15,28 @@ interface tcp { /// Similar to `SHUT_RDWR` in POSIX. both, } - - - /// A TCP socket handle. + + /// A TCP socket resource. + /// + /// The socket can be in one of the following states: + /// - `unbound` + /// - `bind-in-progress` + /// - `bound` (See note below) + /// - `listen-in-progress` + /// - `listening` + /// - `connect-in-progress` + /// - `connected` + /// - `closed` + /// See + /// for a more information. + /// + /// Note: Except where explicitly mentioned, whenever this documentation uses + /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. + /// (i.e. `bound`, `listen-in-progress`, `listening`, `connect-in-progress` or `connected`) + /// + /// In addition to the general error codes documented on the + /// `network::error-code` type, TCP socket methods may always return + /// `error(invalid-state)` when in the `closed` state. resource tcp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -25,15 +44,16 @@ interface tcp { /// network interface(s) to bind to. /// If the TCP/UDP port is zero, the socket will be bound to a random free port. /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// Bind can be attempted multiple times on the same socket, even with + /// different arguments on each iteration. But never concurrently and + /// only as long as the previous bind failed. Once a bind succeeds, the + /// binding can't be changed anymore. /// - /// # Typical `start` errors + /// # Typical errors /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - /// # Typical `finish` errors /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) /// - `address-in-use`: Address is already in use. (EADDRINUSE) /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) @@ -46,6 +66,11 @@ interface tcp { /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior /// and SO_REUSEADDR performs something different entirely. /// + /// Unlike in POSIX, in WASI the bind operation is async. This enables + /// interactive WASI hosts to inject permission prompts. Runtimes that + /// don't want to make use of this ability can simply call the native + /// `bind` as part of either `start-bind` or `finish-bind`. + /// /// # References /// - /// - @@ -57,32 +82,40 @@ interface tcp { /// Connect to a remote endpoint. /// /// On success: - /// - the socket is transitioned into the Connection state + /// - the socket is transitioned into the `connection` state. /// - a pair of streams is returned that can be used to read & write to the connection /// - /// After a failed connection attempt, the only valid action left is to - /// `drop` the socket. A single socket can not be used to connect more than once. + /// After a failed connection attempt, the socket will be in the `closed` + /// state and the only valid action left is to `drop` the socket. A single + /// socket can not be used to connect more than once. /// - /// # Typical `start` errors + /// # Typical errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `invalid-state`: The socket is already in the Connection state. (EISCONN) - /// - `invalid-state`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) - /// - /// # Typical `finish` errors + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) + /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) /// - `timeout`: Connection timed out. (ETIMEDOUT) /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) /// - `connection-reset`: The connection was reset. (ECONNRESET) /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `not-in-progress`: A connect operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) /// + /// # Implementors note + /// The POSIX equivalent of `start-connect` is the regular `connect` syscall. + /// Because all WASI sockets are non-blocking this is expected to return + /// EINPROGRESS, which should be translated to `ok()` in WASI. + /// + /// The POSIX equivalent of `finish-connect` is a `poll` for event `POLLOUT` + /// with a timeout of 0 on the socket descriptor. Followed by a check for + /// the `SO_ERROR` socket option, in case the poll signaled readiness. + /// /// # References /// - /// - @@ -93,22 +126,24 @@ interface tcp { /// Start listening for new connections. /// - /// Transitions the socket into the Listener state. + /// Transitions the socket into the `listening` state. /// - /// Unlike POSIX: - /// - this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - the socket must already be explicitly bound. + /// Unlike POSIX, the socket must already be explicitly bound. /// - /// # Typical `start` errors + /// # Typical errors /// - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ) - /// - `invalid-state`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) - /// - `invalid-state`: The socket is already in the Listener state. - /// - /// # Typical `finish` errors + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) + /// - `invalid-state`: The socket is already in the `listening` state. /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - `not-in-progress`: A `listen` operation is not in progress. + /// - `not-in-progress`: A listen operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) /// + /// # Implementors note + /// Unlike in POSIX, in WASI the listen operation is async. This enables + /// interactive WASI hosts to inject permission prompts. Runtimes that + /// don't want to make use of this ability can simply call the native + /// `listen` as part of either `start-listen` or `finish-listen`. + /// /// # References /// - /// - @@ -119,7 +154,7 @@ interface tcp { /// Accept a new client socket. /// - /// The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket: + /// The returned socket is bound and in the `connected` state. The following properties are inherited from the listener socket: /// - `address-family` /// - `keep-alive-enabled` /// - `keep-alive-idle-time` @@ -133,7 +168,7 @@ interface tcp { /// a pair of streams that can be used to read & write to the connection. /// /// # Typical errors - /// - `invalid-state`: Socket is not in the Listener state. (EINVAL) + /// - `invalid-state`: Socket is not in the `listening` state. (EINVAL) /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) /// - `connection-aborted`: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED) /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) @@ -175,7 +210,7 @@ interface tcp { /// - remote-address: func() -> result; - /// Whether the socket is listening for new connections. + /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. is-listening: func() -> bool; @@ -193,7 +228,7 @@ interface tcp { /// # Typical errors /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. - /// - `invalid-state`: (set) The socket is already in the Connection state. + /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -253,8 +288,6 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - /// - `invalid-state`: (set) The socket is already in the Connection state. - /// - `invalid-state`: (set) The socket is already in the Listener state. hop-limit: func() -> result; set-hop-limit: func(value: u8) -> result<_, error-code>; @@ -268,14 +301,25 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - /// - `invalid-state`: (set) The socket is already in the Connection state. - /// - `invalid-state`: (set) The socket is already in the Listener state. receive-buffer-size: func() -> result; set-receive-buffer-size: func(value: u64) -> result<_, error-code>; send-buffer-size: func() -> result; set-send-buffer-size: func(value: u64) -> result<_, error-code>; - /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// Create a `pollable` which can be used to poll for, or block on, + /// completion of any of the asynchronous operations of this socket. + /// + /// When `finish-bind`, `finish-listen`, `finish-connect` or `accept` + /// return `error(would-block)`, this pollable can be used to wait for + /// their success or failure, after which the method can be retried. + /// + /// The pollable is not limited to the async operation that happens to be + /// in progress at the time of calling `subscribe` (if any). Theoretically, + /// `subscribe` only has to be called once per socket and can then be + /// (re)used for the remainder of the socket's lifetime. + /// + /// See + /// for a more information. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @@ -297,7 +341,7 @@ interface tcp { /// The shutdown function does not close (drop) the socket. /// /// # Typical errors - /// - `invalid-state`: The socket is not in the Connection state. (ENOTCONN) + /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) /// /// # References /// - diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index ae82b97fc..6ba380ff7 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -43,19 +43,21 @@ interface udp { /// network interface(s) to bind to. /// If the port is zero, the socket will be bound to a random free port. /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors + /// # Typical errors /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - /// # Typical `finish` errors /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) /// - `address-in-use`: Address is already in use. (EADDRINUSE) /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) /// - `not-in-progress`: A `bind` operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) /// + /// # Implementors note + /// Unlike in POSIX, in WASI the bind operation is async. This enables + /// interactive WASI hosts to inject permission prompts. Runtimes that + /// don't want to make use of this ability can simply call the native + /// `bind` as part of either `start-bind` or `finish-bind`. + /// /// # References /// - /// - From 4fa445dbe344ad4cab4d0103bd86db3ab465082f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 22 Jan 2024 18:06:08 -0800 Subject: [PATCH 1395/1772] Update to the latest wasi-sockets. (#40) * Update to the latest wasi-sockets. Update to the latest wasi-sockets. This just contains documentation changes, and no interface changes. * Update generated files. --- proposals/cli/command.md | 121 ++++++++++++++++--------- proposals/cli/imports.md | 121 ++++++++++++++++--------- proposals/cli/wit/deps.lock | 4 +- proposals/cli/wit/deps/sockets/tcp.wit | 116 ++++++++++++++++-------- proposals/cli/wit/deps/sockets/udp.wit | 12 ++- 5 files changed, 243 insertions(+), 131 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 263c2ac06..3d92c2063 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -1859,20 +1859,21 @@ supported size.

                                If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the port is zero, the socket will be bound to a random free port.

                                -

                                Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                                -

                                Typical start errors

                                +

                                Typical errors

                                • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
                                • invalid-state: The socket is already bound. (EINVAL)
                                • -
                                -

                                Typical finish errors

                                -
                                • address-in-use: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
                                • address-in-use: Address is already in use. (EADDRINUSE)
                                • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
                                • not-in-progress: A bind operation is not in progress.
                                • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
                                +

                                Implementors note

                                +

                                Unlike in POSIX, in WASI the bind operation is async. This enables +interactive WASI hosts to inject permission prompts. Runtimes that +don't want to make use of this ability can simply call the native +bind as part of either start-bind or finish-bind.

                                References

                                resource tcp-socket

                                -

                                A TCP socket handle.

                                +

                                A TCP socket resource.

                                +

                                The socket can be in one of the following states:

                                + +

                                Note: Except where explicitly mentioned, whenever this documentation uses +the term "bound" without backticks it actually means: in the bound state or higher. +(i.e. bound, listen-in-progress, listening, connect-in-progress or connected)

                                +

                                In addition to the general error codes documented on the +network::error-code type, TCP socket methods may always return +error(invalid-state) when in the closed state.

                                Functions

                                [method]tcp-socket.start-bind: func

                                Bind the socket to a specific network on the provided IP address and port.

                                If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the TCP/UDP port is zero, the socket will be bound to a random free port.

                                -

                                Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                                -

                                Typical start errors

                                +

                                Bind can be attempted multiple times on the same socket, even with +different arguments on each iteration. But never concurrently and +only as long as the previous bind failed. Once a bind succeeds, the +binding can't be changed anymore.

                                +

                                Typical errors

                                • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
                                • invalid-argument: local-address is not a unicast address. (EINVAL)
                                • invalid-argument: local-address is an IPv4-mapped IPv6 address. (EINVAL)
                                • invalid-state: The socket is already bound. (EINVAL)
                                • -
                                -

                                Typical finish errors

                                -
                                • address-in-use: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
                                • address-in-use: Address is already in use. (EADDRINUSE)
                                • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
                                • @@ -2325,6 +2345,10 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                                  state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR socket option should be set implicitly on all platforms, except on Windows where this is the default behavior and SO_REUSEADDR performs something different entirely.

                                  +

                                  Unlike in POSIX, in WASI the bind operation is async. This enables +interactive WASI hosts to inject permission prompts. Runtimes that +don't want to make use of this ability can simply call the native +bind as part of either start-bind or finish-bind.

                                  References

                                  • https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
                                  • @@ -2355,12 +2379,13 @@ and SO_REUSEADDR performs something different entirely.

                                    Connect to a remote endpoint.

                                    On success:

                                      -
                                    • the socket is transitioned into the Connection state
                                    • +
                                    • the socket is transitioned into the connection state.
                                    • a pair of streams is returned that can be used to read & write to the connection
                                    -

                                    After a failed connection attempt, the only valid action left is to -drop the socket. A single socket can not be used to connect more than once.

                                    -

                                    Typical start errors

                                    +

                                    After a failed connection attempt, the socket will be in the closed +state and the only valid action left is to drop the socket. A single +socket can not be used to connect more than once.

                                    +

                                    Typical errors

                                    • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
                                    • invalid-argument: remote-address is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
                                    • @@ -2368,20 +2393,24 @@ and SO_REUSEADDR performs something different entirely.

                                    • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
                                    • invalid-argument: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
                                    • invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
                                    • -
                                    • invalid-state: The socket is already in the Connection state. (EISCONN)
                                    • -
                                    • invalid-state: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
                                    • -
                                    -

                                    Typical finish errors

                                    -
                                      +
                                    • invalid-state: The socket is already in the connected state. (EISCONN)
                                    • +
                                    • invalid-state: The socket is already in the listening state. (EOPNOTSUPP, EINVAL on Windows)
                                    • timeout: Connection timed out. (ETIMEDOUT)
                                    • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
                                    • connection-reset: The connection was reset. (ECONNRESET)
                                    • connection-aborted: The connection was aborted. (ECONNABORTED)
                                    • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
                                    • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
                                    • -
                                    • not-in-progress: A connect operation is not in progress.
                                    • +
                                    • not-in-progress: A connect operation is not in progress.
                                    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
                                    +

                                    Implementors note

                                    +

                                    The POSIX equivalent of start-connect is the regular connect syscall. +Because all WASI sockets are non-blocking this is expected to return +EINPROGRESS, which should be translated to ok() in WASI.

                                    +

                                    The POSIX equivalent of finish-connect is a poll for event POLLOUT +with a timeout of 0 on the socket descriptor. Followed by a check for +the SO_ERROR socket option, in case the poll signaled readiness.

                                    References

                                    [method]tcp-socket.start-listen: func

                                    Start listening for new connections.

                                    -

                                    Transitions the socket into the Listener state.

                                    -

                                    Unlike POSIX:

                                    -
                                      -
                                    • this function is async. This enables interactive WASI hosts to inject permission prompts.
                                    • -
                                    • the socket must already be explicitly bound.
                                    • -
                                    -

                                    Typical start errors

                                    +

                                    Transitions the socket into the listening state.

                                    +

                                    Unlike POSIX, the socket must already be explicitly bound.

                                    +

                                    Typical errors

                                    • invalid-state: The socket is not bound to any local address. (EDESTADDRREQ)
                                    • -
                                    • invalid-state: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
                                    • -
                                    • invalid-state: The socket is already in the Listener state.
                                    • -
                                    -

                                    Typical finish errors

                                    -
                                      +
                                    • invalid-state: The socket is already in the connected state. (EISCONN, EINVAL on BSD)
                                    • +
                                    • invalid-state: The socket is already in the listening state.
                                    • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
                                    • -
                                    • not-in-progress: A listen operation is not in progress.
                                    • +
                                    • not-in-progress: A listen operation is not in progress.
                                    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
                                    +

                                    Implementors note

                                    +

                                    Unlike in POSIX, in WASI the listen operation is async. This enables +interactive WASI hosts to inject permission prompts. Runtimes that +don't want to make use of this ability can simply call the native +listen as part of either start-listen or finish-listen.

                                    References

                                    [method]tcp-socket.accept: func

                                    Accept a new client socket.

                                    -

                                    The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket:

                                    +

                                    The returned socket is bound and in the connected state. The following properties are inherited from the listener socket:

                                    • address-family
                                    • keep-alive-enabled
                                    • @@ -2469,7 +2496,7 @@ and SO_REUSEADDR performs something different entirely.

                                      a pair of streams that can be used to read & write to the connection.

                                      Typical errors

                                        -
                                      • invalid-state: Socket is not in the Listener state. (EINVAL)
                                      • +
                                      • invalid-state: Socket is not in the listening state. (EINVAL)
                                      • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
                                      • connection-aborted: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED)
                                      • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
                                      • @@ -2538,7 +2565,7 @@ stored in the object pointed to by address is unspecified.

                                      • result<ip-socket-address, error-code>

                                      [method]tcp-socket.is-listening: func

                                      -

                                      Whether the socket is listening for new connections.

                                      +

                                      Whether the socket is in the listening state.

                                      Equivalent to the SO_ACCEPTCONN socket option.

                                      Params
                                        @@ -2567,7 +2594,7 @@ Any other value will never cause an error, but it might be silently clamped and/
                                        • not-supported: (set) The platform does not support changing the backlog size after the initial listen.
                                        • invalid-argument: (set) The provided value was 0.
                                        • -
                                        • invalid-state: (set) The socket is already in the Connection state.
                                        • +
                                        • invalid-state: (set) The socket is in the connect-in-progress or connected state.
                                        Params
                                          @@ -2696,8 +2723,6 @@ I.e. after setting a value, reading the same setting back may return a different

                                          Typical errors

                                          • invalid-argument: (set) The TTL value must be 1 or higher.
                                          • -
                                          • invalid-state: (set) The socket is already in the Connection state.
                                          • -
                                          • invalid-state: (set) The socket is already in the Listener state.
                                          Params
                                            @@ -2726,8 +2751,6 @@ I.e. after setting a value, reading the same setting back may return a different

                                            Typical errors

                                            • invalid-argument: (set) The provided value was 0.
                                            • -
                                            • invalid-state: (set) The socket is already in the Connection state.
                                            • -
                                            • invalid-state: (set) The socket is already in the Listener state.
                                            Params
                                              @@ -2767,7 +2790,17 @@ I.e. after setting a value, reading the same setting back may return a different
                                            • result<_, error-code>

                                            [method]tcp-socket.subscribe: func

                                            -

                                            Create a pollable which will resolve once the socket is ready for I/O.

                                            +

                                            Create a pollable which can be used to poll for, or block on, +completion of any of the asynchronous operations of this socket.

                                            +

                                            When finish-bind, finish-listen, finish-connect or accept +return error(would-block), this pollable can be used to wait for +their success or failure, after which the method can be retried.

                                            +

                                            The pollable is not limited to the async operation that happens to be +in progress at the time of calling subscribe (if any). Theoretically, +subscribe only has to be called once per socket and can then be +(re)used for the remainder of the socket's lifetime.

                                            +

                                            See https://github.com/WebAssembly/wasi-sockets/TcpSocketOperationalSemantics.md#Pollable-readiness +for a more information.

                                            Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

                                            Params
                                            @@ -2794,7 +2827,7 @@ has no effect and returns ok.

                                            The shutdown function does not close (drop) the socket.

                                            Typical errors

                                              -
                                            • invalid-state: The socket is not in the Connection state. (ENOTCONN)
                                            • +
                                            • invalid-state: The socket is not in the connected state. (ENOTCONN)

                                            References

                                              diff --git a/proposals/cli/imports.md b/proposals/cli/imports.md index 0e264c07a..48cd5a078 100644 --- a/proposals/cli/imports.md +++ b/proposals/cli/imports.md @@ -1854,20 +1854,21 @@ supported size.

                                              If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the port is zero, the socket will be bound to a random free port.

                                              -

                                              Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                                              -

                                              Typical start errors

                                              +

                                              Typical errors

                                              • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
                                              • invalid-state: The socket is already bound. (EINVAL)
                                              • -
                                              -

                                              Typical finish errors

                                              -
                                              • address-in-use: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
                                              • address-in-use: Address is already in use. (EADDRINUSE)
                                              • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
                                              • not-in-progress: A bind operation is not in progress.
                                              • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
                                              +

                                              Implementors note

                                              +

                                              Unlike in POSIX, in WASI the bind operation is async. This enables +interactive WASI hosts to inject permission prompts. Runtimes that +don't want to make use of this ability can simply call the native +bind as part of either start-bind or finish-bind.

                                              References

                                              resource tcp-socket

                                              -

                                              A TCP socket handle.

                                              +

                                              A TCP socket resource.

                                              +

                                              The socket can be in one of the following states:

                                              + +

                                              Note: Except where explicitly mentioned, whenever this documentation uses +the term "bound" without backticks it actually means: in the bound state or higher. +(i.e. bound, listen-in-progress, listening, connect-in-progress or connected)

                                              +

                                              In addition to the general error codes documented on the +network::error-code type, TCP socket methods may always return +error(invalid-state) when in the closed state.

                                              Functions

                                              [method]tcp-socket.start-bind: func

                                              Bind the socket to a specific network on the provided IP address and port.

                                              If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the TCP/UDP port is zero, the socket will be bound to a random free port.

                                              -

                                              Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

                                              -

                                              Typical start errors

                                              +

                                              Bind can be attempted multiple times on the same socket, even with +different arguments on each iteration. But never concurrently and +only as long as the previous bind failed. Once a bind succeeds, the +binding can't be changed anymore.

                                              +

                                              Typical errors

                                              • invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
                                              • invalid-argument: local-address is not a unicast address. (EINVAL)
                                              • invalid-argument: local-address is an IPv4-mapped IPv6 address. (EINVAL)
                                              • invalid-state: The socket is already bound. (EINVAL)
                                              • -
                                              -

                                              Typical finish errors

                                              -
                                              • address-in-use: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
                                              • address-in-use: Address is already in use. (EADDRINUSE)
                                              • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
                                              • @@ -2320,6 +2340,10 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

                                                state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR socket option should be set implicitly on all platforms, except on Windows where this is the default behavior and SO_REUSEADDR performs something different entirely.

                                                +

                                                Unlike in POSIX, in WASI the bind operation is async. This enables +interactive WASI hosts to inject permission prompts. Runtimes that +don't want to make use of this ability can simply call the native +bind as part of either start-bind or finish-bind.

                                                References

                                                • https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
                                                • @@ -2350,12 +2374,13 @@ and SO_REUSEADDR performs something different entirely.

                                                  Connect to a remote endpoint.

                                                  On success:

                                                    -
                                                  • the socket is transitioned into the Connection state
                                                  • +
                                                  • the socket is transitioned into the connection state.
                                                  • a pair of streams is returned that can be used to read & write to the connection
                                                  -

                                                  After a failed connection attempt, the only valid action left is to -drop the socket. A single socket can not be used to connect more than once.

                                                  -

                                                  Typical start errors

                                                  +

                                                  After a failed connection attempt, the socket will be in the closed +state and the only valid action left is to drop the socket. A single +socket can not be used to connect more than once.

                                                  +

                                                  Typical errors

                                                  • invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
                                                  • invalid-argument: remote-address is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
                                                  • @@ -2363,20 +2388,24 @@ and SO_REUSEADDR performs something different entirely.

                                                  • invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
                                                  • invalid-argument: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
                                                  • invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
                                                  • -
                                                  • invalid-state: The socket is already in the Connection state. (EISCONN)
                                                  • -
                                                  • invalid-state: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
                                                  • -
                                                  -

                                                  Typical finish errors

                                                  -
                                                    +
                                                  • invalid-state: The socket is already in the connected state. (EISCONN)
                                                  • +
                                                  • invalid-state: The socket is already in the listening state. (EOPNOTSUPP, EINVAL on Windows)
                                                  • timeout: Connection timed out. (ETIMEDOUT)
                                                  • connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
                                                  • connection-reset: The connection was reset. (ECONNRESET)
                                                  • connection-aborted: The connection was aborted. (ECONNABORTED)
                                                  • remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
                                                  • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
                                                  • -
                                                  • not-in-progress: A connect operation is not in progress.
                                                  • +
                                                  • not-in-progress: A connect operation is not in progress.
                                                  • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
                                                  +

                                                  Implementors note

                                                  +

                                                  The POSIX equivalent of start-connect is the regular connect syscall. +Because all WASI sockets are non-blocking this is expected to return +EINPROGRESS, which should be translated to ok() in WASI.

                                                  +

                                                  The POSIX equivalent of finish-connect is a poll for event POLLOUT +with a timeout of 0 on the socket descriptor. Followed by a check for +the SO_ERROR socket option, in case the poll signaled readiness.

                                                  References

                                                  [method]tcp-socket.start-listen: func

                                                  Start listening for new connections.

                                                  -

                                                  Transitions the socket into the Listener state.

                                                  -

                                                  Unlike POSIX:

                                                  -
                                                    -
                                                  • this function is async. This enables interactive WASI hosts to inject permission prompts.
                                                  • -
                                                  • the socket must already be explicitly bound.
                                                  • -
                                                  -

                                                  Typical start errors

                                                  +

                                                  Transitions the socket into the listening state.

                                                  +

                                                  Unlike POSIX, the socket must already be explicitly bound.

                                                  +

                                                  Typical errors

                                                  • invalid-state: The socket is not bound to any local address. (EDESTADDRREQ)
                                                  • -
                                                  • invalid-state: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
                                                  • -
                                                  • invalid-state: The socket is already in the Listener state.
                                                  • -
                                                  -

                                                  Typical finish errors

                                                  -
                                                    +
                                                  • invalid-state: The socket is already in the connected state. (EISCONN, EINVAL on BSD)
                                                  • +
                                                  • invalid-state: The socket is already in the listening state.
                                                  • address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
                                                  • -
                                                  • not-in-progress: A listen operation is not in progress.
                                                  • +
                                                  • not-in-progress: A listen operation is not in progress.
                                                  • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
                                                  +

                                                  Implementors note

                                                  +

                                                  Unlike in POSIX, in WASI the listen operation is async. This enables +interactive WASI hosts to inject permission prompts. Runtimes that +don't want to make use of this ability can simply call the native +listen as part of either start-listen or finish-listen.

                                                  References

                                                  [method]tcp-socket.accept: func

                                                  Accept a new client socket.

                                                  -

                                                  The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket:

                                                  +

                                                  The returned socket is bound and in the connected state. The following properties are inherited from the listener socket:

                                                  • address-family
                                                  • keep-alive-enabled
                                                  • @@ -2464,7 +2491,7 @@ and SO_REUSEADDR performs something different entirely.

                                                    a pair of streams that can be used to read & write to the connection.

                                                    Typical errors

                                                      -
                                                    • invalid-state: Socket is not in the Listener state. (EINVAL)
                                                    • +
                                                    • invalid-state: Socket is not in the listening state. (EINVAL)
                                                    • would-block: No pending connections at the moment. (EWOULDBLOCK, EAGAIN)
                                                    • connection-aborted: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED)
                                                    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
                                                    • @@ -2533,7 +2560,7 @@ stored in the object pointed to by address is unspecified.

                                                    • result<ip-socket-address, error-code>

                                                    [method]tcp-socket.is-listening: func

                                                    -

                                                    Whether the socket is listening for new connections.

                                                    +

                                                    Whether the socket is in the listening state.

                                                    Equivalent to the SO_ACCEPTCONN socket option.

                                                    Params
                                                      @@ -2562,7 +2589,7 @@ Any other value will never cause an error, but it might be silently clamped and/
                                                      • not-supported: (set) The platform does not support changing the backlog size after the initial listen.
                                                      • invalid-argument: (set) The provided value was 0.
                                                      • -
                                                      • invalid-state: (set) The socket is already in the Connection state.
                                                      • +
                                                      • invalid-state: (set) The socket is in the connect-in-progress or connected state.
                                                      Params
                                                        @@ -2691,8 +2718,6 @@ I.e. after setting a value, reading the same setting back may return a different

                                                        Typical errors

                                                        • invalid-argument: (set) The TTL value must be 1 or higher.
                                                        • -
                                                        • invalid-state: (set) The socket is already in the Connection state.
                                                        • -
                                                        • invalid-state: (set) The socket is already in the Listener state.
                                                        Params
                                                          @@ -2721,8 +2746,6 @@ I.e. after setting a value, reading the same setting back may return a different

                                                          Typical errors

                                                          • invalid-argument: (set) The provided value was 0.
                                                          • -
                                                          • invalid-state: (set) The socket is already in the Connection state.
                                                          • -
                                                          • invalid-state: (set) The socket is already in the Listener state.
                                                          Params
                                                            @@ -2762,7 +2785,17 @@ I.e. after setting a value, reading the same setting back may return a different
                                                          • result<_, error-code>

                                                          [method]tcp-socket.subscribe: func

                                                          -

                                                          Create a pollable which will resolve once the socket is ready for I/O.

                                                          +

                                                          Create a pollable which can be used to poll for, or block on, +completion of any of the asynchronous operations of this socket.

                                                          +

                                                          When finish-bind, finish-listen, finish-connect or accept +return error(would-block), this pollable can be used to wait for +their success or failure, after which the method can be retried.

                                                          +

                                                          The pollable is not limited to the async operation that happens to be +in progress at the time of calling subscribe (if any). Theoretically, +subscribe only has to be called once per socket and can then be +(re)used for the remainder of the socket's lifetime.

                                                          +

                                                          See https://github.com/WebAssembly/wasi-sockets/TcpSocketOperationalSemantics.md#Pollable-readiness +for a more information.

                                                          Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

                                                          Params
                                                          @@ -2789,7 +2822,7 @@ has no effect and returns ok.

                                                          The shutdown function does not close (drop) the socket.

                                                          Typical errors

                                                            -
                                                          • invalid-state: The socket is not in the Connection state. (ENOTCONN)
                                                          • +
                                                          • invalid-state: The socket is not in the connected state. (ENOTCONN)

                                                          References

                                                            diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index c891d86cc..24b86d96f 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -20,5 +20,5 @@ sha512 = "cc4fa3d178559a89d9d6a376e3359b892158d1e73317c5db1f797ebc6b0b57abf24227 [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "40863017f355ac90c57630cc00b94518804e8e2c5694a7870b7a54dbdcda0e08" -sha512 = "2d6a919247430e869bf85a06a6a1d198f04368951e76c1fec7961b2b07af381c58c8e8b9079c91925dfbf80976971213329be57d59a90bae6e4e6460b073dc88" +sha256 = "9a3816bfa5a8b0673e5651024d8f9a1540f169f6d70f2bde6ee0e8240cd177ee" +sha512 = "bfcce89127510e16e9e7d7ac058ba3108953067e2d53f05cb1020dadf552738753b7fc9d10797236f2ced089063de7ac853fd9526079758fab1419d9b58a5212" diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index e045a436a..9f12b8212 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -15,9 +15,28 @@ interface tcp { /// Similar to `SHUT_RDWR` in POSIX. both, } - - - /// A TCP socket handle. + + /// A TCP socket resource. + /// + /// The socket can be in one of the following states: + /// - `unbound` + /// - `bind-in-progress` + /// - `bound` (See note below) + /// - `listen-in-progress` + /// - `listening` + /// - `connect-in-progress` + /// - `connected` + /// - `closed` + /// See + /// for a more information. + /// + /// Note: Except where explicitly mentioned, whenever this documentation uses + /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. + /// (i.e. `bound`, `listen-in-progress`, `listening`, `connect-in-progress` or `connected`) + /// + /// In addition to the general error codes documented on the + /// `network::error-code` type, TCP socket methods may always return + /// `error(invalid-state)` when in the `closed` state. resource tcp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -25,15 +44,16 @@ interface tcp { /// network interface(s) to bind to. /// If the TCP/UDP port is zero, the socket will be bound to a random free port. /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. + /// Bind can be attempted multiple times on the same socket, even with + /// different arguments on each iteration. But never concurrently and + /// only as long as the previous bind failed. Once a bind succeeds, the + /// binding can't be changed anymore. /// - /// # Typical `start` errors + /// # Typical errors /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - /// # Typical `finish` errors /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) /// - `address-in-use`: Address is already in use. (EADDRINUSE) /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) @@ -46,6 +66,11 @@ interface tcp { /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior /// and SO_REUSEADDR performs something different entirely. /// + /// Unlike in POSIX, in WASI the bind operation is async. This enables + /// interactive WASI hosts to inject permission prompts. Runtimes that + /// don't want to make use of this ability can simply call the native + /// `bind` as part of either `start-bind` or `finish-bind`. + /// /// # References /// - /// - @@ -57,32 +82,40 @@ interface tcp { /// Connect to a remote endpoint. /// /// On success: - /// - the socket is transitioned into the Connection state + /// - the socket is transitioned into the `connection` state. /// - a pair of streams is returned that can be used to read & write to the connection /// - /// After a failed connection attempt, the only valid action left is to - /// `drop` the socket. A single socket can not be used to connect more than once. + /// After a failed connection attempt, the socket will be in the `closed` + /// state and the only valid action left is to `drop` the socket. A single + /// socket can not be used to connect more than once. /// - /// # Typical `start` errors + /// # Typical errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `invalid-state`: The socket is already in the Connection state. (EISCONN) - /// - `invalid-state`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows) - /// - /// # Typical `finish` errors + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) + /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) /// - `timeout`: Connection timed out. (ETIMEDOUT) /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) /// - `connection-reset`: The connection was reset. (ECONNRESET) /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A `connect` operation is not in progress. + /// - `not-in-progress`: A connect operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) /// + /// # Implementors note + /// The POSIX equivalent of `start-connect` is the regular `connect` syscall. + /// Because all WASI sockets are non-blocking this is expected to return + /// EINPROGRESS, which should be translated to `ok()` in WASI. + /// + /// The POSIX equivalent of `finish-connect` is a `poll` for event `POLLOUT` + /// with a timeout of 0 on the socket descriptor. Followed by a check for + /// the `SO_ERROR` socket option, in case the poll signaled readiness. + /// /// # References /// - /// - @@ -93,22 +126,24 @@ interface tcp { /// Start listening for new connections. /// - /// Transitions the socket into the Listener state. + /// Transitions the socket into the `listening` state. /// - /// Unlike POSIX: - /// - this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - the socket must already be explicitly bound. + /// Unlike POSIX, the socket must already be explicitly bound. /// - /// # Typical `start` errors + /// # Typical errors /// - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ) - /// - `invalid-state`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD) - /// - `invalid-state`: The socket is already in the Listener state. - /// - /// # Typical `finish` errors + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) + /// - `invalid-state`: The socket is already in the `listening` state. /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - `not-in-progress`: A `listen` operation is not in progress. + /// - `not-in-progress`: A listen operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) /// + /// # Implementors note + /// Unlike in POSIX, in WASI the listen operation is async. This enables + /// interactive WASI hosts to inject permission prompts. Runtimes that + /// don't want to make use of this ability can simply call the native + /// `listen` as part of either `start-listen` or `finish-listen`. + /// /// # References /// - /// - @@ -119,7 +154,7 @@ interface tcp { /// Accept a new client socket. /// - /// The returned socket is bound and in the Connection state. The following properties are inherited from the listener socket: + /// The returned socket is bound and in the `connected` state. The following properties are inherited from the listener socket: /// - `address-family` /// - `keep-alive-enabled` /// - `keep-alive-idle-time` @@ -133,7 +168,7 @@ interface tcp { /// a pair of streams that can be used to read & write to the connection. /// /// # Typical errors - /// - `invalid-state`: Socket is not in the Listener state. (EINVAL) + /// - `invalid-state`: Socket is not in the `listening` state. (EINVAL) /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) /// - `connection-aborted`: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED) /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) @@ -175,7 +210,7 @@ interface tcp { /// - remote-address: func() -> result; - /// Whether the socket is listening for new connections. + /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. is-listening: func() -> bool; @@ -193,7 +228,7 @@ interface tcp { /// # Typical errors /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. - /// - `invalid-state`: (set) The socket is already in the Connection state. + /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -253,8 +288,6 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - /// - `invalid-state`: (set) The socket is already in the Connection state. - /// - `invalid-state`: (set) The socket is already in the Listener state. hop-limit: func() -> result; set-hop-limit: func(value: u8) -> result<_, error-code>; @@ -268,14 +301,25 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - /// - `invalid-state`: (set) The socket is already in the Connection state. - /// - `invalid-state`: (set) The socket is already in the Listener state. receive-buffer-size: func() -> result; set-receive-buffer-size: func(value: u64) -> result<_, error-code>; send-buffer-size: func() -> result; set-send-buffer-size: func(value: u64) -> result<_, error-code>; - /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// Create a `pollable` which can be used to poll for, or block on, + /// completion of any of the asynchronous operations of this socket. + /// + /// When `finish-bind`, `finish-listen`, `finish-connect` or `accept` + /// return `error(would-block)`, this pollable can be used to wait for + /// their success or failure, after which the method can be retried. + /// + /// The pollable is not limited to the async operation that happens to be + /// in progress at the time of calling `subscribe` (if any). Theoretically, + /// `subscribe` only has to be called once per socket and can then be + /// (re)used for the remainder of the socket's lifetime. + /// + /// See + /// for a more information. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @@ -297,7 +341,7 @@ interface tcp { /// The shutdown function does not close (drop) the socket. /// /// # Typical errors - /// - `invalid-state`: The socket is not in the Connection state. (ENOTCONN) + /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) /// /// # References /// - diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index ae82b97fc..6ba380ff7 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -43,19 +43,21 @@ interface udp { /// network interface(s) to bind to. /// If the port is zero, the socket will be bound to a random free port. /// - /// Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts. - /// - /// # Typical `start` errors + /// # Typical errors /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - /// # Typical `finish` errors /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) /// - `address-in-use`: Address is already in use. (EADDRINUSE) /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) /// - `not-in-progress`: A `bind` operation is not in progress. /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) /// + /// # Implementors note + /// Unlike in POSIX, in WASI the bind operation is async. This enables + /// interactive WASI hosts to inject permission prompts. Runtimes that + /// don't want to make use of this ability can simply call the native + /// `bind` as part of either `start-bind` or `finish-bind`. + /// /// # References /// - /// - From 75e17d76209fcf387c24e90d989d07b660566f39 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 11:53:43 -0800 Subject: [PATCH 1396/1772] copy in updated clocks and io packages at 0.2.0 --- .../wit/deps/clocks/monotonic-clock.wit | 4 ++-- .../filesystem/wit/deps/clocks/wall-clock.wit | 2 +- .../filesystem/wit/deps/clocks/world.wit | 2 +- proposals/filesystem/wit/deps/io/error.wit | 2 +- proposals/filesystem/wit/deps/io/poll.wit | 4 ++-- proposals/filesystem/wit/deps/io/streams.wit | 23 ++++++++++++++----- proposals/filesystem/wit/deps/io/world.wit | 2 +- 7 files changed, 25 insertions(+), 14 deletions(-) diff --git a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit index 09ef32c36..4e4dc3a19 100644 --- a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.0-rc-2023-11-10; /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:io/poll@0.2.0.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/filesystem/wit/deps/clocks/wall-clock.wit b/proposals/filesystem/wit/deps/clocks/wall-clock.wit index 8abb9a0c0..440ca0f33 100644 --- a/proposals/filesystem/wit/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/filesystem/wit/deps/clocks/world.wit b/proposals/filesystem/wit/deps/clocks/world.wit index 8fa080f0e..c0224572a 100644 --- a/proposals/filesystem/wit/deps/clocks/world.wit +++ b/proposals/filesystem/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; world imports { import monotonic-clock; diff --git a/proposals/filesystem/wit/deps/io/error.wit b/proposals/filesystem/wit/deps/io/error.wit index 31918acbb..22e5b6489 100644 --- a/proposals/filesystem/wit/deps/io/error.wit +++ b/proposals/filesystem/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; interface error { diff --git a/proposals/filesystem/wit/deps/io/poll.wit b/proposals/filesystem/wit/deps/io/poll.wit index bddde3c19..ddc67f8b7 100644 --- a/proposals/filesystem/wit/deps/io/poll.wit +++ b/proposals/filesystem/wit/deps/io/poll.wit @@ -1,9 +1,9 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { - /// `pollable` epresents a single I/O event which may be ready, or not. + /// `pollable` represents a single I/O event which may be ready, or not. resource pollable { /// Return the readiness of a pollable. This function never blocks. diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index e7e1b689a..6d2f871e3 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -32,6 +32,11 @@ interface streams { resource input-stream { /// Perform a non-blocking read from the stream. /// + /// When the source of a `read` is binary data, the bytes from the source + /// are returned verbatim. When the source of a `read` is known to the + /// implementation to be text, bytes containing the UTF-8 encoding of the + /// text are returned. + /// /// This function returns a list of bytes containing the read data, /// when successful. The returned list will contain up to `len` bytes; /// it may return fewer than requested, but not more. The list is @@ -111,6 +116,12 @@ interface streams { /// Perform a write. This function never blocks. /// + /// When the destination of a `write` is binary data, the bytes from + /// `contents` are written verbatim. When the destination of a `write` is + /// known to the implementation to be text, the bytes of `contents` are + /// transcoded from UTF-8 into the encoding of the destination and then + /// written. + /// /// Precondition: check-write gave permit of Ok(n) and contents has a /// length of less than or equal to n. Otherwise, this function will trap. /// @@ -131,7 +142,7 @@ interface streams { /// let pollable = this.subscribe(); /// while !contents.is_empty() { /// // Wait for the stream to become writable - /// poll-one(pollable); + /// pollable.block(); /// let Ok(n) = this.check-write(); // eliding error handling /// let len = min(n, contents.len()); /// let (chunk, rest) = contents.split_at(len); @@ -140,7 +151,7 @@ interface streams { /// } /// this.flush(); /// // Wait for completion of `flush` - /// poll-one(pollable); + /// pollable.block(); /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` @@ -178,7 +189,7 @@ interface streams { /// Write zeroes to a stream. /// - /// this should be used precisely like `write` with the exact same + /// This should be used precisely like `write` with the exact same /// preconditions (must use check-write first), but instead of /// passing a list of bytes, you simply pass the number of zero-bytes /// that should be written. @@ -199,7 +210,7 @@ interface streams { /// let pollable = this.subscribe(); /// while num_zeroes != 0 { /// // Wait for the stream to become writable - /// poll-one(pollable); + /// pollable.block(); /// let Ok(n) = this.check-write(); // eliding error handling /// let len = min(n, num_zeroes); /// this.write-zeroes(len); // eliding error handling @@ -207,7 +218,7 @@ interface streams { /// } /// this.flush(); /// // Wait for completion of `flush` - /// poll-one(pollable); + /// pollable.block(); /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` diff --git a/proposals/filesystem/wit/deps/io/world.wit b/proposals/filesystem/wit/deps/io/world.wit index 8243da2ee..5f0b43fe5 100644 --- a/proposals/filesystem/wit/deps/io/world.wit +++ b/proposals/filesystem/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; world imports { import streams; From b5a6e95ef200040cbd43ca27e740df1aa46b44b3 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 11:54:24 -0800 Subject: [PATCH 1397/1772] uses of io and clocks now @0.2.0 --- proposals/filesystem/wit/types.wit | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 059722ab8..ef1847f2b 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -24,8 +24,8 @@ package wasi:filesystem@0.2.0-rc-2023-11-10; /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { - use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream, error}; - use wasi:clocks/wall-clock@0.2.0-rc-2023-11-10.{datetime}; + use wasi:io/streams@0.2.0.{input-stream, output-stream, error}; + use wasi:clocks/wall-clock@0.2.0.{datetime}; /// File size or length of a region within a file. type filesize = u64; From 84ef2d31aa1dd645b43fb93459dfef25e70063a7 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 11:54:52 -0800 Subject: [PATCH 1398/1772] set wasi:filesysem package version to 0.2.0 --- proposals/filesystem/wit/preopens.wit | 2 +- proposals/filesystem/wit/types.wit | 2 +- proposals/filesystem/wit/world.wit | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit index 95ec67843..da801f6d6 100644 --- a/proposals/filesystem/wit/preopens.wit +++ b/proposals/filesystem/wit/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0-rc-2023-11-10; +package wasi:filesystem@0.2.0; interface preopens { use types.{descriptor}; diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index ef1847f2b..11108fcda 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0-rc-2023-11-10; +package wasi:filesystem@0.2.0; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index 285e0bae9..663f57920 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0-rc-2023-11-10; +package wasi:filesystem@0.2.0; world imports { import types; From 0008c366a60e9f124493b6937c8f553a477c068b Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 11:56:16 -0800 Subject: [PATCH 1399/1772] generate markdown --- proposals/filesystem/imports.md | 81 ++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 21 deletions(-) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index a0210f0d2..78acb2f58 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -2,20 +2,34 @@ -

                                                            Import interface wasi:io/error@0.2.0-rc-2023-11-10

                                                            +

                                                            Import interface wasi:io/error@0.2.0


                                                            Types

                                                            resource error

                                                            -
                                                            +

                                                            A resource which represents some error information.

                                                            +

                                                            The only method provided by this resource is to-debug-string, +which provides some human-readable information about the error.

                                                            +

                                                            In the wasi:io package, this resource is returned through the +wasi:io/streams/stream-error type.

                                                            +

                                                            To provide more specific error information, other interfaces may +provide functions to further "downcast" this error into more specific +error information. For example, errors returned in streams derived +from filesystem types to be described using the filesystem's own +error-code type, using the function +wasi:filesystem/types/filesystem-error-code, which takes a parameter +borrow<error> and returns +option<wasi:filesystem/types/error-code>.

                                                            +

                                                            The set of functions which can "downcast" an error into a more +concrete type is open.

                                                            Functions

                                                            [method]error.to-debug-string: func

                                                            Returns a string that is suitable to assist humans in debugging @@ -32,13 +46,13 @@ hazard.

                                                            • string
                                                            -

                                                            Import interface wasi:io/poll@0.2.0-rc-2023-11-10

                                                            +

                                                            Import interface wasi:io/poll@0.2.0

                                                            A poll API intended to let users wait for I/O events on multiple handles at once.


                                                            Types

                                                            resource pollable

                                                            -
                                                            +

                                                            pollable represents a single I/O event which may be ready, or not.

                                                            Functions

                                                            [method]pollable.ready: func

                                                            Return the readiness of a pollable. This function never blocks.

                                                            @@ -82,7 +96,7 @@ being reaedy for I/O.

                                                            • list<u32>
                                                            -

                                                            Import interface wasi:io/streams@0.2.0-rc-2023-11-10

                                                            +

                                                            Import interface wasi:io/streams@0.2.0

                                                            WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                                                            In the future, the component model is expected to add built-in stream types; @@ -112,11 +126,28 @@ future operations.

                                                          resource input-stream

                                                          +

                                                          An input bytestream.

                                                          +

                                                          input-streams are non-blocking to the extent practical on underlying +platforms. I/O operations always return promptly; if fewer bytes are +promptly available than requested, they return the number of bytes promptly +available, which could even be zero. To wait for data to be available, +use the subscribe function to obtain a pollable which can be polled +for using wasi:io/poll.

                                                          resource output-stream

                                                          -
                                                          +

                                                          An output bytestream.

                                                          +

                                                          output-streams are non-blocking to the extent practical on +underlying platforms. Except where specified otherwise, I/O operations also +always return promptly, after the number of bytes that can be written +promptly, which could even be zero. To wait for the stream to be ready to +accept data, the subscribe function to obtain a pollable which can be +polled for using wasi:io/poll.

                                                          Functions

                                                          [method]input-stream.read: func

                                                          Perform a non-blocking read from the stream.

                                                          +

                                                          When the source of a read is binary data, the bytes from the source +are returned verbatim. When the source of a read is known to the +implementation to be text, bytes containing the UTF-8 encoding of the +text are returned.

                                                          This function returns a list of bytes containing the read data, when successful. The returned list will contain up to len bytes; it may return fewer than requested, but not more. The list is @@ -212,6 +243,11 @@ error.

                                                        [method]output-stream.write: func

                                                        Perform a write. This function never blocks.

                                                        +

                                                        When the destination of a write is binary data, the bytes from +contents are written verbatim. When the destination of a write is +known to the implementation to be text, the bytes of contents are +transcoded from UTF-8 into the encoding of the destination and then +written.

                                                        Precondition: check-write gave permit of Ok(n) and contents has a length of less than or equal to n. Otherwise, this function will trap.

                                                        returns Err(closed) without writing if the stream has closed since @@ -234,7 +270,7 @@ following pseudo-code:

                                                        let pollable = this.subscribe();
                                                         while !contents.is_empty() {
                                                           // Wait for the stream to become writable
                                                        -  poll-one(pollable);
                                                        +  pollable.block();
                                                           let Ok(n) = this.check-write(); // eliding error handling
                                                           let len = min(n, contents.len());
                                                           let (chunk, rest) = contents.split_at(len);
                                                        @@ -243,7 +279,7 @@ while !contents.is_empty() {
                                                         }
                                                         this.flush();
                                                         // Wait for completion of `flush`
                                                        -poll-one(pollable);
                                                        +pollable.block();
                                                         // Check for any errors that arose during `flush`
                                                         let _ = this.check-write();         // eliding error handling
                                                         
                                                        @@ -303,7 +339,7 @@ all derived pollables created with this fun

                                                      [method]output-stream.write-zeroes: func

                                                      Write zeroes to a stream.

                                                      -

                                                      this should be used precisely like write with the exact same +

                                                      This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of passing a list of bytes, you simply pass the number of zero-bytes that should be written.

                                                      @@ -326,7 +362,7 @@ the following pseudo-code:

                                                      let pollable = this.subscribe();
                                                       while num_zeroes != 0 {
                                                         // Wait for the stream to become writable
                                                      -  poll-one(pollable);
                                                      +  pollable.block();
                                                         let Ok(n) = this.check-write(); // eliding error handling
                                                         let len = min(n, num_zeroes);
                                                         this.write-zeroes(len);         // eliding error handling
                                                      @@ -334,7 +370,7 @@ while num_zeroes != 0 {
                                                       }
                                                       this.flush();
                                                       // Wait for completion of `flush`
                                                      -poll-one(pollable);
                                                      +pollable.block();
                                                       // Check for any errors that arose during `flush`
                                                       let _ = this.check-write();         // eliding error handling
                                                       
                                                      @@ -385,7 +421,7 @@ is ready for reading, before performing the splice.

                                                      -

                                                      Import interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10

                                                      +

                                                      Import interface wasi:clocks/wall-clock@0.2.0

                                                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                                                      @@ -426,7 +462,7 @@ also known as Unix Time.
                                                    • datetime
                                                    -

                                                    Import interface wasi:filesystem/types@0.2.0-rc-2023-11-10

                                                    +

                                                    Import interface wasi:filesystem/types@0.2.0

                                                    WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                                                    @@ -856,8 +892,11 @@ not reuse it thereafter.

                                                  resource descriptor

                                                  +

                                                  A descriptor is a reference to a filesystem object, which may be a file, +directory, named pipe, special file, or other object on which filesystem +calls may be made.

                                                  resource directory-entry-stream

                                                  -
                                                  +

                                                  A stream of directory entries.

                                                  Functions

                                                  [method]descriptor.read-via-stream: func

                                                  Return a stream for reading from a file, if available.

                                                  @@ -1303,7 +1342,7 @@ errors are filesystem-related errors.

                                                  -

                                                  Import interface wasi:filesystem/preopens@0.2.0-rc-2023-11-10

                                                  +

                                                  Import interface wasi:filesystem/preopens@0.2.0


                                                  Types

                                                  type descriptor

                                                  From 4c6422ad6b44662cf8aff67e6fbc4b63e4f53998 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 11:59:36 -0800 Subject: [PATCH 1400/1772] copy in io and clocks deps at 0.2.0 --- .../wit/deps/clocks/monotonic-clock.wit | 4 ++-- .../sockets/wit/deps/clocks/wall-clock.wit | 2 +- proposals/sockets/wit/deps/clocks/world.wit | 2 +- proposals/sockets/wit/deps/io/error.wit | 2 +- proposals/sockets/wit/deps/io/poll.wit | 4 ++-- proposals/sockets/wit/deps/io/streams.wit | 23 ++++++++++++++----- proposals/sockets/wit/deps/io/world.wit | 2 +- 7 files changed, 25 insertions(+), 14 deletions(-) diff --git a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit index 09ef32c36..4e4dc3a19 100644 --- a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.0-rc-2023-11-10; /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:io/poll@0.2.0.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/sockets/wit/deps/clocks/wall-clock.wit b/proposals/sockets/wit/deps/clocks/wall-clock.wit index 8abb9a0c0..440ca0f33 100644 --- a/proposals/sockets/wit/deps/clocks/wall-clock.wit +++ b/proposals/sockets/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/sockets/wit/deps/clocks/world.wit b/proposals/sockets/wit/deps/clocks/world.wit index 8fa080f0e..c0224572a 100644 --- a/proposals/sockets/wit/deps/clocks/world.wit +++ b/proposals/sockets/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; world imports { import monotonic-clock; diff --git a/proposals/sockets/wit/deps/io/error.wit b/proposals/sockets/wit/deps/io/error.wit index 31918acbb..22e5b6489 100644 --- a/proposals/sockets/wit/deps/io/error.wit +++ b/proposals/sockets/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; interface error { diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit index bddde3c19..ddc67f8b7 100644 --- a/proposals/sockets/wit/deps/io/poll.wit +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -1,9 +1,9 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { - /// `pollable` epresents a single I/O event which may be ready, or not. + /// `pollable` represents a single I/O event which may be ready, or not. resource pollable { /// Return the readiness of a pollable. This function never blocks. diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index e7e1b689a..6d2f871e3 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -32,6 +32,11 @@ interface streams { resource input-stream { /// Perform a non-blocking read from the stream. /// + /// When the source of a `read` is binary data, the bytes from the source + /// are returned verbatim. When the source of a `read` is known to the + /// implementation to be text, bytes containing the UTF-8 encoding of the + /// text are returned. + /// /// This function returns a list of bytes containing the read data, /// when successful. The returned list will contain up to `len` bytes; /// it may return fewer than requested, but not more. The list is @@ -111,6 +116,12 @@ interface streams { /// Perform a write. This function never blocks. /// + /// When the destination of a `write` is binary data, the bytes from + /// `contents` are written verbatim. When the destination of a `write` is + /// known to the implementation to be text, the bytes of `contents` are + /// transcoded from UTF-8 into the encoding of the destination and then + /// written. + /// /// Precondition: check-write gave permit of Ok(n) and contents has a /// length of less than or equal to n. Otherwise, this function will trap. /// @@ -131,7 +142,7 @@ interface streams { /// let pollable = this.subscribe(); /// while !contents.is_empty() { /// // Wait for the stream to become writable - /// poll-one(pollable); + /// pollable.block(); /// let Ok(n) = this.check-write(); // eliding error handling /// let len = min(n, contents.len()); /// let (chunk, rest) = contents.split_at(len); @@ -140,7 +151,7 @@ interface streams { /// } /// this.flush(); /// // Wait for completion of `flush` - /// poll-one(pollable); + /// pollable.block(); /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` @@ -178,7 +189,7 @@ interface streams { /// Write zeroes to a stream. /// - /// this should be used precisely like `write` with the exact same + /// This should be used precisely like `write` with the exact same /// preconditions (must use check-write first), but instead of /// passing a list of bytes, you simply pass the number of zero-bytes /// that should be written. @@ -199,7 +210,7 @@ interface streams { /// let pollable = this.subscribe(); /// while num_zeroes != 0 { /// // Wait for the stream to become writable - /// poll-one(pollable); + /// pollable.block(); /// let Ok(n) = this.check-write(); // eliding error handling /// let len = min(n, num_zeroes); /// this.write-zeroes(len); // eliding error handling @@ -207,7 +218,7 @@ interface streams { /// } /// this.flush(); /// // Wait for completion of `flush` - /// poll-one(pollable); + /// pollable.block(); /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit index 8243da2ee..5f0b43fe5 100644 --- a/proposals/sockets/wit/deps/io/world.wit +++ b/proposals/sockets/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; world imports { import streams; From 03a6e09599e526f30eba602ad9d364014a7eb70f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 12:00:51 -0800 Subject: [PATCH 1401/1772] update uses of io and clocks to @0.2.0 --- proposals/sockets/wit/ip-name-lookup.wit | 2 +- proposals/sockets/wit/tcp.wit | 6 +++--- proposals/sockets/wit/udp.wit | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index 931ccf7e0..8e639ec59 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,6 +1,6 @@ interface ip-name-lookup { - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:io/poll@0.2.0.{pollable}; use network.{network, error-code, ip-address}; diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 9f12b8212..5902b9ee0 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,8 +1,8 @@ interface tcp { - use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream}; - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; - use wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10.{duration}; + use wasi:io/streams@0.2.0.{input-stream, output-stream}; + use wasi:io/poll@0.2.0.{pollable}; + use wasi:clocks/monotonic-clock@0.2.0.{duration}; use network.{network, error-code, ip-socket-address, ip-address-family}; enum shutdown-type { diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 6ba380ff7..d987a0a90 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,6 +1,6 @@ interface udp { - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:io/poll@0.2.0.{pollable}; use network.{network, error-code, ip-socket-address, ip-address-family}; /// A received datagram. From 059c2907ae4965309184338a3eef39e473e81ac1 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 12:01:10 -0800 Subject: [PATCH 1402/1772] set wasi:sockets package version to 0.2.0 --- proposals/sockets/wit/world.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index 8588cc6c1..f8bb92ae0 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.0-rc-2024-01-16; +package wasi:sockets@0.2.0; world imports { import instance-network; From dc7d002fab5aeeccb9789c36d71ea0ab4e6e0ef1 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 12:01:28 -0800 Subject: [PATCH 1403/1772] update markdown --- proposals/sockets/imports.md | 65 ++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 8f73f27f2..45ff95366 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -2,21 +2,21 @@ -

                                                  Import interface wasi:sockets/network@0.2.0-rc-2024-01-16

                                                  +

                                                  Import interface wasi:sockets/network@0.2.0


                                                  Types

                                                  resource network

                                                  @@ -209,7 +209,7 @@ supported size.
                                                • ipv4: ipv4-socket-address
                                                • ipv6: ipv6-socket-address
                                                -

                                                Import interface wasi:sockets/instance-network@0.2.0-rc-2024-01-16

                                                +

                                                Import interface wasi:sockets/instance-network@0.2.0

                                                This interface provides a value-export of the default network handle..


                                                Types

                                                @@ -224,13 +224,13 @@ supported size. -

                                                Import interface wasi:io/poll@0.2.0-rc-2023-11-10

                                                +

                                                Import interface wasi:io/poll@0.2.0

                                                A poll API intended to let users wait for I/O events on multiple handles at once.


                                                Types

                                                resource pollable

                                                -

                                                pollable epresents a single I/O event which may be ready, or not.

                                                +

                                                pollable represents a single I/O event which may be ready, or not.

                                                Functions

                                                [method]pollable.ready: func

                                                Return the readiness of a pollable. This function never blocks.

                                                @@ -274,7 +274,7 @@ being reaedy for I/O.

                                                • list<u32>
                                                -

                                                Import interface wasi:sockets/udp@0.2.0-rc-2024-01-16

                                                +

                                                Import interface wasi:sockets/udp@0.2.0


                                                Types

                                                type pollable

                                                @@ -688,7 +688,7 @@ It's planned to be removed when future is natively supported in Pre -

                                                Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2024-01-16

                                                +

                                                Import interface wasi:sockets/udp-create-socket@0.2.0


                                                Types

                                                type network

                                                @@ -733,7 +733,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                                                Import interface wasi:io/error@0.2.0-rc-2023-11-10

                                                +

                                                Import interface wasi:io/error@0.2.0


                                                Types

                                                resource error

                                                @@ -768,7 +768,7 @@ hazard.

                                                • string
                                                -

                                                Import interface wasi:io/streams@0.2.0-rc-2023-11-10

                                                +

                                                Import interface wasi:io/streams@0.2.0

                                                WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                                                In the future, the component model is expected to add built-in stream types; @@ -816,6 +816,10 @@ polled for using wasi:io/poll.

    Functions

    [method]input-stream.read: func

    Perform a non-blocking read from the stream.

    +

    When the source of a read is binary data, the bytes from the source +are returned verbatim. When the source of a read is known to the +implementation to be text, bytes containing the UTF-8 encoding of the +text are returned.

    This function returns a list of bytes containing the read data, when successful. The returned list will contain up to len bytes; it may return fewer than requested, but not more. The list is @@ -911,6 +915,11 @@ error.

    [method]output-stream.write: func

    Perform a write. This function never blocks.

    +

    When the destination of a write is binary data, the bytes from +contents are written verbatim. When the destination of a write is +known to the implementation to be text, the bytes of contents are +transcoded from UTF-8 into the encoding of the destination and then +written.

    Precondition: check-write gave permit of Ok(n) and contents has a length of less than or equal to n. Otherwise, this function will trap.

    returns Err(closed) without writing if the stream has closed since @@ -933,7 +942,7 @@ following pseudo-code:

    let pollable = this.subscribe();
     while !contents.is_empty() {
       // Wait for the stream to become writable
    -  poll-one(pollable);
    +  pollable.block();
       let Ok(n) = this.check-write(); // eliding error handling
       let len = min(n, contents.len());
       let (chunk, rest) = contents.split_at(len);
    @@ -942,7 +951,7 @@ while !contents.is_empty() {
     }
     this.flush();
     // Wait for completion of `flush`
    -poll-one(pollable);
    +pollable.block();
     // Check for any errors that arose during `flush`
     let _ = this.check-write();         // eliding error handling
     
    @@ -1002,7 +1011,7 @@ all derived pollables created with this fun

    [method]output-stream.write-zeroes: func

    Write zeroes to a stream.

    -

    this should be used precisely like write with the exact same +

    This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of passing a list of bytes, you simply pass the number of zero-bytes that should be written.

    @@ -1025,7 +1034,7 @@ the following pseudo-code:

    let pollable = this.subscribe();
     while num_zeroes != 0 {
       // Wait for the stream to become writable
    -  poll-one(pollable);
    +  pollable.block();
       let Ok(n) = this.check-write(); // eliding error handling
       let len = min(n, num_zeroes);
       this.write-zeroes(len);         // eliding error handling
    @@ -1033,7 +1042,7 @@ while num_zeroes != 0 {
     }
     this.flush();
     // Wait for completion of `flush`
    -poll-one(pollable);
    +pollable.block();
     // Check for any errors that arose during `flush`
     let _ = this.check-write();         // eliding error handling
     
    @@ -1084,7 +1093,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

    +

    Import interface wasi:clocks/monotonic-clock@0.2.0

    WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

    It is intended to be portable at least between Unix-family platforms and @@ -1145,7 +1154,7 @@ occured.

    -

    Import interface wasi:sockets/tcp@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/tcp@0.2.0


    Types

    type input-stream

    @@ -1736,7 +1745,7 @@ has no effect and returns ok.

    -

    Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/tcp-create-socket@0.2.0


    Types

    type network

    @@ -1781,7 +1790,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

    Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/ip-name-lookup@0.2.0


    Types

    type pollable

    From a5bebb4ce018ecc92f37d136bf7179a5325ce5c2 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 12:19:06 -0800 Subject: [PATCH 1404/1772] copy in wasi-cli, clocks, filesystem, io, random, and sockets at 0.2.0 --- proposals/http/wit/deps/cli/command.wit | 2 +- proposals/http/wit/deps/cli/imports.wit | 12 ++++++------ proposals/http/wit/deps/cli/stdio.wit | 6 +++--- proposals/http/wit/deps/clocks/monotonic-clock.wit | 4 ++-- proposals/http/wit/deps/clocks/wall-clock.wit | 2 +- proposals/http/wit/deps/clocks/world.wit | 2 +- proposals/http/wit/deps/filesystem/preopens.wit | 2 +- proposals/http/wit/deps/filesystem/types.wit | 6 +++--- proposals/http/wit/deps/filesystem/world.wit | 2 +- proposals/http/wit/deps/io/error.wit | 2 +- proposals/http/wit/deps/io/poll.wit | 2 +- proposals/http/wit/deps/io/streams.wit | 2 +- proposals/http/wit/deps/io/world.wit | 2 +- proposals/http/wit/deps/random/insecure-seed.wit | 2 +- proposals/http/wit/deps/random/insecure.wit | 2 +- proposals/http/wit/deps/random/random.wit | 2 +- proposals/http/wit/deps/random/world.wit | 2 +- proposals/http/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/http/wit/deps/sockets/tcp.wit | 6 +++--- proposals/http/wit/deps/sockets/udp.wit | 2 +- proposals/http/wit/deps/sockets/world.wit | 2 +- 21 files changed, 33 insertions(+), 33 deletions(-) diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit index a9889164f..d8005bd38 100644 --- a/proposals/http/wit/deps/cli/command.wit +++ b/proposals/http/wit/deps/cli/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.0-rc-2024-01-16; +package wasi:cli@0.2.0; world command { include imports; diff --git a/proposals/http/wit/deps/cli/imports.wit b/proposals/http/wit/deps/cli/imports.wit index 8ce1abec3..083b84a03 100644 --- a/proposals/http/wit/deps/cli/imports.wit +++ b/proposals/http/wit/deps/cli/imports.wit @@ -1,11 +1,11 @@ -package wasi:cli@0.2.0-rc-2024-01-16; +package wasi:cli@0.2.0; world imports { - include wasi:clocks/imports@0.2.0-rc-2023-11-10; - include wasi:filesystem/imports@0.2.0-rc-2023-11-10; - include wasi:sockets/imports@0.2.0-rc-2024-01-16; - include wasi:random/imports@0.2.0-rc-2023-11-10; - include wasi:io/imports@0.2.0-rc-2023-11-10; + include wasi:clocks/imports@0.2.0; + include wasi:filesystem/imports@0.2.0; + include wasi:sockets/imports@0.2.0; + include wasi:random/imports@0.2.0; + include wasi:io/imports@0.2.0; import environment; import exit; diff --git a/proposals/http/wit/deps/cli/stdio.wit b/proposals/http/wit/deps/cli/stdio.wit index 1b653b6e2..31ef35b5a 100644 --- a/proposals/http/wit/deps/cli/stdio.wit +++ b/proposals/http/wit/deps/cli/stdio.wit @@ -1,17 +1,17 @@ interface stdin { - use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream}; + use wasi:io/streams@0.2.0.{input-stream}; get-stdin: func() -> input-stream; } interface stdout { - use wasi:io/streams@0.2.0-rc-2023-11-10.{output-stream}; + use wasi:io/streams@0.2.0.{output-stream}; get-stdout: func() -> output-stream; } interface stderr { - use wasi:io/streams@0.2.0-rc-2023-11-10.{output-stream}; + use wasi:io/streams@0.2.0.{output-stream}; get-stderr: func() -> output-stream; } diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index 09ef32c36..4e4dc3a19 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.0-rc-2023-11-10; /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:io/poll@0.2.0.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/http/wit/deps/clocks/wall-clock.wit b/proposals/http/wit/deps/clocks/wall-clock.wit index 8abb9a0c0..440ca0f33 100644 --- a/proposals/http/wit/deps/clocks/wall-clock.wit +++ b/proposals/http/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/http/wit/deps/clocks/world.wit b/proposals/http/wit/deps/clocks/world.wit index 8fa080f0e..c0224572a 100644 --- a/proposals/http/wit/deps/clocks/world.wit +++ b/proposals/http/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; world imports { import monotonic-clock; diff --git a/proposals/http/wit/deps/filesystem/preopens.wit b/proposals/http/wit/deps/filesystem/preopens.wit index 95ec67843..da801f6d6 100644 --- a/proposals/http/wit/deps/filesystem/preopens.wit +++ b/proposals/http/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0-rc-2023-11-10; +package wasi:filesystem@0.2.0; interface preopens { use types.{descriptor}; diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index 059722ab8..11108fcda 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0-rc-2023-11-10; +package wasi:filesystem@0.2.0; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -24,8 +24,8 @@ package wasi:filesystem@0.2.0-rc-2023-11-10; /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { - use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream, error}; - use wasi:clocks/wall-clock@0.2.0-rc-2023-11-10.{datetime}; + use wasi:io/streams@0.2.0.{input-stream, output-stream, error}; + use wasi:clocks/wall-clock@0.2.0.{datetime}; /// File size or length of a region within a file. type filesize = u64; diff --git a/proposals/http/wit/deps/filesystem/world.wit b/proposals/http/wit/deps/filesystem/world.wit index 285e0bae9..663f57920 100644 --- a/proposals/http/wit/deps/filesystem/world.wit +++ b/proposals/http/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0-rc-2023-11-10; +package wasi:filesystem@0.2.0; world imports { import types; diff --git a/proposals/http/wit/deps/io/error.wit b/proposals/http/wit/deps/io/error.wit index 31918acbb..22e5b6489 100644 --- a/proposals/http/wit/deps/io/error.wit +++ b/proposals/http/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; interface error { diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/io/poll.wit index 81b1cab99..ddc67f8b7 100644 --- a/proposals/http/wit/deps/io/poll.wit +++ b/proposals/http/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index 82e6e073e..6d2f871e3 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit index 8243da2ee..5f0b43fe5 100644 --- a/proposals/http/wit/deps/io/world.wit +++ b/proposals/http/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; world imports { import streams; diff --git a/proposals/http/wit/deps/random/insecure-seed.wit b/proposals/http/wit/deps/random/insecure-seed.wit index f76e87dad..47210ac6b 100644 --- a/proposals/http/wit/deps/random/insecure-seed.wit +++ b/proposals/http/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0-rc-2023-11-10; +package wasi:random@0.2.0; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/insecure.wit b/proposals/http/wit/deps/random/insecure.wit index ec7b99737..c58f4ee85 100644 --- a/proposals/http/wit/deps/random/insecure.wit +++ b/proposals/http/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0-rc-2023-11-10; +package wasi:random@0.2.0; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index 7a7dfa27a..0c017f093 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0-rc-2023-11-10; +package wasi:random@0.2.0; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit index 49e5743b4..3da34914a 100644 --- a/proposals/http/wit/deps/random/world.wit +++ b/proposals/http/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0-rc-2023-11-10; +package wasi:random@0.2.0; world imports { import random; diff --git a/proposals/http/wit/deps/sockets/ip-name-lookup.wit b/proposals/http/wit/deps/sockets/ip-name-lookup.wit index 931ccf7e0..8e639ec59 100644 --- a/proposals/http/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit/deps/sockets/ip-name-lookup.wit @@ -1,6 +1,6 @@ interface ip-name-lookup { - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:io/poll@0.2.0.{pollable}; use network.{network, error-code, ip-address}; diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index 9f12b8212..5902b9ee0 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -1,8 +1,8 @@ interface tcp { - use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream}; - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; - use wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10.{duration}; + use wasi:io/streams@0.2.0.{input-stream, output-stream}; + use wasi:io/poll@0.2.0.{pollable}; + use wasi:clocks/monotonic-clock@0.2.0.{duration}; use network.{network, error-code, ip-socket-address, ip-address-family}; enum shutdown-type { diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index 6ba380ff7..d987a0a90 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -1,6 +1,6 @@ interface udp { - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:io/poll@0.2.0.{pollable}; use network.{network, error-code, ip-socket-address, ip-address-family}; /// A received datagram. diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit index 8588cc6c1..f8bb92ae0 100644 --- a/proposals/http/wit/deps/sockets/world.wit +++ b/proposals/http/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.0-rc-2024-01-16; +package wasi:sockets@0.2.0; world imports { import instance-network; From 310aa3546cff86f048798f1f63cf74007b1d50c4 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 12:19:59 -0800 Subject: [PATCH 1405/1772] update uses of io, clocks, random, and cli to @0.2.0 --- proposals/http/wit/proxy.wit | 10 +++++----- proposals/http/wit/types.wit | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 2b0ce4b8a..77b2601d1 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -6,19 +6,19 @@ package wasi:http@0.2.0-rc-2024-01-16; /// outgoing HTTP requests. world proxy { /// HTTP proxies have access to time and randomness. - include wasi:clocks/imports@0.2.0-rc-2023-11-10; - import wasi:random/random@0.2.0-rc-2023-11-10; + include wasi:clocks/imports@0.2.0; + import wasi:random/random@0.2.0; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.2.0-rc-2024-01-16; - import wasi:cli/stderr@0.2.0-rc-2024-01-16; + import wasi:cli/stdout@0.2.0; + import wasi:cli/stderr@0.2.0; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. - import wasi:cli/stdin@0.2.0-rc-2024-01-16; + import wasi:cli/stdin@0.2.0; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 0f698e769..755ac6a6b 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -2,10 +2,10 @@ /// HTTP Requests and Responses, both incoming and outgoing, as well as /// their headers, trailers, and bodies. interface types { - use wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10.{duration}; - use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream}; - use wasi:io/error@0.2.0-rc-2023-11-10.{error as io-error}; - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:clocks/monotonic-clock@0.2.0.{duration}; + use wasi:io/streams@0.2.0.{input-stream, output-stream}; + use wasi:io/error@0.2.0.{error as io-error}; + use wasi:io/poll@0.2.0.{pollable}; /// This type corresponds to HTTP standard Methods. variant method { From 64fa440747a0990276c292be559e3f526b9c5c0f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 12:21:07 -0800 Subject: [PATCH 1406/1772] set wasi:http package version to 0.2.0 --- proposals/http/wit/proxy.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 77b2601d1..687c24d23 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,4 +1,4 @@ -package wasi:http@0.2.0-rc-2024-01-16; +package wasi:http@0.2.0; /// The `wasi:http/proxy` world captures a widely-implementable intersection of /// hosts that includes HTTP forward and reverse proxies. Components targeting From 74970c08b0894e5e73449b857e6a3c966bbd0213 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 12:24:49 -0800 Subject: [PATCH 1407/1772] generate markdown --- proposals/http/proxy.md | 48 ++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 7781e3b3b..5a249a419 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -6,26 +6,26 @@ outgoing HTTP requests.

    -

    Import interface wasi:random/random@0.2.0-rc-2023-11-10

    +

    Import interface wasi:random/random@0.2.0

    WASI Random is a random data API.

    It is intended to be portable at least between Unix-family platforms and Windows.

    @@ -58,7 +58,7 @@ represented as a u64.

    • u64
    -

    Import interface wasi:io/error@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/error@0.2.0


    Types

    resource error

    @@ -93,7 +93,7 @@ hazard.

    • string
    -

    Import interface wasi:io/poll@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/poll@0.2.0

    A poll API intended to let users wait for I/O events on multiple handles at once.


    @@ -143,7 +143,7 @@ being reaedy for I/O.

    • list<u32>
    -

    Import interface wasi:io/streams@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/streams@0.2.0

    WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

    In the future, the component model is expected to add built-in stream types; @@ -468,7 +468,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stdout@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/stdout@0.2.0


    Types

    type output-stream

    @@ -481,7 +481,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stderr@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/stderr@0.2.0


    Types

    type output-stream

    @@ -494,7 +494,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stdin@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/stdin@0.2.0


    Types

    type input-stream

    @@ -507,7 +507,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

    +

    Import interface wasi:clocks/monotonic-clock@0.2.0

    WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

    It is intended to be portable at least between Unix-family platforms and @@ -568,7 +568,7 @@ occured.

    -

    Import interface wasi:http/types@0.2.0-rc-2024-01-16

    +

    Import interface wasi:http/types@0.2.0

    This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

    @@ -1454,7 +1454,7 @@ but those will be reported by the incoming-body
  • option<result<result<own<incoming-response>, error-code>>>
  • -

    Import interface wasi:http/outgoing-handler@0.2.0-rc-2024-01-16

    +

    Import interface wasi:http/outgoing-handler@0.2.0

    This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


    @@ -1491,7 +1491,7 @@ through the future-incoming-response
  • result<own<future-incoming-response>, error-code>
  • -

    Import interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10

    +

    Import interface wasi:clocks/wall-clock@0.2.0

    WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

    @@ -1532,7 +1532,7 @@ also known as Unix Time.
  • datetime
  • -

    Export interface wasi:http/incoming-handler@0.2.0-rc-2024-01-16

    +

    Export interface wasi:http/incoming-handler@0.2.0


    Types

    type incoming-request

    From 9c5938634ec1e415a0062e0a429ebf73af5180af Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 10:44:26 -0800 Subject: [PATCH 1408/1772] set wasi:io package version to 0.2.0 --- proposals/io/wit/error.wit | 2 +- proposals/io/wit/poll.wit | 2 +- proposals/io/wit/streams.wit | 2 +- proposals/io/wit/world.wit | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/io/wit/error.wit b/proposals/io/wit/error.wit index 31918acbb..22e5b6489 100644 --- a/proposals/io/wit/error.wit +++ b/proposals/io/wit/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; interface error { diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index 81b1cab99..ddc67f8b7 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index 82e6e073e..6d2f871e3 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index 8243da2ee..5f0b43fe5 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; world imports { import streams; From c0123ef58226e5ff8ba7e21f5716ff6ce9f61b20 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 10:45:31 -0800 Subject: [PATCH 1409/1772] generate markdown --- proposals/io/imports.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index 0d295ccb2..1ae5b12e8 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -2,13 +2,13 @@ -

    Import interface wasi:io/error@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/error@0.2.0


    Types

    resource error

    @@ -43,7 +43,7 @@ hazard.

    • string
    -

    Import interface wasi:io/poll@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/poll@0.2.0

    A poll API intended to let users wait for I/O events on multiple handles at once.


    @@ -93,7 +93,7 @@ being reaedy for I/O.

    • list<u32>
    -

    Import interface wasi:io/streams@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/streams@0.2.0

    WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

    In the future, the component model is expected to add built-in stream types; From 640aa30fd218e675ee653d098648b9b1451f68fc Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 10:47:24 -0800 Subject: [PATCH 1410/1772] set wasi:random package version to 0.2.0 --- proposals/random/wit/insecure-seed.wit | 2 +- proposals/random/wit/insecure.wit | 2 +- proposals/random/wit/random.wit | 2 +- proposals/random/wit/world.wit | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index f76e87dad..47210ac6b 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0-rc-2023-11-10; +package wasi:random@0.2.0; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index ec7b99737..c58f4ee85 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0-rc-2023-11-10; +package wasi:random@0.2.0; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 7a7dfa27a..0c017f093 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0-rc-2023-11-10; +package wasi:random@0.2.0; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index 49e5743b4..3da34914a 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0-rc-2023-11-10; +package wasi:random@0.2.0; world imports { import random; From ce5caec5e8f5e8c4b4801ee7301e3e2acc4dfd7f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 10:47:34 -0800 Subject: [PATCH 1411/1772] generate markdown --- proposals/random/imports.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/random/imports.md b/proposals/random/imports.md index 4bd886c5d..4da4585dc 100644 --- a/proposals/random/imports.md +++ b/proposals/random/imports.md @@ -2,13 +2,13 @@

    -

    Import interface wasi:random/random@0.2.0-rc-2023-11-10

    +

    Import interface wasi:random/random@0.2.0

    WASI Random is a random data API.

    It is intended to be portable at least between Unix-family platforms and Windows.

    @@ -41,7 +41,7 @@ represented as a u64.

    • u64
    -

    Import interface wasi:random/insecure@0.2.0-rc-2023-11-10

    +

    Import interface wasi:random/insecure@0.2.0

    The insecure interface for insecure pseudo-random numbers.

    It is intended to be portable at least between Unix-family platforms and Windows.

    @@ -70,7 +70,7 @@ a long period.

    • u64
    -

    Import interface wasi:random/insecure-seed@0.2.0-rc-2023-11-10

    +

    Import interface wasi:random/insecure-seed@0.2.0

    The insecure-seed interface for seeding hash-map DoS resistance.

    It is intended to be portable at least between Unix-family platforms and Windows.

    From 315ab5d177388de971ea7d7dc4613af53249f247 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 25 Jan 2024 10:59:48 -0800 Subject: [PATCH 1412/1772] CI: use wit-abi-up-to-date@v17 --- proposals/filesystem/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index af3c079b1..5ca5ba1fa 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -18,4 +18,4 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v16 + - uses: WebAssembly/wit-abi-up-to-date@v17 From c1b81ae11bf626c8584454926f99c0d700a5c394 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 25 Jan 2024 11:02:37 -0800 Subject: [PATCH 1413/1772] CI: use wit-abi-up-to-date@v17 --- proposals/http/.github/workflows/main.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index ed406c5c4..c5740dc1c 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -16,6 +16,4 @@ jobs: curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.2/wit-deps-x86_64-unknown-linux-musl chmod +x ./wit-deps ./wit-deps lock --check - - uses: WebAssembly/wit-abi-up-to-date@v16 - with: - wit-bindgen: '0.15.0' + - uses: WebAssembly/wit-abi-up-to-date@v17 From 2440778620e35743bcf9c9d90fc52b3a59588fb5 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 10:48:52 -0800 Subject: [PATCH 1414/1772] wasi-io dep: updated to 0.2.0 this is copied in manually, not using wit-deps, because wasi:io's change hasnt merged to main yet. --- proposals/clocks/wit/deps/io/error.wit | 2 +- proposals/clocks/wit/deps/io/poll.wit | 4 ++-- proposals/clocks/wit/deps/io/streams.wit | 23 +++++++++++++++++------ proposals/clocks/wit/deps/io/world.wit | 2 +- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/proposals/clocks/wit/deps/io/error.wit b/proposals/clocks/wit/deps/io/error.wit index 31918acbb..22e5b6489 100644 --- a/proposals/clocks/wit/deps/io/error.wit +++ b/proposals/clocks/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; interface error { diff --git a/proposals/clocks/wit/deps/io/poll.wit b/proposals/clocks/wit/deps/io/poll.wit index bddde3c19..ddc67f8b7 100644 --- a/proposals/clocks/wit/deps/io/poll.wit +++ b/proposals/clocks/wit/deps/io/poll.wit @@ -1,9 +1,9 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. interface poll { - /// `pollable` epresents a single I/O event which may be ready, or not. + /// `pollable` represents a single I/O event which may be ready, or not. resource pollable { /// Return the readiness of a pollable. This function never blocks. diff --git a/proposals/clocks/wit/deps/io/streams.wit b/proposals/clocks/wit/deps/io/streams.wit index e7e1b689a..6d2f871e3 100644 --- a/proposals/clocks/wit/deps/io/streams.wit +++ b/proposals/clocks/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -32,6 +32,11 @@ interface streams { resource input-stream { /// Perform a non-blocking read from the stream. /// + /// When the source of a `read` is binary data, the bytes from the source + /// are returned verbatim. When the source of a `read` is known to the + /// implementation to be text, bytes containing the UTF-8 encoding of the + /// text are returned. + /// /// This function returns a list of bytes containing the read data, /// when successful. The returned list will contain up to `len` bytes; /// it may return fewer than requested, but not more. The list is @@ -111,6 +116,12 @@ interface streams { /// Perform a write. This function never blocks. /// + /// When the destination of a `write` is binary data, the bytes from + /// `contents` are written verbatim. When the destination of a `write` is + /// known to the implementation to be text, the bytes of `contents` are + /// transcoded from UTF-8 into the encoding of the destination and then + /// written. + /// /// Precondition: check-write gave permit of Ok(n) and contents has a /// length of less than or equal to n. Otherwise, this function will trap. /// @@ -131,7 +142,7 @@ interface streams { /// let pollable = this.subscribe(); /// while !contents.is_empty() { /// // Wait for the stream to become writable - /// poll-one(pollable); + /// pollable.block(); /// let Ok(n) = this.check-write(); // eliding error handling /// let len = min(n, contents.len()); /// let (chunk, rest) = contents.split_at(len); @@ -140,7 +151,7 @@ interface streams { /// } /// this.flush(); /// // Wait for completion of `flush` - /// poll-one(pollable); + /// pollable.block(); /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` @@ -178,7 +189,7 @@ interface streams { /// Write zeroes to a stream. /// - /// this should be used precisely like `write` with the exact same + /// This should be used precisely like `write` with the exact same /// preconditions (must use check-write first), but instead of /// passing a list of bytes, you simply pass the number of zero-bytes /// that should be written. @@ -199,7 +210,7 @@ interface streams { /// let pollable = this.subscribe(); /// while num_zeroes != 0 { /// // Wait for the stream to become writable - /// poll-one(pollable); + /// pollable.block(); /// let Ok(n) = this.check-write(); // eliding error handling /// let len = min(n, num_zeroes); /// this.write-zeroes(len); // eliding error handling @@ -207,7 +218,7 @@ interface streams { /// } /// this.flush(); /// // Wait for completion of `flush` - /// poll-one(pollable); + /// pollable.block(); /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` diff --git a/proposals/clocks/wit/deps/io/world.wit b/proposals/clocks/wit/deps/io/world.wit index 8243da2ee..5f0b43fe5 100644 --- a/proposals/clocks/wit/deps/io/world.wit +++ b/proposals/clocks/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; world imports { import streams; From aa5af314ca097b11059cde70a645efdb0765b323 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 10:50:22 -0800 Subject: [PATCH 1415/1772] use wasi:io at 0.2.0 --- proposals/clocks/wit/monotonic-clock.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index 09ef32c36..975aa273f 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -10,7 +10,7 @@ package wasi:clocks@0.2.0-rc-2023-11-10; /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:io/poll@0.2.0.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from From 397eb44743eee305b9ab39d9dda74628d8315b94 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 10:50:37 -0800 Subject: [PATCH 1416/1772] set wasi:clocks package version to 0.2.0 --- proposals/clocks/wit/monotonic-clock.wit | 2 +- proposals/clocks/wit/wall-clock.wit | 2 +- proposals/clocks/wit/world.wit | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index 975aa273f..4e4dc3a19 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// diff --git a/proposals/clocks/wit/wall-clock.wit b/proposals/clocks/wit/wall-clock.wit index 8abb9a0c0..440ca0f33 100644 --- a/proposals/clocks/wit/wall-clock.wit +++ b/proposals/clocks/wit/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index 8fa080f0e..c0224572a 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; world imports { import monotonic-clock; From 2e55244e321c2ee0d36fa191f548c5528270a4f9 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 24 Jan 2024 10:50:51 -0800 Subject: [PATCH 1417/1772] generate markdown --- proposals/clocks/imports.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index 54b0ed639..7857ce6ef 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -2,19 +2,19 @@ -

    Import interface wasi:io/poll@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/poll@0.2.0

    A poll API intended to let users wait for I/O events on multiple handles at once.


    Types

    resource pollable

    -
    +

    pollable represents a single I/O event which may be ready, or not.

    Functions

    [method]pollable.ready: func

    Return the readiness of a pollable. This function never blocks.

    @@ -58,7 +58,7 @@ being reaedy for I/O.

    • list<u32>
    -

    Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

    +

    Import interface wasi:clocks/monotonic-clock@0.2.0

    WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

    It is intended to be portable at least between Unix-family platforms and @@ -119,7 +119,7 @@ occured.

    -

    Import interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10

    +

    Import interface wasi:clocks/wall-clock@0.2.0

    WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

    From 19aeb72169b407a94cfb1909c50bd58ff2279a81 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 25 Jan 2024 10:55:45 -0800 Subject: [PATCH 1418/1772] wit-deps update: only changes to lockfile! --- proposals/clocks/wit/deps.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/wit/deps.lock b/proposals/clocks/wit/deps.lock index 48ee47f75..a1d7a278a 100644 --- a/proposals/clocks/wit/deps.lock +++ b/proposals/clocks/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "f2e6127b235c37c06be675a904d6acf08db953ea688d78c42892c6ad3bd194e4" -sha512 = "32feefbc115c34bf6968cb6e9dc15e755698ee90648e5a5d84448917c36a318bd61b401195eb64330e2475e1d098bfb8dee1440d594a68e0797748762bd84ae5" +sha256 = "7210e5653539a15478f894d4da24cc69d61924cbcba21d2804d69314a88e5a4c" +sha512 = "49184a1b0945a889abd52d25271172ed3dc2db6968fcdddb1bab7ee0081f4a3eeee0977ad2291126a37631c0d86eeea75d822fa8af224c422134500bf9f0f2bb" From 1f7e8260aefd79d0db1009bb865769c9dfc762eb Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 25 Jan 2024 10:59:03 -0800 Subject: [PATCH 1419/1772] CI: wit-abi-up-to-date@v17 --- proposals/clocks/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index af3c079b1..5ca5ba1fa 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -18,4 +18,4 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v16 + - uses: WebAssembly/wit-abi-up-to-date@v17 From 05e3fe7ae91f96caf7eb61e8fdc4d7e9346989b8 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 25 Jan 2024 14:03:37 -0500 Subject: [PATCH 1420/1772] chore: bump wit-abi-up-to-date (#41) --- proposals/random/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index b45623289..0df64e9ce 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -11,4 +11,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: WebAssembly/wit-abi-up-to-date@v16 + - uses: WebAssembly/wit-abi-up-to-date@v17 From 51e5f93ba60836ee4e13c225d1eb23cac5b59d7a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 25 Jan 2024 11:03:54 -0800 Subject: [PATCH 1421/1772] wit-deps update: just lockfile changes --- proposals/filesystem/wit/deps.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index be53c765e..64c71e7df 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "89da8eca4cd195516574c89c5b3c24a7b5af3ff2565c16753d20d3bdbc5fc60f" -sha512 = "244079b3f592d58478a97adbd0bee8d49ae9dd1a3e435651ee40997b50da9fe62cfaba7e3ec7f7406d7d0288d278a43a3a0bc5150226ba40ce0f8ac6d33f7ddb" +sha256 = "468b4d12892fe926b8eb5d398dbf579d566c93231fa44f415440572c695b7613" +sha512 = "e6b53a07221f1413953c9797c68f08b815fdaebf66419bbc1ea3e8b7dece73731062693634731f311a03957b268cf9cc509c518bd15e513c318aa04a8459b93a" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "f2e6127b235c37c06be675a904d6acf08db953ea688d78c42892c6ad3bd194e4" -sha512 = "32feefbc115c34bf6968cb6e9dc15e755698ee90648e5a5d84448917c36a318bd61b401195eb64330e2475e1d098bfb8dee1440d594a68e0797748762bd84ae5" +sha256 = "7210e5653539a15478f894d4da24cc69d61924cbcba21d2804d69314a88e5a4c" +sha512 = "49184a1b0945a889abd52d25271172ed3dc2db6968fcdddb1bab7ee0081f4a3eeee0977ad2291126a37631c0d86eeea75d822fa8af224c422134500bf9f0f2bb" From 613c00b5c4fbaad21ba07554752c9de8f06a1cc7 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 25 Jan 2024 11:04:13 -0800 Subject: [PATCH 1422/1772] wit-deps update: just lockfile changes --- proposals/sockets/wit/deps.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index be53c765e..64c71e7df 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "89da8eca4cd195516574c89c5b3c24a7b5af3ff2565c16753d20d3bdbc5fc60f" -sha512 = "244079b3f592d58478a97adbd0bee8d49ae9dd1a3e435651ee40997b50da9fe62cfaba7e3ec7f7406d7d0288d278a43a3a0bc5150226ba40ce0f8ac6d33f7ddb" +sha256 = "468b4d12892fe926b8eb5d398dbf579d566c93231fa44f415440572c695b7613" +sha512 = "e6b53a07221f1413953c9797c68f08b815fdaebf66419bbc1ea3e8b7dece73731062693634731f311a03957b268cf9cc509c518bd15e513c318aa04a8459b93a" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "f2e6127b235c37c06be675a904d6acf08db953ea688d78c42892c6ad3bd194e4" -sha512 = "32feefbc115c34bf6968cb6e9dc15e755698ee90648e5a5d84448917c36a318bd61b401195eb64330e2475e1d098bfb8dee1440d594a68e0797748762bd84ae5" +sha256 = "7210e5653539a15478f894d4da24cc69d61924cbcba21d2804d69314a88e5a4c" +sha512 = "49184a1b0945a889abd52d25271172ed3dc2db6968fcdddb1bab7ee0081f4a3eeee0977ad2291126a37631c0d86eeea75d822fa8af224c422134500bf9f0f2bb" From 01d27b648ccdd48642cbfcece0d4e4329bab2b75 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 25 Jan 2024 11:14:30 -0800 Subject: [PATCH 1423/1772] Release Preview 2: set package version to 0.2.0 (#41) * io, clocks, random, filesystem, sockets: copy in version 0.2.0 * update all uses of io, clocks, filesystem, sockets, random to 0.2.0 * set wasi:cli package version to 0.2.0 * generate markdown * wit-deps update: just lockfile changes --- proposals/cli/command.md | 112 ++++++++--------- proposals/cli/imports.md | 114 +++++++++--------- proposals/cli/wit/command.wit | 2 +- proposals/cli/wit/deps.lock | 20 +-- .../cli/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/cli/wit/deps/clocks/wall-clock.wit | 2 +- proposals/cli/wit/deps/clocks/world.wit | 2 +- .../cli/wit/deps/filesystem/preopens.wit | 2 +- proposals/cli/wit/deps/filesystem/types.wit | 6 +- proposals/cli/wit/deps/filesystem/world.wit | 2 +- proposals/cli/wit/deps/io/error.wit | 2 +- proposals/cli/wit/deps/io/poll.wit | 2 +- proposals/cli/wit/deps/io/streams.wit | 2 +- proposals/cli/wit/deps/io/world.wit | 2 +- .../cli/wit/deps/random/insecure-seed.wit | 2 +- proposals/cli/wit/deps/random/insecure.wit | 2 +- proposals/cli/wit/deps/random/random.wit | 2 +- proposals/cli/wit/deps/random/world.wit | 2 +- .../cli/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/cli/wit/deps/sockets/tcp.wit | 6 +- proposals/cli/wit/deps/sockets/udp.wit | 2 +- proposals/cli/wit/deps/sockets/world.wit | 2 +- proposals/cli/wit/imports.wit | 12 +- proposals/cli/wit/stdio.wit | 6 +- 24 files changed, 156 insertions(+), 156 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 3d92c2063..04dfb7b41 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -2,42 +2,42 @@ -

    Import interface wasi:cli/environment@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/environment@0.2.0


    Functions

    get-environment: func

    @@ -64,7 +64,7 @@ directory, interpreting . as shorthand for this.

    • option<string>
    -

    Import interface wasi:cli/exit@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/exit@0.2.0


    Functions

    exit: func

    @@ -73,7 +73,7 @@ directory, interpreting . as shorthand for this.

    -

    Import interface wasi:io/error@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/error@0.2.0


    Types

    resource error

    @@ -108,7 +108,7 @@ hazard.

    • string
    -

    Import interface wasi:io/poll@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/poll@0.2.0

    A poll API intended to let users wait for I/O events on multiple handles at once.


    @@ -158,7 +158,7 @@ being reaedy for I/O.

    • list<u32>
    -

    Import interface wasi:io/streams@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/streams@0.2.0

    WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

    In the future, the component model is expected to add built-in stream types; @@ -483,7 +483,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stdin@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/stdin@0.2.0


    Types

    type input-stream

    @@ -496,7 +496,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stdout@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/stdout@0.2.0


    Types

    type output-stream

    @@ -509,7 +509,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stderr@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/stderr@0.2.0


    Types

    type output-stream

    @@ -522,7 +522,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/terminal-input@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/terminal-input@0.2.0

    Terminal input.

    In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -531,7 +531,7 @@ immediately, querying supported features, and so on.

    Types

    resource terminal-input

    The input side of a terminal.

    -

    Import interface wasi:cli/terminal-output@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/terminal-output@0.2.0

    Terminal output.

    In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -540,7 +540,7 @@ features, and so on.

    Types

    resource terminal-output

    The output side of a terminal.

    -

    Import interface wasi:cli/terminal-stdin@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/terminal-stdin@0.2.0

    An interface providing an optional terminal-input for stdin as a link-time authority.


    @@ -557,7 +557,7 @@ allowing further interaction with it.

    -

    Import interface wasi:cli/terminal-stdout@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/terminal-stdout@0.2.0

    An interface providing an optional terminal-output for stdout as a link-time authority.


    @@ -574,7 +574,7 @@ allowing further interaction with it.

    -

    Import interface wasi:cli/terminal-stderr@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/terminal-stderr@0.2.0

    An interface providing an optional terminal-output for stderr as a link-time authority.


    @@ -591,7 +591,7 @@ allowing further interaction with it.

    -

    Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

    +

    Import interface wasi:clocks/monotonic-clock@0.2.0

    WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

    It is intended to be portable at least between Unix-family platforms and @@ -652,7 +652,7 @@ occured.

    -

    Import interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10

    +

    Import interface wasi:clocks/wall-clock@0.2.0

    WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

    @@ -693,7 +693,7 @@ also known as Unix Time.
  • datetime
  • -

    Import interface wasi:filesystem/types@0.2.0-rc-2023-11-10

    +

    Import interface wasi:filesystem/types@0.2.0

    WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

    @@ -1573,7 +1573,7 @@ errors are filesystem-related errors.

    -

    Import interface wasi:filesystem/preopens@0.2.0-rc-2023-11-10

    +

    Import interface wasi:filesystem/preopens@0.2.0


    Types

    type descriptor

    @@ -1587,7 +1587,7 @@ errors are filesystem-related errors.

    -

    Import interface wasi:sockets/network@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/network@0.2.0


    Types

    resource network

    @@ -1780,7 +1780,7 @@ supported size.
  • ipv4: ipv4-socket-address
  • ipv6: ipv6-socket-address
  • -

    Import interface wasi:sockets/instance-network@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/instance-network@0.2.0

    This interface provides a value-export of the default network handle..


    Types

    @@ -1795,7 +1795,7 @@ supported size. -

    Import interface wasi:sockets/udp@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/udp@0.2.0


    Types

    type pollable

    @@ -2209,7 +2209,7 @@ It's planned to be removed when future is natively supported in Pre -

    Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/udp-create-socket@0.2.0


    Types

    type network

    @@ -2254,7 +2254,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

    Import interface wasi:sockets/tcp@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/tcp@0.2.0


    Types

    type input-stream

    @@ -2845,7 +2845,7 @@ has no effect and returns ok.

    -

    Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/tcp-create-socket@0.2.0


    Types

    type network

    @@ -2890,7 +2890,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

    Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/ip-name-lookup@0.2.0


    Types

    type pollable

    @@ -2970,7 +2970,7 @@ It's planned to be removed when future is natively supported in Pre -

    Import interface wasi:random/random@0.2.0-rc-2023-11-10

    +

    Import interface wasi:random/random@0.2.0

    WASI Random is a random data API.

    It is intended to be portable at least between Unix-family platforms and Windows.

    @@ -3003,7 +3003,7 @@ represented as a u64.

    • u64
    -

    Import interface wasi:random/insecure@0.2.0-rc-2023-11-10

    +

    Import interface wasi:random/insecure@0.2.0

    The insecure interface for insecure pseudo-random numbers.

    It is intended to be portable at least between Unix-family platforms and Windows.

    @@ -3032,7 +3032,7 @@ a long period.

    • u64
    -

    Import interface wasi:random/insecure-seed@0.2.0-rc-2023-11-10

    +

    Import interface wasi:random/insecure-seed@0.2.0

    The insecure-seed interface for seeding hash-map DoS resistance.

    It is intended to be portable at least between Unix-family platforms and Windows.

    @@ -3056,7 +3056,7 @@ protection.

    • (u64, u64)
    -

    Export interface wasi:cli/run@0.2.0-rc-2024-01-16

    +

    Export interface wasi:cli/run@0.2.0


    Functions

    run: func

    diff --git a/proposals/cli/imports.md b/proposals/cli/imports.md index 48cd5a078..02f8f93df 100644 --- a/proposals/cli/imports.md +++ b/proposals/cli/imports.md @@ -2,37 +2,37 @@ -

    Import interface wasi:cli/environment@0.2.0-rc-2024-01-16

    +
  • interface wasi:cli/environment@0.2.0
  • +
  • interface wasi:cli/exit@0.2.0
  • +
  • interface wasi:io/error@0.2.0
  • +
  • interface wasi:io/poll@0.2.0
  • +
  • interface wasi:io/streams@0.2.0
  • +
  • interface wasi:cli/stdin@0.2.0
  • +
  • interface wasi:cli/stdout@0.2.0
  • +
  • interface wasi:cli/stderr@0.2.0
  • +
  • interface wasi:cli/terminal-input@0.2.0
  • +
  • interface wasi:cli/terminal-output@0.2.0
  • +
  • interface wasi:cli/terminal-stdin@0.2.0
  • +
  • interface wasi:cli/terminal-stdout@0.2.0
  • +
  • interface wasi:cli/terminal-stderr@0.2.0
  • +
  • interface wasi:clocks/monotonic-clock@0.2.0
  • +
  • interface wasi:clocks/wall-clock@0.2.0
  • +
  • interface wasi:filesystem/types@0.2.0
  • +
  • interface wasi:filesystem/preopens@0.2.0
  • +
  • interface wasi:sockets/network@0.2.0
  • +
  • interface wasi:sockets/instance-network@0.2.0
  • +
  • interface wasi:sockets/udp@0.2.0
  • +
  • interface wasi:sockets/udp-create-socket@0.2.0
  • +
  • interface wasi:sockets/tcp@0.2.0
  • +
  • interface wasi:sockets/tcp-create-socket@0.2.0
  • +
  • interface wasi:sockets/ip-name-lookup@0.2.0
  • +
  • interface wasi:random/random@0.2.0
  • +
  • interface wasi:random/insecure@0.2.0
  • +
  • interface wasi:random/insecure-seed@0.2.0
  • + + + +

    Import interface wasi:cli/environment@0.2.0


    Functions

    get-environment: func

    @@ -59,7 +59,7 @@ directory, interpreting . as shorthand for this.

    • option<string>
    -

    Import interface wasi:cli/exit@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/exit@0.2.0


    Functions

    exit: func

    @@ -68,7 +68,7 @@ directory, interpreting . as shorthand for this.

    -

    Import interface wasi:io/error@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/error@0.2.0


    Types

    resource error

    @@ -103,7 +103,7 @@ hazard.

    • string
    -

    Import interface wasi:io/poll@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/poll@0.2.0

    A poll API intended to let users wait for I/O events on multiple handles at once.


    @@ -153,7 +153,7 @@ being reaedy for I/O.

    • list<u32>
    -

    Import interface wasi:io/streams@0.2.0-rc-2023-11-10

    +

    Import interface wasi:io/streams@0.2.0

    WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

    In the future, the component model is expected to add built-in stream types; @@ -478,7 +478,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stdin@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/stdin@0.2.0


    Types

    type input-stream

    @@ -491,7 +491,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stdout@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/stdout@0.2.0


    Types

    type output-stream

    @@ -504,7 +504,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/stderr@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/stderr@0.2.0


    Types

    type output-stream

    @@ -517,7 +517,7 @@ is ready for reading, before performing the splice.

    -

    Import interface wasi:cli/terminal-input@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/terminal-input@0.2.0

    Terminal input.

    In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -526,7 +526,7 @@ immediately, querying supported features, and so on.

    Types

    resource terminal-input

    The input side of a terminal.

    -

    Import interface wasi:cli/terminal-output@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/terminal-output@0.2.0

    Terminal output.

    In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -535,7 +535,7 @@ features, and so on.

    Types

    resource terminal-output

    The output side of a terminal.

    -

    Import interface wasi:cli/terminal-stdin@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/terminal-stdin@0.2.0

    An interface providing an optional terminal-input for stdin as a link-time authority.


    @@ -552,7 +552,7 @@ allowing further interaction with it.

    -

    Import interface wasi:cli/terminal-stdout@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/terminal-stdout@0.2.0

    An interface providing an optional terminal-output for stdout as a link-time authority.


    @@ -569,7 +569,7 @@ allowing further interaction with it.

    -

    Import interface wasi:cli/terminal-stderr@0.2.0-rc-2024-01-16

    +

    Import interface wasi:cli/terminal-stderr@0.2.0

    An interface providing an optional terminal-output for stderr as a link-time authority.


    @@ -586,7 +586,7 @@ allowing further interaction with it.

    -

    Import interface wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10

    +

    Import interface wasi:clocks/monotonic-clock@0.2.0

    WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

    It is intended to be portable at least between Unix-family platforms and @@ -647,7 +647,7 @@ occured.

    -

    Import interface wasi:clocks/wall-clock@0.2.0-rc-2023-11-10

    +

    Import interface wasi:clocks/wall-clock@0.2.0

    WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

    @@ -688,7 +688,7 @@ also known as Unix Time.
  • datetime
  • -

    Import interface wasi:filesystem/types@0.2.0-rc-2023-11-10

    +

    Import interface wasi:filesystem/types@0.2.0

    WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

    @@ -1568,7 +1568,7 @@ errors are filesystem-related errors.

    -

    Import interface wasi:filesystem/preopens@0.2.0-rc-2023-11-10

    +

    Import interface wasi:filesystem/preopens@0.2.0


    Types

    type descriptor

    @@ -1582,7 +1582,7 @@ errors are filesystem-related errors.

    -

    Import interface wasi:sockets/network@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/network@0.2.0


    Types

    resource network

    @@ -1775,7 +1775,7 @@ supported size.
  • ipv4: ipv4-socket-address
  • ipv6: ipv6-socket-address
  • -

    Import interface wasi:sockets/instance-network@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/instance-network@0.2.0

    This interface provides a value-export of the default network handle..


    Types

    @@ -1790,7 +1790,7 @@ supported size. -

    Import interface wasi:sockets/udp@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/udp@0.2.0


    Types

    type pollable

    @@ -2204,7 +2204,7 @@ It's planned to be removed when future is natively supported in Pre -

    Import interface wasi:sockets/udp-create-socket@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/udp-create-socket@0.2.0


    Types

    type network

    @@ -2249,7 +2249,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

    Import interface wasi:sockets/tcp@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/tcp@0.2.0


    Types

    type input-stream

    @@ -2840,7 +2840,7 @@ has no effect and returns ok.

    -

    Import interface wasi:sockets/tcp-create-socket@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/tcp-create-socket@0.2.0


    Types

    type network

    @@ -2885,7 +2885,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

    Import interface wasi:sockets/ip-name-lookup@0.2.0-rc-2024-01-16

    +

    Import interface wasi:sockets/ip-name-lookup@0.2.0


    Types

    type pollable

    @@ -2965,7 +2965,7 @@ It's planned to be removed when future is natively supported in Pre -

    Import interface wasi:random/random@0.2.0-rc-2023-11-10

    +

    Import interface wasi:random/random@0.2.0

    WASI Random is a random data API.

    It is intended to be portable at least between Unix-family platforms and Windows.

    @@ -2998,7 +2998,7 @@ represented as a u64.

    • u64
    -

    Import interface wasi:random/insecure@0.2.0-rc-2023-11-10

    +

    Import interface wasi:random/insecure@0.2.0

    The insecure interface for insecure pseudo-random numbers.

    It is intended to be portable at least between Unix-family platforms and Windows.

    @@ -3027,7 +3027,7 @@ a long period.

    • u64
    -

    Import interface wasi:random/insecure-seed@0.2.0-rc-2023-11-10

    +

    Import interface wasi:random/insecure-seed@0.2.0

    The insecure-seed interface for seeding hash-map DoS resistance.

    It is intended to be portable at least between Unix-family platforms and Windows.

    diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index a9889164f..d8005bd38 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.0-rc-2024-01-16; +package wasi:cli@0.2.0; world command { include imports; diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index 24b86d96f..704339a11 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,24 +1,24 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "89da8eca4cd195516574c89c5b3c24a7b5af3ff2565c16753d20d3bdbc5fc60f" -sha512 = "244079b3f592d58478a97adbd0bee8d49ae9dd1a3e435651ee40997b50da9fe62cfaba7e3ec7f7406d7d0288d278a43a3a0bc5150226ba40ce0f8ac6d33f7ddb" +sha256 = "468b4d12892fe926b8eb5d398dbf579d566c93231fa44f415440572c695b7613" +sha512 = "e6b53a07221f1413953c9797c68f08b815fdaebf66419bbc1ea3e8b7dece73731062693634731f311a03957b268cf9cc509c518bd15e513c318aa04a8459b93a" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "05952bbc98895aa3aeda6c765a3e521016de59f993f3b60394c724640935c09c" -sha512 = "2c242489801a75466986fe014d730fb3aa7b5c6e56a230c8735e6672711b58bcbe92ba78a341b78fc3ac69339e55d3859d8bb14410230f0371ee30dbd83add64" +sha256 = "498c465cfd04587db40f970fff2185daa597d074c20b68a8bcbae558f261499b" +sha512 = "ead452f9b7bfb88593a502ec00d76d4228003d51c40fd0408aebc32d35c94673551b00230d730873361567cc209ec218c41fb4e95bad194268592c49e7964347" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "7a3c644dfd434f77fdf3f3d3b3caaca9538a0ade785167a3cce0321609f9d4e1" -sha512 = "2888f12b91359d630b4270f60e3c78855d9b305274ebf8a5decaef8698a74cc85c426823dc708b393f461b85ad991711d7400c2b2a24795001db5aee3ae19c70" +sha256 = "7210e5653539a15478f894d4da24cc69d61924cbcba21d2804d69314a88e5a4c" +sha512 = "49184a1b0945a889abd52d25271172ed3dc2db6968fcdddb1bab7ee0081f4a3eeee0977ad2291126a37631c0d86eeea75d822fa8af224c422134500bf9f0f2bb" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "11afcbff9920f5f1f72b6764d01e59a5faa2c671f0c59f0c9b405778f3708745" -sha512 = "cc4fa3d178559a89d9d6a376e3359b892158d1e73317c5db1f797ebc6b0b57abf2422797648d5b2b494c50cf9360720bc451cc27e15def7d278ba875805ccbf5" +sha256 = "7371d03c037d924caba2587fb2e7c5773a0d3c5fcecbf7971e0e0ba57973c53d" +sha512 = "964c4e8925a53078e4d94ba907b54f89a0b7e154f46823a505391471466c17f53c8692682e5c85771712acd88b348686173fc07c53a3cfe3d301b8cd8ddd0de4" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "9a3816bfa5a8b0673e5651024d8f9a1540f169f6d70f2bde6ee0e8240cd177ee" -sha512 = "bfcce89127510e16e9e7d7ac058ba3108953067e2d53f05cb1020dadf552738753b7fc9d10797236f2ced089063de7ac853fd9526079758fab1419d9b58a5212" +sha256 = "622bd28bbeb43736375dc02bd003fd3a016ff8ee91e14bab488325c6b38bf966" +sha512 = "5a63c1f36de0c4548e1d2297bdbededb28721cbad94ef7825c469eae29d7451c97e00b4c1d6730ee1ec0c4a5aac922961a2795762d4a0c3bb54e30a391a84bae" diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index 09ef32c36..4e4dc3a19 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.0-rc-2023-11-10; /// /// It is intended for measuring elapsed time. interface monotonic-clock { - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:io/poll@0.2.0.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit index 8abb9a0c0..440ca0f33 100644 --- a/proposals/cli/wit/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/cli/wit/deps/clocks/world.wit b/proposals/cli/wit/deps/clocks/world.wit index 8fa080f0e..c0224572a 100644 --- a/proposals/cli/wit/deps/clocks/world.wit +++ b/proposals/cli/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0-rc-2023-11-10; +package wasi:clocks@0.2.0; world imports { import monotonic-clock; diff --git a/proposals/cli/wit/deps/filesystem/preopens.wit b/proposals/cli/wit/deps/filesystem/preopens.wit index 95ec67843..da801f6d6 100644 --- a/proposals/cli/wit/deps/filesystem/preopens.wit +++ b/proposals/cli/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0-rc-2023-11-10; +package wasi:filesystem@0.2.0; interface preopens { use types.{descriptor}; diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index 059722ab8..11108fcda 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0-rc-2023-11-10; +package wasi:filesystem@0.2.0; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -24,8 +24,8 @@ package wasi:filesystem@0.2.0-rc-2023-11-10; /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md interface types { - use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream, error}; - use wasi:clocks/wall-clock@0.2.0-rc-2023-11-10.{datetime}; + use wasi:io/streams@0.2.0.{input-stream, output-stream, error}; + use wasi:clocks/wall-clock@0.2.0.{datetime}; /// File size or length of a region within a file. type filesize = u64; diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit index 285e0bae9..663f57920 100644 --- a/proposals/cli/wit/deps/filesystem/world.wit +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0-rc-2023-11-10; +package wasi:filesystem@0.2.0; world imports { import types; diff --git a/proposals/cli/wit/deps/io/error.wit b/proposals/cli/wit/deps/io/error.wit index 31918acbb..22e5b6489 100644 --- a/proposals/cli/wit/deps/io/error.wit +++ b/proposals/cli/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; interface error { diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit index 81b1cab99..ddc67f8b7 100644 --- a/proposals/cli/wit/deps/io/poll.wit +++ b/proposals/cli/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index 82e6e073e..6d2f871e3 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/cli/wit/deps/io/world.wit b/proposals/cli/wit/deps/io/world.wit index 8243da2ee..5f0b43fe5 100644 --- a/proposals/cli/wit/deps/io/world.wit +++ b/proposals/cli/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0-rc-2023-11-10; +package wasi:io@0.2.0; world imports { import streams; diff --git a/proposals/cli/wit/deps/random/insecure-seed.wit b/proposals/cli/wit/deps/random/insecure-seed.wit index f76e87dad..47210ac6b 100644 --- a/proposals/cli/wit/deps/random/insecure-seed.wit +++ b/proposals/cli/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0-rc-2023-11-10; +package wasi:random@0.2.0; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/insecure.wit b/proposals/cli/wit/deps/random/insecure.wit index ec7b99737..c58f4ee85 100644 --- a/proposals/cli/wit/deps/random/insecure.wit +++ b/proposals/cli/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0-rc-2023-11-10; +package wasi:random@0.2.0; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index 7a7dfa27a..0c017f093 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0-rc-2023-11-10; +package wasi:random@0.2.0; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/world.wit b/proposals/cli/wit/deps/random/world.wit index 49e5743b4..3da34914a 100644 --- a/proposals/cli/wit/deps/random/world.wit +++ b/proposals/cli/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0-rc-2023-11-10; +package wasi:random@0.2.0; world imports { import random; diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index 931ccf7e0..8e639ec59 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,6 +1,6 @@ interface ip-name-lookup { - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:io/poll@0.2.0.{pollable}; use network.{network, error-code, ip-address}; diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index 9f12b8212..5902b9ee0 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -1,8 +1,8 @@ interface tcp { - use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream, output-stream}; - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; - use wasi:clocks/monotonic-clock@0.2.0-rc-2023-11-10.{duration}; + use wasi:io/streams@0.2.0.{input-stream, output-stream}; + use wasi:io/poll@0.2.0.{pollable}; + use wasi:clocks/monotonic-clock@0.2.0.{duration}; use network.{network, error-code, ip-socket-address, ip-address-family}; enum shutdown-type { diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index 6ba380ff7..d987a0a90 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,6 +1,6 @@ interface udp { - use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable}; + use wasi:io/poll@0.2.0.{pollable}; use network.{network, error-code, ip-socket-address, ip-address-family}; /// A received datagram. diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit index 8588cc6c1..f8bb92ae0 100644 --- a/proposals/cli/wit/deps/sockets/world.wit +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.0-rc-2024-01-16; +package wasi:sockets@0.2.0; world imports { import instance-network; diff --git a/proposals/cli/wit/imports.wit b/proposals/cli/wit/imports.wit index 8ce1abec3..083b84a03 100644 --- a/proposals/cli/wit/imports.wit +++ b/proposals/cli/wit/imports.wit @@ -1,11 +1,11 @@ -package wasi:cli@0.2.0-rc-2024-01-16; +package wasi:cli@0.2.0; world imports { - include wasi:clocks/imports@0.2.0-rc-2023-11-10; - include wasi:filesystem/imports@0.2.0-rc-2023-11-10; - include wasi:sockets/imports@0.2.0-rc-2024-01-16; - include wasi:random/imports@0.2.0-rc-2023-11-10; - include wasi:io/imports@0.2.0-rc-2023-11-10; + include wasi:clocks/imports@0.2.0; + include wasi:filesystem/imports@0.2.0; + include wasi:sockets/imports@0.2.0; + include wasi:random/imports@0.2.0; + include wasi:io/imports@0.2.0; import environment; import exit; diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index 1b653b6e2..31ef35b5a 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,17 +1,17 @@ interface stdin { - use wasi:io/streams@0.2.0-rc-2023-11-10.{input-stream}; + use wasi:io/streams@0.2.0.{input-stream}; get-stdin: func() -> input-stream; } interface stdout { - use wasi:io/streams@0.2.0-rc-2023-11-10.{output-stream}; + use wasi:io/streams@0.2.0.{output-stream}; get-stdout: func() -> output-stream; } interface stderr { - use wasi:io/streams@0.2.0-rc-2023-11-10.{output-stream}; + use wasi:io/streams@0.2.0.{output-stream}; get-stderr: func() -> output-stream; } From a5deaa448ec0cee3c59cef53ed5b9de7e50a7b79 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 25 Jan 2024 11:15:05 -0800 Subject: [PATCH 1424/1772] wit-deps update: update lockfile only --- proposals/http/wit/deps.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index fa5d5682b..96be4b203 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,29 +1,29 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -sha256 = "754f9d1de112e106cc7131b79b1efd29340f9d6191699f224835fd41521ba386" -sha512 = "908a67492c05f752b0152646e5acdccdde89d8b303db254bf462d2e6714c420d80ebebc46ab75b8953c060a06ea06d99d55b523f6aa09e2f4f16d5e63649f0ea" +sha256 = "285865a31d777181b075f39e92bcfe59c89cd6bacce660be1b9a627646956258" +sha512 = "da2622210a9e3eea82b99f1a5b8a44ce5443d009cb943f7bca0bf9cf4360829b289913d7ee727c011f0f72994ea7dc8e661ebcc0a6b34b587297d80cd9b3f7e8" [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "89da8eca4cd195516574c89c5b3c24a7b5af3ff2565c16753d20d3bdbc5fc60f" -sha512 = "244079b3f592d58478a97adbd0bee8d49ae9dd1a3e435651ee40997b50da9fe62cfaba7e3ec7f7406d7d0288d278a43a3a0bc5150226ba40ce0f8ac6d33f7ddb" +sha256 = "468b4d12892fe926b8eb5d398dbf579d566c93231fa44f415440572c695b7613" +sha512 = "e6b53a07221f1413953c9797c68f08b815fdaebf66419bbc1ea3e8b7dece73731062693634731f311a03957b268cf9cc509c518bd15e513c318aa04a8459b93a" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "05952bbc98895aa3aeda6c765a3e521016de59f993f3b60394c724640935c09c" -sha512 = "2c242489801a75466986fe014d730fb3aa7b5c6e56a230c8735e6672711b58bcbe92ba78a341b78fc3ac69339e55d3859d8bb14410230f0371ee30dbd83add64" +sha256 = "498c465cfd04587db40f970fff2185daa597d074c20b68a8bcbae558f261499b" +sha512 = "ead452f9b7bfb88593a502ec00d76d4228003d51c40fd0408aebc32d35c94673551b00230d730873361567cc209ec218c41fb4e95bad194268592c49e7964347" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "7a3c644dfd434f77fdf3f3d3b3caaca9538a0ade785167a3cce0321609f9d4e1" -sha512 = "2888f12b91359d630b4270f60e3c78855d9b305274ebf8a5decaef8698a74cc85c426823dc708b393f461b85ad991711d7400c2b2a24795001db5aee3ae19c70" +sha256 = "7210e5653539a15478f894d4da24cc69d61924cbcba21d2804d69314a88e5a4c" +sha512 = "49184a1b0945a889abd52d25271172ed3dc2db6968fcdddb1bab7ee0081f4a3eeee0977ad2291126a37631c0d86eeea75d822fa8af224c422134500bf9f0f2bb" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "11afcbff9920f5f1f72b6764d01e59a5faa2c671f0c59f0c9b405778f3708745" -sha512 = "cc4fa3d178559a89d9d6a376e3359b892158d1e73317c5db1f797ebc6b0b57abf2422797648d5b2b494c50cf9360720bc451cc27e15def7d278ba875805ccbf5" +sha256 = "7371d03c037d924caba2587fb2e7c5773a0d3c5fcecbf7971e0e0ba57973c53d" +sha512 = "964c4e8925a53078e4d94ba907b54f89a0b7e154f46823a505391471466c17f53c8692682e5c85771712acd88b348686173fc07c53a3cfe3d301b8cd8ddd0de4" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "9a3816bfa5a8b0673e5651024d8f9a1540f169f6d70f2bde6ee0e8240cd177ee" -sha512 = "bfcce89127510e16e9e7d7ac058ba3108953067e2d53f05cb1020dadf552738753b7fc9d10797236f2ced089063de7ac853fd9526079758fab1419d9b58a5212" +sha256 = "622bd28bbeb43736375dc02bd003fd3a016ff8ee91e14bab488325c6b38bf966" +sha512 = "5a63c1f36de0c4548e1d2297bdbededb28721cbad94ef7825c469eae29d7451c97e00b4c1d6730ee1ec0c4a5aac922961a2795762d4a0c3bb54e30a391a84bae" From 526390e5c5111b9580a95e03c37e2dd530e5bbbd Mon Sep 17 00:00:00 2001 From: "Jiaxiao Zhou (Mossaka)" Date: Thu, 8 Feb 2024 12:38:54 -0800 Subject: [PATCH 1425/1772] refactor the imports to its own world Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/http/imports.md | 1527 ++++++++++++++++++++++++++++++++++ proposals/http/proxy.md | 912 ++++++++++---------- proposals/http/wit/proxy.wit | 16 +- 3 files changed, 1994 insertions(+), 461 deletions(-) create mode 100644 proposals/http/imports.md diff --git a/proposals/http/imports.md b/proposals/http/imports.md new file mode 100644 index 000000000..0493c522d --- /dev/null +++ b/proposals/http/imports.md @@ -0,0 +1,1527 @@ +

    World imports

    +

    The wasi:http/imports world imports all the APIs for HTTP proxies. +Is is intended to be included in other worlds.

    + +

    Import interface wasi:random/random@0.2.0

    +

    WASI Random is a random data API.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +
    +

    Functions

    +

    get-random-bytes: func

    +

    Return len cryptographically-secure random or pseudo-random bytes.

    +

    This function must produce data at least as cryptographically secure and +fast as an adequately seeded cryptographically-secure pseudo-random +number generator (CSPRNG). It must not block, from the perspective of +the calling program, under any circumstances, including on the first +request and on requests for numbers of bytes. The returned data must +always be unpredictable.

    +

    This function must always return fresh data. Deterministic environments +must omit this function, rather than implementing it with deterministic +data.

    +
    Params
    +
      +
    • len: u64
    • +
    +
    Return values
    +
      +
    • list<u8>
    • +
    +

    get-random-u64: func

    +

    Return a cryptographically-secure random or pseudo-random u64 value.

    +

    This function returns the same type of data as get-random-bytes, +represented as a u64.

    +
    Return values
    +
      +
    • u64
    • +
    +

    Import interface wasi:io/error@0.2.0

    +
    +

    Types

    +

    resource error

    +

    A resource which represents some error information.

    +

    The only method provided by this resource is to-debug-string, +which provides some human-readable information about the error.

    +

    In the wasi:io package, this resource is returned through the +wasi:io/streams/stream-error type.

    +

    To provide more specific error information, other interfaces may +provide functions to further "downcast" this error into more specific +error information. For example, errors returned in streams derived +from filesystem types to be described using the filesystem's own +error-code type, using the function +wasi:filesystem/types/filesystem-error-code, which takes a parameter +borrow<error> and returns +option<wasi:filesystem/types/error-code>.

    +

    The set of functions which can "downcast" an error into a more +concrete type is open.

    +

    Functions

    +

    [method]error.to-debug-string: func

    +

    Returns a string that is suitable to assist humans in debugging +this error.

    +

    WARNING: The returned string should not be consumed mechanically! +It may change across platforms, hosts, or other implementation +details. Parsing this string is a major platform-compatibility +hazard.

    +
    Params
    + +
    Return values
    +
      +
    • string
    • +
    +

    Import interface wasi:io/poll@0.2.0

    +

    A poll API intended to let users wait for I/O events on multiple handles +at once.

    +
    +

    Types

    +

    resource pollable

    +

    pollable represents a single I/O event which may be ready, or not.

    +

    Functions

    +

    [method]pollable.ready: func

    +

    Return the readiness of a pollable. This function never blocks.

    +

    Returns true when the pollable is ready, and false otherwise.

    +
    Params
    + +
    Return values
    +
      +
    • bool
    • +
    +

    [method]pollable.block: func

    +

    block returns immediately if the pollable is ready, and otherwise +blocks until ready.

    +

    This function is equivalent to calling poll.poll on a list +containing only this pollable.

    +
    Params
    + +

    poll: func

    +

    Poll for completion on a set of pollables.

    +

    This function takes a list of pollables, which identify I/O sources of +interest, and waits until one or more of the events is ready for I/O.

    +

    The result list<u32> contains one or more indices of handles in the +argument list that is ready for I/O.

    +

    If the list contains more elements than can be indexed with a u32 +value, this function traps.

    +

    A timeout can be implemented by adding a pollable from the +wasi-clocks API to the list.

    +

    This function does not return a result; polling in itself does not +do any I/O so it doesn't fail. If any of the I/O sources identified by +the pollables has an error, it is indicated by marking the source as +being reaedy for I/O.

    +
    Params
    + +
    Return values
    +
      +
    • list<u32>
    • +
    +

    Import interface wasi:io/streams@0.2.0

    +

    WASI I/O is an I/O abstraction API which is currently focused on providing +stream types.

    +

    In the future, the component model is expected to add built-in stream types; +when it does, they are expected to subsume this API.

    +
    +

    Types

    +

    type error

    +

    error

    +

    +#### `type pollable` +[`pollable`](#pollable) +

    +#### `variant stream-error` +

    An error for input-stream and output-stream operations.

    +
    Variant Cases
    +
      +
    • +

      last-operation-failed: own<error>

      +

      The last operation (a write or flush) failed before completion. +

      More information is available in the error payload.

      +
    • +
    • +

      closed

      +

      The stream is closed: no more input will be accepted by the +stream. A closed output-stream will return this error on all +future operations. +

    • +
    +

    resource input-stream

    +

    An input bytestream.

    +

    input-streams are non-blocking to the extent practical on underlying +platforms. I/O operations always return promptly; if fewer bytes are +promptly available than requested, they return the number of bytes promptly +available, which could even be zero. To wait for data to be available, +use the subscribe function to obtain a pollable which can be polled +for using wasi:io/poll.

    +

    resource output-stream

    +

    An output bytestream.

    +

    output-streams are non-blocking to the extent practical on +underlying platforms. Except where specified otherwise, I/O operations also +always return promptly, after the number of bytes that can be written +promptly, which could even be zero. To wait for the stream to be ready to +accept data, the subscribe function to obtain a pollable which can be +polled for using wasi:io/poll.

    +

    Functions

    +

    [method]input-stream.read: func

    +

    Perform a non-blocking read from the stream.

    +

    When the source of a read is binary data, the bytes from the source +are returned verbatim. When the source of a read is known to the +implementation to be text, bytes containing the UTF-8 encoding of the +text are returned.

    +

    This function returns a list of bytes containing the read data, +when successful. The returned list will contain up to len bytes; +it may return fewer than requested, but not more. The list is +empty when no bytes are available for reading at this time. The +pollable given by subscribe will be ready when more bytes are +available.

    +

    This function fails with a stream-error when the operation +encounters an error, giving last-operation-failed, or when the +stream is closed, giving closed.

    +

    When the caller gives a len of 0, it represents a request to +read 0 bytes. If the stream is still open, this call should +succeed and return an empty list, or otherwise fail with closed.

    +

    The len parameter is a u64, which could represent a list of u8 which +is not possible to allocate in wasm32, or not desirable to allocate as +as a return value by the callee. The callee may return a list of bytes +less than len in size while more bytes are available for reading.

    +
    Params
    + +
    Return values
    + +

    [method]input-stream.blocking-read: func

    +

    Read bytes from a stream, after blocking until at least one byte can +be read. Except for blocking, behavior is identical to read.

    +
    Params
    + +
    Return values
    + +

    [method]input-stream.skip: func

    +

    Skip bytes from a stream. Returns number of bytes skipped.

    +

    Behaves identical to read, except instead of returning a list +of bytes, returns the number of bytes consumed from the stream.

    +
    Params
    + +
    Return values
    + +

    [method]input-stream.blocking-skip: func

    +

    Skip bytes from a stream, after blocking until at least one byte +can be skipped. Except for blocking behavior, identical to skip.

    +
    Params
    + +
    Return values
    + +

    [method]input-stream.subscribe: func

    +

    Create a pollable which will resolve once either the specified stream +has bytes available to read or the other end of the stream has been +closed. +The created pollable is a child resource of the input-stream. +Implementations may trap if the input-stream is dropped before +all derived pollables created with this function are dropped.

    +
    Params
    + +
    Return values
    + +

    [method]output-stream.check-write: func

    +

    Check readiness for writing. This function never blocks.

    +

    Returns the number of bytes permitted for the next call to write, +or an error. Calling write with more bytes than this function has +permitted will trap.

    +

    When this function returns 0 bytes, the subscribe pollable will +become ready when this function will report at least 1 byte, or an +error.

    +
    Params
    + +
    Return values
    + +

    [method]output-stream.write: func

    +

    Perform a write. This function never blocks.

    +

    When the destination of a write is binary data, the bytes from +contents are written verbatim. When the destination of a write is +known to the implementation to be text, the bytes of contents are +transcoded from UTF-8 into the encoding of the destination and then +written.

    +

    Precondition: check-write gave permit of Ok(n) and contents has a +length of less than or equal to n. Otherwise, this function will trap.

    +

    returns Err(closed) without writing if the stream has closed since +the last call to check-write provided a permit.

    +
    Params
    + +
    Return values
    + +

    [method]output-stream.blocking-write-and-flush: func

    +

    Perform a write of up to 4096 bytes, and then flush the stream. Block +until all of these operations are complete, or an error occurs.

    +

    This is a convenience wrapper around the use of check-write, +subscribe, write, and flush, and is implemented with the +following pseudo-code:

    +
    let pollable = this.subscribe();
    +while !contents.is_empty() {
    +  // Wait for the stream to become writable
    +  pollable.block();
    +  let Ok(n) = this.check-write(); // eliding error handling
    +  let len = min(n, contents.len());
    +  let (chunk, rest) = contents.split_at(len);
    +  this.write(chunk  );            // eliding error handling
    +  contents = rest;
    +}
    +this.flush();
    +// Wait for completion of `flush`
    +pollable.block();
    +// Check for any errors that arose during `flush`
    +let _ = this.check-write();         // eliding error handling
    +
    +
    Params
    + +
    Return values
    + +

    [method]output-stream.flush: func

    +

    Request to flush buffered output. This function never blocks.

    +

    This tells the output-stream that the caller intends any buffered +output to be flushed. the output which is expected to be flushed +is all that has been passed to write prior to this call.

    +

    Upon calling this function, the output-stream will not accept any +writes (check-write will return ok(0)) until the flush has +completed. The subscribe pollable will become ready when the +flush has completed and the stream can accept more writes.

    +
    Params
    + +
    Return values
    + +

    [method]output-stream.blocking-flush: func

    +

    Request to flush buffered output, and block until flush completes +and stream is ready for writing again.

    +
    Params
    + +
    Return values
    + +

    [method]output-stream.subscribe: func

    +

    Create a pollable which will resolve once the output-stream +is ready for more writing, or an error has occured. When this +pollable is ready, check-write will return ok(n) with n>0, or an +error.

    +

    If the stream is closed, this pollable is always ready immediately.

    +

    The created pollable is a child resource of the output-stream. +Implementations may trap if the output-stream is dropped before +all derived pollables created with this function are dropped.

    +
    Params
    + +
    Return values
    + +

    [method]output-stream.write-zeroes: func

    +

    Write zeroes to a stream.

    +

    This should be used precisely like write with the exact same +preconditions (must use check-write first), but instead of +passing a list of bytes, you simply pass the number of zero-bytes +that should be written.

    +
    Params
    + +
    Return values
    + +

    [method]output-stream.blocking-write-zeroes-and-flush: func

    +

    Perform a write of up to 4096 zeroes, and then flush the stream. +Block until all of these operations are complete, or an error +occurs.

    +

    This is a convenience wrapper around the use of check-write, +subscribe, write-zeroes, and flush, and is implemented with +the following pseudo-code:

    +
    let pollable = this.subscribe();
    +while num_zeroes != 0 {
    +  // Wait for the stream to become writable
    +  pollable.block();
    +  let Ok(n) = this.check-write(); // eliding error handling
    +  let len = min(n, num_zeroes);
    +  this.write-zeroes(len);         // eliding error handling
    +  num_zeroes -= len;
    +}
    +this.flush();
    +// Wait for completion of `flush`
    +pollable.block();
    +// Check for any errors that arose during `flush`
    +let _ = this.check-write();         // eliding error handling
    +
    +
    Params
    + +
    Return values
    + +

    [method]output-stream.splice: func

    +

    Read from one stream and write to another.

    +

    The behavior of splice is equivelant to:

    +
      +
    1. calling check-write on the output-stream
    2. +
    3. calling read on the input-stream with the smaller of the +check-write permitted length and the len provided to splice
    4. +
    5. calling write on the output-stream with that read data.
    6. +
    +

    Any error reported by the call to check-write, read, or +write ends the splice and reports that error.

    +

    This function returns the number of bytes transferred; it may be less +than len.

    +
    Params
    + +
    Return values
    + +

    [method]output-stream.blocking-splice: func

    +

    Read from one stream and write to another, with blocking.

    +

    This is similar to splice, except that it blocks until the +output-stream is ready for writing, and the input-stream +is ready for reading, before performing the splice.

    +
    Params
    + +
    Return values
    + +

    Import interface wasi:cli/stdout@0.2.0

    +
    +

    Types

    +

    type output-stream

    +

    output-stream

    +

    +---- +

    Functions

    +

    get-stdout: func

    +
    Return values
    + +

    Import interface wasi:cli/stderr@0.2.0

    +
    +

    Types

    +

    type output-stream

    +

    output-stream

    +

    +---- +

    Functions

    +

    get-stderr: func

    +
    Return values
    + +

    Import interface wasi:cli/stdin@0.2.0

    +
    +

    Types

    +

    type input-stream

    +

    input-stream

    +

    +---- +

    Functions

    +

    get-stdin: func

    +
    Return values
    + +

    Import interface wasi:clocks/monotonic-clock@0.2.0

    +

    WASI Monotonic Clock is a clock API intended to let users measure elapsed +time.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +

    A monotonic clock is a clock which has an unspecified initial value, and +successive reads of the clock will produce non-decreasing values.

    +

    It is intended for measuring elapsed time.

    +
    +

    Types

    +

    type pollable

    +

    pollable

    +

    +#### `type instant` +`u64` +

    An instant in time, in nanoseconds. An instant is relative to an +unspecified initial value, and can only be compared to instances from +the same monotonic-clock. +

    type duration

    +

    u64

    +

    A duration of time, in nanoseconds. +


    +

    Functions

    +

    now: func

    +

    Read the current value of the clock.

    +

    The clock is monotonic, therefore calling this function repeatedly will +produce a sequence of non-decreasing values.

    +
    Return values
    + +

    resolution: func

    +

    Query the resolution of the clock. Returns the duration of time +corresponding to a clock tick.

    +
    Return values
    + +

    subscribe-instant: func

    +

    Create a pollable which will resolve once the specified instant +occured.

    +
    Params
    + +
    Return values
    + +

    subscribe-duration: func

    +

    Create a pollable which will resolve once the given duration has +elapsed, starting at the time at which this function was called. +occured.

    +
    Params
    + +
    Return values
    + +

    Import interface wasi:http/types@0.2.0

    +

    This interface defines all of the types and methods for implementing +HTTP Requests and Responses, both incoming and outgoing, as well as +their headers, trailers, and bodies.

    +
    +

    Types

    +

    type duration

    +

    duration

    +

    +#### `type input-stream` +[`input-stream`](#input_stream) +

    +#### `type output-stream` +[`output-stream`](#output_stream) +

    +#### `type io-error` +[`error`](#error) +

    +#### `type pollable` +[`pollable`](#pollable) +

    +#### `variant method` +

    This type corresponds to HTTP standard Methods.

    +
    Variant Cases
    +
      +
    • get
    • +
    • head
    • +
    • post
    • +
    • put
    • +
    • delete
    • +
    • connect
    • +
    • options
    • +
    • trace
    • +
    • patch
    • +
    • other: string
    • +
    +

    variant scheme

    +

    This type corresponds to HTTP standard Related Schemes.

    +
    Variant Cases
    +
      +
    • HTTP
    • +
    • HTTPS
    • +
    • other: string
    • +
    +

    record DNS-error-payload

    +

    Defines the case payload type for DNS-error above:

    +
    Record Fields
    +
      +
    • rcode: option<string>
    • +
    • info-code: option<u16>
    • +
    +

    record TLS-alert-received-payload

    +

    Defines the case payload type for TLS-alert-received above:

    +
    Record Fields
    +
      +
    • alert-id: option<u8>
    • +
    • alert-message: option<string>
    • +
    +

    record field-size-payload

    +

    Defines the case payload type for HTTP-response-{header,trailer}-size above:

    +
    Record Fields
    +
      +
    • field-name: option<string>
    • +
    • field-size: option<u32>
    • +
    +

    variant error-code

    +

    These cases are inspired by the IANA HTTP Proxy Error Types: +https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types

    +
    Variant Cases
    +
      +
    • DNS-timeout
    • +
    • DNS-error: DNS-error-payload
    • +
    • destination-not-found
    • +
    • destination-unavailable
    • +
    • destination-IP-prohibited
    • +
    • destination-IP-unroutable
    • +
    • connection-refused
    • +
    • connection-terminated
    • +
    • connection-timeout
    • +
    • connection-read-timeout
    • +
    • connection-write-timeout
    • +
    • connection-limit-reached
    • +
    • TLS-protocol-error
    • +
    • TLS-certificate-error
    • +
    • TLS-alert-received: TLS-alert-received-payload
    • +
    • HTTP-request-denied
    • +
    • HTTP-request-length-required
    • +
    • HTTP-request-body-size: option<u64>
    • +
    • HTTP-request-method-invalid
    • +
    • HTTP-request-URI-invalid
    • +
    • HTTP-request-URI-too-long
    • +
    • HTTP-request-header-section-size: option<u32>
    • +
    • HTTP-request-header-size: option<field-size-payload>
    • +
    • HTTP-request-trailer-section-size: option<u32>
    • +
    • HTTP-request-trailer-size: field-size-payload
    • +
    • HTTP-response-incomplete
    • +
    • HTTP-response-header-section-size: option<u32>
    • +
    • HTTP-response-header-size: field-size-payload
    • +
    • HTTP-response-body-size: option<u64>
    • +
    • HTTP-response-trailer-section-size: option<u32>
    • +
    • HTTP-response-trailer-size: field-size-payload
    • +
    • HTTP-response-transfer-coding: option<string>
    • +
    • HTTP-response-content-coding: option<string>
    • +
    • HTTP-response-timeout
    • +
    • HTTP-upgrade-failed
    • +
    • HTTP-protocol-error
    • +
    • loop-detected
    • +
    • configuration-error
    • +
    • internal-error: option<string>

      This is a catch-all error for anything that doesn't fit cleanly into a +more specific case. It also includes an optional string for an +unstructured description of the error. Users should not depend on the +string for diagnosing errors, as it's not required to be consistent +between implementations. +

    • +
    +

    variant header-error

    +

    This type enumerates the different kinds of errors that may occur when +setting or appending to a fields resource.

    +
    Variant Cases
    +
      +
    • +

      invalid-syntax

      +

      This error indicates that a `field-key` or `field-value` was +syntactically invalid when used with an operation that sets headers in a +`fields`. +

    • +
    • +

      forbidden

      +

      This error indicates that a forbidden `field-key` was used when trying +to set a header in a `fields`. +

    • +
    • +

      immutable

      +

      This error indicates that the operation on the `fields` was not +permitted because the fields are immutable. +

    • +
    +

    type field-key

    +

    string

    +

    Field keys are always strings. +

    type field-value

    +

    field-value

    +

    Field values should always be ASCII strings. However, in +reality, HTTP implementations often have to interpret malformed values, +so they are provided as a list of bytes. +

    resource fields

    +

    This following block defines the fields resource which corresponds to +HTTP standard Fields. Fields are a common representation used for both +Headers and Trailers.

    +

    A fields may be mutable or immutable. A fields created using the +constructor, from-list, or clone will be mutable, but a fields +resource given by other means (including, but not limited to, +incoming-request.headers, outgoing-request.headers) might be be +immutable. In an immutable fields, the set, append, and delete +operations will fail with header-error.immutable.

    +

    type headers

    +

    fields

    +

    Headers is an alias for Fields. +

    type trailers

    +

    fields

    +

    Trailers is an alias for Fields. +

    resource incoming-request

    +

    Represents an incoming HTTP Request.

    +

    resource outgoing-request

    +

    Represents an outgoing HTTP Request.

    +

    resource request-options

    +

    Parameters for making an HTTP Request. Each of these parameters is +currently an optional timeout applicable to the transport layer of the +HTTP protocol.

    +

    These timeouts are separate from any the user may use to bound a +blocking call to wasi:io/poll.poll.

    +

    resource response-outparam

    +

    Represents the ability to send an HTTP Response.

    +

    This resource is used by the wasi:http/incoming-handler interface to +allow a Response to be sent corresponding to the Request provided as the +other argument to incoming-handler.handle.

    +

    type status-code

    +

    u16

    +

    This type corresponds to the HTTP standard Status Code. +

    resource incoming-response

    +

    Represents an incoming HTTP Response.

    +

    resource incoming-body

    +

    Represents an incoming HTTP Request or Response's Body.

    +

    A body has both its contents - a stream of bytes - and a (possibly +empty) set of trailers, indicating that the full contents of the +body have been received. This resource represents the contents as +an input-stream and the delivery of trailers as a future-trailers, +and ensures that the user of this interface may only be consuming either +the body contents or waiting on trailers at any given time.

    +

    resource future-trailers

    +

    Represents a future which may eventaully return trailers, or an error.

    +

    In the case that the incoming HTTP Request or Response did not have any +trailers, this future will resolve to the empty set of trailers once the +complete Request or Response body has been received.

    +

    resource outgoing-response

    +

    Represents an outgoing HTTP Response.

    +

    resource outgoing-body

    +

    Represents an outgoing HTTP Request or Response's Body.

    +

    A body has both its contents - a stream of bytes - and a (possibly +empty) set of trailers, inducating the full contents of the body +have been sent. This resource represents the contents as an +output-stream child resource, and the completion of the body (with +optional trailers) with a static function that consumes the +outgoing-body resource, and ensures that the user of this interface +may not write to the body contents after the body has been finished.

    +

    If the user code drops this resource, as opposed to calling the static +method finish, the implementation should treat the body as incomplete, +and that an error has occured. The implementation should propogate this +error to the HTTP protocol by whatever means it has available, +including: corrupting the body on the wire, aborting the associated +Request, or sending a late status code for the Response.

    +

    resource future-incoming-response

    +

    Represents a future which may eventaully return an incoming HTTP +Response, or an error.

    +

    This resource is returned by the wasi:http/outgoing-handler interface to +provide the HTTP Response corresponding to the sent Request.

    +

    Functions

    +

    http-error-code: func

    +

    Attempts to extract a http-related error from the wasi:io error +provided.

    +

    Stream operations which return +wasi:io/stream/stream-error::last-operation-failed have a payload of +type wasi:io/error/error with more information about the operation +that failed. This payload can be passed through to this function to see +if there's http-related information about the error to return.

    +

    Note that this function is fallible because not all io-errors are +http-related errors.

    +
    Params
    + +
    Return values
    + +

    [constructor]fields: func

    +

    Construct an empty HTTP Fields.

    +

    The resulting fields is mutable.

    +
    Return values
    + +

    [static]fields.from-list: func

    +

    Construct an HTTP Fields.

    +

    The resulting fields is mutable.

    +

    The list represents each key-value pair in the Fields. Keys +which have multiple values are represented by multiple entries in this +list with the same key.

    +

    The tuple is a pair of the field key, represented as a string, and +Value, represented as a list of bytes. In a valid Fields, all keys +and values are valid UTF-8 strings. However, values are not always +well-formed, so they are represented as a raw list of bytes.

    +

    An error result will be returned if any header or value was +syntactically invalid, or if a header was forbidden.

    +
    Params
    + +
    Return values
    + +

    [method]fields.get: func

    +

    Get all of the values corresponding to a key. If the key is not present +in this fields, an empty list is returned. However, if the key is +present but empty, this is represented by a list with one or more +empty field-values present.

    +
    Params
    + +
    Return values
    + +

    [method]fields.has: func

    +

    Returns true when the key is present in this fields. If the key is +syntactically invalid, false is returned.

    +
    Params
    + +
    Return values
    +
      +
    • bool
    • +
    +

    [method]fields.set: func

    +

    Set all of the values for a key. Clears any existing values for that +key, if they have been set.

    +

    Fails with header-error.immutable if the fields are immutable.

    +
    Params
    + +
    Return values
    + +

    [method]fields.delete: func

    +

    Delete all values for a key. Does nothing if no values for the key +exist.

    +

    Fails with header-error.immutable if the fields are immutable.

    +
    Params
    + +
    Return values
    + +

    [method]fields.append: func

    +

    Append a value for a key. Does not change or delete any existing +values for that key.

    +

    Fails with header-error.immutable if the fields are immutable.

    +
    Params
    + +
    Return values
    + +

    [method]fields.entries: func

    +

    Retrieve the full set of keys and values in the Fields. Like the +constructor, the list represents each key-value pair.

    +

    The outer list represents each key-value pair in the Fields. Keys +which have multiple values are represented by multiple entries in this +list with the same key.

    +
    Params
    + +
    Return values
    + +

    [method]fields.clone: func

    +

    Make a deep copy of the Fields. Equivelant in behavior to calling the +fields constructor on the return value of entries. The resulting +fields is mutable.

    +
    Params
    + +
    Return values
    + +

    [method]incoming-request.method: func

    +

    Returns the method of the incoming request.

    +
    Params
    + +
    Return values
    + +

    [method]incoming-request.path-with-query: func

    +

    Returns the path with query parameters from the request, as a string.

    +
    Params
    + +
    Return values
    +
      +
    • option<string>
    • +
    +

    [method]incoming-request.scheme: func

    +

    Returns the protocol scheme from the request.

    +
    Params
    + +
    Return values
    + +

    [method]incoming-request.authority: func

    +

    Returns the authority from the request, if it was present.

    +
    Params
    + +
    Return values
    +
      +
    • option<string>
    • +
    +

    [method]incoming-request.headers: func

    +

    Get the headers associated with the request.

    +

    The returned headers resource is immutable: set, append, and +delete operations will fail with header-error.immutable.

    +

    The headers returned are a child resource: it must be dropped before +the parent incoming-request is dropped. Dropping this +incoming-request before all children are dropped will trap.

    +
    Params
    + +
    Return values
    + +

    [method]incoming-request.consume: func

    +

    Gives the incoming-body associated with this request. Will only +return success at most once, and subsequent calls will return error.

    +
    Params
    + +
    Return values
    + +

    [constructor]outgoing-request: func

    +

    Construct a new outgoing-request with a default method of GET, and +none values for path-with-query, scheme, and authority.

    +
      +
    • headers is the HTTP Headers for the Request.
    • +
    +

    It is possible to construct, or manipulate with the accessor functions +below, an outgoing-request with an invalid combination of scheme +and authority, or headers which are not permitted to be sent. +It is the obligation of the outgoing-handler.handle implementation +to reject invalid constructions of outgoing-request.

    +
    Params
    + +
    Return values
    + +

    [method]outgoing-request.body: func

    +

    Returns the resource corresponding to the outgoing Body for this +Request.

    +

    Returns success on the first call: the outgoing-body resource for +this outgoing-request can be retrieved at most once. Subsequent +calls will return error.

    +
    Params
    + +
    Return values
    + +

    [method]outgoing-request.method: func

    +

    Get the Method for the Request.

    +
    Params
    + +
    Return values
    + +

    [method]outgoing-request.set-method: func

    +

    Set the Method for the Request. Fails if the string present in a +method.other argument is not a syntactically valid method.

    +
    Params
    + +
    Return values
    +
      +
    • result
    • +
    +

    [method]outgoing-request.path-with-query: func

    +

    Get the combination of the HTTP Path and Query for the Request. +When none, this represents an empty Path and empty Query.

    +
    Params
    + +
    Return values
    +
      +
    • option<string>
    • +
    +

    [method]outgoing-request.set-path-with-query: func

    +

    Set the combination of the HTTP Path and Query for the Request. +When none, this represents an empty Path and empty Query. Fails is the +string given is not a syntactically valid path and query uri component.

    +
    Params
    + +
    Return values
    +
      +
    • result
    • +
    +

    [method]outgoing-request.scheme: func

    +

    Get the HTTP Related Scheme for the Request. When none, the +implementation may choose an appropriate default scheme.

    +
    Params
    + +
    Return values
    + +

    [method]outgoing-request.set-scheme: func

    +

    Set the HTTP Related Scheme for the Request. When none, the +implementation may choose an appropriate default scheme. Fails if the +string given is not a syntactically valid uri scheme.

    +
    Params
    + +
    Return values
    +
      +
    • result
    • +
    +

    [method]outgoing-request.authority: func

    +

    Get the HTTP Authority for the Request. A value of none may be used +with Related Schemes which do not require an Authority. The HTTP and +HTTPS schemes always require an authority.

    +
    Params
    + +
    Return values
    +
      +
    • option<string>
    • +
    +

    [method]outgoing-request.set-authority: func

    +

    Set the HTTP Authority for the Request. A value of none may be used +with Related Schemes which do not require an Authority. The HTTP and +HTTPS schemes always require an authority. Fails if the string given is +not a syntactically valid uri authority.

    +
    Params
    + +
    Return values
    +
      +
    • result
    • +
    +

    [method]outgoing-request.headers: func

    +

    Get the headers associated with the Request.

    +

    The returned headers resource is immutable: set, append, and +delete operations will fail with header-error.immutable.

    +

    This headers resource is a child: it must be dropped before the parent +outgoing-request is dropped, or its ownership is transfered to +another component by e.g. outgoing-handler.handle.

    +
    Params
    + +
    Return values
    + +

    [constructor]request-options: func

    +

    Construct a default request-options value.

    +
    Return values
    + +

    [method]request-options.connect-timeout: func

    +

    The timeout for the initial connect to the HTTP Server.

    +
    Params
    + +
    Return values
    + +

    [method]request-options.set-connect-timeout: func

    +

    Set the timeout for the initial connect to the HTTP Server. An error +return value indicates that this timeout is not supported.

    +
    Params
    + +
    Return values
    +
      +
    • result
    • +
    +

    [method]request-options.first-byte-timeout: func

    +

    The timeout for receiving the first byte of the Response body.

    +
    Params
    + +
    Return values
    + +

    [method]request-options.set-first-byte-timeout: func

    +

    Set the timeout for receiving the first byte of the Response body. An +error return value indicates that this timeout is not supported.

    +
    Params
    + +
    Return values
    +
      +
    • result
    • +
    +

    [method]request-options.between-bytes-timeout: func

    +

    The timeout for receiving subsequent chunks of bytes in the Response +body stream.

    +
    Params
    + +
    Return values
    + +

    [method]request-options.set-between-bytes-timeout: func

    +

    Set the timeout for receiving subsequent chunks of bytes in the Response +body stream. An error return value indicates that this timeout is not +supported.

    +
    Params
    + +
    Return values
    +
      +
    • result
    • +
    +

    [static]response-outparam.set: func

    +

    Set the value of the response-outparam to either send a response, +or indicate an error.

    +

    This method consumes the response-outparam to ensure that it is +called at most once. If it is never called, the implementation +will respond with an error.

    +

    The user may provide an error to response to allow the +implementation determine how to respond with an HTTP error response.

    +
    Params
    + +

    [method]incoming-response.status: func

    +

    Returns the status code from the incoming response.

    +
    Params
    + +
    Return values
    + +

    [method]incoming-response.headers: func

    +

    Returns the headers from the incoming response.

    +

    The returned headers resource is immutable: set, append, and +delete operations will fail with header-error.immutable.

    +

    This headers resource is a child: it must be dropped before the parent +incoming-response is dropped.

    +
    Params
    + +
    Return values
    + +

    [method]incoming-response.consume: func

    +

    Returns the incoming body. May be called at most once. Returns error +if called additional times.

    +
    Params
    + +
    Return values
    + +

    [method]incoming-body.stream: func

    +

    Returns the contents of the body, as a stream of bytes.

    +

    Returns success on first call: the stream representing the contents +can be retrieved at most once. Subsequent calls will return error.

    +

    The returned input-stream resource is a child: it must be dropped +before the parent incoming-body is dropped, or consumed by +incoming-body.finish.

    +

    This invariant ensures that the implementation can determine whether +the user is consuming the contents of the body, waiting on the +future-trailers to be ready, or neither. This allows for network +backpressure is to be applied when the user is consuming the body, +and for that backpressure to not inhibit delivery of the trailers if +the user does not read the entire body.

    +
    Params
    + +
    Return values
    + +

    [static]incoming-body.finish: func

    +

    Takes ownership of incoming-body, and returns a future-trailers. +This function will trap if the input-stream child is still alive.

    +
    Params
    + +
    Return values
    + +

    [method]future-trailers.subscribe: func

    +

    Returns a pollable which becomes ready when either the trailers have +been received, or an error has occured. When this pollable is ready, +the get method will return some.

    +
    Params
    + +
    Return values
    + +

    [method]future-trailers.get: func

    +

    Returns the contents of the trailers, or an error which occured, +once the future is ready.

    +

    The outer option represents future readiness. Users can wait on this +option to become some using the subscribe method.

    +

    The outer result is used to retrieve the trailers or error at most +once. It will be success on the first call in which the outer option +is some, and error on subsequent calls.

    +

    The inner result represents that either the HTTP Request or Response +body, as well as any trailers, were received successfully, or that an +error occured receiving them. The optional trailers indicates whether +or not trailers were present in the body.

    +

    When some trailers are returned by this method, the trailers +resource is immutable, and a child. Use of the set, append, or +delete methods will return an error, and the resource must be +dropped before the parent future-trailers is dropped.

    +
    Params
    + +
    Return values
    + +

    [constructor]outgoing-response: func

    +

    Construct an outgoing-response, with a default status-code of 200. +If a different status-code is needed, it must be set via the +set-status-code method.

    +
      +
    • headers is the HTTP Headers for the Response.
    • +
    +
    Params
    + +
    Return values
    + +

    [method]outgoing-response.status-code: func

    +

    Get the HTTP Status Code for the Response.

    +
    Params
    + +
    Return values
    + +

    [method]outgoing-response.set-status-code: func

    +

    Set the HTTP Status Code for the Response. Fails if the status-code +given is not a valid http status code.

    +
    Params
    + +
    Return values
    +
      +
    • result
    • +
    +

    [method]outgoing-response.headers: func

    +

    Get the headers associated with the Request.

    +

    The returned headers resource is immutable: set, append, and +delete operations will fail with header-error.immutable.

    +

    This headers resource is a child: it must be dropped before the parent +outgoing-request is dropped, or its ownership is transfered to +another component by e.g. outgoing-handler.handle.

    +
    Params
    + +
    Return values
    + +

    [method]outgoing-response.body: func

    +

    Returns the resource corresponding to the outgoing Body for this Response.

    +

    Returns success on the first call: the outgoing-body resource for +this outgoing-response can be retrieved at most once. Subsequent +calls will return error.

    +
    Params
    + +
    Return values
    + +

    [method]outgoing-body.write: func

    +

    Returns a stream for writing the body contents.

    +

    The returned output-stream is a child resource: it must be dropped +before the parent outgoing-body resource is dropped (or finished), +otherwise the outgoing-body drop or finish will trap.

    +

    Returns success on the first call: the output-stream resource for +this outgoing-body may be retrieved at most once. Subsequent calls +will return error.

    +
    Params
    + +
    Return values
    + +

    [static]outgoing-body.finish: func

    +

    Finalize an outgoing body, optionally providing trailers. This must be +called to signal that the response is complete. If the outgoing-body +is dropped without calling outgoing-body.finalize, the implementation +should treat the body as corrupted.

    +

    Fails if the body's outgoing-request or outgoing-response was +constructed with a Content-Length header, and the contents written +to the body (via write) does not match the value given in the +Content-Length.

    +
    Params
    + +
    Return values
    + +

    [method]future-incoming-response.subscribe: func

    +

    Returns a pollable which becomes ready when either the Response has +been received, or an error has occured. When this pollable is ready, +the get method will return some.

    +
    Params
    + +
    Return values
    + +

    [method]future-incoming-response.get: func

    +

    Returns the incoming HTTP Response, or an error, once one is ready.

    +

    The outer option represents future readiness. Users can wait on this +option to become some using the subscribe method.

    +

    The outer result is used to retrieve the response or error at most +once. It will be success on the first call in which the outer option +is some, and error on subsequent calls.

    +

    The inner result represents that either the incoming HTTP Response +status and headers have recieved successfully, or that an error +occured. Errors may also occur while consuming the response body, +but those will be reported by the incoming-body and its +output-stream child.

    +
    Params
    + +
    Return values
    + +

    Import interface wasi:http/outgoing-handler@0.2.0

    +

    This interface defines a handler of outgoing HTTP Requests. It should be +imported by components which wish to make HTTP Requests.

    +
    +

    Types

    +

    type outgoing-request

    +

    outgoing-request

    +

    +#### `type request-options` +[`request-options`](#request_options) +

    +#### `type future-incoming-response` +[`future-incoming-response`](#future_incoming_response) +

    +#### `type error-code` +[`error-code`](#error_code) +

    +---- +

    Functions

    +

    handle: func

    +

    This function is invoked with an outgoing HTTP Request, and it returns +a resource future-incoming-response which represents an HTTP Response +which may arrive in the future.

    +

    The options argument accepts optional parameters for the HTTP +protocol's transport layer.

    +

    This function may return an error if the outgoing-request is invalid +or not allowed to be made. Otherwise, protocol errors are reported +through the future-incoming-response.

    +
    Params
    + +
    Return values
    + +

    Import interface wasi:clocks/wall-clock@0.2.0

    +

    WASI Wall Clock is a clock API intended to let users query the current +time. The name "wall" makes an analogy to a "clock on the wall", which +is not necessarily monotonic as it may be reset.

    +

    It is intended to be portable at least between Unix-family platforms and +Windows.

    +

    A wall clock is a clock which measures the date and time according to +some external reference.

    +

    External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time.

    +

    It is intended for reporting the current date and time for humans.

    +
    +

    Types

    +

    record datetime

    +

    A time and date in seconds plus nanoseconds.

    +
    Record Fields
    +
      +
    • seconds: u64
    • +
    • nanoseconds: u32
    • +
    +
    +

    Functions

    +

    now: func

    +

    Read the current value of the clock.

    +

    This clock is not monotonic, therefore calling this function repeatedly +will not necessarily produce a sequence of non-decreasing values.

    +

    The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, +also known as Unix Time.

    +

    The nanoseconds field of the output is always less than 1000000000.

    +
    Return values
    + +

    resolution: func

    +

    Query the resolution of the clock.

    +

    The nanoseconds field of the output is always less than 1000000000.

    +
    Return values
    + diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 5a249a419..b3945ad44 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -6,15 +6,15 @@ outgoing HTTP requests.

    -

    Import interface wasi:random/random@0.2.0

    -

    WASI Random is a random data API.

    +

    Import interface wasi:io/poll@0.2.0

    +

    A poll API intended to let users wait for I/O events on multiple handles +at once.

    +
    +

    Types

    +

    resource pollable

    +

    pollable represents a single I/O event which may be ready, or not.

    +

    Functions

    +

    [method]pollable.ready: func

    +

    Return the readiness of a pollable. This function never blocks.

    +

    Returns true when the pollable is ready, and false otherwise.

    +
    Params
    + +
    Return values
    +
      +
    • bool
    • +
    +

    [method]pollable.block: func

    +

    block returns immediately if the pollable is ready, and otherwise +blocks until ready.

    +

    This function is equivalent to calling poll.poll on a list +containing only this pollable.

    +
    Params
    + +

    poll: func

    +

    Poll for completion on a set of pollables.

    +

    This function takes a list of pollables, which identify I/O sources of +interest, and waits until one or more of the events is ready for I/O.

    +

    The result list<u32> contains one or more indices of handles in the +argument list that is ready for I/O.

    +

    If the list contains more elements than can be indexed with a u32 +value, this function traps.

    +

    A timeout can be implemented by adding a pollable from the +wasi-clocks API to the list.

    +

    This function does not return a result; polling in itself does not +do any I/O so it doesn't fail. If any of the I/O sources identified by +the pollables has an error, it is indicated by marking the source as +being reaedy for I/O.

    +
    Params
    + +
    Return values
    +
      +
    • list<u32>
    • +
    +

    Import interface wasi:clocks/monotonic-clock@0.2.0

    +

    WASI Monotonic Clock is a clock API intended to let users measure elapsed +time.

    It is intended to be portable at least between Unix-family platforms and Windows.

    +

    A monotonic clock is a clock which has an unspecified initial value, and +successive reads of the clock will produce non-decreasing values.

    +

    It is intended for measuring elapsed time.

    +
    +

    Types

    +

    type pollable

    +

    pollable

    +

    +#### `type instant` +`u64` +

    An instant in time, in nanoseconds. An instant is relative to an +unspecified initial value, and can only be compared to instances from +the same monotonic-clock. +

    type duration

    +

    u64

    +

    A duration of time, in nanoseconds.


    Functions

    -

    get-random-bytes: func

    -

    Return len cryptographically-secure random or pseudo-random bytes.

    -

    This function must produce data at least as cryptographically secure and -fast as an adequately seeded cryptographically-secure pseudo-random -number generator (CSPRNG). It must not block, from the perspective of -the calling program, under any circumstances, including on the first -request and on requests for numbers of bytes. The returned data must -always be unpredictable.

    -

    This function must always return fresh data. Deterministic environments -must omit this function, rather than implementing it with deterministic -data.

    +

    now: func

    +

    Read the current value of the clock.

    +

    The clock is monotonic, therefore calling this function repeatedly will +produce a sequence of non-decreasing values.

    +
    Return values
    + +

    resolution: func

    +

    Query the resolution of the clock. Returns the duration of time +corresponding to a clock tick.

    +
    Return values
    + +

    subscribe-instant: func

    +

    Create a pollable which will resolve once the specified instant +occured.

    Params
    Return values
    +

    subscribe-duration: func

    +

    Create a pollable which will resolve once the given duration has +elapsed, starting at the time at which this function was called. +occured.

    +
    Params
    + -

    get-random-u64: func

    -

    Return a cryptographically-secure random or pseudo-random u64 value.

    -

    This function returns the same type of data as get-random-bytes, -represented as a u64.

    Return values
    -

    Import interface wasi:io/error@0.2.0

    +

    Import interface wasi:io/error@0.2.0


    Types

    -

    resource error

    +

    resource error

    A resource which represents some error information.

    The only method provided by this resource is to-debug-string, which provides some human-readable information about the error.

    @@ -78,7 +156,7 @@ error-code type, using the function

    The set of functions which can "downcast" an error into a more concrete type is open.

    Functions

    -

    [method]error.to-debug-string: func

    +

    [method]error.to-debug-string: func

    Returns a string that is suitable to assist humans in debugging this error.

    WARNING: The returned string should not be consumed mechanically! @@ -87,92 +165,42 @@ details. Parsing this string is a major platform-compatibility hazard.

    Params
    Return values
    • string
    -

    Import interface wasi:io/poll@0.2.0

    -

    A poll API intended to let users wait for I/O events on multiple handles -at once.

    -
    -

    Types

    -

    resource pollable

    -

    pollable represents a single I/O event which may be ready, or not.

    -

    Functions

    -

    [method]pollable.ready: func

    -

    Return the readiness of a pollable. This function never blocks.

    -

    Returns true when the pollable is ready, and false otherwise.

    -
    Params
    - -
    Return values
    -
      -
    • bool
    • -
    -

    [method]pollable.block: func

    -

    block returns immediately if the pollable is ready, and otherwise -blocks until ready.

    -

    This function is equivalent to calling poll.poll on a list -containing only this pollable.

    -
    Params
    - -

    poll: func

    -

    Poll for completion on a set of pollables.

    -

    This function takes a list of pollables, which identify I/O sources of -interest, and waits until one or more of the events is ready for I/O.

    -

    The result list<u32> contains one or more indices of handles in the -argument list that is ready for I/O.

    -

    If the list contains more elements than can be indexed with a u32 -value, this function traps.

    -

    A timeout can be implemented by adding a pollable from the -wasi-clocks API to the list.

    -

    This function does not return a result; polling in itself does not -do any I/O so it doesn't fail. If any of the I/O sources identified by -the pollables has an error, it is indicated by marking the source as -being reaedy for I/O.

    -
    Params
    - -
    Return values
    -
      -
    • list<u32>
    • -
    -

    Import interface wasi:io/streams@0.2.0

    +

    Import interface wasi:io/streams@0.2.0

    WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

    In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


    Types

    -

    type error

    +

    type error

    error

    -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

    -#### `variant stream-error` +#### `variant stream-error`

    An error for input-stream and output-stream operations.

    Variant Cases
    • -

      last-operation-failed: own<error>

      +

      last-operation-failed: own<error>

      The last operation (a write or flush) failed before completion.

      More information is available in the error payload.

    • -

      closed

      +

      closed

      The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

    -

    resource input-stream

    +

    resource input-stream

    An input bytestream.

    input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are @@ -180,7 +208,7 @@ promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

    -

    resource output-stream

    +

    resource output-stream

    An output bytestream.

    output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also @@ -189,7 +217,7 @@ promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

    Functions

    -

    [method]input-stream.read: func

    +

    [method]input-stream.read: func

    Perform a non-blocking read from the stream.

    When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -213,51 +241,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

    Params
    Return values
    -

    [method]input-stream.blocking-read: func

    +

    [method]input-stream.blocking-read: func

    Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

    Params
    Return values
    -

    [method]input-stream.skip: func

    +

    [method]input-stream.skip: func

    Skip bytes from a stream. Returns number of bytes skipped.

    Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

    Params
    Return values
    -

    [method]input-stream.blocking-skip: func

    +

    [method]input-stream.blocking-skip: func

    Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

    Params
    Return values
    -

    [method]input-stream.subscribe: func

    +

    [method]input-stream.subscribe: func

    Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -266,13 +294,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

    Params
    Return values
    -

    [method]output-stream.check-write: func

    +

    [method]output-stream.check-write: func

    Check readiness for writing. This function never blocks.

    Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -282,13 +310,13 @@ become ready when this function will report at least 1 byte, or an error.

    Params
    Return values
    -

    [method]output-stream.write: func

    +

    [method]output-stream.write: func

    Perform a write. This function never blocks.

    When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -301,14 +329,14 @@ length of less than or equal to n. Otherwise, this function will trap.

    the last call to check-write provided a permit.

    Params
    Return values
    -

    [method]output-stream.blocking-write-and-flush: func

    +

    [method]output-stream.blocking-write-and-flush: func

    Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

    This is a convenience wrapper around the use of check-write, @@ -332,14 +360,14 @@ let _ = this.check-write(); // eliding error handling

    Params
    Return values
    -

    [method]output-stream.flush: func

    +

    [method]output-stream.flush: func

    Request to flush buffered output. This function never blocks.

    This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -350,24 +378,24 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

    Params
    Return values
    -

    [method]output-stream.blocking-flush: func

    +

    [method]output-stream.blocking-flush: func

    Request to flush buffered output, and block until flush completes and stream is ready for writing again.

    Params
    Return values
    -

    [method]output-stream.subscribe: func

    +

    [method]output-stream.subscribe: func

    Create a pollable which will resolve once the output-stream is ready for more writing, or an error has occured. When this pollable is ready, check-write will return ok(n) with n>0, or an @@ -378,13 +406,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

    Params
    Return values
    -

    [method]output-stream.write-zeroes: func

    +

    [method]output-stream.write-zeroes: func

    Write zeroes to a stream.

    This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -392,14 +420,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

    Params
    Return values
    -

    [method]output-stream.blocking-write-zeroes-and-flush: func

    +

    [method]output-stream.blocking-write-zeroes-and-flush: func

    Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

    @@ -423,14 +451,14 @@ let _ = this.check-write(); // eliding error handling
    Params
    Return values
    -

    [method]output-stream.splice: func

    +

    [method]output-stream.splice: func

    Read from one stream and write to another.

    The behavior of splice is equivelant to:

      @@ -445,275 +473,175 @@ let _ = this.check-write(); // eliding error handling than len.

      Params
      Return values
      -

      [method]output-stream.blocking-splice: func

      +

      [method]output-stream.blocking-splice: func

      Read from one stream and write to another, with blocking.

      This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

      Params
      Return values
      -

      Import interface wasi:cli/stdout@0.2.0

      -
      -

      Types

      -

      type output-stream

      -

      output-stream

      -

      ----- -

      Functions

      -

      get-stdout: func

      -
      Return values
      - -

      Import interface wasi:cli/stderr@0.2.0

      -
      -

      Types

      -

      type output-stream

      -

      output-stream

      -

      ----- -

      Functions

      -

      get-stderr: func

      -
      Return values
      - -

      Import interface wasi:cli/stdin@0.2.0

      -
      -

      Types

      -

      type input-stream

      -

      input-stream

      -

      ----- -

      Functions

      -

      get-stdin: func

      -
      Return values
      - -

      Import interface wasi:clocks/monotonic-clock@0.2.0

      -

      WASI Monotonic Clock is a clock API intended to let users measure elapsed -time.

      -

      It is intended to be portable at least between Unix-family platforms and -Windows.

      -

      A monotonic clock is a clock which has an unspecified initial value, and -successive reads of the clock will produce non-decreasing values.

      -

      It is intended for measuring elapsed time.

      -
      -

      Types

      -

      type pollable

      -

      pollable

      -

      -#### `type instant` -`u64` -

      An instant in time, in nanoseconds. An instant is relative to an -unspecified initial value, and can only be compared to instances from -the same monotonic-clock. -

      type duration

      -

      u64

      -

      A duration of time, in nanoseconds. -


      -

      Functions

      -

      now: func

      -

      Read the current value of the clock.

      -

      The clock is monotonic, therefore calling this function repeatedly will -produce a sequence of non-decreasing values.

      -
      Return values
      - -

      resolution: func

      -

      Query the resolution of the clock. Returns the duration of time -corresponding to a clock tick.

      -
      Return values
      - -

      subscribe-instant: func

      -

      Create a pollable which will resolve once the specified instant -occured.

      -
      Params
      - -
      Return values
      - -

      subscribe-duration: func

      -

      Create a pollable which will resolve once the given duration has -elapsed, starting at the time at which this function was called. -occured.

      -
      Params
      - -
      Return values
      - -

      Import interface wasi:http/types@0.2.0

      +

      Import interface wasi:http/types@0.2.0

      This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.


      Types

      -

      type duration

      +

      type duration

      duration

      -#### `type input-stream` +#### `type input-stream` [`input-stream`](#input_stream)

      -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

      -#### `type io-error` +#### `type io-error` [`error`](#error)

      -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

      -#### `variant method` +#### `variant method`

      This type corresponds to HTTP standard Methods.

      Variant Cases
      -

      variant scheme

      +
    1. get
    2. +
    3. head
    4. +
    5. post
    6. +
    7. put
    8. +
    9. delete
    10. +
    11. connect
    12. +
    13. options
    14. +
    15. trace
    16. +
    17. patch
    18. +
    19. other: string
    20. + +

      variant scheme

      This type corresponds to HTTP standard Related Schemes.

      Variant Cases
      -

      record DNS-error-payload

      +

      record DNS-error-payload

      Defines the case payload type for DNS-error above:

      Record Fields
        -
      • rcode: option<string>
      • -
      • info-code: option<u16>
      • +
      • rcode: option<string>
      • +
      • info-code: option<u16>
      -

      record TLS-alert-received-payload

      +

      record TLS-alert-received-payload

      Defines the case payload type for TLS-alert-received above:

      Record Fields
        -
      • alert-id: option<u8>
      • -
      • alert-message: option<string>
      • +
      • alert-id: option<u8>
      • +
      • alert-message: option<string>
      -

      record field-size-payload

      +

      record field-size-payload

      Defines the case payload type for HTTP-response-{header,trailer}-size above:

      Record Fields
        -
      • field-name: option<string>
      • -
      • field-size: option<u32>
      • +
      • field-name: option<string>
      • +
      • field-size: option<u32>
      -

      variant error-code

      +

      variant error-code

      These cases are inspired by the IANA HTTP Proxy Error Types: https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types

      Variant Cases
      -

      variant header-error

      +

      variant header-error

      This type enumerates the different kinds of errors that may occur when setting or appending to a fields resource.

      Variant Cases
      • -

        invalid-syntax

        +

        invalid-syntax

        This error indicates that a `field-key` or `field-value` was syntactically invalid when used with an operation that sets headers in a `fields`.

      • -

        forbidden

        +

        forbidden

        This error indicates that a forbidden `field-key` was used when trying to set a header in a `fields`.

      • -

        immutable

        +

        immutable

        This error indicates that the operation on the `fields` was not permitted because the fields are immutable.

      -

      type field-key

      +

      type field-key

      string

      Field keys are always strings. -

      type field-value

      +

      type field-value

      field-value

      Field values should always be ASCII strings. However, in reality, HTTP implementations often have to interpret malformed values, so they are provided as a list of bytes. -

      resource fields

      +

      resource fields

      This following block defines the fields resource which corresponds to HTTP standard Fields. Fields are a common representation used for both Headers and Trailers.

      @@ -723,33 +651,33 @@ resource given by other means (including, but not limited to, incoming-request.headers, outgoing-request.headers) might be be immutable. In an immutable fields, the set, append, and delete operations will fail with header-error.immutable.

      -

      type headers

      +

      type headers

      fields

      Headers is an alias for Fields. -

      type trailers

      +

      type trailers

      fields

      Trailers is an alias for Fields. -

      resource incoming-request

      +

      resource incoming-request

      Represents an incoming HTTP Request.

      -

      resource outgoing-request

      +

      resource outgoing-request

      Represents an outgoing HTTP Request.

      -

      resource request-options

      +

      resource request-options

      Parameters for making an HTTP Request. Each of these parameters is currently an optional timeout applicable to the transport layer of the HTTP protocol.

      These timeouts are separate from any the user may use to bound a blocking call to wasi:io/poll.poll.

      -

      resource response-outparam

      +

      resource response-outparam

      Represents the ability to send an HTTP Response.

      This resource is used by the wasi:http/incoming-handler interface to allow a Response to be sent corresponding to the Request provided as the other argument to incoming-handler.handle.

      -

      type status-code

      +

      type status-code

      u16

      This type corresponds to the HTTP standard Status Code. -

      resource incoming-response

      +

      resource incoming-response

      Represents an incoming HTTP Response.

      -

      resource incoming-body

      +

      resource incoming-body

      Represents an incoming HTTP Request or Response's Body.

      A body has both its contents - a stream of bytes - and a (possibly empty) set of trailers, indicating that the full contents of the @@ -757,14 +685,14 @@ body have been received. This resource represents the contents as an input-stream and the delivery of trailers as a future-trailers, and ensures that the user of this interface may only be consuming either the body contents or waiting on trailers at any given time.

      -

      resource future-trailers

      +

      resource future-trailers

      Represents a future which may eventaully return trailers, or an error.

      In the case that the incoming HTTP Request or Response did not have any trailers, this future will resolve to the empty set of trailers once the complete Request or Response body has been received.

      -

      resource outgoing-response

      +

      resource outgoing-response

      Represents an outgoing HTTP Response.

      -

      resource outgoing-body

      +

      resource outgoing-body

      Represents an outgoing HTTP Request or Response's Body.

      A body has both its contents - a stream of bytes - and a (possibly empty) set of trailers, inducating the full contents of the body @@ -779,13 +707,13 @@ and that an error has occured. The implementation should propogate this error to the HTTP protocol by whatever means it has available, including: corrupting the body on the wire, aborting the associated Request, or sending a late status code for the Response.

      -

      resource future-incoming-response

      +

      resource future-incoming-response

      Represents a future which may eventaully return an incoming HTTP Response, or an error.

      This resource is returned by the wasi:http/outgoing-handler interface to provide the HTTP Response corresponding to the sent Request.

      Functions

      -

      http-error-code: func

      +

      http-error-code: func

      Attempts to extract a http-related error from the wasi:io error provided.

      Stream operations which return @@ -797,20 +725,20 @@ if there's http-related information about the error to return.

      http-related errors.

      Params
      Return values
      -

      [constructor]fields: func

      +

      [constructor]fields: func

      Construct an empty HTTP Fields.

      The resulting fields is mutable.

      Return values
      -

      [static]fields.from-list: func

      +

      [static]fields.from-list: func

      Construct an HTTP Fields.

      The resulting fields is mutable.

      The list represents each key-value pair in the Fields. Keys @@ -824,80 +752,80 @@ well-formed, so they are represented as a raw list of bytes.

      syntactically invalid, or if a header was forbidden.

      Params
      Return values
      -

      [method]fields.get: func

      +

      [method]fields.get: func

      Get all of the values corresponding to a key. If the key is not present in this fields, an empty list is returned. However, if the key is present but empty, this is represented by a list with one or more empty field-values present.

      Params
      Return values
      -

      [method]fields.has: func

      +

      [method]fields.has: func

      Returns true when the key is present in this fields. If the key is syntactically invalid, false is returned.

      Params
      Return values
      • bool
      -

      [method]fields.set: func

      +

      [method]fields.set: func

      Set all of the values for a key. Clears any existing values for that key, if they have been set.

      Fails with header-error.immutable if the fields are immutable.

      Params
      Return values
      -

      [method]fields.delete: func

      +

      [method]fields.delete: func

      Delete all values for a key. Does nothing if no values for the key exist.

      Fails with header-error.immutable if the fields are immutable.

      Params
      Return values
      -

      [method]fields.append: func

      +

      [method]fields.append: func

      Append a value for a key. Does not change or delete any existing values for that key.

      Fails with header-error.immutable if the fields are immutable.

      Params
      Return values
      -

      [method]fields.entries: func

      +

      [method]fields.entries: func

      Retrieve the full set of keys and values in the Fields. Like the constructor, the list represents each key-value pair.

      The outer list represents each key-value pair in the Fields. Keys @@ -905,65 +833,65 @@ which have multiple values are represented by multiple entries in this list with the same key.

      Params
      Return values
      -

      [method]fields.clone: func

      +

      [method]fields.clone: func

      Make a deep copy of the Fields. Equivelant in behavior to calling the fields constructor on the return value of entries. The resulting fields is mutable.

      Params
      Return values
      -

      [method]incoming-request.method: func

      +

      [method]incoming-request.method: func

      Returns the method of the incoming request.

      Params
      Return values
      -

      [method]incoming-request.path-with-query: func

      +

      [method]incoming-request.path-with-query: func

      Returns the path with query parameters from the request, as a string.

      Params
      Return values
      • option<string>
      -

      [method]incoming-request.scheme: func

      +

      [method]incoming-request.scheme: func

      Returns the protocol scheme from the request.

      Params
      Return values
      -

      [method]incoming-request.authority: func

      +

      [method]incoming-request.authority: func

      Returns the authority from the request, if it was present.

      Params
      Return values
      • option<string>
      -

      [method]incoming-request.headers: func

      +

      [method]incoming-request.headers: func

      Get the headers associated with the request.

      The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

      @@ -972,24 +900,24 @@ the parent incoming-request is drop incoming-request before all children are dropped will trap.

      Params
      Return values
      -

      [method]incoming-request.consume: func

      +

      [method]incoming-request.consume: func

      Gives the incoming-body associated with this request. Will only return success at most once, and subsequent calls will return error.

      Params
      Return values
      -

      [constructor]outgoing-request: func

      +

      [constructor]outgoing-request: func

      Construct a new outgoing-request with a default method of GET, and none values for path-with-query, scheme, and authority.

      Params
      Return values
      -

      [method]outgoing-response.status-code: func

      +

      [method]outgoing-response.status-code: func

      Get the HTTP Status Code for the Response.

      Params
      Return values
      -

      [method]outgoing-response.set-status-code: func

      +

      [method]outgoing-response.set-status-code: func

      Set the HTTP Status Code for the Response. Fails if the status-code given is not a valid http status code.

      Params
      Return values
      • result
      -

      [method]outgoing-response.headers: func

      +

      [method]outgoing-response.headers: func

      Get the headers associated with the Request.

      The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

      @@ -1369,26 +1297,26 @@ given is not a valid http status code.

      another component by e.g. outgoing-handler.handle.

      Params
      Return values
      -

      [method]outgoing-response.body: func

      +

      [method]outgoing-response.body: func

      Returns the resource corresponding to the outgoing Body for this Response.

      Returns success on the first call: the outgoing-body resource for this outgoing-response can be retrieved at most once. Subsequent calls will return error.

      Params
      Return values
      -

      [method]outgoing-body.write: func

      +

      [method]outgoing-body.write: func

      Returns a stream for writing the body contents.

      The returned output-stream is a child resource: it must be dropped before the parent outgoing-body resource is dropped (or finished), @@ -1398,13 +1326,13 @@ this outgoing-body may be retrieved at will return error.

      Params
      Return values
      -

      [static]outgoing-body.finish: func

      +

      [static]outgoing-body.finish: func

      Finalize an outgoing body, optionally providing trailers. This must be called to signal that the response is complete. If the outgoing-body is dropped without calling outgoing-body.finalize, the implementation @@ -1415,26 +1343,26 @@ to the body (via write) does not match the value given in the Content-Length.

      Params
      Return values
      -

      [method]future-incoming-response.subscribe: func

      +

      [method]future-incoming-response.subscribe: func

      Returns a pollable which becomes ready when either the Response has been received, or an error has occured. When this pollable is ready, the get method will return some.

      Params
      Return values
      -

      [method]future-incoming-response.get: func

      +

      [method]future-incoming-response.get: func

      Returns the incoming HTTP Response, or an error, once one is ready.

      The outer option represents future readiness. Users can wait on this option to become some using the subscribe method.

      @@ -1448,32 +1376,104 @@ but those will be reported by the incoming-bodyoutput-stream child.

      Params
      Return values
      -

      Import interface wasi:http/outgoing-handler@0.2.0

      +

      Import interface wasi:random/random@0.2.0

      +

      WASI Random is a random data API.

      +

      It is intended to be portable at least between Unix-family platforms and +Windows.

      +
      +

      Functions

      +

      get-random-bytes: func

      +

      Return len cryptographically-secure random or pseudo-random bytes.

      +

      This function must produce data at least as cryptographically secure and +fast as an adequately seeded cryptographically-secure pseudo-random +number generator (CSPRNG). It must not block, from the perspective of +the calling program, under any circumstances, including on the first +request and on requests for numbers of bytes. The returned data must +always be unpredictable.

      +

      This function must always return fresh data. Deterministic environments +must omit this function, rather than implementing it with deterministic +data.

      +
      Params
      +
        +
      • len: u64
      • +
      +
      Return values
      +
        +
      • list<u8>
      • +
      +

      get-random-u64: func

      +

      Return a cryptographically-secure random or pseudo-random u64 value.

      +

      This function returns the same type of data as get-random-bytes, +represented as a u64.

      +
      Return values
      +
        +
      • u64
      • +
      +

      Import interface wasi:cli/stdout@0.2.0

      +
      +

      Types

      +

      type output-stream

      +

      output-stream

      +

      +---- +

      Functions

      +

      get-stdout: func

      +
      Return values
      + +

      Import interface wasi:cli/stderr@0.2.0

      +
      +

      Types

      +

      type output-stream

      +

      output-stream

      +

      +---- +

      Functions

      +

      get-stderr: func

      +
      Return values
      + +

      Import interface wasi:cli/stdin@0.2.0

      +
      +

      Types

      +

      type input-stream

      +

      input-stream

      +

      +---- +

      Functions

      +

      get-stdin: func

      +
      Return values
      + +

      Import interface wasi:http/outgoing-handler@0.2.0

      This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


      Types

      -

      type outgoing-request

      +

      type outgoing-request

      outgoing-request

      -#### `type request-options` +#### `type request-options` [`request-options`](#request_options)

      -#### `type future-incoming-response` +#### `type future-incoming-response` [`future-incoming-response`](#future_incoming_response)

      -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

      ----

      Functions

      -

      handle: func

      +

      handle: func

      This function is invoked with an outgoing HTTP Request, and it returns a resource future-incoming-response which represents an HTTP Response which may arrive in the future.

      @@ -1484,14 +1484,14 @@ or not allowed to be made. Otherwise, protocol errors are reported through the future-incoming-response.

      Params
      Return values
      -

      Import interface wasi:clocks/wall-clock@0.2.0

      +

      Import interface wasi:clocks/wall-clock@0.2.0

      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

      @@ -1504,16 +1504,16 @@ monotonic, making it unsuitable for measuring elapsed time.

      It is intended for reporting the current date and time for humans.


      Types

      -

      record datetime

      +

      record datetime

      A time and date in seconds plus nanoseconds.

      Record Fields

      Functions

      -

      now: func

      +

      now: func

      Read the current value of the clock.

      This clock is not monotonic, therefore calling this function repeatedly will not necessarily produce a sequence of non-decreasing values.

      @@ -1525,25 +1525,25 @@ also known as Unix Time.
    21. datetime
    22. -

      resolution: func

      +

      resolution: func

      Query the resolution of the clock.

      The nanoseconds field of the output is always less than 1000000000.

      Return values
      -

      Export interface wasi:http/incoming-handler@0.2.0

      +

      Export interface wasi:http/incoming-handler@0.2.0


      Types

      -

      type incoming-request

      +

      type incoming-request

      incoming-request

      -#### `type response-outparam` +#### `type response-outparam` [`response-outparam`](#response_outparam)

      ----

      Functions

      -

      handle: func

      +

      handle: func

      This function is invoked with an incoming HTTP Request, and a resource response-outparam which provides the capability to reply with an HTTP Response. The response is sent by calling the response-outparam.set @@ -1555,6 +1555,6 @@ work.

      with an error on its behalf.

      Params
      diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 687c24d23..dac5c9613 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,10 +1,8 @@ package wasi:http@0.2.0; -/// The `wasi:http/proxy` world captures a widely-implementable intersection of -/// hosts that includes HTTP forward and reverse proxies. Components targeting -/// this world may concurrently stream in and out any number of incoming and -/// outgoing HTTP requests. -world proxy { +/// The `wasi:http/imports` world imports all the APIs for HTTP proxies. +/// Is is intended to be `include`d in other worlds. +world imports { /// HTTP proxies have access to time and randomness. include wasi:clocks/imports@0.2.0; import wasi:random/random@0.2.0; @@ -23,6 +21,14 @@ world proxy { /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). import outgoing-handler; +} + +/// The `wasi:http/proxy` world captures a widely-implementable intersection of +/// hosts that includes HTTP forward and reverse proxies. Components targeting +/// this world may concurrently stream in and out any number of incoming and +/// outgoing HTTP requests. +world proxy { + include imports; /// The host delivers incoming HTTP requests to a component by calling the /// `handle` function of this exported interface. A host may arbitrarily reuse From 61bfb4864e289eac92ea6703b0390f59cdb4f2b7 Mon Sep 17 00:00:00 2001 From: "Jiaxiao Zhou (Mossaka)" Date: Thu, 8 Feb 2024 13:15:06 -0800 Subject: [PATCH 1426/1772] pin wit-bindgen 0.17.0 Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/http/.github/workflows/main.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index c5740dc1c..bbd477f43 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -17,3 +17,6 @@ jobs: chmod +x ./wit-deps ./wit-deps lock --check - uses: WebAssembly/wit-abi-up-to-date@v17 + with: + wit-bindgen: '0.17.0' + worlds: 'imports proxy' \ No newline at end of file From c0f0e79fa71d6f62a1cdf58f4032401e7b7efce8 Mon Sep 17 00:00:00 2001 From: Jiaxiao Zhou Date: Thu, 8 Feb 2024 18:09:04 -0800 Subject: [PATCH 1427/1772] Update wit/proxy.wit Co-authored-by: Luke Wagner --- proposals/http/wit/proxy.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index dac5c9613..26a975eb1 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,7 +1,7 @@ package wasi:http@0.2.0; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. -/// Is is intended to be `include`d in other worlds. +/// It is intended to be `include`d in other worlds. world imports { /// HTTP proxies have access to time and randomness. include wasi:clocks/imports@0.2.0; From 771f7f1104b3b340674d7bcbb73b8eed63f45a08 Mon Sep 17 00:00:00 2001 From: "Jiaxiao Zhou (Mossaka)" Date: Sat, 10 Feb 2024 17:53:30 -0800 Subject: [PATCH 1428/1772] re-generate the markdown Signed-off-by: Jiaxiao Zhou (Mossaka) --- proposals/http/imports.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index 0493c522d..5dff42af7 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -1,6 +1,6 @@

      World imports

      The wasi:http/imports world imports all the APIs for HTTP proxies. -Is is intended to be included in other worlds.

      +It is intended to be included in other worlds.

      • Imports:
          From 7f21dd6bb1678ea97d47210871e99a4e557e4e4a Mon Sep 17 00:00:00 2001 From: "Adam C. Foltzer" Date: Tue, 20 Feb 2024 14:35:05 -0800 Subject: [PATCH 1429/1772] Tweak a few `fields` docs (#99) * Tweak a few `fields` docs - This patch clarifies the behavior of the various `fields` methods when syntactically invalid inputs are given. Some methods already noted this, but `get` in particular was missing a clarification that an invalid key would result in an empty list result - Removed some text in the doc for `from-list`. While non-UTF-8 values are not preferred for new applications, they are syntactically valid due to the [`obs-text` production](https://www.rfc-editor.org/rfc/rfc9110#section-5.5-2) in the RFC grammar. * regenerate markdown --- proposals/http/proxy.md | 20 ++++++++++++-------- proposals/http/wit/types.wit | 23 +++++++++++++++-------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index b3945ad44..f1787e7d0 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -745,11 +745,9 @@ http-related errors.

          which have multiple values are represented by multiple entries in this list with the same key.

          The tuple is a pair of the field key, represented as a string, and -Value, represented as a list of bytes. In a valid Fields, all keys -and values are valid UTF-8 strings. However, values are not always -well-formed, so they are represented as a raw list of bytes.

          -

          An error result will be returned if any header or value was -syntactically invalid, or if a header was forbidden.

          +Value, represented as a list of bytes.

          +

          An error result will be returned if any field-key or field-value is +syntactically invalid, or if a field is forbidden.

          Params
          • entries: list<(field-key, field-value)>
          • @@ -760,9 +758,9 @@ syntactically invalid, or if a header was forbidden.

          [method]fields.get: func

          Get all of the values corresponding to a key. If the key is not present -in this fields, an empty list is returned. However, if the key is -present but empty, this is represented by a list with one or more -empty field-values present.

          +in this fields or is syntactically invalid, an empty list is returned. +However, if the key is present but empty, this is represented by a list +with one or more empty field-values present.

          Params
          • self: borrow<fields>
          • @@ -788,6 +786,8 @@ syntactically invalid, false is returned.

            Set all of the values for a key. Clears any existing values for that key, if they have been set.

            Fails with header-error.immutable if the fields are immutable.

            +

            Fails with header-error.invalid-syntax if the field-key or any of +the field-values are syntactically invalid.

            Params
            • self: borrow<fields>
            • @@ -802,6 +802,8 @@ key, if they have been set.

              Delete all values for a key. Does nothing if no values for the key exist.

              Fails with header-error.immutable if the fields are immutable.

              +

              Fails with header-error.invalid-syntax if the field-key is +syntactically invalid.

              Params
              • self: borrow<fields>
              • @@ -815,6 +817,8 @@ exist.

                Append a value for a key. Does not change or delete any existing values for that key.

                Fails with header-error.immutable if the fields are immutable.

                +

                Fails with header-error.invalid-syntax if the field-key or +field-value are syntactically invalid.

                Params
                • self: borrow<fields>
                • diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 755ac6a6b..70cce5526 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -159,20 +159,18 @@ interface types { /// list with the same key. /// /// The tuple is a pair of the field key, represented as a string, and - /// Value, represented as a list of bytes. In a valid Fields, all keys - /// and values are valid UTF-8 strings. However, values are not always - /// well-formed, so they are represented as a raw list of bytes. + /// Value, represented as a list of bytes. /// - /// An error result will be returned if any header or value was - /// syntactically invalid, or if a header was forbidden. + /// An error result will be returned if any `field-key` or `field-value` is + /// syntactically invalid, or if a field is forbidden. from-list: static func( entries: list> ) -> result; /// Get all of the values corresponding to a key. If the key is not present - /// in this `fields`, an empty list is returned. However, if the key is - /// present but empty, this is represented by a list with one or more - /// empty field-values present. + /// in this `fields` or is syntactically invalid, an empty list is returned. + /// However, if the key is present but empty, this is represented by a list + /// with one or more empty field-values present. get: func(name: field-key) -> list; /// Returns `true` when the key is present in this `fields`. If the key is @@ -183,18 +181,27 @@ interface types { /// key, if they have been set. /// /// Fails with `header-error.immutable` if the `fields` are immutable. + /// + /// Fails with `header-error.invalid-syntax` if the `field-key` or any of + /// the `field-value`s are syntactically invalid. set: func(name: field-key, value: list) -> result<_, header-error>; /// Delete all values for a key. Does nothing if no values for the key /// exist. /// /// Fails with `header-error.immutable` if the `fields` are immutable. + /// + /// Fails with `header-error.invalid-syntax` if the `field-key` is + /// syntactically invalid. delete: func(name: field-key) -> result<_, header-error>; /// Append a value for a key. Does not change or delete any existing /// values for that key. /// /// Fails with `header-error.immutable` if the `fields` are immutable. + /// + /// Fails with `header-error.invalid-syntax` if the `field-key` or + /// `field-value` are syntactically invalid. append: func(name: field-key, value: field-value) -> result<_, header-error>; /// Retrieve the full set of keys and values in the Fields. Like the From 52648b2be242791fa0b17755b56caedbfa32103d Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 8 Mar 2024 15:19:04 -0700 Subject: [PATCH 1430/1772] add draft of wasi:http@0.3.0 (#106) * add draft of wasi:http@0.3.0 This adds a `wit-0.3.0-draft` directory so we can iterate on the 0.3.0 design in parallel with the 0.2.x work. It's currently an exact copy of the `wit` directory except for the `handler.wit`, `proxy.wit`, and `types.wit` files, which have been updated to assume Component Model async, `stream`s, and `future`s are available. High level description: - The incoming-handler and outgoing-handler interfaces have been combined into a single handler interface. - The incoming- and outgoing- variations of request, response, and body have been combined. - I've added a option field to request since it would be awkward to leave it as a parameter of handler.handle (e.g. what would it mean to receive such a parameter for an incoming request or for a request passed from one component to the other without any use of the network?). - I've added a request-options-error (analogous to header-error) to distinguish between unsupported fields and immutable handles. - We use `stream` and `future` where appropriate. You can find a working implementation of this API, plus several examples, in the [isyswasfa](https://github.com/dicej/isyswasfa) repository. Signed-off-by: Joel Dice * regenerate markdown files Signed-off-by: Joel Dice --------- Signed-off-by: Joel Dice --- proposals/http/imports.md | 20 +- proposals/http/wit-0.3.0-draft/deps.lock | 29 + proposals/http/wit-0.3.0-draft/deps.toml | 7 + .../http/wit-0.3.0-draft/deps/cli/command.wit | 7 + .../wit-0.3.0-draft/deps/cli/environment.wit | 18 + .../http/wit-0.3.0-draft/deps/cli/exit.wit | 4 + .../http/wit-0.3.0-draft/deps/cli/imports.wit | 20 + .../http/wit-0.3.0-draft/deps/cli/run.wit | 4 + .../http/wit-0.3.0-draft/deps/cli/stdio.wit | 17 + .../wit-0.3.0-draft/deps/cli/terminal.wit | 49 ++ .../deps/clocks/monotonic-clock.wit | 45 ++ .../deps/clocks/wall-clock.wit | 42 ++ .../wit-0.3.0-draft/deps/clocks/world.wit | 6 + .../deps/filesystem/preopens.wit | 8 + .../wit-0.3.0-draft/deps/filesystem/types.wit | 634 ++++++++++++++++++ .../wit-0.3.0-draft/deps/filesystem/world.wit | 6 + .../http/wit-0.3.0-draft/deps/io/error.wit | 34 + .../http/wit-0.3.0-draft/deps/io/poll.wit | 41 ++ .../http/wit-0.3.0-draft/deps/io/streams.wit | 262 ++++++++ .../http/wit-0.3.0-draft/deps/io/world.wit | 6 + .../deps/random/insecure-seed.wit | 25 + .../wit-0.3.0-draft/deps/random/insecure.wit | 22 + .../wit-0.3.0-draft/deps/random/random.wit | 26 + .../wit-0.3.0-draft/deps/random/world.wit | 7 + .../deps/sockets/instance-network.wit | 9 + .../deps/sockets/ip-name-lookup.wit | 51 ++ .../wit-0.3.0-draft/deps/sockets/network.wit | 145 ++++ .../deps/sockets/tcp-create-socket.wit | 27 + .../http/wit-0.3.0-draft/deps/sockets/tcp.wit | 353 ++++++++++ .../deps/sockets/udp-create-socket.wit | 27 + .../http/wit-0.3.0-draft/deps/sockets/udp.wit | 266 ++++++++ .../wit-0.3.0-draft/deps/sockets/world.wit | 11 + proposals/http/wit-0.3.0-draft/handler.wit | 17 + proposals/http/wit-0.3.0-draft/proxy.wit | 44 ++ proposals/http/wit-0.3.0-draft/types.wit | 423 ++++++++++++ 35 files changed, 2704 insertions(+), 8 deletions(-) create mode 100644 proposals/http/wit-0.3.0-draft/deps.lock create mode 100644 proposals/http/wit-0.3.0-draft/deps.toml create mode 100644 proposals/http/wit-0.3.0-draft/deps/cli/command.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/cli/environment.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/cli/exit.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/cli/imports.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/cli/run.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/clocks/world.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/io/error.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/io/poll.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/io/streams.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/io/world.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/random/insecure.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/random/random.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/random/world.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/instance-network.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/network.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/tcp-create-socket.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/udp-create-socket.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/world.wit create mode 100644 proposals/http/wit-0.3.0-draft/handler.wit create mode 100644 proposals/http/wit-0.3.0-draft/proxy.wit create mode 100644 proposals/http/wit-0.3.0-draft/types.wit diff --git a/proposals/http/imports.md b/proposals/http/imports.md index 5dff42af7..605686394 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -810,11 +810,9 @@ http-related errors.

                  which have multiple values are represented by multiple entries in this list with the same key.

                  The tuple is a pair of the field key, represented as a string, and -Value, represented as a list of bytes. In a valid Fields, all keys -and values are valid UTF-8 strings. However, values are not always -well-formed, so they are represented as a raw list of bytes.

                  -

                  An error result will be returned if any header or value was -syntactically invalid, or if a header was forbidden.

                  +Value, represented as a list of bytes.

                  +

                  An error result will be returned if any field-key or field-value is +syntactically invalid, or if a field is forbidden.

                  Params
                  • entries: list<(field-key, field-value)>
                  • @@ -825,9 +823,9 @@ syntactically invalid, or if a header was forbidden.

                  [method]fields.get: func

                  Get all of the values corresponding to a key. If the key is not present -in this fields, an empty list is returned. However, if the key is -present but empty, this is represented by a list with one or more -empty field-values present.

                  +in this fields or is syntactically invalid, an empty list is returned. +However, if the key is present but empty, this is represented by a list +with one or more empty field-values present.

                  Params
                  • self: borrow<fields>
                  • @@ -853,6 +851,8 @@ syntactically invalid, false is returned.

                    Set all of the values for a key. Clears any existing values for that key, if they have been set.

                    Fails with header-error.immutable if the fields are immutable.

                    +

                    Fails with header-error.invalid-syntax if the field-key or any of +the field-values are syntactically invalid.

                    Params
                    • self: borrow<fields>
                    • @@ -867,6 +867,8 @@ key, if they have been set.

                      Delete all values for a key. Does nothing if no values for the key exist.

                      Fails with header-error.immutable if the fields are immutable.

                      +

                      Fails with header-error.invalid-syntax if the field-key is +syntactically invalid.

                      Params
                      • self: borrow<fields>
                      • @@ -880,6 +882,8 @@ exist.

                        Append a value for a key. Does not change or delete any existing values for that key.

                        Fails with header-error.immutable if the fields are immutable.

                        +

                        Fails with header-error.invalid-syntax if the field-key or +field-value are syntactically invalid.

                        Params
                        • self: borrow<fields>
                        • diff --git a/proposals/http/wit-0.3.0-draft/deps.lock b/proposals/http/wit-0.3.0-draft/deps.lock new file mode 100644 index 000000000..96be4b203 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps.lock @@ -0,0 +1,29 @@ +[cli] +url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" +sha256 = "285865a31d777181b075f39e92bcfe59c89cd6bacce660be1b9a627646956258" +sha512 = "da2622210a9e3eea82b99f1a5b8a44ce5443d009cb943f7bca0bf9cf4360829b289913d7ee727c011f0f72994ea7dc8e661ebcc0a6b34b587297d80cd9b3f7e8" + +[clocks] +url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" +sha256 = "468b4d12892fe926b8eb5d398dbf579d566c93231fa44f415440572c695b7613" +sha512 = "e6b53a07221f1413953c9797c68f08b815fdaebf66419bbc1ea3e8b7dece73731062693634731f311a03957b268cf9cc509c518bd15e513c318aa04a8459b93a" + +[filesystem] +url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" +sha256 = "498c465cfd04587db40f970fff2185daa597d074c20b68a8bcbae558f261499b" +sha512 = "ead452f9b7bfb88593a502ec00d76d4228003d51c40fd0408aebc32d35c94673551b00230d730873361567cc209ec218c41fb4e95bad194268592c49e7964347" + +[io] +url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +sha256 = "7210e5653539a15478f894d4da24cc69d61924cbcba21d2804d69314a88e5a4c" +sha512 = "49184a1b0945a889abd52d25271172ed3dc2db6968fcdddb1bab7ee0081f4a3eeee0977ad2291126a37631c0d86eeea75d822fa8af224c422134500bf9f0f2bb" + +[random] +url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" +sha256 = "7371d03c037d924caba2587fb2e7c5773a0d3c5fcecbf7971e0e0ba57973c53d" +sha512 = "964c4e8925a53078e4d94ba907b54f89a0b7e154f46823a505391471466c17f53c8692682e5c85771712acd88b348686173fc07c53a3cfe3d301b8cd8ddd0de4" + +[sockets] +url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" +sha256 = "622bd28bbeb43736375dc02bd003fd3a016ff8ee91e14bab488325c6b38bf966" +sha512 = "5a63c1f36de0c4548e1d2297bdbededb28721cbad94ef7825c469eae29d7451c97e00b4c1d6730ee1ec0c4a5aac922961a2795762d4a0c3bb54e30a391a84bae" diff --git a/proposals/http/wit-0.3.0-draft/deps.toml b/proposals/http/wit-0.3.0-draft/deps.toml new file mode 100644 index 000000000..dd738ac4c --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps.toml @@ -0,0 +1,7 @@ +io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +cli = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" +random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" +clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" +# not used by http/proxy, but included to allow full contents of wasi-cli to validate +filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" +sockets = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit new file mode 100644 index 000000000..d8005bd38 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit @@ -0,0 +1,7 @@ +package wasi:cli@0.2.0; + +world command { + include imports; + + export run; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit b/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit new file mode 100644 index 000000000..70065233e --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit @@ -0,0 +1,18 @@ +interface environment { + /// Get the POSIX-style environment variables. + /// + /// Each environment variable is provided as a pair of string variable names + /// and string value. + /// + /// Morally, these are a value import, but until value imports are available + /// in the component model, this import function should return the same + /// values each time it is called. + get-environment: func() -> list>; + + /// Get the POSIX-style arguments to the program. + get-arguments: func() -> list; + + /// Return a path that programs should use as their initial current working + /// directory, interpreting `.` as shorthand for this. + initial-cwd: func() -> option; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit b/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit new file mode 100644 index 000000000..d0c2b82ae --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit @@ -0,0 +1,4 @@ +interface exit { + /// Exit the current instance and any linked instances. + exit: func(status: result); +} diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit new file mode 100644 index 000000000..083b84a03 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit @@ -0,0 +1,20 @@ +package wasi:cli@0.2.0; + +world imports { + include wasi:clocks/imports@0.2.0; + include wasi:filesystem/imports@0.2.0; + include wasi:sockets/imports@0.2.0; + include wasi:random/imports@0.2.0; + include wasi:io/imports@0.2.0; + + import environment; + import exit; + import stdin; + import stdout; + import stderr; + import terminal-input; + import terminal-output; + import terminal-stdin; + import terminal-stdout; + import terminal-stderr; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/run.wit b/proposals/http/wit-0.3.0-draft/deps/cli/run.wit new file mode 100644 index 000000000..a70ee8c03 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/cli/run.wit @@ -0,0 +1,4 @@ +interface run { + /// Run the program. + run: func() -> result; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit new file mode 100644 index 000000000..31ef35b5a --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit @@ -0,0 +1,17 @@ +interface stdin { + use wasi:io/streams@0.2.0.{input-stream}; + + get-stdin: func() -> input-stream; +} + +interface stdout { + use wasi:io/streams@0.2.0.{output-stream}; + + get-stdout: func() -> output-stream; +} + +interface stderr { + use wasi:io/streams@0.2.0.{output-stream}; + + get-stderr: func() -> output-stream; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit b/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit new file mode 100644 index 000000000..38c724efc --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit @@ -0,0 +1,49 @@ +/// Terminal input. +/// +/// In the future, this may include functions for disabling echoing, +/// disabling input buffering so that keyboard events are sent through +/// immediately, querying supported features, and so on. +interface terminal-input { + /// The input side of a terminal. + resource terminal-input; +} + +/// Terminal output. +/// +/// In the future, this may include functions for querying the terminal +/// size, being notified of terminal size changes, querying supported +/// features, and so on. +interface terminal-output { + /// The output side of a terminal. + resource terminal-output; +} + +/// An interface providing an optional `terminal-input` for stdin as a +/// link-time authority. +interface terminal-stdin { + use terminal-input.{terminal-input}; + + /// If stdin is connected to a terminal, return a `terminal-input` handle + /// allowing further interaction with it. + get-terminal-stdin: func() -> option; +} + +/// An interface providing an optional `terminal-output` for stdout as a +/// link-time authority. +interface terminal-stdout { + use terminal-output.{terminal-output}; + + /// If stdout is connected to a terminal, return a `terminal-output` handle + /// allowing further interaction with it. + get-terminal-stdout: func() -> option; +} + +/// An interface providing an optional `terminal-output` for stderr as a +/// link-time authority. +interface terminal-stderr { + use terminal-output.{terminal-output}; + + /// If stderr is connected to a terminal, return a `terminal-output` handle + /// allowing further interaction with it. + get-terminal-stderr: func() -> option; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit new file mode 100644 index 000000000..4e4dc3a19 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -0,0 +1,45 @@ +package wasi:clocks@0.2.0; +/// WASI Monotonic Clock is a clock API intended to let users measure elapsed +/// time. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A monotonic clock is a clock which has an unspecified initial value, and +/// successive reads of the clock will produce non-decreasing values. +/// +/// It is intended for measuring elapsed time. +interface monotonic-clock { + use wasi:io/poll@0.2.0.{pollable}; + + /// An instant in time, in nanoseconds. An instant is relative to an + /// unspecified initial value, and can only be compared to instances from + /// the same monotonic-clock. + type instant = u64; + + /// A duration of time, in nanoseconds. + type duration = u64; + + /// Read the current value of the clock. + /// + /// The clock is monotonic, therefore calling this function repeatedly will + /// produce a sequence of non-decreasing values. + now: func() -> instant; + + /// Query the resolution of the clock. Returns the duration of time + /// corresponding to a clock tick. + resolution: func() -> duration; + + /// Create a `pollable` which will resolve once the specified instant + /// occured. + subscribe-instant: func( + when: instant, + ) -> pollable; + + /// Create a `pollable` which will resolve once the given duration has + /// elapsed, starting at the time at which this function was called. + /// occured. + subscribe-duration: func( + when: duration, + ) -> pollable; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit new file mode 100644 index 000000000..440ca0f33 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -0,0 +1,42 @@ +package wasi:clocks@0.2.0; +/// WASI Wall Clock is a clock API intended to let users query the current +/// time. The name "wall" makes an analogy to a "clock on the wall", which +/// is not necessarily monotonic as it may be reset. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A wall clock is a clock which measures the date and time according to +/// some external reference. +/// +/// External references may be reset, so this clock is not necessarily +/// monotonic, making it unsuitable for measuring elapsed time. +/// +/// It is intended for reporting the current date and time for humans. +interface wall-clock { + /// A time and date in seconds plus nanoseconds. + record datetime { + seconds: u64, + nanoseconds: u32, + } + + /// Read the current value of the clock. + /// + /// This clock is not monotonic, therefore calling this function repeatedly + /// will not necessarily produce a sequence of non-decreasing values. + /// + /// The returned timestamps represent the number of seconds since + /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], + /// also known as [Unix Time]. + /// + /// The nanoseconds field of the output is always less than 1000000000. + /// + /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + now: func() -> datetime; + + /// Query the resolution of the clock. + /// + /// The nanoseconds field of the output is always less than 1000000000. + resolution: func() -> datetime; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit new file mode 100644 index 000000000..c0224572a --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit @@ -0,0 +1,6 @@ +package wasi:clocks@0.2.0; + +world imports { + import monotonic-clock; + import wall-clock; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit new file mode 100644 index 000000000..da801f6d6 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit @@ -0,0 +1,8 @@ +package wasi:filesystem@0.2.0; + +interface preopens { + use types.{descriptor}; + + /// Return the set of preopened directories, and their path. + get-directories: func() -> list>; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit new file mode 100644 index 000000000..11108fcda --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit @@ -0,0 +1,634 @@ +package wasi:filesystem@0.2.0; +/// WASI filesystem is a filesystem API primarily intended to let users run WASI +/// programs that access their files on their existing filesystems, without +/// significant overhead. +/// +/// It is intended to be roughly portable between Unix-family platforms and +/// Windows, though it does not hide many of the major differences. +/// +/// Paths are passed as interface-type `string`s, meaning they must consist of +/// a sequence of Unicode Scalar Values (USVs). Some filesystems may contain +/// paths which are not accessible by this API. +/// +/// The directory separator in WASI is always the forward-slash (`/`). +/// +/// All paths in WASI are relative paths, and are interpreted relative to a +/// `descriptor` referring to a base directory. If a `path` argument to any WASI +/// function starts with `/`, or if any step of resolving a `path`, including +/// `..` and symbolic link steps, reaches a directory outside of the base +/// directory, or reaches a symlink to an absolute or rooted path in the +/// underlying filesystem, the function fails with `error-code::not-permitted`. +/// +/// For more information about WASI path resolution and sandboxing, see +/// [WASI filesystem path resolution]. +/// +/// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md +interface types { + use wasi:io/streams@0.2.0.{input-stream, output-stream, error}; + use wasi:clocks/wall-clock@0.2.0.{datetime}; + + /// File size or length of a region within a file. + type filesize = u64; + + /// The type of a filesystem object referenced by a descriptor. + /// + /// Note: This was called `filetype` in earlier versions of WASI. + enum descriptor-type { + /// The type of the descriptor or file is unknown or is different from + /// any of the other types specified. + unknown, + /// The descriptor refers to a block device inode. + block-device, + /// The descriptor refers to a character device inode. + character-device, + /// The descriptor refers to a directory inode. + directory, + /// The descriptor refers to a named pipe. + fifo, + /// The file refers to a symbolic link inode. + symbolic-link, + /// The descriptor refers to a regular file inode. + regular-file, + /// The descriptor refers to a socket. + socket, + } + + /// Descriptor flags. + /// + /// Note: This was called `fdflags` in earlier versions of WASI. + flags descriptor-flags { + /// Read mode: Data can be read. + read, + /// Write mode: Data can be written to. + write, + /// Request that writes be performed according to synchronized I/O file + /// integrity completion. The data stored in the file and the file's + /// metadata are synchronized. This is similar to `O_SYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + file-integrity-sync, + /// Request that writes be performed according to synchronized I/O data + /// integrity completion. Only the data stored in the file is + /// synchronized. This is similar to `O_DSYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + data-integrity-sync, + /// Requests that reads be performed at the same level of integrety + /// requested for writes. This is similar to `O_RSYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + requested-write-sync, + /// Mutating directories mode: Directory contents may be mutated. + /// + /// When this flag is unset on a descriptor, operations using the + /// descriptor which would create, rename, delete, modify the data or + /// metadata of filesystem objects, or obtain another handle which + /// would permit any of those, shall fail with `error-code::read-only` if + /// they would otherwise succeed. + /// + /// This may only be set on directories. + mutate-directory, + } + + /// File attributes. + /// + /// Note: This was called `filestat` in earlier versions of WASI. + record descriptor-stat { + /// File type. + %type: descriptor-type, + /// Number of hard links to the file. + link-count: link-count, + /// For regular files, the file size in bytes. For symbolic links, the + /// length in bytes of the pathname contained in the symbolic link. + size: filesize, + /// Last data access timestamp. + /// + /// If the `option` is none, the platform doesn't maintain an access + /// timestamp for this file. + data-access-timestamp: option, + /// Last data modification timestamp. + /// + /// If the `option` is none, the platform doesn't maintain a + /// modification timestamp for this file. + data-modification-timestamp: option, + /// Last file status-change timestamp. + /// + /// If the `option` is none, the platform doesn't maintain a + /// status-change timestamp for this file. + status-change-timestamp: option, + } + + /// Flags determining the method of how paths are resolved. + flags path-flags { + /// As long as the resolved path corresponds to a symbolic link, it is + /// expanded. + symlink-follow, + } + + /// Open flags used by `open-at`. + flags open-flags { + /// Create file if it does not exist, similar to `O_CREAT` in POSIX. + create, + /// Fail if not a directory, similar to `O_DIRECTORY` in POSIX. + directory, + /// Fail if file already exists, similar to `O_EXCL` in POSIX. + exclusive, + /// Truncate file to size 0, similar to `O_TRUNC` in POSIX. + truncate, + } + + /// Number of hard links to an inode. + type link-count = u64; + + /// When setting a timestamp, this gives the value to set it to. + variant new-timestamp { + /// Leave the timestamp set to its previous value. + no-change, + /// Set the timestamp to the current time of the system clock associated + /// with the filesystem. + now, + /// Set the timestamp to the given value. + timestamp(datetime), + } + + /// A directory entry. + record directory-entry { + /// The type of the file referred to by this directory entry. + %type: descriptor-type, + + /// The name of the object. + name: string, + } + + /// Error codes returned by functions, similar to `errno` in POSIX. + /// Not all of these error codes are returned by the functions provided by this + /// API; some are used in higher-level library layers, and others are provided + /// merely for alignment with POSIX. + enum error-code { + /// Permission denied, similar to `EACCES` in POSIX. + access, + /// Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. + would-block, + /// Connection already in progress, similar to `EALREADY` in POSIX. + already, + /// Bad descriptor, similar to `EBADF` in POSIX. + bad-descriptor, + /// Device or resource busy, similar to `EBUSY` in POSIX. + busy, + /// Resource deadlock would occur, similar to `EDEADLK` in POSIX. + deadlock, + /// Storage quota exceeded, similar to `EDQUOT` in POSIX. + quota, + /// File exists, similar to `EEXIST` in POSIX. + exist, + /// File too large, similar to `EFBIG` in POSIX. + file-too-large, + /// Illegal byte sequence, similar to `EILSEQ` in POSIX. + illegal-byte-sequence, + /// Operation in progress, similar to `EINPROGRESS` in POSIX. + in-progress, + /// Interrupted function, similar to `EINTR` in POSIX. + interrupted, + /// Invalid argument, similar to `EINVAL` in POSIX. + invalid, + /// I/O error, similar to `EIO` in POSIX. + io, + /// Is a directory, similar to `EISDIR` in POSIX. + is-directory, + /// Too many levels of symbolic links, similar to `ELOOP` in POSIX. + loop, + /// Too many links, similar to `EMLINK` in POSIX. + too-many-links, + /// Message too large, similar to `EMSGSIZE` in POSIX. + message-size, + /// Filename too long, similar to `ENAMETOOLONG` in POSIX. + name-too-long, + /// No such device, similar to `ENODEV` in POSIX. + no-device, + /// No such file or directory, similar to `ENOENT` in POSIX. + no-entry, + /// No locks available, similar to `ENOLCK` in POSIX. + no-lock, + /// Not enough space, similar to `ENOMEM` in POSIX. + insufficient-memory, + /// No space left on device, similar to `ENOSPC` in POSIX. + insufficient-space, + /// Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. + not-directory, + /// Directory not empty, similar to `ENOTEMPTY` in POSIX. + not-empty, + /// State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. + not-recoverable, + /// Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. + unsupported, + /// Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. + no-tty, + /// No such device or address, similar to `ENXIO` in POSIX. + no-such-device, + /// Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. + overflow, + /// Operation not permitted, similar to `EPERM` in POSIX. + not-permitted, + /// Broken pipe, similar to `EPIPE` in POSIX. + pipe, + /// Read-only file system, similar to `EROFS` in POSIX. + read-only, + /// Invalid seek, similar to `ESPIPE` in POSIX. + invalid-seek, + /// Text file busy, similar to `ETXTBSY` in POSIX. + text-file-busy, + /// Cross-device link, similar to `EXDEV` in POSIX. + cross-device, + } + + /// File or memory access pattern advisory information. + enum advice { + /// The application has no advice to give on its behavior with respect + /// to the specified data. + normal, + /// The application expects to access the specified data sequentially + /// from lower offsets to higher offsets. + sequential, + /// The application expects to access the specified data in a random + /// order. + random, + /// The application expects to access the specified data in the near + /// future. + will-need, + /// The application expects that it will not access the specified data + /// in the near future. + dont-need, + /// The application expects to access the specified data once and then + /// not reuse it thereafter. + no-reuse, + } + + /// A 128-bit hash value, split into parts because wasm doesn't have a + /// 128-bit integer type. + record metadata-hash-value { + /// 64 bits of a 128-bit hash value. + lower: u64, + /// Another 64 bits of a 128-bit hash value. + upper: u64, + } + + /// A descriptor is a reference to a filesystem object, which may be a file, + /// directory, named pipe, special file, or other object on which filesystem + /// calls may be made. + resource descriptor { + /// Return a stream for reading from a file, if available. + /// + /// May fail with an error-code describing why the file cannot be read. + /// + /// Multiple read, write, and append streams may be active on the same open + /// file and they do not interfere with each other. + /// + /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. + read-via-stream: func( + /// The offset within the file at which to start reading. + offset: filesize, + ) -> result; + + /// Return a stream for writing to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be written. + /// + /// Note: This allows using `write-stream`, which is similar to `write` in + /// POSIX. + write-via-stream: func( + /// The offset within the file at which to start writing. + offset: filesize, + ) -> result; + + /// Return a stream for appending to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be appended. + /// + /// Note: This allows using `write-stream`, which is similar to `write` with + /// `O_APPEND` in in POSIX. + append-via-stream: func() -> result; + + /// Provide file advisory information on a descriptor. + /// + /// This is similar to `posix_fadvise` in POSIX. + advise: func( + /// The offset within the file to which the advisory applies. + offset: filesize, + /// The length of the region to which the advisory applies. + length: filesize, + /// The advice. + advice: advice + ) -> result<_, error-code>; + + /// Synchronize the data of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fdatasync` in POSIX. + sync-data: func() -> result<_, error-code>; + + /// Get flags associated with a descriptor. + /// + /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. + /// + /// Note: This returns the value that was the `fs_flags` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-flags: func() -> result; + + /// Get the dynamic type of a descriptor. + /// + /// Note: This returns the same value as the `type` field of the `fd-stat` + /// returned by `stat`, `stat-at` and similar. + /// + /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided + /// by `fstat` in POSIX. + /// + /// Note: This returns the value that was the `fs_filetype` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-type: func() -> result; + + /// Adjust the size of an open file. If this increases the file's size, the + /// extra bytes are filled with zeros. + /// + /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. + set-size: func(size: filesize) -> result<_, error-code>; + + /// Adjust the timestamps of an open file or directory. + /// + /// Note: This is similar to `futimens` in POSIX. + /// + /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. + set-times: func( + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code>; + + /// Read from a descriptor, without using and updating the descriptor's offset. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a bool which, when true, indicates that the end of the + /// file was reached. The returned list will contain up to `length` bytes; it + /// may return fewer than requested, if the end of the file is reached or + /// if the I/O operation is interrupted. + /// + /// In the future, this may change to return a `stream`. + /// + /// Note: This is similar to `pread` in POSIX. + read: func( + /// The maximum number of bytes to read. + length: filesize, + /// The offset within the file at which to read. + offset: filesize, + ) -> result, bool>, error-code>; + + /// Write to a descriptor, without using and updating the descriptor's offset. + /// + /// It is valid to write past the end of a file; the file is extended to the + /// extent of the write, with bytes between the previous end and the start of + /// the write set to zero. + /// + /// In the future, this may change to take a `stream`. + /// + /// Note: This is similar to `pwrite` in POSIX. + write: func( + /// Data to write + buffer: list, + /// The offset within the file at which to write. + offset: filesize, + ) -> result; + + /// Read directory entries from a directory. + /// + /// On filesystems where directories contain entries referring to themselves + /// and their parents, often named `.` and `..` respectively, these entries + /// are omitted. + /// + /// This always returns a new stream which starts at the beginning of the + /// directory. Multiple streams may be active on the same directory, and they + /// do not interfere with each other. + read-directory: func() -> result; + + /// Synchronize the data and metadata of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fsync` in POSIX. + sync: func() -> result<_, error-code>; + + /// Create a directory. + /// + /// Note: This is similar to `mkdirat` in POSIX. + create-directory-at: func( + /// The relative path at which to create the directory. + path: string, + ) -> result<_, error-code>; + + /// Return the attributes of an open file or directory. + /// + /// Note: This is similar to `fstat` in POSIX, except that it does not return + /// device and inode information. For testing whether two descriptors refer to + /// the same underlying filesystem object, use `is-same-object`. To obtain + /// additional data that can be used do determine whether a file has been + /// modified, use `metadata-hash`. + /// + /// Note: This was called `fd_filestat_get` in earlier versions of WASI. + stat: func() -> result; + + /// Return the attributes of a file or directory. + /// + /// Note: This is similar to `fstatat` in POSIX, except that it does not + /// return device and inode information. See the `stat` description for a + /// discussion of alternatives. + /// + /// Note: This was called `path_filestat_get` in earlier versions of WASI. + stat-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result; + + /// Adjust the timestamps of a file or directory. + /// + /// Note: This is similar to `utimensat` in POSIX. + /// + /// Note: This was called `path_filestat_set_times` in earlier versions of + /// WASI. + set-times-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to operate on. + path: string, + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code>; + + /// Create a hard link. + /// + /// Note: This is similar to `linkat` in POSIX. + link-at: func( + /// Flags determining the method of how the path is resolved. + old-path-flags: path-flags, + /// The relative source path from which to link. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: borrow, + /// The relative destination path at which to create the hard link. + new-path: string, + ) -> result<_, error-code>; + + /// Open a file or directory. + /// + /// The returned descriptor is not guaranteed to be the lowest-numbered + /// descriptor not currently open/ it is randomized to prevent applications + /// from depending on making assumptions about indexes, since this is + /// error-prone in multi-threaded contexts. The returned descriptor is + /// guaranteed to be less than 2**31. + /// + /// If `flags` contains `descriptor-flags::mutate-directory`, and the base + /// descriptor doesn't have `descriptor-flags::mutate-directory` set, + /// `open-at` fails with `error-code::read-only`. + /// + /// If `flags` contains `write` or `mutate-directory`, or `open-flags` + /// contains `truncate` or `create`, and the base descriptor doesn't have + /// `descriptor-flags::mutate-directory` set, `open-at` fails with + /// `error-code::read-only`. + /// + /// Note: This is similar to `openat` in POSIX. + open-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the object to open. + path: string, + /// The method by which to open the file. + open-flags: open-flags, + /// Flags to use for the resulting descriptor. + %flags: descriptor-flags, + ) -> result; + + /// Read the contents of a symbolic link. + /// + /// If the contents contain an absolute or rooted path in the underlying + /// filesystem, this function fails with `error-code::not-permitted`. + /// + /// Note: This is similar to `readlinkat` in POSIX. + readlink-at: func( + /// The relative path of the symbolic link from which to read. + path: string, + ) -> result; + + /// Remove a directory. + /// + /// Return `error-code::not-empty` if the directory is not empty. + /// + /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + remove-directory-at: func( + /// The relative path to a directory to remove. + path: string, + ) -> result<_, error-code>; + + /// Rename a filesystem object. + /// + /// Note: This is similar to `renameat` in POSIX. + rename-at: func( + /// The relative source path of the file or directory to rename. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: borrow, + /// The relative destination path to which to rename the file or directory. + new-path: string, + ) -> result<_, error-code>; + + /// Create a symbolic link (also known as a "symlink"). + /// + /// If `old-path` starts with `/`, the function fails with + /// `error-code::not-permitted`. + /// + /// Note: This is similar to `symlinkat` in POSIX. + symlink-at: func( + /// The contents of the symbolic link. + old-path: string, + /// The relative destination path at which to create the symbolic link. + new-path: string, + ) -> result<_, error-code>; + + /// Unlink a filesystem object that is not a directory. + /// + /// Return `error-code::is-directory` if the path refers to a directory. + /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + unlink-file-at: func( + /// The relative path to a file to unlink. + path: string, + ) -> result<_, error-code>; + + /// Test whether two descriptors refer to the same filesystem object. + /// + /// In POSIX, this corresponds to testing whether the two descriptors have the + /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. + /// wasi-filesystem does not expose device and inode numbers, so this function + /// may be used instead. + is-same-object: func(other: borrow) -> bool; + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a descriptor. + /// + /// This returns a hash of the last-modification timestamp and file size, and + /// may also include the inode number, device number, birth timestamp, and + /// other metadata fields that may change when the file is modified or + /// replaced. It may also include a secret value chosen by the + /// implementation and not otherwise exposed. + /// + /// Implementations are encourated to provide the following properties: + /// + /// - If the file is not modified or replaced, the computed hash value should + /// usually not change. + /// - If the object is modified or replaced, the computed hash value should + /// usually change. + /// - The inputs to the hash should not be easily computable from the + /// computed hash. + /// + /// However, none of these is required. + metadata-hash: func() -> result; + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a directory descriptor and a relative path. + /// + /// This performs the same hash computation as `metadata-hash`. + metadata-hash-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result; + } + + /// A stream of directory entries. + resource directory-entry-stream { + /// Read a single directory entry from a `directory-entry-stream`. + read-directory-entry: func() -> result, error-code>; + } + + /// Attempts to extract a filesystem-related `error-code` from the stream + /// `error` provided. + /// + /// Stream operations which return `stream-error::last-operation-failed` + /// have a payload with more information about the operation that failed. + /// This payload can be passed through to this function to see if there's + /// filesystem-related information about the error to return. + /// + /// Note that this function is fallible because not all stream-related + /// errors are filesystem-related errors. + filesystem-error-code: func(err: borrow) -> option; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit new file mode 100644 index 000000000..663f57920 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit @@ -0,0 +1,6 @@ +package wasi:filesystem@0.2.0; + +world imports { + import types; + import preopens; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/io/error.wit b/proposals/http/wit-0.3.0-draft/deps/io/error.wit new file mode 100644 index 000000000..22e5b6489 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/io/error.wit @@ -0,0 +1,34 @@ +package wasi:io@0.2.0; + + +interface error { + /// A resource which represents some error information. + /// + /// The only method provided by this resource is `to-debug-string`, + /// which provides some human-readable information about the error. + /// + /// In the `wasi:io` package, this resource is returned through the + /// `wasi:io/streams/stream-error` type. + /// + /// To provide more specific error information, other interfaces may + /// provide functions to further "downcast" this error into more specific + /// error information. For example, `error`s returned in streams derived + /// from filesystem types to be described using the filesystem's own + /// error-code type, using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter + /// `borrow` and returns + /// `option`. + /// + /// The set of functions which can "downcast" an `error` into a more + /// concrete type is open. + resource error { + /// Returns a string that is suitable to assist humans in debugging + /// this error. + /// + /// WARNING: The returned string should not be consumed mechanically! + /// It may change across platforms, hosts, or other implementation + /// details. Parsing this string is a major platform-compatibility + /// hazard. + to-debug-string: func() -> string; + } +} diff --git a/proposals/http/wit-0.3.0-draft/deps/io/poll.wit b/proposals/http/wit-0.3.0-draft/deps/io/poll.wit new file mode 100644 index 000000000..ddc67f8b7 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/io/poll.wit @@ -0,0 +1,41 @@ +package wasi:io@0.2.0; + +/// A poll API intended to let users wait for I/O events on multiple handles +/// at once. +interface poll { + /// `pollable` represents a single I/O event which may be ready, or not. + resource pollable { + + /// Return the readiness of a pollable. This function never blocks. + /// + /// Returns `true` when the pollable is ready, and `false` otherwise. + ready: func() -> bool; + + /// `block` returns immediately if the pollable is ready, and otherwise + /// blocks until ready. + /// + /// This function is equivalent to calling `poll.poll` on a list + /// containing only this pollable. + block: func(); + } + + /// Poll for completion on a set of pollables. + /// + /// This function takes a list of pollables, which identify I/O sources of + /// interest, and waits until one or more of the events is ready for I/O. + /// + /// The result `list` contains one or more indices of handles in the + /// argument list that is ready for I/O. + /// + /// If the list contains more elements than can be indexed with a `u32` + /// value, this function traps. + /// + /// A timeout can be implemented by adding a pollable from the + /// wasi-clocks API to the list. + /// + /// This function does not return a `result`; polling in itself does not + /// do any I/O so it doesn't fail. If any of the I/O sources identified by + /// the pollables has an error, it is indicated by marking the source as + /// being reaedy for I/O. + poll: func(in: list>) -> list; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/io/streams.wit b/proposals/http/wit-0.3.0-draft/deps/io/streams.wit new file mode 100644 index 000000000..6d2f871e3 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/io/streams.wit @@ -0,0 +1,262 @@ +package wasi:io@0.2.0; + +/// WASI I/O is an I/O abstraction API which is currently focused on providing +/// stream types. +/// +/// In the future, the component model is expected to add built-in stream types; +/// when it does, they are expected to subsume this API. +interface streams { + use error.{error}; + use poll.{pollable}; + + /// An error for input-stream and output-stream operations. + variant stream-error { + /// The last operation (a write or flush) failed before completion. + /// + /// More information is available in the `error` payload. + last-operation-failed(error), + /// The stream is closed: no more input will be accepted by the + /// stream. A closed output-stream will return this error on all + /// future operations. + closed + } + + /// An input bytestream. + /// + /// `input-stream`s are *non-blocking* to the extent practical on underlying + /// platforms. I/O operations always return promptly; if fewer bytes are + /// promptly available than requested, they return the number of bytes promptly + /// available, which could even be zero. To wait for data to be available, + /// use the `subscribe` function to obtain a `pollable` which can be polled + /// for using `wasi:io/poll`. + resource input-stream { + /// Perform a non-blocking read from the stream. + /// + /// When the source of a `read` is binary data, the bytes from the source + /// are returned verbatim. When the source of a `read` is known to the + /// implementation to be text, bytes containing the UTF-8 encoding of the + /// text are returned. + /// + /// This function returns a list of bytes containing the read data, + /// when successful. The returned list will contain up to `len` bytes; + /// it may return fewer than requested, but not more. The list is + /// empty when no bytes are available for reading at this time. The + /// pollable given by `subscribe` will be ready when more bytes are + /// available. + /// + /// This function fails with a `stream-error` when the operation + /// encounters an error, giving `last-operation-failed`, or when the + /// stream is closed, giving `closed`. + /// + /// When the caller gives a `len` of 0, it represents a request to + /// read 0 bytes. If the stream is still open, this call should + /// succeed and return an empty list, or otherwise fail with `closed`. + /// + /// The `len` parameter is a `u64`, which could represent a list of u8 which + /// is not possible to allocate in wasm32, or not desirable to allocate as + /// as a return value by the callee. The callee may return a list of bytes + /// less than `len` in size while more bytes are available for reading. + read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-error>; + + /// Read bytes from a stream, after blocking until at least one byte can + /// be read. Except for blocking, behavior is identical to `read`. + blocking-read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-error>; + + /// Skip bytes from a stream. Returns number of bytes skipped. + /// + /// Behaves identical to `read`, except instead of returning a list + /// of bytes, returns the number of bytes consumed from the stream. + skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result; + + /// Skip bytes from a stream, after blocking until at least one byte + /// can be skipped. Except for blocking behavior, identical to `skip`. + blocking-skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result; + + /// Create a `pollable` which will resolve once either the specified stream + /// has bytes available to read or the other end of the stream has been + /// closed. + /// The created `pollable` is a child resource of the `input-stream`. + /// Implementations may trap if the `input-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe: func() -> pollable; + } + + + /// An output bytestream. + /// + /// `output-stream`s are *non-blocking* to the extent practical on + /// underlying platforms. Except where specified otherwise, I/O operations also + /// always return promptly, after the number of bytes that can be written + /// promptly, which could even be zero. To wait for the stream to be ready to + /// accept data, the `subscribe` function to obtain a `pollable` which can be + /// polled for using `wasi:io/poll`. + resource output-stream { + /// Check readiness for writing. This function never blocks. + /// + /// Returns the number of bytes permitted for the next call to `write`, + /// or an error. Calling `write` with more bytes than this function has + /// permitted will trap. + /// + /// When this function returns 0 bytes, the `subscribe` pollable will + /// become ready when this function will report at least 1 byte, or an + /// error. + check-write: func() -> result; + + /// Perform a write. This function never blocks. + /// + /// When the destination of a `write` is binary data, the bytes from + /// `contents` are written verbatim. When the destination of a `write` is + /// known to the implementation to be text, the bytes of `contents` are + /// transcoded from UTF-8 into the encoding of the destination and then + /// written. + /// + /// Precondition: check-write gave permit of Ok(n) and contents has a + /// length of less than or equal to n. Otherwise, this function will trap. + /// + /// returns Err(closed) without writing if the stream has closed since + /// the last call to check-write provided a permit. + write: func( + contents: list + ) -> result<_, stream-error>; + + /// Perform a write of up to 4096 bytes, and then flush the stream. Block + /// until all of these operations are complete, or an error occurs. + /// + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe`, `write`, and `flush`, and is implemented with the + /// following pseudo-code: + /// + /// ```text + /// let pollable = this.subscribe(); + /// while !contents.is_empty() { + /// // Wait for the stream to become writable + /// pollable.block(); + /// let Ok(n) = this.check-write(); // eliding error handling + /// let len = min(n, contents.len()); + /// let (chunk, rest) = contents.split_at(len); + /// this.write(chunk ); // eliding error handling + /// contents = rest; + /// } + /// this.flush(); + /// // Wait for completion of `flush` + /// pollable.block(); + /// // Check for any errors that arose during `flush` + /// let _ = this.check-write(); // eliding error handling + /// ``` + blocking-write-and-flush: func( + contents: list + ) -> result<_, stream-error>; + + /// Request to flush buffered output. This function never blocks. + /// + /// This tells the output-stream that the caller intends any buffered + /// output to be flushed. the output which is expected to be flushed + /// is all that has been passed to `write` prior to this call. + /// + /// Upon calling this function, the `output-stream` will not accept any + /// writes (`check-write` will return `ok(0)`) until the flush has + /// completed. The `subscribe` pollable will become ready when the + /// flush has completed and the stream can accept more writes. + flush: func() -> result<_, stream-error>; + + /// Request to flush buffered output, and block until flush completes + /// and stream is ready for writing again. + blocking-flush: func() -> result<_, stream-error>; + + /// Create a `pollable` which will resolve once the output-stream + /// is ready for more writing, or an error has occured. When this + /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an + /// error. + /// + /// If the stream is closed, this pollable is always ready immediately. + /// + /// The created `pollable` is a child resource of the `output-stream`. + /// Implementations may trap if the `output-stream` is dropped before + /// all derived `pollable`s created with this function are dropped. + subscribe: func() -> pollable; + + /// Write zeroes to a stream. + /// + /// This should be used precisely like `write` with the exact same + /// preconditions (must use check-write first), but instead of + /// passing a list of bytes, you simply pass the number of zero-bytes + /// that should be written. + write-zeroes: func( + /// The number of zero-bytes to write + len: u64 + ) -> result<_, stream-error>; + + /// Perform a write of up to 4096 zeroes, and then flush the stream. + /// Block until all of these operations are complete, or an error + /// occurs. + /// + /// This is a convenience wrapper around the use of `check-write`, + /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with + /// the following pseudo-code: + /// + /// ```text + /// let pollable = this.subscribe(); + /// while num_zeroes != 0 { + /// // Wait for the stream to become writable + /// pollable.block(); + /// let Ok(n) = this.check-write(); // eliding error handling + /// let len = min(n, num_zeroes); + /// this.write-zeroes(len); // eliding error handling + /// num_zeroes -= len; + /// } + /// this.flush(); + /// // Wait for completion of `flush` + /// pollable.block(); + /// // Check for any errors that arose during `flush` + /// let _ = this.check-write(); // eliding error handling + /// ``` + blocking-write-zeroes-and-flush: func( + /// The number of zero-bytes to write + len: u64 + ) -> result<_, stream-error>; + + /// Read from one stream and write to another. + /// + /// The behavior of splice is equivelant to: + /// 1. calling `check-write` on the `output-stream` + /// 2. calling `read` on the `input-stream` with the smaller of the + /// `check-write` permitted length and the `len` provided to `splice` + /// 3. calling `write` on the `output-stream` with that read data. + /// + /// Any error reported by the call to `check-write`, `read`, or + /// `write` ends the splice and reports that error. + /// + /// This function returns the number of bytes transferred; it may be less + /// than `len`. + splice: func( + /// The stream to read from + src: borrow, + /// The number of bytes to splice + len: u64, + ) -> result; + + /// Read from one stream and write to another, with blocking. + /// + /// This is similar to `splice`, except that it blocks until the + /// `output-stream` is ready for writing, and the `input-stream` + /// is ready for reading, before performing the `splice`. + blocking-splice: func( + /// The stream to read from + src: borrow, + /// The number of bytes to splice + len: u64, + ) -> result; + } +} diff --git a/proposals/http/wit-0.3.0-draft/deps/io/world.wit b/proposals/http/wit-0.3.0-draft/deps/io/world.wit new file mode 100644 index 000000000..5f0b43fe5 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/io/world.wit @@ -0,0 +1,6 @@ +package wasi:io@0.2.0; + +world imports { + import streams; + import poll; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit new file mode 100644 index 000000000..47210ac6b --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit @@ -0,0 +1,25 @@ +package wasi:random@0.2.0; +/// The insecure-seed interface for seeding hash-map DoS resistance. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +interface insecure-seed { + /// Return a 128-bit value that may contain a pseudo-random value. + /// + /// The returned value is not required to be computed from a CSPRNG, and may + /// even be entirely deterministic. Host implementations are encouraged to + /// provide pseudo-random values to any program exposed to + /// attacker-controlled content, to enable DoS protection built into many + /// languages' hash-map implementations. + /// + /// This function is intended to only be called once, by a source language + /// to initialize Denial Of Service (DoS) protection in its hash-map + /// implementation. + /// + /// # Expected future evolution + /// + /// This will likely be changed to a value import, to prevent it from being + /// called multiple times and potentially used for purposes other than DoS + /// protection. + insecure-seed: func() -> tuple; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit new file mode 100644 index 000000000..c58f4ee85 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit @@ -0,0 +1,22 @@ +package wasi:random@0.2.0; +/// The insecure interface for insecure pseudo-random numbers. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +interface insecure { + /// Return `len` insecure pseudo-random bytes. + /// + /// This function is not cryptographically secure. Do not use it for + /// anything related to security. + /// + /// There are no requirements on the values of the returned bytes, however + /// implementations are encouraged to return evenly distributed values with + /// a long period. + get-insecure-random-bytes: func(len: u64) -> list; + + /// Return an insecure pseudo-random `u64` value. + /// + /// This function returns the same type of pseudo-random data as + /// `get-insecure-random-bytes`, represented as a `u64`. + get-insecure-random-u64: func() -> u64; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/random/random.wit b/proposals/http/wit-0.3.0-draft/deps/random/random.wit new file mode 100644 index 000000000..0c017f093 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/random/random.wit @@ -0,0 +1,26 @@ +package wasi:random@0.2.0; +/// WASI Random is a random data API. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +interface random { + /// Return `len` cryptographically-secure random or pseudo-random bytes. + /// + /// This function must produce data at least as cryptographically secure and + /// fast as an adequately seeded cryptographically-secure pseudo-random + /// number generator (CSPRNG). It must not block, from the perspective of + /// the calling program, under any circumstances, including on the first + /// request and on requests for numbers of bytes. The returned data must + /// always be unpredictable. + /// + /// This function must always return fresh data. Deterministic environments + /// must omit this function, rather than implementing it with deterministic + /// data. + get-random-bytes: func(len: u64) -> list; + + /// Return a cryptographically-secure random or pseudo-random `u64` value. + /// + /// This function returns the same type of data as `get-random-bytes`, + /// represented as a `u64`. + get-random-u64: func() -> u64; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/random/world.wit b/proposals/http/wit-0.3.0-draft/deps/random/world.wit new file mode 100644 index 000000000..3da34914a --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/random/world.wit @@ -0,0 +1,7 @@ +package wasi:random@0.2.0; + +world imports { + import random; + import insecure; + import insecure-seed; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/instance-network.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/instance-network.wit new file mode 100644 index 000000000..e455d0ff7 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/instance-network.wit @@ -0,0 +1,9 @@ + +/// This interface provides a value-export of the default network handle.. +interface instance-network { + use network.{network}; + + /// Get a handle to the default network. + instance-network: func() -> network; + +} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit new file mode 100644 index 000000000..8e639ec59 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit @@ -0,0 +1,51 @@ + +interface ip-name-lookup { + use wasi:io/poll@0.2.0.{pollable}; + use network.{network, error-code, ip-address}; + + + /// Resolve an internet host name to a list of IP addresses. + /// + /// Unicode domain names are automatically converted to ASCII using IDNA encoding. + /// If the input is an IP address string, the address is parsed and returned + /// as-is without making any external requests. + /// + /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. + /// + /// This function never blocks. It either immediately fails or immediately + /// returns successfully with a `resolve-address-stream` that can be used + /// to (asynchronously) fetch the results. + /// + /// # Typical errors + /// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address. + /// + /// # References: + /// - + /// - + /// - + /// - + resolve-addresses: func(network: borrow, name: string) -> result; + + resource resolve-address-stream { + /// Returns the next address from the resolver. + /// + /// This function should be called multiple times. On each call, it will + /// return the next address in connection order preference. If all + /// addresses have been exhausted, this function returns `none`. + /// + /// This function never returns IPv4-mapped IPv6 addresses. + /// + /// # Typical errors + /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) + /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) + /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) + /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) + resolve-next-address: func() -> result, error-code>; + + /// Create a `pollable` which will resolve once the stream is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } +} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit new file mode 100644 index 000000000..9cadf0650 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit @@ -0,0 +1,145 @@ + +interface network { + /// An opaque resource that represents access to (a subset of) the network. + /// This enables context-based security for networking. + /// There is no need for this to map 1:1 to a physical network interface. + resource network; + + /// Error codes. + /// + /// In theory, every API can return any error code. + /// In practice, API's typically only return the errors documented per API + /// combined with a couple of errors that are always possible: + /// - `unknown` + /// - `access-denied` + /// - `not-supported` + /// - `out-of-memory` + /// - `concurrency-conflict` + /// + /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. + enum error-code { + /// Unknown error + unknown, + + /// Access denied. + /// + /// POSIX equivalent: EACCES, EPERM + access-denied, + + /// The operation is not supported. + /// + /// POSIX equivalent: EOPNOTSUPP + not-supported, + + /// One of the arguments is invalid. + /// + /// POSIX equivalent: EINVAL + invalid-argument, + + /// Not enough memory to complete the operation. + /// + /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY + out-of-memory, + + /// The operation timed out before it could finish completely. + timeout, + + /// This operation is incompatible with another asynchronous operation that is already in progress. + /// + /// POSIX equivalent: EALREADY + concurrency-conflict, + + /// Trying to finish an asynchronous operation that: + /// - has not been started yet, or: + /// - was already finished by a previous `finish-*` call. + /// + /// Note: this is scheduled to be removed when `future`s are natively supported. + not-in-progress, + + /// The operation has been aborted because it could not be completed immediately. + /// + /// Note: this is scheduled to be removed when `future`s are natively supported. + would-block, + + + /// The operation is not valid in the socket's current state. + invalid-state, + + /// A new socket resource could not be created because of a system limit. + new-socket-limit, + + /// A bind operation failed because the provided address is not an address that the `network` can bind to. + address-not-bindable, + + /// A bind operation failed because the provided address is already in use or because there are no ephemeral ports available. + address-in-use, + + /// The remote address is not reachable + remote-unreachable, + + + /// The TCP connection was forcefully rejected + connection-refused, + + /// The TCP connection was reset. + connection-reset, + + /// A TCP connection was aborted. + connection-aborted, + + + /// The size of a datagram sent to a UDP socket exceeded the maximum + /// supported size. + datagram-too-large, + + + /// Name does not exist or has no suitable associated IP addresses. + name-unresolvable, + + /// A temporary failure in name resolution occurred. + temporary-resolver-failure, + + /// A permanent failure in name resolution occurred. + permanent-resolver-failure, + } + + enum ip-address-family { + /// Similar to `AF_INET` in POSIX. + ipv4, + + /// Similar to `AF_INET6` in POSIX. + ipv6, + } + + type ipv4-address = tuple; + type ipv6-address = tuple; + + variant ip-address { + ipv4(ipv4-address), + ipv6(ipv6-address), + } + + record ipv4-socket-address { + /// sin_port + port: u16, + /// sin_addr + address: ipv4-address, + } + + record ipv6-socket-address { + /// sin6_port + port: u16, + /// sin6_flowinfo + flow-info: u32, + /// sin6_addr + address: ipv6-address, + /// sin6_scope_id + scope-id: u32, + } + + variant ip-socket-address { + ipv4(ipv4-socket-address), + ipv6(ipv6-socket-address), + } + +} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp-create-socket.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp-create-socket.wit new file mode 100644 index 000000000..c7ddf1f22 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp-create-socket.wit @@ -0,0 +1,27 @@ + +interface tcp-create-socket { + use network.{network, error-code, ip-address-family}; + use tcp.{tcp-socket}; + + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` + /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # Typical errors + /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References + /// - + /// - + /// - + /// - + create-tcp-socket: func(address-family: ip-address-family) -> result; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit new file mode 100644 index 000000000..5902b9ee0 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit @@ -0,0 +1,353 @@ + +interface tcp { + use wasi:io/streams@0.2.0.{input-stream, output-stream}; + use wasi:io/poll@0.2.0.{pollable}; + use wasi:clocks/monotonic-clock@0.2.0.{duration}; + use network.{network, error-code, ip-socket-address, ip-address-family}; + + enum shutdown-type { + /// Similar to `SHUT_RD` in POSIX. + receive, + + /// Similar to `SHUT_WR` in POSIX. + send, + + /// Similar to `SHUT_RDWR` in POSIX. + both, + } + + /// A TCP socket resource. + /// + /// The socket can be in one of the following states: + /// - `unbound` + /// - `bind-in-progress` + /// - `bound` (See note below) + /// - `listen-in-progress` + /// - `listening` + /// - `connect-in-progress` + /// - `connected` + /// - `closed` + /// See + /// for a more information. + /// + /// Note: Except where explicitly mentioned, whenever this documentation uses + /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. + /// (i.e. `bound`, `listen-in-progress`, `listening`, `connect-in-progress` or `connected`) + /// + /// In addition to the general error codes documented on the + /// `network::error-code` type, TCP socket methods may always return + /// `error(invalid-state)` when in the `closed` state. + resource tcp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// Bind can be attempted multiple times on the same socket, even with + /// different arguments on each iteration. But never concurrently and + /// only as long as the previous bind failed. Once a bind succeeds, the + /// binding can't be changed anymore. + /// + /// # Typical errors + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) + /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # Implementors note + /// When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT + /// state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR + /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior + /// and SO_REUSEADDR performs something different entirely. + /// + /// Unlike in POSIX, in WASI the bind operation is async. This enables + /// interactive WASI hosts to inject permission prompts. Runtimes that + /// don't want to make use of this ability can simply call the native + /// `bind` as part of either `start-bind` or `finish-bind`. + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + finish-bind: func() -> result<_, error-code>; + + /// Connect to a remote endpoint. + /// + /// On success: + /// - the socket is transitioned into the `connection` state. + /// - a pair of streams is returned that can be used to read & write to the connection + /// + /// After a failed connection attempt, the socket will be in the `closed` + /// state and the only valid action left is to `drop` the socket. A single + /// socket can not be used to connect more than once. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) + /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) + /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `not-in-progress`: A connect operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # Implementors note + /// The POSIX equivalent of `start-connect` is the regular `connect` syscall. + /// Because all WASI sockets are non-blocking this is expected to return + /// EINPROGRESS, which should be translated to `ok()` in WASI. + /// + /// The POSIX equivalent of `finish-connect` is a `poll` for event `POLLOUT` + /// with a timeout of 0 on the socket descriptor. Followed by a check for + /// the `SO_ERROR` socket option, in case the poll signaled readiness. + /// + /// # References + /// - + /// - + /// - + /// - + start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + finish-connect: func() -> result, error-code>; + + /// Start listening for new connections. + /// + /// Transitions the socket into the `listening` state. + /// + /// Unlike POSIX, the socket must already be explicitly bound. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ) + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) + /// - `invalid-state`: The socket is already in the `listening` state. + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// - `not-in-progress`: A listen operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # Implementors note + /// Unlike in POSIX, in WASI the listen operation is async. This enables + /// interactive WASI hosts to inject permission prompts. Runtimes that + /// don't want to make use of this ability can simply call the native + /// `listen` as part of either `start-listen` or `finish-listen`. + /// + /// # References + /// - + /// - + /// - + /// - + start-listen: func() -> result<_, error-code>; + finish-listen: func() -> result<_, error-code>; + + /// Accept a new client socket. + /// + /// The returned socket is bound and in the `connected` state. The following properties are inherited from the listener socket: + /// - `address-family` + /// - `keep-alive-enabled` + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// - `hop-limit` + /// - `receive-buffer-size` + /// - `send-buffer-size` + /// + /// On success, this function returns the newly accepted client socket along with + /// a pair of streams that can be used to read & write to the connection. + /// + /// # Typical errors + /// - `invalid-state`: Socket is not in the `listening` state. (EINVAL) + /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) + /// - `connection-aborted`: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References + /// - + /// - + /// - + /// - + accept: func() -> result, error-code>; + + /// Get the bound local address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func() -> result; + + /// Get the remote address. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func() -> result; + + /// Whether the socket is in the `listening` state. + /// + /// Equivalent to the SO_ACCEPTCONN socket option. + is-listening: func() -> bool; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family; + + /// Hints the desired listen queue size. Implementations are free to ignore this. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// + /// # Typical errors + /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. + /// - `invalid-argument`: (set) The provided value was 0. + /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. + set-listen-backlog-size: func(value: u64) -> result<_, error-code>; + + /// Enables or disables keepalive. + /// + /// The keepalive behavior can be adjusted using: + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. + /// + /// Equivalent to the SO_KEEPALIVE socket option. + keep-alive-enabled: func() -> result; + set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; + + /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS) + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + keep-alive-idle-time: func() -> result; + set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; + + /// The time between keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPINTVL socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + keep-alive-interval: func() -> result; + set-keep-alive-interval: func(value: duration) -> result<_, error-code>; + + /// The maximum amount of keepalive packets TCP should send before aborting the connection. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPCNT socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + keep-alive-count: func() -> result; + set-keep-alive-count: func(value: u32) -> result<_, error-code>; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + hop-limit: func() -> result; + set-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + receive-buffer-size: func() -> result; + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + send-buffer-size: func() -> result; + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + + /// Create a `pollable` which can be used to poll for, or block on, + /// completion of any of the asynchronous operations of this socket. + /// + /// When `finish-bind`, `finish-listen`, `finish-connect` or `accept` + /// return `error(would-block)`, this pollable can be used to wait for + /// their success or failure, after which the method can be retried. + /// + /// The pollable is not limited to the async operation that happens to be + /// in progress at the time of calling `subscribe` (if any). Theoretically, + /// `subscribe` only has to be called once per socket and can then be + /// (re)used for the remainder of the socket's lifetime. + /// + /// See + /// for a more information. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + + /// Initiate a graceful shutdown. + /// + /// - `receive`: The socket is not expecting to receive any data from + /// the peer. The `input-stream` associated with this socket will be + /// closed. Any data still in the receive queue at time of calling + /// this method will be discarded. + /// - `send`: The socket has no more data to send to the peer. The `output-stream` + /// associated with this socket will be closed and a FIN packet will be sent. + /// - `both`: Same effect as `receive` & `send` combined. + /// + /// This function is idempotent. Shutting a down a direction more than once + /// has no effect and returns `ok`. + /// + /// The shutdown function does not close (drop) the socket. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; + } +} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/udp-create-socket.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/udp-create-socket.wit new file mode 100644 index 000000000..0482d1fe7 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/udp-create-socket.wit @@ -0,0 +1,27 @@ + +interface udp-create-socket { + use network.{network, error-code, ip-address-family}; + use udp.{udp-socket}; + + /// Create a new UDP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind` is called, + /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # Typical errors + /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References: + /// - + /// - + /// - + /// - + create-udp-socket: func(address-family: ip-address-family) -> result; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit new file mode 100644 index 000000000..d987a0a90 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit @@ -0,0 +1,266 @@ + +interface udp { + use wasi:io/poll@0.2.0.{pollable}; + use network.{network, error-code, ip-socket-address, ip-address-family}; + + /// A received datagram. + record incoming-datagram { + /// The payload. + /// + /// Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. + data: list, + + /// The source address. + /// + /// This field is guaranteed to match the remote address the stream was initialized with, if any. + /// + /// Equivalent to the `src_addr` out parameter of `recvfrom`. + remote-address: ip-socket-address, + } + + /// A datagram to be sent out. + record outgoing-datagram { + /// The payload. + data: list, + + /// The destination address. + /// + /// The requirements on this field depend on how the stream was initialized: + /// - with a remote address: this field must be None or match the stream's remote address exactly. + /// - without a remote address: this field is required. + /// + /// If this value is None, the send operation is equivalent to `send` in POSIX. Otherwise it is equivalent to `sendto`. + remote-address: option, + } + + + + /// A UDP socket handle. + resource udp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the port is zero, the socket will be bound to a random free port. + /// + /// # Typical errors + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `not-in-progress`: A `bind` operation is not in progress. + /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) + /// + /// # Implementors note + /// Unlike in POSIX, in WASI the bind operation is async. This enables + /// interactive WASI hosts to inject permission prompts. Runtimes that + /// don't want to make use of this ability can simply call the native + /// `bind` as part of either `start-bind` or `finish-bind`. + /// + /// # References + /// - + /// - + /// - + /// - + start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + finish-bind: func() -> result<_, error-code>; + + /// Set up inbound & outbound communication channels, optionally to a specific peer. + /// + /// This function only changes the local socket configuration and does not generate any network traffic. + /// On success, the `remote-address` of the socket is updated. The `local-address` may be updated as well, + /// based on the best network path to `remote-address`. + /// + /// When a `remote-address` is provided, the returned streams are limited to communicating with that specific peer: + /// - `send` can only be used to send to this destination. + /// - `receive` will only return datagrams sent from the provided `remote-address`. + /// + /// This method may be called multiple times on the same socket to change its association, but + /// only the most recently returned pair of streams will be operational. Implementations may trap if + /// the streams returned by a previous invocation haven't been dropped yet before calling `stream` again. + /// + /// The POSIX equivalent in pseudo-code is: + /// ```text + /// if (was previously connected) { + /// connect(s, AF_UNSPEC) + /// } + /// if (remote_address is Some) { + /// connect(s, remote_address) + /// } + /// ``` + /// + /// Unlike in POSIX, the socket must already be explicitly bound. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-state`: The socket is not bound. + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// + /// # References + /// - + /// - + /// - + /// - + %stream: func(remote-address: option) -> result, error-code>; + + /// Get the current bound address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + local-address: func() -> result; + + /// Get the address the socket is currently streaming to. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not streaming to a specific remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + remote-address: func() -> result; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + address-family: func() -> ip-address-family; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + unicast-hop-limit: func() -> result; + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + receive-buffer-size: func() -> result; + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + send-buffer-size: func() -> result; + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + + /// Create a `pollable` which will resolve once the socket is ready for I/O. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } + + resource incoming-datagram-stream { + /// Receive messages on the socket. + /// + /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. + /// The returned list may contain fewer elements than requested, but never more. + /// + /// This function returns successfully with an empty list when either: + /// - `max-results` is 0, or: + /// - `max-results` is greater than 0, but no results are immediately available. + /// This function never returns `error(would-block)`. + /// + /// # Typical errors + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + receive: func(max-results: u64) -> result, error-code>; + + /// Create a `pollable` which will resolve once the stream is ready to receive again. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } + + resource outgoing-datagram-stream { + /// Check readiness for sending. This function never blocks. + /// + /// Returns the number of datagrams permitted for the next call to `send`, + /// or an error. Calling `send` with more datagrams than this function has + /// permitted will trap. + /// + /// When this function returns ok(0), the `subscribe` pollable will + /// become ready when this function will report at least ok(1), or an + /// error. + /// + /// Never returns `would-block`. + check-send: func() -> result; + + /// Send messages on the socket. + /// + /// This function attempts to send all provided `datagrams` on the socket without blocking and + /// returns how many messages were actually sent (or queued for sending). This function never + /// returns `error(would-block)`. If none of the datagrams were able to be sent, `ok(0)` is returned. + /// + /// This function semantically behaves the same as iterating the `datagrams` list and sequentially + /// sending each individual datagram until either the end of the list has been reached or the first error occurred. + /// If at least one datagram has been sent successfully, this function never returns an error. + /// + /// If the input list is empty, the function returns `ok(0)`. + /// + /// Each call to `send` must be permitted by a preceding `check-send`. Implementations must trap if + /// either `check-send` was not called or `datagrams` contains more items than `check-send` permitted. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `stream`. (EISCONN) + /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + send: func(datagrams: list) -> result; + + /// Create a `pollable` which will resolve once the stream is ready to send again. + /// + /// Note: this function is here for WASI Preview2 only. + /// It's planned to be removed when `future` is natively supported in Preview3. + subscribe: func() -> pollable; + } +} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit new file mode 100644 index 000000000..f8bb92ae0 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit @@ -0,0 +1,11 @@ +package wasi:sockets@0.2.0; + +world imports { + import instance-network; + import network; + import udp; + import udp-create-socket; + import tcp; + import tcp-create-socket; + import ip-name-lookup; +} diff --git a/proposals/http/wit-0.3.0-draft/handler.wit b/proposals/http/wit-0.3.0-draft/handler.wit new file mode 100644 index 000000000..099d094c7 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/handler.wit @@ -0,0 +1,17 @@ +/// This interface defines a handler of HTTP Requests. It may be imported by +/// components which wish to send HTTP Requests and also exported by components +/// which can respond to HTTP Requests. In addition, it may be used to pass +/// a request from one component to another without any use of a network. +interface handler { + use types.{request, response, error-code}; + + /// When exported, this function may be called with either an incoming + /// request read from the network or a request synthesized or forwarded by + /// another component. + /// + /// When imported, this function may be used to either send an outgoing + /// request over the network or pass it to another component. + handle: func( + request: request, + ) -> result; +} diff --git a/proposals/http/wit-0.3.0-draft/proxy.wit b/proposals/http/wit-0.3.0-draft/proxy.wit new file mode 100644 index 000000000..2226bc011 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/proxy.wit @@ -0,0 +1,44 @@ +package wasi:http@0.3.0-draft; + +/// The `wasi:http/imports` world imports all the APIs for HTTP proxies. +/// It is intended to be `include`d in other worlds. +world imports { + /// HTTP proxies have access to time and randomness. + include wasi:clocks/imports@0.2.0; + import wasi:random/random@0.2.0; + + /// Proxies have standard output and error streams which are expected to + /// terminate in a developer-facing console provided by the host. + import wasi:cli/stdout@0.2.0; + import wasi:cli/stderr@0.2.0; + + /// TODO: this is a temporary workaround until component tooling is able to + /// gracefully handle the absence of stdin. Hosts must return an eof stream + /// for this import, which is what wasi-libc + tooling will do automatically + /// when this import is properly removed. + import wasi:cli/stdin@0.2.0; + + /// This is the default handler to use when user code simply wants to make an + /// HTTP request (e.g., via `fetch()`). + /// + /// This may also be used to pass synthesized or forwarded requests to another + /// component. + import handler; +} + +/// The `wasi:http/proxy` world captures a widely-implementable intersection of +/// hosts that includes HTTP forward and reverse proxies. Components targeting +/// this world may concurrently stream in and out any number of incoming and +/// outgoing HTTP requests. +world proxy { + include imports; + + /// The host delivers incoming HTTP requests to a component by calling the + /// `handle` function of this exported interface. A host may arbitrarily reuse + /// or not reuse component instance when delivering incoming HTTP requests and + /// thus a component must be able to handle 0..N calls to `handle`. + /// + /// This may also be used to receive synthesized or forwarded requests from + /// another component. + export handler; +} diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit new file mode 100644 index 000000000..d754bf46f --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -0,0 +1,423 @@ +/// This interface defines all of the types and methods for implementing HTTP +/// Requests and Responses, as well as their headers, trailers, and bodies. +interface types { + use wasi:clocks/monotonic-clock@0.2.0.{duration}; + use wasi:io/error@0.2.0.{error}; + + /// This type corresponds to HTTP standard Methods. + variant method { + get, + head, + post, + put, + delete, + connect, + options, + trace, + patch, + other(string) + } + + /// This type corresponds to HTTP standard Related Schemes. + variant scheme { + HTTP, + HTTPS, + other(string) + } + + /// These cases are inspired by the IANA HTTP Proxy Error Types: + /// https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types + variant error-code { + DNS-timeout, + DNS-error(DNS-error-payload), + destination-not-found, + destination-unavailable, + destination-IP-prohibited, + destination-IP-unroutable, + connection-refused, + connection-terminated, + connection-timeout, + connection-read-timeout, + connection-write-timeout, + connection-limit-reached, + TLS-protocol-error, + TLS-certificate-error, + TLS-alert-received(TLS-alert-received-payload), + HTTP-request-denied, + HTTP-request-length-required, + HTTP-request-body-size(option), + HTTP-request-method-invalid, + HTTP-request-URI-invalid, + HTTP-request-URI-too-long, + HTTP-request-header-section-size(option), + HTTP-request-header-size(option), + HTTP-request-trailer-section-size(option), + HTTP-request-trailer-size(field-size-payload), + HTTP-response-incomplete, + HTTP-response-header-section-size(option), + HTTP-response-header-size(field-size-payload), + HTTP-response-body-size(option), + HTTP-response-trailer-section-size(option), + HTTP-response-trailer-size(field-size-payload), + HTTP-response-transfer-coding(option), + HTTP-response-content-coding(option), + HTTP-response-timeout, + HTTP-upgrade-failed, + HTTP-protocol-error, + loop-detected, + configuration-error, + /// This is a catch-all error for anything that doesn't fit cleanly into a + /// more specific case. It also includes an optional string for an + /// unstructured description of the error. Users should not depend on the + /// string for diagnosing errors, as it's not required to be consistent + /// between implementations. + internal-error(option) + } + + /// Defines the case payload type for `DNS-error` above: + record DNS-error-payload { + rcode: option, + info-code: option + } + + /// Defines the case payload type for `TLS-alert-received` above: + record TLS-alert-received-payload { + alert-id: option, + alert-message: option + } + + /// Defines the case payload type for `HTTP-response-{header,trailer}-size` above: + record field-size-payload { + field-name: option, + field-size: option + } + + /// Attempts to extract a http-related `error-code` from the stream `error` + /// provided. + /// + /// Stream operations may fail with a stream `error` with more information + /// about the operation that failed. This `error` can be passed to this + /// function to see if there's http-related information about the error to + /// return. + /// + /// Note that this function is fallible because not all stream errors are + /// http-related errors. + http-error-code: func(err: borrow) -> option; + + /// This type enumerates the different kinds of errors that may occur when + /// setting or appending to a `fields` resource. + variant header-error { + /// This error indicates that a `field-key` or `field-value` was + /// syntactically invalid when used with an operation that sets headers in a + /// `fields`. + invalid-syntax, + + /// This error indicates that a forbidden `field-key` was used when trying + /// to set a header in a `fields`. + forbidden, + + /// This error indicates that the operation on the `fields` was not + /// permitted because the fields are immutable. + immutable, + } + + /// This type enumerates the different kinds of errors that may occur when + /// setting fields of a `request-options` resource. + variant request-options-error { + /// Indicates the specified field is not supported by this implementation. + not-supported, + + /// Indicates that the operation on the `request-options` was not permitted + /// because it is immutable. + immutable, + } + + /// Field keys are always strings. + type field-key = string; + + /// Field values should always be ASCII strings. However, in + /// reality, HTTP implementations often have to interpret malformed values, + /// so they are provided as a list of bytes. + type field-value = list; + + /// This following block defines the `fields` resource which corresponds to + /// HTTP standard Fields. Fields are a common representation used for both + /// Headers and Trailers. + /// + /// A `fields` may be mutable or immutable. A `fields` created using the + /// constructor, `from-list`, or `clone` will be mutable, but a `fields` + /// resource given by other means (including, but not limited to, + /// `request.headers`) might be be immutable. In an immutable fields, the + /// `set`, `append`, and `delete` operations will fail with + /// `header-error.immutable`. + resource fields { + + /// Construct an empty HTTP Fields. + /// + /// The resulting `fields` is mutable. + constructor(); + + /// Construct an HTTP Fields. + /// + /// The resulting `fields` is mutable. + /// + /// The list represents each key-value pair in the Fields. Keys + /// which have multiple values are represented by multiple entries in this + /// list with the same key. + /// + /// The tuple is a pair of the field key, represented as a string, and + /// Value, represented as a list of bytes. In a valid Fields, all keys + /// and values are valid UTF-8 strings. However, values are not always + /// well-formed, so they are represented as a raw list of bytes. + /// + /// An error result will be returned if any header or value was + /// syntactically invalid, or if a header was forbidden. + from-list: static func( + entries: list> + ) -> result; + + /// Get all of the values corresponding to a key. If the key is not present + /// in this `fields`, an empty list is returned. However, if the key is + /// present but empty, this is represented by a list with one or more + /// empty field-values present. + get: func(name: field-key) -> list; + + /// Returns `true` when the key is present in this `fields`. If the key is + /// syntactically invalid, `false` is returned. + has: func(name: field-key) -> bool; + + /// Set all of the values for a key. Clears any existing values for that + /// key, if they have been set. + /// + /// Fails with `header-error.immutable` if the `fields` are immutable. + set: func(name: field-key, value: list) -> result<_, header-error>; + + /// Delete all values for a key. Does nothing if no values for the key + /// exist. + /// + /// Fails with `header-error.immutable` if the `fields` are immutable. + delete: func(name: field-key) -> result<_, header-error>; + + /// Append a value for a key. Does not change or delete any existing + /// values for that key. + /// + /// Fails with `header-error.immutable` if the `fields` are immutable. + append: func(name: field-key, value: field-value) -> result<_, header-error>; + + /// Retrieve the full set of keys and values in the Fields. Like the + /// constructor, the list represents each key-value pair. + /// + /// The outer list represents each key-value pair in the Fields. Keys + /// which have multiple values are represented by multiple entries in this + /// list with the same key. + entries: func() -> list>; + + /// Make a deep copy of the Fields. Equivelant in behavior to calling the + /// `fields` constructor on the return value of `entries`. The resulting + /// `fields` is mutable. + clone: func() -> fields; + } + + /// Headers is an alias for Fields. + type headers = fields; + + /// Trailers is an alias for Fields. + type trailers = fields; + + /// Represents an HTTP Request or Response's Body. + /// + /// A body has both its contents - a stream of bytes - and a (possibly empty) + /// set of trailers, indicating that the full contents of the body have been + /// received. This resource represents the contents as a `stream` and the + /// delivery of trailers as a `trailers`, and ensures that the user of this + /// interface may only be consuming either the body contents or waiting on + /// trailers at any given time. + resource body { + + /// Construct a new `body` with the specified stream and trailers. + constructor( + %stream: stream, + trailers: option> + ); + + /// Returns the contents of the body, as a stream of bytes. + /// + /// This function may be called multiple times as long as any `stream`s + /// returned by previous calls have been dropped first. + %stream: func() -> result>; + + /// Takes ownership of `body`, and returns a `trailers`. This function will + /// trap if a `stream` child is still alive. + finish: static func(this: body) -> result, error-code>; + } + + /// Represents an HTTP Request. + resource request { + + /// Construct a new `request` with a default `method` of `GET`, and + /// `none` values for `path-with-query`, `scheme`, and `authority`. + /// + /// * `headers` is the HTTP Headers for the Response. + /// * `body` is the contents of the body, as a stream of bytes. + /// * `trailers` is an optional `future` which resolves to the HTTP Trailers + /// for the Response. + /// * `options` is optional `request-options` to be used if the request is + /// sent over a network connection. + /// + /// It is possible to construct, or manipulate with the accessor functions + /// below, an `request` with an invalid combination of `scheme` + /// and `authority`, or `headers` which are not permitted to be sent. + /// It is the obligation of the `handler.handle` implementation + /// to reject invalid constructions of `request`. + constructor( + headers: headers, + body: body, + options: option + ); + + /// Get the Method for the Request. + method: func() -> method; + /// Set the Method for the Request. Fails if the string present in a + /// `method.other` argument is not a syntactically valid method. + set-method: func(method: method) -> result; + + /// Get the combination of the HTTP Path and Query for the Request. When + /// `none`, this represents an empty Path and empty Query. + path-with-query: func() -> option; + /// Set the combination of the HTTP Path and Query for the Request. When + /// `none`, this represents an empty Path and empty Query. Fails is the + /// string given is not a syntactically valid path and query uri component. + set-path-with-query: func(path-with-query: option) -> result; + + /// Get the HTTP Related Scheme for the Request. When `none`, the + /// implementation may choose an appropriate default scheme. + scheme: func() -> option; + /// Set the HTTP Related Scheme for the Request. When `none`, the + /// implementation may choose an appropriate default scheme. Fails if the + /// string given is not a syntactically valid uri scheme. + set-scheme: func(scheme: option) -> result; + + /// Get the HTTP Authority for the Request. A value of `none` may be used + /// with Related Schemes which do not require an Authority. The HTTP and + /// HTTPS schemes always require an authority. + authority: func() -> option; + /// Set the HTTP Authority for the Request. A value of `none` may be used + /// with Related Schemes which do not require an Authority. The HTTP and + /// HTTPS schemes always require an authority. Fails if the string given is + /// not a syntactically valid uri authority. + set-authority: func(authority: option) -> result; + + /// Get the `request-options` to be associated with this request + /// + /// The returned `request-options` resource is immutable: `set-*` operations + /// will fail if invoked. + /// + /// This `request-options` resource is a child: it must be dropped before + /// the parent `request` is dropped, or its ownership is transfered to + /// another component by e.g. `handler.handle`. + options: func() -> option; + + /// Get the headers associated with the Request. + /// + /// The returned `headers` resource is immutable: `set`, `append`, and + /// `delete` operations will fail with `header-error.immutable`. + /// + /// This headers resource is a child: it must be dropped before the parent + /// `request` is dropped, or its ownership is transfered to another + /// component by e.g. `handler.handle`. + headers: func() -> headers; + + /// Get the body associated with the Request. + /// + /// This body resource is a child: it must be dropped before the parent + /// `request` is dropped, or its ownership is transfered to another + /// component by e.g. `handler.handle`. + body: func() -> body; + + /// Takes onwership of the `request` and returns the `headers` and `body`. + into-parts: static func(this: request) -> tuple; + } + + /// Parameters for making an HTTP Request. Each of these parameters is + /// currently an optional timeout applicable to the transport layer of the + /// HTTP protocol. + /// + /// These timeouts are separate from any the user may use to bound an + /// asynchronous call. + resource request-options { + /// Construct a default `request-options` value. + constructor(); + + /// The timeout for the initial connect to the HTTP Server. + connect-timeout: func() -> option; + + /// Set the timeout for the initial connect to the HTTP Server. An error + /// return value indicates that this timeout is not supported or that this + /// handle is immutable. + set-connect-timeout: func(duration: option) -> result<_, request-options-error>; + + /// The timeout for receiving the first byte of the Response body. + first-byte-timeout: func() -> option; + + /// Set the timeout for receiving the first byte of the Response body. An + /// error return value indicates that this timeout is not supported or that + /// this handle is immutable. + set-first-byte-timeout: func(duration: option) -> result<_, request-options-error>; + + /// The timeout for receiving subsequent chunks of bytes in the Response + /// body stream. + between-bytes-timeout: func() -> option; + + /// Set the timeout for receiving subsequent chunks of bytes in the Response + /// body stream. An error return value indicates that this timeout is not + /// supported or that this handle is immutable. + set-between-bytes-timeout: func(duration: option) -> result<_, request-options-error>; + } + + /// This type corresponds to the HTTP standard Status Code. + type status-code = u16; + + /// Represents an HTTP Response. + resource response { + + /// Construct an `response`, with a default `status-code` of `200`. If a + /// different `status-code` is needed, it must be set via the + /// `set-status-code` method. + /// + /// * `headers` is the HTTP Headers for the Response. + /// * `body` is the contents of the body, as a stream of bytes. + /// * `trailers` is an optional `future` which resolves to the HTTP Trailers + /// for the Response. + constructor( + headers: headers, + body: body, + ); + + /// Get the HTTP Status Code for the Response. + status-code: func() -> status-code; + + /// Set the HTTP Status Code for the Response. Fails if the status-code + /// given is not a valid http status code. + set-status-code: func(status-code: status-code) -> result; + + /// Get the headers associated with the Request. + /// + /// The returned `headers` resource is immutable: `set`, `append`, and + /// `delete` operations will fail with `header-error.immutable`. + /// + /// This headers resource is a child: it must be dropped before the parent + /// `response` is dropped, or its ownership is transfered to another + /// component by e.g. `handler.handle`. + headers: func() -> headers; + + /// Get the body associated with the Response. + /// + /// This body resource is a child: it must be dropped before the parent + /// `response` is dropped, or its ownership is transfered to another + /// component by e.g. `handler.handle`. + body: func() -> body; + + /// Takes onwership of the `response` and returns the `headers` and `body`. + into-parts: static func(this: response) -> tuple; + } +} From a174e58a339420c400a619e02f4b739c78d75ad9 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Sun, 17 Mar 2024 16:23:44 -0600 Subject: [PATCH 1431/1772] [0.3.0-draft] make {request|response} body optional (#109) This makes creating e.g. outbound GET requests easier and more efficient. Signed-off-by: Joel Dice --- proposals/http/wit-0.3.0-draft/types.wit | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index d754bf46f..fba48ccf2 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -258,9 +258,8 @@ interface types { /// `none` values for `path-with-query`, `scheme`, and `authority`. /// /// * `headers` is the HTTP Headers for the Response. - /// * `body` is the contents of the body, as a stream of bytes. - /// * `trailers` is an optional `future` which resolves to the HTTP Trailers - /// for the Response. + /// * `body` is the optional contents of the body, possibly including + /// trailers. /// * `options` is optional `request-options` to be used if the request is /// sent over a network connection. /// @@ -271,7 +270,7 @@ interface types { /// to reject invalid constructions of `request`. constructor( headers: headers, - body: body, + body: option, options: option ); @@ -327,15 +326,16 @@ interface types { /// component by e.g. `handler.handle`. headers: func() -> headers; - /// Get the body associated with the Request. + /// Get the body associated with the Request, if any. /// /// This body resource is a child: it must be dropped before the parent /// `request` is dropped, or its ownership is transfered to another /// component by e.g. `handler.handle`. - body: func() -> body; + body: func() -> option; - /// Takes onwership of the `request` and returns the `headers` and `body`. - into-parts: static func(this: request) -> tuple; + /// Takes ownership of the `request` and returns the `headers` and `body`, + /// if any. + into-parts: static func(this: request) -> tuple>; } /// Parameters for making an HTTP Request. Each of these parameters is @@ -385,12 +385,11 @@ interface types { /// `set-status-code` method. /// /// * `headers` is the HTTP Headers for the Response. - /// * `body` is the contents of the body, as a stream of bytes. - /// * `trailers` is an optional `future` which resolves to the HTTP Trailers - /// for the Response. + /// * `body` is the optional contents of the body, possibly including + /// trailers. constructor( headers: headers, - body: body, + body: option, ); /// Get the HTTP Status Code for the Response. @@ -410,14 +409,15 @@ interface types { /// component by e.g. `handler.handle`. headers: func() -> headers; - /// Get the body associated with the Response. + /// Get the body associated with the Response, if any. /// /// This body resource is a child: it must be dropped before the parent /// `response` is dropped, or its ownership is transfered to another /// component by e.g. `handler.handle`. - body: func() -> body; + body: func() -> option; - /// Takes onwership of the `response` and returns the `headers` and `body`. - into-parts: static func(this: response) -> tuple; + /// Takes ownership of the `response` and returns the `headers` and `body`, + /// if any. + into-parts: static func(this: response) -> tuple>; } } From a996dd4bb461a7e2c1cd4be463fd812fe6b9f4ac Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 18 Mar 2024 10:31:33 -0600 Subject: [PATCH 1432/1772] [0.3.0-draft] add `fields.get-and-delete` This saves the user from having to use `get` followed by `delete` if they want access to the values they're removing. Signed-off-by: Joel Dice --- proposals/http/wit-0.3.0-draft/types.wit | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index fba48ccf2..e28332939 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -198,6 +198,14 @@ interface types { /// Fails with `header-error.immutable` if the `fields` are immutable. delete: func(name: field-key) -> result<_, header-error>; + /// Delete all values for a key. Does nothing if no values for the key + /// exist. + /// + /// Returns all values previously corresponding to the key, if any. + /// + /// Fails with `header-error.immutable` if the `fields` are immutable. + get-and-delete: func(name: field-key) -> result, header-error>; + /// Append a value for a key. Does not change or delete any existing /// values for that key. /// From 4efe438eeea085d8793a4d0b8230a247dab75545 Mon Sep 17 00:00:00 2001 From: Frank Rehwinkel Date: Sat, 27 Apr 2024 08:24:42 -0400 Subject: [PATCH 1433/1772] comment sentence structure --- proposals/sockets/imports.md | 4 ++-- proposals/sockets/wit/tcp.wit | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 45ff95366..512453c82 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -1210,7 +1210,7 @@ occured.

                        • connected
                        • closed See https://github.com/WebAssembly/wasi-sockets/TcpSocketOperationalSemantics.md -for a more information.
                        • +for more information.

                        Note: Except where explicitly mentioned, whenever this documentation uses the term "bound" without backticks it actually means: in the bound state or higher. @@ -1700,7 +1700,7 @@ in progress at the time of calling subscribe (if any). Theoreticall subscribe only has to be called once per socket and can then be (re)used for the remainder of the socket's lifetime.

                        See https://github.com/WebAssembly/wasi-sockets/TcpSocketOperationalSemantics.md#Pollable-readiness -for a more information.

                        +for more information.

                        Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

                        Params
                        diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 5902b9ee0..310b5093a 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -27,8 +27,8 @@ interface tcp { /// - `connect-in-progress` /// - `connected` /// - `closed` - /// See - /// for a more information. + /// See + /// for more information. /// /// Note: Except where explicitly mentioned, whenever this documentation uses /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. @@ -318,8 +318,8 @@ interface tcp { /// `subscribe` only has to be called once per socket and can then be /// (re)used for the remainder of the socket's lifetime. /// - /// See - /// for a more information. + /// See + /// for more information. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. From ad1d26abb03c3650022307d8396564cb41a1069c Mon Sep 17 00:00:00 2001 From: Frank Rehwinkel Date: Sat, 27 Apr 2024 08:26:33 -0400 Subject: [PATCH 1434/1772] consistent number of blank lines --- proposals/sockets/wit/network.wit | 4 ---- 1 file changed, 4 deletions(-) diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 9cadf0650..cee7cb3cf 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -61,7 +61,6 @@ interface network { /// Note: this is scheduled to be removed when `future`s are natively supported. would-block, - /// The operation is not valid in the socket's current state. invalid-state, @@ -77,7 +76,6 @@ interface network { /// The remote address is not reachable remote-unreachable, - /// The TCP connection was forcefully rejected connection-refused, @@ -87,12 +85,10 @@ interface network { /// A TCP connection was aborted. connection-aborted, - /// The size of a datagram sent to a UDP socket exceeded the maximum /// supported size. datagram-too-large, - /// Name does not exist or has no suitable associated IP addresses. name-unresolvable, From 8e648f87b027b52d660af430d547158842a5b96f Mon Sep 17 00:00:00 2001 From: Frank Rehwinkel Date: Sat, 27 Apr 2024 08:27:37 -0400 Subject: [PATCH 1435/1772] fix `connected` name in comment --- proposals/sockets/wit/tcp.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 310b5093a..a96e18270 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -82,7 +82,7 @@ interface tcp { /// Connect to a remote endpoint. /// /// On success: - /// - the socket is transitioned into the `connection` state. + /// - the socket is transitioned into the `connected` state. /// - a pair of streams is returned that can be used to read & write to the connection /// /// After a failed connection attempt, the socket will be in the `closed` From 84fa643950c025e3405ac56f8e472a4a704e8bc4 Mon Sep 17 00:00:00 2001 From: Frank Rehwinkel Date: Sat, 27 Apr 2024 08:28:13 -0400 Subject: [PATCH 1436/1772] slight sentence structure adjustment --- proposals/sockets/wit/tcp.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index a96e18270..9aa79bde8 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -335,7 +335,7 @@ interface tcp { /// associated with this socket will be closed and a FIN packet will be sent. /// - `both`: Same effect as `receive` & `send` combined. /// - /// This function is idempotent. Shutting a down a direction more than once + /// This function is idempotent; shutting down a direction more than once /// has no effect and returns `ok`. /// /// The shutdown function does not close (drop) the socket. From a33d9e8080c3e37463fd6f5411645b2c798fb72f Mon Sep 17 00:00:00 2001 From: FrankReh Date: Mon, 29 Apr 2024 16:19:31 -0400 Subject: [PATCH 1437/1772] Comment changes (#77) * comment typos * error comment: another approach I wasn't able to parse the error comment. Could just be me. --- proposals/io/imports.md | 2 +- proposals/io/wit/error.wit | 12 +++++------- proposals/io/wit/poll.wit | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index 1ae5b12e8..be5b89945 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -84,7 +84,7 @@ wasi-clocks API to the list.

                        This function does not return a result; polling in itself does not do any I/O so it doesn't fail. If any of the I/O sources identified by the pollables has an error, it is indicated by marking the source as -being reaedy for I/O.

                        +being ready for I/O.

                        Params
                        • in: list<borrow<pollable>>
                        • diff --git a/proposals/io/wit/error.wit b/proposals/io/wit/error.wit index 22e5b6489..8d11483a9 100644 --- a/proposals/io/wit/error.wit +++ b/proposals/io/wit/error.wit @@ -11,13 +11,11 @@ interface error { /// `wasi:io/streams/stream-error` type. /// /// To provide more specific error information, other interfaces may - /// provide functions to further "downcast" this error into more specific - /// error information. For example, `error`s returned in streams derived - /// from filesystem types to be described using the filesystem's own - /// error-code type, using the function - /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter - /// `borrow` and returns - /// `option`. + /// offer functions to "downcast" this error into more specific types. For example, + /// errors returned from streams derived from filesystem types can be described using + /// the filesystem's own error-code type. This is done using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a `borrow` + /// parameter and returns an `option`. /// /// The set of functions which can "downcast" an `error` into a more /// concrete type is open. diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index ddc67f8b7..b1e120eb7 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -36,6 +36,6 @@ interface poll { /// This function does not return a `result`; polling in itself does not /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as - /// being reaedy for I/O. + /// being ready for I/O. poll: func(in: list>) -> list; } From dc3290d618fb93a919dd4248e4c6b214d60e86cb Mon Sep 17 00:00:00 2001 From: FrankReh Date: Mon, 29 Apr 2024 16:20:28 -0400 Subject: [PATCH 1438/1772] Comment adjustments (#63) * comment sentence structure * remove redundancy in comment --- proposals/clocks/README.md | 2 +- proposals/clocks/imports.md | 7 +++---- proposals/clocks/wit/monotonic-clock.wit | 9 +++------ 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 919f6cb7e..1690e32b9 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -42,7 +42,7 @@ WASI Clocks is a WASI API for reading the current time and measuring elapsed time. Unlike many clock APIs, WASI Clocks is capability-oriented. Instead -of having functions that implicitly reference a clock, WASI clocks' APIs are +of having functions that implicitly reference a clock, WASI Clocks' APIs are passed a clock handle. ### Goals diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index 7857ce6ef..126ff577a 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -98,7 +98,7 @@ corresponding to a clock tick.

                        subscribe-instant: func

                        Create a pollable which will resolve once the specified instant -occured.

                        +has occurred.

                        Params

                        subscribe-duration: func

                        -

                        Create a pollable which will resolve once the given duration has -elapsed, starting at the time at which this function was called. -occured.

                        +

                        Create a pollable that will resolve after the specified duration has +elapsed from the time this function is invoked.

                        Params
                        • when: duration
                        • diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index 4e4dc3a19..a242b41c3 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -7,8 +7,6 @@ package wasi:clocks@0.2.0; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -/// -/// It is intended for measuring elapsed time. interface monotonic-clock { use wasi:io/poll@0.2.0.{pollable}; @@ -31,14 +29,13 @@ interface monotonic-clock { resolution: func() -> duration; /// Create a `pollable` which will resolve once the specified instant - /// occured. + /// has occurred. subscribe-instant: func( when: instant, ) -> pollable; - /// Create a `pollable` which will resolve once the given duration has - /// elapsed, starting at the time at which this function was called. - /// occured. + /// Create a `pollable` that will resolve after the specified duration has + /// elapsed from the time this function is invoked. subscribe-duration: func( when: duration, ) -> pollable; From 3ba10b4a9fed3796687374b09ecf9c4c0bd32a4d Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Mon, 13 May 2024 20:06:41 +0200 Subject: [PATCH 1439/1772] Regenerate imports.md --- proposals/sockets/imports.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 512453c82..6716d298b 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -1209,7 +1209,7 @@ occured.

                        • connect-in-progress
                        • connected
                        • closed -See https://github.com/WebAssembly/wasi-sockets/TcpSocketOperationalSemantics.md +See https://github.com/WebAssembly/wasi-sockets/blob/main/TcpSocketOperationalSemantics.md for more information.

                        Note: Except where explicitly mentioned, whenever this documentation uses @@ -1279,7 +1279,7 @@ don't want to make use of this ability can simply call the native

                        Connect to a remote endpoint.

                        On success:

                          -
                        • the socket is transitioned into the connection state.
                        • +
                        • the socket is transitioned into the connected state.
                        • a pair of streams is returned that can be used to read & write to the connection

                        After a failed connection attempt, the socket will be in the closed @@ -1699,7 +1699,7 @@ their success or failure, after which the method can be retried.

                        in progress at the time of calling subscribe (if any). Theoretically, subscribe only has to be called once per socket and can then be (re)used for the remainder of the socket's lifetime.

                        -

                        See https://github.com/WebAssembly/wasi-sockets/TcpSocketOperationalSemantics.md#Pollable-readiness +

                        See https://github.com/WebAssembly/wasi-sockets/blob/main/TcpSocketOperationalSemantics.md#pollable-readiness for more information.

                        Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

                        @@ -1722,7 +1722,7 @@ this method will be discarded. associated with this socket will be closed and a FIN packet will be sent.
                      • both: Same effect as receive & send combined.
                      -

                      This function is idempotent. Shutting a down a direction more than once +

                      This function is idempotent; shutting down a direction more than once has no effect and returns ok.

                      The shutdown function does not close (drop) the socket.

                      Typical errors

                      From 6599a2411ee3a3d271bbce6cd7a9e6795ecbc92b Mon Sep 17 00:00:00 2001 From: Yosh Date: Tue, 28 May 2024 14:09:28 +0200 Subject: [PATCH 1440/1772] Document per-item versions using `@since` gates --- proposals/cli/wit/command.wit | 3 +++ proposals/cli/wit/environment.wit | 4 ++++ proposals/cli/wit/exit.wit | 2 ++ proposals/cli/wit/imports.wit | 16 ++++++++++++++++ proposals/cli/wit/run.wit | 2 ++ proposals/cli/wit/stdio.wit | 6 ++++++ proposals/cli/wit/terminal.wit | 10 ++++++++++ 7 files changed, 43 insertions(+) diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index d8005bd38..0fc85e95a 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,7 +1,10 @@ package wasi:cli@0.2.0; +@since(version = 0.2.0) world command { + @since(version = 0.2.0) include imports; + @since(version = 0.2.0) export run; } diff --git a/proposals/cli/wit/environment.wit b/proposals/cli/wit/environment.wit index 70065233e..2f449bd7c 100644 --- a/proposals/cli/wit/environment.wit +++ b/proposals/cli/wit/environment.wit @@ -1,3 +1,4 @@ +@since(version = 0.2.0) interface environment { /// Get the POSIX-style environment variables. /// @@ -7,12 +8,15 @@ interface environment { /// Morally, these are a value import, but until value imports are available /// in the component model, this import function should return the same /// values each time it is called. + @since(version = 0.2.0) get-environment: func() -> list>; /// Get the POSIX-style arguments to the program. + @since(version = 0.2.0) get-arguments: func() -> list; /// Return a path that programs should use as their initial current working /// directory, interpreting `.` as shorthand for this. + @since(version = 0.2.0) initial-cwd: func() -> option; } diff --git a/proposals/cli/wit/exit.wit b/proposals/cli/wit/exit.wit index d0c2b82ae..357e6707b 100644 --- a/proposals/cli/wit/exit.wit +++ b/proposals/cli/wit/exit.wit @@ -1,4 +1,6 @@ +@since(version = 0.2.0) interface exit { /// Exit the current instance and any linked instances. + @since(version = 0.2.0) exit: func(status: result); } diff --git a/proposals/cli/wit/imports.wit b/proposals/cli/wit/imports.wit index 083b84a03..cd59ba1c0 100644 --- a/proposals/cli/wit/imports.wit +++ b/proposals/cli/wit/imports.wit @@ -1,20 +1,36 @@ package wasi:cli@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) include wasi:clocks/imports@0.2.0; + @since(version = 0.2.0) include wasi:filesystem/imports@0.2.0; + @since(version = 0.2.0) include wasi:sockets/imports@0.2.0; + @since(version = 0.2.0) include wasi:random/imports@0.2.0; + @since(version = 0.2.0) include wasi:io/imports@0.2.0; + @since(version = 0.2.0) import environment; + @since(version = 0.2.0) import exit; + @since(version = 0.2.0) import stdin; + @since(version = 0.2.0) import stdout; + @since(version = 0.2.0) import stderr; + @since(version = 0.2.0) import terminal-input; + @since(version = 0.2.0) import terminal-output; + @since(version = 0.2.0) import terminal-stdin; + @since(version = 0.2.0) import terminal-stdout; + @since(version = 0.2.0) import terminal-stderr; } diff --git a/proposals/cli/wit/run.wit b/proposals/cli/wit/run.wit index a70ee8c03..655346efb 100644 --- a/proposals/cli/wit/run.wit +++ b/proposals/cli/wit/run.wit @@ -1,4 +1,6 @@ +@since(version = 0.2.0) interface run { /// Run the program. + @since(version = 0.2.0) run: func() -> result; } diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index 31ef35b5a..584b3e836 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,17 +1,23 @@ +@since(version = 0.2.0) interface stdin { use wasi:io/streams@0.2.0.{input-stream}; + @since(version = 0.2.0) get-stdin: func() -> input-stream; } +@since(version = 0.2.0) interface stdout { use wasi:io/streams@0.2.0.{output-stream}; + @since(version = 0.2.0) get-stdout: func() -> output-stream; } +@since(version = 0.2.0) interface stderr { use wasi:io/streams@0.2.0.{output-stream}; + @since(version = 0.2.0) get-stderr: func() -> output-stream; } diff --git a/proposals/cli/wit/terminal.wit b/proposals/cli/wit/terminal.wit index 38c724efc..c1d9c7092 100644 --- a/proposals/cli/wit/terminal.wit +++ b/proposals/cli/wit/terminal.wit @@ -3,8 +3,10 @@ /// In the future, this may include functions for disabling echoing, /// disabling input buffering so that keyboard events are sent through /// immediately, querying supported features, and so on. +@since(version = 0.2.0) interface terminal-input { /// The input side of a terminal. + @since(version = 0.2.0) resource terminal-input; } @@ -13,37 +15,45 @@ interface terminal-input { /// In the future, this may include functions for querying the terminal /// size, being notified of terminal size changes, querying supported /// features, and so on. +@since(version = 0.2.0) interface terminal-output { /// The output side of a terminal. + @since(version = 0.2.0) resource terminal-output; } /// An interface providing an optional `terminal-input` for stdin as a /// link-time authority. +@since(version = 0.2.0) interface terminal-stdin { use terminal-input.{terminal-input}; /// If stdin is connected to a terminal, return a `terminal-input` handle /// allowing further interaction with it. + @since(version = 0.2.0) get-terminal-stdin: func() -> option; } /// An interface providing an optional `terminal-output` for stdout as a /// link-time authority. +@since(version = 0.2.0) interface terminal-stdout { use terminal-output.{terminal-output}; /// If stdout is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. + @since(version = 0.2.0) get-terminal-stdout: func() -> option; } /// An interface providing an optional `terminal-output` for stderr as a /// link-time authority. +@since(version = 0.2.0) interface terminal-stderr { use terminal-output.{terminal-output}; /// If stderr is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. + @since(version = 0.2.0) get-terminal-stderr: func() -> option; } From 2d4fcbe77f76e0cd900bd69a93cd75e9626e176c Mon Sep 17 00:00:00 2001 From: Yosh Date: Tue, 28 May 2024 14:42:08 +0200 Subject: [PATCH 1441/1772] Document per-item versions using `@since` gates --- proposals/sockets/wit/instance-network.wit | 3 +- proposals/sockets/wit/ip-name-lookup.wit | 7 +++-- proposals/sockets/wit/network.wit | 16 +++++++++-- proposals/sockets/wit/tcp-create-socket.wit | 3 +- proposals/sockets/wit/tcp.wit | 32 ++++++++++++++++++++- proposals/sockets/wit/udp-create-socket.wit | 3 +- proposals/sockets/wit/udp.wit | 26 +++++++++++++++-- proposals/sockets/wit/world.wit | 8 ++++++ 8 files changed, 87 insertions(+), 11 deletions(-) diff --git a/proposals/sockets/wit/instance-network.wit b/proposals/sockets/wit/instance-network.wit index e455d0ff7..55dc11aba 100644 --- a/proposals/sockets/wit/instance-network.wit +++ b/proposals/sockets/wit/instance-network.wit @@ -1,9 +1,10 @@ /// This interface provides a value-export of the default network handle.. +@since(version = 0.2.0) interface instance-network { use network.{network}; /// Get a handle to the default network. + @since(version = 0.2.0) instance-network: func() -> network; - } diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index 8e639ec59..83c6c74e1 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,9 +1,8 @@ - +@since(version = 0.2.0) interface ip-name-lookup { use wasi:io/poll@0.2.0.{pollable}; use network.{network, error-code, ip-address}; - /// Resolve an internet host name to a list of IP addresses. /// /// Unicode domain names are automatically converted to ASCII using IDNA encoding. @@ -24,8 +23,10 @@ interface ip-name-lookup { /// - /// - /// - + @since(version = 0.2.0) resolve-addresses: func(network: borrow, name: string) -> result; + @since(version = 0.2.0) resource resolve-address-stream { /// Returns the next address from the resolver. /// @@ -40,12 +41,14 @@ interface ip-name-lookup { /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) + @since(version = 0.2.0) resolve-next-address: func() -> result, error-code>; /// Create a `pollable` which will resolve once the stream is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } } diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index cee7cb3cf..8c13b348e 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -1,8 +1,9 @@ - +@since(version = 0.2.0) interface network { /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. + @since(version = 0.2.0) resource network; /// Error codes. @@ -17,6 +18,7 @@ interface network { /// - `concurrency-conflict` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. + @since(version = 0.2.0) enum error-code { /// Unknown error unknown, @@ -61,6 +63,7 @@ interface network { /// Note: this is scheduled to be removed when `future`s are natively supported. would-block, + /// The operation is not valid in the socket's current state. invalid-state, @@ -76,6 +79,7 @@ interface network { /// The remote address is not reachable remote-unreachable, + /// The TCP connection was forcefully rejected connection-refused, @@ -85,10 +89,12 @@ interface network { /// A TCP connection was aborted. connection-aborted, + /// The size of a datagram sent to a UDP socket exceeded the maximum /// supported size. datagram-too-large, + /// Name does not exist or has no suitable associated IP addresses. name-unresolvable, @@ -99,6 +105,7 @@ interface network { permanent-resolver-failure, } + @since(version = 0.2.0) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -107,14 +114,18 @@ interface network { ipv6, } + @since(version = 0.2.0) type ipv4-address = tuple; + @since(version = 0.2.0) type ipv6-address = tuple; + @since(version = 0.2.0) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } + @since(version = 0.2.0) record ipv4-socket-address { /// sin_port port: u16, @@ -122,6 +133,7 @@ interface network { address: ipv4-address, } + @since(version = 0.2.0) record ipv6-socket-address { /// sin6_port port: u16, @@ -133,9 +145,9 @@ interface network { scope-id: u32, } + @since(version = 0.2.0) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), } - } diff --git a/proposals/sockets/wit/tcp-create-socket.wit b/proposals/sockets/wit/tcp-create-socket.wit index c7ddf1f22..a283f8b4b 100644 --- a/proposals/sockets/wit/tcp-create-socket.wit +++ b/proposals/sockets/wit/tcp-create-socket.wit @@ -1,4 +1,4 @@ - +@since(version = 0.2.0) interface tcp-create-socket { use network.{network, error-code, ip-address-family}; use tcp.{tcp-socket}; @@ -23,5 +23,6 @@ interface tcp-create-socket { /// - /// - /// - + @since(version = 0.2.0) create-tcp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 9aa79bde8..e52a8c81a 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,10 +1,11 @@ - +@since(version = 0.2.0) interface tcp { use wasi:io/streams@0.2.0.{input-stream, output-stream}; use wasi:io/poll@0.2.0.{pollable}; use wasi:clocks/monotonic-clock@0.2.0.{duration}; use network.{network, error-code, ip-socket-address, ip-address-family}; + @since(version = 0.2.0) enum shutdown-type { /// Similar to `SHUT_RD` in POSIX. receive, @@ -37,6 +38,7 @@ interface tcp { /// In addition to the general error codes documented on the /// `network::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. + @since(version = 0.2.0) resource tcp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -76,7 +78,9 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) finish-bind: func() -> result<_, error-code>; /// Connect to a remote endpoint. @@ -121,7 +125,9 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) finish-connect: func() -> result, error-code>; /// Start listening for new connections. @@ -149,7 +155,9 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) start-listen: func() -> result<_, error-code>; + @since(version = 0.2.0) finish-listen: func() -> result<_, error-code>; /// Accept a new client socket. @@ -178,6 +186,7 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) accept: func() -> result, error-code>; /// Get the bound local address. @@ -196,6 +205,7 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) local-address: func() -> result; /// Get the remote address. @@ -208,16 +218,19 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. + @since(version = 0.2.0) is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.2.0) address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. @@ -229,6 +242,7 @@ interface tcp { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. + @since(version = 0.2.0) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -240,7 +254,9 @@ interface tcp { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. + @since(version = 0.2.0) keep-alive-enabled: func() -> result; + @since(version = 0.2.0) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. @@ -253,7 +269,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) keep-alive-idle-time: func() -> result; + @since(version = 0.2.0) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. @@ -266,7 +284,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) keep-alive-interval: func() -> result; + @since(version = 0.2.0) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. @@ -279,7 +299,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) keep-alive-count: func() -> result; + @since(version = 0.2.0) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -288,7 +310,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.2.0) hop-limit: func() -> result; + @since(version = 0.2.0) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -301,9 +325,13 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) receive-buffer-size: func() -> result; + @since(version = 0.2.0) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) send-buffer-size: func() -> result; + @since(version = 0.2.0) set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Create a `pollable` which can be used to poll for, or block on, @@ -323,6 +351,7 @@ interface tcp { /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; /// Initiate a graceful shutdown. @@ -348,6 +377,7 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; } } diff --git a/proposals/sockets/wit/udp-create-socket.wit b/proposals/sockets/wit/udp-create-socket.wit index 0482d1fe7..90f3d83a7 100644 --- a/proposals/sockets/wit/udp-create-socket.wit +++ b/proposals/sockets/wit/udp-create-socket.wit @@ -1,4 +1,4 @@ - +@since(version = 0.2.0) interface udp-create-socket { use network.{network, error-code, ip-address-family}; use udp.{udp-socket}; @@ -23,5 +23,6 @@ interface udp-create-socket { /// - /// - /// - + @since(version = 0.2.0) create-udp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index d987a0a90..5d49a43f3 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,9 +1,10 @@ - +@since(version = 0.2.0) interface udp { use wasi:io/poll@0.2.0.{pollable}; use network.{network, error-code, ip-socket-address, ip-address-family}; /// A received datagram. + @since(version = 0.2.0) record incoming-datagram { /// The payload. /// @@ -19,6 +20,7 @@ interface udp { } /// A datagram to be sent out. + @since(version = 0.2.0) record outgoing-datagram { /// The payload. data: list, @@ -33,9 +35,8 @@ interface udp { remote-address: option, } - - /// A UDP socket handle. + @since(version = 0.2.0) resource udp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -63,7 +64,9 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) finish-bind: func() -> result<_, error-code>; /// Set up inbound & outbound communication channels, optionally to a specific peer. @@ -106,6 +109,7 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) %stream: func(remote-address: option) -> result, error-code>; /// Get the current bound address. @@ -124,6 +128,7 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) local-address: func() -> result; /// Get the address the socket is currently streaming to. @@ -136,11 +141,13 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.2.0) address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -149,7 +156,9 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.2.0) unicast-hop-limit: func() -> result; + @since(version = 0.2.0) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -162,18 +171,24 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) receive-buffer-size: func() -> result; + @since(version = 0.2.0) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) send-buffer-size: func() -> result; + @since(version = 0.2.0) set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Create a `pollable` which will resolve once the socket is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } + @since(version = 0.2.0) resource incoming-datagram-stream { /// Receive messages on the socket. /// @@ -198,15 +213,18 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) receive: func(max-results: u64) -> result, error-code>; /// Create a `pollable` which will resolve once the stream is ready to receive again. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } + @since(version = 0.2.0) resource outgoing-datagram-stream { /// Check readiness for sending. This function never blocks. /// @@ -255,12 +273,14 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) send: func(datagrams: list) -> result; /// Create a `pollable` which will resolve once the stream is ready to send again. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } } diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index f8bb92ae0..a1f7d14bc 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,11 +1,19 @@ package wasi:sockets@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import instance-network; + @since(version = 0.2.0) import network; + @since(version = 0.2.0) import udp; + @since(version = 0.2.0) import udp-create-socket; + @since(version = 0.2.0) import tcp; + @since(version = 0.2.0) import tcp-create-socket; + @since(version = 0.2.0) import ip-name-lookup; } From 7eaf3e6dec39125baad3845c45d487143981f78a Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 31 May 2024 23:41:58 +0200 Subject: [PATCH 1442/1772] Update `wit-abi-up-to-date` to `v20` (#67) * Update `wit-abi-up-to-date` to `v20` This adds support for `@since` and `@unstable` gates * Regenerate imports.md with wit-bindgen 0.26.0. --------- Co-authored-by: Dan Gohman --- proposals/clocks/.github/workflows/main.yml | 2 +- proposals/clocks/imports.md | 57 ++++++++++----------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 5ca5ba1fa..abb15ec86 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -18,4 +18,4 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v17 + - uses: WebAssembly/wit-abi-up-to-date@v20 diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index 126ff577a..ec3beddf9 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -2,41 +2,41 @@ -

                      Import interface wasi:io/poll@0.2.0

                      +

                      Import interface wasi:io/poll@0.2.0

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      Types

                      -

                      resource pollable

                      +

                      resource pollable

                      pollable represents a single I/O event which may be ready, or not.

                      Functions

                      -

                      [method]pollable.ready: func

                      +

                      [method]pollable.ready: func

                      Return the readiness of a pollable. This function never blocks.

                      Returns true when the pollable is ready, and false otherwise.

                      Params
                      Return values
                        -
                      • bool
                      • +
                      • bool
                      -

                      [method]pollable.block: func

                      +

                      [method]pollable.block: func

                      block returns immediately if the pollable is ready, and otherwise blocks until ready.

                      This function is equivalent to calling poll.poll on a list containing only this pollable.

                      Params
                      -

                      poll: func

                      +

                      poll: func

                      Poll for completion on a set of pollables.

                      This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

                      @@ -52,36 +52,35 @@ the pollables has an error, it is indicated by marking the source as being reaedy for I/O.

                      Params
                      Return values
                      • list<u32>
                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.0

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.0

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      A monotonic clock is a clock which has an unspecified initial value, and successive reads of the clock will produce non-decreasing values.

                      -

                      It is intended for measuring elapsed time.


                      Types

                      -

                      type pollable

                      +

                      type pollable

                      pollable

                      -#### `type instant` +#### `type instant` `u64`

                      An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. -

                      type duration

                      +

                      type duration

                      u64

                      A duration of time, in nanoseconds.


                      Functions

                      -

                      now: func

                      +

                      now: func

                      Read the current value of the clock.

                      The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

                      @@ -89,36 +88,36 @@ produce a sequence of non-decreasing values.

                      -

                      resolution: func

                      +

                      resolution: func

                      Query the resolution of the clock. Returns the duration of time corresponding to a clock tick.

                      Return values
                      -

                      subscribe-instant: func

                      +

                      subscribe-instant: func

                      Create a pollable which will resolve once the specified instant has occurred.

                      Params
                      Return values
                      -

                      subscribe-duration: func

                      +

                      subscribe-duration: func

                      Create a pollable that will resolve after the specified duration has elapsed from the time this function is invoked.

                      Params
                      Return values
                      -

                      Import interface wasi:clocks/wall-clock@0.2.0

                      +

                      Import interface wasi:clocks/wall-clock@0.2.0

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -131,16 +130,16 @@ monotonic, making it unsuitable for measuring elapsed time.

                      It is intended for reporting the current date and time for humans.


                      Types

                      -

                      record datetime

                      +

                      record datetime

                      A time and date in seconds plus nanoseconds.

                      Record Fields

                      Functions

                      -

                      now: func

                      +

                      now: func

                      Read the current value of the clock.

                      This clock is not monotonic, therefore calling this function repeatedly will not necessarily produce a sequence of non-decreasing values.

                      @@ -152,7 +151,7 @@ also known as Unix Time.
                    • datetime
                    -

                    resolution: func

                    +

                    resolution: func

                    Query the resolution of the clock.

                    The nanoseconds field of the output is always less than 1000000000.

                    Return values
                    From 8ea64d53e073c8905dce5667ddec0e7d262e6be2 Mon Sep 17 00:00:00 2001 From: Colin D Murphy Date: Fri, 14 Jun 2024 09:42:29 -0400 Subject: [PATCH 1443/1772] Add timezone back in. (#61) * Add timezone back in. Update README with markdown generation step. * Add `@unstable` feature gates for `timezone` * Update wit/world.wit --------- Co-authored-by: Yosh Co-authored-by: Dan Gohman --- proposals/clocks/.github/workflows/main.yml | 4 +- proposals/clocks/README.md | 11 ++++ proposals/clocks/imports.md | 66 +++++++++++++++++++++ proposals/clocks/wit/timezone.wit | 55 +++++++++++++++++ proposals/clocks/wit/world.wit | 2 + 5 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 proposals/clocks/wit/timezone.wit diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index abb15ec86..58d8a1f04 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -18,4 +18,6 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v20 + - uses: WebAssembly/wit-abi-up-to-date@v21 + with: + features: clocks-timezone diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 1690e32b9..49b40b980 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -35,6 +35,7 @@ WASI clocks must have at least two complete independent implementations. - [[Alternative 2]](#alternative-2) - [Stakeholder Interest & Feedback](#stakeholder-interest--feedback) - [References & acknowledgements](#references--acknowledgements) +- [Development](#development) ### Introduction @@ -132,3 +133,13 @@ Many thanks for valuable feedback and advice from: - [Person 1] - [Person 2] - [etc.] + +### Development + +#### Generating imports.md + +The file `imports.md` is generated using [wit-bindgen](https://github.com/bytecodealliance/wit-bindgen). + +```bash +wit-bindgen markdown wit --html-in-md --features clocks-timezone +``` diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index ec3beddf9..b1fefd7b5 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -5,6 +5,7 @@
                  • interface wasi:io/poll@0.2.0
                  • interface wasi:clocks/monotonic-clock@0.2.0
                  • interface wasi:clocks/wall-clock@0.2.0
                  • +
                  • interface wasi:clocks/timezone@0.2.0
                @@ -158,3 +159,68 @@ also known as Unix Time.
              • datetime
              +

              Import interface wasi:clocks/timezone@0.2.0

              +
              +

              Types

              +

              type datetime

              +

              datetime

              +

              +#### `record timezone-display` +

              Information useful for displaying the timezone of a specific datetime.

              +

              This information may vary within a single timezone to reflect daylight +saving time adjustments.

              +
              Record Fields
              +
                +
              • +

                utc-offset: s32

                +

                The number of seconds difference between UTC time and the local +time of the timezone. +

                The returned value will always be less than 86400 which is the +number of seconds in a day (246060).

                +

                In implementations that do not expose an actual time zone, this +should return 0.

                +
              • +
              • +

                name: string

                +

                The abbreviated name of the timezone to display to a user. The name +`UTC` indicates Coordinated Universal Time. Otherwise, this should +reference local standards for the name of the time zone. +

                In implementations that do not expose an actual time zone, this +should be the string UTC.

                +

                In time zones that do not have an applicable name, a formatted +representation of the UTC offset may be returned, such as -04:00.

                +
              • +
              • +

                in-daylight-saving-time: bool

                +

                Whether daylight saving time is active. +

                In implementations that do not expose an actual time zone, this +should return false.

                +
              • +
              +
              +

              Functions

              +

              display: func

              +

              Return information needed to display the given datetime. This includes +the UTC offset, the time zone name, and a flag indicating whether +daylight saving time is active.

              +

              If the timezone cannot be determined for the given datetime, return a +timezone-display for UTC with a utc-offset of 0 and no daylight +saving time.

              +
              Params
              + +
              Return values
              + +

              utc-offset: func

              +

              The same as display, but only return the UTC offset.

              +
              Params
              + +
              Return values
              +
                +
              • s32
              • +
              diff --git a/proposals/clocks/wit/timezone.wit b/proposals/clocks/wit/timezone.wit new file mode 100644 index 000000000..3c286889e --- /dev/null +++ b/proposals/clocks/wit/timezone.wit @@ -0,0 +1,55 @@ +package wasi:clocks@0.2.0; + +@unstable(feature = clocks-timezone) +interface timezone { + @unstable(feature = clocks-timezone) + use wall-clock.{datetime}; + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + @unstable(feature = clocks-timezone) + display: func(when: datetime) -> timezone-display; + + /// The same as `display`, but only return the UTC offset. + @unstable(feature = clocks-timezone) + utc-offset: func(when: datetime) -> s32; + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + @unstable(feature = clocks-timezone) + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index c0224572a..b76a00514 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -3,4 +3,6 @@ package wasi:clocks@0.2.0; world imports { import monotonic-clock; import wall-clock; + @unstable(feature = clocks-timezone) + import timezone; } From 3f4f8e867a8353db07c0bdb03209c027f26544e1 Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 21 Jun 2024 02:09:09 +0200 Subject: [PATCH 1444/1772] annotate `use` statements --- proposals/cli/wit/stdio.wit | 3 +++ proposals/cli/wit/terminal.wit | 3 +++ 2 files changed, 6 insertions(+) diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index 584b3e836..e9502a93d 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,5 +1,6 @@ @since(version = 0.2.0) interface stdin { + @since(version = 0.2.0) use wasi:io/streams@0.2.0.{input-stream}; @since(version = 0.2.0) @@ -8,6 +9,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { + @since(version = 0.2.0) use wasi:io/streams@0.2.0.{output-stream}; @since(version = 0.2.0) @@ -16,6 +18,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { + @since(version = 0.2.0) use wasi:io/streams@0.2.0.{output-stream}; @since(version = 0.2.0) diff --git a/proposals/cli/wit/terminal.wit b/proposals/cli/wit/terminal.wit index c1d9c7092..d305498c6 100644 --- a/proposals/cli/wit/terminal.wit +++ b/proposals/cli/wit/terminal.wit @@ -26,6 +26,7 @@ interface terminal-output { /// link-time authority. @since(version = 0.2.0) interface terminal-stdin { + @since(version = 0.2.0) use terminal-input.{terminal-input}; /// If stdin is connected to a terminal, return a `terminal-input` handle @@ -38,6 +39,7 @@ interface terminal-stdin { /// link-time authority. @since(version = 0.2.0) interface terminal-stdout { + @since(version = 0.2.0) use terminal-output.{terminal-output}; /// If stdout is connected to a terminal, return a `terminal-output` handle @@ -50,6 +52,7 @@ interface terminal-stdout { /// link-time authority. @since(version = 0.2.0) interface terminal-stderr { + @since(version = 0.2.0) use terminal-output.{terminal-output}; /// If stderr is connected to a terminal, return a `terminal-output` handle From 6b5c2e8dc71e8fcc8436369d85fb9dfcc58bd56e Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 21 Jun 2024 02:16:59 +0200 Subject: [PATCH 1445/1772] annotate `use` statements --- proposals/sockets/wit/instance-network.wit | 1 + proposals/sockets/wit/ip-name-lookup.wit | 2 ++ proposals/sockets/wit/tcp-create-socket.wit | 2 ++ proposals/sockets/wit/tcp.wit | 4 ++++ proposals/sockets/wit/udp-create-socket.wit | 2 ++ proposals/sockets/wit/udp.wit | 2 ++ 6 files changed, 13 insertions(+) diff --git a/proposals/sockets/wit/instance-network.wit b/proposals/sockets/wit/instance-network.wit index 55dc11aba..5f6e6c1cc 100644 --- a/proposals/sockets/wit/instance-network.wit +++ b/proposals/sockets/wit/instance-network.wit @@ -2,6 +2,7 @@ /// This interface provides a value-export of the default network handle.. @since(version = 0.2.0) interface instance-network { + @since(version = 0.2.0) use network.{network}; /// Get a handle to the default network. diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index 83c6c74e1..0368b4801 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,6 +1,8 @@ @since(version = 0.2.0) interface ip-name-lookup { + @since(version = 0.2.0) use wasi:io/poll@0.2.0.{pollable}; + @since(version = 0.2.0) use network.{network, error-code, ip-address}; /// Resolve an internet host name to a list of IP addresses. diff --git a/proposals/sockets/wit/tcp-create-socket.wit b/proposals/sockets/wit/tcp-create-socket.wit index a283f8b4b..eedbd3076 100644 --- a/proposals/sockets/wit/tcp-create-socket.wit +++ b/proposals/sockets/wit/tcp-create-socket.wit @@ -1,6 +1,8 @@ @since(version = 0.2.0) interface tcp-create-socket { + @since(version = 0.2.0) use network.{network, error-code, ip-address-family}; + @since(version = 0.2.0) use tcp.{tcp-socket}; /// Create a new TCP socket. diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index e52a8c81a..e4a62101b 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,8 +1,12 @@ @since(version = 0.2.0) interface tcp { + @since(version = 0.2.0) use wasi:io/streams@0.2.0.{input-stream, output-stream}; + @since(version = 0.2.0) use wasi:io/poll@0.2.0.{pollable}; + @since(version = 0.2.0) use wasi:clocks/monotonic-clock@0.2.0.{duration}; + @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; @since(version = 0.2.0) diff --git a/proposals/sockets/wit/udp-create-socket.wit b/proposals/sockets/wit/udp-create-socket.wit index 90f3d83a7..e8eeacbfe 100644 --- a/proposals/sockets/wit/udp-create-socket.wit +++ b/proposals/sockets/wit/udp-create-socket.wit @@ -1,6 +1,8 @@ @since(version = 0.2.0) interface udp-create-socket { + @since(version = 0.2.0) use network.{network, error-code, ip-address-family}; + @since(version = 0.2.0) use udp.{udp-socket}; /// Create a new UDP socket. diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 5d49a43f3..48e753cac 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,6 +1,8 @@ @since(version = 0.2.0) interface udp { + @since(version = 0.2.0) use wasi:io/poll@0.2.0.{pollable}; + @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; /// A received datagram. From e886d5a04a4b768d32b864a0646f782f524fbfae Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sat, 22 Jun 2024 11:35:37 +0200 Subject: [PATCH 1446/1772] Update wit-abi-up-to-date to recognize the new @since annotations --- proposals/sockets/.github/workflows/main.yml | 2 +- proposals/sockets/imports.md | 750 +++++++++---------- 2 files changed, 376 insertions(+), 376 deletions(-) diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index 185f6a10f..e5a958551 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -18,4 +18,4 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v17 + - uses: WebAssembly/wit-abi-up-to-date@v21 diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 6716d298b..44eb2c08a 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -2,28 +2,28 @@ -

              Import interface wasi:sockets/network@0.2.0

              +

              Import interface wasi:sockets/network@0.2.0


              Types

              -

              resource network

              +

              resource network

              An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

              -

              enum error-code

              +

              enum error-code

              Error codes.

              In theory, every API can return any error code. In practice, API's typically only return the errors documented per API @@ -39,220 +39,220 @@ combined with a couple of errors that are always possible:

              Enum Cases
              • -

                unknown

                +

                unknown

                Unknown error

              • -

                access-denied

                +

                access-denied

                Access denied.

                POSIX equivalent: EACCES, EPERM

              • -

                not-supported

                +

                not-supported

                The operation is not supported.

                POSIX equivalent: EOPNOTSUPP

              • -

                invalid-argument

                +

                invalid-argument

                One of the arguments is invalid.

                POSIX equivalent: EINVAL

              • -

                out-of-memory

                +

                out-of-memory

                Not enough memory to complete the operation.

                POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY

              • -

                timeout

                +

                timeout

                The operation timed out before it could finish completely.

              • -

                concurrency-conflict

                +

                concurrency-conflict

                This operation is incompatible with another asynchronous operation that is already in progress.

                POSIX equivalent: EALREADY

              • -

                not-in-progress

                +

                not-in-progress

                Trying to finish an asynchronous operation that: - has not been started yet, or: - was already finished by a previous `finish-*` call.

                Note: this is scheduled to be removed when futures are natively supported.

              • -

                would-block

                +

                would-block

                The operation has been aborted because it could not be completed immediately.

                Note: this is scheduled to be removed when futures are natively supported.

              • -

                invalid-state

                +

                invalid-state

                The operation is not valid in the socket's current state.

              • -

                new-socket-limit

                +

                new-socket-limit

                A new socket resource could not be created because of a system limit.

              • -

                address-not-bindable

                +

                address-not-bindable

                A bind operation failed because the provided address is not an address that the `network` can bind to.

              • -

                address-in-use

                +

                address-in-use

                A bind operation failed because the provided address is already in use or because there are no ephemeral ports available.

              • -

                remote-unreachable

                +

                remote-unreachable

                The remote address is not reachable

              • -

                connection-refused

                +

                connection-refused

                The TCP connection was forcefully rejected

              • -

                connection-reset

                +

                connection-reset

                The TCP connection was reset.

              • -

                connection-aborted

                +

                connection-aborted

                A TCP connection was aborted.

              • -

                datagram-too-large

                +

                datagram-too-large

                The size of a datagram sent to a UDP socket exceeded the maximum supported size.

              • -

                name-unresolvable

                +

                name-unresolvable

                Name does not exist or has no suitable associated IP addresses.

              • -

                temporary-resolver-failure

                +

                temporary-resolver-failure

                A temporary failure in name resolution occurred.

              • -

                permanent-resolver-failure

                +

                permanent-resolver-failure

                A permanent failure in name resolution occurred.

              -

              enum ip-address-family

              +

              enum ip-address-family

              Enum Cases
              • -

                ipv4

                +

                ipv4

                Similar to `AF_INET` in POSIX.

              • -

                ipv6

                +

                ipv6

                Similar to `AF_INET6` in POSIX.

              -

              tuple ipv4-address

              +

              tuple ipv4-address

              Tuple Fields
                -
              • 0: u8
              • -
              • 1: u8
              • -
              • 2: u8
              • -
              • 3: u8
              • +
              • 0: u8
              • +
              • 1: u8
              • +
              • 2: u8
              • +
              • 3: u8
              -

              tuple ipv6-address

              +

              tuple ipv6-address

              Tuple Fields
                -
              • 0: u16
              • -
              • 1: u16
              • -
              • 2: u16
              • -
              • 3: u16
              • -
              • 4: u16
              • -
              • 5: u16
              • -
              • 6: u16
              • -
              • 7: u16
              • +
              • 0: u16
              • +
              • 1: u16
              • +
              • 2: u16
              • +
              • 3: u16
              • +
              • 4: u16
              • +
              • 5: u16
              • +
              • 6: u16
              • +
              • 7: u16
              -

              variant ip-address

              +

              variant ip-address

              Variant Cases
              -

              record ipv4-socket-address

              +

              record ipv4-socket-address

              Record Fields
              -

              record ipv6-socket-address

              +

              record ipv6-socket-address

              Record Fields
              -

              variant ip-socket-address

              +

              variant ip-socket-address

              Variant Cases
              -

              Import interface wasi:sockets/instance-network@0.2.0

              +

              Import interface wasi:sockets/instance-network@0.2.0

              This interface provides a value-export of the default network handle..


              Types

              -

              type network

              +

              type network

              network

              ----

              Functions

              -

              instance-network: func

              +

              instance-network: func

              Get a handle to the default network.

              Return values
              -

              Import interface wasi:io/poll@0.2.0

              +

              Import interface wasi:io/poll@0.2.0

              A poll API intended to let users wait for I/O events on multiple handles at once.


              Types

              -

              resource pollable

              +

              resource pollable

              pollable represents a single I/O event which may be ready, or not.

              Functions

              -

              [method]pollable.ready: func

              +

              [method]pollable.ready: func

              Return the readiness of a pollable. This function never blocks.

              Returns true when the pollable is ready, and false otherwise.

              Params
              Return values
                -
              • bool
              • +
              • bool
              -

              [method]pollable.block: func

              +

              [method]pollable.block: func

              block returns immediately if the pollable is ready, and otherwise blocks until ready.

              This function is equivalent to calling poll.poll on a list containing only this pollable.

              Params
              -

              poll: func

              +

              poll: func

              Poll for completion on a set of pollables.

              This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

              @@ -268,56 +268,56 @@ the pollables has an error, it is indicated by marking the source as being reaedy for I/O.

              Params
              Return values
              • list<u32>
              -

              Import interface wasi:sockets/udp@0.2.0

              +

              Import interface wasi:sockets/udp@0.2.0


              Types

              -

              type pollable

              +

              type pollable

              pollable

              -#### `type network` +#### `type network` [`network`](#network)

              -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

              -#### `type ip-socket-address` +#### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address)

              -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

              -#### `record incoming-datagram` +#### `record incoming-datagram`

              A received datagram.

              Record Fields
              • -

                data: list<u8>

                +

                data: list<u8>

                The payload.

                Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes.

              • -

                remote-address: ip-socket-address

                +

                remote-address: ip-socket-address

                The source address.

                This field is guaranteed to match the remote address the stream was initialized with, if any.

                Equivalent to the src_addr out parameter of recvfrom.

              -

              record outgoing-datagram

              +

              record outgoing-datagram

              A datagram to be sent out.

              Record Fields
              • -

                data: list<u8>

                +

                data: list<u8>

                The payload.

              • -

                remote-address: option<ip-socket-address>

                +

                remote-address: option<ip-socket-address>

                The destination address.

                The requirements on this field depend on how the stream was initialized:

                  @@ -327,13 +327,13 @@ being reaedy for I/O.

                  If this value is None, the send operation is equivalent to send in POSIX. Otherwise it is equivalent to sendto.

                -

                resource udp-socket

                +

                resource udp-socket

                A UDP socket handle.

                -

                resource incoming-datagram-stream

                -

                resource outgoing-datagram-stream

                +

                resource incoming-datagram-stream

                +

                resource outgoing-datagram-stream


                Functions

                -

                [method]udp-socket.start-bind: func

                +

                [method]udp-socket.start-bind: func

                Bind the socket to a specific network on the provided IP address and port.

                If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -362,24 +362,24 @@ don't want to make use of this ability can simply call the native

              Params
              Return values
              -

              [method]udp-socket.finish-bind: func

              +

              [method]udp-socket.finish-bind: func

              Params
              Return values
              -

              [method]udp-socket.stream: func

              +

              [method]udp-socket.stream: func

              Set up inbound & outbound communication channels, optionally to a specific peer.

              This function only changes the local socket configuration and does not generate any network traffic. On success, the remote-address of the socket is updated. The local-address may be updated as well, @@ -420,14 +420,14 @@ if (remote_address is Some) {

            Params
            Return values
            -

            [method]udp-socket.local-address: func

            +

            [method]udp-socket.local-address: func

            Get the current bound address.

            POSIX mentions:

            @@ -448,13 +448,13 @@ stored in the object pointed to by address is unspecified.

          Params
          Return values
          -

          [method]udp-socket.remote-address: func

          +

          [method]udp-socket.remote-address: func

          Get the address the socket is currently streaming to.

          Typical errors

            @@ -469,24 +469,24 @@ stored in the object pointed to by address is unspecified.

          Params
          Return values
          -

          [method]udp-socket.address-family: func

          +

          [method]udp-socket.address-family: func

          Whether this is a IPv4 or IPv6 socket.

          Equivalent to the SO_DOMAIN socket option.

          Params
          Return values
          -

          [method]udp-socket.unicast-hop-limit: func

          +

          [method]udp-socket.unicast-hop-limit: func

          Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

          If the provided value is 0, an invalid-argument error is returned.

          Typical errors

          @@ -495,23 +495,23 @@ stored in the object pointed to by address is unspecified.

        Params
        Return values
        -

        [method]udp-socket.set-unicast-hop-limit: func

        +

        [method]udp-socket.set-unicast-hop-limit: func

        Params
        Return values
        -

        [method]udp-socket.receive-buffer-size: func

        +

        [method]udp-socket.receive-buffer-size: func

        The kernel buffer space reserved for sends/receives on this socket.

        If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -523,54 +523,54 @@ I.e. after setting a value, reading the same setting back may return a different

      Params
      Return values
      -

      [method]udp-socket.set-receive-buffer-size: func

      +

      [method]udp-socket.set-receive-buffer-size: func

      Params
      Return values
      -

      [method]udp-socket.send-buffer-size: func

      +

      [method]udp-socket.send-buffer-size: func

      Params
      Return values
      -

      [method]udp-socket.set-send-buffer-size: func

      +

      [method]udp-socket.set-send-buffer-size: func

      Params
      Return values
      -

      [method]udp-socket.subscribe: func

      +

      [method]udp-socket.subscribe: func

      Create a pollable which will resolve once the socket is ready for I/O.

      Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

      Params
      Return values
      -

      [method]incoming-datagram-stream.receive: func

      +

      [method]incoming-datagram-stream.receive: func

      Receive messages on the socket.

      This function attempts to receive up to max-results datagrams on the socket without blocking. The returned list may contain fewer elements than requested, but never more.

      @@ -598,26 +598,26 @@ This function never returns error(would-block).
      Params
      Return values
      -

      [method]incoming-datagram-stream.subscribe: func

      +

      [method]incoming-datagram-stream.subscribe: func

      Create a pollable which will resolve once the stream is ready to receive again.

      Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

      Params
      Return values
      -

      [method]outgoing-datagram-stream.check-send: func

      +

      [method]outgoing-datagram-stream.check-send: func

      Check readiness for sending. This function never blocks.

      Returns the number of datagrams permitted for the next call to send, or an error. Calling send with more datagrams than this function has @@ -628,13 +628,13 @@ error.

      Never returns would-block.

      Params
      Return values
      -

      [method]outgoing-datagram-stream.send: func

      +

      [method]outgoing-datagram-stream.send: func

      Send messages on the socket.

      This function attempts to send all provided datagrams on the socket without blocking and returns how many messages were actually sent (or queued for sending). This function never @@ -669,43 +669,43 @@ either check-send was not called or datagrams contains

      Params
      Return values
      -

      [method]outgoing-datagram-stream.subscribe: func

      +

      [method]outgoing-datagram-stream.subscribe: func

      Create a pollable which will resolve once the stream is ready to send again.

      Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

      Params
      Return values
      -

      Import interface wasi:sockets/udp-create-socket@0.2.0

      +

      Import interface wasi:sockets/udp-create-socket@0.2.0


      Types

      -

      type network

      +

      type network

      network

      -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

      -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

      -#### `type udp-socket` +#### `type udp-socket` [`udp-socket`](#udp_socket)

      ----

      Functions

      -

      create-udp-socket: func

      +

      create-udp-socket: func

      Create a new UDP socket.

      Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX. On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

      @@ -727,16 +727,16 @@ the socket is effectively an in-memory configuration object, unable to communica
      Params
      Return values
      -

      Import interface wasi:io/error@0.2.0

      +

      Import interface wasi:io/error@0.2.0


      Types

      -

      resource error

      +

      resource error

      A resource which represents some error information.

      The only method provided by this resource is to-debug-string, which provides some human-readable information about the error.

      @@ -753,7 +753,7 @@ error-code type, using the function

      The set of functions which can "downcast" an error into a more concrete type is open.

      Functions

      -

      [method]error.to-debug-string: func

      +

      [method]error.to-debug-string: func

      Returns a string that is suitable to assist humans in debugging this error.

      WARNING: The returned string should not be consumed mechanically! @@ -762,42 +762,42 @@ details. Parsing this string is a major platform-compatibility hazard.

      Params
      Return values
        -
      • string
      • +
      • string
      -

      Import interface wasi:io/streams@0.2.0

      +

      Import interface wasi:io/streams@0.2.0

      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

      In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


      Types

      -

      type error

      +

      type error

      error

      -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

      -#### `variant stream-error` +#### `variant stream-error`

      An error for input-stream and output-stream operations.

      Variant Cases
      • -

        last-operation-failed: own<error>

        +

        last-operation-failed: own<error>

        The last operation (a write or flush) failed before completion.

        More information is available in the error payload.

      • -

        closed

        +

        closed

        The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

      -

      resource input-stream

      +

      resource input-stream

      An input bytestream.

      input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are @@ -805,7 +805,7 @@ promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

      -

      resource output-stream

      +

      resource output-stream

      An output bytestream.

      output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also @@ -814,7 +814,7 @@ promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

      Functions

      -

      [method]input-stream.read: func

      +

      [method]input-stream.read: func

      Perform a non-blocking read from the stream.

      When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -838,51 +838,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

      Params
      Return values
      -

      [method]input-stream.blocking-read: func

      +

      [method]input-stream.blocking-read: func

      Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

      Params
      Return values
      -

      [method]input-stream.skip: func

      +

      [method]input-stream.skip: func

      Skip bytes from a stream. Returns number of bytes skipped.

      Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

      Params
      Return values
      -

      [method]input-stream.blocking-skip: func

      +

      [method]input-stream.blocking-skip: func

      Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

      Params
      Return values
      -

      [method]input-stream.subscribe: func

      +

      [method]input-stream.subscribe: func

      Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -891,13 +891,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

      Params
      Return values
      -

      [method]output-stream.check-write: func

      +

      [method]output-stream.check-write: func

      Check readiness for writing. This function never blocks.

      Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -907,13 +907,13 @@ become ready when this function will report at least 1 byte, or an error.

      Params
      Return values
      -

      [method]output-stream.write: func

      +

      [method]output-stream.write: func

      Perform a write. This function never blocks.

      When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -926,14 +926,14 @@ length of less than or equal to n. Otherwise, this function will trap.

      the last call to check-write provided a permit.

      Params
      Return values
      -

      [method]output-stream.blocking-write-and-flush: func

      +

      [method]output-stream.blocking-write-and-flush: func

      Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

      This is a convenience wrapper around the use of check-write, @@ -957,14 +957,14 @@ let _ = this.check-write(); // eliding error handling

      Params
      Return values
      -

      [method]output-stream.flush: func

      +

      [method]output-stream.flush: func

      Request to flush buffered output. This function never blocks.

      This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -975,24 +975,24 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

      Params
      Return values
      -

      [method]output-stream.blocking-flush: func

      +

      [method]output-stream.blocking-flush: func

      Request to flush buffered output, and block until flush completes and stream is ready for writing again.

      Params
      Return values
      -

      [method]output-stream.subscribe: func

      +

      [method]output-stream.subscribe: func

      Create a pollable which will resolve once the output-stream is ready for more writing, or an error has occured. When this pollable is ready, check-write will return ok(n) with n>0, or an @@ -1003,13 +1003,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

      Params
      Return values
      -

      [method]output-stream.write-zeroes: func

      +

      [method]output-stream.write-zeroes: func

      Write zeroes to a stream.

      This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -1017,14 +1017,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

      Params
      Return values
      -

      [method]output-stream.blocking-write-zeroes-and-flush: func

      +

      [method]output-stream.blocking-write-zeroes-and-flush: func

      Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

      @@ -1048,14 +1048,14 @@ let _ = this.check-write(); // eliding error handling
      Params
      Return values
      -

      [method]output-stream.splice: func

      +

      [method]output-stream.splice: func

      Read from one stream and write to another.

      The behavior of splice is equivelant to:

        @@ -1070,30 +1070,30 @@ let _ = this.check-write(); // eliding error handling than len.

        Params
        Return values
        -

        [method]output-stream.blocking-splice: func

        +

        [method]output-stream.blocking-splice: func

        Read from one stream and write to another, with blocking.

        This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

        Params
        Return values
        -

        Import interface wasi:clocks/monotonic-clock@0.2.0

        +

        Import interface wasi:clocks/monotonic-clock@0.2.0

        WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

        It is intended to be portable at least between Unix-family platforms and @@ -1103,20 +1103,20 @@ successive reads of the clock will produce non-decreasing values.

        It is intended for measuring elapsed time.


        Types

        -

        type pollable

        +

        type pollable

        pollable

        -#### `type instant` +#### `type instant` `u64`

        An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. -

        type duration

        +

        type duration

        u64

        A duration of time, in nanoseconds.


        Functions

        -

        now: func

        +

        now: func

        Read the current value of the clock.

        The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

        @@ -1124,80 +1124,80 @@ produce a sequence of non-decreasing values.

        -

        resolution: func

        +

        resolution: func

        Query the resolution of the clock. Returns the duration of time corresponding to a clock tick.

        Return values
        -

        subscribe-instant: func

        +

        subscribe-instant: func

        Create a pollable which will resolve once the specified instant occured.

        Params
        Return values
        -

        subscribe-duration: func

        +

        subscribe-duration: func

        Create a pollable which will resolve once the given duration has elapsed, starting at the time at which this function was called. occured.

        Params
        Return values
        -

        Import interface wasi:sockets/tcp@0.2.0

        +

        Import interface wasi:sockets/tcp@0.2.0


        Types

        -

        type input-stream

        +

        type input-stream

        input-stream

        -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

        -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

        -#### `type duration` +#### `type duration` [`duration`](#duration)

        -#### `type network` +#### `type network` [`network`](#network)

        -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

        -#### `type ip-socket-address` +#### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address)

        -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

        -#### `enum shutdown-type` +#### `enum shutdown-type`

        Enum Cases
        • -

          receive

          +

          receive

          Similar to `SHUT_RD` in POSIX.

        • -

          send

          +

          send

          Similar to `SHUT_WR` in POSIX.

        • -

          both

          +

          both

          Similar to `SHUT_RDWR` in POSIX.

        -

        resource tcp-socket

        +

        resource tcp-socket

        A TCP socket resource.

        The socket can be in one of the following states:

          @@ -1219,7 +1219,7 @@ the term "bound" without backticks it actually means: in the bou network::error-code type, TCP socket methods may always return error(invalid-state) when in the closed state.

    Functions

    -

    [method]tcp-socket.start-bind: func

    +

    [method]tcp-socket.start-bind: func

    Bind the socket to a specific network on the provided IP address and port.

    If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -1258,24 +1258,24 @@ don't want to make use of this ability can simply call the native

    Params
    Return values
    -

    [method]tcp-socket.finish-bind: func

    +

    [method]tcp-socket.finish-bind: func

    Params
    Return values
    -

    [method]tcp-socket.start-connect: func

    +

    [method]tcp-socket.start-connect: func

    Connect to a remote endpoint.

    On success:

    Params
    Return values
    -

    [method]tcp-socket.finish-listen: func

    +

    [method]tcp-socket.finish-listen: func

    Params
    Return values
    -

    [method]tcp-socket.accept: func

    +

    [method]tcp-socket.accept: func

    Accept a new client socket.

    The returned socket is bound and in the connected state. The following properties are inherited from the listener socket:

      @@ -1410,13 +1410,13 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    [method]tcp-socket.local-address: func

    +

    [method]tcp-socket.local-address: func

    Get the bound local address.

    POSIX mentions:

    @@ -1437,13 +1437,13 @@ stored in the object pointed to by address is unspecified.

    Params
    Return values
    -

    [method]tcp-socket.remote-address: func

    +

    [method]tcp-socket.remote-address: func

    Get the remote address.

    Typical errors

      @@ -1458,35 +1458,35 @@ stored in the object pointed to by address is unspecified.

    Params
    Return values
    -

    [method]tcp-socket.is-listening: func

    +

    [method]tcp-socket.is-listening: func

    Whether the socket is in the listening state.

    Equivalent to the SO_ACCEPTCONN socket option.

    Params
    Return values
      -
    • bool
    • +
    • bool
    -

    [method]tcp-socket.address-family: func

    +

    [method]tcp-socket.address-family: func

    Whether this is a IPv4 or IPv6 socket.

    Equivalent to the SO_DOMAIN socket option.

    Params
    Return values
    -

    [method]tcp-socket.set-listen-backlog-size: func

    +

    [method]tcp-socket.set-listen-backlog-size: func

    Hints the desired listen queue size. Implementations are free to ignore this.

    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded.

    @@ -1498,14 +1498,14 @@ Any other value will never cause an error, but it might be silently clamped and/
    Params
    Return values
    -

    [method]tcp-socket.keep-alive-enabled: func

    +

    [method]tcp-socket.keep-alive-enabled: func

    Enables or disables keepalive.

    The keepalive behavior can be adjusted using:

      @@ -1517,23 +1517,23 @@ These properties can be configured while keep-alive-enabled is fals

      Equivalent to the SO_KEEPALIVE socket option.

      Params
      Return values
      -

      [method]tcp-socket.set-keep-alive-enabled: func

      +

      [method]tcp-socket.set-keep-alive-enabled: func

      Params
      Return values
      -

      [method]tcp-socket.keep-alive-idle-time: func

      +

      [method]tcp-socket.keep-alive-idle-time: func

      Amount of time the connection has to be idle before TCP starts sending keepalive packets.

      If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -1545,23 +1545,23 @@ I.e. after setting a value, reading the same setting back may return a different

    Params
    Return values
    -

    [method]tcp-socket.set-keep-alive-idle-time: func

    +

    [method]tcp-socket.set-keep-alive-idle-time: func

    Params
    Return values
    -

    [method]tcp-socket.keep-alive-interval: func

    +

    [method]tcp-socket.keep-alive-interval: func

    The time between keepalive packets.

    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -1573,23 +1573,23 @@ I.e. after setting a value, reading the same setting back may return a different

    Params
    Return values
    -

    [method]tcp-socket.set-keep-alive-interval: func

    +

    [method]tcp-socket.set-keep-alive-interval: func

    Params
    Return values
    -

    [method]tcp-socket.keep-alive-count: func

    +

    [method]tcp-socket.keep-alive-count: func

    The maximum amount of keepalive packets TCP should send before aborting the connection.

    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -1601,23 +1601,23 @@ I.e. after setting a value, reading the same setting back may return a different

    Params
    Return values
    -

    [method]tcp-socket.set-keep-alive-count: func

    +

    [method]tcp-socket.set-keep-alive-count: func

    Params
    Return values
    -

    [method]tcp-socket.hop-limit: func

    +

    [method]tcp-socket.hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    If the provided value is 0, an invalid-argument error is returned.

    Typical errors

    @@ -1626,23 +1626,23 @@ I.e. after setting a value, reading the same setting back may return a different
    Params
    Return values
    -

    [method]tcp-socket.set-hop-limit: func

    +

    [method]tcp-socket.set-hop-limit: func

    Params
    Return values
    -

    [method]tcp-socket.receive-buffer-size: func

    +

    [method]tcp-socket.receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -1654,42 +1654,42 @@ I.e. after setting a value, reading the same setting back may return a different

    Params
    Return values
    -

    [method]tcp-socket.set-receive-buffer-size: func

    +

    [method]tcp-socket.set-receive-buffer-size: func

    Params
    Return values
    -

    [method]tcp-socket.send-buffer-size: func

    +

    [method]tcp-socket.send-buffer-size: func

    Params
    Return values
    -

    [method]tcp-socket.set-send-buffer-size: func

    +

    [method]tcp-socket.set-send-buffer-size: func

    Params
    Return values
    -

    [method]tcp-socket.subscribe: func

    +

    [method]tcp-socket.subscribe: func

    Create a pollable which can be used to poll for, or block on, completion of any of the asynchronous operations of this socket.

    When finish-bind, finish-listen, finish-connect or accept @@ -1705,13 +1705,13 @@ for more information.

    It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    [method]tcp-socket.shutdown: func

    +

    [method]tcp-socket.shutdown: func

    Initiate a graceful shutdown.

    • receive: The socket is not expecting to receive any data from @@ -1738,31 +1738,31 @@ has no effect and returns ok.

    Params
    Return values
    -

    Import interface wasi:sockets/tcp-create-socket@0.2.0

    +

    Import interface wasi:sockets/tcp-create-socket@0.2.0


    Types

    -

    type network

    +

    type network

    network

    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

    -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `type tcp-socket` +#### `type tcp-socket` [`tcp-socket`](#tcp_socket)

    ----

    Functions

    -

    create-tcp-socket: func

    +

    create-tcp-socket: func

    Create a new TCP socket.

    Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX. On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

    @@ -1784,31 +1784,31 @@ is called, the socket is effectively an in-memory configuration object, unable t
    Params
    Return values
    -

    Import interface wasi:sockets/ip-name-lookup@0.2.0

    +

    Import interface wasi:sockets/ip-name-lookup@0.2.0


    Types

    -

    type pollable

    +

    type pollable

    pollable

    -#### `type network` +#### `type network` [`network`](#network)

    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

    -#### `type ip-address` +#### `type ip-address` [`ip-address`](#ip_address)

    -#### `resource resolve-address-stream` +#### `resource resolve-address-stream`


    Functions

    -

    resolve-addresses: func

    +

    resolve-addresses: func

    Resolve an internet host name to a list of IP addresses.

    Unicode domain names are automatically converted to ASCII using IDNA encoding. If the input is an IP address string, the address is parsed and returned @@ -1830,14 +1830,14 @@ to (asynchronously) fetch the results.

    Params
    Return values
    -

    [method]resolve-address-stream.resolve-next-address: func

    +

    [method]resolve-address-stream.resolve-next-address: func

    Returns the next address from the resolver.

    This function should be called multiple times. On each call, it will return the next address in connection order preference. If all @@ -1852,21 +1852,21 @@ addresses have been exhausted, this function returns none.

    Params
    Return values
    -

    [method]resolve-address-stream.subscribe: func

    +

    [method]resolve-address-stream.subscribe: func

    Create a pollable which will resolve once the stream is ready for I/O.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    From a7f3e7b1d36f8b71bcb73949d7de2844e5c0e646 Mon Sep 17 00:00:00 2001 From: Yosh Date: Mon, 24 Jun 2024 02:56:25 +0200 Subject: [PATCH 1447/1772] update `wit-abi-up-to-date` to parse `@since` gates --- proposals/cli/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml index 767e09199..a37194ca6 100644 --- a/proposals/cli/.github/workflows/main.yml +++ b/proposals/cli/.github/workflows/main.yml @@ -18,7 +18,7 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v17 + - uses: WebAssembly/wit-abi-up-to-date@v21 with: wit-bindgen: '0.16.0' worlds: "command imports" From 2536140a85890ac7b7bff4cdee6ef2ba3ba2dacf Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Fri, 28 Jun 2024 01:03:40 +0200 Subject: [PATCH 1448/1772] Require there to be at least one item. (#69) Fixes https://github.com/WebAssembly/wasi-io/issues/67 --- proposals/io/imports.md | 7 +++++-- proposals/io/wit/poll.wit | 5 +++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index be5b89945..6828e9300 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -77,8 +77,11 @@ containing only this pollable.

    interest, and waits until one or more of the events is ready for I/O.

    The result list<u32> contains one or more indices of handles in the argument list that is ready for I/O.

    -

    If the list contains more elements than can be indexed with a u32 -value, this function traps.

    +

    This function traps if either:

    +
      +
    • the list is empty, or:
    • +
    • the list contains more elements than can be indexed with a u32 value.
    • +

    A timeout can be implemented by adding a pollable from the wasi-clocks API to the list.

    This function does not return a result; polling in itself does not diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index b1e120eb7..e69e82217 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -27,8 +27,9 @@ interface poll { /// The result `list` contains one or more indices of handles in the /// argument list that is ready for I/O. /// - /// If the list contains more elements than can be indexed with a `u32` - /// value, this function traps. + /// This function traps if either: + /// - the list is empty, or: + /// - the list contains more elements than can be indexed with a `u32` value. /// /// A timeout can be implemented by adding a pollable from the /// wasi-clocks API to the list. From 790b76ddf7eed8206cd78e2f1b14ca96ba1d97ab Mon Sep 17 00:00:00 2001 From: Yosh Date: Tue, 28 May 2024 14:20:09 +0200 Subject: [PATCH 1449/1772] Document per-item versions using `@since` gates --- proposals/clocks/wit/monotonic-clock.wit | 9 ++++++++- proposals/clocks/wit/wall-clock.wit | 4 ++++ proposals/clocks/wit/world.wit | 3 +++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index a242b41c3..f7888bcca 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -7,35 +7,42 @@ package wasi:clocks@0.2.0; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. +@since(version = 0.2.0) interface monotonic-clock { use wasi:io/poll@0.2.0.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. + @since(version = 0.2.0) type instant = u64; /// A duration of time, in nanoseconds. + @since(version = 0.2.0) type duration = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + @since(version = 0.2.0) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. + @since(version = 0.2.0) resolution: func() -> duration; /// Create a `pollable` which will resolve once the specified instant - /// has occurred. + /// has occured. + @since(version = 0.2.0) subscribe-instant: func( when: instant, ) -> pollable; /// Create a `pollable` that will resolve after the specified duration has /// elapsed from the time this function is invoked. + @since(version = 0.2.0) subscribe-duration: func( when: duration, ) -> pollable; diff --git a/proposals/clocks/wit/wall-clock.wit b/proposals/clocks/wit/wall-clock.wit index 440ca0f33..4b08d71ee 100644 --- a/proposals/clocks/wit/wall-clock.wit +++ b/proposals/clocks/wit/wall-clock.wit @@ -13,8 +13,10 @@ package wasi:clocks@0.2.0; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. +@since(version = 0.2.0) interface wall-clock { /// A time and date in seconds plus nanoseconds. + @since(version = 0.2.0) record datetime { seconds: u64, nanoseconds: u32, @@ -33,10 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + @since(version = 0.2.0) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. + @since(version = 0.2.0) resolution: func() -> datetime; } diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index b76a00514..76a9206c5 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -1,7 +1,10 @@ package wasi:clocks@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import monotonic-clock; + @since(version = 0.2.0) import wall-clock; @unstable(feature = clocks-timezone) import timezone; From ea19e3e61c5ea3b431c3b2ad27da5dea1f9f13c8 Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 21 Jun 2024 02:10:26 +0200 Subject: [PATCH 1450/1772] annotate `use` statements --- proposals/clocks/wit/monotonic-clock.wit | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index f7888bcca..cae2363bf 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -9,6 +9,7 @@ package wasi:clocks@0.2.0; /// successive reads of the clock will produce non-decreasing values. @since(version = 0.2.0) interface monotonic-clock { + @since(version = 0.2.0) use wasi:io/poll@0.2.0.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an From d44a35fe56491f8635ac63062b19a1c731f336fb Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 28 Jun 2024 18:07:55 +0200 Subject: [PATCH 1451/1772] Update imports.md --- proposals/clocks/imports.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index b1fefd7b5..8b977ac32 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -98,7 +98,7 @@ corresponding to a clock tick.

    subscribe-instant: func

    Create a pollable which will resolve once the specified instant -has occurred.

    +has occured.

    Params
    • when: instant
    • From 9407fca14ce6609d451bee97069ad6bc512bf465 Mon Sep 17 00:00:00 2001 From: Yosh Date: Tue, 28 May 2024 14:30:23 +0200 Subject: [PATCH 1452/1772] Document per-item versions using `@since` gates --- proposals/io/wit/error.wit | 4 +++- proposals/io/wit/poll.wit | 5 +++++ proposals/io/wit/streams.wit | 18 ++++++++++++++++++ proposals/io/wit/world.wit | 4 ++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/proposals/io/wit/error.wit b/proposals/io/wit/error.wit index 8d11483a9..7e66dbba2 100644 --- a/proposals/io/wit/error.wit +++ b/proposals/io/wit/error.wit @@ -1,6 +1,6 @@ package wasi:io@0.2.0; - +@since(version = 0.2.0) interface error { /// A resource which represents some error information. /// @@ -19,6 +19,7 @@ interface error { /// /// The set of functions which can "downcast" an `error` into a more /// concrete type is open. + @since(version = 0.2.0) resource error { /// Returns a string that is suitable to assist humans in debugging /// this error. @@ -27,6 +28,7 @@ interface error { /// It may change across platforms, hosts, or other implementation /// details. Parsing this string is a major platform-compatibility /// hazard. + @since(version = 0.2.0) to-debug-string: func() -> string; } } diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index e69e82217..cbdc960f0 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -2,13 +2,16 @@ package wasi:io@0.2.0; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. +@since(version = 0.2.0) interface poll { /// `pollable` represents a single I/O event which may be ready, or not. + @since(version = 0.2.0) resource pollable { /// Return the readiness of a pollable. This function never blocks. /// /// Returns `true` when the pollable is ready, and `false` otherwise. + @since(version = 0.2.0) ready: func() -> bool; /// `block` returns immediately if the pollable is ready, and otherwise @@ -16,6 +19,7 @@ interface poll { /// /// This function is equivalent to calling `poll.poll` on a list /// containing only this pollable. + @since(version = 0.2.0) block: func(); } @@ -38,5 +42,6 @@ interface poll { /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as /// being ready for I/O. + @since(version = 0.2.0) poll: func(in: list>) -> list; } diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index 6d2f871e3..e9b21eda6 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -5,11 +5,13 @@ package wasi:io@0.2.0; /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. +@since(version = 0.2.0) interface streams { use error.{error}; use poll.{pollable}; /// An error for input-stream and output-stream operations. + @since(version = 0.2.0) variant stream-error { /// The last operation (a write or flush) failed before completion. /// @@ -29,6 +31,7 @@ interface streams { /// available, which could even be zero. To wait for data to be available, /// use the `subscribe` function to obtain a `pollable` which can be polled /// for using `wasi:io/poll`. + @since(version = 0.2.0) resource input-stream { /// Perform a non-blocking read from the stream. /// @@ -56,6 +59,7 @@ interface streams { /// is not possible to allocate in wasm32, or not desirable to allocate as /// as a return value by the callee. The callee may return a list of bytes /// less than `len` in size while more bytes are available for reading. + @since(version = 0.2.0) read: func( /// The maximum number of bytes to read len: u64 @@ -63,6 +67,7 @@ interface streams { /// Read bytes from a stream, after blocking until at least one byte can /// be read. Except for blocking, behavior is identical to `read`. + @since(version = 0.2.0) blocking-read: func( /// The maximum number of bytes to read len: u64 @@ -72,6 +77,7 @@ interface streams { /// /// Behaves identical to `read`, except instead of returning a list /// of bytes, returns the number of bytes consumed from the stream. + @since(version = 0.2.0) skip: func( /// The maximum number of bytes to skip. len: u64, @@ -79,6 +85,7 @@ interface streams { /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. + @since(version = 0.2.0) blocking-skip: func( /// The maximum number of bytes to skip. len: u64, @@ -90,6 +97,7 @@ interface streams { /// The created `pollable` is a child resource of the `input-stream`. /// Implementations may trap if the `input-stream` is dropped before /// all derived `pollable`s created with this function are dropped. + @since(version = 0.2.0) subscribe: func() -> pollable; } @@ -102,6 +110,7 @@ interface streams { /// promptly, which could even be zero. To wait for the stream to be ready to /// accept data, the `subscribe` function to obtain a `pollable` which can be /// polled for using `wasi:io/poll`. + @since(version = 0.2.0) resource output-stream { /// Check readiness for writing. This function never blocks. /// @@ -112,6 +121,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. + @since(version = 0.2.0) check-write: func() -> result; /// Perform a write. This function never blocks. @@ -127,6 +137,7 @@ interface streams { /// /// returns Err(closed) without writing if the stream has closed since /// the last call to check-write provided a permit. + @since(version = 0.2.0) write: func( contents: list ) -> result<_, stream-error>; @@ -155,6 +166,7 @@ interface streams { /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` + @since(version = 0.2.0) blocking-write-and-flush: func( contents: list ) -> result<_, stream-error>; @@ -169,10 +181,12 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. + @since(version = 0.2.0) flush: func() -> result<_, stream-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. + @since(version = 0.2.0) blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream @@ -193,6 +207,7 @@ interface streams { /// preconditions (must use check-write first), but instead of /// passing a list of bytes, you simply pass the number of zero-bytes /// that should be written. + @since(version = 0.2.0) write-zeroes: func( /// The number of zero-bytes to write len: u64 @@ -222,6 +237,7 @@ interface streams { /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` + @since(version = 0.2.0) blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 @@ -240,6 +256,7 @@ interface streams { /// /// This function returns the number of bytes transferred; it may be less /// than `len`. + @since(version = 0.2.0) splice: func( /// The stream to read from src: borrow, @@ -252,6 +269,7 @@ interface streams { /// This is similar to `splice`, except that it blocks until the /// `output-stream` is ready for writing, and the `input-stream` /// is ready for reading, before performing the `splice`. + @since(version = 0.2.0) blocking-splice: func( /// The stream to read from src: borrow, diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index 5f0b43fe5..f5c098793 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -1,6 +1,10 @@ package wasi:io@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import streams; + + @since(version = 0.2.0) import poll; } From 1db33a5f4f9b89685548a81b657e1af196d7ef6c Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 21 Jun 2024 02:14:01 +0200 Subject: [PATCH 1453/1772] annotate `use` statements --- proposals/io/wit/streams.wit | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index e9b21eda6..a57f20439 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -7,7 +7,9 @@ package wasi:io@0.2.0; /// when it does, they are expected to subsume this API. @since(version = 0.2.0) interface streams { + @since(version = 0.2.0) use error.{error}; + @since(version = 0.2.0) use poll.{pollable}; /// An error for input-stream and output-stream operations. From a7a4dd5aa9e8299f2d41559652368abf78bdcdca Mon Sep 17 00:00:00 2001 From: Yosh Date: Mon, 24 Jun 2024 02:57:24 +0200 Subject: [PATCH 1454/1772] update `wit-abi-up-to-date` to parse `@since` gates --- proposals/io/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index b944a0ddb..77fabf7a8 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -11,4 +11,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: WebAssembly/wit-abi-up-to-date@v17 + - uses: WebAssembly/wit-abi-up-to-date@v21 From 00369bbdc05b7d863a9faeb35e2104248eb3e26d Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 28 Jun 2024 18:09:26 +0200 Subject: [PATCH 1455/1772] Update imports.md --- proposals/io/imports.md | 176 ++++++++++++++++++++-------------------- 1 file changed, 87 insertions(+), 89 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index 6828e9300..dd0c4f2fd 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -2,33 +2,31 @@ -

      Import interface wasi:io/error@0.2.0

      +

      Import interface wasi:io/error@0.2.0


      Types

      -

      resource error

      +

      resource error

      A resource which represents some error information.

      The only method provided by this resource is to-debug-string, which provides some human-readable information about the error.

      In the wasi:io package, this resource is returned through the wasi:io/streams/stream-error type.

      To provide more specific error information, other interfaces may -provide functions to further "downcast" this error into more specific -error information. For example, errors returned in streams derived -from filesystem types to be described using the filesystem's own -error-code type, using the function -wasi:filesystem/types/filesystem-error-code, which takes a parameter -borrow<error> and returns -option<wasi:filesystem/types/error-code>.

      +offer functions to "downcast" this error into more specific types. For example, +errors returned from streams derived from filesystem types can be described using +the filesystem's own error-code type. This is done using the function +wasi:filesystem/types/filesystem-error-code, which takes a borrow<error> +parameter and returns an option<wasi:filesystem/types/error-code>.

      The set of functions which can "downcast" an error into a more concrete type is open.

      Functions

      -

      [method]error.to-debug-string: func

      +

      [method]error.to-debug-string: func

      Returns a string that is suitable to assist humans in debugging this error.

      WARNING: The returned string should not be consumed mechanically! @@ -37,41 +35,41 @@ details. Parsing this string is a major platform-compatibility hazard.

      Params
      Return values
        -
      • string
      • +
      • string
      -

      Import interface wasi:io/poll@0.2.0

      +

      Import interface wasi:io/poll@0.2.0

      A poll API intended to let users wait for I/O events on multiple handles at once.


      Types

      -

      resource pollable

      +

      resource pollable

      pollable represents a single I/O event which may be ready, or not.

      Functions

      -

      [method]pollable.ready: func

      +

      [method]pollable.ready: func

      Return the readiness of a pollable. This function never blocks.

      Returns true when the pollable is ready, and false otherwise.

      Params
      Return values
        -
      • bool
      • +
      • bool
      -

      [method]pollable.block: func

      +

      [method]pollable.block: func

      block returns immediately if the pollable is ready, and otherwise blocks until ready.

      This function is equivalent to calling poll.poll on a list containing only this pollable.

      Params
      -

      poll: func

      +

      poll: func

      Poll for completion on a set of pollables.

      This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

      @@ -90,42 +88,42 @@ the pollables has an error, it is indicated by marking the source as being ready for I/O.

      Params
      Return values
      • list<u32>
      -

      Import interface wasi:io/streams@0.2.0

      +

      Import interface wasi:io/streams@0.2.0

      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

      In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


      Types

      -

      type error

      +

      type error

      error

      -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

      -#### `variant stream-error` +#### `variant stream-error`

      An error for input-stream and output-stream operations.

      Variant Cases
      • -

        last-operation-failed: own<error>

        +

        last-operation-failed: own<error>

        The last operation (a write or flush) failed before completion.

        More information is available in the error payload.

      • -

        closed

        +

        closed

        The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

      -

      resource input-stream

      +

      resource input-stream

      An input bytestream.

      input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are @@ -133,7 +131,7 @@ promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

      -

      resource output-stream

      +

      resource output-stream

      An output bytestream.

      output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also @@ -142,7 +140,7 @@ promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

      Functions

      -

      [method]input-stream.read: func

      +

      [method]input-stream.read: func

      Perform a non-blocking read from the stream.

      When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -166,51 +164,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

      Params
      Return values
      -

      [method]input-stream.blocking-read: func

      +

      [method]input-stream.blocking-read: func

      Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

      Params
      Return values
      -

      [method]input-stream.skip: func

      +

      [method]input-stream.skip: func

      Skip bytes from a stream. Returns number of bytes skipped.

      Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

      Params
      Return values
      -

      [method]input-stream.blocking-skip: func

      +

      [method]input-stream.blocking-skip: func

      Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

      Params
      Return values
      -

      [method]input-stream.subscribe: func

      +

      [method]input-stream.subscribe: func

      Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -219,13 +217,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

      Params
      Return values
      -

      [method]output-stream.check-write: func

      +

      [method]output-stream.check-write: func

      Check readiness for writing. This function never blocks.

      Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -235,13 +233,13 @@ become ready when this function will report at least 1 byte, or an error.

      Params
      Return values
      -

      [method]output-stream.write: func

      +

      [method]output-stream.write: func

      Perform a write. This function never blocks.

      When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -254,14 +252,14 @@ length of less than or equal to n. Otherwise, this function will trap.

      the last call to check-write provided a permit.

      Params
      Return values
      -

      [method]output-stream.blocking-write-and-flush: func

      +

      [method]output-stream.blocking-write-and-flush: func

      Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

      This is a convenience wrapper around the use of check-write, @@ -285,14 +283,14 @@ let _ = this.check-write(); // eliding error handling

      Params
      Return values
      -

      [method]output-stream.flush: func

      +

      [method]output-stream.flush: func

      Request to flush buffered output. This function never blocks.

      This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -303,24 +301,24 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

      Params
      Return values
      -

      [method]output-stream.blocking-flush: func

      +

      [method]output-stream.blocking-flush: func

      Request to flush buffered output, and block until flush completes and stream is ready for writing again.

      Params
      Return values
      -

      [method]output-stream.subscribe: func

      +

      [method]output-stream.subscribe: func

      Create a pollable which will resolve once the output-stream is ready for more writing, or an error has occured. When this pollable is ready, check-write will return ok(n) with n>0, or an @@ -331,13 +329,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

      Params
      Return values
      -

      [method]output-stream.write-zeroes: func

      +

      [method]output-stream.write-zeroes: func

      Write zeroes to a stream.

      This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -345,14 +343,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

      Params
      Return values
      -

      [method]output-stream.blocking-write-zeroes-and-flush: func

      +

      [method]output-stream.blocking-write-zeroes-and-flush: func

      Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

      @@ -376,14 +374,14 @@ let _ = this.check-write(); // eliding error handling
      Params
      Return values
      -

      [method]output-stream.splice: func

      +

      [method]output-stream.splice: func

      Read from one stream and write to another.

      The behavior of splice is equivelant to:

        @@ -398,26 +396,26 @@ let _ = this.check-write(); // eliding error handling than len.

        Params
        Return values
        -

        [method]output-stream.blocking-splice: func

        +

        [method]output-stream.blocking-splice: func

        Read from one stream and write to another, with blocking.

        This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

        Params
        Return values
        From e395fdebc2cea7dd80b0ed8f60bdd78061388f18 Mon Sep 17 00:00:00 2001 From: Yosh Date: Tue, 28 May 2024 14:21:45 +0200 Subject: [PATCH 1456/1772] Document per-item versions using `@since` gates --- proposals/filesystem/wit/preopens.wit | 2 ++ proposals/filesystem/wit/types.wit | 42 +++++++++++++++++++++++++++ proposals/filesystem/wit/world.wit | 3 ++ 3 files changed, 47 insertions(+) diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit index da801f6d6..d081ff768 100644 --- a/proposals/filesystem/wit/preopens.wit +++ b/proposals/filesystem/wit/preopens.wit @@ -1,8 +1,10 @@ package wasi:filesystem@0.2.0; +@since(version = 0.2.0) interface preopens { use types.{descriptor}; /// Return the set of preopened directories, and their path. + @since(version = 0.2.0) get-directories: func() -> list>; } diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 11108fcda..a3e3bf0a9 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -23,16 +23,19 @@ package wasi:filesystem@0.2.0; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md +@since(version = 0.2.0) interface types { use wasi:io/streams@0.2.0.{input-stream, output-stream, error}; use wasi:clocks/wall-clock@0.2.0.{datetime}; /// File size or length of a region within a file. + @since(version = 0.2.0) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. + @since(version = 0.2.0) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -56,6 +59,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. + @since(version = 0.2.0) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -99,6 +103,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. + @since(version = 0.2.0) record descriptor-stat { /// File type. %type: descriptor-type, @@ -125,6 +130,7 @@ interface types { } /// Flags determining the method of how paths are resolved. + @since(version = 0.2.0) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -132,6 +138,7 @@ interface types { } /// Open flags used by `open-at`. + @since(version = 0.2.0) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -144,9 +151,11 @@ interface types { } /// Number of hard links to an inode. + @since(version = 0.2.0) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. + @since(version = 0.2.0) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -248,6 +257,7 @@ interface types { } /// File or memory access pattern advisory information. + @since(version = 0.2.0) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -271,6 +281,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. + @since(version = 0.2.0) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -281,6 +292,7 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. + @since(version = 0.2.0) resource descriptor { /// Return a stream for reading from a file, if available. /// @@ -290,6 +302,7 @@ interface types { /// file and they do not interfere with each other. /// /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. + @since(version = 0.2.0) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, @@ -301,6 +314,7 @@ interface types { /// /// Note: This allows using `write-stream`, which is similar to `write` in /// POSIX. + @since(version = 0.2.0) write-via-stream: func( /// The offset within the file at which to start writing. offset: filesize, @@ -312,11 +326,13 @@ interface types { /// /// Note: This allows using `write-stream`, which is similar to `write` with /// `O_APPEND` in in POSIX. + @since(version = 0.2.0) append-via-stream: func() -> result; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. + @since(version = 0.2.0) advise: func( /// The offset within the file to which the advisory applies. offset: filesize, @@ -332,6 +348,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. + @since(version = 0.2.0) sync-data: func() -> result<_, error-code>; /// Get flags associated with a descriptor. @@ -340,6 +357,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. + @since(version = 0.2.0) get-flags: func() -> result; /// Get the dynamic type of a descriptor. @@ -352,12 +370,14 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. + @since(version = 0.2.0) get-type: func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. + @since(version = 0.2.0) set-size: func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. @@ -365,6 +385,7 @@ interface types { /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. + @since(version = 0.2.0) set-times: func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, @@ -383,6 +404,7 @@ interface types { /// In the future, this may change to return a `stream`. /// /// Note: This is similar to `pread` in POSIX. + @since(version = 0.2.0) read: func( /// The maximum number of bytes to read. length: filesize, @@ -399,6 +421,7 @@ interface types { /// In the future, this may change to take a `stream`. /// /// Note: This is similar to `pwrite` in POSIX. + @since(version = 0.2.0) write: func( /// Data to write buffer: list, @@ -415,6 +438,7 @@ interface types { /// This always returns a new stream which starts at the beginning of the /// directory. Multiple streams may be active on the same directory, and they /// do not interfere with each other. + @since(version = 0.2.0) read-directory: func() -> result; /// Synchronize the data and metadata of a file to disk. @@ -423,11 +447,13 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. + @since(version = 0.2.0) sync: func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. + @since(version = 0.2.0) create-directory-at: func( /// The relative path at which to create the directory. path: string, @@ -442,6 +468,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. + @since(version = 0.2.0) stat: func() -> result; /// Return the attributes of a file or directory. @@ -451,6 +478,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. + @since(version = 0.2.0) stat-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -464,6 +492,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. + @since(version = 0.2.0) set-times-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -478,6 +507,7 @@ interface types { /// Create a hard link. /// /// Note: This is similar to `linkat` in POSIX. + @since(version = 0.2.0) link-at: func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, @@ -507,6 +537,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. + @since(version = 0.2.0) open-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -524,6 +555,7 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. + @since(version = 0.2.0) readlink-at: func( /// The relative path of the symbolic link from which to read. path: string, @@ -534,6 +566,7 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + @since(version = 0.2.0) remove-directory-at: func( /// The relative path to a directory to remove. path: string, @@ -542,6 +575,7 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. + @since(version = 0.2.0) rename-at: func( /// The relative source path of the file or directory to rename. old-path: string, @@ -557,6 +591,7 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. + @since(version = 0.2.0) symlink-at: func( /// The contents of the symbolic link. old-path: string, @@ -568,6 +603,7 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + @since(version = 0.2.0) unlink-file-at: func( /// The relative path to a file to unlink. path: string, @@ -579,6 +615,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. + @since(version = 0.2.0) is-same-object: func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred @@ -600,12 +637,14 @@ interface types { /// computed hash. /// /// However, none of these is required. + @since(version = 0.2.0) metadata-hash: func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. + @since(version = 0.2.0) metadata-hash-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -615,8 +654,10 @@ interface types { } /// A stream of directory entries. + @since(version = 0.2.0) resource directory-entry-stream { /// Read a single directory entry from a `directory-entry-stream`. + @since(version = 0.2.0) read-directory-entry: func() -> result, error-code>; } @@ -630,5 +671,6 @@ interface types { /// /// Note that this function is fallible because not all stream-related /// errors are filesystem-related errors. + @since(version = 0.2.0) filesystem-error-code: func(err: borrow) -> option; } diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index 663f57920..c8d99f56e 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,6 +1,9 @@ package wasi:filesystem@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import types; + @since(version = 0.2.0) import preopens; } From 6459996e82d9ebae03e91f8d2c7b6a6e42f0a2b6 Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 21 Jun 2024 02:11:41 +0200 Subject: [PATCH 1457/1772] annotate `use` statements --- proposals/filesystem/wit/preopens.wit | 1 + proposals/filesystem/wit/types.wit | 2 ++ 2 files changed, 3 insertions(+) diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit index d081ff768..08094ab3f 100644 --- a/proposals/filesystem/wit/preopens.wit +++ b/proposals/filesystem/wit/preopens.wit @@ -2,6 +2,7 @@ package wasi:filesystem@0.2.0; @since(version = 0.2.0) interface preopens { + @since(version = 0.2.0) use types.{descriptor}; /// Return the set of preopened directories, and their path. diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index a3e3bf0a9..4900ae2c4 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -25,7 +25,9 @@ package wasi:filesystem@0.2.0; /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md @since(version = 0.2.0) interface types { + @since(version = 0.2.0) use wasi:io/streams@0.2.0.{input-stream, output-stream, error}; + @since(version = 0.2.0) use wasi:clocks/wall-clock@0.2.0.{datetime}; /// File size or length of a region within a file. From 74fc7ac7350267a8b496bac12f60b65054740cda Mon Sep 17 00:00:00 2001 From: Yosh Date: Mon, 24 Jun 2024 02:59:55 +0200 Subject: [PATCH 1458/1772] update `wit-abi-up-to-date` to parse `@since` gates --- proposals/filesystem/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index 5ca5ba1fa..1b92987e9 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -18,4 +18,4 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v17 + - uses: WebAssembly/wit-abi-up-to-date@v21 From 384d028e665d33e1fa462f221621044026bd489b Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 28 Jun 2024 23:02:37 +0200 Subject: [PATCH 1459/1772] Update imports.md --- proposals/filesystem/imports.md | 624 ++++++++++++++++---------------- 1 file changed, 312 insertions(+), 312 deletions(-) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index 78acb2f58..660858be1 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -2,19 +2,19 @@ -

        Import interface wasi:io/error@0.2.0

        +

        Import interface wasi:io/error@0.2.0


        Types

        -

        resource error

        +

        resource error

        A resource which represents some error information.

        The only method provided by this resource is to-debug-string, which provides some human-readable information about the error.

        @@ -31,7 +31,7 @@ error-code type, using the function

        The set of functions which can "downcast" an error into a more concrete type is open.

        Functions

        -

        [method]error.to-debug-string: func

        +

        [method]error.to-debug-string: func

        Returns a string that is suitable to assist humans in debugging this error.

        WARNING: The returned string should not be consumed mechanically! @@ -40,41 +40,41 @@ details. Parsing this string is a major platform-compatibility hazard.

        Params
        Return values
          -
        • string
        • +
        • string
        -

        Import interface wasi:io/poll@0.2.0

        +

        Import interface wasi:io/poll@0.2.0

        A poll API intended to let users wait for I/O events on multiple handles at once.


        Types

        -

        resource pollable

        +

        resource pollable

        pollable represents a single I/O event which may be ready, or not.

        Functions

        -

        [method]pollable.ready: func

        +

        [method]pollable.ready: func

        Return the readiness of a pollable. This function never blocks.

        Returns true when the pollable is ready, and false otherwise.

        Params
        Return values
          -
        • bool
        • +
        • bool
        -

        [method]pollable.block: func

        +

        [method]pollable.block: func

        block returns immediately if the pollable is ready, and otherwise blocks until ready.

        This function is equivalent to calling poll.poll on a list containing only this pollable.

        Params
        -

        poll: func

        +

        poll: func

        Poll for completion on a set of pollables.

        This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

        @@ -90,42 +90,42 @@ the pollables has an error, it is indicated by marking the source as being reaedy for I/O.

        Params
        Return values
        • list<u32>
        -

        Import interface wasi:io/streams@0.2.0

        +

        Import interface wasi:io/streams@0.2.0

        WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

        In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


        Types

        -

        type error

        +

        type error

        error

        -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

        -#### `variant stream-error` +#### `variant stream-error`

        An error for input-stream and output-stream operations.

        Variant Cases
        • -

          last-operation-failed: own<error>

          +

          last-operation-failed: own<error>

          The last operation (a write or flush) failed before completion.

          More information is available in the error payload.

        • -

          closed

          +

          closed

          The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

        -

        resource input-stream

        +

        resource input-stream

        An input bytestream.

        input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are @@ -133,7 +133,7 @@ promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

        -

        resource output-stream

        +

        resource output-stream

        An output bytestream.

        output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also @@ -142,7 +142,7 @@ promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

        Functions

        -

        [method]input-stream.read: func

        +

        [method]input-stream.read: func

        Perform a non-blocking read from the stream.

        When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -166,51 +166,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

        Params
        Return values
        -

        [method]input-stream.blocking-read: func

        +

        [method]input-stream.blocking-read: func

        Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

        Params
        Return values
        -

        [method]input-stream.skip: func

        +

        [method]input-stream.skip: func

        Skip bytes from a stream. Returns number of bytes skipped.

        Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

        Params
        Return values
        -

        [method]input-stream.blocking-skip: func

        +

        [method]input-stream.blocking-skip: func

        Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

        Params
        Return values
        -

        [method]input-stream.subscribe: func

        +

        [method]input-stream.subscribe: func

        Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -219,13 +219,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

        Params
        Return values
        -

        [method]output-stream.check-write: func

        +

        [method]output-stream.check-write: func

        Check readiness for writing. This function never blocks.

        Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -235,13 +235,13 @@ become ready when this function will report at least 1 byte, or an error.

        Params
        Return values
        -

        [method]output-stream.write: func

        +

        [method]output-stream.write: func

        Perform a write. This function never blocks.

        When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -254,14 +254,14 @@ length of less than or equal to n. Otherwise, this function will trap.

        the last call to check-write provided a permit.

        Params
        Return values
        -

        [method]output-stream.blocking-write-and-flush: func

        +

        [method]output-stream.blocking-write-and-flush: func

        Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

        This is a convenience wrapper around the use of check-write, @@ -285,14 +285,14 @@ let _ = this.check-write(); // eliding error handling

        Params
        Return values
        -

        [method]output-stream.flush: func

        +

        [method]output-stream.flush: func

        Request to flush buffered output. This function never blocks.

        This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -303,24 +303,24 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

        Params
        Return values
        -

        [method]output-stream.blocking-flush: func

        +

        [method]output-stream.blocking-flush: func

        Request to flush buffered output, and block until flush completes and stream is ready for writing again.

        Params
        Return values
        -

        [method]output-stream.subscribe: func

        +

        [method]output-stream.subscribe: func

        Create a pollable which will resolve once the output-stream is ready for more writing, or an error has occured. When this pollable is ready, check-write will return ok(n) with n>0, or an @@ -331,13 +331,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

        Params
        Return values
        -

        [method]output-stream.write-zeroes: func

        +

        [method]output-stream.write-zeroes: func

        Write zeroes to a stream.

        This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -345,14 +345,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

        Params
        Return values
        -

        [method]output-stream.blocking-write-zeroes-and-flush: func

        +

        [method]output-stream.blocking-write-zeroes-and-flush: func

        Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

        @@ -376,14 +376,14 @@ let _ = this.check-write(); // eliding error handling
        Params
        Return values
        -

        [method]output-stream.splice: func

        +

        [method]output-stream.splice: func

        Read from one stream and write to another.

        The behavior of splice is equivelant to:

          @@ -398,30 +398,30 @@ let _ = this.check-write(); // eliding error handling than len.

          Params
          Return values
          -

          [method]output-stream.blocking-splice: func

          +

          [method]output-stream.blocking-splice: func

          Read from one stream and write to another, with blocking.

          This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

          Params
          Return values
          -

          Import interface wasi:clocks/wall-clock@0.2.0

          +

          Import interface wasi:clocks/wall-clock@0.2.0

          WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

          @@ -434,16 +434,16 @@ monotonic, making it unsuitable for measuring elapsed time.

          It is intended for reporting the current date and time for humans.


          Types

          -

          record datetime

          +

          record datetime

          A time and date in seconds plus nanoseconds.

          Record Fields

          Functions

          -

          now: func

          +

          now: func

          Read the current value of the clock.

          This clock is not monotonic, therefore calling this function repeatedly will not necessarily produce a sequence of non-decreasing values.

          @@ -455,14 +455,14 @@ also known as Unix Time.
        1. datetime
    -

    resolution: func

    +

    resolution: func

    Query the resolution of the clock.

    The nanoseconds field of the output is always less than 1000000000.

    Return values
    -

    Import interface wasi:filesystem/types@0.2.0

    +

    Import interface wasi:filesystem/types@0.2.0

    WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

    @@ -482,75 +482,75 @@ underlying filesystem, the function fails with WASI filesystem path resolution.


    Types

    -

    type input-stream

    +

    type input-stream

    input-stream

    -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

    -#### `type error` +#### `type error` [`error`](#error)

    -#### `type datetime` +#### `type datetime` [`datetime`](#datetime)

    -#### `type filesize` +#### `type filesize` `u64`

    File size or length of a region within a file. -

    enum descriptor-type

    +

    enum descriptor-type

    The type of a filesystem object referenced by a descriptor.

    Note: This was called filetype in earlier versions of WASI.

    Enum Cases
    • -

      unknown

      +

      unknown

      The type of the descriptor or file is unknown or is different from any of the other types specified.

    • -

      block-device

      +

      block-device

      The descriptor refers to a block device inode.

    • -

      character-device

      +

      character-device

      The descriptor refers to a character device inode.

    • -

      directory

      +

      directory

      The descriptor refers to a directory inode.

    • -

      fifo

      +

      fifo

      The descriptor refers to a named pipe.

    • -

      symbolic-link

      +

      symbolic-link

      The file refers to a symbolic link inode.

    • -

      regular-file

      +

      regular-file

      The descriptor refers to a regular file inode.

    • -

      socket

      +

      socket

      The descriptor refers to a socket.

    -

    flags descriptor-flags

    +

    flags descriptor-flags

    Descriptor flags.

    Note: This was called fdflags in earlier versions of WASI.

    Flags members
    • -

      read:

      +

      read:

      Read mode: Data can be read.

    • -

      write:

      +

      write:

      Write mode: Data can be written to.

    • -

      file-integrity-sync:

      +

      file-integrity-sync:

      Request that writes be performed according to synchronized I/O file integrity completion. The data stored in the file and the file's metadata are synchronized. This is similar to `O_SYNC` in POSIX. @@ -559,7 +559,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

    • -

      data-integrity-sync:

      +

      data-integrity-sync:

      Request that writes be performed according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. This is similar to `O_DSYNC` in POSIX. @@ -568,7 +568,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

    • -

      requested-write-sync:

      +

      requested-write-sync:

      Requests that reads be performed at the same level of integrety requested for writes. This is similar to `O_RSYNC` in POSIX.

      The precise semantics of this operation have not yet been defined for @@ -576,7 +576,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

    • -

      mutate-directory:

      +

      mutate-directory:

      Mutating directories mode: Directory contents may be mutated.

      When this flag is unset on a descriptor, operations using the descriptor which would create, rename, delete, modify the data or @@ -586,107 +586,107 @@ they would otherwise succeed.

      This may only be set on directories.

    -

    flags path-flags

    +

    flags path-flags

    Flags determining the method of how paths are resolved.

    Flags members
      -
    • symlink-follow:

      As long as the resolved path corresponds to a symbolic link, it is +

    • symlink-follow:

      As long as the resolved path corresponds to a symbolic link, it is expanded.

    -

    flags open-flags

    +

    flags open-flags

    Open flags used by open-at.

    Flags members
    • -

      create:

      +

      create:

      Create file if it does not exist, similar to `O_CREAT` in POSIX.

    • -

      directory:

      +

      directory:

      Fail if not a directory, similar to `O_DIRECTORY` in POSIX.

    • -

      exclusive:

      +

      exclusive:

      Fail if file already exists, similar to `O_EXCL` in POSIX.

    • -

      truncate:

      +

      truncate:

      Truncate file to size 0, similar to `O_TRUNC` in POSIX.

    -

    type link-count

    +

    type link-count

    u64

    Number of hard links to an inode. -

    record descriptor-stat

    +

    record descriptor-stat

    File attributes.

    Note: This was called filestat in earlier versions of WASI.

    Record Fields
    -

    variant new-timestamp

    +

    variant new-timestamp

    When setting a timestamp, this gives the value to set it to.

    Variant Cases
    • -

      no-change

      +

      no-change

      Leave the timestamp set to its previous value.

    • -

      now

      +

      now

      Set the timestamp to the current time of the system clock associated with the filesystem.

    • -

      timestamp: datetime

      +

      timestamp: datetime

      Set the timestamp to the given value.

    -

    record directory-entry

    +

    record directory-entry

    A directory entry.

    Record Fields
    -

    enum error-code

    +

    enum error-code

    Error codes returned by functions, similar to errno in POSIX. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -694,211 +694,211 @@ merely for alignment with POSIX.

    Enum Cases
    • -

      access

      +

      access

      Permission denied, similar to `EACCES` in POSIX.

    • -

      would-block

      +

      would-block

      Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX.

    • -

      already

      +

      already

      Connection already in progress, similar to `EALREADY` in POSIX.

    • -

      bad-descriptor

      +

      bad-descriptor

      Bad descriptor, similar to `EBADF` in POSIX.

    • -

      busy

      +

      busy

      Device or resource busy, similar to `EBUSY` in POSIX.

    • -

      deadlock

      +

      deadlock

      Resource deadlock would occur, similar to `EDEADLK` in POSIX.

    • -

      quota

      +

      quota

      Storage quota exceeded, similar to `EDQUOT` in POSIX.

    • -

      exist

      +

      exist

      File exists, similar to `EEXIST` in POSIX.

    • -

      file-too-large

      +

      file-too-large

      File too large, similar to `EFBIG` in POSIX.

    • -

      illegal-byte-sequence

      +

      illegal-byte-sequence

      Illegal byte sequence, similar to `EILSEQ` in POSIX.

    • -

      in-progress

      +

      in-progress

      Operation in progress, similar to `EINPROGRESS` in POSIX.

    • -

      interrupted

      +

      interrupted

      Interrupted function, similar to `EINTR` in POSIX.

    • -

      invalid

      +

      invalid

      Invalid argument, similar to `EINVAL` in POSIX.

    • -

      io

      +

      io

      I/O error, similar to `EIO` in POSIX.

    • -

      is-directory

      +

      is-directory

      Is a directory, similar to `EISDIR` in POSIX.

    • -

      loop

      +

      loop

      Too many levels of symbolic links, similar to `ELOOP` in POSIX.

    • -

      too-many-links

      +

      too-many-links

      Too many links, similar to `EMLINK` in POSIX.

    • -

      message-size

      +

      message-size

      Message too large, similar to `EMSGSIZE` in POSIX.

    • -

      name-too-long

      +

      name-too-long

      Filename too long, similar to `ENAMETOOLONG` in POSIX.

    • -

      no-device

      +

      no-device

      No such device, similar to `ENODEV` in POSIX.

    • -

      no-entry

      +

      no-entry

      No such file or directory, similar to `ENOENT` in POSIX.

    • -

      no-lock

      +

      no-lock

      No locks available, similar to `ENOLCK` in POSIX.

    • -

      insufficient-memory

      +

      insufficient-memory

      Not enough space, similar to `ENOMEM` in POSIX.

    • -

      insufficient-space

      +

      insufficient-space

      No space left on device, similar to `ENOSPC` in POSIX.

    • -

      not-directory

      +

      not-directory

      Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX.

    • -

      not-empty

      +

      not-empty

      Directory not empty, similar to `ENOTEMPTY` in POSIX.

    • -

      not-recoverable

      +

      not-recoverable

      State not recoverable, similar to `ENOTRECOVERABLE` in POSIX.

    • -

      unsupported

      +

      unsupported

      Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX.

    • -

      no-tty

      +

      no-tty

      Inappropriate I/O control operation, similar to `ENOTTY` in POSIX.

    • -

      no-such-device

      +

      no-such-device

      No such device or address, similar to `ENXIO` in POSIX.

    • -

      overflow

      +

      overflow

      Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX.

    • -

      not-permitted

      +

      not-permitted

      Operation not permitted, similar to `EPERM` in POSIX.

    • -

      pipe

      +

      pipe

      Broken pipe, similar to `EPIPE` in POSIX.

    • -

      read-only

      +

      read-only

      Read-only file system, similar to `EROFS` in POSIX.

    • -

      invalid-seek

      +

      invalid-seek

      Invalid seek, similar to `ESPIPE` in POSIX.

    • -

      text-file-busy

      +

      text-file-busy

      Text file busy, similar to `ETXTBSY` in POSIX.

    • -

      cross-device

      +

      cross-device

      Cross-device link, similar to `EXDEV` in POSIX.

    -

    enum advice

    +

    enum advice

    File or memory access pattern advisory information.

    Enum Cases
    • -

      normal

      +

      normal

      The application has no advice to give on its behavior with respect to the specified data.

    • -

      sequential

      +

      sequential

      The application expects to access the specified data sequentially from lower offsets to higher offsets.

    • -

      random

      +

      random

      The application expects to access the specified data in a random order.

    • -

      will-need

      +

      will-need

      The application expects to access the specified data in the near future.

    • -

      dont-need

      +

      dont-need

      The application expects that it will not access the specified data in the near future.

    • -

      no-reuse

      +

      no-reuse

      The application expects to access the specified data once and then not reuse it thereafter.

    -

    record metadata-hash-value

    +

    record metadata-hash-value

    A 128-bit hash value, split into parts because wasm doesn't have a 128-bit integer type.

    Record Fields
    • -

      lower: u64

      +

      lower: u64

      64 bits of a 128-bit hash value.

    • -

      upper: u64

      +

      upper: u64

      Another 64 bits of a 128-bit hash value.

    -

    resource descriptor

    +

    resource descriptor

    A descriptor is a reference to a filesystem object, which may be a file, directory, named pipe, special file, or other object on which filesystem calls may be made.

    -

    resource directory-entry-stream

    +

    resource directory-entry-stream

    A stream of directory entries.

    Functions

    -

    [method]descriptor.read-via-stream: func

    +

    [method]descriptor.read-via-stream: func

    Return a stream for reading from a file, if available.

    May fail with an error-code describing why the file cannot be read.

    Multiple read, write, and append streams may be active on the same open @@ -906,81 +906,81 @@ file and they do not interfere with each other.

    Note: This allows using read-stream, which is similar to read in POSIX.

    Params
    Return values
    -

    [method]descriptor.write-via-stream: func

    +

    [method]descriptor.write-via-stream: func

    Return a stream for writing to a file, if available.

    May fail with an error-code describing why the file cannot be written.

    Note: This allows using write-stream, which is similar to write in POSIX.

    Params
    Return values
    -

    [method]descriptor.append-via-stream: func

    +

    [method]descriptor.append-via-stream: func

    Return a stream for appending to a file, if available.

    May fail with an error-code describing why the file cannot be appended.

    Note: This allows using write-stream, which is similar to write with O_APPEND in in POSIX.

    Params
    Return values
    -

    [method]descriptor.advise: func

    +

    [method]descriptor.advise: func

    Provide file advisory information on a descriptor.

    This is similar to posix_fadvise in POSIX.

    Params
    Return values
    -

    [method]descriptor.sync-data: func

    +

    [method]descriptor.sync-data: func

    Synchronize the data of a file to disk.

    This function succeeds with no effect if the file descriptor is not opened for writing.

    Note: This is similar to fdatasync in POSIX.

    Params
    Return values
    -

    [method]descriptor.get-flags: func

    +

    [method]descriptor.get-flags: func

    Get flags associated with a descriptor.

    Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

    Note: This returns the value that was the fs_flags value returned from fdstat_get in earlier versions of WASI.

    Params
    Return values
    -

    [method]descriptor.get-type: func

    +

    [method]descriptor.get-type: func

    Get the dynamic type of a descriptor.

    Note: This returns the same value as the type field of the fd-stat returned by stat, stat-at and similar.

    @@ -990,40 +990,40 @@ by fstat in POSIX.

    from fdstat_get in earlier versions of WASI.

    Params
    Return values
    -

    [method]descriptor.set-size: func

    +

    [method]descriptor.set-size: func

    Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.

    Note: This was called fd_filestat_set_size in earlier versions of WASI.

    Params
    Return values
    -

    [method]descriptor.set-times: func

    +

    [method]descriptor.set-times: func

    Adjust the timestamps of an open file or directory.

    Note: This is similar to futimens in POSIX.

    Note: This was called fd_filestat_set_times in earlier versions of WASI.

    Params
    Return values
    -

    [method]descriptor.read: func

    +

    [method]descriptor.read: func

    Read from a descriptor, without using and updating the descriptor's offset.

    This function returns a list of bytes containing the data that was read, along with a bool which, when true, indicates that the end of the @@ -1034,15 +1034,15 @@ if the I/O operation is interrupted.

    Note: This is similar to pread in POSIX.

    Params
    Return values
    -

    [method]descriptor.write: func

    +

    [method]descriptor.write: func

    Write to a descriptor, without using and updating the descriptor's offset.

    It is valid to write past the end of a file; the file is extended to the extent of the write, with bytes between the previous end and the start of @@ -1051,15 +1051,15 @@ the write set to zero.

    Note: This is similar to pwrite in POSIX.

    Params
    Return values
    -

    [method]descriptor.read-directory: func

    +

    [method]descriptor.read-directory: func

    Read directory entries from a directory.

    On filesystems where directories contain entries referring to themselves and their parents, often named . and .. respectively, these entries @@ -1069,38 +1069,38 @@ directory. Multiple streams may be active on the same directory, and they do not interfere with each other.

    Params
    Return values
    -

    [method]descriptor.sync: func

    +

    [method]descriptor.sync: func

    Synchronize the data and metadata of a file to disk.

    This function succeeds with no effect if the file descriptor is not opened for writing.

    Note: This is similar to fsync in POSIX.

    Params
    Return values
    -

    [method]descriptor.create-directory-at: func

    +

    [method]descriptor.create-directory-at: func

    Create a directory.

    Note: This is similar to mkdirat in POSIX.

    Params
    Return values
    -

    [method]descriptor.stat: func

    +

    [method]descriptor.stat: func

    Return the attributes of an open file or directory.

    Note: This is similar to fstat in POSIX, except that it does not return device and inode information. For testing whether two descriptors refer to @@ -1110,13 +1110,13 @@ modified, use metadata-hash.

    Note: This was called fd_filestat_get in earlier versions of WASI.

    Params
    Return values
    -

    [method]descriptor.stat-at: func

    +

    [method]descriptor.stat-at: func

    Return the attributes of a file or directory.

    Note: This is similar to fstatat in POSIX, except that it does not return device and inode information. See the stat description for a @@ -1124,47 +1124,47 @@ discussion of alternatives.

    Note: This was called path_filestat_get in earlier versions of WASI.

    Params
    Return values
    -

    [method]descriptor.set-times-at: func

    +

    [method]descriptor.set-times-at: func

    Adjust the timestamps of a file or directory.

    Note: This is similar to utimensat in POSIX.

    Note: This was called path_filestat_set_times in earlier versions of WASI.

    Params
    Return values
    -

    [method]descriptor.link-at: func

    +

    [method]descriptor.link-at: func

    Create a hard link.

    Note: This is similar to linkat in POSIX.

    Params
    Return values
    -

    [method]descriptor.open-at: func

    +

    [method]descriptor.open-at: func

    Open a file or directory.

    The returned descriptor is not guaranteed to be the lowest-numbered descriptor not currently open/ it is randomized to prevent applications @@ -1181,86 +1181,86 @@ contains truncate or create, and the base descriptor d

    Note: This is similar to openat in POSIX.

    Params
    Return values
    -

    [method]descriptor.readlink-at: func

    +

    [method]descriptor.readlink-at: func

    Read the contents of a symbolic link.

    If the contents contain an absolute or rooted path in the underlying filesystem, this function fails with error-code::not-permitted.

    Note: This is similar to readlinkat in POSIX.

    Params
    Return values
    -

    [method]descriptor.remove-directory-at: func

    +

    [method]descriptor.remove-directory-at: func

    Remove a directory.

    Return error-code::not-empty if the directory is not empty.

    Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

    Params
    Return values
    -

    [method]descriptor.rename-at: func

    +

    [method]descriptor.rename-at: func

    Rename a filesystem object.

    Note: This is similar to renameat in POSIX.

    Params
    Return values
    -

    [method]descriptor.symlink-at: func

    +

    [method]descriptor.symlink-at: func

    Create a symbolic link (also known as a "symlink").

    If old-path starts with /, the function fails with error-code::not-permitted.

    Note: This is similar to symlinkat in POSIX.

    Params
    Return values
    -

    [method]descriptor.unlink-file-at: func

    +

    [method]descriptor.unlink-file-at: func

    Unlink a filesystem object that is not a directory.

    Return error-code::is-directory if the path refers to a directory. Note: This is similar to unlinkat(fd, path, 0) in POSIX.

    Params
    Return values
    -

    [method]descriptor.is-same-object: func

    +

    [method]descriptor.is-same-object: func

    Test whether two descriptors refer to the same filesystem object.

    In POSIX, this corresponds to testing whether the two descriptors have the same device (st_dev) and inode (st_ino or d_ino) numbers. @@ -1268,14 +1268,14 @@ wasi-filesystem does not expose device and inode numbers, so this function may be used instead.

    Params
    Return values
      -
    • bool
    • +
    • bool
    -

    [method]descriptor.metadata-hash: func

    +

    [method]descriptor.metadata-hash: func

    Return a hash of the metadata associated with a filesystem object referred to by a descriptor.

    This returns a hash of the last-modification timestamp and file size, and @@ -1295,37 +1295,37 @@ computed hash.

    However, none of these is required.

    Params
    Return values
    -

    [method]descriptor.metadata-hash-at: func

    +

    [method]descriptor.metadata-hash-at: func

    Return a hash of the metadata associated with a filesystem object referred to by a directory descriptor and a relative path.

    This performs the same hash computation as metadata-hash.

    Params
    Return values
    -

    [method]directory-entry-stream.read-directory-entry: func

    +

    [method]directory-entry-stream.read-directory-entry: func

    Read a single directory entry from a directory-entry-stream.

    Params
    Return values
    -

    filesystem-error-code: func

    +

    filesystem-error-code: func

    Attempts to extract a filesystem-related error-code from the stream error provided.

    Stream operations which return stream-error::last-operation-failed @@ -1336,21 +1336,21 @@ filesystem-related information about the error to return.

    errors are filesystem-related errors.

    Params
    Return values
    -

    Import interface wasi:filesystem/preopens@0.2.0

    +

    Import interface wasi:filesystem/preopens@0.2.0


    Types

    -

    type descriptor

    +

    type descriptor

    descriptor

    ----

    Functions

    -

    get-directories: func

    +

    get-directories: func

    Return the set of preopened directories, and their path.

    Return values
      From d401d0e23fd60e99bf2af256957b9c35692e4e19 Mon Sep 17 00:00:00 2001 From: Yosh Date: Tue, 28 May 2024 14:36:57 +0200 Subject: [PATCH 1460/1772] Document per-item versions using `@since` gates --- proposals/random/wit/insecure-seed.wit | 2 ++ proposals/random/wit/insecure.wit | 3 +++ proposals/random/wit/random.wit | 3 +++ proposals/random/wit/world.wit | 6 ++++++ 4 files changed, 14 insertions(+) diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index 47210ac6b..4cce62858 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -3,6 +3,7 @@ package wasi:random@0.2.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +@since(version = 0.2.0) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -21,5 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. + @since(version = 0.2.0) insecure-seed: func() -> tuple; } diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index c58f4ee85..3cea0c4a6 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -3,6 +3,7 @@ package wasi:random@0.2.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +@since(version = 0.2.0) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -12,11 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. + @since(version = 0.2.0) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. + @since(version = 0.2.0) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 0c017f093..41c3a0367 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -3,6 +3,7 @@ package wasi:random@0.2.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +@since(version = 0.2.0) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -16,11 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. + @since(version = 0.2.0) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. + @since(version = 0.2.0) get-random-u64: func() -> u64; } diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index 3da34914a..b5560a67a 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,7 +1,13 @@ package wasi:random@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import random; + + @since(version = 0.2.0) import insecure; + + @since(version = 0.2.0) import insecure-seed; } From 51aa54b779028d291d3f9f9f7996dae5cefce90c Mon Sep 17 00:00:00 2001 From: Yosh Date: Mon, 24 Jun 2024 02:59:33 +0200 Subject: [PATCH 1461/1772] update `wit-abi-up-to-date` to parse `@since` gates --- proposals/random/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index 0df64e9ce..293e49214 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -11,4 +11,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: WebAssembly/wit-abi-up-to-date@v17 + - uses: WebAssembly/wit-abi-up-to-date@v21 From 4d97192666591b6e368f6a2fd85e479be7ec6a92 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Wed, 3 Jul 2024 16:24:30 -0400 Subject: [PATCH 1462/1772] docs: regen md with newer wit-bindgen --- proposals/random/imports.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/proposals/random/imports.md b/proposals/random/imports.md index 4da4585dc..c97955792 100644 --- a/proposals/random/imports.md +++ b/proposals/random/imports.md @@ -2,19 +2,19 @@ -

      Import interface wasi:random/random@0.2.0

      +

      Import interface wasi:random/random@0.2.0

      WASI Random is a random data API.

      It is intended to be portable at least between Unix-family platforms and Windows.


      Functions

      -

      get-random-bytes: func

      +

      get-random-bytes: func

      Return len cryptographically-secure random or pseudo-random bytes.

      This function must produce data at least as cryptographically secure and fast as an adequately seeded cryptographically-secure pseudo-random @@ -27,13 +27,13 @@ must omit this function, rather than implementing it with deterministic data.

      Params
        -
      • len: u64
      • +
      • len: u64
      Return values
      • list<u8>
      -

      get-random-u64: func

      +

      get-random-u64: func

      Return a cryptographically-secure random or pseudo-random u64 value.

      This function returns the same type of data as get-random-bytes, represented as a u64.

      @@ -41,13 +41,13 @@ represented as a u64.

      • u64
      -

      Import interface wasi:random/insecure@0.2.0

      +

      Import interface wasi:random/insecure@0.2.0

      The insecure interface for insecure pseudo-random numbers.

      It is intended to be portable at least between Unix-family platforms and Windows.


      Functions

      -

      get-insecure-random-bytes: func

      +

      get-insecure-random-bytes: func

      Return len insecure pseudo-random bytes.

      This function is not cryptographically secure. Do not use it for anything related to security.

      @@ -56,13 +56,13 @@ implementations are encouraged to return evenly distributed values with a long period.

      Params
        -
      • len: u64
      • +
      • len: u64
      Return values
      • list<u8>
      -

      get-insecure-random-u64: func

      +

      get-insecure-random-u64: func

      Return an insecure pseudo-random u64 value.

      This function returns the same type of pseudo-random data as get-insecure-random-bytes, represented as a u64.

      @@ -70,13 +70,13 @@ a long period.

      • u64
      -

      Import interface wasi:random/insecure-seed@0.2.0

      +

      Import interface wasi:random/insecure-seed@0.2.0

      The insecure-seed interface for seeding hash-map DoS resistance.

      It is intended to be portable at least between Unix-family platforms and Windows.


      Functions

      -

      insecure-seed: func

      +

      insecure-seed: func

      Return a 128-bit value that may contain a pseudo-random value.

      The returned value is not required to be computed from a CSPRNG, and may even be entirely deterministic. Host implementations are encouraged to From 751ea76132a2565805c2b1300d2ad2b80f43e1a2 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Wed, 3 Jul 2024 16:31:00 -0400 Subject: [PATCH 1463/1772] wit-deps update --- proposals/cli/.github/workflows/main.yml | 1 - proposals/cli/command.md | 1361 ++++++++--------- proposals/cli/imports.md | 1361 ++++++++--------- proposals/cli/wit/deps.lock | 20 +- .../cli/wit/deps/clocks/monotonic-clock.wit | 17 +- proposals/cli/wit/deps/clocks/timezone.wit | 55 + proposals/cli/wit/deps/clocks/wall-clock.wit | 4 + proposals/cli/wit/deps/clocks/world.wit | 5 + .../cli/wit/deps/filesystem/preopens.wit | 3 + proposals/cli/wit/deps/filesystem/types.wit | 44 + proposals/cli/wit/deps/filesystem/world.wit | 3 + proposals/cli/wit/deps/io/error.wit | 16 +- proposals/cli/wit/deps/io/poll.wit | 12 +- proposals/cli/wit/deps/io/streams.wit | 20 + proposals/cli/wit/deps/io/world.wit | 4 + .../cli/wit/deps/random/insecure-seed.wit | 2 + proposals/cli/wit/deps/random/insecure.wit | 3 + proposals/cli/wit/deps/random/random.wit | 3 + proposals/cli/wit/deps/random/world.wit | 6 + .../cli/wit/deps/sockets/instance-network.wit | 4 +- .../cli/wit/deps/sockets/ip-name-lookup.wit | 9 +- proposals/cli/wit/deps/sockets/network.wit | 12 +- .../wit/deps/sockets/tcp-create-socket.wit | 5 +- proposals/cli/wit/deps/sockets/tcp.wit | 48 +- .../wit/deps/sockets/udp-create-socket.wit | 5 +- proposals/cli/wit/deps/sockets/udp.wit | 28 +- proposals/cli/wit/deps/sockets/world.wit | 8 + 27 files changed, 1652 insertions(+), 1407 deletions(-) create mode 100644 proposals/cli/wit/deps/clocks/timezone.wit diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml index a37194ca6..286495620 100644 --- a/proposals/cli/.github/workflows/main.yml +++ b/proposals/cli/.github/workflows/main.yml @@ -20,5 +20,4 @@ jobs: git diff --exit-code - uses: WebAssembly/wit-abi-up-to-date@v21 with: - wit-bindgen: '0.16.0' worlds: "command imports" diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 04dfb7b41..cdd51c13a 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -2,45 +2,45 @@

      -

      Import interface wasi:cli/environment@0.2.0

      +

      Import interface wasi:cli/environment@0.2.0


      Functions

      -

      get-environment: func

      +

      get-environment: func

      Get the POSIX-style environment variables.

      Each environment variable is provided as a pair of string variable names and string value.

      @@ -51,49 +51,47 @@ values each time it is called.

      • list<(string, string)>
      -

      get-arguments: func

      +

      get-arguments: func

      Get the POSIX-style arguments to the program.

      Return values
      • list<string>
      -

      initial-cwd: func

      +

      initial-cwd: func

      Return a path that programs should use as their initial current working directory, interpreting . as shorthand for this.

      Return values
      • option<string>
      -

      Import interface wasi:cli/exit@0.2.0

      +

      Import interface wasi:cli/exit@0.2.0


      Functions

      -

      exit: func

      +

      exit: func

      Exit the current instance and any linked instances.

      Params
        -
      • status: result
      • +
      • status: result
      -

      Import interface wasi:io/error@0.2.0

      +

      Import interface wasi:io/error@0.2.0


      Types

      -

      resource error

      +

      resource error

      A resource which represents some error information.

      The only method provided by this resource is to-debug-string, which provides some human-readable information about the error.

      In the wasi:io package, this resource is returned through the wasi:io/streams/stream-error type.

      To provide more specific error information, other interfaces may -provide functions to further "downcast" this error into more specific -error information. For example, errors returned in streams derived -from filesystem types to be described using the filesystem's own -error-code type, using the function -wasi:filesystem/types/filesystem-error-code, which takes a parameter -borrow<error> and returns -option<wasi:filesystem/types/error-code>.

      +offer functions to "downcast" this error into more specific types. For example, +errors returned from streams derived from filesystem types can be described using +the filesystem's own error-code type. This is done using the function +wasi:filesystem/types/filesystem-error-code, which takes a borrow<error> +parameter and returns an option<wasi:filesystem/types/error-code>.

      The set of functions which can "downcast" an error into a more concrete type is open.

      Functions

      -

      [method]error.to-debug-string: func

      +

      [method]error.to-debug-string: func

      Returns a string that is suitable to assist humans in debugging this error.

      WARNING: The returned string should not be consumed mechanically! @@ -102,92 +100,95 @@ details. Parsing this string is a major platform-compatibility hazard.

      Params
      Return values
        -
      • string
      • +
      • string
      -

      Import interface wasi:io/poll@0.2.0

      +

      Import interface wasi:io/poll@0.2.0

      A poll API intended to let users wait for I/O events on multiple handles at once.


      Types

      -

      resource pollable

      +

      resource pollable

      pollable represents a single I/O event which may be ready, or not.

      Functions

      -

      [method]pollable.ready: func

      +

      [method]pollable.ready: func

      Return the readiness of a pollable. This function never blocks.

      Returns true when the pollable is ready, and false otherwise.

      Params
      Return values
        -
      • bool
      • +
      • bool
      -

      [method]pollable.block: func

      +

      [method]pollable.block: func

      block returns immediately if the pollable is ready, and otherwise blocks until ready.

      This function is equivalent to calling poll.poll on a list containing only this pollable.

      Params
      -

      poll: func

      +

      poll: func

      Poll for completion on a set of pollables.

      This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

      The result list<u32> contains one or more indices of handles in the argument list that is ready for I/O.

      -

      If the list contains more elements than can be indexed with a u32 -value, this function traps.

      +

      This function traps if either:

      +
        +
      • the list is empty, or:
      • +
      • the list contains more elements than can be indexed with a u32 value.
      • +

      A timeout can be implemented by adding a pollable from the wasi-clocks API to the list.

      This function does not return a result; polling in itself does not do any I/O so it doesn't fail. If any of the I/O sources identified by the pollables has an error, it is indicated by marking the source as -being reaedy for I/O.

      +being ready for I/O.

      Params
      Return values
      • list<u32>
      -

      Import interface wasi:io/streams@0.2.0

      +

      Import interface wasi:io/streams@0.2.0

      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

      In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


      Types

      -

      type error

      +

      type error

      error

      -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

      -#### `variant stream-error` +#### `variant stream-error`

      An error for input-stream and output-stream operations.

      Variant Cases
      • -

        last-operation-failed: own<error>

        +

        last-operation-failed: own<error>

        The last operation (a write or flush) failed before completion.

        More information is available in the error payload.

      • -

        closed

        +

        closed

        The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

      -

      resource input-stream

      +

      resource input-stream

      An input bytestream.

      input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are @@ -195,7 +196,7 @@ promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

      -

      resource output-stream

      +

      resource output-stream

      An output bytestream.

      output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also @@ -204,7 +205,7 @@ promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

      Functions

      -

      [method]input-stream.read: func

      +

      [method]input-stream.read: func

      Perform a non-blocking read from the stream.

      When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -228,51 +229,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

      Params
      Return values
      -

      [method]input-stream.blocking-read: func

      +

      [method]input-stream.blocking-read: func

      Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

      Params
      Return values
      -

      [method]input-stream.skip: func

      +

      [method]input-stream.skip: func

      Skip bytes from a stream. Returns number of bytes skipped.

      Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

      Params
      Return values
      -

      [method]input-stream.blocking-skip: func

      +

      [method]input-stream.blocking-skip: func

      Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

      Params
      Return values
      -

      [method]input-stream.subscribe: func

      +

      [method]input-stream.subscribe: func

      Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -281,13 +282,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

      Params
      Return values
      -

      [method]output-stream.check-write: func

      +

      [method]output-stream.check-write: func

      Check readiness for writing. This function never blocks.

      Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -297,13 +298,13 @@ become ready when this function will report at least 1 byte, or an error.

      Params
      Return values
      -

      [method]output-stream.write: func

      +

      [method]output-stream.write: func

      Perform a write. This function never blocks.

      When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -316,14 +317,14 @@ length of less than or equal to n. Otherwise, this function will trap.

      the last call to check-write provided a permit.

      Params
      Return values
      -

      [method]output-stream.blocking-write-and-flush: func

      +

      [method]output-stream.blocking-write-and-flush: func

      Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

      This is a convenience wrapper around the use of check-write, @@ -347,14 +348,14 @@ let _ = this.check-write(); // eliding error handling

      Params
      Return values
      -

      [method]output-stream.flush: func

      +

      [method]output-stream.flush: func

      Request to flush buffered output. This function never blocks.

      This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -365,24 +366,24 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

      Params
      Return values
      -

      [method]output-stream.blocking-flush: func

      +

      [method]output-stream.blocking-flush: func

      Request to flush buffered output, and block until flush completes and stream is ready for writing again.

      Params
      Return values
      -

      [method]output-stream.subscribe: func

      +

      [method]output-stream.subscribe: func

      Create a pollable which will resolve once the output-stream is ready for more writing, or an error has occured. When this pollable is ready, check-write will return ok(n) with n>0, or an @@ -393,13 +394,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

      Params
      Return values
      -

      [method]output-stream.write-zeroes: func

      +

      [method]output-stream.write-zeroes: func

      Write zeroes to a stream.

      This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -407,14 +408,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

      Params
      Return values
      -

      [method]output-stream.blocking-write-zeroes-and-flush: func

      +

      [method]output-stream.blocking-write-zeroes-and-flush: func

      Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

      @@ -438,14 +439,14 @@ let _ = this.check-write(); // eliding error handling
      Params
      Return values
      -

      [method]output-stream.splice: func

      +

      [method]output-stream.splice: func

      Read from one stream and write to another.

      The behavior of splice is equivelant to:

        @@ -460,161 +461,160 @@ let _ = this.check-write(); // eliding error handling than len.

        Params
        Return values
        -

        [method]output-stream.blocking-splice: func

        +

        [method]output-stream.blocking-splice: func

        Read from one stream and write to another, with blocking.

        This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

        Params
        Return values
        -

        Import interface wasi:cli/stdin@0.2.0

        +

        Import interface wasi:cli/stdin@0.2.0


        Types

        -

        type input-stream

        +

        type input-stream

        input-stream

        ----

        Functions

        -

        get-stdin: func

        +

        get-stdin: func

        Return values
        -

        Import interface wasi:cli/stdout@0.2.0

        +

        Import interface wasi:cli/stdout@0.2.0


        Types

        -

        type output-stream

        +

        type output-stream

        output-stream

        ----

        Functions

        -

        get-stdout: func

        +

        get-stdout: func

        Return values
        -

        Import interface wasi:cli/stderr@0.2.0

        +

        Import interface wasi:cli/stderr@0.2.0


        Types

        -

        type output-stream

        +

        type output-stream

        output-stream

        ----

        Functions

        -

        get-stderr: func

        +

        get-stderr: func

        Return values
        -

        Import interface wasi:cli/terminal-input@0.2.0

        +

        Import interface wasi:cli/terminal-input@0.2.0

        Terminal input.

        In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through immediately, querying supported features, and so on.


        Types

        -

        resource terminal-input

        +

        resource terminal-input

        The input side of a terminal.

        -

        Import interface wasi:cli/terminal-output@0.2.0

        +

        Import interface wasi:cli/terminal-output@0.2.0

        Terminal output.

        In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported features, and so on.


        Types

        -

        resource terminal-output

        +

        resource terminal-output

        The output side of a terminal.

        -

        Import interface wasi:cli/terminal-stdin@0.2.0

        +

        Import interface wasi:cli/terminal-stdin@0.2.0

        An interface providing an optional terminal-input for stdin as a link-time authority.


        Types

        -

        type terminal-input

        +

        type terminal-input

        terminal-input

        ----

        Functions

        -

        get-terminal-stdin: func

        +

        get-terminal-stdin: func

        If stdin is connected to a terminal, return a terminal-input handle allowing further interaction with it.

        Return values
        -

        Import interface wasi:cli/terminal-stdout@0.2.0

        +

        Import interface wasi:cli/terminal-stdout@0.2.0

        An interface providing an optional terminal-output for stdout as a link-time authority.


        Types

        -

        type terminal-output

        +

        type terminal-output

        terminal-output

        ----

        Functions

        -

        get-terminal-stdout: func

        +

        get-terminal-stdout: func

        If stdout is connected to a terminal, return a terminal-output handle allowing further interaction with it.

        Return values
        -

        Import interface wasi:cli/terminal-stderr@0.2.0

        +

        Import interface wasi:cli/terminal-stderr@0.2.0

        An interface providing an optional terminal-output for stderr as a link-time authority.


        Types

        -

        type terminal-output

        +

        type terminal-output

        terminal-output

        ----

        Functions

        -

        get-terminal-stderr: func

        +

        get-terminal-stderr: func

        If stderr is connected to a terminal, return a terminal-output handle allowing further interaction with it.

        Return values
        -

        Import interface wasi:clocks/monotonic-clock@0.2.0

        +

        Import interface wasi:clocks/monotonic-clock@0.2.0

        WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

        It is intended to be portable at least between Unix-family platforms and Windows.

        A monotonic clock is a clock which has an unspecified initial value, and successive reads of the clock will produce non-decreasing values.

        -

        It is intended for measuring elapsed time.


        Types

        -

        type pollable

        +

        type pollable

        pollable

        -#### `type instant` +#### `type instant` `u64`

        An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. -

        type duration

        +

        type duration

        u64

        A duration of time, in nanoseconds.


        Functions

        -

        now: func

        +

        now: func

        Read the current value of the clock.

        The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

        @@ -622,37 +622,36 @@ produce a sequence of non-decreasing values.

        -

        resolution: func

        +

        resolution: func

        Query the resolution of the clock. Returns the duration of time corresponding to a clock tick.

        Return values
        -

        subscribe-instant: func

        +

        subscribe-instant: func

        Create a pollable which will resolve once the specified instant -occured.

        +has occured.

        Params
        Return values
        -

        subscribe-duration: func

        -

        Create a pollable which will resolve once the given duration has -elapsed, starting at the time at which this function was called. -occured.

        +

        subscribe-duration: func

        +

        Create a pollable that will resolve after the specified duration has +elapsed from the time this function is invoked.

        Params
        Return values
        -

        Import interface wasi:clocks/wall-clock@0.2.0

        +

        Import interface wasi:clocks/wall-clock@0.2.0

        WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

        @@ -665,16 +664,16 @@ monotonic, making it unsuitable for measuring elapsed time.

        It is intended for reporting the current date and time for humans.


        Types

        -

        record datetime

        +

        record datetime

        A time and date in seconds plus nanoseconds.

        Record Fields

        Functions

        -

        now: func

        +

        now: func

        Read the current value of the clock.

        This clock is not monotonic, therefore calling this function repeatedly will not necessarily produce a sequence of non-decreasing values.

        @@ -686,14 +685,14 @@ also known as Unix Time.
      1. datetime
    -

    resolution: func

    +

    resolution: func

    Query the resolution of the clock.

    The nanoseconds field of the output is always less than 1000000000.

    Return values
    -

    Import interface wasi:filesystem/types@0.2.0

    +

    Import interface wasi:filesystem/types@0.2.0

    WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

    @@ -713,75 +712,75 @@ underlying filesystem, the function fails with WASI filesystem path resolution.


    Types

    -

    type input-stream

    +

    type input-stream

    input-stream

    -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

    -#### `type error` +#### `type error` [`error`](#error)

    -#### `type datetime` +#### `type datetime` [`datetime`](#datetime)

    -#### `type filesize` +#### `type filesize` `u64`

    File size or length of a region within a file. -

    enum descriptor-type

    +

    enum descriptor-type

    The type of a filesystem object referenced by a descriptor.

    Note: This was called filetype in earlier versions of WASI.

    Enum Cases
    • -

      unknown

      +

      unknown

      The type of the descriptor or file is unknown or is different from any of the other types specified.

    • -

      block-device

      +

      block-device

      The descriptor refers to a block device inode.

    • -

      character-device

      +

      character-device

      The descriptor refers to a character device inode.

    • -

      directory

      +

      directory

      The descriptor refers to a directory inode.

    • -

      fifo

      +

      fifo

      The descriptor refers to a named pipe.

    • -

      symbolic-link

      +

      symbolic-link

      The file refers to a symbolic link inode.

    • -

      regular-file

      +

      regular-file

      The descriptor refers to a regular file inode.

    • -

      socket

      +

      socket

      The descriptor refers to a socket.

    -

    flags descriptor-flags

    +

    flags descriptor-flags

    Descriptor flags.

    Note: This was called fdflags in earlier versions of WASI.

    Flags members
    • -

      read:

      +

      read:

      Read mode: Data can be read.

    • -

      write:

      +

      write:

      Write mode: Data can be written to.

    • -

      file-integrity-sync:

      +

      file-integrity-sync:

      Request that writes be performed according to synchronized I/O file integrity completion. The data stored in the file and the file's metadata are synchronized. This is similar to `O_SYNC` in POSIX. @@ -790,7 +789,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

    • -

      data-integrity-sync:

      +

      data-integrity-sync:

      Request that writes be performed according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. This is similar to `O_DSYNC` in POSIX. @@ -799,7 +798,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

    • -

      requested-write-sync:

      +

      requested-write-sync:

      Requests that reads be performed at the same level of integrety requested for writes. This is similar to `O_RSYNC` in POSIX.

      The precise semantics of this operation have not yet been defined for @@ -807,7 +806,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

    • -

      mutate-directory:

      +

      mutate-directory:

      Mutating directories mode: Directory contents may be mutated.

      When this flag is unset on a descriptor, operations using the descriptor which would create, rename, delete, modify the data or @@ -817,107 +816,107 @@ they would otherwise succeed.

      This may only be set on directories.

    -

    flags path-flags

    +

    flags path-flags

    Flags determining the method of how paths are resolved.

    Flags members
      -
    • symlink-follow:

      As long as the resolved path corresponds to a symbolic link, it is +

    • symlink-follow:

      As long as the resolved path corresponds to a symbolic link, it is expanded.

    -

    flags open-flags

    +

    flags open-flags

    Open flags used by open-at.

    Flags members
    • -

      create:

      +

      create:

      Create file if it does not exist, similar to `O_CREAT` in POSIX.

    • -

      directory:

      +

      directory:

      Fail if not a directory, similar to `O_DIRECTORY` in POSIX.

    • -

      exclusive:

      +

      exclusive:

      Fail if file already exists, similar to `O_EXCL` in POSIX.

    • -

      truncate:

      +

      truncate:

      Truncate file to size 0, similar to `O_TRUNC` in POSIX.

    -

    type link-count

    +

    type link-count

    u64

    Number of hard links to an inode. -

    record descriptor-stat

    +

    record descriptor-stat

    File attributes.

    Note: This was called filestat in earlier versions of WASI.

    Record Fields
    -

    variant new-timestamp

    +

    variant new-timestamp

    When setting a timestamp, this gives the value to set it to.

    Variant Cases
    • -

      no-change

      +

      no-change

      Leave the timestamp set to its previous value.

    • -

      now

      +

      now

      Set the timestamp to the current time of the system clock associated with the filesystem.

    • -

      timestamp: datetime

      +

      timestamp: datetime

      Set the timestamp to the given value.

    -

    record directory-entry

    +

    record directory-entry

    A directory entry.

    Record Fields
    -

    enum error-code

    +

    enum error-code

    Error codes returned by functions, similar to errno in POSIX. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -925,211 +924,211 @@ merely for alignment with POSIX.

    Enum Cases
    • -

      access

      +

      access

      Permission denied, similar to `EACCES` in POSIX.

    • -

      would-block

      +

      would-block

      Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX.

    • -

      already

      +

      already

      Connection already in progress, similar to `EALREADY` in POSIX.

    • -

      bad-descriptor

      +

      bad-descriptor

      Bad descriptor, similar to `EBADF` in POSIX.

    • -

      busy

      +

      busy

      Device or resource busy, similar to `EBUSY` in POSIX.

    • -

      deadlock

      +

      deadlock

      Resource deadlock would occur, similar to `EDEADLK` in POSIX.

    • -

      quota

      +

      quota

      Storage quota exceeded, similar to `EDQUOT` in POSIX.

    • -

      exist

      +

      exist

      File exists, similar to `EEXIST` in POSIX.

    • -

      file-too-large

      +

      file-too-large

      File too large, similar to `EFBIG` in POSIX.

    • -

      illegal-byte-sequence

      +

      illegal-byte-sequence

      Illegal byte sequence, similar to `EILSEQ` in POSIX.

    • -

      in-progress

      +

      in-progress

      Operation in progress, similar to `EINPROGRESS` in POSIX.

    • -

      interrupted

      +

      interrupted

      Interrupted function, similar to `EINTR` in POSIX.

    • -

      invalid

      +

      invalid

      Invalid argument, similar to `EINVAL` in POSIX.

    • -

      io

      +

      io

      I/O error, similar to `EIO` in POSIX.

    • -

      is-directory

      +

      is-directory

      Is a directory, similar to `EISDIR` in POSIX.

    • -

      loop

      +

      loop

      Too many levels of symbolic links, similar to `ELOOP` in POSIX.

    • -

      too-many-links

      +

      too-many-links

      Too many links, similar to `EMLINK` in POSIX.

    • -

      message-size

      +

      message-size

      Message too large, similar to `EMSGSIZE` in POSIX.

    • -

      name-too-long

      +

      name-too-long

      Filename too long, similar to `ENAMETOOLONG` in POSIX.

    • -

      no-device

      +

      no-device

      No such device, similar to `ENODEV` in POSIX.

    • -

      no-entry

      +

      no-entry

      No such file or directory, similar to `ENOENT` in POSIX.

    • -

      no-lock

      +

      no-lock

      No locks available, similar to `ENOLCK` in POSIX.

    • -

      insufficient-memory

      +

      insufficient-memory

      Not enough space, similar to `ENOMEM` in POSIX.

    • -

      insufficient-space

      +

      insufficient-space

      No space left on device, similar to `ENOSPC` in POSIX.

    • -

      not-directory

      +

      not-directory

      Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX.

    • -

      not-empty

      +

      not-empty

      Directory not empty, similar to `ENOTEMPTY` in POSIX.

    • -

      not-recoverable

      +

      not-recoverable

      State not recoverable, similar to `ENOTRECOVERABLE` in POSIX.

    • -

      unsupported

      +

      unsupported

      Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX.

    • -

      no-tty

      +

      no-tty

      Inappropriate I/O control operation, similar to `ENOTTY` in POSIX.

    • -

      no-such-device

      +

      no-such-device

      No such device or address, similar to `ENXIO` in POSIX.

    • -

      overflow

      +

      overflow

      Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX.

    • -

      not-permitted

      +

      not-permitted

      Operation not permitted, similar to `EPERM` in POSIX.

    • -

      pipe

      +

      pipe

      Broken pipe, similar to `EPIPE` in POSIX.

    • -

      read-only

      +

      read-only

      Read-only file system, similar to `EROFS` in POSIX.

    • -

      invalid-seek

      +

      invalid-seek

      Invalid seek, similar to `ESPIPE` in POSIX.

    • -

      text-file-busy

      +

      text-file-busy

      Text file busy, similar to `ETXTBSY` in POSIX.

    • -

      cross-device

      +

      cross-device

      Cross-device link, similar to `EXDEV` in POSIX.

    -

    enum advice

    +

    enum advice

    File or memory access pattern advisory information.

    Enum Cases
    • -

      normal

      +

      normal

      The application has no advice to give on its behavior with respect to the specified data.

    • -

      sequential

      +

      sequential

      The application expects to access the specified data sequentially from lower offsets to higher offsets.

    • -

      random

      +

      random

      The application expects to access the specified data in a random order.

    • -

      will-need

      +

      will-need

      The application expects to access the specified data in the near future.

    • -

      dont-need

      +

      dont-need

      The application expects that it will not access the specified data in the near future.

    • -

      no-reuse

      +

      no-reuse

      The application expects to access the specified data once and then not reuse it thereafter.

    -

    record metadata-hash-value

    +

    record metadata-hash-value

    A 128-bit hash value, split into parts because wasm doesn't have a 128-bit integer type.

    Record Fields
    • -

      lower: u64

      +

      lower: u64

      64 bits of a 128-bit hash value.

    • -

      upper: u64

      +

      upper: u64

      Another 64 bits of a 128-bit hash value.

    -

    resource descriptor

    +

    resource descriptor

    A descriptor is a reference to a filesystem object, which may be a file, directory, named pipe, special file, or other object on which filesystem calls may be made.

    -

    resource directory-entry-stream

    +

    resource directory-entry-stream

    A stream of directory entries.

    Functions

    -

    [method]descriptor.read-via-stream: func

    +

    [method]descriptor.read-via-stream: func

    Return a stream for reading from a file, if available.

    May fail with an error-code describing why the file cannot be read.

    Multiple read, write, and append streams may be active on the same open @@ -1137,81 +1136,81 @@ file and they do not interfere with each other.

    Note: This allows using read-stream, which is similar to read in POSIX.

    Params
    Return values
    -

    [method]descriptor.write-via-stream: func

    +

    [method]descriptor.write-via-stream: func

    Return a stream for writing to a file, if available.

    May fail with an error-code describing why the file cannot be written.

    Note: This allows using write-stream, which is similar to write in POSIX.

    Params
    Return values
    -

    [method]descriptor.append-via-stream: func

    +

    [method]descriptor.append-via-stream: func

    Return a stream for appending to a file, if available.

    May fail with an error-code describing why the file cannot be appended.

    Note: This allows using write-stream, which is similar to write with O_APPEND in in POSIX.

    Params
    Return values
    -

    [method]descriptor.advise: func

    +

    [method]descriptor.advise: func

    Provide file advisory information on a descriptor.

    This is similar to posix_fadvise in POSIX.

    Params
    Return values
    -

    [method]descriptor.sync-data: func

    +

    [method]descriptor.sync-data: func

    Synchronize the data of a file to disk.

    This function succeeds with no effect if the file descriptor is not opened for writing.

    Note: This is similar to fdatasync in POSIX.

    Params
    Return values
    -

    [method]descriptor.get-flags: func

    +

    [method]descriptor.get-flags: func

    Get flags associated with a descriptor.

    Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

    Note: This returns the value that was the fs_flags value returned from fdstat_get in earlier versions of WASI.

    Params
    Return values
    -

    [method]descriptor.get-type: func

    +

    [method]descriptor.get-type: func

    Get the dynamic type of a descriptor.

    Note: This returns the same value as the type field of the fd-stat returned by stat, stat-at and similar.

    @@ -1221,40 +1220,40 @@ by fstat in POSIX.

    from fdstat_get in earlier versions of WASI.

    Params
    Return values
    -

    [method]descriptor.set-size: func

    +

    [method]descriptor.set-size: func

    Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.

    Note: This was called fd_filestat_set_size in earlier versions of WASI.

    Params
    Return values
    -

    [method]descriptor.set-times: func

    +

    [method]descriptor.set-times: func

    Adjust the timestamps of an open file or directory.

    Note: This is similar to futimens in POSIX.

    Note: This was called fd_filestat_set_times in earlier versions of WASI.

    Params
    Return values
    -

    [method]descriptor.read: func

    +

    [method]descriptor.read: func

    Read from a descriptor, without using and updating the descriptor's offset.

    This function returns a list of bytes containing the data that was read, along with a bool which, when true, indicates that the end of the @@ -1265,15 +1264,15 @@ if the I/O operation is interrupted.

    Note: This is similar to pread in POSIX.

    Params
    Return values
    -

    [method]descriptor.write: func

    +

    [method]descriptor.write: func

    Write to a descriptor, without using and updating the descriptor's offset.

    It is valid to write past the end of a file; the file is extended to the extent of the write, with bytes between the previous end and the start of @@ -1282,15 +1281,15 @@ the write set to zero.

    Note: This is similar to pwrite in POSIX.

    Params
    Return values
    -

    [method]descriptor.read-directory: func

    +

    [method]descriptor.read-directory: func

    Read directory entries from a directory.

    On filesystems where directories contain entries referring to themselves and their parents, often named . and .. respectively, these entries @@ -1300,38 +1299,38 @@ directory. Multiple streams may be active on the same directory, and they do not interfere with each other.

    Params
    Return values
    -

    [method]descriptor.sync: func

    +

    [method]descriptor.sync: func

    Synchronize the data and metadata of a file to disk.

    This function succeeds with no effect if the file descriptor is not opened for writing.

    Note: This is similar to fsync in POSIX.

    Params
    Return values
    -

    [method]descriptor.create-directory-at: func

    +

    [method]descriptor.create-directory-at: func

    Create a directory.

    Note: This is similar to mkdirat in POSIX.

    Params
    Return values
    -

    [method]descriptor.stat: func

    +

    [method]descriptor.stat: func

    Return the attributes of an open file or directory.

    Note: This is similar to fstat in POSIX, except that it does not return device and inode information. For testing whether two descriptors refer to @@ -1341,13 +1340,13 @@ modified, use metadata-hash.

    Note: This was called fd_filestat_get in earlier versions of WASI.

    Params
    Return values
    -

    [method]descriptor.stat-at: func

    +

    [method]descriptor.stat-at: func

    Return the attributes of a file or directory.

    Note: This is similar to fstatat in POSIX, except that it does not return device and inode information. See the stat description for a @@ -1355,47 +1354,47 @@ discussion of alternatives.

    Note: This was called path_filestat_get in earlier versions of WASI.

    Params
    Return values
    -

    [method]descriptor.set-times-at: func

    +

    [method]descriptor.set-times-at: func

    Adjust the timestamps of a file or directory.

    Note: This is similar to utimensat in POSIX.

    Note: This was called path_filestat_set_times in earlier versions of WASI.

    Params
    Return values
    -

    [method]descriptor.link-at: func

    +

    [method]descriptor.link-at: func

    Create a hard link.

    Note: This is similar to linkat in POSIX.

    Params
    Return values
    -

    [method]descriptor.open-at: func

    +

    [method]descriptor.open-at: func

    Open a file or directory.

    The returned descriptor is not guaranteed to be the lowest-numbered descriptor not currently open/ it is randomized to prevent applications @@ -1412,86 +1411,86 @@ contains truncate or create, and the base descriptor d

    Note: This is similar to openat in POSIX.

    Params
    Return values
    -

    [method]descriptor.readlink-at: func

    +

    [method]descriptor.readlink-at: func

    Read the contents of a symbolic link.

    If the contents contain an absolute or rooted path in the underlying filesystem, this function fails with error-code::not-permitted.

    Note: This is similar to readlinkat in POSIX.

    Params
    Return values
    -

    [method]descriptor.remove-directory-at: func

    +

    [method]descriptor.remove-directory-at: func

    Remove a directory.

    Return error-code::not-empty if the directory is not empty.

    Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

    Params
    Return values
    -

    [method]descriptor.rename-at: func

    +

    [method]descriptor.rename-at: func

    Rename a filesystem object.

    Note: This is similar to renameat in POSIX.

    Params
    Return values
    -

    [method]descriptor.symlink-at: func

    +

    [method]descriptor.symlink-at: func

    Create a symbolic link (also known as a "symlink").

    If old-path starts with /, the function fails with error-code::not-permitted.

    Note: This is similar to symlinkat in POSIX.

    Params
    Return values
    -

    [method]descriptor.unlink-file-at: func

    +

    [method]descriptor.unlink-file-at: func

    Unlink a filesystem object that is not a directory.

    Return error-code::is-directory if the path refers to a directory. Note: This is similar to unlinkat(fd, path, 0) in POSIX.

    Params
    Return values
    -

    [method]descriptor.is-same-object: func

    +

    [method]descriptor.is-same-object: func

    Test whether two descriptors refer to the same filesystem object.

    In POSIX, this corresponds to testing whether the two descriptors have the same device (st_dev) and inode (st_ino or d_ino) numbers. @@ -1499,14 +1498,14 @@ wasi-filesystem does not expose device and inode numbers, so this function may be used instead.

    Params
    Return values
      -
    • bool
    • +
    • bool
    -

    [method]descriptor.metadata-hash: func

    +

    [method]descriptor.metadata-hash: func

    Return a hash of the metadata associated with a filesystem object referred to by a descriptor.

    This returns a hash of the last-modification timestamp and file size, and @@ -1526,37 +1525,37 @@ computed hash.

    However, none of these is required.

    Params
    Return values
    -

    [method]descriptor.metadata-hash-at: func

    +

    [method]descriptor.metadata-hash-at: func

    Return a hash of the metadata associated with a filesystem object referred to by a directory descriptor and a relative path.

    This performs the same hash computation as metadata-hash.

    Params
    Return values
    -

    [method]directory-entry-stream.read-directory-entry: func

    +

    [method]directory-entry-stream.read-directory-entry: func

    Read a single directory entry from a directory-entry-stream.

    Params
    Return values
    -

    filesystem-error-code: func

    +

    filesystem-error-code: func

    Attempts to extract a filesystem-related error-code from the stream error provided.

    Stream operations which return stream-error::last-operation-failed @@ -1567,34 +1566,34 @@ filesystem-related information about the error to return.

    errors are filesystem-related errors.

    Params
    Return values
    -

    Import interface wasi:filesystem/preopens@0.2.0

    +

    Import interface wasi:filesystem/preopens@0.2.0


    Types

    -

    type descriptor

    +

    type descriptor

    descriptor

    ----

    Functions

    -

    get-directories: func

    +

    get-directories: func

    Return the set of preopened directories, and their path.

    Return values
    -

    Import interface wasi:sockets/network@0.2.0

    +

    Import interface wasi:sockets/network@0.2.0


    Types

    -

    resource network

    +

    resource network

    An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

    -

    enum error-code

    +

    enum error-code

    Error codes.

    In theory, every API can return any error code. In practice, API's typically only return the errors documented per API @@ -1610,235 +1609,235 @@ combined with a couple of errors that are always possible:

    Enum Cases
    • -

      unknown

      +

      unknown

      Unknown error

    • -

      access-denied

      +

      access-denied

      Access denied.

      POSIX equivalent: EACCES, EPERM

    • -

      not-supported

      +

      not-supported

      The operation is not supported.

      POSIX equivalent: EOPNOTSUPP

    • -

      invalid-argument

      +

      invalid-argument

      One of the arguments is invalid.

      POSIX equivalent: EINVAL

    • -

      out-of-memory

      +

      out-of-memory

      Not enough memory to complete the operation.

      POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY

    • -

      timeout

      +

      timeout

      The operation timed out before it could finish completely.

    • -

      concurrency-conflict

      +

      concurrency-conflict

      This operation is incompatible with another asynchronous operation that is already in progress.

      POSIX equivalent: EALREADY

    • -

      not-in-progress

      +

      not-in-progress

      Trying to finish an asynchronous operation that: - has not been started yet, or: - was already finished by a previous `finish-*` call.

      Note: this is scheduled to be removed when futures are natively supported.

    • -

      would-block

      +

      would-block

      The operation has been aborted because it could not be completed immediately.

      Note: this is scheduled to be removed when futures are natively supported.

    • -

      invalid-state

      +

      invalid-state

      The operation is not valid in the socket's current state.

    • -

      new-socket-limit

      +

      new-socket-limit

      A new socket resource could not be created because of a system limit.

    • -

      address-not-bindable

      +

      address-not-bindable

      A bind operation failed because the provided address is not an address that the `network` can bind to.

    • -

      address-in-use

      +

      address-in-use

      A bind operation failed because the provided address is already in use or because there are no ephemeral ports available.

    • -

      remote-unreachable

      +

      remote-unreachable

      The remote address is not reachable

    • -

      connection-refused

      +

      connection-refused

      The TCP connection was forcefully rejected

    • -

      connection-reset

      +

      connection-reset

      The TCP connection was reset.

    • -

      connection-aborted

      +

      connection-aborted

      A TCP connection was aborted.

    • -

      datagram-too-large

      +

      datagram-too-large

      The size of a datagram sent to a UDP socket exceeded the maximum supported size.

    • -

      name-unresolvable

      +

      name-unresolvable

      Name does not exist or has no suitable associated IP addresses.

    • -

      temporary-resolver-failure

      +

      temporary-resolver-failure

      A temporary failure in name resolution occurred.

    • -

      permanent-resolver-failure

      +

      permanent-resolver-failure

      A permanent failure in name resolution occurred.

    -

    enum ip-address-family

    +

    enum ip-address-family

    Enum Cases
    • -

      ipv4

      +

      ipv4

      Similar to `AF_INET` in POSIX.

    • -

      ipv6

      +

      ipv6

      Similar to `AF_INET6` in POSIX.

    -

    tuple ipv4-address

    +

    tuple ipv4-address

    Tuple Fields
      -
    • 0: u8
    • -
    • 1: u8
    • -
    • 2: u8
    • -
    • 3: u8
    • +
    • 0: u8
    • +
    • 1: u8
    • +
    • 2: u8
    • +
    • 3: u8
    -

    tuple ipv6-address

    +

    tuple ipv6-address

    Tuple Fields
      -
    • 0: u16
    • -
    • 1: u16
    • -
    • 2: u16
    • -
    • 3: u16
    • -
    • 4: u16
    • -
    • 5: u16
    • -
    • 6: u16
    • -
    • 7: u16
    • +
    • 0: u16
    • +
    • 1: u16
    • +
    • 2: u16
    • +
    • 3: u16
    • +
    • 4: u16
    • +
    • 5: u16
    • +
    • 6: u16
    • +
    • 7: u16
    -

    variant ip-address

    +

    variant ip-address

    Variant Cases
    -

    record ipv4-socket-address

    +

    record ipv4-socket-address

    Record Fields
    -

    record ipv6-socket-address

    +

    record ipv6-socket-address

    Record Fields
    -

    variant ip-socket-address

    +

    variant ip-socket-address

    Variant Cases
    -

    Import interface wasi:sockets/instance-network@0.2.0

    +

    Import interface wasi:sockets/instance-network@0.2.0

    This interface provides a value-export of the default network handle..


    Types

    -

    type network

    +

    type network

    network

    ----

    Functions

    -

    instance-network: func

    +

    instance-network: func

    Get a handle to the default network.

    Return values
    -

    Import interface wasi:sockets/udp@0.2.0

    +

    Import interface wasi:sockets/udp@0.2.0


    Types

    -

    type pollable

    +

    type pollable

    pollable

    -#### `type network` +#### `type network` [`network`](#network)

    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

    -#### `type ip-socket-address` +#### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address)

    -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `record incoming-datagram` +#### `record incoming-datagram`

    A received datagram.

    Record Fields
    • -

      data: list<u8>

      +

      data: list<u8>

      The payload.

      Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes.

    • -

      remote-address: ip-socket-address

      +

      remote-address: ip-socket-address

      The source address.

      This field is guaranteed to match the remote address the stream was initialized with, if any.

      Equivalent to the src_addr out parameter of recvfrom.

    -

    record outgoing-datagram

    +

    record outgoing-datagram

    A datagram to be sent out.

    Record Fields
    • -

      data: list<u8>

      +

      data: list<u8>

      The payload.

    • -

      remote-address: option<ip-socket-address>

      +

      remote-address: option<ip-socket-address>

      The destination address.

      The requirements on this field depend on how the stream was initialized:

        @@ -1848,13 +1847,13 @@ supported size.

        If this value is None, the send operation is equivalent to send in POSIX. Otherwise it is equivalent to sendto.

      -

      resource udp-socket

      +

      resource udp-socket

      A UDP socket handle.

      -

      resource incoming-datagram-stream

      -

      resource outgoing-datagram-stream

      +

      resource incoming-datagram-stream

      +

      resource outgoing-datagram-stream


      Functions

      -

      [method]udp-socket.start-bind: func

      +

      [method]udp-socket.start-bind: func

      Bind the socket to a specific network on the provided IP address and port.

      If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -1883,24 +1882,24 @@ don't want to make use of this ability can simply call the native

    Params
    Return values
    -

    [method]udp-socket.finish-bind: func

    +

    [method]udp-socket.finish-bind: func

    Params
    Return values
    -

    [method]udp-socket.stream: func

    +

    [method]udp-socket.stream: func

    Set up inbound & outbound communication channels, optionally to a specific peer.

    This function only changes the local socket configuration and does not generate any network traffic. On success, the remote-address of the socket is updated. The local-address may be updated as well, @@ -1941,14 +1940,14 @@ if (remote_address is Some) {

    Params
    Return values
    -

    [method]udp-socket.local-address: func

    +

    [method]udp-socket.local-address: func

    Get the current bound address.

    POSIX mentions:

    @@ -1969,13 +1968,13 @@ stored in the object pointed to by address is unspecified.

    Params
    Return values
    -

    [method]udp-socket.remote-address: func

    +

    [method]udp-socket.remote-address: func

    Get the address the socket is currently streaming to.

    Typical errors

      @@ -1990,24 +1989,24 @@ stored in the object pointed to by address is unspecified.

    Params
    Return values
    -

    [method]udp-socket.address-family: func

    +

    [method]udp-socket.address-family: func

    Whether this is a IPv4 or IPv6 socket.

    Equivalent to the SO_DOMAIN socket option.

    Params
    Return values
    -

    [method]udp-socket.unicast-hop-limit: func

    +

    [method]udp-socket.unicast-hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    If the provided value is 0, an invalid-argument error is returned.

    Typical errors

    @@ -2016,23 +2015,23 @@ stored in the object pointed to by address is unspecified.

    Params
    Return values
    -

    [method]udp-socket.set-unicast-hop-limit: func

    +

    [method]udp-socket.set-unicast-hop-limit: func

    Params
    Return values
    -

    [method]udp-socket.receive-buffer-size: func

    +

    [method]udp-socket.receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2044,54 +2043,54 @@ I.e. after setting a value, reading the same setting back may return a different

    Params
    Return values
    -

    [method]udp-socket.set-receive-buffer-size: func

    +

    [method]udp-socket.set-receive-buffer-size: func

    Params
    Return values
    -

    [method]udp-socket.send-buffer-size: func

    +

    [method]udp-socket.send-buffer-size: func

    Params
    Return values
    -

    [method]udp-socket.set-send-buffer-size: func

    +

    [method]udp-socket.set-send-buffer-size: func

    Params
    Return values
    -

    [method]udp-socket.subscribe: func

    +

    [method]udp-socket.subscribe: func

    Create a pollable which will resolve once the socket is ready for I/O.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    [method]incoming-datagram-stream.receive: func

    +

    [method]incoming-datagram-stream.receive: func

    Receive messages on the socket.

    This function attempts to receive up to max-results datagrams on the socket without blocking. The returned list may contain fewer elements than requested, but never more.

    @@ -2119,26 +2118,26 @@ This function never returns error(would-block).
    Params
    Return values
    -

    [method]incoming-datagram-stream.subscribe: func

    +

    [method]incoming-datagram-stream.subscribe: func

    Create a pollable which will resolve once the stream is ready to receive again.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    [method]outgoing-datagram-stream.check-send: func

    +

    [method]outgoing-datagram-stream.check-send: func

    Check readiness for sending. This function never blocks.

    Returns the number of datagrams permitted for the next call to send, or an error. Calling send with more datagrams than this function has @@ -2149,13 +2148,13 @@ error.

    Never returns would-block.

    Params
    Return values
    -

    [method]outgoing-datagram-stream.send: func

    +

    [method]outgoing-datagram-stream.send: func

    Send messages on the socket.

    This function attempts to send all provided datagrams on the socket without blocking and returns how many messages were actually sent (or queued for sending). This function never @@ -2190,43 +2189,43 @@ either check-send was not called or datagrams contains

    Params
    Return values
    -

    [method]outgoing-datagram-stream.subscribe: func

    +

    [method]outgoing-datagram-stream.subscribe: func

    Create a pollable which will resolve once the stream is ready to send again.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    Import interface wasi:sockets/udp-create-socket@0.2.0

    +

    Import interface wasi:sockets/udp-create-socket@0.2.0


    Types

    -

    type network

    +

    type network

    network

    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

    -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `type udp-socket` +#### `type udp-socket` [`udp-socket`](#udp_socket)

    ----

    Functions

    -

    create-udp-socket: func

    +

    create-udp-socket: func

    Create a new UDP socket.

    Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX. On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

    @@ -2248,56 +2247,56 @@ the socket is effectively an in-memory configuration object, unable to communica
    Params
    Return values
    -

    Import interface wasi:sockets/tcp@0.2.0

    +

    Import interface wasi:sockets/tcp@0.2.0


    Types

    -

    type input-stream

    +

    type input-stream

    input-stream

    -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

    -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

    -#### `type duration` +#### `type duration` [`duration`](#duration)

    -#### `type network` +#### `type network` [`network`](#network)

    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

    -#### `type ip-socket-address` +#### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address)

    -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `enum shutdown-type` +#### `enum shutdown-type`

    Enum Cases
    • -

      receive

      +

      receive

      Similar to `SHUT_RD` in POSIX.

    • -

      send

      +

      send

      Similar to `SHUT_WR` in POSIX.

    • -

      both

      +

      both

      Similar to `SHUT_RDWR` in POSIX.

    -

    resource tcp-socket

    +

    resource tcp-socket

    A TCP socket resource.

    The socket can be in one of the following states:

    Note: Except where explicitly mentioned, whenever this documentation uses the term "bound" without backticks it actually means: in the bound state or higher. @@ -2319,7 +2318,7 @@ the term "bound" without backticks it actually means: in the bou network::error-code type, TCP socket methods may always return error(invalid-state) when in the closed state.

    Functions

    -

    [method]tcp-socket.start-bind: func

    +

    [method]tcp-socket.start-bind: func

    Bind the socket to a specific network on the provided IP address and port.

    If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -2358,28 +2357,28 @@ don't want to make use of this ability can simply call the native

    Params
    Return values
    -

    [method]tcp-socket.finish-bind: func

    +

    [method]tcp-socket.finish-bind: func

    Params
    Return values
    -

    [method]tcp-socket.start-connect: func

    +

    [method]tcp-socket.start-connect: func

    Connect to a remote endpoint.

    On success:

      -
    • the socket is transitioned into the connection state.
    • +
    • the socket is transitioned into the connected state.
    • a pair of streams is returned that can be used to read & write to the connection

    After a failed connection attempt, the socket will be in the closed @@ -2420,24 +2419,24 @@ the SO_ERROR socket option, in case the poll signaled readiness.

    Params
    Return values
    -

    [method]tcp-socket.finish-connect: func

    +

    [method]tcp-socket.finish-connect: func

    Params
    Return values
    -

    [method]tcp-socket.start-listen: func

    +

    [method]tcp-socket.start-listen: func

    Start listening for new connections.

    Transitions the socket into the listening state.

    Unlike POSIX, the socket must already be explicitly bound.

    @@ -2464,22 +2463,22 @@ don't want to make use of this ability can simply call the native
    Params
    Return values
    -

    [method]tcp-socket.finish-listen: func

    +

    [method]tcp-socket.finish-listen: func

    Params
    Return values
    -

    [method]tcp-socket.accept: func

    +

    [method]tcp-socket.accept: func

    Accept a new client socket.

    The returned socket is bound and in the connected state. The following properties are inherited from the listener socket:

      @@ -2510,13 +2509,13 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    [method]tcp-socket.local-address: func

    +

    [method]tcp-socket.local-address: func

    Get the bound local address.

    POSIX mentions:

    @@ -2537,13 +2536,13 @@ stored in the object pointed to by address is unspecified.

    Params
    Return values
    -

    [method]tcp-socket.remote-address: func

    +

    [method]tcp-socket.remote-address: func

    Get the remote address.

    Typical errors

      @@ -2558,35 +2557,35 @@ stored in the object pointed to by address is unspecified.

    Params
    Return values
    -

    [method]tcp-socket.is-listening: func

    +

    [method]tcp-socket.is-listening: func

    Whether the socket is in the listening state.

    Equivalent to the SO_ACCEPTCONN socket option.

    Params
    Return values
      -
    • bool
    • +
    • bool
    -

    [method]tcp-socket.address-family: func

    +

    [method]tcp-socket.address-family: func

    Whether this is a IPv4 or IPv6 socket.

    Equivalent to the SO_DOMAIN socket option.

    Params
    Return values
    -

    [method]tcp-socket.set-listen-backlog-size: func

    +

    [method]tcp-socket.set-listen-backlog-size: func

    Hints the desired listen queue size. Implementations are free to ignore this.

    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded.

    @@ -2598,14 +2597,14 @@ Any other value will never cause an error, but it might be silently clamped and/
    Params
    Return values
    -

    [method]tcp-socket.keep-alive-enabled: func

    +

    [method]tcp-socket.keep-alive-enabled: func

    Enables or disables keepalive.

    The keepalive behavior can be adjusted using:

      @@ -2617,23 +2616,23 @@ These properties can be configured while keep-alive-enabled is fals

      Equivalent to the SO_KEEPALIVE socket option.

      Params
      Return values
      -

      [method]tcp-socket.set-keep-alive-enabled: func

      +

      [method]tcp-socket.set-keep-alive-enabled: func

      Params
      Return values
      -

      [method]tcp-socket.keep-alive-idle-time: func

      +

      [method]tcp-socket.keep-alive-idle-time: func

      Amount of time the connection has to be idle before TCP starts sending keepalive packets.

      If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2645,23 +2644,23 @@ I.e. after setting a value, reading the same setting back may return a different

    Params
    Return values
    -

    [method]tcp-socket.set-keep-alive-idle-time: func

    +

    [method]tcp-socket.set-keep-alive-idle-time: func

    Params
    Return values
    -

    [method]tcp-socket.keep-alive-interval: func

    +

    [method]tcp-socket.keep-alive-interval: func

    The time between keepalive packets.

    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2673,23 +2672,23 @@ I.e. after setting a value, reading the same setting back may return a different

    Params
    Return values
    -

    [method]tcp-socket.set-keep-alive-interval: func

    +

    [method]tcp-socket.set-keep-alive-interval: func

    Params
    Return values
    -

    [method]tcp-socket.keep-alive-count: func

    +

    [method]tcp-socket.keep-alive-count: func

    The maximum amount of keepalive packets TCP should send before aborting the connection.

    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2701,23 +2700,23 @@ I.e. after setting a value, reading the same setting back may return a different

    Params
    Return values
    -

    [method]tcp-socket.set-keep-alive-count: func

    +

    [method]tcp-socket.set-keep-alive-count: func

    Params
    Return values
    -

    [method]tcp-socket.hop-limit: func

    +

    [method]tcp-socket.hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    If the provided value is 0, an invalid-argument error is returned.

    Typical errors

    @@ -2726,23 +2725,23 @@ I.e. after setting a value, reading the same setting back may return a different
    Params
    Return values
    -

    [method]tcp-socket.set-hop-limit: func

    +

    [method]tcp-socket.set-hop-limit: func

    Params
    Return values
    -

    [method]tcp-socket.receive-buffer-size: func

    +

    [method]tcp-socket.receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2754,42 +2753,42 @@ I.e. after setting a value, reading the same setting back may return a different

    Params
    Return values
    -

    [method]tcp-socket.set-receive-buffer-size: func

    +

    [method]tcp-socket.set-receive-buffer-size: func

    Params
    Return values
    -

    [method]tcp-socket.send-buffer-size: func

    +

    [method]tcp-socket.send-buffer-size: func

    Params
    Return values
    -

    [method]tcp-socket.set-send-buffer-size: func

    +

    [method]tcp-socket.set-send-buffer-size: func

    Params
    Return values
    -

    [method]tcp-socket.subscribe: func

    +

    [method]tcp-socket.subscribe: func

    Create a pollable which can be used to poll for, or block on, completion of any of the asynchronous operations of this socket.

    When finish-bind, finish-listen, finish-connect or accept @@ -2799,19 +2798,19 @@ their success or failure, after which the method can be retried.

    in progress at the time of calling subscribe (if any). Theoretically, subscribe only has to be called once per socket and can then be (re)used for the remainder of the socket's lifetime.

    -

    See https://github.com/WebAssembly/wasi-sockets/TcpSocketOperationalSemantics.md#Pollable-readiness -for a more information.

    +

    See https://github.com/WebAssembly/wasi-sockets/blob/main/TcpSocketOperationalSemantics.md#pollable-readiness +for more information.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    [method]tcp-socket.shutdown: func

    +

    [method]tcp-socket.shutdown: func

    Initiate a graceful shutdown.

    • receive: The socket is not expecting to receive any data from @@ -2822,7 +2821,7 @@ this method will be discarded.
    • associated with this socket will be closed and a FIN packet will be sent.
    • both: Same effect as receive & send combined.
    -

    This function is idempotent. Shutting a down a direction more than once +

    This function is idempotent; shutting down a direction more than once has no effect and returns ok.

    The shutdown function does not close (drop) the socket.

    Typical errors

    @@ -2838,31 +2837,31 @@ has no effect and returns ok.

    Params
    Return values
    -

    Import interface wasi:sockets/tcp-create-socket@0.2.0

    +

    Import interface wasi:sockets/tcp-create-socket@0.2.0


    Types

    -

    type network

    +

    type network

    network

    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

    -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `type tcp-socket` +#### `type tcp-socket` [`tcp-socket`](#tcp_socket)

    ----

    Functions

    -

    create-tcp-socket: func

    +

    create-tcp-socket: func

    Create a new TCP socket.

    Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX. On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

    @@ -2884,31 +2883,31 @@ is called, the socket is effectively an in-memory configuration object, unable t
    Params
    Return values
    -

    Import interface wasi:sockets/ip-name-lookup@0.2.0

    +

    Import interface wasi:sockets/ip-name-lookup@0.2.0


    Types

    -

    type pollable

    +

    type pollable

    pollable

    -#### `type network` +#### `type network` [`network`](#network)

    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

    -#### `type ip-address` +#### `type ip-address` [`ip-address`](#ip_address)

    -#### `resource resolve-address-stream` +#### `resource resolve-address-stream`


    Functions

    -

    resolve-addresses: func

    +

    resolve-addresses: func

    Resolve an internet host name to a list of IP addresses.

    Unicode domain names are automatically converted to ASCII using IDNA encoding. If the input is an IP address string, the address is parsed and returned @@ -2930,14 +2929,14 @@ to (asynchronously) fetch the results.

    Params
    Return values
    -

    [method]resolve-address-stream.resolve-next-address: func

    +

    [method]resolve-address-stream.resolve-next-address: func

    Returns the next address from the resolver.

    This function should be called multiple times. On each call, it will return the next address in connection order preference. If all @@ -2952,31 +2951,31 @@ addresses have been exhausted, this function returns none.

    Params
    Return values
    -

    [method]resolve-address-stream.subscribe: func

    +

    [method]resolve-address-stream.subscribe: func

    Create a pollable which will resolve once the stream is ready for I/O.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    Import interface wasi:random/random@0.2.0

    +

    Import interface wasi:random/random@0.2.0

    WASI Random is a random data API.

    It is intended to be portable at least between Unix-family platforms and Windows.


    Functions

    -

    get-random-bytes: func

    +

    get-random-bytes: func

    Return len cryptographically-secure random or pseudo-random bytes.

    This function must produce data at least as cryptographically secure and fast as an adequately seeded cryptographically-secure pseudo-random @@ -2989,13 +2988,13 @@ must omit this function, rather than implementing it with deterministic data.

    Params
      -
    • len: u64
    • +
    • len: u64
    Return values
    • list<u8>
    -

    get-random-u64: func

    +

    get-random-u64: func

    Return a cryptographically-secure random or pseudo-random u64 value.

    This function returns the same type of data as get-random-bytes, represented as a u64.

    @@ -3003,13 +3002,13 @@ represented as a u64.

    • u64
    -

    Import interface wasi:random/insecure@0.2.0

    +

    Import interface wasi:random/insecure@0.2.0

    The insecure interface for insecure pseudo-random numbers.

    It is intended to be portable at least between Unix-family platforms and Windows.


    Functions

    -

    get-insecure-random-bytes: func

    +

    get-insecure-random-bytes: func

    Return len insecure pseudo-random bytes.

    This function is not cryptographically secure. Do not use it for anything related to security.

    @@ -3018,13 +3017,13 @@ implementations are encouraged to return evenly distributed values with a long period.

    Params
      -
    • len: u64
    • +
    • len: u64
    Return values
    • list<u8>
    -

    get-insecure-random-u64: func

    +

    get-insecure-random-u64: func

    Return an insecure pseudo-random u64 value.

    This function returns the same type of pseudo-random data as get-insecure-random-bytes, represented as a u64.

    @@ -3032,13 +3031,13 @@ a long period.

    • u64
    -

    Import interface wasi:random/insecure-seed@0.2.0

    +

    Import interface wasi:random/insecure-seed@0.2.0

    The insecure-seed interface for seeding hash-map DoS resistance.

    It is intended to be portable at least between Unix-family platforms and Windows.


    Functions

    -

    insecure-seed: func

    +

    insecure-seed: func

    Return a 128-bit value that may contain a pseudo-random value.

    The returned value is not required to be computed from a CSPRNG, and may even be entirely deterministic. Host implementations are encouraged to @@ -3056,10 +3055,10 @@ protection.

    • (u64, u64)
    -

    Export interface wasi:cli/run@0.2.0

    +

    Export interface wasi:cli/run@0.2.0


    Functions

    -

    run: func

    +

    run: func

    Run the program.

    Return values
    + + +

    Import interface wasi:cli/environment@0.2.0


    Functions

    -

    get-environment: func

    +

    get-environment: func

    Get the POSIX-style environment variables.

    Each environment variable is provided as a pair of string variable names and string value.

    @@ -46,49 +46,47 @@ values each time it is called.

    • list<(string, string)>
    -

    get-arguments: func

    +

    get-arguments: func

    Get the POSIX-style arguments to the program.

    Return values
    • list<string>
    -

    initial-cwd: func

    +

    initial-cwd: func

    Return a path that programs should use as their initial current working directory, interpreting . as shorthand for this.

    Return values
    • option<string>
    -

    Import interface wasi:cli/exit@0.2.0

    +

    Import interface wasi:cli/exit@0.2.0


    Functions

    -

    exit: func

    +

    exit: func

    Exit the current instance and any linked instances.

    Params
      -
    • status: result
    • +
    • status: result
    -

    Import interface wasi:io/error@0.2.0

    +

    Import interface wasi:io/error@0.2.0


    Types

    -

    resource error

    +

    resource error

    A resource which represents some error information.

    The only method provided by this resource is to-debug-string, which provides some human-readable information about the error.

    In the wasi:io package, this resource is returned through the wasi:io/streams/stream-error type.

    To provide more specific error information, other interfaces may -provide functions to further "downcast" this error into more specific -error information. For example, errors returned in streams derived -from filesystem types to be described using the filesystem's own -error-code type, using the function -wasi:filesystem/types/filesystem-error-code, which takes a parameter -borrow<error> and returns -option<wasi:filesystem/types/error-code>.

    +offer functions to "downcast" this error into more specific types. For example, +errors returned from streams derived from filesystem types can be described using +the filesystem's own error-code type. This is done using the function +wasi:filesystem/types/filesystem-error-code, which takes a borrow<error> +parameter and returns an option<wasi:filesystem/types/error-code>.

    The set of functions which can "downcast" an error into a more concrete type is open.

    Functions

    -

    [method]error.to-debug-string: func

    +

    [method]error.to-debug-string: func

    Returns a string that is suitable to assist humans in debugging this error.

    WARNING: The returned string should not be consumed mechanically! @@ -97,92 +95,95 @@ details. Parsing this string is a major platform-compatibility hazard.

    Params
    Return values
      -
    • string
    • +
    • string
    -

    Import interface wasi:io/poll@0.2.0

    +

    Import interface wasi:io/poll@0.2.0

    A poll API intended to let users wait for I/O events on multiple handles at once.


    Types

    -

    resource pollable

    +

    resource pollable

    pollable represents a single I/O event which may be ready, or not.

    Functions

    -

    [method]pollable.ready: func

    +

    [method]pollable.ready: func

    Return the readiness of a pollable. This function never blocks.

    Returns true when the pollable is ready, and false otherwise.

    Params
    Return values
      -
    • bool
    • +
    • bool
    -

    [method]pollable.block: func

    +

    [method]pollable.block: func

    block returns immediately if the pollable is ready, and otherwise blocks until ready.

    This function is equivalent to calling poll.poll on a list containing only this pollable.

    Params
    -

    poll: func

    +

    poll: func

    Poll for completion on a set of pollables.

    This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

    The result list<u32> contains one or more indices of handles in the argument list that is ready for I/O.

    -

    If the list contains more elements than can be indexed with a u32 -value, this function traps.

    +

    This function traps if either:

    +
      +
    • the list is empty, or:
    • +
    • the list contains more elements than can be indexed with a u32 value.
    • +

    A timeout can be implemented by adding a pollable from the wasi-clocks API to the list.

    This function does not return a result; polling in itself does not do any I/O so it doesn't fail. If any of the I/O sources identified by the pollables has an error, it is indicated by marking the source as -being reaedy for I/O.

    +being ready for I/O.

    Params
    Return values
    • list<u32>
    -

    Import interface wasi:io/streams@0.2.0

    +

    Import interface wasi:io/streams@0.2.0

    WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

    In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


    Types

    -

    type error

    +

    type error

    error

    -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

    -#### `variant stream-error` +#### `variant stream-error`

    An error for input-stream and output-stream operations.

    Variant Cases
    • -

      last-operation-failed: own<error>

      +

      last-operation-failed: own<error>

      The last operation (a write or flush) failed before completion.

      More information is available in the error payload.

    • -

      closed

      +

      closed

      The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

    -

    resource input-stream

    +

    resource input-stream

    An input bytestream.

    input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are @@ -190,7 +191,7 @@ promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

    -

    resource output-stream

    +

    resource output-stream

    An output bytestream.

    output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also @@ -199,7 +200,7 @@ promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

    Functions

    -

    [method]input-stream.read: func

    +

    [method]input-stream.read: func

    Perform a non-blocking read from the stream.

    When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -223,51 +224,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

    Params
    Return values
    -

    [method]input-stream.blocking-read: func

    +

    [method]input-stream.blocking-read: func

    Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

    Params
    Return values
    -

    [method]input-stream.skip: func

    +

    [method]input-stream.skip: func

    Skip bytes from a stream. Returns number of bytes skipped.

    Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

    Params
    Return values
    -

    [method]input-stream.blocking-skip: func

    +

    [method]input-stream.blocking-skip: func

    Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

    Params
    Return values
    -

    [method]input-stream.subscribe: func

    +

    [method]input-stream.subscribe: func

    Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -276,13 +277,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

    Params
    Return values
    -

    [method]output-stream.check-write: func

    +

    [method]output-stream.check-write: func

    Check readiness for writing. This function never blocks.

    Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -292,13 +293,13 @@ become ready when this function will report at least 1 byte, or an error.

    Params
    Return values
    -

    [method]output-stream.write: func

    +

    [method]output-stream.write: func

    Perform a write. This function never blocks.

    When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -311,14 +312,14 @@ length of less than or equal to n. Otherwise, this function will trap.

    the last call to check-write provided a permit.

    Params
    Return values
    -

    [method]output-stream.blocking-write-and-flush: func

    +

    [method]output-stream.blocking-write-and-flush: func

    Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

    This is a convenience wrapper around the use of check-write, @@ -342,14 +343,14 @@ let _ = this.check-write(); // eliding error handling

    Params
    Return values
    -

    [method]output-stream.flush: func

    +

    [method]output-stream.flush: func

    Request to flush buffered output. This function never blocks.

    This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -360,24 +361,24 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

    Params
    Return values
    -

    [method]output-stream.blocking-flush: func

    +

    [method]output-stream.blocking-flush: func

    Request to flush buffered output, and block until flush completes and stream is ready for writing again.

    Params
    Return values
    -

    [method]output-stream.subscribe: func

    +

    [method]output-stream.subscribe: func

    Create a pollable which will resolve once the output-stream is ready for more writing, or an error has occured. When this pollable is ready, check-write will return ok(n) with n>0, or an @@ -388,13 +389,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

    Params
    Return values
    -

    [method]output-stream.write-zeroes: func

    +

    [method]output-stream.write-zeroes: func

    Write zeroes to a stream.

    This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -402,14 +403,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

    Params
    Return values
    -

    [method]output-stream.blocking-write-zeroes-and-flush: func

    +

    [method]output-stream.blocking-write-zeroes-and-flush: func

    Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

    @@ -433,14 +434,14 @@ let _ = this.check-write(); // eliding error handling
    Params
    Return values
    -

    [method]output-stream.splice: func

    +

    [method]output-stream.splice: func

    Read from one stream and write to another.

    The behavior of splice is equivelant to:

      @@ -455,161 +456,160 @@ let _ = this.check-write(); // eliding error handling than len.

      Params
      Return values
      -

      [method]output-stream.blocking-splice: func

      +

      [method]output-stream.blocking-splice: func

      Read from one stream and write to another, with blocking.

      This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

      Params
      Return values
      -

      Import interface wasi:cli/stdin@0.2.0

      +

      Import interface wasi:cli/stdin@0.2.0


      Types

      -

      type input-stream

      +

      type input-stream

      input-stream

      ----

      Functions

      -

      get-stdin: func

      +

      get-stdin: func

      Return values
      -

      Import interface wasi:cli/stdout@0.2.0

      +

      Import interface wasi:cli/stdout@0.2.0


      Types

      -

      type output-stream

      +

      type output-stream

      output-stream

      ----

      Functions

      -

      get-stdout: func

      +

      get-stdout: func

      Return values
      -

      Import interface wasi:cli/stderr@0.2.0

      +

      Import interface wasi:cli/stderr@0.2.0


      Types

      -

      type output-stream

      +

      type output-stream

      output-stream

      ----

      Functions

      -

      get-stderr: func

      +

      get-stderr: func

      Return values
      -

      Import interface wasi:cli/terminal-input@0.2.0

      +

      Import interface wasi:cli/terminal-input@0.2.0

      Terminal input.

      In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through immediately, querying supported features, and so on.


      Types

      -

      resource terminal-input

      +

      resource terminal-input

      The input side of a terminal.

      -

      Import interface wasi:cli/terminal-output@0.2.0

      +

      Import interface wasi:cli/terminal-output@0.2.0

      Terminal output.

      In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported features, and so on.


      Types

      -

      resource terminal-output

      +

      resource terminal-output

      The output side of a terminal.

      -

      Import interface wasi:cli/terminal-stdin@0.2.0

      +

      Import interface wasi:cli/terminal-stdin@0.2.0

      An interface providing an optional terminal-input for stdin as a link-time authority.


      Types

      -

      type terminal-input

      +

      type terminal-input

      terminal-input

      ----

      Functions

      -

      get-terminal-stdin: func

      +

      get-terminal-stdin: func

      If stdin is connected to a terminal, return a terminal-input handle allowing further interaction with it.

      Return values
      -

      Import interface wasi:cli/terminal-stdout@0.2.0

      +

      Import interface wasi:cli/terminal-stdout@0.2.0

      An interface providing an optional terminal-output for stdout as a link-time authority.


      Types

      -

      type terminal-output

      +

      type terminal-output

      terminal-output

      ----

      Functions

      -

      get-terminal-stdout: func

      +

      get-terminal-stdout: func

      If stdout is connected to a terminal, return a terminal-output handle allowing further interaction with it.

      Return values
      -

      Import interface wasi:cli/terminal-stderr@0.2.0

      +

      Import interface wasi:cli/terminal-stderr@0.2.0

      An interface providing an optional terminal-output for stderr as a link-time authority.


      Types

      -

      type terminal-output

      +

      type terminal-output

      terminal-output

      ----

      Functions

      -

      get-terminal-stderr: func

      +

      get-terminal-stderr: func

      If stderr is connected to a terminal, return a terminal-output handle allowing further interaction with it.

      Return values
      -

      Import interface wasi:clocks/monotonic-clock@0.2.0

      +

      Import interface wasi:clocks/monotonic-clock@0.2.0

      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

      It is intended to be portable at least between Unix-family platforms and Windows.

      A monotonic clock is a clock which has an unspecified initial value, and successive reads of the clock will produce non-decreasing values.

      -

      It is intended for measuring elapsed time.


      Types

      -

      type pollable

      +

      type pollable

      pollable

      -#### `type instant` +#### `type instant` `u64`

      An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. -

      type duration

      +

      type duration

      u64

      A duration of time, in nanoseconds.


      Functions

      -

      now: func

      +

      now: func

      Read the current value of the clock.

      The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

      @@ -617,37 +617,36 @@ produce a sequence of non-decreasing values.

      -

      resolution: func

      +

      resolution: func

      Query the resolution of the clock. Returns the duration of time corresponding to a clock tick.

      Return values
      -

      subscribe-instant: func

      +

      subscribe-instant: func

      Create a pollable which will resolve once the specified instant -occured.

      +has occured.

      Params
      Return values
      -

      subscribe-duration: func

      -

      Create a pollable which will resolve once the given duration has -elapsed, starting at the time at which this function was called. -occured.

      +

      subscribe-duration: func

      +

      Create a pollable that will resolve after the specified duration has +elapsed from the time this function is invoked.

      Params
      Return values
      -

      Import interface wasi:clocks/wall-clock@0.2.0

      +

      Import interface wasi:clocks/wall-clock@0.2.0

      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

      @@ -660,16 +659,16 @@ monotonic, making it unsuitable for measuring elapsed time.

      It is intended for reporting the current date and time for humans.


      Types

      -

      record datetime

      +

      record datetime

      A time and date in seconds plus nanoseconds.

      Record Fields

      Functions

      -

      now: func

      +

      now: func

      Read the current value of the clock.

      This clock is not monotonic, therefore calling this function repeatedly will not necessarily produce a sequence of non-decreasing values.

      @@ -681,14 +680,14 @@ also known as Unix Time.
    1. datetime
    2. -

      resolution: func

      +

      resolution: func

      Query the resolution of the clock.

      The nanoseconds field of the output is always less than 1000000000.

      Return values
      -

      Import interface wasi:filesystem/types@0.2.0

      +

      Import interface wasi:filesystem/types@0.2.0

      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

      @@ -708,75 +707,75 @@ underlying filesystem, the function fails with WASI filesystem path resolution.


      Types

      -

      type input-stream

      +

      type input-stream

      input-stream

      -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

      -#### `type error` +#### `type error` [`error`](#error)

      -#### `type datetime` +#### `type datetime` [`datetime`](#datetime)

      -#### `type filesize` +#### `type filesize` `u64`

      File size or length of a region within a file. -

      enum descriptor-type

      +

      enum descriptor-type

      The type of a filesystem object referenced by a descriptor.

      Note: This was called filetype in earlier versions of WASI.

      Enum Cases
      • -

        unknown

        +

        unknown

        The type of the descriptor or file is unknown or is different from any of the other types specified.

      • -

        block-device

        +

        block-device

        The descriptor refers to a block device inode.

      • -

        character-device

        +

        character-device

        The descriptor refers to a character device inode.

      • -

        directory

        +

        directory

        The descriptor refers to a directory inode.

      • -

        fifo

        +

        fifo

        The descriptor refers to a named pipe.

      • -

        symbolic-link

        +

        symbolic-link

        The file refers to a symbolic link inode.

      • -

        regular-file

        +

        regular-file

        The descriptor refers to a regular file inode.

      • -

        socket

        +

        socket

        The descriptor refers to a socket.

      -

      flags descriptor-flags

      +

      flags descriptor-flags

      Descriptor flags.

      Note: This was called fdflags in earlier versions of WASI.

      Flags members
      • -

        read:

        +

        read:

        Read mode: Data can be read.

      • -

        write:

        +

        write:

        Write mode: Data can be written to.

      • -

        file-integrity-sync:

        +

        file-integrity-sync:

        Request that writes be performed according to synchronized I/O file integrity completion. The data stored in the file and the file's metadata are synchronized. This is similar to `O_SYNC` in POSIX. @@ -785,7 +784,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

      • -

        data-integrity-sync:

        +

        data-integrity-sync:

        Request that writes be performed according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. This is similar to `O_DSYNC` in POSIX. @@ -794,7 +793,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

      • -

        requested-write-sync:

        +

        requested-write-sync:

        Requests that reads be performed at the same level of integrety requested for writes. This is similar to `O_RSYNC` in POSIX.

        The precise semantics of this operation have not yet been defined for @@ -802,7 +801,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

      • -

        mutate-directory:

        +

        mutate-directory:

        Mutating directories mode: Directory contents may be mutated.

        When this flag is unset on a descriptor, operations using the descriptor which would create, rename, delete, modify the data or @@ -812,107 +811,107 @@ they would otherwise succeed.

        This may only be set on directories.

      -

      flags path-flags

      +

      flags path-flags

      Flags determining the method of how paths are resolved.

      Flags members
        -
      • symlink-follow:

        As long as the resolved path corresponds to a symbolic link, it is +

      • symlink-follow:

        As long as the resolved path corresponds to a symbolic link, it is expanded.

      -

      flags open-flags

      +

      flags open-flags

      Open flags used by open-at.

      Flags members
      • -

        create:

        +

        create:

        Create file if it does not exist, similar to `O_CREAT` in POSIX.

      • -

        directory:

        +

        directory:

        Fail if not a directory, similar to `O_DIRECTORY` in POSIX.

      • -

        exclusive:

        +

        exclusive:

        Fail if file already exists, similar to `O_EXCL` in POSIX.

      • -

        truncate:

        +

        truncate:

        Truncate file to size 0, similar to `O_TRUNC` in POSIX.

      -

      type link-count

      +

      type link-count

      u64

      Number of hard links to an inode. -

      record descriptor-stat

      +

      record descriptor-stat

      File attributes.

      Note: This was called filestat in earlier versions of WASI.

      Record Fields
      -

      variant new-timestamp

      +

      variant new-timestamp

      When setting a timestamp, this gives the value to set it to.

      Variant Cases
      • -

        no-change

        +

        no-change

        Leave the timestamp set to its previous value.

      • -

        now

        +

        now

        Set the timestamp to the current time of the system clock associated with the filesystem.

      • -

        timestamp: datetime

        +

        timestamp: datetime

        Set the timestamp to the given value.

      -

      record directory-entry

      +

      record directory-entry

      A directory entry.

      Record Fields
      -

      enum error-code

      +

      enum error-code

      Error codes returned by functions, similar to errno in POSIX. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -920,211 +919,211 @@ merely for alignment with POSIX.

      Enum Cases
      • -

        access

        +

        access

        Permission denied, similar to `EACCES` in POSIX.

      • -

        would-block

        +

        would-block

        Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX.

      • -

        already

        +

        already

        Connection already in progress, similar to `EALREADY` in POSIX.

      • -

        bad-descriptor

        +

        bad-descriptor

        Bad descriptor, similar to `EBADF` in POSIX.

      • -

        busy

        +

        busy

        Device or resource busy, similar to `EBUSY` in POSIX.

      • -

        deadlock

        +

        deadlock

        Resource deadlock would occur, similar to `EDEADLK` in POSIX.

      • -

        quota

        +

        quota

        Storage quota exceeded, similar to `EDQUOT` in POSIX.

      • -

        exist

        +

        exist

        File exists, similar to `EEXIST` in POSIX.

      • -

        file-too-large

        +

        file-too-large

        File too large, similar to `EFBIG` in POSIX.

      • -

        illegal-byte-sequence

        +

        illegal-byte-sequence

        Illegal byte sequence, similar to `EILSEQ` in POSIX.

      • -

        in-progress

        +

        in-progress

        Operation in progress, similar to `EINPROGRESS` in POSIX.

      • -

        interrupted

        +

        interrupted

        Interrupted function, similar to `EINTR` in POSIX.

      • -

        invalid

        +

        invalid

        Invalid argument, similar to `EINVAL` in POSIX.

      • -

        io

        +

        io

        I/O error, similar to `EIO` in POSIX.

      • -

        is-directory

        +

        is-directory

        Is a directory, similar to `EISDIR` in POSIX.

      • -

        loop

        +

        loop

        Too many levels of symbolic links, similar to `ELOOP` in POSIX.

      • -

        too-many-links

        +

        too-many-links

        Too many links, similar to `EMLINK` in POSIX.

      • -

        message-size

        +

        message-size

        Message too large, similar to `EMSGSIZE` in POSIX.

      • -

        name-too-long

        +

        name-too-long

        Filename too long, similar to `ENAMETOOLONG` in POSIX.

      • -

        no-device

        +

        no-device

        No such device, similar to `ENODEV` in POSIX.

      • -

        no-entry

        +

        no-entry

        No such file or directory, similar to `ENOENT` in POSIX.

      • -

        no-lock

        +

        no-lock

        No locks available, similar to `ENOLCK` in POSIX.

      • -

        insufficient-memory

        +

        insufficient-memory

        Not enough space, similar to `ENOMEM` in POSIX.

      • -

        insufficient-space

        +

        insufficient-space

        No space left on device, similar to `ENOSPC` in POSIX.

      • -

        not-directory

        +

        not-directory

        Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX.

      • -

        not-empty

        +

        not-empty

        Directory not empty, similar to `ENOTEMPTY` in POSIX.

      • -

        not-recoverable

        +

        not-recoverable

        State not recoverable, similar to `ENOTRECOVERABLE` in POSIX.

      • -

        unsupported

        +

        unsupported

        Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX.

      • -

        no-tty

        +

        no-tty

        Inappropriate I/O control operation, similar to `ENOTTY` in POSIX.

      • -

        no-such-device

        +

        no-such-device

        No such device or address, similar to `ENXIO` in POSIX.

      • -

        overflow

        +

        overflow

        Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX.

      • -

        not-permitted

        +

        not-permitted

        Operation not permitted, similar to `EPERM` in POSIX.

      • -

        pipe

        +

        pipe

        Broken pipe, similar to `EPIPE` in POSIX.

      • -

        read-only

        +

        read-only

        Read-only file system, similar to `EROFS` in POSIX.

      • -

        invalid-seek

        +

        invalid-seek

        Invalid seek, similar to `ESPIPE` in POSIX.

      • -

        text-file-busy

        +

        text-file-busy

        Text file busy, similar to `ETXTBSY` in POSIX.

      • -

        cross-device

        +

        cross-device

        Cross-device link, similar to `EXDEV` in POSIX.

      -

      enum advice

      +

      enum advice

      File or memory access pattern advisory information.

      Enum Cases
      • -

        normal

        +

        normal

        The application has no advice to give on its behavior with respect to the specified data.

      • -

        sequential

        +

        sequential

        The application expects to access the specified data sequentially from lower offsets to higher offsets.

      • -

        random

        +

        random

        The application expects to access the specified data in a random order.

      • -

        will-need

        +

        will-need

        The application expects to access the specified data in the near future.

      • -

        dont-need

        +

        dont-need

        The application expects that it will not access the specified data in the near future.

      • -

        no-reuse

        +

        no-reuse

        The application expects to access the specified data once and then not reuse it thereafter.

      -

      record metadata-hash-value

      +

      record metadata-hash-value

      A 128-bit hash value, split into parts because wasm doesn't have a 128-bit integer type.

      Record Fields
      • -

        lower: u64

        +

        lower: u64

        64 bits of a 128-bit hash value.

      • -

        upper: u64

        +

        upper: u64

        Another 64 bits of a 128-bit hash value.

      -

      resource descriptor

      +

      resource descriptor

      A descriptor is a reference to a filesystem object, which may be a file, directory, named pipe, special file, or other object on which filesystem calls may be made.

      -

      resource directory-entry-stream

      +

      resource directory-entry-stream

      A stream of directory entries.

      Functions

      -

      [method]descriptor.read-via-stream: func

      +

      [method]descriptor.read-via-stream: func

      Return a stream for reading from a file, if available.

      May fail with an error-code describing why the file cannot be read.

      Multiple read, write, and append streams may be active on the same open @@ -1132,81 +1131,81 @@ file and they do not interfere with each other.

      Note: This allows using read-stream, which is similar to read in POSIX.

      Params
      Return values
      -

      [method]descriptor.write-via-stream: func

      +

      [method]descriptor.write-via-stream: func

      Return a stream for writing to a file, if available.

      May fail with an error-code describing why the file cannot be written.

      Note: This allows using write-stream, which is similar to write in POSIX.

      Params
      Return values
      -

      [method]descriptor.append-via-stream: func

      +

      [method]descriptor.append-via-stream: func

      Return a stream for appending to a file, if available.

      May fail with an error-code describing why the file cannot be appended.

      Note: This allows using write-stream, which is similar to write with O_APPEND in in POSIX.

      Params
      Return values
      -

      [method]descriptor.advise: func

      +

      [method]descriptor.advise: func

      Provide file advisory information on a descriptor.

      This is similar to posix_fadvise in POSIX.

      Params
      Return values
      -

      [method]descriptor.sync-data: func

      +

      [method]descriptor.sync-data: func

      Synchronize the data of a file to disk.

      This function succeeds with no effect if the file descriptor is not opened for writing.

      Note: This is similar to fdatasync in POSIX.

      Params
      Return values
      -

      [method]descriptor.get-flags: func

      +

      [method]descriptor.get-flags: func

      Get flags associated with a descriptor.

      Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

      Note: This returns the value that was the fs_flags value returned from fdstat_get in earlier versions of WASI.

      Params
      Return values
      -

      [method]descriptor.get-type: func

      +

      [method]descriptor.get-type: func

      Get the dynamic type of a descriptor.

      Note: This returns the same value as the type field of the fd-stat returned by stat, stat-at and similar.

      @@ -1216,40 +1215,40 @@ by fstat in POSIX.

      from fdstat_get in earlier versions of WASI.

      Params
      Return values
      -

      [method]descriptor.set-size: func

      +

      [method]descriptor.set-size: func

      Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.

      Note: This was called fd_filestat_set_size in earlier versions of WASI.

      Params
      Return values
      -

      [method]descriptor.set-times: func

      +

      [method]descriptor.set-times: func

      Adjust the timestamps of an open file or directory.

      Note: This is similar to futimens in POSIX.

      Note: This was called fd_filestat_set_times in earlier versions of WASI.

      Params
      Return values
      -

      [method]descriptor.read: func

      +

      [method]descriptor.read: func

      Read from a descriptor, without using and updating the descriptor's offset.

      This function returns a list of bytes containing the data that was read, along with a bool which, when true, indicates that the end of the @@ -1260,15 +1259,15 @@ if the I/O operation is interrupted.

      Note: This is similar to pread in POSIX.

      Params
      Return values
      -

      [method]descriptor.write: func

      +

      [method]descriptor.write: func

      Write to a descriptor, without using and updating the descriptor's offset.

      It is valid to write past the end of a file; the file is extended to the extent of the write, with bytes between the previous end and the start of @@ -1277,15 +1276,15 @@ the write set to zero.

      Note: This is similar to pwrite in POSIX.

      Params
      Return values
      -

      [method]descriptor.read-directory: func

      +

      [method]descriptor.read-directory: func

      Read directory entries from a directory.

      On filesystems where directories contain entries referring to themselves and their parents, often named . and .. respectively, these entries @@ -1295,38 +1294,38 @@ directory. Multiple streams may be active on the same directory, and they do not interfere with each other.

      Params
      Return values
      -

      [method]descriptor.sync: func

      +

      [method]descriptor.sync: func

      Synchronize the data and metadata of a file to disk.

      This function succeeds with no effect if the file descriptor is not opened for writing.

      Note: This is similar to fsync in POSIX.

      Params
      Return values
      -

      [method]descriptor.create-directory-at: func

      +

      [method]descriptor.create-directory-at: func

      Create a directory.

      Note: This is similar to mkdirat in POSIX.

      Params
      Return values
      -

      [method]descriptor.stat: func

      +

      [method]descriptor.stat: func

      Return the attributes of an open file or directory.

      Note: This is similar to fstat in POSIX, except that it does not return device and inode information. For testing whether two descriptors refer to @@ -1336,13 +1335,13 @@ modified, use metadata-hash.

      Note: This was called fd_filestat_get in earlier versions of WASI.

      Params
      Return values
      -

      [method]descriptor.stat-at: func

      +

      [method]descriptor.stat-at: func

      Return the attributes of a file or directory.

      Note: This is similar to fstatat in POSIX, except that it does not return device and inode information. See the stat description for a @@ -1350,47 +1349,47 @@ discussion of alternatives.

      Note: This was called path_filestat_get in earlier versions of WASI.

      Params
      Return values
      -

      [method]descriptor.set-times-at: func

      +

      [method]descriptor.set-times-at: func

      Adjust the timestamps of a file or directory.

      Note: This is similar to utimensat in POSIX.

      Note: This was called path_filestat_set_times in earlier versions of WASI.

      Params
      Return values
      -

      [method]descriptor.link-at: func

      +

      [method]descriptor.link-at: func

      Create a hard link.

      Note: This is similar to linkat in POSIX.

      Params
      Return values
      -

      [method]descriptor.open-at: func

      +

      [method]descriptor.open-at: func

      Open a file or directory.

      The returned descriptor is not guaranteed to be the lowest-numbered descriptor not currently open/ it is randomized to prevent applications @@ -1407,86 +1406,86 @@ contains truncate or create, and the base descriptor d

      Note: This is similar to openat in POSIX.

      Params
      Return values
      -

      [method]descriptor.readlink-at: func

      +

      [method]descriptor.readlink-at: func

      Read the contents of a symbolic link.

      If the contents contain an absolute or rooted path in the underlying filesystem, this function fails with error-code::not-permitted.

      Note: This is similar to readlinkat in POSIX.

      Params
      Return values
      -

      [method]descriptor.remove-directory-at: func

      +

      [method]descriptor.remove-directory-at: func

      Remove a directory.

      Return error-code::not-empty if the directory is not empty.

      Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

      Params
      Return values
      -

      [method]descriptor.rename-at: func

      +

      [method]descriptor.rename-at: func

      Rename a filesystem object.

      Note: This is similar to renameat in POSIX.

      Params
      Return values
      -

      [method]descriptor.symlink-at: func

      +

      [method]descriptor.symlink-at: func

      Create a symbolic link (also known as a "symlink").

      If old-path starts with /, the function fails with error-code::not-permitted.

      Note: This is similar to symlinkat in POSIX.

      Params
      Return values
      -

      [method]descriptor.unlink-file-at: func

      +

      [method]descriptor.unlink-file-at: func

      Unlink a filesystem object that is not a directory.

      Return error-code::is-directory if the path refers to a directory. Note: This is similar to unlinkat(fd, path, 0) in POSIX.

      Params
      Return values
      -

      [method]descriptor.is-same-object: func

      +

      [method]descriptor.is-same-object: func

      Test whether two descriptors refer to the same filesystem object.

      In POSIX, this corresponds to testing whether the two descriptors have the same device (st_dev) and inode (st_ino or d_ino) numbers. @@ -1494,14 +1493,14 @@ wasi-filesystem does not expose device and inode numbers, so this function may be used instead.

      Params
      Return values
        -
      • bool
      • +
      • bool
      -

      [method]descriptor.metadata-hash: func

      +

      [method]descriptor.metadata-hash: func

      Return a hash of the metadata associated with a filesystem object referred to by a descriptor.

      This returns a hash of the last-modification timestamp and file size, and @@ -1521,37 +1520,37 @@ computed hash.

      However, none of these is required.

      Params
      Return values
      -

      [method]descriptor.metadata-hash-at: func

      +

      [method]descriptor.metadata-hash-at: func

      Return a hash of the metadata associated with a filesystem object referred to by a directory descriptor and a relative path.

      This performs the same hash computation as metadata-hash.

      Params
      Return values
      -

      [method]directory-entry-stream.read-directory-entry: func

      +

      [method]directory-entry-stream.read-directory-entry: func

      Read a single directory entry from a directory-entry-stream.

      Params
      Return values
      -

      filesystem-error-code: func

      +

      filesystem-error-code: func

      Attempts to extract a filesystem-related error-code from the stream error provided.

      Stream operations which return stream-error::last-operation-failed @@ -1562,34 +1561,34 @@ filesystem-related information about the error to return.

      errors are filesystem-related errors.

      Params
      Return values
      -

      Import interface wasi:filesystem/preopens@0.2.0

      +

      Import interface wasi:filesystem/preopens@0.2.0


      Types

      -

      type descriptor

      +

      type descriptor

      descriptor

      ----

      Functions

      -

      get-directories: func

      +

      get-directories: func

      Return the set of preopened directories, and their path.

      Return values
      -

      Import interface wasi:sockets/network@0.2.0

      +

      Import interface wasi:sockets/network@0.2.0


      Types

      -

      resource network

      +

      resource network

      An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

      -

      enum error-code

      +

      enum error-code

      Error codes.

      In theory, every API can return any error code. In practice, API's typically only return the errors documented per API @@ -1605,235 +1604,235 @@ combined with a couple of errors that are always possible:

      Enum Cases
      • -

        unknown

        +

        unknown

        Unknown error

      • -

        access-denied

        +

        access-denied

        Access denied.

        POSIX equivalent: EACCES, EPERM

      • -

        not-supported

        +

        not-supported

        The operation is not supported.

        POSIX equivalent: EOPNOTSUPP

      • -

        invalid-argument

        +

        invalid-argument

        One of the arguments is invalid.

        POSIX equivalent: EINVAL

      • -

        out-of-memory

        +

        out-of-memory

        Not enough memory to complete the operation.

        POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY

      • -

        timeout

        +

        timeout

        The operation timed out before it could finish completely.

      • -

        concurrency-conflict

        +

        concurrency-conflict

        This operation is incompatible with another asynchronous operation that is already in progress.

        POSIX equivalent: EALREADY

      • -

        not-in-progress

        +

        not-in-progress

        Trying to finish an asynchronous operation that: - has not been started yet, or: - was already finished by a previous `finish-*` call.

        Note: this is scheduled to be removed when futures are natively supported.

      • -

        would-block

        +

        would-block

        The operation has been aborted because it could not be completed immediately.

        Note: this is scheduled to be removed when futures are natively supported.

      • -

        invalid-state

        +

        invalid-state

        The operation is not valid in the socket's current state.

      • -

        new-socket-limit

        +

        new-socket-limit

        A new socket resource could not be created because of a system limit.

      • -

        address-not-bindable

        +

        address-not-bindable

        A bind operation failed because the provided address is not an address that the `network` can bind to.

      • -

        address-in-use

        +

        address-in-use

        A bind operation failed because the provided address is already in use or because there are no ephemeral ports available.

      • -

        remote-unreachable

        +

        remote-unreachable

        The remote address is not reachable

      • -

        connection-refused

        +

        connection-refused

        The TCP connection was forcefully rejected

      • -

        connection-reset

        +

        connection-reset

        The TCP connection was reset.

      • -

        connection-aborted

        +

        connection-aborted

        A TCP connection was aborted.

      • -

        datagram-too-large

        +

        datagram-too-large

        The size of a datagram sent to a UDP socket exceeded the maximum supported size.

      • -

        name-unresolvable

        +

        name-unresolvable

        Name does not exist or has no suitable associated IP addresses.

      • -

        temporary-resolver-failure

        +

        temporary-resolver-failure

        A temporary failure in name resolution occurred.

      • -

        permanent-resolver-failure

        +

        permanent-resolver-failure

        A permanent failure in name resolution occurred.

      -

      enum ip-address-family

      +

      enum ip-address-family

      Enum Cases
      • -

        ipv4

        +

        ipv4

        Similar to `AF_INET` in POSIX.

      • -

        ipv6

        +

        ipv6

        Similar to `AF_INET6` in POSIX.

      -

      tuple ipv4-address

      +

      tuple ipv4-address

      Tuple Fields
        -
      • 0: u8
      • -
      • 1: u8
      • -
      • 2: u8
      • -
      • 3: u8
      • +
      • 0: u8
      • +
      • 1: u8
      • +
      • 2: u8
      • +
      • 3: u8
      -

      tuple ipv6-address

      +

      tuple ipv6-address

      Tuple Fields
        -
      • 0: u16
      • -
      • 1: u16
      • -
      • 2: u16
      • -
      • 3: u16
      • -
      • 4: u16
      • -
      • 5: u16
      • -
      • 6: u16
      • -
      • 7: u16
      • +
      • 0: u16
      • +
      • 1: u16
      • +
      • 2: u16
      • +
      • 3: u16
      • +
      • 4: u16
      • +
      • 5: u16
      • +
      • 6: u16
      • +
      • 7: u16
      -

      variant ip-address

      +

      variant ip-address

      Variant Cases
      -

      record ipv4-socket-address

      +

      record ipv4-socket-address

      Record Fields
      -

      record ipv6-socket-address

      +

      record ipv6-socket-address

      Record Fields
      -

      variant ip-socket-address

      +

      variant ip-socket-address

      Variant Cases
      -

      Import interface wasi:sockets/instance-network@0.2.0

      +

      Import interface wasi:sockets/instance-network@0.2.0

      This interface provides a value-export of the default network handle..


      Types

      -

      type network

      +

      type network

      network

      ----

      Functions

      -

      instance-network: func

      +

      instance-network: func

      Get a handle to the default network.

      Return values
      -

      Import interface wasi:sockets/udp@0.2.0

      +

      Import interface wasi:sockets/udp@0.2.0


      Types

      -

      type pollable

      +

      type pollable

      pollable

      -#### `type network` +#### `type network` [`network`](#network)

      -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

      -#### `type ip-socket-address` +#### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address)

      -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

      -#### `record incoming-datagram` +#### `record incoming-datagram`

      A received datagram.

      Record Fields
      • -

        data: list<u8>

        +

        data: list<u8>

        The payload.

        Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes.

      • -

        remote-address: ip-socket-address

        +

        remote-address: ip-socket-address

        The source address.

        This field is guaranteed to match the remote address the stream was initialized with, if any.

        Equivalent to the src_addr out parameter of recvfrom.

      -

      record outgoing-datagram

      +

      record outgoing-datagram

      A datagram to be sent out.

      Record Fields
      • -

        data: list<u8>

        +

        data: list<u8>

        The payload.

      • -

        remote-address: option<ip-socket-address>

        +

        remote-address: option<ip-socket-address>

        The destination address.

        The requirements on this field depend on how the stream was initialized:

          @@ -1843,13 +1842,13 @@ supported size.

          If this value is None, the send operation is equivalent to send in POSIX. Otherwise it is equivalent to sendto.

        -

        resource udp-socket

        +

        resource udp-socket

        A UDP socket handle.

        -

        resource incoming-datagram-stream

        -

        resource outgoing-datagram-stream

        +

        resource incoming-datagram-stream

        +

        resource outgoing-datagram-stream


        Functions

        -

        [method]udp-socket.start-bind: func

        +

        [method]udp-socket.start-bind: func

        Bind the socket to a specific network on the provided IP address and port.

        If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -1878,24 +1877,24 @@ don't want to make use of this ability can simply call the native

      Params
      Return values
      -

      [method]udp-socket.finish-bind: func

      +

      [method]udp-socket.finish-bind: func

      Params
      Return values
      -

      [method]udp-socket.stream: func

      +

      [method]udp-socket.stream: func

      Set up inbound & outbound communication channels, optionally to a specific peer.

      This function only changes the local socket configuration and does not generate any network traffic. On success, the remote-address of the socket is updated. The local-address may be updated as well, @@ -1936,14 +1935,14 @@ if (remote_address is Some) {

      Params
      Return values
      -

      [method]udp-socket.local-address: func

      +

      [method]udp-socket.local-address: func

      Get the current bound address.

      POSIX mentions:

      @@ -1964,13 +1963,13 @@ stored in the object pointed to by address is unspecified.

      Params
      Return values
      -

      [method]udp-socket.remote-address: func

      +

      [method]udp-socket.remote-address: func

      Get the address the socket is currently streaming to.

      Typical errors

        @@ -1985,24 +1984,24 @@ stored in the object pointed to by address is unspecified.

      Params
      Return values
      -

      [method]udp-socket.address-family: func

      +

      [method]udp-socket.address-family: func

      Whether this is a IPv4 or IPv6 socket.

      Equivalent to the SO_DOMAIN socket option.

      Params
      Return values
      -

      [method]udp-socket.unicast-hop-limit: func

      +

      [method]udp-socket.unicast-hop-limit: func

      Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

      If the provided value is 0, an invalid-argument error is returned.

      Typical errors

      @@ -2011,23 +2010,23 @@ stored in the object pointed to by address is unspecified.

      Params
      Return values
      -

      [method]udp-socket.set-unicast-hop-limit: func

      +

      [method]udp-socket.set-unicast-hop-limit: func

      Params
      Return values
      -

      [method]udp-socket.receive-buffer-size: func

      +

      [method]udp-socket.receive-buffer-size: func

      The kernel buffer space reserved for sends/receives on this socket.

      If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2039,54 +2038,54 @@ I.e. after setting a value, reading the same setting back may return a different

      Params
      Return values
      -

      [method]udp-socket.set-receive-buffer-size: func

      +

      [method]udp-socket.set-receive-buffer-size: func

      Params
      Return values
      -

      [method]udp-socket.send-buffer-size: func

      +

      [method]udp-socket.send-buffer-size: func

      Params
      Return values
      -

      [method]udp-socket.set-send-buffer-size: func

      +

      [method]udp-socket.set-send-buffer-size: func

      Params
      Return values
      -

      [method]udp-socket.subscribe: func

      +

      [method]udp-socket.subscribe: func

      Create a pollable which will resolve once the socket is ready for I/O.

      Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

      Params
      Return values
      -

      [method]incoming-datagram-stream.receive: func

      +

      [method]incoming-datagram-stream.receive: func

      Receive messages on the socket.

      This function attempts to receive up to max-results datagrams on the socket without blocking. The returned list may contain fewer elements than requested, but never more.

      @@ -2114,26 +2113,26 @@ This function never returns error(would-block).
      Params
      Return values
      -

      [method]incoming-datagram-stream.subscribe: func

      +

      [method]incoming-datagram-stream.subscribe: func

      Create a pollable which will resolve once the stream is ready to receive again.

      Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

      Params
      Return values
      -

      [method]outgoing-datagram-stream.check-send: func

      +

      [method]outgoing-datagram-stream.check-send: func

      Check readiness for sending. This function never blocks.

      Returns the number of datagrams permitted for the next call to send, or an error. Calling send with more datagrams than this function has @@ -2144,13 +2143,13 @@ error.

      Never returns would-block.

      Params
      Return values
      -

      [method]outgoing-datagram-stream.send: func

      +

      [method]outgoing-datagram-stream.send: func

      Send messages on the socket.

      This function attempts to send all provided datagrams on the socket without blocking and returns how many messages were actually sent (or queued for sending). This function never @@ -2185,43 +2184,43 @@ either check-send was not called or datagrams contains

      Params
      Return values
      -

      [method]outgoing-datagram-stream.subscribe: func

      +

      [method]outgoing-datagram-stream.subscribe: func

      Create a pollable which will resolve once the stream is ready to send again.

      Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

      Params
      Return values
      -

      Import interface wasi:sockets/udp-create-socket@0.2.0

      +

      Import interface wasi:sockets/udp-create-socket@0.2.0


      Types

      -

      type network

      +

      type network

      network

      -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

      -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

      -#### `type udp-socket` +#### `type udp-socket` [`udp-socket`](#udp_socket)

      ----

      Functions

      -

      create-udp-socket: func

      +

      create-udp-socket: func

      Create a new UDP socket.

      Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX. On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

      @@ -2243,56 +2242,56 @@ the socket is effectively an in-memory configuration object, unable to communica
      Params
      Return values
      -

      Import interface wasi:sockets/tcp@0.2.0

      +

      Import interface wasi:sockets/tcp@0.2.0


      Types

      -

      type input-stream

      +

      type input-stream

      input-stream

      -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

      -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

      -#### `type duration` +#### `type duration` [`duration`](#duration)

      -#### `type network` +#### `type network` [`network`](#network)

      -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

      -#### `type ip-socket-address` +#### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address)

      -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

      -#### `enum shutdown-type` +#### `enum shutdown-type`

      Enum Cases
      • -

        receive

        +

        receive

        Similar to `SHUT_RD` in POSIX.

      • -

        send

        +

        send

        Similar to `SHUT_WR` in POSIX.

      • -

        both

        +

        both

        Similar to `SHUT_RDWR` in POSIX.

      -

      resource tcp-socket

      +

      resource tcp-socket

      A TCP socket resource.

      The socket can be in one of the following states:

      Note: Except where explicitly mentioned, whenever this documentation uses the term "bound" without backticks it actually means: in the bound state or higher. @@ -2314,7 +2313,7 @@ the term "bound" without backticks it actually means: in the bou network::error-code type, TCP socket methods may always return error(invalid-state) when in the closed state.

    Functions

    -

    [method]tcp-socket.start-bind: func

    +

    [method]tcp-socket.start-bind: func

    Bind the socket to a specific network on the provided IP address and port.

    If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -2353,28 +2352,28 @@ don't want to make use of this ability can simply call the native

    Params
    Return values
    -

    [method]tcp-socket.finish-bind: func

    +

    [method]tcp-socket.finish-bind: func

    Params
    Return values
    -

    [method]tcp-socket.start-connect: func

    +

    [method]tcp-socket.start-connect: func

    Connect to a remote endpoint.

    On success:

      -
    • the socket is transitioned into the connection state.
    • +
    • the socket is transitioned into the connected state.
    • a pair of streams is returned that can be used to read & write to the connection

    After a failed connection attempt, the socket will be in the closed @@ -2415,24 +2414,24 @@ the SO_ERROR socket option, in case the poll signaled readiness.

    Params
    Return values
    -

    [method]tcp-socket.finish-connect: func

    +

    [method]tcp-socket.finish-connect: func

    Params
    Return values
    -

    [method]tcp-socket.start-listen: func

    +

    [method]tcp-socket.start-listen: func

    Start listening for new connections.

    Transitions the socket into the listening state.

    Unlike POSIX, the socket must already be explicitly bound.

    @@ -2459,22 +2458,22 @@ don't want to make use of this ability can simply call the native
    Params
    Return values
    -

    [method]tcp-socket.finish-listen: func

    +

    [method]tcp-socket.finish-listen: func

    Params
    Return values
    -

    [method]tcp-socket.accept: func

    +

    [method]tcp-socket.accept: func

    Accept a new client socket.

    The returned socket is bound and in the connected state. The following properties are inherited from the listener socket:

      @@ -2505,13 +2504,13 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    [method]tcp-socket.local-address: func

    +

    [method]tcp-socket.local-address: func

    Get the bound local address.

    POSIX mentions:

    @@ -2532,13 +2531,13 @@ stored in the object pointed to by address is unspecified.

    Params
    Return values
    -

    [method]tcp-socket.remote-address: func

    +

    [method]tcp-socket.remote-address: func

    Get the remote address.

    Typical errors

      @@ -2553,35 +2552,35 @@ stored in the object pointed to by address is unspecified.

    Params
    Return values
    -

    [method]tcp-socket.is-listening: func

    +

    [method]tcp-socket.is-listening: func

    Whether the socket is in the listening state.

    Equivalent to the SO_ACCEPTCONN socket option.

    Params
    Return values
      -
    • bool
    • +
    • bool
    -

    [method]tcp-socket.address-family: func

    +

    [method]tcp-socket.address-family: func

    Whether this is a IPv4 or IPv6 socket.

    Equivalent to the SO_DOMAIN socket option.

    Params
    Return values
    -

    [method]tcp-socket.set-listen-backlog-size: func

    +

    [method]tcp-socket.set-listen-backlog-size: func

    Hints the desired listen queue size. Implementations are free to ignore this.

    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded.

    @@ -2593,14 +2592,14 @@ Any other value will never cause an error, but it might be silently clamped and/
    Params
    Return values
    -

    [method]tcp-socket.keep-alive-enabled: func

    +

    [method]tcp-socket.keep-alive-enabled: func

    Enables or disables keepalive.

    The keepalive behavior can be adjusted using:

      @@ -2612,23 +2611,23 @@ These properties can be configured while keep-alive-enabled is fals

      Equivalent to the SO_KEEPALIVE socket option.

      Params
      Return values
      -

      [method]tcp-socket.set-keep-alive-enabled: func

      +

      [method]tcp-socket.set-keep-alive-enabled: func

      Params
      Return values
      -

      [method]tcp-socket.keep-alive-idle-time: func

      +

      [method]tcp-socket.keep-alive-idle-time: func

      Amount of time the connection has to be idle before TCP starts sending keepalive packets.

      If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2640,23 +2639,23 @@ I.e. after setting a value, reading the same setting back may return a different

    Params
    Return values
    -

    [method]tcp-socket.set-keep-alive-idle-time: func

    +

    [method]tcp-socket.set-keep-alive-idle-time: func

    Params
    Return values
    -

    [method]tcp-socket.keep-alive-interval: func

    +

    [method]tcp-socket.keep-alive-interval: func

    The time between keepalive packets.

    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2668,23 +2667,23 @@ I.e. after setting a value, reading the same setting back may return a different

    Params
    Return values
    -

    [method]tcp-socket.set-keep-alive-interval: func

    +

    [method]tcp-socket.set-keep-alive-interval: func

    Params
    Return values
    -

    [method]tcp-socket.keep-alive-count: func

    +

    [method]tcp-socket.keep-alive-count: func

    The maximum amount of keepalive packets TCP should send before aborting the connection.

    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2696,23 +2695,23 @@ I.e. after setting a value, reading the same setting back may return a different

    Params
    Return values
    -

    [method]tcp-socket.set-keep-alive-count: func

    +

    [method]tcp-socket.set-keep-alive-count: func

    Params
    Return values
    -

    [method]tcp-socket.hop-limit: func

    +

    [method]tcp-socket.hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    If the provided value is 0, an invalid-argument error is returned.

    Typical errors

    @@ -2721,23 +2720,23 @@ I.e. after setting a value, reading the same setting back may return a different
    Params
    Return values
    -

    [method]tcp-socket.set-hop-limit: func

    +

    [method]tcp-socket.set-hop-limit: func

    Params
    Return values
    -

    [method]tcp-socket.receive-buffer-size: func

    +

    [method]tcp-socket.receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2749,42 +2748,42 @@ I.e. after setting a value, reading the same setting back may return a different

    Params
    Return values
    -

    [method]tcp-socket.set-receive-buffer-size: func

    +

    [method]tcp-socket.set-receive-buffer-size: func

    Params
    Return values
    -

    [method]tcp-socket.send-buffer-size: func

    +

    [method]tcp-socket.send-buffer-size: func

    Params
    Return values
    -

    [method]tcp-socket.set-send-buffer-size: func

    +

    [method]tcp-socket.set-send-buffer-size: func

    Params
    Return values
    -

    [method]tcp-socket.subscribe: func

    +

    [method]tcp-socket.subscribe: func

    Create a pollable which can be used to poll for, or block on, completion of any of the asynchronous operations of this socket.

    When finish-bind, finish-listen, finish-connect or accept @@ -2794,19 +2793,19 @@ their success or failure, after which the method can be retried.

    in progress at the time of calling subscribe (if any). Theoretically, subscribe only has to be called once per socket and can then be (re)used for the remainder of the socket's lifetime.

    -

    See https://github.com/WebAssembly/wasi-sockets/TcpSocketOperationalSemantics.md#Pollable-readiness -for a more information.

    +

    See https://github.com/WebAssembly/wasi-sockets/blob/main/TcpSocketOperationalSemantics.md#pollable-readiness +for more information.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    [method]tcp-socket.shutdown: func

    +

    [method]tcp-socket.shutdown: func

    Initiate a graceful shutdown.

    • receive: The socket is not expecting to receive any data from @@ -2817,7 +2816,7 @@ this method will be discarded.
    • associated with this socket will be closed and a FIN packet will be sent.
    • both: Same effect as receive & send combined.
    -

    This function is idempotent. Shutting a down a direction more than once +

    This function is idempotent; shutting down a direction more than once has no effect and returns ok.

    The shutdown function does not close (drop) the socket.

    Typical errors

    @@ -2833,31 +2832,31 @@ has no effect and returns ok.

    Params
    Return values
    -

    Import interface wasi:sockets/tcp-create-socket@0.2.0

    +

    Import interface wasi:sockets/tcp-create-socket@0.2.0


    Types

    -

    type network

    +

    type network

    network

    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

    -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `type tcp-socket` +#### `type tcp-socket` [`tcp-socket`](#tcp_socket)

    ----

    Functions

    -

    create-tcp-socket: func

    +

    create-tcp-socket: func

    Create a new TCP socket.

    Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX. On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

    @@ -2879,31 +2878,31 @@ is called, the socket is effectively an in-memory configuration object, unable t
    Params
    Return values
    -

    Import interface wasi:sockets/ip-name-lookup@0.2.0

    +

    Import interface wasi:sockets/ip-name-lookup@0.2.0


    Types

    -

    type pollable

    +

    type pollable

    pollable

    -#### `type network` +#### `type network` [`network`](#network)

    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

    -#### `type ip-address` +#### `type ip-address` [`ip-address`](#ip_address)

    -#### `resource resolve-address-stream` +#### `resource resolve-address-stream`


    Functions

    -

    resolve-addresses: func

    +

    resolve-addresses: func

    Resolve an internet host name to a list of IP addresses.

    Unicode domain names are automatically converted to ASCII using IDNA encoding. If the input is an IP address string, the address is parsed and returned @@ -2925,14 +2924,14 @@ to (asynchronously) fetch the results.

    Params
    Return values
    -

    [method]resolve-address-stream.resolve-next-address: func

    +

    [method]resolve-address-stream.resolve-next-address: func

    Returns the next address from the resolver.

    This function should be called multiple times. On each call, it will return the next address in connection order preference. If all @@ -2947,31 +2946,31 @@ addresses have been exhausted, this function returns none.

    Params
    Return values
    -

    [method]resolve-address-stream.subscribe: func

    +

    [method]resolve-address-stream.subscribe: func

    Create a pollable which will resolve once the stream is ready for I/O.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    Import interface wasi:random/random@0.2.0

    +

    Import interface wasi:random/random@0.2.0

    WASI Random is a random data API.

    It is intended to be portable at least between Unix-family platforms and Windows.


    Functions

    -

    get-random-bytes: func

    +

    get-random-bytes: func

    Return len cryptographically-secure random or pseudo-random bytes.

    This function must produce data at least as cryptographically secure and fast as an adequately seeded cryptographically-secure pseudo-random @@ -2984,13 +2983,13 @@ must omit this function, rather than implementing it with deterministic data.

    Params
      -
    • len: u64
    • +
    • len: u64
    Return values
    • list<u8>
    -

    get-random-u64: func

    +

    get-random-u64: func

    Return a cryptographically-secure random or pseudo-random u64 value.

    This function returns the same type of data as get-random-bytes, represented as a u64.

    @@ -2998,13 +2997,13 @@ represented as a u64.

    • u64
    -

    Import interface wasi:random/insecure@0.2.0

    +

    Import interface wasi:random/insecure@0.2.0

    The insecure interface for insecure pseudo-random numbers.

    It is intended to be portable at least between Unix-family platforms and Windows.


    Functions

    -

    get-insecure-random-bytes: func

    +

    get-insecure-random-bytes: func

    Return len insecure pseudo-random bytes.

    This function is not cryptographically secure. Do not use it for anything related to security.

    @@ -3013,13 +3012,13 @@ implementations are encouraged to return evenly distributed values with a long period.

    Params
      -
    • len: u64
    • +
    • len: u64
    Return values
    • list<u8>
    -

    get-insecure-random-u64: func

    +

    get-insecure-random-u64: func

    Return an insecure pseudo-random u64 value.

    This function returns the same type of pseudo-random data as get-insecure-random-bytes, represented as a u64.

    @@ -3027,13 +3026,13 @@ a long period.

    • u64
    -

    Import interface wasi:random/insecure-seed@0.2.0

    +

    Import interface wasi:random/insecure-seed@0.2.0

    The insecure-seed interface for seeding hash-map DoS resistance.

    It is intended to be portable at least between Unix-family platforms and Windows.


    Functions

    -

    insecure-seed: func

    +

    insecure-seed: func

    Return a 128-bit value that may contain a pseudo-random value.

    The returned value is not required to be computed from a CSPRNG, and may even be entirely deterministic. Host implementations are encouraged to diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index 704339a11..8660c85a4 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,24 +1,24 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "468b4d12892fe926b8eb5d398dbf579d566c93231fa44f415440572c695b7613" -sha512 = "e6b53a07221f1413953c9797c68f08b815fdaebf66419bbc1ea3e8b7dece73731062693634731f311a03957b268cf9cc509c518bd15e513c318aa04a8459b93a" +sha256 = "f27a857de70c1b0dfbabda35812a8de1253089623b1a84ddd066183c6ffac5f8" +sha512 = "9df1b0be1e4925f671fda65d433217798404f8e2e4fa60ff8bfdfd257f0b6d212ea350c141f308cf4cc57fb0b44899b14af1f9af97a05dcd6f8ae00a7594de8d" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "498c465cfd04587db40f970fff2185daa597d074c20b68a8bcbae558f261499b" -sha512 = "ead452f9b7bfb88593a502ec00d76d4228003d51c40fd0408aebc32d35c94673551b00230d730873361567cc209ec218c41fb4e95bad194268592c49e7964347" +sha256 = "e37bda5e27222621771ba07d2e9daf862a728c31f91024badfc4f9a42c9ae8ee" +sha512 = "81e92f5e4eca0c8f9606f26a1c4eebb3c53a708b57d3f7e7c60e97aa3c18794b72a44c39212de566442e25313b5ccb5b0b7c9070f3600f0c7c584ea9db91e207" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "7210e5653539a15478f894d4da24cc69d61924cbcba21d2804d69314a88e5a4c" -sha512 = "49184a1b0945a889abd52d25271172ed3dc2db6968fcdddb1bab7ee0081f4a3eeee0977ad2291126a37631c0d86eeea75d822fa8af224c422134500bf9f0f2bb" +sha256 = "f3e976740ed9512674c627c6588864c477a9ff539bb7e55c7b9ceab222399b52" +sha512 = "c785122b4c04e2297e3fa37ae76c149b0a681444da106758cf673023923b69a6b2c65624ffbb6ad31edef02f9fbc677b05c89525f07b1159fe0c997a8c6b1a8f" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "7371d03c037d924caba2587fb2e7c5773a0d3c5fcecbf7971e0e0ba57973c53d" -sha512 = "964c4e8925a53078e4d94ba907b54f89a0b7e154f46823a505391471466c17f53c8692682e5c85771712acd88b348686173fc07c53a3cfe3d301b8cd8ddd0de4" +sha256 = "2f0014e946e38947afe120836b17cdcfa608be993d38d55b81cc2d31e7e70b16" +sha512 = "51ee623509040de77b0ba236e29589102538aacd3dd67168b06a09bf6ae469c762818fc07b5039d2a8b1838f4b5a5965a7c81ed0e2d47b142bece9d1ab8b93a6" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "622bd28bbeb43736375dc02bd003fd3a016ff8ee91e14bab488325c6b38bf966" -sha512 = "5a63c1f36de0c4548e1d2297bdbededb28721cbad94ef7825c469eae29d7451c97e00b4c1d6730ee1ec0c4a5aac922961a2795762d4a0c3bb54e30a391a84bae" +sha256 = "5321ba37115d503bfe0880349e99ecbd26ee812708fa83d2b276ec8ee7571443" +sha512 = "c3d71c2afa1475bf10d86b1e0623e2292e5dd407cf54103ad0d05c07fa95323bff9ad06e929d508b318a0a99a67132793fb9a04c17585843e24f090f5ee91367" diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index 4e4dc3a19..cae2363bf 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -7,38 +7,43 @@ package wasi:clocks@0.2.0; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -/// -/// It is intended for measuring elapsed time. +@since(version = 0.2.0) interface monotonic-clock { + @since(version = 0.2.0) use wasi:io/poll@0.2.0.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. + @since(version = 0.2.0) type instant = u64; /// A duration of time, in nanoseconds. + @since(version = 0.2.0) type duration = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + @since(version = 0.2.0) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. + @since(version = 0.2.0) resolution: func() -> duration; /// Create a `pollable` which will resolve once the specified instant - /// occured. + /// has occured. + @since(version = 0.2.0) subscribe-instant: func( when: instant, ) -> pollable; - /// Create a `pollable` which will resolve once the given duration has - /// elapsed, starting at the time at which this function was called. - /// occured. + /// Create a `pollable` that will resolve after the specified duration has + /// elapsed from the time this function is invoked. + @since(version = 0.2.0) subscribe-duration: func( when: duration, ) -> pollable; diff --git a/proposals/cli/wit/deps/clocks/timezone.wit b/proposals/cli/wit/deps/clocks/timezone.wit new file mode 100644 index 000000000..3c286889e --- /dev/null +++ b/proposals/cli/wit/deps/clocks/timezone.wit @@ -0,0 +1,55 @@ +package wasi:clocks@0.2.0; + +@unstable(feature = clocks-timezone) +interface timezone { + @unstable(feature = clocks-timezone) + use wall-clock.{datetime}; + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + @unstable(feature = clocks-timezone) + display: func(when: datetime) -> timezone-display; + + /// The same as `display`, but only return the UTC offset. + @unstable(feature = clocks-timezone) + utc-offset: func(when: datetime) -> s32; + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + @unstable(feature = clocks-timezone) + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit index 440ca0f33..4b08d71ee 100644 --- a/proposals/cli/wit/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -13,8 +13,10 @@ package wasi:clocks@0.2.0; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. +@since(version = 0.2.0) interface wall-clock { /// A time and date in seconds plus nanoseconds. + @since(version = 0.2.0) record datetime { seconds: u64, nanoseconds: u32, @@ -33,10 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + @since(version = 0.2.0) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. + @since(version = 0.2.0) resolution: func() -> datetime; } diff --git a/proposals/cli/wit/deps/clocks/world.wit b/proposals/cli/wit/deps/clocks/world.wit index c0224572a..76a9206c5 100644 --- a/proposals/cli/wit/deps/clocks/world.wit +++ b/proposals/cli/wit/deps/clocks/world.wit @@ -1,6 +1,11 @@ package wasi:clocks@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import monotonic-clock; + @since(version = 0.2.0) import wall-clock; + @unstable(feature = clocks-timezone) + import timezone; } diff --git a/proposals/cli/wit/deps/filesystem/preopens.wit b/proposals/cli/wit/deps/filesystem/preopens.wit index da801f6d6..08094ab3f 100644 --- a/proposals/cli/wit/deps/filesystem/preopens.wit +++ b/proposals/cli/wit/deps/filesystem/preopens.wit @@ -1,8 +1,11 @@ package wasi:filesystem@0.2.0; +@since(version = 0.2.0) interface preopens { + @since(version = 0.2.0) use types.{descriptor}; /// Return the set of preopened directories, and their path. + @since(version = 0.2.0) get-directories: func() -> list>; } diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index 11108fcda..4900ae2c4 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -23,16 +23,21 @@ package wasi:filesystem@0.2.0; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md +@since(version = 0.2.0) interface types { + @since(version = 0.2.0) use wasi:io/streams@0.2.0.{input-stream, output-stream, error}; + @since(version = 0.2.0) use wasi:clocks/wall-clock@0.2.0.{datetime}; /// File size or length of a region within a file. + @since(version = 0.2.0) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. + @since(version = 0.2.0) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -56,6 +61,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. + @since(version = 0.2.0) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -99,6 +105,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. + @since(version = 0.2.0) record descriptor-stat { /// File type. %type: descriptor-type, @@ -125,6 +132,7 @@ interface types { } /// Flags determining the method of how paths are resolved. + @since(version = 0.2.0) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -132,6 +140,7 @@ interface types { } /// Open flags used by `open-at`. + @since(version = 0.2.0) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -144,9 +153,11 @@ interface types { } /// Number of hard links to an inode. + @since(version = 0.2.0) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. + @since(version = 0.2.0) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -248,6 +259,7 @@ interface types { } /// File or memory access pattern advisory information. + @since(version = 0.2.0) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -271,6 +283,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. + @since(version = 0.2.0) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -281,6 +294,7 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. + @since(version = 0.2.0) resource descriptor { /// Return a stream for reading from a file, if available. /// @@ -290,6 +304,7 @@ interface types { /// file and they do not interfere with each other. /// /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. + @since(version = 0.2.0) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, @@ -301,6 +316,7 @@ interface types { /// /// Note: This allows using `write-stream`, which is similar to `write` in /// POSIX. + @since(version = 0.2.0) write-via-stream: func( /// The offset within the file at which to start writing. offset: filesize, @@ -312,11 +328,13 @@ interface types { /// /// Note: This allows using `write-stream`, which is similar to `write` with /// `O_APPEND` in in POSIX. + @since(version = 0.2.0) append-via-stream: func() -> result; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. + @since(version = 0.2.0) advise: func( /// The offset within the file to which the advisory applies. offset: filesize, @@ -332,6 +350,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. + @since(version = 0.2.0) sync-data: func() -> result<_, error-code>; /// Get flags associated with a descriptor. @@ -340,6 +359,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. + @since(version = 0.2.0) get-flags: func() -> result; /// Get the dynamic type of a descriptor. @@ -352,12 +372,14 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. + @since(version = 0.2.0) get-type: func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. + @since(version = 0.2.0) set-size: func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. @@ -365,6 +387,7 @@ interface types { /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. + @since(version = 0.2.0) set-times: func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, @@ -383,6 +406,7 @@ interface types { /// In the future, this may change to return a `stream`. /// /// Note: This is similar to `pread` in POSIX. + @since(version = 0.2.0) read: func( /// The maximum number of bytes to read. length: filesize, @@ -399,6 +423,7 @@ interface types { /// In the future, this may change to take a `stream`. /// /// Note: This is similar to `pwrite` in POSIX. + @since(version = 0.2.0) write: func( /// Data to write buffer: list, @@ -415,6 +440,7 @@ interface types { /// This always returns a new stream which starts at the beginning of the /// directory. Multiple streams may be active on the same directory, and they /// do not interfere with each other. + @since(version = 0.2.0) read-directory: func() -> result; /// Synchronize the data and metadata of a file to disk. @@ -423,11 +449,13 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. + @since(version = 0.2.0) sync: func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. + @since(version = 0.2.0) create-directory-at: func( /// The relative path at which to create the directory. path: string, @@ -442,6 +470,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. + @since(version = 0.2.0) stat: func() -> result; /// Return the attributes of a file or directory. @@ -451,6 +480,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. + @since(version = 0.2.0) stat-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -464,6 +494,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. + @since(version = 0.2.0) set-times-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -478,6 +509,7 @@ interface types { /// Create a hard link. /// /// Note: This is similar to `linkat` in POSIX. + @since(version = 0.2.0) link-at: func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, @@ -507,6 +539,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. + @since(version = 0.2.0) open-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -524,6 +557,7 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. + @since(version = 0.2.0) readlink-at: func( /// The relative path of the symbolic link from which to read. path: string, @@ -534,6 +568,7 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + @since(version = 0.2.0) remove-directory-at: func( /// The relative path to a directory to remove. path: string, @@ -542,6 +577,7 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. + @since(version = 0.2.0) rename-at: func( /// The relative source path of the file or directory to rename. old-path: string, @@ -557,6 +593,7 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. + @since(version = 0.2.0) symlink-at: func( /// The contents of the symbolic link. old-path: string, @@ -568,6 +605,7 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + @since(version = 0.2.0) unlink-file-at: func( /// The relative path to a file to unlink. path: string, @@ -579,6 +617,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. + @since(version = 0.2.0) is-same-object: func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred @@ -600,12 +639,14 @@ interface types { /// computed hash. /// /// However, none of these is required. + @since(version = 0.2.0) metadata-hash: func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. + @since(version = 0.2.0) metadata-hash-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -615,8 +656,10 @@ interface types { } /// A stream of directory entries. + @since(version = 0.2.0) resource directory-entry-stream { /// Read a single directory entry from a `directory-entry-stream`. + @since(version = 0.2.0) read-directory-entry: func() -> result, error-code>; } @@ -630,5 +673,6 @@ interface types { /// /// Note that this function is fallible because not all stream-related /// errors are filesystem-related errors. + @since(version = 0.2.0) filesystem-error-code: func(err: borrow) -> option; } diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit index 663f57920..c8d99f56e 100644 --- a/proposals/cli/wit/deps/filesystem/world.wit +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -1,6 +1,9 @@ package wasi:filesystem@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import types; + @since(version = 0.2.0) import preopens; } diff --git a/proposals/cli/wit/deps/io/error.wit b/proposals/cli/wit/deps/io/error.wit index 22e5b6489..7e66dbba2 100644 --- a/proposals/cli/wit/deps/io/error.wit +++ b/proposals/cli/wit/deps/io/error.wit @@ -1,6 +1,6 @@ package wasi:io@0.2.0; - +@since(version = 0.2.0) interface error { /// A resource which represents some error information. /// @@ -11,16 +11,15 @@ interface error { /// `wasi:io/streams/stream-error` type. /// /// To provide more specific error information, other interfaces may - /// provide functions to further "downcast" this error into more specific - /// error information. For example, `error`s returned in streams derived - /// from filesystem types to be described using the filesystem's own - /// error-code type, using the function - /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter - /// `borrow` and returns - /// `option`. + /// offer functions to "downcast" this error into more specific types. For example, + /// errors returned from streams derived from filesystem types can be described using + /// the filesystem's own error-code type. This is done using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a `borrow` + /// parameter and returns an `option`. /// /// The set of functions which can "downcast" an `error` into a more /// concrete type is open. + @since(version = 0.2.0) resource error { /// Returns a string that is suitable to assist humans in debugging /// this error. @@ -29,6 +28,7 @@ interface error { /// It may change across platforms, hosts, or other implementation /// details. Parsing this string is a major platform-compatibility /// hazard. + @since(version = 0.2.0) to-debug-string: func() -> string; } } diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit index ddc67f8b7..cbdc960f0 100644 --- a/proposals/cli/wit/deps/io/poll.wit +++ b/proposals/cli/wit/deps/io/poll.wit @@ -2,13 +2,16 @@ package wasi:io@0.2.0; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. +@since(version = 0.2.0) interface poll { /// `pollable` represents a single I/O event which may be ready, or not. + @since(version = 0.2.0) resource pollable { /// Return the readiness of a pollable. This function never blocks. /// /// Returns `true` when the pollable is ready, and `false` otherwise. + @since(version = 0.2.0) ready: func() -> bool; /// `block` returns immediately if the pollable is ready, and otherwise @@ -16,6 +19,7 @@ interface poll { /// /// This function is equivalent to calling `poll.poll` on a list /// containing only this pollable. + @since(version = 0.2.0) block: func(); } @@ -27,8 +31,9 @@ interface poll { /// The result `list` contains one or more indices of handles in the /// argument list that is ready for I/O. /// - /// If the list contains more elements than can be indexed with a `u32` - /// value, this function traps. + /// This function traps if either: + /// - the list is empty, or: + /// - the list contains more elements than can be indexed with a `u32` value. /// /// A timeout can be implemented by adding a pollable from the /// wasi-clocks API to the list. @@ -36,6 +41,7 @@ interface poll { /// This function does not return a `result`; polling in itself does not /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as - /// being reaedy for I/O. + /// being ready for I/O. + @since(version = 0.2.0) poll: func(in: list>) -> list; } diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index 6d2f871e3..a57f20439 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -5,11 +5,15 @@ package wasi:io@0.2.0; /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. +@since(version = 0.2.0) interface streams { + @since(version = 0.2.0) use error.{error}; + @since(version = 0.2.0) use poll.{pollable}; /// An error for input-stream and output-stream operations. + @since(version = 0.2.0) variant stream-error { /// The last operation (a write or flush) failed before completion. /// @@ -29,6 +33,7 @@ interface streams { /// available, which could even be zero. To wait for data to be available, /// use the `subscribe` function to obtain a `pollable` which can be polled /// for using `wasi:io/poll`. + @since(version = 0.2.0) resource input-stream { /// Perform a non-blocking read from the stream. /// @@ -56,6 +61,7 @@ interface streams { /// is not possible to allocate in wasm32, or not desirable to allocate as /// as a return value by the callee. The callee may return a list of bytes /// less than `len` in size while more bytes are available for reading. + @since(version = 0.2.0) read: func( /// The maximum number of bytes to read len: u64 @@ -63,6 +69,7 @@ interface streams { /// Read bytes from a stream, after blocking until at least one byte can /// be read. Except for blocking, behavior is identical to `read`. + @since(version = 0.2.0) blocking-read: func( /// The maximum number of bytes to read len: u64 @@ -72,6 +79,7 @@ interface streams { /// /// Behaves identical to `read`, except instead of returning a list /// of bytes, returns the number of bytes consumed from the stream. + @since(version = 0.2.0) skip: func( /// The maximum number of bytes to skip. len: u64, @@ -79,6 +87,7 @@ interface streams { /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. + @since(version = 0.2.0) blocking-skip: func( /// The maximum number of bytes to skip. len: u64, @@ -90,6 +99,7 @@ interface streams { /// The created `pollable` is a child resource of the `input-stream`. /// Implementations may trap if the `input-stream` is dropped before /// all derived `pollable`s created with this function are dropped. + @since(version = 0.2.0) subscribe: func() -> pollable; } @@ -102,6 +112,7 @@ interface streams { /// promptly, which could even be zero. To wait for the stream to be ready to /// accept data, the `subscribe` function to obtain a `pollable` which can be /// polled for using `wasi:io/poll`. + @since(version = 0.2.0) resource output-stream { /// Check readiness for writing. This function never blocks. /// @@ -112,6 +123,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. + @since(version = 0.2.0) check-write: func() -> result; /// Perform a write. This function never blocks. @@ -127,6 +139,7 @@ interface streams { /// /// returns Err(closed) without writing if the stream has closed since /// the last call to check-write provided a permit. + @since(version = 0.2.0) write: func( contents: list ) -> result<_, stream-error>; @@ -155,6 +168,7 @@ interface streams { /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` + @since(version = 0.2.0) blocking-write-and-flush: func( contents: list ) -> result<_, stream-error>; @@ -169,10 +183,12 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. + @since(version = 0.2.0) flush: func() -> result<_, stream-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. + @since(version = 0.2.0) blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream @@ -193,6 +209,7 @@ interface streams { /// preconditions (must use check-write first), but instead of /// passing a list of bytes, you simply pass the number of zero-bytes /// that should be written. + @since(version = 0.2.0) write-zeroes: func( /// The number of zero-bytes to write len: u64 @@ -222,6 +239,7 @@ interface streams { /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` + @since(version = 0.2.0) blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 @@ -240,6 +258,7 @@ interface streams { /// /// This function returns the number of bytes transferred; it may be less /// than `len`. + @since(version = 0.2.0) splice: func( /// The stream to read from src: borrow, @@ -252,6 +271,7 @@ interface streams { /// This is similar to `splice`, except that it blocks until the /// `output-stream` is ready for writing, and the `input-stream` /// is ready for reading, before performing the `splice`. + @since(version = 0.2.0) blocking-splice: func( /// The stream to read from src: borrow, diff --git a/proposals/cli/wit/deps/io/world.wit b/proposals/cli/wit/deps/io/world.wit index 5f0b43fe5..f5c098793 100644 --- a/proposals/cli/wit/deps/io/world.wit +++ b/proposals/cli/wit/deps/io/world.wit @@ -1,6 +1,10 @@ package wasi:io@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import streams; + + @since(version = 0.2.0) import poll; } diff --git a/proposals/cli/wit/deps/random/insecure-seed.wit b/proposals/cli/wit/deps/random/insecure-seed.wit index 47210ac6b..4cce62858 100644 --- a/proposals/cli/wit/deps/random/insecure-seed.wit +++ b/proposals/cli/wit/deps/random/insecure-seed.wit @@ -3,6 +3,7 @@ package wasi:random@0.2.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +@since(version = 0.2.0) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -21,5 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. + @since(version = 0.2.0) insecure-seed: func() -> tuple; } diff --git a/proposals/cli/wit/deps/random/insecure.wit b/proposals/cli/wit/deps/random/insecure.wit index c58f4ee85..3cea0c4a6 100644 --- a/proposals/cli/wit/deps/random/insecure.wit +++ b/proposals/cli/wit/deps/random/insecure.wit @@ -3,6 +3,7 @@ package wasi:random@0.2.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +@since(version = 0.2.0) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -12,11 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. + @since(version = 0.2.0) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. + @since(version = 0.2.0) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index 0c017f093..41c3a0367 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -3,6 +3,7 @@ package wasi:random@0.2.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +@since(version = 0.2.0) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -16,11 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. + @since(version = 0.2.0) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. + @since(version = 0.2.0) get-random-u64: func() -> u64; } diff --git a/proposals/cli/wit/deps/random/world.wit b/proposals/cli/wit/deps/random/world.wit index 3da34914a..b5560a67a 100644 --- a/proposals/cli/wit/deps/random/world.wit +++ b/proposals/cli/wit/deps/random/world.wit @@ -1,7 +1,13 @@ package wasi:random@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import random; + + @since(version = 0.2.0) import insecure; + + @since(version = 0.2.0) import insecure-seed; } diff --git a/proposals/cli/wit/deps/sockets/instance-network.wit b/proposals/cli/wit/deps/sockets/instance-network.wit index e455d0ff7..5f6e6c1cc 100644 --- a/proposals/cli/wit/deps/sockets/instance-network.wit +++ b/proposals/cli/wit/deps/sockets/instance-network.wit @@ -1,9 +1,11 @@ /// This interface provides a value-export of the default network handle.. +@since(version = 0.2.0) interface instance-network { + @since(version = 0.2.0) use network.{network}; /// Get a handle to the default network. + @since(version = 0.2.0) instance-network: func() -> network; - } diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index 8e639ec59..0368b4801 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,9 +1,10 @@ - +@since(version = 0.2.0) interface ip-name-lookup { + @since(version = 0.2.0) use wasi:io/poll@0.2.0.{pollable}; + @since(version = 0.2.0) use network.{network, error-code, ip-address}; - /// Resolve an internet host name to a list of IP addresses. /// /// Unicode domain names are automatically converted to ASCII using IDNA encoding. @@ -24,8 +25,10 @@ interface ip-name-lookup { /// - /// - /// - + @since(version = 0.2.0) resolve-addresses: func(network: borrow, name: string) -> result; + @since(version = 0.2.0) resource resolve-address-stream { /// Returns the next address from the resolver. /// @@ -40,12 +43,14 @@ interface ip-name-lookup { /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) + @since(version = 0.2.0) resolve-next-address: func() -> result, error-code>; /// Create a `pollable` which will resolve once the stream is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } } diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit index 9cadf0650..8c13b348e 100644 --- a/proposals/cli/wit/deps/sockets/network.wit +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -1,8 +1,9 @@ - +@since(version = 0.2.0) interface network { /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. + @since(version = 0.2.0) resource network; /// Error codes. @@ -17,6 +18,7 @@ interface network { /// - `concurrency-conflict` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. + @since(version = 0.2.0) enum error-code { /// Unknown error unknown, @@ -103,6 +105,7 @@ interface network { permanent-resolver-failure, } + @since(version = 0.2.0) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -111,14 +114,18 @@ interface network { ipv6, } + @since(version = 0.2.0) type ipv4-address = tuple; + @since(version = 0.2.0) type ipv6-address = tuple; + @since(version = 0.2.0) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } + @since(version = 0.2.0) record ipv4-socket-address { /// sin_port port: u16, @@ -126,6 +133,7 @@ interface network { address: ipv4-address, } + @since(version = 0.2.0) record ipv6-socket-address { /// sin6_port port: u16, @@ -137,9 +145,9 @@ interface network { scope-id: u32, } + @since(version = 0.2.0) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), } - } diff --git a/proposals/cli/wit/deps/sockets/tcp-create-socket.wit b/proposals/cli/wit/deps/sockets/tcp-create-socket.wit index c7ddf1f22..eedbd3076 100644 --- a/proposals/cli/wit/deps/sockets/tcp-create-socket.wit +++ b/proposals/cli/wit/deps/sockets/tcp-create-socket.wit @@ -1,6 +1,8 @@ - +@since(version = 0.2.0) interface tcp-create-socket { + @since(version = 0.2.0) use network.{network, error-code, ip-address-family}; + @since(version = 0.2.0) use tcp.{tcp-socket}; /// Create a new TCP socket. @@ -23,5 +25,6 @@ interface tcp-create-socket { /// - /// - /// - + @since(version = 0.2.0) create-tcp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index 5902b9ee0..e4a62101b 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -1,10 +1,15 @@ - +@since(version = 0.2.0) interface tcp { + @since(version = 0.2.0) use wasi:io/streams@0.2.0.{input-stream, output-stream}; + @since(version = 0.2.0) use wasi:io/poll@0.2.0.{pollable}; + @since(version = 0.2.0) use wasi:clocks/monotonic-clock@0.2.0.{duration}; + @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; + @since(version = 0.2.0) enum shutdown-type { /// Similar to `SHUT_RD` in POSIX. receive, @@ -27,8 +32,8 @@ interface tcp { /// - `connect-in-progress` /// - `connected` /// - `closed` - /// See - /// for a more information. + /// See + /// for more information. /// /// Note: Except where explicitly mentioned, whenever this documentation uses /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. @@ -37,6 +42,7 @@ interface tcp { /// In addition to the general error codes documented on the /// `network::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. + @since(version = 0.2.0) resource tcp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -76,13 +82,15 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) finish-bind: func() -> result<_, error-code>; /// Connect to a remote endpoint. /// /// On success: - /// - the socket is transitioned into the `connection` state. + /// - the socket is transitioned into the `connected` state. /// - a pair of streams is returned that can be used to read & write to the connection /// /// After a failed connection attempt, the socket will be in the `closed` @@ -121,7 +129,9 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) finish-connect: func() -> result, error-code>; /// Start listening for new connections. @@ -149,7 +159,9 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) start-listen: func() -> result<_, error-code>; + @since(version = 0.2.0) finish-listen: func() -> result<_, error-code>; /// Accept a new client socket. @@ -178,6 +190,7 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) accept: func() -> result, error-code>; /// Get the bound local address. @@ -196,6 +209,7 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) local-address: func() -> result; /// Get the remote address. @@ -208,16 +222,19 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. + @since(version = 0.2.0) is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.2.0) address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. @@ -229,6 +246,7 @@ interface tcp { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. + @since(version = 0.2.0) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -240,7 +258,9 @@ interface tcp { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. + @since(version = 0.2.0) keep-alive-enabled: func() -> result; + @since(version = 0.2.0) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. @@ -253,7 +273,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) keep-alive-idle-time: func() -> result; + @since(version = 0.2.0) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. @@ -266,7 +288,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) keep-alive-interval: func() -> result; + @since(version = 0.2.0) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. @@ -279,7 +303,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) keep-alive-count: func() -> result; + @since(version = 0.2.0) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -288,7 +314,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.2.0) hop-limit: func() -> result; + @since(version = 0.2.0) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -301,9 +329,13 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) receive-buffer-size: func() -> result; + @since(version = 0.2.0) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) send-buffer-size: func() -> result; + @since(version = 0.2.0) set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Create a `pollable` which can be used to poll for, or block on, @@ -318,11 +350,12 @@ interface tcp { /// `subscribe` only has to be called once per socket and can then be /// (re)used for the remainder of the socket's lifetime. /// - /// See - /// for a more information. + /// See + /// for more information. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; /// Initiate a graceful shutdown. @@ -335,7 +368,7 @@ interface tcp { /// associated with this socket will be closed and a FIN packet will be sent. /// - `both`: Same effect as `receive` & `send` combined. /// - /// This function is idempotent. Shutting a down a direction more than once + /// This function is idempotent; shutting down a direction more than once /// has no effect and returns `ok`. /// /// The shutdown function does not close (drop) the socket. @@ -348,6 +381,7 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; } } diff --git a/proposals/cli/wit/deps/sockets/udp-create-socket.wit b/proposals/cli/wit/deps/sockets/udp-create-socket.wit index 0482d1fe7..e8eeacbfe 100644 --- a/proposals/cli/wit/deps/sockets/udp-create-socket.wit +++ b/proposals/cli/wit/deps/sockets/udp-create-socket.wit @@ -1,6 +1,8 @@ - +@since(version = 0.2.0) interface udp-create-socket { + @since(version = 0.2.0) use network.{network, error-code, ip-address-family}; + @since(version = 0.2.0) use udp.{udp-socket}; /// Create a new UDP socket. @@ -23,5 +25,6 @@ interface udp-create-socket { /// - /// - /// - + @since(version = 0.2.0) create-udp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index d987a0a90..48e753cac 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,9 +1,12 @@ - +@since(version = 0.2.0) interface udp { + @since(version = 0.2.0) use wasi:io/poll@0.2.0.{pollable}; + @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; /// A received datagram. + @since(version = 0.2.0) record incoming-datagram { /// The payload. /// @@ -19,6 +22,7 @@ interface udp { } /// A datagram to be sent out. + @since(version = 0.2.0) record outgoing-datagram { /// The payload. data: list, @@ -33,9 +37,8 @@ interface udp { remote-address: option, } - - /// A UDP socket handle. + @since(version = 0.2.0) resource udp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -63,7 +66,9 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) finish-bind: func() -> result<_, error-code>; /// Set up inbound & outbound communication channels, optionally to a specific peer. @@ -106,6 +111,7 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) %stream: func(remote-address: option) -> result, error-code>; /// Get the current bound address. @@ -124,6 +130,7 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) local-address: func() -> result; /// Get the address the socket is currently streaming to. @@ -136,11 +143,13 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.2.0) address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -149,7 +158,9 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.2.0) unicast-hop-limit: func() -> result; + @since(version = 0.2.0) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -162,18 +173,24 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) receive-buffer-size: func() -> result; + @since(version = 0.2.0) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) send-buffer-size: func() -> result; + @since(version = 0.2.0) set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Create a `pollable` which will resolve once the socket is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } + @since(version = 0.2.0) resource incoming-datagram-stream { /// Receive messages on the socket. /// @@ -198,15 +215,18 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) receive: func(max-results: u64) -> result, error-code>; /// Create a `pollable` which will resolve once the stream is ready to receive again. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } + @since(version = 0.2.0) resource outgoing-datagram-stream { /// Check readiness for sending. This function never blocks. /// @@ -255,12 +275,14 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) send: func(datagrams: list) -> result; /// Create a `pollable` which will resolve once the stream is ready to send again. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } } diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit index f8bb92ae0..a1f7d14bc 100644 --- a/proposals/cli/wit/deps/sockets/world.wit +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -1,11 +1,19 @@ package wasi:sockets@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import instance-network; + @since(version = 0.2.0) import network; + @since(version = 0.2.0) import udp; + @since(version = 0.2.0) import udp-create-socket; + @since(version = 0.2.0) import tcp; + @since(version = 0.2.0) import tcp-create-socket; + @since(version = 0.2.0) import ip-name-lookup; } From ad6eec27f9e67d1ea365bec86100165e81976d95 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Sun, 14 Jul 2024 00:12:57 +0700 Subject: [PATCH 1464/1772] Fix typos. --- proposals/filesystem/README.md | 6 +++--- proposals/filesystem/imports.md | 2 +- proposals/filesystem/wit/types.wit | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index 9780c6c3b..73dd4d5bd 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -55,7 +55,7 @@ semantics of path lookup, and the semantics of files, directories, and symlinks, and the constraints on filesystem paths, is host-dependent. WASI filesystem is not intended to be used as a virtual API for accessing -arbitary resources. Unix's "everything is a file" philosophy is in conflict +arbitrary resources. Unix's "everything is a file" philosophy is in conflict with the goals of supporting modularity and the principle of least authority. Many of the ideas related to doing capability-based filesystem sandboxing with @@ -94,7 +94,7 @@ fn write_hello_world_to_a_file(dir: Descriptor) -> Result<(), Errno> { while !view.is_empty() { let num_written = file.pwrite(view.to_owned(), 0)?; offset += num_written; - view = &view[num_writen..]; + view = &view[num_written..]; } // The file descriptor is closed when it's dropped! } @@ -141,7 +141,7 @@ case-insensitivity on a case-sensitive filesystem, are both tricky to do. One issue is that case insensitivity depends on a Unicode version, so the details can differ between different case-insensitive platforms. Another -issue is tha WASI filesystem in general can't assume it has exclusive access +issue is the WASI filesystem in general can't assume it has exclusive access to the filesystem, so approaches that involve checking for files with names that differ only by case can race with other processes creating new files. diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index 660858be1..f3e9b7b2a 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -569,7 +569,7 @@ requirement.

  • requested-write-sync:

    -

    Requests that reads be performed at the same level of integrety +

    Requests that reads be performed at the same level of integrity requested for writes. This is similar to `O_RSYNC` in POSIX.

    The precise semantics of this operation have not yet been defined for WASI. At this time, it should be interpreted as a request, and not a diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 4900ae2c4..d061d5fd4 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -83,7 +83,7 @@ interface types { /// WASI. At this time, it should be interpreted as a request, and not a /// requirement. data-integrity-sync, - /// Requests that reads be performed at the same level of integrety + /// Requests that reads be performed at the same level of integrity /// requested for writes. This is similar to `O_RSYNC` in POSIX. /// /// The precise semantics of this operation have not yet been defined for From ba885f50e74c48b2cf0e6af6ea21d72e56c078d8 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Sun, 14 Jul 2024 00:18:36 +0700 Subject: [PATCH 1465/1772] ci: Update `actions/checkout` to v4 --- proposals/filesystem/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index 1b92987e9..e5a958551 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: ensure `./wit/deps` are in sync run: | curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.3/wit-deps-x86_64-unknown-linux-musl From 10ab8ed8847df5998e6e084220f57db36a748467 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Sun, 14 Jul 2024 00:33:02 +0700 Subject: [PATCH 1466/1772] ci: Update `actions/checkout` to v4 --- proposals/http/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index bbd477f43..113cfe9c4 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: ensure `./wit/deps` are in sync run: | curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.2/wit-deps-x86_64-unknown-linux-musl From 64e014047dc839c856ed190a39409a861c72026b Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Sun, 14 Jul 2024 00:42:11 +0700 Subject: [PATCH 1467/1772] ci: Update `actions/checkout` to v4 --- proposals/random/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index 293e49214..77fabf7a8 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -10,5 +10,5 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: WebAssembly/wit-abi-up-to-date@v21 From 34f924d4895370732e5a4162f30450b457599e1e Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Mon, 15 Jul 2024 23:43:38 +0700 Subject: [PATCH 1468/1772] Fix typos. (#119) --- proposals/http/README.md | 2 +- proposals/http/imports.md | 24 ++++++++++++------------ proposals/http/proxy.md | 24 ++++++++++++------------ proposals/http/wit-0.3.0-draft/types.wit | 12 ++++++------ proposals/http/wit/types.wit | 24 ++++++++++++------------ 5 files changed, 43 insertions(+), 43 deletions(-) diff --git a/proposals/http/README.md b/proposals/http/README.md index 54035f7ee..bfe0572a4 100644 --- a/proposals/http/README.md +++ b/proposals/http/README.md @@ -88,7 +88,7 @@ The `wit/deps` directory contains a live snapshot of the contents of several other WASI proposals upon which this proposal depends. It is automatically updated by running [`wit-deps update`](https://crates.io/crates/wit-deps-cli) in the root directory, which fetches the live contents of the `main` branch of -each proposal. As things stablize, `wit/deps.toml` will be updated to refer to +each proposal. As things stabilize, `wit/deps.toml` will be updated to refer to versioned releases. ### References & acknowledgements diff --git a/proposals/http/imports.md b/proposals/http/imports.md index 605686394..db11f4cef 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -751,7 +751,7 @@ an input-stream and the delivery of tra and ensures that the user of this interface may only be consuming either the body contents or waiting on trailers at any given time.

    resource future-trailers

    -

    Represents a future which may eventaully return trailers, or an error.

    +

    Represents a future which may eventually return trailers, or an error.

    In the case that the incoming HTTP Request or Response did not have any trailers, this future will resolve to the empty set of trailers once the complete Request or Response body has been received.

    @@ -768,12 +768,12 @@ optional trailers) with a static function that consumes the may not write to the body contents after the body has been finished.

    If the user code drops this resource, as opposed to calling the static method finish, the implementation should treat the body as incomplete, -and that an error has occured. The implementation should propogate this +and that an error has occurred. The implementation should propagate this error to the HTTP protocol by whatever means it has available, including: corrupting the body on the wire, aborting the associated Request, or sending a late status code for the Response.

    resource future-incoming-response

    -

    Represents a future which may eventaully return an incoming HTTP +

    Represents a future which may eventually return an incoming HTTP Response, or an error.

    This resource is returned by the wasi:http/outgoing-handler interface to provide the HTTP Response corresponding to the sent Request.

    @@ -909,7 +909,7 @@ list with the same key.

  • list<(field-key, field-value)>
  • [method]fields.clone: func

    -

    Make a deep copy of the Fields. Equivelant in behavior to calling the +

    Make a deep copy of the Fields. Equivalent in behavior to calling the fields constructor on the return value of entries. The resulting fields is mutable.

    Params
    @@ -1120,7 +1120,7 @@ not a syntactically valid uri authority.

    The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

    This headers resource is a child: it must be dropped before the parent -outgoing-request is dropped, or its ownership is transfered to +outgoing-request is dropped, or its ownership is transferred to another component by e.g. outgoing-handler.handle.

    Params
      @@ -1286,7 +1286,7 @@ This function will trap if the input-stream

    [method]future-trailers.subscribe: func

    Returns a pollable which becomes ready when either the trailers have -been received, or an error has occured. When this pollable is ready, +been received, or an error has occurred. When this pollable is ready, the get method will return some.

    Params
      @@ -1297,7 +1297,7 @@ the get method will return some.

    • own<pollable>

    [method]future-trailers.get: func

    -

    Returns the contents of the trailers, or an error which occured, +

    Returns the contents of the trailers, or an error which occurred, once the future is ready.

    The outer option represents future readiness. Users can wait on this option to become some using the subscribe method.

    @@ -1306,7 +1306,7 @@ once. It will be success on the first call in which the outer option is some, and error on subsequent calls.

    The inner result represents that either the HTTP Request or Response body, as well as any trailers, were received successfully, or that an -error occured receiving them. The optional trailers indicates whether +error occurred receiving them. The optional trailers indicates whether or not trailers were present in the body.

    When some trailers are returned by this method, the trailers resource is immutable, and a child. Use of the set, append, or @@ -1362,7 +1362,7 @@ given is not a valid http status code.

    The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

    This headers resource is a child: it must be dropped before the parent -outgoing-request is dropped, or its ownership is transfered to +outgoing-request is dropped, or its ownership is transferred to another component by e.g. outgoing-handler.handle.

    Params
      @@ -1421,7 +1421,7 @@ Content-Length.

    [method]future-incoming-response.subscribe: func

    Returns a pollable which becomes ready when either the Response has -been received, or an error has occured. When this pollable is ready, +been received, or an error has occurred. When this pollable is ready, the get method will return some.

    Params
      @@ -1439,8 +1439,8 @@ the get method will return some.

      once. It will be success on the first call in which the outer option is some, and error on subsequent calls.

      The inner result represents that either the incoming HTTP Response -status and headers have recieved successfully, or that an error -occured. Errors may also occur while consuming the response body, +status and headers have received successfully, or that an error +occurred. Errors may also occur while consuming the response body, but those will be reported by the incoming-body and its output-stream child.

      Params
      diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index f1787e7d0..af5c1933f 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -686,7 +686,7 @@ an input-stream and the delivery of tra and ensures that the user of this interface may only be consuming either the body contents or waiting on trailers at any given time.

      resource future-trailers

      -

      Represents a future which may eventaully return trailers, or an error.

      +

      Represents a future which may eventually return trailers, or an error.

      In the case that the incoming HTTP Request or Response did not have any trailers, this future will resolve to the empty set of trailers once the complete Request or Response body has been received.

      @@ -703,12 +703,12 @@ optional trailers) with a static function that consumes the may not write to the body contents after the body has been finished.

      If the user code drops this resource, as opposed to calling the static method finish, the implementation should treat the body as incomplete, -and that an error has occured. The implementation should propogate this +and that an error has occurred. The implementation should propagate this error to the HTTP protocol by whatever means it has available, including: corrupting the body on the wire, aborting the associated Request, or sending a late status code for the Response.

      resource future-incoming-response

      -

      Represents a future which may eventaully return an incoming HTTP +

      Represents a future which may eventually return an incoming HTTP Response, or an error.

      This resource is returned by the wasi:http/outgoing-handler interface to provide the HTTP Response corresponding to the sent Request.

      @@ -844,7 +844,7 @@ list with the same key.

    • list<(field-key, field-value)>

    [method]fields.clone: func

    -

    Make a deep copy of the Fields. Equivelant in behavior to calling the +

    Make a deep copy of the Fields. Equivalent in behavior to calling the fields constructor on the return value of entries. The resulting fields is mutable.

    Params
    @@ -1055,7 +1055,7 @@ not a syntactically valid uri authority.

    The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

    This headers resource is a child: it must be dropped before the parent -outgoing-request is dropped, or its ownership is transfered to +outgoing-request is dropped, or its ownership is transferred to another component by e.g. outgoing-handler.handle.

    Params
      @@ -1221,7 +1221,7 @@ This function will trap if the input-stream

    [method]future-trailers.subscribe: func

    Returns a pollable which becomes ready when either the trailers have -been received, or an error has occured. When this pollable is ready, +been received, or an error has occurred. When this pollable is ready, the get method will return some.

    Params
      @@ -1232,7 +1232,7 @@ the get method will return some.

    • own<pollable>

    [method]future-trailers.get: func

    -

    Returns the contents of the trailers, or an error which occured, +

    Returns the contents of the trailers, or an error which occurred, once the future is ready.

    The outer option represents future readiness. Users can wait on this option to become some using the subscribe method.

    @@ -1241,7 +1241,7 @@ once. It will be success on the first call in which the outer option is some, and error on subsequent calls.

    The inner result represents that either the HTTP Request or Response body, as well as any trailers, were received successfully, or that an -error occured receiving them. The optional trailers indicates whether +error occurred receiving them. The optional trailers indicates whether or not trailers were present in the body.

    When some trailers are returned by this method, the trailers resource is immutable, and a child. Use of the set, append, or @@ -1297,7 +1297,7 @@ given is not a valid http status code.

    The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

    This headers resource is a child: it must be dropped before the parent -outgoing-request is dropped, or its ownership is transfered to +outgoing-request is dropped, or its ownership is transferred to another component by e.g. outgoing-handler.handle.

    Params
      @@ -1356,7 +1356,7 @@ Content-Length.

    [method]future-incoming-response.subscribe: func

    Returns a pollable which becomes ready when either the Response has -been received, or an error has occured. When this pollable is ready, +been received, or an error has occurred. When this pollable is ready, the get method will return some.

    Params
      @@ -1374,8 +1374,8 @@ the get method will return some.

      once. It will be success on the first call in which the outer option is some, and error on subsequent calls.

      The inner result represents that either the incoming HTTP Response -status and headers have recieved successfully, or that an error -occured. Errors may also occur while consuming the response body, +status and headers have received successfully, or that an error +occurred. Errors may also occur while consuming the response body, but those will be reported by the incoming-body and its output-stream child.

      Params
      diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index e28332939..58c655c2a 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -220,7 +220,7 @@ interface types { /// list with the same key. entries: func() -> list>; - /// Make a deep copy of the Fields. Equivelant in behavior to calling the + /// Make a deep copy of the Fields. Equivalent in behavior to calling the /// `fields` constructor on the return value of `entries`. The resulting /// `fields` is mutable. clone: func() -> fields; @@ -320,7 +320,7 @@ interface types { /// will fail if invoked. /// /// This `request-options` resource is a child: it must be dropped before - /// the parent `request` is dropped, or its ownership is transfered to + /// the parent `request` is dropped, or its ownership is transferred to /// another component by e.g. `handler.handle`. options: func() -> option; @@ -330,14 +330,14 @@ interface types { /// `delete` operations will fail with `header-error.immutable`. /// /// This headers resource is a child: it must be dropped before the parent - /// `request` is dropped, or its ownership is transfered to another + /// `request` is dropped, or its ownership is transferred to another /// component by e.g. `handler.handle`. headers: func() -> headers; /// Get the body associated with the Request, if any. /// /// This body resource is a child: it must be dropped before the parent - /// `request` is dropped, or its ownership is transfered to another + /// `request` is dropped, or its ownership is transferred to another /// component by e.g. `handler.handle`. body: func() -> option; @@ -413,14 +413,14 @@ interface types { /// `delete` operations will fail with `header-error.immutable`. /// /// This headers resource is a child: it must be dropped before the parent - /// `response` is dropped, or its ownership is transfered to another + /// `response` is dropped, or its ownership is transferred to another /// component by e.g. `handler.handle`. headers: func() -> headers; /// Get the body associated with the Response, if any. /// /// This body resource is a child: it must be dropped before the parent - /// `response` is dropped, or its ownership is transfered to another + /// `response` is dropped, or its ownership is transferred to another /// component by e.g. `handler.handle`. body: func() -> option; diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 70cce5526..0ead17884 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -212,7 +212,7 @@ interface types { /// list with the same key. entries: func() -> list>; - /// Make a deep copy of the Fields. Equivelant in behavior to calling the + /// Make a deep copy of the Fields. Equivalent in behavior to calling the /// `fields` constructor on the return value of `entries`. The resulting /// `fields` is mutable. clone: func() -> fields; @@ -317,7 +317,7 @@ interface types { /// `delete` operations will fail with `header-error.immutable`. /// /// This headers resource is a child: it must be dropped before the parent - /// `outgoing-request` is dropped, or its ownership is transfered to + /// `outgoing-request` is dropped, or its ownership is transferred to /// another component by e.g. `outgoing-handler.handle`. headers: func() -> headers; } @@ -433,7 +433,7 @@ interface types { finish: static func(this: incoming-body) -> future-trailers; } - /// Represents a future which may eventaully return trailers, or an error. + /// Represents a future which may eventually return trailers, or an error. /// /// In the case that the incoming HTTP Request or Response did not have any /// trailers, this future will resolve to the empty set of trailers once the @@ -441,11 +441,11 @@ interface types { resource future-trailers { /// Returns a pollable which becomes ready when either the trailers have - /// been received, or an error has occured. When this pollable is ready, + /// been received, or an error has occurred. When this pollable is ready, /// the `get` method will return `some`. subscribe: func() -> pollable; - /// Returns the contents of the trailers, or an error which occured, + /// Returns the contents of the trailers, or an error which occurred, /// once the future is ready. /// /// The outer `option` represents future readiness. Users can wait on this @@ -457,7 +457,7 @@ interface types { /// /// The inner `result` represents that either the HTTP Request or Response /// body, as well as any trailers, were received successfully, or that an - /// error occured receiving them. The optional `trailers` indicates whether + /// error occurred receiving them. The optional `trailers` indicates whether /// or not trailers were present in the body. /// /// When some `trailers` are returned by this method, the `trailers` @@ -490,7 +490,7 @@ interface types { /// `delete` operations will fail with `header-error.immutable`. /// /// This headers resource is a child: it must be dropped before the parent - /// `outgoing-request` is dropped, or its ownership is transfered to + /// `outgoing-request` is dropped, or its ownership is transferred to /// another component by e.g. `outgoing-handler.handle`. headers: func() -> headers; @@ -514,7 +514,7 @@ interface types { /// /// If the user code drops this resource, as opposed to calling the static /// method `finish`, the implementation should treat the body as incomplete, - /// and that an error has occured. The implementation should propogate this + /// and that an error has occurred. The implementation should propagate this /// error to the HTTP protocol by whatever means it has available, /// including: corrupting the body on the wire, aborting the associated /// Request, or sending a late status code for the Response. @@ -546,14 +546,14 @@ interface types { ) -> result<_, error-code>; } - /// Represents a future which may eventaully return an incoming HTTP + /// Represents a future which may eventually return an incoming HTTP /// Response, or an error. /// /// This resource is returned by the `wasi:http/outgoing-handler` interface to /// provide the HTTP Response corresponding to the sent Request. resource future-incoming-response { /// Returns a pollable which becomes ready when either the Response has - /// been received, or an error has occured. When this pollable is ready, + /// been received, or an error has occurred. When this pollable is ready, /// the `get` method will return `some`. subscribe: func() -> pollable; @@ -567,8 +567,8 @@ interface types { /// is `some`, and error on subsequent calls. /// /// The inner `result` represents that either the incoming HTTP Response - /// status and headers have recieved successfully, or that an error - /// occured. Errors may also occur while consuming the response body, + /// status and headers have received successfully, or that an error + /// occurred. Errors may also occur while consuming the response body, /// but those will be reported by the `incoming-body` and its /// `output-stream` child. get: func() -> option>>; From 2a9162d07b324f195aaca7405c22e19812571dfc Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Tue, 16 Jul 2024 00:38:28 +0700 Subject: [PATCH 1469/1772] ci: Update `actions/checkout` to v4 (#73) --- proposals/clocks/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 58d8a1f04..bcb035e69 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: ensure `./wit/deps` are in sync run: | curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.3/wit-deps-x86_64-unknown-linux-musl From b887e54f9b56c14ae774ca16055d53ed0b6af3df Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Tue, 16 Jul 2024 00:38:55 +0700 Subject: [PATCH 1470/1772] Fix typos (#72) --- proposals/clocks/imports.md | 2 +- proposals/clocks/wit/monotonic-clock.wit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index 8b977ac32..b1fefd7b5 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -98,7 +98,7 @@ corresponding to a clock tick.

    subscribe-instant: func

    Create a pollable which will resolve once the specified instant -has occured.

    +has occurred.

    Params
    • when: instant
    • diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index cae2363bf..afbd700e1 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -35,7 +35,7 @@ interface monotonic-clock { resolution: func() -> duration; /// Create a `pollable` which will resolve once the specified instant - /// has occured. + /// has occurred. @since(version = 0.2.0) subscribe-instant: func( when: instant, From d9789a1ea4eb22ddb531d149c05468ff948a16c2 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Tue, 16 Jul 2024 00:44:53 +0700 Subject: [PATCH 1471/1772] Fix typos. (#80) --- proposals/io/README.md | 2 +- proposals/io/imports.md | 4 ++-- proposals/io/wit/streams.wit | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/io/README.md b/proposals/io/README.md index 999de2a07..4dd4464fe 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -49,7 +49,7 @@ types, `input-stream`, and `output-stream`, which support `read` and ### Non-goals - Support for async. That will be addressed in the component-model async - design, where we can have the benefit of tigher integration with language + design, where we can have the benefit of tighter integration with language bindings. - Bidirectional streams. diff --git a/proposals/io/imports.md b/proposals/io/imports.md index dd0c4f2fd..01969c535 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -320,7 +320,7 @@ and stream is ready for writing again.

    [method]output-stream.subscribe: func

    Create a pollable which will resolve once the output-stream -is ready for more writing, or an error has occured. When this +is ready for more writing, or an error has occurred. When this pollable is ready, check-write will return ok(n) with n>0, or an error.

    If the stream is closed, this pollable is always ready immediately.

    @@ -383,7 +383,7 @@ let _ = this.check-write(); // eliding error handling

    [method]output-stream.splice: func

    Read from one stream and write to another.

    -

    The behavior of splice is equivelant to:

    +

    The behavior of splice is equivalent to:

    1. calling check-write on the output-stream
    2. calling read on the input-stream with the smaller of the diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index a57f20439..c93836246 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -192,7 +192,7 @@ interface streams { blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream - /// is ready for more writing, or an error has occured. When this + /// is ready for more writing, or an error has occurred. When this /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an /// error. /// @@ -247,7 +247,7 @@ interface streams { /// Read from one stream and write to another. /// - /// The behavior of splice is equivelant to: + /// The behavior of splice is equivalent to: /// 1. calling `check-write` on the `output-stream` /// 2. calling `read` on the `input-stream` with the smaller of the /// `check-write` permitted length and the `len` provided to `splice` From 6b1f218febf1234fa111fa74ff46ab60606a0521 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Mon, 15 Jul 2024 19:53:13 +0200 Subject: [PATCH 1472/1772] Clarify behavior when dropping an active output-stream (#79) --- proposals/io/imports.md | 7 +++++-- proposals/io/wit/streams.wit | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index 01969c535..b26ca790d 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -133,12 +133,15 @@ use the subscribe function to obtain a po for using wasi:io/poll.

      resource output-stream

      An output bytestream.

      -

      output-streams are non-blocking to the extent practical on +

      output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also always return promptly, after the number of bytes that can be written promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe function to obtain a pollable which can be -polled for using wasi:io/poll.

      +polled for using wasi:io/poll.

      +

      Dropping an output-stream while there's still an active write in +progress may result in the data being lost. Before dropping the stream, +be sure to fully flush your writes.

      Functions

      [method]input-stream.read: func

      Perform a non-blocking read from the stream.

      diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index c93836246..b5e2a36ac 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -112,6 +112,10 @@ interface streams { /// promptly, which could even be zero. To wait for the stream to be ready to /// accept data, the `subscribe` function to obtain a `pollable` which can be /// polled for using `wasi:io/poll`. + /// + /// Dropping an `output-stream` while there's still an active write in + /// progress may result in the data being lost. Before dropping the stream, + /// be sure to fully flush your writes. @since(version = 0.2.0) resource output-stream { /// Check readiness for writing. This function never blocks. From 6cfc67a4e8e33ee079e925e751d8dda3dc61e0a0 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Tue, 16 Jul 2024 17:13:47 +0200 Subject: [PATCH 1473/1772] Specify the casing of field keys and values. --- proposals/http/wit-0.3.0-draft/types.wit | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index 58c655c2a..6a067b819 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -133,6 +133,9 @@ interface types { } /// Field keys are always strings. + /// + /// Field keys should always be treated as case insensitive by the `fields` + /// resource for the purposes of equality checking. type field-key = string; /// Field values should always be ASCII strings. However, in @@ -150,6 +153,11 @@ interface types { /// `request.headers`) might be be immutable. In an immutable fields, the /// `set`, `append`, and `delete` operations will fail with /// `header-error.immutable`. + /// + /// A `fields` resource should store `field-key`s and `field-value`s in their + /// original casing used to construct or mutate the `fields` resource. The `fields` + /// resource should use that original casing when serializing the fields for + /// transport or when returning them from a method. resource fields { /// Construct an empty HTTP Fields. @@ -218,6 +226,9 @@ interface types { /// The outer list represents each key-value pair in the Fields. Keys /// which have multiple values are represented by multiple entries in this /// list with the same key. + /// + /// The keys and values are always returned in the original casing and in + /// the order in which they will be serialized for transport. entries: func() -> list>; /// Make a deep copy of the Fields. Equivalent in behavior to calling the From a7375789b3e374f0cfae2932878e465d3243afab Mon Sep 17 00:00:00 2001 From: Yosh Date: Tue, 28 May 2024 14:25:19 +0200 Subject: [PATCH 1474/1772] Document per-item versions using `@since` gates --- proposals/http/wit/handler.wit | 4 ++ proposals/http/wit/proxy.wit | 10 +++++ proposals/http/wit/types.wit | 76 +++++++++++++++++++++++++++++++++- 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/proposals/http/wit/handler.wit b/proposals/http/wit/handler.wit index a34a0649d..deecce22a 100644 --- a/proposals/http/wit/handler.wit +++ b/proposals/http/wit/handler.wit @@ -1,5 +1,6 @@ /// This interface defines a handler of incoming HTTP Requests. It should /// be exported by components which can respond to HTTP Requests. +@since(version = 0.2.0) interface incoming-handler { use types.{incoming-request, response-outparam}; @@ -13,6 +14,7 @@ interface incoming-handler { /// The implementor of this function must write a response to the /// `response-outparam` before returning, or else the caller will respond /// with an error on its behalf. + @since(version = 0.2.0) handle: func( request: incoming-request, response-out: response-outparam @@ -21,6 +23,7 @@ interface incoming-handler { /// This interface defines a handler of outgoing HTTP Requests. It should be /// imported by components which wish to make HTTP Requests. +@since(version = 0.2.0) interface outgoing-handler { use types.{ outgoing-request, request-options, future-incoming-response, error-code @@ -36,6 +39,7 @@ interface outgoing-handler { /// This function may return an error if the `outgoing-request` is invalid /// or not allowed to be made. Otherwise, protocol errors are reported /// through the `future-incoming-response`. + @since(version = 0.2.0) handle: func( request: outgoing-request, options: option diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 26a975eb1..e8966b0cc 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -2,24 +2,31 @@ package wasi:http@0.2.0; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. /// It is intended to be `include`d in other worlds. +@since(version = 0.2.0) world imports { /// HTTP proxies have access to time and randomness. + @since(version = 0.2.0) include wasi:clocks/imports@0.2.0; + @since(version = 0.2.0) import wasi:random/random@0.2.0; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. + @since(version = 0.2.0) import wasi:cli/stdout@0.2.0; + @since(version = 0.2.0) import wasi:cli/stderr@0.2.0; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. + @since(version = 0.2.0) import wasi:cli/stdin@0.2.0; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). + @since(version = 0.2.0) import outgoing-handler; } @@ -27,12 +34,15 @@ world imports { /// hosts that includes HTTP forward and reverse proxies. Components targeting /// this world may concurrently stream in and out any number of incoming and /// outgoing HTTP requests. +@since(version = 0.2.0) world proxy { + @since(version = 0.2.0) include imports; /// The host delivers incoming HTTP requests to a component by calling the /// `handle` function of this exported interface. A host may arbitrarily reuse /// or not reuse component instance when delivering incoming HTTP requests and /// thus a component must be able to handle 0..N calls to `handle`. + @since(version = 0.2.0) export incoming-handler; } diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 0ead17884..5f6cfd784 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -1,6 +1,7 @@ /// This interface defines all of the types and methods for implementing /// HTTP Requests and Responses, both incoming and outgoing, as well as /// their headers, trailers, and bodies. +@since(version = 0.2.0) interface types { use wasi:clocks/monotonic-clock@0.2.0.{duration}; use wasi:io/streams@0.2.0.{input-stream, output-stream}; @@ -8,6 +9,7 @@ interface types { use wasi:io/poll@0.2.0.{pollable}; /// This type corresponds to HTTP standard Methods. + @since(version = 0.2.0) variant method { get, head, @@ -22,6 +24,7 @@ interface types { } /// This type corresponds to HTTP standard Related Schemes. + @since(version = 0.2.0) variant scheme { HTTP, HTTPS, @@ -30,6 +33,7 @@ interface types { /// These cases are inspired by the IANA HTTP Proxy Error Types: /// https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types + @since(version = 0.2.0) variant error-code { DNS-timeout, DNS-error(DNS-error-payload), @@ -78,18 +82,21 @@ interface types { } /// Defines the case payload type for `DNS-error` above: + @since(version = 0.2.0) record DNS-error-payload { rcode: option, info-code: option } /// Defines the case payload type for `TLS-alert-received` above: + @since(version = 0.2.0) record TLS-alert-received-payload { alert-id: option, alert-message: option } /// Defines the case payload type for `HTTP-response-{header,trailer}-size` above: + @since(version = 0.2.0) record field-size-payload { field-name: option, field-size: option @@ -106,10 +113,12 @@ interface types { /// /// Note that this function is fallible because not all io-errors are /// http-related errors. + @since(version = 0.2.0) http-error-code: func(err: borrow) -> option; /// This type enumerates the different kinds of errors that may occur when /// setting or appending to a `fields` resource. + @since(version = 0.2.0) variant header-error { /// This error indicates that a `field-key` or `field-value` was /// syntactically invalid when used with an operation that sets headers in a @@ -126,11 +135,13 @@ interface types { } /// Field keys are always strings. + @since(version = 0.2.0) type field-key = string; /// Field values should always be ASCII strings. However, in /// reality, HTTP implementations often have to interpret malformed values, /// so they are provided as a list of bytes. + @since(version = 0.2.0) type field-value = list; /// This following block defines the `fields` resource which corresponds to @@ -143,11 +154,13 @@ interface types { /// `incoming-request.headers`, `outgoing-request.headers`) might be be /// immutable. In an immutable fields, the `set`, `append`, and `delete` /// operations will fail with `header-error.immutable`. + @since(version = 0.2.0) resource fields { /// Construct an empty HTTP Fields. /// /// The resulting `fields` is mutable. + @since(version = 0.2.0) constructor(); /// Construct an HTTP Fields. @@ -163,6 +176,7 @@ interface types { /// /// An error result will be returned if any `field-key` or `field-value` is /// syntactically invalid, or if a field is forbidden. + @since(version = 0.2.0) from-list: static func( entries: list> ) -> result; @@ -171,10 +185,12 @@ interface types { /// in this `fields` or is syntactically invalid, an empty list is returned. /// However, if the key is present but empty, this is represented by a list /// with one or more empty field-values present. + @since(version = 0.2.0) get: func(name: field-key) -> list; /// Returns `true` when the key is present in this `fields`. If the key is /// syntactically invalid, `false` is returned. + @since(version = 0.2.0) has: func(name: field-key) -> bool; /// Set all of the values for a key. Clears any existing values for that @@ -184,6 +200,7 @@ interface types { /// /// Fails with `header-error.invalid-syntax` if the `field-key` or any of /// the `field-value`s are syntactically invalid. + @since(version = 0.2.0) set: func(name: field-key, value: list) -> result<_, header-error>; /// Delete all values for a key. Does nothing if no values for the key @@ -193,6 +210,7 @@ interface types { /// /// Fails with `header-error.invalid-syntax` if the `field-key` is /// syntactically invalid. + @since(version = 0.2.0) delete: func(name: field-key) -> result<_, header-error>; /// Append a value for a key. Does not change or delete any existing @@ -202,6 +220,7 @@ interface types { /// /// Fails with `header-error.invalid-syntax` if the `field-key` or /// `field-value` are syntactically invalid. + @since(version = 0.2.0) append: func(name: field-key, value: field-value) -> result<_, header-error>; /// Retrieve the full set of keys and values in the Fields. Like the @@ -210,33 +229,42 @@ interface types { /// The outer list represents each key-value pair in the Fields. Keys /// which have multiple values are represented by multiple entries in this /// list with the same key. + @since(version = 0.2.0) entries: func() -> list>; /// Make a deep copy of the Fields. Equivalent in behavior to calling the /// `fields` constructor on the return value of `entries`. The resulting /// `fields` is mutable. + @since(version = 0.2.0) clone: func() -> fields; } /// Headers is an alias for Fields. + @since(version = 0.2.0) type headers = fields; /// Trailers is an alias for Fields. + @since(version = 0.2.0) type trailers = fields; /// Represents an incoming HTTP Request. + @since(version = 0.2.0) resource incoming-request { /// Returns the method of the incoming request. + @since(version = 0.2.0) method: func() -> method; /// Returns the path with query parameters from the request, as a string. + @since(version = 0.2.0) path-with-query: func() -> option; /// Returns the protocol scheme from the request. + @since(version = 0.2.0) scheme: func() -> option; /// Returns the authority from the request, if it was present. + @since(version = 0.2.0) authority: func() -> option; /// Get the `headers` associated with the request. @@ -247,14 +275,17 @@ interface types { /// The `headers` returned are a child resource: it must be dropped before /// the parent `incoming-request` is dropped. Dropping this /// `incoming-request` before all children are dropped will trap. + @since(version = 0.2.0) headers: func() -> headers; /// Gives the `incoming-body` associated with this request. Will only /// return success at most once, and subsequent calls will return error. + @since(version = 0.2.0) consume: func() -> result; } /// Represents an outgoing HTTP Request. + @since(version = 0.2.0) resource outgoing-request { /// Construct a new `outgoing-request` with a default `method` of `GET`, and @@ -267,6 +298,7 @@ interface types { /// and `authority`, or `headers` which are not permitted to be sent. /// It is the obligation of the `outgoing-handler.handle` implementation /// to reject invalid constructions of `outgoing-request`. + @since(version = 0.2.0) constructor( headers: headers ); @@ -277,38 +309,47 @@ interface types { /// Returns success on the first call: the `outgoing-body` resource for /// this `outgoing-request` can be retrieved at most once. Subsequent /// calls will return error. + @since(version = 0.2.0) body: func() -> result; /// Get the Method for the Request. + @since(version = 0.2.0) method: func() -> method; /// Set the Method for the Request. Fails if the string present in a /// `method.other` argument is not a syntactically valid method. + @since(version = 0.2.0) set-method: func(method: method) -> result; /// Get the combination of the HTTP Path and Query for the Request. /// When `none`, this represents an empty Path and empty Query. + @since(version = 0.2.0) path-with-query: func() -> option; /// Set the combination of the HTTP Path and Query for the Request. /// When `none`, this represents an empty Path and empty Query. Fails is the /// string given is not a syntactically valid path and query uri component. + @since(version = 0.2.0) set-path-with-query: func(path-with-query: option) -> result; /// Get the HTTP Related Scheme for the Request. When `none`, the /// implementation may choose an appropriate default scheme. + @since(version = 0.2.0) scheme: func() -> option; /// Set the HTTP Related Scheme for the Request. When `none`, the /// implementation may choose an appropriate default scheme. Fails if the /// string given is not a syntactically valid uri scheme. + @since(version = 0.2.0) set-scheme: func(scheme: option) -> result; /// Get the HTTP Authority for the Request. A value of `none` may be used /// with Related Schemes which do not require an Authority. The HTTP and /// HTTPS schemes always require an authority. + @since(version = 0.2.0) authority: func() -> option; /// Set the HTTP Authority for the Request. A value of `none` may be used /// with Related Schemes which do not require an Authority. The HTTP and /// HTTPS schemes always require an authority. Fails if the string given is /// not a syntactically valid uri authority. + @since(version = 0.2.0) set-authority: func(authority: option) -> result; /// Get the headers associated with the Request. @@ -319,6 +360,7 @@ interface types { /// This headers resource is a child: it must be dropped before the parent /// `outgoing-request` is dropped, or its ownership is transferred to /// another component by e.g. `outgoing-handler.handle`. + @since(version = 0.2.0) headers: func() -> headers; } @@ -328,31 +370,39 @@ interface types { /// /// These timeouts are separate from any the user may use to bound a /// blocking call to `wasi:io/poll.poll`. + @since(version = 0.2.0) resource request-options { /// Construct a default `request-options` value. + @since(version = 0.2.0) constructor(); /// The timeout for the initial connect to the HTTP Server. + @since(version = 0.2.0) connect-timeout: func() -> option; /// Set the timeout for the initial connect to the HTTP Server. An error /// return value indicates that this timeout is not supported. + @since(version = 0.2.0) set-connect-timeout: func(duration: option) -> result; /// The timeout for receiving the first byte of the Response body. + @since(version = 0.2.0) first-byte-timeout: func() -> option; /// Set the timeout for receiving the first byte of the Response body. An /// error return value indicates that this timeout is not supported. + @since(version = 0.2.0) set-first-byte-timeout: func(duration: option) -> result; /// The timeout for receiving subsequent chunks of bytes in the Response /// body stream. + @since(version = 0.2.0) between-bytes-timeout: func() -> option; /// Set the timeout for receiving subsequent chunks of bytes in the Response /// body stream. An error return value indicates that this timeout is not /// supported. + @since(version = 0.2.0) set-between-bytes-timeout: func(duration: option) -> result; } @@ -361,6 +411,7 @@ interface types { /// This resource is used by the `wasi:http/incoming-handler` interface to /// allow a Response to be sent corresponding to the Request provided as the /// other argument to `incoming-handler.handle`. + @since(version = 0.2.0) resource response-outparam { /// Set the value of the `response-outparam` to either send a response, @@ -372,6 +423,7 @@ interface types { /// /// The user may provide an `error` to `response` to allow the /// implementation determine how to respond with an HTTP error response. + @since(version = 0.2.0) set: static func( param: response-outparam, response: result, @@ -379,12 +431,15 @@ interface types { } /// This type corresponds to the HTTP standard Status Code. + @since(version = 0.2.0) type status-code = u16; /// Represents an incoming HTTP Response. + @since(version = 0.2.0) resource incoming-response { /// Returns the status code from the incoming response. + @since(version = 0.2.0) status: func() -> status-code; /// Returns the headers from the incoming response. @@ -394,10 +449,12 @@ interface types { /// /// This headers resource is a child: it must be dropped before the parent /// `incoming-response` is dropped. + @since(version = 0.2.0) headers: func() -> headers; /// Returns the incoming body. May be called at most once. Returns error /// if called additional times. + @since(version = 0.2.0) consume: func() -> result; } @@ -409,6 +466,7 @@ interface types { /// an `input-stream` and the delivery of trailers as a `future-trailers`, /// and ensures that the user of this interface may only be consuming either /// the body contents or waiting on trailers at any given time. + @since(version = 0.2.0) resource incoming-body { /// Returns the contents of the body, as a stream of bytes. @@ -426,10 +484,12 @@ interface types { /// backpressure is to be applied when the user is consuming the body, /// and for that backpressure to not inhibit delivery of the trailers if /// the user does not read the entire body. + @since(version = 0.2.0) %stream: func() -> result; /// Takes ownership of `incoming-body`, and returns a `future-trailers`. /// This function will trap if the `input-stream` child is still alive. + @since(version = 0.2.0) finish: static func(this: incoming-body) -> future-trailers; } @@ -438,11 +498,13 @@ interface types { /// In the case that the incoming HTTP Request or Response did not have any /// trailers, this future will resolve to the empty set of trailers once the /// complete Request or Response body has been received. + @since(version = 0.2.0) resource future-trailers { /// Returns a pollable which becomes ready when either the trailers have /// been received, or an error has occurred. When this pollable is ready, /// the `get` method will return `some`. + @since(version = 0.2.0) subscribe: func() -> pollable; /// Returns the contents of the trailers, or an error which occurred, @@ -464,10 +526,12 @@ interface types { /// resource is immutable, and a child. Use of the `set`, `append`, or /// `delete` methods will return an error, and the resource must be /// dropped before the parent `future-trailers` is dropped. + @since(version = 0.2.0) get: func() -> option, error-code>>>; } /// Represents an outgoing HTTP Response. + @since(version = 0.2.0) resource outgoing-response { /// Construct an `outgoing-response`, with a default `status-code` of `200`. @@ -475,13 +539,16 @@ interface types { /// `set-status-code` method. /// /// * `headers` is the HTTP Headers for the Response. + @since(version = 0.2.0) constructor(headers: headers); /// Get the HTTP Status Code for the Response. + @since(version = 0.2.0) status-code: func() -> status-code; /// Set the HTTP Status Code for the Response. Fails if the status-code /// given is not a valid http status code. + @since(version = 0.2.0) set-status-code: func(status-code: status-code) -> result; /// Get the headers associated with the Request. @@ -492,6 +559,7 @@ interface types { /// This headers resource is a child: it must be dropped before the parent /// `outgoing-request` is dropped, or its ownership is transferred to /// another component by e.g. `outgoing-handler.handle`. + @since(version = 0.2.0) headers: func() -> headers; /// Returns the resource corresponding to the outgoing Body for this Response. @@ -499,6 +567,7 @@ interface types { /// Returns success on the first call: the `outgoing-body` resource for /// this `outgoing-response` can be retrieved at most once. Subsequent /// calls will return error. + @since(version = 0.2.0) body: func() -> result; } @@ -518,6 +587,7 @@ interface types { /// error to the HTTP protocol by whatever means it has available, /// including: corrupting the body on the wire, aborting the associated /// Request, or sending a late status code for the Response. + @since(version = 0.2.0) resource outgoing-body { /// Returns a stream for writing the body contents. @@ -529,6 +599,7 @@ interface types { /// Returns success on the first call: the `output-stream` resource for /// this `outgoing-body` may be retrieved at most once. Subsequent calls /// will return error. + @since(version = 0.2.0) write: func() -> result; /// Finalize an outgoing body, optionally providing trailers. This must be @@ -540,6 +611,7 @@ interface types { /// constructed with a Content-Length header, and the contents written /// to the body (via `write`) does not match the value given in the /// Content-Length. + @since(version = 0.2.0) finish: static func( this: outgoing-body, trailers: option @@ -551,10 +623,12 @@ interface types { /// /// This resource is returned by the `wasi:http/outgoing-handler` interface to /// provide the HTTP Response corresponding to the sent Request. + @since(version = 0.2.0) resource future-incoming-response { /// Returns a pollable which becomes ready when either the Response has /// been received, or an error has occurred. When this pollable is ready, /// the `get` method will return `some`. + @since(version = 0.2.0) subscribe: func() -> pollable; /// Returns the incoming HTTP Response, or an error, once one is ready. @@ -571,7 +645,7 @@ interface types { /// occurred. Errors may also occur while consuming the response body, /// but those will be reported by the `incoming-body` and its /// `output-stream` child. + @since(version = 0.2.0) get: func() -> option>>; - } } From 5e789b6645be924822e32a964acf7e05e9241d3d Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 21 Jun 2024 02:13:08 +0200 Subject: [PATCH 1475/1772] annotate `use` statements --- proposals/http/wit-0.3.0-draft/handler.wit | 1 + proposals/http/wit-0.3.0-draft/types.wit | 2 ++ proposals/http/wit/handler.wit | 2 ++ proposals/http/wit/types.wit | 4 ++++ 4 files changed, 9 insertions(+) diff --git a/proposals/http/wit-0.3.0-draft/handler.wit b/proposals/http/wit-0.3.0-draft/handler.wit index 099d094c7..a2c5bc57a 100644 --- a/proposals/http/wit-0.3.0-draft/handler.wit +++ b/proposals/http/wit-0.3.0-draft/handler.wit @@ -3,6 +3,7 @@ /// which can respond to HTTP Requests. In addition, it may be used to pass /// a request from one component to another without any use of a network. interface handler { + @since(version = 0.2.0) use types.{request, response, error-code}; /// When exported, this function may be called with either an incoming diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index 58c655c2a..eda519d22 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -1,7 +1,9 @@ /// This interface defines all of the types and methods for implementing HTTP /// Requests and Responses, as well as their headers, trailers, and bodies. interface types { + @since(version = 0.2.0) use wasi:clocks/monotonic-clock@0.2.0.{duration}; + @since(version = 0.2.0) use wasi:io/error@0.2.0.{error}; /// This type corresponds to HTTP standard Methods. diff --git a/proposals/http/wit/handler.wit b/proposals/http/wit/handler.wit index deecce22a..6a6c62966 100644 --- a/proposals/http/wit/handler.wit +++ b/proposals/http/wit/handler.wit @@ -2,6 +2,7 @@ /// be exported by components which can respond to HTTP Requests. @since(version = 0.2.0) interface incoming-handler { + @since(version = 0.2.0) use types.{incoming-request, response-outparam}; /// This function is invoked with an incoming HTTP Request, and a resource @@ -25,6 +26,7 @@ interface incoming-handler { /// imported by components which wish to make HTTP Requests. @since(version = 0.2.0) interface outgoing-handler { + @since(version = 0.2.0) use types.{ outgoing-request, request-options, future-incoming-response, error-code }; diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 5f6cfd784..981c110d1 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -3,9 +3,13 @@ /// their headers, trailers, and bodies. @since(version = 0.2.0) interface types { + @since(version = 0.2.0) use wasi:clocks/monotonic-clock@0.2.0.{duration}; + @since(version = 0.2.0) use wasi:io/streams@0.2.0.{input-stream, output-stream}; + @since(version = 0.2.0) use wasi:io/error@0.2.0.{error as io-error}; + @since(version = 0.2.0) use wasi:io/poll@0.2.0.{pollable}; /// This type corresponds to HTTP standard Methods. From e3310a676f53f94b771470adf927421a1b702995 Mon Sep 17 00:00:00 2001 From: Yosh Date: Mon, 24 Jun 2024 02:59:05 +0200 Subject: [PATCH 1476/1772] update `wit-abi-up-to-date` to parse `@since` gates --- proposals/http/.github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index 113cfe9c4..43efdf3a5 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -16,7 +16,7 @@ jobs: curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.2/wit-deps-x86_64-unknown-linux-musl chmod +x ./wit-deps ./wit-deps lock --check - - uses: WebAssembly/wit-abi-up-to-date@v17 + - uses: WebAssembly/wit-abi-up-to-date@v21 with: wit-bindgen: '0.17.0' - worlds: 'imports proxy' \ No newline at end of file + worlds: 'imports proxy' From 5e97ddd273c5b107308dac715019ec426bf58c10 Mon Sep 17 00:00:00 2001 From: Yosh Date: Sat, 13 Jul 2024 17:13:44 +0200 Subject: [PATCH 1477/1772] update wit deps --- proposals/http/wit/deps.lock | 20 +++---- .../http/wit/deps/clocks/monotonic-clock.wit | 17 ++++-- proposals/http/wit/deps/clocks/timezone.wit | 55 +++++++++++++++++++ proposals/http/wit/deps/clocks/wall-clock.wit | 4 ++ proposals/http/wit/deps/clocks/world.wit | 5 ++ .../http/wit/deps/filesystem/preopens.wit | 3 + proposals/http/wit/deps/filesystem/types.wit | 44 +++++++++++++++ proposals/http/wit/deps/filesystem/world.wit | 3 + proposals/http/wit/deps/io/error.wit | 16 +++--- proposals/http/wit/deps/io/poll.wit | 12 +++- proposals/http/wit/deps/io/streams.wit | 20 +++++++ proposals/http/wit/deps/io/world.wit | 4 ++ .../http/wit/deps/random/insecure-seed.wit | 2 + proposals/http/wit/deps/random/insecure.wit | 3 + proposals/http/wit/deps/random/random.wit | 3 + proposals/http/wit/deps/random/world.wit | 6 ++ .../wit/deps/sockets/instance-network.wit | 4 +- .../http/wit/deps/sockets/ip-name-lookup.wit | 9 ++- proposals/http/wit/deps/sockets/network.wit | 12 +++- .../wit/deps/sockets/tcp-create-socket.wit | 5 +- proposals/http/wit/deps/sockets/tcp.wit | 48 +++++++++++++--- .../wit/deps/sockets/udp-create-socket.wit | 5 +- proposals/http/wit/deps/sockets/udp.wit | 28 +++++++++- proposals/http/wit/deps/sockets/world.wit | 8 +++ 24 files changed, 292 insertions(+), 44 deletions(-) create mode 100644 proposals/http/wit/deps/clocks/timezone.wit diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 96be4b203..343925389 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -5,25 +5,25 @@ sha512 = "da2622210a9e3eea82b99f1a5b8a44ce5443d009cb943f7bca0bf9cf4360829b289913 [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "468b4d12892fe926b8eb5d398dbf579d566c93231fa44f415440572c695b7613" -sha512 = "e6b53a07221f1413953c9797c68f08b815fdaebf66419bbc1ea3e8b7dece73731062693634731f311a03957b268cf9cc509c518bd15e513c318aa04a8459b93a" +sha256 = "f27a857de70c1b0dfbabda35812a8de1253089623b1a84ddd066183c6ffac5f8" +sha512 = "9df1b0be1e4925f671fda65d433217798404f8e2e4fa60ff8bfdfd257f0b6d212ea350c141f308cf4cc57fb0b44899b14af1f9af97a05dcd6f8ae00a7594de8d" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "498c465cfd04587db40f970fff2185daa597d074c20b68a8bcbae558f261499b" -sha512 = "ead452f9b7bfb88593a502ec00d76d4228003d51c40fd0408aebc32d35c94673551b00230d730873361567cc209ec218c41fb4e95bad194268592c49e7964347" +sha256 = "e37bda5e27222621771ba07d2e9daf862a728c31f91024badfc4f9a42c9ae8ee" +sha512 = "81e92f5e4eca0c8f9606f26a1c4eebb3c53a708b57d3f7e7c60e97aa3c18794b72a44c39212de566442e25313b5ccb5b0b7c9070f3600f0c7c584ea9db91e207" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "7210e5653539a15478f894d4da24cc69d61924cbcba21d2804d69314a88e5a4c" -sha512 = "49184a1b0945a889abd52d25271172ed3dc2db6968fcdddb1bab7ee0081f4a3eeee0977ad2291126a37631c0d86eeea75d822fa8af224c422134500bf9f0f2bb" +sha256 = "f3e976740ed9512674c627c6588864c477a9ff539bb7e55c7b9ceab222399b52" +sha512 = "c785122b4c04e2297e3fa37ae76c149b0a681444da106758cf673023923b69a6b2c65624ffbb6ad31edef02f9fbc677b05c89525f07b1159fe0c997a8c6b1a8f" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "7371d03c037d924caba2587fb2e7c5773a0d3c5fcecbf7971e0e0ba57973c53d" -sha512 = "964c4e8925a53078e4d94ba907b54f89a0b7e154f46823a505391471466c17f53c8692682e5c85771712acd88b348686173fc07c53a3cfe3d301b8cd8ddd0de4" +sha256 = "2f0014e946e38947afe120836b17cdcfa608be993d38d55b81cc2d31e7e70b16" +sha512 = "51ee623509040de77b0ba236e29589102538aacd3dd67168b06a09bf6ae469c762818fc07b5039d2a8b1838f4b5a5965a7c81ed0e2d47b142bece9d1ab8b93a6" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "622bd28bbeb43736375dc02bd003fd3a016ff8ee91e14bab488325c6b38bf966" -sha512 = "5a63c1f36de0c4548e1d2297bdbededb28721cbad94ef7825c469eae29d7451c97e00b4c1d6730ee1ec0c4a5aac922961a2795762d4a0c3bb54e30a391a84bae" +sha256 = "5321ba37115d503bfe0880349e99ecbd26ee812708fa83d2b276ec8ee7571443" +sha512 = "c3d71c2afa1475bf10d86b1e0623e2292e5dd407cf54103ad0d05c07fa95323bff9ad06e929d508b318a0a99a67132793fb9a04c17585843e24f090f5ee91367" diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index 4e4dc3a19..cae2363bf 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -7,38 +7,43 @@ package wasi:clocks@0.2.0; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -/// -/// It is intended for measuring elapsed time. +@since(version = 0.2.0) interface monotonic-clock { + @since(version = 0.2.0) use wasi:io/poll@0.2.0.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. + @since(version = 0.2.0) type instant = u64; /// A duration of time, in nanoseconds. + @since(version = 0.2.0) type duration = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + @since(version = 0.2.0) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. + @since(version = 0.2.0) resolution: func() -> duration; /// Create a `pollable` which will resolve once the specified instant - /// occured. + /// has occured. + @since(version = 0.2.0) subscribe-instant: func( when: instant, ) -> pollable; - /// Create a `pollable` which will resolve once the given duration has - /// elapsed, starting at the time at which this function was called. - /// occured. + /// Create a `pollable` that will resolve after the specified duration has + /// elapsed from the time this function is invoked. + @since(version = 0.2.0) subscribe-duration: func( when: duration, ) -> pollable; diff --git a/proposals/http/wit/deps/clocks/timezone.wit b/proposals/http/wit/deps/clocks/timezone.wit new file mode 100644 index 000000000..3c286889e --- /dev/null +++ b/proposals/http/wit/deps/clocks/timezone.wit @@ -0,0 +1,55 @@ +package wasi:clocks@0.2.0; + +@unstable(feature = clocks-timezone) +interface timezone { + @unstable(feature = clocks-timezone) + use wall-clock.{datetime}; + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + @unstable(feature = clocks-timezone) + display: func(when: datetime) -> timezone-display; + + /// The same as `display`, but only return the UTC offset. + @unstable(feature = clocks-timezone) + utc-offset: func(when: datetime) -> s32; + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + @unstable(feature = clocks-timezone) + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/http/wit/deps/clocks/wall-clock.wit b/proposals/http/wit/deps/clocks/wall-clock.wit index 440ca0f33..4b08d71ee 100644 --- a/proposals/http/wit/deps/clocks/wall-clock.wit +++ b/proposals/http/wit/deps/clocks/wall-clock.wit @@ -13,8 +13,10 @@ package wasi:clocks@0.2.0; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. +@since(version = 0.2.0) interface wall-clock { /// A time and date in seconds plus nanoseconds. + @since(version = 0.2.0) record datetime { seconds: u64, nanoseconds: u32, @@ -33,10 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + @since(version = 0.2.0) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. + @since(version = 0.2.0) resolution: func() -> datetime; } diff --git a/proposals/http/wit/deps/clocks/world.wit b/proposals/http/wit/deps/clocks/world.wit index c0224572a..76a9206c5 100644 --- a/proposals/http/wit/deps/clocks/world.wit +++ b/proposals/http/wit/deps/clocks/world.wit @@ -1,6 +1,11 @@ package wasi:clocks@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import monotonic-clock; + @since(version = 0.2.0) import wall-clock; + @unstable(feature = clocks-timezone) + import timezone; } diff --git a/proposals/http/wit/deps/filesystem/preopens.wit b/proposals/http/wit/deps/filesystem/preopens.wit index da801f6d6..08094ab3f 100644 --- a/proposals/http/wit/deps/filesystem/preopens.wit +++ b/proposals/http/wit/deps/filesystem/preopens.wit @@ -1,8 +1,11 @@ package wasi:filesystem@0.2.0; +@since(version = 0.2.0) interface preopens { + @since(version = 0.2.0) use types.{descriptor}; /// Return the set of preopened directories, and their path. + @since(version = 0.2.0) get-directories: func() -> list>; } diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index 11108fcda..4900ae2c4 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -23,16 +23,21 @@ package wasi:filesystem@0.2.0; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md +@since(version = 0.2.0) interface types { + @since(version = 0.2.0) use wasi:io/streams@0.2.0.{input-stream, output-stream, error}; + @since(version = 0.2.0) use wasi:clocks/wall-clock@0.2.0.{datetime}; /// File size or length of a region within a file. + @since(version = 0.2.0) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. + @since(version = 0.2.0) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -56,6 +61,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. + @since(version = 0.2.0) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -99,6 +105,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. + @since(version = 0.2.0) record descriptor-stat { /// File type. %type: descriptor-type, @@ -125,6 +132,7 @@ interface types { } /// Flags determining the method of how paths are resolved. + @since(version = 0.2.0) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -132,6 +140,7 @@ interface types { } /// Open flags used by `open-at`. + @since(version = 0.2.0) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -144,9 +153,11 @@ interface types { } /// Number of hard links to an inode. + @since(version = 0.2.0) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. + @since(version = 0.2.0) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -248,6 +259,7 @@ interface types { } /// File or memory access pattern advisory information. + @since(version = 0.2.0) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -271,6 +283,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. + @since(version = 0.2.0) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -281,6 +294,7 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. + @since(version = 0.2.0) resource descriptor { /// Return a stream for reading from a file, if available. /// @@ -290,6 +304,7 @@ interface types { /// file and they do not interfere with each other. /// /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. + @since(version = 0.2.0) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, @@ -301,6 +316,7 @@ interface types { /// /// Note: This allows using `write-stream`, which is similar to `write` in /// POSIX. + @since(version = 0.2.0) write-via-stream: func( /// The offset within the file at which to start writing. offset: filesize, @@ -312,11 +328,13 @@ interface types { /// /// Note: This allows using `write-stream`, which is similar to `write` with /// `O_APPEND` in in POSIX. + @since(version = 0.2.0) append-via-stream: func() -> result; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. + @since(version = 0.2.0) advise: func( /// The offset within the file to which the advisory applies. offset: filesize, @@ -332,6 +350,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. + @since(version = 0.2.0) sync-data: func() -> result<_, error-code>; /// Get flags associated with a descriptor. @@ -340,6 +359,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. + @since(version = 0.2.0) get-flags: func() -> result; /// Get the dynamic type of a descriptor. @@ -352,12 +372,14 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. + @since(version = 0.2.0) get-type: func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. + @since(version = 0.2.0) set-size: func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. @@ -365,6 +387,7 @@ interface types { /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. + @since(version = 0.2.0) set-times: func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, @@ -383,6 +406,7 @@ interface types { /// In the future, this may change to return a `stream`. /// /// Note: This is similar to `pread` in POSIX. + @since(version = 0.2.0) read: func( /// The maximum number of bytes to read. length: filesize, @@ -399,6 +423,7 @@ interface types { /// In the future, this may change to take a `stream`. /// /// Note: This is similar to `pwrite` in POSIX. + @since(version = 0.2.0) write: func( /// Data to write buffer: list, @@ -415,6 +440,7 @@ interface types { /// This always returns a new stream which starts at the beginning of the /// directory. Multiple streams may be active on the same directory, and they /// do not interfere with each other. + @since(version = 0.2.0) read-directory: func() -> result; /// Synchronize the data and metadata of a file to disk. @@ -423,11 +449,13 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. + @since(version = 0.2.0) sync: func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. + @since(version = 0.2.0) create-directory-at: func( /// The relative path at which to create the directory. path: string, @@ -442,6 +470,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. + @since(version = 0.2.0) stat: func() -> result; /// Return the attributes of a file or directory. @@ -451,6 +480,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. + @since(version = 0.2.0) stat-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -464,6 +494,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. + @since(version = 0.2.0) set-times-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -478,6 +509,7 @@ interface types { /// Create a hard link. /// /// Note: This is similar to `linkat` in POSIX. + @since(version = 0.2.0) link-at: func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, @@ -507,6 +539,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. + @since(version = 0.2.0) open-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -524,6 +557,7 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. + @since(version = 0.2.0) readlink-at: func( /// The relative path of the symbolic link from which to read. path: string, @@ -534,6 +568,7 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + @since(version = 0.2.0) remove-directory-at: func( /// The relative path to a directory to remove. path: string, @@ -542,6 +577,7 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. + @since(version = 0.2.0) rename-at: func( /// The relative source path of the file or directory to rename. old-path: string, @@ -557,6 +593,7 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. + @since(version = 0.2.0) symlink-at: func( /// The contents of the symbolic link. old-path: string, @@ -568,6 +605,7 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + @since(version = 0.2.0) unlink-file-at: func( /// The relative path to a file to unlink. path: string, @@ -579,6 +617,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. + @since(version = 0.2.0) is-same-object: func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred @@ -600,12 +639,14 @@ interface types { /// computed hash. /// /// However, none of these is required. + @since(version = 0.2.0) metadata-hash: func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. + @since(version = 0.2.0) metadata-hash-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -615,8 +656,10 @@ interface types { } /// A stream of directory entries. + @since(version = 0.2.0) resource directory-entry-stream { /// Read a single directory entry from a `directory-entry-stream`. + @since(version = 0.2.0) read-directory-entry: func() -> result, error-code>; } @@ -630,5 +673,6 @@ interface types { /// /// Note that this function is fallible because not all stream-related /// errors are filesystem-related errors. + @since(version = 0.2.0) filesystem-error-code: func(err: borrow) -> option; } diff --git a/proposals/http/wit/deps/filesystem/world.wit b/proposals/http/wit/deps/filesystem/world.wit index 663f57920..c8d99f56e 100644 --- a/proposals/http/wit/deps/filesystem/world.wit +++ b/proposals/http/wit/deps/filesystem/world.wit @@ -1,6 +1,9 @@ package wasi:filesystem@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import types; + @since(version = 0.2.0) import preopens; } diff --git a/proposals/http/wit/deps/io/error.wit b/proposals/http/wit/deps/io/error.wit index 22e5b6489..7e66dbba2 100644 --- a/proposals/http/wit/deps/io/error.wit +++ b/proposals/http/wit/deps/io/error.wit @@ -1,6 +1,6 @@ package wasi:io@0.2.0; - +@since(version = 0.2.0) interface error { /// A resource which represents some error information. /// @@ -11,16 +11,15 @@ interface error { /// `wasi:io/streams/stream-error` type. /// /// To provide more specific error information, other interfaces may - /// provide functions to further "downcast" this error into more specific - /// error information. For example, `error`s returned in streams derived - /// from filesystem types to be described using the filesystem's own - /// error-code type, using the function - /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter - /// `borrow` and returns - /// `option`. + /// offer functions to "downcast" this error into more specific types. For example, + /// errors returned from streams derived from filesystem types can be described using + /// the filesystem's own error-code type. This is done using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a `borrow` + /// parameter and returns an `option`. /// /// The set of functions which can "downcast" an `error` into a more /// concrete type is open. + @since(version = 0.2.0) resource error { /// Returns a string that is suitable to assist humans in debugging /// this error. @@ -29,6 +28,7 @@ interface error { /// It may change across platforms, hosts, or other implementation /// details. Parsing this string is a major platform-compatibility /// hazard. + @since(version = 0.2.0) to-debug-string: func() -> string; } } diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/io/poll.wit index ddc67f8b7..cbdc960f0 100644 --- a/proposals/http/wit/deps/io/poll.wit +++ b/proposals/http/wit/deps/io/poll.wit @@ -2,13 +2,16 @@ package wasi:io@0.2.0; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. +@since(version = 0.2.0) interface poll { /// `pollable` represents a single I/O event which may be ready, or not. + @since(version = 0.2.0) resource pollable { /// Return the readiness of a pollable. This function never blocks. /// /// Returns `true` when the pollable is ready, and `false` otherwise. + @since(version = 0.2.0) ready: func() -> bool; /// `block` returns immediately if the pollable is ready, and otherwise @@ -16,6 +19,7 @@ interface poll { /// /// This function is equivalent to calling `poll.poll` on a list /// containing only this pollable. + @since(version = 0.2.0) block: func(); } @@ -27,8 +31,9 @@ interface poll { /// The result `list` contains one or more indices of handles in the /// argument list that is ready for I/O. /// - /// If the list contains more elements than can be indexed with a `u32` - /// value, this function traps. + /// This function traps if either: + /// - the list is empty, or: + /// - the list contains more elements than can be indexed with a `u32` value. /// /// A timeout can be implemented by adding a pollable from the /// wasi-clocks API to the list. @@ -36,6 +41,7 @@ interface poll { /// This function does not return a `result`; polling in itself does not /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as - /// being reaedy for I/O. + /// being ready for I/O. + @since(version = 0.2.0) poll: func(in: list>) -> list; } diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index 6d2f871e3..a57f20439 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -5,11 +5,15 @@ package wasi:io@0.2.0; /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. +@since(version = 0.2.0) interface streams { + @since(version = 0.2.0) use error.{error}; + @since(version = 0.2.0) use poll.{pollable}; /// An error for input-stream and output-stream operations. + @since(version = 0.2.0) variant stream-error { /// The last operation (a write or flush) failed before completion. /// @@ -29,6 +33,7 @@ interface streams { /// available, which could even be zero. To wait for data to be available, /// use the `subscribe` function to obtain a `pollable` which can be polled /// for using `wasi:io/poll`. + @since(version = 0.2.0) resource input-stream { /// Perform a non-blocking read from the stream. /// @@ -56,6 +61,7 @@ interface streams { /// is not possible to allocate in wasm32, or not desirable to allocate as /// as a return value by the callee. The callee may return a list of bytes /// less than `len` in size while more bytes are available for reading. + @since(version = 0.2.0) read: func( /// The maximum number of bytes to read len: u64 @@ -63,6 +69,7 @@ interface streams { /// Read bytes from a stream, after blocking until at least one byte can /// be read. Except for blocking, behavior is identical to `read`. + @since(version = 0.2.0) blocking-read: func( /// The maximum number of bytes to read len: u64 @@ -72,6 +79,7 @@ interface streams { /// /// Behaves identical to `read`, except instead of returning a list /// of bytes, returns the number of bytes consumed from the stream. + @since(version = 0.2.0) skip: func( /// The maximum number of bytes to skip. len: u64, @@ -79,6 +87,7 @@ interface streams { /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. + @since(version = 0.2.0) blocking-skip: func( /// The maximum number of bytes to skip. len: u64, @@ -90,6 +99,7 @@ interface streams { /// The created `pollable` is a child resource of the `input-stream`. /// Implementations may trap if the `input-stream` is dropped before /// all derived `pollable`s created with this function are dropped. + @since(version = 0.2.0) subscribe: func() -> pollable; } @@ -102,6 +112,7 @@ interface streams { /// promptly, which could even be zero. To wait for the stream to be ready to /// accept data, the `subscribe` function to obtain a `pollable` which can be /// polled for using `wasi:io/poll`. + @since(version = 0.2.0) resource output-stream { /// Check readiness for writing. This function never blocks. /// @@ -112,6 +123,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. + @since(version = 0.2.0) check-write: func() -> result; /// Perform a write. This function never blocks. @@ -127,6 +139,7 @@ interface streams { /// /// returns Err(closed) without writing if the stream has closed since /// the last call to check-write provided a permit. + @since(version = 0.2.0) write: func( contents: list ) -> result<_, stream-error>; @@ -155,6 +168,7 @@ interface streams { /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` + @since(version = 0.2.0) blocking-write-and-flush: func( contents: list ) -> result<_, stream-error>; @@ -169,10 +183,12 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. + @since(version = 0.2.0) flush: func() -> result<_, stream-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. + @since(version = 0.2.0) blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream @@ -193,6 +209,7 @@ interface streams { /// preconditions (must use check-write first), but instead of /// passing a list of bytes, you simply pass the number of zero-bytes /// that should be written. + @since(version = 0.2.0) write-zeroes: func( /// The number of zero-bytes to write len: u64 @@ -222,6 +239,7 @@ interface streams { /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` + @since(version = 0.2.0) blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 @@ -240,6 +258,7 @@ interface streams { /// /// This function returns the number of bytes transferred; it may be less /// than `len`. + @since(version = 0.2.0) splice: func( /// The stream to read from src: borrow, @@ -252,6 +271,7 @@ interface streams { /// This is similar to `splice`, except that it blocks until the /// `output-stream` is ready for writing, and the `input-stream` /// is ready for reading, before performing the `splice`. + @since(version = 0.2.0) blocking-splice: func( /// The stream to read from src: borrow, diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit index 5f0b43fe5..f5c098793 100644 --- a/proposals/http/wit/deps/io/world.wit +++ b/proposals/http/wit/deps/io/world.wit @@ -1,6 +1,10 @@ package wasi:io@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import streams; + + @since(version = 0.2.0) import poll; } diff --git a/proposals/http/wit/deps/random/insecure-seed.wit b/proposals/http/wit/deps/random/insecure-seed.wit index 47210ac6b..4cce62858 100644 --- a/proposals/http/wit/deps/random/insecure-seed.wit +++ b/proposals/http/wit/deps/random/insecure-seed.wit @@ -3,6 +3,7 @@ package wasi:random@0.2.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +@since(version = 0.2.0) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -21,5 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. + @since(version = 0.2.0) insecure-seed: func() -> tuple; } diff --git a/proposals/http/wit/deps/random/insecure.wit b/proposals/http/wit/deps/random/insecure.wit index c58f4ee85..3cea0c4a6 100644 --- a/proposals/http/wit/deps/random/insecure.wit +++ b/proposals/http/wit/deps/random/insecure.wit @@ -3,6 +3,7 @@ package wasi:random@0.2.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +@since(version = 0.2.0) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -12,11 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. + @since(version = 0.2.0) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. + @since(version = 0.2.0) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index 0c017f093..41c3a0367 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -3,6 +3,7 @@ package wasi:random@0.2.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +@since(version = 0.2.0) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -16,11 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. + @since(version = 0.2.0) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. + @since(version = 0.2.0) get-random-u64: func() -> u64; } diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit index 3da34914a..b5560a67a 100644 --- a/proposals/http/wit/deps/random/world.wit +++ b/proposals/http/wit/deps/random/world.wit @@ -1,7 +1,13 @@ package wasi:random@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import random; + + @since(version = 0.2.0) import insecure; + + @since(version = 0.2.0) import insecure-seed; } diff --git a/proposals/http/wit/deps/sockets/instance-network.wit b/proposals/http/wit/deps/sockets/instance-network.wit index e455d0ff7..5f6e6c1cc 100644 --- a/proposals/http/wit/deps/sockets/instance-network.wit +++ b/proposals/http/wit/deps/sockets/instance-network.wit @@ -1,9 +1,11 @@ /// This interface provides a value-export of the default network handle.. +@since(version = 0.2.0) interface instance-network { + @since(version = 0.2.0) use network.{network}; /// Get a handle to the default network. + @since(version = 0.2.0) instance-network: func() -> network; - } diff --git a/proposals/http/wit/deps/sockets/ip-name-lookup.wit b/proposals/http/wit/deps/sockets/ip-name-lookup.wit index 8e639ec59..0368b4801 100644 --- a/proposals/http/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit/deps/sockets/ip-name-lookup.wit @@ -1,9 +1,10 @@ - +@since(version = 0.2.0) interface ip-name-lookup { + @since(version = 0.2.0) use wasi:io/poll@0.2.0.{pollable}; + @since(version = 0.2.0) use network.{network, error-code, ip-address}; - /// Resolve an internet host name to a list of IP addresses. /// /// Unicode domain names are automatically converted to ASCII using IDNA encoding. @@ -24,8 +25,10 @@ interface ip-name-lookup { /// - /// - /// - + @since(version = 0.2.0) resolve-addresses: func(network: borrow, name: string) -> result; + @since(version = 0.2.0) resource resolve-address-stream { /// Returns the next address from the resolver. /// @@ -40,12 +43,14 @@ interface ip-name-lookup { /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) + @since(version = 0.2.0) resolve-next-address: func() -> result, error-code>; /// Create a `pollable` which will resolve once the stream is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } } diff --git a/proposals/http/wit/deps/sockets/network.wit b/proposals/http/wit/deps/sockets/network.wit index 9cadf0650..8c13b348e 100644 --- a/proposals/http/wit/deps/sockets/network.wit +++ b/proposals/http/wit/deps/sockets/network.wit @@ -1,8 +1,9 @@ - +@since(version = 0.2.0) interface network { /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. + @since(version = 0.2.0) resource network; /// Error codes. @@ -17,6 +18,7 @@ interface network { /// - `concurrency-conflict` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. + @since(version = 0.2.0) enum error-code { /// Unknown error unknown, @@ -103,6 +105,7 @@ interface network { permanent-resolver-failure, } + @since(version = 0.2.0) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -111,14 +114,18 @@ interface network { ipv6, } + @since(version = 0.2.0) type ipv4-address = tuple; + @since(version = 0.2.0) type ipv6-address = tuple; + @since(version = 0.2.0) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } + @since(version = 0.2.0) record ipv4-socket-address { /// sin_port port: u16, @@ -126,6 +133,7 @@ interface network { address: ipv4-address, } + @since(version = 0.2.0) record ipv6-socket-address { /// sin6_port port: u16, @@ -137,9 +145,9 @@ interface network { scope-id: u32, } + @since(version = 0.2.0) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), } - } diff --git a/proposals/http/wit/deps/sockets/tcp-create-socket.wit b/proposals/http/wit/deps/sockets/tcp-create-socket.wit index c7ddf1f22..eedbd3076 100644 --- a/proposals/http/wit/deps/sockets/tcp-create-socket.wit +++ b/proposals/http/wit/deps/sockets/tcp-create-socket.wit @@ -1,6 +1,8 @@ - +@since(version = 0.2.0) interface tcp-create-socket { + @since(version = 0.2.0) use network.{network, error-code, ip-address-family}; + @since(version = 0.2.0) use tcp.{tcp-socket}; /// Create a new TCP socket. @@ -23,5 +25,6 @@ interface tcp-create-socket { /// - /// - /// - + @since(version = 0.2.0) create-tcp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index 5902b9ee0..e4a62101b 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -1,10 +1,15 @@ - +@since(version = 0.2.0) interface tcp { + @since(version = 0.2.0) use wasi:io/streams@0.2.0.{input-stream, output-stream}; + @since(version = 0.2.0) use wasi:io/poll@0.2.0.{pollable}; + @since(version = 0.2.0) use wasi:clocks/monotonic-clock@0.2.0.{duration}; + @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; + @since(version = 0.2.0) enum shutdown-type { /// Similar to `SHUT_RD` in POSIX. receive, @@ -27,8 +32,8 @@ interface tcp { /// - `connect-in-progress` /// - `connected` /// - `closed` - /// See - /// for a more information. + /// See + /// for more information. /// /// Note: Except where explicitly mentioned, whenever this documentation uses /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. @@ -37,6 +42,7 @@ interface tcp { /// In addition to the general error codes documented on the /// `network::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. + @since(version = 0.2.0) resource tcp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -76,13 +82,15 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) finish-bind: func() -> result<_, error-code>; /// Connect to a remote endpoint. /// /// On success: - /// - the socket is transitioned into the `connection` state. + /// - the socket is transitioned into the `connected` state. /// - a pair of streams is returned that can be used to read & write to the connection /// /// After a failed connection attempt, the socket will be in the `closed` @@ -121,7 +129,9 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) finish-connect: func() -> result, error-code>; /// Start listening for new connections. @@ -149,7 +159,9 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) start-listen: func() -> result<_, error-code>; + @since(version = 0.2.0) finish-listen: func() -> result<_, error-code>; /// Accept a new client socket. @@ -178,6 +190,7 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) accept: func() -> result, error-code>; /// Get the bound local address. @@ -196,6 +209,7 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) local-address: func() -> result; /// Get the remote address. @@ -208,16 +222,19 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. + @since(version = 0.2.0) is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.2.0) address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. @@ -229,6 +246,7 @@ interface tcp { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. + @since(version = 0.2.0) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -240,7 +258,9 @@ interface tcp { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. + @since(version = 0.2.0) keep-alive-enabled: func() -> result; + @since(version = 0.2.0) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. @@ -253,7 +273,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) keep-alive-idle-time: func() -> result; + @since(version = 0.2.0) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. @@ -266,7 +288,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) keep-alive-interval: func() -> result; + @since(version = 0.2.0) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. @@ -279,7 +303,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) keep-alive-count: func() -> result; + @since(version = 0.2.0) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -288,7 +314,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.2.0) hop-limit: func() -> result; + @since(version = 0.2.0) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -301,9 +329,13 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) receive-buffer-size: func() -> result; + @since(version = 0.2.0) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) send-buffer-size: func() -> result; + @since(version = 0.2.0) set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Create a `pollable` which can be used to poll for, or block on, @@ -318,11 +350,12 @@ interface tcp { /// `subscribe` only has to be called once per socket and can then be /// (re)used for the remainder of the socket's lifetime. /// - /// See - /// for a more information. + /// See + /// for more information. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; /// Initiate a graceful shutdown. @@ -335,7 +368,7 @@ interface tcp { /// associated with this socket will be closed and a FIN packet will be sent. /// - `both`: Same effect as `receive` & `send` combined. /// - /// This function is idempotent. Shutting a down a direction more than once + /// This function is idempotent; shutting down a direction more than once /// has no effect and returns `ok`. /// /// The shutdown function does not close (drop) the socket. @@ -348,6 +381,7 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; } } diff --git a/proposals/http/wit/deps/sockets/udp-create-socket.wit b/proposals/http/wit/deps/sockets/udp-create-socket.wit index 0482d1fe7..e8eeacbfe 100644 --- a/proposals/http/wit/deps/sockets/udp-create-socket.wit +++ b/proposals/http/wit/deps/sockets/udp-create-socket.wit @@ -1,6 +1,8 @@ - +@since(version = 0.2.0) interface udp-create-socket { + @since(version = 0.2.0) use network.{network, error-code, ip-address-family}; + @since(version = 0.2.0) use udp.{udp-socket}; /// Create a new UDP socket. @@ -23,5 +25,6 @@ interface udp-create-socket { /// - /// - /// - + @since(version = 0.2.0) create-udp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index d987a0a90..48e753cac 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -1,9 +1,12 @@ - +@since(version = 0.2.0) interface udp { + @since(version = 0.2.0) use wasi:io/poll@0.2.0.{pollable}; + @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; /// A received datagram. + @since(version = 0.2.0) record incoming-datagram { /// The payload. /// @@ -19,6 +22,7 @@ interface udp { } /// A datagram to be sent out. + @since(version = 0.2.0) record outgoing-datagram { /// The payload. data: list, @@ -33,9 +37,8 @@ interface udp { remote-address: option, } - - /// A UDP socket handle. + @since(version = 0.2.0) resource udp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -63,7 +66,9 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) finish-bind: func() -> result<_, error-code>; /// Set up inbound & outbound communication channels, optionally to a specific peer. @@ -106,6 +111,7 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) %stream: func(remote-address: option) -> result, error-code>; /// Get the current bound address. @@ -124,6 +130,7 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) local-address: func() -> result; /// Get the address the socket is currently streaming to. @@ -136,11 +143,13 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.2.0) address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -149,7 +158,9 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.2.0) unicast-hop-limit: func() -> result; + @since(version = 0.2.0) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -162,18 +173,24 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) receive-buffer-size: func() -> result; + @since(version = 0.2.0) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) send-buffer-size: func() -> result; + @since(version = 0.2.0) set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Create a `pollable` which will resolve once the socket is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } + @since(version = 0.2.0) resource incoming-datagram-stream { /// Receive messages on the socket. /// @@ -198,15 +215,18 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) receive: func(max-results: u64) -> result, error-code>; /// Create a `pollable` which will resolve once the stream is ready to receive again. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } + @since(version = 0.2.0) resource outgoing-datagram-stream { /// Check readiness for sending. This function never blocks. /// @@ -255,12 +275,14 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) send: func(datagrams: list) -> result; /// Create a `pollable` which will resolve once the stream is ready to send again. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } } diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit index f8bb92ae0..a1f7d14bc 100644 --- a/proposals/http/wit/deps/sockets/world.wit +++ b/proposals/http/wit/deps/sockets/world.wit @@ -1,11 +1,19 @@ package wasi:sockets@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import instance-network; + @since(version = 0.2.0) import network; + @since(version = 0.2.0) import udp; + @since(version = 0.2.0) import udp-create-socket; + @since(version = 0.2.0) import tcp; + @since(version = 0.2.0) import tcp-create-socket; + @since(version = 0.2.0) import ip-name-lookup; } From 3f976602f3516dbecbb9464f571493fdbfbcf7ac Mon Sep 17 00:00:00 2001 From: Yosh Date: Sat, 13 Jul 2024 17:14:56 +0200 Subject: [PATCH 1478/1772] don't update the 0.3.0 draft --- proposals/http/wit-0.3.0-draft/handler.wit | 1 - proposals/http/wit-0.3.0-draft/types.wit | 2 -- 2 files changed, 3 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/handler.wit b/proposals/http/wit-0.3.0-draft/handler.wit index a2c5bc57a..099d094c7 100644 --- a/proposals/http/wit-0.3.0-draft/handler.wit +++ b/proposals/http/wit-0.3.0-draft/handler.wit @@ -3,7 +3,6 @@ /// which can respond to HTTP Requests. In addition, it may be used to pass /// a request from one component to another without any use of a network. interface handler { - @since(version = 0.2.0) use types.{request, response, error-code}; /// When exported, this function may be called with either an incoming diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index eda519d22..58c655c2a 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -1,9 +1,7 @@ /// This interface defines all of the types and methods for implementing HTTP /// Requests and Responses, as well as their headers, trailers, and bodies. interface types { - @since(version = 0.2.0) use wasi:clocks/monotonic-clock@0.2.0.{duration}; - @since(version = 0.2.0) use wasi:io/error@0.2.0.{error}; /// This type corresponds to HTTP standard Methods. From 3f69c19a46c2c78365cbcccc96e94d66d83de07d Mon Sep 17 00:00:00 2001 From: Yosh Date: Tue, 16 Jul 2024 17:09:40 +0200 Subject: [PATCH 1479/1772] update wit-deps --- proposals/http/wit/deps.lock | 16 ++++++++-------- proposals/http/wit/deps/cli/command.wit | 3 +++ proposals/http/wit/deps/cli/environment.wit | 4 ++++ proposals/http/wit/deps/cli/exit.wit | 2 ++ proposals/http/wit/deps/cli/imports.wit | 16 ++++++++++++++++ proposals/http/wit/deps/cli/run.wit | 2 ++ proposals/http/wit/deps/cli/stdio.wit | 9 +++++++++ proposals/http/wit/deps/cli/terminal.wit | 13 +++++++++++++ .../http/wit/deps/clocks/monotonic-clock.wit | 2 +- proposals/http/wit/deps/filesystem/types.wit | 2 +- proposals/http/wit/deps/io/streams.wit | 8 ++++++-- 11 files changed, 65 insertions(+), 12 deletions(-) diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 343925389..34441a507 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,22 +1,22 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -sha256 = "285865a31d777181b075f39e92bcfe59c89cd6bacce660be1b9a627646956258" -sha512 = "da2622210a9e3eea82b99f1a5b8a44ce5443d009cb943f7bca0bf9cf4360829b289913d7ee727c011f0f72994ea7dc8e661ebcc0a6b34b587297d80cd9b3f7e8" +sha256 = "a690bfee4b365af5ec012cb664c82ce53076bef5263d3da45c5da42271eaf98c" +sha512 = "21e687cb2d8d7ba2ba5bcf40ef43b8c68e4f2c1c6e8dd147166e695b3462a1650d2b806636c8608e8b42d24a498016a003d6127ebb784bf4f5b329ed1d07817e" [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "f27a857de70c1b0dfbabda35812a8de1253089623b1a84ddd066183c6ffac5f8" -sha512 = "9df1b0be1e4925f671fda65d433217798404f8e2e4fa60ff8bfdfd257f0b6d212ea350c141f308cf4cc57fb0b44899b14af1f9af97a05dcd6f8ae00a7594de8d" +sha256 = "b7fbb753c70fe6727ea3456bc2cde3230df69d1f4f004cda7014625783959e50" +sha512 = "99310e017418553a0613247a65aef39e46b08b27f2d3d170465f5ecb97ec9c0ccbcb4e358526440ba6ef9d37cf991d04367ffa6b87d2d8db4e1b36a737f2191e" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "e37bda5e27222621771ba07d2e9daf862a728c31f91024badfc4f9a42c9ae8ee" -sha512 = "81e92f5e4eca0c8f9606f26a1c4eebb3c53a708b57d3f7e7c60e97aa3c18794b72a44c39212de566442e25313b5ccb5b0b7c9070f3600f0c7c584ea9db91e207" +sha256 = "cc45d3ebf145274e7e4d1eb516099c87c68ef6062447e3f8bcd492d60dfa27a8" +sha512 = "0b0af2b253de228fb282f270f5337df728834421000b6a2a789cc47460b36548babd1f77eca698308fef00896ce3c8509071b0da636babd6e87599e4d1400e53" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "f3e976740ed9512674c627c6588864c477a9ff539bb7e55c7b9ceab222399b52" -sha512 = "c785122b4c04e2297e3fa37ae76c149b0a681444da106758cf673023923b69a6b2c65624ffbb6ad31edef02f9fbc677b05c89525f07b1159fe0c997a8c6b1a8f" +sha256 = "f1d1f111840529e06cd5f53726ebac82f344caf64f65a38dfef84e036643ef75" +sha512 = "8a09fb15e4a5d46c910d4a05ed90551166192dcfb28309f08f23237ad926fb4685ce95f06905929cb47e209b291b26d1baa92c3e3dbabf81308654453927ec26" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit index d8005bd38..0fc85e95a 100644 --- a/proposals/http/wit/deps/cli/command.wit +++ b/proposals/http/wit/deps/cli/command.wit @@ -1,7 +1,10 @@ package wasi:cli@0.2.0; +@since(version = 0.2.0) world command { + @since(version = 0.2.0) include imports; + @since(version = 0.2.0) export run; } diff --git a/proposals/http/wit/deps/cli/environment.wit b/proposals/http/wit/deps/cli/environment.wit index 70065233e..2f449bd7c 100644 --- a/proposals/http/wit/deps/cli/environment.wit +++ b/proposals/http/wit/deps/cli/environment.wit @@ -1,3 +1,4 @@ +@since(version = 0.2.0) interface environment { /// Get the POSIX-style environment variables. /// @@ -7,12 +8,15 @@ interface environment { /// Morally, these are a value import, but until value imports are available /// in the component model, this import function should return the same /// values each time it is called. + @since(version = 0.2.0) get-environment: func() -> list>; /// Get the POSIX-style arguments to the program. + @since(version = 0.2.0) get-arguments: func() -> list; /// Return a path that programs should use as their initial current working /// directory, interpreting `.` as shorthand for this. + @since(version = 0.2.0) initial-cwd: func() -> option; } diff --git a/proposals/http/wit/deps/cli/exit.wit b/proposals/http/wit/deps/cli/exit.wit index d0c2b82ae..357e6707b 100644 --- a/proposals/http/wit/deps/cli/exit.wit +++ b/proposals/http/wit/deps/cli/exit.wit @@ -1,4 +1,6 @@ +@since(version = 0.2.0) interface exit { /// Exit the current instance and any linked instances. + @since(version = 0.2.0) exit: func(status: result); } diff --git a/proposals/http/wit/deps/cli/imports.wit b/proposals/http/wit/deps/cli/imports.wit index 083b84a03..cd59ba1c0 100644 --- a/proposals/http/wit/deps/cli/imports.wit +++ b/proposals/http/wit/deps/cli/imports.wit @@ -1,20 +1,36 @@ package wasi:cli@0.2.0; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) include wasi:clocks/imports@0.2.0; + @since(version = 0.2.0) include wasi:filesystem/imports@0.2.0; + @since(version = 0.2.0) include wasi:sockets/imports@0.2.0; + @since(version = 0.2.0) include wasi:random/imports@0.2.0; + @since(version = 0.2.0) include wasi:io/imports@0.2.0; + @since(version = 0.2.0) import environment; + @since(version = 0.2.0) import exit; + @since(version = 0.2.0) import stdin; + @since(version = 0.2.0) import stdout; + @since(version = 0.2.0) import stderr; + @since(version = 0.2.0) import terminal-input; + @since(version = 0.2.0) import terminal-output; + @since(version = 0.2.0) import terminal-stdin; + @since(version = 0.2.0) import terminal-stdout; + @since(version = 0.2.0) import terminal-stderr; } diff --git a/proposals/http/wit/deps/cli/run.wit b/proposals/http/wit/deps/cli/run.wit index a70ee8c03..655346efb 100644 --- a/proposals/http/wit/deps/cli/run.wit +++ b/proposals/http/wit/deps/cli/run.wit @@ -1,4 +1,6 @@ +@since(version = 0.2.0) interface run { /// Run the program. + @since(version = 0.2.0) run: func() -> result; } diff --git a/proposals/http/wit/deps/cli/stdio.wit b/proposals/http/wit/deps/cli/stdio.wit index 31ef35b5a..e9502a93d 100644 --- a/proposals/http/wit/deps/cli/stdio.wit +++ b/proposals/http/wit/deps/cli/stdio.wit @@ -1,17 +1,26 @@ +@since(version = 0.2.0) interface stdin { + @since(version = 0.2.0) use wasi:io/streams@0.2.0.{input-stream}; + @since(version = 0.2.0) get-stdin: func() -> input-stream; } +@since(version = 0.2.0) interface stdout { + @since(version = 0.2.0) use wasi:io/streams@0.2.0.{output-stream}; + @since(version = 0.2.0) get-stdout: func() -> output-stream; } +@since(version = 0.2.0) interface stderr { + @since(version = 0.2.0) use wasi:io/streams@0.2.0.{output-stream}; + @since(version = 0.2.0) get-stderr: func() -> output-stream; } diff --git a/proposals/http/wit/deps/cli/terminal.wit b/proposals/http/wit/deps/cli/terminal.wit index 38c724efc..d305498c6 100644 --- a/proposals/http/wit/deps/cli/terminal.wit +++ b/proposals/http/wit/deps/cli/terminal.wit @@ -3,8 +3,10 @@ /// In the future, this may include functions for disabling echoing, /// disabling input buffering so that keyboard events are sent through /// immediately, querying supported features, and so on. +@since(version = 0.2.0) interface terminal-input { /// The input side of a terminal. + @since(version = 0.2.0) resource terminal-input; } @@ -13,37 +15,48 @@ interface terminal-input { /// In the future, this may include functions for querying the terminal /// size, being notified of terminal size changes, querying supported /// features, and so on. +@since(version = 0.2.0) interface terminal-output { /// The output side of a terminal. + @since(version = 0.2.0) resource terminal-output; } /// An interface providing an optional `terminal-input` for stdin as a /// link-time authority. +@since(version = 0.2.0) interface terminal-stdin { + @since(version = 0.2.0) use terminal-input.{terminal-input}; /// If stdin is connected to a terminal, return a `terminal-input` handle /// allowing further interaction with it. + @since(version = 0.2.0) get-terminal-stdin: func() -> option; } /// An interface providing an optional `terminal-output` for stdout as a /// link-time authority. +@since(version = 0.2.0) interface terminal-stdout { + @since(version = 0.2.0) use terminal-output.{terminal-output}; /// If stdout is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. + @since(version = 0.2.0) get-terminal-stdout: func() -> option; } /// An interface providing an optional `terminal-output` for stderr as a /// link-time authority. +@since(version = 0.2.0) interface terminal-stderr { + @since(version = 0.2.0) use terminal-output.{terminal-output}; /// If stderr is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. + @since(version = 0.2.0) get-terminal-stderr: func() -> option; } diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index cae2363bf..afbd700e1 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -35,7 +35,7 @@ interface monotonic-clock { resolution: func() -> duration; /// Create a `pollable` which will resolve once the specified instant - /// has occured. + /// has occurred. @since(version = 0.2.0) subscribe-instant: func( when: instant, diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index 4900ae2c4..d061d5fd4 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -83,7 +83,7 @@ interface types { /// WASI. At this time, it should be interpreted as a request, and not a /// requirement. data-integrity-sync, - /// Requests that reads be performed at the same level of integrety + /// Requests that reads be performed at the same level of integrity /// requested for writes. This is similar to `O_RSYNC` in POSIX. /// /// The precise semantics of this operation have not yet been defined for diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index a57f20439..b5e2a36ac 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -112,6 +112,10 @@ interface streams { /// promptly, which could even be zero. To wait for the stream to be ready to /// accept data, the `subscribe` function to obtain a `pollable` which can be /// polled for using `wasi:io/poll`. + /// + /// Dropping an `output-stream` while there's still an active write in + /// progress may result in the data being lost. Before dropping the stream, + /// be sure to fully flush your writes. @since(version = 0.2.0) resource output-stream { /// Check readiness for writing. This function never blocks. @@ -192,7 +196,7 @@ interface streams { blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream - /// is ready for more writing, or an error has occured. When this + /// is ready for more writing, or an error has occurred. When this /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an /// error. /// @@ -247,7 +251,7 @@ interface streams { /// Read from one stream and write to another. /// - /// The behavior of splice is equivelant to: + /// The behavior of splice is equivalent to: /// 1. calling `check-write` on the `output-stream` /// 2. calling `read` on the `input-stream` with the smaller of the /// `check-write` permitted length and the `len` provided to `splice` From a62f8c253d8a483c20af8a96cc3f9a3bcb9d917c Mon Sep 17 00:00:00 2001 From: Yosh Date: Tue, 16 Jul 2024 17:18:01 +0200 Subject: [PATCH 1480/1772] re-generate md files --- proposals/http/imports.md | 522 ++++++++++++++++++------------------- proposals/http/proxy.md | 526 +++++++++++++++++++------------------- 2 files changed, 526 insertions(+), 522 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index db11f4cef..e99ef318e 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -4,21 +4,21 @@ It is intended to be included in other worlds.

      -

      Import interface wasi:random/random@0.2.0

      +

      Import interface wasi:random/random@0.2.0

      WASI Random is a random data API.

      It is intended to be portable at least between Unix-family platforms and Windows.

      @@ -51,7 +51,7 @@ represented as a u64.

      • u64
      -

      Import interface wasi:io/error@0.2.0

      +

      Import interface wasi:io/error@0.2.0


      Types

      resource error

      @@ -61,17 +61,15 @@ which provides some human-readable information about the error.

      In the wasi:io package, this resource is returned through the wasi:io/streams/stream-error type.

      To provide more specific error information, other interfaces may -provide functions to further "downcast" this error into more specific -error information. For example, errors returned in streams derived -from filesystem types to be described using the filesystem's own -error-code type, using the function -wasi:filesystem/types/filesystem-error-code, which takes a parameter -borrow<error> and returns -option<wasi:filesystem/types/error-code>.

      +offer functions to "downcast" this error into more specific types. For example, +errors returned from streams derived from filesystem types can be described using +the filesystem's own error-code type. This is done using the function +wasi:filesystem/types/filesystem-error-code, which takes a borrow<error> +parameter and returns an option<wasi:filesystem/types/error-code>.

      The set of functions which can "downcast" an error into a more concrete type is open.

      Functions

      -

      [method]error.to-debug-string: func

      +

      [method]error.to-debug-string: func

      Returns a string that is suitable to assist humans in debugging this error.

      WARNING: The returned string should not be consumed mechanically! @@ -80,13 +78,13 @@ details. Parsing this string is a major platform-compatibility hazard.

      Params
      Return values
        -
      • string
      • +
      • string
      -

      Import interface wasi:io/poll@0.2.0

      +

      Import interface wasi:io/poll@0.2.0

      A poll API intended to let users wait for I/O events on multiple handles at once.


      @@ -94,25 +92,25 @@ at once.

      resource pollable

      pollable represents a single I/O event which may be ready, or not.

      Functions

      -

      [method]pollable.ready: func

      +

      [method]pollable.ready: func

      Return the readiness of a pollable. This function never blocks.

      Returns true when the pollable is ready, and false otherwise.

      Params
      Return values
        -
      • bool
      • +
      • bool
      -

      [method]pollable.block: func

      +

      [method]pollable.block: func

      block returns immediately if the pollable is ready, and otherwise blocks until ready.

      This function is equivalent to calling poll.poll on a list containing only this pollable.

      Params

      poll: func

      Poll for completion on a set of pollables.

      @@ -120,14 +118,17 @@ containing only this pollable.

      interest, and waits until one or more of the events is ready for I/O.

      The result list<u32> contains one or more indices of handles in the argument list that is ready for I/O.

      -

      If the list contains more elements than can be indexed with a u32 -value, this function traps.

      +

      This function traps if either:

      +
        +
      • the list is empty, or:
      • +
      • the list contains more elements than can be indexed with a u32 value.
      • +

      A timeout can be implemented by adding a pollable from the wasi-clocks API to the list.

      This function does not return a result; polling in itself does not do any I/O so it doesn't fail. If any of the I/O sources identified by the pollables has an error, it is indicated by marking the source as -being reaedy for I/O.

      +being ready for I/O.

      Params
      • in: list<borrow<pollable>>
      • @@ -136,7 +137,7 @@ being reaedy for I/O.

        • list<u32>
        -

        Import interface wasi:io/streams@0.2.0

        +

        Import interface wasi:io/streams@0.2.0

        WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

        In the future, the component model is expected to add built-in stream types; @@ -175,14 +176,17 @@ use the subscribe function to obtain a po for using wasi:io/poll.

        resource output-stream

        An output bytestream.

        -

        output-streams are non-blocking to the extent practical on +

        output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also always return promptly, after the number of bytes that can be written promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe function to obtain a pollable which can be -polled for using wasi:io/poll.

        +polled for using wasi:io/poll.

        +

        Dropping an output-stream while there's still an active write in +progress may result in the data being lost. Before dropping the stream, +be sure to fully flush your writes.

        Functions

        -

        [method]input-stream.read: func

        +

        [method]input-stream.read: func

        Perform a non-blocking read from the stream.

        When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -206,51 +210,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

        Params
        Return values
        -

        [method]input-stream.blocking-read: func

        +

        [method]input-stream.blocking-read: func

        Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

        Params
        Return values
        -

        [method]input-stream.skip: func

        +

        [method]input-stream.skip: func

        Skip bytes from a stream. Returns number of bytes skipped.

        Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

        Params
        Return values
        -

        [method]input-stream.blocking-skip: func

        +

        [method]input-stream.blocking-skip: func

        Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

        Params
        Return values
        -

        [method]input-stream.subscribe: func

        +

        [method]input-stream.subscribe: func

        Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -259,13 +263,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

        Params
        Return values
        -

        [method]output-stream.check-write: func

        +

        [method]output-stream.check-write: func

        Check readiness for writing. This function never blocks.

        Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -275,13 +279,13 @@ become ready when this function will report at least 1 byte, or an error.

        Params
        Return values
        -

        [method]output-stream.write: func

        +

        [method]output-stream.write: func

        Perform a write. This function never blocks.

        When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -294,14 +298,14 @@ length of less than or equal to n. Otherwise, this function will trap.

        the last call to check-write provided a permit.

        Params
        Return values
        -

        [method]output-stream.blocking-write-and-flush: func

        +

        [method]output-stream.blocking-write-and-flush: func

        Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

        This is a convenience wrapper around the use of check-write, @@ -325,14 +329,14 @@ let _ = this.check-write(); // eliding error handling

        Params
        Return values
        -

        [method]output-stream.flush: func

        +

        [method]output-stream.flush: func

        Request to flush buffered output. This function never blocks.

        This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -343,26 +347,26 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

        Params
        Return values
        -

        [method]output-stream.blocking-flush: func

        +

        [method]output-stream.blocking-flush: func

        Request to flush buffered output, and block until flush completes and stream is ready for writing again.

        Params
        Return values
        -

        [method]output-stream.subscribe: func

        +

        [method]output-stream.subscribe: func

        Create a pollable which will resolve once the output-stream -is ready for more writing, or an error has occured. When this +is ready for more writing, or an error has occurred. When this pollable is ready, check-write will return ok(n) with n>0, or an error.

        If the stream is closed, this pollable is always ready immediately.

        @@ -371,13 +375,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

        Params
        Return values
        -

        [method]output-stream.write-zeroes: func

        +

        [method]output-stream.write-zeroes: func

        Write zeroes to a stream.

        This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -385,14 +389,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

        Params
        Return values
        -

        [method]output-stream.blocking-write-zeroes-and-flush: func

        +

        [method]output-stream.blocking-write-zeroes-and-flush: func

        Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

        @@ -416,16 +420,16 @@ let _ = this.check-write(); // eliding error handling
        Params
        Return values
        -

        [method]output-stream.splice: func

        +

        [method]output-stream.splice: func

        Read from one stream and write to another.

        -

        The behavior of splice is equivelant to:

        +

        The behavior of splice is equivalent to:

        1. calling check-write on the output-stream
        2. calling read on the input-stream with the smaller of the @@ -438,30 +442,30 @@ let _ = this.check-write(); // eliding error handling than len.

          Params
          Return values
          -

          [method]output-stream.blocking-splice: func

          +

          [method]output-stream.blocking-splice: func

          Read from one stream and write to another, with blocking.

          This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

          Params
          Return values
          -

          Import interface wasi:cli/stdout@0.2.0

          +

          Import interface wasi:cli/stdout@0.2.0


          Types

          type output-stream

          @@ -474,7 +478,7 @@ is ready for reading, before performing the splice.

          -

          Import interface wasi:cli/stderr@0.2.0

          +

          Import interface wasi:cli/stderr@0.2.0


          Types

          type output-stream

          @@ -487,7 +491,7 @@ is ready for reading, before performing the splice.

          -

          Import interface wasi:cli/stdin@0.2.0

          +

          Import interface wasi:cli/stdin@0.2.0


          Types

          type input-stream

          @@ -500,14 +504,13 @@ is ready for reading, before performing the splice.

          -

          Import interface wasi:clocks/monotonic-clock@0.2.0

          +

          Import interface wasi:clocks/monotonic-clock@0.2.0

          WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

          It is intended to be portable at least between Unix-family platforms and Windows.

          A monotonic clock is a clock which has an unspecified initial value, and successive reads of the clock will produce non-decreasing values.

          -

          It is intended for measuring elapsed time.


          Types

          type pollable

          @@ -540,7 +543,7 @@ corresponding to a clock tick.

      subscribe-instant: func

      Create a pollable which will resolve once the specified instant -occured.

      +has occurred.

      Params

      subscribe-duration: func

      -

      Create a pollable which will resolve once the given duration has -elapsed, starting at the time at which this function was called. -occured.

      +

      Create a pollable that will resolve after the specified duration has +elapsed from the time this function is invoked.

      Params
      • when: duration
      • @@ -561,7 +563,7 @@ occured.

        -

        Import interface wasi:http/types@0.2.0

        +

        Import interface wasi:http/types@0.2.0

        This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

        @@ -803,7 +805,7 @@ http-related errors.

        -

        [static]fields.from-list: func

        +

        [static]fields.from-list: func

        Construct an HTTP Fields.

        The resulting fields is mutable.

        The list represents each key-value pair in the Fields. Keys @@ -815,39 +817,39 @@ Value, represented as a list of bytes.

        syntactically invalid, or if a field is forbidden.

        Params
        Return values
        -

        [method]fields.get: func

        +

        [method]fields.get: func

        Get all of the values corresponding to a key. If the key is not present in this fields or is syntactically invalid, an empty list is returned. However, if the key is present but empty, this is represented by a list with one or more empty field-values present.

        Params
        Return values
        -

        [method]fields.has: func

        +

        [method]fields.has: func

        Returns true when the key is present in this fields. If the key is syntactically invalid, false is returned.

        Params
        Return values
          -
        • bool
        • +
        • bool
        -

        [method]fields.set: func

        +

        [method]fields.set: func

        Set all of the values for a key. Clears any existing values for that key, if they have been set.

        Fails with header-error.immutable if the fields are immutable.

        @@ -855,15 +857,15 @@ key, if they have been set.

        the field-values are syntactically invalid.

        Params
        Return values
        -

        [method]fields.delete: func

        +

        [method]fields.delete: func

        Delete all values for a key. Does nothing if no values for the key exist.

        Fails with header-error.immutable if the fields are immutable.

        @@ -871,14 +873,14 @@ exist.

        syntactically invalid.

        Params
        Return values
        -

        [method]fields.append: func

        +

        [method]fields.append: func

        Append a value for a key. Does not change or delete any existing values for that key.

        Fails with header-error.immutable if the fields are immutable.

        @@ -886,15 +888,15 @@ values for that key.

        field-value are syntactically invalid.

        Params
        Return values
        -

        [method]fields.entries: func

        +

        [method]fields.entries: func

        Retrieve the full set of keys and values in the Fields. Like the constructor, the list represents each key-value pair.

        The outer list represents each key-value pair in the Fields. Keys @@ -902,65 +904,65 @@ which have multiple values are represented by multiple entries in this list with the same key.

        Params
        Return values
        -

        [method]fields.clone: func

        +

        [method]fields.clone: func

        Make a deep copy of the Fields. Equivalent in behavior to calling the fields constructor on the return value of entries. The resulting fields is mutable.

        Params
        Return values
        -

        [method]incoming-request.method: func

        +

        [method]incoming-request.method: func

        Returns the method of the incoming request.

        Params
        Return values
        -

        [method]incoming-request.path-with-query: func

        +

        [method]incoming-request.path-with-query: func

        Returns the path with query parameters from the request, as a string.

        Params
        Return values
          -
        • option<string>
        • +
        • option<string>
        -

        [method]incoming-request.scheme: func

        +

        [method]incoming-request.scheme: func

        Returns the protocol scheme from the request.

        Params
        Return values
        -

        [method]incoming-request.authority: func

        +

        [method]incoming-request.authority: func

        Returns the authority from the request, if it was present.

        Params
        Return values
          -
        • option<string>
        • +
        • option<string>
        -

        [method]incoming-request.headers: func

        +

        [method]incoming-request.headers: func

        Get the headers associated with the request.

        The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

        @@ -969,22 +971,22 @@ the parent incoming-request is drop incoming-request before all children are dropped will trap.

        Params
        Return values
        -

        [method]incoming-request.consume: func

        +

        [method]incoming-request.consume: func

        Gives the incoming-body associated with this request. Will only return success at most once, and subsequent calls will return error.

        Params
        Return values

        [constructor]outgoing-request: func

        Construct a new outgoing-request with a default method of GET, and @@ -1005,7 +1007,7 @@ to reject invalid constructions of outgoing-re

        -

        [method]outgoing-request.body: func

        +

        [method]outgoing-request.body: func

        Returns the resource corresponding to the outgoing Body for this Request.

        Returns success on the first call: the outgoing-body resource for @@ -1013,109 +1015,109 @@ this outgoing-request can be retrie calls will return error.

        Params
        Return values
        -

        [method]outgoing-request.method: func

        +

        [method]outgoing-request.method: func

        Get the Method for the Request.

        Params
        Return values
        -

        [method]outgoing-request.set-method: func

        +

        [method]outgoing-request.set-method: func

        Set the Method for the Request. Fails if the string present in a method.other argument is not a syntactically valid method.

        Params
        Return values
          -
        • result
        • +
        • result
        -

        [method]outgoing-request.path-with-query: func

        +

        [method]outgoing-request.path-with-query: func

        Get the combination of the HTTP Path and Query for the Request. When none, this represents an empty Path and empty Query.

        Params
        Return values
          -
        • option<string>
        • +
        • option<string>
        -

        [method]outgoing-request.set-path-with-query: func

        +

        [method]outgoing-request.set-path-with-query: func

        Set the combination of the HTTP Path and Query for the Request. When none, this represents an empty Path and empty Query. Fails is the string given is not a syntactically valid path and query uri component.

        Params
        Return values
          -
        • result
        • +
        • result
        -

        [method]outgoing-request.scheme: func

        +

        [method]outgoing-request.scheme: func

        Get the HTTP Related Scheme for the Request. When none, the implementation may choose an appropriate default scheme.

        Params
        Return values
        -

        [method]outgoing-request.set-scheme: func

        +

        [method]outgoing-request.set-scheme: func

        Set the HTTP Related Scheme for the Request. When none, the implementation may choose an appropriate default scheme. Fails if the string given is not a syntactically valid uri scheme.

        Params
        Return values
          -
        • result
        • +
        • result
        -

        [method]outgoing-request.authority: func

        +

        [method]outgoing-request.authority: func

        Get the HTTP Authority for the Request. A value of none may be used with Related Schemes which do not require an Authority. The HTTP and HTTPS schemes always require an authority.

        Params
        Return values
          -
        • option<string>
        • +
        • option<string>
        -

        [method]outgoing-request.set-authority: func

        +

        [method]outgoing-request.set-authority: func

        Set the HTTP Authority for the Request. A value of none may be used with Related Schemes which do not require an Authority. The HTTP and HTTPS schemes always require an authority. Fails if the string given is not a syntactically valid uri authority.

        Params
        Return values
          -
        • result
        • +
        • result
        -

        [method]outgoing-request.headers: func

        +

        [method]outgoing-request.headers: func

        Get the headers associated with the Request.

        The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

        @@ -1124,11 +1126,11 @@ not a syntactically valid uri authority.

        another component by e.g. outgoing-handler.handle.

        Params
        Return values

        [constructor]request-options: func

        Construct a default request-options value.

        @@ -1136,75 +1138,75 @@ another component by e.g. outgoing-handler.handle.

        -

        [method]request-options.connect-timeout: func

        +

        [method]request-options.connect-timeout: func

        The timeout for the initial connect to the HTTP Server.

        Params
        Return values
        -

        [method]request-options.set-connect-timeout: func

        +

        [method]request-options.set-connect-timeout: func

        Set the timeout for the initial connect to the HTTP Server. An error return value indicates that this timeout is not supported.

        Params
        Return values
          -
        • result
        • +
        • result
        -

        [method]request-options.first-byte-timeout: func

        +

        [method]request-options.first-byte-timeout: func

        The timeout for receiving the first byte of the Response body.

        Params
        Return values
        -

        [method]request-options.set-first-byte-timeout: func

        +

        [method]request-options.set-first-byte-timeout: func

        Set the timeout for receiving the first byte of the Response body. An error return value indicates that this timeout is not supported.

        Params
        Return values
          -
        • result
        • +
        • result
        -

        [method]request-options.between-bytes-timeout: func

        +

        [method]request-options.between-bytes-timeout: func

        The timeout for receiving subsequent chunks of bytes in the Response body stream.

        Params
        Return values
        -

        [method]request-options.set-between-bytes-timeout: func

        +

        [method]request-options.set-between-bytes-timeout: func

        Set the timeout for receiving subsequent chunks of bytes in the Response body stream. An error return value indicates that this timeout is not supported.

        Params
        Return values
          -
        • result
        • +
        • result
        -

        [static]response-outparam.set: func

        +

        [static]response-outparam.set: func

        Set the value of the response-outparam to either send a response, or indicate an error.

        This method consumes the response-outparam to ensure that it is @@ -1214,20 +1216,20 @@ will respond with an error.

        implementation determine how to respond with an HTTP error response.

        Params
        -

        [method]incoming-response.status: func

        +

        [method]incoming-response.status: func

        Returns the status code from the incoming response.

        Params
        Return values
        -

        [method]incoming-response.headers: func

        +

        [method]incoming-response.headers: func

        Returns the headers from the incoming response.

        The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

        @@ -1235,24 +1237,24 @@ implementation determine how to respond with an HTTP error response.

        incoming-response is dropped.

        Params
        Return values
        -

        [method]incoming-response.consume: func

        +

        [method]incoming-response.consume: func

        Returns the incoming body. May be called at most once. Returns error if called additional times.

        Params
        Return values
        -

        [method]incoming-body.stream: func

        +

        [method]incoming-body.stream: func

        Returns the contents of the body, as a stream of bytes.

        Returns success on first call: the stream representing the contents can be retrieved at most once. Subsequent calls will return error.

        @@ -1267,36 +1269,36 @@ and for that backpressure to not inhibit delivery of the trailers if the user does not read the entire body.

        Params
        Return values
        -

        [static]incoming-body.finish: func

        +

        [static]incoming-body.finish: func

        Takes ownership of incoming-body, and returns a future-trailers. This function will trap if the input-stream child is still alive.

        Params
        Return values
        -

        [method]future-trailers.subscribe: func

        +

        [method]future-trailers.subscribe: func

        Returns a pollable which becomes ready when either the trailers have been received, or an error has occurred. When this pollable is ready, the get method will return some.

        Params
        Return values
        -

        [method]future-trailers.get: func

        +

        [method]future-trailers.get: func

        Returns the contents of the trailers, or an error which occurred, once the future is ready.

        The outer option represents future readiness. Users can wait on this @@ -1314,11 +1316,11 @@ resource is immutable, and a child. Use of the set, appendfuture-trailers is dropped.

        Params
        Return values

        [constructor]outgoing-response: func

        Construct an outgoing-response, with a default status-code of 200. @@ -1335,29 +1337,29 @@ If a different status-code is needed, it

        -

        [method]outgoing-response.status-code: func

        +

        [method]outgoing-response.status-code: func

        Get the HTTP Status Code for the Response.

        Params
        Return values
        -

        [method]outgoing-response.set-status-code: func

        +

        [method]outgoing-response.set-status-code: func

        Set the HTTP Status Code for the Response. Fails if the status-code given is not a valid http status code.

        Params
        Return values
          -
        • result
        • +
        • result
        -

        [method]outgoing-response.headers: func

        +

        [method]outgoing-response.headers: func

        Get the headers associated with the Request.

        The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

        @@ -1366,26 +1368,26 @@ given is not a valid http status code.

        another component by e.g. outgoing-handler.handle.

        Params
        Return values
        -

        [method]outgoing-response.body: func

        +

        [method]outgoing-response.body: func

        Returns the resource corresponding to the outgoing Body for this Response.

        Returns success on the first call: the outgoing-body resource for this outgoing-response can be retrieved at most once. Subsequent calls will return error.

        Params
        Return values
        -

        [method]outgoing-body.write: func

        +

        [method]outgoing-body.write: func

        Returns a stream for writing the body contents.

        The returned output-stream is a child resource: it must be dropped before the parent outgoing-body resource is dropped (or finished), @@ -1395,13 +1397,13 @@ this outgoing-body may be retrieved at will return error.

        Params
        Return values
        -

        [static]outgoing-body.finish: func

        +

        [static]outgoing-body.finish: func

        Finalize an outgoing body, optionally providing trailers. This must be called to signal that the response is complete. If the outgoing-body is dropped without calling outgoing-body.finalize, the implementation @@ -1412,26 +1414,26 @@ to the body (via write) does not match the value given in the Content-Length.

        Params
        Return values
        -

        [method]future-incoming-response.subscribe: func

        +

        [method]future-incoming-response.subscribe: func

        Returns a pollable which becomes ready when either the Response has been received, or an error has occurred. When this pollable is ready, the get method will return some.

        Params
        Return values
        -

        [method]future-incoming-response.get: func

        +

        [method]future-incoming-response.get: func

        Returns the incoming HTTP Response, or an error, once one is ready.

        The outer option represents future readiness. Users can wait on this option to become some using the subscribe method.

        @@ -1445,13 +1447,13 @@ but those will be reported by the incoming-bodyoutput-stream child.

        Params
        Return values
        -

        Import interface wasi:http/outgoing-handler@0.2.0

        +

        Import interface wasi:http/outgoing-handler@0.2.0

        This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


        @@ -1488,7 +1490,7 @@ through the future-incoming-response
      • result<own<future-incoming-response>, error-code>
      -

      Import interface wasi:clocks/wall-clock@0.2.0

      +

      Import interface wasi:clocks/wall-clock@0.2.0

      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

      diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index af5c1933f..ac879d4c0 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -6,26 +6,26 @@ outgoing HTTP requests.

      -

      Import interface wasi:io/poll@0.2.0

      +

      Import interface wasi:io/poll@0.2.0

      A poll API intended to let users wait for I/O events on multiple handles at once.


      @@ -33,25 +33,25 @@ at once.

      resource pollable

      pollable represents a single I/O event which may be ready, or not.

      Functions

      -

      [method]pollable.ready: func

      +

      [method]pollable.ready: func

      Return the readiness of a pollable. This function never blocks.

      Returns true when the pollable is ready, and false otherwise.

      Params
      Return values
        -
      • bool
      • +
      • bool
      -

      [method]pollable.block: func

      +

      [method]pollable.block: func

      block returns immediately if the pollable is ready, and otherwise blocks until ready.

      This function is equivalent to calling poll.poll on a list containing only this pollable.

      Params

      poll: func

      Poll for completion on a set of pollables.

      @@ -59,14 +59,17 @@ containing only this pollable.

      interest, and waits until one or more of the events is ready for I/O.

      The result list<u32> contains one or more indices of handles in the argument list that is ready for I/O.

      -

      If the list contains more elements than can be indexed with a u32 -value, this function traps.

      +

      This function traps if either:

      +
        +
      • the list is empty, or:
      • +
      • the list contains more elements than can be indexed with a u32 value.
      • +

      A timeout can be implemented by adding a pollable from the wasi-clocks API to the list.

      This function does not return a result; polling in itself does not do any I/O so it doesn't fail. If any of the I/O sources identified by the pollables has an error, it is indicated by marking the source as -being reaedy for I/O.

      +being ready for I/O.

      Params
      • in: list<borrow<pollable>>
      • @@ -75,14 +78,13 @@ being reaedy for I/O.

        • list<u32>
        -

        Import interface wasi:clocks/monotonic-clock@0.2.0

        +

        Import interface wasi:clocks/monotonic-clock@0.2.0

        WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

        It is intended to be portable at least between Unix-family platforms and Windows.

        A monotonic clock is a clock which has an unspecified initial value, and successive reads of the clock will produce non-decreasing values.

        -

        It is intended for measuring elapsed time.


        Types

        type pollable

        @@ -115,7 +117,7 @@ corresponding to a clock tick.

      subscribe-instant: func

      Create a pollable which will resolve once the specified instant -occured.

      +has occurred.

      Params

      subscribe-duration: func

      -

      Create a pollable which will resolve once the given duration has -elapsed, starting at the time at which this function was called. -occured.

      +

      Create a pollable that will resolve after the specified duration has +elapsed from the time this function is invoked.

      Params
      • when: duration
      • @@ -136,7 +137,7 @@ occured.

        -

        Import interface wasi:io/error@0.2.0

        +

        Import interface wasi:io/error@0.2.0


        Types

        resource error

        @@ -146,17 +147,15 @@ which provides some human-readable information about the error.

        In the wasi:io package, this resource is returned through the wasi:io/streams/stream-error type.

        To provide more specific error information, other interfaces may -provide functions to further "downcast" this error into more specific -error information. For example, errors returned in streams derived -from filesystem types to be described using the filesystem's own -error-code type, using the function -wasi:filesystem/types/filesystem-error-code, which takes a parameter -borrow<error> and returns -option<wasi:filesystem/types/error-code>.

        +offer functions to "downcast" this error into more specific types. For example, +errors returned from streams derived from filesystem types can be described using +the filesystem's own error-code type. This is done using the function +wasi:filesystem/types/filesystem-error-code, which takes a borrow<error> +parameter and returns an option<wasi:filesystem/types/error-code>.

        The set of functions which can "downcast" an error into a more concrete type is open.

        Functions

        -

        [method]error.to-debug-string: func

        +

        [method]error.to-debug-string: func

        Returns a string that is suitable to assist humans in debugging this error.

        WARNING: The returned string should not be consumed mechanically! @@ -165,13 +164,13 @@ details. Parsing this string is a major platform-compatibility hazard.

        Params
        Return values
          -
        • string
        • +
        • string
        -

        Import interface wasi:io/streams@0.2.0

        +

        Import interface wasi:io/streams@0.2.0

        WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

        In the future, the component model is expected to add built-in stream types; @@ -210,14 +209,17 @@ use the subscribe function to obtain a po for using wasi:io/poll.

        resource output-stream

        An output bytestream.

        -

        output-streams are non-blocking to the extent practical on +

        output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also always return promptly, after the number of bytes that can be written promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe function to obtain a pollable which can be -polled for using wasi:io/poll.

        +polled for using wasi:io/poll.

        +

        Dropping an output-stream while there's still an active write in +progress may result in the data being lost. Before dropping the stream, +be sure to fully flush your writes.

        Functions

        -

        [method]input-stream.read: func

        +

        [method]input-stream.read: func

        Perform a non-blocking read from the stream.

        When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -241,51 +243,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

        Params
        Return values
        -

        [method]input-stream.blocking-read: func

        +

        [method]input-stream.blocking-read: func

        Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

        Params
        Return values
        -

        [method]input-stream.skip: func

        +

        [method]input-stream.skip: func

        Skip bytes from a stream. Returns number of bytes skipped.

        Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

        Params
        Return values
        -

        [method]input-stream.blocking-skip: func

        +

        [method]input-stream.blocking-skip: func

        Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

        Params
        Return values
        -

        [method]input-stream.subscribe: func

        +

        [method]input-stream.subscribe: func

        Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -294,13 +296,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

        Params
        Return values
        -

        [method]output-stream.check-write: func

        +

        [method]output-stream.check-write: func

        Check readiness for writing. This function never blocks.

        Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -310,13 +312,13 @@ become ready when this function will report at least 1 byte, or an error.

        Params
        Return values
        -

        [method]output-stream.write: func

        +

        [method]output-stream.write: func

        Perform a write. This function never blocks.

        When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -329,14 +331,14 @@ length of less than or equal to n. Otherwise, this function will trap.

        the last call to check-write provided a permit.

        Params
        Return values
        -

        [method]output-stream.blocking-write-and-flush: func

        +

        [method]output-stream.blocking-write-and-flush: func

        Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

        This is a convenience wrapper around the use of check-write, @@ -360,14 +362,14 @@ let _ = this.check-write(); // eliding error handling

        Params
        Return values
        -

        [method]output-stream.flush: func

        +

        [method]output-stream.flush: func

        Request to flush buffered output. This function never blocks.

        This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -378,26 +380,26 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

        Params
        Return values
        -

        [method]output-stream.blocking-flush: func

        +

        [method]output-stream.blocking-flush: func

        Request to flush buffered output, and block until flush completes and stream is ready for writing again.

        Params
        Return values
        -

        [method]output-stream.subscribe: func

        +

        [method]output-stream.subscribe: func

        Create a pollable which will resolve once the output-stream -is ready for more writing, or an error has occured. When this +is ready for more writing, or an error has occurred. When this pollable is ready, check-write will return ok(n) with n>0, or an error.

        If the stream is closed, this pollable is always ready immediately.

        @@ -406,13 +408,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

        Params
        Return values
        -

        [method]output-stream.write-zeroes: func

        +

        [method]output-stream.write-zeroes: func

        Write zeroes to a stream.

        This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -420,14 +422,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

        Params
        Return values
        -

        [method]output-stream.blocking-write-zeroes-and-flush: func

        +

        [method]output-stream.blocking-write-zeroes-and-flush: func

        Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

        @@ -451,16 +453,16 @@ let _ = this.check-write(); // eliding error handling
        Params
        Return values
        -

        [method]output-stream.splice: func

        +

        [method]output-stream.splice: func

        Read from one stream and write to another.

        -

        The behavior of splice is equivelant to:

        +

        The behavior of splice is equivalent to:

        1. calling check-write on the output-stream
        2. calling read on the input-stream with the smaller of the @@ -473,30 +475,30 @@ let _ = this.check-write(); // eliding error handling than len.

          Params
          Return values
          -

          [method]output-stream.blocking-splice: func

          +

          [method]output-stream.blocking-splice: func

          Read from one stream and write to another, with blocking.

          This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

          Params
          Return values
          -

          Import interface wasi:http/types@0.2.0

          +

          Import interface wasi:http/types@0.2.0

          This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

          @@ -738,7 +740,7 @@ http-related errors.

          -

          [static]fields.from-list: func

          +

          [static]fields.from-list: func

          Construct an HTTP Fields.

          The resulting fields is mutable.

          The list represents each key-value pair in the Fields. Keys @@ -750,39 +752,39 @@ Value, represented as a list of bytes.

          syntactically invalid, or if a field is forbidden.

          Params
          Return values
          -

          [method]fields.get: func

          +

          [method]fields.get: func

          Get all of the values corresponding to a key. If the key is not present in this fields or is syntactically invalid, an empty list is returned. However, if the key is present but empty, this is represented by a list with one or more empty field-values present.

          Params
          Return values
          -

          [method]fields.has: func

          +

          [method]fields.has: func

          Returns true when the key is present in this fields. If the key is syntactically invalid, false is returned.

          Params
          Return values
            -
          • bool
          • +
          • bool
          -

          [method]fields.set: func

          +

          [method]fields.set: func

          Set all of the values for a key. Clears any existing values for that key, if they have been set.

          Fails with header-error.immutable if the fields are immutable.

          @@ -790,15 +792,15 @@ key, if they have been set.

          the field-values are syntactically invalid.

          Params
          Return values
          -

          [method]fields.delete: func

          +

          [method]fields.delete: func

          Delete all values for a key. Does nothing if no values for the key exist.

          Fails with header-error.immutable if the fields are immutable.

          @@ -806,14 +808,14 @@ exist.

          syntactically invalid.

          Params
          Return values
          -

          [method]fields.append: func

          +

          [method]fields.append: func

          Append a value for a key. Does not change or delete any existing values for that key.

          Fails with header-error.immutable if the fields are immutable.

          @@ -821,15 +823,15 @@ values for that key.

          field-value are syntactically invalid.

          Params
          Return values
          -

          [method]fields.entries: func

          +

          [method]fields.entries: func

          Retrieve the full set of keys and values in the Fields. Like the constructor, the list represents each key-value pair.

          The outer list represents each key-value pair in the Fields. Keys @@ -837,65 +839,65 @@ which have multiple values are represented by multiple entries in this list with the same key.

          Params
          Return values
          -

          [method]fields.clone: func

          +

          [method]fields.clone: func

          Make a deep copy of the Fields. Equivalent in behavior to calling the fields constructor on the return value of entries. The resulting fields is mutable.

          Params
          Return values
          -

          [method]incoming-request.method: func

          +

          [method]incoming-request.method: func

          Returns the method of the incoming request.

          Params
          Return values
          -

          [method]incoming-request.path-with-query: func

          +

          [method]incoming-request.path-with-query: func

          Returns the path with query parameters from the request, as a string.

          Params
          Return values
            -
          • option<string>
          • +
          • option<string>
          -

          [method]incoming-request.scheme: func

          +

          [method]incoming-request.scheme: func

          Returns the protocol scheme from the request.

          Params
          Return values
          -

          [method]incoming-request.authority: func

          +

          [method]incoming-request.authority: func

          Returns the authority from the request, if it was present.

          Params
          Return values
            -
          • option<string>
          • +
          • option<string>
          -

          [method]incoming-request.headers: func

          +

          [method]incoming-request.headers: func

          Get the headers associated with the request.

          The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

          @@ -904,22 +906,22 @@ the parent incoming-request is drop incoming-request before all children are dropped will trap.

          Params
          Return values
          -

          [method]incoming-request.consume: func

          +

          [method]incoming-request.consume: func

          Gives the incoming-body associated with this request. Will only return success at most once, and subsequent calls will return error.

          Params
          Return values

          [constructor]outgoing-request: func

          Construct a new outgoing-request with a default method of GET, and @@ -940,7 +942,7 @@ to reject invalid constructions of outgoing-re

          -

          [method]outgoing-request.body: func

          +

          [method]outgoing-request.body: func

          Returns the resource corresponding to the outgoing Body for this Request.

          Returns success on the first call: the outgoing-body resource for @@ -948,109 +950,109 @@ this outgoing-request can be retrie calls will return error.

          Params
          Return values
          -

          [method]outgoing-request.method: func

          +

          [method]outgoing-request.method: func

          Get the Method for the Request.

          Params
          Return values
          -

          [method]outgoing-request.set-method: func

          +

          [method]outgoing-request.set-method: func

          Set the Method for the Request. Fails if the string present in a method.other argument is not a syntactically valid method.

          Params
          Return values
            -
          • result
          • +
          • result
          -

          [method]outgoing-request.path-with-query: func

          +

          [method]outgoing-request.path-with-query: func

          Get the combination of the HTTP Path and Query for the Request. When none, this represents an empty Path and empty Query.

          Params
          Return values
            -
          • option<string>
          • +
          • option<string>
          -

          [method]outgoing-request.set-path-with-query: func

          +

          [method]outgoing-request.set-path-with-query: func

          Set the combination of the HTTP Path and Query for the Request. When none, this represents an empty Path and empty Query. Fails is the string given is not a syntactically valid path and query uri component.

          Params
          Return values
            -
          • result
          • +
          • result
          -

          [method]outgoing-request.scheme: func

          +

          [method]outgoing-request.scheme: func

          Get the HTTP Related Scheme for the Request. When none, the implementation may choose an appropriate default scheme.

          Params
          Return values
          -

          [method]outgoing-request.set-scheme: func

          +

          [method]outgoing-request.set-scheme: func

          Set the HTTP Related Scheme for the Request. When none, the implementation may choose an appropriate default scheme. Fails if the string given is not a syntactically valid uri scheme.

          Params
          Return values
            -
          • result
          • +
          • result
          -

          [method]outgoing-request.authority: func

          +

          [method]outgoing-request.authority: func

          Get the HTTP Authority for the Request. A value of none may be used with Related Schemes which do not require an Authority. The HTTP and HTTPS schemes always require an authority.

          Params
          Return values
            -
          • option<string>
          • +
          • option<string>
          -

          [method]outgoing-request.set-authority: func

          +

          [method]outgoing-request.set-authority: func

          Set the HTTP Authority for the Request. A value of none may be used with Related Schemes which do not require an Authority. The HTTP and HTTPS schemes always require an authority. Fails if the string given is not a syntactically valid uri authority.

          Params
          Return values
            -
          • result
          • +
          • result
          -

          [method]outgoing-request.headers: func

          +

          [method]outgoing-request.headers: func

          Get the headers associated with the Request.

          The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

          @@ -1059,11 +1061,11 @@ not a syntactically valid uri authority.

          another component by e.g. outgoing-handler.handle.

          Params
          Return values

          [constructor]request-options: func

          Construct a default request-options value.

          @@ -1071,75 +1073,75 @@ another component by e.g. outgoing-handler.handle.

          -

          [method]request-options.connect-timeout: func

          +

          [method]request-options.connect-timeout: func

          The timeout for the initial connect to the HTTP Server.

          Params
          Return values
          -

          [method]request-options.set-connect-timeout: func

          +

          [method]request-options.set-connect-timeout: func

          Set the timeout for the initial connect to the HTTP Server. An error return value indicates that this timeout is not supported.

          Params
          Return values
            -
          • result
          • +
          • result
          -

          [method]request-options.first-byte-timeout: func

          +

          [method]request-options.first-byte-timeout: func

          The timeout for receiving the first byte of the Response body.

          Params
          Return values
          -

          [method]request-options.set-first-byte-timeout: func

          +

          [method]request-options.set-first-byte-timeout: func

          Set the timeout for receiving the first byte of the Response body. An error return value indicates that this timeout is not supported.

          Params
          Return values
            -
          • result
          • +
          • result
          -

          [method]request-options.between-bytes-timeout: func

          +

          [method]request-options.between-bytes-timeout: func

          The timeout for receiving subsequent chunks of bytes in the Response body stream.

          Params
          Return values
          -

          [method]request-options.set-between-bytes-timeout: func

          +

          [method]request-options.set-between-bytes-timeout: func

          Set the timeout for receiving subsequent chunks of bytes in the Response body stream. An error return value indicates that this timeout is not supported.

          Params
          Return values
            -
          • result
          • +
          • result
          -

          [static]response-outparam.set: func

          +

          [static]response-outparam.set: func

          Set the value of the response-outparam to either send a response, or indicate an error.

          This method consumes the response-outparam to ensure that it is @@ -1149,20 +1151,20 @@ will respond with an error.

          implementation determine how to respond with an HTTP error response.

          Params
          -

          [method]incoming-response.status: func

          +

          [method]incoming-response.status: func

          Returns the status code from the incoming response.

          Params
          Return values
          -

          [method]incoming-response.headers: func

          +

          [method]incoming-response.headers: func

          Returns the headers from the incoming response.

          The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

          @@ -1170,24 +1172,24 @@ implementation determine how to respond with an HTTP error response.

          incoming-response is dropped.

          Params
          Return values
          -

          [method]incoming-response.consume: func

          +

          [method]incoming-response.consume: func

          Returns the incoming body. May be called at most once. Returns error if called additional times.

          Params
          Return values
          -

          [method]incoming-body.stream: func

          +

          [method]incoming-body.stream: func

          Returns the contents of the body, as a stream of bytes.

          Returns success on first call: the stream representing the contents can be retrieved at most once. Subsequent calls will return error.

          @@ -1202,36 +1204,36 @@ and for that backpressure to not inhibit delivery of the trailers if the user does not read the entire body.

          Params
          Return values
          -

          [static]incoming-body.finish: func

          +

          [static]incoming-body.finish: func

          Takes ownership of incoming-body, and returns a future-trailers. This function will trap if the input-stream child is still alive.

          Params
          Return values
          -

          [method]future-trailers.subscribe: func

          +

          [method]future-trailers.subscribe: func

          Returns a pollable which becomes ready when either the trailers have been received, or an error has occurred. When this pollable is ready, the get method will return some.

          Params
          Return values
          -

          [method]future-trailers.get: func

          +

          [method]future-trailers.get: func

          Returns the contents of the trailers, or an error which occurred, once the future is ready.

          The outer option represents future readiness. Users can wait on this @@ -1249,11 +1251,11 @@ resource is immutable, and a child. Use of the set, appendfuture-trailers is dropped.

          Params
          Return values

          [constructor]outgoing-response: func

          Construct an outgoing-response, with a default status-code of 200. @@ -1270,29 +1272,29 @@ If a different status-code is needed, it

          -

          [method]outgoing-response.status-code: func

          +

          [method]outgoing-response.status-code: func

          Get the HTTP Status Code for the Response.

          Params
          Return values
          -

          [method]outgoing-response.set-status-code: func

          +

          [method]outgoing-response.set-status-code: func

          Set the HTTP Status Code for the Response. Fails if the status-code given is not a valid http status code.

          Params
          Return values
            -
          • result
          • +
          • result
          -

          [method]outgoing-response.headers: func

          +

          [method]outgoing-response.headers: func

          Get the headers associated with the Request.

          The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

          @@ -1301,26 +1303,26 @@ given is not a valid http status code.

          another component by e.g. outgoing-handler.handle.

          Params
          Return values
          -

          [method]outgoing-response.body: func

          +

          [method]outgoing-response.body: func

          Returns the resource corresponding to the outgoing Body for this Response.

          Returns success on the first call: the outgoing-body resource for this outgoing-response can be retrieved at most once. Subsequent calls will return error.

          Params
          Return values
          -

          [method]outgoing-body.write: func

          +

          [method]outgoing-body.write: func

          Returns a stream for writing the body contents.

          The returned output-stream is a child resource: it must be dropped before the parent outgoing-body resource is dropped (or finished), @@ -1330,13 +1332,13 @@ this outgoing-body may be retrieved at will return error.

          Params
          Return values
          -

          [static]outgoing-body.finish: func

          +

          [static]outgoing-body.finish: func

          Finalize an outgoing body, optionally providing trailers. This must be called to signal that the response is complete. If the outgoing-body is dropped without calling outgoing-body.finalize, the implementation @@ -1347,26 +1349,26 @@ to the body (via write) does not match the value given in the Content-Length.

          Params
          Return values
          -

          [method]future-incoming-response.subscribe: func

          +

          [method]future-incoming-response.subscribe: func

          Returns a pollable which becomes ready when either the Response has been received, or an error has occurred. When this pollable is ready, the get method will return some.

          Params
          Return values
          -

          [method]future-incoming-response.get: func

          +

          [method]future-incoming-response.get: func

          Returns the incoming HTTP Response, or an error, once one is ready.

          The outer option represents future readiness. Users can wait on this option to become some using the subscribe method.

          @@ -1380,13 +1382,13 @@ but those will be reported by the incoming-bodyoutput-stream child.

          Params
          Return values
          -

          Import interface wasi:random/random@0.2.0

          +

          Import interface wasi:random/random@0.2.0

          WASI Random is a random data API.

          It is intended to be portable at least between Unix-family platforms and Windows.

          @@ -1419,7 +1421,7 @@ represented as a u64.

          • u64
          -

          Import interface wasi:cli/stdout@0.2.0

          +

          Import interface wasi:cli/stdout@0.2.0


          Types

          type output-stream

          @@ -1432,7 +1434,7 @@ represented as a u64.

          -

          Import interface wasi:cli/stderr@0.2.0

          +

          Import interface wasi:cli/stderr@0.2.0


          Types

          type output-stream

          @@ -1445,7 +1447,7 @@ represented as a u64.

          -

          Import interface wasi:cli/stdin@0.2.0

          +

          Import interface wasi:cli/stdin@0.2.0


          Types

          type input-stream

          @@ -1458,7 +1460,7 @@ represented as a u64.

          -

          Import interface wasi:http/outgoing-handler@0.2.0

          +

          Import interface wasi:http/outgoing-handler@0.2.0

          This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


          @@ -1495,7 +1497,7 @@ through the future-incoming-response
        3. result<own<future-incoming-response>, error-code>
      -

      Import interface wasi:clocks/wall-clock@0.2.0

      +

      Import interface wasi:clocks/wall-clock@0.2.0

      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

      @@ -1536,7 +1538,7 @@ also known as Unix Time.
    3. datetime
    4. -

      Export interface wasi:http/incoming-handler@0.2.0

      +

      Export interface wasi:http/incoming-handler@0.2.0


      Types

      type incoming-request

      From a98439060b7bd35abe5aa89af4ae2007d65bc8e8 Mon Sep 17 00:00:00 2001 From: Yosh Date: Tue, 16 Jul 2024 17:21:45 +0200 Subject: [PATCH 1481/1772] update wit-bindgen version --- proposals/http/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index 43efdf3a5..8a72c4d3f 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -18,5 +18,5 @@ jobs: ./wit-deps lock --check - uses: WebAssembly/wit-abi-up-to-date@v21 with: - wit-bindgen: '0.17.0' + wit-bindgen: '0.26.0' worlds: 'imports proxy' From a6ab5f769e42ea9ee21821445683bcfae9456496 Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 17 Jul 2024 04:49:02 +0200 Subject: [PATCH 1482/1772] Change `wasi:clocks` from `include` to `import` in `wasi:http/proxy` (#115) * Change `wasi:clocks` from `include` to `import` * gen docs --- proposals/http/imports.md | 312 +++++++++++++++++------------------ proposals/http/proxy.md | 84 +++++----- proposals/http/wit/proxy.wit | 4 +- 3 files changed, 201 insertions(+), 199 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index e99ef318e..dce2c7ae1 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -4,20 +4,173 @@ It is intended to be included in other worlds.

      +

      Import interface wasi:io/poll@0.2.0

      +

      A poll API intended to let users wait for I/O events on multiple handles +at once.

      +
      +

      Types

      +

      resource pollable

      +

      pollable represents a single I/O event which may be ready, or not.

      +

      Functions

      +

      [method]pollable.ready: func

      +

      Return the readiness of a pollable. This function never blocks.

      +

      Returns true when the pollable is ready, and false otherwise.

      +
      Params
      + +
      Return values
      +
        +
      • bool
      • +
      +

      [method]pollable.block: func

      +

      block returns immediately if the pollable is ready, and otherwise +blocks until ready.

      +

      This function is equivalent to calling poll.poll on a list +containing only this pollable.

      +
      Params
      + +

      poll: func

      +

      Poll for completion on a set of pollables.

      +

      This function takes a list of pollables, which identify I/O sources of +interest, and waits until one or more of the events is ready for I/O.

      +

      The result list<u32> contains one or more indices of handles in the +argument list that is ready for I/O.

      +

      This function traps if either:

      +
        +
      • the list is empty, or:
      • +
      • the list contains more elements than can be indexed with a u32 value.
      • +
      +

      A timeout can be implemented by adding a pollable from the +wasi-clocks API to the list.

      +

      This function does not return a result; polling in itself does not +do any I/O so it doesn't fail. If any of the I/O sources identified by +the pollables has an error, it is indicated by marking the source as +being ready for I/O.

      +
      Params
      + +
      Return values
      +
        +
      • list<u32>
      • +
      +

      Import interface wasi:clocks/monotonic-clock@0.2.0

      +

      WASI Monotonic Clock is a clock API intended to let users measure elapsed +time.

      +

      It is intended to be portable at least between Unix-family platforms and +Windows.

      +

      A monotonic clock is a clock which has an unspecified initial value, and +successive reads of the clock will produce non-decreasing values.

      +
      +

      Types

      +

      type pollable

      +

      pollable

      +

      +#### `type instant` +`u64` +

      An instant in time, in nanoseconds. An instant is relative to an +unspecified initial value, and can only be compared to instances from +the same monotonic-clock. +

      type duration

      +

      u64

      +

      A duration of time, in nanoseconds. +


      +

      Functions

      +

      now: func

      +

      Read the current value of the clock.

      +

      The clock is monotonic, therefore calling this function repeatedly will +produce a sequence of non-decreasing values.

      +
      Return values
      + +

      resolution: func

      +

      Query the resolution of the clock. Returns the duration of time +corresponding to a clock tick.

      +
      Return values
      + +

      subscribe-instant: func

      +

      Create a pollable which will resolve once the specified instant +has occurred.

      +
      Params
      + +
      Return values
      + +

      subscribe-duration: func

      +

      Create a pollable that will resolve after the specified duration has +elapsed from the time this function is invoked.

      +
      Params
      + +
      Return values
      + +

      Import interface wasi:clocks/wall-clock@0.2.0

      +

      WASI Wall Clock is a clock API intended to let users query the current +time. The name "wall" makes an analogy to a "clock on the wall", which +is not necessarily monotonic as it may be reset.

      +

      It is intended to be portable at least between Unix-family platforms and +Windows.

      +

      A wall clock is a clock which measures the date and time according to +some external reference.

      +

      External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time.

      +

      It is intended for reporting the current date and time for humans.

      +
      +

      Types

      +

      record datetime

      +

      A time and date in seconds plus nanoseconds.

      +
      Record Fields
      +
        +
      • seconds: u64
      • +
      • nanoseconds: u32
      • +
      +
      +

      Functions

      +

      now: func

      +

      Read the current value of the clock.

      +

      This clock is not monotonic, therefore calling this function repeatedly +will not necessarily produce a sequence of non-decreasing values.

      +

      The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, +also known as Unix Time.

      +

      The nanoseconds field of the output is always less than 1000000000.

      +
      Return values
      + +

      resolution: func

      +

      Query the resolution of the clock.

      +

      The nanoseconds field of the output is always less than 1000000000.

      +
      Return values
      +

      Import interface wasi:random/random@0.2.0

      WASI Random is a random data API.

      It is intended to be portable at least between Unix-family platforms and @@ -84,59 +237,6 @@ hazard.

      • string
      -

      Import interface wasi:io/poll@0.2.0

      -

      A poll API intended to let users wait for I/O events on multiple handles -at once.

      -
      -

      Types

      -

      resource pollable

      -

      pollable represents a single I/O event which may be ready, or not.

      -

      Functions

      -

      [method]pollable.ready: func

      -

      Return the readiness of a pollable. This function never blocks.

      -

      Returns true when the pollable is ready, and false otherwise.

      -
      Params
      - -
      Return values
      -
        -
      • bool
      • -
      -

      [method]pollable.block: func

      -

      block returns immediately if the pollable is ready, and otherwise -blocks until ready.

      -

      This function is equivalent to calling poll.poll on a list -containing only this pollable.

      -
      Params
      - -

      poll: func

      -

      Poll for completion on a set of pollables.

      -

      This function takes a list of pollables, which identify I/O sources of -interest, and waits until one or more of the events is ready for I/O.

      -

      The result list<u32> contains one or more indices of handles in the -argument list that is ready for I/O.

      -

      This function traps if either:

      -
        -
      • the list is empty, or:
      • -
      • the list contains more elements than can be indexed with a u32 value.
      • -
      -

      A timeout can be implemented by adding a pollable from the -wasi-clocks API to the list.

      -

      This function does not return a result; polling in itself does not -do any I/O so it doesn't fail. If any of the I/O sources identified by -the pollables has an error, it is indicated by marking the source as -being ready for I/O.

      -
      Params
      - -
      Return values
      -
        -
      • list<u32>
      • -

      Import interface wasi:io/streams@0.2.0

      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

      @@ -504,65 +604,6 @@ is ready for reading, before performing the splice.

      -

      Import interface wasi:clocks/monotonic-clock@0.2.0

      -

      WASI Monotonic Clock is a clock API intended to let users measure elapsed -time.

      -

      It is intended to be portable at least between Unix-family platforms and -Windows.

      -

      A monotonic clock is a clock which has an unspecified initial value, and -successive reads of the clock will produce non-decreasing values.

      -
      -

      Types

      -

      type pollable

      -

      pollable

      -

      -#### `type instant` -`u64` -

      An instant in time, in nanoseconds. An instant is relative to an -unspecified initial value, and can only be compared to instances from -the same monotonic-clock. -

      type duration

      -

      u64

      -

      A duration of time, in nanoseconds. -


      -

      Functions

      -

      now: func

      -

      Read the current value of the clock.

      -

      The clock is monotonic, therefore calling this function repeatedly will -produce a sequence of non-decreasing values.

      -
      Return values
      - -

      resolution: func

      -

      Query the resolution of the clock. Returns the duration of time -corresponding to a clock tick.

      -
      Return values
      - -

      subscribe-instant: func

      -

      Create a pollable which will resolve once the specified instant -has occurred.

      -
      Params
      - -
      Return values
      - -

      subscribe-duration: func

      -

      Create a pollable that will resolve after the specified duration has -elapsed from the time this function is invoked.

      -
      Params
      - -
      Return values
      -

      Import interface wasi:http/types@0.2.0

      This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as @@ -1490,44 +1531,3 @@ through the future-incoming-response

    5. result<own<future-incoming-response>, error-code>
    6. -

      Import interface wasi:clocks/wall-clock@0.2.0

      -

      WASI Wall Clock is a clock API intended to let users query the current -time. The name "wall" makes an analogy to a "clock on the wall", which -is not necessarily monotonic as it may be reset.

      -

      It is intended to be portable at least between Unix-family platforms and -Windows.

      -

      A wall clock is a clock which measures the date and time according to -some external reference.

      -

      External references may be reset, so this clock is not necessarily -monotonic, making it unsuitable for measuring elapsed time.

      -

      It is intended for reporting the current date and time for humans.

      -
      -

      Types

      -

      record datetime

      -

      A time and date in seconds plus nanoseconds.

      -
      Record Fields
      -
        -
      • seconds: u64
      • -
      • nanoseconds: u32
      • -
      -
      -

      Functions

      -

      now: func

      -

      Read the current value of the clock.

      -

      This clock is not monotonic, therefore calling this function repeatedly -will not necessarily produce a sequence of non-decreasing values.

      -

      The returned timestamps represent the number of seconds since -1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, -also known as Unix Time.

      -

      The nanoseconds field of the output is always less than 1000000000.

      -
      Return values
      - -

      resolution: func

      -

      Query the resolution of the clock.

      -

      The nanoseconds field of the output is always less than 1000000000.

      -
      Return values
      - diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index ac879d4c0..528ba1cb4 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -11,12 +11,12 @@ outgoing HTTP requests.

    7. interface wasi:io/error@0.2.0
    8. interface wasi:io/streams@0.2.0
    9. interface wasi:http/types@0.2.0
    10. +
    11. interface wasi:clocks/wall-clock@0.2.0
    12. interface wasi:random/random@0.2.0
    13. interface wasi:cli/stdout@0.2.0
    14. interface wasi:cli/stderr@0.2.0
    15. interface wasi:cli/stdin@0.2.0
    16. interface wasi:http/outgoing-handler@0.2.0
    17. -
    18. interface wasi:clocks/wall-clock@0.2.0
    19. Exports: @@ -1388,6 +1388,47 @@ but those will be reported by the incoming-body
    20. option<result<result<own<incoming-response>, error-code>>>
    21. +

      Import interface wasi:clocks/wall-clock@0.2.0

      +

      WASI Wall Clock is a clock API intended to let users query the current +time. The name "wall" makes an analogy to a "clock on the wall", which +is not necessarily monotonic as it may be reset.

      +

      It is intended to be portable at least between Unix-family platforms and +Windows.

      +

      A wall clock is a clock which measures the date and time according to +some external reference.

      +

      External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time.

      +

      It is intended for reporting the current date and time for humans.

      +
      +

      Types

      +

      record datetime

      +

      A time and date in seconds plus nanoseconds.

      +
      Record Fields
      +
        +
      • seconds: u64
      • +
      • nanoseconds: u32
      • +
      +
      +

      Functions

      +

      now: func

      +

      Read the current value of the clock.

      +

      This clock is not monotonic, therefore calling this function repeatedly +will not necessarily produce a sequence of non-decreasing values.

      +

      The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, +also known as Unix Time.

      +

      The nanoseconds field of the output is always less than 1000000000.

      +
      Return values
      + +

      resolution: func

      +

      Query the resolution of the clock.

      +

      The nanoseconds field of the output is always less than 1000000000.

      +
      Return values
      +

      Import interface wasi:random/random@0.2.0

      WASI Random is a random data API.

      It is intended to be portable at least between Unix-family platforms and @@ -1497,47 +1538,6 @@ through the future-incoming-response

    22. result<own<future-incoming-response>, error-code>
    23. -

      Import interface wasi:clocks/wall-clock@0.2.0

      -

      WASI Wall Clock is a clock API intended to let users query the current -time. The name "wall" makes an analogy to a "clock on the wall", which -is not necessarily monotonic as it may be reset.

      -

      It is intended to be portable at least between Unix-family platforms and -Windows.

      -

      A wall clock is a clock which measures the date and time according to -some external reference.

      -

      External references may be reset, so this clock is not necessarily -monotonic, making it unsuitable for measuring elapsed time.

      -

      It is intended for reporting the current date and time for humans.

      -
      -

      Types

      -

      record datetime

      -

      A time and date in seconds plus nanoseconds.

      -
      Record Fields
      -
        -
      • seconds: u64
      • -
      • nanoseconds: u32
      • -
      -
      -

      Functions

      -

      now: func

      -

      Read the current value of the clock.

      -

      This clock is not monotonic, therefore calling this function repeatedly -will not necessarily produce a sequence of non-decreasing values.

      -

      The returned timestamps represent the number of seconds since -1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, -also known as Unix Time.

      -

      The nanoseconds field of the output is always less than 1000000000.

      -
      Return values
      - -

      resolution: func

      -

      Query the resolution of the clock.

      -

      The nanoseconds field of the output is always less than 1000000000.

      -
      Return values
      -

      Export interface wasi:http/incoming-handler@0.2.0


      Types

      diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index e8966b0cc..84802480b 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -6,7 +6,9 @@ package wasi:http@0.2.0; world imports { /// HTTP proxies have access to time and randomness. @since(version = 0.2.0) - include wasi:clocks/imports@0.2.0; + import wasi:clocks/monotonic-clock@0.2.0; + @since(version = 0.2.0) + import wasi:clocks/wall-clock@0.2.0; @since(version = 0.2.0) import wasi:random/random@0.2.0; From 01c6f9b80a06b1fc49d6f999fbd26a2f092b3ccc Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 1 Aug 2024 16:52:58 +0200 Subject: [PATCH 1483/1772] Update to v0.2.1 --- proposals/io/.github/workflows/main.yml | 2 ++ proposals/io/imports.md | 12 ++++++------ proposals/io/wit/error.wit | 2 +- proposals/io/wit/poll.wit | 2 +- proposals/io/wit/streams.wit | 2 +- proposals/io/wit/world.wit | 2 +- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index 77fabf7a8..675238430 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -12,3 +12,5 @@ jobs: steps: - uses: actions/checkout@v4 - uses: WebAssembly/wit-abi-up-to-date@v21 + with: + wit-bindgen: '0.28.0' diff --git a/proposals/io/imports.md b/proposals/io/imports.md index b26ca790d..7f456058b 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -2,13 +2,13 @@ -

      Import interface wasi:io/error@0.2.0

      +

      Import interface wasi:io/error@0.2.1


      Types

      resource error

      @@ -41,7 +41,7 @@ hazard.

      • string
      -

      Import interface wasi:io/poll@0.2.0

      +

      Import interface wasi:io/poll@0.2.1

      A poll API intended to let users wait for I/O events on multiple handles at once.


      @@ -94,7 +94,7 @@ being ready for I/O.

      • list<u32>
      -

      Import interface wasi:io/streams@0.2.0

      +

      Import interface wasi:io/streams@0.2.1

      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

      In the future, the component model is expected to add built-in stream types; diff --git a/proposals/io/wit/error.wit b/proposals/io/wit/error.wit index 7e66dbba2..4ea29c469 100644 --- a/proposals/io/wit/error.wit +++ b/proposals/io/wit/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; @since(version = 0.2.0) interface error { diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index cbdc960f0..b25ac729f 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index b5e2a36ac..b697e24d6 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index f5c098793..6405a4e48 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; @since(version = 0.2.0) world imports { From c54e4799f201c4f005a08799396fad8eddac9f66 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 1 Aug 2024 17:02:54 +0200 Subject: [PATCH 1484/1772] Update to v0.2.1 --- proposals/random/.github/workflows/main.yml | 4 +++- proposals/random/imports.md | 12 ++++++------ proposals/random/wit/insecure-seed.wit | 2 +- proposals/random/wit/insecure.wit | 2 +- proposals/random/wit/random.wit | 2 +- proposals/random/wit/world.wit | 2 +- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index 293e49214..675238430 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -10,5 +10,7 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: WebAssembly/wit-abi-up-to-date@v21 + with: + wit-bindgen: '0.28.0' diff --git a/proposals/random/imports.md b/proposals/random/imports.md index c97955792..19f1cc8a1 100644 --- a/proposals/random/imports.md +++ b/proposals/random/imports.md @@ -2,13 +2,13 @@

      -

      Import interface wasi:random/random@0.2.0

      +

      Import interface wasi:random/random@0.2.1

      WASI Random is a random data API.

      It is intended to be portable at least between Unix-family platforms and Windows.

      @@ -41,7 +41,7 @@ represented as a u64.

      • u64
      -

      Import interface wasi:random/insecure@0.2.0

      +

      Import interface wasi:random/insecure@0.2.1

      The insecure interface for insecure pseudo-random numbers.

      It is intended to be portable at least between Unix-family platforms and Windows.

      @@ -70,7 +70,7 @@ a long period.

      • u64
      -

      Import interface wasi:random/insecure-seed@0.2.0

      +

      Import interface wasi:random/insecure-seed@0.2.1

      The insecure-seed interface for seeding hash-map DoS resistance.

      It is intended to be portable at least between Unix-family platforms and Windows.

      diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index 4cce62858..7e708dc52 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index 3cea0c4a6..3cdb53dfb 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 41c3a0367..2b5035d1c 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index b5560a67a..c615e96dc 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; @since(version = 0.2.0) world imports { From cd2a65b4a1d8d0defc051d8fd725c618666e7487 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 1 Aug 2024 17:14:00 +0200 Subject: [PATCH 1485/1772] Update to v0.2.1 --- proposals/clocks/.github/workflows/main.yml | 3 +- proposals/clocks/README.md | 35 ++++++++++++--------- proposals/clocks/imports.md | 25 ++++++++------- proposals/clocks/wit/deps.lock | 4 +-- proposals/clocks/wit/deps/io/error.wit | 18 +++++------ proposals/clocks/wit/deps/io/poll.wit | 14 ++++++--- proposals/clocks/wit/deps/io/streams.wit | 30 ++++++++++++++++-- proposals/clocks/wit/deps/io/world.wit | 6 +++- proposals/clocks/wit/monotonic-clock.wit | 4 +-- proposals/clocks/wit/timezone.wit | 2 +- proposals/clocks/wit/wall-clock.wit | 2 +- proposals/clocks/wit/world.wit | 2 +- 12 files changed, 94 insertions(+), 51 deletions(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index bcb035e69..244de48de 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v4 - name: ensure `./wit/deps` are in sync run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.3/wit-deps-x86_64-unknown-linux-musl + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.5/wit-deps-x86_64-unknown-linux-musl chmod +x wit-deps ./wit-deps lock git add -N wit/deps @@ -21,3 +21,4 @@ jobs: - uses: WebAssembly/wit-abi-up-to-date@v21 with: features: clocks-timezone + wit-bindgen: '0.28.0' diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 49b40b980..cd01d6916 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -21,21 +21,26 @@ WASI clocks must have at least two complete independent implementations. ## Table of Contents -- [Introduction](#introduction) -- [Goals](#goals) -- [Non-goals](#non-goals) -- [API walk-through](#api-walk-through) - - [Use case 1](#use-case-1) - - [Use case 2](#use-case-2) -- [Detailed design discussion](#detailed-design-discussion) - - [[Tricky design choice 1]](#tricky-design-choice-1) - - [[Tricky design choice 2]](#tricky-design-choice-2) -- [Considered alternatives](#considered-alternatives) - - [[Alternative 1]](#alternative-1) - - [[Alternative 2]](#alternative-2) -- [Stakeholder Interest & Feedback](#stakeholder-interest--feedback) -- [References & acknowledgements](#references--acknowledgements) -- [Development](#development) +- [WASI Clocks](#wasi-clocks) + - [Current Phase](#current-phase) + - [Champions](#champions) + - [Portability Criteria](#portability-criteria) + - [Table of Contents](#table-of-contents) + - [Introduction](#introduction) + - [Goals](#goals) + - [Non-goals](#non-goals) + - [API walk-through](#api-walk-through) + - [Measuring elapsed time](#measuring-elapsed-time) + - [Telling the current human time:](#telling-the-current-human-time) + - [Retrieving the timezone:](#retrieving-the-timezone) + - [Detailed design discussion](#detailed-design-discussion) + - [What should the type of a timestamp be?](#what-should-the-type-of-a-timestamp-be) + - [Considered alternatives](#considered-alternatives) + - [Per-process and per-thread clocks](#per-process-and-per-thread-clocks) + - [Stakeholder Interest \& Feedback](#stakeholder-interest--feedback) + - [References \& acknowledgements](#references--acknowledgements) + - [Development](#development) + - [Generating imports.md](#generating-importsmd) ### Introduction diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index b1fefd7b5..886f9ff19 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -2,14 +2,14 @@ -

      Import interface wasi:io/poll@0.2.0

      +

      Import interface wasi:io/poll@0.2.1

      A poll API intended to let users wait for I/O events on multiple handles at once.


      @@ -43,14 +43,17 @@ containing only this pollable.

      interest, and waits until one or more of the events is ready for I/O.

      The result list<u32> contains one or more indices of handles in the argument list that is ready for I/O.

      -

      If the list contains more elements than can be indexed with a u32 -value, this function traps.

      +

      This function traps if either:

      +
        +
      • the list is empty, or:
      • +
      • the list contains more elements than can be indexed with a u32 value.
      • +

      A timeout can be implemented by adding a pollable from the wasi-clocks API to the list.

      This function does not return a result; polling in itself does not do any I/O so it doesn't fail. If any of the I/O sources identified by the pollables has an error, it is indicated by marking the source as -being reaedy for I/O.

      +being ready for I/O.

      Params
      • in: list<borrow<pollable>>
      • @@ -59,7 +62,7 @@ being reaedy for I/O.

        • list<u32>
        -

        Import interface wasi:clocks/monotonic-clock@0.2.0

        +

        Import interface wasi:clocks/monotonic-clock@0.2.1

        WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

        It is intended to be portable at least between Unix-family platforms and @@ -118,7 +121,7 @@ elapsed from the time this function is invoked.

        -

        Import interface wasi:clocks/wall-clock@0.2.0

        +

        Import interface wasi:clocks/wall-clock@0.2.1

        WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

        @@ -159,7 +162,7 @@ also known as Unix Time.
      • datetime
      -

      Import interface wasi:clocks/timezone@0.2.0

      +

      Import interface wasi:clocks/timezone@0.2.1


      Types

      type datetime

      diff --git a/proposals/clocks/wit/deps.lock b/proposals/clocks/wit/deps.lock index a1d7a278a..0d0c51ddc 100644 --- a/proposals/clocks/wit/deps.lock +++ b/proposals/clocks/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "7210e5653539a15478f894d4da24cc69d61924cbcba21d2804d69314a88e5a4c" -sha512 = "49184a1b0945a889abd52d25271172ed3dc2db6968fcdddb1bab7ee0081f4a3eeee0977ad2291126a37631c0d86eeea75d822fa8af224c422134500bf9f0f2bb" +sha256 = "2a74bd811adc46b5a0f19827ddbde89870e52b17615f4d0873f06fd977250caf" +sha512 = "94624f00c66e66203592cee820f80b1ba91ecdb71f682c154f25eaf71f8d8954197dcb64503bc21e72ed5e812af7eae876df47b7eb727b02db3a74a7ce0aefca" diff --git a/proposals/clocks/wit/deps/io/error.wit b/proposals/clocks/wit/deps/io/error.wit index 22e5b6489..4ea29c469 100644 --- a/proposals/clocks/wit/deps/io/error.wit +++ b/proposals/clocks/wit/deps/io/error.wit @@ -1,6 +1,6 @@ -package wasi:io@0.2.0; - +package wasi:io@0.2.1; +@since(version = 0.2.0) interface error { /// A resource which represents some error information. /// @@ -11,16 +11,15 @@ interface error { /// `wasi:io/streams/stream-error` type. /// /// To provide more specific error information, other interfaces may - /// provide functions to further "downcast" this error into more specific - /// error information. For example, `error`s returned in streams derived - /// from filesystem types to be described using the filesystem's own - /// error-code type, using the function - /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter - /// `borrow` and returns - /// `option`. + /// offer functions to "downcast" this error into more specific types. For example, + /// errors returned from streams derived from filesystem types can be described using + /// the filesystem's own error-code type. This is done using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a `borrow` + /// parameter and returns an `option`. /// /// The set of functions which can "downcast" an `error` into a more /// concrete type is open. + @since(version = 0.2.0) resource error { /// Returns a string that is suitable to assist humans in debugging /// this error. @@ -29,6 +28,7 @@ interface error { /// It may change across platforms, hosts, or other implementation /// details. Parsing this string is a major platform-compatibility /// hazard. + @since(version = 0.2.0) to-debug-string: func() -> string; } } diff --git a/proposals/clocks/wit/deps/io/poll.wit b/proposals/clocks/wit/deps/io/poll.wit index ddc67f8b7..b25ac729f 100644 --- a/proposals/clocks/wit/deps/io/poll.wit +++ b/proposals/clocks/wit/deps/io/poll.wit @@ -1,14 +1,17 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. +@since(version = 0.2.0) interface poll { /// `pollable` represents a single I/O event which may be ready, or not. + @since(version = 0.2.0) resource pollable { /// Return the readiness of a pollable. This function never blocks. /// /// Returns `true` when the pollable is ready, and `false` otherwise. + @since(version = 0.2.0) ready: func() -> bool; /// `block` returns immediately if the pollable is ready, and otherwise @@ -16,6 +19,7 @@ interface poll { /// /// This function is equivalent to calling `poll.poll` on a list /// containing only this pollable. + @since(version = 0.2.0) block: func(); } @@ -27,8 +31,9 @@ interface poll { /// The result `list` contains one or more indices of handles in the /// argument list that is ready for I/O. /// - /// If the list contains more elements than can be indexed with a `u32` - /// value, this function traps. + /// This function traps if either: + /// - the list is empty, or: + /// - the list contains more elements than can be indexed with a `u32` value. /// /// A timeout can be implemented by adding a pollable from the /// wasi-clocks API to the list. @@ -36,6 +41,7 @@ interface poll { /// This function does not return a `result`; polling in itself does not /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as - /// being reaedy for I/O. + /// being ready for I/O. + @since(version = 0.2.0) poll: func(in: list>) -> list; } diff --git a/proposals/clocks/wit/deps/io/streams.wit b/proposals/clocks/wit/deps/io/streams.wit index 6d2f871e3..b697e24d6 100644 --- a/proposals/clocks/wit/deps/io/streams.wit +++ b/proposals/clocks/wit/deps/io/streams.wit @@ -1,15 +1,19 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. +@since(version = 0.2.0) interface streams { + @since(version = 0.2.0) use error.{error}; + @since(version = 0.2.0) use poll.{pollable}; /// An error for input-stream and output-stream operations. + @since(version = 0.2.0) variant stream-error { /// The last operation (a write or flush) failed before completion. /// @@ -29,6 +33,7 @@ interface streams { /// available, which could even be zero. To wait for data to be available, /// use the `subscribe` function to obtain a `pollable` which can be polled /// for using `wasi:io/poll`. + @since(version = 0.2.0) resource input-stream { /// Perform a non-blocking read from the stream. /// @@ -56,6 +61,7 @@ interface streams { /// is not possible to allocate in wasm32, or not desirable to allocate as /// as a return value by the callee. The callee may return a list of bytes /// less than `len` in size while more bytes are available for reading. + @since(version = 0.2.0) read: func( /// The maximum number of bytes to read len: u64 @@ -63,6 +69,7 @@ interface streams { /// Read bytes from a stream, after blocking until at least one byte can /// be read. Except for blocking, behavior is identical to `read`. + @since(version = 0.2.0) blocking-read: func( /// The maximum number of bytes to read len: u64 @@ -72,6 +79,7 @@ interface streams { /// /// Behaves identical to `read`, except instead of returning a list /// of bytes, returns the number of bytes consumed from the stream. + @since(version = 0.2.0) skip: func( /// The maximum number of bytes to skip. len: u64, @@ -79,6 +87,7 @@ interface streams { /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. + @since(version = 0.2.0) blocking-skip: func( /// The maximum number of bytes to skip. len: u64, @@ -90,6 +99,7 @@ interface streams { /// The created `pollable` is a child resource of the `input-stream`. /// Implementations may trap if the `input-stream` is dropped before /// all derived `pollable`s created with this function are dropped. + @since(version = 0.2.0) subscribe: func() -> pollable; } @@ -102,6 +112,11 @@ interface streams { /// promptly, which could even be zero. To wait for the stream to be ready to /// accept data, the `subscribe` function to obtain a `pollable` which can be /// polled for using `wasi:io/poll`. + /// + /// Dropping an `output-stream` while there's still an active write in + /// progress may result in the data being lost. Before dropping the stream, + /// be sure to fully flush your writes. + @since(version = 0.2.0) resource output-stream { /// Check readiness for writing. This function never blocks. /// @@ -112,6 +127,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. + @since(version = 0.2.0) check-write: func() -> result; /// Perform a write. This function never blocks. @@ -127,6 +143,7 @@ interface streams { /// /// returns Err(closed) without writing if the stream has closed since /// the last call to check-write provided a permit. + @since(version = 0.2.0) write: func( contents: list ) -> result<_, stream-error>; @@ -155,6 +172,7 @@ interface streams { /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` + @since(version = 0.2.0) blocking-write-and-flush: func( contents: list ) -> result<_, stream-error>; @@ -169,14 +187,16 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. + @since(version = 0.2.0) flush: func() -> result<_, stream-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. + @since(version = 0.2.0) blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream - /// is ready for more writing, or an error has occured. When this + /// is ready for more writing, or an error has occurred. When this /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an /// error. /// @@ -193,6 +213,7 @@ interface streams { /// preconditions (must use check-write first), but instead of /// passing a list of bytes, you simply pass the number of zero-bytes /// that should be written. + @since(version = 0.2.0) write-zeroes: func( /// The number of zero-bytes to write len: u64 @@ -222,6 +243,7 @@ interface streams { /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` + @since(version = 0.2.0) blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 @@ -229,7 +251,7 @@ interface streams { /// Read from one stream and write to another. /// - /// The behavior of splice is equivelant to: + /// The behavior of splice is equivalent to: /// 1. calling `check-write` on the `output-stream` /// 2. calling `read` on the `input-stream` with the smaller of the /// `check-write` permitted length and the `len` provided to `splice` @@ -240,6 +262,7 @@ interface streams { /// /// This function returns the number of bytes transferred; it may be less /// than `len`. + @since(version = 0.2.0) splice: func( /// The stream to read from src: borrow, @@ -252,6 +275,7 @@ interface streams { /// This is similar to `splice`, except that it blocks until the /// `output-stream` is ready for writing, and the `input-stream` /// is ready for reading, before performing the `splice`. + @since(version = 0.2.0) blocking-splice: func( /// The stream to read from src: borrow, diff --git a/proposals/clocks/wit/deps/io/world.wit b/proposals/clocks/wit/deps/io/world.wit index 5f0b43fe5..6405a4e48 100644 --- a/proposals/clocks/wit/deps/io/world.wit +++ b/proposals/clocks/wit/deps/io/world.wit @@ -1,6 +1,10 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import streams; + + @since(version = 0.2.0) import poll; } diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index afbd700e1..3c24840c9 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.0; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.0.{pollable}; + use wasi:io/poll@0.2.1.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/clocks/wit/timezone.wit b/proposals/clocks/wit/timezone.wit index 3c286889e..212da6682 100644 --- a/proposals/clocks/wit/timezone.wit +++ b/proposals/clocks/wit/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/clocks/wit/wall-clock.wit b/proposals/clocks/wit/wall-clock.wit index 4b08d71ee..6be069a32 100644 --- a/proposals/clocks/wit/wall-clock.wit +++ b/proposals/clocks/wit/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index 76a9206c5..9251ac645 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; @since(version = 0.2.0) world imports { From ac57200fb95272a9a9b7db18755d47c6410b3a88 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Sun, 14 Jul 2024 00:41:09 +0700 Subject: [PATCH 1486/1772] Fix typos --- proposals/random/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/random/README.md b/proposals/random/README.md index 44fca0824..f68b5ace6 100644 --- a/proposals/random/README.md +++ b/proposals/random/README.md @@ -57,7 +57,7 @@ unavailable, programs may fail to be instantiated or may trap). WASI Random is not aiming to be a full DRBG API. Such an API could be considered in WASI, but it should be a separate proposal. -And, WASI Random is not include facilities for feeding entropy back into +WASI Random does not include facilities for feeding entropy back into the system. It is expected that most entropy that applications would observe should also be observable by the host implementation, and so there should be little need to feed it back in. There may be other uses for such an API, @@ -168,7 +168,7 @@ their imports, as mentioned in the previous question. Best practices suggest that implementations should provide at least 196 bits of security. However, many host platforms' CSPRNG APIs do not currently document their bits of security, and it doesn't seem desirable to require wasm engines to -run their own CSPRNG on a platform which alreay has one, so for now, the API +run their own CSPRNG on a platform which already has one, so for now, the API does not specify a specific number. ### Why is insecure-random a fixed-sized return value? From 39654a0a9c4d7da109a8e74885af2cc349e36412 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 1 Aug 2024 17:23:45 +0200 Subject: [PATCH 1487/1772] Update to v0.2.1 --- .../filesystem/.github/workflows/main.yml | 2 + proposals/filesystem/imports.md | 56 ++++++++++--------- proposals/filesystem/wit/deps.lock | 8 +-- .../wit/deps/clocks/monotonic-clock.wit | 21 ++++--- .../filesystem/wit/deps/clocks/timezone.wit | 55 ++++++++++++++++++ .../filesystem/wit/deps/clocks/wall-clock.wit | 6 +- .../filesystem/wit/deps/clocks/world.wit | 7 ++- proposals/filesystem/wit/deps/io/error.wit | 18 +++--- proposals/filesystem/wit/deps/io/poll.wit | 14 +++-- proposals/filesystem/wit/deps/io/streams.wit | 30 +++++++++- proposals/filesystem/wit/deps/io/world.wit | 6 +- proposals/filesystem/wit/preopens.wit | 2 +- proposals/filesystem/wit/types.wit | 6 +- proposals/filesystem/wit/world.wit | 2 +- 14 files changed, 171 insertions(+), 62 deletions(-) create mode 100644 proposals/filesystem/wit/deps/clocks/timezone.wit diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index e5a958551..52a7b9e8a 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -19,3 +19,5 @@ jobs: git add -N wit/deps git diff --exit-code - uses: WebAssembly/wit-abi-up-to-date@v21 + with: + wit-bindgen: '0.28.0' diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index f3e9b7b2a..cede7691e 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -2,16 +2,16 @@ -

      Import interface wasi:io/error@0.2.0

      +

      Import interface wasi:io/error@0.2.1


      Types

      resource error

      @@ -21,13 +21,11 @@ which provides some human-readable information about the error.

      In the wasi:io package, this resource is returned through the wasi:io/streams/stream-error type.

      To provide more specific error information, other interfaces may -provide functions to further "downcast" this error into more specific -error information. For example, errors returned in streams derived -from filesystem types to be described using the filesystem's own -error-code type, using the function -wasi:filesystem/types/filesystem-error-code, which takes a parameter -borrow<error> and returns -option<wasi:filesystem/types/error-code>.

      +offer functions to "downcast" this error into more specific types. For example, +errors returned from streams derived from filesystem types can be described using +the filesystem's own error-code type. This is done using the function +wasi:filesystem/types/filesystem-error-code, which takes a borrow<error> +parameter and returns an option<wasi:filesystem/types/error-code>.

      The set of functions which can "downcast" an error into a more concrete type is open.

      Functions

      @@ -46,7 +44,7 @@ hazard.

      • string
      -

      Import interface wasi:io/poll@0.2.0

      +

      Import interface wasi:io/poll@0.2.1

      A poll API intended to let users wait for I/O events on multiple handles at once.


      @@ -80,14 +78,17 @@ containing only this pollable.

      interest, and waits until one or more of the events is ready for I/O.

      The result list<u32> contains one or more indices of handles in the argument list that is ready for I/O.

      -

      If the list contains more elements than can be indexed with a u32 -value, this function traps.

      +

      This function traps if either:

      +
        +
      • the list is empty, or:
      • +
      • the list contains more elements than can be indexed with a u32 value.
      • +

      A timeout can be implemented by adding a pollable from the wasi-clocks API to the list.

      This function does not return a result; polling in itself does not do any I/O so it doesn't fail. If any of the I/O sources identified by the pollables has an error, it is indicated by marking the source as -being reaedy for I/O.

      +being ready for I/O.

      Params
      • in: list<borrow<pollable>>
      • @@ -96,7 +97,7 @@ being reaedy for I/O.

        • list<u32>
        -

        Import interface wasi:io/streams@0.2.0

        +

        Import interface wasi:io/streams@0.2.1

        WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

        In the future, the component model is expected to add built-in stream types; @@ -135,12 +136,15 @@ use the subscribe function to obtain a po for using wasi:io/poll.

        resource output-stream

        An output bytestream.

        -

        output-streams are non-blocking to the extent practical on +

        output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also always return promptly, after the number of bytes that can be written promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe function to obtain a pollable which can be -polled for using wasi:io/poll.

        +polled for using wasi:io/poll.

        +

        Dropping an output-stream while there's still an active write in +progress may result in the data being lost. Before dropping the stream, +be sure to fully flush your writes.

        Functions

        [method]input-stream.read: func

        Perform a non-blocking read from the stream.

        @@ -322,7 +326,7 @@ and stream is ready for writing again.

      [method]output-stream.subscribe: func

      Create a pollable which will resolve once the output-stream -is ready for more writing, or an error has occured. When this +is ready for more writing, or an error has occurred. When this pollable is ready, check-write will return ok(n) with n>0, or an error.

      If the stream is closed, this pollable is always ready immediately.

      @@ -385,7 +389,7 @@ let _ = this.check-write(); // eliding error handling

      [method]output-stream.splice: func

      Read from one stream and write to another.

      -

      The behavior of splice is equivelant to:

      +

      The behavior of splice is equivalent to:

      1. calling check-write on the output-stream
      2. calling read on the input-stream with the smaller of the @@ -421,7 +425,7 @@ is ready for reading, before performing the splice.

        -

        Import interface wasi:clocks/wall-clock@0.2.0

        +

        Import interface wasi:clocks/wall-clock@0.2.1

        WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

        @@ -462,7 +466,7 @@ also known as Unix Time.
      3. datetime
      4. -

        Import interface wasi:filesystem/types@0.2.0

        +

        Import interface wasi:filesystem/types@0.2.1

        WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

        @@ -1342,7 +1346,7 @@ errors are filesystem-related errors.

        -

        Import interface wasi:filesystem/preopens@0.2.0

        +

        Import interface wasi:filesystem/preopens@0.2.1


        Types

        type descriptor

        diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index 64c71e7df..2b50429e0 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "468b4d12892fe926b8eb5d398dbf579d566c93231fa44f415440572c695b7613" -sha512 = "e6b53a07221f1413953c9797c68f08b815fdaebf66419bbc1ea3e8b7dece73731062693634731f311a03957b268cf9cc509c518bd15e513c318aa04a8459b93a" +sha256 = "ea9d69ee803bc176e23e5268f5e24a2ac485dd1f62a0ab4c748e9d3f901f576f" +sha512 = "5efc22927c46cd56c41e5549ec775561c7fac2ea0d365abc0b55396d9475a7c9f984077a81f84a44a726f1c008fd2fadbffffa4fa53ecd5fbfd05afd379ab428" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "7210e5653539a15478f894d4da24cc69d61924cbcba21d2804d69314a88e5a4c" -sha512 = "49184a1b0945a889abd52d25271172ed3dc2db6968fcdddb1bab7ee0081f4a3eeee0977ad2291126a37631c0d86eeea75d822fa8af224c422134500bf9f0f2bb" +sha256 = "2a74bd811adc46b5a0f19827ddbde89870e52b17615f4d0873f06fd977250caf" +sha512 = "94624f00c66e66203592cee820f80b1ba91ecdb71f682c154f25eaf71f8d8954197dcb64503bc21e72ed5e812af7eae876df47b7eb727b02db3a74a7ce0aefca" diff --git a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit index 4e4dc3a19..3c24840c9 100644 --- a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,38 +7,43 @@ package wasi:clocks@0.2.0; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -/// -/// It is intended for measuring elapsed time. +@since(version = 0.2.0) interface monotonic-clock { - use wasi:io/poll@0.2.0.{pollable}; + @since(version = 0.2.0) + use wasi:io/poll@0.2.1.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. + @since(version = 0.2.0) type instant = u64; /// A duration of time, in nanoseconds. + @since(version = 0.2.0) type duration = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + @since(version = 0.2.0) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. + @since(version = 0.2.0) resolution: func() -> duration; /// Create a `pollable` which will resolve once the specified instant - /// occured. + /// has occurred. + @since(version = 0.2.0) subscribe-instant: func( when: instant, ) -> pollable; - /// Create a `pollable` which will resolve once the given duration has - /// elapsed, starting at the time at which this function was called. - /// occured. + /// Create a `pollable` that will resolve after the specified duration has + /// elapsed from the time this function is invoked. + @since(version = 0.2.0) subscribe-duration: func( when: duration, ) -> pollable; diff --git a/proposals/filesystem/wit/deps/clocks/timezone.wit b/proposals/filesystem/wit/deps/clocks/timezone.wit new file mode 100644 index 000000000..212da6682 --- /dev/null +++ b/proposals/filesystem/wit/deps/clocks/timezone.wit @@ -0,0 +1,55 @@ +package wasi:clocks@0.2.1; + +@unstable(feature = clocks-timezone) +interface timezone { + @unstable(feature = clocks-timezone) + use wall-clock.{datetime}; + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + @unstable(feature = clocks-timezone) + display: func(when: datetime) -> timezone-display; + + /// The same as `display`, but only return the UTC offset. + @unstable(feature = clocks-timezone) + utc-offset: func(when: datetime) -> s32; + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + @unstable(feature = clocks-timezone) + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/filesystem/wit/deps/clocks/wall-clock.wit b/proposals/filesystem/wit/deps/clocks/wall-clock.wit index 440ca0f33..6be069a32 100644 --- a/proposals/filesystem/wit/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,8 +13,10 @@ package wasi:clocks@0.2.0; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. +@since(version = 0.2.0) interface wall-clock { /// A time and date in seconds plus nanoseconds. + @since(version = 0.2.0) record datetime { seconds: u64, nanoseconds: u32, @@ -33,10 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + @since(version = 0.2.0) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. + @since(version = 0.2.0) resolution: func() -> datetime; } diff --git a/proposals/filesystem/wit/deps/clocks/world.wit b/proposals/filesystem/wit/deps/clocks/world.wit index c0224572a..9251ac645 100644 --- a/proposals/filesystem/wit/deps/clocks/world.wit +++ b/proposals/filesystem/wit/deps/clocks/world.wit @@ -1,6 +1,11 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import monotonic-clock; + @since(version = 0.2.0) import wall-clock; + @unstable(feature = clocks-timezone) + import timezone; } diff --git a/proposals/filesystem/wit/deps/io/error.wit b/proposals/filesystem/wit/deps/io/error.wit index 22e5b6489..4ea29c469 100644 --- a/proposals/filesystem/wit/deps/io/error.wit +++ b/proposals/filesystem/wit/deps/io/error.wit @@ -1,6 +1,6 @@ -package wasi:io@0.2.0; - +package wasi:io@0.2.1; +@since(version = 0.2.0) interface error { /// A resource which represents some error information. /// @@ -11,16 +11,15 @@ interface error { /// `wasi:io/streams/stream-error` type. /// /// To provide more specific error information, other interfaces may - /// provide functions to further "downcast" this error into more specific - /// error information. For example, `error`s returned in streams derived - /// from filesystem types to be described using the filesystem's own - /// error-code type, using the function - /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter - /// `borrow` and returns - /// `option`. + /// offer functions to "downcast" this error into more specific types. For example, + /// errors returned from streams derived from filesystem types can be described using + /// the filesystem's own error-code type. This is done using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a `borrow` + /// parameter and returns an `option`. /// /// The set of functions which can "downcast" an `error` into a more /// concrete type is open. + @since(version = 0.2.0) resource error { /// Returns a string that is suitable to assist humans in debugging /// this error. @@ -29,6 +28,7 @@ interface error { /// It may change across platforms, hosts, or other implementation /// details. Parsing this string is a major platform-compatibility /// hazard. + @since(version = 0.2.0) to-debug-string: func() -> string; } } diff --git a/proposals/filesystem/wit/deps/io/poll.wit b/proposals/filesystem/wit/deps/io/poll.wit index ddc67f8b7..b25ac729f 100644 --- a/proposals/filesystem/wit/deps/io/poll.wit +++ b/proposals/filesystem/wit/deps/io/poll.wit @@ -1,14 +1,17 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. +@since(version = 0.2.0) interface poll { /// `pollable` represents a single I/O event which may be ready, or not. + @since(version = 0.2.0) resource pollable { /// Return the readiness of a pollable. This function never blocks. /// /// Returns `true` when the pollable is ready, and `false` otherwise. + @since(version = 0.2.0) ready: func() -> bool; /// `block` returns immediately if the pollable is ready, and otherwise @@ -16,6 +19,7 @@ interface poll { /// /// This function is equivalent to calling `poll.poll` on a list /// containing only this pollable. + @since(version = 0.2.0) block: func(); } @@ -27,8 +31,9 @@ interface poll { /// The result `list` contains one or more indices of handles in the /// argument list that is ready for I/O. /// - /// If the list contains more elements than can be indexed with a `u32` - /// value, this function traps. + /// This function traps if either: + /// - the list is empty, or: + /// - the list contains more elements than can be indexed with a `u32` value. /// /// A timeout can be implemented by adding a pollable from the /// wasi-clocks API to the list. @@ -36,6 +41,7 @@ interface poll { /// This function does not return a `result`; polling in itself does not /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as - /// being reaedy for I/O. + /// being ready for I/O. + @since(version = 0.2.0) poll: func(in: list>) -> list; } diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index 6d2f871e3..b697e24d6 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -1,15 +1,19 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. +@since(version = 0.2.0) interface streams { + @since(version = 0.2.0) use error.{error}; + @since(version = 0.2.0) use poll.{pollable}; /// An error for input-stream and output-stream operations. + @since(version = 0.2.0) variant stream-error { /// The last operation (a write or flush) failed before completion. /// @@ -29,6 +33,7 @@ interface streams { /// available, which could even be zero. To wait for data to be available, /// use the `subscribe` function to obtain a `pollable` which can be polled /// for using `wasi:io/poll`. + @since(version = 0.2.0) resource input-stream { /// Perform a non-blocking read from the stream. /// @@ -56,6 +61,7 @@ interface streams { /// is not possible to allocate in wasm32, or not desirable to allocate as /// as a return value by the callee. The callee may return a list of bytes /// less than `len` in size while more bytes are available for reading. + @since(version = 0.2.0) read: func( /// The maximum number of bytes to read len: u64 @@ -63,6 +69,7 @@ interface streams { /// Read bytes from a stream, after blocking until at least one byte can /// be read. Except for blocking, behavior is identical to `read`. + @since(version = 0.2.0) blocking-read: func( /// The maximum number of bytes to read len: u64 @@ -72,6 +79,7 @@ interface streams { /// /// Behaves identical to `read`, except instead of returning a list /// of bytes, returns the number of bytes consumed from the stream. + @since(version = 0.2.0) skip: func( /// The maximum number of bytes to skip. len: u64, @@ -79,6 +87,7 @@ interface streams { /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. + @since(version = 0.2.0) blocking-skip: func( /// The maximum number of bytes to skip. len: u64, @@ -90,6 +99,7 @@ interface streams { /// The created `pollable` is a child resource of the `input-stream`. /// Implementations may trap if the `input-stream` is dropped before /// all derived `pollable`s created with this function are dropped. + @since(version = 0.2.0) subscribe: func() -> pollable; } @@ -102,6 +112,11 @@ interface streams { /// promptly, which could even be zero. To wait for the stream to be ready to /// accept data, the `subscribe` function to obtain a `pollable` which can be /// polled for using `wasi:io/poll`. + /// + /// Dropping an `output-stream` while there's still an active write in + /// progress may result in the data being lost. Before dropping the stream, + /// be sure to fully flush your writes. + @since(version = 0.2.0) resource output-stream { /// Check readiness for writing. This function never blocks. /// @@ -112,6 +127,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. + @since(version = 0.2.0) check-write: func() -> result; /// Perform a write. This function never blocks. @@ -127,6 +143,7 @@ interface streams { /// /// returns Err(closed) without writing if the stream has closed since /// the last call to check-write provided a permit. + @since(version = 0.2.0) write: func( contents: list ) -> result<_, stream-error>; @@ -155,6 +172,7 @@ interface streams { /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` + @since(version = 0.2.0) blocking-write-and-flush: func( contents: list ) -> result<_, stream-error>; @@ -169,14 +187,16 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. + @since(version = 0.2.0) flush: func() -> result<_, stream-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. + @since(version = 0.2.0) blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream - /// is ready for more writing, or an error has occured. When this + /// is ready for more writing, or an error has occurred. When this /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an /// error. /// @@ -193,6 +213,7 @@ interface streams { /// preconditions (must use check-write first), but instead of /// passing a list of bytes, you simply pass the number of zero-bytes /// that should be written. + @since(version = 0.2.0) write-zeroes: func( /// The number of zero-bytes to write len: u64 @@ -222,6 +243,7 @@ interface streams { /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` + @since(version = 0.2.0) blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 @@ -229,7 +251,7 @@ interface streams { /// Read from one stream and write to another. /// - /// The behavior of splice is equivelant to: + /// The behavior of splice is equivalent to: /// 1. calling `check-write` on the `output-stream` /// 2. calling `read` on the `input-stream` with the smaller of the /// `check-write` permitted length and the `len` provided to `splice` @@ -240,6 +262,7 @@ interface streams { /// /// This function returns the number of bytes transferred; it may be less /// than `len`. + @since(version = 0.2.0) splice: func( /// The stream to read from src: borrow, @@ -252,6 +275,7 @@ interface streams { /// This is similar to `splice`, except that it blocks until the /// `output-stream` is ready for writing, and the `input-stream` /// is ready for reading, before performing the `splice`. + @since(version = 0.2.0) blocking-splice: func( /// The stream to read from src: borrow, diff --git a/proposals/filesystem/wit/deps/io/world.wit b/proposals/filesystem/wit/deps/io/world.wit index 5f0b43fe5..6405a4e48 100644 --- a/proposals/filesystem/wit/deps/io/world.wit +++ b/proposals/filesystem/wit/deps/io/world.wit @@ -1,6 +1,10 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import streams; + + @since(version = 0.2.0) import poll; } diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit index 08094ab3f..ca2f726af 100644 --- a/proposals/filesystem/wit/preopens.wit +++ b/proposals/filesystem/wit/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0; +package wasi:filesystem@0.2.1; @since(version = 0.2.0) interface preopens { diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index d061d5fd4..db3d96867 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0; +package wasi:filesystem@0.2.1; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.0; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.0.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.1.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.0.{datetime}; + use wasi:clocks/wall-clock@0.2.1.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index c8d99f56e..af0146cbc 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0; +package wasi:filesystem@0.2.1; @since(version = 0.2.0) world imports { From 1fc8459ff4bf64d529505e6713ad0cf52b856c80 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 1 Aug 2024 17:27:31 +0200 Subject: [PATCH 1488/1772] v0.2.1 --- proposals/sockets/.github/workflows/main.yml | 2 + proposals/sockets/imports.md | 84 ++++++++++--------- proposals/sockets/wit/deps.lock | 8 +- .../wit/deps/clocks/monotonic-clock.wit | 21 +++-- .../sockets/wit/deps/clocks/timezone.wit | 55 ++++++++++++ .../sockets/wit/deps/clocks/wall-clock.wit | 6 +- proposals/sockets/wit/deps/clocks/world.wit | 7 +- proposals/sockets/wit/deps/io/error.wit | 18 ++-- proposals/sockets/wit/deps/io/poll.wit | 14 +++- proposals/sockets/wit/deps/io/streams.wit | 30 ++++++- proposals/sockets/wit/deps/io/world.wit | 6 +- proposals/sockets/wit/ip-name-lookup.wit | 2 +- proposals/sockets/wit/tcp.wit | 6 +- proposals/sockets/wit/udp.wit | 2 +- proposals/sockets/wit/world.wit | 2 +- 15 files changed, 185 insertions(+), 78 deletions(-) create mode 100644 proposals/sockets/wit/deps/clocks/timezone.wit diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index e5a958551..52a7b9e8a 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -19,3 +19,5 @@ jobs: git add -N wit/deps git diff --exit-code - uses: WebAssembly/wit-abi-up-to-date@v21 + with: + wit-bindgen: '0.28.0' diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 44eb2c08a..737ff7d7f 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -2,21 +2,21 @@ -

        Import interface wasi:sockets/network@0.2.0

        +

        Import interface wasi:sockets/network@0.2.1


        Types

        resource network

        @@ -209,7 +209,7 @@ supported size.
      5. ipv4: ipv4-socket-address
      6. ipv6: ipv6-socket-address
      7. -

        Import interface wasi:sockets/instance-network@0.2.0

        +

        Import interface wasi:sockets/instance-network@0.2.1

        This interface provides a value-export of the default network handle..


        Types

        @@ -224,7 +224,7 @@ supported size. -

        Import interface wasi:io/poll@0.2.0

        +

        Import interface wasi:io/poll@0.2.1

        A poll API intended to let users wait for I/O events on multiple handles at once.


        @@ -258,14 +258,17 @@ containing only this pollable.

        interest, and waits until one or more of the events is ready for I/O.

        The result list<u32> contains one or more indices of handles in the argument list that is ready for I/O.

        -

        If the list contains more elements than can be indexed with a u32 -value, this function traps.

        +

        This function traps if either:

        +
          +
        • the list is empty, or:
        • +
        • the list contains more elements than can be indexed with a u32 value.
        • +

        A timeout can be implemented by adding a pollable from the wasi-clocks API to the list.

        This function does not return a result; polling in itself does not do any I/O so it doesn't fail. If any of the I/O sources identified by the pollables has an error, it is indicated by marking the source as -being reaedy for I/O.

        +being ready for I/O.

        Params
        • in: list<borrow<pollable>>
        • @@ -274,7 +277,7 @@ being reaedy for I/O.

          • list<u32>
          -

          Import interface wasi:sockets/udp@0.2.0

          +

          Import interface wasi:sockets/udp@0.2.1


          Types

          type pollable

          @@ -688,7 +691,7 @@ It's planned to be removed when future is natively supported in Pre -

          Import interface wasi:sockets/udp-create-socket@0.2.0

          +

          Import interface wasi:sockets/udp-create-socket@0.2.1


          Types

          type network

          @@ -733,7 +736,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

          Import interface wasi:io/error@0.2.0

          +

          Import interface wasi:io/error@0.2.1


          Types

          resource error

          @@ -743,13 +746,11 @@ which provides some human-readable information about the error.

          In the wasi:io package, this resource is returned through the wasi:io/streams/stream-error type.

          To provide more specific error information, other interfaces may -provide functions to further "downcast" this error into more specific -error information. For example, errors returned in streams derived -from filesystem types to be described using the filesystem's own -error-code type, using the function -wasi:filesystem/types/filesystem-error-code, which takes a parameter -borrow<error> and returns -option<wasi:filesystem/types/error-code>.

          +offer functions to "downcast" this error into more specific types. For example, +errors returned from streams derived from filesystem types can be described using +the filesystem's own error-code type. This is done using the function +wasi:filesystem/types/filesystem-error-code, which takes a borrow<error> +parameter and returns an option<wasi:filesystem/types/error-code>.

          The set of functions which can "downcast" an error into a more concrete type is open.

          Functions

          @@ -768,7 +769,7 @@ hazard.

          • string
          -

          Import interface wasi:io/streams@0.2.0

          +

          Import interface wasi:io/streams@0.2.1

          WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

          In the future, the component model is expected to add built-in stream types; @@ -807,12 +808,15 @@ use the subscribe function to obtain a po for using wasi:io/poll.

          resource output-stream

          An output bytestream.

          -

          output-streams are non-blocking to the extent practical on +

          output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also always return promptly, after the number of bytes that can be written promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe function to obtain a pollable which can be -polled for using wasi:io/poll.

          +polled for using wasi:io/poll.

          +

          Dropping an output-stream while there's still an active write in +progress may result in the data being lost. Before dropping the stream, +be sure to fully flush your writes.

          Functions

          [method]input-stream.read: func

          Perform a non-blocking read from the stream.

          @@ -994,7 +998,7 @@ and stream is ready for writing again.

        [method]output-stream.subscribe: func

        Create a pollable which will resolve once the output-stream -is ready for more writing, or an error has occured. When this +is ready for more writing, or an error has occurred. When this pollable is ready, check-write will return ok(n) with n>0, or an error.

        If the stream is closed, this pollable is always ready immediately.

        @@ -1057,7 +1061,7 @@ let _ = this.check-write(); // eliding error handling

        [method]output-stream.splice: func

        Read from one stream and write to another.

        -

        The behavior of splice is equivelant to:

        +

        The behavior of splice is equivalent to:

        1. calling check-write on the output-stream
        2. calling read on the input-stream with the smaller of the @@ -1093,14 +1097,13 @@ is ready for reading, before performing the splice.

          -

          Import interface wasi:clocks/monotonic-clock@0.2.0

          +

          Import interface wasi:clocks/monotonic-clock@0.2.1

          WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

          It is intended to be portable at least between Unix-family platforms and Windows.

          A monotonic clock is a clock which has an unspecified initial value, and successive reads of the clock will produce non-decreasing values.

          -

          It is intended for measuring elapsed time.


          Types

          type pollable

          @@ -1133,7 +1136,7 @@ corresponding to a clock tick.

          subscribe-instant: func

          Create a pollable which will resolve once the specified instant -occured.

          +has occurred.

          Params

          subscribe-duration: func

          -

          Create a pollable which will resolve once the given duration has -elapsed, starting at the time at which this function was called. -occured.

          +

          Create a pollable that will resolve after the specified duration has +elapsed from the time this function is invoked.

          Params
          • when: duration
          • @@ -1154,7 +1156,7 @@ occured.

            -

            Import interface wasi:sockets/tcp@0.2.0

            +

            Import interface wasi:sockets/tcp@0.2.1


            Types

            type input-stream

            @@ -1745,7 +1747,7 @@ has no effect and returns ok.

            -

            Import interface wasi:sockets/tcp-create-socket@0.2.0

            +

            Import interface wasi:sockets/tcp-create-socket@0.2.1


            Types

            type network

            @@ -1790,7 +1792,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

            Import interface wasi:sockets/ip-name-lookup@0.2.0

            +

            Import interface wasi:sockets/ip-name-lookup@0.2.1


            Types

            type pollable

            diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index 64c71e7df..2b50429e0 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "468b4d12892fe926b8eb5d398dbf579d566c93231fa44f415440572c695b7613" -sha512 = "e6b53a07221f1413953c9797c68f08b815fdaebf66419bbc1ea3e8b7dece73731062693634731f311a03957b268cf9cc509c518bd15e513c318aa04a8459b93a" +sha256 = "ea9d69ee803bc176e23e5268f5e24a2ac485dd1f62a0ab4c748e9d3f901f576f" +sha512 = "5efc22927c46cd56c41e5549ec775561c7fac2ea0d365abc0b55396d9475a7c9f984077a81f84a44a726f1c008fd2fadbffffa4fa53ecd5fbfd05afd379ab428" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "7210e5653539a15478f894d4da24cc69d61924cbcba21d2804d69314a88e5a4c" -sha512 = "49184a1b0945a889abd52d25271172ed3dc2db6968fcdddb1bab7ee0081f4a3eeee0977ad2291126a37631c0d86eeea75d822fa8af224c422134500bf9f0f2bb" +sha256 = "2a74bd811adc46b5a0f19827ddbde89870e52b17615f4d0873f06fd977250caf" +sha512 = "94624f00c66e66203592cee820f80b1ba91ecdb71f682c154f25eaf71f8d8954197dcb64503bc21e72ed5e812af7eae876df47b7eb727b02db3a74a7ce0aefca" diff --git a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit index 4e4dc3a19..3c24840c9 100644 --- a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,38 +7,43 @@ package wasi:clocks@0.2.0; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -/// -/// It is intended for measuring elapsed time. +@since(version = 0.2.0) interface monotonic-clock { - use wasi:io/poll@0.2.0.{pollable}; + @since(version = 0.2.0) + use wasi:io/poll@0.2.1.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. + @since(version = 0.2.0) type instant = u64; /// A duration of time, in nanoseconds. + @since(version = 0.2.0) type duration = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + @since(version = 0.2.0) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. + @since(version = 0.2.0) resolution: func() -> duration; /// Create a `pollable` which will resolve once the specified instant - /// occured. + /// has occurred. + @since(version = 0.2.0) subscribe-instant: func( when: instant, ) -> pollable; - /// Create a `pollable` which will resolve once the given duration has - /// elapsed, starting at the time at which this function was called. - /// occured. + /// Create a `pollable` that will resolve after the specified duration has + /// elapsed from the time this function is invoked. + @since(version = 0.2.0) subscribe-duration: func( when: duration, ) -> pollable; diff --git a/proposals/sockets/wit/deps/clocks/timezone.wit b/proposals/sockets/wit/deps/clocks/timezone.wit new file mode 100644 index 000000000..212da6682 --- /dev/null +++ b/proposals/sockets/wit/deps/clocks/timezone.wit @@ -0,0 +1,55 @@ +package wasi:clocks@0.2.1; + +@unstable(feature = clocks-timezone) +interface timezone { + @unstable(feature = clocks-timezone) + use wall-clock.{datetime}; + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + @unstable(feature = clocks-timezone) + display: func(when: datetime) -> timezone-display; + + /// The same as `display`, but only return the UTC offset. + @unstable(feature = clocks-timezone) + utc-offset: func(when: datetime) -> s32; + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + @unstable(feature = clocks-timezone) + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/sockets/wit/deps/clocks/wall-clock.wit b/proposals/sockets/wit/deps/clocks/wall-clock.wit index 440ca0f33..6be069a32 100644 --- a/proposals/sockets/wit/deps/clocks/wall-clock.wit +++ b/proposals/sockets/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,8 +13,10 @@ package wasi:clocks@0.2.0; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. +@since(version = 0.2.0) interface wall-clock { /// A time and date in seconds plus nanoseconds. + @since(version = 0.2.0) record datetime { seconds: u64, nanoseconds: u32, @@ -33,10 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + @since(version = 0.2.0) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. + @since(version = 0.2.0) resolution: func() -> datetime; } diff --git a/proposals/sockets/wit/deps/clocks/world.wit b/proposals/sockets/wit/deps/clocks/world.wit index c0224572a..9251ac645 100644 --- a/proposals/sockets/wit/deps/clocks/world.wit +++ b/proposals/sockets/wit/deps/clocks/world.wit @@ -1,6 +1,11 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import monotonic-clock; + @since(version = 0.2.0) import wall-clock; + @unstable(feature = clocks-timezone) + import timezone; } diff --git a/proposals/sockets/wit/deps/io/error.wit b/proposals/sockets/wit/deps/io/error.wit index 22e5b6489..4ea29c469 100644 --- a/proposals/sockets/wit/deps/io/error.wit +++ b/proposals/sockets/wit/deps/io/error.wit @@ -1,6 +1,6 @@ -package wasi:io@0.2.0; - +package wasi:io@0.2.1; +@since(version = 0.2.0) interface error { /// A resource which represents some error information. /// @@ -11,16 +11,15 @@ interface error { /// `wasi:io/streams/stream-error` type. /// /// To provide more specific error information, other interfaces may - /// provide functions to further "downcast" this error into more specific - /// error information. For example, `error`s returned in streams derived - /// from filesystem types to be described using the filesystem's own - /// error-code type, using the function - /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter - /// `borrow` and returns - /// `option`. + /// offer functions to "downcast" this error into more specific types. For example, + /// errors returned from streams derived from filesystem types can be described using + /// the filesystem's own error-code type. This is done using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a `borrow` + /// parameter and returns an `option`. /// /// The set of functions which can "downcast" an `error` into a more /// concrete type is open. + @since(version = 0.2.0) resource error { /// Returns a string that is suitable to assist humans in debugging /// this error. @@ -29,6 +28,7 @@ interface error { /// It may change across platforms, hosts, or other implementation /// details. Parsing this string is a major platform-compatibility /// hazard. + @since(version = 0.2.0) to-debug-string: func() -> string; } } diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit index ddc67f8b7..b25ac729f 100644 --- a/proposals/sockets/wit/deps/io/poll.wit +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -1,14 +1,17 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. +@since(version = 0.2.0) interface poll { /// `pollable` represents a single I/O event which may be ready, or not. + @since(version = 0.2.0) resource pollable { /// Return the readiness of a pollable. This function never blocks. /// /// Returns `true` when the pollable is ready, and `false` otherwise. + @since(version = 0.2.0) ready: func() -> bool; /// `block` returns immediately if the pollable is ready, and otherwise @@ -16,6 +19,7 @@ interface poll { /// /// This function is equivalent to calling `poll.poll` on a list /// containing only this pollable. + @since(version = 0.2.0) block: func(); } @@ -27,8 +31,9 @@ interface poll { /// The result `list` contains one or more indices of handles in the /// argument list that is ready for I/O. /// - /// If the list contains more elements than can be indexed with a `u32` - /// value, this function traps. + /// This function traps if either: + /// - the list is empty, or: + /// - the list contains more elements than can be indexed with a `u32` value. /// /// A timeout can be implemented by adding a pollable from the /// wasi-clocks API to the list. @@ -36,6 +41,7 @@ interface poll { /// This function does not return a `result`; polling in itself does not /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as - /// being reaedy for I/O. + /// being ready for I/O. + @since(version = 0.2.0) poll: func(in: list>) -> list; } diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index 6d2f871e3..b697e24d6 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -1,15 +1,19 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. +@since(version = 0.2.0) interface streams { + @since(version = 0.2.0) use error.{error}; + @since(version = 0.2.0) use poll.{pollable}; /// An error for input-stream and output-stream operations. + @since(version = 0.2.0) variant stream-error { /// The last operation (a write or flush) failed before completion. /// @@ -29,6 +33,7 @@ interface streams { /// available, which could even be zero. To wait for data to be available, /// use the `subscribe` function to obtain a `pollable` which can be polled /// for using `wasi:io/poll`. + @since(version = 0.2.0) resource input-stream { /// Perform a non-blocking read from the stream. /// @@ -56,6 +61,7 @@ interface streams { /// is not possible to allocate in wasm32, or not desirable to allocate as /// as a return value by the callee. The callee may return a list of bytes /// less than `len` in size while more bytes are available for reading. + @since(version = 0.2.0) read: func( /// The maximum number of bytes to read len: u64 @@ -63,6 +69,7 @@ interface streams { /// Read bytes from a stream, after blocking until at least one byte can /// be read. Except for blocking, behavior is identical to `read`. + @since(version = 0.2.0) blocking-read: func( /// The maximum number of bytes to read len: u64 @@ -72,6 +79,7 @@ interface streams { /// /// Behaves identical to `read`, except instead of returning a list /// of bytes, returns the number of bytes consumed from the stream. + @since(version = 0.2.0) skip: func( /// The maximum number of bytes to skip. len: u64, @@ -79,6 +87,7 @@ interface streams { /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. + @since(version = 0.2.0) blocking-skip: func( /// The maximum number of bytes to skip. len: u64, @@ -90,6 +99,7 @@ interface streams { /// The created `pollable` is a child resource of the `input-stream`. /// Implementations may trap if the `input-stream` is dropped before /// all derived `pollable`s created with this function are dropped. + @since(version = 0.2.0) subscribe: func() -> pollable; } @@ -102,6 +112,11 @@ interface streams { /// promptly, which could even be zero. To wait for the stream to be ready to /// accept data, the `subscribe` function to obtain a `pollable` which can be /// polled for using `wasi:io/poll`. + /// + /// Dropping an `output-stream` while there's still an active write in + /// progress may result in the data being lost. Before dropping the stream, + /// be sure to fully flush your writes. + @since(version = 0.2.0) resource output-stream { /// Check readiness for writing. This function never blocks. /// @@ -112,6 +127,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. + @since(version = 0.2.0) check-write: func() -> result; /// Perform a write. This function never blocks. @@ -127,6 +143,7 @@ interface streams { /// /// returns Err(closed) without writing if the stream has closed since /// the last call to check-write provided a permit. + @since(version = 0.2.0) write: func( contents: list ) -> result<_, stream-error>; @@ -155,6 +172,7 @@ interface streams { /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` + @since(version = 0.2.0) blocking-write-and-flush: func( contents: list ) -> result<_, stream-error>; @@ -169,14 +187,16 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. + @since(version = 0.2.0) flush: func() -> result<_, stream-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. + @since(version = 0.2.0) blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream - /// is ready for more writing, or an error has occured. When this + /// is ready for more writing, or an error has occurred. When this /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an /// error. /// @@ -193,6 +213,7 @@ interface streams { /// preconditions (must use check-write first), but instead of /// passing a list of bytes, you simply pass the number of zero-bytes /// that should be written. + @since(version = 0.2.0) write-zeroes: func( /// The number of zero-bytes to write len: u64 @@ -222,6 +243,7 @@ interface streams { /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` + @since(version = 0.2.0) blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 @@ -229,7 +251,7 @@ interface streams { /// Read from one stream and write to another. /// - /// The behavior of splice is equivelant to: + /// The behavior of splice is equivalent to: /// 1. calling `check-write` on the `output-stream` /// 2. calling `read` on the `input-stream` with the smaller of the /// `check-write` permitted length and the `len` provided to `splice` @@ -240,6 +262,7 @@ interface streams { /// /// This function returns the number of bytes transferred; it may be less /// than `len`. + @since(version = 0.2.0) splice: func( /// The stream to read from src: borrow, @@ -252,6 +275,7 @@ interface streams { /// This is similar to `splice`, except that it blocks until the /// `output-stream` is ready for writing, and the `input-stream` /// is ready for reading, before performing the `splice`. + @since(version = 0.2.0) blocking-splice: func( /// The stream to read from src: borrow, diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit index 5f0b43fe5..6405a4e48 100644 --- a/proposals/sockets/wit/deps/io/world.wit +++ b/proposals/sockets/wit/deps/io/world.wit @@ -1,6 +1,10 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import streams; + + @since(version = 0.2.0) import poll; } diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index 0368b4801..dc56f3000 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.0.{pollable}; + use wasi:io/poll@0.2.1.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index e4a62101b..bae5a29ec 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.0.{input-stream, output-stream}; + use wasi:io/streams@0.2.1.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.0.{pollable}; + use wasi:io/poll@0.2.1.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.0.{duration}; + use wasi:clocks/monotonic-clock@0.2.1.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 48e753cac..b289e4943 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.0.{pollable}; + use wasi:io/poll@0.2.1.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index a1f7d14bc..a1d42670e 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.0; +package wasi:sockets@0.2.1; @since(version = 0.2.0) world imports { From e543a58706076930234f3954b425fd460065c84f Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 1 Aug 2024 09:42:12 -0600 Subject: [PATCH 1489/1772] add unstable `exit-with-code` function (#44) * add unstable `exit-with-code` function Whereas the existing `exit` function only accepts a `result` parameter (i.e. binary success or failure), this function allows the instance to report any status code from 0 to 255 to the host, with 0 usually meaning "success" and other values having their own meaning depending on the context. Fixes #11 Signed-off-by: Joel Dice --------- Signed-off-by: Joel Dice Co-authored-by: Bailey Hayes --- proposals/cli/.github/workflows/main.yml | 4 +++- proposals/cli/command.md | 11 +++++++++++ proposals/cli/imports.md | 11 +++++++++++ proposals/cli/wit/exit.wit | 11 +++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml index 286495620..ecc71c41f 100644 --- a/proposals/cli/.github/workflows/main.yml +++ b/proposals/cli/.github/workflows/main.yml @@ -20,4 +20,6 @@ jobs: git diff --exit-code - uses: WebAssembly/wit-abi-up-to-date@v21 with: - worlds: "command imports" + wit-bindgen: '0.28.0' + worlds: 'command imports' + features: 'cli-exit-with-code' diff --git a/proposals/cli/command.md b/proposals/cli/command.md index cdd51c13a..5e5fe2a2b 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -73,6 +73,17 @@ directory, interpreting . as shorthand for this.

            • status: result
            +

            exit-with-code: func

            +

            Exit the current instance and any linked instances, reporting the +specified status code to the host.

            +

            The meaning of the code depends on the context, with 0 usually meaning +"success", and other values indicating various types of failure.

            +

            This function does not return; the effect is analogous to a trap, but +without the connotation that something bad has happened.

            +
            Params
            +
              +
            • status-code: u8
            • +

            Import interface wasi:io/error@0.2.0


            Types

            diff --git a/proposals/cli/imports.md b/proposals/cli/imports.md index 93e32c35b..495ad207c 100644 --- a/proposals/cli/imports.md +++ b/proposals/cli/imports.md @@ -68,6 +68,17 @@ directory, interpreting . as shorthand for this.

            • status: result
            +

            exit-with-code: func

            +

            Exit the current instance and any linked instances, reporting the +specified status code to the host.

            +

            The meaning of the code depends on the context, with 0 usually meaning +"success", and other values indicating various types of failure.

            +

            This function does not return; the effect is analogous to a trap, but +without the connotation that something bad has happened.

            +
            Params
            +
              +
            • status-code: u8
            • +

            Import interface wasi:io/error@0.2.0


            Types

            diff --git a/proposals/cli/wit/exit.wit b/proposals/cli/wit/exit.wit index 357e6707b..427935c8d 100644 --- a/proposals/cli/wit/exit.wit +++ b/proposals/cli/wit/exit.wit @@ -3,4 +3,15 @@ interface exit { /// Exit the current instance and any linked instances. @since(version = 0.2.0) exit: func(status: result); + + /// Exit the current instance and any linked instances, reporting the + /// specified status code to the host. + /// + /// The meaning of the code depends on the context, with 0 usually meaning + /// "success", and other values indicating various types of failure. + /// + /// This function does not return; the effect is analogous to a trap, but + /// without the connotation that something bad has happened. + @unstable(feature = cli-exit-with-code) + exit-with-code: func(status-code: u8); } From c75ad10a7165304ef6910f65acaefad39e26495a Mon Sep 17 00:00:00 2001 From: Lann Date: Thu, 25 Jul 2024 10:15:57 -0400 Subject: [PATCH 1490/1772] Update request authority documentation The existing wording refers to a "request's authority", which is not well-defined. This rewords it to refer to the "request's target URI authority" - the "authority" part of the "target URI" of the request, which is well-defined. --- proposals/http/imports.md | 12 ++++++------ proposals/http/proxy.md | 12 ++++++------ proposals/http/wit-0.3.0-draft/types.wit | 10 +++++----- proposals/http/wit/types.wit | 12 ++++++------ 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index dce2c7ae1..04435c870 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -994,7 +994,7 @@ list with the same key.

          • option<scheme>

          [method]incoming-request.authority: func

          -

          Returns the authority from the request, if it was present.

          +

          Returns the authority of the Request's target URI, if present.

          Params
          • self: borrow<incoming-request>
          • @@ -1133,8 +1133,8 @@ string given is not a syntactically valid uri scheme.

          • result

          [method]outgoing-request.authority: func

          -

          Get the HTTP Authority for the Request. A value of none may be used -with Related Schemes which do not require an Authority. The HTTP and +

          Get the authority of the Request's target URI. A value of none may be used +with Related Schemes which do not require an authority. The HTTP and HTTPS schemes always require an authority.

          Params
            @@ -1145,10 +1145,10 @@ HTTPS schemes always require an authority.

          • option<string>

          [method]outgoing-request.set-authority: func

          -

          Set the HTTP Authority for the Request. A value of none may be used -with Related Schemes which do not require an Authority. The HTTP and +

          Set the authority of the Request's target URI. A value of none may be used +with Related Schemes which do not require an authority. The HTTP and HTTPS schemes always require an authority. Fails if the string given is -not a syntactically valid uri authority.

          +not a syntactically valid URI authority.

          Params
          • self: borrow<outgoing-request>
          • diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 528ba1cb4..6b0de97d6 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -888,7 +888,7 @@ list with the same key.

          • option<scheme>

          [method]incoming-request.authority: func

          -

          Returns the authority from the request, if it was present.

          +

          Returns the authority of the Request's target URI, if present.

          Params
          • self: borrow<incoming-request>
          • @@ -1027,8 +1027,8 @@ string given is not a syntactically valid uri scheme.

          • result

          [method]outgoing-request.authority: func

          -

          Get the HTTP Authority for the Request. A value of none may be used -with Related Schemes which do not require an Authority. The HTTP and +

          Get the authority of the Request's target URI. A value of none may be used +with Related Schemes which do not require an authority. The HTTP and HTTPS schemes always require an authority.

          Params
            @@ -1039,10 +1039,10 @@ HTTPS schemes always require an authority.

          • option<string>

          [method]outgoing-request.set-authority: func

          -

          Set the HTTP Authority for the Request. A value of none may be used -with Related Schemes which do not require an Authority. The HTTP and +

          Set the authority of the Request's target URI. A value of none may be used +with Related Schemes which do not require an authority. The HTTP and HTTPS schemes always require an authority. Fails if the string given is -not a syntactically valid uri authority.

          +not a syntactically valid URI authority.

          Params
          • self: borrow<outgoing-request>
          • diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index 6a067b819..a41624cac 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -315,14 +315,14 @@ interface types { /// string given is not a syntactically valid uri scheme. set-scheme: func(scheme: option) -> result; - /// Get the HTTP Authority for the Request. A value of `none` may be used - /// with Related Schemes which do not require an Authority. The HTTP and + /// Get the authority of the Request's target URI. A value of `none` may be used + /// with Related Schemes which do not require an authority. The HTTP and /// HTTPS schemes always require an authority. authority: func() -> option; - /// Set the HTTP Authority for the Request. A value of `none` may be used - /// with Related Schemes which do not require an Authority. The HTTP and + /// Set the authority of the Request's target URI. A value of `none` may be used + /// with Related Schemes which do not require an authority. The HTTP and /// HTTPS schemes always require an authority. Fails if the string given is - /// not a syntactically valid uri authority. + /// not a syntactically valid URI authority. set-authority: func(authority: option) -> result; /// Get the `request-options` to be associated with this request diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 981c110d1..f2ce84638 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -267,7 +267,7 @@ interface types { @since(version = 0.2.0) scheme: func() -> option; - /// Returns the authority from the request, if it was present. + /// Returns the authority of the Request's target URI, if present. @since(version = 0.2.0) authority: func() -> option; @@ -344,15 +344,15 @@ interface types { @since(version = 0.2.0) set-scheme: func(scheme: option) -> result; - /// Get the HTTP Authority for the Request. A value of `none` may be used - /// with Related Schemes which do not require an Authority. The HTTP and + /// Get the authority of the Request's target URI. A value of `none` may be used + /// with Related Schemes which do not require an authority. The HTTP and /// HTTPS schemes always require an authority. @since(version = 0.2.0) authority: func() -> option; - /// Set the HTTP Authority for the Request. A value of `none` may be used - /// with Related Schemes which do not require an Authority. The HTTP and + /// Set the authority of the Request's target URI. A value of `none` may be used + /// with Related Schemes which do not require an authority. The HTTP and /// HTTPS schemes always require an authority. Fails if the string given is - /// not a syntactically valid uri authority. + /// not a syntactically valid URI authority. @since(version = 0.2.0) set-authority: func(authority: option) -> result; From ebe34a03dcdc25e50840b4b85a3272325119bb5a Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 1 Aug 2024 17:46:44 +0200 Subject: [PATCH 1491/1772] Update to v0.2.1 --- proposals/cli/command.md | 127 ++++++++--------- proposals/cli/imports.md | 129 +++++++++--------- proposals/cli/wit/command.wit | 2 +- proposals/cli/wit/deps.lock | 20 +-- .../cli/wit/deps/clocks/monotonic-clock.wit | 6 +- proposals/cli/wit/deps/clocks/timezone.wit | 2 +- proposals/cli/wit/deps/clocks/wall-clock.wit | 2 +- proposals/cli/wit/deps/clocks/world.wit | 2 +- .../cli/wit/deps/filesystem/preopens.wit | 2 +- proposals/cli/wit/deps/filesystem/types.wit | 8 +- proposals/cli/wit/deps/filesystem/world.wit | 2 +- proposals/cli/wit/deps/io/error.wit | 2 +- proposals/cli/wit/deps/io/poll.wit | 2 +- proposals/cli/wit/deps/io/streams.wit | 10 +- proposals/cli/wit/deps/io/world.wit | 2 +- .../cli/wit/deps/random/insecure-seed.wit | 2 +- proposals/cli/wit/deps/random/insecure.wit | 2 +- proposals/cli/wit/deps/random/random.wit | 2 +- proposals/cli/wit/deps/random/world.wit | 2 +- .../cli/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/cli/wit/deps/sockets/tcp.wit | 6 +- proposals/cli/wit/deps/sockets/udp.wit | 2 +- proposals/cli/wit/deps/sockets/world.wit | 2 +- proposals/cli/wit/imports.wit | 12 +- proposals/cli/wit/stdio.wit | 6 +- 25 files changed, 183 insertions(+), 173 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 5e5fe2a2b..b6394017d 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -2,42 +2,42 @@ -

            Import interface wasi:cli/environment@0.2.0

            +

            Import interface wasi:cli/environment@0.2.1


            Functions

            get-environment: func

            @@ -64,7 +64,7 @@ directory, interpreting . as shorthand for this.

            • option<string>
            -

            Import interface wasi:cli/exit@0.2.0

            +

            Import interface wasi:cli/exit@0.2.1


            Functions

            exit: func

            @@ -84,7 +84,7 @@ without the connotation that something bad has happened.

            • status-code: u8
            -

            Import interface wasi:io/error@0.2.0

            +

            Import interface wasi:io/error@0.2.1


            Types

            resource error

            @@ -117,7 +117,7 @@ hazard.

            • string
            -

            Import interface wasi:io/poll@0.2.0

            +

            Import interface wasi:io/poll@0.2.1

            A poll API intended to let users wait for I/O events on multiple handles at once.


            @@ -170,7 +170,7 @@ being ready for I/O.

            • list<u32>
            -

            Import interface wasi:io/streams@0.2.0

            +

            Import interface wasi:io/streams@0.2.1

            WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

            In the future, the component model is expected to add built-in stream types; @@ -209,12 +209,15 @@ use the subscribe function to obtain a po for using wasi:io/poll.

            resource output-stream

            An output bytestream.

            -

            output-streams are non-blocking to the extent practical on +

            output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also always return promptly, after the number of bytes that can be written promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe function to obtain a pollable which can be -polled for using wasi:io/poll.

            +polled for using wasi:io/poll.

            +

            Dropping an output-stream while there's still an active write in +progress may result in the data being lost. Before dropping the stream, +be sure to fully flush your writes.

            Functions

            [method]input-stream.read: func

            Perform a non-blocking read from the stream.

            @@ -396,7 +399,7 @@ and stream is ready for writing again.

          [method]output-stream.subscribe: func

          Create a pollable which will resolve once the output-stream -is ready for more writing, or an error has occured. When this +is ready for more writing, or an error has occurred. When this pollable is ready, check-write will return ok(n) with n>0, or an error.

          If the stream is closed, this pollable is always ready immediately.

          @@ -459,7 +462,7 @@ let _ = this.check-write(); // eliding error handling

          [method]output-stream.splice: func

          Read from one stream and write to another.

          -

          The behavior of splice is equivelant to:

          +

          The behavior of splice is equivalent to:

          1. calling check-write on the output-stream
          2. calling read on the input-stream with the smaller of the @@ -495,7 +498,7 @@ is ready for reading, before performing the splice.

            -

            Import interface wasi:cli/stdin@0.2.0

            +

            Import interface wasi:cli/stdin@0.2.1


            Types

            type input-stream

            @@ -508,7 +511,7 @@ is ready for reading, before performing the splice.

            -

            Import interface wasi:cli/stdout@0.2.0

            +

            Import interface wasi:cli/stdout@0.2.1


            Types

            type output-stream

            @@ -521,7 +524,7 @@ is ready for reading, before performing the splice.

            -

            Import interface wasi:cli/stderr@0.2.0

            +

            Import interface wasi:cli/stderr@0.2.1


            Types

            type output-stream

            @@ -534,7 +537,7 @@ is ready for reading, before performing the splice.

            -

            Import interface wasi:cli/terminal-input@0.2.0

            +

            Import interface wasi:cli/terminal-input@0.2.1

            Terminal input.

            In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -543,7 +546,7 @@ immediately, querying supported features, and so on.

            Types

            resource terminal-input

            The input side of a terminal.

            -

            Import interface wasi:cli/terminal-output@0.2.0

            +

            Import interface wasi:cli/terminal-output@0.2.1

            Terminal output.

            In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -552,7 +555,7 @@ features, and so on.

            Types

            resource terminal-output

            The output side of a terminal.

            -

            Import interface wasi:cli/terminal-stdin@0.2.0

            +

            Import interface wasi:cli/terminal-stdin@0.2.1

            An interface providing an optional terminal-input for stdin as a link-time authority.


            @@ -569,7 +572,7 @@ allowing further interaction with it.

            -

            Import interface wasi:cli/terminal-stdout@0.2.0

            +

            Import interface wasi:cli/terminal-stdout@0.2.1

            An interface providing an optional terminal-output for stdout as a link-time authority.


            @@ -586,7 +589,7 @@ allowing further interaction with it.

            -

            Import interface wasi:cli/terminal-stderr@0.2.0

            +

            Import interface wasi:cli/terminal-stderr@0.2.1

            An interface providing an optional terminal-output for stderr as a link-time authority.


            @@ -603,7 +606,7 @@ allowing further interaction with it.

            -

            Import interface wasi:clocks/monotonic-clock@0.2.0

            +

            Import interface wasi:clocks/monotonic-clock@0.2.1

            WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

            It is intended to be portable at least between Unix-family platforms and @@ -642,7 +645,7 @@ corresponding to a clock tick.

            subscribe-instant: func

            Create a pollable which will resolve once the specified instant -has occured.

            +has occurred.

            Params
            • when: instant
            • @@ -662,7 +665,7 @@ elapsed from the time this function is invoked.

              -

              Import interface wasi:clocks/wall-clock@0.2.0

              +

              Import interface wasi:clocks/wall-clock@0.2.1

              WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

              @@ -703,7 +706,7 @@ also known as Unix Time.
            • datetime
            -

            Import interface wasi:filesystem/types@0.2.0

            +

            Import interface wasi:filesystem/types@0.2.1

            WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

            @@ -810,7 +813,7 @@ requirement.

          3. requested-write-sync:

            -

            Requests that reads be performed at the same level of integrety +

            Requests that reads be performed at the same level of integrity requested for writes. This is similar to `O_RSYNC` in POSIX.

            The precise semantics of this operation have not yet been defined for WASI. At this time, it should be interpreted as a request, and not a @@ -1583,7 +1586,7 @@ errors are filesystem-related errors.

            -

            Import interface wasi:filesystem/preopens@0.2.0

            +

            Import interface wasi:filesystem/preopens@0.2.1


            Types

            type descriptor

            @@ -1597,7 +1600,7 @@ errors are filesystem-related errors.

            -

            Import interface wasi:sockets/network@0.2.0

            +

            Import interface wasi:sockets/network@0.2.1


            Types

            resource network

            @@ -1790,7 +1793,7 @@ supported size.
          4. ipv4: ipv4-socket-address
          5. ipv6: ipv6-socket-address
          6. -

            Import interface wasi:sockets/instance-network@0.2.0

            +

            Import interface wasi:sockets/instance-network@0.2.1

            This interface provides a value-export of the default network handle..


            Types

            @@ -1805,7 +1808,7 @@ supported size. -

            Import interface wasi:sockets/udp@0.2.0

            +

            Import interface wasi:sockets/udp@0.2.1


            Types

            type pollable

            @@ -2219,7 +2222,7 @@ It's planned to be removed when future is natively supported in Pre -

            Import interface wasi:sockets/udp-create-socket@0.2.0

            +

            Import interface wasi:sockets/udp-create-socket@0.2.1


            Types

            type network

            @@ -2264,7 +2267,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

            Import interface wasi:sockets/tcp@0.2.0

            +

            Import interface wasi:sockets/tcp@0.2.1


            Types

            type input-stream

            @@ -2855,7 +2858,7 @@ has no effect and returns ok.

            -

            Import interface wasi:sockets/tcp-create-socket@0.2.0

            +

            Import interface wasi:sockets/tcp-create-socket@0.2.1


            Types

            type network

            @@ -2900,7 +2903,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

            Import interface wasi:sockets/ip-name-lookup@0.2.0

            +

            Import interface wasi:sockets/ip-name-lookup@0.2.1


            Types

            type pollable

            @@ -2980,7 +2983,7 @@ It's planned to be removed when future is natively supported in Pre -

            Import interface wasi:random/random@0.2.0

            +

            Import interface wasi:random/random@0.2.1

            WASI Random is a random data API.

            It is intended to be portable at least between Unix-family platforms and Windows.

            @@ -3013,7 +3016,7 @@ represented as a u64.

            • u64
            -

            Import interface wasi:random/insecure@0.2.0

            +

            Import interface wasi:random/insecure@0.2.1

            The insecure interface for insecure pseudo-random numbers.

            It is intended to be portable at least between Unix-family platforms and Windows.

            @@ -3042,7 +3045,7 @@ a long period.

            • u64
            -

            Import interface wasi:random/insecure-seed@0.2.0

            +

            Import interface wasi:random/insecure-seed@0.2.1

            The insecure-seed interface for seeding hash-map DoS resistance.

            It is intended to be portable at least between Unix-family platforms and Windows.

            @@ -3066,7 +3069,7 @@ protection.

            • (u64, u64)
            -

            Export interface wasi:cli/run@0.2.0

            +

            Export interface wasi:cli/run@0.2.1


            Functions

            run: func

            diff --git a/proposals/cli/imports.md b/proposals/cli/imports.md index 495ad207c..ab22b2ad8 100644 --- a/proposals/cli/imports.md +++ b/proposals/cli/imports.md @@ -2,37 +2,37 @@ -

            Import interface wasi:cli/environment@0.2.0

            +
          7. interface wasi:cli/environment@0.2.1
          8. +
          9. interface wasi:cli/exit@0.2.1
          10. +
          11. interface wasi:io/error@0.2.1
          12. +
          13. interface wasi:io/poll@0.2.1
          14. +
          15. interface wasi:io/streams@0.2.1
          16. +
          17. interface wasi:cli/stdin@0.2.1
          18. +
          19. interface wasi:cli/stdout@0.2.1
          20. +
          21. interface wasi:cli/stderr@0.2.1
          22. +
          23. interface wasi:cli/terminal-input@0.2.1
          24. +
          25. interface wasi:cli/terminal-output@0.2.1
          26. +
          27. interface wasi:cli/terminal-stdin@0.2.1
          28. +
          29. interface wasi:cli/terminal-stdout@0.2.1
          30. +
          31. interface wasi:cli/terminal-stderr@0.2.1
          32. +
          33. interface wasi:clocks/monotonic-clock@0.2.1
          34. +
          35. interface wasi:clocks/wall-clock@0.2.1
          36. +
          37. interface wasi:filesystem/types@0.2.1
          38. +
          39. interface wasi:filesystem/preopens@0.2.1
          40. +
          41. interface wasi:sockets/network@0.2.1
          42. +
          43. interface wasi:sockets/instance-network@0.2.1
          44. +
          45. interface wasi:sockets/udp@0.2.1
          46. +
          47. interface wasi:sockets/udp-create-socket@0.2.1
          48. +
          49. interface wasi:sockets/tcp@0.2.1
          50. +
          51. interface wasi:sockets/tcp-create-socket@0.2.1
          52. +
          53. interface wasi:sockets/ip-name-lookup@0.2.1
          54. +
          55. interface wasi:random/random@0.2.1
          56. +
          57. interface wasi:random/insecure@0.2.1
          58. +
          59. interface wasi:random/insecure-seed@0.2.1
          60. + + + +

            Import interface wasi:cli/environment@0.2.1


            Functions

            get-environment: func

            @@ -59,7 +59,7 @@ directory, interpreting . as shorthand for this.

            • option<string>
            -

            Import interface wasi:cli/exit@0.2.0

            +

            Import interface wasi:cli/exit@0.2.1


            Functions

            exit: func

            @@ -79,7 +79,7 @@ without the connotation that something bad has happened.

            • status-code: u8
            -

            Import interface wasi:io/error@0.2.0

            +

            Import interface wasi:io/error@0.2.1


            Types

            resource error

            @@ -112,7 +112,7 @@ hazard.

            • string
            -

            Import interface wasi:io/poll@0.2.0

            +

            Import interface wasi:io/poll@0.2.1

            A poll API intended to let users wait for I/O events on multiple handles at once.


            @@ -165,7 +165,7 @@ being ready for I/O.

            • list<u32>
            -

            Import interface wasi:io/streams@0.2.0

            +

            Import interface wasi:io/streams@0.2.1

            WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

            In the future, the component model is expected to add built-in stream types; @@ -204,12 +204,15 @@ use the subscribe function to obtain a po for using wasi:io/poll.

            resource output-stream

            An output bytestream.

            -

            output-streams are non-blocking to the extent practical on +

            output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also always return promptly, after the number of bytes that can be written promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe function to obtain a pollable which can be -polled for using wasi:io/poll.

            +polled for using wasi:io/poll.

            +

            Dropping an output-stream while there's still an active write in +progress may result in the data being lost. Before dropping the stream, +be sure to fully flush your writes.

            Functions

            [method]input-stream.read: func

            Perform a non-blocking read from the stream.

            @@ -391,7 +394,7 @@ and stream is ready for writing again.

            [method]output-stream.subscribe: func

            Create a pollable which will resolve once the output-stream -is ready for more writing, or an error has occured. When this +is ready for more writing, or an error has occurred. When this pollable is ready, check-write will return ok(n) with n>0, or an error.

            If the stream is closed, this pollable is always ready immediately.

            @@ -454,7 +457,7 @@ let _ = this.check-write(); // eliding error handling

            [method]output-stream.splice: func

            Read from one stream and write to another.

            -

            The behavior of splice is equivelant to:

            +

            The behavior of splice is equivalent to:

            1. calling check-write on the output-stream
            2. calling read on the input-stream with the smaller of the @@ -490,7 +493,7 @@ is ready for reading, before performing the splice.

              -

              Import interface wasi:cli/stdin@0.2.0

              +

              Import interface wasi:cli/stdin@0.2.1


              Types

              type input-stream

              @@ -503,7 +506,7 @@ is ready for reading, before performing the splice.

              -

              Import interface wasi:cli/stdout@0.2.0

              +

              Import interface wasi:cli/stdout@0.2.1


              Types

              type output-stream

              @@ -516,7 +519,7 @@ is ready for reading, before performing the splice.

              -

              Import interface wasi:cli/stderr@0.2.0

              +

              Import interface wasi:cli/stderr@0.2.1


              Types

              type output-stream

              @@ -529,7 +532,7 @@ is ready for reading, before performing the splice.

              -

              Import interface wasi:cli/terminal-input@0.2.0

              +

              Import interface wasi:cli/terminal-input@0.2.1

              Terminal input.

              In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -538,7 +541,7 @@ immediately, querying supported features, and so on.

              Types

              resource terminal-input

              The input side of a terminal.

              -

              Import interface wasi:cli/terminal-output@0.2.0

              +

              Import interface wasi:cli/terminal-output@0.2.1

              Terminal output.

              In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -547,7 +550,7 @@ features, and so on.

              Types

              resource terminal-output

              The output side of a terminal.

              -

              Import interface wasi:cli/terminal-stdin@0.2.0

              +

              Import interface wasi:cli/terminal-stdin@0.2.1

              An interface providing an optional terminal-input for stdin as a link-time authority.


              @@ -564,7 +567,7 @@ allowing further interaction with it.

              -

              Import interface wasi:cli/terminal-stdout@0.2.0

              +

              Import interface wasi:cli/terminal-stdout@0.2.1

              An interface providing an optional terminal-output for stdout as a link-time authority.


              @@ -581,7 +584,7 @@ allowing further interaction with it.

              -

              Import interface wasi:cli/terminal-stderr@0.2.0

              +

              Import interface wasi:cli/terminal-stderr@0.2.1

              An interface providing an optional terminal-output for stderr as a link-time authority.


              @@ -598,7 +601,7 @@ allowing further interaction with it.

              -

              Import interface wasi:clocks/monotonic-clock@0.2.0

              +

              Import interface wasi:clocks/monotonic-clock@0.2.1

              WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

              It is intended to be portable at least between Unix-family platforms and @@ -637,7 +640,7 @@ corresponding to a clock tick.

              subscribe-instant: func

              Create a pollable which will resolve once the specified instant -has occured.

              +has occurred.

              Params
              • when: instant
              • @@ -657,7 +660,7 @@ elapsed from the time this function is invoked.

                -

                Import interface wasi:clocks/wall-clock@0.2.0

                +

                Import interface wasi:clocks/wall-clock@0.2.1

                WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                @@ -698,7 +701,7 @@ also known as Unix Time.
              • datetime
              -

              Import interface wasi:filesystem/types@0.2.0

              +

              Import interface wasi:filesystem/types@0.2.1

              WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

              @@ -805,7 +808,7 @@ requirement.

            3. requested-write-sync:

              -

              Requests that reads be performed at the same level of integrety +

              Requests that reads be performed at the same level of integrity requested for writes. This is similar to `O_RSYNC` in POSIX.

              The precise semantics of this operation have not yet been defined for WASI. At this time, it should be interpreted as a request, and not a @@ -1578,7 +1581,7 @@ errors are filesystem-related errors.

              -

              Import interface wasi:filesystem/preopens@0.2.0

              +

              Import interface wasi:filesystem/preopens@0.2.1


              Types

              type descriptor

              @@ -1592,7 +1595,7 @@ errors are filesystem-related errors.

              -

              Import interface wasi:sockets/network@0.2.0

              +

              Import interface wasi:sockets/network@0.2.1


              Types

              resource network

              @@ -1785,7 +1788,7 @@ supported size.
            4. ipv4: ipv4-socket-address
            5. ipv6: ipv6-socket-address
            6. -

              Import interface wasi:sockets/instance-network@0.2.0

              +

              Import interface wasi:sockets/instance-network@0.2.1

              This interface provides a value-export of the default network handle..


              Types

              @@ -1800,7 +1803,7 @@ supported size. -

              Import interface wasi:sockets/udp@0.2.0

              +

              Import interface wasi:sockets/udp@0.2.1


              Types

              type pollable

              @@ -2214,7 +2217,7 @@ It's planned to be removed when future is natively supported in Pre -

              Import interface wasi:sockets/udp-create-socket@0.2.0

              +

              Import interface wasi:sockets/udp-create-socket@0.2.1


              Types

              type network

              @@ -2259,7 +2262,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

              Import interface wasi:sockets/tcp@0.2.0

              +

              Import interface wasi:sockets/tcp@0.2.1


              Types

              type input-stream

              @@ -2850,7 +2853,7 @@ has no effect and returns ok.

              -

              Import interface wasi:sockets/tcp-create-socket@0.2.0

              +

              Import interface wasi:sockets/tcp-create-socket@0.2.1


              Types

              type network

              @@ -2895,7 +2898,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

              Import interface wasi:sockets/ip-name-lookup@0.2.0

              +

              Import interface wasi:sockets/ip-name-lookup@0.2.1


              Types

              type pollable

              @@ -2975,7 +2978,7 @@ It's planned to be removed when future is natively supported in Pre -

              Import interface wasi:random/random@0.2.0

              +

              Import interface wasi:random/random@0.2.1

              WASI Random is a random data API.

              It is intended to be portable at least between Unix-family platforms and Windows.

              @@ -3008,7 +3011,7 @@ represented as a u64.

              • u64
              -

              Import interface wasi:random/insecure@0.2.0

              +

              Import interface wasi:random/insecure@0.2.1

              The insecure interface for insecure pseudo-random numbers.

              It is intended to be portable at least between Unix-family platforms and Windows.

              @@ -3037,7 +3040,7 @@ a long period.

              • u64
              -

              Import interface wasi:random/insecure-seed@0.2.0

              +

              Import interface wasi:random/insecure-seed@0.2.1

              The insecure-seed interface for seeding hash-map DoS resistance.

              It is intended to be portable at least between Unix-family platforms and Windows.

              diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index 0fc85e95a..dc064a3cd 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.0; +package wasi:cli@0.2.1; @since(version = 0.2.0) world command { diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index 8660c85a4..4308eabff 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,24 +1,24 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "f27a857de70c1b0dfbabda35812a8de1253089623b1a84ddd066183c6ffac5f8" -sha512 = "9df1b0be1e4925f671fda65d433217798404f8e2e4fa60ff8bfdfd257f0b6d212ea350c141f308cf4cc57fb0b44899b14af1f9af97a05dcd6f8ae00a7594de8d" +sha256 = "ea9d69ee803bc176e23e5268f5e24a2ac485dd1f62a0ab4c748e9d3f901f576f" +sha512 = "5efc22927c46cd56c41e5549ec775561c7fac2ea0d365abc0b55396d9475a7c9f984077a81f84a44a726f1c008fd2fadbffffa4fa53ecd5fbfd05afd379ab428" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "e37bda5e27222621771ba07d2e9daf862a728c31f91024badfc4f9a42c9ae8ee" -sha512 = "81e92f5e4eca0c8f9606f26a1c4eebb3c53a708b57d3f7e7c60e97aa3c18794b72a44c39212de566442e25313b5ccb5b0b7c9070f3600f0c7c584ea9db91e207" +sha256 = "cfe8c420e8b857de612ae2a3336680dae16b95c93c8ba3a6ff05b21210966740" +sha512 = "3c00c5544a58658e3e8025677091685286027fd49f37abf198c30b4e83b9e68f19723975aaa98794fba9f425ae9ef4f3dc0f5b9cf59203b5ecfaadf62b296f9a" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "f3e976740ed9512674c627c6588864c477a9ff539bb7e55c7b9ceab222399b52" -sha512 = "c785122b4c04e2297e3fa37ae76c149b0a681444da106758cf673023923b69a6b2c65624ffbb6ad31edef02f9fbc677b05c89525f07b1159fe0c997a8c6b1a8f" +sha256 = "2a74bd811adc46b5a0f19827ddbde89870e52b17615f4d0873f06fd977250caf" +sha512 = "94624f00c66e66203592cee820f80b1ba91ecdb71f682c154f25eaf71f8d8954197dcb64503bc21e72ed5e812af7eae876df47b7eb727b02db3a74a7ce0aefca" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "2f0014e946e38947afe120836b17cdcfa608be993d38d55b81cc2d31e7e70b16" -sha512 = "51ee623509040de77b0ba236e29589102538aacd3dd67168b06a09bf6ae469c762818fc07b5039d2a8b1838f4b5a5965a7c81ed0e2d47b142bece9d1ab8b93a6" +sha256 = "9e2d5056186f81b2e7f96bc97d2babd0341840f6abb4f170449b70992f1b598f" +sha512 = "67bf41d8d5d4b7af084124ee85196585225785969059f59e2f9ddb77ac1a8095cfe811ae29d076aac817418fa01064d7b9fbc0233930bace680758eeb21e36f8" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "5321ba37115d503bfe0880349e99ecbd26ee812708fa83d2b276ec8ee7571443" -sha512 = "c3d71c2afa1475bf10d86b1e0623e2292e5dd407cf54103ad0d05c07fa95323bff9ad06e929d508b318a0a99a67132793fb9a04c17585843e24f090f5ee91367" +sha256 = "4c361137a7e61e8b9a73da2a0899dd9ad1a0c2dfee7d310cf168704c57b7a07c" +sha512 = "348b4ef381f57aec23d48537df8b69ab8963587dcb056e94c4cd5657e217677a4ee2a545868a5c829d2334cc6b8b0a61d3e72797999f44d78553fbd3a73c5b8d" diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index cae2363bf..3c24840c9 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.0; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.0.{pollable}; + use wasi:io/poll@0.2.1.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from @@ -35,7 +35,7 @@ interface monotonic-clock { resolution: func() -> duration; /// Create a `pollable` which will resolve once the specified instant - /// has occured. + /// has occurred. @since(version = 0.2.0) subscribe-instant: func( when: instant, diff --git a/proposals/cli/wit/deps/clocks/timezone.wit b/proposals/cli/wit/deps/clocks/timezone.wit index 3c286889e..212da6682 100644 --- a/proposals/cli/wit/deps/clocks/timezone.wit +++ b/proposals/cli/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit index 4b08d71ee..6be069a32 100644 --- a/proposals/cli/wit/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/cli/wit/deps/clocks/world.wit b/proposals/cli/wit/deps/clocks/world.wit index 76a9206c5..9251ac645 100644 --- a/proposals/cli/wit/deps/clocks/world.wit +++ b/proposals/cli/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/filesystem/preopens.wit b/proposals/cli/wit/deps/filesystem/preopens.wit index 08094ab3f..ca2f726af 100644 --- a/proposals/cli/wit/deps/filesystem/preopens.wit +++ b/proposals/cli/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0; +package wasi:filesystem@0.2.1; @since(version = 0.2.0) interface preopens { diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index 4900ae2c4..db3d96867 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0; +package wasi:filesystem@0.2.1; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.0; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.0.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.1.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.0.{datetime}; + use wasi:clocks/wall-clock@0.2.1.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) @@ -83,7 +83,7 @@ interface types { /// WASI. At this time, it should be interpreted as a request, and not a /// requirement. data-integrity-sync, - /// Requests that reads be performed at the same level of integrety + /// Requests that reads be performed at the same level of integrity /// requested for writes. This is similar to `O_RSYNC` in POSIX. /// /// The precise semantics of this operation have not yet been defined for diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit index c8d99f56e..af0146cbc 100644 --- a/proposals/cli/wit/deps/filesystem/world.wit +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0; +package wasi:filesystem@0.2.1; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/io/error.wit b/proposals/cli/wit/deps/io/error.wit index 7e66dbba2..4ea29c469 100644 --- a/proposals/cli/wit/deps/io/error.wit +++ b/proposals/cli/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; @since(version = 0.2.0) interface error { diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit index cbdc960f0..b25ac729f 100644 --- a/proposals/cli/wit/deps/io/poll.wit +++ b/proposals/cli/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index a57f20439..b697e24d6 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -112,6 +112,10 @@ interface streams { /// promptly, which could even be zero. To wait for the stream to be ready to /// accept data, the `subscribe` function to obtain a `pollable` which can be /// polled for using `wasi:io/poll`. + /// + /// Dropping an `output-stream` while there's still an active write in + /// progress may result in the data being lost. Before dropping the stream, + /// be sure to fully flush your writes. @since(version = 0.2.0) resource output-stream { /// Check readiness for writing. This function never blocks. @@ -192,7 +196,7 @@ interface streams { blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream - /// is ready for more writing, or an error has occured. When this + /// is ready for more writing, or an error has occurred. When this /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an /// error. /// @@ -247,7 +251,7 @@ interface streams { /// Read from one stream and write to another. /// - /// The behavior of splice is equivelant to: + /// The behavior of splice is equivalent to: /// 1. calling `check-write` on the `output-stream` /// 2. calling `read` on the `input-stream` with the smaller of the /// `check-write` permitted length and the `len` provided to `splice` diff --git a/proposals/cli/wit/deps/io/world.wit b/proposals/cli/wit/deps/io/world.wit index f5c098793..6405a4e48 100644 --- a/proposals/cli/wit/deps/io/world.wit +++ b/proposals/cli/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/random/insecure-seed.wit b/proposals/cli/wit/deps/random/insecure-seed.wit index 4cce62858..7e708dc52 100644 --- a/proposals/cli/wit/deps/random/insecure-seed.wit +++ b/proposals/cli/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/insecure.wit b/proposals/cli/wit/deps/random/insecure.wit index 3cea0c4a6..3cdb53dfb 100644 --- a/proposals/cli/wit/deps/random/insecure.wit +++ b/proposals/cli/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index 41c3a0367..2b5035d1c 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/world.wit b/proposals/cli/wit/deps/random/world.wit index b5560a67a..c615e96dc 100644 --- a/proposals/cli/wit/deps/random/world.wit +++ b/proposals/cli/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index 0368b4801..dc56f3000 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.0.{pollable}; + use wasi:io/poll@0.2.1.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index e4a62101b..bae5a29ec 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.0.{input-stream, output-stream}; + use wasi:io/streams@0.2.1.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.0.{pollable}; + use wasi:io/poll@0.2.1.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.0.{duration}; + use wasi:clocks/monotonic-clock@0.2.1.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index 48e753cac..b289e4943 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.0.{pollable}; + use wasi:io/poll@0.2.1.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit index a1f7d14bc..a1d42670e 100644 --- a/proposals/cli/wit/deps/sockets/world.wit +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.0; +package wasi:sockets@0.2.1; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/imports.wit b/proposals/cli/wit/imports.wit index cd59ba1c0..b8339d3b2 100644 --- a/proposals/cli/wit/imports.wit +++ b/proposals/cli/wit/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.0; +package wasi:cli@0.2.1; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.0; + include wasi:clocks/imports@0.2.1; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.0; + include wasi:filesystem/imports@0.2.1; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.0; + include wasi:sockets/imports@0.2.1; @since(version = 0.2.0) - include wasi:random/imports@0.2.0; + include wasi:random/imports@0.2.1; @since(version = 0.2.0) - include wasi:io/imports@0.2.0; + include wasi:io/imports@0.2.1; @since(version = 0.2.0) import environment; diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index e9502a93d..d1d26eb61 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.0.{input-stream}; + use wasi:io/streams@0.2.1.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.0.{output-stream}; + use wasi:io/streams@0.2.1.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.0.{output-stream}; + use wasi:io/streams@0.2.1.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; From 95875abcf4d1ccbce9c42dcbc6c0ca16906175f2 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 1 Aug 2024 17:56:04 +0200 Subject: [PATCH 1492/1772] Update to v0.2.1 --- proposals/http/.github/workflows/main.yml | 2 +- proposals/http/imports.md | 44 +++++++-------- proposals/http/proxy.md | 48 ++++++++-------- proposals/http/wit-0.3.0-draft/deps.lock | 24 ++++---- .../http/wit-0.3.0-draft/deps/cli/command.wit | 5 +- .../wit-0.3.0-draft/deps/cli/environment.wit | 4 ++ .../http/wit-0.3.0-draft/deps/cli/exit.wit | 13 +++++ .../http/wit-0.3.0-draft/deps/cli/imports.wit | 28 ++++++++-- .../http/wit-0.3.0-draft/deps/cli/run.wit | 2 + .../http/wit-0.3.0-draft/deps/cli/stdio.wit | 15 ++++- .../wit-0.3.0-draft/deps/cli/terminal.wit | 13 +++++ .../deps/clocks/monotonic-clock.wit | 21 ++++--- .../wit-0.3.0-draft/deps/clocks/timezone.wit | 55 +++++++++++++++++++ .../deps/clocks/wall-clock.wit | 6 +- .../wit-0.3.0-draft/deps/clocks/world.wit | 7 ++- .../deps/filesystem/preopens.wit | 5 +- .../wit-0.3.0-draft/deps/filesystem/types.wit | 52 ++++++++++++++++-- .../wit-0.3.0-draft/deps/filesystem/world.wit | 5 +- .../http/wit-0.3.0-draft/deps/io/error.wit | 18 +++--- .../http/wit-0.3.0-draft/deps/io/poll.wit | 14 +++-- .../http/wit-0.3.0-draft/deps/io/streams.wit | 30 +++++++++- .../http/wit-0.3.0-draft/deps/io/world.wit | 6 +- .../deps/random/insecure-seed.wit | 4 +- .../wit-0.3.0-draft/deps/random/insecure.wit | 5 +- .../wit-0.3.0-draft/deps/random/random.wit | 5 +- .../wit-0.3.0-draft/deps/random/world.wit | 8 ++- .../deps/sockets/instance-network.wit | 4 +- .../deps/sockets/ip-name-lookup.wit | 11 +++- .../wit-0.3.0-draft/deps/sockets/network.wit | 12 +++- .../deps/sockets/tcp-create-socket.wit | 5 +- .../http/wit-0.3.0-draft/deps/sockets/tcp.wit | 54 ++++++++++++++---- .../deps/sockets/udp-create-socket.wit | 5 +- .../http/wit-0.3.0-draft/deps/sockets/udp.wit | 30 ++++++++-- .../wit-0.3.0-draft/deps/sockets/world.wit | 10 +++- proposals/http/wit-0.3.0-draft/proxy.wit | 10 ++-- proposals/http/wit-0.3.0-draft/types.wit | 4 +- proposals/http/wit/deps.lock | 24 ++++---- proposals/http/wit/deps/cli/command.wit | 2 +- proposals/http/wit/deps/cli/exit.wit | 11 ++++ proposals/http/wit/deps/cli/imports.wit | 12 ++-- proposals/http/wit/deps/cli/stdio.wit | 6 +- .../http/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/http/wit/deps/clocks/timezone.wit | 2 +- proposals/http/wit/deps/clocks/wall-clock.wit | 2 +- proposals/http/wit/deps/clocks/world.wit | 2 +- .../http/wit/deps/filesystem/preopens.wit | 2 +- proposals/http/wit/deps/filesystem/types.wit | 6 +- proposals/http/wit/deps/filesystem/world.wit | 2 +- proposals/http/wit/deps/io/error.wit | 2 +- proposals/http/wit/deps/io/poll.wit | 2 +- proposals/http/wit/deps/io/streams.wit | 2 +- proposals/http/wit/deps/io/world.wit | 2 +- .../http/wit/deps/random/insecure-seed.wit | 2 +- proposals/http/wit/deps/random/insecure.wit | 2 +- proposals/http/wit/deps/random/random.wit | 2 +- proposals/http/wit/deps/random/world.wit | 2 +- .../http/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/http/wit/deps/sockets/tcp.wit | 6 +- proposals/http/wit/deps/sockets/udp.wit | 2 +- proposals/http/wit/deps/sockets/world.wit | 2 +- proposals/http/wit/proxy.wit | 14 ++--- proposals/http/wit/types.wit | 8 +-- 62 files changed, 516 insertions(+), 193 deletions(-) create mode 100644 proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index 8a72c4d3f..2d34992f6 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -18,5 +18,5 @@ jobs: ./wit-deps lock --check - uses: WebAssembly/wit-abi-up-to-date@v21 with: - wit-bindgen: '0.26.0' + wit-bindgen: '0.28.0' worlds: 'imports proxy' diff --git a/proposals/http/imports.md b/proposals/http/imports.md index 04435c870..c4abffb43 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -4,21 +4,21 @@ It is intended to be included in other worlds.

              -

              Import interface wasi:io/poll@0.2.0

              +

              Import interface wasi:io/poll@0.2.1

              A poll API intended to let users wait for I/O events on multiple handles at once.


              @@ -71,7 +71,7 @@ being ready for I/O.

              • list<u32>
              -

              Import interface wasi:clocks/monotonic-clock@0.2.0

              +

              Import interface wasi:clocks/monotonic-clock@0.2.1

              WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

              It is intended to be portable at least between Unix-family platforms and @@ -130,7 +130,7 @@ elapsed from the time this function is invoked.

              -

              Import interface wasi:clocks/wall-clock@0.2.0

              +

              Import interface wasi:clocks/wall-clock@0.2.1

              WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

              @@ -171,7 +171,7 @@ also known as Unix Time.
            7. datetime
            8. -

              Import interface wasi:random/random@0.2.0

              +

              Import interface wasi:random/random@0.2.1

              WASI Random is a random data API.

              It is intended to be portable at least between Unix-family platforms and Windows.

              @@ -204,7 +204,7 @@ represented as a u64.

              • u64
              -

              Import interface wasi:io/error@0.2.0

              +

              Import interface wasi:io/error@0.2.1


              Types

              resource error

              @@ -237,7 +237,7 @@ hazard.

              • string
              -

              Import interface wasi:io/streams@0.2.0

              +

              Import interface wasi:io/streams@0.2.1

              WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

              In the future, the component model is expected to add built-in stream types; @@ -565,7 +565,7 @@ is ready for reading, before performing the splice.

              -

              Import interface wasi:cli/stdout@0.2.0

              +

              Import interface wasi:cli/stdout@0.2.1


              Types

              type output-stream

              @@ -578,7 +578,7 @@ is ready for reading, before performing the splice.

              -

              Import interface wasi:cli/stderr@0.2.0

              +

              Import interface wasi:cli/stderr@0.2.1


              Types

              type output-stream

              @@ -591,7 +591,7 @@ is ready for reading, before performing the splice.

              -

              Import interface wasi:cli/stdin@0.2.0

              +

              Import interface wasi:cli/stdin@0.2.1


              Types

              type input-stream

              @@ -604,7 +604,7 @@ is ready for reading, before performing the splice.

              -

              Import interface wasi:http/types@0.2.0

              +

              Import interface wasi:http/types@0.2.1

              This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

              @@ -1494,7 +1494,7 @@ but those will be reported by the incoming-body
            9. option<result<result<own<incoming-response>, error-code>>>
            10. -

              Import interface wasi:http/outgoing-handler@0.2.0

              +

              Import interface wasi:http/outgoing-handler@0.2.1

              This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


              diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 6b0de97d6..a1d3f93a1 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -6,26 +6,26 @@ outgoing HTTP requests.

              -

              Import interface wasi:io/poll@0.2.0

              +

              Import interface wasi:io/poll@0.2.1

              A poll API intended to let users wait for I/O events on multiple handles at once.


              @@ -78,7 +78,7 @@ being ready for I/O.

              • list<u32>
              -

              Import interface wasi:clocks/monotonic-clock@0.2.0

              +

              Import interface wasi:clocks/monotonic-clock@0.2.1

              WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

              It is intended to be portable at least between Unix-family platforms and @@ -137,7 +137,7 @@ elapsed from the time this function is invoked.

              -

              Import interface wasi:io/error@0.2.0

              +

              Import interface wasi:io/error@0.2.1


              Types

              resource error

              @@ -170,7 +170,7 @@ hazard.

              • string
              -

              Import interface wasi:io/streams@0.2.0

              +

              Import interface wasi:io/streams@0.2.1

              WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

              In the future, the component model is expected to add built-in stream types; @@ -498,7 +498,7 @@ is ready for reading, before performing the splice.

              -

              Import interface wasi:http/types@0.2.0

              +

              Import interface wasi:http/types@0.2.1

              This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

              @@ -1388,7 +1388,7 @@ but those will be reported by the incoming-body
            11. option<result<result<own<incoming-response>, error-code>>>
            12. -

              Import interface wasi:clocks/wall-clock@0.2.0

              +

              Import interface wasi:clocks/wall-clock@0.2.1

              WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

              @@ -1429,7 +1429,7 @@ also known as Unix Time.
            13. datetime
            14. -

              Import interface wasi:random/random@0.2.0

              +

              Import interface wasi:random/random@0.2.1

              WASI Random is a random data API.

              It is intended to be portable at least between Unix-family platforms and Windows.

              @@ -1462,7 +1462,7 @@ represented as a u64.

              • u64
              -

              Import interface wasi:cli/stdout@0.2.0

              +

              Import interface wasi:cli/stdout@0.2.1


              Types

              type output-stream

              @@ -1475,7 +1475,7 @@ represented as a u64.

              -

              Import interface wasi:cli/stderr@0.2.0

              +

              Import interface wasi:cli/stderr@0.2.1


              Types

              type output-stream

              @@ -1488,7 +1488,7 @@ represented as a u64.

              -

              Import interface wasi:cli/stdin@0.2.0

              +

              Import interface wasi:cli/stdin@0.2.1


              Types

              type input-stream

              @@ -1501,7 +1501,7 @@ represented as a u64.

              -

              Import interface wasi:http/outgoing-handler@0.2.0

              +

              Import interface wasi:http/outgoing-handler@0.2.1

              This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


              @@ -1538,7 +1538,7 @@ through the future-incoming-response
            15. result<own<future-incoming-response>, error-code>
            16. -

              Export interface wasi:http/incoming-handler@0.2.0

              +

              Export interface wasi:http/incoming-handler@0.2.1


              Types

              type incoming-request

              diff --git a/proposals/http/wit-0.3.0-draft/deps.lock b/proposals/http/wit-0.3.0-draft/deps.lock index 96be4b203..a12064a91 100644 --- a/proposals/http/wit-0.3.0-draft/deps.lock +++ b/proposals/http/wit-0.3.0-draft/deps.lock @@ -1,29 +1,29 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -sha256 = "285865a31d777181b075f39e92bcfe59c89cd6bacce660be1b9a627646956258" -sha512 = "da2622210a9e3eea82b99f1a5b8a44ce5443d009cb943f7bca0bf9cf4360829b289913d7ee727c011f0f72994ea7dc8e661ebcc0a6b34b587297d80cd9b3f7e8" +sha256 = "1de50b8e6940e73110cda10b7f90ca87a8fea886f0fa36c748f96dc70671ee38" +sha512 = "bbb6cd3e7b4d3237b6af9bfbb2633ccd2c4ea2a4f37b8c033255c7e0c1cb037be7f22ec1f8ca792cc8ec1942199582943979e646b4b272b85dcff7654eac51d0" [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "468b4d12892fe926b8eb5d398dbf579d566c93231fa44f415440572c695b7613" -sha512 = "e6b53a07221f1413953c9797c68f08b815fdaebf66419bbc1ea3e8b7dece73731062693634731f311a03957b268cf9cc509c518bd15e513c318aa04a8459b93a" +sha256 = "ea9d69ee803bc176e23e5268f5e24a2ac485dd1f62a0ab4c748e9d3f901f576f" +sha512 = "5efc22927c46cd56c41e5549ec775561c7fac2ea0d365abc0b55396d9475a7c9f984077a81f84a44a726f1c008fd2fadbffffa4fa53ecd5fbfd05afd379ab428" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "498c465cfd04587db40f970fff2185daa597d074c20b68a8bcbae558f261499b" -sha512 = "ead452f9b7bfb88593a502ec00d76d4228003d51c40fd0408aebc32d35c94673551b00230d730873361567cc209ec218c41fb4e95bad194268592c49e7964347" +sha256 = "cfe8c420e8b857de612ae2a3336680dae16b95c93c8ba3a6ff05b21210966740" +sha512 = "3c00c5544a58658e3e8025677091685286027fd49f37abf198c30b4e83b9e68f19723975aaa98794fba9f425ae9ef4f3dc0f5b9cf59203b5ecfaadf62b296f9a" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "7210e5653539a15478f894d4da24cc69d61924cbcba21d2804d69314a88e5a4c" -sha512 = "49184a1b0945a889abd52d25271172ed3dc2db6968fcdddb1bab7ee0081f4a3eeee0977ad2291126a37631c0d86eeea75d822fa8af224c422134500bf9f0f2bb" +sha256 = "2a74bd811adc46b5a0f19827ddbde89870e52b17615f4d0873f06fd977250caf" +sha512 = "94624f00c66e66203592cee820f80b1ba91ecdb71f682c154f25eaf71f8d8954197dcb64503bc21e72ed5e812af7eae876df47b7eb727b02db3a74a7ce0aefca" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "7371d03c037d924caba2587fb2e7c5773a0d3c5fcecbf7971e0e0ba57973c53d" -sha512 = "964c4e8925a53078e4d94ba907b54f89a0b7e154f46823a505391471466c17f53c8692682e5c85771712acd88b348686173fc07c53a3cfe3d301b8cd8ddd0de4" +sha256 = "9e2d5056186f81b2e7f96bc97d2babd0341840f6abb4f170449b70992f1b598f" +sha512 = "67bf41d8d5d4b7af084124ee85196585225785969059f59e2f9ddb77ac1a8095cfe811ae29d076aac817418fa01064d7b9fbc0233930bace680758eeb21e36f8" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "622bd28bbeb43736375dc02bd003fd3a016ff8ee91e14bab488325c6b38bf966" -sha512 = "5a63c1f36de0c4548e1d2297bdbededb28721cbad94ef7825c469eae29d7451c97e00b4c1d6730ee1ec0c4a5aac922961a2795762d4a0c3bb54e30a391a84bae" +sha256 = "4c361137a7e61e8b9a73da2a0899dd9ad1a0c2dfee7d310cf168704c57b7a07c" +sha512 = "348b4ef381f57aec23d48537df8b69ab8963587dcb056e94c4cd5657e217677a4ee2a545868a5c829d2334cc6b8b0a61d3e72797999f44d78553fbd3a73c5b8d" diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit index d8005bd38..dc064a3cd 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit @@ -1,7 +1,10 @@ -package wasi:cli@0.2.0; +package wasi:cli@0.2.1; +@since(version = 0.2.0) world command { + @since(version = 0.2.0) include imports; + @since(version = 0.2.0) export run; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit b/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit index 70065233e..2f449bd7c 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit @@ -1,3 +1,4 @@ +@since(version = 0.2.0) interface environment { /// Get the POSIX-style environment variables. /// @@ -7,12 +8,15 @@ interface environment { /// Morally, these are a value import, but until value imports are available /// in the component model, this import function should return the same /// values each time it is called. + @since(version = 0.2.0) get-environment: func() -> list>; /// Get the POSIX-style arguments to the program. + @since(version = 0.2.0) get-arguments: func() -> list; /// Return a path that programs should use as their initial current working /// directory, interpreting `.` as shorthand for this. + @since(version = 0.2.0) initial-cwd: func() -> option; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit b/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit index d0c2b82ae..427935c8d 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit @@ -1,4 +1,17 @@ +@since(version = 0.2.0) interface exit { /// Exit the current instance and any linked instances. + @since(version = 0.2.0) exit: func(status: result); + + /// Exit the current instance and any linked instances, reporting the + /// specified status code to the host. + /// + /// The meaning of the code depends on the context, with 0 usually meaning + /// "success", and other values indicating various types of failure. + /// + /// This function does not return; the effect is analogous to a trap, but + /// without the connotation that something bad has happened. + @unstable(feature = cli-exit-with-code) + exit-with-code: func(status-code: u8); } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit index 083b84a03..b8339d3b2 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit @@ -1,20 +1,36 @@ -package wasi:cli@0.2.0; +package wasi:cli@0.2.1; +@since(version = 0.2.0) world imports { - include wasi:clocks/imports@0.2.0; - include wasi:filesystem/imports@0.2.0; - include wasi:sockets/imports@0.2.0; - include wasi:random/imports@0.2.0; - include wasi:io/imports@0.2.0; + @since(version = 0.2.0) + include wasi:clocks/imports@0.2.1; + @since(version = 0.2.0) + include wasi:filesystem/imports@0.2.1; + @since(version = 0.2.0) + include wasi:sockets/imports@0.2.1; + @since(version = 0.2.0) + include wasi:random/imports@0.2.1; + @since(version = 0.2.0) + include wasi:io/imports@0.2.1; + @since(version = 0.2.0) import environment; + @since(version = 0.2.0) import exit; + @since(version = 0.2.0) import stdin; + @since(version = 0.2.0) import stdout; + @since(version = 0.2.0) import stderr; + @since(version = 0.2.0) import terminal-input; + @since(version = 0.2.0) import terminal-output; + @since(version = 0.2.0) import terminal-stdin; + @since(version = 0.2.0) import terminal-stdout; + @since(version = 0.2.0) import terminal-stderr; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/run.wit b/proposals/http/wit-0.3.0-draft/deps/cli/run.wit index a70ee8c03..655346efb 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/run.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/run.wit @@ -1,4 +1,6 @@ +@since(version = 0.2.0) interface run { /// Run the program. + @since(version = 0.2.0) run: func() -> result; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit index 31ef35b5a..d1d26eb61 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit @@ -1,17 +1,26 @@ +@since(version = 0.2.0) interface stdin { - use wasi:io/streams@0.2.0.{input-stream}; + @since(version = 0.2.0) + use wasi:io/streams@0.2.1.{input-stream}; + @since(version = 0.2.0) get-stdin: func() -> input-stream; } +@since(version = 0.2.0) interface stdout { - use wasi:io/streams@0.2.0.{output-stream}; + @since(version = 0.2.0) + use wasi:io/streams@0.2.1.{output-stream}; + @since(version = 0.2.0) get-stdout: func() -> output-stream; } +@since(version = 0.2.0) interface stderr { - use wasi:io/streams@0.2.0.{output-stream}; + @since(version = 0.2.0) + use wasi:io/streams@0.2.1.{output-stream}; + @since(version = 0.2.0) get-stderr: func() -> output-stream; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit b/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit index 38c724efc..d305498c6 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit @@ -3,8 +3,10 @@ /// In the future, this may include functions for disabling echoing, /// disabling input buffering so that keyboard events are sent through /// immediately, querying supported features, and so on. +@since(version = 0.2.0) interface terminal-input { /// The input side of a terminal. + @since(version = 0.2.0) resource terminal-input; } @@ -13,37 +15,48 @@ interface terminal-input { /// In the future, this may include functions for querying the terminal /// size, being notified of terminal size changes, querying supported /// features, and so on. +@since(version = 0.2.0) interface terminal-output { /// The output side of a terminal. + @since(version = 0.2.0) resource terminal-output; } /// An interface providing an optional `terminal-input` for stdin as a /// link-time authority. +@since(version = 0.2.0) interface terminal-stdin { + @since(version = 0.2.0) use terminal-input.{terminal-input}; /// If stdin is connected to a terminal, return a `terminal-input` handle /// allowing further interaction with it. + @since(version = 0.2.0) get-terminal-stdin: func() -> option; } /// An interface providing an optional `terminal-output` for stdout as a /// link-time authority. +@since(version = 0.2.0) interface terminal-stdout { + @since(version = 0.2.0) use terminal-output.{terminal-output}; /// If stdout is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. + @since(version = 0.2.0) get-terminal-stdout: func() -> option; } /// An interface providing an optional `terminal-output` for stderr as a /// link-time authority. +@since(version = 0.2.0) interface terminal-stderr { + @since(version = 0.2.0) use terminal-output.{terminal-output}; /// If stderr is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. + @since(version = 0.2.0) get-terminal-stderr: func() -> option; } diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 4e4dc3a19..3c24840c9 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,38 +7,43 @@ package wasi:clocks@0.2.0; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -/// -/// It is intended for measuring elapsed time. +@since(version = 0.2.0) interface monotonic-clock { - use wasi:io/poll@0.2.0.{pollable}; + @since(version = 0.2.0) + use wasi:io/poll@0.2.1.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. + @since(version = 0.2.0) type instant = u64; /// A duration of time, in nanoseconds. + @since(version = 0.2.0) type duration = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + @since(version = 0.2.0) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. + @since(version = 0.2.0) resolution: func() -> duration; /// Create a `pollable` which will resolve once the specified instant - /// occured. + /// has occurred. + @since(version = 0.2.0) subscribe-instant: func( when: instant, ) -> pollable; - /// Create a `pollable` which will resolve once the given duration has - /// elapsed, starting at the time at which this function was called. - /// occured. + /// Create a `pollable` that will resolve after the specified duration has + /// elapsed from the time this function is invoked. + @since(version = 0.2.0) subscribe-duration: func( when: duration, ) -> pollable; diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit new file mode 100644 index 000000000..212da6682 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -0,0 +1,55 @@ +package wasi:clocks@0.2.1; + +@unstable(feature = clocks-timezone) +interface timezone { + @unstable(feature = clocks-timezone) + use wall-clock.{datetime}; + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + @unstable(feature = clocks-timezone) + display: func(when: datetime) -> timezone-display; + + /// The same as `display`, but only return the UTC offset. + @unstable(feature = clocks-timezone) + utc-offset: func(when: datetime) -> s32; + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + @unstable(feature = clocks-timezone) + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit index 440ca0f33..6be069a32 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,8 +13,10 @@ package wasi:clocks@0.2.0; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. +@since(version = 0.2.0) interface wall-clock { /// A time and date in seconds plus nanoseconds. + @since(version = 0.2.0) record datetime { seconds: u64, nanoseconds: u32, @@ -33,10 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + @since(version = 0.2.0) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. + @since(version = 0.2.0) resolution: func() -> datetime; } diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit index c0224572a..9251ac645 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit @@ -1,6 +1,11 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import monotonic-clock; + @since(version = 0.2.0) import wall-clock; + @unstable(feature = clocks-timezone) + import timezone; } diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit index da801f6d6..ca2f726af 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit @@ -1,8 +1,11 @@ -package wasi:filesystem@0.2.0; +package wasi:filesystem@0.2.1; +@since(version = 0.2.0) interface preopens { + @since(version = 0.2.0) use types.{descriptor}; /// Return the set of preopened directories, and their path. + @since(version = 0.2.0) get-directories: func() -> list>; } diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit index 11108fcda..db3d96867 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0; +package wasi:filesystem@0.2.1; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -23,16 +23,21 @@ package wasi:filesystem@0.2.0; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md +@since(version = 0.2.0) interface types { - use wasi:io/streams@0.2.0.{input-stream, output-stream, error}; - use wasi:clocks/wall-clock@0.2.0.{datetime}; + @since(version = 0.2.0) + use wasi:io/streams@0.2.1.{input-stream, output-stream, error}; + @since(version = 0.2.0) + use wasi:clocks/wall-clock@0.2.1.{datetime}; /// File size or length of a region within a file. + @since(version = 0.2.0) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. + @since(version = 0.2.0) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -56,6 +61,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. + @since(version = 0.2.0) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -77,7 +83,7 @@ interface types { /// WASI. At this time, it should be interpreted as a request, and not a /// requirement. data-integrity-sync, - /// Requests that reads be performed at the same level of integrety + /// Requests that reads be performed at the same level of integrity /// requested for writes. This is similar to `O_RSYNC` in POSIX. /// /// The precise semantics of this operation have not yet been defined for @@ -99,6 +105,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. + @since(version = 0.2.0) record descriptor-stat { /// File type. %type: descriptor-type, @@ -125,6 +132,7 @@ interface types { } /// Flags determining the method of how paths are resolved. + @since(version = 0.2.0) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -132,6 +140,7 @@ interface types { } /// Open flags used by `open-at`. + @since(version = 0.2.0) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -144,9 +153,11 @@ interface types { } /// Number of hard links to an inode. + @since(version = 0.2.0) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. + @since(version = 0.2.0) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -248,6 +259,7 @@ interface types { } /// File or memory access pattern advisory information. + @since(version = 0.2.0) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -271,6 +283,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. + @since(version = 0.2.0) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -281,6 +294,7 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. + @since(version = 0.2.0) resource descriptor { /// Return a stream for reading from a file, if available. /// @@ -290,6 +304,7 @@ interface types { /// file and they do not interfere with each other. /// /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. + @since(version = 0.2.0) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, @@ -301,6 +316,7 @@ interface types { /// /// Note: This allows using `write-stream`, which is similar to `write` in /// POSIX. + @since(version = 0.2.0) write-via-stream: func( /// The offset within the file at which to start writing. offset: filesize, @@ -312,11 +328,13 @@ interface types { /// /// Note: This allows using `write-stream`, which is similar to `write` with /// `O_APPEND` in in POSIX. + @since(version = 0.2.0) append-via-stream: func() -> result; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. + @since(version = 0.2.0) advise: func( /// The offset within the file to which the advisory applies. offset: filesize, @@ -332,6 +350,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. + @since(version = 0.2.0) sync-data: func() -> result<_, error-code>; /// Get flags associated with a descriptor. @@ -340,6 +359,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. + @since(version = 0.2.0) get-flags: func() -> result; /// Get the dynamic type of a descriptor. @@ -352,12 +372,14 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. + @since(version = 0.2.0) get-type: func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. + @since(version = 0.2.0) set-size: func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. @@ -365,6 +387,7 @@ interface types { /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. + @since(version = 0.2.0) set-times: func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, @@ -383,6 +406,7 @@ interface types { /// In the future, this may change to return a `stream`. /// /// Note: This is similar to `pread` in POSIX. + @since(version = 0.2.0) read: func( /// The maximum number of bytes to read. length: filesize, @@ -399,6 +423,7 @@ interface types { /// In the future, this may change to take a `stream`. /// /// Note: This is similar to `pwrite` in POSIX. + @since(version = 0.2.0) write: func( /// Data to write buffer: list, @@ -415,6 +440,7 @@ interface types { /// This always returns a new stream which starts at the beginning of the /// directory. Multiple streams may be active on the same directory, and they /// do not interfere with each other. + @since(version = 0.2.0) read-directory: func() -> result; /// Synchronize the data and metadata of a file to disk. @@ -423,11 +449,13 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. + @since(version = 0.2.0) sync: func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. + @since(version = 0.2.0) create-directory-at: func( /// The relative path at which to create the directory. path: string, @@ -442,6 +470,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. + @since(version = 0.2.0) stat: func() -> result; /// Return the attributes of a file or directory. @@ -451,6 +480,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. + @since(version = 0.2.0) stat-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -464,6 +494,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. + @since(version = 0.2.0) set-times-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -478,6 +509,7 @@ interface types { /// Create a hard link. /// /// Note: This is similar to `linkat` in POSIX. + @since(version = 0.2.0) link-at: func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, @@ -507,6 +539,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. + @since(version = 0.2.0) open-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -524,6 +557,7 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. + @since(version = 0.2.0) readlink-at: func( /// The relative path of the symbolic link from which to read. path: string, @@ -534,6 +568,7 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + @since(version = 0.2.0) remove-directory-at: func( /// The relative path to a directory to remove. path: string, @@ -542,6 +577,7 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. + @since(version = 0.2.0) rename-at: func( /// The relative source path of the file or directory to rename. old-path: string, @@ -557,6 +593,7 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. + @since(version = 0.2.0) symlink-at: func( /// The contents of the symbolic link. old-path: string, @@ -568,6 +605,7 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + @since(version = 0.2.0) unlink-file-at: func( /// The relative path to a file to unlink. path: string, @@ -579,6 +617,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. + @since(version = 0.2.0) is-same-object: func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred @@ -600,12 +639,14 @@ interface types { /// computed hash. /// /// However, none of these is required. + @since(version = 0.2.0) metadata-hash: func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. + @since(version = 0.2.0) metadata-hash-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -615,8 +656,10 @@ interface types { } /// A stream of directory entries. + @since(version = 0.2.0) resource directory-entry-stream { /// Read a single directory entry from a `directory-entry-stream`. + @since(version = 0.2.0) read-directory-entry: func() -> result, error-code>; } @@ -630,5 +673,6 @@ interface types { /// /// Note that this function is fallible because not all stream-related /// errors are filesystem-related errors. + @since(version = 0.2.0) filesystem-error-code: func(err: borrow) -> option; } diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit index 663f57920..af0146cbc 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit @@ -1,6 +1,9 @@ -package wasi:filesystem@0.2.0; +package wasi:filesystem@0.2.1; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import types; + @since(version = 0.2.0) import preopens; } diff --git a/proposals/http/wit-0.3.0-draft/deps/io/error.wit b/proposals/http/wit-0.3.0-draft/deps/io/error.wit index 22e5b6489..4ea29c469 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/error.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/error.wit @@ -1,6 +1,6 @@ -package wasi:io@0.2.0; - +package wasi:io@0.2.1; +@since(version = 0.2.0) interface error { /// A resource which represents some error information. /// @@ -11,16 +11,15 @@ interface error { /// `wasi:io/streams/stream-error` type. /// /// To provide more specific error information, other interfaces may - /// provide functions to further "downcast" this error into more specific - /// error information. For example, `error`s returned in streams derived - /// from filesystem types to be described using the filesystem's own - /// error-code type, using the function - /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter - /// `borrow` and returns - /// `option`. + /// offer functions to "downcast" this error into more specific types. For example, + /// errors returned from streams derived from filesystem types can be described using + /// the filesystem's own error-code type. This is done using the function + /// `wasi:filesystem/types/filesystem-error-code`, which takes a `borrow` + /// parameter and returns an `option`. /// /// The set of functions which can "downcast" an `error` into a more /// concrete type is open. + @since(version = 0.2.0) resource error { /// Returns a string that is suitable to assist humans in debugging /// this error. @@ -29,6 +28,7 @@ interface error { /// It may change across platforms, hosts, or other implementation /// details. Parsing this string is a major platform-compatibility /// hazard. + @since(version = 0.2.0) to-debug-string: func() -> string; } } diff --git a/proposals/http/wit-0.3.0-draft/deps/io/poll.wit b/proposals/http/wit-0.3.0-draft/deps/io/poll.wit index ddc67f8b7..b25ac729f 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/poll.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/poll.wit @@ -1,14 +1,17 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. +@since(version = 0.2.0) interface poll { /// `pollable` represents a single I/O event which may be ready, or not. + @since(version = 0.2.0) resource pollable { /// Return the readiness of a pollable. This function never blocks. /// /// Returns `true` when the pollable is ready, and `false` otherwise. + @since(version = 0.2.0) ready: func() -> bool; /// `block` returns immediately if the pollable is ready, and otherwise @@ -16,6 +19,7 @@ interface poll { /// /// This function is equivalent to calling `poll.poll` on a list /// containing only this pollable. + @since(version = 0.2.0) block: func(); } @@ -27,8 +31,9 @@ interface poll { /// The result `list` contains one or more indices of handles in the /// argument list that is ready for I/O. /// - /// If the list contains more elements than can be indexed with a `u32` - /// value, this function traps. + /// This function traps if either: + /// - the list is empty, or: + /// - the list contains more elements than can be indexed with a `u32` value. /// /// A timeout can be implemented by adding a pollable from the /// wasi-clocks API to the list. @@ -36,6 +41,7 @@ interface poll { /// This function does not return a `result`; polling in itself does not /// do any I/O so it doesn't fail. If any of the I/O sources identified by /// the pollables has an error, it is indicated by marking the source as - /// being reaedy for I/O. + /// being ready for I/O. + @since(version = 0.2.0) poll: func(in: list>) -> list; } diff --git a/proposals/http/wit-0.3.0-draft/deps/io/streams.wit b/proposals/http/wit-0.3.0-draft/deps/io/streams.wit index 6d2f871e3..b697e24d6 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/streams.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/streams.wit @@ -1,15 +1,19 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. +@since(version = 0.2.0) interface streams { + @since(version = 0.2.0) use error.{error}; + @since(version = 0.2.0) use poll.{pollable}; /// An error for input-stream and output-stream operations. + @since(version = 0.2.0) variant stream-error { /// The last operation (a write or flush) failed before completion. /// @@ -29,6 +33,7 @@ interface streams { /// available, which could even be zero. To wait for data to be available, /// use the `subscribe` function to obtain a `pollable` which can be polled /// for using `wasi:io/poll`. + @since(version = 0.2.0) resource input-stream { /// Perform a non-blocking read from the stream. /// @@ -56,6 +61,7 @@ interface streams { /// is not possible to allocate in wasm32, or not desirable to allocate as /// as a return value by the callee. The callee may return a list of bytes /// less than `len` in size while more bytes are available for reading. + @since(version = 0.2.0) read: func( /// The maximum number of bytes to read len: u64 @@ -63,6 +69,7 @@ interface streams { /// Read bytes from a stream, after blocking until at least one byte can /// be read. Except for blocking, behavior is identical to `read`. + @since(version = 0.2.0) blocking-read: func( /// The maximum number of bytes to read len: u64 @@ -72,6 +79,7 @@ interface streams { /// /// Behaves identical to `read`, except instead of returning a list /// of bytes, returns the number of bytes consumed from the stream. + @since(version = 0.2.0) skip: func( /// The maximum number of bytes to skip. len: u64, @@ -79,6 +87,7 @@ interface streams { /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. + @since(version = 0.2.0) blocking-skip: func( /// The maximum number of bytes to skip. len: u64, @@ -90,6 +99,7 @@ interface streams { /// The created `pollable` is a child resource of the `input-stream`. /// Implementations may trap if the `input-stream` is dropped before /// all derived `pollable`s created with this function are dropped. + @since(version = 0.2.0) subscribe: func() -> pollable; } @@ -102,6 +112,11 @@ interface streams { /// promptly, which could even be zero. To wait for the stream to be ready to /// accept data, the `subscribe` function to obtain a `pollable` which can be /// polled for using `wasi:io/poll`. + /// + /// Dropping an `output-stream` while there's still an active write in + /// progress may result in the data being lost. Before dropping the stream, + /// be sure to fully flush your writes. + @since(version = 0.2.0) resource output-stream { /// Check readiness for writing. This function never blocks. /// @@ -112,6 +127,7 @@ interface streams { /// When this function returns 0 bytes, the `subscribe` pollable will /// become ready when this function will report at least 1 byte, or an /// error. + @since(version = 0.2.0) check-write: func() -> result; /// Perform a write. This function never blocks. @@ -127,6 +143,7 @@ interface streams { /// /// returns Err(closed) without writing if the stream has closed since /// the last call to check-write provided a permit. + @since(version = 0.2.0) write: func( contents: list ) -> result<_, stream-error>; @@ -155,6 +172,7 @@ interface streams { /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` + @since(version = 0.2.0) blocking-write-and-flush: func( contents: list ) -> result<_, stream-error>; @@ -169,14 +187,16 @@ interface streams { /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe` pollable will become ready when the /// flush has completed and the stream can accept more writes. + @since(version = 0.2.0) flush: func() -> result<_, stream-error>; /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. + @since(version = 0.2.0) blocking-flush: func() -> result<_, stream-error>; /// Create a `pollable` which will resolve once the output-stream - /// is ready for more writing, or an error has occured. When this + /// is ready for more writing, or an error has occurred. When this /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an /// error. /// @@ -193,6 +213,7 @@ interface streams { /// preconditions (must use check-write first), but instead of /// passing a list of bytes, you simply pass the number of zero-bytes /// that should be written. + @since(version = 0.2.0) write-zeroes: func( /// The number of zero-bytes to write len: u64 @@ -222,6 +243,7 @@ interface streams { /// // Check for any errors that arose during `flush` /// let _ = this.check-write(); // eliding error handling /// ``` + @since(version = 0.2.0) blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write len: u64 @@ -229,7 +251,7 @@ interface streams { /// Read from one stream and write to another. /// - /// The behavior of splice is equivelant to: + /// The behavior of splice is equivalent to: /// 1. calling `check-write` on the `output-stream` /// 2. calling `read` on the `input-stream` with the smaller of the /// `check-write` permitted length and the `len` provided to `splice` @@ -240,6 +262,7 @@ interface streams { /// /// This function returns the number of bytes transferred; it may be less /// than `len`. + @since(version = 0.2.0) splice: func( /// The stream to read from src: borrow, @@ -252,6 +275,7 @@ interface streams { /// This is similar to `splice`, except that it blocks until the /// `output-stream` is ready for writing, and the `input-stream` /// is ready for reading, before performing the `splice`. + @since(version = 0.2.0) blocking-splice: func( /// The stream to read from src: borrow, diff --git a/proposals/http/wit-0.3.0-draft/deps/io/world.wit b/proposals/http/wit-0.3.0-draft/deps/io/world.wit index 5f0b43fe5..6405a4e48 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/world.wit @@ -1,6 +1,10 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import streams; + + @since(version = 0.2.0) import poll; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit index 47210ac6b..7e708dc52 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit @@ -1,8 +1,9 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +@since(version = 0.2.0) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -21,5 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. + @since(version = 0.2.0) insecure-seed: func() -> tuple; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit index c58f4ee85..3cdb53dfb 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit @@ -1,8 +1,9 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +@since(version = 0.2.0) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -12,11 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. + @since(version = 0.2.0) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. + @since(version = 0.2.0) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/random.wit b/proposals/http/wit-0.3.0-draft/deps/random/random.wit index 0c017f093..2b5035d1c 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/random.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/random.wit @@ -1,8 +1,9 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. +@since(version = 0.2.0) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -16,11 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. + @since(version = 0.2.0) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. + @since(version = 0.2.0) get-random-u64: func() -> u64; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/world.wit b/proposals/http/wit-0.3.0-draft/deps/random/world.wit index 3da34914a..c615e96dc 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/world.wit @@ -1,7 +1,13 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import random; + + @since(version = 0.2.0) import insecure; + + @since(version = 0.2.0) import insecure-seed; } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/instance-network.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/instance-network.wit index e455d0ff7..5f6e6c1cc 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/instance-network.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/instance-network.wit @@ -1,9 +1,11 @@ /// This interface provides a value-export of the default network handle.. +@since(version = 0.2.0) interface instance-network { + @since(version = 0.2.0) use network.{network}; /// Get a handle to the default network. + @since(version = 0.2.0) instance-network: func() -> network; - } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit index 8e639ec59..dc56f3000 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit @@ -1,9 +1,10 @@ - +@since(version = 0.2.0) interface ip-name-lookup { - use wasi:io/poll@0.2.0.{pollable}; + @since(version = 0.2.0) + use wasi:io/poll@0.2.1.{pollable}; + @since(version = 0.2.0) use network.{network, error-code, ip-address}; - /// Resolve an internet host name to a list of IP addresses. /// /// Unicode domain names are automatically converted to ASCII using IDNA encoding. @@ -24,8 +25,10 @@ interface ip-name-lookup { /// - /// - /// - + @since(version = 0.2.0) resolve-addresses: func(network: borrow, name: string) -> result; + @since(version = 0.2.0) resource resolve-address-stream { /// Returns the next address from the resolver. /// @@ -40,12 +43,14 @@ interface ip-name-lookup { /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) + @since(version = 0.2.0) resolve-next-address: func() -> result, error-code>; /// Create a `pollable` which will resolve once the stream is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit index 9cadf0650..8c13b348e 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit @@ -1,8 +1,9 @@ - +@since(version = 0.2.0) interface network { /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. + @since(version = 0.2.0) resource network; /// Error codes. @@ -17,6 +18,7 @@ interface network { /// - `concurrency-conflict` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. + @since(version = 0.2.0) enum error-code { /// Unknown error unknown, @@ -103,6 +105,7 @@ interface network { permanent-resolver-failure, } + @since(version = 0.2.0) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -111,14 +114,18 @@ interface network { ipv6, } + @since(version = 0.2.0) type ipv4-address = tuple; + @since(version = 0.2.0) type ipv6-address = tuple; + @since(version = 0.2.0) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } + @since(version = 0.2.0) record ipv4-socket-address { /// sin_port port: u16, @@ -126,6 +133,7 @@ interface network { address: ipv4-address, } + @since(version = 0.2.0) record ipv6-socket-address { /// sin6_port port: u16, @@ -137,9 +145,9 @@ interface network { scope-id: u32, } + @since(version = 0.2.0) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), } - } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp-create-socket.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp-create-socket.wit index c7ddf1f22..eedbd3076 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp-create-socket.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp-create-socket.wit @@ -1,6 +1,8 @@ - +@since(version = 0.2.0) interface tcp-create-socket { + @since(version = 0.2.0) use network.{network, error-code, ip-address-family}; + @since(version = 0.2.0) use tcp.{tcp-socket}; /// Create a new TCP socket. @@ -23,5 +25,6 @@ interface tcp-create-socket { /// - /// - /// - + @since(version = 0.2.0) create-tcp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit index 5902b9ee0..bae5a29ec 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit @@ -1,10 +1,15 @@ - +@since(version = 0.2.0) interface tcp { - use wasi:io/streams@0.2.0.{input-stream, output-stream}; - use wasi:io/poll@0.2.0.{pollable}; - use wasi:clocks/monotonic-clock@0.2.0.{duration}; + @since(version = 0.2.0) + use wasi:io/streams@0.2.1.{input-stream, output-stream}; + @since(version = 0.2.0) + use wasi:io/poll@0.2.1.{pollable}; + @since(version = 0.2.0) + use wasi:clocks/monotonic-clock@0.2.1.{duration}; + @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; + @since(version = 0.2.0) enum shutdown-type { /// Similar to `SHUT_RD` in POSIX. receive, @@ -27,8 +32,8 @@ interface tcp { /// - `connect-in-progress` /// - `connected` /// - `closed` - /// See - /// for a more information. + /// See + /// for more information. /// /// Note: Except where explicitly mentioned, whenever this documentation uses /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. @@ -37,6 +42,7 @@ interface tcp { /// In addition to the general error codes documented on the /// `network::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. + @since(version = 0.2.0) resource tcp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -76,13 +82,15 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) finish-bind: func() -> result<_, error-code>; /// Connect to a remote endpoint. /// /// On success: - /// - the socket is transitioned into the `connection` state. + /// - the socket is transitioned into the `connected` state. /// - a pair of streams is returned that can be used to read & write to the connection /// /// After a failed connection attempt, the socket will be in the `closed` @@ -121,7 +129,9 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) finish-connect: func() -> result, error-code>; /// Start listening for new connections. @@ -149,7 +159,9 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) start-listen: func() -> result<_, error-code>; + @since(version = 0.2.0) finish-listen: func() -> result<_, error-code>; /// Accept a new client socket. @@ -178,6 +190,7 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) accept: func() -> result, error-code>; /// Get the bound local address. @@ -196,6 +209,7 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) local-address: func() -> result; /// Get the remote address. @@ -208,16 +222,19 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. + @since(version = 0.2.0) is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.2.0) address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. @@ -229,6 +246,7 @@ interface tcp { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. + @since(version = 0.2.0) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -240,7 +258,9 @@ interface tcp { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. + @since(version = 0.2.0) keep-alive-enabled: func() -> result; + @since(version = 0.2.0) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. @@ -253,7 +273,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) keep-alive-idle-time: func() -> result; + @since(version = 0.2.0) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. @@ -266,7 +288,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) keep-alive-interval: func() -> result; + @since(version = 0.2.0) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. @@ -279,7 +303,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) keep-alive-count: func() -> result; + @since(version = 0.2.0) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -288,7 +314,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.2.0) hop-limit: func() -> result; + @since(version = 0.2.0) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -301,9 +329,13 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) receive-buffer-size: func() -> result; + @since(version = 0.2.0) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) send-buffer-size: func() -> result; + @since(version = 0.2.0) set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Create a `pollable` which can be used to poll for, or block on, @@ -318,11 +350,12 @@ interface tcp { /// `subscribe` only has to be called once per socket and can then be /// (re)used for the remainder of the socket's lifetime. /// - /// See - /// for a more information. + /// See + /// for more information. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; /// Initiate a graceful shutdown. @@ -335,7 +368,7 @@ interface tcp { /// associated with this socket will be closed and a FIN packet will be sent. /// - `both`: Same effect as `receive` & `send` combined. /// - /// This function is idempotent. Shutting a down a direction more than once + /// This function is idempotent; shutting down a direction more than once /// has no effect and returns `ok`. /// /// The shutdown function does not close (drop) the socket. @@ -348,6 +381,7 @@ interface tcp { /// - /// - /// - + @since(version = 0.2.0) shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; } } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/udp-create-socket.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/udp-create-socket.wit index 0482d1fe7..e8eeacbfe 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/udp-create-socket.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/udp-create-socket.wit @@ -1,6 +1,8 @@ - +@since(version = 0.2.0) interface udp-create-socket { + @since(version = 0.2.0) use network.{network, error-code, ip-address-family}; + @since(version = 0.2.0) use udp.{udp-socket}; /// Create a new UDP socket. @@ -23,5 +25,6 @@ interface udp-create-socket { /// - /// - /// - + @since(version = 0.2.0) create-udp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit index d987a0a90..b289e4943 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit @@ -1,9 +1,12 @@ - +@since(version = 0.2.0) interface udp { - use wasi:io/poll@0.2.0.{pollable}; + @since(version = 0.2.0) + use wasi:io/poll@0.2.1.{pollable}; + @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; /// A received datagram. + @since(version = 0.2.0) record incoming-datagram { /// The payload. /// @@ -19,6 +22,7 @@ interface udp { } /// A datagram to be sent out. + @since(version = 0.2.0) record outgoing-datagram { /// The payload. data: list, @@ -33,9 +37,8 @@ interface udp { remote-address: option, } - - /// A UDP socket handle. + @since(version = 0.2.0) resource udp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -63,7 +66,9 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.2.0) finish-bind: func() -> result<_, error-code>; /// Set up inbound & outbound communication channels, optionally to a specific peer. @@ -106,6 +111,7 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) %stream: func(remote-address: option) -> result, error-code>; /// Get the current bound address. @@ -124,6 +130,7 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) local-address: func() -> result; /// Get the address the socket is currently streaming to. @@ -136,11 +143,13 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.2.0) address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -149,7 +158,9 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.2.0) unicast-hop-limit: func() -> result; + @since(version = 0.2.0) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -162,18 +173,24 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) receive-buffer-size: func() -> result; + @since(version = 0.2.0) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) send-buffer-size: func() -> result; + @since(version = 0.2.0) set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Create a `pollable` which will resolve once the socket is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } + @since(version = 0.2.0) resource incoming-datagram-stream { /// Receive messages on the socket. /// @@ -198,15 +215,18 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) receive: func(max-results: u64) -> result, error-code>; /// Create a `pollable` which will resolve once the stream is ready to receive again. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } + @since(version = 0.2.0) resource outgoing-datagram-stream { /// Check readiness for sending. This function never blocks. /// @@ -255,12 +275,14 @@ interface udp { /// - /// - /// - + @since(version = 0.2.0) send: func(datagrams: list) -> result; /// Create a `pollable` which will resolve once the stream is ready to send again. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. + @since(version = 0.2.0) subscribe: func() -> pollable; } } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit index f8bb92ae0..a1d42670e 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit @@ -1,11 +1,19 @@ -package wasi:sockets@0.2.0; +package wasi:sockets@0.2.1; +@since(version = 0.2.0) world imports { + @since(version = 0.2.0) import instance-network; + @since(version = 0.2.0) import network; + @since(version = 0.2.0) import udp; + @since(version = 0.2.0) import udp-create-socket; + @since(version = 0.2.0) import tcp; + @since(version = 0.2.0) import tcp-create-socket; + @since(version = 0.2.0) import ip-name-lookup; } diff --git a/proposals/http/wit-0.3.0-draft/proxy.wit b/proposals/http/wit-0.3.0-draft/proxy.wit index 2226bc011..6a83dc740 100644 --- a/proposals/http/wit-0.3.0-draft/proxy.wit +++ b/proposals/http/wit-0.3.0-draft/proxy.wit @@ -4,19 +4,19 @@ package wasi:http@0.3.0-draft; /// It is intended to be `include`d in other worlds. world imports { /// HTTP proxies have access to time and randomness. - include wasi:clocks/imports@0.2.0; - import wasi:random/random@0.2.0; + include wasi:clocks/imports@0.2.1; + import wasi:random/random@0.2.1; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.2.0; - import wasi:cli/stderr@0.2.0; + import wasi:cli/stdout@0.2.1; + import wasi:cli/stderr@0.2.1; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. - import wasi:cli/stdin@0.2.0; + import wasi:cli/stdin@0.2.1; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index a41624cac..da636bcb4 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -1,8 +1,8 @@ /// This interface defines all of the types and methods for implementing HTTP /// Requests and Responses, as well as their headers, trailers, and bodies. interface types { - use wasi:clocks/monotonic-clock@0.2.0.{duration}; - use wasi:io/error@0.2.0.{error}; + use wasi:clocks/monotonic-clock@0.2.1.{duration}; + use wasi:io/error@0.2.1.{error}; /// This type corresponds to HTTP standard Methods. variant method { diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 34441a507..a12064a91 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,29 +1,29 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -sha256 = "a690bfee4b365af5ec012cb664c82ce53076bef5263d3da45c5da42271eaf98c" -sha512 = "21e687cb2d8d7ba2ba5bcf40ef43b8c68e4f2c1c6e8dd147166e695b3462a1650d2b806636c8608e8b42d24a498016a003d6127ebb784bf4f5b329ed1d07817e" +sha256 = "1de50b8e6940e73110cda10b7f90ca87a8fea886f0fa36c748f96dc70671ee38" +sha512 = "bbb6cd3e7b4d3237b6af9bfbb2633ccd2c4ea2a4f37b8c033255c7e0c1cb037be7f22ec1f8ca792cc8ec1942199582943979e646b4b272b85dcff7654eac51d0" [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "b7fbb753c70fe6727ea3456bc2cde3230df69d1f4f004cda7014625783959e50" -sha512 = "99310e017418553a0613247a65aef39e46b08b27f2d3d170465f5ecb97ec9c0ccbcb4e358526440ba6ef9d37cf991d04367ffa6b87d2d8db4e1b36a737f2191e" +sha256 = "ea9d69ee803bc176e23e5268f5e24a2ac485dd1f62a0ab4c748e9d3f901f576f" +sha512 = "5efc22927c46cd56c41e5549ec775561c7fac2ea0d365abc0b55396d9475a7c9f984077a81f84a44a726f1c008fd2fadbffffa4fa53ecd5fbfd05afd379ab428" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "cc45d3ebf145274e7e4d1eb516099c87c68ef6062447e3f8bcd492d60dfa27a8" -sha512 = "0b0af2b253de228fb282f270f5337df728834421000b6a2a789cc47460b36548babd1f77eca698308fef00896ce3c8509071b0da636babd6e87599e4d1400e53" +sha256 = "cfe8c420e8b857de612ae2a3336680dae16b95c93c8ba3a6ff05b21210966740" +sha512 = "3c00c5544a58658e3e8025677091685286027fd49f37abf198c30b4e83b9e68f19723975aaa98794fba9f425ae9ef4f3dc0f5b9cf59203b5ecfaadf62b296f9a" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "f1d1f111840529e06cd5f53726ebac82f344caf64f65a38dfef84e036643ef75" -sha512 = "8a09fb15e4a5d46c910d4a05ed90551166192dcfb28309f08f23237ad926fb4685ce95f06905929cb47e209b291b26d1baa92c3e3dbabf81308654453927ec26" +sha256 = "2a74bd811adc46b5a0f19827ddbde89870e52b17615f4d0873f06fd977250caf" +sha512 = "94624f00c66e66203592cee820f80b1ba91ecdb71f682c154f25eaf71f8d8954197dcb64503bc21e72ed5e812af7eae876df47b7eb727b02db3a74a7ce0aefca" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "2f0014e946e38947afe120836b17cdcfa608be993d38d55b81cc2d31e7e70b16" -sha512 = "51ee623509040de77b0ba236e29589102538aacd3dd67168b06a09bf6ae469c762818fc07b5039d2a8b1838f4b5a5965a7c81ed0e2d47b142bece9d1ab8b93a6" +sha256 = "9e2d5056186f81b2e7f96bc97d2babd0341840f6abb4f170449b70992f1b598f" +sha512 = "67bf41d8d5d4b7af084124ee85196585225785969059f59e2f9ddb77ac1a8095cfe811ae29d076aac817418fa01064d7b9fbc0233930bace680758eeb21e36f8" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "5321ba37115d503bfe0880349e99ecbd26ee812708fa83d2b276ec8ee7571443" -sha512 = "c3d71c2afa1475bf10d86b1e0623e2292e5dd407cf54103ad0d05c07fa95323bff9ad06e929d508b318a0a99a67132793fb9a04c17585843e24f090f5ee91367" +sha256 = "4c361137a7e61e8b9a73da2a0899dd9ad1a0c2dfee7d310cf168704c57b7a07c" +sha512 = "348b4ef381f57aec23d48537df8b69ab8963587dcb056e94c4cd5657e217677a4ee2a545868a5c829d2334cc6b8b0a61d3e72797999f44d78553fbd3a73c5b8d" diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit index 0fc85e95a..dc064a3cd 100644 --- a/proposals/http/wit/deps/cli/command.wit +++ b/proposals/http/wit/deps/cli/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.0; +package wasi:cli@0.2.1; @since(version = 0.2.0) world command { diff --git a/proposals/http/wit/deps/cli/exit.wit b/proposals/http/wit/deps/cli/exit.wit index 357e6707b..427935c8d 100644 --- a/proposals/http/wit/deps/cli/exit.wit +++ b/proposals/http/wit/deps/cli/exit.wit @@ -3,4 +3,15 @@ interface exit { /// Exit the current instance and any linked instances. @since(version = 0.2.0) exit: func(status: result); + + /// Exit the current instance and any linked instances, reporting the + /// specified status code to the host. + /// + /// The meaning of the code depends on the context, with 0 usually meaning + /// "success", and other values indicating various types of failure. + /// + /// This function does not return; the effect is analogous to a trap, but + /// without the connotation that something bad has happened. + @unstable(feature = cli-exit-with-code) + exit-with-code: func(status-code: u8); } diff --git a/proposals/http/wit/deps/cli/imports.wit b/proposals/http/wit/deps/cli/imports.wit index cd59ba1c0..b8339d3b2 100644 --- a/proposals/http/wit/deps/cli/imports.wit +++ b/proposals/http/wit/deps/cli/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.0; +package wasi:cli@0.2.1; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.0; + include wasi:clocks/imports@0.2.1; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.0; + include wasi:filesystem/imports@0.2.1; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.0; + include wasi:sockets/imports@0.2.1; @since(version = 0.2.0) - include wasi:random/imports@0.2.0; + include wasi:random/imports@0.2.1; @since(version = 0.2.0) - include wasi:io/imports@0.2.0; + include wasi:io/imports@0.2.1; @since(version = 0.2.0) import environment; diff --git a/proposals/http/wit/deps/cli/stdio.wit b/proposals/http/wit/deps/cli/stdio.wit index e9502a93d..d1d26eb61 100644 --- a/proposals/http/wit/deps/cli/stdio.wit +++ b/proposals/http/wit/deps/cli/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.0.{input-stream}; + use wasi:io/streams@0.2.1.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.0.{output-stream}; + use wasi:io/streams@0.2.1.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.0.{output-stream}; + use wasi:io/streams@0.2.1.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index afbd700e1..3c24840c9 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.0; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.0.{pollable}; + use wasi:io/poll@0.2.1.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/http/wit/deps/clocks/timezone.wit b/proposals/http/wit/deps/clocks/timezone.wit index 3c286889e..212da6682 100644 --- a/proposals/http/wit/deps/clocks/timezone.wit +++ b/proposals/http/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/http/wit/deps/clocks/wall-clock.wit b/proposals/http/wit/deps/clocks/wall-clock.wit index 4b08d71ee..6be069a32 100644 --- a/proposals/http/wit/deps/clocks/wall-clock.wit +++ b/proposals/http/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/http/wit/deps/clocks/world.wit b/proposals/http/wit/deps/clocks/world.wit index 76a9206c5..9251ac645 100644 --- a/proposals/http/wit/deps/clocks/world.wit +++ b/proposals/http/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.0; +package wasi:clocks@0.2.1; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/filesystem/preopens.wit b/proposals/http/wit/deps/filesystem/preopens.wit index 08094ab3f..ca2f726af 100644 --- a/proposals/http/wit/deps/filesystem/preopens.wit +++ b/proposals/http/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0; +package wasi:filesystem@0.2.1; @since(version = 0.2.0) interface preopens { diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index d061d5fd4..db3d96867 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0; +package wasi:filesystem@0.2.1; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.0; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.0.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.1.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.0.{datetime}; + use wasi:clocks/wall-clock@0.2.1.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/http/wit/deps/filesystem/world.wit b/proposals/http/wit/deps/filesystem/world.wit index c8d99f56e..af0146cbc 100644 --- a/proposals/http/wit/deps/filesystem/world.wit +++ b/proposals/http/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.0; +package wasi:filesystem@0.2.1; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/io/error.wit b/proposals/http/wit/deps/io/error.wit index 7e66dbba2..4ea29c469 100644 --- a/proposals/http/wit/deps/io/error.wit +++ b/proposals/http/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; @since(version = 0.2.0) interface error { diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/io/poll.wit index cbdc960f0..b25ac729f 100644 --- a/proposals/http/wit/deps/io/poll.wit +++ b/proposals/http/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index b5e2a36ac..b697e24d6 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit index f5c098793..6405a4e48 100644 --- a/proposals/http/wit/deps/io/world.wit +++ b/proposals/http/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.0; +package wasi:io@0.2.1; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/random/insecure-seed.wit b/proposals/http/wit/deps/random/insecure-seed.wit index 4cce62858..7e708dc52 100644 --- a/proposals/http/wit/deps/random/insecure-seed.wit +++ b/proposals/http/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/insecure.wit b/proposals/http/wit/deps/random/insecure.wit index 3cea0c4a6..3cdb53dfb 100644 --- a/proposals/http/wit/deps/random/insecure.wit +++ b/proposals/http/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index 41c3a0367..2b5035d1c 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit index b5560a67a..c615e96dc 100644 --- a/proposals/http/wit/deps/random/world.wit +++ b/proposals/http/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.0; +package wasi:random@0.2.1; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/sockets/ip-name-lookup.wit b/proposals/http/wit/deps/sockets/ip-name-lookup.wit index 0368b4801..dc56f3000 100644 --- a/proposals/http/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.0.{pollable}; + use wasi:io/poll@0.2.1.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index e4a62101b..bae5a29ec 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.0.{input-stream, output-stream}; + use wasi:io/streams@0.2.1.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.0.{pollable}; + use wasi:io/poll@0.2.1.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.0.{duration}; + use wasi:clocks/monotonic-clock@0.2.1.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index 48e753cac..b289e4943 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.0.{pollable}; + use wasi:io/poll@0.2.1.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit index a1f7d14bc..a1d42670e 100644 --- a/proposals/http/wit/deps/sockets/world.wit +++ b/proposals/http/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.0; +package wasi:sockets@0.2.1; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 84802480b..415d2ee1c 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,4 +1,4 @@ -package wasi:http@0.2.0; +package wasi:http@0.2.1; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. /// It is intended to be `include`d in other worlds. @@ -6,25 +6,25 @@ package wasi:http@0.2.0; world imports { /// HTTP proxies have access to time and randomness. @since(version = 0.2.0) - import wasi:clocks/monotonic-clock@0.2.0; + import wasi:clocks/monotonic-clock@0.2.1; @since(version = 0.2.0) - import wasi:clocks/wall-clock@0.2.0; + import wasi:clocks/wall-clock@0.2.1; @since(version = 0.2.0) - import wasi:random/random@0.2.0; + import wasi:random/random@0.2.1; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. @since(version = 0.2.0) - import wasi:cli/stdout@0.2.0; + import wasi:cli/stdout@0.2.1; @since(version = 0.2.0) - import wasi:cli/stderr@0.2.0; + import wasi:cli/stderr@0.2.1; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. @since(version = 0.2.0) - import wasi:cli/stdin@0.2.0; + import wasi:cli/stdin@0.2.1; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index f2ce84638..3c45cd08b 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -4,13 +4,13 @@ @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.0.{duration}; + use wasi:clocks/monotonic-clock@0.2.1.{duration}; @since(version = 0.2.0) - use wasi:io/streams@0.2.0.{input-stream, output-stream}; + use wasi:io/streams@0.2.1.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/error@0.2.0.{error as io-error}; + use wasi:io/error@0.2.1.{error as io-error}; @since(version = 0.2.0) - use wasi:io/poll@0.2.0.{pollable}; + use wasi:io/poll@0.2.1.{pollable}; /// This type corresponds to HTTP standard Methods. @since(version = 0.2.0) From e8eb211ab9e44ca99c7a99fb10ff113a0c3bd1b5 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 7 Aug 2024 09:30:35 +0200 Subject: [PATCH 1493/1772] Remove documentation on the numeric resource id value. --- proposals/filesystem/imports.md | 5 ----- proposals/filesystem/wit/types.wit | 6 ------ 2 files changed, 11 deletions(-) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index cede7691e..ba18125cf 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -1170,11 +1170,6 @@ WASI.

              [method]descriptor.open-at: func

              Open a file or directory.

              -

              The returned descriptor is not guaranteed to be the lowest-numbered -descriptor not currently open/ it is randomized to prevent applications -from depending on making assumptions about indexes, since this is -error-prone in multi-threaded contexts. The returned descriptor is -guaranteed to be less than 2**31.

              If flags contains descriptor-flags::mutate-directory, and the base descriptor doesn't have descriptor-flags::mutate-directory set, open-at fails with error-code::read-only.

              diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index db3d96867..db3f3c614 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -523,12 +523,6 @@ interface types { /// Open a file or directory. /// - /// The returned descriptor is not guaranteed to be the lowest-numbered - /// descriptor not currently open/ it is randomized to prevent applications - /// from depending on making assumptions about indexes, since this is - /// error-prone in multi-threaded contexts. The returned descriptor is - /// guaranteed to be less than 2**31. - /// /// If `flags` contains `descriptor-flags::mutate-directory`, and the base /// descriptor doesn't have `descriptor-flags::mutate-directory` set, /// `open-at` fails with `error-code::read-only`. From 4913db042d4685f76df0e63c5c4ff7dd17b8825c Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 7 Aug 2024 19:24:39 +0200 Subject: [PATCH 1494/1772] Document that stream errors are final. (#84) --- proposals/io/imports.md | 2 ++ proposals/io/wit/streams.wit | 3 +++ 2 files changed, 5 insertions(+) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index 7f456058b..da7edcb11 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -115,6 +115,8 @@ when it does, they are expected to subsume this API.

              last-operation-failed: own<error>

              The last operation (a write or flush) failed before completion.

              More information is available in the error payload.

              +

              After this, the stream will be closed. All future operations return +stream-error::closed.

            17. closed

              diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index b697e24d6..49108236b 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -18,6 +18,9 @@ interface streams { /// The last operation (a write or flush) failed before completion. /// /// More information is available in the `error` payload. + /// + /// After this, the stream will be closed. All future operations return + /// `stream-error::closed`. last-operation-failed(error), /// The stream is closed: no more input will be accepted by the /// stream. A closed output-stream will return this error on all From c2475d7a266828198af70b51992184a191903077 Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 14 Aug 2024 14:19:54 +0200 Subject: [PATCH 1495/1772] Specify the casing of field keys and values The PR updating this only caught the 0.3-draft APIs, presumably by accident. Including it in this change since we're touching the header names already. --- proposals/http/wit/types.wit | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 3c45cd08b..71482776b 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -139,6 +139,9 @@ interface types { } /// Field keys are always strings. + /// + /// Field keys should always be treated as case insensitive by the `fields` + /// resource for the purposes of equality checking. @since(version = 0.2.0) type field-key = string; From f5847c44dafc0d56b17e8c623301fdfb10014872 Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 14 Aug 2024 14:20:28 +0200 Subject: [PATCH 1496/1772] deprecate `field-key` in favor of `field-name` --- proposals/http/proxy.md | 811 ++++++++++++----------- proposals/http/wit-0.3.0-draft/types.wit | 27 +- proposals/http/wit/types.wit | 41 +- 3 files changed, 452 insertions(+), 427 deletions(-) diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index a1d3f93a1..f019fb553 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -1,4 +1,4 @@ -

              World proxy

              +

              World proxy

              The wasi:http/proxy world captures a widely-implementable intersection of hosts that includes HTTP forward and reverse proxies. Components targeting this world may concurrently stream in and out any number of incoming and @@ -25,35 +25,35 @@ outgoing HTTP requests.

            18. -

              Import interface wasi:io/poll@0.2.1

              +

              Import interface wasi:io/poll@0.2.1

              A poll API intended to let users wait for I/O events on multiple handles at once.


              Types

              -

              resource pollable

              +

              resource pollable

              pollable represents a single I/O event which may be ready, or not.

              Functions

              -

              [method]pollable.ready: func

              +

              [method]pollable.ready: func

              Return the readiness of a pollable. This function never blocks.

              Returns true when the pollable is ready, and false otherwise.

              Params
              Return values
                -
              • bool
              • +
              • bool
              -

              [method]pollable.block: func

              +

              [method]pollable.block: func

              block returns immediately if the pollable is ready, and otherwise blocks until ready.

              This function is equivalent to calling poll.poll on a list containing only this pollable.

              Params
              -

              poll: func

              +

              poll: func

              Poll for completion on a set of pollables.

              This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

              @@ -72,13 +72,13 @@ the pollables has an error, it is indicated by marking the source as being ready for I/O.

              Params
              Return values
                -
              • list<u32>
              • +
              • list<u32>
              -

              Import interface wasi:clocks/monotonic-clock@0.2.1

              +

              Import interface wasi:clocks/monotonic-clock@0.2.1

              WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

              It is intended to be portable at least between Unix-family platforms and @@ -87,60 +87,60 @@ Windows.

              successive reads of the clock will produce non-decreasing values.


              Types

              -

              type pollable

              +

              type pollable

              pollable

              -#### `type instant` +#### `type instant` `u64`

              An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. -

              type duration

              +

              type duration

              u64

              A duration of time, in nanoseconds.


              Functions

              -

              now: func

              +

              now: func

              Read the current value of the clock.

              The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

              Return values
              -

              resolution: func

              +

              resolution: func

              Query the resolution of the clock. Returns the duration of time corresponding to a clock tick.

              Return values
              -

              subscribe-instant: func

              +

              subscribe-instant: func

              Create a pollable which will resolve once the specified instant has occurred.

              Params
              Return values
              -

              subscribe-duration: func

              +

              subscribe-duration: func

              Create a pollable that will resolve after the specified duration has elapsed from the time this function is invoked.

              Params
              Return values
              -

              Import interface wasi:io/error@0.2.1

              +

              Import interface wasi:io/error@0.2.1


              Types

              -

              resource error

              +

              resource error

              A resource which represents some error information.

              The only method provided by this resource is to-debug-string, which provides some human-readable information about the error.

              @@ -155,7 +155,7 @@ parameter and returns an option<wasi:filesystem/types/error-code>The set of functions which can "downcast" an error into a more concrete type is open.

              Functions

              -

              [method]error.to-debug-string: func

              +

              [method]error.to-debug-string: func

              Returns a string that is suitable to assist humans in debugging this error.

              WARNING: The returned string should not be consumed mechanically! @@ -164,42 +164,42 @@ details. Parsing this string is a major platform-compatibility hazard.

              Params
              Return values
                -
              • string
              • +
              • string
              -

              Import interface wasi:io/streams@0.2.1

              +

              Import interface wasi:io/streams@0.2.1

              WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

              In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


              Types

              -

              type error

              +

              type error

              error

              -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

              -#### `variant stream-error` +#### `variant stream-error`

              An error for input-stream and output-stream operations.

              Variant Cases
              • -

                last-operation-failed: own<error>

                +

                last-operation-failed: own<error>

                The last operation (a write or flush) failed before completion.

                More information is available in the error payload.

              • -

                closed

                +

                closed

                The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

              -

              resource input-stream

              +

              resource input-stream

              An input bytestream.

              input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are @@ -207,7 +207,7 @@ promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

              -

              resource output-stream

              +

              resource output-stream

              An output bytestream.

              output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also @@ -219,7 +219,7 @@ polled for using wasi:io/poll.

              progress may result in the data being lost. Before dropping the stream, be sure to fully flush your writes.

              Functions

              -

              [method]input-stream.read: func

              +

              [method]input-stream.read: func

              Perform a non-blocking read from the stream.

              When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -243,51 +243,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

              Params
              Return values
              -

              [method]input-stream.blocking-read: func

              +

              [method]input-stream.blocking-read: func

              Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

              Params
              Return values
              -

              [method]input-stream.skip: func

              +

              [method]input-stream.skip: func

              Skip bytes from a stream. Returns number of bytes skipped.

              Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

              Params
              Return values
              -

              [method]input-stream.blocking-skip: func

              +

              [method]input-stream.blocking-skip: func

              Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

              Params
              Return values
              -

              [method]input-stream.subscribe: func

              +

              [method]input-stream.subscribe: func

              Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -296,13 +296,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

              Params
              Return values
              -

              [method]output-stream.check-write: func

              +

              [method]output-stream.check-write: func

              Check readiness for writing. This function never blocks.

              Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -312,13 +312,13 @@ become ready when this function will report at least 1 byte, or an error.

              Params
              Return values
              -

              [method]output-stream.write: func

              +

              [method]output-stream.write: func

              Perform a write. This function never blocks.

              When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -331,14 +331,14 @@ length of less than or equal to n. Otherwise, this function will trap.

              the last call to check-write provided a permit.

              Params
              Return values
              -

              [method]output-stream.blocking-write-and-flush: func

              +

              [method]output-stream.blocking-write-and-flush: func

              Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

              This is a convenience wrapper around the use of check-write, @@ -362,14 +362,14 @@ let _ = this.check-write(); // eliding error handling

              Params
              Return values
              -

              [method]output-stream.flush: func

              +

              [method]output-stream.flush: func

              Request to flush buffered output. This function never blocks.

              This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -380,24 +380,24 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

              Params
              Return values
              -

              [method]output-stream.blocking-flush: func

              +

              [method]output-stream.blocking-flush: func

              Request to flush buffered output, and block until flush completes and stream is ready for writing again.

              Params
              Return values
              -

              [method]output-stream.subscribe: func

              +

              [method]output-stream.subscribe: func

              Create a pollable which will resolve once the output-stream is ready for more writing, or an error has occurred. When this pollable is ready, check-write will return ok(n) with n>0, or an @@ -408,13 +408,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

              Params
              Return values
              -

              [method]output-stream.write-zeroes: func

              +

              [method]output-stream.write-zeroes: func

              Write zeroes to a stream.

              This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -422,14 +422,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

              Params
              Return values
              -

              [method]output-stream.blocking-write-zeroes-and-flush: func

              +

              [method]output-stream.blocking-write-zeroes-and-flush: func

              Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

              @@ -453,14 +453,14 @@ let _ = this.check-write(); // eliding error handling
              Params
              Return values
              -

              [method]output-stream.splice: func

              +

              [method]output-stream.splice: func

              Read from one stream and write to another.

              The behavior of splice is equivalent to:

                @@ -475,175 +475,184 @@ let _ = this.check-write(); // eliding error handling than len.

                Params
                Return values
                -

                [method]output-stream.blocking-splice: func

                +

                [method]output-stream.blocking-splice: func

                Read from one stream and write to another, with blocking.

                This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

                Params
                Return values
                -

                Import interface wasi:http/types@0.2.1

                +

                Import interface wasi:http/types@0.2.1

                This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.


                Types

                -

                type duration

                +

                type duration

                duration

                -#### `type input-stream` +#### `type input-stream` [`input-stream`](#input_stream)

                -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

                -#### `type io-error` +#### `type io-error` [`error`](#error)

                -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

                -#### `variant method` +#### `variant method`

                This type corresponds to HTTP standard Methods.

                Variant Cases
                  -
                • get
                • -
                • head
                • -
                • post
                • -
                • put
                • -
                • delete
                • -
                • connect
                • -
                • options
                • -
                • trace
                • -
                • patch
                • -
                • other: string
                • -
                -

                variant scheme

                +
              1. get
              2. +
              3. head
              4. +
              5. post
              6. +
              7. put
              8. +
              9. delete
              10. +
              11. connect
              12. +
              13. options
              14. +
              15. trace
              16. +
              17. patch
              18. +
              19. other: string
              20. + +

                variant scheme

                This type corresponds to HTTP standard Related Schemes.

                Variant Cases
                  -
                • HTTP
                • -
                • HTTPS
                • -
                • other: string
                • +
                • HTTP
                • +
                • HTTPS
                • +
                • other: string
                -

                record DNS-error-payload

                +

                record DNS-error-payload

                Defines the case payload type for DNS-error above:

                Record Fields
                  -
                • rcode: option<string>
                • -
                • info-code: option<u16>
                • +
                • rcode: option<string>
                • +
                • info-code: option<u16>
                -

                record TLS-alert-received-payload

                +

                record TLS-alert-received-payload

                Defines the case payload type for TLS-alert-received above:

                Record Fields
                  -
                • alert-id: option<u8>
                • -
                • alert-message: option<string>
                • +
                • alert-id: option<u8>
                • +
                • alert-message: option<string>
                -

                record field-size-payload

                +

                record field-size-payload

                Defines the case payload type for HTTP-response-{header,trailer}-size above:

                Record Fields
                  -
                • field-name: option<string>
                • -
                • field-size: option<u32>
                • +
                • field-name: option<string>
                • +
                • field-size: option<u32>
                -

                variant error-code

                +

                variant error-code

                These cases are inspired by the IANA HTTP Proxy Error Types: https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types

                Variant Cases
                  -
                • DNS-timeout
                • -
                • DNS-error: DNS-error-payload
                • -
                • destination-not-found
                • -
                • destination-unavailable
                • -
                • destination-IP-prohibited
                • -
                • destination-IP-unroutable
                • -
                • connection-refused
                • -
                • connection-terminated
                • -
                • connection-timeout
                • -
                • connection-read-timeout
                • -
                • connection-write-timeout
                • -
                • connection-limit-reached
                • -
                • TLS-protocol-error
                • -
                • TLS-certificate-error
                • -
                • TLS-alert-received: TLS-alert-received-payload
                • -
                • HTTP-request-denied
                • -
                • HTTP-request-length-required
                • -
                • HTTP-request-body-size: option<u64>
                • -
                • HTTP-request-method-invalid
                • -
                • HTTP-request-URI-invalid
                • -
                • HTTP-request-URI-too-long
                • -
                • HTTP-request-header-section-size: option<u32>
                • -
                • HTTP-request-header-size: option<field-size-payload>
                • -
                • HTTP-request-trailer-section-size: option<u32>
                • -
                • HTTP-request-trailer-size: field-size-payload
                • -
                • HTTP-response-incomplete
                • -
                • HTTP-response-header-section-size: option<u32>
                • -
                • HTTP-response-header-size: field-size-payload
                • -
                • HTTP-response-body-size: option<u64>
                • -
                • HTTP-response-trailer-section-size: option<u32>
                • -
                • HTTP-response-trailer-size: field-size-payload
                • -
                • HTTP-response-transfer-coding: option<string>
                • -
                • HTTP-response-content-coding: option<string>
                • -
                • HTTP-response-timeout
                • -
                • HTTP-upgrade-failed
                • -
                • HTTP-protocol-error
                • -
                • loop-detected
                • -
                • configuration-error
                • -
                • internal-error: option<string>

                  This is a catch-all error for anything that doesn't fit cleanly into a +

                • DNS-timeout
                • +
                • DNS-error: DNS-error-payload
                • +
                • destination-not-found
                • +
                • destination-unavailable
                • +
                • destination-IP-prohibited
                • +
                • destination-IP-unroutable
                • +
                • connection-refused
                • +
                • connection-terminated
                • +
                • connection-timeout
                • +
                • connection-read-timeout
                • +
                • connection-write-timeout
                • +
                • connection-limit-reached
                • +
                • TLS-protocol-error
                • +
                • TLS-certificate-error
                • +
                • TLS-alert-received: TLS-alert-received-payload
                • +
                • HTTP-request-denied
                • +
                • HTTP-request-length-required
                • +
                • HTTP-request-body-size: option<u64>
                • +
                • HTTP-request-method-invalid
                • +
                • HTTP-request-URI-invalid
                • +
                • HTTP-request-URI-too-long
                • +
                • HTTP-request-header-section-size: option<u32>
                • +
                • HTTP-request-header-size: option<field-size-payload>
                • +
                • HTTP-request-trailer-section-size: option<u32>
                • +
                • HTTP-request-trailer-size: field-size-payload
                • +
                • HTTP-response-incomplete
                • +
                • HTTP-response-header-section-size: option<u32>
                • +
                • HTTP-response-header-size: field-size-payload
                • +
                • HTTP-response-body-size: option<u64>
                • +
                • HTTP-response-trailer-section-size: option<u32>
                • +
                • HTTP-response-trailer-size: field-size-payload
                • +
                • HTTP-response-transfer-coding: option<string>
                • +
                • HTTP-response-content-coding: option<string>
                • +
                • HTTP-response-timeout
                • +
                • HTTP-upgrade-failed
                • +
                • HTTP-protocol-error
                • +
                • loop-detected
                • +
                • configuration-error
                • +
                • internal-error: option<string>

                  This is a catch-all error for anything that doesn't fit cleanly into a more specific case. It also includes an optional string for an unstructured description of the error. Users should not depend on the string for diagnosing errors, as it's not required to be consistent between implementations.

                -

                variant header-error

                +

                variant header-error

                This type enumerates the different kinds of errors that may occur when setting or appending to a fields resource.

                Variant Cases
                • -

                  invalid-syntax

                  -

                  This error indicates that a `field-key` or `field-value` was +

                  invalid-syntax

                  +

                  This error indicates that a `field-name` or `field-value` was syntactically invalid when used with an operation that sets headers in a `fields`.

                • -

                  forbidden

                  -

                  This error indicates that a forbidden `field-key` was used when trying +

                  forbidden

                  +

                  This error indicates that a forbidden `field-name` was used when trying to set a header in a `fields`.

                • -

                  immutable

                  +

                  immutable

                  This error indicates that the operation on the `fields` was not permitted because the fields are immutable.

                -

                type field-key

                +

                type field-key

                string

                Field keys are always strings. -

                type field-value

                +

                Field keys should always be treated as case insensitive by the fields +resource for the purposes of equality checking.

                +

                Deprecation

                +

                This type has been deprecated in favor of the field-name type.

                +

                type field-name

                +

                field-key

                +

                Field names are always strings. +

                Field keys should always be treated as case insensitive by the fields +resource for the purposes of equality checking.

                +

                type field-value

                field-value

                Field values should always be ASCII strings. However, in reality, HTTP implementations often have to interpret malformed values, so they are provided as a list of bytes. -

                resource fields

                +

                resource fields

                This following block defines the fields resource which corresponds to HTTP standard Fields. Fields are a common representation used for both Headers and Trailers.

                @@ -653,33 +662,33 @@ resource given by other means (including, but not limited to, incoming-request.headers, outgoing-request.headers) might be be immutable. In an immutable fields, the set, append, and delete operations will fail with header-error.immutable.

                -

                type headers

                +

                type headers

                fields

                Headers is an alias for Fields. -

                type trailers

                +

                type trailers

                fields

                Trailers is an alias for Fields. -

                resource incoming-request

                +

                resource incoming-request

                Represents an incoming HTTP Request.

                -

                resource outgoing-request

                +

                resource outgoing-request

                Represents an outgoing HTTP Request.

                -

                resource request-options

                +

                resource request-options

                Parameters for making an HTTP Request. Each of these parameters is currently an optional timeout applicable to the transport layer of the HTTP protocol.

                These timeouts are separate from any the user may use to bound a blocking call to wasi:io/poll.poll.

                -

                resource response-outparam

                +

                resource response-outparam

                Represents the ability to send an HTTP Response.

                This resource is used by the wasi:http/incoming-handler interface to allow a Response to be sent corresponding to the Request provided as the other argument to incoming-handler.handle.

                -

                type status-code

                +

                type status-code

                u16

                This type corresponds to the HTTP standard Status Code. -

                resource incoming-response

                +

                resource incoming-response

                Represents an incoming HTTP Response.

                -

                resource incoming-body

                +

                resource incoming-body

                Represents an incoming HTTP Request or Response's Body.

                A body has both its contents - a stream of bytes - and a (possibly empty) set of trailers, indicating that the full contents of the @@ -687,14 +696,14 @@ body have been received. This resource represents the contents as an input-stream and the delivery of trailers as a future-trailers, and ensures that the user of this interface may only be consuming either the body contents or waiting on trailers at any given time.

                -

                resource future-trailers

                +

                resource future-trailers

                Represents a future which may eventually return trailers, or an error.

                In the case that the incoming HTTP Request or Response did not have any trailers, this future will resolve to the empty set of trailers once the complete Request or Response body has been received.

                -

                resource outgoing-response

                +

                resource outgoing-response

                Represents an outgoing HTTP Response.

                -

                resource outgoing-body

                +

                resource outgoing-body

                Represents an outgoing HTTP Request or Response's Body.

                A body has both its contents - a stream of bytes - and a (possibly empty) set of trailers, inducating the full contents of the body @@ -709,13 +718,13 @@ and that an error has occurred. The implementation should propagate this error to the HTTP protocol by whatever means it has available, including: corrupting the body on the wire, aborting the associated Request, or sending a late status code for the Response.

                -

                resource future-incoming-response

                +

                resource future-incoming-response

                Represents a future which may eventually return an incoming HTTP Response, or an error.

                This resource is returned by the wasi:http/outgoing-handler interface to provide the HTTP Response corresponding to the sent Request.

                Functions

                -

                http-error-code: func

                +

                http-error-code: func

                Attempts to extract a http-related error from the wasi:io error provided.

                Stream operations which return @@ -727,20 +736,20 @@ if there's http-related information about the error to return.

                http-related errors.

                Params
                Return values
                -

                [constructor]fields: func

                +

                [constructor]fields: func

                Construct an empty HTTP Fields.

                The resulting fields is mutable.

                Return values
                -

                [static]fields.from-list: func

                +

                [static]fields.from-list: func

                Construct an HTTP Fields.

                The resulting fields is mutable.

                The list represents each key-value pair in the Fields. Keys @@ -748,156 +757,158 @@ which have multiple values are represented by multiple entries in this list with the same key.

                The tuple is a pair of the field key, represented as a string, and Value, represented as a list of bytes.

                -

                An error result will be returned if any field-key or field-value is +

                An error result will be returned if any field-name or field-value is syntactically invalid, or if a field is forbidden.

                Params
                Return values
                -

                [method]fields.get: func

                +

                [method]fields.get: func

                Get all of the values corresponding to a key. If the key is not present in this fields or is syntactically invalid, an empty list is returned. However, if the key is present but empty, this is represented by a list with one or more empty field-values present.

                Params
                Return values
                -

                [method]fields.has: func

                +

                [method]fields.has: func

                Returns true when the key is present in this fields. If the key is syntactically invalid, false is returned.

                Params
                Return values
                  -
                • bool
                • +
                • bool
                -

                [method]fields.set: func

                +

                [method]fields.set: func

                Set all of the values for a key. Clears any existing values for that key, if they have been set.

                Fails with header-error.immutable if the fields are immutable.

                -

                Fails with header-error.invalid-syntax if the field-key or any of +

                Fails with header-error.invalid-syntax if the field-name or any of the field-values are syntactically invalid.

                Params
                Return values
                -

                [method]fields.delete: func

                +

                [method]fields.delete: func

                Delete all values for a key. Does nothing if no values for the key exist.

                Fails with header-error.immutable if the fields are immutable.

                -

                Fails with header-error.invalid-syntax if the field-key is +

                Fails with header-error.invalid-syntax if the field-name is syntactically invalid.

                Params
                Return values
                -

                [method]fields.append: func

                +

                [method]fields.append: func

                Append a value for a key. Does not change or delete any existing values for that key.

                Fails with header-error.immutable if the fields are immutable.

                -

                Fails with header-error.invalid-syntax if the field-key or +

                Fails with header-error.invalid-syntax if the field-name or field-value are syntactically invalid.

                Params
                Return values
                -

                [method]fields.entries: func

                +

                [method]fields.entries: func

                Retrieve the full set of keys and values in the Fields. Like the constructor, the list represents each key-value pair.

                The outer list represents each key-value pair in the Fields. Keys which have multiple values are represented by multiple entries in this list with the same key.

                +

                The keys and values are always returned in the original casing and in +the order in which they will be serialized for transport.

                Params
                Return values
                -

                [method]fields.clone: func

                +

                [method]fields.clone: func

                Make a deep copy of the Fields. Equivalent in behavior to calling the fields constructor on the return value of entries. The resulting fields is mutable.

                Params
                Return values
                -

                [method]incoming-request.method: func

                +

                [method]incoming-request.method: func

                Returns the method of the incoming request.

                Params
                Return values
                -

                [method]incoming-request.path-with-query: func

                +

                [method]incoming-request.path-with-query: func

                Returns the path with query parameters from the request, as a string.

                Params
                Return values
                  -
                • option<string>
                • +
                • option<string>
                -

                [method]incoming-request.scheme: func

                +

                [method]incoming-request.scheme: func

                Returns the protocol scheme from the request.

                Params
                Return values
                -

                [method]incoming-request.authority: func

                +

                [method]incoming-request.authority: func

                Returns the authority of the Request's target URI, if present.

                Params
                Return values
                  -
                • option<string>
                • +
                • option<string>
                -

                [method]incoming-request.headers: func

                +

                [method]incoming-request.headers: func

                Get the headers associated with the request.

                The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

                @@ -906,24 +917,24 @@ the parent incoming-request is drop incoming-request before all children are dropped will trap.

                Params
                Return values
                -

                [method]incoming-request.consume: func

                +

                [method]incoming-request.consume: func

                Gives the incoming-body associated with this request. Will only return success at most once, and subsequent calls will return error.

                Params
                Return values
                -

                [constructor]outgoing-request: func

                +

                [constructor]outgoing-request: func

                Construct a new outgoing-request with a default method of GET, and none values for path-with-query, scheme, and authority.

                  @@ -936,13 +947,13 @@ It is the obligation of the outgoing-handler.handle implementation to reject invalid constructions of outgoing-request.

                  Params
                  Return values
                  -

                  [method]outgoing-request.body: func

                  +

                  [method]outgoing-request.body: func

                  Returns the resource corresponding to the outgoing Body for this Request.

                  Returns success on the first call: the outgoing-body resource for @@ -950,109 +961,109 @@ this outgoing-request can be retrie calls will return error.

                  Params
                  Return values
                  -

                  [method]outgoing-request.method: func

                  +

                  [method]outgoing-request.method: func

                  Get the Method for the Request.

                  Params
                  Return values
                  -

                  [method]outgoing-request.set-method: func

                  +

                  [method]outgoing-request.set-method: func

                  Set the Method for the Request. Fails if the string present in a method.other argument is not a syntactically valid method.

                  Params
                  Return values
                    -
                  • result
                  • +
                  • result
                  -

                  [method]outgoing-request.path-with-query: func

                  +

                  [method]outgoing-request.path-with-query: func

                  Get the combination of the HTTP Path and Query for the Request. When none, this represents an empty Path and empty Query.

                  Params
                  Return values
                    -
                  • option<string>
                  • +
                  • option<string>
                  -

                  [method]outgoing-request.set-path-with-query: func

                  +

                  [method]outgoing-request.set-path-with-query: func

                  Set the combination of the HTTP Path and Query for the Request. When none, this represents an empty Path and empty Query. Fails is the string given is not a syntactically valid path and query uri component.

                  Params
                  Return values
                    -
                  • result
                  • +
                  • result
                  -

                  [method]outgoing-request.scheme: func

                  +

                  [method]outgoing-request.scheme: func

                  Get the HTTP Related Scheme for the Request. When none, the implementation may choose an appropriate default scheme.

                  Params
                  Return values
                  -

                  [method]outgoing-request.set-scheme: func

                  +

                  [method]outgoing-request.set-scheme: func

                  Set the HTTP Related Scheme for the Request. When none, the implementation may choose an appropriate default scheme. Fails if the string given is not a syntactically valid uri scheme.

                  Params
                  Return values
                    -
                  • result
                  • +
                  • result
                  -

                  [method]outgoing-request.authority: func

                  +

                  [method]outgoing-request.authority: func

                  Get the authority of the Request's target URI. A value of none may be used with Related Schemes which do not require an authority. The HTTP and HTTPS schemes always require an authority.

                  Params
                  Return values
                    -
                  • option<string>
                  • +
                  • option<string>
                  -

                  [method]outgoing-request.set-authority: func

                  +

                  [method]outgoing-request.set-authority: func

                  Set the authority of the Request's target URI. A value of none may be used with Related Schemes which do not require an authority. The HTTP and HTTPS schemes always require an authority. Fails if the string given is not a syntactically valid URI authority.

                  Params
                  Return values
                    -
                  • result
                  • +
                  • result
                  -

                  [method]outgoing-request.headers: func

                  +

                  [method]outgoing-request.headers: func

                  Get the headers associated with the Request.

                  The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

                  @@ -1061,87 +1072,87 @@ not a syntactically valid URI authority.

                  another component by e.g. outgoing-handler.handle.

                  Params
                  Return values
                  -

                  [constructor]request-options: func

                  +

                  [constructor]request-options: func

                  Construct a default request-options value.

                  Return values
                  -

                  [method]request-options.connect-timeout: func

                  +

                  [method]request-options.connect-timeout: func

                  The timeout for the initial connect to the HTTP Server.

                  Params
                  Return values
                  -

                  [method]request-options.set-connect-timeout: func

                  +

                  [method]request-options.set-connect-timeout: func

                  Set the timeout for the initial connect to the HTTP Server. An error return value indicates that this timeout is not supported.

                  Params
                  Return values
                    -
                  • result
                  • +
                  • result
                  -

                  [method]request-options.first-byte-timeout: func

                  +

                  [method]request-options.first-byte-timeout: func

                  The timeout for receiving the first byte of the Response body.

                  Params
                  Return values
                  -

                  [method]request-options.set-first-byte-timeout: func

                  +

                  [method]request-options.set-first-byte-timeout: func

                  Set the timeout for receiving the first byte of the Response body. An error return value indicates that this timeout is not supported.

                  Params
                  Return values
                    -
                  • result
                  • +
                  • result
                  -

                  [method]request-options.between-bytes-timeout: func

                  +

                  [method]request-options.between-bytes-timeout: func

                  The timeout for receiving subsequent chunks of bytes in the Response body stream.

                  Params
                  Return values
                  -

                  [method]request-options.set-between-bytes-timeout: func

                  +

                  [method]request-options.set-between-bytes-timeout: func

                  Set the timeout for receiving subsequent chunks of bytes in the Response body stream. An error return value indicates that this timeout is not supported.

                  Params
                  Return values
                    -
                  • result
                  • +
                  • result
                  -

                  [static]response-outparam.set: func

                  +

                  [static]response-outparam.set: func

                  Set the value of the response-outparam to either send a response, or indicate an error.

                  This method consumes the response-outparam to ensure that it is @@ -1151,20 +1162,20 @@ will respond with an error.

                  implementation determine how to respond with an HTTP error response.

                  Params
                  -

                  [method]incoming-response.status: func

                  +

                  [method]incoming-response.status: func

                  Returns the status code from the incoming response.

                  Params
                  Return values
                  -

                  [method]incoming-response.headers: func

                  +

                  [method]incoming-response.headers: func

                  Returns the headers from the incoming response.

                  The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

                  @@ -1172,24 +1183,24 @@ implementation determine how to respond with an HTTP error response.

                  incoming-response is dropped.

                  Params
                  Return values
                  -

                  [method]incoming-response.consume: func

                  +

                  [method]incoming-response.consume: func

                  Returns the incoming body. May be called at most once. Returns error if called additional times.

                  Params
                  Return values
                  -

                  [method]incoming-body.stream: func

                  +

                  [method]incoming-body.stream: func

                  Returns the contents of the body, as a stream of bytes.

                  Returns success on first call: the stream representing the contents can be retrieved at most once. Subsequent calls will return error.

                  @@ -1204,36 +1215,36 @@ and for that backpressure to not inhibit delivery of the trailers if the user does not read the entire body.

                  Params
                  Return values
                  -

                  [static]incoming-body.finish: func

                  +

                  [static]incoming-body.finish: func

                  Takes ownership of incoming-body, and returns a future-trailers. This function will trap if the input-stream child is still alive.

                  Params
                  Return values
                  -

                  [method]future-trailers.subscribe: func

                  +

                  [method]future-trailers.subscribe: func

                  Returns a pollable which becomes ready when either the trailers have been received, or an error has occurred. When this pollable is ready, the get method will return some.

                  Params
                  Return values
                  -

                  [method]future-trailers.get: func

                  +

                  [method]future-trailers.get: func

                  Returns the contents of the trailers, or an error which occurred, once the future is ready.

                  The outer option represents future readiness. Users can wait on this @@ -1251,13 +1262,13 @@ resource is immutable, and a child. Use of the set, appendfuture-trailers is dropped.

                  Params
                  Return values
                  -

                  [constructor]outgoing-response: func

                  +

                  [constructor]outgoing-response: func

                  Construct an outgoing-response, with a default status-code of 200. If a different status-code is needed, it must be set via the set-status-code method.

                  @@ -1266,35 +1277,35 @@ If a different status-code is needed, it
                Params
                Return values
                -

                [method]outgoing-response.status-code: func

                +

                [method]outgoing-response.status-code: func

                Get the HTTP Status Code for the Response.

                Params
                Return values
                -

                [method]outgoing-response.set-status-code: func

                +

                [method]outgoing-response.set-status-code: func

                Set the HTTP Status Code for the Response. Fails if the status-code given is not a valid http status code.

                Params
                Return values
                  -
                • result
                • +
                • result
                -

                [method]outgoing-response.headers: func

                +

                [method]outgoing-response.headers: func

                Get the headers associated with the Request.

                The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

                @@ -1303,26 +1314,26 @@ given is not a valid http status code.

                another component by e.g. outgoing-handler.handle.

                Params
                Return values
                -

                [method]outgoing-response.body: func

                +

                [method]outgoing-response.body: func

                Returns the resource corresponding to the outgoing Body for this Response.

                Returns success on the first call: the outgoing-body resource for this outgoing-response can be retrieved at most once. Subsequent calls will return error.

                Params
                Return values
                -

                [method]outgoing-body.write: func

                +

                [method]outgoing-body.write: func

                Returns a stream for writing the body contents.

                The returned output-stream is a child resource: it must be dropped before the parent outgoing-body resource is dropped (or finished), @@ -1332,13 +1343,13 @@ this outgoing-body may be retrieved at will return error.

                Params
                Return values
                -

                [static]outgoing-body.finish: func

                +

                [static]outgoing-body.finish: func

                Finalize an outgoing body, optionally providing trailers. This must be called to signal that the response is complete. If the outgoing-body is dropped without calling outgoing-body.finalize, the implementation @@ -1349,26 +1360,26 @@ to the body (via write) does not match the value given in the Content-Length.

                Params
                Return values
                -

                [method]future-incoming-response.subscribe: func

                +

                [method]future-incoming-response.subscribe: func

                Returns a pollable which becomes ready when either the Response has been received, or an error has occurred. When this pollable is ready, the get method will return some.

                Params
                Return values
                -

                [method]future-incoming-response.get: func

                +

                [method]future-incoming-response.get: func

                Returns the incoming HTTP Response, or an error, once one is ready.

                The outer option represents future readiness. Users can wait on this option to become some using the subscribe method.

                @@ -1382,13 +1393,13 @@ but those will be reported by the incoming-bodyoutput-stream child.

                Params
                Return values
                -

                Import interface wasi:clocks/wall-clock@0.2.1

                +

                Import interface wasi:clocks/wall-clock@0.2.1

                WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                @@ -1401,16 +1412,16 @@ monotonic, making it unsuitable for measuring elapsed time.

                It is intended for reporting the current date and time for humans.


                Types

                -

                record datetime

                +

                record datetime

                A time and date in seconds plus nanoseconds.

                Record Fields
                  -
                • seconds: u64
                • -
                • nanoseconds: u32
                • +
                • seconds: u64
                • +
                • nanoseconds: u32

                Functions

                -

                now: func

                +

                now: func

                Read the current value of the clock.

                This clock is not monotonic, therefore calling this function repeatedly will not necessarily produce a sequence of non-decreasing values.

                @@ -1420,22 +1431,22 @@ also known as Unix Time.The nanoseconds field of the output is always less than 1000000000.

                Return values
                -

                resolution: func

                +

                resolution: func

                Query the resolution of the clock.

                The nanoseconds field of the output is always less than 1000000000.

                Return values
                -

                Import interface wasi:random/random@0.2.1

                +

                Import interface wasi:random/random@0.2.1

                WASI Random is a random data API.

                It is intended to be portable at least between Unix-family platforms and Windows.


                Functions

                -

                get-random-bytes: func

                +

                get-random-bytes: func

                Return len cryptographically-secure random or pseudo-random bytes.

                This function must produce data at least as cryptographically secure and fast as an adequately seeded cryptographically-secure pseudo-random @@ -1448,79 +1459,79 @@ must omit this function, rather than implementing it with deterministic data.

                Params
                  -
                • len: u64
                • +
                • len: u64
                Return values
                  -
                • list<u8>
                • +
                • list<u8>
                -

                get-random-u64: func

                +

                get-random-u64: func

                Return a cryptographically-secure random or pseudo-random u64 value.

                This function returns the same type of data as get-random-bytes, represented as a u64.

                Return values
                  -
                • u64
                • +
                • u64
                -

                Import interface wasi:cli/stdout@0.2.1

                +

                Import interface wasi:cli/stdout@0.2.1


                Types

                -

                type output-stream

                +

                type output-stream

                output-stream

                ----

                Functions

                -

                get-stdout: func

                +

                get-stdout: func

                Return values
                -

                Import interface wasi:cli/stderr@0.2.1

                +

                Import interface wasi:cli/stderr@0.2.1


                Types

                -

                type output-stream

                +

                type output-stream

                output-stream

                ----

                Functions

                -

                get-stderr: func

                +

                get-stderr: func

                Return values
                -

                Import interface wasi:cli/stdin@0.2.1

                +

                Import interface wasi:cli/stdin@0.2.1


                Types

                -

                type input-stream

                +

                type input-stream

                input-stream

                ----

                Functions

                -

                get-stdin: func

                +

                get-stdin: func

                Return values
                -

                Import interface wasi:http/outgoing-handler@0.2.1

                +

                Import interface wasi:http/outgoing-handler@0.2.1

                This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                Types

                -

                type outgoing-request

                +

                type outgoing-request

                outgoing-request

                -#### `type request-options` +#### `type request-options` [`request-options`](#request_options)

                -#### `type future-incoming-response` +#### `type future-incoming-response` [`future-incoming-response`](#future_incoming_response)

                -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                ----

                Functions

                -

                handle: func

                +

                handle: func

                This function is invoked with an outgoing HTTP Request, and it returns a resource future-incoming-response which represents an HTTP Response which may arrive in the future.

                @@ -1531,25 +1542,25 @@ or not allowed to be made. Otherwise, protocol errors are reported through the future-incoming-response.

                Params
                Return values
                -

                Export interface wasi:http/incoming-handler@0.2.1

                +

                Export interface wasi:http/incoming-handler@0.2.1


                Types

                -

                type incoming-request

                +

                type incoming-request

                incoming-request

                -#### `type response-outparam` +#### `type response-outparam` [`response-outparam`](#response_outparam)

                ----

                Functions

                -

                handle: func

                +

                handle: func

                This function is invoked with an incoming HTTP Request, and a resource response-outparam which provides the capability to reply with an HTTP Response. The response is sent by calling the response-outparam.set @@ -1561,6 +1572,6 @@ work.

                with an error on its behalf.

                Params
                diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index da636bcb4..e562d8d25 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -107,12 +107,12 @@ interface types { /// This type enumerates the different kinds of errors that may occur when /// setting or appending to a `fields` resource. variant header-error { - /// This error indicates that a `field-key` or `field-value` was + /// This error indicates that a `field-name` or `field-value` was /// syntactically invalid when used with an operation that sets headers in a /// `fields`. invalid-syntax, - /// This error indicates that a forbidden `field-key` was used when trying + /// This error indicates that a forbidden `field-name` was used when trying /// to set a header in a `fields`. forbidden, @@ -132,11 +132,11 @@ interface types { immutable, } - /// Field keys are always strings. + /// Field names are always strings. /// /// Field keys should always be treated as case insensitive by the `fields` /// resource for the purposes of equality checking. - type field-key = string; + type field-name = string; /// Field values should always be ASCII strings. However, in /// reality, HTTP implementations often have to interpret malformed values, @@ -154,8 +154,7 @@ interface types { /// `set`, `append`, and `delete` operations will fail with /// `header-error.immutable`. /// - /// A `fields` resource should store `field-key`s and `field-value`s in their - /// original casing used to construct or mutate the `fields` resource. The `fields` + /// A `fields` resource should store `field-name`s and `field-value`s in their /// original casing used to construct or mutate the `fields` resource. The `fields` /// resource should use that original casing when serializing the fields for /// transport or when returning them from a method. resource fields { @@ -181,30 +180,30 @@ interface types { /// An error result will be returned if any header or value was /// syntactically invalid, or if a header was forbidden. from-list: static func( - entries: list> + entries: list> ) -> result; /// Get all of the values corresponding to a key. If the key is not present /// in this `fields`, an empty list is returned. However, if the key is /// present but empty, this is represented by a list with one or more /// empty field-values present. - get: func(name: field-key) -> list; + get: func(name: field-name) -> list; /// Returns `true` when the key is present in this `fields`. If the key is /// syntactically invalid, `false` is returned. - has: func(name: field-key) -> bool; + has: func(name: field-name) -> bool; /// Set all of the values for a key. Clears any existing values for that /// key, if they have been set. /// /// Fails with `header-error.immutable` if the `fields` are immutable. - set: func(name: field-key, value: list) -> result<_, header-error>; + set: func(name: field-name, value: list) -> result<_, header-error>; /// Delete all values for a key. Does nothing if no values for the key /// exist. /// /// Fails with `header-error.immutable` if the `fields` are immutable. - delete: func(name: field-key) -> result<_, header-error>; + delete: func(name: field-name) -> result<_, header-error>; /// Delete all values for a key. Does nothing if no values for the key /// exist. @@ -212,13 +211,13 @@ interface types { /// Returns all values previously corresponding to the key, if any. /// /// Fails with `header-error.immutable` if the `fields` are immutable. - get-and-delete: func(name: field-key) -> result, header-error>; + get-and-delete: func(name: field-name) -> result, header-error>; /// Append a value for a key. Does not change or delete any existing /// values for that key. /// /// Fails with `header-error.immutable` if the `fields` are immutable. - append: func(name: field-key, value: field-value) -> result<_, header-error>; + append: func(name: field-name, value: field-value) -> result<_, header-error>; /// Retrieve the full set of keys and values in the Fields. Like the /// constructor, the list represents each key-value pair. @@ -229,7 +228,7 @@ interface types { /// /// The keys and values are always returned in the original casing and in /// the order in which they will be serialized for transport. - entries: func() -> list>; + entries: func() -> list>; /// Make a deep copy of the Fields. Equivalent in behavior to calling the /// `fields` constructor on the return value of `entries`. The resulting diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 71482776b..5836a9ca2 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -124,12 +124,12 @@ interface types { /// setting or appending to a `fields` resource. @since(version = 0.2.0) variant header-error { - /// This error indicates that a `field-key` or `field-value` was + /// This error indicates that a `field-name` or `field-value` was /// syntactically invalid when used with an operation that sets headers in a /// `fields`. invalid-syntax, - /// This error indicates that a forbidden `field-key` was used when trying + /// This error indicates that a forbidden `field-name` was used when trying /// to set a header in a `fields`. forbidden, @@ -138,11 +138,23 @@ interface types { immutable, } + /// Field names are always strings. + /// + /// Field keys should always be treated as case insensitive by the `fields` + /// resource for the purposes of equality checking. + @since(version = 0.2.1) + type field-name = field-key; + /// Field keys are always strings. /// /// Field keys should always be treated as case insensitive by the `fields` /// resource for the purposes of equality checking. + /// + /// # Deprecation + /// + /// This type has been deprecated in favor of the `field-name` type. @since(version = 0.2.0) + @deprecated(version = 0.2.1) type field-key = string; /// Field values should always be ASCII strings. However, in @@ -181,11 +193,11 @@ interface types { /// The tuple is a pair of the field key, represented as a string, and /// Value, represented as a list of bytes. /// - /// An error result will be returned if any `field-key` or `field-value` is + /// An error result will be returned if any `field-name` or `field-value` is /// syntactically invalid, or if a field is forbidden. @since(version = 0.2.0) from-list: static func( - entries: list> + entries: list> ) -> result; /// Get all of the values corresponding to a key. If the key is not present @@ -193,42 +205,42 @@ interface types { /// However, if the key is present but empty, this is represented by a list /// with one or more empty field-values present. @since(version = 0.2.0) - get: func(name: field-key) -> list; + get: func(name: field-name) -> list; /// Returns `true` when the key is present in this `fields`. If the key is /// syntactically invalid, `false` is returned. @since(version = 0.2.0) - has: func(name: field-key) -> bool; + has: func(name: field-name) -> bool; /// Set all of the values for a key. Clears any existing values for that /// key, if they have been set. /// /// Fails with `header-error.immutable` if the `fields` are immutable. /// - /// Fails with `header-error.invalid-syntax` if the `field-key` or any of + /// Fails with `header-error.invalid-syntax` if the `field-name` or any of /// the `field-value`s are syntactically invalid. @since(version = 0.2.0) - set: func(name: field-key, value: list) -> result<_, header-error>; + set: func(name: field-name, value: list) -> result<_, header-error>; /// Delete all values for a key. Does nothing if no values for the key /// exist. /// /// Fails with `header-error.immutable` if the `fields` are immutable. /// - /// Fails with `header-error.invalid-syntax` if the `field-key` is + /// Fails with `header-error.invalid-syntax` if the `field-name` is /// syntactically invalid. @since(version = 0.2.0) - delete: func(name: field-key) -> result<_, header-error>; + delete: func(name: field-name) -> result<_, header-error>; /// Append a value for a key. Does not change or delete any existing /// values for that key. /// /// Fails with `header-error.immutable` if the `fields` are immutable. /// - /// Fails with `header-error.invalid-syntax` if the `field-key` or + /// Fails with `header-error.invalid-syntax` if the `field-name` or /// `field-value` are syntactically invalid. @since(version = 0.2.0) - append: func(name: field-key, value: field-value) -> result<_, header-error>; + append: func(name: field-name, value: field-value) -> result<_, header-error>; /// Retrieve the full set of keys and values in the Fields. Like the /// constructor, the list represents each key-value pair. @@ -236,8 +248,11 @@ interface types { /// The outer list represents each key-value pair in the Fields. Keys /// which have multiple values are represented by multiple entries in this /// list with the same key. + /// + /// The keys and values are always returned in the original casing and in + /// the order in which they will be serialized for transport. @since(version = 0.2.0) - entries: func() -> list>; + entries: func() -> list>; /// Make a deep copy of the Fields. Equivalent in behavior to calling the /// `fields` constructor on the return value of `entries`. The resulting From e6f8fe685202fc54bbfc9d8bb5ccabbaa2c14072 Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 14 Aug 2024 15:04:06 +0200 Subject: [PATCH 1497/1772] update to wit-bindgen@0.30.0 --- proposals/http/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index 2d34992f6..b8f6fd92b 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -18,5 +18,5 @@ jobs: ./wit-deps lock --check - uses: WebAssembly/wit-abi-up-to-date@v21 with: - wit-bindgen: '0.28.0' + wit-bindgen: '0.30.0' worlds: 'imports proxy' From 7f5c8e8564a0ec489e109922e0f96c4dba5a2915 Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 14 Aug 2024 15:06:47 +0200 Subject: [PATCH 1498/1772] generate `import` docs --- proposals/http/imports.md | 799 +++++++++++++++++++------------------- 1 file changed, 405 insertions(+), 394 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index c4abffb43..22d946e78 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -1,4 +1,4 @@ -

                World imports

                +

                World imports

                The wasi:http/imports world imports all the APIs for HTTP proxies. It is intended to be included in other worlds.

                  @@ -18,35 +18,35 @@ It is intended to be included in other worlds.

                -

                Import interface wasi:io/poll@0.2.1

                +

                Import interface wasi:io/poll@0.2.1

                A poll API intended to let users wait for I/O events on multiple handles at once.


                Types

                -

                resource pollable

                +

                resource pollable

                pollable represents a single I/O event which may be ready, or not.

                Functions

                -

                [method]pollable.ready: func

                +

                [method]pollable.ready: func

                Return the readiness of a pollable. This function never blocks.

                Returns true when the pollable is ready, and false otherwise.

                Params
                Return values
                  -
                • bool
                • +
                • bool
                -

                [method]pollable.block: func

                +

                [method]pollable.block: func

                block returns immediately if the pollable is ready, and otherwise blocks until ready.

                This function is equivalent to calling poll.poll on a list containing only this pollable.

                Params
                -

                poll: func

                +

                poll: func

                Poll for completion on a set of pollables.

                This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

                @@ -65,13 +65,13 @@ the pollables has an error, it is indicated by marking the source as being ready for I/O.

                Params
                Return values
                  -
                • list<u32>
                • +
                • list<u32>
                -

                Import interface wasi:clocks/monotonic-clock@0.2.1

                +

                Import interface wasi:clocks/monotonic-clock@0.2.1

                WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                It is intended to be portable at least between Unix-family platforms and @@ -80,57 +80,57 @@ Windows.

                successive reads of the clock will produce non-decreasing values.


                Types

                -

                type pollable

                +

                type pollable

                pollable

                -#### `type instant` +#### `type instant` `u64`

                An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. -

                type duration

                +

                type duration

                u64

                A duration of time, in nanoseconds.


                Functions

                -

                now: func

                +

                now: func

                Read the current value of the clock.

                The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

                Return values
                -

                resolution: func

                +

                resolution: func

                Query the resolution of the clock. Returns the duration of time corresponding to a clock tick.

                Return values
                -

                subscribe-instant: func

                +

                subscribe-instant: func

                Create a pollable which will resolve once the specified instant has occurred.

                Params
                Return values
                -

                subscribe-duration: func

                +

                subscribe-duration: func

                Create a pollable that will resolve after the specified duration has elapsed from the time this function is invoked.

                Params
                Return values
                -

                Import interface wasi:clocks/wall-clock@0.2.1

                +

                Import interface wasi:clocks/wall-clock@0.2.1

                WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                @@ -143,16 +143,16 @@ monotonic, making it unsuitable for measuring elapsed time.

                It is intended for reporting the current date and time for humans.


                Types

                -

                record datetime

                +

                record datetime

                A time and date in seconds plus nanoseconds.

                Record Fields
                  -
                • seconds: u64
                • -
                • nanoseconds: u32
                • +
                • seconds: u64
                • +
                • nanoseconds: u32

                Functions

                -

                now: func

                +

                now: func

                Read the current value of the clock.

                This clock is not monotonic, therefore calling this function repeatedly will not necessarily produce a sequence of non-decreasing values.

                @@ -162,22 +162,22 @@ also known as Unix Time.The nanoseconds field of the output is always less than 1000000000.

                Return values
                -

                resolution: func

                +

                resolution: func

                Query the resolution of the clock.

                The nanoseconds field of the output is always less than 1000000000.

                Return values
                -

                Import interface wasi:random/random@0.2.1

                +

                Import interface wasi:random/random@0.2.1

                WASI Random is a random data API.

                It is intended to be portable at least between Unix-family platforms and Windows.


                Functions

                -

                get-random-bytes: func

                +

                get-random-bytes: func

                Return len cryptographically-secure random or pseudo-random bytes.

                This function must produce data at least as cryptographically secure and fast as an adequately seeded cryptographically-secure pseudo-random @@ -190,24 +190,24 @@ must omit this function, rather than implementing it with deterministic data.

                Params
                  -
                • len: u64
                • +
                • len: u64
                Return values
                  -
                • list<u8>
                • +
                • list<u8>
                -

                get-random-u64: func

                +

                get-random-u64: func

                Return a cryptographically-secure random or pseudo-random u64 value.

                This function returns the same type of data as get-random-bytes, represented as a u64.

                Return values
                  -
                • u64
                • +
                • u64
                -

                Import interface wasi:io/error@0.2.1

                +

                Import interface wasi:io/error@0.2.1


                Types

                -

                resource error

                +

                resource error

                A resource which represents some error information.

                The only method provided by this resource is to-debug-string, which provides some human-readable information about the error.

                @@ -222,7 +222,7 @@ parameter and returns an option<wasi:filesystem/types/error-code>The set of functions which can "downcast" an error into a more concrete type is open.

                Functions

                -

                [method]error.to-debug-string: func

                +

                [method]error.to-debug-string: func

                Returns a string that is suitable to assist humans in debugging this error.

                WARNING: The returned string should not be consumed mechanically! @@ -231,42 +231,42 @@ details. Parsing this string is a major platform-compatibility hazard.

                Params
                Return values
                  -
                • string
                • +
                • string
                -

                Import interface wasi:io/streams@0.2.1

                +

                Import interface wasi:io/streams@0.2.1

                WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


                Types

                -

                type error

                +

                type error

                error

                -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

                -#### `variant stream-error` +#### `variant stream-error`

                An error for input-stream and output-stream operations.

                Variant Cases
                • -

                  last-operation-failed: own<error>

                  +

                  last-operation-failed: own<error>

                  The last operation (a write or flush) failed before completion.

                  More information is available in the error payload.

                • -

                  closed

                  +

                  closed

                  The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

                -

                resource input-stream

                +

                resource input-stream

                An input bytestream.

                input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are @@ -274,7 +274,7 @@ promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

                -

                resource output-stream

                +

                resource output-stream

                An output bytestream.

                output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also @@ -286,7 +286,7 @@ polled for using wasi:io/poll.

                progress may result in the data being lost. Before dropping the stream, be sure to fully flush your writes.

                Functions

                -

                [method]input-stream.read: func

                +

                [method]input-stream.read: func

                Perform a non-blocking read from the stream.

                When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -310,51 +310,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

                Params
                Return values
                -

                [method]input-stream.blocking-read: func

                +

                [method]input-stream.blocking-read: func

                Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

                Params
                Return values
                -

                [method]input-stream.skip: func

                +

                [method]input-stream.skip: func

                Skip bytes from a stream. Returns number of bytes skipped.

                Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

                Params
                Return values
                -

                [method]input-stream.blocking-skip: func

                +

                [method]input-stream.blocking-skip: func

                Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

                Params
                Return values
                -

                [method]input-stream.subscribe: func

                +

                [method]input-stream.subscribe: func

                Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -363,13 +363,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

                Params
                Return values
                -

                [method]output-stream.check-write: func

                +

                [method]output-stream.check-write: func

                Check readiness for writing. This function never blocks.

                Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -379,13 +379,13 @@ become ready when this function will report at least 1 byte, or an error.

                Params
                Return values
                -

                [method]output-stream.write: func

                +

                [method]output-stream.write: func

                Perform a write. This function never blocks.

                When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -398,14 +398,14 @@ length of less than or equal to n. Otherwise, this function will trap.

                the last call to check-write provided a permit.

                Params
                Return values
                -

                [method]output-stream.blocking-write-and-flush: func

                +

                [method]output-stream.blocking-write-and-flush: func

                Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                This is a convenience wrapper around the use of check-write, @@ -429,14 +429,14 @@ let _ = this.check-write(); // eliding error handling

                Params
                Return values
                -

                [method]output-stream.flush: func

                +

                [method]output-stream.flush: func

                Request to flush buffered output. This function never blocks.

                This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -447,24 +447,24 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

                Params
                Return values
                -

                [method]output-stream.blocking-flush: func

                +

                [method]output-stream.blocking-flush: func

                Request to flush buffered output, and block until flush completes and stream is ready for writing again.

                Params
                Return values
                -

                [method]output-stream.subscribe: func

                +

                [method]output-stream.subscribe: func

                Create a pollable which will resolve once the output-stream is ready for more writing, or an error has occurred. When this pollable is ready, check-write will return ok(n) with n>0, or an @@ -475,13 +475,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

                Params
                Return values
                -

                [method]output-stream.write-zeroes: func

                +

                [method]output-stream.write-zeroes: func

                Write zeroes to a stream.

                This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -489,14 +489,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

                Params
                Return values
                -

                [method]output-stream.blocking-write-zeroes-and-flush: func

                +

                [method]output-stream.blocking-write-zeroes-and-flush: func

                Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                @@ -520,14 +520,14 @@ let _ = this.check-write(); // eliding error handling
                Params
                Return values
                -

                [method]output-stream.splice: func

                +

                [method]output-stream.splice: func

                Read from one stream and write to another.

                The behavior of splice is equivalent to:

                  @@ -542,214 +542,223 @@ let _ = this.check-write(); // eliding error handling than len.

                  Params
                  Return values
                  -

                  [method]output-stream.blocking-splice: func

                  +

                  [method]output-stream.blocking-splice: func

                  Read from one stream and write to another, with blocking.

                  This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

                  Params
                  Return values
                  -

                  Import interface wasi:cli/stdout@0.2.1

                  +

                  Import interface wasi:cli/stdout@0.2.1


                  Types

                  -

                  type output-stream

                  +

                  type output-stream

                  output-stream

                  ----

                  Functions

                  -

                  get-stdout: func

                  +

                  get-stdout: func

                  Return values
                  -

                  Import interface wasi:cli/stderr@0.2.1

                  +

                  Import interface wasi:cli/stderr@0.2.1


                  Types

                  -

                  type output-stream

                  +

                  type output-stream

                  output-stream

                  ----

                  Functions

                  -

                  get-stderr: func

                  +

                  get-stderr: func

                  Return values
                  -

                  Import interface wasi:cli/stdin@0.2.1

                  +

                  Import interface wasi:cli/stdin@0.2.1


                  Types

                  -

                  type input-stream

                  +

                  type input-stream

                  input-stream

                  ----

                  Functions

                  -

                  get-stdin: func

                  +

                  get-stdin: func

                  Return values
                  -

                  Import interface wasi:http/types@0.2.1

                  +

                  Import interface wasi:http/types@0.2.1

                  This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.


                  Types

                  -

                  type duration

                  +

                  type duration

                  duration

                  -#### `type input-stream` +#### `type input-stream` [`input-stream`](#input_stream)

                  -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

                  -#### `type io-error` +#### `type io-error` [`error`](#error)

                  -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

                  -#### `variant method` +#### `variant method`

                  This type corresponds to HTTP standard Methods.

                  Variant Cases
                    -
                  • get
                  • -
                  • head
                  • -
                  • post
                  • -
                  • put
                  • -
                  • delete
                  • -
                  • connect
                  • -
                  • options
                  • -
                  • trace
                  • -
                  • patch
                  • -
                  • other: string
                  • -
                  -

                  variant scheme

                  +
                1. get
                2. +
                3. head
                4. +
                5. post
                6. +
                7. put
                8. +
                9. delete
                10. +
                11. connect
                12. +
                13. options
                14. +
                15. trace
                16. +
                17. patch
                18. +
                19. other: string
                20. + +

                  variant scheme

                  This type corresponds to HTTP standard Related Schemes.

                  Variant Cases
                    -
                  • HTTP
                  • -
                  • HTTPS
                  • -
                  • other: string
                  • +
                  • HTTP
                  • +
                  • HTTPS
                  • +
                  • other: string
                  -

                  record DNS-error-payload

                  +

                  record DNS-error-payload

                  Defines the case payload type for DNS-error above:

                  Record Fields
                    -
                  • rcode: option<string>
                  • -
                  • info-code: option<u16>
                  • +
                  • rcode: option<string>
                  • +
                  • info-code: option<u16>
                  -

                  record TLS-alert-received-payload

                  +

                  record TLS-alert-received-payload

                  Defines the case payload type for TLS-alert-received above:

                  Record Fields
                    -
                  • alert-id: option<u8>
                  • -
                  • alert-message: option<string>
                  • +
                  • alert-id: option<u8>
                  • +
                  • alert-message: option<string>
                  -

                  record field-size-payload

                  +

                  record field-size-payload

                  Defines the case payload type for HTTP-response-{header,trailer}-size above:

                  Record Fields
                    -
                  • field-name: option<string>
                  • -
                  • field-size: option<u32>
                  • +
                  • field-name: option<string>
                  • +
                  • field-size: option<u32>
                  -

                  variant error-code

                  +

                  variant error-code

                  These cases are inspired by the IANA HTTP Proxy Error Types: https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types

                  Variant Cases
                    -
                  • DNS-timeout
                  • -
                  • DNS-error: DNS-error-payload
                  • -
                  • destination-not-found
                  • -
                  • destination-unavailable
                  • -
                  • destination-IP-prohibited
                  • -
                  • destination-IP-unroutable
                  • -
                  • connection-refused
                  • -
                  • connection-terminated
                  • -
                  • connection-timeout
                  • -
                  • connection-read-timeout
                  • -
                  • connection-write-timeout
                  • -
                  • connection-limit-reached
                  • -
                  • TLS-protocol-error
                  • -
                  • TLS-certificate-error
                  • -
                  • TLS-alert-received: TLS-alert-received-payload
                  • -
                  • HTTP-request-denied
                  • -
                  • HTTP-request-length-required
                  • -
                  • HTTP-request-body-size: option<u64>
                  • -
                  • HTTP-request-method-invalid
                  • -
                  • HTTP-request-URI-invalid
                  • -
                  • HTTP-request-URI-too-long
                  • -
                  • HTTP-request-header-section-size: option<u32>
                  • -
                  • HTTP-request-header-size: option<field-size-payload>
                  • -
                  • HTTP-request-trailer-section-size: option<u32>
                  • -
                  • HTTP-request-trailer-size: field-size-payload
                  • -
                  • HTTP-response-incomplete
                  • -
                  • HTTP-response-header-section-size: option<u32>
                  • -
                  • HTTP-response-header-size: field-size-payload
                  • -
                  • HTTP-response-body-size: option<u64>
                  • -
                  • HTTP-response-trailer-section-size: option<u32>
                  • -
                  • HTTP-response-trailer-size: field-size-payload
                  • -
                  • HTTP-response-transfer-coding: option<string>
                  • -
                  • HTTP-response-content-coding: option<string>
                  • -
                  • HTTP-response-timeout
                  • -
                  • HTTP-upgrade-failed
                  • -
                  • HTTP-protocol-error
                  • -
                  • loop-detected
                  • -
                  • configuration-error
                  • -
                  • internal-error: option<string>

                    This is a catch-all error for anything that doesn't fit cleanly into a +

                  • DNS-timeout
                  • +
                  • DNS-error: DNS-error-payload
                  • +
                  • destination-not-found
                  • +
                  • destination-unavailable
                  • +
                  • destination-IP-prohibited
                  • +
                  • destination-IP-unroutable
                  • +
                  • connection-refused
                  • +
                  • connection-terminated
                  • +
                  • connection-timeout
                  • +
                  • connection-read-timeout
                  • +
                  • connection-write-timeout
                  • +
                  • connection-limit-reached
                  • +
                  • TLS-protocol-error
                  • +
                  • TLS-certificate-error
                  • +
                  • TLS-alert-received: TLS-alert-received-payload
                  • +
                  • HTTP-request-denied
                  • +
                  • HTTP-request-length-required
                  • +
                  • HTTP-request-body-size: option<u64>
                  • +
                  • HTTP-request-method-invalid
                  • +
                  • HTTP-request-URI-invalid
                  • +
                  • HTTP-request-URI-too-long
                  • +
                  • HTTP-request-header-section-size: option<u32>
                  • +
                  • HTTP-request-header-size: option<field-size-payload>
                  • +
                  • HTTP-request-trailer-section-size: option<u32>
                  • +
                  • HTTP-request-trailer-size: field-size-payload
                  • +
                  • HTTP-response-incomplete
                  • +
                  • HTTP-response-header-section-size: option<u32>
                  • +
                  • HTTP-response-header-size: field-size-payload
                  • +
                  • HTTP-response-body-size: option<u64>
                  • +
                  • HTTP-response-trailer-section-size: option<u32>
                  • +
                  • HTTP-response-trailer-size: field-size-payload
                  • +
                  • HTTP-response-transfer-coding: option<string>
                  • +
                  • HTTP-response-content-coding: option<string>
                  • +
                  • HTTP-response-timeout
                  • +
                  • HTTP-upgrade-failed
                  • +
                  • HTTP-protocol-error
                  • +
                  • loop-detected
                  • +
                  • configuration-error
                  • +
                  • internal-error: option<string>

                    This is a catch-all error for anything that doesn't fit cleanly into a more specific case. It also includes an optional string for an unstructured description of the error. Users should not depend on the string for diagnosing errors, as it's not required to be consistent between implementations.

                  -

                  variant header-error

                  +

                  variant header-error

                  This type enumerates the different kinds of errors that may occur when setting or appending to a fields resource.

                  Variant Cases
                  • -

                    invalid-syntax

                    -

                    This error indicates that a `field-key` or `field-value` was +

                    invalid-syntax

                    +

                    This error indicates that a `field-name` or `field-value` was syntactically invalid when used with an operation that sets headers in a `fields`.

                  • -

                    forbidden

                    -

                    This error indicates that a forbidden `field-key` was used when trying +

                    forbidden

                    +

                    This error indicates that a forbidden `field-name` was used when trying to set a header in a `fields`.

                  • -

                    immutable

                    +

                    immutable

                    This error indicates that the operation on the `fields` was not permitted because the fields are immutable.

                  -

                  type field-key

                  +

                  type field-key

                  string

                  Field keys are always strings. -

                  type field-value

                  +

                  Field keys should always be treated as case insensitive by the fields +resource for the purposes of equality checking.

                  +

                  Deprecation

                  +

                  This type has been deprecated in favor of the field-name type.

                  +

                  type field-name

                  +

                  field-key

                  +

                  Field names are always strings. +

                  Field keys should always be treated as case insensitive by the fields +resource for the purposes of equality checking.

                  +

                  type field-value

                  field-value

                  Field values should always be ASCII strings. However, in reality, HTTP implementations often have to interpret malformed values, so they are provided as a list of bytes. -

                  resource fields

                  +

                  resource fields

                  This following block defines the fields resource which corresponds to HTTP standard Fields. Fields are a common representation used for both Headers and Trailers.

                  @@ -759,33 +768,33 @@ resource given by other means (including, but not limited to, incoming-request.headers, outgoing-request.headers) might be be immutable. In an immutable fields, the set, append, and delete operations will fail with header-error.immutable.

                  -

                  type headers

                  +

                  type headers

                  fields

                  Headers is an alias for Fields. -

                  type trailers

                  +

                  type trailers

                  fields

                  Trailers is an alias for Fields. -

                  resource incoming-request

                  +

                  resource incoming-request

                  Represents an incoming HTTP Request.

                  -

                  resource outgoing-request

                  +

                  resource outgoing-request

                  Represents an outgoing HTTP Request.

                  -

                  resource request-options

                  +

                  resource request-options

                  Parameters for making an HTTP Request. Each of these parameters is currently an optional timeout applicable to the transport layer of the HTTP protocol.

                  These timeouts are separate from any the user may use to bound a blocking call to wasi:io/poll.poll.

                  -

                  resource response-outparam

                  +

                  resource response-outparam

                  Represents the ability to send an HTTP Response.

                  This resource is used by the wasi:http/incoming-handler interface to allow a Response to be sent corresponding to the Request provided as the other argument to incoming-handler.handle.

                  -

                  type status-code

                  +

                  type status-code

                  u16

                  This type corresponds to the HTTP standard Status Code. -

                  resource incoming-response

                  +

                  resource incoming-response

                  Represents an incoming HTTP Response.

                  -

                  resource incoming-body

                  +

                  resource incoming-body

                  Represents an incoming HTTP Request or Response's Body.

                  A body has both its contents - a stream of bytes - and a (possibly empty) set of trailers, indicating that the full contents of the @@ -793,14 +802,14 @@ body have been received. This resource represents the contents as an input-stream and the delivery of trailers as a future-trailers, and ensures that the user of this interface may only be consuming either the body contents or waiting on trailers at any given time.

                  -

                  resource future-trailers

                  +

                  resource future-trailers

                  Represents a future which may eventually return trailers, or an error.

                  In the case that the incoming HTTP Request or Response did not have any trailers, this future will resolve to the empty set of trailers once the complete Request or Response body has been received.

                  -

                  resource outgoing-response

                  +

                  resource outgoing-response

                  Represents an outgoing HTTP Response.

                  -

                  resource outgoing-body

                  +

                  resource outgoing-body

                  Represents an outgoing HTTP Request or Response's Body.

                  A body has both its contents - a stream of bytes - and a (possibly empty) set of trailers, inducating the full contents of the body @@ -815,13 +824,13 @@ and that an error has occurred. The implementation should propagate this error to the HTTP protocol by whatever means it has available, including: corrupting the body on the wire, aborting the associated Request, or sending a late status code for the Response.

                  -

                  resource future-incoming-response

                  +

                  resource future-incoming-response

                  Represents a future which may eventually return an incoming HTTP Response, or an error.

                  This resource is returned by the wasi:http/outgoing-handler interface to provide the HTTP Response corresponding to the sent Request.

                  Functions

                  -

                  http-error-code: func

                  +

                  http-error-code: func

                  Attempts to extract a http-related error from the wasi:io error provided.

                  Stream operations which return @@ -833,20 +842,20 @@ if there's http-related information about the error to return.

                  http-related errors.

                  Params
                  Return values
                  -

                  [constructor]fields: func

                  +

                  [constructor]fields: func

                  Construct an empty HTTP Fields.

                  The resulting fields is mutable.

                  Return values
                  -

                  [static]fields.from-list: func

                  +

                  [static]fields.from-list: func

                  Construct an HTTP Fields.

                  The resulting fields is mutable.

                  The list represents each key-value pair in the Fields. Keys @@ -854,156 +863,158 @@ which have multiple values are represented by multiple entries in this list with the same key.

                  The tuple is a pair of the field key, represented as a string, and Value, represented as a list of bytes.

                  -

                  An error result will be returned if any field-key or field-value is +

                  An error result will be returned if any field-name or field-value is syntactically invalid, or if a field is forbidden.

                  Params
                  Return values
                  -

                  [method]fields.get: func

                  +

                  [method]fields.get: func

                  Get all of the values corresponding to a key. If the key is not present in this fields or is syntactically invalid, an empty list is returned. However, if the key is present but empty, this is represented by a list with one or more empty field-values present.

                  Params
                  Return values
                  -

                  [method]fields.has: func

                  +

                  [method]fields.has: func

                  Returns true when the key is present in this fields. If the key is syntactically invalid, false is returned.

                  Params
                  Return values
                    -
                  • bool
                  • +
                  • bool
                  -

                  [method]fields.set: func

                  +

                  [method]fields.set: func

                  Set all of the values for a key. Clears any existing values for that key, if they have been set.

                  Fails with header-error.immutable if the fields are immutable.

                  -

                  Fails with header-error.invalid-syntax if the field-key or any of +

                  Fails with header-error.invalid-syntax if the field-name or any of the field-values are syntactically invalid.

                  Params
                  Return values
                  -

                  [method]fields.delete: func

                  +

                  [method]fields.delete: func

                  Delete all values for a key. Does nothing if no values for the key exist.

                  Fails with header-error.immutable if the fields are immutable.

                  -

                  Fails with header-error.invalid-syntax if the field-key is +

                  Fails with header-error.invalid-syntax if the field-name is syntactically invalid.

                  Params
                  Return values
                  -

                  [method]fields.append: func

                  +

                  [method]fields.append: func

                  Append a value for a key. Does not change or delete any existing values for that key.

                  Fails with header-error.immutable if the fields are immutable.

                  -

                  Fails with header-error.invalid-syntax if the field-key or +

                  Fails with header-error.invalid-syntax if the field-name or field-value are syntactically invalid.

                  Params
                  Return values
                  -

                  [method]fields.entries: func

                  +

                  [method]fields.entries: func

                  Retrieve the full set of keys and values in the Fields. Like the constructor, the list represents each key-value pair.

                  The outer list represents each key-value pair in the Fields. Keys which have multiple values are represented by multiple entries in this list with the same key.

                  +

                  The keys and values are always returned in the original casing and in +the order in which they will be serialized for transport.

                  Params
                  Return values
                  -

                  [method]fields.clone: func

                  +

                  [method]fields.clone: func

                  Make a deep copy of the Fields. Equivalent in behavior to calling the fields constructor on the return value of entries. The resulting fields is mutable.

                  Params
                  Return values
                  -

                  [method]incoming-request.method: func

                  +

                  [method]incoming-request.method: func

                  Returns the method of the incoming request.

                  Params
                  Return values
                  -

                  [method]incoming-request.path-with-query: func

                  +

                  [method]incoming-request.path-with-query: func

                  Returns the path with query parameters from the request, as a string.

                  Params
                  Return values
                    -
                  • option<string>
                  • +
                  • option<string>
                  -

                  [method]incoming-request.scheme: func

                  +

                  [method]incoming-request.scheme: func

                  Returns the protocol scheme from the request.

                  Params
                  Return values
                  -

                  [method]incoming-request.authority: func

                  +

                  [method]incoming-request.authority: func

                  Returns the authority of the Request's target URI, if present.

                  Params
                  Return values
                    -
                  • option<string>
                  • +
                  • option<string>
                  -

                  [method]incoming-request.headers: func

                  +

                  [method]incoming-request.headers: func

                  Get the headers associated with the request.

                  The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

                  @@ -1012,24 +1023,24 @@ the parent incoming-request is drop incoming-request before all children are dropped will trap.

                  Params
                  Return values
                  -

                  [method]incoming-request.consume: func

                  +

                  [method]incoming-request.consume: func

                  Gives the incoming-body associated with this request. Will only return success at most once, and subsequent calls will return error.

                  Params
                  Return values
                  -

                  [constructor]outgoing-request: func

                  +

                  [constructor]outgoing-request: func

                  Construct a new outgoing-request with a default method of GET, and none values for path-with-query, scheme, and authority.

                    @@ -1042,13 +1053,13 @@ It is the obligation of the outgoing-handler.handle implementation to reject invalid constructions of outgoing-request.

                    Params
                    Return values
                    -

                    [method]outgoing-request.body: func

                    +

                    [method]outgoing-request.body: func

                    Returns the resource corresponding to the outgoing Body for this Request.

                    Returns success on the first call: the outgoing-body resource for @@ -1056,109 +1067,109 @@ this outgoing-request can be retrie calls will return error.

                    Params
                    Return values
                    -

                    [method]outgoing-request.method: func

                    +

                    [method]outgoing-request.method: func

                    Get the Method for the Request.

                    Params
                    Return values
                    -

                    [method]outgoing-request.set-method: func

                    +

                    [method]outgoing-request.set-method: func

                    Set the Method for the Request. Fails if the string present in a method.other argument is not a syntactically valid method.

                    Params
                    Return values
                      -
                    • result
                    • +
                    • result
                    -

                    [method]outgoing-request.path-with-query: func

                    +

                    [method]outgoing-request.path-with-query: func

                    Get the combination of the HTTP Path and Query for the Request. When none, this represents an empty Path and empty Query.

                    Params
                    Return values
                      -
                    • option<string>
                    • +
                    • option<string>
                    -

                    [method]outgoing-request.set-path-with-query: func

                    +

                    [method]outgoing-request.set-path-with-query: func

                    Set the combination of the HTTP Path and Query for the Request. When none, this represents an empty Path and empty Query. Fails is the string given is not a syntactically valid path and query uri component.

                    Params
                    Return values
                      -
                    • result
                    • +
                    • result
                    -

                    [method]outgoing-request.scheme: func

                    +

                    [method]outgoing-request.scheme: func

                    Get the HTTP Related Scheme for the Request. When none, the implementation may choose an appropriate default scheme.

                    Params
                    Return values
                    -

                    [method]outgoing-request.set-scheme: func

                    +

                    [method]outgoing-request.set-scheme: func

                    Set the HTTP Related Scheme for the Request. When none, the implementation may choose an appropriate default scheme. Fails if the string given is not a syntactically valid uri scheme.

                    Params
                    Return values
                      -
                    • result
                    • +
                    • result
                    -

                    [method]outgoing-request.authority: func

                    +

                    [method]outgoing-request.authority: func

                    Get the authority of the Request's target URI. A value of none may be used with Related Schemes which do not require an authority. The HTTP and HTTPS schemes always require an authority.

                    Params
                    Return values
                      -
                    • option<string>
                    • +
                    • option<string>
                    -

                    [method]outgoing-request.set-authority: func

                    +

                    [method]outgoing-request.set-authority: func

                    Set the authority of the Request's target URI. A value of none may be used with Related Schemes which do not require an authority. The HTTP and HTTPS schemes always require an authority. Fails if the string given is not a syntactically valid URI authority.

                    Params
                    Return values
                      -
                    • result
                    • +
                    • result
                    -

                    [method]outgoing-request.headers: func

                    +

                    [method]outgoing-request.headers: func

                    Get the headers associated with the Request.

                    The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

                    @@ -1167,87 +1178,87 @@ not a syntactically valid URI authority.

                    another component by e.g. outgoing-handler.handle.

                    Params
                    Return values
                    -

                    [constructor]request-options: func

                    +

                    [constructor]request-options: func

                    Construct a default request-options value.

                    Return values
                    -

                    [method]request-options.connect-timeout: func

                    +

                    [method]request-options.connect-timeout: func

                    The timeout for the initial connect to the HTTP Server.

                    Params
                    Return values
                    -

                    [method]request-options.set-connect-timeout: func

                    +

                    [method]request-options.set-connect-timeout: func

                    Set the timeout for the initial connect to the HTTP Server. An error return value indicates that this timeout is not supported.

                    Params
                    Return values
                      -
                    • result
                    • +
                    • result
                    -

                    [method]request-options.first-byte-timeout: func

                    +

                    [method]request-options.first-byte-timeout: func

                    The timeout for receiving the first byte of the Response body.

                    Params
                    Return values
                    -

                    [method]request-options.set-first-byte-timeout: func

                    +

                    [method]request-options.set-first-byte-timeout: func

                    Set the timeout for receiving the first byte of the Response body. An error return value indicates that this timeout is not supported.

                    Params
                    Return values
                      -
                    • result
                    • +
                    • result
                    -

                    [method]request-options.between-bytes-timeout: func

                    +

                    [method]request-options.between-bytes-timeout: func

                    The timeout for receiving subsequent chunks of bytes in the Response body stream.

                    Params
                    Return values
                    -

                    [method]request-options.set-between-bytes-timeout: func

                    +

                    [method]request-options.set-between-bytes-timeout: func

                    Set the timeout for receiving subsequent chunks of bytes in the Response body stream. An error return value indicates that this timeout is not supported.

                    Params
                    Return values
                      -
                    • result
                    • +
                    • result
                    -

                    [static]response-outparam.set: func

                    +

                    [static]response-outparam.set: func

                    Set the value of the response-outparam to either send a response, or indicate an error.

                    This method consumes the response-outparam to ensure that it is @@ -1257,20 +1268,20 @@ will respond with an error.

                    implementation determine how to respond with an HTTP error response.

                    Params
                    -

                    [method]incoming-response.status: func

                    +

                    [method]incoming-response.status: func

                    Returns the status code from the incoming response.

                    Params
                    Return values
                    -

                    [method]incoming-response.headers: func

                    +

                    [method]incoming-response.headers: func

                    Returns the headers from the incoming response.

                    The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

                    @@ -1278,24 +1289,24 @@ implementation determine how to respond with an HTTP error response.

                    incoming-response is dropped.

                    Params
                    Return values
                    -

                    [method]incoming-response.consume: func

                    +

                    [method]incoming-response.consume: func

                    Returns the incoming body. May be called at most once. Returns error if called additional times.

                    Params
                    Return values
                    -

                    [method]incoming-body.stream: func

                    +

                    [method]incoming-body.stream: func

                    Returns the contents of the body, as a stream of bytes.

                    Returns success on first call: the stream representing the contents can be retrieved at most once. Subsequent calls will return error.

                    @@ -1310,36 +1321,36 @@ and for that backpressure to not inhibit delivery of the trailers if the user does not read the entire body.

                    Params
                    Return values
                    -

                    [static]incoming-body.finish: func

                    +

                    [static]incoming-body.finish: func

                    Takes ownership of incoming-body, and returns a future-trailers. This function will trap if the input-stream child is still alive.

                    Params
                    Return values
                    -

                    [method]future-trailers.subscribe: func

                    +

                    [method]future-trailers.subscribe: func

                    Returns a pollable which becomes ready when either the trailers have been received, or an error has occurred. When this pollable is ready, the get method will return some.

                    Params
                    Return values
                    -

                    [method]future-trailers.get: func

                    +

                    [method]future-trailers.get: func

                    Returns the contents of the trailers, or an error which occurred, once the future is ready.

                    The outer option represents future readiness. Users can wait on this @@ -1357,13 +1368,13 @@ resource is immutable, and a child. Use of the set, appendfuture-trailers is dropped.

                    Params
                    Return values
                    -

                    [constructor]outgoing-response: func

                    +

                    [constructor]outgoing-response: func

                    Construct an outgoing-response, with a default status-code of 200. If a different status-code is needed, it must be set via the set-status-code method.

                    @@ -1372,35 +1383,35 @@ If a different status-code is needed, it
                  Params
                  Return values
                  -

                  [method]outgoing-response.status-code: func

                  +

                  [method]outgoing-response.status-code: func

                  Get the HTTP Status Code for the Response.

                  Params
                  Return values
                  -

                  [method]outgoing-response.set-status-code: func

                  +

                  [method]outgoing-response.set-status-code: func

                  Set the HTTP Status Code for the Response. Fails if the status-code given is not a valid http status code.

                  Params
                  Return values
                    -
                  • result
                  • +
                  • result
                  -

                  [method]outgoing-response.headers: func

                  +

                  [method]outgoing-response.headers: func

                  Get the headers associated with the Request.

                  The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

                  @@ -1409,26 +1420,26 @@ given is not a valid http status code.

                  another component by e.g. outgoing-handler.handle.

                  Params
                  Return values
                  -

                  [method]outgoing-response.body: func

                  +

                  [method]outgoing-response.body: func

                  Returns the resource corresponding to the outgoing Body for this Response.

                  Returns success on the first call: the outgoing-body resource for this outgoing-response can be retrieved at most once. Subsequent calls will return error.

                  Params
                  Return values
                  -

                  [method]outgoing-body.write: func

                  +

                  [method]outgoing-body.write: func

                  Returns a stream for writing the body contents.

                  The returned output-stream is a child resource: it must be dropped before the parent outgoing-body resource is dropped (or finished), @@ -1438,13 +1449,13 @@ this outgoing-body may be retrieved at will return error.

                  Params
                  Return values
                  -

                  [static]outgoing-body.finish: func

                  +

                  [static]outgoing-body.finish: func

                  Finalize an outgoing body, optionally providing trailers. This must be called to signal that the response is complete. If the outgoing-body is dropped without calling outgoing-body.finalize, the implementation @@ -1455,26 +1466,26 @@ to the body (via write) does not match the value given in the Content-Length.

                  Params
                  Return values
                  -

                  [method]future-incoming-response.subscribe: func

                  +

                  [method]future-incoming-response.subscribe: func

                  Returns a pollable which becomes ready when either the Response has been received, or an error has occurred. When this pollable is ready, the get method will return some.

                  Params
                  Return values
                  -

                  [method]future-incoming-response.get: func

                  +

                  [method]future-incoming-response.get: func

                  Returns the incoming HTTP Response, or an error, once one is ready.

                  The outer option represents future readiness. Users can wait on this option to become some using the subscribe method.

                  @@ -1488,32 +1499,32 @@ but those will be reported by the incoming-bodyoutput-stream child.

                  Params
                  Return values
                  -

                  Import interface wasi:http/outgoing-handler@0.2.1

                  +

                  Import interface wasi:http/outgoing-handler@0.2.1

                  This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                  Types

                  -

                  type outgoing-request

                  +

                  type outgoing-request

                  outgoing-request

                  -#### `type request-options` +#### `type request-options` [`request-options`](#request_options)

                  -#### `type future-incoming-response` +#### `type future-incoming-response` [`future-incoming-response`](#future_incoming_response)

                  -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                  ----

                  Functions

                  -

                  handle: func

                  +

                  handle: func

                  This function is invoked with an outgoing HTTP Request, and it returns a resource future-incoming-response which represents an HTTP Response which may arrive in the future.

                  @@ -1524,10 +1535,10 @@ or not allowed to be made. Otherwise, protocol errors are reported through the future-incoming-response.

                  Params
                  Return values
                  From 47b1b053e1702f8093bd5a9e64ebddf355a183c9 Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 14 Aug 2024 15:12:18 +0200 Subject: [PATCH 1499/1772] pin `wasm-tools` version in CI --- proposals/http/.github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index b8f6fd92b..3bfc2ee18 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -18,5 +18,6 @@ jobs: ./wit-deps lock --check - uses: WebAssembly/wit-abi-up-to-date@v21 with: + wasm-tools: '1.215.0' wit-bindgen: '0.30.0' worlds: 'imports proxy' From d2c8e61721f03c6e14ba64221672d457121f7852 Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 21 Aug 2024 16:36:16 +0200 Subject: [PATCH 1500/1772] bump `wit-abi-up-to-date` --- proposals/http/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index 3bfc2ee18..e5ad56545 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -16,7 +16,7 @@ jobs: curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.2/wit-deps-x86_64-unknown-linux-musl chmod +x ./wit-deps ./wit-deps lock --check - - uses: WebAssembly/wit-abi-up-to-date@v21 + - uses: WebAssembly/wit-abi-up-to-date@v22 with: wasm-tools: '1.215.0' wit-bindgen: '0.30.0' From baaf976d7ed48c72ca705bc9e1c69af3477ed83e Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 21 Aug 2024 16:42:04 +0200 Subject: [PATCH 1501/1772] Replace all references to `field-key` in docs Co-Authored-By: Luke Wagner --- proposals/http/wit-0.3.0-draft/types.wit | 40 ++++++++++++------------ proposals/http/wit/types.wit | 34 ++++++++++---------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index e562d8d25..1f3c6889c 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -134,7 +134,7 @@ interface types { /// Field names are always strings. /// - /// Field keys should always be treated as case insensitive by the `fields` + /// Field names should always be treated as case insensitive by the `fields` /// resource for the purposes of equality checking. type field-name = string; @@ -168,12 +168,12 @@ interface types { /// /// The resulting `fields` is mutable. /// - /// The list represents each key-value pair in the Fields. Keys + /// The list represents each name-value pair in the Fields. Names /// which have multiple values are represented by multiple entries in this - /// list with the same key. + /// list with the same name. /// - /// The tuple is a pair of the field key, represented as a string, and - /// Value, represented as a list of bytes. In a valid Fields, all keys + /// The tuple is a pair of the field name, represented as a string, and + /// Value, represented as a list of bytes. In a valid Fields, all names /// and values are valid UTF-8 strings. However, values are not always /// well-formed, so they are represented as a raw list of bytes. /// @@ -183,50 +183,50 @@ interface types { entries: list> ) -> result; - /// Get all of the values corresponding to a key. If the key is not present - /// in this `fields`, an empty list is returned. However, if the key is + /// Get all of the values corresponding to a name. If the name is not present + /// in this `fields`, an empty list is returned. However, if the name is /// present but empty, this is represented by a list with one or more /// empty field-values present. get: func(name: field-name) -> list; - /// Returns `true` when the key is present in this `fields`. If the key is + /// Returns `true` when the name is present in this `fields`. If the name is /// syntactically invalid, `false` is returned. has: func(name: field-name) -> bool; - /// Set all of the values for a key. Clears any existing values for that - /// key, if they have been set. + /// Set all of the values for a name. Clears any existing values for that + /// name, if they have been set. /// /// Fails with `header-error.immutable` if the `fields` are immutable. set: func(name: field-name, value: list) -> result<_, header-error>; - /// Delete all values for a key. Does nothing if no values for the key + /// Delete all values for a name. Does nothing if no values for the name /// exist. /// /// Fails with `header-error.immutable` if the `fields` are immutable. delete: func(name: field-name) -> result<_, header-error>; - /// Delete all values for a key. Does nothing if no values for the key + /// Delete all values for a name. Does nothing if no values for the name /// exist. /// - /// Returns all values previously corresponding to the key, if any. + /// Returns all values previously corresponding to the name, if any. /// /// Fails with `header-error.immutable` if the `fields` are immutable. get-and-delete: func(name: field-name) -> result, header-error>; - /// Append a value for a key. Does not change or delete any existing - /// values for that key. + /// Append a value for a name. Does not change or delete any existing + /// values for that name. /// /// Fails with `header-error.immutable` if the `fields` are immutable. append: func(name: field-name, value: field-value) -> result<_, header-error>; - /// Retrieve the full set of keys and values in the Fields. Like the - /// constructor, the list represents each key-value pair. + /// Retrieve the full set of names and values in the Fields. Like the + /// constructor, the list represents each name-value pair. /// - /// The outer list represents each key-value pair in the Fields. Keys + /// The outer list represents each name-value pair in the Fields. Names /// which have multiple values are represented by multiple entries in this - /// list with the same key. + /// list with the same name. /// - /// The keys and values are always returned in the original casing and in + /// The names and values are always returned in the original casing and in /// the order in which they will be serialized for transport. entries: func() -> list>; diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 5836a9ca2..002bed9a7 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -140,7 +140,7 @@ interface types { /// Field names are always strings. /// - /// Field keys should always be treated as case insensitive by the `fields` + /// Field names should always be treated as case insensitive by the `fields` /// resource for the purposes of equality checking. @since(version = 0.2.1) type field-name = field-key; @@ -186,11 +186,11 @@ interface types { /// /// The resulting `fields` is mutable. /// - /// The list represents each key-value pair in the Fields. Keys + /// The list represents each name-value pair in the Fields. Names /// which have multiple values are represented by multiple entries in this - /// list with the same key. + /// list with the same name. /// - /// The tuple is a pair of the field key, represented as a string, and + /// The tuple is a pair of the field name, represented as a string, and /// Value, represented as a list of bytes. /// /// An error result will be returned if any `field-name` or `field-value` is @@ -200,20 +200,20 @@ interface types { entries: list> ) -> result; - /// Get all of the values corresponding to a key. If the key is not present + /// Get all of the values corresponding to a name. If the name is not present /// in this `fields` or is syntactically invalid, an empty list is returned. - /// However, if the key is present but empty, this is represented by a list + /// However, if the name is present but empty, this is represented by a list /// with one or more empty field-values present. @since(version = 0.2.0) get: func(name: field-name) -> list; - /// Returns `true` when the key is present in this `fields`. If the key is + /// Returns `true` when the name is present in this `fields`. If the name is /// syntactically invalid, `false` is returned. @since(version = 0.2.0) has: func(name: field-name) -> bool; - /// Set all of the values for a key. Clears any existing values for that - /// key, if they have been set. + /// Set all of the values for a name. Clears any existing values for that + /// name, if they have been set. /// /// Fails with `header-error.immutable` if the `fields` are immutable. /// @@ -222,7 +222,7 @@ interface types { @since(version = 0.2.0) set: func(name: field-name, value: list) -> result<_, header-error>; - /// Delete all values for a key. Does nothing if no values for the key + /// Delete all values for a name. Does nothing if no values for the name /// exist. /// /// Fails with `header-error.immutable` if the `fields` are immutable. @@ -232,8 +232,8 @@ interface types { @since(version = 0.2.0) delete: func(name: field-name) -> result<_, header-error>; - /// Append a value for a key. Does not change or delete any existing - /// values for that key. + /// Append a value for a name. Does not change or delete any existing + /// values for that name. /// /// Fails with `header-error.immutable` if the `fields` are immutable. /// @@ -242,14 +242,14 @@ interface types { @since(version = 0.2.0) append: func(name: field-name, value: field-value) -> result<_, header-error>; - /// Retrieve the full set of keys and values in the Fields. Like the - /// constructor, the list represents each key-value pair. + /// Retrieve the full set of names and values in the Fields. Like the + /// constructor, the list represents each name-value pair. /// - /// The outer list represents each key-value pair in the Fields. Keys + /// The outer list represents each name-value pair in the Fields. Names /// which have multiple values are represented by multiple entries in this - /// list with the same key. + /// list with the same name. /// - /// The keys and values are always returned in the original casing and in + /// The names and values are always returned in the original casing and in /// the order in which they will be serialized for transport. @since(version = 0.2.0) entries: func() -> list>; From dff91b868d47afacbe854b094ef421b1a7d7edbd Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 21 Aug 2024 16:44:27 +0200 Subject: [PATCH 1502/1772] Fix doc format issue Co-Authored-By: Luke Wagner --- proposals/http/wit-0.3.0-draft/types.wit | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index 1f3c6889c..f702c15ed 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -154,7 +154,8 @@ interface types { /// `set`, `append`, and `delete` operations will fail with /// `header-error.immutable`. /// - /// A `fields` resource should store `field-name`s and `field-value`s in their /// original casing used to construct or mutate the `fields` resource. The `fields` + /// A `fields` resource should store `field-name`s and `field-value`s in their + /// original casing used to construct or mutate the `fields` resource. The `fields` /// resource should use that original casing when serializing the fields for /// transport or when returning them from a method. resource fields { From da01ee251382047e560e332ca539b6608cd54cfe Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 21 Aug 2024 16:46:16 +0200 Subject: [PATCH 1503/1772] re-generate docs Co-Authored-By: Luke Wagner --- proposals/http/imports.md | 34 +++++++++++++++++----------------- proposals/http/proxy.md | 34 +++++++++++++++++----------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index 22d946e78..6a3caf156 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -751,7 +751,7 @@ resource for the purposes of equality checking.

                  type field-name

                  field-key

                  Field names are always strings. -

                  Field keys should always be treated as case insensitive by the fields +

                  Field names should always be treated as case insensitive by the fields resource for the purposes of equality checking.

                  type field-value

                  field-value

                  @@ -858,10 +858,10 @@ http-related errors.

                  [static]fields.from-list: func

                  Construct an HTTP Fields.

                  The resulting fields is mutable.

                  -

                  The list represents each key-value pair in the Fields. Keys +

                  The list represents each name-value pair in the Fields. Names which have multiple values are represented by multiple entries in this -list with the same key.

                  -

                  The tuple is a pair of the field key, represented as a string, and +list with the same name.

                  +

                  The tuple is a pair of the field name, represented as a string, and Value, represented as a list of bytes.

                  An error result will be returned if any field-name or field-value is syntactically invalid, or if a field is forbidden.

                  @@ -874,9 +874,9 @@ syntactically invalid, or if a field is forbidden.

                21. result<own<fields>, header-error>
                22. [method]fields.get: func

                  -

                  Get all of the values corresponding to a key. If the key is not present +

                  Get all of the values corresponding to a name. If the name is not present in this fields or is syntactically invalid, an empty list is returned. -However, if the key is present but empty, this is represented by a list +However, if the name is present but empty, this is represented by a list with one or more empty field-values present.

                  Params
                    @@ -888,7 +888,7 @@ with one or more empty field-values present.

                  • list<field-value>

                  [method]fields.has: func

                  -

                  Returns true when the key is present in this fields. If the key is +

                  Returns true when the name is present in this fields. If the name is syntactically invalid, false is returned.

                  Params
                    @@ -900,8 +900,8 @@ syntactically invalid, false is returned.

                  • bool

                  [method]fields.set: func

                  -

                  Set all of the values for a key. Clears any existing values for that -key, if they have been set.

                  +

                  Set all of the values for a name. Clears any existing values for that +name, if they have been set.

                  Fails with header-error.immutable if the fields are immutable.

                  Fails with header-error.invalid-syntax if the field-name or any of the field-values are syntactically invalid.

                  @@ -916,7 +916,7 @@ the field-values are syntactically inval
                23. result<_, header-error>
                24. [method]fields.delete: func

                  -

                  Delete all values for a key. Does nothing if no values for the key +

                  Delete all values for a name. Does nothing if no values for the name exist.

                  Fails with header-error.immutable if the fields are immutable.

                  Fails with header-error.invalid-syntax if the field-name is @@ -931,8 +931,8 @@ syntactically invalid.

                25. result<_, header-error>
                26. [method]fields.append: func

                  -

                  Append a value for a key. Does not change or delete any existing -values for that key.

                  +

                  Append a value for a name. Does not change or delete any existing +values for that name.

                  Fails with header-error.immutable if the fields are immutable.

                  Fails with header-error.invalid-syntax if the field-name or field-value are syntactically invalid.

                  @@ -947,12 +947,12 @@ values for that key.

                27. result<_, header-error>
                28. [method]fields.entries: func

                  -

                  Retrieve the full set of keys and values in the Fields. Like the -constructor, the list represents each key-value pair.

                  -

                  The outer list represents each key-value pair in the Fields. Keys +

                  Retrieve the full set of names and values in the Fields. Like the +constructor, the list represents each name-value pair.

                  +

                  The outer list represents each name-value pair in the Fields. Names which have multiple values are represented by multiple entries in this -list with the same key.

                  -

                  The keys and values are always returned in the original casing and in +list with the same name.

                  +

                  The names and values are always returned in the original casing and in the order in which they will be serialized for transport.

                  Params
                    diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index f019fb553..b0f72e258 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -645,7 +645,7 @@ resource for the purposes of equality checking.

                    type field-name

                    field-key

                    Field names are always strings. -

                    Field keys should always be treated as case insensitive by the fields +

                    Field names should always be treated as case insensitive by the fields resource for the purposes of equality checking.

                    type field-value

                    field-value

                    @@ -752,10 +752,10 @@ http-related errors.

                    [static]fields.from-list: func

                    Construct an HTTP Fields.

                    The resulting fields is mutable.

                    -

                    The list represents each key-value pair in the Fields. Keys +

                    The list represents each name-value pair in the Fields. Names which have multiple values are represented by multiple entries in this -list with the same key.

                    -

                    The tuple is a pair of the field key, represented as a string, and +list with the same name.

                    +

                    The tuple is a pair of the field name, represented as a string, and Value, represented as a list of bytes.

                    An error result will be returned if any field-name or field-value is syntactically invalid, or if a field is forbidden.

                    @@ -768,9 +768,9 @@ syntactically invalid, or if a field is forbidden.

                  • result<own<fields>, header-error>

                  [method]fields.get: func

                  -

                  Get all of the values corresponding to a key. If the key is not present +

                  Get all of the values corresponding to a name. If the name is not present in this fields or is syntactically invalid, an empty list is returned. -However, if the key is present but empty, this is represented by a list +However, if the name is present but empty, this is represented by a list with one or more empty field-values present.

                  Params
                    @@ -782,7 +782,7 @@ with one or more empty field-values present.

                  • list<field-value>

                  [method]fields.has: func

                  -

                  Returns true when the key is present in this fields. If the key is +

                  Returns true when the name is present in this fields. If the name is syntactically invalid, false is returned.

                  Params
                    @@ -794,8 +794,8 @@ syntactically invalid, false is returned.

                  • bool

                  [method]fields.set: func

                  -

                  Set all of the values for a key. Clears any existing values for that -key, if they have been set.

                  +

                  Set all of the values for a name. Clears any existing values for that +name, if they have been set.

                  Fails with header-error.immutable if the fields are immutable.

                  Fails with header-error.invalid-syntax if the field-name or any of the field-values are syntactically invalid.

                  @@ -810,7 +810,7 @@ the field-values are syntactically inval
                29. result<_, header-error>
                30. [method]fields.delete: func

                  -

                  Delete all values for a key. Does nothing if no values for the key +

                  Delete all values for a name. Does nothing if no values for the name exist.

                  Fails with header-error.immutable if the fields are immutable.

                  Fails with header-error.invalid-syntax if the field-name is @@ -825,8 +825,8 @@ syntactically invalid.

                31. result<_, header-error>
                32. [method]fields.append: func

                  -

                  Append a value for a key. Does not change or delete any existing -values for that key.

                  +

                  Append a value for a name. Does not change or delete any existing +values for that name.

                  Fails with header-error.immutable if the fields are immutable.

                  Fails with header-error.invalid-syntax if the field-name or field-value are syntactically invalid.

                  @@ -841,12 +841,12 @@ values for that key.

                33. result<_, header-error>
                34. [method]fields.entries: func

                  -

                  Retrieve the full set of keys and values in the Fields. Like the -constructor, the list represents each key-value pair.

                  -

                  The outer list represents each key-value pair in the Fields. Keys +

                  Retrieve the full set of names and values in the Fields. Like the +constructor, the list represents each name-value pair.

                  +

                  The outer list represents each name-value pair in the Fields. Names which have multiple values are represented by multiple entries in this -list with the same key.

                  -

                  The keys and values are always returned in the original casing and in +list with the same name.

                  +

                  The names and values are always returned in the original casing and in the order in which they will be serialized for transport.

                  Params
                    From d11cafc0a92df0f38adba06d9efe8c28f10f31a9 Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 21 Aug 2024 16:53:52 +0200 Subject: [PATCH 1504/1772] oops --- proposals/http/wit/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 002bed9a7..30b364226 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -154,7 +154,7 @@ interface types { /// /// This type has been deprecated in favor of the `field-name` type. @since(version = 0.2.0) - @deprecated(version = 0.2.1) + @deprecated(version = 0.2.2) type field-key = string; /// Field values should always be ASCII strings. However, in From 36e8511ca1146cfde1aacaeb427e00d39bf98965 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 22 Aug 2024 17:41:32 +0200 Subject: [PATCH 1505/1772] Add missing since annotation to `output-stream::subscribe` (#85) --- proposals/io/wit/streams.wit | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index 49108236b..72b3ccd36 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -208,6 +208,7 @@ interface streams { /// The created `pollable` is a child resource of the `output-stream`. /// Implementations may trap if the `output-stream` is dropped before /// all derived `pollable`s created with this function are dropped. + @since(version = 0.2.0) subscribe: func() -> pollable; /// Write zeroes to a stream. From afdbca454c200aedd7752a8ebb502f8f9e6985a1 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sat, 14 Sep 2024 13:40:40 +0200 Subject: [PATCH 1506/1772] Add function to downcast a stream error to a network-related error. Similar to the existing `filesystem-error-code` and `http-error-code` functions. --- proposals/sockets/wit/network.wit | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 8c13b348e..993c4ce61 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -1,5 +1,8 @@ @since(version = 0.2.0) interface network { + @unstable(feature = network-error-code) + use wasi:io/error@0.2.1.{error}; + /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. @@ -105,6 +108,19 @@ interface network { permanent-resolver-failure, } + /// Attempts to extract a network-related `error-code` from the stream + /// `error` provided. + /// + /// Stream operations which return `stream-error::last-operation-failed` + /// have a payload with more information about the operation that failed. + /// This payload can be passed through to this function to see if there's + /// network-related information about the error to return. + /// + /// Note that this function is fallible because not all stream-related + /// errors are network-related errors. + @unstable(feature = network-error-code) + network-error-code: func(err: borrow) -> option; + @since(version = 0.2.0) enum ip-address-family { /// Similar to `AF_INET` in POSIX. From 03140ea6f8594196d70d78b0adbad4e0303eac97 Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:55:28 +0200 Subject: [PATCH 1507/1772] Update to v0.2.2 (#87) --- proposals/io/.github/workflows/main.yml | 4 +- proposals/io/imports.md | 168 ++++++++++++------------ proposals/io/wit/error.wit | 2 +- proposals/io/wit/poll.wit | 2 +- proposals/io/wit/streams.wit | 2 +- proposals/io/wit/world.wit | 2 +- 6 files changed, 90 insertions(+), 90 deletions(-) diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index 675238430..431b96bc0 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: WebAssembly/wit-abi-up-to-date@v21 + - uses: WebAssembly/wit-abi-up-to-date@v22 with: - wit-bindgen: '0.28.0' + wit-bindgen: '0.33.0' diff --git a/proposals/io/imports.md b/proposals/io/imports.md index da7edcb11..da344c741 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -1,17 +1,17 @@ -

                    World imports

                    +

                    World imports

                    -

                    Import interface wasi:io/error@0.2.1

                    +

                    Import interface wasi:io/error@0.2.2


                    Types

                    -

                    resource error

                    +

                    resource error

                    A resource which represents some error information.

                    The only method provided by this resource is to-debug-string, which provides some human-readable information about the error.

                    @@ -26,7 +26,7 @@ parameter and returns an option<wasi:filesystem/types/error-code>The set of functions which can "downcast" an error into a more concrete type is open.

                    Functions

                    -

                    [method]error.to-debug-string: func

                    +

                    [method]error.to-debug-string: func

                    Returns a string that is suitable to assist humans in debugging this error.

                    WARNING: The returned string should not be consumed mechanically! @@ -35,41 +35,41 @@ details. Parsing this string is a major platform-compatibility hazard.

                    Params
                    Return values
                      -
                    • string
                    • +
                    • string
                    -

                    Import interface wasi:io/poll@0.2.1

                    +

                    Import interface wasi:io/poll@0.2.2

                    A poll API intended to let users wait for I/O events on multiple handles at once.


                    Types

                    -

                    resource pollable

                    +

                    resource pollable

                    pollable represents a single I/O event which may be ready, or not.

                    Functions

                    -

                    [method]pollable.ready: func

                    +

                    [method]pollable.ready: func

                    Return the readiness of a pollable. This function never blocks.

                    Returns true when the pollable is ready, and false otherwise.

                    Params
                    Return values
                      -
                    • bool
                    • +
                    • bool
                    -

                    [method]pollable.block: func

                    +

                    [method]pollable.block: func

                    block returns immediately if the pollable is ready, and otherwise blocks until ready.

                    This function is equivalent to calling poll.poll on a list containing only this pollable.

                    Params
                    -

                    poll: func

                    +

                    poll: func

                    Poll for completion on a set of pollables.

                    This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

                    @@ -88,44 +88,44 @@ the pollables has an error, it is indicated by marking the source as being ready for I/O.

                    Params
                    Return values
                      -
                    • list<u32>
                    • +
                    • list<u32>
                    -

                    Import interface wasi:io/streams@0.2.1

                    +

                    Import interface wasi:io/streams@0.2.2

                    WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                    In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


                    Types

                    -

                    type error

                    +

                    type error

                    error

                    -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

                    -#### `variant stream-error` +#### `variant stream-error`

                    An error for input-stream and output-stream operations.

                    Variant Cases
                    • -

                      last-operation-failed: own<error>

                      +

                      last-operation-failed: own<error>

                      The last operation (a write or flush) failed before completion.

                      More information is available in the error payload.

                      After this, the stream will be closed. All future operations return stream-error::closed.

                    • -

                      closed

                      +

                      closed

                      The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

                    -

                    resource input-stream

                    +

                    resource input-stream

                    An input bytestream.

                    input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are @@ -133,7 +133,7 @@ promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

                    -

                    resource output-stream

                    +

                    resource output-stream

                    An output bytestream.

                    output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also @@ -145,7 +145,7 @@ polled for using wasi:io/poll.

                    progress may result in the data being lost. Before dropping the stream, be sure to fully flush your writes.

                    Functions

                    -

                    [method]input-stream.read: func

                    +

                    [method]input-stream.read: func

                    Perform a non-blocking read from the stream.

                    When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -169,51 +169,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

                    Params
                    Return values
                    -

                    [method]input-stream.blocking-read: func

                    +

                    [method]input-stream.blocking-read: func

                    Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

                    Params
                    Return values
                    -

                    [method]input-stream.skip: func

                    +

                    [method]input-stream.skip: func

                    Skip bytes from a stream. Returns number of bytes skipped.

                    Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

                    Params
                    Return values
                    -

                    [method]input-stream.blocking-skip: func

                    +

                    [method]input-stream.blocking-skip: func

                    Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

                    Params
                    Return values
                    -

                    [method]input-stream.subscribe: func

                    +

                    [method]input-stream.subscribe: func

                    Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -222,13 +222,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

                    Params
                    Return values
                    -

                    [method]output-stream.check-write: func

                    +

                    [method]output-stream.check-write: func

                    Check readiness for writing. This function never blocks.

                    Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -238,13 +238,13 @@ become ready when this function will report at least 1 byte, or an error.

                    Params
                    Return values
                    -

                    [method]output-stream.write: func

                    +

                    [method]output-stream.write: func

                    Perform a write. This function never blocks.

                    When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -257,14 +257,14 @@ length of less than or equal to n. Otherwise, this function will trap.

                    the last call to check-write provided a permit.

                    Params
                    Return values
                    -

                    [method]output-stream.blocking-write-and-flush: func

                    +

                    [method]output-stream.blocking-write-and-flush: func

                    Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                    This is a convenience wrapper around the use of check-write, @@ -288,14 +288,14 @@ let _ = this.check-write(); // eliding error handling

                    Params
                    Return values
                    -

                    [method]output-stream.flush: func

                    +

                    [method]output-stream.flush: func

                    Request to flush buffered output. This function never blocks.

                    This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -306,24 +306,24 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

                    Params
                    Return values
                    -

                    [method]output-stream.blocking-flush: func

                    +

                    [method]output-stream.blocking-flush: func

                    Request to flush buffered output, and block until flush completes and stream is ready for writing again.

                    Params
                    Return values
                    -

                    [method]output-stream.subscribe: func

                    +

                    [method]output-stream.subscribe: func

                    Create a pollable which will resolve once the output-stream is ready for more writing, or an error has occurred. When this pollable is ready, check-write will return ok(n) with n>0, or an @@ -334,13 +334,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

                    Params
                    Return values
                    -

                    [method]output-stream.write-zeroes: func

                    +

                    [method]output-stream.write-zeroes: func

                    Write zeroes to a stream.

                    This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -348,14 +348,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

                    Params
                    Return values
                    -

                    [method]output-stream.blocking-write-zeroes-and-flush: func

                    +

                    [method]output-stream.blocking-write-zeroes-and-flush: func

                    Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                    @@ -379,14 +379,14 @@ let _ = this.check-write(); // eliding error handling
                    Params
                    Return values
                    -

                    [method]output-stream.splice: func

                    +

                    [method]output-stream.splice: func

                    Read from one stream and write to another.

                    The behavior of splice is equivalent to:

                      @@ -401,26 +401,26 @@ let _ = this.check-write(); // eliding error handling than len.

                      Params
                      Return values
                      -

                      [method]output-stream.blocking-splice: func

                      +

                      [method]output-stream.blocking-splice: func

                      Read from one stream and write to another, with blocking.

                      This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

                      Params
                      Return values
                      diff --git a/proposals/io/wit/error.wit b/proposals/io/wit/error.wit index 4ea29c469..717135f8c 100644 --- a/proposals/io/wit/error.wit +++ b/proposals/io/wit/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; @since(version = 0.2.0) interface error { diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index b25ac729f..49c1c5ede 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index 72b3ccd36..330f7095c 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index 6405a4e48..f7001ccff 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; @since(version = 0.2.0) world imports { From 02fbeec337625717bf8adfcb01130675f6d66081 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 3 Oct 2024 16:02:27 +0200 Subject: [PATCH 1508/1772] Update to v0.2.2 --- proposals/random/.github/workflows/main.yml | 4 +-- proposals/random/imports.md | 38 ++++++++++----------- proposals/random/wit/insecure-seed.wit | 2 +- proposals/random/wit/insecure.wit | 2 +- proposals/random/wit/random.wit | 2 +- proposals/random/wit/world.wit | 2 +- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index 675238430..431b96bc0 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: WebAssembly/wit-abi-up-to-date@v21 + - uses: WebAssembly/wit-abi-up-to-date@v22 with: - wit-bindgen: '0.28.0' + wit-bindgen: '0.33.0' diff --git a/proposals/random/imports.md b/proposals/random/imports.md index 19f1cc8a1..597b93039 100644 --- a/proposals/random/imports.md +++ b/proposals/random/imports.md @@ -1,20 +1,20 @@ -

                      World imports

                      +

                      World imports

                      -

                      Import interface wasi:random/random@0.2.1

                      +

                      Import interface wasi:random/random@0.2.2

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.


                      Functions

                      -

                      get-random-bytes: func

                      +

                      get-random-bytes: func

                      Return len cryptographically-secure random or pseudo-random bytes.

                      This function must produce data at least as cryptographically secure and fast as an adequately seeded cryptographically-secure pseudo-random @@ -27,27 +27,27 @@ must omit this function, rather than implementing it with deterministic data.

                      Params
                        -
                      • len: u64
                      • +
                      • len: u64
                      Return values
                        -
                      • list<u8>
                      • +
                      • list<u8>
                      -

                      get-random-u64: func

                      +

                      get-random-u64: func

                      Return a cryptographically-secure random or pseudo-random u64 value.

                      This function returns the same type of data as get-random-bytes, represented as a u64.

                      Return values
                        -
                      • u64
                      • +
                      • u64
                      -

                      Import interface wasi:random/insecure@0.2.1

                      +

                      Import interface wasi:random/insecure@0.2.2

                      The insecure interface for insecure pseudo-random numbers.

                      It is intended to be portable at least between Unix-family platforms and Windows.


                      Functions

                      -

                      get-insecure-random-bytes: func

                      +

                      get-insecure-random-bytes: func

                      Return len insecure pseudo-random bytes.

                      This function is not cryptographically secure. Do not use it for anything related to security.

                      @@ -56,27 +56,27 @@ implementations are encouraged to return evenly distributed values with a long period.

                      Params
                        -
                      • len: u64
                      • +
                      • len: u64
                      Return values
                        -
                      • list<u8>
                      • +
                      • list<u8>
                      -

                      get-insecure-random-u64: func

                      +

                      get-insecure-random-u64: func

                      Return an insecure pseudo-random u64 value.

                      This function returns the same type of pseudo-random data as get-insecure-random-bytes, represented as a u64.

                      Return values
                        -
                      • u64
                      • +
                      • u64
                      -

                      Import interface wasi:random/insecure-seed@0.2.1

                      +

                      Import interface wasi:random/insecure-seed@0.2.2

                      The insecure-seed interface for seeding hash-map DoS resistance.

                      It is intended to be portable at least between Unix-family platforms and Windows.


                      Functions

                      -

                      insecure-seed: func

                      +

                      insecure-seed: func

                      Return a 128-bit value that may contain a pseudo-random value.

                      The returned value is not required to be computed from a CSPRNG, and may even be entirely deterministic. Host implementations are encouraged to @@ -92,5 +92,5 @@ called multiple times and potentially used for purposes other than DoS protection.

                      Return values
                        -
                      • (u64, u64)
                      • +
                      • (u64, u64)
                      diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index 7e708dc52..cdea716cf 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index 3cdb53dfb..b71e85879 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 2b5035d1c..0c57e8c80 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index c615e96dc..16d68acfa 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; @since(version = 0.2.0) world imports { From b2891409ae80c349dcc65e2245c4ee1dd890039e Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Thu, 3 Oct 2024 16:17:30 +0200 Subject: [PATCH 1509/1772] Update to v0.2.2 (#75) --- proposals/clocks/.github/workflows/main.yml | 4 +- proposals/clocks/imports.md | 98 ++++++++++----------- proposals/clocks/wit/deps.lock | 4 +- proposals/clocks/wit/deps/io/error.wit | 2 +- proposals/clocks/wit/deps/io/poll.wit | 2 +- proposals/clocks/wit/deps/io/streams.wit | 6 +- proposals/clocks/wit/deps/io/world.wit | 2 +- proposals/clocks/wit/monotonic-clock.wit | 4 +- proposals/clocks/wit/timezone.wit | 2 +- proposals/clocks/wit/wall-clock.wit | 2 +- proposals/clocks/wit/world.wit | 2 +- 11 files changed, 66 insertions(+), 62 deletions(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 244de48de..2b0fc356f 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -18,7 +18,7 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v21 + - uses: WebAssembly/wit-abi-up-to-date@v22 with: features: clocks-timezone - wit-bindgen: '0.28.0' + wit-bindgen: '0.33.0' diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index 886f9ff19..ee9ca51c1 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -1,43 +1,43 @@ -

                      World imports

                      +

                      World imports

                      -

                      Import interface wasi:io/poll@0.2.1

                      +

                      Import interface wasi:io/poll@0.2.2

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      Types

                      -

                      resource pollable

                      +

                      resource pollable

                      pollable represents a single I/O event which may be ready, or not.

                      Functions

                      -

                      [method]pollable.ready: func

                      +

                      [method]pollable.ready: func

                      Return the readiness of a pollable. This function never blocks.

                      Returns true when the pollable is ready, and false otherwise.

                      Params
                      Return values
                        -
                      • bool
                      • +
                      • bool
                      -

                      [method]pollable.block: func

                      +

                      [method]pollable.block: func

                      block returns immediately if the pollable is ready, and otherwise blocks until ready.

                      This function is equivalent to calling poll.poll on a list containing only this pollable.

                      Params
                      -

                      poll: func

                      +

                      poll: func

                      Poll for completion on a set of pollables.

                      This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

                      @@ -56,13 +56,13 @@ the pollables has an error, it is indicated by marking the source as being ready for I/O.

                      Params
                      Return values
                        -
                      • list<u32>
                      • +
                      • list<u32>
                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.1

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.2

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -71,57 +71,57 @@ Windows.

                      successive reads of the clock will produce non-decreasing values.


                      Types

                      -

                      type pollable

                      +

                      type pollable

                      pollable

                      -#### `type instant` +#### `type instant` `u64`

                      An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. -

                      type duration

                      +

                      type duration

                      u64

                      A duration of time, in nanoseconds.


                      Functions

                      -

                      now: func

                      +

                      now: func

                      Read the current value of the clock.

                      The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

                      Return values
                      -

                      resolution: func

                      +

                      resolution: func

                      Query the resolution of the clock. Returns the duration of time corresponding to a clock tick.

                      Return values
                      -

                      subscribe-instant: func

                      +

                      subscribe-instant: func

                      Create a pollable which will resolve once the specified instant has occurred.

                      Params
                      Return values
                      -

                      subscribe-duration: func

                      +

                      subscribe-duration: func

                      Create a pollable that will resolve after the specified duration has elapsed from the time this function is invoked.

                      Params
                      Return values
                      -

                      Import interface wasi:clocks/wall-clock@0.2.1

                      +

                      Import interface wasi:clocks/wall-clock@0.2.2

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -134,16 +134,16 @@ monotonic, making it unsuitable for measuring elapsed time.

                      It is intended for reporting the current date and time for humans.


                      Types

                      -

                      record datetime

                      +

                      record datetime

                      A time and date in seconds plus nanoseconds.

                      Record Fields
                        -
                      • seconds: u64
                      • -
                      • nanoseconds: u32
                      • +
                      • seconds: u64
                      • +
                      • nanoseconds: u32

                      Functions

                      -

                      now: func

                      +

                      now: func

                      Read the current value of the clock.

                      This clock is not monotonic, therefore calling this function repeatedly will not necessarily produce a sequence of non-decreasing values.

                      @@ -153,29 +153,29 @@ also known as Unix Time.The nanoseconds field of the output is always less than 1000000000.

                      Return values
                      -

                      resolution: func

                      +

                      resolution: func

                      Query the resolution of the clock.

                      The nanoseconds field of the output is always less than 1000000000.

                      Return values
                      -

                      Import interface wasi:clocks/timezone@0.2.1

                      +

                      Import interface wasi:clocks/timezone@0.2.2


                      Types

                      -

                      type datetime

                      +

                      type datetime

                      datetime

                      -#### `record timezone-display` +#### `record timezone-display`

                      Information useful for displaying the timezone of a specific datetime.

                      This information may vary within a single timezone to reflect daylight saving time adjustments.

                      Record Fields
                      • -

                        utc-offset: s32

                        +

                        utc-offset: s32

                        The number of seconds difference between UTC time and the local time of the timezone.

                        The returned value will always be less than 86400 which is the @@ -184,7 +184,7 @@ number of seconds in a day (246060).

                        should return 0.

                      • -

                        name: string

                        +

                        name: string

                        The abbreviated name of the timezone to display to a user. The name `UTC` indicates Coordinated Universal Time. Otherwise, this should reference local standards for the name of the time zone. @@ -194,7 +194,7 @@ should be the string UTC.

                        representation of the UTC offset may be returned, such as -04:00.

                      • -

                        in-daylight-saving-time: bool

                        +

                        in-daylight-saving-time: bool

                        Whether daylight saving time is active.

                        In implementations that do not expose an actual time zone, this should return false.

                        @@ -202,7 +202,7 @@ should return false.


                      Functions

                      -

                      display: func

                      +

                      display: func

                      Return information needed to display the given datetime. This includes the UTC offset, the time zone name, and a flag indicating whether daylight saving time is active.

                      @@ -211,19 +211,19 @@ daylight saving time is active.

                      saving time.

                      Params
                      Return values
                      -

                      utc-offset: func

                      +

                      utc-offset: func

                      The same as display, but only return the UTC offset.

                      Params
                      Return values
                        -
                      • s32
                      • +
                      • s32
                      diff --git a/proposals/clocks/wit/deps.lock b/proposals/clocks/wit/deps.lock index 0d0c51ddc..0e1333bc5 100644 --- a/proposals/clocks/wit/deps.lock +++ b/proposals/clocks/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "2a74bd811adc46b5a0f19827ddbde89870e52b17615f4d0873f06fd977250caf" -sha512 = "94624f00c66e66203592cee820f80b1ba91ecdb71f682c154f25eaf71f8d8954197dcb64503bc21e72ed5e812af7eae876df47b7eb727b02db3a74a7ce0aefca" +sha256 = "6d8dbfaaaa685167c1829616dc7265f5f3cb776845879555612d56544f6d9bfc" +sha512 = "52219562c4183503169cd2947b8164e1c96974500a5adf15bbf382c5992a10a626cc89c3b319204aeda6698ce59cbca2c42f98f7fde296aa77b9db4b41154dbe" diff --git a/proposals/clocks/wit/deps/io/error.wit b/proposals/clocks/wit/deps/io/error.wit index 4ea29c469..717135f8c 100644 --- a/proposals/clocks/wit/deps/io/error.wit +++ b/proposals/clocks/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; @since(version = 0.2.0) interface error { diff --git a/proposals/clocks/wit/deps/io/poll.wit b/proposals/clocks/wit/deps/io/poll.wit index b25ac729f..49c1c5ede 100644 --- a/proposals/clocks/wit/deps/io/poll.wit +++ b/proposals/clocks/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/clocks/wit/deps/io/streams.wit b/proposals/clocks/wit/deps/io/streams.wit index b697e24d6..330f7095c 100644 --- a/proposals/clocks/wit/deps/io/streams.wit +++ b/proposals/clocks/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -18,6 +18,9 @@ interface streams { /// The last operation (a write or flush) failed before completion. /// /// More information is available in the `error` payload. + /// + /// After this, the stream will be closed. All future operations return + /// `stream-error::closed`. last-operation-failed(error), /// The stream is closed: no more input will be accepted by the /// stream. A closed output-stream will return this error on all @@ -205,6 +208,7 @@ interface streams { /// The created `pollable` is a child resource of the `output-stream`. /// Implementations may trap if the `output-stream` is dropped before /// all derived `pollable`s created with this function are dropped. + @since(version = 0.2.0) subscribe: func() -> pollable; /// Write zeroes to a stream. diff --git a/proposals/clocks/wit/deps/io/world.wit b/proposals/clocks/wit/deps/io/world.wit index 6405a4e48..f7001ccff 100644 --- a/proposals/clocks/wit/deps/io/world.wit +++ b/proposals/clocks/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index 3c24840c9..233cace4c 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.1; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/clocks/wit/timezone.wit b/proposals/clocks/wit/timezone.wit index 212da6682..349fb5703 100644 --- a/proposals/clocks/wit/timezone.wit +++ b/proposals/clocks/wit/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/clocks/wit/wall-clock.wit b/proposals/clocks/wit/wall-clock.wit index 6be069a32..ec05a1f1a 100644 --- a/proposals/clocks/wit/wall-clock.wit +++ b/proposals/clocks/wit/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index 9251ac645..e36802cc8 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; @since(version = 0.2.0) world imports { From e4201860d57ee7087e3386e87e0ca0135ed7c870 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 3 Oct 2024 18:12:57 +0200 Subject: [PATCH 1510/1772] Update to v0.2.2 --- .../filesystem/.github/workflows/main.yml | 4 +- proposals/filesystem/imports.md | 638 +++++++++--------- proposals/filesystem/wit/deps.lock | 8 +- .../wit/deps/clocks/monotonic-clock.wit | 4 +- .../filesystem/wit/deps/clocks/timezone.wit | 2 +- .../filesystem/wit/deps/clocks/wall-clock.wit | 2 +- .../filesystem/wit/deps/clocks/world.wit | 2 +- proposals/filesystem/wit/deps/io/error.wit | 2 +- proposals/filesystem/wit/deps/io/poll.wit | 2 +- proposals/filesystem/wit/deps/io/streams.wit | 6 +- proposals/filesystem/wit/deps/io/world.wit | 2 +- proposals/filesystem/wit/preopens.wit | 2 +- proposals/filesystem/wit/types.wit | 6 +- proposals/filesystem/wit/world.wit | 2 +- 14 files changed, 344 insertions(+), 338 deletions(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index 52a7b9e8a..d42ff77d1 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -18,6 +18,6 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v21 + - uses: WebAssembly/wit-abi-up-to-date@v22 with: - wit-bindgen: '0.28.0' + wit-bindgen: '0.33.0' diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index ba18125cf..6d958eea1 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -1,20 +1,20 @@ -

                      World imports

                      +

                      World imports

                      -

                      Import interface wasi:io/error@0.2.1

                      +

                      Import interface wasi:io/error@0.2.2


                      Types

                      -

                      resource error

                      +

                      resource error

                      A resource which represents some error information.

                      The only method provided by this resource is to-debug-string, which provides some human-readable information about the error.

                      @@ -29,7 +29,7 @@ parameter and returns an option<wasi:filesystem/types/error-code>The set of functions which can "downcast" an error into a more concrete type is open.

                      Functions

                      -

                      [method]error.to-debug-string: func

                      +

                      [method]error.to-debug-string: func

                      Returns a string that is suitable to assist humans in debugging this error.

                      WARNING: The returned string should not be consumed mechanically! @@ -38,41 +38,41 @@ details. Parsing this string is a major platform-compatibility hazard.

                      Params
                      Return values
                        -
                      • string
                      • +
                      • string
                      -

                      Import interface wasi:io/poll@0.2.1

                      +

                      Import interface wasi:io/poll@0.2.2

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      Types

                      -

                      resource pollable

                      +

                      resource pollable

                      pollable represents a single I/O event which may be ready, or not.

                      Functions

                      -

                      [method]pollable.ready: func

                      +

                      [method]pollable.ready: func

                      Return the readiness of a pollable. This function never blocks.

                      Returns true when the pollable is ready, and false otherwise.

                      Params
                      Return values
                        -
                      • bool
                      • +
                      • bool
                      -

                      [method]pollable.block: func

                      +

                      [method]pollable.block: func

                      block returns immediately if the pollable is ready, and otherwise blocks until ready.

                      This function is equivalent to calling poll.poll on a list containing only this pollable.

                      Params
                      -

                      poll: func

                      +

                      poll: func

                      Poll for completion on a set of pollables.

                      This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

                      @@ -91,42 +91,44 @@ the pollables has an error, it is indicated by marking the source as being ready for I/O.

                      Params
                      Return values
                        -
                      • list<u32>
                      • +
                      • list<u32>
                      -

                      Import interface wasi:io/streams@0.2.1

                      +

                      Import interface wasi:io/streams@0.2.2

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


                      Types

                      -

                      type error

                      +

                      type error

                      error

                      -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

                      -#### `variant stream-error` +#### `variant stream-error`

                      An error for input-stream and output-stream operations.

                      Variant Cases
                      • -

                        last-operation-failed: own<error>

                        +

                        last-operation-failed: own<error>

                        The last operation (a write or flush) failed before completion.

                        More information is available in the error payload.

                        +

                        After this, the stream will be closed. All future operations return +stream-error::closed.

                      • -

                        closed

                        +

                        closed

                        The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

                      -

                      resource input-stream

                      +

                      resource input-stream

                      An input bytestream.

                      input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are @@ -134,7 +136,7 @@ promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

                      -

                      resource output-stream

                      +

                      resource output-stream

                      An output bytestream.

                      output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also @@ -146,7 +148,7 @@ polled for using wasi:io/poll.

                      progress may result in the data being lost. Before dropping the stream, be sure to fully flush your writes.

                      Functions

                      -

                      [method]input-stream.read: func

                      +

                      [method]input-stream.read: func

                      Perform a non-blocking read from the stream.

                      When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -170,51 +172,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

                      Params
                      Return values
                      -

                      [method]input-stream.blocking-read: func

                      +

                      [method]input-stream.blocking-read: func

                      Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

                      Params
                      Return values
                      -

                      [method]input-stream.skip: func

                      +

                      [method]input-stream.skip: func

                      Skip bytes from a stream. Returns number of bytes skipped.

                      Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

                      Params
                      Return values
                      -

                      [method]input-stream.blocking-skip: func

                      +

                      [method]input-stream.blocking-skip: func

                      Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

                      Params
                      Return values
                      -

                      [method]input-stream.subscribe: func

                      +

                      [method]input-stream.subscribe: func

                      Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -223,13 +225,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

                      Params
                      Return values
                      -

                      [method]output-stream.check-write: func

                      +

                      [method]output-stream.check-write: func

                      Check readiness for writing. This function never blocks.

                      Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -239,13 +241,13 @@ become ready when this function will report at least 1 byte, or an error.

                      Params
                      Return values
                      -

                      [method]output-stream.write: func

                      +

                      [method]output-stream.write: func

                      Perform a write. This function never blocks.

                      When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -258,14 +260,14 @@ length of less than or equal to n. Otherwise, this function will trap.

                      the last call to check-write provided a permit.

                      Params
                      Return values
                      -

                      [method]output-stream.blocking-write-and-flush: func

                      +

                      [method]output-stream.blocking-write-and-flush: func

                      Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                      This is a convenience wrapper around the use of check-write, @@ -289,14 +291,14 @@ let _ = this.check-write(); // eliding error handling

                      Params
                      Return values
                      -

                      [method]output-stream.flush: func

                      +

                      [method]output-stream.flush: func

                      Request to flush buffered output. This function never blocks.

                      This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -307,24 +309,24 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

                      Params
                      Return values
                      -

                      [method]output-stream.blocking-flush: func

                      +

                      [method]output-stream.blocking-flush: func

                      Request to flush buffered output, and block until flush completes and stream is ready for writing again.

                      Params
                      Return values
                      -

                      [method]output-stream.subscribe: func

                      +

                      [method]output-stream.subscribe: func

                      Create a pollable which will resolve once the output-stream is ready for more writing, or an error has occurred. When this pollable is ready, check-write will return ok(n) with n>0, or an @@ -335,13 +337,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

                      Params
                      Return values
                      -

                      [method]output-stream.write-zeroes: func

                      +

                      [method]output-stream.write-zeroes: func

                      Write zeroes to a stream.

                      This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -349,14 +351,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

                      Params
                      Return values
                      -

                      [method]output-stream.blocking-write-zeroes-and-flush: func

                      +

                      [method]output-stream.blocking-write-zeroes-and-flush: func

                      Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                      @@ -380,14 +382,14 @@ let _ = this.check-write(); // eliding error handling
                      Params
                      Return values
                      -

                      [method]output-stream.splice: func

                      +

                      [method]output-stream.splice: func

                      Read from one stream and write to another.

                      The behavior of splice is equivalent to:

                        @@ -402,30 +404,30 @@ let _ = this.check-write(); // eliding error handling than len.

                        Params
                        Return values
                        -

                        [method]output-stream.blocking-splice: func

                        +

                        [method]output-stream.blocking-splice: func

                        Read from one stream and write to another, with blocking.

                        This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

                        Params
                        Return values
                        -

                        Import interface wasi:clocks/wall-clock@0.2.1

                        +

                        Import interface wasi:clocks/wall-clock@0.2.2

                        WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                        @@ -438,16 +440,16 @@ monotonic, making it unsuitable for measuring elapsed time.

                        It is intended for reporting the current date and time for humans.


                        Types

                        -

                        record datetime

                        +

                        record datetime

                        A time and date in seconds plus nanoseconds.

                        Record Fields
                          -
                        • seconds: u64
                        • -
                        • nanoseconds: u32
                        • +
                        • seconds: u64
                        • +
                        • nanoseconds: u32

                        Functions

                        -

                        now: func

                        +

                        now: func

                        Read the current value of the clock.

                        This clock is not monotonic, therefore calling this function repeatedly will not necessarily produce a sequence of non-decreasing values.

                        @@ -457,16 +459,16 @@ also known as Unix Time.The nanoseconds field of the output is always less than 1000000000.

                        Return values
                        -

                        resolution: func

                        +

                        resolution: func

                        Query the resolution of the clock.

                        The nanoseconds field of the output is always less than 1000000000.

                        Return values
                        -

                        Import interface wasi:filesystem/types@0.2.1

                        +

                        Import interface wasi:filesystem/types@0.2.2

                        WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                        @@ -486,75 +488,75 @@ underlying filesystem, the function fails with WASI filesystem path resolution.


                        Types

                        -

                        type input-stream

                        +

                        type input-stream

                        input-stream

                        -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

                        -#### `type error` +#### `type error` [`error`](#error)

                        -#### `type datetime` +#### `type datetime` [`datetime`](#datetime)

                        -#### `type filesize` +#### `type filesize` `u64`

                        File size or length of a region within a file. -

                        enum descriptor-type

                        +

                        enum descriptor-type

                        The type of a filesystem object referenced by a descriptor.

                        Note: This was called filetype in earlier versions of WASI.

                        Enum Cases
                        • -

                          unknown

                          +

                          unknown

                          The type of the descriptor or file is unknown or is different from any of the other types specified.

                        • -

                          block-device

                          +

                          block-device

                          The descriptor refers to a block device inode.

                        • -

                          character-device

                          +

                          character-device

                          The descriptor refers to a character device inode.

                        • -

                          directory

                          +

                          directory

                          The descriptor refers to a directory inode.

                        • -

                          fifo

                          +

                          fifo

                          The descriptor refers to a named pipe.

                        • -

                          symbolic-link

                          +

                          symbolic-link

                          The file refers to a symbolic link inode.

                        • -

                          regular-file

                          +

                          regular-file

                          The descriptor refers to a regular file inode.

                        • -

                          socket

                          +

                          socket

                          The descriptor refers to a socket.

                        -

                        flags descriptor-flags

                        +

                        flags descriptor-flags

                        Descriptor flags.

                        Note: This was called fdflags in earlier versions of WASI.

                        Flags members
                        • -

                          read:

                          +

                          read:

                          Read mode: Data can be read.

                        • -

                          write:

                          +

                          write:

                          Write mode: Data can be written to.

                        • -

                          file-integrity-sync:

                          +

                          file-integrity-sync:

                          Request that writes be performed according to synchronized I/O file integrity completion. The data stored in the file and the file's metadata are synchronized. This is similar to `O_SYNC` in POSIX. @@ -563,7 +565,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

                        • -

                          data-integrity-sync:

                          +

                          data-integrity-sync:

                          Request that writes be performed according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. This is similar to `O_DSYNC` in POSIX. @@ -572,7 +574,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

                        • -

                          requested-write-sync:

                          +

                          requested-write-sync:

                          Requests that reads be performed at the same level of integrity requested for writes. This is similar to `O_RSYNC` in POSIX.

                          The precise semantics of this operation have not yet been defined for @@ -580,7 +582,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

                        • -

                          mutate-directory:

                          +

                          mutate-directory:

                          Mutating directories mode: Directory contents may be mutated.

                          When this flag is unset on a descriptor, operations using the descriptor which would create, rename, delete, modify the data or @@ -590,107 +592,107 @@ they would otherwise succeed.

                          This may only be set on directories.

                        -

                        flags path-flags

                        +

                        flags path-flags

                        Flags determining the method of how paths are resolved.

                        Flags members
                          -
                        • symlink-follow:

                          As long as the resolved path corresponds to a symbolic link, it is +

                        • symlink-follow:

                          As long as the resolved path corresponds to a symbolic link, it is expanded.

                        -

                        flags open-flags

                        +

                        flags open-flags

                        Open flags used by open-at.

                        Flags members
                        • -

                          create:

                          +

                          create:

                          Create file if it does not exist, similar to `O_CREAT` in POSIX.

                        • -

                          directory:

                          +

                          directory:

                          Fail if not a directory, similar to `O_DIRECTORY` in POSIX.

                        • -

                          exclusive:

                          +

                          exclusive:

                          Fail if file already exists, similar to `O_EXCL` in POSIX.

                        • -

                          truncate:

                          +

                          truncate:

                          Truncate file to size 0, similar to `O_TRUNC` in POSIX.

                        -

                        type link-count

                        +

                        type link-count

                        u64

                        Number of hard links to an inode. -

                        record descriptor-stat

                        +

                        record descriptor-stat

                        File attributes.

                        Note: This was called filestat in earlier versions of WASI.

                        Record Fields
                        • -

                          type: descriptor-type

                          +

                          type: descriptor-type

                          File type.

                        • -

                          link-count: link-count

                          +

                          link-count: link-count

                          Number of hard links to the file.

                        • -

                          size: filesize

                          +

                          size: filesize

                          For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link.

                        • -

                          data-access-timestamp: option<datetime>

                          +

                          data-access-timestamp: option<datetime>

                          Last data access timestamp.

                          If the option is none, the platform doesn't maintain an access timestamp for this file.

                        • -

                          data-modification-timestamp: option<datetime>

                          +

                          data-modification-timestamp: option<datetime>

                          Last data modification timestamp.

                          If the option is none, the platform doesn't maintain a modification timestamp for this file.

                        • -

                          status-change-timestamp: option<datetime>

                          +

                          status-change-timestamp: option<datetime>

                          Last file status-change timestamp.

                          If the option is none, the platform doesn't maintain a status-change timestamp for this file.

                        -

                        variant new-timestamp

                        +

                        variant new-timestamp

                        When setting a timestamp, this gives the value to set it to.

                        Variant Cases
                        • -

                          no-change

                          +

                          no-change

                          Leave the timestamp set to its previous value.

                        • -

                          now

                          +

                          now

                          Set the timestamp to the current time of the system clock associated with the filesystem.

                        • -

                          timestamp: datetime

                          +

                          timestamp: datetime

                          Set the timestamp to the given value.

                        -

                        record directory-entry

                        +

                        record directory-entry

                        A directory entry.

                        Record Fields
                        • -

                          type: descriptor-type

                          +

                          type: descriptor-type

                          The type of the file referred to by this directory entry.

                        • -

                          name: string

                          +

                          name: string

                          The name of the object.

                        -

                        enum error-code

                        +

                        enum error-code

                        Error codes returned by functions, similar to errno in POSIX. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -698,211 +700,211 @@ merely for alignment with POSIX.

                        Enum Cases
                        • -

                          access

                          +

                          access

                          Permission denied, similar to `EACCES` in POSIX.

                        • -

                          would-block

                          +

                          would-block

                          Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX.

                        • -

                          already

                          +

                          already

                          Connection already in progress, similar to `EALREADY` in POSIX.

                        • -

                          bad-descriptor

                          +

                          bad-descriptor

                          Bad descriptor, similar to `EBADF` in POSIX.

                        • -

                          busy

                          +

                          busy

                          Device or resource busy, similar to `EBUSY` in POSIX.

                        • -

                          deadlock

                          +

                          deadlock

                          Resource deadlock would occur, similar to `EDEADLK` in POSIX.

                        • -

                          quota

                          +

                          quota

                          Storage quota exceeded, similar to `EDQUOT` in POSIX.

                        • -

                          exist

                          +

                          exist

                          File exists, similar to `EEXIST` in POSIX.

                        • -

                          file-too-large

                          +

                          file-too-large

                          File too large, similar to `EFBIG` in POSIX.

                        • -

                          illegal-byte-sequence

                          +

                          illegal-byte-sequence

                          Illegal byte sequence, similar to `EILSEQ` in POSIX.

                        • -

                          in-progress

                          +

                          in-progress

                          Operation in progress, similar to `EINPROGRESS` in POSIX.

                        • -

                          interrupted

                          +

                          interrupted

                          Interrupted function, similar to `EINTR` in POSIX.

                        • -

                          invalid

                          +

                          invalid

                          Invalid argument, similar to `EINVAL` in POSIX.

                        • -

                          io

                          +

                          io

                          I/O error, similar to `EIO` in POSIX.

                        • -

                          is-directory

                          +

                          is-directory

                          Is a directory, similar to `EISDIR` in POSIX.

                        • -

                          loop

                          +

                          loop

                          Too many levels of symbolic links, similar to `ELOOP` in POSIX.

                        • -

                          too-many-links

                          +

                          too-many-links

                          Too many links, similar to `EMLINK` in POSIX.

                        • -

                          message-size

                          +

                          message-size

                          Message too large, similar to `EMSGSIZE` in POSIX.

                        • -

                          name-too-long

                          +

                          name-too-long

                          Filename too long, similar to `ENAMETOOLONG` in POSIX.

                        • -

                          no-device

                          +

                          no-device

                          No such device, similar to `ENODEV` in POSIX.

                        • -

                          no-entry

                          +

                          no-entry

                          No such file or directory, similar to `ENOENT` in POSIX.

                        • -

                          no-lock

                          +

                          no-lock

                          No locks available, similar to `ENOLCK` in POSIX.

                        • -

                          insufficient-memory

                          +

                          insufficient-memory

                          Not enough space, similar to `ENOMEM` in POSIX.

                        • -

                          insufficient-space

                          +

                          insufficient-space

                          No space left on device, similar to `ENOSPC` in POSIX.

                        • -

                          not-directory

                          +

                          not-directory

                          Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX.

                        • -

                          not-empty

                          +

                          not-empty

                          Directory not empty, similar to `ENOTEMPTY` in POSIX.

                        • -

                          not-recoverable

                          +

                          not-recoverable

                          State not recoverable, similar to `ENOTRECOVERABLE` in POSIX.

                        • -

                          unsupported

                          +

                          unsupported

                          Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX.

                        • -

                          no-tty

                          +

                          no-tty

                          Inappropriate I/O control operation, similar to `ENOTTY` in POSIX.

                        • -

                          no-such-device

                          +

                          no-such-device

                          No such device or address, similar to `ENXIO` in POSIX.

                        • -

                          overflow

                          +

                          overflow

                          Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX.

                        • -

                          not-permitted

                          +

                          not-permitted

                          Operation not permitted, similar to `EPERM` in POSIX.

                        • -

                          pipe

                          +

                          pipe

                          Broken pipe, similar to `EPIPE` in POSIX.

                        • -

                          read-only

                          +

                          read-only

                          Read-only file system, similar to `EROFS` in POSIX.

                        • -

                          invalid-seek

                          +

                          invalid-seek

                          Invalid seek, similar to `ESPIPE` in POSIX.

                        • -

                          text-file-busy

                          +

                          text-file-busy

                          Text file busy, similar to `ETXTBSY` in POSIX.

                        • -

                          cross-device

                          +

                          cross-device

                          Cross-device link, similar to `EXDEV` in POSIX.

                        -

                        enum advice

                        +

                        enum advice

                        File or memory access pattern advisory information.

                        Enum Cases
                        • -

                          normal

                          +

                          normal

                          The application has no advice to give on its behavior with respect to the specified data.

                        • -

                          sequential

                          +

                          sequential

                          The application expects to access the specified data sequentially from lower offsets to higher offsets.

                        • -

                          random

                          +

                          random

                          The application expects to access the specified data in a random order.

                        • -

                          will-need

                          +

                          will-need

                          The application expects to access the specified data in the near future.

                        • -

                          dont-need

                          +

                          dont-need

                          The application expects that it will not access the specified data in the near future.

                        • -

                          no-reuse

                          +

                          no-reuse

                          The application expects to access the specified data once and then not reuse it thereafter.

                        -

                        record metadata-hash-value

                        +

                        record metadata-hash-value

                        A 128-bit hash value, split into parts because wasm doesn't have a 128-bit integer type.

                        Record Fields
                        • -

                          lower: u64

                          +

                          lower: u64

                          64 bits of a 128-bit hash value.

                        • -

                          upper: u64

                          +

                          upper: u64

                          Another 64 bits of a 128-bit hash value.

                        -

                        resource descriptor

                        +

                        resource descriptor

                        A descriptor is a reference to a filesystem object, which may be a file, directory, named pipe, special file, or other object on which filesystem calls may be made.

                        -

                        resource directory-entry-stream

                        +

                        resource directory-entry-stream

                        A stream of directory entries.

                        Functions

                        -

                        [method]descriptor.read-via-stream: func

                        +

                        [method]descriptor.read-via-stream: func

                        Return a stream for reading from a file, if available.

                        May fail with an error-code describing why the file cannot be read.

                        Multiple read, write, and append streams may be active on the same open @@ -910,81 +912,81 @@ file and they do not interfere with each other.

                        Note: This allows using read-stream, which is similar to read in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.write-via-stream: func

                        +

                        [method]descriptor.write-via-stream: func

                        Return a stream for writing to a file, if available.

                        May fail with an error-code describing why the file cannot be written.

                        Note: This allows using write-stream, which is similar to write in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.append-via-stream: func

                        +

                        [method]descriptor.append-via-stream: func

                        Return a stream for appending to a file, if available.

                        May fail with an error-code describing why the file cannot be appended.

                        Note: This allows using write-stream, which is similar to write with O_APPEND in in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.advise: func

                        +

                        [method]descriptor.advise: func

                        Provide file advisory information on a descriptor.

                        This is similar to posix_fadvise in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.sync-data: func

                        +

                        [method]descriptor.sync-data: func

                        Synchronize the data of a file to disk.

                        This function succeeds with no effect if the file descriptor is not opened for writing.

                        Note: This is similar to fdatasync in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.get-flags: func

                        +

                        [method]descriptor.get-flags: func

                        Get flags associated with a descriptor.

                        Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

                        Note: This returns the value that was the fs_flags value returned from fdstat_get in earlier versions of WASI.

                        Params
                        Return values
                        -

                        [method]descriptor.get-type: func

                        +

                        [method]descriptor.get-type: func

                        Get the dynamic type of a descriptor.

                        Note: This returns the same value as the type field of the fd-stat returned by stat, stat-at and similar.

                        @@ -994,40 +996,40 @@ by fstat in POSIX.

                        from fdstat_get in earlier versions of WASI.

                        Params
                        Return values
                        -

                        [method]descriptor.set-size: func

                        +

                        [method]descriptor.set-size: func

                        Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.

                        Note: This was called fd_filestat_set_size in earlier versions of WASI.

                        Params
                        Return values
                        -

                        [method]descriptor.set-times: func

                        +

                        [method]descriptor.set-times: func

                        Adjust the timestamps of an open file or directory.

                        Note: This is similar to futimens in POSIX.

                        Note: This was called fd_filestat_set_times in earlier versions of WASI.

                        Params
                        Return values
                        -

                        [method]descriptor.read: func

                        +

                        [method]descriptor.read: func

                        Read from a descriptor, without using and updating the descriptor's offset.

                        This function returns a list of bytes containing the data that was read, along with a bool which, when true, indicates that the end of the @@ -1038,15 +1040,15 @@ if the I/O operation is interrupted.

                        Note: This is similar to pread in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.write: func

                        +

                        [method]descriptor.write: func

                        Write to a descriptor, without using and updating the descriptor's offset.

                        It is valid to write past the end of a file; the file is extended to the extent of the write, with bytes between the previous end and the start of @@ -1055,15 +1057,15 @@ the write set to zero.

                        Note: This is similar to pwrite in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.read-directory: func

                        +

                        [method]descriptor.read-directory: func

                        Read directory entries from a directory.

                        On filesystems where directories contain entries referring to themselves and their parents, often named . and .. respectively, these entries @@ -1073,38 +1075,38 @@ directory. Multiple streams may be active on the same directory, and they do not interfere with each other.

                        Params
                        Return values
                        -

                        [method]descriptor.sync: func

                        +

                        [method]descriptor.sync: func

                        Synchronize the data and metadata of a file to disk.

                        This function succeeds with no effect if the file descriptor is not opened for writing.

                        Note: This is similar to fsync in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.create-directory-at: func

                        +

                        [method]descriptor.create-directory-at: func

                        Create a directory.

                        Note: This is similar to mkdirat in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.stat: func

                        +

                        [method]descriptor.stat: func

                        Return the attributes of an open file or directory.

                        Note: This is similar to fstat in POSIX, except that it does not return device and inode information. For testing whether two descriptors refer to @@ -1114,13 +1116,13 @@ modified, use metadata-hash.

                        Note: This was called fd_filestat_get in earlier versions of WASI.

                        Params
                        Return values
                        -

                        [method]descriptor.stat-at: func

                        +

                        [method]descriptor.stat-at: func

                        Return the attributes of a file or directory.

                        Note: This is similar to fstatat in POSIX, except that it does not return device and inode information. See the stat description for a @@ -1128,47 +1130,47 @@ discussion of alternatives.

                        Note: This was called path_filestat_get in earlier versions of WASI.

                        Params
                        Return values
                        -

                        [method]descriptor.set-times-at: func

                        +

                        [method]descriptor.set-times-at: func

                        Adjust the timestamps of a file or directory.

                        Note: This is similar to utimensat in POSIX.

                        Note: This was called path_filestat_set_times in earlier versions of WASI.

                        Params
                        Return values
                        -

                        [method]descriptor.link-at: func

                        +

                        [method]descriptor.link-at: func

                        Create a hard link.

                        Note: This is similar to linkat in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.open-at: func

                        +

                        [method]descriptor.open-at: func

                        Open a file or directory.

                        If flags contains descriptor-flags::mutate-directory, and the base descriptor doesn't have descriptor-flags::mutate-directory set, @@ -1180,86 +1182,86 @@ contains truncate or create, and the base descriptor d

                        Note: This is similar to openat in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.readlink-at: func

                        +

                        [method]descriptor.readlink-at: func

                        Read the contents of a symbolic link.

                        If the contents contain an absolute or rooted path in the underlying filesystem, this function fails with error-code::not-permitted.

                        Note: This is similar to readlinkat in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.remove-directory-at: func

                        +

                        [method]descriptor.remove-directory-at: func

                        Remove a directory.

                        Return error-code::not-empty if the directory is not empty.

                        Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.rename-at: func

                        +

                        [method]descriptor.rename-at: func

                        Rename a filesystem object.

                        Note: This is similar to renameat in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.symlink-at: func

                        +

                        [method]descriptor.symlink-at: func

                        Create a symbolic link (also known as a "symlink").

                        If old-path starts with /, the function fails with error-code::not-permitted.

                        Note: This is similar to symlinkat in POSIX.

                        Params
                          -
                        • self: borrow<descriptor>
                        • -
                        • old-path: string
                        • -
                        • new-path: string
                        • +
                        • self: borrow<descriptor>
                        • +
                        • old-path: string
                        • +
                        • new-path: string
                        Return values
                        -

                        [method]descriptor.unlink-file-at: func

                        +

                        [method]descriptor.unlink-file-at: func

                        Unlink a filesystem object that is not a directory.

                        Return error-code::is-directory if the path refers to a directory. Note: This is similar to unlinkat(fd, path, 0) in POSIX.

                        Params
                        Return values
                        -

                        [method]descriptor.is-same-object: func

                        +

                        [method]descriptor.is-same-object: func

                        Test whether two descriptors refer to the same filesystem object.

                        In POSIX, this corresponds to testing whether the two descriptors have the same device (st_dev) and inode (st_ino or d_ino) numbers. @@ -1267,14 +1269,14 @@ wasi-filesystem does not expose device and inode numbers, so this function may be used instead.

                        Params
                        Return values
                          -
                        • bool
                        • +
                        • bool
                        -

                        [method]descriptor.metadata-hash: func

                        +

                        [method]descriptor.metadata-hash: func

                        Return a hash of the metadata associated with a filesystem object referred to by a descriptor.

                        This returns a hash of the last-modification timestamp and file size, and @@ -1294,37 +1296,37 @@ computed hash.

                        However, none of these is required.

                        Params
                        Return values
                        -

                        [method]descriptor.metadata-hash-at: func

                        +

                        [method]descriptor.metadata-hash-at: func

                        Return a hash of the metadata associated with a filesystem object referred to by a directory descriptor and a relative path.

                        This performs the same hash computation as metadata-hash.

                        Params
                        Return values
                        -

                        [method]directory-entry-stream.read-directory-entry: func

                        +

                        [method]directory-entry-stream.read-directory-entry: func

                        Read a single directory entry from a directory-entry-stream.

                        Params
                        Return values
                        -

                        filesystem-error-code: func

                        +

                        filesystem-error-code: func

                        Attempts to extract a filesystem-related error-code from the stream error provided.

                        Stream operations which return stream-error::last-operation-failed @@ -1335,23 +1337,23 @@ filesystem-related information about the error to return.

                        errors are filesystem-related errors.

                        Params
                        Return values
                        -

                        Import interface wasi:filesystem/preopens@0.2.1

                        +

                        Import interface wasi:filesystem/preopens@0.2.2


                        Types

                        -

                        type descriptor

                        +

                        type descriptor

                        descriptor

                        ----

                        Functions

                        -

                        get-directories: func

                        +

                        get-directories: func

                        Return the set of preopened directories, and their path.

                        Return values
                        diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index 2b50429e0..5cab24d2b 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "ea9d69ee803bc176e23e5268f5e24a2ac485dd1f62a0ab4c748e9d3f901f576f" -sha512 = "5efc22927c46cd56c41e5549ec775561c7fac2ea0d365abc0b55396d9475a7c9f984077a81f84a44a726f1c008fd2fadbffffa4fa53ecd5fbfd05afd379ab428" +sha256 = "c2da62619d1067646316e8592b583d77036d778e28b1154353e0825956b3d6aa" +sha512 = "4d409fc38b31646fc5de70160e81bd3fa67f9c99b4d24543b4fd40a922c7545739869521b8a997efb675d0816de8b001b6af7950e0cb0bc823d89b9f07b286c4" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "2a74bd811adc46b5a0f19827ddbde89870e52b17615f4d0873f06fd977250caf" -sha512 = "94624f00c66e66203592cee820f80b1ba91ecdb71f682c154f25eaf71f8d8954197dcb64503bc21e72ed5e812af7eae876df47b7eb727b02db3a74a7ce0aefca" +sha256 = "6d8dbfaaaa685167c1829616dc7265f5f3cb776845879555612d56544f6d9bfc" +sha512 = "52219562c4183503169cd2947b8164e1c96974500a5adf15bbf382c5992a10a626cc89c3b319204aeda6698ce59cbca2c42f98f7fde296aa77b9db4b41154dbe" diff --git a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit index 3c24840c9..233cace4c 100644 --- a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.1; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/filesystem/wit/deps/clocks/timezone.wit b/proposals/filesystem/wit/deps/clocks/timezone.wit index 212da6682..349fb5703 100644 --- a/proposals/filesystem/wit/deps/clocks/timezone.wit +++ b/proposals/filesystem/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/filesystem/wit/deps/clocks/wall-clock.wit b/proposals/filesystem/wit/deps/clocks/wall-clock.wit index 6be069a32..ec05a1f1a 100644 --- a/proposals/filesystem/wit/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/filesystem/wit/deps/clocks/world.wit b/proposals/filesystem/wit/deps/clocks/world.wit index 9251ac645..e36802cc8 100644 --- a/proposals/filesystem/wit/deps/clocks/world.wit +++ b/proposals/filesystem/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/filesystem/wit/deps/io/error.wit b/proposals/filesystem/wit/deps/io/error.wit index 4ea29c469..717135f8c 100644 --- a/proposals/filesystem/wit/deps/io/error.wit +++ b/proposals/filesystem/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; @since(version = 0.2.0) interface error { diff --git a/proposals/filesystem/wit/deps/io/poll.wit b/proposals/filesystem/wit/deps/io/poll.wit index b25ac729f..49c1c5ede 100644 --- a/proposals/filesystem/wit/deps/io/poll.wit +++ b/proposals/filesystem/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index b697e24d6..330f7095c 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -18,6 +18,9 @@ interface streams { /// The last operation (a write or flush) failed before completion. /// /// More information is available in the `error` payload. + /// + /// After this, the stream will be closed. All future operations return + /// `stream-error::closed`. last-operation-failed(error), /// The stream is closed: no more input will be accepted by the /// stream. A closed output-stream will return this error on all @@ -205,6 +208,7 @@ interface streams { /// The created `pollable` is a child resource of the `output-stream`. /// Implementations may trap if the `output-stream` is dropped before /// all derived `pollable`s created with this function are dropped. + @since(version = 0.2.0) subscribe: func() -> pollable; /// Write zeroes to a stream. diff --git a/proposals/filesystem/wit/deps/io/world.wit b/proposals/filesystem/wit/deps/io/world.wit index 6405a4e48..f7001ccff 100644 --- a/proposals/filesystem/wit/deps/io/world.wit +++ b/proposals/filesystem/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit index ca2f726af..410bec1dc 100644 --- a/proposals/filesystem/wit/preopens.wit +++ b/proposals/filesystem/wit/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.1; +package wasi:filesystem@0.2.2; @since(version = 0.2.0) interface preopens { diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index db3f3c614..49e0a30bb 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.1; +package wasi:filesystem@0.2.2; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.1; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.2.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.1.{datetime}; + use wasi:clocks/wall-clock@0.2.2.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index af0146cbc..8064bd64b 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.1; +package wasi:filesystem@0.2.2; @since(version = 0.2.0) world imports { From 2572951ba625e33a765dd850c52979f820b17912 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 3 Oct 2024 18:21:50 +0200 Subject: [PATCH 1511/1772] Update to v0.2.2 --- proposals/sockets/.github/workflows/main.yml | 5 +- proposals/sockets/imports.md | 772 +++++++++--------- proposals/sockets/wit/deps.lock | 8 +- .../wit/deps/clocks/monotonic-clock.wit | 4 +- .../sockets/wit/deps/clocks/timezone.wit | 2 +- .../sockets/wit/deps/clocks/wall-clock.wit | 2 +- proposals/sockets/wit/deps/clocks/world.wit | 2 +- proposals/sockets/wit/deps/io/error.wit | 2 +- proposals/sockets/wit/deps/io/poll.wit | 2 +- proposals/sockets/wit/deps/io/streams.wit | 6 +- proposals/sockets/wit/deps/io/world.wit | 2 +- proposals/sockets/wit/ip-name-lookup.wit | 2 +- proposals/sockets/wit/network.wit | 2 +- proposals/sockets/wit/tcp.wit | 6 +- proposals/sockets/wit/udp.wit | 2 +- proposals/sockets/wit/world.wit | 2 +- 16 files changed, 414 insertions(+), 407 deletions(-) diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index 52a7b9e8a..248ca1d9d 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -18,6 +18,7 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v21 + - uses: WebAssembly/wit-abi-up-to-date@v22 with: - wit-bindgen: '0.28.0' + wit-bindgen: '0.33.0' + wasm-tools: '1.218.0' diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 737ff7d7f..f494ad32f 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -1,29 +1,29 @@ -

                        World imports

                        +

                        World imports

                        -

                        Import interface wasi:sockets/network@0.2.1

                        +

                        Import interface wasi:sockets/network@0.2.2


                        Types

                        -

                        resource network

                        +

                        resource network

                        An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                        -

                        enum error-code

                        +

                        enum error-code

                        Error codes.

                        In theory, every API can return any error code. In practice, API's typically only return the errors documented per API @@ -39,220 +39,220 @@ combined with a couple of errors that are always possible:

                        Enum Cases
                        • -

                          unknown

                          +

                          unknown

                          Unknown error

                        • -

                          access-denied

                          +

                          access-denied

                          Access denied.

                          POSIX equivalent: EACCES, EPERM

                        • -

                          not-supported

                          +

                          not-supported

                          The operation is not supported.

                          POSIX equivalent: EOPNOTSUPP

                        • -

                          invalid-argument

                          +

                          invalid-argument

                          One of the arguments is invalid.

                          POSIX equivalent: EINVAL

                        • -

                          out-of-memory

                          +

                          out-of-memory

                          Not enough memory to complete the operation.

                          POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY

                        • -

                          timeout

                          +

                          timeout

                          The operation timed out before it could finish completely.

                        • -

                          concurrency-conflict

                          +

                          concurrency-conflict

                          This operation is incompatible with another asynchronous operation that is already in progress.

                          POSIX equivalent: EALREADY

                        • -

                          not-in-progress

                          +

                          not-in-progress

                          Trying to finish an asynchronous operation that: - has not been started yet, or: - was already finished by a previous `finish-*` call.

                          Note: this is scheduled to be removed when futures are natively supported.

                        • -

                          would-block

                          +

                          would-block

                          The operation has been aborted because it could not be completed immediately.

                          Note: this is scheduled to be removed when futures are natively supported.

                        • -

                          invalid-state

                          +

                          invalid-state

                          The operation is not valid in the socket's current state.

                        • -

                          new-socket-limit

                          +

                          new-socket-limit

                          A new socket resource could not be created because of a system limit.

                        • -

                          address-not-bindable

                          +

                          address-not-bindable

                          A bind operation failed because the provided address is not an address that the `network` can bind to.

                        • -

                          address-in-use

                          +

                          address-in-use

                          A bind operation failed because the provided address is already in use or because there are no ephemeral ports available.

                        • -

                          remote-unreachable

                          +

                          remote-unreachable

                          The remote address is not reachable

                        • -

                          connection-refused

                          +

                          connection-refused

                          The TCP connection was forcefully rejected

                        • -

                          connection-reset

                          +

                          connection-reset

                          The TCP connection was reset.

                        • -

                          connection-aborted

                          +

                          connection-aborted

                          A TCP connection was aborted.

                        • -

                          datagram-too-large

                          +

                          datagram-too-large

                          The size of a datagram sent to a UDP socket exceeded the maximum supported size.

                        • -

                          name-unresolvable

                          +

                          name-unresolvable

                          Name does not exist or has no suitable associated IP addresses.

                        • -

                          temporary-resolver-failure

                          +

                          temporary-resolver-failure

                          A temporary failure in name resolution occurred.

                        • -

                          permanent-resolver-failure

                          +

                          permanent-resolver-failure

                          A permanent failure in name resolution occurred.

                        -

                        enum ip-address-family

                        +

                        enum ip-address-family

                        Enum Cases
                        • -

                          ipv4

                          +

                          ipv4

                          Similar to `AF_INET` in POSIX.

                        • -

                          ipv6

                          +

                          ipv6

                          Similar to `AF_INET6` in POSIX.

                        -

                        tuple ipv4-address

                        +

                        tuple ipv4-address

                        Tuple Fields
                          -
                        • 0: u8
                        • -
                        • 1: u8
                        • -
                        • 2: u8
                        • -
                        • 3: u8
                        • +
                        • 0: u8
                        • +
                        • 1: u8
                        • +
                        • 2: u8
                        • +
                        • 3: u8
                        -

                        tuple ipv6-address

                        +

                        tuple ipv6-address

                        Tuple Fields
                          -
                        • 0: u16
                        • -
                        • 1: u16
                        • -
                        • 2: u16
                        • -
                        • 3: u16
                        • -
                        • 4: u16
                        • -
                        • 5: u16
                        • -
                        • 6: u16
                        • -
                        • 7: u16
                        • +
                        • 0: u16
                        • +
                        • 1: u16
                        • +
                        • 2: u16
                        • +
                        • 3: u16
                        • +
                        • 4: u16
                        • +
                        • 5: u16
                        • +
                        • 6: u16
                        • +
                        • 7: u16
                        -

                        variant ip-address

                        +

                        variant ip-address

                        Variant Cases
                        -

                        record ipv4-socket-address

                        +

                        record ipv4-socket-address

                        Record Fields
                        -

                        record ipv6-socket-address

                        +

                        record ipv6-socket-address

                        Record Fields
                        • -

                          port: u16

                          +

                          port: u16

                          sin6_port

                        • -

                          flow-info: u32

                          +

                          flow-info: u32

                          sin6_flowinfo

                        • -

                          address: ipv6-address

                          +

                          address: ipv6-address

                          sin6_addr

                        • -

                          scope-id: u32

                          +

                          scope-id: u32

                          sin6_scope_id

                        -

                        variant ip-socket-address

                        +

                        variant ip-socket-address

                        Variant Cases
                        -

                        Import interface wasi:sockets/instance-network@0.2.1

                        +

                        Import interface wasi:sockets/instance-network@0.2.2

                        This interface provides a value-export of the default network handle..


                        Types

                        -

                        type network

                        +

                        type network

                        network

                        ----

                        Functions

                        -

                        instance-network: func

                        +

                        instance-network: func

                        Get a handle to the default network.

                        Return values
                        -

                        Import interface wasi:io/poll@0.2.1

                        +

                        Import interface wasi:io/poll@0.2.2

                        A poll API intended to let users wait for I/O events on multiple handles at once.


                        Types

                        -

                        resource pollable

                        +

                        resource pollable

                        pollable represents a single I/O event which may be ready, or not.

                        Functions

                        -

                        [method]pollable.ready: func

                        +

                        [method]pollable.ready: func

                        Return the readiness of a pollable. This function never blocks.

                        Returns true when the pollable is ready, and false otherwise.

                        Params
                        Return values
                          -
                        • bool
                        • +
                        • bool
                        -

                        [method]pollable.block: func

                        +

                        [method]pollable.block: func

                        block returns immediately if the pollable is ready, and otherwise blocks until ready.

                        This function is equivalent to calling poll.poll on a list containing only this pollable.

                        Params
                        -

                        poll: func

                        +

                        poll: func

                        Poll for completion on a set of pollables.

                        This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

                        @@ -271,56 +271,56 @@ the pollables has an error, it is indicated by marking the source as being ready for I/O.

                        Params
                        Return values
                          -
                        • list<u32>
                        • +
                        • list<u32>
                        -

                        Import interface wasi:sockets/udp@0.2.1

                        +

                        Import interface wasi:sockets/udp@0.2.2


                        Types

                        -

                        type pollable

                        +

                        type pollable

                        pollable

                        -#### `type network` +#### `type network` [`network`](#network)

                        -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                        -#### `type ip-socket-address` +#### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address)

                        -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                        -#### `record incoming-datagram` +#### `record incoming-datagram`

                        A received datagram.

                        Record Fields
                        • -

                          data: list<u8>

                          +

                          data: list<u8>

                          The payload.

                          Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes.

                        • -

                          remote-address: ip-socket-address

                          +

                          remote-address: ip-socket-address

                          The source address.

                          This field is guaranteed to match the remote address the stream was initialized with, if any.

                          Equivalent to the src_addr out parameter of recvfrom.

                        -

                        record outgoing-datagram

                        +

                        record outgoing-datagram

                        A datagram to be sent out.

                        Record Fields
                        • -

                          data: list<u8>

                          +

                          data: list<u8>

                          The payload.

                        • -

                          remote-address: option<ip-socket-address>

                          +

                          remote-address: option<ip-socket-address>

                          The destination address.

                          The requirements on this field depend on how the stream was initialized:

                            @@ -330,13 +330,13 @@ being ready for I/O.

                            If this value is None, the send operation is equivalent to send in POSIX. Otherwise it is equivalent to sendto.

                          -

                          resource udp-socket

                          +

                          resource udp-socket

                          A UDP socket handle.

                          -

                          resource incoming-datagram-stream

                          -

                          resource outgoing-datagram-stream

                          +

                          resource incoming-datagram-stream

                          +

                          resource outgoing-datagram-stream


                          Functions

                          -

                          [method]udp-socket.start-bind: func

                          +

                          [method]udp-socket.start-bind: func

                          Bind the socket to a specific network on the provided IP address and port.

                          If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -365,24 +365,24 @@ don't want to make use of this ability can simply call the native

                        Params
                        Return values
                        -

                        [method]udp-socket.finish-bind: func

                        +

                        [method]udp-socket.finish-bind: func

                        Params
                        Return values
                        -

                        [method]udp-socket.stream: func

                        +

                        [method]udp-socket.stream: func

                        Set up inbound & outbound communication channels, optionally to a specific peer.

                        This function only changes the local socket configuration and does not generate any network traffic. On success, the remote-address of the socket is updated. The local-address may be updated as well, @@ -423,14 +423,14 @@ if (remote_address is Some) {

                  Params
                  Return values
                  -

                  [method]udp-socket.local-address: func

                  +

                  [method]udp-socket.local-address: func

                  Get the current bound address.

                  POSIX mentions:

                  @@ -451,13 +451,13 @@ stored in the object pointed to by address is unspecified.

                  Params
                  Return values
                  -

                  [method]udp-socket.remote-address: func

                  +

                  [method]udp-socket.remote-address: func

                  Get the address the socket is currently streaming to.

                  Typical errors

                    @@ -472,24 +472,24 @@ stored in the object pointed to by address is unspecified.

                  Params
                  Return values
                  -

                  [method]udp-socket.address-family: func

                  +

                  [method]udp-socket.address-family: func

                  Whether this is a IPv4 or IPv6 socket.

                  Equivalent to the SO_DOMAIN socket option.

                  Params
                  Return values
                  -

                  [method]udp-socket.unicast-hop-limit: func

                  +

                  [method]udp-socket.unicast-hop-limit: func

                  Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                  If the provided value is 0, an invalid-argument error is returned.

                  Typical errors

                  @@ -498,23 +498,23 @@ stored in the object pointed to by address is unspecified.

                  Params
                  Return values
                  -

                  [method]udp-socket.set-unicast-hop-limit: func

                  +

                  [method]udp-socket.set-unicast-hop-limit: func

                  Params
                  Return values
                  -

                  [method]udp-socket.receive-buffer-size: func

                  +

                  [method]udp-socket.receive-buffer-size: func

                  The kernel buffer space reserved for sends/receives on this socket.

                  If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -526,54 +526,54 @@ I.e. after setting a value, reading the same setting back may return a different

                  Params
                  Return values
                  -

                  [method]udp-socket.set-receive-buffer-size: func

                  +

                  [method]udp-socket.set-receive-buffer-size: func

                  Params
                  Return values
                  -

                  [method]udp-socket.send-buffer-size: func

                  +

                  [method]udp-socket.send-buffer-size: func

                  Params
                  Return values
                  -

                  [method]udp-socket.set-send-buffer-size: func

                  +

                  [method]udp-socket.set-send-buffer-size: func

                  Params
                  Return values
                  -

                  [method]udp-socket.subscribe: func

                  +

                  [method]udp-socket.subscribe: func

                  Create a pollable which will resolve once the socket is ready for I/O.

                  Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

                  Params
                  Return values
                  -

                  [method]incoming-datagram-stream.receive: func

                  +

                  [method]incoming-datagram-stream.receive: func

                  Receive messages on the socket.

                  This function attempts to receive up to max-results datagrams on the socket without blocking. The returned list may contain fewer elements than requested, but never more.

                  @@ -601,26 +601,26 @@ This function never returns error(would-block).
                  Params
                  Return values
                  -

                  [method]incoming-datagram-stream.subscribe: func

                  +

                  [method]incoming-datagram-stream.subscribe: func

                  Create a pollable which will resolve once the stream is ready to receive again.

                  Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

                  Params
                  Return values
                  -

                  [method]outgoing-datagram-stream.check-send: func

                  +

                  [method]outgoing-datagram-stream.check-send: func

                  Check readiness for sending. This function never blocks.

                  Returns the number of datagrams permitted for the next call to send, or an error. Calling send with more datagrams than this function has @@ -631,13 +631,13 @@ error.

                  Never returns would-block.

                  Params
                  Return values
                  -

                  [method]outgoing-datagram-stream.send: func

                  +

                  [method]outgoing-datagram-stream.send: func

                  Send messages on the socket.

                  This function attempts to send all provided datagrams on the socket without blocking and returns how many messages were actually sent (or queued for sending). This function never @@ -672,43 +672,43 @@ either check-send was not called or datagrams contains

                  Params
                  Return values
                  -

                  [method]outgoing-datagram-stream.subscribe: func

                  +

                  [method]outgoing-datagram-stream.subscribe: func

                  Create a pollable which will resolve once the stream is ready to send again.

                  Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

                  Params
                  Return values
                  -

                  Import interface wasi:sockets/udp-create-socket@0.2.1

                  +

                  Import interface wasi:sockets/udp-create-socket@0.2.2


                  Types

                  -

                  type network

                  +

                  type network

                  network

                  -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                  -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                  -#### `type udp-socket` +#### `type udp-socket` [`udp-socket`](#udp_socket)

                  ----

                  Functions

                  -

                  create-udp-socket: func

                  +

                  create-udp-socket: func

                  Create a new UDP socket.

                  Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX. On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

                  @@ -730,16 +730,16 @@ the socket is effectively an in-memory configuration object, unable to communica
                  Params
                  Return values
                  -

                  Import interface wasi:io/error@0.2.1

                  +

                  Import interface wasi:io/error@0.2.2


                  Types

                  -

                  resource error

                  +

                  resource error

                  A resource which represents some error information.

                  The only method provided by this resource is to-debug-string, which provides some human-readable information about the error.

                  @@ -754,7 +754,7 @@ parameter and returns an option<wasi:filesystem/types/error-code>The set of functions which can "downcast" an error into a more concrete type is open.

                  Functions

                  -

                  [method]error.to-debug-string: func

                  +

                  [method]error.to-debug-string: func

                  Returns a string that is suitable to assist humans in debugging this error.

                  WARNING: The returned string should not be consumed mechanically! @@ -763,42 +763,44 @@ details. Parsing this string is a major platform-compatibility hazard.

                  Params
                  Return values
                    -
                  • string
                  • +
                  • string
                  -

                  Import interface wasi:io/streams@0.2.1

                  +

                  Import interface wasi:io/streams@0.2.2

                  WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                  In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


                  Types

                  -

                  type error

                  +

                  type error

                  error

                  -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

                  -#### `variant stream-error` +#### `variant stream-error`

                  An error for input-stream and output-stream operations.

                  Variant Cases
                  • -

                    last-operation-failed: own<error>

                    +

                    last-operation-failed: own<error>

                    The last operation (a write or flush) failed before completion.

                    More information is available in the error payload.

                    +

                    After this, the stream will be closed. All future operations return +stream-error::closed.

                  • -

                    closed

                    +

                    closed

                    The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

                  -

                  resource input-stream

                  +

                  resource input-stream

                  An input bytestream.

                  input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are @@ -806,7 +808,7 @@ promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

                  -

                  resource output-stream

                  +

                  resource output-stream

                  An output bytestream.

                  output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also @@ -818,7 +820,7 @@ polled for using wasi:io/poll.

                  progress may result in the data being lost. Before dropping the stream, be sure to fully flush your writes.

                  Functions

                  -

                  [method]input-stream.read: func

                  +

                  [method]input-stream.read: func

                  Perform a non-blocking read from the stream.

                  When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -842,51 +844,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

                  Params
                  Return values
                  -

                  [method]input-stream.blocking-read: func

                  +

                  [method]input-stream.blocking-read: func

                  Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

                  Params
                  Return values
                  -

                  [method]input-stream.skip: func

                  +

                  [method]input-stream.skip: func

                  Skip bytes from a stream. Returns number of bytes skipped.

                  Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

                  Params
                  Return values
                  -

                  [method]input-stream.blocking-skip: func

                  +

                  [method]input-stream.blocking-skip: func

                  Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

                  Params
                  Return values
                  -

                  [method]input-stream.subscribe: func

                  +

                  [method]input-stream.subscribe: func

                  Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -895,13 +897,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

                  Params
                  Return values
                  -

                  [method]output-stream.check-write: func

                  +

                  [method]output-stream.check-write: func

                  Check readiness for writing. This function never blocks.

                  Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -911,13 +913,13 @@ become ready when this function will report at least 1 byte, or an error.

                  Params
                  Return values
                  -

                  [method]output-stream.write: func

                  +

                  [method]output-stream.write: func

                  Perform a write. This function never blocks.

                  When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -930,14 +932,14 @@ length of less than or equal to n. Otherwise, this function will trap.

                  the last call to check-write provided a permit.

                  Params
                  Return values
                  -

                  [method]output-stream.blocking-write-and-flush: func

                  +

                  [method]output-stream.blocking-write-and-flush: func

                  Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                  This is a convenience wrapper around the use of check-write, @@ -961,14 +963,14 @@ let _ = this.check-write(); // eliding error handling

                  Params
                  Return values
                  -

                  [method]output-stream.flush: func

                  +

                  [method]output-stream.flush: func

                  Request to flush buffered output. This function never blocks.

                  This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -979,24 +981,24 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

                  Params
                  Return values
                  -

                  [method]output-stream.blocking-flush: func

                  +

                  [method]output-stream.blocking-flush: func

                  Request to flush buffered output, and block until flush completes and stream is ready for writing again.

                  Params
                  Return values
                  -

                  [method]output-stream.subscribe: func

                  +

                  [method]output-stream.subscribe: func

                  Create a pollable which will resolve once the output-stream is ready for more writing, or an error has occurred. When this pollable is ready, check-write will return ok(n) with n>0, or an @@ -1007,13 +1009,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

                  Params
                  Return values
                  -

                  [method]output-stream.write-zeroes: func

                  +

                  [method]output-stream.write-zeroes: func

                  Write zeroes to a stream.

                  This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -1021,14 +1023,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

                  Params
                  Return values
                  -

                  [method]output-stream.blocking-write-zeroes-and-flush: func

                  +

                  [method]output-stream.blocking-write-zeroes-and-flush: func

                  Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                  @@ -1052,14 +1054,14 @@ let _ = this.check-write(); // eliding error handling
                  Params
                  Return values
                  -

                  [method]output-stream.splice: func

                  +

                  [method]output-stream.splice: func

                  Read from one stream and write to another.

                  The behavior of splice is equivalent to:

                    @@ -1074,30 +1076,30 @@ let _ = this.check-write(); // eliding error handling than len.

                    Params
                    Return values
                    -

                    [method]output-stream.blocking-splice: func

                    +

                    [method]output-stream.blocking-splice: func

                    Read from one stream and write to another, with blocking.

                    This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

                    Params
                    Return values
                    -

                    Import interface wasi:clocks/monotonic-clock@0.2.1

                    +

                    Import interface wasi:clocks/monotonic-clock@0.2.2

                    WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                    It is intended to be portable at least between Unix-family platforms and @@ -1106,100 +1108,100 @@ Windows.

                    successive reads of the clock will produce non-decreasing values.


                    Types

                    -

                    type pollable

                    +

                    type pollable

                    pollable

                    -#### `type instant` +#### `type instant` `u64`

                    An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. -

                    type duration

                    +

                    type duration

                    u64

                    A duration of time, in nanoseconds.


                    Functions

                    -

                    now: func

                    +

                    now: func

                    Read the current value of the clock.

                    The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

                    Return values
                    -

                    resolution: func

                    +

                    resolution: func

                    Query the resolution of the clock. Returns the duration of time corresponding to a clock tick.

                    Return values
                    -

                    subscribe-instant: func

                    +

                    subscribe-instant: func

                    Create a pollable which will resolve once the specified instant has occurred.

                    Params
                    Return values
                    -

                    subscribe-duration: func

                    +

                    subscribe-duration: func

                    Create a pollable that will resolve after the specified duration has elapsed from the time this function is invoked.

                    Params
                    Return values
                    -

                    Import interface wasi:sockets/tcp@0.2.1

                    +

                    Import interface wasi:sockets/tcp@0.2.2


                    Types

                    -

                    type input-stream

                    +

                    type input-stream

                    input-stream

                    -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

                    -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

                    -#### `type duration` +#### `type duration` [`duration`](#duration)

                    -#### `type network` +#### `type network` [`network`](#network)

                    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                    -#### `type ip-socket-address` +#### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address)

                    -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                    -#### `enum shutdown-type` +#### `enum shutdown-type`

                    Enum Cases
                    • -

                      receive

                      +

                      receive

                      Similar to `SHUT_RD` in POSIX.

                    • -

                      send

                      +

                      send

                      Similar to `SHUT_WR` in POSIX.

                    • -

                      both

                      +

                      both

                      Similar to `SHUT_RDWR` in POSIX.

                    -

                    resource tcp-socket

                    +

                    resource tcp-socket

                    A TCP socket resource.

                    The socket can be in one of the following states:

                      @@ -1221,7 +1223,7 @@ the term "bound" without backticks it actually means: in the bou network::error-code type, TCP socket methods may always return error(invalid-state) when in the closed state.

                      Functions

                      -

                      [method]tcp-socket.start-bind: func

                      +

                      [method]tcp-socket.start-bind: func

                      Bind the socket to a specific network on the provided IP address and port.

                      If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -1260,24 +1262,24 @@ don't want to make use of this ability can simply call the native

                    Params
                    Return values
                    -

                    [method]tcp-socket.finish-bind: func

                    +

                    [method]tcp-socket.finish-bind: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.start-connect: func

                    +

                    [method]tcp-socket.start-connect: func

                    Connect to a remote endpoint.

                    On success:

                    Params
                    Return values
                    -

                    [method]tcp-socket.finish-listen: func

                    +

                    [method]tcp-socket.finish-listen: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.accept: func

                    +

                    [method]tcp-socket.accept: func

                    Accept a new client socket.

                    The returned socket is bound and in the connected state. The following properties are inherited from the listener socket:

                      @@ -1412,13 +1414,13 @@ a pair of streams that can be used to read & write to the connection.

                    Params
                    Return values
                    -

                    [method]tcp-socket.local-address: func

                    +

                    [method]tcp-socket.local-address: func

                    Get the bound local address.

                    POSIX mentions:

                    @@ -1439,13 +1441,13 @@ stored in the object pointed to by address is unspecified.

                    Params
                    Return values
                    -

                    [method]tcp-socket.remote-address: func

                    +

                    [method]tcp-socket.remote-address: func

                    Get the remote address.

                    Typical errors

                      @@ -1460,35 +1462,35 @@ stored in the object pointed to by address is unspecified.

                    Params
                    Return values
                    -

                    [method]tcp-socket.is-listening: func

                    +

                    [method]tcp-socket.is-listening: func

                    Whether the socket is in the listening state.

                    Equivalent to the SO_ACCEPTCONN socket option.

                    Params
                    Return values
                      -
                    • bool
                    • +
                    • bool
                    -

                    [method]tcp-socket.address-family: func

                    +

                    [method]tcp-socket.address-family: func

                    Whether this is a IPv4 or IPv6 socket.

                    Equivalent to the SO_DOMAIN socket option.

                    Params
                    Return values
                    -

                    [method]tcp-socket.set-listen-backlog-size: func

                    +

                    [method]tcp-socket.set-listen-backlog-size: func

                    Hints the desired listen queue size. Implementations are free to ignore this.

                    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded.

                    @@ -1500,14 +1502,14 @@ Any other value will never cause an error, but it might be silently clamped and/
                    Params
                    Return values
                    -

                    [method]tcp-socket.keep-alive-enabled: func

                    +

                    [method]tcp-socket.keep-alive-enabled: func

                    Enables or disables keepalive.

                    The keepalive behavior can be adjusted using:

                      @@ -1519,23 +1521,23 @@ These properties can be configured while keep-alive-enabled is fals

                      Equivalent to the SO_KEEPALIVE socket option.

                      Params
                      Return values
                      -

                      [method]tcp-socket.set-keep-alive-enabled: func

                      +

                      [method]tcp-socket.set-keep-alive-enabled: func

                      Params
                      Return values
                      -

                      [method]tcp-socket.keep-alive-idle-time: func

                      +

                      [method]tcp-socket.keep-alive-idle-time: func

                      Amount of time the connection has to be idle before TCP starts sending keepalive packets.

                      If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -1547,23 +1549,23 @@ I.e. after setting a value, reading the same setting back may return a different

                    Params
                    Return values
                    -

                    [method]tcp-socket.set-keep-alive-idle-time: func

                    +

                    [method]tcp-socket.set-keep-alive-idle-time: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.keep-alive-interval: func

                    +

                    [method]tcp-socket.keep-alive-interval: func

                    The time between keepalive packets.

                    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -1575,23 +1577,23 @@ I.e. after setting a value, reading the same setting back may return a different

                    Params
                    Return values
                    -

                    [method]tcp-socket.set-keep-alive-interval: func

                    +

                    [method]tcp-socket.set-keep-alive-interval: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.keep-alive-count: func

                    +

                    [method]tcp-socket.keep-alive-count: func

                    The maximum amount of keepalive packets TCP should send before aborting the connection.

                    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -1603,23 +1605,23 @@ I.e. after setting a value, reading the same setting back may return a different

                    Params
                    Return values
                    -

                    [method]tcp-socket.set-keep-alive-count: func

                    +

                    [method]tcp-socket.set-keep-alive-count: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.hop-limit: func

                    +

                    [method]tcp-socket.hop-limit: func

                    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                    If the provided value is 0, an invalid-argument error is returned.

                    Typical errors

                    @@ -1628,23 +1630,23 @@ I.e. after setting a value, reading the same setting back may return a different
                    Params
                    Return values
                    -

                    [method]tcp-socket.set-hop-limit: func

                    +

                    [method]tcp-socket.set-hop-limit: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.receive-buffer-size: func

                    +

                    [method]tcp-socket.receive-buffer-size: func

                    The kernel buffer space reserved for sends/receives on this socket.

                    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -1656,42 +1658,42 @@ I.e. after setting a value, reading the same setting back may return a different

                    Params
                    Return values
                    -

                    [method]tcp-socket.set-receive-buffer-size: func

                    +

                    [method]tcp-socket.set-receive-buffer-size: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.send-buffer-size: func

                    +

                    [method]tcp-socket.send-buffer-size: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.set-send-buffer-size: func

                    +

                    [method]tcp-socket.set-send-buffer-size: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.subscribe: func

                    +

                    [method]tcp-socket.subscribe: func

                    Create a pollable which can be used to poll for, or block on, completion of any of the asynchronous operations of this socket.

                    When finish-bind, finish-listen, finish-connect or accept @@ -1707,13 +1709,13 @@ for more information.

                    It's planned to be removed when future is natively supported in Preview3.

                    Params
                    Return values
                    -

                    [method]tcp-socket.shutdown: func

                    +

                    [method]tcp-socket.shutdown: func

                    Initiate a graceful shutdown.

                    • receive: The socket is not expecting to receive any data from @@ -1740,31 +1742,31 @@ has no effect and returns ok.

                    Params
                    Return values
                    -

                    Import interface wasi:sockets/tcp-create-socket@0.2.1

                    +

                    Import interface wasi:sockets/tcp-create-socket@0.2.2


                    Types

                    -

                    type network

                    +

                    type network

                    network

                    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                    -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                    -#### `type tcp-socket` +#### `type tcp-socket` [`tcp-socket`](#tcp_socket)

                    ----

                    Functions

                    -

                    create-tcp-socket: func

                    +

                    create-tcp-socket: func

                    Create a new TCP socket.

                    Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX. On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

                    @@ -1786,31 +1788,31 @@ is called, the socket is effectively an in-memory configuration object, unable t
                    Params
                    Return values
                    -

                    Import interface wasi:sockets/ip-name-lookup@0.2.1

                    +

                    Import interface wasi:sockets/ip-name-lookup@0.2.2


                    Types

                    -

                    type pollable

                    +

                    type pollable

                    pollable

                    -#### `type network` +#### `type network` [`network`](#network)

                    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                    -#### `type ip-address` +#### `type ip-address` [`ip-address`](#ip_address)

                    -#### `resource resolve-address-stream` +#### `resource resolve-address-stream`


                    Functions

                    -

                    resolve-addresses: func

                    +

                    resolve-addresses: func

                    Resolve an internet host name to a list of IP addresses.

                    Unicode domain names are automatically converted to ASCII using IDNA encoding. If the input is an IP address string, the address is parsed and returned @@ -1832,14 +1834,14 @@ to (asynchronously) fetch the results.

                    Params
                    Return values
                    -

                    [method]resolve-address-stream.resolve-next-address: func

                    +

                    [method]resolve-address-stream.resolve-next-address: func

                    Returns the next address from the resolver.

                    This function should be called multiple times. On each call, it will return the next address in connection order preference. If all @@ -1854,21 +1856,21 @@ addresses have been exhausted, this function returns none.

                    Params
                    Return values
                    -

                    [method]resolve-address-stream.subscribe: func

                    +

                    [method]resolve-address-stream.subscribe: func

                    Create a pollable which will resolve once the stream is ready for I/O.

                    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

                    Params
                    Return values
                    diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index 2b50429e0..5cab24d2b 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "ea9d69ee803bc176e23e5268f5e24a2ac485dd1f62a0ab4c748e9d3f901f576f" -sha512 = "5efc22927c46cd56c41e5549ec775561c7fac2ea0d365abc0b55396d9475a7c9f984077a81f84a44a726f1c008fd2fadbffffa4fa53ecd5fbfd05afd379ab428" +sha256 = "c2da62619d1067646316e8592b583d77036d778e28b1154353e0825956b3d6aa" +sha512 = "4d409fc38b31646fc5de70160e81bd3fa67f9c99b4d24543b4fd40a922c7545739869521b8a997efb675d0816de8b001b6af7950e0cb0bc823d89b9f07b286c4" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "2a74bd811adc46b5a0f19827ddbde89870e52b17615f4d0873f06fd977250caf" -sha512 = "94624f00c66e66203592cee820f80b1ba91ecdb71f682c154f25eaf71f8d8954197dcb64503bc21e72ed5e812af7eae876df47b7eb727b02db3a74a7ce0aefca" +sha256 = "6d8dbfaaaa685167c1829616dc7265f5f3cb776845879555612d56544f6d9bfc" +sha512 = "52219562c4183503169cd2947b8164e1c96974500a5adf15bbf382c5992a10a626cc89c3b319204aeda6698ce59cbca2c42f98f7fde296aa77b9db4b41154dbe" diff --git a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit index 3c24840c9..233cace4c 100644 --- a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.1; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/sockets/wit/deps/clocks/timezone.wit b/proposals/sockets/wit/deps/clocks/timezone.wit index 212da6682..349fb5703 100644 --- a/proposals/sockets/wit/deps/clocks/timezone.wit +++ b/proposals/sockets/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/sockets/wit/deps/clocks/wall-clock.wit b/proposals/sockets/wit/deps/clocks/wall-clock.wit index 6be069a32..ec05a1f1a 100644 --- a/proposals/sockets/wit/deps/clocks/wall-clock.wit +++ b/proposals/sockets/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/sockets/wit/deps/clocks/world.wit b/proposals/sockets/wit/deps/clocks/world.wit index 9251ac645..e36802cc8 100644 --- a/proposals/sockets/wit/deps/clocks/world.wit +++ b/proposals/sockets/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/sockets/wit/deps/io/error.wit b/proposals/sockets/wit/deps/io/error.wit index 4ea29c469..717135f8c 100644 --- a/proposals/sockets/wit/deps/io/error.wit +++ b/proposals/sockets/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; @since(version = 0.2.0) interface error { diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit index b25ac729f..49c1c5ede 100644 --- a/proposals/sockets/wit/deps/io/poll.wit +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index b697e24d6..330f7095c 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -18,6 +18,9 @@ interface streams { /// The last operation (a write or flush) failed before completion. /// /// More information is available in the `error` payload. + /// + /// After this, the stream will be closed. All future operations return + /// `stream-error::closed`. last-operation-failed(error), /// The stream is closed: no more input will be accepted by the /// stream. A closed output-stream will return this error on all @@ -205,6 +208,7 @@ interface streams { /// The created `pollable` is a child resource of the `output-stream`. /// Implementations may trap if the `output-stream` is dropped before /// all derived `pollable`s created with this function are dropped. + @since(version = 0.2.0) subscribe: func() -> pollable; /// Write zeroes to a stream. diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit index 6405a4e48..f7001ccff 100644 --- a/proposals/sockets/wit/deps/io/world.wit +++ b/proposals/sockets/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index dc56f3000..8d6dcec31 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 993c4ce61..7f2d86a4c 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.1.{error}; + use wasi:io/error@0.2.2.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index bae5a29ec..91f421b44 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{input-stream, output-stream}; + use wasi:io/streams@0.2.2.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.1.{duration}; + use wasi:clocks/monotonic-clock@0.2.2.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index b289e4943..328d91683 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index a1d42670e..6e349c756 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.1; +package wasi:sockets@0.2.2; @since(version = 0.2.0) world imports { From 2d8beacbf60ebaacdf256878f26ec7666bdbf13a Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 3 Oct 2024 19:05:35 +0200 Subject: [PATCH 1512/1772] doc: change WASI Preview2 -> WASI 0.2 --- proposals/sockets/imports.md | 10 +++++----- proposals/sockets/wit/ip-name-lookup.wit | 2 +- proposals/sockets/wit/tcp.wit | 2 +- proposals/sockets/wit/udp.wit | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index f494ad32f..661c21725 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -563,7 +563,7 @@ I.e. after setting a value, reading the same setting back may return a different

                    [method]udp-socket.subscribe: func

                    Create a pollable which will resolve once the socket is ready for I/O.

                    -

                    Note: this function is here for WASI Preview2 only. +

                    Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                    Params
                      @@ -610,7 +610,7 @@ This function never returns error(would-block).

                    [method]incoming-datagram-stream.subscribe: func

                    Create a pollable which will resolve once the stream is ready to receive again.

                    -

                    Note: this function is here for WASI Preview2 only. +

                    Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                    Params
                      @@ -681,7 +681,7 @@ either check-send was not called or datagrams contains

                    [method]outgoing-datagram-stream.subscribe: func

                    Create a pollable which will resolve once the stream is ready to send again.

                    -

                    Note: this function is here for WASI Preview2 only. +

                    Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                    Params
                      @@ -1705,7 +1705,7 @@ in progress at the time of calling subscribe (if any). Theoreticall (re)used for the remainder of the socket's lifetime.

                      See https://github.com/WebAssembly/wasi-sockets/blob/main/TcpSocketOperationalSemantics.md#pollable-readiness for more information.

                      -

                      Note: this function is here for WASI Preview2 only. +

                      Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                      Params
                        @@ -1864,7 +1864,7 @@ addresses have been exhausted, this function returns none.

                      [method]resolve-address-stream.subscribe: func

                      Create a pollable which will resolve once the stream is ready for I/O.

                      -

                      Note: this function is here for WASI Preview2 only. +

                      Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                      Params
                        diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index 8d6dcec31..d3ab88aed 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -48,7 +48,7 @@ interface ip-name-lookup { /// Create a `pollable` which will resolve once the stream is ready for I/O. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 91f421b44..728822dfa 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -353,7 +353,7 @@ interface tcp { /// See /// for more information. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 328d91683..d8acb2d29 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -184,7 +184,7 @@ interface udp { /// Create a `pollable` which will resolve once the socket is ready for I/O. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; @@ -220,7 +220,7 @@ interface udp { /// Create a `pollable` which will resolve once the stream is ready to receive again. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; @@ -280,7 +280,7 @@ interface udp { /// Create a `pollable` which will resolve once the stream is ready to send again. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; From 7b587c47eb119e7accae7dd70e2bcea7626248dc Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 3 Oct 2024 20:44:15 +0200 Subject: [PATCH 1513/1772] Update to v0.2.2 --- proposals/cli/.github/workflows/main.yml | 5 +- proposals/cli/command.md | 1399 ++++++++--------- proposals/cli/imports.md | 1397 ++++++++-------- proposals/cli/wit/command.wit | 2 +- proposals/cli/wit/deps.lock | 20 +- .../cli/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/cli/wit/deps/clocks/timezone.wit | 2 +- proposals/cli/wit/deps/clocks/wall-clock.wit | 2 +- proposals/cli/wit/deps/clocks/world.wit | 2 +- .../cli/wit/deps/filesystem/preopens.wit | 2 +- proposals/cli/wit/deps/filesystem/types.wit | 12 +- proposals/cli/wit/deps/filesystem/world.wit | 2 +- proposals/cli/wit/deps/io/error.wit | 2 +- proposals/cli/wit/deps/io/poll.wit | 2 +- proposals/cli/wit/deps/io/streams.wit | 6 +- proposals/cli/wit/deps/io/world.wit | 2 +- .../cli/wit/deps/random/insecure-seed.wit | 2 +- proposals/cli/wit/deps/random/insecure.wit | 2 +- proposals/cli/wit/deps/random/random.wit | 2 +- proposals/cli/wit/deps/random/world.wit | 2 +- .../cli/wit/deps/sockets/ip-name-lookup.wit | 4 +- proposals/cli/wit/deps/sockets/network.wit | 16 + proposals/cli/wit/deps/sockets/tcp.wit | 8 +- proposals/cli/wit/deps/sockets/udp.wit | 8 +- proposals/cli/wit/deps/sockets/world.wit | 2 +- proposals/cli/wit/imports.wit | 12 +- proposals/cli/wit/stdio.wit | 6 +- 27 files changed, 1467 insertions(+), 1458 deletions(-) diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml index ecc71c41f..88e43c754 100644 --- a/proposals/cli/.github/workflows/main.yml +++ b/proposals/cli/.github/workflows/main.yml @@ -18,8 +18,9 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v21 + - uses: WebAssembly/wit-abi-up-to-date@v22 with: - wit-bindgen: '0.28.0' + wit-bindgen: '0.33.0' + wasm-tools: '1.218.0' worlds: 'command imports' features: 'cli-exit-with-code' diff --git a/proposals/cli/command.md b/proposals/cli/command.md index b6394017d..7da1f925c 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -1,46 +1,46 @@ -

                        World command

                        +

                        World command

                        -

                        Import interface wasi:cli/environment@0.2.1

                        +

                        Import interface wasi:cli/environment@0.2.2


                        Functions

                        -

                        get-environment: func

                        +

                        get-environment: func

                        Get the POSIX-style environment variables.

                        Each environment variable is provided as a pair of string variable names and string value.

                        @@ -49,31 +49,31 @@ in the component model, this import function should return the same values each time it is called.

                        Return values
                          -
                        • list<(string, string)>
                        • +
                        • list<(string, string)>
                        -

                        get-arguments: func

                        +

                        get-arguments: func

                        Get the POSIX-style arguments to the program.

                        Return values
                          -
                        • list<string>
                        • +
                        • list<string>
                        -

                        initial-cwd: func

                        +

                        initial-cwd: func

                        Return a path that programs should use as their initial current working directory, interpreting . as shorthand for this.

                        Return values
                          -
                        • option<string>
                        • +
                        • option<string>
                        -

                        Import interface wasi:cli/exit@0.2.1

                        +

                        Import interface wasi:cli/exit@0.2.2


                        Functions

                        -

                        exit: func

                        +

                        exit: func

                        Exit the current instance and any linked instances.

                        Params
                          -
                        • status: result
                        • +
                        • status: result
                        -

                        exit-with-code: func

                        +

                        exit-with-code: func

                        Exit the current instance and any linked instances, reporting the specified status code to the host.

                        The meaning of the code depends on the context, with 0 usually meaning @@ -82,12 +82,12 @@ specified status code to the host.

                        without the connotation that something bad has happened.

                        Params
                          -
                        • status-code: u8
                        • +
                        • status-code: u8
                        -

                        Import interface wasi:io/error@0.2.1

                        +

                        Import interface wasi:io/error@0.2.2


                        Types

                        -

                        resource error

                        +

                        resource error

                        A resource which represents some error information.

                        The only method provided by this resource is to-debug-string, which provides some human-readable information about the error.

                        @@ -102,7 +102,7 @@ parameter and returns an option<wasi:filesystem/types/error-code>The set of functions which can "downcast" an error into a more concrete type is open.

                        Functions

                        -

                        [method]error.to-debug-string: func

                        +

                        [method]error.to-debug-string: func

                        Returns a string that is suitable to assist humans in debugging this error.

                        WARNING: The returned string should not be consumed mechanically! @@ -111,41 +111,41 @@ details. Parsing this string is a major platform-compatibility hazard.

                        Params
                        Return values
                          -
                        • string
                        • +
                        • string
                        -

                        Import interface wasi:io/poll@0.2.1

                        +

                        Import interface wasi:io/poll@0.2.2

                        A poll API intended to let users wait for I/O events on multiple handles at once.


                        Types

                        -

                        resource pollable

                        +

                        resource pollable

                        pollable represents a single I/O event which may be ready, or not.

                        Functions

                        -

                        [method]pollable.ready: func

                        +

                        [method]pollable.ready: func

                        Return the readiness of a pollable. This function never blocks.

                        Returns true when the pollable is ready, and false otherwise.

                        Params
                        Return values
                          -
                        • bool
                        • +
                        • bool
                        -

                        [method]pollable.block: func

                        +

                        [method]pollable.block: func

                        block returns immediately if the pollable is ready, and otherwise blocks until ready.

                        This function is equivalent to calling poll.poll on a list containing only this pollable.

                        Params
                        -

                        poll: func

                        +

                        poll: func

                        Poll for completion on a set of pollables.

                        This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

                        @@ -164,42 +164,44 @@ the pollables has an error, it is indicated by marking the source as being ready for I/O.

                        Params
                        Return values
                          -
                        • list<u32>
                        • +
                        • list<u32>
                        -

                        Import interface wasi:io/streams@0.2.1

                        +

                        Import interface wasi:io/streams@0.2.2

                        WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                        In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


                        Types

                        -

                        type error

                        +

                        type error

                        error

                        -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

                        -#### `variant stream-error` +#### `variant stream-error`

                        An error for input-stream and output-stream operations.

                        Variant Cases
                        • -

                          last-operation-failed: own<error>

                          +

                          last-operation-failed: own<error>

                          The last operation (a write or flush) failed before completion.

                          More information is available in the error payload.

                          +

                          After this, the stream will be closed. All future operations return +stream-error::closed.

                        • -

                          closed

                          +

                          closed

                          The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

                        -

                        resource input-stream

                        +

                        resource input-stream

                        An input bytestream.

                        input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are @@ -207,7 +209,7 @@ promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

                        -

                        resource output-stream

                        +

                        resource output-stream

                        An output bytestream.

                        output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also @@ -219,7 +221,7 @@ polled for using wasi:io/poll.

                        progress may result in the data being lost. Before dropping the stream, be sure to fully flush your writes.

                        Functions

                        -

                        [method]input-stream.read: func

                        +

                        [method]input-stream.read: func

                        Perform a non-blocking read from the stream.

                        When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -243,51 +245,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

                        Params
                        Return values
                        -

                        [method]input-stream.blocking-read: func

                        +

                        [method]input-stream.blocking-read: func

                        Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

                        Params
                        Return values
                        -

                        [method]input-stream.skip: func

                        +

                        [method]input-stream.skip: func

                        Skip bytes from a stream. Returns number of bytes skipped.

                        Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

                        Params
                        Return values
                        -

                        [method]input-stream.blocking-skip: func

                        +

                        [method]input-stream.blocking-skip: func

                        Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

                        Params
                        Return values
                        -

                        [method]input-stream.subscribe: func

                        +

                        [method]input-stream.subscribe: func

                        Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -296,13 +298,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

                        Params
                        Return values
                        -

                        [method]output-stream.check-write: func

                        +

                        [method]output-stream.check-write: func

                        Check readiness for writing. This function never blocks.

                        Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -312,13 +314,13 @@ become ready when this function will report at least 1 byte, or an error.

                        Params
                        Return values
                        -

                        [method]output-stream.write: func

                        +

                        [method]output-stream.write: func

                        Perform a write. This function never blocks.

                        When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -331,14 +333,14 @@ length of less than or equal to n. Otherwise, this function will trap.

                        the last call to check-write provided a permit.

                        Params
                        Return values
                        -

                        [method]output-stream.blocking-write-and-flush: func

                        +

                        [method]output-stream.blocking-write-and-flush: func

                        Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                        This is a convenience wrapper around the use of check-write, @@ -362,14 +364,14 @@ let _ = this.check-write(); // eliding error handling

                        Params
                        Return values
                        -

                        [method]output-stream.flush: func

                        +

                        [method]output-stream.flush: func

                        Request to flush buffered output. This function never blocks.

                        This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -380,24 +382,24 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

                        Params
                        Return values
                        -

                        [method]output-stream.blocking-flush: func

                        +

                        [method]output-stream.blocking-flush: func

                        Request to flush buffered output, and block until flush completes and stream is ready for writing again.

                        Params
                        Return values
                        -

                        [method]output-stream.subscribe: func

                        +

                        [method]output-stream.subscribe: func

                        Create a pollable which will resolve once the output-stream is ready for more writing, or an error has occurred. When this pollable is ready, check-write will return ok(n) with n>0, or an @@ -408,13 +410,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

                        Params
                        Return values
                        -

                        [method]output-stream.write-zeroes: func

                        +

                        [method]output-stream.write-zeroes: func

                        Write zeroes to a stream.

                        This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -422,14 +424,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

                        Params
                        Return values
                        -

                        [method]output-stream.blocking-write-zeroes-and-flush: func

                        +

                        [method]output-stream.blocking-write-zeroes-and-flush: func

                        Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                        @@ -453,14 +455,14 @@ let _ = this.check-write(); // eliding error handling
                        Params
                        Return values
                        -

                        [method]output-stream.splice: func

                        +

                        [method]output-stream.splice: func

                        Read from one stream and write to another.

                        The behavior of splice is equivalent to:

                          @@ -475,138 +477,138 @@ let _ = this.check-write(); // eliding error handling than len.

                          Params
                          Return values
                          -

                          [method]output-stream.blocking-splice: func

                          +

                          [method]output-stream.blocking-splice: func

                          Read from one stream and write to another, with blocking.

                          This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

                          Params
                          Return values
                          -

                          Import interface wasi:cli/stdin@0.2.1

                          +

                          Import interface wasi:cli/stdin@0.2.2


                          Types

                          -

                          type input-stream

                          +

                          type input-stream

                          input-stream

                          ----

                          Functions

                          -

                          get-stdin: func

                          +

                          get-stdin: func

                          Return values
                          -

                          Import interface wasi:cli/stdout@0.2.1

                          +

                          Import interface wasi:cli/stdout@0.2.2


                          Types

                          -

                          type output-stream

                          +

                          type output-stream

                          output-stream

                          ----

                          Functions

                          -

                          get-stdout: func

                          +

                          get-stdout: func

                          Return values
                          -

                          Import interface wasi:cli/stderr@0.2.1

                          +

                          Import interface wasi:cli/stderr@0.2.2


                          Types

                          -

                          type output-stream

                          +

                          type output-stream

                          output-stream

                          ----

                          Functions

                          -

                          get-stderr: func

                          +

                          get-stderr: func

                          Return values
                          -

                          Import interface wasi:cli/terminal-input@0.2.1

                          +

                          Import interface wasi:cli/terminal-input@0.2.2

                          Terminal input.

                          In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through immediately, querying supported features, and so on.


                          Types

                          -

                          resource terminal-input

                          +

                          resource terminal-input

                          The input side of a terminal.

                          -

                          Import interface wasi:cli/terminal-output@0.2.1

                          +

                          Import interface wasi:cli/terminal-output@0.2.2

                          Terminal output.

                          In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported features, and so on.


                          Types

                          -

                          resource terminal-output

                          +

                          resource terminal-output

                          The output side of a terminal.

                          -

                          Import interface wasi:cli/terminal-stdin@0.2.1

                          +

                          Import interface wasi:cli/terminal-stdin@0.2.2

                          An interface providing an optional terminal-input for stdin as a link-time authority.


                          Types

                          -

                          type terminal-input

                          +

                          type terminal-input

                          terminal-input

                          ----

                          Functions

                          -

                          get-terminal-stdin: func

                          +

                          get-terminal-stdin: func

                          If stdin is connected to a terminal, return a terminal-input handle allowing further interaction with it.

                          Return values
                          -

                          Import interface wasi:cli/terminal-stdout@0.2.1

                          +

                          Import interface wasi:cli/terminal-stdout@0.2.2

                          An interface providing an optional terminal-output for stdout as a link-time authority.


                          Types

                          -

                          type terminal-output

                          +

                          type terminal-output

                          terminal-output

                          ----

                          Functions

                          -

                          get-terminal-stdout: func

                          +

                          get-terminal-stdout: func

                          If stdout is connected to a terminal, return a terminal-output handle allowing further interaction with it.

                          Return values
                          -

                          Import interface wasi:cli/terminal-stderr@0.2.1

                          +

                          Import interface wasi:cli/terminal-stderr@0.2.2

                          An interface providing an optional terminal-output for stderr as a link-time authority.


                          Types

                          -

                          type terminal-output

                          +

                          type terminal-output

                          terminal-output

                          ----

                          Functions

                          -

                          get-terminal-stderr: func

                          +

                          get-terminal-stderr: func

                          If stderr is connected to a terminal, return a terminal-output handle allowing further interaction with it.

                          Return values
                          -

                          Import interface wasi:clocks/monotonic-clock@0.2.1

                          +

                          Import interface wasi:clocks/monotonic-clock@0.2.2

                          WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                          It is intended to be portable at least between Unix-family platforms and @@ -615,57 +617,57 @@ Windows.

                          successive reads of the clock will produce non-decreasing values.


                          Types

                          -

                          type pollable

                          +

                          type pollable

                          pollable

                          -#### `type instant` +#### `type instant` `u64`

                          An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. -

                          type duration

                          +

                          type duration

                          u64

                          A duration of time, in nanoseconds.


                          Functions

                          -

                          now: func

                          +

                          now: func

                          Read the current value of the clock.

                          The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

                          Return values
                          -

                          resolution: func

                          +

                          resolution: func

                          Query the resolution of the clock. Returns the duration of time corresponding to a clock tick.

                          Return values
                          -

                          subscribe-instant: func

                          +

                          subscribe-instant: func

                          Create a pollable which will resolve once the specified instant has occurred.

                          Params
                          Return values
                          -

                          subscribe-duration: func

                          +

                          subscribe-duration: func

                          Create a pollable that will resolve after the specified duration has elapsed from the time this function is invoked.

                          Params
                          Return values
                          -

                          Import interface wasi:clocks/wall-clock@0.2.1

                          +

                          Import interface wasi:clocks/wall-clock@0.2.2

                          WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                          @@ -678,16 +680,16 @@ monotonic, making it unsuitable for measuring elapsed time.

                          It is intended for reporting the current date and time for humans.


                          Types

                          -

                          record datetime

                          +

                          record datetime

                          A time and date in seconds plus nanoseconds.

                          Record Fields
                            -
                          • seconds: u64
                          • -
                          • nanoseconds: u32
                          • +
                          • seconds: u64
                          • +
                          • nanoseconds: u32

                          Functions

                          -

                          now: func

                          +

                          now: func

                          Read the current value of the clock.

                          This clock is not monotonic, therefore calling this function repeatedly will not necessarily produce a sequence of non-decreasing values.

                          @@ -697,16 +699,16 @@ also known as Unix Time.The nanoseconds field of the output is always less than 1000000000.

                          Return values
                          -

                          resolution: func

                          +

                          resolution: func

                          Query the resolution of the clock.

                          The nanoseconds field of the output is always less than 1000000000.

                          Return values
                          -

                          Import interface wasi:filesystem/types@0.2.1

                          +

                          Import interface wasi:filesystem/types@0.2.2

                          WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                          @@ -726,75 +728,75 @@ underlying filesystem, the function fails with WASI filesystem path resolution.


                          Types

                          -

                          type input-stream

                          +

                          type input-stream

                          input-stream

                          -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

                          -#### `type error` +#### `type error` [`error`](#error)

                          -#### `type datetime` +#### `type datetime` [`datetime`](#datetime)

                          -#### `type filesize` +#### `type filesize` `u64`

                          File size or length of a region within a file. -

                          enum descriptor-type

                          +

                          enum descriptor-type

                          The type of a filesystem object referenced by a descriptor.

                          Note: This was called filetype in earlier versions of WASI.

                          Enum Cases
                          • -

                            unknown

                            +

                            unknown

                            The type of the descriptor or file is unknown or is different from any of the other types specified.

                          • -

                            block-device

                            +

                            block-device

                            The descriptor refers to a block device inode.

                          • -

                            character-device

                            +

                            character-device

                            The descriptor refers to a character device inode.

                          • -

                            directory

                            +

                            directory

                            The descriptor refers to a directory inode.

                          • -

                            fifo

                            +

                            fifo

                            The descriptor refers to a named pipe.

                          • -

                            symbolic-link

                            +

                            symbolic-link

                            The file refers to a symbolic link inode.

                          • -

                            regular-file

                            +

                            regular-file

                            The descriptor refers to a regular file inode.

                          • -

                            socket

                            +

                            socket

                            The descriptor refers to a socket.

                          -

                          flags descriptor-flags

                          +

                          flags descriptor-flags

                          Descriptor flags.

                          Note: This was called fdflags in earlier versions of WASI.

                          Flags members
                          • -

                            read:

                            +

                            read:

                            Read mode: Data can be read.

                          • -

                            write:

                            +

                            write:

                            Write mode: Data can be written to.

                          • -

                            file-integrity-sync:

                            +

                            file-integrity-sync:

                            Request that writes be performed according to synchronized I/O file integrity completion. The data stored in the file and the file's metadata are synchronized. This is similar to `O_SYNC` in POSIX. @@ -803,7 +805,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

                          • -

                            data-integrity-sync:

                            +

                            data-integrity-sync:

                            Request that writes be performed according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. This is similar to `O_DSYNC` in POSIX. @@ -812,7 +814,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

                          • -

                            requested-write-sync:

                            +

                            requested-write-sync:

                            Requests that reads be performed at the same level of integrity requested for writes. This is similar to `O_RSYNC` in POSIX.

                            The precise semantics of this operation have not yet been defined for @@ -820,7 +822,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

                          • -

                            mutate-directory:

                            +

                            mutate-directory:

                            Mutating directories mode: Directory contents may be mutated.

                            When this flag is unset on a descriptor, operations using the descriptor which would create, rename, delete, modify the data or @@ -830,107 +832,107 @@ they would otherwise succeed.

                            This may only be set on directories.

                          -

                          flags path-flags

                          +

                          flags path-flags

                          Flags determining the method of how paths are resolved.

                          Flags members
                            -
                          • symlink-follow:

                            As long as the resolved path corresponds to a symbolic link, it is +

                          • symlink-follow:

                            As long as the resolved path corresponds to a symbolic link, it is expanded.

                          -

                          flags open-flags

                          +

                          flags open-flags

                          Open flags used by open-at.

                          Flags members
                          • -

                            create:

                            +

                            create:

                            Create file if it does not exist, similar to `O_CREAT` in POSIX.

                          • -

                            directory:

                            +

                            directory:

                            Fail if not a directory, similar to `O_DIRECTORY` in POSIX.

                          • -

                            exclusive:

                            +

                            exclusive:

                            Fail if file already exists, similar to `O_EXCL` in POSIX.

                          • -

                            truncate:

                            +

                            truncate:

                            Truncate file to size 0, similar to `O_TRUNC` in POSIX.

                          -

                          type link-count

                          +

                          type link-count

                          u64

                          Number of hard links to an inode. -

                          record descriptor-stat

                          +

                          record descriptor-stat

                          File attributes.

                          Note: This was called filestat in earlier versions of WASI.

                          Record Fields
                          • -

                            type: descriptor-type

                            +

                            type: descriptor-type

                            File type.

                          • -

                            link-count: link-count

                            +

                            link-count: link-count

                            Number of hard links to the file.

                          • -

                            size: filesize

                            +

                            size: filesize

                            For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link.

                          • -

                            data-access-timestamp: option<datetime>

                            +

                            data-access-timestamp: option<datetime>

                            Last data access timestamp.

                            If the option is none, the platform doesn't maintain an access timestamp for this file.

                          • -

                            data-modification-timestamp: option<datetime>

                            +

                            data-modification-timestamp: option<datetime>

                            Last data modification timestamp.

                            If the option is none, the platform doesn't maintain a modification timestamp for this file.

                          • -

                            status-change-timestamp: option<datetime>

                            +

                            status-change-timestamp: option<datetime>

                            Last file status-change timestamp.

                            If the option is none, the platform doesn't maintain a status-change timestamp for this file.

                          -

                          variant new-timestamp

                          +

                          variant new-timestamp

                          When setting a timestamp, this gives the value to set it to.

                          Variant Cases
                          • -

                            no-change

                            +

                            no-change

                            Leave the timestamp set to its previous value.

                          • -

                            now

                            +

                            now

                            Set the timestamp to the current time of the system clock associated with the filesystem.

                          • -

                            timestamp: datetime

                            +

                            timestamp: datetime

                            Set the timestamp to the given value.

                          -

                          record directory-entry

                          +

                          record directory-entry

                          A directory entry.

                          Record Fields
                          • -

                            type: descriptor-type

                            +

                            type: descriptor-type

                            The type of the file referred to by this directory entry.

                          • -

                            name: string

                            +

                            name: string

                            The name of the object.

                          -

                          enum error-code

                          +

                          enum error-code

                          Error codes returned by functions, similar to errno in POSIX. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -938,211 +940,211 @@ merely for alignment with POSIX.

                          Enum Cases
                          • -

                            access

                            +

                            access

                            Permission denied, similar to `EACCES` in POSIX.

                          • -

                            would-block

                            +

                            would-block

                            Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX.

                          • -

                            already

                            +

                            already

                            Connection already in progress, similar to `EALREADY` in POSIX.

                          • -

                            bad-descriptor

                            +

                            bad-descriptor

                            Bad descriptor, similar to `EBADF` in POSIX.

                          • -

                            busy

                            +

                            busy

                            Device or resource busy, similar to `EBUSY` in POSIX.

                          • -

                            deadlock

                            +

                            deadlock

                            Resource deadlock would occur, similar to `EDEADLK` in POSIX.

                          • -

                            quota

                            +

                            quota

                            Storage quota exceeded, similar to `EDQUOT` in POSIX.

                          • -

                            exist

                            +

                            exist

                            File exists, similar to `EEXIST` in POSIX.

                          • -

                            file-too-large

                            +

                            file-too-large

                            File too large, similar to `EFBIG` in POSIX.

                          • -

                            illegal-byte-sequence

                            +

                            illegal-byte-sequence

                            Illegal byte sequence, similar to `EILSEQ` in POSIX.

                          • -

                            in-progress

                            +

                            in-progress

                            Operation in progress, similar to `EINPROGRESS` in POSIX.

                          • -

                            interrupted

                            +

                            interrupted

                            Interrupted function, similar to `EINTR` in POSIX.

                          • -

                            invalid

                            +

                            invalid

                            Invalid argument, similar to `EINVAL` in POSIX.

                          • -

                            io

                            +

                            io

                            I/O error, similar to `EIO` in POSIX.

                          • -

                            is-directory

                            +

                            is-directory

                            Is a directory, similar to `EISDIR` in POSIX.

                          • -

                            loop

                            +

                            loop

                            Too many levels of symbolic links, similar to `ELOOP` in POSIX.

                          • -

                            too-many-links

                            +

                            too-many-links

                            Too many links, similar to `EMLINK` in POSIX.

                          • -

                            message-size

                            +

                            message-size

                            Message too large, similar to `EMSGSIZE` in POSIX.

                          • -

                            name-too-long

                            +

                            name-too-long

                            Filename too long, similar to `ENAMETOOLONG` in POSIX.

                          • -

                            no-device

                            +

                            no-device

                            No such device, similar to `ENODEV` in POSIX.

                          • -

                            no-entry

                            +

                            no-entry

                            No such file or directory, similar to `ENOENT` in POSIX.

                          • -

                            no-lock

                            +

                            no-lock

                            No locks available, similar to `ENOLCK` in POSIX.

                          • -

                            insufficient-memory

                            +

                            insufficient-memory

                            Not enough space, similar to `ENOMEM` in POSIX.

                          • -

                            insufficient-space

                            +

                            insufficient-space

                            No space left on device, similar to `ENOSPC` in POSIX.

                          • -

                            not-directory

                            +

                            not-directory

                            Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX.

                          • -

                            not-empty

                            +

                            not-empty

                            Directory not empty, similar to `ENOTEMPTY` in POSIX.

                          • -

                            not-recoverable

                            +

                            not-recoverable

                            State not recoverable, similar to `ENOTRECOVERABLE` in POSIX.

                          • -

                            unsupported

                            +

                            unsupported

                            Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX.

                          • -

                            no-tty

                            +

                            no-tty

                            Inappropriate I/O control operation, similar to `ENOTTY` in POSIX.

                          • -

                            no-such-device

                            +

                            no-such-device

                            No such device or address, similar to `ENXIO` in POSIX.

                          • -

                            overflow

                            +

                            overflow

                            Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX.

                          • -

                            not-permitted

                            +

                            not-permitted

                            Operation not permitted, similar to `EPERM` in POSIX.

                          • -

                            pipe

                            +

                            pipe

                            Broken pipe, similar to `EPIPE` in POSIX.

                          • -

                            read-only

                            +

                            read-only

                            Read-only file system, similar to `EROFS` in POSIX.

                          • -

                            invalid-seek

                            +

                            invalid-seek

                            Invalid seek, similar to `ESPIPE` in POSIX.

                          • -

                            text-file-busy

                            +

                            text-file-busy

                            Text file busy, similar to `ETXTBSY` in POSIX.

                          • -

                            cross-device

                            +

                            cross-device

                            Cross-device link, similar to `EXDEV` in POSIX.

                          -

                          enum advice

                          +

                          enum advice

                          File or memory access pattern advisory information.

                          Enum Cases
                          • -

                            normal

                            +

                            normal

                            The application has no advice to give on its behavior with respect to the specified data.

                          • -

                            sequential

                            +

                            sequential

                            The application expects to access the specified data sequentially from lower offsets to higher offsets.

                          • -

                            random

                            +

                            random

                            The application expects to access the specified data in a random order.

                          • -

                            will-need

                            +

                            will-need

                            The application expects to access the specified data in the near future.

                          • -

                            dont-need

                            +

                            dont-need

                            The application expects that it will not access the specified data in the near future.

                          • -

                            no-reuse

                            +

                            no-reuse

                            The application expects to access the specified data once and then not reuse it thereafter.

                          -

                          record metadata-hash-value

                          +

                          record metadata-hash-value

                          A 128-bit hash value, split into parts because wasm doesn't have a 128-bit integer type.

                          Record Fields
                          • -

                            lower: u64

                            +

                            lower: u64

                            64 bits of a 128-bit hash value.

                          • -

                            upper: u64

                            +

                            upper: u64

                            Another 64 bits of a 128-bit hash value.

                          -

                          resource descriptor

                          +

                          resource descriptor

                          A descriptor is a reference to a filesystem object, which may be a file, directory, named pipe, special file, or other object on which filesystem calls may be made.

                          -

                          resource directory-entry-stream

                          +

                          resource directory-entry-stream

                          A stream of directory entries.

                          Functions

                          -

                          [method]descriptor.read-via-stream: func

                          +

                          [method]descriptor.read-via-stream: func

                          Return a stream for reading from a file, if available.

                          May fail with an error-code describing why the file cannot be read.

                          Multiple read, write, and append streams may be active on the same open @@ -1150,81 +1152,81 @@ file and they do not interfere with each other.

                          Note: This allows using read-stream, which is similar to read in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.write-via-stream: func

                          +

                          [method]descriptor.write-via-stream: func

                          Return a stream for writing to a file, if available.

                          May fail with an error-code describing why the file cannot be written.

                          Note: This allows using write-stream, which is similar to write in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.append-via-stream: func

                          +

                          [method]descriptor.append-via-stream: func

                          Return a stream for appending to a file, if available.

                          May fail with an error-code describing why the file cannot be appended.

                          Note: This allows using write-stream, which is similar to write with O_APPEND in in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.advise: func

                          +

                          [method]descriptor.advise: func

                          Provide file advisory information on a descriptor.

                          This is similar to posix_fadvise in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.sync-data: func

                          +

                          [method]descriptor.sync-data: func

                          Synchronize the data of a file to disk.

                          This function succeeds with no effect if the file descriptor is not opened for writing.

                          Note: This is similar to fdatasync in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.get-flags: func

                          +

                          [method]descriptor.get-flags: func

                          Get flags associated with a descriptor.

                          Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

                          Note: This returns the value that was the fs_flags value returned from fdstat_get in earlier versions of WASI.

                          Params
                          Return values
                          -

                          [method]descriptor.get-type: func

                          +

                          [method]descriptor.get-type: func

                          Get the dynamic type of a descriptor.

                          Note: This returns the same value as the type field of the fd-stat returned by stat, stat-at and similar.

                          @@ -1234,40 +1236,40 @@ by fstat in POSIX.

                          from fdstat_get in earlier versions of WASI.

                          Params
                          Return values
                          -

                          [method]descriptor.set-size: func

                          +

                          [method]descriptor.set-size: func

                          Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.

                          Note: This was called fd_filestat_set_size in earlier versions of WASI.

                          Params
                          Return values
                          -

                          [method]descriptor.set-times: func

                          +

                          [method]descriptor.set-times: func

                          Adjust the timestamps of an open file or directory.

                          Note: This is similar to futimens in POSIX.

                          Note: This was called fd_filestat_set_times in earlier versions of WASI.

                          Params
                          Return values
                          -

                          [method]descriptor.read: func

                          +

                          [method]descriptor.read: func

                          Read from a descriptor, without using and updating the descriptor's offset.

                          This function returns a list of bytes containing the data that was read, along with a bool which, when true, indicates that the end of the @@ -1278,15 +1280,15 @@ if the I/O operation is interrupted.

                          Note: This is similar to pread in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.write: func

                          +

                          [method]descriptor.write: func

                          Write to a descriptor, without using and updating the descriptor's offset.

                          It is valid to write past the end of a file; the file is extended to the extent of the write, with bytes between the previous end and the start of @@ -1295,15 +1297,15 @@ the write set to zero.

                          Note: This is similar to pwrite in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.read-directory: func

                          +

                          [method]descriptor.read-directory: func

                          Read directory entries from a directory.

                          On filesystems where directories contain entries referring to themselves and their parents, often named . and .. respectively, these entries @@ -1313,38 +1315,38 @@ directory. Multiple streams may be active on the same directory, and they do not interfere with each other.

                          Params
                          Return values
                          -

                          [method]descriptor.sync: func

                          +

                          [method]descriptor.sync: func

                          Synchronize the data and metadata of a file to disk.

                          This function succeeds with no effect if the file descriptor is not opened for writing.

                          Note: This is similar to fsync in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.create-directory-at: func

                          +

                          [method]descriptor.create-directory-at: func

                          Create a directory.

                          Note: This is similar to mkdirat in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.stat: func

                          +

                          [method]descriptor.stat: func

                          Return the attributes of an open file or directory.

                          Note: This is similar to fstat in POSIX, except that it does not return device and inode information. For testing whether two descriptors refer to @@ -1354,13 +1356,13 @@ modified, use metadata-hash.

                          Note: This was called fd_filestat_get in earlier versions of WASI.

                          Params
                          Return values
                          -

                          [method]descriptor.stat-at: func

                          +

                          [method]descriptor.stat-at: func

                          Return the attributes of a file or directory.

                          Note: This is similar to fstatat in POSIX, except that it does not return device and inode information. See the stat description for a @@ -1368,53 +1370,48 @@ discussion of alternatives.

                          Note: This was called path_filestat_get in earlier versions of WASI.

                          Params
                          Return values
                          -

                          [method]descriptor.set-times-at: func

                          +

                          [method]descriptor.set-times-at: func

                          Adjust the timestamps of a file or directory.

                          Note: This is similar to utimensat in POSIX.

                          Note: This was called path_filestat_set_times in earlier versions of WASI.

                          Params
                          Return values
                          -

                          [method]descriptor.link-at: func

                          +

                          [method]descriptor.link-at: func

                          Create a hard link.

                          Note: This is similar to linkat in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.open-at: func

                          +

                          [method]descriptor.open-at: func

                          Open a file or directory.

                          -

                          The returned descriptor is not guaranteed to be the lowest-numbered -descriptor not currently open/ it is randomized to prevent applications -from depending on making assumptions about indexes, since this is -error-prone in multi-threaded contexts. The returned descriptor is -guaranteed to be less than 2**31.

                          If flags contains descriptor-flags::mutate-directory, and the base descriptor doesn't have descriptor-flags::mutate-directory set, open-at fails with error-code::read-only.

                          @@ -1425,86 +1422,86 @@ contains truncate or create, and the base descriptor d

                          Note: This is similar to openat in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.readlink-at: func

                          +

                          [method]descriptor.readlink-at: func

                          Read the contents of a symbolic link.

                          If the contents contain an absolute or rooted path in the underlying filesystem, this function fails with error-code::not-permitted.

                          Note: This is similar to readlinkat in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.remove-directory-at: func

                          +

                          [method]descriptor.remove-directory-at: func

                          Remove a directory.

                          Return error-code::not-empty if the directory is not empty.

                          Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.rename-at: func

                          +

                          [method]descriptor.rename-at: func

                          Rename a filesystem object.

                          Note: This is similar to renameat in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.symlink-at: func

                          +

                          [method]descriptor.symlink-at: func

                          Create a symbolic link (also known as a "symlink").

                          If old-path starts with /, the function fails with error-code::not-permitted.

                          Note: This is similar to symlinkat in POSIX.

                          Params
                            -
                          • self: borrow<descriptor>
                          • -
                          • old-path: string
                          • -
                          • new-path: string
                          • +
                          • self: borrow<descriptor>
                          • +
                          • old-path: string
                          • +
                          • new-path: string
                          Return values
                          -

                          [method]descriptor.unlink-file-at: func

                          +

                          [method]descriptor.unlink-file-at: func

                          Unlink a filesystem object that is not a directory.

                          Return error-code::is-directory if the path refers to a directory. Note: This is similar to unlinkat(fd, path, 0) in POSIX.

                          Params
                          Return values
                          -

                          [method]descriptor.is-same-object: func

                          +

                          [method]descriptor.is-same-object: func

                          Test whether two descriptors refer to the same filesystem object.

                          In POSIX, this corresponds to testing whether the two descriptors have the same device (st_dev) and inode (st_ino or d_ino) numbers. @@ -1512,14 +1509,14 @@ wasi-filesystem does not expose device and inode numbers, so this function may be used instead.

                          Params
                          Return values
                            -
                          • bool
                          • +
                          • bool
                          -

                          [method]descriptor.metadata-hash: func

                          +

                          [method]descriptor.metadata-hash: func

                          Return a hash of the metadata associated with a filesystem object referred to by a descriptor.

                          This returns a hash of the last-modification timestamp and file size, and @@ -1539,37 +1536,37 @@ computed hash.

                          However, none of these is required.

                          Params
                          Return values
                          -

                          [method]descriptor.metadata-hash-at: func

                          +

                          [method]descriptor.metadata-hash-at: func

                          Return a hash of the metadata associated with a filesystem object referred to by a directory descriptor and a relative path.

                          This performs the same hash computation as metadata-hash.

                          Params
                          Return values
                          -

                          [method]directory-entry-stream.read-directory-entry: func

                          +

                          [method]directory-entry-stream.read-directory-entry: func

                          Read a single directory entry from a directory-entry-stream.

                          Params
                          Return values
                          -

                          filesystem-error-code: func

                          +

                          filesystem-error-code: func

                          Attempts to extract a filesystem-related error-code from the stream error provided.

                          Stream operations which return stream-error::last-operation-failed @@ -1580,34 +1577,34 @@ filesystem-related information about the error to return.

                          errors are filesystem-related errors.

                          Params
                          Return values
                          -

                          Import interface wasi:filesystem/preopens@0.2.1

                          +

                          Import interface wasi:filesystem/preopens@0.2.2


                          Types

                          -

                          type descriptor

                          +

                          type descriptor

                          descriptor

                          ----

                          Functions

                          -

                          get-directories: func

                          +

                          get-directories: func

                          Return the set of preopened directories, and their path.

                          Return values
                          -

                          Import interface wasi:sockets/network@0.2.1

                          +

                          Import interface wasi:sockets/network@0.2.2


                          Types

                          -

                          resource network

                          +

                          resource network

                          An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                          -

                          enum error-code

                          +

                          enum error-code

                          Error codes.

                          In theory, every API can return any error code. In practice, API's typically only return the errors documented per API @@ -1623,235 +1620,235 @@ combined with a couple of errors that are always possible:

                          Enum Cases
                          • -

                            unknown

                            +

                            unknown

                            Unknown error

                          • -

                            access-denied

                            +

                            access-denied

                            Access denied.

                            POSIX equivalent: EACCES, EPERM

                          • -

                            not-supported

                            +

                            not-supported

                            The operation is not supported.

                            POSIX equivalent: EOPNOTSUPP

                          • -

                            invalid-argument

                            +

                            invalid-argument

                            One of the arguments is invalid.

                            POSIX equivalent: EINVAL

                          • -

                            out-of-memory

                            +

                            out-of-memory

                            Not enough memory to complete the operation.

                            POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY

                          • -

                            timeout

                            +

                            timeout

                            The operation timed out before it could finish completely.

                          • -

                            concurrency-conflict

                            +

                            concurrency-conflict

                            This operation is incompatible with another asynchronous operation that is already in progress.

                            POSIX equivalent: EALREADY

                          • -

                            not-in-progress

                            +

                            not-in-progress

                            Trying to finish an asynchronous operation that: - has not been started yet, or: - was already finished by a previous `finish-*` call.

                            Note: this is scheduled to be removed when futures are natively supported.

                          • -

                            would-block

                            +

                            would-block

                            The operation has been aborted because it could not be completed immediately.

                            Note: this is scheduled to be removed when futures are natively supported.

                          • -

                            invalid-state

                            +

                            invalid-state

                            The operation is not valid in the socket's current state.

                          • -

                            new-socket-limit

                            +

                            new-socket-limit

                            A new socket resource could not be created because of a system limit.

                          • -

                            address-not-bindable

                            +

                            address-not-bindable

                            A bind operation failed because the provided address is not an address that the `network` can bind to.

                          • -

                            address-in-use

                            +

                            address-in-use

                            A bind operation failed because the provided address is already in use or because there are no ephemeral ports available.

                          • -

                            remote-unreachable

                            +

                            remote-unreachable

                            The remote address is not reachable

                          • -

                            connection-refused

                            +

                            connection-refused

                            The TCP connection was forcefully rejected

                          • -

                            connection-reset

                            +

                            connection-reset

                            The TCP connection was reset.

                          • -

                            connection-aborted

                            +

                            connection-aborted

                            A TCP connection was aborted.

                          • -

                            datagram-too-large

                            +

                            datagram-too-large

                            The size of a datagram sent to a UDP socket exceeded the maximum supported size.

                          • -

                            name-unresolvable

                            +

                            name-unresolvable

                            Name does not exist or has no suitable associated IP addresses.

                          • -

                            temporary-resolver-failure

                            +

                            temporary-resolver-failure

                            A temporary failure in name resolution occurred.

                          • -

                            permanent-resolver-failure

                            +

                            permanent-resolver-failure

                            A permanent failure in name resolution occurred.

                          -

                          enum ip-address-family

                          +

                          enum ip-address-family

                          Enum Cases
                          • -

                            ipv4

                            +

                            ipv4

                            Similar to `AF_INET` in POSIX.

                          • -

                            ipv6

                            +

                            ipv6

                            Similar to `AF_INET6` in POSIX.

                          -

                          tuple ipv4-address

                          +

                          tuple ipv4-address

                          Tuple Fields
                            -
                          • 0: u8
                          • -
                          • 1: u8
                          • -
                          • 2: u8
                          • -
                          • 3: u8
                          • +
                          • 0: u8
                          • +
                          • 1: u8
                          • +
                          • 2: u8
                          • +
                          • 3: u8
                          -

                          tuple ipv6-address

                          +

                          tuple ipv6-address

                          Tuple Fields
                            -
                          • 0: u16
                          • -
                          • 1: u16
                          • -
                          • 2: u16
                          • -
                          • 3: u16
                          • -
                          • 4: u16
                          • -
                          • 5: u16
                          • -
                          • 6: u16
                          • -
                          • 7: u16
                          • +
                          • 0: u16
                          • +
                          • 1: u16
                          • +
                          • 2: u16
                          • +
                          • 3: u16
                          • +
                          • 4: u16
                          • +
                          • 5: u16
                          • +
                          • 6: u16
                          • +
                          • 7: u16
                          -

                          variant ip-address

                          +

                          variant ip-address

                          Variant Cases
                          -

                          record ipv4-socket-address

                          +

                          record ipv4-socket-address

                          Record Fields
                          -

                          record ipv6-socket-address

                          +

                          record ipv6-socket-address

                          Record Fields
                          • -

                            port: u16

                            +

                            port: u16

                            sin6_port

                          • -

                            flow-info: u32

                            +

                            flow-info: u32

                            sin6_flowinfo

                          • -

                            address: ipv6-address

                            +

                            address: ipv6-address

                            sin6_addr

                          • -

                            scope-id: u32

                            +

                            scope-id: u32

                            sin6_scope_id

                          -

                          variant ip-socket-address

                          +

                          variant ip-socket-address

                          Variant Cases
                          -

                          Import interface wasi:sockets/instance-network@0.2.1

                          +

                          Import interface wasi:sockets/instance-network@0.2.2

                          This interface provides a value-export of the default network handle..


                          Types

                          -

                          type network

                          +

                          type network

                          network

                          ----

                          Functions

                          -

                          instance-network: func

                          +

                          instance-network: func

                          Get a handle to the default network.

                          Return values
                          -

                          Import interface wasi:sockets/udp@0.2.1

                          +

                          Import interface wasi:sockets/udp@0.2.2


                          Types

                          -

                          type pollable

                          +

                          type pollable

                          pollable

                          -#### `type network` +#### `type network` [`network`](#network)

                          -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                          -#### `type ip-socket-address` +#### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address)

                          -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                          -#### `record incoming-datagram` +#### `record incoming-datagram`

                          A received datagram.

                          Record Fields
                          • -

                            data: list<u8>

                            +

                            data: list<u8>

                            The payload.

                            Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes.

                          • -

                            remote-address: ip-socket-address

                            +

                            remote-address: ip-socket-address

                            The source address.

                            This field is guaranteed to match the remote address the stream was initialized with, if any.

                            Equivalent to the src_addr out parameter of recvfrom.

                          -

                          record outgoing-datagram

                          +

                          record outgoing-datagram

                          A datagram to be sent out.

                          Record Fields
                          • -

                            data: list<u8>

                            +

                            data: list<u8>

                            The payload.

                          • -

                            remote-address: option<ip-socket-address>

                            +

                            remote-address: option<ip-socket-address>

                            The destination address.

                            The requirements on this field depend on how the stream was initialized:

                              @@ -1861,13 +1858,13 @@ supported size.

                              If this value is None, the send operation is equivalent to send in POSIX. Otherwise it is equivalent to sendto.

                            -

                            resource udp-socket

                            +

                            resource udp-socket

                            A UDP socket handle.

                            -

                            resource incoming-datagram-stream

                            -

                            resource outgoing-datagram-stream

                            +

                            resource incoming-datagram-stream

                            +

                            resource outgoing-datagram-stream


                            Functions

                            -

                            [method]udp-socket.start-bind: func

                            +

                            [method]udp-socket.start-bind: func

                            Bind the socket to a specific network on the provided IP address and port.

                            If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -1896,24 +1893,24 @@ don't want to make use of this ability can simply call the native

                          Params
                          Return values
                          -

                          [method]udp-socket.finish-bind: func

                          +

                          [method]udp-socket.finish-bind: func

                          Params
                          Return values
                          -

                          [method]udp-socket.stream: func

                          +

                          [method]udp-socket.stream: func

                          Set up inbound & outbound communication channels, optionally to a specific peer.

                          This function only changes the local socket configuration and does not generate any network traffic. On success, the remote-address of the socket is updated. The local-address may be updated as well, @@ -1954,14 +1951,14 @@ if (remote_address is Some) {

                      Params
                      Return values
                      -

                      [method]udp-socket.local-address: func

                      +

                      [method]udp-socket.local-address: func

                      Get the current bound address.

                      POSIX mentions:

                      @@ -1982,13 +1979,13 @@ stored in the object pointed to by address is unspecified.

                    Params
                    Return values
                    -

                    [method]udp-socket.remote-address: func

                    +

                    [method]udp-socket.remote-address: func

                    Get the address the socket is currently streaming to.

                    Typical errors

                      @@ -2003,24 +2000,24 @@ stored in the object pointed to by address is unspecified.

                    Params
                    Return values
                    -

                    [method]udp-socket.address-family: func

                    +

                    [method]udp-socket.address-family: func

                    Whether this is a IPv4 or IPv6 socket.

                    Equivalent to the SO_DOMAIN socket option.

                    Params
                    Return values
                    -

                    [method]udp-socket.unicast-hop-limit: func

                    +

                    [method]udp-socket.unicast-hop-limit: func

                    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                    If the provided value is 0, an invalid-argument error is returned.

                    Typical errors

                    @@ -2029,23 +2026,23 @@ stored in the object pointed to by address is unspecified.

                    Params
                    Return values
                    -

                    [method]udp-socket.set-unicast-hop-limit: func

                    +

                    [method]udp-socket.set-unicast-hop-limit: func

                    Params
                    Return values
                    -

                    [method]udp-socket.receive-buffer-size: func

                    +

                    [method]udp-socket.receive-buffer-size: func

                    The kernel buffer space reserved for sends/receives on this socket.

                    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2057,54 +2054,54 @@ I.e. after setting a value, reading the same setting back may return a different

                    Params
                    Return values
                    -

                    [method]udp-socket.set-receive-buffer-size: func

                    +

                    [method]udp-socket.set-receive-buffer-size: func

                    Params
                    Return values
                    -

                    [method]udp-socket.send-buffer-size: func

                    +

                    [method]udp-socket.send-buffer-size: func

                    Params
                    Return values
                    -

                    [method]udp-socket.set-send-buffer-size: func

                    +

                    [method]udp-socket.set-send-buffer-size: func

                    Params
                    Return values
                    -

                    [method]udp-socket.subscribe: func

                    +

                    [method]udp-socket.subscribe: func

                    Create a pollable which will resolve once the socket is ready for I/O.

                    -

                    Note: this function is here for WASI Preview2 only. +

                    Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                    Params
                    Return values
                    -

                    [method]incoming-datagram-stream.receive: func

                    +

                    [method]incoming-datagram-stream.receive: func

                    Receive messages on the socket.

                    This function attempts to receive up to max-results datagrams on the socket without blocking. The returned list may contain fewer elements than requested, but never more.

                    @@ -2132,26 +2129,26 @@ This function never returns error(would-block).
                    Params
                    Return values
                    -

                    [method]incoming-datagram-stream.subscribe: func

                    +

                    [method]incoming-datagram-stream.subscribe: func

                    Create a pollable which will resolve once the stream is ready to receive again.

                    -

                    Note: this function is here for WASI Preview2 only. +

                    Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                    Params
                    Return values
                    -

                    [method]outgoing-datagram-stream.check-send: func

                    +

                    [method]outgoing-datagram-stream.check-send: func

                    Check readiness for sending. This function never blocks.

                    Returns the number of datagrams permitted for the next call to send, or an error. Calling send with more datagrams than this function has @@ -2162,13 +2159,13 @@ error.

                    Never returns would-block.

                    Params
                    Return values
                    -

                    [method]outgoing-datagram-stream.send: func

                    +

                    [method]outgoing-datagram-stream.send: func

                    Send messages on the socket.

                    This function attempts to send all provided datagrams on the socket without blocking and returns how many messages were actually sent (or queued for sending). This function never @@ -2203,43 +2200,43 @@ either check-send was not called or datagrams contains

                    Params
                    Return values
                    -

                    [method]outgoing-datagram-stream.subscribe: func

                    +

                    [method]outgoing-datagram-stream.subscribe: func

                    Create a pollable which will resolve once the stream is ready to send again.

                    -

                    Note: this function is here for WASI Preview2 only. +

                    Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                    Params
                    Return values
                    -

                    Import interface wasi:sockets/udp-create-socket@0.2.1

                    +

                    Import interface wasi:sockets/udp-create-socket@0.2.2


                    Types

                    -

                    type network

                    +

                    type network

                    network

                    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                    -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                    -#### `type udp-socket` +#### `type udp-socket` [`udp-socket`](#udp_socket)

                    ----

                    Functions

                    -

                    create-udp-socket: func

                    +

                    create-udp-socket: func

                    Create a new UDP socket.

                    Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX. On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

                    @@ -2261,56 +2258,56 @@ the socket is effectively an in-memory configuration object, unable to communica
                    Params
                    Return values
                    -

                    Import interface wasi:sockets/tcp@0.2.1

                    +

                    Import interface wasi:sockets/tcp@0.2.2


                    Types

                    -

                    type input-stream

                    +

                    type input-stream

                    input-stream

                    -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

                    -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

                    -#### `type duration` +#### `type duration` [`duration`](#duration)

                    -#### `type network` +#### `type network` [`network`](#network)

                    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                    -#### `type ip-socket-address` +#### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address)

                    -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                    -#### `enum shutdown-type` +#### `enum shutdown-type`

                    Enum Cases
                    • -

                      receive

                      +

                      receive

                      Similar to `SHUT_RD` in POSIX.

                    • -

                      send

                      +

                      send

                      Similar to `SHUT_WR` in POSIX.

                    • -

                      both

                      +

                      both

                      Similar to `SHUT_RDWR` in POSIX.

                    -

                    resource tcp-socket

                    +

                    resource tcp-socket

                    A TCP socket resource.

                    The socket can be in one of the following states:

                      @@ -2332,7 +2329,7 @@ the term "bound" without backticks it actually means: in the bou network::error-code type, TCP socket methods may always return error(invalid-state) when in the closed state.

                      Functions

                      -

                      [method]tcp-socket.start-bind: func

                      +

                      [method]tcp-socket.start-bind: func

                      Bind the socket to a specific network on the provided IP address and port.

                      If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -2371,24 +2368,24 @@ don't want to make use of this ability can simply call the native

                    Params
                    Return values
                    -

                    [method]tcp-socket.finish-bind: func

                    +

                    [method]tcp-socket.finish-bind: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.start-connect: func

                    +

                    [method]tcp-socket.start-connect: func

                    Connect to a remote endpoint.

                    On success:

                    Params
                    Return values
                    -

                    [method]tcp-socket.finish-listen: func

                    +

                    [method]tcp-socket.finish-listen: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.accept: func

                    +

                    [method]tcp-socket.accept: func

                    Accept a new client socket.

                    The returned socket is bound and in the connected state. The following properties are inherited from the listener socket:

                      @@ -2523,13 +2520,13 @@ a pair of streams that can be used to read & write to the connection.

                    Params
                    Return values
                    -

                    [method]tcp-socket.local-address: func

                    +

                    [method]tcp-socket.local-address: func

                    Get the bound local address.

                    POSIX mentions:

                    @@ -2550,13 +2547,13 @@ stored in the object pointed to by address is unspecified.

                    Params
                    Return values
                    -

                    [method]tcp-socket.remote-address: func

                    +

                    [method]tcp-socket.remote-address: func

                    Get the remote address.

                    Typical errors

                      @@ -2571,35 +2568,35 @@ stored in the object pointed to by address is unspecified.

                    Params
                    Return values
                    -

                    [method]tcp-socket.is-listening: func

                    +

                    [method]tcp-socket.is-listening: func

                    Whether the socket is in the listening state.

                    Equivalent to the SO_ACCEPTCONN socket option.

                    Params
                    Return values
                      -
                    • bool
                    • +
                    • bool
                    -

                    [method]tcp-socket.address-family: func

                    +

                    [method]tcp-socket.address-family: func

                    Whether this is a IPv4 or IPv6 socket.

                    Equivalent to the SO_DOMAIN socket option.

                    Params
                    Return values
                    -

                    [method]tcp-socket.set-listen-backlog-size: func

                    +

                    [method]tcp-socket.set-listen-backlog-size: func

                    Hints the desired listen queue size. Implementations are free to ignore this.

                    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded.

                    @@ -2611,14 +2608,14 @@ Any other value will never cause an error, but it might be silently clamped and/
                    Params
                    Return values
                    -

                    [method]tcp-socket.keep-alive-enabled: func

                    +

                    [method]tcp-socket.keep-alive-enabled: func

                    Enables or disables keepalive.

                    The keepalive behavior can be adjusted using:

                      @@ -2630,23 +2627,23 @@ These properties can be configured while keep-alive-enabled is fals

                      Equivalent to the SO_KEEPALIVE socket option.

                      Params
                      Return values
                      -

                      [method]tcp-socket.set-keep-alive-enabled: func

                      +

                      [method]tcp-socket.set-keep-alive-enabled: func

                      Params
                      Return values
                      -

                      [method]tcp-socket.keep-alive-idle-time: func

                      +

                      [method]tcp-socket.keep-alive-idle-time: func

                      Amount of time the connection has to be idle before TCP starts sending keepalive packets.

                      If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2658,23 +2655,23 @@ I.e. after setting a value, reading the same setting back may return a different

                    Params
                    Return values
                    -

                    [method]tcp-socket.set-keep-alive-idle-time: func

                    +

                    [method]tcp-socket.set-keep-alive-idle-time: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.keep-alive-interval: func

                    +

                    [method]tcp-socket.keep-alive-interval: func

                    The time between keepalive packets.

                    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2686,23 +2683,23 @@ I.e. after setting a value, reading the same setting back may return a different

                    Params
                    Return values
                    -

                    [method]tcp-socket.set-keep-alive-interval: func

                    +

                    [method]tcp-socket.set-keep-alive-interval: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.keep-alive-count: func

                    +

                    [method]tcp-socket.keep-alive-count: func

                    The maximum amount of keepalive packets TCP should send before aborting the connection.

                    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2714,23 +2711,23 @@ I.e. after setting a value, reading the same setting back may return a different

                    Params
                    Return values
                    -

                    [method]tcp-socket.set-keep-alive-count: func

                    +

                    [method]tcp-socket.set-keep-alive-count: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.hop-limit: func

                    +

                    [method]tcp-socket.hop-limit: func

                    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                    If the provided value is 0, an invalid-argument error is returned.

                    Typical errors

                    @@ -2739,23 +2736,23 @@ I.e. after setting a value, reading the same setting back may return a different
                    Params
                    Return values
                    -

                    [method]tcp-socket.set-hop-limit: func

                    +

                    [method]tcp-socket.set-hop-limit: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.receive-buffer-size: func

                    +

                    [method]tcp-socket.receive-buffer-size: func

                    The kernel buffer space reserved for sends/receives on this socket.

                    If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2767,42 +2764,42 @@ I.e. after setting a value, reading the same setting back may return a different

                    Params
                    Return values
                    -

                    [method]tcp-socket.set-receive-buffer-size: func

                    +

                    [method]tcp-socket.set-receive-buffer-size: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.send-buffer-size: func

                    +

                    [method]tcp-socket.send-buffer-size: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.set-send-buffer-size: func

                    +

                    [method]tcp-socket.set-send-buffer-size: func

                    Params
                    Return values
                    -

                    [method]tcp-socket.subscribe: func

                    +

                    [method]tcp-socket.subscribe: func

                    Create a pollable which can be used to poll for, or block on, completion of any of the asynchronous operations of this socket.

                    When finish-bind, finish-listen, finish-connect or accept @@ -2814,17 +2811,17 @@ in progress at the time of calling subscribe (if any). Theoreticall (re)used for the remainder of the socket's lifetime.

                    See https://github.com/WebAssembly/wasi-sockets/blob/main/TcpSocketOperationalSemantics.md#pollable-readiness for more information.

                    -

                    Note: this function is here for WASI Preview2 only. +

                    Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                    Params
                    Return values
                    -

                    [method]tcp-socket.shutdown: func

                    +

                    [method]tcp-socket.shutdown: func

                    Initiate a graceful shutdown.

                    • receive: The socket is not expecting to receive any data from @@ -2851,31 +2848,31 @@ has no effect and returns ok.

                    Params
                    Return values
                    -

                    Import interface wasi:sockets/tcp-create-socket@0.2.1

                    +

                    Import interface wasi:sockets/tcp-create-socket@0.2.2


                    Types

                    -

                    type network

                    +

                    type network

                    network

                    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                    -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                    -#### `type tcp-socket` +#### `type tcp-socket` [`tcp-socket`](#tcp_socket)

                    ----

                    Functions

                    -

                    create-tcp-socket: func

                    +

                    create-tcp-socket: func

                    Create a new TCP socket.

                    Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX. On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

                    @@ -2897,31 +2894,31 @@ is called, the socket is effectively an in-memory configuration object, unable t
                    Params
                    Return values
                    -

                    Import interface wasi:sockets/ip-name-lookup@0.2.1

                    +

                    Import interface wasi:sockets/ip-name-lookup@0.2.2


                    Types

                    -

                    type pollable

                    +

                    type pollable

                    pollable

                    -#### `type network` +#### `type network` [`network`](#network)

                    -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                    -#### `type ip-address` +#### `type ip-address` [`ip-address`](#ip_address)

                    -#### `resource resolve-address-stream` +#### `resource resolve-address-stream`


                    Functions

                    -

                    resolve-addresses: func

                    +

                    resolve-addresses: func

                    Resolve an internet host name to a list of IP addresses.

                    Unicode domain names are automatically converted to ASCII using IDNA encoding. If the input is an IP address string, the address is parsed and returned @@ -2943,14 +2940,14 @@ to (asynchronously) fetch the results.

                    Params
                    Return values
                    -

                    [method]resolve-address-stream.resolve-next-address: func

                    +

                    [method]resolve-address-stream.resolve-next-address: func

                    Returns the next address from the resolver.

                    This function should be called multiple times. On each call, it will return the next address in connection order preference. If all @@ -2965,31 +2962,31 @@ addresses have been exhausted, this function returns none.

                    Params
                    Return values
                    -

                    [method]resolve-address-stream.subscribe: func

                    +

                    [method]resolve-address-stream.subscribe: func

                    Create a pollable which will resolve once the stream is ready for I/O.

                    -

                    Note: this function is here for WASI Preview2 only. +

                    Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                    Params
                    Return values
                    -

                    Import interface wasi:random/random@0.2.1

                    +

                    Import interface wasi:random/random@0.2.2

                    WASI Random is a random data API.

                    It is intended to be portable at least between Unix-family platforms and Windows.


                    Functions

                    -

                    get-random-bytes: func

                    +

                    get-random-bytes: func

                    Return len cryptographically-secure random or pseudo-random bytes.

                    This function must produce data at least as cryptographically secure and fast as an adequately seeded cryptographically-secure pseudo-random @@ -3002,27 +2999,27 @@ must omit this function, rather than implementing it with deterministic data.

                    Params
                      -
                    • len: u64
                    • +
                    • len: u64
                    Return values
                      -
                    • list<u8>
                    • +
                    • list<u8>
                    -

                    get-random-u64: func

                    +

                    get-random-u64: func

                    Return a cryptographically-secure random or pseudo-random u64 value.

                    This function returns the same type of data as get-random-bytes, represented as a u64.

                    Return values
                      -
                    • u64
                    • +
                    • u64
                    -

                    Import interface wasi:random/insecure@0.2.1

                    +

                    Import interface wasi:random/insecure@0.2.2

                    The insecure interface for insecure pseudo-random numbers.

                    It is intended to be portable at least between Unix-family platforms and Windows.


                    Functions

                    -

                    get-insecure-random-bytes: func

                    +

                    get-insecure-random-bytes: func

                    Return len insecure pseudo-random bytes.

                    This function is not cryptographically secure. Do not use it for anything related to security.

                    @@ -3031,27 +3028,27 @@ implementations are encouraged to return evenly distributed values with a long period.

                    Params
                      -
                    • len: u64
                    • +
                    • len: u64
                    Return values
                      -
                    • list<u8>
                    • +
                    • list<u8>
                    -

                    get-insecure-random-u64: func

                    +

                    get-insecure-random-u64: func

                    Return an insecure pseudo-random u64 value.

                    This function returns the same type of pseudo-random data as get-insecure-random-bytes, represented as a u64.

                    Return values
                      -
                    • u64
                    • +
                    • u64
                    -

                    Import interface wasi:random/insecure-seed@0.2.1

                    +

                    Import interface wasi:random/insecure-seed@0.2.2

                    The insecure-seed interface for seeding hash-map DoS resistance.

                    It is intended to be portable at least between Unix-family platforms and Windows.


                    Functions

                    -

                    insecure-seed: func

                    +

                    insecure-seed: func

                    Return a 128-bit value that may contain a pseudo-random value.

                    The returned value is not required to be computed from a CSPRNG, and may even be entirely deterministic. Host implementations are encouraged to @@ -3067,14 +3064,14 @@ called multiple times and potentially used for purposes other than DoS protection.

                    Return values
                      -
                    • (u64, u64)
                    • +
                    • (u64, u64)
                    -

                    Export interface wasi:cli/run@0.2.1

                    +

                    Export interface wasi:cli/run@0.2.2


                    Functions

                    -

                    run: func

                    +

                    run: func

                    Run the program.

                    Return values
                      -
                    • result
                    • +
                    • result
                    diff --git a/proposals/cli/imports.md b/proposals/cli/imports.md index ab22b2ad8..b6aad62e9 100644 --- a/proposals/cli/imports.md +++ b/proposals/cli/imports.md @@ -1,41 +1,41 @@ -

                    World imports

                    +

                    World imports

                    -

                    Import interface wasi:cli/environment@0.2.1

                    +
                  1. interface wasi:cli/environment@0.2.2
                  2. +
                  3. interface wasi:cli/exit@0.2.2
                  4. +
                  5. interface wasi:io/error@0.2.2
                  6. +
                  7. interface wasi:io/poll@0.2.2
                  8. +
                  9. interface wasi:io/streams@0.2.2
                  10. +
                  11. interface wasi:cli/stdin@0.2.2
                  12. +
                  13. interface wasi:cli/stdout@0.2.2
                  14. +
                  15. interface wasi:cli/stderr@0.2.2
                  16. +
                  17. interface wasi:cli/terminal-input@0.2.2
                  18. +
                  19. interface wasi:cli/terminal-output@0.2.2
                  20. +
                  21. interface wasi:cli/terminal-stdin@0.2.2
                  22. +
                  23. interface wasi:cli/terminal-stdout@0.2.2
                  24. +
                  25. interface wasi:cli/terminal-stderr@0.2.2
                  26. +
                  27. interface wasi:clocks/monotonic-clock@0.2.2
                  28. +
                  29. interface wasi:clocks/wall-clock@0.2.2
                  30. +
                  31. interface wasi:filesystem/types@0.2.2
                  32. +
                  33. interface wasi:filesystem/preopens@0.2.2
                  34. +
                  35. interface wasi:sockets/network@0.2.2
                  36. +
                  37. interface wasi:sockets/instance-network@0.2.2
                  38. +
                  39. interface wasi:sockets/udp@0.2.2
                  40. +
                  41. interface wasi:sockets/udp-create-socket@0.2.2
                  42. +
                  43. interface wasi:sockets/tcp@0.2.2
                  44. +
                  45. interface wasi:sockets/tcp-create-socket@0.2.2
                  46. +
                  47. interface wasi:sockets/ip-name-lookup@0.2.2
                  48. +
                  49. interface wasi:random/random@0.2.2
                  50. +
                  51. interface wasi:random/insecure@0.2.2
                  52. +
                  53. interface wasi:random/insecure-seed@0.2.2
                  54. + + + +

                    Import interface wasi:cli/environment@0.2.2


                    Functions

                    -

                    get-environment: func

                    +

                    get-environment: func

                    Get the POSIX-style environment variables.

                    Each environment variable is provided as a pair of string variable names and string value.

                    @@ -44,31 +44,31 @@ in the component model, this import function should return the same values each time it is called.

                    Return values
                      -
                    • list<(string, string)>
                    • +
                    • list<(string, string)>
                    -

                    get-arguments: func

                    +

                    get-arguments: func

                    Get the POSIX-style arguments to the program.

                    Return values
                      -
                    • list<string>
                    • +
                    • list<string>
                    -

                    initial-cwd: func

                    +

                    initial-cwd: func

                    Return a path that programs should use as their initial current working directory, interpreting . as shorthand for this.

                    Return values
                      -
                    • option<string>
                    • +
                    • option<string>
                    -

                    Import interface wasi:cli/exit@0.2.1

                    +

                    Import interface wasi:cli/exit@0.2.2


                    Functions

                    -

                    exit: func

                    +

                    exit: func

                    Exit the current instance and any linked instances.

                    Params
                      -
                    • status: result
                    • +
                    • status: result
                    -

                    exit-with-code: func

                    +

                    exit-with-code: func

                    Exit the current instance and any linked instances, reporting the specified status code to the host.

                    The meaning of the code depends on the context, with 0 usually meaning @@ -77,12 +77,12 @@ specified status code to the host.

                    without the connotation that something bad has happened.

                    Params
                      -
                    • status-code: u8
                    • +
                    • status-code: u8
                    -

                    Import interface wasi:io/error@0.2.1

                    +

                    Import interface wasi:io/error@0.2.2


                    Types

                    -

                    resource error

                    +

                    resource error

                    A resource which represents some error information.

                    The only method provided by this resource is to-debug-string, which provides some human-readable information about the error.

                    @@ -97,7 +97,7 @@ parameter and returns an option<wasi:filesystem/types/error-code>The set of functions which can "downcast" an error into a more concrete type is open.

                    Functions

                    -

                    [method]error.to-debug-string: func

                    +

                    [method]error.to-debug-string: func

                    Returns a string that is suitable to assist humans in debugging this error.

                    WARNING: The returned string should not be consumed mechanically! @@ -106,41 +106,41 @@ details. Parsing this string is a major platform-compatibility hazard.

                    Params
                    Return values
                      -
                    • string
                    • +
                    • string
                    -

                    Import interface wasi:io/poll@0.2.1

                    +

                    Import interface wasi:io/poll@0.2.2

                    A poll API intended to let users wait for I/O events on multiple handles at once.


                    Types

                    -

                    resource pollable

                    +

                    resource pollable

                    pollable represents a single I/O event which may be ready, or not.

                    Functions

                    -

                    [method]pollable.ready: func

                    +

                    [method]pollable.ready: func

                    Return the readiness of a pollable. This function never blocks.

                    Returns true when the pollable is ready, and false otherwise.

                    Params
                    Return values
                      -
                    • bool
                    • +
                    • bool
                    -

                    [method]pollable.block: func

                    +

                    [method]pollable.block: func

                    block returns immediately if the pollable is ready, and otherwise blocks until ready.

                    This function is equivalent to calling poll.poll on a list containing only this pollable.

                    Params
                    -

                    poll: func

                    +

                    poll: func

                    Poll for completion on a set of pollables.

                    This function takes a list of pollables, which identify I/O sources of interest, and waits until one or more of the events is ready for I/O.

                    @@ -159,42 +159,44 @@ the pollables has an error, it is indicated by marking the source as being ready for I/O.

                    Params
                    Return values
                      -
                    • list<u32>
                    • +
                    • list<u32>
                    -

                    Import interface wasi:io/streams@0.2.1

                    +

                    Import interface wasi:io/streams@0.2.2

                    WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                    In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.


                    Types

                    -

                    type error

                    +

                    type error

                    error

                    -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

                    -#### `variant stream-error` +#### `variant stream-error`

                    An error for input-stream and output-stream operations.

                    Variant Cases
                    • -

                      last-operation-failed: own<error>

                      +

                      last-operation-failed: own<error>

                      The last operation (a write or flush) failed before completion.

                      More information is available in the error payload.

                      +

                      After this, the stream will be closed. All future operations return +stream-error::closed.

                    • -

                      closed

                      +

                      closed

                      The stream is closed: no more input will be accepted by the stream. A closed output-stream will return this error on all future operations.

                    -

                    resource input-stream

                    +

                    resource input-stream

                    An input bytestream.

                    input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are @@ -202,7 +204,7 @@ promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

                    -

                    resource output-stream

                    +

                    resource output-stream

                    An output bytestream.

                    output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also @@ -214,7 +216,7 @@ polled for using wasi:io/poll.

                    progress may result in the data being lost. Before dropping the stream, be sure to fully flush your writes.

                    Functions

                    -

                    [method]input-stream.read: func

                    +

                    [method]input-stream.read: func

                    Perform a non-blocking read from the stream.

                    When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the @@ -238,51 +240,51 @@ as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

                    Params
                    Return values
                    -

                    [method]input-stream.blocking-read: func

                    +

                    [method]input-stream.blocking-read: func

                    Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

                    Params
                    Return values
                    -

                    [method]input-stream.skip: func

                    +

                    [method]input-stream.skip: func

                    Skip bytes from a stream. Returns number of bytes skipped.

                    Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

                    Params
                    Return values
                    -

                    [method]input-stream.blocking-skip: func

                    +

                    [method]input-stream.blocking-skip: func

                    Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

                    Params
                    Return values
                    -

                    [method]input-stream.subscribe: func

                    +

                    [method]input-stream.subscribe: func

                    Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. @@ -291,13 +293,13 @@ Implementations may trap if the input-streampollables created with this function are dropped.

                    Params
                    Return values
                    -

                    [method]output-stream.check-write: func

                    +

                    [method]output-stream.check-write: func

                    Check readiness for writing. This function never blocks.

                    Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has @@ -307,13 +309,13 @@ become ready when this function will report at least 1 byte, or an error.

                    Params
                    Return values
                    -

                    [method]output-stream.write: func

                    +

                    [method]output-stream.write: func

                    Perform a write. This function never blocks.

                    When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is @@ -326,14 +328,14 @@ length of less than or equal to n. Otherwise, this function will trap.

                    the last call to check-write provided a permit.

                    Params
                    Return values
                    -

                    [method]output-stream.blocking-write-and-flush: func

                    +

                    [method]output-stream.blocking-write-and-flush: func

                    Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                    This is a convenience wrapper around the use of check-write, @@ -357,14 +359,14 @@ let _ = this.check-write(); // eliding error handling

                    Params
                    Return values
                    -

                    [method]output-stream.flush: func

                    +

                    [method]output-stream.flush: func

                    Request to flush buffered output. This function never blocks.

                    This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed @@ -375,24 +377,24 @@ completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

                    Params
                    Return values
                    -

                    [method]output-stream.blocking-flush: func

                    +

                    [method]output-stream.blocking-flush: func

                    Request to flush buffered output, and block until flush completes and stream is ready for writing again.

                    Params
                    Return values
                    -

                    [method]output-stream.subscribe: func

                    +

                    [method]output-stream.subscribe: func

                    Create a pollable which will resolve once the output-stream is ready for more writing, or an error has occurred. When this pollable is ready, check-write will return ok(n) with n>0, or an @@ -403,13 +405,13 @@ Implementations may trap if the output-streampollables created with this function are dropped.

                    Params
                    Return values
                    -

                    [method]output-stream.write-zeroes: func

                    +

                    [method]output-stream.write-zeroes: func

                    Write zeroes to a stream.

                    This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of @@ -417,14 +419,14 @@ passing a list of bytes, you simply pass the number of zero-bytes that should be written.

                    Params
                    Return values
                    -

                    [method]output-stream.blocking-write-zeroes-and-flush: func

                    +

                    [method]output-stream.blocking-write-zeroes-and-flush: func

                    Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                    @@ -448,14 +450,14 @@ let _ = this.check-write(); // eliding error handling
                    Params
                    Return values
                    -

                    [method]output-stream.splice: func

                    +

                    [method]output-stream.splice: func

                    Read from one stream and write to another.

                    The behavior of splice is equivalent to:

                      @@ -470,138 +472,138 @@ let _ = this.check-write(); // eliding error handling than len.

                      Params
                      Return values
                      -

                      [method]output-stream.blocking-splice: func

                      +

                      [method]output-stream.blocking-splice: func

                      Read from one stream and write to another, with blocking.

                      This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

                      Params
                      Return values
                      -

                      Import interface wasi:cli/stdin@0.2.1

                      +

                      Import interface wasi:cli/stdin@0.2.2


                      Types

                      -

                      type input-stream

                      +

                      type input-stream

                      input-stream

                      ----

                      Functions

                      -

                      get-stdin: func

                      +

                      get-stdin: func

                      Return values
                      -

                      Import interface wasi:cli/stdout@0.2.1

                      +

                      Import interface wasi:cli/stdout@0.2.2


                      Types

                      -

                      type output-stream

                      +

                      type output-stream

                      output-stream

                      ----

                      Functions

                      -

                      get-stdout: func

                      +

                      get-stdout: func

                      Return values
                      -

                      Import interface wasi:cli/stderr@0.2.1

                      +

                      Import interface wasi:cli/stderr@0.2.2


                      Types

                      -

                      type output-stream

                      +

                      type output-stream

                      output-stream

                      ----

                      Functions

                      -

                      get-stderr: func

                      +

                      get-stderr: func

                      Return values
                      -

                      Import interface wasi:cli/terminal-input@0.2.1

                      +

                      Import interface wasi:cli/terminal-input@0.2.2

                      Terminal input.

                      In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through immediately, querying supported features, and so on.


                      Types

                      -

                      resource terminal-input

                      +

                      resource terminal-input

                      The input side of a terminal.

                      -

                      Import interface wasi:cli/terminal-output@0.2.1

                      +

                      Import interface wasi:cli/terminal-output@0.2.2

                      Terminal output.

                      In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported features, and so on.


                      Types

                      -

                      resource terminal-output

                      +

                      resource terminal-output

                      The output side of a terminal.

                      -

                      Import interface wasi:cli/terminal-stdin@0.2.1

                      +

                      Import interface wasi:cli/terminal-stdin@0.2.2

                      An interface providing an optional terminal-input for stdin as a link-time authority.


                      Types

                      -

                      type terminal-input

                      +

                      type terminal-input

                      terminal-input

                      ----

                      Functions

                      -

                      get-terminal-stdin: func

                      +

                      get-terminal-stdin: func

                      If stdin is connected to a terminal, return a terminal-input handle allowing further interaction with it.

                      Return values
                      -

                      Import interface wasi:cli/terminal-stdout@0.2.1

                      +

                      Import interface wasi:cli/terminal-stdout@0.2.2

                      An interface providing an optional terminal-output for stdout as a link-time authority.


                      Types

                      -

                      type terminal-output

                      +

                      type terminal-output

                      terminal-output

                      ----

                      Functions

                      -

                      get-terminal-stdout: func

                      +

                      get-terminal-stdout: func

                      If stdout is connected to a terminal, return a terminal-output handle allowing further interaction with it.

                      Return values
                      -

                      Import interface wasi:cli/terminal-stderr@0.2.1

                      +

                      Import interface wasi:cli/terminal-stderr@0.2.2

                      An interface providing an optional terminal-output for stderr as a link-time authority.


                      Types

                      -

                      type terminal-output

                      +

                      type terminal-output

                      terminal-output

                      ----

                      Functions

                      -

                      get-terminal-stderr: func

                      +

                      get-terminal-stderr: func

                      If stderr is connected to a terminal, return a terminal-output handle allowing further interaction with it.

                      Return values
                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.1

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.2

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -610,57 +612,57 @@ Windows.

                      successive reads of the clock will produce non-decreasing values.


                      Types

                      -

                      type pollable

                      +

                      type pollable

                      pollable

                      -#### `type instant` +#### `type instant` `u64`

                      An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. -

                      type duration

                      +

                      type duration

                      u64

                      A duration of time, in nanoseconds.


                      Functions

                      -

                      now: func

                      +

                      now: func

                      Read the current value of the clock.

                      The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

                      Return values
                      -

                      resolution: func

                      +

                      resolution: func

                      Query the resolution of the clock. Returns the duration of time corresponding to a clock tick.

                      Return values
                      -

                      subscribe-instant: func

                      +

                      subscribe-instant: func

                      Create a pollable which will resolve once the specified instant has occurred.

                      Params
                      Return values
                      -

                      subscribe-duration: func

                      +

                      subscribe-duration: func

                      Create a pollable that will resolve after the specified duration has elapsed from the time this function is invoked.

                      Params
                      Return values
                      -

                      Import interface wasi:clocks/wall-clock@0.2.1

                      +

                      Import interface wasi:clocks/wall-clock@0.2.2

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -673,16 +675,16 @@ monotonic, making it unsuitable for measuring elapsed time.

                      It is intended for reporting the current date and time for humans.


                      Types

                      -

                      record datetime

                      +

                      record datetime

                      A time and date in seconds plus nanoseconds.

                      Record Fields
                        -
                      • seconds: u64
                      • -
                      • nanoseconds: u32
                      • +
                      • seconds: u64
                      • +
                      • nanoseconds: u32

                      Functions

                      -

                      now: func

                      +

                      now: func

                      Read the current value of the clock.

                      This clock is not monotonic, therefore calling this function repeatedly will not necessarily produce a sequence of non-decreasing values.

                      @@ -692,16 +694,16 @@ also known as Unix Time.The nanoseconds field of the output is always less than 1000000000.

                      Return values
                      -

                      resolution: func

                      +

                      resolution: func

                      Query the resolution of the clock.

                      The nanoseconds field of the output is always less than 1000000000.

                      Return values
                      -

                      Import interface wasi:filesystem/types@0.2.1

                      +

                      Import interface wasi:filesystem/types@0.2.2

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                      @@ -721,75 +723,75 @@ underlying filesystem, the function fails with WASI filesystem path resolution.


                      Types

                      -

                      type input-stream

                      +

                      type input-stream

                      input-stream

                      -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

                      -#### `type error` +#### `type error` [`error`](#error)

                      -#### `type datetime` +#### `type datetime` [`datetime`](#datetime)

                      -#### `type filesize` +#### `type filesize` `u64`

                      File size or length of a region within a file. -

                      enum descriptor-type

                      +

                      enum descriptor-type

                      The type of a filesystem object referenced by a descriptor.

                      Note: This was called filetype in earlier versions of WASI.

                      Enum Cases
                      • -

                        unknown

                        +

                        unknown

                        The type of the descriptor or file is unknown or is different from any of the other types specified.

                      • -

                        block-device

                        +

                        block-device

                        The descriptor refers to a block device inode.

                      • -

                        character-device

                        +

                        character-device

                        The descriptor refers to a character device inode.

                      • -

                        directory

                        +

                        directory

                        The descriptor refers to a directory inode.

                      • -

                        fifo

                        +

                        fifo

                        The descriptor refers to a named pipe.

                      • -

                        symbolic-link

                        +

                        symbolic-link

                        The file refers to a symbolic link inode.

                      • -

                        regular-file

                        +

                        regular-file

                        The descriptor refers to a regular file inode.

                      • -

                        socket

                        +

                        socket

                        The descriptor refers to a socket.

                      -

                      flags descriptor-flags

                      +

                      flags descriptor-flags

                      Descriptor flags.

                      Note: This was called fdflags in earlier versions of WASI.

                      Flags members
                      • -

                        read:

                        +

                        read:

                        Read mode: Data can be read.

                      • -

                        write:

                        +

                        write:

                        Write mode: Data can be written to.

                      • -

                        file-integrity-sync:

                        +

                        file-integrity-sync:

                        Request that writes be performed according to synchronized I/O file integrity completion. The data stored in the file and the file's metadata are synchronized. This is similar to `O_SYNC` in POSIX. @@ -798,7 +800,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

                      • -

                        data-integrity-sync:

                        +

                        data-integrity-sync:

                        Request that writes be performed according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. This is similar to `O_DSYNC` in POSIX. @@ -807,7 +809,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

                      • -

                        requested-write-sync:

                        +

                        requested-write-sync:

                        Requests that reads be performed at the same level of integrity requested for writes. This is similar to `O_RSYNC` in POSIX.

                        The precise semantics of this operation have not yet been defined for @@ -815,7 +817,7 @@ WASI. At this time, it should be interpreted as a request, and not a requirement.

                      • -

                        mutate-directory:

                        +

                        mutate-directory:

                        Mutating directories mode: Directory contents may be mutated.

                        When this flag is unset on a descriptor, operations using the descriptor which would create, rename, delete, modify the data or @@ -825,107 +827,107 @@ they would otherwise succeed.

                        This may only be set on directories.

                      -

                      flags path-flags

                      +

                      flags path-flags

                      Flags determining the method of how paths are resolved.

                      Flags members
                        -
                      • symlink-follow:

                        As long as the resolved path corresponds to a symbolic link, it is +

                      • symlink-follow:

                        As long as the resolved path corresponds to a symbolic link, it is expanded.

                      -

                      flags open-flags

                      +

                      flags open-flags

                      Open flags used by open-at.

                      Flags members
                      • -

                        create:

                        +

                        create:

                        Create file if it does not exist, similar to `O_CREAT` in POSIX.

                      • -

                        directory:

                        +

                        directory:

                        Fail if not a directory, similar to `O_DIRECTORY` in POSIX.

                      • -

                        exclusive:

                        +

                        exclusive:

                        Fail if file already exists, similar to `O_EXCL` in POSIX.

                      • -

                        truncate:

                        +

                        truncate:

                        Truncate file to size 0, similar to `O_TRUNC` in POSIX.

                      -

                      type link-count

                      +

                      type link-count

                      u64

                      Number of hard links to an inode. -

                      record descriptor-stat

                      +

                      record descriptor-stat

                      File attributes.

                      Note: This was called filestat in earlier versions of WASI.

                      Record Fields
                      • -

                        type: descriptor-type

                        +

                        type: descriptor-type

                        File type.

                      • -

                        link-count: link-count

                        +

                        link-count: link-count

                        Number of hard links to the file.

                      • -

                        size: filesize

                        +

                        size: filesize

                        For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link.

                      • -

                        data-access-timestamp: option<datetime>

                        +

                        data-access-timestamp: option<datetime>

                        Last data access timestamp.

                        If the option is none, the platform doesn't maintain an access timestamp for this file.

                      • -

                        data-modification-timestamp: option<datetime>

                        +

                        data-modification-timestamp: option<datetime>

                        Last data modification timestamp.

                        If the option is none, the platform doesn't maintain a modification timestamp for this file.

                      • -

                        status-change-timestamp: option<datetime>

                        +

                        status-change-timestamp: option<datetime>

                        Last file status-change timestamp.

                        If the option is none, the platform doesn't maintain a status-change timestamp for this file.

                      -

                      variant new-timestamp

                      +

                      variant new-timestamp

                      When setting a timestamp, this gives the value to set it to.

                      Variant Cases
                      • -

                        no-change

                        +

                        no-change

                        Leave the timestamp set to its previous value.

                      • -

                        now

                        +

                        now

                        Set the timestamp to the current time of the system clock associated with the filesystem.

                      • -

                        timestamp: datetime

                        +

                        timestamp: datetime

                        Set the timestamp to the given value.

                      -

                      record directory-entry

                      +

                      record directory-entry

                      A directory entry.

                      Record Fields
                      • -

                        type: descriptor-type

                        +

                        type: descriptor-type

                        The type of the file referred to by this directory entry.

                      • -

                        name: string

                        +

                        name: string

                        The name of the object.

                      -

                      enum error-code

                      +

                      enum error-code

                      Error codes returned by functions, similar to errno in POSIX. Not all of these error codes are returned by the functions provided by this API; some are used in higher-level library layers, and others are provided @@ -933,211 +935,211 @@ merely for alignment with POSIX.

                      Enum Cases
                      • -

                        access

                        +

                        access

                        Permission denied, similar to `EACCES` in POSIX.

                      • -

                        would-block

                        +

                        would-block

                        Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX.

                      • -

                        already

                        +

                        already

                        Connection already in progress, similar to `EALREADY` in POSIX.

                      • -

                        bad-descriptor

                        +

                        bad-descriptor

                        Bad descriptor, similar to `EBADF` in POSIX.

                      • -

                        busy

                        +

                        busy

                        Device or resource busy, similar to `EBUSY` in POSIX.

                      • -

                        deadlock

                        +

                        deadlock

                        Resource deadlock would occur, similar to `EDEADLK` in POSIX.

                      • -

                        quota

                        +

                        quota

                        Storage quota exceeded, similar to `EDQUOT` in POSIX.

                      • -

                        exist

                        +

                        exist

                        File exists, similar to `EEXIST` in POSIX.

                      • -

                        file-too-large

                        +

                        file-too-large

                        File too large, similar to `EFBIG` in POSIX.

                      • -

                        illegal-byte-sequence

                        +

                        illegal-byte-sequence

                        Illegal byte sequence, similar to `EILSEQ` in POSIX.

                      • -

                        in-progress

                        +

                        in-progress

                        Operation in progress, similar to `EINPROGRESS` in POSIX.

                      • -

                        interrupted

                        +

                        interrupted

                        Interrupted function, similar to `EINTR` in POSIX.

                      • -

                        invalid

                        +

                        invalid

                        Invalid argument, similar to `EINVAL` in POSIX.

                      • -

                        io

                        +

                        io

                        I/O error, similar to `EIO` in POSIX.

                      • -

                        is-directory

                        +

                        is-directory

                        Is a directory, similar to `EISDIR` in POSIX.

                      • -

                        loop

                        +

                        loop

                        Too many levels of symbolic links, similar to `ELOOP` in POSIX.

                      • -

                        too-many-links

                        +

                        too-many-links

                        Too many links, similar to `EMLINK` in POSIX.

                      • -

                        message-size

                        +

                        message-size

                        Message too large, similar to `EMSGSIZE` in POSIX.

                      • -

                        name-too-long

                        +

                        name-too-long

                        Filename too long, similar to `ENAMETOOLONG` in POSIX.

                      • -

                        no-device

                        +

                        no-device

                        No such device, similar to `ENODEV` in POSIX.

                      • -

                        no-entry

                        +

                        no-entry

                        No such file or directory, similar to `ENOENT` in POSIX.

                      • -

                        no-lock

                        +

                        no-lock

                        No locks available, similar to `ENOLCK` in POSIX.

                      • -

                        insufficient-memory

                        +

                        insufficient-memory

                        Not enough space, similar to `ENOMEM` in POSIX.

                      • -

                        insufficient-space

                        +

                        insufficient-space

                        No space left on device, similar to `ENOSPC` in POSIX.

                      • -

                        not-directory

                        +

                        not-directory

                        Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX.

                      • -

                        not-empty

                        +

                        not-empty

                        Directory not empty, similar to `ENOTEMPTY` in POSIX.

                      • -

                        not-recoverable

                        +

                        not-recoverable

                        State not recoverable, similar to `ENOTRECOVERABLE` in POSIX.

                      • -

                        unsupported

                        +

                        unsupported

                        Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX.

                      • -

                        no-tty

                        +

                        no-tty

                        Inappropriate I/O control operation, similar to `ENOTTY` in POSIX.

                      • -

                        no-such-device

                        +

                        no-such-device

                        No such device or address, similar to `ENXIO` in POSIX.

                      • -

                        overflow

                        +

                        overflow

                        Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX.

                      • -

                        not-permitted

                        +

                        not-permitted

                        Operation not permitted, similar to `EPERM` in POSIX.

                      • -

                        pipe

                        +

                        pipe

                        Broken pipe, similar to `EPIPE` in POSIX.

                      • -

                        read-only

                        +

                        read-only

                        Read-only file system, similar to `EROFS` in POSIX.

                      • -

                        invalid-seek

                        +

                        invalid-seek

                        Invalid seek, similar to `ESPIPE` in POSIX.

                      • -

                        text-file-busy

                        +

                        text-file-busy

                        Text file busy, similar to `ETXTBSY` in POSIX.

                      • -

                        cross-device

                        +

                        cross-device

                        Cross-device link, similar to `EXDEV` in POSIX.

                      -

                      enum advice

                      +

                      enum advice

                      File or memory access pattern advisory information.

                      Enum Cases
                      • -

                        normal

                        +

                        normal

                        The application has no advice to give on its behavior with respect to the specified data.

                      • -

                        sequential

                        +

                        sequential

                        The application expects to access the specified data sequentially from lower offsets to higher offsets.

                      • -

                        random

                        +

                        random

                        The application expects to access the specified data in a random order.

                      • -

                        will-need

                        +

                        will-need

                        The application expects to access the specified data in the near future.

                      • -

                        dont-need

                        +

                        dont-need

                        The application expects that it will not access the specified data in the near future.

                      • -

                        no-reuse

                        +

                        no-reuse

                        The application expects to access the specified data once and then not reuse it thereafter.

                      -

                      record metadata-hash-value

                      +

                      record metadata-hash-value

                      A 128-bit hash value, split into parts because wasm doesn't have a 128-bit integer type.

                      Record Fields
                      • -

                        lower: u64

                        +

                        lower: u64

                        64 bits of a 128-bit hash value.

                      • -

                        upper: u64

                        +

                        upper: u64

                        Another 64 bits of a 128-bit hash value.

                      -

                      resource descriptor

                      +

                      resource descriptor

                      A descriptor is a reference to a filesystem object, which may be a file, directory, named pipe, special file, or other object on which filesystem calls may be made.

                      -

                      resource directory-entry-stream

                      +

                      resource directory-entry-stream

                      A stream of directory entries.

                      Functions

                      -

                      [method]descriptor.read-via-stream: func

                      +

                      [method]descriptor.read-via-stream: func

                      Return a stream for reading from a file, if available.

                      May fail with an error-code describing why the file cannot be read.

                      Multiple read, write, and append streams may be active on the same open @@ -1145,81 +1147,81 @@ file and they do not interfere with each other.

                      Note: This allows using read-stream, which is similar to read in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.write-via-stream: func

                      +

                      [method]descriptor.write-via-stream: func

                      Return a stream for writing to a file, if available.

                      May fail with an error-code describing why the file cannot be written.

                      Note: This allows using write-stream, which is similar to write in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.append-via-stream: func

                      +

                      [method]descriptor.append-via-stream: func

                      Return a stream for appending to a file, if available.

                      May fail with an error-code describing why the file cannot be appended.

                      Note: This allows using write-stream, which is similar to write with O_APPEND in in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.advise: func

                      +

                      [method]descriptor.advise: func

                      Provide file advisory information on a descriptor.

                      This is similar to posix_fadvise in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.sync-data: func

                      +

                      [method]descriptor.sync-data: func

                      Synchronize the data of a file to disk.

                      This function succeeds with no effect if the file descriptor is not opened for writing.

                      Note: This is similar to fdatasync in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.get-flags: func

                      +

                      [method]descriptor.get-flags: func

                      Get flags associated with a descriptor.

                      Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

                      Note: This returns the value that was the fs_flags value returned from fdstat_get in earlier versions of WASI.

                      Params
                      Return values
                      -

                      [method]descriptor.get-type: func

                      +

                      [method]descriptor.get-type: func

                      Get the dynamic type of a descriptor.

                      Note: This returns the same value as the type field of the fd-stat returned by stat, stat-at and similar.

                      @@ -1229,40 +1231,40 @@ by fstat in POSIX.

                      from fdstat_get in earlier versions of WASI.

                      Params
                      Return values
                      -

                      [method]descriptor.set-size: func

                      +

                      [method]descriptor.set-size: func

                      Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.

                      Note: This was called fd_filestat_set_size in earlier versions of WASI.

                      Params
                      Return values
                      -

                      [method]descriptor.set-times: func

                      +

                      [method]descriptor.set-times: func

                      Adjust the timestamps of an open file or directory.

                      Note: This is similar to futimens in POSIX.

                      Note: This was called fd_filestat_set_times in earlier versions of WASI.

                      Params
                      Return values
                      -

                      [method]descriptor.read: func

                      +

                      [method]descriptor.read: func

                      Read from a descriptor, without using and updating the descriptor's offset.

                      This function returns a list of bytes containing the data that was read, along with a bool which, when true, indicates that the end of the @@ -1273,15 +1275,15 @@ if the I/O operation is interrupted.

                      Note: This is similar to pread in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.write: func

                      +

                      [method]descriptor.write: func

                      Write to a descriptor, without using and updating the descriptor's offset.

                      It is valid to write past the end of a file; the file is extended to the extent of the write, with bytes between the previous end and the start of @@ -1290,15 +1292,15 @@ the write set to zero.

                      Note: This is similar to pwrite in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.read-directory: func

                      +

                      [method]descriptor.read-directory: func

                      Read directory entries from a directory.

                      On filesystems where directories contain entries referring to themselves and their parents, often named . and .. respectively, these entries @@ -1308,38 +1310,38 @@ directory. Multiple streams may be active on the same directory, and they do not interfere with each other.

                      Params
                      Return values
                      -

                      [method]descriptor.sync: func

                      +

                      [method]descriptor.sync: func

                      Synchronize the data and metadata of a file to disk.

                      This function succeeds with no effect if the file descriptor is not opened for writing.

                      Note: This is similar to fsync in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.create-directory-at: func

                      +

                      [method]descriptor.create-directory-at: func

                      Create a directory.

                      Note: This is similar to mkdirat in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.stat: func

                      +

                      [method]descriptor.stat: func

                      Return the attributes of an open file or directory.

                      Note: This is similar to fstat in POSIX, except that it does not return device and inode information. For testing whether two descriptors refer to @@ -1349,13 +1351,13 @@ modified, use metadata-hash.

                      Note: This was called fd_filestat_get in earlier versions of WASI.

                      Params
                      Return values
                      -

                      [method]descriptor.stat-at: func

                      +

                      [method]descriptor.stat-at: func

                      Return the attributes of a file or directory.

                      Note: This is similar to fstatat in POSIX, except that it does not return device and inode information. See the stat description for a @@ -1363,53 +1365,48 @@ discussion of alternatives.

                      Note: This was called path_filestat_get in earlier versions of WASI.

                      Params
                      Return values
                      -

                      [method]descriptor.set-times-at: func

                      +

                      [method]descriptor.set-times-at: func

                      Adjust the timestamps of a file or directory.

                      Note: This is similar to utimensat in POSIX.

                      Note: This was called path_filestat_set_times in earlier versions of WASI.

                      Params
                      Return values
                      -

                      [method]descriptor.link-at: func

                      +

                      [method]descriptor.link-at: func

                      Create a hard link.

                      Note: This is similar to linkat in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.open-at: func

                      +

                      [method]descriptor.open-at: func

                      Open a file or directory.

                      -

                      The returned descriptor is not guaranteed to be the lowest-numbered -descriptor not currently open/ it is randomized to prevent applications -from depending on making assumptions about indexes, since this is -error-prone in multi-threaded contexts. The returned descriptor is -guaranteed to be less than 2**31.

                      If flags contains descriptor-flags::mutate-directory, and the base descriptor doesn't have descriptor-flags::mutate-directory set, open-at fails with error-code::read-only.

                      @@ -1420,86 +1417,86 @@ contains truncate or create, and the base descriptor d

                      Note: This is similar to openat in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.readlink-at: func

                      +

                      [method]descriptor.readlink-at: func

                      Read the contents of a symbolic link.

                      If the contents contain an absolute or rooted path in the underlying filesystem, this function fails with error-code::not-permitted.

                      Note: This is similar to readlinkat in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.remove-directory-at: func

                      +

                      [method]descriptor.remove-directory-at: func

                      Remove a directory.

                      Return error-code::not-empty if the directory is not empty.

                      Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.rename-at: func

                      +

                      [method]descriptor.rename-at: func

                      Rename a filesystem object.

                      Note: This is similar to renameat in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.symlink-at: func

                      +

                      [method]descriptor.symlink-at: func

                      Create a symbolic link (also known as a "symlink").

                      If old-path starts with /, the function fails with error-code::not-permitted.

                      Note: This is similar to symlinkat in POSIX.

                      Params
                        -
                      • self: borrow<descriptor>
                      • -
                      • old-path: string
                      • -
                      • new-path: string
                      • +
                      • self: borrow<descriptor>
                      • +
                      • old-path: string
                      • +
                      • new-path: string
                      Return values
                      -

                      [method]descriptor.unlink-file-at: func

                      +

                      [method]descriptor.unlink-file-at: func

                      Unlink a filesystem object that is not a directory.

                      Return error-code::is-directory if the path refers to a directory. Note: This is similar to unlinkat(fd, path, 0) in POSIX.

                      Params
                      Return values
                      -

                      [method]descriptor.is-same-object: func

                      +

                      [method]descriptor.is-same-object: func

                      Test whether two descriptors refer to the same filesystem object.

                      In POSIX, this corresponds to testing whether the two descriptors have the same device (st_dev) and inode (st_ino or d_ino) numbers. @@ -1507,14 +1504,14 @@ wasi-filesystem does not expose device and inode numbers, so this function may be used instead.

                      Params
                      Return values
                        -
                      • bool
                      • +
                      • bool
                      -

                      [method]descriptor.metadata-hash: func

                      +

                      [method]descriptor.metadata-hash: func

                      Return a hash of the metadata associated with a filesystem object referred to by a descriptor.

                      This returns a hash of the last-modification timestamp and file size, and @@ -1534,37 +1531,37 @@ computed hash.

                      However, none of these is required.

                      Params
                      Return values
                      -

                      [method]descriptor.metadata-hash-at: func

                      +

                      [method]descriptor.metadata-hash-at: func

                      Return a hash of the metadata associated with a filesystem object referred to by a directory descriptor and a relative path.

                      This performs the same hash computation as metadata-hash.

                      Params
                      Return values
                      -

                      [method]directory-entry-stream.read-directory-entry: func

                      +

                      [method]directory-entry-stream.read-directory-entry: func

                      Read a single directory entry from a directory-entry-stream.

                      Params
                      Return values
                      -

                      filesystem-error-code: func

                      +

                      filesystem-error-code: func

                      Attempts to extract a filesystem-related error-code from the stream error provided.

                      Stream operations which return stream-error::last-operation-failed @@ -1575,34 +1572,34 @@ filesystem-related information about the error to return.

                      errors are filesystem-related errors.

                      Params
                      Return values
                      -

                      Import interface wasi:filesystem/preopens@0.2.1

                      +

                      Import interface wasi:filesystem/preopens@0.2.2


                      Types

                      -

                      type descriptor

                      +

                      type descriptor

                      descriptor

                      ----

                      Functions

                      -

                      get-directories: func

                      +

                      get-directories: func

                      Return the set of preopened directories, and their path.

                      Return values
                      -

                      Import interface wasi:sockets/network@0.2.1

                      +

                      Import interface wasi:sockets/network@0.2.2


                      Types

                      -

                      resource network

                      +

                      resource network

                      An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                      -

                      enum error-code

                      +

                      enum error-code

                      Error codes.

                      In theory, every API can return any error code. In practice, API's typically only return the errors documented per API @@ -1618,235 +1615,235 @@ combined with a couple of errors that are always possible:

                      Enum Cases
                      • -

                        unknown

                        +

                        unknown

                        Unknown error

                      • -

                        access-denied

                        +

                        access-denied

                        Access denied.

                        POSIX equivalent: EACCES, EPERM

                      • -

                        not-supported

                        +

                        not-supported

                        The operation is not supported.

                        POSIX equivalent: EOPNOTSUPP

                      • -

                        invalid-argument

                        +

                        invalid-argument

                        One of the arguments is invalid.

                        POSIX equivalent: EINVAL

                      • -

                        out-of-memory

                        +

                        out-of-memory

                        Not enough memory to complete the operation.

                        POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY

                      • -

                        timeout

                        +

                        timeout

                        The operation timed out before it could finish completely.

                      • -

                        concurrency-conflict

                        +

                        concurrency-conflict

                        This operation is incompatible with another asynchronous operation that is already in progress.

                        POSIX equivalent: EALREADY

                      • -

                        not-in-progress

                        +

                        not-in-progress

                        Trying to finish an asynchronous operation that: - has not been started yet, or: - was already finished by a previous `finish-*` call.

                        Note: this is scheduled to be removed when futures are natively supported.

                      • -

                        would-block

                        +

                        would-block

                        The operation has been aborted because it could not be completed immediately.

                        Note: this is scheduled to be removed when futures are natively supported.

                      • -

                        invalid-state

                        +

                        invalid-state

                        The operation is not valid in the socket's current state.

                      • -

                        new-socket-limit

                        +

                        new-socket-limit

                        A new socket resource could not be created because of a system limit.

                      • -

                        address-not-bindable

                        +

                        address-not-bindable

                        A bind operation failed because the provided address is not an address that the `network` can bind to.

                      • -

                        address-in-use

                        +

                        address-in-use

                        A bind operation failed because the provided address is already in use or because there are no ephemeral ports available.

                      • -

                        remote-unreachable

                        +

                        remote-unreachable

                        The remote address is not reachable

                      • -

                        connection-refused

                        +

                        connection-refused

                        The TCP connection was forcefully rejected

                      • -

                        connection-reset

                        +

                        connection-reset

                        The TCP connection was reset.

                      • -

                        connection-aborted

                        +

                        connection-aborted

                        A TCP connection was aborted.

                      • -

                        datagram-too-large

                        +

                        datagram-too-large

                        The size of a datagram sent to a UDP socket exceeded the maximum supported size.

                      • -

                        name-unresolvable

                        +

                        name-unresolvable

                        Name does not exist or has no suitable associated IP addresses.

                      • -

                        temporary-resolver-failure

                        +

                        temporary-resolver-failure

                        A temporary failure in name resolution occurred.

                      • -

                        permanent-resolver-failure

                        +

                        permanent-resolver-failure

                        A permanent failure in name resolution occurred.

                      -

                      enum ip-address-family

                      +

                      enum ip-address-family

                      Enum Cases
                      • -

                        ipv4

                        +

                        ipv4

                        Similar to `AF_INET` in POSIX.

                      • -

                        ipv6

                        +

                        ipv6

                        Similar to `AF_INET6` in POSIX.

                      -

                      tuple ipv4-address

                      +

                      tuple ipv4-address

                      Tuple Fields
                        -
                      • 0: u8
                      • -
                      • 1: u8
                      • -
                      • 2: u8
                      • -
                      • 3: u8
                      • +
                      • 0: u8
                      • +
                      • 1: u8
                      • +
                      • 2: u8
                      • +
                      • 3: u8
                      -

                      tuple ipv6-address

                      +

                      tuple ipv6-address

                      Tuple Fields
                        -
                      • 0: u16
                      • -
                      • 1: u16
                      • -
                      • 2: u16
                      • -
                      • 3: u16
                      • -
                      • 4: u16
                      • -
                      • 5: u16
                      • -
                      • 6: u16
                      • -
                      • 7: u16
                      • +
                      • 0: u16
                      • +
                      • 1: u16
                      • +
                      • 2: u16
                      • +
                      • 3: u16
                      • +
                      • 4: u16
                      • +
                      • 5: u16
                      • +
                      • 6: u16
                      • +
                      • 7: u16
                      -

                      variant ip-address

                      +

                      variant ip-address

                      Variant Cases
                      -

                      record ipv4-socket-address

                      +

                      record ipv4-socket-address

                      Record Fields
                      -

                      record ipv6-socket-address

                      +

                      record ipv6-socket-address

                      Record Fields
                      • -

                        port: u16

                        +

                        port: u16

                        sin6_port

                      • -

                        flow-info: u32

                        +

                        flow-info: u32

                        sin6_flowinfo

                      • -

                        address: ipv6-address

                        +

                        address: ipv6-address

                        sin6_addr

                      • -

                        scope-id: u32

                        +

                        scope-id: u32

                        sin6_scope_id

                      -

                      variant ip-socket-address

                      +

                      variant ip-socket-address

                      Variant Cases
                      -

                      Import interface wasi:sockets/instance-network@0.2.1

                      +

                      Import interface wasi:sockets/instance-network@0.2.2

                      This interface provides a value-export of the default network handle..


                      Types

                      -

                      type network

                      +

                      type network

                      network

                      ----

                      Functions

                      -

                      instance-network: func

                      +

                      instance-network: func

                      Get a handle to the default network.

                      Return values
                      -

                      Import interface wasi:sockets/udp@0.2.1

                      +

                      Import interface wasi:sockets/udp@0.2.2


                      Types

                      -

                      type pollable

                      +

                      type pollable

                      pollable

                      -#### `type network` +#### `type network` [`network`](#network)

                      -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                      -#### `type ip-socket-address` +#### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address)

                      -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                      -#### `record incoming-datagram` +#### `record incoming-datagram`

                      A received datagram.

                      Record Fields
                      • -

                        data: list<u8>

                        +

                        data: list<u8>

                        The payload.

                        Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes.

                      • -

                        remote-address: ip-socket-address

                        +

                        remote-address: ip-socket-address

                        The source address.

                        This field is guaranteed to match the remote address the stream was initialized with, if any.

                        Equivalent to the src_addr out parameter of recvfrom.

                      -

                      record outgoing-datagram

                      +

                      record outgoing-datagram

                      A datagram to be sent out.

                      Record Fields
                      • -

                        data: list<u8>

                        +

                        data: list<u8>

                        The payload.

                      • -

                        remote-address: option<ip-socket-address>

                        +

                        remote-address: option<ip-socket-address>

                        The destination address.

                        The requirements on this field depend on how the stream was initialized:

                          @@ -1856,13 +1853,13 @@ supported size.

                          If this value is None, the send operation is equivalent to send in POSIX. Otherwise it is equivalent to sendto.

                        -

                        resource udp-socket

                        +

                        resource udp-socket

                        A UDP socket handle.

                        -

                        resource incoming-datagram-stream

                        -

                        resource outgoing-datagram-stream

                        +

                        resource incoming-datagram-stream

                        +

                        resource outgoing-datagram-stream


                        Functions

                        -

                        [method]udp-socket.start-bind: func

                        +

                        [method]udp-socket.start-bind: func

                        Bind the socket to a specific network on the provided IP address and port.

                        If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -1891,24 +1888,24 @@ don't want to make use of this ability can simply call the native

                      Params
                      Return values
                      -

                      [method]udp-socket.finish-bind: func

                      +

                      [method]udp-socket.finish-bind: func

                      Params
                      Return values
                      -

                      [method]udp-socket.stream: func

                      +

                      [method]udp-socket.stream: func

                      Set up inbound & outbound communication channels, optionally to a specific peer.

                      This function only changes the local socket configuration and does not generate any network traffic. On success, the remote-address of the socket is updated. The local-address may be updated as well, @@ -1949,14 +1946,14 @@ if (remote_address is Some) {

                      Params
                      Return values
                      -

                      [method]udp-socket.local-address: func

                      +

                      [method]udp-socket.local-address: func

                      Get the current bound address.

                      POSIX mentions:

                      @@ -1977,13 +1974,13 @@ stored in the object pointed to by address is unspecified.

                      Params
                      Return values
                      -

                      [method]udp-socket.remote-address: func

                      +

                      [method]udp-socket.remote-address: func

                      Get the address the socket is currently streaming to.

                      Typical errors

                        @@ -1998,24 +1995,24 @@ stored in the object pointed to by address is unspecified.

                      Params
                      Return values
                      -

                      [method]udp-socket.address-family: func

                      +

                      [method]udp-socket.address-family: func

                      Whether this is a IPv4 or IPv6 socket.

                      Equivalent to the SO_DOMAIN socket option.

                      Params
                      Return values
                      -

                      [method]udp-socket.unicast-hop-limit: func

                      +

                      [method]udp-socket.unicast-hop-limit: func

                      Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                      If the provided value is 0, an invalid-argument error is returned.

                      Typical errors

                      @@ -2024,23 +2021,23 @@ stored in the object pointed to by address is unspecified.

                      Params
                      Return values
                      -

                      [method]udp-socket.set-unicast-hop-limit: func

                      +

                      [method]udp-socket.set-unicast-hop-limit: func

                      Params
                      Return values
                      -

                      [method]udp-socket.receive-buffer-size: func

                      +

                      [method]udp-socket.receive-buffer-size: func

                      The kernel buffer space reserved for sends/receives on this socket.

                      If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2052,54 +2049,54 @@ I.e. after setting a value, reading the same setting back may return a different

                      Params
                      Return values
                      -

                      [method]udp-socket.set-receive-buffer-size: func

                      +

                      [method]udp-socket.set-receive-buffer-size: func

                      Params
                      Return values
                      -

                      [method]udp-socket.send-buffer-size: func

                      +

                      [method]udp-socket.send-buffer-size: func

                      Params
                      Return values
                      -

                      [method]udp-socket.set-send-buffer-size: func

                      +

                      [method]udp-socket.set-send-buffer-size: func

                      Params
                      Return values
                      -

                      [method]udp-socket.subscribe: func

                      +

                      [method]udp-socket.subscribe: func

                      Create a pollable which will resolve once the socket is ready for I/O.

                      -

                      Note: this function is here for WASI Preview2 only. +

                      Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                      Params
                      Return values
                      -

                      [method]incoming-datagram-stream.receive: func

                      +

                      [method]incoming-datagram-stream.receive: func

                      Receive messages on the socket.

                      This function attempts to receive up to max-results datagrams on the socket without blocking. The returned list may contain fewer elements than requested, but never more.

                      @@ -2127,26 +2124,26 @@ This function never returns error(would-block).
                      Params
                      Return values
                      -

                      [method]incoming-datagram-stream.subscribe: func

                      +

                      [method]incoming-datagram-stream.subscribe: func

                      Create a pollable which will resolve once the stream is ready to receive again.

                      -

                      Note: this function is here for WASI Preview2 only. +

                      Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                      Params
                      Return values
                      -

                      [method]outgoing-datagram-stream.check-send: func

                      +

                      [method]outgoing-datagram-stream.check-send: func

                      Check readiness for sending. This function never blocks.

                      Returns the number of datagrams permitted for the next call to send, or an error. Calling send with more datagrams than this function has @@ -2157,13 +2154,13 @@ error.

                      Never returns would-block.

                      Params
                      Return values
                      -

                      [method]outgoing-datagram-stream.send: func

                      +

                      [method]outgoing-datagram-stream.send: func

                      Send messages on the socket.

                      This function attempts to send all provided datagrams on the socket without blocking and returns how many messages were actually sent (or queued for sending). This function never @@ -2198,43 +2195,43 @@ either check-send was not called or datagrams contains

                      Params
                      Return values
                      -

                      [method]outgoing-datagram-stream.subscribe: func

                      +

                      [method]outgoing-datagram-stream.subscribe: func

                      Create a pollable which will resolve once the stream is ready to send again.

                      -

                      Note: this function is here for WASI Preview2 only. +

                      Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                      Params
                      Return values
                      -

                      Import interface wasi:sockets/udp-create-socket@0.2.1

                      +

                      Import interface wasi:sockets/udp-create-socket@0.2.2


                      Types

                      -

                      type network

                      +

                      type network

                      network

                      -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                      -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                      -#### `type udp-socket` +#### `type udp-socket` [`udp-socket`](#udp_socket)

                      ----

                      Functions

                      -

                      create-udp-socket: func

                      +

                      create-udp-socket: func

                      Create a new UDP socket.

                      Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX. On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

                      @@ -2256,56 +2253,56 @@ the socket is effectively an in-memory configuration object, unable to communica
                      Params
                      Return values
                      -

                      Import interface wasi:sockets/tcp@0.2.1

                      +

                      Import interface wasi:sockets/tcp@0.2.2


                      Types

                      -

                      type input-stream

                      +

                      type input-stream

                      input-stream

                      -#### `type output-stream` +#### `type output-stream` [`output-stream`](#output_stream)

                      -#### `type pollable` +#### `type pollable` [`pollable`](#pollable)

                      -#### `type duration` +#### `type duration` [`duration`](#duration)

                      -#### `type network` +#### `type network` [`network`](#network)

                      -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                      -#### `type ip-socket-address` +#### `type ip-socket-address` [`ip-socket-address`](#ip_socket_address)

                      -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                      -#### `enum shutdown-type` +#### `enum shutdown-type`

                      Enum Cases
                      • -

                        receive

                        +

                        receive

                        Similar to `SHUT_RD` in POSIX.

                      • -

                        send

                        +

                        send

                        Similar to `SHUT_WR` in POSIX.

                      • -

                        both

                        +

                        both

                        Similar to `SHUT_RDWR` in POSIX.

                      -

                      resource tcp-socket

                      +

                      resource tcp-socket

                      A TCP socket resource.

                      The socket can be in one of the following states:

                        @@ -2327,7 +2324,7 @@ the term "bound" without backticks it actually means: in the bou network::error-code type, TCP socket methods may always return error(invalid-state) when in the closed state.

                        Functions

                        -

                        [method]tcp-socket.start-bind: func

                        +

                        [method]tcp-socket.start-bind: func

                        Bind the socket to a specific network on the provided IP address and port.

                        If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -2366,24 +2363,24 @@ don't want to make use of this ability can simply call the native

                      Params
                      Return values
                      -

                      [method]tcp-socket.finish-bind: func

                      +

                      [method]tcp-socket.finish-bind: func

                      Params
                      Return values
                      -

                      [method]tcp-socket.start-connect: func

                      +

                      [method]tcp-socket.start-connect: func

                      Connect to a remote endpoint.

                      On success:

                      Params
                      Return values
                      -

                      [method]tcp-socket.finish-listen: func

                      +

                      [method]tcp-socket.finish-listen: func

                      Params
                      Return values
                      -

                      [method]tcp-socket.accept: func

                      +

                      [method]tcp-socket.accept: func

                      Accept a new client socket.

                      The returned socket is bound and in the connected state. The following properties are inherited from the listener socket:

                        @@ -2518,13 +2515,13 @@ a pair of streams that can be used to read & write to the connection.

                      Params
                      Return values
                      -

                      [method]tcp-socket.local-address: func

                      +

                      [method]tcp-socket.local-address: func

                      Get the bound local address.

                      POSIX mentions:

                      @@ -2545,13 +2542,13 @@ stored in the object pointed to by address is unspecified.

                      Params
                      Return values
                      -

                      [method]tcp-socket.remote-address: func

                      +

                      [method]tcp-socket.remote-address: func

                      Get the remote address.

                      Typical errors

                        @@ -2566,35 +2563,35 @@ stored in the object pointed to by address is unspecified.

                      Params
                      Return values
                      -

                      [method]tcp-socket.is-listening: func

                      +

                      [method]tcp-socket.is-listening: func

                      Whether the socket is in the listening state.

                      Equivalent to the SO_ACCEPTCONN socket option.

                      Params
                      Return values
                        -
                      • bool
                      • +
                      • bool
                      -

                      [method]tcp-socket.address-family: func

                      +

                      [method]tcp-socket.address-family: func

                      Whether this is a IPv4 or IPv6 socket.

                      Equivalent to the SO_DOMAIN socket option.

                      Params
                      Return values
                      -

                      [method]tcp-socket.set-listen-backlog-size: func

                      +

                      [method]tcp-socket.set-listen-backlog-size: func

                      Hints the desired listen queue size. Implementations are free to ignore this.

                      If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded.

                      @@ -2606,14 +2603,14 @@ Any other value will never cause an error, but it might be silently clamped and/
                      Params
                      Return values
                      -

                      [method]tcp-socket.keep-alive-enabled: func

                      +

                      [method]tcp-socket.keep-alive-enabled: func

                      Enables or disables keepalive.

                      The keepalive behavior can be adjusted using:

                        @@ -2625,23 +2622,23 @@ These properties can be configured while keep-alive-enabled is fals

                        Equivalent to the SO_KEEPALIVE socket option.

                        Params
                        Return values
                        -

                        [method]tcp-socket.set-keep-alive-enabled: func

                        +

                        [method]tcp-socket.set-keep-alive-enabled: func

                        Params
                        Return values
                        -

                        [method]tcp-socket.keep-alive-idle-time: func

                        +

                        [method]tcp-socket.keep-alive-idle-time: func

                        Amount of time the connection has to be idle before TCP starts sending keepalive packets.

                        If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2653,23 +2650,23 @@ I.e. after setting a value, reading the same setting back may return a different

                      Params
                      Return values
                      -

                      [method]tcp-socket.set-keep-alive-idle-time: func

                      +

                      [method]tcp-socket.set-keep-alive-idle-time: func

                      Params
                      Return values
                      -

                      [method]tcp-socket.keep-alive-interval: func

                      +

                      [method]tcp-socket.keep-alive-interval: func

                      The time between keepalive packets.

                      If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2681,23 +2678,23 @@ I.e. after setting a value, reading the same setting back may return a different

                      Params
                      Return values
                      -

                      [method]tcp-socket.set-keep-alive-interval: func

                      +

                      [method]tcp-socket.set-keep-alive-interval: func

                      Params
                      Return values
                      -

                      [method]tcp-socket.keep-alive-count: func

                      +

                      [method]tcp-socket.keep-alive-count: func

                      The maximum amount of keepalive packets TCP should send before aborting the connection.

                      If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2709,23 +2706,23 @@ I.e. after setting a value, reading the same setting back may return a different

                      Params
                      Return values
                      -

                      [method]tcp-socket.set-keep-alive-count: func

                      +

                      [method]tcp-socket.set-keep-alive-count: func

                      Params
                      Return values
                      -

                      [method]tcp-socket.hop-limit: func

                      +

                      [method]tcp-socket.hop-limit: func

                      Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

                      If the provided value is 0, an invalid-argument error is returned.

                      Typical errors

                      @@ -2734,23 +2731,23 @@ I.e. after setting a value, reading the same setting back may return a different
                      Params
                      Return values
                      -

                      [method]tcp-socket.set-hop-limit: func

                      +

                      [method]tcp-socket.set-hop-limit: func

                      Params
                      Return values
                      -

                      [method]tcp-socket.receive-buffer-size: func

                      +

                      [method]tcp-socket.receive-buffer-size: func

                      The kernel buffer space reserved for sends/receives on this socket.

                      If the provided value is 0, an invalid-argument error is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. @@ -2762,42 +2759,42 @@ I.e. after setting a value, reading the same setting back may return a different

                      Params
                      Return values
                      -

                      [method]tcp-socket.set-receive-buffer-size: func

                      +

                      [method]tcp-socket.set-receive-buffer-size: func

                      Params
                      Return values
                      -

                      [method]tcp-socket.send-buffer-size: func

                      +

                      [method]tcp-socket.send-buffer-size: func

                      Params
                      Return values
                      -

                      [method]tcp-socket.set-send-buffer-size: func

                      +

                      [method]tcp-socket.set-send-buffer-size: func

                      Params
                      Return values
                      -

                      [method]tcp-socket.subscribe: func

                      +

                      [method]tcp-socket.subscribe: func

                      Create a pollable which can be used to poll for, or block on, completion of any of the asynchronous operations of this socket.

                      When finish-bind, finish-listen, finish-connect or accept @@ -2809,17 +2806,17 @@ in progress at the time of calling subscribe (if any). Theoreticall (re)used for the remainder of the socket's lifetime.

                      See https://github.com/WebAssembly/wasi-sockets/blob/main/TcpSocketOperationalSemantics.md#pollable-readiness for more information.

                      -

                      Note: this function is here for WASI Preview2 only. +

                      Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                      Params
                      Return values
                      -

                      [method]tcp-socket.shutdown: func

                      +

                      [method]tcp-socket.shutdown: func

                      Initiate a graceful shutdown.

                      • receive: The socket is not expecting to receive any data from @@ -2846,31 +2843,31 @@ has no effect and returns ok.

                      Params
                      Return values
                      -

                      Import interface wasi:sockets/tcp-create-socket@0.2.1

                      +

                      Import interface wasi:sockets/tcp-create-socket@0.2.2


                      Types

                      -

                      type network

                      +

                      type network

                      network

                      -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                      -#### `type ip-address-family` +#### `type ip-address-family` [`ip-address-family`](#ip_address_family)

                      -#### `type tcp-socket` +#### `type tcp-socket` [`tcp-socket`](#tcp_socket)

                      ----

                      Functions

                      -

                      create-tcp-socket: func

                      +

                      create-tcp-socket: func

                      Create a new TCP socket.

                      Similar to socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP) in POSIX. On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.

                      @@ -2892,31 +2889,31 @@ is called, the socket is effectively an in-memory configuration object, unable t
                      Params
                      Return values
                      -

                      Import interface wasi:sockets/ip-name-lookup@0.2.1

                      +

                      Import interface wasi:sockets/ip-name-lookup@0.2.2


                      Types

                      -

                      type pollable

                      +

                      type pollable

                      pollable

                      -#### `type network` +#### `type network` [`network`](#network)

                      -#### `type error-code` +#### `type error-code` [`error-code`](#error_code)

                      -#### `type ip-address` +#### `type ip-address` [`ip-address`](#ip_address)

                      -#### `resource resolve-address-stream` +#### `resource resolve-address-stream`


                      Functions

                      -

                      resolve-addresses: func

                      +

                      resolve-addresses: func

                      Resolve an internet host name to a list of IP addresses.

                      Unicode domain names are automatically converted to ASCII using IDNA encoding. If the input is an IP address string, the address is parsed and returned @@ -2938,14 +2935,14 @@ to (asynchronously) fetch the results.

                      Params
                      Return values
                      -

                      [method]resolve-address-stream.resolve-next-address: func

                      +

                      [method]resolve-address-stream.resolve-next-address: func

                      Returns the next address from the resolver.

                      This function should be called multiple times. On each call, it will return the next address in connection order preference. If all @@ -2960,31 +2957,31 @@ addresses have been exhausted, this function returns none.

                      Params
                      Return values
                      -

                      [method]resolve-address-stream.subscribe: func

                      +

                      [method]resolve-address-stream.subscribe: func

                      Create a pollable which will resolve once the stream is ready for I/O.

                      -

                      Note: this function is here for WASI Preview2 only. +

                      Note: this function is here for WASI 0.2 only. It's planned to be removed when future is natively supported in Preview3.

                      Params
                      Return values
                      -

                      Import interface wasi:random/random@0.2.1

                      +

                      Import interface wasi:random/random@0.2.2

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.


                      Functions

                      -

                      get-random-bytes: func

                      +

                      get-random-bytes: func

                      Return len cryptographically-secure random or pseudo-random bytes.

                      This function must produce data at least as cryptographically secure and fast as an adequately seeded cryptographically-secure pseudo-random @@ -2997,27 +2994,27 @@ must omit this function, rather than implementing it with deterministic data.

                      Params
                        -
                      • len: u64
                      • +
                      • len: u64
                      Return values
                        -
                      • list<u8>
                      • +
                      • list<u8>
                      -

                      get-random-u64: func

                      +

                      get-random-u64: func

                      Return a cryptographically-secure random or pseudo-random u64 value.

                      This function returns the same type of data as get-random-bytes, represented as a u64.

                      Return values
                        -
                      • u64
                      • +
                      • u64
                      -

                      Import interface wasi:random/insecure@0.2.1

                      +

                      Import interface wasi:random/insecure@0.2.2

                      The insecure interface for insecure pseudo-random numbers.

                      It is intended to be portable at least between Unix-family platforms and Windows.


                      Functions

                      -

                      get-insecure-random-bytes: func

                      +

                      get-insecure-random-bytes: func

                      Return len insecure pseudo-random bytes.

                      This function is not cryptographically secure. Do not use it for anything related to security.

                      @@ -3026,27 +3023,27 @@ implementations are encouraged to return evenly distributed values with a long period.

                      Params
                        -
                      • len: u64
                      • +
                      • len: u64
                      Return values
                        -
                      • list<u8>
                      • +
                      • list<u8>
                      -

                      get-insecure-random-u64: func

                      +

                      get-insecure-random-u64: func

                      Return an insecure pseudo-random u64 value.

                      This function returns the same type of pseudo-random data as get-insecure-random-bytes, represented as a u64.

                      Return values
                        -
                      • u64
                      • +
                      • u64
                      -

                      Import interface wasi:random/insecure-seed@0.2.1

                      +

                      Import interface wasi:random/insecure-seed@0.2.2

                      The insecure-seed interface for seeding hash-map DoS resistance.

                      It is intended to be portable at least between Unix-family platforms and Windows.


                      Functions

                      -

                      insecure-seed: func

                      +

                      insecure-seed: func

                      Return a 128-bit value that may contain a pseudo-random value.

                      The returned value is not required to be computed from a CSPRNG, and may even be entirely deterministic. Host implementations are encouraged to @@ -3062,5 +3059,5 @@ called multiple times and potentially used for purposes other than DoS protection.

                      Return values
                        -
                      • (u64, u64)
                      • +
                      • (u64, u64)
                      diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index dc064a3cd..cc7a352c2 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.1; +package wasi:cli@0.2.2; @since(version = 0.2.0) world command { diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index 4308eabff..db5e12945 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,24 +1,24 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "ea9d69ee803bc176e23e5268f5e24a2ac485dd1f62a0ab4c748e9d3f901f576f" -sha512 = "5efc22927c46cd56c41e5549ec775561c7fac2ea0d365abc0b55396d9475a7c9f984077a81f84a44a726f1c008fd2fadbffffa4fa53ecd5fbfd05afd379ab428" +sha256 = "c2da62619d1067646316e8592b583d77036d778e28b1154353e0825956b3d6aa" +sha512 = "4d409fc38b31646fc5de70160e81bd3fa67f9c99b4d24543b4fd40a922c7545739869521b8a997efb675d0816de8b001b6af7950e0cb0bc823d89b9f07b286c4" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "cfe8c420e8b857de612ae2a3336680dae16b95c93c8ba3a6ff05b21210966740" -sha512 = "3c00c5544a58658e3e8025677091685286027fd49f37abf198c30b4e83b9e68f19723975aaa98794fba9f425ae9ef4f3dc0f5b9cf59203b5ecfaadf62b296f9a" +sha256 = "69e220ec22593f097c7f486dd9e4f95576ef7056d3d531a86a277654872997ba" +sha512 = "457c027aebd1430e924564b3bb2477bc163083cb1029105c1432cbdc165cdf3cce4ac62dbb8e43e3dec09e24a6b2029204212e2f0e3919137cb207165368e157" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "2a74bd811adc46b5a0f19827ddbde89870e52b17615f4d0873f06fd977250caf" -sha512 = "94624f00c66e66203592cee820f80b1ba91ecdb71f682c154f25eaf71f8d8954197dcb64503bc21e72ed5e812af7eae876df47b7eb727b02db3a74a7ce0aefca" +sha256 = "6d8dbfaaaa685167c1829616dc7265f5f3cb776845879555612d56544f6d9bfc" +sha512 = "52219562c4183503169cd2947b8164e1c96974500a5adf15bbf382c5992a10a626cc89c3b319204aeda6698ce59cbca2c42f98f7fde296aa77b9db4b41154dbe" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "9e2d5056186f81b2e7f96bc97d2babd0341840f6abb4f170449b70992f1b598f" -sha512 = "67bf41d8d5d4b7af084124ee85196585225785969059f59e2f9ddb77ac1a8095cfe811ae29d076aac817418fa01064d7b9fbc0233930bace680758eeb21e36f8" +sha256 = "b4bb285b1c51aac2f8911f6b44ba1587108a2b24f910fe4774414dc286678b66" +sha512 = "bc2ffca0ae48f54977a763a70fcfcd5f4fca6b7c530916352f98c59627cc3f5899e47b6308bd9848b8c72e14db57e254757d580010a3d56e6888dafce3dcb679" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "4c361137a7e61e8b9a73da2a0899dd9ad1a0c2dfee7d310cf168704c57b7a07c" -sha512 = "348b4ef381f57aec23d48537df8b69ab8963587dcb056e94c4cd5657e217677a4ee2a545868a5c829d2334cc6b8b0a61d3e72797999f44d78553fbd3a73c5b8d" +sha256 = "f254783796170fdeac6756496cc6169903a88adeda7a5895265414bc63ba4d66" +sha512 = "3f68e874beb0ac9729d1738546a430f2f8b369eb510d3cd6dfcfc41427acb52a82701d73584b8ab637b8c3908c5d4f7a7d4806032cc5d375643fad0ebf84e053" diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index 3c24840c9..233cace4c 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.1; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/cli/wit/deps/clocks/timezone.wit b/proposals/cli/wit/deps/clocks/timezone.wit index 212da6682..349fb5703 100644 --- a/proposals/cli/wit/deps/clocks/timezone.wit +++ b/proposals/cli/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit index 6be069a32..ec05a1f1a 100644 --- a/proposals/cli/wit/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/cli/wit/deps/clocks/world.wit b/proposals/cli/wit/deps/clocks/world.wit index 9251ac645..e36802cc8 100644 --- a/proposals/cli/wit/deps/clocks/world.wit +++ b/proposals/cli/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/filesystem/preopens.wit b/proposals/cli/wit/deps/filesystem/preopens.wit index ca2f726af..410bec1dc 100644 --- a/proposals/cli/wit/deps/filesystem/preopens.wit +++ b/proposals/cli/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.1; +package wasi:filesystem@0.2.2; @since(version = 0.2.0) interface preopens { diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index db3d96867..49e0a30bb 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.1; +package wasi:filesystem@0.2.2; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.1; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.2.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.1.{datetime}; + use wasi:clocks/wall-clock@0.2.2.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) @@ -523,12 +523,6 @@ interface types { /// Open a file or directory. /// - /// The returned descriptor is not guaranteed to be the lowest-numbered - /// descriptor not currently open/ it is randomized to prevent applications - /// from depending on making assumptions about indexes, since this is - /// error-prone in multi-threaded contexts. The returned descriptor is - /// guaranteed to be less than 2**31. - /// /// If `flags` contains `descriptor-flags::mutate-directory`, and the base /// descriptor doesn't have `descriptor-flags::mutate-directory` set, /// `open-at` fails with `error-code::read-only`. diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit index af0146cbc..8064bd64b 100644 --- a/proposals/cli/wit/deps/filesystem/world.wit +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.1; +package wasi:filesystem@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/io/error.wit b/proposals/cli/wit/deps/io/error.wit index 4ea29c469..717135f8c 100644 --- a/proposals/cli/wit/deps/io/error.wit +++ b/proposals/cli/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; @since(version = 0.2.0) interface error { diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit index b25ac729f..49c1c5ede 100644 --- a/proposals/cli/wit/deps/io/poll.wit +++ b/proposals/cli/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index b697e24d6..330f7095c 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -18,6 +18,9 @@ interface streams { /// The last operation (a write or flush) failed before completion. /// /// More information is available in the `error` payload. + /// + /// After this, the stream will be closed. All future operations return + /// `stream-error::closed`. last-operation-failed(error), /// The stream is closed: no more input will be accepted by the /// stream. A closed output-stream will return this error on all @@ -205,6 +208,7 @@ interface streams { /// The created `pollable` is a child resource of the `output-stream`. /// Implementations may trap if the `output-stream` is dropped before /// all derived `pollable`s created with this function are dropped. + @since(version = 0.2.0) subscribe: func() -> pollable; /// Write zeroes to a stream. diff --git a/proposals/cli/wit/deps/io/world.wit b/proposals/cli/wit/deps/io/world.wit index 6405a4e48..f7001ccff 100644 --- a/proposals/cli/wit/deps/io/world.wit +++ b/proposals/cli/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/random/insecure-seed.wit b/proposals/cli/wit/deps/random/insecure-seed.wit index 7e708dc52..cdea716cf 100644 --- a/proposals/cli/wit/deps/random/insecure-seed.wit +++ b/proposals/cli/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/insecure.wit b/proposals/cli/wit/deps/random/insecure.wit index 3cdb53dfb..b71e85879 100644 --- a/proposals/cli/wit/deps/random/insecure.wit +++ b/proposals/cli/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index 2b5035d1c..0c57e8c80 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/world.wit b/proposals/cli/wit/deps/random/world.wit index c615e96dc..16d68acfa 100644 --- a/proposals/cli/wit/deps/random/world.wit +++ b/proposals/cli/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index dc56f3000..d3ab88aed 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; @@ -48,7 +48,7 @@ interface ip-name-lookup { /// Create a `pollable` which will resolve once the stream is ready for I/O. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit index 8c13b348e..7f2d86a4c 100644 --- a/proposals/cli/wit/deps/sockets/network.wit +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -1,5 +1,8 @@ @since(version = 0.2.0) interface network { + @unstable(feature = network-error-code) + use wasi:io/error@0.2.2.{error}; + /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. @@ -105,6 +108,19 @@ interface network { permanent-resolver-failure, } + /// Attempts to extract a network-related `error-code` from the stream + /// `error` provided. + /// + /// Stream operations which return `stream-error::last-operation-failed` + /// have a payload with more information about the operation that failed. + /// This payload can be passed through to this function to see if there's + /// network-related information about the error to return. + /// + /// Note that this function is fallible because not all stream-related + /// errors are network-related errors. + @unstable(feature = network-error-code) + network-error-code: func(err: borrow) -> option; + @since(version = 0.2.0) enum ip-address-family { /// Similar to `AF_INET` in POSIX. diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index bae5a29ec..728822dfa 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{input-stream, output-stream}; + use wasi:io/streams@0.2.2.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.1.{duration}; + use wasi:clocks/monotonic-clock@0.2.2.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; @@ -353,7 +353,7 @@ interface tcp { /// See /// for more information. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index b289e4943..d8acb2d29 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; @@ -184,7 +184,7 @@ interface udp { /// Create a `pollable` which will resolve once the socket is ready for I/O. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; @@ -220,7 +220,7 @@ interface udp { /// Create a `pollable` which will resolve once the stream is ready to receive again. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; @@ -280,7 +280,7 @@ interface udp { /// Create a `pollable` which will resolve once the stream is ready to send again. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit index a1d42670e..6e349c756 100644 --- a/proposals/cli/wit/deps/sockets/world.wit +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.1; +package wasi:sockets@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/imports.wit b/proposals/cli/wit/imports.wit index b8339d3b2..ebd7ba173 100644 --- a/proposals/cli/wit/imports.wit +++ b/proposals/cli/wit/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.1; +package wasi:cli@0.2.2; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.1; + include wasi:clocks/imports@0.2.2; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.1; + include wasi:filesystem/imports@0.2.2; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.1; + include wasi:sockets/imports@0.2.2; @since(version = 0.2.0) - include wasi:random/imports@0.2.1; + include wasi:random/imports@0.2.2; @since(version = 0.2.0) - include wasi:io/imports@0.2.1; + include wasi:io/imports@0.2.2; @since(version = 0.2.0) import environment; diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index d1d26eb61..860313eea 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{input-stream}; + use wasi:io/streams@0.2.2.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{output-stream}; + use wasi:io/streams@0.2.2.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{output-stream}; + use wasi:io/streams@0.2.2.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; From 5ac3ea46e79f381c34fdb2fdb0b728a3d095b8f9 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 3 Oct 2024 20:57:43 +0200 Subject: [PATCH 1514/1772] Update to v0.2.2 --- proposals/http/.github/workflows/main.yml | 4 +- proposals/http/imports.md | 46 +-- proposals/http/proxy.md | 266 +++++++++--------- .../http/wit-0.3.0-draft/deps/cli/command.wit | 2 +- .../http/wit-0.3.0-draft/deps/cli/imports.wit | 12 +- .../http/wit-0.3.0-draft/deps/cli/stdio.wit | 6 +- .../deps/clocks/monotonic-clock.wit | 4 +- .../wit-0.3.0-draft/deps/clocks/timezone.wit | 2 +- .../deps/clocks/wall-clock.wit | 2 +- .../wit-0.3.0-draft/deps/clocks/world.wit | 2 +- .../deps/filesystem/preopens.wit | 2 +- .../wit-0.3.0-draft/deps/filesystem/types.wit | 6 +- .../wit-0.3.0-draft/deps/filesystem/world.wit | 2 +- .../http/wit-0.3.0-draft/deps/io/error.wit | 2 +- .../http/wit-0.3.0-draft/deps/io/poll.wit | 2 +- .../http/wit-0.3.0-draft/deps/io/streams.wit | 2 +- .../http/wit-0.3.0-draft/deps/io/world.wit | 2 +- .../deps/random/insecure-seed.wit | 2 +- .../wit-0.3.0-draft/deps/random/insecure.wit | 2 +- .../wit-0.3.0-draft/deps/random/random.wit | 2 +- .../wit-0.3.0-draft/deps/random/world.wit | 2 +- .../deps/sockets/ip-name-lookup.wit | 2 +- .../http/wit-0.3.0-draft/deps/sockets/tcp.wit | 6 +- .../http/wit-0.3.0-draft/deps/sockets/udp.wit | 2 +- .../wit-0.3.0-draft/deps/sockets/world.wit | 2 +- proposals/http/wit-0.3.0-draft/proxy.wit | 10 +- proposals/http/wit-0.3.0-draft/types.wit | 4 +- proposals/http/wit/deps.lock | 24 +- proposals/http/wit/deps/cli/command.wit | 2 +- proposals/http/wit/deps/cli/imports.wit | 12 +- proposals/http/wit/deps/cli/stdio.wit | 6 +- .../http/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/http/wit/deps/clocks/timezone.wit | 2 +- proposals/http/wit/deps/clocks/wall-clock.wit | 2 +- proposals/http/wit/deps/clocks/world.wit | 2 +- .../http/wit/deps/filesystem/preopens.wit | 2 +- proposals/http/wit/deps/filesystem/types.wit | 12 +- proposals/http/wit/deps/filesystem/world.wit | 2 +- proposals/http/wit/deps/io/error.wit | 2 +- proposals/http/wit/deps/io/poll.wit | 2 +- proposals/http/wit/deps/io/streams.wit | 6 +- proposals/http/wit/deps/io/world.wit | 2 +- .../http/wit/deps/random/insecure-seed.wit | 2 +- proposals/http/wit/deps/random/insecure.wit | 2 +- proposals/http/wit/deps/random/random.wit | 2 +- proposals/http/wit/deps/random/world.wit | 2 +- .../http/wit/deps/sockets/ip-name-lookup.wit | 4 +- proposals/http/wit/deps/sockets/network.wit | 16 ++ proposals/http/wit/deps/sockets/tcp.wit | 8 +- proposals/http/wit/deps/sockets/udp.wit | 8 +- proposals/http/wit/deps/sockets/world.wit | 2 +- proposals/http/wit/proxy.wit | 14 +- proposals/http/wit/types.wit | 8 +- 53 files changed, 283 insertions(+), 265 deletions(-) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index e5ad56545..d7a090b50 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -18,6 +18,6 @@ jobs: ./wit-deps lock --check - uses: WebAssembly/wit-abi-up-to-date@v22 with: - wasm-tools: '1.215.0' - wit-bindgen: '0.30.0' + wasm-tools: '1.218.0' + wit-bindgen: '0.33.0' worlds: 'imports proxy' diff --git a/proposals/http/imports.md b/proposals/http/imports.md index 6a3caf156..5b71ecc30 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -4,21 +4,21 @@ It is intended to be included in other worlds.

                      -

                      Import interface wasi:io/poll@0.2.1

                      +

                      Import interface wasi:io/poll@0.2.2

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -71,7 +71,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.1

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.2

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -130,7 +130,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.1

                      +

                      Import interface wasi:clocks/wall-clock@0.2.2

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -171,7 +171,7 @@ also known as Unix Time.
                    1. datetime
                    2. -

                      Import interface wasi:random/random@0.2.1

                      +

                      Import interface wasi:random/random@0.2.2

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -204,7 +204,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:io/error@0.2.1

                      +

                      Import interface wasi:io/error@0.2.2


                      Types

                      resource error

                      @@ -237,7 +237,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/streams@0.2.1

                      +

                      Import interface wasi:io/streams@0.2.2

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -258,6 +258,8 @@ when it does, they are expected to subsume this API.

                      last-operation-failed: own<error>

                      The last operation (a write or flush) failed before completion.

                      More information is available in the error payload.

                      +

                      After this, the stream will be closed. All future operations return +stream-error::closed.

                    3. closed

                      @@ -565,7 +567,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.1

                      +

                      Import interface wasi:cli/stdout@0.2.2


                      Types

                      type output-stream

                      @@ -578,7 +580,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.1

                      +

                      Import interface wasi:cli/stderr@0.2.2


                      Types

                      type output-stream

                      @@ -591,7 +593,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.1

                      +

                      Import interface wasi:cli/stdin@0.2.2


                      Types

                      type input-stream

                      @@ -604,7 +606,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:http/types@0.2.1

                      +

                      Import interface wasi:http/types@0.2.2

                      This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                      @@ -1505,7 +1507,7 @@ but those will be reported by the incoming-body
                    4. option<result<result<own<incoming-response>, error-code>>>
                    5. -

                      Import interface wasi:http/outgoing-handler@0.2.1

                      +

                      Import interface wasi:http/outgoing-handler@0.2.2

                      This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                      diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index b0f72e258..ceb59c0ad 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -6,26 +6,26 @@ outgoing HTTP requests.

                      -

                      Import interface wasi:io/poll@0.2.1

                      +

                      Import interface wasi:io/poll@0.2.2

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -78,7 +78,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.1

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.2

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -137,7 +137,81 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:io/error@0.2.1

                      +

                      Import interface wasi:clocks/wall-clock@0.2.2

                      +

                      WASI Wall Clock is a clock API intended to let users query the current +time. The name "wall" makes an analogy to a "clock on the wall", which +is not necessarily monotonic as it may be reset.

                      +

                      It is intended to be portable at least between Unix-family platforms and +Windows.

                      +

                      A wall clock is a clock which measures the date and time according to +some external reference.

                      +

                      External references may be reset, so this clock is not necessarily +monotonic, making it unsuitable for measuring elapsed time.

                      +

                      It is intended for reporting the current date and time for humans.

                      +
                      +

                      Types

                      +

                      record datetime

                      +

                      A time and date in seconds plus nanoseconds.

                      +
                      Record Fields
                      +
                        +
                      • seconds: u64
                      • +
                      • nanoseconds: u32
                      • +
                      +
                      +

                      Functions

                      +

                      now: func

                      +

                      Read the current value of the clock.

                      +

                      This clock is not monotonic, therefore calling this function repeatedly +will not necessarily produce a sequence of non-decreasing values.

                      +

                      The returned timestamps represent the number of seconds since +1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, +also known as Unix Time.

                      +

                      The nanoseconds field of the output is always less than 1000000000.

                      +
                      Return values
                      + +

                      resolution: func

                      +

                      Query the resolution of the clock.

                      +

                      The nanoseconds field of the output is always less than 1000000000.

                      +
                      Return values
                      + +

                      Import interface wasi:random/random@0.2.2

                      +

                      WASI Random is a random data API.

                      +

                      It is intended to be portable at least between Unix-family platforms and +Windows.

                      +
                      +

                      Functions

                      +

                      get-random-bytes: func

                      +

                      Return len cryptographically-secure random or pseudo-random bytes.

                      +

                      This function must produce data at least as cryptographically secure and +fast as an adequately seeded cryptographically-secure pseudo-random +number generator (CSPRNG). It must not block, from the perspective of +the calling program, under any circumstances, including on the first +request and on requests for numbers of bytes. The returned data must +always be unpredictable.

                      +

                      This function must always return fresh data. Deterministic environments +must omit this function, rather than implementing it with deterministic +data.

                      +
                      Params
                      +
                        +
                      • len: u64
                      • +
                      +
                      Return values
                      +
                        +
                      • list<u8>
                      • +
                      +

                      get-random-u64: func

                      +

                      Return a cryptographically-secure random or pseudo-random u64 value.

                      +

                      This function returns the same type of data as get-random-bytes, +represented as a u64.

                      +
                      Return values
                      +
                        +
                      • u64
                      • +
                      +

                      Import interface wasi:io/error@0.2.2


                      Types

                      resource error

                      @@ -170,7 +244,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/streams@0.2.1

                      +

                      Import interface wasi:io/streams@0.2.2

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -191,6 +265,8 @@ when it does, they are expected to subsume this API.

                      last-operation-failed: own<error>

                      The last operation (a write or flush) failed before completion.

                      More information is available in the error payload.

                      +

                      After this, the stream will be closed. All future operations return +stream-error::closed.

                    6. closed

                      @@ -498,7 +574,46 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:http/types@0.2.1

                      +

                      Import interface wasi:cli/stdout@0.2.2

                      +
                      +

                      Types

                      +

                      type output-stream

                      +

                      output-stream

                      +

                      +---- +

                      Functions

                      +

                      get-stdout: func

                      +
                      Return values
                      + +

                      Import interface wasi:cli/stderr@0.2.2

                      +
                      +

                      Types

                      +

                      type output-stream

                      +

                      output-stream

                      +

                      +---- +

                      Functions

                      +

                      get-stderr: func

                      +
                      Return values
                      + +

                      Import interface wasi:cli/stdin@0.2.2

                      +
                      +

                      Types

                      +

                      type input-stream

                      +

                      input-stream

                      +

                      +---- +

                      Functions

                      +

                      get-stdin: func

                      +
                      Return values
                      + +

                      Import interface wasi:http/types@0.2.2

                      This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                      @@ -1399,120 +1514,7 @@ but those will be reported by the incoming-body
                    7. option<result<result<own<incoming-response>, error-code>>>
                    8. -

                      Import interface wasi:clocks/wall-clock@0.2.1

                      -

                      WASI Wall Clock is a clock API intended to let users query the current -time. The name "wall" makes an analogy to a "clock on the wall", which -is not necessarily monotonic as it may be reset.

                      -

                      It is intended to be portable at least between Unix-family platforms and -Windows.

                      -

                      A wall clock is a clock which measures the date and time according to -some external reference.

                      -

                      External references may be reset, so this clock is not necessarily -monotonic, making it unsuitable for measuring elapsed time.

                      -

                      It is intended for reporting the current date and time for humans.

                      -
                      -

                      Types

                      -

                      record datetime

                      -

                      A time and date in seconds plus nanoseconds.

                      -
                      Record Fields
                      -
                        -
                      • seconds: u64
                      • -
                      • nanoseconds: u32
                      • -
                      -
                      -

                      Functions

                      -

                      now: func

                      -

                      Read the current value of the clock.

                      -

                      This clock is not monotonic, therefore calling this function repeatedly -will not necessarily produce a sequence of non-decreasing values.

                      -

                      The returned timestamps represent the number of seconds since -1970-01-01T00:00:00Z, also known as POSIX's Seconds Since the Epoch, -also known as Unix Time.

                      -

                      The nanoseconds field of the output is always less than 1000000000.

                      -
                      Return values
                      - -

                      resolution: func

                      -

                      Query the resolution of the clock.

                      -

                      The nanoseconds field of the output is always less than 1000000000.

                      -
                      Return values
                      - -

                      Import interface wasi:random/random@0.2.1

                      -

                      WASI Random is a random data API.

                      -

                      It is intended to be portable at least between Unix-family platforms and -Windows.

                      -
                      -

                      Functions

                      -

                      get-random-bytes: func

                      -

                      Return len cryptographically-secure random or pseudo-random bytes.

                      -

                      This function must produce data at least as cryptographically secure and -fast as an adequately seeded cryptographically-secure pseudo-random -number generator (CSPRNG). It must not block, from the perspective of -the calling program, under any circumstances, including on the first -request and on requests for numbers of bytes. The returned data must -always be unpredictable.

                      -

                      This function must always return fresh data. Deterministic environments -must omit this function, rather than implementing it with deterministic -data.

                      -
                      Params
                      -
                        -
                      • len: u64
                      • -
                      -
                      Return values
                      -
                        -
                      • list<u8>
                      • -
                      -

                      get-random-u64: func

                      -

                      Return a cryptographically-secure random or pseudo-random u64 value.

                      -

                      This function returns the same type of data as get-random-bytes, -represented as a u64.

                      -
                      Return values
                      -
                        -
                      • u64
                      • -
                      -

                      Import interface wasi:cli/stdout@0.2.1

                      -
                      -

                      Types

                      -

                      type output-stream

                      -

                      output-stream

                      -

                      ----- -

                      Functions

                      -

                      get-stdout: func

                      -
                      Return values
                      - -

                      Import interface wasi:cli/stderr@0.2.1

                      -
                      -

                      Types

                      -

                      type output-stream

                      -

                      output-stream

                      -

                      ----- -

                      Functions

                      -

                      get-stderr: func

                      -
                      Return values
                      - -

                      Import interface wasi:cli/stdin@0.2.1

                      -
                      -

                      Types

                      -

                      type input-stream

                      -

                      input-stream

                      -

                      ----- -

                      Functions

                      -

                      get-stdin: func

                      -
                      Return values
                      - -

                      Import interface wasi:http/outgoing-handler@0.2.1

                      +

                      Import interface wasi:http/outgoing-handler@0.2.2

                      This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                      @@ -1549,7 +1551,7 @@ through the future-incoming-response
                    9. result<own<future-incoming-response>, error-code>
                    10. -

                      Export interface wasi:http/incoming-handler@0.2.1

                      +

                      Export interface wasi:http/incoming-handler@0.2.2


                      Types

                      type incoming-request

                      diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit index dc064a3cd..cc7a352c2 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.1; +package wasi:cli@0.2.2; @since(version = 0.2.0) world command { diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit index b8339d3b2..ebd7ba173 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.1; +package wasi:cli@0.2.2; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.1; + include wasi:clocks/imports@0.2.2; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.1; + include wasi:filesystem/imports@0.2.2; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.1; + include wasi:sockets/imports@0.2.2; @since(version = 0.2.0) - include wasi:random/imports@0.2.1; + include wasi:random/imports@0.2.2; @since(version = 0.2.0) - include wasi:io/imports@0.2.1; + include wasi:io/imports@0.2.2; @since(version = 0.2.0) import environment; diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit index d1d26eb61..860313eea 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{input-stream}; + use wasi:io/streams@0.2.2.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{output-stream}; + use wasi:io/streams@0.2.2.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{output-stream}; + use wasi:io/streams@0.2.2.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 3c24840c9..233cace4c 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.1; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit index 212da6682..349fb5703 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit index 6be069a32..ec05a1f1a 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit index 9251ac645..e36802cc8 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit index ca2f726af..410bec1dc 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.1; +package wasi:filesystem@0.2.2; @since(version = 0.2.0) interface preopens { diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit index db3d96867..57dffb27b 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.1; +package wasi:filesystem@0.2.2; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.1; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.2.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.1.{datetime}; + use wasi:clocks/wall-clock@0.2.2.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit index af0146cbc..8064bd64b 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.1; +package wasi:filesystem@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/deps/io/error.wit b/proposals/http/wit-0.3.0-draft/deps/io/error.wit index 4ea29c469..717135f8c 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/error.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; @since(version = 0.2.0) interface error { diff --git a/proposals/http/wit-0.3.0-draft/deps/io/poll.wit b/proposals/http/wit-0.3.0-draft/deps/io/poll.wit index b25ac729f..49c1c5ede 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/poll.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/http/wit-0.3.0-draft/deps/io/streams.wit b/proposals/http/wit-0.3.0-draft/deps/io/streams.wit index b697e24d6..80437d62e 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/streams.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/http/wit-0.3.0-draft/deps/io/world.wit b/proposals/http/wit-0.3.0-draft/deps/io/world.wit index 6405a4e48..f7001ccff 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit index 7e708dc52..cdea716cf 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit index 3cdb53dfb..b71e85879 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit-0.3.0-draft/deps/random/random.wit b/proposals/http/wit-0.3.0-draft/deps/random/random.wit index 2b5035d1c..0c57e8c80 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/random.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit-0.3.0-draft/deps/random/world.wit b/proposals/http/wit-0.3.0-draft/deps/random/world.wit index c615e96dc..16d68acfa 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit index dc56f3000..8d6dcec31 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit index bae5a29ec..91f421b44 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{input-stream, output-stream}; + use wasi:io/streams@0.2.2.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.1.{duration}; + use wasi:clocks/monotonic-clock@0.2.2.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit index b289e4943..328d91683 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit index a1d42670e..6e349c756 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.1; +package wasi:sockets@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/proxy.wit b/proposals/http/wit-0.3.0-draft/proxy.wit index 6a83dc740..5342784a1 100644 --- a/proposals/http/wit-0.3.0-draft/proxy.wit +++ b/proposals/http/wit-0.3.0-draft/proxy.wit @@ -4,19 +4,19 @@ package wasi:http@0.3.0-draft; /// It is intended to be `include`d in other worlds. world imports { /// HTTP proxies have access to time and randomness. - include wasi:clocks/imports@0.2.1; - import wasi:random/random@0.2.1; + include wasi:clocks/imports@0.2.2; + import wasi:random/random@0.2.2; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.2.1; - import wasi:cli/stderr@0.2.1; + import wasi:cli/stdout@0.2.2; + import wasi:cli/stderr@0.2.2; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. - import wasi:cli/stdin@0.2.1; + import wasi:cli/stdin@0.2.2; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index f702c15ed..e272ab0d3 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -1,8 +1,8 @@ /// This interface defines all of the types and methods for implementing HTTP /// Requests and Responses, as well as their headers, trailers, and bodies. interface types { - use wasi:clocks/monotonic-clock@0.2.1.{duration}; - use wasi:io/error@0.2.1.{error}; + use wasi:clocks/monotonic-clock@0.2.2.{duration}; + use wasi:io/error@0.2.2.{error}; /// This type corresponds to HTTP standard Methods. variant method { diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index a12064a91..8d1257da3 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,29 +1,29 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -sha256 = "1de50b8e6940e73110cda10b7f90ca87a8fea886f0fa36c748f96dc70671ee38" -sha512 = "bbb6cd3e7b4d3237b6af9bfbb2633ccd2c4ea2a4f37b8c033255c7e0c1cb037be7f22ec1f8ca792cc8ec1942199582943979e646b4b272b85dcff7654eac51d0" +sha256 = "052c438d7606115bcfbe43094c55764c3396acfc8e4c69a6f54f7abcf8ef7c8c" +sha512 = "cce72d006e639cacabbd01137af99029591403a9bf6db8475e87d82cd6f256fa2118f9d15d5d88a34cacfaeb8d472f21f0914b20c83f6da1771f763cad4e1379" [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "ea9d69ee803bc176e23e5268f5e24a2ac485dd1f62a0ab4c748e9d3f901f576f" -sha512 = "5efc22927c46cd56c41e5549ec775561c7fac2ea0d365abc0b55396d9475a7c9f984077a81f84a44a726f1c008fd2fadbffffa4fa53ecd5fbfd05afd379ab428" +sha256 = "c2da62619d1067646316e8592b583d77036d778e28b1154353e0825956b3d6aa" +sha512 = "4d409fc38b31646fc5de70160e81bd3fa67f9c99b4d24543b4fd40a922c7545739869521b8a997efb675d0816de8b001b6af7950e0cb0bc823d89b9f07b286c4" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "cfe8c420e8b857de612ae2a3336680dae16b95c93c8ba3a6ff05b21210966740" -sha512 = "3c00c5544a58658e3e8025677091685286027fd49f37abf198c30b4e83b9e68f19723975aaa98794fba9f425ae9ef4f3dc0f5b9cf59203b5ecfaadf62b296f9a" +sha256 = "69e220ec22593f097c7f486dd9e4f95576ef7056d3d531a86a277654872997ba" +sha512 = "457c027aebd1430e924564b3bb2477bc163083cb1029105c1432cbdc165cdf3cce4ac62dbb8e43e3dec09e24a6b2029204212e2f0e3919137cb207165368e157" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "2a74bd811adc46b5a0f19827ddbde89870e52b17615f4d0873f06fd977250caf" -sha512 = "94624f00c66e66203592cee820f80b1ba91ecdb71f682c154f25eaf71f8d8954197dcb64503bc21e72ed5e812af7eae876df47b7eb727b02db3a74a7ce0aefca" +sha256 = "6d8dbfaaaa685167c1829616dc7265f5f3cb776845879555612d56544f6d9bfc" +sha512 = "52219562c4183503169cd2947b8164e1c96974500a5adf15bbf382c5992a10a626cc89c3b319204aeda6698ce59cbca2c42f98f7fde296aa77b9db4b41154dbe" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "9e2d5056186f81b2e7f96bc97d2babd0341840f6abb4f170449b70992f1b598f" -sha512 = "67bf41d8d5d4b7af084124ee85196585225785969059f59e2f9ddb77ac1a8095cfe811ae29d076aac817418fa01064d7b9fbc0233930bace680758eeb21e36f8" +sha256 = "b4bb285b1c51aac2f8911f6b44ba1587108a2b24f910fe4774414dc286678b66" +sha512 = "bc2ffca0ae48f54977a763a70fcfcd5f4fca6b7c530916352f98c59627cc3f5899e47b6308bd9848b8c72e14db57e254757d580010a3d56e6888dafce3dcb679" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "4c361137a7e61e8b9a73da2a0899dd9ad1a0c2dfee7d310cf168704c57b7a07c" -sha512 = "348b4ef381f57aec23d48537df8b69ab8963587dcb056e94c4cd5657e217677a4ee2a545868a5c829d2334cc6b8b0a61d3e72797999f44d78553fbd3a73c5b8d" +sha256 = "f254783796170fdeac6756496cc6169903a88adeda7a5895265414bc63ba4d66" +sha512 = "3f68e874beb0ac9729d1738546a430f2f8b369eb510d3cd6dfcfc41427acb52a82701d73584b8ab637b8c3908c5d4f7a7d4806032cc5d375643fad0ebf84e053" diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit index dc064a3cd..cc7a352c2 100644 --- a/proposals/http/wit/deps/cli/command.wit +++ b/proposals/http/wit/deps/cli/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.1; +package wasi:cli@0.2.2; @since(version = 0.2.0) world command { diff --git a/proposals/http/wit/deps/cli/imports.wit b/proposals/http/wit/deps/cli/imports.wit index b8339d3b2..ebd7ba173 100644 --- a/proposals/http/wit/deps/cli/imports.wit +++ b/proposals/http/wit/deps/cli/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.1; +package wasi:cli@0.2.2; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.1; + include wasi:clocks/imports@0.2.2; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.1; + include wasi:filesystem/imports@0.2.2; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.1; + include wasi:sockets/imports@0.2.2; @since(version = 0.2.0) - include wasi:random/imports@0.2.1; + include wasi:random/imports@0.2.2; @since(version = 0.2.0) - include wasi:io/imports@0.2.1; + include wasi:io/imports@0.2.2; @since(version = 0.2.0) import environment; diff --git a/proposals/http/wit/deps/cli/stdio.wit b/proposals/http/wit/deps/cli/stdio.wit index d1d26eb61..860313eea 100644 --- a/proposals/http/wit/deps/cli/stdio.wit +++ b/proposals/http/wit/deps/cli/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{input-stream}; + use wasi:io/streams@0.2.2.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{output-stream}; + use wasi:io/streams@0.2.2.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{output-stream}; + use wasi:io/streams@0.2.2.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index 3c24840c9..233cace4c 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.1; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/http/wit/deps/clocks/timezone.wit b/proposals/http/wit/deps/clocks/timezone.wit index 212da6682..349fb5703 100644 --- a/proposals/http/wit/deps/clocks/timezone.wit +++ b/proposals/http/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/http/wit/deps/clocks/wall-clock.wit b/proposals/http/wit/deps/clocks/wall-clock.wit index 6be069a32..ec05a1f1a 100644 --- a/proposals/http/wit/deps/clocks/wall-clock.wit +++ b/proposals/http/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/http/wit/deps/clocks/world.wit b/proposals/http/wit/deps/clocks/world.wit index 9251ac645..e36802cc8 100644 --- a/proposals/http/wit/deps/clocks/world.wit +++ b/proposals/http/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.1; +package wasi:clocks@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/filesystem/preopens.wit b/proposals/http/wit/deps/filesystem/preopens.wit index ca2f726af..410bec1dc 100644 --- a/proposals/http/wit/deps/filesystem/preopens.wit +++ b/proposals/http/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.1; +package wasi:filesystem@0.2.2; @since(version = 0.2.0) interface preopens { diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index db3d96867..49e0a30bb 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.1; +package wasi:filesystem@0.2.2; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.1; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.2.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.1.{datetime}; + use wasi:clocks/wall-clock@0.2.2.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) @@ -523,12 +523,6 @@ interface types { /// Open a file or directory. /// - /// The returned descriptor is not guaranteed to be the lowest-numbered - /// descriptor not currently open/ it is randomized to prevent applications - /// from depending on making assumptions about indexes, since this is - /// error-prone in multi-threaded contexts. The returned descriptor is - /// guaranteed to be less than 2**31. - /// /// If `flags` contains `descriptor-flags::mutate-directory`, and the base /// descriptor doesn't have `descriptor-flags::mutate-directory` set, /// `open-at` fails with `error-code::read-only`. diff --git a/proposals/http/wit/deps/filesystem/world.wit b/proposals/http/wit/deps/filesystem/world.wit index af0146cbc..8064bd64b 100644 --- a/proposals/http/wit/deps/filesystem/world.wit +++ b/proposals/http/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.1; +package wasi:filesystem@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/io/error.wit b/proposals/http/wit/deps/io/error.wit index 4ea29c469..717135f8c 100644 --- a/proposals/http/wit/deps/io/error.wit +++ b/proposals/http/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; @since(version = 0.2.0) interface error { diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/io/poll.wit index b25ac729f..49c1c5ede 100644 --- a/proposals/http/wit/deps/io/poll.wit +++ b/proposals/http/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index b697e24d6..330f7095c 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -18,6 +18,9 @@ interface streams { /// The last operation (a write or flush) failed before completion. /// /// More information is available in the `error` payload. + /// + /// After this, the stream will be closed. All future operations return + /// `stream-error::closed`. last-operation-failed(error), /// The stream is closed: no more input will be accepted by the /// stream. A closed output-stream will return this error on all @@ -205,6 +208,7 @@ interface streams { /// The created `pollable` is a child resource of the `output-stream`. /// Implementations may trap if the `output-stream` is dropped before /// all derived `pollable`s created with this function are dropped. + @since(version = 0.2.0) subscribe: func() -> pollable; /// Write zeroes to a stream. diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit index 6405a4e48..f7001ccff 100644 --- a/proposals/http/wit/deps/io/world.wit +++ b/proposals/http/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.1; +package wasi:io@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/random/insecure-seed.wit b/proposals/http/wit/deps/random/insecure-seed.wit index 7e708dc52..cdea716cf 100644 --- a/proposals/http/wit/deps/random/insecure-seed.wit +++ b/proposals/http/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/insecure.wit b/proposals/http/wit/deps/random/insecure.wit index 3cdb53dfb..b71e85879 100644 --- a/proposals/http/wit/deps/random/insecure.wit +++ b/proposals/http/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index 2b5035d1c..0c57e8c80 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit index c615e96dc..16d68acfa 100644 --- a/proposals/http/wit/deps/random/world.wit +++ b/proposals/http/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.1; +package wasi:random@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/sockets/ip-name-lookup.wit b/proposals/http/wit/deps/sockets/ip-name-lookup.wit index dc56f3000..d3ab88aed 100644 --- a/proposals/http/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; @@ -48,7 +48,7 @@ interface ip-name-lookup { /// Create a `pollable` which will resolve once the stream is ready for I/O. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; diff --git a/proposals/http/wit/deps/sockets/network.wit b/proposals/http/wit/deps/sockets/network.wit index 8c13b348e..7f2d86a4c 100644 --- a/proposals/http/wit/deps/sockets/network.wit +++ b/proposals/http/wit/deps/sockets/network.wit @@ -1,5 +1,8 @@ @since(version = 0.2.0) interface network { + @unstable(feature = network-error-code) + use wasi:io/error@0.2.2.{error}; + /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. @@ -105,6 +108,19 @@ interface network { permanent-resolver-failure, } + /// Attempts to extract a network-related `error-code` from the stream + /// `error` provided. + /// + /// Stream operations which return `stream-error::last-operation-failed` + /// have a payload with more information about the operation that failed. + /// This payload can be passed through to this function to see if there's + /// network-related information about the error to return. + /// + /// Note that this function is fallible because not all stream-related + /// errors are network-related errors. + @unstable(feature = network-error-code) + network-error-code: func(err: borrow) -> option; + @since(version = 0.2.0) enum ip-address-family { /// Similar to `AF_INET` in POSIX. diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index bae5a29ec..728822dfa 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{input-stream, output-stream}; + use wasi:io/streams@0.2.2.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.1.{duration}; + use wasi:clocks/monotonic-clock@0.2.2.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; @@ -353,7 +353,7 @@ interface tcp { /// See /// for more information. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index b289e4943..d8acb2d29 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; @@ -184,7 +184,7 @@ interface udp { /// Create a `pollable` which will resolve once the socket is ready for I/O. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; @@ -220,7 +220,7 @@ interface udp { /// Create a `pollable` which will resolve once the stream is ready to receive again. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; @@ -280,7 +280,7 @@ interface udp { /// Create a `pollable` which will resolve once the stream is ready to send again. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit index a1d42670e..6e349c756 100644 --- a/proposals/http/wit/deps/sockets/world.wit +++ b/proposals/http/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.1; +package wasi:sockets@0.2.2; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 415d2ee1c..fadb89a3e 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,4 +1,4 @@ -package wasi:http@0.2.1; +package wasi:http@0.2.2; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. /// It is intended to be `include`d in other worlds. @@ -6,25 +6,25 @@ package wasi:http@0.2.1; world imports { /// HTTP proxies have access to time and randomness. @since(version = 0.2.0) - import wasi:clocks/monotonic-clock@0.2.1; + import wasi:clocks/monotonic-clock@0.2.2; @since(version = 0.2.0) - import wasi:clocks/wall-clock@0.2.1; + import wasi:clocks/wall-clock@0.2.2; @since(version = 0.2.0) - import wasi:random/random@0.2.1; + import wasi:random/random@0.2.2; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. @since(version = 0.2.0) - import wasi:cli/stdout@0.2.1; + import wasi:cli/stdout@0.2.2; @since(version = 0.2.0) - import wasi:cli/stderr@0.2.1; + import wasi:cli/stderr@0.2.2; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. @since(version = 0.2.0) - import wasi:cli/stdin@0.2.1; + import wasi:cli/stdin@0.2.2; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 30b364226..40ee77068 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -4,13 +4,13 @@ @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.1.{duration}; + use wasi:clocks/monotonic-clock@0.2.2.{duration}; @since(version = 0.2.0) - use wasi:io/streams@0.2.1.{input-stream, output-stream}; + use wasi:io/streams@0.2.2.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/error@0.2.1.{error as io-error}; + use wasi:io/error@0.2.2.{error as io-error}; @since(version = 0.2.0) - use wasi:io/poll@0.2.1.{pollable}; + use wasi:io/poll@0.2.2.{pollable}; /// This type corresponds to HTTP standard Methods. @since(version = 0.2.0) From b3c13355fc708e6313ebacf1e1f93671055d34e0 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 30 Oct 2024 10:39:50 -0700 Subject: [PATCH 1515/1772] add LICENSE.md from wasi-proposal-template License is the is the W3C CLA deed. Updated end date to 2024. --- proposals/cli/LICENSE.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 proposals/cli/LICENSE.md diff --git a/proposals/cli/LICENSE.md b/proposals/cli/LICENSE.md new file mode 100644 index 000000000..c1c3b9443 --- /dev/null +++ b/proposals/cli/LICENSE.md @@ -0,0 +1,8 @@ +Copyright © 2019-2024 the Contributors to the WASI Specification, published +by the [WebAssembly Community Group][cg] under the +[W3C Community Contributor License Agreement (CLA)][cla]. A human-readable +[summary][summary] is available. + +[cg]: https://www.w3.org/community/webassembly/ +[cla]: https://www.w3.org/community/about/agreements/cla/ +[summary]: https://www.w3.org/community/about/agreements/cla-deed/ From 3ea7762a0cb588bba42501563691ca494c4b1751 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 30 Oct 2024 10:41:52 -0700 Subject: [PATCH 1516/1772] add LICENSE.md from wasi-proposal-template which is the W3C CLA deed. End date updates to 2024. --- proposals/http/LICENSE.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 proposals/http/LICENSE.md diff --git a/proposals/http/LICENSE.md b/proposals/http/LICENSE.md new file mode 100644 index 000000000..c1c3b9443 --- /dev/null +++ b/proposals/http/LICENSE.md @@ -0,0 +1,8 @@ +Copyright © 2019-2024 the Contributors to the WASI Specification, published +by the [WebAssembly Community Group][cg] under the +[W3C Community Contributor License Agreement (CLA)][cla]. A human-readable +[summary][summary] is available. + +[cg]: https://www.w3.org/community/webassembly/ +[cla]: https://www.w3.org/community/about/agreements/cla/ +[summary]: https://www.w3.org/community/about/agreements/cla-deed/ From 6f780e7ca404a628537437946e44f0e979218199 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 30 Oct 2024 10:43:31 -0700 Subject: [PATCH 1517/1772] add LICENSE.md from wasi-proposal-template --- proposals/sockets/LICENSE.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 proposals/sockets/LICENSE.md diff --git a/proposals/sockets/LICENSE.md b/proposals/sockets/LICENSE.md new file mode 100644 index 000000000..c1c3b9443 --- /dev/null +++ b/proposals/sockets/LICENSE.md @@ -0,0 +1,8 @@ +Copyright © 2019-2024 the Contributors to the WASI Specification, published +by the [WebAssembly Community Group][cg] under the +[W3C Community Contributor License Agreement (CLA)][cla]. A human-readable +[summary][summary] is available. + +[cg]: https://www.w3.org/community/webassembly/ +[cla]: https://www.w3.org/community/about/agreements/cla/ +[summary]: https://www.w3.org/community/about/agreements/cla-deed/ From 33403f7112837c34d8fafb7f329621ca1558fcbc Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 30 Oct 2024 10:44:20 -0700 Subject: [PATCH 1518/1772] add LICENSE.md from wasi-proposal-template --- proposals/random/LICENSE.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 proposals/random/LICENSE.md diff --git a/proposals/random/LICENSE.md b/proposals/random/LICENSE.md new file mode 100644 index 000000000..c1c3b9443 --- /dev/null +++ b/proposals/random/LICENSE.md @@ -0,0 +1,8 @@ +Copyright © 2019-2024 the Contributors to the WASI Specification, published +by the [WebAssembly Community Group][cg] under the +[W3C Community Contributor License Agreement (CLA)][cla]. A human-readable +[summary][summary] is available. + +[cg]: https://www.w3.org/community/webassembly/ +[cla]: https://www.w3.org/community/about/agreements/cla/ +[summary]: https://www.w3.org/community/about/agreements/cla-deed/ From 7129c3d8e7125f56ae3876cdf09b881c50b72786 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 30 Oct 2024 10:45:17 -0700 Subject: [PATCH 1519/1772] add LICENSE.md from wasi-proposal-template --- proposals/filesystem/LICENSE.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 proposals/filesystem/LICENSE.md diff --git a/proposals/filesystem/LICENSE.md b/proposals/filesystem/LICENSE.md new file mode 100644 index 000000000..c1c3b9443 --- /dev/null +++ b/proposals/filesystem/LICENSE.md @@ -0,0 +1,8 @@ +Copyright © 2019-2024 the Contributors to the WASI Specification, published +by the [WebAssembly Community Group][cg] under the +[W3C Community Contributor License Agreement (CLA)][cla]. A human-readable +[summary][summary] is available. + +[cg]: https://www.w3.org/community/webassembly/ +[cla]: https://www.w3.org/community/about/agreements/cla/ +[summary]: https://www.w3.org/community/about/agreements/cla-deed/ From 2c45971797fdfbde1ad9d39b7fe45a9c070c5ad8 Mon Sep 17 00:00:00 2001 From: Ali Karami <117063502+1alii@users.noreply.github.com> Date: Wed, 13 Nov 2024 19:54:13 +0330 Subject: [PATCH 1520/1772] fix typo: remove extra '}' in API walk-through (#88) Co-authored-by: Ali Karami <0.ali.karami.0@gmail.com> --- proposals/io/README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/proposals/io/README.md b/proposals/io/README.md index 4dd4464fe..9efd0bcaf 100644 --- a/proposals/io/README.md +++ b/proposals/io/README.md @@ -91,7 +91,6 @@ types, `input-stream`, and `output-stream`, which support `read` and } Ok(()) } -} ``` #### Use case: copying from input to output using `splice` @@ -113,7 +112,6 @@ types, `input-stream`, and `output-stream`, which support `read` and } Ok(()) } -} ``` #### Use case: copying from input to output using `forward` @@ -123,7 +121,6 @@ types, `input-stream`, and `output-stream`, which support `read` and output.forward(input)?; Ok(()) } -} ``` ### Detailed design discussion From 5ebb2f2a2f402d4dab6090038d2148c108e0cea1 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 21 Nov 2024 16:37:00 -0500 Subject: [PATCH 1521/1772] feat: create 0.3.0-draft (#49) NOTE: no changes to interfaces --- .../random/wit-0.3.0-draft/insecure-seed.wit | 27 +++++++++++++++++ proposals/random/wit-0.3.0-draft/insecure.wit | 25 ++++++++++++++++ proposals/random/wit-0.3.0-draft/random.wit | 29 +++++++++++++++++++ proposals/random/wit-0.3.0-draft/world.wit | 13 +++++++++ 4 files changed, 94 insertions(+) create mode 100644 proposals/random/wit-0.3.0-draft/insecure-seed.wit create mode 100644 proposals/random/wit-0.3.0-draft/insecure.wit create mode 100644 proposals/random/wit-0.3.0-draft/random.wit create mode 100644 proposals/random/wit-0.3.0-draft/world.wit diff --git a/proposals/random/wit-0.3.0-draft/insecure-seed.wit b/proposals/random/wit-0.3.0-draft/insecure-seed.wit new file mode 100644 index 000000000..66a469432 --- /dev/null +++ b/proposals/random/wit-0.3.0-draft/insecure-seed.wit @@ -0,0 +1,27 @@ +package wasi:random@0.3.0; +/// The insecure-seed interface for seeding hash-map DoS resistance. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +@since(version = 0.2.0) +interface insecure-seed { + /// Return a 128-bit value that may contain a pseudo-random value. + /// + /// The returned value is not required to be computed from a CSPRNG, and may + /// even be entirely deterministic. Host implementations are encouraged to + /// provide pseudo-random values to any program exposed to + /// attacker-controlled content, to enable DoS protection built into many + /// languages' hash-map implementations. + /// + /// This function is intended to only be called once, by a source language + /// to initialize Denial Of Service (DoS) protection in its hash-map + /// implementation. + /// + /// # Expected future evolution + /// + /// This will likely be changed to a value import, to prevent it from being + /// called multiple times and potentially used for purposes other than DoS + /// protection. + @since(version = 0.2.0) + insecure-seed: func() -> tuple; +} diff --git a/proposals/random/wit-0.3.0-draft/insecure.wit b/proposals/random/wit-0.3.0-draft/insecure.wit new file mode 100644 index 000000000..7f2b86fbe --- /dev/null +++ b/proposals/random/wit-0.3.0-draft/insecure.wit @@ -0,0 +1,25 @@ +package wasi:random@0.3.0; +/// The insecure interface for insecure pseudo-random numbers. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +@since(version = 0.2.0) +interface insecure { + /// Return `len` insecure pseudo-random bytes. + /// + /// This function is not cryptographically secure. Do not use it for + /// anything related to security. + /// + /// There are no requirements on the values of the returned bytes, however + /// implementations are encouraged to return evenly distributed values with + /// a long period. + @since(version = 0.2.0) + get-insecure-random-bytes: func(len: u64) -> list; + + /// Return an insecure pseudo-random `u64` value. + /// + /// This function returns the same type of pseudo-random data as + /// `get-insecure-random-bytes`, represented as a `u64`. + @since(version = 0.2.0) + get-insecure-random-u64: func() -> u64; +} diff --git a/proposals/random/wit-0.3.0-draft/random.wit b/proposals/random/wit-0.3.0-draft/random.wit new file mode 100644 index 000000000..5edfa2baa --- /dev/null +++ b/proposals/random/wit-0.3.0-draft/random.wit @@ -0,0 +1,29 @@ +package wasi:random@0.3.0; +/// WASI Random is a random data API. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +@since(version = 0.2.0) +interface random { + /// Return `len` cryptographically-secure random or pseudo-random bytes. + /// + /// This function must produce data at least as cryptographically secure and + /// fast as an adequately seeded cryptographically-secure pseudo-random + /// number generator (CSPRNG). It must not block, from the perspective of + /// the calling program, under any circumstances, including on the first + /// request and on requests for numbers of bytes. The returned data must + /// always be unpredictable. + /// + /// This function must always return fresh data. Deterministic environments + /// must omit this function, rather than implementing it with deterministic + /// data. + @since(version = 0.2.0) + get-random-bytes: func(len: u64) -> list; + + /// Return a cryptographically-secure random or pseudo-random `u64` value. + /// + /// This function returns the same type of data as `get-random-bytes`, + /// represented as a `u64`. + @since(version = 0.2.0) + get-random-u64: func() -> u64; +} diff --git a/proposals/random/wit-0.3.0-draft/world.wit b/proposals/random/wit-0.3.0-draft/world.wit new file mode 100644 index 000000000..d01746d1e --- /dev/null +++ b/proposals/random/wit-0.3.0-draft/world.wit @@ -0,0 +1,13 @@ +package wasi:random@0.3.0; + +@since(version = 0.2.0) +world imports { + @since(version = 0.2.0) + import random; + + @since(version = 0.2.0) + import insecure; + + @since(version = 0.2.0) + import insecure-seed; +} From 8176fe2a4a519d038b33fdd3f5d8af6fd47dd1b1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Nov 2024 13:00:18 -0800 Subject: [PATCH 1522/1772] Enclose URLs in documentation with angle brakcets. Put angle brackets around URLs in documentation, to help documentation tools like cargo doc generate clickable links for them. --- proposals/http/wit-0.3.0-draft/types.wit | 2 +- proposals/http/wit/types.wit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index e272ab0d3..b75ad47e3 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -26,7 +26,7 @@ interface types { } /// These cases are inspired by the IANA HTTP Proxy Error Types: - /// https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types + /// variant error-code { DNS-timeout, DNS-error(DNS-error-payload), diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 40ee77068..90b75a876 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -36,7 +36,7 @@ interface types { } /// These cases are inspired by the IANA HTTP Proxy Error Types: - /// https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types + /// @since(version = 0.2.0) variant error-code { DNS-timeout, From 2862140512f467df0b49363278399cdb5ea2d1f7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Nov 2024 13:02:16 -0800 Subject: [PATCH 1523/1772] Update generated files. --- proposals/http/imports.md | 2 +- proposals/http/proxy.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index 5b71ecc30..11c1cb83f 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -673,7 +673,7 @@ their headers, trailers, and bodies.

                      variant error-code

                      These cases are inspired by the IANA HTTP Proxy Error Types: -https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types

                      +https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types

                      Variant Cases
                      • DNS-timeout
                      • diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index ceb59c0ad..d609995ec 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -680,7 +680,7 @@ their headers, trailers, and bodies.

                      variant error-code

                      These cases are inspired by the IANA HTTP Proxy Error Types: -https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types

                      +https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types

                      Variant Cases
                      • DNS-timeout
                      • From 44175f9575cdac3d87385ef6fbcd972a6dcbffe0 Mon Sep 17 00:00:00 2001 From: FrankReh Date: Tue, 3 Dec 2024 15:24:57 -0500 Subject: [PATCH 1524/1772] Typos in comments (#147) and in the imports.md as those comments are duplicated there. --- proposals/filesystem/imports.md | 6 +++--- proposals/filesystem/wit/preopens.wit | 2 +- proposals/filesystem/wit/types.wit | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index 6d958eea1..34f0bf7ff 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -937,7 +937,7 @@ POSIX.

                        Return a stream for appending to a file, if available.

                        May fail with an error-code describing why the file cannot be appended.

                        Note: This allows using write-stream, which is similar to write with -O_APPEND in in POSIX.

                        +O_APPEND in POSIX.

                        Params
                        • self: borrow<descriptor>
                        • @@ -1284,7 +1284,7 @@ may also include the inode number, device number, birth timestamp, and other metadata fields that may change when the file is modified or replaced. It may also include a secret value chosen by the implementation and not otherwise exposed.

                          -

                          Implementations are encourated to provide the following properties:

                          +

                          Implementations are encouraged to provide the following properties:

                          • If the file is not modified or replaced, the computed hash value should usually not change.
                          • @@ -1352,7 +1352,7 @@ errors are filesystem-related errors.

                            ----

                            Functions

                            get-directories: func

                            -

                            Return the set of preopened directories, and their path.

                            +

                            Return the set of preopened directories, and their paths.

                            Return values
                            • list<(own<descriptor>, string)>
                            • diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit index 410bec1dc..d7f21a367 100644 --- a/proposals/filesystem/wit/preopens.wit +++ b/proposals/filesystem/wit/preopens.wit @@ -5,7 +5,7 @@ interface preopens { @since(version = 0.2.0) use types.{descriptor}; - /// Return the set of preopened directories, and their path. + /// Return the set of preopened directories, and their paths. @since(version = 0.2.0) get-directories: func() -> list>; } diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 49e0a30bb..88b7fcf0a 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -327,7 +327,7 @@ interface types { /// May fail with an error-code describing why the file cannot be appended. /// /// Note: This allows using `write-stream`, which is similar to `write` with - /// `O_APPEND` in in POSIX. + /// `O_APPEND` in POSIX. @since(version = 0.2.0) append-via-stream: func() -> result; @@ -623,7 +623,7 @@ interface types { /// replaced. It may also include a secret value chosen by the /// implementation and not otherwise exposed. /// - /// Implementations are encourated to provide the following properties: + /// Implementations are encouraged to provide the following properties: /// /// - If the file is not modified or replaced, the computed hash value should /// usually not change. From cd67380f1d17a2d02f86e35450ebe52076e3c3e6 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 5 Dec 2024 09:25:00 -0500 Subject: [PATCH 1525/1772] ci: add wkg oci publish --- proposals/io/.github/workflows/publish.yml | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 proposals/io/.github/workflows/publish.yml diff --git a/proposals/io/.github/workflows/publish.yml b/proposals/io/.github/workflows/publish.yml new file mode 100644 index 000000000..d6b84c5a8 --- /dev/null +++ b/proposals/io/.github/workflows/publish.yml @@ -0,0 +1,40 @@ +name: Publish a Wasm Component package to GitHub Artifacts + +on: + push: + tags: + - v* + workflow_dispatch: + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + publish: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/WebAssembly/wasi/io + tags: | + type=semver,pattern={{version}} + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: bytecodealliance/wkg-github-action + with: + description: 'A WASI API providing I/O stream abstractions.' + oci-reference-without-tag: 'ghcr.io/WebAssembly/wasi/io' + source: 'https://github.com/webassembly/wasi' + homepage: 'https://wasi.dev' + version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + licenses: 'Apache-2.0 WITH LLVM-exception' From c24bd5cb88f19c2383ba955dea1f9c7bafc1613e Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 5 Dec 2024 08:11:58 -0500 Subject: [PATCH 1526/1772] release: v0.2.3 --- proposals/io/.github/workflows/main.yml | 2 +- proposals/io/imports.md | 12 ++++++------ proposals/io/wit/error.wit | 2 +- proposals/io/wit/poll.wit | 2 +- proposals/io/wit/streams.wit | 2 +- proposals/io/wit/world.wit | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index 431b96bc0..d74c466ef 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -13,4 +13,4 @@ jobs: - uses: actions/checkout@v4 - uses: WebAssembly/wit-abi-up-to-date@v22 with: - wit-bindgen: '0.33.0' + wit-bindgen: '0.36.0' diff --git a/proposals/io/imports.md b/proposals/io/imports.md index da344c741..8101d1eea 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -2,13 +2,13 @@ -

                              Import interface wasi:io/error@0.2.2

                              +

                              Import interface wasi:io/error@0.2.3


                              Types

                              resource error

                              @@ -41,7 +41,7 @@ hazard.

                              • string
                              -

                              Import interface wasi:io/poll@0.2.2

                              +

                              Import interface wasi:io/poll@0.2.3

                              A poll API intended to let users wait for I/O events on multiple handles at once.


                              @@ -94,7 +94,7 @@ being ready for I/O.

                              • list<u32>
                              -

                              Import interface wasi:io/streams@0.2.2

                              +

                              Import interface wasi:io/streams@0.2.3

                              WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                              In the future, the component model is expected to add built-in stream types; diff --git a/proposals/io/wit/error.wit b/proposals/io/wit/error.wit index 717135f8c..97c606877 100644 --- a/proposals/io/wit/error.wit +++ b/proposals/io/wit/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; @since(version = 0.2.0) interface error { diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index 49c1c5ede..9bcbe8e03 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index 330f7095c..0de084629 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index f7001ccff..f1d2102dc 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; @since(version = 0.2.0) world imports { From 2534bc090b3cad8759f25be0f1541a4e73bcd857 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 5 Dec 2024 09:36:55 -0500 Subject: [PATCH 1527/1772] fix: pin version for action (#91) --- proposals/io/.github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/io/.github/workflows/publish.yml b/proposals/io/.github/workflows/publish.yml index d6b84c5a8..335266469 100644 --- a/proposals/io/.github/workflows/publish.yml +++ b/proposals/io/.github/workflows/publish.yml @@ -30,7 +30,7 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - uses: bytecodealliance/wkg-github-action + - uses: bytecodealliance/wkg-github-action@v1 with: description: 'A WASI API providing I/O stream abstractions.' oci-reference-without-tag: 'ghcr.io/WebAssembly/wasi/io' From 6ccfecc6f43af46c5d35af7678c1bad66e37dac0 Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Thu, 5 Dec 2024 16:51:06 +0100 Subject: [PATCH 1528/1772] Update publish.yml (#92) --- proposals/io/.github/workflows/publish.yml | 26 ++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/proposals/io/.github/workflows/publish.yml b/proposals/io/.github/workflows/publish.yml index 335266469..0e0613ecf 100644 --- a/proposals/io/.github/workflows/publish.yml +++ b/proposals/io/.github/workflows/publish.yml @@ -1,5 +1,6 @@ name: Publish a Wasm Component package to GitHub Artifacts +# Run this action whenever a new release is tagged on: push: tags: @@ -14,26 +15,43 @@ jobs: runs-on: ubuntu-latest steps: + # Checkout the repo and install dependencies - name: Checkout repository uses: actions/checkout@v2 - - name: Docker meta + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.10.15 + - name: Install wkg + shell: bash + run: cargo binstall wkg + + # To version our image we want to obtain the version from the tag + - name: Get version id: meta uses: docker/metadata-action@v5 with: images: ghcr.io/WebAssembly/wasi/io tags: | type=semver,pattern={{version}} - - name: Login to GitHub Container Registry + + # To upload our image to the GitHub registry, we first have to login + - name: Login to the GitHub registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + + # Build our `.wit` files into a Wasm binary + - name: Build + shell: bash + run: wkg wit build -o wasi-io.wasm - - uses: bytecodealliance/wkg-github-action@v1 + # Upload the Wasm binary to the GitHub registry + - uses: bytecodealliance/wkg-github-action@v2 with: - description: 'A WASI API providing I/O stream abstractions.' oci-reference-without-tag: 'ghcr.io/WebAssembly/wasi/io' + file: 'wasi-io.wasm' + description: 'A WASI API providing I/O stream abstractions.' source: 'https://github.com/webassembly/wasi' homepage: 'https://wasi.dev' version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} From a83efbc882b2f2af9774391b2bc57dd19abcc064 Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Thu, 5 Dec 2024 17:03:54 +0100 Subject: [PATCH 1529/1772] Update publish.yml (#93) --- proposals/io/.github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/io/.github/workflows/publish.yml b/proposals/io/.github/workflows/publish.yml index 0e0613ecf..6db87e5f8 100644 --- a/proposals/io/.github/workflows/publish.yml +++ b/proposals/io/.github/workflows/publish.yml @@ -47,7 +47,7 @@ jobs: run: wkg wit build -o wasi-io.wasm # Upload the Wasm binary to the GitHub registry - - uses: bytecodealliance/wkg-github-action@v2 + - uses: bytecodealliance/wkg-github-action@v3 with: oci-reference-without-tag: 'ghcr.io/WebAssembly/wasi/io' file: 'wasi-io.wasm' From aa42a4769a229d72b74754ea03a1f3fe4974633b Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Thu, 5 Dec 2024 20:00:43 +0100 Subject: [PATCH 1530/1772] Update publish.yml (#94) --- proposals/io/.github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/io/.github/workflows/publish.yml b/proposals/io/.github/workflows/publish.yml index 6db87e5f8..ad1ff0f16 100644 --- a/proposals/io/.github/workflows/publish.yml +++ b/proposals/io/.github/workflows/publish.yml @@ -49,7 +49,7 @@ jobs: # Upload the Wasm binary to the GitHub registry - uses: bytecodealliance/wkg-github-action@v3 with: - oci-reference-without-tag: 'ghcr.io/WebAssembly/wasi/io' + oci-reference-without-tag: 'ghcr.io/webassembly/wasi/io' file: 'wasi-io.wasm' description: 'A WASI API providing I/O stream abstractions.' source: 'https://github.com/webassembly/wasi' From 8f280d8be9b00c2f86d71b9087ace83dd3afa79e Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Thu, 5 Dec 2024 20:10:45 +0100 Subject: [PATCH 1531/1772] Update publish.yml (#95) --- proposals/io/.github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/io/.github/workflows/publish.yml b/proposals/io/.github/workflows/publish.yml index ad1ff0f16..3e514b8dd 100644 --- a/proposals/io/.github/workflows/publish.yml +++ b/proposals/io/.github/workflows/publish.yml @@ -47,7 +47,7 @@ jobs: run: wkg wit build -o wasi-io.wasm # Upload the Wasm binary to the GitHub registry - - uses: bytecodealliance/wkg-github-action@v3 + - uses: bytecodealliance/wkg-github-action@v4 with: oci-reference-without-tag: 'ghcr.io/webassembly/wasi/io' file: 'wasi-io.wasm' From 8e537d95d7083e673b0278563209eebc4590ce27 Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Thu, 5 Dec 2024 20:35:03 +0100 Subject: [PATCH 1532/1772] Update publish.yml (#96) --- proposals/io/.github/workflows/publish.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/io/.github/workflows/publish.yml b/proposals/io/.github/workflows/publish.yml index 3e514b8dd..54f87ca4f 100644 --- a/proposals/io/.github/workflows/publish.yml +++ b/proposals/io/.github/workflows/publish.yml @@ -10,6 +10,9 @@ on: env: IMAGE_NAME: ${{ github.repository }} +permissions: + packages: write + jobs: publish: runs-on: ubuntu-latest From 50e6ca1f3e1a0d910066facb48bfce435d9704f2 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 5 Dec 2024 22:11:53 +0100 Subject: [PATCH 1533/1772] v0.2.3 --- proposals/random/imports.md | 12 ++++++------ proposals/random/wit/insecure-seed.wit | 2 +- proposals/random/wit/insecure.wit | 2 +- proposals/random/wit/random.wit | 2 +- proposals/random/wit/world.wit | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/random/imports.md b/proposals/random/imports.md index 597b93039..122be7c7b 100644 --- a/proposals/random/imports.md +++ b/proposals/random/imports.md @@ -2,13 +2,13 @@

                              -

                              Import interface wasi:random/random@0.2.2

                              +

                              Import interface wasi:random/random@0.2.3

                              WASI Random is a random data API.

                              It is intended to be portable at least between Unix-family platforms and Windows.

                              @@ -41,7 +41,7 @@ represented as a u64.

                              • u64
                              -

                              Import interface wasi:random/insecure@0.2.2

                              +

                              Import interface wasi:random/insecure@0.2.3

                              The insecure interface for insecure pseudo-random numbers.

                              It is intended to be portable at least between Unix-family platforms and Windows.

                              @@ -70,7 +70,7 @@ a long period.

                              • u64
                              -

                              Import interface wasi:random/insecure-seed@0.2.2

                              +

                              Import interface wasi:random/insecure-seed@0.2.3

                              The insecure-seed interface for seeding hash-map DoS resistance.

                              It is intended to be portable at least between Unix-family platforms and Windows.

                              diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index cdea716cf..67d024d5b 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index b71e85879..a07dfab32 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 0c57e8c80..91957e633 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index 16d68acfa..0c1218f36 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; @since(version = 0.2.0) world imports { From 8a74834b0b7622587c0705993a3baa5dbe0a8e59 Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Thu, 5 Dec 2024 22:25:02 +0100 Subject: [PATCH 1534/1772] v0.2.3 (#76) --- proposals/clocks/imports.md | 16 ++++++++-------- proposals/clocks/wit/deps.lock | 4 ++-- proposals/clocks/wit/deps/io/error.wit | 2 +- proposals/clocks/wit/deps/io/poll.wit | 2 +- proposals/clocks/wit/deps/io/streams.wit | 2 +- proposals/clocks/wit/deps/io/world.wit | 2 +- proposals/clocks/wit/monotonic-clock.wit | 4 ++-- proposals/clocks/wit/timezone.wit | 2 +- proposals/clocks/wit/wall-clock.wit | 2 +- proposals/clocks/wit/world.wit | 2 +- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index ee9ca51c1..090dbb9a9 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -2,14 +2,14 @@ -

                              Import interface wasi:io/poll@0.2.2

                              +

                              Import interface wasi:io/poll@0.2.3

                              A poll API intended to let users wait for I/O events on multiple handles at once.


                              @@ -62,7 +62,7 @@ being ready for I/O.

                              • list<u32>
                              -

                              Import interface wasi:clocks/monotonic-clock@0.2.2

                              +

                              Import interface wasi:clocks/monotonic-clock@0.2.3

                              WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                              It is intended to be portable at least between Unix-family platforms and @@ -121,7 +121,7 @@ elapsed from the time this function is invoked.

                              -

                              Import interface wasi:clocks/wall-clock@0.2.2

                              +

                              Import interface wasi:clocks/wall-clock@0.2.3

                              WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                              @@ -162,7 +162,7 @@ also known as Unix Time.
                            • datetime
                            -

                            Import interface wasi:clocks/timezone@0.2.2

                            +

                            Import interface wasi:clocks/timezone@0.2.3


                            Types

                            type datetime

                            diff --git a/proposals/clocks/wit/deps.lock b/proposals/clocks/wit/deps.lock index 0e1333bc5..23fb87f77 100644 --- a/proposals/clocks/wit/deps.lock +++ b/proposals/clocks/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "6d8dbfaaaa685167c1829616dc7265f5f3cb776845879555612d56544f6d9bfc" -sha512 = "52219562c4183503169cd2947b8164e1c96974500a5adf15bbf382c5992a10a626cc89c3b319204aeda6698ce59cbca2c42f98f7fde296aa77b9db4b41154dbe" +sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" +sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" diff --git a/proposals/clocks/wit/deps/io/error.wit b/proposals/clocks/wit/deps/io/error.wit index 717135f8c..97c606877 100644 --- a/proposals/clocks/wit/deps/io/error.wit +++ b/proposals/clocks/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; @since(version = 0.2.0) interface error { diff --git a/proposals/clocks/wit/deps/io/poll.wit b/proposals/clocks/wit/deps/io/poll.wit index 49c1c5ede..9bcbe8e03 100644 --- a/proposals/clocks/wit/deps/io/poll.wit +++ b/proposals/clocks/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/clocks/wit/deps/io/streams.wit b/proposals/clocks/wit/deps/io/streams.wit index 330f7095c..0de084629 100644 --- a/proposals/clocks/wit/deps/io/streams.wit +++ b/proposals/clocks/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/clocks/wit/deps/io/world.wit b/proposals/clocks/wit/deps/io/world.wit index f7001ccff..f1d2102dc 100644 --- a/proposals/clocks/wit/deps/io/world.wit +++ b/proposals/clocks/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index 233cace4c..c676fb84d 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.2; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/clocks/wit/timezone.wit b/proposals/clocks/wit/timezone.wit index 349fb5703..b43e93b23 100644 --- a/proposals/clocks/wit/timezone.wit +++ b/proposals/clocks/wit/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/clocks/wit/wall-clock.wit b/proposals/clocks/wit/wall-clock.wit index ec05a1f1a..e00ce0893 100644 --- a/proposals/clocks/wit/wall-clock.wit +++ b/proposals/clocks/wit/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index e36802cc8..05f04f797 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; @since(version = 0.2.0) world imports { From bcec6c1f59007e44fd9a59cf869afd97cf613ea9 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 5 Dec 2024 22:28:10 +0100 Subject: [PATCH 1535/1772] v0.2.3 --- proposals/filesystem/imports.md | 24 +++++++++---------- proposals/filesystem/wit/deps.lock | 8 +++---- .../wit/deps/clocks/monotonic-clock.wit | 4 ++-- .../filesystem/wit/deps/clocks/timezone.wit | 2 +- .../filesystem/wit/deps/clocks/wall-clock.wit | 2 +- .../filesystem/wit/deps/clocks/world.wit | 2 +- proposals/filesystem/wit/deps/io/error.wit | 2 +- proposals/filesystem/wit/deps/io/poll.wit | 2 +- proposals/filesystem/wit/deps/io/streams.wit | 2 +- proposals/filesystem/wit/deps/io/world.wit | 2 +- proposals/filesystem/wit/preopens.wit | 2 +- proposals/filesystem/wit/types.wit | 6 ++--- proposals/filesystem/wit/world.wit | 2 +- 13 files changed, 30 insertions(+), 30 deletions(-) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index 34f0bf7ff..03cccfbef 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -2,16 +2,16 @@ -

                            Import interface wasi:io/error@0.2.2

                            +

                            Import interface wasi:io/error@0.2.3


                            Types

                            resource error

                            @@ -44,7 +44,7 @@ hazard.

                            • string
                            -

                            Import interface wasi:io/poll@0.2.2

                            +

                            Import interface wasi:io/poll@0.2.3

                            A poll API intended to let users wait for I/O events on multiple handles at once.


                            @@ -97,7 +97,7 @@ being ready for I/O.

                            • list<u32>
                            -

                            Import interface wasi:io/streams@0.2.2

                            +

                            Import interface wasi:io/streams@0.2.3

                            WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                            In the future, the component model is expected to add built-in stream types; @@ -427,7 +427,7 @@ is ready for reading, before performing the splice.

                            -

                            Import interface wasi:clocks/wall-clock@0.2.2

                            +

                            Import interface wasi:clocks/wall-clock@0.2.3

                            WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                            @@ -468,7 +468,7 @@ also known as Unix Time.
                          • datetime
                          -

                          Import interface wasi:filesystem/types@0.2.2

                          +

                          Import interface wasi:filesystem/types@0.2.3

                          WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                          @@ -1343,7 +1343,7 @@ errors are filesystem-related errors.

                          -

                          Import interface wasi:filesystem/preopens@0.2.2

                          +

                          Import interface wasi:filesystem/preopens@0.2.3


                          Types

                          type descriptor

                          diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index 5cab24d2b..316cbaa96 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "c2da62619d1067646316e8592b583d77036d778e28b1154353e0825956b3d6aa" -sha512 = "4d409fc38b31646fc5de70160e81bd3fa67f9c99b4d24543b4fd40a922c7545739869521b8a997efb675d0816de8b001b6af7950e0cb0bc823d89b9f07b286c4" +sha256 = "93a701968a7dd3c5d69031bc0601681c468972fdf7e28a93bb6150a67d6ebe8b" +sha512 = "98fca567c7a01887b0fb38981f1772169b6ea8de475b546508f8b86738d84e44ba95cae81def40ac34e8809f5f60e85224077ab8cb6d6d5d6296acc1df73c159" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "6d8dbfaaaa685167c1829616dc7265f5f3cb776845879555612d56544f6d9bfc" -sha512 = "52219562c4183503169cd2947b8164e1c96974500a5adf15bbf382c5992a10a626cc89c3b319204aeda6698ce59cbca2c42f98f7fde296aa77b9db4b41154dbe" +sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" +sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" diff --git a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit index 233cace4c..c676fb84d 100644 --- a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.2; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/filesystem/wit/deps/clocks/timezone.wit b/proposals/filesystem/wit/deps/clocks/timezone.wit index 349fb5703..b43e93b23 100644 --- a/proposals/filesystem/wit/deps/clocks/timezone.wit +++ b/proposals/filesystem/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/filesystem/wit/deps/clocks/wall-clock.wit b/proposals/filesystem/wit/deps/clocks/wall-clock.wit index ec05a1f1a..e00ce0893 100644 --- a/proposals/filesystem/wit/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/filesystem/wit/deps/clocks/world.wit b/proposals/filesystem/wit/deps/clocks/world.wit index e36802cc8..05f04f797 100644 --- a/proposals/filesystem/wit/deps/clocks/world.wit +++ b/proposals/filesystem/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/filesystem/wit/deps/io/error.wit b/proposals/filesystem/wit/deps/io/error.wit index 717135f8c..97c606877 100644 --- a/proposals/filesystem/wit/deps/io/error.wit +++ b/proposals/filesystem/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; @since(version = 0.2.0) interface error { diff --git a/proposals/filesystem/wit/deps/io/poll.wit b/proposals/filesystem/wit/deps/io/poll.wit index 49c1c5ede..9bcbe8e03 100644 --- a/proposals/filesystem/wit/deps/io/poll.wit +++ b/proposals/filesystem/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index 330f7095c..0de084629 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/filesystem/wit/deps/io/world.wit b/proposals/filesystem/wit/deps/io/world.wit index f7001ccff..f1d2102dc 100644 --- a/proposals/filesystem/wit/deps/io/world.wit +++ b/proposals/filesystem/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit index d7f21a367..cea97495b 100644 --- a/proposals/filesystem/wit/preopens.wit +++ b/proposals/filesystem/wit/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.2; +package wasi:filesystem@0.2.3; @since(version = 0.2.0) interface preopens { diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 88b7fcf0a..d229a21f4 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.2; +package wasi:filesystem@0.2.3; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.2; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.3.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.2.{datetime}; + use wasi:clocks/wall-clock@0.2.3.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index 8064bd64b..29405bc2c 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.2; +package wasi:filesystem@0.2.3; @since(version = 0.2.0) world imports { From 045bafa924e15baf6150707f92b288a52a1dc749 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 5 Dec 2024 22:32:01 +0100 Subject: [PATCH 1536/1772] v0.2.3 --- proposals/sockets/imports.md | 132 ++++++++++-------- proposals/sockets/wit/deps.lock | 8 +- .../wit/deps/clocks/monotonic-clock.wit | 4 +- .../sockets/wit/deps/clocks/timezone.wit | 2 +- .../sockets/wit/deps/clocks/wall-clock.wit | 2 +- proposals/sockets/wit/deps/clocks/world.wit | 2 +- proposals/sockets/wit/deps/io/error.wit | 2 +- proposals/sockets/wit/deps/io/poll.wit | 2 +- proposals/sockets/wit/deps/io/streams.wit | 2 +- proposals/sockets/wit/deps/io/world.wit | 2 +- proposals/sockets/wit/ip-name-lookup.wit | 2 +- proposals/sockets/wit/network.wit | 2 +- proposals/sockets/wit/tcp.wit | 6 +- proposals/sockets/wit/udp.wit | 2 +- proposals/sockets/wit/world.wit | 2 +- 15 files changed, 97 insertions(+), 75 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 661c21725..59d7d69b2 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -2,24 +2,60 @@ -

                          Import interface wasi:sockets/network@0.2.2

                          +

                          Import interface wasi:io/error@0.2.3


                          Types

                          -

                          resource network

                          +

                          resource error

                          +

                          A resource which represents some error information.

                          +

                          The only method provided by this resource is to-debug-string, +which provides some human-readable information about the error.

                          +

                          In the wasi:io package, this resource is returned through the +wasi:io/streams/stream-error type.

                          +

                          To provide more specific error information, other interfaces may +offer functions to "downcast" this error into more specific types. For example, +errors returned from streams derived from filesystem types can be described using +the filesystem's own error-code type. This is done using the function +wasi:filesystem/types/filesystem-error-code, which takes a borrow<error> +parameter and returns an option<wasi:filesystem/types/error-code>.

                          +

                          The set of functions which can "downcast" an error into a more +concrete type is open.

                          +

                          Functions

                          +

                          [method]error.to-debug-string: func

                          +

                          Returns a string that is suitable to assist humans in debugging +this error.

                          +

                          WARNING: The returned string should not be consumed mechanically! +It may change across platforms, hosts, or other implementation +details. Parsing this string is a major platform-compatibility +hazard.

                          +
                          Params
                          + +
                          Return values
                          +
                            +
                          • string
                          • +
                          +

                          Import interface wasi:sockets/network@0.2.3

                          +
                          +

                          Types

                          +

                          type error

                          +

                          error

                          +

                          +#### `resource network`

                          An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                          @@ -209,7 +245,26 @@ supported size.
                        • ipv4: ipv4-socket-address
                        • ipv6: ipv6-socket-address
                        -

                        Import interface wasi:sockets/instance-network@0.2.2

                        +
                        +

                        Functions

                        +

                        network-error-code: func

                        +

                        Attempts to extract a network-related error-code from the stream +error provided.

                        +

                        Stream operations which return stream-error::last-operation-failed +have a payload with more information about the operation that failed. +This payload can be passed through to this function to see if there's +network-related information about the error to return.

                        +

                        Note that this function is fallible because not all stream-related +errors are network-related errors.

                        +
                        Params
                        + +
                        Return values
                        + +

                        Import interface wasi:sockets/instance-network@0.2.3

                        This interface provides a value-export of the default network handle..


                        Types

                        @@ -224,7 +279,7 @@ supported size. -

                        Import interface wasi:io/poll@0.2.2

                        +

                        Import interface wasi:io/poll@0.2.3

                        A poll API intended to let users wait for I/O events on multiple handles at once.


                        @@ -277,7 +332,7 @@ being ready for I/O.

                        • list<u32>
                        -

                        Import interface wasi:sockets/udp@0.2.2

                        +

                        Import interface wasi:sockets/udp@0.2.3


                        Types

                        type pollable

                        @@ -691,7 +746,7 @@ It's planned to be removed when future is natively supported in Pre -

                        Import interface wasi:sockets/udp-create-socket@0.2.2

                        +

                        Import interface wasi:sockets/udp-create-socket@0.2.3


                        Types

                        type network

                        @@ -736,40 +791,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                        Import interface wasi:io/error@0.2.2

                        -
                        -

                        Types

                        -

                        resource error

                        -

                        A resource which represents some error information.

                        -

                        The only method provided by this resource is to-debug-string, -which provides some human-readable information about the error.

                        -

                        In the wasi:io package, this resource is returned through the -wasi:io/streams/stream-error type.

                        -

                        To provide more specific error information, other interfaces may -offer functions to "downcast" this error into more specific types. For example, -errors returned from streams derived from filesystem types can be described using -the filesystem's own error-code type. This is done using the function -wasi:filesystem/types/filesystem-error-code, which takes a borrow<error> -parameter and returns an option<wasi:filesystem/types/error-code>.

                        -

                        The set of functions which can "downcast" an error into a more -concrete type is open.

                        -

                        Functions

                        -

                        [method]error.to-debug-string: func

                        -

                        Returns a string that is suitable to assist humans in debugging -this error.

                        -

                        WARNING: The returned string should not be consumed mechanically! -It may change across platforms, hosts, or other implementation -details. Parsing this string is a major platform-compatibility -hazard.

                        -
                        Params
                        - -
                        Return values
                        -
                          -
                        • string
                        • -
                        -

                        Import interface wasi:io/streams@0.2.2

                        +

                        Import interface wasi:io/streams@0.2.3

                        WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                        In the future, the component model is expected to add built-in stream types; @@ -1099,7 +1121,7 @@ is ready for reading, before performing the splice.

                        -

                        Import interface wasi:clocks/monotonic-clock@0.2.2

                        +

                        Import interface wasi:clocks/monotonic-clock@0.2.3

                        WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                        It is intended to be portable at least between Unix-family platforms and @@ -1158,7 +1180,7 @@ elapsed from the time this function is invoked.

                        -

                        Import interface wasi:sockets/tcp@0.2.2

                        +

                        Import interface wasi:sockets/tcp@0.2.3


                        Types

                        type input-stream

                        @@ -1749,7 +1771,7 @@ has no effect and returns ok.

                        -

                        Import interface wasi:sockets/tcp-create-socket@0.2.2

                        +

                        Import interface wasi:sockets/tcp-create-socket@0.2.3


                        Types

                        type network

                        @@ -1794,7 +1816,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                        Import interface wasi:sockets/ip-name-lookup@0.2.2

                        +

                        Import interface wasi:sockets/ip-name-lookup@0.2.3


                        Types

                        type pollable

                        diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index 5cab24d2b..316cbaa96 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "c2da62619d1067646316e8592b583d77036d778e28b1154353e0825956b3d6aa" -sha512 = "4d409fc38b31646fc5de70160e81bd3fa67f9c99b4d24543b4fd40a922c7545739869521b8a997efb675d0816de8b001b6af7950e0cb0bc823d89b9f07b286c4" +sha256 = "93a701968a7dd3c5d69031bc0601681c468972fdf7e28a93bb6150a67d6ebe8b" +sha512 = "98fca567c7a01887b0fb38981f1772169b6ea8de475b546508f8b86738d84e44ba95cae81def40ac34e8809f5f60e85224077ab8cb6d6d5d6296acc1df73c159" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "6d8dbfaaaa685167c1829616dc7265f5f3cb776845879555612d56544f6d9bfc" -sha512 = "52219562c4183503169cd2947b8164e1c96974500a5adf15bbf382c5992a10a626cc89c3b319204aeda6698ce59cbca2c42f98f7fde296aa77b9db4b41154dbe" +sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" +sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" diff --git a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit index 233cace4c..c676fb84d 100644 --- a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.2; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/sockets/wit/deps/clocks/timezone.wit b/proposals/sockets/wit/deps/clocks/timezone.wit index 349fb5703..b43e93b23 100644 --- a/proposals/sockets/wit/deps/clocks/timezone.wit +++ b/proposals/sockets/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/sockets/wit/deps/clocks/wall-clock.wit b/proposals/sockets/wit/deps/clocks/wall-clock.wit index ec05a1f1a..e00ce0893 100644 --- a/proposals/sockets/wit/deps/clocks/wall-clock.wit +++ b/proposals/sockets/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/sockets/wit/deps/clocks/world.wit b/proposals/sockets/wit/deps/clocks/world.wit index e36802cc8..05f04f797 100644 --- a/proposals/sockets/wit/deps/clocks/world.wit +++ b/proposals/sockets/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/sockets/wit/deps/io/error.wit b/proposals/sockets/wit/deps/io/error.wit index 717135f8c..97c606877 100644 --- a/proposals/sockets/wit/deps/io/error.wit +++ b/proposals/sockets/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; @since(version = 0.2.0) interface error { diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit index 49c1c5ede..9bcbe8e03 100644 --- a/proposals/sockets/wit/deps/io/poll.wit +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index 330f7095c..0de084629 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit index f7001ccff..f1d2102dc 100644 --- a/proposals/sockets/wit/deps/io/world.wit +++ b/proposals/sockets/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index d3ab88aed..c1d8a47c1 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 7f2d86a4c..f3f60a370 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.2.{error}; + use wasi:io/error@0.2.3.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 728822dfa..b4cd87fce 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{input-stream, output-stream}; + use wasi:io/streams@0.2.3.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.2.{duration}; + use wasi:clocks/monotonic-clock@0.2.3.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index d8acb2d29..01901ca27 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index 6e349c756..2f0ad0d7c 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.2; +package wasi:sockets@0.2.3; @since(version = 0.2.0) world imports { From 012342d5dd9203e96e030ce0967187c5f8e83b82 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 5 Dec 2024 22:38:37 +0100 Subject: [PATCH 1537/1772] Update imports.md --- proposals/sockets/imports.md | 92 ++++++++++++++---------------------- 1 file changed, 35 insertions(+), 57 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 59d7d69b2..9ae46377f 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -2,12 +2,12 @@ -

                        Import interface wasi:io/error@0.2.3

                        -
                        -

                        Types

                        -

                        resource error

                        -

                        A resource which represents some error information.

                        -

                        The only method provided by this resource is to-debug-string, -which provides some human-readable information about the error.

                        -

                        In the wasi:io package, this resource is returned through the -wasi:io/streams/stream-error type.

                        -

                        To provide more specific error information, other interfaces may -offer functions to "downcast" this error into more specific types. For example, -errors returned from streams derived from filesystem types can be described using -the filesystem's own error-code type. This is done using the function -wasi:filesystem/types/filesystem-error-code, which takes a borrow<error> -parameter and returns an option<wasi:filesystem/types/error-code>.

                        -

                        The set of functions which can "downcast" an error into a more -concrete type is open.

                        -

                        Functions

                        -

                        [method]error.to-debug-string: func

                        -

                        Returns a string that is suitable to assist humans in debugging -this error.

                        -

                        WARNING: The returned string should not be consumed mechanically! -It may change across platforms, hosts, or other implementation -details. Parsing this string is a major platform-compatibility -hazard.

                        -
                        Params
                        - -
                        Return values
                        -
                          -
                        • string
                        • -

                        Import interface wasi:sockets/network@0.2.3


                        Types

                        -

                        type error

                        -

                        error

                        -

                        -#### `resource network` +

                        resource network

                        An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                        @@ -245,25 +209,6 @@ supported size.
                      • ipv4: ipv4-socket-address
                      • ipv6: ipv6-socket-address
                      -
                      -

                      Functions

                      -

                      network-error-code: func

                      -

                      Attempts to extract a network-related error-code from the stream -error provided.

                      -

                      Stream operations which return stream-error::last-operation-failed -have a payload with more information about the operation that failed. -This payload can be passed through to this function to see if there's -network-related information about the error to return.

                      -

                      Note that this function is fallible because not all stream-related -errors are network-related errors.

                      -
                      Params
                      - -
                      Return values
                      -

                      Import interface wasi:sockets/instance-network@0.2.3

                      This interface provides a value-export of the default network handle..


                      @@ -791,6 +736,39 @@ the socket is effectively an in-memory configuration object, unable to communica +

                      Import interface wasi:io/error@0.2.3

                      +
                      +

                      Types

                      +

                      resource error

                      +

                      A resource which represents some error information.

                      +

                      The only method provided by this resource is to-debug-string, +which provides some human-readable information about the error.

                      +

                      In the wasi:io package, this resource is returned through the +wasi:io/streams/stream-error type.

                      +

                      To provide more specific error information, other interfaces may +offer functions to "downcast" this error into more specific types. For example, +errors returned from streams derived from filesystem types can be described using +the filesystem's own error-code type. This is done using the function +wasi:filesystem/types/filesystem-error-code, which takes a borrow<error> +parameter and returns an option<wasi:filesystem/types/error-code>.

                      +

                      The set of functions which can "downcast" an error into a more +concrete type is open.

                      +

                      Functions

                      +

                      [method]error.to-debug-string: func

                      +

                      Returns a string that is suitable to assist humans in debugging +this error.

                      +

                      WARNING: The returned string should not be consumed mechanically! +It may change across platforms, hosts, or other implementation +details. Parsing this string is a major platform-compatibility +hazard.

                      +
                      Params
                      + +
                      Return values
                      +
                        +
                      • string
                      • +

                      Import interface wasi:io/streams@0.2.3

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      From b69fef6932458dd89b06d8bbca03f124e7acc175 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 5 Dec 2024 22:41:23 +0100 Subject: [PATCH 1538/1772] v0.2.3 --- proposals/cli/command.md | 118 ++++++++--------- proposals/cli/imports.md | 120 +++++++++--------- proposals/cli/wit/command.wit | 2 +- proposals/cli/wit/deps.lock | 20 +-- .../cli/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/cli/wit/deps/clocks/timezone.wit | 2 +- proposals/cli/wit/deps/clocks/wall-clock.wit | 2 +- proposals/cli/wit/deps/clocks/world.wit | 2 +- .../cli/wit/deps/filesystem/preopens.wit | 4 +- proposals/cli/wit/deps/filesystem/types.wit | 10 +- proposals/cli/wit/deps/filesystem/world.wit | 2 +- proposals/cli/wit/deps/io/error.wit | 2 +- proposals/cli/wit/deps/io/poll.wit | 2 +- proposals/cli/wit/deps/io/streams.wit | 2 +- proposals/cli/wit/deps/io/world.wit | 2 +- .../cli/wit/deps/random/insecure-seed.wit | 2 +- proposals/cli/wit/deps/random/insecure.wit | 2 +- proposals/cli/wit/deps/random/random.wit | 2 +- proposals/cli/wit/deps/random/world.wit | 2 +- .../cli/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/cli/wit/deps/sockets/network.wit | 2 +- proposals/cli/wit/deps/sockets/tcp.wit | 6 +- proposals/cli/wit/deps/sockets/udp.wit | 2 +- proposals/cli/wit/deps/sockets/world.wit | 2 +- proposals/cli/wit/imports.wit | 12 +- proposals/cli/wit/stdio.wit | 6 +- 26 files changed, 167 insertions(+), 167 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 7da1f925c..b25b71e82 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -2,42 +2,42 @@ -

                      Import interface wasi:cli/environment@0.2.2

                      +

                      Import interface wasi:cli/environment@0.2.3


                      Functions

                      get-environment: func

                      @@ -64,7 +64,7 @@ directory, interpreting . as shorthand for this.

                      • option<string>
                      -

                      Import interface wasi:cli/exit@0.2.2

                      +

                      Import interface wasi:cli/exit@0.2.3


                      Functions

                      exit: func

                      @@ -84,7 +84,7 @@ without the connotation that something bad has happened.

                      • status-code: u8
                      -

                      Import interface wasi:io/error@0.2.2

                      +

                      Import interface wasi:io/error@0.2.3


                      Types

                      resource error

                      @@ -117,7 +117,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/poll@0.2.2

                      +

                      Import interface wasi:io/poll@0.2.3

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -170,7 +170,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:io/streams@0.2.2

                      +

                      Import interface wasi:io/streams@0.2.3

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -500,7 +500,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.2

                      +

                      Import interface wasi:cli/stdin@0.2.3


                      Types

                      type input-stream

                      @@ -513,7 +513,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.2

                      +

                      Import interface wasi:cli/stdout@0.2.3


                      Types

                      type output-stream

                      @@ -526,7 +526,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.2

                      +

                      Import interface wasi:cli/stderr@0.2.3


                      Types

                      type output-stream

                      @@ -539,7 +539,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/terminal-input@0.2.2

                      +

                      Import interface wasi:cli/terminal-input@0.2.3

                      Terminal input.

                      In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -548,7 +548,7 @@ immediately, querying supported features, and so on.

                      Types

                      resource terminal-input

                      The input side of a terminal.

                      -

                      Import interface wasi:cli/terminal-output@0.2.2

                      +

                      Import interface wasi:cli/terminal-output@0.2.3

                      Terminal output.

                      In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -557,7 +557,7 @@ features, and so on.

                      Types

                      resource terminal-output

                      The output side of a terminal.

                      -

                      Import interface wasi:cli/terminal-stdin@0.2.2

                      +

                      Import interface wasi:cli/terminal-stdin@0.2.3

                      An interface providing an optional terminal-input for stdin as a link-time authority.


                      @@ -574,7 +574,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stdout@0.2.2

                      +

                      Import interface wasi:cli/terminal-stdout@0.2.3

                      An interface providing an optional terminal-output for stdout as a link-time authority.


                      @@ -591,7 +591,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stderr@0.2.2

                      +

                      Import interface wasi:cli/terminal-stderr@0.2.3

                      An interface providing an optional terminal-output for stderr as a link-time authority.


                      @@ -608,7 +608,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.2

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.3

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -667,7 +667,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.2

                      +

                      Import interface wasi:clocks/wall-clock@0.2.3

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -708,7 +708,7 @@ also known as Unix Time.
                    11. datetime
                    12. -

                      Import interface wasi:filesystem/types@0.2.2

                      +

                      Import interface wasi:filesystem/types@0.2.3

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                      @@ -1177,7 +1177,7 @@ POSIX.

                      Return a stream for appending to a file, if available.

                      May fail with an error-code describing why the file cannot be appended.

                      Note: This allows using write-stream, which is similar to write with -O_APPEND in in POSIX.

                      +O_APPEND in POSIX.

                      Params
                      + + +

                      Import interface wasi:cli/environment@0.2.3


                      Functions

                      get-environment: func

                      @@ -59,7 +59,7 @@ directory, interpreting . as shorthand for this.

                      • option<string>
                      -

                      Import interface wasi:cli/exit@0.2.2

                      +

                      Import interface wasi:cli/exit@0.2.3


                      Functions

                      exit: func

                      @@ -79,7 +79,7 @@ without the connotation that something bad has happened.

                      • status-code: u8
                      -

                      Import interface wasi:io/error@0.2.2

                      +

                      Import interface wasi:io/error@0.2.3


                      Types

                      resource error

                      @@ -112,7 +112,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/poll@0.2.2

                      +

                      Import interface wasi:io/poll@0.2.3

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -165,7 +165,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:io/streams@0.2.2

                      +

                      Import interface wasi:io/streams@0.2.3

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -495,7 +495,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.2

                      +

                      Import interface wasi:cli/stdin@0.2.3


                      Types

                      type input-stream

                      @@ -508,7 +508,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.2

                      +

                      Import interface wasi:cli/stdout@0.2.3


                      Types

                      type output-stream

                      @@ -521,7 +521,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.2

                      +

                      Import interface wasi:cli/stderr@0.2.3


                      Types

                      type output-stream

                      @@ -534,7 +534,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/terminal-input@0.2.2

                      +

                      Import interface wasi:cli/terminal-input@0.2.3

                      Terminal input.

                      In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -543,7 +543,7 @@ immediately, querying supported features, and so on.

                      Types

                      resource terminal-input

                      The input side of a terminal.

                      -

                      Import interface wasi:cli/terminal-output@0.2.2

                      +

                      Import interface wasi:cli/terminal-output@0.2.3

                      Terminal output.

                      In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -552,7 +552,7 @@ features, and so on.

                      Types

                      resource terminal-output

                      The output side of a terminal.

                      -

                      Import interface wasi:cli/terminal-stdin@0.2.2

                      +

                      Import interface wasi:cli/terminal-stdin@0.2.3

                      An interface providing an optional terminal-input for stdin as a link-time authority.


                      @@ -569,7 +569,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stdout@0.2.2

                      +

                      Import interface wasi:cli/terminal-stdout@0.2.3

                      An interface providing an optional terminal-output for stdout as a link-time authority.


                      @@ -586,7 +586,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stderr@0.2.2

                      +

                      Import interface wasi:cli/terminal-stderr@0.2.3

                      An interface providing an optional terminal-output for stderr as a link-time authority.


                      @@ -603,7 +603,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.2

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.3

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -662,7 +662,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.2

                      +

                      Import interface wasi:clocks/wall-clock@0.2.3

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -703,7 +703,7 @@ also known as Unix Time.
                    13. datetime
                    14. -

                      Import interface wasi:filesystem/types@0.2.2

                      +

                      Import interface wasi:filesystem/types@0.2.3

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                      @@ -1172,7 +1172,7 @@ POSIX.

                      Return a stream for appending to a file, if available.

                      May fail with an error-code describing why the file cannot be appended.

                      Note: This allows using write-stream, which is similar to write with -O_APPEND in in POSIX.

                      +O_APPEND in POSIX.

                      Params
                      • self: borrow<descriptor>
                      • @@ -1519,7 +1519,7 @@ may also include the inode number, device number, birth timestamp, and other metadata fields that may change when the file is modified or replaced. It may also include a secret value chosen by the implementation and not otherwise exposed.

                        -

                        Implementations are encourated to provide the following properties:

                        +

                        Implementations are encouraged to provide the following properties:

                        • If the file is not modified or replaced, the computed hash value should usually not change.
                        • @@ -1578,7 +1578,7 @@ errors are filesystem-related errors.

                          -

                          Import interface wasi:filesystem/preopens@0.2.2

                          +

                          Import interface wasi:filesystem/preopens@0.2.3


                          Types

                          type descriptor

                          @@ -1587,12 +1587,12 @@ errors are filesystem-related errors.

                          ----

                          Functions

                          get-directories: func

                          -

                          Return the set of preopened directories, and their path.

                          +

                          Return the set of preopened directories, and their paths.

                          Return values
                          -

                          Import interface wasi:sockets/network@0.2.2

                          +

                          Import interface wasi:sockets/network@0.2.3


                          Types

                          resource network

                          @@ -1785,7 +1785,7 @@ supported size.
                        • ipv4: ipv4-socket-address
                        • ipv6: ipv6-socket-address
                        -

                        Import interface wasi:sockets/instance-network@0.2.2

                        +

                        Import interface wasi:sockets/instance-network@0.2.3

                        This interface provides a value-export of the default network handle..


                        Types

                        @@ -1800,7 +1800,7 @@ supported size. -

                        Import interface wasi:sockets/udp@0.2.2

                        +

                        Import interface wasi:sockets/udp@0.2.3


                        Types

                        type pollable

                        @@ -2214,7 +2214,7 @@ It's planned to be removed when future is natively supported in Pre -

                        Import interface wasi:sockets/udp-create-socket@0.2.2

                        +

                        Import interface wasi:sockets/udp-create-socket@0.2.3


                        Types

                        type network

                        @@ -2259,7 +2259,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                        Import interface wasi:sockets/tcp@0.2.2

                        +

                        Import interface wasi:sockets/tcp@0.2.3


                        Types

                        type input-stream

                        @@ -2850,7 +2850,7 @@ has no effect and returns ok.

                        -

                        Import interface wasi:sockets/tcp-create-socket@0.2.2

                        +

                        Import interface wasi:sockets/tcp-create-socket@0.2.3


                        Types

                        type network

                        @@ -2895,7 +2895,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                        Import interface wasi:sockets/ip-name-lookup@0.2.2

                        +

                        Import interface wasi:sockets/ip-name-lookup@0.2.3


                        Types

                        type pollable

                        @@ -2975,7 +2975,7 @@ It's planned to be removed when future is natively supported in Pre -

                        Import interface wasi:random/random@0.2.2

                        +

                        Import interface wasi:random/random@0.2.3

                        WASI Random is a random data API.

                        It is intended to be portable at least between Unix-family platforms and Windows.

                        @@ -3008,7 +3008,7 @@ represented as a u64.

                        • u64
                        -

                        Import interface wasi:random/insecure@0.2.2

                        +

                        Import interface wasi:random/insecure@0.2.3

                        The insecure interface for insecure pseudo-random numbers.

                        It is intended to be portable at least between Unix-family platforms and Windows.

                        @@ -3037,7 +3037,7 @@ a long period.

                        • u64
                        -

                        Import interface wasi:random/insecure-seed@0.2.2

                        +

                        Import interface wasi:random/insecure-seed@0.2.3

                        The insecure-seed interface for seeding hash-map DoS resistance.

                        It is intended to be portable at least between Unix-family platforms and Windows.

                        diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index cc7a352c2..3a81766d6 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.2; +package wasi:cli@0.2.3; @since(version = 0.2.0) world command { diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index db5e12945..b08adc8fe 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,24 +1,24 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "c2da62619d1067646316e8592b583d77036d778e28b1154353e0825956b3d6aa" -sha512 = "4d409fc38b31646fc5de70160e81bd3fa67f9c99b4d24543b4fd40a922c7545739869521b8a997efb675d0816de8b001b6af7950e0cb0bc823d89b9f07b286c4" +sha256 = "93a701968a7dd3c5d69031bc0601681c468972fdf7e28a93bb6150a67d6ebe8b" +sha512 = "98fca567c7a01887b0fb38981f1772169b6ea8de475b546508f8b86738d84e44ba95cae81def40ac34e8809f5f60e85224077ab8cb6d6d5d6296acc1df73c159" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "69e220ec22593f097c7f486dd9e4f95576ef7056d3d531a86a277654872997ba" -sha512 = "457c027aebd1430e924564b3bb2477bc163083cb1029105c1432cbdc165cdf3cce4ac62dbb8e43e3dec09e24a6b2029204212e2f0e3919137cb207165368e157" +sha256 = "69d42fb10a04a33545b17e055f13db9b1e10e82ba0ed5bdb52334e40dc07c679" +sha512 = "612effbac6f4804fe0c29dae20b78bbba59e52cb754c15402f5fe229c3153a221e0fbdff1d9d00ceaa3fe049c6a95523a5b99f772f1c16d972eade2c88326a30" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "6d8dbfaaaa685167c1829616dc7265f5f3cb776845879555612d56544f6d9bfc" -sha512 = "52219562c4183503169cd2947b8164e1c96974500a5adf15bbf382c5992a10a626cc89c3b319204aeda6698ce59cbca2c42f98f7fde296aa77b9db4b41154dbe" +sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" +sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "b4bb285b1c51aac2f8911f6b44ba1587108a2b24f910fe4774414dc286678b66" -sha512 = "bc2ffca0ae48f54977a763a70fcfcd5f4fca6b7c530916352f98c59627cc3f5899e47b6308bd9848b8c72e14db57e254757d580010a3d56e6888dafce3dcb679" +sha256 = "dd0c91e7125172eb8fd4568e15ad9fc7305643015e6ece4396c3cc5e8c2bf79a" +sha512 = "d1ca2e7b0616a94a3b39d1b9450bb3fb595b01fd94a8626ad75433038dde40988ecb41ab93a374d569ab72163af3b30038d7bfc3499b9c07193181f4f1d9292a" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "f254783796170fdeac6756496cc6169903a88adeda7a5895265414bc63ba4d66" -sha512 = "3f68e874beb0ac9729d1738546a430f2f8b369eb510d3cd6dfcfc41427acb52a82701d73584b8ab637b8c3908c5d4f7a7d4806032cc5d375643fad0ebf84e053" +sha256 = "2bc0f65a8046207ee3330ad7d63f6fafeafd4cc0ea4084f081bd5e4f7b177e74" +sha512 = "3e5490e41547dffa78d52631825d93da8d60f4af0246cbaf97e1ecb879285953a86d5f1f390b10c32f91dd7eaec6f43e625a26b1c92c32a0c86fde428aedaaab" diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index 233cace4c..c676fb84d 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.2; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/cli/wit/deps/clocks/timezone.wit b/proposals/cli/wit/deps/clocks/timezone.wit index 349fb5703..b43e93b23 100644 --- a/proposals/cli/wit/deps/clocks/timezone.wit +++ b/proposals/cli/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit index ec05a1f1a..e00ce0893 100644 --- a/proposals/cli/wit/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/cli/wit/deps/clocks/world.wit b/proposals/cli/wit/deps/clocks/world.wit index e36802cc8..05f04f797 100644 --- a/proposals/cli/wit/deps/clocks/world.wit +++ b/proposals/cli/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/filesystem/preopens.wit b/proposals/cli/wit/deps/filesystem/preopens.wit index 410bec1dc..cea97495b 100644 --- a/proposals/cli/wit/deps/filesystem/preopens.wit +++ b/proposals/cli/wit/deps/filesystem/preopens.wit @@ -1,11 +1,11 @@ -package wasi:filesystem@0.2.2; +package wasi:filesystem@0.2.3; @since(version = 0.2.0) interface preopens { @since(version = 0.2.0) use types.{descriptor}; - /// Return the set of preopened directories, and their path. + /// Return the set of preopened directories, and their paths. @since(version = 0.2.0) get-directories: func() -> list>; } diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index 49e0a30bb..d229a21f4 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.2; +package wasi:filesystem@0.2.3; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.2; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.3.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.2.{datetime}; + use wasi:clocks/wall-clock@0.2.3.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) @@ -327,7 +327,7 @@ interface types { /// May fail with an error-code describing why the file cannot be appended. /// /// Note: This allows using `write-stream`, which is similar to `write` with - /// `O_APPEND` in in POSIX. + /// `O_APPEND` in POSIX. @since(version = 0.2.0) append-via-stream: func() -> result; @@ -623,7 +623,7 @@ interface types { /// replaced. It may also include a secret value chosen by the /// implementation and not otherwise exposed. /// - /// Implementations are encourated to provide the following properties: + /// Implementations are encouraged to provide the following properties: /// /// - If the file is not modified or replaced, the computed hash value should /// usually not change. diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit index 8064bd64b..29405bc2c 100644 --- a/proposals/cli/wit/deps/filesystem/world.wit +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.2; +package wasi:filesystem@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/io/error.wit b/proposals/cli/wit/deps/io/error.wit index 717135f8c..97c606877 100644 --- a/proposals/cli/wit/deps/io/error.wit +++ b/proposals/cli/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; @since(version = 0.2.0) interface error { diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit index 49c1c5ede..9bcbe8e03 100644 --- a/proposals/cli/wit/deps/io/poll.wit +++ b/proposals/cli/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index 330f7095c..0de084629 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/cli/wit/deps/io/world.wit b/proposals/cli/wit/deps/io/world.wit index f7001ccff..f1d2102dc 100644 --- a/proposals/cli/wit/deps/io/world.wit +++ b/proposals/cli/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/random/insecure-seed.wit b/proposals/cli/wit/deps/random/insecure-seed.wit index cdea716cf..67d024d5b 100644 --- a/proposals/cli/wit/deps/random/insecure-seed.wit +++ b/proposals/cli/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/insecure.wit b/proposals/cli/wit/deps/random/insecure.wit index b71e85879..a07dfab32 100644 --- a/proposals/cli/wit/deps/random/insecure.wit +++ b/proposals/cli/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index 0c57e8c80..91957e633 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/world.wit b/proposals/cli/wit/deps/random/world.wit index 16d68acfa..0c1218f36 100644 --- a/proposals/cli/wit/deps/random/world.wit +++ b/proposals/cli/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index d3ab88aed..c1d8a47c1 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit index 7f2d86a4c..f3f60a370 100644 --- a/proposals/cli/wit/deps/sockets/network.wit +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.2.{error}; + use wasi:io/error@0.2.3.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index 728822dfa..b4cd87fce 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{input-stream, output-stream}; + use wasi:io/streams@0.2.3.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.2.{duration}; + use wasi:clocks/monotonic-clock@0.2.3.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index d8acb2d29..01901ca27 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit index 6e349c756..2f0ad0d7c 100644 --- a/proposals/cli/wit/deps/sockets/world.wit +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.2; +package wasi:sockets@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/imports.wit b/proposals/cli/wit/imports.wit index ebd7ba173..8b4e3975e 100644 --- a/proposals/cli/wit/imports.wit +++ b/proposals/cli/wit/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.2; +package wasi:cli@0.2.3; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.2; + include wasi:clocks/imports@0.2.3; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.2; + include wasi:filesystem/imports@0.2.3; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.2; + include wasi:sockets/imports@0.2.3; @since(version = 0.2.0) - include wasi:random/imports@0.2.2; + include wasi:random/imports@0.2.3; @since(version = 0.2.0) - include wasi:io/imports@0.2.2; + include wasi:io/imports@0.2.3; @since(version = 0.2.0) import environment; diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index 860313eea..1b54f5318 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{input-stream}; + use wasi:io/streams@0.2.3.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{output-stream}; + use wasi:io/streams@0.2.3.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{output-stream}; + use wasi:io/streams@0.2.3.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; From 45dc703c391314b01799f7ff26de69f95460fa27 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 5 Dec 2024 22:50:38 +0100 Subject: [PATCH 1539/1772] v0.2.3 --- proposals/http/imports.md | 44 ++++++++--------- proposals/http/proxy.md | 48 +++++++++---------- .../http/wit-0.3.0-draft/deps/cli/command.wit | 2 +- .../http/wit-0.3.0-draft/deps/cli/imports.wit | 12 ++--- .../http/wit-0.3.0-draft/deps/cli/stdio.wit | 6 +-- .../deps/clocks/monotonic-clock.wit | 4 +- .../wit-0.3.0-draft/deps/clocks/timezone.wit | 2 +- .../deps/clocks/wall-clock.wit | 2 +- .../wit-0.3.0-draft/deps/clocks/world.wit | 2 +- .../deps/filesystem/preopens.wit | 2 +- .../wit-0.3.0-draft/deps/filesystem/types.wit | 6 +-- .../wit-0.3.0-draft/deps/filesystem/world.wit | 2 +- .../http/wit-0.3.0-draft/deps/io/error.wit | 2 +- .../http/wit-0.3.0-draft/deps/io/poll.wit | 2 +- .../http/wit-0.3.0-draft/deps/io/streams.wit | 2 +- .../http/wit-0.3.0-draft/deps/io/world.wit | 2 +- .../deps/random/insecure-seed.wit | 2 +- .../wit-0.3.0-draft/deps/random/insecure.wit | 2 +- .../wit-0.3.0-draft/deps/random/random.wit | 2 +- .../wit-0.3.0-draft/deps/random/world.wit | 2 +- .../deps/sockets/ip-name-lookup.wit | 2 +- .../http/wit-0.3.0-draft/deps/sockets/tcp.wit | 6 +-- .../http/wit-0.3.0-draft/deps/sockets/udp.wit | 2 +- .../wit-0.3.0-draft/deps/sockets/world.wit | 2 +- proposals/http/wit-0.3.0-draft/proxy.wit | 10 ++-- proposals/http/wit-0.3.0-draft/types.wit | 4 +- proposals/http/wit/deps.lock | 24 +++++----- proposals/http/wit/deps/cli/command.wit | 2 +- proposals/http/wit/deps/cli/imports.wit | 12 ++--- proposals/http/wit/deps/cli/stdio.wit | 6 +-- .../http/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/http/wit/deps/clocks/timezone.wit | 2 +- proposals/http/wit/deps/clocks/wall-clock.wit | 2 +- proposals/http/wit/deps/clocks/world.wit | 2 +- .../http/wit/deps/filesystem/preopens.wit | 4 +- proposals/http/wit/deps/filesystem/types.wit | 10 ++-- proposals/http/wit/deps/filesystem/world.wit | 2 +- proposals/http/wit/deps/io/error.wit | 2 +- proposals/http/wit/deps/io/poll.wit | 2 +- proposals/http/wit/deps/io/streams.wit | 2 +- proposals/http/wit/deps/io/world.wit | 2 +- .../http/wit/deps/random/insecure-seed.wit | 2 +- proposals/http/wit/deps/random/insecure.wit | 2 +- proposals/http/wit/deps/random/random.wit | 2 +- proposals/http/wit/deps/random/world.wit | 2 +- .../http/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/http/wit/deps/sockets/network.wit | 2 +- proposals/http/wit/deps/sockets/tcp.wit | 6 +-- proposals/http/wit/deps/sockets/udp.wit | 2 +- proposals/http/wit/deps/sockets/world.wit | 2 +- proposals/http/wit/proxy.wit | 14 +++--- proposals/http/wit/types.wit | 8 ++-- 52 files changed, 148 insertions(+), 148 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index 11c1cb83f..c5b7d1b38 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -4,21 +4,21 @@ It is intended to be included in other worlds.

                        -

                        Import interface wasi:io/poll@0.2.2

                        +

                        Import interface wasi:io/poll@0.2.3

                        A poll API intended to let users wait for I/O events on multiple handles at once.


                        @@ -71,7 +71,7 @@ being ready for I/O.

                        • list<u32>
                        -

                        Import interface wasi:clocks/monotonic-clock@0.2.2

                        +

                        Import interface wasi:clocks/monotonic-clock@0.2.3

                        WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                        It is intended to be portable at least between Unix-family platforms and @@ -130,7 +130,7 @@ elapsed from the time this function is invoked.

                        -

                        Import interface wasi:clocks/wall-clock@0.2.2

                        +

                        Import interface wasi:clocks/wall-clock@0.2.3

                        WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                        @@ -171,7 +171,7 @@ also known as Unix Time.
                      • datetime
                      -

                      Import interface wasi:random/random@0.2.2

                      +

                      Import interface wasi:random/random@0.2.3

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -204,7 +204,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:io/error@0.2.2

                      +

                      Import interface wasi:io/error@0.2.3


                      Types

                      resource error

                      @@ -237,7 +237,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/streams@0.2.2

                      +

                      Import interface wasi:io/streams@0.2.3

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -567,7 +567,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.2

                      +

                      Import interface wasi:cli/stdout@0.2.3


                      Types

                      type output-stream

                      @@ -580,7 +580,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.2

                      +

                      Import interface wasi:cli/stderr@0.2.3


                      Types

                      type output-stream

                      @@ -593,7 +593,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.2

                      +

                      Import interface wasi:cli/stdin@0.2.3


                      Types

                      type input-stream

                      @@ -606,7 +606,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:http/types@0.2.2

                      +

                      Import interface wasi:http/types@0.2.3

                      This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                      @@ -1507,7 +1507,7 @@ but those will be reported by the incoming-body
                    15. option<result<result<own<incoming-response>, error-code>>>
                    16. -

                      Import interface wasi:http/outgoing-handler@0.2.2

                      +

                      Import interface wasi:http/outgoing-handler@0.2.3

                      This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                      diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index d609995ec..be326b998 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -6,26 +6,26 @@ outgoing HTTP requests.

                      -

                      Import interface wasi:io/poll@0.2.2

                      +

                      Import interface wasi:io/poll@0.2.3

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -78,7 +78,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.2

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.3

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -137,7 +137,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.2

                      +

                      Import interface wasi:clocks/wall-clock@0.2.3

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -178,7 +178,7 @@ also known as Unix Time.
                    17. datetime
                    18. -

                      Import interface wasi:random/random@0.2.2

                      +

                      Import interface wasi:random/random@0.2.3

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -211,7 +211,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:io/error@0.2.2

                      +

                      Import interface wasi:io/error@0.2.3


                      Types

                      resource error

                      @@ -244,7 +244,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/streams@0.2.2

                      +

                      Import interface wasi:io/streams@0.2.3

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -574,7 +574,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.2

                      +

                      Import interface wasi:cli/stdout@0.2.3


                      Types

                      type output-stream

                      @@ -587,7 +587,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.2

                      +

                      Import interface wasi:cli/stderr@0.2.3


                      Types

                      type output-stream

                      @@ -600,7 +600,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.2

                      +

                      Import interface wasi:cli/stdin@0.2.3


                      Types

                      type input-stream

                      @@ -613,7 +613,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:http/types@0.2.2

                      +

                      Import interface wasi:http/types@0.2.3

                      This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                      @@ -1514,7 +1514,7 @@ but those will be reported by the incoming-body
                    19. option<result<result<own<incoming-response>, error-code>>>
                    20. -

                      Import interface wasi:http/outgoing-handler@0.2.2

                      +

                      Import interface wasi:http/outgoing-handler@0.2.3

                      This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                      @@ -1551,7 +1551,7 @@ through the future-incoming-response
                    21. result<own<future-incoming-response>, error-code>
                    22. -

                      Export interface wasi:http/incoming-handler@0.2.2

                      +

                      Export interface wasi:http/incoming-handler@0.2.3


                      Types

                      type incoming-request

                      diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit index cc7a352c2..3a81766d6 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.2; +package wasi:cli@0.2.3; @since(version = 0.2.0) world command { diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit index ebd7ba173..8b4e3975e 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.2; +package wasi:cli@0.2.3; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.2; + include wasi:clocks/imports@0.2.3; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.2; + include wasi:filesystem/imports@0.2.3; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.2; + include wasi:sockets/imports@0.2.3; @since(version = 0.2.0) - include wasi:random/imports@0.2.2; + include wasi:random/imports@0.2.3; @since(version = 0.2.0) - include wasi:io/imports@0.2.2; + include wasi:io/imports@0.2.3; @since(version = 0.2.0) import environment; diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit index 860313eea..1b54f5318 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{input-stream}; + use wasi:io/streams@0.2.3.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{output-stream}; + use wasi:io/streams@0.2.3.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{output-stream}; + use wasi:io/streams@0.2.3.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 233cace4c..c676fb84d 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.2; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit index 349fb5703..b43e93b23 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit index ec05a1f1a..e00ce0893 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit index e36802cc8..05f04f797 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit index 410bec1dc..4bc202e9c 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.2; +package wasi:filesystem@0.2.3; @since(version = 0.2.0) interface preopens { diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit index 57dffb27b..826acd1c4 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.2; +package wasi:filesystem@0.2.3; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.2; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.3.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.2.{datetime}; + use wasi:clocks/wall-clock@0.2.3.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit index 8064bd64b..29405bc2c 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.2; +package wasi:filesystem@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/deps/io/error.wit b/proposals/http/wit-0.3.0-draft/deps/io/error.wit index 717135f8c..97c606877 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/error.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; @since(version = 0.2.0) interface error { diff --git a/proposals/http/wit-0.3.0-draft/deps/io/poll.wit b/proposals/http/wit-0.3.0-draft/deps/io/poll.wit index 49c1c5ede..9bcbe8e03 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/poll.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/http/wit-0.3.0-draft/deps/io/streams.wit b/proposals/http/wit-0.3.0-draft/deps/io/streams.wit index 80437d62e..c441d77b2 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/streams.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/http/wit-0.3.0-draft/deps/io/world.wit b/proposals/http/wit-0.3.0-draft/deps/io/world.wit index f7001ccff..f1d2102dc 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit index cdea716cf..67d024d5b 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit index b71e85879..a07dfab32 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit-0.3.0-draft/deps/random/random.wit b/proposals/http/wit-0.3.0-draft/deps/random/random.wit index 0c57e8c80..91957e633 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/random.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit-0.3.0-draft/deps/random/world.wit b/proposals/http/wit-0.3.0-draft/deps/random/world.wit index 16d68acfa..0c1218f36 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit index 8d6dcec31..6b87a0a98 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit index 91f421b44..3a86f5ee0 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{input-stream, output-stream}; + use wasi:io/streams@0.2.3.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.2.{duration}; + use wasi:clocks/monotonic-clock@0.2.3.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit index 328d91683..357d1d555 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit index 6e349c756..2f0ad0d7c 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.2; +package wasi:sockets@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/proxy.wit b/proposals/http/wit-0.3.0-draft/proxy.wit index 5342784a1..f39199249 100644 --- a/proposals/http/wit-0.3.0-draft/proxy.wit +++ b/proposals/http/wit-0.3.0-draft/proxy.wit @@ -4,19 +4,19 @@ package wasi:http@0.3.0-draft; /// It is intended to be `include`d in other worlds. world imports { /// HTTP proxies have access to time and randomness. - include wasi:clocks/imports@0.2.2; - import wasi:random/random@0.2.2; + include wasi:clocks/imports@0.2.3; + import wasi:random/random@0.2.3; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.2.2; - import wasi:cli/stderr@0.2.2; + import wasi:cli/stdout@0.2.3; + import wasi:cli/stderr@0.2.3; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. - import wasi:cli/stdin@0.2.2; + import wasi:cli/stdin@0.2.3; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index b75ad47e3..f2ed3a513 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -1,8 +1,8 @@ /// This interface defines all of the types and methods for implementing HTTP /// Requests and Responses, as well as their headers, trailers, and bodies. interface types { - use wasi:clocks/monotonic-clock@0.2.2.{duration}; - use wasi:io/error@0.2.2.{error}; + use wasi:clocks/monotonic-clock@0.2.3.{duration}; + use wasi:io/error@0.2.3.{error}; /// This type corresponds to HTTP standard Methods. variant method { diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 8d1257da3..935a1971f 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,29 +1,29 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -sha256 = "052c438d7606115bcfbe43094c55764c3396acfc8e4c69a6f54f7abcf8ef7c8c" -sha512 = "cce72d006e639cacabbd01137af99029591403a9bf6db8475e87d82cd6f256fa2118f9d15d5d88a34cacfaeb8d472f21f0914b20c83f6da1771f763cad4e1379" +sha256 = "4dadd13d55aaf626833d1f4b9c34a17b0f04e993babd09552b785cda3b95ea76" +sha512 = "898dcc4e8c15d18acc6b88dbe232336fa4d19019430a910dbc9e7aeaace3077a164af3be9f002de6e7e65ef693df340801ac0c7e421e9a746bf1b6d698a90835" [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "c2da62619d1067646316e8592b583d77036d778e28b1154353e0825956b3d6aa" -sha512 = "4d409fc38b31646fc5de70160e81bd3fa67f9c99b4d24543b4fd40a922c7545739869521b8a997efb675d0816de8b001b6af7950e0cb0bc823d89b9f07b286c4" +sha256 = "93a701968a7dd3c5d69031bc0601681c468972fdf7e28a93bb6150a67d6ebe8b" +sha512 = "98fca567c7a01887b0fb38981f1772169b6ea8de475b546508f8b86738d84e44ba95cae81def40ac34e8809f5f60e85224077ab8cb6d6d5d6296acc1df73c159" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "69e220ec22593f097c7f486dd9e4f95576ef7056d3d531a86a277654872997ba" -sha512 = "457c027aebd1430e924564b3bb2477bc163083cb1029105c1432cbdc165cdf3cce4ac62dbb8e43e3dec09e24a6b2029204212e2f0e3919137cb207165368e157" +sha256 = "69d42fb10a04a33545b17e055f13db9b1e10e82ba0ed5bdb52334e40dc07c679" +sha512 = "612effbac6f4804fe0c29dae20b78bbba59e52cb754c15402f5fe229c3153a221e0fbdff1d9d00ceaa3fe049c6a95523a5b99f772f1c16d972eade2c88326a30" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "6d8dbfaaaa685167c1829616dc7265f5f3cb776845879555612d56544f6d9bfc" -sha512 = "52219562c4183503169cd2947b8164e1c96974500a5adf15bbf382c5992a10a626cc89c3b319204aeda6698ce59cbca2c42f98f7fde296aa77b9db4b41154dbe" +sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" +sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "b4bb285b1c51aac2f8911f6b44ba1587108a2b24f910fe4774414dc286678b66" -sha512 = "bc2ffca0ae48f54977a763a70fcfcd5f4fca6b7c530916352f98c59627cc3f5899e47b6308bd9848b8c72e14db57e254757d580010a3d56e6888dafce3dcb679" +sha256 = "dd0c91e7125172eb8fd4568e15ad9fc7305643015e6ece4396c3cc5e8c2bf79a" +sha512 = "d1ca2e7b0616a94a3b39d1b9450bb3fb595b01fd94a8626ad75433038dde40988ecb41ab93a374d569ab72163af3b30038d7bfc3499b9c07193181f4f1d9292a" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "f254783796170fdeac6756496cc6169903a88adeda7a5895265414bc63ba4d66" -sha512 = "3f68e874beb0ac9729d1738546a430f2f8b369eb510d3cd6dfcfc41427acb52a82701d73584b8ab637b8c3908c5d4f7a7d4806032cc5d375643fad0ebf84e053" +sha256 = "2bc0f65a8046207ee3330ad7d63f6fafeafd4cc0ea4084f081bd5e4f7b177e74" +sha512 = "3e5490e41547dffa78d52631825d93da8d60f4af0246cbaf97e1ecb879285953a86d5f1f390b10c32f91dd7eaec6f43e625a26b1c92c32a0c86fde428aedaaab" diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit index cc7a352c2..3a81766d6 100644 --- a/proposals/http/wit/deps/cli/command.wit +++ b/proposals/http/wit/deps/cli/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.2; +package wasi:cli@0.2.3; @since(version = 0.2.0) world command { diff --git a/proposals/http/wit/deps/cli/imports.wit b/proposals/http/wit/deps/cli/imports.wit index ebd7ba173..8b4e3975e 100644 --- a/proposals/http/wit/deps/cli/imports.wit +++ b/proposals/http/wit/deps/cli/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.2; +package wasi:cli@0.2.3; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.2; + include wasi:clocks/imports@0.2.3; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.2; + include wasi:filesystem/imports@0.2.3; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.2; + include wasi:sockets/imports@0.2.3; @since(version = 0.2.0) - include wasi:random/imports@0.2.2; + include wasi:random/imports@0.2.3; @since(version = 0.2.0) - include wasi:io/imports@0.2.2; + include wasi:io/imports@0.2.3; @since(version = 0.2.0) import environment; diff --git a/proposals/http/wit/deps/cli/stdio.wit b/proposals/http/wit/deps/cli/stdio.wit index 860313eea..1b54f5318 100644 --- a/proposals/http/wit/deps/cli/stdio.wit +++ b/proposals/http/wit/deps/cli/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{input-stream}; + use wasi:io/streams@0.2.3.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{output-stream}; + use wasi:io/streams@0.2.3.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{output-stream}; + use wasi:io/streams@0.2.3.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index 233cace4c..c676fb84d 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.2; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/http/wit/deps/clocks/timezone.wit b/proposals/http/wit/deps/clocks/timezone.wit index 349fb5703..b43e93b23 100644 --- a/proposals/http/wit/deps/clocks/timezone.wit +++ b/proposals/http/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/http/wit/deps/clocks/wall-clock.wit b/proposals/http/wit/deps/clocks/wall-clock.wit index ec05a1f1a..e00ce0893 100644 --- a/proposals/http/wit/deps/clocks/wall-clock.wit +++ b/proposals/http/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/http/wit/deps/clocks/world.wit b/proposals/http/wit/deps/clocks/world.wit index e36802cc8..05f04f797 100644 --- a/proposals/http/wit/deps/clocks/world.wit +++ b/proposals/http/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.2; +package wasi:clocks@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/filesystem/preopens.wit b/proposals/http/wit/deps/filesystem/preopens.wit index 410bec1dc..cea97495b 100644 --- a/proposals/http/wit/deps/filesystem/preopens.wit +++ b/proposals/http/wit/deps/filesystem/preopens.wit @@ -1,11 +1,11 @@ -package wasi:filesystem@0.2.2; +package wasi:filesystem@0.2.3; @since(version = 0.2.0) interface preopens { @since(version = 0.2.0) use types.{descriptor}; - /// Return the set of preopened directories, and their path. + /// Return the set of preopened directories, and their paths. @since(version = 0.2.0) get-directories: func() -> list>; } diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index 49e0a30bb..d229a21f4 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.2; +package wasi:filesystem@0.2.3; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.2; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.3.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.2.{datetime}; + use wasi:clocks/wall-clock@0.2.3.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) @@ -327,7 +327,7 @@ interface types { /// May fail with an error-code describing why the file cannot be appended. /// /// Note: This allows using `write-stream`, which is similar to `write` with - /// `O_APPEND` in in POSIX. + /// `O_APPEND` in POSIX. @since(version = 0.2.0) append-via-stream: func() -> result; @@ -623,7 +623,7 @@ interface types { /// replaced. It may also include a secret value chosen by the /// implementation and not otherwise exposed. /// - /// Implementations are encourated to provide the following properties: + /// Implementations are encouraged to provide the following properties: /// /// - If the file is not modified or replaced, the computed hash value should /// usually not change. diff --git a/proposals/http/wit/deps/filesystem/world.wit b/proposals/http/wit/deps/filesystem/world.wit index 8064bd64b..29405bc2c 100644 --- a/proposals/http/wit/deps/filesystem/world.wit +++ b/proposals/http/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.2; +package wasi:filesystem@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/io/error.wit b/proposals/http/wit/deps/io/error.wit index 717135f8c..97c606877 100644 --- a/proposals/http/wit/deps/io/error.wit +++ b/proposals/http/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; @since(version = 0.2.0) interface error { diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/io/poll.wit index 49c1c5ede..9bcbe8e03 100644 --- a/proposals/http/wit/deps/io/poll.wit +++ b/proposals/http/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index 330f7095c..0de084629 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit index f7001ccff..f1d2102dc 100644 --- a/proposals/http/wit/deps/io/world.wit +++ b/proposals/http/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.2; +package wasi:io@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/random/insecure-seed.wit b/proposals/http/wit/deps/random/insecure-seed.wit index cdea716cf..67d024d5b 100644 --- a/proposals/http/wit/deps/random/insecure-seed.wit +++ b/proposals/http/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/insecure.wit b/proposals/http/wit/deps/random/insecure.wit index b71e85879..a07dfab32 100644 --- a/proposals/http/wit/deps/random/insecure.wit +++ b/proposals/http/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index 0c57e8c80..91957e633 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit index 16d68acfa..0c1218f36 100644 --- a/proposals/http/wit/deps/random/world.wit +++ b/proposals/http/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.2; +package wasi:random@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/sockets/ip-name-lookup.wit b/proposals/http/wit/deps/sockets/ip-name-lookup.wit index d3ab88aed..c1d8a47c1 100644 --- a/proposals/http/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/http/wit/deps/sockets/network.wit b/proposals/http/wit/deps/sockets/network.wit index 7f2d86a4c..f3f60a370 100644 --- a/proposals/http/wit/deps/sockets/network.wit +++ b/proposals/http/wit/deps/sockets/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.2.{error}; + use wasi:io/error@0.2.3.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index 728822dfa..b4cd87fce 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{input-stream, output-stream}; + use wasi:io/streams@0.2.3.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.2.{duration}; + use wasi:clocks/monotonic-clock@0.2.3.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index d8acb2d29..01901ca27 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit index 6e349c756..2f0ad0d7c 100644 --- a/proposals/http/wit/deps/sockets/world.wit +++ b/proposals/http/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.2; +package wasi:sockets@0.2.3; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index fadb89a3e..de3bbe8ae 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,4 +1,4 @@ -package wasi:http@0.2.2; +package wasi:http@0.2.3; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. /// It is intended to be `include`d in other worlds. @@ -6,25 +6,25 @@ package wasi:http@0.2.2; world imports { /// HTTP proxies have access to time and randomness. @since(version = 0.2.0) - import wasi:clocks/monotonic-clock@0.2.2; + import wasi:clocks/monotonic-clock@0.2.3; @since(version = 0.2.0) - import wasi:clocks/wall-clock@0.2.2; + import wasi:clocks/wall-clock@0.2.3; @since(version = 0.2.0) - import wasi:random/random@0.2.2; + import wasi:random/random@0.2.3; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. @since(version = 0.2.0) - import wasi:cli/stdout@0.2.2; + import wasi:cli/stdout@0.2.3; @since(version = 0.2.0) - import wasi:cli/stderr@0.2.2; + import wasi:cli/stderr@0.2.3; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. @since(version = 0.2.0) - import wasi:cli/stdin@0.2.2; + import wasi:cli/stdin@0.2.3; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 90b75a876..2498f180a 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -4,13 +4,13 @@ @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.2.{duration}; + use wasi:clocks/monotonic-clock@0.2.3.{duration}; @since(version = 0.2.0) - use wasi:io/streams@0.2.2.{input-stream, output-stream}; + use wasi:io/streams@0.2.3.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/error@0.2.2.{error as io-error}; + use wasi:io/error@0.2.3.{error as io-error}; @since(version = 0.2.0) - use wasi:io/poll@0.2.2.{pollable}; + use wasi:io/poll@0.2.3.{pollable}; /// This type corresponds to HTTP standard Methods. @since(version = 0.2.0) From 5ca408eede012dcb0bd180817fa8acffee99fa5f Mon Sep 17 00:00:00 2001 From: Ilia Date: Mon, 6 Jan 2025 13:48:39 -0800 Subject: [PATCH 1540/1772] typo/grammar in README.md --- proposals/filesystem/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/README.md b/proposals/filesystem/README.md index 73dd4d5bd..b71eab4ee 100644 --- a/proposals/filesystem/README.md +++ b/proposals/filesystem/README.md @@ -39,7 +39,7 @@ WASI filesystem must have at least two complete independent implementations. ### Introduction WASI filesystem is a WASI API primarily for accessing host filesystems. It -has function for opening, reading, and writing files, and for working with +has functions for opening, reading, and writing files, and for working with directories. Unlike many filesystem APIs, WASI filesystem is capability-oriented. Instead From 18ae1e22abdba87fe974dea2778009a990fda033 Mon Sep 17 00:00:00 2001 From: linchizhen Date: Fri, 10 Jan 2025 23:40:43 +0800 Subject: [PATCH 1541/1772] chore: remove redundant word in comment (#140) * chore: remove redundant word in comment Signed-off-by: linchizhen * regenerate markdown file Signed-off-by: Joel Dice * regenerate other markdown file Signed-off-by: Joel Dice --------- Signed-off-by: linchizhen Signed-off-by: Joel Dice Co-authored-by: Joel Dice --- proposals/http/imports.md | 2 +- proposals/http/proxy.md | 2 +- proposals/http/wit/types.wit | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index c5b7d1b38..cc7589725 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -767,7 +767,7 @@ Headers and Trailers.

                      A fields may be mutable or immutable. A fields created using the constructor, from-list, or clone will be mutable, but a fields resource given by other means (including, but not limited to, -incoming-request.headers, outgoing-request.headers) might be be +incoming-request.headers, outgoing-request.headers) might be immutable. In an immutable fields, the set, append, and delete operations will fail with header-error.immutable.

                      type headers

                      diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index be326b998..27eabb194 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -774,7 +774,7 @@ Headers and Trailers.

                      A fields may be mutable or immutable. A fields created using the constructor, from-list, or clone will be mutable, but a fields resource given by other means (including, but not limited to, -incoming-request.headers, outgoing-request.headers) might be be +incoming-request.headers, outgoing-request.headers) might be immutable. In an immutable fields, the set, append, and delete operations will fail with header-error.immutable.

                      type headers

                      diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 2498f180a..0bd34fc72 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -170,7 +170,7 @@ interface types { /// A `fields` may be mutable or immutable. A `fields` created using the /// constructor, `from-list`, or `clone` will be mutable, but a `fields` /// resource given by other means (including, but not limited to, - /// `incoming-request.headers`, `outgoing-request.headers`) might be be + /// `incoming-request.headers`, `outgoing-request.headers`) might be /// immutable. In an immutable fields, the `set`, `append`, and `delete` /// operations will fail with `header-error.immutable`. @since(version = 0.2.0) From 238006d2df73d2d36581e4471ebff364dc7862ad Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 10 Jan 2025 10:49:52 -0700 Subject: [PATCH 1542/1772] add `response-outparam.send-informational` (#139) * add `response-outparam.send-informational` This allows a server to send zero or more HTTP 1xx responses prior to sending the final response using `response-outparam.set`. Note that this does not include support for consuming informational responses for outbound requests (which would be required to losslessly proxy such requests). Signed-off-by: Joel Dice * update wit-bindgen version Signed-off-by: Joel Dice * update wasm-tools version Signed-off-by: Joel Dice --------- Signed-off-by: Joel Dice --- proposals/http/.github/workflows/main.yml | 4 ++-- proposals/http/wit/types.wit | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index d7a090b50..a4336b25f 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -18,6 +18,6 @@ jobs: ./wit-deps lock --check - uses: WebAssembly/wit-abi-up-to-date@v22 with: - wasm-tools: '1.218.0' - wit-bindgen: '0.33.0' + wasm-tools: '1.223.0' + wit-bindgen: '0.37.0' worlds: 'imports proxy' diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 0bd34fc72..9c0ce8b32 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -435,6 +435,21 @@ interface types { /// other argument to `incoming-handler.handle`. @since(version = 0.2.0) resource response-outparam { + /// Send an HTTP 1xx response. + /// + /// Unlike `response-outparam.set`, this does not consume the + /// `response-outparam`, allowing the guest to send an arbitrary number of + /// informational responses before sending the final response using + /// `response-outparam.set`. + /// + /// This will return an `HTTP-protocol-error` if `status` is not in the + /// range [100-199], or an `internal-error` if the implementation does not + /// support informational responses. + @unstable(feature = informational-outbound-responses) + send-informational: func( + status: u16, + headers: headers + ) -> result<_, error-code>; /// Set the value of the `response-outparam` to either send a response, /// or indicate an error. From 62f2f8c316dd3842d7c66eb3ec614922ae25ce43 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Tue, 31 Dec 2024 15:47:24 -0500 Subject: [PATCH 1543/1772] feat: wasi-0.3.0 draft Signed-off-by: Bailey Hayes --- .../wit-0.3.0-draft/monotonic-clock.wit | 47 ++++++++++++++++ proposals/clocks/wit-0.3.0-draft/timezone.wit | 55 +++++++++++++++++++ .../clocks/wit-0.3.0-draft/wall-clock.wit | 46 ++++++++++++++++ proposals/clocks/wit-0.3.0-draft/world.wit | 11 ++++ 4 files changed, 159 insertions(+) create mode 100644 proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit create mode 100644 proposals/clocks/wit-0.3.0-draft/timezone.wit create mode 100644 proposals/clocks/wit-0.3.0-draft/wall-clock.wit create mode 100644 proposals/clocks/wit-0.3.0-draft/world.wit diff --git a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit new file mode 100644 index 000000000..05512bd32 --- /dev/null +++ b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit @@ -0,0 +1,47 @@ +package wasi:clocks@0.3.0; +/// WASI Monotonic Clock is a clock API intended to let users measure elapsed +/// time. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A monotonic clock is a clock which has an unspecified initial value, and +/// successive reads of the clock will produce non-decreasing values. +@since(version = 0.3.0) +interface monotonic-clock { + /// An instant in time, in nanoseconds. An instant is relative to an + /// unspecified initial value, and can only be compared to instances from + /// the same monotonic-clock. + @since(version = 0.3.0) + type instant = u64; + + /// A duration of time, in nanoseconds. + @since(version = 0.3.0) + type duration = u64; + + /// Read the current value of the clock. + /// + /// The clock is monotonic, therefore calling this function repeatedly will + /// produce a sequence of non-decreasing values. + @since(version = 0.3.0) + now: func() -> instant; + + /// Query the resolution of the clock. Returns the duration of time + /// corresponding to a clock tick. + @since(version = 0.3.0) + resolution: func() -> duration; + + /// Create a `future` which will resolve once the specified instant + /// has occurred. + @since(version = 0.3.0) + subscribe-instant: func( + when: instant, + ) -> future; + + /// Create a `future` that will resolve after the specified duration has + /// elapsed from the time this function is invoked. + @since(version = 0.3.0) + subscribe-duration: func( + when: duration, + ) -> future; +} diff --git a/proposals/clocks/wit-0.3.0-draft/timezone.wit b/proposals/clocks/wit-0.3.0-draft/timezone.wit new file mode 100644 index 000000000..ac9146834 --- /dev/null +++ b/proposals/clocks/wit-0.3.0-draft/timezone.wit @@ -0,0 +1,55 @@ +package wasi:clocks@0.3.0; + +@unstable(feature = clocks-timezone) +interface timezone { + @unstable(feature = clocks-timezone) + use wall-clock.{datetime}; + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + @unstable(feature = clocks-timezone) + display: func(when: datetime) -> timezone-display; + + /// The same as `display`, but only return the UTC offset. + @unstable(feature = clocks-timezone) + utc-offset: func(when: datetime) -> s32; + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + @unstable(feature = clocks-timezone) + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/clocks/wit-0.3.0-draft/wall-clock.wit b/proposals/clocks/wit-0.3.0-draft/wall-clock.wit new file mode 100644 index 000000000..b7a85ab35 --- /dev/null +++ b/proposals/clocks/wit-0.3.0-draft/wall-clock.wit @@ -0,0 +1,46 @@ +package wasi:clocks@0.3.0; +/// WASI Wall Clock is a clock API intended to let users query the current +/// time. The name "wall" makes an analogy to a "clock on the wall", which +/// is not necessarily monotonic as it may be reset. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A wall clock is a clock which measures the date and time according to +/// some external reference. +/// +/// External references may be reset, so this clock is not necessarily +/// monotonic, making it unsuitable for measuring elapsed time. +/// +/// It is intended for reporting the current date and time for humans. +@since(version = 0.3.0) +interface wall-clock { + /// A time and date in seconds plus nanoseconds. + @since(version = 0.3.0) + record datetime { + seconds: u64, + nanoseconds: u32, + } + + /// Read the current value of the clock. + /// + /// This clock is not monotonic, therefore calling this function repeatedly + /// will not necessarily produce a sequence of non-decreasing values. + /// + /// The returned timestamps represent the number of seconds since + /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], + /// also known as [Unix Time]. + /// + /// The nanoseconds field of the output is always less than 1000000000. + /// + /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + @since(version = 0.3.0) + now: func() -> datetime; + + /// Query the resolution of the clock. + /// + /// The nanoseconds field of the output is always less than 1000000000. + @since(version = 0.3.0) + resolution: func() -> datetime; +} diff --git a/proposals/clocks/wit-0.3.0-draft/world.wit b/proposals/clocks/wit-0.3.0-draft/world.wit new file mode 100644 index 000000000..f97bcfef1 --- /dev/null +++ b/proposals/clocks/wit-0.3.0-draft/world.wit @@ -0,0 +1,11 @@ +package wasi:clocks@0.3.0; + +@since(version = 0.3.0) +world imports { + @since(version = 0.3.0) + import monotonic-clock; + @since(version = 0.3.0) + import wall-clock; + @unstable(feature = clocks-timezone) + import timezone; +} From eb63cc252ab9c077efa5783bac05129f89292397 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Tue, 31 Dec 2024 18:09:21 -0500 Subject: [PATCH 1544/1772] feat: change API to be regular async func --- .../clocks/wit-0.3.0-draft/monotonic-clock.wit | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit index 05512bd32..87ebdaac5 100644 --- a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit +++ b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit @@ -31,17 +31,15 @@ interface monotonic-clock { @since(version = 0.3.0) resolution: func() -> duration; - /// Create a `future` which will resolve once the specified instant - /// has occurred. + /// Wait until the specified instant has occurred. @since(version = 0.3.0) - subscribe-instant: func( + wait-until: func( when: instant, - ) -> future; + ); - /// Create a `future` that will resolve after the specified duration has - /// elapsed from the time this function is invoked. + /// Wait for the specified duration has elapsed. @since(version = 0.3.0) - subscribe-duration: func( - when: duration, - ) -> future; + wait-for: func( + how-long: duration, + ); } From 7a90dba1e904d34d69cfdcd93b3acde29d95b574 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 14 Jan 2025 12:29:41 +0100 Subject: [PATCH 1545/1772] feat: add `wasi-0.3.0` draft Followed the example of `wasi-http` and `wasi-clocks` duplicating the package in a subdirectory - In wasip3 return values of functions are pollable by guests, therefore remove abstractions for which there is no need anymore: - Replace `start-X`/`finish-X` function pairs by `X` - Remove `would-block` error code - Remove `not-in-progress` error code - Replace `wasi:io/error.error` usage by `error-context` - Replace `wasi:io/streams.input-stream` return values by `stream` in return position - Replace `wasi:io/streams.output-stream` return values by `stream` in parameter position - Guests should be able to rely on `stream.new` to construct streams Signed-off-by: Roman Volosatovs --- proposals/sockets/wit-0.3.0-draft/deps.lock | 4 + proposals/sockets/wit-0.3.0-draft/deps.toml | 1 + .../deps/clocks/monotonic-clock.wit | 45 +++ .../wit-0.3.0-draft/deps/clocks/timezone.wit | 55 +++ .../deps/clocks/wall-clock.wit | 46 +++ .../wit-0.3.0-draft/deps/clocks/world.wit | 11 + .../wit-0.3.0-draft/instance-network.wit | 11 + .../wit-0.3.0-draft/ip-name-lookup.wit | 46 +++ proposals/sockets/wit-0.3.0-draft/network.wit | 153 ++++++++ .../wit-0.3.0-draft/tcp-create-socket.wit | 30 ++ proposals/sockets/wit-0.3.0-draft/tcp.wit | 331 ++++++++++++++++++ .../wit-0.3.0-draft/udp-create-socket.wit | 30 ++ proposals/sockets/wit-0.3.0-draft/udp.wit | 208 +++++++++++ proposals/sockets/wit-0.3.0-draft/world.wit | 19 + 14 files changed, 990 insertions(+) create mode 100644 proposals/sockets/wit-0.3.0-draft/deps.lock create mode 100644 proposals/sockets/wit-0.3.0-draft/deps.toml create mode 100644 proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit create mode 100644 proposals/sockets/wit-0.3.0-draft/deps/clocks/timezone.wit create mode 100644 proposals/sockets/wit-0.3.0-draft/deps/clocks/wall-clock.wit create mode 100644 proposals/sockets/wit-0.3.0-draft/deps/clocks/world.wit create mode 100644 proposals/sockets/wit-0.3.0-draft/instance-network.wit create mode 100644 proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit create mode 100644 proposals/sockets/wit-0.3.0-draft/network.wit create mode 100644 proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit create mode 100644 proposals/sockets/wit-0.3.0-draft/tcp.wit create mode 100644 proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit create mode 100644 proposals/sockets/wit-0.3.0-draft/udp.wit create mode 100644 proposals/sockets/wit-0.3.0-draft/world.wit diff --git a/proposals/sockets/wit-0.3.0-draft/deps.lock b/proposals/sockets/wit-0.3.0-draft/deps.lock new file mode 100644 index 000000000..20306c6fe --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/deps.lock @@ -0,0 +1,4 @@ +[clocks] +url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" +sha256 = "26e315db0d371495f8834edfc0e479042f94152ce677d96d54d3623d0e4ffb1e" +sha512 = "e1c76f499435841316f9287b88d8173558e64f277c321ff390556de8707a0b18dd6c1749bbb17bbbba8d523da246ef6eb05c990ceddb762e03efb2ae30cacc76" diff --git a/proposals/sockets/wit-0.3.0-draft/deps.toml b/proposals/sockets/wit-0.3.0-draft/deps.toml new file mode 100644 index 000000000..3f6ad6d2e --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/deps.toml @@ -0,0 +1 @@ +clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit new file mode 100644 index 000000000..87ebdaac5 --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -0,0 +1,45 @@ +package wasi:clocks@0.3.0; +/// WASI Monotonic Clock is a clock API intended to let users measure elapsed +/// time. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A monotonic clock is a clock which has an unspecified initial value, and +/// successive reads of the clock will produce non-decreasing values. +@since(version = 0.3.0) +interface monotonic-clock { + /// An instant in time, in nanoseconds. An instant is relative to an + /// unspecified initial value, and can only be compared to instances from + /// the same monotonic-clock. + @since(version = 0.3.0) + type instant = u64; + + /// A duration of time, in nanoseconds. + @since(version = 0.3.0) + type duration = u64; + + /// Read the current value of the clock. + /// + /// The clock is monotonic, therefore calling this function repeatedly will + /// produce a sequence of non-decreasing values. + @since(version = 0.3.0) + now: func() -> instant; + + /// Query the resolution of the clock. Returns the duration of time + /// corresponding to a clock tick. + @since(version = 0.3.0) + resolution: func() -> duration; + + /// Wait until the specified instant has occurred. + @since(version = 0.3.0) + wait-until: func( + when: instant, + ); + + /// Wait for the specified duration has elapsed. + @since(version = 0.3.0) + wait-for: func( + how-long: duration, + ); +} diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/timezone.wit new file mode 100644 index 000000000..ac9146834 --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -0,0 +1,55 @@ +package wasi:clocks@0.3.0; + +@unstable(feature = clocks-timezone) +interface timezone { + @unstable(feature = clocks-timezone) + use wall-clock.{datetime}; + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + @unstable(feature = clocks-timezone) + display: func(when: datetime) -> timezone-display; + + /// The same as `display`, but only return the UTC offset. + @unstable(feature = clocks-timezone) + utc-offset: func(when: datetime) -> s32; + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + @unstable(feature = clocks-timezone) + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/wall-clock.wit new file mode 100644 index 000000000..b7a85ab35 --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -0,0 +1,46 @@ +package wasi:clocks@0.3.0; +/// WASI Wall Clock is a clock API intended to let users query the current +/// time. The name "wall" makes an analogy to a "clock on the wall", which +/// is not necessarily monotonic as it may be reset. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A wall clock is a clock which measures the date and time according to +/// some external reference. +/// +/// External references may be reset, so this clock is not necessarily +/// monotonic, making it unsuitable for measuring elapsed time. +/// +/// It is intended for reporting the current date and time for humans. +@since(version = 0.3.0) +interface wall-clock { + /// A time and date in seconds plus nanoseconds. + @since(version = 0.3.0) + record datetime { + seconds: u64, + nanoseconds: u32, + } + + /// Read the current value of the clock. + /// + /// This clock is not monotonic, therefore calling this function repeatedly + /// will not necessarily produce a sequence of non-decreasing values. + /// + /// The returned timestamps represent the number of seconds since + /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], + /// also known as [Unix Time]. + /// + /// The nanoseconds field of the output is always less than 1000000000. + /// + /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + @since(version = 0.3.0) + now: func() -> datetime; + + /// Query the resolution of the clock. + /// + /// The nanoseconds field of the output is always less than 1000000000. + @since(version = 0.3.0) + resolution: func() -> datetime; +} diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/world.wit new file mode 100644 index 000000000..f97bcfef1 --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/world.wit @@ -0,0 +1,11 @@ +package wasi:clocks@0.3.0; + +@since(version = 0.3.0) +world imports { + @since(version = 0.3.0) + import monotonic-clock; + @since(version = 0.3.0) + import wall-clock; + @unstable(feature = clocks-timezone) + import timezone; +} diff --git a/proposals/sockets/wit-0.3.0-draft/instance-network.wit b/proposals/sockets/wit-0.3.0-draft/instance-network.wit new file mode 100644 index 000000000..5f6e6c1cc --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/instance-network.wit @@ -0,0 +1,11 @@ + +/// This interface provides a value-export of the default network handle.. +@since(version = 0.2.0) +interface instance-network { + @since(version = 0.2.0) + use network.{network}; + + /// Get a handle to the default network. + @since(version = 0.2.0) + instance-network: func() -> network; +} diff --git a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit new file mode 100644 index 000000000..dd26e6aa4 --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit @@ -0,0 +1,46 @@ +@since(version = 0.2.0) +interface ip-name-lookup { + @since(version = 0.2.0) + use network.{network, error-code, ip-address}; + + /// Resolve an internet host name to a list of IP addresses. + /// + /// Unicode domain names are automatically converted to ASCII using IDNA encoding. + /// If the input is an IP address string, the address is parsed and returned + /// as-is without making any external requests. + /// + /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. + /// + /// This function never blocks. It either immediately fails or immediately + /// returns successfully with a `resolve-address-stream` that can be used + /// to (asynchronously) fetch the results. + /// + /// # Typical errors + /// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address. + /// + /// # References: + /// - + /// - + /// - + /// - + @since(version = 0.2.0) + resolve-addresses: func(network: borrow, name: string) -> result; + + @since(version = 0.2.0) + resource resolve-address-stream { + /// Returns the next address from the resolver. + /// + /// This function should be called multiple times. On each call, it will + /// return the next address in connection order preference. If all + /// addresses have been exhausted, this function returns `none`. + /// + /// This function never returns IPv4-mapped IPv6 addresses. + /// + /// # Typical errors + /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) + /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) + /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) + @since(version = 0.2.0) + resolve-next-address: func() -> result, error-code>; + } +} diff --git a/proposals/sockets/wit-0.3.0-draft/network.wit b/proposals/sockets/wit-0.3.0-draft/network.wit new file mode 100644 index 000000000..c66efec0b --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/network.wit @@ -0,0 +1,153 @@ +@since(version = 0.2.0) +interface network { + /// An opaque resource that represents access to (a subset of) the network. + /// This enables context-based security for networking. + /// There is no need for this to map 1:1 to a physical network interface. + @since(version = 0.2.0) + resource network; + + /// Error codes. + /// + /// In theory, every API can return any error code. + /// In practice, API's typically only return the errors documented per API + /// combined with a couple of errors that are always possible: + /// - `unknown` + /// - `access-denied` + /// - `not-supported` + /// - `out-of-memory` + /// - `concurrency-conflict` + /// + /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. + @since(version = 0.2.0) + enum error-code { + /// Unknown error + unknown, + + /// Access denied. + /// + /// POSIX equivalent: EACCES, EPERM + access-denied, + + /// The operation is not supported. + /// + /// POSIX equivalent: EOPNOTSUPP + not-supported, + + /// One of the arguments is invalid. + /// + /// POSIX equivalent: EINVAL + invalid-argument, + + /// Not enough memory to complete the operation. + /// + /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY + out-of-memory, + + /// The operation timed out before it could finish completely. + timeout, + + /// This operation is incompatible with another asynchronous operation that is already in progress. + /// + /// POSIX equivalent: EALREADY + concurrency-conflict, + + /// The operation is not valid in the socket's current state. + invalid-state, + + /// A new socket resource could not be created because of a system limit. + new-socket-limit, + + /// A bind operation failed because the provided address is not an address that the `network` can bind to. + address-not-bindable, + + /// A bind operation failed because the provided address is already in use or because there are no ephemeral ports available. + address-in-use, + + /// The remote address is not reachable + remote-unreachable, + + + /// The TCP connection was forcefully rejected + connection-refused, + + /// The TCP connection was reset. + connection-reset, + + /// A TCP connection was aborted. + connection-aborted, + + + /// The size of a datagram sent to a UDP socket exceeded the maximum + /// supported size. + datagram-too-large, + + + /// Name does not exist or has no suitable associated IP addresses. + name-unresolvable, + + /// A temporary failure in name resolution occurred. + temporary-resolver-failure, + + /// A permanent failure in name resolution occurred. + permanent-resolver-failure, + } + + /// Attempts to extract a network-related `error-code` from the stream + /// `error` provided. + /// + /// Stream operations which return `stream-error::last-operation-failed` + /// have a payload with more information about the operation that failed. + /// This payload can be passed through to this function to see if there's + /// network-related information about the error to return. + /// + /// Note that this function is fallible because not all stream-related + /// errors are network-related errors. + @unstable(feature = network-error-code) + network-error-code: func(err: borrow) -> option; + + @since(version = 0.2.0) + enum ip-address-family { + /// Similar to `AF_INET` in POSIX. + ipv4, + + /// Similar to `AF_INET6` in POSIX. + ipv6, + } + + @since(version = 0.2.0) + type ipv4-address = tuple; + @since(version = 0.2.0) + type ipv6-address = tuple; + + @since(version = 0.2.0) + variant ip-address { + ipv4(ipv4-address), + ipv6(ipv6-address), + } + + @since(version = 0.2.0) + record ipv4-socket-address { + /// sin_port + port: u16, + /// sin_addr + address: ipv4-address, + } + + @since(version = 0.2.0) + record ipv6-socket-address { + /// sin6_port + port: u16, + /// sin6_flowinfo + flow-info: u32, + /// sin6_addr + address: ipv6-address, + /// sin6_scope_id + scope-id: u32, + } + + @since(version = 0.2.0) + variant ip-socket-address { + ipv4(ipv4-socket-address), + ipv6(ipv6-socket-address), + } +} diff --git a/proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit b/proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit new file mode 100644 index 000000000..eedbd3076 --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit @@ -0,0 +1,30 @@ +@since(version = 0.2.0) +interface tcp-create-socket { + @since(version = 0.2.0) + use network.{network, error-code, ip-address-family}; + @since(version = 0.2.0) + use tcp.{tcp-socket}; + + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` + /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # Typical errors + /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.2.0) + create-tcp-socket: func(address-family: ip-address-family) -> result; +} diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit new file mode 100644 index 000000000..23ab05d33 --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -0,0 +1,331 @@ +@since(version = 0.2.0) +interface tcp { + @since(version = 0.2.0) + use wasi:clocks/monotonic-clock@0.3.0.{duration}; + @since(version = 0.2.0) + use network.{network, error-code, ip-socket-address, ip-address-family}; + + @since(version = 0.2.0) + enum shutdown-type { + /// Similar to `SHUT_RD` in POSIX. + receive, + + /// Similar to `SHUT_WR` in POSIX. + send, + + /// Similar to `SHUT_RDWR` in POSIX. + both, + } + + /// A TCP socket resource. + /// + /// The socket can be in one of the following states: + /// - `unbound` + /// - `bind-in-progress` + /// - `bound` (See note below) + /// - `listen-in-progress` + /// - `listening` + /// - `connect-in-progress` + /// - `connected` + /// - `closed` + /// See + /// for more information. + /// + /// Note: Except where explicitly mentioned, whenever this documentation uses + /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. + /// (i.e. `bound`, `listen-in-progress`, `listening`, `connect-in-progress` or `connected`) + /// + /// In addition to the general error codes documented on the + /// `network::error-code` type, TCP socket methods may always return + /// `error(invalid-state)` when in the `closed` state. + @since(version = 0.2.0) + resource tcp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// Bind can be attempted multiple times on the same socket, even with + /// different arguments on each iteration. But never concurrently and + /// only as long as the previous bind failed. Once a bind succeeds, the + /// binding can't be changed anymore. + /// + /// # Typical errors + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) + /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// + /// # Implementors note + /// When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT + /// state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR + /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior + /// and SO_REUSEADDR performs something different entirely. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + + /// Connect to a remote endpoint. + /// This function takes a stream as a parameter, which will be used for data transmission to the server. + /// + /// On success: + /// - the socket is transitioned into the `connected` state. + /// - a stream is returned that can be used to read from the connection + /// + /// After a failed connection attempt, the socket will be in the `closed` + /// state and the only valid action left is to `drop` the socket. A single + /// socket can not be used to connect more than once. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) + /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) + /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + connect: func(network: borrow, remote-address: ip-socket-address, tx: stream) -> result, error-code>; + + /// Start listening for new connections. + /// + /// Transitions the socket into the `listening` state. + /// + /// Unlike POSIX, the socket must already be explicitly bound. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ) + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) + /// - `invalid-state`: The socket is already in the `listening` state. + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + listen: func() -> result<_, error-code>; + + /// Accept a new client socket. + /// This function takes a stream as a parameter, which will be used for data transmission to the client. + /// + /// The returned socket is bound and in the `connected` state. The following properties are inherited from the listener socket: + /// - `address-family` + /// - `keep-alive-enabled` + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// - `hop-limit` + /// - `receive-buffer-size` + /// - `send-buffer-size` + /// + /// On success, this function returns the newly accepted client socket along with + /// a streams that can be used to read from the connection. + /// + /// # Typical errors + /// - `invalid-state`: Socket is not in the `listening` state. (EINVAL) + /// - `connection-aborted`: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + accept: func(tx: stream) -> result>, error-code>; + + /// Get the bound local address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.2.0) + local-address: func() -> result; + + /// Get the remote address. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.2.0) + remote-address: func() -> result; + + /// Whether the socket is in the `listening` state. + /// + /// Equivalent to the SO_ACCEPTCONN socket option. + @since(version = 0.2.0) + is-listening: func() -> bool; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.2.0) + address-family: func() -> ip-address-family; + + /// Hints the desired listen queue size. Implementations are free to ignore this. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// + /// # Typical errors + /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. + /// - `invalid-argument`: (set) The provided value was 0. + /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. + @since(version = 0.2.0) + set-listen-backlog-size: func(value: u64) -> result<_, error-code>; + + /// Enables or disables keepalive. + /// + /// The keepalive behavior can be adjusted using: + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. + /// + /// Equivalent to the SO_KEEPALIVE socket option. + @since(version = 0.2.0) + keep-alive-enabled: func() -> result; + @since(version = 0.2.0) + set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; + + /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS) + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) + keep-alive-idle-time: func() -> result; + @since(version = 0.2.0) + set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; + + /// The time between keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPINTVL socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) + keep-alive-interval: func() -> result; + @since(version = 0.2.0) + set-keep-alive-interval: func(value: duration) -> result<_, error-code>; + + /// The maximum amount of keepalive packets TCP should send before aborting the connection. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPCNT socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) + keep-alive-count: func() -> result; + @since(version = 0.2.0) + set-keep-alive-count: func(value: u32) -> result<_, error-code>; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.2.0) + hop-limit: func() -> result; + @since(version = 0.2.0) + set-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) + receive-buffer-size: func() -> result; + @since(version = 0.2.0) + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) + send-buffer-size: func() -> result; + @since(version = 0.2.0) + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + + /// Initiate a graceful shutdown. + /// + /// - `receive`: The socket is not expecting to receive any data from + /// the peer. The `input-stream` associated with this socket will be + /// closed. Any data still in the receive queue at time of calling + /// this method will be discarded. + /// - `send`: The socket has no more data to send to the peer. The `output-stream` + /// associated with this socket will be closed and a FIN packet will be sent. + /// - `both`: Same effect as `receive` & `send` combined. + /// + /// This function is idempotent; shutting down a direction more than once + /// has no effect and returns `ok`. + /// + /// The shutdown function does not close (drop) the socket. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.2.0) + shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; + } +} diff --git a/proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit b/proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit new file mode 100644 index 000000000..e8eeacbfe --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit @@ -0,0 +1,30 @@ +@since(version = 0.2.0) +interface udp-create-socket { + @since(version = 0.2.0) + use network.{network, error-code, ip-address-family}; + @since(version = 0.2.0) + use udp.{udp-socket}; + + /// Create a new UDP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. + /// + /// This function does not require a network capability handle. This is considered to be safe because + /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind` is called, + /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. + /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # Typical errors + /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) + /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// + /// # References: + /// - + /// - + /// - + /// - + @since(version = 0.2.0) + create-udp-socket: func(address-family: ip-address-family) -> result; +} diff --git a/proposals/sockets/wit-0.3.0-draft/udp.wit b/proposals/sockets/wit-0.3.0-draft/udp.wit new file mode 100644 index 000000000..0f9e1c2e2 --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/udp.wit @@ -0,0 +1,208 @@ +@since(version = 0.2.0) +interface udp { + @since(version = 0.2.0) + use network.{network, error-code, ip-socket-address, ip-address-family}; + + /// A received datagram. + @since(version = 0.2.0) + record incoming-datagram { + /// The payload. + /// + /// Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. + data: list, + + /// The source address. + /// + /// This field is guaranteed to match the remote address the stream was initialized with, if any. + /// + /// Equivalent to the `src_addr` out parameter of `recvfrom`. + remote-address: ip-socket-address, + } + + /// A datagram to be sent out. + @since(version = 0.2.0) + record outgoing-datagram { + /// The payload. + data: list, + + /// The destination address. + /// + /// The requirements on this field depend on how the stream was initialized: + /// - with a remote address: this field must be None or match the stream's remote address exactly. + /// - without a remote address: this field is required. + /// + /// If this value is None, the send operation is equivalent to `send` in POSIX. Otherwise it is equivalent to `sendto`. + remote-address: option, + } + + /// A UDP socket handle. + @since(version = 0.2.0) + resource udp-socket { + /// Bind the socket to a specific network on the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the port is zero, the socket will be bound to a random free port. + /// + /// # Typical errors + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + + /// Set up inbound & outbound communication channels, optionally to a specific peer. + /// + /// This function only changes the local socket configuration and does not generate any network traffic. + /// On success, the `remote-address` of the socket is updated. The `local-address` may be updated as well, + /// based on the best network path to `remote-address`. + /// + /// When a `remote-address` is provided, the returned streams are limited to communicating with that specific peer: + /// - `send` can only be used to send to this destination. + /// - `receive` will only return datagrams sent from the provided `remote-address`. + /// + /// This method may be called multiple times on the same socket to change its association, but + /// only the most recently returned pair of streams will be operational. Implementations may trap if + /// the streams returned by a previous invocation haven't been dropped yet before calling `stream` again. + /// + /// The POSIX equivalent in pseudo-code is: + /// ```text + /// if (was previously connected) { + /// connect(s, AF_UNSPEC) + /// } + /// if (remote_address is Some) { + /// connect(s, remote_address) + /// } + /// ``` + /// + /// Unlike in POSIX, the socket must already be explicitly bound. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-state`: The socket is not bound. + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + %stream: func(remote-address: option) -> result, error-code>; + + /// Send messages on the socket. + /// + /// This function attempts to send all provided `datagrams` on the socket without blocking and + /// returns how many messages were actually sent (or queued for sending). + /// If none of the datagrams were able to be sent, `ok(0)` is returned. + /// + /// This function semantically behaves the same as iterating the `datagrams` list and sequentially + /// sending each individual datagram until either the end of the list has been reached or the first error occurred. + /// If at least one datagram has been sent successfully, this function never returns an error. + /// + /// If the input list is empty, the function returns `ok(0)`. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `stream`. (EISCONN) + /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + send: func(datagrams: list) -> result; + + + /// Get the current bound address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.2.0) + local-address: func() -> result; + + /// Get the address the socket is currently streaming to. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not streaming to a specific remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.2.0) + remote-address: func() -> result; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.2.0) + address-family: func() -> ip-address-family; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.2.0) + unicast-hop-limit: func() -> result; + @since(version = 0.2.0) + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.2.0) + receive-buffer-size: func() -> result; + @since(version = 0.2.0) + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.2.0) + send-buffer-size: func() -> result; + @since(version = 0.2.0) + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + } +} diff --git a/proposals/sockets/wit-0.3.0-draft/world.wit b/proposals/sockets/wit-0.3.0-draft/world.wit new file mode 100644 index 000000000..e7ba6a1f7 --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/world.wit @@ -0,0 +1,19 @@ +package wasi:sockets@0.3.0-draft; + +@since(version = 0.2.0) +world imports { + @since(version = 0.2.0) + import instance-network; + @since(version = 0.2.0) + import network; + @since(version = 0.2.0) + import udp; + @since(version = 0.2.0) + import udp-create-socket; + @since(version = 0.2.0) + import tcp; + @since(version = 0.2.0) + import tcp-create-socket; + @since(version = 0.2.0) + import ip-name-lookup; +} From 26a96e3baabfd460ec48fd43bb6aebc693886a12 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 14 Jan 2025 15:06:32 +0100 Subject: [PATCH 1546/1772] refactor: replace `error-context` introspection by futures This seems to be better aligned with latest specification on error context https://github.com/WebAssembly/component-model/blob/cbdd15d9033446558571824af52a78022aaa3f58/design/mvp/Explainer.md#error-context-type > A consequence of this, however, is that components *must not* depend on the > contents of `error-context` values for behavioral correctness. In particular, > case analysis of the contents of an `error-context` should not determine > *error recovery*; explicit `result` or `variant` types must be used in the > function return type instead (e.g., > `(func (result (tuple (stream u8) (future $my-error)))`). Signed-off-by: Roman Volosatovs --- proposals/sockets/wit-0.3.0-draft/network.wit | 13 ---------- proposals/sockets/wit-0.3.0-draft/tcp.wit | 24 +++++++++++++------ 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/network.wit b/proposals/sockets/wit-0.3.0-draft/network.wit index c66efec0b..bbe138f12 100644 --- a/proposals/sockets/wit-0.3.0-draft/network.wit +++ b/proposals/sockets/wit-0.3.0-draft/network.wit @@ -92,19 +92,6 @@ interface network { permanent-resolver-failure, } - /// Attempts to extract a network-related `error-code` from the stream - /// `error` provided. - /// - /// Stream operations which return `stream-error::last-operation-failed` - /// have a payload with more information about the operation that failed. - /// This payload can be passed through to this function to see if there's - /// network-related information about the error to return. - /// - /// Note that this function is fallible because not all stream-related - /// errors are network-related errors. - @unstable(feature = network-error-code) - network-error-code: func(err: borrow) -> option; - @since(version = 0.2.0) enum ip-address-family { /// Similar to `AF_INET` in POSIX. diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index 23ab05d33..58fdd6b59 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -77,9 +77,13 @@ interface tcp { /// Connect to a remote endpoint. /// This function takes a stream as a parameter, which will be used for data transmission to the server. /// - /// On success: - /// - the socket is transitioned into the `connected` state. - /// - a stream is returned that can be used to read from the connection + /// On success, the socket is transitioned into the `connected` state and this function returns: + /// - Future, which will resolve to an optional error code if writing full contents of the stream to the connection fails. + /// The future resolves to `none` once full contents of the stream are transmitted successfully and the writing side of the + /// connection is closed. + /// - A stream that can be used to read from the connection + /// - Future, which will resolve to an optional error code if reading contents from the connection fails. + /// The future resolves to `none` once receiving side of the stream is closed. /// /// After a failed connection attempt, the socket will be in the `closed` /// state and the only valid action left is to `drop` the socket. A single @@ -106,7 +110,7 @@ interface tcp { /// - /// - @since(version = 0.3.0) - connect: func(network: borrow, remote-address: ip-socket-address, tx: stream) -> result, error-code>; + connect: func(network: borrow, remote-address: ip-socket-address, tx: stream) -> result>, stream, future>>, error-code>; /// Start listening for new connections. /// @@ -141,8 +145,14 @@ interface tcp { /// - `receive-buffer-size` /// - `send-buffer-size` /// - /// On success, this function returns the newly accepted client socket along with - /// a streams that can be used to read from the connection. + /// On success, this function returns: + /// - Future, which will resolve to an optional error code if writing full contents of the stream to the connection fails. + /// The future resolves to `none` once full contents of the stream are transmitted successfully and the writing side of the + /// connection is closed. + /// - Newly accepted client socket + /// - A stream that can be used to read from the connection + /// - Future, which will resolve to an optional error code if reading contents from the connection fails. + /// The future resolves to `none` once receiving side of the stream is closed. /// /// # Typical errors /// - `invalid-state`: Socket is not in the `listening` state. (EINVAL) @@ -155,7 +165,7 @@ interface tcp { /// - /// - @since(version = 0.3.0) - accept: func(tx: stream) -> result>, error-code>; + accept: func(tx: stream) -> result>, tcp-socket, stream, future>>, error-code>; /// Get the bound local address. /// From 11f3bd4ae1aa982f2093fa9b2b144ddcb464f7df Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 14 Jan 2025 16:24:58 +0100 Subject: [PATCH 1547/1772] chore: bump `@since` to `0.3.0` https://github.com/WebAssembly/wasi-filesystem/pull/164#discussion_r1914946117 Signed-off-by: Roman Volosatovs --- .../wit-0.3.0-draft/instance-network.wit | 6 +-- .../wit-0.3.0-draft/ip-name-lookup.wit | 10 ++-- proposals/sockets/wit-0.3.0-draft/network.wit | 20 ++++---- .../wit-0.3.0-draft/tcp-create-socket.wit | 8 +-- proposals/sockets/wit-0.3.0-draft/tcp.wit | 50 +++++++++---------- .../wit-0.3.0-draft/udp-create-socket.wit | 8 +-- proposals/sockets/wit-0.3.0-draft/udp.wit | 28 +++++------ proposals/sockets/wit-0.3.0-draft/world.wit | 16 +++--- 8 files changed, 73 insertions(+), 73 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/instance-network.wit b/proposals/sockets/wit-0.3.0-draft/instance-network.wit index 5f6e6c1cc..a9e54ef36 100644 --- a/proposals/sockets/wit-0.3.0-draft/instance-network.wit +++ b/proposals/sockets/wit-0.3.0-draft/instance-network.wit @@ -1,11 +1,11 @@ /// This interface provides a value-export of the default network handle.. -@since(version = 0.2.0) +@since(version = 0.3.0) interface instance-network { - @since(version = 0.2.0) + @since(version = 0.3.0) use network.{network}; /// Get a handle to the default network. - @since(version = 0.2.0) + @since(version = 0.3.0) instance-network: func() -> network; } diff --git a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit index dd26e6aa4..2be9bc079 100644 --- a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit +++ b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit @@ -1,6 +1,6 @@ -@since(version = 0.2.0) +@since(version = 0.3.0) interface ip-name-lookup { - @since(version = 0.2.0) + @since(version = 0.3.0) use network.{network, error-code, ip-address}; /// Resolve an internet host name to a list of IP addresses. @@ -23,10 +23,10 @@ interface ip-name-lookup { /// - /// - /// - - @since(version = 0.2.0) + @since(version = 0.3.0) resolve-addresses: func(network: borrow, name: string) -> result; - @since(version = 0.2.0) + @since(version = 0.3.0) resource resolve-address-stream { /// Returns the next address from the resolver. /// @@ -40,7 +40,7 @@ interface ip-name-lookup { /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) - @since(version = 0.2.0) + @since(version = 0.3.0) resolve-next-address: func() -> result, error-code>; } } diff --git a/proposals/sockets/wit-0.3.0-draft/network.wit b/proposals/sockets/wit-0.3.0-draft/network.wit index bbe138f12..21644ba7a 100644 --- a/proposals/sockets/wit-0.3.0-draft/network.wit +++ b/proposals/sockets/wit-0.3.0-draft/network.wit @@ -1,9 +1,9 @@ -@since(version = 0.2.0) +@since(version = 0.3.0) interface network { /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. - @since(version = 0.2.0) + @since(version = 0.3.0) resource network; /// Error codes. @@ -18,7 +18,7 @@ interface network { /// - `concurrency-conflict` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - @since(version = 0.2.0) + @since(version = 0.3.0) enum error-code { /// Unknown error unknown, @@ -92,7 +92,7 @@ interface network { permanent-resolver-failure, } - @since(version = 0.2.0) + @since(version = 0.3.0) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -101,18 +101,18 @@ interface network { ipv6, } - @since(version = 0.2.0) + @since(version = 0.3.0) type ipv4-address = tuple; - @since(version = 0.2.0) + @since(version = 0.3.0) type ipv6-address = tuple; - @since(version = 0.2.0) + @since(version = 0.3.0) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } - @since(version = 0.2.0) + @since(version = 0.3.0) record ipv4-socket-address { /// sin_port port: u16, @@ -120,7 +120,7 @@ interface network { address: ipv4-address, } - @since(version = 0.2.0) + @since(version = 0.3.0) record ipv6-socket-address { /// sin6_port port: u16, @@ -132,7 +132,7 @@ interface network { scope-id: u32, } - @since(version = 0.2.0) + @since(version = 0.3.0) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), diff --git a/proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit b/proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit index eedbd3076..3b6206296 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit @@ -1,8 +1,8 @@ -@since(version = 0.2.0) +@since(version = 0.3.0) interface tcp-create-socket { - @since(version = 0.2.0) + @since(version = 0.3.0) use network.{network, error-code, ip-address-family}; - @since(version = 0.2.0) + @since(version = 0.3.0) use tcp.{tcp-socket}; /// Create a new TCP socket. @@ -25,6 +25,6 @@ interface tcp-create-socket { /// - /// - /// - - @since(version = 0.2.0) + @since(version = 0.3.0) create-tcp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index 58fdd6b59..a6fd58e4b 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -1,11 +1,11 @@ -@since(version = 0.2.0) +@since(version = 0.3.0) interface tcp { - @since(version = 0.2.0) + @since(version = 0.3.0) use wasi:clocks/monotonic-clock@0.3.0.{duration}; - @since(version = 0.2.0) + @since(version = 0.3.0) use network.{network, error-code, ip-socket-address, ip-address-family}; - @since(version = 0.2.0) + @since(version = 0.3.0) enum shutdown-type { /// Similar to `SHUT_RD` in POSIX. receive, @@ -38,7 +38,7 @@ interface tcp { /// In addition to the general error codes documented on the /// `network::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. - @since(version = 0.2.0) + @since(version = 0.3.0) resource tcp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -183,7 +183,7 @@ interface tcp { /// - /// - /// - - @since(version = 0.2.0) + @since(version = 0.3.0) local-address: func() -> result; /// Get the remote address. @@ -196,19 +196,19 @@ interface tcp { /// - /// - /// - - @since(version = 0.2.0) + @since(version = 0.3.0) remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. - @since(version = 0.2.0) + @since(version = 0.3.0) is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.2.0) + @since(version = 0.3.0) address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. @@ -220,7 +220,7 @@ interface tcp { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. - @since(version = 0.2.0) + @since(version = 0.3.0) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -232,9 +232,9 @@ interface tcp { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. - @since(version = 0.2.0) + @since(version = 0.3.0) keep-alive-enabled: func() -> result; - @since(version = 0.2.0) + @since(version = 0.3.0) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. @@ -247,9 +247,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.2.0) + @since(version = 0.3.0) keep-alive-idle-time: func() -> result; - @since(version = 0.2.0) + @since(version = 0.3.0) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. @@ -262,9 +262,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.2.0) + @since(version = 0.3.0) keep-alive-interval: func() -> result; - @since(version = 0.2.0) + @since(version = 0.3.0) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. @@ -277,9 +277,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.2.0) + @since(version = 0.3.0) keep-alive-count: func() -> result; - @since(version = 0.2.0) + @since(version = 0.3.0) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -288,9 +288,9 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.2.0) + @since(version = 0.3.0) hop-limit: func() -> result; - @since(version = 0.2.0) + @since(version = 0.3.0) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -303,13 +303,13 @@ interface tcp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.2.0) + @since(version = 0.3.0) receive-buffer-size: func() -> result; - @since(version = 0.2.0) + @since(version = 0.3.0) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.2.0) + @since(version = 0.3.0) send-buffer-size: func() -> result; - @since(version = 0.2.0) + @since(version = 0.3.0) set-send-buffer-size: func(value: u64) -> result<_, error-code>; /// Initiate a graceful shutdown. @@ -335,7 +335,7 @@ interface tcp { /// - /// - /// - - @since(version = 0.2.0) + @since(version = 0.3.0) shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; } } diff --git a/proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit b/proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit index e8eeacbfe..339afee07 100644 --- a/proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit +++ b/proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit @@ -1,8 +1,8 @@ -@since(version = 0.2.0) +@since(version = 0.3.0) interface udp-create-socket { - @since(version = 0.2.0) + @since(version = 0.3.0) use network.{network, error-code, ip-address-family}; - @since(version = 0.2.0) + @since(version = 0.3.0) use udp.{udp-socket}; /// Create a new UDP socket. @@ -25,6 +25,6 @@ interface udp-create-socket { /// - /// - /// - - @since(version = 0.2.0) + @since(version = 0.3.0) create-udp-socket: func(address-family: ip-address-family) -> result; } diff --git a/proposals/sockets/wit-0.3.0-draft/udp.wit b/proposals/sockets/wit-0.3.0-draft/udp.wit index 0f9e1c2e2..f3d5f1a73 100644 --- a/proposals/sockets/wit-0.3.0-draft/udp.wit +++ b/proposals/sockets/wit-0.3.0-draft/udp.wit @@ -1,10 +1,10 @@ -@since(version = 0.2.0) +@since(version = 0.3.0) interface udp { - @since(version = 0.2.0) + @since(version = 0.3.0) use network.{network, error-code, ip-socket-address, ip-address-family}; /// A received datagram. - @since(version = 0.2.0) + @since(version = 0.3.0) record incoming-datagram { /// The payload. /// @@ -20,7 +20,7 @@ interface udp { } /// A datagram to be sent out. - @since(version = 0.2.0) + @since(version = 0.3.0) record outgoing-datagram { /// The payload. data: list, @@ -36,7 +36,7 @@ interface udp { } /// A UDP socket handle. - @since(version = 0.2.0) + @since(version = 0.3.0) resource udp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -153,7 +153,7 @@ interface udp { /// - /// - /// - - @since(version = 0.2.0) + @since(version = 0.3.0) local-address: func() -> result; /// Get the address the socket is currently streaming to. @@ -166,13 +166,13 @@ interface udp { /// - /// - /// - - @since(version = 0.2.0) + @since(version = 0.3.0) remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.2.0) + @since(version = 0.3.0) address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -181,9 +181,9 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.2.0) + @since(version = 0.3.0) unicast-hop-limit: func() -> result; - @since(version = 0.2.0) + @since(version = 0.3.0) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -196,13 +196,13 @@ interface udp { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.2.0) + @since(version = 0.3.0) receive-buffer-size: func() -> result; - @since(version = 0.2.0) + @since(version = 0.3.0) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.2.0) + @since(version = 0.3.0) send-buffer-size: func() -> result; - @since(version = 0.2.0) + @since(version = 0.3.0) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } } diff --git a/proposals/sockets/wit-0.3.0-draft/world.wit b/proposals/sockets/wit-0.3.0-draft/world.wit index e7ba6a1f7..61007bc4c 100644 --- a/proposals/sockets/wit-0.3.0-draft/world.wit +++ b/proposals/sockets/wit-0.3.0-draft/world.wit @@ -1,19 +1,19 @@ package wasi:sockets@0.3.0-draft; -@since(version = 0.2.0) +@since(version = 0.3.0) world imports { - @since(version = 0.2.0) + @since(version = 0.3.0) import instance-network; - @since(version = 0.2.0) + @since(version = 0.3.0) import network; - @since(version = 0.2.0) + @since(version = 0.3.0) import udp; - @since(version = 0.2.0) + @since(version = 0.3.0) import udp-create-socket; - @since(version = 0.2.0) + @since(version = 0.3.0) import tcp; - @since(version = 0.2.0) + @since(version = 0.3.0) import tcp-create-socket; - @since(version = 0.2.0) + @since(version = 0.3.0) import ip-name-lookup; } From 0d74de2bb2410c18407bada70c6113dd7da35c28 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 15 Jan 2025 12:12:55 +0100 Subject: [PATCH 1548/1772] feat(0.3): introduce `tcp-connection` Signed-off-by: Roman Volosatovs --- proposals/sockets/wit-0.3.0-draft/tcp.wit | 42 +++++++++++++---------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index a6fd58e4b..1733f1880 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -16,6 +16,26 @@ interface tcp { /// Similar to `SHUT_RDWR` in POSIX. both, } + + /// A TCP connection resource + /// + /// The connection is used to transmit and receive data. + resource tcp-connection { + /// Transmit data to peer. + /// + /// This function returns once full contents of the stream are transmitted + /// or an error is encoutered. + write: func(data: stream) -> result<_, error-code>; + + /// Read data from peer. + /// + /// This function fails if `read` was already called before on this connection. + /// + /// On sucess, this function returns a stream and a future, which will resolve + /// to an error code if receiving data from stream fails. + /// The returned future resolves to success if receiving side of the connection is closed. + read: func() -> result, future>>>; + } /// A TCP socket resource. /// @@ -77,13 +97,7 @@ interface tcp { /// Connect to a remote endpoint. /// This function takes a stream as a parameter, which will be used for data transmission to the server. /// - /// On success, the socket is transitioned into the `connected` state and this function returns: - /// - Future, which will resolve to an optional error code if writing full contents of the stream to the connection fails. - /// The future resolves to `none` once full contents of the stream are transmitted successfully and the writing side of the - /// connection is closed. - /// - A stream that can be used to read from the connection - /// - Future, which will resolve to an optional error code if reading contents from the connection fails. - /// The future resolves to `none` once receiving side of the stream is closed. + /// On success, the socket is transitioned into the `connected` state and this function returns a connection resource. /// /// After a failed connection attempt, the socket will be in the `closed` /// state and the only valid action left is to `drop` the socket. A single @@ -110,7 +124,7 @@ interface tcp { /// - /// - @since(version = 0.3.0) - connect: func(network: borrow, remote-address: ip-socket-address, tx: stream) -> result>, stream, future>>, error-code>; + connect: func(network: borrow, remote-address: ip-socket-address) -> result; /// Start listening for new connections. /// @@ -133,7 +147,6 @@ interface tcp { listen: func() -> result<_, error-code>; /// Accept a new client socket. - /// This function takes a stream as a parameter, which will be used for data transmission to the client. /// /// The returned socket is bound and in the `connected` state. The following properties are inherited from the listener socket: /// - `address-family` @@ -145,14 +158,7 @@ interface tcp { /// - `receive-buffer-size` /// - `send-buffer-size` /// - /// On success, this function returns: - /// - Future, which will resolve to an optional error code if writing full contents of the stream to the connection fails. - /// The future resolves to `none` once full contents of the stream are transmitted successfully and the writing side of the - /// connection is closed. - /// - Newly accepted client socket - /// - A stream that can be used to read from the connection - /// - Future, which will resolve to an optional error code if reading contents from the connection fails. - /// The future resolves to `none` once receiving side of the stream is closed. + /// On success, this function returns the newly accepted client socket and associated TCP connection. /// /// # Typical errors /// - `invalid-state`: Socket is not in the `listening` state. (EINVAL) @@ -165,7 +171,7 @@ interface tcp { /// - /// - @since(version = 0.3.0) - accept: func(tx: stream) -> result>, tcp-socket, stream, future>>, error-code>; + accept: func() -> result, error-code>; /// Get the bound local address. /// From 43cd03a83bbbaec3ffe703c3f7d560554a33a3c5 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 11:40:47 +0100 Subject: [PATCH 1549/1772] Add TcpSocketOperationalSemantics-0.3.0-draft.md --- ...pSocketOperationalSemantics-0.3.0-draft.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md diff --git a/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md b/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md new file mode 100644 index 000000000..6ff5689a1 --- /dev/null +++ b/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md @@ -0,0 +1,53 @@ +# Operational semantics of WASI TCP sockets + +WASI TCP sockets must behave [as-if](https://en.wikipedia.org/wiki/As-if_rule) they are implemented using the state machine described in this document. + +## States +> Note: These refer to the states of the TCP socket, not the [TCP connection](https://datatracker.ietf.org/doc/html/rfc9293#name-state-machine-overview) + +In pseudo code: + +```wit +interface tcp { + variant state { + unbound, + bound, + listening(accept-stream), + connecting(connect-future), + connected, + closed, + } +} +``` + +## Transitions +The following diagram describes the exhaustive set of all possible state transitions: + +```mermaid +stateDiagram-v2 + state "unbound" as Unbound + state "bound" as Bound + state "connecting" as Connecting + state "connected" as Connected + state "listening" as Listening + state "closed" as Closed + + + [*] --> Unbound: create-tcp-socket() -> ok + Unbound --> Bound: bind() -> ok + Unbound --> Connecting: connect() + + Connecting --> Connected: «task resolves successfully» + Connecting --> Closed: «task resolves with error» + + Connected --> Closed: «connection terminated» + + Bound --> Connecting: connect() + Bound --> Listening: listen() -> ok +``` + +- Transitions annotated with `-> ok` only apply when the method returns successfully. +- Calling a method from the wrong state returns `error(invalid-state)` and does not affect the state of the socket. +- This diagram only includes the methods that impact the socket's state. For an overview of all methods and their required states, see [tcp.wit](./wit/tcp.wit) +- Client sockets returned by `accept()` are in immediately in the `connected` state. +- A socket resource can be dropped in any state. From f3005e5598fdc7f151af22c21ed54037c00efede Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 12:04:30 +0100 Subject: [PATCH 1550/1772] Remove resolve-address-stream --- .../wit-0.3.0-draft/ip-name-lookup.wit | 31 +++++-------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit index 2be9bc079..f1dc5bfc7 100644 --- a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit +++ b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit @@ -11,12 +11,15 @@ interface ip-name-lookup { /// /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. /// - /// This function never blocks. It either immediately fails or immediately - /// returns successfully with a `resolve-address-stream` that can be used - /// to (asynchronously) fetch the results. + /// This function never succeeds with 0 results. It either fails succeeds + /// with at least one address. Additionally, this function never returns + /// IPv4-mapped IPv6 addresses. /// /// # Typical errors - /// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address. + /// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address. + /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) + /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) + /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) /// /// # References: /// - @@ -24,23 +27,5 @@ interface ip-name-lookup { /// - /// - @since(version = 0.3.0) - resolve-addresses: func(network: borrow, name: string) -> result; - - @since(version = 0.3.0) - resource resolve-address-stream { - /// Returns the next address from the resolver. - /// - /// This function should be called multiple times. On each call, it will - /// return the next address in connection order preference. If all - /// addresses have been exhausted, this function returns `none`. - /// - /// This function never returns IPv4-mapped IPv6 addresses. - /// - /// # Typical errors - /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) - /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) - /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) - @since(version = 0.3.0) - resolve-next-address: func() -> result, error-code>; - } + resolve-addresses: func(network: borrow, name: string) -> result, error-code>; } From 9fe4f64a5d8e4c3fb8713ef6fe7fbab373c17118 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 12:24:30 +0100 Subject: [PATCH 1551/1772] Split lookup errors off from the general socket errors type --- .../wit-0.3.0-draft/ip-name-lookup.wit | 10 ++------- proposals/sockets/wit-0.3.0-draft/network.wit | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit index f1dc5bfc7..7063ff923 100644 --- a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit +++ b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.3.0) interface ip-name-lookup { @since(version = 0.3.0) - use network.{network, error-code, ip-address}; + use network.{network, lookup-error, ip-address}; /// Resolve an internet host name to a list of IP addresses. /// @@ -15,17 +15,11 @@ interface ip-name-lookup { /// with at least one address. Additionally, this function never returns /// IPv4-mapped IPv6 addresses. /// - /// # Typical errors - /// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address. - /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) - /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) - /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) - /// /// # References: /// - /// - /// - /// - @since(version = 0.3.0) - resolve-addresses: func(network: borrow, name: string) -> result, error-code>; + resolve-addresses: func(network: borrow, name: string) -> result, lookup-error>; } diff --git a/proposals/sockets/wit-0.3.0-draft/network.wit b/proposals/sockets/wit-0.3.0-draft/network.wit index 21644ba7a..902ba3cea 100644 --- a/proposals/sockets/wit-0.3.0-draft/network.wit +++ b/proposals/sockets/wit-0.3.0-draft/network.wit @@ -80,15 +80,37 @@ interface network { /// The size of a datagram sent to a UDP socket exceeded the maximum /// supported size. datagram-too-large, + } + + /// Lookup error codes. + @since(version = 0.3.0) + enum lookup-error { + /// Unknown error + unknown, + + /// Access denied. + /// + /// POSIX equivalent: EACCES, EPERM + access-denied, + /// `name` is a syntactically invalid domain name or IP address. + /// + /// POSIX equivalent: EINVAL + invalid-argument, /// Name does not exist or has no suitable associated IP addresses. + /// + /// POSIX equivalent: EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY name-unresolvable, /// A temporary failure in name resolution occurred. + /// + /// POSIX equivalent: EAI_AGAIN temporary-resolver-failure, /// A permanent failure in name resolution occurred. + /// + /// POSIX equivalent: EAI_FAIL permanent-resolver-failure, } From fd6055d8839ebb78d1bc8118ed92aea0b9906c5f Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 12:40:45 +0100 Subject: [PATCH 1552/1772] Remove the runtime `network` capability and rely solely on link-time capability. --- .../sockets/wit-0.3.0-draft/instance-network.wit | 11 ----------- proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit | 4 ++-- proposals/sockets/wit-0.3.0-draft/network.wit | 6 ------ .../sockets/wit-0.3.0-draft/tcp-create-socket.wit | 6 +----- proposals/sockets/wit-0.3.0-draft/tcp.wit | 11 +++++------ .../sockets/wit-0.3.0-draft/udp-create-socket.wit | 6 +----- proposals/sockets/wit-0.3.0-draft/udp.wit | 8 ++++---- proposals/sockets/wit-0.3.0-draft/world.wit | 2 -- 8 files changed, 13 insertions(+), 41 deletions(-) delete mode 100644 proposals/sockets/wit-0.3.0-draft/instance-network.wit diff --git a/proposals/sockets/wit-0.3.0-draft/instance-network.wit b/proposals/sockets/wit-0.3.0-draft/instance-network.wit deleted file mode 100644 index a9e54ef36..000000000 --- a/proposals/sockets/wit-0.3.0-draft/instance-network.wit +++ /dev/null @@ -1,11 +0,0 @@ - -/// This interface provides a value-export of the default network handle.. -@since(version = 0.3.0) -interface instance-network { - @since(version = 0.3.0) - use network.{network}; - - /// Get a handle to the default network. - @since(version = 0.3.0) - instance-network: func() -> network; -} diff --git a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit index 7063ff923..58a102d80 100644 --- a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit +++ b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.3.0) interface ip-name-lookup { @since(version = 0.3.0) - use network.{network, lookup-error, ip-address}; + use network.{lookup-error, ip-address}; /// Resolve an internet host name to a list of IP addresses. /// @@ -21,5 +21,5 @@ interface ip-name-lookup { /// - /// - @since(version = 0.3.0) - resolve-addresses: func(network: borrow, name: string) -> result, lookup-error>; + resolve-addresses: func(name: string) -> result, lookup-error>; } diff --git a/proposals/sockets/wit-0.3.0-draft/network.wit b/proposals/sockets/wit-0.3.0-draft/network.wit index 902ba3cea..8b93ac499 100644 --- a/proposals/sockets/wit-0.3.0-draft/network.wit +++ b/proposals/sockets/wit-0.3.0-draft/network.wit @@ -1,11 +1,5 @@ @since(version = 0.3.0) interface network { - /// An opaque resource that represents access to (a subset of) the network. - /// This enables context-based security for networking. - /// There is no need for this to map 1:1 to a physical network interface. - @since(version = 0.3.0) - resource network; - /// Error codes. /// /// In theory, every API can return any error code. diff --git a/proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit b/proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit index 3b6206296..d9c94fc4b 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit @@ -1,7 +1,7 @@ @since(version = 0.3.0) interface tcp-create-socket { @since(version = 0.3.0) - use network.{network, error-code, ip-address-family}; + use network.{error-code, ip-address-family}; @since(version = 0.3.0) use tcp.{tcp-socket}; @@ -10,10 +10,6 @@ interface tcp-create-socket { /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. /// - /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` - /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. /// /// # Typical errors diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index 1733f1880..573e95dc8 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -3,7 +3,7 @@ interface tcp { @since(version = 0.3.0) use wasi:clocks/monotonic-clock@0.3.0.{duration}; @since(version = 0.3.0) - use network.{network, error-code, ip-socket-address, ip-address-family}; + use network.{error-code, ip-socket-address, ip-address-family}; @since(version = 0.3.0) enum shutdown-type { @@ -60,7 +60,7 @@ interface tcp { /// `error(invalid-state)` when in the `closed` state. @since(version = 0.3.0) resource tcp-socket { - /// Bind the socket to a specific network on the provided IP address and port. + /// Bind the socket to the provided IP address and port. /// /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which /// network interface(s) to bind to. @@ -78,7 +78,7 @@ interface tcp { /// - `invalid-state`: The socket is already bound. (EINVAL) /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `address-not-bindable`: `local-address` is not an address that can be bound to. (EADDRNOTAVAIL) /// /// # Implementors note /// When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT @@ -92,7 +92,7 @@ interface tcp { /// - /// - @since(version = 0.3.0) - bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Connect to a remote endpoint. /// This function takes a stream as a parameter, which will be used for data transmission to the server. @@ -109,7 +109,6 @@ interface tcp { /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) - /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) /// - `timeout`: Connection timed out. (ETIMEDOUT) @@ -124,7 +123,7 @@ interface tcp { /// - /// - @since(version = 0.3.0) - connect: func(network: borrow, remote-address: ip-socket-address) -> result; + connect: func(remote-address: ip-socket-address) -> result; /// Start listening for new connections. /// diff --git a/proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit b/proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit index 339afee07..0fdd4d349 100644 --- a/proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit +++ b/proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit @@ -1,7 +1,7 @@ @since(version = 0.3.0) interface udp-create-socket { @since(version = 0.3.0) - use network.{network, error-code, ip-address-family}; + use network.{error-code, ip-address-family}; @since(version = 0.3.0) use udp.{udp-socket}; @@ -10,10 +10,6 @@ interface udp-create-socket { /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. /// - /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind` is called, - /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. /// /// # Typical errors diff --git a/proposals/sockets/wit-0.3.0-draft/udp.wit b/proposals/sockets/wit-0.3.0-draft/udp.wit index f3d5f1a73..d557c6d7e 100644 --- a/proposals/sockets/wit-0.3.0-draft/udp.wit +++ b/proposals/sockets/wit-0.3.0-draft/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.3.0) interface udp { @since(version = 0.3.0) - use network.{network, error-code, ip-socket-address, ip-address-family}; + use network.{error-code, ip-socket-address, ip-address-family}; /// A received datagram. @since(version = 0.3.0) @@ -38,7 +38,7 @@ interface udp { /// A UDP socket handle. @since(version = 0.3.0) resource udp-socket { - /// Bind the socket to a specific network on the provided IP address and port. + /// Bind the socket to the provided IP address and port. /// /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which /// network interface(s) to bind to. @@ -49,7 +49,7 @@ interface udp { /// - `invalid-state`: The socket is already bound. (EINVAL) /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) + /// - `address-not-bindable`: `local-address` is not an address that can be bound to. (EADDRNOTAVAIL) /// /// # References /// - @@ -57,7 +57,7 @@ interface udp { /// - /// - @since(version = 0.3.0) - bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; + bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Set up inbound & outbound communication channels, optionally to a specific peer. /// diff --git a/proposals/sockets/wit-0.3.0-draft/world.wit b/proposals/sockets/wit-0.3.0-draft/world.wit index 61007bc4c..352af8e08 100644 --- a/proposals/sockets/wit-0.3.0-draft/world.wit +++ b/proposals/sockets/wit-0.3.0-draft/world.wit @@ -2,8 +2,6 @@ package wasi:sockets@0.3.0-draft; @since(version = 0.3.0) world imports { - @since(version = 0.3.0) - import instance-network; @since(version = 0.3.0) import network; @since(version = 0.3.0) From 93643830f5cff149390b6624b0872286a340c3a8 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 12:49:17 +0100 Subject: [PATCH 1553/1772] Remove `create-tcp/udp-socket` methods & interfaces in favor of plain `constructor`s --- proposals/sockets/wit-0.3.0-draft/network.wit | 3 --- .../wit-0.3.0-draft/tcp-create-socket.wit | 26 ------------------- proposals/sockets/wit-0.3.0-draft/tcp.wit | 16 ++++++++++++ .../wit-0.3.0-draft/udp-create-socket.wit | 26 ------------------- proposals/sockets/wit-0.3.0-draft/udp.wit | 16 ++++++++++++ proposals/sockets/wit-0.3.0-draft/world.wit | 4 --- 6 files changed, 32 insertions(+), 59 deletions(-) delete mode 100644 proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit delete mode 100644 proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit diff --git a/proposals/sockets/wit-0.3.0-draft/network.wit b/proposals/sockets/wit-0.3.0-draft/network.wit index 8b93ac499..aa4aa8e78 100644 --- a/proposals/sockets/wit-0.3.0-draft/network.wit +++ b/proposals/sockets/wit-0.3.0-draft/network.wit @@ -48,9 +48,6 @@ interface network { /// The operation is not valid in the socket's current state. invalid-state, - /// A new socket resource could not be created because of a system limit. - new-socket-limit, - /// A bind operation failed because the provided address is not an address that the `network` can bind to. address-not-bindable, diff --git a/proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit b/proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit deleted file mode 100644 index d9c94fc4b..000000000 --- a/proposals/sockets/wit-0.3.0-draft/tcp-create-socket.wit +++ /dev/null @@ -1,26 +0,0 @@ -@since(version = 0.3.0) -interface tcp-create-socket { - @since(version = 0.3.0) - use network.{error-code, ip-address-family}; - @since(version = 0.3.0) - use tcp.{tcp-socket}; - - /// Create a new TCP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. - /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. - /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// - /// # Typical errors - /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - create-tcp-socket: func(address-family: ip-address-family) -> result; -} diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index 573e95dc8..9d0d9322f 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -60,6 +60,22 @@ interface tcp { /// `error(invalid-state)` when in the `closed` state. @since(version = 0.3.0) resource tcp-socket { + + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. + /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + constructor(address-family: ip-address-family); + /// Bind the socket to the provided IP address and port. /// /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which diff --git a/proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit b/proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit deleted file mode 100644 index 0fdd4d349..000000000 --- a/proposals/sockets/wit-0.3.0-draft/udp-create-socket.wit +++ /dev/null @@ -1,26 +0,0 @@ -@since(version = 0.3.0) -interface udp-create-socket { - @since(version = 0.3.0) - use network.{error-code, ip-address-family}; - @since(version = 0.3.0) - use udp.{udp-socket}; - - /// Create a new UDP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. - /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. - /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// - /// # Typical errors - /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References: - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - create-udp-socket: func(address-family: ip-address-family) -> result; -} diff --git a/proposals/sockets/wit-0.3.0-draft/udp.wit b/proposals/sockets/wit-0.3.0-draft/udp.wit index d557c6d7e..0a86ad998 100644 --- a/proposals/sockets/wit-0.3.0-draft/udp.wit +++ b/proposals/sockets/wit-0.3.0-draft/udp.wit @@ -38,6 +38,22 @@ interface udp { /// A UDP socket handle. @since(version = 0.3.0) resource udp-socket { + + /// Create a new UDP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. + /// + /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// + /// # References: + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + constructor(address-family: ip-address-family); + /// Bind the socket to the provided IP address and port. /// /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which diff --git a/proposals/sockets/wit-0.3.0-draft/world.wit b/proposals/sockets/wit-0.3.0-draft/world.wit index 352af8e08..b9b7461e4 100644 --- a/proposals/sockets/wit-0.3.0-draft/world.wit +++ b/proposals/sockets/wit-0.3.0-draft/world.wit @@ -7,11 +7,7 @@ world imports { @since(version = 0.3.0) import udp; @since(version = 0.3.0) - import udp-create-socket; - @since(version = 0.3.0) import tcp; @since(version = 0.3.0) - import tcp-create-socket; - @since(version = 0.3.0) import ip-name-lookup; } From b230088f30465503d6f9c882b5ffa56277a3261e Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 12:52:47 +0100 Subject: [PATCH 1554/1772] Rename `write` -> `send`, `read` -> `receive` --- proposals/sockets/wit-0.3.0-draft/tcp.wit | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index 9d0d9322f..6feab00de 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -24,8 +24,8 @@ interface tcp { /// Transmit data to peer. /// /// This function returns once full contents of the stream are transmitted - /// or an error is encoutered. - write: func(data: stream) -> result<_, error-code>; + /// or an error is encountered. + send: func(data: stream) -> result<_, error-code>; /// Read data from peer. /// @@ -34,7 +34,7 @@ interface tcp { /// On sucess, this function returns a stream and a future, which will resolve /// to an error code if receiving data from stream fails. /// The returned future resolves to success if receiving side of the connection is closed. - read: func() -> result, future>>>; + receive: func() -> result, future>>>; } /// A TCP socket resource. From bf66a1e0993bf4a926fd6230a724e913bc99c6da Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 13:06:15 +0100 Subject: [PATCH 1555/1772] Remove the TCP `shutdown` method. It is redundant now that we have proper streams with cancellation. --- proposals/sockets/wit-0.3.0-draft/tcp.wit | 52 ++++++----------------- 1 file changed, 12 insertions(+), 40 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index 6feab00de..24bd96a22 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -5,26 +5,19 @@ interface tcp { @since(version = 0.3.0) use network.{error-code, ip-socket-address, ip-address-family}; - @since(version = 0.3.0) - enum shutdown-type { - /// Similar to `SHUT_RD` in POSIX. - receive, - - /// Similar to `SHUT_WR` in POSIX. - send, - - /// Similar to `SHUT_RDWR` in POSIX. - both, - } - /// A TCP connection resource /// /// The connection is used to transmit and receive data. resource tcp-connection { /// Transmit data to peer. /// - /// This function returns once full contents of the stream are transmitted - /// or an error is encountered. + /// The caller should close the stream when it has no more data to send + /// to the peer. Under normal circumstances this will cause a FIN packet + /// to be sent. Closing the stream is equivalent to calling + /// `shutdown(SHUT_WR)` in POSIX. + /// + /// This function may be called at most once and returns once the full + /// contents of the stream are transmitted or an error is encountered. send: func(data: stream) -> result<_, error-code>; /// Read data from peer. @@ -34,6 +27,11 @@ interface tcp { /// On sucess, this function returns a stream and a future, which will resolve /// to an error code if receiving data from stream fails. /// The returned future resolves to success if receiving side of the connection is closed. + /// + /// If the caller is not expecting to receive any data from the peer, + /// they may cancel the receive task. Any data still in the receive queue + /// will be discarded. This is equivalent to calling `shutdown(SHUT_RD)` + /// in POSIX. receive: func() -> result, future>>>; } @@ -332,31 +330,5 @@ interface tcp { send-buffer-size: func() -> result; @since(version = 0.3.0) set-send-buffer-size: func(value: u64) -> result<_, error-code>; - - /// Initiate a graceful shutdown. - /// - /// - `receive`: The socket is not expecting to receive any data from - /// the peer. The `input-stream` associated with this socket will be - /// closed. Any data still in the receive queue at time of calling - /// this method will be discarded. - /// - `send`: The socket has no more data to send to the peer. The `output-stream` - /// associated with this socket will be closed and a FIN packet will be sent. - /// - `both`: Same effect as `receive` & `send` combined. - /// - /// This function is idempotent; shutting down a direction more than once - /// has no effect and returns `ok`. - /// - /// The shutdown function does not close (drop) the socket. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; } } From 8ef53594f6a178aa7360e81ddd8be7ba80ea1043 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 14:04:11 +0100 Subject: [PATCH 1556/1772] Now that binding a socket doesn't require a runtime network handle anymore, `listen` is free to do an implicit bind again. Just like POSIX. --- .../sockets/TcpSocketOperationalSemantics-0.3.0-draft.md | 1 + proposals/sockets/wit-0.3.0-draft/tcp.wit | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md b/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md index 6ff5689a1..d5db7d97b 100644 --- a/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md +++ b/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md @@ -44,6 +44,7 @@ stateDiagram-v2 Bound --> Connecting: connect() Bound --> Listening: listen() -> ok + Unbound --> Listening: listen() -> ok ``` - Transitions annotated with `-> ok` only apply when the method returns successfully. diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index 24bd96a22..1c4d90214 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -143,10 +143,10 @@ interface tcp { /// /// Transitions the socket into the `listening` state. /// - /// Unlike POSIX, the socket must already be explicitly bound. + /// If the socket is not already explicitly bound, this function will + /// implicitly bind the socket to a random free port. /// /// # Typical errors - /// - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ) /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) /// - `invalid-state`: The socket is already in the `listening` state. /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) From 5c0ac2bb54f9f85712d85236c504f4497da93052 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 14:15:42 +0100 Subject: [PATCH 1557/1772] Merge `listen` & `accept` into a single method that returns a stream of client sockets. --- ...pSocketOperationalSemantics-0.3.0-draft.md | 2 +- proposals/sockets/wit-0.3.0-draft/tcp.wit | 34 ++++++------------- 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md b/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md index d5db7d97b..364016381 100644 --- a/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md +++ b/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md @@ -50,5 +50,5 @@ stateDiagram-v2 - Transitions annotated with `-> ok` only apply when the method returns successfully. - Calling a method from the wrong state returns `error(invalid-state)` and does not affect the state of the socket. - This diagram only includes the methods that impact the socket's state. For an overview of all methods and their required states, see [tcp.wit](./wit/tcp.wit) -- Client sockets returned by `accept()` are in immediately in the `connected` state. +- Client sockets returned by `listen()` are in immediately in the `connected` state. - A socket resource can be dropped in any state. diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index 1c4d90214..2d4788b87 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -139,29 +139,15 @@ interface tcp { @since(version = 0.3.0) connect: func(remote-address: ip-socket-address) -> result; - /// Start listening for new connections. + /// Start listening return a stream of new inbound connections. /// /// Transitions the socket into the `listening` state. /// /// If the socket is not already explicitly bound, this function will /// implicitly bind the socket to a random free port. /// - /// # Typical errors - /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) - /// - `invalid-state`: The socket is already in the `listening` state. - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - listen: func() -> result<_, error-code>; - - /// Accept a new client socket. - /// - /// The returned socket is bound and in the `connected` state. The following properties are inherited from the listener socket: + /// The returned sockets are bound and in the `connected` state. + /// The following properties are inherited from the listener socket: /// - `address-family` /// - `keep-alive-enabled` /// - `keep-alive-idle-time` @@ -171,20 +157,22 @@ interface tcp { /// - `receive-buffer-size` /// - `send-buffer-size` /// - /// On success, this function returns the newly accepted client socket and associated TCP connection. - /// /// # Typical errors - /// - `invalid-state`: Socket is not in the `listening` state. (EINVAL) - /// - `connection-aborted`: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) + /// - `invalid-state`: The socket is already in the `listening` state. + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) /// /// # References + /// - /// - + /// - /// - + /// - /// - + /// - /// - @since(version = 0.3.0) - accept: func() -> result, error-code>; + listen: func() -> result>, error-code>; /// Get the bound local address. /// From c0cd3a944df2ccd6a278dc3fa3bffb1b4e383c7b Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 14:21:30 +0100 Subject: [PATCH 1558/1772] Update state names --- proposals/sockets/wit-0.3.0-draft/tcp.wit | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index 2d4788b87..d9b1348aa 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -39,11 +39,9 @@ interface tcp { /// /// The socket can be in one of the following states: /// - `unbound` - /// - `bind-in-progress` /// - `bound` (See note below) - /// - `listen-in-progress` /// - `listening` - /// - `connect-in-progress` + /// - `connecting` /// - `connected` /// - `closed` /// See @@ -51,7 +49,7 @@ interface tcp { /// /// Note: Except where explicitly mentioned, whenever this documentation uses /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. - /// (i.e. `bound`, `listen-in-progress`, `listening`, `connect-in-progress` or `connected`) + /// (i.e. `bound`, `listening`, `connecting` or `connected`) /// /// In addition to the general error codes documented on the /// `network::error-code` type, TCP socket methods may always return @@ -226,7 +224,7 @@ interface tcp { /// # Typical errors /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. - /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. + /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. @since(version = 0.3.0) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; From 4ef6cb70f3f5c635c422ed208c83e8f4557dc75e Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 14:29:23 +0100 Subject: [PATCH 1559/1772] Clarify EALREADY equivalence --- proposals/sockets/wit-0.3.0-draft/tcp.wit | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index d9b1348aa..b1e3ae62d 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -121,6 +121,7 @@ interface tcp { /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `invalid-state`: The socket is already in the `connecting` state. (EALREADY) /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) /// - `timeout`: Connection timed out. (ETIMEDOUT) From 3c162c0a59fbc3347769233bcb94f96e8e2d8e1c Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 14:41:28 +0100 Subject: [PATCH 1560/1772] Remove superfluous `concurrency-conflict` error code. `invalid-state` already covers all its use-cases. Was an oversight in v0.2 --- proposals/sockets/wit-0.3.0-draft/network.wit | 6 ------ 1 file changed, 6 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/network.wit b/proposals/sockets/wit-0.3.0-draft/network.wit index aa4aa8e78..81b923f6d 100644 --- a/proposals/sockets/wit-0.3.0-draft/network.wit +++ b/proposals/sockets/wit-0.3.0-draft/network.wit @@ -9,7 +9,6 @@ interface network { /// - `access-denied` /// - `not-supported` /// - `out-of-memory` - /// - `concurrency-conflict` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. @since(version = 0.3.0) @@ -40,11 +39,6 @@ interface network { /// The operation timed out before it could finish completely. timeout, - /// This operation is incompatible with another asynchronous operation that is already in progress. - /// - /// POSIX equivalent: EALREADY - concurrency-conflict, - /// The operation is not valid in the socket's current state. invalid-state, From 3916265c19f72dfa48beb9e442b7f8a50483e6aa Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 14:48:40 +0100 Subject: [PATCH 1561/1772] Add Since annotations to tcp-connection --- proposals/sockets/wit-0.3.0-draft/tcp.wit | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index b1e3ae62d..28f771bbd 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -8,6 +8,7 @@ interface tcp { /// A TCP connection resource /// /// The connection is used to transmit and receive data. + @since(version = 0.3.0) resource tcp-connection { /// Transmit data to peer. /// @@ -18,6 +19,7 @@ interface tcp { /// /// This function may be called at most once and returns once the full /// contents of the stream are transmitted or an error is encountered. + @since(version = 0.3.0) send: func(data: stream) -> result<_, error-code>; /// Read data from peer. @@ -32,6 +34,7 @@ interface tcp { /// they may cancel the receive task. Any data still in the receive queue /// will be discarded. This is equivalent to calling `shutdown(SHUT_RD)` /// in POSIX. + @since(version = 0.3.0) receive: func() -> result, future>>>; } From bb4ecd13256de690cd607f4ffd117c3dba9593a0 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 15:06:21 +0100 Subject: [PATCH 1562/1772] Remove last references to wasi:io --- proposals/sockets/wit-0.3.0-draft/tcp.wit | 4 +++- proposals/sockets/wit-0.3.0-draft/udp.wit | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index 28f771bbd..e9ffdd0b6 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -65,7 +65,9 @@ interface tcp { /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// Unlike POSIX, WASI sockets have no notion of a socket-level + /// `O_NONBLOCK` flag. Instead they fully rely on the Component Model's + /// async support. /// /// # References /// - diff --git a/proposals/sockets/wit-0.3.0-draft/udp.wit b/proposals/sockets/wit-0.3.0-draft/udp.wit index 0a86ad998..8e46b7ec9 100644 --- a/proposals/sockets/wit-0.3.0-draft/udp.wit +++ b/proposals/sockets/wit-0.3.0-draft/udp.wit @@ -44,7 +44,9 @@ interface udp { /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. + /// Unlike POSIX, WASI sockets have no notion of a socket-level + /// `O_NONBLOCK` flag. Instead they fully rely on the Component Model's + /// async support. /// /// # References: /// - From c29cb310457245f9f16d17afa4dfbe883f355cc8 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 15:07:07 +0100 Subject: [PATCH 1563/1772] Remove outdated doc now that we have tcp-connection. --- proposals/sockets/wit-0.3.0-draft/tcp.wit | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index e9ffdd0b6..210949873 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -112,7 +112,6 @@ interface tcp { bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Connect to a remote endpoint. - /// This function takes a stream as a parameter, which will be used for data transmission to the server. /// /// On success, the socket is transitioned into the `connected` state and this function returns a connection resource. /// From 86fb0a06a066ab2aec476f240839413c72afbb5a Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 15:28:53 +0100 Subject: [PATCH 1564/1772] Now that binding a socket doesn't require a runtime network handle anymore, `stream` is free to do an implicit bind again. Just like POSIX. --- proposals/sockets/wit-0.3.0-draft/udp.wit | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/udp.wit b/proposals/sockets/wit-0.3.0-draft/udp.wit index 8e46b7ec9..97c94e277 100644 --- a/proposals/sockets/wit-0.3.0-draft/udp.wit +++ b/proposals/sockets/wit-0.3.0-draft/udp.wit @@ -79,9 +79,12 @@ interface udp { /// Set up inbound & outbound communication channels, optionally to a specific peer. /// - /// This function only changes the local socket configuration and does not generate any network traffic. - /// On success, the `remote-address` of the socket is updated. The `local-address` may be updated as well, - /// based on the best network path to `remote-address`. + /// This function only changes the local socket configuration and does + /// not generate any network traffic. On success, the `remote-address` + /// of the socket is updated. The `local-address` may be updated as well, + /// based on the best network path to `remote-address`. If the socket was + /// not already explicitly bound, this function will implicitly bind the + /// socket to a random free port. /// /// When a `remote-address` is provided, the returned streams are limited to communicating with that specific peer: /// - `send` can only be used to send to this destination. @@ -100,14 +103,11 @@ interface udp { /// connect(s, remote_address) /// } /// ``` - /// - /// Unlike in POSIX, the socket must already be explicitly bound. /// /// # Typical errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-state`: The socket is not bound. /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) /// - `connection-refused`: The connection was refused. (ECONNREFUSED) From c7f8226e1691846488123253f3ac0df69ae3fdf2 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Thu, 16 Jan 2025 15:48:12 +0100 Subject: [PATCH 1565/1772] feat(0.3): asyncify `resolve-address-stream` Signed-off-by: Roman Volosatovs --- .../wit-0.3.0-draft/ip-name-lookup.wit | 35 +++++++------------ 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit index 2be9bc079..73f5ec913 100644 --- a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit +++ b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit @@ -11,12 +11,19 @@ interface ip-name-lookup { /// /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. /// - /// This function never blocks. It either immediately fails or immediately - /// returns successfully with a `resolve-address-stream` that can be used - /// to (asynchronously) fetch the results. + /// This function returns a stream that can be used + /// to (asynchronously) fetch the resolved IP addresses. + /// Addresses are fetched in connection order preference. + /// This stream will never contain IPv4-mapped IPv6 addresses. + /// + /// The returned future will resolve to an error code in case of failure. + /// It will resolve to success once the returned stream is exhausted. /// /// # Typical errors - /// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address. + /// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address. + /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) + /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) + /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) /// /// # References: /// - @@ -24,23 +31,5 @@ interface ip-name-lookup { /// - /// - @since(version = 0.3.0) - resolve-addresses: func(network: borrow, name: string) -> result; - - @since(version = 0.3.0) - resource resolve-address-stream { - /// Returns the next address from the resolver. - /// - /// This function should be called multiple times. On each call, it will - /// return the next address in connection order preference. If all - /// addresses have been exhausted, this function returns `none`. - /// - /// This function never returns IPv4-mapped IPv6 addresses. - /// - /// # Typical errors - /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) - /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) - /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) - @since(version = 0.3.0) - resolve-next-address: func() -> result, error-code>; - } + resolve-addresses: func(network: borrow, name: string) -> tuple, future>>; } From 767490ea52ef97f6db7fadedfe0a9c9f43ce941a Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 16:19:09 +0100 Subject: [PATCH 1566/1772] Merge UDP `send` into `%stream` --- proposals/sockets/wit-0.3.0-draft/udp.wit | 64 +++++++++-------------- 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/udp.wit b/proposals/sockets/wit-0.3.0-draft/udp.wit index 97c94e277..ade7d3f12 100644 --- a/proposals/sockets/wit-0.3.0-draft/udp.wit +++ b/proposals/sockets/wit-0.3.0-draft/udp.wit @@ -79,6 +79,9 @@ interface udp { /// Set up inbound & outbound communication channels, optionally to a specific peer. /// + /// The `datagrams` stream parameter represents the data to be sent out. + /// The returned stream represents the data that was received. + /// /// This function only changes the local socket configuration and does /// not generate any network traffic. On success, the `remote-address` /// of the socket is updated. The `local-address` may be updated as well, @@ -86,13 +89,15 @@ interface udp { /// not already explicitly bound, this function will implicitly bind the /// socket to a random free port. /// - /// When a `remote-address` is provided, the returned streams are limited to communicating with that specific peer: - /// - `send` can only be used to send to this destination. - /// - `receive` will only return datagrams sent from the provided `remote-address`. - /// - /// This method may be called multiple times on the same socket to change its association, but - /// only the most recently returned pair of streams will be operational. Implementations may trap if - /// the streams returned by a previous invocation haven't been dropped yet before calling `stream` again. + /// When a `remote-address` is provided, the streams are limited to + /// communicating with that specific peer: + /// - The `outgoing-datagram` stream can only be used to send to this destination. + /// - The `incoming-datagram` stream will only return datagrams sent from the provided `remote-address`. + /// + /// This method may be called multiple times on the same socket to change + /// its association, but only the most recent pair of streams will be + /// operational. Calling this function more than once effectively cancels + /// any previously started `%stream` tasks. /// /// The POSIX equivalent in pseudo-code is: /// ```text @@ -109,51 +114,30 @@ interface udp { /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `connection-refused`: The connection was refused. (ECONNREFUSED) /// /// # References /// - - /// - - /// - - /// - - @since(version = 0.3.0) - %stream: func(remote-address: option) -> result, error-code>; - - /// Send messages on the socket. - /// - /// This function attempts to send all provided `datagrams` on the socket without blocking and - /// returns how many messages were actually sent (or queued for sending). - /// If none of the datagrams were able to be sent, `ok(0)` is returned. - /// - /// This function semantically behaves the same as iterating the `datagrams` list and sequentially - /// sending each individual datagram until either the end of the list has been reached or the first error occurred. - /// If at least one datagram has been sent successfully, this function never returns an error. - /// - /// If the input list is empty, the function returns `ok(0)`. - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `stream`. (EISCONN) - /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `connection-refused`: The connection was refused. (ECONNREFUSED) - /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) - /// - /// # References /// - /// - + /// - + /// - + /// - /// - /// - + /// - + /// - + /// - /// - /// - /// - + /// - + /// - + /// - + /// - /// - + /// - @since(version = 0.3.0) - send: func(datagrams: list) -> result; - + %stream: func(datagrams: list, remote-address: option) -> result, error-code>; /// Get the current bound address. /// From 21575e08de653ac02c2c31be461900451799c439 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 16:24:06 +0100 Subject: [PATCH 1567/1772] Rename `%stream` to `transfer`. The `%stream` name was already suboptimal, but now that streams are actually a thing, it was even more akward. --- proposals/sockets/wit-0.3.0-draft/udp.wit | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/udp.wit b/proposals/sockets/wit-0.3.0-draft/udp.wit index ade7d3f12..819eecc37 100644 --- a/proposals/sockets/wit-0.3.0-draft/udp.wit +++ b/proposals/sockets/wit-0.3.0-draft/udp.wit @@ -97,7 +97,7 @@ interface udp { /// This method may be called multiple times on the same socket to change /// its association, but only the most recent pair of streams will be /// operational. Calling this function more than once effectively cancels - /// any previously started `%stream` tasks. + /// any previously started `transfer` tasks. /// /// The POSIX equivalent in pseudo-code is: /// ```text @@ -137,7 +137,7 @@ interface udp { /// - /// - @since(version = 0.3.0) - %stream: func(datagrams: list, remote-address: option) -> result, error-code>; + transfer: func(datagrams: list, remote-address: option) -> result, error-code>; /// Get the current bound address. /// From 1d7858a8cc7d443814c13ee5463f043ec77b186d Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 16:46:06 +0100 Subject: [PATCH 1568/1772] Rename `network.wit` to `types.wit` to match other proposals --- proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit | 2 +- proposals/sockets/wit-0.3.0-draft/tcp.wit | 4 ++-- proposals/sockets/wit-0.3.0-draft/{network.wit => types.wit} | 2 +- proposals/sockets/wit-0.3.0-draft/udp.wit | 2 +- proposals/sockets/wit-0.3.0-draft/world.wit | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) rename proposals/sockets/wit-0.3.0-draft/{network.wit => types.wit} (99%) diff --git a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit index 6391a8cc1..c8c6b3f20 100644 --- a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit +++ b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.3.0) interface ip-name-lookup { @since(version = 0.3.0) - use network.{lookup-error, ip-address}; + use types.{lookup-error, ip-address}; /// Resolve an internet host name to a list of IP addresses. /// diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit index 210949873..7deecb533 100644 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ b/proposals/sockets/wit-0.3.0-draft/tcp.wit @@ -3,7 +3,7 @@ interface tcp { @since(version = 0.3.0) use wasi:clocks/monotonic-clock@0.3.0.{duration}; @since(version = 0.3.0) - use network.{error-code, ip-socket-address, ip-address-family}; + use types.{error-code, ip-socket-address, ip-address-family}; /// A TCP connection resource /// @@ -55,7 +55,7 @@ interface tcp { /// (i.e. `bound`, `listening`, `connecting` or `connected`) /// /// In addition to the general error codes documented on the - /// `network::error-code` type, TCP socket methods may always return + /// `types::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. @since(version = 0.3.0) resource tcp-socket { diff --git a/proposals/sockets/wit-0.3.0-draft/network.wit b/proposals/sockets/wit-0.3.0-draft/types.wit similarity index 99% rename from proposals/sockets/wit-0.3.0-draft/network.wit rename to proposals/sockets/wit-0.3.0-draft/types.wit index 81b923f6d..dae70962a 100644 --- a/proposals/sockets/wit-0.3.0-draft/network.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -1,5 +1,5 @@ @since(version = 0.3.0) -interface network { +interface types { /// Error codes. /// /// In theory, every API can return any error code. diff --git a/proposals/sockets/wit-0.3.0-draft/udp.wit b/proposals/sockets/wit-0.3.0-draft/udp.wit index 819eecc37..4dd76fe49 100644 --- a/proposals/sockets/wit-0.3.0-draft/udp.wit +++ b/proposals/sockets/wit-0.3.0-draft/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.3.0) interface udp { @since(version = 0.3.0) - use network.{error-code, ip-socket-address, ip-address-family}; + use types.{error-code, ip-socket-address, ip-address-family}; /// A received datagram. @since(version = 0.3.0) diff --git a/proposals/sockets/wit-0.3.0-draft/world.wit b/proposals/sockets/wit-0.3.0-draft/world.wit index b9b7461e4..6704b67c7 100644 --- a/proposals/sockets/wit-0.3.0-draft/world.wit +++ b/proposals/sockets/wit-0.3.0-draft/world.wit @@ -3,7 +3,7 @@ package wasi:sockets@0.3.0-draft; @since(version = 0.3.0) world imports { @since(version = 0.3.0) - import network; + import types; @since(version = 0.3.0) import udp; @since(version = 0.3.0) From ed7054100cab1fbebfe006bf060393ffa9ed4a40 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 16:51:50 +0100 Subject: [PATCH 1569/1772] Move tcp-socket & udp-socket into types.wit to match other proposals. --- .../wit-0.3.0-draft/ip-name-lookup.wit | 36 +- proposals/sockets/wit-0.3.0-draft/tcp.wit | 325 ---------- proposals/sockets/wit-0.3.0-draft/types.wit | 558 +++++++++++++++++- proposals/sockets/wit-0.3.0-draft/udp.wit | 210 ------- proposals/sockets/wit-0.3.0-draft/world.wit | 4 - 5 files changed, 560 insertions(+), 573 deletions(-) delete mode 100644 proposals/sockets/wit-0.3.0-draft/tcp.wit delete mode 100644 proposals/sockets/wit-0.3.0-draft/udp.wit diff --git a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit index c8c6b3f20..7cc8b03e3 100644 --- a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit +++ b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit @@ -1,7 +1,39 @@ @since(version = 0.3.0) interface ip-name-lookup { @since(version = 0.3.0) - use types.{lookup-error, ip-address}; + use types.{ip-address}; + + /// Lookup error codes. + @since(version = 0.3.0) + enum error-code { + /// Unknown error + unknown, + + /// Access denied. + /// + /// POSIX equivalent: EACCES, EPERM + access-denied, + + /// `name` is a syntactically invalid domain name or IP address. + /// + /// POSIX equivalent: EINVAL + invalid-argument, + + /// Name does not exist or has no suitable associated IP addresses. + /// + /// POSIX equivalent: EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY + name-unresolvable, + + /// A temporary failure in name resolution occurred. + /// + /// POSIX equivalent: EAI_AGAIN + temporary-resolver-failure, + + /// A permanent failure in name resolution occurred. + /// + /// POSIX equivalent: EAI_FAIL + permanent-resolver-failure, + } /// Resolve an internet host name to a list of IP addresses. /// @@ -26,5 +58,5 @@ interface ip-name-lookup { /// - /// - @since(version = 0.3.0) - resolve-addresses: func(name: string) -> result, lookup-error>; + resolve-addresses: func(name: string) -> result, error-code>; } diff --git a/proposals/sockets/wit-0.3.0-draft/tcp.wit b/proposals/sockets/wit-0.3.0-draft/tcp.wit deleted file mode 100644 index 7deecb533..000000000 --- a/proposals/sockets/wit-0.3.0-draft/tcp.wit +++ /dev/null @@ -1,325 +0,0 @@ -@since(version = 0.3.0) -interface tcp { - @since(version = 0.3.0) - use wasi:clocks/monotonic-clock@0.3.0.{duration}; - @since(version = 0.3.0) - use types.{error-code, ip-socket-address, ip-address-family}; - - /// A TCP connection resource - /// - /// The connection is used to transmit and receive data. - @since(version = 0.3.0) - resource tcp-connection { - /// Transmit data to peer. - /// - /// The caller should close the stream when it has no more data to send - /// to the peer. Under normal circumstances this will cause a FIN packet - /// to be sent. Closing the stream is equivalent to calling - /// `shutdown(SHUT_WR)` in POSIX. - /// - /// This function may be called at most once and returns once the full - /// contents of the stream are transmitted or an error is encountered. - @since(version = 0.3.0) - send: func(data: stream) -> result<_, error-code>; - - /// Read data from peer. - /// - /// This function fails if `read` was already called before on this connection. - /// - /// On sucess, this function returns a stream and a future, which will resolve - /// to an error code if receiving data from stream fails. - /// The returned future resolves to success if receiving side of the connection is closed. - /// - /// If the caller is not expecting to receive any data from the peer, - /// they may cancel the receive task. Any data still in the receive queue - /// will be discarded. This is equivalent to calling `shutdown(SHUT_RD)` - /// in POSIX. - @since(version = 0.3.0) - receive: func() -> result, future>>>; - } - - /// A TCP socket resource. - /// - /// The socket can be in one of the following states: - /// - `unbound` - /// - `bound` (See note below) - /// - `listening` - /// - `connecting` - /// - `connected` - /// - `closed` - /// See - /// for more information. - /// - /// Note: Except where explicitly mentioned, whenever this documentation uses - /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. - /// (i.e. `bound`, `listening`, `connecting` or `connected`) - /// - /// In addition to the general error codes documented on the - /// `types::error-code` type, TCP socket methods may always return - /// `error(invalid-state)` when in the `closed` state. - @since(version = 0.3.0) - resource tcp-socket { - - /// Create a new TCP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. - /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. - /// - /// Unlike POSIX, WASI sockets have no notion of a socket-level - /// `O_NONBLOCK` flag. Instead they fully rely on the Component Model's - /// async support. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - constructor(address-family: ip-address-family); - - /// Bind the socket to the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// Bind can be attempted multiple times on the same socket, even with - /// different arguments on each iteration. But never concurrently and - /// only as long as the previous bind failed. Once a bind succeeds, the - /// binding can't be changed anymore. - /// - /// # Typical errors - /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) - /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) - /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) - /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that can be bound to. (EADDRNOTAVAIL) - /// - /// # Implementors note - /// When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT - /// state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR - /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior - /// and SO_REUSEADDR performs something different entirely. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - bind: func(local-address: ip-socket-address) -> result<_, error-code>; - - /// Connect to a remote endpoint. - /// - /// On success, the socket is transitioned into the `connected` state and this function returns a connection resource. - /// - /// After a failed connection attempt, the socket will be in the `closed` - /// state and the only valid action left is to `drop` the socket. A single - /// socket can not be used to connect more than once. - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) - /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) - /// - `invalid-state`: The socket is already in the `connecting` state. (EALREADY) - /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) - /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) - /// - `timeout`: Connection timed out. (ETIMEDOUT) - /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) - /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - connect: func(remote-address: ip-socket-address) -> result; - - /// Start listening return a stream of new inbound connections. - /// - /// Transitions the socket into the `listening` state. - /// - /// If the socket is not already explicitly bound, this function will - /// implicitly bind the socket to a random free port. - /// - /// The returned sockets are bound and in the `connected` state. - /// The following properties are inherited from the listener socket: - /// - `address-family` - /// - `keep-alive-enabled` - /// - `keep-alive-idle-time` - /// - `keep-alive-interval` - /// - `keep-alive-count` - /// - `hop-limit` - /// - `receive-buffer-size` - /// - `send-buffer-size` - /// - /// # Typical errors - /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) - /// - `invalid-state`: The socket is already in the `listening` state. - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - listen: func() -> result>, error-code>; - - /// Get the bound local address. - /// - /// POSIX mentions: - /// > If the socket has not been bound to a local name, the value - /// > stored in the object pointed to by `address` is unspecified. - /// - /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - local-address: func() -> result; - - /// Get the remote address. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - remote-address: func() -> result; - - /// Whether the socket is in the `listening` state. - /// - /// Equivalent to the SO_ACCEPTCONN socket option. - @since(version = 0.3.0) - is-listening: func() -> bool; - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0) - address-family: func() -> ip-address-family; - - /// Hints the desired listen queue size. Implementations are free to ignore this. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// - /// # Typical errors - /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. - /// - `invalid-argument`: (set) The provided value was 0. - /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. - @since(version = 0.3.0) - set-listen-backlog-size: func(value: u64) -> result<_, error-code>; - - /// Enables or disables keepalive. - /// - /// The keepalive behavior can be adjusted using: - /// - `keep-alive-idle-time` - /// - `keep-alive-interval` - /// - `keep-alive-count` - /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. - /// - /// Equivalent to the SO_KEEPALIVE socket option. - @since(version = 0.3.0) - keep-alive-enabled: func() -> result; - @since(version = 0.3.0) - set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; - - /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS) - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - keep-alive-idle-time: func() -> result; - @since(version = 0.3.0) - set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; - - /// The time between keepalive packets. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the TCP_KEEPINTVL socket option. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - keep-alive-interval: func() -> result; - @since(version = 0.3.0) - set-keep-alive-interval: func(value: duration) -> result<_, error-code>; - - /// The maximum amount of keepalive packets TCP should send before aborting the connection. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the TCP_KEEPCNT socket option. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - keep-alive-count: func() -> result; - @since(version = 0.3.0) - set-keep-alive-count: func(value: u32) -> result<_, error-code>; - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0) - hop-limit: func() -> result; - @since(version = 0.3.0) - set-hop-limit: func(value: u8) -> result<_, error-code>; - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - receive-buffer-size: func() -> result; - @since(version = 0.3.0) - set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0) - send-buffer-size: func() -> result; - @since(version = 0.3.0) - set-send-buffer-size: func(value: u64) -> result<_, error-code>; - } -} diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index dae70962a..ef6c8daf2 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -1,5 +1,8 @@ @since(version = 0.3.0) interface types { + @since(version = 0.3.0) + use wasi:clocks/monotonic-clock@0.3.0.{duration}; + /// Error codes. /// /// In theory, every API can return any error code. @@ -67,38 +70,6 @@ interface types { datagram-too-large, } - /// Lookup error codes. - @since(version = 0.3.0) - enum lookup-error { - /// Unknown error - unknown, - - /// Access denied. - /// - /// POSIX equivalent: EACCES, EPERM - access-denied, - - /// `name` is a syntactically invalid domain name or IP address. - /// - /// POSIX equivalent: EINVAL - invalid-argument, - - /// Name does not exist or has no suitable associated IP addresses. - /// - /// POSIX equivalent: EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY - name-unresolvable, - - /// A temporary failure in name resolution occurred. - /// - /// POSIX equivalent: EAI_AGAIN - temporary-resolver-failure, - - /// A permanent failure in name resolution occurred. - /// - /// POSIX equivalent: EAI_FAIL - permanent-resolver-failure, - } - @since(version = 0.3.0) enum ip-address-family { /// Similar to `AF_INET` in POSIX. @@ -144,4 +115,527 @@ interface types { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), } + + /// A TCP connection resource + /// + /// The connection is used to transmit and receive data. + @since(version = 0.3.0) + resource tcp-connection { + /// Transmit data to peer. + /// + /// The caller should close the stream when it has no more data to send + /// to the peer. Under normal circumstances this will cause a FIN packet + /// to be sent. Closing the stream is equivalent to calling + /// `shutdown(SHUT_WR)` in POSIX. + /// + /// This function may be called at most once and returns once the full + /// contents of the stream are transmitted or an error is encountered. + @since(version = 0.3.0) + send: func(data: stream) -> result<_, error-code>; + + /// Read data from peer. + /// + /// This function fails if `read` was already called before on this connection. + /// + /// On sucess, this function returns a stream and a future, which will resolve + /// to an error code if receiving data from stream fails. + /// The returned future resolves to success if receiving side of the connection is closed. + /// + /// If the caller is not expecting to receive any data from the peer, + /// they may cancel the receive task. Any data still in the receive queue + /// will be discarded. This is equivalent to calling `shutdown(SHUT_RD)` + /// in POSIX. + @since(version = 0.3.0) + receive: func() -> result, future>>>; + } + + /// A TCP socket resource. + /// + /// The socket can be in one of the following states: + /// - `unbound` + /// - `bound` (See note below) + /// - `listening` + /// - `connecting` + /// - `connected` + /// - `closed` + /// See + /// for more information. + /// + /// Note: Except where explicitly mentioned, whenever this documentation uses + /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. + /// (i.e. `bound`, `listening`, `connecting` or `connected`) + /// + /// In addition to the general error codes documented on the + /// `types::error-code` type, TCP socket methods may always return + /// `error(invalid-state)` when in the `closed` state. + @since(version = 0.3.0) + resource tcp-socket { + + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. + /// + /// Unlike POSIX, WASI sockets have no notion of a socket-level + /// `O_NONBLOCK` flag. Instead they fully rely on the Component Model's + /// async support. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + constructor(address-family: ip-address-family); + + /// Bind the socket to the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// Bind can be attempted multiple times on the same socket, even with + /// different arguments on each iteration. But never concurrently and + /// only as long as the previous bind failed. Once a bind succeeds, the + /// binding can't be changed anymore. + /// + /// # Typical errors + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) + /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that can be bound to. (EADDRNOTAVAIL) + /// + /// # Implementors note + /// When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT + /// state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR + /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior + /// and SO_REUSEADDR performs something different entirely. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + bind: func(local-address: ip-socket-address) -> result<_, error-code>; + + /// Connect to a remote endpoint. + /// + /// On success, the socket is transitioned into the `connected` state and this function returns a connection resource. + /// + /// After a failed connection attempt, the socket will be in the `closed` + /// state and the only valid action left is to `drop` the socket. A single + /// socket can not be used to connect more than once. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) + /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `invalid-state`: The socket is already in the `connecting` state. (EALREADY) + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) + /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + connect: func(remote-address: ip-socket-address) -> result; + + /// Start listening return a stream of new inbound connections. + /// + /// Transitions the socket into the `listening` state. + /// + /// If the socket is not already explicitly bound, this function will + /// implicitly bind the socket to a random free port. + /// + /// The returned sockets are bound and in the `connected` state. + /// The following properties are inherited from the listener socket: + /// - `address-family` + /// - `keep-alive-enabled` + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// - `hop-limit` + /// - `receive-buffer-size` + /// - `send-buffer-size` + /// + /// # Typical errors + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) + /// - `invalid-state`: The socket is already in the `listening` state. + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + listen: func() -> result>, error-code>; + + /// Get the bound local address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + local-address: func() -> result; + + /// Get the remote address. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + remote-address: func() -> result; + + /// Whether the socket is in the `listening` state. + /// + /// Equivalent to the SO_ACCEPTCONN socket option. + @since(version = 0.3.0) + is-listening: func() -> bool; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.3.0) + address-family: func() -> ip-address-family; + + /// Hints the desired listen queue size. Implementations are free to ignore this. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// + /// # Typical errors + /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. + /// - `invalid-argument`: (set) The provided value was 0. + /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. + @since(version = 0.3.0) + set-listen-backlog-size: func(value: u64) -> result<_, error-code>; + + /// Enables or disables keepalive. + /// + /// The keepalive behavior can be adjusted using: + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. + /// + /// Equivalent to the SO_KEEPALIVE socket option. + @since(version = 0.3.0) + keep-alive-enabled: func() -> result; + @since(version = 0.3.0) + set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; + + /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS) + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + keep-alive-idle-time: func() -> result; + @since(version = 0.3.0) + set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; + + /// The time between keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPINTVL socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + keep-alive-interval: func() -> result; + @since(version = 0.3.0) + set-keep-alive-interval: func(value: duration) -> result<_, error-code>; + + /// The maximum amount of keepalive packets TCP should send before aborting the connection. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPCNT socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + keep-alive-count: func() -> result; + @since(version = 0.3.0) + set-keep-alive-count: func(value: u32) -> result<_, error-code>; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.3.0) + hop-limit: func() -> result; + @since(version = 0.3.0) + set-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + receive-buffer-size: func() -> result; + @since(version = 0.3.0) + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.3.0) + send-buffer-size: func() -> result; + @since(version = 0.3.0) + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + } + + /// A received datagram. + @since(version = 0.3.0) + record incoming-datagram { + /// The payload. + /// + /// Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. + data: list, + + /// The source address. + /// + /// This field is guaranteed to match the remote address the stream was initialized with, if any. + /// + /// Equivalent to the `src_addr` out parameter of `recvfrom`. + remote-address: ip-socket-address, + } + + /// A datagram to be sent out. + @since(version = 0.3.0) + record outgoing-datagram { + /// The payload. + data: list, + + /// The destination address. + /// + /// The requirements on this field depend on how the stream was initialized: + /// - with a remote address: this field must be None or match the stream's remote address exactly. + /// - without a remote address: this field is required. + /// + /// If this value is None, the send operation is equivalent to `send` in POSIX. Otherwise it is equivalent to `sendto`. + remote-address: option, + } + + /// A UDP socket handle. + @since(version = 0.3.0) + resource udp-socket { + + /// Create a new UDP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. + /// + /// Unlike POSIX, WASI sockets have no notion of a socket-level + /// `O_NONBLOCK` flag. Instead they fully rely on the Component Model's + /// async support. + /// + /// # References: + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + constructor(address-family: ip-address-family); + + /// Bind the socket to the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the port is zero, the socket will be bound to a random free port. + /// + /// # Typical errors + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that can be bound to. (EADDRNOTAVAIL) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + bind: func(local-address: ip-socket-address) -> result<_, error-code>; + + /// Set up inbound & outbound communication channels, optionally to a specific peer. + /// + /// The `datagrams` stream parameter represents the data to be sent out. + /// The returned stream represents the data that was received. + /// + /// This function only changes the local socket configuration and does + /// not generate any network traffic. On success, the `remote-address` + /// of the socket is updated. The `local-address` may be updated as well, + /// based on the best network path to `remote-address`. If the socket was + /// not already explicitly bound, this function will implicitly bind the + /// socket to a random free port. + /// + /// When a `remote-address` is provided, the streams are limited to + /// communicating with that specific peer: + /// - The `outgoing-datagram` stream can only be used to send to this destination. + /// - The `incoming-datagram` stream will only return datagrams sent from the provided `remote-address`. + /// + /// This method may be called multiple times on the same socket to change + /// its association, but only the most recent pair of streams will be + /// operational. Calling this function more than once effectively cancels + /// any previously started `transfer` tasks. + /// + /// The POSIX equivalent in pseudo-code is: + /// ```text + /// if (was previously connected) { + /// connect(s, AF_UNSPEC) + /// } + /// if (remote_address is Some) { + /// connect(s, remote_address) + /// } + /// ``` + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + transfer: func(datagrams: list, remote-address: option) -> result, error-code>; + + /// Get the current bound address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + local-address: func() -> result; + + /// Get the address the socket is currently streaming to. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not streaming to a specific remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + remote-address: func() -> result; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.3.0) + address-family: func() -> ip-address-family; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.3.0) + unicast-hop-limit: func() -> result; + @since(version = 0.3.0) + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + receive-buffer-size: func() -> result; + @since(version = 0.3.0) + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.3.0) + send-buffer-size: func() -> result; + @since(version = 0.3.0) + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + } } diff --git a/proposals/sockets/wit-0.3.0-draft/udp.wit b/proposals/sockets/wit-0.3.0-draft/udp.wit deleted file mode 100644 index 4dd76fe49..000000000 --- a/proposals/sockets/wit-0.3.0-draft/udp.wit +++ /dev/null @@ -1,210 +0,0 @@ -@since(version = 0.3.0) -interface udp { - @since(version = 0.3.0) - use types.{error-code, ip-socket-address, ip-address-family}; - - /// A received datagram. - @since(version = 0.3.0) - record incoming-datagram { - /// The payload. - /// - /// Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. - data: list, - - /// The source address. - /// - /// This field is guaranteed to match the remote address the stream was initialized with, if any. - /// - /// Equivalent to the `src_addr` out parameter of `recvfrom`. - remote-address: ip-socket-address, - } - - /// A datagram to be sent out. - @since(version = 0.3.0) - record outgoing-datagram { - /// The payload. - data: list, - - /// The destination address. - /// - /// The requirements on this field depend on how the stream was initialized: - /// - with a remote address: this field must be None or match the stream's remote address exactly. - /// - without a remote address: this field is required. - /// - /// If this value is None, the send operation is equivalent to `send` in POSIX. Otherwise it is equivalent to `sendto`. - remote-address: option, - } - - /// A UDP socket handle. - @since(version = 0.3.0) - resource udp-socket { - - /// Create a new UDP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. - /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. - /// - /// Unlike POSIX, WASI sockets have no notion of a socket-level - /// `O_NONBLOCK` flag. Instead they fully rely on the Component Model's - /// async support. - /// - /// # References: - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - constructor(address-family: ip-address-family); - - /// Bind the socket to the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the port is zero, the socket will be bound to a random free port. - /// - /// # Typical errors - /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) - /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that can be bound to. (EADDRNOTAVAIL) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - bind: func(local-address: ip-socket-address) -> result<_, error-code>; - - /// Set up inbound & outbound communication channels, optionally to a specific peer. - /// - /// The `datagrams` stream parameter represents the data to be sent out. - /// The returned stream represents the data that was received. - /// - /// This function only changes the local socket configuration and does - /// not generate any network traffic. On success, the `remote-address` - /// of the socket is updated. The `local-address` may be updated as well, - /// based on the best network path to `remote-address`. If the socket was - /// not already explicitly bound, this function will implicitly bind the - /// socket to a random free port. - /// - /// When a `remote-address` is provided, the streams are limited to - /// communicating with that specific peer: - /// - The `outgoing-datagram` stream can only be used to send to this destination. - /// - The `incoming-datagram` stream will only return datagrams sent from the provided `remote-address`. - /// - /// This method may be called multiple times on the same socket to change - /// its association, but only the most recent pair of streams will be - /// operational. Calling this function more than once effectively cancels - /// any previously started `transfer` tasks. - /// - /// The POSIX equivalent in pseudo-code is: - /// ```text - /// if (was previously connected) { - /// connect(s, AF_UNSPEC) - /// } - /// if (remote_address is Some) { - /// connect(s, remote_address) - /// } - /// ``` - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - transfer: func(datagrams: list, remote-address: option) -> result, error-code>; - - /// Get the current bound address. - /// - /// POSIX mentions: - /// > If the socket has not been bound to a local name, the value - /// > stored in the object pointed to by `address` is unspecified. - /// - /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - local-address: func() -> result; - - /// Get the address the socket is currently streaming to. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not streaming to a specific remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0) - remote-address: func() -> result; - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0) - address-family: func() -> ip-address-family; - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0) - unicast-hop-limit: func() -> result; - @since(version = 0.3.0) - set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - receive-buffer-size: func() -> result; - @since(version = 0.3.0) - set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0) - send-buffer-size: func() -> result; - @since(version = 0.3.0) - set-send-buffer-size: func(value: u64) -> result<_, error-code>; - } -} diff --git a/proposals/sockets/wit-0.3.0-draft/world.wit b/proposals/sockets/wit-0.3.0-draft/world.wit index 6704b67c7..a293a3009 100644 --- a/proposals/sockets/wit-0.3.0-draft/world.wit +++ b/proposals/sockets/wit-0.3.0-draft/world.wit @@ -5,9 +5,5 @@ world imports { @since(version = 0.3.0) import types; @since(version = 0.3.0) - import udp; - @since(version = 0.3.0) - import tcp; - @since(version = 0.3.0) import ip-name-lookup; } From 3a4bfe8f4a7c469807a5baa4dcd4d29295f47ff2 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 16:53:42 +0100 Subject: [PATCH 1570/1772] Make wit-bindgen work. It failed with: ``` Error: failed to resolve directory while parsing WIT for path [wit-0.3.0-draft] Caused by: 0: failed to process feature gate for type [duration] in package [wasi:sockets@0.3.0-draft] 1: feature gate cannot reference unreleased version 0.3.0 of package [wasi:sockets@0.3.0-draft] (current version 0.3.0-draft) ``` --- proposals/sockets/wit-0.3.0-draft/world.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit-0.3.0-draft/world.wit b/proposals/sockets/wit-0.3.0-draft/world.wit index a293a3009..6c9951d1c 100644 --- a/proposals/sockets/wit-0.3.0-draft/world.wit +++ b/proposals/sockets/wit-0.3.0-draft/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.3.0-draft; +package wasi:sockets@0.3.0; @since(version = 0.3.0) world imports { From c37526eca8a98ebfb622e7125590c335b3867516 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Thu, 16 Jan 2025 19:36:47 +0100 Subject: [PATCH 1571/1772] Update TcpSocketOperationalSemantics-0.3.0-draft.md Co-authored-by: Roman Volosatovs --- proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md b/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md index 364016381..b64e1853b 100644 --- a/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md +++ b/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md @@ -50,5 +50,5 @@ stateDiagram-v2 - Transitions annotated with `-> ok` only apply when the method returns successfully. - Calling a method from the wrong state returns `error(invalid-state)` and does not affect the state of the socket. - This diagram only includes the methods that impact the socket's state. For an overview of all methods and their required states, see [tcp.wit](./wit/tcp.wit) -- Client sockets returned by `listen()` are in immediately in the `connected` state. +- Client sockets returned by `listen()` are immediately in the `connected` state. - A socket resource can be dropped in any state. From 1c44c8fea0ff82cd451d660088ff4ee7d8f3f69d Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Thu, 16 Jan 2025 18:44:31 +0100 Subject: [PATCH 1572/1772] feat: update wit-deps to 0.5.0 Signed-off-by: Roman Volosatovs --- proposals/sockets/.github/workflows/main.yml | 4 +++- proposals/sockets/wit-0.3.0-draft/deps.lock | 1 + proposals/sockets/wit-0.3.0-draft/deps.toml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index 248ca1d9d..3e61870eb 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -13,10 +13,12 @@ jobs: - uses: actions/checkout@v4 - name: ensure `./wit/deps` are in sync run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.3/wit-deps-x86_64-unknown-linux-musl + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.5.0/wit-deps-x86_64-unknown-linux-musl chmod +x wit-deps ./wit-deps lock + ./wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps lock git add -N wit/deps + git add -N wit-0.3.0-draft/deps git diff --exit-code - uses: WebAssembly/wit-abi-up-to-date@v22 with: diff --git a/proposals/sockets/wit-0.3.0-draft/deps.lock b/proposals/sockets/wit-0.3.0-draft/deps.lock index 20306c6fe..03868084d 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps.lock +++ b/proposals/sockets/wit-0.3.0-draft/deps.lock @@ -1,4 +1,5 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" +subdir = "wit-0.3.0-draft" sha256 = "26e315db0d371495f8834edfc0e479042f94152ce677d96d54d3623d0e4ffb1e" sha512 = "e1c76f499435841316f9287b88d8173558e64f277c321ff390556de8707a0b18dd6c1749bbb17bbbba8d523da246ef6eb05c990ceddb762e03efb2ae30cacc76" diff --git a/proposals/sockets/wit-0.3.0-draft/deps.toml b/proposals/sockets/wit-0.3.0-draft/deps.toml index 3f6ad6d2e..e00454742 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps.toml +++ b/proposals/sockets/wit-0.3.0-draft/deps.toml @@ -1 +1 @@ -clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" +clocks = { url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz", subdir = "wit-0.3.0-draft" } From c9a7d4e48e958c7d692c2372fd9bd29febd54b1a Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 17 Jan 2025 12:14:49 +0100 Subject: [PATCH 1573/1772] chore(0.3): bump `@since` gates to `0.3.0` Signed-off-by: Roman Volosatovs --- proposals/random/wit-0.3.0-draft/insecure-seed.wit | 4 ++-- proposals/random/wit-0.3.0-draft/insecure.wit | 6 +++--- proposals/random/wit-0.3.0-draft/random.wit | 6 +++--- proposals/random/wit-0.3.0-draft/world.wit | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/proposals/random/wit-0.3.0-draft/insecure-seed.wit b/proposals/random/wit-0.3.0-draft/insecure-seed.wit index 66a469432..4708d9049 100644 --- a/proposals/random/wit-0.3.0-draft/insecure-seed.wit +++ b/proposals/random/wit-0.3.0-draft/insecure-seed.wit @@ -3,7 +3,7 @@ package wasi:random@0.3.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.2.0) +@since(version = 0.3.0) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.2.0) + @since(version = 0.3.0) insecure-seed: func() -> tuple; } diff --git a/proposals/random/wit-0.3.0-draft/insecure.wit b/proposals/random/wit-0.3.0-draft/insecure.wit index 7f2b86fbe..4ea5e581f 100644 --- a/proposals/random/wit-0.3.0-draft/insecure.wit +++ b/proposals/random/wit-0.3.0-draft/insecure.wit @@ -3,7 +3,7 @@ package wasi:random@0.3.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.2.0) +@since(version = 0.3.0) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.2.0) + @since(version = 0.3.0) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.2.0) + @since(version = 0.3.0) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/random.wit b/proposals/random/wit-0.3.0-draft/random.wit index 5edfa2baa..786ef25f6 100644 --- a/proposals/random/wit-0.3.0-draft/random.wit +++ b/proposals/random/wit-0.3.0-draft/random.wit @@ -3,7 +3,7 @@ package wasi:random@0.3.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.2.0) +@since(version = 0.3.0) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.2.0) + @since(version = 0.3.0) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.2.0) + @since(version = 0.3.0) get-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/world.wit b/proposals/random/wit-0.3.0-draft/world.wit index d01746d1e..838d38023 100644 --- a/proposals/random/wit-0.3.0-draft/world.wit +++ b/proposals/random/wit-0.3.0-draft/world.wit @@ -1,13 +1,13 @@ package wasi:random@0.3.0; -@since(version = 0.2.0) +@since(version = 0.3.0) world imports { - @since(version = 0.2.0) + @since(version = 0.3.0) import random; - @since(version = 0.2.0) + @since(version = 0.3.0) import insecure; - @since(version = 0.2.0) + @since(version = 0.3.0) import insecure-seed; } From a72b08345c6bf90d26b34f42401cd946b15677a6 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Fri, 17 Jan 2025 21:19:01 +0100 Subject: [PATCH 1574/1772] Update wit-0.3.0-draft/types.wit Co-authored-by: Roman Volosatovs --- proposals/sockets/wit-0.3.0-draft/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index ef6c8daf2..4c4a85132 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -568,7 +568,7 @@ interface types { /// - /// - @since(version = 0.3.0) - transfer: func(datagrams: list, remote-address: option) -> result, error-code>; + transfer: func(datagrams: stream, remote-address: option) -> result, error-code>; /// Get the current bound address. /// From 313e5af9ba5923ccd3b1c45fa7a4422d811e4218 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 19 Jan 2025 18:01:17 +0100 Subject: [PATCH 1575/1772] Fix WSARecvMsg link --- proposals/sockets/wit-0.3.0-draft/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 4c4a85132..8014ffb05 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -563,7 +563,7 @@ interface types { /// - /// - /// - - /// - + /// - /// - /// - /// - From 798e2480d5c3e14f32448973632691debc3bb26c Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 19 Jan 2025 19:22:17 +0100 Subject: [PATCH 1576/1772] Document the distinction between permanent and transient errors on `listen`, and provide guidance on how implementations may handle them. --- ...pSocketOperationalSemantics-0.3.0-draft.md | 2 +- proposals/sockets/wit-0.3.0-draft/types.wit | 36 +++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md b/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md index b64e1853b..9aeeddff3 100644 --- a/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md +++ b/proposals/sockets/TcpSocketOperationalSemantics-0.3.0-draft.md @@ -15,7 +15,7 @@ interface tcp { listening(accept-stream), connecting(connect-future), connected, - closed, + closed(option), } } ``` diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 8014ffb05..2b7b462f5 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -255,12 +255,19 @@ interface types { /// Start listening return a stream of new inbound connections. /// - /// Transitions the socket into the `listening` state. + /// Transitions the socket into the `listening` state. This can be called + /// at most once per socket. /// /// If the socket is not already explicitly bound, this function will /// implicitly bind the socket to a random free port. /// - /// The returned sockets are bound and in the `connected` state. + /// Normally, the returned sockets are bound, in the `connected` state + /// and immediately ready for I/O. Though, depending on exact timing and + /// circumstances, a newly accepted connection may already be `closed` + /// by the time the server attempts to perform its first I/O on it. This + /// is true regardless of whether the WASI implementation uses + /// "synthesized" sockets or not (see Implementors Notes below). + /// /// The following properties are inherited from the listener socket: /// - `address-family` /// - `keep-alive-enabled` @@ -276,6 +283,31 @@ interface types { /// - `invalid-state`: The socket is already in the `listening` state. /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) /// + /// # Implementors note + /// This method returns a single perpetual stream that should only close + /// on fatal errors (if any). Yet, the POSIX' `accept` function may also + /// return transient errors (e.g. ECONNABORTED). The exact details differ + /// per operation system. For example, the Linux manual mentions: + /// + /// > Linux accept() passes already-pending network errors on the new + /// > socket as an error code from accept(). This behavior differs from + /// > other BSD socket implementations. For reliable operation the + /// > application should detect the network errors defined for the + /// > protocol after accept() and treat them like EAGAIN by retrying. + /// > In the case of TCP/IP, these are ENETDOWN, EPROTO, ENOPROTOOPT, + /// > EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP, and ENETUNREACH. + /// Source: https://man7.org/linux/man-pages/man2/accept.2.html + /// + /// WASI implementations have two options to handle this: + /// - Optionally log it and then skip over non-fatal errors returned by + /// `accept`. Guest code never gets to see these failures. Or: + /// - Synthesize a `tcp-socket` resource that exposes the error when + /// attempting to send or receive on it. Guest code then sees these + /// failures as regular I/O errors. + /// + /// In either case, the stream returned by this `listen` method remains + /// operational. + /// /// # References /// - /// - From 8dc34f3aa96065b4f092aaacc36e31e59689341e Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 19 Jan 2025 20:00:46 +0100 Subject: [PATCH 1577/1772] Move `send` & `receive` into `tcp-socket`, simplifying the signatures of `connect` & `listen` even further. --- proposals/sockets/wit-0.3.0-draft/types.wit | 86 ++++++++++++--------- 1 file changed, 51 insertions(+), 35 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 2b7b462f5..5d9cdcbba 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -116,39 +116,6 @@ interface types { ipv6(ipv6-socket-address), } - /// A TCP connection resource - /// - /// The connection is used to transmit and receive data. - @since(version = 0.3.0) - resource tcp-connection { - /// Transmit data to peer. - /// - /// The caller should close the stream when it has no more data to send - /// to the peer. Under normal circumstances this will cause a FIN packet - /// to be sent. Closing the stream is equivalent to calling - /// `shutdown(SHUT_WR)` in POSIX. - /// - /// This function may be called at most once and returns once the full - /// contents of the stream are transmitted or an error is encountered. - @since(version = 0.3.0) - send: func(data: stream) -> result<_, error-code>; - - /// Read data from peer. - /// - /// This function fails if `read` was already called before on this connection. - /// - /// On sucess, this function returns a stream and a future, which will resolve - /// to an error code if receiving data from stream fails. - /// The returned future resolves to success if receiving side of the connection is closed. - /// - /// If the caller is not expecting to receive any data from the peer, - /// they may cancel the receive task. Any data still in the receive queue - /// will be discarded. This is equivalent to calling `shutdown(SHUT_RD)` - /// in POSIX. - @since(version = 0.3.0) - receive: func() -> result, future>>>; - } - /// A TCP socket resource. /// /// The socket can be in one of the following states: @@ -251,7 +218,7 @@ interface types { /// - /// - @since(version = 0.3.0) - connect: func(remote-address: ip-socket-address) -> result; + connect: func(remote-address: ip-socket-address) -> result<_, error-code>; /// Start listening return a stream of new inbound connections. /// @@ -318,7 +285,56 @@ interface types { /// - /// - @since(version = 0.3.0) - listen: func() -> result>, error-code>; + listen: func() -> result, error-code>; + + /// Transmit data to peer. + /// + /// The caller should close the stream when it has no more data to send + /// to the peer. Under normal circumstances this will cause a FIN packet + /// to be sent out. Closing the stream is equivalent to calling + /// `shutdown(SHUT_WR)` in POSIX. + /// + /// This function may be called at most once and returns once the full + /// contents of the stream are transmitted or an error is encountered. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + send: func(data: stream) -> result<_, error-code>; + + /// Read data from peer. + /// + /// This function fails if `receive` was already called before on this connection. + /// + /// On success, this function returns a stream and a future, which will resolve + /// to an error code if receiving data from stream fails. + /// The returned future resolves to success if receiving side of the connection is closed. + /// + /// If the caller is not expecting to receive any data from the peer, + /// they may cancel the receive task. Any data still in the receive queue + /// will be discarded. This is equivalent to calling `shutdown(SHUT_RD)` + /// in POSIX. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + receive: func() -> result, future>>>; /// Get the bound local address. /// From 2cdbdc64a2f0a29fbfb453c0b0f841c1a909e890 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 19 Jan 2025 21:43:50 +0100 Subject: [PATCH 1578/1772] Revert usage of `streams` for UDP. `stream`s can fail only once and then they're done, whereas UDP packets should be able to fail/succeed independently without affecting the transmission of other packets. Without the stream parameter and return value, the `transfer` method is beginning to look an afwul lot like `connect` again, so we might as well call it that. --- proposals/sockets/wit-0.3.0-draft/types.wit | 125 +++++++++++++------- 1 file changed, 82 insertions(+), 43 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 5d9cdcbba..2c0d55964 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -212,6 +212,7 @@ interface types { /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// /// # References /// - /// - @@ -492,7 +493,7 @@ interface types { /// The source address. /// - /// This field is guaranteed to match the remote address the stream was initialized with, if any. + /// This field is guaranteed to match the remote address the socket is connected to, if any. /// /// Equivalent to the `src_addr` out parameter of `recvfrom`. remote-address: ip-socket-address, @@ -506,8 +507,8 @@ interface types { /// The destination address. /// - /// The requirements on this field depend on how the stream was initialized: - /// - with a remote address: this field must be None or match the stream's remote address exactly. + /// The requirements on this field depend on how the socket is configured: + /// - with a remote address: this field must be None or match the socket's remote address exactly. /// - without a remote address: this field is required. /// /// If this value is None, the send operation is equivalent to `send` in POSIX. Otherwise it is equivalent to `sendto`. @@ -556,67 +557,105 @@ interface types { @since(version = 0.3.0) bind: func(local-address: ip-socket-address) -> result<_, error-code>; - /// Set up inbound & outbound communication channels, optionally to a specific peer. + /// Associate this socket with a specific peer address. /// - /// The `datagrams` stream parameter represents the data to be sent out. - /// The returned stream represents the data that was received. + /// On success, the `remote-address` of the socket is updated. + /// The `local-address` may be updated as well, based on the best network + /// path to `remote-address`. If the socket was not already explicitly + /// bound, this function will implicitly bind the socket to a random + /// free port. /// - /// This function only changes the local socket configuration and does - /// not generate any network traffic. On success, the `remote-address` - /// of the socket is updated. The `local-address` may be updated as well, - /// based on the best network path to `remote-address`. If the socket was - /// not already explicitly bound, this function will implicitly bind the - /// socket to a random free port. + /// When a UDP socket is "connected", the `send` and `receive` methods + /// are limited to communicating with that peer only: + /// - `send` can only be used to send to this destination. + /// - `receive` will only return datagrams sent from the provided `remote-address`. + /// + /// The name "connect" was kept to align with the existing POSIX + /// terminology. Other than that, this function only changes the local + /// socket configuration and does not generate any network traffic. + /// The peer is not aware of this "connection". /// - /// When a `remote-address` is provided, the streams are limited to - /// communicating with that specific peer: - /// - The `outgoing-datagram` stream can only be used to send to this destination. - /// - The `incoming-datagram` stream will only return datagrams sent from the provided `remote-address`. - /// /// This method may be called multiple times on the same socket to change - /// its association, but only the most recent pair of streams will be - /// operational. Calling this function more than once effectively cancels - /// any previously started `transfer` tasks. - /// - /// The POSIX equivalent in pseudo-code is: - /// ```text - /// if (was previously connected) { - /// connect(s, AF_UNSPEC) - /// } - /// if (remote_address is Some) { - /// connect(s, remote_address) - /// } - /// ``` - /// + /// its association, but only the most recent one will be effective. + /// /// # Typical errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) /// + /// # Implementors note + /// If the socket is already connected, some platforms (e.g. Linux) + /// require a disconnect before connecting to a different peer address. + /// /// # References /// - + /// - + /// - + /// - + @since(version = 0.3.0) + connect: func(remote-address: ip-socket-address) -> result<_, error-code>; + + /// Dissociate this socket from its peer address. + /// + /// After calling this method, `send` & `receive` are free to communicate + /// with any address again. + /// + /// The POSIX equivalent of this is calling `connect` with an `AF_UNSPEC` address. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not connected. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + disconnect: func() -> result<_, error-code>; + + /// Send a message on the socket. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `connect`. (EISCONN) + /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) + /// - `invalid-state`: The socket has not been bound yet. + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// + /// # References /// - /// - - /// - - /// - - /// - /// - /// - - /// - - /// - - /// - /// - /// - /// - - /// - + /// - + @since(version = 0.3.0) + send: func(data: outgoing-datagram) -> result<_, error-code>; + + /// Receive a message on the socket. + /// + /// # Typical errors + /// - `invalid-state`: The socket has not been bound yet. + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// + /// # References + /// - + /// - + /// - + /// - /// - /// - - /// - - /// - /// - @since(version = 0.3.0) - transfer: func(datagrams: stream, remote-address: option) -> result, error-code>; + receive: func() -> result; /// Get the current bound address. /// @@ -637,10 +676,10 @@ interface types { @since(version = 0.3.0) local-address: func() -> result; - /// Get the address the socket is currently streaming to. + /// Get the address the socket is currently "connected" to. /// /// # Typical errors - /// - `invalid-state`: The socket is not streaming to a specific remote address. (ENOTCONN) + /// - `invalid-state`: The socket is not "connected" to a specific remote address. (ENOTCONN) /// /// # References /// - From 1a27b45adabd59edd7a86f7578ddd1b37fc90133 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 19 Jan 2025 22:25:24 +0100 Subject: [PATCH 1579/1772] Remove inbound/outbound-datagram records. They were added in anticipation of ComponentModel-level subtyping of value types, so that we could add additional fields (e.g. TTL, TOS, etc.) without breaking backwards-compatibility. AFAIK, that idea has been put on hold indefinitely, so we might as well make the 0.3.0 interface as simple as possible --- proposals/sockets/wit-0.3.0-draft/types.wit | 58 ++++++++------------- 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 2c0d55964..4d454fbab 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -483,38 +483,6 @@ interface types { set-send-buffer-size: func(value: u64) -> result<_, error-code>; } - /// A received datagram. - @since(version = 0.3.0) - record incoming-datagram { - /// The payload. - /// - /// Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. - data: list, - - /// The source address. - /// - /// This field is guaranteed to match the remote address the socket is connected to, if any. - /// - /// Equivalent to the `src_addr` out parameter of `recvfrom`. - remote-address: ip-socket-address, - } - - /// A datagram to be sent out. - @since(version = 0.3.0) - record outgoing-datagram { - /// The payload. - data: list, - - /// The destination address. - /// - /// The requirements on this field depend on how the socket is configured: - /// - with a remote address: this field must be None or match the socket's remote address exactly. - /// - without a remote address: this field is required. - /// - /// If this value is None, the send operation is equivalent to `send` in POSIX. Otherwise it is equivalent to `sendto`. - remote-address: option, - } - /// A UDP socket handle. @since(version = 0.3.0) resource udp-socket { @@ -614,7 +582,17 @@ interface types { @since(version = 0.3.0) disconnect: func() -> result<_, error-code>; - /// Send a message on the socket. + /// Send a message on the socket to a particular peer. + /// + /// If the socket is connected, the peer address may be left empty. In + /// that case this is equivalent to `send` in POSIX. Otherwise it is + /// equivalent to `sendto`. + /// + /// Additionally, if the socket is connected, a `remote-address` argument + /// _may_ be provided but then it must be identical to the address + /// passed to `connect`. + /// + /// Implementations may trap if the `data` length exceeds 64 KiB. /// /// # Typical errors /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) @@ -637,10 +615,18 @@ interface types { /// - /// - @since(version = 0.3.0) - send: func(data: outgoing-datagram) -> result<_, error-code>; + send: func(data: list, remote-address: option) -> result<_, error-code>; /// Receive a message on the socket. /// + /// On success, the return value contains a tuple of the received data + /// and the address of the sender. Theoretical maximum length of the + /// data is 64 KiB. Though in practice, it will typically be less than + /// 1500 bytes. + /// + /// If the socket is connected, the sender address is guaranteed to + /// match the remote address passed to `connect`. + /// /// # Typical errors /// - `invalid-state`: The socket has not been bound yet. /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) @@ -655,7 +641,7 @@ interface types { /// - /// - @since(version = 0.3.0) - receive: func() -> result; + receive: func() -> result, ip-socket-address>, error-code>; /// Get the current bound address. /// @@ -664,7 +650,7 @@ interface types { /// > stored in the object pointed to by `address` is unspecified. /// /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. - /// + /// /// # Typical errors /// - `invalid-state`: The socket is not bound to any local address. /// From 4cadb013ac633f984177859000e3f4a9fe326e0a Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 19 Jan 2025 22:32:08 +0100 Subject: [PATCH 1580/1772] Remove outer result from `receive` --- proposals/sockets/wit-0.3.0-draft/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 4d454fbab..9b4a243f3 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -335,7 +335,7 @@ interface types { /// - /// - @since(version = 0.3.0) - receive: func() -> result, future>>>; + receive: func() -> tuple, future>>; /// Get the bound local address. /// From f13a2de8b5d33076163fdf2e8c9f89ac5f42f540 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sun, 19 Jan 2025 23:13:42 +0100 Subject: [PATCH 1581/1772] Clarify `address-family` --- proposals/sockets/wit-0.3.0-draft/types.wit | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 9b4a243f3..c20954db0 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -377,6 +377,8 @@ interface types { /// Whether this is a IPv4 or IPv6 socket. /// + /// This is the value passed to the constructor. + /// /// Equivalent to the SO_DOMAIN socket option. @since(version = 0.3.0) address-family: func() -> ip-address-family; @@ -677,6 +679,8 @@ interface types { /// Whether this is a IPv4 or IPv6 socket. /// + /// This is the value passed to the constructor. + /// /// Equivalent to the SO_DOMAIN socket option. @since(version = 0.3.0) address-family: func() -> ip-address-family; From 4197b06e7e73e27ed8ac58a520518a6f87628ae7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 21 Jan 2025 12:46:35 -0800 Subject: [PATCH 1582/1772] Revise the documentation for WASI 0.3.0's `tcp-socket::receive`. `receive` no longer returns its own `result`, so update the text that says it fails if `receive` has already been called. Instead say that a new stream that immediately fails is returned. And, be specific about how the `stream` and the `future` to say that either both succeed or both fail. This eliminates ambiguity about whether the `stream` could report a failure independently of the `future`. --- proposals/sockets/wit-0.3.0-draft/types.wit | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index c20954db0..b5f84d360 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -313,11 +313,19 @@ interface types { /// Read data from peer. /// - /// This function fails if `receive` was already called before on this connection. - /// - /// On success, this function returns a stream and a future, which will resolve - /// to an error code if receiving data from stream fails. - /// The returned future resolves to success if receiving side of the connection is closed. + /// This function returns a `stream` which provides the data received from the + /// socket, and a `future` providing additional error information in case the + /// socket is closed abnormally. + /// + /// If the socket is closed normally, `stream.read` on the `stream` will return + /// `read-status::closed` with no `error-context` and the future resolves to + /// the value `ok`. If the socket is closed abnormally, `stream.read` on the + /// `stream` returns `read-status::closed` with an `error-context` and the future + /// resolves to `err` with an `error-code`. + /// + /// `receive` is meant to be called only once per socket. If it is called more + /// than once, the subsequent calls return a new `stream` that fails as if it + /// were closed abnormally. /// /// If the caller is not expecting to receive any data from the peer, /// they may cancel the receive task. Any data still in the receive queue From 8f3e1ea1909f54cc946f557b86eaeabb1d404b8e Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 24 Jan 2025 02:18:31 +0100 Subject: [PATCH 1583/1772] chore(0.3.0-draft): update `wasi:{clocks,random}` to `0.3.0` (#142) * ci: update `wit-deps` to 0.5.0 Signed-off-by: Roman Volosatovs * chore(0.3): update `wasi:clocks` to `0.3.0` Signed-off-by: Roman Volosatovs * chore(0.3): update `wasi:random` to `0.3.0` Signed-off-by: Roman Volosatovs --------- Signed-off-by: Roman Volosatovs --- proposals/http/.github/workflows/main.yml | 3 +- proposals/http/wit-0.3.0-draft/deps.lock | 40 ++++++++------ proposals/http/wit-0.3.0-draft/deps.toml | 10 +--- .../deps/clocks-0-3-0/monotonic-clock.wit | 45 +++++++++++++++ .../deps/clocks-0-3-0/timezone.wit | 55 +++++++++++++++++++ .../deps/clocks-0-3-0/wall-clock.wit | 46 ++++++++++++++++ .../deps/clocks-0-3-0/world.wit | 11 ++++ .../deps/filesystem/preopens.wit | 2 +- .../wit-0.3.0-draft/deps/filesystem/types.wit | 10 +--- .../http/wit-0.3.0-draft/deps/io/streams.wit | 4 ++ .../deps/random-0-3-0/insecure-seed.wit | 27 +++++++++ .../deps/random-0-3-0/insecure.wit | 25 +++++++++ .../deps/random-0-3-0/random.wit | 29 ++++++++++ .../deps/random-0-3-0/world.wit | 13 +++++ .../deps/sockets/ip-name-lookup.wit | 2 +- .../wit-0.3.0-draft/deps/sockets/network.wit | 16 ++++++ .../http/wit-0.3.0-draft/deps/sockets/tcp.wit | 2 +- .../http/wit-0.3.0-draft/deps/sockets/udp.wit | 6 +- proposals/http/wit-0.3.0-draft/proxy.wit | 4 +- proposals/http/wit-0.3.0-draft/types.wit | 2 +- 20 files changed, 311 insertions(+), 41 deletions(-) create mode 100644 proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/monotonic-clock.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/timezone.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/wall-clock.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/world.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure-seed.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/random-0-3-0/random.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/random-0-3-0/world.wit diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index a4336b25f..09d983612 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -13,9 +13,10 @@ jobs: - uses: actions/checkout@v4 - name: ensure `./wit/deps` are in sync run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.2/wit-deps-x86_64-unknown-linux-musl + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.5.0/wit-deps-x86_64-unknown-linux-musl chmod +x ./wit-deps ./wit-deps lock --check + ./wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps lock --check - uses: WebAssembly/wit-abi-up-to-date@v22 with: wasm-tools: '1.223.0' diff --git a/proposals/http/wit-0.3.0-draft/deps.lock b/proposals/http/wit-0.3.0-draft/deps.lock index a12064a91..43e3f8ce5 100644 --- a/proposals/http/wit-0.3.0-draft/deps.lock +++ b/proposals/http/wit-0.3.0-draft/deps.lock @@ -1,29 +1,37 @@ [cli] -url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -sha256 = "1de50b8e6940e73110cda10b7f90ca87a8fea886f0fa36c748f96dc70671ee38" -sha512 = "bbb6cd3e7b4d3237b6af9bfbb2633ccd2c4ea2a4f37b8c033255c7e0c1cb037be7f22ec1f8ca792cc8ec1942199582943979e646b4b272b85dcff7654eac51d0" +url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.3.tar.gz" +sha256 = "4dadd13d55aaf626833d1f4b9c34a17b0f04e993babd09552b785cda3b95ea76" +sha512 = "898dcc4e8c15d18acc6b88dbe232336fa4d19019430a910dbc9e7aeaace3077a164af3be9f002de6e7e65ef693df340801ac0c7e421e9a746bf1b6d698a90835" +deps = ["clocks", "filesystem", "io", "random", "sockets"] [clocks] +sha256 = "93a701968a7dd3c5d69031bc0601681c468972fdf7e28a93bb6150a67d6ebe8b" +sha512 = "98fca567c7a01887b0fb38981f1772169b6ea8de475b546508f8b86738d84e44ba95cae81def40ac34e8809f5f60e85224077ab8cb6d6d5d6296acc1df73c159" + +[clocks-0-3-0] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "ea9d69ee803bc176e23e5268f5e24a2ac485dd1f62a0ab4c748e9d3f901f576f" -sha512 = "5efc22927c46cd56c41e5549ec775561c7fac2ea0d365abc0b55396d9475a7c9f984077a81f84a44a726f1c008fd2fadbffffa4fa53ecd5fbfd05afd379ab428" +subdir = "wit-0.3.0-draft" +sha256 = "26e315db0d371495f8834edfc0e479042f94152ce677d96d54d3623d0e4ffb1e" +sha512 = "e1c76f499435841316f9287b88d8173558e64f277c321ff390556de8707a0b18dd6c1749bbb17bbbba8d523da246ef6eb05c990ceddb762e03efb2ae30cacc76" [filesystem] -url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sha256 = "cfe8c420e8b857de612ae2a3336680dae16b95c93c8ba3a6ff05b21210966740" -sha512 = "3c00c5544a58658e3e8025677091685286027fd49f37abf198c30b4e83b9e68f19723975aaa98794fba9f425ae9ef4f3dc0f5b9cf59203b5ecfaadf62b296f9a" +sha256 = "69d42fb10a04a33545b17e055f13db9b1e10e82ba0ed5bdb52334e40dc07c679" +sha512 = "612effbac6f4804fe0c29dae20b78bbba59e52cb754c15402f5fe229c3153a221e0fbdff1d9d00ceaa3fe049c6a95523a5b99f772f1c16d972eade2c88326a30" [io] -url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "2a74bd811adc46b5a0f19827ddbde89870e52b17615f4d0873f06fd977250caf" -sha512 = "94624f00c66e66203592cee820f80b1ba91ecdb71f682c154f25eaf71f8d8954197dcb64503bc21e72ed5e812af7eae876df47b7eb727b02db3a74a7ce0aefca" +sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" +sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" [random] +sha256 = "dd0c91e7125172eb8fd4568e15ad9fc7305643015e6ece4396c3cc5e8c2bf79a" +sha512 = "d1ca2e7b0616a94a3b39d1b9450bb3fb595b01fd94a8626ad75433038dde40988ecb41ab93a374d569ab72163af3b30038d7bfc3499b9c07193181f4f1d9292a" + +[random-0-3-0] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -sha256 = "9e2d5056186f81b2e7f96bc97d2babd0341840f6abb4f170449b70992f1b598f" -sha512 = "67bf41d8d5d4b7af084124ee85196585225785969059f59e2f9ddb77ac1a8095cfe811ae29d076aac817418fa01064d7b9fbc0233930bace680758eeb21e36f8" +subdir = "wit-0.3.0-draft" +sha256 = "f14fa20b4a1ab8e93adc6aa81175b886c951a75ea8fe36f94902bd31c3b709da" +sha512 = "fea98fb83f997e436457652a9f11b911fabd7a904fcce52fc8dcd5c5746609d6329b3992570c12d04b6b0e09427674805f4a563cde90a4af014fe0915178e189" [sockets] -url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" -sha256 = "4c361137a7e61e8b9a73da2a0899dd9ad1a0c2dfee7d310cf168704c57b7a07c" -sha512 = "348b4ef381f57aec23d48537df8b69ab8963587dcb056e94c4cd5657e217677a4ee2a545868a5c829d2334cc6b8b0a61d3e72797999f44d78553fbd3a73c5b8d" +sha256 = "2bc0f65a8046207ee3330ad7d63f6fafeafd4cc0ea4084f081bd5e4f7b177e74" +sha512 = "3e5490e41547dffa78d52631825d93da8d60f4af0246cbaf97e1ecb879285953a86d5f1f390b10c32f91dd7eaec6f43e625a26b1c92c32a0c86fde428aedaaab" diff --git a/proposals/http/wit-0.3.0-draft/deps.toml b/proposals/http/wit-0.3.0-draft/deps.toml index dd738ac4c..772bb1be3 100644 --- a/proposals/http/wit-0.3.0-draft/deps.toml +++ b/proposals/http/wit-0.3.0-draft/deps.toml @@ -1,7 +1,3 @@ -io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -cli = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -# not used by http/proxy, but included to allow full contents of wasi-cli to validate -filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sockets = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" +cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.3.tar.gz" # TODO: update to v0.3.0-draft and remove custom clock and random imports +clocks-0-3-0 = { url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz", subdir = "wit-0.3.0-draft" } +random-0-3-0 = { url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz", subdir = "wit-0.3.0-draft" } diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/monotonic-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/monotonic-clock.wit new file mode 100644 index 000000000..87ebdaac5 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/monotonic-clock.wit @@ -0,0 +1,45 @@ +package wasi:clocks@0.3.0; +/// WASI Monotonic Clock is a clock API intended to let users measure elapsed +/// time. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A monotonic clock is a clock which has an unspecified initial value, and +/// successive reads of the clock will produce non-decreasing values. +@since(version = 0.3.0) +interface monotonic-clock { + /// An instant in time, in nanoseconds. An instant is relative to an + /// unspecified initial value, and can only be compared to instances from + /// the same monotonic-clock. + @since(version = 0.3.0) + type instant = u64; + + /// A duration of time, in nanoseconds. + @since(version = 0.3.0) + type duration = u64; + + /// Read the current value of the clock. + /// + /// The clock is monotonic, therefore calling this function repeatedly will + /// produce a sequence of non-decreasing values. + @since(version = 0.3.0) + now: func() -> instant; + + /// Query the resolution of the clock. Returns the duration of time + /// corresponding to a clock tick. + @since(version = 0.3.0) + resolution: func() -> duration; + + /// Wait until the specified instant has occurred. + @since(version = 0.3.0) + wait-until: func( + when: instant, + ); + + /// Wait for the specified duration has elapsed. + @since(version = 0.3.0) + wait-for: func( + how-long: duration, + ); +} diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/timezone.wit b/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/timezone.wit new file mode 100644 index 000000000..ac9146834 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/timezone.wit @@ -0,0 +1,55 @@ +package wasi:clocks@0.3.0; + +@unstable(feature = clocks-timezone) +interface timezone { + @unstable(feature = clocks-timezone) + use wall-clock.{datetime}; + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + @unstable(feature = clocks-timezone) + display: func(when: datetime) -> timezone-display; + + /// The same as `display`, but only return the UTC offset. + @unstable(feature = clocks-timezone) + utc-offset: func(when: datetime) -> s32; + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + @unstable(feature = clocks-timezone) + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/wall-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/wall-clock.wit new file mode 100644 index 000000000..b7a85ab35 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/wall-clock.wit @@ -0,0 +1,46 @@ +package wasi:clocks@0.3.0; +/// WASI Wall Clock is a clock API intended to let users query the current +/// time. The name "wall" makes an analogy to a "clock on the wall", which +/// is not necessarily monotonic as it may be reset. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A wall clock is a clock which measures the date and time according to +/// some external reference. +/// +/// External references may be reset, so this clock is not necessarily +/// monotonic, making it unsuitable for measuring elapsed time. +/// +/// It is intended for reporting the current date and time for humans. +@since(version = 0.3.0) +interface wall-clock { + /// A time and date in seconds plus nanoseconds. + @since(version = 0.3.0) + record datetime { + seconds: u64, + nanoseconds: u32, + } + + /// Read the current value of the clock. + /// + /// This clock is not monotonic, therefore calling this function repeatedly + /// will not necessarily produce a sequence of non-decreasing values. + /// + /// The returned timestamps represent the number of seconds since + /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], + /// also known as [Unix Time]. + /// + /// The nanoseconds field of the output is always less than 1000000000. + /// + /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + @since(version = 0.3.0) + now: func() -> datetime; + + /// Query the resolution of the clock. + /// + /// The nanoseconds field of the output is always less than 1000000000. + @since(version = 0.3.0) + resolution: func() -> datetime; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/world.wit b/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/world.wit new file mode 100644 index 000000000..f97bcfef1 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/world.wit @@ -0,0 +1,11 @@ +package wasi:clocks@0.3.0; + +@since(version = 0.3.0) +world imports { + @since(version = 0.3.0) + import monotonic-clock; + @since(version = 0.3.0) + import wall-clock; + @unstable(feature = clocks-timezone) + import timezone; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit index 4bc202e9c..cea97495b 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit @@ -5,7 +5,7 @@ interface preopens { @since(version = 0.2.0) use types.{descriptor}; - /// Return the set of preopened directories, and their path. + /// Return the set of preopened directories, and their paths. @since(version = 0.2.0) get-directories: func() -> list>; } diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit index 826acd1c4..d229a21f4 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit @@ -327,7 +327,7 @@ interface types { /// May fail with an error-code describing why the file cannot be appended. /// /// Note: This allows using `write-stream`, which is similar to `write` with - /// `O_APPEND` in in POSIX. + /// `O_APPEND` in POSIX. @since(version = 0.2.0) append-via-stream: func() -> result; @@ -523,12 +523,6 @@ interface types { /// Open a file or directory. /// - /// The returned descriptor is not guaranteed to be the lowest-numbered - /// descriptor not currently open/ it is randomized to prevent applications - /// from depending on making assumptions about indexes, since this is - /// error-prone in multi-threaded contexts. The returned descriptor is - /// guaranteed to be less than 2**31. - /// /// If `flags` contains `descriptor-flags::mutate-directory`, and the base /// descriptor doesn't have `descriptor-flags::mutate-directory` set, /// `open-at` fails with `error-code::read-only`. @@ -629,7 +623,7 @@ interface types { /// replaced. It may also include a secret value chosen by the /// implementation and not otherwise exposed. /// - /// Implementations are encourated to provide the following properties: + /// Implementations are encouraged to provide the following properties: /// /// - If the file is not modified or replaced, the computed hash value should /// usually not change. diff --git a/proposals/http/wit-0.3.0-draft/deps/io/streams.wit b/proposals/http/wit-0.3.0-draft/deps/io/streams.wit index c441d77b2..0de084629 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/streams.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/streams.wit @@ -18,6 +18,9 @@ interface streams { /// The last operation (a write or flush) failed before completion. /// /// More information is available in the `error` payload. + /// + /// After this, the stream will be closed. All future operations return + /// `stream-error::closed`. last-operation-failed(error), /// The stream is closed: no more input will be accepted by the /// stream. A closed output-stream will return this error on all @@ -205,6 +208,7 @@ interface streams { /// The created `pollable` is a child resource of the `output-stream`. /// Implementations may trap if the `output-stream` is dropped before /// all derived `pollable`s created with this function are dropped. + @since(version = 0.2.0) subscribe: func() -> pollable; /// Write zeroes to a stream. diff --git a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure-seed.wit b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure-seed.wit new file mode 100644 index 000000000..66a469432 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure-seed.wit @@ -0,0 +1,27 @@ +package wasi:random@0.3.0; +/// The insecure-seed interface for seeding hash-map DoS resistance. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +@since(version = 0.2.0) +interface insecure-seed { + /// Return a 128-bit value that may contain a pseudo-random value. + /// + /// The returned value is not required to be computed from a CSPRNG, and may + /// even be entirely deterministic. Host implementations are encouraged to + /// provide pseudo-random values to any program exposed to + /// attacker-controlled content, to enable DoS protection built into many + /// languages' hash-map implementations. + /// + /// This function is intended to only be called once, by a source language + /// to initialize Denial Of Service (DoS) protection in its hash-map + /// implementation. + /// + /// # Expected future evolution + /// + /// This will likely be changed to a value import, to prevent it from being + /// called multiple times and potentially used for purposes other than DoS + /// protection. + @since(version = 0.2.0) + insecure-seed: func() -> tuple; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure.wit b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure.wit new file mode 100644 index 000000000..7f2b86fbe --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure.wit @@ -0,0 +1,25 @@ +package wasi:random@0.3.0; +/// The insecure interface for insecure pseudo-random numbers. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +@since(version = 0.2.0) +interface insecure { + /// Return `len` insecure pseudo-random bytes. + /// + /// This function is not cryptographically secure. Do not use it for + /// anything related to security. + /// + /// There are no requirements on the values of the returned bytes, however + /// implementations are encouraged to return evenly distributed values with + /// a long period. + @since(version = 0.2.0) + get-insecure-random-bytes: func(len: u64) -> list; + + /// Return an insecure pseudo-random `u64` value. + /// + /// This function returns the same type of pseudo-random data as + /// `get-insecure-random-bytes`, represented as a `u64`. + @since(version = 0.2.0) + get-insecure-random-u64: func() -> u64; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/random.wit b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/random.wit new file mode 100644 index 000000000..5edfa2baa --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/random.wit @@ -0,0 +1,29 @@ +package wasi:random@0.3.0; +/// WASI Random is a random data API. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +@since(version = 0.2.0) +interface random { + /// Return `len` cryptographically-secure random or pseudo-random bytes. + /// + /// This function must produce data at least as cryptographically secure and + /// fast as an adequately seeded cryptographically-secure pseudo-random + /// number generator (CSPRNG). It must not block, from the perspective of + /// the calling program, under any circumstances, including on the first + /// request and on requests for numbers of bytes. The returned data must + /// always be unpredictable. + /// + /// This function must always return fresh data. Deterministic environments + /// must omit this function, rather than implementing it with deterministic + /// data. + @since(version = 0.2.0) + get-random-bytes: func(len: u64) -> list; + + /// Return a cryptographically-secure random or pseudo-random `u64` value. + /// + /// This function returns the same type of data as `get-random-bytes`, + /// represented as a `u64`. + @since(version = 0.2.0) + get-random-u64: func() -> u64; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/world.wit b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/world.wit new file mode 100644 index 000000000..d01746d1e --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/world.wit @@ -0,0 +1,13 @@ +package wasi:random@0.3.0; + +@since(version = 0.2.0) +world imports { + @since(version = 0.2.0) + import random; + + @since(version = 0.2.0) + import insecure; + + @since(version = 0.2.0) + import insecure-seed; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit index 6b87a0a98..c1d8a47c1 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit @@ -48,7 +48,7 @@ interface ip-name-lookup { /// Create a `pollable` which will resolve once the stream is ready for I/O. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit index 8c13b348e..f3f60a370 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit @@ -1,5 +1,8 @@ @since(version = 0.2.0) interface network { + @unstable(feature = network-error-code) + use wasi:io/error@0.2.3.{error}; + /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. @@ -105,6 +108,19 @@ interface network { permanent-resolver-failure, } + /// Attempts to extract a network-related `error-code` from the stream + /// `error` provided. + /// + /// Stream operations which return `stream-error::last-operation-failed` + /// have a payload with more information about the operation that failed. + /// This payload can be passed through to this function to see if there's + /// network-related information about the error to return. + /// + /// Note that this function is fallible because not all stream-related + /// errors are network-related errors. + @unstable(feature = network-error-code) + network-error-code: func(err: borrow) -> option; + @since(version = 0.2.0) enum ip-address-family { /// Similar to `AF_INET` in POSIX. diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit index 3a86f5ee0..b4cd87fce 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit @@ -353,7 +353,7 @@ interface tcp { /// See /// for more information. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit index 357d1d555..01901ca27 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit @@ -184,7 +184,7 @@ interface udp { /// Create a `pollable` which will resolve once the socket is ready for I/O. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; @@ -220,7 +220,7 @@ interface udp { /// Create a `pollable` which will resolve once the stream is ready to receive again. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; @@ -280,7 +280,7 @@ interface udp { /// Create a `pollable` which will resolve once the stream is ready to send again. /// - /// Note: this function is here for WASI Preview2 only. + /// Note: this function is here for WASI 0.2 only. /// It's planned to be removed when `future` is natively supported in Preview3. @since(version = 0.2.0) subscribe: func() -> pollable; diff --git a/proposals/http/wit-0.3.0-draft/proxy.wit b/proposals/http/wit-0.3.0-draft/proxy.wit index f39199249..8e10fd789 100644 --- a/proposals/http/wit-0.3.0-draft/proxy.wit +++ b/proposals/http/wit-0.3.0-draft/proxy.wit @@ -4,8 +4,8 @@ package wasi:http@0.3.0-draft; /// It is intended to be `include`d in other worlds. world imports { /// HTTP proxies have access to time and randomness. - include wasi:clocks/imports@0.2.3; - import wasi:random/random@0.2.3; + include wasi:clocks/imports@0.3.0; + import wasi:random/random@0.3.0; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index f2ed3a513..852130226 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -1,7 +1,7 @@ /// This interface defines all of the types and methods for implementing HTTP /// Requests and Responses, as well as their headers, trailers, and bodies. interface types { - use wasi:clocks/monotonic-clock@0.2.3.{duration}; + use wasi:clocks/monotonic-clock@0.3.0.{duration}; use wasi:io/error@0.2.3.{error}; /// This type corresponds to HTTP standard Methods. From 55c7ef56565185b84d494e4264436c29b58eb351 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 28 Jan 2025 21:08:14 +0100 Subject: [PATCH 1584/1772] feat(0.3): rework stream error handling (#143) Signed-off-by: Roman Volosatovs --- proposals/http/wit-0.3.0-draft/types.wit | 27 ++++++++++-------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index 852130226..d720fbed5 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -2,7 +2,6 @@ /// Requests and Responses, as well as their headers, trailers, and bodies. interface types { use wasi:clocks/monotonic-clock@0.3.0.{duration}; - use wasi:io/error@0.2.3.{error}; /// This type corresponds to HTTP standard Methods. variant method { @@ -92,18 +91,6 @@ interface types { field-size: option } - /// Attempts to extract a http-related `error-code` from the stream `error` - /// provided. - /// - /// Stream operations may fail with a stream `error` with more information - /// about the operation that failed. This `error` can be passed to this - /// function to see if there's http-related information about the error to - /// return. - /// - /// Note that this function is fallible because not all stream errors are - /// http-related errors. - http-error-code: func(err: borrow) -> option; - /// This type enumerates the different kinds of errors that may occur when /// setting or appending to a `fields` resource. variant header-error { @@ -254,16 +241,24 @@ interface types { resource body { /// Construct a new `body` with the specified stream and trailers. - constructor( + /// This function returns a future, which will resolve + /// to an error code if transmitting stream data or trailers fails. + /// The returned future resolves to success once body stream and trailers + /// are fully transmitted. + new: static func( %stream: stream, trailers: option> - ); + ) -> tuple>>; /// Returns the contents of the body, as a stream of bytes. /// /// This function may be called multiple times as long as any `stream`s /// returned by previous calls have been dropped first. - %stream: func() -> result>; + /// + /// On success, this function returns a stream and a future, which will resolve + /// to an error code if receiving data from stream fails. + /// The returned future resolves to success if body is closed. + %stream: func() -> result>, future>>; /// Takes ownership of `body`, and returns a `trailers`. This function will /// trap if a `stream` child is still alive. From 8a6e2436d453b12c0856a47f9ccfdf16e8994d87 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 17 Jan 2025 11:22:49 +0100 Subject: [PATCH 1585/1772] chore: remove redundant `deps.toml` entries Signed-off-by: Roman Volosatovs --- proposals/http/wit/deps.lock | 8 ++------ proposals/http/wit/deps.toml | 8 +------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 935a1971f..24a22f6d7 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,29 +1,25 @@ [cli] -url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" +url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.3.tar.gz" sha256 = "4dadd13d55aaf626833d1f4b9c34a17b0f04e993babd09552b785cda3b95ea76" sha512 = "898dcc4e8c15d18acc6b88dbe232336fa4d19019430a910dbc9e7aeaace3077a164af3be9f002de6e7e65ef693df340801ac0c7e421e9a746bf1b6d698a90835" +deps = ["clocks", "filesystem", "io", "random", "sockets"] [clocks] -url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" sha256 = "93a701968a7dd3c5d69031bc0601681c468972fdf7e28a93bb6150a67d6ebe8b" sha512 = "98fca567c7a01887b0fb38981f1772169b6ea8de475b546508f8b86738d84e44ba95cae81def40ac34e8809f5f60e85224077ab8cb6d6d5d6296acc1df73c159" [filesystem] -url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" sha256 = "69d42fb10a04a33545b17e055f13db9b1e10e82ba0ed5bdb52334e40dc07c679" sha512 = "612effbac6f4804fe0c29dae20b78bbba59e52cb754c15402f5fe229c3153a221e0fbdff1d9d00ceaa3fe049c6a95523a5b99f772f1c16d972eade2c88326a30" [io] -url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" [random] -url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" sha256 = "dd0c91e7125172eb8fd4568e15ad9fc7305643015e6ece4396c3cc5e8c2bf79a" sha512 = "d1ca2e7b0616a94a3b39d1b9450bb3fb595b01fd94a8626ad75433038dde40988ecb41ab93a374d569ab72163af3b30038d7bfc3499b9c07193181f4f1d9292a" [sockets] -url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" sha256 = "2bc0f65a8046207ee3330ad7d63f6fafeafd4cc0ea4084f081bd5e4f7b177e74" sha512 = "3e5490e41547dffa78d52631825d93da8d60f4af0246cbaf97e1ecb879285953a86d5f1f390b10c32f91dd7eaec6f43e625a26b1c92c32a0c86fde428aedaaab" diff --git a/proposals/http/wit/deps.toml b/proposals/http/wit/deps.toml index dd738ac4c..fbadb972d 100644 --- a/proposals/http/wit/deps.toml +++ b/proposals/http/wit/deps.toml @@ -1,7 +1 @@ -io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -cli = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" -random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -# not used by http/proxy, but included to allow full contents of wasi-cli to validate -filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sockets = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" +cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.3.tar.gz" From d8a20d19fc2cfa1216efd784879f44199564025e Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 5 Feb 2025 00:44:15 +0100 Subject: [PATCH 1586/1772] feat: add `wasi-0.3.0` draft (#164) * feat: add `wasi-0.3.0` draft Followed the example of `wasi-http` and `wasi-clocks` duplicating the package in a subdirectory - Remove `would-block` error code - Replace `wasi:io/error.error` usage by `error-context` - Replace `wasi:io/streams.input-stream` return values by `stream` in return position - Replace `wasi:io/streams.output-stream` return values by `stream` in parameter position - Guests should be able to rely on `stream.new` to construct streams - Merge `read{,via-stream}` into a singular `read`. Both functions take an offset as a parameter and since they now return `stream`, callers can limit the amount of bytes read by using the `stream` directly, therefore functionality of both is identical - Merge `write{,via-stream}` into a singular `write`. Both functions take an offset and `stream` as a parameter. It is assumed that `error-context` returned by writes to the stream and reads from the stream are sufficient for error handling. Signed-off-by: Roman Volosatovs * refactor: avoid introspecting `error-context` This seems to be better aligned with latest specification on error context https://github.com/WebAssembly/component-model/blob/cbdd15d9033446558571824af52a78022aaa3f58/design/mvp/Explainer.md#error-context-type > A consequence of this, however, is that components *must not* depend on the > contents of `error-context` values for behavioral correctness. In particular, > case analysis of the contents of an `error-context` should not determine > *error recovery*; explicit `result` or `variant` types must be used in the > function return type instead (e.g., > `(func (result (tuple (stream u8) (future $my-error)))`). Signed-off-by: Roman Volosatovs * chore: bump `@since` to `0.3.0` https://github.com/WebAssembly/wasi-filesystem/pull/164#discussion_r1914946117 Signed-off-by: Roman Volosatovs * refactor(0.3): simplify error handling Signed-off-by: Roman Volosatovs * refactor(0.3): asyncify `read-directory` Signed-off-by: Roman Volosatovs * feat: update wit-deps to 0.5.0 Signed-off-by: Roman Volosatovs * drop `-draft` version suffix This ensures that e.g.: ``` wit-bindgen markdown wit-0.3.0-draft -w imports --html-in-md ``` works with wit-bindgen 0.37 refs: https://github.com/WebAssembly/wasi-sockets/commit/3abda6e0bccd1743fa0736c94e5fbb3ec2fb0eaf refs: https://github.com/WebAssembly/wasi-sockets/pull/111#issuecomment-2596214201 Signed-off-by: Roman Volosatovs --------- Signed-off-by: Roman Volosatovs --- .../filesystem/.github/workflows/main.yml | 4 +- .../filesystem/wit-0.3.0-draft/deps.lock | 5 + .../filesystem/wit-0.3.0-draft/deps.toml | 1 + .../deps/clocks/monotonic-clock.wit | 45 ++ .../wit-0.3.0-draft/deps/clocks/timezone.wit | 55 ++ .../deps/clocks/wall-clock.wit | 46 ++ .../wit-0.3.0-draft/deps/clocks/world.wit | 11 + .../filesystem/wit-0.3.0-draft/preopens.wit | 11 + .../filesystem/wit-0.3.0-draft/types.wit | 625 ++++++++++++++++++ .../filesystem/wit-0.3.0-draft/world.wit | 9 + 10 files changed, 811 insertions(+), 1 deletion(-) create mode 100644 proposals/filesystem/wit-0.3.0-draft/deps.lock create mode 100644 proposals/filesystem/wit-0.3.0-draft/deps.toml create mode 100644 proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit create mode 100644 proposals/filesystem/wit-0.3.0-draft/deps/clocks/timezone.wit create mode 100644 proposals/filesystem/wit-0.3.0-draft/deps/clocks/wall-clock.wit create mode 100644 proposals/filesystem/wit-0.3.0-draft/deps/clocks/world.wit create mode 100644 proposals/filesystem/wit-0.3.0-draft/preopens.wit create mode 100644 proposals/filesystem/wit-0.3.0-draft/types.wit create mode 100644 proposals/filesystem/wit-0.3.0-draft/world.wit diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index d42ff77d1..db3a34490 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -13,10 +13,12 @@ jobs: - uses: actions/checkout@v4 - name: ensure `./wit/deps` are in sync run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.3/wit-deps-x86_64-unknown-linux-musl + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.5.0/wit-deps-x86_64-unknown-linux-musl chmod +x wit-deps ./wit-deps lock + ./wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps lock git add -N wit/deps + git add -N wit-0.3.0-draft/deps git diff --exit-code - uses: WebAssembly/wit-abi-up-to-date@v22 with: diff --git a/proposals/filesystem/wit-0.3.0-draft/deps.lock b/proposals/filesystem/wit-0.3.0-draft/deps.lock new file mode 100644 index 000000000..03868084d --- /dev/null +++ b/proposals/filesystem/wit-0.3.0-draft/deps.lock @@ -0,0 +1,5 @@ +[clocks] +url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" +subdir = "wit-0.3.0-draft" +sha256 = "26e315db0d371495f8834edfc0e479042f94152ce677d96d54d3623d0e4ffb1e" +sha512 = "e1c76f499435841316f9287b88d8173558e64f277c321ff390556de8707a0b18dd6c1749bbb17bbbba8d523da246ef6eb05c990ceddb762e03efb2ae30cacc76" diff --git a/proposals/filesystem/wit-0.3.0-draft/deps.toml b/proposals/filesystem/wit-0.3.0-draft/deps.toml new file mode 100644 index 000000000..e00454742 --- /dev/null +++ b/proposals/filesystem/wit-0.3.0-draft/deps.toml @@ -0,0 +1 @@ +clocks = { url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz", subdir = "wit-0.3.0-draft" } diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit new file mode 100644 index 000000000..87ebdaac5 --- /dev/null +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -0,0 +1,45 @@ +package wasi:clocks@0.3.0; +/// WASI Monotonic Clock is a clock API intended to let users measure elapsed +/// time. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A monotonic clock is a clock which has an unspecified initial value, and +/// successive reads of the clock will produce non-decreasing values. +@since(version = 0.3.0) +interface monotonic-clock { + /// An instant in time, in nanoseconds. An instant is relative to an + /// unspecified initial value, and can only be compared to instances from + /// the same monotonic-clock. + @since(version = 0.3.0) + type instant = u64; + + /// A duration of time, in nanoseconds. + @since(version = 0.3.0) + type duration = u64; + + /// Read the current value of the clock. + /// + /// The clock is monotonic, therefore calling this function repeatedly will + /// produce a sequence of non-decreasing values. + @since(version = 0.3.0) + now: func() -> instant; + + /// Query the resolution of the clock. Returns the duration of time + /// corresponding to a clock tick. + @since(version = 0.3.0) + resolution: func() -> duration; + + /// Wait until the specified instant has occurred. + @since(version = 0.3.0) + wait-until: func( + when: instant, + ); + + /// Wait for the specified duration has elapsed. + @since(version = 0.3.0) + wait-for: func( + how-long: duration, + ); +} diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/timezone.wit new file mode 100644 index 000000000..ac9146834 --- /dev/null +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -0,0 +1,55 @@ +package wasi:clocks@0.3.0; + +@unstable(feature = clocks-timezone) +interface timezone { + @unstable(feature = clocks-timezone) + use wall-clock.{datetime}; + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + @unstable(feature = clocks-timezone) + display: func(when: datetime) -> timezone-display; + + /// The same as `display`, but only return the UTC offset. + @unstable(feature = clocks-timezone) + utc-offset: func(when: datetime) -> s32; + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + @unstable(feature = clocks-timezone) + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/wall-clock.wit new file mode 100644 index 000000000..b7a85ab35 --- /dev/null +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -0,0 +1,46 @@ +package wasi:clocks@0.3.0; +/// WASI Wall Clock is a clock API intended to let users query the current +/// time. The name "wall" makes an analogy to a "clock on the wall", which +/// is not necessarily monotonic as it may be reset. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A wall clock is a clock which measures the date and time according to +/// some external reference. +/// +/// External references may be reset, so this clock is not necessarily +/// monotonic, making it unsuitable for measuring elapsed time. +/// +/// It is intended for reporting the current date and time for humans. +@since(version = 0.3.0) +interface wall-clock { + /// A time and date in seconds plus nanoseconds. + @since(version = 0.3.0) + record datetime { + seconds: u64, + nanoseconds: u32, + } + + /// Read the current value of the clock. + /// + /// This clock is not monotonic, therefore calling this function repeatedly + /// will not necessarily produce a sequence of non-decreasing values. + /// + /// The returned timestamps represent the number of seconds since + /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], + /// also known as [Unix Time]. + /// + /// The nanoseconds field of the output is always less than 1000000000. + /// + /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + @since(version = 0.3.0) + now: func() -> datetime; + + /// Query the resolution of the clock. + /// + /// The nanoseconds field of the output is always less than 1000000000. + @since(version = 0.3.0) + resolution: func() -> datetime; +} diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/world.wit new file mode 100644 index 000000000..f97bcfef1 --- /dev/null +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/world.wit @@ -0,0 +1,11 @@ +package wasi:clocks@0.3.0; + +@since(version = 0.3.0) +world imports { + @since(version = 0.3.0) + import monotonic-clock; + @since(version = 0.3.0) + import wall-clock; + @unstable(feature = clocks-timezone) + import timezone; +} diff --git a/proposals/filesystem/wit-0.3.0-draft/preopens.wit b/proposals/filesystem/wit-0.3.0-draft/preopens.wit new file mode 100644 index 000000000..0b29aae33 --- /dev/null +++ b/proposals/filesystem/wit-0.3.0-draft/preopens.wit @@ -0,0 +1,11 @@ +package wasi:filesystem@0.3.0; + +@since(version = 0.3.0) +interface preopens { + @since(version = 0.3.0) + use types.{descriptor}; + + /// Return the set of preopened directories, and their paths. + @since(version = 0.3.0) + get-directories: func() -> list>; +} diff --git a/proposals/filesystem/wit-0.3.0-draft/types.wit b/proposals/filesystem/wit-0.3.0-draft/types.wit new file mode 100644 index 000000000..ba91568c0 --- /dev/null +++ b/proposals/filesystem/wit-0.3.0-draft/types.wit @@ -0,0 +1,625 @@ +package wasi:filesystem@0.3.0; +/// WASI filesystem is a filesystem API primarily intended to let users run WASI +/// programs that access their files on their existing filesystems, without +/// significant overhead. +/// +/// It is intended to be roughly portable between Unix-family platforms and +/// Windows, though it does not hide many of the major differences. +/// +/// Paths are passed as interface-type `string`s, meaning they must consist of +/// a sequence of Unicode Scalar Values (USVs). Some filesystems may contain +/// paths which are not accessible by this API. +/// +/// The directory separator in WASI is always the forward-slash (`/`). +/// +/// All paths in WASI are relative paths, and are interpreted relative to a +/// `descriptor` referring to a base directory. If a `path` argument to any WASI +/// function starts with `/`, or if any step of resolving a `path`, including +/// `..` and symbolic link steps, reaches a directory outside of the base +/// directory, or reaches a symlink to an absolute or rooted path in the +/// underlying filesystem, the function fails with `error-code::not-permitted`. +/// +/// For more information about WASI path resolution and sandboxing, see +/// [WASI filesystem path resolution]. +/// +/// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md +@since(version = 0.3.0) +interface types { + @since(version = 0.3.0) + use wasi:clocks/wall-clock@0.3.0.{datetime}; + + /// File size or length of a region within a file. + @since(version = 0.3.0) + type filesize = u64; + + /// The type of a filesystem object referenced by a descriptor. + /// + /// Note: This was called `filetype` in earlier versions of WASI. + @since(version = 0.3.0) + enum descriptor-type { + /// The type of the descriptor or file is unknown or is different from + /// any of the other types specified. + unknown, + /// The descriptor refers to a block device inode. + block-device, + /// The descriptor refers to a character device inode. + character-device, + /// The descriptor refers to a directory inode. + directory, + /// The descriptor refers to a named pipe. + fifo, + /// The file refers to a symbolic link inode. + symbolic-link, + /// The descriptor refers to a regular file inode. + regular-file, + /// The descriptor refers to a socket. + socket, + } + + /// Descriptor flags. + /// + /// Note: This was called `fdflags` in earlier versions of WASI. + @since(version = 0.3.0) + flags descriptor-flags { + /// Read mode: Data can be read. + read, + /// Write mode: Data can be written to. + write, + /// Request that writes be performed according to synchronized I/O file + /// integrity completion. The data stored in the file and the file's + /// metadata are synchronized. This is similar to `O_SYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + file-integrity-sync, + /// Request that writes be performed according to synchronized I/O data + /// integrity completion. Only the data stored in the file is + /// synchronized. This is similar to `O_DSYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + data-integrity-sync, + /// Requests that reads be performed at the same level of integrity + /// requested for writes. This is similar to `O_RSYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + requested-write-sync, + /// Mutating directories mode: Directory contents may be mutated. + /// + /// When this flag is unset on a descriptor, operations using the + /// descriptor which would create, rename, delete, modify the data or + /// metadata of filesystem objects, or obtain another handle which + /// would permit any of those, shall fail with `error-code::read-only` if + /// they would otherwise succeed. + /// + /// This may only be set on directories. + mutate-directory, + } + + /// File attributes. + /// + /// Note: This was called `filestat` in earlier versions of WASI. + @since(version = 0.3.0) + record descriptor-stat { + /// File type. + %type: descriptor-type, + /// Number of hard links to the file. + link-count: link-count, + /// For regular files, the file size in bytes. For symbolic links, the + /// length in bytes of the pathname contained in the symbolic link. + size: filesize, + /// Last data access timestamp. + /// + /// If the `option` is none, the platform doesn't maintain an access + /// timestamp for this file. + data-access-timestamp: option, + /// Last data modification timestamp. + /// + /// If the `option` is none, the platform doesn't maintain a + /// modification timestamp for this file. + data-modification-timestamp: option, + /// Last file status-change timestamp. + /// + /// If the `option` is none, the platform doesn't maintain a + /// status-change timestamp for this file. + status-change-timestamp: option, + } + + /// Flags determining the method of how paths are resolved. + @since(version = 0.3.0) + flags path-flags { + /// As long as the resolved path corresponds to a symbolic link, it is + /// expanded. + symlink-follow, + } + + /// Open flags used by `open-at`. + @since(version = 0.3.0) + flags open-flags { + /// Create file if it does not exist, similar to `O_CREAT` in POSIX. + create, + /// Fail if not a directory, similar to `O_DIRECTORY` in POSIX. + directory, + /// Fail if file already exists, similar to `O_EXCL` in POSIX. + exclusive, + /// Truncate file to size 0, similar to `O_TRUNC` in POSIX. + truncate, + } + + /// Number of hard links to an inode. + @since(version = 0.3.0) + type link-count = u64; + + /// When setting a timestamp, this gives the value to set it to. + @since(version = 0.3.0) + variant new-timestamp { + /// Leave the timestamp set to its previous value. + no-change, + /// Set the timestamp to the current time of the system clock associated + /// with the filesystem. + now, + /// Set the timestamp to the given value. + timestamp(datetime), + } + + /// A directory entry. + record directory-entry { + /// The type of the file referred to by this directory entry. + %type: descriptor-type, + + /// The name of the object. + name: string, + } + + /// Error codes returned by functions, similar to `errno` in POSIX. + /// Not all of these error codes are returned by the functions provided by this + /// API; some are used in higher-level library layers, and others are provided + /// merely for alignment with POSIX. + enum error-code { + /// Permission denied, similar to `EACCES` in POSIX. + access, + /// Connection already in progress, similar to `EALREADY` in POSIX. + already, + /// Bad descriptor, similar to `EBADF` in POSIX. + bad-descriptor, + /// Device or resource busy, similar to `EBUSY` in POSIX. + busy, + /// Resource deadlock would occur, similar to `EDEADLK` in POSIX. + deadlock, + /// Storage quota exceeded, similar to `EDQUOT` in POSIX. + quota, + /// File exists, similar to `EEXIST` in POSIX. + exist, + /// File too large, similar to `EFBIG` in POSIX. + file-too-large, + /// Illegal byte sequence, similar to `EILSEQ` in POSIX. + illegal-byte-sequence, + /// Operation in progress, similar to `EINPROGRESS` in POSIX. + in-progress, + /// Interrupted function, similar to `EINTR` in POSIX. + interrupted, + /// Invalid argument, similar to `EINVAL` in POSIX. + invalid, + /// I/O error, similar to `EIO` in POSIX. + io, + /// Is a directory, similar to `EISDIR` in POSIX. + is-directory, + /// Too many levels of symbolic links, similar to `ELOOP` in POSIX. + loop, + /// Too many links, similar to `EMLINK` in POSIX. + too-many-links, + /// Message too large, similar to `EMSGSIZE` in POSIX. + message-size, + /// Filename too long, similar to `ENAMETOOLONG` in POSIX. + name-too-long, + /// No such device, similar to `ENODEV` in POSIX. + no-device, + /// No such file or directory, similar to `ENOENT` in POSIX. + no-entry, + /// No locks available, similar to `ENOLCK` in POSIX. + no-lock, + /// Not enough space, similar to `ENOMEM` in POSIX. + insufficient-memory, + /// No space left on device, similar to `ENOSPC` in POSIX. + insufficient-space, + /// Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. + not-directory, + /// Directory not empty, similar to `ENOTEMPTY` in POSIX. + not-empty, + /// State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. + not-recoverable, + /// Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. + unsupported, + /// Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. + no-tty, + /// No such device or address, similar to `ENXIO` in POSIX. + no-such-device, + /// Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. + overflow, + /// Operation not permitted, similar to `EPERM` in POSIX. + not-permitted, + /// Broken pipe, similar to `EPIPE` in POSIX. + pipe, + /// Read-only file system, similar to `EROFS` in POSIX. + read-only, + /// Invalid seek, similar to `ESPIPE` in POSIX. + invalid-seek, + /// Text file busy, similar to `ETXTBSY` in POSIX. + text-file-busy, + /// Cross-device link, similar to `EXDEV` in POSIX. + cross-device, + } + + /// File or memory access pattern advisory information. + @since(version = 0.3.0) + enum advice { + /// The application has no advice to give on its behavior with respect + /// to the specified data. + normal, + /// The application expects to access the specified data sequentially + /// from lower offsets to higher offsets. + sequential, + /// The application expects to access the specified data in a random + /// order. + random, + /// The application expects to access the specified data in the near + /// future. + will-need, + /// The application expects that it will not access the specified data + /// in the near future. + dont-need, + /// The application expects to access the specified data once and then + /// not reuse it thereafter. + no-reuse, + } + + /// A 128-bit hash value, split into parts because wasm doesn't have a + /// 128-bit integer type. + @since(version = 0.3.0) + record metadata-hash-value { + /// 64 bits of a 128-bit hash value. + lower: u64, + /// Another 64 bits of a 128-bit hash value. + upper: u64, + } + + /// A descriptor is a reference to a filesystem object, which may be a file, + /// directory, named pipe, special file, or other object on which filesystem + /// calls may be made. + @since(version = 0.3.0) + resource descriptor { + /// Return a stream for reading from a file. + /// + /// Multiple read, write, and append streams may be active on the same open + /// file and they do not interfere with each other. + /// + /// This function returns a future, which will resolve to an error code if + /// reading full contents of the file fails. + /// + /// Note: This is similar to `pread` in POSIX. + @since(version = 0.3.0) + read-via-stream: func( + /// The offset within the file at which to start reading. + offset: filesize, + ) -> tuple, future>>; + + /// Return a stream for writing to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be written. + /// + /// It is valid to write past the end of a file; the file is extended to the + /// extent of the write, with bytes between the previous end and the start of + /// the write set to zero. + /// + /// This function returns once either full contents of the stream are + /// written or an error is encountered. + /// + /// Note: This is similar to `pwrite` in POSIX. + @since(version = 0.3.0) + write-via-stream: func( + /// Data to write + data: stream, + /// The offset within the file at which to start writing. + offset: filesize, + ) -> result<_, error-code>; + + /// Return a stream for appending to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be appended. + /// + /// This function returns once either full contents of the stream are + /// written or an error is encountered. + /// + /// Note: This is similar to `write` with `O_APPEND` in POSIX. + @since(version = 0.3.0) + append-via-stream: func(data: stream) -> result<_, error-code>; + + /// Provide file advisory information on a descriptor. + /// + /// This is similar to `posix_fadvise` in POSIX. + @since(version = 0.3.0) + advise: func( + /// The offset within the file to which the advisory applies. + offset: filesize, + /// The length of the region to which the advisory applies. + length: filesize, + /// The advice. + advice: advice + ) -> result<_, error-code>; + + /// Synchronize the data of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fdatasync` in POSIX. + @since(version = 0.3.0) + sync-data: func() -> result<_, error-code>; + + /// Get flags associated with a descriptor. + /// + /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. + /// + /// Note: This returns the value that was the `fs_flags` value returned + /// from `fdstat_get` in earlier versions of WASI. + @since(version = 0.3.0) + get-flags: func() -> result; + + /// Get the dynamic type of a descriptor. + /// + /// Note: This returns the same value as the `type` field of the `fd-stat` + /// returned by `stat`, `stat-at` and similar. + /// + /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided + /// by `fstat` in POSIX. + /// + /// Note: This returns the value that was the `fs_filetype` value returned + /// from `fdstat_get` in earlier versions of WASI. + @since(version = 0.3.0) + get-type: func() -> result; + + /// Adjust the size of an open file. If this increases the file's size, the + /// extra bytes are filled with zeros. + /// + /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. + @since(version = 0.3.0) + set-size: func(size: filesize) -> result<_, error-code>; + + /// Adjust the timestamps of an open file or directory. + /// + /// Note: This is similar to `futimens` in POSIX. + /// + /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. + @since(version = 0.3.0) + set-times: func( + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code>; + + /// Read directory entries from a directory. + /// + /// On filesystems where directories contain entries referring to themselves + /// and their parents, often named `.` and `..` respectively, these entries + /// are omitted. + /// + /// This always returns a new stream which starts at the beginning of the + /// directory. Multiple streams may be active on the same directory, and they + /// do not interfere with each other. + /// + /// This function returns a future, which will resolve to an error code if + /// reading full contents of the directory fails. + @since(version = 0.3.0) + read-directory: func() -> tuple, future>>; + + /// Synchronize the data and metadata of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fsync` in POSIX. + @since(version = 0.3.0) + sync: func() -> result<_, error-code>; + + /// Create a directory. + /// + /// Note: This is similar to `mkdirat` in POSIX. + @since(version = 0.3.0) + create-directory-at: func( + /// The relative path at which to create the directory. + path: string, + ) -> result<_, error-code>; + + /// Return the attributes of an open file or directory. + /// + /// Note: This is similar to `fstat` in POSIX, except that it does not return + /// device and inode information. For testing whether two descriptors refer to + /// the same underlying filesystem object, use `is-same-object`. To obtain + /// additional data that can be used do determine whether a file has been + /// modified, use `metadata-hash`. + /// + /// Note: This was called `fd_filestat_get` in earlier versions of WASI. + @since(version = 0.3.0) + stat: func() -> result; + + /// Return the attributes of a file or directory. + /// + /// Note: This is similar to `fstatat` in POSIX, except that it does not + /// return device and inode information. See the `stat` description for a + /// discussion of alternatives. + /// + /// Note: This was called `path_filestat_get` in earlier versions of WASI. + @since(version = 0.3.0) + stat-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result; + + /// Adjust the timestamps of a file or directory. + /// + /// Note: This is similar to `utimensat` in POSIX. + /// + /// Note: This was called `path_filestat_set_times` in earlier versions of + /// WASI. + @since(version = 0.3.0) + set-times-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to operate on. + path: string, + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code>; + + /// Create a hard link. + /// + /// Note: This is similar to `linkat` in POSIX. + @since(version = 0.3.0) + link-at: func( + /// Flags determining the method of how the path is resolved. + old-path-flags: path-flags, + /// The relative source path from which to link. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: borrow, + /// The relative destination path at which to create the hard link. + new-path: string, + ) -> result<_, error-code>; + + /// Open a file or directory. + /// + /// If `flags` contains `descriptor-flags::mutate-directory`, and the base + /// descriptor doesn't have `descriptor-flags::mutate-directory` set, + /// `open-at` fails with `error-code::read-only`. + /// + /// If `flags` contains `write` or `mutate-directory`, or `open-flags` + /// contains `truncate` or `create`, and the base descriptor doesn't have + /// `descriptor-flags::mutate-directory` set, `open-at` fails with + /// `error-code::read-only`. + /// + /// Note: This is similar to `openat` in POSIX. + @since(version = 0.3.0) + open-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the object to open. + path: string, + /// The method by which to open the file. + open-flags: open-flags, + /// Flags to use for the resulting descriptor. + %flags: descriptor-flags, + ) -> result; + + /// Read the contents of a symbolic link. + /// + /// If the contents contain an absolute or rooted path in the underlying + /// filesystem, this function fails with `error-code::not-permitted`. + /// + /// Note: This is similar to `readlinkat` in POSIX. + @since(version = 0.3.0) + readlink-at: func( + /// The relative path of the symbolic link from which to read. + path: string, + ) -> result; + + /// Remove a directory. + /// + /// Return `error-code::not-empty` if the directory is not empty. + /// + /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + @since(version = 0.3.0) + remove-directory-at: func( + /// The relative path to a directory to remove. + path: string, + ) -> result<_, error-code>; + + /// Rename a filesystem object. + /// + /// Note: This is similar to `renameat` in POSIX. + @since(version = 0.3.0) + rename-at: func( + /// The relative source path of the file or directory to rename. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: borrow, + /// The relative destination path to which to rename the file or directory. + new-path: string, + ) -> result<_, error-code>; + + /// Create a symbolic link (also known as a "symlink"). + /// + /// If `old-path` starts with `/`, the function fails with + /// `error-code::not-permitted`. + /// + /// Note: This is similar to `symlinkat` in POSIX. + @since(version = 0.3.0) + symlink-at: func( + /// The contents of the symbolic link. + old-path: string, + /// The relative destination path at which to create the symbolic link. + new-path: string, + ) -> result<_, error-code>; + + /// Unlink a filesystem object that is not a directory. + /// + /// Return `error-code::is-directory` if the path refers to a directory. + /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + @since(version = 0.3.0) + unlink-file-at: func( + /// The relative path to a file to unlink. + path: string, + ) -> result<_, error-code>; + + /// Test whether two descriptors refer to the same filesystem object. + /// + /// In POSIX, this corresponds to testing whether the two descriptors have the + /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. + /// wasi-filesystem does not expose device and inode numbers, so this function + /// may be used instead. + @since(version = 0.3.0) + is-same-object: func(other: borrow) -> bool; + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a descriptor. + /// + /// This returns a hash of the last-modification timestamp and file size, and + /// may also include the inode number, device number, birth timestamp, and + /// other metadata fields that may change when the file is modified or + /// replaced. It may also include a secret value chosen by the + /// implementation and not otherwise exposed. + /// + /// Implementations are encouraged to provide the following properties: + /// + /// - If the file is not modified or replaced, the computed hash value should + /// usually not change. + /// - If the object is modified or replaced, the computed hash value should + /// usually change. + /// - The inputs to the hash should not be easily computable from the + /// computed hash. + /// + /// However, none of these is required. + @since(version = 0.3.0) + metadata-hash: func() -> result; + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a directory descriptor and a relative path. + /// + /// This performs the same hash computation as `metadata-hash`. + @since(version = 0.3.0) + metadata-hash-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result; + } +} diff --git a/proposals/filesystem/wit-0.3.0-draft/world.wit b/proposals/filesystem/wit-0.3.0-draft/world.wit new file mode 100644 index 000000000..c0ab32afe --- /dev/null +++ b/proposals/filesystem/wit-0.3.0-draft/world.wit @@ -0,0 +1,9 @@ +package wasi:filesystem@0.3.0; + +@since(version = 0.3.0) +world imports { + @since(version = 0.3.0) + import types; + @since(version = 0.3.0) + import preopens; +} From 532b3931c7d53d1c827421de7b8ef1a1370ba1a1 Mon Sep 17 00:00:00 2001 From: SasakiSaki <192608617@qq.com> Date: Wed, 5 Feb 2025 09:30:45 +0800 Subject: [PATCH 1587/1772] Unify the format of wit files (#97) --- proposals/io/wit/poll.wit | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index 9bcbe8e03..8d74fd891 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -8,19 +8,19 @@ interface poll { @since(version = 0.2.0) resource pollable { - /// Return the readiness of a pollable. This function never blocks. - /// - /// Returns `true` when the pollable is ready, and `false` otherwise. - @since(version = 0.2.0) - ready: func() -> bool; + /// Return the readiness of a pollable. This function never blocks. + /// + /// Returns `true` when the pollable is ready, and `false` otherwise. + @since(version = 0.2.0) + ready: func() -> bool; - /// `block` returns immediately if the pollable is ready, and otherwise - /// blocks until ready. - /// - /// This function is equivalent to calling `poll.poll` on a list - /// containing only this pollable. - @since(version = 0.2.0) - block: func(); + /// `block` returns immediately if the pollable is ready, and otherwise + /// blocks until ready. + /// + /// This function is equivalent to calling `poll.poll` on a list + /// containing only this pollable. + @since(version = 0.2.0) + block: func(); } /// Poll for completion on a set of pollables. From 7f524772987774792a31bfcc34664e748260fed8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 4 Feb 2025 17:31:23 -0800 Subject: [PATCH 1588/1772] Document the `link` function's error conditions. (#165) * Document the `link` function's error conditions. Document that `link` fails if old-path doesn't exist or isn't a file, or if new-path already exists. * Autogenerate imports.md. --- proposals/filesystem/imports.md | 3 +++ proposals/filesystem/wit/types.wit | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index 03cccfbef..869a4bb5a 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -1157,6 +1157,9 @@ WASI.

                      [method]descriptor.link-at: func

                      Create a hard link.

                      +

                      Fails with error-code::no-entry if the old path does not exist, +with error-code::exist if the new path already exists, and +error-code::not-permitted if the old path is not a file.

                      Note: This is similar to linkat in POSIX.

                      Params
                        diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index d229a21f4..6ca962c48 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -508,6 +508,10 @@ interface types { /// Create a hard link. /// + /// Fails with `error-code::no-entry` if the old path does not exist, + /// with `error-code::exist` if the new path already exists, and + /// `error-code::not-permitted` if the old path is not a file. + /// /// Note: This is similar to `linkat` in POSIX. @since(version = 0.2.0) link-at: func( From 55b03a4cea9cd9382e07894029c6fb25f429b745 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 4 Feb 2025 18:49:52 -0800 Subject: [PATCH 1589/1772] Port #165 to wit-0.3.0. (#166) Port the documentation of the `link` function's error conditions added in #165 to the wit-0.3.0-draft branch. --- proposals/filesystem/wit-0.3.0-draft/types.wit | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/filesystem/wit-0.3.0-draft/types.wit b/proposals/filesystem/wit-0.3.0-draft/types.wit index ba91568c0..af3cb254c 100644 --- a/proposals/filesystem/wit-0.3.0-draft/types.wit +++ b/proposals/filesystem/wit-0.3.0-draft/types.wit @@ -482,6 +482,10 @@ interface types { /// Create a hard link. /// + /// Fails with `error-code::no-entry` if the old path does not exist, + /// with `error-code::exist` if the new path already exists, and + /// `error-code::not-permitted` if the old path is not a file. + /// /// Note: This is similar to `linkat` in POSIX. @since(version = 0.3.0) link-at: func( From 5ec10be26ff6dd97e626963ec80f449c6d8a2531 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 17 Jan 2025 12:20:42 +0100 Subject: [PATCH 1590/1772] chore: pin deps Signed-off-by: Roman Volosatovs --- proposals/cli/wit/deps.lock | 10 +++++----- proposals/cli/wit/deps.toml | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index b08adc8fe..4dd8fd96f 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,24 +1,24 @@ [clocks] -url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" +url = "https://github.com/WebAssembly/wasi-clocks/archive/v0.2.3.tar.gz" sha256 = "93a701968a7dd3c5d69031bc0601681c468972fdf7e28a93bb6150a67d6ebe8b" sha512 = "98fca567c7a01887b0fb38981f1772169b6ea8de475b546508f8b86738d84e44ba95cae81def40ac34e8809f5f60e85224077ab8cb6d6d5d6296acc1df73c159" [filesystem] -url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" +url = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.3.tar.gz" sha256 = "69d42fb10a04a33545b17e055f13db9b1e10e82ba0ed5bdb52334e40dc07c679" sha512 = "612effbac6f4804fe0c29dae20b78bbba59e52cb754c15402f5fe229c3153a221e0fbdff1d9d00ceaa3fe049c6a95523a5b99f772f1c16d972eade2c88326a30" [io] -url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" +url = "https://github.com/WebAssembly/wasi-io/archive/v0.2.3.tar.gz" sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" [random] -url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" +url = "https://github.com/WebAssembly/wasi-random/archive/v0.2.3.tar.gz" sha256 = "dd0c91e7125172eb8fd4568e15ad9fc7305643015e6ece4396c3cc5e8c2bf79a" sha512 = "d1ca2e7b0616a94a3b39d1b9450bb3fb595b01fd94a8626ad75433038dde40988ecb41ab93a374d569ab72163af3b30038d7bfc3499b9c07193181f4f1d9292a" [sockets] -url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" +url = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.3.tar.gz" sha256 = "2bc0f65a8046207ee3330ad7d63f6fafeafd4cc0ea4084f081bd5e4f7b177e74" sha512 = "3e5490e41547dffa78d52631825d93da8d60f4af0246cbaf97e1ecb879285953a86d5f1f390b10c32f91dd7eaec6f43e625a26b1c92c32a0c86fde428aedaaab" diff --git a/proposals/cli/wit/deps.toml b/proposals/cli/wit/deps.toml index bb1b2ab1b..76cc8ca00 100644 --- a/proposals/cli/wit/deps.toml +++ b/proposals/cli/wit/deps.toml @@ -1,5 +1,5 @@ -io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -random = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" -sockets = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" +clocks = "https://github.com/WebAssembly/wasi-clocks/archive/v0.2.3.tar.gz" +filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.3.tar.gz" +io = "https://github.com/WebAssembly/wasi-io/archive/v0.2.3.tar.gz" +random = "https://github.com/WebAssembly/wasi-random/archive/v0.2.3.tar.gz" +sockets = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.3.tar.gz" From ea84385bd9e9e3c082686af06685285b13d34655 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 17 Jan 2025 12:21:40 +0100 Subject: [PATCH 1591/1772] chore: remove redundant `deps.toml` entries Signed-off-by: Roman Volosatovs --- proposals/cli/wit/deps.lock | 4 ++-- proposals/cli/wit/deps.toml | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index 4dd8fd96f..889946b16 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,5 +1,4 @@ [clocks] -url = "https://github.com/WebAssembly/wasi-clocks/archive/v0.2.3.tar.gz" sha256 = "93a701968a7dd3c5d69031bc0601681c468972fdf7e28a93bb6150a67d6ebe8b" sha512 = "98fca567c7a01887b0fb38981f1772169b6ea8de475b546508f8b86738d84e44ba95cae81def40ac34e8809f5f60e85224077ab8cb6d6d5d6296acc1df73c159" @@ -7,9 +6,9 @@ sha512 = "98fca567c7a01887b0fb38981f1772169b6ea8de475b546508f8b86738d84e44ba95ca url = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.3.tar.gz" sha256 = "69d42fb10a04a33545b17e055f13db9b1e10e82ba0ed5bdb52334e40dc07c679" sha512 = "612effbac6f4804fe0c29dae20b78bbba59e52cb754c15402f5fe229c3153a221e0fbdff1d9d00ceaa3fe049c6a95523a5b99f772f1c16d972eade2c88326a30" +deps = ["clocks", "io"] [io] -url = "https://github.com/WebAssembly/wasi-io/archive/v0.2.3.tar.gz" sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" @@ -22,3 +21,4 @@ sha512 = "d1ca2e7b0616a94a3b39d1b9450bb3fb595b01fd94a8626ad75433038dde40988ecb41 url = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.3.tar.gz" sha256 = "2bc0f65a8046207ee3330ad7d63f6fafeafd4cc0ea4084f081bd5e4f7b177e74" sha512 = "3e5490e41547dffa78d52631825d93da8d60f4af0246cbaf97e1ecb879285953a86d5f1f390b10c32f91dd7eaec6f43e625a26b1c92c32a0c86fde428aedaaab" +deps = ["clocks", "io"] diff --git a/proposals/cli/wit/deps.toml b/proposals/cli/wit/deps.toml index 76cc8ca00..6b2e9eb93 100644 --- a/proposals/cli/wit/deps.toml +++ b/proposals/cli/wit/deps.toml @@ -1,5 +1,3 @@ -clocks = "https://github.com/WebAssembly/wasi-clocks/archive/v0.2.3.tar.gz" filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.3.tar.gz" -io = "https://github.com/WebAssembly/wasi-io/archive/v0.2.3.tar.gz" random = "https://github.com/WebAssembly/wasi-random/archive/v0.2.3.tar.gz" sockets = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.3.tar.gz" From ed70bd61d24c7d08384533479e664c03a906c22d Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 5 Feb 2025 22:13:45 +0100 Subject: [PATCH 1592/1772] Automate publishing and signing of Wasm Components --- .../sockets/.github/workflows/publish.yml | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 proposals/sockets/.github/workflows/publish.yml diff --git a/proposals/sockets/.github/workflows/publish.yml b/proposals/sockets/.github/workflows/publish.yml new file mode 100644 index 000000000..e7aa6ebd5 --- /dev/null +++ b/proposals/sockets/.github/workflows/publish.yml @@ -0,0 +1,70 @@ +name: Publish a Wasm Component package to GitHub Artifacts + +# Run this action whenever a new release is tagged +on: + push: + tags: + - v* + workflow_dispatch: + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + packages: write + contents: read + + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.10.15 + - name: Install wkg + shell: bash + run: cargo binstall wkg + - name: Install cosign + uses: sigstore/cosign-installer@v3.7.0 + + # To version our image we want to obtain the version from the tag + - name: Get version + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/webassembly/wasi/sockets + tags: | + type=semver,pattern={{version}} + + # To upload our image to the GitHub registry, we first have to login + - name: Login to the GitHub registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Build our `.wit` files into a Wasm binary + - name: Build + shell: bash + run: wkg wit build -o wasi-sockets.wasm + + # Upload the Wasm binary to the GitHub registry + - name: Publish to GitHub Container Registry + id: publish + uses: bytecodealliance/wkg-github-action@v5 + with: + oci-reference-without-tag: 'ghcr.io/webassembly/wasi/sockets' + file: 'wasi-sockets.wasm' + description: 'A WASI API for TCP & UDP sockets and domain name lookup.' + source: 'https://github.com/webassembly/wasi' + homepage: 'https://wasi.dev' + version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + licenses: 'Apache-2.0 WITH LLVM-exception' + + # Sign the output component + - name: Sign the wasm component + run: cosign sign --yes ghcr.io/webassembly/wasi/sockets@${{ steps.publish.outputs.digest }} From 7ed0f729dc4bb4c8ceaced84507c047c93c1fb25 Mon Sep 17 00:00:00 2001 From: Yosh Date: Tue, 4 Feb 2025 17:06:48 +0100 Subject: [PATCH 1593/1772] Fix publish.yml --- proposals/io/.github/workflows/publish.yml | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/proposals/io/.github/workflows/publish.yml b/proposals/io/.github/workflows/publish.yml index 54f87ca4f..407761eed 100644 --- a/proposals/io/.github/workflows/publish.yml +++ b/proposals/io/.github/workflows/publish.yml @@ -10,12 +10,13 @@ on: env: IMAGE_NAME: ${{ github.repository }} -permissions: - packages: write - jobs: publish: runs-on: ubuntu-latest + permissions: + id-token: write + packages: write + contents: read steps: # Checkout the repo and install dependencies @@ -26,13 +27,15 @@ jobs: - name: Install wkg shell: bash run: cargo binstall wkg + - name: Install cosign + uses: sigstore/cosign-installer@v3.7.0 # To version our image we want to obtain the version from the tag - name: Get version id: meta uses: docker/metadata-action@v5 with: - images: ghcr.io/WebAssembly/wasi/io + images: ghcr.io/webassembly/wasi/io tags: | type=semver,pattern={{version}} @@ -50,7 +53,9 @@ jobs: run: wkg wit build -o wasi-io.wasm # Upload the Wasm binary to the GitHub registry - - uses: bytecodealliance/wkg-github-action@v4 + - name: Publish to GitHub Container Registry + id: publish + uses: bytecodealliance/wkg-github-action@v5 with: oci-reference-without-tag: 'ghcr.io/webassembly/wasi/io' file: 'wasi-io.wasm' @@ -59,3 +64,7 @@ jobs: homepage: 'https://wasi.dev' version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} licenses: 'Apache-2.0 WITH LLVM-exception' + + # Sign the output component + - name: Sign the wasm component + run: cosign sign --yes ghcr.io/webassembly/wasi/io@${{ steps.publish.outputs.digest }} From c7b25f71557cba6583708a073e750b0c576fbbca Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 5 Feb 2025 22:12:50 +0100 Subject: [PATCH 1594/1772] Automate publishing and signing of Wasm Components --- .../random/.github/workflows/publish.yml | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 proposals/random/.github/workflows/publish.yml diff --git a/proposals/random/.github/workflows/publish.yml b/proposals/random/.github/workflows/publish.yml new file mode 100644 index 000000000..a9734235e --- /dev/null +++ b/proposals/random/.github/workflows/publish.yml @@ -0,0 +1,70 @@ +name: Publish a Wasm Component package to GitHub Artifacts + +# Run this action whenever a new release is tagged +on: + push: + tags: + - v* + workflow_dispatch: + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + packages: write + contents: read + + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.10.15 + - name: Install wkg + shell: bash + run: cargo binstall wkg + - name: Install cosign + uses: sigstore/cosign-installer@v3.7.0 + + # To version our image we want to obtain the version from the tag + - name: Get version + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/webassembly/wasi/random + tags: | + type=semver,pattern={{version}} + + # To upload our image to the GitHub registry, we first have to login + - name: Login to the GitHub registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Build our `.wit` files into a Wasm binary + - name: Build + shell: bash + run: wkg wit build -o wasi-random.wasm + + # Upload the Wasm binary to the GitHub registry + - name: Publish to GitHub Container Registry + id: publish + uses: bytecodealliance/wkg-github-action@v5 + with: + oci-reference-without-tag: 'ghcr.io/webassembly/wasi/random' + file: 'wasi-random.wasm' + description: 'A WASI API for obtaining pseudo-random data.' + source: 'https://github.com/webassembly/wasi' + homepage: 'https://wasi.dev' + version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + licenses: 'Apache-2.0 WITH LLVM-exception' + + # Sign the output component + - name: Sign the wasm component + run: cosign sign --yes ghcr.io/webassembly/wasi/random@${{ steps.publish.outputs.digest }} From 2af455da1904ceb1c661261981b9a75972bba749 Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 5 Feb 2025 22:11:52 +0100 Subject: [PATCH 1595/1772] Automate publishing and signing of Wasm Components --- .../clocks/.github/workflows/publish.yml | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 proposals/clocks/.github/workflows/publish.yml diff --git a/proposals/clocks/.github/workflows/publish.yml b/proposals/clocks/.github/workflows/publish.yml new file mode 100644 index 000000000..5354d30d2 --- /dev/null +++ b/proposals/clocks/.github/workflows/publish.yml @@ -0,0 +1,70 @@ +name: Publish a Wasm Component package to GitHub Artifacts + +# Run this action whenever a new release is tagged +on: + push: + tags: + - v* + workflow_dispatch: + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + packages: write + contents: read + + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.10.15 + - name: Install wkg + shell: bash + run: cargo binstall wkg + - name: Install cosign + uses: sigstore/cosign-installer@v3.7.0 + + # To version our image we want to obtain the version from the tag + - name: Get version + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/webassembly/wasi/clocks + tags: | + type=semver,pattern={{version}} + + # To upload our image to the GitHub registry, we first have to login + - name: Login to the GitHub registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Build our `.wit` files into a Wasm binary + - name: Build + shell: bash + run: wkg wit build -o wasi-clocks.wasm + + # Upload the Wasm binary to the GitHub registry + - name: Publish to GitHub Container Registry + id: publish + uses: bytecodealliance/wkg-github-action@v5 + with: + oci-reference-without-tag: 'ghcr.io/webassembly/wasi/clocks' + file: 'wasi-clocks.wasm' + description: 'A WASI API for reading the current time and measuring elapsed time.' + source: 'https://github.com/webassembly/wasi' + homepage: 'https://wasi.dev' + version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + licenses: 'Apache-2.0 WITH LLVM-exception' + + # Sign the output component + - name: Sign the wasm component + run: cosign sign --yes ghcr.io/webassembly/wasi/clocks@${{ steps.publish.outputs.digest }} From 6474855cf7ba8842cb0b2e5c3086a45b5c8c8767 Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 5 Feb 2025 22:14:46 +0100 Subject: [PATCH 1596/1772] Automate publishing and signing of Wasm Components --- .../filesystem/.github/workflows/publish.yml | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 proposals/filesystem/.github/workflows/publish.yml diff --git a/proposals/filesystem/.github/workflows/publish.yml b/proposals/filesystem/.github/workflows/publish.yml new file mode 100644 index 000000000..020a60b68 --- /dev/null +++ b/proposals/filesystem/.github/workflows/publish.yml @@ -0,0 +1,70 @@ +name: Publish a Wasm Component package to GitHub Artifacts + +# Run this action whenever a new release is tagged +on: + push: + tags: + - v* + workflow_dispatch: + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + packages: write + contents: read + + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.10.15 + - name: Install wkg + shell: bash + run: cargo binstall wkg + - name: Install cosign + uses: sigstore/cosign-installer@v3.7.0 + + # To version our image we want to obtain the version from the tag + - name: Get version + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/webassembly/wasi/filesystem + tags: | + type=semver,pattern={{version}} + + # To upload our image to the GitHub registry, we first have to login + - name: Login to the GitHub registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Build our `.wit` files into a Wasm binary + - name: Build + shell: bash + run: wkg wit build -o wasi-filesystem.wasm + + # Upload the Wasm binary to the GitHub registry + - name: Publish to GitHub Container Registry + id: publish + uses: bytecodealliance/wkg-github-action@v5 + with: + oci-reference-without-tag: 'ghcr.io/webassembly/wasi/filesystem' + file: 'wasi-filesystem.wasm' + description: 'A WASI API primarily for accessing host filesystems.' + source: 'https://github.com/webassembly/wasi' + homepage: 'https://wasi.dev' + version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + licenses: 'Apache-2.0 WITH LLVM-exception' + + # Sign the output component + - name: Sign the wasm component + run: cosign sign --yes ghcr.io/webassembly/wasi/filesystem@${{ steps.publish.outputs.digest }} From 9b6bbe361c11e466ba35bf4789548a14c4205152 Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 5 Feb 2025 22:10:25 +0100 Subject: [PATCH 1597/1772] Create publish.yml --- proposals/cli/.github/workflows/publish.yml | 70 +++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 proposals/cli/.github/workflows/publish.yml diff --git a/proposals/cli/.github/workflows/publish.yml b/proposals/cli/.github/workflows/publish.yml new file mode 100644 index 000000000..c06d645fb --- /dev/null +++ b/proposals/cli/.github/workflows/publish.yml @@ -0,0 +1,70 @@ +name: Publish a Wasm Component package to GitHub Artifacts + +# Run this action whenever a new release is tagged +on: + push: + tags: + - v* + workflow_dispatch: + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + packages: write + contents: read + + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.10.15 + - name: Install wkg + shell: bash + run: cargo binstall wkg + - name: Install cosign + uses: sigstore/cosign-installer@v3.7.0 + + # To version our image we want to obtain the version from the tag + - name: Get version + id: meta +: uses: docker/metadata-action@v5 + with: + images: ghcr.io/webassembly/wasi/cli + tags: | + type=semver,pattern={{version}} + + # To upload our image to the GitHub registry, we first have to login + - name: Login to the GitHub registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Build our `.wit` files into a Wasm binary + - name: Build + shell: bash + run: wkg wit build -o wasi-cli.wasm + + # Upload the Wasm binary to the GitHub registry + - name: Publish to GitHub Container Registry + id: publish + uses: bytecodealliance/wkg-github-action@v5 + with: + oci-reference-without-tag: 'ghcr.io/webassembly/wasi/cli' + file: 'wasi-cli.wasm' + description: 'A WASI API for Command-Line Interface environments.' + source: 'https://github.com/webassembly/wasi' + homepage: 'https://wasi.dev' + version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + licenses: 'Apache-2.0 WITH LLVM-exception' + + # Sign the output component + - name: Sign the wasm component + run: cosign sign --yes ghcr.io/webassembly/wasi/cli@${{ steps.publish.outputs.digest }} From 1eeab9a73386613a9b9dc2a485804d9827ff10d4 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 13:12:34 +0100 Subject: [PATCH 1598/1772] Update publish.yml --- proposals/cli/.github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/cli/.github/workflows/publish.yml b/proposals/cli/.github/workflows/publish.yml index c06d645fb..495751bb6 100644 --- a/proposals/cli/.github/workflows/publish.yml +++ b/proposals/cli/.github/workflows/publish.yml @@ -33,7 +33,7 @@ jobs: # To version our image we want to obtain the version from the tag - name: Get version id: meta -: uses: docker/metadata-action@v5 + uses: docker/metadata-action@v5 with: images: ghcr.io/webassembly/wasi/cli tags: | From 3b3bf8aad8e8c9eb0cbb0250eec090db0467c980 Mon Sep 17 00:00:00 2001 From: Yosh Date: Wed, 5 Feb 2025 22:03:28 +0100 Subject: [PATCH 1599/1772] Create publish.yml --- proposals/http/.github/workflows/publish.yml | 70 ++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 proposals/http/.github/workflows/publish.yml diff --git a/proposals/http/.github/workflows/publish.yml b/proposals/http/.github/workflows/publish.yml new file mode 100644 index 000000000..9cfcdb968 --- /dev/null +++ b/proposals/http/.github/workflows/publish.yml @@ -0,0 +1,70 @@ +name: Publish a Wasm Component package to GitHub Artifacts + +# Run this action whenever a new release is tagged +on: + push: + tags: + - v* + workflow_dispatch: + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + packages: write + contents: read + + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.10.15 + - name: Install wkg + shell: bash + run: cargo binstall wkg + - name: Install cosign + uses: sigstore/cosign-installer@v3.7.0 + + # To version our image we want to obtain the version from the tag + - name: Get version + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/webassembly/wasi/http + tags: | + type=semver,pattern={{version}} + + # To upload our image to the GitHub registry, we first have to login + - name: Login to the GitHub registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Build our `.wit` files into a Wasm binary + - name: Build + shell: bash + run: wkg wit build -o wasi-http.wasm + + # Upload the Wasm binary to the GitHub registry + - name: Publish to GitHub Container Registry + id: publish + uses: bytecodealliance/wkg-github-action@v5 + with: + oci-reference-without-tag: 'ghcr.io/webassembly/wasi/http' + file: 'wasi-http.wasm' + description: 'A WASI API for sending and receiving HTTP requests and responses.' + source: 'https://github.com/webassembly/wasi' + homepage: 'https://wasi.dev' + version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + licenses: 'Apache-2.0 WITH LLVM-exception' + + # Sign the output component + - name: Sign the wasm component + run: cosign sign --yes ghcr.io/webassembly/wasi/http@${{ steps.publish.outputs.digest }} From 0313fd90c035f57f2152fa303101fc71b5343f37 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 6 Feb 2025 08:40:11 -0500 Subject: [PATCH 1600/1772] ci: update wit version workflow --- proposals/io/.github/workflows/update.yml | 64 +++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 proposals/io/.github/workflows/update.yml diff --git a/proposals/io/.github/workflows/update.yml b/proposals/io/.github/workflows/update.yml new file mode 100644 index 000000000..55ea02c43 --- /dev/null +++ b/proposals/io/.github/workflows/update.yml @@ -0,0 +1,64 @@ +name: Create a PR to upgrade WIT to a new version + +# Manually dispatch this action from the Actions page +on: + workflow_dispatch: + inputs: + prev_version: + description: 'Upgrading from version (without the v)' + required: true + type: string + next_version: + description: 'Upgrading to version (without the v)' + required: true + type: string + +permissions: + pull-requests: write + contents: write + +jobs: + print-versions: + runs-on: ubuntu-latest + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.10.15 + - name: Install wit-bindgen + shell: bash + run: cargo binstall wit-bindgen-cli + - name: Install wit-deps + shell: bash + run: cargo binstall wit-deps-cli + + # echo input + - name: Print the versions + run: echo Upgrading from ${{ inputs.prev_version }} to ${{ inputs.next_version }} + + # upgrade + - name: Upgrade tag + run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + + # - name: Upgrade wit deps + # run: wit-deps update + - name: Generate markdown + run: wit-bindgen markdown wit --html-in-md --all-features + + # file PR + - name: Create feature branch + env: + FEATURE_BRANCH: v${{ inputs.next_version }} + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add . + git checkout -b $FEATURE_BRANCH + git push -u origin $FEATURE_BRANCH + git commit -m "Update to v${{ inputs.next_version }}" + git push + + - name: Create pull request + run: gh pr create -B main -H v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From ec3a24dab6af3d091eedef458b01583ac892c346 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 14:44:49 +0100 Subject: [PATCH 1601/1772] Update to v0.2.4 (#100) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- proposals/io/imports.md | 12 ++++++------ proposals/io/wit/error.wit | 2 +- proposals/io/wit/poll.wit | 2 +- proposals/io/wit/streams.wit | 2 +- proposals/io/wit/world.wit | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index 8101d1eea..f888233ca 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -2,13 +2,13 @@ -

                        Import interface wasi:io/error@0.2.3

                        +

                        Import interface wasi:io/error@0.2.4


                        Types

                        resource error

                        @@ -41,7 +41,7 @@ hazard.

                        • string
                        -

                        Import interface wasi:io/poll@0.2.3

                        +

                        Import interface wasi:io/poll@0.2.4

                        A poll API intended to let users wait for I/O events on multiple handles at once.


                        @@ -94,7 +94,7 @@ being ready for I/O.

                        • list<u32>
                        -

                        Import interface wasi:io/streams@0.2.3

                        +

                        Import interface wasi:io/streams@0.2.4

                        WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                        In the future, the component model is expected to add built-in stream types; diff --git a/proposals/io/wit/error.wit b/proposals/io/wit/error.wit index 97c606877..eb0600f9e 100644 --- a/proposals/io/wit/error.wit +++ b/proposals/io/wit/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; @since(version = 0.2.0) interface error { diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index 8d74fd891..170deff70 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index 0de084629..bb9a31e81 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index f1d2102dc..8e0fa5c53 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; @since(version = 0.2.0) world imports { From 6a2c01f8214563bc78241f29a9c0afe1491d9f93 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 6 Feb 2025 08:49:05 -0500 Subject: [PATCH 1602/1772] ci: use release prefix for pr (#101) Use a differently named release branch from tag. --- proposals/io/.github/workflows/update.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/io/.github/workflows/update.yml b/proposals/io/.github/workflows/update.yml index 55ea02c43..b3cfe25e8 100644 --- a/proposals/io/.github/workflows/update.yml +++ b/proposals/io/.github/workflows/update.yml @@ -18,7 +18,7 @@ permissions: contents: write jobs: - print-versions: + update-versions: runs-on: ubuntu-latest steps: # Checkout the repo and install dependencies @@ -48,7 +48,7 @@ jobs: # file PR - name: Create feature branch env: - FEATURE_BRANCH: v${{ inputs.next_version }} + FEATURE_BRANCH: release-v${{ inputs.next_version }} run: | git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" From e4a17ab57b887e5209b1ac86a8c229dabe1ab88f Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 6 Feb 2025 09:17:05 -0500 Subject: [PATCH 1603/1772] ci: update publish.yml with org pat (#103) --- proposals/io/.github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/io/.github/workflows/publish.yml b/proposals/io/.github/workflows/publish.yml index 407761eed..d68437074 100644 --- a/proposals/io/.github/workflows/publish.yml +++ b/proposals/io/.github/workflows/publish.yml @@ -45,7 +45,7 @@ jobs: with: registry: ghcr.io username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + password: ${{ secrets.ORG_PAT }} # Build our `.wit` files into a Wasm binary - name: Build From 497d4c1675773fb74ac1e0a7c781ef493bdfddfd Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 14:58:44 +0100 Subject: [PATCH 1604/1772] Update publish.yml --- proposals/io/.github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/io/.github/workflows/publish.yml b/proposals/io/.github/workflows/publish.yml index d68437074..ad76665f3 100644 --- a/proposals/io/.github/workflows/publish.yml +++ b/proposals/io/.github/workflows/publish.yml @@ -16,7 +16,7 @@ jobs: permissions: id-token: write packages: write - contents: read + contents: write steps: # Checkout the repo and install dependencies From 9da51e0e8867c683030ba6a4b4291a87d11a9cca Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 6 Feb 2025 09:27:54 -0500 Subject: [PATCH 1605/1772] ci: set user (#104) --- proposals/io/.github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/io/.github/workflows/publish.yml b/proposals/io/.github/workflows/publish.yml index ad76665f3..9221d2dcc 100644 --- a/proposals/io/.github/workflows/publish.yml +++ b/proposals/io/.github/workflows/publish.yml @@ -44,7 +44,7 @@ jobs: uses: docker/login-action@v3 with: registry: ghcr.io - username: ${{ github.actor }} + username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.ORG_PAT }} # Build our `.wit` files into a Wasm binary From b79addaf0a495ccc8904ec542a1926e63f6530d8 Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Thu, 6 Feb 2025 15:34:15 +0100 Subject: [PATCH 1606/1772] Revert "ci: set user (#104)" This reverts commit 9da51e0e8867c683030ba6a4b4291a87d11a9cca. --- proposals/io/.github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/io/.github/workflows/publish.yml b/proposals/io/.github/workflows/publish.yml index 9221d2dcc..ad76665f3 100644 --- a/proposals/io/.github/workflows/publish.yml +++ b/proposals/io/.github/workflows/publish.yml @@ -44,7 +44,7 @@ jobs: uses: docker/login-action@v3 with: registry: ghcr.io - username: ${{ secrets.DOCKER_USER }} + username: ${{ github.actor }} password: ${{ secrets.ORG_PAT }} # Build our `.wit` files into a Wasm binary From 4fec878b27ab6d3eed6f68bc5d42166e9f405ea4 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 15:51:06 +0100 Subject: [PATCH 1607/1772] Add update action --- .../random/.github/workflows/publish.yml | 4 +- proposals/random/.github/workflows/update.yml | 59 +++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 proposals/random/.github/workflows/update.yml diff --git a/proposals/random/.github/workflows/publish.yml b/proposals/random/.github/workflows/publish.yml index a9734235e..8b5f3c54a 100644 --- a/proposals/random/.github/workflows/publish.yml +++ b/proposals/random/.github/workflows/publish.yml @@ -16,7 +16,7 @@ jobs: permissions: id-token: write packages: write - contents: read + contents: write steps: # Checkout the repo and install dependencies @@ -45,7 +45,7 @@ jobs: with: registry: ghcr.io username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + password: ${{ secrets.ORG_PAT }} # Build our `.wit` files into a Wasm binary - name: Build diff --git a/proposals/random/.github/workflows/update.yml b/proposals/random/.github/workflows/update.yml new file mode 100644 index 000000000..9c72d9446 --- /dev/null +++ b/proposals/random/.github/workflows/update.yml @@ -0,0 +1,59 @@ +name: Create a PR to upgrade WIT to a new version + +# Manually dispatch this action from the Actions page +on: + workflow_dispatch: + inputs: + prev_version: + description: 'Upgrading from version (without the v)' + required: true + type: string + next_version: + description: 'Upgrading to version (without the v)' + required: true + type: string + +permissions: + pull-requests: write + contents: write + +jobs: + update-versions: + runs-on: ubuntu-latest + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.10.15 + - name: Install wit-bindgen + shell: bash + run: cargo binstall wit-bindgen-cli + + # echo input + - name: Print the versions + run: echo Upgrading from ${{ inputs.prev_version }} to ${{ inputs.next_version }} + + # upgrade + - name: Upgrade tag + run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + + - name: Generate markdown + run: wit-bindgen markdown wit --html-in-md --all-features + + # file PR + - name: Create feature branch + env: + FEATURE_BRANCH: release-v${{ inputs.next_version }} + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add . + git checkout -b $FEATURE_BRANCH + git push -u origin $FEATURE_BRANCH + git commit -m "Update to v${{ inputs.next_version }}" + git push + + - name: Create pull request + run: gh pr create -B main -H v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From c15bd28bb97da4ba242f0cadbb9de6b0d7f48ae7 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 6 Feb 2025 09:57:36 -0500 Subject: [PATCH 1608/1772] ci: fix pr branch --- proposals/random/.github/workflows/update.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/.github/workflows/update.yml b/proposals/random/.github/workflows/update.yml index 9c72d9446..b2eaec687 100644 --- a/proposals/random/.github/workflows/update.yml +++ b/proposals/random/.github/workflows/update.yml @@ -54,6 +54,6 @@ jobs: git push - name: Create pull request - run: gh pr create -B main -H v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' + run: gh pr create -B main -H release-v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From d6d66aab525f320ae5ab17259f94fd1220e7da2c Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 6 Feb 2025 09:57:39 -0500 Subject: [PATCH 1609/1772] ci: fix pr branch (#106) --- proposals/io/.github/workflows/update.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/io/.github/workflows/update.yml b/proposals/io/.github/workflows/update.yml index b3cfe25e8..22d10e7a3 100644 --- a/proposals/io/.github/workflows/update.yml +++ b/proposals/io/.github/workflows/update.yml @@ -59,6 +59,6 @@ jobs: git push - name: Create pull request - run: gh pr create -B main -H v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' + run: gh pr create -B main -H release-v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 6c2f32626a69a54c8c9dc0e0d636bb31a905db77 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 15:52:31 +0100 Subject: [PATCH 1610/1772] Add publish action --- .../clocks/.github/workflows/publish.yml | 4 +- proposals/clocks/.github/workflows/update.yml | 64 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 proposals/clocks/.github/workflows/update.yml diff --git a/proposals/clocks/.github/workflows/publish.yml b/proposals/clocks/.github/workflows/publish.yml index 5354d30d2..e66a5ed1e 100644 --- a/proposals/clocks/.github/workflows/publish.yml +++ b/proposals/clocks/.github/workflows/publish.yml @@ -16,7 +16,7 @@ jobs: permissions: id-token: write packages: write - contents: read + contents: write steps: # Checkout the repo and install dependencies @@ -45,7 +45,7 @@ jobs: with: registry: ghcr.io username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + password: ${{ secrets.ORG_PAT }} # Build our `.wit` files into a Wasm binary - name: Build diff --git a/proposals/clocks/.github/workflows/update.yml b/proposals/clocks/.github/workflows/update.yml new file mode 100644 index 000000000..b3cfe25e8 --- /dev/null +++ b/proposals/clocks/.github/workflows/update.yml @@ -0,0 +1,64 @@ +name: Create a PR to upgrade WIT to a new version + +# Manually dispatch this action from the Actions page +on: + workflow_dispatch: + inputs: + prev_version: + description: 'Upgrading from version (without the v)' + required: true + type: string + next_version: + description: 'Upgrading to version (without the v)' + required: true + type: string + +permissions: + pull-requests: write + contents: write + +jobs: + update-versions: + runs-on: ubuntu-latest + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.10.15 + - name: Install wit-bindgen + shell: bash + run: cargo binstall wit-bindgen-cli + - name: Install wit-deps + shell: bash + run: cargo binstall wit-deps-cli + + # echo input + - name: Print the versions + run: echo Upgrading from ${{ inputs.prev_version }} to ${{ inputs.next_version }} + + # upgrade + - name: Upgrade tag + run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + + # - name: Upgrade wit deps + # run: wit-deps update + - name: Generate markdown + run: wit-bindgen markdown wit --html-in-md --all-features + + # file PR + - name: Create feature branch + env: + FEATURE_BRANCH: release-v${{ inputs.next_version }} + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add . + git checkout -b $FEATURE_BRANCH + git push -u origin $FEATURE_BRANCH + git commit -m "Update to v${{ inputs.next_version }}" + git push + + - name: Create pull request + run: gh pr create -B main -H v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From e294abaca8fc2b63d569eff9222f3beaabad9be6 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 15:55:57 +0100 Subject: [PATCH 1611/1772] Update update.yml --- proposals/clocks/.github/workflows/update.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/.github/workflows/update.yml b/proposals/clocks/.github/workflows/update.yml index b3cfe25e8..22d10e7a3 100644 --- a/proposals/clocks/.github/workflows/update.yml +++ b/proposals/clocks/.github/workflows/update.yml @@ -59,6 +59,6 @@ jobs: git push - name: Create pull request - run: gh pr create -B main -H v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' + run: gh pr create -B main -H release-v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 509ccaad23b2e097d222f7368d3e5a657820e7a9 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 15:58:45 +0100 Subject: [PATCH 1612/1772] Update update.yml --- proposals/clocks/.github/workflows/update.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/clocks/.github/workflows/update.yml b/proposals/clocks/.github/workflows/update.yml index 22d10e7a3..bdf61d30c 100644 --- a/proposals/clocks/.github/workflows/update.yml +++ b/proposals/clocks/.github/workflows/update.yml @@ -40,8 +40,8 @@ jobs: # upgrade - name: Upgrade tag run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - # - name: Upgrade wit deps - # run: wit-deps update + - name: Upgrade wit deps + run: wit-deps update - name: Generate markdown run: wit-bindgen markdown wit --html-in-md --all-features From de2644ef51186765f08366b5ddc79299ae607b9d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 15:01:16 +0000 Subject: [PATCH 1613/1772] Update to v0.2.4 --- proposals/random/imports.md | 12 ++++++------ proposals/random/wit/insecure-seed.wit | 2 +- proposals/random/wit/insecure.wit | 2 +- proposals/random/wit/random.wit | 2 +- proposals/random/wit/world.wit | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/random/imports.md b/proposals/random/imports.md index 122be7c7b..196e50bf1 100644 --- a/proposals/random/imports.md +++ b/proposals/random/imports.md @@ -2,13 +2,13 @@

                        -

                        Import interface wasi:random/random@0.2.3

                        +

                        Import interface wasi:random/random@0.2.4

                        WASI Random is a random data API.

                        It is intended to be portable at least between Unix-family platforms and Windows.

                        @@ -41,7 +41,7 @@ represented as a u64.

                        • u64
                        -

                        Import interface wasi:random/insecure@0.2.3

                        +

                        Import interface wasi:random/insecure@0.2.4

                        The insecure interface for insecure pseudo-random numbers.

                        It is intended to be portable at least between Unix-family platforms and Windows.

                        @@ -70,7 +70,7 @@ a long period.

                        • u64
                        -

                        Import interface wasi:random/insecure-seed@0.2.3

                        +

                        Import interface wasi:random/insecure-seed@0.2.4

                        The insecure-seed interface for seeding hash-map DoS resistance.

                        It is intended to be portable at least between Unix-family platforms and Windows.

                        diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index 67d024d5b..45e8bafdb 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index a07dfab32..5ab5030c5 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 91957e633..9e5220d82 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index 0c1218f36..d89055819 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; @since(version = 0.2.0) world imports { From 3ca6b84f2500cca464a0eb90523d9694398d8e2d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 15:03:52 +0000 Subject: [PATCH 1614/1772] Update to v0.2.4 --- proposals/clocks/imports.md | 16 +++++++-------- proposals/clocks/wit/deps.lock | 4 ++-- proposals/clocks/wit/deps/io/error.wit | 2 +- proposals/clocks/wit/deps/io/poll.wit | 26 ++++++++++++------------ proposals/clocks/wit/deps/io/streams.wit | 2 +- proposals/clocks/wit/deps/io/world.wit | 2 +- proposals/clocks/wit/monotonic-clock.wit | 4 ++-- proposals/clocks/wit/timezone.wit | 2 +- proposals/clocks/wit/wall-clock.wit | 2 +- proposals/clocks/wit/world.wit | 2 +- 10 files changed, 31 insertions(+), 31 deletions(-) diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index 090dbb9a9..006a2b32e 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -2,14 +2,14 @@ -

                        Import interface wasi:io/poll@0.2.3

                        +

                        Import interface wasi:io/poll@0.2.4

                        A poll API intended to let users wait for I/O events on multiple handles at once.


                        @@ -62,7 +62,7 @@ being ready for I/O.

                        • list<u32>
                        -

                        Import interface wasi:clocks/monotonic-clock@0.2.3

                        +

                        Import interface wasi:clocks/monotonic-clock@0.2.4

                        WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                        It is intended to be portable at least between Unix-family platforms and @@ -121,7 +121,7 @@ elapsed from the time this function is invoked.

                        -

                        Import interface wasi:clocks/wall-clock@0.2.3

                        +

                        Import interface wasi:clocks/wall-clock@0.2.4

                        WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                        @@ -162,7 +162,7 @@ also known as Unix Time.
                      • datetime
                      -

                      Import interface wasi:clocks/timezone@0.2.3

                      +

                      Import interface wasi:clocks/timezone@0.2.4


                      Types

                      type datetime

                      diff --git a/proposals/clocks/wit/deps.lock b/proposals/clocks/wit/deps.lock index 23fb87f77..4f895ac79 100644 --- a/proposals/clocks/wit/deps.lock +++ b/proposals/clocks/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" -sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" +sha256 = "770a73d479cda8e4c4064dd4006d2654ebcc358952079d74e41af27cf26bddbf" +sha512 = "b790f9750ac6782d9aaaa379845600b66dbde14ecee42f159c29796447eb8e61ee61f3b306e92622993b5e25298834b6ff62d7d9a04f8f18c05f07eda8f47ae0" diff --git a/proposals/clocks/wit/deps/io/error.wit b/proposals/clocks/wit/deps/io/error.wit index 97c606877..eb0600f9e 100644 --- a/proposals/clocks/wit/deps/io/error.wit +++ b/proposals/clocks/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; @since(version = 0.2.0) interface error { diff --git a/proposals/clocks/wit/deps/io/poll.wit b/proposals/clocks/wit/deps/io/poll.wit index 9bcbe8e03..170deff70 100644 --- a/proposals/clocks/wit/deps/io/poll.wit +++ b/proposals/clocks/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. @@ -8,19 +8,19 @@ interface poll { @since(version = 0.2.0) resource pollable { - /// Return the readiness of a pollable. This function never blocks. - /// - /// Returns `true` when the pollable is ready, and `false` otherwise. - @since(version = 0.2.0) - ready: func() -> bool; + /// Return the readiness of a pollable. This function never blocks. + /// + /// Returns `true` when the pollable is ready, and `false` otherwise. + @since(version = 0.2.0) + ready: func() -> bool; - /// `block` returns immediately if the pollable is ready, and otherwise - /// blocks until ready. - /// - /// This function is equivalent to calling `poll.poll` on a list - /// containing only this pollable. - @since(version = 0.2.0) - block: func(); + /// `block` returns immediately if the pollable is ready, and otherwise + /// blocks until ready. + /// + /// This function is equivalent to calling `poll.poll` on a list + /// containing only this pollable. + @since(version = 0.2.0) + block: func(); } /// Poll for completion on a set of pollables. diff --git a/proposals/clocks/wit/deps/io/streams.wit b/proposals/clocks/wit/deps/io/streams.wit index 0de084629..bb9a31e81 100644 --- a/proposals/clocks/wit/deps/io/streams.wit +++ b/proposals/clocks/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/clocks/wit/deps/io/world.wit b/proposals/clocks/wit/deps/io/world.wit index f1d2102dc..8e0fa5c53 100644 --- a/proposals/clocks/wit/deps/io/world.wit +++ b/proposals/clocks/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index c676fb84d..175f8fe2d 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.3; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/clocks/wit/timezone.wit b/proposals/clocks/wit/timezone.wit index b43e93b23..658cb17e7 100644 --- a/proposals/clocks/wit/timezone.wit +++ b/proposals/clocks/wit/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/clocks/wit/wall-clock.wit b/proposals/clocks/wit/wall-clock.wit index e00ce0893..f826cd1e0 100644 --- a/proposals/clocks/wit/wall-clock.wit +++ b/proposals/clocks/wit/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index 05f04f797..9e2087447 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; @since(version = 0.2.0) world imports { From 79a4cd60bbc287485e7b6e3f13dca6207022158d Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 16:04:59 +0100 Subject: [PATCH 1615/1772] Add publish action --- .../filesystem/.github/workflows/publish.yml | 4 +- .../filesystem/.github/workflows/update.yml | 64 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 proposals/filesystem/.github/workflows/update.yml diff --git a/proposals/filesystem/.github/workflows/publish.yml b/proposals/filesystem/.github/workflows/publish.yml index 020a60b68..8c04ca6eb 100644 --- a/proposals/filesystem/.github/workflows/publish.yml +++ b/proposals/filesystem/.github/workflows/publish.yml @@ -16,7 +16,7 @@ jobs: permissions: id-token: write packages: write - contents: read + contents: write steps: # Checkout the repo and install dependencies @@ -45,7 +45,7 @@ jobs: with: registry: ghcr.io username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + password: ${{ secrets.ORG_PAT }} # Build our `.wit` files into a Wasm binary - name: Build diff --git a/proposals/filesystem/.github/workflows/update.yml b/proposals/filesystem/.github/workflows/update.yml new file mode 100644 index 000000000..73a4df3cf --- /dev/null +++ b/proposals/filesystem/.github/workflows/update.yml @@ -0,0 +1,64 @@ +name: Create a PR to upgrade WIT to a new version + +# Manually dispatch this action from the Actions page +on: + workflow_dispatch: + inputs: + prev_version: + description: 'Upgrading from version (without the v)' + required: true + type: string + next_version: + description: 'Upgrading to version (without the v)' + required: true + type: string + +permissions: + pull-requests: write + contents: write + +jobs: + update-versions: + runs-on: ubuntu-latest + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.10.15 + - name: Install wit-bindgen + shell: bash + run: cargo binstall wit-bindgen-cli + - name: Install wit-deps + shell: bash + run: cargo binstall wit-deps-cli + + # echo input + - name: Print the versions + run: echo Upgrading from ${{ inputs.prev_version }} to ${{ inputs.next_version }} + + # upgrade + - name: Upgrade tag + run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + + - name: Upgrade wit deps + run: wit-deps update + - name: Generate markdown + run: wit-bindgen markdown wit --html-in-md --all-features + + # file PR + - name: Create feature branch + env: + FEATURE_BRANCH: release-v${{ inputs.next_version }} + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add . + git checkout -b $FEATURE_BRANCH + git push -u origin $FEATURE_BRANCH + git commit -m "Update to v${{ inputs.next_version }}" + git push + + - name: Create pull request + run: gh pr create -B main -H v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 1a94d012f9d4860c8c1763a35e45b557aaace665 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 6 Feb 2025 10:10:02 -0500 Subject: [PATCH 1616/1772] ci: fix release branch --- proposals/filesystem/.github/workflows/update.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/.github/workflows/update.yml b/proposals/filesystem/.github/workflows/update.yml index 73a4df3cf..bdf61d30c 100644 --- a/proposals/filesystem/.github/workflows/update.yml +++ b/proposals/filesystem/.github/workflows/update.yml @@ -59,6 +59,6 @@ jobs: git push - name: Create pull request - run: gh pr create -B main -H v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' + run: gh pr create -B main -H release-v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 5ac4019e03f62e19e2b2255dc2f7aee194a06323 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 15:13:14 +0000 Subject: [PATCH 1617/1772] Update to v0.2.4 --- proposals/filesystem/imports.md | 24 ++++++++--------- proposals/filesystem/wit/deps.lock | 8 +++--- .../wit/deps/clocks/monotonic-clock.wit | 4 +-- .../filesystem/wit/deps/clocks/timezone.wit | 2 +- .../filesystem/wit/deps/clocks/wall-clock.wit | 2 +- .../filesystem/wit/deps/clocks/world.wit | 2 +- proposals/filesystem/wit/deps/io/error.wit | 2 +- proposals/filesystem/wit/deps/io/poll.wit | 26 +++++++++---------- proposals/filesystem/wit/deps/io/streams.wit | 2 +- proposals/filesystem/wit/deps/io/world.wit | 2 +- proposals/filesystem/wit/preopens.wit | 2 +- proposals/filesystem/wit/types.wit | 6 ++--- proposals/filesystem/wit/world.wit | 2 +- 13 files changed, 42 insertions(+), 42 deletions(-) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index 869a4bb5a..e0e88e386 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -2,16 +2,16 @@ -

                      Import interface wasi:io/error@0.2.3

                      +

                      Import interface wasi:io/error@0.2.4


                      Types

                      resource error

                      @@ -44,7 +44,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/poll@0.2.3

                      +

                      Import interface wasi:io/poll@0.2.4

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -97,7 +97,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:io/streams@0.2.3

                      +

                      Import interface wasi:io/streams@0.2.4

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -427,7 +427,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.3

                      +

                      Import interface wasi:clocks/wall-clock@0.2.4

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -468,7 +468,7 @@ also known as Unix Time.
                    23. datetime
                    24. -

                      Import interface wasi:filesystem/types@0.2.3

                      +

                      Import interface wasi:filesystem/types@0.2.4

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                      @@ -1346,7 +1346,7 @@ errors are filesystem-related errors.

                      -

                      Import interface wasi:filesystem/preopens@0.2.3

                      +

                      Import interface wasi:filesystem/preopens@0.2.4


                      Types

                      type descriptor

                      diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index 316cbaa96..f9154882f 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "93a701968a7dd3c5d69031bc0601681c468972fdf7e28a93bb6150a67d6ebe8b" -sha512 = "98fca567c7a01887b0fb38981f1772169b6ea8de475b546508f8b86738d84e44ba95cae81def40ac34e8809f5f60e85224077ab8cb6d6d5d6296acc1df73c159" +sha256 = "fc36267c5098ad9ac6455396b27c8ef206ca23cae74f40bd44c57be68e7849b6" +sha512 = "0deed3d3a86f284adda7991cd24c0c4aab806ba2e0cb111da80d7f99c05f10793a602b28451407cad58ab762997f60c0f6d173e919e4a0988773b455d3a410d3" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" -sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" +sha256 = "770a73d479cda8e4c4064dd4006d2654ebcc358952079d74e41af27cf26bddbf" +sha512 = "b790f9750ac6782d9aaaa379845600b66dbde14ecee42f159c29796447eb8e61ee61f3b306e92622993b5e25298834b6ff62d7d9a04f8f18c05f07eda8f47ae0" diff --git a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit index c676fb84d..175f8fe2d 100644 --- a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.3; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/filesystem/wit/deps/clocks/timezone.wit b/proposals/filesystem/wit/deps/clocks/timezone.wit index b43e93b23..658cb17e7 100644 --- a/proposals/filesystem/wit/deps/clocks/timezone.wit +++ b/proposals/filesystem/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/filesystem/wit/deps/clocks/wall-clock.wit b/proposals/filesystem/wit/deps/clocks/wall-clock.wit index e00ce0893..f826cd1e0 100644 --- a/proposals/filesystem/wit/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/filesystem/wit/deps/clocks/world.wit b/proposals/filesystem/wit/deps/clocks/world.wit index 05f04f797..9e2087447 100644 --- a/proposals/filesystem/wit/deps/clocks/world.wit +++ b/proposals/filesystem/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/filesystem/wit/deps/io/error.wit b/proposals/filesystem/wit/deps/io/error.wit index 97c606877..eb0600f9e 100644 --- a/proposals/filesystem/wit/deps/io/error.wit +++ b/proposals/filesystem/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; @since(version = 0.2.0) interface error { diff --git a/proposals/filesystem/wit/deps/io/poll.wit b/proposals/filesystem/wit/deps/io/poll.wit index 9bcbe8e03..170deff70 100644 --- a/proposals/filesystem/wit/deps/io/poll.wit +++ b/proposals/filesystem/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. @@ -8,19 +8,19 @@ interface poll { @since(version = 0.2.0) resource pollable { - /// Return the readiness of a pollable. This function never blocks. - /// - /// Returns `true` when the pollable is ready, and `false` otherwise. - @since(version = 0.2.0) - ready: func() -> bool; + /// Return the readiness of a pollable. This function never blocks. + /// + /// Returns `true` when the pollable is ready, and `false` otherwise. + @since(version = 0.2.0) + ready: func() -> bool; - /// `block` returns immediately if the pollable is ready, and otherwise - /// blocks until ready. - /// - /// This function is equivalent to calling `poll.poll` on a list - /// containing only this pollable. - @since(version = 0.2.0) - block: func(); + /// `block` returns immediately if the pollable is ready, and otherwise + /// blocks until ready. + /// + /// This function is equivalent to calling `poll.poll` on a list + /// containing only this pollable. + @since(version = 0.2.0) + block: func(); } /// Poll for completion on a set of pollables. diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index 0de084629..bb9a31e81 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/filesystem/wit/deps/io/world.wit b/proposals/filesystem/wit/deps/io/world.wit index f1d2102dc..8e0fa5c53 100644 --- a/proposals/filesystem/wit/deps/io/world.wit +++ b/proposals/filesystem/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit index cea97495b..6e6003954 100644 --- a/proposals/filesystem/wit/preopens.wit +++ b/proposals/filesystem/wit/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.3; +package wasi:filesystem@0.2.4; @since(version = 0.2.0) interface preopens { diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 6ca962c48..962cadfef 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.3; +package wasi:filesystem@0.2.4; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.3; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.4.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.3.{datetime}; + use wasi:clocks/wall-clock@0.2.4.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index 29405bc2c..7742ed6bb 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.3; +package wasi:filesystem@0.2.4; @since(version = 0.2.0) world imports { From b89db73d71cca284d9ad2da437f9e42e6691dd7c Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 16:09:25 +0100 Subject: [PATCH 1618/1772] Add update github action --- .../sockets/.github/workflows/publish.yml | 4 +- .../sockets/.github/workflows/update.yml | 64 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 proposals/sockets/.github/workflows/update.yml diff --git a/proposals/sockets/.github/workflows/publish.yml b/proposals/sockets/.github/workflows/publish.yml index e7aa6ebd5..90109fb63 100644 --- a/proposals/sockets/.github/workflows/publish.yml +++ b/proposals/sockets/.github/workflows/publish.yml @@ -16,7 +16,7 @@ jobs: permissions: id-token: write packages: write - contents: read + contents: write steps: # Checkout the repo and install dependencies @@ -45,7 +45,7 @@ jobs: with: registry: ghcr.io username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + password: ${{ secrets.ORG_PAT }} # Build our `.wit` files into a Wasm binary - name: Build diff --git a/proposals/sockets/.github/workflows/update.yml b/proposals/sockets/.github/workflows/update.yml new file mode 100644 index 000000000..bdf61d30c --- /dev/null +++ b/proposals/sockets/.github/workflows/update.yml @@ -0,0 +1,64 @@ +name: Create a PR to upgrade WIT to a new version + +# Manually dispatch this action from the Actions page +on: + workflow_dispatch: + inputs: + prev_version: + description: 'Upgrading from version (without the v)' + required: true + type: string + next_version: + description: 'Upgrading to version (without the v)' + required: true + type: string + +permissions: + pull-requests: write + contents: write + +jobs: + update-versions: + runs-on: ubuntu-latest + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.10.15 + - name: Install wit-bindgen + shell: bash + run: cargo binstall wit-bindgen-cli + - name: Install wit-deps + shell: bash + run: cargo binstall wit-deps-cli + + # echo input + - name: Print the versions + run: echo Upgrading from ${{ inputs.prev_version }} to ${{ inputs.next_version }} + + # upgrade + - name: Upgrade tag + run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + + - name: Upgrade wit deps + run: wit-deps update + - name: Generate markdown + run: wit-bindgen markdown wit --html-in-md --all-features + + # file PR + - name: Create feature branch + env: + FEATURE_BRANCH: release-v${{ inputs.next_version }} + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add . + git checkout -b $FEATURE_BRANCH + git push -u origin $FEATURE_BRANCH + git commit -m "Update to v${{ inputs.next_version }}" + git push + + - name: Create pull request + run: gh pr create -B main -H release-v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From be12da9f8aebc0ffe10a0999d6b03ab7752822f2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 15:17:20 +0000 Subject: [PATCH 1619/1772] Update to v0.2.4 --- proposals/sockets/imports.md | 132 ++++++++++-------- proposals/sockets/wit/deps.lock | 8 +- .../wit/deps/clocks/monotonic-clock.wit | 4 +- .../sockets/wit/deps/clocks/timezone.wit | 2 +- .../sockets/wit/deps/clocks/wall-clock.wit | 2 +- proposals/sockets/wit/deps/clocks/world.wit | 2 +- proposals/sockets/wit/deps/io/error.wit | 2 +- proposals/sockets/wit/deps/io/poll.wit | 26 ++-- proposals/sockets/wit/deps/io/streams.wit | 2 +- proposals/sockets/wit/deps/io/world.wit | 2 +- proposals/sockets/wit/ip-name-lookup.wit | 2 +- proposals/sockets/wit/network.wit | 2 +- proposals/sockets/wit/tcp.wit | 6 +- proposals/sockets/wit/udp.wit | 2 +- proposals/sockets/wit/world.wit | 2 +- 15 files changed, 109 insertions(+), 87 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 9ae46377f..5a5645303 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -2,24 +2,60 @@ -

                      Import interface wasi:sockets/network@0.2.3

                      +

                      Import interface wasi:io/error@0.2.4


                      Types

                      -

                      resource network

                      +

                      resource error

                      +

                      A resource which represents some error information.

                      +

                      The only method provided by this resource is to-debug-string, +which provides some human-readable information about the error.

                      +

                      In the wasi:io package, this resource is returned through the +wasi:io/streams/stream-error type.

                      +

                      To provide more specific error information, other interfaces may +offer functions to "downcast" this error into more specific types. For example, +errors returned from streams derived from filesystem types can be described using +the filesystem's own error-code type. This is done using the function +wasi:filesystem/types/filesystem-error-code, which takes a borrow<error> +parameter and returns an option<wasi:filesystem/types/error-code>.

                      +

                      The set of functions which can "downcast" an error into a more +concrete type is open.

                      +

                      Functions

                      +

                      [method]error.to-debug-string: func

                      +

                      Returns a string that is suitable to assist humans in debugging +this error.

                      +

                      WARNING: The returned string should not be consumed mechanically! +It may change across platforms, hosts, or other implementation +details. Parsing this string is a major platform-compatibility +hazard.

                      +
                      Params
                      + +
                      Return values
                      +
                        +
                      • string
                      • +
                      +

                      Import interface wasi:sockets/network@0.2.4

                      +
                      +

                      Types

                      +

                      type error

                      +

                      error

                      +

                      +#### `resource network`

                      An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                      @@ -209,7 +245,26 @@ supported size.
                    25. ipv4: ipv4-socket-address
                    26. ipv6: ipv6-socket-address
                    27. -

                      Import interface wasi:sockets/instance-network@0.2.3

                      +
                      +

                      Functions

                      +

                      network-error-code: func

                      +

                      Attempts to extract a network-related error-code from the stream +error provided.

                      +

                      Stream operations which return stream-error::last-operation-failed +have a payload with more information about the operation that failed. +This payload can be passed through to this function to see if there's +network-related information about the error to return.

                      +

                      Note that this function is fallible because not all stream-related +errors are network-related errors.

                      +
                      Params
                      + +
                      Return values
                      + +

                      Import interface wasi:sockets/instance-network@0.2.4

                      This interface provides a value-export of the default network handle..


                      Types

                      @@ -224,7 +279,7 @@ supported size. -

                      Import interface wasi:io/poll@0.2.3

                      +

                      Import interface wasi:io/poll@0.2.4

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -277,7 +332,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:sockets/udp@0.2.3

                      +

                      Import interface wasi:sockets/udp@0.2.4


                      Types

                      type pollable

                      @@ -691,7 +746,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:sockets/udp-create-socket@0.2.3

                      +

                      Import interface wasi:sockets/udp-create-socket@0.2.4


                      Types

                      type network

                      @@ -736,40 +791,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                      Import interface wasi:io/error@0.2.3

                      -
                      -

                      Types

                      -

                      resource error

                      -

                      A resource which represents some error information.

                      -

                      The only method provided by this resource is to-debug-string, -which provides some human-readable information about the error.

                      -

                      In the wasi:io package, this resource is returned through the -wasi:io/streams/stream-error type.

                      -

                      To provide more specific error information, other interfaces may -offer functions to "downcast" this error into more specific types. For example, -errors returned from streams derived from filesystem types can be described using -the filesystem's own error-code type. This is done using the function -wasi:filesystem/types/filesystem-error-code, which takes a borrow<error> -parameter and returns an option<wasi:filesystem/types/error-code>.

                      -

                      The set of functions which can "downcast" an error into a more -concrete type is open.

                      -

                      Functions

                      -

                      [method]error.to-debug-string: func

                      -

                      Returns a string that is suitable to assist humans in debugging -this error.

                      -

                      WARNING: The returned string should not be consumed mechanically! -It may change across platforms, hosts, or other implementation -details. Parsing this string is a major platform-compatibility -hazard.

                      -
                      Params
                      - -
                      Return values
                      -
                        -
                      • string
                      • -
                      -

                      Import interface wasi:io/streams@0.2.3

                      +

                      Import interface wasi:io/streams@0.2.4

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -1099,7 +1121,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.3

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.4

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -1158,7 +1180,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:sockets/tcp@0.2.3

                      +

                      Import interface wasi:sockets/tcp@0.2.4


                      Types

                      type input-stream

                      @@ -1749,7 +1771,7 @@ has no effect and returns ok.

                      -

                      Import interface wasi:sockets/tcp-create-socket@0.2.3

                      +

                      Import interface wasi:sockets/tcp-create-socket@0.2.4


                      Types

                      type network

                      @@ -1794,7 +1816,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                      Import interface wasi:sockets/ip-name-lookup@0.2.3

                      +

                      Import interface wasi:sockets/ip-name-lookup@0.2.4


                      Types

                      type pollable

                      diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index 316cbaa96..f9154882f 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "93a701968a7dd3c5d69031bc0601681c468972fdf7e28a93bb6150a67d6ebe8b" -sha512 = "98fca567c7a01887b0fb38981f1772169b6ea8de475b546508f8b86738d84e44ba95cae81def40ac34e8809f5f60e85224077ab8cb6d6d5d6296acc1df73c159" +sha256 = "fc36267c5098ad9ac6455396b27c8ef206ca23cae74f40bd44c57be68e7849b6" +sha512 = "0deed3d3a86f284adda7991cd24c0c4aab806ba2e0cb111da80d7f99c05f10793a602b28451407cad58ab762997f60c0f6d173e919e4a0988773b455d3a410d3" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" -sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" +sha256 = "770a73d479cda8e4c4064dd4006d2654ebcc358952079d74e41af27cf26bddbf" +sha512 = "b790f9750ac6782d9aaaa379845600b66dbde14ecee42f159c29796447eb8e61ee61f3b306e92622993b5e25298834b6ff62d7d9a04f8f18c05f07eda8f47ae0" diff --git a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit index c676fb84d..175f8fe2d 100644 --- a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.3; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/sockets/wit/deps/clocks/timezone.wit b/proposals/sockets/wit/deps/clocks/timezone.wit index b43e93b23..658cb17e7 100644 --- a/proposals/sockets/wit/deps/clocks/timezone.wit +++ b/proposals/sockets/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/sockets/wit/deps/clocks/wall-clock.wit b/proposals/sockets/wit/deps/clocks/wall-clock.wit index e00ce0893..f826cd1e0 100644 --- a/proposals/sockets/wit/deps/clocks/wall-clock.wit +++ b/proposals/sockets/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/sockets/wit/deps/clocks/world.wit b/proposals/sockets/wit/deps/clocks/world.wit index 05f04f797..9e2087447 100644 --- a/proposals/sockets/wit/deps/clocks/world.wit +++ b/proposals/sockets/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/sockets/wit/deps/io/error.wit b/proposals/sockets/wit/deps/io/error.wit index 97c606877..eb0600f9e 100644 --- a/proposals/sockets/wit/deps/io/error.wit +++ b/proposals/sockets/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; @since(version = 0.2.0) interface error { diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit index 9bcbe8e03..170deff70 100644 --- a/proposals/sockets/wit/deps/io/poll.wit +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. @@ -8,19 +8,19 @@ interface poll { @since(version = 0.2.0) resource pollable { - /// Return the readiness of a pollable. This function never blocks. - /// - /// Returns `true` when the pollable is ready, and `false` otherwise. - @since(version = 0.2.0) - ready: func() -> bool; + /// Return the readiness of a pollable. This function never blocks. + /// + /// Returns `true` when the pollable is ready, and `false` otherwise. + @since(version = 0.2.0) + ready: func() -> bool; - /// `block` returns immediately if the pollable is ready, and otherwise - /// blocks until ready. - /// - /// This function is equivalent to calling `poll.poll` on a list - /// containing only this pollable. - @since(version = 0.2.0) - block: func(); + /// `block` returns immediately if the pollable is ready, and otherwise + /// blocks until ready. + /// + /// This function is equivalent to calling `poll.poll` on a list + /// containing only this pollable. + @since(version = 0.2.0) + block: func(); } /// Poll for completion on a set of pollables. diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index 0de084629..bb9a31e81 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit index f1d2102dc..8e0fa5c53 100644 --- a/proposals/sockets/wit/deps/io/world.wit +++ b/proposals/sockets/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index c1d8a47c1..48b41a5b1 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index f3f60a370..aa4985e14 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.3.{error}; + use wasi:io/error@0.2.4.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index b4cd87fce..b3311332f 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{input-stream, output-stream}; + use wasi:io/streams@0.2.4.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.3.{duration}; + use wasi:clocks/monotonic-clock@0.2.4.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 01901ca27..cfc07ba81 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index 2f0ad0d7c..82acdb9f0 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.3; +package wasi:sockets@0.2.4; @since(version = 0.2.0) world imports { From a46cb2d6b67db7d9666d77f5c7bfee6eea45701a Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 16:16:27 +0100 Subject: [PATCH 1620/1772] Add "update" github action --- proposals/cli/.github/workflows/publish.yml | 4 +- proposals/cli/.github/workflows/update.yml | 64 +++++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 proposals/cli/.github/workflows/update.yml diff --git a/proposals/cli/.github/workflows/publish.yml b/proposals/cli/.github/workflows/publish.yml index 495751bb6..af5bd0699 100644 --- a/proposals/cli/.github/workflows/publish.yml +++ b/proposals/cli/.github/workflows/publish.yml @@ -16,7 +16,7 @@ jobs: permissions: id-token: write packages: write - contents: read + contents: write steps: # Checkout the repo and install dependencies @@ -45,7 +45,7 @@ jobs: with: registry: ghcr.io username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + password: ${{ secrets.ORG_PAT }} # Build our `.wit` files into a Wasm binary - name: Build diff --git a/proposals/cli/.github/workflows/update.yml b/proposals/cli/.github/workflows/update.yml new file mode 100644 index 000000000..bdf61d30c --- /dev/null +++ b/proposals/cli/.github/workflows/update.yml @@ -0,0 +1,64 @@ +name: Create a PR to upgrade WIT to a new version + +# Manually dispatch this action from the Actions page +on: + workflow_dispatch: + inputs: + prev_version: + description: 'Upgrading from version (without the v)' + required: true + type: string + next_version: + description: 'Upgrading to version (without the v)' + required: true + type: string + +permissions: + pull-requests: write + contents: write + +jobs: + update-versions: + runs-on: ubuntu-latest + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.10.15 + - name: Install wit-bindgen + shell: bash + run: cargo binstall wit-bindgen-cli + - name: Install wit-deps + shell: bash + run: cargo binstall wit-deps-cli + + # echo input + - name: Print the versions + run: echo Upgrading from ${{ inputs.prev_version }} to ${{ inputs.next_version }} + + # upgrade + - name: Upgrade tag + run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + + - name: Upgrade wit deps + run: wit-deps update + - name: Generate markdown + run: wit-bindgen markdown wit --html-in-md --all-features + + # file PR + - name: Create feature branch + env: + FEATURE_BRANCH: release-v${{ inputs.next_version }} + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add . + git checkout -b $FEATURE_BRANCH + git push -u origin $FEATURE_BRANCH + git commit -m "Update to v${{ inputs.next_version }}" + git push + + - name: Create pull request + run: gh pr create -B main -H release-v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 3c11659e7cf3e8e577ead4b4e96436cfecc81d88 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 6 Feb 2025 10:30:24 -0500 Subject: [PATCH 1621/1772] ci: update deps.toml --- proposals/cli/.github/workflows/update.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/cli/.github/workflows/update.yml b/proposals/cli/.github/workflows/update.yml index bdf61d30c..a0b1112e6 100644 --- a/proposals/cli/.github/workflows/update.yml +++ b/proposals/cli/.github/workflows/update.yml @@ -40,6 +40,8 @@ jobs: # upgrade - name: Upgrade tag run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + + - name: Upgrade tag + run: find . -type f -name "deps.toml" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - name: Upgrade wit deps run: wit-deps update - name: Generate markdown From 467663290ba7b9ad372c2642aa5263d01789d870 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 16:59:01 +0100 Subject: [PATCH 1622/1772] fix markdown generation --- proposals/cli/.github/workflows/update.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/proposals/cli/.github/workflows/update.yml b/proposals/cli/.github/workflows/update.yml index a0b1112e6..e6ba2cd4f 100644 --- a/proposals/cli/.github/workflows/update.yml +++ b/proposals/cli/.github/workflows/update.yml @@ -44,8 +44,10 @@ jobs: run: find . -type f -name "deps.toml" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - name: Upgrade wit deps run: wit-deps update - - name: Generate markdown - run: wit-bindgen markdown wit --html-in-md --all-features + - name: Generate markdown for the command world + run: wit-bindgen markdown wit -w command --html-in-md --all-features + - name: Generate markdown for the imports world + run: wit-bindgen markdown wit -w imports --html-in-md --all-features # file PR - name: Create feature branch From 2f8b2d8534479468138e35284881e23a09026b9a Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 16:21:29 +0100 Subject: [PATCH 1623/1772] Add "update" action --- proposals/http/.github/workflows/publish.yml | 4 +- proposals/http/.github/workflows/update.yml | 64 ++++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 proposals/http/.github/workflows/update.yml diff --git a/proposals/http/.github/workflows/publish.yml b/proposals/http/.github/workflows/publish.yml index 9cfcdb968..5d691b7c4 100644 --- a/proposals/http/.github/workflows/publish.yml +++ b/proposals/http/.github/workflows/publish.yml @@ -16,7 +16,7 @@ jobs: permissions: id-token: write packages: write - contents: read + contents: write steps: # Checkout the repo and install dependencies @@ -45,7 +45,7 @@ jobs: with: registry: ghcr.io username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + password: ${{ secrets.PAT_TOKEN }} # Build our `.wit` files into a Wasm binary - name: Build diff --git a/proposals/http/.github/workflows/update.yml b/proposals/http/.github/workflows/update.yml new file mode 100644 index 000000000..bdf61d30c --- /dev/null +++ b/proposals/http/.github/workflows/update.yml @@ -0,0 +1,64 @@ +name: Create a PR to upgrade WIT to a new version + +# Manually dispatch this action from the Actions page +on: + workflow_dispatch: + inputs: + prev_version: + description: 'Upgrading from version (without the v)' + required: true + type: string + next_version: + description: 'Upgrading to version (without the v)' + required: true + type: string + +permissions: + pull-requests: write + contents: write + +jobs: + update-versions: + runs-on: ubuntu-latest + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.10.15 + - name: Install wit-bindgen + shell: bash + run: cargo binstall wit-bindgen-cli + - name: Install wit-deps + shell: bash + run: cargo binstall wit-deps-cli + + # echo input + - name: Print the versions + run: echo Upgrading from ${{ inputs.prev_version }} to ${{ inputs.next_version }} + + # upgrade + - name: Upgrade tag + run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + + - name: Upgrade wit deps + run: wit-deps update + - name: Generate markdown + run: wit-bindgen markdown wit --html-in-md --all-features + + # file PR + - name: Create feature branch + env: + FEATURE_BRANCH: release-v${{ inputs.next_version }} + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add . + git checkout -b $FEATURE_BRANCH + git push -u origin $FEATURE_BRANCH + git commit -m "Update to v${{ inputs.next_version }}" + git push + + - name: Create pull request + run: gh pr create -B main -H release-v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From d95032a8b0eb8f31b63377e2744bd3dc403f489a Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 16:58:15 +0100 Subject: [PATCH 1624/1772] generate markdown for both worlds --- proposals/http/.github/workflows/update.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/proposals/http/.github/workflows/update.yml b/proposals/http/.github/workflows/update.yml index bdf61d30c..f65b676da 100644 --- a/proposals/http/.github/workflows/update.yml +++ b/proposals/http/.github/workflows/update.yml @@ -42,8 +42,10 @@ jobs: run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - name: Upgrade wit deps run: wit-deps update - - name: Generate markdown - run: wit-bindgen markdown wit --html-in-md --all-features + - name: Generate markdown for the proxy world + run: wit-bindgen markdown wit -w proxy --html-in-md --all-features + - name: Generate markdown for the imports world + run: wit-bindgen markdown wit -w imports --html-in-md --all-features # file PR - name: Create feature branch From d0ee7f592dbaada22ca5efd328e2dff1e6ae8476 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 17:04:17 +0100 Subject: [PATCH 1625/1772] Update publish.yml --- proposals/http/.github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/.github/workflows/publish.yml b/proposals/http/.github/workflows/publish.yml index 5d691b7c4..2c78c373d 100644 --- a/proposals/http/.github/workflows/publish.yml +++ b/proposals/http/.github/workflows/publish.yml @@ -45,7 +45,7 @@ jobs: with: registry: ghcr.io username: ${{ github.actor }} - password: ${{ secrets.PAT_TOKEN }} + password: ${{ secrets.ORG_PAT }} # Build our `.wit` files into a Wasm binary - name: Build From ae259e2286636fc59e85b7c8069ae4e99cf6b8b2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:08:25 +0000 Subject: [PATCH 1626/1772] Update to v0.2.4 --- proposals/cli/command.md | 205 ++++++++++++----- proposals/cli/imports.md | 207 +++++++++++++----- proposals/cli/wit/command.wit | 2 +- proposals/cli/wit/deps.lock | 26 +-- proposals/cli/wit/deps.toml | 6 +- .../cli/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/cli/wit/deps/clocks/timezone.wit | 2 +- proposals/cli/wit/deps/clocks/wall-clock.wit | 2 +- proposals/cli/wit/deps/clocks/world.wit | 2 +- .../cli/wit/deps/filesystem/preopens.wit | 2 +- proposals/cli/wit/deps/filesystem/types.wit | 10 +- proposals/cli/wit/deps/filesystem/world.wit | 2 +- proposals/cli/wit/deps/io/error.wit | 2 +- proposals/cli/wit/deps/io/poll.wit | 26 +-- proposals/cli/wit/deps/io/streams.wit | 2 +- proposals/cli/wit/deps/io/world.wit | 2 +- .../cli/wit/deps/random/insecure-seed.wit | 2 +- proposals/cli/wit/deps/random/insecure.wit | 2 +- proposals/cli/wit/deps/random/random.wit | 2 +- proposals/cli/wit/deps/random/world.wit | 2 +- .../cli/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/cli/wit/deps/sockets/network.wit | 2 +- proposals/cli/wit/deps/sockets/tcp.wit | 6 +- proposals/cli/wit/deps/sockets/udp.wit | 2 +- proposals/cli/wit/deps/sockets/world.wit | 2 +- proposals/cli/wit/imports.wit | 12 +- proposals/cli/wit/stdio.wit | 6 +- 27 files changed, 364 insertions(+), 178 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index b25b71e82..ee3d65058 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -2,42 +2,43 @@ -

                      Import interface wasi:cli/environment@0.2.3

                      +

                      Import interface wasi:cli/environment@0.2.4


                      Functions

                      get-environment: func

                      @@ -64,7 +65,7 @@ directory, interpreting . as shorthand for this.

                      • option<string>
                      -

                      Import interface wasi:cli/exit@0.2.3

                      +

                      Import interface wasi:cli/exit@0.2.4


                      Functions

                      exit: func

                      @@ -84,7 +85,7 @@ without the connotation that something bad has happened.

                      • status-code: u8
                      -

                      Import interface wasi:io/error@0.2.3

                      +

                      Import interface wasi:io/error@0.2.4


                      Types

                      resource error

                      @@ -117,7 +118,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/poll@0.2.3

                      +

                      Import interface wasi:io/poll@0.2.4

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -170,7 +171,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:io/streams@0.2.3

                      +

                      Import interface wasi:io/streams@0.2.4

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -500,7 +501,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.3

                      +

                      Import interface wasi:cli/stdin@0.2.4


                      Types

                      type input-stream

                      @@ -513,7 +514,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.3

                      +

                      Import interface wasi:cli/stdout@0.2.4


                      Types

                      type output-stream

                      @@ -526,7 +527,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.3

                      +

                      Import interface wasi:cli/stderr@0.2.4


                      Types

                      type output-stream

                      @@ -539,7 +540,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/terminal-input@0.2.3

                      +

                      Import interface wasi:cli/terminal-input@0.2.4

                      Terminal input.

                      In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -548,7 +549,7 @@ immediately, querying supported features, and so on.

                      Types

                      resource terminal-input

                      The input side of a terminal.

                      -

                      Import interface wasi:cli/terminal-output@0.2.3

                      +

                      Import interface wasi:cli/terminal-output@0.2.4

                      Terminal output.

                      In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -557,7 +558,7 @@ features, and so on.

                      Types

                      resource terminal-output

                      The output side of a terminal.

                      -

                      Import interface wasi:cli/terminal-stdin@0.2.3

                      +

                      Import interface wasi:cli/terminal-stdin@0.2.4

                      An interface providing an optional terminal-input for stdin as a link-time authority.


                      @@ -574,7 +575,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stdout@0.2.3

                      +

                      Import interface wasi:cli/terminal-stdout@0.2.4

                      An interface providing an optional terminal-output for stdout as a link-time authority.


                      @@ -591,7 +592,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stderr@0.2.3

                      +

                      Import interface wasi:cli/terminal-stderr@0.2.4

                      An interface providing an optional terminal-output for stderr as a link-time authority.


                      @@ -608,7 +609,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.3

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.4

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -667,7 +668,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.3

                      +

                      Import interface wasi:clocks/wall-clock@0.2.4

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -708,7 +709,72 @@ also known as Unix Time.
                    28. datetime
                    29. -

                      Import interface wasi:filesystem/types@0.2.3

                      +

                      Import interface wasi:clocks/timezone@0.2.4

                      +
                      +

                      Types

                      +

                      type datetime

                      +

                      datetime

                      +

                      +#### `record timezone-display` +

                      Information useful for displaying the timezone of a specific datetime.

                      +

                      This information may vary within a single timezone to reflect daylight +saving time adjustments.

                      +
                      Record Fields
                      +
                        +
                      • +

                        utc-offset: s32

                        +

                        The number of seconds difference between UTC time and the local +time of the timezone. +

                        The returned value will always be less than 86400 which is the +number of seconds in a day (246060).

                        +

                        In implementations that do not expose an actual time zone, this +should return 0.

                        +
                      • +
                      • +

                        name: string

                        +

                        The abbreviated name of the timezone to display to a user. The name +`UTC` indicates Coordinated Universal Time. Otherwise, this should +reference local standards for the name of the time zone. +

                        In implementations that do not expose an actual time zone, this +should be the string UTC.

                        +

                        In time zones that do not have an applicable name, a formatted +representation of the UTC offset may be returned, such as -04:00.

                        +
                      • +
                      • +

                        in-daylight-saving-time: bool

                        +

                        Whether daylight saving time is active. +

                        In implementations that do not expose an actual time zone, this +should return false.

                        +
                      • +
                      +
                      +

                      Functions

                      +

                      display: func

                      +

                      Return information needed to display the given datetime. This includes +the UTC offset, the time zone name, and a flag indicating whether +daylight saving time is active.

                      +

                      If the timezone cannot be determined for the given datetime, return a +timezone-display for UTC with a utc-offset of 0 and no daylight +saving time.

                      +
                      Params
                      + +
                      Return values
                      + +

                      utc-offset: func

                      +

                      The same as display, but only return the UTC offset.

                      +
                      Params
                      + +
                      Return values
                      +
                        +
                      • s32
                      • +
                      +

                      Import interface wasi:filesystem/types@0.2.4

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                      @@ -1397,6 +1463,9 @@ WASI.

                      [method]descriptor.link-at: func

                      Create a hard link.

                      +

                      Fails with error-code::no-entry if the old path does not exist, +with error-code::exist if the new path already exists, and +error-code::not-permitted if the old path is not a file.

                      Note: This is similar to linkat in POSIX.

                      Params
                        @@ -1583,7 +1652,7 @@ errors are filesystem-related errors.

                        -

                        Import interface wasi:filesystem/preopens@0.2.3

                        +

                        Import interface wasi:filesystem/preopens@0.2.4


                        Types

                        type descriptor

                        @@ -1597,10 +1666,13 @@ errors are filesystem-related errors.

                        -

                        Import interface wasi:sockets/network@0.2.3

                        +

                        Import interface wasi:sockets/network@0.2.4


                        Types

                        -

                        resource network

                        +

                        type error

                        +

                        error

                        +

                        +#### `resource network`

                        An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                        @@ -1790,7 +1862,26 @@ supported size.
                      • ipv4: ipv4-socket-address
                      • ipv6: ipv6-socket-address
                      -

                      Import interface wasi:sockets/instance-network@0.2.3

                      +
                      +

                      Functions

                      +

                      network-error-code: func

                      +

                      Attempts to extract a network-related error-code from the stream +error provided.

                      +

                      Stream operations which return stream-error::last-operation-failed +have a payload with more information about the operation that failed. +This payload can be passed through to this function to see if there's +network-related information about the error to return.

                      +

                      Note that this function is fallible because not all stream-related +errors are network-related errors.

                      +
                      Params
                      + +
                      Return values
                      + +

                      Import interface wasi:sockets/instance-network@0.2.4

                      This interface provides a value-export of the default network handle..


                      Types

                      @@ -1805,7 +1896,7 @@ supported size. -

                      Import interface wasi:sockets/udp@0.2.3

                      +

                      Import interface wasi:sockets/udp@0.2.4


                      Types

                      type pollable

                      @@ -2219,7 +2310,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:sockets/udp-create-socket@0.2.3

                      +

                      Import interface wasi:sockets/udp-create-socket@0.2.4


                      Types

                      type network

                      @@ -2264,7 +2355,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                      Import interface wasi:sockets/tcp@0.2.3

                      +

                      Import interface wasi:sockets/tcp@0.2.4


                      Types

                      type input-stream

                      @@ -2855,7 +2946,7 @@ has no effect and returns ok.

                      -

                      Import interface wasi:sockets/tcp-create-socket@0.2.3

                      +

                      Import interface wasi:sockets/tcp-create-socket@0.2.4


                      Types

                      type network

                      @@ -2900,7 +2991,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                      Import interface wasi:sockets/ip-name-lookup@0.2.3

                      +

                      Import interface wasi:sockets/ip-name-lookup@0.2.4


                      Types

                      type pollable

                      @@ -2980,7 +3071,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:random/random@0.2.3

                      +

                      Import interface wasi:random/random@0.2.4

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3013,7 +3104,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:random/insecure@0.2.3

                      +

                      Import interface wasi:random/insecure@0.2.4

                      The insecure interface for insecure pseudo-random numbers.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3042,7 +3133,7 @@ a long period.

                      • u64
                      -

                      Import interface wasi:random/insecure-seed@0.2.3

                      +

                      Import interface wasi:random/insecure-seed@0.2.4

                      The insecure-seed interface for seeding hash-map DoS resistance.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3066,7 +3157,7 @@ protection.

                      • (u64, u64)
                      -

                      Export interface wasi:cli/run@0.2.3

                      +

                      Export interface wasi:cli/run@0.2.4


                      Functions

                      run: func

                      diff --git a/proposals/cli/imports.md b/proposals/cli/imports.md index a264d431c..58c8d2995 100644 --- a/proposals/cli/imports.md +++ b/proposals/cli/imports.md @@ -2,37 +2,38 @@ -

                      Import interface wasi:cli/environment@0.2.3

                      +
                    30. interface wasi:cli/environment@0.2.4
                    31. +
                    32. interface wasi:cli/exit@0.2.4
                    33. +
                    34. interface wasi:io/error@0.2.4
                    35. +
                    36. interface wasi:io/poll@0.2.4
                    37. +
                    38. interface wasi:io/streams@0.2.4
                    39. +
                    40. interface wasi:cli/stdin@0.2.4
                    41. +
                    42. interface wasi:cli/stdout@0.2.4
                    43. +
                    44. interface wasi:cli/stderr@0.2.4
                    45. +
                    46. interface wasi:cli/terminal-input@0.2.4
                    47. +
                    48. interface wasi:cli/terminal-output@0.2.4
                    49. +
                    50. interface wasi:cli/terminal-stdin@0.2.4
                    51. +
                    52. interface wasi:cli/terminal-stdout@0.2.4
                    53. +
                    54. interface wasi:cli/terminal-stderr@0.2.4
                    55. +
                    56. interface wasi:clocks/monotonic-clock@0.2.4
                    57. +
                    58. interface wasi:clocks/wall-clock@0.2.4
                    59. +
                    60. interface wasi:clocks/timezone@0.2.4
                    61. +
                    62. interface wasi:filesystem/types@0.2.4
                    63. +
                    64. interface wasi:filesystem/preopens@0.2.4
                    65. +
                    66. interface wasi:sockets/network@0.2.4
                    67. +
                    68. interface wasi:sockets/instance-network@0.2.4
                    69. +
                    70. interface wasi:sockets/udp@0.2.4
                    71. +
                    72. interface wasi:sockets/udp-create-socket@0.2.4
                    73. +
                    74. interface wasi:sockets/tcp@0.2.4
                    75. +
                    76. interface wasi:sockets/tcp-create-socket@0.2.4
                    77. +
                    78. interface wasi:sockets/ip-name-lookup@0.2.4
                    79. +
                    80. interface wasi:random/random@0.2.4
                    81. +
                    82. interface wasi:random/insecure@0.2.4
                    83. +
                    84. interface wasi:random/insecure-seed@0.2.4
                    85. + + + +

                      Import interface wasi:cli/environment@0.2.4


                      Functions

                      get-environment: func

                      @@ -59,7 +60,7 @@ directory, interpreting . as shorthand for this.

                      • option<string>
                      -

                      Import interface wasi:cli/exit@0.2.3

                      +

                      Import interface wasi:cli/exit@0.2.4


                      Functions

                      exit: func

                      @@ -79,7 +80,7 @@ without the connotation that something bad has happened.

                      • status-code: u8
                      -

                      Import interface wasi:io/error@0.2.3

                      +

                      Import interface wasi:io/error@0.2.4


                      Types

                      resource error

                      @@ -112,7 +113,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/poll@0.2.3

                      +

                      Import interface wasi:io/poll@0.2.4

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -165,7 +166,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:io/streams@0.2.3

                      +

                      Import interface wasi:io/streams@0.2.4

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -495,7 +496,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.3

                      +

                      Import interface wasi:cli/stdin@0.2.4


                      Types

                      type input-stream

                      @@ -508,7 +509,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.3

                      +

                      Import interface wasi:cli/stdout@0.2.4


                      Types

                      type output-stream

                      @@ -521,7 +522,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.3

                      +

                      Import interface wasi:cli/stderr@0.2.4


                      Types

                      type output-stream

                      @@ -534,7 +535,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/terminal-input@0.2.3

                      +

                      Import interface wasi:cli/terminal-input@0.2.4

                      Terminal input.

                      In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -543,7 +544,7 @@ immediately, querying supported features, and so on.

                      Types

                      resource terminal-input

                      The input side of a terminal.

                      -

                      Import interface wasi:cli/terminal-output@0.2.3

                      +

                      Import interface wasi:cli/terminal-output@0.2.4

                      Terminal output.

                      In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -552,7 +553,7 @@ features, and so on.

                      Types

                      resource terminal-output

                      The output side of a terminal.

                      -

                      Import interface wasi:cli/terminal-stdin@0.2.3

                      +

                      Import interface wasi:cli/terminal-stdin@0.2.4

                      An interface providing an optional terminal-input for stdin as a link-time authority.


                      @@ -569,7 +570,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stdout@0.2.3

                      +

                      Import interface wasi:cli/terminal-stdout@0.2.4

                      An interface providing an optional terminal-output for stdout as a link-time authority.


                      @@ -586,7 +587,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stderr@0.2.3

                      +

                      Import interface wasi:cli/terminal-stderr@0.2.4

                      An interface providing an optional terminal-output for stderr as a link-time authority.


                      @@ -603,7 +604,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.3

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.4

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -662,7 +663,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.3

                      +

                      Import interface wasi:clocks/wall-clock@0.2.4

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -703,7 +704,72 @@ also known as Unix Time.
                    86. datetime
                    87. -

                      Import interface wasi:filesystem/types@0.2.3

                      +

                      Import interface wasi:clocks/timezone@0.2.4

                      +
                      +

                      Types

                      +

                      type datetime

                      +

                      datetime

                      +

                      +#### `record timezone-display` +

                      Information useful for displaying the timezone of a specific datetime.

                      +

                      This information may vary within a single timezone to reflect daylight +saving time adjustments.

                      +
                      Record Fields
                      +
                        +
                      • +

                        utc-offset: s32

                        +

                        The number of seconds difference between UTC time and the local +time of the timezone. +

                        The returned value will always be less than 86400 which is the +number of seconds in a day (246060).

                        +

                        In implementations that do not expose an actual time zone, this +should return 0.

                        +
                      • +
                      • +

                        name: string

                        +

                        The abbreviated name of the timezone to display to a user. The name +`UTC` indicates Coordinated Universal Time. Otherwise, this should +reference local standards for the name of the time zone. +

                        In implementations that do not expose an actual time zone, this +should be the string UTC.

                        +

                        In time zones that do not have an applicable name, a formatted +representation of the UTC offset may be returned, such as -04:00.

                        +
                      • +
                      • +

                        in-daylight-saving-time: bool

                        +

                        Whether daylight saving time is active. +

                        In implementations that do not expose an actual time zone, this +should return false.

                        +
                      • +
                      +
                      +

                      Functions

                      +

                      display: func

                      +

                      Return information needed to display the given datetime. This includes +the UTC offset, the time zone name, and a flag indicating whether +daylight saving time is active.

                      +

                      If the timezone cannot be determined for the given datetime, return a +timezone-display for UTC with a utc-offset of 0 and no daylight +saving time.

                      +
                      Params
                      + +
                      Return values
                      + +

                      utc-offset: func

                      +

                      The same as display, but only return the UTC offset.

                      +
                      Params
                      + +
                      Return values
                      +
                        +
                      • s32
                      • +
                      +

                      Import interface wasi:filesystem/types@0.2.4

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                      @@ -1392,6 +1458,9 @@ WASI.

                      [method]descriptor.link-at: func

                      Create a hard link.

                      +

                      Fails with error-code::no-entry if the old path does not exist, +with error-code::exist if the new path already exists, and +error-code::not-permitted if the old path is not a file.

                      Note: This is similar to linkat in POSIX.

                      Params
                        @@ -1578,7 +1647,7 @@ errors are filesystem-related errors.

                        -

                        Import interface wasi:filesystem/preopens@0.2.3

                        +

                        Import interface wasi:filesystem/preopens@0.2.4


                        Types

                        type descriptor

                        @@ -1592,10 +1661,13 @@ errors are filesystem-related errors.

                        -

                        Import interface wasi:sockets/network@0.2.3

                        +

                        Import interface wasi:sockets/network@0.2.4


                        Types

                        -

                        resource network

                        +

                        type error

                        +

                        error

                        +

                        +#### `resource network`

                        An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                        @@ -1785,7 +1857,26 @@ supported size.
                      • ipv4: ipv4-socket-address
                      • ipv6: ipv6-socket-address
                      -

                      Import interface wasi:sockets/instance-network@0.2.3

                      +
                      +

                      Functions

                      +

                      network-error-code: func

                      +

                      Attempts to extract a network-related error-code from the stream +error provided.

                      +

                      Stream operations which return stream-error::last-operation-failed +have a payload with more information about the operation that failed. +This payload can be passed through to this function to see if there's +network-related information about the error to return.

                      +

                      Note that this function is fallible because not all stream-related +errors are network-related errors.

                      +
                      Params
                      + +
                      Return values
                      + +

                      Import interface wasi:sockets/instance-network@0.2.4

                      This interface provides a value-export of the default network handle..


                      Types

                      @@ -1800,7 +1891,7 @@ supported size. -

                      Import interface wasi:sockets/udp@0.2.3

                      +

                      Import interface wasi:sockets/udp@0.2.4


                      Types

                      type pollable

                      @@ -2214,7 +2305,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:sockets/udp-create-socket@0.2.3

                      +

                      Import interface wasi:sockets/udp-create-socket@0.2.4


                      Types

                      type network

                      @@ -2259,7 +2350,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                      Import interface wasi:sockets/tcp@0.2.3

                      +

                      Import interface wasi:sockets/tcp@0.2.4


                      Types

                      type input-stream

                      @@ -2850,7 +2941,7 @@ has no effect and returns ok.

                      -

                      Import interface wasi:sockets/tcp-create-socket@0.2.3

                      +

                      Import interface wasi:sockets/tcp-create-socket@0.2.4


                      Types

                      type network

                      @@ -2895,7 +2986,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                      Import interface wasi:sockets/ip-name-lookup@0.2.3

                      +

                      Import interface wasi:sockets/ip-name-lookup@0.2.4


                      Types

                      type pollable

                      @@ -2975,7 +3066,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:random/random@0.2.3

                      +

                      Import interface wasi:random/random@0.2.4

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3008,7 +3099,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:random/insecure@0.2.3

                      +

                      Import interface wasi:random/insecure@0.2.4

                      The insecure interface for insecure pseudo-random numbers.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3037,7 +3128,7 @@ a long period.

                      • u64
                      -

                      Import interface wasi:random/insecure-seed@0.2.3

                      +

                      Import interface wasi:random/insecure-seed@0.2.4

                      The insecure-seed interface for seeding hash-map DoS resistance.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index 3a81766d6..88ab2a97e 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.3; +package wasi:cli@0.2.4; @since(version = 0.2.0) world command { diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index 889946b16..e80ab8753 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,24 +1,24 @@ [clocks] -sha256 = "93a701968a7dd3c5d69031bc0601681c468972fdf7e28a93bb6150a67d6ebe8b" -sha512 = "98fca567c7a01887b0fb38981f1772169b6ea8de475b546508f8b86738d84e44ba95cae81def40ac34e8809f5f60e85224077ab8cb6d6d5d6296acc1df73c159" +sha256 = "fc36267c5098ad9ac6455396b27c8ef206ca23cae74f40bd44c57be68e7849b6" +sha512 = "0deed3d3a86f284adda7991cd24c0c4aab806ba2e0cb111da80d7f99c05f10793a602b28451407cad58ab762997f60c0f6d173e919e4a0988773b455d3a410d3" [filesystem] -url = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.3.tar.gz" -sha256 = "69d42fb10a04a33545b17e055f13db9b1e10e82ba0ed5bdb52334e40dc07c679" -sha512 = "612effbac6f4804fe0c29dae20b78bbba59e52cb754c15402f5fe229c3153a221e0fbdff1d9d00ceaa3fe049c6a95523a5b99f772f1c16d972eade2c88326a30" +url = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.4.tar.gz" +sha256 = "dd435f78b23714bd9d51ef3789c43b831549e71f54b57394a41bbf0c4da45f42" +sha512 = "d58bcf6eae908a6b2d883bcdfe456dc31aa99c848d0b3d21f710bde5bbb59ec105dbd5085004eadd0faa938530e4c29f88e589f525c080eb6d5971775a0b64ed" deps = ["clocks", "io"] [io] -sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" -sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" +sha256 = "770a73d479cda8e4c4064dd4006d2654ebcc358952079d74e41af27cf26bddbf" +sha512 = "b790f9750ac6782d9aaaa379845600b66dbde14ecee42f159c29796447eb8e61ee61f3b306e92622993b5e25298834b6ff62d7d9a04f8f18c05f07eda8f47ae0" [random] -url = "https://github.com/WebAssembly/wasi-random/archive/v0.2.3.tar.gz" -sha256 = "dd0c91e7125172eb8fd4568e15ad9fc7305643015e6ece4396c3cc5e8c2bf79a" -sha512 = "d1ca2e7b0616a94a3b39d1b9450bb3fb595b01fd94a8626ad75433038dde40988ecb41ab93a374d569ab72163af3b30038d7bfc3499b9c07193181f4f1d9292a" +url = "https://github.com/WebAssembly/wasi-random/archive/v0.2.4.tar.gz" +sha256 = "876d81b0a777f1dc9db215fa36f45898a907188819185d6b189345f28c081a45" +sha512 = "fc6a0ed97e0525456222b28bcc49431bade826a97cb6eb52cde595908865d1ed7835c54a63b408ba82e3d49061aebb9a8725d1d2316d28c0ccb12af8ec968ab8" [sockets] -url = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.3.tar.gz" -sha256 = "2bc0f65a8046207ee3330ad7d63f6fafeafd4cc0ea4084f081bd5e4f7b177e74" -sha512 = "3e5490e41547dffa78d52631825d93da8d60f4af0246cbaf97e1ecb879285953a86d5f1f390b10c32f91dd7eaec6f43e625a26b1c92c32a0c86fde428aedaaab" +url = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.4.tar.gz" +sha256 = "e6872db116eb02f2043c4238999712de19bdb22e3c8da00af563f8b6c4dabb18" +sha512 = "28c05fe8acd691d808b6a90b950483bbf59983c02e91ed4a89b0e06c3e2a27e0f73be678979309553f0889fc3fea00c4740b007946d7285aa554dc65d56b1b7f" deps = ["clocks", "io"] diff --git a/proposals/cli/wit/deps.toml b/proposals/cli/wit/deps.toml index 6b2e9eb93..0b2cbed2b 100644 --- a/proposals/cli/wit/deps.toml +++ b/proposals/cli/wit/deps.toml @@ -1,3 +1,3 @@ -filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.3.tar.gz" -random = "https://github.com/WebAssembly/wasi-random/archive/v0.2.3.tar.gz" -sockets = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.3.tar.gz" +filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.4.tar.gz" +random = "https://github.com/WebAssembly/wasi-random/archive/v0.2.4.tar.gz" +sockets = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.4.tar.gz" diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index c676fb84d..175f8fe2d 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.3; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/cli/wit/deps/clocks/timezone.wit b/proposals/cli/wit/deps/clocks/timezone.wit index b43e93b23..658cb17e7 100644 --- a/proposals/cli/wit/deps/clocks/timezone.wit +++ b/proposals/cli/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit index e00ce0893..f826cd1e0 100644 --- a/proposals/cli/wit/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/cli/wit/deps/clocks/world.wit b/proposals/cli/wit/deps/clocks/world.wit index 05f04f797..9e2087447 100644 --- a/proposals/cli/wit/deps/clocks/world.wit +++ b/proposals/cli/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/filesystem/preopens.wit b/proposals/cli/wit/deps/filesystem/preopens.wit index cea97495b..6e6003954 100644 --- a/proposals/cli/wit/deps/filesystem/preopens.wit +++ b/proposals/cli/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.3; +package wasi:filesystem@0.2.4; @since(version = 0.2.0) interface preopens { diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index d229a21f4..962cadfef 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.3; +package wasi:filesystem@0.2.4; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.3; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.4.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.3.{datetime}; + use wasi:clocks/wall-clock@0.2.4.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) @@ -508,6 +508,10 @@ interface types { /// Create a hard link. /// + /// Fails with `error-code::no-entry` if the old path does not exist, + /// with `error-code::exist` if the new path already exists, and + /// `error-code::not-permitted` if the old path is not a file. + /// /// Note: This is similar to `linkat` in POSIX. @since(version = 0.2.0) link-at: func( diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit index 29405bc2c..7742ed6bb 100644 --- a/proposals/cli/wit/deps/filesystem/world.wit +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.3; +package wasi:filesystem@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/io/error.wit b/proposals/cli/wit/deps/io/error.wit index 97c606877..eb0600f9e 100644 --- a/proposals/cli/wit/deps/io/error.wit +++ b/proposals/cli/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; @since(version = 0.2.0) interface error { diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit index 9bcbe8e03..170deff70 100644 --- a/proposals/cli/wit/deps/io/poll.wit +++ b/proposals/cli/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. @@ -8,19 +8,19 @@ interface poll { @since(version = 0.2.0) resource pollable { - /// Return the readiness of a pollable. This function never blocks. - /// - /// Returns `true` when the pollable is ready, and `false` otherwise. - @since(version = 0.2.0) - ready: func() -> bool; + /// Return the readiness of a pollable. This function never blocks. + /// + /// Returns `true` when the pollable is ready, and `false` otherwise. + @since(version = 0.2.0) + ready: func() -> bool; - /// `block` returns immediately if the pollable is ready, and otherwise - /// blocks until ready. - /// - /// This function is equivalent to calling `poll.poll` on a list - /// containing only this pollable. - @since(version = 0.2.0) - block: func(); + /// `block` returns immediately if the pollable is ready, and otherwise + /// blocks until ready. + /// + /// This function is equivalent to calling `poll.poll` on a list + /// containing only this pollable. + @since(version = 0.2.0) + block: func(); } /// Poll for completion on a set of pollables. diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index 0de084629..bb9a31e81 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/cli/wit/deps/io/world.wit b/proposals/cli/wit/deps/io/world.wit index f1d2102dc..8e0fa5c53 100644 --- a/proposals/cli/wit/deps/io/world.wit +++ b/proposals/cli/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/random/insecure-seed.wit b/proposals/cli/wit/deps/random/insecure-seed.wit index 67d024d5b..45e8bafdb 100644 --- a/proposals/cli/wit/deps/random/insecure-seed.wit +++ b/proposals/cli/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/insecure.wit b/proposals/cli/wit/deps/random/insecure.wit index a07dfab32..5ab5030c5 100644 --- a/proposals/cli/wit/deps/random/insecure.wit +++ b/proposals/cli/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index 91957e633..9e5220d82 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/world.wit b/proposals/cli/wit/deps/random/world.wit index 0c1218f36..d89055819 100644 --- a/proposals/cli/wit/deps/random/world.wit +++ b/proposals/cli/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index c1d8a47c1..48b41a5b1 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit index f3f60a370..aa4985e14 100644 --- a/proposals/cli/wit/deps/sockets/network.wit +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.3.{error}; + use wasi:io/error@0.2.4.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index b4cd87fce..b3311332f 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{input-stream, output-stream}; + use wasi:io/streams@0.2.4.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.3.{duration}; + use wasi:clocks/monotonic-clock@0.2.4.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index 01901ca27..cfc07ba81 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit index 2f0ad0d7c..82acdb9f0 100644 --- a/proposals/cli/wit/deps/sockets/world.wit +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.3; +package wasi:sockets@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/imports.wit b/proposals/cli/wit/imports.wit index 8b4e3975e..ad5c6bb23 100644 --- a/proposals/cli/wit/imports.wit +++ b/proposals/cli/wit/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.3; +package wasi:cli@0.2.4; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.3; + include wasi:clocks/imports@0.2.4; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.3; + include wasi:filesystem/imports@0.2.4; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.3; + include wasi:sockets/imports@0.2.4; @since(version = 0.2.0) - include wasi:random/imports@0.2.3; + include wasi:random/imports@0.2.4; @since(version = 0.2.0) - include wasi:io/imports@0.2.3; + include wasi:io/imports@0.2.4; @since(version = 0.2.0) import environment; diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index 1b54f5318..60727a930 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{input-stream}; + use wasi:io/streams@0.2.4.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{output-stream}; + use wasi:io/streams@0.2.4.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{output-stream}; + use wasi:io/streams@0.2.4.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; From c1efed83057dde6af6ba788354297a74b4b99316 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 17:22:37 +0100 Subject: [PATCH 1627/1772] Update update.yml --- proposals/cli/.github/workflows/update.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/cli/.github/workflows/update.yml b/proposals/cli/.github/workflows/update.yml index e6ba2cd4f..34ffe2fd9 100644 --- a/proposals/cli/.github/workflows/update.yml +++ b/proposals/cli/.github/workflows/update.yml @@ -45,9 +45,9 @@ jobs: - name: Upgrade wit deps run: wit-deps update - name: Generate markdown for the command world - run: wit-bindgen markdown wit -w command --html-in-md --all-features + run: wit-bindgen markdown wit -w command --html-in-md --features=cli-with-exit-code - name: Generate markdown for the imports world - run: wit-bindgen markdown wit -w imports --html-in-md --all-features + run: wit-bindgen markdown wit -w imports --html-in-md --features=cli-with-exit-code # file PR - name: Create feature branch From 9649c84a0e8aebb77c5e5285b003bb43e6dd6267 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 17:25:16 +0100 Subject: [PATCH 1628/1772] run html gen --- proposals/cli/command.md | 90 +--------------------------------------- proposals/cli/imports.md | 90 +--------------------------------------- 2 files changed, 2 insertions(+), 178 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index ee3d65058..1350bc214 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -17,7 +17,6 @@
                    88. interface wasi:cli/terminal-stderr@0.2.4
                    89. interface wasi:clocks/monotonic-clock@0.2.4
                    90. interface wasi:clocks/wall-clock@0.2.4
                    91. -
                    92. interface wasi:clocks/timezone@0.2.4
                    93. interface wasi:filesystem/types@0.2.4
                    94. interface wasi:filesystem/preopens@0.2.4
                    95. interface wasi:sockets/network@0.2.4
                    96. @@ -709,71 +708,6 @@ also known as Unix Time.
                    97. datetime
                    98. -

                      Import interface wasi:clocks/timezone@0.2.4

                      -
                      -

                      Types

                      -

                      type datetime

                      -

                      datetime

                      -

                      -#### `record timezone-display` -

                      Information useful for displaying the timezone of a specific datetime.

                      -

                      This information may vary within a single timezone to reflect daylight -saving time adjustments.

                      -
                      Record Fields
                      -
                        -
                      • -

                        utc-offset: s32

                        -

                        The number of seconds difference between UTC time and the local -time of the timezone. -

                        The returned value will always be less than 86400 which is the -number of seconds in a day (246060).

                        -

                        In implementations that do not expose an actual time zone, this -should return 0.

                        -
                      • -
                      • -

                        name: string

                        -

                        The abbreviated name of the timezone to display to a user. The name -`UTC` indicates Coordinated Universal Time. Otherwise, this should -reference local standards for the name of the time zone. -

                        In implementations that do not expose an actual time zone, this -should be the string UTC.

                        -

                        In time zones that do not have an applicable name, a formatted -representation of the UTC offset may be returned, such as -04:00.

                        -
                      • -
                      • -

                        in-daylight-saving-time: bool

                        -

                        Whether daylight saving time is active. -

                        In implementations that do not expose an actual time zone, this -should return false.

                        -
                      • -
                      -
                      -

                      Functions

                      -

                      display: func

                      -

                      Return information needed to display the given datetime. This includes -the UTC offset, the time zone name, and a flag indicating whether -daylight saving time is active.

                      -

                      If the timezone cannot be determined for the given datetime, return a -timezone-display for UTC with a utc-offset of 0 and no daylight -saving time.

                      -
                      Params
                      - -
                      Return values
                      - -

                      utc-offset: func

                      -

                      The same as display, but only return the UTC offset.

                      -
                      Params
                      - -
                      Return values
                      -
                        -
                      • s32
                      • -

                      Import interface wasi:filesystem/types@0.2.4

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without @@ -1669,10 +1603,7 @@ errors are filesystem-related errors.

                      Import interface wasi:sockets/network@0.2.4


                      Types

                      -

                      type error

                      -

                      error

                      -

                      -#### `resource network` +

                      resource network

                      An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                      @@ -1862,25 +1793,6 @@ supported size.
                    99. ipv4: ipv4-socket-address
                    100. ipv6: ipv6-socket-address
                    101. -
                      -

                      Functions

                      -

                      network-error-code: func

                      -

                      Attempts to extract a network-related error-code from the stream -error provided.

                      -

                      Stream operations which return stream-error::last-operation-failed -have a payload with more information about the operation that failed. -This payload can be passed through to this function to see if there's -network-related information about the error to return.

                      -

                      Note that this function is fallible because not all stream-related -errors are network-related errors.

                      -
                      Params
                      - -
                      Return values
                      -

                      Import interface wasi:sockets/instance-network@0.2.4

                      This interface provides a value-export of the default network handle..


                      diff --git a/proposals/cli/imports.md b/proposals/cli/imports.md index 58c8d2995..1751177df 100644 --- a/proposals/cli/imports.md +++ b/proposals/cli/imports.md @@ -17,7 +17,6 @@
                    102. interface wasi:cli/terminal-stderr@0.2.4
                    103. interface wasi:clocks/monotonic-clock@0.2.4
                    104. interface wasi:clocks/wall-clock@0.2.4
                    105. -
                    106. interface wasi:clocks/timezone@0.2.4
                    107. interface wasi:filesystem/types@0.2.4
                    108. interface wasi:filesystem/preopens@0.2.4
                    109. interface wasi:sockets/network@0.2.4
                    110. @@ -704,71 +703,6 @@ also known as Unix Time.
                    111. datetime
                    112. -

                      Import interface wasi:clocks/timezone@0.2.4

                      -
                      -

                      Types

                      -

                      type datetime

                      -

                      datetime

                      -

                      -#### `record timezone-display` -

                      Information useful for displaying the timezone of a specific datetime.

                      -

                      This information may vary within a single timezone to reflect daylight -saving time adjustments.

                      -
                      Record Fields
                      -
                        -
                      • -

                        utc-offset: s32

                        -

                        The number of seconds difference between UTC time and the local -time of the timezone. -

                        The returned value will always be less than 86400 which is the -number of seconds in a day (246060).

                        -

                        In implementations that do not expose an actual time zone, this -should return 0.

                        -
                      • -
                      • -

                        name: string

                        -

                        The abbreviated name of the timezone to display to a user. The name -`UTC` indicates Coordinated Universal Time. Otherwise, this should -reference local standards for the name of the time zone. -

                        In implementations that do not expose an actual time zone, this -should be the string UTC.

                        -

                        In time zones that do not have an applicable name, a formatted -representation of the UTC offset may be returned, such as -04:00.

                        -
                      • -
                      • -

                        in-daylight-saving-time: bool

                        -

                        Whether daylight saving time is active. -

                        In implementations that do not expose an actual time zone, this -should return false.

                        -
                      • -
                      -
                      -

                      Functions

                      -

                      display: func

                      -

                      Return information needed to display the given datetime. This includes -the UTC offset, the time zone name, and a flag indicating whether -daylight saving time is active.

                      -

                      If the timezone cannot be determined for the given datetime, return a -timezone-display for UTC with a utc-offset of 0 and no daylight -saving time.

                      -
                      Params
                      - -
                      Return values
                      - -

                      utc-offset: func

                      -

                      The same as display, but only return the UTC offset.

                      -
                      Params
                      - -
                      Return values
                      -
                        -
                      • s32
                      • -

                      Import interface wasi:filesystem/types@0.2.4

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without @@ -1664,10 +1598,7 @@ errors are filesystem-related errors.

                      Import interface wasi:sockets/network@0.2.4


                      Types

                      -

                      type error

                      -

                      error

                      -

                      -#### `resource network` +

                      resource network

                      An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                      @@ -1857,25 +1788,6 @@ supported size.
                    113. ipv4: ipv4-socket-address
                    114. ipv6: ipv6-socket-address
                    115. -
                      -

                      Functions

                      -

                      network-error-code: func

                      -

                      Attempts to extract a network-related error-code from the stream -error provided.

                      -

                      Stream operations which return stream-error::last-operation-failed -have a payload with more information about the operation that failed. -This payload can be passed through to this function to see if there's -network-related information about the error to return.

                      -

                      Note that this function is fallible because not all stream-related -errors are network-related errors.

                      -
                      Params
                      - -
                      Return values
                      -

                      Import interface wasi:sockets/instance-network@0.2.4

                      This interface provides a value-export of the default network handle..


                      From 6c33b00d526d9b79ea40701817d8da53a8f30c92 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 6 Feb 2025 17:28:05 +0100 Subject: [PATCH 1629/1772] specify features --- proposals/http/.github/workflows/update.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/http/.github/workflows/update.yml b/proposals/http/.github/workflows/update.yml index f65b676da..f38266bc8 100644 --- a/proposals/http/.github/workflows/update.yml +++ b/proposals/http/.github/workflows/update.yml @@ -43,9 +43,9 @@ jobs: - name: Upgrade wit deps run: wit-deps update - name: Generate markdown for the proxy world - run: wit-bindgen markdown wit -w proxy --html-in-md --all-features + run: wit-bindgen markdown wit -w proxy --html-in-md --features=informational-outbound-responses - name: Generate markdown for the imports world - run: wit-bindgen markdown wit -w imports --html-in-md --all-features + run: wit-bindgen markdown wit -w imports --html-in-md --features=informational-outbound-responses # file PR - name: Create feature branch From 4f4f3ea5c7bec48a0a0702b82ed60e57b744b99b Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 6 Feb 2025 11:33:20 -0500 Subject: [PATCH 1630/1772] ci: find replace deps version in update --- proposals/http/.github/workflows/update.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/http/.github/workflows/update.yml b/proposals/http/.github/workflows/update.yml index f38266bc8..46ebb8329 100644 --- a/proposals/http/.github/workflows/update.yml +++ b/proposals/http/.github/workflows/update.yml @@ -40,6 +40,8 @@ jobs: # upgrade - name: Upgrade tag run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + + - name: Upgrade deps tags + run: find . -type f -name "deps.toml" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - name: Upgrade wit deps run: wit-deps update - name: Generate markdown for the proxy world From 4fc87fa4e8a5b69393fb13303bfd6ca875a1a037 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:35:26 +0000 Subject: [PATCH 1631/1772] Update to v0.2.4 --- proposals/http/imports.md | 63 +++++++++++------ proposals/http/proxy.md | 67 ++++++++++++------- proposals/http/wit-0.3.0-draft/deps.toml | 2 +- .../http/wit-0.3.0-draft/deps/cli/command.wit | 2 +- .../http/wit-0.3.0-draft/deps/cli/imports.wit | 12 ++-- .../http/wit-0.3.0-draft/deps/cli/stdio.wit | 6 +- .../deps/clocks/monotonic-clock.wit | 4 +- .../wit-0.3.0-draft/deps/clocks/timezone.wit | 2 +- .../deps/clocks/wall-clock.wit | 2 +- .../wit-0.3.0-draft/deps/clocks/world.wit | 2 +- .../deps/filesystem/preopens.wit | 2 +- .../wit-0.3.0-draft/deps/filesystem/types.wit | 6 +- .../wit-0.3.0-draft/deps/filesystem/world.wit | 2 +- .../http/wit-0.3.0-draft/deps/io/error.wit | 2 +- .../http/wit-0.3.0-draft/deps/io/poll.wit | 2 +- .../http/wit-0.3.0-draft/deps/io/streams.wit | 2 +- .../http/wit-0.3.0-draft/deps/io/world.wit | 2 +- .../deps/random/insecure-seed.wit | 2 +- .../wit-0.3.0-draft/deps/random/insecure.wit | 2 +- .../wit-0.3.0-draft/deps/random/random.wit | 2 +- .../wit-0.3.0-draft/deps/random/world.wit | 2 +- .../deps/sockets/ip-name-lookup.wit | 2 +- .../wit-0.3.0-draft/deps/sockets/network.wit | 2 +- .../http/wit-0.3.0-draft/deps/sockets/tcp.wit | 6 +- .../http/wit-0.3.0-draft/deps/sockets/udp.wit | 2 +- .../wit-0.3.0-draft/deps/sockets/world.wit | 2 +- proposals/http/wit-0.3.0-draft/proxy.wit | 6 +- proposals/http/wit/deps.lock | 26 +++---- proposals/http/wit/deps.toml | 2 +- proposals/http/wit/deps/cli/command.wit | 2 +- proposals/http/wit/deps/cli/imports.wit | 12 ++-- proposals/http/wit/deps/cli/stdio.wit | 6 +- .../http/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/http/wit/deps/clocks/timezone.wit | 2 +- proposals/http/wit/deps/clocks/wall-clock.wit | 2 +- proposals/http/wit/deps/clocks/world.wit | 2 +- .../http/wit/deps/filesystem/preopens.wit | 2 +- proposals/http/wit/deps/filesystem/types.wit | 10 ++- proposals/http/wit/deps/filesystem/world.wit | 2 +- proposals/http/wit/deps/io/error.wit | 2 +- proposals/http/wit/deps/io/poll.wit | 26 +++---- proposals/http/wit/deps/io/streams.wit | 2 +- proposals/http/wit/deps/io/world.wit | 2 +- .../http/wit/deps/random/insecure-seed.wit | 2 +- proposals/http/wit/deps/random/insecure.wit | 2 +- proposals/http/wit/deps/random/random.wit | 2 +- proposals/http/wit/deps/random/world.wit | 2 +- .../http/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/http/wit/deps/sockets/network.wit | 2 +- proposals/http/wit/deps/sockets/tcp.wit | 6 +- proposals/http/wit/deps/sockets/udp.wit | 2 +- proposals/http/wit/deps/sockets/world.wit | 2 +- proposals/http/wit/proxy.wit | 14 ++-- proposals/http/wit/types.wit | 8 +-- 54 files changed, 199 insertions(+), 157 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index cc7589725..b3374320c 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -4,21 +4,21 @@ It is intended to be included in other worlds.

                      -

                      Import interface wasi:io/poll@0.2.3

                      +

                      Import interface wasi:io/poll@0.2.4

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -71,7 +71,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.3

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.4

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -130,7 +130,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.3

                      +

                      Import interface wasi:clocks/wall-clock@0.2.4

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -171,7 +171,7 @@ also known as Unix Time.
                    116. datetime
                    117. -

                      Import interface wasi:random/random@0.2.3

                      +

                      Import interface wasi:random/random@0.2.4

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -204,7 +204,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:io/error@0.2.3

                      +

                      Import interface wasi:io/error@0.2.4


                      Types

                      resource error

                      @@ -237,7 +237,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/streams@0.2.3

                      +

                      Import interface wasi:io/streams@0.2.4

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -567,7 +567,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.3

                      +

                      Import interface wasi:cli/stdout@0.2.4


                      Types

                      type output-stream

                      @@ -580,7 +580,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.3

                      +

                      Import interface wasi:cli/stderr@0.2.4


                      Types

                      type output-stream

                      @@ -593,7 +593,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.3

                      +

                      Import interface wasi:cli/stdin@0.2.4


                      Types

                      type input-stream

                      @@ -606,7 +606,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:http/types@0.2.3

                      +

                      Import interface wasi:http/types@0.2.4

                      This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                      @@ -1260,6 +1260,25 @@ supported.

                      • result
                      +

                      [method]response-outparam.send-informational: func

                      +

                      Send an HTTP 1xx response.

                      +

                      Unlike response-outparam.set, this does not consume the +response-outparam, allowing the guest to send an arbitrary number of +informational responses before sending the final response using +response-outparam.set.

                      +

                      This will return an HTTP-protocol-error if status is not in the +range [100-199], or an internal-error if the implementation does not +support informational responses.

                      +
                      Params
                      + +
                      Return values
                      +

                      [static]response-outparam.set: func

                      Set the value of the response-outparam to either send a response, or indicate an error.

                      @@ -1507,7 +1526,7 @@ but those will be reported by the incoming-body
                    118. option<result<result<own<incoming-response>, error-code>>>
                    119. -

                      Import interface wasi:http/outgoing-handler@0.2.3

                      +

                      Import interface wasi:http/outgoing-handler@0.2.4

                      This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                      diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 27eabb194..07dcd3e0a 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -6,26 +6,26 @@ outgoing HTTP requests.

                      -

                      Import interface wasi:io/poll@0.2.3

                      +

                      Import interface wasi:io/poll@0.2.4

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -78,7 +78,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.3

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.4

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -137,7 +137,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.3

                      +

                      Import interface wasi:clocks/wall-clock@0.2.4

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -178,7 +178,7 @@ also known as Unix Time.
                    120. datetime
                    121. -

                      Import interface wasi:random/random@0.2.3

                      +

                      Import interface wasi:random/random@0.2.4

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -211,7 +211,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:io/error@0.2.3

                      +

                      Import interface wasi:io/error@0.2.4


                      Types

                      resource error

                      @@ -244,7 +244,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/streams@0.2.3

                      +

                      Import interface wasi:io/streams@0.2.4

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -574,7 +574,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.3

                      +

                      Import interface wasi:cli/stdout@0.2.4


                      Types

                      type output-stream

                      @@ -587,7 +587,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.3

                      +

                      Import interface wasi:cli/stderr@0.2.4


                      Types

                      type output-stream

                      @@ -600,7 +600,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.3

                      +

                      Import interface wasi:cli/stdin@0.2.4


                      Types

                      type input-stream

                      @@ -613,7 +613,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:http/types@0.2.3

                      +

                      Import interface wasi:http/types@0.2.4

                      This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                      @@ -1267,6 +1267,25 @@ supported.

                      • result
                      +

                      [method]response-outparam.send-informational: func

                      +

                      Send an HTTP 1xx response.

                      +

                      Unlike response-outparam.set, this does not consume the +response-outparam, allowing the guest to send an arbitrary number of +informational responses before sending the final response using +response-outparam.set.

                      +

                      This will return an HTTP-protocol-error if status is not in the +range [100-199], or an internal-error if the implementation does not +support informational responses.

                      +
                      Params
                      + +
                      Return values
                      +

                      [static]response-outparam.set: func

                      Set the value of the response-outparam to either send a response, or indicate an error.

                      @@ -1514,7 +1533,7 @@ but those will be reported by the incoming-body
                    122. option<result<result<own<incoming-response>, error-code>>>
                    123. -

                      Import interface wasi:http/outgoing-handler@0.2.3

                      +

                      Import interface wasi:http/outgoing-handler@0.2.4

                      This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                      @@ -1551,7 +1570,7 @@ through the future-incoming-response
                    124. result<own<future-incoming-response>, error-code>
                    125. -

                      Export interface wasi:http/incoming-handler@0.2.3

                      +

                      Export interface wasi:http/incoming-handler@0.2.4


                      Types

                      type incoming-request

                      diff --git a/proposals/http/wit-0.3.0-draft/deps.toml b/proposals/http/wit-0.3.0-draft/deps.toml index 772bb1be3..da0017d04 100644 --- a/proposals/http/wit-0.3.0-draft/deps.toml +++ b/proposals/http/wit-0.3.0-draft/deps.toml @@ -1,3 +1,3 @@ -cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.3.tar.gz" # TODO: update to v0.3.0-draft and remove custom clock and random imports +cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.4.tar.gz" # TODO: update to v0.3.0-draft and remove custom clock and random imports clocks-0-3-0 = { url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz", subdir = "wit-0.3.0-draft" } random-0-3-0 = { url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz", subdir = "wit-0.3.0-draft" } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit index 3a81766d6..88ab2a97e 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.3; +package wasi:cli@0.2.4; @since(version = 0.2.0) world command { diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit index 8b4e3975e..ad5c6bb23 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.3; +package wasi:cli@0.2.4; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.3; + include wasi:clocks/imports@0.2.4; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.3; + include wasi:filesystem/imports@0.2.4; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.3; + include wasi:sockets/imports@0.2.4; @since(version = 0.2.0) - include wasi:random/imports@0.2.3; + include wasi:random/imports@0.2.4; @since(version = 0.2.0) - include wasi:io/imports@0.2.3; + include wasi:io/imports@0.2.4; @since(version = 0.2.0) import environment; diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit index 1b54f5318..60727a930 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{input-stream}; + use wasi:io/streams@0.2.4.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{output-stream}; + use wasi:io/streams@0.2.4.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{output-stream}; + use wasi:io/streams@0.2.4.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index c676fb84d..175f8fe2d 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.3; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit index b43e93b23..658cb17e7 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit index e00ce0893..f826cd1e0 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit index 05f04f797..9e2087447 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit index cea97495b..6e6003954 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.3; +package wasi:filesystem@0.2.4; @since(version = 0.2.0) interface preopens { diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit index d229a21f4..194414edc 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.3; +package wasi:filesystem@0.2.4; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.3; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.4.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.3.{datetime}; + use wasi:clocks/wall-clock@0.2.4.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit index 29405bc2c..7742ed6bb 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.3; +package wasi:filesystem@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/deps/io/error.wit b/proposals/http/wit-0.3.0-draft/deps/io/error.wit index 97c606877..eb0600f9e 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/error.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; @since(version = 0.2.0) interface error { diff --git a/proposals/http/wit-0.3.0-draft/deps/io/poll.wit b/proposals/http/wit-0.3.0-draft/deps/io/poll.wit index 9bcbe8e03..98eda9326 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/poll.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/http/wit-0.3.0-draft/deps/io/streams.wit b/proposals/http/wit-0.3.0-draft/deps/io/streams.wit index 0de084629..bb9a31e81 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/streams.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/http/wit-0.3.0-draft/deps/io/world.wit b/proposals/http/wit-0.3.0-draft/deps/io/world.wit index f1d2102dc..8e0fa5c53 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit index 67d024d5b..45e8bafdb 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit index a07dfab32..5ab5030c5 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit-0.3.0-draft/deps/random/random.wit b/proposals/http/wit-0.3.0-draft/deps/random/random.wit index 91957e633..9e5220d82 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/random.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit-0.3.0-draft/deps/random/world.wit b/proposals/http/wit-0.3.0-draft/deps/random/world.wit index 0c1218f36..d89055819 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit index c1d8a47c1..48b41a5b1 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit index f3f60a370..aa4985e14 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.3.{error}; + use wasi:io/error@0.2.4.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit index b4cd87fce..b3311332f 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{input-stream, output-stream}; + use wasi:io/streams@0.2.4.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.3.{duration}; + use wasi:clocks/monotonic-clock@0.2.4.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit index 01901ca27..cfc07ba81 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit index 2f0ad0d7c..82acdb9f0 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.3; +package wasi:sockets@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit-0.3.0-draft/proxy.wit b/proposals/http/wit-0.3.0-draft/proxy.wit index 8e10fd789..e5f45a984 100644 --- a/proposals/http/wit-0.3.0-draft/proxy.wit +++ b/proposals/http/wit-0.3.0-draft/proxy.wit @@ -9,14 +9,14 @@ world imports { /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.2.3; - import wasi:cli/stderr@0.2.3; + import wasi:cli/stdout@0.2.4; + import wasi:cli/stderr@0.2.4; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. - import wasi:cli/stdin@0.2.3; + import wasi:cli/stdin@0.2.4; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 24a22f6d7..d1ea8ceb0 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,25 +1,25 @@ [cli] -url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.3.tar.gz" -sha256 = "4dadd13d55aaf626833d1f4b9c34a17b0f04e993babd09552b785cda3b95ea76" -sha512 = "898dcc4e8c15d18acc6b88dbe232336fa4d19019430a910dbc9e7aeaace3077a164af3be9f002de6e7e65ef693df340801ac0c7e421e9a746bf1b6d698a90835" +url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.4.tar.gz" +sha256 = "674ab0febcabe50a68122751160d243361f401d923e93e4f9c0e6f9d424d21e1" +sha512 = "70529da20c463b37aeff9fb40586e093ee3560bdacf573e8dc8ec2a380c598456294d1308aee9431745ad0fef6ac67aae53b5abb4578c7d682cd5b1485825191" deps = ["clocks", "filesystem", "io", "random", "sockets"] [clocks] -sha256 = "93a701968a7dd3c5d69031bc0601681c468972fdf7e28a93bb6150a67d6ebe8b" -sha512 = "98fca567c7a01887b0fb38981f1772169b6ea8de475b546508f8b86738d84e44ba95cae81def40ac34e8809f5f60e85224077ab8cb6d6d5d6296acc1df73c159" +sha256 = "fc36267c5098ad9ac6455396b27c8ef206ca23cae74f40bd44c57be68e7849b6" +sha512 = "0deed3d3a86f284adda7991cd24c0c4aab806ba2e0cb111da80d7f99c05f10793a602b28451407cad58ab762997f60c0f6d173e919e4a0988773b455d3a410d3" [filesystem] -sha256 = "69d42fb10a04a33545b17e055f13db9b1e10e82ba0ed5bdb52334e40dc07c679" -sha512 = "612effbac6f4804fe0c29dae20b78bbba59e52cb754c15402f5fe229c3153a221e0fbdff1d9d00ceaa3fe049c6a95523a5b99f772f1c16d972eade2c88326a30" +sha256 = "dd435f78b23714bd9d51ef3789c43b831549e71f54b57394a41bbf0c4da45f42" +sha512 = "d58bcf6eae908a6b2d883bcdfe456dc31aa99c848d0b3d21f710bde5bbb59ec105dbd5085004eadd0faa938530e4c29f88e589f525c080eb6d5971775a0b64ed" [io] -sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" -sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" +sha256 = "770a73d479cda8e4c4064dd4006d2654ebcc358952079d74e41af27cf26bddbf" +sha512 = "b790f9750ac6782d9aaaa379845600b66dbde14ecee42f159c29796447eb8e61ee61f3b306e92622993b5e25298834b6ff62d7d9a04f8f18c05f07eda8f47ae0" [random] -sha256 = "dd0c91e7125172eb8fd4568e15ad9fc7305643015e6ece4396c3cc5e8c2bf79a" -sha512 = "d1ca2e7b0616a94a3b39d1b9450bb3fb595b01fd94a8626ad75433038dde40988ecb41ab93a374d569ab72163af3b30038d7bfc3499b9c07193181f4f1d9292a" +sha256 = "876d81b0a777f1dc9db215fa36f45898a907188819185d6b189345f28c081a45" +sha512 = "fc6a0ed97e0525456222b28bcc49431bade826a97cb6eb52cde595908865d1ed7835c54a63b408ba82e3d49061aebb9a8725d1d2316d28c0ccb12af8ec968ab8" [sockets] -sha256 = "2bc0f65a8046207ee3330ad7d63f6fafeafd4cc0ea4084f081bd5e4f7b177e74" -sha512 = "3e5490e41547dffa78d52631825d93da8d60f4af0246cbaf97e1ecb879285953a86d5f1f390b10c32f91dd7eaec6f43e625a26b1c92c32a0c86fde428aedaaab" +sha256 = "e6872db116eb02f2043c4238999712de19bdb22e3c8da00af563f8b6c4dabb18" +sha512 = "28c05fe8acd691d808b6a90b950483bbf59983c02e91ed4a89b0e06c3e2a27e0f73be678979309553f0889fc3fea00c4740b007946d7285aa554dc65d56b1b7f" diff --git a/proposals/http/wit/deps.toml b/proposals/http/wit/deps.toml index fbadb972d..5a337428a 100644 --- a/proposals/http/wit/deps.toml +++ b/proposals/http/wit/deps.toml @@ -1 +1 @@ -cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.3.tar.gz" +cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.4.tar.gz" diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit index 3a81766d6..88ab2a97e 100644 --- a/proposals/http/wit/deps/cli/command.wit +++ b/proposals/http/wit/deps/cli/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.3; +package wasi:cli@0.2.4; @since(version = 0.2.0) world command { diff --git a/proposals/http/wit/deps/cli/imports.wit b/proposals/http/wit/deps/cli/imports.wit index 8b4e3975e..ad5c6bb23 100644 --- a/proposals/http/wit/deps/cli/imports.wit +++ b/proposals/http/wit/deps/cli/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.3; +package wasi:cli@0.2.4; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.3; + include wasi:clocks/imports@0.2.4; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.3; + include wasi:filesystem/imports@0.2.4; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.3; + include wasi:sockets/imports@0.2.4; @since(version = 0.2.0) - include wasi:random/imports@0.2.3; + include wasi:random/imports@0.2.4; @since(version = 0.2.0) - include wasi:io/imports@0.2.3; + include wasi:io/imports@0.2.4; @since(version = 0.2.0) import environment; diff --git a/proposals/http/wit/deps/cli/stdio.wit b/proposals/http/wit/deps/cli/stdio.wit index 1b54f5318..60727a930 100644 --- a/proposals/http/wit/deps/cli/stdio.wit +++ b/proposals/http/wit/deps/cli/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{input-stream}; + use wasi:io/streams@0.2.4.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{output-stream}; + use wasi:io/streams@0.2.4.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{output-stream}; + use wasi:io/streams@0.2.4.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index c676fb84d..175f8fe2d 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.3; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/http/wit/deps/clocks/timezone.wit b/proposals/http/wit/deps/clocks/timezone.wit index b43e93b23..658cb17e7 100644 --- a/proposals/http/wit/deps/clocks/timezone.wit +++ b/proposals/http/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/http/wit/deps/clocks/wall-clock.wit b/proposals/http/wit/deps/clocks/wall-clock.wit index e00ce0893..f826cd1e0 100644 --- a/proposals/http/wit/deps/clocks/wall-clock.wit +++ b/proposals/http/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/http/wit/deps/clocks/world.wit b/proposals/http/wit/deps/clocks/world.wit index 05f04f797..9e2087447 100644 --- a/proposals/http/wit/deps/clocks/world.wit +++ b/proposals/http/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.3; +package wasi:clocks@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/filesystem/preopens.wit b/proposals/http/wit/deps/filesystem/preopens.wit index cea97495b..6e6003954 100644 --- a/proposals/http/wit/deps/filesystem/preopens.wit +++ b/proposals/http/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.3; +package wasi:filesystem@0.2.4; @since(version = 0.2.0) interface preopens { diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index d229a21f4..962cadfef 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.3; +package wasi:filesystem@0.2.4; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.3; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.4.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.3.{datetime}; + use wasi:clocks/wall-clock@0.2.4.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) @@ -508,6 +508,10 @@ interface types { /// Create a hard link. /// + /// Fails with `error-code::no-entry` if the old path does not exist, + /// with `error-code::exist` if the new path already exists, and + /// `error-code::not-permitted` if the old path is not a file. + /// /// Note: This is similar to `linkat` in POSIX. @since(version = 0.2.0) link-at: func( diff --git a/proposals/http/wit/deps/filesystem/world.wit b/proposals/http/wit/deps/filesystem/world.wit index 29405bc2c..7742ed6bb 100644 --- a/proposals/http/wit/deps/filesystem/world.wit +++ b/proposals/http/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.3; +package wasi:filesystem@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/io/error.wit b/proposals/http/wit/deps/io/error.wit index 97c606877..eb0600f9e 100644 --- a/proposals/http/wit/deps/io/error.wit +++ b/proposals/http/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; @since(version = 0.2.0) interface error { diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/io/poll.wit index 9bcbe8e03..170deff70 100644 --- a/proposals/http/wit/deps/io/poll.wit +++ b/proposals/http/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. @@ -8,19 +8,19 @@ interface poll { @since(version = 0.2.0) resource pollable { - /// Return the readiness of a pollable. This function never blocks. - /// - /// Returns `true` when the pollable is ready, and `false` otherwise. - @since(version = 0.2.0) - ready: func() -> bool; + /// Return the readiness of a pollable. This function never blocks. + /// + /// Returns `true` when the pollable is ready, and `false` otherwise. + @since(version = 0.2.0) + ready: func() -> bool; - /// `block` returns immediately if the pollable is ready, and otherwise - /// blocks until ready. - /// - /// This function is equivalent to calling `poll.poll` on a list - /// containing only this pollable. - @since(version = 0.2.0) - block: func(); + /// `block` returns immediately if the pollable is ready, and otherwise + /// blocks until ready. + /// + /// This function is equivalent to calling `poll.poll` on a list + /// containing only this pollable. + @since(version = 0.2.0) + block: func(); } /// Poll for completion on a set of pollables. diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index 0de084629..bb9a31e81 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit index f1d2102dc..8e0fa5c53 100644 --- a/proposals/http/wit/deps/io/world.wit +++ b/proposals/http/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.3; +package wasi:io@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/random/insecure-seed.wit b/proposals/http/wit/deps/random/insecure-seed.wit index 67d024d5b..45e8bafdb 100644 --- a/proposals/http/wit/deps/random/insecure-seed.wit +++ b/proposals/http/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/insecure.wit b/proposals/http/wit/deps/random/insecure.wit index a07dfab32..5ab5030c5 100644 --- a/proposals/http/wit/deps/random/insecure.wit +++ b/proposals/http/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index 91957e633..9e5220d82 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit index 0c1218f36..d89055819 100644 --- a/proposals/http/wit/deps/random/world.wit +++ b/proposals/http/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.3; +package wasi:random@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/sockets/ip-name-lookup.wit b/proposals/http/wit/deps/sockets/ip-name-lookup.wit index c1d8a47c1..48b41a5b1 100644 --- a/proposals/http/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/http/wit/deps/sockets/network.wit b/proposals/http/wit/deps/sockets/network.wit index f3f60a370..aa4985e14 100644 --- a/proposals/http/wit/deps/sockets/network.wit +++ b/proposals/http/wit/deps/sockets/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.3.{error}; + use wasi:io/error@0.2.4.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index b4cd87fce..b3311332f 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{input-stream, output-stream}; + use wasi:io/streams@0.2.4.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.3.{duration}; + use wasi:clocks/monotonic-clock@0.2.4.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index 01901ca27..cfc07ba81 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit index 2f0ad0d7c..82acdb9f0 100644 --- a/proposals/http/wit/deps/sockets/world.wit +++ b/proposals/http/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.3; +package wasi:sockets@0.2.4; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index de3bbe8ae..cd3af25c6 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,4 +1,4 @@ -package wasi:http@0.2.3; +package wasi:http@0.2.4; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. /// It is intended to be `include`d in other worlds. @@ -6,25 +6,25 @@ package wasi:http@0.2.3; world imports { /// HTTP proxies have access to time and randomness. @since(version = 0.2.0) - import wasi:clocks/monotonic-clock@0.2.3; + import wasi:clocks/monotonic-clock@0.2.4; @since(version = 0.2.0) - import wasi:clocks/wall-clock@0.2.3; + import wasi:clocks/wall-clock@0.2.4; @since(version = 0.2.0) - import wasi:random/random@0.2.3; + import wasi:random/random@0.2.4; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. @since(version = 0.2.0) - import wasi:cli/stdout@0.2.3; + import wasi:cli/stdout@0.2.4; @since(version = 0.2.0) - import wasi:cli/stderr@0.2.3; + import wasi:cli/stderr@0.2.4; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. @since(version = 0.2.0) - import wasi:cli/stdin@0.2.3; + import wasi:cli/stdin@0.2.4; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 9c0ce8b32..254a1bbed 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -4,13 +4,13 @@ @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.3.{duration}; + use wasi:clocks/monotonic-clock@0.2.4.{duration}; @since(version = 0.2.0) - use wasi:io/streams@0.2.3.{input-stream, output-stream}; + use wasi:io/streams@0.2.4.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/error@0.2.3.{error as io-error}; + use wasi:io/error@0.2.4.{error as io-error}; @since(version = 0.2.0) - use wasi:io/poll@0.2.3.{pollable}; + use wasi:io/poll@0.2.4.{pollable}; /// This type corresponds to HTTP standard Methods. @since(version = 0.2.0) From 8dd0f57f806493c47c9773336c536a21bf4bf07a Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Thu, 6 Feb 2025 18:23:22 +0100 Subject: [PATCH 1632/1772] feat: add `wit-0.3.0-draft` (#52) * ci: update `wit-deps` to 0.5.0 Signed-off-by: Roman Volosatovs * feat: add `wit-0.3.0-draft` Signed-off-by: Roman Volosatovs --------- Signed-off-by: Roman Volosatovs --- proposals/cli/.github/workflows/main.yml | 4 +- proposals/cli/wit-0.3.0-draft/command.wit | 10 + proposals/cli/wit-0.3.0-draft/deps.lock | 23 + proposals/cli/wit-0.3.0-draft/deps.toml | 3 + .../deps/clocks/monotonic-clock.wit | 45 ++ .../wit-0.3.0-draft/deps/clocks/timezone.wit | 55 ++ .../deps/clocks/wall-clock.wit | 46 ++ .../cli/wit-0.3.0-draft/deps/clocks/world.wit | 11 + .../deps/filesystem/preopens.wit | 11 + .../wit-0.3.0-draft/deps/filesystem/types.wit | 629 +++++++++++++++ .../wit-0.3.0-draft/deps/filesystem/world.wit | 9 + .../deps/random/insecure-seed.wit | 27 + .../wit-0.3.0-draft/deps/random/insecure.wit | 25 + .../wit-0.3.0-draft/deps/random/random.wit | 29 + .../cli/wit-0.3.0-draft/deps/random/world.wit | 13 + .../deps/sockets/ip-name-lookup.wit | 62 ++ .../wit-0.3.0-draft/deps/sockets/types.wit | 726 ++++++++++++++++++ .../wit-0.3.0-draft/deps/sockets/world.wit | 9 + proposals/cli/wit-0.3.0-draft/environment.wit | 22 + proposals/cli/wit-0.3.0-draft/exit.wit | 17 + proposals/cli/wit-0.3.0-draft/imports.wit | 34 + proposals/cli/wit-0.3.0-draft/run.wit | 6 + proposals/cli/wit-0.3.0-draft/stdio.wit | 17 + proposals/cli/wit-0.3.0-draft/terminal.wit | 62 ++ 24 files changed, 1894 insertions(+), 1 deletion(-) create mode 100644 proposals/cli/wit-0.3.0-draft/command.wit create mode 100644 proposals/cli/wit-0.3.0-draft/deps.lock create mode 100644 proposals/cli/wit-0.3.0-draft/deps.toml create mode 100644 proposals/cli/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit create mode 100644 proposals/cli/wit-0.3.0-draft/deps/clocks/timezone.wit create mode 100644 proposals/cli/wit-0.3.0-draft/deps/clocks/wall-clock.wit create mode 100644 proposals/cli/wit-0.3.0-draft/deps/clocks/world.wit create mode 100644 proposals/cli/wit-0.3.0-draft/deps/filesystem/preopens.wit create mode 100644 proposals/cli/wit-0.3.0-draft/deps/filesystem/types.wit create mode 100644 proposals/cli/wit-0.3.0-draft/deps/filesystem/world.wit create mode 100644 proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit create mode 100644 proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit create mode 100644 proposals/cli/wit-0.3.0-draft/deps/random/random.wit create mode 100644 proposals/cli/wit-0.3.0-draft/deps/random/world.wit create mode 100644 proposals/cli/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit create mode 100644 proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit create mode 100644 proposals/cli/wit-0.3.0-draft/deps/sockets/world.wit create mode 100644 proposals/cli/wit-0.3.0-draft/environment.wit create mode 100644 proposals/cli/wit-0.3.0-draft/exit.wit create mode 100644 proposals/cli/wit-0.3.0-draft/imports.wit create mode 100644 proposals/cli/wit-0.3.0-draft/run.wit create mode 100644 proposals/cli/wit-0.3.0-draft/stdio.wit create mode 100644 proposals/cli/wit-0.3.0-draft/terminal.wit diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml index 88e43c754..ef428071e 100644 --- a/proposals/cli/.github/workflows/main.yml +++ b/proposals/cli/.github/workflows/main.yml @@ -13,10 +13,12 @@ jobs: - uses: actions/checkout@v4 - name: ensure `./wit/deps` are in sync run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.5/wit-deps-x86_64-unknown-linux-musl + curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.5.0/wit-deps-x86_64-unknown-linux-musl chmod +x wit-deps ./wit-deps lock + ./wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps lock git add -N wit/deps + git add -N wit-0.3.0-draft/deps git diff --exit-code - uses: WebAssembly/wit-abi-up-to-date@v22 with: diff --git a/proposals/cli/wit-0.3.0-draft/command.wit b/proposals/cli/wit-0.3.0-draft/command.wit new file mode 100644 index 000000000..0310e5151 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/command.wit @@ -0,0 +1,10 @@ +package wasi:cli@0.3.0; + +@since(version = 0.3.0) +world command { + @since(version = 0.3.0) + include imports; + + @since(version = 0.3.0) + export run; +} diff --git a/proposals/cli/wit-0.3.0-draft/deps.lock b/proposals/cli/wit-0.3.0-draft/deps.lock new file mode 100644 index 000000000..7cb659e99 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps.lock @@ -0,0 +1,23 @@ +[clocks] +sha256 = "26e315db0d371495f8834edfc0e479042f94152ce677d96d54d3623d0e4ffb1e" +sha512 = "e1c76f499435841316f9287b88d8173558e64f277c321ff390556de8707a0b18dd6c1749bbb17bbbba8d523da246ef6eb05c990ceddb762e03efb2ae30cacc76" + +[filesystem] +url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" +subdir = "wit-0.3.0-draft" +sha256 = "f8a82b21e18cad3498b53475666a3f00c4c1b5f030b7ed47c79262e3dbe97461" +sha512 = "0e62fe9ff3ba0572d890a2edd969e88a5c2327279cec681d3f2688ed8442820333f6041b0f0956b44941f971a6afb785bd2f5248ca0c99b51f13521496cadbcc" +deps = ["clocks"] + +[random] +url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" +subdir = "wit-0.3.0-draft" +sha256 = "7a483077cc23fc9dc7a3f067d62795663cceee7dbbd23f205934282b1164a83e" +sha512 = "b99280fd60699f781f20209659e94c0058ce6b9e973ddbd0b8865d752f88c74633485d486d5a86b709385b6e60357470d1c6fbcb3a2769af210c0b1f52417506" + +[sockets] +url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" +subdir = "wit-0.3.0-draft" +sha256 = "48fa617cdf64b66adc7136e4f0c14886061e6d5134072bf8e1698b84e2579669" +sha512 = "786b8a03c14d3f529500275762a37c497ea1e6479e71028e8173aa07594beb77226904d77970a7c356ff3f59aa4a5c10f2e68537cc96b9916ff03a317b05a229" +deps = ["clocks"] diff --git a/proposals/cli/wit-0.3.0-draft/deps.toml b/proposals/cli/wit-0.3.0-draft/deps.toml new file mode 100644 index 000000000..39bc16e55 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps.toml @@ -0,0 +1,3 @@ +filesystem = { url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz", subdir = "wit-0.3.0-draft" } +random = { url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz", subdir = "wit-0.3.0-draft" } +sockets = { url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz", subdir = "wit-0.3.0-draft" } diff --git a/proposals/cli/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/cli/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit new file mode 100644 index 000000000..87ebdaac5 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -0,0 +1,45 @@ +package wasi:clocks@0.3.0; +/// WASI Monotonic Clock is a clock API intended to let users measure elapsed +/// time. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A monotonic clock is a clock which has an unspecified initial value, and +/// successive reads of the clock will produce non-decreasing values. +@since(version = 0.3.0) +interface monotonic-clock { + /// An instant in time, in nanoseconds. An instant is relative to an + /// unspecified initial value, and can only be compared to instances from + /// the same monotonic-clock. + @since(version = 0.3.0) + type instant = u64; + + /// A duration of time, in nanoseconds. + @since(version = 0.3.0) + type duration = u64; + + /// Read the current value of the clock. + /// + /// The clock is monotonic, therefore calling this function repeatedly will + /// produce a sequence of non-decreasing values. + @since(version = 0.3.0) + now: func() -> instant; + + /// Query the resolution of the clock. Returns the duration of time + /// corresponding to a clock tick. + @since(version = 0.3.0) + resolution: func() -> duration; + + /// Wait until the specified instant has occurred. + @since(version = 0.3.0) + wait-until: func( + when: instant, + ); + + /// Wait for the specified duration has elapsed. + @since(version = 0.3.0) + wait-for: func( + how-long: duration, + ); +} diff --git a/proposals/cli/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/cli/wit-0.3.0-draft/deps/clocks/timezone.wit new file mode 100644 index 000000000..ac9146834 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -0,0 +1,55 @@ +package wasi:clocks@0.3.0; + +@unstable(feature = clocks-timezone) +interface timezone { + @unstable(feature = clocks-timezone) + use wall-clock.{datetime}; + + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + @unstable(feature = clocks-timezone) + display: func(when: datetime) -> timezone-display; + + /// The same as `display`, but only return the UTC offset. + @unstable(feature = clocks-timezone) + utc-offset: func(when: datetime) -> s32; + + /// Information useful for displaying the timezone of a specific `datetime`. + /// + /// This information may vary within a single `timezone` to reflect daylight + /// saving time adjustments. + @unstable(feature = clocks-timezone) + record timezone-display { + /// The number of seconds difference between UTC time and the local + /// time of the timezone. + /// + /// The returned value will always be less than 86400 which is the + /// number of seconds in a day (24*60*60). + /// + /// In implementations that do not expose an actual time zone, this + /// should return 0. + utc-offset: s32, + + /// The abbreviated name of the timezone to display to a user. The name + /// `UTC` indicates Coordinated Universal Time. Otherwise, this should + /// reference local standards for the name of the time zone. + /// + /// In implementations that do not expose an actual time zone, this + /// should be the string `UTC`. + /// + /// In time zones that do not have an applicable name, a formatted + /// representation of the UTC offset may be returned, such as `-04:00`. + name: string, + + /// Whether daylight saving time is active. + /// + /// In implementations that do not expose an actual time zone, this + /// should return false. + in-daylight-saving-time: bool, + } +} diff --git a/proposals/cli/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/cli/wit-0.3.0-draft/deps/clocks/wall-clock.wit new file mode 100644 index 000000000..b7a85ab35 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -0,0 +1,46 @@ +package wasi:clocks@0.3.0; +/// WASI Wall Clock is a clock API intended to let users query the current +/// time. The name "wall" makes an analogy to a "clock on the wall", which +/// is not necessarily monotonic as it may be reset. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +/// +/// A wall clock is a clock which measures the date and time according to +/// some external reference. +/// +/// External references may be reset, so this clock is not necessarily +/// monotonic, making it unsuitable for measuring elapsed time. +/// +/// It is intended for reporting the current date and time for humans. +@since(version = 0.3.0) +interface wall-clock { + /// A time and date in seconds plus nanoseconds. + @since(version = 0.3.0) + record datetime { + seconds: u64, + nanoseconds: u32, + } + + /// Read the current value of the clock. + /// + /// This clock is not monotonic, therefore calling this function repeatedly + /// will not necessarily produce a sequence of non-decreasing values. + /// + /// The returned timestamps represent the number of seconds since + /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], + /// also known as [Unix Time]. + /// + /// The nanoseconds field of the output is always less than 1000000000. + /// + /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time + @since(version = 0.3.0) + now: func() -> datetime; + + /// Query the resolution of the clock. + /// + /// The nanoseconds field of the output is always less than 1000000000. + @since(version = 0.3.0) + resolution: func() -> datetime; +} diff --git a/proposals/cli/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/cli/wit-0.3.0-draft/deps/clocks/world.wit new file mode 100644 index 000000000..f97bcfef1 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/clocks/world.wit @@ -0,0 +1,11 @@ +package wasi:clocks@0.3.0; + +@since(version = 0.3.0) +world imports { + @since(version = 0.3.0) + import monotonic-clock; + @since(version = 0.3.0) + import wall-clock; + @unstable(feature = clocks-timezone) + import timezone; +} diff --git a/proposals/cli/wit-0.3.0-draft/deps/filesystem/preopens.wit b/proposals/cli/wit-0.3.0-draft/deps/filesystem/preopens.wit new file mode 100644 index 000000000..0b29aae33 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/filesystem/preopens.wit @@ -0,0 +1,11 @@ +package wasi:filesystem@0.3.0; + +@since(version = 0.3.0) +interface preopens { + @since(version = 0.3.0) + use types.{descriptor}; + + /// Return the set of preopened directories, and their paths. + @since(version = 0.3.0) + get-directories: func() -> list>; +} diff --git a/proposals/cli/wit-0.3.0-draft/deps/filesystem/types.wit b/proposals/cli/wit-0.3.0-draft/deps/filesystem/types.wit new file mode 100644 index 000000000..af3cb254c --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/filesystem/types.wit @@ -0,0 +1,629 @@ +package wasi:filesystem@0.3.0; +/// WASI filesystem is a filesystem API primarily intended to let users run WASI +/// programs that access their files on their existing filesystems, without +/// significant overhead. +/// +/// It is intended to be roughly portable between Unix-family platforms and +/// Windows, though it does not hide many of the major differences. +/// +/// Paths are passed as interface-type `string`s, meaning they must consist of +/// a sequence of Unicode Scalar Values (USVs). Some filesystems may contain +/// paths which are not accessible by this API. +/// +/// The directory separator in WASI is always the forward-slash (`/`). +/// +/// All paths in WASI are relative paths, and are interpreted relative to a +/// `descriptor` referring to a base directory. If a `path` argument to any WASI +/// function starts with `/`, or if any step of resolving a `path`, including +/// `..` and symbolic link steps, reaches a directory outside of the base +/// directory, or reaches a symlink to an absolute or rooted path in the +/// underlying filesystem, the function fails with `error-code::not-permitted`. +/// +/// For more information about WASI path resolution and sandboxing, see +/// [WASI filesystem path resolution]. +/// +/// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md +@since(version = 0.3.0) +interface types { + @since(version = 0.3.0) + use wasi:clocks/wall-clock@0.3.0.{datetime}; + + /// File size or length of a region within a file. + @since(version = 0.3.0) + type filesize = u64; + + /// The type of a filesystem object referenced by a descriptor. + /// + /// Note: This was called `filetype` in earlier versions of WASI. + @since(version = 0.3.0) + enum descriptor-type { + /// The type of the descriptor or file is unknown or is different from + /// any of the other types specified. + unknown, + /// The descriptor refers to a block device inode. + block-device, + /// The descriptor refers to a character device inode. + character-device, + /// The descriptor refers to a directory inode. + directory, + /// The descriptor refers to a named pipe. + fifo, + /// The file refers to a symbolic link inode. + symbolic-link, + /// The descriptor refers to a regular file inode. + regular-file, + /// The descriptor refers to a socket. + socket, + } + + /// Descriptor flags. + /// + /// Note: This was called `fdflags` in earlier versions of WASI. + @since(version = 0.3.0) + flags descriptor-flags { + /// Read mode: Data can be read. + read, + /// Write mode: Data can be written to. + write, + /// Request that writes be performed according to synchronized I/O file + /// integrity completion. The data stored in the file and the file's + /// metadata are synchronized. This is similar to `O_SYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + file-integrity-sync, + /// Request that writes be performed according to synchronized I/O data + /// integrity completion. Only the data stored in the file is + /// synchronized. This is similar to `O_DSYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + data-integrity-sync, + /// Requests that reads be performed at the same level of integrity + /// requested for writes. This is similar to `O_RSYNC` in POSIX. + /// + /// The precise semantics of this operation have not yet been defined for + /// WASI. At this time, it should be interpreted as a request, and not a + /// requirement. + requested-write-sync, + /// Mutating directories mode: Directory contents may be mutated. + /// + /// When this flag is unset on a descriptor, operations using the + /// descriptor which would create, rename, delete, modify the data or + /// metadata of filesystem objects, or obtain another handle which + /// would permit any of those, shall fail with `error-code::read-only` if + /// they would otherwise succeed. + /// + /// This may only be set on directories. + mutate-directory, + } + + /// File attributes. + /// + /// Note: This was called `filestat` in earlier versions of WASI. + @since(version = 0.3.0) + record descriptor-stat { + /// File type. + %type: descriptor-type, + /// Number of hard links to the file. + link-count: link-count, + /// For regular files, the file size in bytes. For symbolic links, the + /// length in bytes of the pathname contained in the symbolic link. + size: filesize, + /// Last data access timestamp. + /// + /// If the `option` is none, the platform doesn't maintain an access + /// timestamp for this file. + data-access-timestamp: option, + /// Last data modification timestamp. + /// + /// If the `option` is none, the platform doesn't maintain a + /// modification timestamp for this file. + data-modification-timestamp: option, + /// Last file status-change timestamp. + /// + /// If the `option` is none, the platform doesn't maintain a + /// status-change timestamp for this file. + status-change-timestamp: option, + } + + /// Flags determining the method of how paths are resolved. + @since(version = 0.3.0) + flags path-flags { + /// As long as the resolved path corresponds to a symbolic link, it is + /// expanded. + symlink-follow, + } + + /// Open flags used by `open-at`. + @since(version = 0.3.0) + flags open-flags { + /// Create file if it does not exist, similar to `O_CREAT` in POSIX. + create, + /// Fail if not a directory, similar to `O_DIRECTORY` in POSIX. + directory, + /// Fail if file already exists, similar to `O_EXCL` in POSIX. + exclusive, + /// Truncate file to size 0, similar to `O_TRUNC` in POSIX. + truncate, + } + + /// Number of hard links to an inode. + @since(version = 0.3.0) + type link-count = u64; + + /// When setting a timestamp, this gives the value to set it to. + @since(version = 0.3.0) + variant new-timestamp { + /// Leave the timestamp set to its previous value. + no-change, + /// Set the timestamp to the current time of the system clock associated + /// with the filesystem. + now, + /// Set the timestamp to the given value. + timestamp(datetime), + } + + /// A directory entry. + record directory-entry { + /// The type of the file referred to by this directory entry. + %type: descriptor-type, + + /// The name of the object. + name: string, + } + + /// Error codes returned by functions, similar to `errno` in POSIX. + /// Not all of these error codes are returned by the functions provided by this + /// API; some are used in higher-level library layers, and others are provided + /// merely for alignment with POSIX. + enum error-code { + /// Permission denied, similar to `EACCES` in POSIX. + access, + /// Connection already in progress, similar to `EALREADY` in POSIX. + already, + /// Bad descriptor, similar to `EBADF` in POSIX. + bad-descriptor, + /// Device or resource busy, similar to `EBUSY` in POSIX. + busy, + /// Resource deadlock would occur, similar to `EDEADLK` in POSIX. + deadlock, + /// Storage quota exceeded, similar to `EDQUOT` in POSIX. + quota, + /// File exists, similar to `EEXIST` in POSIX. + exist, + /// File too large, similar to `EFBIG` in POSIX. + file-too-large, + /// Illegal byte sequence, similar to `EILSEQ` in POSIX. + illegal-byte-sequence, + /// Operation in progress, similar to `EINPROGRESS` in POSIX. + in-progress, + /// Interrupted function, similar to `EINTR` in POSIX. + interrupted, + /// Invalid argument, similar to `EINVAL` in POSIX. + invalid, + /// I/O error, similar to `EIO` in POSIX. + io, + /// Is a directory, similar to `EISDIR` in POSIX. + is-directory, + /// Too many levels of symbolic links, similar to `ELOOP` in POSIX. + loop, + /// Too many links, similar to `EMLINK` in POSIX. + too-many-links, + /// Message too large, similar to `EMSGSIZE` in POSIX. + message-size, + /// Filename too long, similar to `ENAMETOOLONG` in POSIX. + name-too-long, + /// No such device, similar to `ENODEV` in POSIX. + no-device, + /// No such file or directory, similar to `ENOENT` in POSIX. + no-entry, + /// No locks available, similar to `ENOLCK` in POSIX. + no-lock, + /// Not enough space, similar to `ENOMEM` in POSIX. + insufficient-memory, + /// No space left on device, similar to `ENOSPC` in POSIX. + insufficient-space, + /// Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. + not-directory, + /// Directory not empty, similar to `ENOTEMPTY` in POSIX. + not-empty, + /// State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. + not-recoverable, + /// Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. + unsupported, + /// Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. + no-tty, + /// No such device or address, similar to `ENXIO` in POSIX. + no-such-device, + /// Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. + overflow, + /// Operation not permitted, similar to `EPERM` in POSIX. + not-permitted, + /// Broken pipe, similar to `EPIPE` in POSIX. + pipe, + /// Read-only file system, similar to `EROFS` in POSIX. + read-only, + /// Invalid seek, similar to `ESPIPE` in POSIX. + invalid-seek, + /// Text file busy, similar to `ETXTBSY` in POSIX. + text-file-busy, + /// Cross-device link, similar to `EXDEV` in POSIX. + cross-device, + } + + /// File or memory access pattern advisory information. + @since(version = 0.3.0) + enum advice { + /// The application has no advice to give on its behavior with respect + /// to the specified data. + normal, + /// The application expects to access the specified data sequentially + /// from lower offsets to higher offsets. + sequential, + /// The application expects to access the specified data in a random + /// order. + random, + /// The application expects to access the specified data in the near + /// future. + will-need, + /// The application expects that it will not access the specified data + /// in the near future. + dont-need, + /// The application expects to access the specified data once and then + /// not reuse it thereafter. + no-reuse, + } + + /// A 128-bit hash value, split into parts because wasm doesn't have a + /// 128-bit integer type. + @since(version = 0.3.0) + record metadata-hash-value { + /// 64 bits of a 128-bit hash value. + lower: u64, + /// Another 64 bits of a 128-bit hash value. + upper: u64, + } + + /// A descriptor is a reference to a filesystem object, which may be a file, + /// directory, named pipe, special file, or other object on which filesystem + /// calls may be made. + @since(version = 0.3.0) + resource descriptor { + /// Return a stream for reading from a file. + /// + /// Multiple read, write, and append streams may be active on the same open + /// file and they do not interfere with each other. + /// + /// This function returns a future, which will resolve to an error code if + /// reading full contents of the file fails. + /// + /// Note: This is similar to `pread` in POSIX. + @since(version = 0.3.0) + read-via-stream: func( + /// The offset within the file at which to start reading. + offset: filesize, + ) -> tuple, future>>; + + /// Return a stream for writing to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be written. + /// + /// It is valid to write past the end of a file; the file is extended to the + /// extent of the write, with bytes between the previous end and the start of + /// the write set to zero. + /// + /// This function returns once either full contents of the stream are + /// written or an error is encountered. + /// + /// Note: This is similar to `pwrite` in POSIX. + @since(version = 0.3.0) + write-via-stream: func( + /// Data to write + data: stream, + /// The offset within the file at which to start writing. + offset: filesize, + ) -> result<_, error-code>; + + /// Return a stream for appending to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be appended. + /// + /// This function returns once either full contents of the stream are + /// written or an error is encountered. + /// + /// Note: This is similar to `write` with `O_APPEND` in POSIX. + @since(version = 0.3.0) + append-via-stream: func(data: stream) -> result<_, error-code>; + + /// Provide file advisory information on a descriptor. + /// + /// This is similar to `posix_fadvise` in POSIX. + @since(version = 0.3.0) + advise: func( + /// The offset within the file to which the advisory applies. + offset: filesize, + /// The length of the region to which the advisory applies. + length: filesize, + /// The advice. + advice: advice + ) -> result<_, error-code>; + + /// Synchronize the data of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fdatasync` in POSIX. + @since(version = 0.3.0) + sync-data: func() -> result<_, error-code>; + + /// Get flags associated with a descriptor. + /// + /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. + /// + /// Note: This returns the value that was the `fs_flags` value returned + /// from `fdstat_get` in earlier versions of WASI. + @since(version = 0.3.0) + get-flags: func() -> result; + + /// Get the dynamic type of a descriptor. + /// + /// Note: This returns the same value as the `type` field of the `fd-stat` + /// returned by `stat`, `stat-at` and similar. + /// + /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided + /// by `fstat` in POSIX. + /// + /// Note: This returns the value that was the `fs_filetype` value returned + /// from `fdstat_get` in earlier versions of WASI. + @since(version = 0.3.0) + get-type: func() -> result; + + /// Adjust the size of an open file. If this increases the file's size, the + /// extra bytes are filled with zeros. + /// + /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. + @since(version = 0.3.0) + set-size: func(size: filesize) -> result<_, error-code>; + + /// Adjust the timestamps of an open file or directory. + /// + /// Note: This is similar to `futimens` in POSIX. + /// + /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. + @since(version = 0.3.0) + set-times: func( + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code>; + + /// Read directory entries from a directory. + /// + /// On filesystems where directories contain entries referring to themselves + /// and their parents, often named `.` and `..` respectively, these entries + /// are omitted. + /// + /// This always returns a new stream which starts at the beginning of the + /// directory. Multiple streams may be active on the same directory, and they + /// do not interfere with each other. + /// + /// This function returns a future, which will resolve to an error code if + /// reading full contents of the directory fails. + @since(version = 0.3.0) + read-directory: func() -> tuple, future>>; + + /// Synchronize the data and metadata of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fsync` in POSIX. + @since(version = 0.3.0) + sync: func() -> result<_, error-code>; + + /// Create a directory. + /// + /// Note: This is similar to `mkdirat` in POSIX. + @since(version = 0.3.0) + create-directory-at: func( + /// The relative path at which to create the directory. + path: string, + ) -> result<_, error-code>; + + /// Return the attributes of an open file or directory. + /// + /// Note: This is similar to `fstat` in POSIX, except that it does not return + /// device and inode information. For testing whether two descriptors refer to + /// the same underlying filesystem object, use `is-same-object`. To obtain + /// additional data that can be used do determine whether a file has been + /// modified, use `metadata-hash`. + /// + /// Note: This was called `fd_filestat_get` in earlier versions of WASI. + @since(version = 0.3.0) + stat: func() -> result; + + /// Return the attributes of a file or directory. + /// + /// Note: This is similar to `fstatat` in POSIX, except that it does not + /// return device and inode information. See the `stat` description for a + /// discussion of alternatives. + /// + /// Note: This was called `path_filestat_get` in earlier versions of WASI. + @since(version = 0.3.0) + stat-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result; + + /// Adjust the timestamps of a file or directory. + /// + /// Note: This is similar to `utimensat` in POSIX. + /// + /// Note: This was called `path_filestat_set_times` in earlier versions of + /// WASI. + @since(version = 0.3.0) + set-times-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to operate on. + path: string, + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code>; + + /// Create a hard link. + /// + /// Fails with `error-code::no-entry` if the old path does not exist, + /// with `error-code::exist` if the new path already exists, and + /// `error-code::not-permitted` if the old path is not a file. + /// + /// Note: This is similar to `linkat` in POSIX. + @since(version = 0.3.0) + link-at: func( + /// Flags determining the method of how the path is resolved. + old-path-flags: path-flags, + /// The relative source path from which to link. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: borrow, + /// The relative destination path at which to create the hard link. + new-path: string, + ) -> result<_, error-code>; + + /// Open a file or directory. + /// + /// If `flags` contains `descriptor-flags::mutate-directory`, and the base + /// descriptor doesn't have `descriptor-flags::mutate-directory` set, + /// `open-at` fails with `error-code::read-only`. + /// + /// If `flags` contains `write` or `mutate-directory`, or `open-flags` + /// contains `truncate` or `create`, and the base descriptor doesn't have + /// `descriptor-flags::mutate-directory` set, `open-at` fails with + /// `error-code::read-only`. + /// + /// Note: This is similar to `openat` in POSIX. + @since(version = 0.3.0) + open-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the object to open. + path: string, + /// The method by which to open the file. + open-flags: open-flags, + /// Flags to use for the resulting descriptor. + %flags: descriptor-flags, + ) -> result; + + /// Read the contents of a symbolic link. + /// + /// If the contents contain an absolute or rooted path in the underlying + /// filesystem, this function fails with `error-code::not-permitted`. + /// + /// Note: This is similar to `readlinkat` in POSIX. + @since(version = 0.3.0) + readlink-at: func( + /// The relative path of the symbolic link from which to read. + path: string, + ) -> result; + + /// Remove a directory. + /// + /// Return `error-code::not-empty` if the directory is not empty. + /// + /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + @since(version = 0.3.0) + remove-directory-at: func( + /// The relative path to a directory to remove. + path: string, + ) -> result<_, error-code>; + + /// Rename a filesystem object. + /// + /// Note: This is similar to `renameat` in POSIX. + @since(version = 0.3.0) + rename-at: func( + /// The relative source path of the file or directory to rename. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: borrow, + /// The relative destination path to which to rename the file or directory. + new-path: string, + ) -> result<_, error-code>; + + /// Create a symbolic link (also known as a "symlink"). + /// + /// If `old-path` starts with `/`, the function fails with + /// `error-code::not-permitted`. + /// + /// Note: This is similar to `symlinkat` in POSIX. + @since(version = 0.3.0) + symlink-at: func( + /// The contents of the symbolic link. + old-path: string, + /// The relative destination path at which to create the symbolic link. + new-path: string, + ) -> result<_, error-code>; + + /// Unlink a filesystem object that is not a directory. + /// + /// Return `error-code::is-directory` if the path refers to a directory. + /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + @since(version = 0.3.0) + unlink-file-at: func( + /// The relative path to a file to unlink. + path: string, + ) -> result<_, error-code>; + + /// Test whether two descriptors refer to the same filesystem object. + /// + /// In POSIX, this corresponds to testing whether the two descriptors have the + /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. + /// wasi-filesystem does not expose device and inode numbers, so this function + /// may be used instead. + @since(version = 0.3.0) + is-same-object: func(other: borrow) -> bool; + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a descriptor. + /// + /// This returns a hash of the last-modification timestamp and file size, and + /// may also include the inode number, device number, birth timestamp, and + /// other metadata fields that may change when the file is modified or + /// replaced. It may also include a secret value chosen by the + /// implementation and not otherwise exposed. + /// + /// Implementations are encouraged to provide the following properties: + /// + /// - If the file is not modified or replaced, the computed hash value should + /// usually not change. + /// - If the object is modified or replaced, the computed hash value should + /// usually change. + /// - The inputs to the hash should not be easily computable from the + /// computed hash. + /// + /// However, none of these is required. + @since(version = 0.3.0) + metadata-hash: func() -> result; + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a directory descriptor and a relative path. + /// + /// This performs the same hash computation as `metadata-hash`. + @since(version = 0.3.0) + metadata-hash-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result; + } +} diff --git a/proposals/cli/wit-0.3.0-draft/deps/filesystem/world.wit b/proposals/cli/wit-0.3.0-draft/deps/filesystem/world.wit new file mode 100644 index 000000000..c0ab32afe --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/filesystem/world.wit @@ -0,0 +1,9 @@ +package wasi:filesystem@0.3.0; + +@since(version = 0.3.0) +world imports { + @since(version = 0.3.0) + import types; + @since(version = 0.3.0) + import preopens; +} diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit b/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit new file mode 100644 index 000000000..4708d9049 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit @@ -0,0 +1,27 @@ +package wasi:random@0.3.0; +/// The insecure-seed interface for seeding hash-map DoS resistance. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +@since(version = 0.3.0) +interface insecure-seed { + /// Return a 128-bit value that may contain a pseudo-random value. + /// + /// The returned value is not required to be computed from a CSPRNG, and may + /// even be entirely deterministic. Host implementations are encouraged to + /// provide pseudo-random values to any program exposed to + /// attacker-controlled content, to enable DoS protection built into many + /// languages' hash-map implementations. + /// + /// This function is intended to only be called once, by a source language + /// to initialize Denial Of Service (DoS) protection in its hash-map + /// implementation. + /// + /// # Expected future evolution + /// + /// This will likely be changed to a value import, to prevent it from being + /// called multiple times and potentially used for purposes other than DoS + /// protection. + @since(version = 0.3.0) + insecure-seed: func() -> tuple; +} diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit b/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit new file mode 100644 index 000000000..4ea5e581f --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit @@ -0,0 +1,25 @@ +package wasi:random@0.3.0; +/// The insecure interface for insecure pseudo-random numbers. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +@since(version = 0.3.0) +interface insecure { + /// Return `len` insecure pseudo-random bytes. + /// + /// This function is not cryptographically secure. Do not use it for + /// anything related to security. + /// + /// There are no requirements on the values of the returned bytes, however + /// implementations are encouraged to return evenly distributed values with + /// a long period. + @since(version = 0.3.0) + get-insecure-random-bytes: func(len: u64) -> list; + + /// Return an insecure pseudo-random `u64` value. + /// + /// This function returns the same type of pseudo-random data as + /// `get-insecure-random-bytes`, represented as a `u64`. + @since(version = 0.3.0) + get-insecure-random-u64: func() -> u64; +} diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/random.wit b/proposals/cli/wit-0.3.0-draft/deps/random/random.wit new file mode 100644 index 000000000..786ef25f6 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/random/random.wit @@ -0,0 +1,29 @@ +package wasi:random@0.3.0; +/// WASI Random is a random data API. +/// +/// It is intended to be portable at least between Unix-family platforms and +/// Windows. +@since(version = 0.3.0) +interface random { + /// Return `len` cryptographically-secure random or pseudo-random bytes. + /// + /// This function must produce data at least as cryptographically secure and + /// fast as an adequately seeded cryptographically-secure pseudo-random + /// number generator (CSPRNG). It must not block, from the perspective of + /// the calling program, under any circumstances, including on the first + /// request and on requests for numbers of bytes. The returned data must + /// always be unpredictable. + /// + /// This function must always return fresh data. Deterministic environments + /// must omit this function, rather than implementing it with deterministic + /// data. + @since(version = 0.3.0) + get-random-bytes: func(len: u64) -> list; + + /// Return a cryptographically-secure random or pseudo-random `u64` value. + /// + /// This function returns the same type of data as `get-random-bytes`, + /// represented as a `u64`. + @since(version = 0.3.0) + get-random-u64: func() -> u64; +} diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/world.wit b/proposals/cli/wit-0.3.0-draft/deps/random/world.wit new file mode 100644 index 000000000..838d38023 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/random/world.wit @@ -0,0 +1,13 @@ +package wasi:random@0.3.0; + +@since(version = 0.3.0) +world imports { + @since(version = 0.3.0) + import random; + + @since(version = 0.3.0) + import insecure; + + @since(version = 0.3.0) + import insecure-seed; +} diff --git a/proposals/cli/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit new file mode 100644 index 000000000..7cc8b03e3 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit @@ -0,0 +1,62 @@ +@since(version = 0.3.0) +interface ip-name-lookup { + @since(version = 0.3.0) + use types.{ip-address}; + + /// Lookup error codes. + @since(version = 0.3.0) + enum error-code { + /// Unknown error + unknown, + + /// Access denied. + /// + /// POSIX equivalent: EACCES, EPERM + access-denied, + + /// `name` is a syntactically invalid domain name or IP address. + /// + /// POSIX equivalent: EINVAL + invalid-argument, + + /// Name does not exist or has no suitable associated IP addresses. + /// + /// POSIX equivalent: EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY + name-unresolvable, + + /// A temporary failure in name resolution occurred. + /// + /// POSIX equivalent: EAI_AGAIN + temporary-resolver-failure, + + /// A permanent failure in name resolution occurred. + /// + /// POSIX equivalent: EAI_FAIL + permanent-resolver-failure, + } + + /// Resolve an internet host name to a list of IP addresses. + /// + /// Unicode domain names are automatically converted to ASCII using IDNA encoding. + /// If the input is an IP address string, the address is parsed and returned + /// as-is without making any external requests. + /// + /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. + /// + /// The results are returned in connection order preference. + /// + /// This function never succeeds with 0 results. It either fails or succeeds + /// with at least one address. Additionally, this function never returns + /// IPv4-mapped IPv6 addresses. + /// + /// The returned future will resolve to an error code in case of failure. + /// It will resolve to success once the returned stream is exhausted. + /// + /// # References: + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + resolve-addresses: func(name: string) -> result, error-code>; +} diff --git a/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit b/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit new file mode 100644 index 000000000..b5f84d360 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit @@ -0,0 +1,726 @@ +@since(version = 0.3.0) +interface types { + @since(version = 0.3.0) + use wasi:clocks/monotonic-clock@0.3.0.{duration}; + + /// Error codes. + /// + /// In theory, every API can return any error code. + /// In practice, API's typically only return the errors documented per API + /// combined with a couple of errors that are always possible: + /// - `unknown` + /// - `access-denied` + /// - `not-supported` + /// - `out-of-memory` + /// + /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. + @since(version = 0.3.0) + enum error-code { + /// Unknown error + unknown, + + /// Access denied. + /// + /// POSIX equivalent: EACCES, EPERM + access-denied, + + /// The operation is not supported. + /// + /// POSIX equivalent: EOPNOTSUPP + not-supported, + + /// One of the arguments is invalid. + /// + /// POSIX equivalent: EINVAL + invalid-argument, + + /// Not enough memory to complete the operation. + /// + /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY + out-of-memory, + + /// The operation timed out before it could finish completely. + timeout, + + /// The operation is not valid in the socket's current state. + invalid-state, + + /// A bind operation failed because the provided address is not an address that the `network` can bind to. + address-not-bindable, + + /// A bind operation failed because the provided address is already in use or because there are no ephemeral ports available. + address-in-use, + + /// The remote address is not reachable + remote-unreachable, + + + /// The TCP connection was forcefully rejected + connection-refused, + + /// The TCP connection was reset. + connection-reset, + + /// A TCP connection was aborted. + connection-aborted, + + + /// The size of a datagram sent to a UDP socket exceeded the maximum + /// supported size. + datagram-too-large, + } + + @since(version = 0.3.0) + enum ip-address-family { + /// Similar to `AF_INET` in POSIX. + ipv4, + + /// Similar to `AF_INET6` in POSIX. + ipv6, + } + + @since(version = 0.3.0) + type ipv4-address = tuple; + @since(version = 0.3.0) + type ipv6-address = tuple; + + @since(version = 0.3.0) + variant ip-address { + ipv4(ipv4-address), + ipv6(ipv6-address), + } + + @since(version = 0.3.0) + record ipv4-socket-address { + /// sin_port + port: u16, + /// sin_addr + address: ipv4-address, + } + + @since(version = 0.3.0) + record ipv6-socket-address { + /// sin6_port + port: u16, + /// sin6_flowinfo + flow-info: u32, + /// sin6_addr + address: ipv6-address, + /// sin6_scope_id + scope-id: u32, + } + + @since(version = 0.3.0) + variant ip-socket-address { + ipv4(ipv4-socket-address), + ipv6(ipv6-socket-address), + } + + /// A TCP socket resource. + /// + /// The socket can be in one of the following states: + /// - `unbound` + /// - `bound` (See note below) + /// - `listening` + /// - `connecting` + /// - `connected` + /// - `closed` + /// See + /// for more information. + /// + /// Note: Except where explicitly mentioned, whenever this documentation uses + /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. + /// (i.e. `bound`, `listening`, `connecting` or `connected`) + /// + /// In addition to the general error codes documented on the + /// `types::error-code` type, TCP socket methods may always return + /// `error(invalid-state)` when in the `closed` state. + @since(version = 0.3.0) + resource tcp-socket { + + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. + /// + /// Unlike POSIX, WASI sockets have no notion of a socket-level + /// `O_NONBLOCK` flag. Instead they fully rely on the Component Model's + /// async support. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + constructor(address-family: ip-address-family); + + /// Bind the socket to the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// Bind can be attempted multiple times on the same socket, even with + /// different arguments on each iteration. But never concurrently and + /// only as long as the previous bind failed. Once a bind succeeds, the + /// binding can't be changed anymore. + /// + /// # Typical errors + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) + /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that can be bound to. (EADDRNOTAVAIL) + /// + /// # Implementors note + /// When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT + /// state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR + /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior + /// and SO_REUSEADDR performs something different entirely. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + bind: func(local-address: ip-socket-address) -> result<_, error-code>; + + /// Connect to a remote endpoint. + /// + /// On success, the socket is transitioned into the `connected` state and this function returns a connection resource. + /// + /// After a failed connection attempt, the socket will be in the `closed` + /// state and the only valid action left is to `drop` the socket. A single + /// socket can not be used to connect more than once. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) + /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `invalid-state`: The socket is already in the `connecting` state. (EALREADY) + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) + /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + connect: func(remote-address: ip-socket-address) -> result<_, error-code>; + + /// Start listening return a stream of new inbound connections. + /// + /// Transitions the socket into the `listening` state. This can be called + /// at most once per socket. + /// + /// If the socket is not already explicitly bound, this function will + /// implicitly bind the socket to a random free port. + /// + /// Normally, the returned sockets are bound, in the `connected` state + /// and immediately ready for I/O. Though, depending on exact timing and + /// circumstances, a newly accepted connection may already be `closed` + /// by the time the server attempts to perform its first I/O on it. This + /// is true regardless of whether the WASI implementation uses + /// "synthesized" sockets or not (see Implementors Notes below). + /// + /// The following properties are inherited from the listener socket: + /// - `address-family` + /// - `keep-alive-enabled` + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// - `hop-limit` + /// - `receive-buffer-size` + /// - `send-buffer-size` + /// + /// # Typical errors + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) + /// - `invalid-state`: The socket is already in the `listening` state. + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// + /// # Implementors note + /// This method returns a single perpetual stream that should only close + /// on fatal errors (if any). Yet, the POSIX' `accept` function may also + /// return transient errors (e.g. ECONNABORTED). The exact details differ + /// per operation system. For example, the Linux manual mentions: + /// + /// > Linux accept() passes already-pending network errors on the new + /// > socket as an error code from accept(). This behavior differs from + /// > other BSD socket implementations. For reliable operation the + /// > application should detect the network errors defined for the + /// > protocol after accept() and treat them like EAGAIN by retrying. + /// > In the case of TCP/IP, these are ENETDOWN, EPROTO, ENOPROTOOPT, + /// > EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP, and ENETUNREACH. + /// Source: https://man7.org/linux/man-pages/man2/accept.2.html + /// + /// WASI implementations have two options to handle this: + /// - Optionally log it and then skip over non-fatal errors returned by + /// `accept`. Guest code never gets to see these failures. Or: + /// - Synthesize a `tcp-socket` resource that exposes the error when + /// attempting to send or receive on it. Guest code then sees these + /// failures as regular I/O errors. + /// + /// In either case, the stream returned by this `listen` method remains + /// operational. + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + listen: func() -> result, error-code>; + + /// Transmit data to peer. + /// + /// The caller should close the stream when it has no more data to send + /// to the peer. Under normal circumstances this will cause a FIN packet + /// to be sent out. Closing the stream is equivalent to calling + /// `shutdown(SHUT_WR)` in POSIX. + /// + /// This function may be called at most once and returns once the full + /// contents of the stream are transmitted or an error is encountered. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + send: func(data: stream) -> result<_, error-code>; + + /// Read data from peer. + /// + /// This function returns a `stream` which provides the data received from the + /// socket, and a `future` providing additional error information in case the + /// socket is closed abnormally. + /// + /// If the socket is closed normally, `stream.read` on the `stream` will return + /// `read-status::closed` with no `error-context` and the future resolves to + /// the value `ok`. If the socket is closed abnormally, `stream.read` on the + /// `stream` returns `read-status::closed` with an `error-context` and the future + /// resolves to `err` with an `error-code`. + /// + /// `receive` is meant to be called only once per socket. If it is called more + /// than once, the subsequent calls return a new `stream` that fails as if it + /// were closed abnormally. + /// + /// If the caller is not expecting to receive any data from the peer, + /// they may cancel the receive task. Any data still in the receive queue + /// will be discarded. This is equivalent to calling `shutdown(SHUT_RD)` + /// in POSIX. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + receive: func() -> tuple, future>>; + + /// Get the bound local address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + local-address: func() -> result; + + /// Get the remote address. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + remote-address: func() -> result; + + /// Whether the socket is in the `listening` state. + /// + /// Equivalent to the SO_ACCEPTCONN socket option. + @since(version = 0.3.0) + is-listening: func() -> bool; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// This is the value passed to the constructor. + /// + /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.3.0) + address-family: func() -> ip-address-family; + + /// Hints the desired listen queue size. Implementations are free to ignore this. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// + /// # Typical errors + /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. + /// - `invalid-argument`: (set) The provided value was 0. + /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. + @since(version = 0.3.0) + set-listen-backlog-size: func(value: u64) -> result<_, error-code>; + + /// Enables or disables keepalive. + /// + /// The keepalive behavior can be adjusted using: + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. + /// + /// Equivalent to the SO_KEEPALIVE socket option. + @since(version = 0.3.0) + keep-alive-enabled: func() -> result; + @since(version = 0.3.0) + set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; + + /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS) + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + keep-alive-idle-time: func() -> result; + @since(version = 0.3.0) + set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; + + /// The time between keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPINTVL socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + keep-alive-interval: func() -> result; + @since(version = 0.3.0) + set-keep-alive-interval: func(value: duration) -> result<_, error-code>; + + /// The maximum amount of keepalive packets TCP should send before aborting the connection. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPCNT socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + keep-alive-count: func() -> result; + @since(version = 0.3.0) + set-keep-alive-count: func(value: u32) -> result<_, error-code>; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.3.0) + hop-limit: func() -> result; + @since(version = 0.3.0) + set-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + receive-buffer-size: func() -> result; + @since(version = 0.3.0) + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.3.0) + send-buffer-size: func() -> result; + @since(version = 0.3.0) + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + } + + /// A UDP socket handle. + @since(version = 0.3.0) + resource udp-socket { + + /// Create a new UDP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. + /// + /// Unlike POSIX, WASI sockets have no notion of a socket-level + /// `O_NONBLOCK` flag. Instead they fully rely on the Component Model's + /// async support. + /// + /// # References: + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + constructor(address-family: ip-address-family); + + /// Bind the socket to the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the port is zero, the socket will be bound to a random free port. + /// + /// # Typical errors + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that can be bound to. (EADDRNOTAVAIL) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + bind: func(local-address: ip-socket-address) -> result<_, error-code>; + + /// Associate this socket with a specific peer address. + /// + /// On success, the `remote-address` of the socket is updated. + /// The `local-address` may be updated as well, based on the best network + /// path to `remote-address`. If the socket was not already explicitly + /// bound, this function will implicitly bind the socket to a random + /// free port. + /// + /// When a UDP socket is "connected", the `send` and `receive` methods + /// are limited to communicating with that peer only: + /// - `send` can only be used to send to this destination. + /// - `receive` will only return datagrams sent from the provided `remote-address`. + /// + /// The name "connect" was kept to align with the existing POSIX + /// terminology. Other than that, this function only changes the local + /// socket configuration and does not generate any network traffic. + /// The peer is not aware of this "connection". + /// + /// This method may be called multiple times on the same socket to change + /// its association, but only the most recent one will be effective. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// + /// # Implementors note + /// If the socket is already connected, some platforms (e.g. Linux) + /// require a disconnect before connecting to a different peer address. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + connect: func(remote-address: ip-socket-address) -> result<_, error-code>; + + /// Dissociate this socket from its peer address. + /// + /// After calling this method, `send` & `receive` are free to communicate + /// with any address again. + /// + /// The POSIX equivalent of this is calling `connect` with an `AF_UNSPEC` address. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not connected. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + disconnect: func() -> result<_, error-code>; + + /// Send a message on the socket to a particular peer. + /// + /// If the socket is connected, the peer address may be left empty. In + /// that case this is equivalent to `send` in POSIX. Otherwise it is + /// equivalent to `sendto`. + /// + /// Additionally, if the socket is connected, a `remote-address` argument + /// _may_ be provided but then it must be identical to the address + /// passed to `connect`. + /// + /// Implementations may trap if the `data` length exceeds 64 KiB. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `connect`. (EISCONN) + /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) + /// - `invalid-state`: The socket has not been bound yet. + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + send: func(data: list, remote-address: option) -> result<_, error-code>; + + /// Receive a message on the socket. + /// + /// On success, the return value contains a tuple of the received data + /// and the address of the sender. Theoretical maximum length of the + /// data is 64 KiB. Though in practice, it will typically be less than + /// 1500 bytes. + /// + /// If the socket is connected, the sender address is guaranteed to + /// match the remote address passed to `connect`. + /// + /// # Typical errors + /// - `invalid-state`: The socket has not been bound yet. + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + receive: func() -> result, ip-socket-address>, error-code>; + + /// Get the current bound address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + local-address: func() -> result; + + /// Get the address the socket is currently "connected" to. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not "connected" to a specific remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + remote-address: func() -> result; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// This is the value passed to the constructor. + /// + /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.3.0) + address-family: func() -> ip-address-family; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.3.0) + unicast-hop-limit: func() -> result; + @since(version = 0.3.0) + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + receive-buffer-size: func() -> result; + @since(version = 0.3.0) + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.3.0) + send-buffer-size: func() -> result; + @since(version = 0.3.0) + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + } +} diff --git a/proposals/cli/wit-0.3.0-draft/deps/sockets/world.wit b/proposals/cli/wit-0.3.0-draft/deps/sockets/world.wit new file mode 100644 index 000000000..6c9951d1c --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/sockets/world.wit @@ -0,0 +1,9 @@ +package wasi:sockets@0.3.0; + +@since(version = 0.3.0) +world imports { + @since(version = 0.3.0) + import types; + @since(version = 0.3.0) + import ip-name-lookup; +} diff --git a/proposals/cli/wit-0.3.0-draft/environment.wit b/proposals/cli/wit-0.3.0-draft/environment.wit new file mode 100644 index 000000000..d99dcc0ae --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/environment.wit @@ -0,0 +1,22 @@ +@since(version = 0.3.0) +interface environment { + /// Get the POSIX-style environment variables. + /// + /// Each environment variable is provided as a pair of string variable names + /// and string value. + /// + /// Morally, these are a value import, but until value imports are available + /// in the component model, this import function should return the same + /// values each time it is called. + @since(version = 0.3.0) + get-environment: func() -> list>; + + /// Get the POSIX-style arguments to the program. + @since(version = 0.3.0) + get-arguments: func() -> list; + + /// Return a path that programs should use as their initial current working + /// directory, interpreting `.` as shorthand for this. + @since(version = 0.3.0) + initial-cwd: func() -> option; +} diff --git a/proposals/cli/wit-0.3.0-draft/exit.wit b/proposals/cli/wit-0.3.0-draft/exit.wit new file mode 100644 index 000000000..e799a95a2 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/exit.wit @@ -0,0 +1,17 @@ +@since(version = 0.3.0) +interface exit { + /// Exit the current instance and any linked instances. + @since(version = 0.3.0) + exit: func(status: result); + + /// Exit the current instance and any linked instances, reporting the + /// specified status code to the host. + /// + /// The meaning of the code depends on the context, with 0 usually meaning + /// "success", and other values indicating various types of failure. + /// + /// This function does not return; the effect is analogous to a trap, but + /// without the connotation that something bad has happened. + @unstable(feature = cli-exit-with-code) + exit-with-code: func(status-code: u8); +} diff --git a/proposals/cli/wit-0.3.0-draft/imports.wit b/proposals/cli/wit-0.3.0-draft/imports.wit new file mode 100644 index 000000000..5dbc2ede8 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/imports.wit @@ -0,0 +1,34 @@ +package wasi:cli@0.3.0; + +@since(version = 0.3.0) +world imports { + @since(version = 0.3.0) + include wasi:clocks/imports@0.3.0; + @since(version = 0.3.0) + include wasi:filesystem/imports@0.3.0; + @since(version = 0.3.0) + include wasi:sockets/imports@0.3.0; + @since(version = 0.3.0) + include wasi:random/imports@0.3.0; + + @since(version = 0.3.0) + import environment; + @since(version = 0.3.0) + import exit; + @since(version = 0.3.0) + import stdin; + @since(version = 0.3.0) + import stdout; + @since(version = 0.3.0) + import stderr; + @since(version = 0.3.0) + import terminal-input; + @since(version = 0.3.0) + import terminal-output; + @since(version = 0.3.0) + import terminal-stdin; + @since(version = 0.3.0) + import terminal-stdout; + @since(version = 0.3.0) + import terminal-stderr; +} diff --git a/proposals/cli/wit-0.3.0-draft/run.wit b/proposals/cli/wit-0.3.0-draft/run.wit new file mode 100644 index 000000000..6dd8b6879 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/run.wit @@ -0,0 +1,6 @@ +@since(version = 0.3.0) +interface run { + /// Run the program. + @since(version = 0.3.0) + run: func() -> result; +} diff --git a/proposals/cli/wit-0.3.0-draft/stdio.wit b/proposals/cli/wit-0.3.0-draft/stdio.wit new file mode 100644 index 000000000..6a1208fad --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/stdio.wit @@ -0,0 +1,17 @@ +@since(version = 0.3.0) +interface stdin { + @since(version = 0.3.0) + get-stdin: func() -> stream; +} + +@since(version = 0.3.0) +interface stdout { + @since(version = 0.3.0) + set-stdout: func(data: stream); +} + +@since(version = 0.3.0) +interface stderr { + @since(version = 0.3.0) + set-stderr: func(data: stream); +} diff --git a/proposals/cli/wit-0.3.0-draft/terminal.wit b/proposals/cli/wit-0.3.0-draft/terminal.wit new file mode 100644 index 000000000..c37184f4c --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/terminal.wit @@ -0,0 +1,62 @@ +/// Terminal input. +/// +/// In the future, this may include functions for disabling echoing, +/// disabling input buffering so that keyboard events are sent through +/// immediately, querying supported features, and so on. +@since(version = 0.3.0) +interface terminal-input { + /// The input side of a terminal. + @since(version = 0.3.0) + resource terminal-input; +} + +/// Terminal output. +/// +/// In the future, this may include functions for querying the terminal +/// size, being notified of terminal size changes, querying supported +/// features, and so on. +@since(version = 0.3.0) +interface terminal-output { + /// The output side of a terminal. + @since(version = 0.3.0) + resource terminal-output; +} + +/// An interface providing an optional `terminal-input` for stdin as a +/// link-time authority. +@since(version = 0.3.0) +interface terminal-stdin { + @since(version = 0.3.0) + use terminal-input.{terminal-input}; + + /// If stdin is connected to a terminal, return a `terminal-input` handle + /// allowing further interaction with it. + @since(version = 0.3.0) + get-terminal-stdin: func() -> option; +} + +/// An interface providing an optional `terminal-output` for stdout as a +/// link-time authority. +@since(version = 0.3.0) +interface terminal-stdout { + @since(version = 0.3.0) + use terminal-output.{terminal-output}; + + /// If stdout is connected to a terminal, return a `terminal-output` handle + /// allowing further interaction with it. + @since(version = 0.3.0) + get-terminal-stdout: func() -> option; +} + +/// An interface providing an optional `terminal-output` for stderr as a +/// link-time authority. +@since(version = 0.3.0) +interface terminal-stderr { + @since(version = 0.3.0) + use terminal-output.{terminal-output}; + + /// If stderr is connected to a terminal, return a `terminal-output` handle + /// allowing further interaction with it. + @since(version = 0.3.0) + get-terminal-stderr: func() -> option; +} From 1b69eb7fcb7168fc4ddd5f5278447e00933532eb Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 7 Feb 2025 20:07:48 +0100 Subject: [PATCH 1633/1772] Fix CI by enabling all features --- proposals/http/.github/workflows/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index 09d983612..a043898b5 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -17,8 +17,9 @@ jobs: chmod +x ./wit-deps ./wit-deps lock --check ./wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps lock --check - - uses: WebAssembly/wit-abi-up-to-date@v22 + - uses: WebAssembly/wit-abi-up-to-date@v23 with: wasm-tools: '1.223.0' wit-bindgen: '0.37.0' worlds: 'imports proxy' + all-features: 'true' From 2ffe6175d3ba8fd35a112d3d157b9544275aacb1 Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 7 Feb 2025 20:47:32 +0100 Subject: [PATCH 1634/1772] re-lock 0.3.0 deps --- proposals/http/wit-0.3.0-draft/deps.lock | 30 +++++++++---------- .../wit-0.3.0-draft/deps/filesystem/types.wit | 4 +++ .../http/wit-0.3.0-draft/deps/io/poll.wit | 24 +++++++-------- .../deps/random-0-3-0/insecure-seed.wit | 4 +-- .../deps/random-0-3-0/insecure.wit | 6 ++-- .../deps/random-0-3-0/random.wit | 6 ++-- .../deps/random-0-3-0/world.wit | 8 ++--- 7 files changed, 43 insertions(+), 39 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/deps.lock b/proposals/http/wit-0.3.0-draft/deps.lock index 43e3f8ce5..f851bccfa 100644 --- a/proposals/http/wit-0.3.0-draft/deps.lock +++ b/proposals/http/wit-0.3.0-draft/deps.lock @@ -1,12 +1,12 @@ [cli] -url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.3.tar.gz" -sha256 = "4dadd13d55aaf626833d1f4b9c34a17b0f04e993babd09552b785cda3b95ea76" -sha512 = "898dcc4e8c15d18acc6b88dbe232336fa4d19019430a910dbc9e7aeaace3077a164af3be9f002de6e7e65ef693df340801ac0c7e421e9a746bf1b6d698a90835" +url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.4.tar.gz" +sha256 = "674ab0febcabe50a68122751160d243361f401d923e93e4f9c0e6f9d424d21e1" +sha512 = "70529da20c463b37aeff9fb40586e093ee3560bdacf573e8dc8ec2a380c598456294d1308aee9431745ad0fef6ac67aae53b5abb4578c7d682cd5b1485825191" deps = ["clocks", "filesystem", "io", "random", "sockets"] [clocks] -sha256 = "93a701968a7dd3c5d69031bc0601681c468972fdf7e28a93bb6150a67d6ebe8b" -sha512 = "98fca567c7a01887b0fb38981f1772169b6ea8de475b546508f8b86738d84e44ba95cae81def40ac34e8809f5f60e85224077ab8cb6d6d5d6296acc1df73c159" +sha256 = "fc36267c5098ad9ac6455396b27c8ef206ca23cae74f40bd44c57be68e7849b6" +sha512 = "0deed3d3a86f284adda7991cd24c0c4aab806ba2e0cb111da80d7f99c05f10793a602b28451407cad58ab762997f60c0f6d173e919e4a0988773b455d3a410d3" [clocks-0-3-0] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" @@ -15,23 +15,23 @@ sha256 = "26e315db0d371495f8834edfc0e479042f94152ce677d96d54d3623d0e4ffb1e" sha512 = "e1c76f499435841316f9287b88d8173558e64f277c321ff390556de8707a0b18dd6c1749bbb17bbbba8d523da246ef6eb05c990ceddb762e03efb2ae30cacc76" [filesystem] -sha256 = "69d42fb10a04a33545b17e055f13db9b1e10e82ba0ed5bdb52334e40dc07c679" -sha512 = "612effbac6f4804fe0c29dae20b78bbba59e52cb754c15402f5fe229c3153a221e0fbdff1d9d00ceaa3fe049c6a95523a5b99f772f1c16d972eade2c88326a30" +sha256 = "dd435f78b23714bd9d51ef3789c43b831549e71f54b57394a41bbf0c4da45f42" +sha512 = "d58bcf6eae908a6b2d883bcdfe456dc31aa99c848d0b3d21f710bde5bbb59ec105dbd5085004eadd0faa938530e4c29f88e589f525c080eb6d5971775a0b64ed" [io] -sha256 = "1cccbfe4122686ea57a25cd368e8cdfc408cbcad089f47fb6685b6f92e96f050" -sha512 = "7a95f964c13da52611141acd89bc8876226497f128e99dd176a4270c5b5efbd8cc847b5fbd1a91258d028c646db99e0424d72590cf1caf20f9f3a3343fad5017" +sha256 = "770a73d479cda8e4c4064dd4006d2654ebcc358952079d74e41af27cf26bddbf" +sha512 = "b790f9750ac6782d9aaaa379845600b66dbde14ecee42f159c29796447eb8e61ee61f3b306e92622993b5e25298834b6ff62d7d9a04f8f18c05f07eda8f47ae0" [random] -sha256 = "dd0c91e7125172eb8fd4568e15ad9fc7305643015e6ece4396c3cc5e8c2bf79a" -sha512 = "d1ca2e7b0616a94a3b39d1b9450bb3fb595b01fd94a8626ad75433038dde40988ecb41ab93a374d569ab72163af3b30038d7bfc3499b9c07193181f4f1d9292a" +sha256 = "876d81b0a777f1dc9db215fa36f45898a907188819185d6b189345f28c081a45" +sha512 = "fc6a0ed97e0525456222b28bcc49431bade826a97cb6eb52cde595908865d1ed7835c54a63b408ba82e3d49061aebb9a8725d1d2316d28c0ccb12af8ec968ab8" [random-0-3-0] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "f14fa20b4a1ab8e93adc6aa81175b886c951a75ea8fe36f94902bd31c3b709da" -sha512 = "fea98fb83f997e436457652a9f11b911fabd7a904fcce52fc8dcd5c5746609d6329b3992570c12d04b6b0e09427674805f4a563cde90a4af014fe0915178e189" +sha256 = "7a483077cc23fc9dc7a3f067d62795663cceee7dbbd23f205934282b1164a83e" +sha512 = "b99280fd60699f781f20209659e94c0058ce6b9e973ddbd0b8865d752f88c74633485d486d5a86b709385b6e60357470d1c6fbcb3a2769af210c0b1f52417506" [sockets] -sha256 = "2bc0f65a8046207ee3330ad7d63f6fafeafd4cc0ea4084f081bd5e4f7b177e74" -sha512 = "3e5490e41547dffa78d52631825d93da8d60f4af0246cbaf97e1ecb879285953a86d5f1f390b10c32f91dd7eaec6f43e625a26b1c92c32a0c86fde428aedaaab" +sha256 = "e6872db116eb02f2043c4238999712de19bdb22e3c8da00af563f8b6c4dabb18" +sha512 = "28c05fe8acd691d808b6a90b950483bbf59983c02e91ed4a89b0e06c3e2a27e0f73be678979309553f0889fc3fea00c4740b007946d7285aa554dc65d56b1b7f" diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit index 194414edc..962cadfef 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit @@ -508,6 +508,10 @@ interface types { /// Create a hard link. /// + /// Fails with `error-code::no-entry` if the old path does not exist, + /// with `error-code::exist` if the new path already exists, and + /// `error-code::not-permitted` if the old path is not a file. + /// /// Note: This is similar to `linkat` in POSIX. @since(version = 0.2.0) link-at: func( diff --git a/proposals/http/wit-0.3.0-draft/deps/io/poll.wit b/proposals/http/wit-0.3.0-draft/deps/io/poll.wit index 98eda9326..170deff70 100644 --- a/proposals/http/wit-0.3.0-draft/deps/io/poll.wit +++ b/proposals/http/wit-0.3.0-draft/deps/io/poll.wit @@ -8,19 +8,19 @@ interface poll { @since(version = 0.2.0) resource pollable { - /// Return the readiness of a pollable. This function never blocks. - /// - /// Returns `true` when the pollable is ready, and `false` otherwise. - @since(version = 0.2.0) - ready: func() -> bool; + /// Return the readiness of a pollable. This function never blocks. + /// + /// Returns `true` when the pollable is ready, and `false` otherwise. + @since(version = 0.2.0) + ready: func() -> bool; - /// `block` returns immediately if the pollable is ready, and otherwise - /// blocks until ready. - /// - /// This function is equivalent to calling `poll.poll` on a list - /// containing only this pollable. - @since(version = 0.2.0) - block: func(); + /// `block` returns immediately if the pollable is ready, and otherwise + /// blocks until ready. + /// + /// This function is equivalent to calling `poll.poll` on a list + /// containing only this pollable. + @since(version = 0.2.0) + block: func(); } /// Poll for completion on a set of pollables. diff --git a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure-seed.wit b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure-seed.wit index 66a469432..4708d9049 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure-seed.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure-seed.wit @@ -3,7 +3,7 @@ package wasi:random@0.3.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.2.0) +@since(version = 0.3.0) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.2.0) + @since(version = 0.3.0) insecure-seed: func() -> tuple; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure.wit b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure.wit index 7f2b86fbe..4ea5e581f 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure.wit @@ -3,7 +3,7 @@ package wasi:random@0.3.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.2.0) +@since(version = 0.3.0) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.2.0) + @since(version = 0.3.0) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.2.0) + @since(version = 0.3.0) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/random.wit b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/random.wit index 5edfa2baa..786ef25f6 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/random.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/random.wit @@ -3,7 +3,7 @@ package wasi:random@0.3.0; /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.2.0) +@since(version = 0.3.0) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.2.0) + @since(version = 0.3.0) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.2.0) + @since(version = 0.3.0) get-random-u64: func() -> u64; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/world.wit b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/world.wit index d01746d1e..838d38023 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/world.wit @@ -1,13 +1,13 @@ package wasi:random@0.3.0; -@since(version = 0.2.0) +@since(version = 0.3.0) world imports { - @since(version = 0.2.0) + @since(version = 0.3.0) import random; - @since(version = 0.2.0) + @since(version = 0.3.0) import insecure; - @since(version = 0.2.0) + @since(version = 0.3.0) import insecure-seed; } From 7e3c8a0871c810f79410146590d91f55af006ef0 Mon Sep 17 00:00:00 2001 From: SasakiSaki <192608617@qq.com> Date: Sat, 8 Feb 2025 08:42:59 +0800 Subject: [PATCH 1635/1772] Unify the format of wit files (#78) From 0f285e34e7918bc90765802e573d48ed24c6a8c7 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Wed, 12 Feb 2025 16:12:18 -0800 Subject: [PATCH 1636/1772] ci: render all-features --- proposals/sockets/.github/workflows/main.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index 3e61870eb..a7b9d318f 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -20,7 +20,8 @@ jobs: git add -N wit/deps git add -N wit-0.3.0-draft/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v22 + - uses: WebAssembly/wit-abi-up-to-date@v23 with: - wit-bindgen: '0.33.0' - wasm-tools: '1.218.0' + wit-bindgen: '0.37.0' + wasm-tools: '1.223.0' + all-features: 'true' From 8d95d266a2de54e9bf117ea38846b26cd2ec42bb Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Wed, 12 Feb 2025 16:18:25 -0800 Subject: [PATCH 1637/1772] ci: render all-features This proposal does not have features, but future-proofing for consistency. --- proposals/random/.github/workflows/main.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index 431b96bc0..5a0984139 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -11,6 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: WebAssembly/wit-abi-up-to-date@v22 + - uses: WebAssembly/wit-abi-up-to-date@v23 with: - wit-bindgen: '0.33.0' + wit-bindgen: '0.37.0' + all-features: 'true' \ No newline at end of file From acfd4d6ff5761cea253fdfb6fbe884f3b3bb12bb Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Wed, 12 Feb 2025 16:23:18 -0800 Subject: [PATCH 1638/1772] ci: render all-features Future-proofing for later feature additions --- proposals/filesystem/.github/workflows/main.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index db3a34490..abe3a4f22 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -20,6 +20,7 @@ jobs: git add -N wit/deps git add -N wit-0.3.0-draft/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v22 + - uses: WebAssembly/wit-abi-up-to-date@v23 with: - wit-bindgen: '0.33.0' + wit-bindgen: '0.37.0' + all-features: 'true' \ No newline at end of file From 3ad78a682c5faeed35b533f04b60e494056cc97e Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 13 Feb 2025 09:55:35 -0500 Subject: [PATCH 1639/1772] ci: render all-features (#107) This proposal does not have features, but future-proofing for consistency. --- proposals/io/.github/workflows/main.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index d74c466ef..5a0984139 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -11,6 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: WebAssembly/wit-abi-up-to-date@v22 + - uses: WebAssembly/wit-abi-up-to-date@v23 with: - wit-bindgen: '0.36.0' + wit-bindgen: '0.37.0' + all-features: 'true' \ No newline at end of file From e1badd2f49f1fa457cb4bb9919e072887d77d1e1 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 13 Feb 2025 14:51:57 -0800 Subject: [PATCH 1640/1772] ci: render all-features Future-proofing for later feature additions --- proposals/cli/.github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml index ef428071e..584e02cb9 100644 --- a/proposals/cli/.github/workflows/main.yml +++ b/proposals/cli/.github/workflows/main.yml @@ -20,9 +20,9 @@ jobs: git add -N wit/deps git add -N wit-0.3.0-draft/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v22 + - uses: WebAssembly/wit-abi-up-to-date@v23 with: wit-bindgen: '0.33.0' wasm-tools: '1.218.0' worlds: 'command imports' - features: 'cli-exit-with-code' + all-features: 'true' From 41687f125eed63aa707254f7b243c9d3b351ac22 Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 14 Feb 2025 17:11:08 +0100 Subject: [PATCH 1641/1772] fix CI --- proposals/cli/command.md | 90 +++++++++++++++++++++++++++++++++++++++- proposals/cli/imports.md | 90 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 178 insertions(+), 2 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 1350bc214..ee3d65058 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -17,6 +17,7 @@
                    126. interface wasi:cli/terminal-stderr@0.2.4
                    127. interface wasi:clocks/monotonic-clock@0.2.4
                    128. interface wasi:clocks/wall-clock@0.2.4
                    129. +
                    130. interface wasi:clocks/timezone@0.2.4
                    131. interface wasi:filesystem/types@0.2.4
                    132. interface wasi:filesystem/preopens@0.2.4
                    133. interface wasi:sockets/network@0.2.4
                    134. @@ -708,6 +709,71 @@ also known as Unix Time.
                    135. datetime
                    136. +

                      Import interface wasi:clocks/timezone@0.2.4

                      +
                      +

                      Types

                      +

                      type datetime

                      +

                      datetime

                      +

                      +#### `record timezone-display` +

                      Information useful for displaying the timezone of a specific datetime.

                      +

                      This information may vary within a single timezone to reflect daylight +saving time adjustments.

                      +
                      Record Fields
                      +
                        +
                      • +

                        utc-offset: s32

                        +

                        The number of seconds difference between UTC time and the local +time of the timezone. +

                        The returned value will always be less than 86400 which is the +number of seconds in a day (246060).

                        +

                        In implementations that do not expose an actual time zone, this +should return 0.

                        +
                      • +
                      • +

                        name: string

                        +

                        The abbreviated name of the timezone to display to a user. The name +`UTC` indicates Coordinated Universal Time. Otherwise, this should +reference local standards for the name of the time zone. +

                        In implementations that do not expose an actual time zone, this +should be the string UTC.

                        +

                        In time zones that do not have an applicable name, a formatted +representation of the UTC offset may be returned, such as -04:00.

                        +
                      • +
                      • +

                        in-daylight-saving-time: bool

                        +

                        Whether daylight saving time is active. +

                        In implementations that do not expose an actual time zone, this +should return false.

                        +
                      • +
                      +
                      +

                      Functions

                      +

                      display: func

                      +

                      Return information needed to display the given datetime. This includes +the UTC offset, the time zone name, and a flag indicating whether +daylight saving time is active.

                      +

                      If the timezone cannot be determined for the given datetime, return a +timezone-display for UTC with a utc-offset of 0 and no daylight +saving time.

                      +
                      Params
                      + +
                      Return values
                      + +

                      utc-offset: func

                      +

                      The same as display, but only return the UTC offset.

                      +
                      Params
                      + +
                      Return values
                      +
                        +
                      • s32
                      • +

                      Import interface wasi:filesystem/types@0.2.4

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without @@ -1603,7 +1669,10 @@ errors are filesystem-related errors.

                      Import interface wasi:sockets/network@0.2.4


                      Types

                      -

                      resource network

                      +

                      type error

                      +

                      error

                      +

                      +#### `resource network`

                      An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                      @@ -1793,6 +1862,25 @@ supported size.
                    137. ipv4: ipv4-socket-address
                    138. ipv6: ipv6-socket-address
                    139. +
                      +

                      Functions

                      +

                      network-error-code: func

                      +

                      Attempts to extract a network-related error-code from the stream +error provided.

                      +

                      Stream operations which return stream-error::last-operation-failed +have a payload with more information about the operation that failed. +This payload can be passed through to this function to see if there's +network-related information about the error to return.

                      +

                      Note that this function is fallible because not all stream-related +errors are network-related errors.

                      +
                      Params
                      + +
                      Return values
                      +

                      Import interface wasi:sockets/instance-network@0.2.4

                      This interface provides a value-export of the default network handle..


                      diff --git a/proposals/cli/imports.md b/proposals/cli/imports.md index 1751177df..58c8d2995 100644 --- a/proposals/cli/imports.md +++ b/proposals/cli/imports.md @@ -17,6 +17,7 @@
                    140. interface wasi:cli/terminal-stderr@0.2.4
                    141. interface wasi:clocks/monotonic-clock@0.2.4
                    142. interface wasi:clocks/wall-clock@0.2.4
                    143. +
                    144. interface wasi:clocks/timezone@0.2.4
                    145. interface wasi:filesystem/types@0.2.4
                    146. interface wasi:filesystem/preopens@0.2.4
                    147. interface wasi:sockets/network@0.2.4
                    148. @@ -703,6 +704,71 @@ also known as Unix Time.
                    149. datetime
                    150. +

                      Import interface wasi:clocks/timezone@0.2.4

                      +
                      +

                      Types

                      +

                      type datetime

                      +

                      datetime

                      +

                      +#### `record timezone-display` +

                      Information useful for displaying the timezone of a specific datetime.

                      +

                      This information may vary within a single timezone to reflect daylight +saving time adjustments.

                      +
                      Record Fields
                      +
                        +
                      • +

                        utc-offset: s32

                        +

                        The number of seconds difference between UTC time and the local +time of the timezone. +

                        The returned value will always be less than 86400 which is the +number of seconds in a day (246060).

                        +

                        In implementations that do not expose an actual time zone, this +should return 0.

                        +
                      • +
                      • +

                        name: string

                        +

                        The abbreviated name of the timezone to display to a user. The name +`UTC` indicates Coordinated Universal Time. Otherwise, this should +reference local standards for the name of the time zone. +

                        In implementations that do not expose an actual time zone, this +should be the string UTC.

                        +

                        In time zones that do not have an applicable name, a formatted +representation of the UTC offset may be returned, such as -04:00.

                        +
                      • +
                      • +

                        in-daylight-saving-time: bool

                        +

                        Whether daylight saving time is active. +

                        In implementations that do not expose an actual time zone, this +should return false.

                        +
                      • +
                      +
                      +

                      Functions

                      +

                      display: func

                      +

                      Return information needed to display the given datetime. This includes +the UTC offset, the time zone name, and a flag indicating whether +daylight saving time is active.

                      +

                      If the timezone cannot be determined for the given datetime, return a +timezone-display for UTC with a utc-offset of 0 and no daylight +saving time.

                      +
                      Params
                      + +
                      Return values
                      + +

                      utc-offset: func

                      +

                      The same as display, but only return the UTC offset.

                      +
                      Params
                      + +
                      Return values
                      +
                        +
                      • s32
                      • +

                      Import interface wasi:filesystem/types@0.2.4

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without @@ -1598,7 +1664,10 @@ errors are filesystem-related errors.

                      Import interface wasi:sockets/network@0.2.4


                      Types

                      -

                      resource network

                      +

                      type error

                      +

                      error

                      +

                      +#### `resource network`

                      An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                      @@ -1788,6 +1857,25 @@ supported size.
                    151. ipv4: ipv4-socket-address
                    152. ipv6: ipv6-socket-address
                    153. +
                      +

                      Functions

                      +

                      network-error-code: func

                      +

                      Attempts to extract a network-related error-code from the stream +error provided.

                      +

                      Stream operations which return stream-error::last-operation-failed +have a payload with more information about the operation that failed. +This payload can be passed through to this function to see if there's +network-related information about the error to return.

                      +

                      Note that this function is fallible because not all stream-related +errors are network-related errors.

                      +
                      Params
                      + +
                      Return values
                      +

                      Import interface wasi:sockets/instance-network@0.2.4

                      This interface provides a value-export of the default network handle..


                      From 200956a145b33c30d068de9aed4eac9f2cf58c0a Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 25 Feb 2025 18:38:14 +0100 Subject: [PATCH 1642/1772] fix(wasip3): allow `send` on unbound UDP sockets Most other `udp-socket` methods (e.g. connect) rely on implicit binding of the socket, however `send` currently requires the socket to be bound, which is inconsistent Signed-off-by: Roman Volosatovs --- proposals/sockets/wit-0.3.0-draft/types.wit | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index b5f84d360..68b3c7918 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -610,7 +610,6 @@ interface types { /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `connect`. (EISCONN) /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) - /// - `invalid-state`: The socket has not been bound yet. /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) /// - `connection-refused`: The connection was refused. (ECONNREFUSED) /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) From 11960410f131df529fb53fce64d27ca59e82252b Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 26 Feb 2025 17:23:36 +0100 Subject: [PATCH 1643/1772] refactor(p3): clarify `tcp-socket.receive` semantics Signed-off-by: Roman Volosatovs --- proposals/sockets/wit-0.3.0-draft/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index b5f84d360..6b6127bc9 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -328,7 +328,7 @@ interface types { /// were closed abnormally. /// /// If the caller is not expecting to receive any data from the peer, - /// they may cancel the receive task. Any data still in the receive queue + /// they may drop the stream. Any data still in the receive queue /// will be discarded. This is equivalent to calling `shutdown(SHUT_RD)` /// in POSIX. /// From ae04aaf52992c3448421bbeba2fee2fd06dd27d4 Mon Sep 17 00:00:00 2001 From: Victor Adossi <123968127+vados-cosmonic@users.noreply.github.com> Date: Tue, 11 Mar 2025 08:51:39 +0900 Subject: [PATCH 1644/1772] feat: allow independent retrieval of trailers (#154) This commit changes wasi:http/types#body.finish to forward the optionally present trailers, rather than retrieve them with the possibility of generating an error along the way. With this change, callers of `body.finish` will have to retreive trailers on their own, which *may* produce an efficiency gain in the case where trailers are present but not needed, and avoiding work of checking for trailers in the first place. Signed-off-by: Victor Adossi --- proposals/http/wit-0.3.0-draft/types.wit | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index d720fbed5..2e785a8b3 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -240,14 +240,27 @@ interface types { /// trailers at any given time. resource body { + /// Construct a new `body` with the specified stream. + /// + /// This function returns a future, which will resolve + /// to an error code if transmitting stream data fails. + /// + /// The returned future resolves to success once body stream + /// is fully transmitted. + new: static func( + %stream: stream, + ) -> tuple>>; + /// Construct a new `body` with the specified stream and trailers. + /// /// This function returns a future, which will resolve /// to an error code if transmitting stream data or trailers fails. + /// /// The returned future resolves to success once body stream and trailers /// are fully transmitted. - new: static func( + new-with-trailers: static func( %stream: stream, - trailers: option> + trailers: future ) -> tuple>>; /// Returns the contents of the body, as a stream of bytes. @@ -260,9 +273,10 @@ interface types { /// The returned future resolves to success if body is closed. %stream: func() -> result>, future>>; - /// Takes ownership of `body`, and returns a `trailers`. This function will - /// trap if a `stream` child is still alive. - finish: static func(this: body) -> result, error-code>; + /// Takes ownership of `body`, and returns an unresolved optional `trailers`. + /// + /// This function will trap if a `stream` child is still alive. + finish: static func(this: body) -> future>; } /// Represents an HTTP Request. From 0a1661be7d79a9887c2fecc560c06b29903d8eb2 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 11 Mar 2025 07:30:11 -0600 Subject: [PATCH 1645/1772] fix misplaced `>` in `body.stream` signature (#155) Signed-off-by: Joel Dice --- proposals/http/wit-0.3.0-draft/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index 2e785a8b3..31eb62add 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -271,7 +271,7 @@ interface types { /// On success, this function returns a stream and a future, which will resolve /// to an error code if receiving data from stream fails. /// The returned future resolves to success if body is closed. - %stream: func() -> result>, future>>; + %stream: func() -> result, future>>>; /// Takes ownership of `body`, and returns an unresolved optional `trailers`. /// From 0d423931d658e25023722d68b3c076d475d1e1a9 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 12 Mar 2025 18:56:16 +0100 Subject: [PATCH 1646/1772] chore(0.3): update to `wasi:cli@0.3.0` (#145) Signed-off-by: Roman Volosatovs --- proposals/http/wit-0.3.0-draft/deps.lock | 33 +- proposals/http/wit-0.3.0-draft/deps.toml | 4 +- .../http/wit-0.3.0-draft/deps/cli/command.wit | 8 +- .../wit-0.3.0-draft/deps/cli/environment.wit | 8 +- .../http/wit-0.3.0-draft/deps/cli/exit.wit | 4 +- .../http/wit-0.3.0-draft/deps/cli/imports.wit | 42 +- .../http/wit-0.3.0-draft/deps/cli/run.wit | 4 +- .../http/wit-0.3.0-draft/deps/cli/stdio.wit | 27 +- .../wit-0.3.0-draft/deps/cli/terminal.wit | 26 +- .../deps/clocks-0-3-0/monotonic-clock.wit | 45 -- .../deps/clocks-0-3-0/timezone.wit | 55 -- .../deps/clocks-0-3-0/wall-clock.wit | 46 -- .../deps/clocks-0-3-0/world.wit | 11 - .../deps/clocks/monotonic-clock.wit | 35 +- .../wit-0.3.0-draft/deps/clocks/timezone.wit | 2 +- .../deps/clocks/wall-clock.wit | 10 +- .../wit-0.3.0-draft/deps/clocks/world.wit | 8 +- .../deps/filesystem/preopens.wit | 8 +- .../wit-0.3.0-draft/deps/filesystem/types.wit | 179 ++--- .../wit-0.3.0-draft/deps/filesystem/world.wit | 8 +- .../http/wit-0.3.0-draft/deps/io/error.wit | 34 - .../http/wit-0.3.0-draft/deps/io/poll.wit | 47 -- .../http/wit-0.3.0-draft/deps/io/streams.wit | 290 ------- .../http/wit-0.3.0-draft/deps/io/world.wit | 10 - .../deps/random-0-3-0/insecure-seed.wit | 27 - .../deps/random-0-3-0/insecure.wit | 25 - .../deps/random-0-3-0/random.wit | 29 - .../deps/random-0-3-0/world.wit | 13 - .../deps/random/insecure-seed.wit | 6 +- .../wit-0.3.0-draft/deps/random/insecure.wit | 8 +- .../wit-0.3.0-draft/deps/random/random.wit | 8 +- .../wit-0.3.0-draft/deps/random/world.wit | 10 +- .../deps/sockets/instance-network.wit | 11 - .../deps/sockets/ip-name-lookup.wit | 82 +- .../wit-0.3.0-draft/deps/sockets/network.wit | 169 ---- .../deps/sockets/tcp-create-socket.wit | 30 - .../http/wit-0.3.0-draft/deps/sockets/tcp.wit | 387 ---------- .../wit-0.3.0-draft/deps/sockets/types.wit | 726 ++++++++++++++++++ .../deps/sockets/udp-create-socket.wit | 30 - .../http/wit-0.3.0-draft/deps/sockets/udp.wit | 288 ------- .../wit-0.3.0-draft/deps/sockets/world.wit | 20 +- proposals/http/wit-0.3.0-draft/proxy.wit | 6 +- 42 files changed, 957 insertions(+), 1862 deletions(-) delete mode 100644 proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/monotonic-clock.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/timezone.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/wall-clock.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/world.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/io/error.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/io/poll.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/io/streams.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/io/world.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure-seed.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/random-0-3-0/random.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/random-0-3-0/world.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/instance-network.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/network.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/tcp-create-socket.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit create mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/types.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/udp-create-socket.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit diff --git a/proposals/http/wit-0.3.0-draft/deps.lock b/proposals/http/wit-0.3.0-draft/deps.lock index f851bccfa..0ee4a25ff 100644 --- a/proposals/http/wit-0.3.0-draft/deps.lock +++ b/proposals/http/wit-0.3.0-draft/deps.lock @@ -1,37 +1,22 @@ [cli] -url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.4.tar.gz" -sha256 = "674ab0febcabe50a68122751160d243361f401d923e93e4f9c0e6f9d424d21e1" -sha512 = "70529da20c463b37aeff9fb40586e093ee3560bdacf573e8dc8ec2a380c598456294d1308aee9431745ad0fef6ac67aae53b5abb4578c7d682cd5b1485825191" -deps = ["clocks", "filesystem", "io", "random", "sockets"] +url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" +subdir = "wit-0.3.0-draft" +sha256 = "9a94018c67baf2ab4475f23c164514724ca08795195184adb4b38cb8dc5d6f9c" +sha512 = "8d2f3076eb94118c5321fd18dda60c0078087dbcbed57c6b973b8fc2225670045d94a6f70f4f19c0fb0e13bbb0344325d4dce3a48417b97434344d2a2c1371fd" +deps = ["clocks", "filesystem", "random", "sockets"] [clocks] -sha256 = "fc36267c5098ad9ac6455396b27c8ef206ca23cae74f40bd44c57be68e7849b6" -sha512 = "0deed3d3a86f284adda7991cd24c0c4aab806ba2e0cb111da80d7f99c05f10793a602b28451407cad58ab762997f60c0f6d173e919e4a0988773b455d3a410d3" - -[clocks-0-3-0] -url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -subdir = "wit-0.3.0-draft" sha256 = "26e315db0d371495f8834edfc0e479042f94152ce677d96d54d3623d0e4ffb1e" sha512 = "e1c76f499435841316f9287b88d8173558e64f277c321ff390556de8707a0b18dd6c1749bbb17bbbba8d523da246ef6eb05c990ceddb762e03efb2ae30cacc76" [filesystem] -sha256 = "dd435f78b23714bd9d51ef3789c43b831549e71f54b57394a41bbf0c4da45f42" -sha512 = "d58bcf6eae908a6b2d883bcdfe456dc31aa99c848d0b3d21f710bde5bbb59ec105dbd5085004eadd0faa938530e4c29f88e589f525c080eb6d5971775a0b64ed" - -[io] -sha256 = "770a73d479cda8e4c4064dd4006d2654ebcc358952079d74e41af27cf26bddbf" -sha512 = "b790f9750ac6782d9aaaa379845600b66dbde14ecee42f159c29796447eb8e61ee61f3b306e92622993b5e25298834b6ff62d7d9a04f8f18c05f07eda8f47ae0" +sha256 = "f8a82b21e18cad3498b53475666a3f00c4c1b5f030b7ed47c79262e3dbe97461" +sha512 = "0e62fe9ff3ba0572d890a2edd969e88a5c2327279cec681d3f2688ed8442820333f6041b0f0956b44941f971a6afb785bd2f5248ca0c99b51f13521496cadbcc" [random] -sha256 = "876d81b0a777f1dc9db215fa36f45898a907188819185d6b189345f28c081a45" -sha512 = "fc6a0ed97e0525456222b28bcc49431bade826a97cb6eb52cde595908865d1ed7835c54a63b408ba82e3d49061aebb9a8725d1d2316d28c0ccb12af8ec968ab8" - -[random-0-3-0] -url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" -subdir = "wit-0.3.0-draft" sha256 = "7a483077cc23fc9dc7a3f067d62795663cceee7dbbd23f205934282b1164a83e" sha512 = "b99280fd60699f781f20209659e94c0058ce6b9e973ddbd0b8865d752f88c74633485d486d5a86b709385b6e60357470d1c6fbcb3a2769af210c0b1f52417506" [sockets] -sha256 = "e6872db116eb02f2043c4238999712de19bdb22e3c8da00af563f8b6c4dabb18" -sha512 = "28c05fe8acd691d808b6a90b950483bbf59983c02e91ed4a89b0e06c3e2a27e0f73be678979309553f0889fc3fea00c4740b007946d7285aa554dc65d56b1b7f" +sha256 = "48fa617cdf64b66adc7136e4f0c14886061e6d5134072bf8e1698b84e2579669" +sha512 = "786b8a03c14d3f529500275762a37c497ea1e6479e71028e8173aa07594beb77226904d77970a7c356ff3f59aa4a5c10f2e68537cc96b9916ff03a317b05a229" diff --git a/proposals/http/wit-0.3.0-draft/deps.toml b/proposals/http/wit-0.3.0-draft/deps.toml index da0017d04..b80f1e2d1 100644 --- a/proposals/http/wit-0.3.0-draft/deps.toml +++ b/proposals/http/wit-0.3.0-draft/deps.toml @@ -1,3 +1 @@ -cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.4.tar.gz" # TODO: update to v0.3.0-draft and remove custom clock and random imports -clocks-0-3-0 = { url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz", subdir = "wit-0.3.0-draft" } -random-0-3-0 = { url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz", subdir = "wit-0.3.0-draft" } +cli = { url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz", subdir = "wit-0.3.0-draft" } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit index 88ab2a97e..0310e5151 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit @@ -1,10 +1,10 @@ -package wasi:cli@0.2.4; +package wasi:cli@0.3.0; -@since(version = 0.2.0) +@since(version = 0.3.0) world command { - @since(version = 0.2.0) + @since(version = 0.3.0) include imports; - @since(version = 0.2.0) + @since(version = 0.3.0) export run; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit b/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit index 2f449bd7c..d99dcc0ae 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit @@ -1,4 +1,4 @@ -@since(version = 0.2.0) +@since(version = 0.3.0) interface environment { /// Get the POSIX-style environment variables. /// @@ -8,15 +8,15 @@ interface environment { /// Morally, these are a value import, but until value imports are available /// in the component model, this import function should return the same /// values each time it is called. - @since(version = 0.2.0) + @since(version = 0.3.0) get-environment: func() -> list>; /// Get the POSIX-style arguments to the program. - @since(version = 0.2.0) + @since(version = 0.3.0) get-arguments: func() -> list; /// Return a path that programs should use as their initial current working /// directory, interpreting `.` as shorthand for this. - @since(version = 0.2.0) + @since(version = 0.3.0) initial-cwd: func() -> option; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit b/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit index 427935c8d..e799a95a2 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit @@ -1,7 +1,7 @@ -@since(version = 0.2.0) +@since(version = 0.3.0) interface exit { /// Exit the current instance and any linked instances. - @since(version = 0.2.0) + @since(version = 0.3.0) exit: func(status: result); /// Exit the current instance and any linked instances, reporting the diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit index ad5c6bb23..5dbc2ede8 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit @@ -1,36 +1,34 @@ -package wasi:cli@0.2.4; +package wasi:cli@0.3.0; -@since(version = 0.2.0) +@since(version = 0.3.0) world imports { - @since(version = 0.2.0) - include wasi:clocks/imports@0.2.4; - @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.4; - @since(version = 0.2.0) - include wasi:sockets/imports@0.2.4; - @since(version = 0.2.0) - include wasi:random/imports@0.2.4; - @since(version = 0.2.0) - include wasi:io/imports@0.2.4; + @since(version = 0.3.0) + include wasi:clocks/imports@0.3.0; + @since(version = 0.3.0) + include wasi:filesystem/imports@0.3.0; + @since(version = 0.3.0) + include wasi:sockets/imports@0.3.0; + @since(version = 0.3.0) + include wasi:random/imports@0.3.0; - @since(version = 0.2.0) + @since(version = 0.3.0) import environment; - @since(version = 0.2.0) + @since(version = 0.3.0) import exit; - @since(version = 0.2.0) + @since(version = 0.3.0) import stdin; - @since(version = 0.2.0) + @since(version = 0.3.0) import stdout; - @since(version = 0.2.0) + @since(version = 0.3.0) import stderr; - @since(version = 0.2.0) + @since(version = 0.3.0) import terminal-input; - @since(version = 0.2.0) + @since(version = 0.3.0) import terminal-output; - @since(version = 0.2.0) + @since(version = 0.3.0) import terminal-stdin; - @since(version = 0.2.0) + @since(version = 0.3.0) import terminal-stdout; - @since(version = 0.2.0) + @since(version = 0.3.0) import terminal-stderr; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/run.wit b/proposals/http/wit-0.3.0-draft/deps/cli/run.wit index 655346efb..6dd8b6879 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/run.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/run.wit @@ -1,6 +1,6 @@ -@since(version = 0.2.0) +@since(version = 0.3.0) interface run { /// Run the program. - @since(version = 0.2.0) + @since(version = 0.3.0) run: func() -> result; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit index 60727a930..6a1208fad 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit @@ -1,26 +1,17 @@ -@since(version = 0.2.0) +@since(version = 0.3.0) interface stdin { - @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{input-stream}; - - @since(version = 0.2.0) - get-stdin: func() -> input-stream; + @since(version = 0.3.0) + get-stdin: func() -> stream; } -@since(version = 0.2.0) +@since(version = 0.3.0) interface stdout { - @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{output-stream}; - - @since(version = 0.2.0) - get-stdout: func() -> output-stream; + @since(version = 0.3.0) + set-stdout: func(data: stream); } -@since(version = 0.2.0) +@since(version = 0.3.0) interface stderr { - @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{output-stream}; - - @since(version = 0.2.0) - get-stderr: func() -> output-stream; + @since(version = 0.3.0) + set-stderr: func(data: stream); } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit b/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit index d305498c6..c37184f4c 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit @@ -3,10 +3,10 @@ /// In the future, this may include functions for disabling echoing, /// disabling input buffering so that keyboard events are sent through /// immediately, querying supported features, and so on. -@since(version = 0.2.0) +@since(version = 0.3.0) interface terminal-input { /// The input side of a terminal. - @since(version = 0.2.0) + @since(version = 0.3.0) resource terminal-input; } @@ -15,48 +15,48 @@ interface terminal-input { /// In the future, this may include functions for querying the terminal /// size, being notified of terminal size changes, querying supported /// features, and so on. -@since(version = 0.2.0) +@since(version = 0.3.0) interface terminal-output { /// The output side of a terminal. - @since(version = 0.2.0) + @since(version = 0.3.0) resource terminal-output; } /// An interface providing an optional `terminal-input` for stdin as a /// link-time authority. -@since(version = 0.2.0) +@since(version = 0.3.0) interface terminal-stdin { - @since(version = 0.2.0) + @since(version = 0.3.0) use terminal-input.{terminal-input}; /// If stdin is connected to a terminal, return a `terminal-input` handle /// allowing further interaction with it. - @since(version = 0.2.0) + @since(version = 0.3.0) get-terminal-stdin: func() -> option; } /// An interface providing an optional `terminal-output` for stdout as a /// link-time authority. -@since(version = 0.2.0) +@since(version = 0.3.0) interface terminal-stdout { - @since(version = 0.2.0) + @since(version = 0.3.0) use terminal-output.{terminal-output}; /// If stdout is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - @since(version = 0.2.0) + @since(version = 0.3.0) get-terminal-stdout: func() -> option; } /// An interface providing an optional `terminal-output` for stderr as a /// link-time authority. -@since(version = 0.2.0) +@since(version = 0.3.0) interface terminal-stderr { - @since(version = 0.2.0) + @since(version = 0.3.0) use terminal-output.{terminal-output}; /// If stderr is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - @since(version = 0.2.0) + @since(version = 0.3.0) get-terminal-stderr: func() -> option; } diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/monotonic-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/monotonic-clock.wit deleted file mode 100644 index 87ebdaac5..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/monotonic-clock.wit +++ /dev/null @@ -1,45 +0,0 @@ -package wasi:clocks@0.3.0; -/// WASI Monotonic Clock is a clock API intended to let users measure elapsed -/// time. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -/// -/// A monotonic clock is a clock which has an unspecified initial value, and -/// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0) -interface monotonic-clock { - /// An instant in time, in nanoseconds. An instant is relative to an - /// unspecified initial value, and can only be compared to instances from - /// the same monotonic-clock. - @since(version = 0.3.0) - type instant = u64; - - /// A duration of time, in nanoseconds. - @since(version = 0.3.0) - type duration = u64; - - /// Read the current value of the clock. - /// - /// The clock is monotonic, therefore calling this function repeatedly will - /// produce a sequence of non-decreasing values. - @since(version = 0.3.0) - now: func() -> instant; - - /// Query the resolution of the clock. Returns the duration of time - /// corresponding to a clock tick. - @since(version = 0.3.0) - resolution: func() -> duration; - - /// Wait until the specified instant has occurred. - @since(version = 0.3.0) - wait-until: func( - when: instant, - ); - - /// Wait for the specified duration has elapsed. - @since(version = 0.3.0) - wait-for: func( - how-long: duration, - ); -} diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/timezone.wit b/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/timezone.wit deleted file mode 100644 index ac9146834..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/timezone.wit +++ /dev/null @@ -1,55 +0,0 @@ -package wasi:clocks@0.3.0; - -@unstable(feature = clocks-timezone) -interface timezone { - @unstable(feature = clocks-timezone) - use wall-clock.{datetime}; - - /// Return information needed to display the given `datetime`. This includes - /// the UTC offset, the time zone name, and a flag indicating whether - /// daylight saving time is active. - /// - /// If the timezone cannot be determined for the given `datetime`, return a - /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight - /// saving time. - @unstable(feature = clocks-timezone) - display: func(when: datetime) -> timezone-display; - - /// The same as `display`, but only return the UTC offset. - @unstable(feature = clocks-timezone) - utc-offset: func(when: datetime) -> s32; - - /// Information useful for displaying the timezone of a specific `datetime`. - /// - /// This information may vary within a single `timezone` to reflect daylight - /// saving time adjustments. - @unstable(feature = clocks-timezone) - record timezone-display { - /// The number of seconds difference between UTC time and the local - /// time of the timezone. - /// - /// The returned value will always be less than 86400 which is the - /// number of seconds in a day (24*60*60). - /// - /// In implementations that do not expose an actual time zone, this - /// should return 0. - utc-offset: s32, - - /// The abbreviated name of the timezone to display to a user. The name - /// `UTC` indicates Coordinated Universal Time. Otherwise, this should - /// reference local standards for the name of the time zone. - /// - /// In implementations that do not expose an actual time zone, this - /// should be the string `UTC`. - /// - /// In time zones that do not have an applicable name, a formatted - /// representation of the UTC offset may be returned, such as `-04:00`. - name: string, - - /// Whether daylight saving time is active. - /// - /// In implementations that do not expose an actual time zone, this - /// should return false. - in-daylight-saving-time: bool, - } -} diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/wall-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/wall-clock.wit deleted file mode 100644 index b7a85ab35..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/wall-clock.wit +++ /dev/null @@ -1,46 +0,0 @@ -package wasi:clocks@0.3.0; -/// WASI Wall Clock is a clock API intended to let users query the current -/// time. The name "wall" makes an analogy to a "clock on the wall", which -/// is not necessarily monotonic as it may be reset. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -/// -/// A wall clock is a clock which measures the date and time according to -/// some external reference. -/// -/// External references may be reset, so this clock is not necessarily -/// monotonic, making it unsuitable for measuring elapsed time. -/// -/// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0) -interface wall-clock { - /// A time and date in seconds plus nanoseconds. - @since(version = 0.3.0) - record datetime { - seconds: u64, - nanoseconds: u32, - } - - /// Read the current value of the clock. - /// - /// This clock is not monotonic, therefore calling this function repeatedly - /// will not necessarily produce a sequence of non-decreasing values. - /// - /// The returned timestamps represent the number of seconds since - /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], - /// also known as [Unix Time]. - /// - /// The nanoseconds field of the output is always less than 1000000000. - /// - /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 - /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0) - now: func() -> datetime; - - /// Query the resolution of the clock. - /// - /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0) - resolution: func() -> datetime; -} diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/world.wit b/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/world.wit deleted file mode 100644 index f97bcfef1..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/clocks-0-3-0/world.wit +++ /dev/null @@ -1,11 +0,0 @@ -package wasi:clocks@0.3.0; - -@since(version = 0.3.0) -world imports { - @since(version = 0.3.0) - import monotonic-clock; - @since(version = 0.3.0) - import wall-clock; - @unstable(feature = clocks-timezone) - import timezone; -} diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 175f8fe2d..87ebdaac5 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.3.0; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,44 +7,39 @@ package wasi:clocks@0.2.4; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -@since(version = 0.2.0) +@since(version = 0.3.0) interface monotonic-clock { - @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; - /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. - @since(version = 0.2.0) + @since(version = 0.3.0) type instant = u64; /// A duration of time, in nanoseconds. - @since(version = 0.2.0) + @since(version = 0.3.0) type duration = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - @since(version = 0.2.0) + @since(version = 0.3.0) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. - @since(version = 0.2.0) + @since(version = 0.3.0) resolution: func() -> duration; - /// Create a `pollable` which will resolve once the specified instant - /// has occurred. - @since(version = 0.2.0) - subscribe-instant: func( + /// Wait until the specified instant has occurred. + @since(version = 0.3.0) + wait-until: func( when: instant, - ) -> pollable; + ); - /// Create a `pollable` that will resolve after the specified duration has - /// elapsed from the time this function is invoked. - @since(version = 0.2.0) - subscribe-duration: func( - when: duration, - ) -> pollable; + /// Wait for the specified duration has elapsed. + @since(version = 0.3.0) + wait-for: func( + how-long: duration, + ); } diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit index 658cb17e7..ac9146834 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.3.0; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit index f826cd1e0..b7a85ab35 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.3.0; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,10 +13,10 @@ package wasi:clocks@0.2.4; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -@since(version = 0.2.0) +@since(version = 0.3.0) interface wall-clock { /// A time and date in seconds plus nanoseconds. - @since(version = 0.2.0) + @since(version = 0.3.0) record datetime { seconds: u64, nanoseconds: u32, @@ -35,12 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.2.0) + @since(version = 0.3.0) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.2.0) + @since(version = 0.3.0) resolution: func() -> datetime; } diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit index 9e2087447..f97bcfef1 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit @@ -1,10 +1,10 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.3.0; -@since(version = 0.2.0) +@since(version = 0.3.0) world imports { - @since(version = 0.2.0) + @since(version = 0.3.0) import monotonic-clock; - @since(version = 0.2.0) + @since(version = 0.3.0) import wall-clock; @unstable(feature = clocks-timezone) import timezone; diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit index 6e6003954..0b29aae33 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit @@ -1,11 +1,11 @@ -package wasi:filesystem@0.2.4; +package wasi:filesystem@0.3.0; -@since(version = 0.2.0) +@since(version = 0.3.0) interface preopens { - @since(version = 0.2.0) + @since(version = 0.3.0) use types.{descriptor}; /// Return the set of preopened directories, and their paths. - @since(version = 0.2.0) + @since(version = 0.3.0) get-directories: func() -> list>; } diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit index 962cadfef..af3cb254c 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.4; +package wasi:filesystem@0.3.0; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -23,21 +23,19 @@ package wasi:filesystem@0.2.4; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -@since(version = 0.2.0) +@since(version = 0.3.0) interface types { - @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{input-stream, output-stream, error}; - @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.4.{datetime}; + @since(version = 0.3.0) + use wasi:clocks/wall-clock@0.3.0.{datetime}; /// File size or length of a region within a file. - @since(version = 0.2.0) + @since(version = 0.3.0) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. - @since(version = 0.2.0) + @since(version = 0.3.0) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -61,7 +59,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. - @since(version = 0.2.0) + @since(version = 0.3.0) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -105,7 +103,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. - @since(version = 0.2.0) + @since(version = 0.3.0) record descriptor-stat { /// File type. %type: descriptor-type, @@ -132,7 +130,7 @@ interface types { } /// Flags determining the method of how paths are resolved. - @since(version = 0.2.0) + @since(version = 0.3.0) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -140,7 +138,7 @@ interface types { } /// Open flags used by `open-at`. - @since(version = 0.2.0) + @since(version = 0.3.0) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -153,11 +151,11 @@ interface types { } /// Number of hard links to an inode. - @since(version = 0.2.0) + @since(version = 0.3.0) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. - @since(version = 0.2.0) + @since(version = 0.3.0) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -184,8 +182,6 @@ interface types { enum error-code { /// Permission denied, similar to `EACCES` in POSIX. access, - /// Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. - would-block, /// Connection already in progress, similar to `EALREADY` in POSIX. already, /// Bad descriptor, similar to `EBADF` in POSIX. @@ -259,7 +255,7 @@ interface types { } /// File or memory access pattern advisory information. - @since(version = 0.2.0) + @since(version = 0.3.0) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -283,7 +279,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. - @since(version = 0.2.0) + @since(version = 0.3.0) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -294,47 +290,58 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. - @since(version = 0.2.0) + @since(version = 0.3.0) resource descriptor { - /// Return a stream for reading from a file, if available. - /// - /// May fail with an error-code describing why the file cannot be read. + /// Return a stream for reading from a file. /// /// Multiple read, write, and append streams may be active on the same open /// file and they do not interfere with each other. /// - /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. - @since(version = 0.2.0) + /// This function returns a future, which will resolve to an error code if + /// reading full contents of the file fails. + /// + /// Note: This is similar to `pread` in POSIX. + @since(version = 0.3.0) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, - ) -> result; + ) -> tuple, future>>; /// Return a stream for writing to a file, if available. /// /// May fail with an error-code describing why the file cannot be written. /// - /// Note: This allows using `write-stream`, which is similar to `write` in - /// POSIX. - @since(version = 0.2.0) + /// It is valid to write past the end of a file; the file is extended to the + /// extent of the write, with bytes between the previous end and the start of + /// the write set to zero. + /// + /// This function returns once either full contents of the stream are + /// written or an error is encountered. + /// + /// Note: This is similar to `pwrite` in POSIX. + @since(version = 0.3.0) write-via-stream: func( + /// Data to write + data: stream, /// The offset within the file at which to start writing. offset: filesize, - ) -> result; + ) -> result<_, error-code>; /// Return a stream for appending to a file, if available. /// /// May fail with an error-code describing why the file cannot be appended. /// - /// Note: This allows using `write-stream`, which is similar to `write` with - /// `O_APPEND` in POSIX. - @since(version = 0.2.0) - append-via-stream: func() -> result; + /// This function returns once either full contents of the stream are + /// written or an error is encountered. + /// + /// Note: This is similar to `write` with `O_APPEND` in POSIX. + @since(version = 0.3.0) + append-via-stream: func(data: stream) -> result<_, error-code>; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. - @since(version = 0.2.0) + @since(version = 0.3.0) advise: func( /// The offset within the file to which the advisory applies. offset: filesize, @@ -350,7 +357,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - @since(version = 0.2.0) + @since(version = 0.3.0) sync-data: func() -> result<_, error-code>; /// Get flags associated with a descriptor. @@ -359,7 +366,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.2.0) + @since(version = 0.3.0) get-flags: func() -> result; /// Get the dynamic type of a descriptor. @@ -372,14 +379,14 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.2.0) + @since(version = 0.3.0) get-type: func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - @since(version = 0.2.0) + @since(version = 0.3.0) set-size: func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. @@ -387,7 +394,7 @@ interface types { /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - @since(version = 0.2.0) + @since(version = 0.3.0) set-times: func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, @@ -395,42 +402,6 @@ interface types { data-modification-timestamp: new-timestamp, ) -> result<_, error-code>; - /// Read from a descriptor, without using and updating the descriptor's offset. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a bool which, when true, indicates that the end of the - /// file was reached. The returned list will contain up to `length` bytes; it - /// may return fewer than requested, if the end of the file is reached or - /// if the I/O operation is interrupted. - /// - /// In the future, this may change to return a `stream`. - /// - /// Note: This is similar to `pread` in POSIX. - @since(version = 0.2.0) - read: func( - /// The maximum number of bytes to read. - length: filesize, - /// The offset within the file at which to read. - offset: filesize, - ) -> result, bool>, error-code>; - - /// Write to a descriptor, without using and updating the descriptor's offset. - /// - /// It is valid to write past the end of a file; the file is extended to the - /// extent of the write, with bytes between the previous end and the start of - /// the write set to zero. - /// - /// In the future, this may change to take a `stream`. - /// - /// Note: This is similar to `pwrite` in POSIX. - @since(version = 0.2.0) - write: func( - /// Data to write - buffer: list, - /// The offset within the file at which to write. - offset: filesize, - ) -> result; - /// Read directory entries from a directory. /// /// On filesystems where directories contain entries referring to themselves @@ -440,8 +411,11 @@ interface types { /// This always returns a new stream which starts at the beginning of the /// directory. Multiple streams may be active on the same directory, and they /// do not interfere with each other. - @since(version = 0.2.0) - read-directory: func() -> result; + /// + /// This function returns a future, which will resolve to an error code if + /// reading full contents of the directory fails. + @since(version = 0.3.0) + read-directory: func() -> tuple, future>>; /// Synchronize the data and metadata of a file to disk. /// @@ -449,13 +423,13 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - @since(version = 0.2.0) + @since(version = 0.3.0) sync: func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. - @since(version = 0.2.0) + @since(version = 0.3.0) create-directory-at: func( /// The relative path at which to create the directory. path: string, @@ -470,7 +444,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - @since(version = 0.2.0) + @since(version = 0.3.0) stat: func() -> result; /// Return the attributes of a file or directory. @@ -480,7 +454,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. - @since(version = 0.2.0) + @since(version = 0.3.0) stat-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -494,7 +468,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. - @since(version = 0.2.0) + @since(version = 0.3.0) set-times-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -513,7 +487,7 @@ interface types { /// `error-code::not-permitted` if the old path is not a file. /// /// Note: This is similar to `linkat` in POSIX. - @since(version = 0.2.0) + @since(version = 0.3.0) link-at: func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, @@ -537,7 +511,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. - @since(version = 0.2.0) + @since(version = 0.3.0) open-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -555,7 +529,7 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. - @since(version = 0.2.0) + @since(version = 0.3.0) readlink-at: func( /// The relative path of the symbolic link from which to read. path: string, @@ -566,7 +540,7 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - @since(version = 0.2.0) + @since(version = 0.3.0) remove-directory-at: func( /// The relative path to a directory to remove. path: string, @@ -575,7 +549,7 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. - @since(version = 0.2.0) + @since(version = 0.3.0) rename-at: func( /// The relative source path of the file or directory to rename. old-path: string, @@ -591,7 +565,7 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. - @since(version = 0.2.0) + @since(version = 0.3.0) symlink-at: func( /// The contents of the symbolic link. old-path: string, @@ -603,7 +577,7 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - @since(version = 0.2.0) + @since(version = 0.3.0) unlink-file-at: func( /// The relative path to a file to unlink. path: string, @@ -615,7 +589,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - @since(version = 0.2.0) + @since(version = 0.3.0) is-same-object: func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred @@ -637,14 +611,14 @@ interface types { /// computed hash. /// /// However, none of these is required. - @since(version = 0.2.0) + @since(version = 0.3.0) metadata-hash: func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. - @since(version = 0.2.0) + @since(version = 0.3.0) metadata-hash-at: func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -652,25 +626,4 @@ interface types { path: string, ) -> result; } - - /// A stream of directory entries. - @since(version = 0.2.0) - resource directory-entry-stream { - /// Read a single directory entry from a `directory-entry-stream`. - @since(version = 0.2.0) - read-directory-entry: func() -> result, error-code>; - } - - /// Attempts to extract a filesystem-related `error-code` from the stream - /// `error` provided. - /// - /// Stream operations which return `stream-error::last-operation-failed` - /// have a payload with more information about the operation that failed. - /// This payload can be passed through to this function to see if there's - /// filesystem-related information about the error to return. - /// - /// Note that this function is fallible because not all stream-related - /// errors are filesystem-related errors. - @since(version = 0.2.0) - filesystem-error-code: func(err: borrow) -> option; } diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit index 7742ed6bb..c0ab32afe 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit @@ -1,9 +1,9 @@ -package wasi:filesystem@0.2.4; +package wasi:filesystem@0.3.0; -@since(version = 0.2.0) +@since(version = 0.3.0) world imports { - @since(version = 0.2.0) + @since(version = 0.3.0) import types; - @since(version = 0.2.0) + @since(version = 0.3.0) import preopens; } diff --git a/proposals/http/wit-0.3.0-draft/deps/io/error.wit b/proposals/http/wit-0.3.0-draft/deps/io/error.wit deleted file mode 100644 index eb0600f9e..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/io/error.wit +++ /dev/null @@ -1,34 +0,0 @@ -package wasi:io@0.2.4; - -@since(version = 0.2.0) -interface error { - /// A resource which represents some error information. - /// - /// The only method provided by this resource is `to-debug-string`, - /// which provides some human-readable information about the error. - /// - /// In the `wasi:io` package, this resource is returned through the - /// `wasi:io/streams/stream-error` type. - /// - /// To provide more specific error information, other interfaces may - /// offer functions to "downcast" this error into more specific types. For example, - /// errors returned from streams derived from filesystem types can be described using - /// the filesystem's own error-code type. This is done using the function - /// `wasi:filesystem/types/filesystem-error-code`, which takes a `borrow` - /// parameter and returns an `option`. - /// - /// The set of functions which can "downcast" an `error` into a more - /// concrete type is open. - @since(version = 0.2.0) - resource error { - /// Returns a string that is suitable to assist humans in debugging - /// this error. - /// - /// WARNING: The returned string should not be consumed mechanically! - /// It may change across platforms, hosts, or other implementation - /// details. Parsing this string is a major platform-compatibility - /// hazard. - @since(version = 0.2.0) - to-debug-string: func() -> string; - } -} diff --git a/proposals/http/wit-0.3.0-draft/deps/io/poll.wit b/proposals/http/wit-0.3.0-draft/deps/io/poll.wit deleted file mode 100644 index 170deff70..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/io/poll.wit +++ /dev/null @@ -1,47 +0,0 @@ -package wasi:io@0.2.4; - -/// A poll API intended to let users wait for I/O events on multiple handles -/// at once. -@since(version = 0.2.0) -interface poll { - /// `pollable` represents a single I/O event which may be ready, or not. - @since(version = 0.2.0) - resource pollable { - - /// Return the readiness of a pollable. This function never blocks. - /// - /// Returns `true` when the pollable is ready, and `false` otherwise. - @since(version = 0.2.0) - ready: func() -> bool; - - /// `block` returns immediately if the pollable is ready, and otherwise - /// blocks until ready. - /// - /// This function is equivalent to calling `poll.poll` on a list - /// containing only this pollable. - @since(version = 0.2.0) - block: func(); - } - - /// Poll for completion on a set of pollables. - /// - /// This function takes a list of pollables, which identify I/O sources of - /// interest, and waits until one or more of the events is ready for I/O. - /// - /// The result `list` contains one or more indices of handles in the - /// argument list that is ready for I/O. - /// - /// This function traps if either: - /// - the list is empty, or: - /// - the list contains more elements than can be indexed with a `u32` value. - /// - /// A timeout can be implemented by adding a pollable from the - /// wasi-clocks API to the list. - /// - /// This function does not return a `result`; polling in itself does not - /// do any I/O so it doesn't fail. If any of the I/O sources identified by - /// the pollables has an error, it is indicated by marking the source as - /// being ready for I/O. - @since(version = 0.2.0) - poll: func(in: list>) -> list; -} diff --git a/proposals/http/wit-0.3.0-draft/deps/io/streams.wit b/proposals/http/wit-0.3.0-draft/deps/io/streams.wit deleted file mode 100644 index bb9a31e81..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/io/streams.wit +++ /dev/null @@ -1,290 +0,0 @@ -package wasi:io@0.2.4; - -/// WASI I/O is an I/O abstraction API which is currently focused on providing -/// stream types. -/// -/// In the future, the component model is expected to add built-in stream types; -/// when it does, they are expected to subsume this API. -@since(version = 0.2.0) -interface streams { - @since(version = 0.2.0) - use error.{error}; - @since(version = 0.2.0) - use poll.{pollable}; - - /// An error for input-stream and output-stream operations. - @since(version = 0.2.0) - variant stream-error { - /// The last operation (a write or flush) failed before completion. - /// - /// More information is available in the `error` payload. - /// - /// After this, the stream will be closed. All future operations return - /// `stream-error::closed`. - last-operation-failed(error), - /// The stream is closed: no more input will be accepted by the - /// stream. A closed output-stream will return this error on all - /// future operations. - closed - } - - /// An input bytestream. - /// - /// `input-stream`s are *non-blocking* to the extent practical on underlying - /// platforms. I/O operations always return promptly; if fewer bytes are - /// promptly available than requested, they return the number of bytes promptly - /// available, which could even be zero. To wait for data to be available, - /// use the `subscribe` function to obtain a `pollable` which can be polled - /// for using `wasi:io/poll`. - @since(version = 0.2.0) - resource input-stream { - /// Perform a non-blocking read from the stream. - /// - /// When the source of a `read` is binary data, the bytes from the source - /// are returned verbatim. When the source of a `read` is known to the - /// implementation to be text, bytes containing the UTF-8 encoding of the - /// text are returned. - /// - /// This function returns a list of bytes containing the read data, - /// when successful. The returned list will contain up to `len` bytes; - /// it may return fewer than requested, but not more. The list is - /// empty when no bytes are available for reading at this time. The - /// pollable given by `subscribe` will be ready when more bytes are - /// available. - /// - /// This function fails with a `stream-error` when the operation - /// encounters an error, giving `last-operation-failed`, or when the - /// stream is closed, giving `closed`. - /// - /// When the caller gives a `len` of 0, it represents a request to - /// read 0 bytes. If the stream is still open, this call should - /// succeed and return an empty list, or otherwise fail with `closed`. - /// - /// The `len` parameter is a `u64`, which could represent a list of u8 which - /// is not possible to allocate in wasm32, or not desirable to allocate as - /// as a return value by the callee. The callee may return a list of bytes - /// less than `len` in size while more bytes are available for reading. - @since(version = 0.2.0) - read: func( - /// The maximum number of bytes to read - len: u64 - ) -> result, stream-error>; - - /// Read bytes from a stream, after blocking until at least one byte can - /// be read. Except for blocking, behavior is identical to `read`. - @since(version = 0.2.0) - blocking-read: func( - /// The maximum number of bytes to read - len: u64 - ) -> result, stream-error>; - - /// Skip bytes from a stream. Returns number of bytes skipped. - /// - /// Behaves identical to `read`, except instead of returning a list - /// of bytes, returns the number of bytes consumed from the stream. - @since(version = 0.2.0) - skip: func( - /// The maximum number of bytes to skip. - len: u64, - ) -> result; - - /// Skip bytes from a stream, after blocking until at least one byte - /// can be skipped. Except for blocking behavior, identical to `skip`. - @since(version = 0.2.0) - blocking-skip: func( - /// The maximum number of bytes to skip. - len: u64, - ) -> result; - - /// Create a `pollable` which will resolve once either the specified stream - /// has bytes available to read or the other end of the stream has been - /// closed. - /// The created `pollable` is a child resource of the `input-stream`. - /// Implementations may trap if the `input-stream` is dropped before - /// all derived `pollable`s created with this function are dropped. - @since(version = 0.2.0) - subscribe: func() -> pollable; - } - - - /// An output bytestream. - /// - /// `output-stream`s are *non-blocking* to the extent practical on - /// underlying platforms. Except where specified otherwise, I/O operations also - /// always return promptly, after the number of bytes that can be written - /// promptly, which could even be zero. To wait for the stream to be ready to - /// accept data, the `subscribe` function to obtain a `pollable` which can be - /// polled for using `wasi:io/poll`. - /// - /// Dropping an `output-stream` while there's still an active write in - /// progress may result in the data being lost. Before dropping the stream, - /// be sure to fully flush your writes. - @since(version = 0.2.0) - resource output-stream { - /// Check readiness for writing. This function never blocks. - /// - /// Returns the number of bytes permitted for the next call to `write`, - /// or an error. Calling `write` with more bytes than this function has - /// permitted will trap. - /// - /// When this function returns 0 bytes, the `subscribe` pollable will - /// become ready when this function will report at least 1 byte, or an - /// error. - @since(version = 0.2.0) - check-write: func() -> result; - - /// Perform a write. This function never blocks. - /// - /// When the destination of a `write` is binary data, the bytes from - /// `contents` are written verbatim. When the destination of a `write` is - /// known to the implementation to be text, the bytes of `contents` are - /// transcoded from UTF-8 into the encoding of the destination and then - /// written. - /// - /// Precondition: check-write gave permit of Ok(n) and contents has a - /// length of less than or equal to n. Otherwise, this function will trap. - /// - /// returns Err(closed) without writing if the stream has closed since - /// the last call to check-write provided a permit. - @since(version = 0.2.0) - write: func( - contents: list - ) -> result<_, stream-error>; - - /// Perform a write of up to 4096 bytes, and then flush the stream. Block - /// until all of these operations are complete, or an error occurs. - /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write`, and `flush`, and is implemented with the - /// following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while !contents.is_empty() { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, contents.len()); - /// let (chunk, rest) = contents.split_at(len); - /// this.write(chunk ); // eliding error handling - /// contents = rest; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` - @since(version = 0.2.0) - blocking-write-and-flush: func( - contents: list - ) -> result<_, stream-error>; - - /// Request to flush buffered output. This function never blocks. - /// - /// This tells the output-stream that the caller intends any buffered - /// output to be flushed. the output which is expected to be flushed - /// is all that has been passed to `write` prior to this call. - /// - /// Upon calling this function, the `output-stream` will not accept any - /// writes (`check-write` will return `ok(0)`) until the flush has - /// completed. The `subscribe` pollable will become ready when the - /// flush has completed and the stream can accept more writes. - @since(version = 0.2.0) - flush: func() -> result<_, stream-error>; - - /// Request to flush buffered output, and block until flush completes - /// and stream is ready for writing again. - @since(version = 0.2.0) - blocking-flush: func() -> result<_, stream-error>; - - /// Create a `pollable` which will resolve once the output-stream - /// is ready for more writing, or an error has occurred. When this - /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an - /// error. - /// - /// If the stream is closed, this pollable is always ready immediately. - /// - /// The created `pollable` is a child resource of the `output-stream`. - /// Implementations may trap if the `output-stream` is dropped before - /// all derived `pollable`s created with this function are dropped. - @since(version = 0.2.0) - subscribe: func() -> pollable; - - /// Write zeroes to a stream. - /// - /// This should be used precisely like `write` with the exact same - /// preconditions (must use check-write first), but instead of - /// passing a list of bytes, you simply pass the number of zero-bytes - /// that should be written. - @since(version = 0.2.0) - write-zeroes: func( - /// The number of zero-bytes to write - len: u64 - ) -> result<_, stream-error>; - - /// Perform a write of up to 4096 zeroes, and then flush the stream. - /// Block until all of these operations are complete, or an error - /// occurs. - /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with - /// the following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while num_zeroes != 0 { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, num_zeroes); - /// this.write-zeroes(len); // eliding error handling - /// num_zeroes -= len; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` - @since(version = 0.2.0) - blocking-write-zeroes-and-flush: func( - /// The number of zero-bytes to write - len: u64 - ) -> result<_, stream-error>; - - /// Read from one stream and write to another. - /// - /// The behavior of splice is equivalent to: - /// 1. calling `check-write` on the `output-stream` - /// 2. calling `read` on the `input-stream` with the smaller of the - /// `check-write` permitted length and the `len` provided to `splice` - /// 3. calling `write` on the `output-stream` with that read data. - /// - /// Any error reported by the call to `check-write`, `read`, or - /// `write` ends the splice and reports that error. - /// - /// This function returns the number of bytes transferred; it may be less - /// than `len`. - @since(version = 0.2.0) - splice: func( - /// The stream to read from - src: borrow, - /// The number of bytes to splice - len: u64, - ) -> result; - - /// Read from one stream and write to another, with blocking. - /// - /// This is similar to `splice`, except that it blocks until the - /// `output-stream` is ready for writing, and the `input-stream` - /// is ready for reading, before performing the `splice`. - @since(version = 0.2.0) - blocking-splice: func( - /// The stream to read from - src: borrow, - /// The number of bytes to splice - len: u64, - ) -> result; - } -} diff --git a/proposals/http/wit-0.3.0-draft/deps/io/world.wit b/proposals/http/wit-0.3.0-draft/deps/io/world.wit deleted file mode 100644 index 8e0fa5c53..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/io/world.wit +++ /dev/null @@ -1,10 +0,0 @@ -package wasi:io@0.2.4; - -@since(version = 0.2.0) -world imports { - @since(version = 0.2.0) - import streams; - - @since(version = 0.2.0) - import poll; -} diff --git a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure-seed.wit b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure-seed.wit deleted file mode 100644 index 4708d9049..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure-seed.wit +++ /dev/null @@ -1,27 +0,0 @@ -package wasi:random@0.3.0; -/// The insecure-seed interface for seeding hash-map DoS resistance. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -@since(version = 0.3.0) -interface insecure-seed { - /// Return a 128-bit value that may contain a pseudo-random value. - /// - /// The returned value is not required to be computed from a CSPRNG, and may - /// even be entirely deterministic. Host implementations are encouraged to - /// provide pseudo-random values to any program exposed to - /// attacker-controlled content, to enable DoS protection built into many - /// languages' hash-map implementations. - /// - /// This function is intended to only be called once, by a source language - /// to initialize Denial Of Service (DoS) protection in its hash-map - /// implementation. - /// - /// # Expected future evolution - /// - /// This will likely be changed to a value import, to prevent it from being - /// called multiple times and potentially used for purposes other than DoS - /// protection. - @since(version = 0.3.0) - insecure-seed: func() -> tuple; -} diff --git a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure.wit b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure.wit deleted file mode 100644 index 4ea5e581f..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/insecure.wit +++ /dev/null @@ -1,25 +0,0 @@ -package wasi:random@0.3.0; -/// The insecure interface for insecure pseudo-random numbers. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -@since(version = 0.3.0) -interface insecure { - /// Return `len` insecure pseudo-random bytes. - /// - /// This function is not cryptographically secure. Do not use it for - /// anything related to security. - /// - /// There are no requirements on the values of the returned bytes, however - /// implementations are encouraged to return evenly distributed values with - /// a long period. - @since(version = 0.3.0) - get-insecure-random-bytes: func(len: u64) -> list; - - /// Return an insecure pseudo-random `u64` value. - /// - /// This function returns the same type of pseudo-random data as - /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0) - get-insecure-random-u64: func() -> u64; -} diff --git a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/random.wit b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/random.wit deleted file mode 100644 index 786ef25f6..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/random.wit +++ /dev/null @@ -1,29 +0,0 @@ -package wasi:random@0.3.0; -/// WASI Random is a random data API. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -@since(version = 0.3.0) -interface random { - /// Return `len` cryptographically-secure random or pseudo-random bytes. - /// - /// This function must produce data at least as cryptographically secure and - /// fast as an adequately seeded cryptographically-secure pseudo-random - /// number generator (CSPRNG). It must not block, from the perspective of - /// the calling program, under any circumstances, including on the first - /// request and on requests for numbers of bytes. The returned data must - /// always be unpredictable. - /// - /// This function must always return fresh data. Deterministic environments - /// must omit this function, rather than implementing it with deterministic - /// data. - @since(version = 0.3.0) - get-random-bytes: func(len: u64) -> list; - - /// Return a cryptographically-secure random or pseudo-random `u64` value. - /// - /// This function returns the same type of data as `get-random-bytes`, - /// represented as a `u64`. - @since(version = 0.3.0) - get-random-u64: func() -> u64; -} diff --git a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/world.wit b/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/world.wit deleted file mode 100644 index 838d38023..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/random-0-3-0/world.wit +++ /dev/null @@ -1,13 +0,0 @@ -package wasi:random@0.3.0; - -@since(version = 0.3.0) -world imports { - @since(version = 0.3.0) - import random; - - @since(version = 0.3.0) - import insecure; - - @since(version = 0.3.0) - import insecure-seed; -} diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit index 45e8bafdb..4708d9049 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit @@ -1,9 +1,9 @@ -package wasi:random@0.2.4; +package wasi:random@0.3.0; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.2.0) +@since(version = 0.3.0) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.2.0) + @since(version = 0.3.0) insecure-seed: func() -> tuple; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit index 5ab5030c5..4ea5e581f 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit @@ -1,9 +1,9 @@ -package wasi:random@0.2.4; +package wasi:random@0.3.0; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.2.0) +@since(version = 0.3.0) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.2.0) + @since(version = 0.3.0) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.2.0) + @since(version = 0.3.0) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/random.wit b/proposals/http/wit-0.3.0-draft/deps/random/random.wit index 9e5220d82..786ef25f6 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/random.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/random.wit @@ -1,9 +1,9 @@ -package wasi:random@0.2.4; +package wasi:random@0.3.0; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.2.0) +@since(version = 0.3.0) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.2.0) + @since(version = 0.3.0) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.2.0) + @since(version = 0.3.0) get-random-u64: func() -> u64; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/world.wit b/proposals/http/wit-0.3.0-draft/deps/random/world.wit index d89055819..838d38023 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/world.wit @@ -1,13 +1,13 @@ -package wasi:random@0.2.4; +package wasi:random@0.3.0; -@since(version = 0.2.0) +@since(version = 0.3.0) world imports { - @since(version = 0.2.0) + @since(version = 0.3.0) import random; - @since(version = 0.2.0) + @since(version = 0.3.0) import insecure; - @since(version = 0.2.0) + @since(version = 0.3.0) import insecure-seed; } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/instance-network.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/instance-network.wit deleted file mode 100644 index 5f6e6c1cc..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/instance-network.wit +++ /dev/null @@ -1,11 +0,0 @@ - -/// This interface provides a value-export of the default network handle.. -@since(version = 0.2.0) -interface instance-network { - @since(version = 0.2.0) - use network.{network}; - - /// Get a handle to the default network. - @since(version = 0.2.0) - instance-network: func() -> network; -} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit index 48b41a5b1..7cc8b03e3 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit @@ -1,9 +1,39 @@ -@since(version = 0.2.0) +@since(version = 0.3.0) interface ip-name-lookup { - @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; - @since(version = 0.2.0) - use network.{network, error-code, ip-address}; + @since(version = 0.3.0) + use types.{ip-address}; + + /// Lookup error codes. + @since(version = 0.3.0) + enum error-code { + /// Unknown error + unknown, + + /// Access denied. + /// + /// POSIX equivalent: EACCES, EPERM + access-denied, + + /// `name` is a syntactically invalid domain name or IP address. + /// + /// POSIX equivalent: EINVAL + invalid-argument, + + /// Name does not exist or has no suitable associated IP addresses. + /// + /// POSIX equivalent: EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY + name-unresolvable, + + /// A temporary failure in name resolution occurred. + /// + /// POSIX equivalent: EAI_AGAIN + temporary-resolver-failure, + + /// A permanent failure in name resolution occurred. + /// + /// POSIX equivalent: EAI_FAIL + permanent-resolver-failure, + } /// Resolve an internet host name to a list of IP addresses. /// @@ -13,44 +43,20 @@ interface ip-name-lookup { /// /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. /// - /// This function never blocks. It either immediately fails or immediately - /// returns successfully with a `resolve-address-stream` that can be used - /// to (asynchronously) fetch the results. + /// The results are returned in connection order preference. + /// + /// This function never succeeds with 0 results. It either fails or succeeds + /// with at least one address. Additionally, this function never returns + /// IPv4-mapped IPv6 addresses. /// - /// # Typical errors - /// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address. + /// The returned future will resolve to an error code in case of failure. + /// It will resolve to success once the returned stream is exhausted. /// /// # References: /// - /// - /// - /// - - @since(version = 0.2.0) - resolve-addresses: func(network: borrow, name: string) -> result; - - @since(version = 0.2.0) - resource resolve-address-stream { - /// Returns the next address from the resolver. - /// - /// This function should be called multiple times. On each call, it will - /// return the next address in connection order preference. If all - /// addresses have been exhausted, this function returns `none`. - /// - /// This function never returns IPv4-mapped IPv6 addresses. - /// - /// # Typical errors - /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) - /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) - /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) - /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) - @since(version = 0.2.0) - resolve-next-address: func() -> result, error-code>; - - /// Create a `pollable` which will resolve once the stream is ready for I/O. - /// - /// Note: this function is here for WASI 0.2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - @since(version = 0.2.0) - subscribe: func() -> pollable; - } + @since(version = 0.3.0) + resolve-addresses: func(name: string) -> result, error-code>; } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit deleted file mode 100644 index aa4985e14..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/network.wit +++ /dev/null @@ -1,169 +0,0 @@ -@since(version = 0.2.0) -interface network { - @unstable(feature = network-error-code) - use wasi:io/error@0.2.4.{error}; - - /// An opaque resource that represents access to (a subset of) the network. - /// This enables context-based security for networking. - /// There is no need for this to map 1:1 to a physical network interface. - @since(version = 0.2.0) - resource network; - - /// Error codes. - /// - /// In theory, every API can return any error code. - /// In practice, API's typically only return the errors documented per API - /// combined with a couple of errors that are always possible: - /// - `unknown` - /// - `access-denied` - /// - `not-supported` - /// - `out-of-memory` - /// - `concurrency-conflict` - /// - /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - @since(version = 0.2.0) - enum error-code { - /// Unknown error - unknown, - - /// Access denied. - /// - /// POSIX equivalent: EACCES, EPERM - access-denied, - - /// The operation is not supported. - /// - /// POSIX equivalent: EOPNOTSUPP - not-supported, - - /// One of the arguments is invalid. - /// - /// POSIX equivalent: EINVAL - invalid-argument, - - /// Not enough memory to complete the operation. - /// - /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY - out-of-memory, - - /// The operation timed out before it could finish completely. - timeout, - - /// This operation is incompatible with another asynchronous operation that is already in progress. - /// - /// POSIX equivalent: EALREADY - concurrency-conflict, - - /// Trying to finish an asynchronous operation that: - /// - has not been started yet, or: - /// - was already finished by a previous `finish-*` call. - /// - /// Note: this is scheduled to be removed when `future`s are natively supported. - not-in-progress, - - /// The operation has been aborted because it could not be completed immediately. - /// - /// Note: this is scheduled to be removed when `future`s are natively supported. - would-block, - - - /// The operation is not valid in the socket's current state. - invalid-state, - - /// A new socket resource could not be created because of a system limit. - new-socket-limit, - - /// A bind operation failed because the provided address is not an address that the `network` can bind to. - address-not-bindable, - - /// A bind operation failed because the provided address is already in use or because there are no ephemeral ports available. - address-in-use, - - /// The remote address is not reachable - remote-unreachable, - - - /// The TCP connection was forcefully rejected - connection-refused, - - /// The TCP connection was reset. - connection-reset, - - /// A TCP connection was aborted. - connection-aborted, - - - /// The size of a datagram sent to a UDP socket exceeded the maximum - /// supported size. - datagram-too-large, - - - /// Name does not exist or has no suitable associated IP addresses. - name-unresolvable, - - /// A temporary failure in name resolution occurred. - temporary-resolver-failure, - - /// A permanent failure in name resolution occurred. - permanent-resolver-failure, - } - - /// Attempts to extract a network-related `error-code` from the stream - /// `error` provided. - /// - /// Stream operations which return `stream-error::last-operation-failed` - /// have a payload with more information about the operation that failed. - /// This payload can be passed through to this function to see if there's - /// network-related information about the error to return. - /// - /// Note that this function is fallible because not all stream-related - /// errors are network-related errors. - @unstable(feature = network-error-code) - network-error-code: func(err: borrow) -> option; - - @since(version = 0.2.0) - enum ip-address-family { - /// Similar to `AF_INET` in POSIX. - ipv4, - - /// Similar to `AF_INET6` in POSIX. - ipv6, - } - - @since(version = 0.2.0) - type ipv4-address = tuple; - @since(version = 0.2.0) - type ipv6-address = tuple; - - @since(version = 0.2.0) - variant ip-address { - ipv4(ipv4-address), - ipv6(ipv6-address), - } - - @since(version = 0.2.0) - record ipv4-socket-address { - /// sin_port - port: u16, - /// sin_addr - address: ipv4-address, - } - - @since(version = 0.2.0) - record ipv6-socket-address { - /// sin6_port - port: u16, - /// sin6_flowinfo - flow-info: u32, - /// sin6_addr - address: ipv6-address, - /// sin6_scope_id - scope-id: u32, - } - - @since(version = 0.2.0) - variant ip-socket-address { - ipv4(ipv4-socket-address), - ipv6(ipv6-socket-address), - } -} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp-create-socket.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp-create-socket.wit deleted file mode 100644 index eedbd3076..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp-create-socket.wit +++ /dev/null @@ -1,30 +0,0 @@ -@since(version = 0.2.0) -interface tcp-create-socket { - @since(version = 0.2.0) - use network.{network, error-code, ip-address-family}; - @since(version = 0.2.0) - use tcp.{tcp-socket}; - - /// Create a new TCP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. - /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. - /// - /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` - /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// - /// # Typical errors - /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - create-tcp-socket: func(address-family: ip-address-family) -> result; -} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit deleted file mode 100644 index b3311332f..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/tcp.wit +++ /dev/null @@ -1,387 +0,0 @@ -@since(version = 0.2.0) -interface tcp { - @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{input-stream, output-stream}; - @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; - @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.4.{duration}; - @since(version = 0.2.0) - use network.{network, error-code, ip-socket-address, ip-address-family}; - - @since(version = 0.2.0) - enum shutdown-type { - /// Similar to `SHUT_RD` in POSIX. - receive, - - /// Similar to `SHUT_WR` in POSIX. - send, - - /// Similar to `SHUT_RDWR` in POSIX. - both, - } - - /// A TCP socket resource. - /// - /// The socket can be in one of the following states: - /// - `unbound` - /// - `bind-in-progress` - /// - `bound` (See note below) - /// - `listen-in-progress` - /// - `listening` - /// - `connect-in-progress` - /// - `connected` - /// - `closed` - /// See - /// for more information. - /// - /// Note: Except where explicitly mentioned, whenever this documentation uses - /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. - /// (i.e. `bound`, `listen-in-progress`, `listening`, `connect-in-progress` or `connected`) - /// - /// In addition to the general error codes documented on the - /// `network::error-code` type, TCP socket methods may always return - /// `error(invalid-state)` when in the `closed` state. - @since(version = 0.2.0) - resource tcp-socket { - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// Bind can be attempted multiple times on the same socket, even with - /// different arguments on each iteration. But never concurrently and - /// only as long as the previous bind failed. Once a bind succeeds, the - /// binding can't be changed anymore. - /// - /// # Typical errors - /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) - /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) - /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) - /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # Implementors note - /// When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT - /// state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR - /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior - /// and SO_REUSEADDR performs something different entirely. - /// - /// Unlike in POSIX, in WASI the bind operation is async. This enables - /// interactive WASI hosts to inject permission prompts. Runtimes that - /// don't want to make use of this ability can simply call the native - /// `bind` as part of either `start-bind` or `finish-bind`. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; - @since(version = 0.2.0) - finish-bind: func() -> result<_, error-code>; - - /// Connect to a remote endpoint. - /// - /// On success: - /// - the socket is transitioned into the `connected` state. - /// - a pair of streams is returned that can be used to read & write to the connection - /// - /// After a failed connection attempt, the socket will be in the `closed` - /// state and the only valid action left is to `drop` the socket. A single - /// socket can not be used to connect more than once. - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) - /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) - /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) - /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) - /// - `timeout`: Connection timed out. (ETIMEDOUT) - /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) - /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A connect operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # Implementors note - /// The POSIX equivalent of `start-connect` is the regular `connect` syscall. - /// Because all WASI sockets are non-blocking this is expected to return - /// EINPROGRESS, which should be translated to `ok()` in WASI. - /// - /// The POSIX equivalent of `finish-connect` is a `poll` for event `POLLOUT` - /// with a timeout of 0 on the socket descriptor. Followed by a check for - /// the `SO_ERROR` socket option, in case the poll signaled readiness. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; - @since(version = 0.2.0) - finish-connect: func() -> result, error-code>; - - /// Start listening for new connections. - /// - /// Transitions the socket into the `listening` state. - /// - /// Unlike POSIX, the socket must already be explicitly bound. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ) - /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) - /// - `invalid-state`: The socket is already in the `listening` state. - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - `not-in-progress`: A listen operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # Implementors note - /// Unlike in POSIX, in WASI the listen operation is async. This enables - /// interactive WASI hosts to inject permission prompts. Runtimes that - /// don't want to make use of this ability can simply call the native - /// `listen` as part of either `start-listen` or `finish-listen`. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - start-listen: func() -> result<_, error-code>; - @since(version = 0.2.0) - finish-listen: func() -> result<_, error-code>; - - /// Accept a new client socket. - /// - /// The returned socket is bound and in the `connected` state. The following properties are inherited from the listener socket: - /// - `address-family` - /// - `keep-alive-enabled` - /// - `keep-alive-idle-time` - /// - `keep-alive-interval` - /// - `keep-alive-count` - /// - `hop-limit` - /// - `receive-buffer-size` - /// - `send-buffer-size` - /// - /// On success, this function returns the newly accepted client socket along with - /// a pair of streams that can be used to read & write to the connection. - /// - /// # Typical errors - /// - `invalid-state`: Socket is not in the `listening` state. (EINVAL) - /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) - /// - `connection-aborted`: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - accept: func() -> result, error-code>; - - /// Get the bound local address. - /// - /// POSIX mentions: - /// > If the socket has not been bound to a local name, the value - /// > stored in the object pointed to by `address` is unspecified. - /// - /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - local-address: func() -> result; - - /// Get the remote address. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - remote-address: func() -> result; - - /// Whether the socket is in the `listening` state. - /// - /// Equivalent to the SO_ACCEPTCONN socket option. - @since(version = 0.2.0) - is-listening: func() -> bool; - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.2.0) - address-family: func() -> ip-address-family; - - /// Hints the desired listen queue size. Implementations are free to ignore this. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// - /// # Typical errors - /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. - /// - `invalid-argument`: (set) The provided value was 0. - /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. - @since(version = 0.2.0) - set-listen-backlog-size: func(value: u64) -> result<_, error-code>; - - /// Enables or disables keepalive. - /// - /// The keepalive behavior can be adjusted using: - /// - `keep-alive-idle-time` - /// - `keep-alive-interval` - /// - `keep-alive-count` - /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. - /// - /// Equivalent to the SO_KEEPALIVE socket option. - @since(version = 0.2.0) - keep-alive-enabled: func() -> result; - @since(version = 0.2.0) - set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; - - /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS) - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.2.0) - keep-alive-idle-time: func() -> result; - @since(version = 0.2.0) - set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; - - /// The time between keepalive packets. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the TCP_KEEPINTVL socket option. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.2.0) - keep-alive-interval: func() -> result; - @since(version = 0.2.0) - set-keep-alive-interval: func(value: duration) -> result<_, error-code>; - - /// The maximum amount of keepalive packets TCP should send before aborting the connection. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the TCP_KEEPCNT socket option. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.2.0) - keep-alive-count: func() -> result; - @since(version = 0.2.0) - set-keep-alive-count: func(value: u32) -> result<_, error-code>; - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.2.0) - hop-limit: func() -> result; - @since(version = 0.2.0) - set-hop-limit: func(value: u8) -> result<_, error-code>; - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.2.0) - receive-buffer-size: func() -> result; - @since(version = 0.2.0) - set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.2.0) - send-buffer-size: func() -> result; - @since(version = 0.2.0) - set-send-buffer-size: func(value: u64) -> result<_, error-code>; - - /// Create a `pollable` which can be used to poll for, or block on, - /// completion of any of the asynchronous operations of this socket. - /// - /// When `finish-bind`, `finish-listen`, `finish-connect` or `accept` - /// return `error(would-block)`, this pollable can be used to wait for - /// their success or failure, after which the method can be retried. - /// - /// The pollable is not limited to the async operation that happens to be - /// in progress at the time of calling `subscribe` (if any). Theoretically, - /// `subscribe` only has to be called once per socket and can then be - /// (re)used for the remainder of the socket's lifetime. - /// - /// See - /// for more information. - /// - /// Note: this function is here for WASI 0.2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - @since(version = 0.2.0) - subscribe: func() -> pollable; - - /// Initiate a graceful shutdown. - /// - /// - `receive`: The socket is not expecting to receive any data from - /// the peer. The `input-stream` associated with this socket will be - /// closed. Any data still in the receive queue at time of calling - /// this method will be discarded. - /// - `send`: The socket has no more data to send to the peer. The `output-stream` - /// associated with this socket will be closed and a FIN packet will be sent. - /// - `both`: Same effect as `receive` & `send` combined. - /// - /// This function is idempotent; shutting down a direction more than once - /// has no effect and returns `ok`. - /// - /// The shutdown function does not close (drop) the socket. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; - } -} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/types.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/types.wit new file mode 100644 index 000000000..b5f84d360 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/types.wit @@ -0,0 +1,726 @@ +@since(version = 0.3.0) +interface types { + @since(version = 0.3.0) + use wasi:clocks/monotonic-clock@0.3.0.{duration}; + + /// Error codes. + /// + /// In theory, every API can return any error code. + /// In practice, API's typically only return the errors documented per API + /// combined with a couple of errors that are always possible: + /// - `unknown` + /// - `access-denied` + /// - `not-supported` + /// - `out-of-memory` + /// + /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. + @since(version = 0.3.0) + enum error-code { + /// Unknown error + unknown, + + /// Access denied. + /// + /// POSIX equivalent: EACCES, EPERM + access-denied, + + /// The operation is not supported. + /// + /// POSIX equivalent: EOPNOTSUPP + not-supported, + + /// One of the arguments is invalid. + /// + /// POSIX equivalent: EINVAL + invalid-argument, + + /// Not enough memory to complete the operation. + /// + /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY + out-of-memory, + + /// The operation timed out before it could finish completely. + timeout, + + /// The operation is not valid in the socket's current state. + invalid-state, + + /// A bind operation failed because the provided address is not an address that the `network` can bind to. + address-not-bindable, + + /// A bind operation failed because the provided address is already in use or because there are no ephemeral ports available. + address-in-use, + + /// The remote address is not reachable + remote-unreachable, + + + /// The TCP connection was forcefully rejected + connection-refused, + + /// The TCP connection was reset. + connection-reset, + + /// A TCP connection was aborted. + connection-aborted, + + + /// The size of a datagram sent to a UDP socket exceeded the maximum + /// supported size. + datagram-too-large, + } + + @since(version = 0.3.0) + enum ip-address-family { + /// Similar to `AF_INET` in POSIX. + ipv4, + + /// Similar to `AF_INET6` in POSIX. + ipv6, + } + + @since(version = 0.3.0) + type ipv4-address = tuple; + @since(version = 0.3.0) + type ipv6-address = tuple; + + @since(version = 0.3.0) + variant ip-address { + ipv4(ipv4-address), + ipv6(ipv6-address), + } + + @since(version = 0.3.0) + record ipv4-socket-address { + /// sin_port + port: u16, + /// sin_addr + address: ipv4-address, + } + + @since(version = 0.3.0) + record ipv6-socket-address { + /// sin6_port + port: u16, + /// sin6_flowinfo + flow-info: u32, + /// sin6_addr + address: ipv6-address, + /// sin6_scope_id + scope-id: u32, + } + + @since(version = 0.3.0) + variant ip-socket-address { + ipv4(ipv4-socket-address), + ipv6(ipv6-socket-address), + } + + /// A TCP socket resource. + /// + /// The socket can be in one of the following states: + /// - `unbound` + /// - `bound` (See note below) + /// - `listening` + /// - `connecting` + /// - `connected` + /// - `closed` + /// See + /// for more information. + /// + /// Note: Except where explicitly mentioned, whenever this documentation uses + /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. + /// (i.e. `bound`, `listening`, `connecting` or `connected`) + /// + /// In addition to the general error codes documented on the + /// `types::error-code` type, TCP socket methods may always return + /// `error(invalid-state)` when in the `closed` state. + @since(version = 0.3.0) + resource tcp-socket { + + /// Create a new TCP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. + /// + /// Unlike POSIX, WASI sockets have no notion of a socket-level + /// `O_NONBLOCK` flag. Instead they fully rely on the Component Model's + /// async support. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + constructor(address-family: ip-address-family); + + /// Bind the socket to the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the TCP/UDP port is zero, the socket will be bound to a random free port. + /// + /// Bind can be attempted multiple times on the same socket, even with + /// different arguments on each iteration. But never concurrently and + /// only as long as the previous bind failed. Once a bind succeeds, the + /// binding can't be changed anymore. + /// + /// # Typical errors + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) + /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that can be bound to. (EADDRNOTAVAIL) + /// + /// # Implementors note + /// When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT + /// state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR + /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior + /// and SO_REUSEADDR performs something different entirely. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + bind: func(local-address: ip-socket-address) -> result<_, error-code>; + + /// Connect to a remote endpoint. + /// + /// On success, the socket is transitioned into the `connected` state and this function returns a connection resource. + /// + /// After a failed connection attempt, the socket will be in the `closed` + /// state and the only valid action left is to `drop` the socket. A single + /// socket can not be used to connect more than once. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) + /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) + /// - `invalid-state`: The socket is already in the `connecting` state. (EALREADY) + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) + /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) + /// - `timeout`: Connection timed out. (ETIMEDOUT) + /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + connect: func(remote-address: ip-socket-address) -> result<_, error-code>; + + /// Start listening return a stream of new inbound connections. + /// + /// Transitions the socket into the `listening` state. This can be called + /// at most once per socket. + /// + /// If the socket is not already explicitly bound, this function will + /// implicitly bind the socket to a random free port. + /// + /// Normally, the returned sockets are bound, in the `connected` state + /// and immediately ready for I/O. Though, depending on exact timing and + /// circumstances, a newly accepted connection may already be `closed` + /// by the time the server attempts to perform its first I/O on it. This + /// is true regardless of whether the WASI implementation uses + /// "synthesized" sockets or not (see Implementors Notes below). + /// + /// The following properties are inherited from the listener socket: + /// - `address-family` + /// - `keep-alive-enabled` + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// - `hop-limit` + /// - `receive-buffer-size` + /// - `send-buffer-size` + /// + /// # Typical errors + /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) + /// - `invalid-state`: The socket is already in the `listening` state. + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) + /// + /// # Implementors note + /// This method returns a single perpetual stream that should only close + /// on fatal errors (if any). Yet, the POSIX' `accept` function may also + /// return transient errors (e.g. ECONNABORTED). The exact details differ + /// per operation system. For example, the Linux manual mentions: + /// + /// > Linux accept() passes already-pending network errors on the new + /// > socket as an error code from accept(). This behavior differs from + /// > other BSD socket implementations. For reliable operation the + /// > application should detect the network errors defined for the + /// > protocol after accept() and treat them like EAGAIN by retrying. + /// > In the case of TCP/IP, these are ENETDOWN, EPROTO, ENOPROTOOPT, + /// > EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP, and ENETUNREACH. + /// Source: https://man7.org/linux/man-pages/man2/accept.2.html + /// + /// WASI implementations have two options to handle this: + /// - Optionally log it and then skip over non-fatal errors returned by + /// `accept`. Guest code never gets to see these failures. Or: + /// - Synthesize a `tcp-socket` resource that exposes the error when + /// attempting to send or receive on it. Guest code then sees these + /// failures as regular I/O errors. + /// + /// In either case, the stream returned by this `listen` method remains + /// operational. + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + listen: func() -> result, error-code>; + + /// Transmit data to peer. + /// + /// The caller should close the stream when it has no more data to send + /// to the peer. Under normal circumstances this will cause a FIN packet + /// to be sent out. Closing the stream is equivalent to calling + /// `shutdown(SHUT_WR)` in POSIX. + /// + /// This function may be called at most once and returns once the full + /// contents of the stream are transmitted or an error is encountered. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + send: func(data: stream) -> result<_, error-code>; + + /// Read data from peer. + /// + /// This function returns a `stream` which provides the data received from the + /// socket, and a `future` providing additional error information in case the + /// socket is closed abnormally. + /// + /// If the socket is closed normally, `stream.read` on the `stream` will return + /// `read-status::closed` with no `error-context` and the future resolves to + /// the value `ok`. If the socket is closed abnormally, `stream.read` on the + /// `stream` returns `read-status::closed` with an `error-context` and the future + /// resolves to `err` with an `error-code`. + /// + /// `receive` is meant to be called only once per socket. If it is called more + /// than once, the subsequent calls return a new `stream` that fails as if it + /// were closed abnormally. + /// + /// If the caller is not expecting to receive any data from the peer, + /// they may cancel the receive task. Any data still in the receive queue + /// will be discarded. This is equivalent to calling `shutdown(SHUT_RD)` + /// in POSIX. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) + /// - `connection-reset`: The connection was reset. (ECONNRESET) + /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + receive: func() -> tuple, future>>; + + /// Get the bound local address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + local-address: func() -> result; + + /// Get the remote address. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + remote-address: func() -> result; + + /// Whether the socket is in the `listening` state. + /// + /// Equivalent to the SO_ACCEPTCONN socket option. + @since(version = 0.3.0) + is-listening: func() -> bool; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// This is the value passed to the constructor. + /// + /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.3.0) + address-family: func() -> ip-address-family; + + /// Hints the desired listen queue size. Implementations are free to ignore this. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// + /// # Typical errors + /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. + /// - `invalid-argument`: (set) The provided value was 0. + /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. + @since(version = 0.3.0) + set-listen-backlog-size: func(value: u64) -> result<_, error-code>; + + /// Enables or disables keepalive. + /// + /// The keepalive behavior can be adjusted using: + /// - `keep-alive-idle-time` + /// - `keep-alive-interval` + /// - `keep-alive-count` + /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. + /// + /// Equivalent to the SO_KEEPALIVE socket option. + @since(version = 0.3.0) + keep-alive-enabled: func() -> result; + @since(version = 0.3.0) + set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; + + /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS) + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + keep-alive-idle-time: func() -> result; + @since(version = 0.3.0) + set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; + + /// The time between keepalive packets. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPINTVL socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + keep-alive-interval: func() -> result; + @since(version = 0.3.0) + set-keep-alive-interval: func(value: duration) -> result<_, error-code>; + + /// The maximum amount of keepalive packets TCP should send before aborting the connection. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the TCP_KEEPCNT socket option. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + keep-alive-count: func() -> result; + @since(version = 0.3.0) + set-keep-alive-count: func(value: u32) -> result<_, error-code>; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.3.0) + hop-limit: func() -> result; + @since(version = 0.3.0) + set-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + receive-buffer-size: func() -> result; + @since(version = 0.3.0) + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.3.0) + send-buffer-size: func() -> result; + @since(version = 0.3.0) + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + } + + /// A UDP socket handle. + @since(version = 0.3.0) + resource udp-socket { + + /// Create a new UDP socket. + /// + /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. + /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. + /// + /// Unlike POSIX, WASI sockets have no notion of a socket-level + /// `O_NONBLOCK` flag. Instead they fully rely on the Component Model's + /// async support. + /// + /// # References: + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + constructor(address-family: ip-address-family); + + /// Bind the socket to the provided IP address and port. + /// + /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which + /// network interface(s) to bind to. + /// If the port is zero, the socket will be bound to a random free port. + /// + /// # Typical errors + /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) + /// - `invalid-state`: The socket is already bound. (EINVAL) + /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) + /// - `address-in-use`: Address is already in use. (EADDRINUSE) + /// - `address-not-bindable`: `local-address` is not an address that can be bound to. (EADDRNOTAVAIL) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + bind: func(local-address: ip-socket-address) -> result<_, error-code>; + + /// Associate this socket with a specific peer address. + /// + /// On success, the `remote-address` of the socket is updated. + /// The `local-address` may be updated as well, based on the best network + /// path to `remote-address`. If the socket was not already explicitly + /// bound, this function will implicitly bind the socket to a random + /// free port. + /// + /// When a UDP socket is "connected", the `send` and `receive` methods + /// are limited to communicating with that peer only: + /// - `send` can only be used to send to this destination. + /// - `receive` will only return datagrams sent from the provided `remote-address`. + /// + /// The name "connect" was kept to align with the existing POSIX + /// terminology. Other than that, this function only changes the local + /// socket configuration and does not generate any network traffic. + /// The peer is not aware of this "connection". + /// + /// This method may be called multiple times on the same socket to change + /// its association, but only the most recent one will be effective. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) + /// + /// # Implementors note + /// If the socket is already connected, some platforms (e.g. Linux) + /// require a disconnect before connecting to a different peer address. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + connect: func(remote-address: ip-socket-address) -> result<_, error-code>; + + /// Dissociate this socket from its peer address. + /// + /// After calling this method, `send` & `receive` are free to communicate + /// with any address again. + /// + /// The POSIX equivalent of this is calling `connect` with an `AF_UNSPEC` address. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not connected. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + disconnect: func() -> result<_, error-code>; + + /// Send a message on the socket to a particular peer. + /// + /// If the socket is connected, the peer address may be left empty. In + /// that case this is equivalent to `send` in POSIX. Otherwise it is + /// equivalent to `sendto`. + /// + /// Additionally, if the socket is connected, a `remote-address` argument + /// _may_ be provided but then it must be identical to the address + /// passed to `connect`. + /// + /// Implementations may trap if the `data` length exceeds 64 KiB. + /// + /// # Typical errors + /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) + /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) + /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `connect`. (EISCONN) + /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) + /// - `invalid-state`: The socket has not been bound yet. + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + send: func(data: list, remote-address: option) -> result<_, error-code>; + + /// Receive a message on the socket. + /// + /// On success, the return value contains a tuple of the received data + /// and the address of the sender. Theoretical maximum length of the + /// data is 64 KiB. Though in practice, it will typically be less than + /// 1500 bytes. + /// + /// If the socket is connected, the sender address is guaranteed to + /// match the remote address passed to `connect`. + /// + /// # Typical errors + /// - `invalid-state`: The socket has not been bound yet. + /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) + /// - `connection-refused`: The connection was refused. (ECONNREFUSED) + /// + /// # References + /// - + /// - + /// - + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + receive: func() -> result, ip-socket-address>, error-code>; + + /// Get the current bound address. + /// + /// POSIX mentions: + /// > If the socket has not been bound to a local name, the value + /// > stored in the object pointed to by `address` is unspecified. + /// + /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not bound to any local address. + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + local-address: func() -> result; + + /// Get the address the socket is currently "connected" to. + /// + /// # Typical errors + /// - `invalid-state`: The socket is not "connected" to a specific remote address. (ENOTCONN) + /// + /// # References + /// - + /// - + /// - + /// - + @since(version = 0.3.0) + remote-address: func() -> result; + + /// Whether this is a IPv4 or IPv6 socket. + /// + /// This is the value passed to the constructor. + /// + /// Equivalent to the SO_DOMAIN socket option. + @since(version = 0.3.0) + address-family: func() -> ip-address-family; + + /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The TTL value must be 1 or higher. + @since(version = 0.3.0) + unicast-hop-limit: func() -> result; + @since(version = 0.3.0) + set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; + + /// The kernel buffer space reserved for sends/receives on this socket. + /// + /// If the provided value is 0, an `invalid-argument` error is returned. + /// Any other value will never cause an error, but it might be silently clamped and/or rounded. + /// I.e. after setting a value, reading the same setting back may return a different value. + /// + /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. + /// + /// # Typical errors + /// - `invalid-argument`: (set) The provided value was 0. + @since(version = 0.3.0) + receive-buffer-size: func() -> result; + @since(version = 0.3.0) + set-receive-buffer-size: func(value: u64) -> result<_, error-code>; + @since(version = 0.3.0) + send-buffer-size: func() -> result; + @since(version = 0.3.0) + set-send-buffer-size: func(value: u64) -> result<_, error-code>; + } +} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/udp-create-socket.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/udp-create-socket.wit deleted file mode 100644 index e8eeacbfe..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/udp-create-socket.wit +++ /dev/null @@ -1,30 +0,0 @@ -@since(version = 0.2.0) -interface udp-create-socket { - @since(version = 0.2.0) - use network.{network, error-code, ip-address-family}; - @since(version = 0.2.0) - use udp.{udp-socket}; - - /// Create a new UDP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. - /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. - /// - /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind` is called, - /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// - /// # Typical errors - /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References: - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - create-udp-socket: func(address-family: ip-address-family) -> result; -} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit deleted file mode 100644 index cfc07ba81..000000000 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/udp.wit +++ /dev/null @@ -1,288 +0,0 @@ -@since(version = 0.2.0) -interface udp { - @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; - @since(version = 0.2.0) - use network.{network, error-code, ip-socket-address, ip-address-family}; - - /// A received datagram. - @since(version = 0.2.0) - record incoming-datagram { - /// The payload. - /// - /// Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. - data: list, - - /// The source address. - /// - /// This field is guaranteed to match the remote address the stream was initialized with, if any. - /// - /// Equivalent to the `src_addr` out parameter of `recvfrom`. - remote-address: ip-socket-address, - } - - /// A datagram to be sent out. - @since(version = 0.2.0) - record outgoing-datagram { - /// The payload. - data: list, - - /// The destination address. - /// - /// The requirements on this field depend on how the stream was initialized: - /// - with a remote address: this field must be None or match the stream's remote address exactly. - /// - without a remote address: this field is required. - /// - /// If this value is None, the send operation is equivalent to `send` in POSIX. Otherwise it is equivalent to `sendto`. - remote-address: option, - } - - /// A UDP socket handle. - @since(version = 0.2.0) - resource udp-socket { - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the port is zero, the socket will be bound to a random free port. - /// - /// # Typical errors - /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) - /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # Implementors note - /// Unlike in POSIX, in WASI the bind operation is async. This enables - /// interactive WASI hosts to inject permission prompts. Runtimes that - /// don't want to make use of this ability can simply call the native - /// `bind` as part of either `start-bind` or `finish-bind`. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; - @since(version = 0.2.0) - finish-bind: func() -> result<_, error-code>; - - /// Set up inbound & outbound communication channels, optionally to a specific peer. - /// - /// This function only changes the local socket configuration and does not generate any network traffic. - /// On success, the `remote-address` of the socket is updated. The `local-address` may be updated as well, - /// based on the best network path to `remote-address`. - /// - /// When a `remote-address` is provided, the returned streams are limited to communicating with that specific peer: - /// - `send` can only be used to send to this destination. - /// - `receive` will only return datagrams sent from the provided `remote-address`. - /// - /// This method may be called multiple times on the same socket to change its association, but - /// only the most recently returned pair of streams will be operational. Implementations may trap if - /// the streams returned by a previous invocation haven't been dropped yet before calling `stream` again. - /// - /// The POSIX equivalent in pseudo-code is: - /// ```text - /// if (was previously connected) { - /// connect(s, AF_UNSPEC) - /// } - /// if (remote_address is Some) { - /// connect(s, remote_address) - /// } - /// ``` - /// - /// Unlike in POSIX, the socket must already be explicitly bound. - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-state`: The socket is not bound. - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `connection-refused`: The connection was refused. (ECONNREFUSED) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - %stream: func(remote-address: option) -> result, error-code>; - - /// Get the current bound address. - /// - /// POSIX mentions: - /// > If the socket has not been bound to a local name, the value - /// > stored in the object pointed to by `address` is unspecified. - /// - /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - local-address: func() -> result; - - /// Get the address the socket is currently streaming to. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not streaming to a specific remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - remote-address: func() -> result; - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.2.0) - address-family: func() -> ip-address-family; - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.2.0) - unicast-hop-limit: func() -> result; - @since(version = 0.2.0) - set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.2.0) - receive-buffer-size: func() -> result; - @since(version = 0.2.0) - set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.2.0) - send-buffer-size: func() -> result; - @since(version = 0.2.0) - set-send-buffer-size: func(value: u64) -> result<_, error-code>; - - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI 0.2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - @since(version = 0.2.0) - subscribe: func() -> pollable; - } - - @since(version = 0.2.0) - resource incoming-datagram-stream { - /// Receive messages on the socket. - /// - /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. - /// The returned list may contain fewer elements than requested, but never more. - /// - /// This function returns successfully with an empty list when either: - /// - `max-results` is 0, or: - /// - `max-results` is greater than 0, but no results are immediately available. - /// This function never returns `error(would-block)`. - /// - /// # Typical errors - /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `connection-refused`: The connection was refused. (ECONNREFUSED) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - receive: func(max-results: u64) -> result, error-code>; - - /// Create a `pollable` which will resolve once the stream is ready to receive again. - /// - /// Note: this function is here for WASI 0.2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - @since(version = 0.2.0) - subscribe: func() -> pollable; - } - - @since(version = 0.2.0) - resource outgoing-datagram-stream { - /// Check readiness for sending. This function never blocks. - /// - /// Returns the number of datagrams permitted for the next call to `send`, - /// or an error. Calling `send` with more datagrams than this function has - /// permitted will trap. - /// - /// When this function returns ok(0), the `subscribe` pollable will - /// become ready when this function will report at least ok(1), or an - /// error. - /// - /// Never returns `would-block`. - check-send: func() -> result; - - /// Send messages on the socket. - /// - /// This function attempts to send all provided `datagrams` on the socket without blocking and - /// returns how many messages were actually sent (or queued for sending). This function never - /// returns `error(would-block)`. If none of the datagrams were able to be sent, `ok(0)` is returned. - /// - /// This function semantically behaves the same as iterating the `datagrams` list and sequentially - /// sending each individual datagram until either the end of the list has been reached or the first error occurred. - /// If at least one datagram has been sent successfully, this function never returns an error. - /// - /// If the input list is empty, the function returns `ok(0)`. - /// - /// Each call to `send` must be permitted by a preceding `check-send`. Implementations must trap if - /// either `check-send` was not called or `datagrams` contains more items than `check-send` permitted. - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `stream`. (EISCONN) - /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `connection-refused`: The connection was refused. (ECONNREFUSED) - /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - @since(version = 0.2.0) - send: func(datagrams: list) -> result; - - /// Create a `pollable` which will resolve once the stream is ready to send again. - /// - /// Note: this function is here for WASI 0.2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - @since(version = 0.2.0) - subscribe: func() -> pollable; - } -} diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit index 82acdb9f0..6c9951d1c 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit @@ -1,19 +1,9 @@ -package wasi:sockets@0.2.4; +package wasi:sockets@0.3.0; -@since(version = 0.2.0) +@since(version = 0.3.0) world imports { - @since(version = 0.2.0) - import instance-network; - @since(version = 0.2.0) - import network; - @since(version = 0.2.0) - import udp; - @since(version = 0.2.0) - import udp-create-socket; - @since(version = 0.2.0) - import tcp; - @since(version = 0.2.0) - import tcp-create-socket; - @since(version = 0.2.0) + @since(version = 0.3.0) + import types; + @since(version = 0.3.0) import ip-name-lookup; } diff --git a/proposals/http/wit-0.3.0-draft/proxy.wit b/proposals/http/wit-0.3.0-draft/proxy.wit index e5f45a984..16688b96e 100644 --- a/proposals/http/wit-0.3.0-draft/proxy.wit +++ b/proposals/http/wit-0.3.0-draft/proxy.wit @@ -9,14 +9,14 @@ world imports { /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.2.4; - import wasi:cli/stderr@0.2.4; + import wasi:cli/stdout@0.3.0; + import wasi:cli/stderr@0.3.0; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. - import wasi:cli/stdin@0.2.4; + import wasi:cli/stdin@0.3.0; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). From c0f8c19c1987a312980df892d583fa380cebff78 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 12 Mar 2025 18:56:26 +0100 Subject: [PATCH 1647/1772] feat(p3): allow trailer retrieval to fail (#157) Signed-off-by: Roman Volosatovs --- proposals/http/wit-0.3.0-draft/types.wit | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index 31eb62add..3cbbe7bab 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -273,10 +273,10 @@ interface types { /// The returned future resolves to success if body is closed. %stream: func() -> result, future>>>; - /// Takes ownership of `body`, and returns an unresolved optional `trailers`. + /// Takes ownership of `body`, and returns an unresolved optional `trailers` result. /// /// This function will trap if a `stream` child is still alive. - finish: static func(this: body) -> future>; + finish: static func(this: body) -> future, error-code>>; } /// Represents an HTTP Request. From b2d02cd034fcdeda4de915f9bb84837449d120d1 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 12 Mar 2025 18:56:40 +0100 Subject: [PATCH 1648/1772] feat(p3): return owned `request-options` on consumption (#160) Signed-off-by: Roman Volosatovs --- proposals/http/wit-0.3.0-draft/types.wit | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index 3cbbe7bab..deec70bce 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -361,9 +361,9 @@ interface types { /// component by e.g. `handler.handle`. body: func() -> option; - /// Takes ownership of the `request` and returns the `headers` and `body`, - /// if any. - into-parts: static func(this: request) -> tuple>; + /// Takes ownership of the `request` and returns the `headers`, `body` + /// and `request-options`, if any. + into-parts: static func(this: request) -> tuple, option>; } /// Parameters for making an HTTP Request. Each of these parameters is From 53c4b877f71d7844337372f018435741a2a98360 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 14:29:31 +0200 Subject: [PATCH 1649/1772] Update to v0.2.5 (#108) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- proposals/io/imports.md | 12 ++++++------ proposals/io/wit/error.wit | 2 +- proposals/io/wit/poll.wit | 2 +- proposals/io/wit/streams.wit | 2 +- proposals/io/wit/world.wit | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index f888233ca..b1f5014f1 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -2,13 +2,13 @@ -

                      Import interface wasi:io/error@0.2.4

                      +

                      Import interface wasi:io/error@0.2.5


                      Types

                      resource error

                      @@ -41,7 +41,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/poll@0.2.4

                      +

                      Import interface wasi:io/poll@0.2.5

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -94,7 +94,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:io/streams@0.2.4

                      +

                      Import interface wasi:io/streams@0.2.5

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; diff --git a/proposals/io/wit/error.wit b/proposals/io/wit/error.wit index eb0600f9e..0e234bebd 100644 --- a/proposals/io/wit/error.wit +++ b/proposals/io/wit/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; @since(version = 0.2.0) interface error { diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index 170deff70..d33353e2a 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index bb9a31e81..8d20252f8 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index 8e0fa5c53..686418343 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; @since(version = 0.2.0) world imports { From 781426582153700a12543e02a10e1c62ce1147a1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 12:35:37 +0000 Subject: [PATCH 1650/1772] Update to v0.2.5 --- proposals/random/imports.md | 12 ++++++------ proposals/random/wit/insecure-seed.wit | 2 +- proposals/random/wit/insecure.wit | 2 +- proposals/random/wit/random.wit | 2 +- proposals/random/wit/world.wit | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/random/imports.md b/proposals/random/imports.md index 196e50bf1..b9b17cd91 100644 --- a/proposals/random/imports.md +++ b/proposals/random/imports.md @@ -2,13 +2,13 @@

                      -

                      Import interface wasi:random/random@0.2.4

                      +

                      Import interface wasi:random/random@0.2.5

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -41,7 +41,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:random/insecure@0.2.4

                      +

                      Import interface wasi:random/insecure@0.2.5

                      The insecure interface for insecure pseudo-random numbers.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -70,7 +70,7 @@ a long period.

                      • u64
                      -

                      Import interface wasi:random/insecure-seed@0.2.4

                      +

                      Import interface wasi:random/insecure-seed@0.2.5

                      The insecure-seed interface for seeding hash-map DoS resistance.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index 45e8bafdb..ab58b46c1 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.4; +package wasi:random@0.2.5; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index 5ab5030c5..f05130392 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.4; +package wasi:random@0.2.5; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 9e5220d82..6b751b031 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.4; +package wasi:random@0.2.5; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index d89055819..c32c48a96 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.4; +package wasi:random@0.2.5; @since(version = 0.2.0) world imports { From 5142c48ef025912d28c5d49a047ad8d0c6f5398e Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 3 Apr 2025 13:38:20 +0100 Subject: [PATCH 1651/1772] ci: render all-features (#83) Future-proofing for later feature additions --- proposals/clocks/.github/workflows/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 2b0fc356f..1d3021fdf 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -18,7 +18,7 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v22 + - uses: WebAssembly/wit-abi-up-to-date@v23 with: - features: clocks-timezone - wit-bindgen: '0.33.0' + wit-bindgen: '0.37.0' + all-features: 'true' \ No newline at end of file From 0a9b965afcbf3c9f26b78d5d32c2d112672a3701 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 14:39:10 +0200 Subject: [PATCH 1652/1772] Update to v0.2.5 (#85) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- proposals/clocks/imports.md | 16 ++++++++-------- proposals/clocks/wit/deps.lock | 4 ++-- proposals/clocks/wit/deps/io/error.wit | 2 +- proposals/clocks/wit/deps/io/poll.wit | 2 +- proposals/clocks/wit/deps/io/streams.wit | 2 +- proposals/clocks/wit/deps/io/world.wit | 2 +- proposals/clocks/wit/monotonic-clock.wit | 4 ++-- proposals/clocks/wit/timezone.wit | 2 +- proposals/clocks/wit/wall-clock.wit | 2 +- proposals/clocks/wit/world.wit | 2 +- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index 006a2b32e..a7ec83703 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -2,14 +2,14 @@ -

                      Import interface wasi:io/poll@0.2.4

                      +

                      Import interface wasi:io/poll@0.2.5

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -62,7 +62,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.4

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.5

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -121,7 +121,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.4

                      +

                      Import interface wasi:clocks/wall-clock@0.2.5

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -162,7 +162,7 @@ also known as Unix Time.
                    154. datetime
                    155. -

                      Import interface wasi:clocks/timezone@0.2.4

                      +

                      Import interface wasi:clocks/timezone@0.2.5


                      Types

                      type datetime

                      diff --git a/proposals/clocks/wit/deps.lock b/proposals/clocks/wit/deps.lock index 4f895ac79..53e7b56f7 100644 --- a/proposals/clocks/wit/deps.lock +++ b/proposals/clocks/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "770a73d479cda8e4c4064dd4006d2654ebcc358952079d74e41af27cf26bddbf" -sha512 = "b790f9750ac6782d9aaaa379845600b66dbde14ecee42f159c29796447eb8e61ee61f3b306e92622993b5e25298834b6ff62d7d9a04f8f18c05f07eda8f47ae0" +sha256 = "749de54c05f7118dc118999ad69c5b63890ea1dd86f1be69270062195c7b79c2" +sha512 = "b5096d518a7931c100594b9216bb4a98cd64533166bc7fdbb7465b48effc345863bd3ce2ec84fef59b273bae507edab08ec08975d56240ccef68f2494964e80a" diff --git a/proposals/clocks/wit/deps/io/error.wit b/proposals/clocks/wit/deps/io/error.wit index eb0600f9e..0e234bebd 100644 --- a/proposals/clocks/wit/deps/io/error.wit +++ b/proposals/clocks/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; @since(version = 0.2.0) interface error { diff --git a/proposals/clocks/wit/deps/io/poll.wit b/proposals/clocks/wit/deps/io/poll.wit index 170deff70..d33353e2a 100644 --- a/proposals/clocks/wit/deps/io/poll.wit +++ b/proposals/clocks/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/clocks/wit/deps/io/streams.wit b/proposals/clocks/wit/deps/io/streams.wit index bb9a31e81..8d20252f8 100644 --- a/proposals/clocks/wit/deps/io/streams.wit +++ b/proposals/clocks/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/clocks/wit/deps/io/world.wit b/proposals/clocks/wit/deps/io/world.wit index 8e0fa5c53..686418343 100644 --- a/proposals/clocks/wit/deps/io/world.wit +++ b/proposals/clocks/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index 175f8fe2d..731e8a1e0 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.4; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/clocks/wit/timezone.wit b/proposals/clocks/wit/timezone.wit index 658cb17e7..ebe21a6e8 100644 --- a/proposals/clocks/wit/timezone.wit +++ b/proposals/clocks/wit/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/clocks/wit/wall-clock.wit b/proposals/clocks/wit/wall-clock.wit index f826cd1e0..2fde831bd 100644 --- a/proposals/clocks/wit/wall-clock.wit +++ b/proposals/clocks/wit/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index 9e2087447..f32eed546 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; @since(version = 0.2.0) world imports { From 786af22991b63d35c80942e4e76a445a3779f386 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 12:49:03 +0000 Subject: [PATCH 1653/1772] Update to v0.2.5 --- proposals/filesystem/imports.md | 24 +++++++++---------- proposals/filesystem/wit/deps.lock | 8 +++---- .../wit/deps/clocks/monotonic-clock.wit | 4 ++-- .../filesystem/wit/deps/clocks/timezone.wit | 2 +- .../filesystem/wit/deps/clocks/wall-clock.wit | 2 +- .../filesystem/wit/deps/clocks/world.wit | 2 +- proposals/filesystem/wit/deps/io/error.wit | 2 +- proposals/filesystem/wit/deps/io/poll.wit | 2 +- proposals/filesystem/wit/deps/io/streams.wit | 2 +- proposals/filesystem/wit/deps/io/world.wit | 2 +- proposals/filesystem/wit/preopens.wit | 2 +- proposals/filesystem/wit/types.wit | 6 ++--- proposals/filesystem/wit/world.wit | 2 +- 13 files changed, 30 insertions(+), 30 deletions(-) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index e0e88e386..ca0c6c906 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -2,16 +2,16 @@ -

                      Import interface wasi:io/error@0.2.4

                      +

                      Import interface wasi:io/error@0.2.5


                      Types

                      resource error

                      @@ -44,7 +44,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/poll@0.2.4

                      +

                      Import interface wasi:io/poll@0.2.5

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -97,7 +97,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:io/streams@0.2.4

                      +

                      Import interface wasi:io/streams@0.2.5

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -427,7 +427,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.4

                      +

                      Import interface wasi:clocks/wall-clock@0.2.5

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -468,7 +468,7 @@ also known as Unix Time.
                    156. datetime
                    157. -

                      Import interface wasi:filesystem/types@0.2.4

                      +

                      Import interface wasi:filesystem/types@0.2.5

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                      @@ -1346,7 +1346,7 @@ errors are filesystem-related errors.

                      -

                      Import interface wasi:filesystem/preopens@0.2.4

                      +

                      Import interface wasi:filesystem/preopens@0.2.5


                      Types

                      type descriptor

                      diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index f9154882f..333ff3a78 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "fc36267c5098ad9ac6455396b27c8ef206ca23cae74f40bd44c57be68e7849b6" -sha512 = "0deed3d3a86f284adda7991cd24c0c4aab806ba2e0cb111da80d7f99c05f10793a602b28451407cad58ab762997f60c0f6d173e919e4a0988773b455d3a410d3" +sha256 = "f1c53079469e20167e2cd4300651f13f34a6fd508b5c7331bb7c8c95fb8857fb" +sha512 = "2a9281d0edcabad3bfef0dcfa7a9712d6beb6d6bb07b29fbf24235706d149672901ffc32192404a1ac511c512eb775daf9716ad3a0514bdf6a5c93a5fed19450" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "770a73d479cda8e4c4064dd4006d2654ebcc358952079d74e41af27cf26bddbf" -sha512 = "b790f9750ac6782d9aaaa379845600b66dbde14ecee42f159c29796447eb8e61ee61f3b306e92622993b5e25298834b6ff62d7d9a04f8f18c05f07eda8f47ae0" +sha256 = "749de54c05f7118dc118999ad69c5b63890ea1dd86f1be69270062195c7b79c2" +sha512 = "b5096d518a7931c100594b9216bb4a98cd64533166bc7fdbb7465b48effc345863bd3ce2ec84fef59b273bae507edab08ec08975d56240ccef68f2494964e80a" diff --git a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit index 175f8fe2d..731e8a1e0 100644 --- a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.4; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/filesystem/wit/deps/clocks/timezone.wit b/proposals/filesystem/wit/deps/clocks/timezone.wit index 658cb17e7..ebe21a6e8 100644 --- a/proposals/filesystem/wit/deps/clocks/timezone.wit +++ b/proposals/filesystem/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/filesystem/wit/deps/clocks/wall-clock.wit b/proposals/filesystem/wit/deps/clocks/wall-clock.wit index f826cd1e0..2fde831bd 100644 --- a/proposals/filesystem/wit/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/filesystem/wit/deps/clocks/world.wit b/proposals/filesystem/wit/deps/clocks/world.wit index 9e2087447..f32eed546 100644 --- a/proposals/filesystem/wit/deps/clocks/world.wit +++ b/proposals/filesystem/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/filesystem/wit/deps/io/error.wit b/proposals/filesystem/wit/deps/io/error.wit index eb0600f9e..0e234bebd 100644 --- a/proposals/filesystem/wit/deps/io/error.wit +++ b/proposals/filesystem/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; @since(version = 0.2.0) interface error { diff --git a/proposals/filesystem/wit/deps/io/poll.wit b/proposals/filesystem/wit/deps/io/poll.wit index 170deff70..d33353e2a 100644 --- a/proposals/filesystem/wit/deps/io/poll.wit +++ b/proposals/filesystem/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index bb9a31e81..8d20252f8 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/filesystem/wit/deps/io/world.wit b/proposals/filesystem/wit/deps/io/world.wit index 8e0fa5c53..686418343 100644 --- a/proposals/filesystem/wit/deps/io/world.wit +++ b/proposals/filesystem/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit index 6e6003954..0a9b8f054 100644 --- a/proposals/filesystem/wit/preopens.wit +++ b/proposals/filesystem/wit/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.4; +package wasi:filesystem@0.2.5; @since(version = 0.2.0) interface preopens { diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 962cadfef..2b67884fb 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.4; +package wasi:filesystem@0.2.5; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.4; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.5.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.4.{datetime}; + use wasi:clocks/wall-clock@0.2.5.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index 7742ed6bb..e7654ee77 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.4; +package wasi:filesystem@0.2.5; @since(version = 0.2.0) world imports { From bf6c212060ee5005edb299757b46f3d70cdada58 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 12:52:12 +0000 Subject: [PATCH 1654/1772] Update to v0.2.5 --- proposals/sockets/imports.md | 44 +++++++++---------- proposals/sockets/wit/deps.lock | 8 ++-- .../wit/deps/clocks/monotonic-clock.wit | 4 +- .../sockets/wit/deps/clocks/timezone.wit | 2 +- .../sockets/wit/deps/clocks/wall-clock.wit | 2 +- proposals/sockets/wit/deps/clocks/world.wit | 2 +- proposals/sockets/wit/deps/io/error.wit | 2 +- proposals/sockets/wit/deps/io/poll.wit | 2 +- proposals/sockets/wit/deps/io/streams.wit | 2 +- proposals/sockets/wit/deps/io/world.wit | 2 +- proposals/sockets/wit/ip-name-lookup.wit | 2 +- proposals/sockets/wit/network.wit | 2 +- proposals/sockets/wit/tcp.wit | 6 +-- proposals/sockets/wit/udp.wit | 2 +- proposals/sockets/wit/world.wit | 2 +- 15 files changed, 42 insertions(+), 42 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 5a5645303..1f0154819 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -2,21 +2,21 @@ -

                      Import interface wasi:io/error@0.2.4

                      +

                      Import interface wasi:io/error@0.2.5


                      Types

                      resource error

                      @@ -49,7 +49,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:sockets/network@0.2.4

                      +

                      Import interface wasi:sockets/network@0.2.5


                      Types

                      type error

                      @@ -264,7 +264,7 @@ errors are network-related errors.

                      -

                      Import interface wasi:sockets/instance-network@0.2.4

                      +

                      Import interface wasi:sockets/instance-network@0.2.5

                      This interface provides a value-export of the default network handle..


                      Types

                      @@ -279,7 +279,7 @@ errors are network-related errors.

                      -

                      Import interface wasi:io/poll@0.2.4

                      +

                      Import interface wasi:io/poll@0.2.5

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -332,7 +332,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:sockets/udp@0.2.4

                      +

                      Import interface wasi:sockets/udp@0.2.5


                      Types

                      type pollable

                      @@ -746,7 +746,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:sockets/udp-create-socket@0.2.4

                      +

                      Import interface wasi:sockets/udp-create-socket@0.2.5


                      Types

                      type network

                      @@ -791,7 +791,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                      Import interface wasi:io/streams@0.2.4

                      +

                      Import interface wasi:io/streams@0.2.5

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -1121,7 +1121,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.4

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.5

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -1180,7 +1180,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:sockets/tcp@0.2.4

                      +

                      Import interface wasi:sockets/tcp@0.2.5


                      Types

                      type input-stream

                      @@ -1771,7 +1771,7 @@ has no effect and returns ok.

                      -

                      Import interface wasi:sockets/tcp-create-socket@0.2.4

                      +

                      Import interface wasi:sockets/tcp-create-socket@0.2.5


                      Types

                      type network

                      @@ -1816,7 +1816,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                      Import interface wasi:sockets/ip-name-lookup@0.2.4

                      +

                      Import interface wasi:sockets/ip-name-lookup@0.2.5


                      Types

                      type pollable

                      diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index f9154882f..333ff3a78 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "fc36267c5098ad9ac6455396b27c8ef206ca23cae74f40bd44c57be68e7849b6" -sha512 = "0deed3d3a86f284adda7991cd24c0c4aab806ba2e0cb111da80d7f99c05f10793a602b28451407cad58ab762997f60c0f6d173e919e4a0988773b455d3a410d3" +sha256 = "f1c53079469e20167e2cd4300651f13f34a6fd508b5c7331bb7c8c95fb8857fb" +sha512 = "2a9281d0edcabad3bfef0dcfa7a9712d6beb6d6bb07b29fbf24235706d149672901ffc32192404a1ac511c512eb775daf9716ad3a0514bdf6a5c93a5fed19450" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "770a73d479cda8e4c4064dd4006d2654ebcc358952079d74e41af27cf26bddbf" -sha512 = "b790f9750ac6782d9aaaa379845600b66dbde14ecee42f159c29796447eb8e61ee61f3b306e92622993b5e25298834b6ff62d7d9a04f8f18c05f07eda8f47ae0" +sha256 = "749de54c05f7118dc118999ad69c5b63890ea1dd86f1be69270062195c7b79c2" +sha512 = "b5096d518a7931c100594b9216bb4a98cd64533166bc7fdbb7465b48effc345863bd3ce2ec84fef59b273bae507edab08ec08975d56240ccef68f2494964e80a" diff --git a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit index 175f8fe2d..731e8a1e0 100644 --- a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.4; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/sockets/wit/deps/clocks/timezone.wit b/proposals/sockets/wit/deps/clocks/timezone.wit index 658cb17e7..ebe21a6e8 100644 --- a/proposals/sockets/wit/deps/clocks/timezone.wit +++ b/proposals/sockets/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/sockets/wit/deps/clocks/wall-clock.wit b/proposals/sockets/wit/deps/clocks/wall-clock.wit index f826cd1e0..2fde831bd 100644 --- a/proposals/sockets/wit/deps/clocks/wall-clock.wit +++ b/proposals/sockets/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/sockets/wit/deps/clocks/world.wit b/proposals/sockets/wit/deps/clocks/world.wit index 9e2087447..f32eed546 100644 --- a/proposals/sockets/wit/deps/clocks/world.wit +++ b/proposals/sockets/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/sockets/wit/deps/io/error.wit b/proposals/sockets/wit/deps/io/error.wit index eb0600f9e..0e234bebd 100644 --- a/proposals/sockets/wit/deps/io/error.wit +++ b/proposals/sockets/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; @since(version = 0.2.0) interface error { diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit index 170deff70..d33353e2a 100644 --- a/proposals/sockets/wit/deps/io/poll.wit +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index bb9a31e81..8d20252f8 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit index 8e0fa5c53..686418343 100644 --- a/proposals/sockets/wit/deps/io/world.wit +++ b/proposals/sockets/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index 48b41a5b1..04ab05d1e 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index aa4985e14..52c830165 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.4.{error}; + use wasi:io/error@0.2.5.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index b3311332f..2f4478511 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{input-stream, output-stream}; + use wasi:io/streams@0.2.5.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.4.{duration}; + use wasi:clocks/monotonic-clock@0.2.5.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index cfc07ba81..9a73a4713 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index 82acdb9f0..733dc07b1 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.4; +package wasi:sockets@0.2.5; @since(version = 0.2.0) world imports { From 9fa10dee84b4accb6b3c8c14959db16cae2efdd5 Mon Sep 17 00:00:00 2001 From: Yosh Date: Thu, 3 Apr 2025 20:19:07 +0200 Subject: [PATCH 1655/1772] render all features on ci --- proposals/cli/.github/workflows/update.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/cli/.github/workflows/update.yml b/proposals/cli/.github/workflows/update.yml index 34ffe2fd9..e6ba2cd4f 100644 --- a/proposals/cli/.github/workflows/update.yml +++ b/proposals/cli/.github/workflows/update.yml @@ -45,9 +45,9 @@ jobs: - name: Upgrade wit deps run: wit-deps update - name: Generate markdown for the command world - run: wit-bindgen markdown wit -w command --html-in-md --features=cli-with-exit-code + run: wit-bindgen markdown wit -w command --html-in-md --all-features - name: Generate markdown for the imports world - run: wit-bindgen markdown wit -w imports --html-in-md --features=cli-with-exit-code + run: wit-bindgen markdown wit -w imports --html-in-md --all-features # file PR - name: Create feature branch From 00a4f79068d3f34861681f0038d8e274942287df Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 18:25:56 +0000 Subject: [PATCH 1656/1772] Update to v0.2.5 --- proposals/cli/command.md | 116 ++++++++--------- proposals/cli/imports.md | 118 +++++++++--------- proposals/cli/wit/command.wit | 2 +- proposals/cli/wit/deps.lock | 26 ++-- proposals/cli/wit/deps.toml | 6 +- .../cli/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/cli/wit/deps/clocks/timezone.wit | 2 +- proposals/cli/wit/deps/clocks/wall-clock.wit | 2 +- proposals/cli/wit/deps/clocks/world.wit | 2 +- .../cli/wit/deps/filesystem/preopens.wit | 2 +- proposals/cli/wit/deps/filesystem/types.wit | 6 +- proposals/cli/wit/deps/filesystem/world.wit | 2 +- proposals/cli/wit/deps/io/error.wit | 2 +- proposals/cli/wit/deps/io/poll.wit | 2 +- proposals/cli/wit/deps/io/streams.wit | 2 +- proposals/cli/wit/deps/io/world.wit | 2 +- .../cli/wit/deps/random/insecure-seed.wit | 2 +- proposals/cli/wit/deps/random/insecure.wit | 2 +- proposals/cli/wit/deps/random/random.wit | 2 +- proposals/cli/wit/deps/random/world.wit | 2 +- .../cli/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/cli/wit/deps/sockets/network.wit | 2 +- proposals/cli/wit/deps/sockets/tcp.wit | 6 +- proposals/cli/wit/deps/sockets/udp.wit | 2 +- proposals/cli/wit/deps/sockets/world.wit | 2 +- proposals/cli/wit/imports.wit | 12 +- proposals/cli/wit/stdio.wit | 6 +- 27 files changed, 168 insertions(+), 168 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index ee3d65058..e99fa9733 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -2,43 +2,43 @@ -

                      Import interface wasi:cli/environment@0.2.4

                      +

                      Import interface wasi:cli/environment@0.2.5


                      Functions

                      get-environment: func

                      @@ -65,7 +65,7 @@ directory, interpreting . as shorthand for this.

                      • option<string>
                      -

                      Import interface wasi:cli/exit@0.2.4

                      +

                      Import interface wasi:cli/exit@0.2.5


                      Functions

                      exit: func

                      @@ -85,7 +85,7 @@ without the connotation that something bad has happened.

                      • status-code: u8
                      -

                      Import interface wasi:io/error@0.2.4

                      +

                      Import interface wasi:io/error@0.2.5


                      Types

                      resource error

                      @@ -118,7 +118,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/poll@0.2.4

                      +

                      Import interface wasi:io/poll@0.2.5

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -171,7 +171,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:io/streams@0.2.4

                      +

                      Import interface wasi:io/streams@0.2.5

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -501,7 +501,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.4

                      +

                      Import interface wasi:cli/stdin@0.2.5


                      Types

                      type input-stream

                      @@ -514,7 +514,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.4

                      +

                      Import interface wasi:cli/stdout@0.2.5


                      Types

                      type output-stream

                      @@ -527,7 +527,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.4

                      +

                      Import interface wasi:cli/stderr@0.2.5


                      Types

                      type output-stream

                      @@ -540,7 +540,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/terminal-input@0.2.4

                      +

                      Import interface wasi:cli/terminal-input@0.2.5

                      Terminal input.

                      In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -549,7 +549,7 @@ immediately, querying supported features, and so on.

                      Types

                      resource terminal-input

                      The input side of a terminal.

                      -

                      Import interface wasi:cli/terminal-output@0.2.4

                      +

                      Import interface wasi:cli/terminal-output@0.2.5

                      Terminal output.

                      In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -558,7 +558,7 @@ features, and so on.

                      Types

                      resource terminal-output

                      The output side of a terminal.

                      -

                      Import interface wasi:cli/terminal-stdin@0.2.4

                      +

                      Import interface wasi:cli/terminal-stdin@0.2.5

                      An interface providing an optional terminal-input for stdin as a link-time authority.


                      @@ -575,7 +575,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stdout@0.2.4

                      +

                      Import interface wasi:cli/terminal-stdout@0.2.5

                      An interface providing an optional terminal-output for stdout as a link-time authority.


                      @@ -592,7 +592,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stderr@0.2.4

                      +

                      Import interface wasi:cli/terminal-stderr@0.2.5

                      An interface providing an optional terminal-output for stderr as a link-time authority.


                      @@ -609,7 +609,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.4

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.5

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -668,7 +668,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.4

                      +

                      Import interface wasi:clocks/wall-clock@0.2.5

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -709,7 +709,7 @@ also known as Unix Time.
                    158. datetime
                    159. -

                      Import interface wasi:clocks/timezone@0.2.4

                      +

                      Import interface wasi:clocks/timezone@0.2.5


                      Types

                      type datetime

                      @@ -774,7 +774,7 @@ saving time.

                      • s32
                      -

                      Import interface wasi:filesystem/types@0.2.4

                      +

                      Import interface wasi:filesystem/types@0.2.5

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                      @@ -1652,7 +1652,7 @@ errors are filesystem-related errors.

                      -

                      Import interface wasi:filesystem/preopens@0.2.4

                      +

                      Import interface wasi:filesystem/preopens@0.2.5


                      Types

                      type descriptor

                      @@ -1666,7 +1666,7 @@ errors are filesystem-related errors.

                      -

                      Import interface wasi:sockets/network@0.2.4

                      +

                      Import interface wasi:sockets/network@0.2.5


                      Types

                      type error

                      @@ -1881,7 +1881,7 @@ errors are network-related errors.

                      -

                      Import interface wasi:sockets/instance-network@0.2.4

                      +

                      Import interface wasi:sockets/instance-network@0.2.5

                      This interface provides a value-export of the default network handle..


                      Types

                      @@ -1896,7 +1896,7 @@ errors are network-related errors.

                      -

                      Import interface wasi:sockets/udp@0.2.4

                      +

                      Import interface wasi:sockets/udp@0.2.5


                      Types

                      type pollable

                      @@ -2310,7 +2310,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:sockets/udp-create-socket@0.2.4

                      +

                      Import interface wasi:sockets/udp-create-socket@0.2.5


                      Types

                      type network

                      @@ -2355,7 +2355,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                      Import interface wasi:sockets/tcp@0.2.4

                      +

                      Import interface wasi:sockets/tcp@0.2.5


                      Types

                      type input-stream

                      @@ -2946,7 +2946,7 @@ has no effect and returns ok.

                      -

                      Import interface wasi:sockets/tcp-create-socket@0.2.4

                      +

                      Import interface wasi:sockets/tcp-create-socket@0.2.5


                      Types

                      type network

                      @@ -2991,7 +2991,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                      Import interface wasi:sockets/ip-name-lookup@0.2.4

                      +

                      Import interface wasi:sockets/ip-name-lookup@0.2.5


                      Types

                      type pollable

                      @@ -3071,7 +3071,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:random/random@0.2.4

                      +

                      Import interface wasi:random/random@0.2.5

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3104,7 +3104,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:random/insecure@0.2.4

                      +

                      Import interface wasi:random/insecure@0.2.5

                      The insecure interface for insecure pseudo-random numbers.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3133,7 +3133,7 @@ a long period.

                      • u64
                      -

                      Import interface wasi:random/insecure-seed@0.2.4

                      +

                      Import interface wasi:random/insecure-seed@0.2.5

                      The insecure-seed interface for seeding hash-map DoS resistance.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3157,7 +3157,7 @@ protection.

                      • (u64, u64)
                      -

                      Export interface wasi:cli/run@0.2.4

                      +

                      Export interface wasi:cli/run@0.2.5


                      Functions

                      run: func

                      diff --git a/proposals/cli/imports.md b/proposals/cli/imports.md index 58c8d2995..f9252b062 100644 --- a/proposals/cli/imports.md +++ b/proposals/cli/imports.md @@ -2,38 +2,38 @@ -

                      Import interface wasi:cli/environment@0.2.4

                      +
                    160. interface wasi:cli/environment@0.2.5
                    161. +
                    162. interface wasi:cli/exit@0.2.5
                    163. +
                    164. interface wasi:io/error@0.2.5
                    165. +
                    166. interface wasi:io/poll@0.2.5
                    167. +
                    168. interface wasi:io/streams@0.2.5
                    169. +
                    170. interface wasi:cli/stdin@0.2.5
                    171. +
                    172. interface wasi:cli/stdout@0.2.5
                    173. +
                    174. interface wasi:cli/stderr@0.2.5
                    175. +
                    176. interface wasi:cli/terminal-input@0.2.5
                    177. +
                    178. interface wasi:cli/terminal-output@0.2.5
                    179. +
                    180. interface wasi:cli/terminal-stdin@0.2.5
                    181. +
                    182. interface wasi:cli/terminal-stdout@0.2.5
                    183. +
                    184. interface wasi:cli/terminal-stderr@0.2.5
                    185. +
                    186. interface wasi:clocks/monotonic-clock@0.2.5
                    187. +
                    188. interface wasi:clocks/wall-clock@0.2.5
                    189. +
                    190. interface wasi:clocks/timezone@0.2.5
                    191. +
                    192. interface wasi:filesystem/types@0.2.5
                    193. +
                    194. interface wasi:filesystem/preopens@0.2.5
                    195. +
                    196. interface wasi:sockets/network@0.2.5
                    197. +
                    198. interface wasi:sockets/instance-network@0.2.5
                    199. +
                    200. interface wasi:sockets/udp@0.2.5
                    201. +
                    202. interface wasi:sockets/udp-create-socket@0.2.5
                    203. +
                    204. interface wasi:sockets/tcp@0.2.5
                    205. +
                    206. interface wasi:sockets/tcp-create-socket@0.2.5
                    207. +
                    208. interface wasi:sockets/ip-name-lookup@0.2.5
                    209. +
                    210. interface wasi:random/random@0.2.5
                    211. +
                    212. interface wasi:random/insecure@0.2.5
                    213. +
                    214. interface wasi:random/insecure-seed@0.2.5
                    215. + + + +

                      Import interface wasi:cli/environment@0.2.5


                      Functions

                      get-environment: func

                      @@ -60,7 +60,7 @@ directory, interpreting . as shorthand for this.

                      • option<string>
                      -

                      Import interface wasi:cli/exit@0.2.4

                      +

                      Import interface wasi:cli/exit@0.2.5


                      Functions

                      exit: func

                      @@ -80,7 +80,7 @@ without the connotation that something bad has happened.

                      • status-code: u8
                      -

                      Import interface wasi:io/error@0.2.4

                      +

                      Import interface wasi:io/error@0.2.5


                      Types

                      resource error

                      @@ -113,7 +113,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/poll@0.2.4

                      +

                      Import interface wasi:io/poll@0.2.5

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -166,7 +166,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:io/streams@0.2.4

                      +

                      Import interface wasi:io/streams@0.2.5

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -496,7 +496,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.4

                      +

                      Import interface wasi:cli/stdin@0.2.5


                      Types

                      type input-stream

                      @@ -509,7 +509,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.4

                      +

                      Import interface wasi:cli/stdout@0.2.5


                      Types

                      type output-stream

                      @@ -522,7 +522,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.4

                      +

                      Import interface wasi:cli/stderr@0.2.5


                      Types

                      type output-stream

                      @@ -535,7 +535,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/terminal-input@0.2.4

                      +

                      Import interface wasi:cli/terminal-input@0.2.5

                      Terminal input.

                      In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -544,7 +544,7 @@ immediately, querying supported features, and so on.

                      Types

                      resource terminal-input

                      The input side of a terminal.

                      -

                      Import interface wasi:cli/terminal-output@0.2.4

                      +

                      Import interface wasi:cli/terminal-output@0.2.5

                      Terminal output.

                      In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -553,7 +553,7 @@ features, and so on.

                      Types

                      resource terminal-output

                      The output side of a terminal.

                      -

                      Import interface wasi:cli/terminal-stdin@0.2.4

                      +

                      Import interface wasi:cli/terminal-stdin@0.2.5

                      An interface providing an optional terminal-input for stdin as a link-time authority.


                      @@ -570,7 +570,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stdout@0.2.4

                      +

                      Import interface wasi:cli/terminal-stdout@0.2.5

                      An interface providing an optional terminal-output for stdout as a link-time authority.


                      @@ -587,7 +587,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stderr@0.2.4

                      +

                      Import interface wasi:cli/terminal-stderr@0.2.5

                      An interface providing an optional terminal-output for stderr as a link-time authority.


                      @@ -604,7 +604,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.4

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.5

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -663,7 +663,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.4

                      +

                      Import interface wasi:clocks/wall-clock@0.2.5

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -704,7 +704,7 @@ also known as Unix Time.
                    216. datetime
                    217. -

                      Import interface wasi:clocks/timezone@0.2.4

                      +

                      Import interface wasi:clocks/timezone@0.2.5


                      Types

                      type datetime

                      @@ -769,7 +769,7 @@ saving time.

                      • s32
                      -

                      Import interface wasi:filesystem/types@0.2.4

                      +

                      Import interface wasi:filesystem/types@0.2.5

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                      @@ -1647,7 +1647,7 @@ errors are filesystem-related errors.

                      -

                      Import interface wasi:filesystem/preopens@0.2.4

                      +

                      Import interface wasi:filesystem/preopens@0.2.5


                      Types

                      type descriptor

                      @@ -1661,7 +1661,7 @@ errors are filesystem-related errors.

                      -

                      Import interface wasi:sockets/network@0.2.4

                      +

                      Import interface wasi:sockets/network@0.2.5


                      Types

                      type error

                      @@ -1876,7 +1876,7 @@ errors are network-related errors.

                      -

                      Import interface wasi:sockets/instance-network@0.2.4

                      +

                      Import interface wasi:sockets/instance-network@0.2.5

                      This interface provides a value-export of the default network handle..


                      Types

                      @@ -1891,7 +1891,7 @@ errors are network-related errors.

                      -

                      Import interface wasi:sockets/udp@0.2.4

                      +

                      Import interface wasi:sockets/udp@0.2.5


                      Types

                      type pollable

                      @@ -2305,7 +2305,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:sockets/udp-create-socket@0.2.4

                      +

                      Import interface wasi:sockets/udp-create-socket@0.2.5


                      Types

                      type network

                      @@ -2350,7 +2350,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                      Import interface wasi:sockets/tcp@0.2.4

                      +

                      Import interface wasi:sockets/tcp@0.2.5


                      Types

                      type input-stream

                      @@ -2941,7 +2941,7 @@ has no effect and returns ok.

                      -

                      Import interface wasi:sockets/tcp-create-socket@0.2.4

                      +

                      Import interface wasi:sockets/tcp-create-socket@0.2.5


                      Types

                      type network

                      @@ -2986,7 +2986,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                      Import interface wasi:sockets/ip-name-lookup@0.2.4

                      +

                      Import interface wasi:sockets/ip-name-lookup@0.2.5


                      Types

                      type pollable

                      @@ -3066,7 +3066,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:random/random@0.2.4

                      +

                      Import interface wasi:random/random@0.2.5

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3099,7 +3099,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:random/insecure@0.2.4

                      +

                      Import interface wasi:random/insecure@0.2.5

                      The insecure interface for insecure pseudo-random numbers.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3128,7 +3128,7 @@ a long period.

                      • u64
                      -

                      Import interface wasi:random/insecure-seed@0.2.4

                      +

                      Import interface wasi:random/insecure-seed@0.2.5

                      The insecure-seed interface for seeding hash-map DoS resistance.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index 88ab2a97e..716539569 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.4; +package wasi:cli@0.2.5; @since(version = 0.2.0) world command { diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index e80ab8753..a1dc926b0 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,24 +1,24 @@ [clocks] -sha256 = "fc36267c5098ad9ac6455396b27c8ef206ca23cae74f40bd44c57be68e7849b6" -sha512 = "0deed3d3a86f284adda7991cd24c0c4aab806ba2e0cb111da80d7f99c05f10793a602b28451407cad58ab762997f60c0f6d173e919e4a0988773b455d3a410d3" +sha256 = "f1c53079469e20167e2cd4300651f13f34a6fd508b5c7331bb7c8c95fb8857fb" +sha512 = "2a9281d0edcabad3bfef0dcfa7a9712d6beb6d6bb07b29fbf24235706d149672901ffc32192404a1ac511c512eb775daf9716ad3a0514bdf6a5c93a5fed19450" [filesystem] -url = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.4.tar.gz" -sha256 = "dd435f78b23714bd9d51ef3789c43b831549e71f54b57394a41bbf0c4da45f42" -sha512 = "d58bcf6eae908a6b2d883bcdfe456dc31aa99c848d0b3d21f710bde5bbb59ec105dbd5085004eadd0faa938530e4c29f88e589f525c080eb6d5971775a0b64ed" +url = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.5.tar.gz" +sha256 = "9122d926d1e9c8c3c1aca0b54fcc6a64fe3b52b701d266af5ecbb7f83124a647" +sha512 = "a8e81ca42f4ff9d58dca945cabbcdf04b7a9870b7acd3bb95c95e40bb656e74c7e190f73cf0b3189b6b01a78f3aaa2e247c215541a7a0f67fb86ed3e0b3f9e35" deps = ["clocks", "io"] [io] -sha256 = "770a73d479cda8e4c4064dd4006d2654ebcc358952079d74e41af27cf26bddbf" -sha512 = "b790f9750ac6782d9aaaa379845600b66dbde14ecee42f159c29796447eb8e61ee61f3b306e92622993b5e25298834b6ff62d7d9a04f8f18c05f07eda8f47ae0" +sha256 = "749de54c05f7118dc118999ad69c5b63890ea1dd86f1be69270062195c7b79c2" +sha512 = "b5096d518a7931c100594b9216bb4a98cd64533166bc7fdbb7465b48effc345863bd3ce2ec84fef59b273bae507edab08ec08975d56240ccef68f2494964e80a" [random] -url = "https://github.com/WebAssembly/wasi-random/archive/v0.2.4.tar.gz" -sha256 = "876d81b0a777f1dc9db215fa36f45898a907188819185d6b189345f28c081a45" -sha512 = "fc6a0ed97e0525456222b28bcc49431bade826a97cb6eb52cde595908865d1ed7835c54a63b408ba82e3d49061aebb9a8725d1d2316d28c0ccb12af8ec968ab8" +url = "https://github.com/WebAssembly/wasi-random/archive/v0.2.5.tar.gz" +sha256 = "c59984d9385d1ef7af6dd817b3d7a0a7f4084baa66c92026d6f9bf1eaf29169a" +sha512 = "7414a1a0616e42ff134ad15b65d9e10bc3b567b34f7f696356e20bc71bcb85ea16188d26d1997ba7e6964df9493f9f748304acaf1169e16ee21a035d8a8b4a89" [sockets] -url = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.4.tar.gz" -sha256 = "e6872db116eb02f2043c4238999712de19bdb22e3c8da00af563f8b6c4dabb18" -sha512 = "28c05fe8acd691d808b6a90b950483bbf59983c02e91ed4a89b0e06c3e2a27e0f73be678979309553f0889fc3fea00c4740b007946d7285aa554dc65d56b1b7f" +url = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.5.tar.gz" +sha256 = "1e55b9b6aa43e02cc0a674e7e6250f5145d48ffbc60c0f200b5ea192dce61640" +sha512 = "019224bb6fead5b6b687aeba7505ed05ebf20b9a60d045a4ab4fc323d0044af729b983b44efbe7ac8e0efda727f5c779fb0ad817c7802b2d7677196cf2cc0652" deps = ["clocks", "io"] diff --git a/proposals/cli/wit/deps.toml b/proposals/cli/wit/deps.toml index 0b2cbed2b..26c0dbb5f 100644 --- a/proposals/cli/wit/deps.toml +++ b/proposals/cli/wit/deps.toml @@ -1,3 +1,3 @@ -filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.4.tar.gz" -random = "https://github.com/WebAssembly/wasi-random/archive/v0.2.4.tar.gz" -sockets = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.4.tar.gz" +filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.5.tar.gz" +random = "https://github.com/WebAssembly/wasi-random/archive/v0.2.5.tar.gz" +sockets = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.5.tar.gz" diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index 175f8fe2d..731e8a1e0 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.4; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/cli/wit/deps/clocks/timezone.wit b/proposals/cli/wit/deps/clocks/timezone.wit index 658cb17e7..ebe21a6e8 100644 --- a/proposals/cli/wit/deps/clocks/timezone.wit +++ b/proposals/cli/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit index f826cd1e0..2fde831bd 100644 --- a/proposals/cli/wit/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/cli/wit/deps/clocks/world.wit b/proposals/cli/wit/deps/clocks/world.wit index 9e2087447..f32eed546 100644 --- a/proposals/cli/wit/deps/clocks/world.wit +++ b/proposals/cli/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/filesystem/preopens.wit b/proposals/cli/wit/deps/filesystem/preopens.wit index 6e6003954..0a9b8f054 100644 --- a/proposals/cli/wit/deps/filesystem/preopens.wit +++ b/proposals/cli/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.4; +package wasi:filesystem@0.2.5; @since(version = 0.2.0) interface preopens { diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index 962cadfef..2b67884fb 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.4; +package wasi:filesystem@0.2.5; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.4; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.5.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.4.{datetime}; + use wasi:clocks/wall-clock@0.2.5.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit index 7742ed6bb..e7654ee77 100644 --- a/proposals/cli/wit/deps/filesystem/world.wit +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.4; +package wasi:filesystem@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/io/error.wit b/proposals/cli/wit/deps/io/error.wit index eb0600f9e..0e234bebd 100644 --- a/proposals/cli/wit/deps/io/error.wit +++ b/proposals/cli/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; @since(version = 0.2.0) interface error { diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit index 170deff70..d33353e2a 100644 --- a/proposals/cli/wit/deps/io/poll.wit +++ b/proposals/cli/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index bb9a31e81..8d20252f8 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/cli/wit/deps/io/world.wit b/proposals/cli/wit/deps/io/world.wit index 8e0fa5c53..686418343 100644 --- a/proposals/cli/wit/deps/io/world.wit +++ b/proposals/cli/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/random/insecure-seed.wit b/proposals/cli/wit/deps/random/insecure-seed.wit index 45e8bafdb..ab58b46c1 100644 --- a/proposals/cli/wit/deps/random/insecure-seed.wit +++ b/proposals/cli/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.4; +package wasi:random@0.2.5; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/insecure.wit b/proposals/cli/wit/deps/random/insecure.wit index 5ab5030c5..f05130392 100644 --- a/proposals/cli/wit/deps/random/insecure.wit +++ b/proposals/cli/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.4; +package wasi:random@0.2.5; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index 9e5220d82..6b751b031 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.4; +package wasi:random@0.2.5; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/world.wit b/proposals/cli/wit/deps/random/world.wit index d89055819..c32c48a96 100644 --- a/proposals/cli/wit/deps/random/world.wit +++ b/proposals/cli/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.4; +package wasi:random@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index 48b41a5b1..04ab05d1e 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit index aa4985e14..52c830165 100644 --- a/proposals/cli/wit/deps/sockets/network.wit +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.4.{error}; + use wasi:io/error@0.2.5.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index b3311332f..2f4478511 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{input-stream, output-stream}; + use wasi:io/streams@0.2.5.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.4.{duration}; + use wasi:clocks/monotonic-clock@0.2.5.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index cfc07ba81..9a73a4713 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit index 82acdb9f0..733dc07b1 100644 --- a/proposals/cli/wit/deps/sockets/world.wit +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.4; +package wasi:sockets@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/imports.wit b/proposals/cli/wit/imports.wit index ad5c6bb23..93a83742f 100644 --- a/proposals/cli/wit/imports.wit +++ b/proposals/cli/wit/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.4; +package wasi:cli@0.2.5; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.4; + include wasi:clocks/imports@0.2.5; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.4; + include wasi:filesystem/imports@0.2.5; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.4; + include wasi:sockets/imports@0.2.5; @since(version = 0.2.0) - include wasi:random/imports@0.2.4; + include wasi:random/imports@0.2.5; @since(version = 0.2.0) - include wasi:io/imports@0.2.4; + include wasi:io/imports@0.2.5; @since(version = 0.2.0) import environment; diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index 60727a930..19a5ab9da 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{input-stream}; + use wasi:io/streams@0.2.5.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{output-stream}; + use wasi:io/streams@0.2.5.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{output-stream}; + use wasi:io/streams@0.2.5.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; From 3a68dbeb7f006c7dd74f348c49223d85bcdb18dc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 18:29:01 +0000 Subject: [PATCH 1657/1772] Update to v0.2.5 --- proposals/http/imports.md | 44 ++++++++--------- proposals/http/proxy.md | 48 +++++++++---------- proposals/http/wit/deps.lock | 26 +++++----- proposals/http/wit/deps.toml | 2 +- proposals/http/wit/deps/cli/command.wit | 2 +- proposals/http/wit/deps/cli/imports.wit | 12 ++--- proposals/http/wit/deps/cli/stdio.wit | 6 +-- .../http/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/http/wit/deps/clocks/timezone.wit | 2 +- proposals/http/wit/deps/clocks/wall-clock.wit | 2 +- proposals/http/wit/deps/clocks/world.wit | 2 +- .../http/wit/deps/filesystem/preopens.wit | 2 +- proposals/http/wit/deps/filesystem/types.wit | 6 +-- proposals/http/wit/deps/filesystem/world.wit | 2 +- proposals/http/wit/deps/io/error.wit | 2 +- proposals/http/wit/deps/io/poll.wit | 2 +- proposals/http/wit/deps/io/streams.wit | 2 +- proposals/http/wit/deps/io/world.wit | 2 +- .../http/wit/deps/random/insecure-seed.wit | 2 +- proposals/http/wit/deps/random/insecure.wit | 2 +- proposals/http/wit/deps/random/random.wit | 2 +- proposals/http/wit/deps/random/world.wit | 2 +- .../http/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/http/wit/deps/sockets/network.wit | 2 +- proposals/http/wit/deps/sockets/tcp.wit | 6 +-- proposals/http/wit/deps/sockets/udp.wit | 2 +- proposals/http/wit/deps/sockets/world.wit | 2 +- proposals/http/wit/proxy.wit | 14 +++--- proposals/http/wit/types.wit | 8 ++-- 29 files changed, 106 insertions(+), 106 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index b3374320c..0bfacf439 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -4,21 +4,21 @@ It is intended to be included in other worlds.

                      -

                      Import interface wasi:io/poll@0.2.4

                      +

                      Import interface wasi:io/poll@0.2.5

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -71,7 +71,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.4

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.5

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -130,7 +130,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.4

                      +

                      Import interface wasi:clocks/wall-clock@0.2.5

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -171,7 +171,7 @@ also known as Unix Time.
                    218. datetime
                    219. -

                      Import interface wasi:random/random@0.2.4

                      +

                      Import interface wasi:random/random@0.2.5

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -204,7 +204,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:io/error@0.2.4

                      +

                      Import interface wasi:io/error@0.2.5


                      Types

                      resource error

                      @@ -237,7 +237,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/streams@0.2.4

                      +

                      Import interface wasi:io/streams@0.2.5

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -567,7 +567,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.4

                      +

                      Import interface wasi:cli/stdout@0.2.5


                      Types

                      type output-stream

                      @@ -580,7 +580,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.4

                      +

                      Import interface wasi:cli/stderr@0.2.5


                      Types

                      type output-stream

                      @@ -593,7 +593,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.4

                      +

                      Import interface wasi:cli/stdin@0.2.5


                      Types

                      type input-stream

                      @@ -606,7 +606,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:http/types@0.2.4

                      +

                      Import interface wasi:http/types@0.2.5

                      This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                      @@ -1526,7 +1526,7 @@ but those will be reported by the incoming-body
                    220. option<result<result<own<incoming-response>, error-code>>>
                    221. -

                      Import interface wasi:http/outgoing-handler@0.2.4

                      +

                      Import interface wasi:http/outgoing-handler@0.2.5

                      This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                      diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 07dcd3e0a..3c4d2340b 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -6,26 +6,26 @@ outgoing HTTP requests.

                      -

                      Import interface wasi:io/poll@0.2.4

                      +

                      Import interface wasi:io/poll@0.2.5

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -78,7 +78,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.4

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.5

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -137,7 +137,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.4

                      +

                      Import interface wasi:clocks/wall-clock@0.2.5

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -178,7 +178,7 @@ also known as Unix Time.
                    222. datetime
                    223. -

                      Import interface wasi:random/random@0.2.4

                      +

                      Import interface wasi:random/random@0.2.5

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -211,7 +211,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:io/error@0.2.4

                      +

                      Import interface wasi:io/error@0.2.5


                      Types

                      resource error

                      @@ -244,7 +244,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/streams@0.2.4

                      +

                      Import interface wasi:io/streams@0.2.5

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -574,7 +574,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.4

                      +

                      Import interface wasi:cli/stdout@0.2.5


                      Types

                      type output-stream

                      @@ -587,7 +587,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.4

                      +

                      Import interface wasi:cli/stderr@0.2.5


                      Types

                      type output-stream

                      @@ -600,7 +600,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.4

                      +

                      Import interface wasi:cli/stdin@0.2.5


                      Types

                      type input-stream

                      @@ -613,7 +613,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:http/types@0.2.4

                      +

                      Import interface wasi:http/types@0.2.5

                      This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                      @@ -1533,7 +1533,7 @@ but those will be reported by the incoming-body
                    224. option<result<result<own<incoming-response>, error-code>>>
                    225. -

                      Import interface wasi:http/outgoing-handler@0.2.4

                      +

                      Import interface wasi:http/outgoing-handler@0.2.5

                      This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                      @@ -1570,7 +1570,7 @@ through the future-incoming-response
                    226. result<own<future-incoming-response>, error-code>
                    227. -

                      Export interface wasi:http/incoming-handler@0.2.4

                      +

                      Export interface wasi:http/incoming-handler@0.2.5


                      Types

                      type incoming-request

                      diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index d1ea8ceb0..d7e6e7f3e 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,25 +1,25 @@ [cli] -url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.4.tar.gz" -sha256 = "674ab0febcabe50a68122751160d243361f401d923e93e4f9c0e6f9d424d21e1" -sha512 = "70529da20c463b37aeff9fb40586e093ee3560bdacf573e8dc8ec2a380c598456294d1308aee9431745ad0fef6ac67aae53b5abb4578c7d682cd5b1485825191" +url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.5.tar.gz" +sha256 = "b65ce8f20c1cfcb874a0083a589c77408188b641a1dfa12cd76158195844f5bd" +sha512 = "f6ce6a3416aa359111f2bf187d23459eef128c623e492f5c56da81099b8fd4bbd6db7274d0093fd70ae9077c812e58e5b221e55e68cd1e815b63b69334789ed8" deps = ["clocks", "filesystem", "io", "random", "sockets"] [clocks] -sha256 = "fc36267c5098ad9ac6455396b27c8ef206ca23cae74f40bd44c57be68e7849b6" -sha512 = "0deed3d3a86f284adda7991cd24c0c4aab806ba2e0cb111da80d7f99c05f10793a602b28451407cad58ab762997f60c0f6d173e919e4a0988773b455d3a410d3" +sha256 = "f1c53079469e20167e2cd4300651f13f34a6fd508b5c7331bb7c8c95fb8857fb" +sha512 = "2a9281d0edcabad3bfef0dcfa7a9712d6beb6d6bb07b29fbf24235706d149672901ffc32192404a1ac511c512eb775daf9716ad3a0514bdf6a5c93a5fed19450" [filesystem] -sha256 = "dd435f78b23714bd9d51ef3789c43b831549e71f54b57394a41bbf0c4da45f42" -sha512 = "d58bcf6eae908a6b2d883bcdfe456dc31aa99c848d0b3d21f710bde5bbb59ec105dbd5085004eadd0faa938530e4c29f88e589f525c080eb6d5971775a0b64ed" +sha256 = "9122d926d1e9c8c3c1aca0b54fcc6a64fe3b52b701d266af5ecbb7f83124a647" +sha512 = "a8e81ca42f4ff9d58dca945cabbcdf04b7a9870b7acd3bb95c95e40bb656e74c7e190f73cf0b3189b6b01a78f3aaa2e247c215541a7a0f67fb86ed3e0b3f9e35" [io] -sha256 = "770a73d479cda8e4c4064dd4006d2654ebcc358952079d74e41af27cf26bddbf" -sha512 = "b790f9750ac6782d9aaaa379845600b66dbde14ecee42f159c29796447eb8e61ee61f3b306e92622993b5e25298834b6ff62d7d9a04f8f18c05f07eda8f47ae0" +sha256 = "749de54c05f7118dc118999ad69c5b63890ea1dd86f1be69270062195c7b79c2" +sha512 = "b5096d518a7931c100594b9216bb4a98cd64533166bc7fdbb7465b48effc345863bd3ce2ec84fef59b273bae507edab08ec08975d56240ccef68f2494964e80a" [random] -sha256 = "876d81b0a777f1dc9db215fa36f45898a907188819185d6b189345f28c081a45" -sha512 = "fc6a0ed97e0525456222b28bcc49431bade826a97cb6eb52cde595908865d1ed7835c54a63b408ba82e3d49061aebb9a8725d1d2316d28c0ccb12af8ec968ab8" +sha256 = "c59984d9385d1ef7af6dd817b3d7a0a7f4084baa66c92026d6f9bf1eaf29169a" +sha512 = "7414a1a0616e42ff134ad15b65d9e10bc3b567b34f7f696356e20bc71bcb85ea16188d26d1997ba7e6964df9493f9f748304acaf1169e16ee21a035d8a8b4a89" [sockets] -sha256 = "e6872db116eb02f2043c4238999712de19bdb22e3c8da00af563f8b6c4dabb18" -sha512 = "28c05fe8acd691d808b6a90b950483bbf59983c02e91ed4a89b0e06c3e2a27e0f73be678979309553f0889fc3fea00c4740b007946d7285aa554dc65d56b1b7f" +sha256 = "1e55b9b6aa43e02cc0a674e7e6250f5145d48ffbc60c0f200b5ea192dce61640" +sha512 = "019224bb6fead5b6b687aeba7505ed05ebf20b9a60d045a4ab4fc323d0044af729b983b44efbe7ac8e0efda727f5c779fb0ad817c7802b2d7677196cf2cc0652" diff --git a/proposals/http/wit/deps.toml b/proposals/http/wit/deps.toml index 5a337428a..4e1cf2e1d 100644 --- a/proposals/http/wit/deps.toml +++ b/proposals/http/wit/deps.toml @@ -1 +1 @@ -cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.4.tar.gz" +cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.5.tar.gz" diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit index 88ab2a97e..716539569 100644 --- a/proposals/http/wit/deps/cli/command.wit +++ b/proposals/http/wit/deps/cli/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.4; +package wasi:cli@0.2.5; @since(version = 0.2.0) world command { diff --git a/proposals/http/wit/deps/cli/imports.wit b/proposals/http/wit/deps/cli/imports.wit index ad5c6bb23..93a83742f 100644 --- a/proposals/http/wit/deps/cli/imports.wit +++ b/proposals/http/wit/deps/cli/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.4; +package wasi:cli@0.2.5; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.4; + include wasi:clocks/imports@0.2.5; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.4; + include wasi:filesystem/imports@0.2.5; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.4; + include wasi:sockets/imports@0.2.5; @since(version = 0.2.0) - include wasi:random/imports@0.2.4; + include wasi:random/imports@0.2.5; @since(version = 0.2.0) - include wasi:io/imports@0.2.4; + include wasi:io/imports@0.2.5; @since(version = 0.2.0) import environment; diff --git a/proposals/http/wit/deps/cli/stdio.wit b/proposals/http/wit/deps/cli/stdio.wit index 60727a930..19a5ab9da 100644 --- a/proposals/http/wit/deps/cli/stdio.wit +++ b/proposals/http/wit/deps/cli/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{input-stream}; + use wasi:io/streams@0.2.5.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{output-stream}; + use wasi:io/streams@0.2.5.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{output-stream}; + use wasi:io/streams@0.2.5.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index 175f8fe2d..731e8a1e0 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.4; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/http/wit/deps/clocks/timezone.wit b/proposals/http/wit/deps/clocks/timezone.wit index 658cb17e7..ebe21a6e8 100644 --- a/proposals/http/wit/deps/clocks/timezone.wit +++ b/proposals/http/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/http/wit/deps/clocks/wall-clock.wit b/proposals/http/wit/deps/clocks/wall-clock.wit index f826cd1e0..2fde831bd 100644 --- a/proposals/http/wit/deps/clocks/wall-clock.wit +++ b/proposals/http/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/http/wit/deps/clocks/world.wit b/proposals/http/wit/deps/clocks/world.wit index 9e2087447..f32eed546 100644 --- a/proposals/http/wit/deps/clocks/world.wit +++ b/proposals/http/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.4; +package wasi:clocks@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/filesystem/preopens.wit b/proposals/http/wit/deps/filesystem/preopens.wit index 6e6003954..0a9b8f054 100644 --- a/proposals/http/wit/deps/filesystem/preopens.wit +++ b/proposals/http/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.4; +package wasi:filesystem@0.2.5; @since(version = 0.2.0) interface preopens { diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index 962cadfef..2b67884fb 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.4; +package wasi:filesystem@0.2.5; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.4; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.5.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.4.{datetime}; + use wasi:clocks/wall-clock@0.2.5.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/http/wit/deps/filesystem/world.wit b/proposals/http/wit/deps/filesystem/world.wit index 7742ed6bb..e7654ee77 100644 --- a/proposals/http/wit/deps/filesystem/world.wit +++ b/proposals/http/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.4; +package wasi:filesystem@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/io/error.wit b/proposals/http/wit/deps/io/error.wit index eb0600f9e..0e234bebd 100644 --- a/proposals/http/wit/deps/io/error.wit +++ b/proposals/http/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; @since(version = 0.2.0) interface error { diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/io/poll.wit index 170deff70..d33353e2a 100644 --- a/proposals/http/wit/deps/io/poll.wit +++ b/proposals/http/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index bb9a31e81..8d20252f8 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit index 8e0fa5c53..686418343 100644 --- a/proposals/http/wit/deps/io/world.wit +++ b/proposals/http/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.4; +package wasi:io@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/random/insecure-seed.wit b/proposals/http/wit/deps/random/insecure-seed.wit index 45e8bafdb..ab58b46c1 100644 --- a/proposals/http/wit/deps/random/insecure-seed.wit +++ b/proposals/http/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.4; +package wasi:random@0.2.5; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/insecure.wit b/proposals/http/wit/deps/random/insecure.wit index 5ab5030c5..f05130392 100644 --- a/proposals/http/wit/deps/random/insecure.wit +++ b/proposals/http/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.4; +package wasi:random@0.2.5; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index 9e5220d82..6b751b031 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.4; +package wasi:random@0.2.5; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit index d89055819..c32c48a96 100644 --- a/proposals/http/wit/deps/random/world.wit +++ b/proposals/http/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.4; +package wasi:random@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/sockets/ip-name-lookup.wit b/proposals/http/wit/deps/sockets/ip-name-lookup.wit index 48b41a5b1..04ab05d1e 100644 --- a/proposals/http/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/http/wit/deps/sockets/network.wit b/proposals/http/wit/deps/sockets/network.wit index aa4985e14..52c830165 100644 --- a/proposals/http/wit/deps/sockets/network.wit +++ b/proposals/http/wit/deps/sockets/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.4.{error}; + use wasi:io/error@0.2.5.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index b3311332f..2f4478511 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{input-stream, output-stream}; + use wasi:io/streams@0.2.5.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.4.{duration}; + use wasi:clocks/monotonic-clock@0.2.5.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index cfc07ba81..9a73a4713 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit index 82acdb9f0..733dc07b1 100644 --- a/proposals/http/wit/deps/sockets/world.wit +++ b/proposals/http/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.4; +package wasi:sockets@0.2.5; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index cd3af25c6..7d7518a68 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,4 +1,4 @@ -package wasi:http@0.2.4; +package wasi:http@0.2.5; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. /// It is intended to be `include`d in other worlds. @@ -6,25 +6,25 @@ package wasi:http@0.2.4; world imports { /// HTTP proxies have access to time and randomness. @since(version = 0.2.0) - import wasi:clocks/monotonic-clock@0.2.4; + import wasi:clocks/monotonic-clock@0.2.5; @since(version = 0.2.0) - import wasi:clocks/wall-clock@0.2.4; + import wasi:clocks/wall-clock@0.2.5; @since(version = 0.2.0) - import wasi:random/random@0.2.4; + import wasi:random/random@0.2.5; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. @since(version = 0.2.0) - import wasi:cli/stdout@0.2.4; + import wasi:cli/stdout@0.2.5; @since(version = 0.2.0) - import wasi:cli/stderr@0.2.4; + import wasi:cli/stderr@0.2.5; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. @since(version = 0.2.0) - import wasi:cli/stdin@0.2.4; + import wasi:cli/stdin@0.2.5; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 254a1bbed..239e7c418 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -4,13 +4,13 @@ @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.4.{duration}; + use wasi:clocks/monotonic-clock@0.2.5.{duration}; @since(version = 0.2.0) - use wasi:io/streams@0.2.4.{input-stream, output-stream}; + use wasi:io/streams@0.2.5.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/error@0.2.4.{error as io-error}; + use wasi:io/error@0.2.5.{error as io-error}; @since(version = 0.2.0) - use wasi:io/poll@0.2.4.{pollable}; + use wasi:io/poll@0.2.5.{pollable}; /// This type corresponds to HTTP standard Methods. @since(version = 0.2.0) From 7e203f98e50a9585e6f352f16b626354155136d0 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 10 Apr 2025 16:51:24 -0700 Subject: [PATCH 1658/1772] Link to correct version of TCP operational semantics doc --- proposals/sockets/wit-0.3.0-draft/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 456d4e5cc..156cc5026 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -125,7 +125,7 @@ interface types { /// - `connecting` /// - `connected` /// - `closed` - /// See + /// See /// for more information. /// /// Note: Except where explicitly mentioned, whenever this documentation uses From 3bc84cb23d3cfab9bb496891d0655bce7fcb7957 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 11 Apr 2025 17:17:20 +0200 Subject: [PATCH 1659/1772] [v0.3] model bodies after `stream`, trap less (#162) * feat(p3): be less trappy Signed-off-by: Roman Volosatovs * chore(p3): orphan `headers` returned by `headers()` Signed-off-by: Roman Volosatovs * doc(p3): improve wording Signed-off-by: Roman Volosatovs * feat(p3): avoid auto-close semantics Signed-off-by: Roman Volosatovs * p3: allow multiple active body refs to exist, drop `into-parts` Signed-off-by: Roman Volosatovs * p3: add `request-options#clone` Signed-off-by: Roman Volosatovs * p3: model `body` after `stream` Signed-off-by: Roman Volosatovs * p3: remove `body` resource Signed-off-by: Roman Volosatovs * p3: use `result`, not `option` in `body()` Signed-off-by: Roman Volosatovs * p3: make request/response bodies optional Signed-off-by: Roman Volosatovs * p3: document optional content stream optimization Signed-off-by: Roman Volosatovs --------- Signed-off-by: Roman Volosatovs --- proposals/http/wit-0.3.0-draft/types.wit | 168 ++++++++++------------- 1 file changed, 75 insertions(+), 93 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index deec70bce..f0ba60536 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -230,77 +230,36 @@ interface types { /// Trailers is an alias for Fields. type trailers = fields; - /// Represents an HTTP Request or Response's Body. - /// - /// A body has both its contents - a stream of bytes - and a (possibly empty) - /// set of trailers, indicating that the full contents of the body have been - /// received. This resource represents the contents as a `stream` and the - /// delivery of trailers as a `trailers`, and ensures that the user of this - /// interface may only be consuming either the body contents or waiting on - /// trailers at any given time. - resource body { - - /// Construct a new `body` with the specified stream. - /// - /// This function returns a future, which will resolve - /// to an error code if transmitting stream data fails. - /// - /// The returned future resolves to success once body stream - /// is fully transmitted. - new: static func( - %stream: stream, - ) -> tuple>>; - - /// Construct a new `body` with the specified stream and trailers. - /// - /// This function returns a future, which will resolve - /// to an error code if transmitting stream data or trailers fails. - /// - /// The returned future resolves to success once body stream and trailers - /// are fully transmitted. - new-with-trailers: static func( - %stream: stream, - trailers: future - ) -> tuple>>; - - /// Returns the contents of the body, as a stream of bytes. - /// - /// This function may be called multiple times as long as any `stream`s - /// returned by previous calls have been dropped first. - /// - /// On success, this function returns a stream and a future, which will resolve - /// to an error code if receiving data from stream fails. - /// The returned future resolves to success if body is closed. - %stream: func() -> result, future>>>; - - /// Takes ownership of `body`, and returns an unresolved optional `trailers` result. - /// - /// This function will trap if a `stream` child is still alive. - finish: static func(this: body) -> future, error-code>>; - } - /// Represents an HTTP Request. resource request { /// Construct a new `request` with a default `method` of `GET`, and /// `none` values for `path-with-query`, `scheme`, and `authority`. /// - /// * `headers` is the HTTP Headers for the Response. - /// * `body` is the optional contents of the body, possibly including - /// trailers. - /// * `options` is optional `request-options` to be used if the request is - /// sent over a network connection. + /// `headers` is the HTTP Headers for the Request. + /// + /// `contents` is the optional body content stream with `none` + /// representing a zero-length content stream. + /// Once it is closed, `trailers` future must resolve to a result. + /// If `trailers` resolves to an error, underlying connection + /// will be closed immediately. + /// + /// `options` is optional `request-options` resource to be used + /// if the request is sent over a network connection. /// /// It is possible to construct, or manipulate with the accessor functions - /// below, an `request` with an invalid combination of `scheme` + /// below, a `request` with an invalid combination of `scheme` /// and `authority`, or `headers` which are not permitted to be sent. /// It is the obligation of the `handler.handle` implementation /// to reject invalid constructions of `request`. - constructor( + /// + /// The returned future resolves to result of transmission of this request. + new: static func( headers: headers, - body: option, + contents: option>, + trailers: future, error-code>>, options: option - ); + ) -> tuple>>; /// Get the Method for the Request. method: func() -> method; @@ -348,22 +307,28 @@ interface types { /// /// The returned `headers` resource is immutable: `set`, `append`, and /// `delete` operations will fail with `header-error.immutable`. - /// - /// This headers resource is a child: it must be dropped before the parent - /// `request` is dropped, or its ownership is transferred to another - /// component by e.g. `handler.handle`. headers: func() -> headers; - /// Get the body associated with the Request, if any. + /// Get body of the Request. /// - /// This body resource is a child: it must be dropped before the parent - /// `request` is dropped, or its ownership is transferred to another - /// component by e.g. `handler.handle`. - body: func() -> option; - - /// Takes ownership of the `request` and returns the `headers`, `body` - /// and `request-options`, if any. - into-parts: static func(this: request) -> tuple, option>; + /// Stream returned by this method represents the contents of the body. + /// Once the stream is reported as closed, callers should await the returned future + /// to determine whether the body was received successfully. + /// The future will only resolve after the stream is reported as closed. + /// + /// The stream and future returned by this method are children: + /// they should be closed or consumed before the parent `response` + /// is dropped, or its ownership is transferred to another component + /// by e.g. `handler.handle`. + /// + /// This method may be called multiple times. + /// + /// This method will return an error if it is called while either: + /// - a stream or future returned by a previous call to this method is still open + /// - a stream returned by a previous call to this method has reported itself as closed + /// Thus there will always be at most one readable stream open for a given body. + /// Each subsequent stream picks up where the last stream left off, up until it is finished. + body: func() -> result, future, error-code>>>>; } /// Parameters for making an HTTP Request. Each of these parameters is @@ -400,6 +365,10 @@ interface types { /// body stream. An error return value indicates that this timeout is not /// supported or that this handle is immutable. set-between-bytes-timeout: func(duration: option) -> result<_, request-options-error>; + + /// Make a deep copy of the `request-options`. + /// The resulting `request-options` is mutable. + clone: func() -> request-options; } /// This type corresponds to the HTTP standard Status Code. @@ -408,17 +377,24 @@ interface types { /// Represents an HTTP Response. resource response { - /// Construct an `response`, with a default `status-code` of `200`. If a - /// different `status-code` is needed, it must be set via the + /// Construct a new `response`, with a default `status-code` of `200`. + /// If a different `status-code` is needed, it must be set via the /// `set-status-code` method. /// - /// * `headers` is the HTTP Headers for the Response. - /// * `body` is the optional contents of the body, possibly including - /// trailers. - constructor( + /// `headers` is the HTTP Headers for the Response. + /// + /// `contents` is the optional body content stream with `none` + /// representing a zero-length content stream. + /// Once it is closed, `trailers` future must resolve to a result. + /// If `trailers` resolves to an error, underlying connection + /// will be closed immediately. + /// + /// The returned future resolves to result of transmission of this response. + new: static func( headers: headers, - body: option, - ); + contents: option>, + trailers: future, error-code>>, + ) -> tuple>>; /// Get the HTTP Status Code for the Response. status-code: func() -> status-code; @@ -427,25 +403,31 @@ interface types { /// given is not a valid http status code. set-status-code: func(status-code: status-code) -> result; - /// Get the headers associated with the Request. + /// Get the headers associated with the Response. /// /// The returned `headers` resource is immutable: `set`, `append`, and /// `delete` operations will fail with `header-error.immutable`. - /// - /// This headers resource is a child: it must be dropped before the parent - /// `response` is dropped, or its ownership is transferred to another - /// component by e.g. `handler.handle`. headers: func() -> headers; - /// Get the body associated with the Response, if any. + /// Get body of the Response. /// - /// This body resource is a child: it must be dropped before the parent - /// `response` is dropped, or its ownership is transferred to another - /// component by e.g. `handler.handle`. - body: func() -> option; - - /// Takes ownership of the `response` and returns the `headers` and `body`, - /// if any. - into-parts: static func(this: response) -> tuple>; + /// Stream returned by this method represents the contents of the body. + /// Once the stream is reported as closed, callers should await the returned future + /// to determine whether the body was received successfully. + /// The future will only resolve after the stream is reported as closed. + /// + /// The stream and future returned by this method are children: + /// they should be closed or consumed before the parent `response` + /// is dropped, or its ownership is transferred to another component + /// by e.g. `handler.handle`. + /// + /// This method may be called multiple times. + /// + /// This method will return an error if it is called while either: + /// - a stream or future returned by a previous call to this method is still open + /// - a stream returned by a previous call to this method has reported itself as closed + /// Thus there will always be at most one readable stream open for a given body. + /// Each subsequent stream picks up where the last stream left off, up until it is finished. + body: func() -> result, future, error-code>>>>; } } From cab6b773e9a1b52cba8a83f7dda6ca007fcb21dd Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Tue, 10 Jun 2025 13:43:11 -0400 Subject: [PATCH 1660/1772] chore: wit-abi-up-to-date v24 Fixes `Error: failed to find release for tag 'wasm-tools-1.215.0'` --- proposals/clocks/.github/workflows/main.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml index 1d3021fdf..abb24eda1 100644 --- a/proposals/clocks/.github/workflows/main.yml +++ b/proposals/clocks/.github/workflows/main.yml @@ -18,7 +18,6 @@ jobs: ./wit-deps lock git add -N wit/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v23 + - uses: WebAssembly/wit-abi-up-to-date@v24 with: - wit-bindgen: '0.37.0' - all-features: 'true' \ No newline at end of file + all-features: 'true' From 0cb985587ba697827b0a8278d92a602334f0f04b Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Tue, 10 Jun 2025 14:30:07 -0400 Subject: [PATCH 1661/1772] chore: wit-abi-up-to-date@v24 --- proposals/io/.github/workflows/main.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml index 5a0984139..9f16450d4 100644 --- a/proposals/io/.github/workflows/main.yml +++ b/proposals/io/.github/workflows/main.yml @@ -11,7 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: WebAssembly/wit-abi-up-to-date@v23 + - uses: WebAssembly/wit-abi-up-to-date@v24 with: - wit-bindgen: '0.37.0' all-features: 'true' \ No newline at end of file From 16751467265995bf1bf08b1985a9e715098563e9 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Tue, 10 Jun 2025 14:26:16 -0400 Subject: [PATCH 1662/1772] chore: wit-abi-up-to-date@v24 --- proposals/random/.github/workflows/main.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml index 5a0984139..9f16450d4 100644 --- a/proposals/random/.github/workflows/main.yml +++ b/proposals/random/.github/workflows/main.yml @@ -11,7 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: WebAssembly/wit-abi-up-to-date@v23 + - uses: WebAssembly/wit-abi-up-to-date@v24 with: - wit-bindgen: '0.37.0' all-features: 'true' \ No newline at end of file From 7bd68e420a053bed425f8c97fb050f25b3e6469a Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Tue, 10 Jun 2025 14:32:45 -0400 Subject: [PATCH 1663/1772] chore: wit-abi-up-to-date@v24 --- proposals/filesystem/.github/workflows/main.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index abe3a4f22..ae5630788 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -20,7 +20,6 @@ jobs: git add -N wit/deps git add -N wit-0.3.0-draft/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v23 + - uses: WebAssembly/wit-abi-up-to-date@v24 with: - wit-bindgen: '0.37.0' all-features: 'true' \ No newline at end of file From af11c3c9529109345dc8b558ebf58e080f787583 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Tue, 10 Jun 2025 14:49:49 -0400 Subject: [PATCH 1664/1772] chore: wit-abi-up-to-date@v24 --- proposals/sockets/.github/workflows/main.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index a7b9d318f..4caaff1aa 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -20,8 +20,6 @@ jobs: git add -N wit/deps git add -N wit-0.3.0-draft/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v23 + - uses: WebAssembly/wit-abi-up-to-date@v24 with: - wit-bindgen: '0.37.0' - wasm-tools: '1.223.0' all-features: 'true' From 53140ddcb853fe08e1e00b3f609fbb187301b85b Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Tue, 10 Jun 2025 14:50:49 -0400 Subject: [PATCH 1665/1772] chore: wit-abi-up-to-date@v24 --- proposals/http/.github/workflows/main.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index a043898b5..84a25f3fd 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -17,9 +17,7 @@ jobs: chmod +x ./wit-deps ./wit-deps lock --check ./wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps lock --check - - uses: WebAssembly/wit-abi-up-to-date@v23 + - uses: WebAssembly/wit-abi-up-to-date@v24 with: - wasm-tools: '1.223.0' - wit-bindgen: '0.37.0' worlds: 'imports proxy' all-features: 'true' From 76462d5d551f3ef76ece14a547e08012fd73d310 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Tue, 10 Jun 2025 14:42:39 -0400 Subject: [PATCH 1666/1772] chore: wit-abi-up-to-date@v24 --- proposals/cli/.github/workflows/main.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml index 584e02cb9..561533b0c 100644 --- a/proposals/cli/.github/workflows/main.yml +++ b/proposals/cli/.github/workflows/main.yml @@ -20,9 +20,8 @@ jobs: git add -N wit/deps git add -N wit-0.3.0-draft/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v23 + + - uses: WebAssembly/wit-abi-up-to-date@v24 with: - wit-bindgen: '0.33.0' - wasm-tools: '1.218.0' worlds: 'command imports' all-features: 'true' From 8fdb2d72150f031d7fba3fc484556ae6d3150f6b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Jun 2025 18:28:52 +0000 Subject: [PATCH 1667/1772] Update to v0.2.6 --- proposals/io/imports.md | 12 ++++++------ proposals/io/wit/error.wit | 2 +- proposals/io/wit/poll.wit | 2 +- proposals/io/wit/streams.wit | 2 +- proposals/io/wit/world.wit | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index b1f5014f1..f9a4f22ed 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -2,13 +2,13 @@ -

                      Import interface wasi:io/error@0.2.5

                      +

                      Import interface wasi:io/error@0.2.6


                      Types

                      resource error

                      @@ -41,7 +41,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/poll@0.2.5

                      +

                      Import interface wasi:io/poll@0.2.6

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -94,7 +94,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:io/streams@0.2.5

                      +

                      Import interface wasi:io/streams@0.2.6

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; diff --git a/proposals/io/wit/error.wit b/proposals/io/wit/error.wit index 0e234bebd..784f74a53 100644 --- a/proposals/io/wit/error.wit +++ b/proposals/io/wit/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; @since(version = 0.2.0) interface error { diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index d33353e2a..7f711836c 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index 8d20252f8..c5da38c86 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index 686418343..84c85c08e 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; @since(version = 0.2.0) world imports { From ac3bbaca18f289555cc4f2c315ffa57490a75ecb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Jun 2025 21:06:30 +0000 Subject: [PATCH 1668/1772] Update to v0.2.6 --- proposals/random/imports.md | 12 ++++++------ proposals/random/wit/insecure-seed.wit | 2 +- proposals/random/wit/insecure.wit | 2 +- proposals/random/wit/random.wit | 2 +- proposals/random/wit/world.wit | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/random/imports.md b/proposals/random/imports.md index b9b17cd91..8b180bf66 100644 --- a/proposals/random/imports.md +++ b/proposals/random/imports.md @@ -2,13 +2,13 @@

                      -

                      Import interface wasi:random/random@0.2.5

                      +

                      Import interface wasi:random/random@0.2.6

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -41,7 +41,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:random/insecure@0.2.5

                      +

                      Import interface wasi:random/insecure@0.2.6

                      The insecure interface for insecure pseudo-random numbers.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -70,7 +70,7 @@ a long period.

                      • u64
                      -

                      Import interface wasi:random/insecure-seed@0.2.5

                      +

                      Import interface wasi:random/insecure-seed@0.2.6

                      The insecure-seed interface for seeding hash-map DoS resistance.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index ab58b46c1..d3dc03a6c 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.5; +package wasi:random@0.2.6; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index f05130392..d4d028480 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.5; +package wasi:random@0.2.6; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 6b751b031..a0ff95646 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.5; +package wasi:random@0.2.6; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index c32c48a96..099f47b36 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.5; +package wasi:random@0.2.6; @since(version = 0.2.0) world imports { From ffb7afcaafff25d67a21d3eb193caa3fd686b360 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Jun 2025 21:22:06 +0000 Subject: [PATCH 1669/1772] Update to v0.2.6 --- proposals/sockets/imports.md | 44 +++++++++---------- proposals/sockets/wit/deps.lock | 8 ++-- .../wit/deps/clocks/monotonic-clock.wit | 4 +- .../sockets/wit/deps/clocks/timezone.wit | 2 +- .../sockets/wit/deps/clocks/wall-clock.wit | 2 +- proposals/sockets/wit/deps/clocks/world.wit | 2 +- proposals/sockets/wit/deps/io/error.wit | 2 +- proposals/sockets/wit/deps/io/poll.wit | 2 +- proposals/sockets/wit/deps/io/streams.wit | 2 +- proposals/sockets/wit/deps/io/world.wit | 2 +- proposals/sockets/wit/ip-name-lookup.wit | 2 +- proposals/sockets/wit/network.wit | 2 +- proposals/sockets/wit/tcp.wit | 6 +-- proposals/sockets/wit/udp.wit | 2 +- proposals/sockets/wit/world.wit | 2 +- 15 files changed, 42 insertions(+), 42 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 1f0154819..e81956b99 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -2,21 +2,21 @@ -

                      Import interface wasi:io/error@0.2.5

                      +

                      Import interface wasi:io/error@0.2.6


                      Types

                      resource error

                      @@ -49,7 +49,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:sockets/network@0.2.5

                      +

                      Import interface wasi:sockets/network@0.2.6


                      Types

                      type error

                      @@ -264,7 +264,7 @@ errors are network-related errors.

                      -

                      Import interface wasi:sockets/instance-network@0.2.5

                      +

                      Import interface wasi:sockets/instance-network@0.2.6

                      This interface provides a value-export of the default network handle..


                      Types

                      @@ -279,7 +279,7 @@ errors are network-related errors.

                      -

                      Import interface wasi:io/poll@0.2.5

                      +

                      Import interface wasi:io/poll@0.2.6

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -332,7 +332,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:sockets/udp@0.2.5

                      +

                      Import interface wasi:sockets/udp@0.2.6


                      Types

                      type pollable

                      @@ -746,7 +746,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:sockets/udp-create-socket@0.2.5

                      +

                      Import interface wasi:sockets/udp-create-socket@0.2.6


                      Types

                      type network

                      @@ -791,7 +791,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                      Import interface wasi:io/streams@0.2.5

                      +

                      Import interface wasi:io/streams@0.2.6

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -1121,7 +1121,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.5

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.6

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -1180,7 +1180,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:sockets/tcp@0.2.5

                      +

                      Import interface wasi:sockets/tcp@0.2.6


                      Types

                      type input-stream

                      @@ -1771,7 +1771,7 @@ has no effect and returns ok.

                      -

                      Import interface wasi:sockets/tcp-create-socket@0.2.5

                      +

                      Import interface wasi:sockets/tcp-create-socket@0.2.6


                      Types

                      type network

                      @@ -1816,7 +1816,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                      Import interface wasi:sockets/ip-name-lookup@0.2.5

                      +

                      Import interface wasi:sockets/ip-name-lookup@0.2.6


                      Types

                      type pollable

                      diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index 333ff3a78..32cd8bf74 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "f1c53079469e20167e2cd4300651f13f34a6fd508b5c7331bb7c8c95fb8857fb" -sha512 = "2a9281d0edcabad3bfef0dcfa7a9712d6beb6d6bb07b29fbf24235706d149672901ffc32192404a1ac511c512eb775daf9716ad3a0514bdf6a5c93a5fed19450" +sha256 = "59b8db7b6f3f8a72418510453c1fa9e437c7c7c2369c0bd5da83aa5d6d1d9b73" +sha512 = "06ce14bbf34d5588ed0c26bd932d46b3025c16723d5b4558def5b8107781b2251471c1f7170640342e3d4f78efb560d5ff6383c6a127c1d9e757e83db31a0185" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "749de54c05f7118dc118999ad69c5b63890ea1dd86f1be69270062195c7b79c2" -sha512 = "b5096d518a7931c100594b9216bb4a98cd64533166bc7fdbb7465b48effc345863bd3ce2ec84fef59b273bae507edab08ec08975d56240ccef68f2494964e80a" +sha256 = "671761f464d312e6c26bcaab5e79fe14ac876b72267867579d5c65e053fe2301" +sha512 = "57e5ed34fa85f35899b324ac7a2473c5fa5cece51d07e6f077637191fadd3c8b6f79324d31a8d497a6ce7b92cfb2a2505ab894337e2c82889f1bdb21f4f24634" diff --git a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit index 731e8a1e0..f3bc83912 100644 --- a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.5; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.6.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/sockets/wit/deps/clocks/timezone.wit b/proposals/sockets/wit/deps/clocks/timezone.wit index ebe21a6e8..ca98ad152 100644 --- a/proposals/sockets/wit/deps/clocks/timezone.wit +++ b/proposals/sockets/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/sockets/wit/deps/clocks/wall-clock.wit b/proposals/sockets/wit/deps/clocks/wall-clock.wit index 2fde831bd..76636a0c9 100644 --- a/proposals/sockets/wit/deps/clocks/wall-clock.wit +++ b/proposals/sockets/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/sockets/wit/deps/clocks/world.wit b/proposals/sockets/wit/deps/clocks/world.wit index f32eed546..5c53c51a1 100644 --- a/proposals/sockets/wit/deps/clocks/world.wit +++ b/proposals/sockets/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; @since(version = 0.2.0) world imports { diff --git a/proposals/sockets/wit/deps/io/error.wit b/proposals/sockets/wit/deps/io/error.wit index 0e234bebd..784f74a53 100644 --- a/proposals/sockets/wit/deps/io/error.wit +++ b/proposals/sockets/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; @since(version = 0.2.0) interface error { diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit index d33353e2a..7f711836c 100644 --- a/proposals/sockets/wit/deps/io/poll.wit +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index 8d20252f8..c5da38c86 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit index 686418343..84c85c08e 100644 --- a/proposals/sockets/wit/deps/io/world.wit +++ b/proposals/sockets/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; @since(version = 0.2.0) world imports { diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index 04ab05d1e..ee6419e7d 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.6.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 52c830165..6ca98b63b 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.5.{error}; + use wasi:io/error@0.2.6.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 2f4478511..beefd7b46 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.5.{input-stream, output-stream}; + use wasi:io/streams@0.2.6.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.6.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.5.{duration}; + use wasi:clocks/monotonic-clock@0.2.6.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 9a73a4713..9dbe6932d 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.6.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index 733dc07b1..e86f02cec 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.5; +package wasi:sockets@0.2.6; @since(version = 0.2.0) world imports { From 0c75dfa78ccd158b335f4eabcec08733e9538b98 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Jun 2025 21:42:42 +0000 Subject: [PATCH 1670/1772] Update to v0.2.6 --- proposals/filesystem/imports.md | 24 +++++++++---------- proposals/filesystem/wit/deps.lock | 8 +++---- .../wit/deps/clocks/monotonic-clock.wit | 4 ++-- .../filesystem/wit/deps/clocks/timezone.wit | 2 +- .../filesystem/wit/deps/clocks/wall-clock.wit | 2 +- .../filesystem/wit/deps/clocks/world.wit | 2 +- proposals/filesystem/wit/deps/io/error.wit | 2 +- proposals/filesystem/wit/deps/io/poll.wit | 2 +- proposals/filesystem/wit/deps/io/streams.wit | 2 +- proposals/filesystem/wit/deps/io/world.wit | 2 +- proposals/filesystem/wit/preopens.wit | 2 +- proposals/filesystem/wit/types.wit | 6 ++--- proposals/filesystem/wit/world.wit | 2 +- 13 files changed, 30 insertions(+), 30 deletions(-) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index ca0c6c906..29819b576 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -2,16 +2,16 @@ -

                      Import interface wasi:io/error@0.2.5

                      +

                      Import interface wasi:io/error@0.2.6


                      Types

                      resource error

                      @@ -44,7 +44,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/poll@0.2.5

                      +

                      Import interface wasi:io/poll@0.2.6

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -97,7 +97,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:io/streams@0.2.5

                      +

                      Import interface wasi:io/streams@0.2.6

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -427,7 +427,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.5

                      +

                      Import interface wasi:clocks/wall-clock@0.2.6

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -468,7 +468,7 @@ also known as Unix Time.
                    228. datetime
                    229. -

                      Import interface wasi:filesystem/types@0.2.5

                      +

                      Import interface wasi:filesystem/types@0.2.6

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                      @@ -1346,7 +1346,7 @@ errors are filesystem-related errors.

                      -

                      Import interface wasi:filesystem/preopens@0.2.5

                      +

                      Import interface wasi:filesystem/preopens@0.2.6


                      Types

                      type descriptor

                      diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index 333ff3a78..32cd8bf74 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "f1c53079469e20167e2cd4300651f13f34a6fd508b5c7331bb7c8c95fb8857fb" -sha512 = "2a9281d0edcabad3bfef0dcfa7a9712d6beb6d6bb07b29fbf24235706d149672901ffc32192404a1ac511c512eb775daf9716ad3a0514bdf6a5c93a5fed19450" +sha256 = "59b8db7b6f3f8a72418510453c1fa9e437c7c7c2369c0bd5da83aa5d6d1d9b73" +sha512 = "06ce14bbf34d5588ed0c26bd932d46b3025c16723d5b4558def5b8107781b2251471c1f7170640342e3d4f78efb560d5ff6383c6a127c1d9e757e83db31a0185" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "749de54c05f7118dc118999ad69c5b63890ea1dd86f1be69270062195c7b79c2" -sha512 = "b5096d518a7931c100594b9216bb4a98cd64533166bc7fdbb7465b48effc345863bd3ce2ec84fef59b273bae507edab08ec08975d56240ccef68f2494964e80a" +sha256 = "671761f464d312e6c26bcaab5e79fe14ac876b72267867579d5c65e053fe2301" +sha512 = "57e5ed34fa85f35899b324ac7a2473c5fa5cece51d07e6f077637191fadd3c8b6f79324d31a8d497a6ce7b92cfb2a2505ab894337e2c82889f1bdb21f4f24634" diff --git a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit index 731e8a1e0..f3bc83912 100644 --- a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.5; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.6.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/filesystem/wit/deps/clocks/timezone.wit b/proposals/filesystem/wit/deps/clocks/timezone.wit index ebe21a6e8..ca98ad152 100644 --- a/proposals/filesystem/wit/deps/clocks/timezone.wit +++ b/proposals/filesystem/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/filesystem/wit/deps/clocks/wall-clock.wit b/proposals/filesystem/wit/deps/clocks/wall-clock.wit index 2fde831bd..76636a0c9 100644 --- a/proposals/filesystem/wit/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/filesystem/wit/deps/clocks/world.wit b/proposals/filesystem/wit/deps/clocks/world.wit index f32eed546..5c53c51a1 100644 --- a/proposals/filesystem/wit/deps/clocks/world.wit +++ b/proposals/filesystem/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; @since(version = 0.2.0) world imports { diff --git a/proposals/filesystem/wit/deps/io/error.wit b/proposals/filesystem/wit/deps/io/error.wit index 0e234bebd..784f74a53 100644 --- a/proposals/filesystem/wit/deps/io/error.wit +++ b/proposals/filesystem/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; @since(version = 0.2.0) interface error { diff --git a/proposals/filesystem/wit/deps/io/poll.wit b/proposals/filesystem/wit/deps/io/poll.wit index d33353e2a..7f711836c 100644 --- a/proposals/filesystem/wit/deps/io/poll.wit +++ b/proposals/filesystem/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index 8d20252f8..c5da38c86 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/filesystem/wit/deps/io/world.wit b/proposals/filesystem/wit/deps/io/world.wit index 686418343..84c85c08e 100644 --- a/proposals/filesystem/wit/deps/io/world.wit +++ b/proposals/filesystem/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; @since(version = 0.2.0) world imports { diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit index 0a9b8f054..f22847940 100644 --- a/proposals/filesystem/wit/preopens.wit +++ b/proposals/filesystem/wit/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.5; +package wasi:filesystem@0.2.6; @since(version = 0.2.0) interface preopens { diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 2b67884fb..75c19044c 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.5; +package wasi:filesystem@0.2.6; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.5; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.5.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.6.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.5.{datetime}; + use wasi:clocks/wall-clock@0.2.6.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index e7654ee77..65597f9f2 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.5; +package wasi:filesystem@0.2.6; @since(version = 0.2.0) world imports { From 820df6475349dcd4d7b1dd8f75898b731b500074 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Jun 2025 21:47:36 +0000 Subject: [PATCH 1671/1772] Update to v0.2.6 --- proposals/cli/command.md | 116 ++++++++--------- proposals/cli/imports.md | 118 +++++++++--------- proposals/cli/wit/command.wit | 2 +- proposals/cli/wit/deps.lock | 26 ++-- proposals/cli/wit/deps.toml | 6 +- .../cli/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/cli/wit/deps/clocks/timezone.wit | 2 +- proposals/cli/wit/deps/clocks/wall-clock.wit | 2 +- proposals/cli/wit/deps/clocks/world.wit | 2 +- .../cli/wit/deps/filesystem/preopens.wit | 2 +- proposals/cli/wit/deps/filesystem/types.wit | 6 +- proposals/cli/wit/deps/filesystem/world.wit | 2 +- proposals/cli/wit/deps/io/error.wit | 2 +- proposals/cli/wit/deps/io/poll.wit | 2 +- proposals/cli/wit/deps/io/streams.wit | 2 +- proposals/cli/wit/deps/io/world.wit | 2 +- .../cli/wit/deps/random/insecure-seed.wit | 2 +- proposals/cli/wit/deps/random/insecure.wit | 2 +- proposals/cli/wit/deps/random/random.wit | 2 +- proposals/cli/wit/deps/random/world.wit | 2 +- .../cli/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/cli/wit/deps/sockets/network.wit | 2 +- proposals/cli/wit/deps/sockets/tcp.wit | 6 +- proposals/cli/wit/deps/sockets/udp.wit | 2 +- proposals/cli/wit/deps/sockets/world.wit | 2 +- proposals/cli/wit/imports.wit | 12 +- proposals/cli/wit/stdio.wit | 6 +- 27 files changed, 168 insertions(+), 168 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index e99fa9733..2a6139c8e 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -2,43 +2,43 @@ -

                      Import interface wasi:cli/environment@0.2.5

                      +

                      Import interface wasi:cli/environment@0.2.6


                      Functions

                      get-environment: func

                      @@ -65,7 +65,7 @@ directory, interpreting . as shorthand for this.

                      • option<string>
                      -

                      Import interface wasi:cli/exit@0.2.5

                      +

                      Import interface wasi:cli/exit@0.2.6


                      Functions

                      exit: func

                      @@ -85,7 +85,7 @@ without the connotation that something bad has happened.

                      • status-code: u8
                      -

                      Import interface wasi:io/error@0.2.5

                      +

                      Import interface wasi:io/error@0.2.6


                      Types

                      resource error

                      @@ -118,7 +118,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/poll@0.2.5

                      +

                      Import interface wasi:io/poll@0.2.6

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -171,7 +171,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:io/streams@0.2.5

                      +

                      Import interface wasi:io/streams@0.2.6

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -501,7 +501,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.5

                      +

                      Import interface wasi:cli/stdin@0.2.6


                      Types

                      type input-stream

                      @@ -514,7 +514,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.5

                      +

                      Import interface wasi:cli/stdout@0.2.6


                      Types

                      type output-stream

                      @@ -527,7 +527,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.5

                      +

                      Import interface wasi:cli/stderr@0.2.6


                      Types

                      type output-stream

                      @@ -540,7 +540,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/terminal-input@0.2.5

                      +

                      Import interface wasi:cli/terminal-input@0.2.6

                      Terminal input.

                      In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -549,7 +549,7 @@ immediately, querying supported features, and so on.

                      Types

                      resource terminal-input

                      The input side of a terminal.

                      -

                      Import interface wasi:cli/terminal-output@0.2.5

                      +

                      Import interface wasi:cli/terminal-output@0.2.6

                      Terminal output.

                      In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -558,7 +558,7 @@ features, and so on.

                      Types

                      resource terminal-output

                      The output side of a terminal.

                      -

                      Import interface wasi:cli/terminal-stdin@0.2.5

                      +

                      Import interface wasi:cli/terminal-stdin@0.2.6

                      An interface providing an optional terminal-input for stdin as a link-time authority.


                      @@ -575,7 +575,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stdout@0.2.5

                      +

                      Import interface wasi:cli/terminal-stdout@0.2.6

                      An interface providing an optional terminal-output for stdout as a link-time authority.


                      @@ -592,7 +592,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stderr@0.2.5

                      +

                      Import interface wasi:cli/terminal-stderr@0.2.6

                      An interface providing an optional terminal-output for stderr as a link-time authority.


                      @@ -609,7 +609,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.5

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.6

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -668,7 +668,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.5

                      +

                      Import interface wasi:clocks/wall-clock@0.2.6

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -709,7 +709,7 @@ also known as Unix Time.
                    230. datetime
                    231. -

                      Import interface wasi:clocks/timezone@0.2.5

                      +

                      Import interface wasi:clocks/timezone@0.2.6


                      Types

                      type datetime

                      @@ -774,7 +774,7 @@ saving time.

                      • s32
                      -

                      Import interface wasi:filesystem/types@0.2.5

                      +

                      Import interface wasi:filesystem/types@0.2.6

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                      @@ -1652,7 +1652,7 @@ errors are filesystem-related errors.

                      -

                      Import interface wasi:filesystem/preopens@0.2.5

                      +

                      Import interface wasi:filesystem/preopens@0.2.6


                      Types

                      type descriptor

                      @@ -1666,7 +1666,7 @@ errors are filesystem-related errors.

                      -

                      Import interface wasi:sockets/network@0.2.5

                      +

                      Import interface wasi:sockets/network@0.2.6


                      Types

                      type error

                      @@ -1881,7 +1881,7 @@ errors are network-related errors.

                      -

                      Import interface wasi:sockets/instance-network@0.2.5

                      +

                      Import interface wasi:sockets/instance-network@0.2.6

                      This interface provides a value-export of the default network handle..


                      Types

                      @@ -1896,7 +1896,7 @@ errors are network-related errors.

                      -

                      Import interface wasi:sockets/udp@0.2.5

                      +

                      Import interface wasi:sockets/udp@0.2.6


                      Types

                      type pollable

                      @@ -2310,7 +2310,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:sockets/udp-create-socket@0.2.5

                      +

                      Import interface wasi:sockets/udp-create-socket@0.2.6


                      Types

                      type network

                      @@ -2355,7 +2355,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                      Import interface wasi:sockets/tcp@0.2.5

                      +

                      Import interface wasi:sockets/tcp@0.2.6


                      Types

                      type input-stream

                      @@ -2946,7 +2946,7 @@ has no effect and returns ok.

                      -

                      Import interface wasi:sockets/tcp-create-socket@0.2.5

                      +

                      Import interface wasi:sockets/tcp-create-socket@0.2.6


                      Types

                      type network

                      @@ -2991,7 +2991,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                      Import interface wasi:sockets/ip-name-lookup@0.2.5

                      +

                      Import interface wasi:sockets/ip-name-lookup@0.2.6


                      Types

                      type pollable

                      @@ -3071,7 +3071,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:random/random@0.2.5

                      +

                      Import interface wasi:random/random@0.2.6

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3104,7 +3104,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:random/insecure@0.2.5

                      +

                      Import interface wasi:random/insecure@0.2.6

                      The insecure interface for insecure pseudo-random numbers.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3133,7 +3133,7 @@ a long period.

                      • u64
                      -

                      Import interface wasi:random/insecure-seed@0.2.5

                      +

                      Import interface wasi:random/insecure-seed@0.2.6

                      The insecure-seed interface for seeding hash-map DoS resistance.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3157,7 +3157,7 @@ protection.

                      • (u64, u64)
                      -

                      Export interface wasi:cli/run@0.2.5

                      +

                      Export interface wasi:cli/run@0.2.6


                      Functions

                      run: func

                      diff --git a/proposals/cli/imports.md b/proposals/cli/imports.md index f9252b062..0547ac19e 100644 --- a/proposals/cli/imports.md +++ b/proposals/cli/imports.md @@ -2,38 +2,38 @@ -

                      Import interface wasi:cli/environment@0.2.5

                      +
                    232. interface wasi:cli/environment@0.2.6
                    233. +
                    234. interface wasi:cli/exit@0.2.6
                    235. +
                    236. interface wasi:io/error@0.2.6
                    237. +
                    238. interface wasi:io/poll@0.2.6
                    239. +
                    240. interface wasi:io/streams@0.2.6
                    241. +
                    242. interface wasi:cli/stdin@0.2.6
                    243. +
                    244. interface wasi:cli/stdout@0.2.6
                    245. +
                    246. interface wasi:cli/stderr@0.2.6
                    247. +
                    248. interface wasi:cli/terminal-input@0.2.6
                    249. +
                    250. interface wasi:cli/terminal-output@0.2.6
                    251. +
                    252. interface wasi:cli/terminal-stdin@0.2.6
                    253. +
                    254. interface wasi:cli/terminal-stdout@0.2.6
                    255. +
                    256. interface wasi:cli/terminal-stderr@0.2.6
                    257. +
                    258. interface wasi:clocks/monotonic-clock@0.2.6
                    259. +
                    260. interface wasi:clocks/wall-clock@0.2.6
                    261. +
                    262. interface wasi:clocks/timezone@0.2.6
                    263. +
                    264. interface wasi:filesystem/types@0.2.6
                    265. +
                    266. interface wasi:filesystem/preopens@0.2.6
                    267. +
                    268. interface wasi:sockets/network@0.2.6
                    269. +
                    270. interface wasi:sockets/instance-network@0.2.6
                    271. +
                    272. interface wasi:sockets/udp@0.2.6
                    273. +
                    274. interface wasi:sockets/udp-create-socket@0.2.6
                    275. +
                    276. interface wasi:sockets/tcp@0.2.6
                    277. +
                    278. interface wasi:sockets/tcp-create-socket@0.2.6
                    279. +
                    280. interface wasi:sockets/ip-name-lookup@0.2.6
                    281. +
                    282. interface wasi:random/random@0.2.6
                    283. +
                    284. interface wasi:random/insecure@0.2.6
                    285. +
                    286. interface wasi:random/insecure-seed@0.2.6
                    287. + + + +

                      Import interface wasi:cli/environment@0.2.6


                      Functions

                      get-environment: func

                      @@ -60,7 +60,7 @@ directory, interpreting . as shorthand for this.

                      • option<string>
                      -

                      Import interface wasi:cli/exit@0.2.5

                      +

                      Import interface wasi:cli/exit@0.2.6


                      Functions

                      exit: func

                      @@ -80,7 +80,7 @@ without the connotation that something bad has happened.

                      • status-code: u8
                      -

                      Import interface wasi:io/error@0.2.5

                      +

                      Import interface wasi:io/error@0.2.6


                      Types

                      resource error

                      @@ -113,7 +113,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/poll@0.2.5

                      +

                      Import interface wasi:io/poll@0.2.6

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -166,7 +166,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:io/streams@0.2.5

                      +

                      Import interface wasi:io/streams@0.2.6

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -496,7 +496,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.5

                      +

                      Import interface wasi:cli/stdin@0.2.6


                      Types

                      type input-stream

                      @@ -509,7 +509,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.5

                      +

                      Import interface wasi:cli/stdout@0.2.6


                      Types

                      type output-stream

                      @@ -522,7 +522,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.5

                      +

                      Import interface wasi:cli/stderr@0.2.6


                      Types

                      type output-stream

                      @@ -535,7 +535,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/terminal-input@0.2.5

                      +

                      Import interface wasi:cli/terminal-input@0.2.6

                      Terminal input.

                      In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -544,7 +544,7 @@ immediately, querying supported features, and so on.

                      Types

                      resource terminal-input

                      The input side of a terminal.

                      -

                      Import interface wasi:cli/terminal-output@0.2.5

                      +

                      Import interface wasi:cli/terminal-output@0.2.6

                      Terminal output.

                      In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -553,7 +553,7 @@ features, and so on.

                      Types

                      resource terminal-output

                      The output side of a terminal.

                      -

                      Import interface wasi:cli/terminal-stdin@0.2.5

                      +

                      Import interface wasi:cli/terminal-stdin@0.2.6

                      An interface providing an optional terminal-input for stdin as a link-time authority.


                      @@ -570,7 +570,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stdout@0.2.5

                      +

                      Import interface wasi:cli/terminal-stdout@0.2.6

                      An interface providing an optional terminal-output for stdout as a link-time authority.


                      @@ -587,7 +587,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:cli/terminal-stderr@0.2.5

                      +

                      Import interface wasi:cli/terminal-stderr@0.2.6

                      An interface providing an optional terminal-output for stderr as a link-time authority.


                      @@ -604,7 +604,7 @@ allowing further interaction with it.

                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.5

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.6

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -663,7 +663,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.5

                      +

                      Import interface wasi:clocks/wall-clock@0.2.6

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -704,7 +704,7 @@ also known as Unix Time.
                    288. datetime
                    289. -

                      Import interface wasi:clocks/timezone@0.2.5

                      +

                      Import interface wasi:clocks/timezone@0.2.6


                      Types

                      type datetime

                      @@ -769,7 +769,7 @@ saving time.

                      • s32
                      -

                      Import interface wasi:filesystem/types@0.2.5

                      +

                      Import interface wasi:filesystem/types@0.2.6

                      WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                      @@ -1647,7 +1647,7 @@ errors are filesystem-related errors.

                      -

                      Import interface wasi:filesystem/preopens@0.2.5

                      +

                      Import interface wasi:filesystem/preopens@0.2.6


                      Types

                      type descriptor

                      @@ -1661,7 +1661,7 @@ errors are filesystem-related errors.

                      -

                      Import interface wasi:sockets/network@0.2.5

                      +

                      Import interface wasi:sockets/network@0.2.6


                      Types

                      type error

                      @@ -1876,7 +1876,7 @@ errors are network-related errors.

                      -

                      Import interface wasi:sockets/instance-network@0.2.5

                      +

                      Import interface wasi:sockets/instance-network@0.2.6

                      This interface provides a value-export of the default network handle..


                      Types

                      @@ -1891,7 +1891,7 @@ errors are network-related errors.

                      -

                      Import interface wasi:sockets/udp@0.2.5

                      +

                      Import interface wasi:sockets/udp@0.2.6


                      Types

                      type pollable

                      @@ -2305,7 +2305,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:sockets/udp-create-socket@0.2.5

                      +

                      Import interface wasi:sockets/udp-create-socket@0.2.6


                      Types

                      type network

                      @@ -2350,7 +2350,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                      Import interface wasi:sockets/tcp@0.2.5

                      +

                      Import interface wasi:sockets/tcp@0.2.6


                      Types

                      type input-stream

                      @@ -2941,7 +2941,7 @@ has no effect and returns ok.

                      -

                      Import interface wasi:sockets/tcp-create-socket@0.2.5

                      +

                      Import interface wasi:sockets/tcp-create-socket@0.2.6


                      Types

                      type network

                      @@ -2986,7 +2986,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                      Import interface wasi:sockets/ip-name-lookup@0.2.5

                      +

                      Import interface wasi:sockets/ip-name-lookup@0.2.6


                      Types

                      type pollable

                      @@ -3066,7 +3066,7 @@ It's planned to be removed when future is natively supported in Pre -

                      Import interface wasi:random/random@0.2.5

                      +

                      Import interface wasi:random/random@0.2.6

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3099,7 +3099,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:random/insecure@0.2.5

                      +

                      Import interface wasi:random/insecure@0.2.6

                      The insecure interface for insecure pseudo-random numbers.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -3128,7 +3128,7 @@ a long period.

                      • u64
                      -

                      Import interface wasi:random/insecure-seed@0.2.5

                      +

                      Import interface wasi:random/insecure-seed@0.2.6

                      The insecure-seed interface for seeding hash-map DoS resistance.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index 716539569..6d3cc83f5 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.5; +package wasi:cli@0.2.6; @since(version = 0.2.0) world command { diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index a1dc926b0..edb40382d 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,24 +1,24 @@ [clocks] -sha256 = "f1c53079469e20167e2cd4300651f13f34a6fd508b5c7331bb7c8c95fb8857fb" -sha512 = "2a9281d0edcabad3bfef0dcfa7a9712d6beb6d6bb07b29fbf24235706d149672901ffc32192404a1ac511c512eb775daf9716ad3a0514bdf6a5c93a5fed19450" +sha256 = "59b8db7b6f3f8a72418510453c1fa9e437c7c7c2369c0bd5da83aa5d6d1d9b73" +sha512 = "06ce14bbf34d5588ed0c26bd932d46b3025c16723d5b4558def5b8107781b2251471c1f7170640342e3d4f78efb560d5ff6383c6a127c1d9e757e83db31a0185" [filesystem] -url = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.5.tar.gz" -sha256 = "9122d926d1e9c8c3c1aca0b54fcc6a64fe3b52b701d266af5ecbb7f83124a647" -sha512 = "a8e81ca42f4ff9d58dca945cabbcdf04b7a9870b7acd3bb95c95e40bb656e74c7e190f73cf0b3189b6b01a78f3aaa2e247c215541a7a0f67fb86ed3e0b3f9e35" +url = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.6.tar.gz" +sha256 = "9eb3e27ea559c679e9fb3c775a7091efedd0dc52aec56d7cd28caba36a76309c" +sha512 = "4207a911dd647ecbe82727af2145d88fc536f013ef76fc173d7d07729c71e9ff8c08ce911f25fa8511705d62e60d4888c5cc43d498cd3753b164bbe1be2d3a55" deps = ["clocks", "io"] [io] -sha256 = "749de54c05f7118dc118999ad69c5b63890ea1dd86f1be69270062195c7b79c2" -sha512 = "b5096d518a7931c100594b9216bb4a98cd64533166bc7fdbb7465b48effc345863bd3ce2ec84fef59b273bae507edab08ec08975d56240ccef68f2494964e80a" +sha256 = "671761f464d312e6c26bcaab5e79fe14ac876b72267867579d5c65e053fe2301" +sha512 = "57e5ed34fa85f35899b324ac7a2473c5fa5cece51d07e6f077637191fadd3c8b6f79324d31a8d497a6ce7b92cfb2a2505ab894337e2c82889f1bdb21f4f24634" [random] -url = "https://github.com/WebAssembly/wasi-random/archive/v0.2.5.tar.gz" -sha256 = "c59984d9385d1ef7af6dd817b3d7a0a7f4084baa66c92026d6f9bf1eaf29169a" -sha512 = "7414a1a0616e42ff134ad15b65d9e10bc3b567b34f7f696356e20bc71bcb85ea16188d26d1997ba7e6964df9493f9f748304acaf1169e16ee21a035d8a8b4a89" +url = "https://github.com/WebAssembly/wasi-random/archive/v0.2.6.tar.gz" +sha256 = "5fc77fdcbf6fc236250c5ba32149ea2fde7a8191696d9a4ed3931bb07202bcc0" +sha512 = "1f3be8d65185552abad4532ed4603643b3f9eed1847d4c1acaec107964701990f18b1a036dcdccead85c29f037f272b3d1ce300c6e4316002b36431c04c00abd" [sockets] -url = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.5.tar.gz" -sha256 = "1e55b9b6aa43e02cc0a674e7e6250f5145d48ffbc60c0f200b5ea192dce61640" -sha512 = "019224bb6fead5b6b687aeba7505ed05ebf20b9a60d045a4ab4fc323d0044af729b983b44efbe7ac8e0efda727f5c779fb0ad817c7802b2d7677196cf2cc0652" +url = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.6.tar.gz" +sha256 = "4f98b623cb6ff6f02c2975cea615fa36de2087dc48e76c4865e0297499c005a1" +sha512 = "cf72b97c46913e752dff2d1c93d2c9bd87210d5714fe43d4eb93fb7512b1c786737e69b444521e77725e12a2689673da786bd0f3f94ce77bf7772671637d7878" deps = ["clocks", "io"] diff --git a/proposals/cli/wit/deps.toml b/proposals/cli/wit/deps.toml index 26c0dbb5f..f7a7430fb 100644 --- a/proposals/cli/wit/deps.toml +++ b/proposals/cli/wit/deps.toml @@ -1,3 +1,3 @@ -filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.5.tar.gz" -random = "https://github.com/WebAssembly/wasi-random/archive/v0.2.5.tar.gz" -sockets = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.5.tar.gz" +filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.6.tar.gz" +random = "https://github.com/WebAssembly/wasi-random/archive/v0.2.6.tar.gz" +sockets = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.6.tar.gz" diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index 731e8a1e0..f3bc83912 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.5; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.6.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/cli/wit/deps/clocks/timezone.wit b/proposals/cli/wit/deps/clocks/timezone.wit index ebe21a6e8..ca98ad152 100644 --- a/proposals/cli/wit/deps/clocks/timezone.wit +++ b/proposals/cli/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit index 2fde831bd..76636a0c9 100644 --- a/proposals/cli/wit/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/cli/wit/deps/clocks/world.wit b/proposals/cli/wit/deps/clocks/world.wit index f32eed546..5c53c51a1 100644 --- a/proposals/cli/wit/deps/clocks/world.wit +++ b/proposals/cli/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/filesystem/preopens.wit b/proposals/cli/wit/deps/filesystem/preopens.wit index 0a9b8f054..f22847940 100644 --- a/proposals/cli/wit/deps/filesystem/preopens.wit +++ b/proposals/cli/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.5; +package wasi:filesystem@0.2.6; @since(version = 0.2.0) interface preopens { diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index 2b67884fb..75c19044c 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.5; +package wasi:filesystem@0.2.6; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.5; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.5.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.6.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.5.{datetime}; + use wasi:clocks/wall-clock@0.2.6.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit index e7654ee77..65597f9f2 100644 --- a/proposals/cli/wit/deps/filesystem/world.wit +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.5; +package wasi:filesystem@0.2.6; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/io/error.wit b/proposals/cli/wit/deps/io/error.wit index 0e234bebd..784f74a53 100644 --- a/proposals/cli/wit/deps/io/error.wit +++ b/proposals/cli/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; @since(version = 0.2.0) interface error { diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit index d33353e2a..7f711836c 100644 --- a/proposals/cli/wit/deps/io/poll.wit +++ b/proposals/cli/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index 8d20252f8..c5da38c86 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/cli/wit/deps/io/world.wit b/proposals/cli/wit/deps/io/world.wit index 686418343..84c85c08e 100644 --- a/proposals/cli/wit/deps/io/world.wit +++ b/proposals/cli/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/random/insecure-seed.wit b/proposals/cli/wit/deps/random/insecure-seed.wit index ab58b46c1..d3dc03a6c 100644 --- a/proposals/cli/wit/deps/random/insecure-seed.wit +++ b/proposals/cli/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.5; +package wasi:random@0.2.6; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/insecure.wit b/proposals/cli/wit/deps/random/insecure.wit index f05130392..d4d028480 100644 --- a/proposals/cli/wit/deps/random/insecure.wit +++ b/proposals/cli/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.5; +package wasi:random@0.2.6; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index 6b751b031..a0ff95646 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.5; +package wasi:random@0.2.6; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/world.wit b/proposals/cli/wit/deps/random/world.wit index c32c48a96..099f47b36 100644 --- a/proposals/cli/wit/deps/random/world.wit +++ b/proposals/cli/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.5; +package wasi:random@0.2.6; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index 04ab05d1e..ee6419e7d 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.6.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit index 52c830165..6ca98b63b 100644 --- a/proposals/cli/wit/deps/sockets/network.wit +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.5.{error}; + use wasi:io/error@0.2.6.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index 2f4478511..beefd7b46 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.5.{input-stream, output-stream}; + use wasi:io/streams@0.2.6.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.6.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.5.{duration}; + use wasi:clocks/monotonic-clock@0.2.6.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index 9a73a4713..9dbe6932d 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.6.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit index 733dc07b1..e86f02cec 100644 --- a/proposals/cli/wit/deps/sockets/world.wit +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.5; +package wasi:sockets@0.2.6; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/imports.wit b/proposals/cli/wit/imports.wit index 93a83742f..d9fd01710 100644 --- a/proposals/cli/wit/imports.wit +++ b/proposals/cli/wit/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.5; +package wasi:cli@0.2.6; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.5; + include wasi:clocks/imports@0.2.6; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.5; + include wasi:filesystem/imports@0.2.6; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.5; + include wasi:sockets/imports@0.2.6; @since(version = 0.2.0) - include wasi:random/imports@0.2.5; + include wasi:random/imports@0.2.6; @since(version = 0.2.0) - include wasi:io/imports@0.2.5; + include wasi:io/imports@0.2.6; @since(version = 0.2.0) import environment; diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index 19a5ab9da..cb8aea2d9 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.5.{input-stream}; + use wasi:io/streams@0.2.6.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.5.{output-stream}; + use wasi:io/streams@0.2.6.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.5.{output-stream}; + use wasi:io/streams@0.2.6.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; From 088ba12bd5d578d27203dbfd6179d608d073dd1d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Jun 2025 21:51:41 +0000 Subject: [PATCH 1672/1772] Update to v0.2.6 --- proposals/http/imports.md | 44 ++++++++--------- proposals/http/proxy.md | 48 +++++++++---------- proposals/http/wit/deps.lock | 26 +++++----- proposals/http/wit/deps.toml | 2 +- proposals/http/wit/deps/cli/command.wit | 2 +- proposals/http/wit/deps/cli/imports.wit | 12 ++--- proposals/http/wit/deps/cli/stdio.wit | 6 +-- .../http/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/http/wit/deps/clocks/timezone.wit | 2 +- proposals/http/wit/deps/clocks/wall-clock.wit | 2 +- proposals/http/wit/deps/clocks/world.wit | 2 +- .../http/wit/deps/filesystem/preopens.wit | 2 +- proposals/http/wit/deps/filesystem/types.wit | 6 +-- proposals/http/wit/deps/filesystem/world.wit | 2 +- proposals/http/wit/deps/io/error.wit | 2 +- proposals/http/wit/deps/io/poll.wit | 2 +- proposals/http/wit/deps/io/streams.wit | 2 +- proposals/http/wit/deps/io/world.wit | 2 +- .../http/wit/deps/random/insecure-seed.wit | 2 +- proposals/http/wit/deps/random/insecure.wit | 2 +- proposals/http/wit/deps/random/random.wit | 2 +- proposals/http/wit/deps/random/world.wit | 2 +- .../http/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/http/wit/deps/sockets/network.wit | 2 +- proposals/http/wit/deps/sockets/tcp.wit | 6 +-- proposals/http/wit/deps/sockets/udp.wit | 2 +- proposals/http/wit/deps/sockets/world.wit | 2 +- proposals/http/wit/proxy.wit | 14 +++--- proposals/http/wit/types.wit | 8 ++-- 29 files changed, 106 insertions(+), 106 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index 0bfacf439..09b77ed94 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -4,21 +4,21 @@ It is intended to be included in other worlds.

                      -

                      Import interface wasi:io/poll@0.2.5

                      +

                      Import interface wasi:io/poll@0.2.6

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -71,7 +71,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.5

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.6

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -130,7 +130,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.5

                      +

                      Import interface wasi:clocks/wall-clock@0.2.6

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -171,7 +171,7 @@ also known as Unix Time.
                    290. datetime
                    291. -

                      Import interface wasi:random/random@0.2.5

                      +

                      Import interface wasi:random/random@0.2.6

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -204,7 +204,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:io/error@0.2.5

                      +

                      Import interface wasi:io/error@0.2.6


                      Types

                      resource error

                      @@ -237,7 +237,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/streams@0.2.5

                      +

                      Import interface wasi:io/streams@0.2.6

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -567,7 +567,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.5

                      +

                      Import interface wasi:cli/stdout@0.2.6


                      Types

                      type output-stream

                      @@ -580,7 +580,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.5

                      +

                      Import interface wasi:cli/stderr@0.2.6


                      Types

                      type output-stream

                      @@ -593,7 +593,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.5

                      +

                      Import interface wasi:cli/stdin@0.2.6


                      Types

                      type input-stream

                      @@ -606,7 +606,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:http/types@0.2.5

                      +

                      Import interface wasi:http/types@0.2.6

                      This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                      @@ -1526,7 +1526,7 @@ but those will be reported by the incoming-body
                    292. option<result<result<own<incoming-response>, error-code>>>
                    293. -

                      Import interface wasi:http/outgoing-handler@0.2.5

                      +

                      Import interface wasi:http/outgoing-handler@0.2.6

                      This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                      diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 3c4d2340b..e099d46d6 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -6,26 +6,26 @@ outgoing HTTP requests.

                      -

                      Import interface wasi:io/poll@0.2.5

                      +

                      Import interface wasi:io/poll@0.2.6

                      A poll API intended to let users wait for I/O events on multiple handles at once.


                      @@ -78,7 +78,7 @@ being ready for I/O.

                      • list<u32>
                      -

                      Import interface wasi:clocks/monotonic-clock@0.2.5

                      +

                      Import interface wasi:clocks/monotonic-clock@0.2.6

                      WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                      It is intended to be portable at least between Unix-family platforms and @@ -137,7 +137,7 @@ elapsed from the time this function is invoked.

                      -

                      Import interface wasi:clocks/wall-clock@0.2.5

                      +

                      Import interface wasi:clocks/wall-clock@0.2.6

                      WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                      @@ -178,7 +178,7 @@ also known as Unix Time.
                    294. datetime
                    295. -

                      Import interface wasi:random/random@0.2.5

                      +

                      Import interface wasi:random/random@0.2.6

                      WASI Random is a random data API.

                      It is intended to be portable at least between Unix-family platforms and Windows.

                      @@ -211,7 +211,7 @@ represented as a u64.

                      • u64
                      -

                      Import interface wasi:io/error@0.2.5

                      +

                      Import interface wasi:io/error@0.2.6


                      Types

                      resource error

                      @@ -244,7 +244,7 @@ hazard.

                      • string
                      -

                      Import interface wasi:io/streams@0.2.5

                      +

                      Import interface wasi:io/streams@0.2.6

                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                      In the future, the component model is expected to add built-in stream types; @@ -574,7 +574,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdout@0.2.5

                      +

                      Import interface wasi:cli/stdout@0.2.6


                      Types

                      type output-stream

                      @@ -587,7 +587,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stderr@0.2.5

                      +

                      Import interface wasi:cli/stderr@0.2.6


                      Types

                      type output-stream

                      @@ -600,7 +600,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:cli/stdin@0.2.5

                      +

                      Import interface wasi:cli/stdin@0.2.6


                      Types

                      type input-stream

                      @@ -613,7 +613,7 @@ is ready for reading, before performing the splice.

                      -

                      Import interface wasi:http/types@0.2.5

                      +

                      Import interface wasi:http/types@0.2.6

                      This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                      @@ -1533,7 +1533,7 @@ but those will be reported by the incoming-body
                    296. option<result<result<own<incoming-response>, error-code>>>
                    297. -

                      Import interface wasi:http/outgoing-handler@0.2.5

                      +

                      Import interface wasi:http/outgoing-handler@0.2.6

                      This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                      @@ -1570,7 +1570,7 @@ through the future-incoming-response
                    298. result<own<future-incoming-response>, error-code>
                    299. -

                      Export interface wasi:http/incoming-handler@0.2.5

                      +

                      Export interface wasi:http/incoming-handler@0.2.6


                      Types

                      type incoming-request

                      diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index d7e6e7f3e..73bb8a09f 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,25 +1,25 @@ [cli] -url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.5.tar.gz" -sha256 = "b65ce8f20c1cfcb874a0083a589c77408188b641a1dfa12cd76158195844f5bd" -sha512 = "f6ce6a3416aa359111f2bf187d23459eef128c623e492f5c56da81099b8fd4bbd6db7274d0093fd70ae9077c812e58e5b221e55e68cd1e815b63b69334789ed8" +url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.6.tar.gz" +sha256 = "e5f2192aeeaa5ca23d584bf1773c126fac268cbc76361a79b3a5afe9d90d4602" +sha512 = "a4d968bd023483a089df7988543aa7ab4817e16d5bb1d99e9f2fcb7811eca2a25e5b7687f6a990c1373c204150eac941d53d50edb23169f3b07eab37b8358c7f" deps = ["clocks", "filesystem", "io", "random", "sockets"] [clocks] -sha256 = "f1c53079469e20167e2cd4300651f13f34a6fd508b5c7331bb7c8c95fb8857fb" -sha512 = "2a9281d0edcabad3bfef0dcfa7a9712d6beb6d6bb07b29fbf24235706d149672901ffc32192404a1ac511c512eb775daf9716ad3a0514bdf6a5c93a5fed19450" +sha256 = "59b8db7b6f3f8a72418510453c1fa9e437c7c7c2369c0bd5da83aa5d6d1d9b73" +sha512 = "06ce14bbf34d5588ed0c26bd932d46b3025c16723d5b4558def5b8107781b2251471c1f7170640342e3d4f78efb560d5ff6383c6a127c1d9e757e83db31a0185" [filesystem] -sha256 = "9122d926d1e9c8c3c1aca0b54fcc6a64fe3b52b701d266af5ecbb7f83124a647" -sha512 = "a8e81ca42f4ff9d58dca945cabbcdf04b7a9870b7acd3bb95c95e40bb656e74c7e190f73cf0b3189b6b01a78f3aaa2e247c215541a7a0f67fb86ed3e0b3f9e35" +sha256 = "9eb3e27ea559c679e9fb3c775a7091efedd0dc52aec56d7cd28caba36a76309c" +sha512 = "4207a911dd647ecbe82727af2145d88fc536f013ef76fc173d7d07729c71e9ff8c08ce911f25fa8511705d62e60d4888c5cc43d498cd3753b164bbe1be2d3a55" [io] -sha256 = "749de54c05f7118dc118999ad69c5b63890ea1dd86f1be69270062195c7b79c2" -sha512 = "b5096d518a7931c100594b9216bb4a98cd64533166bc7fdbb7465b48effc345863bd3ce2ec84fef59b273bae507edab08ec08975d56240ccef68f2494964e80a" +sha256 = "671761f464d312e6c26bcaab5e79fe14ac876b72267867579d5c65e053fe2301" +sha512 = "57e5ed34fa85f35899b324ac7a2473c5fa5cece51d07e6f077637191fadd3c8b6f79324d31a8d497a6ce7b92cfb2a2505ab894337e2c82889f1bdb21f4f24634" [random] -sha256 = "c59984d9385d1ef7af6dd817b3d7a0a7f4084baa66c92026d6f9bf1eaf29169a" -sha512 = "7414a1a0616e42ff134ad15b65d9e10bc3b567b34f7f696356e20bc71bcb85ea16188d26d1997ba7e6964df9493f9f748304acaf1169e16ee21a035d8a8b4a89" +sha256 = "5fc77fdcbf6fc236250c5ba32149ea2fde7a8191696d9a4ed3931bb07202bcc0" +sha512 = "1f3be8d65185552abad4532ed4603643b3f9eed1847d4c1acaec107964701990f18b1a036dcdccead85c29f037f272b3d1ce300c6e4316002b36431c04c00abd" [sockets] -sha256 = "1e55b9b6aa43e02cc0a674e7e6250f5145d48ffbc60c0f200b5ea192dce61640" -sha512 = "019224bb6fead5b6b687aeba7505ed05ebf20b9a60d045a4ab4fc323d0044af729b983b44efbe7ac8e0efda727f5c779fb0ad817c7802b2d7677196cf2cc0652" +sha256 = "4f98b623cb6ff6f02c2975cea615fa36de2087dc48e76c4865e0297499c005a1" +sha512 = "cf72b97c46913e752dff2d1c93d2c9bd87210d5714fe43d4eb93fb7512b1c786737e69b444521e77725e12a2689673da786bd0f3f94ce77bf7772671637d7878" diff --git a/proposals/http/wit/deps.toml b/proposals/http/wit/deps.toml index 4e1cf2e1d..9f04d9e04 100644 --- a/proposals/http/wit/deps.toml +++ b/proposals/http/wit/deps.toml @@ -1 +1 @@ -cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.5.tar.gz" +cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.6.tar.gz" diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit index 716539569..6d3cc83f5 100644 --- a/proposals/http/wit/deps/cli/command.wit +++ b/proposals/http/wit/deps/cli/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.5; +package wasi:cli@0.2.6; @since(version = 0.2.0) world command { diff --git a/proposals/http/wit/deps/cli/imports.wit b/proposals/http/wit/deps/cli/imports.wit index 93a83742f..d9fd01710 100644 --- a/proposals/http/wit/deps/cli/imports.wit +++ b/proposals/http/wit/deps/cli/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.5; +package wasi:cli@0.2.6; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.5; + include wasi:clocks/imports@0.2.6; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.5; + include wasi:filesystem/imports@0.2.6; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.5; + include wasi:sockets/imports@0.2.6; @since(version = 0.2.0) - include wasi:random/imports@0.2.5; + include wasi:random/imports@0.2.6; @since(version = 0.2.0) - include wasi:io/imports@0.2.5; + include wasi:io/imports@0.2.6; @since(version = 0.2.0) import environment; diff --git a/proposals/http/wit/deps/cli/stdio.wit b/proposals/http/wit/deps/cli/stdio.wit index 19a5ab9da..cb8aea2d9 100644 --- a/proposals/http/wit/deps/cli/stdio.wit +++ b/proposals/http/wit/deps/cli/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.5.{input-stream}; + use wasi:io/streams@0.2.6.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.5.{output-stream}; + use wasi:io/streams@0.2.6.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.5.{output-stream}; + use wasi:io/streams@0.2.6.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index 731e8a1e0..f3bc83912 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.5; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.6.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/http/wit/deps/clocks/timezone.wit b/proposals/http/wit/deps/clocks/timezone.wit index ebe21a6e8..ca98ad152 100644 --- a/proposals/http/wit/deps/clocks/timezone.wit +++ b/proposals/http/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/http/wit/deps/clocks/wall-clock.wit b/proposals/http/wit/deps/clocks/wall-clock.wit index 2fde831bd..76636a0c9 100644 --- a/proposals/http/wit/deps/clocks/wall-clock.wit +++ b/proposals/http/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/http/wit/deps/clocks/world.wit b/proposals/http/wit/deps/clocks/world.wit index f32eed546..5c53c51a1 100644 --- a/proposals/http/wit/deps/clocks/world.wit +++ b/proposals/http/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.6; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/filesystem/preopens.wit b/proposals/http/wit/deps/filesystem/preopens.wit index 0a9b8f054..f22847940 100644 --- a/proposals/http/wit/deps/filesystem/preopens.wit +++ b/proposals/http/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.5; +package wasi:filesystem@0.2.6; @since(version = 0.2.0) interface preopens { diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index 2b67884fb..75c19044c 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.5; +package wasi:filesystem@0.2.6; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.5; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.5.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.6.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.5.{datetime}; + use wasi:clocks/wall-clock@0.2.6.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/http/wit/deps/filesystem/world.wit b/proposals/http/wit/deps/filesystem/world.wit index e7654ee77..65597f9f2 100644 --- a/proposals/http/wit/deps/filesystem/world.wit +++ b/proposals/http/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.5; +package wasi:filesystem@0.2.6; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/io/error.wit b/proposals/http/wit/deps/io/error.wit index 0e234bebd..784f74a53 100644 --- a/proposals/http/wit/deps/io/error.wit +++ b/proposals/http/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; @since(version = 0.2.0) interface error { diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/io/poll.wit index d33353e2a..7f711836c 100644 --- a/proposals/http/wit/deps/io/poll.wit +++ b/proposals/http/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index 8d20252f8..c5da38c86 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit index 686418343..84c85c08e 100644 --- a/proposals/http/wit/deps/io/world.wit +++ b/proposals/http/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.6; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/random/insecure-seed.wit b/proposals/http/wit/deps/random/insecure-seed.wit index ab58b46c1..d3dc03a6c 100644 --- a/proposals/http/wit/deps/random/insecure-seed.wit +++ b/proposals/http/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.5; +package wasi:random@0.2.6; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/insecure.wit b/proposals/http/wit/deps/random/insecure.wit index f05130392..d4d028480 100644 --- a/proposals/http/wit/deps/random/insecure.wit +++ b/proposals/http/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.5; +package wasi:random@0.2.6; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index 6b751b031..a0ff95646 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.5; +package wasi:random@0.2.6; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit index c32c48a96..099f47b36 100644 --- a/proposals/http/wit/deps/random/world.wit +++ b/proposals/http/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.5; +package wasi:random@0.2.6; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/sockets/ip-name-lookup.wit b/proposals/http/wit/deps/sockets/ip-name-lookup.wit index 04ab05d1e..ee6419e7d 100644 --- a/proposals/http/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.6.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/http/wit/deps/sockets/network.wit b/proposals/http/wit/deps/sockets/network.wit index 52c830165..6ca98b63b 100644 --- a/proposals/http/wit/deps/sockets/network.wit +++ b/proposals/http/wit/deps/sockets/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.5.{error}; + use wasi:io/error@0.2.6.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index 2f4478511..beefd7b46 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.5.{input-stream, output-stream}; + use wasi:io/streams@0.2.6.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.6.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.5.{duration}; + use wasi:clocks/monotonic-clock@0.2.6.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index 9a73a4713..9dbe6932d 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.6.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit index 733dc07b1..e86f02cec 100644 --- a/proposals/http/wit/deps/sockets/world.wit +++ b/proposals/http/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.5; +package wasi:sockets@0.2.6; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 7d7518a68..5bd9f9989 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,4 +1,4 @@ -package wasi:http@0.2.5; +package wasi:http@0.2.6; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. /// It is intended to be `include`d in other worlds. @@ -6,25 +6,25 @@ package wasi:http@0.2.5; world imports { /// HTTP proxies have access to time and randomness. @since(version = 0.2.0) - import wasi:clocks/monotonic-clock@0.2.5; + import wasi:clocks/monotonic-clock@0.2.6; @since(version = 0.2.0) - import wasi:clocks/wall-clock@0.2.5; + import wasi:clocks/wall-clock@0.2.6; @since(version = 0.2.0) - import wasi:random/random@0.2.5; + import wasi:random/random@0.2.6; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. @since(version = 0.2.0) - import wasi:cli/stdout@0.2.5; + import wasi:cli/stdout@0.2.6; @since(version = 0.2.0) - import wasi:cli/stderr@0.2.5; + import wasi:cli/stderr@0.2.6; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. @since(version = 0.2.0) - import wasi:cli/stdin@0.2.5; + import wasi:cli/stdin@0.2.6; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 239e7c418..c9f3cc4b9 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -4,13 +4,13 @@ @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.5.{duration}; + use wasi:clocks/monotonic-clock@0.2.6.{duration}; @since(version = 0.2.0) - use wasi:io/streams@0.2.5.{input-stream, output-stream}; + use wasi:io/streams@0.2.6.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/error@0.2.5.{error as io-error}; + use wasi:io/error@0.2.6.{error as io-error}; @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.6.{pollable}; /// This type corresponds to HTTP standard Methods. @since(version = 0.2.0) From 9208c5361d0b00572f52c8b27d0cd2fd728e2b06 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 19 Jun 2025 09:48:26 -0700 Subject: [PATCH 1673/1772] output-stream: clarify semantics of blocking-write-and-flush (#112) * output-stream: clarify semantics of blocking-write-and-flush Closes https://github.com/WebAssembly/wasi-io/issues/109 * generate md --- proposals/io/imports.md | 46 +++++++-------------------------- proposals/io/wit/streams.wit | 50 +++++++----------------------------- 2 files changed, 18 insertions(+), 78 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index f9a4f22ed..57fc87c87 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -267,25 +267,13 @@ the last call to check-write provided a permit.

                      [method]output-stream.blocking-write-and-flush: func

                      Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                      -

                      This is a convenience wrapper around the use of check-write, -subscribe, write, and flush, and is implemented with the -following pseudo-code:

                      -
                      let pollable = this.subscribe();
                      -while !contents.is_empty() {
                      -  // Wait for the stream to become writable
                      -  pollable.block();
                      -  let Ok(n) = this.check-write(); // eliding error handling
                      -  let len = min(n, contents.len());
                      -  let (chunk, rest) = contents.split_at(len);
                      -  this.write(chunk  );            // eliding error handling
                      -  contents = rest;
                      -}
                      -this.flush();
                      -// Wait for completion of `flush`
                      -pollable.block();
                      -// Check for any errors that arose during `flush`
                      -let _ = this.check-write();         // eliding error handling
                      -
                      +

                      Returns success when all of the contents written are successfully +flushed to output. If an error occurs at any point before all +contents are successfully flushed, that error is returned as soon as +possible. If writing and flushing the complete contents causes the +stream to become closed, this call should return success, and +subsequent calls to check-write or other interfaces should return +stream-error::closed.

                      Params
                      • self: borrow<output-stream>
                      • @@ -359,24 +347,8 @@ that should be written.

                        Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                        -

                        This is a convenience wrapper around the use of check-write, -subscribe, write-zeroes, and flush, and is implemented with -the following pseudo-code:

                        -
                        let pollable = this.subscribe();
                        -while num_zeroes != 0 {
                        -  // Wait for the stream to become writable
                        -  pollable.block();
                        -  let Ok(n) = this.check-write(); // eliding error handling
                        -  let len = min(n, num_zeroes);
                        -  this.write-zeroes(len);         // eliding error handling
                        -  num_zeroes -= len;
                        -}
                        -this.flush();
                        -// Wait for completion of `flush`
                        -pollable.block();
                        -// Check for any errors that arose during `flush`
                        -let _ = this.check-write();         // eliding error handling
                        -
                        +

                        Functionality is equivelant to blocking-write-and-flush with +contents given as a list of len containing only zeroes.

                        Params
                        • self: borrow<output-stream>
                        • diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index c5da38c86..af0fcf481 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -154,27 +154,13 @@ interface streams { /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write`, and `flush`, and is implemented with the - /// following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while !contents.is_empty() { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, contents.len()); - /// let (chunk, rest) = contents.split_at(len); - /// this.write(chunk ); // eliding error handling - /// contents = rest; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` + /// Returns success when all of the contents written are successfully + /// flushed to output. If an error occurs at any point before all + /// contents are successfully flushed, that error is returned as soon as + /// possible. If writing and flushing the complete contents causes the + /// stream to become closed, this call should return success, and + /// subsequent calls to check-write or other interfaces should return + /// stream-error::closed. @since(version = 0.2.0) blocking-write-and-flush: func( contents: list @@ -227,26 +213,8 @@ interface streams { /// Block until all of these operations are complete, or an error /// occurs. /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with - /// the following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while num_zeroes != 0 { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, num_zeroes); - /// this.write-zeroes(len); // eliding error handling - /// num_zeroes -= len; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` + /// Functionality is equivelant to `blocking-write-and-flush` with + /// contents given as a list of len containing only zeroes. @since(version = 0.2.0) blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write From 6b4b048412b3ce040c56e5bd2b463b7494814cb8 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 18 Jul 2025 18:06:51 +0200 Subject: [PATCH 1674/1772] chore: mark async functions as such Signed-off-by: Roman Volosatovs --- proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit | 2 +- proposals/sockets/wit-0.3.0-draft/types.wit | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit index 7cc8b03e3..73b4b201f 100644 --- a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit +++ b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit @@ -58,5 +58,5 @@ interface ip-name-lookup { /// - /// - @since(version = 0.3.0) - resolve-addresses: func(name: string) -> result, error-code>; + resolve-addresses: async func(name: string) -> result, error-code>; } diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 156cc5026..86315314f 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -219,7 +219,7 @@ interface types { /// - /// - @since(version = 0.3.0) - connect: func(remote-address: ip-socket-address) -> result<_, error-code>; + connect: async func(remote-address: ip-socket-address) -> result<_, error-code>; /// Start listening return a stream of new inbound connections. /// @@ -309,7 +309,7 @@ interface types { /// - /// - @since(version = 0.3.0) - send: func(data: stream) -> result<_, error-code>; + send: async func(data: stream) -> result<_, error-code>; /// Read data from peer. /// @@ -624,7 +624,7 @@ interface types { /// - /// - @since(version = 0.3.0) - send: func(data: list, remote-address: option) -> result<_, error-code>; + send: async func(data: list, remote-address: option) -> result<_, error-code>; /// Receive a message on the socket. /// @@ -650,7 +650,7 @@ interface types { /// - /// - @since(version = 0.3.0) - receive: func() -> result, ip-socket-address>, error-code>; + receive: async func() -> result, ip-socket-address>, error-code>; /// Get the current bound address. /// From 9fbbaf5e3bcecf2aed3a5957151253ea20d02fa5 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 23 Jul 2025 02:10:13 +0200 Subject: [PATCH 1675/1772] chore: update WIT dependencies (#66) Signed-off-by: Roman Volosatovs --- proposals/cli/wit-0.3.0-draft/deps.lock | 4 ++-- proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/proposals/cli/wit-0.3.0-draft/deps.lock b/proposals/cli/wit-0.3.0-draft/deps.lock index 7cb659e99..350728a38 100644 --- a/proposals/cli/wit-0.3.0-draft/deps.lock +++ b/proposals/cli/wit-0.3.0-draft/deps.lock @@ -18,6 +18,6 @@ sha512 = "b99280fd60699f781f20209659e94c0058ce6b9e973ddbd0b8865d752f88c74633485d [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "48fa617cdf64b66adc7136e4f0c14886061e6d5134072bf8e1698b84e2579669" -sha512 = "786b8a03c14d3f529500275762a37c497ea1e6479e71028e8173aa07594beb77226904d77970a7c356ff3f59aa4a5c10f2e68537cc96b9916ff03a317b05a229" +sha256 = "a439ac477ff57f24331eb40989d50455b04cde0a12f235e88a5477614ea90264" +sha512 = "cf779c887fa401695215122621d7715aa5716f09dc94087887c93964fd454a146bc3b20c834e4a8e997ccb190910699a1a880e6caaaec25c32d941f9c26ba37f" deps = ["clocks"] diff --git a/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit b/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit index b5f84d360..456d4e5cc 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit @@ -328,7 +328,7 @@ interface types { /// were closed abnormally. /// /// If the caller is not expecting to receive any data from the peer, - /// they may cancel the receive task. Any data still in the receive queue + /// they may drop the stream. Any data still in the receive queue /// will be discarded. This is equivalent to calling `shutdown(SHUT_RD)` /// in POSIX. /// @@ -610,7 +610,6 @@ interface types { /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `connect`. (EISCONN) /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) - /// - `invalid-state`: The socket has not been bound yet. /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) /// - `connection-refused`: The connection was refused. (ECONNREFUSED) /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) From 405a878f724746e495d85b60f5987ffce9980630 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 23 Jul 2025 02:10:25 +0200 Subject: [PATCH 1676/1772] Add `get-*` prefix (#73) --- proposals/cli/wit-0.3.0-draft/environment.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/cli/wit-0.3.0-draft/environment.wit b/proposals/cli/wit-0.3.0-draft/environment.wit index d99dcc0ae..fb14eee67 100644 --- a/proposals/cli/wit-0.3.0-draft/environment.wit +++ b/proposals/cli/wit-0.3.0-draft/environment.wit @@ -18,5 +18,5 @@ interface environment { /// Return a path that programs should use as their initial current working /// directory, interpreting `.` as shorthand for this. @since(version = 0.3.0) - initial-cwd: func() -> option; + get-initial-cwd: func() -> option; } From ef09bd261f483e69b4ecdc9193388d34e3eacaf7 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Wed, 23 Jul 2025 17:11:52 +0200 Subject: [PATCH 1677/1772] Add `get-*` prefix to getters (#170) * Add `get-*` prefix * Prefix `header` & `options` as well. * Rename `entries` to `copy-all` to better indicate the associated cost. * Rename `body` to `consume-body` to better communicate that it is not a simple property and has side effects. --- proposals/http/wit-0.3.0-draft/types.wit | 44 +++++++++++++----------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index f0ba60536..7a072b640 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -216,10 +216,10 @@ interface types { /// /// The names and values are always returned in the original casing and in /// the order in which they will be serialized for transport. - entries: func() -> list>; + copy-all: func() -> list>; /// Make a deep copy of the Fields. Equivalent in behavior to calling the - /// `fields` constructor on the return value of `entries`. The resulting + /// `fields` constructor on the return value of `copy-all`. The resulting /// `fields` is mutable. clone: func() -> fields; } @@ -262,14 +262,14 @@ interface types { ) -> tuple>>; /// Get the Method for the Request. - method: func() -> method; + get-method: func() -> method; /// Set the Method for the Request. Fails if the string present in a /// `method.other` argument is not a syntactically valid method. set-method: func(method: method) -> result; /// Get the combination of the HTTP Path and Query for the Request. When /// `none`, this represents an empty Path and empty Query. - path-with-query: func() -> option; + get-path-with-query: func() -> option; /// Set the combination of the HTTP Path and Query for the Request. When /// `none`, this represents an empty Path and empty Query. Fails is the /// string given is not a syntactically valid path and query uri component. @@ -277,7 +277,7 @@ interface types { /// Get the HTTP Related Scheme for the Request. When `none`, the /// implementation may choose an appropriate default scheme. - scheme: func() -> option; + get-scheme: func() -> option; /// Set the HTTP Related Scheme for the Request. When `none`, the /// implementation may choose an appropriate default scheme. Fails if the /// string given is not a syntactically valid uri scheme. @@ -286,7 +286,7 @@ interface types { /// Get the authority of the Request's target URI. A value of `none` may be used /// with Related Schemes which do not require an authority. The HTTP and /// HTTPS schemes always require an authority. - authority: func() -> option; + get-authority: func() -> option; /// Set the authority of the Request's target URI. A value of `none` may be used /// with Related Schemes which do not require an authority. The HTTP and /// HTTPS schemes always require an authority. Fails if the string given is @@ -301,19 +301,19 @@ interface types { /// This `request-options` resource is a child: it must be dropped before /// the parent `request` is dropped, or its ownership is transferred to /// another component by e.g. `handler.handle`. - options: func() -> option; + get-options: func() -> option; /// Get the headers associated with the Request. /// /// The returned `headers` resource is immutable: `set`, `append`, and /// `delete` operations will fail with `header-error.immutable`. - headers: func() -> headers; + get-headers: func() -> headers; /// Get body of the Request. /// /// Stream returned by this method represents the contents of the body. - /// Once the stream is reported as closed, callers should await the returned future - /// to determine whether the body was received successfully. + /// Once the stream is reported as closed, callers should await the returned + /// future to determine whether the body was received successfully. /// The future will only resolve after the stream is reported as closed. /// /// The stream and future returned by this method are children: @@ -327,8 +327,9 @@ interface types { /// - a stream or future returned by a previous call to this method is still open /// - a stream returned by a previous call to this method has reported itself as closed /// Thus there will always be at most one readable stream open for a given body. - /// Each subsequent stream picks up where the last stream left off, up until it is finished. - body: func() -> result, future, error-code>>>>; + /// Each subsequent stream picks up where the previous one left off, + /// continuing until the entire body has been consumed. + consume-body: func() -> result, future, error-code>>>>; } /// Parameters for making an HTTP Request. Each of these parameters is @@ -342,7 +343,7 @@ interface types { constructor(); /// The timeout for the initial connect to the HTTP Server. - connect-timeout: func() -> option; + get-connect-timeout: func() -> option; /// Set the timeout for the initial connect to the HTTP Server. An error /// return value indicates that this timeout is not supported or that this @@ -350,7 +351,7 @@ interface types { set-connect-timeout: func(duration: option) -> result<_, request-options-error>; /// The timeout for receiving the first byte of the Response body. - first-byte-timeout: func() -> option; + get-first-byte-timeout: func() -> option; /// Set the timeout for receiving the first byte of the Response body. An /// error return value indicates that this timeout is not supported or that @@ -359,7 +360,7 @@ interface types { /// The timeout for receiving subsequent chunks of bytes in the Response /// body stream. - between-bytes-timeout: func() -> option; + get-between-bytes-timeout: func() -> option; /// Set the timeout for receiving subsequent chunks of bytes in the Response /// body stream. An error return value indicates that this timeout is not @@ -397,7 +398,7 @@ interface types { ) -> tuple>>; /// Get the HTTP Status Code for the Response. - status-code: func() -> status-code; + get-status-code: func() -> status-code; /// Set the HTTP Status Code for the Response. Fails if the status-code /// given is not a valid http status code. @@ -407,13 +408,13 @@ interface types { /// /// The returned `headers` resource is immutable: `set`, `append`, and /// `delete` operations will fail with `header-error.immutable`. - headers: func() -> headers; + get-headers: func() -> headers; /// Get body of the Response. /// /// Stream returned by this method represents the contents of the body. - /// Once the stream is reported as closed, callers should await the returned future - /// to determine whether the body was received successfully. + /// Once the stream is reported as closed, callers should await the returned + /// future to determine whether the body was received successfully. /// The future will only resolve after the stream is reported as closed. /// /// The stream and future returned by this method are children: @@ -427,7 +428,8 @@ interface types { /// - a stream or future returned by a previous call to this method is still open /// - a stream returned by a previous call to this method has reported itself as closed /// Thus there will always be at most one readable stream open for a given body. - /// Each subsequent stream picks up where the last stream left off, up until it is finished. - body: func() -> result, future, error-code>>>>; + /// Each subsequent stream picks up where the previous one left off, + /// continuing until the entire body has been consumed. + consume-body: func() -> result, future, error-code>>>>; } } From 42c6a2af74d5ab435e0eca061ffe3672929e74ee Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Mon, 4 Aug 2025 21:48:21 +0200 Subject: [PATCH 1678/1772] Change constructors to fallible static methods. Socket creation may fail under certain conditions. WIT does not allow constructors to be fallible (yet). So this is changing socket creation to a static fallible method. Freeing up the resource's `constructor` for if/when fallible constructors have been implemented. --- proposals/sockets/wit-0.3.0-draft/types.wit | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 86315314f..23f9e2fa2 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -153,7 +153,7 @@ interface types { /// - /// - @since(version = 0.3.0) - constructor(address-family: ip-address-family); + new: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. /// @@ -512,7 +512,7 @@ interface types { /// - /// - @since(version = 0.3.0) - constructor(address-family: ip-address-family); + new: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. /// From 6ebe347add9636621e758c6d94da9d2d20b3dda6 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 31 Jul 2025 10:37:31 -0700 Subject: [PATCH 1679/1772] Add `async` annotation to 0.3.0-draft WITs Pulling in changes from wasip3-prototyping. --- .../filesystem/wit-0.3.0-draft/types.wit | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/proposals/filesystem/wit-0.3.0-draft/types.wit b/proposals/filesystem/wit-0.3.0-draft/types.wit index af3cb254c..03958752c 100644 --- a/proposals/filesystem/wit-0.3.0-draft/types.wit +++ b/proposals/filesystem/wit-0.3.0-draft/types.wit @@ -320,7 +320,7 @@ interface types { /// /// Note: This is similar to `pwrite` in POSIX. @since(version = 0.3.0) - write-via-stream: func( + write-via-stream: async func( /// Data to write data: stream, /// The offset within the file at which to start writing. @@ -336,13 +336,13 @@ interface types { /// /// Note: This is similar to `write` with `O_APPEND` in POSIX. @since(version = 0.3.0) - append-via-stream: func(data: stream) -> result<_, error-code>; + append-via-stream: async func(data: stream) -> result<_, error-code>; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. @since(version = 0.3.0) - advise: func( + advise: async func( /// The offset within the file to which the advisory applies. offset: filesize, /// The length of the region to which the advisory applies. @@ -358,7 +358,7 @@ interface types { /// /// Note: This is similar to `fdatasync` in POSIX. @since(version = 0.3.0) - sync-data: func() -> result<_, error-code>; + sync-data: async func() -> result<_, error-code>; /// Get flags associated with a descriptor. /// @@ -367,7 +367,7 @@ interface types { /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. @since(version = 0.3.0) - get-flags: func() -> result; + get-flags: async func() -> result; /// Get the dynamic type of a descriptor. /// @@ -380,14 +380,14 @@ interface types { /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. @since(version = 0.3.0) - get-type: func() -> result; + get-type: async func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. @since(version = 0.3.0) - set-size: func(size: filesize) -> result<_, error-code>; + set-size: async func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. /// @@ -395,7 +395,7 @@ interface types { /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. @since(version = 0.3.0) - set-times: func( + set-times: async func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, /// The desired values of the data modification timestamp. @@ -415,7 +415,7 @@ interface types { /// This function returns a future, which will resolve to an error code if /// reading full contents of the directory fails. @since(version = 0.3.0) - read-directory: func() -> tuple, future>>; + read-directory: async func() -> tuple, future>>; /// Synchronize the data and metadata of a file to disk. /// @@ -424,13 +424,13 @@ interface types { /// /// Note: This is similar to `fsync` in POSIX. @since(version = 0.3.0) - sync: func() -> result<_, error-code>; + sync: async func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. @since(version = 0.3.0) - create-directory-at: func( + create-directory-at: async func( /// The relative path at which to create the directory. path: string, ) -> result<_, error-code>; @@ -445,7 +445,7 @@ interface types { /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. @since(version = 0.3.0) - stat: func() -> result; + stat: async func() -> result; /// Return the attributes of a file or directory. /// @@ -455,7 +455,7 @@ interface types { /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. @since(version = 0.3.0) - stat-at: func( + stat-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, /// The relative path of the file or directory to inspect. @@ -469,7 +469,7 @@ interface types { /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. @since(version = 0.3.0) - set-times-at: func( + set-times-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, /// The relative path of the file or directory to operate on. @@ -488,7 +488,7 @@ interface types { /// /// Note: This is similar to `linkat` in POSIX. @since(version = 0.3.0) - link-at: func( + link-at: async func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, /// The relative source path from which to link. @@ -512,7 +512,7 @@ interface types { /// /// Note: This is similar to `openat` in POSIX. @since(version = 0.3.0) - open-at: func( + open-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, /// The relative path of the object to open. @@ -530,7 +530,7 @@ interface types { /// /// Note: This is similar to `readlinkat` in POSIX. @since(version = 0.3.0) - readlink-at: func( + readlink-at: async func( /// The relative path of the symbolic link from which to read. path: string, ) -> result; @@ -541,7 +541,7 @@ interface types { /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. @since(version = 0.3.0) - remove-directory-at: func( + remove-directory-at: async func( /// The relative path to a directory to remove. path: string, ) -> result<_, error-code>; @@ -550,7 +550,7 @@ interface types { /// /// Note: This is similar to `renameat` in POSIX. @since(version = 0.3.0) - rename-at: func( + rename-at: async func( /// The relative source path of the file or directory to rename. old-path: string, /// The base directory for `new-path`. @@ -566,7 +566,7 @@ interface types { /// /// Note: This is similar to `symlinkat` in POSIX. @since(version = 0.3.0) - symlink-at: func( + symlink-at: async func( /// The contents of the symbolic link. old-path: string, /// The relative destination path at which to create the symbolic link. @@ -578,7 +578,7 @@ interface types { /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. @since(version = 0.3.0) - unlink-file-at: func( + unlink-file-at: async func( /// The relative path to a file to unlink. path: string, ) -> result<_, error-code>; @@ -590,7 +590,7 @@ interface types { /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. @since(version = 0.3.0) - is-same-object: func(other: borrow) -> bool; + is-same-object: async func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred /// to by a descriptor. @@ -612,14 +612,14 @@ interface types { /// /// However, none of these is required. @since(version = 0.3.0) - metadata-hash: func() -> result; + metadata-hash: async func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. @since(version = 0.3.0) - metadata-hash-at: func( + metadata-hash-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, /// The relative path of the file or directory to inspect. From a88ea89038e81e79ef5c35f74a9d0f0ea8eaed1b Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sat, 28 Jun 2025 20:36:52 +0200 Subject: [PATCH 1680/1772] Add `get-*` prefix --- proposals/random/wit-0.3.0-draft/insecure-seed.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/random/wit-0.3.0-draft/insecure-seed.wit b/proposals/random/wit-0.3.0-draft/insecure-seed.wit index 4708d9049..86c988c2e 100644 --- a/proposals/random/wit-0.3.0-draft/insecure-seed.wit +++ b/proposals/random/wit-0.3.0-draft/insecure-seed.wit @@ -23,5 +23,5 @@ interface insecure-seed { /// called multiple times and potentially used for purposes other than DoS /// protection. @since(version = 0.3.0) - insecure-seed: func() -> tuple; + get-insecure-seed: func() -> tuple; } From f7d6db7352222b5433c19fc5d3fa71727e7b0bb7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 7 Feb 2025 16:50:38 -0800 Subject: [PATCH 1681/1772] Revise the documentation for WASI 0.3.0's descriptor::read. Similar to WebAssembly/wasi-sockets#112, revise the description of `read` to clarify the relationship between the `stream` and the `future`. --- proposals/filesystem/wit-0.3.0-draft/types.wit | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/proposals/filesystem/wit-0.3.0-draft/types.wit b/proposals/filesystem/wit-0.3.0-draft/types.wit index 03958752c..8b2ded238 100644 --- a/proposals/filesystem/wit-0.3.0-draft/types.wit +++ b/proposals/filesystem/wit-0.3.0-draft/types.wit @@ -297,8 +297,15 @@ interface types { /// Multiple read, write, and append streams may be active on the same open /// file and they do not interfere with each other. /// - /// This function returns a future, which will resolve to an error code if - /// reading full contents of the file fails. + /// This function returns a `stream` which provides the data received from the + /// file, and a `future` providing additional error information in case an + /// error is encountered. + /// + /// If no error is encountered, `stream.read` on the `stream` will return + /// `read-status::closed` with no `error-context` and the future resolves to + /// the value `ok`. If an error is encounttered, `stream.read` on the + /// `stream` returns `read-status::closed` with an `error-context` and the future + /// resolves to `err` with an `error-code`. /// /// Note: This is similar to `pread` in POSIX. @since(version = 0.3.0) From 24a22b249df10a84927bf82eaa69669ad308344f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 21 Jul 2025 18:28:59 -0700 Subject: [PATCH 1682/1772] Update wit-0.3.0-draft/types.wit Co-authored-by: Bailey Hayes --- proposals/filesystem/wit-0.3.0-draft/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/filesystem/wit-0.3.0-draft/types.wit b/proposals/filesystem/wit-0.3.0-draft/types.wit index 8b2ded238..b73b6759f 100644 --- a/proposals/filesystem/wit-0.3.0-draft/types.wit +++ b/proposals/filesystem/wit-0.3.0-draft/types.wit @@ -303,7 +303,7 @@ interface types { /// /// If no error is encountered, `stream.read` on the `stream` will return /// `read-status::closed` with no `error-context` and the future resolves to - /// the value `ok`. If an error is encounttered, `stream.read` on the + /// the value `ok`. If an error is encountered, `stream.read` on the /// `stream` returns `read-status::closed` with an `error-context` and the future /// resolves to `err` with an `error-code`. /// From ffe0165f376194f04d24d1e66638cf62d2cbe051 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Sat, 28 Jun 2025 20:39:24 +0200 Subject: [PATCH 1683/1772] Add `get-*` prefix --- proposals/sockets/wit-0.3.0-draft/types.wit | 40 ++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 86315314f..fcafd457e 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -221,7 +221,7 @@ interface types { @since(version = 0.3.0) connect: async func(remote-address: ip-socket-address) -> result<_, error-code>; - /// Start listening return a stream of new inbound connections. + /// Start listening and return a stream of new inbound connections. /// /// Transitions the socket into the `listening` state. This can be called /// at most once per socket. @@ -351,7 +351,7 @@ interface types { /// > If the socket has not been bound to a local name, the value /// > stored in the object pointed to by `address` is unspecified. /// - /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// WASI is stricter and requires `get-local-address` to return `invalid-state` when the socket hasn't been bound yet. /// /// # Typical errors /// - `invalid-state`: The socket is not bound to any local address. @@ -362,7 +362,7 @@ interface types { /// - /// - @since(version = 0.3.0) - local-address: func() -> result; + get-local-address: func() -> result; /// Get the remote address. /// @@ -375,13 +375,13 @@ interface types { /// - /// - @since(version = 0.3.0) - remote-address: func() -> result; + get-remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. @since(version = 0.3.0) - is-listening: func() -> bool; + get-is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. /// @@ -389,7 +389,7 @@ interface types { /// /// Equivalent to the SO_DOMAIN socket option. @since(version = 0.3.0) - address-family: func() -> ip-address-family; + get-address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. /// @@ -413,7 +413,7 @@ interface types { /// /// Equivalent to the SO_KEEPALIVE socket option. @since(version = 0.3.0) - keep-alive-enabled: func() -> result; + get-keep-alive-enabled: func() -> result; @since(version = 0.3.0) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; @@ -428,7 +428,7 @@ interface types { /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. @since(version = 0.3.0) - keep-alive-idle-time: func() -> result; + get-keep-alive-idle-time: func() -> result; @since(version = 0.3.0) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; @@ -443,7 +443,7 @@ interface types { /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. @since(version = 0.3.0) - keep-alive-interval: func() -> result; + get-keep-alive-interval: func() -> result; @since(version = 0.3.0) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; @@ -458,7 +458,7 @@ interface types { /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. @since(version = 0.3.0) - keep-alive-count: func() -> result; + get-keep-alive-count: func() -> result; @since(version = 0.3.0) set-keep-alive-count: func(value: u32) -> result<_, error-code>; @@ -469,7 +469,7 @@ interface types { /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. @since(version = 0.3.0) - hop-limit: func() -> result; + get-hop-limit: func() -> result; @since(version = 0.3.0) set-hop-limit: func(value: u8) -> result<_, error-code>; @@ -484,11 +484,11 @@ interface types { /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. @since(version = 0.3.0) - receive-buffer-size: func() -> result; + get-receive-buffer-size: func() -> result; @since(version = 0.3.0) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; @since(version = 0.3.0) - send-buffer-size: func() -> result; + get-send-buffer-size: func() -> result; @since(version = 0.3.0) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } @@ -658,7 +658,7 @@ interface types { /// > If the socket has not been bound to a local name, the value /// > stored in the object pointed to by `address` is unspecified. /// - /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// WASI is stricter and requires `get-local-address` to return `invalid-state` when the socket hasn't been bound yet. /// /// # Typical errors /// - `invalid-state`: The socket is not bound to any local address. @@ -669,7 +669,7 @@ interface types { /// - /// - @since(version = 0.3.0) - local-address: func() -> result; + get-local-address: func() -> result; /// Get the address the socket is currently "connected" to. /// @@ -682,7 +682,7 @@ interface types { /// - /// - @since(version = 0.3.0) - remote-address: func() -> result; + get-remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. /// @@ -690,7 +690,7 @@ interface types { /// /// Equivalent to the SO_DOMAIN socket option. @since(version = 0.3.0) - address-family: func() -> ip-address-family; + get-address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// @@ -699,7 +699,7 @@ interface types { /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. @since(version = 0.3.0) - unicast-hop-limit: func() -> result; + get-unicast-hop-limit: func() -> result; @since(version = 0.3.0) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; @@ -714,11 +714,11 @@ interface types { /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. @since(version = 0.3.0) - receive-buffer-size: func() -> result; + get-receive-buffer-size: func() -> result; @since(version = 0.3.0) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; @since(version = 0.3.0) - send-buffer-size: func() -> result; + get-send-buffer-size: func() -> result; @since(version = 0.3.0) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } From 2ae4911d9acabe7b326859f67695ec3f667872a2 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Tue, 12 Aug 2025 18:48:48 +0200 Subject: [PATCH 1684/1772] Update wit-0.3.0-draft/types.wit Co-authored-by: Bailey Hayes --- proposals/sockets/wit-0.3.0-draft/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 23f9e2fa2..f17e48c9c 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -153,7 +153,7 @@ interface types { /// - /// - @since(version = 0.3.0) - new: static func(address-family: ip-address-family) -> result; + create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. /// From 8ec88c2645e1523e6bfb9538afe5a7522cd08ae8 Mon Sep 17 00:00:00 2001 From: Dave Bakker Date: Tue, 12 Aug 2025 18:48:58 +0200 Subject: [PATCH 1685/1772] Update wit-0.3.0-draft/types.wit Co-authored-by: Bailey Hayes --- proposals/sockets/wit-0.3.0-draft/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index f17e48c9c..2b796dbfe 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -512,7 +512,7 @@ interface types { /// - /// - @since(version = 0.3.0) - new: static func(address-family: ip-address-family) -> result; + create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. /// From 46965d74f822a2e13155db67e952e4dbca4345e3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 19:26:01 +0200 Subject: [PATCH 1686/1772] Update to v0.2.7 (#113) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- proposals/io/imports.md | 12 ++++++------ proposals/io/wit/error.wit | 2 +- proposals/io/wit/poll.wit | 2 +- proposals/io/wit/streams.wit | 2 +- proposals/io/wit/world.wit | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index 57fc87c87..a64a3d09d 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -2,13 +2,13 @@ -

                          Import interface wasi:io/error@0.2.6

                          +

                          Import interface wasi:io/error@0.2.7


                          Types

                          resource error

                          @@ -41,7 +41,7 @@ hazard.

                          • string
                          -

                          Import interface wasi:io/poll@0.2.6

                          +

                          Import interface wasi:io/poll@0.2.7

                          A poll API intended to let users wait for I/O events on multiple handles at once.


                          @@ -94,7 +94,7 @@ being ready for I/O.

                          • list<u32>
                          -

                          Import interface wasi:io/streams@0.2.6

                          +

                          Import interface wasi:io/streams@0.2.7

                          WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                          In the future, the component model is expected to add built-in stream types; diff --git a/proposals/io/wit/error.wit b/proposals/io/wit/error.wit index 784f74a53..acab3a811 100644 --- a/proposals/io/wit/error.wit +++ b/proposals/io/wit/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; @since(version = 0.2.0) interface error { diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index 7f711836c..a525164b9 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index af0fcf481..7ae29a3cd 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index 84c85c08e..73b1a6df5 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; @since(version = 0.2.0) world imports { From f38ad9511a0a308843df89cc7c2ecf701da6071d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 17:31:49 +0000 Subject: [PATCH 1687/1772] Update to v0.2.7 --- proposals/random/imports.md | 12 ++++++------ proposals/random/wit/insecure-seed.wit | 2 +- proposals/random/wit/insecure.wit | 2 +- proposals/random/wit/random.wit | 2 +- proposals/random/wit/world.wit | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/random/imports.md b/proposals/random/imports.md index 8b180bf66..9e1d2f21c 100644 --- a/proposals/random/imports.md +++ b/proposals/random/imports.md @@ -2,13 +2,13 @@

                          -

                          Import interface wasi:random/random@0.2.6

                          +

                          Import interface wasi:random/random@0.2.7

                          WASI Random is a random data API.

                          It is intended to be portable at least between Unix-family platforms and Windows.

                          @@ -41,7 +41,7 @@ represented as a u64.

                          • u64
                          -

                          Import interface wasi:random/insecure@0.2.6

                          +

                          Import interface wasi:random/insecure@0.2.7

                          The insecure interface for insecure pseudo-random numbers.

                          It is intended to be portable at least between Unix-family platforms and Windows.

                          @@ -70,7 +70,7 @@ a long period.

                          • u64
                          -

                          Import interface wasi:random/insecure-seed@0.2.6

                          +

                          Import interface wasi:random/insecure-seed@0.2.7

                          The insecure-seed interface for seeding hash-map DoS resistance.

                          It is intended to be portable at least between Unix-family platforms and Windows.

                          diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index d3dc03a6c..0209b84b0 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.6; +package wasi:random@0.2.7; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index d4d028480..820d069ee 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.6; +package wasi:random@0.2.7; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index a0ff95646..974ab465d 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.6; +package wasi:random@0.2.7; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index 099f47b36..333b42598 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.6; +package wasi:random@0.2.7; @since(version = 0.2.0) world imports { From 964ada6ff21f2e8edf77b205ae829cd689b61620 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 17:53:32 +0000 Subject: [PATCH 1688/1772] Update to v0.2.7 --- proposals/filesystem/imports.md | 70 ++++++------------- proposals/filesystem/wit/deps.lock | 8 +-- .../wit/deps/clocks/monotonic-clock.wit | 4 +- .../filesystem/wit/deps/clocks/timezone.wit | 2 +- .../filesystem/wit/deps/clocks/wall-clock.wit | 2 +- .../filesystem/wit/deps/clocks/world.wit | 2 +- proposals/filesystem/wit/deps/io/error.wit | 2 +- proposals/filesystem/wit/deps/io/poll.wit | 2 +- proposals/filesystem/wit/deps/io/streams.wit | 52 +++----------- proposals/filesystem/wit/deps/io/world.wit | 2 +- proposals/filesystem/wit/preopens.wit | 2 +- proposals/filesystem/wit/types.wit | 6 +- proposals/filesystem/wit/world.wit | 2 +- 13 files changed, 48 insertions(+), 108 deletions(-) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index 29819b576..9a726c743 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -2,16 +2,16 @@ -

                          Import interface wasi:io/error@0.2.6

                          +

                          Import interface wasi:io/error@0.2.7


                          Types

                          resource error

                          @@ -44,7 +44,7 @@ hazard.

                          • string
                          -

                          Import interface wasi:io/poll@0.2.6

                          +

                          Import interface wasi:io/poll@0.2.7

                          A poll API intended to let users wait for I/O events on multiple handles at once.


                          @@ -97,7 +97,7 @@ being ready for I/O.

                          • list<u32>
                          -

                          Import interface wasi:io/streams@0.2.6

                          +

                          Import interface wasi:io/streams@0.2.7

                          WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                          In the future, the component model is expected to add built-in stream types; @@ -270,25 +270,13 @@ the last call to check-write provided a permit.

                          [method]output-stream.blocking-write-and-flush: func

                          Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                          -

                          This is a convenience wrapper around the use of check-write, -subscribe, write, and flush, and is implemented with the -following pseudo-code:

                          -
                          let pollable = this.subscribe();
                          -while !contents.is_empty() {
                          -  // Wait for the stream to become writable
                          -  pollable.block();
                          -  let Ok(n) = this.check-write(); // eliding error handling
                          -  let len = min(n, contents.len());
                          -  let (chunk, rest) = contents.split_at(len);
                          -  this.write(chunk  );            // eliding error handling
                          -  contents = rest;
                          -}
                          -this.flush();
                          -// Wait for completion of `flush`
                          -pollable.block();
                          -// Check for any errors that arose during `flush`
                          -let _ = this.check-write();         // eliding error handling
                          -
                          +

                          Returns success when all of the contents written are successfully +flushed to output. If an error occurs at any point before all +contents are successfully flushed, that error is returned as soon as +possible. If writing and flushing the complete contents causes the +stream to become closed, this call should return success, and +subsequent calls to check-write or other interfaces should return +stream-error::closed.

                          Params
                          • self: borrow<output-stream>
                          • @@ -362,24 +350,8 @@ that should be written.

                            Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                            -

                            This is a convenience wrapper around the use of check-write, -subscribe, write-zeroes, and flush, and is implemented with -the following pseudo-code:

                            -
                            let pollable = this.subscribe();
                            -while num_zeroes != 0 {
                            -  // Wait for the stream to become writable
                            -  pollable.block();
                            -  let Ok(n) = this.check-write(); // eliding error handling
                            -  let len = min(n, num_zeroes);
                            -  this.write-zeroes(len);         // eliding error handling
                            -  num_zeroes -= len;
                            -}
                            -this.flush();
                            -// Wait for completion of `flush`
                            -pollable.block();
                            -// Check for any errors that arose during `flush`
                            -let _ = this.check-write();         // eliding error handling
                            -
                            +

                            Functionality is equivelant to blocking-write-and-flush with +contents given as a list of len containing only zeroes.

                            Params
                            • self: borrow<output-stream>
                            • @@ -427,7 +399,7 @@ is ready for reading, before performing the splice.

                              -

                              Import interface wasi:clocks/wall-clock@0.2.6

                              +

                              Import interface wasi:clocks/wall-clock@0.2.7

                              WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                              @@ -468,7 +440,7 @@ also known as Unix Time.
                            • datetime
                            -

                            Import interface wasi:filesystem/types@0.2.6

                            +

                            Import interface wasi:filesystem/types@0.2.7

                            WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                            @@ -1346,7 +1318,7 @@ errors are filesystem-related errors.

                            -

                            Import interface wasi:filesystem/preopens@0.2.6

                            +

                            Import interface wasi:filesystem/preopens@0.2.7


                            Types

                            type descriptor

                            diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index 32cd8bf74..1d550cb8f 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "59b8db7b6f3f8a72418510453c1fa9e437c7c7c2369c0bd5da83aa5d6d1d9b73" -sha512 = "06ce14bbf34d5588ed0c26bd932d46b3025c16723d5b4558def5b8107781b2251471c1f7170640342e3d4f78efb560d5ff6383c6a127c1d9e757e83db31a0185" +sha256 = "d0a8d048c41b566b978cd8ecd03fa51ec1f65af4c26be2f0fc9cfdd7dd6f34f3" +sha512 = "8d1c9ddaaea70ae54376bfc02dcdd0437336fb4fc67f89763ce09540caefe84cbae89a8de3605aa7613c49188636e925047bcd150c2c60685850095fefb68b73" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "671761f464d312e6c26bcaab5e79fe14ac876b72267867579d5c65e053fe2301" -sha512 = "57e5ed34fa85f35899b324ac7a2473c5fa5cece51d07e6f077637191fadd3c8b6f79324d31a8d497a6ce7b92cfb2a2505ab894337e2c82889f1bdb21f4f24634" +sha256 = "62ae80f2e340cddbac8e94f78e6270735aea536367ecb98de5f4ac6aef66b5c4" +sha512 = "a02a1ebd261ae884b0315b3528d1a93819ddc4b616f66c77f2bea9dd1de888208dc3b9004a553363f5e8491ea925d65ebbd0d68eaa87238316b47469a3bf97bb" diff --git a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit index f3bc83912..98a9ad42a 100644 --- a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.6; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.6.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/filesystem/wit/deps/clocks/timezone.wit b/proposals/filesystem/wit/deps/clocks/timezone.wit index ca98ad152..4740bde00 100644 --- a/proposals/filesystem/wit/deps/clocks/timezone.wit +++ b/proposals/filesystem/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/filesystem/wit/deps/clocks/wall-clock.wit b/proposals/filesystem/wit/deps/clocks/wall-clock.wit index 76636a0c9..2179b6c56 100644 --- a/proposals/filesystem/wit/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/filesystem/wit/deps/clocks/world.wit b/proposals/filesystem/wit/deps/clocks/world.wit index 5c53c51a1..a08ff2c2c 100644 --- a/proposals/filesystem/wit/deps/clocks/world.wit +++ b/proposals/filesystem/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/filesystem/wit/deps/io/error.wit b/proposals/filesystem/wit/deps/io/error.wit index 784f74a53..acab3a811 100644 --- a/proposals/filesystem/wit/deps/io/error.wit +++ b/proposals/filesystem/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; @since(version = 0.2.0) interface error { diff --git a/proposals/filesystem/wit/deps/io/poll.wit b/proposals/filesystem/wit/deps/io/poll.wit index 7f711836c..a525164b9 100644 --- a/proposals/filesystem/wit/deps/io/poll.wit +++ b/proposals/filesystem/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index c5da38c86..7ae29a3cd 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -154,27 +154,13 @@ interface streams { /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write`, and `flush`, and is implemented with the - /// following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while !contents.is_empty() { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, contents.len()); - /// let (chunk, rest) = contents.split_at(len); - /// this.write(chunk ); // eliding error handling - /// contents = rest; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` + /// Returns success when all of the contents written are successfully + /// flushed to output. If an error occurs at any point before all + /// contents are successfully flushed, that error is returned as soon as + /// possible. If writing and flushing the complete contents causes the + /// stream to become closed, this call should return success, and + /// subsequent calls to check-write or other interfaces should return + /// stream-error::closed. @since(version = 0.2.0) blocking-write-and-flush: func( contents: list @@ -227,26 +213,8 @@ interface streams { /// Block until all of these operations are complete, or an error /// occurs. /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with - /// the following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while num_zeroes != 0 { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, num_zeroes); - /// this.write-zeroes(len); // eliding error handling - /// num_zeroes -= len; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` + /// Functionality is equivelant to `blocking-write-and-flush` with + /// contents given as a list of len containing only zeroes. @since(version = 0.2.0) blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write diff --git a/proposals/filesystem/wit/deps/io/world.wit b/proposals/filesystem/wit/deps/io/world.wit index 84c85c08e..73b1a6df5 100644 --- a/proposals/filesystem/wit/deps/io/world.wit +++ b/proposals/filesystem/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit index f22847940..b1a0a9972 100644 --- a/proposals/filesystem/wit/preopens.wit +++ b/proposals/filesystem/wit/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.6; +package wasi:filesystem@0.2.7; @since(version = 0.2.0) interface preopens { diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index 75c19044c..a7da2b72f 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.6; +package wasi:filesystem@0.2.7; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.6; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.6.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.7.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.6.{datetime}; + use wasi:clocks/wall-clock@0.2.7.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index 65597f9f2..67309b43f 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.6; +package wasi:filesystem@0.2.7; @since(version = 0.2.0) world imports { From 80c421f90ef0fa0b1f4044ff8d8ce68be67fab69 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 17:59:53 +0000 Subject: [PATCH 1689/1772] Update to v0.2.7 --- proposals/sockets/imports.md | 90 +++++++------------ proposals/sockets/wit/deps.lock | 8 +- .../wit/deps/clocks/monotonic-clock.wit | 4 +- .../sockets/wit/deps/clocks/timezone.wit | 2 +- .../sockets/wit/deps/clocks/wall-clock.wit | 2 +- proposals/sockets/wit/deps/clocks/world.wit | 2 +- proposals/sockets/wit/deps/io/error.wit | 2 +- proposals/sockets/wit/deps/io/poll.wit | 2 +- proposals/sockets/wit/deps/io/streams.wit | 52 +++-------- proposals/sockets/wit/deps/io/world.wit | 2 +- proposals/sockets/wit/ip-name-lookup.wit | 2 +- proposals/sockets/wit/network.wit | 2 +- proposals/sockets/wit/tcp.wit | 6 +- proposals/sockets/wit/udp.wit | 2 +- proposals/sockets/wit/world.wit | 2 +- 15 files changed, 60 insertions(+), 120 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index e81956b99..390830530 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -2,21 +2,21 @@ -

                            Import interface wasi:io/error@0.2.6

                            +

                            Import interface wasi:io/error@0.2.7


                            Types

                            resource error

                            @@ -49,7 +49,7 @@ hazard.

                            • string
                            -

                            Import interface wasi:sockets/network@0.2.6

                            +

                            Import interface wasi:sockets/network@0.2.7


                            Types

                            type error

                            @@ -264,7 +264,7 @@ errors are network-related errors.

                            -

                            Import interface wasi:sockets/instance-network@0.2.6

                            +

                            Import interface wasi:sockets/instance-network@0.2.7

                            This interface provides a value-export of the default network handle..


                            Types

                            @@ -279,7 +279,7 @@ errors are network-related errors.

                            -

                            Import interface wasi:io/poll@0.2.6

                            +

                            Import interface wasi:io/poll@0.2.7

                            A poll API intended to let users wait for I/O events on multiple handles at once.


                            @@ -332,7 +332,7 @@ being ready for I/O.

                            • list<u32>
                            -

                            Import interface wasi:sockets/udp@0.2.6

                            +

                            Import interface wasi:sockets/udp@0.2.7


                            Types

                            type pollable

                            @@ -746,7 +746,7 @@ It's planned to be removed when future is natively supported in Pre -

                            Import interface wasi:sockets/udp-create-socket@0.2.6

                            +

                            Import interface wasi:sockets/udp-create-socket@0.2.7


                            Types

                            type network

                            @@ -791,7 +791,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                            Import interface wasi:io/streams@0.2.6

                            +

                            Import interface wasi:io/streams@0.2.7

                            WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                            In the future, the component model is expected to add built-in stream types; @@ -964,25 +964,13 @@ the last call to check-write provided a permit.

                            [method]output-stream.blocking-write-and-flush: func

                            Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                            -

                            This is a convenience wrapper around the use of check-write, -subscribe, write, and flush, and is implemented with the -following pseudo-code:

                            -
                            let pollable = this.subscribe();
                            -while !contents.is_empty() {
                            -  // Wait for the stream to become writable
                            -  pollable.block();
                            -  let Ok(n) = this.check-write(); // eliding error handling
                            -  let len = min(n, contents.len());
                            -  let (chunk, rest) = contents.split_at(len);
                            -  this.write(chunk  );            // eliding error handling
                            -  contents = rest;
                            -}
                            -this.flush();
                            -// Wait for completion of `flush`
                            -pollable.block();
                            -// Check for any errors that arose during `flush`
                            -let _ = this.check-write();         // eliding error handling
                            -
                            +

                            Returns success when all of the contents written are successfully +flushed to output. If an error occurs at any point before all +contents are successfully flushed, that error is returned as soon as +possible. If writing and flushing the complete contents causes the +stream to become closed, this call should return success, and +subsequent calls to check-write or other interfaces should return +stream-error::closed.

                            Params
                            • self: borrow<output-stream>
                            • @@ -1056,24 +1044,8 @@ that should be written.

                              Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                              -

                              This is a convenience wrapper around the use of check-write, -subscribe, write-zeroes, and flush, and is implemented with -the following pseudo-code:

                              -
                              let pollable = this.subscribe();
                              -while num_zeroes != 0 {
                              -  // Wait for the stream to become writable
                              -  pollable.block();
                              -  let Ok(n) = this.check-write(); // eliding error handling
                              -  let len = min(n, num_zeroes);
                              -  this.write-zeroes(len);         // eliding error handling
                              -  num_zeroes -= len;
                              -}
                              -this.flush();
                              -// Wait for completion of `flush`
                              -pollable.block();
                              -// Check for any errors that arose during `flush`
                              -let _ = this.check-write();         // eliding error handling
                              -
                              +

                              Functionality is equivelant to blocking-write-and-flush with +contents given as a list of len containing only zeroes.

                              Params
                              • self: borrow<output-stream>
                              • @@ -1121,7 +1093,7 @@ is ready for reading, before performing the splice.

                                -

                                Import interface wasi:clocks/monotonic-clock@0.2.6

                                +

                                Import interface wasi:clocks/monotonic-clock@0.2.7

                                WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                                It is intended to be portable at least between Unix-family platforms and @@ -1180,7 +1152,7 @@ elapsed from the time this function is invoked.

                                -

                                Import interface wasi:sockets/tcp@0.2.6

                                +

                                Import interface wasi:sockets/tcp@0.2.7


                                Types

                                type input-stream

                                @@ -1771,7 +1743,7 @@ has no effect and returns ok.

                                -

                                Import interface wasi:sockets/tcp-create-socket@0.2.6

                                +

                                Import interface wasi:sockets/tcp-create-socket@0.2.7


                                Types

                                type network

                                @@ -1816,7 +1788,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                                Import interface wasi:sockets/ip-name-lookup@0.2.6

                                +

                                Import interface wasi:sockets/ip-name-lookup@0.2.7


                                Types

                                type pollable

                                diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index 32cd8bf74..1d550cb8f 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "59b8db7b6f3f8a72418510453c1fa9e437c7c7c2369c0bd5da83aa5d6d1d9b73" -sha512 = "06ce14bbf34d5588ed0c26bd932d46b3025c16723d5b4558def5b8107781b2251471c1f7170640342e3d4f78efb560d5ff6383c6a127c1d9e757e83db31a0185" +sha256 = "d0a8d048c41b566b978cd8ecd03fa51ec1f65af4c26be2f0fc9cfdd7dd6f34f3" +sha512 = "8d1c9ddaaea70ae54376bfc02dcdd0437336fb4fc67f89763ce09540caefe84cbae89a8de3605aa7613c49188636e925047bcd150c2c60685850095fefb68b73" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "671761f464d312e6c26bcaab5e79fe14ac876b72267867579d5c65e053fe2301" -sha512 = "57e5ed34fa85f35899b324ac7a2473c5fa5cece51d07e6f077637191fadd3c8b6f79324d31a8d497a6ce7b92cfb2a2505ab894337e2c82889f1bdb21f4f24634" +sha256 = "62ae80f2e340cddbac8e94f78e6270735aea536367ecb98de5f4ac6aef66b5c4" +sha512 = "a02a1ebd261ae884b0315b3528d1a93819ddc4b616f66c77f2bea9dd1de888208dc3b9004a553363f5e8491ea925d65ebbd0d68eaa87238316b47469a3bf97bb" diff --git a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit index f3bc83912..98a9ad42a 100644 --- a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.6; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.6.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/sockets/wit/deps/clocks/timezone.wit b/proposals/sockets/wit/deps/clocks/timezone.wit index ca98ad152..4740bde00 100644 --- a/proposals/sockets/wit/deps/clocks/timezone.wit +++ b/proposals/sockets/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/sockets/wit/deps/clocks/wall-clock.wit b/proposals/sockets/wit/deps/clocks/wall-clock.wit index 76636a0c9..2179b6c56 100644 --- a/proposals/sockets/wit/deps/clocks/wall-clock.wit +++ b/proposals/sockets/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/sockets/wit/deps/clocks/world.wit b/proposals/sockets/wit/deps/clocks/world.wit index 5c53c51a1..a08ff2c2c 100644 --- a/proposals/sockets/wit/deps/clocks/world.wit +++ b/proposals/sockets/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/sockets/wit/deps/io/error.wit b/proposals/sockets/wit/deps/io/error.wit index 784f74a53..acab3a811 100644 --- a/proposals/sockets/wit/deps/io/error.wit +++ b/proposals/sockets/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; @since(version = 0.2.0) interface error { diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit index 7f711836c..a525164b9 100644 --- a/proposals/sockets/wit/deps/io/poll.wit +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index c5da38c86..7ae29a3cd 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -154,27 +154,13 @@ interface streams { /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write`, and `flush`, and is implemented with the - /// following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while !contents.is_empty() { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, contents.len()); - /// let (chunk, rest) = contents.split_at(len); - /// this.write(chunk ); // eliding error handling - /// contents = rest; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` + /// Returns success when all of the contents written are successfully + /// flushed to output. If an error occurs at any point before all + /// contents are successfully flushed, that error is returned as soon as + /// possible. If writing and flushing the complete contents causes the + /// stream to become closed, this call should return success, and + /// subsequent calls to check-write or other interfaces should return + /// stream-error::closed. @since(version = 0.2.0) blocking-write-and-flush: func( contents: list @@ -227,26 +213,8 @@ interface streams { /// Block until all of these operations are complete, or an error /// occurs. /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with - /// the following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while num_zeroes != 0 { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, num_zeroes); - /// this.write-zeroes(len); // eliding error handling - /// num_zeroes -= len; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` + /// Functionality is equivelant to `blocking-write-and-flush` with + /// contents given as a list of len containing only zeroes. @since(version = 0.2.0) blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit index 84c85c08e..73b1a6df5 100644 --- a/proposals/sockets/wit/deps/io/world.wit +++ b/proposals/sockets/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index ee6419e7d..df2735aac 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.6.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 6ca98b63b..95df71ff3 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.6.{error}; + use wasi:io/error@0.2.7.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index beefd7b46..104d9aa39 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.6.{input-stream, output-stream}; + use wasi:io/streams@0.2.7.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.6.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.6.{duration}; + use wasi:clocks/monotonic-clock@0.2.7.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index 9dbe6932d..ecf2dfe60 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.6.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index e86f02cec..9a4d317f7 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.6; +package wasi:sockets@0.2.7; @since(version = 0.2.0) world imports { From 594aac9c560dc37a92c4b183d11e3519dc918c93 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 18:46:40 +0000 Subject: [PATCH 1690/1772] Update to v0.2.7 --- proposals/cli/command.md | 162 +++++++---------- proposals/cli/imports.md | 164 ++++++++---------- proposals/cli/wit/command.wit | 2 +- proposals/cli/wit/deps.lock | 26 +-- proposals/cli/wit/deps.toml | 6 +- .../cli/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/cli/wit/deps/clocks/timezone.wit | 2 +- proposals/cli/wit/deps/clocks/wall-clock.wit | 2 +- proposals/cli/wit/deps/clocks/world.wit | 2 +- .../cli/wit/deps/filesystem/preopens.wit | 2 +- proposals/cli/wit/deps/filesystem/types.wit | 6 +- proposals/cli/wit/deps/filesystem/world.wit | 2 +- proposals/cli/wit/deps/io/error.wit | 2 +- proposals/cli/wit/deps/io/poll.wit | 2 +- proposals/cli/wit/deps/io/streams.wit | 52 ++---- proposals/cli/wit/deps/io/world.wit | 2 +- .../cli/wit/deps/random/insecure-seed.wit | 2 +- proposals/cli/wit/deps/random/insecure.wit | 2 +- proposals/cli/wit/deps/random/random.wit | 2 +- proposals/cli/wit/deps/random/world.wit | 2 +- .../cli/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/cli/wit/deps/sockets/network.wit | 2 +- proposals/cli/wit/deps/sockets/tcp.wit | 6 +- proposals/cli/wit/deps/sockets/udp.wit | 2 +- proposals/cli/wit/deps/sockets/world.wit | 2 +- proposals/cli/wit/imports.wit | 12 +- proposals/cli/wit/stdio.wit | 6 +- 27 files changed, 195 insertions(+), 283 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index 2a6139c8e..f1b5188c4 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -2,43 +2,43 @@ -

                                Import interface wasi:cli/environment@0.2.6

                                +

                                Import interface wasi:cli/environment@0.2.7


                                Functions

                                get-environment: func

                                @@ -65,7 +65,7 @@ directory, interpreting . as shorthand for this.

                                • option<string>
                                -

                                Import interface wasi:cli/exit@0.2.6

                                +

                                Import interface wasi:cli/exit@0.2.7


                                Functions

                                exit: func

                                @@ -85,7 +85,7 @@ without the connotation that something bad has happened.

                                • status-code: u8
                                -

                                Import interface wasi:io/error@0.2.6

                                +

                                Import interface wasi:io/error@0.2.7


                                Types

                                resource error

                                @@ -118,7 +118,7 @@ hazard.

                                • string
                                -

                                Import interface wasi:io/poll@0.2.6

                                +

                                Import interface wasi:io/poll@0.2.7

                                A poll API intended to let users wait for I/O events on multiple handles at once.


                                @@ -171,7 +171,7 @@ being ready for I/O.

                                • list<u32>
                                -

                                Import interface wasi:io/streams@0.2.6

                                +

                                Import interface wasi:io/streams@0.2.7

                                WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                                In the future, the component model is expected to add built-in stream types; @@ -344,25 +344,13 @@ the last call to check-write provided a permit.

                                [method]output-stream.blocking-write-and-flush: func

                                Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                                -

                                This is a convenience wrapper around the use of check-write, -subscribe, write, and flush, and is implemented with the -following pseudo-code:

                                -
                                let pollable = this.subscribe();
                                -while !contents.is_empty() {
                                -  // Wait for the stream to become writable
                                -  pollable.block();
                                -  let Ok(n) = this.check-write(); // eliding error handling
                                -  let len = min(n, contents.len());
                                -  let (chunk, rest) = contents.split_at(len);
                                -  this.write(chunk  );            // eliding error handling
                                -  contents = rest;
                                -}
                                -this.flush();
                                -// Wait for completion of `flush`
                                -pollable.block();
                                -// Check for any errors that arose during `flush`
                                -let _ = this.check-write();         // eliding error handling
                                -
                                +

                                Returns success when all of the contents written are successfully +flushed to output. If an error occurs at any point before all +contents are successfully flushed, that error is returned as soon as +possible. If writing and flushing the complete contents causes the +stream to become closed, this call should return success, and +subsequent calls to check-write or other interfaces should return +stream-error::closed.

                                Params
                                • self: borrow<output-stream>
                                • @@ -436,24 +424,8 @@ that should be written.

                                  Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                                  -

                                  This is a convenience wrapper around the use of check-write, -subscribe, write-zeroes, and flush, and is implemented with -the following pseudo-code:

                                  -
                                  let pollable = this.subscribe();
                                  -while num_zeroes != 0 {
                                  -  // Wait for the stream to become writable
                                  -  pollable.block();
                                  -  let Ok(n) = this.check-write(); // eliding error handling
                                  -  let len = min(n, num_zeroes);
                                  -  this.write-zeroes(len);         // eliding error handling
                                  -  num_zeroes -= len;
                                  -}
                                  -this.flush();
                                  -// Wait for completion of `flush`
                                  -pollable.block();
                                  -// Check for any errors that arose during `flush`
                                  -let _ = this.check-write();         // eliding error handling
                                  -
                                  +

                                  Functionality is equivelant to blocking-write-and-flush with +contents given as a list of len containing only zeroes.

                                  Params
                                  • self: borrow<output-stream>
                                  • @@ -501,7 +473,7 @@ is ready for reading, before performing the splice.

                                    -

                                    Import interface wasi:cli/stdin@0.2.6

                                    +

                                    Import interface wasi:cli/stdin@0.2.7


                                    Types

                                    type input-stream

                                    @@ -514,7 +486,7 @@ is ready for reading, before performing the splice.

                                    -

                                    Import interface wasi:cli/stdout@0.2.6

                                    +

                                    Import interface wasi:cli/stdout@0.2.7


                                    Types

                                    type output-stream

                                    @@ -527,7 +499,7 @@ is ready for reading, before performing the splice.

                                    -

                                    Import interface wasi:cli/stderr@0.2.6

                                    +

                                    Import interface wasi:cli/stderr@0.2.7


                                    Types

                                    type output-stream

                                    @@ -540,7 +512,7 @@ is ready for reading, before performing the splice.

                                    -

                                    Import interface wasi:cli/terminal-input@0.2.6

                                    +

                                    Import interface wasi:cli/terminal-input@0.2.7

                                    Terminal input.

                                    In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -549,7 +521,7 @@ immediately, querying supported features, and so on.

                                    Types

                                    resource terminal-input

                                    The input side of a terminal.

                                    -

                                    Import interface wasi:cli/terminal-output@0.2.6

                                    +

                                    Import interface wasi:cli/terminal-output@0.2.7

                                    Terminal output.

                                    In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -558,7 +530,7 @@ features, and so on.

                                    Types

                                    resource terminal-output

                                    The output side of a terminal.

                                    -

                                    Import interface wasi:cli/terminal-stdin@0.2.6

                                    +

                                    Import interface wasi:cli/terminal-stdin@0.2.7

                                    An interface providing an optional terminal-input for stdin as a link-time authority.


                                    @@ -575,7 +547,7 @@ allowing further interaction with it.

                                    -

                                    Import interface wasi:cli/terminal-stdout@0.2.6

                                    +

                                    Import interface wasi:cli/terminal-stdout@0.2.7

                                    An interface providing an optional terminal-output for stdout as a link-time authority.


                                    @@ -592,7 +564,7 @@ allowing further interaction with it.

                                    -

                                    Import interface wasi:cli/terminal-stderr@0.2.6

                                    +

                                    Import interface wasi:cli/terminal-stderr@0.2.7

                                    An interface providing an optional terminal-output for stderr as a link-time authority.


                                    @@ -609,7 +581,7 @@ allowing further interaction with it.

                                    -

                                    Import interface wasi:clocks/monotonic-clock@0.2.6

                                    +

                                    Import interface wasi:clocks/monotonic-clock@0.2.7

                                    WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                                    It is intended to be portable at least between Unix-family platforms and @@ -668,7 +640,7 @@ elapsed from the time this function is invoked.

                                    -

                                    Import interface wasi:clocks/wall-clock@0.2.6

                                    +

                                    Import interface wasi:clocks/wall-clock@0.2.7

                                    WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                                    @@ -709,7 +681,7 @@ also known as Unix Time.
                                  • datetime
                                  -

                                  Import interface wasi:clocks/timezone@0.2.6

                                  +

                                  Import interface wasi:clocks/timezone@0.2.7


                                  Types

                                  type datetime

                                  @@ -774,7 +746,7 @@ saving time.

                                  • s32
                                  -

                                  Import interface wasi:filesystem/types@0.2.6

                                  +

                                  Import interface wasi:filesystem/types@0.2.7

                                  WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                                  @@ -1652,7 +1624,7 @@ errors are filesystem-related errors.

                                  -

                                  Import interface wasi:filesystem/preopens@0.2.6

                                  +

                                  Import interface wasi:filesystem/preopens@0.2.7


                                  Types

                                  type descriptor

                                  @@ -1666,7 +1638,7 @@ errors are filesystem-related errors.

                                  -

                                  Import interface wasi:sockets/network@0.2.6

                                  +

                                  Import interface wasi:sockets/network@0.2.7


                                  Types

                                  type error

                                  @@ -1881,7 +1853,7 @@ errors are network-related errors.

                                  -

                                  Import interface wasi:sockets/instance-network@0.2.6

                                  +

                                  Import interface wasi:sockets/instance-network@0.2.7

                                  This interface provides a value-export of the default network handle..


                                  Types

                                  @@ -1896,7 +1868,7 @@ errors are network-related errors.

                                  -

                                  Import interface wasi:sockets/udp@0.2.6

                                  +

                                  Import interface wasi:sockets/udp@0.2.7


                                  Types

                                  type pollable

                                  @@ -2310,7 +2282,7 @@ It's planned to be removed when future is natively supported in Pre -

                                  Import interface wasi:sockets/udp-create-socket@0.2.6

                                  +

                                  Import interface wasi:sockets/udp-create-socket@0.2.7


                                  Types

                                  type network

                                  @@ -2355,7 +2327,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                                  Import interface wasi:sockets/tcp@0.2.6

                                  +

                                  Import interface wasi:sockets/tcp@0.2.7


                                  Types

                                  type input-stream

                                  @@ -2946,7 +2918,7 @@ has no effect and returns ok.

                                  -

                                  Import interface wasi:sockets/tcp-create-socket@0.2.6

                                  +

                                  Import interface wasi:sockets/tcp-create-socket@0.2.7


                                  Types

                                  type network

                                  @@ -2991,7 +2963,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                                  Import interface wasi:sockets/ip-name-lookup@0.2.6

                                  +

                                  Import interface wasi:sockets/ip-name-lookup@0.2.7


                                  Types

                                  type pollable

                                  @@ -3071,7 +3043,7 @@ It's planned to be removed when future is natively supported in Pre -

                                  Import interface wasi:random/random@0.2.6

                                  +

                                  Import interface wasi:random/random@0.2.7

                                  WASI Random is a random data API.

                                  It is intended to be portable at least between Unix-family platforms and Windows.

                                  @@ -3104,7 +3076,7 @@ represented as a u64.

                                  • u64
                                  -

                                  Import interface wasi:random/insecure@0.2.6

                                  +

                                  Import interface wasi:random/insecure@0.2.7

                                  The insecure interface for insecure pseudo-random numbers.

                                  It is intended to be portable at least between Unix-family platforms and Windows.

                                  @@ -3133,7 +3105,7 @@ a long period.

                                  • u64
                                  -

                                  Import interface wasi:random/insecure-seed@0.2.6

                                  +

                                  Import interface wasi:random/insecure-seed@0.2.7

                                  The insecure-seed interface for seeding hash-map DoS resistance.

                                  It is intended to be portable at least between Unix-family platforms and Windows.

                                  @@ -3157,7 +3129,7 @@ protection.

                                  • (u64, u64)
                                  -

                                  Export interface wasi:cli/run@0.2.6

                                  +

                                  Export interface wasi:cli/run@0.2.7


                                  Functions

                                  run: func

                                  diff --git a/proposals/cli/imports.md b/proposals/cli/imports.md index 0547ac19e..3aee65fe4 100644 --- a/proposals/cli/imports.md +++ b/proposals/cli/imports.md @@ -2,38 +2,38 @@ -

                                  Import interface wasi:cli/environment@0.2.6

                                  +
                                • interface wasi:cli/environment@0.2.7
                                • +
                                • interface wasi:cli/exit@0.2.7
                                • +
                                • interface wasi:io/error@0.2.7
                                • +
                                • interface wasi:io/poll@0.2.7
                                • +
                                • interface wasi:io/streams@0.2.7
                                • +
                                • interface wasi:cli/stdin@0.2.7
                                • +
                                • interface wasi:cli/stdout@0.2.7
                                • +
                                • interface wasi:cli/stderr@0.2.7
                                • +
                                • interface wasi:cli/terminal-input@0.2.7
                                • +
                                • interface wasi:cli/terminal-output@0.2.7
                                • +
                                • interface wasi:cli/terminal-stdin@0.2.7
                                • +
                                • interface wasi:cli/terminal-stdout@0.2.7
                                • +
                                • interface wasi:cli/terminal-stderr@0.2.7
                                • +
                                • interface wasi:clocks/monotonic-clock@0.2.7
                                • +
                                • interface wasi:clocks/wall-clock@0.2.7
                                • +
                                • interface wasi:clocks/timezone@0.2.7
                                • +
                                • interface wasi:filesystem/types@0.2.7
                                • +
                                • interface wasi:filesystem/preopens@0.2.7
                                • +
                                • interface wasi:sockets/network@0.2.7
                                • +
                                • interface wasi:sockets/instance-network@0.2.7
                                • +
                                • interface wasi:sockets/udp@0.2.7
                                • +
                                • interface wasi:sockets/udp-create-socket@0.2.7
                                • +
                                • interface wasi:sockets/tcp@0.2.7
                                • +
                                • interface wasi:sockets/tcp-create-socket@0.2.7
                                • +
                                • interface wasi:sockets/ip-name-lookup@0.2.7
                                • +
                                • interface wasi:random/random@0.2.7
                                • +
                                • interface wasi:random/insecure@0.2.7
                                • +
                                • interface wasi:random/insecure-seed@0.2.7
                                • +
                                + +
                              +

                              Import interface wasi:cli/environment@0.2.7


                              Functions

                              get-environment: func

                              @@ -60,7 +60,7 @@ directory, interpreting . as shorthand for this.

                              • option<string>
                              -

                              Import interface wasi:cli/exit@0.2.6

                              +

                              Import interface wasi:cli/exit@0.2.7


                              Functions

                              exit: func

                              @@ -80,7 +80,7 @@ without the connotation that something bad has happened.

                              • status-code: u8
                              -

                              Import interface wasi:io/error@0.2.6

                              +

                              Import interface wasi:io/error@0.2.7


                              Types

                              resource error

                              @@ -113,7 +113,7 @@ hazard.

                              • string
                              -

                              Import interface wasi:io/poll@0.2.6

                              +

                              Import interface wasi:io/poll@0.2.7

                              A poll API intended to let users wait for I/O events on multiple handles at once.


                              @@ -166,7 +166,7 @@ being ready for I/O.

                              • list<u32>
                              -

                              Import interface wasi:io/streams@0.2.6

                              +

                              Import interface wasi:io/streams@0.2.7

                              WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                              In the future, the component model is expected to add built-in stream types; @@ -339,25 +339,13 @@ the last call to check-write provided a permit.

                              [method]output-stream.blocking-write-and-flush: func

                              Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                              -

                              This is a convenience wrapper around the use of check-write, -subscribe, write, and flush, and is implemented with the -following pseudo-code:

                              -
                              let pollable = this.subscribe();
                              -while !contents.is_empty() {
                              -  // Wait for the stream to become writable
                              -  pollable.block();
                              -  let Ok(n) = this.check-write(); // eliding error handling
                              -  let len = min(n, contents.len());
                              -  let (chunk, rest) = contents.split_at(len);
                              -  this.write(chunk  );            // eliding error handling
                              -  contents = rest;
                              -}
                              -this.flush();
                              -// Wait for completion of `flush`
                              -pollable.block();
                              -// Check for any errors that arose during `flush`
                              -let _ = this.check-write();         // eliding error handling
                              -
                              +

                              Returns success when all of the contents written are successfully +flushed to output. If an error occurs at any point before all +contents are successfully flushed, that error is returned as soon as +possible. If writing and flushing the complete contents causes the +stream to become closed, this call should return success, and +subsequent calls to check-write or other interfaces should return +stream-error::closed.

                              Params
                              • self: borrow<output-stream>
                              • @@ -431,24 +419,8 @@ that should be written.

                                Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                                -

                                This is a convenience wrapper around the use of check-write, -subscribe, write-zeroes, and flush, and is implemented with -the following pseudo-code:

                                -
                                let pollable = this.subscribe();
                                -while num_zeroes != 0 {
                                -  // Wait for the stream to become writable
                                -  pollable.block();
                                -  let Ok(n) = this.check-write(); // eliding error handling
                                -  let len = min(n, num_zeroes);
                                -  this.write-zeroes(len);         // eliding error handling
                                -  num_zeroes -= len;
                                -}
                                -this.flush();
                                -// Wait for completion of `flush`
                                -pollable.block();
                                -// Check for any errors that arose during `flush`
                                -let _ = this.check-write();         // eliding error handling
                                -
                                +

                                Functionality is equivelant to blocking-write-and-flush with +contents given as a list of len containing only zeroes.

                                Params
                                • self: borrow<output-stream>
                                • @@ -496,7 +468,7 @@ is ready for reading, before performing the splice.

                                  -

                                  Import interface wasi:cli/stdin@0.2.6

                                  +

                                  Import interface wasi:cli/stdin@0.2.7


                                  Types

                                  type input-stream

                                  @@ -509,7 +481,7 @@ is ready for reading, before performing the splice.

                                  -

                                  Import interface wasi:cli/stdout@0.2.6

                                  +

                                  Import interface wasi:cli/stdout@0.2.7


                                  Types

                                  type output-stream

                                  @@ -522,7 +494,7 @@ is ready for reading, before performing the splice.

                                  -

                                  Import interface wasi:cli/stderr@0.2.6

                                  +

                                  Import interface wasi:cli/stderr@0.2.7


                                  Types

                                  type output-stream

                                  @@ -535,7 +507,7 @@ is ready for reading, before performing the splice.

                                  -

                                  Import interface wasi:cli/terminal-input@0.2.6

                                  +

                                  Import interface wasi:cli/terminal-input@0.2.7

                                  Terminal input.

                                  In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -544,7 +516,7 @@ immediately, querying supported features, and so on.

                                  Types

                                  resource terminal-input

                                  The input side of a terminal.

                                  -

                                  Import interface wasi:cli/terminal-output@0.2.6

                                  +

                                  Import interface wasi:cli/terminal-output@0.2.7

                                  Terminal output.

                                  In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -553,7 +525,7 @@ features, and so on.

                                  Types

                                  resource terminal-output

                                  The output side of a terminal.

                                  -

                                  Import interface wasi:cli/terminal-stdin@0.2.6

                                  +

                                  Import interface wasi:cli/terminal-stdin@0.2.7

                                  An interface providing an optional terminal-input for stdin as a link-time authority.


                                  @@ -570,7 +542,7 @@ allowing further interaction with it.

                                  -

                                  Import interface wasi:cli/terminal-stdout@0.2.6

                                  +

                                  Import interface wasi:cli/terminal-stdout@0.2.7

                                  An interface providing an optional terminal-output for stdout as a link-time authority.


                                  @@ -587,7 +559,7 @@ allowing further interaction with it.

                                  -

                                  Import interface wasi:cli/terminal-stderr@0.2.6

                                  +

                                  Import interface wasi:cli/terminal-stderr@0.2.7

                                  An interface providing an optional terminal-output for stderr as a link-time authority.


                                  @@ -604,7 +576,7 @@ allowing further interaction with it.

                                  -

                                  Import interface wasi:clocks/monotonic-clock@0.2.6

                                  +

                                  Import interface wasi:clocks/monotonic-clock@0.2.7

                                  WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                                  It is intended to be portable at least between Unix-family platforms and @@ -663,7 +635,7 @@ elapsed from the time this function is invoked.

                                  -

                                  Import interface wasi:clocks/wall-clock@0.2.6

                                  +

                                  Import interface wasi:clocks/wall-clock@0.2.7

                                  WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                                  @@ -704,7 +676,7 @@ also known as Unix Time.
                                • datetime
                                -

                                Import interface wasi:clocks/timezone@0.2.6

                                +

                                Import interface wasi:clocks/timezone@0.2.7


                                Types

                                type datetime

                                @@ -769,7 +741,7 @@ saving time.

                                • s32
                                -

                                Import interface wasi:filesystem/types@0.2.6

                                +

                                Import interface wasi:filesystem/types@0.2.7

                                WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                                @@ -1647,7 +1619,7 @@ errors are filesystem-related errors.

                                -

                                Import interface wasi:filesystem/preopens@0.2.6

                                +

                                Import interface wasi:filesystem/preopens@0.2.7


                                Types

                                type descriptor

                                @@ -1661,7 +1633,7 @@ errors are filesystem-related errors.

                                -

                                Import interface wasi:sockets/network@0.2.6

                                +

                                Import interface wasi:sockets/network@0.2.7


                                Types

                                type error

                                @@ -1876,7 +1848,7 @@ errors are network-related errors.

                                -

                                Import interface wasi:sockets/instance-network@0.2.6

                                +

                                Import interface wasi:sockets/instance-network@0.2.7

                                This interface provides a value-export of the default network handle..


                                Types

                                @@ -1891,7 +1863,7 @@ errors are network-related errors.

                                -

                                Import interface wasi:sockets/udp@0.2.6

                                +

                                Import interface wasi:sockets/udp@0.2.7


                                Types

                                type pollable

                                @@ -2305,7 +2277,7 @@ It's planned to be removed when future is natively supported in Pre -

                                Import interface wasi:sockets/udp-create-socket@0.2.6

                                +

                                Import interface wasi:sockets/udp-create-socket@0.2.7


                                Types

                                type network

                                @@ -2350,7 +2322,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                                Import interface wasi:sockets/tcp@0.2.6

                                +

                                Import interface wasi:sockets/tcp@0.2.7


                                Types

                                type input-stream

                                @@ -2941,7 +2913,7 @@ has no effect and returns ok.

                                -

                                Import interface wasi:sockets/tcp-create-socket@0.2.6

                                +

                                Import interface wasi:sockets/tcp-create-socket@0.2.7


                                Types

                                type network

                                @@ -2986,7 +2958,7 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                                Import interface wasi:sockets/ip-name-lookup@0.2.6

                                +

                                Import interface wasi:sockets/ip-name-lookup@0.2.7


                                Types

                                type pollable

                                @@ -3066,7 +3038,7 @@ It's planned to be removed when future is natively supported in Pre -

                                Import interface wasi:random/random@0.2.6

                                +

                                Import interface wasi:random/random@0.2.7

                                WASI Random is a random data API.

                                It is intended to be portable at least between Unix-family platforms and Windows.

                                @@ -3099,7 +3071,7 @@ represented as a u64.

                                • u64
                                -

                                Import interface wasi:random/insecure@0.2.6

                                +

                                Import interface wasi:random/insecure@0.2.7

                                The insecure interface for insecure pseudo-random numbers.

                                It is intended to be portable at least between Unix-family platforms and Windows.

                                @@ -3128,7 +3100,7 @@ a long period.

                                • u64
                                -

                                Import interface wasi:random/insecure-seed@0.2.6

                                +

                                Import interface wasi:random/insecure-seed@0.2.7

                                The insecure-seed interface for seeding hash-map DoS resistance.

                                It is intended to be portable at least between Unix-family platforms and Windows.

                                diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index 6d3cc83f5..dfecf913e 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.6; +package wasi:cli@0.2.7; @since(version = 0.2.0) world command { diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index edb40382d..dc0c8620a 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,24 +1,24 @@ [clocks] -sha256 = "59b8db7b6f3f8a72418510453c1fa9e437c7c7c2369c0bd5da83aa5d6d1d9b73" -sha512 = "06ce14bbf34d5588ed0c26bd932d46b3025c16723d5b4558def5b8107781b2251471c1f7170640342e3d4f78efb560d5ff6383c6a127c1d9e757e83db31a0185" +sha256 = "d0a8d048c41b566b978cd8ecd03fa51ec1f65af4c26be2f0fc9cfdd7dd6f34f3" +sha512 = "8d1c9ddaaea70ae54376bfc02dcdd0437336fb4fc67f89763ce09540caefe84cbae89a8de3605aa7613c49188636e925047bcd150c2c60685850095fefb68b73" [filesystem] -url = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.6.tar.gz" -sha256 = "9eb3e27ea559c679e9fb3c775a7091efedd0dc52aec56d7cd28caba36a76309c" -sha512 = "4207a911dd647ecbe82727af2145d88fc536f013ef76fc173d7d07729c71e9ff8c08ce911f25fa8511705d62e60d4888c5cc43d498cd3753b164bbe1be2d3a55" +url = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.7.tar.gz" +sha256 = "55942d9c31ed62d05d32d62d211a5c93983df7c0f1489124ca120cf58c4d61c0" +sha512 = "1250a19334ad6acf18adead4503f22c99bfbca7cfb7267431547d4bcca34f91e9635648d00f064276086887a9c80ffacbf68bee832b9e4cd1c921bec0776717f" deps = ["clocks", "io"] [io] -sha256 = "671761f464d312e6c26bcaab5e79fe14ac876b72267867579d5c65e053fe2301" -sha512 = "57e5ed34fa85f35899b324ac7a2473c5fa5cece51d07e6f077637191fadd3c8b6f79324d31a8d497a6ce7b92cfb2a2505ab894337e2c82889f1bdb21f4f24634" +sha256 = "62ae80f2e340cddbac8e94f78e6270735aea536367ecb98de5f4ac6aef66b5c4" +sha512 = "a02a1ebd261ae884b0315b3528d1a93819ddc4b616f66c77f2bea9dd1de888208dc3b9004a553363f5e8491ea925d65ebbd0d68eaa87238316b47469a3bf97bb" [random] -url = "https://github.com/WebAssembly/wasi-random/archive/v0.2.6.tar.gz" -sha256 = "5fc77fdcbf6fc236250c5ba32149ea2fde7a8191696d9a4ed3931bb07202bcc0" -sha512 = "1f3be8d65185552abad4532ed4603643b3f9eed1847d4c1acaec107964701990f18b1a036dcdccead85c29f037f272b3d1ce300c6e4316002b36431c04c00abd" +url = "https://github.com/WebAssembly/wasi-random/archive/v0.2.7.tar.gz" +sha256 = "168a5a22cfc489bbde2a2ce38d3a20b5c418fb099d3993196fca2129f8e9bfc0" +sha512 = "1641fed653abe0991cdeee330bf6d3f6e17b9d2b3b9766588c792f181e8133727efa20feb41d0f325e3db8158ce51948c2d6648e02e8998df8eba3c88959bfca" [sockets] -url = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.6.tar.gz" -sha256 = "4f98b623cb6ff6f02c2975cea615fa36de2087dc48e76c4865e0297499c005a1" -sha512 = "cf72b97c46913e752dff2d1c93d2c9bd87210d5714fe43d4eb93fb7512b1c786737e69b444521e77725e12a2689673da786bd0f3f94ce77bf7772671637d7878" +url = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.7.tar.gz" +sha256 = "33b150bb413c6f4e2ab1ab12b6da822d6c712f13a0644177b108f57dff5783d6" +sha512 = "47efa2fea61374da2853b4ff2aed394b54c8e1d164ce6706332bd1056a16c2eb0a8d7c0ab5408a8b08537b615197ff4a44bdb5d132772a8d6049de5c39ec5e68" deps = ["clocks", "io"] diff --git a/proposals/cli/wit/deps.toml b/proposals/cli/wit/deps.toml index f7a7430fb..fd5a7018a 100644 --- a/proposals/cli/wit/deps.toml +++ b/proposals/cli/wit/deps.toml @@ -1,3 +1,3 @@ -filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.6.tar.gz" -random = "https://github.com/WebAssembly/wasi-random/archive/v0.2.6.tar.gz" -sockets = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.6.tar.gz" +filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.7.tar.gz" +random = "https://github.com/WebAssembly/wasi-random/archive/v0.2.7.tar.gz" +sockets = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.7.tar.gz" diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index f3bc83912..98a9ad42a 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.6; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.6.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/cli/wit/deps/clocks/timezone.wit b/proposals/cli/wit/deps/clocks/timezone.wit index ca98ad152..4740bde00 100644 --- a/proposals/cli/wit/deps/clocks/timezone.wit +++ b/proposals/cli/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit index 76636a0c9..2179b6c56 100644 --- a/proposals/cli/wit/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/cli/wit/deps/clocks/world.wit b/proposals/cli/wit/deps/clocks/world.wit index 5c53c51a1..a08ff2c2c 100644 --- a/proposals/cli/wit/deps/clocks/world.wit +++ b/proposals/cli/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/filesystem/preopens.wit b/proposals/cli/wit/deps/filesystem/preopens.wit index f22847940..b1a0a9972 100644 --- a/proposals/cli/wit/deps/filesystem/preopens.wit +++ b/proposals/cli/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.6; +package wasi:filesystem@0.2.7; @since(version = 0.2.0) interface preopens { diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index 75c19044c..a7da2b72f 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.6; +package wasi:filesystem@0.2.7; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.6; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.6.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.7.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.6.{datetime}; + use wasi:clocks/wall-clock@0.2.7.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit index 65597f9f2..67309b43f 100644 --- a/proposals/cli/wit/deps/filesystem/world.wit +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.6; +package wasi:filesystem@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/io/error.wit b/proposals/cli/wit/deps/io/error.wit index 784f74a53..acab3a811 100644 --- a/proposals/cli/wit/deps/io/error.wit +++ b/proposals/cli/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; @since(version = 0.2.0) interface error { diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit index 7f711836c..a525164b9 100644 --- a/proposals/cli/wit/deps/io/poll.wit +++ b/proposals/cli/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index c5da38c86..7ae29a3cd 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -154,27 +154,13 @@ interface streams { /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write`, and `flush`, and is implemented with the - /// following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while !contents.is_empty() { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, contents.len()); - /// let (chunk, rest) = contents.split_at(len); - /// this.write(chunk ); // eliding error handling - /// contents = rest; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` + /// Returns success when all of the contents written are successfully + /// flushed to output. If an error occurs at any point before all + /// contents are successfully flushed, that error is returned as soon as + /// possible. If writing and flushing the complete contents causes the + /// stream to become closed, this call should return success, and + /// subsequent calls to check-write or other interfaces should return + /// stream-error::closed. @since(version = 0.2.0) blocking-write-and-flush: func( contents: list @@ -227,26 +213,8 @@ interface streams { /// Block until all of these operations are complete, or an error /// occurs. /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with - /// the following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while num_zeroes != 0 { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, num_zeroes); - /// this.write-zeroes(len); // eliding error handling - /// num_zeroes -= len; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` + /// Functionality is equivelant to `blocking-write-and-flush` with + /// contents given as a list of len containing only zeroes. @since(version = 0.2.0) blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write diff --git a/proposals/cli/wit/deps/io/world.wit b/proposals/cli/wit/deps/io/world.wit index 84c85c08e..73b1a6df5 100644 --- a/proposals/cli/wit/deps/io/world.wit +++ b/proposals/cli/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/random/insecure-seed.wit b/proposals/cli/wit/deps/random/insecure-seed.wit index d3dc03a6c..0209b84b0 100644 --- a/proposals/cli/wit/deps/random/insecure-seed.wit +++ b/proposals/cli/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.6; +package wasi:random@0.2.7; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/insecure.wit b/proposals/cli/wit/deps/random/insecure.wit index d4d028480..820d069ee 100644 --- a/proposals/cli/wit/deps/random/insecure.wit +++ b/proposals/cli/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.6; +package wasi:random@0.2.7; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index a0ff95646..974ab465d 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.6; +package wasi:random@0.2.7; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/world.wit b/proposals/cli/wit/deps/random/world.wit index 099f47b36..333b42598 100644 --- a/proposals/cli/wit/deps/random/world.wit +++ b/proposals/cli/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.6; +package wasi:random@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index ee6419e7d..df2735aac 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.6.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit index 6ca98b63b..95df71ff3 100644 --- a/proposals/cli/wit/deps/sockets/network.wit +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.6.{error}; + use wasi:io/error@0.2.7.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index beefd7b46..104d9aa39 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.6.{input-stream, output-stream}; + use wasi:io/streams@0.2.7.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.6.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.6.{duration}; + use wasi:clocks/monotonic-clock@0.2.7.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index 9dbe6932d..ecf2dfe60 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.6.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit index e86f02cec..9a4d317f7 100644 --- a/proposals/cli/wit/deps/sockets/world.wit +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.6; +package wasi:sockets@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/imports.wit b/proposals/cli/wit/imports.wit index d9fd01710..e7f7942de 100644 --- a/proposals/cli/wit/imports.wit +++ b/proposals/cli/wit/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.6; +package wasi:cli@0.2.7; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.6; + include wasi:clocks/imports@0.2.7; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.6; + include wasi:filesystem/imports@0.2.7; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.6; + include wasi:sockets/imports@0.2.7; @since(version = 0.2.0) - include wasi:random/imports@0.2.6; + include wasi:random/imports@0.2.7; @since(version = 0.2.0) - include wasi:io/imports@0.2.6; + include wasi:io/imports@0.2.7; @since(version = 0.2.0) import environment; diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index cb8aea2d9..1c3c6d074 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.6.{input-stream}; + use wasi:io/streams@0.2.7.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.6.{output-stream}; + use wasi:io/streams@0.2.7.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.6.{output-stream}; + use wasi:io/streams@0.2.7.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; From 2bd6d231a6f1610f1fae774b19e5068d2ae88a78 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 19:04:52 +0000 Subject: [PATCH 1691/1772] Update to v0.2.7 --- proposals/http/imports.md | 90 ++++++------------ proposals/http/proxy.md | 94 +++++++------------ proposals/http/wit/deps.lock | 26 ++--- proposals/http/wit/deps.toml | 2 +- proposals/http/wit/deps/cli/command.wit | 2 +- proposals/http/wit/deps/cli/imports.wit | 12 +-- proposals/http/wit/deps/cli/stdio.wit | 6 +- .../http/wit/deps/clocks/monotonic-clock.wit | 4 +- proposals/http/wit/deps/clocks/timezone.wit | 2 +- proposals/http/wit/deps/clocks/wall-clock.wit | 2 +- proposals/http/wit/deps/clocks/world.wit | 2 +- .../http/wit/deps/filesystem/preopens.wit | 2 +- proposals/http/wit/deps/filesystem/types.wit | 6 +- proposals/http/wit/deps/filesystem/world.wit | 2 +- proposals/http/wit/deps/io/error.wit | 2 +- proposals/http/wit/deps/io/poll.wit | 2 +- proposals/http/wit/deps/io/streams.wit | 52 ++-------- proposals/http/wit/deps/io/world.wit | 2 +- .../http/wit/deps/random/insecure-seed.wit | 2 +- proposals/http/wit/deps/random/insecure.wit | 2 +- proposals/http/wit/deps/random/random.wit | 2 +- proposals/http/wit/deps/random/world.wit | 2 +- .../http/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/http/wit/deps/sockets/network.wit | 2 +- proposals/http/wit/deps/sockets/tcp.wit | 6 +- proposals/http/wit/deps/sockets/udp.wit | 2 +- proposals/http/wit/deps/sockets/world.wit | 2 +- proposals/http/wit/proxy.wit | 14 +-- proposals/http/wit/types.wit | 8 +- 29 files changed, 133 insertions(+), 221 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index 09b77ed94..49a15d2f5 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -4,21 +4,21 @@ It is intended to be included in other worlds.

                                -

                                Import interface wasi:io/poll@0.2.6

                                +

                                Import interface wasi:io/poll@0.2.7

                                A poll API intended to let users wait for I/O events on multiple handles at once.


                                @@ -71,7 +71,7 @@ being ready for I/O.

                                • list<u32>
                                -

                                Import interface wasi:clocks/monotonic-clock@0.2.6

                                +

                                Import interface wasi:clocks/monotonic-clock@0.2.7

                                WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                                It is intended to be portable at least between Unix-family platforms and @@ -130,7 +130,7 @@ elapsed from the time this function is invoked.

                                -

                                Import interface wasi:clocks/wall-clock@0.2.6

                                +

                                Import interface wasi:clocks/wall-clock@0.2.7

                                WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                                @@ -171,7 +171,7 @@ also known as Unix Time.
                              • datetime
                              -

                              Import interface wasi:random/random@0.2.6

                              +

                              Import interface wasi:random/random@0.2.7

                              WASI Random is a random data API.

                              It is intended to be portable at least between Unix-family platforms and Windows.

                              @@ -204,7 +204,7 @@ represented as a u64.

                              • u64
                              -

                              Import interface wasi:io/error@0.2.6

                              +

                              Import interface wasi:io/error@0.2.7


                              Types

                              resource error

                              @@ -237,7 +237,7 @@ hazard.

                              • string
                              -

                              Import interface wasi:io/streams@0.2.6

                              +

                              Import interface wasi:io/streams@0.2.7

                              WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                              In the future, the component model is expected to add built-in stream types; @@ -410,25 +410,13 @@ the last call to check-write provided a permit.

                              [method]output-stream.blocking-write-and-flush: func

                              Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                              -

                              This is a convenience wrapper around the use of check-write, -subscribe, write, and flush, and is implemented with the -following pseudo-code:

                              -
                              let pollable = this.subscribe();
                              -while !contents.is_empty() {
                              -  // Wait for the stream to become writable
                              -  pollable.block();
                              -  let Ok(n) = this.check-write(); // eliding error handling
                              -  let len = min(n, contents.len());
                              -  let (chunk, rest) = contents.split_at(len);
                              -  this.write(chunk  );            // eliding error handling
                              -  contents = rest;
                              -}
                              -this.flush();
                              -// Wait for completion of `flush`
                              -pollable.block();
                              -// Check for any errors that arose during `flush`
                              -let _ = this.check-write();         // eliding error handling
                              -
                              +

                              Returns success when all of the contents written are successfully +flushed to output. If an error occurs at any point before all +contents are successfully flushed, that error is returned as soon as +possible. If writing and flushing the complete contents causes the +stream to become closed, this call should return success, and +subsequent calls to check-write or other interfaces should return +stream-error::closed.

                              Params
                              • self: borrow<output-stream>
                              • @@ -502,24 +490,8 @@ that should be written.

                                Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                                -

                                This is a convenience wrapper around the use of check-write, -subscribe, write-zeroes, and flush, and is implemented with -the following pseudo-code:

                                -
                                let pollable = this.subscribe();
                                -while num_zeroes != 0 {
                                -  // Wait for the stream to become writable
                                -  pollable.block();
                                -  let Ok(n) = this.check-write(); // eliding error handling
                                -  let len = min(n, num_zeroes);
                                -  this.write-zeroes(len);         // eliding error handling
                                -  num_zeroes -= len;
                                -}
                                -this.flush();
                                -// Wait for completion of `flush`
                                -pollable.block();
                                -// Check for any errors that arose during `flush`
                                -let _ = this.check-write();         // eliding error handling
                                -
                                +

                                Functionality is equivelant to blocking-write-and-flush with +contents given as a list of len containing only zeroes.

                                Params
                                • self: borrow<output-stream>
                                • @@ -567,7 +539,7 @@ is ready for reading, before performing the splice.

                                  -

                                  Import interface wasi:cli/stdout@0.2.6

                                  +

                                  Import interface wasi:cli/stdout@0.2.7


                                  Types

                                  type output-stream

                                  @@ -580,7 +552,7 @@ is ready for reading, before performing the splice.

                                  -

                                  Import interface wasi:cli/stderr@0.2.6

                                  +

                                  Import interface wasi:cli/stderr@0.2.7


                                  Types

                                  type output-stream

                                  @@ -593,7 +565,7 @@ is ready for reading, before performing the splice.

                                  -

                                  Import interface wasi:cli/stdin@0.2.6

                                  +

                                  Import interface wasi:cli/stdin@0.2.7


                                  Types

                                  type input-stream

                                  @@ -606,7 +578,7 @@ is ready for reading, before performing the splice.

                                  -

                                  Import interface wasi:http/types@0.2.6

                                  +

                                  Import interface wasi:http/types@0.2.7

                                  This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                                  @@ -1526,7 +1498,7 @@ but those will be reported by the incoming-body
                                • option<result<result<own<incoming-response>, error-code>>>
                                -

                                Import interface wasi:http/outgoing-handler@0.2.6

                                +

                                Import interface wasi:http/outgoing-handler@0.2.7

                                This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                                diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index e099d46d6..990350382 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -6,26 +6,26 @@ outgoing HTTP requests.

                                -

                                Import interface wasi:io/poll@0.2.6

                                +

                                Import interface wasi:io/poll@0.2.7

                                A poll API intended to let users wait for I/O events on multiple handles at once.


                                @@ -78,7 +78,7 @@ being ready for I/O.

                                • list<u32>
                                -

                                Import interface wasi:clocks/monotonic-clock@0.2.6

                                +

                                Import interface wasi:clocks/monotonic-clock@0.2.7

                                WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                                It is intended to be portable at least between Unix-family platforms and @@ -137,7 +137,7 @@ elapsed from the time this function is invoked.

                                -

                                Import interface wasi:clocks/wall-clock@0.2.6

                                +

                                Import interface wasi:clocks/wall-clock@0.2.7

                                WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                                @@ -178,7 +178,7 @@ also known as Unix Time.
                              • datetime
                              -

                              Import interface wasi:random/random@0.2.6

                              +

                              Import interface wasi:random/random@0.2.7

                              WASI Random is a random data API.

                              It is intended to be portable at least between Unix-family platforms and Windows.

                              @@ -211,7 +211,7 @@ represented as a u64.

                              • u64
                              -

                              Import interface wasi:io/error@0.2.6

                              +

                              Import interface wasi:io/error@0.2.7


                              Types

                              resource error

                              @@ -244,7 +244,7 @@ hazard.

                              • string
                              -

                              Import interface wasi:io/streams@0.2.6

                              +

                              Import interface wasi:io/streams@0.2.7

                              WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                              In the future, the component model is expected to add built-in stream types; @@ -417,25 +417,13 @@ the last call to check-write provided a permit.

                              [method]output-stream.blocking-write-and-flush: func

                              Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                              -

                              This is a convenience wrapper around the use of check-write, -subscribe, write, and flush, and is implemented with the -following pseudo-code:

                              -
                              let pollable = this.subscribe();
                              -while !contents.is_empty() {
                              -  // Wait for the stream to become writable
                              -  pollable.block();
                              -  let Ok(n) = this.check-write(); // eliding error handling
                              -  let len = min(n, contents.len());
                              -  let (chunk, rest) = contents.split_at(len);
                              -  this.write(chunk  );            // eliding error handling
                              -  contents = rest;
                              -}
                              -this.flush();
                              -// Wait for completion of `flush`
                              -pollable.block();
                              -// Check for any errors that arose during `flush`
                              -let _ = this.check-write();         // eliding error handling
                              -
                              +

                              Returns success when all of the contents written are successfully +flushed to output. If an error occurs at any point before all +contents are successfully flushed, that error is returned as soon as +possible. If writing and flushing the complete contents causes the +stream to become closed, this call should return success, and +subsequent calls to check-write or other interfaces should return +stream-error::closed.

                              Params
                              • self: borrow<output-stream>
                              • @@ -509,24 +497,8 @@ that should be written.

                                Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

                                -

                                This is a convenience wrapper around the use of check-write, -subscribe, write-zeroes, and flush, and is implemented with -the following pseudo-code:

                                -
                                let pollable = this.subscribe();
                                -while num_zeroes != 0 {
                                -  // Wait for the stream to become writable
                                -  pollable.block();
                                -  let Ok(n) = this.check-write(); // eliding error handling
                                -  let len = min(n, num_zeroes);
                                -  this.write-zeroes(len);         // eliding error handling
                                -  num_zeroes -= len;
                                -}
                                -this.flush();
                                -// Wait for completion of `flush`
                                -pollable.block();
                                -// Check for any errors that arose during `flush`
                                -let _ = this.check-write();         // eliding error handling
                                -
                                +

                                Functionality is equivelant to blocking-write-and-flush with +contents given as a list of len containing only zeroes.

                                Params
                                • self: borrow<output-stream>
                                • @@ -574,7 +546,7 @@ is ready for reading, before performing the splice.

                                  -

                                  Import interface wasi:cli/stdout@0.2.6

                                  +

                                  Import interface wasi:cli/stdout@0.2.7


                                  Types

                                  type output-stream

                                  @@ -587,7 +559,7 @@ is ready for reading, before performing the splice.

                                  -

                                  Import interface wasi:cli/stderr@0.2.6

                                  +

                                  Import interface wasi:cli/stderr@0.2.7


                                  Types

                                  type output-stream

                                  @@ -600,7 +572,7 @@ is ready for reading, before performing the splice.

                                  -

                                  Import interface wasi:cli/stdin@0.2.6

                                  +

                                  Import interface wasi:cli/stdin@0.2.7


                                  Types

                                  type input-stream

                                  @@ -613,7 +585,7 @@ is ready for reading, before performing the splice.

                                  -

                                  Import interface wasi:http/types@0.2.6

                                  +

                                  Import interface wasi:http/types@0.2.7

                                  This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                                  @@ -1533,7 +1505,7 @@ but those will be reported by the incoming-body
                                • option<result<result<own<incoming-response>, error-code>>>
                                -

                                Import interface wasi:http/outgoing-handler@0.2.6

                                +

                                Import interface wasi:http/outgoing-handler@0.2.7

                                This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                                @@ -1570,7 +1542,7 @@ through the future-incoming-response
                              • result<own<future-incoming-response>, error-code>
                              -

                              Export interface wasi:http/incoming-handler@0.2.6

                              +

                              Export interface wasi:http/incoming-handler@0.2.7


                              Types

                              type incoming-request

                              diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index 73bb8a09f..de72b0a79 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,25 +1,25 @@ [cli] -url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.6.tar.gz" -sha256 = "e5f2192aeeaa5ca23d584bf1773c126fac268cbc76361a79b3a5afe9d90d4602" -sha512 = "a4d968bd023483a089df7988543aa7ab4817e16d5bb1d99e9f2fcb7811eca2a25e5b7687f6a990c1373c204150eac941d53d50edb23169f3b07eab37b8358c7f" +url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.7.tar.gz" +sha256 = "0595631e4b6c425fd5b976315cbb278248c7c1aa20c368bfb0c6581b0cbba274" +sha512 = "2cf8b0575382a823aa0f7f943ad980a4a8076843600882fb046a753bd10a1dbf92b966e2087e892b7d9f35e6e25110514ee8269249c16977323fb2914a248ab9" deps = ["clocks", "filesystem", "io", "random", "sockets"] [clocks] -sha256 = "59b8db7b6f3f8a72418510453c1fa9e437c7c7c2369c0bd5da83aa5d6d1d9b73" -sha512 = "06ce14bbf34d5588ed0c26bd932d46b3025c16723d5b4558def5b8107781b2251471c1f7170640342e3d4f78efb560d5ff6383c6a127c1d9e757e83db31a0185" +sha256 = "d0a8d048c41b566b978cd8ecd03fa51ec1f65af4c26be2f0fc9cfdd7dd6f34f3" +sha512 = "8d1c9ddaaea70ae54376bfc02dcdd0437336fb4fc67f89763ce09540caefe84cbae89a8de3605aa7613c49188636e925047bcd150c2c60685850095fefb68b73" [filesystem] -sha256 = "9eb3e27ea559c679e9fb3c775a7091efedd0dc52aec56d7cd28caba36a76309c" -sha512 = "4207a911dd647ecbe82727af2145d88fc536f013ef76fc173d7d07729c71e9ff8c08ce911f25fa8511705d62e60d4888c5cc43d498cd3753b164bbe1be2d3a55" +sha256 = "55942d9c31ed62d05d32d62d211a5c93983df7c0f1489124ca120cf58c4d61c0" +sha512 = "1250a19334ad6acf18adead4503f22c99bfbca7cfb7267431547d4bcca34f91e9635648d00f064276086887a9c80ffacbf68bee832b9e4cd1c921bec0776717f" [io] -sha256 = "671761f464d312e6c26bcaab5e79fe14ac876b72267867579d5c65e053fe2301" -sha512 = "57e5ed34fa85f35899b324ac7a2473c5fa5cece51d07e6f077637191fadd3c8b6f79324d31a8d497a6ce7b92cfb2a2505ab894337e2c82889f1bdb21f4f24634" +sha256 = "62ae80f2e340cddbac8e94f78e6270735aea536367ecb98de5f4ac6aef66b5c4" +sha512 = "a02a1ebd261ae884b0315b3528d1a93819ddc4b616f66c77f2bea9dd1de888208dc3b9004a553363f5e8491ea925d65ebbd0d68eaa87238316b47469a3bf97bb" [random] -sha256 = "5fc77fdcbf6fc236250c5ba32149ea2fde7a8191696d9a4ed3931bb07202bcc0" -sha512 = "1f3be8d65185552abad4532ed4603643b3f9eed1847d4c1acaec107964701990f18b1a036dcdccead85c29f037f272b3d1ce300c6e4316002b36431c04c00abd" +sha256 = "168a5a22cfc489bbde2a2ce38d3a20b5c418fb099d3993196fca2129f8e9bfc0" +sha512 = "1641fed653abe0991cdeee330bf6d3f6e17b9d2b3b9766588c792f181e8133727efa20feb41d0f325e3db8158ce51948c2d6648e02e8998df8eba3c88959bfca" [sockets] -sha256 = "4f98b623cb6ff6f02c2975cea615fa36de2087dc48e76c4865e0297499c005a1" -sha512 = "cf72b97c46913e752dff2d1c93d2c9bd87210d5714fe43d4eb93fb7512b1c786737e69b444521e77725e12a2689673da786bd0f3f94ce77bf7772671637d7878" +sha256 = "33b150bb413c6f4e2ab1ab12b6da822d6c712f13a0644177b108f57dff5783d6" +sha512 = "47efa2fea61374da2853b4ff2aed394b54c8e1d164ce6706332bd1056a16c2eb0a8d7c0ab5408a8b08537b615197ff4a44bdb5d132772a8d6049de5c39ec5e68" diff --git a/proposals/http/wit/deps.toml b/proposals/http/wit/deps.toml index 9f04d9e04..b1f5af240 100644 --- a/proposals/http/wit/deps.toml +++ b/proposals/http/wit/deps.toml @@ -1 +1 @@ -cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.6.tar.gz" +cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.7.tar.gz" diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit index 6d3cc83f5..dfecf913e 100644 --- a/proposals/http/wit/deps/cli/command.wit +++ b/proposals/http/wit/deps/cli/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.6; +package wasi:cli@0.2.7; @since(version = 0.2.0) world command { diff --git a/proposals/http/wit/deps/cli/imports.wit b/proposals/http/wit/deps/cli/imports.wit index d9fd01710..e7f7942de 100644 --- a/proposals/http/wit/deps/cli/imports.wit +++ b/proposals/http/wit/deps/cli/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.6; +package wasi:cli@0.2.7; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.6; + include wasi:clocks/imports@0.2.7; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.6; + include wasi:filesystem/imports@0.2.7; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.6; + include wasi:sockets/imports@0.2.7; @since(version = 0.2.0) - include wasi:random/imports@0.2.6; + include wasi:random/imports@0.2.7; @since(version = 0.2.0) - include wasi:io/imports@0.2.6; + include wasi:io/imports@0.2.7; @since(version = 0.2.0) import environment; diff --git a/proposals/http/wit/deps/cli/stdio.wit b/proposals/http/wit/deps/cli/stdio.wit index cb8aea2d9..1c3c6d074 100644 --- a/proposals/http/wit/deps/cli/stdio.wit +++ b/proposals/http/wit/deps/cli/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.6.{input-stream}; + use wasi:io/streams@0.2.7.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.6.{output-stream}; + use wasi:io/streams@0.2.7.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.6.{output-stream}; + use wasi:io/streams@0.2.7.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index f3bc83912..98a9ad42a 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.6; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.6.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/http/wit/deps/clocks/timezone.wit b/proposals/http/wit/deps/clocks/timezone.wit index ca98ad152..4740bde00 100644 --- a/proposals/http/wit/deps/clocks/timezone.wit +++ b/proposals/http/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/http/wit/deps/clocks/wall-clock.wit b/proposals/http/wit/deps/clocks/wall-clock.wit index 76636a0c9..2179b6c56 100644 --- a/proposals/http/wit/deps/clocks/wall-clock.wit +++ b/proposals/http/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/http/wit/deps/clocks/world.wit b/proposals/http/wit/deps/clocks/world.wit index 5c53c51a1..a08ff2c2c 100644 --- a/proposals/http/wit/deps/clocks/world.wit +++ b/proposals/http/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.6; +package wasi:clocks@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/filesystem/preopens.wit b/proposals/http/wit/deps/filesystem/preopens.wit index f22847940..b1a0a9972 100644 --- a/proposals/http/wit/deps/filesystem/preopens.wit +++ b/proposals/http/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.6; +package wasi:filesystem@0.2.7; @since(version = 0.2.0) interface preopens { diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index 75c19044c..a7da2b72f 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.6; +package wasi:filesystem@0.2.7; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.6; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.6.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.7.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.6.{datetime}; + use wasi:clocks/wall-clock@0.2.7.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/http/wit/deps/filesystem/world.wit b/proposals/http/wit/deps/filesystem/world.wit index 65597f9f2..67309b43f 100644 --- a/proposals/http/wit/deps/filesystem/world.wit +++ b/proposals/http/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.6; +package wasi:filesystem@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/io/error.wit b/proposals/http/wit/deps/io/error.wit index 784f74a53..acab3a811 100644 --- a/proposals/http/wit/deps/io/error.wit +++ b/proposals/http/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; @since(version = 0.2.0) interface error { diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/io/poll.wit index 7f711836c..a525164b9 100644 --- a/proposals/http/wit/deps/io/poll.wit +++ b/proposals/http/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index c5da38c86..7ae29a3cd 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -154,27 +154,13 @@ interface streams { /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write`, and `flush`, and is implemented with the - /// following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while !contents.is_empty() { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, contents.len()); - /// let (chunk, rest) = contents.split_at(len); - /// this.write(chunk ); // eliding error handling - /// contents = rest; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` + /// Returns success when all of the contents written are successfully + /// flushed to output. If an error occurs at any point before all + /// contents are successfully flushed, that error is returned as soon as + /// possible. If writing and flushing the complete contents causes the + /// stream to become closed, this call should return success, and + /// subsequent calls to check-write or other interfaces should return + /// stream-error::closed. @since(version = 0.2.0) blocking-write-and-flush: func( contents: list @@ -227,26 +213,8 @@ interface streams { /// Block until all of these operations are complete, or an error /// occurs. /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with - /// the following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while num_zeroes != 0 { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, num_zeroes); - /// this.write-zeroes(len); // eliding error handling - /// num_zeroes -= len; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` + /// Functionality is equivelant to `blocking-write-and-flush` with + /// contents given as a list of len containing only zeroes. @since(version = 0.2.0) blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit index 84c85c08e..73b1a6df5 100644 --- a/proposals/http/wit/deps/io/world.wit +++ b/proposals/http/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.6; +package wasi:io@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/random/insecure-seed.wit b/proposals/http/wit/deps/random/insecure-seed.wit index d3dc03a6c..0209b84b0 100644 --- a/proposals/http/wit/deps/random/insecure-seed.wit +++ b/proposals/http/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.6; +package wasi:random@0.2.7; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/insecure.wit b/proposals/http/wit/deps/random/insecure.wit index d4d028480..820d069ee 100644 --- a/proposals/http/wit/deps/random/insecure.wit +++ b/proposals/http/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.6; +package wasi:random@0.2.7; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index a0ff95646..974ab465d 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.6; +package wasi:random@0.2.7; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit index 099f47b36..333b42598 100644 --- a/proposals/http/wit/deps/random/world.wit +++ b/proposals/http/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.6; +package wasi:random@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/sockets/ip-name-lookup.wit b/proposals/http/wit/deps/sockets/ip-name-lookup.wit index ee6419e7d..df2735aac 100644 --- a/proposals/http/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.6.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/http/wit/deps/sockets/network.wit b/proposals/http/wit/deps/sockets/network.wit index 6ca98b63b..95df71ff3 100644 --- a/proposals/http/wit/deps/sockets/network.wit +++ b/proposals/http/wit/deps/sockets/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.6.{error}; + use wasi:io/error@0.2.7.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index beefd7b46..104d9aa39 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.6.{input-stream, output-stream}; + use wasi:io/streams@0.2.7.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.6.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.6.{duration}; + use wasi:clocks/monotonic-clock@0.2.7.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index 9dbe6932d..ecf2dfe60 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.6.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit index e86f02cec..9a4d317f7 100644 --- a/proposals/http/wit/deps/sockets/world.wit +++ b/proposals/http/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.6; +package wasi:sockets@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index 5bd9f9989..b503ea795 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,4 +1,4 @@ -package wasi:http@0.2.6; +package wasi:http@0.2.7; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. /// It is intended to be `include`d in other worlds. @@ -6,25 +6,25 @@ package wasi:http@0.2.6; world imports { /// HTTP proxies have access to time and randomness. @since(version = 0.2.0) - import wasi:clocks/monotonic-clock@0.2.6; + import wasi:clocks/monotonic-clock@0.2.7; @since(version = 0.2.0) - import wasi:clocks/wall-clock@0.2.6; + import wasi:clocks/wall-clock@0.2.7; @since(version = 0.2.0) - import wasi:random/random@0.2.6; + import wasi:random/random@0.2.7; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. @since(version = 0.2.0) - import wasi:cli/stdout@0.2.6; + import wasi:cli/stdout@0.2.7; @since(version = 0.2.0) - import wasi:cli/stderr@0.2.6; + import wasi:cli/stderr@0.2.7; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. @since(version = 0.2.0) - import wasi:cli/stdin@0.2.6; + import wasi:cli/stdin@0.2.7; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index c9f3cc4b9..9ebff8b50 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -4,13 +4,13 @@ @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.6.{duration}; + use wasi:clocks/monotonic-clock@0.2.7.{duration}; @since(version = 0.2.0) - use wasi:io/streams@0.2.6.{input-stream, output-stream}; + use wasi:io/streams@0.2.7.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/error@0.2.6.{error as io-error}; + use wasi:io/error@0.2.7.{error as io-error}; @since(version = 0.2.0) - use wasi:io/poll@0.2.6.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; /// This type corresponds to HTTP standard Methods. @since(version = 0.2.0) From dccc7144bdb10a82597d17609928d5fbd751fc3f Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 14 Aug 2025 13:15:09 -0400 Subject: [PATCH 1692/1772] ci: update, test, publish 0.3.0 workflows Intentionally keeping these distinct from 0.2.0 to allow for rapid iteration and changes to how we want to release in this next update to wasi. --- .../clocks/.github/workflows/publish-0.3.yml | 71 +++++++++++++++++ .../clocks/.github/workflows/update-0.3.yml | 79 +++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 proposals/clocks/.github/workflows/publish-0.3.yml create mode 100644 proposals/clocks/.github/workflows/update-0.3.yml diff --git a/proposals/clocks/.github/workflows/publish-0.3.yml b/proposals/clocks/.github/workflows/publish-0.3.yml new file mode 100644 index 000000000..cd5cdb0b0 --- /dev/null +++ b/proposals/clocks/.github/workflows/publish-0.3.yml @@ -0,0 +1,71 @@ +name: Publish 0.3.0 WIT Definitions + +# Run this action when changes are pushed to the main branch and affect files in the wit-0.3.0-draft directory +on: + push: + tags: + - v0.3.0-rc-* + workflow_dispatch: # Allow manual triggering + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + packages: write + contents: write + + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 + + - name: Install wkg + shell: bash + run: cargo binstall wkg + + - name: Install cosign + uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 + + # To version our image we want to obtain the version from the tag + - name: Get version + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/webassembly/wasi/clocks-0.3.0 + tags: | + type=semver,pattern={{version}} + + - name: Login to the GitHub registry + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.ORG_PAT }} + + - name: Build + shell: bash + run: wkg wit build -o "${{ github.event.repository.name }}-0.3.0.wasm" --wit-dir wit-0.3.0-draft + + # Upload the Wasm binary to the GitHub registry + - name: Publish to GitHub Container Registry + id: publish + uses: bytecodealliance/wkg-github-action@v5 + with: + oci-reference-without-tag: "ghcr.io/webassembly/wasi/clocks-0.3.0" + file: "${{ github.event.repository.name }}-0.3.0.wasm" + description: "A WASI API for reading the current time and measuring elapsed time (0.3.0 version)." + source: 'https://github.com/webassembly/wasi' + homepage: 'https://wasi.dev' + version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + licenses: 'Apache-2.0 WITH LLVM-exception' + + # Sign the output component + - name: Sign the wasm component + run: cosign sign --yes ghcr.io/webassembly/wasi/clocks-0.3.0@${{ steps.publish.outputs.digest }} diff --git a/proposals/clocks/.github/workflows/update-0.3.yml b/proposals/clocks/.github/workflows/update-0.3.yml new file mode 100644 index 000000000..77d122ee8 --- /dev/null +++ b/proposals/clocks/.github/workflows/update-0.3.yml @@ -0,0 +1,79 @@ +name: Update 0.3.0 WIT Definitions + +# Manually dispatch this action from the Actions page +on: + workflow_dispatch: + +permissions: + pull-requests: write + contents: write + +jobs: + update-versions: + runs-on: ubuntu-latest + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 + + # TODO: we don't pin the versions here. It's not great but this will simplify our iteration + # while we rapidly iterate on these tools. Pin when we're stable. + - name: Install wit-bindgen + shell: bash + run: cargo binstall wit-bindgen-cli + + - name: Install wit-deps + shell: bash + run: cargo binstall wit-deps-cli + + - name: Set version with RC timestamp + id: version + run: | + DATE=$(date +'%Y-%m-%d') + BASE_VERSION="0.3.0-rc-${DATE}" + COUNTER=1 + VERSION="${BASE_VERSION}" + + # Check if the tag already exists + while git ls-remote --tags origin | grep -q "refs/tags/v${VERSION}$"; do + VERSION="${BASE_VERSION}-${COUNTER}" + COUNTER=$((COUNTER + 1)) + done + + echo "value=${VERSION}" >> $GITHUB_OUTPUT + echo "Version will be: ${VERSION}" + + # Update version in WIT definitions + - name: Update version in WIT files + run: | + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(package wasi:[a-zA-Z0-9_-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + + + - name: Update wit deps + run: | + cd wit-0.3.0-draft + wit-deps update || true # Continue even if no deps to update + + # Create PR with changes using create-pull-request action + - name: Create Pull Request + uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" + committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + branch: update-wit-${{ steps.version.outputs.value }} + title: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" + body: | + Updates the 0.3.0 WIT definitions with version ${{ steps.version.outputs.value }}. + + This is an automated update to rev the RC timestamp. + + ## Changes + - Updated package and since version in WIT files + - Updated WIT dependencies if applicable + draft: false + delete-branch: true From 3298d76a10ff1373cc6fff28dc55d42348400929 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Aug 2025 21:26:02 +0000 Subject: [PATCH 1693/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-08-14 --- .../clocks/wit-0.3.0-draft/monotonic-clock.wit | 16 ++++++++-------- proposals/clocks/wit-0.3.0-draft/timezone.wit | 2 +- proposals/clocks/wit-0.3.0-draft/wall-clock.wit | 10 +++++----- proposals/clocks/wit-0.3.0-draft/world.wit | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit index 87ebdaac5..28dc81069 100644 --- a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit +++ b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-14; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,38 +7,38 @@ package wasi:clocks@0.3.0; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-14) interface monotonic-clock { /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-14) type instant = u64; /// A duration of time, in nanoseconds. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-14) type duration = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-14) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-14) resolution: func() -> duration; /// Wait until the specified instant has occurred. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-14) wait-until: func( when: instant, ); /// Wait for the specified duration has elapsed. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-14) wait-for: func( how-long: duration, ); diff --git a/proposals/clocks/wit-0.3.0-draft/timezone.wit b/proposals/clocks/wit-0.3.0-draft/timezone.wit index ac9146834..6311d6540 100644 --- a/proposals/clocks/wit-0.3.0-draft/timezone.wit +++ b/proposals/clocks/wit-0.3.0-draft/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-14; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/clocks/wit-0.3.0-draft/wall-clock.wit b/proposals/clocks/wit-0.3.0-draft/wall-clock.wit index b7a85ab35..88e4f9813 100644 --- a/proposals/clocks/wit-0.3.0-draft/wall-clock.wit +++ b/proposals/clocks/wit-0.3.0-draft/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-14; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,10 +13,10 @@ package wasi:clocks@0.3.0; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-14) interface wall-clock { /// A time and date in seconds plus nanoseconds. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-14) record datetime { seconds: u64, nanoseconds: u32, @@ -35,12 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-14) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-14) resolution: func() -> datetime; } diff --git a/proposals/clocks/wit-0.3.0-draft/world.wit b/proposals/clocks/wit-0.3.0-draft/world.wit index f97bcfef1..3c973184e 100644 --- a/proposals/clocks/wit-0.3.0-draft/world.wit +++ b/proposals/clocks/wit-0.3.0-draft/world.wit @@ -1,10 +1,10 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-14; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-14) world imports { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-14) import monotonic-clock; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-14) import wall-clock; @unstable(feature = clocks-timezone) import timezone; From 145bc3453d2523465f34acc7a9af2bdb33fc11e5 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 14 Aug 2025 19:36:53 -0400 Subject: [PATCH 1694/1772] ci: publish workflows for 0.3.0-rc's --- .../random/.github/workflows/publish-0.3.yml | 70 ++++++++++++++++ .../random/.github/workflows/publish.yml | 2 +- .../random/.github/workflows/update-0.3.yml | 79 +++++++++++++++++++ 3 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 proposals/random/.github/workflows/publish-0.3.yml create mode 100644 proposals/random/.github/workflows/update-0.3.yml diff --git a/proposals/random/.github/workflows/publish-0.3.yml b/proposals/random/.github/workflows/publish-0.3.yml new file mode 100644 index 000000000..52a2e728e --- /dev/null +++ b/proposals/random/.github/workflows/publish-0.3.yml @@ -0,0 +1,70 @@ +name: Publish 0.3.0 WIT Definitions + +on: + push: + tags: + - v0.3.0-rc-* + workflow_dispatch: # Allow manual triggering + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + packages: write + contents: write + + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 + + - name: Install wkg + shell: bash + run: cargo binstall wkg + + - name: Install cosign + uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 + + # To version our image we want to obtain the version from the tag + - name: Get version + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/webassembly/wasi/random-0.3.0 + tags: | + type=semver,pattern={{version}} + + - name: Login to the GitHub registry + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.ORG_PAT }} + + - name: Build + shell: bash + run: wkg wit build -o "${{ github.event.repository.name }}-0.3.0.wasm" --wit-dir wit-0.3.0-draft + + # Upload the Wasm binary to the GitHub registry + - name: Publish to GitHub Container Registry + id: publish + uses: bytecodealliance/wkg-github-action@v5 + with: + oci-reference-without-tag: "ghcr.io/webassembly/wasi/random-0.3.0" + file: "${{ github.event.repository.name }}-0.3.0.wasm" + description: "A WASI API for reading the current time and measuring elapsed time (0.3.0 version)." + source: 'https://github.com/webassembly/wasi' + homepage: 'https://wasi.dev' + version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + licenses: 'Apache-2.0 WITH LLVM-exception' + + # Sign the output component + - name: Sign the wasm component + run: cosign sign --yes ghcr.io/webassembly/wasi/random-0.3.0@${{ steps.publish.outputs.digest }} diff --git a/proposals/random/.github/workflows/publish.yml b/proposals/random/.github/workflows/publish.yml index 8b5f3c54a..1ed7fad7c 100644 --- a/proposals/random/.github/workflows/publish.yml +++ b/proposals/random/.github/workflows/publish.yml @@ -4,7 +4,7 @@ name: Publish a Wasm Component package to GitHub Artifacts on: push: tags: - - v* + - v0.2.* workflow_dispatch: env: diff --git a/proposals/random/.github/workflows/update-0.3.yml b/proposals/random/.github/workflows/update-0.3.yml new file mode 100644 index 000000000..77d122ee8 --- /dev/null +++ b/proposals/random/.github/workflows/update-0.3.yml @@ -0,0 +1,79 @@ +name: Update 0.3.0 WIT Definitions + +# Manually dispatch this action from the Actions page +on: + workflow_dispatch: + +permissions: + pull-requests: write + contents: write + +jobs: + update-versions: + runs-on: ubuntu-latest + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 + + # TODO: we don't pin the versions here. It's not great but this will simplify our iteration + # while we rapidly iterate on these tools. Pin when we're stable. + - name: Install wit-bindgen + shell: bash + run: cargo binstall wit-bindgen-cli + + - name: Install wit-deps + shell: bash + run: cargo binstall wit-deps-cli + + - name: Set version with RC timestamp + id: version + run: | + DATE=$(date +'%Y-%m-%d') + BASE_VERSION="0.3.0-rc-${DATE}" + COUNTER=1 + VERSION="${BASE_VERSION}" + + # Check if the tag already exists + while git ls-remote --tags origin | grep -q "refs/tags/v${VERSION}$"; do + VERSION="${BASE_VERSION}-${COUNTER}" + COUNTER=$((COUNTER + 1)) + done + + echo "value=${VERSION}" >> $GITHUB_OUTPUT + echo "Version will be: ${VERSION}" + + # Update version in WIT definitions + - name: Update version in WIT files + run: | + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(package wasi:[a-zA-Z0-9_-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + + + - name: Update wit deps + run: | + cd wit-0.3.0-draft + wit-deps update || true # Continue even if no deps to update + + # Create PR with changes using create-pull-request action + - name: Create Pull Request + uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" + committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + branch: update-wit-${{ steps.version.outputs.value }} + title: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" + body: | + Updates the 0.3.0 WIT definitions with version ${{ steps.version.outputs.value }}. + + This is an automated update to rev the RC timestamp. + + ## Changes + - Updated package and since version in WIT files + - Updated WIT dependencies if applicable + draft: false + delete-branch: true From e64e6ac007179cbb52a9d3a25a4c0ca02fbb43c8 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 14 Aug 2025 13:15:09 -0400 Subject: [PATCH 1695/1772] ci: update, test, publish 0.3.0 workflows Intentionally keeping these distinct from 0.2.0 to allow for rapid iteration and changes to how we want to release in this next update to wasi. --- proposals/clocks/.github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/.github/workflows/publish.yml b/proposals/clocks/.github/workflows/publish.yml index e66a5ed1e..84d44f3be 100644 --- a/proposals/clocks/.github/workflows/publish.yml +++ b/proposals/clocks/.github/workflows/publish.yml @@ -4,7 +4,7 @@ name: Publish a Wasm Component package to GitHub Artifacts on: push: tags: - - v* + - v0.2.* workflow_dispatch: env: From 171e314355b690e61a4bf2f47690d171cb19573f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Aug 2025 17:05:11 +0200 Subject: [PATCH 1696/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-08-15 (#92) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../wit-0.3.0-draft/monotonic-clock.wit | 22 +++++++++---------- proposals/clocks/wit-0.3.0-draft/timezone.wit | 2 +- .../clocks/wit-0.3.0-draft/wall-clock.wit | 12 +++++----- proposals/clocks/wit-0.3.0-draft/world.wit | 8 +++---- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit index 28dc81069..0c58241ff 100644 --- a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit +++ b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-14; +package wasi:clocks@0.3.0-rc-2025-08-15; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,39 +7,39 @@ package wasi:clocks@0.3.0-rc-2025-08-14; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0-rc-2025-08-14) +@since(version = 0.3.0-rc-2025-08-15) interface monotonic-clock { /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. - @since(version = 0.3.0-rc-2025-08-14) + @since(version = 0.3.0-rc-2025-08-15) type instant = u64; /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-08-14) + @since(version = 0.3.0-rc-2025-08-15) type duration = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - @since(version = 0.3.0-rc-2025-08-14) + @since(version = 0.3.0-rc-2025-08-15) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. - @since(version = 0.3.0-rc-2025-08-14) - resolution: func() -> duration; + @since(version = 0.3.0-rc-2025-08-15) + get-resolution: func() -> duration; /// Wait until the specified instant has occurred. - @since(version = 0.3.0-rc-2025-08-14) - wait-until: func( + @since(version = 0.3.0-rc-2025-08-15) + wait-until: async func( when: instant, ); /// Wait for the specified duration has elapsed. - @since(version = 0.3.0-rc-2025-08-14) - wait-for: func( + @since(version = 0.3.0-rc-2025-08-15) + wait-for: async func( how-long: duration, ); } diff --git a/proposals/clocks/wit-0.3.0-draft/timezone.wit b/proposals/clocks/wit-0.3.0-draft/timezone.wit index 6311d6540..2ee16ab20 100644 --- a/proposals/clocks/wit-0.3.0-draft/timezone.wit +++ b/proposals/clocks/wit-0.3.0-draft/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-14; +package wasi:clocks@0.3.0-rc-2025-08-15; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/clocks/wit-0.3.0-draft/wall-clock.wit b/proposals/clocks/wit-0.3.0-draft/wall-clock.wit index 88e4f9813..2e3b2d441 100644 --- a/proposals/clocks/wit-0.3.0-draft/wall-clock.wit +++ b/proposals/clocks/wit-0.3.0-draft/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-14; +package wasi:clocks@0.3.0-rc-2025-08-15; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,10 +13,10 @@ package wasi:clocks@0.3.0-rc-2025-08-14; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0-rc-2025-08-14) +@since(version = 0.3.0-rc-2025-08-15) interface wall-clock { /// A time and date in seconds plus nanoseconds. - @since(version = 0.3.0-rc-2025-08-14) + @since(version = 0.3.0-rc-2025-08-15) record datetime { seconds: u64, nanoseconds: u32, @@ -35,12 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0-rc-2025-08-14) + @since(version = 0.3.0-rc-2025-08-15) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0-rc-2025-08-14) - resolution: func() -> datetime; + @since(version = 0.3.0-rc-2025-08-15) + get-resolution: func() -> datetime; } diff --git a/proposals/clocks/wit-0.3.0-draft/world.wit b/proposals/clocks/wit-0.3.0-draft/world.wit index 3c973184e..94068c75c 100644 --- a/proposals/clocks/wit-0.3.0-draft/world.wit +++ b/proposals/clocks/wit-0.3.0-draft/world.wit @@ -1,10 +1,10 @@ -package wasi:clocks@0.3.0-rc-2025-08-14; +package wasi:clocks@0.3.0-rc-2025-08-15; -@since(version = 0.3.0-rc-2025-08-14) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0-rc-2025-08-14) + @since(version = 0.3.0-rc-2025-08-15) import monotonic-clock; - @since(version = 0.3.0-rc-2025-08-14) + @since(version = 0.3.0-rc-2025-08-15) import wall-clock; @unstable(feature = clocks-timezone) import timezone; From b090ec20e2d4b9180b3d719fa6a40fcd6562229f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Aug 2025 17:44:32 +0000 Subject: [PATCH 1697/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-08-15 --- proposals/random/wit-0.3.0-draft/insecure-seed.wit | 6 +++--- proposals/random/wit-0.3.0-draft/insecure.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/random.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/world.wit | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/proposals/random/wit-0.3.0-draft/insecure-seed.wit b/proposals/random/wit-0.3.0-draft/insecure-seed.wit index 86c988c2e..ecd504318 100644 --- a/proposals/random/wit-0.3.0-draft/insecure-seed.wit +++ b/proposals/random/wit-0.3.0-draft/insecure-seed.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0; +package wasi:random@0.3.0-rc-2025-08-15; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-insecure-seed: func() -> tuple; } diff --git a/proposals/random/wit-0.3.0-draft/insecure.wit b/proposals/random/wit-0.3.0-draft/insecure.wit index 4ea5e581f..d08d85e0b 100644 --- a/proposals/random/wit-0.3.0-draft/insecure.wit +++ b/proposals/random/wit-0.3.0-draft/insecure.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0; +package wasi:random@0.3.0-rc-2025-08-15; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/random.wit b/proposals/random/wit-0.3.0-draft/random.wit index 786ef25f6..3808c3095 100644 --- a/proposals/random/wit-0.3.0-draft/random.wit +++ b/proposals/random/wit-0.3.0-draft/random.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0; +package wasi:random@0.3.0-rc-2025-08-15; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/world.wit b/proposals/random/wit-0.3.0-draft/world.wit index 838d38023..e8f05cc43 100644 --- a/proposals/random/wit-0.3.0-draft/world.wit +++ b/proposals/random/wit-0.3.0-draft/world.wit @@ -1,13 +1,13 @@ -package wasi:random@0.3.0; +package wasi:random@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import random; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import insecure; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import insecure-seed; } From 560df25a1276032566b6254c004dbccd512f0451 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Fri, 15 Aug 2025 14:22:00 -0400 Subject: [PATCH 1698/1772] ci: add 0.3 publishing workflows --- proposals/sockets/.github/workflows/main.yml | 2 +- .../sockets/.github/workflows/publish-0.3.yml | 72 +++++++++++++++++ .../sockets/.github/workflows/publish.yml | 8 +- .../sockets/.github/workflows/update-0.3.yml | 79 +++++++++++++++++++ .../sockets/.github/workflows/update.yml | 4 +- 5 files changed, 158 insertions(+), 7 deletions(-) create mode 100644 proposals/sockets/.github/workflows/publish-0.3.yml create mode 100644 proposals/sockets/.github/workflows/update-0.3.yml diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml index 4caaff1aa..cfc4f7ea5 100644 --- a/proposals/sockets/.github/workflows/main.yml +++ b/proposals/sockets/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ensure `./wit/deps` are in sync run: | curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.5.0/wit-deps-x86_64-unknown-linux-musl diff --git a/proposals/sockets/.github/workflows/publish-0.3.yml b/proposals/sockets/.github/workflows/publish-0.3.yml new file mode 100644 index 000000000..e278d528e --- /dev/null +++ b/proposals/sockets/.github/workflows/publish-0.3.yml @@ -0,0 +1,72 @@ +name: Publish 0.3.0 WIT Definitions + +on: + push: + tags: + - v0.3.0-rc-* + workflow_dispatch: # Allow manual triggering + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + packages: write + contents: write + + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 + + # TODO: we don't pin the versions here. It's not great but this will simplify our iteration + # while we rapidly iterate on these tools. Pin when we're stable. + - name: Install wkg + shell: bash + run: cargo binstall wkg + + - name: Install cosign + uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 + + # To version our image we want to obtain the version from the tag + - name: Get version + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/webassembly/wasi/sockets-0.3.0 + tags: | + type=semver,pattern={{version}} + + - name: Login to the GitHub registry + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.ORG_PAT }} + + - name: Build + shell: bash + run: wkg wit build -o "${{ github.event.repository.name }}-0.3.0.wasm" --wit-dir wit-0.3.0-draft + + # Upload the Wasm binary to the GitHub registry + - name: Publish to GitHub Container Registry + id: publish + uses: bytecodealliance/wkg-github-action@v5 + with: + oci-reference-without-tag: "ghcr.io/webassembly/wasi/sockets-0.3.0" + file: "${{ github.event.repository.name }}-0.3.0.wasm" + description: "A WASI API for reading the current time and measuring elapsed time (0.3.0 version)." + source: 'https://github.com/webassembly/wasi' + homepage: 'https://wasi.dev' + version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + licenses: 'Apache-2.0 WITH LLVM-exception' + + # Sign the output component + - name: Sign the wasm component + run: cosign sign --yes ghcr.io/webassembly/wasi/sockets-0.3.0@${{ steps.publish.outputs.digest }} diff --git a/proposals/sockets/.github/workflows/publish.yml b/proposals/sockets/.github/workflows/publish.yml index 90109fb63..cf5f71c66 100644 --- a/proposals/sockets/.github/workflows/publish.yml +++ b/proposals/sockets/.github/workflows/publish.yml @@ -4,7 +4,7 @@ name: Publish a Wasm Component package to GitHub Artifacts on: push: tags: - - v* + - v0.2.* workflow_dispatch: env: @@ -23,12 +23,12 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@v1.10.15 + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - name: Install wkg shell: bash run: cargo binstall wkg - name: Install cosign - uses: sigstore/cosign-installer@v3.7.0 + uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 # To version our image we want to obtain the version from the tag - name: Get version @@ -41,7 +41,7 @@ jobs: # To upload our image to the GitHub registry, we first have to login - name: Login to the GitHub registry - uses: docker/login-action@v3 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 with: registry: ghcr.io username: ${{ github.actor }} diff --git a/proposals/sockets/.github/workflows/update-0.3.yml b/proposals/sockets/.github/workflows/update-0.3.yml new file mode 100644 index 000000000..77d122ee8 --- /dev/null +++ b/proposals/sockets/.github/workflows/update-0.3.yml @@ -0,0 +1,79 @@ +name: Update 0.3.0 WIT Definitions + +# Manually dispatch this action from the Actions page +on: + workflow_dispatch: + +permissions: + pull-requests: write + contents: write + +jobs: + update-versions: + runs-on: ubuntu-latest + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 + + # TODO: we don't pin the versions here. It's not great but this will simplify our iteration + # while we rapidly iterate on these tools. Pin when we're stable. + - name: Install wit-bindgen + shell: bash + run: cargo binstall wit-bindgen-cli + + - name: Install wit-deps + shell: bash + run: cargo binstall wit-deps-cli + + - name: Set version with RC timestamp + id: version + run: | + DATE=$(date +'%Y-%m-%d') + BASE_VERSION="0.3.0-rc-${DATE}" + COUNTER=1 + VERSION="${BASE_VERSION}" + + # Check if the tag already exists + while git ls-remote --tags origin | grep -q "refs/tags/v${VERSION}$"; do + VERSION="${BASE_VERSION}-${COUNTER}" + COUNTER=$((COUNTER + 1)) + done + + echo "value=${VERSION}" >> $GITHUB_OUTPUT + echo "Version will be: ${VERSION}" + + # Update version in WIT definitions + - name: Update version in WIT files + run: | + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(package wasi:[a-zA-Z0-9_-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + + + - name: Update wit deps + run: | + cd wit-0.3.0-draft + wit-deps update || true # Continue even if no deps to update + + # Create PR with changes using create-pull-request action + - name: Create Pull Request + uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" + committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + branch: update-wit-${{ steps.version.outputs.value }} + title: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" + body: | + Updates the 0.3.0 WIT definitions with version ${{ steps.version.outputs.value }}. + + This is an automated update to rev the RC timestamp. + + ## Changes + - Updated package and since version in WIT files + - Updated WIT dependencies if applicable + draft: false + delete-branch: true diff --git a/proposals/sockets/.github/workflows/update.yml b/proposals/sockets/.github/workflows/update.yml index bdf61d30c..850cb6bf3 100644 --- a/proposals/sockets/.github/workflows/update.yml +++ b/proposals/sockets/.github/workflows/update.yml @@ -23,9 +23,9 @@ jobs: steps: # Checkout the repo and install dependencies - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@v1.10.15 + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - name: Install wit-bindgen shell: bash run: cargo binstall wit-bindgen-cli From 72c7646065626da53c1df6710423d5e8144fc6d5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Aug 2025 18:28:44 +0000 Subject: [PATCH 1699/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-08-15 --- proposals/sockets/wit-0.3.0-draft/deps.lock | 4 +- .../deps/clocks/monotonic-clock.wit | 22 ++-- .../wit-0.3.0-draft/deps/clocks/timezone.wit | 2 +- .../deps/clocks/wall-clock.wit | 12 +- .../wit-0.3.0-draft/deps/clocks/world.wit | 8 +- .../wit-0.3.0-draft/ip-name-lookup.wit | 8 +- proposals/sockets/wit-0.3.0-draft/types.wit | 106 +++++++++--------- proposals/sockets/wit-0.3.0-draft/world.wit | 8 +- 8 files changed, 85 insertions(+), 85 deletions(-) diff --git a/proposals/sockets/wit-0.3.0-draft/deps.lock b/proposals/sockets/wit-0.3.0-draft/deps.lock index 03868084d..07d589294 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps.lock +++ b/proposals/sockets/wit-0.3.0-draft/deps.lock @@ -1,5 +1,5 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "26e315db0d371495f8834edfc0e479042f94152ce677d96d54d3623d0e4ffb1e" -sha512 = "e1c76f499435841316f9287b88d8173558e64f277c321ff390556de8707a0b18dd6c1749bbb17bbbba8d523da246ef6eb05c990ceddb762e03efb2ae30cacc76" +sha256 = "626953ec28ae956ec1233c4350deab6e5cdcbdd9ae6d491e102ad7c6901cc8bf" +sha512 = "ae375b002cfaacdbaa133bb87747d1b86675e13144067c3005d6c32cf5c37bb7a52b693ae46d5cd65fc4910a78d7255d0ada5142828a022497fd0eaacb61761f" diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 87ebdaac5..0c58241ff 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,39 +7,39 @@ package wasi:clocks@0.3.0; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface monotonic-clock { /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type instant = u64; /// A duration of time, in nanoseconds. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type duration = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. - @since(version = 0.3.0) - resolution: func() -> duration; + @since(version = 0.3.0-rc-2025-08-15) + get-resolution: func() -> duration; /// Wait until the specified instant has occurred. - @since(version = 0.3.0) - wait-until: func( + @since(version = 0.3.0-rc-2025-08-15) + wait-until: async func( when: instant, ); /// Wait for the specified duration has elapsed. - @since(version = 0.3.0) - wait-for: func( + @since(version = 0.3.0-rc-2025-08-15) + wait-for: async func( how-long: duration, ); } diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/timezone.wit index ac9146834..2ee16ab20 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps/clocks/timezone.wit +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/wall-clock.wit index b7a85ab35..2e3b2d441 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps/clocks/wall-clock.wit +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,10 +13,10 @@ package wasi:clocks@0.3.0; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface wall-clock { /// A time and date in seconds plus nanoseconds. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record datetime { seconds: u64, nanoseconds: u32, @@ -35,12 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0) - resolution: func() -> datetime; + @since(version = 0.3.0-rc-2025-08-15) + get-resolution: func() -> datetime; } diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/world.wit index f97bcfef1..94068c75c 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps/clocks/world.wit +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/world.wit @@ -1,10 +1,10 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import monotonic-clock; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import wall-clock; @unstable(feature = clocks-timezone) import timezone; diff --git a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit index 73b4b201f..ab4156e25 100644 --- a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit +++ b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit @@ -1,10 +1,10 @@ -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface ip-name-lookup { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) use types.{ip-address}; /// Lookup error codes. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum error-code { /// Unknown error unknown, @@ -57,6 +57,6 @@ interface ip-name-lookup { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) resolve-addresses: async func(name: string) -> result, error-code>; } diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index dcc61265c..3a7915ce9 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -1,7 +1,7 @@ -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface types { - @since(version = 0.3.0) - use wasi:clocks/monotonic-clock@0.3.0.{duration}; + @since(version = 0.3.0-rc-2025-08-15) + use wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15.{duration}; /// Error codes. /// @@ -14,7 +14,7 @@ interface types { /// - `out-of-memory` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum error-code { /// Unknown error unknown, @@ -70,7 +70,7 @@ interface types { datagram-too-large, } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -79,18 +79,18 @@ interface types { ipv6, } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type ipv4-address = tuple; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type ipv6-address = tuple; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record ipv4-socket-address { /// sin_port port: u16, @@ -98,7 +98,7 @@ interface types { address: ipv4-address, } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record ipv6-socket-address { /// sin6_port port: u16, @@ -110,7 +110,7 @@ interface types { scope-id: u32, } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), @@ -135,7 +135,7 @@ interface types { /// In addition to the general error codes documented on the /// `types::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) resource tcp-socket { /// Create a new TCP socket. @@ -152,7 +152,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. @@ -186,7 +186,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Connect to a remote endpoint. @@ -218,7 +218,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) connect: async func(remote-address: ip-socket-address) -> result<_, error-code>; /// Start listening and return a stream of new inbound connections. @@ -285,7 +285,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) listen: func() -> result, error-code>; /// Transmit data to peer. @@ -308,7 +308,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) send: async func(data: stream) -> result<_, error-code>; /// Read data from peer. @@ -342,7 +342,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) receive: func() -> tuple, future>>; /// Get the bound local address. @@ -361,7 +361,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-local-address: func() -> result; /// Get the remote address. @@ -374,13 +374,13 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. @@ -388,7 +388,7 @@ interface types { /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. @@ -400,7 +400,7 @@ interface types { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -412,9 +412,9 @@ interface types { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-keep-alive-enabled: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. @@ -427,9 +427,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-keep-alive-idle-time: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. @@ -442,9 +442,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-keep-alive-interval: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. @@ -457,9 +457,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-keep-alive-count: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -468,9 +468,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-hop-limit: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -483,18 +483,18 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-send-buffer-size: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } /// A UDP socket handle. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) resource udp-socket { /// Create a new UDP socket. @@ -511,7 +511,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. @@ -532,7 +532,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Associate this socket with a specific peer address. @@ -571,7 +571,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) connect: func(remote-address: ip-socket-address) -> result<_, error-code>; /// Dissociate this socket from its peer address. @@ -589,7 +589,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) disconnect: func() -> result<_, error-code>; /// Send a message on the socket to a particular peer. @@ -623,7 +623,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) send: async func(data: list, remote-address: option) -> result<_, error-code>; /// Receive a message on the socket. @@ -649,7 +649,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) receive: async func() -> result, ip-socket-address>, error-code>; /// Get the current bound address. @@ -668,7 +668,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-local-address: func() -> result; /// Get the address the socket is currently "connected" to. @@ -681,7 +681,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. @@ -689,7 +689,7 @@ interface types { /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -698,9 +698,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-unicast-hop-limit: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -713,13 +713,13 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-send-buffer-size: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } } diff --git a/proposals/sockets/wit-0.3.0-draft/world.wit b/proposals/sockets/wit-0.3.0-draft/world.wit index 6c9951d1c..dfafac2ae 100644 --- a/proposals/sockets/wit-0.3.0-draft/world.wit +++ b/proposals/sockets/wit-0.3.0-draft/world.wit @@ -1,9 +1,9 @@ -package wasi:sockets@0.3.0; +package wasi:sockets@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import types; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import ip-name-lookup; } From 503065e341e574e4eca85216a55b7adec532450e Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Fri, 15 Aug 2025 14:46:59 -0400 Subject: [PATCH 1700/1772] fix: regex to include all wit directives Signed-off-by: Bailey Hayes --- proposals/sockets/.github/workflows/update-0.3.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/sockets/.github/workflows/update-0.3.yml b/proposals/sockets/.github/workflows/update-0.3.yml index 77d122ee8..d64510e1c 100644 --- a/proposals/sockets/.github/workflows/update-0.3.yml +++ b/proposals/sockets/.github/workflows/update-0.3.yml @@ -49,8 +49,10 @@ jobs: # Update version in WIT definitions - name: Update version in WIT files run: | + # Update @since version annotations find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(package wasi:[a-zA-Z0-9_-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + + # Update all wasi package references (package, use, import, export, from) + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\( wasi:[a-zA-Z0-9_/-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + - name: Update wit deps run: | From 6c07397f185085db56497d23427026a13eb342b9 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Fri, 15 Aug 2025 15:11:51 -0400 Subject: [PATCH 1701/1772] ci: fix 0.3 wit-deps update --- proposals/sockets/.github/workflows/update-0.3.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/sockets/.github/workflows/update-0.3.yml b/proposals/sockets/.github/workflows/update-0.3.yml index d64510e1c..7bceb94e1 100644 --- a/proposals/sockets/.github/workflows/update-0.3.yml +++ b/proposals/sockets/.github/workflows/update-0.3.yml @@ -56,8 +56,7 @@ jobs: - name: Update wit deps run: | - cd wit-0.3.0-draft - wit-deps update || true # Continue even if no deps to update + wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps update # Create PR with changes using create-pull-request action - name: Create Pull Request From 2c3ee2a21ba80724cb5e8938ed89fc3cdb4016a5 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Fri, 15 Aug 2025 15:31:07 -0400 Subject: [PATCH 1702/1772] ci: must use same oci URI as 0.2 Limited by wkg registry discovery for downstream wkg build --- proposals/clocks/.github/workflows/publish-0.3.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/clocks/.github/workflows/publish-0.3.yml b/proposals/clocks/.github/workflows/publish-0.3.yml index cd5cdb0b0..1f1304ceb 100644 --- a/proposals/clocks/.github/workflows/publish-0.3.yml +++ b/proposals/clocks/.github/workflows/publish-0.3.yml @@ -38,7 +38,7 @@ jobs: id: meta uses: docker/metadata-action@v5 with: - images: ghcr.io/webassembly/wasi/clocks-0.3.0 + images: ghcr.io/webassembly/wasi/clocks tags: | type=semver,pattern={{version}} @@ -58,7 +58,7 @@ jobs: id: publish uses: bytecodealliance/wkg-github-action@v5 with: - oci-reference-without-tag: "ghcr.io/webassembly/wasi/clocks-0.3.0" + oci-reference-without-tag: "ghcr.io/webassembly/wasi/clocks" file: "${{ github.event.repository.name }}-0.3.0.wasm" description: "A WASI API for reading the current time and measuring elapsed time (0.3.0 version)." source: 'https://github.com/webassembly/wasi' @@ -68,4 +68,4 @@ jobs: # Sign the output component - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/clocks-0.3.0@${{ steps.publish.outputs.digest }} + run: cosign sign --yes ghcr.io/webassembly/wasi/clocks@${{ steps.publish.outputs.digest }} From 310b6af74e936098cadc1c5fb4a165fe719c7371 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Fri, 15 Aug 2025 15:39:37 -0400 Subject: [PATCH 1703/1772] fix: regex to include all wit directives --- proposals/clocks/.github/workflows/update-0.3.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/proposals/clocks/.github/workflows/update-0.3.yml b/proposals/clocks/.github/workflows/update-0.3.yml index 77d122ee8..7ed9421cf 100644 --- a/proposals/clocks/.github/workflows/update-0.3.yml +++ b/proposals/clocks/.github/workflows/update-0.3.yml @@ -49,13 +49,10 @@ jobs: # Update version in WIT definitions - name: Update version in WIT files run: | + # Update @since version annotations find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(package wasi:[a-zA-Z0-9_-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + - - - name: Update wit deps - run: | - cd wit-0.3.0-draft - wit-deps update || true # Continue even if no deps to update + # Update all wasi package references (package, use, import, export, from) + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\( wasi:[a-zA-Z0-9_/-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + # Create PR with changes using create-pull-request action - name: Create Pull Request From ffea48184df605917ee9bdb7bbc63c0d2fc155ef Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Fri, 15 Aug 2025 15:48:04 -0400 Subject: [PATCH 1704/1772] ci: must use same oci URI package as 0.2 Limited by wkg registry discovery for downstream wkg build --- proposals/sockets/.github/workflows/publish-0.3.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/sockets/.github/workflows/publish-0.3.yml b/proposals/sockets/.github/workflows/publish-0.3.yml index e278d528e..5eb3c0b0e 100644 --- a/proposals/sockets/.github/workflows/publish-0.3.yml +++ b/proposals/sockets/.github/workflows/publish-0.3.yml @@ -39,7 +39,7 @@ jobs: id: meta uses: docker/metadata-action@v5 with: - images: ghcr.io/webassembly/wasi/sockets-0.3.0 + images: ghcr.io/webassembly/wasi/sockets tags: | type=semver,pattern={{version}} @@ -59,7 +59,7 @@ jobs: id: publish uses: bytecodealliance/wkg-github-action@v5 with: - oci-reference-without-tag: "ghcr.io/webassembly/wasi/sockets-0.3.0" + oci-reference-without-tag: "ghcr.io/webassembly/wasi/sockets" file: "${{ github.event.repository.name }}-0.3.0.wasm" description: "A WASI API for reading the current time and measuring elapsed time (0.3.0 version)." source: 'https://github.com/webassembly/wasi' @@ -69,4 +69,4 @@ jobs: # Sign the output component - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/sockets-0.3.0@${{ steps.publish.outputs.digest }} + run: cosign sign --yes ghcr.io/webassembly/wasi/sockets@${{ steps.publish.outputs.digest }} From f07667c03f5ee81064c99da4bcbda1547b2ae34a Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Fri, 15 Aug 2025 15:36:12 -0400 Subject: [PATCH 1705/1772] ci: publish 0.3. workflows --- .../filesystem/.github/workflows/main.yml | 6 +- .../.github/workflows/publish-0.3.yml | 72 +++++++++++++++++ .../filesystem/.github/workflows/publish.yml | 8 +- .../.github/workflows/update-0.3.yml | 80 +++++++++++++++++++ .../filesystem/.github/workflows/update.yml | 4 +- 5 files changed, 161 insertions(+), 9 deletions(-) create mode 100644 proposals/filesystem/.github/workflows/publish-0.3.yml create mode 100644 proposals/filesystem/.github/workflows/update-0.3.yml diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml index ae5630788..7641394b9 100644 --- a/proposals/filesystem/.github/workflows/main.yml +++ b/proposals/filesystem/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ensure `./wit/deps` are in sync run: | curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.5.0/wit-deps-x86_64-unknown-linux-musl @@ -20,6 +20,6 @@ jobs: git add -N wit/deps git add -N wit-0.3.0-draft/deps git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v24 + - uses: WebAssembly/wit-abi-up-to-date@v25 with: - all-features: 'true' \ No newline at end of file + all-features: 'true' diff --git a/proposals/filesystem/.github/workflows/publish-0.3.yml b/proposals/filesystem/.github/workflows/publish-0.3.yml new file mode 100644 index 000000000..0367997eb --- /dev/null +++ b/proposals/filesystem/.github/workflows/publish-0.3.yml @@ -0,0 +1,72 @@ +name: Publish 0.3.0 WIT Definitions + +on: + push: + tags: + - v0.3.0-rc-* + workflow_dispatch: # Allow manual triggering + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + packages: write + contents: write + + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 + + # TODO: we don't pin the versions here. It's not great but this will simplify our iteration + # while we rapidly iterate on these tools. Pin when we're stable. + - name: Install wkg + shell: bash + run: cargo binstall wkg + + - name: Install cosign + uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 + + # To version our image we want to obtain the version from the tag + - name: Get version + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/webassembly/wasi/filesystem + tags: | + type=semver,pattern={{version}} + + - name: Login to the GitHub registry + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.ORG_PAT }} + + - name: Build + shell: bash + run: wkg wit build -o "${{ github.event.repository.name }}-0.3.0.wasm" --wit-dir wit-0.3.0-draft + + # Upload the Wasm binary to the GitHub registry + - name: Publish to GitHub Container Registry + id: publish + uses: bytecodealliance/wkg-github-action@v5 + with: + oci-reference-without-tag: "ghcr.io/webassembly/wasi/filesystem" + file: "${{ github.event.repository.name }}-0.3.0.wasm" + description: "A WASI API for reading the current time and measuring elapsed time (0.3.0 version)." + source: 'https://github.com/webassembly/wasi' + homepage: 'https://wasi.dev' + version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + licenses: 'Apache-2.0 WITH LLVM-exception' + + # Sign the output component + - name: Sign the wasm component + run: cosign sign --yes ghcr.io/webassembly/wasi/filesystem@${{ steps.publish.outputs.digest }} diff --git a/proposals/filesystem/.github/workflows/publish.yml b/proposals/filesystem/.github/workflows/publish.yml index 8c04ca6eb..1e4de427f 100644 --- a/proposals/filesystem/.github/workflows/publish.yml +++ b/proposals/filesystem/.github/workflows/publish.yml @@ -4,7 +4,7 @@ name: Publish a Wasm Component package to GitHub Artifacts on: push: tags: - - v* + - v0.2.* workflow_dispatch: env: @@ -23,12 +23,12 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@v1.10.15 + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - name: Install wkg shell: bash run: cargo binstall wkg - name: Install cosign - uses: sigstore/cosign-installer@v3.7.0 + uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 # To version our image we want to obtain the version from the tag - name: Get version @@ -41,7 +41,7 @@ jobs: # To upload our image to the GitHub registry, we first have to login - name: Login to the GitHub registry - uses: docker/login-action@v3 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 with: registry: ghcr.io username: ${{ github.actor }} diff --git a/proposals/filesystem/.github/workflows/update-0.3.yml b/proposals/filesystem/.github/workflows/update-0.3.yml new file mode 100644 index 000000000..7bceb94e1 --- /dev/null +++ b/proposals/filesystem/.github/workflows/update-0.3.yml @@ -0,0 +1,80 @@ +name: Update 0.3.0 WIT Definitions + +# Manually dispatch this action from the Actions page +on: + workflow_dispatch: + +permissions: + pull-requests: write + contents: write + +jobs: + update-versions: + runs-on: ubuntu-latest + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 + + # TODO: we don't pin the versions here. It's not great but this will simplify our iteration + # while we rapidly iterate on these tools. Pin when we're stable. + - name: Install wit-bindgen + shell: bash + run: cargo binstall wit-bindgen-cli + + - name: Install wit-deps + shell: bash + run: cargo binstall wit-deps-cli + + - name: Set version with RC timestamp + id: version + run: | + DATE=$(date +'%Y-%m-%d') + BASE_VERSION="0.3.0-rc-${DATE}" + COUNTER=1 + VERSION="${BASE_VERSION}" + + # Check if the tag already exists + while git ls-remote --tags origin | grep -q "refs/tags/v${VERSION}$"; do + VERSION="${BASE_VERSION}-${COUNTER}" + COUNTER=$((COUNTER + 1)) + done + + echo "value=${VERSION}" >> $GITHUB_OUTPUT + echo "Version will be: ${VERSION}" + + # Update version in WIT definitions + - name: Update version in WIT files + run: | + # Update @since version annotations + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + + # Update all wasi package references (package, use, import, export, from) + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\( wasi:[a-zA-Z0-9_/-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + + + - name: Update wit deps + run: | + wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps update + + # Create PR with changes using create-pull-request action + - name: Create Pull Request + uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" + committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + branch: update-wit-${{ steps.version.outputs.value }} + title: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" + body: | + Updates the 0.3.0 WIT definitions with version ${{ steps.version.outputs.value }}. + + This is an automated update to rev the RC timestamp. + + ## Changes + - Updated package and since version in WIT files + - Updated WIT dependencies if applicable + draft: false + delete-branch: true diff --git a/proposals/filesystem/.github/workflows/update.yml b/proposals/filesystem/.github/workflows/update.yml index bdf61d30c..850cb6bf3 100644 --- a/proposals/filesystem/.github/workflows/update.yml +++ b/proposals/filesystem/.github/workflows/update.yml @@ -23,9 +23,9 @@ jobs: steps: # Checkout the repo and install dependencies - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@v1.10.15 + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - name: Install wit-bindgen shell: bash run: cargo binstall wit-bindgen-cli From 5d91676af524fbceb7a29c351d1f2a7999ca9e5b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Aug 2025 20:07:16 +0000 Subject: [PATCH 1706/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-08-15 --- .../filesystem/wit-0.3.0-draft/deps.lock | 4 +- .../deps/clocks/monotonic-clock.wit | 22 ++--- .../wit-0.3.0-draft/deps/clocks/timezone.wit | 2 +- .../deps/clocks/wall-clock.wit | 12 +-- .../wit-0.3.0-draft/deps/clocks/world.wit | 8 +- .../filesystem/wit-0.3.0-draft/preopens.wit | 8 +- .../filesystem/wit-0.3.0-draft/types.wit | 80 +++++++++---------- .../filesystem/wit-0.3.0-draft/world.wit | 8 +- 8 files changed, 72 insertions(+), 72 deletions(-) diff --git a/proposals/filesystem/wit-0.3.0-draft/deps.lock b/proposals/filesystem/wit-0.3.0-draft/deps.lock index 03868084d..07d589294 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps.lock +++ b/proposals/filesystem/wit-0.3.0-draft/deps.lock @@ -1,5 +1,5 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "26e315db0d371495f8834edfc0e479042f94152ce677d96d54d3623d0e4ffb1e" -sha512 = "e1c76f499435841316f9287b88d8173558e64f277c321ff390556de8707a0b18dd6c1749bbb17bbbba8d523da246ef6eb05c990ceddb762e03efb2ae30cacc76" +sha256 = "626953ec28ae956ec1233c4350deab6e5cdcbdd9ae6d491e102ad7c6901cc8bf" +sha512 = "ae375b002cfaacdbaa133bb87747d1b86675e13144067c3005d6c32cf5c37bb7a52b693ae46d5cd65fc4910a78d7255d0ada5142828a022497fd0eaacb61761f" diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 87ebdaac5..0c58241ff 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,39 +7,39 @@ package wasi:clocks@0.3.0; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface monotonic-clock { /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type instant = u64; /// A duration of time, in nanoseconds. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type duration = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. - @since(version = 0.3.0) - resolution: func() -> duration; + @since(version = 0.3.0-rc-2025-08-15) + get-resolution: func() -> duration; /// Wait until the specified instant has occurred. - @since(version = 0.3.0) - wait-until: func( + @since(version = 0.3.0-rc-2025-08-15) + wait-until: async func( when: instant, ); /// Wait for the specified duration has elapsed. - @since(version = 0.3.0) - wait-for: func( + @since(version = 0.3.0-rc-2025-08-15) + wait-for: async func( how-long: duration, ); } diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/timezone.wit index ac9146834..2ee16ab20 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/timezone.wit +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/wall-clock.wit index b7a85ab35..2e3b2d441 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,10 +13,10 @@ package wasi:clocks@0.3.0; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface wall-clock { /// A time and date in seconds plus nanoseconds. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record datetime { seconds: u64, nanoseconds: u32, @@ -35,12 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0) - resolution: func() -> datetime; + @since(version = 0.3.0-rc-2025-08-15) + get-resolution: func() -> datetime; } diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/world.wit index f97bcfef1..94068c75c 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/world.wit +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/world.wit @@ -1,10 +1,10 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import monotonic-clock; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import wall-clock; @unstable(feature = clocks-timezone) import timezone; diff --git a/proposals/filesystem/wit-0.3.0-draft/preopens.wit b/proposals/filesystem/wit-0.3.0-draft/preopens.wit index 0b29aae33..b0f609aa9 100644 --- a/proposals/filesystem/wit-0.3.0-draft/preopens.wit +++ b/proposals/filesystem/wit-0.3.0-draft/preopens.wit @@ -1,11 +1,11 @@ -package wasi:filesystem@0.3.0; +package wasi:filesystem@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface preopens { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) use types.{descriptor}; /// Return the set of preopened directories, and their paths. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-directories: func() -> list>; } diff --git a/proposals/filesystem/wit-0.3.0-draft/types.wit b/proposals/filesystem/wit-0.3.0-draft/types.wit index b73b6759f..07d770a83 100644 --- a/proposals/filesystem/wit-0.3.0-draft/types.wit +++ b/proposals/filesystem/wit-0.3.0-draft/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.3.0; +package wasi:filesystem@0.3.0-rc-2025-08-15; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -23,19 +23,19 @@ package wasi:filesystem@0.3.0; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface types { - @since(version = 0.3.0) - use wasi:clocks/wall-clock@0.3.0.{datetime}; + @since(version = 0.3.0-rc-2025-08-15) + use wasi:clocks/wall-clock@0.3.0-rc-2025-08-15.{datetime}; /// File size or length of a region within a file. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -59,7 +59,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -103,7 +103,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record descriptor-stat { /// File type. %type: descriptor-type, @@ -130,7 +130,7 @@ interface types { } /// Flags determining the method of how paths are resolved. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -138,7 +138,7 @@ interface types { } /// Open flags used by `open-at`. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -151,11 +151,11 @@ interface types { } /// Number of hard links to an inode. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -255,7 +255,7 @@ interface types { } /// File or memory access pattern advisory information. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -279,7 +279,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -290,7 +290,7 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) resource descriptor { /// Return a stream for reading from a file. /// @@ -308,7 +308,7 @@ interface types { /// resolves to `err` with an `error-code`. /// /// Note: This is similar to `pread` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, @@ -326,7 +326,7 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `pwrite` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) write-via-stream: async func( /// Data to write data: stream, @@ -342,13 +342,13 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `write` with `O_APPEND` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) append-via-stream: async func(data: stream) -> result<_, error-code>; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) advise: async func( /// The offset within the file to which the advisory applies. offset: filesize, @@ -364,7 +364,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) sync-data: async func() -> result<_, error-code>; /// Get flags associated with a descriptor. @@ -373,7 +373,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-flags: async func() -> result; /// Get the dynamic type of a descriptor. @@ -386,14 +386,14 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-type: async func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-size: async func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. @@ -401,7 +401,7 @@ interface types { /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-times: async func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, @@ -421,7 +421,7 @@ interface types { /// /// This function returns a future, which will resolve to an error code if /// reading full contents of the directory fails. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) read-directory: async func() -> tuple, future>>; /// Synchronize the data and metadata of a file to disk. @@ -430,13 +430,13 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) sync: async func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) create-directory-at: async func( /// The relative path at which to create the directory. path: string, @@ -451,7 +451,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) stat: async func() -> result; /// Return the attributes of a file or directory. @@ -461,7 +461,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) stat-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -475,7 +475,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-times-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -494,7 +494,7 @@ interface types { /// `error-code::not-permitted` if the old path is not a file. /// /// Note: This is similar to `linkat` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) link-at: async func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, @@ -518,7 +518,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) open-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -536,7 +536,7 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) readlink-at: async func( /// The relative path of the symbolic link from which to read. path: string, @@ -547,7 +547,7 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) remove-directory-at: async func( /// The relative path to a directory to remove. path: string, @@ -556,7 +556,7 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) rename-at: async func( /// The relative source path of the file or directory to rename. old-path: string, @@ -572,7 +572,7 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) symlink-at: async func( /// The contents of the symbolic link. old-path: string, @@ -584,7 +584,7 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) unlink-file-at: async func( /// The relative path to a file to unlink. path: string, @@ -596,7 +596,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) is-same-object: async func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred @@ -618,14 +618,14 @@ interface types { /// computed hash. /// /// However, none of these is required. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) metadata-hash: async func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) metadata-hash-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, diff --git a/proposals/filesystem/wit-0.3.0-draft/world.wit b/proposals/filesystem/wit-0.3.0-draft/world.wit index c0ab32afe..b9dcfd562 100644 --- a/proposals/filesystem/wit-0.3.0-draft/world.wit +++ b/proposals/filesystem/wit-0.3.0-draft/world.wit @@ -1,9 +1,9 @@ -package wasi:filesystem@0.3.0; +package wasi:filesystem@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import types; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import preopens; } From 90f6d7b5b9889bc73ffb315ad4bd349fdb99a379 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Fri, 15 Aug 2025 16:22:43 -0400 Subject: [PATCH 1707/1772] ci: must use same oci URI package as 0.2 Limited by wkg registry discovery for downstream wkg build --- proposals/random/.github/workflows/publish-0.3.yml | 6 +++--- proposals/random/.github/workflows/update-0.3.yml | 9 +++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/proposals/random/.github/workflows/publish-0.3.yml b/proposals/random/.github/workflows/publish-0.3.yml index 52a2e728e..84b54723c 100644 --- a/proposals/random/.github/workflows/publish-0.3.yml +++ b/proposals/random/.github/workflows/publish-0.3.yml @@ -37,7 +37,7 @@ jobs: id: meta uses: docker/metadata-action@v5 with: - images: ghcr.io/webassembly/wasi/random-0.3.0 + images: ghcr.io/webassembly/wasi/random tags: | type=semver,pattern={{version}} @@ -57,7 +57,7 @@ jobs: id: publish uses: bytecodealliance/wkg-github-action@v5 with: - oci-reference-without-tag: "ghcr.io/webassembly/wasi/random-0.3.0" + oci-reference-without-tag: "ghcr.io/webassembly/wasi/random" file: "${{ github.event.repository.name }}-0.3.0.wasm" description: "A WASI API for reading the current time and measuring elapsed time (0.3.0 version)." source: 'https://github.com/webassembly/wasi' @@ -67,4 +67,4 @@ jobs: # Sign the output component - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/random-0.3.0@${{ steps.publish.outputs.digest }} + run: cosign sign --yes ghcr.io/webassembly/wasi/random@${{ steps.publish.outputs.digest }} diff --git a/proposals/random/.github/workflows/update-0.3.yml b/proposals/random/.github/workflows/update-0.3.yml index 77d122ee8..7ed9421cf 100644 --- a/proposals/random/.github/workflows/update-0.3.yml +++ b/proposals/random/.github/workflows/update-0.3.yml @@ -49,13 +49,10 @@ jobs: # Update version in WIT definitions - name: Update version in WIT files run: | + # Update @since version annotations find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(package wasi:[a-zA-Z0-9_-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + - - - name: Update wit deps - run: | - cd wit-0.3.0-draft - wit-deps update || true # Continue even if no deps to update + # Update all wasi package references (package, use, import, export, from) + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\( wasi:[a-zA-Z0-9_/-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + # Create PR with changes using create-pull-request action - name: Create Pull Request From 974cc2b3352c103e3ddc6cc5348a05017b79eb03 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Fri, 15 Aug 2025 16:35:37 -0400 Subject: [PATCH 1708/1772] ci: publish 0.3. workflows --- proposals/cli/.github/workflows/main.yml | 2 +- .../cli/.github/workflows/publish-0.3.yml | 72 +++++++++++++++++ proposals/cli/.github/workflows/publish.yml | 8 +- .../cli/.github/workflows/update-0.3.yml | 80 +++++++++++++++++++ proposals/cli/.github/workflows/update.yml | 4 +- 5 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 proposals/cli/.github/workflows/publish-0.3.yml create mode 100644 proposals/cli/.github/workflows/update-0.3.yml diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml index 561533b0c..53052b2be 100644 --- a/proposals/cli/.github/workflows/main.yml +++ b/proposals/cli/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ensure `./wit/deps` are in sync run: | curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.5.0/wit-deps-x86_64-unknown-linux-musl diff --git a/proposals/cli/.github/workflows/publish-0.3.yml b/proposals/cli/.github/workflows/publish-0.3.yml new file mode 100644 index 000000000..e65ffc2fe --- /dev/null +++ b/proposals/cli/.github/workflows/publish-0.3.yml @@ -0,0 +1,72 @@ +name: Publish 0.3.0 WIT Definitions + +on: + push: + tags: + - v0.3.0-rc-* + workflow_dispatch: # Allow manual triggering + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + packages: write + contents: write + + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 + + # TODO: we don't pin the versions here. It's not great but this will simplify our iteration + # while we rapidly iterate on these tools. Pin when we're stable. + - name: Install wkg + shell: bash + run: cargo binstall wkg + + - name: Install cosign + uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 + + # To version our image we want to obtain the version from the tag + - name: Get version + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/webassembly/wasi/cli + tags: | + type=semver,pattern={{version}} + + - name: Login to the GitHub registry + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.ORG_PAT }} + + - name: Build + shell: bash + run: wkg wit build -o "${{ github.event.repository.name }}-0.3.0.wasm" --wit-dir wit-0.3.0-draft + + # Upload the Wasm binary to the GitHub registry + - name: Publish to GitHub Container Registry + id: publish + uses: bytecodealliance/wkg-github-action@v5 + with: + oci-reference-without-tag: "ghcr.io/webassembly/wasi/cli" + file: "${{ github.event.repository.name }}-0.3.0.wasm" + description: "A WASI API for Command-Line Interface environments." + source: 'https://github.com/webassembly/wasi' + homepage: 'https://wasi.dev' + version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + licenses: 'Apache-2.0 WITH LLVM-exception' + + # Sign the output component + - name: Sign the wasm component + run: cosign sign --yes ghcr.io/webassembly/wasi/cli@${{ steps.publish.outputs.digest }} diff --git a/proposals/cli/.github/workflows/publish.yml b/proposals/cli/.github/workflows/publish.yml index af5bd0699..73418306f 100644 --- a/proposals/cli/.github/workflows/publish.yml +++ b/proposals/cli/.github/workflows/publish.yml @@ -4,7 +4,7 @@ name: Publish a Wasm Component package to GitHub Artifacts on: push: tags: - - v* + - v0.2.* workflow_dispatch: env: @@ -23,12 +23,12 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@v1.10.15 + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - name: Install wkg shell: bash run: cargo binstall wkg - name: Install cosign - uses: sigstore/cosign-installer@v3.7.0 + uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 # To version our image we want to obtain the version from the tag - name: Get version @@ -41,7 +41,7 @@ jobs: # To upload our image to the GitHub registry, we first have to login - name: Login to the GitHub registry - uses: docker/login-action@v3 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 with: registry: ghcr.io username: ${{ github.actor }} diff --git a/proposals/cli/.github/workflows/update-0.3.yml b/proposals/cli/.github/workflows/update-0.3.yml new file mode 100644 index 000000000..7bceb94e1 --- /dev/null +++ b/proposals/cli/.github/workflows/update-0.3.yml @@ -0,0 +1,80 @@ +name: Update 0.3.0 WIT Definitions + +# Manually dispatch this action from the Actions page +on: + workflow_dispatch: + +permissions: + pull-requests: write + contents: write + +jobs: + update-versions: + runs-on: ubuntu-latest + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 + + # TODO: we don't pin the versions here. It's not great but this will simplify our iteration + # while we rapidly iterate on these tools. Pin when we're stable. + - name: Install wit-bindgen + shell: bash + run: cargo binstall wit-bindgen-cli + + - name: Install wit-deps + shell: bash + run: cargo binstall wit-deps-cli + + - name: Set version with RC timestamp + id: version + run: | + DATE=$(date +'%Y-%m-%d') + BASE_VERSION="0.3.0-rc-${DATE}" + COUNTER=1 + VERSION="${BASE_VERSION}" + + # Check if the tag already exists + while git ls-remote --tags origin | grep -q "refs/tags/v${VERSION}$"; do + VERSION="${BASE_VERSION}-${COUNTER}" + COUNTER=$((COUNTER + 1)) + done + + echo "value=${VERSION}" >> $GITHUB_OUTPUT + echo "Version will be: ${VERSION}" + + # Update version in WIT definitions + - name: Update version in WIT files + run: | + # Update @since version annotations + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + + # Update all wasi package references (package, use, import, export, from) + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\( wasi:[a-zA-Z0-9_/-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + + + - name: Update wit deps + run: | + wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps update + + # Create PR with changes using create-pull-request action + - name: Create Pull Request + uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" + committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + branch: update-wit-${{ steps.version.outputs.value }} + title: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" + body: | + Updates the 0.3.0 WIT definitions with version ${{ steps.version.outputs.value }}. + + This is an automated update to rev the RC timestamp. + + ## Changes + - Updated package and since version in WIT files + - Updated WIT dependencies if applicable + draft: false + delete-branch: true diff --git a/proposals/cli/.github/workflows/update.yml b/proposals/cli/.github/workflows/update.yml index e6ba2cd4f..793ee90d0 100644 --- a/proposals/cli/.github/workflows/update.yml +++ b/proposals/cli/.github/workflows/update.yml @@ -23,9 +23,9 @@ jobs: steps: # Checkout the repo and install dependencies - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@v1.10.15 + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - name: Install wit-bindgen shell: bash run: cargo binstall wit-bindgen-cli From 7604ad1a7e3e90bade7f6fd07514af7adda79f2a Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 15 Aug 2025 12:52:30 +0200 Subject: [PATCH 1709/1772] p3: add `async` annotations Signed-off-by: Roman Volosatovs --- proposals/http/wit-0.3.0-draft/handler.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit-0.3.0-draft/handler.wit b/proposals/http/wit-0.3.0-draft/handler.wit index 099d094c7..e4446cbec 100644 --- a/proposals/http/wit-0.3.0-draft/handler.wit +++ b/proposals/http/wit-0.3.0-draft/handler.wit @@ -11,7 +11,7 @@ interface handler { /// /// When imported, this function may be used to either send an outgoing /// request over the network or pass it to another component. - handle: func( + handle: async func( request: request, ) -> result; } From 89ee3f872302b806a6e503efd3a12a0fafaccd5a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Aug 2025 20:39:28 +0000 Subject: [PATCH 1710/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-08-15 --- proposals/cli/wit-0.3.0-draft/command.wit | 8 +- proposals/cli/wit-0.3.0-draft/deps.lock | 16 +- .../deps/clocks/monotonic-clock.wit | 22 +-- .../wit-0.3.0-draft/deps/clocks/timezone.wit | 2 +- .../deps/clocks/wall-clock.wit | 12 +- .../cli/wit-0.3.0-draft/deps/clocks/world.wit | 8 +- .../deps/filesystem/preopens.wit | 8 +- .../wit-0.3.0-draft/deps/filesystem/types.wit | 139 +++++++-------- .../wit-0.3.0-draft/deps/filesystem/world.wit | 8 +- .../deps/random/insecure-seed.wit | 8 +- .../wit-0.3.0-draft/deps/random/insecure.wit | 8 +- .../wit-0.3.0-draft/deps/random/random.wit | 8 +- .../cli/wit-0.3.0-draft/deps/random/world.wit | 10 +- .../deps/sockets/ip-name-lookup.wit | 10 +- .../wit-0.3.0-draft/deps/sockets/types.wit | 160 +++++++++--------- .../wit-0.3.0-draft/deps/sockets/world.wit | 8 +- proposals/cli/wit-0.3.0-draft/environment.wit | 8 +- proposals/cli/wit-0.3.0-draft/exit.wit | 4 +- proposals/cli/wit-0.3.0-draft/imports.wit | 40 ++--- proposals/cli/wit-0.3.0-draft/run.wit | 4 +- proposals/cli/wit-0.3.0-draft/stdio.wit | 12 +- proposals/cli/wit-0.3.0-draft/terminal.wit | 26 +-- 22 files changed, 268 insertions(+), 261 deletions(-) diff --git a/proposals/cli/wit-0.3.0-draft/command.wit b/proposals/cli/wit-0.3.0-draft/command.wit index 0310e5151..13e92bdec 100644 --- a/proposals/cli/wit-0.3.0-draft/command.wit +++ b/proposals/cli/wit-0.3.0-draft/command.wit @@ -1,10 +1,10 @@ -package wasi:cli@0.3.0; +package wasi:cli@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world command { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) include imports; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) export run; } diff --git a/proposals/cli/wit-0.3.0-draft/deps.lock b/proposals/cli/wit-0.3.0-draft/deps.lock index 350728a38..97759f336 100644 --- a/proposals/cli/wit-0.3.0-draft/deps.lock +++ b/proposals/cli/wit-0.3.0-draft/deps.lock @@ -1,23 +1,23 @@ [clocks] -sha256 = "26e315db0d371495f8834edfc0e479042f94152ce677d96d54d3623d0e4ffb1e" -sha512 = "e1c76f499435841316f9287b88d8173558e64f277c321ff390556de8707a0b18dd6c1749bbb17bbbba8d523da246ef6eb05c990ceddb762e03efb2ae30cacc76" +sha256 = "626953ec28ae956ec1233c4350deab6e5cdcbdd9ae6d491e102ad7c6901cc8bf" +sha512 = "ae375b002cfaacdbaa133bb87747d1b86675e13144067c3005d6c32cf5c37bb7a52b693ae46d5cd65fc4910a78d7255d0ada5142828a022497fd0eaacb61761f" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "f8a82b21e18cad3498b53475666a3f00c4c1b5f030b7ed47c79262e3dbe97461" -sha512 = "0e62fe9ff3ba0572d890a2edd969e88a5c2327279cec681d3f2688ed8442820333f6041b0f0956b44941f971a6afb785bd2f5248ca0c99b51f13521496cadbcc" +sha256 = "a65db475f8e41fa1701de4dc467ed748af5b807bdb2b5ff5027fefd0c0eab7a2" +sha512 = "3a797b5eacad135ed8e0a903c3db8f9073e79ecc547e31bf1ec62e9576e2069ecd2e37561674c000ab6cabf1cfeec5c32648b58c592bf52911c5783f179db83a" deps = ["clocks"] [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "7a483077cc23fc9dc7a3f067d62795663cceee7dbbd23f205934282b1164a83e" -sha512 = "b99280fd60699f781f20209659e94c0058ce6b9e973ddbd0b8865d752f88c74633485d486d5a86b709385b6e60357470d1c6fbcb3a2769af210c0b1f52417506" +sha256 = "fcc4d3b51564274bb05ebd7cad65ff036eed5c1ac1316639e0c04aa0d64fc938" +sha512 = "d3b10e7791fc354730551f8e21beff96bdbf16f96ef655cd0ac7e0489a9e28c4a7a602d50b199de4a27981643bdbea7ec075cfa80ca351aea6ae74ea660b0568" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "a439ac477ff57f24331eb40989d50455b04cde0a12f235e88a5477614ea90264" -sha512 = "cf779c887fa401695215122621d7715aa5716f09dc94087887c93964fd454a146bc3b20c834e4a8e997ccb190910699a1a880e6caaaec25c32d941f9c26ba37f" +sha256 = "307e8459b8be0587000871d3f67fc04041e4cb1eb6c27e97183332fdb641926f" +sha512 = "183054d40082bf9e0fd38daf77df0189445c54384537548d5d37bc1b3cfd05190b1ca4377760a7108c39650785c74e5e230abd296e0fda8e2a5b263cd41f848b" deps = ["clocks"] diff --git a/proposals/cli/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/cli/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 87ebdaac5..0c58241ff 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,39 +7,39 @@ package wasi:clocks@0.3.0; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface monotonic-clock { /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type instant = u64; /// A duration of time, in nanoseconds. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type duration = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. - @since(version = 0.3.0) - resolution: func() -> duration; + @since(version = 0.3.0-rc-2025-08-15) + get-resolution: func() -> duration; /// Wait until the specified instant has occurred. - @since(version = 0.3.0) - wait-until: func( + @since(version = 0.3.0-rc-2025-08-15) + wait-until: async func( when: instant, ); /// Wait for the specified duration has elapsed. - @since(version = 0.3.0) - wait-for: func( + @since(version = 0.3.0-rc-2025-08-15) + wait-for: async func( how-long: duration, ); } diff --git a/proposals/cli/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/cli/wit-0.3.0-draft/deps/clocks/timezone.wit index ac9146834..2ee16ab20 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/clocks/timezone.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/cli/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/cli/wit-0.3.0-draft/deps/clocks/wall-clock.wit index b7a85ab35..2e3b2d441 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,10 +13,10 @@ package wasi:clocks@0.3.0; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface wall-clock { /// A time and date in seconds plus nanoseconds. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record datetime { seconds: u64, nanoseconds: u32, @@ -35,12 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0) - resolution: func() -> datetime; + @since(version = 0.3.0-rc-2025-08-15) + get-resolution: func() -> datetime; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/cli/wit-0.3.0-draft/deps/clocks/world.wit index f97bcfef1..94068c75c 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/clocks/world.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/clocks/world.wit @@ -1,10 +1,10 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import monotonic-clock; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import wall-clock; @unstable(feature = clocks-timezone) import timezone; diff --git a/proposals/cli/wit-0.3.0-draft/deps/filesystem/preopens.wit b/proposals/cli/wit-0.3.0-draft/deps/filesystem/preopens.wit index 0b29aae33..b0f609aa9 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/filesystem/preopens.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/filesystem/preopens.wit @@ -1,11 +1,11 @@ -package wasi:filesystem@0.3.0; +package wasi:filesystem@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface preopens { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) use types.{descriptor}; /// Return the set of preopened directories, and their paths. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-directories: func() -> list>; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/filesystem/types.wit b/proposals/cli/wit-0.3.0-draft/deps/filesystem/types.wit index af3cb254c..07d770a83 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/filesystem/types.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.3.0; +package wasi:filesystem@0.3.0-rc-2025-08-15; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -23,19 +23,19 @@ package wasi:filesystem@0.3.0; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface types { - @since(version = 0.3.0) - use wasi:clocks/wall-clock@0.3.0.{datetime}; + @since(version = 0.3.0-rc-2025-08-15) + use wasi:clocks/wall-clock@0.3.0-rc-2025-08-15.{datetime}; /// File size or length of a region within a file. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -59,7 +59,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -103,7 +103,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record descriptor-stat { /// File type. %type: descriptor-type, @@ -130,7 +130,7 @@ interface types { } /// Flags determining the method of how paths are resolved. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -138,7 +138,7 @@ interface types { } /// Open flags used by `open-at`. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -151,11 +151,11 @@ interface types { } /// Number of hard links to an inode. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -255,7 +255,7 @@ interface types { } /// File or memory access pattern advisory information. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -279,7 +279,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -290,18 +290,25 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) resource descriptor { /// Return a stream for reading from a file. /// /// Multiple read, write, and append streams may be active on the same open /// file and they do not interfere with each other. /// - /// This function returns a future, which will resolve to an error code if - /// reading full contents of the file fails. + /// This function returns a `stream` which provides the data received from the + /// file, and a `future` providing additional error information in case an + /// error is encountered. + /// + /// If no error is encountered, `stream.read` on the `stream` will return + /// `read-status::closed` with no `error-context` and the future resolves to + /// the value `ok`. If an error is encountered, `stream.read` on the + /// `stream` returns `read-status::closed` with an `error-context` and the future + /// resolves to `err` with an `error-code`. /// /// Note: This is similar to `pread` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, @@ -319,8 +326,8 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `pwrite` in POSIX. - @since(version = 0.3.0) - write-via-stream: func( + @since(version = 0.3.0-rc-2025-08-15) + write-via-stream: async func( /// Data to write data: stream, /// The offset within the file at which to start writing. @@ -335,14 +342,14 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `write` with `O_APPEND` in POSIX. - @since(version = 0.3.0) - append-via-stream: func(data: stream) -> result<_, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + append-via-stream: async func(data: stream) -> result<_, error-code>; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. - @since(version = 0.3.0) - advise: func( + @since(version = 0.3.0-rc-2025-08-15) + advise: async func( /// The offset within the file to which the advisory applies. offset: filesize, /// The length of the region to which the advisory applies. @@ -357,8 +364,8 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - @since(version = 0.3.0) - sync-data: func() -> result<_, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + sync-data: async func() -> result<_, error-code>; /// Get flags associated with a descriptor. /// @@ -366,8 +373,8 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0) - get-flags: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + get-flags: async func() -> result; /// Get the dynamic type of a descriptor. /// @@ -379,23 +386,23 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0) - get-type: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + get-type: async func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - @since(version = 0.3.0) - set-size: func(size: filesize) -> result<_, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + set-size: async func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. /// /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - @since(version = 0.3.0) - set-times: func( + @since(version = 0.3.0-rc-2025-08-15) + set-times: async func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, /// The desired values of the data modification timestamp. @@ -414,8 +421,8 @@ interface types { /// /// This function returns a future, which will resolve to an error code if /// reading full contents of the directory fails. - @since(version = 0.3.0) - read-directory: func() -> tuple, future>>; + @since(version = 0.3.0-rc-2025-08-15) + read-directory: async func() -> tuple, future>>; /// Synchronize the data and metadata of a file to disk. /// @@ -423,14 +430,14 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - @since(version = 0.3.0) - sync: func() -> result<_, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + sync: async func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. - @since(version = 0.3.0) - create-directory-at: func( + @since(version = 0.3.0-rc-2025-08-15) + create-directory-at: async func( /// The relative path at which to create the directory. path: string, ) -> result<_, error-code>; @@ -444,8 +451,8 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0) - stat: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + stat: async func() -> result; /// Return the attributes of a file or directory. /// @@ -454,8 +461,8 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0) - stat-at: func( + @since(version = 0.3.0-rc-2025-08-15) + stat-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, /// The relative path of the file or directory to inspect. @@ -468,8 +475,8 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. - @since(version = 0.3.0) - set-times-at: func( + @since(version = 0.3.0-rc-2025-08-15) + set-times-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, /// The relative path of the file or directory to operate on. @@ -487,8 +494,8 @@ interface types { /// `error-code::not-permitted` if the old path is not a file. /// /// Note: This is similar to `linkat` in POSIX. - @since(version = 0.3.0) - link-at: func( + @since(version = 0.3.0-rc-2025-08-15) + link-at: async func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, /// The relative source path from which to link. @@ -511,8 +518,8 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. - @since(version = 0.3.0) - open-at: func( + @since(version = 0.3.0-rc-2025-08-15) + open-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, /// The relative path of the object to open. @@ -529,8 +536,8 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. - @since(version = 0.3.0) - readlink-at: func( + @since(version = 0.3.0-rc-2025-08-15) + readlink-at: async func( /// The relative path of the symbolic link from which to read. path: string, ) -> result; @@ -540,8 +547,8 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - @since(version = 0.3.0) - remove-directory-at: func( + @since(version = 0.3.0-rc-2025-08-15) + remove-directory-at: async func( /// The relative path to a directory to remove. path: string, ) -> result<_, error-code>; @@ -549,8 +556,8 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. - @since(version = 0.3.0) - rename-at: func( + @since(version = 0.3.0-rc-2025-08-15) + rename-at: async func( /// The relative source path of the file or directory to rename. old-path: string, /// The base directory for `new-path`. @@ -565,8 +572,8 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. - @since(version = 0.3.0) - symlink-at: func( + @since(version = 0.3.0-rc-2025-08-15) + symlink-at: async func( /// The contents of the symbolic link. old-path: string, /// The relative destination path at which to create the symbolic link. @@ -577,8 +584,8 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - @since(version = 0.3.0) - unlink-file-at: func( + @since(version = 0.3.0-rc-2025-08-15) + unlink-file-at: async func( /// The relative path to a file to unlink. path: string, ) -> result<_, error-code>; @@ -589,8 +596,8 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - @since(version = 0.3.0) - is-same-object: func(other: borrow) -> bool; + @since(version = 0.3.0-rc-2025-08-15) + is-same-object: async func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred /// to by a descriptor. @@ -611,15 +618,15 @@ interface types { /// computed hash. /// /// However, none of these is required. - @since(version = 0.3.0) - metadata-hash: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + metadata-hash: async func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. - @since(version = 0.3.0) - metadata-hash-at: func( + @since(version = 0.3.0-rc-2025-08-15) + metadata-hash-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, /// The relative path of the file or directory to inspect. diff --git a/proposals/cli/wit-0.3.0-draft/deps/filesystem/world.wit b/proposals/cli/wit-0.3.0-draft/deps/filesystem/world.wit index c0ab32afe..b9dcfd562 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/filesystem/world.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/filesystem/world.wit @@ -1,9 +1,9 @@ -package wasi:filesystem@0.3.0; +package wasi:filesystem@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import types; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import preopens; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit b/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit index 4708d9049..ecd504318 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0; +package wasi:random@0.3.0-rc-2025-08-15; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0) - insecure-seed: func() -> tuple; + @since(version = 0.3.0-rc-2025-08-15) + get-insecure-seed: func() -> tuple; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit b/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit index 4ea5e581f..d08d85e0b 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0; +package wasi:random@0.3.0-rc-2025-08-15; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/random.wit b/proposals/cli/wit-0.3.0-draft/deps/random/random.wit index 786ef25f6..3808c3095 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/random/random.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/random/random.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0; +package wasi:random@0.3.0-rc-2025-08-15; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-random-u64: func() -> u64; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/world.wit b/proposals/cli/wit-0.3.0-draft/deps/random/world.wit index 838d38023..e8f05cc43 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/random/world.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/random/world.wit @@ -1,13 +1,13 @@ -package wasi:random@0.3.0; +package wasi:random@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import random; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import insecure; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import insecure-seed; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit index 7cc8b03e3..ab4156e25 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit @@ -1,10 +1,10 @@ -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface ip-name-lookup { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) use types.{ip-address}; /// Lookup error codes. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum error-code { /// Unknown error unknown, @@ -57,6 +57,6 @@ interface ip-name-lookup { /// - /// - /// - - @since(version = 0.3.0) - resolve-addresses: func(name: string) -> result, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + resolve-addresses: async func(name: string) -> result, error-code>; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit b/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit index 456d4e5cc..3a7915ce9 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit @@ -1,7 +1,7 @@ -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface types { - @since(version = 0.3.0) - use wasi:clocks/monotonic-clock@0.3.0.{duration}; + @since(version = 0.3.0-rc-2025-08-15) + use wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15.{duration}; /// Error codes. /// @@ -14,7 +14,7 @@ interface types { /// - `out-of-memory` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum error-code { /// Unknown error unknown, @@ -70,7 +70,7 @@ interface types { datagram-too-large, } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -79,18 +79,18 @@ interface types { ipv6, } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type ipv4-address = tuple; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type ipv6-address = tuple; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record ipv4-socket-address { /// sin_port port: u16, @@ -98,7 +98,7 @@ interface types { address: ipv4-address, } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record ipv6-socket-address { /// sin6_port port: u16, @@ -110,7 +110,7 @@ interface types { scope-id: u32, } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), @@ -125,7 +125,7 @@ interface types { /// - `connecting` /// - `connected` /// - `closed` - /// See + /// See /// for more information. /// /// Note: Except where explicitly mentioned, whenever this documentation uses @@ -135,7 +135,7 @@ interface types { /// In addition to the general error codes documented on the /// `types::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) resource tcp-socket { /// Create a new TCP socket. @@ -152,8 +152,8 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - constructor(address-family: ip-address-family); + @since(version = 0.3.0-rc-2025-08-15) + create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. /// @@ -186,7 +186,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Connect to a remote endpoint. @@ -218,10 +218,10 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - connect: func(remote-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + connect: async func(remote-address: ip-socket-address) -> result<_, error-code>; - /// Start listening return a stream of new inbound connections. + /// Start listening and return a stream of new inbound connections. /// /// Transitions the socket into the `listening` state. This can be called /// at most once per socket. @@ -285,7 +285,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) listen: func() -> result, error-code>; /// Transmit data to peer. @@ -308,8 +308,8 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - send: func(data: stream) -> result<_, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + send: async func(data: stream) -> result<_, error-code>; /// Read data from peer. /// @@ -342,7 +342,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) receive: func() -> tuple, future>>; /// Get the bound local address. @@ -351,7 +351,7 @@ interface types { /// > If the socket has not been bound to a local name, the value /// > stored in the object pointed to by `address` is unspecified. /// - /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// WASI is stricter and requires `get-local-address` to return `invalid-state` when the socket hasn't been bound yet. /// /// # Typical errors /// - `invalid-state`: The socket is not bound to any local address. @@ -361,8 +361,8 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - local-address: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + get-local-address: func() -> result; /// Get the remote address. /// @@ -374,22 +374,22 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - remote-address: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + get-remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. - @since(version = 0.3.0) - is-listening: func() -> bool; + @since(version = 0.3.0-rc-2025-08-15) + get-is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. /// /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0) - address-family: func() -> ip-address-family; + @since(version = 0.3.0-rc-2025-08-15) + get-address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. /// @@ -400,7 +400,7 @@ interface types { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -412,9 +412,9 @@ interface types { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. - @since(version = 0.3.0) - keep-alive-enabled: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-keep-alive-enabled: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. @@ -427,9 +427,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - keep-alive-idle-time: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-keep-alive-idle-time: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. @@ -442,9 +442,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - keep-alive-interval: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-keep-alive-interval: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. @@ -457,9 +457,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - keep-alive-count: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-keep-alive-count: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -468,9 +468,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0) - hop-limit: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-hop-limit: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -483,18 +483,18 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - receive-buffer-size: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-receive-buffer-size: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0) - send-buffer-size: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-send-buffer-size: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } /// A UDP socket handle. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) resource udp-socket { /// Create a new UDP socket. @@ -511,8 +511,8 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - constructor(address-family: ip-address-family); + @since(version = 0.3.0-rc-2025-08-15) + create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. /// @@ -532,7 +532,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Associate this socket with a specific peer address. @@ -571,7 +571,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) connect: func(remote-address: ip-socket-address) -> result<_, error-code>; /// Dissociate this socket from its peer address. @@ -589,7 +589,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) disconnect: func() -> result<_, error-code>; /// Send a message on the socket to a particular peer. @@ -623,8 +623,8 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - send: func(data: list, remote-address: option) -> result<_, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + send: async func(data: list, remote-address: option) -> result<_, error-code>; /// Receive a message on the socket. /// @@ -649,8 +649,8 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - receive: func() -> result, ip-socket-address>, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + receive: async func() -> result, ip-socket-address>, error-code>; /// Get the current bound address. /// @@ -658,7 +658,7 @@ interface types { /// > If the socket has not been bound to a local name, the value /// > stored in the object pointed to by `address` is unspecified. /// - /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// WASI is stricter and requires `get-local-address` to return `invalid-state` when the socket hasn't been bound yet. /// /// # Typical errors /// - `invalid-state`: The socket is not bound to any local address. @@ -668,8 +668,8 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - local-address: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + get-local-address: func() -> result; /// Get the address the socket is currently "connected" to. /// @@ -681,16 +681,16 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - remote-address: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + get-remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. /// /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0) - address-family: func() -> ip-address-family; + @since(version = 0.3.0-rc-2025-08-15) + get-address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// @@ -698,9 +698,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0) - unicast-hop-limit: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-unicast-hop-limit: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -713,13 +713,13 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - receive-buffer-size: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-receive-buffer-size: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0) - send-buffer-size: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-send-buffer-size: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } } diff --git a/proposals/cli/wit-0.3.0-draft/deps/sockets/world.wit b/proposals/cli/wit-0.3.0-draft/deps/sockets/world.wit index 6c9951d1c..dfafac2ae 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/sockets/world.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/sockets/world.wit @@ -1,9 +1,9 @@ -package wasi:sockets@0.3.0; +package wasi:sockets@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import types; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import ip-name-lookup; } diff --git a/proposals/cli/wit-0.3.0-draft/environment.wit b/proposals/cli/wit-0.3.0-draft/environment.wit index fb14eee67..769858af1 100644 --- a/proposals/cli/wit-0.3.0-draft/environment.wit +++ b/proposals/cli/wit-0.3.0-draft/environment.wit @@ -1,4 +1,4 @@ -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface environment { /// Get the POSIX-style environment variables. /// @@ -8,15 +8,15 @@ interface environment { /// Morally, these are a value import, but until value imports are available /// in the component model, this import function should return the same /// values each time it is called. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-environment: func() -> list>; /// Get the POSIX-style arguments to the program. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-arguments: func() -> list; /// Return a path that programs should use as their initial current working /// directory, interpreting `.` as shorthand for this. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-initial-cwd: func() -> option; } diff --git a/proposals/cli/wit-0.3.0-draft/exit.wit b/proposals/cli/wit-0.3.0-draft/exit.wit index e799a95a2..dcf791a20 100644 --- a/proposals/cli/wit-0.3.0-draft/exit.wit +++ b/proposals/cli/wit-0.3.0-draft/exit.wit @@ -1,7 +1,7 @@ -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface exit { /// Exit the current instance and any linked instances. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) exit: func(status: result); /// Exit the current instance and any linked instances, reporting the diff --git a/proposals/cli/wit-0.3.0-draft/imports.wit b/proposals/cli/wit-0.3.0-draft/imports.wit index 5dbc2ede8..2d513ead9 100644 --- a/proposals/cli/wit-0.3.0-draft/imports.wit +++ b/proposals/cli/wit-0.3.0-draft/imports.wit @@ -1,34 +1,34 @@ -package wasi:cli@0.3.0; +package wasi:cli@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) - include wasi:clocks/imports@0.3.0; - @since(version = 0.3.0) - include wasi:filesystem/imports@0.3.0; - @since(version = 0.3.0) - include wasi:sockets/imports@0.3.0; - @since(version = 0.3.0) - include wasi:random/imports@0.3.0; + @since(version = 0.3.0-rc-2025-08-15) + include wasi:clocks/imports@0.3.0-rc-2025-08-15; + @since(version = 0.3.0-rc-2025-08-15) + include wasi:filesystem/imports@0.3.0-rc-2025-08-15; + @since(version = 0.3.0-rc-2025-08-15) + include wasi:sockets/imports@0.3.0-rc-2025-08-15; + @since(version = 0.3.0-rc-2025-08-15) + include wasi:random/imports@0.3.0-rc-2025-08-15; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import environment; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import exit; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import stdin; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import stdout; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import stderr; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import terminal-input; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import terminal-output; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import terminal-stdin; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import terminal-stdout; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import terminal-stderr; } diff --git a/proposals/cli/wit-0.3.0-draft/run.wit b/proposals/cli/wit-0.3.0-draft/run.wit index 6dd8b6879..6149db760 100644 --- a/proposals/cli/wit-0.3.0-draft/run.wit +++ b/proposals/cli/wit-0.3.0-draft/run.wit @@ -1,6 +1,6 @@ -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface run { /// Run the program. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) run: func() -> result; } diff --git a/proposals/cli/wit-0.3.0-draft/stdio.wit b/proposals/cli/wit-0.3.0-draft/stdio.wit index 6a1208fad..6c99a56f1 100644 --- a/proposals/cli/wit-0.3.0-draft/stdio.wit +++ b/proposals/cli/wit-0.3.0-draft/stdio.wit @@ -1,17 +1,17 @@ -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface stdin { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-stdin: func() -> stream; } -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface stdout { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-stdout: func(data: stream); } -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface stderr { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-stderr: func(data: stream); } diff --git a/proposals/cli/wit-0.3.0-draft/terminal.wit b/proposals/cli/wit-0.3.0-draft/terminal.wit index c37184f4c..3b2b72bba 100644 --- a/proposals/cli/wit-0.3.0-draft/terminal.wit +++ b/proposals/cli/wit-0.3.0-draft/terminal.wit @@ -3,10 +3,10 @@ /// In the future, this may include functions for disabling echoing, /// disabling input buffering so that keyboard events are sent through /// immediately, querying supported features, and so on. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface terminal-input { /// The input side of a terminal. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) resource terminal-input; } @@ -15,48 +15,48 @@ interface terminal-input { /// In the future, this may include functions for querying the terminal /// size, being notified of terminal size changes, querying supported /// features, and so on. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface terminal-output { /// The output side of a terminal. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) resource terminal-output; } /// An interface providing an optional `terminal-input` for stdin as a /// link-time authority. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface terminal-stdin { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) use terminal-input.{terminal-input}; /// If stdin is connected to a terminal, return a `terminal-input` handle /// allowing further interaction with it. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-terminal-stdin: func() -> option; } /// An interface providing an optional `terminal-output` for stdout as a /// link-time authority. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface terminal-stdout { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) use terminal-output.{terminal-output}; /// If stdout is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-terminal-stdout: func() -> option; } /// An interface providing an optional `terminal-output` for stderr as a /// link-time authority. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface terminal-stderr { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) use terminal-output.{terminal-output}; /// If stderr is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-terminal-stderr: func() -> option; } From d74deb28a397dffb234d2d8e33da5f77bac5cb80 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Fri, 15 Aug 2025 16:44:24 -0400 Subject: [PATCH 1711/1772] ci: publish 0.3. workflows --- proposals/http/.github/workflows/main.yml | 2 +- .../http/.github/workflows/publish-0.3.yml | 72 +++++++++++++++++ proposals/http/.github/workflows/publish.yml | 8 +- .../http/.github/workflows/update-0.3.yml | 80 +++++++++++++++++++ proposals/http/.github/workflows/update.yml | 6 +- 5 files changed, 160 insertions(+), 8 deletions(-) create mode 100644 proposals/http/.github/workflows/publish-0.3.yml create mode 100644 proposals/http/.github/workflows/update-0.3.yml diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index 84a25f3fd..71542547a 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: name: Check ABI files are up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ensure `./wit/deps` are in sync run: | curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.5.0/wit-deps-x86_64-unknown-linux-musl diff --git a/proposals/http/.github/workflows/publish-0.3.yml b/proposals/http/.github/workflows/publish-0.3.yml new file mode 100644 index 000000000..ed05a0d25 --- /dev/null +++ b/proposals/http/.github/workflows/publish-0.3.yml @@ -0,0 +1,72 @@ +name: Publish 0.3.0 WIT Definitions + +on: + push: + tags: + - v0.3.0-rc-* + workflow_dispatch: # Allow manual triggering + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + packages: write + contents: write + + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 + + # TODO: we don't pin the versions here. It's not great but this will simplify our iteration + # while we rapidly iterate on these tools. Pin when we're stable. + - name: Install wkg + shell: bash + run: cargo binstall wkg + + - name: Install cosign + uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 + + # To version our image we want to obtain the version from the tag + - name: Get version + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/webassembly/wasi/http + tags: | + type=semver,pattern={{version}} + + - name: Login to the GitHub registry + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.ORG_PAT }} + + - name: Build + shell: bash + run: wkg wit build -o "${{ github.event.repository.name }}-0.3.0.wasm" --wit-dir wit-0.3.0-draft + + # Upload the Wasm binary to the GitHub registry + - name: Publish to GitHub Container Registry + id: publish + uses: bytecodealliance/wkg-github-action@v5 + with: + oci-reference-without-tag: "ghcr.io/webassembly/wasi/http" + file: "${{ github.event.repository.name }}-0.3.0.wasm" + description: "A WASI API for sending and receiving HTTP requests and responses." + source: 'https://github.com/webassembly/wasi' + homepage: 'https://wasi.dev' + version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + licenses: 'Apache-2.0 WITH LLVM-exception' + + # Sign the output component + - name: Sign the wasm component + run: cosign sign --yes ghcr.io/webassembly/wasi/http@${{ steps.publish.outputs.digest }} diff --git a/proposals/http/.github/workflows/publish.yml b/proposals/http/.github/workflows/publish.yml index 2c78c373d..654ad8bc4 100644 --- a/proposals/http/.github/workflows/publish.yml +++ b/proposals/http/.github/workflows/publish.yml @@ -4,7 +4,7 @@ name: Publish a Wasm Component package to GitHub Artifacts on: push: tags: - - v* + - v0.2.* workflow_dispatch: env: @@ -23,12 +23,12 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@v1.10.15 + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - name: Install wkg shell: bash run: cargo binstall wkg - name: Install cosign - uses: sigstore/cosign-installer@v3.7.0 + uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 # To version our image we want to obtain the version from the tag - name: Get version @@ -41,7 +41,7 @@ jobs: # To upload our image to the GitHub registry, we first have to login - name: Login to the GitHub registry - uses: docker/login-action@v3 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 with: registry: ghcr.io username: ${{ github.actor }} diff --git a/proposals/http/.github/workflows/update-0.3.yml b/proposals/http/.github/workflows/update-0.3.yml new file mode 100644 index 000000000..7bceb94e1 --- /dev/null +++ b/proposals/http/.github/workflows/update-0.3.yml @@ -0,0 +1,80 @@ +name: Update 0.3.0 WIT Definitions + +# Manually dispatch this action from the Actions page +on: + workflow_dispatch: + +permissions: + pull-requests: write + contents: write + +jobs: + update-versions: + runs-on: ubuntu-latest + steps: + # Checkout the repo and install dependencies + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 + + # TODO: we don't pin the versions here. It's not great but this will simplify our iteration + # while we rapidly iterate on these tools. Pin when we're stable. + - name: Install wit-bindgen + shell: bash + run: cargo binstall wit-bindgen-cli + + - name: Install wit-deps + shell: bash + run: cargo binstall wit-deps-cli + + - name: Set version with RC timestamp + id: version + run: | + DATE=$(date +'%Y-%m-%d') + BASE_VERSION="0.3.0-rc-${DATE}" + COUNTER=1 + VERSION="${BASE_VERSION}" + + # Check if the tag already exists + while git ls-remote --tags origin | grep -q "refs/tags/v${VERSION}$"; do + VERSION="${BASE_VERSION}-${COUNTER}" + COUNTER=$((COUNTER + 1)) + done + + echo "value=${VERSION}" >> $GITHUB_OUTPUT + echo "Version will be: ${VERSION}" + + # Update version in WIT definitions + - name: Update version in WIT files + run: | + # Update @since version annotations + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + + # Update all wasi package references (package, use, import, export, from) + find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\( wasi:[a-zA-Z0-9_/-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + + + - name: Update wit deps + run: | + wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps update + + # Create PR with changes using create-pull-request action + - name: Create Pull Request + uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" + committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + branch: update-wit-${{ steps.version.outputs.value }} + title: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" + body: | + Updates the 0.3.0 WIT definitions with version ${{ steps.version.outputs.value }}. + + This is an automated update to rev the RC timestamp. + + ## Changes + - Updated package and since version in WIT files + - Updated WIT dependencies if applicable + draft: false + delete-branch: true diff --git a/proposals/http/.github/workflows/update.yml b/proposals/http/.github/workflows/update.yml index 46ebb8329..f306a3040 100644 --- a/proposals/http/.github/workflows/update.yml +++ b/proposals/http/.github/workflows/update.yml @@ -23,9 +23,9 @@ jobs: steps: # Checkout the repo and install dependencies - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@v1.10.15 + uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - name: Install wit-bindgen shell: bash run: cargo binstall wit-bindgen-cli @@ -41,7 +41,7 @@ jobs: - name: Upgrade tag run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - name: Upgrade deps tags - run: find . -type f -name "deps.toml" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + + run: find . -type f -name "deps.toml" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - name: Upgrade wit deps run: wit-deps update - name: Generate markdown for the proxy world From 409bb0d571e3eb161a67f3a6c755f15369aced49 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Aug 2025 20:54:47 +0000 Subject: [PATCH 1712/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-08-15 --- proposals/http/wit-0.3.0-draft/deps.lock | 20 +-- .../http/wit-0.3.0-draft/deps/cli/command.wit | 8 +- .../wit-0.3.0-draft/deps/cli/environment.wit | 10 +- .../http/wit-0.3.0-draft/deps/cli/exit.wit | 4 +- .../http/wit-0.3.0-draft/deps/cli/imports.wit | 40 ++--- .../http/wit-0.3.0-draft/deps/cli/run.wit | 4 +- .../http/wit-0.3.0-draft/deps/cli/stdio.wit | 12 +- .../wit-0.3.0-draft/deps/cli/terminal.wit | 26 +-- .../deps/clocks/monotonic-clock.wit | 22 +-- .../wit-0.3.0-draft/deps/clocks/timezone.wit | 2 +- .../deps/clocks/wall-clock.wit | 12 +- .../wit-0.3.0-draft/deps/clocks/world.wit | 8 +- .../deps/filesystem/preopens.wit | 8 +- .../wit-0.3.0-draft/deps/filesystem/types.wit | 139 ++++++++------- .../wit-0.3.0-draft/deps/filesystem/world.wit | 8 +- .../deps/random/insecure-seed.wit | 8 +- .../wit-0.3.0-draft/deps/random/insecure.wit | 8 +- .../wit-0.3.0-draft/deps/random/random.wit | 8 +- .../wit-0.3.0-draft/deps/random/world.wit | 10 +- .../deps/sockets/ip-name-lookup.wit | 10 +- .../wit-0.3.0-draft/deps/sockets/types.wit | 163 +++++++++--------- .../wit-0.3.0-draft/deps/sockets/world.wit | 8 +- proposals/http/wit-0.3.0-draft/proxy.wit | 12 +- proposals/http/wit-0.3.0-draft/types.wit | 2 +- 24 files changed, 279 insertions(+), 273 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/deps.lock b/proposals/http/wit-0.3.0-draft/deps.lock index 0ee4a25ff..be1b0569e 100644 --- a/proposals/http/wit-0.3.0-draft/deps.lock +++ b/proposals/http/wit-0.3.0-draft/deps.lock @@ -1,22 +1,22 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "9a94018c67baf2ab4475f23c164514724ca08795195184adb4b38cb8dc5d6f9c" -sha512 = "8d2f3076eb94118c5321fd18dda60c0078087dbcbed57c6b973b8fc2225670045d94a6f70f4f19c0fb0e13bbb0344325d4dce3a48417b97434344d2a2c1371fd" +sha256 = "7f9cf181100ca1cadcb49a1efa3e80828d375df2d5ddf10a8f66e848d423aea5" +sha512 = "569f6b4ed2a3bec913e5e06fd35caab564048cf31632795c2fbdd8c40ddb5f5eea7b1cc59d33c80e5d7b642ed246ba4a3e40d3edeaaa2c6a5c4bcd02e0b67212" deps = ["clocks", "filesystem", "random", "sockets"] [clocks] -sha256 = "26e315db0d371495f8834edfc0e479042f94152ce677d96d54d3623d0e4ffb1e" -sha512 = "e1c76f499435841316f9287b88d8173558e64f277c321ff390556de8707a0b18dd6c1749bbb17bbbba8d523da246ef6eb05c990ceddb762e03efb2ae30cacc76" +sha256 = "626953ec28ae956ec1233c4350deab6e5cdcbdd9ae6d491e102ad7c6901cc8bf" +sha512 = "ae375b002cfaacdbaa133bb87747d1b86675e13144067c3005d6c32cf5c37bb7a52b693ae46d5cd65fc4910a78d7255d0ada5142828a022497fd0eaacb61761f" [filesystem] -sha256 = "f8a82b21e18cad3498b53475666a3f00c4c1b5f030b7ed47c79262e3dbe97461" -sha512 = "0e62fe9ff3ba0572d890a2edd969e88a5c2327279cec681d3f2688ed8442820333f6041b0f0956b44941f971a6afb785bd2f5248ca0c99b51f13521496cadbcc" +sha256 = "a65db475f8e41fa1701de4dc467ed748af5b807bdb2b5ff5027fefd0c0eab7a2" +sha512 = "3a797b5eacad135ed8e0a903c3db8f9073e79ecc547e31bf1ec62e9576e2069ecd2e37561674c000ab6cabf1cfeec5c32648b58c592bf52911c5783f179db83a" [random] -sha256 = "7a483077cc23fc9dc7a3f067d62795663cceee7dbbd23f205934282b1164a83e" -sha512 = "b99280fd60699f781f20209659e94c0058ce6b9e973ddbd0b8865d752f88c74633485d486d5a86b709385b6e60357470d1c6fbcb3a2769af210c0b1f52417506" +sha256 = "fcc4d3b51564274bb05ebd7cad65ff036eed5c1ac1316639e0c04aa0d64fc938" +sha512 = "d3b10e7791fc354730551f8e21beff96bdbf16f96ef655cd0ac7e0489a9e28c4a7a602d50b199de4a27981643bdbea7ec075cfa80ca351aea6ae74ea660b0568" [sockets] -sha256 = "48fa617cdf64b66adc7136e4f0c14886061e6d5134072bf8e1698b84e2579669" -sha512 = "786b8a03c14d3f529500275762a37c497ea1e6479e71028e8173aa07594beb77226904d77970a7c356ff3f59aa4a5c10f2e68537cc96b9916ff03a317b05a229" +sha256 = "307e8459b8be0587000871d3f67fc04041e4cb1eb6c27e97183332fdb641926f" +sha512 = "183054d40082bf9e0fd38daf77df0189445c54384537548d5d37bc1b3cfd05190b1ca4377760a7108c39650785c74e5e230abd296e0fda8e2a5b263cd41f848b" diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit index 0310e5151..13e92bdec 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit @@ -1,10 +1,10 @@ -package wasi:cli@0.3.0; +package wasi:cli@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world command { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) include imports; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) export run; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit b/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit index d99dcc0ae..769858af1 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit @@ -1,4 +1,4 @@ -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface environment { /// Get the POSIX-style environment variables. /// @@ -8,15 +8,15 @@ interface environment { /// Morally, these are a value import, but until value imports are available /// in the component model, this import function should return the same /// values each time it is called. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-environment: func() -> list>; /// Get the POSIX-style arguments to the program. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-arguments: func() -> list; /// Return a path that programs should use as their initial current working /// directory, interpreting `.` as shorthand for this. - @since(version = 0.3.0) - initial-cwd: func() -> option; + @since(version = 0.3.0-rc-2025-08-15) + get-initial-cwd: func() -> option; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit b/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit index e799a95a2..dcf791a20 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit @@ -1,7 +1,7 @@ -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface exit { /// Exit the current instance and any linked instances. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) exit: func(status: result); /// Exit the current instance and any linked instances, reporting the diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit index 5dbc2ede8..2d513ead9 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit @@ -1,34 +1,34 @@ -package wasi:cli@0.3.0; +package wasi:cli@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) - include wasi:clocks/imports@0.3.0; - @since(version = 0.3.0) - include wasi:filesystem/imports@0.3.0; - @since(version = 0.3.0) - include wasi:sockets/imports@0.3.0; - @since(version = 0.3.0) - include wasi:random/imports@0.3.0; + @since(version = 0.3.0-rc-2025-08-15) + include wasi:clocks/imports@0.3.0-rc-2025-08-15; + @since(version = 0.3.0-rc-2025-08-15) + include wasi:filesystem/imports@0.3.0-rc-2025-08-15; + @since(version = 0.3.0-rc-2025-08-15) + include wasi:sockets/imports@0.3.0-rc-2025-08-15; + @since(version = 0.3.0-rc-2025-08-15) + include wasi:random/imports@0.3.0-rc-2025-08-15; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import environment; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import exit; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import stdin; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import stdout; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import stderr; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import terminal-input; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import terminal-output; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import terminal-stdin; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import terminal-stdout; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import terminal-stderr; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/run.wit b/proposals/http/wit-0.3.0-draft/deps/cli/run.wit index 6dd8b6879..6149db760 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/run.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/run.wit @@ -1,6 +1,6 @@ -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface run { /// Run the program. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) run: func() -> result; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit index 6a1208fad..6c99a56f1 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit @@ -1,17 +1,17 @@ -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface stdin { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-stdin: func() -> stream; } -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface stdout { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-stdout: func(data: stream); } -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface stderr { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-stderr: func(data: stream); } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit b/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit index c37184f4c..3b2b72bba 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit @@ -3,10 +3,10 @@ /// In the future, this may include functions for disabling echoing, /// disabling input buffering so that keyboard events are sent through /// immediately, querying supported features, and so on. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface terminal-input { /// The input side of a terminal. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) resource terminal-input; } @@ -15,48 +15,48 @@ interface terminal-input { /// In the future, this may include functions for querying the terminal /// size, being notified of terminal size changes, querying supported /// features, and so on. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface terminal-output { /// The output side of a terminal. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) resource terminal-output; } /// An interface providing an optional `terminal-input` for stdin as a /// link-time authority. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface terminal-stdin { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) use terminal-input.{terminal-input}; /// If stdin is connected to a terminal, return a `terminal-input` handle /// allowing further interaction with it. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-terminal-stdin: func() -> option; } /// An interface providing an optional `terminal-output` for stdout as a /// link-time authority. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface terminal-stdout { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) use terminal-output.{terminal-output}; /// If stdout is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-terminal-stdout: func() -> option; } /// An interface providing an optional `terminal-output` for stderr as a /// link-time authority. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface terminal-stderr { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) use terminal-output.{terminal-output}; /// If stderr is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-terminal-stderr: func() -> option; } diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 87ebdaac5..0c58241ff 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,39 +7,39 @@ package wasi:clocks@0.3.0; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface monotonic-clock { /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type instant = u64; /// A duration of time, in nanoseconds. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type duration = u64; /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. - @since(version = 0.3.0) - resolution: func() -> duration; + @since(version = 0.3.0-rc-2025-08-15) + get-resolution: func() -> duration; /// Wait until the specified instant has occurred. - @since(version = 0.3.0) - wait-until: func( + @since(version = 0.3.0-rc-2025-08-15) + wait-until: async func( when: instant, ); /// Wait for the specified duration has elapsed. - @since(version = 0.3.0) - wait-for: func( + @since(version = 0.3.0-rc-2025-08-15) + wait-for: async func( how-long: duration, ); } diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit index ac9146834..2ee16ab20 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit index b7a85ab35..2e3b2d441 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,10 +13,10 @@ package wasi:clocks@0.3.0; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface wall-clock { /// A time and date in seconds plus nanoseconds. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record datetime { seconds: u64, nanoseconds: u32, @@ -35,12 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0) - resolution: func() -> datetime; + @since(version = 0.3.0-rc-2025-08-15) + get-resolution: func() -> datetime; } diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit index f97bcfef1..94068c75c 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit @@ -1,10 +1,10 @@ -package wasi:clocks@0.3.0; +package wasi:clocks@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import monotonic-clock; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import wall-clock; @unstable(feature = clocks-timezone) import timezone; diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit index 0b29aae33..b0f609aa9 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit @@ -1,11 +1,11 @@ -package wasi:filesystem@0.3.0; +package wasi:filesystem@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface preopens { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) use types.{descriptor}; /// Return the set of preopened directories, and their paths. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-directories: func() -> list>; } diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit index af3cb254c..07d770a83 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.3.0; +package wasi:filesystem@0.3.0-rc-2025-08-15; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -23,19 +23,19 @@ package wasi:filesystem@0.3.0; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface types { - @since(version = 0.3.0) - use wasi:clocks/wall-clock@0.3.0.{datetime}; + @since(version = 0.3.0-rc-2025-08-15) + use wasi:clocks/wall-clock@0.3.0-rc-2025-08-15.{datetime}; /// File size or length of a region within a file. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -59,7 +59,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -103,7 +103,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record descriptor-stat { /// File type. %type: descriptor-type, @@ -130,7 +130,7 @@ interface types { } /// Flags determining the method of how paths are resolved. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -138,7 +138,7 @@ interface types { } /// Open flags used by `open-at`. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -151,11 +151,11 @@ interface types { } /// Number of hard links to an inode. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -255,7 +255,7 @@ interface types { } /// File or memory access pattern advisory information. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -279,7 +279,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -290,18 +290,25 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) resource descriptor { /// Return a stream for reading from a file. /// /// Multiple read, write, and append streams may be active on the same open /// file and they do not interfere with each other. /// - /// This function returns a future, which will resolve to an error code if - /// reading full contents of the file fails. + /// This function returns a `stream` which provides the data received from the + /// file, and a `future` providing additional error information in case an + /// error is encountered. + /// + /// If no error is encountered, `stream.read` on the `stream` will return + /// `read-status::closed` with no `error-context` and the future resolves to + /// the value `ok`. If an error is encountered, `stream.read` on the + /// `stream` returns `read-status::closed` with an `error-context` and the future + /// resolves to `err` with an `error-code`. /// /// Note: This is similar to `pread` in POSIX. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, @@ -319,8 +326,8 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `pwrite` in POSIX. - @since(version = 0.3.0) - write-via-stream: func( + @since(version = 0.3.0-rc-2025-08-15) + write-via-stream: async func( /// Data to write data: stream, /// The offset within the file at which to start writing. @@ -335,14 +342,14 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `write` with `O_APPEND` in POSIX. - @since(version = 0.3.0) - append-via-stream: func(data: stream) -> result<_, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + append-via-stream: async func(data: stream) -> result<_, error-code>; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. - @since(version = 0.3.0) - advise: func( + @since(version = 0.3.0-rc-2025-08-15) + advise: async func( /// The offset within the file to which the advisory applies. offset: filesize, /// The length of the region to which the advisory applies. @@ -357,8 +364,8 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - @since(version = 0.3.0) - sync-data: func() -> result<_, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + sync-data: async func() -> result<_, error-code>; /// Get flags associated with a descriptor. /// @@ -366,8 +373,8 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0) - get-flags: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + get-flags: async func() -> result; /// Get the dynamic type of a descriptor. /// @@ -379,23 +386,23 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0) - get-type: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + get-type: async func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - @since(version = 0.3.0) - set-size: func(size: filesize) -> result<_, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + set-size: async func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. /// /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - @since(version = 0.3.0) - set-times: func( + @since(version = 0.3.0-rc-2025-08-15) + set-times: async func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, /// The desired values of the data modification timestamp. @@ -414,8 +421,8 @@ interface types { /// /// This function returns a future, which will resolve to an error code if /// reading full contents of the directory fails. - @since(version = 0.3.0) - read-directory: func() -> tuple, future>>; + @since(version = 0.3.0-rc-2025-08-15) + read-directory: async func() -> tuple, future>>; /// Synchronize the data and metadata of a file to disk. /// @@ -423,14 +430,14 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - @since(version = 0.3.0) - sync: func() -> result<_, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + sync: async func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. - @since(version = 0.3.0) - create-directory-at: func( + @since(version = 0.3.0-rc-2025-08-15) + create-directory-at: async func( /// The relative path at which to create the directory. path: string, ) -> result<_, error-code>; @@ -444,8 +451,8 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0) - stat: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + stat: async func() -> result; /// Return the attributes of a file or directory. /// @@ -454,8 +461,8 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0) - stat-at: func( + @since(version = 0.3.0-rc-2025-08-15) + stat-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, /// The relative path of the file or directory to inspect. @@ -468,8 +475,8 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. - @since(version = 0.3.0) - set-times-at: func( + @since(version = 0.3.0-rc-2025-08-15) + set-times-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, /// The relative path of the file or directory to operate on. @@ -487,8 +494,8 @@ interface types { /// `error-code::not-permitted` if the old path is not a file. /// /// Note: This is similar to `linkat` in POSIX. - @since(version = 0.3.0) - link-at: func( + @since(version = 0.3.0-rc-2025-08-15) + link-at: async func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, /// The relative source path from which to link. @@ -511,8 +518,8 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. - @since(version = 0.3.0) - open-at: func( + @since(version = 0.3.0-rc-2025-08-15) + open-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, /// The relative path of the object to open. @@ -529,8 +536,8 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. - @since(version = 0.3.0) - readlink-at: func( + @since(version = 0.3.0-rc-2025-08-15) + readlink-at: async func( /// The relative path of the symbolic link from which to read. path: string, ) -> result; @@ -540,8 +547,8 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - @since(version = 0.3.0) - remove-directory-at: func( + @since(version = 0.3.0-rc-2025-08-15) + remove-directory-at: async func( /// The relative path to a directory to remove. path: string, ) -> result<_, error-code>; @@ -549,8 +556,8 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. - @since(version = 0.3.0) - rename-at: func( + @since(version = 0.3.0-rc-2025-08-15) + rename-at: async func( /// The relative source path of the file or directory to rename. old-path: string, /// The base directory for `new-path`. @@ -565,8 +572,8 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. - @since(version = 0.3.0) - symlink-at: func( + @since(version = 0.3.0-rc-2025-08-15) + symlink-at: async func( /// The contents of the symbolic link. old-path: string, /// The relative destination path at which to create the symbolic link. @@ -577,8 +584,8 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - @since(version = 0.3.0) - unlink-file-at: func( + @since(version = 0.3.0-rc-2025-08-15) + unlink-file-at: async func( /// The relative path to a file to unlink. path: string, ) -> result<_, error-code>; @@ -589,8 +596,8 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - @since(version = 0.3.0) - is-same-object: func(other: borrow) -> bool; + @since(version = 0.3.0-rc-2025-08-15) + is-same-object: async func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred /// to by a descriptor. @@ -611,15 +618,15 @@ interface types { /// computed hash. /// /// However, none of these is required. - @since(version = 0.3.0) - metadata-hash: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + metadata-hash: async func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. - @since(version = 0.3.0) - metadata-hash-at: func( + @since(version = 0.3.0-rc-2025-08-15) + metadata-hash-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, /// The relative path of the file or directory to inspect. diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit index c0ab32afe..b9dcfd562 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit @@ -1,9 +1,9 @@ -package wasi:filesystem@0.3.0; +package wasi:filesystem@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import types; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import preopens; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit index 4708d9049..ecd504318 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0; +package wasi:random@0.3.0-rc-2025-08-15; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0) - insecure-seed: func() -> tuple; + @since(version = 0.3.0-rc-2025-08-15) + get-insecure-seed: func() -> tuple; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit index 4ea5e581f..d08d85e0b 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0; +package wasi:random@0.3.0-rc-2025-08-15; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/random.wit b/proposals/http/wit-0.3.0-draft/deps/random/random.wit index 786ef25f6..3808c3095 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/random.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/random.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0; +package wasi:random@0.3.0-rc-2025-08-15; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) get-random-u64: func() -> u64; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/world.wit b/proposals/http/wit-0.3.0-draft/deps/random/world.wit index 838d38023..e8f05cc43 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/world.wit @@ -1,13 +1,13 @@ -package wasi:random@0.3.0; +package wasi:random@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import random; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import insecure; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import insecure-seed; } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit index 7cc8b03e3..ab4156e25 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit @@ -1,10 +1,10 @@ -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface ip-name-lookup { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) use types.{ip-address}; /// Lookup error codes. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum error-code { /// Unknown error unknown, @@ -57,6 +57,6 @@ interface ip-name-lookup { /// - /// - /// - - @since(version = 0.3.0) - resolve-addresses: func(name: string) -> result, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + resolve-addresses: async func(name: string) -> result, error-code>; } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/types.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/types.wit index b5f84d360..3a7915ce9 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/types.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/types.wit @@ -1,7 +1,7 @@ -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) interface types { - @since(version = 0.3.0) - use wasi:clocks/monotonic-clock@0.3.0.{duration}; + @since(version = 0.3.0-rc-2025-08-15) + use wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15.{duration}; /// Error codes. /// @@ -14,7 +14,7 @@ interface types { /// - `out-of-memory` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum error-code { /// Unknown error unknown, @@ -70,7 +70,7 @@ interface types { datagram-too-large, } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -79,18 +79,18 @@ interface types { ipv6, } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type ipv4-address = tuple; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) type ipv6-address = tuple; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record ipv4-socket-address { /// sin_port port: u16, @@ -98,7 +98,7 @@ interface types { address: ipv4-address, } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) record ipv6-socket-address { /// sin6_port port: u16, @@ -110,7 +110,7 @@ interface types { scope-id: u32, } - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), @@ -125,7 +125,7 @@ interface types { /// - `connecting` /// - `connected` /// - `closed` - /// See + /// See /// for more information. /// /// Note: Except where explicitly mentioned, whenever this documentation uses @@ -135,7 +135,7 @@ interface types { /// In addition to the general error codes documented on the /// `types::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) resource tcp-socket { /// Create a new TCP socket. @@ -152,8 +152,8 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - constructor(address-family: ip-address-family); + @since(version = 0.3.0-rc-2025-08-15) + create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. /// @@ -186,7 +186,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Connect to a remote endpoint. @@ -218,10 +218,10 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - connect: func(remote-address: ip-socket-address) -> result<_, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + connect: async func(remote-address: ip-socket-address) -> result<_, error-code>; - /// Start listening return a stream of new inbound connections. + /// Start listening and return a stream of new inbound connections. /// /// Transitions the socket into the `listening` state. This can be called /// at most once per socket. @@ -285,7 +285,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) listen: func() -> result, error-code>; /// Transmit data to peer. @@ -308,8 +308,8 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - send: func(data: stream) -> result<_, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + send: async func(data: stream) -> result<_, error-code>; /// Read data from peer. /// @@ -328,7 +328,7 @@ interface types { /// were closed abnormally. /// /// If the caller is not expecting to receive any data from the peer, - /// they may cancel the receive task. Any data still in the receive queue + /// they may drop the stream. Any data still in the receive queue /// will be discarded. This is equivalent to calling `shutdown(SHUT_RD)` /// in POSIX. /// @@ -342,7 +342,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) receive: func() -> tuple, future>>; /// Get the bound local address. @@ -351,7 +351,7 @@ interface types { /// > If the socket has not been bound to a local name, the value /// > stored in the object pointed to by `address` is unspecified. /// - /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// WASI is stricter and requires `get-local-address` to return `invalid-state` when the socket hasn't been bound yet. /// /// # Typical errors /// - `invalid-state`: The socket is not bound to any local address. @@ -361,8 +361,8 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - local-address: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + get-local-address: func() -> result; /// Get the remote address. /// @@ -374,22 +374,22 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - remote-address: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + get-remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. - @since(version = 0.3.0) - is-listening: func() -> bool; + @since(version = 0.3.0-rc-2025-08-15) + get-is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. /// /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0) - address-family: func() -> ip-address-family; + @since(version = 0.3.0-rc-2025-08-15) + get-address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. /// @@ -400,7 +400,7 @@ interface types { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -412,9 +412,9 @@ interface types { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. - @since(version = 0.3.0) - keep-alive-enabled: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-keep-alive-enabled: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. @@ -427,9 +427,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - keep-alive-idle-time: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-keep-alive-idle-time: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. @@ -442,9 +442,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - keep-alive-interval: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-keep-alive-interval: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. @@ -457,9 +457,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - keep-alive-count: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-keep-alive-count: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -468,9 +468,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0) - hop-limit: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-hop-limit: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -483,18 +483,18 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - receive-buffer-size: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-receive-buffer-size: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0) - send-buffer-size: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-send-buffer-size: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } /// A UDP socket handle. - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) resource udp-socket { /// Create a new UDP socket. @@ -511,8 +511,8 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - constructor(address-family: ip-address-family); + @since(version = 0.3.0-rc-2025-08-15) + create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. /// @@ -532,7 +532,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Associate this socket with a specific peer address. @@ -571,7 +571,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) connect: func(remote-address: ip-socket-address) -> result<_, error-code>; /// Dissociate this socket from its peer address. @@ -589,7 +589,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) disconnect: func() -> result<_, error-code>; /// Send a message on the socket to a particular peer. @@ -610,7 +610,6 @@ interface types { /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `connect`. (EISCONN) /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) - /// - `invalid-state`: The socket has not been bound yet. /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) /// - `connection-refused`: The connection was refused. (ECONNREFUSED) /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) @@ -624,8 +623,8 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - send: func(data: list, remote-address: option) -> result<_, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + send: async func(data: list, remote-address: option) -> result<_, error-code>; /// Receive a message on the socket. /// @@ -650,8 +649,8 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - receive: func() -> result, ip-socket-address>, error-code>; + @since(version = 0.3.0-rc-2025-08-15) + receive: async func() -> result, ip-socket-address>, error-code>; /// Get the current bound address. /// @@ -659,7 +658,7 @@ interface types { /// > If the socket has not been bound to a local name, the value /// > stored in the object pointed to by `address` is unspecified. /// - /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. + /// WASI is stricter and requires `get-local-address` to return `invalid-state` when the socket hasn't been bound yet. /// /// # Typical errors /// - `invalid-state`: The socket is not bound to any local address. @@ -669,8 +668,8 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - local-address: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + get-local-address: func() -> result; /// Get the address the socket is currently "connected" to. /// @@ -682,16 +681,16 @@ interface types { /// - /// - /// - - @since(version = 0.3.0) - remote-address: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) + get-remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. /// /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0) - address-family: func() -> ip-address-family; + @since(version = 0.3.0-rc-2025-08-15) + get-address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// @@ -699,9 +698,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0) - unicast-hop-limit: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-unicast-hop-limit: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -714,13 +713,13 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0) - receive-buffer-size: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-receive-buffer-size: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0) - send-buffer-size: func() -> result; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) + get-send-buffer-size: func() -> result; + @since(version = 0.3.0-rc-2025-08-15) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit index 6c9951d1c..dfafac2ae 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit @@ -1,9 +1,9 @@ -package wasi:sockets@0.3.0; +package wasi:sockets@0.3.0-rc-2025-08-15; -@since(version = 0.3.0) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import types; - @since(version = 0.3.0) + @since(version = 0.3.0-rc-2025-08-15) import ip-name-lookup; } diff --git a/proposals/http/wit-0.3.0-draft/proxy.wit b/proposals/http/wit-0.3.0-draft/proxy.wit index 16688b96e..0ce3a3518 100644 --- a/proposals/http/wit-0.3.0-draft/proxy.wit +++ b/proposals/http/wit-0.3.0-draft/proxy.wit @@ -1,22 +1,22 @@ -package wasi:http@0.3.0-draft; +package wasi:http@0.3.0-rc-2025-08-15-draft; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. /// It is intended to be `include`d in other worlds. world imports { /// HTTP proxies have access to time and randomness. - include wasi:clocks/imports@0.3.0; - import wasi:random/random@0.3.0; + include wasi:clocks/imports@0.3.0-rc-2025-08-15; + import wasi:random/random@0.3.0-rc-2025-08-15; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.3.0; - import wasi:cli/stderr@0.3.0; + import wasi:cli/stdout@0.3.0-rc-2025-08-15; + import wasi:cli/stderr@0.3.0-rc-2025-08-15; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. - import wasi:cli/stdin@0.3.0; + import wasi:cli/stdin@0.3.0-rc-2025-08-15; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index 7a072b640..3d1d0ac78 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -1,7 +1,7 @@ /// This interface defines all of the types and methods for implementing HTTP /// Requests and Responses, as well as their headers, trailers, and bodies. interface types { - use wasi:clocks/monotonic-clock@0.3.0.{duration}; + use wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15.{duration}; /// This type corresponds to HTTP standard Methods. variant method { From 7e7423193e72f7c508fcc2b7790ca05c5bc92fa6 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Fri, 15 Aug 2025 17:09:10 -0400 Subject: [PATCH 1713/1772] fix: 0.3 remove additional -draft --- proposals/http/wit-0.3.0-draft/proxy.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit-0.3.0-draft/proxy.wit b/proposals/http/wit-0.3.0-draft/proxy.wit index 0ce3a3518..31e5facd0 100644 --- a/proposals/http/wit-0.3.0-draft/proxy.wit +++ b/proposals/http/wit-0.3.0-draft/proxy.wit @@ -1,4 +1,4 @@ -package wasi:http@0.3.0-rc-2025-08-15-draft; +package wasi:http@0.3.0-rc-2025-08-15; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. /// It is intended to be `include`d in other worlds. From de13592ae68858fbbe1c92bd615962a64d655561 Mon Sep 17 00:00:00 2001 From: Eugen Date: Sat, 16 Aug 2025 21:59:09 +0900 Subject: [PATCH 1714/1772] correct grammar (#95) --- proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit index 0c58241ff..d60a1ece8 100644 --- a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit +++ b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit @@ -37,7 +37,7 @@ interface monotonic-clock { when: instant, ); - /// Wait for the specified duration has elapsed. + /// Wait for the specified duration to elapse. @since(version = 0.3.0-rc-2025-08-15) wait-for: async func( how-long: duration, From 5fae7737eaad94c4a3a84356f6675746f5560232 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Sep 2025 16:48:18 -0500 Subject: [PATCH 1715/1772] Flag `wasi:cli/run#run` as an async function (#79) I think this was lost in various translations here and there, but I'm under the impression that the intention is that this is should be `async`-by-default. --- proposals/cli/wit-0.3.0-draft/run.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/cli/wit-0.3.0-draft/run.wit b/proposals/cli/wit-0.3.0-draft/run.wit index 6149db760..906b6ae10 100644 --- a/proposals/cli/wit-0.3.0-draft/run.wit +++ b/proposals/cli/wit-0.3.0-draft/run.wit @@ -2,5 +2,5 @@ interface run { /// Run the program. @since(version = 0.3.0-rc-2025-08-15) - run: func() -> result; + run: async func() -> result; } From 26e5038c9aaeb44bb1e59fa913e8a56e652dbe59 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 8 Sep 2025 14:51:36 -0700 Subject: [PATCH 1716/1772] Document that `monotonic-clock.now` doesn't wrap. (#96) * Document that `monotonic-clock.now` doesn't wrap. 584 years ought to be enough for anyone. * Document that implementations should pick a low start value. --- proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit | 5 +++++ proposals/clocks/wit/monotonic-clock.wit | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit index d60a1ece8..0dc02ab90 100644 --- a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit +++ b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit @@ -23,6 +23,11 @@ interface monotonic-clock { /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + /// + /// For completeness, this function traps if it's not possible to represent + /// the value of the clock in an `instant`. Consequently, implementations + /// should ensure that the starting time is low enough to avoid the + /// possibility of overflow in practice. @since(version = 0.3.0-rc-2025-08-15) now: func() -> instant; diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index 731e8a1e0..6ebd14e59 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -26,6 +26,11 @@ interface monotonic-clock { /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + /// + /// For completeness, this function traps if it's not possible to represent + /// the value of the clock in an `instant`. Consequently, implementations + /// should ensure that the starting time is low enough to avoid the + /// possibility of overflow in practice. @since(version = 0.2.0) now: func() -> instant; From 9e4209447e0317b5dec59444a0c33979ed7a8dbe Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Mon, 8 Sep 2025 16:28:12 -0700 Subject: [PATCH 1717/1772] add new types.wit package to hold `duration` (#98) --- proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit | 6 ++---- proposals/clocks/wit-0.3.0-draft/types.wit | 8 ++++++++ 2 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 proposals/clocks/wit-0.3.0-draft/types.wit diff --git a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit index 0dc02ab90..4464d29ba 100644 --- a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit +++ b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit @@ -9,16 +9,14 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// successive reads of the clock will produce non-decreasing values. @since(version = 0.3.0-rc-2025-08-15) interface monotonic-clock { + use types.{duration}; + /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. @since(version = 0.3.0-rc-2025-08-15) type instant = u64; - /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) - type duration = u64; - /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will diff --git a/proposals/clocks/wit-0.3.0-draft/types.wit b/proposals/clocks/wit-0.3.0-draft/types.wit new file mode 100644 index 000000000..4736b896e --- /dev/null +++ b/proposals/clocks/wit-0.3.0-draft/types.wit @@ -0,0 +1,8 @@ +package wasi:clocks@0.3.0-rc-2025-08-15; +/// This interface common types used throughout wasi:clocks. +@since(version = 0.3.0-rc-2025-08-15) +interface types { + /// A duration of time, in nanoseconds. + @since(version = 0.3.0-rc-2025-08-15) + type duration = u64; +} From 1f2b9ac0297db4c65bf8047f2d678bb80c6fe63e Mon Sep 17 00:00:00 2001 From: Lann Martin Date: Mon, 8 Sep 2025 17:38:47 -0400 Subject: [PATCH 1718/1772] stdio: Update interfaces to support error results --- proposals/cli/wit-0.3.0-draft/stdio.wit | 48 +++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/proposals/cli/wit-0.3.0-draft/stdio.wit b/proposals/cli/wit-0.3.0-draft/stdio.wit index 6c99a56f1..3b9c09c9b 100644 --- a/proposals/cli/wit-0.3.0-draft/stdio.wit +++ b/proposals/cli/wit-0.3.0-draft/stdio.wit @@ -1,17 +1,59 @@ +@since(version = 0.3.0-rc-2025-08-15) +interface stdio { + @since(version = 0.3.0-rc-2025-08-15) + enum error-code { + /// Input/output error + io, + /// Invalid or incomplete multibyte or wide character + illegal-byte-sequence, + /// Broken pipe + pipe, + } +} + @since(version = 0.3.0-rc-2025-08-15) interface stdin { + /// Return a stream for reading from stdin. + /// + /// This function returns a stream which provides data read from stdin, + /// and a future to signal read results. + /// + /// If the stream's readable end is dropped the future will resolve to success. + /// + /// If the stream's writable end is dropped the future will either resolve to + /// success if stdin was closed by the writer or to an error-code if reading + /// failed for some other reason. + /// + /// Multiple streams may be active at the same time. The behavior of concurrent + /// reads is implementation-specific. @since(version = 0.3.0-rc-2025-08-15) - get-stdin: func() -> stream; + read-stdin: func() -> tuple, future>>; } @since(version = 0.3.0-rc-2025-08-15) interface stdout { + /// Append from the given stream to stdout. + /// + /// If the stream's writable end is dropped this function will either return + /// success once the entire contents of the stream have been written or an + /// error-code representing a failure. + /// + /// Otherwise if there is an error the readable end of the stream will be + /// dropped and this function will return an error-code. @since(version = 0.3.0-rc-2025-08-15) - set-stdout: func(data: stream); + append-stdout: async func(data: stream) -> result<_, error-code>; } @since(version = 0.3.0-rc-2025-08-15) interface stderr { + /// Append from the given stream to stderr. + /// + /// If the stream's writable end is dropped this function will either return + /// success once the entire contents of the stream have been written or an + /// error-code representing a failure. + /// + /// Otherwise if there is an error the readable end of the stream will be + /// dropped and this function will return an error-code. @since(version = 0.3.0-rc-2025-08-15) - set-stderr: func(data: stream); + append-stderr: async func(data: stream) -> result<_, error-code>; } From 506143f4acf2a2ff55713efc95f921a0e750b0c1 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Mon, 15 Sep 2025 17:56:03 +0200 Subject: [PATCH 1719/1772] p3: rework `consume-body` (#185) Signed-off-by: Roman Volosatovs --- proposals/http/wit-0.3.0-draft/types.wit | 36 +++++++----------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index 3d1d0ac78..d8933cdcc 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -316,20 +316,12 @@ interface types { /// future to determine whether the body was received successfully. /// The future will only resolve after the stream is reported as closed. /// - /// The stream and future returned by this method are children: - /// they should be closed or consumed before the parent `response` - /// is dropped, or its ownership is transferred to another component - /// by e.g. `handler.handle`. + /// This function takes a `res` future as a parameter, which can be used to + /// communicate an error in handling of the request. /// - /// This method may be called multiple times. - /// - /// This method will return an error if it is called while either: - /// - a stream or future returned by a previous call to this method is still open - /// - a stream returned by a previous call to this method has reported itself as closed - /// Thus there will always be at most one readable stream open for a given body. - /// Each subsequent stream picks up where the previous one left off, - /// continuing until the entire body has been consumed. - consume-body: func() -> result, future, error-code>>>>; + /// Note that function will move the `request`, but references to headers or + /// request options acquired from it previously will remain valid. + consume-body: static func(this: request, res: future>) -> tuple, future, error-code>>>; } /// Parameters for making an HTTP Request. Each of these parameters is @@ -417,19 +409,11 @@ interface types { /// future to determine whether the body was received successfully. /// The future will only resolve after the stream is reported as closed. /// - /// The stream and future returned by this method are children: - /// they should be closed or consumed before the parent `response` - /// is dropped, or its ownership is transferred to another component - /// by e.g. `handler.handle`. - /// - /// This method may be called multiple times. + /// This function takes a `res` future as a parameter, which can be used to + /// communicate an error in handling of the response. /// - /// This method will return an error if it is called while either: - /// - a stream or future returned by a previous call to this method is still open - /// - a stream returned by a previous call to this method has reported itself as closed - /// Thus there will always be at most one readable stream open for a given body. - /// Each subsequent stream picks up where the previous one left off, - /// continuing until the entire body has been consumed. - consume-body: func() -> result, future, error-code>>>>; + /// Note that function will move the `response`, but references to headers + /// acquired from it previously will remain valid. + consume-body: static func(this: response, res: future>) -> tuple, future, error-code>>>; } } From b1d38533df096e74a320fa46a671d0524fbbf1b4 Mon Sep 17 00:00:00 2001 From: Lann Martin Date: Mon, 15 Sep 2025 13:19:56 -0400 Subject: [PATCH 1720/1772] stdio: Tweak method names --- proposals/cli/wit-0.3.0-draft/stdio.wit | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/cli/wit-0.3.0-draft/stdio.wit b/proposals/cli/wit-0.3.0-draft/stdio.wit index 3b9c09c9b..c1bc8acda 100644 --- a/proposals/cli/wit-0.3.0-draft/stdio.wit +++ b/proposals/cli/wit-0.3.0-draft/stdio.wit @@ -27,12 +27,12 @@ interface stdin { /// Multiple streams may be active at the same time. The behavior of concurrent /// reads is implementation-specific. @since(version = 0.3.0-rc-2025-08-15) - read-stdin: func() -> tuple, future>>; + read-via-stream: func() -> tuple, future>>; } @since(version = 0.3.0-rc-2025-08-15) interface stdout { - /// Append from the given stream to stdout. + /// Write the given stream to stdout. /// /// If the stream's writable end is dropped this function will either return /// success once the entire contents of the stream have been written or an @@ -41,12 +41,12 @@ interface stdout { /// Otherwise if there is an error the readable end of the stream will be /// dropped and this function will return an error-code. @since(version = 0.3.0-rc-2025-08-15) - append-stdout: async func(data: stream) -> result<_, error-code>; + write-via-stream: async func(data: stream) -> result<_, error-code>; } @since(version = 0.3.0-rc-2025-08-15) interface stderr { - /// Append from the given stream to stderr. + /// Write the given stream to stderr. /// /// If the stream's writable end is dropped this function will either return /// success once the entire contents of the stream have been written or an @@ -55,5 +55,5 @@ interface stderr { /// Otherwise if there is an error the readable end of the stream will be /// dropped and this function will return an error-code. @since(version = 0.3.0-rc-2025-08-15) - append-stderr: async func(data: stream) -> result<_, error-code>; + write-via-stream: async func(data: stream) -> result<_, error-code>; } From 4c5cae58801e6467965bcbc05641c9c1e0c60d78 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 14:21:31 +0000 Subject: [PATCH 1721/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16 --- proposals/random/wit-0.3.0-draft/insecure-seed.wit | 6 +++--- proposals/random/wit-0.3.0-draft/insecure.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/random.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/world.wit | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/proposals/random/wit-0.3.0-draft/insecure-seed.wit b/proposals/random/wit-0.3.0-draft/insecure-seed.wit index ecd504318..302151ba6 100644 --- a/proposals/random/wit-0.3.0-draft/insecure-seed.wit +++ b/proposals/random/wit-0.3.0-draft/insecure-seed.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-seed: func() -> tuple; } diff --git a/proposals/random/wit-0.3.0-draft/insecure.wit b/proposals/random/wit-0.3.0-draft/insecure.wit index d08d85e0b..39146e391 100644 --- a/proposals/random/wit-0.3.0-draft/insecure.wit +++ b/proposals/random/wit-0.3.0-draft/insecure.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/random.wit b/proposals/random/wit-0.3.0-draft/random.wit index 3808c3095..fa1f111dc 100644 --- a/proposals/random/wit-0.3.0-draft/random.wit +++ b/proposals/random/wit-0.3.0-draft/random.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/world.wit b/proposals/random/wit-0.3.0-draft/world.wit index e8f05cc43..08c5ed88b 100644 --- a/proposals/random/wit-0.3.0-draft/world.wit +++ b/proposals/random/wit-0.3.0-draft/world.wit @@ -1,13 +1,13 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import random; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import insecure; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import insecure-seed; } From e33f06c05bb650b19bd8f20a6ca2b356a02aa002 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 14:31:37 +0000 Subject: [PATCH 1722/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16 --- .../filesystem/wit-0.3.0-draft/deps.lock | 4 +- .../deps/clocks/monotonic-clock.wit | 13 +-- .../wit-0.3.0-draft/deps/clocks/types.wit | 8 ++ .../filesystem/wit-0.3.0-draft/preopens.wit | 8 +- .../filesystem/wit-0.3.0-draft/types.wit | 80 +++++++++---------- .../filesystem/wit-0.3.0-draft/world.wit | 8 +- 6 files changed, 66 insertions(+), 55 deletions(-) create mode 100644 proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit diff --git a/proposals/filesystem/wit-0.3.0-draft/deps.lock b/proposals/filesystem/wit-0.3.0-draft/deps.lock index 07d589294..5a3600321 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps.lock +++ b/proposals/filesystem/wit-0.3.0-draft/deps.lock @@ -1,5 +1,5 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "626953ec28ae956ec1233c4350deab6e5cdcbdd9ae6d491e102ad7c6901cc8bf" -sha512 = "ae375b002cfaacdbaa133bb87747d1b86675e13144067c3005d6c32cf5c37bb7a52b693ae46d5cd65fc4910a78d7255d0ada5142828a022497fd0eaacb61761f" +sha256 = "d0257e056a4061eaab58a934d84b4b35534d90866667054e886da65c170aeef6" +sha512 = "b033cd0171d9d0c908b17f98f792e47eaeee7534d4bca664c62bdab6f48a8046179e068d4ef11d1e333d3ca44777691b14293eb955e88fda701bdcf90637efae" diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 0c58241ff..4464d29ba 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -9,20 +9,23 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// successive reads of the clock will produce non-decreasing values. @since(version = 0.3.0-rc-2025-08-15) interface monotonic-clock { + use types.{duration}; + /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. @since(version = 0.3.0-rc-2025-08-15) type instant = u64; - /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) - type duration = u64; - /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + /// + /// For completeness, this function traps if it's not possible to represent + /// the value of the clock in an `instant`. Consequently, implementations + /// should ensure that the starting time is low enough to avoid the + /// possibility of overflow in practice. @since(version = 0.3.0-rc-2025-08-15) now: func() -> instant; @@ -37,7 +40,7 @@ interface monotonic-clock { when: instant, ); - /// Wait for the specified duration has elapsed. + /// Wait for the specified duration to elapse. @since(version = 0.3.0-rc-2025-08-15) wait-for: async func( how-long: duration, diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit new file mode 100644 index 000000000..4736b896e --- /dev/null +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit @@ -0,0 +1,8 @@ +package wasi:clocks@0.3.0-rc-2025-08-15; +/// This interface common types used throughout wasi:clocks. +@since(version = 0.3.0-rc-2025-08-15) +interface types { + /// A duration of time, in nanoseconds. + @since(version = 0.3.0-rc-2025-08-15) + type duration = u64; +} diff --git a/proposals/filesystem/wit-0.3.0-draft/preopens.wit b/proposals/filesystem/wit-0.3.0-draft/preopens.wit index b0f609aa9..9036e90e8 100644 --- a/proposals/filesystem/wit-0.3.0-draft/preopens.wit +++ b/proposals/filesystem/wit-0.3.0-draft/preopens.wit @@ -1,11 +1,11 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface preopens { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use types.{descriptor}; /// Return the set of preopened directories, and their paths. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-directories: func() -> list>; } diff --git a/proposals/filesystem/wit-0.3.0-draft/types.wit b/proposals/filesystem/wit-0.3.0-draft/types.wit index 07d770a83..41d91beee 100644 --- a/proposals/filesystem/wit-0.3.0-draft/types.wit +++ b/proposals/filesystem/wit-0.3.0-draft/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -23,19 +23,19 @@ package wasi:filesystem@0.3.0-rc-2025-08-15; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface types { - @since(version = 0.3.0-rc-2025-08-15) - use wasi:clocks/wall-clock@0.3.0-rc-2025-08-15.{datetime}; + @since(version = 0.3.0-rc-2025-09-16) + use wasi:clocks/wall-clock@0.3.0-rc-2025-09-16.{datetime}; /// File size or length of a region within a file. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -59,7 +59,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -103,7 +103,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record descriptor-stat { /// File type. %type: descriptor-type, @@ -130,7 +130,7 @@ interface types { } /// Flags determining the method of how paths are resolved. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -138,7 +138,7 @@ interface types { } /// Open flags used by `open-at`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -151,11 +151,11 @@ interface types { } /// Number of hard links to an inode. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -255,7 +255,7 @@ interface types { } /// File or memory access pattern advisory information. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -279,7 +279,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -290,7 +290,7 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource descriptor { /// Return a stream for reading from a file. /// @@ -308,7 +308,7 @@ interface types { /// resolves to `err` with an `error-code`. /// /// Note: This is similar to `pread` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, @@ -326,7 +326,7 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `pwrite` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) write-via-stream: async func( /// Data to write data: stream, @@ -342,13 +342,13 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `write` with `O_APPEND` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) append-via-stream: async func(data: stream) -> result<_, error-code>; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) advise: async func( /// The offset within the file to which the advisory applies. offset: filesize, @@ -364,7 +364,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) sync-data: async func() -> result<_, error-code>; /// Get flags associated with a descriptor. @@ -373,7 +373,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-flags: async func() -> result; /// Get the dynamic type of a descriptor. @@ -386,14 +386,14 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-type: async func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-size: async func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. @@ -401,7 +401,7 @@ interface types { /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-times: async func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, @@ -421,7 +421,7 @@ interface types { /// /// This function returns a future, which will resolve to an error code if /// reading full contents of the directory fails. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) read-directory: async func() -> tuple, future>>; /// Synchronize the data and metadata of a file to disk. @@ -430,13 +430,13 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) sync: async func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) create-directory-at: async func( /// The relative path at which to create the directory. path: string, @@ -451,7 +451,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) stat: async func() -> result; /// Return the attributes of a file or directory. @@ -461,7 +461,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) stat-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -475,7 +475,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-times-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -494,7 +494,7 @@ interface types { /// `error-code::not-permitted` if the old path is not a file. /// /// Note: This is similar to `linkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) link-at: async func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, @@ -518,7 +518,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) open-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -536,7 +536,7 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) readlink-at: async func( /// The relative path of the symbolic link from which to read. path: string, @@ -547,7 +547,7 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) remove-directory-at: async func( /// The relative path to a directory to remove. path: string, @@ -556,7 +556,7 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) rename-at: async func( /// The relative source path of the file or directory to rename. old-path: string, @@ -572,7 +572,7 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) symlink-at: async func( /// The contents of the symbolic link. old-path: string, @@ -584,7 +584,7 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) unlink-file-at: async func( /// The relative path to a file to unlink. path: string, @@ -596,7 +596,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) is-same-object: async func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred @@ -618,14 +618,14 @@ interface types { /// computed hash. /// /// However, none of these is required. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) metadata-hash: async func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) metadata-hash-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, diff --git a/proposals/filesystem/wit-0.3.0-draft/world.wit b/proposals/filesystem/wit-0.3.0-draft/world.wit index b9dcfd562..87fc72716 100644 --- a/proposals/filesystem/wit-0.3.0-draft/world.wit +++ b/proposals/filesystem/wit-0.3.0-draft/world.wit @@ -1,9 +1,9 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import types; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import preopens; } From 74447ccabc304d326f99b073f09316051c8e1092 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 14:34:08 +0000 Subject: [PATCH 1723/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16 --- proposals/sockets/wit-0.3.0-draft/deps.lock | 4 +- .../deps/clocks/monotonic-clock.wit | 13 ++- .../wit-0.3.0-draft/deps/clocks/types.wit | 8 ++ .../wit-0.3.0-draft/ip-name-lookup.wit | 8 +- proposals/sockets/wit-0.3.0-draft/types.wit | 106 +++++++++--------- proposals/sockets/wit-0.3.0-draft/world.wit | 8 +- 6 files changed, 79 insertions(+), 68 deletions(-) create mode 100644 proposals/sockets/wit-0.3.0-draft/deps/clocks/types.wit diff --git a/proposals/sockets/wit-0.3.0-draft/deps.lock b/proposals/sockets/wit-0.3.0-draft/deps.lock index 07d589294..5a3600321 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps.lock +++ b/proposals/sockets/wit-0.3.0-draft/deps.lock @@ -1,5 +1,5 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "626953ec28ae956ec1233c4350deab6e5cdcbdd9ae6d491e102ad7c6901cc8bf" -sha512 = "ae375b002cfaacdbaa133bb87747d1b86675e13144067c3005d6c32cf5c37bb7a52b693ae46d5cd65fc4910a78d7255d0ada5142828a022497fd0eaacb61761f" +sha256 = "d0257e056a4061eaab58a934d84b4b35534d90866667054e886da65c170aeef6" +sha512 = "b033cd0171d9d0c908b17f98f792e47eaeee7534d4bca664c62bdab6f48a8046179e068d4ef11d1e333d3ca44777691b14293eb955e88fda701bdcf90637efae" diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 0c58241ff..4464d29ba 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -9,20 +9,23 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// successive reads of the clock will produce non-decreasing values. @since(version = 0.3.0-rc-2025-08-15) interface monotonic-clock { + use types.{duration}; + /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. @since(version = 0.3.0-rc-2025-08-15) type instant = u64; - /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) - type duration = u64; - /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + /// + /// For completeness, this function traps if it's not possible to represent + /// the value of the clock in an `instant`. Consequently, implementations + /// should ensure that the starting time is low enough to avoid the + /// possibility of overflow in practice. @since(version = 0.3.0-rc-2025-08-15) now: func() -> instant; @@ -37,7 +40,7 @@ interface monotonic-clock { when: instant, ); - /// Wait for the specified duration has elapsed. + /// Wait for the specified duration to elapse. @since(version = 0.3.0-rc-2025-08-15) wait-for: async func( how-long: duration, diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/types.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/types.wit new file mode 100644 index 000000000..4736b896e --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/types.wit @@ -0,0 +1,8 @@ +package wasi:clocks@0.3.0-rc-2025-08-15; +/// This interface common types used throughout wasi:clocks. +@since(version = 0.3.0-rc-2025-08-15) +interface types { + /// A duration of time, in nanoseconds. + @since(version = 0.3.0-rc-2025-08-15) + type duration = u64; +} diff --git a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit index ab4156e25..6a652ff23 100644 --- a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit +++ b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit @@ -1,10 +1,10 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface ip-name-lookup { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use types.{ip-address}; /// Lookup error codes. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum error-code { /// Unknown error unknown, @@ -57,6 +57,6 @@ interface ip-name-lookup { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resolve-addresses: async func(name: string) -> result, error-code>; } diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 3a7915ce9..2ed1912e4 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -1,7 +1,7 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface types { - @since(version = 0.3.0-rc-2025-08-15) - use wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15.{duration}; + @since(version = 0.3.0-rc-2025-09-16) + use wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16.{duration}; /// Error codes. /// @@ -14,7 +14,7 @@ interface types { /// - `out-of-memory` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum error-code { /// Unknown error unknown, @@ -70,7 +70,7 @@ interface types { datagram-too-large, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -79,18 +79,18 @@ interface types { ipv6, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type ipv4-address = tuple; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type ipv6-address = tuple; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record ipv4-socket-address { /// sin_port port: u16, @@ -98,7 +98,7 @@ interface types { address: ipv4-address, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record ipv6-socket-address { /// sin6_port port: u16, @@ -110,7 +110,7 @@ interface types { scope-id: u32, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), @@ -135,7 +135,7 @@ interface types { /// In addition to the general error codes documented on the /// `types::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource tcp-socket { /// Create a new TCP socket. @@ -152,7 +152,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. @@ -186,7 +186,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Connect to a remote endpoint. @@ -218,7 +218,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) connect: async func(remote-address: ip-socket-address) -> result<_, error-code>; /// Start listening and return a stream of new inbound connections. @@ -285,7 +285,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) listen: func() -> result, error-code>; /// Transmit data to peer. @@ -308,7 +308,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) send: async func(data: stream) -> result<_, error-code>; /// Read data from peer. @@ -342,7 +342,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) receive: func() -> tuple, future>>; /// Get the bound local address. @@ -361,7 +361,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-local-address: func() -> result; /// Get the remote address. @@ -374,13 +374,13 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. @@ -388,7 +388,7 @@ interface types { /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. @@ -400,7 +400,7 @@ interface types { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -412,9 +412,9 @@ interface types { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-enabled: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. @@ -427,9 +427,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-idle-time: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. @@ -442,9 +442,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-interval: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. @@ -457,9 +457,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-count: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -468,9 +468,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -483,18 +483,18 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } /// A UDP socket handle. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource udp-socket { /// Create a new UDP socket. @@ -511,7 +511,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. @@ -532,7 +532,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Associate this socket with a specific peer address. @@ -571,7 +571,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) connect: func(remote-address: ip-socket-address) -> result<_, error-code>; /// Dissociate this socket from its peer address. @@ -589,7 +589,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) disconnect: func() -> result<_, error-code>; /// Send a message on the socket to a particular peer. @@ -623,7 +623,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) send: async func(data: list, remote-address: option) -> result<_, error-code>; /// Receive a message on the socket. @@ -649,7 +649,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) receive: async func() -> result, ip-socket-address>, error-code>; /// Get the current bound address. @@ -668,7 +668,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-local-address: func() -> result; /// Get the address the socket is currently "connected" to. @@ -681,7 +681,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. @@ -689,7 +689,7 @@ interface types { /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -698,9 +698,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-unicast-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -713,13 +713,13 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } } diff --git a/proposals/sockets/wit-0.3.0-draft/world.wit b/proposals/sockets/wit-0.3.0-draft/world.wit index dfafac2ae..44cc427ed 100644 --- a/proposals/sockets/wit-0.3.0-draft/world.wit +++ b/proposals/sockets/wit-0.3.0-draft/world.wit @@ -1,9 +1,9 @@ -package wasi:sockets@0.3.0-rc-2025-08-15; +package wasi:sockets@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import types; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import ip-name-lookup; } From 0c90454ef9da3ee3906edcaa4c4519d3403b9809 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 14:38:29 +0000 Subject: [PATCH 1724/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16 --- proposals/http/wit-0.3.0-draft/deps.lock | 4 +- .../http/wit-0.3.0-draft/deps/cli/run.wit | 2 +- .../http/wit-0.3.0-draft/deps/cli/stdio.wit | 48 +++++++++++++++++-- proposals/http/wit-0.3.0-draft/proxy.wit | 12 ++--- proposals/http/wit-0.3.0-draft/types.wit | 2 +- 5 files changed, 55 insertions(+), 13 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/deps.lock b/proposals/http/wit-0.3.0-draft/deps.lock index be1b0569e..9912e0de2 100644 --- a/proposals/http/wit-0.3.0-draft/deps.lock +++ b/proposals/http/wit-0.3.0-draft/deps.lock @@ -1,8 +1,8 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "7f9cf181100ca1cadcb49a1efa3e80828d375df2d5ddf10a8f66e848d423aea5" -sha512 = "569f6b4ed2a3bec913e5e06fd35caab564048cf31632795c2fbdd8c40ddb5f5eea7b1cc59d33c80e5d7b642ed246ba4a3e40d3edeaaa2c6a5c4bcd02e0b67212" +sha256 = "5ff03c236a6fed89d2968c3fd5d9e2b3f4fcd7a606dc94ead51df5357bdabe76" +sha512 = "d0277a9b3692de917ef8b1bbe6be9247157d548962dde181b159788064a06513c6f6d775fcca94a3170fe2149ca75d609664938716f4dc877ef65cd7db07eb76" deps = ["clocks", "filesystem", "random", "sockets"] [clocks] diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/run.wit b/proposals/http/wit-0.3.0-draft/deps/cli/run.wit index 6149db760..906b6ae10 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/run.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/run.wit @@ -2,5 +2,5 @@ interface run { /// Run the program. @since(version = 0.3.0-rc-2025-08-15) - run: func() -> result; + run: async func() -> result; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit index 6c99a56f1..c1bc8acda 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit @@ -1,17 +1,59 @@ +@since(version = 0.3.0-rc-2025-08-15) +interface stdio { + @since(version = 0.3.0-rc-2025-08-15) + enum error-code { + /// Input/output error + io, + /// Invalid or incomplete multibyte or wide character + illegal-byte-sequence, + /// Broken pipe + pipe, + } +} + @since(version = 0.3.0-rc-2025-08-15) interface stdin { + /// Return a stream for reading from stdin. + /// + /// This function returns a stream which provides data read from stdin, + /// and a future to signal read results. + /// + /// If the stream's readable end is dropped the future will resolve to success. + /// + /// If the stream's writable end is dropped the future will either resolve to + /// success if stdin was closed by the writer or to an error-code if reading + /// failed for some other reason. + /// + /// Multiple streams may be active at the same time. The behavior of concurrent + /// reads is implementation-specific. @since(version = 0.3.0-rc-2025-08-15) - get-stdin: func() -> stream; + read-via-stream: func() -> tuple, future>>; } @since(version = 0.3.0-rc-2025-08-15) interface stdout { + /// Write the given stream to stdout. + /// + /// If the stream's writable end is dropped this function will either return + /// success once the entire contents of the stream have been written or an + /// error-code representing a failure. + /// + /// Otherwise if there is an error the readable end of the stream will be + /// dropped and this function will return an error-code. @since(version = 0.3.0-rc-2025-08-15) - set-stdout: func(data: stream); + write-via-stream: async func(data: stream) -> result<_, error-code>; } @since(version = 0.3.0-rc-2025-08-15) interface stderr { + /// Write the given stream to stderr. + /// + /// If the stream's writable end is dropped this function will either return + /// success once the entire contents of the stream have been written or an + /// error-code representing a failure. + /// + /// Otherwise if there is an error the readable end of the stream will be + /// dropped and this function will return an error-code. @since(version = 0.3.0-rc-2025-08-15) - set-stderr: func(data: stream); + write-via-stream: async func(data: stream) -> result<_, error-code>; } diff --git a/proposals/http/wit-0.3.0-draft/proxy.wit b/proposals/http/wit-0.3.0-draft/proxy.wit index 31e5facd0..223083ea2 100644 --- a/proposals/http/wit-0.3.0-draft/proxy.wit +++ b/proposals/http/wit-0.3.0-draft/proxy.wit @@ -1,22 +1,22 @@ -package wasi:http@0.3.0-rc-2025-08-15; +package wasi:http@0.3.0-rc-2025-09-16; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. /// It is intended to be `include`d in other worlds. world imports { /// HTTP proxies have access to time and randomness. - include wasi:clocks/imports@0.3.0-rc-2025-08-15; - import wasi:random/random@0.3.0-rc-2025-08-15; + include wasi:clocks/imports@0.3.0-rc-2025-09-16; + import wasi:random/random@0.3.0-rc-2025-09-16; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.3.0-rc-2025-08-15; - import wasi:cli/stderr@0.3.0-rc-2025-08-15; + import wasi:cli/stdout@0.3.0-rc-2025-09-16; + import wasi:cli/stderr@0.3.0-rc-2025-09-16; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. - import wasi:cli/stdin@0.3.0-rc-2025-08-15; + import wasi:cli/stdin@0.3.0-rc-2025-09-16; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index d8933cdcc..8269eea20 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -1,7 +1,7 @@ /// This interface defines all of the types and methods for implementing HTTP /// Requests and Responses, as well as their headers, trailers, and bodies. interface types { - use wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15.{duration}; + use wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16.{duration}; /// This type corresponds to HTTP standard Methods. variant method { From 7fea3a4f6a53e7ccde08379e3ca0ad15130dbb9d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 17:58:20 +0000 Subject: [PATCH 1725/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16-1 --- proposals/random/wit-0.3.0-draft/insecure-seed.wit | 6 +++--- proposals/random/wit-0.3.0-draft/insecure.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/random.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/world.wit | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/proposals/random/wit-0.3.0-draft/insecure-seed.wit b/proposals/random/wit-0.3.0-draft/insecure-seed.wit index 302151ba6..155a88fbf 100644 --- a/proposals/random/wit-0.3.0-draft/insecure-seed.wit +++ b/proposals/random/wit-0.3.0-draft/insecure-seed.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16; +package wasi:random@0.3.0-rc-2025-09-16-1; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-09-16-1) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-09-16-1) get-insecure-seed: func() -> tuple; } diff --git a/proposals/random/wit-0.3.0-draft/insecure.wit b/proposals/random/wit-0.3.0-draft/insecure.wit index 39146e391..2b190a4a1 100644 --- a/proposals/random/wit-0.3.0-draft/insecure.wit +++ b/proposals/random/wit-0.3.0-draft/insecure.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16; +package wasi:random@0.3.0-rc-2025-09-16-1; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-09-16-1) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-09-16-1) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-09-16-1) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/random.wit b/proposals/random/wit-0.3.0-draft/random.wit index fa1f111dc..620d82cb8 100644 --- a/proposals/random/wit-0.3.0-draft/random.wit +++ b/proposals/random/wit-0.3.0-draft/random.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16; +package wasi:random@0.3.0-rc-2025-09-16-1; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-09-16-1) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-09-16-1) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-09-16-1) get-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/world.wit b/proposals/random/wit-0.3.0-draft/world.wit index 08c5ed88b..e7ce9713f 100644 --- a/proposals/random/wit-0.3.0-draft/world.wit +++ b/proposals/random/wit-0.3.0-draft/world.wit @@ -1,13 +1,13 @@ -package wasi:random@0.3.0-rc-2025-09-16; +package wasi:random@0.3.0-rc-2025-09-16-1; -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-09-16-1) world imports { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-09-16-1) import random; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-09-16-1) import insecure; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-09-16-1) import insecure-seed; } From c1ee1cb967afbfa505660ab8a61610f9d645fe8d Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Tue, 16 Sep 2025 20:01:05 +0200 Subject: [PATCH 1726/1772] Revert "Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16-1" --- proposals/random/wit-0.3.0-draft/insecure-seed.wit | 6 +++--- proposals/random/wit-0.3.0-draft/insecure.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/random.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/world.wit | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/proposals/random/wit-0.3.0-draft/insecure-seed.wit b/proposals/random/wit-0.3.0-draft/insecure-seed.wit index 155a88fbf..302151ba6 100644 --- a/proposals/random/wit-0.3.0-draft/insecure-seed.wit +++ b/proposals/random/wit-0.3.0-draft/insecure-seed.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16-1; +package wasi:random@0.3.0-rc-2025-09-16; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16-1) +@since(version = 0.3.0-rc-2025-09-16) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-seed: func() -> tuple; } diff --git a/proposals/random/wit-0.3.0-draft/insecure.wit b/proposals/random/wit-0.3.0-draft/insecure.wit index 2b190a4a1..39146e391 100644 --- a/proposals/random/wit-0.3.0-draft/insecure.wit +++ b/proposals/random/wit-0.3.0-draft/insecure.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16-1; +package wasi:random@0.3.0-rc-2025-09-16; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16-1) +@since(version = 0.3.0-rc-2025-09-16) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/random.wit b/proposals/random/wit-0.3.0-draft/random.wit index 620d82cb8..fa1f111dc 100644 --- a/proposals/random/wit-0.3.0-draft/random.wit +++ b/proposals/random/wit-0.3.0-draft/random.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16-1; +package wasi:random@0.3.0-rc-2025-09-16; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16-1) +@since(version = 0.3.0-rc-2025-09-16) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) get-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/world.wit b/proposals/random/wit-0.3.0-draft/world.wit index e7ce9713f..08c5ed88b 100644 --- a/proposals/random/wit-0.3.0-draft/world.wit +++ b/proposals/random/wit-0.3.0-draft/world.wit @@ -1,13 +1,13 @@ -package wasi:random@0.3.0-rc-2025-09-16-1; +package wasi:random@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-09-16-1) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) import random; - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) import insecure; - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) import insecure-seed; } From d0e9226c06bf7dde2f9bd354015b57f4591d37ed Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Tue, 16 Sep 2025 20:06:28 +0200 Subject: [PATCH 1727/1772] Revert "Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16" --- proposals/random/wit-0.3.0-draft/insecure-seed.wit | 6 +++--- proposals/random/wit-0.3.0-draft/insecure.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/random.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/world.wit | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/proposals/random/wit-0.3.0-draft/insecure-seed.wit b/proposals/random/wit-0.3.0-draft/insecure-seed.wit index 302151ba6..ecd504318 100644 --- a/proposals/random/wit-0.3.0-draft/insecure-seed.wit +++ b/proposals/random/wit-0.3.0-draft/insecure-seed.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16; +package wasi:random@0.3.0-rc-2025-08-15; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-08-15) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-insecure-seed: func() -> tuple; } diff --git a/proposals/random/wit-0.3.0-draft/insecure.wit b/proposals/random/wit-0.3.0-draft/insecure.wit index 39146e391..d08d85e0b 100644 --- a/proposals/random/wit-0.3.0-draft/insecure.wit +++ b/proposals/random/wit-0.3.0-draft/insecure.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16; +package wasi:random@0.3.0-rc-2025-08-15; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-08-15) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/random.wit b/proposals/random/wit-0.3.0-draft/random.wit index fa1f111dc..3808c3095 100644 --- a/proposals/random/wit-0.3.0-draft/random.wit +++ b/proposals/random/wit-0.3.0-draft/random.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16; +package wasi:random@0.3.0-rc-2025-08-15; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-08-15) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/world.wit b/proposals/random/wit-0.3.0-draft/world.wit index 08c5ed88b..e8f05cc43 100644 --- a/proposals/random/wit-0.3.0-draft/world.wit +++ b/proposals/random/wit-0.3.0-draft/world.wit @@ -1,13 +1,13 @@ -package wasi:random@0.3.0-rc-2025-09-16; +package wasi:random@0.3.0-rc-2025-08-15; -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) import random; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) import insecure; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) import insecure-seed; } From 7c0110a232162a28a770a1d21ed00e1629525638 Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Tue, 16 Sep 2025 20:08:40 +0200 Subject: [PATCH 1728/1772] Revert "Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16" --- proposals/sockets/wit-0.3.0-draft/deps.lock | 4 +- .../deps/clocks/monotonic-clock.wit | 13 +-- .../wit-0.3.0-draft/deps/clocks/types.wit | 8 -- .../wit-0.3.0-draft/ip-name-lookup.wit | 8 +- proposals/sockets/wit-0.3.0-draft/types.wit | 106 +++++++++--------- proposals/sockets/wit-0.3.0-draft/world.wit | 8 +- 6 files changed, 68 insertions(+), 79 deletions(-) delete mode 100644 proposals/sockets/wit-0.3.0-draft/deps/clocks/types.wit diff --git a/proposals/sockets/wit-0.3.0-draft/deps.lock b/proposals/sockets/wit-0.3.0-draft/deps.lock index 5a3600321..07d589294 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps.lock +++ b/proposals/sockets/wit-0.3.0-draft/deps.lock @@ -1,5 +1,5 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "d0257e056a4061eaab58a934d84b4b35534d90866667054e886da65c170aeef6" -sha512 = "b033cd0171d9d0c908b17f98f792e47eaeee7534d4bca664c62bdab6f48a8046179e068d4ef11d1e333d3ca44777691b14293eb955e88fda701bdcf90637efae" +sha256 = "626953ec28ae956ec1233c4350deab6e5cdcbdd9ae6d491e102ad7c6901cc8bf" +sha512 = "ae375b002cfaacdbaa133bb87747d1b86675e13144067c3005d6c32cf5c37bb7a52b693ae46d5cd65fc4910a78d7255d0ada5142828a022497fd0eaacb61761f" diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 4464d29ba..0c58241ff 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -9,23 +9,20 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// successive reads of the clock will produce non-decreasing values. @since(version = 0.3.0-rc-2025-08-15) interface monotonic-clock { - use types.{duration}; - /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. @since(version = 0.3.0-rc-2025-08-15) type instant = u64; + /// A duration of time, in nanoseconds. + @since(version = 0.3.0-rc-2025-08-15) + type duration = u64; + /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - /// - /// For completeness, this function traps if it's not possible to represent - /// the value of the clock in an `instant`. Consequently, implementations - /// should ensure that the starting time is low enough to avoid the - /// possibility of overflow in practice. @since(version = 0.3.0-rc-2025-08-15) now: func() -> instant; @@ -40,7 +37,7 @@ interface monotonic-clock { when: instant, ); - /// Wait for the specified duration to elapse. + /// Wait for the specified duration has elapsed. @since(version = 0.3.0-rc-2025-08-15) wait-for: async func( how-long: duration, diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/types.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/types.wit deleted file mode 100644 index 4736b896e..000000000 --- a/proposals/sockets/wit-0.3.0-draft/deps/clocks/types.wit +++ /dev/null @@ -1,8 +0,0 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; -/// This interface common types used throughout wasi:clocks. -@since(version = 0.3.0-rc-2025-08-15) -interface types { - /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) - type duration = u64; -} diff --git a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit index 6a652ff23..ab4156e25 100644 --- a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit +++ b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit @@ -1,10 +1,10 @@ -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-08-15) interface ip-name-lookup { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) use types.{ip-address}; /// Lookup error codes. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) enum error-code { /// Unknown error unknown, @@ -57,6 +57,6 @@ interface ip-name-lookup { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) resolve-addresses: async func(name: string) -> result, error-code>; } diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 2ed1912e4..3a7915ce9 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -1,7 +1,7 @@ -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-08-15) interface types { - @since(version = 0.3.0-rc-2025-09-16) - use wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16.{duration}; + @since(version = 0.3.0-rc-2025-08-15) + use wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15.{duration}; /// Error codes. /// @@ -14,7 +14,7 @@ interface types { /// - `out-of-memory` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) enum error-code { /// Unknown error unknown, @@ -70,7 +70,7 @@ interface types { datagram-too-large, } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -79,18 +79,18 @@ interface types { ipv6, } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) type ipv4-address = tuple; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) type ipv6-address = tuple; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) record ipv4-socket-address { /// sin_port port: u16, @@ -98,7 +98,7 @@ interface types { address: ipv4-address, } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) record ipv6-socket-address { /// sin6_port port: u16, @@ -110,7 +110,7 @@ interface types { scope-id: u32, } - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), @@ -135,7 +135,7 @@ interface types { /// In addition to the general error codes documented on the /// `types::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) resource tcp-socket { /// Create a new TCP socket. @@ -152,7 +152,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. @@ -186,7 +186,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Connect to a remote endpoint. @@ -218,7 +218,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) connect: async func(remote-address: ip-socket-address) -> result<_, error-code>; /// Start listening and return a stream of new inbound connections. @@ -285,7 +285,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) listen: func() -> result, error-code>; /// Transmit data to peer. @@ -308,7 +308,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) send: async func(data: stream) -> result<_, error-code>; /// Read data from peer. @@ -342,7 +342,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) receive: func() -> tuple, future>>; /// Get the bound local address. @@ -361,7 +361,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-local-address: func() -> result; /// Get the remote address. @@ -374,13 +374,13 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. @@ -388,7 +388,7 @@ interface types { /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. @@ -400,7 +400,7 @@ interface types { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -412,9 +412,9 @@ interface types { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-keep-alive-enabled: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. @@ -427,9 +427,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-keep-alive-idle-time: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. @@ -442,9 +442,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-keep-alive-interval: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. @@ -457,9 +457,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-keep-alive-count: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -468,9 +468,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -483,18 +483,18 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } /// A UDP socket handle. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) resource udp-socket { /// Create a new UDP socket. @@ -511,7 +511,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. @@ -532,7 +532,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Associate this socket with a specific peer address. @@ -571,7 +571,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) connect: func(remote-address: ip-socket-address) -> result<_, error-code>; /// Dissociate this socket from its peer address. @@ -589,7 +589,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) disconnect: func() -> result<_, error-code>; /// Send a message on the socket to a particular peer. @@ -623,7 +623,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) send: async func(data: list, remote-address: option) -> result<_, error-code>; /// Receive a message on the socket. @@ -649,7 +649,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) receive: async func() -> result, ip-socket-address>, error-code>; /// Get the current bound address. @@ -668,7 +668,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-local-address: func() -> result; /// Get the address the socket is currently "connected" to. @@ -681,7 +681,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. @@ -689,7 +689,7 @@ interface types { /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -698,9 +698,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-unicast-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -713,13 +713,13 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } } diff --git a/proposals/sockets/wit-0.3.0-draft/world.wit b/proposals/sockets/wit-0.3.0-draft/world.wit index 44cc427ed..dfafac2ae 100644 --- a/proposals/sockets/wit-0.3.0-draft/world.wit +++ b/proposals/sockets/wit-0.3.0-draft/world.wit @@ -1,9 +1,9 @@ -package wasi:sockets@0.3.0-rc-2025-09-16; +package wasi:sockets@0.3.0-rc-2025-08-15; -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) import types; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) import ip-name-lookup; } From fdfe834e97fa10630937785904c1572f7e3104c3 Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Tue, 16 Sep 2025 20:09:01 +0200 Subject: [PATCH 1729/1772] Revert "Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16" --- proposals/http/wit-0.3.0-draft/deps.lock | 4 +- .../http/wit-0.3.0-draft/deps/cli/run.wit | 2 +- .../http/wit-0.3.0-draft/deps/cli/stdio.wit | 48 ++----------------- proposals/http/wit-0.3.0-draft/proxy.wit | 12 ++--- proposals/http/wit-0.3.0-draft/types.wit | 2 +- 5 files changed, 13 insertions(+), 55 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/deps.lock b/proposals/http/wit-0.3.0-draft/deps.lock index 9912e0de2..be1b0569e 100644 --- a/proposals/http/wit-0.3.0-draft/deps.lock +++ b/proposals/http/wit-0.3.0-draft/deps.lock @@ -1,8 +1,8 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "5ff03c236a6fed89d2968c3fd5d9e2b3f4fcd7a606dc94ead51df5357bdabe76" -sha512 = "d0277a9b3692de917ef8b1bbe6be9247157d548962dde181b159788064a06513c6f6d775fcca94a3170fe2149ca75d609664938716f4dc877ef65cd7db07eb76" +sha256 = "7f9cf181100ca1cadcb49a1efa3e80828d375df2d5ddf10a8f66e848d423aea5" +sha512 = "569f6b4ed2a3bec913e5e06fd35caab564048cf31632795c2fbdd8c40ddb5f5eea7b1cc59d33c80e5d7b642ed246ba4a3e40d3edeaaa2c6a5c4bcd02e0b67212" deps = ["clocks", "filesystem", "random", "sockets"] [clocks] diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/run.wit b/proposals/http/wit-0.3.0-draft/deps/cli/run.wit index 906b6ae10..6149db760 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/run.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/run.wit @@ -2,5 +2,5 @@ interface run { /// Run the program. @since(version = 0.3.0-rc-2025-08-15) - run: async func() -> result; + run: func() -> result; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit index c1bc8acda..6c99a56f1 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit @@ -1,59 +1,17 @@ -@since(version = 0.3.0-rc-2025-08-15) -interface stdio { - @since(version = 0.3.0-rc-2025-08-15) - enum error-code { - /// Input/output error - io, - /// Invalid or incomplete multibyte or wide character - illegal-byte-sequence, - /// Broken pipe - pipe, - } -} - @since(version = 0.3.0-rc-2025-08-15) interface stdin { - /// Return a stream for reading from stdin. - /// - /// This function returns a stream which provides data read from stdin, - /// and a future to signal read results. - /// - /// If the stream's readable end is dropped the future will resolve to success. - /// - /// If the stream's writable end is dropped the future will either resolve to - /// success if stdin was closed by the writer or to an error-code if reading - /// failed for some other reason. - /// - /// Multiple streams may be active at the same time. The behavior of concurrent - /// reads is implementation-specific. @since(version = 0.3.0-rc-2025-08-15) - read-via-stream: func() -> tuple, future>>; + get-stdin: func() -> stream; } @since(version = 0.3.0-rc-2025-08-15) interface stdout { - /// Write the given stream to stdout. - /// - /// If the stream's writable end is dropped this function will either return - /// success once the entire contents of the stream have been written or an - /// error-code representing a failure. - /// - /// Otherwise if there is an error the readable end of the stream will be - /// dropped and this function will return an error-code. @since(version = 0.3.0-rc-2025-08-15) - write-via-stream: async func(data: stream) -> result<_, error-code>; + set-stdout: func(data: stream); } @since(version = 0.3.0-rc-2025-08-15) interface stderr { - /// Write the given stream to stderr. - /// - /// If the stream's writable end is dropped this function will either return - /// success once the entire contents of the stream have been written or an - /// error-code representing a failure. - /// - /// Otherwise if there is an error the readable end of the stream will be - /// dropped and this function will return an error-code. @since(version = 0.3.0-rc-2025-08-15) - write-via-stream: async func(data: stream) -> result<_, error-code>; + set-stderr: func(data: stream); } diff --git a/proposals/http/wit-0.3.0-draft/proxy.wit b/proposals/http/wit-0.3.0-draft/proxy.wit index 223083ea2..31e5facd0 100644 --- a/proposals/http/wit-0.3.0-draft/proxy.wit +++ b/proposals/http/wit-0.3.0-draft/proxy.wit @@ -1,22 +1,22 @@ -package wasi:http@0.3.0-rc-2025-09-16; +package wasi:http@0.3.0-rc-2025-08-15; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. /// It is intended to be `include`d in other worlds. world imports { /// HTTP proxies have access to time and randomness. - include wasi:clocks/imports@0.3.0-rc-2025-09-16; - import wasi:random/random@0.3.0-rc-2025-09-16; + include wasi:clocks/imports@0.3.0-rc-2025-08-15; + import wasi:random/random@0.3.0-rc-2025-08-15; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.3.0-rc-2025-09-16; - import wasi:cli/stderr@0.3.0-rc-2025-09-16; + import wasi:cli/stdout@0.3.0-rc-2025-08-15; + import wasi:cli/stderr@0.3.0-rc-2025-08-15; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. - import wasi:cli/stdin@0.3.0-rc-2025-09-16; + import wasi:cli/stdin@0.3.0-rc-2025-08-15; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index 8269eea20..d8933cdcc 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -1,7 +1,7 @@ /// This interface defines all of the types and methods for implementing HTTP /// Requests and Responses, as well as their headers, trailers, and bodies. interface types { - use wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16.{duration}; + use wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15.{duration}; /// This type corresponds to HTTP standard Methods. variant method { From 718418c2fe22c9d9e2dd2ee38e2d23105bf2d2ef Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Tue, 16 Sep 2025 20:11:10 +0200 Subject: [PATCH 1730/1772] Revert "Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16" --- .../filesystem/wit-0.3.0-draft/deps.lock | 4 +- .../deps/clocks/monotonic-clock.wit | 13 ++- .../wit-0.3.0-draft/deps/clocks/types.wit | 8 -- .../filesystem/wit-0.3.0-draft/preopens.wit | 8 +- .../filesystem/wit-0.3.0-draft/types.wit | 80 +++++++++---------- .../filesystem/wit-0.3.0-draft/world.wit | 8 +- 6 files changed, 55 insertions(+), 66 deletions(-) delete mode 100644 proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit diff --git a/proposals/filesystem/wit-0.3.0-draft/deps.lock b/proposals/filesystem/wit-0.3.0-draft/deps.lock index 5a3600321..07d589294 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps.lock +++ b/proposals/filesystem/wit-0.3.0-draft/deps.lock @@ -1,5 +1,5 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "d0257e056a4061eaab58a934d84b4b35534d90866667054e886da65c170aeef6" -sha512 = "b033cd0171d9d0c908b17f98f792e47eaeee7534d4bca664c62bdab6f48a8046179e068d4ef11d1e333d3ca44777691b14293eb955e88fda701bdcf90637efae" +sha256 = "626953ec28ae956ec1233c4350deab6e5cdcbdd9ae6d491e102ad7c6901cc8bf" +sha512 = "ae375b002cfaacdbaa133bb87747d1b86675e13144067c3005d6c32cf5c37bb7a52b693ae46d5cd65fc4910a78d7255d0ada5142828a022497fd0eaacb61761f" diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 4464d29ba..0c58241ff 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -9,23 +9,20 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// successive reads of the clock will produce non-decreasing values. @since(version = 0.3.0-rc-2025-08-15) interface monotonic-clock { - use types.{duration}; - /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. @since(version = 0.3.0-rc-2025-08-15) type instant = u64; + /// A duration of time, in nanoseconds. + @since(version = 0.3.0-rc-2025-08-15) + type duration = u64; + /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - /// - /// For completeness, this function traps if it's not possible to represent - /// the value of the clock in an `instant`. Consequently, implementations - /// should ensure that the starting time is low enough to avoid the - /// possibility of overflow in practice. @since(version = 0.3.0-rc-2025-08-15) now: func() -> instant; @@ -40,7 +37,7 @@ interface monotonic-clock { when: instant, ); - /// Wait for the specified duration to elapse. + /// Wait for the specified duration has elapsed. @since(version = 0.3.0-rc-2025-08-15) wait-for: async func( how-long: duration, diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit deleted file mode 100644 index 4736b896e..000000000 --- a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit +++ /dev/null @@ -1,8 +0,0 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; -/// This interface common types used throughout wasi:clocks. -@since(version = 0.3.0-rc-2025-08-15) -interface types { - /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) - type duration = u64; -} diff --git a/proposals/filesystem/wit-0.3.0-draft/preopens.wit b/proposals/filesystem/wit-0.3.0-draft/preopens.wit index 9036e90e8..b0f609aa9 100644 --- a/proposals/filesystem/wit-0.3.0-draft/preopens.wit +++ b/proposals/filesystem/wit-0.3.0-draft/preopens.wit @@ -1,11 +1,11 @@ -package wasi:filesystem@0.3.0-rc-2025-09-16; +package wasi:filesystem@0.3.0-rc-2025-08-15; -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-08-15) interface preopens { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) use types.{descriptor}; /// Return the set of preopened directories, and their paths. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-directories: func() -> list>; } diff --git a/proposals/filesystem/wit-0.3.0-draft/types.wit b/proposals/filesystem/wit-0.3.0-draft/types.wit index 41d91beee..07d770a83 100644 --- a/proposals/filesystem/wit-0.3.0-draft/types.wit +++ b/proposals/filesystem/wit-0.3.0-draft/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.3.0-rc-2025-09-16; +package wasi:filesystem@0.3.0-rc-2025-08-15; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -23,19 +23,19 @@ package wasi:filesystem@0.3.0-rc-2025-09-16; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-08-15) interface types { - @since(version = 0.3.0-rc-2025-09-16) - use wasi:clocks/wall-clock@0.3.0-rc-2025-09-16.{datetime}; + @since(version = 0.3.0-rc-2025-08-15) + use wasi:clocks/wall-clock@0.3.0-rc-2025-08-15.{datetime}; /// File size or length of a region within a file. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -59,7 +59,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -103,7 +103,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) record descriptor-stat { /// File type. %type: descriptor-type, @@ -130,7 +130,7 @@ interface types { } /// Flags determining the method of how paths are resolved. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -138,7 +138,7 @@ interface types { } /// Open flags used by `open-at`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -151,11 +151,11 @@ interface types { } /// Number of hard links to an inode. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -255,7 +255,7 @@ interface types { } /// File or memory access pattern advisory information. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -279,7 +279,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -290,7 +290,7 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) resource descriptor { /// Return a stream for reading from a file. /// @@ -308,7 +308,7 @@ interface types { /// resolves to `err` with an `error-code`. /// /// Note: This is similar to `pread` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, @@ -326,7 +326,7 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `pwrite` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) write-via-stream: async func( /// Data to write data: stream, @@ -342,13 +342,13 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `write` with `O_APPEND` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) append-via-stream: async func(data: stream) -> result<_, error-code>; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) advise: async func( /// The offset within the file to which the advisory applies. offset: filesize, @@ -364,7 +364,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) sync-data: async func() -> result<_, error-code>; /// Get flags associated with a descriptor. @@ -373,7 +373,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-flags: async func() -> result; /// Get the dynamic type of a descriptor. @@ -386,14 +386,14 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-type: async func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-size: async func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. @@ -401,7 +401,7 @@ interface types { /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-times: async func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, @@ -421,7 +421,7 @@ interface types { /// /// This function returns a future, which will resolve to an error code if /// reading full contents of the directory fails. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) read-directory: async func() -> tuple, future>>; /// Synchronize the data and metadata of a file to disk. @@ -430,13 +430,13 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) sync: async func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) create-directory-at: async func( /// The relative path at which to create the directory. path: string, @@ -451,7 +451,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) stat: async func() -> result; /// Return the attributes of a file or directory. @@ -461,7 +461,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) stat-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -475,7 +475,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-times-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -494,7 +494,7 @@ interface types { /// `error-code::not-permitted` if the old path is not a file. /// /// Note: This is similar to `linkat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) link-at: async func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, @@ -518,7 +518,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) open-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -536,7 +536,7 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) readlink-at: async func( /// The relative path of the symbolic link from which to read. path: string, @@ -547,7 +547,7 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) remove-directory-at: async func( /// The relative path to a directory to remove. path: string, @@ -556,7 +556,7 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) rename-at: async func( /// The relative source path of the file or directory to rename. old-path: string, @@ -572,7 +572,7 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) symlink-at: async func( /// The contents of the symbolic link. old-path: string, @@ -584,7 +584,7 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) unlink-file-at: async func( /// The relative path to a file to unlink. path: string, @@ -596,7 +596,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) is-same-object: async func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred @@ -618,14 +618,14 @@ interface types { /// computed hash. /// /// However, none of these is required. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) metadata-hash: async func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) metadata-hash-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, diff --git a/proposals/filesystem/wit-0.3.0-draft/world.wit b/proposals/filesystem/wit-0.3.0-draft/world.wit index 87fc72716..b9dcfd562 100644 --- a/proposals/filesystem/wit-0.3.0-draft/world.wit +++ b/proposals/filesystem/wit-0.3.0-draft/world.wit @@ -1,9 +1,9 @@ -package wasi:filesystem@0.3.0-rc-2025-09-16; +package wasi:filesystem@0.3.0-rc-2025-08-15; -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) import types; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) import preopens; } From dcdadcf23b46b95801251af89b8c004da6a76217 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 18:21:31 +0000 Subject: [PATCH 1731/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16-1 --- proposals/random/wit-0.3.0-draft/insecure-seed.wit | 6 +++--- proposals/random/wit-0.3.0-draft/insecure.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/random.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/world.wit | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/proposals/random/wit-0.3.0-draft/insecure-seed.wit b/proposals/random/wit-0.3.0-draft/insecure-seed.wit index ecd504318..155a88fbf 100644 --- a/proposals/random/wit-0.3.0-draft/insecure-seed.wit +++ b/proposals/random/wit-0.3.0-draft/insecure-seed.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16-1; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16-1) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) get-insecure-seed: func() -> tuple; } diff --git a/proposals/random/wit-0.3.0-draft/insecure.wit b/proposals/random/wit-0.3.0-draft/insecure.wit index d08d85e0b..2b190a4a1 100644 --- a/proposals/random/wit-0.3.0-draft/insecure.wit +++ b/proposals/random/wit-0.3.0-draft/insecure.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16-1; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16-1) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/random.wit b/proposals/random/wit-0.3.0-draft/random.wit index 3808c3095..620d82cb8 100644 --- a/proposals/random/wit-0.3.0-draft/random.wit +++ b/proposals/random/wit-0.3.0-draft/random.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16-1; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16-1) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) get-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/world.wit b/proposals/random/wit-0.3.0-draft/world.wit index e8f05cc43..e7ce9713f 100644 --- a/proposals/random/wit-0.3.0-draft/world.wit +++ b/proposals/random/wit-0.3.0-draft/world.wit @@ -1,13 +1,13 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16-1; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16-1) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) import random; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) import insecure; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) import insecure-seed; } From 377abcd0aac562655b8275a61ca65f9c19183835 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 19:37:48 +0000 Subject: [PATCH 1732/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16 --- .../filesystem/wit-0.3.0-draft/deps.lock | 4 +- .../deps/clocks/monotonic-clock.wit | 13 +-- .../wit-0.3.0-draft/deps/clocks/types.wit | 8 ++ .../filesystem/wit-0.3.0-draft/preopens.wit | 8 +- .../filesystem/wit-0.3.0-draft/types.wit | 80 +++++++++---------- .../filesystem/wit-0.3.0-draft/world.wit | 8 +- 6 files changed, 66 insertions(+), 55 deletions(-) create mode 100644 proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit diff --git a/proposals/filesystem/wit-0.3.0-draft/deps.lock b/proposals/filesystem/wit-0.3.0-draft/deps.lock index 07d589294..5a3600321 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps.lock +++ b/proposals/filesystem/wit-0.3.0-draft/deps.lock @@ -1,5 +1,5 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "626953ec28ae956ec1233c4350deab6e5cdcbdd9ae6d491e102ad7c6901cc8bf" -sha512 = "ae375b002cfaacdbaa133bb87747d1b86675e13144067c3005d6c32cf5c37bb7a52b693ae46d5cd65fc4910a78d7255d0ada5142828a022497fd0eaacb61761f" +sha256 = "d0257e056a4061eaab58a934d84b4b35534d90866667054e886da65c170aeef6" +sha512 = "b033cd0171d9d0c908b17f98f792e47eaeee7534d4bca664c62bdab6f48a8046179e068d4ef11d1e333d3ca44777691b14293eb955e88fda701bdcf90637efae" diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 0c58241ff..4464d29ba 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -9,20 +9,23 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// successive reads of the clock will produce non-decreasing values. @since(version = 0.3.0-rc-2025-08-15) interface monotonic-clock { + use types.{duration}; + /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. @since(version = 0.3.0-rc-2025-08-15) type instant = u64; - /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) - type duration = u64; - /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + /// + /// For completeness, this function traps if it's not possible to represent + /// the value of the clock in an `instant`. Consequently, implementations + /// should ensure that the starting time is low enough to avoid the + /// possibility of overflow in practice. @since(version = 0.3.0-rc-2025-08-15) now: func() -> instant; @@ -37,7 +40,7 @@ interface monotonic-clock { when: instant, ); - /// Wait for the specified duration has elapsed. + /// Wait for the specified duration to elapse. @since(version = 0.3.0-rc-2025-08-15) wait-for: async func( how-long: duration, diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit new file mode 100644 index 000000000..4736b896e --- /dev/null +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit @@ -0,0 +1,8 @@ +package wasi:clocks@0.3.0-rc-2025-08-15; +/// This interface common types used throughout wasi:clocks. +@since(version = 0.3.0-rc-2025-08-15) +interface types { + /// A duration of time, in nanoseconds. + @since(version = 0.3.0-rc-2025-08-15) + type duration = u64; +} diff --git a/proposals/filesystem/wit-0.3.0-draft/preopens.wit b/proposals/filesystem/wit-0.3.0-draft/preopens.wit index b0f609aa9..9036e90e8 100644 --- a/proposals/filesystem/wit-0.3.0-draft/preopens.wit +++ b/proposals/filesystem/wit-0.3.0-draft/preopens.wit @@ -1,11 +1,11 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface preopens { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use types.{descriptor}; /// Return the set of preopened directories, and their paths. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-directories: func() -> list>; } diff --git a/proposals/filesystem/wit-0.3.0-draft/types.wit b/proposals/filesystem/wit-0.3.0-draft/types.wit index 07d770a83..41d91beee 100644 --- a/proposals/filesystem/wit-0.3.0-draft/types.wit +++ b/proposals/filesystem/wit-0.3.0-draft/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -23,19 +23,19 @@ package wasi:filesystem@0.3.0-rc-2025-08-15; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface types { - @since(version = 0.3.0-rc-2025-08-15) - use wasi:clocks/wall-clock@0.3.0-rc-2025-08-15.{datetime}; + @since(version = 0.3.0-rc-2025-09-16) + use wasi:clocks/wall-clock@0.3.0-rc-2025-09-16.{datetime}; /// File size or length of a region within a file. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -59,7 +59,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -103,7 +103,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record descriptor-stat { /// File type. %type: descriptor-type, @@ -130,7 +130,7 @@ interface types { } /// Flags determining the method of how paths are resolved. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -138,7 +138,7 @@ interface types { } /// Open flags used by `open-at`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -151,11 +151,11 @@ interface types { } /// Number of hard links to an inode. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -255,7 +255,7 @@ interface types { } /// File or memory access pattern advisory information. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -279,7 +279,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -290,7 +290,7 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource descriptor { /// Return a stream for reading from a file. /// @@ -308,7 +308,7 @@ interface types { /// resolves to `err` with an `error-code`. /// /// Note: This is similar to `pread` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, @@ -326,7 +326,7 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `pwrite` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) write-via-stream: async func( /// Data to write data: stream, @@ -342,13 +342,13 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `write` with `O_APPEND` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) append-via-stream: async func(data: stream) -> result<_, error-code>; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) advise: async func( /// The offset within the file to which the advisory applies. offset: filesize, @@ -364,7 +364,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) sync-data: async func() -> result<_, error-code>; /// Get flags associated with a descriptor. @@ -373,7 +373,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-flags: async func() -> result; /// Get the dynamic type of a descriptor. @@ -386,14 +386,14 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-type: async func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-size: async func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. @@ -401,7 +401,7 @@ interface types { /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-times: async func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, @@ -421,7 +421,7 @@ interface types { /// /// This function returns a future, which will resolve to an error code if /// reading full contents of the directory fails. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) read-directory: async func() -> tuple, future>>; /// Synchronize the data and metadata of a file to disk. @@ -430,13 +430,13 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) sync: async func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) create-directory-at: async func( /// The relative path at which to create the directory. path: string, @@ -451,7 +451,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) stat: async func() -> result; /// Return the attributes of a file or directory. @@ -461,7 +461,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) stat-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -475,7 +475,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-times-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -494,7 +494,7 @@ interface types { /// `error-code::not-permitted` if the old path is not a file. /// /// Note: This is similar to `linkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) link-at: async func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, @@ -518,7 +518,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) open-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -536,7 +536,7 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) readlink-at: async func( /// The relative path of the symbolic link from which to read. path: string, @@ -547,7 +547,7 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) remove-directory-at: async func( /// The relative path to a directory to remove. path: string, @@ -556,7 +556,7 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) rename-at: async func( /// The relative source path of the file or directory to rename. old-path: string, @@ -572,7 +572,7 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) symlink-at: async func( /// The contents of the symbolic link. old-path: string, @@ -584,7 +584,7 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) unlink-file-at: async func( /// The relative path to a file to unlink. path: string, @@ -596,7 +596,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) is-same-object: async func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred @@ -618,14 +618,14 @@ interface types { /// computed hash. /// /// However, none of these is required. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) metadata-hash: async func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) metadata-hash-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, diff --git a/proposals/filesystem/wit-0.3.0-draft/world.wit b/proposals/filesystem/wit-0.3.0-draft/world.wit index b9dcfd562..87fc72716 100644 --- a/proposals/filesystem/wit-0.3.0-draft/world.wit +++ b/proposals/filesystem/wit-0.3.0-draft/world.wit @@ -1,9 +1,9 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import types; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import preopens; } From 4458fd47381e6350998119f65bd68eb61c8d4771 Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Tue, 16 Sep 2025 22:10:17 +0200 Subject: [PATCH 1733/1772] fix ci (#102) --- proposals/clocks/imports.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index a7ec83703..0f74163d8 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -88,6 +88,10 @@ the same monotonic-clock.

                              Read the current value of the clock.

                              The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

                              +

                              For completeness, this function traps if it's not possible to represent +the value of the clock in an instant. Consequently, implementations +should ensure that the starting time is low enough to avoid the +possibility of overflow in practice.

                              Return values
                              • instant
                              • From e59053976fb77f0e5e6a58ae40aabe47e755c999 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 22:23:58 +0200 Subject: [PATCH 1734/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16 (#103) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../clocks/wit-0.3.0-draft/monotonic-clock.wit | 14 +++++++------- proposals/clocks/wit-0.3.0-draft/timezone.wit | 2 +- proposals/clocks/wit-0.3.0-draft/types.wit | 6 +++--- proposals/clocks/wit-0.3.0-draft/wall-clock.wit | 10 +++++----- proposals/clocks/wit-0.3.0-draft/world.wit | 8 ++++---- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit index 4464d29ba..a91d495c6 100644 --- a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit +++ b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,14 +7,14 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface monotonic-clock { use types.{duration}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type instant = u64; /// Read the current value of the clock. @@ -26,22 +26,22 @@ interface monotonic-clock { /// the value of the clock in an `instant`. Consequently, implementations /// should ensure that the starting time is low enough to avoid the /// possibility of overflow in practice. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-resolution: func() -> duration; /// Wait until the specified instant has occurred. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) wait-until: async func( when: instant, ); /// Wait for the specified duration to elapse. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) wait-for: async func( how-long: duration, ); diff --git a/proposals/clocks/wit-0.3.0-draft/timezone.wit b/proposals/clocks/wit-0.3.0-draft/timezone.wit index 2ee16ab20..ab8f5c080 100644 --- a/proposals/clocks/wit-0.3.0-draft/timezone.wit +++ b/proposals/clocks/wit-0.3.0-draft/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/clocks/wit-0.3.0-draft/types.wit b/proposals/clocks/wit-0.3.0-draft/types.wit index 4736b896e..aff7c2a22 100644 --- a/proposals/clocks/wit-0.3.0-draft/types.wit +++ b/proposals/clocks/wit-0.3.0-draft/types.wit @@ -1,8 +1,8 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; /// This interface common types used throughout wasi:clocks. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface types { /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type duration = u64; } diff --git a/proposals/clocks/wit-0.3.0-draft/wall-clock.wit b/proposals/clocks/wit-0.3.0-draft/wall-clock.wit index 2e3b2d441..ea940500f 100644 --- a/proposals/clocks/wit-0.3.0-draft/wall-clock.wit +++ b/proposals/clocks/wit-0.3.0-draft/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,10 +13,10 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface wall-clock { /// A time and date in seconds plus nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record datetime { seconds: u64, nanoseconds: u32, @@ -35,12 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-resolution: func() -> datetime; } diff --git a/proposals/clocks/wit-0.3.0-draft/world.wit b/proposals/clocks/wit-0.3.0-draft/world.wit index 94068c75c..a6b885f07 100644 --- a/proposals/clocks/wit-0.3.0-draft/world.wit +++ b/proposals/clocks/wit-0.3.0-draft/world.wit @@ -1,10 +1,10 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import monotonic-clock; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import wall-clock; @unstable(feature = clocks-timezone) import timezone; From 9ba65ff9058000df4a040f9b95c66504d898db3c Mon Sep 17 00:00:00 2001 From: Yosh <2467194+yoshuawuyts@users.noreply.github.com> Date: Tue, 16 Sep 2025 22:29:54 +0200 Subject: [PATCH 1735/1772] Revert "Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16" --- .../filesystem/wit-0.3.0-draft/deps.lock | 4 +- .../deps/clocks/monotonic-clock.wit | 13 ++- .../wit-0.3.0-draft/deps/clocks/types.wit | 8 -- .../filesystem/wit-0.3.0-draft/preopens.wit | 8 +- .../filesystem/wit-0.3.0-draft/types.wit | 80 +++++++++---------- .../filesystem/wit-0.3.0-draft/world.wit | 8 +- 6 files changed, 55 insertions(+), 66 deletions(-) delete mode 100644 proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit diff --git a/proposals/filesystem/wit-0.3.0-draft/deps.lock b/proposals/filesystem/wit-0.3.0-draft/deps.lock index 5a3600321..07d589294 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps.lock +++ b/proposals/filesystem/wit-0.3.0-draft/deps.lock @@ -1,5 +1,5 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "d0257e056a4061eaab58a934d84b4b35534d90866667054e886da65c170aeef6" -sha512 = "b033cd0171d9d0c908b17f98f792e47eaeee7534d4bca664c62bdab6f48a8046179e068d4ef11d1e333d3ca44777691b14293eb955e88fda701bdcf90637efae" +sha256 = "626953ec28ae956ec1233c4350deab6e5cdcbdd9ae6d491e102ad7c6901cc8bf" +sha512 = "ae375b002cfaacdbaa133bb87747d1b86675e13144067c3005d6c32cf5c37bb7a52b693ae46d5cd65fc4910a78d7255d0ada5142828a022497fd0eaacb61761f" diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 4464d29ba..0c58241ff 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -9,23 +9,20 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// successive reads of the clock will produce non-decreasing values. @since(version = 0.3.0-rc-2025-08-15) interface monotonic-clock { - use types.{duration}; - /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. @since(version = 0.3.0-rc-2025-08-15) type instant = u64; + /// A duration of time, in nanoseconds. + @since(version = 0.3.0-rc-2025-08-15) + type duration = u64; + /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - /// - /// For completeness, this function traps if it's not possible to represent - /// the value of the clock in an `instant`. Consequently, implementations - /// should ensure that the starting time is low enough to avoid the - /// possibility of overflow in practice. @since(version = 0.3.0-rc-2025-08-15) now: func() -> instant; @@ -40,7 +37,7 @@ interface monotonic-clock { when: instant, ); - /// Wait for the specified duration to elapse. + /// Wait for the specified duration has elapsed. @since(version = 0.3.0-rc-2025-08-15) wait-for: async func( how-long: duration, diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit deleted file mode 100644 index 4736b896e..000000000 --- a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit +++ /dev/null @@ -1,8 +0,0 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; -/// This interface common types used throughout wasi:clocks. -@since(version = 0.3.0-rc-2025-08-15) -interface types { - /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) - type duration = u64; -} diff --git a/proposals/filesystem/wit-0.3.0-draft/preopens.wit b/proposals/filesystem/wit-0.3.0-draft/preopens.wit index 9036e90e8..b0f609aa9 100644 --- a/proposals/filesystem/wit-0.3.0-draft/preopens.wit +++ b/proposals/filesystem/wit-0.3.0-draft/preopens.wit @@ -1,11 +1,11 @@ -package wasi:filesystem@0.3.0-rc-2025-09-16; +package wasi:filesystem@0.3.0-rc-2025-08-15; -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-08-15) interface preopens { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) use types.{descriptor}; /// Return the set of preopened directories, and their paths. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-directories: func() -> list>; } diff --git a/proposals/filesystem/wit-0.3.0-draft/types.wit b/proposals/filesystem/wit-0.3.0-draft/types.wit index 41d91beee..07d770a83 100644 --- a/proposals/filesystem/wit-0.3.0-draft/types.wit +++ b/proposals/filesystem/wit-0.3.0-draft/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.3.0-rc-2025-09-16; +package wasi:filesystem@0.3.0-rc-2025-08-15; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -23,19 +23,19 @@ package wasi:filesystem@0.3.0-rc-2025-09-16; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-08-15) interface types { - @since(version = 0.3.0-rc-2025-09-16) - use wasi:clocks/wall-clock@0.3.0-rc-2025-09-16.{datetime}; + @since(version = 0.3.0-rc-2025-08-15) + use wasi:clocks/wall-clock@0.3.0-rc-2025-08-15.{datetime}; /// File size or length of a region within a file. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -59,7 +59,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -103,7 +103,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) record descriptor-stat { /// File type. %type: descriptor-type, @@ -130,7 +130,7 @@ interface types { } /// Flags determining the method of how paths are resolved. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -138,7 +138,7 @@ interface types { } /// Open flags used by `open-at`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -151,11 +151,11 @@ interface types { } /// Number of hard links to an inode. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -255,7 +255,7 @@ interface types { } /// File or memory access pattern advisory information. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -279,7 +279,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -290,7 +290,7 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) resource descriptor { /// Return a stream for reading from a file. /// @@ -308,7 +308,7 @@ interface types { /// resolves to `err` with an `error-code`. /// /// Note: This is similar to `pread` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, @@ -326,7 +326,7 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `pwrite` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) write-via-stream: async func( /// Data to write data: stream, @@ -342,13 +342,13 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `write` with `O_APPEND` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) append-via-stream: async func(data: stream) -> result<_, error-code>; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) advise: async func( /// The offset within the file to which the advisory applies. offset: filesize, @@ -364,7 +364,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) sync-data: async func() -> result<_, error-code>; /// Get flags associated with a descriptor. @@ -373,7 +373,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-flags: async func() -> result; /// Get the dynamic type of a descriptor. @@ -386,14 +386,14 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) get-type: async func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-size: async func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. @@ -401,7 +401,7 @@ interface types { /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-times: async func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, @@ -421,7 +421,7 @@ interface types { /// /// This function returns a future, which will resolve to an error code if /// reading full contents of the directory fails. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) read-directory: async func() -> tuple, future>>; /// Synchronize the data and metadata of a file to disk. @@ -430,13 +430,13 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) sync: async func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) create-directory-at: async func( /// The relative path at which to create the directory. path: string, @@ -451,7 +451,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) stat: async func() -> result; /// Return the attributes of a file or directory. @@ -461,7 +461,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) stat-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -475,7 +475,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) set-times-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -494,7 +494,7 @@ interface types { /// `error-code::not-permitted` if the old path is not a file. /// /// Note: This is similar to `linkat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) link-at: async func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, @@ -518,7 +518,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) open-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -536,7 +536,7 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) readlink-at: async func( /// The relative path of the symbolic link from which to read. path: string, @@ -547,7 +547,7 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) remove-directory-at: async func( /// The relative path to a directory to remove. path: string, @@ -556,7 +556,7 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) rename-at: async func( /// The relative source path of the file or directory to rename. old-path: string, @@ -572,7 +572,7 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) symlink-at: async func( /// The contents of the symbolic link. old-path: string, @@ -584,7 +584,7 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) unlink-file-at: async func( /// The relative path to a file to unlink. path: string, @@ -596,7 +596,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) is-same-object: async func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred @@ -618,14 +618,14 @@ interface types { /// computed hash. /// /// However, none of these is required. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) metadata-hash: async func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) metadata-hash-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, diff --git a/proposals/filesystem/wit-0.3.0-draft/world.wit b/proposals/filesystem/wit-0.3.0-draft/world.wit index 87fc72716..b9dcfd562 100644 --- a/proposals/filesystem/wit-0.3.0-draft/world.wit +++ b/proposals/filesystem/wit-0.3.0-draft/world.wit @@ -1,9 +1,9 @@ -package wasi:filesystem@0.3.0-rc-2025-09-16; +package wasi:filesystem@0.3.0-rc-2025-08-15; -@since(version = 0.3.0-rc-2025-09-16) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) import types; - @since(version = 0.3.0-rc-2025-09-16) + @since(version = 0.3.0-rc-2025-08-15) import preopens; } From b42d96639465d8fce02b11aefe6115d660876864 Mon Sep 17 00:00:00 2001 From: Lann Martin Date: Tue, 16 Sep 2025 16:45:38 -0400 Subject: [PATCH 1736/1772] stdio: Fix error-code references --- proposals/cli/wit-0.3.0-draft/stdio.wit | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/proposals/cli/wit-0.3.0-draft/stdio.wit b/proposals/cli/wit-0.3.0-draft/stdio.wit index c1bc8acda..5536cee51 100644 --- a/proposals/cli/wit-0.3.0-draft/stdio.wit +++ b/proposals/cli/wit-0.3.0-draft/stdio.wit @@ -1,5 +1,5 @@ @since(version = 0.3.0-rc-2025-08-15) -interface stdio { +interface types { @since(version = 0.3.0-rc-2025-08-15) enum error-code { /// Input/output error @@ -13,6 +13,8 @@ interface stdio { @since(version = 0.3.0-rc-2025-08-15) interface stdin { + use types.{error-code}; + /// Return a stream for reading from stdin. /// /// This function returns a stream which provides data read from stdin, @@ -32,6 +34,8 @@ interface stdin { @since(version = 0.3.0-rc-2025-08-15) interface stdout { + use types.{error-code}; + /// Write the given stream to stdout. /// /// If the stream's writable end is dropped this function will either return @@ -46,6 +50,8 @@ interface stdout { @since(version = 0.3.0-rc-2025-08-15) interface stderr { + use types.{error-code}; + /// Write the given stream to stderr. /// /// If the stream's writable end is dropped this function will either return From f367c465d5032e5fe9c6b960ae2c0a81a50da4e5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 20:50:48 +0000 Subject: [PATCH 1737/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16 --- proposals/cli/wit-0.3.0-draft/command.wit | 8 ++-- proposals/cli/wit-0.3.0-draft/deps.lock | 4 +- .../deps/random/insecure-seed.wit | 6 +-- .../wit-0.3.0-draft/deps/random/insecure.wit | 8 ++-- .../wit-0.3.0-draft/deps/random/random.wit | 8 ++-- .../cli/wit-0.3.0-draft/deps/random/world.wit | 10 ++--- proposals/cli/wit-0.3.0-draft/environment.wit | 8 ++-- proposals/cli/wit-0.3.0-draft/exit.wit | 4 +- proposals/cli/wit-0.3.0-draft/imports.wit | 40 +++++++++---------- proposals/cli/wit-0.3.0-draft/run.wit | 4 +- proposals/cli/wit-0.3.0-draft/stdio.wit | 16 ++++---- proposals/cli/wit-0.3.0-draft/terminal.wit | 26 ++++++------ 12 files changed, 71 insertions(+), 71 deletions(-) diff --git a/proposals/cli/wit-0.3.0-draft/command.wit b/proposals/cli/wit-0.3.0-draft/command.wit index 13e92bdec..f2f613e55 100644 --- a/proposals/cli/wit-0.3.0-draft/command.wit +++ b/proposals/cli/wit-0.3.0-draft/command.wit @@ -1,10 +1,10 @@ -package wasi:cli@0.3.0-rc-2025-08-15; +package wasi:cli@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world command { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) include imports; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) export run; } diff --git a/proposals/cli/wit-0.3.0-draft/deps.lock b/proposals/cli/wit-0.3.0-draft/deps.lock index 97759f336..d31343695 100644 --- a/proposals/cli/wit-0.3.0-draft/deps.lock +++ b/proposals/cli/wit-0.3.0-draft/deps.lock @@ -12,8 +12,8 @@ deps = ["clocks"] [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "fcc4d3b51564274bb05ebd7cad65ff036eed5c1ac1316639e0c04aa0d64fc938" -sha512 = "d3b10e7791fc354730551f8e21beff96bdbf16f96ef655cd0ac7e0489a9e28c4a7a602d50b199de4a27981643bdbea7ec075cfa80ca351aea6ae74ea660b0568" +sha256 = "45a5fa540deaf386de72bcf53c4462901919532e6dc1a80226c117a0d6e7c5e5" +sha512 = "984b48f604992236530c190b00de9feba45f908b83a0dad31b6a1c117b6146bdfc838f4669d23763604a464bc6b980e35c07943e1bc22305e94a87c6acc51e5a" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit b/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit index ecd504318..155a88fbf 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16-1; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16-1) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) get-insecure-seed: func() -> tuple; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit b/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit index d08d85e0b..2b190a4a1 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16-1; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16-1) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/random.wit b/proposals/cli/wit-0.3.0-draft/deps/random/random.wit index 3808c3095..620d82cb8 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/random/random.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/random/random.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16-1; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16-1) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) get-random-u64: func() -> u64; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/world.wit b/proposals/cli/wit-0.3.0-draft/deps/random/world.wit index e8f05cc43..e7ce9713f 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/random/world.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/random/world.wit @@ -1,13 +1,13 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16-1; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16-1) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) import random; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) import insecure; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16-1) import insecure-seed; } diff --git a/proposals/cli/wit-0.3.0-draft/environment.wit b/proposals/cli/wit-0.3.0-draft/environment.wit index 769858af1..3763f2f6c 100644 --- a/proposals/cli/wit-0.3.0-draft/environment.wit +++ b/proposals/cli/wit-0.3.0-draft/environment.wit @@ -1,4 +1,4 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface environment { /// Get the POSIX-style environment variables. /// @@ -8,15 +8,15 @@ interface environment { /// Morally, these are a value import, but until value imports are available /// in the component model, this import function should return the same /// values each time it is called. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-environment: func() -> list>; /// Get the POSIX-style arguments to the program. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-arguments: func() -> list; /// Return a path that programs should use as their initial current working /// directory, interpreting `.` as shorthand for this. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-initial-cwd: func() -> option; } diff --git a/proposals/cli/wit-0.3.0-draft/exit.wit b/proposals/cli/wit-0.3.0-draft/exit.wit index dcf791a20..1efba7d68 100644 --- a/proposals/cli/wit-0.3.0-draft/exit.wit +++ b/proposals/cli/wit-0.3.0-draft/exit.wit @@ -1,7 +1,7 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface exit { /// Exit the current instance and any linked instances. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) exit: func(status: result); /// Exit the current instance and any linked instances, reporting the diff --git a/proposals/cli/wit-0.3.0-draft/imports.wit b/proposals/cli/wit-0.3.0-draft/imports.wit index 2d513ead9..660a2dd95 100644 --- a/proposals/cli/wit-0.3.0-draft/imports.wit +++ b/proposals/cli/wit-0.3.0-draft/imports.wit @@ -1,34 +1,34 @@ -package wasi:cli@0.3.0-rc-2025-08-15; +package wasi:cli@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) - include wasi:clocks/imports@0.3.0-rc-2025-08-15; - @since(version = 0.3.0-rc-2025-08-15) - include wasi:filesystem/imports@0.3.0-rc-2025-08-15; - @since(version = 0.3.0-rc-2025-08-15) - include wasi:sockets/imports@0.3.0-rc-2025-08-15; - @since(version = 0.3.0-rc-2025-08-15) - include wasi:random/imports@0.3.0-rc-2025-08-15; + @since(version = 0.3.0-rc-2025-09-16) + include wasi:clocks/imports@0.3.0-rc-2025-09-16; + @since(version = 0.3.0-rc-2025-09-16) + include wasi:filesystem/imports@0.3.0-rc-2025-09-16; + @since(version = 0.3.0-rc-2025-09-16) + include wasi:sockets/imports@0.3.0-rc-2025-09-16; + @since(version = 0.3.0-rc-2025-09-16) + include wasi:random/imports@0.3.0-rc-2025-09-16; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import environment; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import exit; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import stdin; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import stdout; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import stderr; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import terminal-input; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import terminal-output; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import terminal-stdin; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import terminal-stdout; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import terminal-stderr; } diff --git a/proposals/cli/wit-0.3.0-draft/run.wit b/proposals/cli/wit-0.3.0-draft/run.wit index 906b6ae10..631441a3f 100644 --- a/proposals/cli/wit-0.3.0-draft/run.wit +++ b/proposals/cli/wit-0.3.0-draft/run.wit @@ -1,6 +1,6 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface run { /// Run the program. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) run: async func() -> result; } diff --git a/proposals/cli/wit-0.3.0-draft/stdio.wit b/proposals/cli/wit-0.3.0-draft/stdio.wit index 5536cee51..51e5ae4b4 100644 --- a/proposals/cli/wit-0.3.0-draft/stdio.wit +++ b/proposals/cli/wit-0.3.0-draft/stdio.wit @@ -1,6 +1,6 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface types { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum error-code { /// Input/output error io, @@ -11,7 +11,7 @@ interface types { } } -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface stdin { use types.{error-code}; @@ -28,11 +28,11 @@ interface stdin { /// /// Multiple streams may be active at the same time. The behavior of concurrent /// reads is implementation-specific. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) read-via-stream: func() -> tuple, future>>; } -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface stdout { use types.{error-code}; @@ -44,11 +44,11 @@ interface stdout { /// /// Otherwise if there is an error the readable end of the stream will be /// dropped and this function will return an error-code. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) write-via-stream: async func(data: stream) -> result<_, error-code>; } -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface stderr { use types.{error-code}; @@ -60,6 +60,6 @@ interface stderr { /// /// Otherwise if there is an error the readable end of the stream will be /// dropped and this function will return an error-code. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) write-via-stream: async func(data: stream) -> result<_, error-code>; } diff --git a/proposals/cli/wit-0.3.0-draft/terminal.wit b/proposals/cli/wit-0.3.0-draft/terminal.wit index 3b2b72bba..74c17694a 100644 --- a/proposals/cli/wit-0.3.0-draft/terminal.wit +++ b/proposals/cli/wit-0.3.0-draft/terminal.wit @@ -3,10 +3,10 @@ /// In the future, this may include functions for disabling echoing, /// disabling input buffering so that keyboard events are sent through /// immediately, querying supported features, and so on. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface terminal-input { /// The input side of a terminal. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource terminal-input; } @@ -15,48 +15,48 @@ interface terminal-input { /// In the future, this may include functions for querying the terminal /// size, being notified of terminal size changes, querying supported /// features, and so on. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface terminal-output { /// The output side of a terminal. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource terminal-output; } /// An interface providing an optional `terminal-input` for stdin as a /// link-time authority. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface terminal-stdin { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use terminal-input.{terminal-input}; /// If stdin is connected to a terminal, return a `terminal-input` handle /// allowing further interaction with it. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-terminal-stdin: func() -> option; } /// An interface providing an optional `terminal-output` for stdout as a /// link-time authority. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface terminal-stdout { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use terminal-output.{terminal-output}; /// If stdout is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-terminal-stdout: func() -> option; } /// An interface providing an optional `terminal-output` for stderr as a /// link-time authority. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface terminal-stderr { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use terminal-output.{terminal-output}; /// If stderr is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-terminal-stderr: func() -> option; } From 07b94ebce9f28929ffc2be5968866e8410b3b8f9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 21:25:07 +0000 Subject: [PATCH 1738/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16 --- .../filesystem/wit-0.3.0-draft/deps.lock | 4 +- .../deps/clocks/monotonic-clock.wit | 27 ++++--- .../wit-0.3.0-draft/deps/clocks/timezone.wit | 2 +- .../wit-0.3.0-draft/deps/clocks/types.wit | 8 ++ .../deps/clocks/wall-clock.wit | 10 +-- .../wit-0.3.0-draft/deps/clocks/world.wit | 8 +- .../filesystem/wit-0.3.0-draft/preopens.wit | 8 +- .../filesystem/wit-0.3.0-draft/types.wit | 80 +++++++++---------- .../filesystem/wit-0.3.0-draft/world.wit | 8 +- 9 files changed, 83 insertions(+), 72 deletions(-) create mode 100644 proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit diff --git a/proposals/filesystem/wit-0.3.0-draft/deps.lock b/proposals/filesystem/wit-0.3.0-draft/deps.lock index 07d589294..4f3b1fe94 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps.lock +++ b/proposals/filesystem/wit-0.3.0-draft/deps.lock @@ -1,5 +1,5 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "626953ec28ae956ec1233c4350deab6e5cdcbdd9ae6d491e102ad7c6901cc8bf" -sha512 = "ae375b002cfaacdbaa133bb87747d1b86675e13144067c3005d6c32cf5c37bb7a52b693ae46d5cd65fc4910a78d7255d0ada5142828a022497fd0eaacb61761f" +sha256 = "cf61a3785c2838340ce530ee1cdc6dbee3257f1672d6000ca748dfe253808dec" +sha512 = "f647de7d6c470595c3e5bf0dba6af98703beb9f701c66543cea5d42e81f7a1a73f199c3949035a9c2c1bd717056e5e68788f520af39b9d26480242b7626f22ce" diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 0c58241ff..a91d495c6 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,38 +7,41 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface monotonic-clock { + use types.{duration}; + /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type instant = u64; - /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) - type duration = u64; - /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - @since(version = 0.3.0-rc-2025-08-15) + /// + /// For completeness, this function traps if it's not possible to represent + /// the value of the clock in an `instant`. Consequently, implementations + /// should ensure that the starting time is low enough to avoid the + /// possibility of overflow in practice. + @since(version = 0.3.0-rc-2025-09-16) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-resolution: func() -> duration; /// Wait until the specified instant has occurred. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) wait-until: async func( when: instant, ); - /// Wait for the specified duration has elapsed. - @since(version = 0.3.0-rc-2025-08-15) + /// Wait for the specified duration to elapse. + @since(version = 0.3.0-rc-2025-09-16) wait-for: async func( how-long: duration, ); diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/timezone.wit index 2ee16ab20..ab8f5c080 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/timezone.wit +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit new file mode 100644 index 000000000..aff7c2a22 --- /dev/null +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/types.wit @@ -0,0 +1,8 @@ +package wasi:clocks@0.3.0-rc-2025-09-16; +/// This interface common types used throughout wasi:clocks. +@since(version = 0.3.0-rc-2025-09-16) +interface types { + /// A duration of time, in nanoseconds. + @since(version = 0.3.0-rc-2025-09-16) + type duration = u64; +} diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/wall-clock.wit index 2e3b2d441..ea940500f 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,10 +13,10 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface wall-clock { /// A time and date in seconds plus nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record datetime { seconds: u64, nanoseconds: u32, @@ -35,12 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-resolution: func() -> datetime; } diff --git a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/world.wit index 94068c75c..a6b885f07 100644 --- a/proposals/filesystem/wit-0.3.0-draft/deps/clocks/world.wit +++ b/proposals/filesystem/wit-0.3.0-draft/deps/clocks/world.wit @@ -1,10 +1,10 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import monotonic-clock; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import wall-clock; @unstable(feature = clocks-timezone) import timezone; diff --git a/proposals/filesystem/wit-0.3.0-draft/preopens.wit b/proposals/filesystem/wit-0.3.0-draft/preopens.wit index b0f609aa9..9036e90e8 100644 --- a/proposals/filesystem/wit-0.3.0-draft/preopens.wit +++ b/proposals/filesystem/wit-0.3.0-draft/preopens.wit @@ -1,11 +1,11 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface preopens { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use types.{descriptor}; /// Return the set of preopened directories, and their paths. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-directories: func() -> list>; } diff --git a/proposals/filesystem/wit-0.3.0-draft/types.wit b/proposals/filesystem/wit-0.3.0-draft/types.wit index 07d770a83..41d91beee 100644 --- a/proposals/filesystem/wit-0.3.0-draft/types.wit +++ b/proposals/filesystem/wit-0.3.0-draft/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -23,19 +23,19 @@ package wasi:filesystem@0.3.0-rc-2025-08-15; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface types { - @since(version = 0.3.0-rc-2025-08-15) - use wasi:clocks/wall-clock@0.3.0-rc-2025-08-15.{datetime}; + @since(version = 0.3.0-rc-2025-09-16) + use wasi:clocks/wall-clock@0.3.0-rc-2025-09-16.{datetime}; /// File size or length of a region within a file. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -59,7 +59,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -103,7 +103,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record descriptor-stat { /// File type. %type: descriptor-type, @@ -130,7 +130,7 @@ interface types { } /// Flags determining the method of how paths are resolved. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -138,7 +138,7 @@ interface types { } /// Open flags used by `open-at`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -151,11 +151,11 @@ interface types { } /// Number of hard links to an inode. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -255,7 +255,7 @@ interface types { } /// File or memory access pattern advisory information. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -279,7 +279,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -290,7 +290,7 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource descriptor { /// Return a stream for reading from a file. /// @@ -308,7 +308,7 @@ interface types { /// resolves to `err` with an `error-code`. /// /// Note: This is similar to `pread` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, @@ -326,7 +326,7 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `pwrite` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) write-via-stream: async func( /// Data to write data: stream, @@ -342,13 +342,13 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `write` with `O_APPEND` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) append-via-stream: async func(data: stream) -> result<_, error-code>; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) advise: async func( /// The offset within the file to which the advisory applies. offset: filesize, @@ -364,7 +364,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) sync-data: async func() -> result<_, error-code>; /// Get flags associated with a descriptor. @@ -373,7 +373,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-flags: async func() -> result; /// Get the dynamic type of a descriptor. @@ -386,14 +386,14 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-type: async func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-size: async func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. @@ -401,7 +401,7 @@ interface types { /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-times: async func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, @@ -421,7 +421,7 @@ interface types { /// /// This function returns a future, which will resolve to an error code if /// reading full contents of the directory fails. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) read-directory: async func() -> tuple, future>>; /// Synchronize the data and metadata of a file to disk. @@ -430,13 +430,13 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) sync: async func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) create-directory-at: async func( /// The relative path at which to create the directory. path: string, @@ -451,7 +451,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) stat: async func() -> result; /// Return the attributes of a file or directory. @@ -461,7 +461,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) stat-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -475,7 +475,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-times-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -494,7 +494,7 @@ interface types { /// `error-code::not-permitted` if the old path is not a file. /// /// Note: This is similar to `linkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) link-at: async func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, @@ -518,7 +518,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) open-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -536,7 +536,7 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) readlink-at: async func( /// The relative path of the symbolic link from which to read. path: string, @@ -547,7 +547,7 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) remove-directory-at: async func( /// The relative path to a directory to remove. path: string, @@ -556,7 +556,7 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) rename-at: async func( /// The relative source path of the file or directory to rename. old-path: string, @@ -572,7 +572,7 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) symlink-at: async func( /// The contents of the symbolic link. old-path: string, @@ -584,7 +584,7 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) unlink-file-at: async func( /// The relative path to a file to unlink. path: string, @@ -596,7 +596,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) is-same-object: async func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred @@ -618,14 +618,14 @@ interface types { /// computed hash. /// /// However, none of these is required. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) metadata-hash: async func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) metadata-hash-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, diff --git a/proposals/filesystem/wit-0.3.0-draft/world.wit b/proposals/filesystem/wit-0.3.0-draft/world.wit index b9dcfd562..87fc72716 100644 --- a/proposals/filesystem/wit-0.3.0-draft/world.wit +++ b/proposals/filesystem/wit-0.3.0-draft/world.wit @@ -1,9 +1,9 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import types; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import preopens; } From 8259d1dae9de24493281e74a5ac2c8fb9c91d178 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 21:31:10 +0000 Subject: [PATCH 1739/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16 --- proposals/sockets/wit-0.3.0-draft/deps.lock | 4 +- .../deps/clocks/monotonic-clock.wit | 27 +++-- .../wit-0.3.0-draft/deps/clocks/timezone.wit | 2 +- .../wit-0.3.0-draft/deps/clocks/types.wit | 8 ++ .../deps/clocks/wall-clock.wit | 10 +- .../wit-0.3.0-draft/deps/clocks/world.wit | 8 +- .../wit-0.3.0-draft/ip-name-lookup.wit | 8 +- proposals/sockets/wit-0.3.0-draft/types.wit | 106 +++++++++--------- proposals/sockets/wit-0.3.0-draft/world.wit | 8 +- 9 files changed, 96 insertions(+), 85 deletions(-) create mode 100644 proposals/sockets/wit-0.3.0-draft/deps/clocks/types.wit diff --git a/proposals/sockets/wit-0.3.0-draft/deps.lock b/proposals/sockets/wit-0.3.0-draft/deps.lock index 07d589294..4f3b1fe94 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps.lock +++ b/proposals/sockets/wit-0.3.0-draft/deps.lock @@ -1,5 +1,5 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "626953ec28ae956ec1233c4350deab6e5cdcbdd9ae6d491e102ad7c6901cc8bf" -sha512 = "ae375b002cfaacdbaa133bb87747d1b86675e13144067c3005d6c32cf5c37bb7a52b693ae46d5cd65fc4910a78d7255d0ada5142828a022497fd0eaacb61761f" +sha256 = "cf61a3785c2838340ce530ee1cdc6dbee3257f1672d6000ca748dfe253808dec" +sha512 = "f647de7d6c470595c3e5bf0dba6af98703beb9f701c66543cea5d42e81f7a1a73f199c3949035a9c2c1bd717056e5e68788f520af39b9d26480242b7626f22ce" diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 0c58241ff..a91d495c6 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,38 +7,41 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface monotonic-clock { + use types.{duration}; + /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type instant = u64; - /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) - type duration = u64; - /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - @since(version = 0.3.0-rc-2025-08-15) + /// + /// For completeness, this function traps if it's not possible to represent + /// the value of the clock in an `instant`. Consequently, implementations + /// should ensure that the starting time is low enough to avoid the + /// possibility of overflow in practice. + @since(version = 0.3.0-rc-2025-09-16) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-resolution: func() -> duration; /// Wait until the specified instant has occurred. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) wait-until: async func( when: instant, ); - /// Wait for the specified duration has elapsed. - @since(version = 0.3.0-rc-2025-08-15) + /// Wait for the specified duration to elapse. + @since(version = 0.3.0-rc-2025-09-16) wait-for: async func( how-long: duration, ); diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/timezone.wit index 2ee16ab20..ab8f5c080 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps/clocks/timezone.wit +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/types.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/types.wit new file mode 100644 index 000000000..aff7c2a22 --- /dev/null +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/types.wit @@ -0,0 +1,8 @@ +package wasi:clocks@0.3.0-rc-2025-09-16; +/// This interface common types used throughout wasi:clocks. +@since(version = 0.3.0-rc-2025-09-16) +interface types { + /// A duration of time, in nanoseconds. + @since(version = 0.3.0-rc-2025-09-16) + type duration = u64; +} diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/wall-clock.wit index 2e3b2d441..ea940500f 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps/clocks/wall-clock.wit +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,10 +13,10 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface wall-clock { /// A time and date in seconds plus nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record datetime { seconds: u64, nanoseconds: u32, @@ -35,12 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-resolution: func() -> datetime; } diff --git a/proposals/sockets/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/sockets/wit-0.3.0-draft/deps/clocks/world.wit index 94068c75c..a6b885f07 100644 --- a/proposals/sockets/wit-0.3.0-draft/deps/clocks/world.wit +++ b/proposals/sockets/wit-0.3.0-draft/deps/clocks/world.wit @@ -1,10 +1,10 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import monotonic-clock; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import wall-clock; @unstable(feature = clocks-timezone) import timezone; diff --git a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit index ab4156e25..6a652ff23 100644 --- a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit +++ b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit @@ -1,10 +1,10 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface ip-name-lookup { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use types.{ip-address}; /// Lookup error codes. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum error-code { /// Unknown error unknown, @@ -57,6 +57,6 @@ interface ip-name-lookup { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resolve-addresses: async func(name: string) -> result, error-code>; } diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 3a7915ce9..2ed1912e4 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -1,7 +1,7 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface types { - @since(version = 0.3.0-rc-2025-08-15) - use wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15.{duration}; + @since(version = 0.3.0-rc-2025-09-16) + use wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16.{duration}; /// Error codes. /// @@ -14,7 +14,7 @@ interface types { /// - `out-of-memory` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum error-code { /// Unknown error unknown, @@ -70,7 +70,7 @@ interface types { datagram-too-large, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -79,18 +79,18 @@ interface types { ipv6, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type ipv4-address = tuple; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type ipv6-address = tuple; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record ipv4-socket-address { /// sin_port port: u16, @@ -98,7 +98,7 @@ interface types { address: ipv4-address, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record ipv6-socket-address { /// sin6_port port: u16, @@ -110,7 +110,7 @@ interface types { scope-id: u32, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), @@ -135,7 +135,7 @@ interface types { /// In addition to the general error codes documented on the /// `types::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource tcp-socket { /// Create a new TCP socket. @@ -152,7 +152,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. @@ -186,7 +186,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Connect to a remote endpoint. @@ -218,7 +218,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) connect: async func(remote-address: ip-socket-address) -> result<_, error-code>; /// Start listening and return a stream of new inbound connections. @@ -285,7 +285,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) listen: func() -> result, error-code>; /// Transmit data to peer. @@ -308,7 +308,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) send: async func(data: stream) -> result<_, error-code>; /// Read data from peer. @@ -342,7 +342,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) receive: func() -> tuple, future>>; /// Get the bound local address. @@ -361,7 +361,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-local-address: func() -> result; /// Get the remote address. @@ -374,13 +374,13 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. @@ -388,7 +388,7 @@ interface types { /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. @@ -400,7 +400,7 @@ interface types { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -412,9 +412,9 @@ interface types { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-enabled: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. @@ -427,9 +427,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-idle-time: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. @@ -442,9 +442,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-interval: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. @@ -457,9 +457,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-count: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -468,9 +468,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -483,18 +483,18 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } /// A UDP socket handle. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource udp-socket { /// Create a new UDP socket. @@ -511,7 +511,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. @@ -532,7 +532,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Associate this socket with a specific peer address. @@ -571,7 +571,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) connect: func(remote-address: ip-socket-address) -> result<_, error-code>; /// Dissociate this socket from its peer address. @@ -589,7 +589,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) disconnect: func() -> result<_, error-code>; /// Send a message on the socket to a particular peer. @@ -623,7 +623,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) send: async func(data: list, remote-address: option) -> result<_, error-code>; /// Receive a message on the socket. @@ -649,7 +649,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) receive: async func() -> result, ip-socket-address>, error-code>; /// Get the current bound address. @@ -668,7 +668,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-local-address: func() -> result; /// Get the address the socket is currently "connected" to. @@ -681,7 +681,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. @@ -689,7 +689,7 @@ interface types { /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -698,9 +698,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-unicast-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -713,13 +713,13 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } } diff --git a/proposals/sockets/wit-0.3.0-draft/world.wit b/proposals/sockets/wit-0.3.0-draft/world.wit index dfafac2ae..44cc427ed 100644 --- a/proposals/sockets/wit-0.3.0-draft/world.wit +++ b/proposals/sockets/wit-0.3.0-draft/world.wit @@ -1,9 +1,9 @@ -package wasi:sockets@0.3.0-rc-2025-08-15; +package wasi:sockets@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import types; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import ip-name-lookup; } From ce50692bb03236a1399d4ba677541708597e1426 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Tue, 16 Sep 2025 17:49:35 -0400 Subject: [PATCH 1740/1772] Revert "Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16-1" --- proposals/random/wit-0.3.0-draft/insecure-seed.wit | 6 +++--- proposals/random/wit-0.3.0-draft/insecure.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/random.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/world.wit | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/proposals/random/wit-0.3.0-draft/insecure-seed.wit b/proposals/random/wit-0.3.0-draft/insecure-seed.wit index 155a88fbf..ecd504318 100644 --- a/proposals/random/wit-0.3.0-draft/insecure-seed.wit +++ b/proposals/random/wit-0.3.0-draft/insecure-seed.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16-1; +package wasi:random@0.3.0-rc-2025-08-15; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16-1) +@since(version = 0.3.0-rc-2025-08-15) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-08-15) get-insecure-seed: func() -> tuple; } diff --git a/proposals/random/wit-0.3.0-draft/insecure.wit b/proposals/random/wit-0.3.0-draft/insecure.wit index 2b190a4a1..d08d85e0b 100644 --- a/proposals/random/wit-0.3.0-draft/insecure.wit +++ b/proposals/random/wit-0.3.0-draft/insecure.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16-1; +package wasi:random@0.3.0-rc-2025-08-15; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16-1) +@since(version = 0.3.0-rc-2025-08-15) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-08-15) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-08-15) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/random.wit b/proposals/random/wit-0.3.0-draft/random.wit index 620d82cb8..3808c3095 100644 --- a/proposals/random/wit-0.3.0-draft/random.wit +++ b/proposals/random/wit-0.3.0-draft/random.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16-1; +package wasi:random@0.3.0-rc-2025-08-15; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16-1) +@since(version = 0.3.0-rc-2025-08-15) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-08-15) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-08-15) get-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/world.wit b/proposals/random/wit-0.3.0-draft/world.wit index e7ce9713f..e8f05cc43 100644 --- a/proposals/random/wit-0.3.0-draft/world.wit +++ b/proposals/random/wit-0.3.0-draft/world.wit @@ -1,13 +1,13 @@ -package wasi:random@0.3.0-rc-2025-09-16-1; +package wasi:random@0.3.0-rc-2025-08-15; -@since(version = 0.3.0-rc-2025-09-16-1) +@since(version = 0.3.0-rc-2025-08-15) world imports { - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-08-15) import random; - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-08-15) import insecure; - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-08-15) import insecure-seed; } From b8931ee5bc73dfa512050541e896fe64245031a4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 21:54:52 +0000 Subject: [PATCH 1741/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16 --- proposals/random/wit-0.3.0-draft/insecure-seed.wit | 6 +++--- proposals/random/wit-0.3.0-draft/insecure.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/random.wit | 8 ++++---- proposals/random/wit-0.3.0-draft/world.wit | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/proposals/random/wit-0.3.0-draft/insecure-seed.wit b/proposals/random/wit-0.3.0-draft/insecure-seed.wit index ecd504318..302151ba6 100644 --- a/proposals/random/wit-0.3.0-draft/insecure-seed.wit +++ b/proposals/random/wit-0.3.0-draft/insecure-seed.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-seed: func() -> tuple; } diff --git a/proposals/random/wit-0.3.0-draft/insecure.wit b/proposals/random/wit-0.3.0-draft/insecure.wit index d08d85e0b..39146e391 100644 --- a/proposals/random/wit-0.3.0-draft/insecure.wit +++ b/proposals/random/wit-0.3.0-draft/insecure.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/random.wit b/proposals/random/wit-0.3.0-draft/random.wit index 3808c3095..fa1f111dc 100644 --- a/proposals/random/wit-0.3.0-draft/random.wit +++ b/proposals/random/wit-0.3.0-draft/random.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-random-u64: func() -> u64; } diff --git a/proposals/random/wit-0.3.0-draft/world.wit b/proposals/random/wit-0.3.0-draft/world.wit index e8f05cc43..08c5ed88b 100644 --- a/proposals/random/wit-0.3.0-draft/world.wit +++ b/proposals/random/wit-0.3.0-draft/world.wit @@ -1,13 +1,13 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import random; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import insecure; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import insecure-seed; } From f4e1913003d46586b505dbd0ac4da60a2f4ff61a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 21:57:13 +0000 Subject: [PATCH 1742/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16 --- proposals/cli/wit-0.3.0-draft/deps.lock | 16 +-- .../deps/clocks/monotonic-clock.wit | 27 +++-- .../wit-0.3.0-draft/deps/clocks/timezone.wit | 2 +- .../cli/wit-0.3.0-draft/deps/clocks/types.wit | 8 ++ .../deps/clocks/wall-clock.wit | 10 +- .../cli/wit-0.3.0-draft/deps/clocks/world.wit | 8 +- .../deps/filesystem/preopens.wit | 8 +- .../wit-0.3.0-draft/deps/filesystem/types.wit | 80 ++++++------- .../wit-0.3.0-draft/deps/filesystem/world.wit | 8 +- .../deps/random/insecure-seed.wit | 6 +- .../wit-0.3.0-draft/deps/random/insecure.wit | 8 +- .../wit-0.3.0-draft/deps/random/random.wit | 8 +- .../cli/wit-0.3.0-draft/deps/random/world.wit | 10 +- .../deps/sockets/ip-name-lookup.wit | 8 +- .../wit-0.3.0-draft/deps/sockets/types.wit | 106 +++++++++--------- .../wit-0.3.0-draft/deps/sockets/world.wit | 8 +- 16 files changed, 166 insertions(+), 155 deletions(-) create mode 100644 proposals/cli/wit-0.3.0-draft/deps/clocks/types.wit diff --git a/proposals/cli/wit-0.3.0-draft/deps.lock b/proposals/cli/wit-0.3.0-draft/deps.lock index d31343695..931f9574c 100644 --- a/proposals/cli/wit-0.3.0-draft/deps.lock +++ b/proposals/cli/wit-0.3.0-draft/deps.lock @@ -1,23 +1,23 @@ [clocks] -sha256 = "626953ec28ae956ec1233c4350deab6e5cdcbdd9ae6d491e102ad7c6901cc8bf" -sha512 = "ae375b002cfaacdbaa133bb87747d1b86675e13144067c3005d6c32cf5c37bb7a52b693ae46d5cd65fc4910a78d7255d0ada5142828a022497fd0eaacb61761f" +sha256 = "cf61a3785c2838340ce530ee1cdc6dbee3257f1672d6000ca748dfe253808dec" +sha512 = "f647de7d6c470595c3e5bf0dba6af98703beb9f701c66543cea5d42e81f7a1a73f199c3949035a9c2c1bd717056e5e68788f520af39b9d26480242b7626f22ce" [filesystem] url = "https://github.com/WebAssembly/wasi-filesystem/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "a65db475f8e41fa1701de4dc467ed748af5b807bdb2b5ff5027fefd0c0eab7a2" -sha512 = "3a797b5eacad135ed8e0a903c3db8f9073e79ecc547e31bf1ec62e9576e2069ecd2e37561674c000ab6cabf1cfeec5c32648b58c592bf52911c5783f179db83a" +sha256 = "99292288bdb7ecb04e0a1a7bee478a9410df9ab57af222c3dcde375f7b957181" +sha512 = "4da72faf65b99263bd0521871a6004ea19fc9189e906451fb4d48b83d9da3269a8e4470c5775faf037a05e03151a0c05fd05cc0dfeb36757715fda2799dd1d85" deps = ["clocks"] [random] url = "https://github.com/WebAssembly/wasi-random/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "45a5fa540deaf386de72bcf53c4462901919532e6dc1a80226c117a0d6e7c5e5" -sha512 = "984b48f604992236530c190b00de9feba45f908b83a0dad31b6a1c117b6146bdfc838f4669d23763604a464bc6b980e35c07943e1bc22305e94a87c6acc51e5a" +sha256 = "0a0cead69094ce1773468ff363b2d324ded025aab4f03a1d53b2538710c31e43" +sha512 = "3596bbd164c28254aefb0f7c7a047d81121df1de170808d16975f021c5170ea35dfe6fc1867f93469013ab8d36df8de14d4c5e1c9b70197bfd10e699fd6757e5" [sockets] url = "https://github.com/WebAssembly/wasi-sockets/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "307e8459b8be0587000871d3f67fc04041e4cb1eb6c27e97183332fdb641926f" -sha512 = "183054d40082bf9e0fd38daf77df0189445c54384537548d5d37bc1b3cfd05190b1ca4377760a7108c39650785c74e5e230abd296e0fda8e2a5b263cd41f848b" +sha256 = "57e9d6df8389015116c5407641af76b717cf0d1a79e36384af3cb7d7fa9687ed" +sha512 = "45dab8dd2fa48450c480b1e770a3739793f6156b07b39075414510ce2cde3db6e714da87f47f0e9b9c82b5ef38a963a59f4d86449aa5f2310c78bc79134d0dd5" deps = ["clocks"] diff --git a/proposals/cli/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/cli/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 0c58241ff..a91d495c6 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,38 +7,41 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface monotonic-clock { + use types.{duration}; + /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type instant = u64; - /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) - type duration = u64; - /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - @since(version = 0.3.0-rc-2025-08-15) + /// + /// For completeness, this function traps if it's not possible to represent + /// the value of the clock in an `instant`. Consequently, implementations + /// should ensure that the starting time is low enough to avoid the + /// possibility of overflow in practice. + @since(version = 0.3.0-rc-2025-09-16) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-resolution: func() -> duration; /// Wait until the specified instant has occurred. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) wait-until: async func( when: instant, ); - /// Wait for the specified duration has elapsed. - @since(version = 0.3.0-rc-2025-08-15) + /// Wait for the specified duration to elapse. + @since(version = 0.3.0-rc-2025-09-16) wait-for: async func( how-long: duration, ); diff --git a/proposals/cli/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/cli/wit-0.3.0-draft/deps/clocks/timezone.wit index 2ee16ab20..ab8f5c080 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/clocks/timezone.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/cli/wit-0.3.0-draft/deps/clocks/types.wit b/proposals/cli/wit-0.3.0-draft/deps/clocks/types.wit new file mode 100644 index 000000000..aff7c2a22 --- /dev/null +++ b/proposals/cli/wit-0.3.0-draft/deps/clocks/types.wit @@ -0,0 +1,8 @@ +package wasi:clocks@0.3.0-rc-2025-09-16; +/// This interface common types used throughout wasi:clocks. +@since(version = 0.3.0-rc-2025-09-16) +interface types { + /// A duration of time, in nanoseconds. + @since(version = 0.3.0-rc-2025-09-16) + type duration = u64; +} diff --git a/proposals/cli/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/cli/wit-0.3.0-draft/deps/clocks/wall-clock.wit index 2e3b2d441..ea940500f 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,10 +13,10 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface wall-clock { /// A time and date in seconds plus nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record datetime { seconds: u64, nanoseconds: u32, @@ -35,12 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-resolution: func() -> datetime; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/cli/wit-0.3.0-draft/deps/clocks/world.wit index 94068c75c..a6b885f07 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/clocks/world.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/clocks/world.wit @@ -1,10 +1,10 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import monotonic-clock; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import wall-clock; @unstable(feature = clocks-timezone) import timezone; diff --git a/proposals/cli/wit-0.3.0-draft/deps/filesystem/preopens.wit b/proposals/cli/wit-0.3.0-draft/deps/filesystem/preopens.wit index b0f609aa9..9036e90e8 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/filesystem/preopens.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/filesystem/preopens.wit @@ -1,11 +1,11 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface preopens { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use types.{descriptor}; /// Return the set of preopened directories, and their paths. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-directories: func() -> list>; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/filesystem/types.wit b/proposals/cli/wit-0.3.0-draft/deps/filesystem/types.wit index 07d770a83..41d91beee 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/filesystem/types.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -23,19 +23,19 @@ package wasi:filesystem@0.3.0-rc-2025-08-15; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface types { - @since(version = 0.3.0-rc-2025-08-15) - use wasi:clocks/wall-clock@0.3.0-rc-2025-08-15.{datetime}; + @since(version = 0.3.0-rc-2025-09-16) + use wasi:clocks/wall-clock@0.3.0-rc-2025-09-16.{datetime}; /// File size or length of a region within a file. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -59,7 +59,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -103,7 +103,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record descriptor-stat { /// File type. %type: descriptor-type, @@ -130,7 +130,7 @@ interface types { } /// Flags determining the method of how paths are resolved. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -138,7 +138,7 @@ interface types { } /// Open flags used by `open-at`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -151,11 +151,11 @@ interface types { } /// Number of hard links to an inode. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -255,7 +255,7 @@ interface types { } /// File or memory access pattern advisory information. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -279,7 +279,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -290,7 +290,7 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource descriptor { /// Return a stream for reading from a file. /// @@ -308,7 +308,7 @@ interface types { /// resolves to `err` with an `error-code`. /// /// Note: This is similar to `pread` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, @@ -326,7 +326,7 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `pwrite` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) write-via-stream: async func( /// Data to write data: stream, @@ -342,13 +342,13 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `write` with `O_APPEND` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) append-via-stream: async func(data: stream) -> result<_, error-code>; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) advise: async func( /// The offset within the file to which the advisory applies. offset: filesize, @@ -364,7 +364,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) sync-data: async func() -> result<_, error-code>; /// Get flags associated with a descriptor. @@ -373,7 +373,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-flags: async func() -> result; /// Get the dynamic type of a descriptor. @@ -386,14 +386,14 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-type: async func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-size: async func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. @@ -401,7 +401,7 @@ interface types { /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-times: async func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, @@ -421,7 +421,7 @@ interface types { /// /// This function returns a future, which will resolve to an error code if /// reading full contents of the directory fails. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) read-directory: async func() -> tuple, future>>; /// Synchronize the data and metadata of a file to disk. @@ -430,13 +430,13 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) sync: async func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) create-directory-at: async func( /// The relative path at which to create the directory. path: string, @@ -451,7 +451,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) stat: async func() -> result; /// Return the attributes of a file or directory. @@ -461,7 +461,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) stat-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -475,7 +475,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-times-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -494,7 +494,7 @@ interface types { /// `error-code::not-permitted` if the old path is not a file. /// /// Note: This is similar to `linkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) link-at: async func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, @@ -518,7 +518,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) open-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -536,7 +536,7 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) readlink-at: async func( /// The relative path of the symbolic link from which to read. path: string, @@ -547,7 +547,7 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) remove-directory-at: async func( /// The relative path to a directory to remove. path: string, @@ -556,7 +556,7 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) rename-at: async func( /// The relative source path of the file or directory to rename. old-path: string, @@ -572,7 +572,7 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) symlink-at: async func( /// The contents of the symbolic link. old-path: string, @@ -584,7 +584,7 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) unlink-file-at: async func( /// The relative path to a file to unlink. path: string, @@ -596,7 +596,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) is-same-object: async func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred @@ -618,14 +618,14 @@ interface types { /// computed hash. /// /// However, none of these is required. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) metadata-hash: async func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) metadata-hash-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, diff --git a/proposals/cli/wit-0.3.0-draft/deps/filesystem/world.wit b/proposals/cli/wit-0.3.0-draft/deps/filesystem/world.wit index b9dcfd562..87fc72716 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/filesystem/world.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/filesystem/world.wit @@ -1,9 +1,9 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import types; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import preopens; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit b/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit index 155a88fbf..302151ba6 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/random/insecure-seed.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16-1; +package wasi:random@0.3.0-rc-2025-09-16; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16-1) +@since(version = 0.3.0-rc-2025-09-16) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-seed: func() -> tuple; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit b/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit index 2b190a4a1..39146e391 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/random/insecure.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16-1; +package wasi:random@0.3.0-rc-2025-09-16; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16-1) +@since(version = 0.3.0-rc-2025-09-16) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/random.wit b/proposals/cli/wit-0.3.0-draft/deps/random/random.wit index 620d82cb8..fa1f111dc 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/random/random.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/random/random.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-09-16-1; +package wasi:random@0.3.0-rc-2025-09-16; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-09-16-1) +@since(version = 0.3.0-rc-2025-09-16) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) get-random-u64: func() -> u64; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/random/world.wit b/proposals/cli/wit-0.3.0-draft/deps/random/world.wit index e7ce9713f..08c5ed88b 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/random/world.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/random/world.wit @@ -1,13 +1,13 @@ -package wasi:random@0.3.0-rc-2025-09-16-1; +package wasi:random@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-09-16-1) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) import random; - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) import insecure; - @since(version = 0.3.0-rc-2025-09-16-1) + @since(version = 0.3.0-rc-2025-09-16) import insecure-seed; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit index ab4156e25..6a652ff23 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit @@ -1,10 +1,10 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface ip-name-lookup { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use types.{ip-address}; /// Lookup error codes. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum error-code { /// Unknown error unknown, @@ -57,6 +57,6 @@ interface ip-name-lookup { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resolve-addresses: async func(name: string) -> result, error-code>; } diff --git a/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit b/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit index 3a7915ce9..2ed1912e4 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/sockets/types.wit @@ -1,7 +1,7 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface types { - @since(version = 0.3.0-rc-2025-08-15) - use wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15.{duration}; + @since(version = 0.3.0-rc-2025-09-16) + use wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16.{duration}; /// Error codes. /// @@ -14,7 +14,7 @@ interface types { /// - `out-of-memory` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum error-code { /// Unknown error unknown, @@ -70,7 +70,7 @@ interface types { datagram-too-large, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -79,18 +79,18 @@ interface types { ipv6, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type ipv4-address = tuple; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type ipv6-address = tuple; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record ipv4-socket-address { /// sin_port port: u16, @@ -98,7 +98,7 @@ interface types { address: ipv4-address, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record ipv6-socket-address { /// sin6_port port: u16, @@ -110,7 +110,7 @@ interface types { scope-id: u32, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), @@ -135,7 +135,7 @@ interface types { /// In addition to the general error codes documented on the /// `types::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource tcp-socket { /// Create a new TCP socket. @@ -152,7 +152,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. @@ -186,7 +186,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Connect to a remote endpoint. @@ -218,7 +218,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) connect: async func(remote-address: ip-socket-address) -> result<_, error-code>; /// Start listening and return a stream of new inbound connections. @@ -285,7 +285,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) listen: func() -> result, error-code>; /// Transmit data to peer. @@ -308,7 +308,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) send: async func(data: stream) -> result<_, error-code>; /// Read data from peer. @@ -342,7 +342,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) receive: func() -> tuple, future>>; /// Get the bound local address. @@ -361,7 +361,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-local-address: func() -> result; /// Get the remote address. @@ -374,13 +374,13 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. @@ -388,7 +388,7 @@ interface types { /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. @@ -400,7 +400,7 @@ interface types { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -412,9 +412,9 @@ interface types { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-enabled: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. @@ -427,9 +427,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-idle-time: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. @@ -442,9 +442,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-interval: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. @@ -457,9 +457,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-count: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -468,9 +468,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -483,18 +483,18 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } /// A UDP socket handle. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource udp-socket { /// Create a new UDP socket. @@ -511,7 +511,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. @@ -532,7 +532,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Associate this socket with a specific peer address. @@ -571,7 +571,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) connect: func(remote-address: ip-socket-address) -> result<_, error-code>; /// Dissociate this socket from its peer address. @@ -589,7 +589,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) disconnect: func() -> result<_, error-code>; /// Send a message on the socket to a particular peer. @@ -623,7 +623,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) send: async func(data: list, remote-address: option) -> result<_, error-code>; /// Receive a message on the socket. @@ -649,7 +649,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) receive: async func() -> result, ip-socket-address>, error-code>; /// Get the current bound address. @@ -668,7 +668,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-local-address: func() -> result; /// Get the address the socket is currently "connected" to. @@ -681,7 +681,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. @@ -689,7 +689,7 @@ interface types { /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -698,9 +698,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-unicast-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -713,13 +713,13 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } } diff --git a/proposals/cli/wit-0.3.0-draft/deps/sockets/world.wit b/proposals/cli/wit-0.3.0-draft/deps/sockets/world.wit index dfafac2ae..44cc427ed 100644 --- a/proposals/cli/wit-0.3.0-draft/deps/sockets/world.wit +++ b/proposals/cli/wit-0.3.0-draft/deps/sockets/world.wit @@ -1,9 +1,9 @@ -package wasi:sockets@0.3.0-rc-2025-08-15; +package wasi:sockets@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import types; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import ip-name-lookup; } From 74cdc6ddf35eae4f5154c234704ee53aa64a7cff Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 22:01:26 +0000 Subject: [PATCH 1743/1772] Update 0.3.0 WIT definitions to 0.3.0-rc-2025-09-16 --- proposals/http/wit-0.3.0-draft/deps.lock | 20 ++-- .../http/wit-0.3.0-draft/deps/cli/command.wit | 8 +- .../wit-0.3.0-draft/deps/cli/environment.wit | 8 +- .../http/wit-0.3.0-draft/deps/cli/exit.wit | 4 +- .../http/wit-0.3.0-draft/deps/cli/imports.wit | 40 +++---- .../http/wit-0.3.0-draft/deps/cli/run.wit | 6 +- .../http/wit-0.3.0-draft/deps/cli/stdio.wit | 66 +++++++++-- .../wit-0.3.0-draft/deps/cli/terminal.wit | 26 ++--- .../deps/clocks/monotonic-clock.wit | 27 +++-- .../wit-0.3.0-draft/deps/clocks/timezone.wit | 2 +- .../wit-0.3.0-draft/deps/clocks/types.wit | 8 ++ .../deps/clocks/wall-clock.wit | 10 +- .../wit-0.3.0-draft/deps/clocks/world.wit | 8 +- .../deps/filesystem/preopens.wit | 8 +- .../wit-0.3.0-draft/deps/filesystem/types.wit | 80 ++++++------- .../wit-0.3.0-draft/deps/filesystem/world.wit | 8 +- .../deps/random/insecure-seed.wit | 6 +- .../wit-0.3.0-draft/deps/random/insecure.wit | 8 +- .../wit-0.3.0-draft/deps/random/random.wit | 8 +- .../wit-0.3.0-draft/deps/random/world.wit | 10 +- .../deps/sockets/ip-name-lookup.wit | 8 +- .../wit-0.3.0-draft/deps/sockets/types.wit | 106 +++++++++--------- .../wit-0.3.0-draft/deps/sockets/world.wit | 8 +- proposals/http/wit-0.3.0-draft/proxy.wit | 12 +- proposals/http/wit-0.3.0-draft/types.wit | 2 +- 25 files changed, 278 insertions(+), 219 deletions(-) create mode 100644 proposals/http/wit-0.3.0-draft/deps/clocks/types.wit diff --git a/proposals/http/wit-0.3.0-draft/deps.lock b/proposals/http/wit-0.3.0-draft/deps.lock index be1b0569e..eb9014bd2 100644 --- a/proposals/http/wit-0.3.0-draft/deps.lock +++ b/proposals/http/wit-0.3.0-draft/deps.lock @@ -1,22 +1,22 @@ [cli] url = "https://github.com/WebAssembly/wasi-cli/archive/main.tar.gz" subdir = "wit-0.3.0-draft" -sha256 = "7f9cf181100ca1cadcb49a1efa3e80828d375df2d5ddf10a8f66e848d423aea5" -sha512 = "569f6b4ed2a3bec913e5e06fd35caab564048cf31632795c2fbdd8c40ddb5f5eea7b1cc59d33c80e5d7b642ed246ba4a3e40d3edeaaa2c6a5c4bcd02e0b67212" +sha256 = "5a4fb9ecf963e19b131821132dd835cc140424e6b03aa8434d4fb4df25a52ec4" +sha512 = "48319184c0b7157bd358cdaf20b9bd054731a06fa032a4c785c72e1f8ced7c1260b135f9801d46d7e031efb3a38b62f0b1a1538955e44ef3abfda7ab353215e6" deps = ["clocks", "filesystem", "random", "sockets"] [clocks] -sha256 = "626953ec28ae956ec1233c4350deab6e5cdcbdd9ae6d491e102ad7c6901cc8bf" -sha512 = "ae375b002cfaacdbaa133bb87747d1b86675e13144067c3005d6c32cf5c37bb7a52b693ae46d5cd65fc4910a78d7255d0ada5142828a022497fd0eaacb61761f" +sha256 = "cf61a3785c2838340ce530ee1cdc6dbee3257f1672d6000ca748dfe253808dec" +sha512 = "f647de7d6c470595c3e5bf0dba6af98703beb9f701c66543cea5d42e81f7a1a73f199c3949035a9c2c1bd717056e5e68788f520af39b9d26480242b7626f22ce" [filesystem] -sha256 = "a65db475f8e41fa1701de4dc467ed748af5b807bdb2b5ff5027fefd0c0eab7a2" -sha512 = "3a797b5eacad135ed8e0a903c3db8f9073e79ecc547e31bf1ec62e9576e2069ecd2e37561674c000ab6cabf1cfeec5c32648b58c592bf52911c5783f179db83a" +sha256 = "99292288bdb7ecb04e0a1a7bee478a9410df9ab57af222c3dcde375f7b957181" +sha512 = "4da72faf65b99263bd0521871a6004ea19fc9189e906451fb4d48b83d9da3269a8e4470c5775faf037a05e03151a0c05fd05cc0dfeb36757715fda2799dd1d85" [random] -sha256 = "fcc4d3b51564274bb05ebd7cad65ff036eed5c1ac1316639e0c04aa0d64fc938" -sha512 = "d3b10e7791fc354730551f8e21beff96bdbf16f96ef655cd0ac7e0489a9e28c4a7a602d50b199de4a27981643bdbea7ec075cfa80ca351aea6ae74ea660b0568" +sha256 = "0a0cead69094ce1773468ff363b2d324ded025aab4f03a1d53b2538710c31e43" +sha512 = "3596bbd164c28254aefb0f7c7a047d81121df1de170808d16975f021c5170ea35dfe6fc1867f93469013ab8d36df8de14d4c5e1c9b70197bfd10e699fd6757e5" [sockets] -sha256 = "307e8459b8be0587000871d3f67fc04041e4cb1eb6c27e97183332fdb641926f" -sha512 = "183054d40082bf9e0fd38daf77df0189445c54384537548d5d37bc1b3cfd05190b1ca4377760a7108c39650785c74e5e230abd296e0fda8e2a5b263cd41f848b" +sha256 = "57e9d6df8389015116c5407641af76b717cf0d1a79e36384af3cb7d7fa9687ed" +sha512 = "45dab8dd2fa48450c480b1e770a3739793f6156b07b39075414510ce2cde3db6e714da87f47f0e9b9c82b5ef38a963a59f4d86449aa5f2310c78bc79134d0dd5" diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit index 13e92bdec..f2f613e55 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/command.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/command.wit @@ -1,10 +1,10 @@ -package wasi:cli@0.3.0-rc-2025-08-15; +package wasi:cli@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world command { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) include imports; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) export run; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit b/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit index 769858af1..3763f2f6c 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/environment.wit @@ -1,4 +1,4 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface environment { /// Get the POSIX-style environment variables. /// @@ -8,15 +8,15 @@ interface environment { /// Morally, these are a value import, but until value imports are available /// in the component model, this import function should return the same /// values each time it is called. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-environment: func() -> list>; /// Get the POSIX-style arguments to the program. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-arguments: func() -> list; /// Return a path that programs should use as their initial current working /// directory, interpreting `.` as shorthand for this. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-initial-cwd: func() -> option; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit b/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit index dcf791a20..1efba7d68 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/exit.wit @@ -1,7 +1,7 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface exit { /// Exit the current instance and any linked instances. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) exit: func(status: result); /// Exit the current instance and any linked instances, reporting the diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit index 2d513ead9..660a2dd95 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/imports.wit @@ -1,34 +1,34 @@ -package wasi:cli@0.3.0-rc-2025-08-15; +package wasi:cli@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) - include wasi:clocks/imports@0.3.0-rc-2025-08-15; - @since(version = 0.3.0-rc-2025-08-15) - include wasi:filesystem/imports@0.3.0-rc-2025-08-15; - @since(version = 0.3.0-rc-2025-08-15) - include wasi:sockets/imports@0.3.0-rc-2025-08-15; - @since(version = 0.3.0-rc-2025-08-15) - include wasi:random/imports@0.3.0-rc-2025-08-15; + @since(version = 0.3.0-rc-2025-09-16) + include wasi:clocks/imports@0.3.0-rc-2025-09-16; + @since(version = 0.3.0-rc-2025-09-16) + include wasi:filesystem/imports@0.3.0-rc-2025-09-16; + @since(version = 0.3.0-rc-2025-09-16) + include wasi:sockets/imports@0.3.0-rc-2025-09-16; + @since(version = 0.3.0-rc-2025-09-16) + include wasi:random/imports@0.3.0-rc-2025-09-16; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import environment; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import exit; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import stdin; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import stdout; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import stderr; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import terminal-input; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import terminal-output; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import terminal-stdin; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import terminal-stdout; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import terminal-stderr; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/run.wit b/proposals/http/wit-0.3.0-draft/deps/cli/run.wit index 6149db760..631441a3f 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/run.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/run.wit @@ -1,6 +1,6 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface run { /// Run the program. - @since(version = 0.3.0-rc-2025-08-15) - run: func() -> result; + @since(version = 0.3.0-rc-2025-09-16) + run: async func() -> result; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit index 6c99a56f1..51e5ae4b4 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/stdio.wit @@ -1,17 +1,65 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) +interface types { + @since(version = 0.3.0-rc-2025-09-16) + enum error-code { + /// Input/output error + io, + /// Invalid or incomplete multibyte or wide character + illegal-byte-sequence, + /// Broken pipe + pipe, + } +} + +@since(version = 0.3.0-rc-2025-09-16) interface stdin { - @since(version = 0.3.0-rc-2025-08-15) - get-stdin: func() -> stream; + use types.{error-code}; + + /// Return a stream for reading from stdin. + /// + /// This function returns a stream which provides data read from stdin, + /// and a future to signal read results. + /// + /// If the stream's readable end is dropped the future will resolve to success. + /// + /// If the stream's writable end is dropped the future will either resolve to + /// success if stdin was closed by the writer or to an error-code if reading + /// failed for some other reason. + /// + /// Multiple streams may be active at the same time. The behavior of concurrent + /// reads is implementation-specific. + @since(version = 0.3.0-rc-2025-09-16) + read-via-stream: func() -> tuple, future>>; } -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface stdout { - @since(version = 0.3.0-rc-2025-08-15) - set-stdout: func(data: stream); + use types.{error-code}; + + /// Write the given stream to stdout. + /// + /// If the stream's writable end is dropped this function will either return + /// success once the entire contents of the stream have been written or an + /// error-code representing a failure. + /// + /// Otherwise if there is an error the readable end of the stream will be + /// dropped and this function will return an error-code. + @since(version = 0.3.0-rc-2025-09-16) + write-via-stream: async func(data: stream) -> result<_, error-code>; } -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface stderr { - @since(version = 0.3.0-rc-2025-08-15) - set-stderr: func(data: stream); + use types.{error-code}; + + /// Write the given stream to stderr. + /// + /// If the stream's writable end is dropped this function will either return + /// success once the entire contents of the stream have been written or an + /// error-code representing a failure. + /// + /// Otherwise if there is an error the readable end of the stream will be + /// dropped and this function will return an error-code. + @since(version = 0.3.0-rc-2025-09-16) + write-via-stream: async func(data: stream) -> result<_, error-code>; } diff --git a/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit b/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit index 3b2b72bba..74c17694a 100644 --- a/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit +++ b/proposals/http/wit-0.3.0-draft/deps/cli/terminal.wit @@ -3,10 +3,10 @@ /// In the future, this may include functions for disabling echoing, /// disabling input buffering so that keyboard events are sent through /// immediately, querying supported features, and so on. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface terminal-input { /// The input side of a terminal. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource terminal-input; } @@ -15,48 +15,48 @@ interface terminal-input { /// In the future, this may include functions for querying the terminal /// size, being notified of terminal size changes, querying supported /// features, and so on. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface terminal-output { /// The output side of a terminal. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource terminal-output; } /// An interface providing an optional `terminal-input` for stdin as a /// link-time authority. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface terminal-stdin { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use terminal-input.{terminal-input}; /// If stdin is connected to a terminal, return a `terminal-input` handle /// allowing further interaction with it. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-terminal-stdin: func() -> option; } /// An interface providing an optional `terminal-output` for stdout as a /// link-time authority. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface terminal-stdout { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use terminal-output.{terminal-output}; /// If stdout is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-terminal-stdout: func() -> option; } /// An interface providing an optional `terminal-output` for stderr as a /// link-time authority. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface terminal-stderr { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use terminal-output.{terminal-output}; /// If stderr is connected to a terminal, return a `terminal-output` handle /// allowing further interaction with it. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-terminal-stderr: func() -> option; } diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit index 0c58241ff..a91d495c6 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -7,38 +7,41 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// /// A monotonic clock is a clock which has an unspecified initial value, and /// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface monotonic-clock { + use types.{duration}; + /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type instant = u64; - /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) - type duration = u64; - /// Read the current value of the clock. /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. - @since(version = 0.3.0-rc-2025-08-15) + /// + /// For completeness, this function traps if it's not possible to represent + /// the value of the clock in an `instant`. Consequently, implementations + /// should ensure that the starting time is low enough to avoid the + /// possibility of overflow in practice. + @since(version = 0.3.0-rc-2025-09-16) now: func() -> instant; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-resolution: func() -> duration; /// Wait until the specified instant has occurred. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) wait-until: async func( when: instant, ); - /// Wait for the specified duration has elapsed. - @since(version = 0.3.0-rc-2025-08-15) + /// Wait for the specified duration to elapse. + @since(version = 0.3.0-rc-2025-09-16) wait-for: async func( how-long: duration, ); diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit index 2ee16ab20..ab8f5c080 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/types.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/types.wit new file mode 100644 index 000000000..aff7c2a22 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/types.wit @@ -0,0 +1,8 @@ +package wasi:clocks@0.3.0-rc-2025-09-16; +/// This interface common types used throughout wasi:clocks. +@since(version = 0.3.0-rc-2025-09-16) +interface types { + /// A duration of time, in nanoseconds. + @since(version = 0.3.0-rc-2025-09-16) + type duration = u64; +} diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit index 2e3b2d441..ea940500f 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. @@ -13,10 +13,10 @@ package wasi:clocks@0.3.0-rc-2025-08-15; /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface wall-clock { /// A time and date in seconds plus nanoseconds. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record datetime { seconds: u64, nanoseconds: u32, @@ -35,12 +35,12 @@ interface wall-clock { /// /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) now: func() -> datetime; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-resolution: func() -> datetime; } diff --git a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit index 94068c75c..a6b885f07 100644 --- a/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/clocks/world.wit @@ -1,10 +1,10 @@ -package wasi:clocks@0.3.0-rc-2025-08-15; +package wasi:clocks@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import monotonic-clock; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import wall-clock; @unstable(feature = clocks-timezone) import timezone; diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit index b0f609aa9..9036e90e8 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/preopens.wit @@ -1,11 +1,11 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface preopens { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use types.{descriptor}; /// Return the set of preopened directories, and their paths. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-directories: func() -> list>; } diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit index 07d770a83..41d91beee 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -23,19 +23,19 @@ package wasi:filesystem@0.3.0-rc-2025-08-15; /// [WASI filesystem path resolution]. /// /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface types { - @since(version = 0.3.0-rc-2025-08-15) - use wasi:clocks/wall-clock@0.3.0-rc-2025-08-15.{datetime}; + @since(version = 0.3.0-rc-2025-09-16) + use wasi:clocks/wall-clock@0.3.0-rc-2025-09-16.{datetime}; /// File size or length of a region within a file. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type filesize = u64; /// The type of a filesystem object referenced by a descriptor. /// /// Note: This was called `filetype` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum descriptor-type { /// The type of the descriptor or file is unknown or is different from /// any of the other types specified. @@ -59,7 +59,7 @@ interface types { /// Descriptor flags. /// /// Note: This was called `fdflags` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags descriptor-flags { /// Read mode: Data can be read. read, @@ -103,7 +103,7 @@ interface types { /// File attributes. /// /// Note: This was called `filestat` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record descriptor-stat { /// File type. %type: descriptor-type, @@ -130,7 +130,7 @@ interface types { } /// Flags determining the method of how paths are resolved. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags path-flags { /// As long as the resolved path corresponds to a symbolic link, it is /// expanded. @@ -138,7 +138,7 @@ interface types { } /// Open flags used by `open-at`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) flags open-flags { /// Create file if it does not exist, similar to `O_CREAT` in POSIX. create, @@ -151,11 +151,11 @@ interface types { } /// Number of hard links to an inode. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type link-count = u64; /// When setting a timestamp, this gives the value to set it to. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) variant new-timestamp { /// Leave the timestamp set to its previous value. no-change, @@ -255,7 +255,7 @@ interface types { } /// File or memory access pattern advisory information. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum advice { /// The application has no advice to give on its behavior with respect /// to the specified data. @@ -279,7 +279,7 @@ interface types { /// A 128-bit hash value, split into parts because wasm doesn't have a /// 128-bit integer type. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record metadata-hash-value { /// 64 bits of a 128-bit hash value. lower: u64, @@ -290,7 +290,7 @@ interface types { /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource descriptor { /// Return a stream for reading from a file. /// @@ -308,7 +308,7 @@ interface types { /// resolves to `err` with an `error-code`. /// /// Note: This is similar to `pread` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) read-via-stream: func( /// The offset within the file at which to start reading. offset: filesize, @@ -326,7 +326,7 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `pwrite` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) write-via-stream: async func( /// Data to write data: stream, @@ -342,13 +342,13 @@ interface types { /// written or an error is encountered. /// /// Note: This is similar to `write` with `O_APPEND` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) append-via-stream: async func(data: stream) -> result<_, error-code>; /// Provide file advisory information on a descriptor. /// /// This is similar to `posix_fadvise` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) advise: async func( /// The offset within the file to which the advisory applies. offset: filesize, @@ -364,7 +364,7 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fdatasync` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) sync-data: async func() -> result<_, error-code>; /// Get flags associated with a descriptor. @@ -373,7 +373,7 @@ interface types { /// /// Note: This returns the value that was the `fs_flags` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-flags: async func() -> result; /// Get the dynamic type of a descriptor. @@ -386,14 +386,14 @@ interface types { /// /// Note: This returns the value that was the `fs_filetype` value returned /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-type: async func() -> result; /// Adjust the size of an open file. If this increases the file's size, the /// extra bytes are filled with zeros. /// /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-size: async func(size: filesize) -> result<_, error-code>; /// Adjust the timestamps of an open file or directory. @@ -401,7 +401,7 @@ interface types { /// Note: This is similar to `futimens` in POSIX. /// /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-times: async func( /// The desired values of the data access timestamp. data-access-timestamp: new-timestamp, @@ -421,7 +421,7 @@ interface types { /// /// This function returns a future, which will resolve to an error code if /// reading full contents of the directory fails. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) read-directory: async func() -> tuple, future>>; /// Synchronize the data and metadata of a file to disk. @@ -430,13 +430,13 @@ interface types { /// opened for writing. /// /// Note: This is similar to `fsync` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) sync: async func() -> result<_, error-code>; /// Create a directory. /// /// Note: This is similar to `mkdirat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) create-directory-at: async func( /// The relative path at which to create the directory. path: string, @@ -451,7 +451,7 @@ interface types { /// modified, use `metadata-hash`. /// /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) stat: async func() -> result; /// Return the attributes of a file or directory. @@ -461,7 +461,7 @@ interface types { /// discussion of alternatives. /// /// Note: This was called `path_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) stat-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -475,7 +475,7 @@ interface types { /// /// Note: This was called `path_filestat_set_times` in earlier versions of /// WASI. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-times-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -494,7 +494,7 @@ interface types { /// `error-code::not-permitted` if the old path is not a file. /// /// Note: This is similar to `linkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) link-at: async func( /// Flags determining the method of how the path is resolved. old-path-flags: path-flags, @@ -518,7 +518,7 @@ interface types { /// `error-code::read-only`. /// /// Note: This is similar to `openat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) open-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, @@ -536,7 +536,7 @@ interface types { /// filesystem, this function fails with `error-code::not-permitted`. /// /// Note: This is similar to `readlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) readlink-at: async func( /// The relative path of the symbolic link from which to read. path: string, @@ -547,7 +547,7 @@ interface types { /// Return `error-code::not-empty` if the directory is not empty. /// /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) remove-directory-at: async func( /// The relative path to a directory to remove. path: string, @@ -556,7 +556,7 @@ interface types { /// Rename a filesystem object. /// /// Note: This is similar to `renameat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) rename-at: async func( /// The relative source path of the file or directory to rename. old-path: string, @@ -572,7 +572,7 @@ interface types { /// `error-code::not-permitted`. /// /// Note: This is similar to `symlinkat` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) symlink-at: async func( /// The contents of the symbolic link. old-path: string, @@ -584,7 +584,7 @@ interface types { /// /// Return `error-code::is-directory` if the path refers to a directory. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) unlink-file-at: async func( /// The relative path to a file to unlink. path: string, @@ -596,7 +596,7 @@ interface types { /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// wasi-filesystem does not expose device and inode numbers, so this function /// may be used instead. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) is-same-object: async func(other: borrow) -> bool; /// Return a hash of the metadata associated with a filesystem object referred @@ -618,14 +618,14 @@ interface types { /// computed hash. /// /// However, none of these is required. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) metadata-hash: async func() -> result; /// Return a hash of the metadata associated with a filesystem object referred /// to by a directory descriptor and a relative path. /// /// This performs the same hash computation as `metadata-hash`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) metadata-hash-at: async func( /// Flags determining the method of how the path is resolved. path-flags: path-flags, diff --git a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit index b9dcfd562..87fc72716 100644 --- a/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/filesystem/world.wit @@ -1,9 +1,9 @@ -package wasi:filesystem@0.3.0-rc-2025-08-15; +package wasi:filesystem@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import types; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import preopens; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit index ecd504318..302151ba6 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure-seed.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface insecure-seed { /// Return a 128-bit value that may contain a pseudo-random value. /// @@ -22,6 +22,6 @@ interface insecure-seed { /// This will likely be changed to a value import, to prevent it from being /// called multiple times and potentially used for purposes other than DoS /// protection. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-seed: func() -> tuple; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit index d08d85e0b..39146e391 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/insecure.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface insecure { /// Return `len` insecure pseudo-random bytes. /// @@ -13,13 +13,13 @@ interface insecure { /// There are no requirements on the values of the returned bytes, however /// implementations are encouraged to return evenly distributed values with /// a long period. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-random-bytes: func(len: u64) -> list; /// Return an insecure pseudo-random `u64` value. /// /// This function returns the same type of pseudo-random data as /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-insecure-random-u64: func() -> u64; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/random.wit b/proposals/http/wit-0.3.0-draft/deps/random/random.wit index 3808c3095..fa1f111dc 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/random.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/random.wit @@ -1,9 +1,9 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface random { /// Return `len` cryptographically-secure random or pseudo-random bytes. /// @@ -17,13 +17,13 @@ interface random { /// This function must always return fresh data. Deterministic environments /// must omit this function, rather than implementing it with deterministic /// data. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-random-bytes: func(len: u64) -> list; /// Return a cryptographically-secure random or pseudo-random `u64` value. /// /// This function returns the same type of data as `get-random-bytes`, /// represented as a `u64`. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-random-u64: func() -> u64; } diff --git a/proposals/http/wit-0.3.0-draft/deps/random/world.wit b/proposals/http/wit-0.3.0-draft/deps/random/world.wit index e8f05cc43..08c5ed88b 100644 --- a/proposals/http/wit-0.3.0-draft/deps/random/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/random/world.wit @@ -1,13 +1,13 @@ -package wasi:random@0.3.0-rc-2025-08-15; +package wasi:random@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import random; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import insecure; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import insecure-seed; } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit index ab4156e25..6a652ff23 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/ip-name-lookup.wit @@ -1,10 +1,10 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface ip-name-lookup { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) use types.{ip-address}; /// Lookup error codes. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum error-code { /// Unknown error unknown, @@ -57,6 +57,6 @@ interface ip-name-lookup { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resolve-addresses: async func(name: string) -> result, error-code>; } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/types.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/types.wit index 3a7915ce9..2ed1912e4 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/types.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/types.wit @@ -1,7 +1,7 @@ -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) interface types { - @since(version = 0.3.0-rc-2025-08-15) - use wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15.{duration}; + @since(version = 0.3.0-rc-2025-09-16) + use wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16.{duration}; /// Error codes. /// @@ -14,7 +14,7 @@ interface types { /// - `out-of-memory` /// /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum error-code { /// Unknown error unknown, @@ -70,7 +70,7 @@ interface types { datagram-too-large, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) enum ip-address-family { /// Similar to `AF_INET` in POSIX. ipv4, @@ -79,18 +79,18 @@ interface types { ipv6, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type ipv4-address = tuple; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) type ipv6-address = tuple; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) variant ip-address { ipv4(ipv4-address), ipv6(ipv6-address), } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record ipv4-socket-address { /// sin_port port: u16, @@ -98,7 +98,7 @@ interface types { address: ipv4-address, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) record ipv6-socket-address { /// sin6_port port: u16, @@ -110,7 +110,7 @@ interface types { scope-id: u32, } - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) variant ip-socket-address { ipv4(ipv4-socket-address), ipv6(ipv6-socket-address), @@ -135,7 +135,7 @@ interface types { /// In addition to the general error codes documented on the /// `types::error-code` type, TCP socket methods may always return /// `error(invalid-state)` when in the `closed` state. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource tcp-socket { /// Create a new TCP socket. @@ -152,7 +152,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. @@ -186,7 +186,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Connect to a remote endpoint. @@ -218,7 +218,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) connect: async func(remote-address: ip-socket-address) -> result<_, error-code>; /// Start listening and return a stream of new inbound connections. @@ -285,7 +285,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) listen: func() -> result, error-code>; /// Transmit data to peer. @@ -308,7 +308,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) send: async func(data: stream) -> result<_, error-code>; /// Read data from peer. @@ -342,7 +342,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) receive: func() -> tuple, future>>; /// Get the bound local address. @@ -361,7 +361,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-local-address: func() -> result; /// Get the remote address. @@ -374,13 +374,13 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-remote-address: func() -> result; /// Whether the socket is in the `listening` state. /// /// Equivalent to the SO_ACCEPTCONN socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-is-listening: func() -> bool; /// Whether this is a IPv4 or IPv6 socket. @@ -388,7 +388,7 @@ interface types { /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-address-family: func() -> ip-address-family; /// Hints the desired listen queue size. Implementations are free to ignore this. @@ -400,7 +400,7 @@ interface types { /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-listen-backlog-size: func(value: u64) -> result<_, error-code>; /// Enables or disables keepalive. @@ -412,9 +412,9 @@ interface types { /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// /// Equivalent to the SO_KEEPALIVE socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-enabled: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. @@ -427,9 +427,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-idle-time: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; /// The time between keepalive packets. @@ -442,9 +442,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-interval: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-interval: func(value: duration) -> result<_, error-code>; /// The maximum amount of keepalive packets TCP should send before aborting the connection. @@ -457,9 +457,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-keep-alive-count: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-keep-alive-count: func(value: u32) -> result<_, error-code>; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -468,9 +468,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -483,18 +483,18 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } /// A UDP socket handle. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) resource udp-socket { /// Create a new UDP socket. @@ -511,7 +511,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) create: static func(address-family: ip-address-family) -> result; /// Bind the socket to the provided IP address and port. @@ -532,7 +532,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) bind: func(local-address: ip-socket-address) -> result<_, error-code>; /// Associate this socket with a specific peer address. @@ -571,7 +571,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) connect: func(remote-address: ip-socket-address) -> result<_, error-code>; /// Dissociate this socket from its peer address. @@ -589,7 +589,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) disconnect: func() -> result<_, error-code>; /// Send a message on the socket to a particular peer. @@ -623,7 +623,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) send: async func(data: list, remote-address: option) -> result<_, error-code>; /// Receive a message on the socket. @@ -649,7 +649,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) receive: async func() -> result, ip-socket-address>, error-code>; /// Get the current bound address. @@ -668,7 +668,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-local-address: func() -> result; /// Get the address the socket is currently "connected" to. @@ -681,7 +681,7 @@ interface types { /// - /// - /// - - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-remote-address: func() -> result; /// Whether this is a IPv4 or IPv6 socket. @@ -689,7 +689,7 @@ interface types { /// This is the value passed to the constructor. /// /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-address-family: func() -> ip-address-family; /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. @@ -698,9 +698,9 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-unicast-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; /// The kernel buffer space reserved for sends/receives on this socket. @@ -713,13 +713,13 @@ interface types { /// /// # Typical errors /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) set-send-buffer-size: func(value: u64) -> result<_, error-code>; } } diff --git a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit index dfafac2ae..44cc427ed 100644 --- a/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit +++ b/proposals/http/wit-0.3.0-draft/deps/sockets/world.wit @@ -1,9 +1,9 @@ -package wasi:sockets@0.3.0-rc-2025-08-15; +package wasi:sockets@0.3.0-rc-2025-09-16; -@since(version = 0.3.0-rc-2025-08-15) +@since(version = 0.3.0-rc-2025-09-16) world imports { - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import types; - @since(version = 0.3.0-rc-2025-08-15) + @since(version = 0.3.0-rc-2025-09-16) import ip-name-lookup; } diff --git a/proposals/http/wit-0.3.0-draft/proxy.wit b/proposals/http/wit-0.3.0-draft/proxy.wit index 31e5facd0..223083ea2 100644 --- a/proposals/http/wit-0.3.0-draft/proxy.wit +++ b/proposals/http/wit-0.3.0-draft/proxy.wit @@ -1,22 +1,22 @@ -package wasi:http@0.3.0-rc-2025-08-15; +package wasi:http@0.3.0-rc-2025-09-16; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. /// It is intended to be `include`d in other worlds. world imports { /// HTTP proxies have access to time and randomness. - include wasi:clocks/imports@0.3.0-rc-2025-08-15; - import wasi:random/random@0.3.0-rc-2025-08-15; + include wasi:clocks/imports@0.3.0-rc-2025-09-16; + import wasi:random/random@0.3.0-rc-2025-09-16; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.3.0-rc-2025-08-15; - import wasi:cli/stderr@0.3.0-rc-2025-08-15; + import wasi:cli/stdout@0.3.0-rc-2025-09-16; + import wasi:cli/stderr@0.3.0-rc-2025-09-16; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. - import wasi:cli/stdin@0.3.0-rc-2025-08-15; + import wasi:cli/stdin@0.3.0-rc-2025-09-16; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index d8933cdcc..8269eea20 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -1,7 +1,7 @@ /// This interface defines all of the types and methods for implementing HTTP /// Requests and Responses, as well as their headers, trailers, and bodies. interface types { - use wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15.{duration}; + use wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16.{duration}; /// This type corresponds to HTTP standard Methods. variant method { From afae8b84a60c2ef51b422c7c962d0e98890591f4 Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Mon, 22 Sep 2025 08:04:32 -0700 Subject: [PATCH 1744/1772] feat: Avoid nonstandard use of names for types in wit-0.3.0-draft (#79) * Avoid nonstandard use of names for types in wit-0.3.0-draft Co-authored-by: Philip Chimento * update one new use of "instant" --------- Co-authored-by: Philip Chimento --- proposals/clocks/README.md | 18 +++++----- .../wit-0.3.0-draft/monotonic-clock.wit | 12 +++---- .../{wall-clock.wit => system-clock.wit} | 35 ++++++++++++------- proposals/clocks/wit-0.3.0-draft/timezone.wit | 12 +++---- proposals/clocks/wit-0.3.0-draft/world.wit | 2 +- 5 files changed, 45 insertions(+), 34 deletions(-) rename proposals/clocks/wit-0.3.0-draft/{wall-clock.wit => system-clock.wit} (57%) diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index cd01d6916..2beab9c7c 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -71,20 +71,20 @@ default-monotonic-clock: monotonic-clock ``` ```rust - let start: Instant = monotonic_clock::now(clock); + let start: Mark = monotonic_clock::now(clock); // some stuff - let stop: Instant = monotonic_clock::now(clock); + let stop: Mark = monotonic_clock::now(clock); - let elapsed: Instant = stop - start; + let elapsed: Duration = stop - start; ``` #### Telling the current human time: ```rust - let the_current_time = wall_clock::now(); + let the_current_time = system_clock::now(); println!("it has been {} seconds and {} nanoseconds since the Unix epoch!", the_current_time.seconds, the_current_time.nanoseconds); ``` @@ -92,9 +92,9 @@ default-monotonic-clock: monotonic-clock #### Retrieving the timezone: ```rust - let datetime: Datetime = wall_clock::now(); + let instant: Instant = system_clock::now(); - let timezone_display: TimezoneDisplay = timezone::display(datetime); + let timezone_display: TimezoneDisplay = timezone::display(instant); println!("the timezone is {}", timezone_display.name); ``` @@ -105,14 +105,14 @@ default-monotonic-clock: monotonic-clock In POSIX, `clock_gettime` uses a single `timespec` type to represent timestamps from all clocks, with two fields: seconds and nanoseconds. However, in applications -that just need to measure elapsed time, and don't need to care about wall clock +that just need to measure elapsed time, and don't need to care about absolute time, working with seconds and nanoseconds as separate fields adds extra code size and complexity. For these use cases, a single 64-bit nanoseconds value, which can measure up to about 584 years, is sufficient and simpler. -For wall clock time, it's still useful to have both seconds and nanoseconds, both +For system time, it's still useful to have both seconds and nanoseconds, both to be able to represent dates in the far future, and to reflect the fact that -code working with wall clock time will often want to treat seconds and fractions +code working with system time will often want to treat seconds and fractions of seconds differently. And so, this API uses different data types for different types of clocks. diff --git a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit index a91d495c6..7f364665a 100644 --- a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit +++ b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit @@ -11,11 +11,11 @@ package wasi:clocks@0.3.0-rc-2025-09-16; interface monotonic-clock { use types.{duration}; - /// An instant in time, in nanoseconds. An instant is relative to an + /// A mark on a monotonic clock is a number of nanoseconds since an /// unspecified initial value, and can only be compared to instances from /// the same monotonic-clock. @since(version = 0.3.0-rc-2025-09-16) - type instant = u64; + type mark = u64; /// Read the current value of the clock. /// @@ -23,21 +23,21 @@ interface monotonic-clock { /// produce a sequence of non-decreasing values. /// /// For completeness, this function traps if it's not possible to represent - /// the value of the clock in an `instant`. Consequently, implementations + /// the value of the clock in a `mark`. Consequently, implementations /// should ensure that the starting time is low enough to avoid the /// possibility of overflow in practice. @since(version = 0.3.0-rc-2025-09-16) - now: func() -> instant; + now: func() -> mark; /// Query the resolution of the clock. Returns the duration of time /// corresponding to a clock tick. @since(version = 0.3.0-rc-2025-09-16) get-resolution: func() -> duration; - /// Wait until the specified instant has occurred. + /// Wait until the specified mark has occurred. @since(version = 0.3.0-rc-2025-09-16) wait-until: async func( - when: instant, + when: mark, ); /// Wait for the specified duration to elapse. diff --git a/proposals/clocks/wit-0.3.0-draft/wall-clock.wit b/proposals/clocks/wit-0.3.0-draft/system-clock.wit similarity index 57% rename from proposals/clocks/wit-0.3.0-draft/wall-clock.wit rename to proposals/clocks/wit-0.3.0-draft/system-clock.wit index ea940500f..4d02d98a6 100644 --- a/proposals/clocks/wit-0.3.0-draft/wall-clock.wit +++ b/proposals/clocks/wit-0.3.0-draft/system-clock.wit @@ -1,27 +1,38 @@ package wasi:clocks@0.3.0-rc-2025-09-16; -/// WASI Wall Clock is a clock API intended to let users query the current -/// time. The name "wall" makes an analogy to a "clock on the wall", which -/// is not necessarily monotonic as it may be reset. +/// WASI System Clock is a clock API intended to let users query the current +/// time. The clock is not necessarily monotonic as it may be reset. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. /// -/// A wall clock is a clock which measures the date and time according to -/// some external reference. -/// /// External references may be reset, so this clock is not necessarily /// monotonic, making it unsuitable for measuring elapsed time. /// /// It is intended for reporting the current date and time for humans. @since(version = 0.3.0-rc-2025-09-16) -interface wall-clock { - /// A time and date in seconds plus nanoseconds. +interface system-clock { + /// An "instant", or "exact time", is a point in time without regard to any + /// time zone: just the time since a particular external reference point, + /// often called an "epoch". + /// Note that even if the seconds field is negative, incrementing + /// nanoseconds always represents moving forwards in time. + /// For example, `{ -1 seconds, 999999999 nanoseconds }` represents the + /// instant one nanosecond before the epoch. + /// For more on various different ways to represent time, see + /// https://tc39.es/proposal-temporal/docs/timezone.html @since(version = 0.3.0-rc-2025-09-16) - record datetime { - seconds: u64, + record instant { + seconds: s64, nanoseconds: u32, } + /// A duration of time, in seconds plus nanoseconds. + @since(version = 0.3.0-rc-2025-09-16) + type duration = { + seconds: u64, + nanoseconds: u32, + }; + /// Read the current value of the clock. /// /// This clock is not monotonic, therefore calling this function repeatedly @@ -36,11 +47,11 @@ interface wall-clock { /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time @since(version = 0.3.0-rc-2025-09-16) - now: func() -> datetime; + now: func() -> instant; /// Query the resolution of the clock. /// /// The nanoseconds field of the output is always less than 1000000000. @since(version = 0.3.0-rc-2025-09-16) - get-resolution: func() -> datetime; + get-resolution: func() -> duration; } diff --git a/proposals/clocks/wit-0.3.0-draft/timezone.wit b/proposals/clocks/wit-0.3.0-draft/timezone.wit index ab8f5c080..508e01883 100644 --- a/proposals/clocks/wit-0.3.0-draft/timezone.wit +++ b/proposals/clocks/wit-0.3.0-draft/timezone.wit @@ -3,23 +3,23 @@ package wasi:clocks@0.3.0-rc-2025-09-16; @unstable(feature = clocks-timezone) interface timezone { @unstable(feature = clocks-timezone) - use wall-clock.{datetime}; + use system-clock.{instant}; - /// Return information needed to display the given `datetime`. This includes + /// Return information needed to display the given `instant`. This includes /// the UTC offset, the time zone name, and a flag indicating whether /// daylight saving time is active. /// - /// If the timezone cannot be determined for the given `datetime`, return a + /// If the timezone cannot be determined for the given `instant`, return a /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight /// saving time. @unstable(feature = clocks-timezone) - display: func(when: datetime) -> timezone-display; + display: func(when: instant) -> timezone-display; /// The same as `display`, but only return the UTC offset. @unstable(feature = clocks-timezone) - utc-offset: func(when: datetime) -> s32; + utc-offset: func(when: instant) -> s32; - /// Information useful for displaying the timezone of a specific `datetime`. + /// Information useful for displaying the timezone of a specific `instant`. /// /// This information may vary within a single `timezone` to reflect daylight /// saving time adjustments. diff --git a/proposals/clocks/wit-0.3.0-draft/world.wit b/proposals/clocks/wit-0.3.0-draft/world.wit index a6b885f07..f274bceb0 100644 --- a/proposals/clocks/wit-0.3.0-draft/world.wit +++ b/proposals/clocks/wit-0.3.0-draft/world.wit @@ -5,7 +5,7 @@ world imports { @since(version = 0.3.0-rc-2025-09-16) import monotonic-clock; @since(version = 0.3.0-rc-2025-09-16) - import wall-clock; + import system-clock; @unstable(feature = clocks-timezone) import timezone; } From 6f69e6d3572f605ba6eaa05574ad0aa6df531268 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Fri, 26 Sep 2025 16:10:58 -0700 Subject: [PATCH 1745/1772] Feat: Timezone improvements (#71) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Change docs to refer to "currently configured time zone" The "timezone of an instant" is a misnomer because the `instant` type doesn't carry timezone information. The host has a currently configured time zone (or has no such concept, in which case the only sensible thing to do is use UTC). * Remove "in-daylight-saving-time" flag This flag is problematic because when a time zone is "in DST" is not well defined. Most time zones in the world don't use DST at all. Of the ones that do, most go to DST during the summer for half the year, but not all. For example, the function in Moment.js that provides this functionality comes with a giant caveat: https://momentjs.com/docs/#/query/is-daylight-saving-time/ * Rename "timezone-display::name" to "id" Other possibilities: "tzid", "iana-id", "identifier", "iana-identifier". Returning a user-displayable name as part of timezone-display would require more information: the user's preferred language, and the preferred style for the name: - abbreviated or not - year-round or specific to the Instant E.g., the time zone with the IANA id "America/Los_Angeles" might be displayed as "Pacific Time", "Pacific Standard Time", "Pacific Daylight Time", "PT", "PST", "PDT", "Nordamerikanische Westküstenzeit"... The Rust iana_time_zone crate uses IANA time zone IDs, so if this interface needs to be able to implement iana_time_zone, timezone-display should have an IANA ID and not a user-displayable name. * Measure UTC offset in nanoseconds There are time zones that used sub-minute or even sub-second UTC offsets for instants in the past. E.g., when built using Vanguard format, the UTC offset in the TZDB for "Asia/Ho_Chi_Minh" before July 1906 is 7:06:30.133333333. * Refactor timezone-display into separate methods If the timezone-display ID is an IANA ID, and we are going with the approach of not making the localized ("PST" vs "PDT" vs "PT") name part of this component, then the current time zone doesn't depend on the current time. After removing the isDST flag, timezone-display contains two pieces of data, the ID and the UTC offset. The UTC offset is already available via a function that takes an Instant as input. The ID could just be available via its own function that doesn't take any input. In that case there would be no need for timezone-display. * Move Unix Time docs to instant type Instead of only specifying the epoch of the instant returned from now(), specify the epoch of the instant type. It then follows that now() returns an instant with that epoch. * Make time zone methods return optional types We wish to be able to represent "is completely unaware of time zones" or "failure to discover a time zone" in the API, distinct from a host that always uses UTC. * Add timezone::to-debug-string method * Remove system-clock::duration Use types::duration for the return type of get-resolution instead. It supports durations up to 584 years which is more than sufficient for any clock resolution. (A more capable duration type would be needed if we were doing any arithmetic between instants.) --- proposals/clocks/README.md | 7 +- .../clocks/wit-0.3.0-draft/system-clock.wit | 28 +++----- proposals/clocks/wit-0.3.0-draft/timezone.wit | 71 ++++++++----------- 3 files changed, 45 insertions(+), 61 deletions(-) diff --git a/proposals/clocks/README.md b/proposals/clocks/README.md index 2beab9c7c..a99080fae 100644 --- a/proposals/clocks/README.md +++ b/proposals/clocks/README.md @@ -93,10 +93,9 @@ default-monotonic-clock: monotonic-clock ```rust let instant: Instant = system_clock::now(); - - let timezone_display: TimezoneDisplay = timezone::display(instant); - - println!("the timezone is {}", timezone_display.name); + let id = timezone::id(); + let offset_h = timezone::utc_offset(instant) as f64 / 3600e9; + println!("the timezone is {} at UTC{:+}", id, offset_h); ``` ### Detailed design discussion diff --git a/proposals/clocks/wit-0.3.0-draft/system-clock.wit b/proposals/clocks/wit-0.3.0-draft/system-clock.wit index 4d02d98a6..bd3049fd4 100644 --- a/proposals/clocks/wit-0.3.0-draft/system-clock.wit +++ b/proposals/clocks/wit-0.3.0-draft/system-clock.wit @@ -11,47 +11,41 @@ package wasi:clocks@0.3.0-rc-2025-09-16; /// It is intended for reporting the current date and time for humans. @since(version = 0.3.0-rc-2025-09-16) interface system-clock { + use types.{duration}; + /// An "instant", or "exact time", is a point in time without regard to any /// time zone: just the time since a particular external reference point, /// often called an "epoch". + /// + /// Here, the epoch is 1970-01-01T00:00:00Z, also known as + /// [POSIX's Seconds Since the Epoch], also known as [Unix Time]. + /// /// Note that even if the seconds field is negative, incrementing /// nanoseconds always represents moving forwards in time. /// For example, `{ -1 seconds, 999999999 nanoseconds }` represents the /// instant one nanosecond before the epoch. /// For more on various different ways to represent time, see /// https://tc39.es/proposal-temporal/docs/timezone.html + /// + /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 + /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time @since(version = 0.3.0-rc-2025-09-16) record instant { seconds: s64, nanoseconds: u32, } - /// A duration of time, in seconds plus nanoseconds. - @since(version = 0.3.0-rc-2025-09-16) - type duration = { - seconds: u64, - nanoseconds: u32, - }; - /// Read the current value of the clock. /// /// This clock is not monotonic, therefore calling this function repeatedly /// will not necessarily produce a sequence of non-decreasing values. /// - /// The returned timestamps represent the number of seconds since - /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], - /// also known as [Unix Time]. - /// /// The nanoseconds field of the output is always less than 1000000000. - /// - /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 - /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time @since(version = 0.3.0-rc-2025-09-16) now: func() -> instant; - /// Query the resolution of the clock. - /// - /// The nanoseconds field of the output is always less than 1000000000. + /// Query the resolution of the clock. Returns the smallest duration of time + /// that the implementation permits distinguishing. @since(version = 0.3.0-rc-2025-09-16) get-resolution: func() -> duration; } diff --git a/proposals/clocks/wit-0.3.0-draft/timezone.wit b/proposals/clocks/wit-0.3.0-draft/timezone.wit index 508e01883..d8d5732dc 100644 --- a/proposals/clocks/wit-0.3.0-draft/timezone.wit +++ b/proposals/clocks/wit-0.3.0-draft/timezone.wit @@ -5,51 +5,42 @@ interface timezone { @unstable(feature = clocks-timezone) use system-clock.{instant}; - /// Return information needed to display the given `instant`. This includes - /// the UTC offset, the time zone name, and a flag indicating whether - /// daylight saving time is active. + /// Return the IANA identifier of the currently configured timezone. This + /// should be an identifier from the IANA Time Zone Database. /// - /// If the timezone cannot be determined for the given `instant`, return a - /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight - /// saving time. + /// For displaying to a user, the identifier should be converted into a + /// localized name by means of an internationalization API. + /// + /// If the implementation does not expose an actual timezone, or is unable + /// to provide mappings from times to deltas between the configured timezone + /// and UTC, or determining the current timezone fails, or the timezone does + /// not have an IANA identifier, this returns nothing. @unstable(feature = clocks-timezone) - display: func(when: instant) -> timezone-display; + iana-id: func() -> option; - /// The same as `display`, but only return the UTC offset. + /// The number of nanoseconds difference between UTC time and the local + /// time of the currently configured timezone, at the exact time of + /// `instant`. + /// + /// The magnitude of the returned value will always be less than + /// 86,400,000,000,000 which is the number of nanoseconds in a day + /// (24*60*60*1e9). + /// + /// If the implementation does not expose an actual timezone, or is unable + /// to provide mappings from times to deltas between the configured timezone + /// and UTC, or determining the current timezone fails, this returns + /// nothing. @unstable(feature = clocks-timezone) - utc-offset: func(when: instant) -> s32; + utc-offset: func(when: instant) -> option; - /// Information useful for displaying the timezone of a specific `instant`. + /// Returns a string that is suitable to assist humans in debugging whether + /// any timezone is available, and if so, which. This may be the same string + /// as `iana-id`, or a formatted representation of the UTC offset such as + /// `-04:00`, or something else. /// - /// This information may vary within a single `timezone` to reflect daylight - /// saving time adjustments. + /// WARNING: The returned string should not be consumed mechanically! It may + /// change across platforms, hosts, or other implementation details. Parsing + /// this string is a major platform-compatibility hazard. @unstable(feature = clocks-timezone) - record timezone-display { - /// The number of seconds difference between UTC time and the local - /// time of the timezone. - /// - /// The returned value will always be less than 86400 which is the - /// number of seconds in a day (24*60*60). - /// - /// In implementations that do not expose an actual time zone, this - /// should return 0. - utc-offset: s32, - - /// The abbreviated name of the timezone to display to a user. The name - /// `UTC` indicates Coordinated Universal Time. Otherwise, this should - /// reference local standards for the name of the time zone. - /// - /// In implementations that do not expose an actual time zone, this - /// should be the string `UTC`. - /// - /// In time zones that do not have an applicable name, a formatted - /// representation of the UTC offset may be returned, such as `-04:00`. - name: string, - - /// Whether daylight saving time is active. - /// - /// In implementations that do not expose an actual time zone, this - /// should return false. - in-daylight-saving-time: bool, - } + to-debug-string: func() -> string; } From 2b0b3177a871134aee6968d39f60bfdac35e6f9b Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Mon, 6 Oct 2025 10:12:11 -0700 Subject: [PATCH 1746/1772] use new clocks/types.{duration} instead of clocks/monotonic (#191) --- proposals/http/wit-0.3.0-draft/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit index 8269eea20..0f0e83851 100644 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ b/proposals/http/wit-0.3.0-draft/types.wit @@ -1,7 +1,7 @@ /// This interface defines all of the types and methods for implementing HTTP /// Requests and Responses, as well as their headers, trailers, and bodies. interface types { - use wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16.{duration}; + use wasi:clocks/types@0.3.0-rc-2025-09-16.{duration}; /// This type corresponds to HTTP standard Methods. variant method { From b7ef60b50d95f9a56ee02f3f4c096a3f902d7a17 Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Tue, 30 Sep 2025 14:24:05 -0700 Subject: [PATCH 1747/1772] use new clocks/types.{duration} instead of clocks/monotonic --- proposals/sockets/wit-0.3.0-draft/types.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit index 2ed1912e4..fdafa5777 100644 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ b/proposals/sockets/wit-0.3.0-draft/types.wit @@ -1,7 +1,7 @@ @since(version = 0.3.0-rc-2025-09-16) interface types { @since(version = 0.3.0-rc-2025-09-16) - use wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16.{duration}; + use wasi:clocks/types@0.3.0-rc-2025-09-16.{duration}; /// Error codes. /// From 34b716c26f51bcfd5e12d112a4aed3241f064e07 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 14:42:46 +0000 Subject: [PATCH 1748/1772] Update to v0.2.8 --- proposals/random/imports.md | 12 ++++++------ proposals/random/wit/insecure-seed.wit | 2 +- proposals/random/wit/insecure.wit | 2 +- proposals/random/wit/random.wit | 2 +- proposals/random/wit/world.wit | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/random/imports.md b/proposals/random/imports.md index 9e1d2f21c..d283771b6 100644 --- a/proposals/random/imports.md +++ b/proposals/random/imports.md @@ -2,13 +2,13 @@ -

                                Import interface wasi:random/random@0.2.7

                                +

                                Import interface wasi:random/random@0.2.8

                                WASI Random is a random data API.

                                It is intended to be portable at least between Unix-family platforms and Windows.

                                @@ -41,7 +41,7 @@ represented as a u64.

                                • u64
                                -

                                Import interface wasi:random/insecure@0.2.7

                                +

                                Import interface wasi:random/insecure@0.2.8

                                The insecure interface for insecure pseudo-random numbers.

                                It is intended to be portable at least between Unix-family platforms and Windows.

                                @@ -70,7 +70,7 @@ a long period.

                                • u64
                                -

                                Import interface wasi:random/insecure-seed@0.2.7

                                +

                                Import interface wasi:random/insecure-seed@0.2.8

                                The insecure-seed interface for seeding hash-map DoS resistance.

                                It is intended to be portable at least between Unix-family platforms and Windows.

                                diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index 0209b84b0..b2b435e55 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index 820d069ee..6dc77adec 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 974ab465d..524e77d4a 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index 333b42598..c0c3272c9 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; @since(version = 0.2.0) world imports { From 8e909932111173f1faef82fad0c00b56d935bda2 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Tue, 7 Oct 2025 10:45:18 -0400 Subject: [PATCH 1749/1772] Revert "Release v0.2.8" --- proposals/random/imports.md | 12 ++++++------ proposals/random/wit/insecure-seed.wit | 2 +- proposals/random/wit/insecure.wit | 2 +- proposals/random/wit/random.wit | 2 +- proposals/random/wit/world.wit | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/random/imports.md b/proposals/random/imports.md index d283771b6..9e1d2f21c 100644 --- a/proposals/random/imports.md +++ b/proposals/random/imports.md @@ -2,13 +2,13 @@ -

                                Import interface wasi:random/random@0.2.8

                                +

                                Import interface wasi:random/random@0.2.7

                                WASI Random is a random data API.

                                It is intended to be portable at least between Unix-family platforms and Windows.

                                @@ -41,7 +41,7 @@ represented as a u64.

                                • u64
                                -

                                Import interface wasi:random/insecure@0.2.8

                                +

                                Import interface wasi:random/insecure@0.2.7

                                The insecure interface for insecure pseudo-random numbers.

                                It is intended to be portable at least between Unix-family platforms and Windows.

                                @@ -70,7 +70,7 @@ a long period.

                                • u64
                                -

                                Import interface wasi:random/insecure-seed@0.2.8

                                +

                                Import interface wasi:random/insecure-seed@0.2.7

                                The insecure-seed interface for seeding hash-map DoS resistance.

                                It is intended to be portable at least between Unix-family platforms and Windows.

                                diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index b2b435e55..0209b84b0 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.8; +package wasi:random@0.2.7; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index 6dc77adec..820d069ee 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.8; +package wasi:random@0.2.7; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 524e77d4a..974ab465d 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.8; +package wasi:random@0.2.7; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index c0c3272c9..333b42598 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.8; +package wasi:random@0.2.7; @since(version = 0.2.0) world imports { From 036fca9f5e3679582ea77863535da0f0628cec43 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 14:49:00 +0000 Subject: [PATCH 1750/1772] Update to v0.2.8 --- proposals/random/imports.md | 12 ++++++------ proposals/random/wit/insecure-seed.wit | 2 +- proposals/random/wit/insecure.wit | 2 +- proposals/random/wit/random.wit | 2 +- proposals/random/wit/world.wit | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/proposals/random/imports.md b/proposals/random/imports.md index 9e1d2f21c..d283771b6 100644 --- a/proposals/random/imports.md +++ b/proposals/random/imports.md @@ -2,13 +2,13 @@ -

                                Import interface wasi:random/random@0.2.7

                                +

                                Import interface wasi:random/random@0.2.8

                                WASI Random is a random data API.

                                It is intended to be portable at least between Unix-family platforms and Windows.

                                @@ -41,7 +41,7 @@ represented as a u64.

                                • u64
                                -

                                Import interface wasi:random/insecure@0.2.7

                                +

                                Import interface wasi:random/insecure@0.2.8

                                The insecure interface for insecure pseudo-random numbers.

                                It is intended to be portable at least between Unix-family platforms and Windows.

                                @@ -70,7 +70,7 @@ a long period.

                                • u64
                                -

                                Import interface wasi:random/insecure-seed@0.2.7

                                +

                                Import interface wasi:random/insecure-seed@0.2.8

                                The insecure-seed interface for seeding hash-map DoS resistance.

                                It is intended to be portable at least between Unix-family platforms and Windows.

                                diff --git a/proposals/random/wit/insecure-seed.wit b/proposals/random/wit/insecure-seed.wit index 0209b84b0..b2b435e55 100644 --- a/proposals/random/wit/insecure-seed.wit +++ b/proposals/random/wit/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/insecure.wit b/proposals/random/wit/insecure.wit index 820d069ee..6dc77adec 100644 --- a/proposals/random/wit/insecure.wit +++ b/proposals/random/wit/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/random.wit b/proposals/random/wit/random.wit index 974ab465d..524e77d4a 100644 --- a/proposals/random/wit/random.wit +++ b/proposals/random/wit/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/random/wit/world.wit b/proposals/random/wit/world.wit index 333b42598..c0c3272c9 100644 --- a/proposals/random/wit/world.wit +++ b/proposals/random/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; @since(version = 0.2.0) world imports { From 0ba9e5d1fba75fd8ba114bfdb67bd5bd011866a1 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Tue, 7 Oct 2025 10:59:02 -0400 Subject: [PATCH 1751/1772] fix: incorrect revert, 0.2.7 pin --- proposals/clocks/imports.md | 16 ++++---- proposals/clocks/wit/deps.lock | 4 +- proposals/clocks/wit/deps/io/error.wit | 2 +- proposals/clocks/wit/deps/io/poll.wit | 2 +- proposals/clocks/wit/deps/io/streams.wit | 52 +++++------------------- proposals/clocks/wit/deps/io/world.wit | 2 +- proposals/clocks/wit/monotonic-clock.wit | 4 +- proposals/clocks/wit/timezone.wit | 2 +- proposals/clocks/wit/wall-clock.wit | 2 +- proposals/clocks/wit/world.wit | 2 +- 10 files changed, 28 insertions(+), 60 deletions(-) diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index 0f74163d8..a0c88a0cc 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -2,14 +2,14 @@ -

                                Import interface wasi:io/poll@0.2.5

                                +

                                Import interface wasi:io/poll@0.2.7

                                A poll API intended to let users wait for I/O events on multiple handles at once.


                                @@ -62,7 +62,7 @@ being ready for I/O.

                                • list<u32>
                                -

                                Import interface wasi:clocks/monotonic-clock@0.2.5

                                +

                                Import interface wasi:clocks/monotonic-clock@0.2.7

                                WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                                It is intended to be portable at least between Unix-family platforms and @@ -125,7 +125,7 @@ elapsed from the time this function is invoked.

                                -

                                Import interface wasi:clocks/wall-clock@0.2.5

                                +

                                Import interface wasi:clocks/wall-clock@0.2.7

                                WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                                @@ -166,7 +166,7 @@ also known as Unix Time.
                              • datetime
                              -

                              Import interface wasi:clocks/timezone@0.2.5

                              +

                              Import interface wasi:clocks/timezone@0.2.7


                              Types

                              type datetime

                              diff --git a/proposals/clocks/wit/deps.lock b/proposals/clocks/wit/deps.lock index 53e7b56f7..bac974df3 100644 --- a/proposals/clocks/wit/deps.lock +++ b/proposals/clocks/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "749de54c05f7118dc118999ad69c5b63890ea1dd86f1be69270062195c7b79c2" -sha512 = "b5096d518a7931c100594b9216bb4a98cd64533166bc7fdbb7465b48effc345863bd3ce2ec84fef59b273bae507edab08ec08975d56240ccef68f2494964e80a" +sha256 = "62ae80f2e340cddbac8e94f78e6270735aea536367ecb98de5f4ac6aef66b5c4" +sha512 = "a02a1ebd261ae884b0315b3528d1a93819ddc4b616f66c77f2bea9dd1de888208dc3b9004a553363f5e8491ea925d65ebbd0d68eaa87238316b47469a3bf97bb" diff --git a/proposals/clocks/wit/deps/io/error.wit b/proposals/clocks/wit/deps/io/error.wit index 0e234bebd..acab3a811 100644 --- a/proposals/clocks/wit/deps/io/error.wit +++ b/proposals/clocks/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.7; @since(version = 0.2.0) interface error { diff --git a/proposals/clocks/wit/deps/io/poll.wit b/proposals/clocks/wit/deps/io/poll.wit index d33353e2a..a525164b9 100644 --- a/proposals/clocks/wit/deps/io/poll.wit +++ b/proposals/clocks/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.7; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/clocks/wit/deps/io/streams.wit b/proposals/clocks/wit/deps/io/streams.wit index 8d20252f8..7ae29a3cd 100644 --- a/proposals/clocks/wit/deps/io/streams.wit +++ b/proposals/clocks/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.7; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. @@ -154,27 +154,13 @@ interface streams { /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write`, and `flush`, and is implemented with the - /// following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while !contents.is_empty() { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, contents.len()); - /// let (chunk, rest) = contents.split_at(len); - /// this.write(chunk ); // eliding error handling - /// contents = rest; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` + /// Returns success when all of the contents written are successfully + /// flushed to output. If an error occurs at any point before all + /// contents are successfully flushed, that error is returned as soon as + /// possible. If writing and flushing the complete contents causes the + /// stream to become closed, this call should return success, and + /// subsequent calls to check-write or other interfaces should return + /// stream-error::closed. @since(version = 0.2.0) blocking-write-and-flush: func( contents: list @@ -227,26 +213,8 @@ interface streams { /// Block until all of these operations are complete, or an error /// occurs. /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with - /// the following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while num_zeroes != 0 { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, num_zeroes); - /// this.write-zeroes(len); // eliding error handling - /// num_zeroes -= len; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` + /// Functionality is equivelant to `blocking-write-and-flush` with + /// contents given as a list of len containing only zeroes. @since(version = 0.2.0) blocking-write-zeroes-and-flush: func( /// The number of zero-bytes to write diff --git a/proposals/clocks/wit/deps/io/world.wit b/proposals/clocks/wit/deps/io/world.wit index 686418343..73b1a6df5 100644 --- a/proposals/clocks/wit/deps/io/world.wit +++ b/proposals/clocks/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.5; +package wasi:io@0.2.7; @since(version = 0.2.0) world imports { diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index 6ebd14e59..8ef1c2a29 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.7; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.5; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.5.{pollable}; + use wasi:io/poll@0.2.7.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/clocks/wit/timezone.wit b/proposals/clocks/wit/timezone.wit index ebe21a6e8..4740bde00 100644 --- a/proposals/clocks/wit/timezone.wit +++ b/proposals/clocks/wit/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.7; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/clocks/wit/wall-clock.wit b/proposals/clocks/wit/wall-clock.wit index 2fde831bd..2179b6c56 100644 --- a/proposals/clocks/wit/wall-clock.wit +++ b/proposals/clocks/wit/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.7; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index f32eed546..a08ff2c2c 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.5; +package wasi:clocks@0.2.7; @since(version = 0.2.0) world imports { From 1c2668e6626352d6517ea70f1284eebaf8068c0e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 15:09:30 +0000 Subject: [PATCH 1752/1772] Update to v0.2.8 --- proposals/io/imports.md | 18 +++++++++--------- proposals/io/wit/error.wit | 2 +- proposals/io/wit/poll.wit | 2 +- proposals/io/wit/streams.wit | 2 +- proposals/io/wit/world.wit | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index a64a3d09d..8a884a370 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -2,13 +2,13 @@ -

                              Import interface wasi:io/error@0.2.7

                              +

                              Import interface wasi:io/error@0.2.8


                              Types

                              resource error

                              @@ -41,7 +41,7 @@ hazard.

                              • string
                              -

                              Import interface wasi:io/poll@0.2.7

                              +

                              Import interface wasi:io/poll@0.2.8

                              A poll API intended to let users wait for I/O events on multiple handles at once.


                              @@ -94,7 +94,7 @@ being ready for I/O.

                              • list<u32>
                              -

                              Import interface wasi:io/streams@0.2.7

                              +

                              Import interface wasi:io/streams@0.2.8

                              WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                              In the future, the component model is expected to add built-in stream types; @@ -104,10 +104,10 @@ when it does, they are expected to subsume this API.

                              type error

                              error

                              -#### `type pollable` -[`pollable`](#pollable) +

                              type pollable

                              +

                              pollable

                              -#### `variant stream-error` +

                              variant stream-error

                              An error for input-stream and output-stream operations.

                              Variant Cases
                                diff --git a/proposals/io/wit/error.wit b/proposals/io/wit/error.wit index acab3a811..dd5a1af03 100644 --- a/proposals/io/wit/error.wit +++ b/proposals/io/wit/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; @since(version = 0.2.0) interface error { diff --git a/proposals/io/wit/poll.wit b/proposals/io/wit/poll.wit index a525164b9..833b381d9 100644 --- a/proposals/io/wit/poll.wit +++ b/proposals/io/wit/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/io/wit/streams.wit b/proposals/io/wit/streams.wit index 7ae29a3cd..fbb0268b0 100644 --- a/proposals/io/wit/streams.wit +++ b/proposals/io/wit/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/io/wit/world.wit b/proposals/io/wit/world.wit index 73b1a6df5..1cc3fce12 100644 --- a/proposals/io/wit/world.wit +++ b/proposals/io/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; @since(version = 0.2.0) world imports { From 98c51bec0d2037e6109a69cbdabb4bf1a68990a8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 15:11:53 +0000 Subject: [PATCH 1753/1772] Update to v0.2.8 --- proposals/clocks/imports.md | 22 +++++++++++----------- proposals/clocks/wit/deps.lock | 4 ++-- proposals/clocks/wit/deps/io/error.wit | 2 +- proposals/clocks/wit/deps/io/poll.wit | 2 +- proposals/clocks/wit/deps/io/streams.wit | 2 +- proposals/clocks/wit/deps/io/world.wit | 2 +- proposals/clocks/wit/monotonic-clock.wit | 4 ++-- proposals/clocks/wit/timezone.wit | 2 +- proposals/clocks/wit/wall-clock.wit | 2 +- proposals/clocks/wit/world.wit | 2 +- 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/proposals/clocks/imports.md b/proposals/clocks/imports.md index a0c88a0cc..bc5c90e20 100644 --- a/proposals/clocks/imports.md +++ b/proposals/clocks/imports.md @@ -2,14 +2,14 @@ -

                                Import interface wasi:io/poll@0.2.7

                                +

                                Import interface wasi:io/poll@0.2.8

                                A poll API intended to let users wait for I/O events on multiple handles at once.


                                @@ -62,7 +62,7 @@ being ready for I/O.

                                • list<u32>
                                -

                                Import interface wasi:clocks/monotonic-clock@0.2.7

                                +

                                Import interface wasi:clocks/monotonic-clock@0.2.8

                                WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                                It is intended to be portable at least between Unix-family platforms and @@ -74,8 +74,8 @@ successive reads of the clock will produce non-decreasing values.

                                type pollable

                                pollable

                                -#### `type instant` -`u64` +

                                type instant

                                +

                                u64

                                An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. @@ -125,7 +125,7 @@ elapsed from the time this function is invoked.

                                -

                                Import interface wasi:clocks/wall-clock@0.2.7

                                +

                                Import interface wasi:clocks/wall-clock@0.2.8

                                WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                                @@ -166,13 +166,13 @@ also known as Unix Time.
                              • datetime
                              -

                              Import interface wasi:clocks/timezone@0.2.7

                              +

                              Import interface wasi:clocks/timezone@0.2.8


                              Types

                              type datetime

                              datetime

                              -#### `record timezone-display` +

                              record timezone-display

                              Information useful for displaying the timezone of a specific datetime.

                              This information may vary within a single timezone to reflect daylight saving time adjustments.

                              diff --git a/proposals/clocks/wit/deps.lock b/proposals/clocks/wit/deps.lock index bac974df3..cc63e4b2f 100644 --- a/proposals/clocks/wit/deps.lock +++ b/proposals/clocks/wit/deps.lock @@ -1,4 +1,4 @@ [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "62ae80f2e340cddbac8e94f78e6270735aea536367ecb98de5f4ac6aef66b5c4" -sha512 = "a02a1ebd261ae884b0315b3528d1a93819ddc4b616f66c77f2bea9dd1de888208dc3b9004a553363f5e8491ea925d65ebbd0d68eaa87238316b47469a3bf97bb" +sha256 = "9f1ad5da70f621bbd4c69e3bd90250a0c12ecfde266aa8f99684fc44bc1e7c15" +sha512 = "6d0a9db6848f24762933d1c168a5b5b1065ba838c253ee20454afeb8dd1a049b918d25deff556083d68095dd3126ae131ac3e738774320eee5d918f5a4b5354e" diff --git a/proposals/clocks/wit/deps/io/error.wit b/proposals/clocks/wit/deps/io/error.wit index acab3a811..dd5a1af03 100644 --- a/proposals/clocks/wit/deps/io/error.wit +++ b/proposals/clocks/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; @since(version = 0.2.0) interface error { diff --git a/proposals/clocks/wit/deps/io/poll.wit b/proposals/clocks/wit/deps/io/poll.wit index a525164b9..833b381d9 100644 --- a/proposals/clocks/wit/deps/io/poll.wit +++ b/proposals/clocks/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/clocks/wit/deps/io/streams.wit b/proposals/clocks/wit/deps/io/streams.wit index 7ae29a3cd..fbb0268b0 100644 --- a/proposals/clocks/wit/deps/io/streams.wit +++ b/proposals/clocks/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/clocks/wit/deps/io/world.wit b/proposals/clocks/wit/deps/io/world.wit index 73b1a6df5..1cc3fce12 100644 --- a/proposals/clocks/wit/deps/io/world.wit +++ b/proposals/clocks/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/clocks/wit/monotonic-clock.wit b/proposals/clocks/wit/monotonic-clock.wit index 8ef1c2a29..e60f366f2 100644 --- a/proposals/clocks/wit/monotonic-clock.wit +++ b/proposals/clocks/wit/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.7; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from diff --git a/proposals/clocks/wit/timezone.wit b/proposals/clocks/wit/timezone.wit index 4740bde00..534814a63 100644 --- a/proposals/clocks/wit/timezone.wit +++ b/proposals/clocks/wit/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/clocks/wit/wall-clock.wit b/proposals/clocks/wit/wall-clock.wit index 2179b6c56..3386c800b 100644 --- a/proposals/clocks/wit/wall-clock.wit +++ b/proposals/clocks/wit/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/clocks/wit/world.wit b/proposals/clocks/wit/world.wit index a08ff2c2c..1655ca830 100644 --- a/proposals/clocks/wit/world.wit +++ b/proposals/clocks/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; @since(version = 0.2.0) world imports { From 1d2f2f00a2e163808ace1e435edeba2f3b04b789 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 15:14:36 +0000 Subject: [PATCH 1754/1772] Update to v0.2.8 --- proposals/filesystem/imports.md | 48 +++++++++---------- proposals/filesystem/wit/deps.lock | 8 ++-- .../wit/deps/clocks/monotonic-clock.wit | 9 +++- .../filesystem/wit/deps/clocks/timezone.wit | 2 +- .../filesystem/wit/deps/clocks/wall-clock.wit | 2 +- .../filesystem/wit/deps/clocks/world.wit | 2 +- proposals/filesystem/wit/deps/io/error.wit | 2 +- proposals/filesystem/wit/deps/io/poll.wit | 2 +- proposals/filesystem/wit/deps/io/streams.wit | 2 +- proposals/filesystem/wit/deps/io/world.wit | 2 +- proposals/filesystem/wit/preopens.wit | 2 +- proposals/filesystem/wit/types.wit | 6 +-- proposals/filesystem/wit/world.wit | 2 +- 13 files changed, 47 insertions(+), 42 deletions(-) diff --git a/proposals/filesystem/imports.md b/proposals/filesystem/imports.md index 9a726c743..537c59b68 100644 --- a/proposals/filesystem/imports.md +++ b/proposals/filesystem/imports.md @@ -2,16 +2,16 @@ -

                              Import interface wasi:io/error@0.2.7

                              +

                              Import interface wasi:io/error@0.2.8


                              Types

                              resource error

                              @@ -44,7 +44,7 @@ hazard.

                              • string
                              -

                              Import interface wasi:io/poll@0.2.7

                              +

                              Import interface wasi:io/poll@0.2.8

                              A poll API intended to let users wait for I/O events on multiple handles at once.


                              @@ -97,7 +97,7 @@ being ready for I/O.

                              • list<u32>
                              -

                              Import interface wasi:io/streams@0.2.7

                              +

                              Import interface wasi:io/streams@0.2.8

                              WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                              In the future, the component model is expected to add built-in stream types; @@ -107,10 +107,10 @@ when it does, they are expected to subsume this API.

                              type error

                              error

                              -#### `type pollable` -[`pollable`](#pollable) +

                              type pollable

                              +

                              pollable

                              -#### `variant stream-error` +

                              variant stream-error

                              An error for input-stream and output-stream operations.

                              Variant Cases
                                @@ -399,7 +399,7 @@ is ready for reading, before performing the splice.

                                -

                                Import interface wasi:clocks/wall-clock@0.2.7

                                +

                                Import interface wasi:clocks/wall-clock@0.2.8

                                WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                                @@ -440,7 +440,7 @@ also known as Unix Time.
                              • datetime
                              -

                              Import interface wasi:filesystem/types@0.2.7

                              +

                              Import interface wasi:filesystem/types@0.2.8

                              WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                              @@ -463,17 +463,17 @@ underlying filesystem, the function fails with type input-stream

                              input-stream

                              -#### `type output-stream` -[`output-stream`](#output_stream) +

                              type output-stream

                              +

                              output-stream

                              -#### `type error` -[`error`](#error) +

                              type error

                              +

                              error

                              -#### `type datetime` -[`datetime`](#datetime) +

                              type datetime

                              +

                              datetime

                              -#### `type filesize` -`u64` +

                              type filesize

                              +

                              u64

                              File size or length of a region within a file.

                              enum descriptor-type

                              The type of a filesystem object referenced by a descriptor.

                              @@ -1318,13 +1318,13 @@ errors are filesystem-related errors.

                              -

                              Import interface wasi:filesystem/preopens@0.2.7

                              +

                              Import interface wasi:filesystem/preopens@0.2.8


                              Types

                              type descriptor

                              descriptor

                              ----- +


                              Functions

                              get-directories: func

                              Return the set of preopened directories, and their paths.

                              diff --git a/proposals/filesystem/wit/deps.lock b/proposals/filesystem/wit/deps.lock index 1d550cb8f..b0d60f694 100644 --- a/proposals/filesystem/wit/deps.lock +++ b/proposals/filesystem/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "d0a8d048c41b566b978cd8ecd03fa51ec1f65af4c26be2f0fc9cfdd7dd6f34f3" -sha512 = "8d1c9ddaaea70ae54376bfc02dcdd0437336fb4fc67f89763ce09540caefe84cbae89a8de3605aa7613c49188636e925047bcd150c2c60685850095fefb68b73" +sha256 = "be1d8c61e2544e2b48d902c60df73577e293349063344ce752cda4d323f8b913" +sha512 = "0fd7962c62b135da0e584c2b58a55147bf09873848b0bb5bd3913019bc3f8d4b5969fbd6f7f96fd99a015efaf562a3eeafe3bc13049f8572a6e13ef9ef0e7e75" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "62ae80f2e340cddbac8e94f78e6270735aea536367ecb98de5f4ac6aef66b5c4" -sha512 = "a02a1ebd261ae884b0315b3528d1a93819ddc4b616f66c77f2bea9dd1de888208dc3b9004a553363f5e8491ea925d65ebbd0d68eaa87238316b47469a3bf97bb" +sha256 = "9f1ad5da70f621bbd4c69e3bd90250a0c12ecfde266aa8f99684fc44bc1e7c15" +sha512 = "6d0a9db6848f24762933d1c168a5b5b1065ba838c253ee20454afeb8dd1a049b918d25deff556083d68095dd3126ae131ac3e738774320eee5d918f5a4b5354e" diff --git a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit index 98a9ad42a..e60f366f2 100644 --- a/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.7; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from @@ -26,6 +26,11 @@ interface monotonic-clock { /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + /// + /// For completeness, this function traps if it's not possible to represent + /// the value of the clock in an `instant`. Consequently, implementations + /// should ensure that the starting time is low enough to avoid the + /// possibility of overflow in practice. @since(version = 0.2.0) now: func() -> instant; diff --git a/proposals/filesystem/wit/deps/clocks/timezone.wit b/proposals/filesystem/wit/deps/clocks/timezone.wit index 4740bde00..534814a63 100644 --- a/proposals/filesystem/wit/deps/clocks/timezone.wit +++ b/proposals/filesystem/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/filesystem/wit/deps/clocks/wall-clock.wit b/proposals/filesystem/wit/deps/clocks/wall-clock.wit index 2179b6c56..3386c800b 100644 --- a/proposals/filesystem/wit/deps/clocks/wall-clock.wit +++ b/proposals/filesystem/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/filesystem/wit/deps/clocks/world.wit b/proposals/filesystem/wit/deps/clocks/world.wit index a08ff2c2c..1655ca830 100644 --- a/proposals/filesystem/wit/deps/clocks/world.wit +++ b/proposals/filesystem/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/filesystem/wit/deps/io/error.wit b/proposals/filesystem/wit/deps/io/error.wit index acab3a811..dd5a1af03 100644 --- a/proposals/filesystem/wit/deps/io/error.wit +++ b/proposals/filesystem/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; @since(version = 0.2.0) interface error { diff --git a/proposals/filesystem/wit/deps/io/poll.wit b/proposals/filesystem/wit/deps/io/poll.wit index a525164b9..833b381d9 100644 --- a/proposals/filesystem/wit/deps/io/poll.wit +++ b/proposals/filesystem/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/filesystem/wit/deps/io/streams.wit b/proposals/filesystem/wit/deps/io/streams.wit index 7ae29a3cd..fbb0268b0 100644 --- a/proposals/filesystem/wit/deps/io/streams.wit +++ b/proposals/filesystem/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/filesystem/wit/deps/io/world.wit b/proposals/filesystem/wit/deps/io/world.wit index 73b1a6df5..1cc3fce12 100644 --- a/proposals/filesystem/wit/deps/io/world.wit +++ b/proposals/filesystem/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/filesystem/wit/preopens.wit b/proposals/filesystem/wit/preopens.wit index b1a0a9972..0d2cca65d 100644 --- a/proposals/filesystem/wit/preopens.wit +++ b/proposals/filesystem/wit/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.7; +package wasi:filesystem@0.2.8; @since(version = 0.2.0) interface preopens { diff --git a/proposals/filesystem/wit/types.wit b/proposals/filesystem/wit/types.wit index a7da2b72f..ac68f88af 100644 --- a/proposals/filesystem/wit/types.wit +++ b/proposals/filesystem/wit/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.7; +package wasi:filesystem@0.2.8; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.7; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.7.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.8.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.7.{datetime}; + use wasi:clocks/wall-clock@0.2.8.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/filesystem/wit/world.wit b/proposals/filesystem/wit/world.wit index 67309b43f..7daf06758 100644 --- a/proposals/filesystem/wit/world.wit +++ b/proposals/filesystem/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.7; +package wasi:filesystem@0.2.8; @since(version = 0.2.0) world imports { From 07e8a0ea2eeebf9b94350a26a6f349040bfe5103 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 15:22:28 +0000 Subject: [PATCH 1755/1772] Update to v0.2.8 --- proposals/sockets/imports.md | 152 +++++++++--------- proposals/sockets/wit/deps.lock | 8 +- .../wit/deps/clocks/monotonic-clock.wit | 9 +- .../sockets/wit/deps/clocks/timezone.wit | 2 +- .../sockets/wit/deps/clocks/wall-clock.wit | 2 +- proposals/sockets/wit/deps/clocks/world.wit | 2 +- proposals/sockets/wit/deps/io/error.wit | 2 +- proposals/sockets/wit/deps/io/poll.wit | 2 +- proposals/sockets/wit/deps/io/streams.wit | 2 +- proposals/sockets/wit/deps/io/world.wit | 2 +- proposals/sockets/wit/ip-name-lookup.wit | 2 +- proposals/sockets/wit/network.wit | 2 +- proposals/sockets/wit/tcp.wit | 6 +- proposals/sockets/wit/udp.wit | 2 +- proposals/sockets/wit/world.wit | 2 +- 15 files changed, 103 insertions(+), 94 deletions(-) diff --git a/proposals/sockets/imports.md b/proposals/sockets/imports.md index 390830530..441464a7e 100644 --- a/proposals/sockets/imports.md +++ b/proposals/sockets/imports.md @@ -2,21 +2,21 @@ -

                              Import interface wasi:io/error@0.2.7

                              +

                              Import interface wasi:io/error@0.2.8


                              Types

                              resource error

                              @@ -49,13 +49,13 @@ hazard.

                              • string
                              -

                              Import interface wasi:sockets/network@0.2.7

                              +

                              Import interface wasi:sockets/network@0.2.8


                              Types

                              type error

                              error

                              -#### `resource network` +

                              resource network

                              An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                              @@ -264,14 +264,14 @@ errors are network-related errors.

                              -

                              Import interface wasi:sockets/instance-network@0.2.7

                              +

                              Import interface wasi:sockets/instance-network@0.2.8

                              This interface provides a value-export of the default network handle..


                              Types

                              type network

                              network

                              ----- +


                              Functions

                              instance-network: func

                              Get a handle to the default network.

                              @@ -279,7 +279,7 @@ errors are network-related errors.

                              -

                              Import interface wasi:io/poll@0.2.7

                              +

                              Import interface wasi:io/poll@0.2.8

                              A poll API intended to let users wait for I/O events on multiple handles at once.


                              @@ -332,25 +332,25 @@ being ready for I/O.

                              • list<u32>
                              -

                              Import interface wasi:sockets/udp@0.2.7

                              +

                              Import interface wasi:sockets/udp@0.2.8


                              Types

                              type pollable

                              pollable

                              -#### `type network` -[`network`](#network) +

                              type network

                              +

                              network

                              -#### `type error-code` -[`error-code`](#error_code) +

                              type error-code

                              +

                              error-code

                              -#### `type ip-socket-address` -[`ip-socket-address`](#ip_socket_address) +

                              type ip-socket-address

                              +

                              ip-socket-address

                              -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) +

                              type ip-address-family

                              +

                              ip-address-family

                              -#### `record incoming-datagram` +

                              record incoming-datagram

                              A received datagram.

                              Record Fields
                                @@ -746,22 +746,22 @@ It's planned to be removed when future is natively supported in Pre -

                                Import interface wasi:sockets/udp-create-socket@0.2.7

                                +

                                Import interface wasi:sockets/udp-create-socket@0.2.8


                                Types

                                type network

                                network

                                -#### `type error-code` -[`error-code`](#error_code) +

                                type error-code

                                +

                                error-code

                                -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) +

                                type ip-address-family

                                +

                                ip-address-family

                                -#### `type udp-socket` -[`udp-socket`](#udp_socket) +

                                type udp-socket

                                +

                                udp-socket

                                ----- +


                                Functions

                                create-udp-socket: func

                                Create a new UDP socket.

                                @@ -791,7 +791,7 @@ the socket is effectively an in-memory configuration object, unable to communica -

                                Import interface wasi:io/streams@0.2.7

                                +

                                Import interface wasi:io/streams@0.2.8

                                WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                                In the future, the component model is expected to add built-in stream types; @@ -801,10 +801,10 @@ when it does, they are expected to subsume this API.

                                type error

                                error

                                -#### `type pollable` -[`pollable`](#pollable) +

                                type pollable

                                +

                                pollable

                                -#### `variant stream-error` +

                                variant stream-error

                                An error for input-stream and output-stream operations.

                                Variant Cases
                                  @@ -1093,7 +1093,7 @@ is ready for reading, before performing the splice.

                                  -

                                  Import interface wasi:clocks/monotonic-clock@0.2.7

                                  +

                                  Import interface wasi:clocks/monotonic-clock@0.2.8

                                  WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                                  It is intended to be portable at least between Unix-family platforms and @@ -1105,8 +1105,8 @@ successive reads of the clock will produce non-decreasing values.

                                  type pollable

                                  pollable

                                  -#### `type instant` -`u64` +

                                  type instant

                                  +

                                  u64

                                  An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. @@ -1119,6 +1119,10 @@ the same monotonic-clock.

                                  Read the current value of the clock.

                                  The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

                                  +

                                  For completeness, this function traps if it's not possible to represent +the value of the clock in an instant. Consequently, implementations +should ensure that the starting time is low enough to avoid the +possibility of overflow in practice.

                                  Return values
                                  • instant
                                  • @@ -1152,34 +1156,34 @@ elapsed from the time this function is invoked.

                                    -

                                    Import interface wasi:sockets/tcp@0.2.7

                                    +

                                    Import interface wasi:sockets/tcp@0.2.8


                                    Types

                                    type input-stream

                                    input-stream

                                    -#### `type output-stream` -[`output-stream`](#output_stream) +

                                    type output-stream

                                    +

                                    output-stream

                                    -#### `type pollable` -[`pollable`](#pollable) +

                                    type pollable

                                    +

                                    pollable

                                    -#### `type duration` -[`duration`](#duration) +

                                    type duration

                                    +

                                    duration

                                    -#### `type network` -[`network`](#network) +

                                    type network

                                    +

                                    network

                                    -#### `type error-code` -[`error-code`](#error_code) +

                                    type error-code

                                    +

                                    error-code

                                    -#### `type ip-socket-address` -[`ip-socket-address`](#ip_socket_address) +

                                    type ip-socket-address

                                    +

                                    ip-socket-address

                                    -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) +

                                    type ip-address-family

                                    +

                                    ip-address-family

                                    -#### `enum shutdown-type` +

                                    enum shutdown-type

                                    Enum Cases
                                    • @@ -1743,22 +1747,22 @@ has no effect and returns ok.

                                      -

                                      Import interface wasi:sockets/tcp-create-socket@0.2.7

                                      +

                                      Import interface wasi:sockets/tcp-create-socket@0.2.8


                                      Types

                                      type network

                                      network

                                      -#### `type error-code` -[`error-code`](#error_code) +

                                      type error-code

                                      +

                                      error-code

                                      -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) +

                                      type ip-address-family

                                      +

                                      ip-address-family

                                      -#### `type tcp-socket` -[`tcp-socket`](#tcp_socket) +

                                      type tcp-socket

                                      +

                                      tcp-socket

                                      ----- +


                                      Functions

                                      create-tcp-socket: func

                                      Create a new TCP socket.

                                      @@ -1788,22 +1792,22 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                                      Import interface wasi:sockets/ip-name-lookup@0.2.7

                                      +

                                      Import interface wasi:sockets/ip-name-lookup@0.2.8


                                      Types

                                      type pollable

                                      pollable

                                      -#### `type network` -[`network`](#network) +

                                      type network

                                      +

                                      network

                                      -#### `type error-code` -[`error-code`](#error_code) +

                                      type error-code

                                      +

                                      error-code

                                      -#### `type ip-address` -[`ip-address`](#ip_address) +

                                      type ip-address

                                      +

                                      ip-address

                                      -#### `resource resolve-address-stream` +

                                      resource resolve-address-stream


                                      Functions

                                      resolve-addresses: func

                                      diff --git a/proposals/sockets/wit/deps.lock b/proposals/sockets/wit/deps.lock index 1d550cb8f..b0d60f694 100644 --- a/proposals/sockets/wit/deps.lock +++ b/proposals/sockets/wit/deps.lock @@ -1,9 +1,9 @@ [clocks] url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz" -sha256 = "d0a8d048c41b566b978cd8ecd03fa51ec1f65af4c26be2f0fc9cfdd7dd6f34f3" -sha512 = "8d1c9ddaaea70ae54376bfc02dcdd0437336fb4fc67f89763ce09540caefe84cbae89a8de3605aa7613c49188636e925047bcd150c2c60685850095fefb68b73" +sha256 = "be1d8c61e2544e2b48d902c60df73577e293349063344ce752cda4d323f8b913" +sha512 = "0fd7962c62b135da0e584c2b58a55147bf09873848b0bb5bd3913019bc3f8d4b5969fbd6f7f96fd99a015efaf562a3eeafe3bc13049f8572a6e13ef9ef0e7e75" [io] url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz" -sha256 = "62ae80f2e340cddbac8e94f78e6270735aea536367ecb98de5f4ac6aef66b5c4" -sha512 = "a02a1ebd261ae884b0315b3528d1a93819ddc4b616f66c77f2bea9dd1de888208dc3b9004a553363f5e8491ea925d65ebbd0d68eaa87238316b47469a3bf97bb" +sha256 = "9f1ad5da70f621bbd4c69e3bd90250a0c12ecfde266aa8f99684fc44bc1e7c15" +sha512 = "6d0a9db6848f24762933d1c168a5b5b1065ba838c253ee20454afeb8dd1a049b918d25deff556083d68095dd3126ae131ac3e738774320eee5d918f5a4b5354e" diff --git a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit index 98a9ad42a..e60f366f2 100644 --- a/proposals/sockets/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/sockets/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.7; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from @@ -26,6 +26,11 @@ interface monotonic-clock { /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + /// + /// For completeness, this function traps if it's not possible to represent + /// the value of the clock in an `instant`. Consequently, implementations + /// should ensure that the starting time is low enough to avoid the + /// possibility of overflow in practice. @since(version = 0.2.0) now: func() -> instant; diff --git a/proposals/sockets/wit/deps/clocks/timezone.wit b/proposals/sockets/wit/deps/clocks/timezone.wit index 4740bde00..534814a63 100644 --- a/proposals/sockets/wit/deps/clocks/timezone.wit +++ b/proposals/sockets/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/sockets/wit/deps/clocks/wall-clock.wit b/proposals/sockets/wit/deps/clocks/wall-clock.wit index 2179b6c56..3386c800b 100644 --- a/proposals/sockets/wit/deps/clocks/wall-clock.wit +++ b/proposals/sockets/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/sockets/wit/deps/clocks/world.wit b/proposals/sockets/wit/deps/clocks/world.wit index a08ff2c2c..1655ca830 100644 --- a/proposals/sockets/wit/deps/clocks/world.wit +++ b/proposals/sockets/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/sockets/wit/deps/io/error.wit b/proposals/sockets/wit/deps/io/error.wit index acab3a811..dd5a1af03 100644 --- a/proposals/sockets/wit/deps/io/error.wit +++ b/proposals/sockets/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; @since(version = 0.2.0) interface error { diff --git a/proposals/sockets/wit/deps/io/poll.wit b/proposals/sockets/wit/deps/io/poll.wit index a525164b9..833b381d9 100644 --- a/proposals/sockets/wit/deps/io/poll.wit +++ b/proposals/sockets/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/sockets/wit/deps/io/streams.wit b/proposals/sockets/wit/deps/io/streams.wit index 7ae29a3cd..fbb0268b0 100644 --- a/proposals/sockets/wit/deps/io/streams.wit +++ b/proposals/sockets/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/sockets/wit/deps/io/world.wit b/proposals/sockets/wit/deps/io/world.wit index 73b1a6df5..1cc3fce12 100644 --- a/proposals/sockets/wit/deps/io/world.wit +++ b/proposals/sockets/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/sockets/wit/ip-name-lookup.wit b/proposals/sockets/wit/ip-name-lookup.wit index df2735aac..ecdaa8493 100644 --- a/proposals/sockets/wit/ip-name-lookup.wit +++ b/proposals/sockets/wit/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/sockets/wit/network.wit b/proposals/sockets/wit/network.wit index 95df71ff3..75a4f7d7f 100644 --- a/proposals/sockets/wit/network.wit +++ b/proposals/sockets/wit/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.7.{error}; + use wasi:io/error@0.2.8.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/sockets/wit/tcp.wit b/proposals/sockets/wit/tcp.wit index 104d9aa39..9b5552d2e 100644 --- a/proposals/sockets/wit/tcp.wit +++ b/proposals/sockets/wit/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.7.{input-stream, output-stream}; + use wasi:io/streams@0.2.8.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.7.{duration}; + use wasi:clocks/monotonic-clock@0.2.8.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/udp.wit b/proposals/sockets/wit/udp.wit index ecf2dfe60..0000a157e 100644 --- a/proposals/sockets/wit/udp.wit +++ b/proposals/sockets/wit/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/sockets/wit/world.wit b/proposals/sockets/wit/world.wit index 9a4d317f7..4441e9119 100644 --- a/proposals/sockets/wit/world.wit +++ b/proposals/sockets/wit/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.7; +package wasi:sockets@0.2.8; @since(version = 0.2.0) world imports { From ce9f5a92930fe56a837c6e8f5e9116a4df5e2990 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 15:24:33 +0000 Subject: [PATCH 1756/1772] Update to v0.2.8 --- proposals/cli/command.md | 256 ++++++++--------- proposals/cli/imports.md | 258 +++++++++--------- proposals/cli/wit/command.wit | 2 +- proposals/cli/wit/deps.lock | 26 +- proposals/cli/wit/deps.toml | 6 +- .../cli/wit/deps/clocks/monotonic-clock.wit | 9 +- proposals/cli/wit/deps/clocks/timezone.wit | 2 +- proposals/cli/wit/deps/clocks/wall-clock.wit | 2 +- proposals/cli/wit/deps/clocks/world.wit | 2 +- .../cli/wit/deps/filesystem/preopens.wit | 2 +- proposals/cli/wit/deps/filesystem/types.wit | 6 +- proposals/cli/wit/deps/filesystem/world.wit | 2 +- proposals/cli/wit/deps/io/error.wit | 2 +- proposals/cli/wit/deps/io/poll.wit | 2 +- proposals/cli/wit/deps/io/streams.wit | 2 +- proposals/cli/wit/deps/io/world.wit | 2 +- .../cli/wit/deps/random/insecure-seed.wit | 2 +- proposals/cli/wit/deps/random/insecure.wit | 2 +- proposals/cli/wit/deps/random/random.wit | 2 +- proposals/cli/wit/deps/random/world.wit | 2 +- .../cli/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/cli/wit/deps/sockets/network.wit | 2 +- proposals/cli/wit/deps/sockets/tcp.wit | 6 +- proposals/cli/wit/deps/sockets/udp.wit | 2 +- proposals/cli/wit/deps/sockets/world.wit | 2 +- proposals/cli/wit/imports.wit | 12 +- proposals/cli/wit/stdio.wit | 6 +- 27 files changed, 317 insertions(+), 304 deletions(-) diff --git a/proposals/cli/command.md b/proposals/cli/command.md index f1b5188c4..34c1c9290 100644 --- a/proposals/cli/command.md +++ b/proposals/cli/command.md @@ -2,43 +2,43 @@ -

                                      Import interface wasi:cli/environment@0.2.7

                                      +

                                      Import interface wasi:cli/environment@0.2.8


                                      Functions

                                      get-environment: func

                                      @@ -65,7 +65,7 @@ directory, interpreting . as shorthand for this.

                                      • option<string>
                                      -

                                      Import interface wasi:cli/exit@0.2.7

                                      +

                                      Import interface wasi:cli/exit@0.2.8


                                      Functions

                                      exit: func

                                      @@ -85,7 +85,7 @@ without the connotation that something bad has happened.

                                      • status-code: u8
                                      -

                                      Import interface wasi:io/error@0.2.7

                                      +

                                      Import interface wasi:io/error@0.2.8


                                      Types

                                      resource error

                                      @@ -118,7 +118,7 @@ hazard.

                                      • string
                                      -

                                      Import interface wasi:io/poll@0.2.7

                                      +

                                      Import interface wasi:io/poll@0.2.8

                                      A poll API intended to let users wait for I/O events on multiple handles at once.


                                      @@ -171,7 +171,7 @@ being ready for I/O.

                                      • list<u32>
                                      -

                                      Import interface wasi:io/streams@0.2.7

                                      +

                                      Import interface wasi:io/streams@0.2.8

                                      WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                                      In the future, the component model is expected to add built-in stream types; @@ -181,10 +181,10 @@ when it does, they are expected to subsume this API.

                                      type error

                                      error

                                      -#### `type pollable` -[`pollable`](#pollable) +

                                      type pollable

                                      +

                                      pollable

                                      -#### `variant stream-error` +

                                      variant stream-error

                                      An error for input-stream and output-stream operations.

                                      Variant Cases
                                        @@ -473,46 +473,46 @@ is ready for reading, before performing the splice.

                                        -

                                        Import interface wasi:cli/stdin@0.2.7

                                        +

                                        Import interface wasi:cli/stdin@0.2.8


                                        Types

                                        type input-stream

                                        input-stream

                                        ----- +


                                        Functions

                                        get-stdin: func

                                        Return values
                                        -

                                        Import interface wasi:cli/stdout@0.2.7

                                        +

                                        Import interface wasi:cli/stdout@0.2.8


                                        Types

                                        type output-stream

                                        output-stream

                                        ----- +


                                        Functions

                                        get-stdout: func

                                        Return values
                                        -

                                        Import interface wasi:cli/stderr@0.2.7

                                        +

                                        Import interface wasi:cli/stderr@0.2.8


                                        Types

                                        type output-stream

                                        output-stream

                                        ----- +


                                        Functions

                                        get-stderr: func

                                        Return values
                                        -

                                        Import interface wasi:cli/terminal-input@0.2.7

                                        +

                                        Import interface wasi:cli/terminal-input@0.2.8

                                        Terminal input.

                                        In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -521,7 +521,7 @@ immediately, querying supported features, and so on.

                                        Types

                                        resource terminal-input

                                        The input side of a terminal.

                                        -

                                        Import interface wasi:cli/terminal-output@0.2.7

                                        +

                                        Import interface wasi:cli/terminal-output@0.2.8

                                        Terminal output.

                                        In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -530,7 +530,7 @@ features, and so on.

                                        Types

                                        resource terminal-output

                                        The output side of a terminal.

                                        -

                                        Import interface wasi:cli/terminal-stdin@0.2.7

                                        +

                                        Import interface wasi:cli/terminal-stdin@0.2.8

                                        An interface providing an optional terminal-input for stdin as a link-time authority.


                                        @@ -538,7 +538,7 @@ link-time authority.

                                        type terminal-input

                                        terminal-input

                                        ----- +


                                        Functions

                                        get-terminal-stdin: func

                                        If stdin is connected to a terminal, return a terminal-input handle @@ -547,7 +547,7 @@ allowing further interaction with it.

                                        -

                                        Import interface wasi:cli/terminal-stdout@0.2.7

                                        +

                                        Import interface wasi:cli/terminal-stdout@0.2.8

                                        An interface providing an optional terminal-output for stdout as a link-time authority.


                                        @@ -555,7 +555,7 @@ link-time authority.

                                        type terminal-output

                                        terminal-output

                                        ----- +


                                        Functions

                                        get-terminal-stdout: func

                                        If stdout is connected to a terminal, return a terminal-output handle @@ -564,7 +564,7 @@ allowing further interaction with it.

                                        -

                                        Import interface wasi:cli/terminal-stderr@0.2.7

                                        +

                                        Import interface wasi:cli/terminal-stderr@0.2.8

                                        An interface providing an optional terminal-output for stderr as a link-time authority.


                                        @@ -572,7 +572,7 @@ link-time authority.

                                        type terminal-output

                                        terminal-output

                                        ----- +


                                        Functions

                                        get-terminal-stderr: func

                                        If stderr is connected to a terminal, return a terminal-output handle @@ -581,7 +581,7 @@ allowing further interaction with it.

                                        -

                                        Import interface wasi:clocks/monotonic-clock@0.2.7

                                        +

                                        Import interface wasi:clocks/monotonic-clock@0.2.8

                                        WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                                        It is intended to be portable at least between Unix-family platforms and @@ -593,8 +593,8 @@ successive reads of the clock will produce non-decreasing values.

                                        type pollable

                                        pollable

                                        -#### `type instant` -`u64` +

                                        type instant

                                        +

                                        u64

                                        An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. @@ -607,6 +607,10 @@ the same monotonic-clock.

                                        Read the current value of the clock.

                                        The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

                                        +

                                        For completeness, this function traps if it's not possible to represent +the value of the clock in an instant. Consequently, implementations +should ensure that the starting time is low enough to avoid the +possibility of overflow in practice.

                                        Return values
                                        • instant
                                        • @@ -640,7 +644,7 @@ elapsed from the time this function is invoked.

                                          -

                                          Import interface wasi:clocks/wall-clock@0.2.7

                                          +

                                          Import interface wasi:clocks/wall-clock@0.2.8

                                          WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                                          @@ -681,13 +685,13 @@ also known as Unix Time.
                                        • datetime
                                        -

                                        Import interface wasi:clocks/timezone@0.2.7

                                        +

                                        Import interface wasi:clocks/timezone@0.2.8


                                        Types

                                        type datetime

                                        datetime

                                        -#### `record timezone-display` +

                                        record timezone-display

                                        Information useful for displaying the timezone of a specific datetime.

                                        This information may vary within a single timezone to reflect daylight saving time adjustments.

                                        @@ -746,7 +750,7 @@ saving time.

                                        • s32
                                        -

                                        Import interface wasi:filesystem/types@0.2.7

                                        +

                                        Import interface wasi:filesystem/types@0.2.8

                                        WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                                        @@ -769,17 +773,17 @@ underlying filesystem, the function fails with type input-stream

                                        input-stream

                                        -#### `type output-stream` -[`output-stream`](#output_stream) +

                                        type output-stream

                                        +

                                        output-stream

                                        -#### `type error` -[`error`](#error) +

                                        type error

                                        +

                                        error

                                        -#### `type datetime` -[`datetime`](#datetime) +

                                        type datetime

                                        +

                                        datetime

                                        -#### `type filesize` -`u64` +

                                        type filesize

                                        +

                                        u64

                                        File size or length of a region within a file.

                                        enum descriptor-type

                                        The type of a filesystem object referenced by a descriptor.

                                        @@ -1624,13 +1628,13 @@ errors are filesystem-related errors.

                                        -

                                        Import interface wasi:filesystem/preopens@0.2.7

                                        +

                                        Import interface wasi:filesystem/preopens@0.2.8


                                        Types

                                        type descriptor

                                        descriptor

                                        ----- +


                                        Functions

                                        get-directories: func

                                        Return the set of preopened directories, and their paths.

                                        @@ -1638,13 +1642,13 @@ errors are filesystem-related errors.

                                        -

                                        Import interface wasi:sockets/network@0.2.7

                                        +

                                        Import interface wasi:sockets/network@0.2.8


                                        Types

                                        type error

                                        error

                                        -#### `resource network` +

                                        resource network

                                        An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                                        @@ -1853,14 +1857,14 @@ errors are network-related errors.

                                        -

                                        Import interface wasi:sockets/instance-network@0.2.7

                                        +

                                        Import interface wasi:sockets/instance-network@0.2.8

                                        This interface provides a value-export of the default network handle..


                                        Types

                                        type network

                                        network

                                        ----- +


                                        Functions

                                        instance-network: func

                                        Get a handle to the default network.

                                        @@ -1868,25 +1872,25 @@ errors are network-related errors.

                                        -

                                        Import interface wasi:sockets/udp@0.2.7

                                        +

                                        Import interface wasi:sockets/udp@0.2.8


                                        Types

                                        type pollable

                                        pollable

                                        -#### `type network` -[`network`](#network) +

                                        type network

                                        +

                                        network

                                        -#### `type error-code` -[`error-code`](#error_code) +

                                        type error-code

                                        +

                                        error-code

                                        -#### `type ip-socket-address` -[`ip-socket-address`](#ip_socket_address) +

                                        type ip-socket-address

                                        +

                                        ip-socket-address

                                        -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) +

                                        type ip-address-family

                                        +

                                        ip-address-family

                                        -#### `record incoming-datagram` +

                                        record incoming-datagram

                                        A received datagram.

                                        Record Fields
                                        +

                                        Import interface wasi:cli/environment@0.2.8


                                        Functions

                                        get-environment: func

                                        @@ -60,7 +60,7 @@ directory, interpreting . as shorthand for this.

                                        • option<string>
                                        -

                                        Import interface wasi:cli/exit@0.2.7

                                        +

                                        Import interface wasi:cli/exit@0.2.8


                                        Functions

                                        exit: func

                                        @@ -80,7 +80,7 @@ without the connotation that something bad has happened.

                                        • status-code: u8
                                        -

                                        Import interface wasi:io/error@0.2.7

                                        +

                                        Import interface wasi:io/error@0.2.8


                                        Types

                                        resource error

                                        @@ -113,7 +113,7 @@ hazard.

                                        • string
                                        -

                                        Import interface wasi:io/poll@0.2.7

                                        +

                                        Import interface wasi:io/poll@0.2.8

                                        A poll API intended to let users wait for I/O events on multiple handles at once.


                                        @@ -166,7 +166,7 @@ being ready for I/O.

                                        • list<u32>
                                        -

                                        Import interface wasi:io/streams@0.2.7

                                        +

                                        Import interface wasi:io/streams@0.2.8

                                        WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                                        In the future, the component model is expected to add built-in stream types; @@ -176,10 +176,10 @@ when it does, they are expected to subsume this API.

                                        type error

                                        error

                                        -#### `type pollable` -[`pollable`](#pollable) +

                                        type pollable

                                        +

                                        pollable

                                        -#### `variant stream-error` +

                                        variant stream-error

                                        An error for input-stream and output-stream operations.

                                        Variant Cases
                                          @@ -468,46 +468,46 @@ is ready for reading, before performing the splice.

                                          -

                                          Import interface wasi:cli/stdin@0.2.7

                                          +

                                          Import interface wasi:cli/stdin@0.2.8


                                          Types

                                          type input-stream

                                          input-stream

                                          ----- +


                                          Functions

                                          get-stdin: func

                                          Return values
                                          -

                                          Import interface wasi:cli/stdout@0.2.7

                                          +

                                          Import interface wasi:cli/stdout@0.2.8


                                          Types

                                          type output-stream

                                          output-stream

                                          ----- +


                                          Functions

                                          get-stdout: func

                                          Return values
                                          -

                                          Import interface wasi:cli/stderr@0.2.7

                                          +

                                          Import interface wasi:cli/stderr@0.2.8


                                          Types

                                          type output-stream

                                          output-stream

                                          ----- +


                                          Functions

                                          get-stderr: func

                                          Return values
                                          -

                                          Import interface wasi:cli/terminal-input@0.2.7

                                          +

                                          Import interface wasi:cli/terminal-input@0.2.8

                                          Terminal input.

                                          In the future, this may include functions for disabling echoing, disabling input buffering so that keyboard events are sent through @@ -516,7 +516,7 @@ immediately, querying supported features, and so on.

                                          Types

                                          resource terminal-input

                                          The input side of a terminal.

                                          -

                                          Import interface wasi:cli/terminal-output@0.2.7

                                          +

                                          Import interface wasi:cli/terminal-output@0.2.8

                                          Terminal output.

                                          In the future, this may include functions for querying the terminal size, being notified of terminal size changes, querying supported @@ -525,7 +525,7 @@ features, and so on.

                                          Types

                                          resource terminal-output

                                          The output side of a terminal.

                                          -

                                          Import interface wasi:cli/terminal-stdin@0.2.7

                                          +

                                          Import interface wasi:cli/terminal-stdin@0.2.8

                                          An interface providing an optional terminal-input for stdin as a link-time authority.


                                          @@ -533,7 +533,7 @@ link-time authority.

                                          type terminal-input

                                          terminal-input

                                          ----- +


                                          Functions

                                          get-terminal-stdin: func

                                          If stdin is connected to a terminal, return a terminal-input handle @@ -542,7 +542,7 @@ allowing further interaction with it.

                                          -

                                          Import interface wasi:cli/terminal-stdout@0.2.7

                                          +

                                          Import interface wasi:cli/terminal-stdout@0.2.8

                                          An interface providing an optional terminal-output for stdout as a link-time authority.


                                          @@ -550,7 +550,7 @@ link-time authority.

                                          type terminal-output

                                          terminal-output

                                          ----- +


                                          Functions

                                          get-terminal-stdout: func

                                          If stdout is connected to a terminal, return a terminal-output handle @@ -559,7 +559,7 @@ allowing further interaction with it.

                                          -

                                          Import interface wasi:cli/terminal-stderr@0.2.7

                                          +

                                          Import interface wasi:cli/terminal-stderr@0.2.8

                                          An interface providing an optional terminal-output for stderr as a link-time authority.


                                          @@ -567,7 +567,7 @@ link-time authority.

                                          type terminal-output

                                          terminal-output

                                          ----- +


                                          Functions

                                          get-terminal-stderr: func

                                          If stderr is connected to a terminal, return a terminal-output handle @@ -576,7 +576,7 @@ allowing further interaction with it.

                                          -

                                          Import interface wasi:clocks/monotonic-clock@0.2.7

                                          +

                                          Import interface wasi:clocks/monotonic-clock@0.2.8

                                          WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                                          It is intended to be portable at least between Unix-family platforms and @@ -588,8 +588,8 @@ successive reads of the clock will produce non-decreasing values.

                                          type pollable

                                          pollable

                                          -#### `type instant` -`u64` +

                                          type instant

                                          +

                                          u64

                                          An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. @@ -602,6 +602,10 @@ the same monotonic-clock.

                                          Read the current value of the clock.

                                          The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

                                          +

                                          For completeness, this function traps if it's not possible to represent +the value of the clock in an instant. Consequently, implementations +should ensure that the starting time is low enough to avoid the +possibility of overflow in practice.

                                          Return values
                                          • instant
                                          • @@ -635,7 +639,7 @@ elapsed from the time this function is invoked.

                                            -

                                            Import interface wasi:clocks/wall-clock@0.2.7

                                            +

                                            Import interface wasi:clocks/wall-clock@0.2.8

                                            WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                                            @@ -676,13 +680,13 @@ also known as Unix Time.
                                          • datetime
                                          -

                                          Import interface wasi:clocks/timezone@0.2.7

                                          +

                                          Import interface wasi:clocks/timezone@0.2.8


                                          Types

                                          type datetime

                                          datetime

                                          -#### `record timezone-display` +

                                          record timezone-display

                                          Information useful for displaying the timezone of a specific datetime.

                                          This information may vary within a single timezone to reflect daylight saving time adjustments.

                                          @@ -741,7 +745,7 @@ saving time.

                                          • s32
                                          -

                                          Import interface wasi:filesystem/types@0.2.7

                                          +

                                          Import interface wasi:filesystem/types@0.2.8

                                          WASI filesystem is a filesystem API primarily intended to let users run WASI programs that access their files on their existing filesystems, without significant overhead.

                                          @@ -764,17 +768,17 @@ underlying filesystem, the function fails with type input-stream

                                          input-stream

                                          -#### `type output-stream` -[`output-stream`](#output_stream) +

                                          type output-stream

                                          +

                                          output-stream

                                          -#### `type error` -[`error`](#error) +

                                          type error

                                          +

                                          error

                                          -#### `type datetime` -[`datetime`](#datetime) +

                                          type datetime

                                          +

                                          datetime

                                          -#### `type filesize` -`u64` +

                                          type filesize

                                          +

                                          u64

                                          File size or length of a region within a file.

                                          enum descriptor-type

                                          The type of a filesystem object referenced by a descriptor.

                                          @@ -1619,13 +1623,13 @@ errors are filesystem-related errors.

                                          -

                                          Import interface wasi:filesystem/preopens@0.2.7

                                          +

                                          Import interface wasi:filesystem/preopens@0.2.8


                                          Types

                                          type descriptor

                                          descriptor

                                          ----- +


                                          Functions

                                          get-directories: func

                                          Return the set of preopened directories, and their paths.

                                          @@ -1633,13 +1637,13 @@ errors are filesystem-related errors.

                                          -

                                          Import interface wasi:sockets/network@0.2.7

                                          +

                                          Import interface wasi:sockets/network@0.2.8


                                          Types

                                          type error

                                          error

                                          -#### `resource network` +

                                          resource network

                                          An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.

                                          @@ -1848,14 +1852,14 @@ errors are network-related errors.

                                          -

                                          Import interface wasi:sockets/instance-network@0.2.7

                                          +

                                          Import interface wasi:sockets/instance-network@0.2.8

                                          This interface provides a value-export of the default network handle..


                                          Types

                                          type network

                                          network

                                          ----- +


                                          Functions

                                          instance-network: func

                                          Get a handle to the default network.

                                          @@ -1863,25 +1867,25 @@ errors are network-related errors.

                                          -

                                          Import interface wasi:sockets/udp@0.2.7

                                          +

                                          Import interface wasi:sockets/udp@0.2.8


                                          Types

                                          type pollable

                                          pollable

                                          -#### `type network` -[`network`](#network) +

                                          type network

                                          +

                                          network

                                          -#### `type error-code` -[`error-code`](#error_code) +

                                          type error-code

                                          +

                                          error-code

                                          -#### `type ip-socket-address` -[`ip-socket-address`](#ip_socket_address) +

                                          type ip-socket-address

                                          +

                                          ip-socket-address

                                          -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) +

                                          type ip-address-family

                                          +

                                          ip-address-family

                                          -#### `record incoming-datagram` +

                                          record incoming-datagram

                                          A received datagram.

                                          Record Fields
                                            @@ -2277,22 +2281,22 @@ It's planned to be removed when future is natively supported in Pre -

                                            Import interface wasi:sockets/udp-create-socket@0.2.7

                                            +

                                            Import interface wasi:sockets/udp-create-socket@0.2.8


                                            Types

                                            type network

                                            network

                                            -#### `type error-code` -[`error-code`](#error_code) +

                                            type error-code

                                            +

                                            error-code

                                            -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) +

                                            type ip-address-family

                                            +

                                            ip-address-family

                                            -#### `type udp-socket` -[`udp-socket`](#udp_socket) +

                                            type udp-socket

                                            +

                                            udp-socket

                                            ----- +


                                            Functions

                                            create-udp-socket: func

                                            Create a new UDP socket.

                                            @@ -2322,34 +2326,34 @@ the socket is effectively an in-memory configuration object, unable to communica -

                                            Import interface wasi:sockets/tcp@0.2.7

                                            +

                                            Import interface wasi:sockets/tcp@0.2.8


                                            Types

                                            type input-stream

                                            input-stream

                                            -#### `type output-stream` -[`output-stream`](#output_stream) +

                                            type output-stream

                                            +

                                            output-stream

                                            -#### `type pollable` -[`pollable`](#pollable) +

                                            type pollable

                                            +

                                            pollable

                                            -#### `type duration` -[`duration`](#duration) +

                                            type duration

                                            +

                                            duration

                                            -#### `type network` -[`network`](#network) +

                                            type network

                                            +

                                            network

                                            -#### `type error-code` -[`error-code`](#error_code) +

                                            type error-code

                                            +

                                            error-code

                                            -#### `type ip-socket-address` -[`ip-socket-address`](#ip_socket_address) +

                                            type ip-socket-address

                                            +

                                            ip-socket-address

                                            -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) +

                                            type ip-address-family

                                            +

                                            ip-address-family

                                            -#### `enum shutdown-type` +

                                            enum shutdown-type

                                            Enum Cases
                                            • @@ -2913,22 +2917,22 @@ has no effect and returns ok.

                                              -

                                              Import interface wasi:sockets/tcp-create-socket@0.2.7

                                              +

                                              Import interface wasi:sockets/tcp-create-socket@0.2.8


                                              Types

                                              type network

                                              network

                                              -#### `type error-code` -[`error-code`](#error_code) +

                                              type error-code

                                              +

                                              error-code

                                              -#### `type ip-address-family` -[`ip-address-family`](#ip_address_family) +

                                              type ip-address-family

                                              +

                                              ip-address-family

                                              -#### `type tcp-socket` -[`tcp-socket`](#tcp_socket) +

                                              type tcp-socket

                                              +

                                              tcp-socket

                                              ----- +


                                              Functions

                                              create-tcp-socket: func

                                              Create a new TCP socket.

                                              @@ -2958,22 +2962,22 @@ is called, the socket is effectively an in-memory configuration object, unable t -

                                              Import interface wasi:sockets/ip-name-lookup@0.2.7

                                              +

                                              Import interface wasi:sockets/ip-name-lookup@0.2.8


                                              Types

                                              type pollable

                                              pollable

                                              -#### `type network` -[`network`](#network) +

                                              type network

                                              +

                                              network

                                              -#### `type error-code` -[`error-code`](#error_code) +

                                              type error-code

                                              +

                                              error-code

                                              -#### `type ip-address` -[`ip-address`](#ip_address) +

                                              type ip-address

                                              +

                                              ip-address

                                              -#### `resource resolve-address-stream` +

                                              resource resolve-address-stream


                                              Functions

                                              resolve-addresses: func

                                              @@ -3038,7 +3042,7 @@ It's planned to be removed when future is natively supported in Pre -

                                              Import interface wasi:random/random@0.2.7

                                              +

                                              Import interface wasi:random/random@0.2.8

                                              WASI Random is a random data API.

                                              It is intended to be portable at least between Unix-family platforms and Windows.

                                              @@ -3071,7 +3075,7 @@ represented as a u64.

                                              • u64
                                              -

                                              Import interface wasi:random/insecure@0.2.7

                                              +

                                              Import interface wasi:random/insecure@0.2.8

                                              The insecure interface for insecure pseudo-random numbers.

                                              It is intended to be portable at least between Unix-family platforms and Windows.

                                              @@ -3100,7 +3104,7 @@ a long period.

                                              • u64
                                              -

                                              Import interface wasi:random/insecure-seed@0.2.7

                                              +

                                              Import interface wasi:random/insecure-seed@0.2.8

                                              The insecure-seed interface for seeding hash-map DoS resistance.

                                              It is intended to be portable at least between Unix-family platforms and Windows.

                                              diff --git a/proposals/cli/wit/command.wit b/proposals/cli/wit/command.wit index dfecf913e..38ef86b86 100644 --- a/proposals/cli/wit/command.wit +++ b/proposals/cli/wit/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.7; +package wasi:cli@0.2.8; @since(version = 0.2.0) world command { diff --git a/proposals/cli/wit/deps.lock b/proposals/cli/wit/deps.lock index dc0c8620a..525406a2b 100644 --- a/proposals/cli/wit/deps.lock +++ b/proposals/cli/wit/deps.lock @@ -1,24 +1,24 @@ [clocks] -sha256 = "d0a8d048c41b566b978cd8ecd03fa51ec1f65af4c26be2f0fc9cfdd7dd6f34f3" -sha512 = "8d1c9ddaaea70ae54376bfc02dcdd0437336fb4fc67f89763ce09540caefe84cbae89a8de3605aa7613c49188636e925047bcd150c2c60685850095fefb68b73" +sha256 = "be1d8c61e2544e2b48d902c60df73577e293349063344ce752cda4d323f8b913" +sha512 = "0fd7962c62b135da0e584c2b58a55147bf09873848b0bb5bd3913019bc3f8d4b5969fbd6f7f96fd99a015efaf562a3eeafe3bc13049f8572a6e13ef9ef0e7e75" [filesystem] -url = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.7.tar.gz" -sha256 = "55942d9c31ed62d05d32d62d211a5c93983df7c0f1489124ca120cf58c4d61c0" -sha512 = "1250a19334ad6acf18adead4503f22c99bfbca7cfb7267431547d4bcca34f91e9635648d00f064276086887a9c80ffacbf68bee832b9e4cd1c921bec0776717f" +url = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.8.tar.gz" +sha256 = "57c2e5e40c57d54a2eacb55d8855d2963a6c0b33971a3620c1468b732233d593" +sha512 = "11d1dee738bea1fdd15f5cc07ea10bfb9953a4e84361bbdc2c1051f9520463329ec839caffe0e5cf22870584846f9bfe627c1b77ee4b555fcc990b8106791c68" deps = ["clocks", "io"] [io] -sha256 = "62ae80f2e340cddbac8e94f78e6270735aea536367ecb98de5f4ac6aef66b5c4" -sha512 = "a02a1ebd261ae884b0315b3528d1a93819ddc4b616f66c77f2bea9dd1de888208dc3b9004a553363f5e8491ea925d65ebbd0d68eaa87238316b47469a3bf97bb" +sha256 = "9f1ad5da70f621bbd4c69e3bd90250a0c12ecfde266aa8f99684fc44bc1e7c15" +sha512 = "6d0a9db6848f24762933d1c168a5b5b1065ba838c253ee20454afeb8dd1a049b918d25deff556083d68095dd3126ae131ac3e738774320eee5d918f5a4b5354e" [random] -url = "https://github.com/WebAssembly/wasi-random/archive/v0.2.7.tar.gz" -sha256 = "168a5a22cfc489bbde2a2ce38d3a20b5c418fb099d3993196fca2129f8e9bfc0" -sha512 = "1641fed653abe0991cdeee330bf6d3f6e17b9d2b3b9766588c792f181e8133727efa20feb41d0f325e3db8158ce51948c2d6648e02e8998df8eba3c88959bfca" +url = "https://github.com/WebAssembly/wasi-random/archive/v0.2.8.tar.gz" +sha256 = "febd6f75dec1fa733b8e25c1cdee4de9acd922ddf755a192d85f479b1f96b445" +sha512 = "1689d2eee3c64b9fc91faaf43741ff95f343b05acc758342dbf3aa86830de1ec66b4bcd0fe22bf1f77abc4a1feeaae90cdc2c06eedc30952a6667f70edca7d8f" [sockets] -url = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.7.tar.gz" -sha256 = "33b150bb413c6f4e2ab1ab12b6da822d6c712f13a0644177b108f57dff5783d6" -sha512 = "47efa2fea61374da2853b4ff2aed394b54c8e1d164ce6706332bd1056a16c2eb0a8d7c0ab5408a8b08537b615197ff4a44bdb5d132772a8d6049de5c39ec5e68" +url = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.8.tar.gz" +sha256 = "e82bb0502324f44ef22f6fdadec51f4963faf8ccd21187c37397ea872c0548c0" +sha512 = "b8139db2b26a95d6948e345cf036497883943134ea832abfabd7267682d9f84b4c86ff38fc771125f1a8e2bcd237ea0a731d83bf22df9d78f19e452061227d77" deps = ["clocks", "io"] diff --git a/proposals/cli/wit/deps.toml b/proposals/cli/wit/deps.toml index fd5a7018a..59d97afe4 100644 --- a/proposals/cli/wit/deps.toml +++ b/proposals/cli/wit/deps.toml @@ -1,3 +1,3 @@ -filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.7.tar.gz" -random = "https://github.com/WebAssembly/wasi-random/archive/v0.2.7.tar.gz" -sockets = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.7.tar.gz" +filesystem = "https://github.com/WebAssembly/wasi-filesystem/archive/v0.2.8.tar.gz" +random = "https://github.com/WebAssembly/wasi-random/archive/v0.2.8.tar.gz" +sockets = "https://github.com/WebAssembly/wasi-sockets/archive/v0.2.8.tar.gz" diff --git a/proposals/cli/wit/deps/clocks/monotonic-clock.wit b/proposals/cli/wit/deps/clocks/monotonic-clock.wit index 98a9ad42a..e60f366f2 100644 --- a/proposals/cli/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/cli/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.7; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from @@ -26,6 +26,11 @@ interface monotonic-clock { /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + /// + /// For completeness, this function traps if it's not possible to represent + /// the value of the clock in an `instant`. Consequently, implementations + /// should ensure that the starting time is low enough to avoid the + /// possibility of overflow in practice. @since(version = 0.2.0) now: func() -> instant; diff --git a/proposals/cli/wit/deps/clocks/timezone.wit b/proposals/cli/wit/deps/clocks/timezone.wit index 4740bde00..534814a63 100644 --- a/proposals/cli/wit/deps/clocks/timezone.wit +++ b/proposals/cli/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/cli/wit/deps/clocks/wall-clock.wit b/proposals/cli/wit/deps/clocks/wall-clock.wit index 2179b6c56..3386c800b 100644 --- a/proposals/cli/wit/deps/clocks/wall-clock.wit +++ b/proposals/cli/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/cli/wit/deps/clocks/world.wit b/proposals/cli/wit/deps/clocks/world.wit index a08ff2c2c..1655ca830 100644 --- a/proposals/cli/wit/deps/clocks/world.wit +++ b/proposals/cli/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/filesystem/preopens.wit b/proposals/cli/wit/deps/filesystem/preopens.wit index b1a0a9972..0d2cca65d 100644 --- a/proposals/cli/wit/deps/filesystem/preopens.wit +++ b/proposals/cli/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.7; +package wasi:filesystem@0.2.8; @since(version = 0.2.0) interface preopens { diff --git a/proposals/cli/wit/deps/filesystem/types.wit b/proposals/cli/wit/deps/filesystem/types.wit index a7da2b72f..ac68f88af 100644 --- a/proposals/cli/wit/deps/filesystem/types.wit +++ b/proposals/cli/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.7; +package wasi:filesystem@0.2.8; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.7; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.7.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.8.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.7.{datetime}; + use wasi:clocks/wall-clock@0.2.8.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/cli/wit/deps/filesystem/world.wit b/proposals/cli/wit/deps/filesystem/world.wit index 67309b43f..7daf06758 100644 --- a/proposals/cli/wit/deps/filesystem/world.wit +++ b/proposals/cli/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.7; +package wasi:filesystem@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/io/error.wit b/proposals/cli/wit/deps/io/error.wit index acab3a811..dd5a1af03 100644 --- a/proposals/cli/wit/deps/io/error.wit +++ b/proposals/cli/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; @since(version = 0.2.0) interface error { diff --git a/proposals/cli/wit/deps/io/poll.wit b/proposals/cli/wit/deps/io/poll.wit index a525164b9..833b381d9 100644 --- a/proposals/cli/wit/deps/io/poll.wit +++ b/proposals/cli/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/cli/wit/deps/io/streams.wit b/proposals/cli/wit/deps/io/streams.wit index 7ae29a3cd..fbb0268b0 100644 --- a/proposals/cli/wit/deps/io/streams.wit +++ b/proposals/cli/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/cli/wit/deps/io/world.wit b/proposals/cli/wit/deps/io/world.wit index 73b1a6df5..1cc3fce12 100644 --- a/proposals/cli/wit/deps/io/world.wit +++ b/proposals/cli/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/random/insecure-seed.wit b/proposals/cli/wit/deps/random/insecure-seed.wit index 0209b84b0..b2b435e55 100644 --- a/proposals/cli/wit/deps/random/insecure-seed.wit +++ b/proposals/cli/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/insecure.wit b/proposals/cli/wit/deps/random/insecure.wit index 820d069ee..6dc77adec 100644 --- a/proposals/cli/wit/deps/random/insecure.wit +++ b/proposals/cli/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/random.wit b/proposals/cli/wit/deps/random/random.wit index 974ab465d..524e77d4a 100644 --- a/proposals/cli/wit/deps/random/random.wit +++ b/proposals/cli/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/cli/wit/deps/random/world.wit b/proposals/cli/wit/deps/random/world.wit index 333b42598..c0c3272c9 100644 --- a/proposals/cli/wit/deps/random/world.wit +++ b/proposals/cli/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit index df2735aac..ecdaa8493 100644 --- a/proposals/cli/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/cli/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/cli/wit/deps/sockets/network.wit b/proposals/cli/wit/deps/sockets/network.wit index 95df71ff3..75a4f7d7f 100644 --- a/proposals/cli/wit/deps/sockets/network.wit +++ b/proposals/cli/wit/deps/sockets/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.7.{error}; + use wasi:io/error@0.2.8.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/cli/wit/deps/sockets/tcp.wit b/proposals/cli/wit/deps/sockets/tcp.wit index 104d9aa39..9b5552d2e 100644 --- a/proposals/cli/wit/deps/sockets/tcp.wit +++ b/proposals/cli/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.7.{input-stream, output-stream}; + use wasi:io/streams@0.2.8.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.7.{duration}; + use wasi:clocks/monotonic-clock@0.2.8.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/cli/wit/deps/sockets/udp.wit b/proposals/cli/wit/deps/sockets/udp.wit index ecf2dfe60..0000a157e 100644 --- a/proposals/cli/wit/deps/sockets/udp.wit +++ b/proposals/cli/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/cli/wit/deps/sockets/world.wit b/proposals/cli/wit/deps/sockets/world.wit index 9a4d317f7..4441e9119 100644 --- a/proposals/cli/wit/deps/sockets/world.wit +++ b/proposals/cli/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.7; +package wasi:sockets@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/cli/wit/imports.wit b/proposals/cli/wit/imports.wit index e7f7942de..cec1be520 100644 --- a/proposals/cli/wit/imports.wit +++ b/proposals/cli/wit/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.7; +package wasi:cli@0.2.8; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.7; + include wasi:clocks/imports@0.2.8; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.7; + include wasi:filesystem/imports@0.2.8; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.7; + include wasi:sockets/imports@0.2.8; @since(version = 0.2.0) - include wasi:random/imports@0.2.7; + include wasi:random/imports@0.2.8; @since(version = 0.2.0) - include wasi:io/imports@0.2.7; + include wasi:io/imports@0.2.8; @since(version = 0.2.0) import environment; diff --git a/proposals/cli/wit/stdio.wit b/proposals/cli/wit/stdio.wit index 1c3c6d074..44767c647 100644 --- a/proposals/cli/wit/stdio.wit +++ b/proposals/cli/wit/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.7.{input-stream}; + use wasi:io/streams@0.2.8.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.7.{output-stream}; + use wasi:io/streams@0.2.8.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.7.{output-stream}; + use wasi:io/streams@0.2.8.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; From 5c7a4e0ee801fd5ff4b5766f368e5c70b05e1902 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 15:26:59 +0000 Subject: [PATCH 1757/1772] Update to v0.2.8 --- proposals/http/imports.md | 96 ++++++++-------- proposals/http/proxy.md | 106 +++++++++--------- proposals/http/wit/deps.lock | 26 ++--- proposals/http/wit/deps.toml | 2 +- proposals/http/wit/deps/cli/command.wit | 2 +- proposals/http/wit/deps/cli/imports.wit | 12 +- proposals/http/wit/deps/cli/stdio.wit | 6 +- .../http/wit/deps/clocks/monotonic-clock.wit | 9 +- proposals/http/wit/deps/clocks/timezone.wit | 2 +- proposals/http/wit/deps/clocks/wall-clock.wit | 2 +- proposals/http/wit/deps/clocks/world.wit | 2 +- .../http/wit/deps/filesystem/preopens.wit | 2 +- proposals/http/wit/deps/filesystem/types.wit | 6 +- proposals/http/wit/deps/filesystem/world.wit | 2 +- proposals/http/wit/deps/io/error.wit | 2 +- proposals/http/wit/deps/io/poll.wit | 2 +- proposals/http/wit/deps/io/streams.wit | 2 +- proposals/http/wit/deps/io/world.wit | 2 +- .../http/wit/deps/random/insecure-seed.wit | 2 +- proposals/http/wit/deps/random/insecure.wit | 2 +- proposals/http/wit/deps/random/random.wit | 2 +- proposals/http/wit/deps/random/world.wit | 2 +- .../http/wit/deps/sockets/ip-name-lookup.wit | 2 +- proposals/http/wit/deps/sockets/network.wit | 2 +- proposals/http/wit/deps/sockets/tcp.wit | 6 +- proposals/http/wit/deps/sockets/udp.wit | 2 +- proposals/http/wit/deps/sockets/world.wit | 2 +- proposals/http/wit/proxy.wit | 14 +-- proposals/http/wit/types.wit | 8 +- 29 files changed, 170 insertions(+), 157 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index 49a15d2f5..9fbc19df9 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -4,21 +4,21 @@ It is intended to be included in other worlds.

                                              -

                                              Import interface wasi:io/poll@0.2.7

                                              +

                                              Import interface wasi:io/poll@0.2.8

                                              A poll API intended to let users wait for I/O events on multiple handles at once.


                                              @@ -71,7 +71,7 @@ being ready for I/O.

                                              • list<u32>
                                              -

                                              Import interface wasi:clocks/monotonic-clock@0.2.7

                                              +

                                              Import interface wasi:clocks/monotonic-clock@0.2.8

                                              WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                                              It is intended to be portable at least between Unix-family platforms and @@ -83,8 +83,8 @@ successive reads of the clock will produce non-decreasing values.

                                              type pollable

                                              pollable

                                              -#### `type instant` -`u64` +

                                              type instant

                                              +

                                              u64

                                              An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. @@ -97,6 +97,10 @@ the same monotonic-clock.

                                              Read the current value of the clock.

                                              The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

                                              +

                                              For completeness, this function traps if it's not possible to represent +the value of the clock in an instant. Consequently, implementations +should ensure that the starting time is low enough to avoid the +possibility of overflow in practice.

                                              Return values
                                              • instant
                                              • @@ -130,7 +134,7 @@ elapsed from the time this function is invoked.

                                                -

                                                Import interface wasi:clocks/wall-clock@0.2.7

                                                +

                                                Import interface wasi:clocks/wall-clock@0.2.8

                                                WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                                                @@ -171,7 +175,7 @@ also known as Unix Time.
                                              • datetime
                                              -

                                              Import interface wasi:random/random@0.2.7

                                              +

                                              Import interface wasi:random/random@0.2.8

                                              WASI Random is a random data API.

                                              It is intended to be portable at least between Unix-family platforms and Windows.

                                              @@ -204,7 +208,7 @@ represented as a u64.

                                              • u64
                                              -

                                              Import interface wasi:io/error@0.2.7

                                              +

                                              Import interface wasi:io/error@0.2.8


                                              Types

                                              resource error

                                              @@ -237,7 +241,7 @@ hazard.

                                              • string
                                              -

                                              Import interface wasi:io/streams@0.2.7

                                              +

                                              Import interface wasi:io/streams@0.2.8

                                              WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                                              In the future, the component model is expected to add built-in stream types; @@ -247,10 +251,10 @@ when it does, they are expected to subsume this API.

                                              type error

                                              error

                                              -#### `type pollable` -[`pollable`](#pollable) +

                                              type pollable

                                              +

                                              pollable

                                              -#### `variant stream-error` +

                                              variant stream-error

                                              An error for input-stream and output-stream operations.

                                              Variant Cases
                                                @@ -539,46 +543,46 @@ is ready for reading, before performing the splice.

                                                -

                                                Import interface wasi:cli/stdout@0.2.7

                                                +

                                                Import interface wasi:cli/stdout@0.2.8


                                                Types

                                                type output-stream

                                                output-stream

                                                ----- +


                                                Functions

                                                get-stdout: func

                                                Return values
                                                -

                                                Import interface wasi:cli/stderr@0.2.7

                                                +

                                                Import interface wasi:cli/stderr@0.2.8


                                                Types

                                                type output-stream

                                                output-stream

                                                ----- +


                                                Functions

                                                get-stderr: func

                                                Return values
                                                -

                                                Import interface wasi:cli/stdin@0.2.7

                                                +

                                                Import interface wasi:cli/stdin@0.2.8


                                                Types

                                                type input-stream

                                                input-stream

                                                ----- +


                                                Functions

                                                get-stdin: func

                                                Return values
                                                -

                                                Import interface wasi:http/types@0.2.7

                                                +

                                                Import interface wasi:http/types@0.2.8

                                                This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                                                @@ -587,19 +591,19 @@ their headers, trailers, and bodies.

                                                type duration

                                                duration

                                                -#### `type input-stream` -[`input-stream`](#input_stream) +

                                                type input-stream

                                                +

                                                input-stream

                                                -#### `type output-stream` -[`output-stream`](#output_stream) +

                                                type output-stream

                                                +

                                                output-stream

                                                -#### `type io-error` -[`error`](#error) +

                                                type io-error

                                                +

                                                error

                                                -#### `type pollable` -[`pollable`](#pollable) +

                                                type pollable

                                                +

                                                pollable

                                                -#### `variant method` +

                                                variant method

                                                This type corresponds to HTTP standard Methods.

                                                Variant Cases
                                                -

                                                Import interface wasi:http/outgoing-handler@0.2.7

                                                +

                                                Import interface wasi:http/outgoing-handler@0.2.8

                                                This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                                                @@ -1506,16 +1510,16 @@ imported by components which wish to make HTTP Requests.

                                                type outgoing-request

                                                outgoing-request

                                                -#### `type request-options` -[`request-options`](#request_options) +

                                                type request-options

                                                +

                                                request-options

                                                -#### `type future-incoming-response` -[`future-incoming-response`](#future_incoming_response) +

                                                type future-incoming-response

                                                +

                                                future-incoming-response

                                                -#### `type error-code` -[`error-code`](#error_code) +

                                                type error-code

                                                +

                                                error-code

                                                ----- +


                                                Functions

                                                handle: func

                                                This function is invoked with an outgoing HTTP Request, and it returns diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 990350382..019f84a62 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -6,26 +6,26 @@ outgoing HTTP requests.

                                                -

                                                Import interface wasi:io/poll@0.2.7

                                                +

                                                Import interface wasi:io/poll@0.2.8

                                                A poll API intended to let users wait for I/O events on multiple handles at once.


                                                @@ -78,7 +78,7 @@ being ready for I/O.

                                                • list<u32>
                                                -

                                                Import interface wasi:clocks/monotonic-clock@0.2.7

                                                +

                                                Import interface wasi:clocks/monotonic-clock@0.2.8

                                                WASI Monotonic Clock is a clock API intended to let users measure elapsed time.

                                                It is intended to be portable at least between Unix-family platforms and @@ -90,8 +90,8 @@ successive reads of the clock will produce non-decreasing values.

                                                type pollable

                                                pollable

                                                -#### `type instant` -`u64` +

                                                type instant

                                                +

                                                u64

                                                An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. @@ -104,6 +104,10 @@ the same monotonic-clock.

                                                Read the current value of the clock.

                                                The clock is monotonic, therefore calling this function repeatedly will produce a sequence of non-decreasing values.

                                                +

                                                For completeness, this function traps if it's not possible to represent +the value of the clock in an instant. Consequently, implementations +should ensure that the starting time is low enough to avoid the +possibility of overflow in practice.

                                                Return values
                                                • instant
                                                • @@ -137,7 +141,7 @@ elapsed from the time this function is invoked.

                                                  -

                                                  Import interface wasi:clocks/wall-clock@0.2.7

                                                  +

                                                  Import interface wasi:clocks/wall-clock@0.2.8

                                                  WASI Wall Clock is a clock API intended to let users query the current time. The name "wall" makes an analogy to a "clock on the wall", which is not necessarily monotonic as it may be reset.

                                                  @@ -178,7 +182,7 @@ also known as Unix Time.
                                                • datetime
                                                -

                                                Import interface wasi:random/random@0.2.7

                                                +

                                                Import interface wasi:random/random@0.2.8

                                                WASI Random is a random data API.

                                                It is intended to be portable at least between Unix-family platforms and Windows.

                                                @@ -211,7 +215,7 @@ represented as a u64.

                                                • u64
                                                -

                                                Import interface wasi:io/error@0.2.7

                                                +

                                                Import interface wasi:io/error@0.2.8


                                                Types

                                                resource error

                                                @@ -244,7 +248,7 @@ hazard.

                                                • string
                                                -

                                                Import interface wasi:io/streams@0.2.7

                                                +

                                                Import interface wasi:io/streams@0.2.8

                                                WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

                                                In the future, the component model is expected to add built-in stream types; @@ -254,10 +258,10 @@ when it does, they are expected to subsume this API.

                                                type error

                                                error

                                                -#### `type pollable` -[`pollable`](#pollable) +

                                                type pollable

                                                +

                                                pollable

                                                -#### `variant stream-error` +

                                                variant stream-error

                                                An error for input-stream and output-stream operations.

                                                Variant Cases
                                                  @@ -546,46 +550,46 @@ is ready for reading, before performing the splice.

                                                  -

                                                  Import interface wasi:cli/stdout@0.2.7

                                                  +

                                                  Import interface wasi:cli/stdout@0.2.8


                                                  Types

                                                  type output-stream

                                                  output-stream

                                                  ----- +


                                                  Functions

                                                  get-stdout: func

                                                  Return values
                                                  -

                                                  Import interface wasi:cli/stderr@0.2.7

                                                  +

                                                  Import interface wasi:cli/stderr@0.2.8


                                                  Types

                                                  type output-stream

                                                  output-stream

                                                  ----- +


                                                  Functions

                                                  get-stderr: func

                                                  Return values
                                                  -

                                                  Import interface wasi:cli/stdin@0.2.7

                                                  +

                                                  Import interface wasi:cli/stdin@0.2.8


                                                  Types

                                                  type input-stream

                                                  input-stream

                                                  ----- +


                                                  Functions

                                                  get-stdin: func

                                                  Return values
                                                  -

                                                  Import interface wasi:http/types@0.2.7

                                                  +

                                                  Import interface wasi:http/types@0.2.8

                                                  This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

                                                  @@ -594,19 +598,19 @@ their headers, trailers, and bodies.

                                                  type duration

                                                  duration

                                                  -#### `type input-stream` -[`input-stream`](#input_stream) +

                                                  type input-stream

                                                  +

                                                  input-stream

                                                  -#### `type output-stream` -[`output-stream`](#output_stream) +

                                                  type output-stream

                                                  +

                                                  output-stream

                                                  -#### `type io-error` -[`error`](#error) +

                                                  type io-error

                                                  +

                                                  error

                                                  -#### `type pollable` -[`pollable`](#pollable) +

                                                  type pollable

                                                  +

                                                  pollable

                                                  -#### `variant method` +

                                                  variant method

                                                  This type corresponds to HTTP standard Methods.

                                                  Variant Cases
                                                  -

                                                  Import interface wasi:http/outgoing-handler@0.2.7

                                                  +

                                                  Import interface wasi:http/outgoing-handler@0.2.8

                                                  This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.


                                                  @@ -1513,16 +1517,16 @@ imported by components which wish to make HTTP Requests.

                                                  type outgoing-request

                                                  outgoing-request

                                                  -#### `type request-options` -[`request-options`](#request_options) +

                                                  type request-options

                                                  +

                                                  request-options

                                                  -#### `type future-incoming-response` -[`future-incoming-response`](#future_incoming_response) +

                                                  type future-incoming-response

                                                  +

                                                  future-incoming-response

                                                  -#### `type error-code` -[`error-code`](#error_code) +

                                                  type error-code

                                                  +

                                                  error-code

                                                  ----- +


                                                  Functions

                                                  handle: func

                                                  This function is invoked with an outgoing HTTP Request, and it returns @@ -1542,16 +1546,16 @@ through the future-incoming-response

                                                • result<own<future-incoming-response>, error-code>
                                                -

                                                Export interface wasi:http/incoming-handler@0.2.7

                                                +

                                                Export interface wasi:http/incoming-handler@0.2.8


                                                Types

                                                type incoming-request

                                                incoming-request

                                                -#### `type response-outparam` -[`response-outparam`](#response_outparam) +

                                                type response-outparam

                                                +

                                                response-outparam

                                                ----- +


                                                Functions

                                                handle: func

                                                This function is invoked with an incoming HTTP Request, and a resource diff --git a/proposals/http/wit/deps.lock b/proposals/http/wit/deps.lock index de72b0a79..cac326b93 100644 --- a/proposals/http/wit/deps.lock +++ b/proposals/http/wit/deps.lock @@ -1,25 +1,25 @@ [cli] -url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.7.tar.gz" -sha256 = "0595631e4b6c425fd5b976315cbb278248c7c1aa20c368bfb0c6581b0cbba274" -sha512 = "2cf8b0575382a823aa0f7f943ad980a4a8076843600882fb046a753bd10a1dbf92b966e2087e892b7d9f35e6e25110514ee8269249c16977323fb2914a248ab9" +url = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.8.tar.gz" +sha256 = "d223b55ba73b8a265cc36db836487a16dcb1ed859d92a693827ad5ca2d2dfba8" +sha512 = "db0dd1a7225f08b27092f75aa32ca3e9fc6cda666cdf0a46521ca32702a1985f4e7b7c5b78e61f6eef348c2807d09fb8c11ccfc95d572465aa86f4024d44afa0" deps = ["clocks", "filesystem", "io", "random", "sockets"] [clocks] -sha256 = "d0a8d048c41b566b978cd8ecd03fa51ec1f65af4c26be2f0fc9cfdd7dd6f34f3" -sha512 = "8d1c9ddaaea70ae54376bfc02dcdd0437336fb4fc67f89763ce09540caefe84cbae89a8de3605aa7613c49188636e925047bcd150c2c60685850095fefb68b73" +sha256 = "be1d8c61e2544e2b48d902c60df73577e293349063344ce752cda4d323f8b913" +sha512 = "0fd7962c62b135da0e584c2b58a55147bf09873848b0bb5bd3913019bc3f8d4b5969fbd6f7f96fd99a015efaf562a3eeafe3bc13049f8572a6e13ef9ef0e7e75" [filesystem] -sha256 = "55942d9c31ed62d05d32d62d211a5c93983df7c0f1489124ca120cf58c4d61c0" -sha512 = "1250a19334ad6acf18adead4503f22c99bfbca7cfb7267431547d4bcca34f91e9635648d00f064276086887a9c80ffacbf68bee832b9e4cd1c921bec0776717f" +sha256 = "57c2e5e40c57d54a2eacb55d8855d2963a6c0b33971a3620c1468b732233d593" +sha512 = "11d1dee738bea1fdd15f5cc07ea10bfb9953a4e84361bbdc2c1051f9520463329ec839caffe0e5cf22870584846f9bfe627c1b77ee4b555fcc990b8106791c68" [io] -sha256 = "62ae80f2e340cddbac8e94f78e6270735aea536367ecb98de5f4ac6aef66b5c4" -sha512 = "a02a1ebd261ae884b0315b3528d1a93819ddc4b616f66c77f2bea9dd1de888208dc3b9004a553363f5e8491ea925d65ebbd0d68eaa87238316b47469a3bf97bb" +sha256 = "9f1ad5da70f621bbd4c69e3bd90250a0c12ecfde266aa8f99684fc44bc1e7c15" +sha512 = "6d0a9db6848f24762933d1c168a5b5b1065ba838c253ee20454afeb8dd1a049b918d25deff556083d68095dd3126ae131ac3e738774320eee5d918f5a4b5354e" [random] -sha256 = "168a5a22cfc489bbde2a2ce38d3a20b5c418fb099d3993196fca2129f8e9bfc0" -sha512 = "1641fed653abe0991cdeee330bf6d3f6e17b9d2b3b9766588c792f181e8133727efa20feb41d0f325e3db8158ce51948c2d6648e02e8998df8eba3c88959bfca" +sha256 = "febd6f75dec1fa733b8e25c1cdee4de9acd922ddf755a192d85f479b1f96b445" +sha512 = "1689d2eee3c64b9fc91faaf43741ff95f343b05acc758342dbf3aa86830de1ec66b4bcd0fe22bf1f77abc4a1feeaae90cdc2c06eedc30952a6667f70edca7d8f" [sockets] -sha256 = "33b150bb413c6f4e2ab1ab12b6da822d6c712f13a0644177b108f57dff5783d6" -sha512 = "47efa2fea61374da2853b4ff2aed394b54c8e1d164ce6706332bd1056a16c2eb0a8d7c0ab5408a8b08537b615197ff4a44bdb5d132772a8d6049de5c39ec5e68" +sha256 = "e82bb0502324f44ef22f6fdadec51f4963faf8ccd21187c37397ea872c0548c0" +sha512 = "b8139db2b26a95d6948e345cf036497883943134ea832abfabd7267682d9f84b4c86ff38fc771125f1a8e2bcd237ea0a731d83bf22df9d78f19e452061227d77" diff --git a/proposals/http/wit/deps.toml b/proposals/http/wit/deps.toml index b1f5af240..07d395a31 100644 --- a/proposals/http/wit/deps.toml +++ b/proposals/http/wit/deps.toml @@ -1 +1 @@ -cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.7.tar.gz" +cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.8.tar.gz" diff --git a/proposals/http/wit/deps/cli/command.wit b/proposals/http/wit/deps/cli/command.wit index dfecf913e..38ef86b86 100644 --- a/proposals/http/wit/deps/cli/command.wit +++ b/proposals/http/wit/deps/cli/command.wit @@ -1,4 +1,4 @@ -package wasi:cli@0.2.7; +package wasi:cli@0.2.8; @since(version = 0.2.0) world command { diff --git a/proposals/http/wit/deps/cli/imports.wit b/proposals/http/wit/deps/cli/imports.wit index e7f7942de..cec1be520 100644 --- a/proposals/http/wit/deps/cli/imports.wit +++ b/proposals/http/wit/deps/cli/imports.wit @@ -1,17 +1,17 @@ -package wasi:cli@0.2.7; +package wasi:cli@0.2.8; @since(version = 0.2.0) world imports { @since(version = 0.2.0) - include wasi:clocks/imports@0.2.7; + include wasi:clocks/imports@0.2.8; @since(version = 0.2.0) - include wasi:filesystem/imports@0.2.7; + include wasi:filesystem/imports@0.2.8; @since(version = 0.2.0) - include wasi:sockets/imports@0.2.7; + include wasi:sockets/imports@0.2.8; @since(version = 0.2.0) - include wasi:random/imports@0.2.7; + include wasi:random/imports@0.2.8; @since(version = 0.2.0) - include wasi:io/imports@0.2.7; + include wasi:io/imports@0.2.8; @since(version = 0.2.0) import environment; diff --git a/proposals/http/wit/deps/cli/stdio.wit b/proposals/http/wit/deps/cli/stdio.wit index 1c3c6d074..44767c647 100644 --- a/proposals/http/wit/deps/cli/stdio.wit +++ b/proposals/http/wit/deps/cli/stdio.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface stdin { @since(version = 0.2.0) - use wasi:io/streams@0.2.7.{input-stream}; + use wasi:io/streams@0.2.8.{input-stream}; @since(version = 0.2.0) get-stdin: func() -> input-stream; @@ -10,7 +10,7 @@ interface stdin { @since(version = 0.2.0) interface stdout { @since(version = 0.2.0) - use wasi:io/streams@0.2.7.{output-stream}; + use wasi:io/streams@0.2.8.{output-stream}; @since(version = 0.2.0) get-stdout: func() -> output-stream; @@ -19,7 +19,7 @@ interface stdout { @since(version = 0.2.0) interface stderr { @since(version = 0.2.0) - use wasi:io/streams@0.2.7.{output-stream}; + use wasi:io/streams@0.2.8.{output-stream}; @since(version = 0.2.0) get-stderr: func() -> output-stream; diff --git a/proposals/http/wit/deps/clocks/monotonic-clock.wit b/proposals/http/wit/deps/clocks/monotonic-clock.wit index 98a9ad42a..e60f366f2 100644 --- a/proposals/http/wit/deps/clocks/monotonic-clock.wit +++ b/proposals/http/wit/deps/clocks/monotonic-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; /// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// time. /// @@ -10,7 +10,7 @@ package wasi:clocks@0.2.7; @since(version = 0.2.0) interface monotonic-clock { @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; /// An instant in time, in nanoseconds. An instant is relative to an /// unspecified initial value, and can only be compared to instances from @@ -26,6 +26,11 @@ interface monotonic-clock { /// /// The clock is monotonic, therefore calling this function repeatedly will /// produce a sequence of non-decreasing values. + /// + /// For completeness, this function traps if it's not possible to represent + /// the value of the clock in an `instant`. Consequently, implementations + /// should ensure that the starting time is low enough to avoid the + /// possibility of overflow in practice. @since(version = 0.2.0) now: func() -> instant; diff --git a/proposals/http/wit/deps/clocks/timezone.wit b/proposals/http/wit/deps/clocks/timezone.wit index 4740bde00..534814a63 100644 --- a/proposals/http/wit/deps/clocks/timezone.wit +++ b/proposals/http/wit/deps/clocks/timezone.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; @unstable(feature = clocks-timezone) interface timezone { diff --git a/proposals/http/wit/deps/clocks/wall-clock.wit b/proposals/http/wit/deps/clocks/wall-clock.wit index 2179b6c56..3386c800b 100644 --- a/proposals/http/wit/deps/clocks/wall-clock.wit +++ b/proposals/http/wit/deps/clocks/wall-clock.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; /// WASI Wall Clock is a clock API intended to let users query the current /// time. The name "wall" makes an analogy to a "clock on the wall", which /// is not necessarily monotonic as it may be reset. diff --git a/proposals/http/wit/deps/clocks/world.wit b/proposals/http/wit/deps/clocks/world.wit index a08ff2c2c..1655ca830 100644 --- a/proposals/http/wit/deps/clocks/world.wit +++ b/proposals/http/wit/deps/clocks/world.wit @@ -1,4 +1,4 @@ -package wasi:clocks@0.2.7; +package wasi:clocks@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/filesystem/preopens.wit b/proposals/http/wit/deps/filesystem/preopens.wit index b1a0a9972..0d2cca65d 100644 --- a/proposals/http/wit/deps/filesystem/preopens.wit +++ b/proposals/http/wit/deps/filesystem/preopens.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.7; +package wasi:filesystem@0.2.8; @since(version = 0.2.0) interface preopens { diff --git a/proposals/http/wit/deps/filesystem/types.wit b/proposals/http/wit/deps/filesystem/types.wit index a7da2b72f..ac68f88af 100644 --- a/proposals/http/wit/deps/filesystem/types.wit +++ b/proposals/http/wit/deps/filesystem/types.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.7; +package wasi:filesystem@0.2.8; /// WASI filesystem is a filesystem API primarily intended to let users run WASI /// programs that access their files on their existing filesystems, without /// significant overhead. @@ -26,9 +26,9 @@ package wasi:filesystem@0.2.7; @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:io/streams@0.2.7.{input-stream, output-stream, error}; + use wasi:io/streams@0.2.8.{input-stream, output-stream, error}; @since(version = 0.2.0) - use wasi:clocks/wall-clock@0.2.7.{datetime}; + use wasi:clocks/wall-clock@0.2.8.{datetime}; /// File size or length of a region within a file. @since(version = 0.2.0) diff --git a/proposals/http/wit/deps/filesystem/world.wit b/proposals/http/wit/deps/filesystem/world.wit index 67309b43f..7daf06758 100644 --- a/proposals/http/wit/deps/filesystem/world.wit +++ b/proposals/http/wit/deps/filesystem/world.wit @@ -1,4 +1,4 @@ -package wasi:filesystem@0.2.7; +package wasi:filesystem@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/io/error.wit b/proposals/http/wit/deps/io/error.wit index acab3a811..dd5a1af03 100644 --- a/proposals/http/wit/deps/io/error.wit +++ b/proposals/http/wit/deps/io/error.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; @since(version = 0.2.0) interface error { diff --git a/proposals/http/wit/deps/io/poll.wit b/proposals/http/wit/deps/io/poll.wit index a525164b9..833b381d9 100644 --- a/proposals/http/wit/deps/io/poll.wit +++ b/proposals/http/wit/deps/io/poll.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; /// A poll API intended to let users wait for I/O events on multiple handles /// at once. diff --git a/proposals/http/wit/deps/io/streams.wit b/proposals/http/wit/deps/io/streams.wit index 7ae29a3cd..fbb0268b0 100644 --- a/proposals/http/wit/deps/io/streams.wit +++ b/proposals/http/wit/deps/io/streams.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. diff --git a/proposals/http/wit/deps/io/world.wit b/proposals/http/wit/deps/io/world.wit index 73b1a6df5..1cc3fce12 100644 --- a/proposals/http/wit/deps/io/world.wit +++ b/proposals/http/wit/deps/io/world.wit @@ -1,4 +1,4 @@ -package wasi:io@0.2.7; +package wasi:io@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/random/insecure-seed.wit b/proposals/http/wit/deps/random/insecure-seed.wit index 0209b84b0..b2b435e55 100644 --- a/proposals/http/wit/deps/random/insecure-seed.wit +++ b/proposals/http/wit/deps/random/insecure-seed.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; /// The insecure-seed interface for seeding hash-map DoS resistance. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/insecure.wit b/proposals/http/wit/deps/random/insecure.wit index 820d069ee..6dc77adec 100644 --- a/proposals/http/wit/deps/random/insecure.wit +++ b/proposals/http/wit/deps/random/insecure.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; /// The insecure interface for insecure pseudo-random numbers. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/random.wit b/proposals/http/wit/deps/random/random.wit index 974ab465d..524e77d4a 100644 --- a/proposals/http/wit/deps/random/random.wit +++ b/proposals/http/wit/deps/random/random.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and diff --git a/proposals/http/wit/deps/random/world.wit b/proposals/http/wit/deps/random/world.wit index 333b42598..c0c3272c9 100644 --- a/proposals/http/wit/deps/random/world.wit +++ b/proposals/http/wit/deps/random/world.wit @@ -1,4 +1,4 @@ -package wasi:random@0.2.7; +package wasi:random@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/deps/sockets/ip-name-lookup.wit b/proposals/http/wit/deps/sockets/ip-name-lookup.wit index df2735aac..ecdaa8493 100644 --- a/proposals/http/wit/deps/sockets/ip-name-lookup.wit +++ b/proposals/http/wit/deps/sockets/ip-name-lookup.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface ip-name-lookup { @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-address}; diff --git a/proposals/http/wit/deps/sockets/network.wit b/proposals/http/wit/deps/sockets/network.wit index 95df71ff3..75a4f7d7f 100644 --- a/proposals/http/wit/deps/sockets/network.wit +++ b/proposals/http/wit/deps/sockets/network.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface network { @unstable(feature = network-error-code) - use wasi:io/error@0.2.7.{error}; + use wasi:io/error@0.2.8.{error}; /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. diff --git a/proposals/http/wit/deps/sockets/tcp.wit b/proposals/http/wit/deps/sockets/tcp.wit index 104d9aa39..9b5552d2e 100644 --- a/proposals/http/wit/deps/sockets/tcp.wit +++ b/proposals/http/wit/deps/sockets/tcp.wit @@ -1,11 +1,11 @@ @since(version = 0.2.0) interface tcp { @since(version = 0.2.0) - use wasi:io/streams@0.2.7.{input-stream, output-stream}; + use wasi:io/streams@0.2.8.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.7.{duration}; + use wasi:clocks/monotonic-clock@0.2.8.{duration}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit/deps/sockets/udp.wit b/proposals/http/wit/deps/sockets/udp.wit index ecf2dfe60..0000a157e 100644 --- a/proposals/http/wit/deps/sockets/udp.wit +++ b/proposals/http/wit/deps/sockets/udp.wit @@ -1,7 +1,7 @@ @since(version = 0.2.0) interface udp { @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; @since(version = 0.2.0) use network.{network, error-code, ip-socket-address, ip-address-family}; diff --git a/proposals/http/wit/deps/sockets/world.wit b/proposals/http/wit/deps/sockets/world.wit index 9a4d317f7..4441e9119 100644 --- a/proposals/http/wit/deps/sockets/world.wit +++ b/proposals/http/wit/deps/sockets/world.wit @@ -1,4 +1,4 @@ -package wasi:sockets@0.2.7; +package wasi:sockets@0.2.8; @since(version = 0.2.0) world imports { diff --git a/proposals/http/wit/proxy.wit b/proposals/http/wit/proxy.wit index b503ea795..5ae19e6d7 100644 --- a/proposals/http/wit/proxy.wit +++ b/proposals/http/wit/proxy.wit @@ -1,4 +1,4 @@ -package wasi:http@0.2.7; +package wasi:http@0.2.8; /// The `wasi:http/imports` world imports all the APIs for HTTP proxies. /// It is intended to be `include`d in other worlds. @@ -6,25 +6,25 @@ package wasi:http@0.2.7; world imports { /// HTTP proxies have access to time and randomness. @since(version = 0.2.0) - import wasi:clocks/monotonic-clock@0.2.7; + import wasi:clocks/monotonic-clock@0.2.8; @since(version = 0.2.0) - import wasi:clocks/wall-clock@0.2.7; + import wasi:clocks/wall-clock@0.2.8; @since(version = 0.2.0) - import wasi:random/random@0.2.7; + import wasi:random/random@0.2.8; /// Proxies have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. @since(version = 0.2.0) - import wasi:cli/stdout@0.2.7; + import wasi:cli/stdout@0.2.8; @since(version = 0.2.0) - import wasi:cli/stderr@0.2.7; + import wasi:cli/stderr@0.2.8; /// TODO: this is a temporary workaround until component tooling is able to /// gracefully handle the absence of stdin. Hosts must return an eof stream /// for this import, which is what wasi-libc + tooling will do automatically /// when this import is properly removed. @since(version = 0.2.0) - import wasi:cli/stdin@0.2.7; + import wasi:cli/stdin@0.2.8; /// This is the default handler to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 9ebff8b50..7af8b962c 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -4,13 +4,13 @@ @since(version = 0.2.0) interface types { @since(version = 0.2.0) - use wasi:clocks/monotonic-clock@0.2.7.{duration}; + use wasi:clocks/monotonic-clock@0.2.8.{duration}; @since(version = 0.2.0) - use wasi:io/streams@0.2.7.{input-stream, output-stream}; + use wasi:io/streams@0.2.8.{input-stream, output-stream}; @since(version = 0.2.0) - use wasi:io/error@0.2.7.{error as io-error}; + use wasi:io/error@0.2.8.{error as io-error}; @since(version = 0.2.0) - use wasi:io/poll@0.2.7.{pollable}; + use wasi:io/poll@0.2.8.{pollable}; /// This type corresponds to HTTP standard Methods. @since(version = 0.2.0) From 7e3231ec8645bc7b9b902117d4f6b39a76a37f23 Mon Sep 17 00:00:00 2001 From: Lann Martin Date: Fri, 10 Oct 2025 16:50:51 -0400 Subject: [PATCH 1758/1772] Regenerate markdown --- proposals/http/imports.md | 48 +++++++++++++++++----------------- proposals/http/proxy.md | 54 +++++++++++++++++++-------------------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index 9fbc19df9..7926bb341 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -83,8 +83,8 @@ successive reads of the clock will produce non-decreasing values.

                                                type pollable

                                                pollable

                                                -

                                                type instant

                                                -

                                                u64

                                                +#### `type instant` +`u64`

                                                An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. @@ -251,10 +251,10 @@ when it does, they are expected to subsume this API.

                                                type error

                                                error

                                                -

                                                type pollable

                                                -

                                                pollable

                                                +#### `type pollable` +[`pollable`](#pollable)

                                                -

                                                variant stream-error

                                                +#### `variant stream-error`

                                                An error for input-stream and output-stream operations.

                                                Variant Cases
                                                  @@ -549,7 +549,7 @@ is ready for reading, before performing the splice.

                                                  type output-stream

                                                  output-stream

                                                  -


                                                  +----

                                                  Functions

                                                  get-stdout: func

                                                  Return values
                                                  @@ -562,7 +562,7 @@ is ready for reading, before performing the splice.

                                                  type output-stream

                                                  output-stream

                                                  -


                                                  +----

                                                  Functions

                                                  get-stderr: func

                                                  Return values
                                                  @@ -575,7 +575,7 @@ is ready for reading, before performing the splice.

                                                  type input-stream

                                                  input-stream

                                                  -


                                                  +----

                                                  Functions

                                                  get-stdin: func

                                                  Return values
                                                  @@ -591,19 +591,19 @@ their headers, trailers, and bodies.

                                                  type duration

                                                  duration

                                                  -

                                                  type input-stream

                                                  -

                                                  input-stream

                                                  +#### `type input-stream` +[`input-stream`](#input_stream)

                                                  -

                                                  type output-stream

                                                  -

                                                  output-stream

                                                  +#### `type output-stream` +[`output-stream`](#output_stream)

                                                  -

                                                  type io-error

                                                  -

                                                  error

                                                  +#### `type io-error` +[`error`](#error)

                                                  -

                                                  type pollable

                                                  -

                                                  pollable

                                                  +#### `type pollable` +[`pollable`](#pollable)

                                                  -

                                                  variant method

                                                  +#### `variant method`

                                                  This type corresponds to HTTP standard Methods.

                                                  Variant Cases
                                                    @@ -1510,16 +1510,16 @@ imported by components which wish to make HTTP Requests.

                                                    type outgoing-request

                                                    outgoing-request

                                                    -

                                                    type request-options

                                                    -

                                                    request-options

                                                    +#### `type request-options` +[`request-options`](#request_options)

                                                    -

                                                    type future-incoming-response

                                                    -

                                                    future-incoming-response

                                                    +#### `type future-incoming-response` +[`future-incoming-response`](#future_incoming_response)

                                                    -

                                                    type error-code

                                                    -

                                                    error-code

                                                    +#### `type error-code` +[`error-code`](#error_code)

                                                    -


                                                    +----

                                                    Functions

                                                    handle: func

                                                    This function is invoked with an outgoing HTTP Request, and it returns diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index 019f84a62..ad6baf8eb 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -90,8 +90,8 @@ successive reads of the clock will produce non-decreasing values.

                                                    type pollable

                                                    pollable

                                                    -

                                                    type instant

                                                    -

                                                    u64

                                                    +#### `type instant` +`u64`

                                                    An instant in time, in nanoseconds. An instant is relative to an unspecified initial value, and can only be compared to instances from the same monotonic-clock. @@ -258,10 +258,10 @@ when it does, they are expected to subsume this API.

                                                    type error

                                                    error

                                                    -

                                                    type pollable

                                                    -

                                                    pollable

                                                    +#### `type pollable` +[`pollable`](#pollable)

                                                    -

                                                    variant stream-error

                                                    +#### `variant stream-error`

                                                    An error for input-stream and output-stream operations.

                                                    Variant Cases
                                                      @@ -556,7 +556,7 @@ is ready for reading, before performing the splice.

                                                      type output-stream

                                                      output-stream

                                                      -


                                                      +----

                                                      Functions

                                                      get-stdout: func

                                                      Return values
                                                      @@ -569,7 +569,7 @@ is ready for reading, before performing the splice.

                                                      type output-stream

                                                      output-stream

                                                      -


                                                      +----

                                                      Functions

                                                      get-stderr: func

                                                      Return values
                                                      @@ -582,7 +582,7 @@ is ready for reading, before performing the splice.

                                                      type input-stream

                                                      input-stream

                                                      -


                                                      +----

                                                      Functions

                                                      get-stdin: func

                                                      Return values
                                                      @@ -598,19 +598,19 @@ their headers, trailers, and bodies.

                                                      type duration

                                                      duration

                                                      -

                                                      type input-stream

                                                      -

                                                      input-stream

                                                      +#### `type input-stream` +[`input-stream`](#input_stream)

                                                      -

                                                      type output-stream

                                                      -

                                                      output-stream

                                                      +#### `type output-stream` +[`output-stream`](#output_stream)

                                                      -

                                                      type io-error

                                                      -

                                                      error

                                                      +#### `type io-error` +[`error`](#error)

                                                      -

                                                      type pollable

                                                      -

                                                      pollable

                                                      +#### `type pollable` +[`pollable`](#pollable)

                                                      -

                                                      variant method

                                                      +#### `variant method`

                                                      This type corresponds to HTTP standard Methods.

                                                      Variant Cases
                                                        @@ -1517,16 +1517,16 @@ imported by components which wish to make HTTP Requests.

                                                        type outgoing-request

                                                        outgoing-request

                                                        -

                                                        type request-options

                                                        -

                                                        request-options

                                                        +#### `type request-options` +[`request-options`](#request_options)

                                                        -

                                                        type future-incoming-response

                                                        -

                                                        future-incoming-response

                                                        +#### `type future-incoming-response` +[`future-incoming-response`](#future_incoming_response)

                                                        -

                                                        type error-code

                                                        -

                                                        error-code

                                                        +#### `type error-code` +[`error-code`](#error_code)

                                                        -


                                                        +----

                                                        Functions

                                                        handle: func

                                                        This function is invoked with an outgoing HTTP Request, and it returns @@ -1552,10 +1552,10 @@ through the future-incoming-responsetype incoming-request

                                                        incoming-request

                                                        -

                                                        type response-outparam

                                                        -

                                                        response-outparam

                                                        +#### `type response-outparam` +[`response-outparam`](#response_outparam)

                                                        -


                                                        +----

                                                        Functions

                                                        handle: func

                                                        This function is invoked with an incoming HTTP Request, and a resource From 00f114663f015e3d2318b36fa61bf654df45c98e Mon Sep 17 00:00:00 2001 From: Lann Martin Date: Mon, 6 Oct 2025 14:57:44 -0400 Subject: [PATCH 1759/1772] Rework 0.3 handlers and worlds - Add a `client` interface with a `send` function matching `handle` - Replace the `imports` world's `handler` import with `client` - Replace the `proxy` world with `service` - Add a `middleware` world --- proposals/http/wit-0.3.0-draft/client.wit | 13 ++++++++ proposals/http/wit-0.3.0-draft/handler.wit | 17 ++++------ .../{proxy.wit => service.wit} | 32 +++++++++++-------- 3 files changed, 38 insertions(+), 24 deletions(-) create mode 100644 proposals/http/wit-0.3.0-draft/client.wit rename proposals/http/wit-0.3.0-draft/{proxy.wit => service.wit} (60%) diff --git a/proposals/http/wit-0.3.0-draft/client.wit b/proposals/http/wit-0.3.0-draft/client.wit new file mode 100644 index 000000000..651d58c50 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/client.wit @@ -0,0 +1,13 @@ +/// This interface defines an HTTP client. It may be imported by components that +/// wish to send HTTP Requests or it may be composed with a `handler` to process +/// requests without any use of a network. In addition, it may be exported by +/// components to wrap another `client` as with "client interceptors". +interface client { + use types.{request, response, error-code}; + + /// This function may be used to either send an outgoing request over the + /// network or to forward it to another component. + send: async func( + request: request, + ) -> result; +} diff --git a/proposals/http/wit-0.3.0-draft/handler.wit b/proposals/http/wit-0.3.0-draft/handler.wit index e4446cbec..e62981d76 100644 --- a/proposals/http/wit-0.3.0-draft/handler.wit +++ b/proposals/http/wit-0.3.0-draft/handler.wit @@ -1,17 +1,12 @@ -/// This interface defines a handler of HTTP Requests. It may be imported by -/// components which wish to send HTTP Requests and also exported by components -/// which can respond to HTTP Requests. In addition, it may be used to pass -/// a request from one component to another without any use of a network. +/// This interface defines a handler of HTTP Requests. It may be exported by +/// components which can respond to HTTP Requests. In addition, it may be +/// imported by components to wrap another `handler` as with "middleware". interface handler { use types.{request, response, error-code}; - /// When exported, this function may be called with either an incoming - /// request read from the network or a request synthesized or forwarded by - /// another component. - /// - /// When imported, this function may be used to either send an outgoing - /// request over the network or pass it to another component. + /// This function may be called with either an incoming request read from the + /// network or a request synthesized or forwarded by another component. handle: async func( request: request, ) -> result; -} +} \ No newline at end of file diff --git a/proposals/http/wit-0.3.0-draft/proxy.wit b/proposals/http/wit-0.3.0-draft/service.wit similarity index 60% rename from proposals/http/wit-0.3.0-draft/proxy.wit rename to proposals/http/wit-0.3.0-draft/service.wit index 223083ea2..caf273003 100644 --- a/proposals/http/wit-0.3.0-draft/proxy.wit +++ b/proposals/http/wit-0.3.0-draft/service.wit @@ -1,13 +1,13 @@ package wasi:http@0.3.0-rc-2025-09-16; -/// The `wasi:http/imports` world imports all the APIs for HTTP proxies. +/// The `wasi:http/imports` world imports all the APIs for HTTP services. /// It is intended to be `include`d in other worlds. world imports { - /// HTTP proxies have access to time and randomness. + /// HTTP services have access to time and randomness. include wasi:clocks/imports@0.3.0-rc-2025-09-16; import wasi:random/random@0.3.0-rc-2025-09-16; - /// Proxies have standard output and error streams which are expected to + /// Services have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. import wasi:cli/stdout@0.3.0-rc-2025-09-16; import wasi:cli/stderr@0.3.0-rc-2025-09-16; @@ -18,19 +18,15 @@ world imports { /// when this import is properly removed. import wasi:cli/stdin@0.3.0-rc-2025-09-16; - /// This is the default handler to use when user code simply wants to make an + /// This is the default `client` to use when user code simply wants to make an /// HTTP request (e.g., via `fetch()`). - /// - /// This may also be used to pass synthesized or forwarded requests to another - /// component. - import handler; + import client; } -/// The `wasi:http/proxy` world captures a widely-implementable intersection of -/// hosts that includes HTTP forward and reverse proxies. Components targeting -/// this world may concurrently stream in and out any number of incoming and -/// outgoing HTTP requests. -world proxy { +/// The `wasi:http/service` world captures a broad category of HTTP services +/// including web applications, API servers, and proxies. It may be `include`d +/// in more specific worlds such as `wasi:http/gateway`. +world service { include imports; /// The host delivers incoming HTTP requests to a component by calling the @@ -42,3 +38,13 @@ world proxy { /// another component. export handler; } + +/// The `wasi:http/middleware` world captures HTTP services that forward HTTP +/// Requests to another handler. Components may implement this world to allow +/// them to participate in handler "chains" where a Request flows through +/// handlers on its way to some "terminal" service and corresponding Responses +/// flow in the opposite direction. +world middleware { + include service; + import handler; +} \ No newline at end of file From 6b3bbb06e70bed2735580ad73f4013a54d84d7c2 Mon Sep 17 00:00:00 2001 From: Lann Martin Date: Wed, 15 Oct 2025 10:28:41 -0400 Subject: [PATCH 1760/1772] Address PR feedback --- proposals/http/wit-0.3.0-draft/client.wit | 13 ---- proposals/http/wit-0.3.0-draft/handler.wit | 12 ---- proposals/http/wit-0.3.0-draft/service.wit | 50 ------------- proposals/http/wit-0.3.0-draft/worlds.wit | 81 ++++++++++++++++++++++ 4 files changed, 81 insertions(+), 75 deletions(-) delete mode 100644 proposals/http/wit-0.3.0-draft/client.wit delete mode 100644 proposals/http/wit-0.3.0-draft/handler.wit delete mode 100644 proposals/http/wit-0.3.0-draft/service.wit create mode 100644 proposals/http/wit-0.3.0-draft/worlds.wit diff --git a/proposals/http/wit-0.3.0-draft/client.wit b/proposals/http/wit-0.3.0-draft/client.wit deleted file mode 100644 index 651d58c50..000000000 --- a/proposals/http/wit-0.3.0-draft/client.wit +++ /dev/null @@ -1,13 +0,0 @@ -/// This interface defines an HTTP client. It may be imported by components that -/// wish to send HTTP Requests or it may be composed with a `handler` to process -/// requests without any use of a network. In addition, it may be exported by -/// components to wrap another `client` as with "client interceptors". -interface client { - use types.{request, response, error-code}; - - /// This function may be used to either send an outgoing request over the - /// network or to forward it to another component. - send: async func( - request: request, - ) -> result; -} diff --git a/proposals/http/wit-0.3.0-draft/handler.wit b/proposals/http/wit-0.3.0-draft/handler.wit deleted file mode 100644 index e62981d76..000000000 --- a/proposals/http/wit-0.3.0-draft/handler.wit +++ /dev/null @@ -1,12 +0,0 @@ -/// This interface defines a handler of HTTP Requests. It may be exported by -/// components which can respond to HTTP Requests. In addition, it may be -/// imported by components to wrap another `handler` as with "middleware". -interface handler { - use types.{request, response, error-code}; - - /// This function may be called with either an incoming request read from the - /// network or a request synthesized or forwarded by another component. - handle: async func( - request: request, - ) -> result; -} \ No newline at end of file diff --git a/proposals/http/wit-0.3.0-draft/service.wit b/proposals/http/wit-0.3.0-draft/service.wit deleted file mode 100644 index caf273003..000000000 --- a/proposals/http/wit-0.3.0-draft/service.wit +++ /dev/null @@ -1,50 +0,0 @@ -package wasi:http@0.3.0-rc-2025-09-16; - -/// The `wasi:http/imports` world imports all the APIs for HTTP services. -/// It is intended to be `include`d in other worlds. -world imports { - /// HTTP services have access to time and randomness. - include wasi:clocks/imports@0.3.0-rc-2025-09-16; - import wasi:random/random@0.3.0-rc-2025-09-16; - - /// Services have standard output and error streams which are expected to - /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.3.0-rc-2025-09-16; - import wasi:cli/stderr@0.3.0-rc-2025-09-16; - - /// TODO: this is a temporary workaround until component tooling is able to - /// gracefully handle the absence of stdin. Hosts must return an eof stream - /// for this import, which is what wasi-libc + tooling will do automatically - /// when this import is properly removed. - import wasi:cli/stdin@0.3.0-rc-2025-09-16; - - /// This is the default `client` to use when user code simply wants to make an - /// HTTP request (e.g., via `fetch()`). - import client; -} - -/// The `wasi:http/service` world captures a broad category of HTTP services -/// including web applications, API servers, and proxies. It may be `include`d -/// in more specific worlds such as `wasi:http/gateway`. -world service { - include imports; - - /// The host delivers incoming HTTP requests to a component by calling the - /// `handle` function of this exported interface. A host may arbitrarily reuse - /// or not reuse component instance when delivering incoming HTTP requests and - /// thus a component must be able to handle 0..N calls to `handle`. - /// - /// This may also be used to receive synthesized or forwarded requests from - /// another component. - export handler; -} - -/// The `wasi:http/middleware` world captures HTTP services that forward HTTP -/// Requests to another handler. Components may implement this world to allow -/// them to participate in handler "chains" where a Request flows through -/// handlers on its way to some "terminal" service and corresponding Responses -/// flow in the opposite direction. -world middleware { - include service; - import handler; -} \ No newline at end of file diff --git a/proposals/http/wit-0.3.0-draft/worlds.wit b/proposals/http/wit-0.3.0-draft/worlds.wit new file mode 100644 index 000000000..777fcc662 --- /dev/null +++ b/proposals/http/wit-0.3.0-draft/worlds.wit @@ -0,0 +1,81 @@ +package wasi:http@0.3.0-rc-2025-09-16; + +/// The `wasi:http/service` world captures a broad category of HTTP services +/// including web applications, API servers, and proxies. It may be `include`d +/// in more specific worlds such as `wasi:http/middleware`. +world service { + /// HTTP services have access to time and randomness. + include wasi:clocks/imports@0.3.0-rc-2025-09-16; + import wasi:random/random@0.3.0-rc-2025-09-16; + + /// Services have standard output and error streams which are expected to + /// terminate in a developer-facing console provided by the host. + import wasi:cli/stdout@0.3.0-rc-2025-09-16; + import wasi:cli/stderr@0.3.0-rc-2025-09-16; + + /// TODO: this is a temporary workaround until component tooling is able to + /// gracefully handle the absence of stdin. Hosts must return an eof stream + /// for this import, which is what wasi-libc + tooling will do automatically + /// when this import is properly removed. + import wasi:cli/stdin@0.3.0-rc-2025-09-16; + + /// This is the default `client` to use when user code simply wants to make an + /// HTTP request (e.g., via `fetch()`). + import client; + + /// The host delivers incoming HTTP requests to a component by calling the + /// `handle` function of this exported interface. A host may arbitrarily reuse + /// or not reuse component instance when delivering incoming HTTP requests and + /// thus a component must be able to handle 0..N calls to `handle`. + /// + /// This may also be used to receive synthesized or forwarded requests from + /// another component. + export handler; +} + +/// The `wasi:http/middleware` world captures HTTP services that forward HTTP +/// Requests to another handler. +/// +/// Components may implement this world to allow them to participate in handler +/// "chains" where a Request flows through handlers on its way to some terminal +/// `service` and corresponding Responses flow in the opposite direction. +world middleware { + include service; + import handler; +} + +/// This interface defines a handler of HTTP Requests. +/// +/// In a `wasi:http/service` this interface is exported to respond to an +/// incoming HTTP Request with a Response. +/// +/// In `wasi:http/middleware` this interface is both exported and imported as +/// the "downstream" and "upstream" directions of the middleware chain. +interface handler { + use types.{request, response, error-code}; + + /// This function may be called with either an incoming request read from the + /// network or a request synthesized or forwarded by another component. + handle: async func( + request: request, + ) -> result; +} + +/// This interface defines an HTTP client for sending "outgoing" requests. +/// +/// Most components are expected to import this interface to provide the +/// capability to send HTTP requests to arbitrary destinations on a network. +/// +/// The type signature of `client.send` is the same as `handler.handle`. This +/// duplication is currently necessary because some Component Model tooling +/// (including WIT itself) is unable to represent a component importing two +/// instances of the same interface. +interface client { + use types.{request, response, error-code}; + + // This function may be used to either send an outgoing request over the + // network or to forward it to another component. + send: async func( + request: request, + ) -> result; +} \ No newline at end of file From fff534d38c7b735147d804c4a5714b712c649117 Mon Sep 17 00:00:00 2001 From: Lann Date: Thu, 16 Oct 2025 08:50:36 -0400 Subject: [PATCH 1761/1772] Adopt PR feedback Co-authored-by: Luke Wagner --- proposals/http/wit-0.3.0-draft/worlds.wit | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/worlds.wit b/proposals/http/wit-0.3.0-draft/worlds.wit index 777fcc662..946eaf4d2 100644 --- a/proposals/http/wit-0.3.0-draft/worlds.wit +++ b/proposals/http/wit-0.3.0-draft/worlds.wit @@ -35,20 +35,20 @@ world service { /// The `wasi:http/middleware` world captures HTTP services that forward HTTP /// Requests to another handler. -/// +/// /// Components may implement this world to allow them to participate in handler -/// "chains" where a Request flows through handlers on its way to some terminal -/// `service` and corresponding Responses flow in the opposite direction. +/// "chains" where a `request` flows through handlers on its way to some terminal +/// `service` and corresponding `response` flows in the opposite direction. world middleware { include service; import handler; } /// This interface defines a handler of HTTP Requests. -/// +/// /// In a `wasi:http/service` this interface is exported to respond to an /// incoming HTTP Request with a Response. -/// +/// /// In `wasi:http/middleware` this interface is both exported and imported as /// the "downstream" and "upstream" directions of the middleware chain. interface handler { @@ -62,10 +62,10 @@ interface handler { } /// This interface defines an HTTP client for sending "outgoing" requests. -/// +/// /// Most components are expected to import this interface to provide the /// capability to send HTTP requests to arbitrary destinations on a network. -/// +/// /// The type signature of `client.send` is the same as `handler.handle`. This /// duplication is currently necessary because some Component Model tooling /// (including WIT itself) is unable to represent a component importing two From 7bb5c6f1c7a40aafc15c979e3136866d56184e65 Mon Sep 17 00:00:00 2001 From: Lann Martin Date: Thu, 16 Oct 2025 14:33:18 -0400 Subject: [PATCH 1762/1772] Add note about linking client to handler --- proposals/http/wit-0.3.0-draft/worlds.wit | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/http/wit-0.3.0-draft/worlds.wit b/proposals/http/wit-0.3.0-draft/worlds.wit index 946eaf4d2..942c47e4e 100644 --- a/proposals/http/wit-0.3.0-draft/worlds.wit +++ b/proposals/http/wit-0.3.0-draft/worlds.wit @@ -69,7 +69,8 @@ interface handler { /// The type signature of `client.send` is the same as `handler.handle`. This /// duplication is currently necessary because some Component Model tooling /// (including WIT itself) is unable to represent a component importing two -/// instances of the same interface. +/// instances of the same interface. A `client.send` import may be linked +/// directly to a `handler.handle` export to bypass the network. interface client { use types.{request, response, error-code}; From 3930ac1bfaefc126f52c8d7d19a91c9aa15e43dd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 27 Oct 2025 11:19:28 -0700 Subject: [PATCH 1763/1772] Use `.` instead of `/` for interface members. Say: ``` wasi:io/streams.stream-error ``` instead of: ``` wasi:io/streams/stream-error ``` This better aligns with WIT's `use` syntax and the upcoming nested namespaces feature in WIT. --- proposals/io/wit/error.wit | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/io/wit/error.wit b/proposals/io/wit/error.wit index dd5a1af03..8caf84539 100644 --- a/proposals/io/wit/error.wit +++ b/proposals/io/wit/error.wit @@ -8,14 +8,14 @@ interface error { /// which provides some human-readable information about the error. /// /// In the `wasi:io` package, this resource is returned through the - /// `wasi:io/streams/stream-error` type. + /// `wasi:io/streams.stream-error` type. /// /// To provide more specific error information, other interfaces may /// offer functions to "downcast" this error into more specific types. For example, /// errors returned from streams derived from filesystem types can be described using /// the filesystem's own error-code type. This is done using the function - /// `wasi:filesystem/types/filesystem-error-code`, which takes a `borrow` - /// parameter and returns an `option`. + /// `wasi:filesystem/types.filesystem-error-code`, which takes a `borrow` + /// parameter and returns an `option`. /// /// The set of functions which can "downcast" an `error` into a more /// concrete type is open. From 446311279de959ce6b4ed85ebc9125ff50758ae4 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 27 Oct 2025 13:57:18 -0700 Subject: [PATCH 1764/1772] Update imports.md. --- proposals/io/imports.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index 8a884a370..fbb55fd58 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -16,13 +16,13 @@

                                                        The only method provided by this resource is to-debug-string, which provides some human-readable information about the error.

                                                        In the wasi:io package, this resource is returned through the -wasi:io/streams/stream-error type.

                                                        +wasi:io/streams.stream-error type.

                                                        To provide more specific error information, other interfaces may offer functions to "downcast" this error into more specific types. For example, errors returned from streams derived from filesystem types can be described using the filesystem's own error-code type. This is done using the function -wasi:filesystem/types/filesystem-error-code, which takes a borrow<error> -parameter and returns an option<wasi:filesystem/types/error-code>.

                                                        +wasi:filesystem/types.filesystem-error-code, which takes a borrow<error> +parameter and returns an option<wasi:filesystem/types.error-code>.

                                                        The set of functions which can "downcast" an error into a more concrete type is open.

                                                        Functions

                                                        From 644cd717bc26d7e58a462b6fe28f29a204a20f4d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 27 Oct 2025 14:16:07 -0700 Subject: [PATCH 1765/1772] Use wit-bindgen 0.43.1. --- proposals/io/imports.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/io/imports.md b/proposals/io/imports.md index fbb55fd58..071128df9 100644 --- a/proposals/io/imports.md +++ b/proposals/io/imports.md @@ -104,10 +104,10 @@ when it does, they are expected to subsume this API.

                                                        type error

                                                        error

                                                        -

                                                        type pollable

                                                        -

                                                        pollable

                                                        +#### `type pollable` +[`pollable`](#pollable)

                                                        -

                                                        variant stream-error

                                                        +#### `variant stream-error`

                                                        An error for input-stream and output-stream operations.

                                                        Variant Cases
                                                          From f43af359cd26d7d8695141e1c7272960666645e3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 27 Oct 2025 11:25:04 -0700 Subject: [PATCH 1766/1772] Use `.` instead of `/` for interface members. Say: ``` wasi:io/streams.stream-error ``` instead of: ``` wasi:io/streams/stream-error ``` This better aligns with WIT's `use` syntax and the upcoming nested namespaces feature in WIT. --- proposals/http/wit/types.wit | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/http/wit/types.wit b/proposals/http/wit/types.wit index 7af8b962c..f91ee1f19 100644 --- a/proposals/http/wit/types.wit +++ b/proposals/http/wit/types.wit @@ -110,8 +110,8 @@ interface types { /// provided. /// /// Stream operations which return - /// `wasi:io/stream/stream-error::last-operation-failed` have a payload of - /// type `wasi:io/error/error` with more information about the operation + /// `wasi:io/stream.stream-error.last-operation-failed` have a payload of + /// type `wasi:io/error.error` with more information about the operation /// that failed. This payload can be passed through to this function to see /// if there's http-related information about the error to return. /// From 2d4638289135af3867debb5fb8fb6a4fbc1385f1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 27 Oct 2025 14:15:27 -0700 Subject: [PATCH 1767/1772] Renegerate markdown files with wit-bindgen 0.43.1. --- proposals/http/imports.md | 23 ++--------------------- proposals/http/proxy.md | 23 ++--------------------- 2 files changed, 4 insertions(+), 42 deletions(-) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index 7926bb341..d9f34f277 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -812,8 +812,8 @@ provide the HTTP Response corresponding to the sent Request.

                                                          Attempts to extract a http-related error from the wasi:io error provided.

                                                          Stream operations which return -wasi:io/stream/stream-error::last-operation-failed have a payload of -type wasi:io/error/error with more information about the operation +wasi:io/stream.stream-error.last-operation-failed have a payload of +type wasi:io/error.error with more information about the operation that failed. This payload can be passed through to this function to see if there's http-related information about the error to return.

                                                          Note that this function is fallible because not all io-errors are @@ -1236,25 +1236,6 @@ supported.

                                                          • result
                                                          -

                                                          [method]response-outparam.send-informational: func

                                                          -

                                                          Send an HTTP 1xx response.

                                                          -

                                                          Unlike response-outparam.set, this does not consume the -response-outparam, allowing the guest to send an arbitrary number of -informational responses before sending the final response using -response-outparam.set.

                                                          -

                                                          This will return an HTTP-protocol-error if status is not in the -range [100-199], or an internal-error if the implementation does not -support informational responses.

                                                          -
                                                          Params
                                                          - -
                                                          Return values
                                                          -

                                                          [static]response-outparam.set: func

                                                          Set the value of the response-outparam to either send a response, or indicate an error.

                                                          diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index ad6baf8eb..df37da4fc 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -819,8 +819,8 @@ provide the HTTP Response corresponding to the sent Request.

                                                          Attempts to extract a http-related error from the wasi:io error provided.

                                                          Stream operations which return -wasi:io/stream/stream-error::last-operation-failed have a payload of -type wasi:io/error/error with more information about the operation +wasi:io/stream.stream-error.last-operation-failed have a payload of +type wasi:io/error.error with more information about the operation that failed. This payload can be passed through to this function to see if there's http-related information about the error to return.

                                                          Note that this function is fallible because not all io-errors are @@ -1243,25 +1243,6 @@ supported.

                                                          • result
                                                          -

                                                          [method]response-outparam.send-informational: func

                                                          -

                                                          Send an HTTP 1xx response.

                                                          -

                                                          Unlike response-outparam.set, this does not consume the -response-outparam, allowing the guest to send an arbitrary number of -informational responses before sending the final response using -response-outparam.set.

                                                          -

                                                          This will return an HTTP-protocol-error if status is not in the -range [100-199], or an internal-error if the implementation does not -support informational responses.

                                                          -
                                                          Params
                                                          - -
                                                          Return values
                                                          -

                                                          [static]response-outparam.set: func

                                                          Set the value of the response-outparam to either send a response, or indicate an error.

                                                          From 8a42980a0c97c71b8ff3319c2760abeacfc37b40 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 27 Oct 2025 15:03:23 -0700 Subject: [PATCH 1768/1772] Update to WebAssembly/wit-abi-up-to-date@v25. --- proposals/http/.github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml index 71542547a..0540b7786 100644 --- a/proposals/http/.github/workflows/main.yml +++ b/proposals/http/.github/workflows/main.yml @@ -17,7 +17,7 @@ jobs: chmod +x ./wit-deps ./wit-deps lock --check ./wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps lock --check - - uses: WebAssembly/wit-abi-up-to-date@v24 + - uses: WebAssembly/wit-abi-up-to-date@v25 with: worlds: 'imports proxy' all-features: 'true' From 0cbeedcb3dd0520f2ca4d046229d3dd333b5e3e0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 27 Oct 2025 15:35:19 -0700 Subject: [PATCH 1769/1772] Generate docs with --all-features. --- proposals/http/imports.md | 19 +++++++++++++++++++ proposals/http/proxy.md | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/proposals/http/imports.md b/proposals/http/imports.md index d9f34f277..b099e2edf 100644 --- a/proposals/http/imports.md +++ b/proposals/http/imports.md @@ -1236,6 +1236,25 @@ supported.

                                                          • result
                                                          +

                                                          [method]response-outparam.send-informational: func

                                                          +

                                                          Send an HTTP 1xx response.

                                                          +

                                                          Unlike response-outparam.set, this does not consume the +response-outparam, allowing the guest to send an arbitrary number of +informational responses before sending the final response using +response-outparam.set.

                                                          +

                                                          This will return an HTTP-protocol-error if status is not in the +range [100-199], or an internal-error if the implementation does not +support informational responses.

                                                          +
                                                          Params
                                                          + +
                                                          Return values
                                                          +

                                                          [static]response-outparam.set: func

                                                          Set the value of the response-outparam to either send a response, or indicate an error.

                                                          diff --git a/proposals/http/proxy.md b/proposals/http/proxy.md index df37da4fc..aed35c1a3 100644 --- a/proposals/http/proxy.md +++ b/proposals/http/proxy.md @@ -1243,6 +1243,25 @@ supported.

                                                          • result
                                                          +

                                                          [method]response-outparam.send-informational: func

                                                          +

                                                          Send an HTTP 1xx response.

                                                          +

                                                          Unlike response-outparam.set, this does not consume the +response-outparam, allowing the guest to send an arbitrary number of +informational responses before sending the final response using +response-outparam.set.

                                                          +

                                                          This will return an HTTP-protocol-error if status is not in the +range [100-199], or an internal-error if the implementation does not +support informational responses.

                                                          +
                                                          Params
                                                          + +
                                                          Return values
                                                          +

                                                          [static]response-outparam.set: func

                                                          Set the value of the response-outparam to either send a response, or indicate an error.

                                                          From 1e6427728adfac3af6e62925f4fb5b619d3aa926 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 3 Nov 2025 13:22:42 -0800 Subject: [PATCH 1770/1772] [0.3.0-draft] Include the full wasi:random/imports This switches `wasi:http/proxy` from just using `wasi:random/random` to also including `wasi:random/insecure` and `wasi:random/insecure-seed`. These "insecure" interfaces allow applications which need random numbers for purposes other than cryptography or UUIDs to request them, which can give hosts more flexibility when running in environments with scarce entropy, such as early boot environments. These interfaces should be easy to support in any host that already supports `wasi:random/random`. They permit alternate implementation strategies, but don't require them. --- proposals/http/wit-0.3.0-draft/worlds.wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/http/wit-0.3.0-draft/worlds.wit b/proposals/http/wit-0.3.0-draft/worlds.wit index 942c47e4e..5a1136809 100644 --- a/proposals/http/wit-0.3.0-draft/worlds.wit +++ b/proposals/http/wit-0.3.0-draft/worlds.wit @@ -6,7 +6,7 @@ package wasi:http@0.3.0-rc-2025-09-16; world service { /// HTTP services have access to time and randomness. include wasi:clocks/imports@0.3.0-rc-2025-09-16; - import wasi:random/random@0.3.0-rc-2025-09-16; + include wasi:random/imports@0.3.0-rc-2025-09-16; /// Services have standard output and error streams which are expected to /// terminate in a developer-facing console provided by the host. From d7c7ce0fa5c91bff04ca86a66537c5c955a14a18 Mon Sep 17 00:00:00 2001 From: Yosh Date: Tue, 25 Nov 2025 14:47:00 +0100 Subject: [PATCH 1771/1772] ignore files in tmp/ --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 917660a34..28b58e27d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -*.wasm \ No newline at end of file +*.wasm +tmp/ From 3a487f4241fa3d1cc3acbe0bc64ef16b2603f44f Mon Sep 17 00:00:00 2001 From: Yosh Date: Tue, 25 Nov 2025 15:49:55 +0100 Subject: [PATCH 1772/1772] Remove the .github dirs from merged proposals --- proposals/cli/.github/workflows/main.yml | 27 ------- .../cli/.github/workflows/publish-0.3.yml | 72 ----------------- proposals/cli/.github/workflows/publish.yml | 70 ---------------- .../cli/.github/workflows/update-0.3.yml | 80 ------------------- proposals/cli/.github/workflows/update.yml | 68 ---------------- proposals/clocks/.github/workflows/main.yml | 23 ------ .../clocks/.github/workflows/publish-0.3.yml | 71 ---------------- .../clocks/.github/workflows/publish.yml | 70 ---------------- .../clocks/.github/workflows/update-0.3.yml | 76 ------------------ proposals/clocks/.github/workflows/update.yml | 64 --------------- .../filesystem/.github/workflows/main.yml | 25 ------ .../.github/workflows/publish-0.3.yml | 72 ----------------- .../filesystem/.github/workflows/publish.yml | 70 ---------------- .../.github/workflows/update-0.3.yml | 80 ------------------- .../filesystem/.github/workflows/update.yml | 64 --------------- proposals/http/.github/workflows/main.yml | 23 ------ .../http/.github/workflows/publish-0.3.yml | 72 ----------------- proposals/http/.github/workflows/publish.yml | 70 ---------------- .../http/.github/workflows/update-0.3.yml | 80 ------------------- proposals/http/.github/workflows/update.yml | 68 ---------------- proposals/io/.github/workflows/main.yml | 16 ---- proposals/io/.github/workflows/publish.yml | 70 ---------------- proposals/io/.github/workflows/update.yml | 64 --------------- proposals/random/.github/workflows/main.yml | 16 ---- .../random/.github/workflows/publish-0.3.yml | 70 ---------------- .../random/.github/workflows/publish.yml | 70 ---------------- .../random/.github/workflows/update-0.3.yml | 76 ------------------ proposals/random/.github/workflows/update.yml | 59 -------------- proposals/sockets/.github/workflows/main.yml | 25 ------ .../sockets/.github/workflows/publish-0.3.yml | 72 ----------------- .../sockets/.github/workflows/publish.yml | 70 ---------------- .../sockets/.github/workflows/update-0.3.yml | 80 ------------------- .../sockets/.github/workflows/update.yml | 64 --------------- 33 files changed, 1997 deletions(-) delete mode 100644 proposals/cli/.github/workflows/main.yml delete mode 100644 proposals/cli/.github/workflows/publish-0.3.yml delete mode 100644 proposals/cli/.github/workflows/publish.yml delete mode 100644 proposals/cli/.github/workflows/update-0.3.yml delete mode 100644 proposals/cli/.github/workflows/update.yml delete mode 100644 proposals/clocks/.github/workflows/main.yml delete mode 100644 proposals/clocks/.github/workflows/publish-0.3.yml delete mode 100644 proposals/clocks/.github/workflows/publish.yml delete mode 100644 proposals/clocks/.github/workflows/update-0.3.yml delete mode 100644 proposals/clocks/.github/workflows/update.yml delete mode 100644 proposals/filesystem/.github/workflows/main.yml delete mode 100644 proposals/filesystem/.github/workflows/publish-0.3.yml delete mode 100644 proposals/filesystem/.github/workflows/publish.yml delete mode 100644 proposals/filesystem/.github/workflows/update-0.3.yml delete mode 100644 proposals/filesystem/.github/workflows/update.yml delete mode 100644 proposals/http/.github/workflows/main.yml delete mode 100644 proposals/http/.github/workflows/publish-0.3.yml delete mode 100644 proposals/http/.github/workflows/publish.yml delete mode 100644 proposals/http/.github/workflows/update-0.3.yml delete mode 100644 proposals/http/.github/workflows/update.yml delete mode 100644 proposals/io/.github/workflows/main.yml delete mode 100644 proposals/io/.github/workflows/publish.yml delete mode 100644 proposals/io/.github/workflows/update.yml delete mode 100644 proposals/random/.github/workflows/main.yml delete mode 100644 proposals/random/.github/workflows/publish-0.3.yml delete mode 100644 proposals/random/.github/workflows/publish.yml delete mode 100644 proposals/random/.github/workflows/update-0.3.yml delete mode 100644 proposals/random/.github/workflows/update.yml delete mode 100644 proposals/sockets/.github/workflows/main.yml delete mode 100644 proposals/sockets/.github/workflows/publish-0.3.yml delete mode 100644 proposals/sockets/.github/workflows/publish.yml delete mode 100644 proposals/sockets/.github/workflows/update-0.3.yml delete mode 100644 proposals/sockets/.github/workflows/update.yml diff --git a/proposals/cli/.github/workflows/main.yml b/proposals/cli/.github/workflows/main.yml deleted file mode 100644 index 53052b2be..000000000 --- a/proposals/cli/.github/workflows/main.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: CI -on: - push: - branches: [main] - pull_request: - branches: [main] - -jobs: - abi-up-to-date: - name: Check ABI files are up-to-date - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: ensure `./wit/deps` are in sync - run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.5.0/wit-deps-x86_64-unknown-linux-musl - chmod +x wit-deps - ./wit-deps lock - ./wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps lock - git add -N wit/deps - git add -N wit-0.3.0-draft/deps - git diff --exit-code - - - uses: WebAssembly/wit-abi-up-to-date@v24 - with: - worlds: 'command imports' - all-features: 'true' diff --git a/proposals/cli/.github/workflows/publish-0.3.yml b/proposals/cli/.github/workflows/publish-0.3.yml deleted file mode 100644 index e65ffc2fe..000000000 --- a/proposals/cli/.github/workflows/publish-0.3.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: Publish 0.3.0 WIT Definitions - -on: - push: - tags: - - v0.3.0-rc-* - workflow_dispatch: # Allow manual triggering - -env: - IMAGE_NAME: ${{ github.repository }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - packages: write - contents: write - - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - # TODO: we don't pin the versions here. It's not great but this will simplify our iteration - # while we rapidly iterate on these tools. Pin when we're stable. - - name: Install wkg - shell: bash - run: cargo binstall wkg - - - name: Install cosign - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 - - # To version our image we want to obtain the version from the tag - - name: Get version - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/webassembly/wasi/cli - tags: | - type=semver,pattern={{version}} - - - name: Login to the GitHub registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ORG_PAT }} - - - name: Build - shell: bash - run: wkg wit build -o "${{ github.event.repository.name }}-0.3.0.wasm" --wit-dir wit-0.3.0-draft - - # Upload the Wasm binary to the GitHub registry - - name: Publish to GitHub Container Registry - id: publish - uses: bytecodealliance/wkg-github-action@v5 - with: - oci-reference-without-tag: "ghcr.io/webassembly/wasi/cli" - file: "${{ github.event.repository.name }}-0.3.0.wasm" - description: "A WASI API for Command-Line Interface environments." - source: 'https://github.com/webassembly/wasi' - homepage: 'https://wasi.dev' - version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - licenses: 'Apache-2.0 WITH LLVM-exception' - - # Sign the output component - - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/cli@${{ steps.publish.outputs.digest }} diff --git a/proposals/cli/.github/workflows/publish.yml b/proposals/cli/.github/workflows/publish.yml deleted file mode 100644 index 73418306f..000000000 --- a/proposals/cli/.github/workflows/publish.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Publish a Wasm Component package to GitHub Artifacts - -# Run this action whenever a new release is tagged -on: - push: - tags: - - v0.2.* - workflow_dispatch: - -env: - IMAGE_NAME: ${{ github.repository }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - packages: write - contents: write - - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@v2 - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - name: Install wkg - shell: bash - run: cargo binstall wkg - - name: Install cosign - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 - - # To version our image we want to obtain the version from the tag - - name: Get version - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/webassembly/wasi/cli - tags: | - type=semver,pattern={{version}} - - # To upload our image to the GitHub registry, we first have to login - - name: Login to the GitHub registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ORG_PAT }} - - # Build our `.wit` files into a Wasm binary - - name: Build - shell: bash - run: wkg wit build -o wasi-cli.wasm - - # Upload the Wasm binary to the GitHub registry - - name: Publish to GitHub Container Registry - id: publish - uses: bytecodealliance/wkg-github-action@v5 - with: - oci-reference-without-tag: 'ghcr.io/webassembly/wasi/cli' - file: 'wasi-cli.wasm' - description: 'A WASI API for Command-Line Interface environments.' - source: 'https://github.com/webassembly/wasi' - homepage: 'https://wasi.dev' - version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - licenses: 'Apache-2.0 WITH LLVM-exception' - - # Sign the output component - - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/cli@${{ steps.publish.outputs.digest }} diff --git a/proposals/cli/.github/workflows/update-0.3.yml b/proposals/cli/.github/workflows/update-0.3.yml deleted file mode 100644 index 7bceb94e1..000000000 --- a/proposals/cli/.github/workflows/update-0.3.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: Update 0.3.0 WIT Definitions - -# Manually dispatch this action from the Actions page -on: - workflow_dispatch: - -permissions: - pull-requests: write - contents: write - -jobs: - update-versions: - runs-on: ubuntu-latest - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - # TODO: we don't pin the versions here. It's not great but this will simplify our iteration - # while we rapidly iterate on these tools. Pin when we're stable. - - name: Install wit-bindgen - shell: bash - run: cargo binstall wit-bindgen-cli - - - name: Install wit-deps - shell: bash - run: cargo binstall wit-deps-cli - - - name: Set version with RC timestamp - id: version - run: | - DATE=$(date +'%Y-%m-%d') - BASE_VERSION="0.3.0-rc-${DATE}" - COUNTER=1 - VERSION="${BASE_VERSION}" - - # Check if the tag already exists - while git ls-remote --tags origin | grep -q "refs/tags/v${VERSION}$"; do - VERSION="${BASE_VERSION}-${COUNTER}" - COUNTER=$((COUNTER + 1)) - done - - echo "value=${VERSION}" >> $GITHUB_OUTPUT - echo "Version will be: ${VERSION}" - - # Update version in WIT definitions - - name: Update version in WIT files - run: | - # Update @since version annotations - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + - # Update all wasi package references (package, use, import, export, from) - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\( wasi:[a-zA-Z0-9_/-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + - - - name: Update wit deps - run: | - wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps update - - # Create PR with changes using create-pull-request action - - name: Create Pull Request - uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" - committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - branch: update-wit-${{ steps.version.outputs.value }} - title: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" - body: | - Updates the 0.3.0 WIT definitions with version ${{ steps.version.outputs.value }}. - - This is an automated update to rev the RC timestamp. - - ## Changes - - Updated package and since version in WIT files - - Updated WIT dependencies if applicable - draft: false - delete-branch: true diff --git a/proposals/cli/.github/workflows/update.yml b/proposals/cli/.github/workflows/update.yml deleted file mode 100644 index 793ee90d0..000000000 --- a/proposals/cli/.github/workflows/update.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: Create a PR to upgrade WIT to a new version - -# Manually dispatch this action from the Actions page -on: - workflow_dispatch: - inputs: - prev_version: - description: 'Upgrading from version (without the v)' - required: true - type: string - next_version: - description: 'Upgrading to version (without the v)' - required: true - type: string - -permissions: - pull-requests: write - contents: write - -jobs: - update-versions: - runs-on: ubuntu-latest - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - name: Install wit-bindgen - shell: bash - run: cargo binstall wit-bindgen-cli - - name: Install wit-deps - shell: bash - run: cargo binstall wit-deps-cli - - # echo input - - name: Print the versions - run: echo Upgrading from ${{ inputs.prev_version }} to ${{ inputs.next_version }} - - # upgrade - - name: Upgrade tag - run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - - name: Upgrade tag - run: find . -type f -name "deps.toml" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - - name: Upgrade wit deps - run: wit-deps update - - name: Generate markdown for the command world - run: wit-bindgen markdown wit -w command --html-in-md --all-features - - name: Generate markdown for the imports world - run: wit-bindgen markdown wit -w imports --html-in-md --all-features - - # file PR - - name: Create feature branch - env: - FEATURE_BRANCH: release-v${{ inputs.next_version }} - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add . - git checkout -b $FEATURE_BRANCH - git push -u origin $FEATURE_BRANCH - git commit -m "Update to v${{ inputs.next_version }}" - git push - - - name: Create pull request - run: gh pr create -B main -H release-v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/proposals/clocks/.github/workflows/main.yml b/proposals/clocks/.github/workflows/main.yml deleted file mode 100644 index abb24eda1..000000000 --- a/proposals/clocks/.github/workflows/main.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: CI -on: - push: - branches: [main] - pull_request: - branches: [main] - -jobs: - abi-up-to-date: - name: Check ABI files are up-to-date - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: ensure `./wit/deps` are in sync - run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.3.5/wit-deps-x86_64-unknown-linux-musl - chmod +x wit-deps - ./wit-deps lock - git add -N wit/deps - git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v24 - with: - all-features: 'true' diff --git a/proposals/clocks/.github/workflows/publish-0.3.yml b/proposals/clocks/.github/workflows/publish-0.3.yml deleted file mode 100644 index 1f1304ceb..000000000 --- a/proposals/clocks/.github/workflows/publish-0.3.yml +++ /dev/null @@ -1,71 +0,0 @@ -name: Publish 0.3.0 WIT Definitions - -# Run this action when changes are pushed to the main branch and affect files in the wit-0.3.0-draft directory -on: - push: - tags: - - v0.3.0-rc-* - workflow_dispatch: # Allow manual triggering - -env: - IMAGE_NAME: ${{ github.repository }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - packages: write - contents: write - - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - - name: Install wkg - shell: bash - run: cargo binstall wkg - - - name: Install cosign - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 - - # To version our image we want to obtain the version from the tag - - name: Get version - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/webassembly/wasi/clocks - tags: | - type=semver,pattern={{version}} - - - name: Login to the GitHub registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ORG_PAT }} - - - name: Build - shell: bash - run: wkg wit build -o "${{ github.event.repository.name }}-0.3.0.wasm" --wit-dir wit-0.3.0-draft - - # Upload the Wasm binary to the GitHub registry - - name: Publish to GitHub Container Registry - id: publish - uses: bytecodealliance/wkg-github-action@v5 - with: - oci-reference-without-tag: "ghcr.io/webassembly/wasi/clocks" - file: "${{ github.event.repository.name }}-0.3.0.wasm" - description: "A WASI API for reading the current time and measuring elapsed time (0.3.0 version)." - source: 'https://github.com/webassembly/wasi' - homepage: 'https://wasi.dev' - version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - licenses: 'Apache-2.0 WITH LLVM-exception' - - # Sign the output component - - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/clocks@${{ steps.publish.outputs.digest }} diff --git a/proposals/clocks/.github/workflows/publish.yml b/proposals/clocks/.github/workflows/publish.yml deleted file mode 100644 index 84d44f3be..000000000 --- a/proposals/clocks/.github/workflows/publish.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Publish a Wasm Component package to GitHub Artifacts - -# Run this action whenever a new release is tagged -on: - push: - tags: - - v0.2.* - workflow_dispatch: - -env: - IMAGE_NAME: ${{ github.repository }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - packages: write - contents: write - - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@v2 - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@v1.10.15 - - name: Install wkg - shell: bash - run: cargo binstall wkg - - name: Install cosign - uses: sigstore/cosign-installer@v3.7.0 - - # To version our image we want to obtain the version from the tag - - name: Get version - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/webassembly/wasi/clocks - tags: | - type=semver,pattern={{version}} - - # To upload our image to the GitHub registry, we first have to login - - name: Login to the GitHub registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ORG_PAT }} - - # Build our `.wit` files into a Wasm binary - - name: Build - shell: bash - run: wkg wit build -o wasi-clocks.wasm - - # Upload the Wasm binary to the GitHub registry - - name: Publish to GitHub Container Registry - id: publish - uses: bytecodealliance/wkg-github-action@v5 - with: - oci-reference-without-tag: 'ghcr.io/webassembly/wasi/clocks' - file: 'wasi-clocks.wasm' - description: 'A WASI API for reading the current time and measuring elapsed time.' - source: 'https://github.com/webassembly/wasi' - homepage: 'https://wasi.dev' - version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - licenses: 'Apache-2.0 WITH LLVM-exception' - - # Sign the output component - - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/clocks@${{ steps.publish.outputs.digest }} diff --git a/proposals/clocks/.github/workflows/update-0.3.yml b/proposals/clocks/.github/workflows/update-0.3.yml deleted file mode 100644 index 7ed9421cf..000000000 --- a/proposals/clocks/.github/workflows/update-0.3.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: Update 0.3.0 WIT Definitions - -# Manually dispatch this action from the Actions page -on: - workflow_dispatch: - -permissions: - pull-requests: write - contents: write - -jobs: - update-versions: - runs-on: ubuntu-latest - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - # TODO: we don't pin the versions here. It's not great but this will simplify our iteration - # while we rapidly iterate on these tools. Pin when we're stable. - - name: Install wit-bindgen - shell: bash - run: cargo binstall wit-bindgen-cli - - - name: Install wit-deps - shell: bash - run: cargo binstall wit-deps-cli - - - name: Set version with RC timestamp - id: version - run: | - DATE=$(date +'%Y-%m-%d') - BASE_VERSION="0.3.0-rc-${DATE}" - COUNTER=1 - VERSION="${BASE_VERSION}" - - # Check if the tag already exists - while git ls-remote --tags origin | grep -q "refs/tags/v${VERSION}$"; do - VERSION="${BASE_VERSION}-${COUNTER}" - COUNTER=$((COUNTER + 1)) - done - - echo "value=${VERSION}" >> $GITHUB_OUTPUT - echo "Version will be: ${VERSION}" - - # Update version in WIT definitions - - name: Update version in WIT files - run: | - # Update @since version annotations - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + - # Update all wasi package references (package, use, import, export, from) - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\( wasi:[a-zA-Z0-9_/-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + - - # Create PR with changes using create-pull-request action - - name: Create Pull Request - uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" - committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - branch: update-wit-${{ steps.version.outputs.value }} - title: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" - body: | - Updates the 0.3.0 WIT definitions with version ${{ steps.version.outputs.value }}. - - This is an automated update to rev the RC timestamp. - - ## Changes - - Updated package and since version in WIT files - - Updated WIT dependencies if applicable - draft: false - delete-branch: true diff --git a/proposals/clocks/.github/workflows/update.yml b/proposals/clocks/.github/workflows/update.yml deleted file mode 100644 index bdf61d30c..000000000 --- a/proposals/clocks/.github/workflows/update.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Create a PR to upgrade WIT to a new version - -# Manually dispatch this action from the Actions page -on: - workflow_dispatch: - inputs: - prev_version: - description: 'Upgrading from version (without the v)' - required: true - type: string - next_version: - description: 'Upgrading to version (without the v)' - required: true - type: string - -permissions: - pull-requests: write - contents: write - -jobs: - update-versions: - runs-on: ubuntu-latest - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@v4 - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@v1.10.15 - - name: Install wit-bindgen - shell: bash - run: cargo binstall wit-bindgen-cli - - name: Install wit-deps - shell: bash - run: cargo binstall wit-deps-cli - - # echo input - - name: Print the versions - run: echo Upgrading from ${{ inputs.prev_version }} to ${{ inputs.next_version }} - - # upgrade - - name: Upgrade tag - run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - - name: Upgrade wit deps - run: wit-deps update - - name: Generate markdown - run: wit-bindgen markdown wit --html-in-md --all-features - - # file PR - - name: Create feature branch - env: - FEATURE_BRANCH: release-v${{ inputs.next_version }} - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add . - git checkout -b $FEATURE_BRANCH - git push -u origin $FEATURE_BRANCH - git commit -m "Update to v${{ inputs.next_version }}" - git push - - - name: Create pull request - run: gh pr create -B main -H release-v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/proposals/filesystem/.github/workflows/main.yml b/proposals/filesystem/.github/workflows/main.yml deleted file mode 100644 index 7641394b9..000000000 --- a/proposals/filesystem/.github/workflows/main.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: CI -on: - push: - branches: [main] - pull_request: - branches: [main] - -jobs: - abi-up-to-date: - name: Check ABI files are up-to-date - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: ensure `./wit/deps` are in sync - run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.5.0/wit-deps-x86_64-unknown-linux-musl - chmod +x wit-deps - ./wit-deps lock - ./wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps lock - git add -N wit/deps - git add -N wit-0.3.0-draft/deps - git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v25 - with: - all-features: 'true' diff --git a/proposals/filesystem/.github/workflows/publish-0.3.yml b/proposals/filesystem/.github/workflows/publish-0.3.yml deleted file mode 100644 index 0367997eb..000000000 --- a/proposals/filesystem/.github/workflows/publish-0.3.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: Publish 0.3.0 WIT Definitions - -on: - push: - tags: - - v0.3.0-rc-* - workflow_dispatch: # Allow manual triggering - -env: - IMAGE_NAME: ${{ github.repository }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - packages: write - contents: write - - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - # TODO: we don't pin the versions here. It's not great but this will simplify our iteration - # while we rapidly iterate on these tools. Pin when we're stable. - - name: Install wkg - shell: bash - run: cargo binstall wkg - - - name: Install cosign - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 - - # To version our image we want to obtain the version from the tag - - name: Get version - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/webassembly/wasi/filesystem - tags: | - type=semver,pattern={{version}} - - - name: Login to the GitHub registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ORG_PAT }} - - - name: Build - shell: bash - run: wkg wit build -o "${{ github.event.repository.name }}-0.3.0.wasm" --wit-dir wit-0.3.0-draft - - # Upload the Wasm binary to the GitHub registry - - name: Publish to GitHub Container Registry - id: publish - uses: bytecodealliance/wkg-github-action@v5 - with: - oci-reference-without-tag: "ghcr.io/webassembly/wasi/filesystem" - file: "${{ github.event.repository.name }}-0.3.0.wasm" - description: "A WASI API for reading the current time and measuring elapsed time (0.3.0 version)." - source: 'https://github.com/webassembly/wasi' - homepage: 'https://wasi.dev' - version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - licenses: 'Apache-2.0 WITH LLVM-exception' - - # Sign the output component - - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/filesystem@${{ steps.publish.outputs.digest }} diff --git a/proposals/filesystem/.github/workflows/publish.yml b/proposals/filesystem/.github/workflows/publish.yml deleted file mode 100644 index 1e4de427f..000000000 --- a/proposals/filesystem/.github/workflows/publish.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Publish a Wasm Component package to GitHub Artifacts - -# Run this action whenever a new release is tagged -on: - push: - tags: - - v0.2.* - workflow_dispatch: - -env: - IMAGE_NAME: ${{ github.repository }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - packages: write - contents: write - - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@v2 - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - name: Install wkg - shell: bash - run: cargo binstall wkg - - name: Install cosign - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 - - # To version our image we want to obtain the version from the tag - - name: Get version - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/webassembly/wasi/filesystem - tags: | - type=semver,pattern={{version}} - - # To upload our image to the GitHub registry, we first have to login - - name: Login to the GitHub registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ORG_PAT }} - - # Build our `.wit` files into a Wasm binary - - name: Build - shell: bash - run: wkg wit build -o wasi-filesystem.wasm - - # Upload the Wasm binary to the GitHub registry - - name: Publish to GitHub Container Registry - id: publish - uses: bytecodealliance/wkg-github-action@v5 - with: - oci-reference-without-tag: 'ghcr.io/webassembly/wasi/filesystem' - file: 'wasi-filesystem.wasm' - description: 'A WASI API primarily for accessing host filesystems.' - source: 'https://github.com/webassembly/wasi' - homepage: 'https://wasi.dev' - version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - licenses: 'Apache-2.0 WITH LLVM-exception' - - # Sign the output component - - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/filesystem@${{ steps.publish.outputs.digest }} diff --git a/proposals/filesystem/.github/workflows/update-0.3.yml b/proposals/filesystem/.github/workflows/update-0.3.yml deleted file mode 100644 index 7bceb94e1..000000000 --- a/proposals/filesystem/.github/workflows/update-0.3.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: Update 0.3.0 WIT Definitions - -# Manually dispatch this action from the Actions page -on: - workflow_dispatch: - -permissions: - pull-requests: write - contents: write - -jobs: - update-versions: - runs-on: ubuntu-latest - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - # TODO: we don't pin the versions here. It's not great but this will simplify our iteration - # while we rapidly iterate on these tools. Pin when we're stable. - - name: Install wit-bindgen - shell: bash - run: cargo binstall wit-bindgen-cli - - - name: Install wit-deps - shell: bash - run: cargo binstall wit-deps-cli - - - name: Set version with RC timestamp - id: version - run: | - DATE=$(date +'%Y-%m-%d') - BASE_VERSION="0.3.0-rc-${DATE}" - COUNTER=1 - VERSION="${BASE_VERSION}" - - # Check if the tag already exists - while git ls-remote --tags origin | grep -q "refs/tags/v${VERSION}$"; do - VERSION="${BASE_VERSION}-${COUNTER}" - COUNTER=$((COUNTER + 1)) - done - - echo "value=${VERSION}" >> $GITHUB_OUTPUT - echo "Version will be: ${VERSION}" - - # Update version in WIT definitions - - name: Update version in WIT files - run: | - # Update @since version annotations - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + - # Update all wasi package references (package, use, import, export, from) - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\( wasi:[a-zA-Z0-9_/-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + - - - name: Update wit deps - run: | - wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps update - - # Create PR with changes using create-pull-request action - - name: Create Pull Request - uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" - committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - branch: update-wit-${{ steps.version.outputs.value }} - title: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" - body: | - Updates the 0.3.0 WIT definitions with version ${{ steps.version.outputs.value }}. - - This is an automated update to rev the RC timestamp. - - ## Changes - - Updated package and since version in WIT files - - Updated WIT dependencies if applicable - draft: false - delete-branch: true diff --git a/proposals/filesystem/.github/workflows/update.yml b/proposals/filesystem/.github/workflows/update.yml deleted file mode 100644 index 850cb6bf3..000000000 --- a/proposals/filesystem/.github/workflows/update.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Create a PR to upgrade WIT to a new version - -# Manually dispatch this action from the Actions page -on: - workflow_dispatch: - inputs: - prev_version: - description: 'Upgrading from version (without the v)' - required: true - type: string - next_version: - description: 'Upgrading to version (without the v)' - required: true - type: string - -permissions: - pull-requests: write - contents: write - -jobs: - update-versions: - runs-on: ubuntu-latest - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - name: Install wit-bindgen - shell: bash - run: cargo binstall wit-bindgen-cli - - name: Install wit-deps - shell: bash - run: cargo binstall wit-deps-cli - - # echo input - - name: Print the versions - run: echo Upgrading from ${{ inputs.prev_version }} to ${{ inputs.next_version }} - - # upgrade - - name: Upgrade tag - run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - - name: Upgrade wit deps - run: wit-deps update - - name: Generate markdown - run: wit-bindgen markdown wit --html-in-md --all-features - - # file PR - - name: Create feature branch - env: - FEATURE_BRANCH: release-v${{ inputs.next_version }} - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add . - git checkout -b $FEATURE_BRANCH - git push -u origin $FEATURE_BRANCH - git commit -m "Update to v${{ inputs.next_version }}" - git push - - - name: Create pull request - run: gh pr create -B main -H release-v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/proposals/http/.github/workflows/main.yml b/proposals/http/.github/workflows/main.yml deleted file mode 100644 index 0540b7786..000000000 --- a/proposals/http/.github/workflows/main.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: CI -on: - push: - branches: [main] - pull_request: - branches: [main] - -jobs: - abi-up-to-date: - name: Check ABI files are up-to-date - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: ensure `./wit/deps` are in sync - run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.5.0/wit-deps-x86_64-unknown-linux-musl - chmod +x ./wit-deps - ./wit-deps lock --check - ./wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps lock --check - - uses: WebAssembly/wit-abi-up-to-date@v25 - with: - worlds: 'imports proxy' - all-features: 'true' diff --git a/proposals/http/.github/workflows/publish-0.3.yml b/proposals/http/.github/workflows/publish-0.3.yml deleted file mode 100644 index ed05a0d25..000000000 --- a/proposals/http/.github/workflows/publish-0.3.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: Publish 0.3.0 WIT Definitions - -on: - push: - tags: - - v0.3.0-rc-* - workflow_dispatch: # Allow manual triggering - -env: - IMAGE_NAME: ${{ github.repository }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - packages: write - contents: write - - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - # TODO: we don't pin the versions here. It's not great but this will simplify our iteration - # while we rapidly iterate on these tools. Pin when we're stable. - - name: Install wkg - shell: bash - run: cargo binstall wkg - - - name: Install cosign - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 - - # To version our image we want to obtain the version from the tag - - name: Get version - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/webassembly/wasi/http - tags: | - type=semver,pattern={{version}} - - - name: Login to the GitHub registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ORG_PAT }} - - - name: Build - shell: bash - run: wkg wit build -o "${{ github.event.repository.name }}-0.3.0.wasm" --wit-dir wit-0.3.0-draft - - # Upload the Wasm binary to the GitHub registry - - name: Publish to GitHub Container Registry - id: publish - uses: bytecodealliance/wkg-github-action@v5 - with: - oci-reference-without-tag: "ghcr.io/webassembly/wasi/http" - file: "${{ github.event.repository.name }}-0.3.0.wasm" - description: "A WASI API for sending and receiving HTTP requests and responses." - source: 'https://github.com/webassembly/wasi' - homepage: 'https://wasi.dev' - version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - licenses: 'Apache-2.0 WITH LLVM-exception' - - # Sign the output component - - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/http@${{ steps.publish.outputs.digest }} diff --git a/proposals/http/.github/workflows/publish.yml b/proposals/http/.github/workflows/publish.yml deleted file mode 100644 index 654ad8bc4..000000000 --- a/proposals/http/.github/workflows/publish.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Publish a Wasm Component package to GitHub Artifacts - -# Run this action whenever a new release is tagged -on: - push: - tags: - - v0.2.* - workflow_dispatch: - -env: - IMAGE_NAME: ${{ github.repository }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - packages: write - contents: write - - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@v2 - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - name: Install wkg - shell: bash - run: cargo binstall wkg - - name: Install cosign - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 - - # To version our image we want to obtain the version from the tag - - name: Get version - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/webassembly/wasi/http - tags: | - type=semver,pattern={{version}} - - # To upload our image to the GitHub registry, we first have to login - - name: Login to the GitHub registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ORG_PAT }} - - # Build our `.wit` files into a Wasm binary - - name: Build - shell: bash - run: wkg wit build -o wasi-http.wasm - - # Upload the Wasm binary to the GitHub registry - - name: Publish to GitHub Container Registry - id: publish - uses: bytecodealliance/wkg-github-action@v5 - with: - oci-reference-without-tag: 'ghcr.io/webassembly/wasi/http' - file: 'wasi-http.wasm' - description: 'A WASI API for sending and receiving HTTP requests and responses.' - source: 'https://github.com/webassembly/wasi' - homepage: 'https://wasi.dev' - version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - licenses: 'Apache-2.0 WITH LLVM-exception' - - # Sign the output component - - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/http@${{ steps.publish.outputs.digest }} diff --git a/proposals/http/.github/workflows/update-0.3.yml b/proposals/http/.github/workflows/update-0.3.yml deleted file mode 100644 index 7bceb94e1..000000000 --- a/proposals/http/.github/workflows/update-0.3.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: Update 0.3.0 WIT Definitions - -# Manually dispatch this action from the Actions page -on: - workflow_dispatch: - -permissions: - pull-requests: write - contents: write - -jobs: - update-versions: - runs-on: ubuntu-latest - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - # TODO: we don't pin the versions here. It's not great but this will simplify our iteration - # while we rapidly iterate on these tools. Pin when we're stable. - - name: Install wit-bindgen - shell: bash - run: cargo binstall wit-bindgen-cli - - - name: Install wit-deps - shell: bash - run: cargo binstall wit-deps-cli - - - name: Set version with RC timestamp - id: version - run: | - DATE=$(date +'%Y-%m-%d') - BASE_VERSION="0.3.0-rc-${DATE}" - COUNTER=1 - VERSION="${BASE_VERSION}" - - # Check if the tag already exists - while git ls-remote --tags origin | grep -q "refs/tags/v${VERSION}$"; do - VERSION="${BASE_VERSION}-${COUNTER}" - COUNTER=$((COUNTER + 1)) - done - - echo "value=${VERSION}" >> $GITHUB_OUTPUT - echo "Version will be: ${VERSION}" - - # Update version in WIT definitions - - name: Update version in WIT files - run: | - # Update @since version annotations - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + - # Update all wasi package references (package, use, import, export, from) - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\( wasi:[a-zA-Z0-9_/-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + - - - name: Update wit deps - run: | - wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps update - - # Create PR with changes using create-pull-request action - - name: Create Pull Request - uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" - committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - branch: update-wit-${{ steps.version.outputs.value }} - title: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" - body: | - Updates the 0.3.0 WIT definitions with version ${{ steps.version.outputs.value }}. - - This is an automated update to rev the RC timestamp. - - ## Changes - - Updated package and since version in WIT files - - Updated WIT dependencies if applicable - draft: false - delete-branch: true diff --git a/proposals/http/.github/workflows/update.yml b/proposals/http/.github/workflows/update.yml deleted file mode 100644 index f306a3040..000000000 --- a/proposals/http/.github/workflows/update.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: Create a PR to upgrade WIT to a new version - -# Manually dispatch this action from the Actions page -on: - workflow_dispatch: - inputs: - prev_version: - description: 'Upgrading from version (without the v)' - required: true - type: string - next_version: - description: 'Upgrading to version (without the v)' - required: true - type: string - -permissions: - pull-requests: write - contents: write - -jobs: - update-versions: - runs-on: ubuntu-latest - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - name: Install wit-bindgen - shell: bash - run: cargo binstall wit-bindgen-cli - - name: Install wit-deps - shell: bash - run: cargo binstall wit-deps-cli - - # echo input - - name: Print the versions - run: echo Upgrading from ${{ inputs.prev_version }} to ${{ inputs.next_version }} - - # upgrade - - name: Upgrade tag - run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - - name: Upgrade deps tags - run: find . -type f -name "deps.toml" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - - name: Upgrade wit deps - run: wit-deps update - - name: Generate markdown for the proxy world - run: wit-bindgen markdown wit -w proxy --html-in-md --features=informational-outbound-responses - - name: Generate markdown for the imports world - run: wit-bindgen markdown wit -w imports --html-in-md --features=informational-outbound-responses - - # file PR - - name: Create feature branch - env: - FEATURE_BRANCH: release-v${{ inputs.next_version }} - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add . - git checkout -b $FEATURE_BRANCH - git push -u origin $FEATURE_BRANCH - git commit -m "Update to v${{ inputs.next_version }}" - git push - - - name: Create pull request - run: gh pr create -B main -H release-v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/proposals/io/.github/workflows/main.yml b/proposals/io/.github/workflows/main.yml deleted file mode 100644 index 9f16450d4..000000000 --- a/proposals/io/.github/workflows/main.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: CI -on: - push: - branches: [main] - pull_request: - branches: [main] - -jobs: - abi-up-to-date: - name: Check ABI files are up-to-date - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: WebAssembly/wit-abi-up-to-date@v24 - with: - all-features: 'true' \ No newline at end of file diff --git a/proposals/io/.github/workflows/publish.yml b/proposals/io/.github/workflows/publish.yml deleted file mode 100644 index ad76665f3..000000000 --- a/proposals/io/.github/workflows/publish.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Publish a Wasm Component package to GitHub Artifacts - -# Run this action whenever a new release is tagged -on: - push: - tags: - - v* - workflow_dispatch: - -env: - IMAGE_NAME: ${{ github.repository }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - packages: write - contents: write - - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@v2 - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@v1.10.15 - - name: Install wkg - shell: bash - run: cargo binstall wkg - - name: Install cosign - uses: sigstore/cosign-installer@v3.7.0 - - # To version our image we want to obtain the version from the tag - - name: Get version - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/webassembly/wasi/io - tags: | - type=semver,pattern={{version}} - - # To upload our image to the GitHub registry, we first have to login - - name: Login to the GitHub registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ORG_PAT }} - - # Build our `.wit` files into a Wasm binary - - name: Build - shell: bash - run: wkg wit build -o wasi-io.wasm - - # Upload the Wasm binary to the GitHub registry - - name: Publish to GitHub Container Registry - id: publish - uses: bytecodealliance/wkg-github-action@v5 - with: - oci-reference-without-tag: 'ghcr.io/webassembly/wasi/io' - file: 'wasi-io.wasm' - description: 'A WASI API providing I/O stream abstractions.' - source: 'https://github.com/webassembly/wasi' - homepage: 'https://wasi.dev' - version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - licenses: 'Apache-2.0 WITH LLVM-exception' - - # Sign the output component - - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/io@${{ steps.publish.outputs.digest }} diff --git a/proposals/io/.github/workflows/update.yml b/proposals/io/.github/workflows/update.yml deleted file mode 100644 index 22d10e7a3..000000000 --- a/proposals/io/.github/workflows/update.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Create a PR to upgrade WIT to a new version - -# Manually dispatch this action from the Actions page -on: - workflow_dispatch: - inputs: - prev_version: - description: 'Upgrading from version (without the v)' - required: true - type: string - next_version: - description: 'Upgrading to version (without the v)' - required: true - type: string - -permissions: - pull-requests: write - contents: write - -jobs: - update-versions: - runs-on: ubuntu-latest - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@v4 - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@v1.10.15 - - name: Install wit-bindgen - shell: bash - run: cargo binstall wit-bindgen-cli - - name: Install wit-deps - shell: bash - run: cargo binstall wit-deps-cli - - # echo input - - name: Print the versions - run: echo Upgrading from ${{ inputs.prev_version }} to ${{ inputs.next_version }} - - # upgrade - - name: Upgrade tag - run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - # - name: Upgrade wit deps - # run: wit-deps update - - name: Generate markdown - run: wit-bindgen markdown wit --html-in-md --all-features - - # file PR - - name: Create feature branch - env: - FEATURE_BRANCH: release-v${{ inputs.next_version }} - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add . - git checkout -b $FEATURE_BRANCH - git push -u origin $FEATURE_BRANCH - git commit -m "Update to v${{ inputs.next_version }}" - git push - - - name: Create pull request - run: gh pr create -B main -H release-v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/proposals/random/.github/workflows/main.yml b/proposals/random/.github/workflows/main.yml deleted file mode 100644 index 9f16450d4..000000000 --- a/proposals/random/.github/workflows/main.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: CI -on: - push: - branches: [main] - pull_request: - branches: [main] - -jobs: - abi-up-to-date: - name: Check ABI files are up-to-date - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: WebAssembly/wit-abi-up-to-date@v24 - with: - all-features: 'true' \ No newline at end of file diff --git a/proposals/random/.github/workflows/publish-0.3.yml b/proposals/random/.github/workflows/publish-0.3.yml deleted file mode 100644 index 84b54723c..000000000 --- a/proposals/random/.github/workflows/publish-0.3.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Publish 0.3.0 WIT Definitions - -on: - push: - tags: - - v0.3.0-rc-* - workflow_dispatch: # Allow manual triggering - -env: - IMAGE_NAME: ${{ github.repository }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - packages: write - contents: write - - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - - name: Install wkg - shell: bash - run: cargo binstall wkg - - - name: Install cosign - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 - - # To version our image we want to obtain the version from the tag - - name: Get version - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/webassembly/wasi/random - tags: | - type=semver,pattern={{version}} - - - name: Login to the GitHub registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ORG_PAT }} - - - name: Build - shell: bash - run: wkg wit build -o "${{ github.event.repository.name }}-0.3.0.wasm" --wit-dir wit-0.3.0-draft - - # Upload the Wasm binary to the GitHub registry - - name: Publish to GitHub Container Registry - id: publish - uses: bytecodealliance/wkg-github-action@v5 - with: - oci-reference-without-tag: "ghcr.io/webassembly/wasi/random" - file: "${{ github.event.repository.name }}-0.3.0.wasm" - description: "A WASI API for reading the current time and measuring elapsed time (0.3.0 version)." - source: 'https://github.com/webassembly/wasi' - homepage: 'https://wasi.dev' - version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - licenses: 'Apache-2.0 WITH LLVM-exception' - - # Sign the output component - - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/random@${{ steps.publish.outputs.digest }} diff --git a/proposals/random/.github/workflows/publish.yml b/proposals/random/.github/workflows/publish.yml deleted file mode 100644 index 1ed7fad7c..000000000 --- a/proposals/random/.github/workflows/publish.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Publish a Wasm Component package to GitHub Artifacts - -# Run this action whenever a new release is tagged -on: - push: - tags: - - v0.2.* - workflow_dispatch: - -env: - IMAGE_NAME: ${{ github.repository }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - packages: write - contents: write - - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@v2 - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@v1.10.15 - - name: Install wkg - shell: bash - run: cargo binstall wkg - - name: Install cosign - uses: sigstore/cosign-installer@v3.7.0 - - # To version our image we want to obtain the version from the tag - - name: Get version - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/webassembly/wasi/random - tags: | - type=semver,pattern={{version}} - - # To upload our image to the GitHub registry, we first have to login - - name: Login to the GitHub registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ORG_PAT }} - - # Build our `.wit` files into a Wasm binary - - name: Build - shell: bash - run: wkg wit build -o wasi-random.wasm - - # Upload the Wasm binary to the GitHub registry - - name: Publish to GitHub Container Registry - id: publish - uses: bytecodealliance/wkg-github-action@v5 - with: - oci-reference-without-tag: 'ghcr.io/webassembly/wasi/random' - file: 'wasi-random.wasm' - description: 'A WASI API for obtaining pseudo-random data.' - source: 'https://github.com/webassembly/wasi' - homepage: 'https://wasi.dev' - version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - licenses: 'Apache-2.0 WITH LLVM-exception' - - # Sign the output component - - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/random@${{ steps.publish.outputs.digest }} diff --git a/proposals/random/.github/workflows/update-0.3.yml b/proposals/random/.github/workflows/update-0.3.yml deleted file mode 100644 index 7ed9421cf..000000000 --- a/proposals/random/.github/workflows/update-0.3.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: Update 0.3.0 WIT Definitions - -# Manually dispatch this action from the Actions page -on: - workflow_dispatch: - -permissions: - pull-requests: write - contents: write - -jobs: - update-versions: - runs-on: ubuntu-latest - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - # TODO: we don't pin the versions here. It's not great but this will simplify our iteration - # while we rapidly iterate on these tools. Pin when we're stable. - - name: Install wit-bindgen - shell: bash - run: cargo binstall wit-bindgen-cli - - - name: Install wit-deps - shell: bash - run: cargo binstall wit-deps-cli - - - name: Set version with RC timestamp - id: version - run: | - DATE=$(date +'%Y-%m-%d') - BASE_VERSION="0.3.0-rc-${DATE}" - COUNTER=1 - VERSION="${BASE_VERSION}" - - # Check if the tag already exists - while git ls-remote --tags origin | grep -q "refs/tags/v${VERSION}$"; do - VERSION="${BASE_VERSION}-${COUNTER}" - COUNTER=$((COUNTER + 1)) - done - - echo "value=${VERSION}" >> $GITHUB_OUTPUT - echo "Version will be: ${VERSION}" - - # Update version in WIT definitions - - name: Update version in WIT files - run: | - # Update @since version annotations - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + - # Update all wasi package references (package, use, import, export, from) - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\( wasi:[a-zA-Z0-9_/-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + - - # Create PR with changes using create-pull-request action - - name: Create Pull Request - uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" - committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - branch: update-wit-${{ steps.version.outputs.value }} - title: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" - body: | - Updates the 0.3.0 WIT definitions with version ${{ steps.version.outputs.value }}. - - This is an automated update to rev the RC timestamp. - - ## Changes - - Updated package and since version in WIT files - - Updated WIT dependencies if applicable - draft: false - delete-branch: true diff --git a/proposals/random/.github/workflows/update.yml b/proposals/random/.github/workflows/update.yml deleted file mode 100644 index b2eaec687..000000000 --- a/proposals/random/.github/workflows/update.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: Create a PR to upgrade WIT to a new version - -# Manually dispatch this action from the Actions page -on: - workflow_dispatch: - inputs: - prev_version: - description: 'Upgrading from version (without the v)' - required: true - type: string - next_version: - description: 'Upgrading to version (without the v)' - required: true - type: string - -permissions: - pull-requests: write - contents: write - -jobs: - update-versions: - runs-on: ubuntu-latest - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@v4 - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@v1.10.15 - - name: Install wit-bindgen - shell: bash - run: cargo binstall wit-bindgen-cli - - # echo input - - name: Print the versions - run: echo Upgrading from ${{ inputs.prev_version }} to ${{ inputs.next_version }} - - # upgrade - - name: Upgrade tag - run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - - name: Generate markdown - run: wit-bindgen markdown wit --html-in-md --all-features - - # file PR - - name: Create feature branch - env: - FEATURE_BRANCH: release-v${{ inputs.next_version }} - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add . - git checkout -b $FEATURE_BRANCH - git push -u origin $FEATURE_BRANCH - git commit -m "Update to v${{ inputs.next_version }}" - git push - - - name: Create pull request - run: gh pr create -B main -H release-v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/proposals/sockets/.github/workflows/main.yml b/proposals/sockets/.github/workflows/main.yml deleted file mode 100644 index cfc4f7ea5..000000000 --- a/proposals/sockets/.github/workflows/main.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: CI -on: - push: - branches: [main] - pull_request: - branches: [main] - -jobs: - abi-up-to-date: - name: Check ABI files are up-to-date - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: ensure `./wit/deps` are in sync - run: | - curl -Lo 'wit-deps' https://github.com/bytecodealliance/wit-deps/releases/download/v0.5.0/wit-deps-x86_64-unknown-linux-musl - chmod +x wit-deps - ./wit-deps lock - ./wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps lock - git add -N wit/deps - git add -N wit-0.3.0-draft/deps - git diff --exit-code - - uses: WebAssembly/wit-abi-up-to-date@v24 - with: - all-features: 'true' diff --git a/proposals/sockets/.github/workflows/publish-0.3.yml b/proposals/sockets/.github/workflows/publish-0.3.yml deleted file mode 100644 index 5eb3c0b0e..000000000 --- a/proposals/sockets/.github/workflows/publish-0.3.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: Publish 0.3.0 WIT Definitions - -on: - push: - tags: - - v0.3.0-rc-* - workflow_dispatch: # Allow manual triggering - -env: - IMAGE_NAME: ${{ github.repository }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - packages: write - contents: write - - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - # TODO: we don't pin the versions here. It's not great but this will simplify our iteration - # while we rapidly iterate on these tools. Pin when we're stable. - - name: Install wkg - shell: bash - run: cargo binstall wkg - - - name: Install cosign - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 - - # To version our image we want to obtain the version from the tag - - name: Get version - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/webassembly/wasi/sockets - tags: | - type=semver,pattern={{version}} - - - name: Login to the GitHub registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ORG_PAT }} - - - name: Build - shell: bash - run: wkg wit build -o "${{ github.event.repository.name }}-0.3.0.wasm" --wit-dir wit-0.3.0-draft - - # Upload the Wasm binary to the GitHub registry - - name: Publish to GitHub Container Registry - id: publish - uses: bytecodealliance/wkg-github-action@v5 - with: - oci-reference-without-tag: "ghcr.io/webassembly/wasi/sockets" - file: "${{ github.event.repository.name }}-0.3.0.wasm" - description: "A WASI API for reading the current time and measuring elapsed time (0.3.0 version)." - source: 'https://github.com/webassembly/wasi' - homepage: 'https://wasi.dev' - version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - licenses: 'Apache-2.0 WITH LLVM-exception' - - # Sign the output component - - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/sockets@${{ steps.publish.outputs.digest }} diff --git a/proposals/sockets/.github/workflows/publish.yml b/proposals/sockets/.github/workflows/publish.yml deleted file mode 100644 index cf5f71c66..000000000 --- a/proposals/sockets/.github/workflows/publish.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Publish a Wasm Component package to GitHub Artifacts - -# Run this action whenever a new release is tagged -on: - push: - tags: - - v0.2.* - workflow_dispatch: - -env: - IMAGE_NAME: ${{ github.repository }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - packages: write - contents: write - - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@v2 - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - name: Install wkg - shell: bash - run: cargo binstall wkg - - name: Install cosign - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 - - # To version our image we want to obtain the version from the tag - - name: Get version - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/webassembly/wasi/sockets - tags: | - type=semver,pattern={{version}} - - # To upload our image to the GitHub registry, we first have to login - - name: Login to the GitHub registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ORG_PAT }} - - # Build our `.wit` files into a Wasm binary - - name: Build - shell: bash - run: wkg wit build -o wasi-sockets.wasm - - # Upload the Wasm binary to the GitHub registry - - name: Publish to GitHub Container Registry - id: publish - uses: bytecodealliance/wkg-github-action@v5 - with: - oci-reference-without-tag: 'ghcr.io/webassembly/wasi/sockets' - file: 'wasi-sockets.wasm' - description: 'A WASI API for TCP & UDP sockets and domain name lookup.' - source: 'https://github.com/webassembly/wasi' - homepage: 'https://wasi.dev' - version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - licenses: 'Apache-2.0 WITH LLVM-exception' - - # Sign the output component - - name: Sign the wasm component - run: cosign sign --yes ghcr.io/webassembly/wasi/sockets@${{ steps.publish.outputs.digest }} diff --git a/proposals/sockets/.github/workflows/update-0.3.yml b/proposals/sockets/.github/workflows/update-0.3.yml deleted file mode 100644 index 7bceb94e1..000000000 --- a/proposals/sockets/.github/workflows/update-0.3.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: Update 0.3.0 WIT Definitions - -# Manually dispatch this action from the Actions page -on: - workflow_dispatch: - -permissions: - pull-requests: write - contents: write - -jobs: - update-versions: - runs-on: ubuntu-latest - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - # TODO: we don't pin the versions here. It's not great but this will simplify our iteration - # while we rapidly iterate on these tools. Pin when we're stable. - - name: Install wit-bindgen - shell: bash - run: cargo binstall wit-bindgen-cli - - - name: Install wit-deps - shell: bash - run: cargo binstall wit-deps-cli - - - name: Set version with RC timestamp - id: version - run: | - DATE=$(date +'%Y-%m-%d') - BASE_VERSION="0.3.0-rc-${DATE}" - COUNTER=1 - VERSION="${BASE_VERSION}" - - # Check if the tag already exists - while git ls-remote --tags origin | grep -q "refs/tags/v${VERSION}$"; do - VERSION="${BASE_VERSION}-${COUNTER}" - COUNTER=$((COUNTER + 1)) - done - - echo "value=${VERSION}" >> $GITHUB_OUTPUT - echo "Version will be: ${VERSION}" - - # Update version in WIT definitions - - name: Update version in WIT files - run: | - # Update @since version annotations - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\(@since(version = \)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?\()\)/\1${{ steps.version.outputs.value }}\4/g" {} + - # Update all wasi package references (package, use, import, export, from) - find wit-0.3.0-draft -name "*.wit" -exec sed -i "s/\( wasi:[a-zA-Z0-9_/-]\+@\)[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\(-[0-9]\+\)\?\)\?/\1${{ steps.version.outputs.value }}/g" {} + - - - name: Update wit deps - run: | - wit-deps -m wit-0.3.0-draft/deps.toml -l wit-0.3.0-draft/deps.lock -d wit-0.3.0-draft/deps update - - # Create PR with changes using create-pull-request action - - name: Create Pull Request - uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" - committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - branch: update-wit-${{ steps.version.outputs.value }} - title: "Update 0.3.0 WIT definitions to ${{ steps.version.outputs.value }}" - body: | - Updates the 0.3.0 WIT definitions with version ${{ steps.version.outputs.value }}. - - This is an automated update to rev the RC timestamp. - - ## Changes - - Updated package and since version in WIT files - - Updated WIT dependencies if applicable - draft: false - delete-branch: true diff --git a/proposals/sockets/.github/workflows/update.yml b/proposals/sockets/.github/workflows/update.yml deleted file mode 100644 index 850cb6bf3..000000000 --- a/proposals/sockets/.github/workflows/update.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Create a PR to upgrade WIT to a new version - -# Manually dispatch this action from the Actions page -on: - workflow_dispatch: - inputs: - prev_version: - description: 'Upgrading from version (without the v)' - required: true - type: string - next_version: - description: 'Upgrading to version (without the v)' - required: true - type: string - -permissions: - pull-requests: write - contents: write - -jobs: - update-versions: - runs-on: ubuntu-latest - steps: - # Checkout the repo and install dependencies - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@8aac5aa2bf0dfaa2863eccad9f43c68fe40e5ec8 # v1.14.1 - - name: Install wit-bindgen - shell: bash - run: cargo binstall wit-bindgen-cli - - name: Install wit-deps - shell: bash - run: cargo binstall wit-deps-cli - - # echo input - - name: Print the versions - run: echo Upgrading from ${{ inputs.prev_version }} to ${{ inputs.next_version }} - - # upgrade - - name: Upgrade tag - run: find . -type f -name "*.wit" -exec sed -i "s/${{ inputs.prev_version }}/${{ inputs.next_version }}/g" {} + - - name: Upgrade wit deps - run: wit-deps update - - name: Generate markdown - run: wit-bindgen markdown wit --html-in-md --all-features - - # file PR - - name: Create feature branch - env: - FEATURE_BRANCH: release-v${{ inputs.next_version }} - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add . - git checkout -b $FEATURE_BRANCH - git push -u origin $FEATURE_BRANCH - git commit -m "Update to v${{ inputs.next_version }}" - git push - - - name: Create pull request - run: gh pr create -B main -H release-v${{ inputs.next_version }} --title 'Release v${{ inputs.next_version }}' --body 'Updates the package version to v${{ inputs.next_version }}. Thanks!' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}